diff options
Diffstat (limited to 'graphs')
661 files changed, 24921 insertions, 0 deletions
diff --git a/graphs/cpp/.clang-format b/graphs/cpp/.clang-format new file mode 100644 index 0000000..6c10a16 --- /dev/null +++ b/graphs/cpp/.clang-format @@ -0,0 +1,80 @@ +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: false +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterEnum: true + AfterClass: true + AfterControlStatement: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeComma +BreakStringLiterals: true +ColumnLimit: 80 +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +FixNamespaceComments: true +ForEachMacros: ['ILIST_FOREACH', 'ILIST_FOREACH_ENTRY'] +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '<.*>' + Priority: 1 + - Regex: '.*' + Priority: 2 +IndentCaseLabels: false +IndentPPDirectives: AfterHash +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +NamespaceIndentation: All +PointerAlignment: Left +ReferenceAlignment: Left +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: Never diff --git a/graphs/cpp/.gitignore b/graphs/cpp/.gitignore new file mode 100644 index 0000000..4cf8e3f --- /dev/null +++ b/graphs/cpp/.gitignore @@ -0,0 +1,6 @@ +*/.gitignore +.idea/ +*.out +*.tar +cmake* +build/ diff --git a/graphs/cpp/CMakeLists.txt b/graphs/cpp/CMakeLists.txt new file mode 100644 index 0000000..a40c5d7 --- /dev/null +++ b/graphs/cpp/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.21.2) +project(cproutprout) + +add_executable(cpipi hello_world/hello_world.cc + directories_infos/directory_info.cc + directories_infos/read_info.cc + war/soldier.hh + war/soldier.cc + war/knight.hh + war/knight.cc + war/regiment.hh + war/regiment.cc)
\ No newline at end of file diff --git a/graphs/cpp/address_book/address_book.cc b/graphs/cpp/address_book/address_book.cc new file mode 100644 index 0000000..92e74cf --- /dev/null +++ b/graphs/cpp/address_book/address_book.cc @@ -0,0 +1,75 @@ +// +// Created by martial.simon on 2/26/25. +// + +#include "address_book.hh" + +#include <iostream> +#include <stdexcept> +bool AddressBook::add(const std::string& full_name, const std::string& email, + const std::string& number) +{ + try + { + ContactDetails details = ContactDetails::makeDetails(number, email); + if (full_name.empty()) + return false; + contact_map_.insert({ full_name, details }); + return true; + } + catch (std::invalid_argument& e) + { + return false; + } +} +std::vector<ContactDetails> AddressBook::find(const std::string& full_name) +{ + std::vector<ContactDetails> res; + for (auto detail = contact_map_.find(full_name); + detail != contact_map_.end() && detail->first == full_name; detail++) + { + res.push_back(detail->second); + } + return res; +} +std::size_t AddressBook::count(const std::string& full_name) +{ + size_t res = 0; + for (auto detail = contact_map_.find(full_name); + detail != contact_map_.end(); detail++) + { + res++; + } + return res; +} +bool AddressBook::remove(const std::string& full_name, std::size_t index) +{ + auto range = contact_map_.equal_range(full_name); + for (auto contact = range.first; contact != range.second; contact++) + { + if (contact->first == full_name) + { + if (index == 0) + { + contact_map_.erase(contact); + return true; + } + index--; + } + } + return false; +} +void AddressBook::remove_all(const std::string& full_name) +{ + auto range = contact_map_.equal_range(full_name); + contact_map_.erase(range.first, range.second); +} +std::ostream& operator<<(std::ostream& os, const AddressBook& b) +{ + os << b.contact_map_.size() << " contact(s) in the address book.\n"; + for (auto& pair : b.contact_map_) + { + os << "- " << pair.first << ": " << pair.second; + } + return os; +}
\ No newline at end of file diff --git a/graphs/cpp/address_book/address_book.hh b/graphs/cpp/address_book/address_book.hh new file mode 100644 index 0000000..9e59ac9 --- /dev/null +++ b/graphs/cpp/address_book/address_book.hh @@ -0,0 +1,25 @@ +// +// Created by martial.simon on 2/26/25. +// + +#pragma once +#include <map> +#include <string> +#include <vector> + +#include "contact_details.hh" + +class AddressBook +{ +public: + bool add(const std::string& full_name, const std::string& email, + const std::string& number); + std::vector<ContactDetails> find(const std::string& full_name); + std::size_t count(const std::string& full_name); + bool remove(const std::string& full_name, std::size_t index); + void remove_all(const std::string& full_name); + friend std::ostream& operator<<(std::ostream& os, const AddressBook& b); + +private: + std::multimap<std::string, ContactDetails> contact_map_; +}; diff --git a/graphs/cpp/address_book/contact_details.cc b/graphs/cpp/address_book/contact_details.cc new file mode 100644 index 0000000..3880d14 --- /dev/null +++ b/graphs/cpp/address_book/contact_details.cc @@ -0,0 +1,38 @@ +// +// Created by martial.simon on 2/26/25. +// + +#include "contact_details.hh" + +#include <iostream> +#include <stdexcept> +ContactDetails ContactDetails::makeDetails(const std::string& telephone_number, + const std::string& personal_email) +{ + for (auto digit : telephone_number) + { + if (!isdigit(digit)) + throw std::invalid_argument{ + "Phone number must only contain digits." + }; + } + size_t i; + for (i = 0; i < personal_email.length(); ++i) + { + if (personal_email[i] == '@') + break; + } + if (i == personal_email.length()) + throw std::invalid_argument{ "Email must contain at least one '@'." }; + return ContactDetails{ telephone_number, personal_email }; +} +std::ostream& operator<<(std::ostream& os, const ContactDetails& dt) +{ + os << dt.phone_ << ", " << dt.email_ << "\n"; + return os; +} +ContactDetails::ContactDetails(const std::string& telephone_number, + const std::string& personal_email) + : phone_{ telephone_number } + , email_{ personal_email } +{}
\ No newline at end of file diff --git a/graphs/cpp/address_book/contact_details.hh b/graphs/cpp/address_book/contact_details.hh new file mode 100644 index 0000000..57a6438 --- /dev/null +++ b/graphs/cpp/address_book/contact_details.hh @@ -0,0 +1,15 @@ +#pragma once +#include <string> + +struct ContactDetails +{ + static ContactDetails makeDetails(const std::string& telephone_number, + const std::string& personal_email); + friend std::ostream& operator<<(std::ostream& os, const ContactDetails& dt); + +private: + const std::string phone_; + const std::string email_; + ContactDetails(const std::string& telephone_number, + const std::string& personal_email); +};
\ No newline at end of file diff --git a/graphs/cpp/address_book/main.cc b/graphs/cpp/address_book/main.cc new file mode 100644 index 0000000..ffdb324 --- /dev/null +++ b/graphs/cpp/address_book/main.cc @@ -0,0 +1,42 @@ +#include <iostream> +#include <string> +#include <vector> + +#include "address_book.hh" + +int main() +{ + AddressBook b = AddressBook(); + + std::cout << "Adding multiple contacts to the address book.\n"; + + b.add("Cyril Berger", "cyril.berger@epita.fr", "33612983402"); + b.add("Thibault Allancon", "thibault.allancon@epita.fr", "33612983409"); + b.add("Cyril Berger", "cyril.berger@epita.fr", "33628359602"); + b.add("Hugo Wahl", "hugo.wahl@epita.fr", "3398560923"); + b.add("Dominique Michel", "dominique.michel@epita.fr", "3345096792"); + + std::cout << "Searching for Maya El Gemayel:\n"; + auto v = b.find("Maya El Gemayel"); + for (auto it = v.begin(); it != v.end(); it++) + std::cout << *it; + + std::cout << "Searching for Thibault Allancon:\n"; + v = b.find("Thibault Allancon"); + for (auto it = v.begin(); it != v.end(); it++) + std::cout << *it; + + std::cout << "Searching for Cyril Berger:\n"; + v = b.find("Cyril Berger"); + for (auto it = v.begin(); it != v.end(); it++) + std::cout << *it; + + std::cout << b; + + std::cout << "Erasing the second Cyril Berger.\n"; + b.remove("Cyril Berger", 1); + + std::cout << b; + + return 0; +} diff --git a/graphs/cpp/antagonist/CMakeLists.txt b/graphs/cpp/antagonist/CMakeLists.txt new file mode 100644 index 0000000..7620cb4 --- /dev/null +++ b/graphs/cpp/antagonist/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.21.2) +project(beaver_run) + +add_executable(beaver_run) +add_subdirectory(test) +target_compile_options(beaver_run PRIVATE -Wall -Wextra -Werror -pedantic -std=c++20 -Wold-style-cast) +set_target_properties(beaver_run PROPERTIES + CXX_STANDARD 20 + CXX_EXTENSIONS OFF) +add_subdirectory(src) + +target_link_libraries(beaver_run PUBLIC libbeaver) +target_include_directories(beaver_run PUBLIC + "${PROJECT_BINARY_DIR}" + "${PROJECT_SOURCE_DIR}/include" +) +target_include_directories(libbeaver PUBLIC + "${PROJECT_BINARY_DIR}" + "${PROJECT_SOURCE_DIR}/include" +)
\ No newline at end of file diff --git a/graphs/cpp/antagonist/include/libbeaver/beaver.hh b/graphs/cpp/antagonist/include/libbeaver/beaver.hh new file mode 100644 index 0000000..ac5cbe4 --- /dev/null +++ b/graphs/cpp/antagonist/include/libbeaver/beaver.hh @@ -0,0 +1,18 @@ +#include <memory> + +namespace beaver +{ + class Beaver + { + public: + virtual ~Beaver() = default; + + virtual const std::string& get_name() const = 0; + + virtual void display_video() = 0; + }; + + std::unique_ptr<Beaver> make_beaver(const std::string& name, + const std::string& video_path); + +} // namespace beaver diff --git a/graphs/cpp/antagonist/src/CMakeLists.txt b/graphs/cpp/antagonist/src/CMakeLists.txt new file mode 100644 index 0000000..8dd9272 --- /dev/null +++ b/graphs/cpp/antagonist/src/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.21.2) + +add_library(libbeaver SHARED) + +target_compile_options(libbeaver PUBLIC -Wall -Wextra -Werror -pedantic -std=c++20 -Wold-style-cast) +set_target_properties(libbeaver PROPERTIES + CXX_STANDARD 20 + CXX_EXTENSIONS OFF + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + OUTPUT_NAME "beaver" ) +target_include_directories(libbeaver PRIVATE + "${PROJECT_SOURCE_DIR}/include" + "${PROJECT_SOURCE_DIR}/src" +) + +find_package(OpenCV REQUIRED) +target_link_libraries(libbeaver PUBLIC ${OpenCV_LIBS}) +add_subdirectory(video_player) +add_subdirectory(beaver)
\ No newline at end of file diff --git a/graphs/cpp/antagonist/src/beaver/CMakeLists.txt b/graphs/cpp/antagonist/src/beaver/CMakeLists.txt new file mode 100644 index 0000000..13a04a6 --- /dev/null +++ b/graphs/cpp/antagonist/src/beaver/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.21.2) + +target_sources(libbeaver PRIVATE beaver.cc beaver_impl.cc) +set_target_properties(libbeaver PROPERTIES + CXX_STANDARD 20 + CXX_EXTENSIONS OFF)
\ No newline at end of file diff --git a/graphs/cpp/antagonist/src/beaver/beaver.cc b/graphs/cpp/antagonist/src/beaver/beaver.cc new file mode 100644 index 0000000..57a612c --- /dev/null +++ b/graphs/cpp/antagonist/src/beaver/beaver.cc @@ -0,0 +1,12 @@ +#include <string> + +#include "beaver_impl.hh" + +namespace beaver +{ + std::unique_ptr<Beaver> make_beaver(const std::string& name, + const std::string& video_path) + { + return std::make_unique<BeaverImpl>(name, video_path); + } +} // namespace beaver diff --git a/graphs/cpp/antagonist/src/beaver/beaver_impl.cc b/graphs/cpp/antagonist/src/beaver/beaver_impl.cc new file mode 100644 index 0000000..27757b5 --- /dev/null +++ b/graphs/cpp/antagonist/src/beaver/beaver_impl.cc @@ -0,0 +1,24 @@ +#include "beaver_impl.hh" + +#include <string> + +#include "video_player/video_player.hh" + +namespace beaver +{ + BeaverImpl::BeaverImpl(const std::string& name, std::string filename) + : beaver_name_(name) + , file_path_(filename) + {} + + const std::string& BeaverImpl::get_name() const + { + return beaver_name_; + } + + void BeaverImpl::display_video() + { + play_video(file_path_); + } + +} // namespace beaver diff --git a/graphs/cpp/antagonist/src/beaver/beaver_impl.hh b/graphs/cpp/antagonist/src/beaver/beaver_impl.hh new file mode 100644 index 0000000..02b84cc --- /dev/null +++ b/graphs/cpp/antagonist/src/beaver/beaver_impl.hh @@ -0,0 +1,21 @@ +#include <libbeaver/beaver.hh> +#include <string> + +namespace beaver +{ + class BeaverImpl : public Beaver + { + public: + BeaverImpl(const std::string& name, std::string filename); + + ~BeaverImpl() override = default; + + const std::string& get_name() const override; + + void display_video() override; + + private: + const std::string& beaver_name_; + std::string file_path_; + }; +} // namespace beaver diff --git a/graphs/cpp/antagonist/src/video_player/CMakeLists.txt b/graphs/cpp/antagonist/src/video_player/CMakeLists.txt new file mode 100644 index 0000000..0420a11 --- /dev/null +++ b/graphs/cpp/antagonist/src/video_player/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.21.2) + +target_sources(libbeaver PRIVATE video_player.cc) +set_target_properties(libbeaver PROPERTIES + CXX_STANDARD 20 + CXX_EXTENSIONS OFF)
\ No newline at end of file diff --git a/graphs/cpp/antagonist/src/video_player/video_player.cc b/graphs/cpp/antagonist/src/video_player/video_player.cc new file mode 100644 index 0000000..f3b724c --- /dev/null +++ b/graphs/cpp/antagonist/src/video_player/video_player.cc @@ -0,0 +1,59 @@ +#include "video_player.hh" + +#include <iostream> +#include <thread> + +static char pixelToAscii(int pixelValue) +{ + const std::string ascii_chars = ".:-=+*#%@8WM"; + int index = pixelValue * ascii_chars.length() / 256; + return ascii_chars[index]; +} + +static std::string rgbToAnsi(int r, int g, int b) +{ + return "\033[38;2;" + std::to_string(r) + ";" + std::to_string(g) + ";" + + std::to_string(b) + "m"; +} + +void play_video(std::string& video_path) +{ + std::cout << std::endl; + cv::VideoCapture video(video_path); + + if (!video.isOpened()) + { + std::cerr << "Error: Impossible to open video." << std::endl; + return; + } + + cv::Mat frame, resizedFrame; + while (true) + { + video >> frame; + if (frame.empty()) + break; + + cv::resize(frame, resizedFrame, cv::Size(105, 56)); + for (int i = 0; i < resizedFrame.rows; ++i) + { + for (int j = 0; j < resizedFrame.cols; ++j) + { + cv::Vec3b pixel = resizedFrame.at<cv::Vec3b>(i, j); + int blue = pixel[0]; + int green = pixel[1]; + int red = pixel[2]; + + char asciiChar = pixelToAscii((red + green + blue) / 3); + std::string colorCode = rgbToAnsi(red, green, blue); + + std::cout << "\033[" << i + 1 << ";" << j + 1 << "H"; + std::cout << colorCode << asciiChar; + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + std::cout << "\033[0m"; + } + video.release(); + std::cout << std::endl; +} diff --git a/graphs/cpp/antagonist/src/video_player/video_player.hh b/graphs/cpp/antagonist/src/video_player/video_player.hh new file mode 100644 index 0000000..3854bdf --- /dev/null +++ b/graphs/cpp/antagonist/src/video_player/video_player.hh @@ -0,0 +1,12 @@ +#pragma once + +#include <iostream> +#include <opencv2/opencv.hpp> +#include <string> + +/** + * @brief Plays a given video file. + * + * @param video_path The path to the video file to play. + */ +void play_video(std::string& video_path); diff --git a/graphs/cpp/antagonist/test/CMakeLists.txt b/graphs/cpp/antagonist/test/CMakeLists.txt new file mode 100644 index 0000000..b05b260 --- /dev/null +++ b/graphs/cpp/antagonist/test/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.21.2) + +target_sources(beaver_run PUBLIC main.cc) +set_target_properties(beaver_run PROPERTIES + CXX_STANDARD 20 + CXX_EXTENSIONS OFF) +file( + COPY ${CMAKE_CURRENT_SOURCE_DIR}/video/ + DESTINATION "${CMAKE_BINARY_DIR}/video" +)
\ No newline at end of file diff --git a/graphs/cpp/antagonist/test/main.cc b/graphs/cpp/antagonist/test/main.cc new file mode 100644 index 0000000..96d267d --- /dev/null +++ b/graphs/cpp/antagonist/test/main.cc @@ -0,0 +1,10 @@ +#include <iostream> +#include <libbeaver/beaver.hh> + +int main(void) +{ + auto bearer_roll = beaver::make_beaver("Frankulin", "video/video.mp4"); + + bearer_roll->display_video(); + std::cout << bearer_roll->get_name() << std::endl; +} diff --git a/graphs/cpp/antagonist/test/video/video.mp4 b/graphs/cpp/antagonist/test/video/video.mp4 Binary files differnew file mode 100644 index 0000000..7b788c6 --- /dev/null +++ b/graphs/cpp/antagonist/test/video/video.mp4 diff --git a/graphs/cpp/bimap/bimap.hh b/graphs/cpp/bimap/bimap.hh new file mode 100644 index 0000000..25f459d --- /dev/null +++ b/graphs/cpp/bimap/bimap.hh @@ -0,0 +1,36 @@ +#pragma once + +#include <map> + + template <typename Lhs, typename Rhs> + class Bimap +{ + static_assert(!std::is_same_v<Lhs, Rhs>, + "Lhs and Rhs must be different types"); + using mapLhs = std::map<Lhs, Rhs>; + using mapRhs = std::map<Rhs, Lhs>; + using iteratorLhs = typename mapLhs::const_iterator; + using iteratorRhs = typename mapRhs::const_iterator; + +public: + bool insert(const Lhs& vl, const Rhs& vr); + bool insert(const Rhs& vr, const Lhs& vl); + + std::size_t erase(const Lhs& vl); + std::size_t erase(const Rhs& vr); + + iteratorLhs find(const Lhs& vl) const; + iteratorRhs find(const Rhs& vr) const; + + std::size_t size() const; + void clear(); + + const mapLhs& get_lhs() const; + const mapRhs& get_rhs() const; + +private: + mapLhs lhs_; + mapRhs rhs_; +}; + +#include "bimap.hxx" diff --git a/graphs/cpp/bimap/bimap.hxx b/graphs/cpp/bimap/bimap.hxx new file mode 100644 index 0000000..9b1eb1f --- /dev/null +++ b/graphs/cpp/bimap/bimap.hxx @@ -0,0 +1,74 @@ +#pragma once +#include "bimap.hh" + +template <typename Lhs, typename Rhs> +bool Bimap<Lhs, Rhs>::insert(const Lhs& vl, const Rhs& vr) +{ + if (lhs_.contains(vl) || rhs_.contains(vr)) + return false; + if (lhs_.contains(vl) || !lhs_.insert({ vl, vr }).second) + return false; + if (rhs_.contains(vr) || !rhs_.insert({ vr, vl }).second) + return false; + return true; +} +template <typename Lhs, typename Rhs> +bool Bimap<Lhs, Rhs>::insert(const Rhs& vr, const Lhs& vl) +{ + return insert(vl, vr); +} +template <typename Lhs, typename Rhs> +std::size_t Bimap<Lhs, Rhs>::erase(const Lhs& vl) +{ + if (lhs_.size() <= 0) + return 0; + auto range = lhs_.find(vl); + if (range == lhs_.end()) + return 0; + rhs_.erase(range->second); + size_t n = lhs_.erase(range->first); + return n; +} +template <typename Lhs, typename Rhs> +std::size_t Bimap<Lhs, Rhs>::erase(const Rhs& vr) +{ + if (lhs_.size() <= 0) + return 0; + auto range = rhs_.find(vr); + if (range == rhs_.end()) + return 0; + lhs_.erase(range->second); + size_t n = rhs_.erase(range->first); + return n; +} +template <typename Lhs, typename Rhs> +typename Bimap<Lhs, Rhs>::iteratorLhs Bimap<Lhs, Rhs>::find(const Lhs& vl) const +{ + return lhs_.find(vl); +} +template <typename Lhs, typename Rhs> +typename Bimap<Lhs, Rhs>::iteratorRhs Bimap<Lhs, Rhs>::find(const Rhs& vr) const +{ + return rhs_.find(vr); +} +template <typename Lhs, typename Rhs> +std::size_t Bimap<Lhs, Rhs>::size() const +{ + return lhs_.size(); +} +template <typename Lhs, typename Rhs> +void Bimap<Lhs, Rhs>::clear() +{ + lhs_ = {}; + rhs_ = {}; +} +template <typename Lhs, typename Rhs> +const typename Bimap<Lhs, Rhs>::mapLhs& Bimap<Lhs, Rhs>::get_lhs() const +{ + return lhs_; +} +template <typename Lhs, typename Rhs> +const typename Bimap<Lhs, Rhs>::mapRhs& Bimap<Lhs, Rhs>::get_rhs() const +{ + return rhs_; +}
\ No newline at end of file diff --git a/graphs/cpp/bimap/bimap_example.cc b/graphs/cpp/bimap/bimap_example.cc new file mode 100644 index 0000000..771a2b0 --- /dev/null +++ b/graphs/cpp/bimap/bimap_example.cc @@ -0,0 +1,26 @@ +#include <iostream> +#include <string> + +#include "bimap.hh" + +int main() +{ + Bimap<int, std::string> bm; + + bm.insert(16, "Test."); + bm.insert("Prologin", 29); + + std::cout << "The bimap contains: " << bm.size() << " elements\n"; + + auto it1 = bm.find("Test."); + auto it2 = bm.find(29); + + std::cout << it1->first << ' ' << it1->second << '\n'; + std::cout << it2->first << ' ' << it2->second << '\n'; + + bm.erase(16); + bm.erase("Prologin"); + + bm.clear(); + return 0; +} diff --git a/graphs/cpp/cartesian_vector/format_numerical_data.cc b/graphs/cpp/cartesian_vector/format_numerical_data.cc new file mode 100644 index 0000000..b6355d2 --- /dev/null +++ b/graphs/cpp/cartesian_vector/format_numerical_data.cc @@ -0,0 +1,13 @@ +#include "format_numerical_data.hh" +std::ostream& FormatNumericalData::formatOs(std::ostream& os) const +{ + if (precision >= 0) + { + os.precision(precision); + } + if (scientific_notation) + std::scientific(os); + if (display_plus) + std::showpos(os); + return os; +}
\ No newline at end of file diff --git a/graphs/cpp/cartesian_vector/format_numerical_data.hh b/graphs/cpp/cartesian_vector/format_numerical_data.hh new file mode 100644 index 0000000..359e297 --- /dev/null +++ b/graphs/cpp/cartesian_vector/format_numerical_data.hh @@ -0,0 +1,22 @@ +#pragma once + +#include <ostream> +#include <string> + +struct FormatNumericalData +{ + //! string to be printed before the data + std::string prefix; + //! string to be printed after the data + std::string suffix; + //! gives the minimum number of digits to appear (after the radix if + //! scientific_notation is enabled) + int precision = -1; + //! define if scientific notation is enabled + bool scientific_notation = false; + //! define if a sign + should be placed before a number + bool display_plus = false; + + //! format the given stream according to class attributes + std::ostream& formatOs(std::ostream& os) const; +}; diff --git a/graphs/cpp/cartesian_vector/state_saver.cc b/graphs/cpp/cartesian_vector/state_saver.cc new file mode 100644 index 0000000..4b4a244 --- /dev/null +++ b/graphs/cpp/cartesian_vector/state_saver.cc @@ -0,0 +1,11 @@ +#include "state_saver.hh" +StateSaver::StateSaver(std::ostream& os) + : saved_stream_{ os } + , saved_flags_{ os.flags() } + , saved_precision_{ os.precision() } +{} +StateSaver::~StateSaver() +{ + saved_stream_.flags(saved_flags_); + saved_stream_.precision(saved_precision_); +}
\ No newline at end of file diff --git a/graphs/cpp/cartesian_vector/state_saver.hh b/graphs/cpp/cartesian_vector/state_saver.hh new file mode 100644 index 0000000..f52127c --- /dev/null +++ b/graphs/cpp/cartesian_vector/state_saver.hh @@ -0,0 +1,20 @@ +#pragma once + +#include <iostream> + +class StateSaver +{ +public: + //! constructor should save all flags and precision + StateSaver(std::ostream& os); + //! destructor should restore all flags and precision + ~StateSaver(); + +private: + //! original stream + std::ostream& saved_stream_; + //! flags of the original stream + std::ios_base::fmtflags saved_flags_; + //! precision of the original stream + std::streamsize saved_precision_; +}; diff --git a/graphs/cpp/cartesian_vector/vector.cc b/graphs/cpp/cartesian_vector/vector.cc new file mode 100644 index 0000000..1291f69 --- /dev/null +++ b/graphs/cpp/cartesian_vector/vector.cc @@ -0,0 +1,69 @@ +#include "vector.hh" + +#include "state_saver.hh" + +Vector::Vector(double x, double y) + : x_{ x } + , y_{ y } +{} +double Vector::get_x() const +{ + return x_; +} +double Vector::get_y() const +{ + return y_; +} +Vector& Vector::operator+=(const Vector& rhs) +{ + x_ += rhs.get_x(); + y_ += rhs.get_y(); + return *this; +} +Vector& Vector::operator-=(const Vector& rhs) +{ + x_ -= rhs.get_x(); + y_ -= rhs.get_y(); + return *this; +} +Vector& Vector::operator*=(double scalar) +{ + x_ *= scalar; + y_ *= scalar; + return *this; +} +Vector operator+(const Vector& lhs, const Vector& rhs) +{ + Vector lhs1{ lhs }; + return lhs1 += rhs; +} +Vector operator-(const Vector& lhs, const Vector& rhs) +{ + Vector lhs1{ lhs }; + return lhs1 -= rhs; +} +Vector operator*(const Vector& lhs, double scalar) +{ + Vector lhs1{ lhs }; + return lhs1 *= scalar; +} +Vector operator*(double scalar, const Vector& rhs) +{ + return rhs * scalar; +} +double operator*(const Vector& lhs, const Vector& rhs) +{ + return lhs.get_x() * rhs.get_x() + lhs.get_y() * rhs.get_y(); +} + +FormatNumericalData Vector::format_numerical_data_{ "[ ", " ]", 12, true, + true }; + +std::ostream& operator<<(std::ostream& os, const Vector& vec) +{ + StateSaver savestate{ os }; + Vector::format_numerical_data_.formatOs(os); + os << Vector::format_numerical_data_.prefix << vec.get_x() << " , " + << vec.get_y() << Vector::format_numerical_data_.suffix; + return os; +}
\ No newline at end of file diff --git a/graphs/cpp/cartesian_vector/vector.hh b/graphs/cpp/cartesian_vector/vector.hh new file mode 100644 index 0000000..b18838c --- /dev/null +++ b/graphs/cpp/cartesian_vector/vector.hh @@ -0,0 +1,29 @@ +#pragma once +#include <iostream> + +#include "format_numerical_data.hh" + +class Vector +{ +public: + Vector() = default; + Vector(double x, double y); + double get_x() const; + double get_y() const; + + Vector& operator+=(const Vector& rhs); + Vector& operator-=(const Vector& rhs); + Vector& operator*=(double scalar); + + friend Vector operator+(const Vector& lhs, const Vector& rhs); + friend Vector operator-(const Vector& lhs, const Vector& rhs); + friend Vector operator*(const Vector& lhs, double scalar); + friend Vector operator*(double scalar, const Vector& rhs); + friend double operator*(const Vector& lhs, const Vector& rhs); + friend std::ostream& operator<<(std::ostream& os, const Vector& vec); + +private: + double x_ = 0; + double y_ = 0; + static FormatNumericalData format_numerical_data_; +}; diff --git a/graphs/cpp/cartesian_vector/vector_test.cc b/graphs/cpp/cartesian_vector/vector_test.cc new file mode 100644 index 0000000..d822c9f --- /dev/null +++ b/graphs/cpp/cartesian_vector/vector_test.cc @@ -0,0 +1,27 @@ +#include <cmath> +#include <iostream> + +#include "vector.hh" + +double pi() +{ + return std::atan2(0., -1.); +} + +int main() +{ + std::cout << "default state pi (double) : " << pi() << '\n'; + Vector piVector{ pi(), pi() }; + Vector t(-1.0E-7, 6.812031E-4); + std::cout << "piVector :\n" << piVector << '\n'; + std::cout << "t + piVector :\n" << t + piVector << '\n'; + + Vector u{ 1923, 8 }; + std::cout << "u :\n" << u << '\n'; + std::cout << "default state (double) : " << u * t << '\n'; + t -= u; + std::cout << "t :\n" << t << '\n'; + std::cout << "t * 3 :\n" << t * 3 << '\n'; + + return 0; +} diff --git a/graphs/cpp/caste_or_cast/Makefile b/graphs/cpp/caste_or_cast/Makefile new file mode 100644 index 0000000..c49f282 --- /dev/null +++ b/graphs/cpp/caste_or_cast/Makefile @@ -0,0 +1,15 @@ +CXX ?= g++ +CXXFLAGS= -std=c++20 -Wall -Wextra -Werror -pedantic \ + -Wold-style-cast + +OBJS = ant.o worker.o nurturer.o provider.o queen.o colony.o main_example.o + +all: my_colony + +my_colony: $(OBJS) + $(CXX) -o $@ $^ + +clean: + $(RM) $(OBJS) my_colony +.PHONY: + clean diff --git a/graphs/cpp/caste_or_cast/ant.cc b/graphs/cpp/caste_or_cast/ant.cc new file mode 100644 index 0000000..2875815 --- /dev/null +++ b/graphs/cpp/caste_or_cast/ant.cc @@ -0,0 +1,87 @@ +#include "ant.hh" + +// The Colony class was forward declared in Ant header +// We need to include its header here so we know Colony implementation +#include "colony.hh" + +Ant::Ant(std::shared_ptr<Colony> colony, DevelopmentStage stage) + : stage_(stage) + , colony_(colony) +{} + +Ant::Ant(const Ant& o) + : stage_(o.stage_) + , colony_(o.colony_) + , hp_(o.hp_) + , food_level_(o.food_level_) +{} + +Ant& Ant::operator=(const Ant& o) +{ + stage_ = o.stage_; + colony_ = o.colony_; + hp_ = o.hp_; + food_level_ = o.food_level_; + return *this; +} + +std::shared_ptr<Colony> Ant::check_colony_access() +{ + std::shared_ptr<Colony> colony = colony_.lock(); + if (colony == nullptr) + throw std::runtime_error("The Colony pointer is expired."); + return colony; +} + +bool Ant::communicate(std::weak_ptr<Ant> wk_receiver) +{ + std::shared_ptr<Ant> receiver = wk_receiver.lock(); + if (receiver == nullptr || stage_ != DevelopmentStage::ADULT + || receiver->get_stage() != DevelopmentStage::ADULT) + return false; + if (receiver->get_passport_pheromone() != get_passport_pheromone()) + return attack(receiver); + return true; +} + +bool Ant::attack(std::weak_ptr<Ant> wk_ant) +{ + if (std::shared_ptr<Ant> ant = wk_ant.lock()) + { + ant->hp_ -= 1; + return true; + } + else + return false; +} + +uint32_t Ant::get_passport_pheromone() +{ + auto c = check_colony_access(); + return c->passport_pheromone_; +} + +DevelopmentStage Ant::get_stage() const +{ + return stage_; +} + +int Ant::get_hp() const +{ + return hp_; +} + +void Ant::set_hp(int hp) +{ + hp_ = hp; +} + +float Ant::get_food_level() const +{ + return food_level_; +} + +void Ant::increment_food_level_by(float value) +{ + food_level_ += value; +} diff --git a/graphs/cpp/caste_or_cast/ant.hh b/graphs/cpp/caste_or_cast/ant.hh new file mode 100644 index 0000000..6a0a0ee --- /dev/null +++ b/graphs/cpp/caste_or_cast/ant.hh @@ -0,0 +1,70 @@ +#pragma once + +#include <memory> + +//! forward declaration +class Colony; + +/* + * Enum Class representing the stage of life for + * an ant + */ +enum class DevelopmentStage : unsigned int +{ + // from the youngest to the oldest stage + EGG = 0, + LARVA, + COCOON, + ADULT +}; + +/* + * Base Class for every ant caste + */ +class Ant +{ +public: + //! delete constructor + Ant() = delete; + //! constructor + Ant(std::shared_ptr<Colony> colony, + DevelopmentStage stage = DevelopmentStage::EGG); + //! copy constructor + Ant(const Ant&); + //! copy assignement + Ant& operator=(const Ant&); + //! default virtual destructor + virtual ~Ant() = default; + //! communicate with another Ant + virtual bool communicate(std::weak_ptr<Ant> wk_receiver); + //! attack given Ant and check if it is dead + bool attack(std::weak_ptr<Ant> wk_ant); + + //! getter for passport_pheromone_ of Colony class + uint32_t get_passport_pheromone(); + //! getter for stage_ + DevelopmentStage get_stage() const; + //! getter for hp_ + int get_hp() const; + //! setter for hp_ + void set_hp(int hp); + //! getter for food_level_ + float get_food_level() const; + //! increment by value food_level_ + void increment_food_level_by(float value); + +protected: + //! return by value the colony shared_ptr if not expired else throw error + std::shared_ptr<Colony> check_colony_access(); + //! development stage + DevelopmentStage stage_; + //! Colony of this Ant + std::weak_ptr<Colony> colony_; + //! health points + int hp_ = 4; + //! represent the energy / food the ant ate for its + // current Development stage + float food_level_ = 0; + //! friend class + friend class Colony; +}; diff --git a/graphs/cpp/caste_or_cast/colony.cc b/graphs/cpp/caste_or_cast/colony.cc new file mode 100644 index 0000000..2c0697a --- /dev/null +++ b/graphs/cpp/caste_or_cast/colony.cc @@ -0,0 +1,116 @@ +#include "colony.hh" + +#include <iostream> + +#include "nurturer.hh" +#include "provider.hh" + +Colony::Colony(uint32_t passport) + : passport_pheromone_(passport) + , workers_() +{} +bool Colony::addAnt(const Ant& ant, std::shared_ptr<Colony> colony) +{ + auto q = dynamic_cast<const Queen*>(&ant); + if (q) + { + if (colony->queen_ || q->get_stage() != DevelopmentStage::ADULT) + return false; + colony->queen_ = std::make_unique<Queen>(*q); + return true; + } + auto n = dynamic_cast<const Nurturer*>(&ant); + if (n) + { + colony->workers_.push_back(std::make_shared<Nurturer>(*n)); + return true; + } + auto p = dynamic_cast<const Provider*>(&ant); + if (p) + { + colony->workers_.push_back(std::make_shared<Provider>(*p)); + return true; + } + return false; +} + +void Colony::manageQueen() +{ + if (queen_ == nullptr) + throw std::runtime_error("Cannot manage a colony without a Queen."); + // check if the queen should lose health points + if (queen_->food_level_ < 0) + queen_->hp_ -= 1; + if (queen_->hp_ <= 0) + { + queen_ = nullptr; + throw std::runtime_error("The Queen died."); + } + // Append to workers_ all the new workers contained in the queen's + // eggs_queue_ + while (!queen_->eggs_queue_.empty()) + { + //! we insert eggs that were laid by the queen + workers_.emplace_back(queen_->eggs_queue_.front()); + queen_->eggs_queue_.pop(); + } +} + +void Colony::removeDeadWorkers() +{ + auto dead_count = std::erase_if( + workers_, [](const std::shared_ptr<Worker> w) { return w->hp_ <= 0; }); + if (dead_count > 0) + { + std::cout << dead_count << " workers_ died.\n"; + // each dead worker decrease the cleanliness of the colony + cleanliness -= 0.5 * dead_count; + } +} + +// this method can be considered as one round of management +void Colony::manageAnts() +{ + // We first manage the queen + manageQueen(); + // We remove all dead workers contained in workers_ + removeDeadWorkers(); + std::cout << "-- THERE ARE " << workers_.size() << " WORKERS --\n"; + // We iterate over all workers + for (auto worker : workers_) + { + if (worker->stage_ == DevelopmentStage::ADULT) + { + /* + * Because work() is a virtual method, dynamic dispatch will be + * used. Which means that the overridden work method of the true + * type (either Nurturer or Provider) will actually be called + * instead of Worker::work(). + */ + worker->work(); + } + else + { + /* + * We increment their food_level_ as if it is a ticking time, + * EXCEPT for the larvae, as they are fed by nurturers. + */ + if (worker->stage_ != DevelopmentStage::LARVA) + worker->food_level_ += 1; + if (worker->food_level_ >= 4.0) + { + /* FIXME : Make the worker change stage_ and reset their + * food_level_ to 0. HINT : This can take only 2/3 lines if + * you use a certain C++ cast instead of a switch. + */ + worker->food_level_ = 0; + auto ant = static_cast<Ant*>(worker.get()); + ant->stage_ = static_cast<DevelopmentStage>( + static_cast<int>(ant->stage_) + 1); + } + } + } + queen_->food_level_ -= 0.2; +} + +// FIXME : Implements addAnt() static method. diff --git a/graphs/cpp/caste_or_cast/colony.hh b/graphs/cpp/caste_or_cast/colony.hh new file mode 100644 index 0000000..917ebf8 --- /dev/null +++ b/graphs/cpp/caste_or_cast/colony.hh @@ -0,0 +1,43 @@ +#pragma once + +#include <vector> + +#include "queen.hh" +#include "worker.hh" + +//! forward declarations +class Provider; +class Nurturer; + +/* + * Colony class that acts as one entity and manage all of its ants + */ +class Colony +{ +public: + //! constructor + Colony(uint32_t passport); + //! static method that adds a COPY of the given ant to the given colony + static bool addAnt(const Ant& ant, std::shared_ptr<Colony> colony); + //! manage all the ants, can be understood as one round + void manageAnts(); + //! overall cleanliness of the colony + float cleanliness = 100; + +private: + //! manage the queen (is alive etc.) + void manageQueen(); + //! remove all the dead workers of the workers_ vector + void removeDeadWorkers(); + //! attribute used to recognise if an Ant is from the same colony + uint32_t passport_pheromone_; + //! vector of all workers of the colony, each worker is stored in a + //! shared_ptr + std::vector<std::shared_ptr<Worker>> workers_; + //! unique queen, only its colony have the ownership of it. + std::unique_ptr<Queen> queen_ = nullptr; + + //! friend classes + friend class Ant; + friend class Nurturer; +}; diff --git a/graphs/cpp/caste_or_cast/main_example.cc b/graphs/cpp/caste_or_cast/main_example.cc new file mode 100644 index 0000000..9708df0 --- /dev/null +++ b/graphs/cpp/caste_or_cast/main_example.cc @@ -0,0 +1,37 @@ +#include <iostream> + +#include "colony.hh" +#include "nurturer.hh" +#include "provider.hh" + +int main() +{ + std::shared_ptr<Colony> myColony = std::make_shared<Colony>(10); + + Queen queen(myColony, DevelopmentStage::ADULT); + queen.increment_food_level_by(3.4); + + std::cout << std::boolalpha << Colony::addAnt(queen, myColony) << " "; + + // create provider with luck_ = 1.32 + Provider provider(myColony, 1.32, DevelopmentStage::ADULT); + + // create nurturer with default luck and 54.289 food_stock_ + Nurturer nurturer(myColony, DevelopmentStage::ADULT); + nurturer.increment_food_stock_by(54.289); + + // create larva with food_level_ = 3 + Provider larva(myColony, DevelopmentStage::LARVA); + larva.increment_food_level_by(3); + + std::cout << std::boolalpha << Colony::addAnt(nurturer, myColony) << " "; + std::cout << std::boolalpha << Colony::addAnt(larva, myColony) << " "; + std::cout << std::boolalpha << Colony::addAnt(provider, myColony) << '\n'; + + for (size_t i = 0; i < 8; i++) + myColony->manageAnts(); + /* + * Don't forget to test the communication methods of your ants. + */ + return 0; +} diff --git a/graphs/cpp/caste_or_cast/nurturer.cc b/graphs/cpp/caste_or_cast/nurturer.cc new file mode 100644 index 0000000..09faa79 --- /dev/null +++ b/graphs/cpp/caste_or_cast/nurturer.cc @@ -0,0 +1,98 @@ +#include "nurturer.hh" + +#include <iostream> + +// The Colony class was forward declared in Ant header +// We need to include its header here so we know Colony implementation +#include "colony.hh" +#include "provider.hh" + +void Nurturer::feedLarvae() +{ + if (food_stock_ < 0.5) + return; + size_t count = 0; + std::shared_ptr<Colony> colony = check_colony_access(); + for (auto i = colony->workers_.begin(); i < colony->workers_.end(); i++) + { + // if it doesn't have food anymore, can't feed more larvae + if (food_stock_ < 0.5) + break; + std::shared_ptr<Worker> worker = *i; + // only feed if it is a larvae and if it is not already full (its + // food_level_ => 4) + if (DevelopmentStage::LARVA == worker->get_stage() + && worker->get_food_level() < 4) + { + worker->increment_food_level_by(0.5); + food_stock_ -= 0.5; + colony->cleanliness -= 0.3; + food_level_ -= 0.03; + count++; + } + } + std::cout << count << " larvae were fed by nurturer.\n"; +} + +void Nurturer::work() +{ + if (stage_ != DevelopmentStage::ADULT) + return; + if (food_stock_ > 0.5) + { + // eat before working + food_level_ += 0.5; + food_stock_ -= 0.5; + // complete its tasks + feedLarvae(); + feedQueen(); + cleanNest(); + } + else + // make the ant more hungry + food_level_ -= 0.042; + //! call base class work() method + Worker::work(); +} +bool Nurturer::communicate(std::weak_ptr<Ant> wk_receiver) +{ + if (wk_receiver.lock() == nullptr) + return false; + if (!Ant::communicate(wk_receiver)) + return false; + std::cout << "Nurturer initiates communication.\n"; + auto p = dynamic_cast<Provider*>(wk_receiver.lock().get()); + if (p) + { + p->transferFood(*this); + } + return true; +} +void Nurturer::feedQueen() +{ + if (food_stock_ < 1) + return; + std::cout << "Feeding Queen.\n"; + auto c = check_colony_access(); + c->queen_->increment_food_level_by(1); + food_stock_--; + if (static_cast<int>(c->queen_->get_food_level()) > 0 + && static_cast<int>(c->queen_->get_food_level()) % 6 == 0) + c->queen_->layEgg(); + c->cleanliness -= .2; +} + +void Nurturer::cleanNest() +{ + std::shared_ptr<Colony> colony = check_colony_access(); + if (colony->cleanliness < 100) + { + // clean the nest according to the luck of the Nurturer + std::cout << "Cleaning nest: gained " << luck_ << " of cleanliness.\n"; + auto cleanliness = colony->cleanliness + luck_; + colony->cleanliness = (cleanliness > 100) ? 100 : cleanliness; + } +} + +// FIXME : Implements communicate(std::weak_ptr<Ant>) virtual overridden method +// and feedQueen() diff --git a/graphs/cpp/caste_or_cast/nurturer.hh b/graphs/cpp/caste_or_cast/nurturer.hh new file mode 100644 index 0000000..af7eec7 --- /dev/null +++ b/graphs/cpp/caste_or_cast/nurturer.hh @@ -0,0 +1,27 @@ +#pragma once + +#include "worker.hh" + +/* + * Nurturers worker sub-caste + */ +class Nurturer : public Worker +{ +public: + //! inherit Worker Constructors + using Worker::Worker; + //! final override of the work() Worker virtual method + void work() override final; + + /*! + * @details final override of the communicate() Ant virtual method + * @return true if the communication succeeded + * */ + bool communicate(std::weak_ptr<Ant> wk_receiver) override final; + //! feed the queen + void feedQueen(); + //! feed larvae + void feedLarvae(); + //! clean the nest / colony + void cleanNest(); +}; diff --git a/graphs/cpp/caste_or_cast/provider.cc b/graphs/cpp/caste_or_cast/provider.cc new file mode 100644 index 0000000..5767743 --- /dev/null +++ b/graphs/cpp/caste_or_cast/provider.cc @@ -0,0 +1,47 @@ +// +// Created by martial.simon on 2/26/25. +// +#include "provider.hh" + +#include <iostream> + +#include "nurturer.hh" +#include "queen.hh" +void Provider::work() +{ + if (stage_ != DevelopmentStage::ADULT) + return; + food_level_ += food_stock_ - static_cast<int>(food_stock_); + food_stock_ -= food_stock_ - static_cast<int>(food_stock_); + harvestFood(); + Worker::work(); +} +void Provider::transferFood(Nurturer& nurturer) +{ + if (food_stock_ < 1) + return; + nurturer.increment_food_stock_by(static_cast<int>(food_stock_)); + food_stock_ -= static_cast<int>(food_stock_); + std::cout << "Transferring food.\n"; +} +void Provider::harvestFood() +{ + float harvest = luck_; + std::cout << "Harvested " << harvest << " food.\n"; + food_stock_ += harvest; + food_level_ -= (harvest - static_cast<int>(harvest)) * 0.5; +} +bool Provider::communicate(std::weak_ptr<Ant> wk_receiver) +{ + if (wk_receiver.lock() == nullptr) + return false; + if (!Ant::communicate(wk_receiver)) + return false; + std::cout << "Provider initiates communication.\n"; + auto p = dynamic_cast<Nurturer*>(wk_receiver.lock().get()); + if (p) + { + transferFood(*p); + } + return true; +}
\ No newline at end of file diff --git a/graphs/cpp/caste_or_cast/provider.hh b/graphs/cpp/caste_or_cast/provider.hh new file mode 100644 index 0000000..5076585 --- /dev/null +++ b/graphs/cpp/caste_or_cast/provider.hh @@ -0,0 +1,29 @@ +#pragma once + +#include "worker.hh" + +//! forward declaration +class Nurturer; + +/* + * Provider worker sub-caste : + * harvest Food in the Outside World and transmit it to + * Nurturers ants + */ +class Provider : public Worker +{ +public: + //! inherit Worker Constructors + using Worker::Worker; + //! final override of the work() Worker virtual method + void work() override final; + //! transfer food to Nurturer workers only + void transferFood(Nurturer& nurturer); + /*! + * @details final override of the communicate() Ant virtual method + * @return true if the communication succeeded + * */ + bool communicate(std::weak_ptr<Ant> wk_receiver) override final; + //! go to the outside world and harvest food + void harvestFood(); +}; diff --git a/graphs/cpp/caste_or_cast/queen.cc b/graphs/cpp/caste_or_cast/queen.cc new file mode 100644 index 0000000..d1a998f --- /dev/null +++ b/graphs/cpp/caste_or_cast/queen.cc @@ -0,0 +1,30 @@ +#include "queen.hh" + +#include <iostream> + +#include "colony.hh" +#include "nurturer.hh" +#include "provider.hh" + +void Queen::layEgg() +{ + std::cout << "Queen is laying an Egg.\n"; + // if the queen tries to lay an egg without enough food_level + // it loses a health point + if (food_level_ < 0) + hp_ -= 1; + // checking if the colony_ attribute is not expired + std::shared_ptr<Colony> colony = check_colony_access(); + // either create a new Provider or a new Nurturer + static bool choose = false; + if (choose) + eggs_queue_.emplace(std::make_shared<Provider>( + colony, food_level_ * 0.5 + 0.2, DevelopmentStage::EGG)); + else + eggs_queue_.emplace(std::make_shared<Nurturer>( + colony, food_level_ * 0.1 + 0.13, DevelopmentStage::EGG)); + choose = !choose; + // consequences of laying an egg + colony->cleanliness -= 0.6; + food_level_ -= 5.7; +} diff --git a/graphs/cpp/caste_or_cast/queen.hh b/graphs/cpp/caste_or_cast/queen.hh new file mode 100644 index 0000000..9192f4c --- /dev/null +++ b/graphs/cpp/caste_or_cast/queen.hh @@ -0,0 +1,32 @@ +#pragma once + +#include <queue> + +#include "ant.hh" + +//! forward declaration +class Worker; + +/* + * Class representing the Queen Caste + */ +class Queen : public Ant +{ +public: + //! inherit Ant Constructors + using Ant::Ant; + //! the queen will create either a new Provider or Nurturer and push it to + //! eggs_queue_ + void layEgg(); + +private: + /*! + * We should not modify the Colony::workers vector while we + * iterate over it (because in some cases it can lead to undefined behavior) + * To solve this problem, we use a queue so we can save the eggs that the + * queen lay in one round (i.e. one call of Colony::manageAnts) and insert + * them in workers_ vector after we finished iterating. + * */ + std::queue<std::shared_ptr<Worker>> eggs_queue_; + friend class Colony; +}; diff --git a/graphs/cpp/caste_or_cast/worker.cc b/graphs/cpp/caste_or_cast/worker.cc new file mode 100644 index 0000000..e5cb532 --- /dev/null +++ b/graphs/cpp/caste_or_cast/worker.cc @@ -0,0 +1,28 @@ +#include "worker.hh" + +Worker::Worker(std::shared_ptr<Colony> colony, float luck, + DevelopmentStage stage) + : Ant(colony, stage) + , luck_(luck) +{} + +void Worker::work() +{ + if (food_level_ < 0) + hp_ -= 0.5; +} + +float Worker::get_luck() const +{ + return luck_; +} + +float Worker::get_food_stock() const +{ + return food_stock_; +} + +void Worker::increment_food_stock_by(float value) +{ + food_stock_ += value; +} diff --git a/graphs/cpp/caste_or_cast/worker.hh b/graphs/cpp/caste_or_cast/worker.hh new file mode 100644 index 0000000..cb8c5ef --- /dev/null +++ b/graphs/cpp/caste_or_cast/worker.hh @@ -0,0 +1,30 @@ +#pragma once + +#include "ant.hh" + +/* + * Class representing the generic Worker Caste + */ +class Worker : public Ant +{ +public: + //! inherit Ant constructors + using Ant::Ant; + //! constructor + Worker(std::shared_ptr<Colony> colony, float luck, + DevelopmentStage stage = DevelopmentStage::EGG); + //! the Worker will do all of its tasks + virtual void work(); + //! getter for food_stock_ + float get_food_stock() const; + //! add given value to food_stock_ + void increment_food_stock_by(float value); + //! return the luck of the worker + float get_luck() const; + +protected: + //! current food that the worker store on her. + float food_stock_ = 0.0; + //! luck of the worker + float luck_ = 3.141592; +}; diff --git a/graphs/cpp/chain_of_responsibility/director.cc b/graphs/cpp/chain_of_responsibility/director.cc new file mode 100644 index 0000000..af4072f --- /dev/null +++ b/graphs/cpp/chain_of_responsibility/director.cc @@ -0,0 +1,10 @@ +#include "director.hh" + +#include <iostream> +void Director::handle_request(int level) +{ + if (level <= 3) + std::cout << "Director handles\n"; + else + forward_request(level); +}
\ No newline at end of file diff --git a/graphs/cpp/chain_of_responsibility/handler.cc b/graphs/cpp/chain_of_responsibility/handler.cc new file mode 100644 index 0000000..256933b --- /dev/null +++ b/graphs/cpp/chain_of_responsibility/handler.cc @@ -0,0 +1,19 @@ +#include "handler.hh" + +#include <iostream> +Handler::Handler(Handler* next) + : next_{ next } +{} +void Handler::set_successor(Handler* h) +{ + next_ = h; +} +void Handler::forward_request(int level) +{ + if (next_ == nullptr) + { + std::cout << "Nobody can handle this request\n"; + } + else + next_->handle_request(level); +}
\ No newline at end of file diff --git a/graphs/cpp/chain_of_responsibility/president.cc b/graphs/cpp/chain_of_responsibility/president.cc new file mode 100644 index 0000000..9ee0566 --- /dev/null +++ b/graphs/cpp/chain_of_responsibility/president.cc @@ -0,0 +1,10 @@ +#include "president.hh" + +#include <iostream> +void President::handle_request(int level) +{ + if (level <= 9) + std::cout << "President handles\n"; + else + forward_request(level); +}
\ No newline at end of file diff --git a/graphs/cpp/chain_of_responsibility/vice_president.cc b/graphs/cpp/chain_of_responsibility/vice_president.cc new file mode 100644 index 0000000..0316d63 --- /dev/null +++ b/graphs/cpp/chain_of_responsibility/vice_president.cc @@ -0,0 +1,10 @@ +#include "vice_president.hh" + +#include <iostream> +void VicePresident::handle_request(int level) +{ + if (level <= 6) + std::cout << "VicePresident handles\n"; + else + forward_request(level); +}
\ No newline at end of file diff --git a/graphs/cpp/closer_to/closer_to.cc b/graphs/cpp/closer_to/closer_to.cc new file mode 100644 index 0000000..779d3b5 --- /dev/null +++ b/graphs/cpp/closer_to/closer_to.cc @@ -0,0 +1,15 @@ +// +// Created by martial.simon on 2/25/25. +// +#include "closer_to.hh" +CloserTo::CloserTo(int i) + : i_{ i } +{} +bool CloserTo::operator()(int a, int b) const +{ + const int da = a - i_ >= 0 ? a - i_ : i_ - a; + const int db = b - i_ >= 0 ? b - i_ : i_ - b; + if (da == db) + return a < b; + return da < db; +}
\ No newline at end of file diff --git a/graphs/cpp/closer_to/closer_to.hh b/graphs/cpp/closer_to/closer_to.hh new file mode 100644 index 0000000..a2462ca --- /dev/null +++ b/graphs/cpp/closer_to/closer_to.hh @@ -0,0 +1,11 @@ +#pragma once + +struct CloserTo +{ + CloserTo(int i); + + bool operator()(int a, int b) const; + +private: + int i_; +}; diff --git a/graphs/cpp/closer_to/closer_to_test.cc b/graphs/cpp/closer_to/closer_to_test.cc new file mode 100644 index 0000000..0edfd5e --- /dev/null +++ b/graphs/cpp/closer_to/closer_to_test.cc @@ -0,0 +1,29 @@ +#include <algorithm> +#include <iostream> +#include <vector> + +#include "closer_to.hh" + +void print_elt(int i) +{ + std::cout << ' ' << i; +} + +int main() +{ + auto v = std::vector<int>{ 1, 2, 3, 4, 5 }; + + std::cout << "Unsorted vector:"; + std::for_each(v.begin(), v.end(), print_elt); + std::cout << '\n'; + + auto n = 3; + + std::sort(v.begin(), v.end(), CloserTo(n)); + + std::cout << "Sorted vector closed to " << n << ':'; + std::for_each(v.begin(), v.end(), print_elt); + std::cout << '\n'; + + return 0; +} diff --git a/graphs/cpp/const-td/CMakeLists.txt b/graphs/cpp/const-td/CMakeLists.txt new file mode 100644 index 0000000..cbda23e --- /dev/null +++ b/graphs/cpp/const-td/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.30) +project(const) + +set(CMAKE_CXX_STANDARD 20) + +add_executable(const main.cc) diff --git a/graphs/cpp/const-td/main.cc b/graphs/cpp/const-td/main.cc new file mode 100644 index 0000000..0368d13 --- /dev/null +++ b/graphs/cpp/const-td/main.cc @@ -0,0 +1,25 @@ +#include <iostream> + +std::string ohio_sigma(const std::string& name) +{ + return "Hello, " + name + "!"; +} + +size_t skibidi(std::string& name) +{ + name = "Hello, " + name + "!"; + return name.length(); +} + +void strlen(const std::string& str, size_t* len) +{} + +int main() +{ + auto name = "Martial"; + std::cout << ohio_sigma(name); + auto new_name = std::string("Martial"); + std::cout << "String length: " << skibidi(new_name) + << "\tNew string: " << new_name << "\n"; + return 0; +} diff --git a/graphs/cpp/const/CMakeLists.txt b/graphs/cpp/const/CMakeLists.txt new file mode 100644 index 0000000..800759f --- /dev/null +++ b/graphs/cpp/const/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.21.2) +project(const) + +add_compile_options(-Wall -Wextra -Werror -pedantic -std=c++20 -Wold-style-cast) + +add_executable(const test_person.cc person.cc)
\ No newline at end of file diff --git a/graphs/cpp/const/person.cc b/graphs/cpp/const/person.cc new file mode 100644 index 0000000..63e8d73 --- /dev/null +++ b/graphs/cpp/const/person.cc @@ -0,0 +1,25 @@ +// +// Created by martial.simon on 2/24/25. +// +#include "person.hh" + +Person::Person(const std::string& name, const unsigned int age) + : name_{ name } + , age_{ age } +{} +std::string Person::get_name() const +{ + return name_; +} +unsigned int Person::get_age() const +{ + return age_; +} +void Person::set_name(const std::string& name) +{ + name_ = name; +} +void Person::set_age(const unsigned int age) +{ + age_ = age; +} diff --git a/graphs/cpp/const/person.hh b/graphs/cpp/const/person.hh new file mode 100644 index 0000000..0b44308 --- /dev/null +++ b/graphs/cpp/const/person.hh @@ -0,0 +1,17 @@ +#pragma once + +#include <string> + +class Person +{ +public: + Person(const std::string& name, const unsigned int age); + std::string get_name() const; + unsigned int get_age() const; + void set_name(const std::string& name); + void set_age(unsigned int age); + +private: + std::string name_; + unsigned int age_; +}; diff --git a/graphs/cpp/const/test_person.cc b/graphs/cpp/const/test_person.cc new file mode 100644 index 0000000..f59286e --- /dev/null +++ b/graphs/cpp/const/test_person.cc @@ -0,0 +1,20 @@ +#include <iostream> + +#include "person.hh" + +int main() +{ + Person my_person("Gordon Freeman", 47); + + const Person& my_person2 = my_person; + + std::cout << "name: " << my_person2.get_name() + << ", years: " << my_person2.get_age() << std::endl; + + std::string name = "Alyx Vance"; + my_person.set_name(name); + my_person.set_age(24); + + std::cout << "name: " << my_person2.get_name() + << ", years: " << my_person2.get_age() << std::endl; +} diff --git a/graphs/cpp/directories_infos/directory_info.cc b/graphs/cpp/directories_infos/directory_info.cc new file mode 100644 index 0000000..2c28150 --- /dev/null +++ b/graphs/cpp/directories_infos/directory_info.cc @@ -0,0 +1,34 @@ +// +// Created by martial.simon on 2/24/25. +// +#include "directory_info.hh" + +DirectoryInfo::DirectoryInfo(const std::string& name, size_t size, + uint16_t rights, const std::string& owner) + : name_{ name } + , size_{ size } + , rights_{ rights } + , owner_{ owner } +{ + is_valid_ = true; +} +const std::string& DirectoryInfo::get_name() const +{ + return name_; +} +const std::string& DirectoryInfo::get_owner() const +{ + return owner_; +} +size_t DirectoryInfo::get_size() const +{ + return size_; +} +uint16_t DirectoryInfo::get_rights() const +{ + return rights_; +} +bool DirectoryInfo::is_valid() const +{ + return is_valid_; +} diff --git a/graphs/cpp/directories_infos/directory_info.hh b/graphs/cpp/directories_infos/directory_info.hh new file mode 100644 index 0000000..eaf7c62 --- /dev/null +++ b/graphs/cpp/directories_infos/directory_info.hh @@ -0,0 +1,24 @@ +#pragma once + +#include <cstdint> +#include <string> + +class DirectoryInfo +{ +public: + DirectoryInfo() = default; + DirectoryInfo(const std::string& name, size_t size, uint16_t rights, + const std::string& owner); + const std::string& get_name() const; + const std::string& get_owner() const; + size_t get_size() const; + uint16_t get_rights() const; + bool is_valid() const; + +private: + std::string name_; + size_t size_; + uint16_t rights_; + std::string owner_; + bool is_valid_ = false; +}; diff --git a/graphs/cpp/directories_infos/main_example.cc b/graphs/cpp/directories_infos/main_example.cc new file mode 100644 index 0000000..db4bfa0 --- /dev/null +++ b/graphs/cpp/directories_infos/main_example.cc @@ -0,0 +1,32 @@ +#include <fstream> +#include <iomanip> +#include <iostream> + +#include "directory_info.hh" +#include "read_info.hh" + +int main(int argc, char** argv) +{ + if (argc < 2) + return 1; + + auto file = std::ifstream(argv[1]); + + DirectoryInfo dir_info; + + while ((dir_info = read_info(file)).is_valid()) + { + std::stringstream str_stream; + str_stream << dir_info.get_name() << ' ' << dir_info.get_size() << ' ' + << std::oct << dir_info.get_rights() << std::dec << ' ' + << dir_info.get_owner() << '\n'; + + dir_info = read_info(str_stream); + if (!dir_info.is_valid()) + break; + + std::cout << dir_info.get_name() << '|' << dir_info.get_size() << '|' + << std::oct << dir_info.get_rights() << std::dec << '|' + << dir_info.get_owner() << '\n'; + } +} diff --git a/graphs/cpp/directories_infos/read_info.cc b/graphs/cpp/directories_infos/read_info.cc new file mode 100644 index 0000000..327d004 --- /dev/null +++ b/graphs/cpp/directories_infos/read_info.cc @@ -0,0 +1,39 @@ +#include "read_info.hh" + +#include <sstream> + +#include "directory_info.hh" + +DirectoryInfo read_info(std::istream& stream) +{ + if (stream.eof()) + { + return DirectoryInfo{}; + } + std::string l; + std::getline(stream, l); + std::istringstream line{ l }; + std::string name; + size_t size; + uint16_t rights; + std::string owner; + if (!(line >> name)) + { + return DirectoryInfo{}; + } + if (!(line >> size)) + { + return DirectoryInfo{}; + } + if (!(line >> std::oct >> rights >> std::dec)) + { + return DirectoryInfo{}; + } + if (!(line >> owner)) + { + return DirectoryInfo{}; + } + if (line.eof()) + return DirectoryInfo{ name, size, rights, owner }; + return DirectoryInfo{}; +}
\ No newline at end of file diff --git a/graphs/cpp/directories_infos/read_info.hh b/graphs/cpp/directories_infos/read_info.hh new file mode 100644 index 0000000..72f64b4 --- /dev/null +++ b/graphs/cpp/directories_infos/read_info.hh @@ -0,0 +1,7 @@ +#pragma once +#include <iostream> + +#include "directory_info.hh" + +// use ref to istream +DirectoryInfo read_info(std::istream& stream);
\ No newline at end of file diff --git a/graphs/cpp/doubly_linked_list/CMakeLists.txt b/graphs/cpp/doubly_linked_list/CMakeLists.txt new file mode 100644 index 0000000..37204f6 --- /dev/null +++ b/graphs/cpp/doubly_linked_list/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.21.2) +project(doubly_linked_list) + +add_library(doubly_linked_list SHARED node.cc list.cc) +target_compile_options(doubly_linked_list PRIVATE -Wall -Wextra -Werror -pedantic -std=c++20 -Wold-style-cast) +set_target_properties(doubly_linked_list PROPERTIES + CXX_STANDARD 20 + CXX_EXTENSIONS OFF)
\ No newline at end of file diff --git a/graphs/cpp/doubly_linked_list/list.cc b/graphs/cpp/doubly_linked_list/list.cc new file mode 100644 index 0000000..36cf5ad --- /dev/null +++ b/graphs/cpp/doubly_linked_list/list.cc @@ -0,0 +1,88 @@ +#include "list.hh" +List::List() + : nb_elts_{ 0 } +{} +void List::push_front(int i) +{ + nb_elts_++; + if (nb_elts_ == 1) + { + first_ = std::make_shared<Node>(i); + last_ = first_; + return; + } + std::shared_ptr<Node> ns = std::make_shared<Node>(i); + ns->set_next(first_); + first_->set_prev(ns); + first_ = ns; +} +std::optional<int> List::pop_front() +{ + if (nb_elts_ == 0) + { + return std::nullopt; + } + nb_elts_--; + int res = first_->get_val(); + if (nb_elts_ == 0) + { + first_ = nullptr; + last_ = nullptr; + return res; + } + std::shared_ptr<Node> tmp = first_->get_next(); + first_->set_next(nullptr); + tmp->set_prev(nullptr); + first_ = tmp; + return res; +} +void List::push_back(int i) +{ + nb_elts_++; + if (nb_elts_ == 1) + { + first_ = std::make_shared<Node>(i); + last_ = first_; + return; + } + std::shared_ptr<Node> ns = std::make_shared<Node>(i); + ns->set_prev(last_); + last_->set_next(ns); + last_ = ns; +} +std::optional<int> List::pop_back() +{ + if (nb_elts_ == 0) + { + return std::nullopt; + } + nb_elts_--; + int res = last_->get_val(); + if (nb_elts_ == 0) + { + first_ = nullptr; + last_ = nullptr; + return res; + } + std::shared_ptr<Node> tmp = last_->get_prev(); + last_->set_prev(nullptr); + tmp->set_next(nullptr); + last_ = tmp; + return res; +} +void List::print(std::ostream& os) const +{ + if (nb_elts_ == 0) + return; + os << first_->get_val(); + for (Node* node = first_->get_next().get(); node; + node = node->get_next().get()) + { + os << " " << node->get_val(); + } + // os << "\n"; +} +size_t List::length() const +{ + return nb_elts_; +}
\ No newline at end of file diff --git a/graphs/cpp/doubly_linked_list/list.hh b/graphs/cpp/doubly_linked_list/list.hh new file mode 100644 index 0000000..50f71c6 --- /dev/null +++ b/graphs/cpp/doubly_linked_list/list.hh @@ -0,0 +1,24 @@ +#pragma once + +#include <optional> +#include <ostream> + +#include "node.hh" + +class List +{ +public: + List(); + + void push_front(int i); + void push_back(int i); + std::optional<int> pop_front(); + std::optional<int> pop_back(); + void print(std::ostream& os) const; + size_t length() const; + +private: + size_t nb_elts_; + std::shared_ptr<Node> first_; + std::shared_ptr<Node> last_; +}; diff --git a/graphs/cpp/doubly_linked_list/main.cc b/graphs/cpp/doubly_linked_list/main.cc new file mode 100644 index 0000000..cd9ab32 --- /dev/null +++ b/graphs/cpp/doubly_linked_list/main.cc @@ -0,0 +1,36 @@ +#include <iostream> + +#include "list.hh" + +int main() +{ + List l = List(); + l.print(std::cout); + std::cout << '\n'; + + l.push_back(13); + l.print(std::cout); + std::cout << '\n'; + + l.push_front(5); + l.print(std::cout); + std::cout << '\n'; + + l.push_back(42); + l.print(std::cout); + std::cout << '\n'; + + l.pop_back(); + l.print(std::cout); + std::cout << '\n'; + + l.push_back(42); + l.print(std::cout); + std::cout << '\n'; + + l.pop_front(); + l.print(std::cout); + std::cout << '\n'; + + std::cout << "Nb elts: " << l.length() << '\n'; +} diff --git a/graphs/cpp/doubly_linked_list/node.cc b/graphs/cpp/doubly_linked_list/node.cc new file mode 100644 index 0000000..b6db962 --- /dev/null +++ b/graphs/cpp/doubly_linked_list/node.cc @@ -0,0 +1,29 @@ +#include "node.hh" + +Node::Node(int v) + : val_{ v } +{} +int Node::get_val() const +{ + return val_; +} +void Node::set_val(int val) +{ + val_ = val; +} +std::shared_ptr<Node> Node::get_next() const +{ + return next_; +} +void Node::set_next(std::shared_ptr<Node> next) +{ + next_ = next; +} +std::shared_ptr<Node> Node::get_prev() const +{ + return prev_.lock(); +} +void Node::set_prev(std::shared_ptr<Node> prev) +{ + prev_ = prev; +}
\ No newline at end of file diff --git a/graphs/cpp/doubly_linked_list/node.hh b/graphs/cpp/doubly_linked_list/node.hh new file mode 100644 index 0000000..9eb2e50 --- /dev/null +++ b/graphs/cpp/doubly_linked_list/node.hh @@ -0,0 +1,23 @@ +#pragma once + +#include <memory> + +class Node +{ +public: + Node(int v); + + int get_val() const; + void set_val(int val); + + std::shared_ptr<Node> get_next() const; + void set_next(std::shared_ptr<Node> next); + + std::shared_ptr<Node> get_prev() const; + void set_prev(std::shared_ptr<Node> prev); + +private: + int val_; + std::shared_ptr<Node> next_; + std::weak_ptr<Node> prev_; +}; diff --git a/graphs/cpp/exception/Makefile b/graphs/cpp/exception/Makefile new file mode 100644 index 0000000..01107c5 --- /dev/null +++ b/graphs/cpp/exception/Makefile @@ -0,0 +1,14 @@ +CC=g++ +CXXFLAGS= -Wall -Wextra -Werror -std=c++20 -pedantic -Wold-style-cast + +OBJS= main.o game.o player.o invalid_argument.o +BIN= main + +all: ${BIN} + +${BIN}: ${OBJS} + +clean: + ${RM} ${OBJS} ${BIN} + +.PHONY: clean all diff --git a/graphs/cpp/exception/game.cc b/graphs/cpp/exception/game.cc new file mode 100644 index 0000000..88d435c --- /dev/null +++ b/graphs/cpp/exception/game.cc @@ -0,0 +1,23 @@ +#include "game.hh" + +#include <iostream> + +Game::Game(int secret) + : secret_(secret) +{} + +void Game::play(const Player& p1, const Player& p2) const +{ + if (p1 == p2) + throw InvalidArgumentException{ "Stop playing by yourself!" }; + + auto d1 = std::abs(p1.get_guess() - secret_); + auto d2 = std::abs(p2.get_guess() - secret_); + + if (d1 > d2) + std::cout << p1 << " wins!" << std::endl; + else if (d1 < d2) + std::cout << p2 << " wins!" << std::endl; + else + std::cout << "Draw!" << std::endl; +} diff --git a/graphs/cpp/exception/game.hh b/graphs/cpp/exception/game.hh new file mode 100644 index 0000000..e162bda --- /dev/null +++ b/graphs/cpp/exception/game.hh @@ -0,0 +1,14 @@ +#pragma once + +#include "invalid_argument.hh" +#include "player.hh" + +class Game +{ +public: + Game(int secret); + void play(const Player& p1, const Player& p2) const; + +private: + int secret_; +}; diff --git a/graphs/cpp/exception/invalid_argument.cc b/graphs/cpp/exception/invalid_argument.cc new file mode 100644 index 0000000..aafa4e3 --- /dev/null +++ b/graphs/cpp/exception/invalid_argument.cc @@ -0,0 +1,9 @@ +#include "invalid_argument.hh" + +InvalidArgumentException::InvalidArgumentException(const std::string& msg) + : msg_{ msg } +{} +const char* InvalidArgumentException::what() const noexcept +{ + return msg_.c_str(); +}
\ No newline at end of file diff --git a/graphs/cpp/exception/invalid_argument.hh b/graphs/cpp/exception/invalid_argument.hh new file mode 100644 index 0000000..25356df --- /dev/null +++ b/graphs/cpp/exception/invalid_argument.hh @@ -0,0 +1,15 @@ +#pragma once + +#include <exception> +#include <string> + +class InvalidArgumentException : public std::exception +{ +public: + InvalidArgumentException(const std::string& msg); + + virtual const char* what() const noexcept; + +private: + std::string msg_; +}; diff --git a/graphs/cpp/exception/main.cc b/graphs/cpp/exception/main.cc new file mode 100644 index 0000000..7881a4c --- /dev/null +++ b/graphs/cpp/exception/main.cc @@ -0,0 +1,80 @@ +#include <iostream> + +#include "game.hh" +#include "invalid_argument.hh" +#include "player.hh" + +int main() +{ + Game g(42); + std::string n1 = "Toto"; + std::string n2 = "Frodo"; + std::string n3 = "Feanor"; + std::string n4 = "Pikachu"; + std::string n5 = "Baby"; + std::string n6 = ""; + + try + { + Player p1 = Player(n1, 9, 3); + } + catch (InvalidArgumentException& e) + { + std::cout << e.what() << std::endl; + } + try + { + Player p2 = Player(n2, 51, 5); + } + catch (InvalidArgumentException& e) + { + std::cout << e.what() << std::endl; + } + try + { + Player p3 = Player(n3, 3142, 42); + } + catch (InvalidArgumentException& e) + { + std::cout << e.what() << std::endl; + } + try + { + Player p4 = Player(n4, 25, 5000); + } + catch (InvalidArgumentException& e) + { + std::cout << e.what() << std::endl; + } + try + { + Player p5 = Player(n5, -1, 1); + } + catch (InvalidArgumentException& e) + { + std::cout << e.what() << std::endl; + } + try + { + Player p6 = Player(n6, 19, 1); + } + catch (InvalidArgumentException& e) + { + std::cout << e.what() << std::endl; + } + + try + { + Player p1 = Player(n1, 9, 3); + Player p2 = Player(n2, 51, -18); + g.play(p1, p1); + } + catch (InvalidArgumentException& e) + { + std::cout << e.what() << std::endl; + } + + Player p1 = Player(n1, 9, 3); + Player p2 = Player(n2, 51, -18); + g.play(p1, p2); +} diff --git a/graphs/cpp/exception/player.cc b/graphs/cpp/exception/player.cc new file mode 100644 index 0000000..4a0b378 --- /dev/null +++ b/graphs/cpp/exception/player.cc @@ -0,0 +1,34 @@ +#include "player.hh" + +Player::Player(const std::string& name, int age, int guess) + : name_(name) + , age_(age) + , guess_(guess) +{ + if (name.empty()) + throw InvalidArgumentException{ "Name can't be empty." }; + if (age < 0) + throw InvalidArgumentException{ + "Well, it seems you are not born yet." + }; + if (age > 150) + throw InvalidArgumentException{ "Sorry gramp, too old to play." }; +} + +int Player::get_guess() const +{ + return guess_; +} +bool Player::operator==(const Player& p) const +{ + return this == &p; +} +bool Player::operator!=(const Player& p) const +{ + return this != &p; +} + +std::ostream& operator<<(std::ostream& os, const Player& p) +{ + return os << p.name_ << '(' << p.age_ << ')'; +} diff --git a/graphs/cpp/exception/player.hh b/graphs/cpp/exception/player.hh new file mode 100644 index 0000000..3ee8060 --- /dev/null +++ b/graphs/cpp/exception/player.hh @@ -0,0 +1,26 @@ +#pragma once + +#include <iostream> + +#include "invalid_argument.hh" + +class Player +{ +public: + Player(const std::string& name, int age, int guess); + + int get_guess() const; + + friend std::ostream& operator<<(std::ostream& os, const Player& b); + + bool operator==(const Player& p) const; + bool operator!=(const Player& p) const; + +private: + std::string name_; + int age_; + + int guess_; +}; + +std::ostream& operator<<(std::ostream& os, const Player& p); diff --git a/graphs/cpp/exist_functor/example.cc b/graphs/cpp/exist_functor/example.cc new file mode 100644 index 0000000..d580f7b --- /dev/null +++ b/graphs/cpp/exist_functor/example.cc @@ -0,0 +1,24 @@ +#include <iostream> + +#include "exist.hh" + +int main() +{ + Exist<int> exist_int; + Exist<std::string> exist_str; + + // Test with integers + std::cout << std::boolalpha; + std::cout << exist_int(1) << std::endl; // Prints false + std::cout << exist_int(2) << std::endl; // Prints false + std::cout << exist_int(1) << std::endl; // Prints true + std::cout << exist_int(3) << std::endl; // Prints false + + // Test with strings + std::cout << exist_str(std::string("Hello")) << std::endl; // Prints false + std::cout << exist_str(std::string("World")) << std::endl; // Prints false + std::cout << exist_str(std::string("Hello")) << std::endl; // Prints true + std::cout << exist_str(std::string("C++")) << std::endl; // Prints false + + return 0; +} diff --git a/graphs/cpp/exist_functor/exist.hh b/graphs/cpp/exist_functor/exist.hh new file mode 100644 index 0000000..49cafd6 --- /dev/null +++ b/graphs/cpp/exist_functor/exist.hh @@ -0,0 +1,14 @@ +#pragma once +#include <vector> + +template <class T> +class Exist +{ +public: + bool operator()(T x); + +private: + std::vector<T> seen_; +}; + +#include "exist.hxx" diff --git a/graphs/cpp/exist_functor/exist.hxx b/graphs/cpp/exist_functor/exist.hxx new file mode 100644 index 0000000..638c4e3 --- /dev/null +++ b/graphs/cpp/exist_functor/exist.hxx @@ -0,0 +1,15 @@ +#pragma once +#include <algorithm> + +#include "exist.hh" + +template <class T> +bool Exist<T>::operator()(T x) +{ + if (std::find(seen_.begin(), seen_.end(), x) == seen_.end()) + { + seen_.push_back(x); + return false; + } + return true; +}
\ No newline at end of file diff --git a/graphs/cpp/for_each/for_each.hh b/graphs/cpp/for_each/for_each.hh new file mode 100644 index 0000000..195c3c6 --- /dev/null +++ b/graphs/cpp/for_each/for_each.hh @@ -0,0 +1,6 @@ +#pragma once + +template <class IT, class F> +void my_foreach(IT begin, IT end, auto fun); + +#include "for_each.hxx"
\ No newline at end of file diff --git a/graphs/cpp/for_each/for_each.hxx b/graphs/cpp/for_each/for_each.hxx new file mode 100644 index 0000000..dcfa0fa --- /dev/null +++ b/graphs/cpp/for_each/for_each.hxx @@ -0,0 +1,9 @@ +#pragma once +#include "for_each.hh" + +template <class IT, class F> +void my_foreach(IT begin, IT end, F fun) +{ + for (; begin != end; ++begin) + fun(*begin); +}
\ No newline at end of file diff --git a/graphs/cpp/for_each/main.cc b/graphs/cpp/for_each/main.cc new file mode 100644 index 0000000..08da792 --- /dev/null +++ b/graphs/cpp/for_each/main.cc @@ -0,0 +1,10 @@ +#include <iostream> + +#include "for_each.hh" + +int main() +{ + auto v = { 'M', 'y', 'S', 'T', 'L', '\n' }; + + my_foreach(v.begin(), v.end(), [](auto c) { std::cout << c; }); +} diff --git a/graphs/cpp/forward_multiplication/forward_multiplication.cc b/graphs/cpp/forward_multiplication/forward_multiplication.cc new file mode 100644 index 0000000..72abc91 --- /dev/null +++ b/graphs/cpp/forward_multiplication/forward_multiplication.cc @@ -0,0 +1,7 @@ +#include "forward_multiplication.hh" +// +// Created by martial.simon on 2/26/25. +// +outer_lambda_type mult_by = [](int val) { + return [val](int mul) { return val * mul; }; +};
\ No newline at end of file diff --git a/graphs/cpp/forward_multiplication/forward_multiplication.hh b/graphs/cpp/forward_multiplication/forward_multiplication.hh new file mode 100644 index 0000000..9cca5e6 --- /dev/null +++ b/graphs/cpp/forward_multiplication/forward_multiplication.hh @@ -0,0 +1,7 @@ +#pragma once + +#include <functional> + +using inner_lambda_type = const std::function<int(int rhs)>; +using outer_lambda_type = const std::function<inner_lambda_type(int lhs)>; +extern outer_lambda_type mult_by; diff --git a/graphs/cpp/forward_multiplication/forward_multiplication_test.cc b/graphs/cpp/forward_multiplication/forward_multiplication_test.cc new file mode 100644 index 0000000..21be1a6 --- /dev/null +++ b/graphs/cpp/forward_multiplication/forward_multiplication_test.cc @@ -0,0 +1,21 @@ +#include <iostream> +#include <string> + +#include "forward_multiplication.hh" + +int main(int argc, char** argv) +{ + if (argc != 3) + { + std::cerr << "Usage: " << argv[0] << " 'number' 'number'" << std::endl; + return 1; + } + + auto lhs = std::stoi(argv[1]); + auto rhs = std::stoi(argv[2]); + + auto mult_by_lhs = mult_by(lhs); + + std::cout << mult_by(lhs)(rhs) << '\n'; + std::cout << mult_by_lhs(rhs) << std::endl; +} diff --git a/graphs/cpp/hello_world/hello_world.cc b/graphs/cpp/hello_world/hello_world.cc new file mode 100644 index 0000000..f3ac0cf --- /dev/null +++ b/graphs/cpp/hello_world/hello_world.cc @@ -0,0 +1,6 @@ +#include <iostream> +int main() +{ + std::cout << "Hello World!\n"; + return 0; +}
\ No newline at end of file diff --git a/graphs/cpp/hot_potato/bomb.cc b/graphs/cpp/hot_potato/bomb.cc new file mode 100644 index 0000000..256e3d7 --- /dev/null +++ b/graphs/cpp/hot_potato/bomb.cc @@ -0,0 +1,28 @@ +#include "bomb.hh" + +#include <iostream> +#include <stdexcept> + +Bomb::Bomb(int ticks) +{ + if (ticks <= 0) + throw std::runtime_error{ + "Number of ticks should be strictly positive" + }; + max_ticks_ = ticks; + count_ = 0; +} +void Bomb::tick() +{ + if (count_ >= max_ticks_) + throw std::runtime_error{ "Bomb should have already exploded." }; + if (count_ % 2) + std::cout << "Tac!\n"; + else + std::cout << "Tic!\n"; + count_++; +} +bool Bomb::has_exploded() const +{ + return count_ >= max_ticks_; +}
\ No newline at end of file diff --git a/graphs/cpp/hot_potato/bomb.hh b/graphs/cpp/hot_potato/bomb.hh new file mode 100644 index 0000000..41e0bd3 --- /dev/null +++ b/graphs/cpp/hot_potato/bomb.hh @@ -0,0 +1,11 @@ +#pragma once + +class Bomb { +public: + Bomb(int ticks); + void tick(); + bool has_exploded() const; +private: + int max_ticks_; + int count_; +};
\ No newline at end of file diff --git a/graphs/cpp/hot_potato/game.cc b/graphs/cpp/hot_potato/game.cc new file mode 100644 index 0000000..3e0889a --- /dev/null +++ b/graphs/cpp/hot_potato/game.cc @@ -0,0 +1,48 @@ +// +// Created by martial.simon on 2/25/25. +// + +#include "game.hh" + +#include <iostream> +#include <stdexcept> +void Game::add_player(const std::string& name, size_t nb_presses) +{ + auto new_player = std::make_unique<Player>(name, nb_presses); + if (head_ == nullptr) + { + head_ = std::move(new_player); + tail_ = head_.get(); + } + else + { + tail_->set_next(std::move(new_player)); + tail_ = tail_->get_next(); + } +} +void Game::play(int bomb_ticks) +{ + if (!head_ || !head_->get_next()) + throw std::runtime_error{ "Not enough players." }; + head_->set_bomb(std::make_unique<Bomb>(bomb_ticks)); + Player* p = head_.get(); + while (true) + { + p->press_bomb(); + if (p->is_dead()) + { + std::cout << p->get_name() << " has exploded.\n"; + return; + } + if (p == tail_) + { + p->pass_bomb(*head_); + p = head_.get(); + } + else + { + p->pass_bomb(*p->get_next()); + p = p->get_next(); + } + } +}
\ No newline at end of file diff --git a/graphs/cpp/hot_potato/game.hh b/graphs/cpp/hot_potato/game.hh new file mode 100644 index 0000000..fd65b28 --- /dev/null +++ b/graphs/cpp/hot_potato/game.hh @@ -0,0 +1,17 @@ +// +// Created by martial.simon on 2/25/25. +// + +#pragma once +#include <memory> + +#include "player.hh" + +class Game { +public: + void add_player(const std::string& name, size_t nb_presses); + void play(int bomb_ticks); +private: + std::unique_ptr<Player> head_; + Player* tail_ = nullptr; +}; diff --git a/graphs/cpp/hot_potato/main.cc b/graphs/cpp/hot_potato/main.cc new file mode 100644 index 0000000..ce491d0 --- /dev/null +++ b/graphs/cpp/hot_potato/main.cc @@ -0,0 +1,20 @@ +// +// Created by martial.simon on 2/25/25. +// +#include "game.hh" +int main() +{ + auto game = Game(); + game.add_player("Benjamin", 2); + game.add_player("Andy", 1); + game.add_player("Geoffrey", 3); + game.add_player("Hugo", 1); + game.add_player("Maayane", 2); + game.add_player("Quentin", 1); + game.add_player("Lucas", 5); // Likes risks + game.add_player("Tom", 1); + game.add_player("Alexis", 0); // Cheater + game.add_player("FX", 3); + game.add_player("Lois", 2); + game.play(12); +}
\ No newline at end of file diff --git a/graphs/cpp/hot_potato/player.cc b/graphs/cpp/hot_potato/player.cc new file mode 100644 index 0000000..3ab0f28 --- /dev/null +++ b/graphs/cpp/hot_potato/player.cc @@ -0,0 +1,63 @@ +// +// Created by martial.simon on 2/25/25. +// + +#include "player.hh" + +#include <iostream> +Player::Player(const std::string& name, size_t nb_presses) + : name_{ name } + , bomb_{ nullptr } + , nb_presses_{ nb_presses } + , next_{ nullptr } +{} +Player* Player::get_next() const +{ + return next_.get(); +} +void Player::set_next(std::unique_ptr<Player> next) +{ + next_ = std::move(next); +} +void Player::pass_bomb(Player& receiver) +{ + if (!this->has_bomb() || receiver.has_bomb()) + throw std::runtime_error{ + "Passer doesn't have the bomb or receiver already has it." + }; + std::cout << this->get_name() << " passes the bomb to " + << receiver.get_name() << ".\n"; + receiver.set_bomb(std::move(this->bomb_)); + this->bomb_ = nullptr; +} +void Player::press_bomb() +{ + if (bomb_ == nullptr) + throw std::runtime_error{ + "Can't press bomb if player doesn't have it." + }; + if (bomb_->has_exploded()) + return; + for (size_t i = 0; i < nb_presses_ && !bomb_->has_exploded(); ++i) + { + bomb_->tick(); + } +} +void Player::set_bomb(std::unique_ptr<Bomb> bomb) +{ + this->bomb_ = std::move(bomb); +} +const std::string& Player::get_name() const +{ + return name_; +} +bool Player::has_bomb() const +{ + return bomb_ != nullptr; +} +bool Player::is_dead() const +{ + if (has_bomb()) + return bomb_->has_exploded(); + return false; +}
\ No newline at end of file diff --git a/graphs/cpp/hot_potato/player.hh b/graphs/cpp/hot_potato/player.hh new file mode 100644 index 0000000..0439305 --- /dev/null +++ b/graphs/cpp/hot_potato/player.hh @@ -0,0 +1,25 @@ +#pragma once +#include <memory> +#include <string> + +#include "bomb.hh" + +class Player +{ +public: + Player(const std::string& name, size_t nb_presses); + Player* get_next() const; + void set_next(std::unique_ptr<Player> next); + void pass_bomb(Player& receiver); + void press_bomb(); + void set_bomb(std::unique_ptr<Bomb> bomb); + const std::string& get_name() const; + bool has_bomb() const; + bool is_dead() const; + +private: + std::string name_; + std::unique_ptr<Bomb> bomb_; + size_t nb_presses_; + std::unique_ptr<Player> next_; +};
\ No newline at end of file diff --git a/graphs/cpp/implements/implements.hh b/graphs/cpp/implements/implements.hh new file mode 100644 index 0000000..bd80d8e --- /dev/null +++ b/graphs/cpp/implements/implements.hh @@ -0,0 +1,47 @@ +#pragma once + +template <typename T, typename T2 = T> +concept impl_basic_op = requires(T a, T2 b) { + +a; + -a; + + -b; + +b; + + a + b; + a - b; + a* b; + a / b; + + b + a; + b - a; + b* a; + b / a; +}; + +template <typename T, typename T2 = T> +concept impl_modulo = requires(T a, T2 b) { + a % b; + b % a; +}; + +template <typename T, typename T2 = T> +concept impl_bitwise_op = requires(T a, T2 b) { + ~a; + ~b; + a & b; + a | b; + a ^ b; + a << b; + a >> b; + + b & a; + b | a; + b ^ a; + b << a; + b >> a; +}; + +template <typename T, typename T2 = T> +concept impl_arith_op = + impl_basic_op<T, T2> && impl_modulo<T, T2> && impl_bitwise_op<T, T2>;
\ No newline at end of file diff --git a/graphs/cpp/int_container/int_container.cc b/graphs/cpp/int_container/int_container.cc new file mode 100644 index 0000000..aabb5ab --- /dev/null +++ b/graphs/cpp/int_container/int_container.cc @@ -0,0 +1,83 @@ +#include "int_container.hh" +MyIntContainer::MyIntContainer(size_t size) + : current_size_{ 0 } + , max_size_{ size } + , elems_{ std::make_unique<int[]>(size) } +{} +void MyIntContainer::print() const +{ + if (current_size_ == 0) + return; + std::cout << elems_[0]; + for (size_t i = 1; i < current_size_; ++i) + { + std::cout << " | " << elems_[i]; + } + std::cout << "\n"; +} +size_t MyIntContainer::get_len() const +{ + return current_size_; +} +bool MyIntContainer::add(int elem) +{ + if (current_size_ == max_size_) + return false; + elems_[current_size_++] = elem; + return true; +} +std::optional<int> MyIntContainer::pop() +{ + if (current_size_ == 0) + return std::nullopt; + int res = elems_[--current_size_]; + elems_[current_size_] = -1; + return res; +} +std::optional<int> MyIntContainer::get(size_t position) const +{ + if (position >= current_size_) + return std::nullopt; + return elems_[position]; +} +std::optional<size_t> MyIntContainer::find(int elem) const +{ + size_t i; + for (i = 0; i < current_size_ && elems_[i] != elem; ++i) + continue; + if (i == current_size_) + return std::nullopt; + return i; +} +void swap(int& a, int& b) +{ + int tmp = a; + a = b; + b = tmp; +} +void MyIntContainer::sort() +{ + for (size_t i = 0; i < current_size_ - 1; i++) + { + bool flag = false; + for (size_t j = 0; j < current_size_ - i - 1; j++) + { + if (elems_[j] > elems_[j + 1]) + { + swap(elems_[j], elems_[j + 1]); + flag = true; + } + } + if (!flag) + break; + } +} +bool MyIntContainer::is_sorted() const +{ + for (size_t i = 1; i < current_size_; i++) + { + if (elems_[i - 1] > elems_[i]) + return false; + } + return true; +}
\ No newline at end of file diff --git a/graphs/cpp/int_container/int_container.hh b/graphs/cpp/int_container/int_container.hh new file mode 100644 index 0000000..2df772a --- /dev/null +++ b/graphs/cpp/int_container/int_container.hh @@ -0,0 +1,45 @@ +#pragma once + +#include <iostream> +#include <memory> +#include <optional> + +class MyIntContainer +{ +public: + MyIntContainer(size_t size); + + // Print the content of the container + void print() const; + + // Get the current number of elements inside the array + size_t get_len() const; + + // Add an element inside the array + bool add(int elem); + + // Get the last element inside the array and remove it + std::optional<int> pop(); + + // Get the element at a given position + std::optional<int> get(size_t position) const; + + // Get the index inside the array of a given element + std::optional<size_t> find(int elem) const; + + // Sort the array + void sort(); + + // Checks if the array is sorted + bool is_sorted() const; + +private: + // Current size of the elems_ array + size_t current_size_; + + // Maximum size of the elems_ array + size_t max_size_; + + // Array containing the elements + std::unique_ptr<int[]> elems_; +}; diff --git a/graphs/cpp/is_prime/is_prime.hh b/graphs/cpp/is_prime/is_prime.hh new file mode 100644 index 0000000..ae83249 --- /dev/null +++ b/graphs/cpp/is_prime/is_prime.hh @@ -0,0 +1,5 @@ +#pragma once + +constexpr bool is_prime(unsigned n); + +#include "is_prime.hxx"
\ No newline at end of file diff --git a/graphs/cpp/is_prime/is_prime.hxx b/graphs/cpp/is_prime/is_prime.hxx new file mode 100644 index 0000000..da2b94d --- /dev/null +++ b/graphs/cpp/is_prime/is_prime.hxx @@ -0,0 +1,21 @@ +#pragma once + +#include "is_prime.hh" +constexpr bool is_prime(unsigned n) +{ + if (n == 0 || n == 1) + { + return false; + } + else + { + for (unsigned i = 2; i <= n / 2; ++i) + { + if (n % i == 0) + { + return false; + } + } + } + return true; +}
\ No newline at end of file diff --git a/graphs/cpp/logger/CMakeLists.txt b/graphs/cpp/logger/CMakeLists.txt new file mode 100644 index 0000000..3a705e9 --- /dev/null +++ b/graphs/cpp/logger/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.21.2) +project(logger) + +add_compile_options(-Wall -Wextra -Werror -pedantic -std=c++20 -Wold-style-cast) + +add_library(logger_a SHARED logger.cc) +add_executable(logger main.cc) +target_link_libraries(logger PUBLIC logger_a)
\ No newline at end of file diff --git a/graphs/cpp/logger/logger.cc b/graphs/cpp/logger/logger.cc new file mode 100644 index 0000000..fa2fed1 --- /dev/null +++ b/graphs/cpp/logger/logger.cc @@ -0,0 +1,73 @@ +#include "logger.hh" + +#include <iostream> +#include <string> + +void LogMe::Logger::set_debug_level(logging_level level) +{ + level_ = level; +} +void LogMe::Logger::log(logging_level level, const std::string& msg) +{ + if (level_ >= level) + { + switch (level) + { + case DEBUG: + debug(msg); + break; + case INFO: + info(msg); + break; + case WARN: + warn(msg); + break; + case CRITICAL: + critical(msg); + break; + case ERROR: + error(msg); + break; + } + } +} + +void LogMe::Logger::debug(const std::string& msg) +{ + if (!output_stream_.is_open()) + std::cerr << "[DEBUG] - " << msg << "\n"; + else + output_stream_ << "[DEBUG] - " << msg << "\n"; +} + +void LogMe::Logger::info(const std::string& msg) +{ + if (!output_stream_.is_open()) + std::cerr << "[INFO] - " << msg << "\n"; + else + output_stream_ << "[INFO] - " << msg << "\n"; +} + +void LogMe::Logger::warn(const std::string& msg) +{ + if (!output_stream_.is_open()) + std::cerr << "[WARN] - " << msg << "\n"; + else + output_stream_ << "[WARN] - " << msg << "\n"; +} + +void LogMe::Logger::error(const std::string& msg) +{ + if (!output_stream_.is_open()) + std::cerr << "[ERROR] - " << msg << "\n"; + else + output_stream_ << "[ERROR] - " << msg << "\n"; +} + +void LogMe::Logger::critical(const std::string& msg) +{ + if (!output_stream_.is_open()) + std::cerr << "[CRITICAL] - " << msg << "\n"; + else + output_stream_ << "[CRITICAL] - " << msg << "\n"; +}
\ No newline at end of file diff --git a/graphs/cpp/logger/logger.hh b/graphs/cpp/logger/logger.hh new file mode 100644 index 0000000..4b3a43b --- /dev/null +++ b/graphs/cpp/logger/logger.hh @@ -0,0 +1,47 @@ +#pragma once +#include <fstream> +#include <string> + +namespace LogMe +{ + enum logging_level + { + DEBUG, + INFO, + WARN, + ERROR, + CRITICAL + }; + class Logger + { + public: + Logger(logging_level level, const std::string& log_file) + : level_{ level } + { + output_stream_.open(log_file); + } + Logger(logging_level level) + : level_{ level } + {} + + ~Logger() + { + if (output_stream_.is_open()) + { + output_stream_.close(); + } + } + + void set_debug_level(logging_level level); + void log(logging_level level, const std::string& msg); + void debug(const std::string& msg); + void info(const std::string& msg); + void warn(const std::string& msg); + void critical(const std::string& msg); + void error(const std::string& msg); + + private: + logging_level level_; + std::ofstream output_stream_; + }; +} // namespace LogMe diff --git a/graphs/cpp/logger/main.cc b/graphs/cpp/logger/main.cc new file mode 100644 index 0000000..483ffdd --- /dev/null +++ b/graphs/cpp/logger/main.cc @@ -0,0 +1,13 @@ +#include <iostream> + +#include "logger.hh" + +int main() +{ + LogMe::Logger logger{ LogMe::INFO }; + logger.log(LogMe::INFO, "Program starting."); + std::cout << "Hello, World!" << std::endl; + logger.log(LogMe::ERROR, "Error log."); + logger.log(LogMe::DEBUG, "Program end."); + return 0; +}
\ No newline at end of file diff --git a/graphs/cpp/lookup_table/fibo.cc b/graphs/cpp/lookup_table/fibo.cc new file mode 100644 index 0000000..80b72b1 --- /dev/null +++ b/graphs/cpp/lookup_table/fibo.cc @@ -0,0 +1,15 @@ +#include "fibo.hh" + +long Fibo::operator()(int x) +{ + if (x <= 1) + return x; + + std::optional<long> opt_lookup_table = lookup_table_.get(x); + if (opt_lookup_table) + return *opt_lookup_table; + + auto res = (*this)(x - 1) + (*this)(x - 2); + lookup_table_.set(x, res); + return res; +} diff --git a/graphs/cpp/lookup_table/fibo.hh b/graphs/cpp/lookup_table/fibo.hh new file mode 100644 index 0000000..8f30851 --- /dev/null +++ b/graphs/cpp/lookup_table/fibo.hh @@ -0,0 +1,12 @@ +#pragma once + +#include "lookup_table.hh" + +class Fibo +{ +private: + LookupTable lookup_table_; + +public: + long operator()(int x); +}; diff --git a/graphs/cpp/lookup_table/lookup_table.cc b/graphs/cpp/lookup_table/lookup_table.cc new file mode 100644 index 0000000..0440e61 --- /dev/null +++ b/graphs/cpp/lookup_table/lookup_table.cc @@ -0,0 +1,14 @@ +// +// Created by martial.simon on 2/26/25. +// +#include "lookup_table.hh" +std::optional<long> LookupTable::get(int x) +{ + if (table_.count(x) == 0) + return std::nullopt; + return table_.at(x); +} +void LookupTable::set(int x, long value) +{ + table_.insert_or_assign(x, value); +}
\ No newline at end of file diff --git a/graphs/cpp/lookup_table/lookup_table.hh b/graphs/cpp/lookup_table/lookup_table.hh new file mode 100644 index 0000000..eb25d43 --- /dev/null +++ b/graphs/cpp/lookup_table/lookup_table.hh @@ -0,0 +1,14 @@ +#pragma once + +#include <optional> +#include <unordered_map> + +class LookupTable +{ +public: + std::optional<long> get(int x); + void set(int x, long value); + +private: + std::unordered_map<int, long> table_; +}; diff --git a/graphs/cpp/lookup_table/lookup_table_test.cc b/graphs/cpp/lookup_table/lookup_table_test.cc new file mode 100644 index 0000000..a17101e --- /dev/null +++ b/graphs/cpp/lookup_table/lookup_table_test.cc @@ -0,0 +1,9 @@ +#include <iostream> + +#include "fibo.hh" + +int main() +{ + Fibo fibo; + std::cout << fibo(42) << '\n'; +} diff --git a/graphs/cpp/merge_sort/merge_sort.cc b/graphs/cpp/merge_sort/merge_sort.cc new file mode 100644 index 0000000..ed7afdf --- /dev/null +++ b/graphs/cpp/merge_sort/merge_sort.cc @@ -0,0 +1,12 @@ +#include "merge_sort.hh" +void merge_sort(iterator_type begin, iterator_type end) +{ + if (const auto diff = distance(begin, end); diff > 1) + { + const auto m = begin + diff / 2; + + merge_sort(begin, m); + merge_sort(m, end); + return std::inplace_merge(begin, m, end); + } +}
\ No newline at end of file diff --git a/graphs/cpp/merge_sort/merge_sort.hh b/graphs/cpp/merge_sort/merge_sort.hh new file mode 100644 index 0000000..7e7f02f --- /dev/null +++ b/graphs/cpp/merge_sort/merge_sort.hh @@ -0,0 +1,16 @@ +#pragma once + +#include <algorithm> +#include <vector> + +#define while forbidden_use_of_while +#define for forbidden_use_of_for +#define goto forbidden_use_of_goto +#define sort forbidden_use_of_sort +#define partial_sort forbidden_use_of_sort +#define stable_sort forbidden_use_of_sort +#define sort_heap forbidden_use_of_sort + +using iterator_type = std::vector<int>::iterator; + +void merge_sort(iterator_type begin, iterator_type end); diff --git a/graphs/cpp/my_nfts/auction.cc b/graphs/cpp/my_nfts/auction.cc new file mode 100644 index 0000000..534c61d --- /dev/null +++ b/graphs/cpp/my_nfts/auction.cc @@ -0,0 +1,45 @@ +#include "auction.hh" + +#include <algorithm> +Auction::Auction(Person& organizer, NFT nft, uint initial_bid) + : organizer_{ organizer } + , nft_{ std::move(nft) } + , highest_bidder_{ nullptr } + , highest_bid_{ initial_bid } +{ + if (!nft_ || nft_->empty()) + throw std::invalid_argument{ "Invalid nft!" }; +} +Auction::~Auction() +{ + if (highest_bidder_ == nullptr) + organizer_.add_nft(std::move(nft_)); + else + { + highest_bidder_->add_nft(std::move(nft_)); + organizer_.add_money(highest_bid_); + } +} +bool Auction::bid(Person& person, uint money) +{ + if (money > highest_bid_) + { + if (highest_bidder_ == nullptr) + highest_bidder_ = &person; + else + highest_bidder_->add_money(highest_bid_); + highest_bid_ = money; + highest_bidder_ = &person; + highest_bidder_->remove_money(money); + return true; + } + return false; +} +const std::string& Auction::get_nft_name() const +{ + return *nft_; +} +uint Auction::get_highest_bid() const +{ + return highest_bid_; +}
\ No newline at end of file diff --git a/graphs/cpp/my_nfts/auction.hh b/graphs/cpp/my_nfts/auction.hh new file mode 100644 index 0000000..9a1d162 --- /dev/null +++ b/graphs/cpp/my_nfts/auction.hh @@ -0,0 +1,34 @@ +#pragma once + +#include "nft.hh" +#include "person.hh" + +// Smart contract to auction a NFT. +// It is a RAII class. +class Auction +{ +public: + // Start the auction with the given (non-null) NFT. + Auction(Person& organizer, NFT nft, uint initial_bid); + // Close the auction. + ~Auction(); + + // https://en.cppreference.com/w/cpp/language/rule_of_three#Rule_of_five + Auction(const Auction&&) = delete; + Auction(const Auction&) = delete; + Auction& operator=(const Auction&&) = delete; + Auction& operator=(const Auction&) = delete; + + // Allow a person to bid at the auction. + bool bid(Person& person, uint money); + + // Getters for the nft name and highest bid. + const std::string& get_nft_name() const; + uint get_highest_bid() const; + +private: + Person& organizer_; + NFT nft_; + Person* highest_bidder_; + uint highest_bid_; +}; diff --git a/graphs/cpp/my_nfts/main.cc b/graphs/cpp/my_nfts/main.cc new file mode 100644 index 0000000..2e9f462 --- /dev/null +++ b/graphs/cpp/my_nfts/main.cc @@ -0,0 +1,37 @@ +#include <iostream> + +#include "auction.hh" +#include "person.hh" + +int main(void) +{ + auto p1 = Person("JP", 100); + auto p2 = Person("Claude", 50); + + p1.add_nft(create_nft("Singe")); + + std::cout << p1; + std::cout << p2; + + p2.add_nft(p1.remove_nft("Singe")); + + std::cout << p1; + std::cout << p2; + + auto p3 = Person("Marie", 20); + std::cout << p1; + std::cout << p2; + std::cout << p3; + + { + Auction auction(p2, p2.remove_nft("Singe"), 10); + std::cout << p1; + std::cout << p2; + std::cout << p3; + + auction.bid(p1, 20); + } + std::cout << p1; + std::cout << p2; + std::cout << p3; +} diff --git a/graphs/cpp/my_nfts/nft.hh b/graphs/cpp/my_nfts/nft.hh new file mode 100644 index 0000000..2147545 --- /dev/null +++ b/graphs/cpp/my_nfts/nft.hh @@ -0,0 +1,15 @@ +#pragma once + +#include <memory> +#include <string> + +// NFT declaration +using NFT = std::unique_ptr<std::string>; + +// Create an empty NFT (convient in some scenarios). +NFT create_empty_nft(); +// Create a NFT with the given name. +NFT create_nft(const std::string& name); + +// Define the functions in the nft.hxx file. +#include "nft.hxx" diff --git a/graphs/cpp/my_nfts/nft.hxx b/graphs/cpp/my_nfts/nft.hxx new file mode 100644 index 0000000..083f10f --- /dev/null +++ b/graphs/cpp/my_nfts/nft.hxx @@ -0,0 +1,11 @@ +#pragma once + +#include "nft.hh" +inline NFT create_empty_nft() +{ + return nullptr; +} +inline NFT create_nft(const std::string& name) +{ + return std::make_unique<std::string>(name); +}
\ No newline at end of file diff --git a/graphs/cpp/my_nfts/person.cc b/graphs/cpp/my_nfts/person.cc new file mode 100644 index 0000000..cf4b291 --- /dev/null +++ b/graphs/cpp/my_nfts/person.cc @@ -0,0 +1,61 @@ +#include "person.hh" + +#include <algorithm> +Person::Person(const std::string& name, uint money) + : name_{ name } + , money_{ money } +{} +std::vector<std::string> Person::enumerate_nfts() const +{ + std::vector<std::string> res; + for (auto nft = nfts_.begin(); nft != nfts_.end(); nft++) + { + res.push_back(**nft); + } + return res; +} +void Person::add_nft(NFT nft) +{ + nfts_.push_back(std::move(nft)); +} +NFT Person::remove_nft(const std::string& name) +{ + auto pos = std::find_if(nfts_.begin(), nfts_.end(), + [&](NFT const& nft) { return *nft == name; }); + if (pos == nfts_.end()) + return create_empty_nft(); + nfts_.erase(pos); + return create_nft(name); +} +void Person::add_money(uint money) +{ + money_ += money; +} +bool Person::remove_money(uint money) +{ + if (money > money_) + return false; + money_ -= money; + return true; +} +uint Person::get_money() const +{ + return money_; +} +const std::string& Person::get_name() const +{ + return name_; +} +std::ostream& operator<<(std::ostream& os, const Person& p) +{ + os << "Name: " << p.get_name() << "\nMoney: " << p.get_money() << "\nNFTs:"; + if (const std::vector<std::string> nfts = p.enumerate_nfts(); !nfts.empty()) + { + for (size_t i = 0; i < nfts.size(); ++i) + { + os << " " << nfts.at(i); + } + } + os << "\n"; + return os; +} diff --git a/graphs/cpp/my_nfts/person.hh b/graphs/cpp/my_nfts/person.hh new file mode 100644 index 0000000..90a2e16 --- /dev/null +++ b/graphs/cpp/my_nfts/person.hh @@ -0,0 +1,39 @@ +#pragma once + +#include <ostream> +#include <vector> + +#include "nft.hh" + +// A person +class Person +{ +public: + // Initiliaze its member attributes. + Person(const std::string& name, uint money); + + // Returns the list of NFTs it owns. + std::vector<std::string> enumerate_nfts() const; + + // Give it a NFT. + void add_nft(NFT nft); + // Take away a NFT. + NFT remove_nft(const std::string& name); + + // Add money. + void add_money(uint money); + // Remove money, if possible. + bool remove_money(uint money); + + // Getters for money and name. + uint get_money() const; + const std::string& get_name() const; + +private: + std::string name_; + uint money_; + std::vector<NFT> nfts_; +}; + +// Write informations about the person on the given stream. +std::ostream& operator<<(std::ostream& os, const Person& p); diff --git a/graphs/cpp/path/path.cc b/graphs/cpp/path/path.cc new file mode 100644 index 0000000..bff3a55 --- /dev/null +++ b/graphs/cpp/path/path.cc @@ -0,0 +1,10 @@ +#include "path.hh" + +Path& Path::join(const std::string& tail, bool is_file) +{ + if (final_) + return *this; + path_.push_back(tail); + final_ = is_file; + return *this; +}
\ No newline at end of file diff --git a/graphs/cpp/path/path.hh b/graphs/cpp/path/path.hh new file mode 100644 index 0000000..0a09d05 --- /dev/null +++ b/graphs/cpp/path/path.hh @@ -0,0 +1,25 @@ +#pragma once + +#include <string> +#include <vector> + +class Path +{ +public: + Path() = default; + virtual ~Path() = default; + + /* + ** Return the complete path as a string. + */ + virtual std::string to_string() const = 0; + + /* + ** Add a directory or a file at the end of the path. + */ + virtual Path& join(const std::string& tail, bool is_file = false); + +protected: + std::vector<std::string> path_; + bool final_ = false; +}; diff --git a/graphs/cpp/path/path_example.cc b/graphs/cpp/path/path_example.cc new file mode 100644 index 0000000..f35c605 --- /dev/null +++ b/graphs/cpp/path/path_example.cc @@ -0,0 +1,22 @@ +#include <iostream> + +#include "unix_path.hh" +#include "windows_path.hh" + +int main() +{ + auto windows_path = WindowsPath('E'); + + std::cout << windows_path.join("Users").join("YAKA").join("cpp").to_string() + << '\n'; /* E:\Users\YAKA\cpp\ */ + + auto unix_path = UnixPath(); + + std::cout << unix_path.join("home").join("yaka").join("cpp").to_string() + << '\n'; // /home/yaka/cpp/ + + std::cout << unix_path.join("main.cc", true).to_string() + << '\n'; // /home/yaka/cpp/main.cc + + return 0; +} diff --git a/graphs/cpp/path/unix_path.cc b/graphs/cpp/path/unix_path.cc new file mode 100644 index 0000000..dfd51b5 --- /dev/null +++ b/graphs/cpp/path/unix_path.cc @@ -0,0 +1,25 @@ +// +// Created by martial.simon on 2/25/25. +// + +#include "unix_path.hh" + +#include <sstream> +UnixPath::UnixPath() + : Path() +{} + +std::string UnixPath::to_string() const +{ + if (path_.empty()) + return "/"; + std::ostringstream os; + os << "/" << path_[0]; + for (size_t i = 1; i < path_.size(); i++) + { + os << "/" << path_[i]; + } + if (!final_) + os << "/"; + return os.str(); +}
\ No newline at end of file diff --git a/graphs/cpp/path/unix_path.hh b/graphs/cpp/path/unix_path.hh new file mode 100644 index 0000000..22976ed --- /dev/null +++ b/graphs/cpp/path/unix_path.hh @@ -0,0 +1,13 @@ +// +// Created by martial.simon on 2/25/25. +// + +#pragma once +#include "path.hh" + +class UnixPath : public Path +{ +public: + UnixPath(); + std::string to_string() const override; +}; diff --git a/graphs/cpp/path/windows_path.cc b/graphs/cpp/path/windows_path.cc new file mode 100644 index 0000000..cc94afa --- /dev/null +++ b/graphs/cpp/path/windows_path.cc @@ -0,0 +1,37 @@ +// +// Created by martial.simon on 2/25/25. +// + +#include "windows_path.hh" + +#include <sstream> +WindowsPath::WindowsPath(char drive) + : Path() +{ + path_.push_back(std::string{ drive } + std::string{ ':' }); +} +std::string WindowsPath::to_string() const +{ + if (path_.empty()) + return ""; + std::ostringstream os; + os << path_[0]; + for (size_t i = 1; i < path_.size(); i++) + { + os << "\\" << path_[i]; + } + if (!final_) + os << "\\"; + return os.str(); +} +Path& WindowsPath::join(const std::string& tail, bool is_file) +{ + // :, ", |, ?, * + if (tail.find(':') != std::string::npos + || tail.find('\"') != std::string::npos + || tail.find('|') != std::string::npos + || tail.find('?') != std::string::npos + || tail.find('*') != std::string::npos) + return *this; + return Path::join(tail, is_file); +}
\ No newline at end of file diff --git a/graphs/cpp/path/windows_path.hh b/graphs/cpp/path/windows_path.hh new file mode 100644 index 0000000..4bd9e2b --- /dev/null +++ b/graphs/cpp/path/windows_path.hh @@ -0,0 +1,14 @@ +// +// Created by martial.simon on 2/25/25. +// + +#pragma once +#include "path.hh" + +class WindowsPath : public Path +{ +public: + WindowsPath(char drive); + std::string to_string() const override; + Path& join(const std::string& tail, bool is_file = false) override; +}; diff --git a/graphs/cpp/point/CMakeLists.txt b/graphs/cpp/point/CMakeLists.txt new file mode 100644 index 0000000..0933e1c --- /dev/null +++ b/graphs/cpp/point/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.30) +project(point) + +set(CMAKE_CXX_STANDARD 20) + +add_executable(point main.cc + point.cc) diff --git a/graphs/cpp/point/main.cc b/graphs/cpp/point/main.cc new file mode 100644 index 0000000..df28b27 --- /dev/null +++ b/graphs/cpp/point/main.cc @@ -0,0 +1,7 @@ +#include <iostream> + +int main() +{ + std::cout << "Hello, World!" << std::endl; + return 0; +}
\ No newline at end of file diff --git a/graphs/cpp/point/point.cc b/graphs/cpp/point/point.cc new file mode 100644 index 0000000..557cab9 --- /dev/null +++ b/graphs/cpp/point/point.cc @@ -0,0 +1,14 @@ +#include "point.hh" + +#include <iostream> + +void Point::display() const +{ + std::cout << "(" << x_ << ", " << y_ << ")"; +} + +void Point::shift(const int dx, const int dy) +{ + x_ += dx; + y_ += dy; +} diff --git a/graphs/cpp/point/point.hh b/graphs/cpp/point/point.hh new file mode 100644 index 0000000..1e33fc8 --- /dev/null +++ b/graphs/cpp/point/point.hh @@ -0,0 +1,12 @@ +#pragma once + +class Point +{ +public: + void display() const; + void shift(int dx, int dy); + +private: + int x_ = 0; + int y_ = 0; +};
\ No newline at end of file diff --git a/graphs/cpp/ref_swap/main.cc b/graphs/cpp/ref_swap/main.cc new file mode 100644 index 0000000..487ab6d --- /dev/null +++ b/graphs/cpp/ref_swap/main.cc @@ -0,0 +1,17 @@ +#include <iostream> + +#include "ref_swap.hh" + +int main() +{ + int a = 3; + int b = 19; + + std::cout << "Before: a = " << a << ", b = " << b << '\n'; + ref_swap(a, b); + std::cout << "After: a = " << a << ", b = " << b << '\n'; + + std::cout << "Before: a = " << a << ", b = " << b << '\n'; + ptr_swap(&a, &b); + std::cout << "After: a = " << a << ", b = " << b << '\n'; +} diff --git a/graphs/cpp/ref_swap/ref_swap.cc b/graphs/cpp/ref_swap/ref_swap.cc new file mode 100644 index 0000000..44cb203 --- /dev/null +++ b/graphs/cpp/ref_swap/ref_swap.cc @@ -0,0 +1,18 @@ +// +// Created by martial.simon on 2/24/25. +// +void ref_swap(int& a, int& b) +{ + int tmp = a; + a = b; + b = tmp; +} + +void ptr_swap(int* a, int* b) +{ + if (!a || !b) + return; + int tmp = *a; + *a = *b; + *b = tmp; +}
\ No newline at end of file diff --git a/graphs/cpp/ref_swap/ref_swap.hh b/graphs/cpp/ref_swap/ref_swap.hh new file mode 100644 index 0000000..1f194b3 --- /dev/null +++ b/graphs/cpp/ref_swap/ref_swap.hh @@ -0,0 +1,5 @@ +#pragma once + +void ref_swap(int& a, int& b); + +void ptr_swap(int* a, int* b); diff --git a/graphs/cpp/replace/inputfile b/graphs/cpp/replace/inputfile new file mode 100644 index 0000000..b4e5a2f --- /dev/null +++ b/graphs/cpp/replace/inputfile @@ -0,0 +1 @@ +abcabcbc
\ No newline at end of file diff --git a/graphs/cpp/replace/replace.cc b/graphs/cpp/replace/replace.cc new file mode 100644 index 0000000..c24bf05 --- /dev/null +++ b/graphs/cpp/replace/replace.cc @@ -0,0 +1,39 @@ +#include "replace.hh" + +#include <fstream> +#include <iostream> +#include <string> + +void replace(const std::string& input_filename, + const std::string& output_filename, const std::string& src_token, + const std::string& dst_token) +{ + std::ofstream file_out; + file_out.open(output_filename); + + if (!file_out.is_open()) + { + std::cerr << "Cannot write output file\n"; + return; + } + + std::ifstream file_in; + file_in.open(input_filename); + if (!file_in.is_open()) + { + std::cerr << "Cannot open input file\n"; + return; + } + + std::string token; + while (std::getline(file_in, token)) + { + std::string::size_type n = 0; + while ((n = token.find(src_token, n)) != std::string::npos) + { + token.replace(n, src_token.size(), dst_token); + n += dst_token.size(); + } + file_out << token << "\n"; + } +}
\ No newline at end of file diff --git a/graphs/cpp/replace/replace.hh b/graphs/cpp/replace/replace.hh new file mode 100644 index 0000000..cbb2e46 --- /dev/null +++ b/graphs/cpp/replace/replace.hh @@ -0,0 +1,6 @@ +#pragma once +#include <string> + +void replace(const std::string& input_filename, + const std::string& output_filename, const std::string& src_token, + const std::string& dst_token);
\ No newline at end of file diff --git a/graphs/cpp/replace/test_replace.cc b/graphs/cpp/replace/test_replace.cc new file mode 100644 index 0000000..be7a488 --- /dev/null +++ b/graphs/cpp/replace/test_replace.cc @@ -0,0 +1,16 @@ +#include <iostream> + +#include "replace.hh" + +int main(int argc, char** argv) +{ + if (argc < 5) + { + std::cerr << "Usage: INPUT_FILE OUTPUT_FILE SRC_TOKEN DST_TOKEN\n"; + return 1; + } + + replace(argv[1], argv[2], argv[3], argv[4]); + + return 0; +} diff --git a/graphs/cpp/singleton/singleton.cc b/graphs/cpp/singleton/singleton.cc new file mode 100644 index 0000000..711e702 --- /dev/null +++ b/graphs/cpp/singleton/singleton.cc @@ -0,0 +1,21 @@ +// +// Created by martial.simon on 2/27/25. +// + +#include "singleton.hh" + +#include <iostream> +#include <string> + +void Logger::open_log_file(const std::string& file) +{ + std::cout << "LOG: Opening file " << file << "\n"; +} +void Logger::write_to_log_file() +{ + std::cout << "LOG: Writing into log file ...\n"; +} +void Logger::close_log_file() +{ + std::cout << "LOG: Closing log file ...\n"; +} diff --git a/graphs/cpp/singleton/singleton.hh b/graphs/cpp/singleton/singleton.hh new file mode 100644 index 0000000..715a85f --- /dev/null +++ b/graphs/cpp/singleton/singleton.hh @@ -0,0 +1,33 @@ +// +// Created by martial.simon on 2/27/25. +// + +#pragma once +#include <string> + +template <typename T> +class Singleton +{ +protected: + Singleton() = default; + +private: + Singleton(const Singleton<T>&) = delete; + Singleton& operator=(const Singleton<T>&) = delete; + +public: + static T& instance(); +}; + +class Logger : public Singleton<Logger> +{ + Logger() = default; + friend class Singleton<Logger>; + +public: + void open_log_file(const std::string& file); + void write_to_log_file(); + void close_log_file(); +}; + +#include "singleton.hxx"
\ No newline at end of file diff --git a/graphs/cpp/singleton/singleton.hxx b/graphs/cpp/singleton/singleton.hxx new file mode 100644 index 0000000..04a36b8 --- /dev/null +++ b/graphs/cpp/singleton/singleton.hxx @@ -0,0 +1,9 @@ +#pragma once + +#include "singleton.hh" +template <typename T> +T& Singleton<T>::instance() +{ + static T instance_; + return instance_; +}
\ No newline at end of file diff --git a/graphs/cpp/smtptr/main.cc b/graphs/cpp/smtptr/main.cc new file mode 100644 index 0000000..a574d45 --- /dev/null +++ b/graphs/cpp/smtptr/main.cc @@ -0,0 +1,20 @@ +#include "shared_pointer.hh" + +int main() +{ + // Lifetime of the data + { + SharedPointer<int> p2; + { + SharedPointer<int> p1{ new int{ 5 } }; + p2 = p1; // Now both SharedPointers own the memory + } + // p1 is freed, but the int pointer remains + // Memory still exists, due to p2 + std::cout << "Value of p2: " << *p2 << std::endl; // Output: 5 + } + // p2 is freed, and since no one else owns the memory, + // the int pointer is freed too + + return 0; +} diff --git a/graphs/cpp/smtptr/shared_pointer.hh b/graphs/cpp/smtptr/shared_pointer.hh new file mode 100644 index 0000000..cc24243 --- /dev/null +++ b/graphs/cpp/smtptr/shared_pointer.hh @@ -0,0 +1,166 @@ +#pragma once + +#include <cassert> +#include <iostream> +#include <string> + +template <typename T> +class SharedPointer +{ +public: + // The type pointed to. + using element_type = T; + + /** + ** \brief Construct a counted reference to a newly allocated object. + */ + SharedPointer(element_type* p = nullptr); + + /** + ** \brief Destroy the SharedPointer. + ** The object pointed to is destroyed only if it is not referenced anymore. + ** Take care to free everything ... + */ + ~SharedPointer(); + + /** + ** \brief Copy constructor. + ** \return A new SharedPointer, pointing + ** to the underlying data of \a other. + ** + ** Although the implementation is subsumed by the previous, more + ** generic one, the C++ standard still mandates this specific + ** signature. Otherwise, the compiler will provide a default + ** implementation, which is of course wrong. Note that the + ** same applies for the assignment operator. + */ + SharedPointer(const SharedPointer<element_type>& other); + + /// \name Assignments. + /// \{ + + /** + ** \brief Replace the underlying data with \a p + ** A call to \c reset is strictly equivalent to: + ** \code + ** r = SharedPointer<element_type>(p); + ** \endcode + ** This line implicitly calls the destructor of \a r before assigning + ** it a new value. + ** \warning You can't reset your \c SharedPointer with the + ** same pointer as the current one. In this case, nothing should + ** be done. + ** \warning Be mindful of other \c SharedPointers + ** which could also be pointing to the same data. + */ + void reset(element_type* p); + + /** + ** \brief Reference assignment + ** Its behavior is similar to \c reset() but you + ** have to use the existing SharedPointer \a other + ** instead of creating a new instance. + */ + SharedPointer<element_type>& + operator=(const SharedPointer<element_type>& other); + /// \} + + /// \name Access to data. + /// \{ + + // Access via a reference. + element_type& operator*() const; + // Access via a pointer. + element_type* operator->() const; + + // Returns the underlying data pointer. + element_type* get() const; + + // Returns the number of SharedPointer objects referring to the same managed + // object + long use_count() const; + /// \} + + /// \name Equality operators. + /// \{ + + /** + ** \brief Reference comparison. + ** Returns true if the two references point to the same object. + */ + template <typename U> + bool operator==(const SharedPointer<U>& rhs) const; + + /** + ** \brief Reference comparison. + ** Returns false if the two references point to the same object. + */ + template <typename U> + bool operator!=(const SharedPointer<U>& rhs) const; + + /** + ** \brief Reference comparison. + ** Returns true if this points to \a p. + */ + bool operator==(const element_type* p) const; + + /** + ** \brief Reference comparison. + ** Returns false if this points to \a p. + */ + bool operator!=(const element_type* p) const; + + /** + ** \brief Move assignment operator for SharedPointer. + ** + ** This operator transfers ownership of the managed object from the + ** \a other to this SharePointer. + ** After the assignment, the \a other will be empty. + ** \warning Don't forget to update the reference counter. + ** + ** Returns a reference to this SharedPointer. + */ + SharedPointer<element_type>& operator=(SharedPointer&& other) noexcept; + + /** + ** \brief Move constructor for SharedPointer. + ** + ** This constructor transfers ownership of the managed object from \a other + ** SharedPointer to the newly created SharedPointer. + ** + */ + SharedPointer(SharedPointer&& other); + + /// \} + + /** + ** \brief Test for validity + ** Returns true if the reference is valid, i.e. it points to an object. + ** This conversion operator allows users to write: + ** + ** \code + ** SharedPointer<int> p1; + ** if (p1) // Here false + ** ... + ** \endcode + */ + operator bool() const; + + /** + ** \brief Test fellowship. + ** Returns true if the SharedPointer points to an object which + ** is of the specified type. + ** Look at the given example file shared_pointer_is_a.cc + ** to better understand its purpose. + */ + template <typename U> + bool is_a() const; + +private: + // Pointer to the underlying data. + element_type* data_; + // A counter shared between all ref pointers to \a data_. + long* count_; +}; + +#include "shared_pointer.hxx" diff --git a/graphs/cpp/smtptr/shared_pointer.hxx b/graphs/cpp/smtptr/shared_pointer.hxx new file mode 100644 index 0000000..fbc0792 --- /dev/null +++ b/graphs/cpp/smtptr/shared_pointer.hxx @@ -0,0 +1,144 @@ +#pragma once +#include "shared_pointer.hh" +template <typename T> +SharedPointer<T>::SharedPointer(element_type* p) +{ + if (p == nullptr) + { + data_ = nullptr; + count_ = nullptr; + } + else + { + data_ = p; + count_ = new long{ 1 }; + } +} +template <typename T> +SharedPointer<T>::~SharedPointer() +{ + if (count_ != nullptr) + { + (*count_)--; + if (*count_ == 0) + { + delete count_; + if (data_ != nullptr) + delete data_; + } + } +} +template <typename T> +SharedPointer<T>::SharedPointer(const SharedPointer<element_type>& other) +{ + this->~SharedPointer(); + data_ = other.data_; + if (data_ == nullptr) + count_ = nullptr; + count_ = other.count_; + if (count_ != nullptr) + (*count_)++; +} +template <typename T> +void SharedPointer<T>::reset(element_type* p) +{ + if (data_ == p) + return; + this->~SharedPointer(); + data_ = p; + if (p == nullptr) + count_ = nullptr; + else + count_ = new long{ 1 }; +} +template <typename T> +SharedPointer<T>& SharedPointer<T>::operator=(const SharedPointer<T>& other) +{ + this->~SharedPointer(); + + data_ = other.data_; + count_ = other.count_; + if (nullptr != other.data_) + { + (*this->count_)++; + } + return *this; +} +template <typename T> +T& SharedPointer<T>::operator*() const +{ + return *data_; +} + +template <typename T> +T* SharedPointer<T>::operator->() const +{ + return data_; +} +template <typename T> +T* SharedPointer<T>::get() const +{ + return data_; +} +template <typename T> +long SharedPointer<T>::use_count() const +{ + if (count_ == nullptr) + return 0; + return *count_; +} +template <typename T> +template <typename U> +bool SharedPointer<T>::operator==(const SharedPointer<U>& rhs) const +{ + if (rhs.data_ == this->data_) + return true; + return false; +} +template <typename T> +template <typename U> +bool SharedPointer<T>::operator!=(const SharedPointer<U>& rhs) const +{ + return !(*this == rhs); +} +template <typename T> +bool SharedPointer<T>::operator==(const T* p) const +{ + return this->data_ == p; +} +template <typename T> +bool SharedPointer<T>::operator!=(const T* p) const +{ + return this->data_ != p; +} +template <typename T> +SharedPointer<T>& SharedPointer<T>::operator=(SharedPointer<T>&& other) noexcept +{ + this->~SharedPointer(); + data_ = other.data_; + count_ = other.count_; + other.data_ = nullptr; + other.count_ = nullptr; + return *this; +} +template <typename T> +SharedPointer<T>::SharedPointer(SharedPointer&& other) +{ + this->~SharedPointer(); + data_ = other.data_; + count_ = other.count_; + + other.data_ = nullptr; + other.count_ = nullptr; +} +template <typename T> +SharedPointer<T>::operator bool() const +{ + return data_ != nullptr; +} +template <typename T> +template <typename U> +bool SharedPointer<T>::is_a() const +{ + return dynamic_cast<U*>(data_); +}
\ No newline at end of file diff --git a/graphs/cpp/smtptr/shared_pointer_is_a.cc b/graphs/cpp/smtptr/shared_pointer_is_a.cc new file mode 100644 index 0000000..b6dcb95 --- /dev/null +++ b/graphs/cpp/smtptr/shared_pointer_is_a.cc @@ -0,0 +1,47 @@ +#include "shared_pointer.hh" + +class Animal +{ +public: + virtual ~Animal() + {} +}; + +class Cat : public Animal +{ +public: + void meow() + { + std::cout << "Meow!\n"; + } +}; + +class Dog : public Animal +{ +public: + void bark() + { + std::cout << "Woof!\n"; + } +}; + +int main() +{ + SharedPointer<Animal> animalPtr{ new Cat }; + if (animalPtr.is_a<Cat>()) + { // true + std::cout << "The pointer points to a Cat.\n"; + } + + SharedPointer<Animal> animalPtr2{ new Dog }; + if (animalPtr2.is_a<Cat>()) + { // false + std::cout << "The pointer points to a Cat.\n"; + } + else if (animalPtr2.is_a<Dog>()) + { + std::cout << "The pointer points to a Dog.\n"; + } + + return 0; +} diff --git a/graphs/cpp/stdin_to_file/stdin_to_file.cc b/graphs/cpp/stdin_to_file/stdin_to_file.cc new file mode 100644 index 0000000..c1519e3 --- /dev/null +++ b/graphs/cpp/stdin_to_file/stdin_to_file.cc @@ -0,0 +1,20 @@ +#include "stdin_to_file.hh" + +#include <fstream> +#include <iostream> +long int stdin_to_file(const std::string& filename) +{ + std::ofstream file_out; + std::string token; + // trying to open output file "data.out" + file_out.open(filename); + size_t res = 0; + // Read until eof or an error occurs + while (std::cin >> token) + { + res++; + file_out << token << '\n'; + } + // stream is closed at the end of the scope + return res; +}
\ No newline at end of file diff --git a/graphs/cpp/stdin_to_file/stdin_to_file.hh b/graphs/cpp/stdin_to_file/stdin_to_file.hh new file mode 100644 index 0000000..9aac89d --- /dev/null +++ b/graphs/cpp/stdin_to_file/stdin_to_file.hh @@ -0,0 +1,6 @@ +#pragma once + +#include <fstream> +#include <iostream> + +long int stdin_to_file(const std::string& filename); diff --git a/graphs/cpp/stdin_to_file/stdin_to_file_example.cc b/graphs/cpp/stdin_to_file/stdin_to_file_example.cc new file mode 100644 index 0000000..3bc211d --- /dev/null +++ b/graphs/cpp/stdin_to_file/stdin_to_file_example.cc @@ -0,0 +1,10 @@ +#include <iostream> + +#include "stdin_to_file.hh" + +int main() +{ + auto word_count = stdin_to_file("file.out"); + std::cout << "File has " << word_count << " words\n"; + return 0; +} diff --git a/graphs/cpp/visitor/compute_visitor.cc b/graphs/cpp/visitor/compute_visitor.cc new file mode 100644 index 0000000..1e4e6dd --- /dev/null +++ b/graphs/cpp/visitor/compute_visitor.cc @@ -0,0 +1,62 @@ +// +// Created by martial.simon on 2/27/25. +// + +#include "compute_visitor.hh" + +#include <stdexcept> + +#include "add.hh" +#include "div.hh" +#include "leaf.hh" +#include "mul.hh" +#include "sub.hh" +void visitor::ComputeVisitor::visit(const tree::Tree& e) +{ + Visitor::visit(e); + value_ = get_value(); +} +void visitor::ComputeVisitor::visit(const tree::Node& e) +{ + visit(*e.get_lhs()); + visit(*e.get_rhs()); + value_ = get_value(); +} +void visitor::ComputeVisitor::visit(const tree::AddNode& e) +{ + visit(*e.get_lhs()); + int lhs = get_value(); + Visitor::visit(*e.get_rhs()); + value_ = lhs + get_value(); +} +void visitor::ComputeVisitor::visit(const tree::SubNode& e) +{ + visit(*e.get_lhs()); + int lhs = get_value(); + Visitor::visit(*e.get_rhs()); + value_ = lhs - get_value(); +} +void visitor::ComputeVisitor::visit(const tree::MulNode& e) +{ + visit(*e.get_lhs()); + int lhs = get_value(); + Visitor::visit(*e.get_rhs()); + value_ = lhs * get_value(); +} +void visitor::ComputeVisitor::visit(const tree::DivNode& e) +{ + visit(*e.get_lhs()); + int lhs = get_value(); + visit(*e.get_rhs()); + if (get_value() == 0) + throw std::overflow_error{ "Divide by zero exception" }; + value_ = lhs / get_value(); +} +void visitor::ComputeVisitor::visit(const tree::Leaf& e) +{ + value_ = std::stoi(e.get_value()); +} +int visitor::ComputeVisitor::get_value() +{ + return value_; +} diff --git a/graphs/cpp/visitor/compute_visitor.hh b/graphs/cpp/visitor/compute_visitor.hh new file mode 100644 index 0000000..0426f29 --- /dev/null +++ b/graphs/cpp/visitor/compute_visitor.hh @@ -0,0 +1,26 @@ +// +// Created by martial.simon on 2/27/25. +// + +#pragma once + +#include "visitor.hh" + +namespace visitor +{ + class ComputeVisitor : public Visitor + { + public: + void visit(const tree::Tree& e); + void visit(const tree::Node& e); + void visit(const tree::AddNode& e); + void visit(const tree::SubNode& e); + void visit(const tree::MulNode& e); + void visit(const tree::DivNode& e); + void visit(const tree::Leaf& e); + int get_value(); + + private: + int value_ = 0; + }; +} // namespace visitor diff --git a/graphs/cpp/visitor/print_visitor.cc b/graphs/cpp/visitor/print_visitor.cc new file mode 100644 index 0000000..bcfd565 --- /dev/null +++ b/graphs/cpp/visitor/print_visitor.cc @@ -0,0 +1,58 @@ +// +// Created by martial.simon on 2/27/25. +// + +#include "print_visitor.hh" + +#include <iostream> + +#include "add.hh" +#include "div.hh" +#include "leaf.hh" +#include "mul.hh" +#include "sub.hh" +void visitor::PrintVisitor::visit(const tree::Tree& e) +{ + Visitor::visit(e); +} +void visitor::PrintVisitor::visit(const tree::Node& e) +{ + visit(*e.get_lhs()); + visit(*e.get_rhs()); +} +void visitor::PrintVisitor::visit(const tree::AddNode& e) +{ + std::cout << "("; + visit(*e.get_lhs()); + std::cout << " + "; + visit(*e.get_rhs()); + std::cout << ")"; +} +void visitor::PrintVisitor::visit(const tree::SubNode& e) +{ + std::cout << "("; + visit(*e.get_lhs()); + std::cout << " - "; + visit(*e.get_rhs()); + std::cout << ")"; +} +void visitor::PrintVisitor::visit(const tree::MulNode& e) +{ + std::cout << "("; + visit(*e.get_lhs()); + std::cout << " * "; + visit(*e.get_rhs()); + std::cout << ")"; +} +void visitor::PrintVisitor::visit(const tree::DivNode& e) +{ + std::cout << "("; + visit(*e.get_lhs()); + std::cout << " / "; + visit(*e.get_rhs()); + std::cout << ")"; +} +void visitor::PrintVisitor::visit(const tree::Leaf& e) +{ + std::cout << e.get_value(); +}
\ No newline at end of file diff --git a/graphs/cpp/visitor/print_visitor.hh b/graphs/cpp/visitor/print_visitor.hh new file mode 100644 index 0000000..aa0ea4c --- /dev/null +++ b/graphs/cpp/visitor/print_visitor.hh @@ -0,0 +1,25 @@ +// +// Created by martial.simon on 2/27/25. +// + +#pragma once + +#include "visitor.hh" + +namespace visitor +{ + class PrintVisitor : public Visitor + { + public: + void visit(const tree::Tree& e); + void visit(const tree::Node& e); + void visit(const tree::AddNode& e); + void visit(const tree::SubNode& e); + void visit(const tree::MulNode& e); + void visit(const tree::DivNode& e); + void visit(const tree::Leaf& e); + + private: + int value_ = 0; + }; +} // namespace visitor diff --git a/graphs/cpp/war/assassin.cc b/graphs/cpp/war/assassin.cc new file mode 100644 index 0000000..090ec8b --- /dev/null +++ b/graphs/cpp/war/assassin.cc @@ -0,0 +1,5 @@ +#include "assassin.hh" + +Assassin::Assassin() + : Soldier(10, 9, "Out of the shadows!") +{} diff --git a/graphs/cpp/war/assassin.hh b/graphs/cpp/war/assassin.hh new file mode 100644 index 0000000..548fd8b --- /dev/null +++ b/graphs/cpp/war/assassin.hh @@ -0,0 +1,8 @@ +#pragma once +#include "soldier.hh" + +class Assassin : public Soldier +{ +public: + Assassin(); +};
\ No newline at end of file diff --git a/graphs/cpp/war/knight.cc b/graphs/cpp/war/knight.cc new file mode 100644 index 0000000..be52105 --- /dev/null +++ b/graphs/cpp/war/knight.cc @@ -0,0 +1,5 @@ +#include "knight.hh" + +Knight::Knight() + : Soldier(20, 5, "Be quick or be dead!") +{} diff --git a/graphs/cpp/war/knight.hh b/graphs/cpp/war/knight.hh new file mode 100644 index 0000000..d4f2b5f --- /dev/null +++ b/graphs/cpp/war/knight.hh @@ -0,0 +1,8 @@ +#pragma once +#include "soldier.hh" + +class Knight : public Soldier +{ +public: + Knight(); +};
\ No newline at end of file diff --git a/graphs/cpp/war/regiment.cc b/graphs/cpp/war/regiment.cc new file mode 100644 index 0000000..3534ced --- /dev/null +++ b/graphs/cpp/war/regiment.cc @@ -0,0 +1,38 @@ +#include "regiment.hh" + +#include <vector> + +void Regiment::join_by(Regiment& r) +{ + if (r.soldiers_.empty()) + return; + std::vector<Soldier*> v{ r.soldiers_.rbegin(), r.soldiers_.rend() }; + while (!v.empty()) + { + this->soldiers_.push_back(v.back()); + v.pop_back(); + } + r.soldiers_.clear(); +} +size_t Regiment::count() const +{ + return soldiers_.size(); +} +void Regiment::add_soldier(Soldier* s) +{ + soldiers_.push_back(s); +} +void Regiment::print_state() const +{ + for (auto soldier : soldiers_) + { + soldier->print_state(); + } +} +void Regiment::scream() const +{ + for (auto soldier : soldiers_) + { + soldier->scream(); + } +}
\ No newline at end of file diff --git a/graphs/cpp/war/regiment.hh b/graphs/cpp/war/regiment.hh new file mode 100644 index 0000000..ac54953 --- /dev/null +++ b/graphs/cpp/war/regiment.hh @@ -0,0 +1,17 @@ +#pragma once +#include <vector> + +#include "soldier.hh" + +class Regiment +{ +public: + void join_by(Regiment& r); + size_t count() const; + void add_soldier(Soldier* s); + void print_state() const; + void scream() const; + +private: + std::vector<Soldier*> soldiers_; +};
\ No newline at end of file diff --git a/graphs/cpp/war/soldier.cc b/graphs/cpp/war/soldier.cc new file mode 100644 index 0000000..01dc57c --- /dev/null +++ b/graphs/cpp/war/soldier.cc @@ -0,0 +1,24 @@ +#include "soldier.hh" + +#include <iostream> + +Soldier::Soldier(int hp, int dmg, std::string scream) + : health_points_{ hp } + , damage_{ dmg } + , scream_{ scream } +{} + +void Soldier::print_state() const +{ + std::cout << "I have " << health_points_ << " health points.\n"; +} + +void Soldier::scream() const +{ + std::cout << scream_ << "\n"; +} + +void Soldier::attack(Soldier& s) +{ + s.health_points_ -= this->damage_; +} diff --git a/graphs/cpp/war/soldier.hh b/graphs/cpp/war/soldier.hh new file mode 100644 index 0000000..1406022 --- /dev/null +++ b/graphs/cpp/war/soldier.hh @@ -0,0 +1,16 @@ +#pragma once +#include <string> + +class Soldier +{ +public: + Soldier(int hp, int dmg, std::string scream); + void attack(Soldier& s); + void print_state() const; + virtual void scream() const; + +private: + int health_points_; + int damage_; + std::string scream_; +};
\ No newline at end of file diff --git a/graphs/java/.gitignore b/graphs/java/.gitignore new file mode 100644 index 0000000..d951fc9 --- /dev/null +++ b/graphs/java/.gitignore @@ -0,0 +1,81 @@ +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +*.tar +# User-specific stuff +.idea/ +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser +target/ +Main.java diff --git a/graphs/java/classics/.gitignore b/graphs/java/classics/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/classics/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/classics/pom.xml b/graphs/java/classics/pom.xml new file mode 100644 index 0000000..ce852cb --- /dev/null +++ b/graphs/java/classics/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>classics</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>2.22.2</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/classics/src/main/java/fr/epita/assistants/classics/Classics.java b/graphs/java/classics/src/main/java/fr/epita/assistants/classics/Classics.java new file mode 100644 index 0000000..9be12e2 --- /dev/null +++ b/graphs/java/classics/src/main/java/fr/epita/assistants/classics/Classics.java @@ -0,0 +1,104 @@ +package fr.epita.assistants.classics; + +public class Classics { + /** + * Computes the factorial of n. + * + * @param n the nth value to compute, negative values should return -1 + * @return the long value of n! + */ + public static long factorial(int n) { + if (n < 0) return -1; + if (n == 0) return 1; + return n * factorial(n - 1); + } + + /** + * Computes the nth value of the tribonacci suite. + * f(0) = 0, f(1) = 1, f(2) = 1, f(n+3) = f(n) + f(n+1) + f(n+2) + * + * @param n the nth sequence to compute + */ + public static long tribonacci(int n) { + if (n < 0) + return -1; + if (n == 0) { + return 0; + } + long fst = 0; + if (n < 3) return 1; + long sec = 1; + long thd = 1; + while (n >= 3) { + long t = fst + sec + thd; + fst = sec; + sec = thd; + thd = t; + n--; + } + return thd; + } + + /** + * Checks if a word is a palindrome. + * + * @param word the string to check + * @return true if the word is a palindrome, false otherwise. + */ + public static boolean isPalindrome(String word) { + if (word == null) return false; + word = word.toLowerCase().strip(); + if (word.isEmpty()) return true; + for (int i = 0, j = word.length() - 1; i < j; i++, j--) { + while (word.charAt(i) == ' ') { + i++; + } + while (word.charAt(j) == ' ') { + j--; + } + if (word.charAt(i) != word.charAt(j)) return false; + } + return true; + } + + /** + * Sorts an array using an insertion sort. + * + * @param array the array to sort in place + */ + public static void insertionSort(int[] array) { + if (array.length == 0) { + return; + } + for (int i = 1; i < array.length; i++) { + for (int j = i; j > 0 && array[j - 1] > array[j]; j--) { + int tmp = array[j]; + array[j] = array[j - 1]; + array[j - 1] = tmp; + } + } + } + + /** + * Combines two strings by alternating their characters. Must use a StringBuilder. + * If the strings do not have the same length, appends the remaining characters at the end of the result. + * For instance, combine("abc", "def") returns "adbecf" + */ + public static String combine(String a, String b) { + if (a.isEmpty()) + return b; + if (b.isEmpty()) + return a; + StringBuilder sb = new StringBuilder(); + int i; + for (i = 0; i < Math.min(a.length(), b.length()); i++) { + sb.append(a.charAt(i)); + sb.append(b.charAt(i)); + } + if (b.length() > a.length()) { + for (; i < b.length(); i++) + sb.append(b.charAt(i)); + } + return new String(sb); + } +}
\ No newline at end of file diff --git a/graphs/java/creatureInterface/.gitignore b/graphs/java/creatureInterface/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/creatureInterface/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/creatureInterface/pom.xml b/graphs/java/creatureInterface/pom.xml new file mode 100644 index 0000000..1272b4c --- /dev/null +++ b/graphs/java/creatureInterface/pom.xml @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>creatureInterface</artifactId> + <version>1.0</version> + + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>2.22.2</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/BaseHuman.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/BaseHuman.java new file mode 100644 index 0000000..308fde9 --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/BaseHuman.java @@ -0,0 +1,51 @@ +package fr.epita.assistants.creatureInterface; + +public abstract class BaseHuman extends Creature implements SpeakableInterface, SwimmingInterface{ + /** + * Constructor for the Creature class. + * + * @param name The name of the creature + */ + boolean inWater; + BaseHuman(String name) { + super(name); + inWater = false; + } + + @Override + public String getName() { + return name; + } + + @Override + public void hello() { + System.out.println("Hello, my name is " + this.name + " and I'm a " + this.getClass().getSimpleName() + "."); + } + + @Override + public void greet(SpeakableInterface contact) { + if (contact instanceof Human) + System.out.println("Hello " + contact.getName() + ", how are you?"); + else + SpeakableInterface.super.greet(contact); + } + + @Override + public void swim() + { + inWater = true; + System.out.println("I'm a " + this.getClass().getSimpleName() + " and I'm swimming."); + } + + @Override + public boolean getSwimmingState() + { + return inWater; + } + + @Override + public void emerge() + { + inWater = false; + } +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Creature.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Creature.java new file mode 100644 index 0000000..1f63459 --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Creature.java @@ -0,0 +1,28 @@ +package fr.epita.assistants.creatureInterface; + +/** + * This abstract class provides a blueprint for creating creatures. + * All creatures extend this class. + */ +public abstract class Creature { + // The name of the creature + protected String name; + + /** + * Constructor for the Creature class. + * + * @param name The name of the creature + */ + Creature(String name) { + this.name = name; + } + + /** + * Get the name of the creature. + * + * @return The name of the creature + */ + public String getName() { + return name; + } +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Dragon.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Dragon.java new file mode 100644 index 0000000..49ee99d --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Dragon.java @@ -0,0 +1,74 @@ +package fr.epita.assistants.creatureInterface; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class Dragon extends Creature implements MagicalInterface, SpeakableInterface, FlyingInterface { + int mana; + Collection<Spell> spells = new ArrayList<Spell>(); + + public Dragon(String name, int mana) { + super(name); + this.mana = mana; + } + + @Override + public void hello() { + System.out.println("Hello, my name is " + this.name + " and I'm a Dragon."); + } + + @Override + public void greet(SpeakableInterface contact) { + if (contact instanceof Dragon) { + System.out.println("Greetings Lord " + contact.getName() + "."); + MagicalInterface.super.doSomeSparkles(); + } + else + SpeakableInterface.super.greet(contact); + } + + @Override + public void fly() { + System.out.println("I'm a Dragon and I'm flying."); + } + + @Override + public int getMana() { + return this.mana; + } + + @Override + public Collection<Spell> getSpells() { + return spells; + } + + @Override + public void addSpell(Spell spell) { + if (spell.getSpellType() == SpellType.WATER) + System.out.println("Dragon cannot learn WATER spells."); + else if (!spells.contains(spell)) + { + spells.add(spell); + } + } + + @Override + public void castSpell(Spell spell) { + if (spell.getSpellType() == SpellType.WATER) + System.out.println("Dragon cannot learn WATER spells."); + else if (!spells.contains(spell)) + System.out.println(this.name + " does not know " + spell.name() + "."); + else if (spell.getManaCost() > this.mana) + System.out.println(this.name + " does not have enough mana."); + else { + System.out.println(this.name + " casted " + spell.name() + "."); + this.mana -= spell.getManaCost(); + } + } + + @Override + public void regenMana(int mana) { + this.mana += mana; + } +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Fish.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Fish.java new file mode 100644 index 0000000..b109493 --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Fish.java @@ -0,0 +1,27 @@ +package fr.epita.assistants.creatureInterface; + +public class Fish extends Creature implements SwimmingInterface{ + /** + * Constructor for the Creature class. + * + * @param name The name of the creature + */ + Fish(String name) { + super(name); + } + + @Override + public void swim() { + System.out.println("I'm a " + this.getClass().getSimpleName() + " and I'm swimming."); + } + + @Override + public boolean getSwimmingState() { + return true; + } + + @Override + public void emerge() { + throw new RuntimeException(name + " died."); + } +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/FlyingInterface.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/FlyingInterface.java new file mode 100644 index 0000000..49ab154 --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/FlyingInterface.java @@ -0,0 +1,12 @@ +package fr.epita.assistants.creatureInterface; + +/** + * This interface provides methods for flying. + * Creatures that fly implement this interface. + */ +public interface FlyingInterface { + /** + * Prints "I'm a {CreatureClassName} and I'm flying." + */ + void fly(); +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Human.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Human.java new file mode 100644 index 0000000..b29b49f --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Human.java @@ -0,0 +1,8 @@ +package fr.epita.assistants.creatureInterface; + +public class Human extends BaseHuman { + public Human(String name) + { + super(name); + } +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Mage.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Mage.java new file mode 100644 index 0000000..dab7630 --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Mage.java @@ -0,0 +1,59 @@ +package fr.epita.assistants.creatureInterface; + +import java.util.ArrayList; +import java.util.Collection; + +public class Mage extends BaseHuman implements MagicalInterface{ + int mana; + Collection<Spell> spells = new ArrayList<Spell>(); + public Mage(String name, int mana) { + super(name); + this.mana = mana; + } + + @Override + public void greet(SpeakableInterface contact) + { + if (contact instanceof Mage) + System.out.println("I welcome you, " + contact.getName() + "."); + else + super.greet(contact); + } + + @Override + public int getMana() { + return this.mana; + } + + @Override + public Collection<Spell> getSpells() { + return spells; + } + + @Override + public void addSpell(Spell spell) { + if (!spells.contains(spell)) + { + spells.add(spell); + } + } + + @Override + public void castSpell(Spell spell) { + if (!spells.contains(spell)) + System.out.println(this.name + " does not know " + spell.name() + "."); + else if (spell.getManaCost() > this.mana) + System.out.println(this.name + " does not have enough mana."); + else { + System.out.println(this.name + " casted " + spell.name() + "."); + this.mana -= spell.getManaCost(); + } + } + + @Override + public void regenMana(int mana) { + if (inWater) + mana = (int)(mana * 0.9); + this.mana += mana; + } +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/MagicalInterface.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/MagicalInterface.java new file mode 100644 index 0000000..d7530ab --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/MagicalInterface.java @@ -0,0 +1,56 @@ +package fr.epita.assistants.creatureInterface; + +import java.util.Collection; + +/** + * This interface provides methods for creatures that are Magical! + * Creatures that implement this interface have magical mana and spells. + */ +public interface MagicalInterface { + /** + * Get the mana of the creature. + * + * @return The mana of the creature + */ + int getMana(); + + /** + * Get the spells of the creature. + * + * @return The spells of the creature + */ + Collection<Spell> getSpells(); + + /** + * Add a spell to the creature. + * If the spell is already present, it will not be added. + * Be sure to check that the creature <strong>can</strong> learn the spell before adding it. + * Prints a message if the creature cannot learn the spell. + * + * @param spell The spell to add + */ + void addSpell(Spell spell); + + /** + * Cast a spell. + * If the creature knows the spell and has enough mana, the spell is cast. + * Otherwise, prints a message indicating the reason. + * + * @param spell The spell to cast + */ + void castSpell(Spell spell); + + /** + * Regenerate an amount of mana. + * + * @param mana The amount of mana to regenerate + */ + void regenMana(int mana); + + /** + * Do some sparkles ✨✨✨ + */ + default void doSomeSparkles() { + System.out.println("*sparkling effects*"); + } +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Mermaid.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Mermaid.java new file mode 100644 index 0000000..d086e8d --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Mermaid.java @@ -0,0 +1,110 @@ +package fr.epita.assistants.creatureInterface; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class Mermaid extends Creature implements SpeakableInterface, MagicalInterface, SwimmingInterface { + int mana; + Collection<Spell> spells = new ArrayList<Spell>(); + boolean swimmingState; + + private String make_name(BaseHuman baseHuman, Fish fish) { + StringBuilder name = new StringBuilder(); + name.append(baseHuman.getName().substring(0, 1).toUpperCase()).append(baseHuman.getName().substring(1).toLowerCase()); + name.append(fish.getName().toLowerCase()); + return new String(name); + } + + public Mermaid(BaseHuman baseHuman, Fish fish) + { + super(""); + this.name = make_name(baseHuman, fish); + if (baseHuman instanceof Mage) + { + for (Spell s : ((Mage) baseHuman).getSpells()) + { + if (s.getSpellType() == SpellType.FIRE) + { + System.out.println(this.name + " forgot the spell " + s.name() + "."); + } + else + { + addSpell(s); + } + } + } + this.swimmingState = baseHuman.getSwimmingState(); + this.mana = 0; + } + + @Override + public void hello() { + System.out.println("Hello, my name is " + this.name + " and I'm a Mermaid."); + } + + @Override + public void greet(SpeakableInterface contact) { + if (contact instanceof Mermaid) + System.out.println("Dear " + contact.getName() + ", welcome."); + else + SpeakableInterface.super.greet(contact); + } + + @Override + public int getMana() { + return this.mana; + } + + @Override + public Collection<Spell> getSpells() { + return spells; + } + + @Override + public void addSpell(Spell spell) { + if (spell.getSpellType() == SpellType.FIRE) + System.out.println("Mermaid cannot learn FIRE spells."); + else if (!spells.contains(spell)) { + spells.add(spell); + } + } + + @Override + public void castSpell(Spell spell) { + if (spell.getSpellType() == SpellType.FIRE) + System.out.println("Mermaid cannot learn FIRE spells."); + else if (!spells.contains(spell)) + System.out.println(this.name + " does not know " + spell.name() + "."); + else if (spell.getSpellType() == SpellType.WATER && swimmingState && spell.getManaCost() * 0.6 <= this.mana) { + this.mana -= (int) (spell.getManaCost() * 0.6); + System.out.println(this.name + " casted " + spell.name() + "."); + } else if (spell.getManaCost() > this.mana) + System.out.println(this.name + " does not have enough mana."); + else { + System.out.println(this.name + " casted " + spell.name() + "."); + this.mana -= spell.getManaCost(); + } + } + + @Override + public void regenMana(int mana) { + this.mana += mana; + } + + @Override + public void swim() { + swimmingState = true; + System.out.println("I'm a Mermaid and I'm swimming."); + } + + @Override + public boolean getSwimmingState() { + return swimmingState; + } + + @Override + public void emerge() { + swimmingState = false; + } +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SpeakableInterface.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SpeakableInterface.java new file mode 100644 index 0000000..cc10988 --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SpeakableInterface.java @@ -0,0 +1,47 @@ +package fr.epita.assistants.creatureInterface; + +import java.util.List; + +/** + * This interface provides communication methods for the objects of the class + * that implements it. Classes adopting this interface instantiate objects + * capable of communication. + */ +public interface SpeakableInterface { + /** + * Returns the name of the object that can speak + */ + String getName(); + + /** + * Prints "Hello, my name is {creatureName} and I'm a {creatureClassName}." + */ + void hello(); + + /** + * Greets the contact + * The default implementation greets the contact based on its type + * @param contact the creature to greet + */ + default void greet(SpeakableInterface contact) { + if (contact instanceof Mage) + System.out.println("Salutations " + contact.getName() + ", keeper of Arcane secrets."); + else if (contact instanceof Human) + System.out.println("Salutations " + contact.getName() + " the human."); + else if (contact instanceof Dragon) + System.out.println("Salutations " + contact.getName() + ", keeper of Ancient treasures."); + else if (contact instanceof Mermaid) + System.out.println("Salutations " + contact.getName() + ", keeper of the Seas."); + } + + + /** + * Allows all speakers in the collection to say hello as explained in the hello() method + * @param speakers the list of creatures that can speak + */ + static void helloAll(List<SpeakableInterface> speakers) { + for (SpeakableInterface speaker : speakers) { + speaker.hello(); + } + } +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Spell.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Spell.java new file mode 100644 index 0000000..87fe68a --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Spell.java @@ -0,0 +1,48 @@ +package fr.epita.assistants.creatureInterface; + +/** + * This enum represents a spell that some creature can cast. + * Refer to the subject for more information about enum with behavior. + */ +public enum Spell { + FIREBALL(40, SpellType.FIRE, "Launches a sphere of fire that explodes upon impact."), + HEAL(30, SpellType.NEUTRAL, "Channels divine energy to restore health."), + MAGIC_SHIELD(15, SpellType.NEUTRAL, "Summons an arcane shield that reflects attacks."), + TIDAL_WAVE(30, SpellType.WATER, "Summons a huge wave of water that crashes down dealing damage."); + + /** + * The cost of the spell in mana. + */ + private final int manaCost; + + /** + * The type of the spell. + */ + private final SpellType spellType; + + /** + * The description of the spell. + */ + private final String description; + + Spell(int manaCost, SpellType spellType, String description) { + this.manaCost = manaCost; + this.spellType = spellType; + this.description = description; + } + + public int getManaCost() { + return manaCost; + } + + public SpellType getSpellType() { + return spellType; + } + + /** + * This method prints a description of the spell and its mana cost. + */ + public void what() { + System.out.println(this.description + "\tUses " + getManaCost() + " mana."); + } +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SpellType.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SpellType.java new file mode 100644 index 0000000..53cca2a --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SpellType.java @@ -0,0 +1,11 @@ +package fr.epita.assistants.creatureInterface; + +/** + * This enumeration provides the types of spells. + * Do not forget that creatures have restrictions on the types of spells they can learn. + */ +public enum SpellType { + FIRE, + WATER, + NEUTRAL, +} diff --git a/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SwimmingInterface.java b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SwimmingInterface.java new file mode 100644 index 0000000..ede4d31 --- /dev/null +++ b/graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SwimmingInterface.java @@ -0,0 +1,25 @@ +package fr.epita.assistants.creatureInterface; + +/** + * This interface provides methods for swimming. + * Creatures that swim implement this interface. + */ +public interface SwimmingInterface { + /** + * Prints "I'm a {CreatureClassName} and I'm swimming." + */ + void swim(); + + /** + * Returns true if the creature is swimming. + * It is up to the implementing class to determine the conditions for swimming. + * + * @return True if the creature is swimming + */ + boolean getSwimmingState(); + + /** + * Emerges from the water. + */ + void emerge(); +} diff --git a/graphs/java/drawing/.gitignore b/graphs/java/drawing/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/drawing/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/drawing/pom.xml b/graphs/java/drawing/pom.xml new file mode 100644 index 0000000..24df903 --- /dev/null +++ b/graphs/java/drawing/pom.xml @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>drawing</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>2.22.2</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>1.18.30</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Circle.java b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Circle.java new file mode 100644 index 0000000..306d870 --- /dev/null +++ b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Circle.java @@ -0,0 +1,27 @@ +package fr.epita.assistants.drawing; + +public class Circle extends Entity { + private int radius; + + public Circle(int radius) { + super(); + this.radius = radius; + } + + @Override + public void draw() { + for (int y = -radius; y < radius + 1; y++) { + for (int x = -radius; x < radius + 1; x++) { + if (Math.abs((radius * radius) - ((x * x) + (y * y))) < radius) { + System.out.print('#'); + } + else + System.out.print(' '); + if (x < radius) + System.out.print(' '); + } + if (y < radius) + System.out.print("\n"); + } + } +} diff --git a/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Entity.java b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Entity.java new file mode 100644 index 0000000..a91aa0f --- /dev/null +++ b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Entity.java @@ -0,0 +1,20 @@ +package fr.epita.assistants.drawing; + +import lombok.Getter; + +public abstract class Entity implements IDrawable { + @Getter + private long id; + private static long SEQUENCE = 0; + + public Entity() { + this.id = SEQUENCE; + SEQUENCE++; + } + + @Override + public void draw() { + System.out.println("This shouldn't happen"); + } + +} diff --git a/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/IDrawable.java b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/IDrawable.java new file mode 100644 index 0000000..2af2df1 --- /dev/null +++ b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/IDrawable.java @@ -0,0 +1,5 @@ +package fr.epita.assistants.drawing; + +public interface IDrawable { + public void draw(); +} diff --git a/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Rectangle.java b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Rectangle.java new file mode 100644 index 0000000..944a75b --- /dev/null +++ b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Rectangle.java @@ -0,0 +1,31 @@ +package fr.epita.assistants.drawing; + +public class Rectangle extends Sharp { + private int width; + + public Rectangle(int width, int length) { + super(length); + this.width = width; + } + + @Override + public void draw() { + for (int i = 0; i < width; i++) { + System.out.print("# "); + } + System.out.print("\n"); + for (int i = 0; i < length - 2; i++) { + System.out.print("# "); + for (int j = 0; j < width - 2; j++) { + System.out.print(" "); + } + System.out.println("# "); + } + if (length < 2) + return; + for (int i = 0; i < width; i++) { + System.out.print("# "); + } + System.out.print("\n"); + } +} diff --git a/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Sharp.java b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Sharp.java new file mode 100644 index 0000000..604f255 --- /dev/null +++ b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Sharp.java @@ -0,0 +1,9 @@ +package fr.epita.assistants.drawing; + +public abstract class Sharp extends Entity { + protected int length; + public Sharp(int length) { + super(); + this.length = length; + } +} diff --git a/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Square.java b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Square.java new file mode 100644 index 0000000..d807bcc --- /dev/null +++ b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Square.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.drawing; + +public class Square extends Rectangle { + public Square(int length) { + super(length, length); + } +} diff --git a/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Triangle.java b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Triangle.java new file mode 100644 index 0000000..a43248c --- /dev/null +++ b/graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Triangle.java @@ -0,0 +1,33 @@ +package fr.epita.assistants.drawing; + +public class Triangle extends Sharp { + public Triangle(int length) { + super(length); + } + + @Override + public void draw() { + if (length == 0) + return; + if (length == 2) + { + System.out.println("#\n# #"); + return; + } + System.out.println('#'); + for (int y = 2; y < length; y++) { + System.out.print("# "); + for (int x = 0; x < y - 2; x++) { + System.out.print(" "); + } + System.out.println("#"); + } + if (length > 2) + { + for (int i = 0; i < length; i++) { + System.out.print("# "); + } + } + System.out.print("\n"); + } +} diff --git a/graphs/java/embedFiles/.gitignore b/graphs/java/embedFiles/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/embedFiles/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/embedFiles/pom.xml b/graphs/java/embedFiles/pom.xml new file mode 100644 index 0000000..399dd7d --- /dev/null +++ b/graphs/java/embedFiles/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>embedFiles</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/embedFiles/src/main/java/fr/epita/assistants/embedfiles/DisplayEmbedFile.java b/graphs/java/embedFiles/src/main/java/fr/epita/assistants/embedfiles/DisplayEmbedFile.java new file mode 100644 index 0000000..2dbd4b8 --- /dev/null +++ b/graphs/java/embedFiles/src/main/java/fr/epita/assistants/embedfiles/DisplayEmbedFile.java @@ -0,0 +1,27 @@ +package fr.epita.assistants.embedfiles; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Optional; + +public class DisplayEmbedFile { + private final String filename; + + public DisplayEmbedFile(String filename) { + this.filename = filename; + } + + public Optional<String> display() { + Optional<String> res = Optional.empty(); + InputStream in = ClassLoader.getSystemResourceAsStream(filename); + if (in != null) { + try { + res = Optional.of(new String(in.readAllBytes(), StandardCharsets.UTF_8)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return res; + } +} diff --git a/graphs/java/embedFiles/src/main/resources/other-sample.txt b/graphs/java/embedFiles/src/main/resources/other-sample.txt new file mode 100644 index 0000000..7631d8a --- /dev/null +++ b/graphs/java/embedFiles/src/main/resources/other-sample.txt @@ -0,0 +1,539 @@ +vwM6YNMqdmoPi0uVyp7jd2v9/nhJxUCX41wPccxQanv1dWdrr2TlI3JtRQddIkMTJ2ZEKAMtR+b+ +tYDCreIQV3SmLcrB7E1JlBXUO3jxFjeoTG9tdVF3Ub8VQLny1QnOHq0q2+Y0GZbQdwN88MfSveyS +MDnzJ+0ZUFGfWfChcLfGJYEqFI/CEnVEn1+QIQFPWaSJ+6emrKhSdt+ofWx0qbu1hfcaWmhbFpCV +WBBB8fKKzO0HJSdKObokoeTv0Fckr7xwcRRnMS/lT6E3rjjFExyn94AT/CyRQg9tDdt0p8SWJqCu +mNX1Ov8SdAWXSMXazdsOcjOA0BGjvZLIbxF4Dn+tUS3wgB781SA6KB3YncYwQoflJlc0Athe1ZVM +G/8JORa4BwFbGp0e4lZMOhQR5iBx775HQhqOiHg8S/Ccj7BCnjDk0F2gnjv1qVLbUuryLi81L5Jp +6dV5amPpN/PDGtohfrosA1VxrqPFKXKOs9cqOzszNs2Acuvnk9gxuKJ6SE1syAmN2tRf5G85jtE2 +PQ761pH7Cq8BEAt/j4yy46/Als/Hjg6W7yWN8BbG5ERS/czuILPZP8noSJ5oFuk4p0T1WR2Y8IDh +hitMAegOpC7lf1zLh6qT+KKMYQxYikXmnbpDa0hpp9tSBBOtz9vOwdXpyqu4h6l5wTMdj956N094 +2qW30rBs8+eRIqd4IjLMObDSXpz9NL3NbozZBpC5H4azAP/gq+4HLE7+HU/3l3aRVupdP3m7bodI +9+g+QlKGecNfGGNihYV31e6+BSDVEj3u1rOllTc397d9hByJ8Z4CwWlinqLNzTzBtQj6ANgof4aE +Bk20hekjs5YvfvXB644oNSub8ynHgp/a2cc1KGuI8KPo5EsjGxmnJBUHVPiBoGpwXLOWuxWEsBA1 +vjj72XFgq/dYDUVNfPWIJU2+UaOIo8G1aGbyCUGS6DHlS/IrcUHtdk/piy0AJ8rOUHn2BnibQ/Ga +AAxt7s6PwRnpGXrxBqbP1CPc3N29oR07dbflhnLknDxpg4pBSYwC3VVpOCcdzEH8UwPqMis3QLPJ +MOPng1mWZGgx4Zs8OScuip1njSl7Ytm3A03KbEbAL/wn8Cbk2Knz59zQfrIUjHaFJQjH4z0GLjov +yS9Kr2meJUPl98skRClhfV7+8e8dugGyaibmmaxyJHuxgsnq1Ez88ZFzmKpCBuLjR9jRAX84yYMd +Bk00v4Yx+aQg+dnxg6qBK52QykJG44UpUKmMrvYoprv0aziB+PYSZi9RzFnbER8K/PR4EcF7cd82 +0q53YdAb/4x5U/O1iljx+P9nrXg5JSGksKVY6R8d5zC1dl38Jh8crjtfVF8t5vTqQh8VZM0KIrKd +CcW0SRexj3dYDtBllS45HzZ3Vm6NN2tVq/jBOmQmArkZaJJ+WBd/HecWwe9CPsZVMkTnyCAipH9c +bJxea4jvCMPG9VHLEros6eXO5+yGXWXlZRdNxBzAjwbfXsMLm1cwoTVip3Zw4VzpwQ9CU3cFJxlz +qmWaTqWRCPMYHhYOyvgyeneimcYU14OlRh1qFQol79T1I6H+ObVlb2HCO/vvqfSVLNUpS1vnwFjO +ohoNHILgyWr4Xyt59OB+rNdZIkH03cEo8dh1QO5nX6uNkJ7OtgVsVWNXEW2gFfbT/PJji1uqY9AT +nFx5OB8rTBYooJ4hmfm1X4W6PJjl+yUrft6NGGZNlr1sbgo+1WjxYUsbEb/s9HcrZzK/8aM9GqoM +QQ9gicbmPXE5sbXBm9+xKjlrrZHURLVOyXEjjMypqhSVU5YZbwb5i+9/ykt2Vf52mOfM1f8+xs8o +MmAIwA7kI3jisUTXPQy4YzPnjCaKcRpDVQ0gapmYPXw8aXf6+UDWq11SgM4vc4ZdIekjOVmo4xDo +aIPoz/SwjwBJUaK2eKUJAv+mLLCgMrtXCT3PO2L9TNuaPNK1EQdAeC2JYT76z2LSs3tjQpFSKErT +tbzKiwzX8Goi23mDIaI4yR4UsamEhFB8IrLJVE87cQPqygJhkYgweYvMdfzF4wiy+u+WBxh8nHNB +NJHSMFqOnRWxfqGpzhrmfnWqEXjeIzKxp/MbjIfPryapIcl7IQPG9qUmk79Cvm5qx3HD6nMO/RCO +DLc8UEsgJ4ntNPjorjxqki54G8jKqeq5yR3EM3N6ga66B5OFL0K47IFsqarsGm7V6O1m3aeIu87V +gg6Xa7ogqmNVW/HL+blEsyhDbXbtGH0BKDOLseuciix49q7uGQ6kZGktXeHLMSWgzywWybRZtxoz +Tq+uw4+WXz7nZ9gFUYHB0+MR5OAVy8uGZ2LlIwVrreCX063Q7t9mBEDTqLE6ejrWmsPhJj0tAnOt +6eR+aklPZVeQ9pjsxIGSvzyHw0awYmQe+k3I01xmhdjU02OwbB+5BwrlsGEAPMh3XJQCFJ81Ma+H +EsudPGqFEJy3DHWiK6a8BDrU2cfxGG+qbgrX5rSEtwwduEtNBzZHe8oOzTgA0kAC+LRQbOzCBdif +NYi7ZmJy7hApF6G1V7IrZFselTga2tnMa6vfGD/JqZZOnBOQGRkS9kTbC/MTI3PvI51U0F92z6u0 +Kt78qANroYYrcF7dAIODtGDL5WUHH2tp0TqLk+DczfxesUooE8NdvhxnECtj+wSzMmjaUuYt8RIb +ZvKB6VwLKafsi77Z+ZkFJywT5hmfXK31Qf+7b0/HTcw4Olyq+aR7wa2wJt/hQU0keo4XOCUvpofj +idnDjumOAnNU5d+jbia+LJt/EvzyXZHuY8BFMkqj5F5cjZHppC5MlslUqhOxQILF17SBaEPk7ZRy +NFVmyFq0mePR2/DCzB+tFVw9n1cxZ3rRtogg0aANm8B0nLVcp6LSpaY8XzqpnLZK5jioeYSjDqVf +cfuZcGu2eUTLvvKcbVxlygO/fhbWKl/fWjYptGXd7dtYokYbwqIfobQv1vnxqAQEBVMzUiMi9dkW +GUiOYk9rDTWG4co8b497oanDYJeWrHLnjvstGq2P2LamJ8VzpX05SSMfPTJgczfvPb10oN3LTDLk +bl9h1+OGOWPdrEUZg+SWNYxDwEdrPh/sv5u7R6V6Rn4IGZUyxPMbQHrTZqBIiTOYjWZzPUxVb5T6 +lrm5kC4x2VJwGT22O/yoVEoF4ofK8fMyzyCdkx/PAmuavR0jivMVKoxGwJOQzWwlT4m4cf+JRjG1 +VCpKmuLBWyGTnKNatWkKbfYYJOR1H98MlQkjyHNOd068yQO7Cv90Iza7Ail8B5RvR4J1BEYn1ZGi +XmgbLcYDxb/2Cdj9/UWn6ER54tWg82MXJnTDYJ98FQZy5HTUQjUT74jcgdUdjG0M3QAwtz2LUNKG +PlePew5G8b/mcoHN2GmnWAl1jjiDuQ5KlpNiHzROhGZEbVx8TL8aHaYd5+4r/l7A6Tfezbje462d +Tuc28nfu5db8Ll9d3aKDvHUan0WSaKRZ0+mGtR2HgIMwEr7b9B8v4QC0UPge6GVXdhb6UxrTnI17 +ixwmW20egnSkDJO+eIUCXLzCzc3v54f9EWg/ajXjcu8yuWo3b2gOVqrk7RrdVVhlLss+W+DqLTFm +pBfdTJf0+6aibfgbVHBIA7aV6QVk9FRMUEAcCwSEOIkEfw+g1fym+VuVWc+ibgicw/bdtmiZ5nfL +pB8W/y/+LsBFqS7USSlp6m8ZAehA3lMl0VpOgDP6eyOeUO3rXMYbN495+JHYvF0s7QXWWs4Z9ZPy +qU/p/cBWbQb+Eeh29SyXR7l9uuahF/OLnEH426DR8METQmmMXMtTWa7KN7y1GxVfykmIh11I9OHB +0nCQ8jeaXePPnpeWT4o3tzId/pq4HsUqZHB4PkhWwYurACx1jWIy4WKgWand9y267pvJmrpTbtQA +u+Kc0HGgb6G/7N+Tr7nqf68lTbtNiMLIZM6S5O78nAbKfMWSnR65DomQfDhnJ1DWlIw54td3LRsv +DZiQr+kilEw1Auhd6FqedW7fA6yaDYRMIgI+PZgCEfaLUOweMA8Jm3+Q2OBJzQFw+NUtCh6NOJix +HRKF8LACF7bgMczHyW49M6XoZ9hwwNFMxGy7fVblWYJKzmdaxpJ1Am2lNokFnjIfMYaSCeE071d2 +pL/efVTtbTzIxYZQg1M8vRlERHzQ9mBSv1OFlnxiXgYqte4uMKT8n90VF4W8PualWKApP8+DMbn3 +glbHxd1P2lMci7+EzVP4x8tJBL64skEKyVPXJCAbsP+39L+uQxmPAQWU0RDkKdD7vp2i2QCVgz4u +F4Haaw5I2Z4iuo7gh2vdSFnhXvfKiFmHAvy9q/TguR0hnCGsmP9zuPSYt1N4TRdb5+5qQLzwO+zD +yPKzBLixS45zWp56x8lmlDLe5jzsY188/7XRe2a+jSBRtniEPsdGPrevPFfUx1bcGluKjNEXW/qT +0HSKlyb7BD9ny1rotzzKB8zpefCiSNDYRXyk2jcp1VOmTVnxo9/hnU5PxiuqmW3HZ7bJQwfeWXji +BmnuO2LQUIhY6Qd2pkx85wM1pzvLOApuFAHTv/knZthmABkROJZeTW7vIvuEx2cq+jv9X/kfiqc3 +Pj35hQk1VCz0V97fkdC97V8sWGtuMCgOZiaO3HHuaAaYhzSwqGUM9/GICLj65q5SxCY7QEJ4yhVq +nn4ObQImhc5LlzdUgHhngg5wWTW7/gANfGqMPhWm8ijz2ZAVRv3APynYtlMl38iJ3b9B1/cGt5pF +Zhv97SGUXt+dZ0VK4StVE6FXQeEoQLbnntIrz9vPRZXZHx57o4baUsWmKOB8MQJtHouW9tIqFZf0 +JdRHZK6eXvhtRxfaZOsXzVvlRR18WfkewyFRvMxgEv6U4jk+M6zrEKUBU1Jmo9ak50tsVYUsYWrc +/xCa1WzGzqUlucuZT7rI0sklOn+t4eAapm82SlSBnf9jqx2Z6ka9EX5aQSiO2hTi5rGpkfa5Nxaz +g3po4dfEc48iXz4HrwxY9NFx4Fh5ZtEc1/cos/gPtXqoIhhnNs6vEjE2vKGKe2OLuekocZbWB+XL +0lxrqHHS4iidC06rgQd460nBBbfn9qjll742frRUCqEUVZegQlvfn6GF45Sm2S8I91C8wWFVQXd/ +xOokQNGcvcSMaNHRHjBfB6HKyfxLT/XgxWOXbOCZWznnoniOHYhXfIzR2a1TibQK8EOgucwYgA1i +NmLLD031EThF1boo7mhIixkidrpPtihI4xOebfijdIPjxmFH/5y1lx8gqeikdaTVy8Lizwds3/sN +WLXivMn0fFw7MbIFihknvLSbQ2+KZ8+GtNVICWSAfo2fkuZxQQlPkTXR9aMb3tt7JbIUkoH31WEc +rmpixcnHXWrKUXBXBth/pxTOA9LH3qw0vfQmN9t1vGA81GNtleEL8NZHeIiKp9jI1MeHZMdVm/4g +4fZ0reT2pL2J2WB6NeTtrmoa5FD4FPv0d5/CPdk+yB7iMf+30rX4WAIZkgXd4+4kBsS3rOZDtYc8 +aCeDmDxp6/eDBJE0UOTSyLuRxyUiP28c361IXWOvt7aEKqbNLXyUknwNYaT12W8TvPehE5RB0yFz +onIHkMxep+f9RZAXaLSixt69ZEGijjgz9tFMpbD/viG17MEdlPFNNaVFWODmSVlUFta81faAxaRQ +1UtYbol+UyQlMbhbizhgWw97E4CD19dRq0NQv54j99eO82NvHzhikcSiJdOO11ItgpD1ZT9lXb6F +JJFRg0HJrKHZjNTIujD4lQ7IWE0JbGQzOechERRAsjsm/sA1X8CugNPMm9/1OBsYpp6ZHWO2eaRF +b+GMl4MYl8L5Cjpj1UclHHpc/pjSj5JRhuoeTlZAwJAGVJpeV8bd/svz0aGOFt0383L9OnViUnoW +nEyXaNbykBiDZjxQHJLiyZHQ0QVqVW5QKkpFCZn7HIcmWtvdkAPbWELbVqIYgWs4t+sEbx2r0U1e +JjuywcbT5ZWsVqiPSb5fO9Fwoqes9hTA9gl0XRwL0UAdsiywwSvezX4d52OAuHxlrplL/qSAawNJ +vf+TO3ioCd+zY56Rk80THbhsFEE34GeFFd4Aw97Km2A6kJdLLRNiZBcNdo1uYrasG40661YJQCqw +2IXJpSNvfajXTygq/O0zfqgLgqZXyyO4YB43LOJa/Df32WylLfYAghjUKXej8EorVT+hTRDzoXea +IE5zDTnolcvKC24Z0x6yHKajKcOA0mjwYyEgnwxHEOaRIjBeSN4of/NdWv9VoOlaTuZhNOiukHFw +LY2doyWfiQq8HcarARZPzgJY04Fjjdm8QQcBbJdn5VbtXunYS297j83ZUf5QSSucq/NmKSte1eNs +GVGRXrodyaXDAitMmoom1DB+bO8Zgen3tHEBpQkzPzfgXXHJcLXYTxYsq8QlUDG10c8v1n2/Bc9d +25rq2Au3aN5mzT6hMZRQWlAh1YQ5Ci6sE+eUEPRxriPsDJMLk5ZvKmk7cW5sfsqcM7GDcKPrGdlI +UW0JiIZf0ndD+sOaBe1sZl3jbja4EBQme/d2B5YBpab8wz5TrI96rSlouB/SnSi7g7eo8Ie51aJB +u4hMFSlElHv2RsvuAGoP5W26G2ScbB7eb+IJtdH0D3O1NtAmpRsb150oB7PV0YNOPRCHXVjNMWq2 +r/zDD5osuQBRvDXYcYtvQmFTE4n5BMTwvdg6GaSa8oRWLNlcrQcEN3BehovhtaWjiO86ZP93ERsk +vyLCYfMEC89oeCj5nDKu+1b5P6FYF5EkQ/paTTODvzaQYjnCqlVBfbzYckYoQk0DhiT8o/R/MhXC +bgc/89dy4e7YNbNIR+mFR+gPL57U7MpYyjNbj9WLWZS/HWm51ikMTF28H3Wqs/n4dbUBpNeBohso +VYpknsnNccajI5Z1sZJTa58ooXFYOeenaaXE+Alke3LUkijkseKGidUgLoA54hVrsvP1rGyciaon +trOXw+SuKkaTuyhXs2WMWs3EZaF+vKpRSYfOZ84sWWtj+7oKGVCVtAnPLlrvi/IheKCVnASLqMkS +WDVXR+zMXiHUGl0B2GTykiy96nNBL3tDPjxMRzX85NR+KtY1xgkcsDtMcR544LQech8kJ7k+AzrM +4olBRpSNyrCHL7ziA2he7FUQSr0fCVxBF4Jv7l3DMWYSlbCExaglLYNjowWX/yvfIiyQoidO3mVV +A3MBD9gZ50Y6lSvTvWCaxVvC/mi/U8kqtqCDtCMS9lQqbwCV5BWL+cziktR6eKuQhLgIlJzg7r0B +Qp/OsIOQ9tRqJ5LDKwk2RaYBNDuU659xP02salaGwo8R+S/LPw29ur0NjY1Dx9kRgFBxuunxa7wz +Zix8Wmmw0y0sIabLTJTXLyMhRqIkQDrQAS3/Wx/18B5iVpwE076fEqYq5vaQ+0O/ixG3Nm7bghLU +zUPoh1jx0+uQKGCRlQV1CFQqBHAR9Kqp94A9/jhl5uT96fxEzug6gmHqS/Vr3dSmH2nZUZLQOqZo +DPCpOQgK6VH0odXeN0mWtIs+u4dEkc36p6Lx2C2w+G+iMrpU/T9sxeF2229hgRSh4l1HDHxibkcL +CvUgBRV73FvQhmkUEXny165goIirmf+nOrxbZsN0dyPG1LIZRj+SBLkAda1mHqeVL6sBAKU7Dz2z +LBr0ewAnkS5Vf0arcmtHqd9nf91fBihHRUQSaD0FqIe6O1CI69/RgNAueEE9bBDgwjriY2lrVPdQ +IwxdYXtSTFRRqMygMHmgSdO90Nmi8x3NByy8a/ChN08uFCZZylnLV6eR0gaX3G/Tm/1Jx+CxS70C +8n5Gbeaw8TQoIjQXhvo0iHTw1t1/qSh7tewe0coGexHFlq0ylN76R57V/yLRVRVAbtldBeBjDUYa +PXfyRWGFvBMkC6mhI8Mbsch2a56uyDxaN7a0Sr5t9hAWngr052Lg+i2WXWAB+OGqpZThl1AlkFQy +myfKO6MQUOXLsQKMwO6XA83vZHrCMXnk+sn1h7XTERfr5nsGnEnKGjNgXQjnSzVOiKHFLjqG1bVP +nNvFtjXLgD5I1+ejxhHxIonx+oj1lf8H6jEfS+XiLo/LFIOt2VqmenrhguLCKSFL8BME1xPXbAO4 +Zqkg4Wqn/ebhegZc0Wjv+weCEqNGYKcA/Vx6aCeNViafNL69LpA4KnqKFJkvGhfCuW+2iAnlZSGH +oIeaGz1KeQ6ZQuZGda5FJTFw1ZiIDII1SyOslVDaygKif1csADr30ADzS4DTCYLEI2NmyoMlE1wo +eTK1gTlhPlHACnBAXa6CJtuZYh5njyEEvsq9qQRBvjWW2nGqKfOhaM9We/8z9T0hEn8xZPX/e74Z +rHpE6yUcVEqNxHTdVJm6pmsFyoPZaBEaKccmdzxQ8B5A8ifSl4WIe5jD4dU/hkiG79B335wjTplE +/fRIOcD+T+e5FtpcI6CU0K8FExCtwyuwVwb8Mtik9aSuOn38yRCXw22NjUQi1stDuahZFwokLLN5 +xqnwEn3fylZuPs5WS6NvLn8x0kCSxa5C+WE5HfASM/EiuOFM91uhulW9n/ihRE+9b26FDaj/EP6/ +bbMNXqtKWPgUOe8oq7ti4mmU26b6RaNVkw/LWgGwZdUjVJgWXVqPYwlvRO6BU2HirmK7VhQQPhx4 +k2MdUFM3MUJloJwCspAaMpV5v9b9UT05bCggTLJ+Gq/0y9NF8Jq4rNNULGaeFmJZ1p0niFGAaSdQ +p2QI8IaEw0WfqlrhZBBRGN5aYxO1/7VHUDNBFE65QxNNWbVhGRk9aLgNuwaovuOS134s0qK2FpJ8 +5cnnTxSrnkmAENtPsPhId+0oMAjGv17CF915WqS40ewfwxGPsu9hl6bEIs+9RPlVSj1aSdEoX1cD +agRVvBjeIcdUIUcYrOTRtqeD7/4DN6kkPiYtVj6W8vpBJ6y5g1a1gjsmPWDMPVGvaVyzaTH5nPfz +RoICopHOKhCrAPx6mrrjdv4skn3bIVKaW2zIFk2EWcl1BxU1b4i7jRhqjXS48V/6uWxlFIFYPJXY +iAIgqvC6d8BIYnArS7h0MNOgFM95fFhujslu/38dOswIukiPGN0TO1aatw92cqge+ooK7VrlvEzh +rgFb1qtd69yyVbr28cy1dMalfP7PESezHYmVbH9M7ORbsVP3mzHYBokI1aeOns2UUqC/0AjjFa5g +tTdK5RW5y+KHJjg+RdTMo2wiBoo9Z0lfX3PsS+Cbksf3UYSWPGVipp98pNr9sQQBda/98reErhmy +Nvdzi/GyJ9eRYPtDYECLvaL1W7ZJA5GLJEao973ZzpiGYSpVR/sLjiIXlO7lQYBV13TYP7FxhHZJ +emnBlUOB+qfe02rxyM80jRmx9TVbMB78K1ZbrBIPmtpIA0eu/qn5QrylQCyQ48cNeGhgG2OehUh+ +3OruL4uil/wO8pht4j2Ropo+JJjGiKo+BzvDFf5yhb1VUrPYawc53ButyQVM9/3yURhwZpSGLpa7 +fPzFPuovczYALzeeOv3z5sHD1fp+NiIuGUgvU6q0TgrK0PY19Pplo/5NHNtzoWPt4icASK1LxIXA +KvEM3nwowh/Cc0z50sX1JGPHQudIirM5w//PktvgTMtVgSLKWzdXbg7217fNHLMsHyZ3jPoejTgB +EJRpFNEKNBudOI4kBSbm2c7oSuHTXOP1pBsKHCuXmVK4mNF23RYu5B00BS0vCBXIStXovHolUXlI +zMKsQF8FIZqkXdZWASvpQmZgoPHIdL65rCQ7tf3qnvZHXaiRWiEUZSP9Hy0mrbTpD2I44qYJBldj +O+UY/yGI6Ot8MHmI5VgbYu/nVCHisrVfqgxUTMP412Wri+ReWfimNbEKJfvvxNgunZBc2PArMzr+ +ZgSd3k71goZKrfAFFSmwSL8fBDVDRNov9ew3p/aaem6IEedsJgN9itRRcHPOFNYNF6vp+J3k4vBq +pgZxnRnYMnx2jv41jGYHL5q6nrHRWU21eMMqRcvXP/WMmy6Hq1q9hEZcMRQVcLTkFgLlDRfT+NMV +wdhUK5RLgFdzIuDN3AOtjYXmFbq6anelrA7DRJsj55l7bxe8WKU+Fbj+BUSZb+x5CqHkRCEzETmq +Gsb1CsRTpEczj+ZJltFlAbkIaFoCvHiDe1sTGcTgHMFwDcKSBKcLfgfbxSQyPXgclwkf32pBzdJD +MW6FjJFv9TrfGGtiGSl5n6k/baab2NdkVpgBjg7FAy02j/9hRe8Et1v0wUJTH4g1U8cj1igN+5k6 +i9gCHBQyldxRq92k/XC5jgpLgXcB9WucrbNbBA1R5zfsuFDiDfDWVGPh652vF2MarhmLMmJsWdki +JcHLRZo0zb/qPD/FKgGWtVdHlQX29AlJ0jkvmjp//i+t6pIht+plWS5D219f6JriaR/FCUUXv1ZS +Sfehaa5NgWXw+WYD3se3SWyKoE4haifbT7aaCV7oQKT8tWZsjjCNsI6ryY6HsLQKFUIjgwx5nwod +RxPyvpFg1TFA4329encaAucPaSfLOWmk8NiP26M5IQGIeTaZBRj8HdUSS/9nQd0XLO+pQD/uh4iT +43QGCOJj+s94dXGBAXSocirDLCYLmLNpwGYr0TGynw8mZDcHwekJSBAqq0eyIVrDK655DKE5LB3c +8yg/UYHcfD3iPHvd8kCTg+GiTXmmZcypkwxhwLpGl9bTe+AtAAVvcA8ADP3Cm3ug3KLpOowTyRUh +7WRNcrG5Tz8esTMlY+bx3PEY/C2Kmf1Enl21rePFopk4W0QZh9Su1AmehCGJEspt4CBJLSSKIssZ +fymQZ448a7airjJfL9k++VUdVkqJBIX8G1/weLnkRbrYGVR6AOJvzsSKaetSLv0SjslTEV/7XV4O +05u7oyq+qGxXOFi4IhQKf8zCLta3tPuwLu8ERI0gSJc3fdvH6hVTIFzGuy0jCF4MaYdPDmlO3iQT +tcUnrte1pqFEBRfEu+ayysunodYyDSusSp/gKECB9BuLKpiCaQJ/yG3JPE+4VH+Wi+TldON0vopO +nR4ZUnC7dY/amVdxS+mO2HHurAPQlXevGjZDtpPDMpliO3T6Zwn4RznRjFPEes96mrna7waNv8Mj +cjTgJiedQXZ0StpyTe+sBV4nxOUvt5eC+ICzyY2bOzGsMEIYkMVocJ2RTfPOGI0tPhDJ9OmKoD0C +63bLkjVlm/UQfrnjwZ8R3S2S1gafPY/p+IWBmr8L4gERvle97JkHrQbMA+3JiEu64aLedUPcSIgs +/Pr7snFpIiOeM9xK9pasjoPnNP9BuPW1JRovph/WdZYCGdQ2SDhjm9Md7suYRTK/W5EIR74qBqoO +OBL5B1tygOzs/Ug9CVsarFhA7HCS+hUIyZpeP29x5ADxkHZipZDCyqq47fK7o/PCLM9AXsrL9JUh +tqDVMxp4+aRRGJ0zHTar/f6dAfczKpgCDWy0waj60FNknZ6meABGyF2paVfMyoQbXp2v68MBqMCe +t2GmzoVM8K/mbJdjXMzOBAZ4HGhzXFsTgQGOqcEurHFvk8pyd3djfLeWQJSw06TrJt8EnL3R8+lY +4FSI7m3m4bzCN3uFrGkdAy4t2p38MyXDKQtnx4U7sCSCCQNRUz2VnzjLci+IeZBhldj77t3cKgba +hC3RzBtqRByoeH4ulQQxZ+MjvHNHbvNyYPPL7++2AVXpUiKyP84G3VcksvTgkCR46xl6S2NbSKQ0 +gYaSNfiTp/OVlnFrWLVgNyf9WczQmcbsKamvRDY7KJqnO15+Y2eqKnL+aBeC+R2ABo+tskmXefDM +jp8mIuBU4bfKXkZB8fsQTb96vc60rJNQ+4SNiByxLbWzQSd+Xk/YLy1X4T/b6NgjjxCnTe0fwCjY +s7tZwrj3e4yXKMH53ZYK38EGblV+LAEh4nV7nYFKP5v3v2cOpkLU/jTcFnK8+U6XkMkWX9CiK08k +WnjpsMdiHDzqNLl4JkqPTIOOQJHG2ZVYK3DqVj1TMIQXJZipZlqILBxolJ/QYny6jZScQy3NziFD +p3iKKMR7Ra4UM6OhVl4djAcjEH5eKLoiuRTSKBvyVSRrtjD9xhulK9TkuSAUQXbsccuQIkywQqCr +pS6P6jx43LvfMN61VakyhGHwSHIoCiH6ZY6hAa5inVyrtDChgN9Bepg9Qa/i5zpvJFfQMFIORmEe +4znQABhbE6PD6gy0EPJtyT+9Zt0J1/AnJueHnq+tpixGJ6a+3R8IIi+JZ0yrWqHns+CuF5hO8yjC +aJe/7QEnh8hDmPEYPl5IRAG7G3Ypy7o8Jqq0POlSzX+IbbbUBNBfPYo3WfGiEG8fX/fxX/4ZfoZR +KaUT+qpaKrxi+cSqobWeOdezesT6dtBNde0CU2Gl764DbuOzFbdAihUT5vUOxAFiz9yF9jQpTNxh +95Ks3TpT4+FaH+reWqiJvQ6IvXRrfPqJ+72/yJHqsqdZ8haPZsGRTT3FYtXtVm1/s0ZjhabwsumT +YIJilZfZuzlWu8Y0wLwt69jDyWs1SrV0ydBi3OZMgR7RqIxN7KYyAS+AQM50+/DxnU2Vkjlt4Fdf +M8rlcQw4pU0N+U+zmLT26mhmNRu4FbWNJ+vNlkoFcLAYOn/BrHg0xLW0DXXH2nnsSSbG16ky5le6 +9o5UpTgH9hohs3NEmNEhZWrtHLi/NSRZQx6QpVzpuaZdzBDv+XZU9jr4ZiL5lUV1RhemCwAwCwtk +dJ5632cBAy24Q9OJ37XU3a54/gbA3Mf2cM3hZn1FlOsqgyQWoamjWDLcEyz1ujBDfArUH5vbgSL0 +jehIu6yM11kFCmak07pSpyEclN2mP5wID2a0KW+JaiwyW+5L7sSHDxC0On/HcJ/eGP8SgS0TmDGw +lE0vJHEzC+JdduFUinGUxnwsvsVhM3oVaTojteIEg4yX0ZND5EVmyO13ALQB5TLwVzmkswspZ0aD ++DdExzWbiF34a4KMzxBMIqs2c1oG2IosnMXNq9Vrte3V1HMcb/oCEcRiUCgdXcf4jM/nHRm3y9J0 ++LTki405XCqJ9sf2ruD+ftX5rFHVPqU1ha+P7fiRF7AYr/R72D6cy7L1d202HyWqjVqa4t67aacR +/vWUHdzhjfjRShfHw2+LM4kcXagOzTaLWZbPw+Yh8EpmVF0NL8Fi32YWJKaXfC5xAWc/AtGk5iYe +a3U3GzqkE1fK4qGrq9Rr1ruRnkMvx3yTS6t4PActqWVmTLXTL05tQoAdWSUA59EUPIqcCPqxsUmG +1ub/thTVXVTU4AB8m6pg9rQk80cPSoPX7le7SvpRni6r3An+9hvDVDpcUR//OB6drtKorMR8sWRw +Fs1WQhS6dZmTJax6eX9h5sHkOEeqt1SrKMV+V8KIGoJmVO/3zP9ZpC1KIYjDZVrJVaY4oyFU42AA +RUAw++2FUGVuGhW1P9pv9FzG2tYLDeh9RiVjaCugmKKYNIYB75YRwh5Fb9/k6P7VH7nQBd9w7Gh4 +IrYqvMBY6zkT7KNl+DgnAL/Jq06KQhIkEaB3TNtyrjy2mZu1WkfW6FB3lH2KK422iqdi07wibadg +M6YFdpvlbwA3LX/pIKRRMvTPpZbwnt+tLN2ggVP0F5yBWexowExyzROay28DTvMXUqVaxhNCGyOL +ecrpwrb5NsmQt3JMl6z8rW/Hxn/5omTPtOBVWQjbDjzjJ4unH8PyflBqC49gPhrLU7h/IC5MLTwc +Uc4QhZ62FlegBrlRg5yBohug7UkHJmt6QKaWozKiAY6Tfwp2ZhSbDVQ2f3IHRxxBpOkE+1gA1e5V +3s9ijKJOM7bNwE2+hWr3EqpprVI3UOOeDPx7Wo8K6WYGGE0+yV8vKCdRckfE/2P0wPt0EKsVi7FL +ALwFNzKGqQi0h+Uy5MkpL+AOJORyfKgQoEZJyopfxlAWNJ2Lh43VjewvtlPiZc13t7vRDCCesgM9 +ddwK88Oy5AOdX0a/qy5B0MsJCu1ynBXTE9vVaqEYbg+FsuNzeyDpyYT7IwWGiJ64WgaazQMFtD9/ +zxOJcGKYZjVEDFS9H6LSNFTPXYF2BBHVdlhJWeqsmyOD9zxR00i3pkVLf0rylqud0cbnHQ6hanxQ +KYkid5uwhRYC51Bb4rRrZNMh8dBIRtrN7e2cSyW7q85O1d8OW+iahg+U/FpLEn2c/LO0t9ZjqEmN +x+wE4Sq61uL9tHhY1MOYGL2cyZyK/dBuCwcU6PBwpmQXN5kYBOGg1IkAZWHbWiIkDc7DwQEj0zXe +YJJN9H5mBVF6cQ5BXiynwCNZLrHO1b2+w1AQZST8EbG/okVcA2dM6YSceKXfbahQgTYgTLBDVlBy +xNOsMX3XqKkqVH0xEwSAqHF9+2qutX5vZhMu+D9G5NkSpwlfG4nb0JHePgXrQrGQV5dqzrHziE8J +aHUwMACuNblfAby2mR/Z2YXQIuma5B8wAG57oCHJfJiJXXMZq4Kh7M03o43y0UW9T9tVwEI8E1KU +40gEJHM64yzBWM1jaPJX4MLvNXLhhmEZZALnf97ipNwpn2usL7FbNDKYnYuLtyLzWnLtaU+cYYJi +efUj0RpLRneKpKS8wiotnvr9kDElIbMlAAFJzxItPMQ9bdJSdeFY9VT64WfipV8X8mFmiUyQ4eDh +9Dj3VOs2jPpN/k+/ekoBy/P1GZLKmpueb7RJcNH2Oh9YwOHyhlzh6OSjBKY2uembylG0KcBABWUo +O+546iHU8b9lob+GyanKDG2oV5S+10g6z0wXhmJwSn4RxaImDYOIOOmYwi0yAu7ZDBPrMpHdtMJI +JU/65pUQ8QXfLz9uEn09AeJVAQxJnUgp8J1ZD1/LY7Qz0/HuTi3TIGVx52nily2O5m6UDKbn5BVX +Kt76qXKzGiWiTU/hi2vP+aS+kq+KlMi7AmIeZUuyulymKjbdsvECmxJHC48/c0czhKfGMqIocJxG +2tICgg73FxMIycUSIeMVqtlykX7grqbJF5lhocpFbRkoEVu1h3Eab8pDqBsHtCO3jAY/O6tCAsfF +BaW1qPv8sPZGBFkqNf7AuSNEvTpPtgS1tBhtcp/4WwP8IjKpEujgG9dMGIlILp1gVPywR1gj3Ci0 +EwY81nwC1p9obul8ZXB/08ko1wxHpZXD15opLU5O771tUSUV0E42U8RnqB5cLgkZ3pA0k6G0snn2 +Dv/897Vp/uj55JVbzSm0yJfYOsQPDzqHsbL4gRa7DaOzaNiLtNaMByvlaoc80sqDXZtl9q96ScGu +WrYjJQaptZiP7cJ6C3xn7VxxI0MvVbx/2uS3XCUe9WG/R70MMOexkvM390us4CG6sg90lW0hThO8 +JXhiztXkpMtM1ghG8/Z9R/QWhY4AWD6L0fRBcxlUc7IawZdHwJSEuQkoasiJkannP5PjNogMTkWx +2hCeancgZWGEt4nzne+PHH+70OrUNuLLmCZBSaZ8dIRU3lcnNb3klDc5325FXU0rq1fEFBuzegY9 +vb/b88M8LQfVZMSX65+mFivH/0S4+Dv3QboF+/CdBKl3JTjr0O/RCXUvU1QJlJNnM7gMxaDLX6/V +zLiqbelH9K1AekfCudch5z8v4va0CF+rJ+vVHDVGD/Y2fX7l6otN3jWHRK/Pwq7EAAB/alFv8+yd +g10FUdanodf6oEBmOlbA6gutvKrEMTfxlb2sBjZq/1o+ufo+BtVj/TcYBVka0agGFh5yYnM+wQM1 +me8OkSOEbH1I+C5PPFSFOhKzzBJ4F8THn2hbka2wBH2j6EMaKZg7l2kCqgbs8ll/+2LBHJ70z1k3 +tOVJ/+st6oKSWB/aD+QVcnCZiYD0+2CkMaO5hMxmPENJBoqXyDzgEEtGzWrxIX7K4NLlAmsYJXqh +6VJ3ET7l+saf8T1lWNFp+NM5vrXVQ5o9nRlfnLfzR/kKOrIWndrafU5UjqS/Jsouf+arAaUAotql +SLuIc85auRl9X+B/nYmSoCjOTwWVY2Aeozwjm8rs6CugSAbO28RdO0Pv4g8M/4mk+5tuhLkuecrx +Gv3GEM/KsO9HwqvRk2ggj2zbvNAizNIDnJvyzwY+YDFyEEFbFAWefuK9iI3YY0Bh2dnCT+d3of32 +YSsQppEUMx+a07q9ALMxMfdudVJ5XyZ7Tc8NpHgCG79ahSvy+7ISx+/dEbHuRDQiRDGLzVAn76kp +v0HAzkaTOCLJxg65vHPeaNlUMo5TIFjD69uTKC7DS6b7rn75snWKin8t7b5pYpXKE+8tEswpIkEv +zWD6u0dacIeh/4oZRMqGMGf9/J4hCWYmHAw3DJw+q3MoKZUUkyanvI6kCFxSXqMBcLAntT9q+DXX +eJo0slEQRbi461BL4Y9jSZOal+lw0lGiD/qzF9IMcRvryxaFyfDnFN6URHv3/e1FFphzbndo12H3 +/nQ5qJlbAZvxC3ECGCfCiRdEtbj7F+6HynSwdFC16IkSSq3bUlEmHFxxqMMrALSvYjwu8+k+fSzu +z04r0OWY4RaBmCjmVl8D+BUIybiC9OuooWAtzQlKbXIVC0qS54wiaJbaR/sHO7KHXDJBfQN35Ltw +UHsOif/3gMd3ZSqBAa1oHq1rIEBPPkS2DKaGgC8hnZQOHGPnqdt16jlm9aVUHBQPyEMgLCTMTIot +tuDJwiQGl3DIMxlkRzEt226S1rwPmQvSYagV+YtlOHH0xxhyosu3t2sioHXI+HVzYIae/ZWK/7Jl +Y9ki7ESTfI2dwdUoJezpA7oVURehDJovhtvhMEjDO/lTkWFaWo6ow9qQdMzBG80vePaIpgCgGli7 +OK/JJTzLewpcrx8uNYPFmW+Z5SHYV19R0+IVqSsBCayss9i/wK+IsoTmSC5Joenoag4okyHAAKsr +LYEx9XT337tDEC/DHXimq52xEBpQuecl5tJSddUnLs9DEy1GPqqFj8wlZu/2lzpxrXJ/553ZNm5W +Jiy0osyxo9qNbIblRYQ5l4ngIpkO6pY4FOIhgA0GhQoSXK1HeEVSygNCDMhMIicFSwX3uHkuGDFy +acR/y2DYRcEZDpm9+VgUtxa2tCn4QN22zEik7WxmyUjNeGGBJFIfB5SxeC6L31fLNaWsGj6O9nBH +DbFSfgrWSPdAQbKhy2QWfzjdrFsT859sQINrKeoAybtbFZf2Xth9xPf6mpf0P7XtcM/Wz02kY8jF +C8lJgyx2F0f2uY5ujjWqtDrWgKb7ERe9mM0tK3Cc7MHcrMNbMwYZJH0Lu8hw2HZsw0tMKyNzDHp8 +3Q/aChZh6ra1s1riGwvim14IJz+Z0ZYqWHsJT8NfOPNBjzM2FB7mHwFjJNRmh2drQClvrkbPebaI +A83opGcgSmZx3TERxKLsLcWJIRM4ovy1f1BX+90pspPCF497q4vFmdntN1D0DBmySbUK85aLNjUB +NaO+6A0JwmjMbnkWhkJT8C9XpfZ7eCUrOEBSqCCqB4ABcflQMy36EQFHz2QcpQl4FKdOpE+0txev +HcmXHODXbEnJBoeozGSb0sY8HQI4cnTNAGcZXzKK0/3q5z+RcZrQk7XdhcSYfplW6ObQKXRgRAvb +gHUsZ9EUSvZcKBXCbxLqsedx9ottpIKpz8qcZOdtrB1GIbQCbK7kspkzTH8aAxq7PAoKc3YtGMSf +h49TTbhXd+BT8mKkMbuFjNGqlsl7DvbtwZWucT51Kz3j0iKcrU2yZwKR3y+ExcDAnou69xBSsAhH +ks0zG79P+ck9T5mKrpKia9TgDhL/fZv8ghz9LC1ewac8/QRqlCvtjQXx7dP27vAMoqUsQXJzB+l8 +mtlfZ1HEaCgSYKo1YFfAfeLwupGifvIWHLuuqU2LdVK3gSGvCkNFdeelRCLJg6wat1fRikwBYf6U +tU++5TIBycCEVN87mdFtBmknslWlxvKPPCT5UHjkl2jRl89bsioCdLVV/7Meucg+6934oH1M1vKL +fkCkJX8+BftVk4BZUT2eMk9BRMwX+j8Ap0hl8X4ZyGeCR/MROKby8GVHip2k23IvuaXxNGS2Nv3v +0qPiZW3PPUoxFgqokRiCU47r0zklDbYlRUEMDDI3X6MSy10cAtzTVuZiXpThp6b0BEpKAmcipkHf +CDDFf8hWEA5olvcASPejxFwTNEPUDK6ggQdMvsagPwgsun8Z6AZy98ibp4ycrm/Co2/CXgkALx3a +7lISoZR4Z2Rz6xZJS0a8nHFHjBLNJXfiHpU7GpZfj2C+AzdKUQiuD4OMe/SPnFCxPkmFxT+EAhFh +iVeUd41J/97L9NjSrRlbhmLnD6mmNfnMD2eAFe+fDl/cnPp/lJnOkcxX2jTZT5J21lJ3HQfUzSky +6Irw9h+ImZDIz76vt+aTB/3A/fvSKV3MpNKQeRakw1Esq1Nh8JZfJZROwdgpyBh0n2KhyWCRGwY6 +8PgGuti+rse5WC/5pWwLSjyqB58I3+lEZYa0ywcBJ8JHoJhXUuhd7sSA9zNiY7g49seRFFLBo+Hr +8ye19L6ekIubusYPQdGTQqTyokLt50GQlWrBCHSg9kvTcuiR/GvXrnnErPfXHSnypQAj0PXdq/77 +86YOJ+P56FVZoXk7oMSyrtr0qgA0h/wWwFea7LUCI03I/eb2qlUVQ9yzdSAkn6vjVnMuYi9J85kl +J8MlbAQV7ViRgUA7HV4Jz7Txh33nLp4qir1OdB1LEK8S5HIn2rafGknpGH4+oynZDomSeOxMp76G +WlDHd2hFqoVKGz/y7NhiqI381ejlycCnhoFbjeR6y6vN9ew1Q7GLkFP/FYgug2p+FXN1SC0KRjLD +XYckTkCOkYZtLeX0C+JgJfygERkAtre+q7KjnTko26Elq+7KZKZqdd3lcs0+cgZxdua/g+NoL3sE +CL5SEw04gqOJLfIIvRhKZ75w3uNI7dEIey4BhES73aNGXsl4StZmE63mxxLpKT1I7mXzriTGQJbi +2jT0z1RA7C9iPRCRif7wn+zZ/uEhNLtwpqTTCYI1u1jivBMnnVN1xMW2RrKV8xTNnrd7uTXJWZSZ +adNkAvoeQkfp+gdSQL0yG3xEugXWY1TRwP79vNeJqPuwXSu+i87R24nvMhkfdZYc5QBJkvXIPR/R +TEIrEmvbYMDzK02uj4e3cnXCNWzLPGLcr9LTjZYnBmtUir5Y/PIxuTB8gXaDBbH2H65pfviRytiN +ByuuARcVjDxAY41TEqxh86mD78zl9wn9bmckJdzrnY/nzW6aApUdYitm9OaQ8bSLmBgyPG6YHy0I +ZTYhE8/UCKR/wYzqXhyyAUoV5fCnG6EFPQ3d42rz+MOfuItYfJDXxQTUrX0bZKV88vFwGfB7d4S2 +rymRriXxi/01017JIDl90/vzz55QSjMZ+Mj+m83bbQFjBF/wwKFLIwqfAijn59y5mhXEu3timlTo +i1POQag2B6gwmC68DoU9qeloSufyRySWA38BRW3RaFhUAP+W29N2I3Yi6a+oAYjralNdRHBPXqiv +Fb94DQUgz1+oaW1+hAMf7RZ75l16hEvh9VywSddoUe6jgSz6YgiOIwbDw7Ga8QnBaiZOFON6cnkS +nZBAxGXYEyj+EI04Dop8B1VCSvkCU71FnfgDSROAzruYzaxmFsWCLbyB//SMv7jFORHOIPNjKJTC +B44j/srqmMn86P7HYga3J4b73yXJeoIyIe3Xm5ZaWyPYnksx6t2PJUHhX4N3mhLHXG0APN5bXmYs +5poBhCLrXMVYHhZI30bOCfKODX+cj4maehh5AR+tJy2vd6WyxqhNMIMprroIkR7K93k1yGjAXK3C +Ovs3a4mdZhqV2j6Ow6RkokHJ+0Ch5T5F3K2npCRezW/z4qhgf9YrVisQMHpvydZkhhLoK1OZTLfI +Y3Z4ETAWmxFNPp6Nq8DLq/q9SP5HavQTysYlGjtG+AN6d5/Xr8ToMyms0gWrxQXyrB1GcC2kGpzs +JjHiKQ8+xuVgacTo3wYeDsshgqx+2TS0i8pd4BE4s5A6M58Rxy+J6jWwLCJzFXmTapuBms0Rs4/e +Q7qq13cjKMXUH7wZ7gHz3nPS14hSen2kd1GytIXIJJ8UpgP/Psef3Nohi1D+opThzE6mRg0C84Hr +9xgp7Yj7JEN2pmxLFSNUk+ja2FzJ52e0veRmdZKneTeC/FsxacSLuw80o0lJDuOyGVrVf4XdeAcV +87vWe561rEBWr15kyxEim+lxpeMcGy4o0o+xEUi4elHAiXwtIv7bFEsAiO60Xc1nTx37z1Us4/Zc +eBA+WrmxZnidPO33B/XqnZO9zUuimh4mKn3FLV4v7vm9MCHabVlI4aD+8TT6/f4rW1mFtmHiQrlv +CDIHgkPA57gYTmwBCfb/XiY66T2WyJDZ0yk4854Xf1W4LkADLVRnMj7ugYQT0j2+s2mARJQM9Yhj +lY0rj4YW9uheRkK5bycL9T7Vel3Dw98fLkGhjZhuwXp/ye0K8RmWbdBQym0auT1gdImCjiNSAS/U +Lx0qYyCOrnNqImz0jBWZMEpwZE7mKcV+xjLjy/TiY3AqJt1hdKXtiyWAPLszypkffd4d32zl7o01 +uXv22d8Ag7iT/Zu51pbLBlzk73IuBA+Vv6F5Y1PAxZCuavJLmBCaP0gF2DYZutUS4Vow/Y+yljdK +ZyybmL/SLNoJKo2aJpSO4f1FFDKCyQGl6gCO6zO37Z5IeXEMruANWgUlnbgeBRiCRXq0ckDllVkB +x1CEWZDCfsr03iHYdw93WNYw796E7a1WEkksa8+m2rZmQLrpOR4vy/lwQdlGT5pSFkO54+6d2CYo +PdnQqw6u3492V++P0pXLHQIuAy8KDqDlnihHNFtKNMuYoSY+6fWr639EW9o4NKlIzHlB78cK5LoT +UyAbsLBbOYOnsf5PB6wQMfWM8mFSg30X37CjS5VwIQhmbQt+W/NpurRQGd/hShSOe6YNFTRG165+ +D2vdLFB3woXw5c/VQHevcvmm3QxJiIhFoJYgZfUOPiirYfsQq9mLap1dpPeCpfMw5l3DXWFtfdi7 +XaLPF0CxRlz7SOKww88ZaVJaek/T9PNQyLBSkGwjZY/y+IG4fqqeUoLWw78hRGKmcbuFh4MyUWGF +lC6eqMVChyUCQkesBe6JMQ5zV0nCn6/hrj1BPu3xkx5qeC7nT5aYyx07MWvyYoIcJ+eIVxQEZ7Gj +GyqDKYsz5dSpBX+dTj2DyCfVx2KBMeFfi4Ecuw+IFr5w3TOid5rFwj2hQSQziMartFir/41Ipuxa +i8w2cNrCx/uxh8N1ns67ezvveJJUhaZzHUXk8VW2CJ3XWzgUdJBxekqY+VBPUYwNd2DpIKNqbdoh +/Cz7Pg+k/ctKkR3jifRgvuRD5VVXXumg40iaZSEmLGgYBZM0riSP7cf5ysdXLnB5GjWmG0o+volC +iFJO0LstqoJXSBU1e9JBVjBLyw2trksyWbXwoGIn1NiDs5su4/vEp5BUzN8U6JMkEwCEinPhqj0V +VfzIXy0z+1dfccS4lHvTWFdrMuPGky2b2JR3oN29HAYrxAB0YYPs/ASlDInUpGHMI//5HufyZoEQ +8P/5uqJ110ZKrgl8wxoKkTL6BMIMgn4ljL5ezQONuPQlPMMqR2+vhEGs8KMPb7aQyrFK8rTUD/KL +Oywd4YTIBTuzMnqlvDiJu4QKb6OMFNpCYn7qVL6y/XFtZh/dikgfoDUd5FM5gUw2GXsl5WKSYSgI +nj4bG2cVs8VE2e+s7RBAK4HY8pYReJPH0L7JE9OqRrTScJbDaIQUqzZ1NtHyqVuciLh2+yE40K3I +6691je4mjyNv/fPDxAnQK1JvDOBW/VhJH9g3FXVCaGyssm2KWkassEFgeW4dvb+nOTxlEpPgl4+D +r1bNHl1b6UCsooSocBU/YeeylNx6BEk3j72mXt5Fslexp2jStwvELtWCXYBFjm+v3B6yYgA+FGP3 +YdE2b4nT9gpx1uFI8KwUa8tg5Al9vxyz4B0hZTPS8Ef0Epx0Eo2/2Hd3GLFa5F+m79VFPlHmwnhB +YgzFRAnNxVrgoDobbp9TnpfvlLUJvslAB+1rgHKS7/0QRju/rKPunLxFNrpy7ir3Kz8oWSvLMfbl +uzGcz0zdvDuVhYhYYnpTeEupAWkzosUr3RwhltZy/Jc5oVWmSSI7geWUxDYr+sKSjvqy5pEiNmU9 +RP4Tr/2c6tNaSrFjEcBkOJsMDwQxbdyoduntFvRVwWN9yL2Q65sU02WrZqoG4cLx7JJtYIIdvk03 +CB3uZ41zK2QVmfxo9VL2NdRjdh2pUlfSx9hvI72kVFQE0wlhPnVisHGdApHwRfjRIhhC3TJjIja7 +oX8hQzzZWG2F4aLy8QmmNVccgxuGS/2OU6P2Ba3YsYISs97llyGJBPjtJVaG6xf5QdC9hhdiGya/ +Z3Z2ubVrN24yJiezVk1SQfrHxSjkS1LALchgmfXOzRdQ2U1AHYiJIX1IghxiNJUq2YIRdXgAPuvH +Jl+tYz6QPKmghyLc1EMJoEkBD6i27TCzy0BIHegBew3rcAE+NLJsERZ9Vd0P9K9Cp87N9ow+E8mp +n8ECiSvLju8vQtsVf7F+u/W0pEx4yN9Ik5Z184EeSnPl1VVrpue1agBdo5dIuS2i2INKhUX2VzaQ +Ckq1tOag8/CI0qdK/zjcXQ9HdAOv+qUNbkYrJ8AuET87fw826G6dLVs4wmmzNMf6YHFTvqzF8kd/ +vcPhtu+N+cXLWVLLyVeKx1z9O9ubh8TWZTeK0rq287LrYfoL3ZG1z/xD9t1OR7dyFWAhjTvy3Cxt +CxntdMaM9C5adQ6vZjUHpSJRGG/OZQxq8x2jWno2BcFZlo+XrLNuFr/aohdZQvVD2FGon2HhDR1T +1I/UEXkf7z/FdSSi6X3s0oiex3IyqW5F5WZoXOwAzTPOVSJE4klIzqY0p0JSrCKbTlWztF2nr1nj +8hMFkmonFnEEEKuZQZyv5hAh9kFSii33uKgInbxeCYe6uBcpEV7RDmiNqx8r5X1+y+QOIRhZ9tZN +sGDDnhWF3pFaT6CGk6ov7KbL6BMJNQDLiWXW/Aiv7CLy/AaU7mN6kZnNRIOO2kf++pVxxc1vlM5m +7G3zLDRCPxBzmjZCzmhxGvCjeujGh4wAGAwXNXlKDA8Lsh3TczrBIgQPOg5T/NY1HO/pTE92N8H8 +tIz9hXiDoe1TdOdZbPJkS03HfqqqXrHY9Bwm4e3DE9cMAb5sFVxXRl2koA2xwd8n0nb331wCVRaE +D0LrQ6qfPQGCX+aj/V1T3m630ZH0/sAvBoLMxEX7ViQY3v/u7j4AMPwSGtHiG56fPOrYCuxVIHWk +mH3/erQFWOcMM7irFDRXT72Z4xvr7u8rA3nbs2a4BmFV3kZCLo2EVrlS7eJCQFO1yL48r2egXGlE +cTXWhCFWkWltFNhMbrwiKNCK2PLMpDZGBgT57ABxBM9q7pVyHw4gub6aNIbjzkDoO7NyjdGfcrC6 +sHr7SDi5DOY3mOQb1pXVUimmc8HVMyXavmayCmHpvWIJG/D1pHWHY6sl/BIMxrbMNYSlra5lLkZ/ +ulnJBCJUHFjiOtI6E1lL9ocXHxFjuUh/SzBB0vfljkBeWNm3k/VZ3leNxU9Nj8yaM6v4N+4eVvaQ +N+z+ji9R5op1bbYsSZdNW6/0q+OiGuHcOyEv2AczRLStILx92MXPgyP1bcO4mpPZXcRMk5Yis6RR +SNpPEzADeose2NfW4u6V/0RI1WJ6doYm1MKEg2TuOkOrEyjuI7RJ+LypuDT1cfmqV8UuJa3gNuQi +BKV866jlAU0A7ke00jdPrtTM0MHDCjgpWwXk5mAkxwwuIdxUOUEYaIRVA0l7gpPOUllWF6CImzdK +h4FzAHMLS7har3+zKkk/WvlDBSGoFdQ/tDD417w9HrZ7tm8wX8JdiT5m9BRPR+4ywD4Gn10OypfO +4aYc3FfONvubFIagLPd11IB6+2/eRgNifDcsRQNX6pwScTYPO9DqtONCrdaKAZQqls8MquKfalUz ++/gMbcdNXI0UZPddjfEu62CeEyvIaMJHomcDp8Ga8Q8SZDHiZuzcrjjF33ku0JsN4hj2l8CCZ8C9 +qRbts9QXfaPKS8Lpel7bhII2DLTqVIL8M/sy16dpYtDmM2vyPv+X33uu0TcAsK52FgJWmlOHspbx +HawPhIDTBbnGSYK7GjqIZ1bppEjFqRIVWIpmmqjopoOeIfPJPrK6+R+CGtQaJPhDh0JdhdOu3yG+ +Q0OC4YdvuPab/HsDd+LeTujNPewJ2cGikVJcQVNYF77G+WqhQfcNZHpBXKA5T5Ob4AfDsnm5OHoa +ASh+OhcIqomFyezm+9ZQ6Q23q2JYapOoZBuqcBwAVS6a1Ym8PpXu64zOj9Y9ceW6+Y5xnObTbFpo +yp6QGTCIPvwiYv9K9nIBFqhD0hV+SG3g2E6hsusHUwRDOErXL0CehTJoUMI8oVQgZXPaWxdwgaSx +tpBn44xaq3i72dBYRDSujuyor25YGMABTuop7Y/KLueFn5QGlGnaSQtd/Gjfq2+hGYbpUHwoeCE/ +s/7CBx0HlKq8lTITMTW/sVGXaKuxpCf8HEJ+qBr6u3jWurjkCkuYTowLdLi8vtL7XA/tm20hZfjf +efF50Ym0lytW8Dkbxf71MZ8wnDM9umT6Bm68+2rRtc7ipS1X6TIFnDBwb32PZbq3ZcJONfbvU5mL +9rX0XjZqWruwJSWaFjfYBYHl8q9c6jww/ddQOM8ixUt5pn1/tCRzbZ9ry1RBhZfu/0OI8GH2Bc6z +MCeisRhAJBqarPC7L3FqdsRQtGSN4ZeR7mofeW9TG7WPOXj4smQq2G2z8GNVrkWfU8crU1K7WjQE +iiV5/3Jq1rCu9PoHU4NH2zKQr3vt2aak4XDzu/P1IPEkxXIzFsVF5oi5O/Snfz3SCU9NI7Bb9zAe +V8R6jcLu06L57Y6NgZnycGozMGQSY5k6Xt+NGcQR6UYiND0DGtyECC6Ayyt1jOguuhbqJoFSZLeN +TLNxzojQLAOlDrw12nyxJyan8LvIqj6nnlEoQ3SewBPqt9qIRH5KFArT92apMWu+nbyoAOtrNFaK +wlR7NZseJCSinoKhetzUK3XAHHNXWvkJv6Afp4gWKKXlGZ3Nm+puTaeo6o8Nx2dPwxn3Xavst4q6 +lXity4/3hFRaDweIpOrR2x03U5/ZD5LJOOHMrP0TFzh7liZLuRdYMV/GaD09eQfagkn44ftjcwDe +6WfCXgxruJOchCSztIcIioYplzBxeN6B0MIJCFiAHv57HjKroEZOQ9itfA4iMHxG+9PQ+RqRMr5Z +55sfJBmm53f/3hemUhrarFIgvF4JeeksQpxgE7JTEbJGsk8iITCAMvdu9G8m452jq8jneKeeundn +AbVJTnN849U+GHXU3fGUHr23n4R6bvCx1NQer0LIylrlTw4kJoWGqbs48k33oKnrJbwPnYk/789q +Tqg1Lvyx8IwjjEt6trDVECXd2MDMxEFE1LYiDqzFIOXG5WbF4mFvTgtgjny/UuenJYnrYC/USWWp +ZlP803TanyXJ9blILwJYIUrSfYY9fbFWATWC37lQigPn1jMZOgCwvBaO8cZzO2Je8R7k0sc8qg+d +Y6HsQ+Ma5ue4MYpcQIr3Vyrv6ul83EQArivPyssUf18wacjXk44uBxusEEPRycitKpP+tDQmv4Ew +uuZY7lbFHGVzOvU9obhAGcsRvYU1/H0jk36uaDXyNpGhiLTjDeTsO7xSEa4oAQ7yhttB4ISGIjaR +hNODdG7E9mORues3bmeUZkNlazel5TXCfTfHzQ9j7oZsKX+Mnqb2uckGLb8dwI+VvGrvHt38D6ww +j9mfQH5IjpSohHR+oiplDANOkwq16E6JJIB/UnHXLREymCckn8DjmFKzIPWtOq4AA8ktFdXcNavG +vEZ2Yn1svj9tXCgchHY7VYRTwQI6J9/Z90HCAdIjKiBbihJxvQRAjAi5kZatyKu3ivP/TaPKV1DL +AnrDzOKe5iRUjkm3Vs7RAyUVmUWdF+/NQSX/R+TJc98OI8dlgqKu+0/u3GMgTAR1+azlQ7It44zt +CLrS1TVKBqUNA/MFCkAX3lv1i2CCmPAm9gRsRfkdswQNOyD6F7pSSk4Y9m5f2OAMwzCLzoE4bzWd +aTsozIUpdu3F4L5z0rFUe34Z6UL6lKW9jxH7ddbKfg9lvEwbLenXkWsVxk+imgFg5KaU3k2SCLsJ +csppx4LPVP4pynncNLCs4Jk3Q+8GFg2NhYLOAL9M2VLZqaPfNzO4FZBGij45AjNpi0rnHzjmSQmp +2JQY7cb6KtL4KCws57KwBFO/cHs4Gon0fHgCYr5pTTepIPPvJ/aPWp1uDvfT+BwoNWxMwcyeoSKh +cwwmZEdABjJfznqQdQdcC9nQYPLhm9ur+FDHymufZEi9sbDPV/mQtk2kmolDZZq3ox0MvT1Yu2f4 +lCPziF8jBZ1aoyk5RzESgGGWYAmgw3eCLYB94ptj3j5qgZvoQieRRoPKwoO0wZrq+U/VLQSllfPy +jRM5brCdaZKyQc5iojDIQOUfJpYSaW3T4HAC12x7PO4Wa9fDr/a+4KXtcw6K5JB0xMk8wEvkJsvt +XkH/Qi5ftTpENZJ3PpDzyZrwopAX7jYJZOClikYwIeJVymm8NGI7No08RgLiRO66OpwOBBAvIlb0 +QhCD5Rz/NMA28Ogsw+99zDbsdSHdeN2Ujxo9bO6lre4LUlJ5Og8VYDX9iH+zndMun7Y41qZ3Ig/t +cRTuGki7Wd97Wyq1BtW1GBJPtS+hKZvX1dnuB75c9aphMevdKK62020a29eNETpxIuzJ/aamXQz9 +JRcwa1f4saOBzJq4f0sH+BYLccB3epBRG0ZvRQ9Q7qMGr6ZfghvI/nPmOpX5gqqioG0uPy4ijzMq ++6L1wPCSmG1XqcUUAIEGHLxcQDpCYrFcfJBuoRtxQmCec5B3059LsBbMWcQFFbtXz/nftvweLJaa +uSjow+rgxTtM7kx4HeWqLEVzdMlXe4aXncGNH1jzKIY5zHz3+wlY0YJLUbjWQwIFb7NGmvFKsEPO +7EixL0S/cjBkRbAq6EmiaCnCguAWZdekpHj/7LQbR+Z1JQ42/wDZTgvarqMOHTzjfQ6wNGEjGv8X +EzIO/fud9xqHDPdfJy47WguzfFF5cdROofINt35ckxgN6GclfiE8hqZwuYSkVMsVO7zW/gL4sqRY +1FslpSKEd/WIp43szwp2ognbnP821hae84rfTaWr9ntMTZP26QsgB9Y1M/ci53amdtWI/HgWWz7z +1lP0NfDKJ780nXEOrCHFKudT8fp66k3IoRtZaRE4MBefFTT7yuuPMgTyKUhDHKr8DaaAZJODg8Tq +ULSgSSytdc6dtBKOf+DD6JvfNtL0BNiP0PMK8PuxfmjR3tZHjZmys7SELwJN390062XNh0OGMoMI +deezXqXgj20lRM7cm5iGUrPLz8OSlzt6wbH7Jz27p0bSo4ns/ugWL7/o8pTVdPWBb+XwLpj0UFf9 +VFMktXXmcHhqqKUYTxich/RFmexRniubyd0HCGEyEaxJ/2sIvf6rDQd2vr2/yBBMZJCQfm/H1ar1 +G/RO9MDkWTRORJ7N3sfDc7df/nGTocRFi84ULC6d5u/bEtHpt9qv4DxapwPuHsY3xAyopyLySugu +7LA1o27D1lpTdW3YRfWM6zn/y0RavV1G8zRORRZEtjdZJBhY2DwYcgd9VubD/3YWvrUYpHaAmKwp +9OqeqG6muB9qIwl3O7cimWUV1WKhCTibSQ5ZB6Q6MOoMoVmZd1HNDKF8uP3rGuVtjnKWzQVX8ljP +8KNEJj6ZVy1sYgQNvZ7hHy8z+esBGHAxa2RcqW0kQgPPXEd3UFc2WsuVKFTWzinynzD5Vlgf8x06 +9RvK0YKhi79AmD9fOTfg7cYAQbO+ZZfCfZcmcGjAiPho4LtHd2I5Gl2AgaGT2CJob35F1hSsX7/Z +bVtnGss4q8urgLIxdW+1nKQsrnLrHR1PUQUqCBl1FdWX7XqfthPKWZpoKDxeMPAjLGiQESFSSwd1 +SfPyQ4huEp6do5/wV4KVjRSA9KZOHDXneIwWgaPQz3OWWmn1wVW+Pc7DnLMcQTe3ZHNvu8v/zDdn +aoOok47xlc615AT6Z0wbHboI5KpWnsm/D+4S3N77a3joLs8HSC2IktGcwNq71EhWHy+uaN7LBY6f +j87TQCrRrp80KMTUDOBVCOHjLZa0L6L4nodCjHTpyiY1Es+gACXnc8j38IrRPOHHdw+++qwuo9WH +v6G+MVsl/vweJNwrahdiS9cRTclFkYQXz36WMr9bDzruacaz5f90Fe1H5ogP5U7xlg36Gg50dPWN +2sU1u1SlYMI6FfiAiR5Njugev81g3kP7ZiWUkrsn/ns/PhS2Py16ZSUgNpoteX85BOf+5G8FrRzk +9q0XOV3cedKRJ7Pd/FmJ01yl/KsQawjiYs5zrcOwSKm5E5/W2ztzh4LhBEazJOSsShvcmedhbEpb +KJtaw/NLWeXt8pWjt1BGBvPmoj15Fv37ts8scZ6eeDYEIie+m1LAt1dr+U82qvWhTb2kH9r6Y2FY +nB5g/8Rv5pzlfjf6+i3/DhdjUeqFN8dXG86lAu466klcE4mJBTpkAXLsF0ieYuvBwInO+25wK+SP +MX4F3XQk7p2kyAF0xvgiBnFhaTmJOGSiqs5bpL2O+nIkNMJXebQ79+x5K+/Cq4WX2wXBR9QMgG4k +p5fYn1Tztbj/4QVKFEZEmwk3DHC3ZyNZUYRySq1nH5XsFXjKewcz9LpN7pP7GhaeFIkBQv8KA7Xh +2LtgM7yguIpL1uqLUOXkp9V/IpWwc5gv/YbUcJlbXb8hPu6JR4qGrrrbNymn5CUDWLZZxVkOwXW0 +uGIxpDrZyBAW5GSNKvMZ4Ocx36Czoj+dVN51vUQTlzRwZt2JvFBpK8C5Y4CXVCUH6VRa4d/N6pnq +ijXzd3cDQv7d4lCKrHAi8Zx2+xok03UA/dctdLsBSq8PzX4fYNrKsHGKdG1yPMR3X0nXE9qafC5h +KHA2fPzTMNSwuoikNLIrsE36T/AyyoO7HSrjR6xa3WHomuaaHnTZ7SMSwyIp0ufe9l9vLuGq0YYk +YEui5K5UhLBBSJmSBuhXGNXBbDxq2QgrDDkfWKMeI1ES8z/ieQBzl2pAZVja9d+2/QamWJBZJgBw +ANQhEJgoeTRK/AgUbs6CrkLWXaiTSY5wLVteZSVLTEA7T2bFcVYsb7VCTkMyfsutldfW2mUTtDRe +OF0nnxsIj7q3El0YA8olZbPy8Hgk8AUh3ICD+EvaLr2Lw6iYVZV8YIsU3Fo2jOEoH+9F6/6p62a4 +twDCYkx9YoJ51tXU4OlM2bqdtbaY9/jk5w8A5grXkpHtNh7psU+4EkUG+QCfnLziTLxJhqLtjg7D +SKKSz9yLr/vhmYqcXDHgDO7wK+yfjdHPt0wWykkqeXDAzco+t+nzMrIYrNeLDnyHIe/rPaDDeP0v +lAmJx+6mUWzDkhFbG/x/aV4qRvXZ1v/5nNd0ZItOLzvrnXoowfbO3+4308xnv8oEMBbrXcuXC0rl +w+PbHBj7yCkU8lUZheo78OS1U8OLrSn+Vzhs6XaFI0phkfyQqikNcgwyPT16E+LVJ+qoNqGKjd8A +BqWWKbcRJSUhQUXOTl1mlkrkHygiK85CLFIEBv/2AtTCiRsRa9293XqcLeJpHMsrwjbjncPmtmQ8 +iJkNhKGjUsuL9pehZEgG3Sz8oazmB/Ad6YtxmnF8ZgYk6efiVnyhoqg7Y+H1409glri8TzK210uZ +4OZTserWTD/ECOkXOLVjkFzesbYhDlDSLKZd7nfGS8kZlDDcmiQ4TSl6jxspCcRijo0p09UOG1WZ +tG4DKtmfAiRYkM6uym1/gbswbvBnuYDX6tMiOiYYgo8SM6T0+gAh4cpNanHmTIZt2YpydWQcquDh +HbPuo+IvINrkrp56BMj1eTSDg+rvVj9ukD+v9gfmeXSo+k7+t4PACNxT0QwMkGvIYPcdQcqKn9xc +YP0GPZ8PW89+joINk+kpcL7Vm0fJX80D5Pml98J/ZOXWU6vdFrjkLN96YdxcO8e9JOMD/gaWKfGe +SJIfIM4fK1/HN1m9VO5RFI5EiA5tFfk1oYQNp58F4URL1LvNIvWLxus8WvBTD11jQ2vt+vp7qX1d ++kvFdvZPzYCP0GbBUq67l81d+X3OsMJ8DNJb81ka1c2wC2SZ18HMpwWGTTFpXZCwkUrQXpulUr0Y +GrJYU8e9hxpasfnQdhdriUz4I7VyY79S77bEEAI28F3uSwMhhn2A32EbGuB46/UBW1P2T1FSkBVe +Dyp7YP3NwSVttlezaHU3TERtuRp9C+DCWbkoZLGLAN5PXUSFNbTntAjgDsfJPOYRNF+a3y5SEjHU +FkBgbOkt7CQzLUrto+LQFJQzpv2gm24SCuxnP1yjUtbRD51/LQKTTBcMooW9gJalbtBtoLJ1x5w3 +HIgKO8cFe9h5P6Qc5nB6PNWhkiSXvuVG/yEZoHDRaD82tTqDuADhzpcLTVm8J+dO6tOthb5/veRe +4YhnzneIF44fCOUvnWo7T590a1TIXkN/+RArbUHE+kjKMA6LzqvpvtWohavsSmIZHRh/xMHdSur9 +FNimGpKRfIQfw3ZzdjH5YxKcyG0ZVgoASoj1FeUcfHGG9Ib5huZ6CfNeXhoIA46wMfN5iUdBa55b +ZAuVw8ShWA2xVgH+PAd0pHfKqdsOvSC1vSz4gEwgCZsw+qsh/HXDm+GrZoRKeo+rmqlB9nj2eYAY +l9f5xYUpzUbUrkR/0zVnwM+DP6Q/UtdvE/UkRt9gt7PWM3yiza6V02iaUUeqsLGKMPhFpBxcnx2T +Q2637IikuZob/LADwd8sAsSNxGqwL9xiEAhm/q+pga59YCpW9+2F9o3ie3/G5+4MpV1FuKfjcd1s +jzN5yka6s7e6tAnleWZQHsMdL35GAQ9TbWkFsHVqCXkrqEYdu28sru5k1G+ZsFz/kYBytgDBmucb +OR2xsXQCKvHuYX8Kd2JW5A76M+Ec1Wr1gxhtsWjod39Ytbtj94XJnV10+Doc9J9nLQceZDTL99NW +jLkjO67VQ7FAUXS72f38yjoeFhTwObviZh/St1S7+pn7HzBsVc0PJxhG+S24jZnv0Fol7i6vnreL +UMVNefBntxFD3/M7utGJw77T/qkaC1CLJmCpnIDae+I3SY9SE6DVxZud1YQy9TXaqObpkPxoUQrc +7Ri0avAgPPEwdF4UEbgnB6JP8JfcwYDTrhjUb3PfAiq0nZyEbhF+hyavsINmgXU6rQLlDKPRiMiD +ZeiuW/xzq0Vlmik1f/HIFPqNYGdnPFJ5EMOcIZ+z4AoXU2SuUyZNqjv3vM71DNvLAjCXOfqTXkL8 +l9GWJlCq225vbNIqi8EIDhthGn+1oBaNQR+ePFfTbzHRZOs6tV2dHkpq8diLDn/j8JzDt/Ngkmj6 +n3fHRd27i4hGJVxRfQhgm77jIXbBqf4vD70Kd3+3pN++l2QI/+LaECke6MttIIIQAK3aeEMXVcZP +SirZ/RzBfJW445hUgEfVBE6vJ8K8xkaZsqtx9wpVDKsvGLu5X4lewUWjPlmVNXv84YUABs+HepYP +ytwjrco6v5nyVu9TgMxxXKeir9S33eQnGm2T4e5QV/gDVryVtN0NRbsOg/rH4YI0DEz48EmQegRu +qUvJK9kSYFTOIjPPOHcNVMm2o/l7pK++scDoepZVLOkmMDs5Zc2367uJsiDldv0ojLw5X5qZW6IM +PIn8IvtvRsSlzMGtwmM3Nf+gjHyf4ta9ZLjM+4L0pG2PPqmYnYsY8SRXmYiKeW/P81xC1xfm7lwW +gGzoy7atBxBI0uyomKY5z13ARP1MzMZHSNpL92lIlrYiyn2p2jIEAYf46PyZe2/gaoxlIY8dN7lx +/5nu+4/Hr7V5bEpa/nECtKVjipZ0IIHZEiZ6/XFQXrTQre0qttHU7uysiMQKUflxyK7COAkvh//2 +JOUCGqln0b7DBy4vCjMsbjGm0sb4mgd0cdi/Bhb4CHElR2S+28+YH9lTd2g3DKGBolD3NNO5w5tD +Suj/PON88+ZCLImSH9lCxFfxBCRToOuK+In0YPb5qj/VVDiedqSBdhJhzv3KpCJ15z7gFU9fRj+X +c6izEkkz/Gr8T0FwDwC2B+Y9aKN99iRi1lc2V2dqEI0ZgToO7Ek3n4E8FFi9eBJit1WfEPGcsaY7 +Nv/JnQPLhq7VersQ7i9N8xl+M2RifxBS6+87YHXcFZbIQCFEt6dLF/siOvnWyEP351OzuGukdN/D +fbb6siJA3OA7NfLgYWbPTN+scAfGQutBYI7I23kWf+wd75C6XR1iP46axXyqCr8sXM7awfwzBxa8 +AFshjyRCH57I3U5kTY/VtsslclZkD+bN3jJuCMrUx6jYPcVwkvgA7TLeUCuWFS59iAYxCzbDUiq6 +BUuhLN+efcsNfARapGRhAHL5DXZaaOgB/IkjqM9fAAdRWLJXw72LB5YGjqQKchP18KbJZP51Gl35 ++6vA8gBzGU3sTgLPBdf9ltVjTDVtcYbsLuYY2INTQSKpkzIVMVV9YkeEH9fGDHztth9ihu4jqa4+ +w8gLQlCsigFjzD4H3CkgpJWfqb5qFTfQruFKM6w5EFNb+jxNNcxoOIXjXJf1KhW2MjzmS9evaCus +AreJTkD5yTX7TvUpVl1ZtJx0dgYj6tv6PNsdLzm0eQj9ps7M6zOHZhEjB5PSHakM1CwaqHsEtP/+ +1WjWYGaqnAlqCICYMfDlD4FMW3lrTWqAWPxqQOZesNUbgG2cwuQf+CG+GIRJqCYhQQ2prT2x8z/e +heSpc29ezoRtm4Lqyyzg03SyLHoCLNOzHgHY/UHfrj77hY4fxym1LwNn+qrrW4OONYhuk2OBgSh9 +fRIS6XkmptiRn9I0Px/+vbAgLgDb8wNY+bFD+X7jYsoqjfhlx7lOsZFoYDb+wv6lVNfk4qu4+QPo +TKnuSH+2S9XmsG1M1QDmrq+hSjPxfYJhfcEzNOl/7C55+2fyOt7rQ7CDxuF1fzIr/EzDZUz0r4m7 +VvAmWYtSJvp9ARBjpE/Sr+BEQm/AEoYj6XvUXUYMY/nXY5iBkcNoLcf3l9aq+wljNhYBQz85xKga +Pv4nDvPw4O4l6mkd0hzDN9V29x/5DlOk3PbguiSdsU6ScqjiC4q5QntaU+nd8UCgxY4yw9w05g46 +Y3IvE66wudu07POQ6q7K62FqxkefkR212q+amvr0oY4IuYXz7UxzzJMPjrv+CW9FeM2xtrdHDX3+ +Jcvdk+zPaH5fDc+2YICBmPjEfXqqMrpqK5EnhgkB1c7bI7lrY3I3lCTPrQ/2hGpnqXtlCVzVPX6w +N2OodH4h9ujJnT/Yxq0UE1t3kfXWgrOvqhpPDUxKZO/b+lwUoXsNze+f+MviZnmxSzfF5L13w3EP +fjU+mr4Jh3R3Mt+Idy/0raRefK4X7YMVd27VlELznDqJXXt/decTIFoZIYRpU3pzZy1nXLQuYZe3 +DC/R8UvSG+ZhL+rddzqC69oDf++geqVXhpvGo6VVi4v24Lqu9j+WoffS5n1iM3vXD7QIJocw5FYX +OpS3J1o7p4FMI8gaiuzt1AAa/7fc+JGc0AN2hg4BXWnB3Ps7i/8h3FMPzFmQC8K49oJF6JzvjTaV +mEbG+PkSXvFeG1IZJz87XjI1FI53fJ2S4OgVTtiLpOni9fD7QgYoMRtWnrFoYPUOUaf1DMBtszX5 +sMyc/pGQwEPozaTJmXmBE5fP7M1ULH/svG0Fp/OUzm08Z3a3wbV0GzzPFJgjJoMq9QHqe4H49SFf +L1V8SIS+wgOKHEGa3KFoWsieASHyx+kE7ACWU/myETEnH3QCB6POdQktvvAep828RCJrxUYVC3as +voP/o69ibvFE0YGFEMK96kGFM+Q+zWU2Xm5lRBMPgV5RsfeuP32oJaZS+gZFdpAuErDowfqyxCpi +RWy4c7Q3ISviaoDY/HZtsClCXsOOAgZ8BL+JaTDTmhsB2ew7U1QcZNLRajpn33gLnMgR6378UrhY +5OqDvOlITcPtq6biVAPSy8Vyar/kaaGYocG2aXE1LZqOfLD2C5K991qgN/rGIceN/WBiMN9uQnz9 +EpJbtGeMEFNhnlC+mnnoUurknzg2XVUKcvst/uvSUB0PHUfKwfrl6R/g2bOA+IjyBZGXq0e3IaET +wb79Fn/k6+mA0jqhfiGJdcRVuv5LCFcuo/ToKOQ/PmAozFsv2Lbuey7NDhEHrygCg7KDhlm1mvqI +M67fH6Ki4EU8m4sgkHI7a75xynXezaY2QgqGFnBdFGocs3jR800S0DehJViToaT6kg2o0LM/NUOE +9BPJCc6XPO/5XL0RJtji8U87GfviXBDcG4NtRCoFgbPhoj2lYPhE5LJ0moig3/BZqwhzApWIBN8G +yOOHJzAEl6VLF0qq0p5tm50LE+AfeiaovdQacOJ9GeVh/a3Z89EvUVqGoyuTGgIkQFi7dcxwjeH2 +ysWqb8cLTlsCjXaNchU27mZxCOAztgj43/CmNoo4wBbU7RARwDjqqOOSXVs+5ib9gOxq+lstXPOd +8Cgme5mD+riif5l0foctZEBsv+XimnK5zYQwO8Rb+2eG07rlwhFGhBv+YFOWVHcwZOaax8BLAyWm +hLLDkDr71ZRQA+XgAs5qSVX9D48lL4ZUMr51HUUZG3WNw8Wf9qUmLs0wP5wgqTent8vvnMIGU9PY +CLQHlbMS0F0EDmwoBnR+70lgy8J1/vQmczrxfmBMNPSn/2/zSVHxxRPloyrOejlgxC16VGlWVQ6c +J6jCUuHgTE3ZM/IkwWyqqKd9f8RtlHQ66Z870IB4aTP2OtHl5ugHwnKBmtlUrLJ29XqhBO8/ZLVd +fVkH83yfXIqgkBP9pgp35B3R/q2UO8R7IiB/0quJITPrZafy3h7Z7JGPuLJTy++PF8sSURfILslE +sRYXDpxVirWQmVEdxZv2pVyS4uGs7DZgTDb6rYblRwVMHuXFRcOP3F4/U5Oc6/GnVNfT5pJnnRLk +4eT8CoDgqPWI/ZwOH85WLOS7x9v+8ATNyEvCTXbVGJxiYvFbfVJfUaPbXZ0vJAQwqPDQfj27r02p +gz1bl/FRcH68BUAoXdbuyAFBYBflwAKexggh9V8bYcIwIAEnCggv2nr7uE7VnCGMBCwNI7L6zeT+ +YEQzcTcq8TDqIZL3FriWYV2FxtER/FcpVIB1lNhkuC4+rI//h8u66JE5/XMsiYTinI7ZI8c2sj7S +hVJgpQS9n2ax2DxODIlkFYK3Rf+uTE4XWzm47Pv8GfbFS5DzX3ON1o3uU03ho9IM0EIbL7Ul15oY +wua/ZyV0FBJ4ur5xADw0arDIb2EZwrVu+wbb0QTDgtAiPxE3P0ehIr7BNXKsZ/g0bi5mLUKf01qW +/bm0pwdaI3NIPOsE6R2dYEpIJbZ2Td4ciC9zN4aBtObDl3fcuyZakYicdAUhx+AH7h6z4bleTV1M +B7YCX4lr/mqrTOUx5jPVRYPjQymmqFfcoM1nYlRwVg6ly9n9ogLVFAIVIoo4HLYrqy4LHjSREu3x +xdjhu2E5EuM4XhumMt/ndanLQZNmwIZNLdZgAzE/7RgUH5VvfWnJVhq/KhPZfioJZ80zRhVBtbOA +D6HKGukZDSghEh70UIJjlEOz9ucppRnuP/f5bZIKnHk97LpJlrBEPIAIQQZH2vry052c1aFZnnqZ +hhZQHy3RTn5TF4Rs9J99xxcqxZJpoOMUeZdhh15KGL5NMy11LaQTXNFBbkKbvrhrvaq4nuaSvblh +YKVxDtfOYnjLeN6C/2lPJYuyClARPwQgo4a5WRNxyCbptgP8QuetLKaZ2ES47Pg3OlVCGiLzjMmR +X4i0zcNqxY+0AclTlXQMV2HN/lnab4GbOyj5MNVZ3l/ruJefLBHNfPGu1vfYR3MYwkX7hUDtDGnI +j2pXuFMA18FCXZA3O7I2mRpwacsYYjnu1I/8o0UMuWPzS0vnK2/RVMKsYzd8qovzYF8714wHt3OF +rsdc4//rCNka5HNUPnA764LplLpNeT8LcUK2GZl9PFg5z/CSjSucbIw2/NmbXSksihaH9IastTC2 +SXbj43jqVLRxderEcrg8TAFGLVZx5JM9BiTQBTeKRo3X8qT7XO2xEbXB5P39tVTp8ESASVJi56M1 +pHf2PDbBxNlCtJpMww5Of9RqNG869E1l9PKZH0+n45KtCPoe2OK4sAZgzAHIHvyxjOl6r5VGqfXq +76tP0Q5Qa9iVxSAIy1NC6ufI0upPsjuc+1BBko25OskuTpYn5+DU0eA9mNdebSM3PKTZdRzmteEw +JODh5JKWqEcjpdAFwqesAM6wPn0Y8G5uwth2aPeQQqPyHY7IopnbzNCNu83lUs589JA6ttEYT8lI +wiflxNbJ9/trKQBIvWstyrZybbLz8R4LMG0t6NUl6klyG7CRqP2KLh7tUdfekfVrsb8B8H7ZkUul +5/7koS6TItHiHS0JaJ+xhPcuvtbbFgJYmvaHFFtp+4K/dCTHxVQEjQXNGDxoOSXqs1UanuszBvMB +jvw2lWsgY4FacgecvSwDmwGCnJSza/ykCOIxf4WsRHltsElSvNJ5M8Z8xFK8eUi1Fn5tulcYiCpK +TECwb65uJdpDwnN5P+SYqcDf7BQZbKdGm2Q1D1HhpiptJipkinYD35IqFjEXC0fvQK3EpfVVo6O6 +inG4KMvCL4W8DYfamriodfOl5PsZ9Ji2558+OvtPdquCD2TeXa7gtCMk8DyafHwNqUFXptTNtFHF +kea6hgOcVptvWrDhazMFqBsonVnVgqtXpXscQRkpQyEoJJba8HnMC5ynRV5I45kxHVM/jdOnd2vc +hmwd+Z6/uH6aRmaWx2OPXwwSTMeGDq/mf7QI4VxFdrFp6N803r8UoBwIQ9RLIJccM3r1jsVa3WMe +k0PcJ9aRe/C47XM12/ZTTS7Nk0GSVWfhRbRdIL2c5d8ycY2LR6XE41DUKAqAqr2dpOHoOW3DwTOq +SxJRyuhGWhDifIyVpKY/Rzn/JcqOctU6t2TnH6wDfoP+td1GZFaPW6sC0r3DAl9+QvO4ZxCLE0HN +KuiOLG83lnmj8TGgQSpbFqS2yTZhAt9Jn0uTbzrc9cIET8W7d5Y8vQP8xN9uD1dG72Zh7mj0moIT +vjJn/OXB7sqW9Yvb8oUFAmCAoc4Y69R4JYe5Vewk4rP9sXP3QxQLe9eK/YrmKr8qWRtXw43pLsCA +tYBM/gtKKaovpnvsdqCogt6HaL2Wc+L3aOXSvbBDxZw0ly4XRT9zNPyFrulGqRwfbxwiu21UyH8U +AmyHh23L/jUC9iiV8uyvJwURILvaCQAfgJByudq5ElX4/uydsZWlgMubiay6yE1npQrIvWcjpivB +kCM7oqeIDJxTBV9p36eyMPqSuM/6F2QQvx9xEBoVKLsIuVCuuiEvyz0nkCepz3bDj/g8aq2uCtKy +r0c5sERvUUe/D4dLlvkF0QTwbj9SvZT8GovbB8AChSC6nMOU8jqRAc4d9ppOwGfubIDgfmJ+cWrh +PTTpzca5hwQbGV0+u2CZw22u94zdOJSuPLFVy8Gjd1IbZ8RaQlsX20PY2z9u3X8k3jB/f05zGyDr +gFrA29Sn85C/TaqWU6w0kj2vlxCDKOaLFS6uCTr8hrIxeluF6wSRFtC2JjFP0ah1I2x24TlSL5xS +ZwTyOnNoClu2jyM9sAmW4lglT9RJNjghR6qkVsiKV4Ij2g1a0HM8xYjB7kHGn3f2tbqDbSeJRmFc +XkRXPSbhkTTxspX0cJvnYZ0LhoBf0yr+e6C47ewfDdWF46Se9/CDNEOvGO2+y+ajsHh+5dC13NAB +gZze8uNxXXg+EwCnaw4rBsedtd6Xs4QDChBNXWc/jUCGC65FpQdUoCvlCDS4vJZOKCvFp8kLaNC3 +VsU+jKRWCFgg2V7azSXU4Hf10tT+YVzp4xLYVypgFkaj+q1b6lCVBYXTkxU7TRnSyua5pQUvz02v +nqJ5BxhtwlC4A7Bxn75oeAOruriAN9hyzX4wo7U72N4Bzi63MbJYYTZMoraLcPwnZTD+lpH+U6wt +S8oBpTXyqLouYfVM/6MX0Oh3iDpEO3wLhRnWtZxxiab55xqZFtLASWiUMClgFuw9jOZKLfBuTXsy +72oKJTiRlBGCjtbcH2vXuh5Iq+N9bOSUjQ3E4wD/yRM/od5+M2XYgMYmCXVmmdkCMA2vN1D3XTrk +Le0aoJYnsGQMBqfWCjPw1DBWYLhzvtvSeN5TfU8QmzU1grJ6sVoaiaJlSpIVKTxh2UAlLu7kGsIf +hPndBijr5c59V6ZbxN39yhoG6Tox29Tyl0uHqwUlWCyj6kIyCq3I6tVm6RPVWBOjw/XhlaClrEqT +ddX3ScYvjH/kH8WWf8c9RDuwsSxMeo63jB9cOCTNvADwaCQ8+YKmaTysvWeiRCC8dS+wYQumPJHn +SeprSJ3SDuQytPdZSrOuK0zQqpW5QslRWY4i4aQ5pMTcZW2KQzOgoxuggBd+bfUwD0bBlT1zsIr6 +eKCxa/X+5qlrR1SM0I9pQvSix4b8yZoXl1foBfwgoWtRymDbWadkOgOZP1G4I7wzs4dT4U4AcPNA +e0wHStm9BDkeECJbu7dxA3x3IQxgT3QxVUdrO4yLKY7AP71j4iTDr5OQPFxzym7xq1TCJBDg+ioJ +GIcxKmDZXaVazWQGun+lArWr/uBYJhO3AB55FxjR0RaxhaT7HreOqwPMWj0p9+8jHiOU5x1ZdbR3 +FleHa8Alcqzr+AfCz+cPgbkerdCx2BKk8mwBDHq7+OLnZ4RyTjZsn6joUvkqbyhXg4ZWf/gscPvE +zY49YfwgbtWTz+nhzTCR1ujGTV2623W845QBqbA5WfXkrfcGYih77KzNKGdtclZlFZF2BPwitoFE +PE+DRCNegmR3ze0rFRqZ+1zE5gLDJKEeSHco53IR5YZW9Gg3tH2VtN46A1H0HgsO5bau+h2sm5em ++lKo/gEDZCH4oUf7If4b1UP0OiAuwZQFTQsUxok6gylxYagmrVeEQzVZKf9mHzGDwfzDir4h33mT +uD2UJggILICgCuR4EVlqQaYR4skDRI6zAlrj5AyjexYLRh7FJjr1yeQMfZrA+ZSk1kXD2iRM6Cfh +nM445Yyw7IMWOmNp8LcoSTwtLrdieXPfLQSg0yEOt73GF/hQEnLOIAPR7txgbOj+CIGbWBkAIviu +nDjdxRgCy2qcYQLChqVGSCdnCXBP5LZJWZKCOUq4uNzgJg+rTexXZX8WBOY3pOcRTwt8dDiD3M1A +yq7MR95LXTWk/shb2wtHkb8sQBDQADWpPscIc94vtKV8PCzmnuSAlYkNru+V8k36C0V94olSxyCi +i16Bq42sallDiLWFag2o3SSx3MAbbnihhsYI4+tkBmQa7cdJg8ryIfu0ShBiS4qnvcF9x6ochPwx +//v9LnvCuvaXpi29pow5B8VcoU6bBFNQSpCLFh2F6VrHxuqHHxxcf67F8qO0RYFEcifG6tTO2tdg +Iwnb1TzAiahF767EHLeOHPy+7w6qjLQOcRAul+mCBP7k4OR5pY+l46/qs0ixSiI4u/uDc9DA60Cp +nbKA6dobpOg0bpKBGJjeFBT4opudB0jyUo15NkNI1UaCPZQDinywUCSJ1SHiaqsdCy5a+zgi4CFJ +ADOdxbGxnmpkXtY2VsDcQxiuHGvSvKuIa9CmcLNq/hydrIXk+7V6HdSV/Txw1dWBrirgz8eUDAIV +QgIq8pfD5IV2be7Hc6VpignhxBQbm6SFx5yzAghmVXXW9jqJ5/PlxYhrCteolcldj5lwfFBkp6Df +QXtQpv+8vHJRVFziN7aaWiipTGrFxjIsKNBqr5wD1n22p25USXEoxu8HnslK9GW2Itfxl8diS8D1 +BAf8CvKlWRzWCFnCGEo0uhKGcAke/mnYamg6WhN+xJN5ceU6uzrDSKFW6o76Uk1Bpi20FBgzstbb +xEANGKw1nEjuwrsGbNH2Yn/9d9K10tTox3FHCzetsD+VmPC9x+49KZtMO57eUa6P4CefmfM4VCNa +4CThLAUFm2C5aKzTwp1ld3/3gO1omLpSrmxUiuSZi4OsMqNipgBjIBbb+lHrnpWGS4DDU9V8NBaH +Pj6Oy4Pljv0a3tlrdfNG+zV/IoxEEsdks8XAKGshORwMmVeFPD3uFsGKKydPa8tqHO1lOQ4dOYq8 +wXPp1KKHxERU3CQJSxMf81xkDQ79ZKLake3mPoL8rUR7ZvqqDLOzf/i+ZWsEjVILULC8LrRaTLYf +ZQNRJ8SVqXbVvl9QX3IkcWcd+9S0O4OEw+6SZui5erhi7vzvM7K70HIxwT1Nts6rVTzl78Q4QYpG +dBa87c9aCmFCHfcZxTBXTp9uFw9pXXWUrujX/34aRt9iFmj182KzIEwy8F8faMr/QCZzBZzy/AGq +H0UZA924hUEJeorhzu5O0M+3rfgBWYBE+y2d3LFd7flOsTPVq3wjfKm+dqBRNYMYDGQrYKNLKuB2 +J1ZGf1wrOnEULqB7LNb9I8UN42npw4UxFYp6JTl/OwCYrBMlhxJJNgdmrEsIVCzRseZuVnJEdTJO +F1DRW4963jUdlo697HpBQYnj9c7FCh/sMbD1g55ebGnCyTuqeOL4lh7ggHUK+Rv5JFIC2GcIao+b +wFv3g3MHR1reK24EOQsWnTZ0KQWQb6r9+ac2a/zMrkScbLmEyUUZhLQFCwpud589m1XdRm24fx8j +Z1mNlcWy6L+AS+kiRQGxoEWdERwlFlAuHPe6xUFSLFOEM2FMS5TOs+g9Hym8cp2WaZIQ53MM1QFz +GlL6CwJ2JIU0sA+dnajLIyTHefjIgSkvMO+YMzLY6Eowf/NFGcxd4a7Fkc4Jfwc36t0nNFSob8xj +M+Uj56a6FJnagwkt1+KaZOw+uo1uoIES4/h8oh8BxhDTBWOG18XJV8ufLVSjFnxmH9r7Pc7z0k9F +8ilDbfSdmvu9qlqxverQkYyC++w0+9doH7QT2rvamPJvvzBsqjwOwMUcEg8TeeNB942bPIyIBlrq +3HhCYDQ3nzGoWjzHsanJpGjIAYMJP5fN4MDZ0FwCBAkIu5P2BkYSydC8Utv54X2wS9s9sWxHb1kK +lcGrz6do32OZNc3Wn7/5PBAar+RsCzmHbe80pMI7pMqx6xSooFAiYgyR8z1F38+RR17FeJrB diff --git a/graphs/java/embedFiles/src/main/resources/sample.txt b/graphs/java/embedFiles/src/main/resources/sample.txt new file mode 100644 index 0000000..f1811f5 --- /dev/null +++ b/graphs/java/embedFiles/src/main/resources/sample.txt @@ -0,0 +1 @@ +This is a sample
\ No newline at end of file diff --git a/graphs/java/fgen/.gitignore b/graphs/java/fgen/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/fgen/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/fgen/pom.xml b/graphs/java/fgen/pom.xml new file mode 100644 index 0000000..d227bcc --- /dev/null +++ b/graphs/java/fgen/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>fgen</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/fgen/src/main/java/fr/epita/assistants/fgen/FGen.java b/graphs/java/fgen/src/main/java/fr/epita/assistants/fgen/FGen.java new file mode 100644 index 0000000..5f5a470 --- /dev/null +++ b/graphs/java/fgen/src/main/java/fr/epita/assistants/fgen/FGen.java @@ -0,0 +1,105 @@ +package fr.epita.assistants.fgen; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Comparator; +import java.util.stream.Stream; + +public class FGen { + private Path cwd; + + public FGen(final String inputPath) { + this.cwd = Paths.get(new File("").getAbsolutePath()); + try (InputStream in = ClassLoader.getSystemResourceAsStream(inputPath)) { + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + String line; + while ((line = br.readLine()) != null) { + execute(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void execute(String l) { + String[] args = l.split("\\s+"); + switch (args[0]) { + case "+": + create(args[1]); + break; + case "-": + delete(args[1]); + break; + case ">": + ceedee(args[1]); + break; + } + } + + private void create(String pathName) { + Path path = cwd.resolve(pathName); + File f = new File(String.valueOf(path)); + if (pathName.endsWith("/")) { + if (!f.exists()) { + if (!f.mkdirs()) + { + throw new RuntimeException("Could not create directories"); + } + } + } else { + if (!f.exists()) { + try { + if (pathName.contains("/")) + { + String tmp = cwd.toString() + "/" + pathName.substring(0, pathName.lastIndexOf('/')); + if (!new File(tmp).exists()) + { + if (!new File(tmp).mkdirs()) + throw new RuntimeException("create(file): Could not create dirs"); + } + } + + if (!f.createNewFile()) + throw new RuntimeException("Could not create file"); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + + private void ceedee(String pathName) { + Path res_path = cwd.resolve(pathName); + if (Files.exists(res_path) && Files.isDirectory(res_path)) { + cwd = res_path; + } + else throw new RuntimeException("Invalid path provided to cd"); + } + private boolean deleteDirectory (File file){ + File[] contents = file.listFiles(); + if (contents != null) { + for (File f : contents) { + deleteDirectory(f); + } + } + return file.delete(); + } + + private void delete(String pathString) { + Path path = cwd.resolve(pathString); + File file = new File(String.valueOf(path)); + if (Files.isDirectory(path)) { + if (!deleteDirectory(file)) + throw new RuntimeException("Unable to delete dir"); + } else { + try { + if (!Files.deleteIfExists(path)) + return; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } +}
\ No newline at end of file diff --git a/graphs/java/fgen/src/main/resources/example.txt b/graphs/java/fgen/src/main/resources/example.txt new file mode 100644 index 0000000..f864008 --- /dev/null +++ b/graphs/java/fgen/src/main/resources/example.txt @@ -0,0 +1,3 @@ ++ hello/dossier +> hello +- dossier
\ No newline at end of file diff --git a/graphs/java/grades/.gitignore b/graphs/java/grades/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/grades/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/grades/pom.xml b/graphs/java/grades/pom.xml new file mode 100644 index 0000000..f48839f --- /dev/null +++ b/graphs/java/grades/pom.xml @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>grades</artifactId> + <version>1.1</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>2.22.2</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>1.18.30</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/grades/src/main/java/fr/epita/assistants/grades/EntryNotFoundException.java b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/EntryNotFoundException.java new file mode 100644 index 0000000..fa9d24e --- /dev/null +++ b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/EntryNotFoundException.java @@ -0,0 +1,13 @@ +package fr.epita.assistants.grades; + +public class EntryNotFoundException extends RuntimeException { + /** + * @param entryClass The class of the collection's entries + * @param query The string representation of the search query + */ + public EntryNotFoundException(Class<?> entryClass, String query) { + super(String.format("%s not found for: `%s`", + entryClass.getSimpleName(), + query)); + } +} diff --git a/graphs/java/grades/src/main/java/fr/epita/assistants/grades/GradeHandler.java b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/GradeHandler.java new file mode 100644 index 0000000..91da40b --- /dev/null +++ b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/GradeHandler.java @@ -0,0 +1,98 @@ +package fr.epita.assistants.grades; + +import fr.epita.assistants.grades.model.*; + +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +public class GradeHandler { + private final List<Activity> activities; + private final List<Student> students; + + public GradeHandler() { + this.activities = new ArrayList<>(); + this.students = new ArrayList<>(); + } + + /** + * @param activity The {@link Activity} to be added + * @return {@code true} (as specified by {@link List#add}) + */ + public boolean addActivity(Activity activity) { + this.activities.add(activity); + return true; + } + + /** + * @param student The {@link Student} to be added + * @return {@code true} (as specified by {@link List#add}) + */ + public boolean addStudent(Student student) { + students.add(student); + return true; + } + + /** + * @param name The name of the desired {@link Student} + * @return The desired student + * @throws EntryNotFoundException No known {@link Student} with the given name + */ + public Student getStudent(String name) throws EntryNotFoundException { + Optional<Student> o = students.stream().filter(i -> i.name().equals(name)).findFirst(); + if (o.isEmpty()) + throw new EntryNotFoundException(Student.class, name); + else + return o.get(); + } + + /** + * @param grade The {@link Grade} to be added to the {@link Student} + * @param name The name of the desired {@link Student} + * @return {@code true} (as specified by {@link List#add}) + * @throws EntryNotFoundException No known {@link Student} with the given name + */ + public boolean addGradeToStudent(Grade grade, String name) throws EntryNotFoundException { + getStudent(name).grades().add(grade); + return true; + } + + /** + * @param name The name of the desired {@link Student} to remove + * @return The removed {@link Student} + * @throws EntryNotFoundException No known {@link Student} with the given name + */ + public Student removeStudent(String name) throws EntryNotFoundException { + Student s = getStudent(name); + students.remove(getStudent(name)); + return s; + } + + /** + * @param name The name of the desired {@link Student} + * @param function A {@link Function} returning an updated {@link Student} from the given one + * @throws EntryNotFoundException No known {@link Student} with the given name + */ + public void updateStudent(String name, Function<Student, Student> function) throws EntryNotFoundException { + addStudent(function.apply(removeStudent(name))); + } + + /** + * @param name The name of the {@link Student} from which to get grades + * @param subject The {@link Subject} from which we want the student's average + * @return The student's average grade in the specified subject (0 if no grades are available) + * @throws EntryNotFoundException No known {@link Student} with the given name + */ + public double getStudentAverageInSubject(String name, Subject subject) throws EntryNotFoundException { + Optional<Student> o = students.stream().filter(i -> i.name().equals(name)).findFirst(); + if (o.isPresent()) { + Student s = o.get(); + OptionalDouble d = s.grades().stream().filter(g -> g.activity().subject() == subject).mapToDouble(Grade::grade).average(); + if (d.isEmpty()) + return 0.0; + else return d.getAsDouble(); + } + else + throw new EntryNotFoundException(getClass(), name); + } +} diff --git a/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Activity.java b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Activity.java new file mode 100644 index 0000000..fe3e285 --- /dev/null +++ b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Activity.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.grades.model; + +public record Activity(String name, Subject subject, float weight) { +} diff --git a/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Grade.java b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Grade.java new file mode 100644 index 0000000..fb63a6c --- /dev/null +++ b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Grade.java @@ -0,0 +1,4 @@ +package fr.epita.assistants.grades.model; + +public record Grade(Activity activity, int grade) { +} diff --git a/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Student.java b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Student.java new file mode 100644 index 0000000..335e073 --- /dev/null +++ b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Student.java @@ -0,0 +1,8 @@ +package fr.epita.assistants.grades.model; + +import lombok.Builder; + +import java.util.List; + +@Builder +public record Student(String name, int age, List<Grade> grades) {} diff --git a/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Subject.java b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Subject.java new file mode 100644 index 0000000..00bc685 --- /dev/null +++ b/graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Subject.java @@ -0,0 +1,8 @@ +package fr.epita.assistants.grades.model; + +public enum Subject { + STEMS, + SHAPE, + HEAL, + Maths; +} diff --git a/graphs/java/helloWorld/pom.xml b/graphs/java/helloWorld/pom.xml new file mode 100644 index 0000000..afbe2f5 --- /dev/null +++ b/graphs/java/helloWorld/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>helloWorld</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/helloWorld/src/main/java/fr/epita/assistants/helloworld/HelloWorld.java b/graphs/java/helloWorld/src/main/java/fr/epita/assistants/helloworld/HelloWorld.java new file mode 100644 index 0000000..b30d8a5 --- /dev/null +++ b/graphs/java/helloWorld/src/main/java/fr/epita/assistants/helloworld/HelloWorld.java @@ -0,0 +1,12 @@ +package fr.epita.assistants.helloworld; + +public class HelloWorld { + public void printHelloWorld() + { + System.out.print("Hello World!"); + } + public void printHelloWorldErr() + { + System.err.println("Hello World!"); + } +} diff --git a/graphs/java/linkedList/.gitignore b/graphs/java/linkedList/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/linkedList/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/linkedList/pom.xml b/graphs/java/linkedList/pom.xml new file mode 100644 index 0000000..e1a9950 --- /dev/null +++ b/graphs/java/linkedList/pom.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>fr.epita.assistants</groupId> + <artifactId>linkedList</artifactId> + <version>1.0-SNAPSHOT</version> + + <properties> + <maven.compiler.source>21</maven.compiler.source> + <maven.compiler.target>21</maven.compiler.target> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>RELEASE</version> + <scope>test</scope> + </dependency> + </dependencies> + +</project>
\ No newline at end of file diff --git a/graphs/java/linkedList/src/main/java/fr/epita/assistants/linkedlist/LinkedList.java b/graphs/java/linkedList/src/main/java/fr/epita/assistants/linkedlist/LinkedList.java new file mode 100644 index 0000000..c54f0f4 --- /dev/null +++ b/graphs/java/linkedList/src/main/java/fr/epita/assistants/linkedlist/LinkedList.java @@ -0,0 +1,99 @@ +package fr.epita.assistants.linkedlist; + +public class LinkedList<T extends Comparable<T>> { + static public class ListElement<T> { + T value; + ListElement<T> next; + + public ListElement(T value) { + this.value = value; + this.next = null; + } + } + + /** + * Initializes the list + **/ + public ListElement<T> head; + public int size; + public LinkedList() { + this.head = new ListElement<T>(null); + this.size = 0; + } + + /** + * Inserts the specified element into the list. + * The elements must be sorted in ascending order. + * null elements should be at the end of the list. + * + * @param e Element to be inserted + **/ + public void insert(T e) { + ListElement<T> h = this.head; + while ((h.next != null) && (h.next.value.compareTo(e) < 0)) + h = h.next; + + if (h.next == null) + h.next = new ListElement<T>(e); + else + { + ListElement<T> tmp = h.next; + h.next = new ListElement<>(e); + h.next.next = tmp; + } + this.size++; + } + + /** + * Returns the n-th element in the list. + * + * @param i Index + * @return The element at the given index + * @throws IndexOutOfBoundsException if there is no element at this + * index. + **/ + public T get(int i) { + if (i >= this.size || i < 0) + throw new IndexOutOfBoundsException(); + ListElement<T> h = this.head; + while(i-- != 0) + h = h.next; + return h.next.value; + } + + /** + * Removes the first occurrence of the specified element in the list. + * + * @param e Element to remove + * @return returns the element that has been removed or null + **/ + public T remove(T e) { + ListElement<T> h = this.head; + while ((h.next != null) && (h.next.value.compareTo(e) != 0)) + h = h.next; + if (h.next == null) + return null; + ListElement<T> res = h.next; + h.next = h.next.next; + res.next = null; + this.size--; + return res.value; + } + + /** + * Returns the size of the list. + * + * @return Number of elements in the list + **/ + public int size() { + return this.size; + } + + /** + * Removes all elements from the list. + **/ + public void clear() { + this.head.next = null; + this.size = 0; + } +}
\ No newline at end of file diff --git a/graphs/java/linkedList/src/test/java/fr/epita/assistants/linkedlist/LinkedListTests.java b/graphs/java/linkedList/src/test/java/fr/epita/assistants/linkedlist/LinkedListTests.java new file mode 100644 index 0000000..58ee1b1 --- /dev/null +++ b/graphs/java/linkedList/src/test/java/fr/epita/assistants/linkedlist/LinkedListTests.java @@ -0,0 +1,38 @@ +package fr.epita.assistants.linkedlist; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +import static org.junit.jupiter.api.Assertions.*; + +public class LinkedListTests { + @Test + @Timeout(value = 10, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) + public void testInsertOne() { + LinkedList<Integer> list = new LinkedList<>(); + list.insert(12); + assertEquals(Integer.valueOf(12), list.get(0), "Invalid element"); + } + + @Test + @Timeout(value = 10, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) + public void testGetFail() { + LinkedList<Integer> list = new LinkedList<>(); + list.insert(3); + list.insert(5); + list.insert(2); + assertThrows(IndexOutOfBoundsException.class, () -> list.get(4)); + } + + @Test + @Timeout(value = 10, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) + public void testRemoveNotPresent() { + LinkedList<Integer> list = new LinkedList<>(); + list.insert(1); + list.insert(2); + list.insert(3); + list.insert(4); + assertNull(list.remove(12), "Invalid return value of remove()"); + } + // add your own tests here +} diff --git a/graphs/java/loggingBasics/.gitignore b/graphs/java/loggingBasics/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/loggingBasics/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/loggingBasics/pom.xml b/graphs/java/loggingBasics/pom.xml new file mode 100644 index 0000000..9728beb --- /dev/null +++ b/graphs/java/loggingBasics/pom.xml @@ -0,0 +1,146 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<modelVersion>4.0.0</modelVersion> +<groupId>fr.epita.assistants</groupId> +<artifactId>loggingBasics</artifactId> +<version>1.0</version> + +<properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <logback-classic.version>1.4.5</logback-classic.version> + <slf4j-api.version>2.0.5</slf4j-api.version> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> +</properties> + +<dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j-api.version}</version> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <version>${logback-classic.version}</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> +</dependencies> + +<build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> +</build> +</project> diff --git a/graphs/java/loggingBasics/src/main/java/fr/epita/assistants/loggingbasics/Trombinoscope.java b/graphs/java/loggingBasics/src/main/java/fr/epita/assistants/loggingbasics/Trombinoscope.java new file mode 100644 index 0000000..2607802 --- /dev/null +++ b/graphs/java/loggingBasics/src/main/java/fr/epita/assistants/loggingbasics/Trombinoscope.java @@ -0,0 +1,43 @@ +package fr.epita.assistants.loggingbasics; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import fr.epita.assistants.Main; +import org.slf4j.LoggerFactory; + +import java.util.*; + +public class Trombinoscope { + private final Logger LOGGER; + private final HashMap<String, Long> map; + + public Trombinoscope() { + // FIXME: Instantiate logger with level TRACE + LOGGER = (Logger) LoggerFactory.getLogger(Trombinoscope.class); + LOGGER.setLevel(Level.TRACE); + + // FIXME: Add logging here + LOGGER.trace("Instantiating new Trombinoscope"); + + map = new HashMap<>(); + } + + public Long putPerson(String name, long photoId) { + // FIXME: Add logging here + LOGGER.setLevel(Level.DEBUG); + LOGGER.debug("Putting person (\"" + name + "\", " + photoId + ")"); + + Long oldPhotoId = map.put(name, + photoId); + + // FIXME: Add logging here + + LOGGER.setLevel(Level.TRACE); + if (oldPhotoId == null) + LOGGER.trace("Added entry for person \"" + name + "\""); + else + LOGGER.trace("Updated entry for person \"" + name + "\""); + + return oldPhotoId; + } +} diff --git a/graphs/java/myKitten/.gitignore b/graphs/java/myKitten/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/myKitten/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/myKitten/assembly.xml b/graphs/java/myKitten/assembly.xml new file mode 100644 index 0000000..4a8c128 --- /dev/null +++ b/graphs/java/myKitten/assembly.xml @@ -0,0 +1,20 @@ + +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>tests</id> + <formats> + <format>jar</format> + </formats> + <includeBaseDirectory>false</includeBaseDirectory> + <dependencySets> + <dependencySet> + <outputDirectory>/</outputDirectory> + <useProjectArtifact>true</useProjectArtifact> + <!-- we're creating the test-jar as an attachement --> + <useProjectAttachments>true</useProjectAttachments> + <unpack>true</unpack> + <scope>test</scope> + </dependencySet> + </dependencySets> +</assembly>
\ No newline at end of file diff --git a/graphs/java/myKitten/pom.xml b/graphs/java/myKitten/pom.xml new file mode 100644 index 0000000..e74e346 --- /dev/null +++ b/graphs/java/myKitten/pom.xml @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>myKitten</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + <dependency> + <groupId>org.javassist</groupId> + <artifactId>javassist</artifactId> + <version>3.29.2-GA</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/myKitten/src/main/java/fr/epita/assistants/mykitten/MyKitten.java b/graphs/java/myKitten/src/main/java/fr/epita/assistants/mykitten/MyKitten.java new file mode 100644 index 0000000..e63c2f7 --- /dev/null +++ b/graphs/java/myKitten/src/main/java/fr/epita/assistants/mykitten/MyKitten.java @@ -0,0 +1,64 @@ +package fr.epita.assistants.mykitten; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.stream.Stream; + +public class MyKitten { + /** + * Initializer. + * + * @param srcPath Source file path. + */ + public MyKitten(String srcPath) { + try { + this.streamContent = Files.lines(Paths.get(srcPath)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Use the streamContent to replace `wordToReplace` with "miaou". Don't forget + * to add the line number beforehand for each line. Store the new + * result directly in the streamContent field. + * + * @param wordToReplace The word to replace + */ + public void replaceByMiaou(String wordToReplace) { + final int[] line = {1}; + this.streamContent = this.streamContent.map(i -> line[0]++ + " " + i).map(i -> i.replace(wordToReplace, "miaou")); + } + + /** + * Use the streamContent to write the content into the destination file. + * + * @param destPath Destination file path. + */ + public void toFile(String destPath) { + try { + Files.write(Paths.get(destPath), this.streamContent.toList(), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Creates an instance of MyKitten and calls the above methods to do it + * straightforwardly. + * + * @param srcPath Source file path + * @param destPath Destination file path + * @param wordToReplace Word to replace + */ + public static void miaou(String srcPath, String destPath, + String wordToReplace) { + MyKitten chatteDeTaDaronne = new MyKitten(srcPath); + chatteDeTaDaronne.replaceByMiaou(wordToReplace); + chatteDeTaDaronne.toFile(destPath); + } + + public Stream<String> streamContent; +} diff --git a/graphs/java/mySet/.gitignore b/graphs/java/mySet/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/mySet/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/mySet/pom.xml b/graphs/java/mySet/pom.xml new file mode 100644 index 0000000..c20e039 --- /dev/null +++ b/graphs/java/mySet/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>mySet</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/mySet/src/main/java/fr/epita/assistants/myset/GenericSet.java b/graphs/java/mySet/src/main/java/fr/epita/assistants/myset/GenericSet.java new file mode 100644 index 0000000..590751f --- /dev/null +++ b/graphs/java/mySet/src/main/java/fr/epita/assistants/myset/GenericSet.java @@ -0,0 +1,83 @@ +package fr.epita.assistants.myset; + +import java.util.ArrayList; + +public class GenericSet<T extends Comparable<T>> { + ArrayList<T> base_; + + public GenericSet() { + base_ = new ArrayList<>(); + } + + private static <T extends Comparable<T>> void insertionSort(ArrayList<T> array) { + if (array.isEmpty()) { + return; + } + for (int i = 1; i < array.size(); i++) { + for (int j = i; j > 0 && array.get(j - 1).compareTo(array.get(j)) > 0; j--) { + T tmp = array.get(j); + array.set(j, array.get(j - 1)); + array.set(j - 1, tmp); + } + } + } + public void insert(T i) { + if (!this.has(i)) { + this.base_.add(i); + insertionSort(base_); + } + } + + public void remove(T i) { + this.base_.remove(i); + } + + public boolean has(T i) { + return this.base_.contains(i); + } + + public boolean isEmpty() { + return this.base_.isEmpty(); + } + + public T min() { + T min = base_.getFirst(); + for (T t : base_) { + if (t.compareTo(min) < 0) + min = t; + } + return min; + } + + public T max() { + T max = base_.getFirst(); + for (T t : base_) { + if (t.compareTo(max) > 0) + max = t; + } + return max; + } + + public int size() { + return base_.size(); + } + + public static <T extends Comparable<T>> GenericSet<T> intersection(GenericSet<T> a, GenericSet<T> b) { + GenericSet<T> res = new GenericSet<T>(); + for (int i = 0; i < a.size(); i++) { + if (b.has(a.base_.get(i))) + res.insert(a.base_.get(i)); + } + return res; + } + + public static <T extends Comparable<T>> GenericSet<T> union(GenericSet<T> a, GenericSet<T> b) { + GenericSet<T> res = new GenericSet<>(); + for (T i : a.base_) + res.insert(i); + for (T i : b.base_) + res.insert(i); + + return res; + } +} diff --git a/graphs/java/mySet/src/main/java/fr/epita/assistants/myset/IntegerSet.java b/graphs/java/mySet/src/main/java/fr/epita/assistants/myset/IntegerSet.java new file mode 100644 index 0000000..25dcfdc --- /dev/null +++ b/graphs/java/mySet/src/main/java/fr/epita/assistants/myset/IntegerSet.java @@ -0,0 +1,83 @@ +package fr.epita.assistants.myset; + +import java.util.ArrayList; + +public class IntegerSet { + ArrayList<Integer> base_; + + public IntegerSet() { + base_ = new ArrayList<Integer>(); + } + + private static void insertionSort(ArrayList<Integer> array) { + if (array.isEmpty()) { + return; + } + for (int i = 1; i < array.size(); i++) { + for (int j = i; j > 0 && array.get(j - 1).compareTo(array.get(j)) > 0; j--) { + Integer tmp = array.get(j); + array.set(j, array.get(j - 1)); + array.set(j - 1, tmp); + } + } + } + public void insert(Integer i) { + if (!this.has(i)) { + this.base_.add(i); + insertionSort(base_); + } + } + + public void remove(Integer i) { + this.base_.remove(i); + } + + public boolean has(Integer i) { + return this.base_.contains(i); + } + + public boolean isEmpty() { + return this.base_.isEmpty(); + } + + public Integer min() { + Integer min = base_.getFirst(); + for (Integer integer : base_) { + if (integer < min) + min = integer; + } + return min; + } + + public Integer max() { + Integer max = base_.getFirst(); + for (Integer integer : base_) { + if (integer > max) + max = integer; + } + return max; + } + + public int size() { + return base_.size(); + } + + public static IntegerSet intersection(IntegerSet a, IntegerSet b) { + IntegerSet res = new IntegerSet(); + for (int i = 0; i < a.size(); i++) { + if (b.has(a.base_.get(i))) + res.insert(a.base_.get(i)); + } + return res; + } + + public static IntegerSet union(IntegerSet a, IntegerSet b) { + IntegerSet res = new IntegerSet(); + for (Integer i : a.base_) + res.insert(i); + for (Integer i : b.base_) + res.insert(i); + + return res; + } +} diff --git a/graphs/java/notifyMe/.gitignore b/graphs/java/notifyMe/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/notifyMe/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/notifyMe/pom.xml b/graphs/java/notifyMe/pom.xml new file mode 100644 index 0000000..67e31e2 --- /dev/null +++ b/graphs/java/notifyMe/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>notifyMe</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/notify/INotificationSender.java b/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/notify/INotificationSender.java new file mode 100644 index 0000000..6146e8e --- /dev/null +++ b/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/notify/INotificationSender.java @@ -0,0 +1,10 @@ +package fr.epita.assistants.notifyme.notify; + +public interface INotificationSender { + /** + * Entrypoint to send notifications. + * @param parMessage the message to use for the notification - may be discarded by the␣ + ↪→implementation + */ + void notify(final String parSender, final String parReceiver, final String parMessage); +} diff --git a/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/notify/ShellNotifier.java b/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/notify/ShellNotifier.java new file mode 100644 index 0000000..c2631f7 --- /dev/null +++ b/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/notify/ShellNotifier.java @@ -0,0 +1,22 @@ +package fr.epita.assistants.notifyme.notify; + +public class ShellNotifier implements INotificationSender { + final boolean err; + + /** + * Constructor + * + * @param parStdErr if true, print to stderr, otherwise print to stdout + */ + public ShellNotifier(final boolean parStdErr) { + err = parStdErr; + } + + @Override + public void notify(String parSender, String parReceiver, String parMessage) { + if (err) + System.err.println("Notification from " + parSender + " to " + parReceiver + " received: " + parMessage); + else + System.out.println("Notification from " + parSender + " to " + parReceiver + " received: " + parMessage); + } +} diff --git a/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/user/IMultiNotificationSender.java b/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/user/IMultiNotificationSender.java new file mode 100644 index 0000000..501a070 --- /dev/null +++ b/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/user/IMultiNotificationSender.java @@ -0,0 +1,26 @@ +package fr.epita.assistants.notifyme.user; + +import fr.epita.assistants.notifyme.notify.INotificationSender; + +import java.util.List; + +public interface IMultiNotificationSender { + /** + * Sends a notification to all registered notifiers + * @param parRecipient the recipient of the notification + * @param parMessage the message to send + */ + void sendNotifications(String parRecipient, String parMessage); + + /** + * Adds a notification sender to the list of possible recipients + * @param parNotifier the new notifier to add, should be ignored if null + */ + void addNotifier(INotificationSender parNotifier); + + /** + * Returns the list of notifiers + * @return the list of notifiers + */ + List<INotificationSender> getNotifiers(); +} diff --git a/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/user/User.java b/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/user/User.java new file mode 100644 index 0000000..58d4446 --- /dev/null +++ b/graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/user/User.java @@ -0,0 +1,41 @@ +package fr.epita.assistants.notifyme.user; + +import fr.epita.assistants.notifyme.notify.INotificationSender; + +import java.util.ArrayList; +import java.util.List; + +public class User implements IMultiNotificationSender { + final List<INotificationSender> parNotificationList; + final String username; + + public String getUsername() { + return username; + } + + public User(String username) { + this.username = username; + this.parNotificationList = new ArrayList<>(); + } + + public User(String username, List<INotificationSender> parNotificationList) { + this.parNotificationList = parNotificationList; + this.username = username; + } + + @Override + public void sendNotifications(String parRecipient, String parMessage) { + for (INotificationSender n : parNotificationList) + n.notify(username, parRecipient, parMessage); + } + + @Override + public void addNotifier(INotificationSender parNotifier) { + parNotificationList.add(parNotifier); + } + + @Override + public List<INotificationSender> getNotifiers() { + return parNotificationList; + } +} diff --git a/graphs/java/nucBatlle/.gitignore b/graphs/java/nucBatlle/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/nucBatlle/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/nucBattle/.gitignore b/graphs/java/nucBattle/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/nucBattle/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/nucBattle/pom.xml b/graphs/java/nucBattle/pom.xml new file mode 100644 index 0000000..2ce959c --- /dev/null +++ b/graphs/java/nucBattle/pom.xml @@ -0,0 +1,150 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>nucBattle</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>1.18.30</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + <version>2.18.0</version> + </dependency> + <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <version>2.18.0</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Battle.java b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Battle.java new file mode 100644 index 0000000..35a9b3e --- /dev/null +++ b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Battle.java @@ -0,0 +1,18 @@ +package fr.epita.assistants.nucbattle; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class Battle { + @JsonProperty("battle_id") + private int battleId; + + private List<Turn> turns; +} diff --git a/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/BattleManager.java b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/BattleManager.java new file mode 100644 index 0000000..57d7dcc --- /dev/null +++ b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/BattleManager.java @@ -0,0 +1,101 @@ +package fr.epita.assistants.nucbattle; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; + +public class BattleManager { + String input; + private Map<String, Nuc> nucs; + private Battle battle; + + public BattleManager(String input) { + this.input = input; + } + + public void computeBattle(String reportPath) { + Report report = new Report(); + try (Stream<String> stream = Files.lines(Paths.get(input))) { + String jsonString = stream.reduce("", (s1, s2) -> s1 + s2); + ObjectMapper om = new ObjectMapper(); + JsonNode jn = om.readTree(jsonString); + if (jn == null || jn.isNull()) { + report.setType(ReportType.ERROR); + exportReport(reportPath, report); + } + nucs = om.readValue(jn.get("NUCs").toString(), new TypeReference<Map<String, Nuc>>() { + }); + + SimpleModule mod = new SimpleModule(); + mod.addDeserializer(Turn.class, new TurnDeserializer(nucs)); + om.registerModule(mod); + battle = om.readValue(jn.get("battle").toString(), Battle.class); + // winner pre-check + for (String t : nucs.keySet()) { + if (nucs.keySet().stream().filter(login -> !t.equals(login)).allMatch(login -> nucs.get(login).getHp() == 0.0)) { + report.setType(ReportType.WINNER); + report.setPlayer(t); + exportReport(reportPath, report); + return; + } + nucs.computeIfPresent(t, (k, tmp) -> new Nuc(tmp.getName(), Math.clamp(tmp.getHp(), 0, 100), tmp.getInstalledPrograms())); + } + for (Turn t : battle.getTurns()) { + if (nucs.get(t.getPlayerLogin()) == null || nucs.get(t.getTargetLogin()) == null) { + report.setType(ReportType.ERROR); + exportReport(reportPath, report); + return; + } + // cheater check + if (!t.getPlayerNuc().getInstalledPrograms().containsAll(t.getPacket().getUsedPrograms())) { + report.setType(ReportType.CHEATER); + report.setPlayer(t.getPlayerLogin()); + exportReport(reportPath, report); + return; + } + // swap nukes to update damage + Nuc n = nucs.get(t.getTargetLogin()); + Nuc tmp = new Nuc(n.getName(), Math.clamp(n.getHp() - t.getPacket().getDamage(), 0, 100), + n.getInstalledPrograms()); + nucs.put(t.getTargetLogin(), tmp); + + // winner check + if (nucs.keySet().stream().filter(login -> !t.getPlayerLogin().equals(login)).allMatch(login -> nucs.get(login).getHp() == 0.0)) { + report.setType(ReportType.WINNER); + report.setPlayer(t.getPlayerLogin()); + exportReport(reportPath, report); + return; + } + } + report.setType(ReportType.UNFINISHED); + exportReport(reportPath, report); + } catch (IOException e) { + report.setType(ReportType.ERROR); + exportReport(reportPath, report); + } + } + + private void exportReport(String reportPath, Report report) { + if (report.getType() != ReportType.ERROR && report.getType() != ReportType.CHEATER) { + report.outcome = new HashMap<>(); + for (String login : nucs.keySet()) { + report.outcome.put(login, nucs.get(login).getHp()); + } + } + ObjectMapper om = new ObjectMapper(); + try { + om.writeValue(new File(reportPath), report); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +}
\ No newline at end of file diff --git a/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Nuc.java b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Nuc.java new file mode 100644 index 0000000..e2e4a48 --- /dev/null +++ b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Nuc.java @@ -0,0 +1,20 @@ +package fr.epita.assistants.nucbattle; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class Nuc { + private String name; + + private float hp; + + @JsonProperty("installed_programs") + private List<String> installedPrograms; +} diff --git a/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Packet.java b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Packet.java new file mode 100644 index 0000000..e8806f7 --- /dev/null +++ b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Packet.java @@ -0,0 +1,20 @@ +package fr.epita.assistants.nucbattle; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class Packet { + @JsonProperty("used_programs") + private List<String> usedPrograms; + + private String command; + + private float damage; +} diff --git a/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Report.java b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Report.java new file mode 100644 index 0000000..56aa10d --- /dev/null +++ b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Report.java @@ -0,0 +1,18 @@ +package fr.epita.assistants.nucbattle; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.Map; + +@NoArgsConstructor +@Getter +@Setter +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Report { + ReportType type = ReportType.UNFINISHED; + String player = null; + Map<String, Float> outcome = null; +} diff --git a/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/ReportType.java b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/ReportType.java new file mode 100644 index 0000000..c643c1b --- /dev/null +++ b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/ReportType.java @@ -0,0 +1,14 @@ +package fr.epita.assistants.nucbattle; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +public enum ReportType { + @JsonProperty("winner") + WINNER, + @JsonProperty("cheater") + CHEATER, + @JsonProperty("error") + ERROR, + @JsonProperty("unfinished") + UNFINISHED; +} diff --git a/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Turn.java b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Turn.java new file mode 100644 index 0000000..57e44dc --- /dev/null +++ b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Turn.java @@ -0,0 +1,18 @@ +package fr.epita.assistants.nucbattle; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +public class Turn { + private Nuc playerNuc; + private String playerLogin; + + private Nuc targetNuc; + private String targetLogin; + + private Packet packet; +} diff --git a/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/TurnDeserializer.java b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/TurnDeserializer.java new file mode 100644 index 0000000..bfd60ba --- /dev/null +++ b/graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/TurnDeserializer.java @@ -0,0 +1,30 @@ +package fr.epita.assistants.nucbattle; + +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.util.Map; + +public class TurnDeserializer extends JsonDeserializer<Turn> { + public TurnDeserializer(Map<String, Nuc> nucs) { + this.nucs = nucs; + } + + Map<String, Nuc> nucs; + @Override + public Turn deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { + JsonNode node = jsonParser.getCodec().readTree(jsonParser); + String player_login = node.get("player_login").asText(); + String target_login = node.get("target_login").asText(); + + final ObjectMapper om = new ObjectMapper(); + Packet packet = om.readValue(node.get("packet").toString(), Packet.class); + return new Turn(nucs.get(player_login), player_login, nucs.get(target_login), target_login, packet); + } +} diff --git a/graphs/java/nucBattle/src/main/resources/exampleBattle1.json b/graphs/java/nucBattle/src/main/resources/exampleBattle1.json new file mode 100644 index 0000000..3d541dd --- /dev/null +++ b/graphs/java/nucBattle/src/main/resources/exampleBattle1.json @@ -0,0 +1,66 @@ +{ + "NUCs": { + "xavier.login": { + "name": "r01p02", + "hp": 50.0, + "installed_programs": [ + "yes", + "grep", + "pkill", + "ping", + "bash" + ] + }, + "xavier.login2": { + "name": "r04p03", + "hp": 72.0, + "installed_programs": [ + "find", + "cp", + "bash", + "wget" + ] + } + }, + "battle": { + "battle_id": 9876, + "turns": [ + { + "player_login": "xavier.prout", + "target_login": "xavier.login2", + "packet": { + "used_programs": [ + "bash", + "yes" + ], + "command": "yes > ~/y", + "damage": 51.0 + } + }, + { + "player_login": "xavier.login2", + "target_login": "xavier.login", + "packet": { + "used_programs": [ + "bash", + "cp", + "find" + ], + "command": "find / -type f -exec cp {} /tmp/ \\;", + "damage": 21.0 + } + }, + { + "player_login": "xavier.login", + "target_login": "xavier.login2", + "packet": { + "used_programs": [ + "bash" + ], + "command": ":(){:|: &};:", + "damage": 32.0 + } + } + ] + } +} diff --git a/graphs/java/observer/.gitignore b/graphs/java/observer/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/observer/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/observer/pom.xml b/graphs/java/observer/pom.xml new file mode 100644 index 0000000..5755011 --- /dev/null +++ b/graphs/java/observer/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>observer</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Lifeguard.java b/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Lifeguard.java new file mode 100644 index 0000000..87c5538 --- /dev/null +++ b/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Lifeguard.java @@ -0,0 +1,21 @@ +package fr.epita.assistants.observer; + +import java.util.Set; + +public class Lifeguard implements Observable.Observer<Swimmer> { + String name; + + public Lifeguard(String name) { + this.name = name; + System.out.println(name + " begins to keep an eye on the swimmers."); + } + + @Override + public void onEvent(Swimmer event) { + if (event.getStatus() == SwimmerStatus.TOO_FAR) + System.out.println(name + ": " + event.getName() + "! You are too far, come back!"); + else if (event.getStatus() == SwimmerStatus.DROWNING) { + System.out.println(name + ": I will save you " + event.getName() + "!"); + } + } +} diff --git a/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Observable.java b/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Observable.java new file mode 100644 index 0000000..1739739 --- /dev/null +++ b/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Observable.java @@ -0,0 +1,55 @@ +package fr.epita.assistants.observer; + +import java.util.Set; + +/** + * Observer interface. + * + * @param <EVENT_T> Type of observed events + */ +public interface Observable<EVENT_T> { + + /** + * Get all registered observers. + * + * @return The set of observers + */ + Set<Observer<EVENT_T>> getObservers(); + + /** + * Register observers. + * + * @param observers Observers to register + */ + void register(final Observer<EVENT_T>... observers); + + /** + * Unregister the given observer. + * + * @param observer The observer to deactivate + */ + void unregister(final Observer<EVENT_T> observer); + + /** + * Notify all registered observers of the given event. + * + * @param event The event to notify observers with. + */ + void fire(final EVENT_T event); + + /** + * Sub interface for observers. + * + * @param <EVENT_T> The type of observed events + */ + @FunctionalInterface + interface Observer<EVENT_T> { + + /** + * Notification callback. + * + * @param event The event being sent + */ + void onEvent(final EVENT_T event); + } +} diff --git a/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Person.java b/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Person.java new file mode 100644 index 0000000..81247ac --- /dev/null +++ b/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Person.java @@ -0,0 +1,15 @@ +package fr.epita.assistants.observer; + +public class Person implements Observable.Observer<Swimmer> { + String name; + + public Person(String name) { + this.name = name; + } + + @Override + public void onEvent(Swimmer event) { + if (event.getStatus() == SwimmerStatus.WAVING) + System.out.println(name + ": Waves back at " + event.getName() + "."); + } +} diff --git a/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Swimmer.java b/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Swimmer.java new file mode 100644 index 0000000..2ce803a --- /dev/null +++ b/graphs/java/observer/src/main/java/fr/epita/assistants/observer/Swimmer.java @@ -0,0 +1,55 @@ +package fr.epita.assistants.observer; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class Swimmer implements Observable<Swimmer> { + Set<Observer<Swimmer>> observers = new HashSet<>(); + String name; + SwimmerStatus status = SwimmerStatus.OK; + + public Swimmer(String name) { + this.name = name; + System.out.println(this.name + " goes into the sea."); + } + + public String getName() { + return name; + } + + public SwimmerStatus getStatus() { + return status; + } + + @Override + public Set<Observer<Swimmer>> getObservers() { + return observers; + } + + public void setStatus(SwimmerStatus status) { + this.status = status; + if (status == SwimmerStatus.DROWNING) { + System.out.println(name + ": I'm drowning, help!!"); + } + else if (status == SwimmerStatus.WAVING) + System.out.println(name + ": Waves towards the shore."); + fire(this); + } + + @Override + public void register(Observer<Swimmer>... observers) { + this.observers.addAll(Arrays.asList(observers)); + } + + @Override + public void unregister(Observer<Swimmer> observer) { + this.observers.remove(observer); + } + + @Override + public void fire(Swimmer event) { + for (Observer<Swimmer> o : this.observers) + o.onEvent(event); + } +} diff --git a/graphs/java/observer/src/main/java/fr/epita/assistants/observer/SwimmerStatus.java b/graphs/java/observer/src/main/java/fr/epita/assistants/observer/SwimmerStatus.java new file mode 100644 index 0000000..71856c6 --- /dev/null +++ b/graphs/java/observer/src/main/java/fr/epita/assistants/observer/SwimmerStatus.java @@ -0,0 +1,11 @@ +package fr.epita.assistants.observer; + +/** + * Status of a swimmer. + */ +public enum SwimmerStatus { + OK, + DROWNING, + TOO_FAR, + WAVING +} diff --git a/graphs/java/pizzaStreams/.gitignore b/graphs/java/pizzaStreams/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/pizzaStreams/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/pizzaStreams/pom.xml b/graphs/java/pizzaStreams/pom.xml new file mode 100644 index 0000000..ffa630f --- /dev/null +++ b/graphs/java/pizzaStreams/pom.xml @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>pizzaStreams</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + <dependency> + <groupId>org.javassist</groupId> + <artifactId>javassist</artifactId> + <version>3.29.2-GA</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Dough.java b/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Dough.java new file mode 100644 index 0000000..a0ea259 --- /dev/null +++ b/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Dough.java @@ -0,0 +1,16 @@ +package fr.epita.assistants.pizzastreams; + +public enum Dough { + NATURE(2), + CAJUN(3); + + private final Integer price; + + Dough(final Integer price) { + this.price = price; + } + + public Integer getPrice() { + return this.price; + } +} diff --git a/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Pizza.java b/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Pizza.java new file mode 100644 index 0000000..d47b8da --- /dev/null +++ b/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Pizza.java @@ -0,0 +1,47 @@ +package fr.epita.assistants.pizzastreams; + +import fr.epita.assistants.pizzastreams.Topping.Cheese; +import fr.epita.assistants.pizzastreams.Topping.Protein; +import fr.epita.assistants.pizzastreams.Topping.Sauce; +import fr.epita.assistants.pizzastreams.Topping.Vegetable; + +import java.util.List; + +public class Pizza { + private final String name; + private final Dough dough; + private final Topping topping; + private final Integer price; + + public Pizza(final String name, final Dough dough, final Sauce sauce, final Cheese cheese, + final List<Vegetable> vegetableList, final Protein protein) { + this.name = name; + this.topping = new Topping(sauce, cheese, vegetableList, protein); + this.dough = dough; + + final int doughPrice = dough.getPrice(); + final int saucePrice = topping.getSaucePrice(); + final int cheesePrice = topping.getCheesePrice(); + final int vegetablesPrice = topping.getVegetablesPrice(); + final int proteinPrice = topping.getProteinPrice(); + + this.price = doughPrice + saucePrice + cheesePrice + vegetablesPrice + + proteinPrice; + } + + public String getName() { + return name; + } + + public Dough getDough() { + return dough; + } + + public Topping getTopping() { + return topping; + } + + public Integer getPrice() { + return price; + } +} diff --git a/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/PizzaStreams.java b/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/PizzaStreams.java new file mode 100644 index 0000000..26259a3 --- /dev/null +++ b/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/PizzaStreams.java @@ -0,0 +1,60 @@ +package fr.epita.assistants.pizzastreams; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Stream; + +import fr.epita.assistants.pizzastreams.Topping.*; + +public class PizzaStreams { + /** + * @return The sum of the prices of all the pizzas in the stream + */ + public static Integer getTotalPrice(Stream<Pizza> pizzaStream) { + return pizzaStream.mapToInt(Pizza::getPrice).sum(); + } + + /** + * @return The average price of the pizzas in the stream, or the + * double NaN if the stream is empty + */ + public static Double getAveragePrice(Stream<Pizza> pizzaStream) { + return pizzaStream.mapToDouble(Pizza::getPrice).average().orElse(Double.NaN); + } + + /** + * @return Names of the pizzas, sorted by price in ascending order + */ + public static List<String> sortByPrice(Stream<Pizza> pizzaStream) { + return pizzaStream.sorted(Comparator.comparing(Pizza::getPrice)).map(Pizza::getName).toList(); + } + + /** + * @return The Pizza object that has the lowest price, or null by default + */ + public static Pizza getCheapest(Stream<Pizza> pizzaStream) { + return pizzaStream.min(Comparator.comparing(Pizza::getPrice)).orElse(null); + } + + /** + * @return Names of the pizzas with meat (Protein) + */ + public static List<String> getCarnivorous(Stream<Pizza> pizzaStream) { + return pizzaStream.filter(i -> i.getTopping().getProtein().isPresent()).map(Pizza::getName).toList(); + } + + /** + * @return Names of the pizzas with at least one Vegetable and no Proteins + */ + public static List<String> getVeggies(Stream<Pizza> pizzaStream) { + return pizzaStream.filter(i -> i.getTopping().getProtein().isEmpty() && !i.getTopping().getVegetableList().isEmpty()).map(Pizza::getName).toList(); + } + + /** + * @return true if all the pizzas with a nature dough are based with tomato + * and mozzarella (italian pizza criteria), false otherwise + */ + public static boolean areAllNatureItalians(Stream<Pizza> pizzaStream) { + return pizzaStream.filter(i -> i.getDough() == Dough.NATURE).allMatch(i -> i.getTopping().getCheese() == Cheese.MOZZARELLA && i.getTopping().getSauce() == Sauce.TOMATO); + } +} diff --git a/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Topping.java b/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Topping.java new file mode 100644 index 0000000..aaacb58 --- /dev/null +++ b/graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Topping.java @@ -0,0 +1,82 @@ +package fr.epita.assistants.pizzastreams; + +import java.util.List; +import java.util.Optional; + +public class Topping { + public enum Sauce { + TOMATO, + BUFFALO, + PESTO, + } + + public enum Cheese { + MOZZARELLA, + CHEDDAR, + CREAM, + } + + public enum Vegetable { + OLIVE, + MUSHROOM, + ONION, + } + + public enum Protein { + CHICKEN, + BACON, + MERGUEZ, + } + + private final Sauce sauce; + private final Cheese cheese; + private final List<Vegetable> vegetableList; + private final Protein protein; + + public Topping(final Sauce sauce, final Cheese cheese, final List<Vegetable> vegetableList, + final Protein protein) { + this.sauce = sauce; + this.cheese = cheese; + this.vegetableList = vegetableList; + this.protein = protein; + } + + public Sauce getSauce() { + return sauce; + } + + public Cheese getCheese() { + return cheese; + } + + public List<Vegetable> getVegetableList() { + return vegetableList; + } + + public Optional<Protein> getProtein() { + return Optional.ofNullable(protein); + } + + public Integer getSaucePrice() { + return (sauce == Sauce.TOMATO) ? 1 : ((sauce == Sauce.BUFFALO) ? 2 : 3); + } + + public Integer getCheesePrice() { + return (cheese == Cheese.MOZZARELLA) ? 2 : ((cheese == Cheese.CHEDDAR) ? 3 : 4); + } + + public Integer getProteinPrice() { + return protein == null ? 0 + : protein == Protein.CHICKEN ? 5 : 8; + } + + public Integer getVegetablesPrice() { + return (vegetableList + .isEmpty() + ? 0 + : vegetableList.stream() + .mapToInt((v) -> (v == Vegetable.OLIVE + || v == Vegetable.ONION) ? 1 : 2) + .sum()); + } +} diff --git a/graphs/java/practiceLombok/.gitignore b/graphs/java/practiceLombok/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/practiceLombok/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/practiceLombok/pom.xml b/graphs/java/practiceLombok/pom.xml new file mode 100644 index 0000000..de31828 --- /dev/null +++ b/graphs/java/practiceLombok/pom.xml @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>practiceLombok</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>1.18.30</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Falcon.java b/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Falcon.java new file mode 100644 index 0000000..6c35ffc --- /dev/null +++ b/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Falcon.java @@ -0,0 +1,10 @@ +package fr.epita.assistants.practicelombok; + +import lombok.Data; + +@Data +public class Falcon { + String name; + String nickname; + int speed; +} diff --git a/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Horse.java b/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Horse.java new file mode 100644 index 0000000..da9981e --- /dev/null +++ b/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Horse.java @@ -0,0 +1,13 @@ +package fr.epita.assistants.practicelombok; + +import lombok.*; + +@AllArgsConstructor +@NoArgsConstructor +@ToString +@EqualsAndHashCode +public class Horse { + @Getter @Setter private String name; + @ToString.Exclude @Getter @Setter private String nickname; + @EqualsAndHashCode.Exclude @Getter private int speed; +} diff --git a/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Shark.java b/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Shark.java new file mode 100644 index 0000000..a2e5f3d --- /dev/null +++ b/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Shark.java @@ -0,0 +1,10 @@ +package fr.epita.assistants.practicelombok; + +import lombok.*; + +@Value +public class Shark { + String name; + String nickname; + int speed; +} diff --git a/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Spider.java b/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Spider.java new file mode 100644 index 0000000..0091fc6 --- /dev/null +++ b/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Spider.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.practicelombok; + +import lombok.*; +@AllArgsConstructor +public class Spider { + @Getter @Setter public String name; +} diff --git a/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Tiger.java b/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Tiger.java new file mode 100644 index 0000000..1028dd3 --- /dev/null +++ b/graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Tiger.java @@ -0,0 +1,11 @@ +package fr.epita.assistants.practicelombok; + +import lombok.*; + +@AllArgsConstructor +@NoArgsConstructor +@ToString +public class Tiger { + @Getter @Setter public String name; + @Getter @Setter public String nickname; +} diff --git a/graphs/java/rockPaperScissors/.gitignore b/graphs/java/rockPaperScissors/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/rockPaperScissors/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/rockPaperScissors/pom.xml b/graphs/java/rockPaperScissors/pom.xml new file mode 100644 index 0000000..747b009 --- /dev/null +++ b/graphs/java/rockPaperScissors/pom.xml @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>rockPaperScissors</artifactId> + <version>1.0</version> + + + <properties> + <versions.java>21</versions.java> + + <versions.junit>5.9.1</versions.junit> + + <versions.maven-compiler-plugin>3.8.1</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>2.22.2</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.6.3</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.6.3</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>2.0.6</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.0.6</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>2.0.5</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.0.6</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.0.6</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.0.6</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.0.6</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Bot.java b/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Bot.java new file mode 100644 index 0000000..5d8005b --- /dev/null +++ b/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Bot.java @@ -0,0 +1,18 @@ +package fr.epita.assistants.rockPaperScissors; + +public class Bot { + final String name; + + public String getName() { + return name; + } + + public Bot(String name) { + this.name = name; + } + + public final HandShape getBotHandShape() + { + return new HandShape((int) (Math.random() * 2)); + } +} diff --git a/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/HandShape.java b/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/HandShape.java new file mode 100644 index 0000000..1d95c92 --- /dev/null +++ b/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/HandShape.java @@ -0,0 +1,26 @@ +package fr.epita.assistants.rockPaperScissors; + +import java.util.Arrays; +import java.util.List; + +/* + Note that this kind of class should be replaced with an Enum. + Enums will be introduced later in the workshop. + */ + +public class HandShape { + final static private List<String> shapesValues = Arrays.asList("ROCK", "PAPER", "SCISSORS"); + final private int index; + + public HandShape(final int index) { + this.index= index; + } + + public String getName(){ + return shapesValues.get(index); + } + + int getIndex() { + return index; + } +}
\ No newline at end of file diff --git a/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Match.java b/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Match.java new file mode 100644 index 0000000..2116f58 --- /dev/null +++ b/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Match.java @@ -0,0 +1,52 @@ +package fr.epita.assistants.rockPaperScissors; + +import java.util.Objects; + +public final class Match { + private static int matchCount; + private final int currentMatchNumber; + final String player1, player2; + final HandShape player1Choice, player2Choice; + + public Match(String player1, String player2, HandShape player1Choice, HandShape player2Choice) { + this.currentMatchNumber = ++matchCount; + this.player1 = player1; + this.player2 = player2; + this.player1Choice = player1Choice; + this.player2Choice = player2Choice; + } + + public static int getMatchCount() { + return matchCount; + } + + static void resetMatchCount() + { + matchCount = 0; + } + + public int getCurrentMatch() { + return currentMatchNumber; + } + + public void runMatch() + { + System.out.println("Let's start match number " + currentMatchNumber + "!"); + System.out.println("Rock, Paper, Scissors!"); + System.out.println(player1 + " is playing: " + player1Choice.getName()); + System.out.println(player2 + " is playing: " + player2Choice.getName()); + + if (player1Choice.getIndex() == player2Choice.getIndex()) + { + System.out.println("DRAW!"); + } + else if (player1Choice.getIndex() == (player2Choice.getIndex() + 1) % 3) + { + System.out.println("The winner is " + player1 + "!"); + } + else + { + System.out.println("The winner is " + player2 + "!"); + } + } +} diff --git a/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Player.java b/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Player.java new file mode 100644 index 0000000..72e0761 --- /dev/null +++ b/graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Player.java @@ -0,0 +1,23 @@ +package fr.epita.assistants.rockPaperScissors; + +public final class Player { + final String name; + int choice; + + public void setChoice(int choice) { + this.choice = choice; + } + + public String getName() { + return name; + } + + public Player(String name) { + this.name = name; + } + + public HandShape getPlayerHandShape() + { + return new HandShape(choice); + } +} diff --git a/graphs/java/scheduler/.gitignore b/graphs/java/scheduler/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/scheduler/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/scheduler/pom.xml b/graphs/java/scheduler/pom.xml new file mode 100644 index 0000000..007367f --- /dev/null +++ b/graphs/java/scheduler/pom.xml @@ -0,0 +1,146 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>scheduler</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + <!-- FIXME This should only be for testing (not included in student pom) --> + <dependency> + <groupId>com.tngtech.archunit</groupId> + <artifactId>archunit</artifactId> + <version>1.2.1</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.tngtech.archunit</groupId> + <artifactId>archunit-junit5-api</artifactId> + <version>1.0.0</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/scheduler/src/main/java/fr/epita/assistants/scheduler/MyTask.java b/graphs/java/scheduler/src/main/java/fr/epita/assistants/scheduler/MyTask.java new file mode 100644 index 0000000..d1de4fb --- /dev/null +++ b/graphs/java/scheduler/src/main/java/fr/epita/assistants/scheduler/MyTask.java @@ -0,0 +1,48 @@ +package fr.epita.assistants.scheduler; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.function.Supplier; + +public class MyTask<INPUT_TYPE, RETURN_TYPE> implements Task<RETURN_TYPE> { + + CompletableFuture<RETURN_TYPE> cpFuture; + + public MyTask(CompletableFuture<RETURN_TYPE> cpFuture) { + this.cpFuture = cpFuture; + } + + public static <RETURN_TYPE> Task<RETURN_TYPE> of(Supplier<RETURN_TYPE> actionSupplier) { + return new MyTask<>(CompletableFuture.supplyAsync(actionSupplier)); + } + + public static <RETURN_TYPE> Task<RETURN_TYPE> of(Supplier<RETURN_TYPE> actionSupplier, Executor executor) { + return new MyTask<>(CompletableFuture.supplyAsync(actionSupplier, executor)); + } + + @Override + public CompletableFuture<RETURN_TYPE> build() { + return cpFuture; + } + + @Override + public Task<RETURN_TYPE> onErrorRecoverWith(Function<Throwable, RETURN_TYPE> recoveryFunction) { + return new MyTask<>(cpFuture.handle((result, exception) -> { + if (exception != null) + return recoveryFunction.apply(exception); + return result; + })); + } + + @Override + public <NEW_RETURN_TYPE> Task<NEW_RETURN_TYPE> andThenDo(Function<RETURN_TYPE, NEW_RETURN_TYPE> action) { + return new MyTask<>(cpFuture.thenApply(action)); + } + + @Override + public Task<RETURN_TYPE> andThenWait(long number, TimeUnit timeUnit) { + return new MyTask<>(cpFuture.thenApplyAsync(i -> i, CompletableFuture.delayedExecutor(number, timeUnit))); + } +} diff --git a/graphs/java/scheduler/src/main/java/fr/epita/assistants/scheduler/Task.java b/graphs/java/scheduler/src/main/java/fr/epita/assistants/scheduler/Task.java new file mode 100644 index 0000000..64c0c03 --- /dev/null +++ b/graphs/java/scheduler/src/main/java/fr/epita/assistants/scheduler/Task.java @@ -0,0 +1,75 @@ +package fr.epita.assistants.scheduler; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Represent a single task to be executed. Tasks can be chained using the andThenDo method. + * + * @param <RETURN_TYPE> The expected return type. + */ +public interface Task<RETURN_TYPE> { + + /** + * Static initializer allowing the creation of a task instance with the given {@link Supplier}. + * + * @param actionSupplier The actual action to execute. + * @param <RETURN_TYPE> The expected return type, inferred by the call chain. + * @return A {@link Task} instance. + */ + static <RETURN_TYPE> Task<RETURN_TYPE> of(Supplier<RETURN_TYPE> actionSupplier) { + throw new UnsupportedOperationException("This default implementation should never be called, and should be" + + "implemented in classes that implement this interface"); + } + + /** + * Build the actual completable future according to this instance specifications. + * + * @return The built {@link CompletableFuture}. + */ + CompletableFuture<RETURN_TYPE> build(); + + /** + * Execute a task and return its result. + * + * @return The result of the execution of this task. + */ + default RETURN_TYPE execute() { + try { + return build().get(); + } catch (InterruptedException | ExecutionException exception) { + throw new RuntimeException("Exception during task computing", exception); + } + } + + /** + * Specify a function that provides a recovery value to use if the task fails. + * + * @param recoveryFunction The function that will be called with the exception - should any happen - in order to + * compute a recovery value. + * @return The updated task. + */ + Task<RETURN_TYPE> onErrorRecoverWith(final Function<Throwable, RETURN_TYPE> recoveryFunction); + + /** + * Chain a new task to be executed after the current one, taking the output of the current one as its input. + * + * @param action The action to perform. + * @param <NEW_RETURN_TYPE> The return type of the task to create. + * @return The created task. + */ + <NEW_RETURN_TYPE> Task<NEW_RETURN_TYPE> andThenDo(final Function<RETURN_TYPE, NEW_RETURN_TYPE> action); + + /** + * Wait for the given number of timeUnit. + * + * @param number The number of units to wait for. + * @param timeUnit The unit. + * @return The created task. + */ + Task<RETURN_TYPE> andThenWait(final long number, final TimeUnit timeUnit); + +} diff --git a/graphs/java/seq/.gitignore b/graphs/java/seq/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/seq/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/seq/pom.xml b/graphs/java/seq/pom.xml new file mode 100644 index 0000000..46ba851 --- /dev/null +++ b/graphs/java/seq/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>seq</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/seq/src/main/java/fr/epita/assistants/seq/ExtendedStream.java b/graphs/java/seq/src/main/java/fr/epita/assistants/seq/ExtendedStream.java new file mode 100644 index 0000000..0ba5f6a --- /dev/null +++ b/graphs/java/seq/src/main/java/fr/epita/assistants/seq/ExtendedStream.java @@ -0,0 +1,204 @@ +package fr.epita.assistants.seq; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Stream; + +/** + * Extends the {@link Stream} interface, adding some very strangely lacking useful methods. + * You should use the Forwarding-Interface pattern. + * <p> + * The use of infinite, unordered or parallel stream in this implementation will + * not be tested. + * + * @param <ELEMENT_TYPE> the type of stream. + */ +@SuppressWarnings("unused") +public interface ExtendedStream<ELEMENT_TYPE> extends Stream<ELEMENT_TYPE> { + + + /** + * Creates a map out of the stream. + * In case of duplicate keys, the latest element in the original stream will overwrite the one(s) in place. + * + * @param keyMapper mapping function to extract map keys. + * @param <KEY_TYPE> the expected type of key. + * @return the created map. + */ + <KEY_TYPE> Map<KEY_TYPE, ELEMENT_TYPE> + toMap(final Function<ELEMENT_TYPE, KEY_TYPE> keyMapper); + + /** + * Creates a map out of the stream. + * In case of key duplicates, the latest element in the original stream will overwrite the one(s) in place. + * + * @param map the map to fill/update. + * @param keyMapper mapping function to extract map keys. + * @param valueMapper mapping function to extract map values. + * @param <KEY_TYPE> the expected type of key. + * @param <VALUE_TYPE> the expected type of value. + * @param <MAP_TYPE> the complete return type. + * @return the created map. + */ + <KEY_TYPE, VALUE_TYPE, MAP_TYPE extends Map<KEY_TYPE, VALUE_TYPE>> + MAP_TYPE toMap(final MAP_TYPE map, + final Function<ELEMENT_TYPE, KEY_TYPE> keyMapper, + final Function<ELEMENT_TYPE, VALUE_TYPE> valueMapper); + + /** + * Creates a map out of the stream. + * In case of duplicate keys, the latest element in the original stream will overwrite the one(s) in place. + * + * @param keyMapper mapping function to extract map keys. + * @param valueMapper mapping function to extract map values. + * @param <KEY_TYPE> the expected type of key. + * @param <VALUE_TYPE> the expected type of value. + * @return the created map. + */ + <KEY_TYPE, VALUE_TYPE> + Map<KEY_TYPE, VALUE_TYPE> toMap(final Function<ELEMENT_TYPE, KEY_TYPE> keyMapper, + final Function<ELEMENT_TYPE, VALUE_TYPE> valueMapper); + + /** + * Converts the stream to a list. + * + * @return the created list. + */ + List<ELEMENT_TYPE> toList(); + + /** + * Dumps the content of the stream to the given list. + * + * @param list the list to dump values to. + * @param <LIST> the exact type of list. + * @return the updated list. + */ + <LIST extends List<ELEMENT_TYPE>> LIST toList(final LIST list); + + /** + * Converts the stream to a set. + * + * @return the built set. + */ + Set<ELEMENT_TYPE> toSet(); + + /** + * Dumps the content of the stream to the given set. + * + * @param set the set to update + * @param <SET> the set type. + * @return the updated set. + */ + <SET extends Set<ELEMENT_TYPE>> SET toSet(final SET set); + + /** + * Creates a stream of pairs of the content of the stream and values produced by a supplier. + * + * @param supplier the value supplier. + * @param <ASSOCIATED_TYPE> the type of associated values. + * @return the built stream. + */ + <ASSOCIATED_TYPE> + ExtendedStream<Pair<ELEMENT_TYPE, ASSOCIATED_TYPE>> associate(final Supplier<ASSOCIATED_TYPE> supplier); + + /** + * Creates a stream of pairs of the content of the stream and values produces by another stream. + * Once any of the two streams is closed, the produced stream is complete, regardless of potential values remaining + * in the other stream. + * + * @param supplier the value supplier. + * @param <ASSOCIATED_TYPE> the type of associated values. + * @return the built stream. + */ + <ASSOCIATED_TYPE> + ExtendedStream<Pair<ELEMENT_TYPE, ASSOCIATED_TYPE>> associate(final Stream<ASSOCIATED_TYPE> supplier); + + /** + * Prints the element of the stream on the standard output. + * + * @return this. + */ + ExtendedStream<ELEMENT_TYPE> print(); + + /** + * Adds the content of the given stream to the current stream and returns it as a new one. + * + * @param stream the stream to add. + * @return a new stream containing the current one then the given one. + */ + ExtendedStream<ELEMENT_TYPE> plus(final Stream<ELEMENT_TYPE> stream); + + /** + * Builds a string by joining the string representation of all contained values, interspersed with the given string + * delimiter. + * + * @param delimiter the delimiter string. + * @return the built {@link String}. + */ + String join(final String delimiter); + + /** + * Builds a string by joining the string representation of all contained values. + * + * @return the built {@link String}. + */ + String join(); + + /** + * Builds a pair of streams by partitioning the current one using the given pivot function. + * + * @param pivot the function to segregate the values of the given stream. + * @param <KEY_TYPE> type of partition key. + * @return the pair of created streams. + */ + <KEY_TYPE> + ExtendedStream<Pair<KEY_TYPE, ExtendedStream<ELEMENT_TYPE>>> + partition(final Function<ELEMENT_TYPE, KEY_TYPE> pivot); + + /** + * A utility class representing a pair. + * + * @param <FIRST_TYPE> the first value type. + * @param <SECOND_TYPE> the second value type. + */ + @SuppressWarnings("WeakerAccess") + class Pair<FIRST_TYPE, SECOND_TYPE> { + /** + * The first value. + */ + public final FIRST_TYPE first; + + /** + * The second value. + */ + public final SECOND_TYPE second; + + /** + * Default CTor. + * + * @param first value of the same name. + * @param second value of the same name. + */ + public Pair(final FIRST_TYPE first, final SECOND_TYPE second) { + this.first = first; + this.second = second; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) return false; + if (!obj.getClass().equals(Pair.class)) return false; + final Pair pair = (Pair) obj; + return Objects.equals(first, pair.first) && Objects.equals(second, pair.second); + } + + @Override + public int hashCode() { + return Objects.hash(first, second); + } + } +} diff --git a/graphs/java/seq/src/main/java/fr/epita/assistants/seq/Seq.java b/graphs/java/seq/src/main/java/fr/epita/assistants/seq/Seq.java new file mode 100644 index 0000000..31e5cab --- /dev/null +++ b/graphs/java/seq/src/main/java/fr/epita/assistants/seq/Seq.java @@ -0,0 +1,413 @@ +package fr.epita.assistants.seq; + +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +public interface Seq<ELEMENT_TYPE> extends ExtendedStream<ELEMENT_TYPE> { + Stream<ELEMENT_TYPE> giveStream(); + + static <ELEMENT_TYPE> Seq<ELEMENT_TYPE> of(Stream<ELEMENT_TYPE> stream) { + return () -> stream; + } + + static <ELEMENT_TYPE> Seq<ELEMENT_TYPE> of(List<ELEMENT_TYPE> list) { + return list::stream; + } + + static <ELEMENT_TYPE> Seq<ELEMENT_TYPE> of(ELEMENT_TYPE... values) { + List<ELEMENT_TYPE> vals = new ArrayList<>(Arrays.asList(values)); + return vals::stream; + } + + /** + * Creates a map out of the stream. + * In case of duplicate keys, the latest element in the original stream will overwrite the one(s) in place. + * + * @param keyMapper mapping function to extract map keys. + * @param <KEY_TYPE> the expected type of key. + * @return the created map. + */ + default <KEY_TYPE> Map<KEY_TYPE, ELEMENT_TYPE> + toMap(final Function<ELEMENT_TYPE, KEY_TYPE> keyMapper) { + Map<KEY_TYPE, ELEMENT_TYPE> map = new HashMap<>(); + giveStream().forEach(e -> map.put(keyMapper.apply(e), e)); + return map; + } + + /** + * Creates a map out of the stream. + * In case of key duplicates, the latest element in the original stream will overwrite the one(s) in place. + * + * @param map the map to fill/update. + * @param keyMapper mapping function to extract map keys. + * @param valueMapper mapping function to extract map values. + * @param <KEY_TYPE> the expected type of key. + * @param <VALUE_TYPE> the expected type of value. + * @param <MAP_TYPE> the complete return type. + * @return the created map. + */ + default <KEY_TYPE, VALUE_TYPE, MAP_TYPE extends Map<KEY_TYPE, VALUE_TYPE>> + MAP_TYPE toMap(final MAP_TYPE map, + final Function<ELEMENT_TYPE, KEY_TYPE> keyMapper, + final Function<ELEMENT_TYPE, VALUE_TYPE> valueMapper) { + giveStream().forEach(e -> map.put(keyMapper.apply(e), valueMapper.apply(e))); + return map; + } + + /** + * Creates a map out of the stream. + * In case of duplicate keys, the latest element in the original stream will overwrite the one(s) in place. + * + * @param keyMapper mapping function to extract map keys. + * @param valueMapper mapping function to extract map values. + * @param <KEY_TYPE> the expected type of key. + * @param <VALUE_TYPE> the expected type of value. + * @return the created map. + */ + default <KEY_TYPE, VALUE_TYPE> + Map<KEY_TYPE, VALUE_TYPE> toMap(final Function<ELEMENT_TYPE, KEY_TYPE> keyMapper, + final Function<ELEMENT_TYPE, VALUE_TYPE> valueMapper) { + Map<KEY_TYPE, VALUE_TYPE> map = new HashMap<>(); + giveStream().forEach(e -> map.put(keyMapper.apply(e), valueMapper.apply(e))); + return map; + } + + @Override + public default Stream<ELEMENT_TYPE> filter(Predicate<? super ELEMENT_TYPE> predicate) { + return giveStream().filter(predicate); + } + + @Override + public default <R> Stream<R> map(Function<? super ELEMENT_TYPE, ? extends R> mapper) { + return giveStream().map(mapper); + } + + @Override + public default IntStream mapToInt(ToIntFunction<? super ELEMENT_TYPE> mapper) { + return giveStream().mapToInt(mapper); + } + + @Override + public default LongStream mapToLong(ToLongFunction<? super ELEMENT_TYPE> mapper) { + return giveStream().mapToLong(mapper); + } + + @Override + public default DoubleStream mapToDouble(ToDoubleFunction<? super ELEMENT_TYPE> mapper) { + return giveStream().mapToDouble(mapper); + } + + @Override + public default <R> Stream<R> flatMap(Function<? super ELEMENT_TYPE, ? extends Stream<? extends R>> mapper) { + return giveStream().flatMap(mapper); + } + + @Override + public default IntStream flatMapToInt(Function<? super ELEMENT_TYPE, ? extends IntStream> mapper) { + return giveStream().flatMapToInt(mapper); + } + + @Override + public default LongStream flatMapToLong(Function<? super ELEMENT_TYPE, ? extends LongStream> mapper) { + return giveStream().flatMapToLong(mapper); + } + + @Override + public default DoubleStream flatMapToDouble(Function<? super ELEMENT_TYPE, ? extends DoubleStream> mapper) { + return giveStream().flatMapToDouble(mapper); + } + + @Override + public default Stream<ELEMENT_TYPE> distinct() { + return giveStream().distinct(); + } + + @Override + public default Stream<ELEMENT_TYPE> sorted() { + return giveStream().sorted(); + } + + @Override + public default Stream<ELEMENT_TYPE> sorted(Comparator<? super ELEMENT_TYPE> comparator) { + return giveStream().sorted(comparator); + } + + @Override + public default Stream<ELEMENT_TYPE> peek(Consumer<? super ELEMENT_TYPE> action) { + return giveStream().peek(action); + } + + @Override + public default Stream<ELEMENT_TYPE> limit(long maxSize) { + return giveStream().limit(maxSize); + } + + @Override + public default Stream<ELEMENT_TYPE> skip(long n) { + return giveStream().skip(n); + } + + @Override + public default void forEach(Consumer<? super ELEMENT_TYPE> action) { + giveStream().forEach(action); + } + + @Override + public default void forEachOrdered(Consumer<? super ELEMENT_TYPE> action) { + giveStream().forEachOrdered(action); + } + + @Override + public default Object[] toArray() { + return giveStream().toArray(); + } + + @Override + public default <A> A[] toArray(IntFunction<A[]> generator) { + return giveStream().toArray(generator); + } + + @Override + public default ELEMENT_TYPE reduce(ELEMENT_TYPE identity, BinaryOperator<ELEMENT_TYPE> accumulator) { + return giveStream().reduce(identity, accumulator); + } + + @Override + public default Optional<ELEMENT_TYPE> reduce(BinaryOperator<ELEMENT_TYPE> accumulator) { + return giveStream().reduce(accumulator); + } + + @Override + public default <U> U reduce(U identity, BiFunction<U, ? super ELEMENT_TYPE, U> accumulator, BinaryOperator<U> combiner) { + return giveStream().reduce(identity, accumulator, combiner); + } + + @Override + public default <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super ELEMENT_TYPE> accumulator, BiConsumer<R, R> combiner) { + return giveStream().collect(supplier, accumulator, combiner); + } + + @Override + public default <R, A> R collect(Collector<? super ELEMENT_TYPE, A, R> collector) { + return giveStream().collect(collector); + } + + /** + * Converts the stream to a list. + * + * @return the created list. + */ + default List<ELEMENT_TYPE> toList() { + return giveStream().toList(); + } + + @Override + public default Optional<ELEMENT_TYPE> min(Comparator<? super ELEMENT_TYPE> comparator) { + return giveStream().min(comparator); + } + + @Override + public default Optional<ELEMENT_TYPE> max(Comparator<? super ELEMENT_TYPE> comparator) { + return giveStream().max(comparator); + } + + @Override + public default long count() { + return giveStream().count(); + } + + @Override + public default boolean anyMatch(Predicate<? super ELEMENT_TYPE> predicate) { + return giveStream().anyMatch(predicate); + } + + @Override + public default boolean allMatch(Predicate<? super ELEMENT_TYPE> predicate) { + return giveStream().allMatch(predicate); + } + + @Override + public default boolean noneMatch(Predicate<? super ELEMENT_TYPE> predicate) { + return giveStream().noneMatch(predicate); + } + + @Override + public default Optional<ELEMENT_TYPE> findFirst() { + return giveStream().findFirst(); + } + + @Override + public default Optional<ELEMENT_TYPE> findAny() { + return giveStream().findAny(); + } + + /** + * Dumps the content of the stream to the given list. + * + * @param list the list to dump values to. + * @param <LIST> the exact type of list. + * @return the updated list. + */ + default <LIST extends List<ELEMENT_TYPE>> LIST toList(final LIST list) { + giveStream().forEach(list::add); + return list; + } + + /** + * Converts the stream to a set. + * + * @return the built set. + */ + default Set<ELEMENT_TYPE> toSet() { + return giveStream().collect(Collectors.toSet()); + } + + /** + * Dumps the content of the stream to the given set. + * + * @param set the set to update + * @param <SET> the set type. + * @return the updated set. + */ + default <SET extends Set<ELEMENT_TYPE>> SET toSet(final SET set) { + giveStream().forEach(set::add); + return set; + } + + /** + * Creates a stream of pairs of the content of the stream and values produced by a supplier. + * + * @param supplier the value supplier. + * @param <ASSOCIATED_TYPE> the type of associated values. + * @return the built stream. + */ + default <ASSOCIATED_TYPE> + ExtendedStream<Pair<ELEMENT_TYPE, ASSOCIATED_TYPE>> associate(final Supplier<ASSOCIATED_TYPE> supplier) { + return Seq.of(giveStream().map(e -> new Pair<ELEMENT_TYPE, + ASSOCIATED_TYPE>(e, supplier.get()))); + } + + /** + * Creates a stream of pairs of the content of the stream and values produces by another stream. + * Once any of the two streams is closed, the produced stream is complete, regardless of potential values remaining + * in the other stream. + * + * @param supplier the value supplier. + * @param <ASSOCIATED_TYPE> the type of associated values. + * @return the built stream. + */ + default <ASSOCIATED_TYPE> + ExtendedStream<Pair<ELEMENT_TYPE, ASSOCIATED_TYPE>> associate(final Stream<ASSOCIATED_TYPE> supplier) { + List<ELEMENT_TYPE> elements = giveStream().toList(); + List<ASSOCIATED_TYPE> assocs = supplier.toList(); + return Seq.of(IntStream.range(0, Math.min(elements.size(), + assocs.size())).mapToObj(i -> new Pair<ELEMENT_TYPE, ASSOCIATED_TYPE>(elements.get(i), assocs.get(i)))); + } + + /** + * Prints the element of the stream on the standard output. + * + * @return this. + */ + default ExtendedStream<ELEMENT_TYPE> print() { + return (ExtendedStream<ELEMENT_TYPE>) giveStream().peek(System.out::println); + } + + /** + * Adds the content of the given stream to the current stream and returns it as a new one. + * + * @param stream the stream to add. + * @return a new stream containing the current one then the given one. + */ + default ExtendedStream<ELEMENT_TYPE> plus(final Stream<ELEMENT_TYPE> stream) { + return Seq.of(Stream.concat(giveStream(), stream)); + } + + /** + * Builds a string by joining the string representation of all contained values, interspersed with the given string + * delimiter. + * + * @param delimiter the delimiter string. + * @return the built {@link String}. + */ + default String join(final String delimiter) { + return giveStream().map(ELEMENT_TYPE::toString).collect(Collectors.joining(delimiter)); + } + + /** + * Builds a string by joining the string representation of all contained values. + * + * @return the built {@link String}. + */ + default String join() { + return giveStream().map(ELEMENT_TYPE::toString).collect(Collectors.joining()); + } + + /** + * Builds a pair of streams by partitioning the current one using the given pivot function. + * + * @param pivot the function to segregate the values of the given stream. + * @param <KEY_TYPE> type of partition key. + * @return the pair of created streams. + */ + default <KEY_TYPE> + ExtendedStream<Pair<KEY_TYPE, ExtendedStream<ELEMENT_TYPE>>> + partition(final Function<ELEMENT_TYPE, KEY_TYPE> pivot) { + Map<KEY_TYPE, List<ELEMENT_TYPE>> map = new HashMap<>(); + giveStream().forEach(e -> { + KEY_TYPE key = pivot.apply(e); + List<ELEMENT_TYPE> assoc = new ArrayList<>(); + if (map.containsKey(key)) { + assoc.addAll(map.get(key)); + } + assoc.add(e); + map.put(key, assoc); + }); + List<Pair<KEY_TYPE, ExtendedStream<ELEMENT_TYPE>>> list = new ArrayList<>(); + for (KEY_TYPE key : map.keySet()) { + list.add(new Pair<>(key, Seq.of(map.get(key).stream()))); + } + return Seq.of(list.stream()); + } + + @Override + public default Iterator<ELEMENT_TYPE> iterator() { + return giveStream().iterator(); + } + + @Override + public default Spliterator<ELEMENT_TYPE> spliterator() { + return giveStream().spliterator(); + } + + @Override + public default boolean isParallel() { + return giveStream().isParallel(); + } + + @Override + public default Stream<ELEMENT_TYPE> sequential() { + return giveStream().sequential(); + } + + @Override + public default Stream<ELEMENT_TYPE> parallel() { + return giveStream().parallel(); + } + + @Override + public default Stream<ELEMENT_TYPE> unordered() { + return giveStream().unordered(); + } + + @Override + public default Stream<ELEMENT_TYPE> onClose(Runnable closeHandler) { + return giveStream().onClose(closeHandler); + } + + @Override + public default void close() { + giveStream().close(); + } +} diff --git a/graphs/java/seq/src/test/java/fr/epita/assistants/seq/ExtendedStreamTest.java b/graphs/java/seq/src/test/java/fr/epita/assistants/seq/ExtendedStreamTest.java new file mode 100644 index 0000000..b0bb911 --- /dev/null +++ b/graphs/java/seq/src/test/java/fr/epita/assistants/seq/ExtendedStreamTest.java @@ -0,0 +1,244 @@ +package fr.epita.assistants.seq; + +import java.lang.reflect.Modifier; +import java.time.Duration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; + +import fr.epita.assistants.seq.ExtendedStream.Pair; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class ExtendedStreamTest { + + private static <TYPE> ExtendedStream<TYPE> ctor(final List<TYPE> values) { + // FIXME: replace by your own implementation. + return Seq.of(values); + } + + private static <TYPE> ExtendedStream<TYPE> ctor(final TYPE... values) { + // FIXME: replace by your own implementation. + return Seq.of(values); + } + + private static <TYPE> ExtendedStream<TYPE> ctor(final Stream<TYPE> values) { + // FIXME: replace by your own implementation. + return Seq.of(values); + } + + private static DummyObject dummy(final int id, final String name) { + return new DummyObject(id, name); + } + + @Test + public void isSeqAnInterface() throws ClassNotFoundException { + Class<?> seqClass = Class.forName("fr.epita.assistants.seq.Seq"); + int modifiers = seqClass.getModifiers(); + boolean isInterface = Modifier.isInterface(modifiers); + assertTrue(isInterface, "Seq must be an interface"); + } + + @Test + public void toMapKeyValue() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<DummyObject> es = ctor(dummy(1, "1"), dummy(2, "2"), dummy(2, "4"), dummy(3, "3")); + final Map<Integer, String> map = es.toMap(DummyObject::getId, DummyObject::getName); + assertEquals(3, map.size()); + assertEquals("1", map.get(1)); + assertEquals("4", map.get(2)); + assertEquals("3", map.get(3)); + }); + } + + @Test + public void toMapKeyValueMap() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<DummyObject> es = ctor(dummy(1, "1"), dummy(2, "2"), dummy(2, "4"), dummy(3, "3")); + final Map<Integer, DummyObject> source = new HashMap<>(); + source.put(42, new DummyObject(42, "me")); + final Map<Integer, DummyObject> map = es.toMap(source, DummyObject::getId, it -> it); + assertEquals(4, map.size()); + assertEquals("1", map.get(1).name); + assertEquals("4", map.get(2).name); + assertEquals("3", map.get(3).name); + assertEquals("me", map.get(42).name); + }); + } + + @Test + public void toMapKey() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<DummyObject> es = ctor(dummy(1, "1"), dummy(2, "2"), dummy(2, "4"), dummy(3, "3")); + final Map<Integer, DummyObject> map = es.toMap(DummyObject::getId); + assertEquals(3, map.size()); + assertEquals("1", map.get(1).name); + assertEquals("4", map.get(2).name); + assertEquals("3", map.get(3).name); + }); + } + + + @Test + public void toList() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<DummyObject> es = ctor(dummy(1, "1"), dummy(2, "2"), dummy(2, "4"), dummy(3, "3")); + final List<DummyObject> list = es.toList(); + assertEquals(4, list.size()); + assertEquals("1", list.get(0).name); + assertEquals("2", list.get(1).name); + assertEquals("4", list.get(2).name); + assertEquals("3", list.get(3).name); + + }); + } + + @Test + public void toListWithList() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<DummyObject> es = ctor(dummy(1, "1"), dummy(2, "2"), dummy(2, "4"), dummy(3, "3")); + final List<DummyObject> source = new ArrayList<>(); + source.add(new DummyObject(42, "me")); + final List<DummyObject> list = es.toList(source); + assertEquals(5, list.size()); + assertEquals("me", list.get(0).name); + assertEquals("1", list.get(1).name); + assertEquals("2", list.get(2).name); + assertEquals("4", list.get(3).name); + assertEquals("3", list.get(4).name); + }); + } + + @Test + public void toSet() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<Integer> es = ctor(1, 2, 2, 3); + final Set<Integer> set = es.toSet(); + assertEquals(3, set.size()); + assertTrue(set.contains(1)); + assertTrue(set.contains(2)); + assertTrue(set.contains(3)); + }); + } + + @Test + public void toSetWithSet() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<Integer> es = ctor(1, 2, 2, 3); + final Set<Integer> source = new HashSet<>(); + source.add(1); + source.add(2); + source.add(42); + final Set<Integer> set = es.toSet(source); + assertEquals(4, set.size()); + assertTrue(set.contains(1)); + assertTrue(set.contains(2)); + assertTrue(set.contains(3)); + assertTrue(set.contains(42)); + }); + } + + @Test + public void associateWithSupplier() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<String> es = ctor("a", "b", "c"); + final List<Pair<String, Integer>> list = es.associate(new Increment()).toList(); + + assertEquals(3, list.size()); + assertEquals(new Pair<>("a", 0), list.get(0)); + assertEquals(new Pair<>("b", 1), list.get(1)); + assertEquals(new Pair<>("c", 2), list.get(2)); + + + }); + } + + @Test + public void associateWithStream() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<String> es = ctor("a", "b", "c"); + final List<Pair<String, Integer>> list = es.associate(ctor(0, 1, 2, 3, 4, 5)).toList(); + + assertEquals(3, list.size()); + assertEquals(new Pair<>("a", 0), list.get(0)); + assertEquals(new Pair<>("b", 1), list.get(1)); + assertEquals(new Pair<>("c", 2), list.get(2)); + }); + } + + @Test + public void plus() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<String> es = ctor("a", "b", "c").plus(ctor("d", "e", "f")); + assertEquals("abcdef", es.join()); + }); + } + + @Test + public void join() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<String> es = ctor("a", "b", "c", "d", "e", "f"); + assertEquals("abcdef", es.join()); + }); + } + + @Test + public void joinWithDelimiter() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<String> es = ctor("a", "b", "c", "d", "e", "f"); + assertEquals("a-b-c-d-e-f", es.join("-")); + }); + } + + @Test + public void partition() { + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + final ExtendedStream<Integer> es = ctor(0, 1, 2, 3, 4, 5, 6, 7); + final ExtendedStream<Pair<Boolean, ExtendedStream<Integer>>> partitions = es.partition(val -> val % 2 == 0); + final List<Pair<Boolean, ExtendedStream<Integer>>> list = partitions.toList(); + + + assertEquals(list.get(0).first ? "0246" : "1357", list.get(0).second.join()); + assertEquals(list.get(0).first ? "1357" : "0246", list.get(1).second.join()); + }); + } + + static class DummyObject { + public final Integer id; + public final String name; + + public DummyObject(final Integer id, final String name) { + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public String getName() { + return name; + } + } + + + static class Increment implements Supplier<Integer> { + private int increment = 0; + + @Override + public Integer get() { + return increment++; + } + } +} diff --git a/graphs/java/singleton/.gitignore b/graphs/java/singleton/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/singleton/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/singleton/pom.xml b/graphs/java/singleton/pom.xml new file mode 100644 index 0000000..6bb46cb --- /dev/null +++ b/graphs/java/singleton/pom.xml @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>singleton</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + <versions.slf4j>1.7.36</versions.slf4j> + <versions.archunit>1.2.0</versions.archunit> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>com.tngtech.archunit</groupId> + <artifactId>archunit-junit5</artifactId> + <version>${versions.archunit}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/singleton/src/main/java/fr/epita/assistants/logger/Logger.java b/graphs/java/singleton/src/main/java/fr/epita/assistants/logger/Logger.java new file mode 100644 index 0000000..4cc59f8 --- /dev/null +++ b/graphs/java/singleton/src/main/java/fr/epita/assistants/logger/Logger.java @@ -0,0 +1,62 @@ +package fr.epita.assistants.logger; + +/** + * A standard logger interface + */ +public interface Logger { + /** + * The Level enum, representing the gravity of a log message. + */ + enum Level { + INFO, + WARN, + ERROR + } + + /** + * Formats a message and returns it as a string + * @param level The gravity level of the logged message. + * @param message The logged message. + * @return + */ + static String getFormattedLog(final Level level, final String message) { + return '[' + + level.toString() + + "] " + + message; + } + + /** + * Outputs the logged message with the format '[LEVEL] Message' to stderr. + * + * @param level The gravity level of the logged message. + * @param message The logged message. + */ + void log(final Level level, final String message); + + /** + * Getter for infoCounter. + * + * @return infoCounter. + */ + int getInfoCounter(); + + /** + * Getter for warnCounter. + * + * @return warnCounter. + */ + int getWarnCounter(); + + /** + * Getter for errorCounter. + * + * @return errorCounter. + */ + int getErrorCounter(); + + /** + * Resets the counters. + */ + void reset(); +} diff --git a/graphs/java/singleton/src/main/java/fr/epita/assistants/singleton/SingletonEnumLogger.java b/graphs/java/singleton/src/main/java/fr/epita/assistants/singleton/SingletonEnumLogger.java new file mode 100644 index 0000000..4fb969e --- /dev/null +++ b/graphs/java/singleton/src/main/java/fr/epita/assistants/singleton/SingletonEnumLogger.java @@ -0,0 +1,49 @@ +package fr.epita.assistants.singleton; + +import fr.epita.assistants.logger.Logger; + +public enum SingletonEnumLogger implements Logger { + INSTANCE; + int infoCounter; + int errorCounter; + int warnCounter; + + @Override + public void log(Level level, String message) { + switch (level) + { + case INFO: + infoCounter++; + break; + case WARN: + warnCounter++; + break; + case ERROR: + errorCounter++; + break; + } + System.err.println(Logger.getFormattedLog(level, message)); + } + + @Override + public int getInfoCounter() { + return infoCounter; + } + + @Override + public int getWarnCounter() { + return warnCounter; + } + + @Override + public int getErrorCounter() { + return errorCounter; + } + + @Override + public void reset() { + infoCounter = 0; + warnCounter = 0; + errorCounter = 0; + } +} diff --git a/graphs/java/singleton/src/main/java/fr/epita/assistants/singleton/StaticSingletonLogger.java b/graphs/java/singleton/src/main/java/fr/epita/assistants/singleton/StaticSingletonLogger.java new file mode 100644 index 0000000..51d1801 --- /dev/null +++ b/graphs/java/singleton/src/main/java/fr/epita/assistants/singleton/StaticSingletonLogger.java @@ -0,0 +1,54 @@ +package fr.epita.assistants.singleton; + +import fr.epita.assistants.logger.Logger; + +public class StaticSingletonLogger implements Logger { + int infoCounter; + int errorCounter; + int warnCounter; + private StaticSingletonLogger() { + infoCounter = 0; + errorCounter = 0; + warnCounter = 0; + } + + private static class InstanceHolder { + private static final StaticSingletonLogger _INSTANCE = new StaticSingletonLogger(); + } + + public static StaticSingletonLogger getInstance() { + return InstanceHolder._INSTANCE; + } + @Override + public void log(Level level, String message) { + switch (level) + { + case INFO -> infoCounter++; + case WARN -> warnCounter++; + case ERROR -> errorCounter++; + } + System.err.println(Logger.getFormattedLog(level, message)); + } + + @Override + public int getInfoCounter() { + return infoCounter; + } + + @Override + public int getWarnCounter() { + return warnCounter; + } + + @Override + public int getErrorCounter() { + return errorCounter; + } + + @Override + public void reset() { + infoCounter = 0; + warnCounter = 0; + errorCounter = 0; + } +} diff --git a/graphs/java/streamStudent/.gitignore b/graphs/java/streamStudent/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/streamStudent/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/streamStudent/pom.xml b/graphs/java/streamStudent/pom.xml new file mode 100644 index 0000000..d304253 --- /dev/null +++ b/graphs/java/streamStudent/pom.xml @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>streamStudent</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + <dependency> + <groupId>org.javassist</groupId> + <artifactId>javassist</artifactId> + <version>3.29.2-GA</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/streamStudent/src/main/java/fr/epita/assistants/streamstudent/Pair.java b/graphs/java/streamStudent/src/main/java/fr/epita/assistants/streamstudent/Pair.java new file mode 100644 index 0000000..c3cde84 --- /dev/null +++ b/graphs/java/streamStudent/src/main/java/fr/epita/assistants/streamstudent/Pair.java @@ -0,0 +1,67 @@ +package fr.epita.assistants.streamstudent; + +public class Pair<K, V> { + + /** + * Key of this pair. + */ + private K key; + + /** + * Gets the key for this pair. + * + * @return key for this pair + */ + public K getKey() { + return key; + } + + /** + * Value of this pair. + */ + private V value; + + /** + * Gets the value for this pair. + * + * @return value for this pair + */ + public V getValue() { + return value; + } + + /** + * Creates a new pair. + * + * @param key The key for this pair + * @param value The value to use for this pair + */ + public Pair(K key, V value) { + this.key = key; + this.value = value; + } + + + @Override + public int hashCode() { + return key.hashCode() * 13 + (value == null ? 0 : value.hashCode()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o instanceof Pair) { + Pair pair = (Pair) o; + if (key != null ? !key.equals(pair.key) : pair.key != null) return false; + if (value != null ? !value.equals(pair.value) : pair.value != null) return false; + return true; + } + return false; + } + + @Override + public String toString() { + return "(" + key + ", " + value + ")"; + } +} + diff --git a/graphs/java/streamStudent/src/main/java/fr/epita/assistants/streamstudent/Streamer.java b/graphs/java/streamStudent/src/main/java/fr/epita/assistants/streamstudent/Streamer.java new file mode 100644 index 0000000..87654a4 --- /dev/null +++ b/graphs/java/streamStudent/src/main/java/fr/epita/assistants/streamstudent/Streamer.java @@ -0,0 +1,58 @@ +package fr.epita.assistants.streamstudent; + +import java.util.Comparator; +import java.util.Objects; +import java.util.Optional; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +public class Streamer { + public Stream<Pair<Integer, String>> validator(Stream<Pair<Integer, String>> stream) { + return stream.filter(student -> student.getKey() >= 0 && student.getKey() <= 100 && (Pattern.matches("[^_" + + ".]*\\.[^_.]*", student.getValue()) || Pattern.matches("[^._]*_[^._]*", student.getValue()))); + } + + public Stream<Pair<Integer, String>> orderGrade(Stream<Pair<Integer, String>> stream) { + return stream.sorted((i, j) -> { + if (!Objects.equals(i.getKey(), j.getKey())) + return i.getKey().compareTo(j.getKey()); + else + return i.getValue().compareTo(j.getValue()); + }); + } + + public Stream<Pair<Integer, String>> lowercase(Stream<Pair<Integer, String>> stream) { + return stream.map(i -> { + if (Pattern.matches(".*[A-Z]+.*", i.getValue())) { + return new Pair<>(i.getKey() / 2, i.getValue().toLowerCase()); + } else + return new Pair<>(i.getKey(), i.getValue().toLowerCase()); + }); + } + + public Optional<Pair<Integer, String>> headOfTheClass(Stream<Pair<Integer, String>> stream) { + return stream.max((i, j) -> { + if (j.getKey().equals(i.getKey())) + return j.getValue().compareTo(i.getValue()); + else + return i.getKey().compareTo(j.getKey()); + }); + } + + public Stream<Pair<Integer, String>> quickFix(Stream<Pair<Integer, String>> stream) { + return stream.map(i -> { + if (Pattern.matches("[mM][Aa].*", i.getValue()) || Pattern.matches("[lL].*[xX]", i.getValue())) { + return new Pair<>(Math.clamp(i.getKey() * 2, 0, 100), i.getValue()); + } else return i; + }); + } + + public Stream<Pair<Integer, String>> encryption(Stream<Pair<Integer, String>> stream) { + return stream.map(i -> { + StringBuilder sb = new StringBuilder(); + sb.append(i.getValue(), i.getValue().length() / 2, i.getValue().length()); + sb.append(i.getValue(), 0, i.getValue().length() / 2); + return new Pair<>(i.getKey(), sb.toString()); + }); + } +} diff --git a/graphs/java/streamStudent/src/test/java/fr/epita/assistants/streamstudent/StreamStudentTest.java b/graphs/java/streamStudent/src/test/java/fr/epita/assistants/streamstudent/StreamStudentTest.java new file mode 100644 index 0000000..d36fc09 --- /dev/null +++ b/graphs/java/streamStudent/src/test/java/fr/epita/assistants/streamstudent/StreamStudentTest.java @@ -0,0 +1,63 @@ +package fr.epita.assistants.streamstudent; + +import org.junit.jupiter.api.Test; + +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +public class StreamStudentTest { + static void assertStreamEquals(Stream<Pair<Integer, String>> expectedStream, + Stream<Pair<Integer, String>> actualStream) { + // Get iterators from stream + Iterator<Pair<Integer, String>> iterator1 = expectedStream.iterator(); + Iterator<Pair<Integer, String>> iterator2 = actualStream.iterator(); + + while (iterator1.hasNext() && iterator2.hasNext()) { + // Get next objects + Pair<Integer, String> login1 = iterator1.next(); + Pair<Integer, String> login2 = iterator2.next(); + + // Check if pairs are equal + assertEquals(login1, login2); + } + + assertTrue(!iterator1.hasNext() && !iterator2.hasNext(), + "Streams do not have the same length"); + + } + + @Test + public void validatorLoginContainsTwoOrMoreUnderscore() { + Pair<Integer, String> loginTwoUnderscore = new Pair<>(50, "xavier_login_"); + Pair<Integer, String> loginValid = new Pair<>(90, "xavierlogin"); + Pair<Integer, String> loginBoth = new Pair<>(90, "xavier._login"); + Pair<Integer, String> loginMultipleUnderscord = new Pair<>(10, "_login__x"); + Streamer streamer = new Streamer(); + + var loginList = List.of(loginTwoUnderscore, loginValid, loginBoth, loginMultipleUnderscord); + + var actual = streamer.validator(loginList.stream()); + + assertEquals(0, actual.count()); + } + + @Test + public void encrypt1() { + Pair<Integer, String> loginTwoUnderscore = new Pair<>(50, "a_b"); + Pair<Integer, String> xavier = new Pair<>(50, "xavier.login"); + Pair<Integer, String> loginValid = new Pair<>(90, "thomas.kummel"); + Pair<Integer, String> loginBoth = new Pair<>(90, "florian.fogliani"); + Pair<Integer, String> loginMultipleUnderscord = new Pair<>(10, "malo.beauchamps"); + Streamer streamer = new Streamer(); + + var loginList = List.of(loginTwoUnderscore, loginValid, loginBoth, loginMultipleUnderscord, xavier); + + var actual = streamer.encryption(loginList.stream()); + System.out.println("actual stream: " + actual.toString()); + } + + // Add your own tests here +}
\ No newline at end of file diff --git a/graphs/java/test1/.gitignore b/graphs/java/test1/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/test1/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/test1/pom.xml b/graphs/java/test1/pom.xml new file mode 100644 index 0000000..1959226 --- /dev/null +++ b/graphs/java/test1/pom.xml @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>test1</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + <versions.slf4j>1.7.36</versions.slf4j> + <versions.archunit>1.2.0</versions.archunit> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>com.tngtech.archunit</groupId> + <artifactId>archunit-junit5</artifactId> + <version>${versions.archunit}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/test1/src/main/java/fr/epita/assistants/maths/Matrix.java b/graphs/java/test1/src/main/java/fr/epita/assistants/maths/Matrix.java new file mode 100644 index 0000000..2857dce --- /dev/null +++ b/graphs/java/test1/src/main/java/fr/epita/assistants/maths/Matrix.java @@ -0,0 +1,33 @@ +package fr.epita.assistants.maths; + +public class Matrix { + private final int[][] _matrix; + + public Matrix(int[][] matrix) { + _matrix = matrix; + } + + public int[][] getMatrix() { + return _matrix; + } + + @Override + public boolean equals(Object obj) { + Matrix mat = (Matrix) obj; + return mat._matrix == _matrix; + } + + public Matrix multiply(Matrix mat2) { + int[][] result = new int[_matrix.length][_matrix[0].length]; + + for (int i = 0; i < _matrix.length; i++) + for (int j = 0; j < mat2._matrix[0].length; j++) { + int value = 0; + for (int x = 0, y = 0; x < _matrix[i].length && y < mat2._matrix.length; x++, y++) + value += _matrix[i][x] * mat2._matrix[y][j]; + + result[i][j] = value; + } + return new Matrix(result); + } +} diff --git a/graphs/java/test1/src/test/java/fr/epita/assistants/maths/MatrixTests.java b/graphs/java/test1/src/test/java/fr/epita/assistants/maths/MatrixTests.java new file mode 100644 index 0000000..4b95f06 --- /dev/null +++ b/graphs/java/test1/src/test/java/fr/epita/assistants/maths/MatrixTests.java @@ -0,0 +1,113 @@ +package fr.epita.assistants.maths; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class MatrixTests { + @Test + public void ctor1() { + Matrix m = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + assertNotEquals(69, m.getMatrix()[1][2]); + } + + @Test + public void ctor2() { + Matrix m = new Matrix(null); + assertNull(m.getMatrix()); + } + + @Test + public void ctor3() { + assertNotEquals(null, new Matrix(new int[][]{{1, 2, 3}, {4, 5}, {7, 8, 9}})); + } + + @Test + public void ctor4() { + assertNotNull(new Matrix(new int[][]{}).getMatrix()); + } + + @Test + public void ctor5() { + Matrix m = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + Matrix n = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + + assertNotEquals(n.getMatrix()[1][2], m.getMatrix()[1][2]); + } + + @Test + public void equals1() { + Matrix m = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + Matrix n = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + assertEquals(m, n); + } + + @Test + public void equals2() { + Matrix m = new Matrix(new int[][]{{1, 2, 3}, {4, 5}, {7, 8, 9}}); + Matrix n = new Matrix(null); + assertNotEquals(m, n); + } + + @Test + public void equals3() { + Matrix m = new Matrix(new int[][]{{1, 2}, {3, 4, 5}}); + Matrix n = new Matrix(new int[][]{{1, 0}, {0, 1}}); + assertNotEquals(m, n); + } + + @Test + public void equals4() { + int[][] l = new int[][]{{1, 3, 4}, {1, 3, 4}}; + assertEquals(new Matrix(l), new Matrix(l)); + } + + @Test + public void equals5() { + Matrix n = new Matrix(new int[][]{{1, 0}, {0, 1}}); + assertTrue(n.equals("test")); + } + + @Test + public void equals6() { + Matrix m = new Matrix(new int[][]{{1, 2}, {4}, {7, 8, 9}}); + Matrix n = new Matrix(new int[][]{{7, 8, 9}}); + assertEquals(m, n); + } + @Test + public void equals7() { + Matrix m = new Matrix(new int[][]{{1, 2}, {4}, {7, 8, 9}}); + Matrix n = new Matrix(new int[][]{}); + assertEquals(m, n); + } + @Test + public void equals8() { + Matrix m = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + Matrix n = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 10}}); + assertEquals(m, n); + } + + @Test + public void mul1() { + Matrix m = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + Matrix n = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + + assertNotEquals(new Matrix(new int[][]{{30, 36, 42}, {66, 81, 96}, {102, 126, 150}}), m.multiply(n)); + } + + @Test + public void mul2() { + Matrix m = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + + assertNotEquals(new Matrix(new int[][]{{30, 36, 42}, {66, 81, 96}}), m.multiply(null)); + } + + @Test + public void mul3() { + Matrix m = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + Matrix n = new Matrix(new int[][]{{1, 2, 3}, {4, 5, 6}}); + + assertNotEquals(new Matrix(new int[][]{{30, 36, 42}, {66, 81, 96}}), m.multiply(n)); + } + // add your own tests here +}
\ No newline at end of file diff --git a/graphs/java/test2/pom.xml b/graphs/java/test2/pom.xml new file mode 100644 index 0000000..f0ab353 --- /dev/null +++ b/graphs/java/test2/pom.xml @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>test2</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + <versions.slf4j>1.7.36</versions.slf4j> + <versions.archunit>1.2.0</versions.archunit> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>com.tngtech.archunit</groupId> + <artifactId>archunit-junit5</artifactId> + <version>${versions.archunit}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/test2/src/main/java/fr/epita/assistants/server/MyServer.java b/graphs/java/test2/src/main/java/fr/epita/assistants/server/MyServer.java new file mode 100644 index 0000000..9a2a213 --- /dev/null +++ b/graphs/java/test2/src/main/java/fr/epita/assistants/server/MyServer.java @@ -0,0 +1,42 @@ +package fr.epita.assistants.server; + +import com.sun.net.httpserver.HttpServer; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static java.net.HttpURLConnection.HTTP_OK; + +public class MyServer { + + private static HttpServer server = null; + private static ExecutorService executor; + + + public static void launchServer() throws IOException { + server = HttpServer.create(new InetSocketAddress("localhost", 8080), 0); + executor = Executors.newFixedThreadPool(10); + server.setExecutor(executor); + var context = server.createContext("/"); + context.setHandler((arg) -> { + try { + Thread.sleep(1500); + arg.sendResponseHeaders(HTTP_OK, 0); + arg.close(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }); + server.start(); + } + + + public static void stopServer() { + if (server == null) + return; + server.stop(0); + executor.shutdownNow(); + } +} diff --git a/graphs/java/test2/src/main/java/fr/epita/assistants/test2/Test2.java b/graphs/java/test2/src/main/java/fr/epita/assistants/test2/Test2.java new file mode 100644 index 0000000..8427b43 --- /dev/null +++ b/graphs/java/test2/src/main/java/fr/epita/assistants/test2/Test2.java @@ -0,0 +1,48 @@ +package fr.epita.assistants.test2; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +public class Test2 { + /** + * Computes the nth value of the tribonacci suite. + * f(0) = 0, f(1) = 1, f(2) = 1, f(n+3) = f(n) + f(n+1) + f(n+2) + * + * @param n the nth sequence to compute + */ + public static long tribonacci(int n) { + if (n < 0) + throw new IllegalArgumentException("Error: n must be positive"); + + if (n == 0) + return 0; + if (n < 3) + return 1; + + long one = 0; + long two = 1; + long three = 1; + long res = 0; + + for (long i = 3; i <= n; i++) { + res = one + two + three; + one = two; + two = three; + three = res; + } + + return res; + } + + public static long serverGetResponseCode() throws IOException { + URL url = new URL("http://localhost:8080/"); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("GET"); + return con.getResponseCode(); + } + + public static int division(int a, int b) { + return a / b; + } +} diff --git a/graphs/java/test2/src/test/java/fr/epita/assistants/test2/Test2Test.java b/graphs/java/test2/src/test/java/fr/epita/assistants/test2/Test2Test.java new file mode 100644 index 0000000..0318dc2 --- /dev/null +++ b/graphs/java/test2/src/test/java/fr/epita/assistants/test2/Test2Test.java @@ -0,0 +1,105 @@ +package fr.epita.assistants.test2; + +import fr.epita.assistants.server.MyServer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +import java.io.IOException; +import java.net.ConnectException; + +import static fr.epita.assistants.test2.Test2.*; +import static org.junit.jupiter.api.Assertions.*; + +public class Test2Test { + @Test + void divPass() { + assertEquals(2, division(5, 2)); + } + + @Test + void divFZero() { + assertThrows(ArithmeticException.class, () -> division(5, 0)); + } + @Test + void divZeroZero() { + assertThrows(ArithmeticException.class, () -> division(0, 0)); + } + + @Test + @Timeout(1) + void divTimeout() { + assertEquals(0, division(0, 2)); + } + @Test + @Timeout(1) + void divTimeoutFatAss() { + assertNotEquals(554468611, division(745343524, 5546344)); + } + + @Test + void divServerPass() throws IOException { + MyServer.stopServer(); + MyServer.launchServer(); + long actual = serverGetResponseCode(); + assertEquals(200, actual); + MyServer.stopServer(); + } + @Test + void divServerSpam() throws IOException { + MyServer.stopServer(); + MyServer.launchServer(); + long actual = serverGetResponseCode(); + assertEquals(200, actual); + actual = serverGetResponseCode(); + assertEquals(200, actual); + actual = serverGetResponseCode(); + assertEquals(200, actual); + actual = serverGetResponseCode(); + assertEquals(200, actual); + actual = serverGetResponseCode(); + assertEquals(200, actual); + actual = serverGetResponseCode(); + assertEquals(200, actual); + actual = serverGetResponseCode(); + assertEquals(200, actual); + + MyServer.stopServer(); + } + @Test + void divServerNotStarted() { + MyServer.stopServer(); + assertThrows(ConnectException.class, () -> serverGetResponseCode()); + } + @Test + @Timeout(1) + void divServerTimeout() throws IOException { + MyServer.stopServer(); + MyServer.launchServer(); + long actual = serverGetResponseCode(); + assertEquals(200, actual); + MyServer.stopServer(); + } + @Test + @Timeout(1) + void triboFail() { + assertThrows(IllegalArgumentException.class, () -> tribonacci(-1)); + } + @Test + @Timeout(1) + void triboPass() { + assertEquals(0, tribonacci(0)); + assertEquals(1, tribonacci(1)); + assertEquals(1, tribonacci(2)); + assertEquals(2, tribonacci(3)); + assertEquals(4, tribonacci(4)); + assertEquals(7, tribonacci(5)); + assertEquals(13, tribonacci(6)); + assertEquals(1, tribonacci(7)); + assertEquals(1, tribonacci(8)); + } + @Test + @Timeout(1) + void triboTime() { + assertEquals(-1, tribonacci(Integer.MAX_VALUE)); + } +} diff --git a/graphs/java/threadForkJoin/.gitignore b/graphs/java/threadForkJoin/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/threadForkJoin/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/threadForkJoin/pom.xml b/graphs/java/threadForkJoin/pom.xml new file mode 100644 index 0000000..8e857e4 --- /dev/null +++ b/graphs/java/threadForkJoin/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>threadForkJoin</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/threadForkJoin/src/main/java/fr/epita/assistants/forkjoin/MyRecursiveTask.java b/graphs/java/threadForkJoin/src/main/java/fr/epita/assistants/forkjoin/MyRecursiveTask.java new file mode 100644 index 0000000..5934f92 --- /dev/null +++ b/graphs/java/threadForkJoin/src/main/java/fr/epita/assistants/forkjoin/MyRecursiveTask.java @@ -0,0 +1,49 @@ +package fr.epita.assistants.forkjoin; + +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.RecursiveTask; + +public class MyRecursiveTask extends RecursiveTask<Double> { + final private double[][] matrix; + final private int xLowerBound; + final private int xUpperBound; + final private int yLowerBound; + final private int yUpperBound; + + public MyRecursiveTask(double[][] matrix, int xLowerBound, int xUpperBound, int yLowerBound, int yUpperBound) { + this.matrix = matrix; + this.xLowerBound = xLowerBound; + this.xUpperBound = xUpperBound; + this.yLowerBound = yLowerBound; + this.yUpperBound = yUpperBound; + } + + @Override + protected Double compute() { + if (xUpperBound - xLowerBound <= 5 && yUpperBound - yLowerBound <= 5) { + Double avg = 0.0; + for (int j = yLowerBound; j < yUpperBound; j++) { + for (int i = xLowerBound; i < xUpperBound; i++) { + avg += matrix[j][i]; + } + } + if ((xUpperBound - xLowerBound) * (yUpperBound - yLowerBound) == 0) + return 0.0; + return avg / ((xUpperBound - xLowerBound) * (yUpperBound - yLowerBound)); + } else { + MyRecursiveTask t1 = new MyRecursiveTask(matrix, xLowerBound, xLowerBound + (xUpperBound - xLowerBound) / 2, + yLowerBound, yLowerBound + (yUpperBound - yLowerBound) / 2); + MyRecursiveTask t2 = new MyRecursiveTask(matrix, xLowerBound + (xUpperBound - xLowerBound) / 2, xUpperBound, + yLowerBound, yLowerBound + (yUpperBound - yLowerBound) / 2); + MyRecursiveTask t3 = new MyRecursiveTask(matrix, xLowerBound, xLowerBound + (xUpperBound - xLowerBound) / 2, + yLowerBound + (yUpperBound - yLowerBound) / 2, yUpperBound); + MyRecursiveTask t4 = new MyRecursiveTask(matrix, xLowerBound + (xUpperBound - xLowerBound) / 2, xUpperBound, + yLowerBound + (yUpperBound - yLowerBound) / 2, yUpperBound); + t1.fork(); + t2.fork(); + t3.fork(); + t4.fork(); + return (t1.join() + t2.join() + t3.join() + t4.join()) / 4; + } + } +}
\ No newline at end of file diff --git a/graphs/java/threadForkJoin/src/test/java/fr/epita/assistants/forkjoin/RecursiveTaskTest.java b/graphs/java/threadForkJoin/src/test/java/fr/epita/assistants/forkjoin/RecursiveTaskTest.java new file mode 100644 index 0000000..c8f6877 --- /dev/null +++ b/graphs/java/threadForkJoin/src/test/java/fr/epita/assistants/forkjoin/RecursiveTaskTest.java @@ -0,0 +1,34 @@ +package fr.epita.assistants.forkjoin; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@Timeout(1) +public class RecursiveTaskTest { + @Test + void exampleTest() { + // Create a Matrix + double[][] matrix = new double[][]{ + new double[]{10, 52, 100, 50, 74, 25}, + new double[]{10, 52, 100, 50, 74, 25}, + new double[]{10, 52, 100, 50, 74, 25}, + new double[]{10, 52, 100, 50, 74, 25}, + new double[]{10, 52, 100, 50, 74, 25}, + new double[]{10, 52, 100, 50, 74, 25} + }; + double expected = 51.83; + + MyRecursiveTask mrt = new MyRecursiveTask(matrix, 0, matrix[0].length, 0, matrix.length); + + // Fork and join task + mrt.fork(); + double got = mrt.join(); + + // Need delta because of 'double' type + assertEquals(expected, got, 0.01); + } + + // Write your tests here ... +} diff --git a/graphs/java/throwback/.gitignore b/graphs/java/throwback/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/throwback/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/throwback/pom.xml b/graphs/java/throwback/pom.xml new file mode 100644 index 0000000..ca306b0 --- /dev/null +++ b/graphs/java/throwback/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>throwback</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/IntegerException.java b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/IntegerException.java new file mode 100644 index 0000000..7bc7337 --- /dev/null +++ b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/IntegerException.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.throwback; + +public abstract class IntegerException extends Exception{ + public IntegerException(String message) { + super("IntegerException: " + message); + } +} diff --git a/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/LongStringException.java b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/LongStringException.java new file mode 100644 index 0000000..687c654 --- /dev/null +++ b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/LongStringException.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.throwback; + +public class LongStringException extends StringException { + public LongStringException(String message) { + super("LongStringException: " + message + " (length: " + message.length() + ")"); + } +} diff --git a/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/NegativeIntegerException.java b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/NegativeIntegerException.java new file mode 100644 index 0000000..ce84fc1 --- /dev/null +++ b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/NegativeIntegerException.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.throwback; + +public class NegativeIntegerException extends IntegerException { + public NegativeIntegerException(String message) { + super("NegativeIntegerException: " + message); + } +} diff --git a/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/Pitcher.java b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/Pitcher.java new file mode 100644 index 0000000..7093b08 --- /dev/null +++ b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/Pitcher.java @@ -0,0 +1,21 @@ +package fr.epita.assistants.throwback; + +import java.util.regex.Pattern; + +public class Pitcher { + public static void throwException(String message) throws + LongStringException, ShortStringException, + PositiveIntegerException, NegativeIntegerException, + UnknownException { + if (Pattern.matches("[0-9]+", message)) + throw new PositiveIntegerException(message); + else if (Pattern.matches("-[0-9]+", message)) + throw new NegativeIntegerException(message); + else if (Pattern.matches("[a-zA-Z ,.']{100,}", message)) + throw new LongStringException(message); + else if (Pattern.matches("[a-zA-Z ,.']{1,100}", message)) + throw new ShortStringException(message); + else + throw new UnknownException(message); + } +} diff --git a/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/PositiveIntegerException.java b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/PositiveIntegerException.java new file mode 100644 index 0000000..124fcf1 --- /dev/null +++ b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/PositiveIntegerException.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.throwback; + +public class PositiveIntegerException extends IntegerException{ + public PositiveIntegerException(String message) { + super("PositiveIntegerException: " + message); + } +} diff --git a/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/ShortStringException.java b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/ShortStringException.java new file mode 100644 index 0000000..28e5eda --- /dev/null +++ b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/ShortStringException.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.throwback; + +public class ShortStringException extends StringException { + public ShortStringException(String message) { + super("ShortStringException: " + message + " (length: " + message.length() + ")"); + } +} diff --git a/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/StringException.java b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/StringException.java new file mode 100644 index 0000000..03f10aa --- /dev/null +++ b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/StringException.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.throwback; + +public abstract class StringException extends Exception { + public StringException(String message) { + super("StringException: " + message); + } +} diff --git a/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/UnknownException.java b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/UnknownException.java new file mode 100644 index 0000000..005ecee --- /dev/null +++ b/graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/UnknownException.java @@ -0,0 +1,7 @@ +package fr.epita.assistants.throwback; + +public class UnknownException extends Exception{ + public UnknownException(String message) { + super("UnknownException: " + message); + } +} diff --git a/graphs/java/travel/.gitignore b/graphs/java/travel/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/travel/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/travel/pom.xml b/graphs/java/travel/pom.xml new file mode 100644 index 0000000..671d430 --- /dev/null +++ b/graphs/java/travel/pom.xml @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>travel</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + <dependency> + <groupId>com.opencsv</groupId> + <artifactId>opencsv</artifactId> + <version>4.1</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/travel/src/main/java/fr/epita/assistants/travel/Country.java b/graphs/java/travel/src/main/java/fr/epita/assistants/travel/Country.java new file mode 100644 index 0000000..e616e64 --- /dev/null +++ b/graphs/java/travel/src/main/java/fr/epita/assistants/travel/Country.java @@ -0,0 +1,44 @@ +package fr.epita.assistants.travel; + +import com.opencsv.CSVReader; + +import java.io.FileReader; +import java.time.ZoneId; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class Country { + String countryName; + public Map<String, Integer> travelTimes; + ZoneId countryZone; + String filename; + + public Country(String countryName, String countryZone, String inputFilePath) { + this.countryName = countryName; + this.countryZone = ZoneId.of(countryZone); + this.filename = inputFilePath; + this.travelTimes = initTravelTimes(inputFilePath); + } + + public Map<String, Integer> initTravelTimes(String inputFilePath) { + Map<String, Integer> res = new HashMap<>(); + try { + CSVReader c = new CSVReader(new FileReader(inputFilePath)); + List<String[]> lines = c.readAll(); + lines.removeFirst(); + for (String[] line : lines) { + if (Objects.equals(line[0], this.countryName)) { + res.put(line[1], Integer.parseInt(line[2])); + } + else if (Objects.equals(line[1], this.countryName)) { + res.put(line[0], Integer.parseInt(line[2])); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return res; + } +} diff --git a/graphs/java/travel/src/main/java/fr/epita/assistants/travel/Travel.java b/graphs/java/travel/src/main/java/fr/epita/assistants/travel/Travel.java new file mode 100644 index 0000000..9302e18 --- /dev/null +++ b/graphs/java/travel/src/main/java/fr/epita/assistants/travel/Travel.java @@ -0,0 +1,13 @@ +package fr.epita.assistants.travel; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +public class Travel { + public static void travelTo(Country source, Country destination) { + ZonedDateTime t1 = ZonedDateTime.now(source.countryZone); + ZonedDateTime t2 = ZonedDateTime.now(destination.countryZone).plusHours(source.travelTimes.get(destination.countryName)); + System.out.println("Boarding in " + source.countryName + ", local date and time is: " + t1.format(DateTimeFormatter.RFC_1123_DATE_TIME)); + System.out.println("Landing in " + destination.countryName + ", local date and time on arrival will be: " + t2.format(DateTimeFormatter.RFC_1123_DATE_TIME)); + } +} diff --git a/graphs/java/travel/src/main/resources/travel_times.csv b/graphs/java/travel/src/main/resources/travel_times.csv new file mode 100644 index 0000000..a6b720b --- /dev/null +++ b/graphs/java/travel/src/main/resources/travel_times.csv @@ -0,0 +1,29 @@ +source,destination,travel_time +France,Italy,1 +France,England,2 +France,Vietnam,12 +France,Chicago,9 +France,Brazil,12 +France,Egypt,4 +France,Australia,24 +Italy,England,3 +Italy,Vietnam,11 +Italy,Chicago,9 +Italy,Brazil,12 +Italy,Egypt,3 +Italy,Australia,17 +England,Vietnam,12 +England,Chicago,11 +England,Brazil,12 +England,Egypt,5 +England,Australia,21 +Vietnam,Chicago,21 +Vietnam,Brazil,21 +Vietnam,Egypt,17 +Vietnam,Australia,6 +Chicago,Brazil,13 +Chicago,Egypt,13 +Chicago,Australia,21 +Brazil,Egypt,17 +Brazil,Australia,21 +Egypt,Australia,19
\ No newline at end of file diff --git a/graphs/java/triad/flake.nix b/graphs/java/triad/flake.nix new file mode 100644 index 0000000..6bf8d07 --- /dev/null +++ b/graphs/java/triad/flake.nix @@ -0,0 +1,29 @@ +{ + description = "Java 2027"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils, ... }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { + inherit system; + }; + in + with pkgs; + { + devShell = mkShell { + buildInputs = [ + jdk21_headless + postgresql + quarkus + maven + nodejs_22 + ]; + }; + } + ); +} diff --git a/graphs/java/triad/pom.xml b/graphs/java/triad/pom.xml new file mode 100644 index 0000000..66ce68d --- /dev/null +++ b/graphs/java/triad/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>triad</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/triad/src/main/java/fr/epita/assistants/triad/FixMyMistake.java b/graphs/java/triad/src/main/java/fr/epita/assistants/triad/FixMyMistake.java new file mode 100644 index 0000000..b5fa908 --- /dev/null +++ b/graphs/java/triad/src/main/java/fr/epita/assistants/triad/FixMyMistake.java @@ -0,0 +1,9 @@ +package fr.epita.assistants.triad; + +public class FixMyMistake { + public static String myEasyFunction() { + // Place your cursor below on aMagicNumber and press Alt+Enter to fix the issue so that the method returns 43 + final String aMagicNumber = "43"; + return aMagicNumber; + } +} diff --git a/graphs/java/triad/src/main/java/fr/epita/assistants/triad/UglyClass.java b/graphs/java/triad/src/main/java/fr/epita/assistants/triad/UglyClass.java new file mode 100644 index 0000000..75b714d --- /dev/null +++ b/graphs/java/triad/src/main/java/fr/epita/assistants/triad/UglyClass.java @@ -0,0 +1,36 @@ +package fr.epita.assistants.triad; + +import java.util.List; +import java.util.function.Function; + +public class UglyClass { + public static List<WriteGettersAndConstructorForMe> getMyMessWithParameters() { + return myNotSoUsefulMethod(); + } + + private static List<WriteGettersAndConstructorForMe> myNotSoUsefulMethod() { + if (false) { + return List.of(); + } else + return List.of(new WriteGettersAndConstructorForMe("name", "firstName", "lastName", "random", "anotherOne" + , "anotherOne2", "anotherOne3", "xyz", 1, 2.0, 3.0f, true, false), + new WriteGettersAndConstructorForMe("name", "firstName", "lastName", "random", "anotherOne", + "anotherOne2", "anotherOne3", "xyz", 1, 2.0, 3.0f, true, false), + new WriteGettersAndConstructorForMe("name", "firstName", "lastName", "random", "anotherOne", + "anotherOne2", "anotherOne3", "xyz", 1, 2.0, 3.0f, true, false), + new WriteGettersAndConstructorForMe("name", "firstName", "lastName", "random", "anotherOne", + "anotherOne2", "anotherOne3", "xyz", 1, 2.0, 3.0f, true, false), + new WriteGettersAndConstructorForMe("name", "firstName", "lastName", "random", "anotherOne", + "anotherOne2", "anotherOne3", "xyz", 1, 2.0, 3.0f, true, false), + new WriteGettersAndConstructorForMe("name", "firstName", "lastName", "random", "anotherOne", + "anotherOne2", "anotherOne3", "xyz", 1, 2.0, 3.0f, true, false), + new WriteGettersAndConstructorForMe("name", "firstName", "lastName", "random", "anotherOne", + "anotherOne2", "anotherOne3", "xyz", 1, 2.0, 3.0f, true, false), + new WriteGettersAndConstructorForMe("name", "firstName", "lastName", "random", "anotherOne", + "anotherOne2", "anotherOne3", "xyz", 1, 2.0, 3.0f, true, false), + new WriteGettersAndConstructorForMe("name", "firstName", "lastName", "random", "anotherOne", + "anotherOne2", "anotherOne3", "xyz", 1, 2.0, 3.0f, true, false), + new WriteGettersAndConstructorForMe("name", "firstName", "lastName", "random", "anotherOne", + "anotherOne2", "anotherOne3", "xyz", 1, 2.0, 3.0f, true, false)).stream().filter(parameter -> parameter.getName().equals("name")).map(Function.identity()).toList(); + } +} diff --git a/graphs/java/triad/src/main/java/fr/epita/assistants/triad/WriteGettersAndConstructorForMe.java b/graphs/java/triad/src/main/java/fr/epita/assistants/triad/WriteGettersAndConstructorForMe.java new file mode 100644 index 0000000..794a8f6 --- /dev/null +++ b/graphs/java/triad/src/main/java/fr/epita/assistants/triad/WriteGettersAndConstructorForMe.java @@ -0,0 +1,98 @@ +package fr.epita.assistants.triad; + +public class WriteGettersAndConstructorForMe { + private final String name; + + public String getName() { + return name; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public String getRandom() { + return random; + } + + public String getAnotherOne() { + return anotherOne; + } + + public boolean isC() { + return c; + } + + public Boolean getB() { + return b; + } + + public float getZ() { + return z; + } + + public double getY() { + return y; + } + + public int getX() { + return x; + } + + public String getXyz() { + return xyz; + } + + public String getAnotherOne3() { + return anotherOne3; + } + + public String getAnotherOne2() { + return anotherOne2; + } + + public WriteGettersAndConstructorForMe(String name, String firstName, String lastName, String random, String anotherOne, String anotherOne2, String anotherOne3, String xyz, int x, double y, float z, Boolean b, boolean c) { + this.name = name; + this.firstName = firstName; + this.lastName = lastName; + this.random = random; + this.anotherOne = anotherOne; + this.anotherOne2 = anotherOne2; + this.anotherOne3 = anotherOne3; + this.xyz = xyz; + this.x = x; + this.y = y; + this.z = z; + this.b = b; + this.c = c; + } + + private final String firstName; + private final String lastName; + + private final String random; + + private final String anotherOne; + + private final String anotherOne2; + + private final String anotherOne3; + + private final String xyz; + + private final int x; + + private final double y; + + private final float z; + + private final Boolean b; + + private final boolean c; + + // FIXME: Add a constructor with all the parameters and all the getters +} diff --git a/graphs/java/war/.gitignore b/graphs/java/war/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/graphs/java/war/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store
\ No newline at end of file diff --git a/graphs/java/war/pom.xml b/graphs/java/war/pom.xml new file mode 100644 index 0000000..99cb248 --- /dev/null +++ b/graphs/java/war/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>fr.epita.assistants</groupId> + <artifactId>war</artifactId> + <version>1.0</version> + + <properties> + <versions.java>21</versions.java> + <versions.junit>5.9.1</versions.junit> + <versions.maven-compiler-plugin>3.13.0</versions.maven-compiler-plugin> + <versions.maven-surefire-plugin>3.5.0</versions.maven-surefire-plugin> + <versions.maven-jar-plugin>3.1.1</versions.maven-jar-plugin> + <versions.maven-install-plugin>3.1.0</versions.maven-install-plugin> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <surefire.reportsDirectory>${project.build.directory}/surefire-reports</surefire.reportsDirectory> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${versions.junit}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit-platform</artifactId> + <version>${versions.maven-surefire-plugin}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.9.8</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-monitor</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.24</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-filtering</artifactId> + <version>3.3.2</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-interpolation</artifactId> + <version>1.13</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-profile</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-registry</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-repository-metadata</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-commons</artifactId> + <version>1.9.3</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${versions.maven-compiler-plugin}</version> + <configuration> + <source>${versions.java}</source> + <target>${versions.java}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>${versions.maven-install-plugin}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <reportsDirectory>${surefire.reportsDirectory}</reportsDirectory> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/graphs/java/war/src/main/java/fr/epita/assistants/war/Assassin.java b/graphs/java/war/src/main/java/fr/epita/assistants/war/Assassin.java new file mode 100644 index 0000000..3415e41 --- /dev/null +++ b/graphs/java/war/src/main/java/fr/epita/assistants/war/Assassin.java @@ -0,0 +1,9 @@ +package fr.epita.assistants.war; + +public class Assassin extends Soldier{ + public Assassin() { + this.health = 10; + this.damage = 9; + this.scream = "Out of the shadows!"; + } +} diff --git a/graphs/java/war/src/main/java/fr/epita/assistants/war/Combatant.java b/graphs/java/war/src/main/java/fr/epita/assistants/war/Combatant.java new file mode 100644 index 0000000..5dc9af4 --- /dev/null +++ b/graphs/java/war/src/main/java/fr/epita/assistants/war/Combatant.java @@ -0,0 +1,12 @@ +package fr.epita.assistants.war; + +public abstract class Combatant { + void printState() + { + System.err.println("Error 404. Class not found."); + } + + abstract void attack(Soldier s); + abstract void attack(Vehicle v); + abstract void scream(); +} diff --git a/graphs/java/war/src/main/java/fr/epita/assistants/war/Knight.java b/graphs/java/war/src/main/java/fr/epita/assistants/war/Knight.java new file mode 100644 index 0000000..1258434 --- /dev/null +++ b/graphs/java/war/src/main/java/fr/epita/assistants/war/Knight.java @@ -0,0 +1,9 @@ +package fr.epita.assistants.war; + +public class Knight extends Soldier { + public Knight() { + this.health = 20; + this.damage = 5; + this.scream = "Be quick or be dead!"; + } +} diff --git a/graphs/java/war/src/main/java/fr/epita/assistants/war/Soldier.java b/graphs/java/war/src/main/java/fr/epita/assistants/war/Soldier.java new file mode 100644 index 0000000..67c3897 --- /dev/null +++ b/graphs/java/war/src/main/java/fr/epita/assistants/war/Soldier.java @@ -0,0 +1,38 @@ +package fr.epita.assistants.war; + +public class Soldier extends Combatant { + int health; + int damage; + String scream; + + public Soldier() { + this.health = 15; + this.damage = 3; + this.scream = "No pity for losers!"; + } + + public void kill(){ + this.health = 0; + } + + @Override + public void printState() + { + System.out.println("I have " + this.health + " health points."); + } + + @Override + public void attack(Soldier s) { + s.health -= this.damage; + } + + @Override + public void attack(Vehicle v) { + System.out.println("I can't fight this."); + } + + @Override + public void scream() { + System.out.println(this.scream); + } +} diff --git a/graphs/java/war/src/main/java/fr/epita/assistants/war/Vehicle.java b/graphs/java/war/src/main/java/fr/epita/assistants/war/Vehicle.java new file mode 100644 index 0000000..b27d072 --- /dev/null +++ b/graphs/java/war/src/main/java/fr/epita/assistants/war/Vehicle.java @@ -0,0 +1,32 @@ +package fr.epita.assistants.war; + +public class Vehicle extends Combatant{ + String name; + int defense; + + public Vehicle(String name, int defense) { + this.name = name; + this.defense = defense; + } + + @Override + public void printState() + { + System.out.println("I have " + this.defense + " defense points."); + } + + @Override + public void attack(Soldier s) { + s.kill(); + } + + @Override + public void attack(Vehicle v) { + v.defense /= 2; + } + + @Override + public void scream() { + System.out.println("I'm " + this.name + "!"); + } +} diff --git a/graphs/js/.gitignore b/graphs/js/.gitignore new file mode 100644 index 0000000..afb8184 --- /dev/null +++ b/graphs/js/.gitignore @@ -0,0 +1,54 @@ +*.tar +main.js +package.json +node_modules/ +yarn.lock +package-lock.json + +# IDEs and editors +.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Dependency directories +jspm_packages/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# System Files +.DS_Store +Thumbs.db + +# Lint and formatter +.prettierrc.js +eslint.config.mjs diff --git a/graphs/js/.prettierrc.cjs b/graphs/js/.prettierrc.cjs new file mode 100644 index 0000000..fcc77f6 --- /dev/null +++ b/graphs/js/.prettierrc.cjs @@ -0,0 +1,6 @@ +module.exports = { + tabWidth: 4, + useTabs: false, // Use spaces instead of defaults tabs + semi: true, // Force semilicons + printWidth: 80, // Max width +}; diff --git a/graphs/js/accountConstraints/account.js b/graphs/js/accountConstraints/account.js new file mode 100644 index 0000000..4a3ddbe --- /dev/null +++ b/graphs/js/accountConstraints/account.js @@ -0,0 +1,42 @@ +"use strict"; + +const { + InvalidUsernameError, + InvalidPasswordError, + InvalidYearOfBirthError, +} = require("./accountError"); + +class Account { + // FIXME DONE: A constructor was deleted here + constructor(username, password, yearOfBirth) { + const regUsername = /^[a-zA-Z0-9\-_]+$/; + const lower = /[a-z]/; + const upper = /[A-Z]/; + const digits = /[0-9]/; + + if (!regUsername.test(username)) { + throw new InvalidUsernameError("Invalid username."); + } + + this.username = username; + if ( + !password.match(lower) || + !password.match(upper) || + !password.match(digits) || + password.length < 8 || + password.length > 100 + ) { + throw new InvalidPasswordError("Invalid password."); + } + + this.password = password; + if (yearOfBirth <= 1800 || yearOfBirth > new Date().getFullYear()) { + throw new InvalidYearOfBirthError("Invalid birth year"); + } + + this.yearOfBirth = yearOfBirth; + } +} +module.exports = { + Account, +}; diff --git a/graphs/js/accountConstraints/accountError.js b/graphs/js/accountConstraints/accountError.js new file mode 100644 index 0000000..9b427e0 --- /dev/null +++ b/graphs/js/accountConstraints/accountError.js @@ -0,0 +1,23 @@ +class InvalidUsernameError extends Error { + name = "InvalidUsernameError"; + constructor(message) { + super("Invalid username: " + message); + } +} +class InvalidPasswordError extends Error { + name = "InvalidPasswordError"; + constructor(message) { + super("Invalid password: " + message); + } +} +class InvalidYearOfBirthError extends Error { + name = "InvalidYearOfBirthError"; + constructor(message) { + super("Invalid birth year: " + message); + } +} +module.exports = { + InvalidPasswordError, + InvalidUsernameError, + InvalidYearOfBirthError, +}; diff --git a/graphs/js/advancedCommunication/client.js b/graphs/js/advancedCommunication/client.js new file mode 100644 index 0000000..7c051a8 --- /dev/null +++ b/graphs/js/advancedCommunication/client.js @@ -0,0 +1,26 @@ +const WebSocket = require("ws"); + +function addClient(userName) { + const socket = new WebSocket("ws://localhost:8080?username=" + userName); + + socket.on("open", () => { + socket.send(userName + ": trying to establish connection"); + }); + socket.on("close", (code, reason) => { + console.log( + "<server to " + + userName + + ">: Connection has been closed: [" + + code + + "] " + + reason, + ); + }); + socket.on("message", (data) => { + console.log("<server to " + userName + ">: " + data); + }); + return socket; +} +module.exports = { + addClient, +}; diff --git a/graphs/js/advancedCommunication/server.js b/graphs/js/advancedCommunication/server.js new file mode 100644 index 0000000..e642396 --- /dev/null +++ b/graphs/js/advancedCommunication/server.js @@ -0,0 +1,88 @@ +const WebSocket = require("ws"); + +function startServer() { + const server = new WebSocket.Server({ port: 8080 }); + const connections = new Array(); + let maxID = 0; + + console.log("Websocket server is running on port 8080."); + server.on("connection", (socket, request) => { + const userName = request.url.substring(11); + + maxID++; + const current_connection = { + userName: userName, + id: maxID, + socket: socket, + }; + + socket.on("message", (data) => { + console.log("[" + current_connection.id + "] " + data); + }); + socket.on("close", (code, reason) => { + console.log( + "[" + + current_connection.id + + "] Disconnected: [" + + code + + "] " + + reason, + ); + if (code !== 1008) { + for (const conn of connections) { + if (conn.id !== current_connection.id) { + conn.socket.send(userName + " disconnected"); + } + } + + connections.splice(connections.indexOf(current_connection), 1); + } + }); + for (const conn of connections) { + if (conn.userName === userName) { + socket.close( + 1008, + 'Username: "' + userName + '" is already taken', + ); + return; + } + } + + socket.send("Welcome " + userName); + connections.push(current_connection); + if (connections.length === 1) { + socket.send(userName + ", you are the only player connected"); + } else { + socket.send(connections.length + " players are connected"); + } + + for (const conn of connections) { + if (conn.userName !== userName) { + conn.socket.send(userName + " connected"); + } + } + + if (connections.length < 4) { + for (const conn of connections) { + conn.socket.send( + "Waiting for " + + (4 - connections.length) + + " other players to start the game", + ); + } + } else { + for (const conn of connections) { + conn.socket.send( + "Match will start soon, disconnecting " + + conn.userName + + " from the lobby", + ); + conn.socket.close(1000, "Match is starting"); + } + } + }); + return server; +} +module.exports = { + startServer, +}; diff --git a/graphs/js/armstrongNumber/armstrongNumber.js b/graphs/js/armstrongNumber/armstrongNumber.js new file mode 100644 index 0000000..59da441 --- /dev/null +++ b/graphs/js/armstrongNumber/armstrongNumber.js @@ -0,0 +1,17 @@ +function armstrongNumber(number) { + if (number < 0 || number == null || number == undefined) { + return false; + } + + const ndigits = number.toString().length; + let sum = 0; + + for (let i = 0; i < ndigits; i++) { + sum = sum + number.toString()[i] ** ndigits; + } + + return sum === number; +} +module.exports = { + armstrongNumber, +}; diff --git a/graphs/js/coordinatesDisplay/coordinates.js b/graphs/js/coordinatesDisplay/coordinates.js new file mode 100644 index 0000000..845599f --- /dev/null +++ b/graphs/js/coordinatesDisplay/coordinates.js @@ -0,0 +1,123 @@ +/** + * Retrieves the width of the map. + * @returns {Promise<any>} A promise that resolves when the width is retrieved. + */ +const getMapWidth = async () => { + const res = await fetch("http://localhost:2707/mapWidth"); + + return res.json(); +}; + +/** + * Fetches the bit at the specified index from the server. + * @param {number} i - The index of the bit to fetch. + * @returns {Promise} - A promise that resolves with the fetched bit. + */ +const getMapPiece = async (i) => { + const res = await fetch(`http://localhost:2707/piece/${i}`); + + return res.json(); +}; + +/** + * Creates a grid element with the specified map width. + * @param {number} mapWidth - The width of the map. + */ + +function createGrid(mapWidth) { + const div = document.createElement("div"); + + div.id = "asyncGrid"; + div.style.display = "grid"; + div.style.gridTemplateColumns = `repeat(${mapWidth}, 1fr)`; + div.style.gridTemplateRows = `repeat(${mapWidth}, 1fr)`; + div.style.width = "fit-content"; + div.style.height = "fit-content"; + document.body.appendChild(div); +} + +/** + * Displays an SVG element asynchronously at the specified coordinates. + * + * @param {string} svg - The SVG element to be displayed. + * @param {number} x - The x-coordinate of the grid cell where the SVG element will be displayed. + * @param {number} y - The y-coordinate of the grid cell where the SVG element will be displayed. + */ +async function displayPiece(svg, x, y) { + const svgElement = document.createElement("div"); + + svgElement.innerHTML = svg; + + const width = svgElement.lastChild.getAttribute("width"); + const height = svgElement.lastChild.getAttribute("height"); + + svgElement.style.width = `${width}px`; + svgElement.style.height = `${height}px`; + svgElement.style.gridColumn = x + 1; + svgElement.style.gridRow = y + 1; + svgElement.style.padding = 0; + svgElement.style.margin = 0; + document.getElementById("asyncGrid").appendChild(svgElement); +} + +async function displayMap() { + // FIXME ! + + const startTime = Date.now(); + const width = await getMapWidth(); + + createGrid(width); + const promises = new Array(); + + for (let i = 0; i < width * width; i++) { + promises.push( + getMapPiece(i).then(async (piece) => { + await displayPiece(piece.svg, piece.x, piece.y); + }), + ); + } + + await Promise.all(promises); + return Date.now() - startTime; + /*return new Promise((resolve, reject) => { + resolve(getMapWidth); + }) + .then((width) => { + createGrid(width); + let promises = new Array(); + for (let i = 0; i < width * width; i++) { + promises.push( + new Promise((resolve) => { + resolve(getMapPiece(i)); + }).then((piece) => { + displayPiece(piece.svg, piece.x, piece.y); + }), + ); + } + Promise.all(promises); + return Date.now() - startTime; + }) + .catch((error) => error);*/ + // don't forget you can use above functions to help you and also make your own +} + +// Your code goes here, the html page will load your script and launch it +// Catch errors if you push your testing code so the Moulinette doesn't fail +displayMap() + .then((time) => { + console.log("displayed in " + time + " ms."); + }) + .catch((error) => { + console.error(error); + }); + +// As always, we need to export the displayMap function for the tests. +// To avoid errors in browsers (where "module" is not defined), +// we wrap the exports inside a conditional check to ensure they +// are only assigned when the code is running in a Node.js environment. + +if (typeof window === "undefined") { + module.exports = { + displayMap, + }; +} diff --git a/graphs/js/coordinatesDisplay/index.html b/graphs/js/coordinatesDisplay/index.html new file mode 100644 index 0000000..d2bf830 --- /dev/null +++ b/graphs/js/coordinatesDisplay/index.html @@ -0,0 +1,20 @@ +<!DOCTYPE html>
+<html>
+<head>
+ <title>Async Display</title>
+ <meta charset="utf-8" />
+ <style type="text/css">
+ #asyncGrid {
+ width: 100px;
+ height: 100px;
+ border: 1px solid black;
+ position: absolute;
+ top: calc(50% - 250px);
+ left: calc(50% - 250px);
+ }
+ </style>
+</head>
+<body>
+ <script type="text/javascript" src="coordinates.js"></script>
+</body>
+</html>
diff --git a/graphs/js/coordinatesDisplay/resources/logo.svg b/graphs/js/coordinatesDisplay/resources/logo.svg new file mode 100755 index 0000000..14ac718 --- /dev/null +++ b/graphs/js/coordinatesDisplay/resources/logo.svg @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<svg width="500" height="500" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" version="1.1" xml:space="preserve"> + <defs id="defs1"> + <rect height="282.09" id="rect1495" width="465.07" x="1074" y="960"/> + <rect height="98.99" id="rect1494" width="995.61" x="-531.74" y="1004.09"/> + <rect height="45.25" id="rect1493" width="135.76" x="1216.22" y="873.98"/> + <rect height="85" id="rect26" width="124" x="366" y="794"/> + <rect height="88" id="rect23" width="455" x="137" y="792"/> + <rect height="105" id="rect22" width="490" x="98" y="816"/> + <rect height="217.05" id="rect2" width="774.19" x="200.65" y="788.82"/> + <clipPath clipPathUnits="userSpaceOnUse" id="clipPath56"> + <g id="use56"/> + </clipPath> + <mask id="mask56" maskUnits="userSpaceOnUse"> + <rect fill="#a72424" height="26.46" id="rect56" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31" width="44.08" x="45.01" y="246.55"/> + </mask> + <clipPath clipPathUnits="userSpaceOnUse" id="clipPath67"> + <g id="use67"> + <rect fill="#a72424" height="38.1" id="rect67" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31" width="44.08" x="31.12" y="258.72"/> + <rect fill="#a72424" height="37.31" id="rect68" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31" width="42.75" x="52.76" y="242.31"/> + <rect fill="#a72424" height="22.82" id="rect69" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31" width="48.36" x="64.4" y="264.54"/> + </g> + </clipPath> + <rect height="217.05" id="rect1489" width="774.19" x="200.65" y="788.82"/> + <rect height="217.05" id="rect1490" width="774.19" x="200.65" y="788.82"/> + <rect height="217.05" id="rect1491" width="774.19" x="200.65" y="788.82"/> + </defs> + <g class="layer" display="inline"> + <title>Layer 1</title> + <g display="none" id="layer1"> + <rect display="none" fill="#000000" height="210.01" id="rect46" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.3" width="171.45" x="20.33" y="28.36"/> + <path d="m352.32,70.27l0.15,-3.44l1.05,0c0.64,0 1.05,0.12 1.04,0.32c-0.01,0.24 0.06,0.24 0.31,0c0.58,-0.56 2.04,-0.38 2.71,0.33c0.91,0.94 0.8,3.06 -0.19,4.03c-0.61,0.58 -0.88,0.66 -1.87,0.55l-1.16,-0.13l-0.04,0.89c-0.03,0.87 -0.06,0.89 -1.09,0.9l-1.05,0l0.14,-3.45zm3.38,-0.05c0.78,-0.76 0.02,-2.2 -0.81,-1.54c-0.22,0.18 -0.42,0.53 -0.43,0.78c-0.01,0.43 0.43,1.08 0.75,1.08c0.09,0 0.3,-0.15 0.49,-0.32zm-127.06,1.76c-1.2,-0.53 -1.71,-2.47 -0.98,-3.74c1.05,-1.83 4.97,-1.71 5.67,0.17c0.6,1.6 0.51,1.69 -1.68,1.69c-1.08,0.01 -1.97,0.11 -1.98,0.24c-0.02,0.41 0.78,0.57 1.33,0.28c0.54,-0.28 2.35,-0.08 2.33,0.27c0,0.1 -0.26,0.41 -0.56,0.68c-0.63,0.55 -3.21,0.81 -4.13,0.41zm2.39,-3.34c-0.22,-0.23 -0.58,-0.33 -0.84,-0.24c-0.74,0.28 -0.52,0.65 0.38,0.65c0.76,0 0.81,-0.05 0.46,-0.41zm3.44,1.13c-0.55,-1.35 -0.99,-2.54 -0.99,-2.65c0.01,-0.11 0.53,-0.19 1.17,-0.2c1.14,0 1.15,0.02 1.43,1.2c0.15,0.65 0.36,1.19 0.45,1.19c0.1,0 0.37,-0.51 0.61,-1.13c0.41,-1.06 0.49,-1.13 1.55,-1.21c0.62,-0.04 1.12,0.02 1.12,0.13c-0.01,0.12 -0.56,1.32 -1.23,2.67c-1.2,2.43 -1.22,2.45 -2.17,2.45c-0.94,0 -0.96,-0.01 -1.94,-2.45zm6.15,2.06c-0.79,-0.46 -1.29,-1.9 -1.01,-2.87c0.1,-0.37 0.5,-0.94 0.87,-1.29c0.58,-0.52 0.96,-0.62 2.4,-0.62c1.55,0 1.77,0.07 2.32,0.74c0.34,0.42 0.59,1.08 0.57,1.52l-0.03,0.78l-2.03,0.01c-1.93,0 -2.01,0.02 -1.6,0.46c0.36,0.38 0.53,0.4 0.97,0.12c0.35,-0.21 0.93,-0.26 1.61,-0.15l1.07,0.17l-0.7,0.67c-0.87,0.84 -3.34,1.1 -4.44,0.46zm2.8,-3.03c0.02,-0.46 -0.86,-0.58 -1.28,-0.17c-0.38,0.37 -0.34,0.41 0.42,0.41c0.47,0 0.86,-0.11 0.86,-0.24zm3.13,0.76l0.11,-2.64l0.9,-0.01c0.5,0 0.98,0.12 1.06,0.27c0.1,0.18 0.32,0.18 0.66,0c0.73,-0.39 1.65,-0.33 2.3,0.14c0.51,0.37 0.56,0.64 0.48,2.65l-0.09,2.24l-1.04,0l-1.05,0l-0.01,-1.66c0,-1.45 -0.07,-1.65 -0.53,-1.65c-0.46,0 -0.55,0.2 -0.67,1.66l-0.15,1.65l-1.04,0l-1.04,0l0.11,-2.65zm10.32,0.46c-0.42,-1.2 -0.83,-2.4 -0.91,-2.67c-0.14,-0.42 -0.03,-0.47 0.98,-0.39c1.07,0.07 1.16,0.14 1.38,1.05c0.33,1.42 0.5,1.44 0.98,0.17c0.4,-1.08 0.48,-1.14 1.42,-1.14c0.94,0 1.02,0.07 1.42,1.19c0.41,1.16 0.43,1.17 0.7,0.53c0.16,-0.37 0.34,-0.9 0.41,-1.2c0.09,-0.41 0.37,-0.54 1.27,-0.61c1.02,-0.07 1.14,-0.03 0.96,0.4c-0.11,0.26 -0.61,1.46 -1.13,2.66c-0.93,2.18 -0.94,2.19 -1.9,2.19c-0.91,0 -0.98,-0.06 -1.38,-1.33l-0.41,-1.32l-0.55,1.32c-0.52,1.27 -0.6,1.33 -1.52,1.33l-0.97,0l-0.75,-2.18zm9.19,-1.27l0.14,-3.44l1.05,0l1.06,0l-0.05,1.07c-0.04,0.97 0,1.04 0.48,0.79c0.81,-0.43 2.01,-0.32 2.47,0.21c0.31,0.37 0.39,1.01 0.32,2.65l-0.09,2.16l-1.05,0l-1.05,0l0.06,-1.59c0.05,-1.22 -0.03,-1.64 -0.35,-1.76c-0.59,-0.24 -0.9,0.38 -0.97,1.96l-0.06,1.39l-1.05,0.01l-1.05,0l0.14,-3.45zm7.59,3.19c-1.78,-0.78 -1.73,-3.72 0.08,-4.64c1.8,-0.92 4.22,-0.29 4.68,1.21c0.46,1.51 0.41,1.56 -1.75,1.56c-1.08,0 -1.98,0.11 -1.98,0.24c-0.02,0.4 0.78,0.57 1.33,0.28c0.54,-0.29 2.35,-0.08 2.33,0.26c0,0.11 -0.26,0.41 -0.56,0.68c-0.63,0.56 -3.21,0.81 -4.13,0.41zm2.39,-3.34c-0.22,-0.23 -0.59,-0.33 -0.84,-0.23c-0.74,0.28 -0.53,0.64 0.38,0.64c0.76,0 0.81,-0.04 0.46,-0.41zm3.15,0.94l0.1,-2.65l1.06,0c0.58,0 1.05,0.12 1.04,0.27c-0.01,0.19 0.15,0.19 0.51,0c0.84,-0.44 2.09,-0.32 2.64,0.25c0.42,0.45 0.49,0.89 0.41,2.65l-0.08,2.12l-1.19,0l-1.18,0l0.07,-1.72c0.06,-1.54 0.02,-1.72 -0.46,-1.72c-0.47,0 -0.53,0.18 -0.59,1.72l-0.08,1.72l-1.18,0l-1.18,0.01l0.11,-2.65zm10,-0.01l0.11,-2.65l1.18,0l1.19,0l-0.11,2.65l-0.11,2.65l-1.19,0l-1.18,0l0.11,-2.65zm4.13,2.13c-0.38,-0.4 -0.5,-0.89 -0.46,-1.87c0.04,-1 -0.04,-1.32 -0.34,-1.32c-0.26,0 -0.38,-0.27 -0.36,-0.8c0.02,-0.53 0.16,-0.79 0.43,-0.79c0.21,0 0.4,-0.16 0.41,-0.35c0.01,-0.33 1.6,-1.24 2.16,-1.24c0.14,0 0.24,0.35 0.22,0.79c-0.02,0.62 0.09,0.8 0.5,0.8c0.41,0 0.52,0.17 0.49,0.79c-0.03,0.62 -0.15,0.79 -0.56,0.79c-0.44,0.01 -0.53,0.18 -0.57,1.06c-0.04,0.9 0.04,1.06 0.5,1.06c0.44,0 0.52,0.14 0.43,0.73c-0.1,0.65 -0.23,0.74 -1.22,0.81c-0.84,0.06 -1.23,-0.05 -1.63,-0.46zm7.43,0.19c-0.61,-0.3 -0.92,-0.91 -0.67,-1.29c0.22,-0.33 1.9,-0.31 2.09,0.02c0.19,0.33 1.17,0.35 1.19,0.03c0,-0.13 -0.44,-0.32 -0.97,-0.42c-1.58,-0.29 -2.19,-0.83 -2.05,-1.81c0.14,-1.03 0.97,-1.5 2.67,-1.51c0.84,0 1.43,0.17 1.89,0.55c1.1,0.9 0.83,1.13 -1.12,0.96c-1.81,-0.15 -1.65,0.16 0.24,0.47c1.79,0.3 2.16,2.13 0.58,2.93c-0.87,0.44 -3.01,0.48 -3.85,0.07zm6.53,-0.04c-1.8,-1.07 -1.52,-3.97 0.46,-4.65c2.51,-0.87 4.7,0.25 4.61,2.37c-0.02,0.46 -0.22,0.51 -2.05,0.51c-1.93,0 -2.01,0.03 -1.6,0.46c0.37,0.38 0.53,0.4 0.98,0.13c0.34,-0.21 0.92,-0.27 1.6,-0.16l1.07,0.18l-0.7,0.67c-0.55,0.53 -1.01,0.69 -2.22,0.76c-0.98,0.06 -1.76,-0.04 -2.15,-0.27zm2.73,-3.06c0.02,-0.46 -0.86,-0.58 -1.28,-0.17c-0.38,0.36 -0.33,0.4 0.43,0.4c0.46,0 0.85,-0.1 0.85,-0.23zm4.21,3.17c-1.6,-0.71 -1.93,-2.98 -0.62,-4.24c0.62,-0.6 0.93,-0.69 2.44,-0.69c1.56,0 1.78,0.07 2.33,0.74c0.34,0.42 0.59,1.08 0.57,1.53l-0.03,0.78l-2.03,0c-1.93,0 -2.01,0.02 -1.6,0.46c0.37,0.38 0.53,0.4 0.98,0.13c0.34,-0.21 0.92,-0.27 1.6,-0.16l1.07,0.17l-0.69,0.67c-0.53,0.51 -1.02,0.69 -2.1,0.75c-0.77,0.05 -1.63,-0.01 -1.92,-0.14zm2.37,-3.22c0.02,-0.49 -0.79,-0.6 -1.25,-0.15c-0.42,0.4 -0.39,0.43 0.4,0.43c0.46,0 0.85,-0.13 0.85,-0.28zm3.13,0.81l0.11,-2.65l1.05,0c0.58,0 1.05,0.1 1.04,0.24c0,0.13 0.36,0.1 0.8,-0.06c0.6,-0.23 1,-0.22 1.61,0.01c0.54,0.21 0.97,0.23 1.3,0.06c0.8,-0.43 2.06,-0.3 2.6,0.27c0.42,0.44 0.49,0.88 0.42,2.66l-0.09,2.14l-1.12,-0.08l-1.11,-0.08l-0.01,-1.68c-0.01,-1.4 -0.08,-1.65 -0.46,-1.58c-0.36,0.07 -0.49,0.43 -0.6,1.74l-0.15,1.65l-1.03,0l-1.02,0l-0.01,-1.65c-0.01,-1.46 -0.08,-1.66 -0.54,-1.66c-0.46,0 -0.54,0.2 -0.67,1.66l-0.15,1.65l-1.04,0l-1.04,0l0.11,-2.64zm10.51,2.37c-0.61,-0.25 -1.17,-1.15 -0.89,-1.42c0.28,-0.27 2.15,-0.19 2.31,0.09c0.19,0.34 1.17,0.35 1.18,0.03c0.01,-0.14 -0.49,-0.33 -1.1,-0.42c-1.46,-0.24 -2.27,-0.8 -2.24,-1.54c0.05,-1.15 0.67,-1.59 2.34,-1.7c1.72,-0.11 2.79,0.3 2.91,1.1c0.07,0.46 -0.05,0.48 -1.59,0.33c-1.12,-0.12 -1.54,-0.09 -1.28,0.08c0.21,0.15 0.65,0.26 0.96,0.27c1.52,0.01 2.59,1.33 1.91,2.36c-0.65,0.97 -3.06,1.41 -4.51,0.82zm8.97,-2.39l0.11,-2.65l1.05,0l1.05,0l-0.11,2.65l-0.11,2.65l-1.05,0l-1.05,0l0.11,-2.65zm3.16,0l0.1,-2.65l1.06,0c0.58,0 1.05,0.11 1.04,0.24c-0.01,0.13 0.35,0.11 0.79,-0.06c0.6,-0.22 1.01,-0.22 1.7,0.04c0.65,0.24 1.05,0.25 1.43,0.05c0.83,-0.43 1.83,-0.33 2.39,0.25c0.42,0.44 0.49,0.88 0.41,2.65l-0.09,2.12l-1.04,0l-1.04,0l-0.01,-1.66c0,-1.45 -0.07,-1.65 -0.53,-1.65c-0.46,0 -0.55,0.2 -0.68,1.66l-0.14,1.65l-1.04,0l-1.04,0l0.06,-1.6c0.05,-1.19 -0.03,-1.63 -0.33,-1.75c-0.6,-0.23 -0.74,0.03 -0.93,1.77l-0.18,1.58l-1.02,0l-1.02,0l0.11,-2.64zm17.66,2.28c-1.98,-0.92 -1.66,-3.98 0.49,-4.69c1.35,-0.44 2.95,-0.17 3.71,0.62c0.88,0.93 0.8,2.62 -0.16,3.55c-0.85,0.82 -2.84,1.07 -4.04,0.52zm2.48,-1.92c0.24,-0.81 -0.35,-1.6 -1,-1.35c-0.42,0.16 -0.65,1.5 -0.32,1.85c0.4,0.43 1.14,0.15 1.32,-0.5zm3.3,1.65c-0.4,-0.36 -0.6,-0.75 -0.49,-0.93c0.25,-0.37 2.28,-0.42 2.27,-0.04c-0.01,0.14 0.23,0.26 0.51,0.26c0.91,0 0.6,-0.46 -0.43,-0.65c-1.57,-0.29 -2.18,-0.83 -2.05,-1.81c0.15,-1.03 0.98,-1.5 2.68,-1.51c0.83,0 1.42,0.17 1.88,0.55c1.08,0.87 0.84,1.13 -0.92,0.97c-0.91,-0.09 -1.52,-0.05 -1.44,0.09c0.08,0.13 0.5,0.24 0.93,0.24c1.46,0 2.5,1.05 2.11,2.13c-0.48,1.35 -3.81,1.81 -5.05,0.7zm6.58,0.36c-0.7,-0.29 -1.22,-0.98 -0.99,-1.33c0.23,-0.35 2.26,-0.36 2.24,-0.01c0,0.15 0.23,0.27 0.52,0.27c0.9,-0.01 0.59,-0.47 -0.44,-0.66c-1.45,-0.27 -2.13,-0.82 -2.1,-1.7c0.04,-0.98 0.58,-1.38 2.03,-1.55c1.39,-0.16 2.32,0.04 2.86,0.61c0.75,0.78 0.45,0.99 -1.2,0.84c-0.91,-0.08 -1.51,-0.04 -1.43,0.1c0.07,0.13 0.53,0.24 1.03,0.24c0.56,0 1.15,0.23 1.59,0.63c0.62,0.56 0.67,0.73 0.42,1.38c-0.16,0.42 -0.6,0.9 -0.96,1.09c-0.75,0.37 -2.76,0.42 -3.57,0.09zm5.51,-2.4l0.11,-2.65l1.05,0l1.05,0l-0.11,2.65l-0.11,2.65l-1.05,0l-1.05,0l0.11,-2.65zm3.19,-0.8l0.14,-3.44l1.19,0c1.17,0 1.18,0.01 1.14,0.9c-0.03,0.89 -0.02,0.9 0.98,0.76c0.81,-0.11 1.15,-0.01 1.73,0.52c0.6,0.53 0.71,0.85 0.67,1.86c-0.08,2.12 -1.46,3.28 -3.14,2.64c-0.41,-0.16 -0.73,-0.18 -0.74,-0.04c0,0.13 -0.48,0.24 -1.06,0.24l-1.05,0l0.14,-3.44zm3.31,1.53c0.41,-0.39 0.45,-1.07 0.08,-1.46c-0.45,-0.47 -1.02,-0.08 -1.05,0.71c-0.05,1.06 0.34,1.36 0.97,0.75zm3.27,-1.53l0.14,-3.45l1.19,0l1.18,0l-0.14,3.44l-0.14,3.45l-1.19,0l-1.18,0l0.14,-3.44zm4.44,3.17c-1.2,-0.49 -1.72,-2.44 -0.99,-3.72c0.65,-1.13 2.76,-1.63 4.41,-1.04c0.86,0.3 1.24,0.83 1.45,2.05l0.15,0.85l-1.99,0c-1.2,0.01 -2,0.12 -2.01,0.28c-0.02,0.43 0.68,0.59 1.25,0.29c0.58,-0.31 2.43,-0.1 2.41,0.27c0,0.12 -0.4,0.47 -0.88,0.76c-0.93,0.55 -2.79,0.68 -3.8,0.26zm2.38,-3.32c-0.22,-0.23 -0.58,-0.33 -0.84,-0.24c-0.73,0.28 -0.52,0.65 0.38,0.65c0.76,0 0.81,-0.05 0.46,-0.41zm-105.15,-2.56c0.03,-0.6 0.13,-0.66 1.22,-0.66c1.08,0 1.18,0.05 1.15,0.66c-0.02,0.61 -0.12,0.66 -1.21,0.67c-1.09,0 -1.18,-0.06 -1.16,-0.67zm50.01,-0.04c0.03,-0.59 0.14,-0.66 1.08,-0.66c0.95,0 1.05,0.07 1.03,0.66c-0.02,0.6 -0.13,0.67 -1.08,0.67c-0.95,0 -1.05,-0.07 -1.03,-0.67zm38.7,-0.03c0.02,-0.59 0.13,-0.66 1.08,-0.66c0.94,0 1.05,0.07 1.02,0.66c-0.02,0.6 -0.13,0.66 -1.08,0.67c-0.95,0 -1.05,-0.07 -1.02,-0.67zm-131.37,-7.17c-0.39,-0.31 -0.69,-0.82 -0.68,-1.12c0.02,-0.49 0.13,-0.52 1.13,-0.36c0.61,0.1 1.22,0.29 1.34,0.42c0.31,0.32 1.22,-0.18 1.24,-0.69c0.01,-0.31 -0.1,-0.33 -0.5,-0.12c-0.87,0.46 -1.86,0.31 -2.52,-0.37c-0.49,-0.52 -0.61,-0.92 -0.56,-1.97c0.04,-1.12 0.16,-1.4 0.8,-1.89c0.56,-0.43 0.96,-0.53 1.66,-0.42c0.5,0.09 1.48,0.15 2.17,0.14l1.25,-0.01l-0.12,2.76c-0.14,3.57 -0.4,3.94 -2.83,4.1c-1.43,0.09 -1.79,0.02 -2.38,-0.47zm2.95,-3.78c0.24,-0.35 0.21,-0.56 -0.13,-0.91c-0.4,-0.42 -0.47,-0.43 -0.88,-0.04c-0.28,0.28 -0.38,0.63 -0.28,1c0.18,0.66 0.83,0.64 1.29,-0.05zm91.85,4.06c-0.71,-0.3 -1.27,-0.96 -1.25,-1.49c0.02,-0.47 0.14,-0.51 1.12,-0.35c0.6,0.1 1.25,0.31 1.43,0.46c0.39,0.34 1.13,-0.14 1.16,-0.74c0.01,-0.3 -0.1,-0.32 -0.55,-0.08c-0.79,0.41 -2.25,0.08 -2.7,-0.61c-0.62,-0.95 -0.41,-2.75 0.41,-3.55c0.59,-0.56 0.86,-0.65 1.67,-0.52c0.53,0.09 1.53,0.16 2.22,0.15l1.25,-0.01l-0.12,2.88c-0.11,2.57 -0.18,2.94 -0.68,3.37c-0.57,0.5 -3.15,0.82 -3.96,0.49zm2.38,-4.13c0.23,-0.35 0.21,-0.56 -0.13,-0.92c-0.4,-0.42 -0.48,-0.42 -0.88,-0.03c-0.29,0.28 -0.38,0.62 -0.28,1c0.18,0.66 0.83,0.63 1.29,-0.05zm25.08,4.03c-0.55,-0.25 -1.09,-1.04 -1.07,-1.59c0.02,-0.41 1.35,-0.34 2.2,0.12c0.8,0.42 1.48,0.17 1.51,-0.56c0.01,-0.29 -0.13,-0.3 -0.64,-0.07c-0.8,0.36 -1.84,0.12 -2.5,-0.57c-0.77,-0.81 -0.61,-2.73 0.31,-3.62c0.63,-0.61 0.84,-0.66 2.06,-0.52c0.74,0.09 1.74,0.17 2.21,0.17l0.85,0l-0.12,2.87c-0.1,2.55 -0.18,2.93 -0.67,3.36c-0.64,0.56 -3.21,0.81 -4.14,0.41zm2.6,-4.02c0.28,-0.79 -0.42,-1.52 -1.01,-1.04c-0.51,0.41 -0.56,0.85 -0.15,1.28c0.46,0.48 0.93,0.38 1.16,-0.24zm-149.34,-0.87l0.14,-3.48l2.72,-0.01c2.31,0 2.79,0.08 3.14,0.49c0.46,0.53 0.51,2.03 0.08,2.29c-0.16,0.1 -0.06,0.46 0.24,0.9c0.36,0.51 0.45,0.94 0.31,1.42c-0.37,1.3 -0.98,1.57 -3.99,1.72l-2.79,0.15l0.15,-3.48zm4.03,1.01c0.01,-0.25 -0.29,-0.42 -0.83,-0.47c-0.72,-0.07 -0.86,0 -0.88,0.48c-0.02,0.47 0.11,0.55 0.84,0.48c0.55,-0.06 0.86,-0.23 0.87,-0.49zm-0.02,-2.51c0.01,-0.27 -0.25,-0.4 -0.78,-0.4c-0.52,0 -0.79,0.14 -0.8,0.4c-0.01,0.27 0.24,0.4 0.77,0.4c0.53,0 0.8,-0.14 0.81,-0.4zm4.05,4.21c-0.67,-0.59 -0.77,-0.86 -0.73,-1.94c0.05,-1.01 0.2,-1.38 0.76,-1.9c0.6,-0.54 0.97,-0.64 2.42,-0.64c1.55,0 1.77,0.07 2.32,0.74c0.34,0.42 0.59,1.08 0.57,1.52l-0.03,0.78l-2.03,0c-1.93,0.01 -2.01,0.03 -1.6,0.46c0.37,0.38 0.53,0.41 0.98,0.13c0.73,-0.45 2.65,-0.15 2.42,0.38c-0.26,0.63 -1.61,1.15 -2.99,1.15c-1.02,0 -1.47,-0.14 -2.09,-0.68zm2.99,-2.77c0.02,-0.5 -0.79,-0.6 -1.25,-0.16c-0.42,0.4 -0.39,0.44 0.4,0.44c0.46,0 0.85,-0.13 0.85,-0.28zm3.12,0.93l0.11,-2.51l1.18,0l1.19,0l-0.11,2.51l-0.1,2.52l-1.19,0l-1.18,0l0.1,-2.52zm3.16,-0.01l0.11,-2.53l1.38,0.02c0.76,0.01 1.81,-0.06 2.35,-0.15c0.77,-0.13 1.07,-0.05 1.49,0.39c0.45,0.47 0.52,0.88 0.45,2.67l-0.09,2.12l-1.05,0l-1.06,0l0.06,-1.39c0.06,-1.58 -0.2,-2.2 -0.81,-1.96c-0.33,0.12 -0.45,0.54 -0.5,1.76l-0.06,1.6l-1.19,0l-1.18,0l0.1,-2.53zm16.95,2.23c-0.53,-0.32 -0.55,-1.89 -0.03,-2.3c0.18,-0.15 1.04,-0.42 1.89,-0.59c1.16,-0.24 1.48,-0.4 1.27,-0.62c-0.21,-0.22 -0.42,-0.22 -0.82,0.03c-0.73,0.45 -2.64,0.43 -2.62,-0.03c0.04,-1.15 3.12,-1.94 4.79,-1.24c0.86,0.36 0.94,0.62 1,3.24l0.04,1.79l-1.02,0c-0.56,0 -1.02,-0.11 -1.01,-0.26c0.01,-0.16 -0.23,-0.16 -0.68,0c-0.88,0.34 -2.23,0.32 -2.81,-0.02zm2.97,-1.36c0.56,-0.55 0.37,-0.73 -0.46,-0.44c-0.44,0.16 -0.8,0.39 -0.81,0.52c-0.01,0.35 0.88,0.29 1.27,-0.08zm6.7,-1.81l0.15,-3.44l1.18,0c1.18,0 1.19,0.01 1.15,0.92l-0.04,0.92l1.16,-0.16c0.96,-0.13 1.25,-0.06 1.69,0.4c0.46,0.48 0.52,0.88 0.45,2.68l-0.09,2.12l-1.18,0l-1.19,0l0.08,-1.74c0.06,-1.51 0.01,-1.73 -0.4,-1.65c-0.37,0.07 -0.49,0.42 -0.61,1.74l-0.14,1.65l-1.18,0.01l-1.17,0l0.14,-3.45zm7.28,2.76c-0.67,-0.59 -0.77,-0.87 -0.73,-1.94c0.04,-1.01 0.19,-1.39 0.76,-1.9c0.6,-0.55 0.97,-0.64 2.42,-0.65c1.55,0 1.77,0.07 2.31,0.75c0.35,0.42 0.59,1.08 0.58,1.52l-0.04,0.78l-2.03,0c-1.92,0 -2,0.03 -1.59,0.46c0.36,0.38 0.53,0.4 0.97,0.13c0.73,-0.45 2.65,-0.15 2.43,0.38c-0.27,0.63 -1.61,1.15 -2.99,1.15c-1.02,0 -1.48,-0.15 -2.09,-0.68zm2.93,-2.83c-0.06,-0.18 -0.32,-0.33 -0.58,-0.33c-0.27,0 -0.54,0.15 -0.61,0.33c-0.08,0.21 0.14,0.33 0.58,0.33c0.44,0 0.67,-0.12 0.61,-0.33zm3.18,1.03l0.1,-2.48l1.91,-0.16c1.07,-0.09 2.02,-0.05 2.15,0.08c0.38,0.4 -0.35,1.59 -0.96,1.59c-0.65,0 -1.09,0.92 -1.16,2.4c-0.04,1.04 -0.04,1.04 -1.09,1.04l-1.05,0.01l0.1,-2.48zm5.8,2.23c-0.82,-0.37 -1.62,-1.59 -1.58,-2.44c0.05,-1.21 1.32,-2.37 2.77,-2.54c2.97,-0.34 4.61,2.17 2.74,4.19c-0.63,0.68 -1.02,0.85 -2.08,0.93c-0.72,0.05 -1.55,-0.01 -1.85,-0.14zm2.23,-2.41c0.04,-0.81 -0.04,-0.93 -0.62,-0.93c-0.48,0.01 -0.68,0.16 -0.77,0.62c-0.17,0.95 0.09,1.42 0.76,1.32c0.49,-0.07 0.6,-0.25 0.63,-1.01zm6.45,0.12l0.1,-2.53l1.25,0.01c0.69,0 1.7,-0.06 2.26,-0.15c0.71,-0.12 1.13,-0.05 1.43,0.24c0.38,0.35 0.5,0.36 0.96,0.03c0.69,-0.49 1.75,-0.48 2.46,0.03c0.51,0.37 0.56,0.64 0.47,2.65l-0.09,2.24l-1.05,0l-1.05,0l0.06,-1.6c0.05,-1.19 -0.03,-1.63 -0.33,-1.75c-0.6,-0.24 -0.74,0.03 -0.93,1.77l-0.18,1.58l-1.03,0l-1.02,0l0.07,-1.72c0.07,-1.54 0.02,-1.72 -0.45,-1.72c-0.47,0 -0.53,0.18 -0.6,1.72l-0.07,1.72l-1.18,0l-1.19,0l0.11,-2.52zm11.05,2.27c-1.2,-0.53 -1.71,-2.47 -0.98,-3.74c0.82,-1.44 3.98,-1.74 5.14,-0.49c0.32,0.35 0.65,1.02 0.72,1.49l0.15,0.86l-2.02,0.01c-1.5,0 -1.99,0.08 -1.92,0.33c0.06,0.18 0.39,0.29 0.74,0.24c0.94,-0.13 2.67,-0.07 2.82,0.09c0.08,0.08 -0.12,0.4 -0.45,0.71c-0.66,0.64 -3.19,0.94 -4.2,0.5zm2.39,-3.34c-0.22,-0.23 -0.59,-0.33 -0.84,-0.24c-0.74,0.28 -0.53,0.65 0.38,0.65c0.76,0 0.8,-0.05 0.46,-0.41zm3.32,3.05c-1.1,-1.15 -0.39,-2.19 1.82,-2.65c0.8,-0.17 1.46,-0.43 1.47,-0.58c0.01,-0.17 -0.22,-0.2 -0.59,-0.08c-0.33,0.11 -1.1,0.25 -1.72,0.32c-0.89,0.1 -1.12,0.05 -1.11,-0.27c0.04,-1.07 1.46,-1.64 3.55,-1.44c1.8,0.17 2.27,0.79 2.18,2.85c-0.03,0.85 0,1.73 0.08,1.96c0.12,0.34 -0.06,0.42 -0.92,0.42c-0.59,0 -1.14,-0.12 -1.22,-0.27c-0.1,-0.17 -0.32,-0.17 -0.66,0c-0.85,0.45 -2.33,0.32 -2.88,-0.26zm3.15,-1.28c0.09,-0.24 -0.06,-0.33 -0.47,-0.27c-0.33,0.05 -0.66,0.25 -0.74,0.45c-0.08,0.24 0.07,0.32 0.48,0.26c0.33,-0.05 0.66,-0.25 0.73,-0.44zm3.25,-0.73l0.1,-2.53l1.38,0.03c0.76,0.01 1.82,-0.06 2.35,-0.15c0.78,-0.13 1.08,-0.05 1.5,0.39c0.45,0.47 0.52,0.87 0.44,2.67l-0.09,2.12l-1.05,0l-1.05,0l0.05,-1.39c0.06,-1.58 -0.19,-2.2 -0.81,-1.96c-0.32,0.12 -0.44,0.54 -0.49,1.76l-0.07,1.59l-1.18,0.01l-1.19,0l0.11,-2.54zm7.36,2.26c-0.8,-0.32 -1.21,-1.21 -0.66,-1.42c0.66,-0.25 1.91,-0.19 2.08,0.1c0.19,0.33 1.17,0.35 1.18,0.02c0.01,-0.13 -0.49,-0.32 -1.1,-0.42c-1.92,-0.31 -2.76,-1.33 -2,-2.41c0.92,-1.3 4.8,-1.13 5,0.23c0.06,0.36 -0.12,0.46 -0.8,0.47l-0.88,0.01l0.77,0.43c0.92,0.5 1.14,0.82 1.12,1.58c-0.04,0.96 -1.26,1.68 -2.8,1.66c-0.74,-0.01 -1.6,-0.12 -1.91,-0.25zm2.43,-3.44c0,-0.14 -0.26,-0.26 -0.59,-0.26c-0.47,0 -0.51,0.05 -0.2,0.26c0.49,0.33 0.77,0.33 0.79,0zm6.49,1.98c0.06,-1.35 -0.01,-1.72 -0.32,-1.72c-0.26,0 -0.38,-0.26 -0.36,-0.79c0.02,-0.5 0.17,-0.8 0.39,-0.8c0.2,0 0.45,-0.35 0.55,-0.78c0.28,-1.17 0.95,-1.38 3.65,-1.18c2.25,0.17 2.36,0.21 2.33,0.8c-0.02,0.56 -0.14,0.63 -1.19,0.63c-0.89,0 -1.19,-0.11 -1.26,-0.46c-0.1,-0.45 -0.11,-0.45 -0.16,0c-0.03,0.27 -0.26,0.46 -0.57,0.46c-0.29,0 -0.53,0.12 -0.54,0.27c0,0.14 0.17,0.26 0.38,0.26c0.27,0 0.39,0.26 0.37,0.79c-0.03,0.53 -0.17,0.8 -0.43,0.8c-0.31,0 -0.41,0.37 -0.47,1.72l-0.07,1.72l-1.18,0l-1.19,0l0.07,-1.72zm3.72,-0.8l0.11,-2.51l1.18,0l1.19,0l-0.11,2.51l-0.1,2.52l-1.19,0l-1.18,0l0.1,-2.52zm10.04,-0.93l0.14,-3.44l1.06,0l1.05,0l-0.04,1.06c-0.04,0.98 0,1.05 0.47,0.8c0.86,-0.45 2.02,-0.32 2.53,0.28c0.37,0.42 0.48,1.06 0.49,2.65l0.01,2.09l-1.22,0l-1.21,0l0.07,-1.72c0.07,-1.51 0.01,-1.72 -0.42,-1.72c-0.63,0 -0.84,0.49 -0.91,2.14l-0.05,1.3l-1.06,0l-1.05,0l0.14,-3.44zm7.44,3.15c-0.34,-0.2 -0.44,-0.62 -0.39,-1.71c0.05,-1.11 -0.03,-1.45 -0.34,-1.45c-0.26,0 -0.38,-0.26 -0.36,-0.79c0.02,-0.53 0.17,-0.79 0.43,-0.79c0.22,-0.01 0.4,-0.24 0.42,-0.53c0.02,-0.49 1.21,-1.33 1.88,-1.33c0.15,0 0.26,0.42 0.24,0.93c-0.03,0.75 0.06,0.92 0.49,0.92c0.41,0 0.52,0.18 0.49,0.8c-0.03,0.61 -0.15,0.79 -0.56,0.79c-0.43,0 -0.53,0.18 -0.56,0.93c-0.03,0.73 0.06,0.93 0.45,0.93c0.48,0 0.9,1.11 0.55,1.45c-0.25,0.24 -2.27,0.13 -2.74,-0.15zm3.58,-2.23l0.1,-2.52l1.19,0l1.18,0l-0.1,2.52l-0.11,2.51l-1.18,0l-1.19,0l0.11,-2.51zm3.16,-0.02l0.1,-2.53l1.38,0.03c0.76,0.01 1.77,-0.06 2.25,-0.15c0.59,-0.12 1.06,-0.05 1.5,0.25c0.6,0.41 0.63,0.58 0.55,2.68l-0.1,2.25l-1.04,0l-1.04,0l-0.01,-1.66c-0.01,-1.45 -0.07,-1.65 -0.53,-1.65c-0.46,0 -0.55,0.2 -0.68,1.65l-0.14,1.66l-1.17,0l-1.18,0l0.11,-2.53zm16.88,-0.94l0.14,-3.43l1.06,0c1.02,0 1.05,0.03 1.01,0.89l-0.03,0.9l1.16,-0.13c1.01,-0.12 1.27,-0.04 1.82,0.54c0.91,0.95 0.85,3.09 -0.11,4.01c-0.58,0.56 -0.88,0.63 -2.92,0.64l-2.27,0l0.14,-3.42zm3.37,1.34c0.3,-0.54 0.03,-1.59 -0.42,-1.59c-0.35,0 -0.86,0.62 -0.88,1.06c-0.01,0.44 0.45,1.06 0.79,1.06c0.11,0 0.34,-0.24 0.51,-0.53zm3.41,1.7c-0.73,-0.53 -0.72,-1.84 0.01,-2.23c0.29,-0.15 1.14,-0.4 1.89,-0.56c1.02,-0.22 1.3,-0.38 1.09,-0.59c-0.21,-0.22 -0.42,-0.22 -0.81,0.02c-0.29,0.18 -0.95,0.33 -1.47,0.33c-0.83,0 -0.93,-0.07 -0.84,-0.59c0.17,-0.89 1.22,-1.3 3.1,-1.2c2.25,0.12 2.52,0.45 2.53,3.12l0.01,2.11l-1.09,0c-0.59,0 -1.07,-0.12 -1.07,-0.28c0.01,-0.18 -0.15,-0.18 -0.5,0c-0.77,0.41 -2.2,0.34 -2.85,-0.13zm2.73,-1.07c0.23,-0.09 0.43,-0.33 0.43,-0.53c0.02,-0.43 -1.09,-0.1 -1.27,0.38c-0.13,0.34 0.19,0.39 0.84,0.15zm4.4,0.97c-0.58,-0.37 -0.86,-0.8 -0.96,-1.47c-0.28,-1.99 1.07,-3.32 3.37,-3.32c1.11,0 2.67,0.84 2.65,1.42c-0.03,0.69 -1.51,0.93 -2.35,0.39c-0.73,-0.47 -1.35,-0.09 -1.39,0.84c-0.03,0.93 0.55,1.3 1.32,0.83c0.6,-0.37 2.61,-0.41 2.6,-0.06c-0.01,0.14 -0.3,0.58 -0.66,0.98c-0.89,0.99 -3.34,1.2 -4.58,0.39zm5.83,-2.94l0.14,-3.44l1.06,0l1.05,-0.01l-0.06,1.51l-0.06,1.5l0.63,-0.58c0.49,-0.44 0.96,-0.57 2.05,-0.57l1.41,0l-0.92,0.91l-0.92,0.92l0.62,1c1.36,2.21 1.36,2.2 -0.09,2.2c-1.19,0 -1.31,-0.06 -1.73,-0.92c-0.35,-0.69 -0.54,-0.84 -0.81,-0.62c-0.19,0.15 -0.36,0.56 -0.38,0.91c-0.02,0.56 -0.14,0.63 -1.08,0.63l-1.05,0l0.14,-3.44zm-161.49,-2.65c0.02,-0.61 0.12,-0.67 1.21,-0.67c1.09,0 1.18,0.06 1.16,0.66c-0.03,0.61 -0.13,0.67 -1.22,0.67c-1.08,0 -1.18,-0.06 -1.15,-0.66zm121.86,-0.1c0.03,-0.61 0.13,-0.66 1.21,-0.66c1.09,0 1.19,0.05 1.16,0.66c-0.02,0.61 -0.12,0.66 -1.21,0.66c-1.09,0 -1.18,-0.05 -1.16,-0.66z" fill="#000000" id="path26"/> + <g id="g48"> + <path d="m30.25,181.33l0,-9.37l3.02,1.03c1.9,0.64 3.04,1.11 3.08,1.25c0.03,0.13 0.14,0.26 0.24,0.29c0.23,0.08 0.95,1.85 1.21,2.86c0.05,0.19 0.09,0.35 0.1,0.47c0.03,0.36 0.1,0.71 0.15,0.79c0.13,0.21 0.11,1.87 -0.03,2.43c-0.06,0.27 -0.29,0.67 -0.51,0.9c-0.4,0.42 -0.5,0.74 -0.27,0.82c0.29,0.1 0.91,1.4 1.14,2.4c0.38,1.67 0.47,3.16 0.29,4.85c-0.15,1.32 -0.42,2.02 -0.97,2.47c-0.43,0.34 -0.48,0.33 -3.94,-0.74l-3.51,-1.08l0,-9.37zm4.38,5.9c0.18,-0.29 0.16,-1.26 -0.04,-1.72c-0.12,-0.28 -0.31,-0.42 -0.64,-0.49c-0.47,-0.1 -0.47,-0.1 -0.51,0.68c-0.01,0.43 0,0.92 0.03,1.09c0.07,0.39 0.99,0.73 1.16,0.44zm-0.54,-5.75c0.31,-0.18 0.42,-0.84 0.26,-1.5c-0.13,-0.54 -0.44,-0.85 -0.94,-0.93c-0.32,-0.04 -0.35,0 -0.37,0.8c-0.03,0.69 0.01,0.92 0.2,1.25c0.27,0.49 0.49,0.59 0.85,0.38zm5.14,5.99c-0.04,-3.49 -0.06,-6.37 -0.04,-6.4c0.06,-0.1 4.02,1.25 4.05,1.38c0.01,0.07 0.02,0.96 0.02,1.98l0,1.86l-0.45,-0.16c-0.33,-0.11 -0.49,-0.06 -0.56,0.17c-0.16,0.53 0.05,1.1 0.45,1.24c0.35,0.12 0.36,0.13 0.37,1.06c0.01,0.51 0.02,1.05 0.03,1.19c0,0.14 -0.17,0.25 -0.38,0.25c-0.46,-0.01 -0.62,0.2 -0.57,0.75c0.03,0.33 0.15,0.44 0.74,0.69l0.7,0.3l-0.07,0.64c-0.05,0.35 -0.11,1.09 -0.14,1.64l-0.07,1.01l-2,-0.63l-2.01,-0.62l-0.07,-6.35zm5.34,7.98l-0.69,-0.31l0,-6.28l0,-6.28l1.18,0.4l1.17,0.4l0.03,5.27c0.01,2.89 0.02,5.75 0.02,6.35l0,1.08l-0.51,-0.16c-0.28,-0.08 -0.82,-0.3 -1.2,-0.47zm2.28,-5.34l0,-6.33l1.09,0.43l1.09,0.43l0.32,1.39c0.42,1.87 0.61,1.87 0.65,0.02l0.03,-1.39l1.2,0.54c0.66,0.31 1.22,0.58 1.24,0.62c0.02,0.04 0.06,2.83 0.09,6.19l0.06,6.12l-1.43,-0.48l-1.43,-0.49l-0.29,-1.24c-0.16,-0.68 -0.34,-1.23 -0.4,-1.21c-0.07,0.02 -0.13,0.52 -0.15,1.1l-0.03,1.05l-0.55,-0.18c-0.3,-0.1 -0.75,-0.2 -1.02,-0.22l-0.47,-0.03l0,-6.32zm10.83,9.6c-0.15,-0.35 -0.21,-0.39 -0.38,-0.24c-0.23,0.22 -1.66,-0.22 -1.92,-0.58c-0.1,-0.14 -0.36,-0.48 -0.57,-0.76c-0.54,-0.72 -1.16,-2.18 -1.46,-3.48c-0.47,-2.02 -0.31,-5.28 0.33,-6.81c0.29,-0.7 1.14,-1.28 1.8,-1.24c0.87,0.06 2.05,1.32 2.7,2.9c0.36,0.85 0.93,3.15 0.82,3.32c-0.03,0.05 -0.53,-0.08 -1.11,-0.3c-0.78,-0.29 -1.08,-0.48 -1.16,-0.73c-0.07,-0.19 -0.26,-0.44 -0.42,-0.57c-0.24,-0.17 -0.38,-0.13 -0.61,0.19c-0.28,0.39 -0.3,0.51 -0.3,2c0,1.48 0.02,1.62 0.29,2.18c0.41,0.83 0.75,1.07 1.17,0.81c0.27,-0.16 0.34,-0.33 0.32,-0.69c-0.03,-0.36 -0.11,-0.51 -0.37,-0.65c-0.27,-0.15 -0.33,-0.26 -0.33,-0.68l0,-0.5l1.28,0.43c0.7,0.24 1.29,0.51 1.31,0.6c0.02,0.1 0.01,1.37 -0.02,2.83l-0.06,2.66l-0.56,-0.13c-0.43,-0.1 -0.61,-0.23 -0.75,-0.56zm12.4,4.42l-0.59,-0.28l0,-6.28l0,-6.28l0.98,0.34l0.97,0.33l0,0.99c0,1.16 0.13,1.52 0.58,1.68c0.38,0.13 0.5,-0.31 0.43,-1.6l-0.04,-0.72l1.01,0.28c0.56,0.15 1.03,0.33 1.05,0.38c0.03,0.06 0.05,2.92 0.05,6.36l0,6.25l-1.02,-0.34l-1.02,-0.35l-0.03,-1.09l-0.04,-1.1l-0.35,-0.12l-0.36,-0.12l-0.05,1.12l-0.06,1.11l-0.46,-0.14c-0.25,-0.07 -0.72,-0.26 -1.05,-0.42zm5.03,-4.48c-0.03,-3.49 -0.04,-6.38 -0.03,-6.4c0,-0.02 0.93,0.27 2.05,0.63l2.05,0.68l0,1.92l0,1.92l-0.51,-0.07c-0.49,-0.06 -0.52,-0.04 -0.52,0.55c0,0.58 0.03,0.63 0.44,0.83l0.44,0.22l-0.03,1.15l-0.03,1.16l-0.41,0.03c-0.5,0.04 -0.6,0.19 -0.51,0.78c0.06,0.4 0.14,0.49 0.74,0.69l0.67,0.22l-0.08,0.75c-0.05,0.41 -0.11,1.16 -0.14,1.66l-0.06,0.9l-2.01,-0.63l-2.02,-0.62l-0.04,-6.37zm5.7,8.12l-0.93,-0.38l-0.07,-2.95c-0.1,-4.56 -0.08,-9.21 0.04,-9.32c0.06,-0.05 0.63,0.03 1.27,0.19c1.56,0.37 2.33,1.07 2.95,2.66c0.25,0.65 0.52,2.75 0.44,3.47c-0.04,0.34 -0.09,0.92 -0.13,1.31c-0.03,0.38 -0.14,0.97 -0.25,1.31c-0.21,0.69 -0.23,1.04 -0.1,1.62c0.21,0.9 0.53,2.88 0.53,3.29c0,0.18 -0.26,0.15 -0.95,-0.13l-0.94,-0.38l-0.11,-0.8c-0.12,-0.93 -0.39,-1.65 -0.55,-1.5c-0.07,0.06 -0.12,0.51 -0.12,1.01c0,0.49 -0.03,0.92 -0.07,0.94c-0.05,0.02 -0.5,-0.13 -1.01,-0.34zm1.7,-4.89c0.44,-0.53 0.34,-1.76 -0.19,-2.39c-0.55,-0.65 -0.63,-0.51 -0.63,1.03l0,1.35l0.33,0.1c0.18,0.06 0.41,0.02 0.49,-0.09zm4.71,7.1c-0.79,-0.55 -1.61,-2.15 -2.01,-3.94c-0.2,-0.92 -0.24,-1.42 -0.24,-3c0,-2.11 0.1,-2.76 0.64,-3.99c0.42,-0.96 0.98,-1.42 1.82,-1.48c1.89,-0.14 3.38,3.4 3.38,8.07c0,2.3 -0.56,3.89 -1.57,4.49c-0.43,0.26 -1.54,0.18 -2.02,-0.15zm1.18,-4.33c0.24,-0.36 0.27,-0.55 0.22,-1.18c-0.14,-1.79 -1.13,-2.15 -1.35,-0.48c-0.06,0.43 -0.01,0.68 0.24,1.27c0.38,0.89 0.52,0.95 0.89,0.39zm9.14,7.84c-0.04,-0.09 -0.07,-0.75 -0.07,-1.46c0,-0.71 -0.04,-1.36 -0.1,-1.44c-0.12,-0.2 -0.38,0.77 -0.47,1.79l-0.07,0.82l-0.57,-0.26c-0.55,-0.24 -0.59,-0.3 -0.68,-0.91c-0.2,-1.37 -0.41,-2.31 -0.51,-2.28c-0.06,0.02 -0.13,0.65 -0.14,1.4l-0.03,1.37l-0.82,-0.28l-0.81,-0.28l0,-6.29l0,-6.29l1.27,0.43l1.27,0.44l0.06,0.69c0.04,0.38 0.1,1.04 0.13,1.47c0.03,0.43 0.12,0.85 0.19,0.94c0.21,0.22 0.46,-0.28 0.46,-0.91c0,-0.3 0.05,-0.83 0.12,-1.18l0.12,-0.64l1.16,0.39l1.16,0.4l-0.02,6.33l-0.03,6.33l-0.77,-0.2c-0.43,-0.11 -0.81,-0.28 -0.85,-0.38zm2.25,0.77c-0.04,-0.09 -0.07,-2.98 -0.07,-6.42l0,-6.26l2.05,0.7l2.05,0.69l0,1.96l0,1.96l-0.43,-0.14c-0.55,-0.19 -0.72,-0.03 -0.68,0.61c0.03,0.43 0.1,0.54 0.47,0.72l0.44,0.21l0,1.2l0,1.2l-0.43,-0.03c-0.47,-0.04 -0.63,0.24 -0.49,0.84c0.08,0.33 0.23,0.45 0.77,0.63c0.6,0.21 0.66,0.27 0.66,0.66c0,0.85 0.26,0.34 0.28,-0.56c0.01,-0.49 0.09,-1.85 0.17,-3.02c0.09,-1.16 0.21,-2.95 0.28,-3.98l0.13,-1.86l1.67,0.57c1.65,0.56 1.67,0.57 1.67,1.02c0,0.24 0.04,0.75 0.1,1.11c0.1,0.7 0.48,4.09 0.63,5.65c0.05,0.5 0.14,1.36 0.2,1.92c0.06,0.56 0.14,1.45 0.19,1.97c0.05,0.53 0.12,1.18 0.16,1.45c0.08,0.49 0.07,0.49 -0.95,0.14c-1.14,-0.39 -1.16,-0.42 -1.25,-1.76c-0.05,-0.8 -0.07,-0.86 -0.43,-1.04c-0.36,-0.18 -0.38,-0.16 -0.49,0.56c-0.06,0.41 -0.11,0.91 -0.11,1.11c0,0.32 -0.12,0.32 -1.07,-0.01l-1.08,-0.37l-0.01,-0.67c0,-0.37 -0.04,-0.92 -0.09,-1.22c-0.1,-0.69 -0.19,-0.32 -0.23,0.96l-0.03,0.92l-2,-0.63c-1.1,-0.35 -2.04,-0.7 -2.08,-0.79zm7.48,-1.76c0.03,-0.16 0.02,-0.65 -0.03,-1.09c-0.08,-0.66 -0.15,-0.84 -0.37,-0.97c-0.22,-0.13 -0.3,-0.05 -0.38,0.35c-0.14,0.7 -0.13,1.45 0.02,1.62c0.27,0.32 0.7,0.37 0.76,0.09zm3.08,5.37c-0.04,-0.1 -0.07,-2.96 -0.07,-6.34l0,-6.15l1.06,0.36c0.73,0.25 1.1,0.45 1.17,0.65c0.2,0.57 0.53,2.01 0.53,2.31c0,0.16 0.1,0.33 0.21,0.37c0.17,0.06 0.2,-0.07 0.2,-0.91c0.01,-1.98 -0.03,-1.94 1.27,-1.35c0.63,0.29 1.17,0.59 1.21,0.67c0.04,0.09 0.09,2.88 0.11,6.2l0.03,6.05l-1.44,-0.54l-1.43,-0.55l-0.26,-1.16c-0.37,-1.67 -0.61,-1.61 -0.61,0.16l0,0.81l-0.5,-0.17c-0.28,-0.09 -0.7,-0.18 -0.95,-0.2c-0.25,-0.02 -0.48,-0.11 -0.53,-0.21zm7.01,2.34c-0.53,-0.24 -0.63,-0.34 -0.59,-0.58c0.04,-0.17 0.06,-0.99 0.06,-1.83l0,-1.53l0.57,0.19c0.49,0.17 0.56,0.14 0.56,-0.2c0,-0.46 -0.18,-0.95 -0.6,-1.58c-0.15,-0.24 -0.41,-0.89 -0.57,-1.45c-0.25,-0.89 -0.28,-1.15 -0.23,-2.06c0.07,-1.18 0.49,-2.36 0.96,-2.73c0.5,-0.4 1.35,-0.41 2.1,-0.03c0.38,0.2 0.74,0.42 0.78,0.49c0.05,0.07 0.08,1.04 0.08,2.15l-0.01,2.02l-0.29,-0.03c-0.73,-0.08 -0.76,1.03 -0.05,2.03c0.79,1.13 1,2.51 0.61,3.93c-0.49,1.77 -1.4,2.1 -3.37,1.21l-0.01,0zm6,2.06c-0.04,-0.09 -0.07,-2.97 -0.07,-6.42l0,-6.25l1.95,0.66l1.94,0.66l0,1.65c0,0.91 0.01,1.72 0.01,1.81c0,0.08 -0.22,0.13 -0.49,0.09c-0.42,-0.05 -0.49,0 -0.52,0.43c-0.05,0.66 0.22,1.12 0.77,1.31l0.44,0.15l0,1l0,1l-0.64,-0.03l-0.64,-0.04l-0.03,2.52l-0.03,2.52l-1.31,-0.45c-0.72,-0.25 -1.34,-0.52 -1.38,-0.61zm5.08,1.72l-0.64,-0.29l-0.02,-6.3l-0.03,-6.29l1.14,0.39l1.14,0.39l0.07,6.19c0.05,3.41 0.05,6.29 0.01,6.4c-0.07,0.19 -0.31,0.12 -1.67,-0.5l0,0.01zm6.86,2.13c-0.2,-0.34 -0.28,-0.39 -0.44,-0.25c-0.22,0.21 -1.65,-0.23 -1.91,-0.59c-0.1,-0.13 -0.35,-0.47 -0.56,-0.75c-0.56,-0.74 -1.21,-2.3 -1.48,-3.57c-0.44,-2.05 -0.28,-5.28 0.33,-6.73c0.3,-0.7 1.15,-1.28 1.81,-1.23c0.87,0.05 2.05,1.31 2.7,2.88c0.37,0.91 0.94,3.14 0.83,3.32c-0.03,0.06 -0.54,-0.07 -1.12,-0.29c-0.78,-0.29 -1.08,-0.48 -1.17,-0.73c-0.06,-0.19 -0.25,-0.44 -0.41,-0.56c-0.24,-0.18 -0.38,-0.13 -0.61,0.18c-0.28,0.4 -0.3,0.51 -0.3,2c0,1.48 0.02,1.62 0.29,2.18c0.41,0.84 0.75,1.08 1.17,0.82c0.27,-0.17 0.34,-0.33 0.32,-0.7c-0.03,-0.36 -0.11,-0.51 -0.37,-0.65c-0.27,-0.14 -0.33,-0.26 -0.33,-0.68l0,-0.5l1.26,0.43c0.7,0.24 1.29,0.48 1.31,0.53c0.02,0.06 0.02,1.33 -0.01,2.83l-0.05,2.74l-0.51,-0.13c-0.34,-0.09 -0.59,-0.27 -0.75,-0.55zm2.46,1.04l-0.53,-0.26l-0.01,-5.82c0,-3.2 -0.02,-6.03 -0.06,-6.3c-0.06,-0.48 -0.05,-0.48 0.91,-0.15l0.98,0.33l0.07,0.98c0.11,1.47 0.14,1.56 0.57,1.71l0.39,0.14l0.04,-1.25l0.03,-1.24l1,0.3l0.99,0.31l0,1.67c0,0.92 0.03,3.78 0.07,6.36l0.07,4.7l-1.04,-0.35l-1.03,-0.36l-0.03,-1.09l-0.03,-1.09l-0.36,-0.12l-0.36,-0.13l-0.05,1.12l-0.05,1.12l-0.52,-0.16c-0.28,-0.08 -0.75,-0.27 -1.05,-0.42zm6.4,-0.49c-0.04,-1.56 -0.07,-3.42 -0.07,-4.13c0,-1.45 -0.04,-1.55 -0.76,-1.79c-0.55,-0.19 -0.57,-0.29 -0.57,-2.69l0,-1.84l2.45,0.84c1.35,0.46 2.48,0.91 2.5,1c0.03,0.1 0.07,1.01 0.09,2.04l0.03,1.87l-0.57,-0.07c-0.32,-0.04 -0.64,-0.02 -0.71,0.05c-0.1,0.09 -0.12,0.78 -0.06,3.15c0.03,1.67 0.09,3.53 0.13,4.14l0.06,1.1l-1.23,-0.41l-1.22,-0.42l-0.07,-2.84zm4.67,4.26l-0.64,-0.3l0,-6.28l0,-6.28l1.12,0.38l1.11,0.38l0.07,2.96c0.04,1.63 0.06,4.49 0.04,6.36l-0.03,3.39l-0.52,-0.16c-0.28,-0.09 -0.8,-0.29 -1.15,-0.45zm2.3,-2.49c-0.04,-1.91 -0.07,-4.76 -0.07,-6.33l0,-2.86l1.05,0.36c0.58,0.2 1.1,0.45 1.16,0.55c0.06,0.1 0.23,0.77 0.39,1.47c0.39,1.75 0.55,1.74 0.63,-0.04l0.08,-1.42l1.13,0.51c0.63,0.29 1.17,0.59 1.21,0.68c0.04,0.08 0.08,2.87 0.1,6.2l0.04,6.05l-1.43,-0.55l-1.44,-0.54l-0.26,-1.17c-0.33,-1.55 -0.51,-1.59 -0.51,-0.13l0,1.14l-0.55,-0.19c-0.3,-0.1 -0.75,-0.2 -1.01,-0.21l-0.45,-0.03l-0.07,-3.49zm10.86,6.76c-0.14,-0.35 -0.21,-0.39 -0.38,-0.24c-0.26,0.24 -1.58,-0.21 -2.05,-0.7c-0.84,-0.89 -1.69,-2.7 -1.99,-4.25c-0.18,-0.93 -0.22,-5.01 -0.05,-5.16c0.05,-0.05 0.1,-0.25 0.1,-0.45c0,-0.52 0.67,-1.8 1.05,-2.02c0.68,-0.38 1.14,-0.41 1.69,-0.11c1.08,0.6 2.16,2.44 2.66,4.53c0.4,1.68 0.38,1.71 -0.81,1.23c-0.84,-0.35 -1.09,-0.53 -1.32,-0.94c-0.72,-1.32 -1.45,0.11 -1.26,2.5c0.15,1.96 1.27,3.2 1.74,1.92c0.15,-0.41 0.15,-0.51 0.03,-0.71c-0.08,-0.13 -0.27,-0.28 -0.43,-0.34c-0.24,-0.08 -0.29,-0.17 -0.26,-0.55c0.03,-0.44 0.06,-0.44 1.31,-0.02l1.28,0.44l0.04,1.56c0.02,0.85 0,2.12 -0.04,2.82l-0.06,1.27l-0.54,-0.19c-0.37,-0.12 -0.58,-0.31 -0.71,-0.59zm3.93,-4.7l0,-6.46l2.02,0.81c1.11,0.44 2.15,0.94 2.3,1.11c0.16,0.17 0.42,0.75 0.59,1.28c0.26,0.79 0.31,1.17 0.31,2.06c0,0.97 -0.03,1.12 -0.3,1.42c-0.34,0.37 -0.32,0.85 0.06,1.27c0.45,0.5 0.65,1.58 0.65,3.46c0,1.66 0,1.7 -0.36,2.3c-0.36,0.6 -0.37,0.6 -1.26,0.3c-0.5,-0.17 -1.6,-0.49 -2.46,-0.7l-1.55,-0.4l0,-6.45zm2.84,4.15c0.46,-0.49 0.2,-1.55 -0.4,-1.64c-0.29,-0.04 -0.35,0.04 -0.38,0.55c-0.02,0.4 0.03,0.71 0.15,0.93c0.24,0.42 0.36,0.46 0.63,0.16zm-0.06,-4.34c0.16,-0.66 -0.04,-1.15 -0.54,-1.32c-0.38,-0.13 -0.4,-0.11 -0.4,0.55c0,0.86 0.05,0.98 0.48,1.13c0.27,0.09 0.37,0.01 0.46,-0.36zm10.64,10.97c-0.2,-0.15 -0.51,-0.51 -0.69,-0.79c-0.34,-0.52 -0.85,-2.01 -0.85,-2.5c0,-0.15 -0.05,-0.4 -0.11,-0.55c-0.16,-0.36 -0.17,-4.26 -0.02,-4.84c0.06,-0.24 0.19,-0.77 0.29,-1.18c0.39,-1.68 1.42,-2.74 2.34,-2.43c0.95,0.33 1.92,2.1 2.05,3.75c0.03,0.43 0.09,1.05 0.13,1.38l0.06,0.59l-0.88,-0.3c-0.76,-0.26 -0.89,-0.36 -0.98,-0.74c-0.14,-0.56 -0.46,-0.86 -0.72,-0.67c-0.51,0.37 -0.69,3 -0.31,4.4c0.18,0.64 0.26,0.76 0.54,0.8c0.26,0.04 0.37,-0.1 0.57,-0.75l0.24,-0.79l0.77,0.26c0.75,0.26 0.77,0.27 0.71,0.7c-0.04,0.25 -0.1,0.72 -0.13,1.04c-0.12,1.33 -0.59,2.6 -1.07,2.92c-0.38,0.25 -1.43,0.09 -1.94,-0.3zm3.66,1.29c-0.04,-0.09 -0.07,-2.98 -0.07,-6.43l0,-6.25l0.97,0.33c0.95,0.32 0.97,0.34 0.97,0.81c0,0.67 0.24,1.35 0.45,1.26c0.1,-0.04 0.27,-0.37 0.39,-0.73l0.21,-0.65l0.91,0.31l0.91,0.31l0,0.81c0,1.03 -0.27,2.21 -0.8,3.44c-0.24,0.55 -0.43,1.05 -0.43,1.13c0,0.08 0.21,0.69 0.45,1.36c0.45,1.21 0.65,2.13 0.87,4.07c0.23,1.95 0.27,1.89 -0.98,1.46l-1.1,-0.38l-0.16,-0.72c-0.11,-0.53 -0.22,-0.74 -0.41,-0.8c-0.21,-0.08 -0.26,0.02 -0.31,0.61l-0.05,0.71l-0.87,-0.24c-0.48,-0.13 -0.91,-0.32 -0.95,-0.41zm-121.57,-42.62c0.03,-0.65 0.13,-2.21 0.22,-3.49c0.09,-1.27 0.21,-3.04 0.26,-3.93c0.06,-0.89 0.13,-2.09 0.17,-2.68l0.06,-1.06l1.68,0.57c1.66,0.57 1.68,0.58 1.68,1.02c0,0.25 0.04,0.75 0.1,1.12c0.15,1.01 0.53,4.43 0.58,5.27c0.03,0.4 0.09,0.93 0.14,1.18c0.05,0.24 0.11,0.77 0.14,1.18c0.05,0.7 0.17,1.96 0.33,3.26l0.06,0.59l-1.03,-0.35c-1.13,-0.39 -1.15,-0.42 -1.24,-1.77c-0.05,-0.79 -0.08,-0.85 -0.42,-1.03c-0.35,-0.17 -0.38,-0.14 -0.49,0.58c-0.06,0.42 -0.12,0.92 -0.12,1.11c0,0.29 -0.15,0.28 -1.09,-0.04l-1.09,-0.37l0.06,-1.16zm3.08,-1.98c0.03,-0.14 -0.01,-0.64 -0.09,-1.11c-0.17,-1.07 -0.56,-1.41 -0.75,-0.64c-0.16,0.65 -0.15,1.44 0.01,1.62c0.27,0.31 0.77,0.39 0.83,0.13zm107.7,39.56c0.15,-3.05 0.25,-4.79 0.35,-6.01c0.06,-0.72 0.16,-2.15 0.24,-3.17l0.13,-1.86l1.67,0.56c1.64,0.56 1.67,0.58 1.67,1.02c0,0.25 0.04,0.75 0.09,1.12c0.06,0.36 0.15,1.24 0.22,1.94c0.07,0.7 0.18,1.71 0.26,2.24c0.08,0.53 0.14,1.22 0.14,1.53c0,0.32 0.05,0.65 0.11,0.74c0.05,0.08 0.1,0.55 0.1,1.03c0,0.48 0.04,0.98 0.09,1.1c0.05,0.13 0.12,0.61 0.14,1.07c0.03,0.47 0.09,1.07 0.13,1.34c0.07,0.48 0.07,0.48 -1.01,0.12l-1.08,-0.37l-0.07,-0.8c-0.03,-0.43 -0.07,-0.93 -0.08,-1.11c-0.01,-0.2 -0.15,-0.38 -0.4,-0.51c-0.35,-0.18 -0.38,-0.15 -0.48,0.56c-0.06,0.41 -0.11,0.91 -0.11,1.11c0,0.32 -0.12,0.32 -1.09,-0.01l-1.09,-0.37l0.07,-1.27zm2.99,-1.91c0.04,-0.16 0.02,-0.65 -0.03,-1.1c-0.07,-0.66 -0.14,-0.83 -0.37,-0.96c-0.22,-0.13 -0.3,-0.06 -0.38,0.34c-0.14,0.7 -0.13,1.45 0.03,1.63c0.27,0.31 0.7,0.36 0.75,0.09z" display="none" fill="#000000" id="path29" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.3"/> + <path d="m32.4,204.14c0,-3.8 0,-6.97 0,-7.06c0,-0.08 1.01,0.17 2.25,0.56l2.26,0.71l0,2.16l0,2.16l-0.53,-0.12c-0.37,-0.08 -0.56,-0.02 -0.64,0.21c-0.18,0.52 0.05,1.08 0.54,1.32c0.33,0.17 0.42,0.3 0.42,0.58c0,0.21 0.03,0.82 0.07,1.36l0.06,0.97l-0.34,-0.11c-0.54,-0.18 -0.8,-0.06 -0.87,0.38c-0.1,0.6 0.21,1.04 0.9,1.28l0.59,0.2l0,1.96l0,1.96l-2.35,-0.8l-2.36,-0.81l0,-6.91zm6.77,7.41c-0.12,-1.03 -0.27,-2.29 -0.32,-2.79c-0.05,-0.5 -0.14,-1.34 -0.2,-1.87c-0.06,-0.53 -0.15,-1.37 -0.2,-1.87c-0.25,-2.38 -0.32,-2.95 -0.51,-4.54c-0.12,-0.94 -0.21,-1.74 -0.21,-1.77c0,-0.04 0.57,0.12 1.26,0.36c1.26,0.42 1.27,0.43 1.39,0.99c0.06,0.31 0.11,0.72 0.11,0.91c0,0.6 0.34,2.24 0.45,2.21c0.12,-0.04 0.22,-0.73 0.35,-2.3l0.08,-0.9l1.16,0.33l1.16,0.34l-0.05,0.97c-0.03,0.53 -0.13,1.64 -0.22,2.46c-0.19,1.56 -0.29,2.56 -0.47,4.38c-0.06,0.6 -0.15,1.54 -0.21,2.09c-0.06,0.55 -0.14,1.45 -0.19,2c-0.18,2.06 -0.04,1.94 -1.69,1.38l-1.46,-0.49l-0.23,-1.89zm5.12,-3.57l0,-7.11l2.25,0.76l2.25,0.77l0,2.16l0,2.15l-0.52,-0.12c-0.37,-0.08 -0.56,-0.02 -0.64,0.21c-0.19,0.52 0.04,1.09 0.53,1.33c0.39,0.19 0.43,0.26 0.43,0.76c0,0.31 0.03,0.92 0.07,1.35c0.06,0.79 0.06,0.8 -0.29,0.68c-0.53,-0.17 -0.79,-0.06 -0.87,0.38c-0.1,0.6 0.21,1.05 0.9,1.28l0.6,0.2l0,1.96l0,1.96l-2.36,-0.8l-2.35,-0.8l0,-7.12zm5.4,8.84c-0.04,-0.1 -0.08,-3.32 -0.08,-7.16l0,-6.98l1.22,0.42l1.22,0.41l0.33,1.4c0.63,2.75 0.82,2.87 0.82,0.53l0,-1.54l1.38,0.47c0.76,0.26 1.4,0.54 1.42,0.64c0.03,0.09 0.08,3.31 0.12,7.16l0.08,6.99l-1.63,-0.61l-1.62,-0.61l-0.36,-1.51c-0.19,-0.84 -0.4,-1.5 -0.46,-1.49c-0.06,0.02 -0.13,0.63 -0.16,1.35l-0.05,1.3l-1.08,-0.3c-0.59,-0.16 -1.11,-0.38 -1.15,-0.47zm10.23,2.52c-0.03,-0.61 -0.1,-1.77 -0.16,-2.59c-0.05,-0.81 -0.14,-2.14 -0.19,-2.95c-0.25,-3.68 -0.34,-4.92 -0.43,-5.77c-0.05,-0.5 -0.1,-1.19 -0.1,-1.53l0,-0.61l1.03,0.35c0.99,0.33 1.02,0.36 1.03,0.81c0.01,0.79 0.35,3.27 0.45,3.3c0.1,0.03 0.35,-1.07 0.57,-2.54l0.13,-0.84l0.88,0.35c0.79,0.32 0.88,0.4 0.91,0.78c0.02,0.24 0.07,0.63 0.12,0.87c0.06,0.25 0.16,0.88 0.24,1.42c0.08,0.53 0.2,1.02 0.26,1.08c0.16,0.16 0.43,-1.16 0.43,-2.09c0,-1.43 0,-1.43 1.24,-1.01l1.11,0.37l-0.09,0.44c-0.06,0.24 -0.15,1.25 -0.21,2.25c-0.2,3.04 -0.31,4.77 -0.42,6.35c-0.06,0.83 -0.13,2.2 -0.16,3.04c-0.03,0.84 -0.11,1.58 -0.18,1.64c-0.06,0.06 -0.68,-0.08 -1.37,-0.31c-1.17,-0.4 -1.26,-0.45 -1.26,-0.83c0,-0.22 -0.04,-0.47 -0.1,-0.56c-0.05,-0.09 -0.1,-0.34 -0.1,-0.57c0,-0.22 -0.04,-0.57 -0.1,-0.79c-0.05,-0.21 -0.12,-0.56 -0.15,-0.77c-0.03,-0.21 -0.1,-0.39 -0.15,-0.41c-0.14,-0.05 -0.42,1.07 -0.42,1.7c0,0.29 -0.07,0.72 -0.16,0.94c-0.15,0.38 -0.23,0.38 -1.37,-0.01l-1.21,-0.41l-0.07,-1.1zm7.92,3.72c0,-0.03 -0.03,-3.24 -0.06,-7.14l-0.05,-7.09l1.16,0.45l1.17,0.46l0.05,1.25l0.05,1.26l0.46,0.16l0.46,0.15l0.03,-1.28l0.03,-1.28l1.11,0.38l1.12,0.38l0.06,2.34c0.04,1.29 0.06,4.48 0.04,7.08l-0.03,4.73l-1.13,-0.38l-1.13,-0.38l-0.05,-1.36l-0.05,-1.36l-0.36,-0.12l-0.36,-0.12l-0.03,1.38l-0.03,1.38l-1.22,-0.42c-0.68,-0.23 -1.23,-0.44 -1.24,-0.47zm6.26,-4.73c0,-3.8 0,-6.97 0,-7.06c0,-0.08 1.02,0.17 2.26,0.56l2.25,0.71l0,2.16l0,2.16l-0.52,-0.12c-0.37,-0.08 -0.57,-0.02 -0.64,0.2c-0.19,0.53 0.04,1.09 0.53,1.33c0.39,0.19 0.43,0.26 0.43,0.77c0,0.3 0.03,0.91 0.06,1.35c0.07,0.79 0.06,0.79 -0.28,0.68c-0.53,-0.18 -0.79,-0.06 -0.87,0.38c-0.1,0.6 0.21,1.04 0.9,1.28l0.6,0.2l0,1.96l0,1.96l-2.36,-0.8l-2.36,-0.81l0,-6.91zm5.41,8.63c-0.04,-0.1 -0.08,-3.32 -0.08,-7.16l0,-6.97l1.22,0.41l1.22,0.42l0.33,1.39c0.63,2.76 0.82,2.88 0.82,0.53l0,-1.53l1.38,0.46c0.75,0.26 1.39,0.55 1.42,0.64c0.02,0.1 0.08,3.32 0.12,7.17l0.08,6.99l-1.63,-0.61l-1.62,-0.61l-0.36,-1.52c-0.2,-0.83 -0.4,-1.5 -0.46,-1.48c-0.06,0.02 -0.13,0.62 -0.16,1.34l-0.05,1.31l-1.08,-0.3c-0.59,-0.16 -1.11,-0.38 -1.15,-0.48zm9.14,-3.88l0,-7.12l1.28,0.44c0.71,0.24 1.3,0.53 1.34,0.65c0.03,0.12 0.09,3.34 0.12,7.16l0.06,6.94l-1.4,-0.48l-1.4,-0.48l0,-7.11zm4.87,5.52c-0.04,-1.8 -0.1,-3.93 -0.14,-4.74l-0.06,-1.46l-0.64,-0.28l-0.64,-0.28l0,-2.36l0,-2.37l2.7,0.92l2.7,0.92l0.12,1.6c0.06,0.87 0.11,1.96 0.11,2.4l0,0.81l-0.74,-0.2l-0.74,-0.19l0,2.17c0.01,1.19 0.05,3.32 0.1,4.72l0.08,2.56l-1.39,-0.47l-1.39,-0.48l-0.07,-3.27zm7.56,5.69l-0.33,-0.21l0,-2.05l0,-2.05l0.66,0.22c0.64,0.22 0.67,0.21 0.67,-0.29c0,-0.37 -0.13,-0.74 -0.49,-1.39c-0.83,-1.49 -1.05,-2.31 -1.05,-3.93c0,-0.97 0.06,-1.36 0.29,-2.02c0.39,-1.09 0.61,-1.37 1.26,-1.63c0.76,-0.3 2.7,0.33 2.84,0.92c0.05,0.22 0.1,1.4 0.11,2.62l0.02,2.22l-0.4,-0.13c-0.38,-0.14 -0.74,0.2 -0.74,0.7c0,0.25 0.44,1.26 0.56,1.3c0.05,0.01 0.24,0.31 0.43,0.66c0.91,1.71 0.55,4.64 -0.68,5.51c-0.51,0.36 -0.68,0.37 -1.69,0.08c-0.62,-0.18 -1.28,-0.42 -1.46,-0.53zm4.86,1.64c-0.02,-0.1 -0.05,-3.31 -0.06,-7.15l-0.03,-6.97l2.32,0.79l2.32,0.79l-0.03,2.11l-0.03,2.1l-0.56,-0.09c-0.54,-0.08 -0.57,-0.05 -0.6,0.5c-0.04,0.7 0.11,0.98 0.62,1.16l0.39,0.13l0,1.01c0,0.56 0.02,1.17 0.06,1.37c0.05,0.27 -0.01,0.32 -0.3,0.22c-0.51,-0.17 -0.89,0.03 -0.89,0.48c0,0.65 0.22,0.94 0.89,1.17l0.65,0.22l-0.03,1.9l-0.03,1.9l-2.32,-0.74c-1.28,-0.4 -2.34,-0.81 -2.37,-0.9zm5.36,-5.15l0,-7.11l2.25,0.77l2.26,0.76l0,2.17l0,2.16l-0.49,-0.16c-0.52,-0.18 -0.74,0 -0.74,0.6c0,0.47 0.3,0.9 0.75,1.05l0.35,0.12l0.02,1.35l0.01,1.34l-0.39,-0.13c-0.36,-0.12 -0.85,0.16 -0.84,0.5c0,0.53 0.25,0.85 0.89,1.16c0.58,0.29 0.69,0.4 0.69,0.7c-0.01,0.2 -0.02,1.05 -0.03,1.9l-0.02,1.54l-2.35,-0.8l-2.36,-0.8l0,-7.12zm5.4,8.83c-0.04,-0.1 -0.07,-3.32 -0.07,-7.16l0,-6.98l1.45,0.55l1.46,0.55l0.14,1.08c0.08,0.6 0.17,1.36 0.21,1.71c0.04,0.35 0.12,0.68 0.18,0.73c0.13,0.14 0.45,-1.08 0.45,-1.73c0,-0.27 0.05,-0.72 0.1,-0.99l0.1,-0.5l1.34,0.46l1.33,0.45l0.01,2.02c0,1.1 0.02,4.29 0.03,7.07l0.01,5.06l-1.02,-0.35l-1.03,-0.35l0.04,-0.49c0.02,-0.27 0,-0.99 -0.03,-1.61c-0.08,-1.22 -0.3,-1.6 -0.4,-0.66c-0.11,1.09 -0.32,2.31 -0.42,2.43c-0.06,0.06 -0.34,0.04 -0.62,-0.06l-0.52,-0.17l-0.19,-1.35c-0.21,-1.52 -0.46,-2.48 -0.58,-2.28c-0.05,0.08 -0.1,0.83 -0.12,1.68l-0.03,1.53l-0.87,-0.24c-0.48,-0.13 -0.91,-0.31 -0.95,-0.4zm7.74,2.62l-0.33,-0.21l0,-2.05l0,-2.04l0.67,0.22c0.62,0.21 0.66,0.2 0.66,-0.24c0,-0.31 -0.16,-0.75 -0.48,-1.34c-0.26,-0.49 -0.62,-1.29 -0.79,-1.78c-0.27,-0.77 -0.31,-1.07 -0.31,-2.07c0,-0.69 0.07,-1.46 0.18,-1.87c0.22,-0.88 1.05,-2.08 1.36,-1.97c0.13,0.04 0.26,-0.01 0.3,-0.11c0.07,-0.21 2.47,0.56 2.54,0.82c0.03,0.09 0.06,1.24 0.08,2.55l0.04,2.39l-0.41,-0.08c-0.79,-0.14 -0.92,0.78 -0.26,1.88c0.23,0.38 0.45,0.7 0.49,0.71c0.05,0.02 0.18,0.27 0.29,0.56c0.31,0.83 0.28,3.01 -0.05,3.85c-0.31,0.78 -0.45,0.95 -1.03,1.33c-0.37,0.24 -0.68,0.23 -1.54,-0.02c-0.59,-0.18 -1.22,-0.41 -1.41,-0.53zm7.25,-4.51l0,-7.11l1.32,0.44l1.31,0.45l0.07,3.15c0.04,1.73 0.07,4.94 0.07,7.14l0,3.99l-1.39,-0.47l-1.38,-0.47l0,-7.12zm3.38,1.15l0,-7.12l1.46,0.55l1.46,0.55l0.08,0.85c0.16,1.95 0.24,2.53 0.35,2.65c0.15,0.15 0.44,-0.83 0.44,-1.47c0,-0.26 0.06,-0.75 0.13,-1.11l0.12,-0.64l1.36,0.46l1.37,0.47l0,7.11l0,7.12l-1.02,-0.35l-1.02,-0.35l-0.03,-1.6c-0.03,-1.25 -0.07,-1.62 -0.18,-1.66c-0.15,-0.05 -0.27,0.57 -0.39,1.97c-0.07,0.9 -0.24,1.04 -0.85,0.76l-0.54,-0.24l-0.15,-1.09c-0.2,-1.45 -0.46,-2.54 -0.59,-2.5c-0.05,0.02 -0.11,0.79 -0.13,1.71l-0.03,1.67l-0.92,-0.31l-0.92,-0.31l0,-7.12zm7.18,2.44l0,-7.11l1.68,0.57c0.93,0.31 1.71,0.66 1.74,0.77c0.03,0.11 0.18,0.3 0.34,0.41c0.4,0.3 0.82,1.16 1.17,2.37c0.27,0.95 0.29,1.19 0.29,3.01c0,1.79 -0.03,2.05 -0.3,2.9c-0.49,1.55 -1.21,2.39 -2.04,2.39c-0.5,0 -0.63,0.32 -0.63,1.63l0,0.94l-1.13,-0.38l-1.12,-0.38l0,-7.12zm3.19,1.68c0.19,-0.29 0.25,-1.13 0.1,-1.65c-0.24,-0.83 -1.07,-1.49 -1.18,-0.94c-0.12,0.56 -0.07,2.5 0.06,2.66c0.22,0.27 0.81,0.23 1.02,-0.07zm4.9,8.01c-0.7,-0.7 -1.65,-2.67 -1.91,-3.96c-0.08,-0.43 -0.2,-0.97 -0.25,-1.18c-0.12,-0.5 -0.12,-4.63 0,-5.06c0.05,-0.18 0.15,-0.57 0.22,-0.86c0.33,-1.29 1.37,-2.77 1.83,-2.62c0.11,0.04 0.23,-0.01 0.26,-0.11c0.04,-0.1 0.45,-0.06 0.93,0.11c0.47,0.16 0.88,0.39 0.92,0.52c0.03,0.12 0.13,0.25 0.22,0.28c0.29,0.1 1.03,1.57 1.36,2.71c0.54,1.87 0.72,3.23 0.72,5.28c0,1.52 -0.04,1.98 -0.25,2.8c-0.15,0.54 -0.32,1.11 -0.39,1.26c-0.16,0.35 -0.95,1.14 -1.35,1.36c-0.37,0.19 -1.95,-0.17 -2.32,-0.53l0.01,0zm1.37,-4.5c0.37,-0.16 0.62,-1.11 0.47,-1.76c-0.33,-1.38 -0.81,-1.83 -1.2,-1.13c-0.47,0.89 -0.27,2.23 0.46,2.98c0.01,0.01 0.13,-0.03 0.27,-0.09zm4.09,6.4l-0.34,-0.21l0,-2.05l0,-2.05l0.67,0.23c0.63,0.21 0.67,0.2 0.67,-0.26c0,-0.3 -0.13,-0.71 -0.33,-1.09c-1.04,-1.93 -1.21,-2.55 -1.21,-4.34c0,-1.34 0.09,-1.73 0.61,-2.69c0.54,-0.99 1.24,-1.19 2.58,-0.73c0.65,0.22 1.13,0.47 1.17,0.61c0.03,0.13 0.09,1.31 0.12,2.62l0.06,2.38l-0.41,-0.13c-0.45,-0.16 -0.79,0.26 -0.73,0.89c0.02,0.19 0.24,0.66 0.49,1.03c0.65,0.94 0.77,1.24 0.92,2.24c0.12,0.9 0.1,1.28 -0.18,2.4c-0.42,1.67 -1.11,2.11 -2.63,1.68c-0.62,-0.17 -1.28,-0.41 -1.46,-0.53zm5.4,1.84l-0.36,-0.21l0.04,-2.03l0.03,-2.04l0.63,0.16c0.56,0.14 0.64,0.1 0.67,-0.28c0.02,-0.3 -0.07,-0.58 -0.31,-0.97c-1.28,-2.03 -1.64,-4.27 -1.01,-6.28c0.31,-0.97 0.77,-1.55 1.44,-1.8c0.4,-0.15 2.62,0.53 2.7,0.83c0.03,0.1 0.06,1.25 0.07,2.55l0.02,2.36l-0.39,-0.06c-0.86,-0.15 -0.91,0.8 -0.12,2.08c0.64,1.03 0.76,1.36 0.84,2.25c0.17,1.84 -0.33,3.42 -1.25,3.98c-0.39,0.24 -0.7,0.24 -1.56,-0.01c-0.59,-0.17 -1.24,-0.41 -1.44,-0.53zm4.82,-5.34l0,-7.13l1.31,0.5l1.3,0.51l0.08,4.04c0.04,2.23 0.06,5.39 0.05,7.03l-0.03,2.99l-1.35,-0.41l-1.36,-0.4l0,-7.13zm3.36,8.12c-0.01,-0.1 -0.02,-3.31 0,-7.13l0.03,-6.95l2.25,0.77c2.53,0.86 2.6,0.91 3.2,2.54c0.57,1.52 0.59,3.74 0.04,4.09c-0.35,0.22 -0.36,0.89 -0.01,1.19c0.77,0.65 1.19,4.32 0.7,6.13c-0.08,0.27 -0.29,0.67 -0.47,0.87c-0.33,0.36 -0.4,0.34 -3.02,-0.48c-1.47,-0.47 -2.69,-0.93 -2.71,-1.03l-0.01,0zm3.34,-2.48c0.21,-0.52 0.21,-0.63 -0.04,-1.21c-0.23,-0.53 -0.71,-0.79 -0.9,-0.47c-0.17,0.29 -0.16,1.05 0.04,1.5c0.23,0.57 0.72,0.66 0.9,0.18zm-0.24,-4.59c0.23,-0.8 -0.13,-1.61 -0.74,-1.65c-0.18,-0.01 -0.25,0.14 -0.27,0.56c-0.06,0.93 0.04,1.19 0.49,1.34c0.3,0.1 0.43,0.04 0.52,-0.25zm3.85,5.71c-0.03,-2.14 -0.06,-5.35 -0.06,-7.14l0,-3.25l1.17,0.4l1.18,0.4l0,4.63c0,2.54 0.03,4.78 0.06,4.97c0.05,0.27 0.23,0.4 0.88,0.62l0.8,0.28l0,2.16l0,2.17l-1.98,-0.68l-1.98,-0.67l-0.07,-3.89zm4.73,5.35c-0.04,-0.08 -0.07,-3.29 -0.08,-7.14l-0.01,-7l2.32,0.79l2.31,0.79l-0.03,2.1l-0.03,2.1l-0.56,-0.08c-0.54,-0.09 -0.57,-0.06 -0.6,0.49c-0.04,0.7 0.11,0.98 0.62,1.16l0.39,0.13l0,1.02c0,0.56 0.02,1.17 0.06,1.36c0.05,0.28 -0.01,0.32 -0.3,0.22c-0.51,-0.17 -0.89,0.03 -0.89,0.48c0,0.66 0.22,0.95 0.89,1.18l0.65,0.22l-0.03,1.9l-0.03,1.89l-2.31,-0.73c-1.27,-0.4 -2.34,-0.8 -2.37,-0.88z" display="none" fill="#000000" id="path48" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.3"/> + </g> + <g id="g49" transform="matrix(0.99029674,0,0,1,-0.91821266,-0.74835467)"> + <path d="m58.16,220.95c-0.03,-0.61 -0.11,-1.76 -0.16,-2.56c-0.05,-0.81 -0.14,-2.13 -0.2,-2.93c-0.24,-3.66 -0.33,-4.88 -0.42,-5.72c-0.05,-0.49 -0.1,-1.17 -0.1,-1.51l0,-0.62l1.02,0.22c0.98,0.21 1.01,0.23 1.02,0.68c0.01,0.79 0.35,3.22 0.45,3.24c0.1,0.03 0.34,-1.11 0.57,-2.61l0.13,-0.86l0.86,0.24c0.78,0.22 0.88,0.29 0.91,0.67c0.01,0.23 0.07,0.61 0.12,0.85c0.05,0.24 0.16,0.86 0.24,1.38c0.08,0.53 0.19,1 0.25,1.05c0.16,0.14 0.42,-1.21 0.42,-2.14c0,-1.43 0,-1.43 1.23,-1.17l1.1,0.24l-0.09,0.44c-0.05,0.24 -0.15,1.27 -0.21,2.28c-0.19,3.06 -0.31,4.81 -0.41,6.4c-0.06,0.84 -0.13,2.22 -0.16,3.06c-0.03,0.85 -0.11,1.59 -0.18,1.66c-0.06,0.07 -0.67,0.01 -1.35,-0.13c-1.17,-0.25 -1.25,-0.29 -1.25,-0.67c0,-0.22 -0.04,-0.46 -0.1,-0.55c-0.05,-0.08 -0.1,-0.33 -0.1,-0.55c0,-0.22 -0.04,-0.57 -0.09,-0.78c-0.06,-0.21 -0.12,-0.55 -0.15,-0.75c-0.03,-0.21 -0.1,-0.38 -0.16,-0.39c-0.14,-0.04 -0.41,1.12 -0.41,1.75c0,0.3 -0.07,0.73 -0.16,0.96c-0.15,0.4 -0.23,0.41 -1.36,0.17l-1.2,-0.26l-0.06,-1.09zm7.84,2.71c0,-0.03 -0.03,-3.24 -0.06,-7.14l-0.06,-7.08l1.16,0.31l1.15,0.3l0.05,1.25l0.05,1.25l0.46,0.1l0.46,0.1l0.03,-1.29l0.03,-1.28l1.1,0.24l1.1,0.23l0.07,2.34c0.04,1.28 0.05,4.47 0.03,7.07l-0.03,4.74l-1.11,-0.24l-1.12,-0.24l-0.05,-1.35l-0.05,-1.35l-0.36,-0.08l-0.35,-0.08l-0.03,1.39l-0.03,1.38l-1.22,-0.26c-0.66,-0.14 -1.21,-0.28 -1.22,-0.31zm6.2,-5.53c0,-3.8 0,-6.98 0,-7.06c0,-0.09 1.01,0.03 2.23,0.27l2.24,0.42l0,2.16l0,2.16l-0.53,-0.05c-0.36,-0.04 -0.55,0.05 -0.63,0.29c-0.18,0.54 0.05,1.08 0.53,1.26c0.38,0.14 0.42,0.2 0.42,0.71c0.01,0.3 0.03,0.91 0.07,1.34c0.06,0.78 0.06,0.78 -0.28,0.71c-0.53,-0.1 -0.79,0.04 -0.86,0.49c-0.1,0.62 0.21,1.02 0.89,1.17l0.59,0.12l0,1.96l0,1.96l-2.33,-0.5l-2.34,-0.5l0,-6.91zm5.35,7.94c-0.04,-0.09 -0.07,-3.31 -0.07,-7.15l0,-6.98l1.21,0.26l1.2,0.26l0.32,1.36c0.64,2.67 0.82,2.77 0.82,0.42l0,-1.54l1.36,0.3c0.75,0.16 1.39,0.36 1.41,0.45c0.03,0.09 0.08,3.31 0.12,7.15l0.08,6.98l-1.61,-0.4l-1.61,-0.4l-0.35,-1.47c-0.2,-0.81 -0.4,-1.45 -0.46,-1.42c-0.06,0.02 -0.13,0.63 -0.16,1.36l-0.05,1.31l-1.06,-0.16c-0.59,-0.09 -1.1,-0.24 -1.15,-0.33z" display="inline" fill="#000000" id="path50" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + <path d="m30.9,206.39c0,-3.8 0,-6.98 0,-7.06c0,-0.09 1.02,0.16 2.26,0.55l2.25,0.71l0,2.16l0,2.16l-0.53,-0.12c-0.36,-0.08 -0.56,-0.01 -0.64,0.21c-0.18,0.52 0.05,1.09 0.54,1.33c0.33,0.16 0.43,0.29 0.43,0.58c0,0.2 0.03,0.81 0.06,1.35l0.07,0.98l-0.35,-0.12c-0.53,-0.17 -0.8,-0.06 -0.87,0.38c-0.1,0.61 0.21,1.05 0.9,1.28l0.6,0.2l0,1.96l0,1.96l-2.36,-0.8l-2.36,-0.8l0,-6.91zm6.77,7.41c-0.12,-1.04 -0.27,-2.29 -0.32,-2.79c-0.05,-0.5 -0.14,-1.34 -0.2,-1.87c-0.05,-0.53 -0.14,-1.38 -0.2,-1.88c-0.25,-2.38 -0.31,-2.95 -0.51,-4.54c-0.11,-0.93 -0.21,-1.73 -0.21,-1.77c0,-0.04 0.57,0.12 1.27,0.36c1.25,0.43 1.26,0.44 1.38,1c0.06,0.31 0.12,0.72 0.12,0.91c0,0.6 0.33,2.24 0.45,2.2c0.11,-0.04 0.21,-0.72 0.35,-2.3l0.07,-0.9l1.16,0.34l1.16,0.34l-0.05,0.97c-0.02,0.53 -0.13,1.63 -0.22,2.45c-0.18,1.57 -0.29,2.57 -0.47,4.38c-0.06,0.61 -0.15,1.55 -0.21,2.1c-0.05,0.54 -0.14,1.44 -0.19,1.99c-0.18,2.06 -0.04,1.95 -1.69,1.39l-1.46,-0.5l-0.23,-1.88zm5.12,-3.57l0,-7.12l2.25,0.77l2.26,0.77l0,2.15l0,2.16l-0.53,-0.12c-0.37,-0.08 -0.56,-0.02 -0.64,0.2c-0.18,0.53 0.05,1.09 0.54,1.33c0.38,0.19 0.42,0.26 0.42,0.77c0,0.3 0.03,0.91 0.07,1.35c0.06,0.79 0.06,0.79 -0.28,0.68c-0.54,-0.18 -0.8,-0.06 -0.87,0.38c-0.1,0.6 0.21,1.04 0.9,1.28l0.59,0.2l0,1.96l0,1.96l-2.35,-0.8l-2.36,-0.81l0,-7.11zm5.4,8.83c-0.04,-0.1 -0.07,-3.32 -0.07,-7.16l0,-6.97l1.22,0.41l1.22,0.42l0.32,1.39c0.64,2.76 0.82,2.88 0.82,0.53l0,-1.53l1.38,0.46c0.76,0.26 1.4,0.55 1.42,0.64c0.03,0.1 0.08,3.32 0.13,7.17l0.07,6.99l-1.62,-0.61l-1.62,-0.61l-0.36,-1.52c-0.2,-0.83 -0.41,-1.5 -0.47,-1.48c-0.06,0.02 -0.13,0.62 -0.16,1.34l-0.05,1.31l-1.07,-0.3c-0.6,-0.16 -1.11,-0.38 -1.16,-0.48z" display="inline" fill="#000000" id="path30" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + <path d="m154.4,221.88l-0.33,0.03l0,-2.05l0,-2.05l0.66,-0.24c0.63,-0.23 0.67,-0.27 0.67,-0.73c0,-0.3 -0.12,-0.62 -0.33,-0.86c-1.03,-1.2 -1.21,-1.71 -1.21,-3.5c0,-1.33 0.09,-1.78 0.62,-3.12c0.53,-1.36 1.23,-2.04 2.58,-2.53c0.65,-0.23 1.12,-0.31 1.16,-0.2c0.04,0.1 0.09,1.24 0.12,2.53l0.06,2.35l-0.41,0.14c-0.45,0.16 -0.79,0.82 -0.73,1.41c0.02,0.18 0.24,0.49 0.49,0.68c0.65,0.49 0.78,0.71 0.92,1.6c0.13,0.82 0.1,1.21 -0.18,2.53c-0.42,1.96 -1.11,2.88 -2.63,3.52c-0.62,0.26 -1.28,0.48 -1.46,0.49zm5.4,-1.94l-0.35,0.04l0.03,-2.06l0.03,-2.05l0.63,-0.29c0.56,-0.26 0.64,-0.34 0.67,-0.74c0.02,-0.32 -0.07,-0.54 -0.31,-0.76c-1.28,-1.13 -1.64,-3.12 -1.01,-5.58c0.31,-1.19 0.77,-2.09 1.44,-2.8c0.4,-0.43 2.62,-1.3 2.71,-1.07c0.02,0.08 0.06,1.21 0.07,2.5l0.01,2.36l-0.39,0.21c-0.85,0.45 -0.91,1.44 -0.12,2.16c0.64,0.59 0.76,0.83 0.84,1.66c0.17,1.72 -0.33,3.66 -1.25,4.86c-0.39,0.51 -0.7,0.72 -1.56,1.08c-0.59,0.24 -1.24,0.46 -1.44,0.48zm4.82,-8.71l0,-7.13l1.31,-0.41l1.3,-0.42l0.08,4c0.04,2.2 0.07,5.34 0.05,6.99l-0.02,3l-1.36,0.55l-1.36,0.54l0,-7.12zm3.37,5.76c-0.02,-0.09 -0.03,-3.29 -0.01,-7.13l0.03,-6.97l2.26,-0.81c2.53,-0.91 2.59,-0.9 3.2,0.3c0.56,1.13 0.58,3.33 0.03,4.06c-0.35,0.48 -0.36,1.15 -0.01,1.2c0.77,0.12 1.19,3.49 0.7,5.65c-0.08,0.33 -0.29,0.87 -0.47,1.2c-0.33,0.58 -0.4,0.62 -3.02,1.63c-1.47,0.56 -2.69,0.95 -2.71,0.87zm3.34,-4.82c0.2,-0.66 0.2,-0.77 -0.05,-1.17c-0.23,-0.38 -0.71,-0.29 -0.9,0.16c-0.17,0.41 -0.15,1.16 0.04,1.47c0.24,0.4 0.72,0.15 0.91,-0.46zm-0.25,-4.41c0.23,-0.97 -0.13,-1.53 -0.74,-1.14c-0.17,0.12 -0.25,0.32 -0.27,0.76c-0.05,0.96 0.04,1.15 0.49,0.99c0.3,-0.11 0.43,-0.26 0.52,-0.61zm3.86,3.01c-0.04,-2.12 -0.07,-5.31 -0.07,-7.1l0,-3.24l1.18,-0.43l1.17,-0.42l0,4.62c0,2.54 0.03,4.76 0.07,4.93c0.05,0.24 0.22,0.24 0.87,0.01l0.81,-0.29l0,2.17l0,2.16l-1.99,0.72l-1.98,0.71l-0.06,-3.84zm4.72,2.04c-0.04,-0.05 -0.07,-3.24 -0.08,-7.09l-0.01,-6.99l2.32,-0.83l2.31,-0.83l-0.03,2.12l-0.03,2.13l-0.56,0.3c-0.53,0.29 -0.57,0.34 -0.6,0.92c-0.04,0.73 0.11,0.9 0.62,0.72l0.39,-0.13l0,1.01c0,0.56 0.02,1.15 0.06,1.32c0.05,0.24 -0.01,0.33 -0.3,0.43c-0.51,0.19 -0.89,0.65 -0.89,1.1c0,0.66 0.22,0.79 0.9,0.55l0.64,-0.23l-0.02,1.92l-0.03,1.91l-2.32,0.89c-1.27,0.49 -2.34,0.84 -2.37,0.78z" display="inline" fill="#000000" id="path53" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + <path d="m87.35,220.75l0,-7.11l1.27,0.14c0.71,0.08 1.3,0.23 1.34,0.34c0.03,0.12 0.09,3.32 0.12,7.13l0.06,6.92l-1.4,-0.15l-1.39,-0.15l0,-7.12zm4.86,4.4c-0.04,-1.79 -0.1,-3.91 -0.14,-4.71l-0.06,-1.45l-0.64,-0.13l-0.64,-0.13l0,-2.36l0,-2.36l2.7,0.29l2.7,0.3l0.12,1.56c0.06,0.87 0.11,1.93 0.11,2.38l0,0.81l-0.74,-0.02l-0.74,-0.03l0,2.17c0.01,1.19 0.05,3.31 0.1,4.7l0.08,2.54l-1.39,-0.15l-1.39,-0.15l-0.07,-3.26z" display="inline" fill="#000000" id="path49" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + <path d="m129.82,219.91l0,-7.11l1.32,-0.24l1.31,-0.23l0.07,3.12c0.04,1.71 0.07,4.91 0.07,7.1l0,3.99l-1.39,0.24l-1.38,0.25l0,-7.12zm3.38,-0.6l0,-7.12l1.46,-0.2l1.46,-0.2l0.07,0.81c0.17,1.86 0.25,2.4 0.36,2.46c0.15,0.07 0.44,-1.06 0.44,-1.7c0,-0.26 0.06,-0.78 0.13,-1.17l0.12,-0.71l1.36,-0.24l1.37,-0.24l0,7.12l0,7.11l-1.03,0.18l-1.02,0.18l-0.03,-1.59c-0.02,-1.23 -0.06,-1.59 -0.17,-1.57c-0.15,0.03 -0.27,0.71 -0.39,2.18c-0.07,0.93 -0.24,1.16 -0.85,1.2l-0.54,0.03l-0.15,-1c-0.2,-1.35 -0.46,-2.31 -0.59,-2.2c-0.06,0.05 -0.12,0.85 -0.13,1.77l-0.03,1.7l-0.92,0.16l-0.92,0.16l0,-7.12zm7.18,-1.27l0,-7.11l1.68,-0.3c0.93,-0.16 1.71,-0.22 1.74,-0.13c0.03,0.09 0.18,0.2 0.34,0.24c0.4,0.09 0.82,0.73 1.17,1.76c0.27,0.81 0.29,1.04 0.29,2.85c0,1.8 -0.03,2.07 -0.3,3.06c-0.49,1.81 -1.21,3.02 -2.04,3.45c-0.5,0.26 -0.63,0.65 -0.63,1.96l0,0.94l-1.13,0.2l-1.12,0.2l0,-7.12zm3.18,0.03c0.2,-0.39 0.26,-1.26 0.11,-1.71c-0.24,-0.7 -1.07,-0.93 -1.18,-0.32c-0.12,0.62 -0.07,2.53 0.06,2.63c0.22,0.15 0.81,-0.19 1.01,-0.6zm4.9,5.48c-0.69,-0.34 -1.64,-1.83 -1.9,-2.98c-0.08,-0.39 -0.2,-0.86 -0.25,-1.05c-0.12,-0.44 -0.12,-4.56 -0.01,-5.06c0.05,-0.2 0.16,-0.64 0.23,-0.97c0.32,-1.46 1.36,-3.48 1.83,-3.56c0.11,-0.02 0.23,-0.14 0.26,-0.26c0.04,-0.12 0.45,-0.28 0.92,-0.37c0.48,-0.08 0.89,-0.06 0.93,0.05c0.03,0.1 0.13,0.18 0.21,0.16c0.3,-0.05 1.04,1.04 1.37,2.01c0.54,1.59 0.72,2.85 0.72,4.9c0,1.53 -0.04,2.01 -0.26,2.94c-0.14,0.61 -0.31,1.27 -0.38,1.46c-0.16,0.43 -0.95,1.64 -1.35,2.06c-0.37,0.39 -1.95,0.84 -2.32,0.66l0,0.01zm1.38,-5.21c0.37,-0.35 0.62,-1.43 0.46,-2.01c-0.32,-1.21 -0.8,-1.41 -1.19,-0.5c-0.48,1.13 -0.27,2.37 0.46,2.74c0.01,0 0.13,-0.1 0.27,-0.23z" display="inline" fill="#000000" id="path52" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + <path d="m99.4,228.26l-0.34,-0.09l0,-2.05l0,-2.05l0.67,-0.01c0.64,-0.01 0.66,-0.03 0.66,-0.53c0,-0.38 -0.13,-0.7 -0.48,-1.22c-0.83,-1.19 -1.05,-1.94 -1.05,-3.56c0,-0.96 0.05,-1.38 0.29,-2.12c0.39,-1.23 0.61,-1.59 1.26,-2.08c0.76,-0.57 2.69,-0.63 2.84,-0.09c0.05,0.2 0.1,1.36 0.11,2.58l0.02,2.22l-0.4,0c-0.39,0.01 -0.74,0.47 -0.74,0.97c0,0.25 0.44,1.1 0.56,1.1c0.05,0 0.24,0.23 0.42,0.51c0.92,1.39 0.56,4.44 -0.68,5.75c-0.5,0.54 -0.67,0.61 -1.68,0.68c-0.62,0.04 -1.28,0.04 -1.46,-0.01zm4.86,-0.1c-0.02,-0.08 -0.05,-3.29 -0.07,-7.11l-0.02,-6.96l2.32,-0.04l2.31,-0.04l-0.03,2.12l-0.02,2.11l-0.57,0.11c-0.53,0.11 -0.56,0.15 -0.6,0.71c-0.04,0.72 0.11,0.94 0.63,0.94l0.38,-0.01l0,1.02c0,0.56 0.03,1.16 0.06,1.34c0.05,0.26 -0.01,0.33 -0.3,0.33c-0.51,0.01 -0.89,0.35 -0.89,0.79c0,0.66 0.23,0.87 0.9,0.86l0.65,-0.01l-0.03,1.91l-0.03,1.91l-2.32,0.09c-1.28,0.05 -2.35,0.02 -2.37,-0.07zm5.36,-7.05l0,-7.11l2.25,-0.04l2.26,-0.03l0,2.16l0,2.17l-0.5,0c-0.51,0.01 -0.73,0.27 -0.73,0.88c0,0.46 0.3,0.78 0.74,0.77l0.35,0l0.02,1.34l0.02,1.34l-0.39,0c-0.36,0.01 -0.85,0.47 -0.85,0.8c0.01,0.54 0.25,0.77 0.9,0.85c0.57,0.08 0.69,0.16 0.68,0.46c0,0.2 -0.01,1.05 -0.02,1.91l-0.02,1.54l-2.36,0.04l-2.35,0.04l0,-7.12zm5.4,6.9c-0.04,-0.08 -0.08,-3.28 -0.08,-7.13l0,-6.98l1.46,0.03l1.45,0.04l0.14,1.03c0.08,0.56 0.18,1.3 0.22,1.63c0.04,0.33 0.12,0.63 0.18,0.67c0.13,0.09 0.45,-1.25 0.45,-1.9c0,-0.27 0.04,-0.73 0.1,-1.02l0.1,-0.53l1.33,-0.03l1.34,-0.02l0.01,2.01c0,1.11 0.01,4.29 0.02,7.07l0.02,5.05l-1.03,0.02l-1.02,0.01l0.03,-0.5c0.02,-0.27 0.01,-0.99 -0.03,-1.6c-0.07,-1.19 -0.3,-1.49 -0.39,-0.52c-0.11,1.14 -0.33,2.43 -0.43,2.58c-0.06,0.09 -0.33,0.16 -0.62,0.17l-0.51,0.01l-0.19,-1.29c-0.22,-1.44 -0.46,-2.31 -0.59,-2.06c-0.04,0.09 -0.09,0.86 -0.11,1.71l-0.03,1.55l-0.88,0.07c-0.48,0.04 -0.9,0.01 -0.94,-0.07zm7.74,-0.13l-0.33,-0.09l0,-2.05l0,-2.05l0.66,-0.01c0.62,-0.01 0.67,-0.04 0.67,-0.48c0,-0.31 -0.16,-0.69 -0.48,-1.17c-0.26,-0.4 -0.62,-1.07 -0.79,-1.5c-0.27,-0.67 -0.32,-0.96 -0.32,-1.96c0,-0.68 0.08,-1.48 0.18,-1.93c0.23,-0.96 1.05,-2.45 1.36,-2.46c0.13,0 0.27,-0.1 0.3,-0.21c0.08,-0.24 2.48,-0.33 2.55,-0.09c0.02,0.08 0.06,1.22 0.08,2.52l0.04,2.37l-0.41,0.08c-0.79,0.14 -0.92,1.1 -0.26,1.97c0.22,0.3 0.44,0.54 0.49,0.54c0.04,-0.01 0.17,0.2 0.28,0.45c0.32,0.72 0.29,2.91 -0.05,3.87c-0.31,0.89 -0.44,1.11 -1.03,1.7c-0.37,0.36 -0.67,0.47 -1.53,0.52c-0.59,0.04 -1.23,0.03 -1.41,-0.02z" display="inline" fill="#000000" id="path51" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + </g> + <g id="g47" transform="matrix(0.99029674,0,0,1,0.93452033,-0.74835467)"> + <path d="m161.09,195.19l0,-6.46l1.99,-0.71c1.09,-0.39 2.11,-0.67 2.26,-0.61c0.15,0.05 0.41,0.43 0.58,0.83c0.25,0.6 0.31,0.94 0.31,1.83c0,0.97 -0.04,1.15 -0.3,1.64c-0.34,0.64 -0.32,1.1 0.06,1.23c0.44,0.16 0.64,1.09 0.64,2.97c0,1.66 -0.01,1.71 -0.36,2.57c-0.35,0.87 -0.36,0.88 -1.24,1.25c-0.49,0.2 -1.58,0.72 -2.42,1.14l-1.52,0.78l0,-6.46zm2.8,2.01c0.44,-0.83 0.18,-1.69 -0.4,-1.33c-0.29,0.18 -0.34,0.3 -0.37,0.83c-0.02,0.42 0.02,0.69 0.14,0.82c0.24,0.25 0.35,0.19 0.63,-0.32zm-0.07,-4.28c0.16,-0.79 -0.03,-1.13 -0.53,-0.92c-0.38,0.16 -0.39,0.19 -0.39,0.85c0,0.86 0.05,0.94 0.47,0.76c0.26,-0.1 0.37,-0.26 0.45,-0.69zm10.47,2.97c-0.2,-0.01 -0.5,-0.13 -0.68,-0.27c-0.34,-0.26 -0.83,-1.38 -0.83,-1.87c0,-0.15 -0.05,-0.36 -0.12,-0.46c-0.15,-0.25 -0.16,-4.13 -0.01,-4.83c0.06,-0.29 0.18,-0.91 0.28,-1.39c0.39,-1.98 1.4,-3.81 2.3,-4.19c0.94,-0.39 1.89,0.65 2.02,2.21c0.03,0.4 0.09,0.98 0.12,1.28l0.07,0.54l-0.87,0.36c-0.75,0.31 -0.88,0.32 -0.97,0.01c-0.13,-0.47 -0.45,-0.53 -0.7,-0.14c-0.5,0.76 -0.68,3.53 -0.31,4.63c0.18,0.51 0.26,0.57 0.53,0.4c0.26,-0.16 0.37,-0.38 0.56,-1.17l0.24,-0.98l0.76,-0.32c0.74,-0.31 0.76,-0.3 0.69,0.18c-0.03,0.27 -0.09,0.78 -0.12,1.13c-0.12,1.42 -0.58,3.04 -1.06,3.72c-0.37,0.54 -1.4,1.16 -1.9,1.16zm3.6,-1.46c-0.04,-0.07 -0.07,-2.93 -0.07,-6.37l0,-6.26l0.95,-0.4c0.94,-0.39 0.96,-0.39 0.96,0.08c0,0.67 0.24,1.17 0.44,0.92c0.1,-0.11 0.27,-0.57 0.38,-1.02l0.21,-0.81l0.9,-0.38l0.89,-0.37l0,0.81c0,1.04 -0.27,2.41 -0.79,4.05c-0.23,0.72 -0.42,1.37 -0.42,1.45c0,0.08 0.2,0.54 0.45,1.02c0.44,0.87 0.63,1.64 0.85,3.41c0.22,1.79 0.26,1.7 -0.97,2.2l-1.08,0.45l-0.15,-0.6c-0.11,-0.44 -0.22,-0.57 -0.41,-0.5c-0.21,0.09 -0.26,0.23 -0.3,0.85l-0.05,0.75l-0.86,0.41c-0.47,0.23 -0.89,0.37 -0.93,0.31zm-10.62,3.07c0.15,-3.17 0.25,-4.99 0.35,-6.28c0.06,-0.76 0.16,-2.27 0.23,-3.35l0.13,-1.96l1.64,-0.68c1.62,-0.68 1.65,-0.68 1.65,-0.24c0,0.25 0.04,0.72 0.09,1.04c0.05,0.33 0.15,1.13 0.21,1.78c0.07,0.66 0.18,1.58 0.26,2.05c0.08,0.47 0.14,1.11 0.14,1.42c0,0.31 0.05,0.61 0.1,0.66c0.06,0.04 0.1,0.48 0.1,0.96c0,0.48 0.04,0.94 0.09,1.03c0.05,0.09 0.12,0.52 0.14,0.96c0.03,0.44 0.09,1 0.13,1.24c0.07,0.43 0.06,0.44 -1,0.88l-1.06,0.44l-0.06,-0.74c-0.04,-0.42 -0.07,-0.89 -0.08,-1.05c-0.02,-0.2 -0.16,-0.27 -0.39,-0.21c-0.36,0.08 -0.38,0.13 -0.48,0.92c-0.06,0.46 -0.11,0.99 -0.11,1.19c0,0.32 -0.12,0.41 -1.07,0.81l-1.07,0.45l0.06,-1.32zm2.95,-4.17c0.03,-0.18 0.02,-0.66 -0.03,-1.07c-0.07,-0.6 -0.14,-0.73 -0.36,-0.69c-0.22,0.04 -0.3,0.17 -0.38,0.64c-0.14,0.8 -0.13,1.54 0.03,1.6c0.27,0.11 0.69,-0.16 0.74,-0.48z" fill="#000000" id="path41" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + <path d="m121.93,209.81c-0.04,-0.07 -0.11,-2.95 -0.17,-6.39l-0.1,-6.25l1.78,-0.28l1.78,-0.27l0.03,1.65c0.02,0.9 0.03,1.72 0.03,1.8c0.01,0.09 -0.19,0.23 -0.44,0.33c-0.39,0.15 -0.45,0.24 -0.47,0.68c-0.03,0.68 0.22,1.01 0.73,0.93l0.4,-0.06l0.02,1l0.01,1l-0.58,0.28l-0.59,0.27l0.02,2.53l0.01,2.53l-1.2,0.19c-0.66,0.1 -1.23,0.13 -1.26,0.06zm4.65,-0.74l-0.58,0.02l-0.13,-6.28l-0.13,-6.27l1.05,-0.16l1.04,-0.17l0.17,6.16c0.09,3.39 0.14,6.27 0.11,6.39c-0.06,0.23 -0.28,0.28 -1.53,0.31zm6.28,-1.16c-0.19,-0.25 -0.26,-0.26 -0.4,-0.04c-0.21,0.32 -1.51,0.56 -1.76,0.33c-0.09,-0.09 -0.32,-0.3 -0.52,-0.48c-0.52,-0.47 -1.13,-1.72 -1.4,-2.86c-0.43,-1.84 -0.34,-5.15 0.19,-6.89c0.26,-0.84 1.03,-1.83 1.62,-2.1c0.8,-0.37 1.89,0.32 2.51,1.58c0.36,0.73 0.91,2.69 0.81,2.92c-0.03,0.08 -0.49,0.19 -1.02,0.25c-0.72,0.09 -0.99,0.04 -1.07,-0.17c-0.06,-0.16 -0.24,-0.32 -0.39,-0.36c-0.22,-0.06 -0.35,0.05 -0.55,0.48c-0.25,0.52 -0.26,0.65 -0.24,2.14c0.02,1.47 0.04,1.61 0.3,2.04c0.38,0.64 0.69,0.71 1.07,0.25c0.24,-0.3 0.31,-0.5 0.28,-0.84c-0.03,-0.35 -0.11,-0.47 -0.34,-0.48c-0.25,-0.01 -0.31,-0.1 -0.32,-0.52l0,-0.5l1.15,-0.18c0.64,-0.1 1.18,-0.14 1.2,-0.1c0.02,0.04 0.04,1.32 0.04,2.84l0,2.76l-0.47,0.11c-0.31,0.08 -0.54,0.02 -0.69,-0.18zm2.26,-0.15l-0.49,0l-0.1,-5.82c-0.05,-3.2 -0.12,-6.02 -0.16,-6.27c-0.06,-0.45 -0.05,-0.46 0.83,-0.59l0.89,-0.14l0.08,0.95c0.12,1.42 0.15,1.5 0.55,1.43l0.36,-0.05l0.01,-1.26l0,-1.26l0.92,-0.17l0.91,-0.18l0.03,1.67c0.02,0.92 0.09,3.77 0.17,6.33l0.13,4.67l-0.94,0.14l-0.95,0.15l-0.05,-1.08l-0.05,-1.08l-0.32,0.05l-0.33,0.05l-0.03,1.14l-0.03,1.15l-0.47,0.09c-0.26,0.05 -0.69,0.08 -0.96,0.08zm5.81,-3.57c-0.05,-1.54 -0.11,-3.39 -0.12,-4.09c-0.03,-1.45 -0.07,-1.53 -0.73,-1.43c-0.5,0.07 -0.52,-0.02 -0.56,-2.41l-0.03,-1.84l2.25,-0.35c1.23,-0.19 2.26,-0.28 2.29,-0.2c0.02,0.08 0.07,0.98 0.11,2l0.06,1.85l-0.52,0.21c-0.29,0.11 -0.58,0.29 -0.65,0.39c-0.09,0.14 -0.09,0.84 0,3.18c0.06,1.65 0.14,3.49 0.18,4.08l0.08,1.07l-1.13,0.17l-1.12,0.18l-0.11,-2.81zm4.33,2.01l-0.59,0.01l-0.1,-6.28l-0.11,-6.28l1.03,-0.16l1.02,-0.16l0.11,2.93c0.06,1.61 0.12,4.47 0.14,6.34l0.02,3.41l-0.47,0.09c-0.25,0.05 -0.73,0.09 -1.05,0.1zm2.07,-3.98c-0.06,-1.9 -0.14,-4.74 -0.16,-6.31l-0.05,-2.85l0.96,-0.15c0.53,-0.08 1.01,-0.08 1.07,-0.01c0.05,0.08 0.22,0.65 0.38,1.28c0.38,1.56 0.52,1.48 0.57,-0.35l0.05,-1.45l1.04,-0.03c0.58,-0.02 1.08,0.02 1.11,0.09c0.04,0.06 0.12,2.83 0.2,6.15l0.13,6.03l-1.32,0.15l-1.32,0.14l-0.25,-1.04c-0.33,-1.39 -0.49,-1.34 -0.47,0.12l0.02,1.14l-0.5,0.07c-0.28,0.05 -0.69,0.17 -0.92,0.27l-0.42,0.19l-0.12,-3.44zm9.91,0.56c-0.14,-0.28 -0.2,-0.28 -0.35,-0.05c-0.23,0.36 -1.44,0.55 -1.87,0.28c-0.78,-0.48 -1.59,-1.88 -1.89,-3.29c-0.18,-0.84 -0.28,-4.9 -0.13,-5.13c0.05,-0.08 0.09,-0.31 0.08,-0.5c0,-0.52 0.59,-2.13 0.93,-2.53c0.61,-0.7 1.03,-0.95 1.54,-0.92c0.99,0.08 2.01,1.4 2.5,3.25c0.39,1.49 0.37,1.53 -0.72,1.62c-0.78,0.06 -1.01,0 -1.22,-0.3c-0.68,-0.98 -1.32,0.8 -1.11,3.1c0.17,1.89 1.21,2.58 1.62,1.08c0.13,-0.48 0.13,-0.58 0.01,-0.72c-0.07,-0.09 -0.25,-0.15 -0.4,-0.13c-0.22,0.03 -0.26,-0.04 -0.24,-0.43c0.02,-0.46 0.05,-0.47 1.2,-0.65l1.17,-0.18l0.05,1.54c0.03,0.85 0.04,2.13 0.02,2.84l-0.04,1.3l-0.49,0.08c-0.34,0.05 -0.54,-0.03 -0.66,-0.26z" fill="#000000" id="path42" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + <path d="m95.76,210.32c-0.04,-0.08 -0.07,-0.73 -0.07,-1.44c0,-0.71 -0.04,-1.35 -0.09,-1.41c-0.13,-0.16 -0.38,0.9 -0.46,1.95l-0.07,0.84l-0.57,-0.06c-0.53,-0.06 -0.58,-0.1 -0.66,-0.68c-0.2,-1.31 -0.41,-2.18 -0.51,-2.11c-0.06,0.04 -0.12,0.69 -0.14,1.45l-0.03,1.38l-0.8,-0.01l-0.8,0l0,-6.29l0,-6.29l1.25,0l1.24,0.01l0.07,0.67c0.04,0.37 0.09,1.01 0.12,1.43c0.03,0.42 0.12,0.81 0.2,0.87c0.2,0.15 0.44,-0.43 0.44,-1.06c0,-0.3 0.06,-0.85 0.13,-1.22l0.12,-0.69l1.14,0.01l1.14,0l-0.03,6.34l-0.03,6.34l-0.76,0.06c-0.42,0.03 -0.79,-0.01 -0.83,-0.09zm2.22,0c-0.04,-0.07 -0.07,-2.95 -0.07,-6.4l0,-6.25l2.01,0l2.02,0.01l0,1.96l0,1.96l-0.43,0c-0.54,0 -0.71,0.22 -0.66,0.84c0.03,0.42 0.1,0.51 0.46,0.56l0.43,0.07l0,1.19l0,1.2l-0.42,0.12c-0.47,0.12 -0.62,0.45 -0.48,1.01c0.08,0.3 0.23,0.37 0.75,0.37c0.59,0 0.65,0.04 0.65,0.43c0,0.85 0.25,0.25 0.28,-0.65c0.01,-0.5 0.09,-1.89 0.17,-3.08c0.08,-1.19 0.2,-3.02 0.27,-4.07l0.13,-1.91l1.64,0.01c1.62,0 1.64,0.01 1.64,0.45c0,0.25 0.05,0.74 0.1,1.09c0.1,0.66 0.47,3.92 0.62,5.43c0.05,0.48 0.14,1.31 0.2,1.85c0.05,0.54 0.14,1.4 0.19,1.91c0.05,0.51 0.12,1.14 0.16,1.39c0.07,0.46 0.06,0.47 -0.95,0.47c-1.11,-0.01 -1.13,-0.03 -1.22,-1.35c-0.05,-0.78 -0.07,-0.83 -0.42,-0.89c-0.36,-0.06 -0.38,-0.02 -0.48,0.72c-0.06,0.43 -0.11,0.95 -0.11,1.15c0,0.32 -0.12,0.36 -1.06,0.36l-1.06,-0.01l-0.01,-0.67c0,-0.37 -0.04,-0.9 -0.08,-1.18c-0.1,-0.66 -0.19,-0.26 -0.23,1.03l-0.03,0.92l-1.97,0.05c-1.09,0.03 -2,-0.01 -2.04,-0.09zm7.35,-4.27c0.03,-0.17 0.02,-0.66 -0.03,-1.09c-0.08,-0.63 -0.14,-0.78 -0.37,-0.84c-0.21,-0.05 -0.29,0.05 -0.37,0.48c-0.14,0.74 -0.13,1.49 0.03,1.62c0.26,0.22 0.68,0.12 0.74,-0.17zm3.03,4.32c-0.04,-0.09 -0.07,-2.93 -0.07,-6.31l0,-6.15l1.05,0c0.71,0 1.07,0.08 1.14,0.26c0.2,0.5 0.53,1.82 0.53,2.12c0,0.17 0.09,0.31 0.2,0.31c0.18,0 0.2,-0.14 0.21,-0.98c0,-1.98 -0.04,-1.93 1.24,-1.78c0.62,0.08 1.15,0.19 1.19,0.27c0.04,0.07 0.09,2.84 0.1,6.16l0.03,6.04l-1.41,-0.06l-1.41,-0.06l-0.25,-1.08c-0.36,-1.54 -0.6,-1.4 -0.6,0.37l0,0.81l-0.49,0c-0.27,0 -0.69,0.05 -0.94,0.12c-0.24,0.06 -0.47,0.05 -0.52,-0.04zm6.9,-0.02c-0.52,-0.06 -0.63,-0.13 -0.58,-0.39c0.03,-0.17 0.06,-1 0.06,-1.84l0,-1.53l0.55,0c0.48,0 0.56,-0.05 0.56,-0.39c0,-0.46 -0.19,-0.88 -0.59,-1.38c-0.15,-0.18 -0.41,-0.75 -0.56,-1.26c-0.25,-0.8 -0.28,-1.05 -0.23,-1.98c0.07,-1.2 0.48,-2.52 0.94,-3.05c0.5,-0.57 1.33,-0.87 2.07,-0.74c0.38,0.07 0.72,0.17 0.77,0.23c0.04,0.05 0.08,1.01 0.07,2.12l0,2.03l-0.29,0.06c-0.72,0.17 -0.75,1.29 -0.05,2.05c0.77,0.86 0.99,2.17 0.6,3.72c-0.48,1.94 -1.38,2.58 -3.32,2.36l0,-0.01z" fill="#000000" id="path43" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + <path d="m68.45,206.75l-0.58,-0.17l0,-6.28l0,-6.28l0.96,0.15l0.96,0.15l0,0.99c0,1.17 0.12,1.51 0.57,1.58c0.37,0.06 0.49,-0.4 0.42,-1.68l-0.04,-0.71l0.99,0.09c0.55,0.05 1.02,0.13 1.04,0.18c0.02,0.06 0.04,2.91 0.04,6.35l0,6.26l-1,-0.16l-1,-0.16l-0.03,-1.08l-0.04,-1.09l-0.35,-0.06l-0.35,-0.05l-0.05,1.13l-0.05,1.12l-0.46,-0.05c-0.24,-0.03 -0.71,-0.13 -1.03,-0.23zm4.95,-5.41c-0.03,-3.49 -0.04,-6.37 -0.04,-6.4c0.01,-0.02 0.92,0.09 2.03,0.25l2.01,0.29l0,1.93l0,1.92l-0.51,0.03c-0.48,0.02 -0.5,0.05 -0.5,0.64c0,0.58 0.03,0.63 0.43,0.75l0.44,0.13l-0.03,1.16l-0.03,1.16l-0.41,0.11c-0.49,0.13 -0.59,0.31 -0.51,0.88c0.06,0.39 0.15,0.46 0.73,0.55l0.66,0.1l-0.08,0.76c-0.04,0.42 -0.1,1.18 -0.13,1.68l-0.06,0.92l-1.98,-0.25l-1.98,-0.26l-0.04,-6.35zm5.6,7.06l-0.92,-0.21l-0.06,-2.94c-0.1,-4.53 -0.08,-9.19 0.04,-9.32c0.05,-0.07 0.62,-0.09 1.25,-0.06c1.53,0.09 2.29,0.64 2.9,2.12c0.24,0.6 0.51,2.66 0.43,3.39c-0.03,0.34 -0.09,0.94 -0.12,1.33c-0.03,0.38 -0.14,1 -0.25,1.36c-0.21,0.73 -0.23,1.09 -0.1,1.64c0.21,0.86 0.52,2.78 0.52,3.19c0,0.18 -0.25,0.2 -0.93,0.05l-0.93,-0.21l-0.11,-0.78c-0.12,-0.9 -0.38,-1.58 -0.54,-1.4c-0.06,0.07 -0.11,0.53 -0.11,1.03c0,0.5 -0.04,0.93 -0.08,0.96c-0.04,0.02 -0.49,-0.04 -0.99,-0.16l0,0.01zm1.68,-5.21c0.43,-0.61 0.33,-1.83 -0.19,-2.35c-0.54,-0.55 -0.62,-0.4 -0.62,1.14l0,1.35l0.32,0.05c0.18,0.02 0.4,-0.06 0.49,-0.19zm4.63,6.22c-0.78,-0.4 -1.59,-1.85 -1.98,-3.56c-0.2,-0.88 -0.24,-1.38 -0.24,-2.95c0,-2.12 0.1,-2.79 0.63,-4.12c0.42,-1.03 0.97,-1.6 1.79,-1.82c1.87,-0.49 3.33,2.78 3.33,7.44c0,2.3 -0.55,4 -1.54,4.79c-0.43,0.34 -1.52,0.46 -1.99,0.22zm1.16,-4.54c0.23,-0.41 0.27,-0.6 0.22,-1.23c-0.14,-1.76 -1.12,-1.93 -1.33,-0.23c-0.06,0.45 -0.01,0.68 0.23,1.23c0.38,0.82 0.52,0.85 0.88,0.23z" fill="#000000" id="path44" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + <path d="m59.8,203.26c0.03,-0.65 0.13,-2.23 0.22,-3.51c0.09,-1.28 0.2,-3.06 0.25,-3.96c0.06,-0.89 0.13,-2.1 0.16,-2.69l0.07,-1.07l1.65,0.41c1.63,0.41 1.65,0.42 1.65,0.86c0,0.25 0.04,0.75 0.1,1.11c0.15,0.99 0.52,4.38 0.57,5.21c0.03,0.41 0.09,0.93 0.14,1.17c0.04,0.24 0.11,0.76 0.13,1.17c0.05,0.7 0.18,1.94 0.33,3.22l0.06,0.59l-1.01,-0.25c-1.12,-0.28 -1.14,-0.31 -1.22,-1.65c-0.06,-0.78 -0.08,-0.85 -0.42,-0.99c-0.34,-0.14 -0.37,-0.11 -0.48,0.63c-0.06,0.43 -0.12,0.93 -0.12,1.11c0,0.29 -0.14,0.3 -1.07,0.07l-1.07,-0.26l0.06,-1.17zm3.02,-2.27c0.03,-0.15 0,-0.65 -0.08,-1.1c-0.17,-1.06 -0.55,-1.36 -0.74,-0.57c-0.15,0.66 -0.15,1.45 0.01,1.62c0.26,0.28 0.76,0.31 0.81,0.05z" fill="#000000" id="path45" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + <path d="m28.53,184.36l0,-10.76l3.34,1c2.1,0.63 3.36,1.1 3.41,1.26c0.03,0.15 0.16,0.29 0.27,0.32c0.25,0.08 1.05,2.07 1.34,3.22c0.05,0.21 0.09,0.39 0.1,0.53c0.04,0.41 0.12,0.82 0.17,0.9c0.14,0.23 0.12,2.14 -0.03,2.8c-0.07,0.3 -0.33,0.78 -0.57,1.05c-0.44,0.51 -0.55,0.88 -0.29,0.96c0.32,0.09 1,1.56 1.26,2.69c0.42,1.89 0.52,3.61 0.31,5.56c-0.16,1.52 -0.46,2.34 -1.07,2.88c-0.47,0.42 -0.53,0.41 -4.36,-0.61l-3.88,-1.04l0,-10.76zm4.85,6.52c0.36,-0.16 0.17,-1.46 -0.05,-1.98c-0.12,-0.3 -0.34,-0.46 -0.7,-0.52c-0.52,-0.09 -0.53,-0.08 -0.56,0.81c-0.02,0.5 -0.01,1.06 0.02,1.25c0.08,0.44 0.94,0.59 1.29,0.44zm-0.6,-6.57c0.34,-0.22 0.47,-0.99 0.29,-1.74c-0.14,-0.62 -0.49,-0.95 -1.04,-1.01c-0.36,-0.04 -0.38,0.02 -0.42,0.94c-0.02,0.79 0.02,1.05 0.23,1.43c0.31,0.54 0.55,0.64 0.94,0.38zm6.08,7.48c-0.04,-3.44 -0.05,-6.28 -0.04,-6.31c0.06,-0.1 3.81,1.03 3.83,1.16c0.02,0.07 0.03,0.95 0.03,1.95l0,1.83l-0.43,-0.13c-0.31,-0.09 -0.46,-0.04 -0.53,0.19c-0.15,0.53 0.04,1.09 0.43,1.2c0.33,0.1 0.33,0.12 0.35,1.02c0.01,0.51 0.02,1.03 0.02,1.17c0.01,0.14 -0.15,0.26 -0.36,0.27c-0.43,0.02 -0.58,0.23 -0.53,0.77c0.03,0.32 0.14,0.43 0.7,0.64l0.66,0.27l-0.07,0.62c-0.04,0.35 -0.1,1.08 -0.14,1.63l-0.05,1l-1.9,-0.52l-1.9,-0.52l-0.07,-6.24zm5.05,7.59l-0.65,-0.27l0,-6.19l0,-6.18l1.11,0.33l1.12,0.34l0.02,5.19c0.01,2.85 0.02,5.66 0.02,6.25l0.01,1.07l-0.49,-0.14c-0.26,-0.07 -0.78,-0.25 -1.14,-0.4zm2.16,-5.38l0,-6.22l1.03,0.36l1.03,0.37l0.3,1.36c0.41,1.82 0.59,1.81 0.62,-0.02l0.03,-1.37l1.14,0.48c0.62,0.26 1.15,0.51 1.17,0.55c0.01,0.03 0.05,2.77 0.08,6.09l0.06,6.02l-1.35,-0.41l-1.36,-0.4l-0.27,-1.21c-0.15,-0.67 -0.32,-1.19 -0.38,-1.17c-0.06,0.02 -0.13,0.51 -0.14,1.09l-0.03,1.04l-0.52,-0.16c-0.28,-0.08 -0.71,-0.16 -0.96,-0.16l-0.45,-0.01l0,-6.23zm10.25,8.93c-0.19,-0.32 -0.2,-0.38 -0.36,-0.22c-0.22,0.22 -1.57,-0.13 -1.82,-0.48c-0.09,-0.13 -0.34,-0.45 -0.54,-0.72c-0.51,-0.68 -1.1,-2.09 -1.38,-3.35c-0.44,-1.97 -0.29,-5.19 0.31,-6.73c0.27,-0.7 1.08,-1.31 1.7,-1.3c0.83,0.01 1.94,1.19 2.56,2.71c0.34,0.83 0.87,3.06 0.78,3.24c-0.03,0.05 -0.5,-0.06 -1.05,-0.25c-0.75,-0.25 -1.03,-0.41 -1.11,-0.66c-0.06,-0.18 -0.23,-0.42 -0.39,-0.54c-0.22,-0.15 -0.36,-0.1 -0.57,0.22c-0.27,0.4 -0.29,0.51 -0.29,1.98c0,1.46 0.02,1.6 0.27,2.13c0.39,0.81 0.71,1.03 1.11,0.75c0.25,-0.18 0.33,-0.34 0.3,-0.7c-0.02,-0.35 -0.1,-0.5 -0.34,-0.62c-0.26,-0.13 -0.32,-0.24 -0.32,-0.65l0,-0.5l1.21,0.37c0.66,0.2 1.22,0.43 1.24,0.52c0.02,0.09 0.01,1.35 -0.02,2.79l-0.05,2.62l-0.54,-0.1c-0.4,-0.08 -0.53,-0.22 -0.7,-0.51z" fill="#000000" id="path46" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.31"/> + </g> + </g> + <g id="layer2" transform="translate(-0.102043 -0.095704) scale(1.0004 1) translate(0.102043 0.095704) translate(-0.102545 -0.0962265) matrix(3.10588 0 0 3.11801 -14.1132 -4.2289)"> + <ellipse cx="104.21" cy="116.26" display="none" fill="#000000" fill-opacity="0.31" id="path2" rx="75.99" ry="73.13" stroke-linecap="round" stroke-linejoin="round" stroke-width="4.7"/> + <text display="none" fill="#000000" font-family="Arial" font-size="37.33px" font-style="normal" font-weight="900" id="text2" stroke-linecap="round" stroke-linejoin="round" stroke-width="18.23" transform="matrix(0.26815815,0,0,0.24784657,153.10668,-184.14648)" xml:space="preserve"> + <tspan fill="#000000" id="tspan1" x="245.46" y="828.83">Being a hero means fighting back</tspan> + <tspan fill="#000000" id="tspan2" x="268.97" y="888.56">even when it seems impossible</tspan> + </text> + <path d="m86.6,161.72c-0.94,-0.09 -1.89,-0.39 -2.63,-0.83c-0.25,-0.16 -0.29,-0.27 -0.15,-0.49c0.11,-0.19 0.34,-0.54 0.44,-0.67c0.05,-0.06 0.09,-0.12 0.09,-0.14c0,-0.01 -0.15,-0.28 -0.33,-0.58l-0.33,-0.56l-0.49,-0.16c-1.15,-0.39 -2.17,-0.65 -3.04,-0.78c-0.4,-0.06 -1.07,-0.08 -1.31,-0.03c-0.19,0.03 -0.4,0.11 -0.4,0.15c0,0.05 0.19,0.22 0.31,0.28c0.19,0.1 0.4,0.16 0.79,0.23c0.64,0.1 0.97,0.23 1.19,0.45c0.48,0.48 0.11,1.11 -0.76,1.34c-0.34,0.08 -0.47,0.1 -0.9,0.1c-0.9,0 -1.65,-0.22 -2.58,-0.75c-1.11,-0.63 -1.98,-0.96 -2.93,-1.11c-0.33,-0.05 -0.96,-0.06 -1.27,-0.02c-0.25,0.03 -0.56,0.1 -0.59,0.13c-0.01,0.01 -0.03,0.12 -0.05,0.25c-0.02,0.17 -0.05,0.28 -0.08,0.35c-0.1,0.2 -0.41,0.44 -0.85,0.66c-0.22,0.11 -0.76,0.32 -0.77,0.31c-0.01,-0.01 0,-0.27 0.02,-0.59c0.01,-0.31 0.02,-0.58 0.01,-0.59c-0.01,0 -0.07,0.02 -0.13,0.05l-0.13,0.06l-0.01,0.11c0,0.06 -0.01,0.32 -0.02,0.57c-0.01,0.3 -0.02,0.47 -0.04,0.48c-0.01,0.01 -0.13,0.04 -0.26,0.08c-0.71,0.19 -1.51,0.32 -2.17,0.36l-0.25,0.01l0,-0.53l0,-0.53l-0.13,0c-0.07,0 -0.14,0 -0.17,-0.01c-0.04,-0.01 -0.04,-0.01 -0.05,0.54l-0.02,0.55l-0.37,-0.01c-0.62,-0.03 -1.13,-0.09 -1.65,-0.2c-0.31,-0.07 -0.75,-0.2 -0.79,-0.23c-0.03,-0.02 -0.04,-0.14 -0.05,-0.63l-0.01,-0.62l-0.12,-0.06c-0.07,-0.03 -0.13,-0.05 -0.13,-0.05c-0.01,0.01 0,0.27 0.01,0.59c0.02,0.32 0.02,0.61 0.02,0.63c-0.01,0.04 -0.02,0.04 -0.23,-0.05c-0.52,-0.24 -1.28,-0.74 -1.36,-0.92c-0.06,-0.12 -0.14,-0.88 -0.12,-1.17c0,-0.12 0.02,-0.18 0.07,-0.29c0.08,-0.16 0.29,-0.39 0.49,-0.54l0.14,-0.1l0,-6.46l0,-6.47l-0.25,-0.13c-0.23,-0.11 -0.26,-0.14 -0.29,-0.2c-0.03,-0.06 -0.04,-0.16 -0.04,-0.64l0,-0.57l0.06,-0.1c0.22,-0.39 1.04,-0.78 2.23,-1.07c0.16,-0.04 0.3,-0.07 0.3,-0.07c0.01,0.01 0.05,0.47 0.05,0.54c0,0.06 0,0.06 -0.21,0.12c-0.78,0.2 -1.49,0.53 -1.57,0.73c-0.05,0.14 0.17,0.28 0.64,0.42l0.16,0.04l0.04,0.57c0.02,0.31 0.03,0.61 0.03,0.66l0,0.1l-0.06,-0.02c-0.1,-0.02 -0.54,-0.15 -0.69,-0.21l-0.14,-0.06l0.01,6.34c0,3.49 0.01,6.35 0.02,6.35c0.01,0.01 0.1,-0.01 0.21,-0.04c0.47,-0.12 0.95,-0.17 1.49,-0.17l0.31,0l-0.18,0.04c-0.51,0.11 -1.15,0.42 -1.69,0.82l-0.15,0.11l0,0.15l0,0.14l0.19,0.19c0.7,0.69 2.02,1.11 3.63,1.15c1.08,0.03 2.1,-0.12 2.85,-0.43c0.54,-0.22 0.93,-0.53 1.09,-0.86c0.06,-0.13 0.07,-0.17 0.07,-0.31l0,-0.15l-0.12,-0.09c-0.51,-0.39 -1.22,-0.74 -1.71,-0.83c-0.09,-0.02 -0.16,-0.04 -0.17,-0.04c-0.01,-0.01 0.35,0 0.8,0.02c0.27,0.01 0.57,0.06 0.91,0.13c0.15,0.04 0.28,0.06 0.28,0.06c0.02,-0.02 0.02,-12.62 0,-12.62c-0.01,0 -0.12,0.03 -0.25,0.07c-0.12,0.04 -0.23,0.07 -0.23,0.07c-0.01,-0.01 0.06,-1.31 0.07,-1.32c0,0 0.07,-0.04 0.14,-0.08c0.08,-0.04 0.18,-0.11 0.22,-0.16c0.17,-0.16 0.08,-0.29 -0.31,-0.49c-0.26,-0.12 -0.54,-0.23 -0.88,-0.32c-0.13,-0.03 -0.24,-0.06 -0.24,-0.06c-0.01,-0.01 0.03,-0.42 0.05,-0.5c0.01,-0.04 0.01,-0.04 0.09,-0.03c0.19,0.03 0.74,0.18 0.99,0.26c0.61,0.22 1.11,0.52 1.23,0.77c0.05,0.09 0.08,0.33 0.08,0.66c0,0.3 -0.02,0.42 -0.09,0.59c-0.07,0.15 -0.17,0.23 -0.4,0.34l-0.17,0.09l-0.01,6.39c-0.02,5.96 -0.02,6.39 0.02,6.41c0.16,0.1 0.41,0.29 0.54,0.43c0.21,0.2 0.27,0.33 0.27,0.51c0,0.11 0.01,0.12 0.04,0.11c0.02,0 0.14,-0.03 0.28,-0.05c0.34,-0.06 0.97,-0.07 1.36,-0.03c1.11,0.13 2.07,0.48 3.38,1.22c0.52,0.3 0.98,0.48 1.46,0.58c0.58,0.12 1.07,0.12 1.55,0.01c0.21,-0.05 0.47,-0.17 0.56,-0.26l0.06,-0.06l-0.05,-0.04c-0.17,-0.13 -0.44,-0.22 -0.95,-0.3c-0.64,-0.11 -1,-0.27 -1.28,-0.57c-0.16,-0.17 -0.23,-0.32 -0.23,-0.51c0,-0.12 0.01,-0.17 0.06,-0.26c0.17,-0.35 0.58,-0.51 1.34,-0.51c0.9,0 2.17,0.26 3.68,0.74c0.12,0.04 0.22,0.07 0.23,0.06c0.01,-0.01 -1.52,-2.55 -2.97,-4.94c-2.33,-3.86 -5.85,-9.62 -10.32,-16.9c-0.95,-1.54 -1.75,-2.88 -1.79,-2.96c-0.15,-0.37 -0.27,-0.83 -0.24,-1.01c0.04,-0.29 0.3,-0.56 0.68,-0.71l0.16,-0.06l11.15,0.02c18.95,0.04 22.15,0.05 22.38,0.09c0.39,0.06 0.68,0.17 0.85,0.32c0.05,0.03 0.11,0.12 0.14,0.19c0.07,0.14 0.07,0.14 0.07,0.42c0,0.3 -0.01,0.37 -0.13,0.68c-0.03,0.09 -2.84,5 -7.38,12.88c-4.03,7 -7.32,12.73 -7.32,12.73c0,0 0.06,0.05 0.14,0.09c0.18,0.1 0.37,0.24 0.52,0.36c0.06,0.05 0.12,0.08 0.13,0.07c0.01,-0.01 3.31,-5.75 7.35,-12.76c6.95,-12.09 7.49,-13.04 7.49,-13.17c0,-0.01 0.01,-0.02 0.02,-0.02c0.07,0 0.51,1.28 0.55,1.6c0.03,0.3 -0.02,0.58 -0.19,0.91c-0.04,0.08 -2.83,4.89 -6.19,10.67l-6.12,10.53l0.06,0.14c0.09,0.21 0.15,0.5 0.22,0.96c0.1,0.66 0.16,0.88 0.35,1.14c0.42,0.6 1.56,0.89 3.49,0.89c1.35,0 2.22,-0.12 2.72,-0.37c0.2,-0.09 0.24,-0.13 0.23,-0.16c-0.02,-0.05 -0.27,-0.17 -0.51,-0.25c-0.51,-0.17 -0.95,-0.25 -2.24,-0.44c-0.95,-0.13 -1.23,-0.19 -1.44,-0.29c-0.23,-0.11 -0.34,-0.25 -0.34,-0.44c0,-0.27 0.22,-0.5 0.73,-0.75c0.44,-0.22 1.11,-0.37 2.05,-0.44c0.45,-0.04 1.81,-0.03 2.46,0.01c0.63,0.04 1.25,0.09 1.85,0.16l0.43,0.05l0.12,-0.09c0.06,-0.05 0.16,-0.12 0.22,-0.15l0.11,-0.07l0,-3.59c0,-1.97 0,-4.85 -0.01,-6.39l-0.01,-2.81l-0.1,-0.04c-0.15,-0.07 -0.33,-0.19 -0.39,-0.27c-0.14,-0.18 -0.19,-0.52 -0.16,-1.01c0.03,-0.33 0.06,-0.41 0.21,-0.54c0.3,-0.28 0.82,-0.53 1.44,-0.7c0.17,-0.05 0.69,-0.17 0.72,-0.17c0.02,0 0.06,0.43 0.06,0.55c0,0.05 -0.01,0.05 -0.12,0.08c-0.38,0.07 -0.85,0.21 -1.06,0.32c-0.43,0.21 -0.44,0.4 -0.02,0.63l0.14,0.08l0.04,0.67c0.02,0.37 0.03,0.67 0.02,0.68c0,0 -0.12,-0.03 -0.25,-0.07l-0.24,-0.08l0,4.87c0,2.67 0,5.53 0.01,6.35l0.01,1.48l0.2,-0.04c0.46,-0.11 1,-0.17 1.57,-0.17l0.22,0l-0.16,0.03c-0.49,0.09 -1.1,0.38 -1.67,0.78l-0.16,0.12l0,0.14c0,0.19 0.08,0.35 0.3,0.57c0.2,0.2 0.35,0.3 0.64,0.44c0.46,0.23 1.04,0.38 1.82,0.48c0.4,0.05 1.56,0.05 2,0c0.99,-0.12 1.86,-0.39 2.41,-0.75c0.35,-0.22 0.65,-0.52 0.65,-0.64c0,-0.07 -0.08,-0.14 -0.47,-0.4c-0.47,-0.31 -0.98,-0.54 -1.41,-0.62c-0.09,-0.02 -0.17,-0.04 -0.18,-0.04c-0.01,-0.02 0.75,0.01 0.99,0.03c0.26,0.03 0.56,0.08 0.85,0.15c0.11,0.03 0.21,0.05 0.21,0.05c0.01,0 0.01,-2.88 0.01,-6.41c0,-6.1 0,-6.41 -0.03,-6.4c-0.25,0.1 -0.83,0.29 -0.85,0.27c-0.01,-0.01 0.07,-1.28 0.08,-1.31c0.01,-0.01 0.03,-0.02 0.05,-0.02c0.05,0 0.46,-0.14 0.56,-0.2c0.11,-0.06 0.19,-0.15 0.19,-0.21c0,-0.08 -0.18,-0.23 -0.47,-0.37c-0.4,-0.19 -0.87,-0.34 -1.53,-0.47l-0.27,-0.06l0,-0.06c0.02,-0.2 0.05,-0.54 0.06,-0.55c0.01,-0.01 0.55,0.1 0.93,0.19c1.18,0.3 2,0.74 2.11,1.12c0.06,0.22 0.04,1.14 -0.03,1.25c-0.02,0.03 -0.13,0.1 -0.27,0.17l-0.24,0.12l-0.01,3.65c-0.01,2.02 -0.01,4.93 -0.01,6.48l0,2.81l0.13,0.1c0.2,0.15 0.41,0.37 0.49,0.53c0.07,0.12 0.07,0.14 0.08,0.36c0.01,0.35 -0.06,1 -0.12,1.13c-0.06,0.11 -0.56,0.48 -0.96,0.7c-0.22,0.12 -0.61,0.31 -0.63,0.29c0,-0.01 0,-0.29 0.02,-0.63c0.01,-0.35 0.03,-0.63 0.02,-0.63c0,-0.01 -0.06,0.02 -0.12,0.05c-0.15,0.08 -0.15,0.08 -0.15,0.52c0,0.17 0,0.42 -0.01,0.55l-0.01,0.25l-0.23,0.07c-0.7,0.22 -1.6,0.35 -2.36,0.35c-0.2,0 -0.24,0 -0.25,-0.03c0,-0.02 -0.01,-0.16 -0.01,-0.32c0,-0.16 -0.01,-0.38 -0.01,-0.5l-0.02,-0.22l-0.16,0l-0.17,0l-0.01,0.53l0,0.53l-0.15,0c-0.18,-0.01 -0.67,-0.06 -0.89,-0.09c-0.51,-0.07 -1.45,-0.28 -1.6,-0.35l-0.05,-0.02l-0.02,-0.36c0,-0.19 -0.01,-0.44 -0.01,-0.56l0,-0.2l-0.14,-0.07c-0.07,-0.04 -0.14,-0.07 -0.14,-0.07c0,0.01 0,0.26 0.02,0.56c0.01,0.31 0.02,0.57 0.01,0.59c0,0.03 -0.04,0.02 -0.27,-0.07c-0.71,-0.27 -1.22,-0.6 -1.35,-0.87c-0.06,-0.12 -0.1,-0.42 -0.14,-1.03c-0.02,-0.38 -0.03,-0.4 -0.06,-0.41c-0.03,0 -0.18,-0.02 -0.35,-0.04c-2.73,-0.28 -4.69,-0.21 -5.68,0.21c-0.13,0.05 -0.37,0.19 -0.38,0.21c0,0.02 0.39,0.09 0.84,0.16c1.36,0.19 1.73,0.25 2.22,0.37c0.78,0.2 1.16,0.4 1.31,0.7c0.16,0.33 -0.01,0.68 -0.44,0.9c-0.63,0.33 -1.66,0.47 -3.27,0.45c-0.74,-0.01 -1.03,-0.03 -1.5,-0.1c-1.25,-0.18 -1.98,-0.58 -2.33,-1.27c-0.14,-0.28 -0.21,-0.55 -0.28,-1.06c-0.06,-0.38 -0.11,-0.64 -0.12,-0.64c-0.01,0 -0.28,0.46 -0.6,1.01c-0.33,0.56 -0.63,1.07 -0.69,1.14c-0.06,0.07 -0.18,0.19 -0.27,0.26l-0.16,0.12l0.08,0.12c0.2,0.3 0.26,0.51 0.18,0.66c-0.04,0.08 -0.12,0.15 -0.17,0.15c-0.01,0 -0.13,0.06 -0.25,0.13c-0.67,0.4 -1.42,0.67 -2.18,0.77c-0.29,0.04 -0.92,0.05 -1.18,0.03zm0.9,-0.51c0.75,-0.06 1.48,-0.3 2.16,-0.69c0.26,-0.14 0.25,-0.13 0.16,-0.27c-0.2,-0.3 -0.57,-0.7 -0.9,-0.96c-0.62,-0.5 -1.24,-0.75 -1.86,-0.75c-0.68,0 -1.3,0.29 -1.9,0.89c-0.29,0.29 -0.45,0.49 -0.69,0.84c-0.13,0.19 -0.16,0.24 -0.14,0.26c0.07,0.04 0.47,0.23 0.69,0.31c0.45,0.18 1.08,0.33 1.56,0.37c0.27,0.03 0.64,0.03 0.92,0zm-1.29,-2.8c0.24,-0.1 0.44,-0.19 0.43,-0.2c0,-0.03 -1.1,-3.4 -1.1,-3.4c0,0 -0.07,0.03 -0.15,0.06c-0.19,0.1 -0.46,0.17 -0.66,0.19c-0.1,0.01 -0.16,0.02 -0.15,0.03c0,0.02 0.26,0.81 0.57,1.77c0.42,1.3 0.57,1.74 0.6,1.74c0.01,0 0.22,-0.08 0.46,-0.19zm-1.39,-3.8c0.34,-0.06 0.58,-0.18 0.84,-0.44c0.2,-0.21 0.32,-0.4 0.39,-0.67c0.06,-0.22 0.06,-0.54 0,-0.77c-0.08,-0.31 -0.31,-0.64 -0.56,-0.83c-0.42,-0.3 -0.96,-0.39 -1.46,-0.22c-0.44,0.15 -0.82,0.52 -0.97,0.97c-0.18,0.52 -0.03,1.14 0.37,1.53c0.16,0.15 0.2,0.18 0.36,0.26c0.31,0.18 0.68,0.24 1.03,0.17zm0.63,-2.04c-0.28,-0.22 -0.5,-0.34 -0.71,-0.39c-0.12,-0.04 -0.22,-0.05 -0.61,-0.1c-0.04,-0.01 -0.08,-0.02 -0.08,-0.03c0,-0.03 0.18,-0.11 0.32,-0.15c0.14,-0.03 0.41,-0.04 0.55,-0.01c0.29,0.07 0.61,0.33 0.75,0.63c0.1,0.19 0.11,0.24 0.07,0.24c-0.01,0 -0.14,-0.09 -0.29,-0.19zm1.65,-3.12c1.03,-0.12 1.94,-0.4 2.82,-0.85c0.33,-0.16 0.89,-0.49 0.91,-0.53c0.01,-0.01 -0.21,-0.29 -0.48,-0.62c-0.48,-0.59 -0.49,-0.59 -0.53,-0.56c-0.03,0.01 -0.16,0.09 -0.3,0.16c-0.77,0.44 -1.58,0.7 -2.52,0.83c-0.39,0.05 -1.35,0.05 -1.74,0c-0.84,-0.11 -1.6,-0.35 -2.32,-0.72l-0.31,-0.16l-0.46,0.61c-0.25,0.33 -0.46,0.61 -0.46,0.62c-0.02,0.04 0.68,0.42 1.12,0.61c0.85,0.35 1.76,0.57 2.73,0.65c0.23,0.02 1.3,-0.01 1.54,-0.04zm-5.12,-2.52l0.18,-0.24l-0.05,-0.04c-0.11,-0.07 -0.55,-0.43 -0.71,-0.58l-0.18,-0.16l-0.61,0.44c-0.34,0.25 -0.62,0.45 -0.62,0.46c-0.02,0.01 0.42,0.44 0.64,0.64c0.11,0.09 0.28,0.24 0.39,0.32l0.2,0.16l0.29,-0.38c0.16,-0.21 0.37,-0.49 0.47,-0.62zm9.56,0.6c0.13,-0.1 0.35,-0.31 0.5,-0.46c0.21,-0.22 0.26,-0.28 0.24,-0.3c-0.02,-0.01 -0.3,-0.2 -0.64,-0.44l-0.6,-0.42l-0.16,0.14c-0.08,0.08 -0.23,0.22 -0.34,0.31c-0.11,0.09 -0.19,0.17 -0.19,0.17c0,0.03 0.95,1.19 0.96,1.19c0.01,0 0.11,-0.09 0.23,-0.19zm-4.68,-0.26c2.58,-0.29 4.69,-2.14 5.23,-4.59c0.09,-0.41 0.12,-0.65 0.12,-1.19c0,-0.57 -0.02,-0.75 -0.13,-1.23c-0.41,-1.88 -1.81,-3.46 -3.68,-4.18c-1.7,-0.65 -3.69,-0.52 -5.25,0.34c-1.68,0.93 -2.76,2.46 -3.04,4.31c-0.04,0.29 -0.05,1.17 -0.01,1.45c0.18,1.26 0.7,2.34 1.56,3.24c1.32,1.38 3.25,2.07 5.2,1.85zm-1.94,-0.58c-1.23,-0.15 -2.55,-1.26 -3.81,-3.18c-0.11,-0.18 -0.23,-0.36 -0.26,-0.41c-0.04,-0.07 -0.04,-0.07 0.06,0.03c1.15,1.32 2.47,2.14 3.78,2.37c0.37,0.07 0.94,0.07 1.31,0c0.7,-0.12 1.33,-0.4 1.97,-0.87c0.1,-0.08 0.19,-0.14 0.19,-0.14c0.02,0.01 -0.33,0.52 -0.5,0.74c-0.31,0.41 -0.74,0.82 -1.08,1.04c-0.18,0.12 -0.47,0.26 -0.65,0.32c-0.3,0.1 -0.71,0.14 -1.01,0.1zm3.13,-0.32c0.1,-0.1 0.28,-0.32 0.41,-0.47c1.07,-1.28 1.69,-2.54 1.84,-3.75c0.03,-0.26 0.03,-0.81 -0.01,-1.07c-0.1,-0.64 -0.37,-1.3 -0.72,-1.72c-0.06,-0.08 -0.09,-0.13 -0.07,-0.12c0.06,0.02 0.46,0.3 0.67,0.46c0.27,0.21 0.67,0.63 0.83,0.86c0.34,0.5 0.49,0.98 0.46,1.53c-0.02,0.44 -0.12,0.82 -0.35,1.27c-0.28,0.56 -0.62,1 -1.24,1.61c-0.46,0.46 -0.75,0.72 -1.22,1.07c-0.28,0.21 -0.75,0.53 -0.77,0.53c-0.01,0 0.07,-0.09 0.17,-0.2zm-3.32,-1.61c-1.45,-0.21 -1.81,-1.33 -1.06,-3.32c0.08,-0.23 0.34,-0.83 0.39,-0.92c0.01,-0.03 0.02,0.16 0.02,0.49c0,0.58 0.02,0.83 0.12,1.22c0.14,0.61 0.37,1.04 0.76,1.43c0.21,0.21 0.42,0.37 0.66,0.49c0.35,0.18 0.8,0.29 1.19,0.31c0.15,0.01 0.22,0.02 0.2,0.03c-0.03,0.02 -0.42,0.13 -0.64,0.17c-0.52,0.11 -1.26,0.16 -1.64,0.1zm-2.36,-1.13c-0.36,-0.25 -0.62,-0.46 -0.89,-0.74c-0.61,-0.62 -0.88,-1.24 -0.84,-1.97c0.01,-0.3 0.04,-0.48 0.14,-0.78c0.22,-0.66 0.66,-1.3 1.37,-2.03c0.49,-0.5 1.04,-0.97 1.67,-1.4c0.43,-0.31 0.45,-0.31 0.22,-0.06c-1.17,1.28 -1.93,2.61 -2.17,3.78c-0.07,0.37 -0.09,0.55 -0.09,0.94c0,0.55 0.09,1 0.28,1.46c0.13,0.33 0.34,0.69 0.51,0.87c0.04,0.05 0.06,0.08 0.05,0.08c-0.01,0 -0.12,-0.07 -0.25,-0.15zm5.61,0.06c-0.64,-0.07 -1.55,-0.28 -2.53,-0.58c-0.19,-0.06 -0.39,-0.12 -0.45,-0.13c-0.06,-0.02 -0.1,-0.04 -0.1,-0.04c0.01,-0.01 0.18,0.01 0.39,0.04c0.21,0.03 0.54,0.07 0.73,0.09c0.42,0.03 1.22,0.04 1.5,0.01c0.65,-0.09 1.05,-0.28 1.2,-0.59c0.08,-0.18 0.08,-0.36 -0.01,-0.62c-0.04,-0.14 0.42,0.49 0.55,0.73c0.13,0.26 0.17,0.39 0.17,0.55c0.01,0.27 -0.14,0.43 -0.48,0.52c-0.17,0.05 -0.66,0.06 -0.97,0.02zm-2.43,-0.95c-0.29,-0.11 -0.59,-0.38 -0.89,-0.8l-0.08,-0.11l0.16,0.13c0.41,0.36 0.76,0.51 1.15,0.51c0.27,0 0.49,-0.07 0.72,-0.23l0.09,-0.06l-0.03,0.06c-0.08,0.14 -0.38,0.42 -0.51,0.48c-0.17,0.08 -0.43,0.09 -0.61,0.02zm1.09,0c0,-0.01 0.06,-0.08 0.13,-0.16c0.07,-0.08 0.19,-0.22 0.25,-0.32c0.34,-0.52 0.39,-1 0.13,-1.4l-0.07,-0.11l0.11,0.06c0.15,0.09 0.34,0.29 0.4,0.41c0.04,0.09 0.05,0.13 0.05,0.29c0,0.17 -0.01,0.19 -0.09,0.36c-0.08,0.16 -0.12,0.21 -0.31,0.4c-0.2,0.19 -0.6,0.51 -0.6,0.47zm1.3,-0.94c0,-0.6 -0.02,-0.81 -0.12,-1.23c-0.33,-1.32 -1.26,-2.1 -2.65,-2.2c-0.21,-0.02 -0.2,-0.02 0.15,-0.11c0.55,-0.14 0.86,-0.18 1.37,-0.2c0.34,-0.01 0.46,0 0.64,0.03c1.32,0.2 1.72,1.2 1.16,2.92c-0.13,0.4 -0.41,1.11 -0.53,1.32c-0.01,0.02 -0.02,-0.17 -0.02,-0.53zm-2.98,0.12c-0.14,-0.09 -0.31,-0.27 -0.37,-0.39c-0.05,-0.08 -0.07,-0.14 -0.07,-0.25c-0.02,-0.26 0.09,-0.48 0.37,-0.77c0.18,-0.19 0.63,-0.55 0.63,-0.5c0,0 -0.06,0.07 -0.13,0.16c-0.39,0.43 -0.59,0.92 -0.53,1.3c0.02,0.17 0.09,0.33 0.17,0.44c0.06,0.09 0.05,0.09 -0.07,0.01zm-1.7,-1.17c-0.18,-0.22 -0.38,-0.52 -0.47,-0.69c-0.38,-0.82 0.13,-1.15 1.48,-0.98c0.56,0.07 1.38,0.26 2.2,0.5c0.8,0.24 0.86,0.27 0.48,0.21c-0.65,-0.1 -1.53,-0.16 -2.04,-0.13c-0.87,0.04 -1.33,0.23 -1.51,0.59c-0.06,0.12 -0.07,0.16 -0.07,0.29c0.01,0.11 0.02,0.19 0.05,0.27c0.02,0.06 0.04,0.11 0.03,0.11c0,0.01 -0.07,-0.07 -0.15,-0.17zm4.16,0.03c-0.31,-0.33 -0.71,-0.53 -1.09,-0.57c-0.24,-0.02 -0.61,0.08 -0.83,0.23c-0.03,0.03 -0.06,0.04 -0.07,0.04c-0.02,0 0.18,-0.23 0.3,-0.35c0.19,-0.17 0.33,-0.23 0.56,-0.23c0.26,0 0.53,0.13 0.81,0.42c0.17,0.17 0.48,0.57 0.44,0.57c0,0 -0.05,-0.05 -0.12,-0.11zm3.66,-1.04c-0.08,-0.12 -0.51,-0.57 -0.74,-0.78c-0.6,-0.55 -1.15,-0.93 -1.75,-1.22c-1.18,-0.56 -2.29,-0.64 -3.4,-0.23c-0.39,0.14 -0.87,0.41 -1.25,0.69c-0.09,0.07 -0.16,0.12 -0.17,0.12c-0.01,-0.02 0.4,-0.62 0.59,-0.84c0.58,-0.72 1.18,-1.14 1.84,-1.31c0.19,-0.05 0.26,-0.06 0.52,-0.06c0.45,0 0.8,0.08 1.24,0.3c0.48,0.24 0.91,0.56 1.42,1.07c0.53,0.53 0.91,1.01 1.39,1.74c0.15,0.22 0.29,0.44 0.31,0.48c0.05,0.08 0.05,0.11 0,0.04zm-10.85,6.19c0.33,-0.24 0.6,-0.45 0.6,-0.46c-0.01,-0.01 -0.09,-0.12 -0.18,-0.25c-0.66,-0.87 -1.06,-1.87 -1.2,-2.99c-0.05,-0.35 -0.05,-1.09 0,-1.45c0.09,-0.76 0.29,-1.42 0.63,-2.09l0.16,-0.3l-0.61,-0.43c-0.33,-0.23 -0.61,-0.42 -0.62,-0.42c-0.01,0 -0.07,0.1 -0.14,0.22c-0.47,0.86 -0.76,1.76 -0.89,2.75c-0.05,0.4 -0.07,1.19 -0.04,1.58c0.11,1.39 0.54,2.64 1.3,3.77c0.16,0.24 0.36,0.51 0.37,0.51c0.01,0 0.29,-0.2 0.62,-0.44zm12.62,0.19c0.86,-1.19 1.35,-2.53 1.47,-3.99c0.03,-0.38 0.02,-1.24 -0.03,-1.58c-0.14,-1.11 -0.5,-2.13 -1.06,-3.07c-0.06,-0.11 -0.12,-0.19 -0.13,-0.19c-0.04,0.01 -1.2,0.86 -1.2,0.88c0,0 0.05,0.1 0.11,0.2c0.33,0.58 0.6,1.28 0.73,1.92c0.09,0.42 0.11,0.71 0.11,1.22c0,0.5 -0.02,0.79 -0.11,1.21c-0.18,0.89 -0.59,1.8 -1.15,2.54l-0.17,0.23l0.61,0.43c0.34,0.24 0.63,0.43 0.64,0.43c0.01,0 0.09,-0.11 0.18,-0.23zm-12.05,-8.53c0.1,-0.13 0.32,-0.37 0.5,-0.54l0.31,-0.32l-0.45,-0.55c-0.25,-0.31 -0.47,-0.58 -0.49,-0.6c-0.03,-0.03 -0.04,-0.02 -0.31,0.24c-0.38,0.36 -0.72,0.75 -0.96,1.1c-0.05,0.07 -0.09,0.13 -0.08,0.14c0.01,0.01 0.28,0.2 0.62,0.43l0.6,0.42l0.04,-0.04c0.02,-0.03 0.12,-0.15 0.22,-0.28zm11.36,-0.32c0.33,-0.24 0.6,-0.44 0.61,-0.45c0.02,-0.02 -0.03,-0.09 -0.32,-0.43c-0.28,-0.33 -1,-1.03 -1.03,-1c0,0 -0.21,0.28 -0.46,0.61l-0.46,0.61l0.11,0.1c0.23,0.19 0.56,0.53 0.75,0.76c0.11,0.12 0.2,0.22 0.2,0.22c0.01,0 0.28,-0.19 0.6,-0.42zm-19.91,-0.91c0.34,-0.17 0.4,-0.66 0.11,-0.92c-0.22,-0.2 -0.56,-0.17 -0.75,0.06c-0.23,0.29 -0.1,0.78 0.24,0.89c0.12,0.04 0.3,0.03 0.4,-0.03zm9.97,-0.08c0.87,-0.6 1.91,-0.99 3.04,-1.15c0.37,-0.05 1.36,-0.05 1.74,0c0.74,0.1 1.41,0.29 2.03,0.57c0.28,0.13 0.67,0.35 0.88,0.48l0.13,0.09l0.04,-0.05c0.12,-0.14 0.87,-1.14 0.88,-1.16c0,-0.02 -0.06,-0.08 -0.22,-0.18c-1.12,-0.74 -2.37,-1.18 -3.75,-1.34c-0.37,-0.04 -1.44,-0.03 -1.81,0.01c-1.41,0.18 -2.65,0.64 -3.78,1.42c-0.27,0.18 -0.3,0.21 -0.3,0.22c0,0.02 0.95,1.19 0.96,1.19c0.01,0 0.08,-0.05 0.16,-0.1zm17.41,0c0.3,-0.16 0.37,-0.58 0.14,-0.85c-0.22,-0.26 -0.64,-0.24 -0.82,0.04c-0.16,0.24 -0.13,0.56 0.08,0.75c0.17,0.15 0.4,0.17 0.6,0.06zm-29.14,-3.03c0.1,-0.06 0.2,-0.18 0.25,-0.29c0.01,-0.04 0.02,-0.13 0.02,-0.2c0,-0.17 -0.06,-0.31 -0.19,-0.42c-0.2,-0.17 -0.47,-0.17 -0.67,0c-0.17,0.15 -0.24,0.4 -0.16,0.62c0.06,0.17 0.21,0.3 0.38,0.35c0.1,0.02 0.26,0 0.37,-0.06zm3.69,0.02c0.09,-0.04 0.21,-0.15 0.27,-0.26c0.03,-0.06 0.04,-0.11 0.04,-0.25c0,-0.2 -0.03,-0.28 -0.16,-0.41c-0.11,-0.1 -0.2,-0.14 -0.36,-0.14c-0.3,0 -0.52,0.23 -0.52,0.55c0,0.21 0.09,0.38 0.26,0.48c0.15,0.09 0.31,0.1 0.47,0.03zm27.3,-0.05c0.2,-0.1 0.31,-0.29 0.31,-0.51c0,-0.17 -0.03,-0.26 -0.14,-0.37c-0.25,-0.28 -0.66,-0.23 -0.85,0.1c-0.05,0.09 -0.06,0.13 -0.06,0.27c0,0.14 0.01,0.17 0.06,0.27c0.11,0.2 0.27,0.29 0.49,0.28c0.07,0 0.15,-0.02 0.19,-0.04zm-3.65,-0.05c0.19,-0.1 0.3,-0.3 0.29,-0.52c-0.01,-0.21 -0.12,-0.36 -0.31,-0.45c-0.25,-0.12 -0.57,0 -0.69,0.25c-0.05,0.11 -0.06,0.31 -0.02,0.42c0.06,0.16 0.19,0.28 0.36,0.34c0.08,0.02 0.28,0 0.37,-0.04zm6.98,24.62c-0.01,-0.01 -0.05,-0.02 -0.08,-0.02c-0.09,-0.02 -0.18,-0.11 -0.18,-0.18c0,-0.1 0.09,-0.17 0.27,-0.2c0.38,-0.06 0.7,0.08 0.6,0.26c-0.05,0.09 -0.16,0.13 -0.39,0.14c-0.11,0 -0.21,0 -0.22,0zm-38.14,-1.29c-0.2,-0.02 -0.3,-0.09 -0.3,-0.21c0,-0.06 0.1,-0.14 0.2,-0.17c0.1,-0.03 0.39,-0.03 0.5,0c0.12,0.03 0.19,0.1 0.19,0.18c0,0.16 -0.23,0.24 -0.59,0.2zm-1.21,-0.71c-0.12,-0.02 -0.19,-0.08 -0.19,-0.16c-0.01,-0.1 0.04,-0.14 0.2,-0.17c0.24,-0.05 0.59,-0.02 0.68,0.06c0.06,0.05 0.05,0.17 -0.02,0.22c-0.1,0.07 -0.44,0.1 -0.67,0.05zm43.95,-0.62c-0.26,-0.06 -0.32,-0.25 -0.11,-0.36c0.06,-0.03 0.12,-0.04 0.32,-0.04c0.21,0 0.25,0.01 0.33,0.05c0.16,0.09 0.14,0.25 -0.05,0.33c-0.08,0.03 -0.38,0.04 -0.49,0.02zm-41.4,-0.36c-0.18,-0.03 -0.26,-0.13 -0.21,-0.26c0.03,-0.07 0.17,-0.12 0.37,-0.13c0.35,-0.01 0.53,0.06 0.53,0.21c0,0.1 -0.08,0.16 -0.25,0.19c-0.16,0.03 -0.29,0.03 -0.44,-0.01zm-23.24,-2.09c-0.01,-0.04 -0.3,-1.59 -0.64,-3.45c-0.35,-1.86 -0.63,-3.4 -0.64,-3.43c-0.01,-0.05 -0.02,-0.06 -0.09,-0.06c-0.04,0 -0.19,-0.01 -0.34,-0.03c-1.54,-0.17 -2.42,-0.8 -2.6,-1.87c-0.04,-0.22 -0.04,-0.65 0,-0.93c0.15,-1.02 0.72,-2.28 1.72,-3.8c0.13,-0.21 0.25,-0.39 0.26,-0.4c0,-0.01 -0.09,0.02 -0.22,0.08c-1.41,0.63 -2.91,0.96 -3.93,0.87c-1.22,-0.11 -2,-0.67 -2.41,-1.73c-0.04,-0.1 -0.11,-0.26 -0.16,-0.36c-0.11,-0.23 -0.2,-0.48 -0.24,-0.73c-0.04,-0.23 -0.03,-0.73 0.02,-0.97c0.06,-0.26 0.19,-0.63 0.33,-0.89l0.12,-0.25l-1.04,-0.68c-0.58,-0.37 -1.06,-0.67 -1.08,-0.68c-0.02,0 -0.06,0.07 -0.16,0.25c-1.03,2.03 -2.56,3.13 -4.74,3.4c-0.12,0.01 -0.22,0.02 -0.23,0.02c0,0 0.05,-0.16 0.11,-0.34c0.24,-0.72 0.4,-1.52 0.48,-2.32c0.03,-0.37 0.02,-1.19 -0.01,-1.55c-0.1,-0.9 -0.37,-1.73 -0.78,-2.41l-0.11,-0.19l-0.09,0.26c-0.26,0.81 -0.72,1.31 -1.31,1.45c-0.2,0.05 -0.66,0.04 -0.69,-0.01c0,-0.01 0.01,-0.06 0.04,-0.12c0.09,-0.17 0.25,-0.6 0.32,-0.85c0.39,-1.32 0.33,-2.55 -0.19,-3.69c-0.07,-0.18 -0.24,-0.48 -0.26,-0.48c-0.01,0 -0.02,0.04 -0.04,0.08c-0.04,0.14 -0.21,0.46 -0.33,0.62c-0.27,0.35 -0.62,0.59 -1.04,0.7c-0.19,0.05 -0.57,0.07 -0.76,0.05l-0.12,-0.01l0.13,-0.13c0.41,-0.45 0.59,-0.97 0.59,-1.75c0,-1.12 -0.41,-2.47 -1.3,-4.25c-0.54,-1.07 -1.3,-2.35 -1.96,-3.29c-0.08,-0.11 -0.14,-0.21 -0.13,-0.21c0.01,0 0.08,0.06 0.17,0.13c0.58,0.48 1.58,1.22 2.37,1.75c2,1.33 3.61,2.09 4.87,2.31c0.81,0.14 1.44,0.02 1.89,-0.35c0.11,-0.08 0.13,-0.09 0.12,-0.05c0,0.02 -0.02,0.1 -0.03,0.17c-0.06,0.28 -0.21,0.63 -0.37,0.87c-0.24,0.32 -0.58,0.57 -0.93,0.66l-0.1,0.02l0.1,0.05c0.19,0.1 0.65,0.28 0.93,0.38c1.24,0.41 2.64,0.47 3.85,0.16c0.15,-0.04 0.27,-0.07 0.28,-0.06c0.02,0.02 -0.28,0.59 -0.42,0.81c-0.25,0.38 -0.49,0.64 -0.75,0.82c-0.13,0.09 -0.33,0.18 -0.38,0.18c-0.07,0 -0.04,0.04 0.08,0.11c0.18,0.1 0.63,0.32 0.78,0.39c0.16,0.06 0.62,0.23 0.62,0.22c0.05,-0.06 0.32,-0.48 0.41,-0.63c0.69,-1.14 1.1,-2.25 1.25,-3.36c0.06,-0.39 0.05,-1.11 -0.01,-1.5c-0.02,-0.16 -0.05,-0.3 -0.05,-0.3c-0.01,-0.01 -0.06,0.03 -0.11,0.1c-0.17,0.2 -0.6,0.61 -0.78,0.74c-0.39,0.27 -0.84,0.45 -1.25,0.48c-0.32,0.02 -0.7,-0.05 -0.97,-0.2l-0.12,-0.06l0.11,-0.09c0.19,-0.16 0.4,-0.37 0.59,-0.58c1,-1.11 1.59,-2.32 1.73,-3.56c0.03,-0.27 0.02,-0.86 -0.01,-1.11c-0.02,-0.12 -0.03,-0.23 -0.03,-0.23c0,-0.01 -0.05,0.04 -0.11,0.1c-0.37,0.38 -0.83,0.67 -1.25,0.8c-0.61,0.19 -1.35,0.14 -1.87,-0.12l-0.08,-0.04l0.19,-0.09c1.08,-0.5 1.74,-1.63 2.01,-3.41c0.14,-0.94 0.15,-2.21 0.05,-3.46c-0.11,-1.25 -0.33,-2.64 -0.62,-3.89c-0.06,-0.24 -0.1,-0.44 -0.1,-0.45c0,-0.01 0,-0.01 0.35,0.54c1.24,1.95 2.8,3.91 4.05,5.07c1.01,0.93 1.89,1.51 2.7,1.78c0.4,0.13 0.59,0.16 0.97,0.16c0.33,0 0.48,-0.03 0.76,-0.12c0.08,-0.03 0.15,-0.05 0.16,-0.05c0.02,0.02 -0.29,0.42 -0.47,0.6c-0.45,0.45 -0.96,0.71 -1.52,0.78c-0.12,0.01 -0.27,0.02 -0.34,0.01c-0.07,-0.01 -0.13,0 -0.12,0c0,0.01 0.09,0.1 0.2,0.2c0.82,0.77 1.86,1.38 3.02,1.75c0.69,0.23 1.46,0.37 2.16,0.41l0.26,0.02l-0.15,0.14c-0.36,0.34 -0.92,0.74 -1.3,0.94c-0.42,0.21 -0.73,0.31 -1.07,0.32l-0.23,0.02l0.4,0.39c0.67,0.68 1.27,1.11 2.11,1.53c1.12,0.56 2.35,0.87 3.76,0.94c0.46,0.03 1.15,0.01 1.48,-0.04c0.06,-0.01 0.12,-0.02 0.12,-0.02c0.01,0.01 -0.11,0.12 -0.26,0.26c-0.15,0.14 -0.51,0.49 -0.81,0.77c-0.59,0.58 -0.88,0.83 -1.24,1.1c-0.98,0.73 -2.09,1.1 -3.54,1.18c-0.18,0.01 -0.33,0.02 -0.34,0.03c0,0.01 0.48,3.2 0.49,3.21c0,0 0.23,-0.1 0.51,-0.22c1.74,-0.77 3.44,-1.4 4.91,-1.81c0.69,-0.19 1.21,-0.3 1.82,-0.39c0.57,-0.08 0.86,-0.13 0.88,-0.14c0.01,-0.01 0.04,-0.1 0.06,-0.2c0.05,-0.16 0.06,-0.29 0.11,-0.89c0.02,-0.39 0.05,-0.7 0.05,-0.71c0.01,0 0.19,-0.08 0.4,-0.19c0.37,-0.17 0.4,-0.18 0.39,-0.23c0,-0.03 -0.28,-1.69 -0.62,-3.7c-0.34,-2 -0.62,-3.64 -0.62,-3.65c0,0 -0.16,0.04 -0.36,0.09l-0.36,0.09l-0.2,0.48l-0.19,0.49l-0.34,0.11c-0.19,0.06 -0.36,0.13 -0.37,0.14c-0.02,0.01 -0.08,0.27 -0.15,0.59c-0.09,0.43 -0.13,0.58 -0.15,0.58c-0.07,0.02 -0.89,0.18 -0.9,0.17c-0.01,0 -0.18,-1.02 -0.39,-2.26l-0.38,-2.25l0.06,-0.09c0.18,-0.25 0.43,-0.43 0.69,-0.52c0.14,-0.05 0.2,-0.06 0.38,-0.06c0.36,0 0.57,0.06 1.22,0.34c0.63,0.26 0.81,0.3 0.97,0.2c0.07,-0.05 0.15,-0.18 0.15,-0.25c0,-0.03 -0.11,-0.72 -0.25,-1.55l-0.26,-1.5l0.13,-0.23c0.08,-0.13 0.14,-0.25 0.14,-0.27c0,-0.02 -0.07,-0.36 -0.16,-0.76c-0.09,-0.4 -0.16,-0.74 -0.16,-0.74c0.02,-0.02 0.31,0.19 0.45,0.32c0.25,0.24 0.44,0.53 0.55,0.82c0.02,0.05 0.04,0.11 0.05,0.12c0,0 0.13,-0.01 0.27,-0.04c0.24,-0.05 0.27,-0.06 0.27,-0.1c0,-0.02 -0.05,-0.34 -0.11,-0.7c-0.06,-0.36 -0.11,-0.67 -0.11,-0.68c0.01,-0.02 0.09,0.05 0.2,0.17c0.4,0.4 0.63,0.79 0.67,1.1l0.01,0.1l0.18,0.1c0.1,0.05 0.19,0.11 0.2,0.12c0.02,0.02 0.09,0.34 0.09,0.42c0,0.03 -0.02,0.04 -0.14,0.07c-0.08,0.01 -0.14,0.03 -0.15,0.04c0,0 0.22,0.13 0.5,0.27c0.28,0.14 0.51,0.27 0.52,0.27c0.02,0.01 0.27,1.12 0.27,1.17c0,0 -0.11,-0.05 -0.24,-0.12l-0.24,-0.12l-0.14,0.02c-0.07,0.02 -0.14,0.04 -0.14,0.05c-0.01,0.01 0.04,0.29 0.1,0.62l0.12,0.61l0.07,0.05c0.04,0.03 0.11,0.06 0.15,0.06c0.19,0.03 0.3,-0.05 0.6,-0.46c0.3,-0.41 0.46,-0.56 0.7,-0.65c0.15,-0.05 0.4,-0.05 0.59,0.01c0.19,0.05 0.52,0.21 0.56,0.27c0.03,0.05 0.73,3.81 0.71,3.83c-0.01,0.01 -0.55,0.12 -0.59,0.12c-0.01,0 -0.12,-0.16 -0.23,-0.36c-0.12,-0.2 -0.22,-0.36 -0.22,-0.36c-0.01,0 -0.18,0.03 -0.39,0.07c-0.2,0.03 -0.37,0.06 -0.38,0.06c0,0 -0.1,-0.19 -0.22,-0.42c-0.11,-0.23 -0.21,-0.41 -0.22,-0.42c0,0 -0.18,0.04 -0.39,0.09l-0.4,0.08l0.01,0.06c0.01,0.11 1.24,7.04 1.25,7.05c0,0 0.19,0.02 0.41,0.03c0.23,0.01 0.41,0.03 0.41,0.03c0.01,0.01 0.23,0.41 0.5,0.9c0.45,0.82 0.5,0.9 0.63,1.03l0.13,0.13l0.63,-0.1c0.35,-0.06 0.63,-0.12 0.63,-0.12c0,-0.01 -0.04,-0.03 -0.08,-0.04c-0.2,-0.06 -0.38,-0.22 -0.42,-0.37c-0.04,-0.12 -0.02,-0.87 0.03,-1.05c0.04,-0.18 0.11,-0.31 0.19,-0.34c0.18,-0.08 0.43,0.14 0.9,0.79c0.09,0.13 0.19,0.25 0.21,0.27c0.04,0.03 0.04,0.03 0.05,-0.19c0.06,-0.85 0.3,-1.55 0.66,-1.87c0.11,-0.09 0.28,-0.17 0.37,-0.17c0.15,0 0.31,0.11 0.38,0.27c0.21,0.48 -0.06,1.36 -0.69,2.26c-0.13,0.19 -0.14,0.2 -0.08,0.19c0.03,-0.01 0.71,-0.13 1.51,-0.27c0.8,-0.14 1.45,-0.25 1.46,-0.26c0.01,-0.01 -0.53,-4.75 -0.55,-4.77c0,-0.01 -0.25,-0.02 -0.56,-0.04c-0.66,-0.04 -0.98,-0.08 -1.28,-0.15c-0.25,-0.07 -0.35,-0.11 -0.52,-0.23c-0.14,-0.1 -0.21,-0.2 -0.25,-0.35c-0.05,-0.17 -0.08,-0.73 -0.07,-1.08c0.02,-0.38 0.07,-0.66 0.21,-1.23c0.06,-0.23 1.14,-4.05 2.41,-8.49c1.27,-4.44 2.76,-9.65 3.3,-11.58c1.43,-5.04 1.79,-6.28 2.05,-7.05c0.21,-0.61 0.28,-0.76 0.48,-0.95c0.19,-0.17 0.38,-0.25 0.61,-0.25c0.18,0 0.33,0.04 0.53,0.13c0.21,0.11 0.6,0.21 1.47,0.36c0.72,0.14 1.14,0.2 3.77,0.58c1.3,0.19 2.4,0.35 2.44,0.36l0.07,0.01l-0.01,-1.54c-0.01,-1.86 0,-2 0.15,-2.16c0.06,-0.06 0.07,-0.06 0.21,-0.06c0.41,0 1.54,0.29 5.47,1.41c2.4,0.69 5.18,1.47 6.35,1.79c0.31,0.09 1.12,0.31 1.79,0.51c3.78,1.08 4.1,1.18 4.44,1.34c0.1,0.05 0.17,0.09 0.18,0.12c0.08,0.25 0.22,2.47 0.28,4.31c0.01,0.41 0.03,0.76 0.04,0.78c0.03,0.07 0.12,0.11 0.33,0.12c0.24,0.02 0.34,0.05 0.47,0.18c0.34,0.32 0.7,1.18 1.87,4.46c0.21,0.6 0.39,1.09 0.4,1.08c0,0 -0.26,-1.02 -0.58,-2.26l-0.59,-2.27l0.06,-5l0.06,-5.01l-0.2,-0.46c-0.11,-0.25 -0.2,-0.46 -0.2,-0.47c0,-0.01 0.12,0 0.27,0.03l0.11,0.03l0.13,0.26l0.13,0.26l0.31,0l0.31,0l0.12,-0.25l0.12,-0.25l0.19,-0.02c0.11,-0.01 0.2,-0.02 0.2,-0.01c0.01,0 -0.07,0.2 -0.18,0.43l-0.19,0.43l0.09,2.6l0.08,2.6l-0.17,0.17c-0.1,0.1 -0.31,0.29 -0.46,0.44l-0.28,0.26l0.47,-0.04c0.26,-0.03 0.48,-0.04 0.48,-0.04c0,0 0.03,2.19 0.06,4.87l0.07,4.88l0.18,0.52c0.21,0.6 0.34,1.03 0.34,1.11c0,0.07 -0.03,0.09 -0.18,0.12c-0.16,0.04 -0.35,0.05 -1.13,0.08c-0.82,0.02 -1,0.06 -1.1,0.25c-0.07,0.1 -0.07,0.19 -0.01,0.27c0.12,0.18 0.26,0.19 1.65,0.18c0.61,-0.01 1.48,-0.02 1.93,-0.04c0.92,-0.02 1.49,0 1.79,0.06c0.09,0.02 0.17,0.03 0.17,0.02c0,-0.01 0.01,-0.35 0.04,-0.76c0.02,-0.4 0.04,-0.74 0.03,-0.74c0,-0.01 -0.36,0.13 -0.78,0.29c-0.43,0.17 -0.84,0.33 -0.91,0.36l-0.14,0.05l-0.02,0.12c-0.03,0.15 -0.12,0.26 -0.22,0.26c-0.09,0 -0.21,-0.11 -0.27,-0.25c-0.06,-0.12 -0.08,-0.38 -0.04,-0.48c0.08,-0.24 0.23,-0.24 0.42,-0.01c0.03,0.03 0.06,0.05 0.07,0.05c0.02,0 0.38,-0.14 0.81,-0.31c0.42,-0.18 0.79,-0.32 0.81,-0.33c0.02,-0.01 -0.24,-0.12 -0.78,-0.34c-0.45,-0.18 -0.82,-0.33 -0.84,-0.33c-0.01,0 -0.04,0.02 -0.07,0.05c-0.19,0.23 -0.34,0.23 -0.42,-0.01c-0.04,-0.1 -0.02,-0.35 0.04,-0.48c0.06,-0.14 0.18,-0.25 0.27,-0.25c0.1,0 0.19,0.11 0.22,0.26l0.02,0.12l0.14,0.05c0.07,0.03 0.52,0.2 0.99,0.39c0.47,0.18 0.88,0.34 0.9,0.34c0.02,0 0.53,-0.2 1.13,-0.45l1.09,-0.44l0.02,-0.08c0.07,-0.22 0.33,-0.25 0.43,-0.05c0.09,0.18 0.05,0.51 -0.06,0.57c-0.07,0.03 -0.09,0.03 -0.21,-0.03l-0.11,-0.05l-0.92,0.35c-0.5,0.2 -0.91,0.36 -0.91,0.37c0,0 0.41,0.16 0.92,0.36l0.91,0.35l0.11,-0.05c0.12,-0.05 0.14,-0.06 0.21,-0.02c0.13,0.06 0.15,0.44 0.03,0.61c-0.11,0.15 -0.35,0.09 -0.4,-0.11l-0.02,-0.07l-1.04,-0.42c-0.57,-0.23 -1.04,-0.42 -1.04,-0.42c0,0.01 0,0.43 0.01,0.94c0.02,0.88 0.03,0.93 0.06,0.98c0.14,0.18 1.87,3.83 3.41,7.19c0.63,1.39 0.89,1.98 0.87,2c-0.03,0.03 -0.53,-0.35 -0.67,-0.5c-0.42,-0.46 -0.96,-1.5 -2.93,-5.61c-0.46,-0.95 -0.78,-1.54 -0.83,-1.54c-0.02,0 -0.07,0.12 -0.23,0.55c-0.17,0.47 -1.05,3.12 -1.49,4.47c-0.62,1.92 -0.87,2.73 -2.11,6.66c-0.12,0.38 -0.23,0.7 -0.23,0.71c-0.01,0 -0.64,0.01 -1.42,0.02c-0.77,0.01 -1.41,0.02 -1.41,0.02c-0.01,0.01 -0.01,0.73 0,1.6c0.01,0.87 0.01,1.59 0.01,1.6c-0.02,0.01 -2.07,-0.05 -2.82,-0.08c-0.87,-0.04 -1.29,-0.1 -1.37,-0.19c-0.07,-0.08 -0.1,-0.3 -0.13,-1.04c-0.02,-0.36 -0.04,-0.76 -0.06,-0.89c-0.02,-0.23 -0.09,-0.83 -0.11,-0.91l-0.01,-0.05l-0.62,0c-0.88,0 -1.45,0.05 -1.47,0.12c-0.02,0.05 0.25,0.79 0.96,2.67c0.22,0.57 0.41,1.07 0.43,1.13l0.04,0.11l2.87,-0.01c1.57,0 3.18,-0.02 3.57,-0.03c0.39,-0.01 1.37,-0.04 2.19,-0.06c0.82,-0.03 1.55,-0.05 1.63,-0.06l0.15,-0.01l-0.01,-2.39c-0.02,-2.79 0.01,-3.71 0.1,-3.89c0.02,-0.05 0.03,-0.05 0.15,-0.05c0.12,0 0.16,0.01 0.33,0.09c0.1,0.05 0.29,0.16 0.4,0.25c0.23,0.17 0.91,0.83 1.15,1.12l0.14,0.17l0.05,2.36c0.02,1.3 0.04,2.36 0.05,2.36c0,0.01 0.43,-0.01 0.95,-0.02c0.52,-0.02 1.04,-0.03 1.15,-0.03l0.21,0l0.01,-0.1c0.01,-0.05 0.14,-1.28 0.29,-2.73c0.15,-1.44 0.27,-2.65 0.27,-2.68l0.01,-0.05l-1.47,0.01l-1.46,0.01l-0.94,-0.8c-1,-0.86 -1.55,-1.34 -1.76,-1.56l-0.13,-0.13l0.02,-0.14c0.02,-0.07 0.07,-0.25 0.11,-0.4l0.09,-0.26l0.34,0.02c1.05,0.04 1.7,0.05 3.18,0.06l1.64,0.02l0.33,0.27c1.38,1.12 1.7,1.4 2.06,1.76c0.45,0.45 0.63,0.78 0.54,0.97c-0.04,0.07 -0.13,0.14 -0.23,0.18c-0.18,0.07 -0.34,0.09 -1.01,0.1l-0.67,0.01l-0.01,0.06c-0.01,0.04 -0.14,1.23 -0.29,2.65c-0.15,1.41 -0.27,2.6 -0.28,2.64c-0.01,0.06 0,0.07 0.04,0.05c0.06,-0.02 0.5,-0.02 0.71,0.01c0.41,0.06 1.43,0.29 1.85,0.41c0.04,0.01 0.07,0.02 0.07,0.01c0,0 -0.06,-0.1 -0.14,-0.22c-0.16,-0.27 -0.38,-0.69 -0.44,-0.9c-0.12,-0.35 -0.15,-0.71 -0.09,-0.93c0.12,-0.4 0.48,-0.48 0.81,-0.18c0.36,0.33 0.57,0.94 0.65,1.87c0.01,0.09 0.02,0.16 0.03,0.16c0.01,-0.01 0.13,-0.17 0.28,-0.36c0.63,-0.84 0.92,-0.94 1.05,-0.36c0.04,0.19 0.06,0.86 0.02,1c-0.04,0.18 -0.19,0.31 -0.46,0.4l-0.11,0.03l0.09,0.03c1.32,0.49 2.05,0.8 3.09,1.32c0.8,0.4 1.75,0.94 2.2,1.25l0.09,0.06l0,-0.12c0,-0.17 0.06,-0.29 0.24,-0.45c0.18,-0.17 0.3,-0.24 0.67,-0.36c0.33,-0.11 0.48,-0.19 0.61,-0.33l0.09,-0.09l-0.49,-0.46c-0.48,-0.47 -1.46,-1.46 -1.87,-1.92c-0.51,-0.56 -0.76,-0.97 -0.84,-1.38c-0.05,-0.23 -0.02,-0.43 0.08,-0.64c0.19,-0.42 0.58,-0.65 1.24,-0.75c0.24,-0.03 1.01,-0.03 1.55,0.01c0.69,0.05 0.95,0.05 1.23,-0.02c0.41,-0.11 0.73,-0.28 1.12,-0.6c1.21,-1.02 2.04,-1.51 2.77,-1.64c0.22,-0.04 0.6,-0.04 0.81,0c0.41,0.08 0.8,0.27 1.18,0.59c0.34,0.28 0.84,0.86 0.94,1.09c0.19,0.43 0.16,1 -0.08,1.77c-0.13,0.38 -0.22,0.62 -0.57,1.43c-0.32,0.76 -0.47,1.16 -0.52,1.4c-0.08,0.39 -0.01,0.83 0.23,1.49c0.25,0.69 0.32,0.94 0.34,1.34c0.03,0.63 -0.13,1.19 -0.44,1.5c-0.46,0.46 -1.24,0.45 -2.37,-0.05c-0.81,-0.36 -1.78,-0.99 -2.76,-1.8c-0.08,-0.06 -0.15,-0.12 -0.15,-0.12c-0.02,0 -0.15,0.31 -0.21,0.48c-0.03,0.09 -0.1,0.35 -0.15,0.57c-0.12,0.46 -0.17,0.61 -0.27,0.75l-0.08,0.1l0.18,0.16c0.21,0.2 0.7,0.72 0.96,1.03c2.01,2.42 2.7,5.19 2.02,8.16c-0.05,0.19 -0.06,0.27 -0.04,0.28c0.03,0.02 0,0.38 -0.55,6.69c-0.24,2.78 -0.26,3 -0.27,2.99c-0.01,0 -0.18,-1.61 -0.39,-3.58c-0.21,-1.97 -0.38,-3.58 -0.38,-3.59c-0.01,-0.01 -0.54,0.43 -0.54,0.46c-0.01,0.02 -0.16,0.7 -0.33,1.51c-0.18,0.81 -0.32,1.48 -0.33,1.49c-0.01,0.01 -0.11,-0.5 -0.23,-1.14c-0.11,-0.63 -0.21,-1.15 -0.22,-1.15c-0.01,0 -0.07,0.03 -0.14,0.07c-0.43,0.25 -1.29,0.65 -1.76,0.82c-0.13,0.05 -0.23,0.09 -0.24,0.09c0,0 0.05,0.1 0.12,0.22c0.46,0.78 0.99,1.83 1.29,2.6c0.33,0.83 0.55,1.59 0.66,2.29c0.06,0.35 0.06,1.11 0,1.37c-0.23,1.04 -0.88,1.57 -2.1,1.72c-0.25,0.03 -0.95,0.03 -1.3,-0.01c-1.32,-0.13 -2.21,-0.46 -2.8,-1.01c-0.64,-0.61 -0.91,-1.51 -0.85,-2.8c0.03,-0.44 0.06,-0.75 0.25,-2.04c0.26,-1.77 0.41,-3.12 0.5,-4.49c0.04,-0.55 0.05,-1.98 0.02,-2.47c-0.11,-2.01 -0.51,-3.52 -1.28,-4.79c-0.76,-1.25 -1.92,-2.29 -3.46,-3.08l-0.32,-0.16l0.04,0.07c0.02,0.03 0.22,0.36 0.43,0.73c0.21,0.37 0.41,0.7 0.43,0.73l0.04,0.07l-0.85,1.08c-0.46,0.59 -0.84,1.09 -0.84,1.1c0,0.02 0.28,0.75 0.62,1.63c0.34,0.88 0.62,1.6 0.61,1.6c0,0.01 -0.45,-0.79 -1.01,-1.78l-1,-1.78l0.58,-1c0.33,-0.54 0.59,-1 0.59,-1.01c0,-0.02 -0.29,-0.5 -0.64,-1.07c-0.58,-0.95 -0.65,-1.05 -0.71,-1.07l-0.06,-0.02l-0.51,0.65c-0.42,0.54 -0.51,0.67 -0.51,0.71c0,0.04 0.05,0.45 0.1,0.92c0.05,0.47 0.09,0.88 0.08,0.9c0,0.02 -0.2,-0.31 -0.48,-0.84l-0.48,-0.87l0.36,-0.9c0.2,-0.5 0.36,-0.91 0.36,-0.91c-0.03,-0.02 -1.12,-0.3 -1.67,-0.42c-3.48,-0.76 -7.86,-1.16 -14.44,-1.31c-1.18,-0.03 -6.95,-0.04 -7.48,-0.02l-0.4,0.01l0.09,0.36l0.1,0.36l-1.08,1.27c-0.6,0.69 -1.09,1.26 -1.09,1.26c-0.01,0 -0.02,0.01 0.62,-1.16l0.47,-0.87l-0.2,-0.61c-0.11,-0.33 -0.2,-0.61 -0.2,-0.61c-0.02,-0.02 -3.02,0.03 -3.97,0.05c-5.74,0.15 -9.32,0.57 -12.04,1.4c-0.18,0.06 -0.34,0.11 -0.34,0.11c-0.02,0.02 -0.16,1.51 -0.15,1.53c0.01,0.02 0.25,0.37 0.53,0.79c0.29,0.42 0.52,0.77 0.53,0.79c0,0.03 -0.84,2.3 -0.85,2.29c0,0 0.05,-0.32 0.13,-0.71c0.07,-0.39 0.13,-0.72 0.13,-0.74c0.01,-0.03 -1.11,-1.8 -1.13,-1.79c-0.01,0.01 -0.14,3.26 -0.15,3.43c0,0.06 -0.07,0.17 -0.61,0.87c-0.57,0.73 -0.62,0.8 -0.61,0.86c0.03,0.17 0.56,4.07 0.55,4.08c0,0.01 -1.24,-4.4 -1.28,-4.58c0,-0.01 0.19,-0.28 0.43,-0.59c0.24,-0.31 0.5,-0.65 0.58,-0.75l0.14,-0.19l0.3,-2.42c0.16,-1.33 0.3,-2.43 0.29,-2.43c-0.02,-0.03 -1.26,0.57 -1.71,0.82c-2.26,1.3 -3.5,3.01 -3.79,5.18c-0.07,0.52 -0.07,1.41 -0.01,1.96c0.17,1.49 0.49,2.68 1.52,5.6c0.58,1.63 0.8,2.33 0.97,3.06c0.16,0.68 0.22,1.15 0.22,1.68c0,0.9 -0.22,1.53 -0.73,2.07c-0.74,0.78 -1.94,1.2 -3.89,1.37c-0.51,0.05 -1.59,0.07 -2.03,0.04c-2.03,-0.14 -3.18,-0.79 -3.57,-2.03c-0.11,-0.34 -0.14,-0.59 -0.14,-1.11c0,-0.63 0.04,-0.97 0.28,-2.14c0.18,-0.88 0.23,-1.2 0.26,-1.6c0.01,-0.08 0.01,-0.14 0,-0.14c0,0 -0.04,0.02 -0.08,0.04c-0.31,0.19 -1.55,0.6 -2.66,0.87l-0.43,0.11l-0.19,0.96c-0.11,0.53 -0.2,0.97 -0.21,0.98c0,0 -0.21,-0.37 -0.46,-0.83c-0.25,-0.47 -0.45,-0.85 -0.45,-0.85c-0.01,0 -0.17,0.02 -0.37,0.05c-0.27,0.04 -0.37,0.06 -0.37,0.08c0,0.02 -0.2,1.58 -0.44,3.47c-0.24,1.89 -0.44,3.48 -0.45,3.52l-0.02,0.08l-0.01,-0.07zm-7.25,-19.84c1.13,-1.07 2.92,-2.29 5.08,-3.46l0.17,-0.09l-1.06,-1.33l-1.06,-1.33l-0.26,0.22c-0.25,0.21 -0.48,0.38 -0.79,0.62c-0.16,0.11 -0.16,0.11 -0.24,0.32c-0.44,1.05 -0.72,1.55 -1.16,2.02c-0.41,0.45 -1.04,0.86 -1.77,1.15c-0.15,0.06 -0.27,0.12 -0.26,0.12c0.02,0.07 1.14,1.94 1.15,1.94c0.01,0 0.1,-0.08 0.2,-0.18zm87.49,-4.29c0.16,-0.06 0.04,-0.36 -0.32,-0.81c-1.23,-1.53 -5.25,-4.79 -6.61,-5.36c-0.4,-0.17 -0.56,-0.15 -0.54,0.08c0.03,0.26 0.38,0.69 1.21,1.5c0.39,0.39 1.36,1.28 1.43,1.32c0.01,0.01 0.08,-0.06 0.19,-0.22c0.24,-0.33 0.35,-0.41 0.47,-0.38c0.04,0.01 0.49,0.4 1.01,0.88c0.2,0.19 0.22,0.21 0.22,0.28c0,0.11 -0.08,0.23 -0.33,0.5c-0.06,0.07 -0.12,0.14 -0.12,0.14c0.01,0.05 1.35,1.06 1.88,1.42c0.84,0.56 1.27,0.74 1.51,0.65zm-56.04,-1.92c0.3,-0.03 0.61,-0.07 0.81,-0.12c0.19,-0.05 0.25,-0.09 0.35,-0.29c0.06,-0.13 0.17,-0.48 0.17,-0.55c0,-0.02 -0.04,-0.03 -0.11,-0.03c-0.06,0 -0.41,-0.03 -0.77,-0.06c-1.14,-0.1 -1.31,-0.11 -2.12,-0.11c-0.77,0 -1.04,0.02 -1.4,0.09c-0.15,0.03 -0.29,0.18 -0.44,0.48c-0.09,0.17 -0.22,0.46 -0.22,0.48c0,0 0.09,0.01 0.21,0.02c0.11,0 0.46,0.03 0.78,0.05c0.32,0.03 0.76,0.05 0.98,0.06c0.47,0.02 1.44,0.01 1.76,-0.02zm57.19,-0.52c0.1,-0.05 0.23,-0.18 0.25,-0.26c0.03,-0.11 0.01,-0.36 -0.05,-0.67c-0.06,-0.28 -0.07,-0.34 -0.06,-0.51c0.01,-0.2 0.09,-0.53 0.19,-0.77c0.02,-0.07 0.05,-0.14 0.05,-0.15c0,-0.03 -0.28,-0.14 -0.47,-0.18c-0.21,-0.05 -0.35,-0.03 -0.55,0.07c-0.54,0.26 -0.92,0.88 -0.85,1.36c0.05,0.33 0.2,0.56 0.54,0.82c0.22,0.17 0.41,0.27 0.55,0.32c0.11,0.04 0.3,0.02 0.4,-0.03zm-55.16,-1.15c0.18,-0.02 0.33,-0.04 0.35,-0.05c0.02,-0.01 0.1,-0.11 0.19,-0.22c0.27,-0.35 0.37,-0.58 0.31,-0.7c-0.02,-0.05 -0.06,-0.07 -0.24,-0.12c-0.99,-0.3 -2.75,-0.42 -3.82,-0.26c-0.27,0.04 -0.63,0.13 -0.76,0.19c-0.12,0.06 -0.19,0.17 -0.26,0.4c-0.07,0.21 -0.12,0.54 -0.09,0.56c0.02,0 0.08,0.01 0.15,0.01c0.12,0 0.54,0.04 1.68,0.14c1.15,0.11 1.8,0.12 2.49,0.05zm15.93,-0.75c2.12,-0.02 3.01,-0.05 3.76,-0.14c0.78,-0.09 1.39,-0.24 1.6,-0.4c0.09,-0.07 0.1,-0.17 0.02,-0.23c-0.1,-0.08 -0.22,-0.09 -1.2,-0.1c-0.54,0 -1.02,-0.01 -1.13,-0.02c-0.32,-0.04 -0.49,-0.11 -0.49,-0.22c0,-0.02 0.02,-0.07 0.05,-0.11c0.04,-0.06 0.07,-0.08 0.21,-0.12c0.2,-0.05 0.61,-0.11 1.07,-0.15c0.89,-0.08 1.27,-0.19 1.09,-0.3c-0.07,-0.05 -0.3,-0.09 -0.63,-0.13c-0.71,-0.07 -0.78,-0.1 -0.78,-0.35c0,-0.19 0.08,-0.24 0.51,-0.27c0.42,-0.02 0.55,-0.05 0.56,-0.11c0.02,-0.12 -0.67,-1.99 -1.19,-3.21c-0.26,-0.63 -0.61,-1.6 -0.79,-2.22c-0.2,-0.66 -0.39,-0.96 -0.61,-0.92c-0.23,0.05 -0.25,0.43 -0.03,0.86c0.09,0.18 0.54,1.61 0.58,1.85c0.05,0.24 0.02,0.27 -0.33,0.29c-0.21,0.01 -0.34,0.05 -0.34,0.11c0,0.05 0.06,0.32 0.21,0.95c0.25,1.03 0.32,1.48 0.25,1.59c-0.11,0.16 -0.46,0.22 -2.61,0.4c-1.22,0.1 -1.73,0.12 -1.9,0.05c-0.09,-0.04 -0.12,-0.11 -0.23,-0.47c-0.09,-0.32 -0.16,-0.62 -0.33,-1.42c-0.24,-1.1 -0.26,-1.15 -0.6,-1.2c-0.57,-0.08 -3.72,-0.08 -3.99,0.01c-0.03,0.01 -0.03,0.02 -0.02,0.1c0.02,0.06 1.11,3.36 1.12,3.38c0,0 0.2,-0.01 0.44,-0.03c0.67,-0.05 0.98,0 1.14,0.18c0.09,0.1 0.1,0.19 0.02,0.27c-0.07,0.07 -0.24,0.11 -0.73,0.14c-0.23,0.02 -0.44,0.06 -0.51,0.11c-0.02,0.01 -0.05,0.05 -0.06,0.08c-0.08,0.2 0.26,0.25 2.94,0.35c2.03,0.08 2.57,0.12 2.74,0.22c0.07,0.05 0.08,0.12 0.01,0.18c-0.09,0.09 -0.29,0.12 -1.26,0.18c-1.75,0.11 -2.66,0.24 -2.81,0.42c-0.06,0.07 -0.06,0.08 0,0.14c0.1,0.1 0.47,0.19 1.05,0.24c0.32,0.02 1.54,0.05 1.9,0.04c0.12,0 0.71,-0.01 1.3,-0.02zm-21.24,-0.67c0.41,-0.05 0.91,-0.12 1.42,-0.2l0.34,-0.05l0,-0.25c0,-0.33 -0.06,-3.31 -0.09,-4.42c-0.04,-1.92 -0.1,-2.54 -0.23,-2.69c-0.02,-0.02 -0.06,-0.04 -0.1,-0.04c-0.19,0 -0.32,-0.11 -0.38,-0.32c-0.06,-0.22 -0.07,-0.46 -0.07,-1.36l0,-0.9l0.3,-0.01c0.17,-0.01 0.79,-0.03 1.38,-0.05c0.59,-0.01 1.19,-0.03 1.33,-0.04l0.25,-0.02l0.07,-0.18c0.05,-0.1 0.18,-0.43 0.31,-0.74c0.36,-0.88 0.61,-1.36 0.74,-1.43c0.04,-0.03 0.05,-0.02 0.11,0.03c0.17,0.16 0.46,0.7 0.93,1.74l0.23,0.51l0.49,-0.01c0.28,-0.01 0.77,-0.02 1.11,-0.02c0.59,0 0.6,0 0.7,0.05c0.1,0.05 0.16,0.12 0.21,0.25c0.03,0.08 0.04,0.18 0.03,1.09c0,1.29 -0.02,1.47 -0.17,1.54c-0.04,0.02 -0.16,0.04 -0.27,0.06c-0.12,0.01 -0.22,0.03 -0.22,0.04c-0.02,0.02 0.05,7.1 0.06,7.11c0.01,0.01 0.35,-0.01 0.76,-0.04c1.1,-0.08 1.88,-0.13 3.04,-0.19c1.59,-0.08 2.08,-0.12 2.35,-0.18c0.14,-0.04 0.17,-0.06 0.17,-0.12c0,-0.08 -0.17,-0.63 -0.68,-2.16c-0.5,-1.52 -0.66,-2.04 -0.7,-2.23c-0.02,-0.15 -0.11,-0.33 -0.24,-0.51c-0.31,-0.42 -0.41,-0.67 -1.73,-4.68c-0.51,-1.54 -1.53,-4.62 -2.27,-6.85c-0.74,-2.23 -1.41,-4.27 -1.5,-4.52c-0.08,-0.26 -0.15,-0.48 -0.16,-0.48c-0.01,-0.01 -0.53,0 -1.15,0.02c-1.33,0.05 -2.04,0.05 -2.15,0c-0.1,-0.06 -0.15,-0.14 -0.14,-0.29c0,-0.31 0.2,-1.04 0.74,-2.75c0.46,-1.48 0.68,-2.26 0.73,-2.68c0,-0.08 0,-0.17 -0.02,-0.27c-0.06,-0.3 -0.33,-1.37 -0.61,-2.38c-0.34,-1.26 -0.5,-1.86 -0.58,-2.19c-0.03,-0.15 -0.08,-0.34 -0.11,-0.43c-0.1,-0.35 -0.29,-0.49 -0.47,-0.37c-0.04,0.03 -0.09,0.08 -0.1,0.11c-0.04,0.08 -0.01,0.24 0.14,0.72c0.21,0.66 0.39,1.27 0.56,1.89c0.28,1 0.47,1.73 0.47,1.78c0,0.02 -0.24,1 -0.55,2.17c-0.94,3.67 -1.37,5.47 -1.32,5.52c0.03,0.03 0.31,0.03 0.52,0c0.33,-0.05 0.44,-0.06 0.55,-0.04c0.12,0.02 0.17,0.08 0.17,0.19c0,0.1 -0.04,0.18 -0.14,0.26c-0.12,0.08 -0.26,0.13 -0.64,0.21c-0.19,0.03 -0.41,0.09 -0.49,0.11c-0.23,0.07 -0.33,0.18 -0.22,0.25c0.05,0.03 0.12,0.05 0.47,0.12c0.12,0.02 0.23,0.08 0.26,0.15c0.02,0.06 -0.04,0.16 -0.14,0.23c-0.11,0.07 -0.31,0.15 -0.65,0.24l-0.24,0.07l-0.05,0.15c-0.02,0.09 -0.17,0.69 -0.34,1.35c-0.17,0.65 -0.35,1.34 -0.4,1.52c-0.09,0.35 -0.1,0.42 -0.06,0.44c0.06,0.04 0.25,0.04 0.84,0.02c0.89,-0.05 0.95,-0.03 0.95,0.21c0,0.25 -0.09,0.28 -1.33,0.43l-0.7,0.09l-0.35,1.38c-0.41,1.66 -0.68,2.71 -1.3,5.04c-0.6,2.23 -0.69,2.6 -0.77,3.03c-0.1,0.48 -0.13,0.8 -0.1,1.13c0.02,0.24 0.22,1.66 0.23,1.68c0.01,0 0.15,0.01 0.32,0.02c0.55,0.04 0.75,0.13 0.75,0.33c0,0.17 -0.2,0.27 -0.59,0.32c-0.38,0.05 -0.42,0.1 -0.36,0.6c0.05,0.49 0.1,0.53 0.65,0.57c0.49,0.04 0.81,0.12 0.93,0.23c0.09,0.08 0.09,0.13 0.02,0.22c-0.12,0.14 -0.35,0.2 -0.89,0.22c-0.6,0.02 -0.6,0.02 -0.44,0.6l0.03,0.11l0.09,-0.01c0.04,-0.01 0.25,-0.03 0.46,-0.05zm9.33,-1.24c-0.13,0 -0.25,-0.02 -0.26,-0.03c-0.04,-0.04 -0.07,-0.39 -0.1,-0.99c-0.03,-0.93 0.02,-2.1 0.11,-2.32c0.04,-0.08 0.12,-0.13 0.33,-0.17c0.23,-0.04 0.84,-0.07 1.28,-0.05l0.39,0.01l0.01,0.12c0.05,0.51 0.07,2.54 0.03,2.97c-0.02,0.14 -0.04,0.25 -0.05,0.28c-0.09,0.12 -0.4,0.18 -1.04,0.19c-0.25,0.01 -0.57,0 -0.7,-0.01zm1.3,-0.86c-0.01,-0.18 -0.02,-0.74 -0.03,-1.25l-0.01,-0.94l-0.54,0l-0.53,0l0,0.88c0,0.48 0.01,1.04 0.01,1.25l0.02,0.38l0.54,0l0.55,0l-0.01,-0.32zm-7.99,1.75c0.11,-0.17 0.12,-0.74 0.13,-4.28l0,-2.9l-0.22,0c-0.11,0 -0.23,0.01 -0.25,0.03c-0.08,0.04 -0.1,0.15 -0.11,0.49c-0.03,0.67 0.1,4.6 0.18,5.83c0.05,0.72 0.09,0.89 0.2,0.89c0.02,0 0.05,-0.02 0.07,-0.06zm5.18,-0.04c0.07,-0.07 0.08,-0.2 0.08,-0.84c0,-0.95 -0.12,-6.1 -0.14,-6.13c-0.01,0 -0.35,-0.04 -0.36,-0.04c0,0.01 0.02,0.74 0.04,1.63c0.02,0.9 0.04,2.15 0.05,2.78c0.02,1.84 0.05,2.42 0.12,2.6c0.03,0.06 0.04,0.07 0.1,0.06c0.03,-0.01 0.08,-0.04 0.11,-0.06zm47.69,-0.21c0.26,-0.25 -0.02,-1.17 -0.5,-1.63c-0.26,-0.24 -0.49,-0.3 -0.82,-0.22c-0.42,0.11 -0.58,0.35 -0.44,0.7c0.08,0.2 0.41,0.56 0.74,0.8c0.23,0.16 0.52,0.34 0.64,0.39c0.15,0.05 0.3,0.04 0.38,-0.04zm-25.88,-0.96c0.03,-0.04 -0.26,-0.39 -0.36,-0.42c-0.05,-0.01 -0.15,0.08 -0.25,0.23c-0.08,0.14 -0.08,0.17 0,0.18c0.17,0.03 0.6,0.04 0.61,0.01zm1.78,-0.03c0.01,-0.04 0.01,-0.07 -0.04,-0.16c-0.05,-0.11 -0.21,-0.27 -0.26,-0.27c-0.05,0 -0.23,0.17 -0.27,0.27c-0.03,0.05 -0.04,0.11 -0.04,0.13c0.01,0.05 0.02,0.05 0.14,0.06c0.07,0.01 0.2,0.02 0.29,0.02c0.14,0 0.15,0 0.18,-0.05zm-1.53,-0.88c0,-0.18 -0.01,-0.48 -0.01,-0.67l-0.01,-0.33l-0.13,0.19c-0.19,0.28 -0.26,0.44 -0.26,0.55c0,0.11 0.1,0.33 0.28,0.6l0.11,0.17l0.01,-0.09c0.01,-0.05 0.01,-0.24 0.01,-0.42zm2.04,-0.14c0.02,-0.56 -0.02,-0.97 -0.09,-0.97c-0.03,0 -0.22,0.28 -0.3,0.44c-0.07,0.14 -0.08,0.17 -0.08,0.31c0,0.13 0.01,0.17 0.07,0.27c0.07,0.15 0.18,0.32 0.28,0.43l0.08,0.09l0.01,-0.06c0.01,-0.03 0.03,-0.26 0.03,-0.51zm26.58,0.48c0.29,-0.07 0.64,-0.27 0.77,-0.45c0.12,-0.14 0.15,-0.23 0.15,-0.39c0,-0.2 -0.06,-0.33 -0.26,-0.52c-0.25,-0.25 -0.53,-0.36 -0.94,-0.36c-0.2,0 -0.26,0.01 -0.39,0.05c-0.28,0.09 -0.46,0.25 -0.58,0.49c-0.05,0.11 -0.05,0.14 -0.05,0.36c0,0.22 0,0.24 0.06,0.37c0.13,0.27 0.37,0.45 0.65,0.49c0.15,0.03 0.4,0.01 0.59,-0.04zm-29.69,-0.17c0.23,-0.33 0.25,-0.4 0.18,-0.56c-0.05,-0.11 -0.36,-0.46 -0.4,-0.46c-0.02,0 -0.02,0.52 0,0.85c0.02,0.23 0.04,0.36 0.07,0.36c0.01,0 0.07,-0.08 0.15,-0.19zm1.81,0.08c0.06,-0.07 0.14,-0.27 0.17,-0.43c0.03,-0.14 0.03,-0.18 0.01,-0.27c-0.05,-0.21 -0.26,-0.58 -0.3,-0.53c-0.03,0.03 -0.05,0.4 -0.04,0.76c0,0.33 0.01,0.4 0.04,0.45c0.04,0.06 0.07,0.07 0.12,0.02zm8.51,-0.21c0.05,-0.04 0.12,-0.13 0.15,-0.18c0.05,-0.1 0.05,-0.12 0.05,-0.25c-0.02,-0.23 -0.14,-0.4 -0.3,-0.43c-0.16,-0.03 -0.25,0.16 -0.25,0.5c0,0.3 0.06,0.44 0.2,0.44c0.05,0 0.09,-0.02 0.15,-0.08zm-34.38,-0.4c0.1,-0.08 0.15,-0.25 0.15,-0.51c0,-0.45 -0.13,-0.69 -0.37,-0.66c-0.3,0.03 -0.45,0.51 -0.28,0.86c0.08,0.16 0.3,0.34 0.41,0.35c0.02,0 0.07,-0.02 0.09,-0.04zm15.53,0.02c0.36,-0.04 0.44,-0.14 0.31,-0.36c-0.07,-0.12 -0.44,-0.5 -0.49,-0.52c-0.08,-0.02 -0.14,0.07 -0.33,0.48c-0.1,0.22 -0.18,0.4 -0.18,0.41c0,0.01 0.49,0.01 0.69,-0.01zm-14.53,-0.17c0.06,-0.03 0.11,-0.07 0.15,-0.13c0.05,-0.09 0.05,-0.11 0.05,-0.34c0,-0.29 -0.04,-0.43 -0.18,-0.57c-0.2,-0.2 -0.35,-0.06 -0.44,0.4c-0.06,0.29 -0.04,0.52 0.07,0.63c0.05,0.05 0.08,0.06 0.16,0.06c0.07,0 0.14,-0.02 0.19,-0.05zm16.54,-0.02c0.16,-0.08 0.11,-0.23 -0.18,-0.51c-0.28,-0.29 -0.32,-0.27 -0.41,0.13c-0.03,0.1 -0.05,0.22 -0.05,0.28c0,0.13 0.03,0.15 0.33,0.14c0.17,0 0.25,-0.02 0.31,-0.04zm7.06,-0.6c0.2,-0.22 0.24,-0.33 0.12,-0.41c-0.05,-0.04 -0.08,-0.05 -0.31,-0.05c-0.22,0 -0.27,0.01 -0.31,0.04c-0.05,0.03 -0.06,0.05 -0.05,0.11c0.02,0.14 0.28,0.45 0.37,0.45c0.03,0 0.09,-0.05 0.18,-0.14zm-6.44,-0.05c0,-0.26 -0.23,-1.34 -0.33,-1.55c-0.04,-0.07 -0.06,-0.09 -0.1,-0.1c-0.08,-0.01 -0.17,0.05 -0.24,0.14c-0.17,0.24 -0.19,0.52 -0.06,0.79c0.1,0.2 0.16,0.29 0.34,0.49c0.14,0.16 0.34,0.34 0.37,0.34c0.01,0 0.02,-0.05 0.02,-0.11zm-3.53,0.02c0.06,-0.07 0.13,-0.26 0.14,-0.42c0.03,-0.22 -0.04,-0.36 -0.37,-0.7l-0.2,-0.22l0.03,0.2c0.13,0.83 0.17,1.05 0.24,1.13c0.06,0.07 0.1,0.07 0.16,0.01zm11.67,0c0.09,-0.06 0.16,-0.29 0.11,-0.37c-0.05,-0.09 -0.25,-0.11 -0.35,-0.03c-0.08,0.07 -0.11,0.17 -0.06,0.28c0.05,0.15 0.17,0.2 0.3,0.12zm-10.44,-0.53c-0.03,-0.33 -0.15,-0.89 -0.22,-1.05c-0.02,-0.06 -0.04,-0.07 -0.12,-0.08c-0.09,-0.01 -0.39,0.01 -0.62,0.04l-0.08,0.01l0.12,0.15c0.46,0.58 0.6,0.75 0.73,0.89c0.18,0.19 0.21,0.2 0.19,0.04zm0.76,-0.13c0.07,-0.13 0.17,-0.46 0.21,-0.67c0.03,-0.16 0,-0.27 -0.07,-0.32c-0.06,-0.03 -0.25,-0.05 -0.34,-0.03c-0.11,0.03 -0.15,0.11 -0.15,0.27c0,0.15 0.07,0.54 0.12,0.71c0.04,0.12 0.09,0.19 0.14,0.17c0.02,-0.01 0.06,-0.06 0.09,-0.13zm-13.21,-3.87c-0.01,-0.09 -0.03,-0.48 -0.05,-0.87c-0.01,-0.39 -0.03,-0.71 -0.04,-0.72c0,-0.01 -6.56,0.04 -6.57,0.05c0,0 -0.02,0.16 -0.04,0.36c-0.02,0.23 -0.03,0.43 -0.02,0.53c0.02,0.27 0.12,0.47 0.25,0.55c0.13,0.06 0.92,0.12 2.28,0.17c1.03,0.04 3.33,0.09 3.79,0.1l0.41,0l-0.01,-0.17zm10.33,-1.3c0.61,-0.16 1.2,-0.61 1.63,-1.26c0.26,-0.39 0.32,-0.64 0.41,-1.64c0.04,-0.43 0.06,-0.54 0.12,-0.57c0.02,-0.01 0.11,-0.02 0.2,-0.03c0.17,-0.01 0.26,-0.04 0.26,-0.1c0,-0.04 -0.12,-0.16 -0.21,-0.22c-0.13,-0.08 -0.34,-0.16 -0.8,-0.29c-0.54,-0.16 -0.78,-0.2 -0.86,-0.16c-0.13,0.06 -0.08,0.18 0.17,0.38c0.1,0.08 0.2,0.17 0.21,0.2c0.05,0.09 0.05,0.86 0.01,1.07c-0.1,0.45 -0.3,0.73 -0.66,0.88c-0.4,0.16 -0.66,0.06 -0.77,-0.3c-0.15,-0.47 -0.08,-1.29 0.21,-2.91c0.1,-0.55 0.12,-0.64 0.13,-0.98c0.01,-0.43 -0.02,-0.67 -0.12,-0.98c-0.27,-0.81 -0.97,-1.4 -1.91,-1.59c-0.35,-0.07 -0.65,-0.03 -1.03,0.16c-0.6,0.3 -1.18,0.96 -1.42,1.61c-0.11,0.32 -0.14,0.52 -0.14,1.04c0,0.42 0,0.47 -0.03,0.49c-0.02,0.01 -0.11,0.02 -0.21,0.03c-0.24,0.01 -0.26,0.02 -0.26,0.07c0,0.19 0.53,0.56 1.16,0.82c0.35,0.13 0.72,0.21 0.75,0.15c0.01,-0.01 -0.02,-0.07 -0.07,-0.14c-0.21,-0.27 -0.28,-0.52 -0.28,-0.93c0,-0.42 0.09,-0.81 0.28,-1.16c0.16,-0.3 0.34,-0.49 0.56,-0.6c0.12,-0.05 0.29,-0.06 0.37,-0.01c0.29,0.14 0.41,0.68 0.37,1.58c-0.03,0.49 -0.09,0.93 -0.23,1.54c-0.2,0.87 -0.27,1.37 -0.25,1.85c0.03,0.67 0.22,1.19 0.61,1.61c0.2,0.21 0.43,0.33 0.76,0.41c0.24,0.05 0.8,0.04 1.04,-0.02zm-12.95,-0.9c0.09,-0.01 0.2,-0.03 0.24,-0.05c0.06,-0.03 0.07,-0.05 0.07,-0.1c-0.01,-0.09 -0.15,-0.42 -0.3,-0.73c-0.13,-0.28 -0.23,-0.42 -0.26,-0.4c-0.03,0.02 -0.14,0.28 -0.29,0.65c-0.15,0.36 -0.22,0.59 -0.2,0.61c0.04,0.04 0.48,0.05 0.74,0.02zm-18.21,-1.01c0.16,-0.06 0.35,-0.24 0.41,-0.41c0.07,-0.2 0.1,-0.46 0.07,-0.64l-0.01,-0.08l-0.15,0c-0.35,0 -0.64,0.14 -0.76,0.37c-0.06,0.11 -0.08,0.29 -0.06,0.45c0.02,0.13 0.07,0.31 0.1,0.36c0.01,0.03 0.27,0 0.4,-0.05zm44.09,-8.7c0.02,-0.02 0.04,-0.05 0.04,-0.06c0,-0.09 -0.34,-0.87 -0.62,-1.4c-0.17,-0.34 -0.32,-0.62 -0.33,-0.62c-0.02,0 -0.1,1.85 -0.08,1.86c0.02,0.02 0.54,0.18 0.69,0.22c0.17,0.03 0.24,0.03 0.3,0zm-2.76,-0.05c0.29,-0.03 0.6,-0.08 0.72,-0.11c0.06,-0.03 0.09,-0.06 0.22,-0.27l0.14,-0.24l0.07,-1.06c0.03,-0.59 0.08,-1.64 0.11,-2.35l0.06,-1.28l-0.08,-0.12c-0.08,-0.13 -0.12,-0.23 -0.11,-0.3c0,-0.04 0.01,-0.05 0.1,-0.04c0.05,0 0.29,0.05 0.52,0.1c0.23,0.06 0.45,0.11 0.49,0.11c0.04,0.01 0.09,0.03 0.11,0.04c0.03,0.03 0.03,0.04 -0.09,0.17c-0.15,0.16 -0.21,0.27 -0.22,0.43c-0.01,0.17 -0.04,1.14 -0.04,1.15c0.01,0.01 0.45,-0.62 0.72,-1.03l0.14,-0.22l-0.03,-0.11c-0.03,-0.06 -0.04,-0.13 -0.03,-0.15c0.03,-0.12 0.29,-0.04 0.65,0.19c0.13,0.08 0.18,0.14 0.18,0.19c0,0.03 -0.12,0.1 -0.17,0.1c-0.04,0 -0.08,0.07 -0.24,0.39c-0.15,0.31 -0.28,0.52 -0.6,1.01c-0.22,0.34 -0.41,0.63 -0.42,0.64c0,0.01 0.07,0.16 0.17,0.33c0.34,0.57 0.58,1.01 0.82,1.52c0.31,0.65 0.42,0.85 0.49,0.85c0.04,0 0.21,-0.35 0.25,-0.52c0.2,-0.75 0.18,-2.05 -0.06,-3.97c-0.09,-0.81 -0.13,-1.01 -0.19,-1.11c-0.2,-0.35 -1.18,-0.74 -2.8,-1.11c-1.12,-0.25 -2.54,-0.52 -5.42,-1.02c-3.02,-0.52 -4.92,-0.9 -6.39,-1.26c-0.28,-0.06 -0.51,-0.12 -0.52,-0.11c-0.1,0.1 -0.09,5.28 0.01,6.46c0.04,0.54 0.3,0.9 0.82,1.15c0.45,0.21 0.95,0.32 2.08,0.45l0.53,0.06l0.09,-0.05c0.13,-0.08 0.22,-0.16 0.24,-0.23c0.09,-0.27 0.29,-3 0.37,-4.92c0.03,-0.64 0.03,-0.68 -0.12,-0.91c-0.08,-0.15 -0.09,-0.16 -0.05,-0.19c0.12,-0.08 0.86,0.05 1.06,0.2c0.04,0.02 0.08,0.08 0.1,0.13c0.05,0.1 0.03,0.17 -0.07,0.26c-0.05,0.05 -0.07,0.09 -0.1,0.23c-0.1,0.54 -0.09,1.1 0.02,1.33c0.04,0.08 0.07,0.12 0.16,0.17c0.07,0.04 0.15,0.07 0.2,0.08c0.09,0.01 0.09,0.01 0.14,-0.08c0.08,-0.17 0.15,-0.52 0.2,-1.11c0.01,-0.14 0.03,-0.32 0.04,-0.4c0.02,-0.13 0.02,-0.16 -0.02,-0.27c-0.06,-0.16 -0.05,-0.19 0.02,-0.25c0.06,-0.05 0.07,-0.05 0.35,-0.05c0.32,0 0.46,0.03 0.55,0.11c0.05,0.04 0.06,0.06 0.06,0.15c-0.01,0.11 -0.02,0.14 -0.12,0.26c-0.17,0.2 -0.21,0.36 -0.27,0.99c-0.17,1.7 -0.29,3.64 -0.26,4.27c0.01,0.34 0.03,0.39 0.15,0.39c0.18,0 0.18,0.01 0.6,-1.76c0.48,-2.01 0.7,-2.8 0.88,-3.19l0.08,-0.17l-0.05,-0.11c-0.03,-0.06 -0.09,-0.16 -0.13,-0.23c-0.09,-0.14 -0.1,-0.21 -0.05,-0.28c0.05,-0.08 0.14,-0.09 0.49,-0.07c0.85,0.06 0.93,0.07 0.99,0.15c0.04,0.07 0.03,0.09 -0.12,0.32c-0.06,0.1 -0.13,0.21 -0.14,0.25c-0.02,0.08 -0.04,-0.01 0.24,1.42c0.59,3.09 0.82,4.21 0.84,4.27c0.12,0.26 0.78,0.39 1.64,0.33zm0.36,-0.63c-0.02,-0.01 -0.07,-0.05 -0.1,-0.09l-0.06,-0.07l-0.23,0c-0.2,0 -0.25,-0.01 -0.4,-0.05c-0.3,-0.1 -0.52,-0.23 -0.74,-0.45c-0.18,-0.19 -0.27,-0.32 -0.39,-0.55c-0.13,-0.26 -0.22,-0.5 -0.28,-0.81c-0.05,-0.24 -0.06,-0.29 -0.06,-0.74c0,-0.32 0.01,-0.54 0.03,-0.64c0.11,-0.64 0.34,-1.15 0.65,-1.47c0.25,-0.26 0.51,-0.38 0.82,-0.4c0.15,-0.01 0.18,-0.01 0.4,0.07c0.14,0.05 0.27,0.08 0.3,0.08c0.03,0 0.08,-0.03 0.14,-0.09c0.05,-0.05 0.11,-0.11 0.14,-0.12c0.05,-0.03 0.06,-0.03 0.09,0.02c0.06,0.08 0.03,0.89 -0.05,1.09c-0.04,0.1 -0.12,0.19 -0.16,0.19c-0.06,0 -0.17,-0.14 -0.28,-0.35c-0.26,-0.46 -0.37,-0.48 -0.64,-0.13c-0.46,0.61 -0.6,1.69 -0.35,2.64c0.17,0.63 0.52,1.06 0.86,1.07c0.13,0 0.17,-0.04 0.21,-0.18c0.12,-0.51 0.23,-0.63 0.34,-0.41c0.06,0.13 0.09,0.36 0.07,0.68c-0.02,0.41 -0.09,0.65 -0.21,0.71c-0.02,0.01 -0.05,0.02 -0.05,0.02c0,0 -0.02,-0.01 -0.05,-0.02zm-3.46,0.06c0.12,-0.03 0.28,-0.1 0.33,-0.15c0.02,-0.03 0.03,-0.06 0.02,-0.12c-0.02,-0.14 -0.09,-0.53 -0.17,-0.98c-0.04,-0.24 -0.09,-0.49 -0.09,-0.55c-0.02,-0.22 -0.18,-0.37 -0.38,-0.37c-0.11,0 -0.21,0.05 -0.27,0.14c-0.02,0.04 -0.07,0.18 -0.11,0.31c-0.07,0.27 -0.35,1.46 -0.37,1.58c-0.02,0.09 -0.04,0.08 0.33,0.13c0.32,0.03 0.57,0.04 0.71,0.01zm-3.2,-0.36c0.03,-0.02 0.06,-0.07 0.08,-0.13c0.03,-0.11 0.08,-0.57 0.1,-1.03c0.03,-0.49 0.03,-1.61 0.01,-1.68c-0.03,-0.06 -0.16,-0.14 -0.24,-0.14c-0.09,0 -0.16,0.04 -0.2,0.12c-0.11,0.24 -0.26,1.23 -0.31,2.16c-0.03,0.39 -0.02,0.62 0.03,0.66c0.01,0.01 0.08,0.04 0.14,0.06c0.15,0.05 0.31,0.04 0.39,-0.02zm-8.62,-1.43c0.25,-0.2 0.7,-0.65 1.28,-1.3c0.27,-0.31 0.62,-0.7 0.78,-0.87c0.33,-0.34 0.34,-0.37 0.37,-0.71c0.04,-0.48 -0.08,-1.04 -0.22,-0.98c-0.02,0.01 -0.1,0.09 -0.17,0.2c-0.22,0.29 -0.65,0.83 -0.93,1.14c-0.34,0.38 -0.96,1 -1.31,1.3c-0.34,0.3 -0.35,0.32 -0.35,0.64c0,0.25 0.05,0.44 0.14,0.59c0.1,0.16 0.17,0.16 0.41,-0.01zm-8.11,-1.26c0.01,-1 0,-1.85 -0.03,-1.96l-0.02,-0.06l-0.05,0.13c-0.12,0.26 -0.64,1.86 -0.78,2.42c-0.09,0.34 -0.09,0.35 -0.04,0.38c0.07,0.04 0.22,0.05 0.57,0.05l0.33,0.01l0.02,-0.97zm1.21,0.86c0.09,-0.02 0.2,-0.06 0.25,-0.08c0.11,-0.04 0.11,-0.06 0.01,-0.46c-0.22,-0.83 -0.59,-1.92 -0.88,-2.59l-0.12,-0.25l0,0.96c0,0.99 0.03,1.91 0.07,2.23c0.01,0.13 0.03,0.19 0.05,0.21c0.05,0.04 0.4,0.02 0.62,-0.02zm18.71,-0.69c0.09,-0.09 0.11,-0.2 0.06,-0.43c-0.03,-0.16 -0.13,-0.47 -0.17,-0.53c-0.03,-0.04 -0.06,0.01 -0.2,0.22c-0.24,0.41 -0.27,0.7 -0.08,0.78c0.04,0.01 0.12,0.03 0.19,0.03c0.12,0 0.14,-0.01 0.2,-0.07zm5.41,-3.51c0.09,-0.08 0.13,-0.17 0.17,-0.4c0.06,-0.36 0.08,-0.9 0.06,-2.69c-0.01,-2.18 -0.03,-2.42 -0.17,-2.55c-0.1,-0.09 -0.75,-0.29 -2.97,-0.91c-1.56,-0.44 -3.54,-1 -4.91,-1.4c-2.06,-0.6 -3.08,-0.89 -3.84,-1.09c-0.42,-0.11 -1.01,-0.28 -1.31,-0.37c-3.58,-1.05 -4.44,-1.27 -4.53,-1.12c-0.04,0.07 -0.01,1.67 0.14,6.43c0.04,1.25 0.07,2.27 0.07,2.29c0,0.01 0.08,0.03 0.25,0.05c0.32,0.03 1.37,0.18 2.01,0.28c0.27,0.05 0.52,0.08 0.54,0.07c0.09,-0.02 0.12,-0.14 0.18,-0.56c0.04,-0.31 0.1,-0.58 0.16,-0.71c0.07,-0.15 0.14,-0.18 0.39,-0.16c0.11,0 0.3,0.03 0.43,0.06c0.13,0.03 0.41,0.08 0.63,0.13c0.3,0.06 0.41,0.08 0.43,0.06c0.07,-0.07 0,-2.06 -0.1,-2.83c-0.07,-0.51 -0.14,-0.73 -0.45,-1.5c-0.29,-0.71 -0.33,-0.86 -0.26,-1.01c0.04,-0.07 0.15,-0.14 0.23,-0.14c0.14,0 0.3,0.28 0.53,0.94c0.16,0.44 0.28,0.72 0.31,0.72c0.04,0 0.09,-0.09 0.17,-0.3c0.11,-0.29 0.16,-0.41 0.29,-0.63c0.16,-0.25 0.22,-0.32 0.29,-0.3c0.21,0.06 0.12,0.69 -0.23,1.58c-0.23,0.61 -0.25,0.78 -0.24,2.17c0.01,0.59 0.02,1.04 0.04,1.11c0.05,0.26 0.14,0.35 0.44,0.41c0.11,0.03 0.25,0.04 0.32,0.04l0.13,0l-0.01,-0.09c-0.03,-0.24 -0.09,-0.79 -0.09,-0.87c0,-0.17 0.06,-0.23 0.19,-0.19c0.14,0.05 0.28,0.28 0.42,0.7c0.13,0.38 0.19,0.44 0.46,0.45c0.9,0.04 0.98,-0.71 0.22,-1.96c-0.59,-0.97 -0.76,-1.28 -0.88,-1.63c-0.05,-0.14 -0.06,-0.18 -0.06,-0.45c0,-0.29 0,-0.3 0.06,-0.41c0.08,-0.15 0.16,-0.22 0.35,-0.29c0.42,-0.15 0.97,0.05 1.09,0.39c0.05,0.17 0.03,0.26 -0.08,0.3c-0.02,0 -0.17,-0.01 -0.33,-0.03c-0.31,-0.05 -0.4,-0.05 -0.48,0.02c-0.04,0.04 -0.05,0.06 -0.05,0.14c0,0.13 0.04,0.24 0.25,0.62c0.23,0.41 0.37,0.65 0.64,1.06c0.42,0.63 0.58,1.09 0.58,1.6c0,0.37 -0.06,0.6 -0.26,0.89c-0.07,0.11 -0.11,0.19 -0.11,0.21c0.02,0.04 0.08,0.06 0.42,0.14c0.17,0.04 0.37,0.09 0.44,0.11c0.07,0.02 0.13,0.04 0.14,0.04c0,0 0.02,-0.03 0.03,-0.07c0.07,-0.16 0.09,-1.02 0.06,-3.26l-0.02,-1.1l-0.15,-0.03c-0.31,-0.06 -0.42,-0.1 -0.48,-0.18c-0.14,-0.16 -0.11,-0.36 0.07,-0.45c0.08,-0.04 0.38,-0.03 0.64,0.02c0.51,0.1 1.25,0.28 1.34,0.33c0.1,0.06 0.15,0.15 0.15,0.3c0,0.22 -0.07,0.25 -0.62,0.2c-0.21,-0.01 -0.38,-0.02 -0.39,-0.02c-0.01,0.02 0.04,4.33 0.05,4.34c0.01,0.01 0.2,0.06 0.43,0.11c0.48,0.11 0.8,0.15 0.86,0.09c0.05,-0.05 0.06,-0.67 0.03,-1.79c-0.02,-1.13 -0.02,-2.22 0,-2.47c0.01,-0.1 0.03,-0.17 0.04,-0.18c0.09,-0.06 0.51,-0.04 0.97,0.04c0.5,0.08 0.61,0.14 0.61,0.36c0,0.23 -0.08,0.26 -0.73,0.22l-0.4,-0.03l0,0.37c0,0.2 0.01,0.44 0.02,0.54c0.02,0.25 0.03,0.27 0.36,0.28c0.3,0.02 0.39,0.04 0.48,0.12c0.08,0.08 0.13,0.23 0.09,0.31c-0.05,0.1 -0.12,0.12 -0.54,0.13l-0.39,0.01l0,0.54c0,0.31 0,0.66 0.01,0.78l0.01,0.23l0.44,0.14c0.26,0.08 0.48,0.17 0.53,0.2c0.11,0.08 0.17,0.18 0.2,0.35c0.05,0.29 0.19,0.45 0.27,0.31c0.07,-0.11 0.08,-0.3 0.09,-2.22c0.02,-1.64 0.02,-1.92 0.05,-2.04c0.08,-0.35 0.2,-0.38 0.64,-0.16c0.41,0.21 0.66,0.48 0.9,0.99c0.19,0.4 0.22,0.56 0.14,0.8c-0.08,0.28 -0.29,0.59 -0.44,0.64c-0.04,0.01 -0.09,0.05 -0.12,0.08c-0.04,0.05 -0.05,0.08 -0.05,0.19c0,0.07 0.01,0.18 0.03,0.25c0.04,0.17 0.23,0.76 0.39,1.18c0.21,0.56 0.31,0.75 0.45,0.82c0.05,0.02 0.45,0.11 0.53,0.11c0.02,0 0.02,-1.65 -0.01,-2.27c-0.03,-0.78 -0.07,-1 -0.29,-1.53c-0.13,-0.31 -0.19,-0.47 -0.23,-0.66c-0.06,-0.21 -0.06,-0.22 0.02,-0.31c0.1,-0.11 0.21,-0.09 0.36,0.08c0.02,0.02 0.11,0.19 0.2,0.36c0.09,0.17 0.19,0.34 0.22,0.36l0.05,0.05l0.08,-0.09c0.05,-0.05 0.14,-0.2 0.21,-0.32c0.13,-0.26 0.2,-0.34 0.25,-0.34c0.05,0 0.14,0.07 0.21,0.16c0.1,0.15 0.08,0.26 -0.2,0.85c-0.31,0.65 -0.32,0.74 -0.31,1.58c0.03,1.3 0.1,2.09 0.2,2.22c0.05,0.07 0.2,0.12 0.36,0.12c0.11,0 0.13,-0.01 0.19,-0.06zm-13.28,-3.12c-0.17,-0.06 -0.28,-0.45 -0.49,-1.81c-0.13,-0.77 -0.22,-1.18 -0.27,-1.18c-0.04,0 -0.13,0.49 -0.23,1.26c-0.11,0.86 -0.2,1.24 -0.32,1.4c-0.07,0.09 -0.16,0.12 -0.23,0.07c-0.08,-0.04 -0.22,-0.51 -0.42,-1.38c-0.22,-0.93 -0.29,-1.19 -0.31,-1.14c-0.01,0.01 -0.07,0.26 -0.13,0.54c-0.07,0.28 -0.15,0.66 -0.19,0.83c-0.07,0.32 -0.21,0.83 -0.26,0.94c-0.03,0.07 -0.03,0.07 -0.16,0.07c-0.16,0 -0.28,-0.04 -0.32,-0.11c-0.03,-0.06 -0.01,-0.63 0.03,-1.01c0.13,-1.07 0.45,-2.64 0.69,-3.37c0.06,-0.2 0.09,-0.27 0.15,-0.33c0.16,-0.15 0.38,-0.11 0.47,0.1c0.03,0.06 0.04,0.13 0.04,0.31c0,0.25 0.04,0.62 0.1,1.03c0.13,0.78 0.31,1.5 0.37,1.47c0.05,-0.01 0.16,-0.54 0.29,-1.42c0.08,-0.56 0.2,-1.26 0.23,-1.37c0.02,-0.08 0.12,-0.15 0.2,-0.15c0.09,0 0.21,0.09 0.26,0.19c0.04,0.07 0.45,2.61 0.67,4.14c0.1,0.63 0.1,0.74 0.04,0.84c-0.02,0.04 -0.04,0.06 -0.04,0.06c-0.01,0 -0.03,0.01 -0.07,0.02c-0.03,0.01 -0.08,0.01 -0.1,0zm10.59,2.57l0.07,0l-0.19,-0.53c-0.25,-0.67 -0.34,-0.89 -0.4,-0.97c-0.09,-0.14 -0.1,-0.08 -0.11,0.48c0,0.45 0.02,0.82 0.06,0.91c0.01,0.03 0.05,0.06 0.08,0.08c0.08,0.03 0.26,0.05 0.35,0.04c0.03,0 0.1,-0.01 0.14,-0.01zm-18.68,-1.02c0.38,-0.25 0.81,-0.65 1.72,-1.62c0.35,-0.36 0.76,-0.78 0.91,-0.93c0.23,-0.23 0.28,-0.28 0.31,-0.38c0.14,-0.38 0.1,-1.16 -0.08,-1.41c-0.07,-0.1 -0.13,-0.07 -0.32,0.17c-0.89,1.12 -1.65,1.9 -2.87,2.91c-0.17,0.15 -0.21,0.23 -0.21,0.51c0,0.33 0.1,0.64 0.24,0.76c0.09,0.08 0.16,0.08 0.3,-0.01zm18.47,-1.79c0.23,-0.11 0.31,-0.36 0.21,-0.63c-0.12,-0.3 -0.47,-0.69 -0.57,-0.63c-0.09,0.05 -0.12,0.92 -0.04,1.15c0.05,0.14 0.24,0.2 0.4,0.11zm12.86,58.4c-0.18,-0.07 -0.2,-0.21 -0.05,-0.29c0.06,-0.03 0.12,-0.04 0.37,-0.04c0.27,0 0.31,0.01 0.37,0.04c0.09,0.05 0.13,0.14 0.09,0.19c-0.01,0.02 -0.05,0.05 -0.09,0.08c-0.06,0.03 -0.11,0.04 -0.34,0.04c-0.2,0.01 -0.29,0 -0.35,-0.02zm1.09,-0.97c-0.15,-0.06 -0.21,-0.16 -0.15,-0.26c0.05,-0.1 0.34,-0.16 0.6,-0.12c0.16,0.02 0.24,0.06 0.29,0.15c0.03,0.06 -0.01,0.15 -0.1,0.2c-0.09,0.06 -0.52,0.07 -0.64,0.03zm28.75,-2.63c-0.18,-0.05 -0.38,-0.19 -0.56,-0.37c-0.2,-0.2 -0.34,-0.37 -1.81,-2.27l-1.16,-1.5l-0.28,0c-0.65,0 -1.15,-0.17 -1.29,-0.45c-0.08,-0.15 -0.04,-0.38 0.07,-0.45c0.08,-0.05 0.26,-0.05 0.54,0.01c0.12,0.02 0.23,0.04 0.25,0.04c0.03,-0.01 -0.01,-0.07 -0.15,-0.25c-0.1,-0.14 -0.19,-0.26 -0.21,-0.27c-0.01,0 -0.1,-0.01 -0.19,-0.01c-0.22,0.01 -0.36,-0.02 -0.5,-0.1c-0.11,-0.07 -0.11,-0.07 -0.12,-0.03c-0.01,0.02 -0.04,0.17 -0.07,0.33c-0.19,0.88 -0.32,1.4 -0.38,1.49c-0.06,0.08 -0.15,0.14 -0.21,0.13c-0.06,-0.02 -0.12,-0.11 -0.12,-0.17c0,-0.05 0,-0.05 -0.09,0.03c-0.21,0.2 -0.34,0.14 -0.31,-0.16l0.01,-0.1l-0.07,0.03c-0.09,0.04 -0.16,0.03 -0.19,-0.03c-0.05,-0.09 -0.01,-0.37 0.12,-0.9c0.16,-0.66 0.2,-0.92 0.2,-1.22c0,-0.28 -0.01,-0.34 -0.13,-0.45c-0.15,-0.13 -0.34,-0.21 -0.8,-0.32c-0.27,-0.06 -0.54,-0.19 -0.65,-0.3c-0.08,-0.08 -0.14,-0.27 -0.14,-0.43c0,-0.11 0.01,-0.15 0.06,-0.26l0.07,-0.12l-0.18,-0.12c-0.43,-0.27 -0.7,-0.61 -0.84,-1.04c-0.08,-0.24 -0.09,-0.37 -0.04,-0.54c0.06,-0.18 0.17,-0.31 0.31,-0.36c0.05,-0.02 0.09,-0.04 0.1,-0.04c0,0 0.01,-0.2 0.01,-0.44c0,-0.37 0.01,-0.44 0.04,-0.54c0.09,-0.23 0.24,-0.4 0.63,-0.69c0.38,-0.29 0.47,-0.39 0.47,-0.5c0,-0.02 -0.16,-0.43 -0.36,-0.91l-0.36,-0.87l-0.11,-0.04c-0.14,-0.06 -0.27,-0.19 -0.3,-0.31c-0.05,-0.19 0.03,-0.39 0.26,-0.62c0.18,-0.18 0.36,-0.28 0.8,-0.45c0.36,-0.14 0.56,-0.18 0.86,-0.19c0.29,0 0.35,0.03 0.43,0.21c0.05,0.1 0.48,0.89 0.49,0.91c0.01,0.01 0.11,-0.03 0.22,-0.08c0.25,-0.11 0.8,-0.33 0.92,-0.36c0.09,-0.02 0.09,-0.03 0.07,-0.14c-0.04,-0.14 -0.13,-0.8 -0.12,-0.85c0.03,-0.13 0.36,-0.42 0.65,-0.56c0.13,-0.06 0.33,-0.12 0.65,-0.18c0.26,-0.05 0.66,-0.03 0.83,0.03c0.14,0.06 0.28,0.18 0.31,0.29c0.03,0.13 -0.02,0.25 -0.12,0.3c-0.07,0.03 -0.07,0.04 -0.04,0.2c0.01,0.06 0.08,0.48 0.15,0.93l0.13,0.82l0.1,0.09c0.13,0.12 0.22,0.15 0.44,0.12c0.27,-0.03 0.44,0.03 0.62,0.22c0.24,0.27 0.4,0.77 0.4,1.27c0,0.32 0.01,0.35 0.19,0.42c0.47,0.19 0.81,0.55 0.97,1.03c0.05,0.18 0.07,0.66 0.02,0.84c-0.06,0.24 -0.15,0.39 -0.31,0.51c-0.04,0.03 -0.07,0.07 -0.08,0.09c0,0.02 -0.01,0.08 -0.01,0.13c-0.01,0.04 -0.01,0.1 -0.01,0.13c0.01,0.02 0.15,0.16 0.33,0.32c0.4,0.35 1.09,1.05 1.29,1.29c0.22,0.28 0.26,0.34 0.26,0.43c0,0.09 -0.04,0.13 -0.13,0.11c-0.07,-0.01 -0.07,-0.01 -0.05,0.03c0.05,0.07 0.06,0.19 0.04,0.24c-0.03,0.05 -0.1,0.05 -0.21,-0.01c-0.06,-0.03 -0.1,-0.05 -0.11,-0.05c0,0 0,0.03 0.02,0.06c0.01,0.03 0.01,0.08 0.01,0.11c-0.01,0.05 -0.02,0.06 -0.07,0.07c-0.09,0.01 -0.18,-0.04 -0.7,-0.34c-0.56,-0.32 -0.77,-0.44 -0.88,-0.48c-0.09,-0.03 -0.09,-0.03 -0.08,0.02c0.03,0.13 0.54,3.03 0.61,3.48c0.04,0.27 0.16,1.2 0.31,2.4c0.11,0.89 0.12,0.99 0.11,1.13c-0.04,0.27 -0.17,0.46 -0.38,0.55c-0.12,0.05 -0.32,0.06 -0.45,0.03zm-4.53,-5.75c0.3,-0.06 0.6,-0.29 0.73,-0.56c0.07,-0.15 0.13,-0.45 0.1,-0.49c-0.11,-0.14 -0.2,-0.31 -0.27,-0.5c-0.07,-0.2 -0.09,-0.24 -0.12,-0.23c-0.16,0.07 -0.42,0.09 -0.62,0.05c-0.19,-0.04 -0.41,-0.15 -0.58,-0.28c-0.16,-0.12 -0.16,-0.12 -0.28,0.03c-0.17,0.22 -0.26,0.49 -0.26,0.77c0,0.35 0.13,0.68 0.36,0.92c0.25,0.27 0.58,0.37 0.94,0.29zm-0.25,-1.12c-0.06,-0.06 -0.06,-0.07 -0.05,-0.16c0.01,-0.08 0.02,-0.12 0.07,-0.17c0.06,-0.06 0.07,-0.06 0.14,-0.04c0.05,0.02 0.11,0.06 0.14,0.09c0.04,0.06 0.05,0.08 0.04,0.16c-0.01,0.12 -0.08,0.18 -0.2,0.18c-0.06,0 -0.09,-0.01 -0.14,-0.06zm2.26,0.24c0.38,-0.07 0.66,-0.36 0.74,-0.79c0.1,-0.46 -0.03,-0.89 -0.35,-1.21c-0.31,-0.31 -0.66,-0.4 -1.03,-0.26c-0.22,0.08 -0.31,0.14 -0.43,0.26c-0.11,0.12 -0.24,0.37 -0.29,0.57c-0.03,0.17 -0.04,0.44 0,0.59c0.15,0.56 0.77,0.95 1.36,0.84zm-0.33,-0.92c-0.1,-0.04 -0.17,-0.12 -0.17,-0.22c0,-0.07 0.06,-0.18 0.13,-0.21c0.06,-0.04 0.17,-0.01 0.23,0.06c0.04,0.06 0.05,0.08 0.04,0.18c-0.01,0.15 -0.1,0.22 -0.23,0.19zm-67.34,6.5c-0.28,-0.05 -0.33,-0.24 -0.11,-0.34c0.08,-0.04 0.13,-0.05 0.36,-0.05c0.22,0 0.27,0.01 0.35,0.05c0.18,0.07 0.18,0.22 0.01,0.3c-0.08,0.04 -0.13,0.05 -0.31,0.06c-0.12,0 -0.26,-0.01 -0.31,-0.02l0.01,0zm39.55,-0.43c-0.14,-0.03 -0.2,-0.06 -0.23,-0.13c-0.05,-0.13 0.06,-0.23 0.27,-0.26c0.17,-0.03 0.51,-0.02 0.63,0.02c0.09,0.03 0.18,0.12 0.18,0.18c0,0.06 -0.09,0.15 -0.18,0.18c-0.11,0.03 -0.54,0.05 -0.67,0.01zm36.17,-0.34c-0.17,-0.06 -0.3,-0.24 -0.36,-0.48c-0.04,-0.16 -0.03,-0.68 0.01,-0.94c0.05,-0.29 0.13,-0.66 0.22,-0.99c0.1,-0.32 0.31,-0.96 0.34,-0.99c0.03,-0.03 0.35,0.88 0.47,1.37c0.28,1.12 0.22,1.8 -0.2,2c-0.12,0.05 -0.35,0.07 -0.48,0.03zm-37.8,-0.49c-0.13,-0.04 -0.17,-0.06 -0.19,-0.13c-0.04,-0.13 0.06,-0.21 0.31,-0.24c0.18,-0.03 0.36,-0.02 0.5,0.03c0.24,0.08 0.2,0.29 -0.06,0.35c-0.14,0.03 -0.46,0.02 -0.56,-0.01zm-39.38,-0.25c-0.23,-0.04 -0.33,-0.13 -0.29,-0.26c0.02,-0.05 0.05,-0.08 0.12,-0.11c0.09,-0.04 0.12,-0.05 0.42,-0.05c0.3,0 0.33,0.01 0.41,0.05c0.14,0.07 0.16,0.17 0.07,0.27c-0.03,0.03 -0.1,0.06 -0.14,0.08c-0.11,0.03 -0.46,0.04 -0.59,0.02zm42.15,-0.99c0,-0.11 -0.01,-0.4 -0.02,-0.64l-0.01,-0.45l0.06,0c0.5,0 1.85,-0.15 2.49,-0.28c0.15,-0.03 0.27,-0.05 0.27,-0.04c0.01,0.01 -0.03,1.3 -0.05,1.31c-0.02,0.02 -0.58,0.13 -0.89,0.18c-0.51,0.07 -1.16,0.12 -1.62,0.12l-0.21,0l-0.02,-0.2zm-0.78,0.17c-0.56,-0.05 -1.23,-0.14 -1.76,-0.24c-0.32,-0.07 -0.64,-0.14 -0.65,-0.16c-0.01,-0.01 -0.06,-1.04 -0.06,-1.2l0.01,-0.13l0.16,0.05c0.71,0.21 1.64,0.37 2.42,0.41l0.29,0.01l0,0.59c0,0.32 0,0.61 0.01,0.63c0.01,0.05 0.01,0.05 -0.16,0.05c-0.09,-0.01 -0.21,-0.01 -0.26,-0.01zm-40.66,-0.05c-0.37,-0.03 -0.81,-0.08 -1.15,-0.13c-0.48,-0.09 -0.44,-0.07 -0.46,-0.18c-0.01,-0.13 -0.04,-1.23 -0.03,-1.23c0.01,0 0.17,0.03 0.35,0.06c0.62,0.11 1.41,0.2 2.11,0.24c0.19,0.01 0.35,0.03 0.36,0.03c0,0 -0.01,0.28 -0.02,0.61l-0.02,0.61l-0.44,0c-0.24,0 -0.55,0 -0.7,-0.01zm1.51,-0.61l0,-0.6l0.25,-0.01c0.81,-0.05 1.7,-0.19 2.39,-0.39c0.13,-0.04 0.24,-0.07 0.24,-0.07c0.01,0.01 -0.05,1.28 -0.05,1.29c-0.02,0.01 -0.71,0.15 -0.98,0.19c-0.51,0.09 -1.48,0.2 -1.76,0.2l-0.09,0l0,-0.61zm37.75,-2.39c-0.01,-0.06 -0.01,-0.19 -0.01,-0.3c0,-0.23 -0.05,-0.2 0.37,-0.26c1.1,-0.16 1.95,-0.18 2.89,-0.07c0.37,0.04 0.34,0.02 0.33,0.26c-0.03,0.39 -0.03,0.42 -0.08,0.41c-0.03,-0.01 -0.19,-0.03 -0.37,-0.05c-0.67,-0.07 -1.86,-0.04 -2.78,0.08c-0.17,0.02 -0.32,0.04 -0.33,0.04c0,0 -0.01,-0.05 -0.02,-0.11zm-39.96,0.05c-0.01,-0.02 -0.01,-0.15 -0.02,-0.3l0,-0.26l0.12,-0.02c0.18,-0.04 0.85,-0.13 1.15,-0.15c0.69,-0.06 1.63,-0.01 2.63,0.14l0.16,0.03l-0.01,0.26c0,0.15 -0.01,0.27 -0.01,0.28c0,0 -0.1,-0.01 -0.22,-0.03c-1.07,-0.18 -2.43,-0.16 -3.57,0.05c-0.11,0.02 -0.21,0.04 -0.22,0.04c0,0 0,-0.02 -0.01,-0.04zm76.3,-8.22c-0.43,-2.65 -0.79,-4.82 -0.8,-4.83c-0.01,-0.01 -0.13,-0.04 -0.27,-0.07c-0.52,-0.1 -1.12,-0.34 -1.55,-0.59c-0.32,-0.19 -0.55,-0.37 -0.8,-0.62c-1.04,-1.05 -1.05,-2.3 -0.02,-3.26c0.28,-0.27 0.53,-0.43 1.19,-0.8c0.17,-0.09 0.41,-0.23 0.54,-0.31c0.21,-0.15 0.75,-0.54 0.91,-0.67l0.06,-0.06l-0.38,-0.87c-0.2,-0.48 -0.4,-0.93 -0.44,-1.01c-0.05,-0.13 -0.07,-0.15 -0.1,-0.14c-0.02,0 -0.5,0.2 -1.05,0.44c-0.56,0.24 -1.01,0.44 -1.02,0.43c0,0 -0.02,-0.09 -0.04,-0.19l-0.03,-0.18l0.18,-0.25c0.09,-0.15 0.16,-0.26 0.15,-0.26c-0.02,0 -0.2,0.01 -0.4,0.03c-0.2,0.02 -0.37,0.03 -0.38,0.03c0,-0.01 -0.2,-0.32 -0.43,-0.69l-0.43,-0.69l0.22,-0.28c0.12,-0.16 0.22,-0.3 0.23,-0.31c0.01,-0.02 -0.12,-0.06 -0.42,-0.14c-0.25,-0.07 -0.47,-0.13 -0.51,-0.14c-0.06,-0.01 -0.06,-0.02 -0.05,-0.06c0.01,-0.03 0.04,-0.12 0.07,-0.21l0.05,-0.16l-0.26,-0.11c-0.19,-0.08 -0.26,-0.12 -0.25,-0.14c0.01,-0.02 0.18,-0.31 0.39,-0.66l0.38,-0.63l2.05,-0.87l2.05,-0.87l0.69,-0.07c0.38,-0.03 0.74,-0.06 0.79,-0.07l0.1,-0.01l-0.32,0.33l-0.32,0.33l0.41,0.03c0.23,0.01 0.42,0.03 0.43,0.04c0,0 0.09,0.29 0.19,0.63l0.18,0.61l-0.09,0.31c-0.04,0.16 -0.08,0.31 -0.08,0.32c0,0.02 0.1,0.06 0.22,0.09c0.13,0.04 0.23,0.07 0.24,0.07c0,0.01 0.06,1.7 0.06,1.7c-0.01,0 -0.39,0.25 -0.86,0.54c-0.46,0.29 -0.85,0.54 -0.86,0.54c-0.02,0.02 0.53,1.7 0.55,1.7c0.01,0 0.32,-0.31 0.7,-0.7c0.38,-0.38 0.81,-0.81 0.96,-0.95c0.95,-0.88 1.67,-1.28 2.58,-1.44c0.39,-0.07 1.11,-0.06 1.75,0.03l0.1,0.01l0,-0.93l0,-0.93l-0.05,0.01c-0.02,0 -0.14,0.02 -0.25,0.03c-0.83,0.08 -1.5,-0.08 -2.15,-0.51c-0.27,-0.18 -0.5,-0.37 -1.04,-0.85c-0.21,-0.19 -0.44,-0.39 -0.5,-0.44l-0.11,-0.1l0.17,-0.01c1.44,-0.12 2.71,-0.8 3.61,-1.92c0.21,-0.26 0.43,-0.6 0.58,-0.9l0.13,-0.23l-0.06,0.01c-0.08,0.02 -0.31,0.02 -0.42,0c-0.23,-0.06 -0.5,-0.18 -0.77,-0.36c-0.17,-0.11 -0.57,-0.42 -0.55,-0.43c0,0 0.09,-0.03 0.2,-0.05c1.13,-0.3 2.21,-1.15 2.9,-2.29c0.07,-0.1 0.08,-0.13 0.05,-0.12c-0.02,0.01 -0.13,0.02 -0.25,0.02c-0.34,0.02 -0.62,-0.08 -0.93,-0.34c-0.14,-0.12 -0.36,-0.36 -0.41,-0.45c-0.01,-0.03 -0.01,-0.03 0.04,-0.02c0.23,0.05 0.38,0.06 0.55,0.03c0.8,-0.11 1.66,-0.92 2.59,-2.4c0.52,-0.83 1.17,-2.12 1.59,-3.17c0.05,-0.12 0.1,-0.23 0.11,-0.24c0.01,-0.01 0,0.12 -0.01,0.27c-0.08,0.95 -0.09,2.59 -0.02,3.37c0.2,2.22 0.78,3.51 1.75,3.9l0.16,0.06l-0.08,0.08c-0.05,0.04 -0.16,0.11 -0.25,0.15c-0.55,0.27 -1.12,0.15 -1.66,-0.35l-0.09,-0.08l0.01,0.21c0.07,1.16 0.47,2.16 1.24,3.07c0.16,0.2 0.48,0.51 0.66,0.66l0.1,0.09l-0.07,0.07c-0.04,0.04 -0.14,0.11 -0.24,0.16c-0.15,0.07 -0.18,0.08 -0.36,0.09c-0.17,0.01 -0.23,0 -0.35,-0.03c-0.29,-0.09 -0.58,-0.28 -0.87,-0.58l-0.17,-0.18l0.02,0.37c0.01,0.56 0.09,1 0.28,1.57c0.38,1.14 1.11,2.31 2.03,3.27l0.19,0.2l-0.12,0.05c-0.85,0.38 -1.68,0.48 -2.49,0.31c-0.63,-0.14 -1.32,-0.48 -1.98,-0.98l-0.26,-0.19l-0.16,0.33c-0.1,0.18 -0.27,0.51 -0.38,0.73l-0.21,0.41l0.27,0.11c1.18,0.46 1.96,1.12 2.14,1.8c0.04,0.16 0.04,0.48 0,0.64c-0.08,0.35 -0.56,1.41 -0.9,1.99c-0.51,0.88 -1.07,1.61 -1.81,2.36c-0.57,0.58 -1.05,0.98 -1.61,1.36l-0.27,0.18l-0.46,1.86c-0.26,1.02 -0.47,1.86 -0.48,1.86c-0.01,0 -0.29,-0.71 -0.62,-1.58c-0.34,-0.87 -0.63,-1.58 -0.64,-1.58c-0.03,0 -1.92,0.55 -1.93,0.56c-0.01,0.01 -0.2,2.23 -0.43,4.93c-0.22,2.71 -0.41,4.93 -0.42,4.95c-0.01,0.02 -0.37,-2.13 -0.8,-4.78zm-1.18,-14.15c0.09,-0.05 0.16,-0.15 0.2,-0.28c0.08,-0.32 -0.19,-0.64 -0.47,-0.55c-0.21,0.07 -0.33,0.36 -0.25,0.59c0.08,0.24 0.31,0.34 0.52,0.24zm-0.45,-1.37c0.03,-0.03 0.08,-0.09 0.1,-0.14c0.05,-0.09 0.05,-0.13 0.05,-0.32c-0.01,-0.35 -0.12,-0.74 -0.4,-1.32c-0.17,-0.34 -0.27,-0.48 -0.41,-0.56c-0.29,-0.17 -0.65,0.07 -0.73,0.5c-0.05,0.19 0.03,0.36 0.17,0.36c0.15,0 0.26,0.16 0.52,0.76c0.33,0.75 0.46,0.88 0.7,0.72zm-120.63,-2.29c-1.46,-0.11 -2.79,-1.03 -3.46,-2.4l-0.1,-0.2l-0.36,-0.14c-1.38,-0.53 -3.07,-1.31 -4.29,-2c-0.74,-0.41 -1.38,-0.87 -2.01,-1.43c-0.12,-0.1 -0.22,-0.19 -0.22,-0.2c0,-0.02 0.4,-0.2 0.59,-0.27c1.1,-0.37 2.76,-0.47 4.74,-0.27c0.46,0.05 1.07,0.14 1.12,0.17c0.02,0.01 0.02,0.04 0,0.11c-0.04,0.25 0,0.56 0.14,0.84c0.05,0.11 0.09,0.19 0.1,0.18c0,0 0.04,-0.11 0.09,-0.25c0.68,-1.95 2.62,-3.16 4.62,-2.86c0.69,0.1 1.37,0.38 1.94,0.81c0.75,0.58 1.31,1.43 1.56,2.38c0.1,0.37 0.13,0.61 0.14,1.03c0.01,0.21 0.02,0.37 0.03,0.37c0.03,0 0.26,-0.23 0.32,-0.31c0.1,-0.15 0.15,-0.34 0.14,-0.53c0,-0.08 0,-0.15 0,-0.15c0.03,0 0.94,0.21 1.23,0.28c2.23,0.55 4.06,1.42 5.06,2.38l0.17,0.17l-0.38,0.11c-0.78,0.23 -1.91,0.51 -2.47,0.61c-1.19,0.21 -3.31,0.34 -4.81,0.3l-0.53,-0.01l-0.17,0.16c-0.68,0.64 -1.59,1.04 -2.55,1.12c-0.29,0.02 -0.33,0.02 -0.64,0zm5.94,-1.79c1.33,-0.11 2.27,-0.25 3.72,-0.56c0.36,-0.08 0.68,-0.15 0.69,-0.15c0.02,-0.01 -0.02,-0.04 -0.1,-0.09c-0.65,-0.42 -1.27,-0.73 -1.65,-0.82c-0.13,-0.03 -0.15,-0.03 -0.28,0c-0.19,0.04 -0.79,0.14 -1.13,0.19c-2.34,0.33 -4.78,0.32 -6.9,-0.04c-2.33,-0.39 -5.05,-1.5 -7.2,-2.92c-0.23,-0.15 -0.45,-0.29 -0.49,-0.3c-0.19,-0.05 -0.83,-0.01 -1.27,0.09c-0.32,0.08 -0.59,0.2 -0.59,0.26c0,0.03 0.79,0.55 1.33,0.88c3.51,2.1 7.15,3.26 10.97,3.49c0.47,0.03 2.46,0.01 2.9,-0.03zm-7.37,-4.17c0.12,-0.06 0.27,-0.18 0.53,-0.43c0.27,-0.26 0.41,-0.36 0.66,-0.45c0.34,-0.12 0.44,-0.19 0.47,-0.32c0.04,-0.17 -0.13,-0.41 -0.35,-0.51c-0.17,-0.08 -0.42,-0.11 -0.64,-0.08c-0.52,0.07 -0.88,0.3 -1.07,0.7c-0.21,0.44 -0.25,0.86 -0.08,1.04c0.12,0.13 0.28,0.15 0.48,0.05zm100.62,4.61c-0.19,-0.08 -0.14,-0.22 0.28,-0.65c0.16,-0.17 0.3,-0.34 0.32,-0.37c0.03,-0.06 0.04,-0.14 0.05,-0.44c0.01,-0.36 0.01,-0.38 0.07,-0.48c0.04,-0.08 0.05,-0.1 0.03,-0.12c-0.12,-0.11 -0.29,-0.23 -0.31,-0.22c-0.01,0 -0.25,0.1 -0.53,0.22c-0.55,0.24 -1.51,0.62 -1.75,0.71c-0.28,0.09 -0.69,0.09 -1.02,-0.02c-0.25,-0.08 -0.35,-0.17 -0.29,-0.28c0.03,-0.07 0.26,-0.23 0.73,-0.51c0.43,-0.25 0.66,-0.41 0.71,-0.5c0.02,-0.03 0.04,-0.15 0.06,-0.28c0.05,-0.52 0.17,-0.76 0.58,-1.21l0.16,-0.18l-0.13,-0.2c-0.16,-0.24 -0.46,-0.84 -0.56,-1.12c-0.28,-0.75 -0.41,-1.5 -0.41,-2.37c0,-0.8 0.1,-1.54 0.3,-2.21c0.03,-0.11 0.05,-0.2 0.05,-0.2c0,0 -0.07,-0.04 -0.16,-0.08c-0.21,-0.11 -0.39,-0.3 -0.5,-0.52c-0.1,-0.21 -0.14,-0.39 -0.14,-0.67l0,-0.22l-0.06,0c-0.18,0 -0.39,-0.24 -0.43,-0.49c-0.05,-0.33 0.17,-0.83 0.51,-1.16c0.21,-0.2 0.23,-0.17 0.07,0.1c-0.23,0.38 -0.29,0.54 -0.29,0.81c0,0.15 0.01,0.2 0.04,0.24c0.05,0.07 0.13,0.11 0.2,0.08c0.05,-0.01 0.07,-0.04 0.12,-0.16c0.16,-0.41 0.45,-0.73 0.68,-0.73c0.08,0 0.19,0.07 0.23,0.16c0.09,0.17 -0.02,0.47 -0.28,0.75c-0.08,0.09 -0.19,0.19 -0.24,0.22c-0.07,0.05 -0.09,0.08 -0.09,0.12c0,0.08 0.08,0.32 0.14,0.42c0.1,0.19 0.33,0.33 0.51,0.33c0.07,0 0.07,0 0.18,-0.21c0.27,-0.55 0.72,-1.1 1.18,-1.48c0.57,-0.46 1.26,-0.79 2.03,-0.98c0.77,-0.18 1.75,-0.21 2.58,-0.08c1.02,0.17 2,0.54 2.68,1.02c0.04,0.03 0.04,0.03 0.05,-0.08c0.06,-0.57 0.12,-0.83 0.27,-1.12c0.08,-0.16 0.3,-0.48 0.35,-0.52c0.01,0 0.03,-0.03 0.04,-0.05c0.03,-0.04 0.02,-0.04 -0.08,-0.03c-0.15,0.02 -0.53,-0.02 -0.75,-0.07c-0.35,-0.08 -0.6,-0.26 -0.73,-0.51c-0.03,-0.06 -0.08,-0.19 -0.11,-0.29c-0.05,-0.16 -0.05,-0.21 -0.06,-0.48c0,-0.34 0.03,-0.49 0.16,-0.73c0.06,-0.12 0.19,-0.25 0.25,-0.25c0.05,0 0.07,0.09 0.05,0.2c-0.06,0.25 -0.01,0.37 0.17,0.46c0.11,0.05 0.14,0.05 0.39,0.05l0.27,0l0.06,-0.07c0.08,-0.1 0.36,-0.34 0.52,-0.44c0.5,-0.32 0.99,-0.28 1.4,0.11c0.17,0.17 0.32,0.37 0.44,0.6l0.08,0.15l0.11,-0.06c0.19,-0.09 0.41,-0.16 0.55,-0.16l0.13,0l0.02,-0.13c0.09,-0.51 0.37,-0.95 0.71,-1.12c0.22,-0.1 0.38,-0.13 0.72,-0.13c0.24,0 0.33,0.01 0.46,0.05c0.21,0.05 0.42,0.17 0.52,0.27c0.07,0.08 0.08,0.08 0.2,0.09c0.35,0.01 0.77,0.25 0.9,0.52c0.09,0.17 0.1,0.42 0.03,0.62c-0.05,0.15 -0.18,0.32 -0.25,0.32c-0.06,0 -0.28,-0.22 -0.56,-0.57c-0.13,-0.16 -0.18,-0.2 -0.24,-0.22c-0.11,-0.03 -0.21,0 -0.34,0.12c-0.17,0.15 -0.17,0.14 0.08,0.24c0.85,0.34 1.52,1.05 1.72,1.84l0.02,0.08l0.1,-0.02c0.34,-0.09 0.89,-0.1 1.23,-0.01c0.24,0.06 0.46,0.16 0.65,0.3c0.17,0.11 0.43,0.36 0.54,0.52c0.13,0.18 0.34,0.56 0.42,0.74c0.33,0.8 0.2,1.76 -0.38,2.77c-0.35,0.6 -0.89,1.27 -1.45,1.8c-0.12,0.11 -0.22,0.22 -0.22,0.23c0,0.03 0.17,0.18 0.3,0.26c0.25,0.15 0.52,0.22 1.22,0.35c0.24,0.05 0.49,0.1 0.55,0.13c0.15,0.05 0.25,0.15 0.25,0.23c0,0.5 -1.36,0.98 -2.91,1.01l-0.48,0.01l-0.26,0.27c-0.15,0.14 -0.37,0.37 -0.5,0.5l-0.22,0.24l0.03,0.06c0.04,0.07 0.19,0.15 0.38,0.19c0.07,0.02 0.33,0.05 0.58,0.08c0.69,0.08 0.88,0.14 1.01,0.29c0.16,0.18 0.01,0.39 -0.43,0.6c-0.44,0.22 -1.07,0.36 -1.9,0.42c-0.36,0.03 -1.23,0.01 -1.61,-0.02l-0.24,-0.03l-0.18,0.14c-1.07,0.84 -2.21,1.42 -3.41,1.72c-0.69,0.18 -1.3,0.26 -2.02,0.26c-0.67,0 -1.02,-0.04 -1.78,-0.18l-0.39,-0.08l-0.16,0.14c-0.69,0.6 -1.71,1.1 -2.72,1.32c-0.32,0.06 -0.74,0.08 -0.85,0.03zm12.55,-10.03c0.04,-0.45 -0.11,-0.75 -0.43,-0.88c-0.1,-0.04 -0.15,-0.05 -0.37,-0.04c-0.14,0 -0.28,0.01 -0.31,0.02l-0.06,0.02l0.08,0c0.27,0.01 0.57,0.13 0.74,0.31c0.18,0.18 0.27,0.4 0.29,0.73c0.02,0.14 0.02,0.16 0.03,0.1c0.01,-0.04 0.03,-0.16 0.03,-0.26zm0.87,-0.65c0.45,-0.08 1.05,-0.32 1.43,-0.56c0.25,-0.17 0.49,-0.41 0.57,-0.57c0.09,-0.18 0.09,-0.35 0.01,-0.5c-0.17,-0.3 -0.57,-0.74 -0.85,-0.94c-0.75,-0.51 -1.44,-0.33 -1.85,0.5c-0.2,0.38 -0.36,1.01 -0.4,1.57c-0.01,0.14 -0.01,0.18 0.03,0.25c0.07,0.14 0.22,0.24 0.42,0.27c0.14,0.03 0.43,0.01 0.64,-0.02zm-0.57,-0.5c-0.03,-0.02 -0.06,-0.08 -0.07,-0.14c-0.06,-0.24 0.1,-0.86 0.28,-1.05c0.07,-0.07 0.11,-0.08 0.17,-0.05c0.21,0.11 0.17,0.84 -0.07,1.15c-0.09,0.12 -0.23,0.16 -0.31,0.09zm1.74,-0.93c-0.31,-0.15 -0.51,-0.65 -0.29,-0.77c0.09,-0.04 0.14,-0.04 0.28,0.03c0.27,0.14 0.5,0.5 0.43,0.67c-0.05,0.13 -0.24,0.16 -0.42,0.07zm1.43,0.68c-0.27,-0.27 -0.33,-0.7 -0.15,-1.22c0.08,-0.25 0.04,-0.22 -0.12,0.12c-0.28,0.55 -0.2,0.93 0.24,1.14c0.06,0.03 0.12,0.06 0.12,0.06c0.01,0 -0.03,-0.04 -0.09,-0.1zm-4.91,-0.77c0.19,-0.06 0.34,-0.31 0.31,-0.52c-0.03,-0.26 -0.22,-0.43 -0.47,-0.43c-0.13,0 -0.22,0.03 -0.31,0.12c-0.09,0.09 -0.12,0.17 -0.14,0.31c-0.02,0.21 0.09,0.4 0.27,0.49c0.11,0.06 0.22,0.06 0.34,0.03zm-12.89,-0.47c0.12,-0.12 0.13,-0.17 0.05,-0.19c-0.09,-0.02 -0.2,0.1 -0.24,0.27c-0.01,0.07 -0.01,0.07 0.03,0.05c0.03,-0.02 0.1,-0.08 0.16,-0.13zm15.81,-1.25c0.18,-0.05 0.31,-0.22 0.31,-0.43c0,-0.14 -0.04,-0.24 -0.13,-0.33c-0.09,-0.1 -0.17,-0.14 -0.29,-0.14c-0.14,0 -0.27,0.07 -0.36,0.19c-0.07,0.11 -0.09,0.3 -0.04,0.43c0.04,0.11 0.16,0.23 0.27,0.27c0.09,0.04 0.13,0.04 0.24,0.01zm-27.93,13.85c-0.55,-0.01 -0.85,-0.04 -0.92,-0.08c-0.06,-0.03 -0.06,-0.02 0.27,-1.03c0.13,-0.39 0.43,-1.31 0.67,-2.06c0.54,-1.7 0.74,-2.29 0.79,-2.29c0.06,0 0.22,0.22 0.41,0.57c0.13,0.23 1.15,2.28 1.54,3.1c0.45,0.94 0.73,1.58 0.73,1.64c0,0.03 -0.13,0.07 -0.33,0.09c-0.5,0.06 -2.19,0.09 -3.16,0.06zm-66.81,-10.79c-0.3,-1.97 -0.61,-3.96 -0.68,-4.42c-1.93,-12.7 -3.52,-21.86 -4.31,-24.86c-0.18,-0.65 -0.34,-1.12 -0.44,-1.23c-0.02,-0.02 -0.14,-0.09 -0.27,-0.15c-0.72,-0.37 -2.43,-1 -5.02,-1.86l-1.01,-0.34l0.16,-0.1c0.23,-0.13 1.23,-0.63 1.52,-0.76c0.63,-0.26 1.22,-0.46 1.71,-0.56c0.23,-0.04 0.31,-0.05 0.64,-0.05c0.45,0 0.66,0.03 1.66,0.23c0.77,0.15 1.2,0.23 1.55,0.26c0.13,0.02 0.24,0.03 0.25,0.03c0.06,0.04 0.27,1.24 0.83,4.62c0.91,5.55 1.26,7.51 1.55,8.71c0.09,0.34 0.19,0.67 0.23,0.69c0.02,0.01 0.02,-0.21 -0.01,-0.51c-0.1,-0.86 -0.33,-2.3 -1.09,-6.81c-0.79,-4.78 -0.99,-5.98 -1.04,-6.51c-0.02,-0.16 0.01,-0.22 0.12,-0.27c0.29,-0.12 1.09,0.04 1.72,0.34c0.41,0.2 0.5,0.32 0.81,1.06c0.62,1.48 1.23,4.19 1.83,8.09c0.35,2.25 0.66,4.6 1.14,8.69c0.54,4.47 0.65,5.37 0.81,6.24c0.09,0.46 0.19,0.77 0.23,0.74c0.17,-0.11 -0.33,-5.75 -1.39,-15.6c-0.27,-2.51 -0.5,-4.65 -0.52,-4.74l-0.01,-0.07l0.52,-0.04c1.47,-0.13 2.42,-0.28 2.54,-0.38c0.02,-0.03 0.02,-0.03 -0.05,-0.06c-0.19,-0.08 -0.73,-0.09 -1.7,-0.04c-0.88,0.05 -1.41,0.04 -1.41,-0.02c0,-0.01 -0.01,-0.09 -0.03,-0.19c-0.01,-0.1 -0.05,-0.44 -0.09,-0.76c-0.03,-0.33 -0.07,-0.62 -0.08,-0.66c-0.06,-0.21 -0.38,-0.47 -0.79,-0.63l-0.07,-0.03l0.06,0c0.04,0 0.55,-0.02 1.14,-0.04c1.88,-0.05 3.26,-0.09 4.21,-0.12l0.92,-0.03l0.32,0.14c0.73,0.29 1.55,0.7 2.09,1.03c0.66,0.41 1.15,0.86 1.32,1.23c0.14,0.29 0.54,2.02 0.8,3.48c0.21,1.15 0.43,2.67 0.41,2.76c-0.02,0.07 -0.15,0.15 -0.32,0.19c-0.25,0.05 -0.52,0.07 -1.47,0.09c-1.03,0.02 -1.38,0.04 -1.62,0.1c-0.24,0.06 -0.35,0.14 -0.23,0.18c0.08,0.02 0.65,0.01 1.24,-0.03c1.55,-0.09 2.23,-0.08 2.49,0.05c0.08,0.04 0.1,0.07 0.1,0.17c0,0.04 0.04,0.33 0.1,0.66c0.06,0.33 0.27,1.63 0.49,2.88c0.83,4.95 1.14,6.61 1.48,7.97c0.09,0.35 0.25,0.87 0.26,0.86c0.04,-0.05 -0.83,-7.3 -0.99,-8.2c-0.09,-0.52 -0.2,-1.25 -0.44,-2.87c-0.69,-4.62 -1.02,-6.36 -1.31,-7c-0.07,-0.16 -0.12,-0.21 -0.21,-0.21c-0.03,0 -0.08,-0.02 -0.1,-0.03c-0.04,-0.03 -0.04,-0.03 0.01,-0.07c0.07,-0.05 0.16,-0.08 0.37,-0.11l0.19,-0.02l2.09,0.39l2.09,0.4l0.88,0.64c0.49,0.36 0.89,0.65 0.89,0.65c0,0.01 0.05,0.27 0.1,0.6c1.25,8.36 1.95,12.86 2.05,13.18c0.03,0.11 0.13,0.23 0.18,0.22c0.09,-0.01 0.1,-0.12 0.08,-0.55c-0.03,-0.55 -0.09,-0.99 -0.23,-1.81c-0.13,-0.78 -0.16,-1.13 -0.12,-1.27c0.07,-0.19 0.17,-0.26 0.45,-0.29c0.11,-0.01 0.33,-0.04 0.49,-0.06c1.04,-0.14 2.18,-0.16 3,-0.05c1.56,0.2 2.43,0.78 2.63,1.74c0.03,0.15 0.64,8.83 0.63,8.91c0,0.03 -0.07,-0.04 -0.24,-0.24c-0.13,-0.16 -0.23,-0.3 -0.24,-0.31c0,-0.01 0.01,-0.02 0.04,-0.02c0.04,0 0.15,-0.09 0.17,-0.14c0.01,-0.03 -0.03,-0.11 -0.13,-0.27c-0.17,-0.27 -0.39,-0.72 -0.5,-1c-0.15,-0.42 -0.25,-0.94 -0.22,-1.24l0.01,-0.13l-0.08,0.16c-0.59,1.12 -0.68,1.41 -0.75,2.17c-0.01,0.17 -0.03,0.3 -0.03,0.31c0,0 -0.06,-0.06 -0.12,-0.13c-0.07,-0.07 -0.25,-0.26 -0.42,-0.43c-0.16,-0.17 -0.35,-0.39 -0.43,-0.49c-0.33,-0.45 -0.64,-1.14 -1.05,-2.33c-0.09,-0.26 -0.16,-0.46 -0.16,-0.46c-0.01,0 0,0.21 0.02,0.45c0.17,2.67 0.14,3.91 -0.11,4.23l-0.05,0.07l0.1,0c0.22,0 0.35,-0.14 0.42,-0.44c0.02,-0.08 0.04,-0.14 0.04,-0.15c0.02,-0.01 0.1,0.17 0.13,0.3c0.04,0.17 0.05,0.84 0.01,1.16c-0.14,1.12 -0.47,2.13 -0.75,2.24c-0.05,0.02 -0.07,0.02 -0.15,-0.02c-0.17,-0.09 -0.43,-0.38 -0.56,-0.64c-0.06,-0.11 -0.05,-0.13 0.01,-0.09c0.17,0.11 0.61,0.01 0.73,-0.17c0.03,-0.05 0.03,-0.05 -0.07,-0.16c-0.29,-0.3 -0.58,-0.71 -0.78,-1.13c-0.16,-0.32 -0.25,-0.58 -0.35,-0.93c-0.06,-0.26 -0.06,-0.26 -0.02,-0.25c0.19,0.06 0.34,0.03 0.41,-0.08c0.03,-0.05 0.03,-0.05 0,-0.07c-0.08,-0.04 -0.21,-0.18 -0.28,-0.28c-0.13,-0.21 -0.25,-0.63 -0.36,-1.31c-0.06,-0.4 -0.18,-1.31 -0.18,-1.4c0,-0.12 -0.04,-0.05 -0.06,0.11c-0.04,0.29 -0.16,0.86 -0.26,1.24c-0.21,0.81 -0.42,1.33 -0.65,1.57l-0.12,0.11l0.04,0.05c0.08,0.11 0.24,0.16 0.38,0.11c0.08,-0.03 0.08,-0.03 0.08,0.01c0,0.08 -0.07,0.35 -0.14,0.51c-0.08,0.18 -0.22,0.41 -0.33,0.52c-0.07,0.06 -0.08,0.06 -0.15,0.04c-0.12,-0.03 -0.25,-0.16 -0.33,-0.32c-0.14,-0.27 -0.21,-0.56 -0.29,-1.26c-0.07,-0.57 -0.13,-1.01 -0.16,-1.15l-0.03,-0.11l-0.05,0.22c-0.03,0.12 -0.1,0.45 -0.17,0.74c-0.28,1.28 -0.52,1.83 -0.88,2.09l-0.06,0.04l0.26,0.12c0.32,0.14 0.35,0.17 0.35,0.34c0,0.23 -0.13,0.55 -0.56,1.4c-0.16,0.3 -0.32,0.63 -0.36,0.72l-0.08,0.18l-0.05,-0.28c-0.17,-0.86 -0.91,-3.38 -1.11,-3.8c-0.07,-0.14 -0.07,-0.12 -0.02,0.08c0.1,0.36 0.1,1.25 0,2.14c-0.1,0.98 -0.3,1.94 -0.47,2.34c-0.04,0.1 -0.13,0.21 -0.17,0.21c-0.02,0 -0.62,0.41 -1.33,0.91c-1.02,0.7 -1.3,0.9 -1.31,0.87c-0.01,-0.02 -0.06,-0.23 -0.11,-0.47c-0.06,-0.24 -0.11,-0.44 -0.11,-0.43c-0.01,0.01 -0.14,0.31 -0.29,0.67c-0.15,0.36 -0.28,0.66 -0.29,0.67c0,0 -0.67,0.27 -1.49,0.59l-1.48,0.58l-0.01,-0.1c0,-0.15 0.09,-2.76 0.1,-2.78c0.01,0 0.12,0.01 0.26,0.03c0.13,0.02 0.47,0.07 0.75,0.11c0.28,0.03 0.55,0.06 0.6,0.07c0.09,0.01 0.11,0.03 -0.26,-0.18c-0.46,-0.26 -0.88,-0.55 -1.24,-0.87l-0.08,-0.07l0.03,-0.76c0.01,-0.41 0.03,-0.8 0.03,-0.87l0.01,-0.11l0.12,0.06c0.16,0.07 0.35,0.12 0.72,0.19c0.17,0.03 0.32,0.05 0.35,0.06c0.02,0.01 0.04,0.01 0.04,0c0,0 -0.13,-0.1 -0.3,-0.22c-0.37,-0.27 -0.62,-0.47 -0.77,-0.65l-0.12,-0.13l0,-0.62c0,-0.34 0,-0.62 0.01,-0.62c0,0 0.04,0.02 0.09,0.03c0.14,0.05 0.38,0.08 0.54,0.06c0.15,-0.01 0.16,-0.01 0.12,-0.04c-0.03,-0.02 -0.13,-0.08 -0.22,-0.14c-0.2,-0.11 -0.34,-0.23 -0.42,-0.34c-0.05,-0.07 -0.06,-0.12 -0.08,-0.32c-0.03,-0.27 -0.02,-0.82 0.02,-1.19c0.04,-0.4 0.01,-0.34 -0.11,0.22c-0.19,0.92 -0.35,1.51 -0.52,1.99c-0.06,0.16 -0.07,0.18 -0.19,0.28c-0.25,0.19 -0.48,0.28 -1.06,0.41c-0.13,0.03 -0.24,0.06 -0.23,0.07c0,0.01 0.08,0.02 0.17,0.03c0.1,0.01 0.27,0.02 0.39,0.04c0.24,0.02 0.45,0.01 0.6,-0.04c0.05,-0.01 0.09,-0.02 0.1,-0.02c0,0 -0.07,0.42 -0.16,0.93l-0.16,0.92l-0.07,0.05c-0.09,0.08 -0.28,0.19 -0.48,0.27c-0.13,0.05 -1.01,0.33 -1.07,0.33c-0.02,0.01 0.65,0.15 0.83,0.18c0.19,0.03 0.37,0.03 0.5,0.01l0.09,-0.02l0,0.08c0,0.04 -0.04,0.44 -0.07,0.9c-0.04,0.45 -0.07,0.84 -0.07,0.86c0,0.04 -0.21,0.2 -0.4,0.31c-0.29,0.18 -0.62,0.27 -1.28,0.39c-0.2,0.04 -0.37,0.08 -0.37,0.08c0,0.01 0.04,0.02 0.09,0.03c0.06,0.01 0.28,0.06 0.52,0.11c0.59,0.15 0.86,0.17 1.25,0.09l0.07,-0.01l-0.01,0.15c-0.01,0.08 -0.02,0.34 -0.03,0.56c-0.01,0.23 -0.02,0.46 -0.02,0.52l-0.02,0.1l-1.22,0.22c-0.9,0.17 -1.23,0.22 -1.25,0.21c-0.01,-0.02 -0.15,-0.3 -0.31,-0.64c-0.16,-0.34 -0.3,-0.65 -0.32,-0.69c-0.04,-0.07 -0.04,-0.06 -0.03,0.71c0.01,0.66 0.01,0.79 -0.01,0.8c-0.04,0.01 -3.41,0.59 -3.45,0.59c-0.04,0 -0.09,-0.3 -0.58,-3.57zm8.91,-7.86c0,-0.01 -0.01,0 -0.01,0.03c0,0.03 0.01,0.04 0.01,0.02c0.01,-0.01 0.01,-0.03 0,-0.05zm-11.13,9.74l-0.7,-1.47l-0.44,-5.46c-0.24,-3 -0.44,-5.48 -0.43,-5.51c0,-0.03 0.51,3.09 1.14,6.92c0.63,3.84 1.14,6.98 1.13,6.98c0,0.01 -0.32,-0.65 -0.7,-1.46zm-10.04,-0.56c-0.53,-1.79 -1.93,-6.89 -1.93,-7.01c0,-0.01 0.05,-0.01 0.11,0c0.09,0 0.12,0 0.22,-0.05l0.12,-0.05l-0.06,-0.05c-0.18,-0.15 -0.65,-1.03 -1.28,-2.4c-0.05,-0.11 -0.1,-0.19 -0.1,-0.19c0,0 -0.03,0.19 -0.07,0.42c-0.18,1.02 -0.41,1.86 -0.61,2.26c-0.06,0.12 -0.2,0.28 -0.25,0.28c-0.02,0 0.02,0.03 0.08,0.06c0.14,0.07 0.25,0.07 0.37,0c0.05,-0.03 0.09,-0.06 0.1,-0.06c0,0 -0.03,0.13 -0.08,0.28c-0.11,0.33 -0.56,1.81 -0.61,1.97l-0.03,0.12l-0.11,-0.18c-0.06,-0.09 -0.14,-0.21 -0.16,-0.24c-0.1,-0.13 -0.38,-0.41 -0.6,-0.6c-0.34,-0.28 -0.45,-0.45 -0.52,-0.81c-0.04,-0.22 -0.02,-0.97 0.04,-1.39c0.02,-0.17 0.03,-0.31 0.03,-0.31c-0.01,-0.02 -0.19,0.24 -0.29,0.41c-0.63,1.1 -1.08,2.86 -1.17,4.59c-0.01,0.15 -0.02,0.27 -0.03,0.27c-0.05,0 -0.31,-0.55 -0.5,-1.06c-0.39,-1.01 -0.59,-1.95 -0.59,-2.71c0,-0.37 0.02,-0.56 0.1,-0.87c0.12,-0.43 0.09,-0.38 -0.41,0.54c-0.77,1.4 -1.13,1.98 -1.48,2.34l-0.16,0.17l-0.06,-0.18c-0.14,-0.45 -0.3,-1.29 -0.37,-1.99c-0.08,-0.65 -0.11,-1.14 -0.12,-1.86l-0.01,-0.69l-0.09,0.12c-0.32,0.41 -0.65,1.01 -0.89,1.6c-0.09,0.23 -0.29,0.82 -0.35,1.08c-0.03,0.09 -0.06,0.17 -0.06,0.17c-0.01,0 -0.07,-0.08 -0.13,-0.17c-0.28,-0.41 -0.65,-0.86 -1.43,-1.73c-0.85,-0.95 -1.15,-1.32 -1.49,-1.8c-0.52,-0.74 -0.9,-1.54 -1.06,-2.25c-0.02,-0.11 -0.05,-0.21 -0.06,-0.22c-0.01,-0.01 -0.05,0.06 -0.09,0.16c-0.34,0.8 -0.6,1.4 -0.62,1.39c-0.05,-0.03 -0.83,-1.24 -1.19,-1.84c-2.02,-3.41 -2.91,-6.22 -2.51,-8.01c0.02,-0.12 0.07,-0.29 0.09,-0.36l0.05,-0.14l1.54,-0.29c0.85,-0.16 1.55,-0.29 1.55,-0.28c0.01,0 0.04,0.1 0.07,0.21c0.26,0.95 0.85,1.89 1.66,2.68c0.21,0.2 0.43,0.4 0.6,0.53c0.02,0.01 -0.06,-0.16 -0.17,-0.38c-0.11,-0.21 -0.52,-1.01 -0.91,-1.78l-0.71,-1.38l-0.47,-5.76l-0.47,-5.77l0.02,-0.56c0.07,-1.68 0.31,-2.71 0.74,-3.14c0.19,-0.19 0.28,-0.22 0.59,-0.2c0.63,0.03 1.53,0.24 2.06,0.47c0.45,0.19 0.82,0.45 0.98,0.71c0.14,0.21 0.14,0.25 0.2,1.24c0.24,4.48 0.62,9.2 0.73,9.2c0.1,0 0.02,-2.94 -0.23,-8.23c-0.08,-1.81 -0.08,-1.85 -0.03,-1.94c0.06,-0.1 0.19,-0.15 0.44,-0.16c0.31,-0.02 0.63,0.04 1.76,0.3c0.71,0.16 0.99,0.2 1.34,0.21c0.33,0.01 0.34,0.01 0.72,-0.09c0.11,-0.03 0.22,-0.05 0.35,-0.05c0.2,0 0.22,0.01 0.68,0.18c0.07,0.03 0.26,0.07 0.4,0.09c0.49,0.08 0.86,0.18 1.32,0.39c0.13,0.05 0.25,0.1 0.27,0.09c0.04,0 0.04,-0.01 -0.01,-0.11c-0.04,-0.1 -0.14,-0.2 -0.21,-0.21c-0.02,-0.01 -0.09,-0.03 -0.15,-0.04c-0.1,-0.02 -0.14,-0.04 -0.21,-0.11c-0.14,-0.14 -0.17,-0.32 -0.13,-0.85c0.01,-0.19 0.03,-0.35 0.03,-0.35c0.01,-0.01 0.25,0.08 0.54,0.18c0.46,0.16 0.8,0.26 0.88,0.26c0.01,0 -0.02,-0.08 -0.07,-0.19c-0.17,-0.34 -0.49,-1.38 -0.7,-2.25c-0.09,-0.4 -0.18,-0.87 -0.16,-0.89c0,0 0.06,0 0.12,0.01c0.13,0.03 0.25,0.03 0.25,0.01c0,0 -0.02,-0.07 -0.06,-0.13c-0.12,-0.26 -0.21,-0.71 -0.29,-1.57l-0.04,-0.48l-0.05,0.12c-0.1,0.29 -0.33,0.64 -0.67,1.03c-0.2,0.23 -0.42,0.44 -0.49,0.46c-0.06,0.03 0.14,0.18 0.23,0.18c0.05,0 0.05,0.02 -0.05,0.15c-0.11,0.17 -0.19,0.25 -0.28,0.3c-0.1,0.05 -0.14,0.05 -0.21,-0.01c-0.04,-0.04 -0.05,-0.09 -0.1,-0.31c-0.08,-0.42 -0.3,-1.06 -0.51,-1.48l-0.08,-0.15l-0.01,0.25c-0.02,0.44 -0.1,0.8 -0.24,1.09c-0.15,0.3 -0.44,0.55 -0.66,0.55l-0.06,0l-0.16,-0.6c-0.08,-0.32 -0.16,-0.6 -0.17,-0.61c0,-0.02 0.03,-0.01 0.09,0.01c0.05,0.03 0.16,0.05 0.25,0.06l0.16,0.01l-0.1,-0.25c-0.2,-0.49 -0.35,-1.04 -0.4,-1.42c-0.05,-0.35 -0.03,-0.35 -0.26,0.06c-0.32,0.57 -0.54,0.83 -0.85,1.01l-0.13,0.07l0.05,0.04c0.12,0.1 0.24,0.16 0.31,0.18l0.09,0.02l-0.04,0.09c-0.13,0.24 -0.39,0.52 -0.72,0.76c-0.21,0.14 -0.24,0.14 -0.35,0.02c-0.13,-0.13 -0.23,-0.48 -0.26,-0.89l-0.01,-0.21l-0.07,0.23c-0.13,0.46 -0.32,0.75 -0.58,0.9l-0.09,0.05l-0.11,-0.08c-0.12,-0.09 -0.27,-0.27 -0.35,-0.43c-0.09,-0.17 -0.29,-0.59 -0.28,-0.59c0,-0.01 0.15,0.03 0.33,0.07c0.18,0.04 0.34,0.08 0.36,0.08c0.02,0 0,-0.05 -0.05,-0.16c-0.31,-0.69 -0.52,-1.46 -0.74,-2.72c-0.03,-0.17 -0.06,-0.33 -0.06,-0.35c-0.01,-0.04 -0.07,0.03 -0.33,0.41c-0.49,0.73 -0.89,1.21 -1.32,1.55c-0.21,0.17 -0.25,0.2 -0.24,0.14c0.04,-0.11 0.65,-3.05 0.64,-3.09c-0.01,-0.13 0.06,-0.22 0.26,-0.33c0.63,-0.33 2.58,-0.61 4.65,-0.67c0.92,-0.02 1.74,0.02 1.84,0.1c0.01,0.01 0.19,0.1 0.39,0.19c1.3,0.62 2.48,1.34 2.98,1.84c0.3,0.31 0.38,0.46 0.44,0.85c0.26,1.81 0.2,4.73 -0.19,8.56c-0.04,0.38 -0.07,0.71 -0.07,0.71c0.01,0.01 0.02,-0.04 0.03,-0.1c0,-0.06 0.09,-0.57 0.19,-1.14c0.1,-0.56 0.21,-1.2 0.24,-1.41c0.2,-1.23 0.31,-2.47 0.34,-3.61l0.01,-0.51l0.08,-0.04c0.26,-0.13 0.5,-0.17 0.7,-0.12c0.04,0.01 0.11,0.02 0.15,0.03c0.16,0.03 0.31,0.23 0.41,0.57c0.13,0.44 0.18,1 0.18,1.93c0,0.86 -0.04,1.61 -0.14,2.64c-0.02,0.18 -0.16,3.11 -0.31,6.52c-0.16,3.56 -0.29,6.2 -0.3,6.21c-0.01,0 -0.58,0.15 -1.26,0.32l-1.23,0.32l0.33,0c0.18,0 0.77,0 1.32,-0.01c0.54,-0.01 1.03,-0.01 1.08,0c0.48,0.09 0.8,0.67 0.89,1.64c0.04,0.5 0.16,2.5 0.3,5.23c0.24,4.69 0.76,15.25 0.74,15.26c0,0.01 -0.02,-0.04 -0.04,-0.1zm-3.72,-33.57c-0.01,-0.01 -0.01,0 -0.01,0.03c0,0.03 0,0.04 0.01,0.02c0.01,-0.01 0.01,-0.03 0,-0.05zm83.33,31.67c-0.14,-0.05 -0.32,-0.22 -0.38,-0.36c-0.14,-0.3 -0.09,-0.63 0.12,-0.86c0.15,-0.16 0.26,-0.21 0.45,-0.22c0.18,-0.01 0.3,0.02 0.43,0.11c0.21,0.15 0.31,0.36 0.31,0.63c0,0.24 -0.05,0.38 -0.21,0.54c-0.21,0.2 -0.47,0.26 -0.72,0.16zm-48.18,-1.77c0,-0.03 0.29,-1.32 0.3,-1.37c0.02,-0.03 0.03,-0.02 0.08,0.06c0.1,0.13 0.14,0.22 0.28,0.61c0.08,0.2 0.16,0.43 0.2,0.5c0.03,0.08 0.05,0.15 0.05,0.16c0,0.01 -0.1,0.02 -0.23,0.03c-0.13,0 -0.34,0.01 -0.46,0.02c-0.14,0.01 -0.22,0.01 -0.22,-0.01zm48.27,-0.2c-0.12,-0.06 -0.2,-0.15 -0.28,-0.31c-0.14,-0.26 -0.21,-0.67 -0.19,-1.09c0.03,-0.47 0.06,-0.51 0.42,-0.59c0.3,-0.07 0.44,-0.14 0.55,-0.26c0.11,-0.11 0.14,-0.21 0.13,-0.37c-0.01,-0.18 -0.09,-0.33 -0.29,-0.53c-0.18,-0.18 -0.3,-0.25 -0.46,-0.27c-0.21,-0.02 -0.34,0.1 -0.43,0.36c-0.08,0.25 -0.17,0.37 -0.37,0.45c-0.08,0.04 -0.14,0.05 -0.41,0.05c-0.48,0.02 -0.52,-0.02 -0.52,-0.38c0,-0.77 0.49,-1.38 1.28,-1.58c0.64,-0.17 1.27,-0.01 1.73,0.41c0.15,0.14 0.34,0.42 0.42,0.62c0.12,0.31 0.14,0.4 0.13,0.75c0,0.31 0,0.33 -0.06,0.48c-0.1,0.28 -0.17,0.38 -0.51,0.72c-0.27,0.27 -0.33,0.35 -0.4,0.47c-0.06,0.14 -0.07,0.17 -0.09,0.39c-0.02,0.42 -0.09,0.58 -0.28,0.68c-0.1,0.05 -0.27,0.05 -0.37,0zm3.96,-2.98c-1.11,-1.76 -1.44,-3.42 -1.01,-5.08c0.24,-0.95 0.7,-1.86 1.56,-3.15c0.4,-0.6 0.97,-1.41 1.01,-1.46c0.04,-0.02 0.25,-0.03 2.42,-0.01c1.32,0.01 2.64,0.01 2.94,0.02l0.55,0l0.37,1.5c0.21,0.82 0.38,1.51 0.38,1.51c0,0.01 -0.15,0.02 -0.33,0.03c-2.01,0.08 -3.5,0.57 -4.7,1.53c-0.3,0.23 -0.76,0.7 -1.02,1.02c-0.77,0.97 -1.41,2.25 -1.92,3.83c-0.07,0.22 -0.13,0.4 -0.14,0.41c0,0.01 -0.06,-0.06 -0.11,-0.15zm-76.95,-8.13l-0.88,-3.72l-0.15,-2.41c-0.15,-2.44 -0.15,-2.49 -0.14,-2.45c0.02,0.04 2.07,12.27 2.07,12.29c-0.01,0.01 -0.41,-1.66 -0.9,-3.71zm106.07,3.49c-1.93,-0.04 -3.59,-0.13 -5.46,-0.29c-0.25,-0.02 -0.54,-0.05 -0.62,-0.05c-0.1,-0.01 -0.16,-0.03 -0.17,-0.04c-0.01,-0.02 0.2,-1.04 0.46,-2.28c0.25,-1.24 0.47,-2.26 0.47,-2.28c0,-0.01 -0.15,-0.15 -0.34,-0.31c-0.19,-0.15 -0.36,-0.3 -0.38,-0.32c-0.04,-0.03 -0.42,-0.03 -3.98,-0.05l-3.93,-0.02l-0.55,0.31l-0.55,0.32l1.58,0.01c0.87,0.01 2.91,0.02 4.54,0.03c2.71,0.01 2.96,0.02 2.96,0.05c-0.01,0.05 -0.93,4.47 -0.94,4.48c-0.01,0.01 -0.99,-0.09 -1.99,-0.21c-1.02,-0.13 -2.18,-0.29 -4.22,-0.58c-3.99,-0.57 -5.14,-0.71 -6.8,-0.78l-0.32,-0.01l-0.37,-1.46c-0.2,-0.8 -0.37,-1.48 -0.38,-1.51l-0.01,-0.05l1.77,0.01l1.77,0.01l-0.01,-0.04c-0.01,-0.03 -0.02,-0.18 -0.04,-0.33c-0.02,-0.15 -0.04,-0.27 -0.04,-0.27c0,0 -2.15,-0.01 -4.77,-0.03c-2.63,-0.01 -4.78,-0.03 -4.78,-0.03c-0.01,0 0.02,-0.06 0.07,-0.13c0.13,-0.19 0.37,-0.6 0.52,-0.88c0.41,-0.76 0.68,-1.51 0.77,-2.17l0.04,-0.25l1.35,0.01c0.75,0.01 2.56,0.02 4.02,0.03l2.66,0.01l0.01,-0.13c0.01,-0.07 0.02,-0.2 0.03,-0.29l0.01,-0.17l-0.7,-0.01c-0.39,-0.01 -1.91,-0.02 -3.38,-0.02c-1.47,-0.01 -2.96,-0.02 -3.33,-0.03l-0.66,-0.01l-0.01,-0.16c-0.09,-1.05 -0.5,-2.07 -1.27,-3.16c-0.1,-0.13 -0.33,-0.43 -0.51,-0.66c-1.82,-2.29 -2.98,-4.01 -3.82,-5.69c-0.56,-1.12 -0.95,-2.25 -1.13,-3.25c-0.1,-0.5 -0.12,-0.84 -0.12,-1.39c0,-0.53 0.01,-0.72 0.09,-1.17c0.27,-1.62 1.12,-3.2 2.73,-5.04c0.41,-0.47 0.92,-1 1.61,-1.69c0.91,-0.9 1.2,-1.17 3.99,-3.73c3.05,-2.81 5.1,-4.84 7.06,-6.99c2.49,-2.73 4.71,-5.54 6.77,-8.57c0.2,-0.3 0.37,-0.55 0.38,-0.56c0,0 0.13,0.04 0.29,0.09c1.05,0.34 2.17,0.56 3.48,0.67c0.44,0.04 1.53,0.05 2.03,0.02l0.28,-0.01l0.46,0.91c7,13.84 15.91,29.39 22.93,40.05c0.22,0.33 0.4,0.61 0.4,0.61c-0.01,0 -4.43,-0.02 -9.84,-0.05c-5.4,-0.04 -10.03,-0.06 -10.29,-0.06l-0.46,0l0,0.3l0,0.3l2.97,0.01c1.63,0.01 2.97,0.02 2.98,0.03c0.01,0.01 0.06,3.4 0.05,3.41c0,0.01 -1.43,0 -3.18,-0.01c-1.75,-0.01 -3.19,-0.02 -3.19,-0.01c-0.01,0.01 -0.15,0.62 -0.15,0.63c0.01,0 2.24,0.01 4.96,0.03c2.73,0.01 5.37,0.03 5.87,0.04l0.91,0.01l-1.68,2.27c-0.92,1.26 -1.68,2.29 -1.69,2.3c-0.03,0.06 -2.12,0.2 -3.78,0.25c-0.61,0.02 -2.89,0.04 -3.43,0.03zm-2.22,-3.05c0.01,-0.03 0.08,-0.2 0.14,-0.37c0.41,-1.14 0.73,-2.6 0.88,-4.01c0.14,-1.37 0.14,-2.92 0.01,-4.36c-0.06,-0.63 -0.24,-1.88 -0.27,-1.94c-0.02,-0.04 -2.09,1.21 -4.82,2.9c-0.76,0.47 -1.49,0.92 -1.61,1c-0.22,0.13 -0.23,0.14 -0.25,0.1c-0.01,-0.02 -0.1,-0.11 -0.2,-0.21c-0.28,-0.28 -0.6,-0.41 -1,-0.41c-0.38,0 -0.71,0.13 -0.97,0.37l-0.15,0.14l-2.28,-1.91c-1.26,-1.06 -2.5,-2.1 -2.77,-2.32c-0.34,-0.29 -0.48,-0.4 -0.49,-0.38c-0.04,0.06 -0.41,1.21 -0.54,1.65c-0.76,2.63 -0.88,4.77 -0.44,7.94c0.03,0.22 0.06,0.4 0.06,0.4c0.01,-0.01 0.29,-0.16 0.62,-0.35c1.6,-0.89 3.88,-2.23 5.44,-3.19l0.28,-0.18l0.09,0.12c0.16,0.22 0.42,0.41 0.7,0.5c0.15,0.05 0.19,0.06 0.45,0.06c0.25,0 0.3,-0.01 0.44,-0.06c0.2,-0.06 0.38,-0.17 0.54,-0.31l0.12,-0.11l0.14,0.11c0.07,0.06 1.41,1.19 2.97,2.5c1.57,1.31 2.86,2.39 2.87,2.39c0.01,0 0.03,-0.03 0.04,-0.07zm-2.48,-11.95c0.21,-0.43 0.31,-0.81 0.34,-1.19c0.01,-0.19 -0.02,-0.49 -0.05,-0.57c-0.01,-0.03 -0.04,-0.03 0.51,-0.15c0.64,-0.15 1.45,-0.4 2.06,-0.64c0.13,-0.05 0.25,-0.09 0.27,-0.09c0.04,0 0.2,0.2 0.31,0.37c0.19,0.32 0.29,0.74 0.24,1.12c-0.01,0.11 -0.04,0.28 -0.07,0.38c-0.03,0.1 -0.05,0.18 -0.04,0.19c0.01,0.01 0.23,-0.28 0.35,-0.46c0.23,-0.35 0.39,-0.72 0.46,-1.07c0.05,-0.26 0.03,-0.65 -0.04,-0.87c-0.03,-0.09 -0.06,-0.17 -0.05,-0.18c0,0 0.13,-0.06 0.28,-0.14c1.43,-0.71 2.9,-1.69 4.06,-2.71c0.24,-0.21 0.3,-0.27 0.2,-0.21c-0.02,0.02 -0.26,0.16 -0.52,0.31c-4.94,2.84 -9.16,3.94 -13.12,3.42c-1.57,-0.21 -3.15,-0.67 -4.8,-1.4c-0.44,-0.19 -1.55,-0.75 -2.03,-1.02c-1.09,-0.6 -2.41,-1.44 -3.67,-2.31c-0.17,-0.12 -0.39,-0.27 -0.47,-0.33l-0.17,-0.11l0.3,0.28c1.36,1.31 2.78,2.43 4.21,3.31l0.26,0.16l-0.15,0.16c-0.26,0.27 -0.35,0.51 -0.35,0.96c0,0.24 0.01,0.31 0.07,0.51c0.03,0.13 0.08,0.3 0.11,0.38c0.07,0.17 0.24,0.53 0.28,0.58c0.03,0.04 0.03,0.03 0,-0.07c-0.15,-0.59 0,-1.18 0.41,-1.6c0.13,-0.14 0.43,-0.37 0.5,-0.39c0.03,-0.01 0.2,0.06 0.54,0.23c0.53,0.26 1,0.46 1.48,0.64c0.16,0.06 0.32,0.12 0.35,0.13l0.05,0.03l-0.12,0.13c-0.13,0.15 -0.26,0.38 -0.31,0.58c-0.09,0.36 0,0.84 0.25,1.26c0.08,0.15 0.26,0.4 0.27,0.38c0.01,0 0,-0.06 -0.02,-0.12c-0.04,-0.16 -0.03,-0.48 0,-0.64c0.1,-0.42 0.45,-0.87 0.93,-1.19l0.1,-0.07l0.31,0.08c0.84,0.22 1.69,0.35 2.6,0.42c0.49,0.04 1.56,0.04 2.03,0.01c0.31,-0.02 0.95,-0.08 1.12,-0.11c0.08,-0.01 0.08,-0.01 0.19,0.12c0.42,0.51 0.51,1.21 0.25,1.98c-0.04,0.1 0.18,-0.26 0.29,-0.48zm-1.43,-3.05c3.35,-0.23 6.59,-1.27 9.6,-3.08c0.64,-0.38 1.75,-1.15 1.89,-1.3c0.03,-0.04 0.04,-0.06 0.01,-0.41c-0.13,-2.09 -0.68,-4.68 -1.49,-7c-1.36,-3.92 -3.35,-6.94 -5.75,-8.76c-2.21,-1.68 -4.86,-2.32 -7.66,-1.86c-3.55,0.57 -6.99,3.01 -9.81,6.93c-1.37,1.9 -2.54,4.15 -3.27,6.28c-0.24,0.72 -0.53,1.77 -0.49,1.85c0.02,0.07 1.05,1.05 1.69,1.61c2.14,1.87 4.39,3.29 6.71,4.27c0.48,0.21 1.5,0.58 1.52,0.56c0,-0.01 -0.03,-0.18 -0.09,-0.39c-0.61,-2.55 -1.11,-6.06 -0.97,-6.83c0.09,-0.46 0.54,-2 1.04,-3.54c1.02,-3.13 1.87,-5.16 2.32,-5.57c0.17,-0.16 0.27,-0.11 0.43,0.2c0.24,0.5 0.54,1.71 0.81,3.39c0.39,2.36 0.69,5.34 0.61,6.03c-0.09,0.83 -1.4,4.64 -2.3,6.7c-0.1,0.24 -0.19,0.44 -0.2,0.45c-0.01,0.03 -0.01,0.03 0.42,0.12c0.98,0.2 1.98,0.33 2.96,0.37c0.44,0.02 1.6,0.01 2.02,-0.02zm8.6,-17.06c-0.1,-0.18 -0.53,-0.86 -0.73,-1.18c-0.85,-1.29 -1.62,-2.25 -2.56,-3.2l-0.46,-0.47l0.08,-0.11c0.41,-0.54 0.49,-1.41 0.23,-2.51c-0.06,-0.26 -0.23,-0.81 -0.24,-0.8c-0.01,0 0,0.1 0.02,0.22c0.04,0.28 0.04,0.72 0,0.98c-0.06,0.41 -0.2,0.78 -0.42,1.09c-0.13,0.2 -0.41,0.48 -0.45,0.47c-0.01,-0.01 -0.12,-0.09 -0.25,-0.18c-0.38,-0.29 -0.82,-0.57 -1.37,-0.88l-0.09,-0.05l0.04,-0.12c0.07,-0.23 0.1,-0.48 0.1,-0.78c0,-0.49 -0.1,-0.97 -0.33,-1.5c-0.12,-0.28 -0.17,-0.35 -0.15,-0.22c0.12,0.75 0.01,1.42 -0.32,2c-0.05,0.08 -0.1,0.17 -0.13,0.2l-0.03,0.04l-0.23,-0.08c-0.64,-0.23 -1.18,-0.36 -1.83,-0.44c-0.41,-0.05 -1.52,-0.05 -1.92,0c-0.39,0.05 -0.78,0.12 -1.11,0.21c-0.16,0.03 -0.28,0.07 -0.29,0.07c0,0 -0.04,-0.08 -0.08,-0.18c-0.28,-0.68 -0.36,-1.52 -0.22,-2.41c0.03,-0.2 -0.26,0.52 -0.38,0.95c-0.16,0.55 -0.24,1.03 -0.25,1.57l0,0.38l-0.25,0.1c-0.62,0.25 -1.38,0.65 -1.79,0.91c-0.05,0.03 -0.05,0.03 -0.09,-0.06c-0.14,-0.31 -0.26,-0.73 -0.32,-1.14c-0.05,-0.34 -0.05,-1.03 0.01,-1.39c0.02,-0.14 0.04,-0.26 0.04,-0.27c-0.02,-0.01 -0.22,0.5 -0.31,0.76c-0.17,0.5 -0.28,1 -0.33,1.5c-0.03,0.29 -0.02,0.81 0.03,1.06l0.02,0.16l-0.27,0.2c-0.83,0.62 -1.45,1.16 -2.29,2c-0.65,0.65 -1.29,1.36 -1.7,1.88l-0.07,0.09l0.07,-0.06c0.04,-0.03 0.23,-0.19 0.43,-0.35c3.93,-3.3 7.48,-4.86 10.67,-4.71c2.29,0.11 4.36,1.02 6.46,2.86c0.31,0.28 1.13,1.09 1.43,1.42c0.49,0.54 1.01,1.18 1.45,1.75c0.09,0.13 0.18,0.24 0.18,0.24c0.01,0 0.01,-0.01 0,-0.02zm5.42,34.78c0.01,-0.02 0.76,-1.04 1.67,-2.27c0.9,-1.23 1.65,-2.24 1.65,-2.25c0.02,-0.01 10.85,0.04 10.98,0.05c0.04,0.01 -0.32,0.3 -1.51,1.27c-1.53,1.24 -1.57,1.27 -1.7,1.3c-0.29,0.08 -1.28,0.31 -1.91,0.45c-2.81,0.63 -5.72,1.11 -8.39,1.39c-0.33,0.03 -0.64,0.06 -0.7,0.07c-0.09,0.01 -0.11,0.01 -0.09,-0.01zm6.37,-5.15c-4.51,-0.03 -8.21,-0.05 -8.21,-0.05c-0.02,-0.02 -0.06,-3.4 -0.05,-3.41c0.02,-0.01 11.79,0.04 13.46,0.07l0.91,0.01l0.29,0.43c0.62,0.91 1.15,1.68 1.71,2.48c0.19,0.27 0.35,0.5 0.35,0.51c0,0.01 -0.05,0.01 -0.12,0.01c-0.07,0 -3.82,-0.02 -8.34,-0.05zm-84.06,-1.77c-0.09,-0.02 -0.17,-0.07 -0.24,-0.14c-0.03,-0.03 -0.58,-0.94 -1.21,-2.02l-1.16,-1.96l-0.12,-0.01c-0.14,-0.02 -0.39,-0.08 -0.54,-0.14c-0.37,-0.15 -0.64,-0.41 -0.75,-0.75c-0.06,-0.16 -0.08,-0.53 -0.04,-0.73c0.02,-0.11 0.11,-0.43 0.15,-0.53c0.01,-0.01 -0.72,-1.25 -1.62,-2.77l-1.62,-2.75l-0.16,-0.02c-0.52,-0.09 -0.95,-0.37 -1.13,-0.74c-0.09,-0.2 -0.12,-0.33 -0.12,-0.58c0,-0.22 0.04,-0.42 0.11,-0.63c0.02,-0.06 0.04,-0.13 0.04,-0.14c0,-0.01 -0.39,-0.68 -0.87,-1.49c-0.48,-0.81 -0.88,-1.51 -0.89,-1.55c-0.07,-0.24 0.07,-0.47 0.36,-0.62l0.13,-0.07l0.38,-0.79l0.38,-0.79l-0.03,-0.1c-0.03,-0.1 -0.03,-0.13 -0.01,-0.22c0.02,-0.13 0.11,-0.27 0.2,-0.33c0.06,-0.04 7.93,-4.23 7.95,-4.23c0,0 0.18,0.1 0.4,0.22c0.22,0.12 0.4,0.22 0.4,0.22c0,-0.01 0.02,-0.21 0.04,-0.46c0.02,-0.25 0.03,-0.46 0.04,-0.46c0.05,-0.04 5.03,-2.68 5.1,-2.7c0.2,-0.07 0.39,-0.03 0.54,0.11c0.08,0.07 1.07,1.74 5.02,8.42c3.42,5.79 4.93,8.36 4.94,8.43c0.03,0.1 0.01,0.23 -0.05,0.33c-0.06,0.12 -0.22,0.22 -0.96,0.62c-0.42,0.22 -0.76,0.41 -0.76,0.41c0,0.01 0.11,0.2 0.24,0.43c0.32,0.55 0.33,0.55 0.33,0.68c0,0.14 -0.06,0.28 -0.16,0.37c-0.04,0.05 -1.72,0.95 -4.97,2.68c-2.7,1.44 -4.92,2.62 -4.94,2.62c-0.01,0 -0.21,-0.08 -0.43,-0.17c-0.22,-0.1 -0.4,-0.17 -0.41,-0.16c0,0 0.01,0.17 0.02,0.38c0.02,0.21 0.02,0.38 0.01,0.39c-0.03,0.03 -3.19,1.71 -3.26,1.74c-0.08,0.02 -0.25,0.03 -0.33,0zm1.97,-2.04c1.02,-0.54 1.19,-0.64 1.19,-0.68c0,-0.04 -0.06,-0.48 -0.07,-0.48c0,-0.01 -0.34,0.17 -0.74,0.39c-0.41,0.21 -0.77,0.4 -0.8,0.41c-0.05,0.02 -0.14,0.12 -0.37,0.43c-0.41,0.54 -0.44,0.59 -0.42,0.57c0.01,0 0.56,-0.29 1.21,-0.64zm6.54,-3.48l4.67,-2.49l-0.1,-0.18c-0.06,-0.09 -0.12,-0.19 -0.14,-0.22c-0.02,-0.04 -0.13,0.02 -4.83,2.52c-2.64,1.41 -4.81,2.57 -4.83,2.58c-0.02,0.02 0.06,0.06 0.25,0.15c0.16,0.07 0.29,0.13 0.29,0.13c0.01,0 2.12,-1.12 4.69,-2.49zm-6.71,1.83c0.1,-0.05 0.18,-0.1 0.18,-0.1c0,0 -0.54,-0.94 -1.21,-2.08l-1.21,-2.07l0.04,-0.08c0.05,-0.09 0.05,-0.26 0.01,-0.37c-0.06,-0.14 -0.2,-0.25 -0.39,-0.29l-0.11,-0.03l-1.97,-3.35c-1.79,-3.05 -1.97,-3.36 -1.96,-3.42c0.01,-0.03 0.02,-0.11 0.02,-0.18c0,-0.21 -0.14,-0.38 -0.36,-0.44l-0.09,-0.03l-0.98,-1.68c-0.54,-0.92 -0.99,-1.68 -0.99,-1.69c-0.01,-0.01 -0.11,0.04 -0.24,0.1l-0.22,0.12l0.96,1.63c0.53,0.89 0.97,1.64 0.97,1.66c0.01,0.02 -0.08,0.11 -0.28,0.28c-0.39,0.33 -1.06,1.01 -1.28,1.28c-0.23,0.29 -0.46,0.64 -0.58,0.89l-0.11,0.21l0,0.22c0.01,0.2 0.01,0.23 0.06,0.33c0.06,0.14 0.19,0.26 0.33,0.33c0.11,0.06 0.39,0.15 0.41,0.13c0,-0.01 0.02,-0.08 0.04,-0.16c0.09,-0.44 0.32,-0.89 0.7,-1.37c0.29,-0.35 1.23,-1.26 1.26,-1.22c0.03,0.02 3.86,6.52 3.87,6.55c0.01,0.01 -0.06,0.08 -0.14,0.15c-0.25,0.21 -0.76,0.72 -0.99,0.98c-0.54,0.62 -0.98,1.32 -1.05,1.7c-0.06,0.32 0,0.6 0.17,0.77c0.11,0.11 0.32,0.22 0.49,0.25c0.12,0.03 0.14,0.02 0.14,-0.08c0,-0.08 0.09,-0.43 0.16,-0.6c0.16,-0.41 0.46,-0.9 0.84,-1.35c0.14,-0.17 0.69,-0.73 0.83,-0.84l0.09,-0.08l1.19,2.01c0.65,1.11 1.2,2.01 1.21,2.01c0.01,0 0.09,-0.04 0.19,-0.09zm1.48,-1.65c0.19,-0.08 0.31,-0.25 0.31,-0.44c0,-0.28 -0.24,-0.49 -0.55,-0.49c-0.49,0 -0.74,0.51 -0.41,0.83c0.11,0.1 0.23,0.14 0.41,0.14c0.1,0 0.17,-0.01 0.24,-0.04zm5.83,-2.25l3.08,-1.64l-0.1,-0.16c-0.45,-0.74 -0.63,-1.58 -0.45,-2.24c0.13,-0.51 0.47,-1 0.96,-1.39c0.09,-0.07 0.16,-0.14 0.15,-0.15c-0.01,-0.04 -5.91,-10.03 -5.93,-10.05c-0.01,-0.01 -0.11,0.02 -0.23,0.07c-0.47,0.21 -0.83,0.3 -1.29,0.31c-0.37,0.02 -0.61,-0.01 -0.93,-0.12c-0.43,-0.15 -0.78,-0.37 -1.15,-0.74c-0.25,-0.25 -0.46,-0.51 -0.63,-0.8c-0.06,-0.09 -0.12,-0.17 -0.13,-0.17c-0.01,-0.01 -0.38,0.19 -0.82,0.43l-0.81,0.43l0.01,0.43c0.01,0.24 0.02,0.49 0.02,0.56c0.01,0.07 0.01,0.11 0,0.11c-0.01,0 -0.24,-0.13 -0.51,-0.29c-0.36,-0.21 -0.5,-0.29 -0.53,-0.28c-0.17,0.09 -3.49,1.86 -3.55,1.9l-0.09,0.05l0.13,0.19c0.32,0.47 0.55,1.04 0.63,1.52c0.04,0.24 0.04,0.65 0,0.88c-0.13,0.73 -0.65,1.42 -1.46,1.92c-0.08,0.05 -0.15,0.09 -0.16,0.1c-0.01,0.01 1.28,2.16 2.86,4.77c1.59,2.62 2.88,4.77 2.89,4.77c0,0 0.14,-0.06 0.31,-0.15c0.5,-0.24 0.87,-0.33 1.35,-0.34c0.17,0 0.35,0.02 0.47,0.04c0.49,0.08 1.02,0.34 1.49,0.71c0.29,0.23 0.69,0.66 0.94,1l0.1,0.13l0.14,-0.07c0.08,-0.05 1.54,-0.82 3.24,-1.73zm-3.6,-1.23c-0.77,-0.09 -1.53,-0.43 -2.26,-1.02c-0.28,-0.22 -0.85,-0.79 -1.13,-1.13c-0.93,-1.11 -1.84,-2.58 -2.94,-4.76c-0.17,-0.33 -0.31,-0.62 -0.31,-0.64c0,-0.03 0.89,-0.54 0.91,-0.52c0.01,0.01 0.44,0.69 0.96,1.52c0.52,0.83 0.95,1.52 0.97,1.53c0.02,0.02 0.13,0.22 -1.33,-2.46c-0.65,-1.19 -1.18,-2.18 -1.17,-2.18c0.02,-0.02 0.96,-0.47 0.96,-0.46c0.01,0 0.61,0.92 1.34,2.04c0.73,1.11 1.34,2.04 1.35,2.05c0.01,0.01 0.01,0 -0.01,-0.03c-0.03,-0.07 -2.59,-4.78 -2.68,-4.95l-0.07,-0.12l0.52,-0.27c0.29,-0.14 0.52,-0.26 0.53,-0.26c0.07,0.13 2.77,4.48 2.78,4.5c0.04,0.04 -0.05,-0.16 -1.1,-2.25c-0.6,-1.2 -1.09,-2.18 -1.09,-2.19c0,-0.01 0.23,-0.12 0.51,-0.26c0.41,-0.2 0.51,-0.24 0.53,-0.22c0.02,0.01 0.61,0.98 1.32,2.15c0.71,1.16 1.3,2.13 1.31,2.14c0.01,0.01 -0.02,-0.05 -0.06,-0.13c-0.23,-0.46 -1.81,-3.71 -1.81,-3.72c0,-0.02 0.93,-0.45 0.96,-0.44c0.01,0 0.87,1.44 1.91,3.2c1.04,1.75 1.89,3.18 1.9,3.18c0,-0.01 -0.13,-0.53 -0.29,-1.15c-0.16,-0.63 -0.29,-1.16 -0.29,-1.17c0,-0.02 1.29,-0.64 1.3,-0.63c0.03,0.03 0.33,0.57 0.45,0.8c0.53,1.02 0.85,1.96 1.01,2.96c0.05,0.33 0.05,1.21 0,1.52c-0.18,1.07 -0.7,1.91 -1.51,2.44c-0.61,0.4 -1.65,0.79 -2.38,0.91c-0.24,0.03 -0.87,0.05 -1.09,0.02zm0.94,-1.66c0,-0.01 -2.07,-3.82 -2.13,-3.91c-0.03,-0.04 -0.03,-0.04 -0.24,0.07l-0.21,0.11l-0.02,0.11c-0.01,0.07 -0.15,0.87 -0.3,1.79l-0.28,1.67l0.11,0.18c0.06,0.1 0.11,0.18 0.11,0.19c0.01,0 1.22,-0.62 1.74,-0.9l0.21,-0.11l0.29,0.52l0.3,0.53l0.21,-0.13c0.11,-0.06 0.21,-0.12 0.21,-0.12zm-2.66,-0.51c0.01,-0.03 0.11,-0.6 0.22,-1.26c0.11,-0.66 0.21,-1.23 0.22,-1.25c0.01,-0.04 0.1,0.11 0.51,0.88c0.27,0.51 0.5,0.94 0.5,0.94c0,0.01 -1.43,0.74 -1.45,0.74c0,0 0,-0.02 0,-0.05zm4.41,-0.5l1.22,-0.7l-0.12,-0.2c-0.06,-0.11 -0.12,-0.2 -0.13,-0.21c-0.01,-0.01 -0.39,0.2 -0.84,0.46c-0.45,0.26 -0.83,0.48 -0.84,0.49c-0.02,0.01 0.02,-0.08 0.07,-0.19c0.12,-0.24 0.23,-0.53 0.3,-0.79c0.27,-1.01 0.11,-1.84 -0.48,-2.41c-0.28,-0.28 -0.55,-0.4 -0.88,-0.38c-0.17,0 -0.2,0.01 -0.36,0.09c-0.54,0.27 -0.82,0.92 -0.74,1.7c0.01,0.12 0.03,0.22 0.03,0.22c0.01,0.01 0.12,-0.05 0.27,-0.13c0.22,-0.12 0.25,-0.14 0.24,-0.18c-0.03,-0.09 -0.04,-0.43 -0.01,-0.54c0.05,-0.27 0.23,-0.53 0.44,-0.63c0.14,-0.06 0.34,-0.06 0.48,0.01c0.27,0.14 0.54,0.56 0.63,0.98c0.06,0.33 0.03,0.82 -0.09,1.24c-0.12,0.4 -0.37,0.94 -0.62,1.33l-0.12,0.19l0.12,0.2c0.11,0.2 0.11,0.21 0.16,0.18c0.02,-0.02 0.59,-0.34 1.27,-0.73zm5.63,0.8c0.16,-0.09 0.27,-0.25 0.27,-0.42c0,-0.14 -0.05,-0.26 -0.16,-0.35c-0.32,-0.29 -0.86,-0.13 -0.94,0.27c-0.05,0.25 0.17,0.51 0.45,0.55c0.12,0.02 0.28,0 0.38,-0.05zm-18.7,-8.25c0.05,-0.01 0.12,-0.06 0.16,-0.1c0.29,-0.26 0.17,-0.7 -0.22,-0.81c-0.48,-0.14 -0.91,0.34 -0.64,0.72c0.13,0.21 0.46,0.3 0.7,0.19zm9.93,-5.63c0.29,-0.08 0.46,-0.39 0.34,-0.64c-0.09,-0.19 -0.24,-0.29 -0.48,-0.31c-0.26,-0.01 -0.45,0.09 -0.54,0.29c-0.18,0.4 0.22,0.79 0.68,0.66zm-48.22,22.09c-0.43,-2.07 -0.52,-2.51 -0.52,-2.64c0,-0.4 0.16,-6.59 0.18,-6.72c0.01,-0.11 0.11,1.27 0.44,5.84c0.24,3.29 0.43,5.99 0.43,5.99c-0.01,0.01 -0.24,-1.11 -0.53,-2.47zm74.93,2.37c-0.24,-0.03 -0.55,-0.08 -0.79,-0.14c-0.16,-0.04 -0.3,-0.08 -0.3,-0.08c-0.01,-0.01 0.04,-0.1 0.12,-0.2c0.07,-0.1 0.24,-0.35 0.37,-0.56c0.38,-0.62 0.56,-0.89 0.72,-1.05c0.09,-0.09 0.18,-0.16 0.2,-0.16c0.05,0 0.19,0.13 0.32,0.29c0.06,0.08 0.25,0.38 0.42,0.65c0.33,0.53 0.47,0.74 0.62,0.91c0.05,0.06 0.08,0.11 0.08,0.12c-0.02,0.02 -0.38,0.11 -0.56,0.15c-0.36,0.07 -0.88,0.1 -1.2,0.07zm-68.49,-6.74c-0.66,-3.22 -1.2,-5.85 -1.19,-5.86c0.01,-0.01 0.71,0.26 0.74,0.28c0.01,0.01 1.66,11.39 1.66,11.4c-0.01,0.01 -0.55,-2.61 -1.21,-5.82zm60.9,0.54c-1.62,-0.12 -2.98,-0.61 -3.71,-1.33c-0.5,-0.49 -0.82,-1.22 -0.96,-2.2c-0.03,-0.24 -0.03,-1.35 0,-1.65c0.21,-1.74 0.76,-3.56 1.79,-5.9c1.43,-3.25 3.95,-7.55 6.69,-11.39c0.23,-0.33 0.42,-0.59 0.42,-0.6c0,0 -0.03,-0.02 -0.07,-0.03c-0.19,-0.06 -0.98,-0.36 -1.29,-0.5c-0.75,-0.32 -0.93,-0.43 -1.24,-0.73c-0.36,-0.36 -0.69,-0.88 -0.95,-1.5c-0.17,-0.4 -0.24,-0.87 -0.22,-1.4c0.05,-1.15 0.47,-2.17 1.06,-2.62c0.29,-0.22 0.74,-0.39 0.91,-0.34c0.15,0.04 0.21,0.14 0.21,0.35c0,0.26 -0.16,0.71 -0.41,1.15c-0.21,0.36 -0.34,0.65 -0.39,0.86c-0.05,0.17 -0.06,0.24 -0.06,0.49c0,0.42 0.07,0.71 0.28,1.11c0.1,0.2 0.35,0.56 0.37,0.54c0,0 0.01,-0.11 0.03,-0.24c0.1,-1.2 0.48,-2.36 1.02,-3.17c0.37,-0.54 0.78,-0.94 1.32,-1.25c0.39,-0.23 0.82,-0.4 1.52,-0.58l0.37,-0.1l0.37,0c0.4,0 0.57,0.03 0.79,0.13c0.16,0.08 0.24,0.15 0.27,0.24c0.03,0.12 0,0.21 -0.15,0.35c-0.16,0.16 -0.48,0.32 -1.14,0.56c-0.64,0.24 -0.8,0.31 -1.08,0.45c-0.45,0.24 -0.64,0.43 -0.86,0.89c-0.09,0.18 -0.27,0.61 -0.27,0.63c0,0.01 0.06,-0.01 0.14,-0.04c0.52,-0.21 1.28,-0.26 1.7,-0.12c0.44,0.15 0.91,0.6 0.91,0.86c0,0.15 -0.19,0.31 -0.43,0.35c-0.19,0.03 -0.38,0.01 -0.72,-0.07c-0.24,-0.06 -0.28,-0.07 -0.36,-0.05c-0.22,0.05 -0.48,0.29 -0.55,0.5c-0.07,0.21 -0.09,0.32 -0.09,0.53c0,0.24 0.05,0.44 0.15,0.66l0.07,0.17l0.15,0.04c0.3,0.07 0.87,0.18 1.21,0.23c1.33,0.19 2.17,0.07 2.37,-0.35c0.05,-0.09 0.05,-0.11 0.05,-0.6c0,-0.37 0.01,-0.55 0.04,-0.68c0.08,-0.45 0.26,-0.69 0.51,-0.69c0.13,0 0.34,0.12 0.52,0.3c0.25,0.25 0.53,0.7 0.64,1.02c0.06,0.19 0.08,0.58 0.03,0.81c-0.05,0.23 -0.29,1.02 -0.34,1.13c-0.23,0.43 -0.82,0.76 -1.69,0.92c-0.5,0.09 -1.26,0.14 -1.87,0.12c-0.24,0 -0.46,-0.01 -0.5,-0.02l-0.07,-0.01l-0.33,0.48c-1.98,2.93 -3.96,6.29 -5.28,8.98c-1.39,2.82 -2.15,4.98 -2.39,6.75c-0.07,0.5 -0.07,1.26 0,1.64c0.11,0.62 0.33,1.09 0.68,1.44c0.9,0.89 2.6,0.97 5.12,0.25c2.02,-0.59 4.68,-1.75 7.72,-3.38c0.23,-0.12 0.42,-0.22 0.42,-0.22c0.01,0 0.08,0.17 0.16,0.38c0.28,0.69 0.6,1.37 0.83,1.75c0.09,0.15 0.14,0.09 -0.36,0.42c-4.03,2.59 -7.89,4.05 -11.33,4.28c-0.36,0.03 -1.4,0.03 -1.73,0zm-40.92,-8.76c-0.08,-0.09 -0.15,-0.29 -0.3,-0.88c-0.21,-0.87 -0.33,-1.19 -0.51,-1.39c-0.2,-0.21 -0.41,-0.27 -1.21,-0.32c-0.51,-0.04 -0.66,-0.07 -0.67,-0.15c-0.01,-0.11 0.07,-0.15 0.62,-0.3c0.22,-0.06 0.48,-0.14 0.56,-0.17c0.31,-0.13 0.5,-0.29 0.63,-0.54c0.16,-0.33 0.21,-0.66 0.22,-1.56c0.01,-0.71 0.02,-0.82 0.11,-0.89c0.06,-0.06 0.08,-0.05 0.14,0.02c0.08,0.08 0.14,0.27 0.27,0.86c0.29,1.37 0.45,1.62 1.1,1.75c0.06,0.01 0.38,0.03 0.7,0.03c0.62,0.02 0.69,0.03 0.7,0.13c0.02,0.1 -0.1,0.16 -0.64,0.3c-0.58,0.16 -0.84,0.27 -1.04,0.44c-0.23,0.21 -0.3,0.5 -0.34,1.33c-0.05,1.06 -0.07,1.26 -0.16,1.35c-0.05,0.05 -0.13,0.05 -0.18,-0.01zm-35.59,-2.05c-0.04,0 -0.12,-0.01 -0.16,-0.02l-0.09,-0.01l0.01,-0.47c0.01,-0.25 0.02,-0.47 0.02,-0.47c0.02,-0.02 0.75,0.07 0.75,0.08c-0.01,0.05 -0.43,0.9 -0.45,0.9c-0.01,0 -0.05,-0.01 -0.08,-0.01zm-2.83,-0.68l-0.27,-0.02l-0.02,-0.06c-0.04,-0.13 -0.22,-0.82 -0.22,-0.84c0,-0.01 0.16,-0.11 0.36,-0.21l0.37,-0.18l0.22,0.21c0.12,0.11 0.22,0.22 0.22,0.23c0,0.01 -0.07,0.21 -0.16,0.45c-0.13,0.37 -0.16,0.44 -0.19,0.44c-0.02,0 -0.16,-0.01 -0.31,-0.02zm-3.39,-0.85c-0.28,-0.05 -0.51,-0.1 -0.52,-0.11c-0.01,0 -0.08,-0.8 -0.08,-0.9l0,-0.07l0.58,-0.19l0.59,-0.18l0.18,0.05c0.15,0.05 0.19,0.07 0.18,0.09c-0.01,0.02 -0.09,0.33 -0.2,0.69c-0.22,0.8 -0.2,0.73 -0.21,0.73c-0.01,-0.01 -0.25,-0.05 -0.52,-0.11zm20.13,-1.51c0.02,-0.01 9.75,-3.86 21.64,-8.56c11.88,-4.71 21.63,-8.56 21.66,-8.58c0.05,-0.02 -1.68,-0.76 -23.16,-9.94c-12.77,-5.45 -23.21,-9.92 -23.21,-9.92c0.01,-0.01 8.57,2.54 19.04,5.66c10.46,3.11 19.65,5.85 20.41,6.07c0.76,0.23 2.82,0.84 4.58,1.37c1.76,0.52 3.2,0.96 3.22,0.98c0.01,0.01 0.42,1.26 0.92,2.76c0.49,1.51 0.9,2.73 0.91,2.72c0.01,-0.01 0.3,-1.13 0.66,-2.48c0.36,-1.35 0.66,-2.46 0.66,-2.46c0,0 1.92,0.45 4.26,1c2.34,0.55 4.28,1 4.3,1c0.03,0 1.55,-0.44 3.38,-0.98l3.33,-0.97l0.79,-0.77c0.94,-0.92 1.33,-1.32 1.63,-1.65c0.92,-1.04 1.36,-1.95 1.53,-3.18c0.04,-0.35 0.04,-1.24 -0.01,-1.69c-0.16,-1.46 -0.65,-3.23 -1.47,-5.31c-0.09,-0.25 -0.18,-0.48 -0.19,-0.51c-0.03,-0.17 0.09,-0.39 0.27,-0.48c0.12,-0.05 0.29,-0.06 0.41,0c0.13,0.05 0.61,0.35 1.02,0.62c2.11,1.39 3.9,3.08 4.97,4.71c0.81,1.21 1.25,2.37 1.38,3.59c0.04,0.37 0.03,1.12 -0.01,1.45c-0.02,0.11 -0.03,0.2 -0.03,0.2c0,0.01 2.5,-0.72 5.56,-1.62c3.06,-0.89 5.57,-1.62 5.58,-1.62c0.02,0.01 0.32,0.68 0.67,1.5c0.42,0.95 0.65,1.47 0.66,1.45c0.01,-0.02 0.19,-0.84 0.41,-1.82c0.31,-1.36 0.41,-1.78 0.44,-1.79c0.29,-0.09 12.89,-3.51 12.89,-3.5c0.01,0 -0.04,0.48 -0.09,1.06c-0.09,0.83 -0.12,1.07 -0.14,1.09c-0.02,0.02 -2.64,1.05 -5.83,2.29l-5.81,2.26l-0.74,4.02c-0.4,2.22 -0.74,4.02 -0.75,4.02c0,-0.01 -0.45,-1.45 -0.99,-3.19c-0.53,-1.75 -0.98,-3.19 -0.98,-3.2c-0.01,-0.02 -2.02,0.81 -5.63,2.32c-3.08,1.28 -5.62,2.34 -5.64,2.35c-0.02,0.02 -0.02,0.05 0.06,0.23c0.31,0.74 0.85,1.32 1.53,1.65c0.12,0.06 0.27,0.13 0.33,0.15c0.11,0.03 0.12,0.03 0.22,-0.01c0.16,-0.05 0.45,-0.19 0.61,-0.29c0.07,-0.05 0.2,-0.16 0.29,-0.25c0.44,-0.44 0.49,-0.95 0.15,-1.68c-0.09,-0.19 -0.11,-0.24 -0.11,-0.33c0.01,-0.26 0.21,-0.45 0.49,-0.45c0.14,0 0.25,0.05 0.35,0.15c0.1,0.11 0.64,1.28 1.04,2.28c0.74,1.83 1.19,3.43 1.4,4.95c0.03,0.19 0.05,0.36 0.06,0.37c0.01,0.01 1.45,0.59 3.19,1.29c1.75,0.71 3.2,1.29 3.23,1.3c0.04,0.03 0,0.06 -0.73,0.75c-0.43,0.39 -1.12,1.03 -1.55,1.42c-0.77,0.71 -1.22,1.12 -1.37,1.27l-0.09,0.08l-1.79,-0.44c-0.99,-0.24 -1.82,-0.44 -1.83,-0.44c-0.02,0 -0.09,0.07 -0.18,0.21c-0.66,0.98 -1.6,1.77 -2.8,2.36c-1.3,0.64 -2.86,1.02 -4.81,1.18c-0.44,0.03 -1.88,0.05 -2.43,0.02c-0.52,-0.03 -0.57,-0.03 -0.55,-0.07c0,-0.02 0.12,-0.21 0.26,-0.44l0.24,-0.4l0.68,0.01c2.95,0.06 5.39,-0.51 7.04,-1.62c0.67,-0.46 1.27,-1.06 1.66,-1.7c1.11,-1.79 1.2,-4.28 0.29,-7.43c-0.16,-0.57 -0.61,-1.86 -0.8,-2.3l-0.03,-0.07l-0.1,0.14c-0.14,0.18 -0.4,0.42 -0.63,0.58c-0.24,0.16 -0.63,0.35 -0.92,0.44c-0.3,0.1 -0.35,0.11 -0.56,0.05c-0.7,-0.17 -1.48,-0.67 -1.98,-1.26c-0.79,-0.94 -1.18,-2.21 -1.13,-3.71c0.04,-0.98 0.18,-1.81 0.56,-3.15c0.14,-0.49 0.19,-0.81 0.2,-1.33c0.01,-0.49 -0.01,-0.73 -0.09,-1.17c-0.19,-1.05 -0.76,-2.23 -1.6,-3.33c-0.62,-0.8 -1.56,-1.76 -2.51,-2.53c-0.47,-0.38 -1.43,-1.1 -1.45,-1.08c-0.01,0 0.04,0.16 0.11,0.34c0.56,1.57 0.94,3.11 1.07,4.38c0.04,0.41 0.04,1.27 0.01,1.6c-0.13,1.23 -0.52,2.23 -1.25,3.2c-0.38,0.52 -0.59,0.75 -1.9,2.05c-1.54,1.54 -1.87,1.89 -2.46,2.68c-0.76,1.02 -1.37,2.12 -1.87,3.37c-0.75,1.9 -0.99,3.44 -0.78,4.93c0.23,1.58 1,2.99 2.29,4.19c0.52,0.48 1.13,0.94 1.76,1.32l0.16,0.09l-0.25,0.39c-0.13,0.21 -0.24,0.38 -0.25,0.39c-0.01,0.01 -0.38,-0.22 -0.71,-0.44c-1,-0.67 -1.87,-1.48 -2.5,-2.34c-0.66,-0.89 -1.12,-1.87 -1.35,-2.92c-0.11,-0.46 -0.18,-1.03 -0.18,-1.39l0,-0.21l-0.07,-0.02c-0.05,-0.01 -0.6,-0.15 -1.24,-0.31l-1.17,-0.3l-1.98,0.51c-1.09,0.28 -1.98,0.51 -1.98,0.51c-0.01,0 -0.22,1.4 -0.49,3.11c-0.26,1.71 -0.49,3.1 -0.49,3.1c-0.01,-0.01 -0.31,-1.28 -0.67,-2.83c-0.37,-1.55 -0.66,-2.82 -0.67,-2.83c0,0 -2.85,0.69 -6.33,1.55c-3.48,0.86 -6.33,1.55 -6.34,1.55c0,-0.01 -0.27,-0.55 -0.58,-1.22c-0.32,-0.66 -0.58,-1.21 -0.58,-1.22c-0.01,0 -0.03,0.03 -0.04,0.07c-0.01,0.04 -0.24,0.77 -0.5,1.61l-0.48,1.52l-17.27,3.95c-9.5,2.17 -17.3,3.95 -17.33,3.96c-0.04,0.01 -0.05,0.01 -0.03,-0.01zm-0.23,-4.29c-0.14,-0.15 -0.29,-0.43 -0.61,-1.19c-0.69,-1.61 -1.03,-2.11 -1.53,-2.26c-0.14,-0.04 -0.49,-0.07 -0.69,-0.06c-0.11,0.01 -0.39,0.04 -0.63,0.06c-0.5,0.04 -0.73,0.04 -0.81,-0.01c-0.11,-0.08 -0.1,-0.2 0.03,-0.3c0.05,-0.03 0.3,-0.18 0.57,-0.31c0.71,-0.37 0.96,-0.55 1.15,-0.84c0.17,-0.27 0.23,-0.59 0.21,-1.17c-0.01,-0.49 -0.04,-0.71 -0.22,-1.64c-0.17,-0.85 -0.18,-0.93 -0.17,-1.14c0.01,-0.16 0.01,-0.18 0.05,-0.22c0.08,-0.06 0.11,-0.05 0.21,0.06c0.12,0.13 0.28,0.45 0.52,1.05c0.54,1.35 0.83,1.9 1.17,2.24c0.35,0.36 0.8,0.43 1.9,0.32c0.55,-0.06 0.67,-0.06 0.76,0.03c0.16,0.17 0.01,0.3 -0.69,0.6c-0.79,0.34 -1.12,0.6 -1.28,0.99c-0.04,0.12 -0.04,0.15 -0.04,0.56c0,0.49 0.02,0.63 0.22,1.7c0.2,1.08 0.23,1.44 0.14,1.57c-0.08,0.09 -0.14,0.08 -0.26,-0.04zm6.75,-4.86c-0.77,-0.17 -1.36,-0.75 -1.55,-1.52c-0.06,-0.25 -0.06,-0.69 0,-0.94c0.15,-0.62 0.56,-1.13 1.12,-1.38c0.3,-0.14 0.43,-0.16 0.82,-0.16c0.33,0 0.37,0 0.54,0.05c0.71,0.22 1.22,0.76 1.4,1.49c0.06,0.23 0.05,0.74 -0.01,0.97c-0.07,0.25 -0.24,0.59 -0.4,0.79c-0.25,0.31 -0.65,0.57 -1.03,0.67c-0.22,0.06 -0.69,0.07 -0.89,0.03zm112.87,-1.53c-0.49,-0.03 -0.97,-0.13 -1.44,-0.32c-0.19,-0.07 -0.41,-0.19 -0.33,-0.17c0.74,0.14 1.38,0.11 2.04,-0.11c1.11,-0.37 2,-1.26 2.36,-2.36c0.13,-0.39 0.17,-0.63 0.18,-1.07c0.02,-0.68 -0.08,-1.15 -0.37,-1.74c-0.26,-0.53 -0.62,-0.97 -1.09,-1.33c-0.94,-0.72 -2.21,-0.94 -3.36,-0.59c-0.62,0.19 -1.14,0.51 -1.61,0.99l-0.18,0.18l0.06,-0.12c0.09,-0.17 0.32,-0.51 0.48,-0.71c0.07,-0.08 0.13,-0.16 0.13,-0.17c0,-0.01 0.02,-0.2 0.04,-0.43c0.06,-0.5 0.07,-1.6 0.02,-1.86c-0.06,-0.36 -0.13,-0.52 -0.31,-0.7c-0.27,-0.27 -0.8,-0.53 -1.39,-0.68c-0.11,-0.03 -0.21,-0.06 -0.22,-0.06c0,0 0.04,-0.12 0.1,-0.27c0.21,-0.54 0.34,-1.07 0.36,-1.46c0.02,-0.43 -0.05,-0.66 -0.3,-0.92c-0.28,-0.27 -0.66,-0.52 -1.25,-0.81l-0.34,-0.17l0.09,-0.19c0.04,-0.1 0.11,-0.27 0.15,-0.38c0.06,-0.17 0.07,-0.21 0.07,-0.4c0,-0.19 -0.01,-0.24 -0.06,-0.38c-0.08,-0.2 -0.2,-0.48 -0.33,-0.69c-0.05,-0.09 -0.09,-0.17 -0.08,-0.18c0.02,-0.02 0.36,0.13 0.64,0.27c1.46,0.76 3.13,2.4 4.1,4.02c0.15,0.24 0.39,0.75 0.47,0.97c0.06,0.2 0.12,0.46 0.12,0.55l0,0.06l-0.12,-0.06c-0.16,-0.07 -0.35,-0.12 -0.41,-0.1c-0.11,0.05 -0.23,0.24 -0.3,0.52c-0.03,0.12 -0.05,0.25 -0.05,0.49c-0.02,0.37 0.01,0.67 0.08,1.04c0.05,0.25 0.2,0.72 0.24,0.78c0.02,0.03 0.05,0.02 0.21,-0.05c0.4,-0.19 0.97,-0.34 1.45,-0.39c0.3,-0.03 0.87,-0.01 1.16,0.03c1.29,0.21 2.42,0.94 3.14,2.04c0.15,0.22 0.38,0.69 0.46,0.92c0.07,0.2 0.07,0.2 0.28,0.12c0.31,-0.12 0.8,-0.41 1.2,-0.71c0.84,-0.63 1.4,-1.28 1.59,-1.83c0.03,-0.09 0.05,-0.2 0.05,-0.25c0,-0.14 -0.09,-0.23 -0.34,-0.35l-0.19,-0.1l0.1,-0.08c0.12,-0.12 0.49,-0.36 0.69,-0.47c0.86,-0.45 2.09,-0.76 3.51,-0.9c0.38,-0.03 1.67,-0.03 2.02,0c1.06,0.11 1.9,0.32 2.56,0.65c0.11,0.06 0.23,0.12 0.26,0.14l0.07,0.04l-0.3,0.1c-0.55,0.19 -0.97,0.4 -1.19,0.6c-0.2,0.17 -0.45,0.61 -0.67,1.14c-0.04,0.1 -0.08,0.18 -0.09,0.19c-0.01,0.01 -0.15,-0.04 -0.31,-0.11c-0.35,-0.16 -0.82,-0.31 -1.13,-0.38c-0.17,-0.04 -0.26,-0.05 -0.54,-0.05c-0.3,0 -0.35,0.01 -0.46,0.05c-0.51,0.19 -1.15,1.01 -1.8,2.32c-0.1,0.21 -0.2,0.38 -0.21,0.39c0,0 -0.13,-0.04 -0.28,-0.1c-0.91,-0.34 -1.74,-0.49 -2.21,-0.4c-0.26,0.06 -0.55,0.23 -0.95,0.54c-0.33,0.27 -1.04,0.99 -1.4,1.44c-0.02,0.01 -0.04,0.12 -0.06,0.22c-0.26,1.64 -1.44,3.02 -3.03,3.56c-0.35,0.12 -0.78,0.21 -1.12,0.23c-0.1,0.01 -0.23,0.02 -0.28,0.02c-0.06,0 -0.23,0 -0.38,-0.01zm-110.23,-0.4c-0.01,-0.34 -0.02,-0.4 -0.04,-0.51c-0.01,-0.07 -0.02,-0.13 -0.02,-0.13c0.01,-0.01 6.04,-0.86 6.77,-0.95l0.13,-0.02l0.03,-0.13c0.03,-0.17 0.14,-0.4 0.26,-0.52c0.12,-0.13 0.3,-0.26 0.46,-0.3c0.11,-0.04 0.11,-0.04 0.11,-0.1c0.01,-0.2 0.24,-6.85 0.25,-6.86c0,0 0.08,0.01 0.16,0.03c0.1,0.02 0.23,0.02 0.39,0.02l0.24,-0.01l0,0.08c0,0.05 -0.06,1.63 -0.12,3.52l-0.13,3.44l0.14,0.13c0.2,0.2 0.33,0.51 0.33,0.78c0,0.26 -0.13,0.56 -0.33,0.76c-0.4,0.42 -1.05,0.42 -1.46,0.01c-0.04,-0.04 -0.09,-0.07 -0.11,-0.07c-0.02,0 -0.3,0.03 -0.61,0.08c-2.64,0.37 -6.39,0.89 -6.42,0.89c-0.02,0 -0.03,-0.03 -0.03,-0.14zm109.08,-0.55c-0.96,-0.06 -1.86,-0.58 -2.41,-1.4c-0.71,-1.07 -0.71,-2.47 -0.01,-3.53c0.86,-1.29 2.48,-1.78 3.89,-1.19c0.39,0.17 0.69,0.37 1,0.68c0.45,0.45 0.73,0.97 0.87,1.61c0.04,0.17 0.05,0.26 0.05,0.64c0,0.37 -0.01,0.46 -0.05,0.64c-0.29,1.32 -1.32,2.31 -2.62,2.52c-0.25,0.04 -0.42,0.05 -0.72,0.03zm0.01,-0.67c0.38,-0.11 0.67,-0.29 0.94,-0.57c0.27,-0.28 0.43,-0.54 0.55,-0.9c0.16,-0.48 0.16,-1.07 0.01,-1.54c-0.19,-0.56 -0.6,-1.05 -1.09,-1.3c-0.42,-0.21 -0.93,-0.27 -1.39,-0.15c-0.21,0.05 -0.57,0.22 -0.75,0.35c-1.09,0.84 -1.23,2.53 -0.29,3.53c0.24,0.25 0.53,0.43 0.85,0.54c0.26,0.09 0.37,0.1 0.7,0.1c0.24,-0.01 0.32,-0.02 0.47,-0.06zm0.16,-1.86c-0.52,-0.09 -0.88,-0.52 -0.88,-1.06c0,-0.49 0.34,-0.93 0.8,-1.05c0.34,-0.09 0.71,0.02 0.96,0.27c0.48,0.48 0.4,1.31 -0.16,1.68c-0.2,0.14 -0.49,0.2 -0.72,0.16zm-93.98,1.38c-0.02,-0.02 -0.06,-0.09 -0.08,-0.16c-0.03,-0.1 -0.03,-0.23 -0.03,-1.19c-0.01,-1.11 -0.01,-1.24 -0.11,-1.59c-0.13,-0.53 -0.46,-0.76 -1.45,-1.02c-0.46,-0.13 -0.59,-0.17 -0.67,-0.24c-0.06,-0.04 -0.07,-0.06 -0.06,-0.12c0,-0.06 0.02,-0.09 0.06,-0.11c0.09,-0.05 0.3,-0.08 0.61,-0.08c0.29,0 0.69,-0.03 0.86,-0.06c0.34,-0.07 0.61,-0.21 0.75,-0.39c0.2,-0.27 0.32,-0.62 0.57,-1.65c0.26,-1.04 0.32,-1.21 0.45,-1.34c0.07,-0.07 0.13,-0.07 0.18,-0.01c0.11,0.11 0.13,0.29 0.15,1.37c0.02,0.95 0.04,1.18 0.12,1.49c0.15,0.53 0.39,0.69 1.47,0.96c0.45,0.11 0.58,0.16 0.67,0.23c0.09,0.07 0.09,0.14 -0.01,0.2c-0.08,0.05 -0.21,0.08 -0.65,0.12c-0.85,0.08 -1.2,0.18 -1.46,0.43c-0.34,0.32 -0.58,0.85 -0.79,1.73c-0.29,1.25 -0.3,1.3 -0.41,1.4c-0.08,0.08 -0.12,0.09 -0.17,0.03zm-19.76,-2.68l-1,-2.39l-0.08,-0.02c-0.14,-0.02 -0.31,-0.08 -0.42,-0.15c-0.09,-0.06 -0.28,-0.25 -0.34,-0.34l-0.03,-0.05l-2.64,0.29c-1.45,0.16 -3.22,0.35 -3.93,0.42c-0.71,0.08 -2.35,0.26 -3.64,0.4c-1.29,0.14 -2.37,0.26 -2.4,0.26l-0.06,0.01l-0.01,-0.28c0,-0.16 -0.02,-0.32 -0.04,-0.39c-0.02,-0.07 -0.03,-0.12 -0.03,-0.13c0.01,0 2.51,-0.27 5.57,-0.6c3.06,-0.33 5.9,-0.64 6.32,-0.69l0.77,-0.08l0.08,-0.17c0.19,-0.38 0.53,-0.59 0.95,-0.59c0.3,0 0.52,0.09 0.74,0.31l0.11,0.1l5.6,-1.39l5.59,-1.4l0.02,0.16c0.01,0.18 0.08,0.43 0.12,0.52c0.02,0.03 0.03,0.07 0.03,0.08c0,0.01 -2.5,0.64 -5.57,1.41c-3.07,0.76 -5.58,1.39 -5.58,1.39c-0.01,0 -0.02,0.06 -0.04,0.12c-0.04,0.16 -0.13,0.33 -0.24,0.45l-0.09,0.1l0.97,2.33c0.53,1.28 0.97,2.34 0.98,2.36c0.01,0.04 -0.01,0.05 -0.13,0.08c-0.07,0.02 -0.24,0.09 -0.36,0.15l-0.23,0.12l-0.99,-2.39zm-20.25,2.33c-0.11,-0.02 -0.29,-0.12 -0.39,-0.2c-0.11,-0.1 -0.22,-0.26 -0.27,-0.42c-0.06,-0.17 -0.05,-0.44 0.02,-0.61c0.08,-0.22 0.3,-0.44 0.52,-0.52c0.17,-0.07 0.48,-0.08 0.64,-0.03c0.1,0.04 0.13,0.04 0.15,0.02c0.02,-0.01 0.44,-0.38 0.94,-0.81c0.5,-0.43 0.91,-0.78 0.92,-0.79c0.01,0 0.07,0.07 0.12,0.15c0.06,0.09 0.18,0.22 0.26,0.3l0.15,0.14l-0.95,0.83l-0.96,0.82l0,0.23c0,0.21 0,0.22 -0.08,0.38c-0.12,0.25 -0.33,0.44 -0.61,0.51c-0.11,0.03 -0.34,0.03 -0.46,0zm17.22,-2.51c-0.13,-0.03 -0.23,-0.1 -0.33,-0.22c-0.12,-0.12 -0.16,-0.24 -0.16,-0.43c0,-0.12 0.01,-0.16 0.06,-0.27c0.08,-0.15 0.21,-0.27 0.36,-0.33c0.16,-0.06 0.4,-0.05 0.54,0.03c0.13,0.06 0.26,0.21 0.32,0.33c0.06,0.15 0.06,0.37 -0.01,0.52c-0.13,0.29 -0.48,0.46 -0.78,0.37zm-13.42,-0.24c-0.52,-0.1 -0.92,-0.46 -1.1,-0.96c-0.05,-0.14 -0.05,-0.19 -0.05,-0.42c0,-0.23 0,-0.28 0.05,-0.42c0.17,-0.47 0.52,-0.81 0.99,-0.94c0.18,-0.05 0.53,-0.05 0.71,0c0.98,0.27 1.37,1.43 0.74,2.23c-0.17,0.22 -0.48,0.41 -0.75,0.48c-0.18,0.05 -0.43,0.06 -0.59,0.03zm-4.9,-1.39c-0.18,-0.04 -0.36,-0.18 -0.45,-0.35c-0.07,-0.12 -0.07,-0.41 0,-0.54c0.07,-0.13 0.17,-0.23 0.3,-0.29c0.1,-0.06 0.14,-0.06 0.29,-0.06c0.14,0 0.18,0 0.28,0.05c0.49,0.24 0.48,0.92 -0.01,1.14c-0.12,0.06 -0.29,0.08 -0.41,0.05zm34,-3.56c-0.44,-0.07 -0.88,-0.39 -1.08,-0.78c-0.12,-0.24 -0.17,-0.41 -0.18,-0.67c-0.01,-0.34 0.07,-0.64 0.26,-0.91c0.21,-0.32 0.52,-0.54 0.91,-0.63c0.24,-0.07 0.61,-0.05 0.84,0.03c0.7,0.24 1.15,0.94 1.04,1.66c-0.1,0.65 -0.58,1.16 -1.22,1.29c-0.16,0.03 -0.4,0.04 -0.57,0.01zm-23.65,-0.55c-0.04,-0.02 -0.1,-0.06 -0.13,-0.1c-0.14,-0.16 -0.17,-0.34 -0.19,-1.21c-0.02,-0.67 -0.05,-0.98 -0.08,-1.08c-0.03,-0.07 -0.22,-0.16 -0.61,-0.28c-0.51,-0.17 -0.68,-0.23 -0.81,-0.3c-0.43,-0.25 -0.45,-0.66 -0.06,-0.96c0.16,-0.12 0.43,-0.26 0.89,-0.45c0.5,-0.21 0.54,-0.23 0.55,-0.31c0.01,-0.04 0.02,-0.39 0.02,-0.78c0.01,-0.77 0.03,-0.98 0.13,-1.17c0.07,-0.13 0.11,-0.18 0.23,-0.23c0.34,-0.14 0.69,0.13 1.56,1.23c0.09,0.11 0.14,0.16 0.17,0.16c0.02,0 0.27,-0.07 0.54,-0.17c0.62,-0.21 0.8,-0.26 1.02,-0.26c0.15,0 0.19,0.01 0.28,0.05c0.11,0.06 0.19,0.17 0.23,0.29c0.07,0.27 -0.03,0.54 -0.46,1.22c-0.3,0.48 -0.36,0.6 -0.34,0.66c0.01,0.06 0.16,0.27 0.58,0.79c0.53,0.65 0.65,0.87 0.65,1.11c0,0.24 -0.1,0.39 -0.32,0.45c-0.2,0.06 -0.49,0.02 -1.06,-0.15c-0.78,-0.23 -0.98,-0.27 -1.04,-0.24c-0.05,0.03 -0.27,0.32 -0.58,0.77c-0.47,0.69 -0.63,0.88 -0.81,0.97c-0.11,0.05 -0.27,0.05 -0.36,-0.01zm62.98,-2.05c-0.36,-0.08 -0.6,-0.35 -0.72,-0.8c-0.06,-0.24 -0.07,-0.88 -0.03,-1.37c0.06,-0.58 0.04,-0.73 -0.08,-0.86c-0.14,-0.15 -0.26,-0.17 -0.95,-0.19c-0.6,-0.02 -0.67,-0.03 -0.96,-0.15c-0.62,-0.25 -1.22,-0.77 -1.52,-1.35c-0.2,-0.37 -0.28,-0.74 -0.28,-1.22c0,-0.44 0.06,-0.81 0.21,-1.24c0.2,-0.58 0.45,-0.99 0.85,-1.37c0.22,-0.22 0.3,-0.28 0.52,-0.42c0.21,-0.13 0.44,-0.23 0.71,-0.3c0.81,-0.22 1.54,-0.24 2.38,-0.05c0.54,0.12 0.94,0.31 1.36,0.67c0.54,0.45 1.03,1.19 1.15,1.76c0.19,0.85 0,2.07 -0.36,2.37c-0.19,0.16 -0.23,0.38 -0.18,0.89c0.07,0.64 0.08,0.77 0.06,0.93c-0.03,0.21 -0.09,0.32 -0.22,0.4c-0.08,0.05 -0.11,0.06 -0.26,0.06c-0.19,0 -0.24,-0.03 -0.34,-0.17c-0.07,-0.1 -0.13,-0.13 -0.22,-0.11c-0.06,0.01 -0.07,0.03 -0.09,0.12c-0.03,0.08 -0.03,0.19 -0.01,0.7c0.04,0.8 0,1.13 -0.13,1.39c-0.07,0.14 -0.13,0.21 -0.25,0.27c-0.1,0.05 -0.13,0.06 -0.31,0.07c-0.13,0 -0.25,-0.01 -0.33,-0.03zm-59.01,-0.86c-0.07,-0.09 -0.13,-0.18 -0.14,-0.19c0,-0.03 0.34,-0.22 0.6,-0.34c0.64,-0.29 1.41,-0.48 2.32,-0.59c0.42,-0.06 1.51,-0.05 1.85,0c0.3,0.04 0.58,0.12 0.76,0.19c0.16,0.08 0.19,0.08 0.26,0.02c0.05,-0.05 0.05,-0.06 0.05,-0.24c-0.01,-0.5 -0.07,-1.55 -0.09,-1.56c-0.04,-0.03 -0.64,-0.08 -0.99,-0.1c-0.19,0 -0.54,0 -0.76,0c-1.47,0.05 -2.88,0.44 -3.8,1.06l-0.22,0.15l0.11,-0.24c0.15,-0.31 0.19,-0.47 0.18,-0.72c-0.01,-0.27 -0.07,-0.4 -0.25,-0.57c-0.07,-0.07 -0.15,-0.13 -0.17,-0.13c-0.02,-0.01 -0.04,-0.02 -0.04,-0.03c0,-0.02 0.6,-0.34 0.86,-0.46c1.13,-0.53 2.3,-0.86 3.49,-0.99c0.39,-0.04 0.97,-0.07 1.3,-0.07c0.15,0 0.28,0 0.28,0c0.01,-0.01 0,-0.32 -0.01,-0.69l-0.03,-0.68l-0.05,-0.08c-0.03,-0.05 -0.09,-0.1 -0.15,-0.13c-0.09,-0.04 -0.1,-0.04 -0.66,-0.03c-0.59,0.01 -0.77,0.02 -1.26,0.09c-1.16,0.17 -2.42,0.58 -3.57,1.16c-0.87,0.43 -1.81,1.05 -2.36,1.54l-0.14,0.13l-0.16,-0.18l-0.17,-0.17l0.09,-0.08c0.22,-0.21 0.7,-0.59 1.1,-0.85c1.47,-0.98 3.16,-1.67 4.8,-1.97c0.6,-0.11 1,-0.15 1.67,-0.16c0.53,-0.01 0.62,-0.01 0.72,0.03c0.16,0.04 0.27,0.11 0.4,0.24c0.12,0.12 0.2,0.27 0.22,0.43c0.02,0.13 0.05,1.04 0.08,2.8c0.01,0.67 0.03,1.48 0.05,1.79c0.01,0.32 0.02,0.63 0.01,0.69c-0.03,0.2 -0.16,0.38 -0.37,0.49c-0.07,0.04 -0.12,0.05 -0.26,0.05c-0.15,0 -0.18,-0.01 -0.33,-0.07c-0.18,-0.09 -0.33,-0.13 -0.64,-0.18c-0.33,-0.05 -1.39,-0.05 -1.85,0.01c-0.64,0.09 -1.25,0.23 -1.72,0.4c-0.22,0.08 -0.61,0.26 -0.76,0.35c-0.05,0.04 -0.1,0.06 -0.1,0.06c0,0 -0.07,-0.08 -0.15,-0.18zm104.86,0.15c-0.26,-0.01 -1.03,-0.09 -1.31,-0.13c-1.9,-0.26 -3.46,-0.81 -4.26,-1.49c-0.23,-0.19 -0.41,-0.41 -0.48,-0.59l-0.04,-0.09l0.24,-1.2l0.25,-1.21l0.1,-0.02c0.2,-0.05 0.64,-0.09 1.18,-0.1l0.55,-0.02l-0.01,0.16c-0.04,0.39 -0.01,0.48 0.23,0.71c0.31,0.3 0.62,0.51 1.03,0.72c0.89,0.44 1.96,0.67 3.01,0.64c0.85,-0.03 1.45,-0.2 1.8,-0.53c0.18,-0.16 0.2,-0.22 0.25,-0.58c0.02,-0.17 0.04,-0.31 0.05,-0.32c0.01,-0.01 0.37,0.1 0.65,0.2c0.49,0.16 0.91,0.37 1.12,0.55l0.09,0.07l-0.15,1.14c-0.1,0.8 -0.16,1.16 -0.18,1.19c-0.3,0.48 -1.21,0.8 -2.54,0.89c-0.26,0.02 -1.28,0.03 -1.58,0.01zm-88.16,-0.09c-0.23,-0.04 -0.52,-0.25 -0.64,-0.46c-0.18,-0.29 -0.17,-0.73 0.01,-1.01c0.14,-0.24 0.41,-0.41 0.69,-0.45c0.45,-0.07 0.9,0.21 1.05,0.64c0.07,0.19 0.07,0.47 0,0.65c-0.18,0.47 -0.63,0.73 -1.11,0.63zm87.85,-3.08c-1.18,-0.14 -2.26,-0.58 -2.84,-1.18l-0.1,-0.1l0.69,-6.85c0.38,-3.77 0.69,-6.9 0.7,-6.95l0.02,-0.09l0.26,-0.13c0.95,-0.47 2.08,-0.66 3.04,-0.51c0.81,0.12 1.6,0.48 2.26,1.04c0.18,0.15 0.2,0.18 0.2,0.23c-0.02,0.14 -1.95,14.08 -1.96,14.12c-0.01,0.04 -0.13,0.14 -0.28,0.21c-0.14,0.07 -0.39,0.15 -0.62,0.19c-0.26,0.05 -1.03,0.06 -1.37,0.02zm3.6,-6.01c0.01,-0.02 0.05,-0.32 0.1,-0.67c0.08,-0.58 0.09,-0.64 0.13,-0.65c0.06,-0.03 10.79,-2.95 10.81,-2.95c0.01,0 -10.74,4.2 -11.01,4.3c-0.03,0.01 -0.04,0 -0.03,-0.03zm-47.39,-1.89c-0.37,-0.05 -0.66,-0.33 -0.81,-0.78c-0.11,-0.36 -0.13,-0.53 -0.13,-1.47c0,-0.93 0,-0.96 -0.11,-0.93c-0.08,0.02 -0.09,0.04 -0.22,0.29c-0.14,0.27 -0.26,0.42 -0.43,0.52c-0.4,0.23 -1.11,0.28 -1.46,0.1c-0.25,-0.12 -0.38,-0.28 -0.59,-0.68c-0.08,-0.15 -0.16,-0.28 -0.19,-0.3c-0.12,-0.1 -0.15,-0.05 -0.38,0.59c-0.18,0.52 -0.4,0.9 -0.6,1.07c-0.16,0.13 -0.29,0.18 -0.49,0.19c-0.22,0.01 -0.37,-0.02 -0.55,-0.1c-0.42,-0.22 -0.69,-0.74 -0.81,-1.59c-0.03,-0.23 -0.03,-0.41 -0.03,-1.11c0,-0.5 0.01,-0.99 0.02,-1.2c0.02,-0.19 0.05,-0.63 0.08,-0.98c0.03,-0.34 0.07,-0.9 0.09,-1.23c0.02,-0.34 0.06,-0.74 0.08,-0.89c0.25,-1.7 1.05,-3.04 2.36,-3.91c0.53,-0.35 0.89,-0.51 1.73,-0.79c0.75,-0.25 1.17,-0.42 1.66,-0.66c1.7,-0.82 2.65,-1.78 2.9,-2.91c0.05,-0.24 0.05,-0.71 -0.01,-0.96c-0.16,-0.73 -0.59,-1.44 -1.34,-2.19c-0.65,-0.65 -1.32,-1.14 -2.06,-1.51c-0.78,-0.39 -1.48,-0.57 -2.19,-0.57c-0.36,0 -0.57,0.02 -0.85,0.09c-0.64,0.17 -1.15,0.51 -1.55,1.03c-0.32,0.4 -0.51,0.84 -1,2.25c-0.37,1.05 -0.63,1.66 -0.89,2.04c-0.15,0.23 -0.45,0.53 -0.63,0.62c-0.32,0.17 -0.68,0.18 -1.07,0.04c-0.35,-0.12 -0.49,-0.48 -0.57,-1.48c-0.04,-0.46 -0.06,-0.61 -0.11,-0.72c-0.04,-0.11 -0.1,-0.14 -0.2,-0.12c-0.12,0.02 -0.2,0.1 -0.33,0.31c-0.19,0.31 -0.42,0.48 -0.76,0.56c-0.22,0.06 -0.8,0.06 -0.99,0c-0.3,-0.07 -0.51,-0.23 -0.64,-0.44c-0.03,-0.05 -0.09,-0.22 -0.14,-0.36c-0.11,-0.34 -0.14,-0.4 -0.23,-0.44c-0.15,-0.06 -0.19,0.02 -0.35,0.65c-0.17,0.68 -0.27,0.93 -0.46,1.2c-0.16,0.23 -0.37,0.38 -0.64,0.45c-0.18,0.04 -0.53,0.02 -0.75,-0.05c-0.48,-0.15 -0.75,-0.51 -0.87,-1.17c-0.06,-0.28 -0.05,-1.29 0.01,-2.03c0.08,-1.08 0.19,-1.65 0.44,-2.42c0.92,-2.82 3.37,-5.04 6.88,-6.24c2.24,-0.77 4.84,-1.06 7.4,-0.84c3.45,0.31 6.57,1.52 8.86,3.45c0.34,0.28 1.13,1.08 1.41,1.41c0.88,1.07 1.5,2.2 1.96,3.54c0.26,0.78 0.44,1.54 0.53,2.31c0.04,0.39 0.06,1.18 0.03,1.57c-0.2,2.51 -1.52,4.65 -3.96,6.39c-0.39,0.28 -0.6,0.42 -1.31,0.84c-0.93,0.56 -1.52,0.96 -2.06,1.4c-0.25,0.21 -0.72,0.69 -0.89,0.9c-0.47,0.6 -0.75,1.21 -0.9,1.96c-0.09,0.45 -0.11,0.78 -0.17,1.96c-0.06,1.34 -0.17,2.04 -0.41,2.57c-0.27,0.57 -0.74,0.85 -1.31,0.77z" display="inline" fill="#000000" id="path1"/> + </g> + </g> +</svg>
\ No newline at end of file diff --git a/graphs/js/coordinatesDisplay/server.js b/graphs/js/coordinatesDisplay/server.js new file mode 100644 index 0000000..45b7fed --- /dev/null +++ b/graphs/js/coordinatesDisplay/server.js @@ -0,0 +1,92 @@ +// svg image server +const express = require("express"); +const cors = require("cors"); +const DOMParser = require("xmldom").DOMParser; +const XMLSerializer = require("xmldom").XMLSerializer; +const fs = require("fs"); + +const app = express(); + +app.use(cors()); + +app.use(express.static("public")); + +app.listen(2707, () => { + console.log("Server listening on port 2707 👂"); +}); + +const sidePiecesCount = 20; // size has to odd to make the puzzle solvable + +app.get("/mapWidth", (req, res) => { + res.json(sidePiecesCount); +}); + +const parser = new DOMParser(); + +const svgText = fs.readFileSync(__dirname + "/resources/logo.svg", "utf8"); +const svg = parser.parseFromString(svgText, "image/svg+xml"); + +const width = svg.documentElement.getAttribute("width"); +const height = svg.documentElement.getAttribute("height"); + +const gridSideSize = Math.max(width, height); + +const pieceSize = gridSideSize / sidePiecesCount; + +const piecesMap = new Array(sidePiecesCount * sidePiecesCount); + +for (let x = 0; x < sidePiecesCount; x++) { + for (let y = 0; y < sidePiecesCount; y++) { + const piece = svg.cloneNode(true); + + piece.documentElement.setAttribute( + "viewBox", + `${x * pieceSize} ${y * pieceSize} ${pieceSize} ${pieceSize}`, + ); // ATTENTION : this method is really slow, in real life cases you should really cut the image and not send it with information on where to crop it + piece.documentElement.setAttribute("width", `${pieceSize}`); + piece.documentElement.setAttribute("height", `${pieceSize}`); + const svgString = new XMLSerializer().serializeToString(piece); + + piecesMap[x + y * sidePiecesCount] = { + svg: svgString, + x: x, + y: y, + }; + } +} + +const shuffledCoordinates = Array.from( + Array(sidePiecesCount * sidePiecesCount).keys(), +); + +const swap = (a, i, j) => { + const tmp = a[i]; + + a[i] = a[j]; + a[j] = tmp; +}; + +const shuffle = (a) => { + let i = a.length - 1; + + while (i > 0) { + const j = Math.floor(Math.random() * i); + + swap(a, i, j); + i--; + } +}; + +shuffle(shuffledCoordinates); + +console.log("Coordinates shuffled ! 🥳"); +console.log("now serving on port 2707. 🫡"); + +for (let x = 0; x < shuffledCoordinates.length; x++) { + app.get(`/piece/${x}`, (req, res) => { + console.log(`piece ${x} requested 🤖`); + res.send(piecesMap[shuffledCoordinates[x]]); + }); +} + +exports.app = app; diff --git a/graphs/js/counter/counter.js b/graphs/js/counter/counter.js new file mode 100644 index 0000000..89198de --- /dev/null +++ b/graphs/js/counter/counter.js @@ -0,0 +1,12 @@ +const counter = document.getElementById("count"); +let counterVal = parseInt(counter.innerHTML); +const btnPlus = document.getElementById("plus"); +const btnMinus = document.getElementById("minus"); + +btnPlus.addEventListener("click", () => { + counter.innerHTML = ++counterVal; +}); + +btnMinus.addEventListener("click", () => { + counter.innerHTML = --counterVal; +}); diff --git a/graphs/js/counter/index.html b/graphs/js/counter/index.html new file mode 100644 index 0000000..d088aac --- /dev/null +++ b/graphs/js/counter/index.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="stylesheet" href="style.css"> + <script defer src="counter.js"></script> + <title>My Super Counter</title> +</head> +<body> + <div class="container"> + <div id="count">0</div> + <div class="actions"> + <button id="plus">+</button> + <button id="minus">-</button> + </div> + </div> +</body> +</html> diff --git a/graphs/js/counter/style.css b/graphs/js/counter/style.css new file mode 100644 index 0000000..677acc2 --- /dev/null +++ b/graphs/js/counter/style.css @@ -0,0 +1,31 @@ +html, +body { + height: 100%; +} + +.container { + height: 100%; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; +} + +#count { + font-size: 20vh; +} + +.actions { + display: flex; + height: 10vh; +} + +.actions > button { + width: 10vw; + background-color: rgb(0, 132, 255); + font-size: 5vh; +} + +#plus { + margin-right: 20px; +} diff --git a/graphs/js/deepCopyAndEquality/deepCopyAndEquality.js b/graphs/js/deepCopyAndEquality/deepCopyAndEquality.js new file mode 100644 index 0000000..4a67b6b --- /dev/null +++ b/graphs/js/deepCopyAndEquality/deepCopyAndEquality.js @@ -0,0 +1,41 @@ +function deepCopy(x) { + if (x == null || x == undefined) { + return x; + } else if (x instanceof Date) { + return new Date(x.valueOf()); + } else if (x instanceof Array) { + const res = new Array(); + + x.forEach((element) => res.push(deepCopy(element))); + return res; + } else if (typeof x === "object") { + const res = {}; + + for (const prop in x) { + res[prop] = deepCopy(x[prop]); + } + + const sort = (o) => + Object.keys(o) + .sort() + .reduce((final, key) => { + final[key] = o[key]; + return final; + }, {}); + + return sort(res); + } else { + return x; + } +} +function deepEquality(a, b) { + if (typeof a !== typeof b) { + return false; + } + + return JSON.stringify(deepCopy(a)) === JSON.stringify(deepCopy(b)); +} +module.exports = { + deepCopy, + deepEquality, +}; diff --git a/graphs/js/epiTinder/data.json b/graphs/js/epiTinder/data.json new file mode 100644 index 0000000..cd325a5 --- /dev/null +++ b/graphs/js/epiTinder/data.json @@ -0,0 +1,118 @@ +{ + "users": [ + { + "id": 0, + "name": "Puff", + "age": 2, + "description": "I like everyone who does javascript (I'm the mascot of the workshop)" + }, + { + "id": 1, + "name": "Bubble", + "age": 1, + "description": "I'm the real javascript mascot but don't tell puff he'll cry again" + }, + { + "id": 2, + "name": "Maxime Buisson", + "age": 40, + "description": "I already have my other half but I want to make friends." + }, + { + "id": 3, + "name": "Dorian Penso", + "age": 25, + "description": "Gym enthusiast by day, code lover by night, seeking a partner to write code and lift weights together." + }, + { + "id": 4, + "name": "Pierre-Alexis Valbrun", + "age": 32, + "description": "I'm a full-stack developer, I can handle both your front-end and back-end." + }, + { + "id": 5, + "name": "Paul Genillon", + "age": 26, + "description": "It’s not humid.. it’s raining" + }, + { + "id": 6, + "name": "Botumrath Morchoisne", + "age": 24, + "description": "What am I doing here??" + }, + { + "id": 7, + "name": "Pierre Santamaria", + "age": 22, + "description": "I'll love you like I love JavaScript, I won't get anything you tell me but it'll be passionate." + }, + { + "id": 8, + "name": "Baptiste Schaudel", + "age": 9, + "description": "I am operational to manage my team, I will let you discover if I am too with love." + }, + { + "id": 9, + "name": "Maxim Payeur", + "age": 8, + "description": "I lost my e, can you help me find it." + }, + { + "id": 10, + "name": "Vinh-Toan Phan", + "age": 17, + "description": "I'm an excelent cooker, do you want to be my cookware." + }, + { + "id": 11, + "name": "Angelina Kuntz", + "age": 44, + "description": "You can call me Ada" + }, + { + "id": 12, + "name": "Ewan Lemonnier", + "age": 19, + "description": "Barely legal" + }, + { + "id": 13, + "name": "Anaïs Druelle", + "age": 21, + "description": "What's the only part of a vegetable you can't eat?" + }, + { + "id": 14, + "name": "Mathéo Romé", + "age": 22, + "description": "I can’t sing but I will charm you anyway" + }, + { + "id": 15, + "name": "Noé Bauvineau", + "age": 58, + "description": "Searching for someone who can appreciate the elegance of a well-designed API." + }, + { + "id": 16, + "name": "Vincent Thirouin", + "age": 39, + "description": "I may not be able to dance, but I can sure write some smooth code." + }, + { + "id": 17, + "name": "Thibault Viennot", + "age": 30, + "description": "Searching for someone who knows how to have fun while debugging" + }, + { + "id": 18, + "name": "Pauline Chautard", + "age": 22, + "description": "I'm like a compiler, I can take your high-level needs and turn them into low-level satisfaction." + } + ] +}
\ No newline at end of file diff --git a/graphs/js/epiTinder/epiTinder.js b/graphs/js/epiTinder/epiTinder.js new file mode 100644 index 0000000..881a2c8 --- /dev/null +++ b/graphs/js/epiTinder/epiTinder.js @@ -0,0 +1,114 @@ +const fs = require("fs"); +const express = require("express"); + +function readUsersFromJSONFile(JSON_filename) { + /* + ** Return the list of users stored in the JSON file + ** JSON_filename: path to the JSON file + */ + const content = fs.readFileSync(JSON_filename, (err) => { + if (err) { + console.error(err); + return; + } + }); + + return JSON.parse(content).users; +} + +function writeUsersToJSONFile(JSON_filename, users) { + /* + ** Overwrite the given JSON_filename with the given + ** list of users. + ** JSON_filename: path to the JSON file + ** users : list of users objects + */ + const usersJSON = JSON.stringify({ users: users }); + + fs.writeFileSync(JSON_filename, usersJSON, (err) => { + if (err) { + console.error(err); + return; + } + }); +} +function epiTinderWebServer(host, port, filename) { + const app = express(); + + app.use(express.json()); + const users = readUsersFromJSONFile(filename); + let maxID = 0; + + if (users.length > 0) { + maxID = Math.max(...users.map((e) => e.id)) + 1; + } + + app.get("/", (req, res) => { + res.status(200).send({ message: "Hello World!" }); + }); + app.get("/users", (req, res) => { + res.status(200).send(users); + }); + app.post("/users", (req, res) => { + const new_user = { + id: maxID++, + name: req.body.name, + age: req.body.age, + description: req.body.description, + }; + + users.push(new_user); + writeUsersToJSONFile(filename, users); + res.status(201).send(new_user); + }); + app.get("/users/:id", (req, res) => { + const u = users.find((e) => e.id == req.params.id); + + if (u == undefined) { + res.status(404).send({ + message: `No user with id: ${req.params.id} found`, + }); + } else { + res.status(200).send(u); + } + }); + app.put("/users/:id", (req, res) => { + const u = users.findIndex((e) => e.id == req.params.id); + + if (u == -1) { + res.status(404).send({ + message: `No user with id: ${req.params.id} found`, + }); + } else { + users[u].name = req.body.name; + users[u].age = req.body.age; + users[u].description = req.body.description; + writeUsersToJSONFile(filename, users); + res.status(201).send(users[u]); + } + }); + app.delete("/users/:id", (req, res) => { + const u = users.findIndex((e) => e.id == req.params.id); + + if (u == -1) { + res.status(404).send({ + message: `No user with id: ${req.params.id} found`, + }); + } else { + const usr = users[u]; + + users.splice(u, 1); + writeUsersToJSONFile(filename, users); + res.status(200).send(usr); + } + }); + app.get("*", (req, res) => { + res.status(404).send({ message: "Not found" }); + }); + return app.listen(port, () => { + console.log("Server running at http://" + host + ":" + port + "/"); + }); +} +module.exports = { + epiTinderWebServer, +}; diff --git a/graphs/js/epiTinderDB/epiTinderDB.js b/graphs/js/epiTinderDB/epiTinderDB.js new file mode 100644 index 0000000..d9f35a8 --- /dev/null +++ b/graphs/js/epiTinderDB/epiTinderDB.js @@ -0,0 +1,204 @@ +const { Sequelize, Op, DataTypes } = require("sequelize"); + +let seq = null; +let userModel = null; + +async function connectToDB() { + if (!seq) { + seq = new Sequelize( + "postgres", + process.env.USERNAME, + process.env.PASSWORD, + { + port: 5432, + dialect: "postgres", + }, + ); + } + + if (!userModel) { + userModel = seq.define( + "epitinder_users", + { + name: { + type: DataTypes.STRING, + }, + age: { + type: DataTypes.INTEGER, + }, + description: { + type: DataTypes.STRING, + }, + }, + { + // Other model options go here + timestamps: false, + }, + ); + } + + return seq; +} + +async function getAllUsers() { + return userModel.findAll({ + attributes: ["id", "name", "age", "description"], + raw: true, + }); +} + +async function getUser(id) { + return userModel + .findOne({ + attributes: ["id", "name", "age", "description"], + where: { id: id }, + raw: true, + }) + .catch(() => { + return null; + }); +} + +async function addUser(newUser) { + if ( + newUser["id"] || + !newUser["name"] || + !newUser["age"] || + !newUser["description"] + ) { + return null; + } + + return userModel + .create({ + name: newUser.name, + age: newUser.age, + description: newUser.description, + }) + .then((usr) => usr.dataValues) + .catch(() => null); +} +async function updateUser(user) { + if ( + !user["id"] || + !user["name"] || + !user["age"] || + !user["description"] || + Object.keys(user).length > 4 + ) { + return null; + } + + const res = await userModel + .findOne({ + where: { id: user.id }, + raw: true, + }) + .catch(() => null); + + if (!res) { + return null; + } + + await userModel + .update( + { + name: user.name, + age: user.age, + description: user.description, + }, + { + where: { id: user.id }, + raw: true, + }, + ) + .catch(() => null); + return user; +} + +async function deleteUser(id) { + let res = await userModel + .findOne({ + where: { id: id }, + raw: true, + }) + .catch(() => null); + + if (!res) { + return null; + } + + res = { + id: res.id, + name: res.name, + age: res.age, + description: res.description, + }; + await userModel.destroy({ where: { id: id } }); + return res; +} + +async function getAllUsersName() { + return userModel + .findAll({ + attributes: ["name"], + raw: true, + }) + .catch(() => { + return null; + }); +} + +async function getAllYoungAdults() { + return userModel + .findAll({ + where: { + age: { + [Op.between]: [18, 29], + }, + }, + raw: true, + }) + .catch(() => { + return null; + }); +} + +module.exports = { + getAllUsers, + getAllUsersName, + getAllYoungAdults, + getUser, + addUser, + deleteUser, + updateUser, + connectToDB, +}; + +async function main() { + await connectToDB(); + //console.log(await getAllUsers()); + //console.log(await getAllUsersName()); + //console.log(await getAllYoungAdults()); + //console.log(await getUser(5)); + /*console.log( + await addUser({ + name: "Martial Simon", + age: 19, + description: "Sex is like pointers, I like it raw", + }), + );*/ + console.log( + await updateUser({ + id: 56, + name: "Mickael Razzouk", + age: 21, + sex_appeal: 100, + description: "Le goat", + }), + ); + //console.log(await getUser(5)); + //console.log(await deleteUser(23)); +} + +main(); diff --git a/graphs/js/epiTinderDB/provided.sql b/graphs/js/epiTinderDB/provided.sql new file mode 100644 index 0000000..81d65da --- /dev/null +++ b/graphs/js/epiTinderDB/provided.sql @@ -0,0 +1,17 @@ +CREATE TABLE epitinder_users (id SERIAL PRIMARY KEY, name VARCHAR(255), age INT, description VARCHAR(255)); + +INSERT INTO epitinder_users (name, age, description) VALUES ('Puff',2, 'I like everyone who does javascript (I m the mascot of the workshop)'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Bubble',1, 'I m the real javascript mascot but don t tell puff he ll cry again'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Maxime Buisson',40, 'I already have my other half but I want to make friends.'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Dorian Penso',25, 'Gym enthusiast by day, code lover by night, seeking a partner to write code and lift weights together.'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Pierre-Alexis Valbrun',32, 'I m a full-stack developer, I can handle both your front-end and back-end.'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Paul Genillon',21, 'It is not compiling since it is a wooclap.'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Botumrath Morchoisne',24, 'What am I doing here ??'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Pierre Santamaria',22, 'I will love you like I love JavaScript, I won t get anything you tell me but it will be passionate.'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Baptiste Schaudel',9, 'I am operational to manage my team, I will let you discover if I am too with love.'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Maxim Payeur',8, 'What am I doing here ??'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Vinh-Toan Phan',17, 'I am an excelent cooker, do you want to be my cookware.'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Angelina Kuntz',44, 'You can call me Ada'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Ewan Lemonnier',19, 'Barely legal'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Anaïs Druelle',21, 'What is the only part of a vegetable you can t eat?'); +INSERT INTO epitinder_users (name, age, description) VALUES ('Mathéo Romé',22, 'I can’t sing but I will charm you anyway');
\ No newline at end of file diff --git a/graphs/js/eslint/fibo.js b/graphs/js/eslint/fibo.js new file mode 100644 index 0000000..9b466e7 --- /dev/null +++ b/graphs/js/eslint/fibo.js @@ -0,0 +1,31 @@ +function fibo(n) { + // I'm a comment + if (typeof n != "number" || isNaN(n)) { + return -1; + } + + if (n < 0) { + return -1; + } + + if (n === 0) { + return 0; + } + + let a = 1; + + let b = 1; + let result = 1; + + for (let i = 2; i < n; i++) { + result = a + b; + b = a; + a = result; + } + + return result; +} + +module.exports = { + fibo, +}; diff --git a/graphs/js/foodTruck/data.js b/graphs/js/foodTruck/data.js new file mode 100644 index 0000000..dab9982 --- /dev/null +++ b/graphs/js/foodTruck/data.js @@ -0,0 +1,70 @@ +"use strict"; + +const stocks = { + mozzarella: 4, + parmesan: 5, + cheddar: 6, + "goat cheese": 7, + meat: 3, + chicken: 4, + salmon: 7, + tuna: 8, + bacon: 4, + mushrooms: 4, + tomato: 5, + "tomato sauce": 5, + "sour cream": 5, + fries: 20, + eggs: 10, + buns: 20, + lettuce: 5, + oregano: 8, +}; + +const recipes = { + pizza: { + Margarita: { + cheese: { + mozzarella: 4, + }, + sauce: "tomato sauce", + toppings: { oregano: 2 }, + }, + "4 cheese": { + cheese: { + mozzarella: 2, + parmesan: 2, + cheddar: 2, + "goat cheese": 2, + }, + toppings: { oregano: 2 }, + sauce: "tomato sauce", + }, + "Creamy 4 cheese": { + cheese: { + mozzarella: 2, + parmesan: 2, + cheddar: 2, + "goat cheese": 2, + }, + toppings: { oregano: 2 }, + sauce: "sour cream", + }, + }, + burger: { + Whoopty: { cheddar: 2, meat: 2, lettuce: 2, tomato: 2, buns: 2 }, + McChicken: { cheddar: 2, chicken: 1, lettuce: 2, buns: 2 }, + }, +}; + +if (typeof window === "undefined") { + module.exports = { + stocks, + recipes, + }; +} else { + if (!globalThis.stocks && !globalThis.recipes) { + globalThis.stocks = stocks; + globalThis.recipes = recipes; + } +} diff --git a/graphs/js/foodTruck/dirtyFoodTruck.js b/graphs/js/foodTruck/dirtyFoodTruck.js new file mode 100644 index 0000000..e0043e1 --- /dev/null +++ b/graphs/js/foodTruck/dirtyFoodTruck.js @@ -0,0 +1,172 @@ +if (typeof window === "undefined") { + if (!globalThis.stocks && !globalThis.recipes) { + const { stocks, recipes } = require("./data"); + + globalThis.stocks = stocks; + globalThis.recipes = recipes; + } +} + +function delivering(recipeName) { + setTimeout(() => { + console.log(`Delivering ${recipeName}`); + }, 2000); +} + +function end_of_order(recipeName) { + console.log("All ingredients have been prepared"); + setTimeout(() => { + console.log(`Cooking ${recipeName}`); + }, 2000); + setTimeout(() => { + delivering(recipeName); + }, 5000); +} + +function check_and_update_ingredient(recipeName, ingredient, quantity) { + if (globalThis.stocks[ingredient] < quantity) { + console.log( + `Not enough ingredients for ${recipeName} because there is no more ${ingredient}`, + ); + return false; + } + + globalThis.stocks[ingredient] -= quantity; + return true; +} + +function check_and_update_ingredients(recipeName, ingredients) { + for (const ingredient in ingredients) { + const quantity = ingredients[ingredient]; + + if (!check_and_update_ingredient(recipeName, ingredient, quantity)) { + return false; + } + } + + return true; +} + +function prepare_pizza(recipeName) { + let i = 0; + const pizza = globalThis.recipes.pizza[recipeName]; + const timeouts = []; + + timeouts.push( + setTimeout(() => { + console.log(`Preparing ${pizza.sauce}`); + if (!check_and_update_ingredient(recipeName, pizza.sauce, 1)) { + for (const t of timeouts) { + clearTimeout(t); + } + + return; + } + }, i), + ); + + timeouts.push( + setTimeout(() => { + i = 1000; + console.log(`Preparing ${Object.keys(pizza.toppings).join(", ")}`); + if (!check_and_update_ingredients(recipeName, pizza.toppings)) { + for (const t of timeouts) { + clearTimeout(t); + } + + return; + } + + setTimeout(() => { + console.log( + `Preparing ${Object.keys(pizza.cheese).join(", ")}`, + ); + if (!check_and_update_ingredients(recipeName, pizza.cheese)) { + for (const t of timeouts) { + clearTimeout(t); + } + + return; + } + }, i); + }, i + 1000), + ); + i += 3000; + timeouts.push( + setTimeout(() => { + end_of_order(recipeName); + }, i), + ); +} + +function prepare_burger(recipeName) { + const burger = globalThis.recipes.burger[recipeName]; + let i = 0; + const timeouts = []; + + for (const ingredient in burger) { + const timeout = setTimeout(() => { + console.log(`Preparing ${ingredient}`); + if ( + !check_and_update_ingredient( + recipeName, + ingredient, + burger[ingredient], + ) + ) { + for (const t of timeouts) { + clearTimeout(t); + } + + return; + } + }, i * 1000); + + timeouts.push(timeout); + i++; + } + + const lastTimeout = setTimeout(() => { + end_of_order(recipeName); + }, i * 1000); + + timeouts.push(lastTimeout); +} + +function order(recipeName) { + let i = 0; + + console.log(`Ordering ${recipeName}`); + + if ( + !(recipeName in globalThis.recipes.pizza) && + !(recipeName in globalThis.recipes.burger) + ) { + console.log(`Recipe ${recipeName} does not exist`); + return; + } + + setTimeout(() => { + i = 1000; + setTimeout(() => { + console.log(`Production has started for ${recipeName}`); + }, i); + }, i + 1000); + i += 3000; + setTimeout(() => { + if (recipeName in globalThis.recipes.pizza) { + prepare_pizza(recipeName); + } + }, i); + setTimeout(() => { + if (recipeName in globalThis.recipes.burger) { + prepare_burger(recipeName); + } + }, i); +} + +if (typeof window === "undefined") { + module.exports = { + order, + }; +} diff --git a/graphs/js/foodTruck/foodTruck.js b/graphs/js/foodTruck/foodTruck.js new file mode 100644 index 0000000..afe14d4 --- /dev/null +++ b/graphs/js/foodTruck/foodTruck.js @@ -0,0 +1,124 @@ +if (typeof window === "undefined") { + if ( + !globalThis.stocks && + !globalThis.recipes && + !globalThis.globalThis.sleep + ) { + const { stocks, recipes } = require("./data"); + const { sleep } = require("./sleep"); + + globalThis.stocks = stocks; + globalThis.recipes = recipes; + globalThis.globalThis.sleep = sleep; + } +} + +if (typeof window === "undefined") { + module.exports = { + order, + }; +} + +/* + * + * Write your code below these lines + * + */ +async function end_of_order(recipeName, wait) { + if (wait) { + await globalThis.sleep(1); + } + + console.log("All ingredients have been prepared"); + await globalThis.sleep(2); + console.log(`Cooking ${recipeName}`); + await globalThis.sleep(5); + console.log(`Delivering ${recipeName}`); + return null; +} +function check_and_update_ingredient(recipeName, ingredient, quantity) { + if (globalThis.stocks[ingredient] < quantity) { + console.log( + `Not enough ingredients for ${recipeName} because there is no more ${ingredient}`, + ); + return false; + } + + globalThis.stocks[ingredient] -= quantity; + return true; +} + +function check_and_update_ingredients(recipeName, ingredients) { + for (const ingredient in ingredients) { + const quantity = ingredients[ingredient]; + + if (!check_and_update_ingredient(recipeName, ingredient, quantity)) { + return false; + } + } + + return true; +} + +async function order(recipeName) { + console.log(`Ordering ${recipeName}`); + + if ( + !(recipeName in globalThis.recipes.pizza) && + !(recipeName in globalThis.recipes.burger) + ) { + console.log(`Recipe ${recipeName} does not exist`); + return; + } + + await globalThis.sleep(2); + console.log(`Production has started for ${recipeName}`); + await globalThis.sleep(1); + if (recipeName in globalThis.recipes.burger) { + const burger = globalThis.recipes.burger[recipeName]; + + for (const ingredient in burger) { + console.log(`Preparing ${ingredient}`); + if ( + !check_and_update_ingredient( + recipeName, + ingredient, + burger[ingredient], + ) + ) { + return; + } + + await globalThis.sleep(1); + } + + return await end_of_order(recipeName, false); + } else if (recipeName in globalThis.recipes.pizza) { + const pizza = globalThis.recipes.pizza[recipeName]; + + console.log(`Preparing ${pizza.sauce}`); + if (!check_and_update_ingredient(recipeName, pizza.sauce, 1)) { + return; + } + + await globalThis.sleep(1); + console.log(`Preparing ${Object.keys(pizza.toppings).join(", ")}`); + if (!check_and_update_ingredients(recipeName, pizza.toppings)) { + return; + } + + await globalThis.sleep(1); + console.log(`Preparing ${Object.keys(pizza.cheese).join(", ")}`); + if (!check_and_update_ingredients(recipeName, pizza.cheese)) { + return; + } + + return await end_of_order(recipeName, true); + } +} + +if (typeof window === "undefined") { + module.exports = { + order, + }; +} diff --git a/graphs/js/foodTruck/index.html b/graphs/js/foodTruck/index.html new file mode 100644 index 0000000..0bbc954 --- /dev/null +++ b/graphs/js/foodTruck/index.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Foodtruck</title> + <link rel="stylesheet" href="static/style.css"> + + +</head> + +<body> + <header> + <h1 id="page-title">FoodTruck</h1> + <p>Choose your order !</p> + <button id="switch-button"> + <a href="#">Switch to Dirty Foodtruck</a> + </button> + </header> + + + <div id="order"> + </div> + + <div id="display"> + </div> + + <footer> + <p>"Being a hero means fighting back even when it seems impossible."</p> + </footer> + +</body> +<script src="static/failedOnload.js"></script> +<script src="data.js" onerror="scriptFailedLoad(this.src)"></script> +<script src="sleep.js" onerror="scriptFailedLoad(this.src)"></script> +<script src="static/index.js"></script> +<script src="foodTruck.js" onerror="scriptFailedLoad(this.src)"></script> + +</html>
\ No newline at end of file diff --git a/graphs/js/foodTruck/sleep.js b/graphs/js/foodTruck/sleep.js new file mode 100644 index 0000000..e4244d9 --- /dev/null +++ b/graphs/js/foodTruck/sleep.js @@ -0,0 +1,11 @@ +function sleep(s) { + return new Promise((resolve) => setTimeout(resolve, s * 1000)); +} + +if (typeof window === "undefined") { + module.exports = { + sleep, + }; +} else { + globalThis.sleep = sleep; +} diff --git a/graphs/js/foodTruck/static/failedOnload.js b/graphs/js/foodTruck/static/failedOnload.js new file mode 100644 index 0000000..cf47073 --- /dev/null +++ b/graphs/js/foodTruck/static/failedOnload.js @@ -0,0 +1,9 @@ +function scriptFailedLoad(src) { + const container = document.getElementById("order"); + const errorDiv = document.createElement("div"); + + errorDiv.id = "errorscript"; + errorDiv.innerHTML = ` + <p><b>Script '${src.split("/").pop()}' does not exist.</b></p>`; + container.appendChild(errorDiv); +} diff --git a/graphs/js/foodTruck/static/index.js b/graphs/js/foodTruck/static/index.js new file mode 100644 index 0000000..6d84098 --- /dev/null +++ b/graphs/js/foodTruck/static/index.js @@ -0,0 +1,78 @@ +function addFood(name) { + const container = document.getElementById("order"); + const foodDiv = document.createElement("div"); + + foodDiv.classList.add("food"); + foodDiv.innerHTML = ` + <p>${name}</p> + <button onclick=" order('${name}')">Order</button>`; + container.appendChild(foodDiv); +} + +function logToDisplay(message, type = "info") { + const displayElement = document.getElementById("display"); + const logMessage = document.createElement("div"); + + logMessage.textContent = message; + logMessage.classList.add("log-message", type); + displayElement.appendChild(logMessage); + + displayElement.scrollTop = displayElement.scrollHeight; + setTimeout(() => { + logMessage.remove(); + }, 5000); +} + +console.log = logToDisplay; + +function loadMenu() { + if (document.getElementById("errorscript") === null) { + Object.keys(recipes).forEach((category) => { + Object.keys(recipes[category]).forEach((recipeName) => { + addFood(recipeName); + }); + }); + } +} + +var isDirtyFoodtruck = false; +var pageTitle = document.getElementById("page-title"); +var switchButton = document.getElementById("switch-button"); + +function loadScript(isDirty) { + var scriptContainer = document.body; + var currentScripts = [...scriptContainer.querySelectorAll("script")].filter( + (script) => { + var name_script = script.src.split("/").pop(); + + return /(dirty)?foodtruck\.js/i.test(name_script); + }, + ); + + // currentScripts should return only one value + scriptToLoad = isDirty ? "dirtyFoodTruck.js" : "foodTruck.js"; + document.body.removeChild(currentScripts[0]); + + const script = document.createElement("script"); + + script.src = scriptToLoad; + + script.onerror = () => scriptFailedLoad(scriptToLoad); + script.onload = () => loadMenu(); + document.body.appendChild(script); +} + +switchButton.addEventListener("click", () => { + isDirtyFoodtruck = !isDirtyFoodtruck; + pageTitle.textContent = isDirtyFoodtruck ? "Dirty Foodtruck" : "Foodtruck"; + switchButton.querySelector("a").textContent = isDirtyFoodtruck + ? "Switch to Foodtruck" + : "Switch to Dirty Foodtruck"; + var orderDiv = document.getElementById("order"); + + orderDiv.innerHTML = ""; + + loadScript(isDirtyFoodtruck); +}); + +loadMenu(); diff --git a/graphs/js/foodTruck/static/style.css b/graphs/js/foodTruck/static/style.css new file mode 100644 index 0000000..c094d98 --- /dev/null +++ b/graphs/js/foodTruck/static/style.css @@ -0,0 +1,200 @@ +:root { + --main-color: #21344a; + --background-color: #333; + --own-white: #FDF0E7; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: Arial, sans-serif; + +} + +body { + background-color: var(--background-color); + color: #333; + font-size: 16px; + line-height: 1.5; + display: flex; + flex-direction: column; + min-height: 100vh; + margin: 0; +} + +header { + background-color: var(--main-color); + color: var(--own-white); + text-align: center; + flex-shrink: 0; + padding: 20px 0; + position: relative; +} + +header h1 { + font-size: 50px; + margin-bottom: 5px; +} + +header p { + font-size: 20px; +} + +header button { + position: absolute; + right: 20px; + top: 50%; + transform: translateY(-50%); + background-color: var(--own-white); + color: var(--main-color); + padding: 10px 15px; + font-size: 1rem; + font-weight: bold; + border-radius: 10px; + border-style: solid; + border-color: #000; + border-width: 1px; + cursor: pointer; + transition: background-color 0.3s, color 0.3s; + text-decoration: none; +} + +header button:hover { + background-color: #f5f5f5; + color: var(--main-color); +} + +header button a { + text-decoration: none; + color: inherit; +} + +#order { + flex-shrink: 0; + margin: 0; + + display: flex; + flex-wrap: wrap; + gap: 20px; + padding: 30px; + margin-top: 20px; + justify-content: space-between; +} + +.food { + background-color: var(--own-white); + padding: 15px; + border-radius: 8px; + text-align: center; + flex: 1 1 calc(25% - 20px); + box-sizing: border-box; +} + +.food p { + font-size: 20px; + margin-bottom: 10px; +} + +.food button { + background-color: var(--main-color); + color: white; + border: none; + padding: 10px; + font-size: 16px; + border-radius: 5px; + cursor: pointer; + width: 100%; + transition: background-color 0.3s; +} + +.food button:hover { + background-color: #972615; +} + +#display { + flex-grow: 1; + overflow-y: auto; + background-color: var(--background-color); + color: white; + padding: 10px; + font-family: monospace; + white-space: pre-wrap; + box-sizing: border-box; + height: 0; + max-height: calc(100vh - 200px); + overflow-y: scroll; +} + +.log-message { + padding: 5px; + border-radius: 5px; + animation: fadeOut 5s forwards; + overflow-y: hidden; + justify-content: center; + text-align: center; + align-items: center; +} + +.log-message.info { + color: var(--own-white); + font-size: 20px; +} + +.log-message.error { + color: #f44336; +} + +.log-message.warn { + color: #ffc107; +} + +@keyframes fadeOut { + 0% { + opacity: 1; + } + + 80% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +#errorscript { + color: red; + font-size: 30px; + font-weight: bold; + text-align: center; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + background-color: rgba(255, 255, 255, 0.8); + box-sizing: border-box; + border-radius: 15px; + padding: 20px; +} + +footer img { + size: 15px; +} + +footer { + flex-shrink: 0; + background-color: var(--main-color); + color: white; + text-align: center; + padding: 20px; + display: flex; + justify-content: center; + align-items: center; + gap: 20px; +} + +footer p { + font-size: 20px; +}
\ No newline at end of file diff --git a/graphs/js/gallery/gallery.js b/graphs/js/gallery/gallery.js new file mode 100644 index 0000000..8446846 --- /dev/null +++ b/graphs/js/gallery/gallery.js @@ -0,0 +1,54 @@ +const fs = require("fs"); +const path = require("path"); + +function extract(directoryPath) { + const mail = new RegExp( + "([a-z0-9_.+-]+)@([a-z0-9.-]+)\\.(([a-zA-Z0-9]|\\.){2,})", + "g", + ); + + try { + let emails = []; + const dirs = fs.readdirSync(directoryPath, { withFileTypes: true }); + + for (const dir of dirs) { + if (dir.isFile()) { + const data = fs.readFileSync( + path.join(directoryPath, dir.name), + "utf8", + ); + const matches = data.match(mail); + + if (matches) { + emails = [...emails, ...matches]; + } + } else if (dir.isDirectory()) { + emails = [ + ...emails, + ...extract(path.join(directoryPath, dir.name)), + ]; + } + } + + return emails; + } catch { + throw new Error("The directory does not exist"); + } +} + +/* + +fzhfeklzjfh@dakljhlzekj.f +fkzjefh@aaa0.fr +dejkzd@djkelh.fr +djhezklf0587dzedez@gmail................ +xavier.login@epita.fr +xavier.login@epita.fR + +*/ + +module.exports = { + extract, +}; + +console.log(extract("gallery")); diff --git a/graphs/js/helloWorld/helloWorld.js b/graphs/js/helloWorld/helloWorld.js new file mode 100644 index 0000000..3564ffc --- /dev/null +++ b/graphs/js/helloWorld/helloWorld.js @@ -0,0 +1,7 @@ +function helloWorld() +{ + console.log("Hello World!") +} +module.exports = { + helloWorld, +};
\ No newline at end of file diff --git a/graphs/js/inspectAndFuse/inspectAndFuse.js b/graphs/js/inspectAndFuse/inspectAndFuse.js new file mode 100644 index 0000000..2072bb1 --- /dev/null +++ b/graphs/js/inspectAndFuse/inspectAndFuse.js @@ -0,0 +1,77 @@ +function getNumberFields(inputObject) { + if (inputObject == null) { + return new Array(); + } + + const res = new Array(); + + for (const prop in inputObject) { + if (typeof inputObject[prop] === "number") { + res.push(prop); + } + } + + return res; +} +function incrementCounters(inputObject) { + const reg = /counter/i; + const fields = getNumberFields(inputObject); + + if (fields == null) { + return; + } + + fields.forEach((f) => { + if (f.match(reg)) { + inputObject[f]++; + } + }); +} +function deleteUppercaseProperties(inputObject) { + if (inputObject == null) { + return; + } + + const reg = /[a-z]/; + + for (const prop in inputObject) { + if (!prop.match(reg)) { + delete inputObject[prop]; + } else if (inputObject[prop] instanceof Object) { + deleteUppercaseProperties(inputObject[prop]); + } + } +} +function fusion(...objs) { + const res = {}; + + for (const obj of objs) { + for (const prop in obj) { + if (!Object.hasOwn(res, prop)) { + res[prop] = obj[prop]; + } else { + if ( + typeof res[prop] != typeof obj[prop] || + typeof res[prop] === "boolean" + ) { + res[prop] = obj[prop]; + } else if (obj[prop] instanceof Array) { + res[prop] = [...res[prop], ...obj[prop]]; + } else if (typeof prop === "object") { + res[prop] = fusion(res[prop], obj[prop]); + } else { + res[prop] += obj[prop]; + } + } + } + } + + return res; +} + +module.exports = { + fusion, + incrementCounters, + deleteUppercaseProperties, + getNumberFields, +}; diff --git a/graphs/js/intergalactic/destinations.js b/graphs/js/intergalactic/destinations.js new file mode 100644 index 0000000..c184458 --- /dev/null +++ b/graphs/js/intergalactic/destinations.js @@ -0,0 +1,47 @@ +function displayDestinations(destinations) { + if ( + !(destinations instanceof Map) || + destinations == null || + destinations == undefined || + destinations.size === 0 + ) { + console.log("No destination is available."); + } else { + destinations.forEach((v, k) => { + console.log(k + ": " + v); + }); + } +} +function addDestination(destinations, name, cost) { + if ( + typeof name != "string" || + typeof cost != "number" || + cost < 0 || + destinations.has(name) + ) { + return false; + } + + destinations.set(name, cost); + return true; +} +function removeDestination(destinations, name) { + if (typeof name != "string" || !destinations.has(name)) { + return false; + } else { + destinations.delete(name); + return true; + } +} +function getDestinationsInOrder(destinations) { + const res = new Array(); + + destinations.forEach((v, k) => res.push([v, k])); + return res.sort((vkp1, vkp2) => vkp1[0] - vkp2[0]).map((vkp) => vkp[1]); +} +module.exports = { + displayDestinations, + addDestination, + removeDestination, + getDestinationsInOrder, +}; diff --git a/graphs/js/intergalactic/travelers.js b/graphs/js/intergalactic/travelers.js new file mode 100644 index 0000000..b806883 --- /dev/null +++ b/graphs/js/intergalactic/travelers.js @@ -0,0 +1,40 @@ +function addTraveler(travelers, firstname, lastname) { + const vip = /(.*[jJ].*[sS].*)|(.*[sS].*[jJ].*)/; + const fullname = firstname + " " + lastname; + + if (travelers.length >= 8) { + console.log(fullname); + if (vip.test(fullname)) { + const last_i = travelers.findLastIndex( + (element) => !vip.test(element), + ); + + if (last_i === -1) { + return false; + } + + travelers.splice(last_i, 1); + } else { + return false; + } + } + + travelers.push(fullname); + return true; +} +function deleteTraveler(travelers, firstname, lastname) { + const fullname = firstname + " " + lastname; + const i = travelers.indexOf(fullname); + + if (i === -1) { + return false; + } + + travelers.splice(i, 1); + return true; +} + +module.exports = { + addTraveler, + deleteTraveler, +}; diff --git a/graphs/js/jestBasic/fibo.js b/graphs/js/jestBasic/fibo.js new file mode 100644 index 0000000..0a19955 --- /dev/null +++ b/graphs/js/jestBasic/fibo.js @@ -0,0 +1,29 @@ +function fibo(n) { + if (typeof n != "number" || isNaN(n)) { + return -1; + } + + if (n < 0) { + return -1; + } + + if (n === 0) { + return 0; + } + + let a = 1; + let b = 1; + let result = 1; + + for (let i = 2; i < n; i++) { + result = a + b; + b = a; + a = result; + } + + return result; +} + +module.exports = { + fibo, +}; diff --git a/graphs/js/jestBasic/fibo.test.js b/graphs/js/jestBasic/fibo.test.js new file mode 100644 index 0000000..6a97365 --- /dev/null +++ b/graphs/js/jestBasic/fibo.test.js @@ -0,0 +1,37 @@ +const { fibo } = require("./fibo"); + +describe("basic value", () => { + test("fibo of 0", () => { + expect(fibo(0)).toBe(0); + }); + test("fibo of 1", () => { + expect(fibo(1)).toBe(1); + }); + test("fibo of 2", () => { + expect(fibo(2)).toBe(1); + }); + test("fibo of 4", () => { + expect(fibo(4)).toBe(3); + }); + test("fibo of 19", () => { + expect(fibo(19)).toBe(4181); + }); +}); + +describe("errors", () => { + test("fibo of -1", () => { + expect(fibo(-1)).toBe(-1); + }); + test("fibo of null", () => { + expect(fibo(null)).toBe(-1); + }); + test("fibo of undefined", () => { + expect(fibo(undefined)).toBe(-1); + }); + test("fibo of a string", () => { + expect(fibo("uwu adrien")).toBe(-1); + }); + test("fibo of NaN", () => { + expect(fibo(NaN)).toBe(-1); + }); +}); diff --git a/graphs/js/logMeIn/logMeIn.js b/graphs/js/logMeIn/logMeIn.js new file mode 100644 index 0000000..2591071 --- /dev/null +++ b/graphs/js/logMeIn/logMeIn.js @@ -0,0 +1,59 @@ +const express = require("express"); +const jsonwebtoken = require("jsonwebtoken"); + +function logMeIn(host, port) { + const secretKey = process.env.JWT_SECRET_KEY; + const app = express(); + + app.use(express.json()); + + app.get("/", (req, res) => { + res.status(200).send({ message: "Hello World!" }); + }); + app.post("/login", (req, res) => { + const login = req.body.username; + const passwd = req.body.password; + + if (login !== "xavier.login" || passwd != "1234") { + res.status(401).send({ error: "Invalid username or password" }); + } else { + const jwt = jsonwebtoken.sign(req.body, secretKey); + + res.status(200).send({ jwt: jwt }); + } + }); + app.get("/secret", (req, res) => { + if (req.headers == null || req.headers == undefined) { + res.status(401).send({ error: "Unauthorized" }); + return; + } + + try { + const decoded = jsonwebtoken.verify( + req.headers.authorization.split(" ")[1], + secretKey, + ); + + if ( + decoded.username !== "xavier.login" || + decoded.password !== "1234" + ) { + res.status(401).send({ error: "Unauthorized" }); + } + + res.status(200).send({ message: "Access granted" }); + } catch { + res.status(401).send({ error: "Unauthorized" }); + } + }); + + return app.listen(port, () => { + console.log("Server running at http://" + host + ":" + port + "/"); + }); +} + +module.exports = { + logMeIn, +}; + +//logMeIn("127.0.0.1", 3000); diff --git a/graphs/js/modularLogger/modularLogger.js b/graphs/js/modularLogger/modularLogger.js new file mode 100644 index 0000000..b22b23c --- /dev/null +++ b/graphs/js/modularLogger/modularLogger.js @@ -0,0 +1,76 @@ +function makeLog(date, nameLogLevel, message) { + return ( + "[" + + date.toLocaleString("fr-FR", { timeStyle: "medium" }) + + "][" + + nameLogLevel + + "] - " + + message + ); +} +function loggerFactory() { + const logs = []; + + return (level = 1000) => { + if (level === 1000) { + return (date, nameLogLevel, message) => { + if ( + !["DEBUG", "INFO", "WARN", "ERROR"].includes(nameLogLevel) + ) { + console.log( + nameLogLevel + + " is an invalid log level. Please use one of the following: DEBUG, INFO, WARN, ERROR.", + ); + } else { + logs.push({ + date: date, + nameLogLevel: nameLogLevel, + message: message, + }); + } + }; + } else if (typeof level !== "number" || level < 0) { + console.log("Bad argument."); + } else { + if (level > 3) { + level = 3; + } + + for (const log of logs) { + const print = makeLog( + log["date"], + log["nameLogLevel"], + log["message"], + ); + + switch (log["nameLogLevel"]) { + case "ERROR": + console.log(print); + break; + case "WARN": + if (level > 0) { + console.log(print); + } + + break; + case "INFO": + if (level > 1) { + console.log(print); + } + + break; + case "DEBUG": + if (level > 2) { + console.log(print); + } + + break; + } + } + } + }; +} + +module.exports = { + loggerFactory, +}; diff --git a/graphs/js/myCompany/boss.js b/graphs/js/myCompany/boss.js new file mode 100644 index 0000000..eadf09c --- /dev/null +++ b/graphs/js/myCompany/boss.js @@ -0,0 +1,30 @@ +const { Employee } = require("./employee"); + +class Boss extends Employee { + constructor(name, accreditationLevel) { + super(name); + this.accreditationLevel = accreditationLevel; + } + getAccreditation() { + return this.accreditationLevel; + } + fire(target) { + if (!(target instanceof Employee)) { + console.log("I cannot fire that!"); + return false; + } else if ( + !(target instanceof Boss) || + target.getAccreditation() < this.accreditationLevel + ) { + console.log(target.getName() + " you are fired!"); + return true; + } else { + console.log("I cannot fire someone superior to me!"); + return false; + } + } +} + +module.exports = { + Boss, +}; diff --git a/graphs/js/myCompany/company.js b/graphs/js/myCompany/company.js new file mode 100644 index 0000000..fd800e7 --- /dev/null +++ b/graphs/js/myCompany/company.js @@ -0,0 +1,77 @@ +const { Boss } = require("./boss"); +const { Employee } = require("./employee"); + +class Company { + constructor(name) { + this.name = name; + this.employees = new Array(); + } + getName() { + return this.name; + } + getEmployees() { + return this.employees; + } + getNumberOfEmployees() { + return this.employees.filter((e) => e instanceof Employee).length; + } + getNumberOfBosses() { + return this.employees.filter((e) => e instanceof Boss).length; + } + addEmployee(target) { + if (!(target instanceof Employee)) { + return; + } + + this.employees.push(target); + } + promoteEmployee(targetIndex) { + if (this.employees[targetIndex] instanceof Boss) { + this.employees[targetIndex].accreditationLevel++; + console.log( + "Boss " + + this.employees[targetIndex].getName() + + " is promoted, his level of accreditation is now " + + this.employees[targetIndex].getAccreditation(), + ); + } else { + this.employees.splice( + targetIndex, + 1, + new Boss(this.employees[targetIndex].getName(), 1), + ); + console.log( + "Employee " + + this.employees[targetIndex].getName() + + " is promoted to boss post", + ); + } + } + fireEmployee(bossIndex, targetIndex) { + if (this.employees[bossIndex].fire(this.employees[targetIndex])) { + if (this.employees[targetIndex] instanceof Boss) { + console.log( + "Boss " + + this.employees[targetIndex].getName() + + " is no longer in " + + this.name + + " company", + ); + } else { + console.log( + "Employee " + + this.employees[targetIndex].getName() + + " is no longer in " + + this.name + + " company", + ); + } + + this.employees.splice(targetIndex, 1); + } + } +} + +module.exports = { + Company, +}; diff --git a/graphs/js/myCompany/employee.js b/graphs/js/myCompany/employee.js new file mode 100644 index 0000000..5489dd7 --- /dev/null +++ b/graphs/js/myCompany/employee.js @@ -0,0 +1,21 @@ +class Employee { + constructor(name) { + this.name = name; + } + getName() { + return this.name; + } + fire(target) { + if (target instanceof Employee) { + console.log("I am an employee, I cannot fire someone!"); + } else { + console.log("I cannot fire that!"); + } + + return false; + } +} + +module.exports = { + Employee, +}; diff --git a/graphs/js/notSoFast/articles.json b/graphs/js/notSoFast/articles.json new file mode 100644 index 0000000..5ffb5fb --- /dev/null +++ b/graphs/js/notSoFast/articles.json @@ -0,0 +1,74 @@ +[ + { + "id":0, + "name": "Cheeseburger", + "description": "Beef patty, melted cheese, ketchup, mustard, pickles", + "price": 4.99, + "customer_note": 4.5, + "stocks": 20 + }, + { + "id":1, + "name": "Fries", + "description": "Crispy, golden-brown potato sticks", + "price": 2.49, + "customer_note": 4.0, + "stocks": 50 + }, + { + "id":2, + "name": "Hot Dog", + "description": "Grilled all-beef frankfurter, topped with ketchup, mustard, and relish", + "price": 3.99, + "customer_note": 3.5, + "stocks": 15 + }, + { + "id":3, + "name": "Chicken Nuggets", + "description": "Crispy breaded chicken bites, perfect for dipping", + "price": 5.99, + "customer_note": 4.2, + "stocks": 30 + }, + { + "id":4, + "name": "Milkshake", + "description": "Thick and creamy vanilla milkshake, made with real ice cream", + "price": 3.49, + "customer_note": 4.8, + "stocks": 10 + }, + { + "id":5, + "name": "BBQ Bacon Burger", + "description": "Beef patty, bacon, cheddar cheese, onion rings, BBQ sauce", + "price": 7.99, + "customer_note": 4.3, + "stocks": 5 + }, + { + "id":6, + "name": "Onion Rings", + "description": "Crispy fried onion rings, perfect as a side", + "price": 2.99, + "customer_note": 4.0, + "stocks": 40 + }, + { + "id":7, + "name": "Chicken Sandwich", + "description": "Grilled chicken breast, lettuce, tomato, mayo", + "price": 6.49, + "customer_note": 3.8, + "stocks": 25 + }, + { + "id":8, + "name": "Spicy Chicken Nuggets", + "description": "Crispy breaded chicken bites with a spicy kick", + "price": 6.99, + "customer_note": 4.5, + "stocks": 15 + } +]
\ No newline at end of file diff --git a/graphs/js/notSoFast/notSoFast.js b/graphs/js/notSoFast/notSoFast.js new file mode 100644 index 0000000..113c8f6 --- /dev/null +++ b/graphs/js/notSoFast/notSoFast.js @@ -0,0 +1,33 @@ +const axios = require("axios"); + +async function notSoFast(host, port) { + let nbArticles = await axios.get(`http://${host}:${port}/articles`); + + nbArticles = nbArticles.data.message; + + const articles = []; + + if (0 + nbArticles === 0) { + return articles; + } + + let res = await axios.get(`http://${host}:${port}/articles/${0}`); + + articles.push(res.data); + for (let i = 1; i < 0 + nbArticles; i++) { + const delay = res.headers["x-ratelimit-reset"] * 1000 - Date.now(); + + if (res.headers["x-ratelimit-remaining"] == 0) { + await new Promise((oof) => setTimeout(oof, delay + 26)); + } + + res = await axios.get(`http://${host}:${port}/articles/${i}`); + articles.push(res.data); + } + + return articles; +} + +module.exports = { + notSoFast, +}; diff --git a/graphs/js/notSoFast/server.js b/graphs/js/notSoFast/server.js new file mode 100644 index 0000000..916c7d8 --- /dev/null +++ b/graphs/js/notSoFast/server.js @@ -0,0 +1,147 @@ +const _0x56061b = _0x4a1f; + +(function (_0x3d4f7d, _0x384467) { + const _0x2bc30d = _0x4a1f, + _0x2a57c0 = _0x3d4f7d(); + + while ([]) { + try { + const _0x509389 = + parseInt(_0x2bc30d(0xf9)) / 0x1 + + (-parseInt(_0x2bc30d(0xf8)) / 0x2) * + (parseInt(_0x2bc30d(0xf3)) / 0x3) + + parseInt(_0x2bc30d(0x100)) / 0x4 + + -parseInt(_0x2bc30d(0xef)) / 0x5 + + parseInt(_0x2bc30d(0xeb)) / 0x6 + + parseInt(_0x2bc30d(0xee)) / 0x7 + + (-parseInt(_0x2bc30d(0xe3)) / 0x8) * + (-parseInt(_0x2bc30d(0xf4)) / 0x9); + + if (_0x509389 === _0x384467) { + break; + } else { + _0x2a57c0["push"](_0x2a57c0["shift"]()); + } + } catch (_0x4f4837) { + _0x2a57c0["push"](_0x2a57c0["shift"]()); + } + } +})(_0x5ba1, 0x37cc5); +const express = require(_0x56061b(0xfa)), + app = express(), + path = require("path"); +const articles_data = require( + path[_0x56061b(0xfd)](__dirname, _0x56061b(0xf7)), + ), + rateLimiter = { + max: 0x5, + windowMs: 0x3e8, + reset: Date[_0x56061b(0xe7)]() - 0x7d0, + remaining: 0x5, + }; + +function _0x4a1f(_0xa5c9f4, _0x34d88a) { + const _0x5ba126 = _0x5ba1(); + + return ( + (_0x4a1f = function (_0x4a1f4f, _0x57de0b) { + _0x4a1f4f = _0x4a1f4f - 0xe1; + const _0x91c04c = _0x5ba126[_0x4a1f4f]; + + return _0x91c04c; + }), + _0x4a1f(_0xa5c9f4, _0x34d88a) + ); +} +function _0x5ba1() { + const _0x15e55c = [ + "remaining", + "/articles", + "X-RateLimit-Reset", + "now", + "X-RateLimit-Remaining", + "\x20has\x20been\x20found", + "end", + "1185066KdUuVR", + "listen", + "send", + "1849449xJgCmq", + "1269280gTNiiN", + "get", + "reset", + "/articles/:id([0-9]+)", + "111uXMghV", + "72891SGOhSD", + "Too\x20many\x20requests", + "Server\x20running\x20at\x20http://localhost:", + "./articles.json", + "11996YaeIzr", + "64830rqNiDl", + "express", + "status", + "find", + "resolve", + "No\x20article\x20with\x20id\x20", + "max", + "678736fMeEWy", + "X-RateLimit-Limit", + "params", + "log", + "set", + "8YaqgyJ", + ]; + + _0x5ba1 = function () { + return _0x15e55c; + }; + return _0x5ba1(); +} +app[_0x56061b(0xf0)](_0x56061b(0xe5), (_0x53adb0, _0x2f6c36) => { + const _0x2e7227 = _0x56061b; + + _0x2f6c36[_0x2e7227(0xfb)](0xc8)[_0x2e7227(0xed)]({ + message: articles_data["length"], + }); +}), + app["get"](_0x56061b(0xf2), (_0x58952c, _0x1c1b41) => { + const _0x1800af = _0x56061b; + + rateLimiter[_0x1800af(0xf1)] < Date[_0x1800af(0xe7)]() && + ((rateLimiter["remaining"] = rateLimiter["max"]), + (rateLimiter["reset"] = Date["now"]() + rateLimiter["windowMs"])); + if (rateLimiter[_0x1800af(0xe4)] == 0x0) { + _0x1c1b41[_0x1800af(0xfb)](0x1ad)["send"](_0x1800af(0xf5)); + return; + } else { + rateLimiter[_0x1800af(0xe4)]--; + } + + const _0xca1069 = rateLimiter[_0x1800af(0xff)], + _0x5c15a1 = rateLimiter[_0x1800af(0xe4)], + _0x5d6b61 = parseFloat(rateLimiter[_0x1800af(0xf1)] / 0x3e8); + + _0x1c1b41[_0x1800af(0xe2)](_0x1800af(0x101), _0xca1069), + _0x1c1b41[_0x1800af(0xe2)](_0x1800af(0xe8), _0x5c15a1), + _0x1c1b41[_0x1800af(0xe2)](_0x1800af(0xe6), _0x5d6b61); + const _0x413373 = articles_data[_0x1800af(0xfc)]( + (_0x4868bf) => + _0x4868bf["id"] === parseInt(_0x58952c[_0x1800af(0x102)]["id"]), + ); + + if (_0x413373) { + _0x1c1b41["status"](0xc8)["send"](_0x413373); + return; + } else { + _0x1c1b41["writeHead"]( + 0x194, + _0x1800af(0xfe) + + _0x58952c[_0x1800af(0x102)]["id"] + + _0x1800af(0xe9), + ); + } + + _0x1c1b41[_0x1800af(0xea)](); + }); +const server = app[_0x56061b(0xec)](0xbb8, () => {}); + +console[_0x56061b(0xe1)](_0x56061b(0xf6) + 0xbb8 + "/"); diff --git a/graphs/js/oidc/complete/epita/index.html b/graphs/js/oidc/complete/epita/index.html new file mode 100644 index 0000000..2706a33 --- /dev/null +++ b/graphs/js/oidc/complete/epita/index.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <script defer src="./index.js" type="module"></script> + <link rel="stylesheet" href="../../style.css"> + </head> + <body> + <div class="card-container"> + <div class="img-container"> + <img class="round" id="image"src="https://cri.epita.fr/photos/square/puff" alt="user" width="225" height="225"/> + </div> + <h1 id="name">Puff Puff</h1> + <h3 id="campus">Marseille</h3> + <p id ="grad-year">2059</p> + + <div class="info-container"> + <div class="infos"> + <h3>infos</h3> + <ul id="list"> + </ul> + </div> + </div> + <div class="buttons"> + <button class="primary" id="RequestBtn"> + Request Infos + </button> + <button class="primary ghost" id="EndBtn"> + End Session + </button> + </div> + </div> + </body> +</html> diff --git a/graphs/js/oidc/complete/epita/index.js b/graphs/js/oidc/complete/epita/index.js new file mode 100644 index 0000000..513197c --- /dev/null +++ b/graphs/js/oidc/complete/epita/index.js @@ -0,0 +1,40 @@ +window.END_SESSION_URL = "https://cri.epita.fr/end-session"; +const reqInfosBtn = document.getElementById("RequestBtn"); +const params = new URLSearchParams(window.location.search); +const code = params.get("code"); + +let form = new FormData(); + +form.append("client_id", "assistants-atelier-js"); +form.append("redirect_uri", "http://localhost:8080/complete/epita/"); +form.append("grant_type", "authorization_code"); +form.append("code", code); +const tokenEndpoint = "http://localhost:8080/auth-api"; +reqInfosBtn.addEventListener("click", async () => { + let response = await fetch(tokenEndpoint, { + method: "POST", + body: form, + }); + const responsePretty = await response.json(); + const token = responsePretty.id_token; + const content = token.split(".")[1]; + const b64 = content.replace(/-/g, "+").replace(/_/g, "/"); + const payload = JSON.parse(window.atob(b64)); + + document.getElementById("name").innerHTML = payload.name; + document.getElementById("campus").innerHTML = payload.zoneinfo; + document.getElementById("grad-year").innerHTML = payload.graduation_years; + document + .getElementById("image") + .setAttribute("src", payload.picture_square); + const ul = document.getElementById("list"); + for (const group of payload.groups) { + const item = document.createElement("li"); + item.innerHTML = group.slug + " " + group.name; + ul.appendChild(item); + } +}); + +document + .getElementById("EndBtn") + .addEventListener("click", () => window.location.replace(END_SESSION_URL)); diff --git a/graphs/js/oidc/main.html b/graphs/js/oidc/main.html new file mode 100644 index 0000000..698eb6d --- /dev/null +++ b/graphs/js/oidc/main.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <link rel="stylesheet" href="./style.css"> + <script defer src="./redirect.js"></script> + </head> + <body> + + <div class="card-container"> + <div class="img-container"> + <img class="round" src="https://cri.epita.fr/photos/square/puff" alt="user" width="225" height="225"/> + </div> + <h1>User Application</h1> + <h3>app</h3> + <p>Small application to display user informations<br/> Using ForgeID for Auth</p> + + <div class="buttons"> + <button class="primary" id="redirectBtn"> + Sign-In + </button> + </div> + </div> + </body> +</html> + diff --git a/graphs/js/oidc/redirect.js b/graphs/js/oidc/redirect.js new file mode 100644 index 0000000..d063df3 --- /dev/null +++ b/graphs/js/oidc/redirect.js @@ -0,0 +1,17 @@ +const redirectBtn = document.getElementById("redirectBtn"); + +const authQueryParams = { + client_id: "assistants-atelier-js", + scope: "epita profile picture", + redirect_uri: "http://localhost:8080/complete/epita/", + response_type: "code", +}; + +const authEndpoint = "https://cri.epita.fr/authorize"; +window.LOGIN_URL = new URL( + `?client_id=${authQueryParams.client_id}&scope=${authQueryParams.scope}&redirect_uri=${authQueryParams.redirect_uri}&response_type=${authQueryParams.response_type}`, + authEndpoint, +); +redirectBtn.addEventListener("click", () => { + window.location.replace(window.LOGIN_URL); +}); diff --git a/graphs/js/oidc/server.js b/graphs/js/oidc/server.js new file mode 100644 index 0000000..401b48f --- /dev/null +++ b/graphs/js/oidc/server.js @@ -0,0 +1,33 @@ +const express = require("express"); +const { createProxyMiddleware } = require("http-proxy-middleware"); + +const app = express(); + +/** + * The requests sent to our local server running on http://localhost:8080 + * will pass by the reverse proxy and be sent to a specified path. + * + * In our case, + * /auth-api -> https://cri.epita.fr/token + **/ + +const path = `https://cri.epita.fr/token`; +const proxyAuth = createProxyMiddleware("/auth-api", { + target: path, + changeOrigin: true, + pathRewrite: { + "^/auth-api": "", + }, +}); + +app.get("/", (req, res) => { + res.sendFile("main.html", { root: "./" }); +}); + +app.use(proxyAuth, express.static("./")); + +const port = 8080; + +app.listen(port, () => { + console.log(`Server is running at http://localhost:${port}`); +}); diff --git a/graphs/js/oidc/style.css b/graphs/js/oidc/style.css new file mode 100644 index 0000000..0433246 --- /dev/null +++ b/graphs/js/oidc/style.css @@ -0,0 +1,116 @@ +@import url('https://fonts.googleapis.com/css?family=Montserrat'); + +* { + box-sizing: border-box; +} + +body { + background-color: whitesmoke; + font-family: Montserrat, sans-serif; + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; +} + +h1 { + margin: 10px 0; + color: white; + word-break: break-all; +} + +h3 { + margin: 5px 0; + text-transform: uppercase; + color: white; + word-break: break-all; +} + +p { + font-size: 16px; + line-height: 21px; + color: white; + word-break: break-all; +} + +.card-container { + background: linear-gradient(180deg, rgba(8,4,78,1) 0%, rgba(9,9,121,1) 51%, rgba(0,155,255,1) 100%); + box-shadow: 0px 20px 40px -10px rgba(0,0,0,0.75); + padding-top: 30px; + width: 600px; + height: auto; + max-width: 100%; + text-align: center; + display: flex; + flex-direction: column; + justify-content: center; + border-radius: 25px; +} + +.img-container { + display: flex; + width: 100%; + align-items: center; + justify-content: center; + margin-bottom: 6em; +} + +.round { + border: 3px solid whitesmoke; + border-radius: 50%; + padding: 2px; +} + +.buttons { + margin-top: 2em; +} + +button { + margin-bottom: 10px; +} + +button.primary { + background-color: whitesmoke; + border: 1px solid black; + border-radius: 3px; + color: #231E39; + font-family: Montserrat, sans-serif; + font-weight: 500; + padding: 10px 25px; +} + +button.primary.ghost { + background-color: transparent; + color: black; +} + +.info-container { + display: flex; + justify-content: center; +} + +.infos { + background-color: #0a0a8a; + border-radius: 10px; + text-align: left; + padding: 15px; + margin-top: 30px; + width: 80%; + margin-bottom: 15px; +} + +.infos ul { + list-style-type: none; + margin: 0; + padding: 0; +} + +.infos ul li { + border: 2px solid whitesmoke; + border-radius: 5px; + color: white; + display: inline-block; + font-size: 14px; + margin: 0 7px 7px 0; + padding: 7px; +}
\ No newline at end of file diff --git a/graphs/js/replace/replace.js b/graphs/js/replace/replace.js new file mode 100644 index 0000000..24b79e4 --- /dev/null +++ b/graphs/js/replace/replace.js @@ -0,0 +1,8 @@ +function replace(str) { + const captureDateRegex = new RegExp("(\\d{2})/(\\d{2})/(\\d{4})", "g"); + + return str.replaceAll(captureDateRegex, "$3-$1-$2"); +} +module.exports = { + replace, +}; diff --git a/graphs/js/storageWars/index.html b/graphs/js/storageWars/index.html new file mode 100644 index 0000000..49fad63 --- /dev/null +++ b/graphs/js/storageWars/index.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <script defer src="storageWars.js"></script> + <title>Storage Wars</title> +</head> +<body style="max-width: fit-content; margin-left: auto; margin-right: auto;"> + <div> + <input type="text" id="inputJWT"> + <button id="addToken" onclick="addToken()">Add JWT</button> + </div> + <div id="userInfo" style="display: none;"> + <h1>User Info</h1> + <p>Name: <span id="name"></span></p> + <p>Email: <span id="email"></span></p> + <p>Age: <span id="age"></span></p> + </div> + <div id="error"></div> +</body> +</html> diff --git a/graphs/js/storageWars/storageWars.js b/graphs/js/storageWars/storageWars.js new file mode 100644 index 0000000..ed90536 --- /dev/null +++ b/graphs/js/storageWars/storageWars.js @@ -0,0 +1,80 @@ +/* FIXME */ +const userInfo = document.getElementById("userInfo"); +const userName = document.getElementById("name"); +const userEmail = document.getElementById("email"); +const userAge = document.getElementById("age"); +const errorBox = document.getElementById("error"); +const jwtField = document.getElementById("inputJWT"); + +localStorage.clear(); + +function displayError() { + errorBox.innerHTML = "Invalid token"; + if (localStorage.getItem("token")) { + localStorage.removeItem("token"); + } + + userInfo.style.display = "none"; +} + +function decodeToken() { + if (localStorage.getItem("token") != null) { + // parse the token + try { + const token = localStorage.getItem("token"); + const content = token.split(".")[1]; + const b64 = content.replace(/-/g, "+").replace(/_/g, "/"); + const payload = decodeURIComponent(window.atob(b64)); + + return JSON.parse(payload); + } catch { + displayError(); + } + } else { + return null; + } +} + +function addToken() { + /* FIXME */ + localStorage.setItem("token", jwtField.value); + display(); +} + +function display() { + errorBox.innerHTML = ""; + if (localStorage.getItem("token") === "") { + displayError(); + return; + } + + // validity check + const dec = decodeToken(); + + if (dec == null || Date.now() < dec.iat * 1000) { + displayError(); + return; + } + + userInfo.style.display = "inherit"; + if (dec["name"] != undefined) { + userName.innerHTML = dec["name"]; + } else { + userName.innerHTML = "No name"; + } + + if (dec["email"] != undefined) { + userEmail.innerHTML = dec["email"]; + } else { + userEmail.innerHTML = "No email"; + } + + if (dec["age"] != undefined) { + userAge.innerHTML = dec["age"]; + } else { + userAge.innerHTML = "No age"; + } +} + +window.addToken = addToken; +display(); diff --git a/graphs/js/throttleDebounce/throttleDebounce.js b/graphs/js/throttleDebounce/throttleDebounce.js new file mode 100644 index 0000000..f6e15f9 --- /dev/null +++ b/graphs/js/throttleDebounce/throttleDebounce.js @@ -0,0 +1,48 @@ +function debounce(func, n) { + let timer = null; + + return (...args) => { + clearTimeout(timer); + timer = setTimeout(func, n, ...args); + }; +} +function throttle(func, n) { + let throttling = false; + let last_args = null; + let last_call = Date.now(); + let timeout = null; + + return (...args) => { + if (!throttling) { + last_call = Date.now(); + if (last_args) { + func.apply(this, last_args); + last_args = null; + } else { + func(...args); + } + + throttling = true; + if (timeout) { + clearTimeout(timeout); + } + + timeout = setTimeout( + () => { + throttling = false; + + if (last_args) { + func.apply(this, last_args); + } + }, + n - (Date.now() - last_call), + ); + } else { + last_args = args; + } + }; +} +module.exports = { + debounce, + throttle, +}; diff --git a/graphs/js/todoList/index.html b/graphs/js/todoList/index.html new file mode 100644 index 0000000..116cd2c --- /dev/null +++ b/graphs/js/todoList/index.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html lang="en" > + <head> + <meta charset="utf-8"> + <title>My To-do List</title> + <script src="todoList.js" defer></script> + <link rel="stylesheet" href="style.css"> + </head> + <body> + <h1>My To-do List</h1> + <div> + <input id="textBox" type="text" placeholder="Enter a task..."> + <button id="addButton">Add Item</button> + </div> + <ul id="todoList"></ul> + </body> +</html> diff --git a/graphs/js/todoList/style.css b/graphs/js/todoList/style.css new file mode 100644 index 0000000..ebdd8d7 --- /dev/null +++ b/graphs/js/todoList/style.css @@ -0,0 +1,64 @@ +body { + background-color: #f2f2f2; + font-family: Arial, sans-serif; +} + +h1 { + text-align: center; + margin-top: 20px; +} + +div { + display: flex; + justify-content: center; + width: 70%; + margin-right: auto; + margin-left: auto; +} + +input[type="text"] { + padding: 10px; + border: none; + border-radius: 5px; + margin-right: 10px; + width: 70%; +} + +#todoList { + display: flex; + flex-direction: column; + align-items: center; + margin-top: 30px; + list-style-type: decimal; +} + +.todoItem { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px; + margin-bottom: 10px; + width: 80%; + background-color: #fff; + border-radius: 5px; + box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3); +} + +.todoText { + flex-grow: 1; + margin-right: 10px; + padding-left: 10px; +} + +button { + padding: 5px 10px; + background-color: #f44336; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; +} + +button:hover { + background-color: #e53935; +} diff --git a/graphs/js/todoList/todoList.js b/graphs/js/todoList/todoList.js new file mode 100644 index 0000000..34b2edf --- /dev/null +++ b/graphs/js/todoList/todoList.js @@ -0,0 +1,27 @@ +const input = document.getElementById("textBox"); +const addBtn = document.getElementById("addButton"); +const list = document.getElementById("todoList"); + +addBtn.addEventListener("click", () => { + if (input.value === "") { + return; + } + + const todo = document.createElement("li"); + + todo.classList.add("todoItem"); + const label = document.createElement("span"); + + label.innerHTML = input.value; + input.value = ""; + label.classList.add("todoText"); + todo.appendChild(label); + const del = document.createElement("button"); + + del.innerHTML = "Delete"; + del.addEventListener("click", () => { + list.removeChild(todo); + }); + todo.appendChild(del); + list.appendChild(todo); +}); diff --git a/graphs/piscine/80cols/80cols.sh b/graphs/piscine/80cols/80cols.sh new file mode 100755 index 0000000..d66cf9b --- /dev/null +++ b/graphs/piscine/80cols/80cols.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +[ $# -ne 1 ] && exit 1 +[ -f $1 ] || exit 1 + +while IFS='' read -r line; do + var=$(printf '%s' "$line" | wc -m) + [ "$var" -ge 80 ] && printf '%s\n' "$line" +done < "$1" + +exit 0 diff --git a/graphs/piscine/80cols_grep/80cols.grep b/graphs/piscine/80cols_grep/80cols.grep new file mode 100644 index 0000000..1fe0c1f --- /dev/null +++ b/graphs/piscine/80cols_grep/80cols.grep @@ -0,0 +1 @@ +.\{80,\} diff --git a/graphs/piscine/a.out b/graphs/piscine/a.out Binary files differnew file mode 100755 index 0000000..33e84ed --- /dev/null +++ b/graphs/piscine/a.out diff --git a/graphs/piscine/add_int_ptr/add_int_ptr.c b/graphs/piscine/add_int_ptr/add_int_ptr.c new file mode 100644 index 0000000..ad48639 --- /dev/null +++ b/graphs/piscine/add_int_ptr/add_int_ptr.c @@ -0,0 +1,7 @@ +int *add_int_ptr(int *a, int *b) +{ + if (!a || !b) + return a; + *a += *b; + return a; +} diff --git a/graphs/piscine/alphabet/alphabet.c b/graphs/piscine/alphabet/alphabet.c new file mode 100644 index 0000000..9496c66 --- /dev/null +++ b/graphs/piscine/alphabet/alphabet.c @@ -0,0 +1,13 @@ +#include <stdio.h> + +int main(void) +{ + for (char i = 'a'; i < 'z'; i++) + { + putchar(i); + putchar(' '); + } + putchar('z'); + putchar('\n'); + return 0; +} diff --git a/graphs/piscine/alphanum/alphanum.sh b/graphs/piscine/alphanum/alphanum.sh new file mode 100755 index 0000000..e4c5aee --- /dev/null +++ b/graphs/piscine/alphanum/alphanum.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +letters() +{ + grepped=$(echo "$1" | grep -E "^[a-zA-Z]+$") + [ "$1" = "$grepped" ] && return 0 || return 1 +} + +empty() +{ + if echo "$1" | grep -qE '^[[:space:]]+$'; then + return 0 + fi + return 1 +} + +digit() +{ + grepped=$(echo "$1" | grep -E "^[0-9]$") + [ "$1" = "$grepped" ] && return 0 || return 1 +} + +number() +{ + grepped=$(echo "$1" | grep -E "^[1-9][0-9]+$") + [ "$1" = "$grepped" ] && return 0 || return 1 +} + +alph() +{ + grepped=$(echo "$1" | grep -E "^[a-zA-Z0-9]+$") + [ "$1" = "$grepped" ] && return 0 || return 1 +} + +while IFS='' read -r str; do + if [ -z "$str" ]; then + echo it is empty + continue + elif letters "$str"; then + echo "it is a word" + elif number "$str"; then + echo "it is a number" + elif digit "$str"; then + echo "it is a digit" + elif empty "$str"; then + echo "it is empty" + elif alph "$str"; then + echo "it is an alphanum" + else + echo "it is too complicated" + exit + fi +done diff --git a/graphs/piscine/array_max_min/array_max_min.c b/graphs/piscine/array_max_min/array_max_min.c new file mode 100644 index 0000000..8b2d3a5 --- /dev/null +++ b/graphs/piscine/array_max_min/array_max_min.c @@ -0,0 +1,23 @@ +#include <stddef.h> +#include <stdio.h> + +void array_max_min(int tab[], size_t len, int *max, int *min) +{ + if (tab && len) + { + *min = tab[0]; + *max = tab[0]; + + for (size_t i = 0; i < len; i++) + { + if (tab[i] > *max) + { + *max = tab[i]; + } + else if (tab[i] < *min) + { + *min = tab[i]; + } + } + } +} diff --git a/graphs/piscine/ascii_carousel/rot_x.c b/graphs/piscine/ascii_carousel/rot_x.c new file mode 100644 index 0000000..667106d --- /dev/null +++ b/graphs/piscine/ascii_carousel/rot_x.c @@ -0,0 +1,26 @@ +#include <stddef.h> + +void rot_x(char *s, int x) +{ + if (s == NULL) + { + return; + } + + if (x < 0) + { + x = 26 + x; + } + + for (size_t i = 0; s[i]; i++) + { + if (s[i] >= 'a' && s[i] <= 'z') + { + s[i] = ((s[i] - 'a') + x) % 26 + 'a'; + } + else if (s[i] >= 'A' && s[i] <= 'Z') + { + s[i] = ((s[i] - 'A') + x) % 26 + 'A'; + } + } +} diff --git a/graphs/piscine/ascii_house/ascii_house.sh b/graphs/piscine/ascii_house/ascii_house.sh new file mode 100755 index 0000000..83d907e --- /dev/null +++ b/graphs/piscine/ascii_house/ascii_house.sh @@ -0,0 +1,9 @@ +#!/bin/sh + + +echo ' /\' +echo ' / \' +echo -n "/____\\ \`" && echo "'\`" +echo -n "| | \`" && echo "'''\`" +echo "| | \`|\`" +echo '|_/\_|___|__' diff --git a/graphs/piscine/assignment_operator/assignment_operator.c b/graphs/piscine/assignment_operator/assignment_operator.c new file mode 100644 index 0000000..cae560f --- /dev/null +++ b/graphs/piscine/assignment_operator/assignment_operator.c @@ -0,0 +1,37 @@ +void plus_equal(int *a, int *b) +{ + if (!a || !b) + { + return; + } + *a = *a + *b; +} + +void minus_equal(int *a, int *b) +{ + if (!a || !b) + { + return; + } + *a = *a - *b; +} + +void mult_equal(int *a, int *b) +{ + if (!a || !b) + { + return; + } + *a = *a * *b; +} + +int div_equal(int *a, int *b) +{ + if (!a || !b || *b == 0) + { + return 0; + } + int res = *a % *b; + *a = *a / *b; + return res; +} diff --git a/graphs/piscine/binary_search_ptr/bsearch.c b/graphs/piscine/binary_search_ptr/bsearch.c new file mode 100644 index 0000000..bdc189c --- /dev/null +++ b/graphs/piscine/binary_search_ptr/bsearch.c @@ -0,0 +1,38 @@ +#include "bsearch.h" + +#include <stddef.h> + +int *binary_search(int *begin, int *end, int elt) +{ + if (begin == end) + { + return begin; + } + if (begin > end) + { + if (elt > *begin) + { + return begin + 1; + } + return begin; + } + + size_t m = (end - begin) / 2; + + if (begin[m] == elt) + { + return begin + m; + } + + if (begin[m] > elt) + { + return binary_search(begin, begin + m, elt); + } + + if (m == 0) + { + m++; + } + + return binary_search(begin + m, end, elt); +} diff --git a/graphs/piscine/binary_search_ptr/bsearch.h b/graphs/piscine/binary_search_ptr/bsearch.h new file mode 100644 index 0000000..e011744 --- /dev/null +++ b/graphs/piscine/binary_search_ptr/bsearch.h @@ -0,0 +1,16 @@ +#ifndef BSEARCH_H_ +#define BSEARCH_H_ + +/* +** Search `elt` in the memory range of [`begin` - `end`[. +** `begin` is a pointer to the first element. +** `end` is a pointer **AFTER** the last element. +** The elements in the range [`begin` - `end`[ are sorted in ascending order. +** If the range is empty, `begin` == `end`. +** `begin` and `end` can't be `NULL`. +** Returns a pointer to the element if found, or a pointer to the memory +** location where the element could be inserted to keep the array sorted. +*/ +int *binary_search(int *begin, int *end, int elt); + +#endif /* !BSEARCH_H_ */ diff --git a/graphs/piscine/binary_tree_dynamic/Makefile b/graphs/piscine/binary_tree_dynamic/Makefile new file mode 100644 index 0000000..7fa9879 --- /dev/null +++ b/graphs/piscine/binary_tree_dynamic/Makefile @@ -0,0 +1,15 @@ +CC = gcc +CFLAGS = -Wall -Werror -Wvla -Wextra -std=c99 -pedantic + +SRC = binary_tree.c binary_tree_print.c +OBJ = $(SRC:.c=.o) + +.PHONY: library clean + +library: $(OBJ) + ar csr libbinary_tree.a $(OBJ) + +$(OBJ): $(SRC) + +clean: + $(RM) libbinary_tree.a $(OBJ) diff --git a/graphs/piscine/binary_tree_dynamic/binary_tree.c b/graphs/piscine/binary_tree_dynamic/binary_tree.c new file mode 100644 index 0000000..6d99e99 --- /dev/null +++ b/graphs/piscine/binary_tree_dynamic/binary_tree.c @@ -0,0 +1,95 @@ +#include "binary_tree.h" + +#include <stddef.h> +#include <stdio.h> + +int size(const struct binary_tree *tree) +{ + if (tree == NULL) + return 0; + + return 1 + size(tree->left) + size(tree->right); +} + +static int max(int a, int b) +{ + if (a > b) + return a; + return b; +} + +int height(const struct binary_tree *tree) +{ + if (tree == NULL) + { + return -1; + } + + return 1 + max(height(tree->left), height(tree->right)); +} + +int is_perfect(const struct binary_tree *tree) +{ + if (tree == NULL) + return 1; + return height(tree->left) == height(tree->right) && is_perfect(tree->right) + && is_perfect(tree->right); +} + +int is_complete(const struct binary_tree *tree) +{ + if (tree == NULL) + { + return 1; + } + + int hg = height(tree->left); + int hd = height(tree->right); + + if (hg - hd != 0 && hg - hd != 1) + { + return 0; + } + + return is_complete(tree->left) && is_complete(tree->right); +} + +int is_degenerate(const struct binary_tree *tree) +{ + if (tree == NULL) + { + return 1; + } + + if (tree->left && tree->right) + { + return 0; + } + return is_degenerate(tree->left) && is_degenerate(tree->right); +} + +int is_full(const struct binary_tree *tree) +{ + if (tree == NULL) + return 1; + if ((tree->left && !tree->right) || (!tree->left && tree->right)) + return 0; + return is_full(tree->right) && is_full(tree->left); +} + +static int is_bzt(const struct binary_tree *tree, int min, int max) +{ + if (tree == NULL) + return 1; + if (tree->data > max || tree->data <= min) + return 0; + return is_bzt(tree->left, min, tree->data) + && is_bzt(tree->right, tree->data, max); +} + +int is_bst(const struct binary_tree *tree) +{ + if (tree == NULL) + return 1; + return is_bzt(tree, -2147483647, 2147483647); +} diff --git a/graphs/piscine/binary_tree_dynamic/binary_tree.h b/graphs/piscine/binary_tree_dynamic/binary_tree.h new file mode 100644 index 0000000..a08e4ef --- /dev/null +++ b/graphs/piscine/binary_tree_dynamic/binary_tree.h @@ -0,0 +1,22 @@ +#ifndef BINARY_TREE_H +#define BINARY_TREE_H + +struct binary_tree +{ + int data; + struct binary_tree *left; + struct binary_tree *right; +}; + +int size(const struct binary_tree *tree); +int height(const struct binary_tree *tree); +void dfs_print_prefix(const struct binary_tree *tree); +void dfs_print_infix(const struct binary_tree *tree); +void dfs_print_postfix(const struct binary_tree *tree); +int is_perfect(const struct binary_tree *tree); +int is_complete(const struct binary_tree *tree); +int is_degenerate(const struct binary_tree *tree); +int is_full(const struct binary_tree *tree); +int is_bst(const struct binary_tree *tree); + +#endif /* !BINARY_TREE_H */ diff --git a/graphs/piscine/binary_tree_dynamic/binary_tree_print.c b/graphs/piscine/binary_tree_dynamic/binary_tree_print.c new file mode 100644 index 0000000..bce0f77 --- /dev/null +++ b/graphs/piscine/binary_tree_dynamic/binary_tree_print.c @@ -0,0 +1,40 @@ +#include <stddef.h> +#include <stdio.h> + +#include "binary_tree.h" + +void dfs_print_prefix(const struct binary_tree *tree) +{ + if (tree == NULL) + { + return; + } + + printf("%d ", tree->data); + dfs_print_prefix(tree->left); + dfs_print_prefix(tree->right); +} + +void dfs_print_infix(const struct binary_tree *tree) +{ + if (tree == NULL) + { + return; + } + + dfs_print_infix(tree->left); + printf("%d ", tree->data); + dfs_print_infix(tree->right); +} + +void dfs_print_postfix(const struct binary_tree *tree) +{ + if (tree == NULL) + { + return; + } + + dfs_print_postfix(tree->left); + dfs_print_postfix(tree->right); + printf("%d ", tree->data); +} diff --git a/graphs/piscine/bit_rotation/rol.c b/graphs/piscine/bit_rotation/rol.c new file mode 100644 index 0000000..151ebb5 --- /dev/null +++ b/graphs/piscine/bit_rotation/rol.c @@ -0,0 +1,5 @@ +unsigned char rol(unsigned char value, unsigned char roll) +{ + roll %= sizeof(unsigned char) * 8; + return (value << roll) | (value >> (8 * sizeof(unsigned char) - roll)); +} diff --git a/graphs/piscine/bubble_sort/bubble_sort.c b/graphs/piscine/bubble_sort/bubble_sort.c new file mode 100644 index 0000000..13d2ba3 --- /dev/null +++ b/graphs/piscine/bubble_sort/bubble_sort.c @@ -0,0 +1,25 @@ +#include "bubble_sort.h" + +void bubble_sort(int array[], size_t size) +{ + if (!array || size == 0) + { + return; + } + + int mod; + do + { + mod = 0; + for (size_t i = 0; i < size - 1; i++) + { + if (array[i] > array[i + 1]) + { + mod = 1; + int tmp = array[i]; + array[i] = array[i + 1]; + array[i + 1] = tmp; + } + } + } while (mod); +} diff --git a/graphs/piscine/bubble_sort/bubble_sort.h b/graphs/piscine/bubble_sort/bubble_sort.h new file mode 100644 index 0000000..a33d531 --- /dev/null +++ b/graphs/piscine/bubble_sort/bubble_sort.h @@ -0,0 +1,8 @@ +#ifndef BUBBLE_SORT_H +#define BUBBLE_SORT_H + +#include <stddef.h> + +void bubble_sort(int array[], size_t size); + +#endif /* !BUBBLE_SORT_H */ diff --git a/graphs/piscine/check_alphabet/check_alphabet.c b/graphs/piscine/check_alphabet/check_alphabet.c new file mode 100644 index 0000000..fc540b4 --- /dev/null +++ b/graphs/piscine/check_alphabet/check_alphabet.c @@ -0,0 +1,25 @@ +#include "check_alphabet.h" + +#include <stddef.h> + +int check_alphabet(const char *str, const char *alphabet) +{ + if (alphabet == NULL || *alphabet == '\0') + { + return 1; + } + + for (int i = 0; alphabet[i]; i++) + { + int j; + for (j = 0; str[j] && str[j] != alphabet[i]; j++) + { + continue; + } + if (str[j] == '\0') + { + return 0; + } + } + return 1; +} diff --git a/graphs/piscine/check_alphabet/check_alphabet.h b/graphs/piscine/check_alphabet/check_alphabet.h new file mode 100644 index 0000000..667a20f --- /dev/null +++ b/graphs/piscine/check_alphabet/check_alphabet.h @@ -0,0 +1,6 @@ +#ifndef CHECK_ALPHABET_H +#define CHECK_ALPHABET_H + +int check_alphabet(const char *str, const char *alphabet); + +#endif /* !CHECK_ALPHABET_H */ diff --git a/graphs/piscine/clang-format/.clang-format b/graphs/piscine/clang-format/.clang-format new file mode 100644 index 0000000..7ed8115 --- /dev/null +++ b/graphs/piscine/clang-format/.clang-format @@ -0,0 +1,79 @@ +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: false +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BreakBeforeBraces: Custom +BraceWrapping: + AfterEnum: true + AfterClass: true + AfterControlStatement: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeComma +BreakStringLiterals: true +ColumnLimit: 80 +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +FixNamespaceComments: true +ForEachMacros: ['ILIST_FOREACH', 'ILIST_FOREACH_ENTRY'] +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '<.*>' + Priority: 1 + - Regex: '.*' + Priority: 2 +IndentCaseLabels: false +IndentPPDirectives: AfterHash +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +NamespaceIndentation: All +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: Never diff --git a/graphs/piscine/clang-format/zaza.c b/graphs/piscine/clang-format/zaza.c new file mode 100644 index 0000000..a6eec9a --- /dev/null +++ b/graphs/piscine/clang-format/zaza.c @@ -0,0 +1,78 @@ +#include <stdio.h> +#include <stdlib.h> +#define ZAZA_SIZE 4 + +static char get_zaza_char(size_t id) +{ + const int zaza[ZAZA_SIZE] = { + 10 * 10 + 2 * 10 + 2 * 10 / 10, + 10 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + + 10 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + + 10 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + + 10 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + + * 1 + + 10 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + + 10 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + + 10 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + + 10 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + + 10 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + + 10 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + - (1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + + 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 + + 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1), + 122, + (38943 * 43 - 84393 / 34583 + + ) % 10 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + }; + switch (id * 2 + 4 - 2 + id * 4 - 2 + -5 * id) + + { + case (0): + return (zaza[0]); + case (1000 - 100 - 4 * 100 + 10 * 100 - 14 * 100 - (10 * 10 - 1)): + return (zaza[1]); + case (1 << 11 >> 3 << 5 >> 2 << 1 << 1 << 1 >> 1 >> 1 >> 1 << 5 >> 4 << 1 + >> 1 >> 2 >> 9): + return zaza[2]; + case (3 ^ 100) - (100 ^ 100) - (99 - 99) - (98 - 98) - (97 - 97) - (96 - 96) + - (95 - 95) - (94 - 94) - (93 - 93) - (92 - 92) - (91 - 91) - (90 - 90) + - (89 - 89) - (88 - 88) - (87 - 87) - (86 - 86) - (85 - 85) - (84 - 84) + - (83 - 83) - (82 - 82) - (81 - 81) - (80 - 80) - (79 - 79) - (78 - 78) + - (77 - 77) - (76 - 76) - (75 - 75) - (74 - 74) - (73 - 73) - (72 - 72) + - (71 - 71) - (70 - 70) - + + (69 - 69) - (68 - 68) - (67 - 67) - (66 - 66) - (65 - 65) - (64 - 64) + - (63 - 63) - (62 - 62) - (61 - 61) - (60 - 60) - (59 - 59) - (58 - 58) + - (57 - 57) - (56 - 56) - (55 - 55) - (54 - 54) - (53 - 53) - (52 - 52) + - (51 - 51) - 100 - (50 - 50) - (49 - 49) - (48 - 48) - (47 - 47) + - (46 - 46) - (45 - 45) - (44 - 44) - (43 - 43) - (42 - 42) - (41 - 41) + - (40 - 40) - (39 - 39) - (38 - 38) - (37 - 37) + + - (36 - 36) - (35 - 35) - (34 - 34) - (33 - 33) - (32 - 32) - (31 - 31) + - (30 - 30) - (29 - 29) - (28 - 28) - (27 - 27) - (26 - 26) - (25 - 25) + - (24 - 24) - (23 - 23) - (22 - 22) - (21 - 21) - (20 - 20) - (19 - 19) + - (18 - 18) - (17 - 17) - (16 - 16) - (15 - 15) - (14 - 14) - (13 - 13) + - (12 - 12) - (11 - 11) - (10 - 10) - (9 - 9) - (8 - 8) - (7 - 7) + - (6 - 6) - (5 - 5) - (4 - 4) - (3 - 3) - (2 - 2) - (1 - 1): + return (zaza[3]); + default: + return (0); + } +} +int main(void) +{ + for (size_t i = 0; i < ZAZA_SIZE; i += (i % 2 == 2 - 2) ? 1 % 2 : 1 % 2) + { + putchar(get_zaza_char(i)); + } + putchar('\n'); + return (0); +} diff --git a/graphs/piscine/create_files/create_files.sh b/graphs/piscine/create_files/create_files.sh new file mode 100755 index 0000000..28dba00 --- /dev/null +++ b/graphs/piscine/create_files/create_files.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +touch ' ' +chmod 644 ' ' + +touch '\' +chmod 644 '\' + +touch -- -- +chmod 644 -- -- + +touch '|' +chmod 644 '|' + +touch '"' +chmod 644 '"' + +touch "'" +chmod 644 "'" + +touch -- --\$i*\'\"\\ +chmod 644 -- --\$i*\'\"\\ + +touch '# Exams are fun!' +chmod 644 '# Exams are fun!' + +touch ";\`kill -9 0\`" +chmod 644 ";\`kill -9 0\`" + +path="1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34/35/36/37/38/39/40/41/42/43/44/45/46/47/48/49/50" + +mkdir -p "$path" +touch $path/farfaraway +chmod 644 $path/farfaraway diff --git a/graphs/piscine/cut_csv/test.csv b/graphs/piscine/cut_csv/test.csv new file mode 100644 index 0000000..d88282b --- /dev/null +++ b/graphs/piscine/cut_csv/test.csv @@ -0,0 +1,15 @@ +James;Lebron;LABron;Lakers; +Davis;Anthony;Unibrow;Pelicans; +Mitchell;Donovan;Spida;Jazz; +Harden;James;TheBeard;Rockets; +Cousins;DeMarcus;Boogie;Wariors; +Embiid;Joel;TheProcess;76Sixers; +Bryant;Kobe;BlackMamba;Lakers; +Jordan;Michael;AirJordan;Bulls; +Johnson;Earvin;Magic;Lakers; +Howard;Dwight;Superman;Wizards; +Westbrook;Russel;MrTripleDouble;Thunder; +Durant;Kevin;KD;Wariors; +George;Paul;PG-13;Thunder; +Leonard;Kawhi;TheKlaw;Raptors; +Irving;Kyrie;UncleDrew;Celtics; diff --git a/graphs/piscine/cut_csv/with_cut.sh b/graphs/piscine/cut_csv/with_cut.sh new file mode 100755 index 0000000..9618f00 --- /dev/null +++ b/graphs/piscine/cut_csv/with_cut.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +[ $# -ne 2 ] && exit 1 + +if ! [ -f "$1" ]; then + exit 1 +fi + +if ! [ "$2" -eq "$2" ] 2> /dev/null; then + exit 1 +fi + +[ "$2" -lt 0 ] && exit 1 + +if [ "$2" -gt "$(wc -l < "$1")" ]; then + exit 1 +fi + +line=$(head --lines="$2" "$1" 2> /dev/null | tail -n 1 | cut -d ';' -f 2-3 || exit 1) +c1=$(echo "$line" | cut -d ';' -f 1) +c2=$(echo "$line" | cut -d ';' -f 2) + +echo "$c1 is $c2" diff --git a/graphs/piscine/cut_csv/with_sed.sh b/graphs/piscine/cut_csv/with_sed.sh new file mode 100755 index 0000000..fb5e1f8 --- /dev/null +++ b/graphs/piscine/cut_csv/with_sed.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +[ $# -ne 2 ] && exit 1 + +if ! [ -f "$1" ]; then + exit 1 +fi + +if ! [ "$2" -eq "$2" ] 2>/dev/null; then + exit 1 +fi + +[ "$2" -lt 0 ] && exit 1 + +if [ "$2" -gt $(wc -l < "$1") ]; then + exit 1 +fi + +i=1 + +while IFS= read -r line; do + [ "$i" -eq "$2" ] && echo "$line" | sed 's/^.*;\(.*\);\(.*\);.*;$/\1 is \2/' + i=$(($i + 1)) +done < "$1" diff --git a/graphs/piscine/digit/digit.c b/graphs/piscine/digit/digit.c new file mode 100644 index 0000000..5646b13 --- /dev/null +++ b/graphs/piscine/digit/digit.c @@ -0,0 +1,13 @@ +unsigned int digit(int n, int k) +{ + if (n <= 0 || k <= 0) + { + return 0; + } + + for (int i = 0; i < k - 1; i++) + { + n /= 10; + } + return n % 10; +} diff --git a/graphs/piscine/display_square/display_square.c b/graphs/piscine/display_square/display_square.c new file mode 100644 index 0000000..9e834d7 --- /dev/null +++ b/graphs/piscine/display_square/display_square.c @@ -0,0 +1,44 @@ +#include <stdio.h> + +void display_square(int width) +{ + if (width <= 0) + { + return; + } + + if (width % 2 == 0) + { + width++; + } + + if (width == 1) + { + putchar('*'); + putchar('\n'); + return; + } + + for (int i = 0; i < width; i++) + { + putchar('*'); + } + putchar('\n'); + + for (int i = 0; i < ((width - 3) / 2); i++) + { + putchar('*'); + for (int j = 0; j < width - 2; j++) + { + putchar(' '); + } + putchar('*'); + putchar('\n'); + } + + for (int i = 0; i < width; i++) + { + putchar('*'); + } + putchar('\n'); +} diff --git a/graphs/piscine/dlist/Makefile b/graphs/piscine/dlist/Makefile new file mode 100644 index 0000000..1251967 --- /dev/null +++ b/graphs/piscine/dlist/Makefile @@ -0,0 +1,15 @@ +CC = gcc +CFLAGS = -std=c99 -pedantic -Werror -Wall -Wextra -Wvla + +SRC = dlist-1.c dlist-2.c dlist-3.c dlist-4.c +OBJ = $(SRC:.c=.o) + +.PHONY: library clean + +library: $(OBJ) + ar csr libdlist.a $(OBJ) + +clean: $(OBJ) + $(RM) *.a $(OBJ) + +$(OBJ): $(SRC) diff --git a/graphs/piscine/dlist/dlist-1.c b/graphs/piscine/dlist/dlist-1.c new file mode 100644 index 0000000..443ebca --- /dev/null +++ b/graphs/piscine/dlist/dlist-1.c @@ -0,0 +1,78 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "dlist.h" + +struct dlist *dlist_init(void) +{ + struct dlist *res = malloc(sizeof(struct dlist)); + if (res == NULL) + return NULL; + + res->size = 0; + res->head = NULL; + res->tail = NULL; + return res; +} + +int dlist_push_front(struct dlist *list, int element) +{ + if (element < 0) + return 0; + struct dlist_item *new = malloc(sizeof(struct dlist_item)); + if (new == NULL) + return 0; + + new->data = element; + new->next = list->head; + new->prev = NULL; + + if (list->size == 0) + list->tail = new; + else + list->head->prev = new; + + list->head = new; + list->size++; + + return 1; +} + +void dlist_print(const struct dlist *list) +{ + if (list->size == 0) + return; + + for (struct dlist_item *i = list->head; i != list->tail; i = i->next) + { + printf("%d\n", i->data); + } + printf("%d\n", list->tail->data); +} + +int dlist_push_back(struct dlist *list, int element) +{ + if (element < 0) + return 0; + struct dlist_item *new = malloc(sizeof(struct dlist_item)); + if (new == NULL) + return 0; + + new->data = element; + new->prev = list->tail; + new->next = NULL; + + if (list->size == 0) + list->head = new; + else + list->tail->next = new; + list->tail = new; + list->size++; + + return 1; +} + +size_t dlist_size(const struct dlist *list) +{ + return list->size; +} diff --git a/graphs/piscine/dlist/dlist-2.c b/graphs/piscine/dlist/dlist-2.c new file mode 100644 index 0000000..5ccdaa3 --- /dev/null +++ b/graphs/piscine/dlist/dlist-2.c @@ -0,0 +1,113 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "dlist.h" + +int dlist_get(const struct dlist *list, size_t index) +{ + if (index >= list->size) + return -1; + + struct dlist_item *i; + for (i = list->head; index; index--, i = i->next) + { + continue; + } + + return i->data; +} + +int dlist_insert_at(struct dlist *list, int element, size_t index) +{ + if (index > list->size || element < 0) + return 0; + else if (index == list->size) + dlist_push_back(list, element); + else if (index == 0) + dlist_push_front(list, element); + else + { + struct dlist_item *new = malloc(sizeof(struct dlist_item)); + if (new == NULL) + return 0; + new->data = element; + + struct dlist_item *i; + for (i = list->head; index - 1; index--, i = i->next) + continue; + new->next = i->next; + i->next->prev = new; + i->next = new; + new->prev = i; + list->size++; + } + return 1; +} + +int dlist_find(const struct dlist *list, int element) +{ + int index = 0; + struct dlist_item *i; + for (i = list->head; i && i->data != element; index++, i = i->next) + continue; + if (!i) + return -1; + return index; +} + +int dlist_remove_at(struct dlist *list, size_t index) +{ + if (index >= list->size) + return -1; + int res; + struct dlist_item *item; + if (list->size == 1) + { + item = list->head; + res = list->head->data; + list->head = NULL; + list->tail = NULL; + } + else if (index == 0) + { + item = list->head; + res = item->data; + item->next->prev = NULL; + list->head = item->next; + } + else if (index == list->size - 1) + { + item = list->tail; + res = item->data; + item->prev->next = NULL; + list->tail = item->prev; + } + else + { + for (item = list->head; index; index--, item = item->next) + continue; + + res = item->data; + item->prev->next = item->next; + item->next->prev = item->prev; + } + + free(item); + list->size--; + return res; +} + +void dlist_clear(struct dlist *list) +{ + if (list->size == 0) + return; + for (struct dlist_item *i = list->head; i;) + { + struct dlist_item *tmp = i->next; + free(i); + i = tmp; + } + list->size = 0; + list->head = NULL; + list->tail = NULL; +} diff --git a/graphs/piscine/dlist/dlist-3.c b/graphs/piscine/dlist/dlist-3.c new file mode 100644 index 0000000..22b4b52 --- /dev/null +++ b/graphs/piscine/dlist/dlist-3.c @@ -0,0 +1,83 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "dlist.h" + +void dlist_map_square(struct dlist *list) +{ + for (struct dlist_item *i = list->head; i; i = i->next) + { + i->data *= i->data; + } +} + +void dlist_reverse(struct dlist *list) +{ + struct dlist_item *tmp; + for (struct dlist_item *i = list->head; i; i = i->prev) + { + tmp = i->next; + i->next = i->prev; + i->prev = tmp; + } + tmp = list->tail; + list->tail = list->head; + list->head = tmp; +} + +struct dlist *dlist_split_at(struct dlist *list, size_t index) +{ + if (list->size == 0) + return dlist_init(); + if (index >= list->size) + { + return NULL; + } + + struct dlist *new = dlist_init(); + if (new == NULL) + return NULL; + new->size = list->size - index; + list->size = index; + + struct dlist_item *i; + for (i = list->head; index; index--, i = i->next) + { + continue; + } + + new->head = i; + new->tail = list->tail; + list->tail = i->prev; + if (i->prev) + { + i->prev->next = NULL; + } + else + { + list->head = NULL; + } + i->prev = NULL; + return new; +} + +void dlist_concat(struct dlist *list1, struct dlist *list2) +{ + if (list2->head == NULL) + return; + if (list1->tail == NULL) + { + list1->head = list2->head; + list1->tail = list2->tail; + list1->size = list2->size; + return; + } + + list1->tail->next = list2->head; + list2->head->prev = list1->tail; + list1->tail = list2->tail; + list1->size += list2->size; + list2->size = 0; + list2->head = NULL; + list2->tail = NULL; +} diff --git a/graphs/piscine/dlist/dlist-4.c b/graphs/piscine/dlist/dlist-4.c new file mode 100644 index 0000000..9ed7aaa --- /dev/null +++ b/graphs/piscine/dlist/dlist-4.c @@ -0,0 +1,97 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "dlist.h" + +size_t max(size_t a, size_t b) +{ + if (a >= b) + { + return a; + } + return b; +} + +size_t min(size_t a, size_t b) +{ + if (a <= b) + { + return a; + } + return b; +} + +size_t min_3(size_t a, size_t b, size_t c) +{ + if (a <= b) + { + if (a <= c) + { + return a; + } + return c; + } + else + { + if (b <= c) + { + return b; + } + return c; + } +} + +size_t my_strlen(const int *s) +{ + size_t i; + for (i = 0; s[i] != -1; i++) + { + continue; + } + return i; +} + +size_t levenshtein(const int *s1, const int *s2) +{ + size_t l1 = my_strlen(s1); + size_t l2 = my_strlen(s2); + if (min(l1, l2) == 0) + { + return max(l1, l2); + } + + if (s1[0] == s2[0]) + { + return levenshtein(s1 + 1, s2 + 1); + } + + size_t lev1 = levenshtein(s1 + 1, s2); + size_t lev2 = levenshtein(s1, s2 + 1); + size_t lev3 = levenshtein(s1 + 1, s2 + 1); + + return 1 + min_3(lev1, lev2, lev3); +} + +int *to_str(const struct dlist *l) +{ + int *res = malloc((l->size + 1) * sizeof(int)); + res[l->size] = -1; + size_t j = 0; + for (struct dlist_item *i = l->head; i; i = i->next, j++) + { + res[j] = i->data; + } + return res; +} + +unsigned int dlist_levenshtein(const struct dlist *list1, + const struct dlist *list2) +{ + int *l1 = to_str(list1); + int *l2 = to_str(list2); + + unsigned int res = levenshtein(l1, l2); + free(l1); + free(l2); + return res; +} diff --git a/graphs/piscine/dlist/dlist.h b/graphs/piscine/dlist/dlist.h new file mode 100644 index 0000000..97cde1a --- /dev/null +++ b/graphs/piscine/dlist/dlist.h @@ -0,0 +1,44 @@ +#ifndef DLIST_H +#define DLIST_H + +#include <stddef.h> + +struct dlist_item +{ + int data; + struct dlist_item *next; + struct dlist_item *prev; +}; + +struct dlist +{ + size_t size; + struct dlist_item *head; + struct dlist_item *tail; +}; + +// Threshold 1 +struct dlist *dlist_init(void); +int dlist_push_front(struct dlist *list, int element); +void dlist_print(const struct dlist *list); +int dlist_push_back(struct dlist *list, int element); +size_t dlist_size(const struct dlist *list); + +// Threshold 2 +int dlist_get(const struct dlist *list, size_t index); +int dlist_insert_at(struct dlist *list, int element, size_t index); +int dlist_find(const struct dlist *list, int element); +int dlist_remove_at(struct dlist *list, size_t index); +void dlist_clear(struct dlist *list); + +// Threshold 3 +void dlist_map_square(struct dlist *list); +void dlist_reverse(struct dlist *list); +struct dlist *dlist_split_at(struct dlist *list, size_t index); +void dlist_concat(struct dlist *list1, struct dlist *list2); + +// Threshold 4 +unsigned int dlist_levenshtein(const struct dlist *list1, + const struct dlist *list2); + +#endif /* !DLIST_H */ diff --git a/graphs/piscine/element_count/element_count.c b/graphs/piscine/element_count/element_count.c new file mode 100644 index 0000000..cec47ae --- /dev/null +++ b/graphs/piscine/element_count/element_count.c @@ -0,0 +1,10 @@ +#include "element_count.h" + +size_t element_count(int *begin, int *end) +{ + if (!begin || !end || begin >= end) + { + return 0; + } + return end - begin; +} diff --git a/graphs/piscine/element_count/element_count.h b/graphs/piscine/element_count/element_count.h new file mode 100644 index 0000000..57412ed --- /dev/null +++ b/graphs/piscine/element_count/element_count.h @@ -0,0 +1,8 @@ +#ifndef ELEMENT_COUNT_H +#define ELEMENT_COUNT_H + +#include <stddef.h> + +size_t element_count(int *begin, int *end); + +#endif /* !ELEMENT_COUNT_H */ diff --git a/graphs/piscine/evalexpr/Makefile b/graphs/piscine/evalexpr/Makefile new file mode 100644 index 0000000..280f19c --- /dev/null +++ b/graphs/piscine/evalexpr/Makefile @@ -0,0 +1,23 @@ +CC = gcc +CFLAGS = -Wall -Werror -Wextra -pedantic -std=c99 -Wvla +AFLAGS = -fsanitize=address + +SRC=src/stack.c src/evalrpn.c src/shunting_yard.c src/fifo_access.c src/fifo_setup_destroy.c src/evalexpr.c +SRC_TEST=tests/unit_tests.c +#OBJ=src/stack.o src/evalrpn.o +OBJ=$(SRC:.c=.o) +#OBJ_TEST=$(SRC_TEST:.c=.o) + +all: $(OBJ) + $(CC) -o evalexpr $(OBJ) + +$(OBJ): $(SRC) + +check: #$(OBJ) $(OBJ_TEST) +# $(CC) $(CFLAGS) -o evaltest $(OBJ) $(OBJ_TEST) -lcriterion + tests/tests.sh + +.PHONY: clean + +clean: + rm $(OBJ) evalexpr diff --git a/graphs/piscine/evalexpr/src/evalexpr.c b/graphs/piscine/evalexpr/src/evalexpr.c new file mode 100644 index 0000000..5012355 --- /dev/null +++ b/graphs/piscine/evalexpr/src/evalexpr.c @@ -0,0 +1,93 @@ +#include "evalexpr.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define BUFFER_SIZE 10 + +char *get_input(void) +{ + size_t r; + char buf[BUFFER_SIZE]; + size_t size = 0; + char *expr = malloc(size * sizeof(char) + 1); + if (expr == NULL) + return NULL; + expr[0] = '\0'; + do + { + r = fread(buf, sizeof(char), BUFFER_SIZE - 1, stdin); + if (r != 0) + { + buf[r] = '\0'; + size += r; + char *tmp = realloc(expr, size * sizeof(char) + 1); + if (tmp == NULL) + { + free(expr); + return NULL; + } + expr = tmp; + strcat(expr, buf); + } + } while (r != 0); + if (size == 0) + { + free(expr); + return NULL; + } + if (expr[size - 1] == '\n') + expr[size - 1] = '\0'; + return expr; +} + +void cleanup(char *expr, char *rpn) +{ + free(expr); + free(rpn); +} + +int main(int argc, char **argv) +{ + if ((argc == 2 && strcmp(argv[1], "-rpn") != 0) || (argc > 2)) + return 4; + char *expr = get_input(); + if (expr == NULL) + return 4; + if (argc == 1) + { + char *rpn; + int e = shunting_yard(expr, &rpn); + if (e != 0) + return e; + // call shunting yard + int retval; + e = evalrpn(rpn, &retval); + if (e != 0) + { + cleanup(expr, rpn); + return e; + } + // FREE RPN + printf("%d\n", retval); + cleanup(expr, rpn); + // return + return 0; + } + + if (argc == 2 && strcmp(argv[1], "-rpn") == 0) + { + // call rpn eval + int retval; + int e = evalrpn(expr, &retval); + printf("%d\n", retval); + // return + free(expr); + if (e != 0) + return e; + return 0; + } + + return 4; +} diff --git a/graphs/piscine/evalexpr/src/evalexpr.h b/graphs/piscine/evalexpr/src/evalexpr.h new file mode 100644 index 0000000..d440ae1 --- /dev/null +++ b/graphs/piscine/evalexpr/src/evalexpr.h @@ -0,0 +1,43 @@ +#ifndef EVALEXPR_H +#define EVALEXPR_H + +#include <stddef.h> + +#include "fifo.h" +#include "stack.h" +#include "stack_struct.h" + +enum token_type +{ + NUMBER = 0, + SUB = 1, + ADD = 1, + MOD = 2, + DIV = 2, + MUL = 2, + EXP = 3, + UN_PLUS = 4, + UN_MINUS = 4, + PAR_LEFT = 5, + PAR_RIGHT = 5, + WRONG_TOKEN = -1, +}; + +struct token +{ + enum token_type type; + int value; +}; + +// evalrpn +int parse_number(const char *expr, size_t *offset); +int get_operands(struct stack **s, int *op1, int *op2); +int my_pow(int a, int b); +int evalrpn(const char *expr, int *retval); + +// shunting yard +int opcmp(struct token *op1, struct token *op2); +enum token_type get_type(char op); +int shunting_yard(const char *expr, char **rpn); + +#endif /* ! EVALEXPR_H */ diff --git a/graphs/piscine/evalexpr/src/evalrpn.c b/graphs/piscine/evalexpr/src/evalrpn.c new file mode 100644 index 0000000..db493eb --- /dev/null +++ b/graphs/piscine/evalexpr/src/evalrpn.c @@ -0,0 +1,145 @@ +#include <ctype.h> + +#include "evalexpr.h" + +int parse_number(const char *expr, size_t *offset) +{ + for (*offset = 0; + expr[*offset] && expr[*offset] >= '0' && expr[*offset] <= '9'; + (*offset)++) + { + continue; + } + (*offset)--; + + int res = 0; + int pow = 1; + for (size_t n = 0; n <= *offset; n++, pow *= 10) + { + res += (expr[*offset - n] - '0') * pow; + } + + return res; +} + +int get_operands(struct stack **s, int *op1, int *op2) +{ + if (*s == NULL) + { + return 2; + } + *op1 = stack_peek(*s); + *s = stack_pop(*s); + if (*s == NULL) + { + return 2; + } + *op2 = stack_peek(*s); + *s = stack_pop(*s); + return 0; +} + +// Computes a to the bth +int my_pow(int a, int b) +{ + if (b == 0) + { + return 1; + } + if (a == 0) + { + return 0; + } + + int res = 1; + int c = b / 2; + while (c != 0) + { + res *= a * a; + c /= 2; + } + if (b % 2 != 0) + res *= a; + return res; +} + +int dispatch(const char c, struct stack **s, int op1, int op2) +{ + switch (c) + { + case '*': + *s = stack_push(*s, op1 * op2); + break; + case '+': + *s = stack_push(*s, op1 + op2); + break; + case '-': + *s = stack_push(*s, op2 - op1); + break; + case '/': + if (op1 == 0) + { + return 3; + } + *s = stack_push(*s, op2 / op1); + break; + case '%': + if (op1 == 0) + { + return 3; + } + *s = stack_push(*s, op2 % op1); + break; + case '^': + if (op1 < 0) + { + return 3; + } + *s = stack_push(*s, my_pow(op2, op1)); + break; + default: + return 1; + } + return 0; +} + +int evalrpn(const char *expr, int *retval) +{ + struct stack *s = NULL; + + for (size_t i = 0; expr[i]; i++) + { + if (expr[i] >= '0' && expr[i] <= '9') + { + size_t offset; + int val = parse_number(expr + i, &offset); + s = stack_push(s, val); + i += offset; + } + else if (isspace(expr[i])) + continue; + else + { + int op1; + int op2; + if (get_operands(&s, &op1, &op2) == 2) + { + return 2; + } + + int d = dispatch(expr[i], &s, op1, op2); + if (d != 0) + { + return d; + } + } + } + + if (s == NULL) + { + return 0; + } + *retval = stack_peek(s); + s = stack_pop(s); + return (!s) ? 0 : 2; +} diff --git a/graphs/piscine/evalexpr/src/fifo.h b/graphs/piscine/evalexpr/src/fifo.h new file mode 100644 index 0000000..b330eac --- /dev/null +++ b/graphs/piscine/evalexpr/src/fifo.h @@ -0,0 +1,29 @@ +#ifndef FIFO_H +#define FIFO_H + +#include <stddef.h> + +#include "evalexpr.h" + +struct list +{ + struct token *data; + struct list *next; +}; + +struct fifo +{ + struct list *head; + struct list *tail; + size_t size; +}; + +struct fifo *fifo_init(void); +size_t fifo_size(struct fifo *fifo); +void fifo_push(struct fifo *fifo, struct token *elt); +struct token *fifo_head(struct fifo *fifo); +void fifo_pop(struct fifo *fifo); +void fifo_clear(struct fifo *fifo); +void fifo_destroy(struct fifo *fifo); + +#endif /* !FIFO_H */ diff --git a/graphs/piscine/evalexpr/src/fifo_access.c b/graphs/piscine/evalexpr/src/fifo_access.c new file mode 100644 index 0000000..1986a09 --- /dev/null +++ b/graphs/piscine/evalexpr/src/fifo_access.c @@ -0,0 +1,61 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "fifo.h" + +size_t fifo_size(struct fifo *fifo) +{ + return fifo->size; +} + +void fifo_push(struct fifo *fifo, struct token *elt) +{ + struct list *new = malloc(sizeof(struct list)); + if (new == NULL) + { + return; + } + new->data = elt; + + if (fifo_size(fifo) == 0) + { + fifo->head = new; + } + new->next = NULL; + if (fifo_size(fifo) != 0) + { + fifo->tail->next = new; + } + fifo->tail = new; + + fifo->size++; +} + +struct token *fifo_head(struct fifo *fifo) +{ + return fifo->head->data; +} + +void fifo_pop(struct fifo *fifo) +{ + if (fifo_size(fifo) == 0) + { + return; + } + if (fifo_size(fifo) == 1) + { + free(fifo->head->data); + free(fifo->head); + fifo->head = NULL; + fifo->tail = NULL; + fifo->size = 0; + return; + } + + struct list *tmp = fifo->head->next; + free(fifo->head->data); + free(fifo->head); + fifo->head = tmp; + + fifo->size--; +} diff --git a/graphs/piscine/evalexpr/src/fifo_setup_destroy.c b/graphs/piscine/evalexpr/src/fifo_setup_destroy.c new file mode 100644 index 0000000..0f99ad0 --- /dev/null +++ b/graphs/piscine/evalexpr/src/fifo_setup_destroy.c @@ -0,0 +1,44 @@ +#include <stdlib.h> + +#include "fifo.h" + +struct fifo *fifo_init(void) +{ + struct fifo *f = malloc(sizeof(struct fifo)); + if (f == NULL) + { + return NULL; + } + + f->size = 0; + f->head = NULL; + f->tail = NULL; + + return f; +} + +void fifo_clear(struct fifo *fifo) +{ + for (struct list *l = fifo->head; l != fifo->tail;) + { + struct list *tmp = l->next; + free(l->data); + free(l); + l = tmp; + } + if (fifo->tail) + { + free(fifo->tail->data); + free(fifo->tail); + } + + fifo->head = NULL; + fifo->tail = NULL; + fifo->size = 0; +} + +void fifo_destroy(struct fifo *fifo) +{ + fifo_clear(fifo); + free(fifo); +} diff --git a/graphs/piscine/evalexpr/src/shunting_yard.c b/graphs/piscine/evalexpr/src/shunting_yard.c new file mode 100644 index 0000000..2db5fc8 --- /dev/null +++ b/graphs/piscine/evalexpr/src/shunting_yard.c @@ -0,0 +1,199 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "evalexpr.h" + +enum assoc +{ + NONE, + RIGHT, + LEFT, +}; + +int opcmp(struct token *op1, struct token *op2) +{ + return op1->type - op2->type; +} + +enum assoc get_assoc(struct token *op) +{ + if (op->type == EXP) + { + return RIGHT; + } + return LEFT; +} + +enum token_type get_type(char op) +{ + switch (op) + { + case '*': + return MUL; + case '/': + return DIV; + case '-': + return SUB; + case '+': + return ADD; + case '%': + return MOD; + case '^': + return EXP; + case '(': + return PAR_LEFT; + case ')': + return PAR_RIGHT; + default: + return WRONG_TOKEN; + } +} + +char *fifo_to_expr(struct fifo *output, size_t size_offset) +{ + char *res = malloc((2 * fifo_size(output) + size_offset) * sizeof(char)); + if (!res) + { + fifo_destroy(output); + return NULL; + } + res[2 * fifo_size(output) + size_offset - 1] = '\0'; + size_t i = 0; + while (fifo_size(output) > 0) + { + if (fifo_head(output)->type == NUMBER) + { + i += sprintf(res + i, "%d", fifo_head(output)->value) - 1; + } + else + { + res[i] = fifo_head(output)->value; + } + fifo_pop(output); + i++; + if (fifo_size(output) != 0) + { + res[i] = ' '; + i++; + } + } + fifo_destroy(output); + return res; +} + +int handle_rpar(struct tstack **opstack, struct fifo *output, struct token **t) +{ + while (*opstack) + { + struct token *o2 = tstack_peek(*opstack); + if (o2->value == '(') + { + free(o2); + break; + } + *opstack = tstack_pop(*opstack); + fifo_push(output, o2); + } + if (*opstack == NULL) + { + free(*t); + fifo_destroy(output); + return 2; + } + free(*t); + *opstack = tstack_pop(*opstack); + return 0; +} + +int empty_opstack(struct tstack **opstack, struct fifo *output) +{ + while (*opstack) + { + struct token *t = tstack_peek(*opstack); + if (t->value == '(' || t->value == ')') + { + fifo_destroy(output); + return 1; + } + *opstack = tstack_pop(*opstack); + fifo_push(output, t); + } + return 0; +} + +void pop_ops(struct tstack **opstack, struct fifo *output, struct token *t) +{ + while (*opstack) + { + struct token *o2 = tstack_peek(*opstack); + if (!(o2->value != '(' + && (opcmp(t, o2) < 0 + || (opcmp(t, o2) == 0 && get_assoc(t) == LEFT)))) + { + break; + } + + *opstack = tstack_pop(*opstack); + fifo_push(output, o2); + } +} + +void handle_numbers(struct fifo *output, size_t *i, int *size_offset, + const char *expr) +{ + size_t offset; + int val = parse_number(expr + *i, &offset); + struct token *t = malloc(sizeof(struct token)); + t->type = NUMBER; + t->value = val; + fifo_push(output, t); + *i += offset; + *size_offset += offset; +} + +int shunting_yard(const char *expr, char **rpn) +{ + struct fifo *output = fifo_init(); + struct tstack *opstack = NULL; + int size_offset = 0; + for (size_t i = 0; expr[i]; i++) + { + if (expr[i] >= '0' && expr[i] <= '9') + { + handle_numbers(output, &i, &size_offset, expr); + } + else if (expr[i] != ' ') + { + struct token *t = malloc(sizeof(struct token)); + t->value = expr[i]; + if ((t->type = get_type(expr[i])) == WRONG_TOKEN) + { + free(t); + return 1; + } + if (t->value == '(') + { + opstack = tstack_push(opstack, t); + continue; + } + else if (t->value == ')') + { + if (handle_rpar(&opstack, output, &t) != 0) + return 2; + continue; + } + pop_ops(&opstack, output, t); + opstack = tstack_push(opstack, t); + } + } + + if (empty_opstack(&opstack, output) != 0) + { + return 1; + } + *rpn = fifo_to_expr(output, size_offset); + if (!*rpn) + return 4; + + return 0; +} diff --git a/graphs/piscine/evalexpr/src/stack.c b/graphs/piscine/evalexpr/src/stack.c new file mode 100644 index 0000000..14f659e --- /dev/null +++ b/graphs/piscine/evalexpr/src/stack.c @@ -0,0 +1,57 @@ +#include "stack.h" + +#include <stdlib.h> + +struct stack *stack_push(struct stack *s, int e) +{ + struct stack *new = malloc(sizeof(struct stack)); + new->data = e; + new->next = NULL; + + new->next = s; + return new; +} + +struct stack *stack_pop(struct stack *s) +{ + if (s == NULL) + { + return NULL; + } + + struct stack *res = s->next; + free(s); + return res; +} + +int stack_peek(struct stack *s) +{ + return s->data; +} + +struct tstack *tstack_push(struct tstack *s, struct token *e) +{ + struct tstack *new = malloc(sizeof(struct tstack)); + new->token = e; + new->next = NULL; + + new->next = s; + return new; +} + +struct tstack *tstack_pop(struct tstack *s) +{ + if (s == NULL) + { + return NULL; + } + + struct tstack *res = s->next; + free(s); + return res; +} + +struct token *tstack_peek(struct tstack *s) +{ + return s->token; +} diff --git a/graphs/piscine/evalexpr/src/stack.h b/graphs/piscine/evalexpr/src/stack.h new file mode 100644 index 0000000..d08e465 --- /dev/null +++ b/graphs/piscine/evalexpr/src/stack.h @@ -0,0 +1,20 @@ +#ifndef STACK_H +#define STACK_H + +#include "evalexpr.h" +#include "stack_struct.h" + +struct tstack +{ + struct token *token; + struct tstack *next; +}; + +struct stack *stack_push(struct stack *s, int e); +struct stack *stack_pop(struct stack *s); +int stack_peek(struct stack *s); + +struct tstack *tstack_push(struct tstack *s, struct token *e); +struct tstack *tstack_pop(struct tstack *s); +struct token *tstack_peek(struct tstack *s); +#endif /* !STACK_H */ diff --git a/graphs/piscine/evalexpr/src/stack_struct.h b/graphs/piscine/evalexpr/src/stack_struct.h new file mode 100644 index 0000000..105cd5d --- /dev/null +++ b/graphs/piscine/evalexpr/src/stack_struct.h @@ -0,0 +1,10 @@ +#ifndef STACK_STRUCT_H +#define STACK_STRUCT_H + +struct stack +{ + int data; + struct stack *next; +}; + +#endif /* ! STACK_STRUCT_H */ diff --git a/graphs/piscine/evalexpr/tests/tests.sh b/graphs/piscine/evalexpr/tests/tests.sh new file mode 100755 index 0000000..920f09b --- /dev/null +++ b/graphs/piscine/evalexpr/tests/tests.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +REF_OUT="ref.out" +TEST_OUT="test.out" + +testrpn() +{ + echo "$2" > "$REF_OUT" + echo "Evaluating '$1' in RPN notation..." + echo "$1" | ./evalexpr -rpn > "$TEST_OUT" + diff "$REF_OUT" "$TEST_OUT" && echo "Success" +} + +testeval() +{ + echo "$1" | bc 2> /dev/null > "$REF_OUT" + echo "Evaluating '$1' in standard notation..." + echo "$1" | ./evalexpr > "$TEST_OUT" + diff "$REF_OUT" "$TEST_OUT" && echo "Success" +} + +testerror() +{ + echo "Testing error code '$2'..." + echo "$1" | ./evalexpr + error="$(echo $?)" + [ "$2" -eq "$error" ] && echo "Succesful failure" || echo "Wrong error $error" +} + +clean() +{ + rm "$REF_OUT" "$TEST_OUT" +} + +# RPN + +echo "Tests for RPN:" +echo "======" + +testrpn "1 1 +" 2 +testrpn "5 2 2 ^ 3 + *" 35 +testrpn "10 6 9 3 + 0 11 - * / * 17 + 5 +" 22 +testrpn "3 4 5 * 3 + -" "-20" +testrpn "3 2 % 9 3 1 2 + * / -" 0 + +echo +echo "=============================================" +echo + +# Standard + +echo "Tests for standard notation:" +echo "======" + +testeval "1 + 1" +testeval " 1 + 1 +1 " +testeval "2 * 2" +testeval "5 * (2 + 4)" +testeval "5 * (2 % 4)" +testeval " 5 *(2 ^4) " +testeval " 5 *(2 ^4 " + +echo +echo "=============================================" +echo + +# Errors + +echo "Error tests:" +echo "======" + +testerror "" 0 +testerror "a+1" 1 +testerror "1%0" 3 + +echo "Testing error code '4'..." +./evalexpr --toto 2> /dev/null +echo $? + +# Cleanup + +clean diff --git a/graphs/piscine/evalexpr/tests/unit_tests.c b/graphs/piscine/evalexpr/tests/unit_tests.c new file mode 100644 index 0000000..ed445a0 --- /dev/null +++ b/graphs/piscine/evalexpr/tests/unit_tests.c @@ -0,0 +1,208 @@ +#include <criterion/criterion.h> +#include <criterion/assert.h> +#include <stddef.h> +#include <string.h> + +#include "../src/evalexpr.h" + +TestSuite(parse_number); + +Test(parse_number, parse_42) +{ + size_t o; + int actual = parse_number("42", &o); + cr_expect(actual == 42, "Attendu : %d, renvoyé : %d", 42, actual); + cr_expect(o == 1, "Décalage attendu : %d, renvoyé : %zu", 1, o); +} + +Test(parse_number, parse_4) +{ + size_t o; + int actual = parse_number("4", &o); + cr_expect(actual == 4, "Attendu : %d, renvoyé : %d", 4, actual); + cr_expect(o == 0, "Décalage attendu : %d, renvoyé : %zu", 0, o); +} + +TestSuite(my_pow); + +Test(my_pow, my_pow00) +{ + int actual = my_pow(0, 0); + cr_expect(actual == 1, "Attendu : %d, renvoyé : %d", 1, actual); +} + +Test(my_pow, my_pown0) +{ + int actual = my_pow(50, 0); + cr_expect(actual == 1, "Attendu : %d, renvoyé : %d", 1, actual); +} +Test(my_pow, my_pow0n) +{ + int actual = my_pow(0, 42); + cr_expect(actual == 0, "Attendu : %d, renvoyé : %d", 0, actual); +} +Test(my_pow, my_powab) +{ + int actual = my_pow(3,3); + cr_expect(actual == 27, "Attendu : %d, renvoyé : %d", 27, actual); +} +Test(my_pow, my_powab_2) +{ + int actual = my_pow(4, 2); + cr_expect(actual == 16, "Attendu : %d, renvoyé : %d", 16, actual); +} +Test(my_pow, my_powab_3) +{ + int actual = my_pow(10, 3); + cr_expect(actual == 1000, "Attendu : %d, renvoyé : %d", 1000, actual); +} +Test(my_pow, my_pow1n) +{ + int actual = my_pow(1, 50); + cr_expect(actual == 1, "Attendu : %d, renvoyé : %d", 1, actual); +} + +TestSuite(RPN); + +Test(RPN, evalrpn_easiest) +{ + const char test[] = "1 1 +"; + int expected = 0; + int retval; + int res = 2; + int actual = evalrpn(test, &retval); + cr_expect(actual == expected, "%s => Retour attendu : %d, renvoyé : %d", test, expected, actual); + cr_expect(retval == res, "%s => Résultat attendu : %d, reçu : %d", test, res, retval); +} +Test(RPN, evalrpn_35) +{ + const char test[] = "5 2 2 ^ 3 + *"; + int expected = 0; + int retval; + int res = 35; + int actual = evalrpn(test, &retval); + cr_expect(actual == expected, "%s => Retour attendu : %d, renvoyé : %d", test, expected, actual); + cr_expect(retval == res, "%s => Résultat attendu : %d, reçu : %d", test, res, retval); +} +Test(RPN, evalrpn_22) +{ + const char test[] = "10 6 9 3 + 0 11 - * / * 17 + 5 +"; + int expected = 0; + int retval; + int res = 22; + int actual = evalrpn(test, &retval); + cr_expect(actual == expected, "%s => Retour attendu : %d, renvoyé : %d", test, expected, actual); + cr_expect(retval == res, "%s => Résultat attendu : %d, reçu : %d", test, res, retval); +} +Test(RPN, evalrpn_minus20) +{ + const char test[] = "3 4 5 * 3 + -"; + int expected = 0; + int retval; + int res = -20; + int actual = evalrpn(test, &retval); + cr_expect(actual == expected, "%s => Retour attendu : %d, renvoyé : %d", test, expected, actual); + cr_expect(retval == res, "%s => Résultat attendu : %d, reçu : %d", test, res, retval); +} +Test(RPN, evalrpn_zero) +{ + const char test[] = "3 2 % 9 3 1 2 + * / -"; + int expected = 0; + int retval; + int res = 0; + int actual = evalrpn(test, &retval); + cr_expect(actual == expected, "%s => Retour attendu : %d, renvoyé : %d", test, expected, actual); + cr_expect(retval == res, "%s => Résultat attendu : %d, reçu : %d", test, res, retval); +} + +TestSuite(Precedence); + +Test(Precedence, parenthesis_above_all) +{ + struct token pleft = { PAR_LEFT, '(' }; + struct token pright = { PAR_RIGHT, ')' }; + struct token unplus = { UN_PLUS, '+' }; + struct token exp = { EXP, '^' }; + struct token mul = { MUL, '*' }; + struct token minus = { SUB, '-' }; + int eq = opcmp(&pleft, &pright); + int sup = opcmp(&pleft, &unplus); + int inf = opcmp(&unplus, &pright); + int parftw = opcmp(&pleft, &exp); + int par4ever = opcmp(&pright, &mul); + int paragain = opcmp(&pright, &minus); + cr_expect(eq == 0, "Wrong order (equal)"); + cr_expect(sup > 0, "Wrong order (>)"); + cr_expect(inf < 0, "Wrong order (<)"); + cr_expect(parftw > 0, "Wrong order (>)"); + cr_expect(par4ever > 0, "Wrong order (>)"); + cr_expect(paragain > 0, "Wrong order (>)"); +} + +Test(Precedence, other_precedence_tests) +{ + struct token exp = { EXP, '^' }; + struct token mul = { MUL, '*' }; + struct token unplus = { UN_PLUS, '+' }; + struct token minus = { SUB, '-' }; + struct token plus = { ADD, '+' }; + int eq = opcmp(&minus, &plus); + int sup = opcmp(&exp, &mul); + int inf = opcmp(&plus, &unplus); + + cr_expect(eq == 0, "Wrong order (equal)"); + cr_expect(sup > 0, "Wrong order (>)"); + cr_expect(inf < 0, "Wrong order (<)"); +} + +TestSuite(ShuntingTests); + +Test(ShuntingTests, shunt_simplest) +{ + char *rpn; + const char *expr = "1 + 1"; + int actual = shunting_yard(expr, &rpn); + cr_expect(actual == 0, "Expected shunting_yard return value %d, got %d", 0, actual); + cr_expect(strcmp(rpn, "1 1 +") == 0, "Expected '1 1 +', got %s", rpn); + free(rpn); +} + +Test(ShuntingTests, shunt_nico) +{ + char *rpn; + const char *expr = "1 + 1 + 1"; + int actual = shunting_yard(expr, &rpn); + cr_expect(actual == 0, "Expected shunting_yard return value %d, got %d", 0, actual); + cr_expect(strcmp(rpn, "1 1 + 1 +") == 0, "Expected '1 1 + 1 +', got %s", rpn); + free(rpn); +} + +Test(ShuntingTests, shunt_harderdaddy) +{ + char *rpn; + const char *expr = "5*(2^2+3)"; + int actual = shunting_yard(expr, &rpn); + cr_expect(actual == 0, "Expected shunting_yard return value %d, got %d", 0, actual); + cr_expect(strcmp(rpn, "5 2 2 ^ 3 + *") == 0, "Expected '5 2 2 ^ 3 + *', got %s", rpn); + free(rpn); +} + +Test(ShuntingTests, shunt_numbers) +{ + char *rpn; + const char *expr = "42 + 50"; + int actual = shunting_yard(expr, &rpn); + cr_expect(actual == 0, "Expected shunting_yard return value %d, got %d", 0, actual); + cr_expect(strcmp(rpn, "42 50 +") == 0, "Expected '42 50 +', got %s", rpn); + free(rpn); +} + +Test(ShuntingTests, shunt_mod) +{ + char *rpn; + const char *expr = "42 % 50"; + int actual = shunting_yard(expr, &rpn); + cr_expect(actual == 0, "Expected shunting_yard return value %d, got %d", 0, actual); + cr_expect(strcmp(rpn, "42 50 %") == 0, "Expected '42 50 +', got %s", rpn); + free(rpn); +} diff --git a/graphs/piscine/fact/fact.c b/graphs/piscine/fact/fact.c new file mode 100644 index 0000000..1440c94 --- /dev/null +++ b/graphs/piscine/fact/fact.c @@ -0,0 +1,8 @@ +unsigned long fact(unsigned n) +{ + if (n == 0) + { + return 1; + } + return n * fact(n - 1); +} diff --git a/graphs/piscine/facto/facto.sh b/graphs/piscine/facto/facto.sh new file mode 100755 index 0000000..350973a --- /dev/null +++ b/graphs/piscine/facto/facto.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +[ $# -ne 1 ] && exit 1 +i=$1 +res=1 +while [ "$i" -gt 0 ]; do + res=$(($res * $i)) + i=$(($i - 1)) +done +echo "$res" diff --git a/graphs/piscine/fibo/fibo.c b/graphs/piscine/fibo/fibo.c new file mode 100644 index 0000000..99c0d79 --- /dev/null +++ b/graphs/piscine/fibo/fibo.c @@ -0,0 +1,8 @@ +unsigned long fibonacci(unsigned long n) +{ + if (n == 0 || n == 1) + { + return n; + } + return fibonacci(n - 1) + fibonacci(n - 2); +} diff --git a/graphs/piscine/fibo_iter/fibo_iter.c b/graphs/piscine/fibo_iter/fibo_iter.c new file mode 100644 index 0000000..36ebf46 --- /dev/null +++ b/graphs/piscine/fibo_iter/fibo_iter.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +unsigned long fibo_iter(unsigned long n) +{ + if (n == 0) + { + return 0; + } + unsigned long prev = 1; + unsigned long pprev = 0; + unsigned long i; + + for (i = 1; i < n; i++) + { + unsigned long next = pprev + prev; + pprev = prev; + prev = next; + } + + return prev; +} diff --git a/graphs/piscine/fifo/Makefile b/graphs/piscine/fifo/Makefile new file mode 100644 index 0000000..e5c9374 --- /dev/null +++ b/graphs/piscine/fifo/Makefile @@ -0,0 +1,16 @@ +CC=gcc +CFLAGS=-std=c99 -Wall -Wextra -Wvla -Werror -pedantic + +.PHONY: library clean + +library: fifo_access.o fifo_setup_destroy.o + ar csr libfifo.a $^ + +fifo_access.o: fifo_access.c + $(CC) $(CFLAGS) -c -o fifo_access.o fifo_access.c + +fifo_setup_destroy.o: fifo_setup_destroy.c + $(CC) $(CFLAGS) -c -o fifo_setup_destroy.o fifo_setup_destroy.c + +clean: + rm *.o libfifo.a diff --git a/graphs/piscine/fifo/fifo.h b/graphs/piscine/fifo/fifo.h new file mode 100644 index 0000000..c4b0a6f --- /dev/null +++ b/graphs/piscine/fifo/fifo.h @@ -0,0 +1,28 @@ +#ifndef FIFO_H +#define FIFO_H + +#include <stddef.h> + +struct list +{ + int data; + struct list *next; +}; + +struct fifo +{ + struct list *head; + struct list *tail; + size_t size; +}; + +struct fifo *fifo_init(void); +size_t fifo_size(struct fifo *fifo); +void fifo_push(struct fifo *fifo, int elt); +int fifo_head(struct fifo *fifo); +void fifo_pop(struct fifo *fifo); +void fifo_clear(struct fifo *fifo); +void fifo_destroy(struct fifo *fifo); +void fifo_print(const struct fifo *fifo); + +#endif /* !FIFO_H */ diff --git a/graphs/piscine/fifo/fifo_access.c b/graphs/piscine/fifo/fifo_access.c new file mode 100644 index 0000000..5d31586 --- /dev/null +++ b/graphs/piscine/fifo/fifo_access.c @@ -0,0 +1,66 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "fifo.h" + +size_t fifo_size(struct fifo *fifo) +{ + return fifo->size; +} + +void fifo_push(struct fifo *fifo, int elt) +{ + struct list *new = malloc(sizeof(struct list)); + if (new == NULL) + { + return; + } + new->data = elt; + + if (fifo_size(fifo) == 0) + { + fifo->head = new; + } + new->next = NULL; + if (fifo_size(fifo) != 0) + { + fifo->tail->next = new; + } + fifo->tail = new; + + fifo->size++; +} + +int fifo_head(struct fifo *fifo) +{ + return fifo->head->data; +} + +void fifo_pop(struct fifo *fifo) +{ + if (fifo_size(fifo) == 0) + { + return; + } + if (fifo_size(fifo) == 1) + { + free(fifo->head); + fifo->head = NULL; + fifo->tail = NULL; + return; + } + + struct list *tmp = fifo->head->next; + free(fifo->head); + fifo->head = tmp; + + fifo->size--; +} + +void fifo_print(const struct fifo *fifo) +{ + for (struct list *l = fifo->head; l; l = l->next) + { + printf("%d\n", l->data); + } +} diff --git a/graphs/piscine/fifo/fifo_setup_destroy.c b/graphs/piscine/fifo/fifo_setup_destroy.c new file mode 100644 index 0000000..80820e1 --- /dev/null +++ b/graphs/piscine/fifo/fifo_setup_destroy.c @@ -0,0 +1,39 @@ +#include <stdlib.h> + +#include "fifo.h" + +struct fifo *fifo_init(void) +{ + struct fifo *f = malloc(sizeof(struct fifo)); + if (f == NULL) + { + return NULL; + } + + f->size = 0; + f->head = NULL; + f->tail = NULL; + + return f; +} + +void fifo_clear(struct fifo *fifo) +{ + for (struct list *l = fifo->head; l != fifo->tail;) + { + struct list *tmp = l->next; + free(l); + l = tmp; + } + free(fifo->tail); + + fifo->head = NULL; + fifo->tail = NULL; + fifo->size = 0; +} + +void fifo_destroy(struct fifo *fifo) +{ + fifo_clear(fifo); + free(fifo); +} diff --git a/graphs/piscine/find_ascii/find_ascii.sh b/graphs/piscine/find_ascii/find_ascii.sh new file mode 100755 index 0000000..db31722 --- /dev/null +++ b/graphs/piscine/find_ascii/find_ascii.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +for filename in $(ls "$1"); do + echo $1/$filename | file -f - | grep ASCII +done diff --git a/graphs/piscine/freq_analysis/freq_analysis.c b/graphs/piscine/freq_analysis/freq_analysis.c new file mode 100644 index 0000000..c60d7a6 --- /dev/null +++ b/graphs/piscine/freq_analysis/freq_analysis.c @@ -0,0 +1,28 @@ +#include <stdio.h> + +int find_rank(int h[26], int min) +{ + int res = 0; + for (int i = 0; i < 26; i++) + { + res += h[i] > h[min] || (h[i] == h[min] && i < min); + } + return res; +} + +void freq_analysis(const char text[], const char table[]) +{ + int h[26] = { 0 }; + for (int i = 0; text[i]; i++) + { + h[text[i] - 'A']++; + } + + for (int j = 0; j < 26; j++) + { + if (h[j] != 0) + { + printf("%c %c\n", j + 'A', table[find_rank(h, j)]); + } + } +} diff --git a/graphs/piscine/functional_programming/foldl.c b/graphs/piscine/functional_programming/foldl.c new file mode 100644 index 0000000..ac222a7 --- /dev/null +++ b/graphs/piscine/functional_programming/foldl.c @@ -0,0 +1,11 @@ +#include "functional_programming.h" + +int foldl(int *array, size_t len, int (*func)(int, int)) +{ + int acc = 0; + for (size_t i = 0; i < len; i++) + { + acc = (*func)(acc, array[i]); + } + return acc; +} diff --git a/graphs/piscine/functional_programming/foldr.c b/graphs/piscine/functional_programming/foldr.c new file mode 100644 index 0000000..c232410 --- /dev/null +++ b/graphs/piscine/functional_programming/foldr.c @@ -0,0 +1,10 @@ +#include "functional_programming.h" + +int foldr(int *array, size_t len, int (*func)(int, int)) +{ + if (len == 1) + { + return (*func)(array[0], 0); + } + return (*func)(array[0], foldr(array + 1, len - 1, func)); +} diff --git a/graphs/piscine/functional_programming/functional_programming.h b/graphs/piscine/functional_programming/functional_programming.h new file mode 100644 index 0000000..429b13c --- /dev/null +++ b/graphs/piscine/functional_programming/functional_programming.h @@ -0,0 +1,10 @@ +#ifndef FUNCTIONAL_PROGRAMMING_H +#define FUNCTIONAL_PROGRAMMING_H + +#include <stddef.h> + +void map(int *array, size_t len, void (*func)(int *)); +int foldr(int *array, size_t len, int (*func)(int, int)); +int foldl(int *array, size_t len, int (*func)(int, int)); + +#endif /* !FUNCTIONAL_PROGRAMMING_H */ diff --git a/graphs/piscine/functional_programming/map.c b/graphs/piscine/functional_programming/map.c new file mode 100644 index 0000000..311c39c --- /dev/null +++ b/graphs/piscine/functional_programming/map.c @@ -0,0 +1,9 @@ +#include "functional_programming.h" + +void map(int *array, size_t len, void (*func)(int *)) +{ + for (size_t i = 0; i < len; i++) + { + (*func)(array + i); + } +} diff --git a/graphs/piscine/generate_files/generate_files.sh b/graphs/piscine/generate_files/generate_files.sh new file mode 100755 index 0000000..cf2ba0a --- /dev/null +++ b/graphs/piscine/generate_files/generate_files.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +FILENAME="default" +NUMBER="1" +EXTENSION="txt" + +while [ $# -gt 0 ]; do + case "$1" in + '-f' | '--filename') + shift + FILENAME="$1" + shift + ;; + '-n' | '--number') + shift + NUMBER="$1" + shift + ;; + '-e' | '--extension') + shift + EXTENSION="$1" + shift + ;; + *) + exit 1 + ;; + esac +done + +for i in $(seq 1 $NUMBER); do + touch -- "$FILENAME-$i.$EXTENSION" +done diff --git a/graphs/piscine/generic_void_list/list.c b/graphs/piscine/generic_void_list/list.c new file mode 100644 index 0000000..20ecfa8 --- /dev/null +++ b/graphs/piscine/generic_void_list/list.c @@ -0,0 +1,36 @@ +#include "list.h" + +#include <stdlib.h> +#include <string.h> + +struct list *list_prepend(struct list *list, const void *value, + size_t data_size) +{ + struct list *new = malloc(sizeof(struct list)); + new->next = list; + new->data = malloc(sizeof(void *)); + memcpy(new->data, value, data_size); + return new; +} + +size_t list_length(struct list *list) +{ + size_t res = 0; + while (list) + { + res++; + list = list->next; + } + return res; +} + +void list_destroy(struct list *list) +{ + while (list) + { + struct list *tmp = list->next; + free(list->data); + free(list); + list = tmp; + } +} diff --git a/graphs/piscine/generic_void_list/list.h b/graphs/piscine/generic_void_list/list.h new file mode 100644 index 0000000..a1bc035 --- /dev/null +++ b/graphs/piscine/generic_void_list/list.h @@ -0,0 +1,31 @@ +#ifndef LIST_H +#define LIST_H + +#include <stddef.h> + +struct list +{ + void *data; + struct list *next; +}; + +/* +** Insert a node containing `value` at the beginning of the list. +** Return `NULL` if an error occurred. +*/ +struct list *list_prepend(struct list *list, const void *value, + size_t data_size); + +/* +** Return the length of the list. +** Return `0` if the list is empty. +*/ +size_t list_length(struct list *list); + +/* +** Release the memory used by the list. +** Does nothing if `list` is `NULL`. +*/ +void list_destroy(struct list *list); + +#endif /* !LIST_H */ diff --git a/graphs/piscine/glob_easy/glob_easy.sh b/graphs/piscine/glob_easy/glob_easy.sh new file mode 100755 index 0000000..b6ae028 --- /dev/null +++ b/graphs/piscine/glob_easy/glob_easy.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +echo $1/*.[A-Za-z][A-Za-z] diff --git a/graphs/piscine/glob_remove_shell/glob_remove_shell.sh b/graphs/piscine/glob_remove_shell/glob_remove_shell.sh new file mode 100755 index 0000000..c2e7ff7 --- /dev/null +++ b/graphs/piscine/glob_remove_shell/glob_remove_shell.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +fmt=*.${1:-"txt"} + +for file in $(echo "$fmt"); do + [ -e "$file" ] && rm "$file" || exit 1 +done diff --git a/graphs/piscine/grade/grade.c b/graphs/piscine/grade/grade.c new file mode 100644 index 0000000..caecc82 --- /dev/null +++ b/graphs/piscine/grade/grade.c @@ -0,0 +1,29 @@ +#include <stdio.h> + +void grade(char g) +{ + switch (g) + { + case 'A': + puts("Excellent"); + break; + case 'B': + puts("Good"); + break; + case 'C': + puts("Not so bad"); + break; + case 'D': + puts("Could be worse"); + break; + case 'E': + puts("Maybe next time"); + break; + case 'F': + puts("No comment"); + break; + default: + puts("Call a wild ACU"); + break; + } +} diff --git a/graphs/piscine/greatest_divisor/greatest_divisor.c b/graphs/piscine/greatest_divisor/greatest_divisor.c new file mode 100644 index 0000000..4c8efef --- /dev/null +++ b/graphs/piscine/greatest_divisor/greatest_divisor.c @@ -0,0 +1,15 @@ +unsigned int greatest_divisor(unsigned int n) +{ + if (n == 0 || n == 1) + { + return 1; + } + + int i; + for (i = n / 2; i > 0 && n % i; i--) + { + continue; + } + + return i; +} diff --git a/graphs/piscine/hacker_news/input.html b/graphs/piscine/hacker_news/input.html new file mode 100644 index 0000000..54d338d --- /dev/null +++ b/graphs/piscine/hacker_news/input.html @@ -0,0 +1,147 @@ +<html op="news" class=" lddwcbt idc0_332" lang="en"><head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta name="referrer" content="origin"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" type="text/css" href="02_files/news.css"> + <link rel="shortcut icon" href="https://news.ycombinator.com/favicon.ico"> + <link rel="alternate" type="application/rss+xml" title="RSS" href="https://news.ycombinator.com/rss"> + <title>Hacker News</title></head><body><center><table id="hnmain" width="85%" cellspacing="0" cellpadding="0" border="0" bgcolor="#f6f6ef"> + <tbody><tr><td bgcolor="#ff6600"><table style="padding:2px" width="100%" cellspacing="0" cellpadding="0" border="0"><tbody><tr><td style="width:18px;padding-right:4px"><a href="https://news.ycombinator.com/"><img src="02_files/y18.gif" style="border:1px white solid;" width="18" height="18"></a></td> + <td style="line-height:12pt; height:10px;"><span class="pagetop"><b class="hnname"><a href="https://news.ycombinator.com/news">Hacker News</a></b> + <a href="https://news.ycombinator.com/newest">new</a> | <a href="https://news.ycombinator.com/front">past</a> | <a href="https://news.ycombinator.com/newcomments">comments</a> | <a href="https://news.ycombinator.com/ask">ask</a> | <a href="https://news.ycombinator.com/show">show</a> | <a href="https://news.ycombinator.com/jobs">jobs</a> | <a href="https://news.ycombinator.com/submit">submit</a> </span></td><td style="text-align:right;padding-right:4px;"><span class="pagetop"> + <a href="https://news.ycombinator.com/login?goto=news%3Fp%3D2">login</a> + </span></td> + </tr></tbody></table></td></tr> +<tr id="pagespace" title="" style="height:10px"></tr><tr><td><table class="itemlist" cellspacing="0" cellpadding="0" border="0"> + <tbody><tr class="athing" id="28943869"> + <td class="title" valign="top" align="right"><span class="rank">31.</span></td> <td class="votelinks" valign="top"><center><a id="up_28943869" href="https://news.ycombinator.com/vote?id=28943869&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://apnews.com/article/technology-business-arts-and-entertainment-be48d7582fdd5604664fff33ed81ca80" class="titlelink">Sinclair Broadcast Group identifies data breach</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=apnews.com"><span class="sitestr">apnews.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28943869">8 points</span> by <a href="https://news.ycombinator.com/user?id=xojoc" class="hnuser">xojoc</a> <span class="age" title="2021-10-21T13:12:05"><a href="https://news.ycombinator.com/item?id=28943869">1 hour ago</a></span> <span id="unv_28943869"></span> | <a href="https://news.ycombinator.com/hide?id=28943869&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28943869">1 comment</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28926775"> + <td class="title" valign="top" align="right"><span class="rank">32.</span></td> <td class="votelinks" valign="top"><center><a id="up_28926775" href="https://news.ycombinator.com/vote?id=28926775&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.earlevel.com/main/2002/08/31/a-gentle-introduction-to-the-fft/" class="titlelink">A gentle introduction to the FFT (2002)</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=earlevel.com"><span class="sitestr">earlevel.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28926775">71 points</span> by <a href="https://news.ycombinator.com/user?id=tigerlily" class="hnuser">tigerlily</a> <span class="age" title="2021-10-20T04:31:20"><a href="https://news.ycombinator.com/item?id=28926775">12 hours ago</a></span> <span id="unv_28926775"></span> | <a href="https://news.ycombinator.com/hide?id=28926775&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28926775">14 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28930157"> + <td class="title" valign="top" align="right"><span class="rank">33.</span></td> <td class="votelinks" valign="top"><center><a id="up_28930157" href="https://news.ycombinator.com/vote?id=28930157&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://thebrowser.com/notes/jon-ingold/" class="titlelink">Jon Ingold on translating archeology into video games</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=thebrowser.com"><span class="sitestr">thebrowser.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28930157">36 points</span> by <a href="https://news.ycombinator.com/user?id=nupitalnumber" class="hnuser">nupitalnumber</a> <span class="age" title="2021-10-20T13:04:53"><a href="https://news.ycombinator.com/item?id=28930157">9 hours ago</a></span> <span id="unv_28930157"></span> | <a href="https://news.ycombinator.com/hide?id=28930157&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28930157">4 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28943611"> + <td class="title" valign="top" align="right"><span class="rank">34.</span></td> <td class="votelinks" valign="top"><center><a id="up_28943611" href="https://news.ycombinator.com/vote?id=28943611&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://news.ycombinator.com/item?id=28943611" class="titlelink">Ask HN: How to Sell a Website</a></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28943611">7 points</span> by <a href="https://news.ycombinator.com/user?id=legrisch" class="hnuser">legrisch</a> <span class="age" title="2021-10-21T12:45:35"><a href="https://news.ycombinator.com/item?id=28943611">1 hour ago</a></span> <span id="unv_28943611"></span> | <a href="https://news.ycombinator.com/hide?id=28943611&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28943611">3 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28933391"> + <td class="title" valign="top" align="right"><span class="rank">35.</span></td> <td class="votelinks" valign="top"><center><a id="up_28933391" href="https://news.ycombinator.com/vote?id=28933391&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://iconmap.io/blog" class="titlelink">We analyzed 425k favicons</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=iconmap.io"><span class="sitestr">iconmap.io</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28933391">493 points</span> by <a href="https://news.ycombinator.com/user?id=gurgeous" class="hnuser">gurgeous</a> <span class="age" title="2021-10-20T17:29:03"><a href="https://news.ycombinator.com/item?id=28933391">20 hours ago</a></span> <span id="unv_28933391"></span> | <a href="https://news.ycombinator.com/hide?id=28933391&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28933391">119 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28938551"> + <td class="title" valign="top" align="right"><span class="rank">36.</span></td> <td class="votelinks" valign="top"><center><a id="up_28938551" href="https://news.ycombinator.com/vote?id=28938551&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.science.org/content/article/machu-picchu-was-built-over-major-fault-zones-now-researchers-think-they-know-why" class="titlelink">Machu Picchu was built over major fault zones (2019)</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=science.org"><span class="sitestr">science.org</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28938551">98 points</span> by <a href="https://news.ycombinator.com/user?id=Anon84" class="hnuser">Anon84</a> <span class="age" title="2021-10-21T00:07:54"><a href="https://news.ycombinator.com/item?id=28938551">14 hours ago</a></span> <span id="unv_28938551"></span> | <a href="https://news.ycombinator.com/hide?id=28938551&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28938551">41 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28940507"> + <td class="title" valign="top" align="right"><span class="rank">37.</span></td> <td class="votelinks" valign="top"><center><a id="up_28940507" href="https://news.ycombinator.com/vote?id=28940507&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://brave.com/wp-content/uploads/2021/03/goggles.pdf" class="titlelink">Goggles: Democracy dies in darkness, and so does the Web [pdf]</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=brave.com"><span class="sitestr">brave.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28940507">114 points</span> by <a href="https://news.ycombinator.com/user?id=InvaderFizz" class="hnuser">InvaderFizz</a> <span class="age" title="2021-10-21T05:03:56"><a href="https://news.ycombinator.com/item?id=28940507">9 hours ago</a></span> <span id="unv_28940507"></span> | <a href="https://news.ycombinator.com/hide?id=28940507&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28940507">119 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28933663"> + <td class="title" valign="top" align="right"><span class="rank">38.</span></td> <td class="votelinks" valign="top"><center><a id="up_28933663" href="https://news.ycombinator.com/vote?id=28933663&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://browser.geekbench.com/v5/cpu/10496766" class="titlelink">Apple M1 Max Geekbench Score</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=geekbench.com"><span class="sitestr">geekbench.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28933663">467 points</span> by <a href="https://news.ycombinator.com/user?id=mv9" class="hnuser">mv9</a> <span class="age" title="2021-10-20T17:50:17"><a href="https://news.ycombinator.com/item?id=28933663">20 hours ago</a></span> <span id="unv_28933663"></span> | <a href="https://news.ycombinator.com/hide?id=28933663&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28933663">771 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28933981"> + <td class="title" valign="top" align="right"><span class="rank">39.</span></td> <td class="votelinks" valign="top"><center><a id="up_28933981" href="https://news.ycombinator.com/vote?id=28933981&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.commerce.gov/news/press-releases/2021/10/commerce-tightens-export-controls-items-used-surveillance-private" class="titlelink">U.S. tightens export controls on items used in surveillance of private citizens</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=commerce.gov"><span class="sitestr">commerce.gov</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28933981">275 points</span> by <a href="https://news.ycombinator.com/user?id=transpute" class="hnuser">transpute</a> <span class="age" title="2021-10-20T18:14:33"><a href="https://news.ycombinator.com/item?id=28933981">20 hours ago</a></span> <span id="unv_28933981"></span> | <a href="https://news.ycombinator.com/hide?id=28933981&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28933981">161 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28943645"> + <td class="title" valign="top" align="right"><span class="rank">40.</span></td> <td class="votelinks" valign="top"><center><a id="up_28943645" href="https://news.ycombinator.com/vote?id=28943645&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.wsj.com/articles/wework-set-to-go-public-via-spac-deal-two-years-after-failed-ipo-11634808600" class="titlelink" rel="nofollow">WeWork is trying to go public – again</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=wsj.com"><span class="sitestr">wsj.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28943645">8 points</span> by <a href="https://news.ycombinator.com/user?id=collegeburner" class="hnuser">collegeburner</a> <span class="age" title="2021-10-21T12:49:02"><a href="https://news.ycombinator.com/item?id=28943645">1 hour ago</a></span> <span id="unv_28943645"></span> | <a href="https://news.ycombinator.com/hide?id=28943645&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28943645">2 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28934624"> + <td class="title" valign="top" align="right"><span class="rank">41.</span></td> <td class="votelinks" valign="top"><center><a id="up_28934624" href="https://news.ycombinator.com/vote?id=28934624&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.copetti.org/writings/consoles/playstation-3/" class="titlelink">Playstation 3 Architecture</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=copetti.org"><span class="sitestr">copetti.org</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28934624">362 points</span> by <a href="https://news.ycombinator.com/user?id=bangonkeyboard" class="hnuser">bangonkeyboard</a> <span class="age" title="2021-10-20T18:56:53"><a href="https://news.ycombinator.com/item?id=28934624">19 hours ago</a></span> <span id="unv_28934624"></span> | <a href="https://news.ycombinator.com/hide?id=28934624&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28934624">81 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28929639"> + <td class="title" valign="top" align="right"><span class="rank">42.</span></td> <td class="votelinks" valign="top"><center><a id="up_28929639" href="https://news.ycombinator.com/vote?id=28929639&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://owlpal.substack.com/p/about-that-time-i-had-an-outburst" class="titlelink">About that time I had an outburst during the Y Combinator Interview</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=owlpal.substack.com"><span class="sitestr">owlpal.substack.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28929639">498 points</span> by <a href="https://news.ycombinator.com/user?id=curiousowl" class="hnuser">curiousowl</a> <span class="age" title="2021-10-20T12:03:25"><a href="https://news.ycombinator.com/item?id=28929639">1 day ago</a></span> <span id="unv_28929639"></span> | <a href="https://news.ycombinator.com/hide?id=28929639&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28929639">242 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28938378"> + <td class="title" valign="top" align="right"><span class="rank">43.</span></td> <td class="votelinks" valign="top"><center><a id="up_28938378" href="https://news.ycombinator.com/vote?id=28938378&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.guernicamag.com/one-mans-pest/" class="titlelink" rel="nofollow">One Man's Pest</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=guernicamag.com"><span class="sitestr">guernicamag.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28938378">8 points</span> by <a href="https://news.ycombinator.com/user?id=yimby" class="hnuser">yimby</a> <span class="age" title="2021-10-20T23:47:13"><a href="https://news.ycombinator.com/item?id=28938378">6 hours ago</a></span> <span id="unv_28938378"></span> | <a href="https://news.ycombinator.com/hide?id=28938378&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28938378">discuss</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28926582"> + <td class="title" valign="top" align="right"><span class="rank">44.</span></td> <td class="votelinks" valign="top"><center><a id="up_28926582" href="https://news.ycombinator.com/vote?id=28926582&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://brave.com/search-and-web-discovery/" class="titlelink">Brave Search replaces Google as default search engine in the Brave browser</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=brave.com"><span class="sitestr">brave.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28926582">723 points</span> by <a href="https://news.ycombinator.com/user?id=skellertor" class="hnuser">skellertor</a> <span class="age" title="2021-10-20T03:56:51"><a href="https://news.ycombinator.com/item?id=28926582">1 day ago</a></span> <span id="unv_28926582"></span> | <a href="https://news.ycombinator.com/hide?id=28926582&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28926582">528 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28943866"> + <td class="title" valign="top" align="right"><span class="rank">45.</span></td> <td class="votelinks" valign="top"><center><a id="up_28943866" href="https://news.ycombinator.com/vote?id=28943866&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://twitter.com//rashiq/status/1319346264992026624" class="titlelink" rel="nofollow">I reverse engineered mcdonald's internal API</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=twitter.com/rashiq"><span class="sitestr">twitter.com/rashiq</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28943866">3 points</span> by <a href="https://news.ycombinator.com/user?id=graderjs" class="hnuser">graderjs</a> <span class="age" title="2021-10-21T13:11:46"><a href="https://news.ycombinator.com/item?id=28943866">1 hour ago</a></span> <span id="unv_28943866"></span> | <a href="https://news.ycombinator.com/hide?id=28943866&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28943866">discuss</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28936324"> + <td class="title" valign="top" align="right"><span class="rank">46.</span></td> <td class="votelinks" valign="top"><center><a id="up_28936324" href="https://news.ycombinator.com/vote?id=28936324&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.science.org/doi/10.1126/scisignal.abc4764" class="titlelink">Injury response to DNA damage in live tumor cells promotes antitumor immunity</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=science.org"><span class="sitestr">science.org</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28936324">109 points</span> by <a href="https://news.ycombinator.com/user?id=bcaulfield" class="hnuser">bcaulfield</a> <span class="age" title="2021-10-20T20:48:40"><a href="https://news.ycombinator.com/item?id=28936324">17 hours ago</a></span> <span id="unv_28936324"></span> | <a href="https://news.ycombinator.com/hide?id=28936324&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28936324">5 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28940197"> + <td class="title" valign="top" align="right"><span class="rank">47.</span></td> <td class="votelinks" valign="top"><center><a id="up_28940197" href="https://news.ycombinator.com/vote?id=28940197&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.cowin.gov.in/" class="titlelink">India Counting Down to 1B Doses</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=cowin.gov.in"><span class="sitestr">cowin.gov.in</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28940197">105 points</span> by <a href="https://news.ycombinator.com/user?id=neelkadia" class="hnuser">neelkadia</a> <span class="age" title="2021-10-21T04:17:41"><a href="https://news.ycombinator.com/item?id=28940197">10 hours ago</a></span> <span id="unv_28940197"></span> | <a href="https://news.ycombinator.com/hide?id=28940197&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28940197">78 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28943066"> + <td class="title" valign="top" align="right"><span class="rank">48.</span></td> <td class="votelinks" valign="top"><center><a id="up_28943066" href="https://news.ycombinator.com/vote?id=28943066&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://slate.com/technology/2021/10/tether-crypto-danger-ben-mckenzie.html" class="titlelink" rel="nofollow">Time to get worried about Tether, the “stablecoin” at center of cryptocurrency</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=slate.com"><span class="sitestr">slate.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28943066">6 points</span> by <a href="https://news.ycombinator.com/user?id=RickJWagner" class="hnuser">RickJWagner</a> <span class="age" title="2021-10-21T11:45:09"><a href="https://news.ycombinator.com/item?id=28943066">2 hours ago</a></span> <span id="unv_28943066"></span> | <a href="https://news.ycombinator.com/hide?id=28943066&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28943066">5 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28940258"> + <td class="title" valign="top" align="right"><span class="rank">49.</span></td> <td class="votelinks" valign="top"><center><a id="up_28940258" href="https://news.ycombinator.com/vote?id=28940258&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.alifewithoutlimits.com.au/the-history-of-surveying/" class="titlelink">The History of Surveying</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=alifewithoutlimits.com.au"><span class="sitestr">alifewithoutlimits.com.au</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28940258">20 points</span> by <a href="https://news.ycombinator.com/user?id=barbazoo" class="hnuser">barbazoo</a> <span class="age" title="2021-10-21T04:27:11"><a href="https://news.ycombinator.com/item?id=28940258">9 hours ago</a></span> <span id="unv_28940258"></span> | <a href="https://news.ycombinator.com/hide?id=28940258&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28940258">9 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28921244"> + <td class="title" valign="top" align="right"><span class="rank">50.</span></td> <td class="votelinks" valign="top"><center><a id="up_28921244" href="https://news.ycombinator.com/vote?id=28921244&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.npr.org/2021/10/19/1047303559/fda-hearing-aid-prescription-over-the-counter" class="titlelink">The FDA wants you to be able to buy a hearing aid without a prescription</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=npr.org"><span class="sitestr">npr.org</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28921244">722 points</span> by <a href="https://news.ycombinator.com/user?id=cf100clunk" class="hnuser">cf100clunk</a> <span class="age" title="2021-10-19T17:58:42"><a href="https://news.ycombinator.com/item?id=28921244">1 day ago</a></span> <span id="unv_28921244"></span> | <a href="https://news.ycombinator.com/hide?id=28921244&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28921244">441 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28942594"> + <td class="title" valign="top" align="right"><span class="rank">51.</span></td> <td class="votelinks" valign="top"><center><a id="up_28942594" href="https://news.ycombinator.com/vote?id=28942594&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.pcgamer.com/windows-11-pcs-can-hobble-gaming-performance/" class="titlelink">Windows 11 will hobble gaming performance by default on some prebuilt PCs</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=pcgamer.com"><span class="sitestr">pcgamer.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28942594">13 points</span> by <a href="https://news.ycombinator.com/user?id=DeathArrow" class="hnuser">DeathArrow</a> <span class="age" title="2021-10-21T10:33:39"><a href="https://news.ycombinator.com/item?id=28942594">3 hours ago</a></span> <span id="unv_28942594"></span> | <a href="https://news.ycombinator.com/hide?id=28942594&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28942594">3 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28940705"> + <td class="title" valign="top" align="right"><span class="rank">52.</span></td> <td class="votelinks" valign="top"><center><a id="up_28940705" href="https://news.ycombinator.com/vote?id=28940705&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.gimp.org/news/2021/10/20/gimp-2-99-8-released/" class="titlelink">Development version: GIMP 2.99.8 Released</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=gimp.org"><span class="sitestr">gimp.org</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28940705">19 points</span> by <a href="https://news.ycombinator.com/user?id=pauloxnet" class="hnuser">pauloxnet</a> <span class="age" title="2021-10-21T05:33:20"><a href="https://news.ycombinator.com/item?id=28940705">8 hours ago</a></span> <span id="unv_28940705"></span> | <a href="https://news.ycombinator.com/hide?id=28940705&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28940705">2 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28903383"> + <td class="title" valign="top" align="right"><span class="rank">53.</span></td> <td class="votelinks" valign="top"><center><a id="up_28903383" href="https://news.ycombinator.com/vote?id=28903383&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://mikolaj-kaminski.com/jetbrains-rider-docker-compose-unicodedecodeerror-issue-fix/" class="titlelink">I couldn't debug the code because of my name</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=mikolaj-kaminski.com"><span class="sitestr">mikolaj-kaminski.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28903383">247 points</span> by <a href="https://news.ycombinator.com/user?id=mikasjp" class="hnuser">mikasjp</a> <span class="age" title="2021-10-18T08:40:39"><a href="https://news.ycombinator.com/item?id=28903383">23 hours ago</a></span> <span id="unv_28903383"></span> | <a href="https://news.ycombinator.com/hide?id=28903383&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28903383">268 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28937484"> + <td class="title" valign="top" align="right"><span class="rank">54.</span></td> <td class="votelinks" valign="top"><center><a id="up_28937484" href="https://news.ycombinator.com/vote?id=28937484&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://calbryant.uk/blog/10-ways-to-get-the-best-out-of-openscad/" class="titlelink">Getting the best out of OpenSCAD</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=calbryant.uk"><span class="sitestr">calbryant.uk</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28937484">109 points</span> by <a href="https://news.ycombinator.com/user?id=naggie" class="hnuser">naggie</a> <span class="age" title="2021-10-20T22:13:20"><a href="https://news.ycombinator.com/item?id=28937484">16 hours ago</a></span> <span id="unv_28937484"></span> | <a href="https://news.ycombinator.com/hide?id=28937484&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28937484">52 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28921083"> + <td class="title" valign="top" align="right"><span class="rank">55.</span></td> <td class="votelinks" valign="top"><center><a id="up_28921083" href="https://news.ycombinator.com/vote?id=28921083&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://spectrum.ieee.org/recycled-batteries-good-as-newly-mined" class="titlelink">Study: Recycled Lithium Batteries as Good as Newly Mined</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=ieee.org"><span class="sitestr">ieee.org</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28921083">623 points</span> by <a href="https://news.ycombinator.com/user?id=mpweiher" class="hnuser">mpweiher</a> <span class="age" title="2021-10-19T17:45:07"><a href="https://news.ycombinator.com/item?id=28921083">1 day ago</a></span> <span id="unv_28921083"></span> | <a href="https://news.ycombinator.com/hide?id=28921083&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28921083">179 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28934715"> + <td class="title" valign="top" align="right"><span class="rank">56.</span></td> <td class="votelinks" valign="top"><center><a id="up_28934715" href="https://news.ycombinator.com/vote?id=28934715&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://americasfuture.org/eliminating-gifted-programs-wont-make-education-fair/" class="titlelink">Eliminating gifted programs won’t make education fair</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=americasfuture.org"><span class="sitestr">americasfuture.org</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28934715">180 points</span> by <a href="https://news.ycombinator.com/user?id=paulpauper" class="hnuser">paulpauper</a> <span class="age" title="2021-10-20T19:03:44"><a href="https://news.ycombinator.com/item?id=28934715">19 hours ago</a></span> <span id="unv_28934715"></span> | <a href="https://news.ycombinator.com/hide?id=28934715&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28934715">400 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28939407"> + <td class="title" valign="top" align="right"><span class="rank">57.</span></td> <td class="votelinks" valign="top"><center><a id="up_28939407" href="https://news.ycombinator.com/vote?id=28939407&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://github.com/ToshioCP/Gtk4-tutorial/blob/main/Readme.md" class="titlelink">Gtk4 Tutorial</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=github.com/toshiocp"><span class="sitestr">github.com/toshiocp</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28939407">53 points</span> by <a href="https://news.ycombinator.com/user?id=marcodiego" class="hnuser">marcodiego</a> <span class="age" title="2021-10-21T01:59:18"><a href="https://news.ycombinator.com/item?id=28939407">12 hours ago</a></span> <span id="unv_28939407"></span> | <a href="https://news.ycombinator.com/hide?id=28939407&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28939407">73 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28940334"> + <td class="title" valign="top" align="right"><span class="rank">58.</span></td> <td class="votelinks" valign="top"><center><a id="up_28940334" href="https://news.ycombinator.com/vote?id=28940334&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://obua.com/publications/cosmo-id/3/" class="titlelink" rel="nofollow">Cosmopolitan Identifiers</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=obua.com"><span class="sitestr">obua.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28940334">10 points</span> by <a href="https://news.ycombinator.com/user?id=BeefySwain" class="hnuser">BeefySwain</a> <span class="age" title="2021-10-21T04:39:41"><a href="https://news.ycombinator.com/item?id=28940334">9 hours ago</a></span> <span id="unv_28940334"></span> | <a href="https://news.ycombinator.com/hide?id=28940334&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28940334">2 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28929840"> + <td class="title" valign="top" align="right"><span class="rank">59.</span></td> <td class="votelinks" valign="top"><center><a id="up_28929840" href="https://news.ycombinator.com/vote?id=28929840&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://madned.substack.com/p/a-talk-with-computer-gaming-pioneer" class="titlelink">A talk with Walter Bright about Empire</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=madned.substack.com"><span class="sitestr">madned.substack.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28929840">218 points</span> by <a href="https://news.ycombinator.com/user?id=mad_ned" class="hnuser">mad_ned</a> <span class="age" title="2021-10-20T12:29:16"><a href="https://news.ycombinator.com/item?id=28929840">1 day ago</a></span> <span id="unv_28929840"></span> | <a href="https://news.ycombinator.com/hide?id=28929840&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28929840">86 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="athing" id="28934833"> + <td class="title" valign="top" align="right"><span class="rank">60.</span></td> <td class="votelinks" valign="top"><center><a id="up_28934833" href="https://news.ycombinator.com/vote?id=28934833&how=up&goto=news%3Fp%3D2"><div class="votearrow" title="upvote"></div></a></center></td><td class="title"><a href="https://www.youtube.com/watch?v=NjrYk546uBA" class="titlelink">Bioelektryczność – Polish Robotics (1968) [video]</a><span class="sitebit comhead"> (<a href="https://news.ycombinator.com/from?site=youtube.com"><span class="sitestr">youtube.com</span></a>)</span></td></tr><tr><td colspan="2"></td><td class="subtext"> + <span class="score" id="score_28934833">123 points</span> by <a href="https://news.ycombinator.com/user?id=danielEM" class="hnuser">danielEM</a> <span class="age" title="2021-10-20T19:11:59"><a href="https://news.ycombinator.com/item?id=28934833">19 hours ago</a></span> <span id="unv_28934833"></span> | <a href="https://news.ycombinator.com/hide?id=28934833&goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28934833">27 comments</a> </td></tr> + <tr class="spacer" style="height:5px"></tr> + <tr class="morespace" style="height:10px"></tr><tr><td colspan="2"></td><td class="title"><a href="https://news.ycombinator.com/news?p=3" class="morelink" rel="next">More</a></td></tr> + </tbody></table> +</td></tr> +<tr><td><img src="02_files/s.gif" width="0" height="10"><table width="100%" cellspacing="0" cellpadding="1"><tbody><tr><td bgcolor="#ff6600"></td></tr></tbody></table><br><center><span class="yclinks"><a href="https://news.ycombinator.com/newsguidelines.html">Guidelines</a> + | <a href="https://news.ycombinator.com/newsfaq.html">FAQ</a> + | <a href="https://news.ycombinator.com/lists">Lists</a> + | <a href="https://github.com/HackerNews/API">API</a> + | <a href="https://news.ycombinator.com/security.html">Security</a> + | <a href="http://www.ycombinator.com/legal/">Legal</a> + | <a href="http://www.ycombinator.com/apply/">Apply to YC</a> + | <a href="mailto:hn@ycombinator.com">Contact</a></span><br><br><form method="get" action="//hn.algolia.com/">Search: + <input type="text" name="q" size="17" autocorrect="off" spellcheck="false" autocapitalize="none" autocomplete="false"></form> + </center></td></tr> + </tbody></table></center><script type="text/javascript" src="02_files/hn.js"></script> +</body></html>
\ No newline at end of file diff --git a/graphs/piscine/hacker_news/news.sed b/graphs/piscine/hacker_news/news.sed new file mode 100644 index 0000000..91b76d6 --- /dev/null +++ b/graphs/piscine/hacker_news/news.sed @@ -0,0 +1 @@ +s/^.*"\(https\?:\/\/.*\)" class="titlelink"\( rel="nofollow"\)\?>\([^<]*\).*$/**\3**\n\1\n/p diff --git a/graphs/piscine/hacker_news/output.txt b/graphs/piscine/hacker_news/output.txt new file mode 100644 index 0000000..68cc714 --- /dev/null +++ b/graphs/piscine/hacker_news/output.txt @@ -0,0 +1,90 @@ +**Sinclair Broadcast Group identifies data breach** +https://apnews.com/article/technology-business-arts-and-entertainment-be48d7582fdd5604664fff33ed81ca80 + +**A gentle introduction to the FFT (2002)** +https://www.earlevel.com/main/2002/08/31/a-gentle-introduction-to-the-fft/ + +**Jon Ingold on translating archeology into video games** +https://thebrowser.com/notes/jon-ingold/ + +**Ask HN: How to Sell a Website** +https://news.ycombinator.com/item?id=28943611 + +**We analyzed 425k favicons** +https://iconmap.io/blog + +**Machu Picchu was built over major fault zones (2019)** +https://www.science.org/content/article/machu-picchu-was-built-over-major-fault-zones-now-researchers-think-they-know-why + +**Goggles: Democracy dies in darkness, and so does the Web [pdf]** +https://brave.com/wp-content/uploads/2021/03/goggles.pdf + +**Apple M1 Max Geekbench Score** +https://browser.geekbench.com/v5/cpu/10496766 + +**U.S. tightens export controls on items used in surveillance of private citizens** +https://www.commerce.gov/news/press-releases/2021/10/commerce-tightens-export-controls-items-used-surveillance-private + +**WeWork is trying to go public – again** +https://www.wsj.com/articles/wework-set-to-go-public-via-spac-deal-two-years-after-failed-ipo-11634808600 + +**Playstation 3 Architecture** +https://www.copetti.org/writings/consoles/playstation-3/ + +**About that time I had an outburst during the Y Combinator Interview** +https://owlpal.substack.com/p/about-that-time-i-had-an-outburst + +**One Man's Pest** +https://www.guernicamag.com/one-mans-pest/ + +**Brave Search replaces Google as default search engine in the Brave browser** +https://brave.com/search-and-web-discovery/ + +**I reverse engineered mcdonald's internal API** +https://twitter.com//rashiq/status/1319346264992026624 + +**Injury response to DNA damage in live tumor cells promotes antitumor immunity** +https://www.science.org/doi/10.1126/scisignal.abc4764 + +**India Counting Down to 1B Doses** +https://www.cowin.gov.in/ + +**Time to get worried about Tether, the “stablecoin” at center of cryptocurrency** +https://slate.com/technology/2021/10/tether-crypto-danger-ben-mckenzie.html + +**The History of Surveying** +https://www.alifewithoutlimits.com.au/the-history-of-surveying/ + +**The FDA wants you to be able to buy a hearing aid without a prescription** +https://www.npr.org/2021/10/19/1047303559/fda-hearing-aid-prescription-over-the-counter + +**Windows 11 will hobble gaming performance by default on some prebuilt PCs** +https://www.pcgamer.com/windows-11-pcs-can-hobble-gaming-performance/ + +**Development version: GIMP 2.99.8 Released** +https://www.gimp.org/news/2021/10/20/gimp-2-99-8-released/ + +**I couldn't debug the code because of my name** +https://mikolaj-kaminski.com/jetbrains-rider-docker-compose-unicodedecodeerror-issue-fix/ + +**Getting the best out of OpenSCAD** +https://calbryant.uk/blog/10-ways-to-get-the-best-out-of-openscad/ + +**Study: Recycled Lithium Batteries as Good as Newly Mined** +https://spectrum.ieee.org/recycled-batteries-good-as-newly-mined + +**Eliminating gifted programs won’t make education fair** +https://americasfuture.org/eliminating-gifted-programs-wont-make-education-fair/ + +**Gtk4 Tutorial** +https://github.com/ToshioCP/Gtk4-tutorial/blob/main/Readme.md + +**Cosmopolitan Identifiers** +https://obua.com/publications/cosmo-id/3/ + +**A talk with Walter Bright about Empire** +https://madned.substack.com/p/a-talk-with-computer-gaming-pioneer + +**Bioelektryczność – Polish Robotics (1968) [video]** +https://www.youtube.com/watch?v=NjrYk546uBA + diff --git a/graphs/piscine/handling_complex/complex.c b/graphs/piscine/handling_complex/complex.c new file mode 100644 index 0000000..79a10be --- /dev/null +++ b/graphs/piscine/handling_complex/complex.c @@ -0,0 +1,51 @@ +#include "complex.h" + +#include <stdio.h> + +void print_complex(struct complex a) +{ + printf("complex(%.2f ", a.real); + + if (a.img < 0) + { + printf("- %.2fi", -a.img); + } + else + { + printf("+ %.2fi", a.img); + } + printf(")\n"); +} + +struct complex neg_complex(struct complex a) +{ + struct complex z = { -a.real, -a.img }; + return z; +} + +struct complex add_complex(struct complex a, struct complex b) +{ + struct complex z = { a.real + b.real, a.img + b.img }; + return z; +} + +struct complex sub_complex(struct complex a, struct complex b) +{ + return add_complex(a, neg_complex(b)); +} + +struct complex mul_complex(struct complex a, struct complex b) +{ + struct complex z = { a.real * b.real - a.img * b.img, + a.real * b.img + a.img * b.real }; + return z; +} + +struct complex div_complex(struct complex a, struct complex b) +{ + struct complex z = { + (a.real * b.real + a.img * b.img) / (b.real * b.real + b.img * b.img), + (a.img * b.real - a.real * b.img) / (b.real * b.real + b.img * b.img) + }; + return z; +} diff --git a/graphs/piscine/handling_complex/complex.h b/graphs/piscine/handling_complex/complex.h new file mode 100644 index 0000000..c562810 --- /dev/null +++ b/graphs/piscine/handling_complex/complex.h @@ -0,0 +1,20 @@ +#ifndef COMPLEX_H +#define COMPLEX_H + +struct complex +{ + float real; + float img; +}; + +// Print +void print_complex(struct complex a); + +// Operations +struct complex neg_complex(struct complex a); +struct complex add_complex(struct complex a, struct complex b); +struct complex sub_complex(struct complex a, struct complex b); +struct complex mul_complex(struct complex a, struct complex b); +struct complex div_complex(struct complex a, struct complex b); + +#endif /* !COMPLEX_H */ diff --git a/graphs/piscine/hanoi/hanoi.c b/graphs/piscine/hanoi/hanoi.c new file mode 100644 index 0000000..6ac2b71 --- /dev/null +++ b/graphs/piscine/hanoi/hanoi.c @@ -0,0 +1,31 @@ +#include <stdio.h> + +void move(unsigned src, unsigned spare, unsigned dst, unsigned n) +{ + if (n == 0) + { + return; + } + + move(src, dst, spare, n - 1); + + printf("%u->%u\n", src, dst); + + move(spare, src, dst, n - 1); +} + +void hanoi(unsigned n) +{ + if (n == 0) + { + return; + } + + move(1, 2, 3, n); +} + +int main(void) +{ + hanoi(3); + return 0; +} diff --git a/graphs/piscine/hash_map/hash.c b/graphs/piscine/hash_map/hash.c new file mode 100644 index 0000000..434616f --- /dev/null +++ b/graphs/piscine/hash_map/hash.c @@ -0,0 +1,13 @@ +#include <stddef.h> + +size_t hash(const char *key) +{ + size_t i = 0; + size_t hash = 0; + + for (i = 0; key[i] != '\0'; ++i) + hash += key[i]; + hash += i; + + return hash; +} diff --git a/graphs/piscine/hash_map/hash_map.c b/graphs/piscine/hash_map/hash_map.c new file mode 100644 index 0000000..4690e8b --- /dev/null +++ b/graphs/piscine/hash_map/hash_map.c @@ -0,0 +1,177 @@ +#include "hash_map.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +struct hash_map *hash_map_init(size_t size) +{ + struct hash_map *new; + if ((new = malloc(sizeof(struct hash_map))) == NULL) + { + return NULL; + } + if ((new->data = malloc(size * sizeof(struct pair_list *))) == NULL) + { + return NULL; + } + new->size = size; + + for (size_t i = 0; i < size; i++) + { + new->data[i] = NULL; + } + + return new; +} + +bool hash_map_insert(struct hash_map *hash_map, const char *key, char *value, + bool *updated) +{ + if (hash_map == NULL || updated == NULL || hash_map->size == 0) + { + return false; + } + *updated = false; + + size_t h = hash(key); + if (h >= hash_map->size) + { + h %= hash_map->size; + } + + struct pair_list *new = malloc(sizeof(struct pair_list)); + if (new == NULL) + { + return false; + } + + for (struct pair_list *p = hash_map->data[h]; p; p = p->next) + { + if (strcmp(p->key, key) == 0) + { + p->value = value; + *updated = true; + free(new); + return true; + } + } + + new->next = hash_map->data[h]; + new->key = key; + new->value = value; + hash_map->data[h] = new; + return true; +} + +void hash_map_free(struct hash_map *hash_map) +{ + if (hash_map == NULL) + { + return; + } + + if (hash_map->data == NULL) + { + free(hash_map); + return; + } + + for (size_t i = 0; i < hash_map->size; i++) + { + while (hash_map->data[i]) + { + struct pair_list *tmp = hash_map->data[i]->next; + free(hash_map->data[i]); + hash_map->data[i] = tmp; + } + } + + free(hash_map->data); + free(hash_map); +} + +void hash_map_dump(struct hash_map *hash_map) +{ + if (hash_map == NULL || hash_map->data == NULL) + { + return; + } + + for (size_t i = 0; i < hash_map->size; i++) + { + if (hash_map->data[i] != NULL) + { + printf("%s: %s", hash_map->data[i]->key, hash_map->data[i]->value); + for (struct pair_list *p = hash_map->data[i]->next; p; p = p->next) + { + printf(", %s: %s", p->key, p->value); + } + printf("\n"); + } + } +} + +const char *hash_map_get(const struct hash_map *hash_map, const char *key) +{ + if (hash_map == NULL || hash_map->data == NULL || hash_map->size == 0) + { + return NULL; + } + + size_t h = hash(key); + if (h >= hash_map->size) + { + h %= hash_map->size; + } + struct pair_list *p; + for (p = hash_map->data[h]; p && strcmp(p->key, key) != 0; p = p->next) + { + continue; + } + + if (p) + { + return p->value; + } + return NULL; +} + +bool hash_map_remove(struct hash_map *hash_map, const char *key) +{ + if (hash_map == NULL || hash_map->data == NULL || hash_map->size == 0) + { + return false; + } + + size_t h = hash(key); + if (h >= hash_map->size) + { + h %= hash_map->size; + } + if (hash_map->data[h] == NULL) + { + return false; + } + + if (strcmp(hash_map->data[h]->key, key) == 0) + { + struct pair_list *tmp = hash_map->data[h]->next; + free(hash_map->data[h]); + hash_map->data[h] = tmp; + return true; + } + + struct pair_list *p; + for (p = hash_map->data[h]; p->next; p = p->next) + { + if (strcmp(p->next->key, key) == 0) + { + struct pair_list *tmp = p->next->next; + free(p->next); + p->next = tmp; + return true; + } + } + return false; +} diff --git a/graphs/piscine/hash_map/hash_map.h b/graphs/piscine/hash_map/hash_map.h new file mode 100644 index 0000000..c731eab --- /dev/null +++ b/graphs/piscine/hash_map/hash_map.h @@ -0,0 +1,29 @@ +#ifndef HASH_MAP_H +#define HASH_MAP_H + +#include <stdbool.h> +#include <stddef.h> + +struct pair_list +{ + const char *key; + char *value; + struct pair_list *next; +}; + +struct hash_map +{ + struct pair_list **data; + size_t size; +}; + +size_t hash(const char *str); +struct hash_map *hash_map_init(size_t size); +bool hash_map_insert(struct hash_map *hash_map, const char *key, char *value, + bool *updated); +void hash_map_free(struct hash_map *hash_map); +void hash_map_dump(struct hash_map *hash_map); +const char *hash_map_get(const struct hash_map *hash_map, const char *key); +bool hash_map_remove(struct hash_map *hash_map, const char *key); + +#endif /* ! HASH_MAP_H */ diff --git a/graphs/piscine/heap/Makefile b/graphs/piscine/heap/Makefile new file mode 100644 index 0000000..2ed972b --- /dev/null +++ b/graphs/piscine/heap/Makefile @@ -0,0 +1,14 @@ +CC = gcc +CFLAGS = -Wall -Werror -Wvla -Wextra -std=c99 -pedantic +SRC = add.c del.c print.c pop.c create.c +OBJ = $(SRC:.c=.o) + +.PHONY: library clean + +library: $(OBJ) + ar csr libheap.a $(OBJ) + +$(OBJ): $(SRC) + +clean: + $(RM) libheap.a $(OBJ) diff --git a/graphs/piscine/heap/add.c b/graphs/piscine/heap/add.c new file mode 100644 index 0000000..78a4db8 --- /dev/null +++ b/graphs/piscine/heap/add.c @@ -0,0 +1,39 @@ +#include <stdlib.h> + +#include "heap.h" + +void heapify(int arr[], int n, int i) +{ + if (i == 0) + return; + int parent = (i - 1) / 2; + if (parent >= 0) + { + if (arr[i] > arr[parent]) + { + int tmp = arr[i]; + arr[i] = arr[parent]; + arr[parent] = tmp; + heapify(arr, n, parent); + } + } +} + +void add(struct heap *heap, int val) +{ + if (heap->size == heap->capacity) + { + heap->array = realloc(heap->array, heap->capacity * 2 * sizeof(int)); + if (heap->array == NULL) + { + free(heap); + return; + } + heap->capacity *= 2; + } + + heap->array[heap->size] = val; + heap->size++; + + heapify(heap->array, heap->size, heap->size - 1); +} diff --git a/graphs/piscine/heap/create.c b/graphs/piscine/heap/create.c new file mode 100644 index 0000000..f0675ad --- /dev/null +++ b/graphs/piscine/heap/create.c @@ -0,0 +1,19 @@ +#include <stdlib.h> + +#include "heap.h" + +struct heap *create_heap(void) +{ + struct heap *res = malloc(sizeof(struct heap)); + if (res == NULL) + return NULL; + res->size = 0; + res->capacity = 8; + res->array = malloc(8 * sizeof(int)); + if (res->array == NULL) + { + free(res); + return NULL; + } + return res; +} diff --git a/graphs/piscine/heap/del.c b/graphs/piscine/heap/del.c new file mode 100644 index 0000000..4d2ae35 --- /dev/null +++ b/graphs/piscine/heap/del.c @@ -0,0 +1,9 @@ +#include <stdlib.h> + +#include "heap.h" + +void delete_heap(struct heap *heap) +{ + free(heap->array); + free(heap); +} diff --git a/graphs/piscine/heap/heap.h b/graphs/piscine/heap/heap.h new file mode 100644 index 0000000..085f436 --- /dev/null +++ b/graphs/piscine/heap/heap.h @@ -0,0 +1,20 @@ +#ifndef HEAP_H +#define HEAP_H + +// size_t +#include <stddef.h> + +struct heap +{ + size_t size; + size_t capacity; + int *array; +}; + +struct heap *create_heap(void); +void add(struct heap *heap, int val); +int pop(struct heap *heap); +void delete_heap(struct heap *heap); +void print_heap(const struct heap *heap); + +#endif /* !HEAP_H */ diff --git a/graphs/piscine/heap/pop.c b/graphs/piscine/heap/pop.c new file mode 100644 index 0000000..55e063f --- /dev/null +++ b/graphs/piscine/heap/pop.c @@ -0,0 +1,49 @@ +#include <assert.h> +#include <stdlib.h> + +#include "heap.h" + +void heapify2(struct heap *h, size_t i) +{ + size_t max = i; + if (2 * i + 1 < h->size && h->array[2 * i + 1] > h->array[max]) + max = 2 * i + 1; + if (2 * i + 2 < h->size && h->array[2 * i + 2] > h->array[max]) + max = 2 * i + 2; + if (max != i) + { + int tmp = h->array[i]; + h->array[i] = h->array[max]; + h->array[max] = tmp; + heapify2(h, max); + } +} + +int pop(struct heap *heap) +{ + assert(heap->size != 0); + if (heap->size == 1) + { + heap->size--; + return heap->array[0]; + } + else + { + int res = heap->array[0]; + heap->array[0] = heap->array[heap->size - 1]; + heap->size--; + heapify2(heap, 0); + if (heap->size < heap->capacity / 2 && heap->capacity > 8) + { + heap->array = + realloc(heap->array, (heap->capacity / 2) * sizeof(int)); + if (heap->array == NULL) + { + free(heap); + return -1; + } + heap->capacity /= 2; + } + return res; + } +} diff --git a/graphs/piscine/heap/print.c b/graphs/piscine/heap/print.c new file mode 100644 index 0000000..f5bbe95 --- /dev/null +++ b/graphs/piscine/heap/print.c @@ -0,0 +1,27 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "heap.h" + +void print_rec(const struct heap *h, size_t i, int root) +{ + if (i >= h->size) + return; + if (!root) + printf(" "); + else + root = 0; + printf("%d", h->array[i]); + if (i == h->size - 1) + { + return; + } + print_rec(h, i * 2 + 1, root); + print_rec(h, i * 2 + 2, root); +} + +void print_heap(const struct heap *heap) +{ + print_rec(heap, 0, 1); + printf("\n"); +} diff --git a/graphs/piscine/hello_friends/hello.c b/graphs/piscine/hello_friends/hello.c new file mode 100644 index 0000000..63df2f1 --- /dev/null +++ b/graphs/piscine/hello_friends/hello.c @@ -0,0 +1,13 @@ +#include <stdio.h> + +int main(int argc, char **argv) +{ + if (argc == 1) + printf("Hello World!\n"); + else + for (int i = 1; i < argc; i++) + { + printf("Hello %s!\n", argv[i]); + } + return 0; +} diff --git a/graphs/piscine/hello_world/hello.c b/graphs/piscine/hello_world/hello.c new file mode 100644 index 0000000..0681c18 --- /dev/null +++ b/graphs/piscine/hello_world/hello.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main(void) +{ + puts("Hello World!"); + return 0; +} diff --git a/graphs/piscine/hello_world_shebang/hello.sh b/graphs/piscine/hello_world_shebang/hello.sh new file mode 100755 index 0000000..8dc4f64 --- /dev/null +++ b/graphs/piscine/hello_world_shebang/hello.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Hello World!" diff --git a/graphs/piscine/hill_array/hill_array.c b/graphs/piscine/hill_array/hill_array.c new file mode 100644 index 0000000..14d3a85 --- /dev/null +++ b/graphs/piscine/hill_array/hill_array.c @@ -0,0 +1,43 @@ +#include "hill_array.h" + +int top_of_the_hill(int tab[], size_t len) +{ + if (len == 0) + { + return -1; + } + + int top = 0; + size_t i = 0; + + while (i + 1 < len && tab[i] <= tab[i + 1]) + { + if (tab[i] < 0 || tab[i + 1] < 0) + { + return -1; + } + if (tab[i] != tab[i + 1]) + { + top = i + 1; + } + i++; + } + + while (i + 1 < len && tab[i] >= tab[i + 1]) + { + if (tab[i] < 0 || tab[i + 1] < 0) + { + return -1; + } + i++; + } + + if (i + 1 == len) + { + return top; + } + else + { + return -1; + } +} diff --git a/graphs/piscine/hill_array/hill_array.h b/graphs/piscine/hill_array/hill_array.h new file mode 100644 index 0000000..3152c19 --- /dev/null +++ b/graphs/piscine/hill_array/hill_array.h @@ -0,0 +1,8 @@ +#ifndef HILL_ARRAY_H +#define HILL_ARRAY_H + +#include <stddef.h> + +int top_of_the_hill(int tab[], size_t len); + +#endif /* !HILL_ARRAY_H */ diff --git a/graphs/piscine/insertion_sort/insertion_sort.c b/graphs/piscine/insertion_sort/insertion_sort.c new file mode 100644 index 0000000..2edd195 --- /dev/null +++ b/graphs/piscine/insertion_sort/insertion_sort.c @@ -0,0 +1,20 @@ +#include "insertion_sort.h" + +#include <stddef.h> + +void insertion_sort(void **array, f_cmp comp) +{ + if (array == NULL || *array == NULL) + { + return; + } + for (int i = 1; array[i]; i++) + { + for (int j = i; j > 0 && comp(array[j - 1], array[j]) > 0; j--) + { + void *tmp = array[j]; + array[j] = array[j - 1]; + array[j - 1] = tmp; + } + } +} diff --git a/graphs/piscine/insertion_sort/insertion_sort.h b/graphs/piscine/insertion_sort/insertion_sort.h new file mode 100644 index 0000000..a7ba674 --- /dev/null +++ b/graphs/piscine/insertion_sort/insertion_sort.h @@ -0,0 +1,8 @@ +#ifndef INSERTION_SORT_H +#define INSERTION_SORT_H + +typedef int (*f_cmp)(const void *, const void *); + +void insertion_sort(void **array, f_cmp comp); + +#endif /* ! INSERTION_SORT_H */ diff --git a/graphs/piscine/inside/inside.sh b/graphs/piscine/inside/inside.sh new file mode 100755 index 0000000..c6872fa --- /dev/null +++ b/graphs/piscine/inside/inside.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +if [ $# -ne 1 ]; then + echo Sorry, expected 1 argument but $# were passed + exit 1 +fi + +if [ -f $1 ]; then + cat $1 + exit 0 +else + echo "$1: + is not a valid file" + exit 2 +fi diff --git a/graphs/piscine/inside_noif/inside_noif.sh b/graphs/piscine/inside_noif/inside_noif.sh new file mode 100755 index 0000000..d4ed8c9 --- /dev/null +++ b/graphs/piscine/inside_noif/inside_noif.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +[ $# -ne 1 ] && echo Sorry, expected 1 argument but $# were passed && exit 1 + +[ -f $1 ] && cat $1 && exit 0 || echo "$1: + is not a valid file" && exit 2 diff --git a/graphs/piscine/int_palindrome/int_palindrome.c b/graphs/piscine/int_palindrome/int_palindrome.c new file mode 100644 index 0000000..6d6847f --- /dev/null +++ b/graphs/piscine/int_palindrome/int_palindrome.c @@ -0,0 +1,18 @@ +int int_palindrome(int n) +{ + if (n < 0) + { + return 0; + } + + int reversed = 0; + int m = n; + + while (m > 0) + { + reversed = reversed * 10 + m % 10; + m /= 10; + } + + return n == reversed; +} diff --git a/graphs/piscine/int_sqrt/int_sqrt.c b/graphs/piscine/int_sqrt/int_sqrt.c new file mode 100644 index 0000000..4b2e5db --- /dev/null +++ b/graphs/piscine/int_sqrt/int_sqrt.c @@ -0,0 +1,20 @@ +int int_sqrt(int n) +{ + if (n < 0) + { + return -1; + } + + if (n == 0 || n == 1) + { + return n; + } + + int i; + for (i = 1; i * i < n; i++) + { + continue; + } + + return i - (i * i != n); +} diff --git a/graphs/piscine/io_count_words/count_words.c b/graphs/piscine/io_count_words/count_words.c new file mode 100644 index 0000000..8b8c9a5 --- /dev/null +++ b/graphs/piscine/io_count_words/count_words.c @@ -0,0 +1,33 @@ +#include <stdio.h> + +int count_words(const char *file_in) +{ + if (file_in == NULL) + { + return -1; + } + + FILE *f = fopen(file_in, "r"); + if (f == NULL) + { + return -1; + } + + int word = 0; + int count = 0; + int c; + while ((c = fgetc(f)) != EOF) + { + if ((c == ' ' || c == '\n' || c == '\t') && word == 1) + { + word = 0; + } + if (c != ' ' && c != '\n' && c != '\t' && word == 0) + { + word = 1; + count++; + } + } + + return count; +} diff --git a/graphs/piscine/io_merge_files/merge_files.c b/graphs/piscine/io_merge_files/merge_files.c new file mode 100644 index 0000000..26ac9cf --- /dev/null +++ b/graphs/piscine/io_merge_files/merge_files.c @@ -0,0 +1,31 @@ +#define _POSIX_C_SOURCE 200809L + +#include <stdio.h> + +int merge_files(const char *file_1, const char *file_2) +{ + FILE *a = fopen(file_1, "a"); + if (a == NULL) + { + return -1; + } + FILE *r = fopen(file_2, "r"); + if (r == NULL) + { + return -1; + } + + int c; + while ((c = fgetc(r)) != EOF) + { + if (fputc(c, a) == EOF) + { + return -1; + } + } + + fclose(a); + fclose(r); + + return 0; +} diff --git a/graphs/piscine/io_replace_line/replace_line.c b/graphs/piscine/io_replace_line/replace_line.c new file mode 100644 index 0000000..7fd0e2a --- /dev/null +++ b/graphs/piscine/io_replace_line/replace_line.c @@ -0,0 +1,50 @@ +#define _POSIX_C_SOURCE 200809L + +#include <stdio.h> +#include <stdlib.h> + +int replace_line(const char *file_in, const char *file_out, const char *content, + int n) +{ + FILE *a = fopen(file_out, "w"); + if (a == NULL) + { + return -1; + } + FILE *r = fopen(file_in, "r"); + if (r == NULL) + { + return -1; + } + + char *buf = NULL; + ssize_t e; + int l = 0; + size_t count = 0; + while ((e = getline(&buf, &count, r)) != 0 && e != -1) + { + if (l == n) + { + if (fputs(content, a) == EOF) + { + free(buf); + return -1; + } + } + else + { + if (fputs(buf, a) == EOF) + { + free(buf); + return -1; + } + } + l++; + } + + fclose(a); + fclose(r); + free(buf); + + return 0; +} diff --git a/graphs/piscine/levenshtein/levenshtein.c b/graphs/piscine/levenshtein/levenshtein.c new file mode 100644 index 0000000..4da9397 --- /dev/null +++ b/graphs/piscine/levenshtein/levenshtein.c @@ -0,0 +1,72 @@ +#include "levenshtein.h" + +#include <stdio.h> + +size_t max(size_t a, size_t b) +{ + if (a >= b) + { + return a; + } + return b; +} + +size_t min(size_t a, size_t b) +{ + if (a <= b) + { + return a; + } + return b; +} + +size_t min_3(size_t a, size_t b, size_t c) +{ + if (a <= b) + { + if (a <= c) + { + return a; + } + return c; + } + else + { + if (b <= c) + { + return b; + } + return c; + } +} + +size_t my_strlen(const char *s) +{ + size_t i; + for (i = 0; s[i]; i++) + { + continue; + } + return i; +} + +size_t levenshtein(const char *s1, const char *s2) +{ + size_t l1 = my_strlen(s1); + size_t l2 = my_strlen(s2); + if (min(l1, l2) == 0) + { + return max(l1, l2); + } + + if (s1[0] == s2[0]) + { + return levenshtein(s1 + 1, s2 + 1); + } + + size_t lev1 = levenshtein(s1 + 1, s2); + size_t lev2 = levenshtein(s1, s2 + 1); + size_t lev3 = levenshtein(s1 + 1, s2 + 1); + + return 1 + min_3(lev1, lev2, lev3); +} diff --git a/graphs/piscine/levenshtein/levenshtein.h b/graphs/piscine/levenshtein/levenshtein.h new file mode 100644 index 0000000..70a5a7b --- /dev/null +++ b/graphs/piscine/levenshtein/levenshtein.h @@ -0,0 +1,8 @@ +#ifndef LEVENSHTEIN_H +#define LEVENSHTEIN_H + +#include <stddef.h> + +size_t levenshtein(const char *s1, const char *s2); + +#endif /* !LEVENSHTEIN_H */ diff --git a/graphs/piscine/main.c b/graphs/piscine/main.c new file mode 100644 index 0000000..4062426 --- /dev/null +++ b/graphs/piscine/main.c @@ -0,0 +1,15 @@ +#include <stdio.h> +#include <stdlib.h> + +//#include "traffic_lights/traffic_lights.h" +unsigned char rol(unsigned char value, unsigned char roll); + +int main(void) +{ + unsigned char l1 = 0b01010101; + unsigned char l2 = 3; + + printf("l1: %b", rol(l1, l2)); + + return 0; +} diff --git a/graphs/piscine/my_abs/my_abs.c b/graphs/piscine/my_abs/my_abs.c new file mode 100644 index 0000000..fc89d2f --- /dev/null +++ b/graphs/piscine/my_abs/my_abs.c @@ -0,0 +1,11 @@ +int my_abs(int n) +{ + if (n < 0) + { + return -n; + } + else + { + return n; + } +} diff --git a/graphs/piscine/my_atoi/my_atoi.c b/graphs/piscine/my_atoi/my_atoi.c new file mode 100644 index 0000000..ca185a5 --- /dev/null +++ b/graphs/piscine/my_atoi/my_atoi.c @@ -0,0 +1,61 @@ +#include "my_atoi.h" + +int my_atoi(const char *str) +{ + int res = 0; + + // str error check + if (str == NULL || *str == '0') + { + return 0; + } + + // trim whitespaces + for (; *str && *str == ' '; str++) + { + continue; + } + + // move to end of str + size_t l; + for (l = 0; str[l]; l++) + { + continue; + } + l--; + + // prepare for calculations + int factor = 1; + + // actual conversion of up to the second element of str (potential sign) + for (; l > 0; l--) + { + char val = str[l]; + if (val < '0' || val > '9') + { + return 0; + } + val -= '0'; + res += val * factor; + + factor *= 10; + } + + // l should be 0 by now + if (str[l] == '-') + { + return -res; + } + else if (str[l] != '+') + { + int val = str[l]; + if (val < '0' || val > '9') + { + return 0; + } + val -= '0'; + return res + val * factor; + } + + return res; +} diff --git a/graphs/piscine/my_atoi/my_atoi.h b/graphs/piscine/my_atoi/my_atoi.h new file mode 100644 index 0000000..b520d09 --- /dev/null +++ b/graphs/piscine/my_atoi/my_atoi.h @@ -0,0 +1,8 @@ +#ifndef MY_ATOI_H +#define MY_ATOI_H + +#include <stddef.h> + +int my_atoi(const char *str); + +#endif /* ! MY_ATOI_H */ diff --git a/graphs/piscine/my_atoi_base/my_atoi_base.c b/graphs/piscine/my_atoi_base/my_atoi_base.c new file mode 100644 index 0000000..46b4560 --- /dev/null +++ b/graphs/piscine/my_atoi_base/my_atoi_base.c @@ -0,0 +1,86 @@ +#include "my_atoi_base.h" + +int val_in_base(char c, const char *base) +{ + size_t i; + for (i = 0; base[i] && base[i] != c; i++) + { + continue; + } + + if (base[i]) + { + return i; + } + + return -1; +} + +int base_size(const char *base) +{ + int res; + for (res = 0; base[res]; res++) + { + continue; + } + return res; +} + +int my_atoi_base(const char *str, const char *base) +{ + int res = 0; + + // str error check + if (str == NULL || *str == '0') + { + return 0; + } + + // trim whitespaces + for (; *str && *str == ' '; str++) + { + continue; + } + + // move to end of str + size_t l; + for (l = 0; str[l]; l++) + { + continue; + } + l--; + + // prepare for calculations + int b = base_size(base); + int factor = 1; + + // actual conversion of up to the second element of str (potential sign) + for (; l > 0; l--) + { + int val = val_in_base(str[l], base); + if (val == -1) + { + return 0; + } + res += val * factor; + + factor *= b; + } + + // l should be 0 by now + if (str[l] == '-') + { + return -res; + } + else if (str[l] != '+') + { + int val = val_in_base(str[l], base); + if (val == -1) + { + return 0; + } + return res + val * factor; + } + + return res; +} diff --git a/graphs/piscine/my_atoi_base/my_atoi_base.h b/graphs/piscine/my_atoi_base/my_atoi_base.h new file mode 100644 index 0000000..296ae23 --- /dev/null +++ b/graphs/piscine/my_atoi_base/my_atoi_base.h @@ -0,0 +1,8 @@ +#ifndef MY_ATOI_BASE_H +#define MY_ATOI_BASE_H + +#include <stddef.h> + +int my_atoi_base(const char *str, const char *base); + +#endif /* ! MY_ATOI_BASE_H */ diff --git a/graphs/piscine/my_bc/my_bc.sh b/graphs/piscine/my_bc/my_bc.sh new file mode 100755 index 0000000..f675838 --- /dev/null +++ b/graphs/piscine/my_bc/my_bc.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +[ -n "$1" ] && echo "$(($1))" && exit 0 + +while IFS='' read -r line; do + [ -z "$line" ] && exit 0 || echo "$(($line))" +done diff --git a/graphs/piscine/my_c_tail/main.c b/graphs/piscine/my_c_tail/main.c new file mode 100644 index 0000000..ba33337 --- /dev/null +++ b/graphs/piscine/my_c_tail/main.c @@ -0,0 +1,10 @@ +#include <stdlib.h> + +#include "my_c_tail.h" + +int main(int argc, char *argv[]) +{ + if (argc > 1) + stdintail(atoi(argv[1])); + return 0; +} diff --git a/graphs/piscine/my_c_tail/my_c_tail.c b/graphs/piscine/my_c_tail/my_c_tail.c new file mode 100644 index 0000000..790240c --- /dev/null +++ b/graphs/piscine/my_c_tail/my_c_tail.c @@ -0,0 +1,46 @@ +#include "my_c_tail.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+void stdintail(unsigned int n)
+{
+ char **lines = calloc(2000, sizeof(char *));
+ lines[0] = malloc(350 * sizeof(char));
+ size_t m = 0;
+ char c;
+ size_t i = 0;
+ while (read(STDIN_FILENO, &c, 1))
+ {
+ if (c == '\n')
+ {
+ lines[m][i] = '\0';
+ lines[++m] = malloc(350 * sizeof(char));
+ i = 0;
+ }
+ else
+ {
+ lines[m][i++] = c;
+ }
+ }
+
+ size_t j;
+ if (m > n)
+ {
+ for (size_t i = 0; i < m - n; i++)
+ free(lines[i]);
+ j = m - n;
+ }
+ else
+ j = 0;
+
+ for (; j < m; j++)
+ {
+ for (size_t i = 0; lines[j][i]; i++)
+ write(STDOUT_FILENO, &(lines[j][i]), 1);
+ write(STDOUT_FILENO, "\n", 1);
+ free(lines[j]);
+ }
+ free(lines[m]);
+ free(lines);
+}
diff --git a/graphs/piscine/my_c_tail/my_c_tail.h b/graphs/piscine/my_c_tail/my_c_tail.h new file mode 100644 index 0000000..172c844 --- /dev/null +++ b/graphs/piscine/my_c_tail/my_c_tail.h @@ -0,0 +1,6 @@ +#ifndef MY_C_TAIL_H +#define MY_C_TAIL_H + +void stdintail(unsigned int n); + +#endif // MY_C_TAIL_H diff --git a/graphs/piscine/my_calloc/my_calloc.c b/graphs/piscine/my_calloc/my_calloc.c new file mode 100644 index 0000000..5a2f7f2 --- /dev/null +++ b/graphs/piscine/my_calloc/my_calloc.c @@ -0,0 +1,11 @@ +#include <stdlib.h> + +void *my_calloc(size_t n, size_t size) +{ + char *res = malloc(n * size); + for (size_t i = 0; i < n * size; i++) + { + res[i] = 0; + } + return res; +} diff --git a/graphs/piscine/my_calloc/my_calloc.h b/graphs/piscine/my_calloc/my_calloc.h new file mode 100644 index 0000000..44bf9a2 --- /dev/null +++ b/graphs/piscine/my_calloc/my_calloc.h @@ -0,0 +1,8 @@ +#ifndef MY_CALLOC_H +#define MY_CALLOC_H + +#include <stdlib.h> + +void *my_calloc(size_t n, size_t size); + +#endif /* ! MY_CALLOC_H */ diff --git a/graphs/piscine/my_file/my_file.sh b/graphs/piscine/my_file/my_file.sh new file mode 100755 index 0000000..93c0c20 --- /dev/null +++ b/graphs/piscine/my_file/my_file.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +for arg; do + if [ -f "$arg" ]; then + echo $arg: file + elif [ -d "$arg" ]; then + echo $arg: directory + else + echo $arg: unknown + fi +done diff --git a/graphs/piscine/my_first_variable/create.sh b/graphs/piscine/my_first_variable/create.sh new file mode 100755 index 0000000..d9264db --- /dev/null +++ b/graphs/piscine/my_first_variable/create.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +my_local_frais="Javotte" + +echo My frais is $my_local_frais diff --git a/graphs/piscine/my_first_variable/edit.sh b/graphs/piscine/my_first_variable/edit.sh new file mode 100755 index 0000000..e47e0c3 --- /dev/null +++ b/graphs/piscine/my_first_variable/edit.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +my_local_frais="Javotte" + +echo My frais is $my_local_frais + +my_local_frais="Pulpa" + +echo My frais is now $my_local_frais diff --git a/graphs/piscine/my_first_variable/use.sh b/graphs/piscine/my_first_variable/use.sh new file mode 100755 index 0000000..f9d462e --- /dev/null +++ b/graphs/piscine/my_first_variable/use.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "My frais is $MY_ENV_FRAIS" diff --git a/graphs/piscine/my_itoa/my_itoa.c b/graphs/piscine/my_itoa/my_itoa.c new file mode 100644 index 0000000..cbb6f73 --- /dev/null +++ b/graphs/piscine/my_itoa/my_itoa.c @@ -0,0 +1,38 @@ +#include "my_itoa.h" + +char *my_itoa(int value, char *s) +{ + if (value == 0) + { + s[0] = '0'; + s[1] = '\0'; + return s; + } + char *head = s; + if (value < 0) + { + s[0] = '-'; + s++; + value = -value; + } + + // count numbers + int t = value; + int n = 0; + while (t > 0) + { + t /= 10; + n++; + } + + // n = number count + s[n] = '\0'; + n--; + for (; n >= 0; n--) + { + s[n] = value % 10 + '0'; + value /= 10; + } + + return head; +} diff --git a/graphs/piscine/my_itoa/my_itoa.h b/graphs/piscine/my_itoa/my_itoa.h new file mode 100644 index 0000000..8e84c72 --- /dev/null +++ b/graphs/piscine/my_itoa/my_itoa.h @@ -0,0 +1,6 @@ +#ifndef MY_ITOA_H +#define MY_ITOA_H + +char *my_itoa(int value, char *s); + +#endif /* ! MY_ITOA_H */ diff --git a/graphs/piscine/my_itoa_base/my_itoa_base.c b/graphs/piscine/my_itoa_base/my_itoa_base.c new file mode 100644 index 0000000..29b3042 --- /dev/null +++ b/graphs/piscine/my_itoa_base/my_itoa_base.c @@ -0,0 +1,49 @@ +#include "my_itoa_base.h" + +int base_count(const char *base) +{ + int i; + for (i = 0; base[i]; i++) + { + continue; + } + return i; +} + +char *my_itoa_base(int n, char *s, const char *base) +{ + if (n == 0) + { + s[0] = base[0]; + s[1] = '\0'; + return s; + } + char *head = s; + if (n < 0) + { + s[0] = '-'; + s++; + n = -n; + } + + // count numbers + int t = n; + int m = 0; + int b = base_count(base); + while (t > 0) + { + t /= b; + m++; + } + + // n = number count + s[m] = '\0'; + m--; + for (; m >= 0; m--) + { + s[m] = base[n % b]; + n /= b; + } + + return head; +} diff --git a/graphs/piscine/my_itoa_base/my_itoa_base.h b/graphs/piscine/my_itoa_base/my_itoa_base.h new file mode 100644 index 0000000..0be6314 --- /dev/null +++ b/graphs/piscine/my_itoa_base/my_itoa_base.h @@ -0,0 +1,6 @@ +#ifndef MY_ITOA_BASE_H +#define MY_ITOA_BASE_H + +char *my_itoa_base(int n, char *s, const char *base); + +#endif /* ! MY_ITOA_BASE_H */ diff --git a/graphs/piscine/my_memcmp/my_memcmp.c b/graphs/piscine/my_memcmp/my_memcmp.c new file mode 100644 index 0000000..d498360 --- /dev/null +++ b/graphs/piscine/my_memcmp/my_memcmp.c @@ -0,0 +1,18 @@ +#include "my_memcmp.h" + +int my_memcmp(const void *s1, const void *s2, size_t num) +{ + if (num == 0) + { + return 0; + } + const unsigned char *a = s1; + const unsigned char *b = s2; + + for (; num - 1 && *a == *b; a++, b++, num--) + { + continue; + } + + return *a - *b; +} diff --git a/graphs/piscine/my_memcmp/my_memcmp.h b/graphs/piscine/my_memcmp/my_memcmp.h new file mode 100644 index 0000000..d17cbe6 --- /dev/null +++ b/graphs/piscine/my_memcmp/my_memcmp.h @@ -0,0 +1,8 @@ +#ifndef MY_MEMCMP_H +#define MY_MEMCMP_H + +#include <stddef.h> + +int my_memcmp(const void *s1, const void *s2, size_t num); + +#endif /* !MY_MEMCMP_H */ diff --git a/graphs/piscine/my_memcpy/my_memcpy.c b/graphs/piscine/my_memcpy/my_memcpy.c new file mode 100644 index 0000000..a6a48d4 --- /dev/null +++ b/graphs/piscine/my_memcpy/my_memcpy.c @@ -0,0 +1,28 @@ +#include "my_memcpy.h" + +void *my_memcpy(void *dest, const void *source, size_t num) +{ + char *d = dest; + const char *s = source; + if (dest > source) // reverse array + { + size_t l = num; + for (; l > 0; l--) + { + d[l - 1] = s[l - 1]; + } + } + else + { + for (size_t i = 0; i < num; i++) + { + d[i] = s[i]; + } + } + return dest; +} + +int main(void) +{ + return 0; +} diff --git a/graphs/piscine/my_memcpy/my_memcpy.h b/graphs/piscine/my_memcpy/my_memcpy.h new file mode 100644 index 0000000..bc1b926 --- /dev/null +++ b/graphs/piscine/my_memcpy/my_memcpy.h @@ -0,0 +1,8 @@ +#ifndef MY_MEMCPY_H +#define MY_MEMCPY_H + +#include <stddef.h> + +void *my_memcpy(void *dest, const void *source, size_t num); + +#endif /* ! MY_MEMCPY_H */ diff --git a/graphs/piscine/my_memmove/my_memmove.c b/graphs/piscine/my_memmove/my_memmove.c new file mode 100644 index 0000000..bb360a5 --- /dev/null +++ b/graphs/piscine/my_memmove/my_memmove.c @@ -0,0 +1,23 @@ +#include "my_memmove.h" + +void *my_memmove(void *dest, const void *src, size_t n) +{ + char *d = dest; + const char *s = src; + if (dest > src) // reverse array + { + size_t l = n; + for (; l > 0; l--) + { + d[l - 1] = s[l - 1]; + } + } + else + { + for (size_t i = 0; i < n; i++) + { + d[i] = s[i]; + } + } + return dest; +} diff --git a/graphs/piscine/my_memmove/my_memmove.h b/graphs/piscine/my_memmove/my_memmove.h new file mode 100644 index 0000000..cb253b7 --- /dev/null +++ b/graphs/piscine/my_memmove/my_memmove.h @@ -0,0 +1,8 @@ +#ifndef MY_MEMMOVE_H +#define MY_MEMMOVE_H + +#include <stddef.h> + +void *my_memmove(void *dest, const void *src, size_t n); + +#endif /* ! MY_MEMMOVE_H */ diff --git a/graphs/piscine/my_memset/my_memset.c b/graphs/piscine/my_memset/my_memset.c new file mode 100644 index 0000000..243a5ac --- /dev/null +++ b/graphs/piscine/my_memset/my_memset.c @@ -0,0 +1,12 @@ +#include "my_memset.h" + +void *my_memset(void *s, int c, size_t n) +{ + unsigned char *t = s; + for (size_t i = 0; i < n; i++) + { + t[i] = c; + } + + return t; +} diff --git a/graphs/piscine/my_memset/my_memset.h b/graphs/piscine/my_memset/my_memset.h new file mode 100644 index 0000000..e5ed0f0 --- /dev/null +++ b/graphs/piscine/my_memset/my_memset.h @@ -0,0 +1,6 @@ +#ifndef MY_MEMSET_H +#define MY_MEMSET_H + +#include <stddef.h> + +#endif /* ! MY_MEMSET_H */ diff --git a/graphs/piscine/my_pow/my_pow.c b/graphs/piscine/my_pow/my_pow.c new file mode 100644 index 0000000..f529d87 --- /dev/null +++ b/graphs/piscine/my_pow/my_pow.c @@ -0,0 +1,13 @@ +int my_pow(int a, int b) +{ + if (!a) + return b == 0; + int res = 1; + for (int i = 0; i < b / 2; i++) + { + res *= a * a; + } + if (b % 2) + res *= a; + return res; +} diff --git a/graphs/piscine/my_round/my_round.c b/graphs/piscine/my_round/my_round.c new file mode 100644 index 0000000..324bc1d --- /dev/null +++ b/graphs/piscine/my_round/my_round.c @@ -0,0 +1,6 @@ +int my_round(float n) +{ + if (n < 0) + return n - 0.5; + return n + 0.5; +} diff --git a/graphs/piscine/my_strcmp/my_strcmp.c b/graphs/piscine/my_strcmp/my_strcmp.c new file mode 100644 index 0000000..d3ef3e3 --- /dev/null +++ b/graphs/piscine/my_strcmp/my_strcmp.c @@ -0,0 +1,11 @@ +#include "my_strcmp.h" + +int my_strcmp(const char *s1, const char *s2) +{ + for (; *s1 && *s1 == *s2; s1++, s2++) + { + continue; + } + + return *s1 - *s2; +} diff --git a/graphs/piscine/my_strcmp/my_strcmp.h b/graphs/piscine/my_strcmp/my_strcmp.h new file mode 100644 index 0000000..d89a00b --- /dev/null +++ b/graphs/piscine/my_strcmp/my_strcmp.h @@ -0,0 +1,6 @@ +#ifndef MY_STRCMP_H +#define MY_STRCMP_H + +#include <stddef.h> + +#endif /* ! MY_STRCMP_H */ diff --git a/graphs/piscine/my_strcpy/my_strcpy.c b/graphs/piscine/my_strcpy/my_strcpy.c new file mode 100644 index 0000000..69ad5ee --- /dev/null +++ b/graphs/piscine/my_strcpy/my_strcpy.c @@ -0,0 +1,13 @@ +#include <stdlib.h> + +char *my_strcpy(char *dest, const char *source) +{ + size_t i; + for (i = 0; source[i]; i++) + { + dest[i] = source[i]; + } + dest[i] = '\0'; + + return dest; +} diff --git a/graphs/piscine/my_strlen/my_strlen.c b/graphs/piscine/my_strlen/my_strlen.c new file mode 100644 index 0000000..ec80d0b --- /dev/null +++ b/graphs/piscine/my_strlen/my_strlen.c @@ -0,0 +1,12 @@ +#include "my_strlen.h" + +size_t my_strlen(const char *s) +{ + size_t i; + for (i = 0; s[i]; i++) + { + continue; + } + + return i; +} diff --git a/graphs/piscine/my_strlen/my_strlen.h b/graphs/piscine/my_strlen/my_strlen.h new file mode 100644 index 0000000..02806cc --- /dev/null +++ b/graphs/piscine/my_strlen/my_strlen.h @@ -0,0 +1,6 @@ +#ifndef MY_STRLEN_H +#define MY_STRLEN_H + +#include <stddef.h> + +#endif /* ! MY_STRLEN_H */ diff --git a/graphs/piscine/my_strlowcase/my_strlowcase.c b/graphs/piscine/my_strlowcase/my_strlowcase.c new file mode 100644 index 0000000..e52ea32 --- /dev/null +++ b/graphs/piscine/my_strlowcase/my_strlowcase.c @@ -0,0 +1,13 @@ +#include "my_strlowcase.h" + +void my_strlowcase(char *s) +{ + size_t i; + for (i = 0; s[i]; i++) + { + if (s[i] >= 'A' && s[i] <= 'Z') + { + s[i] += ('a' - 'A'); + } + } +} diff --git a/graphs/piscine/my_strlowcase/my_strlowcase.h b/graphs/piscine/my_strlowcase/my_strlowcase.h new file mode 100644 index 0000000..d4996b8 --- /dev/null +++ b/graphs/piscine/my_strlowcase/my_strlowcase.h @@ -0,0 +1,8 @@ +#ifndef MY_STRLOWCASE_H +#define MY_STRLOWCASE_H + +#include <stddef.h> + +void my_strlowcase(char *str); + +#endif /* ! MY_STRLOWCASE_H */ diff --git a/graphs/piscine/my_strspn/my_strspn.c b/graphs/piscine/my_strspn/my_strspn.c new file mode 100644 index 0000000..18bba0f --- /dev/null +++ b/graphs/piscine/my_strspn/my_strspn.c @@ -0,0 +1,26 @@ +#include "my_strspn.h" + +int is_in(char c, const char *accept) +{ + for (; *accept && *accept != c; accept++) + { + continue; + } + return *accept != '\0'; +} + +size_t my_strspn(const char *s, const char *accept) +{ + if (s == NULL || *s == '\0') + { + return 0; + } + + size_t res; + for (res = 0; *s && is_in(*s, accept) != 0; res++, s++) + { + continue; + } + + return res; +} diff --git a/graphs/piscine/my_strspn/my_strspn.h b/graphs/piscine/my_strspn/my_strspn.h new file mode 100644 index 0000000..f2d7759 --- /dev/null +++ b/graphs/piscine/my_strspn/my_strspn.h @@ -0,0 +1,8 @@ +#ifndef MY_STRSPN_H +#define MY_STRSPN_H + +#include <stddef.h> + +size_t my_strspn(const char *s, const char *accept); + +#endif /* ! MY_STRSPN_H */ diff --git a/graphs/piscine/my_strstr/my_strstr.c b/graphs/piscine/my_strstr/my_strstr.c new file mode 100644 index 0000000..36ac439 --- /dev/null +++ b/graphs/piscine/my_strstr/my_strstr.c @@ -0,0 +1,34 @@ +#include "my_strstr.h" + +#include <stddef.h> + +int my_strstr(const char *haystack, const char *needle) +{ + if (needle == NULL || *needle == '\0') + { + return 0; + } + + for (int i = 0; haystack[i]; i++) + { + if (haystack[i] == needle[0]) + { + int j; + for (j = 0; + haystack[i + j] && needle[j] && needle[j] == haystack[i + j]; + j++) + { + continue; + } + if (needle[j] == '\0') + { + return i; + } + if (haystack[i + j] == '\0') + { + return -1; + } + } + } + return -1; +} diff --git a/graphs/piscine/my_strstr/my_strstr.h b/graphs/piscine/my_strstr/my_strstr.h new file mode 100644 index 0000000..1b734b2 --- /dev/null +++ b/graphs/piscine/my_strstr/my_strstr.h @@ -0,0 +1,6 @@ +#ifndef MY_STRSTR_H +#define MY_STRSTR_H + +int my_strstr(const char *haystack, const char *needle); + +#endif /* ! MY_STRSTR_H */ diff --git a/graphs/piscine/my_strtok_r/my_strtok_r.c b/graphs/piscine/my_strtok_r/my_strtok_r.c new file mode 100644 index 0000000..ec052b7 --- /dev/null +++ b/graphs/piscine/my_strtok_r/my_strtok_r.c @@ -0,0 +1,51 @@ +#include "my_strtok_r.h" + +#include <stddef.h> + +static int is_delim(char c, const char *delims) +{ + for (const char *d = delims; *d; d++) + { + if (*d == c) + return 1; + } + return 0; +} + +char *my_strtok_r(char *str, const char *delim, char **saveptr) +{ + if (str == NULL) + { + if (*saveptr == NULL) + { + return NULL; + } + str = *saveptr; + } + + size_t i = 0; + while (str[i] != '\0' && is_delim(str[i], delim)) + { + i++; + } + if (str[i] == '\0') + { + *saveptr = NULL; + return NULL; + } + + char *res = str + i; + + while (str[i] != '\0' && !is_delim(str[i], delim)) + { + i++; + } + if (str[i] == '\0') + { + *saveptr = NULL; + return res; + } + *saveptr = str + i + 1; + str[i] = '\0'; + return res; +} diff --git a/graphs/piscine/my_strtok_r/my_strtok_r.h b/graphs/piscine/my_strtok_r/my_strtok_r.h new file mode 100644 index 0000000..5603729 --- /dev/null +++ b/graphs/piscine/my_strtok_r/my_strtok_r.h @@ -0,0 +1,6 @@ +#ifndef MY_STRTOK_R_H +#define MY_STRTOK_R_H + +char *my_strtok_r(char *str, const char *delim, char **saveptr); + +#endif /* ! MY_STRTOK_R_H */ diff --git a/graphs/piscine/null_terminated_arrays/null_terminated_arrays.c b/graphs/piscine/null_terminated_arrays/null_terminated_arrays.c new file mode 100644 index 0000000..32d2a17 --- /dev/null +++ b/graphs/piscine/null_terminated_arrays/null_terminated_arrays.c @@ -0,0 +1,50 @@ +#include "null_terminated_arrays.h" + +#include <assert.h> +#include <stddef.h> +#include <stdio.h> + +void reverse_array(const char **arr) +{ + const char **p; + for (p = arr; *p; p++) + { + continue; + } + p--; + + while (p > arr) + { + const char *tmp = *p; + *p = *arr; + *arr = tmp; + arr++; + p--; + } +} + +void reverse_matrix(const char ***matrix) +{ + const char ***p; + for (p = matrix; *p; p++) + { + continue; + } + p--; + + while (p > matrix) + { + reverse_array(*p); + reverse_array(*matrix); + const char **tmp = *p; + *p = *matrix; + *matrix = tmp; + matrix++; + p--; + } + + if (p == matrix) + { + reverse_array(*matrix); + } +} diff --git a/graphs/piscine/null_terminated_arrays/null_terminated_arrays.h b/graphs/piscine/null_terminated_arrays/null_terminated_arrays.h new file mode 100644 index 0000000..31fccc5 --- /dev/null +++ b/graphs/piscine/null_terminated_arrays/null_terminated_arrays.h @@ -0,0 +1,6 @@ +#ifndef NULL_TERMINATED_ARRAYS_H_ +#define NULL_TERMINATED_ARRAYS_H_ + +void reverse_matrix(const char ***matrix); + +#endif /* !NULL_TERMINATED_ARRAYS_H_ */ diff --git a/graphs/piscine/number_digits_rec/number_digits_rec.c b/graphs/piscine/number_digits_rec/number_digits_rec.c new file mode 100644 index 0000000..94de296 --- /dev/null +++ b/graphs/piscine/number_digits_rec/number_digits_rec.c @@ -0,0 +1,8 @@ +unsigned int number_digits_rec(unsigned int n) +{ + if (n / 10 == 0) + { + return 1; + } + return 1 + number_digits_rec(n / 10); +} diff --git a/graphs/piscine/palindrome/palindrome.c b/graphs/piscine/palindrome/palindrome.c new file mode 100644 index 0000000..2ecacfd --- /dev/null +++ b/graphs/piscine/palindrome/palindrome.c @@ -0,0 +1,47 @@ +#include "palindrome.h" + +#include <stddef.h> + +int palindrome(const char *s) +{ + if (s == NULL) + { + return 0; + } + + if (*s == '\0') + { + return 1; + } + + const char *p = s; + while (*p) + { + p++; + } + p--; + + while (p > s) + { + while ((*p < '0' || (*p > '9' && *p < 'A') || (*p > 'Z' && *p < 'a') + || *p > 'z') + && p > s) + { + p--; + } + while ((*s < '0' || (*s > '9' && *s < 'A') || (*s > 'Z' && *s < 'a') + || *s > 'z') + && p > s) + { + s++; + } + if (*p != *s) + { + return 0; + } + p--; + s++; + } + + return 1; +} diff --git a/graphs/piscine/palindrome/palindrome.h b/graphs/piscine/palindrome/palindrome.h new file mode 100644 index 0000000..8595911 --- /dev/null +++ b/graphs/piscine/palindrome/palindrome.h @@ -0,0 +1,6 @@ +#ifndef PALINDROME_H +#define PALINDROME_H + +int palindrome(const char *s); + +#endif /* !PALINDROME_H */ diff --git a/graphs/piscine/pine/pine.c b/graphs/piscine/pine/pine.c new file mode 100644 index 0000000..9d48761 --- /dev/null +++ b/graphs/piscine/pine/pine.c @@ -0,0 +1,36 @@ +#include <stdio.h> + +int pine(unsigned n) +{ + if (n < 3) + { + return 1; + } + + for (unsigned i = 0; i < n; i++) + { + for (unsigned j = 0; j < n - i - 1; j++) + { + putchar(' '); + } + + for (unsigned j = 0; j < 2 * i + 1; j++) + { + putchar('*'); + } + + putchar('\n'); + } + + for (unsigned i = 0; i < n / 2; i++) + { + for (unsigned j = 0; j < n - 1; j++) + { + putchar(' '); + } + putchar('*'); + putchar('\n'); + } + + return 0; +} diff --git a/graphs/piscine/pointer_swap/pointer_swap.c b/graphs/piscine/pointer_swap/pointer_swap.c new file mode 100644 index 0000000..32ceb84 --- /dev/null +++ b/graphs/piscine/pointer_swap/pointer_swap.c @@ -0,0 +1,6 @@ +void pointer_swap(int **a, int **b) +{ + int *tmp = *a; + *a = *b; + *b = tmp; +} diff --git a/graphs/piscine/prototypes/prototypes.sh b/graphs/piscine/prototypes/prototypes.sh new file mode 100755 index 0000000..3c80468 --- /dev/null +++ b/graphs/piscine/prototypes/prototypes.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +sed -En 's/^(([a-zA-Z]* ){0,2}([a-zA-Z]*) *\**([a-z][a-z0-9_]*)\((([a-zA-Z]* )?([a-zA-Z]* )?([a-z][a-z0-9_]* *)(\**[a-z][a-z0-9_]*|[a-z][a-z0-9_]*\[([0-9][0-9]*)?\])(, ([a-zA-Z]* )?([a-zA-Z]* )?([a-z][a-z0-9_]* *)(\**[a-z][a-z0-9_]*|[a-z][a-z0-9_]*\[([0-9][0-9]*)?\])){0,3}|void)\))$/\1;/p' "$1" diff --git a/graphs/piscine/quick_sort/quick_sort.c b/graphs/piscine/quick_sort/quick_sort.c new file mode 100644 index 0000000..6c61fc3 --- /dev/null +++ b/graphs/piscine/quick_sort/quick_sort.c @@ -0,0 +1,18 @@ +#include <stddef.h> + +void quicksort(int *tab, size_t len) +{ + if (tab == NULL) + { + return; + } + for (size_t i = 1; i < len; i++) + { + for (size_t j = i; j > 0 && tab[j - 1] > tab[j]; j--) + { + int tmp = tab[j]; + tab[j] = tab[j - 1]; + tab[j - 1] = tmp; + } + } +} diff --git a/graphs/piscine/quick_sort/quick_sort_example.c b/graphs/piscine/quick_sort/quick_sort_example.c new file mode 100644 index 0000000..2a5228f --- /dev/null +++ b/graphs/piscine/quick_sort/quick_sort_example.c @@ -0,0 +1,19 @@ +#include <stdio.h> + +void quicksort(int *tab, int len); + +int main(void) +{ + unsigned i = 0; + int tab[] = { 10, 11, 2, 3, 8, 5, 7, 6, 26, 30, 2, 1, 17, 13, 14 }; + + unsigned size = sizeof(tab) / sizeof(int); + + quicksort(tab, size); + + for (; i < size - 1; ++i) + printf("%d ", tab[i]); + printf("%d\n", tab[i]); + + return 0; +} diff --git a/graphs/piscine/repeat/repeat.c b/graphs/piscine/repeat/repeat.c new file mode 100644 index 0000000..06d0b43 --- /dev/null +++ b/graphs/piscine/repeat/repeat.c @@ -0,0 +1,11 @@ +#include <stdio.h> + +int main(int argc, char **argv) +{ + if (argc != 3) + return 1; + + for (int i = 0; i < argv[2][0] - '0'; i++) + puts(argv[1]); + return 0; +} diff --git a/graphs/piscine/right_tarball/my_tarball.tar.gz b/graphs/piscine/right_tarball/my_tarball.tar.gz Binary files differnew file mode 100644 index 0000000..eb6acfc --- /dev/null +++ b/graphs/piscine/right_tarball/my_tarball.tar.gz diff --git a/graphs/piscine/rotx/rotx.c b/graphs/piscine/rotx/rotx.c new file mode 100644 index 0000000..a2cb820 --- /dev/null +++ b/graphs/piscine/rotx/rotx.c @@ -0,0 +1,59 @@ +#include <stdlib.h> +#include <unistd.h> + +#define BUFFER_SIZE 10 + +int main(int argc, char **argv) +{ + if (argc != 2) + { + return 0; + } + + int rot = atoi(argv[1]); + int rod = rot; + if (rot < 0) + { + rot = (rot % 26) + 26; + rod = (rod % 10) + 10; + } + + char buf[BUFFER_SIZE]; + ssize_t r; + + while ((r = read(STDIN_FILENO, buf, BUFFER_SIZE))) + { + if (r == -1) + { + return 1; + } + + for (ssize_t i = 0; i < r; i++) + { + if (buf[i] >= 'a' && buf[i] <= 'z') + { + buf[i] = ((buf[i] - 'a') + rot) % 26 + 'a'; + } + else if (buf[i] >= 'A' && buf[i] <= 'Z') + { + buf[i] = ((buf[i] - 'A') + rot) % 26 + 'A'; + } + else if (buf[i] >= '0' && buf[i] <= '9') + { + buf[i] = ((buf[i] - '0') + rod) % 10 + '0'; + } + } + + ssize_t w = write(STDOUT_FILENO, buf, r); + while (w != r) + { + w += write(STDOUT_FILENO, buf, r); + if (w == -1) + { + return 1; + } + } + } + + return 0; +} diff --git a/graphs/piscine/sed_trailing_whitespaces/whitespaces.sed b/graphs/piscine/sed_trailing_whitespaces/whitespaces.sed new file mode 100644 index 0000000..46b7017 --- /dev/null +++ b/graphs/piscine/sed_trailing_whitespaces/whitespaces.sed @@ -0,0 +1 @@ +s/[ \t]*$// diff --git a/graphs/piscine/selection_sort/selection_sort.c b/graphs/piscine/selection_sort/selection_sort.c new file mode 100644 index 0000000..98adc7e --- /dev/null +++ b/graphs/piscine/selection_sort/selection_sort.c @@ -0,0 +1,30 @@ +#include <stddef.h> + +void swap(int *a, int *b) +{ + int tmp = *a; + *a = *b; + *b = tmp; +} + +unsigned array_min(const int arr[], unsigned start, unsigned size) +{ + unsigned min = start; + for (; start < size; start++) + { + if (arr[min] > arr[start]) + { + min = start; + } + } + return min; +} + +void selection_sort(int arr[], unsigned size) +{ + for (size_t i = 0; i < size; i++) + { + unsigned j = array_min(arr, i, size); + swap(&(arr[i]), &(arr[j])); + } +} diff --git a/graphs/piscine/seq/seq.sh b/graphs/piscine/seq/seq.sh new file mode 100755 index 0000000..9721432 --- /dev/null +++ b/graphs/piscine/seq/seq.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +if [ $# -ne 3 ]; then + echo "Usage: ./seq.sh FIRST INCREMENT LAST" 1>&2 + exit 1 +fi + +if [ "$2" -eq 0 ]; then + exit 1 +fi + +if [ "$1" -eq "$3" ]; then + echo "$1" + exit 0 +fi + +if [ "$1" -lt "$3" ]; then + [ 0 -gt "$2" ] && exit 1 + i="$1" + while [ "$3" -ge "$i" ]; do + echo "$i" + i=$(($i + $2)) + done + exit 0 +fi + +[ "$2" -gt 0 ] && exit 1 +i="$1" +while [ "$i" -ge "$3" ]; do + echo "$i" + i=$(($i + $2)) +done +exit 0 diff --git a/graphs/piscine/sieve_eratosthenes_advanced/Makefile b/graphs/piscine/sieve_eratosthenes_advanced/Makefile new file mode 100644 index 0000000..c7e35f9 --- /dev/null +++ b/graphs/piscine/sieve_eratosthenes_advanced/Makefile @@ -0,0 +1,13 @@ +CC=gcc +CFLAGS=-std=c99 -Wall -Wextra -Werror -Wvla -pedantic +LDLIBS= + +all: sieve.o + +sieve.o: sieve.c + $(CC) $(CFLAGS) -c -o sieve.o sieve.c + +.PHONY: clean + +clean: + rm sieve.o diff --git a/graphs/piscine/sieve_eratosthenes_advanced/sieve.c b/graphs/piscine/sieve_eratosthenes_advanced/sieve.c new file mode 100644 index 0000000..7dd4816 --- /dev/null +++ b/graphs/piscine/sieve_eratosthenes_advanced/sieve.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <stdlib.h> + +void sieve(int n) +{ + if (n <= 2) + { + return; + } + + // Generate array + int *a = calloc(n, sizeof(int)); + int count = 0; + + // Actual sieve and count + for (int i = 2; i < n; i++) + { + if (a[i] == 0) + { + for (int k = 2 * i; k < n; k += i) + { + a[k] = 1; + } + } + } + + for (int i = 2; i < n; i++) + { + if (a[i] == 0) + { + count++; + } + } + + // Print the count + printf("%d\n", count); + + free(a); +} diff --git a/graphs/piscine/simple_fnmatch/simple_fnmatch.c b/graphs/piscine/simple_fnmatch/simple_fnmatch.c new file mode 100644 index 0000000..d40353f --- /dev/null +++ b/graphs/piscine/simple_fnmatch/simple_fnmatch.c @@ -0,0 +1,46 @@ +#include "simple_fnmatch.h" + +int simple_fnmatch(const char *pattern, const char *string) +{ + if (!pattern || !string) + return FNM_NOMATCH; + if (*pattern == '*' && pattern[1] == '\0') + return 0; + while (*pattern && *string) + { + if (*pattern == '?') + { + pattern++; + string++; + } + else if (*pattern == '\\') + { + pattern++; + if (!pattern || *pattern != *string) + return FNM_NOMATCH; + string++; + pattern++; + } + else if (*pattern == '*') + { + pattern++; + while (*string && simple_fnmatch(pattern, string)) + string++; + if (*string) + return 0; + } + else if (*pattern != *string) + return FNM_NOMATCH; + else + { + string++; + pattern++; + } + } + + if (*pattern == '*' && pattern[1] == '\0') + return 0; + if (*string || *pattern) + return FNM_NOMATCH; + return 0; +} diff --git a/graphs/piscine/simple_fnmatch/simple_fnmatch.h b/graphs/piscine/simple_fnmatch/simple_fnmatch.h new file mode 100644 index 0000000..e1ae166 --- /dev/null +++ b/graphs/piscine/simple_fnmatch/simple_fnmatch.h @@ -0,0 +1,8 @@ +#ifndef SIMPLE_FNMATCH_H +#define SIMPLE_FNMATCH_H + +#define FNM_NOMATCH 1 + +int simple_fnmatch(const char *pattern, const char *string); + +#endif /* !SIMPLE_FNMATCH_H */ diff --git a/graphs/piscine/stack/stack.c b/graphs/piscine/stack/stack.c new file mode 100644 index 0000000..0498abc --- /dev/null +++ b/graphs/piscine/stack/stack.c @@ -0,0 +1,30 @@ +#include "stack.h" + +#include <stdlib.h> + +struct stack *stack_push(struct stack *s, int e) +{ + struct stack *new = malloc(sizeof(struct stack)); + new->data = e; + new->next = NULL; + + new->next = s; + return new; +} + +struct stack *stack_pop(struct stack *s) +{ + if (s == NULL) + { + return NULL; + } + + struct stack *res = s->next; + free(s); + return res; +} + +int stack_peek(struct stack *s) +{ + return s->data; +} diff --git a/graphs/piscine/stack/stack.h b/graphs/piscine/stack/stack.h new file mode 100644 index 0000000..bd5dd24 --- /dev/null +++ b/graphs/piscine/stack/stack.h @@ -0,0 +1,14 @@ +#ifndef STACK_H +#define STACK_H + +struct stack +{ + int data; + struct stack *next; +}; + +struct stack *stack_push(struct stack *s, int e); +struct stack *stack_pop(struct stack *s); +int stack_peek(struct stack *s); + +#endif /* !STACK_H */ diff --git a/graphs/piscine/str_revert/str_revert.c b/graphs/piscine/str_revert/str_revert.c new file mode 100644 index 0000000..31f7f3d --- /dev/null +++ b/graphs/piscine/str_revert/str_revert.c @@ -0,0 +1,25 @@ +#include "str_revert.h" + +#include <stddef.h> + +void str_revert(char str[]) +{ + if (*str == '\0') + { + return; + } + + size_t len = 0; + for (; str[len]; len++) + { + continue; + } + len--; + + for (size_t i = 0; i <= len / 2; i++) + { + char tmp = str[i]; + str[i] = str[len - i]; + str[len - i] = tmp; + } +} diff --git a/graphs/piscine/str_revert/str_revert.h b/graphs/piscine/str_revert/str_revert.h new file mode 100644 index 0000000..daa23d4 --- /dev/null +++ b/graphs/piscine/str_revert/str_revert.h @@ -0,0 +1,6 @@ +#ifndef STR_REVERT_H +#define STR_REVERT_H + +void str_revert(char str[]); + +#endif /* ! STR_REVERT_H */ diff --git a/graphs/piscine/test.txt b/graphs/piscine/test.txt new file mode 100644 index 0000000..958cdbc --- /dev/null +++ b/graphs/piscine/test.txt @@ -0,0 +1,3 @@ +This is a short line. +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +This is another short line. diff --git a/graphs/piscine/test_a_bit/is_set.c b/graphs/piscine/test_a_bit/is_set.c new file mode 100644 index 0000000..38fccf8 --- /dev/null +++ b/graphs/piscine/test_a_bit/is_set.c @@ -0,0 +1,6 @@ +#include "is_set.h" + +unsigned int is_set(unsigned int value, unsigned char n) +{ + return (value & (1 << (n - 1))) != 0; +} diff --git a/graphs/piscine/test_a_bit/is_set.h b/graphs/piscine/test_a_bit/is_set.h new file mode 100644 index 0000000..8f2fd9a --- /dev/null +++ b/graphs/piscine/test_a_bit/is_set.h @@ -0,0 +1,6 @@ +#ifndef IS_SET_H +#define IS_SET_H + +unsigned int is_set(unsigned int value, unsigned char n); + +#endif /* ! IS_SET_H */ diff --git a/graphs/piscine/test_a_bit/test.c b/graphs/piscine/test_a_bit/test.c new file mode 100644 index 0000000..e3403e4 --- /dev/null +++ b/graphs/piscine/test_a_bit/test.c @@ -0,0 +1,11 @@ +#include <stdio.h> + +#include "is_set.h" + +int main(void) +{ + printf("%d\n", is_set(24, 4)); + printf("%d\n", is_set(24, 3)); + + return 0; +} diff --git a/graphs/piscine/tinylibstream/Makefile b/graphs/piscine/tinylibstream/Makefile new file mode 100644 index 0000000..b060495 --- /dev/null +++ b/graphs/piscine/tinylibstream/Makefile @@ -0,0 +1,13 @@ +CC = gcc +CFLAGS = -std=c99 -pedantic -Werror -Wall -Wextra -Wvla + +.PHONY: library clean + +library: src/tinylibstream.o + ar csr libstream.a src/tinylibstream.o + +clean: + rm libstream.a src/tinylibstream.o + +check: + $(CC) $(CFLAGS) -lcriterion src/tinylibstream.c tests/tests.c diff --git a/graphs/piscine/tinylibstream/include/libstream.h b/graphs/piscine/tinylibstream/include/libstream.h new file mode 100644 index 0000000..459432d --- /dev/null +++ b/graphs/piscine/tinylibstream/include/libstream.h @@ -0,0 +1,167 @@ +#ifndef LIBSTREAM_H +#define LIBSTREAM_H + +#include <fcntl.h> +#include <stdbool.h> +#include <stddef.h> +#include <unistd.h> + +/* +** /!\ DO NOT MODIFY THIS FILE, AS IT WILL BE OVERRIDDEN DURING CORRECTION. /!\ +** +** You can add your own functions declarations to OTHER HEADER FILES. +*/ + +/* the value returned when end of file is reached */ +#define LBS_EOF (-1) + +/* the size of the buffer */ +#define LBS_BUFFER_SIZE 32 + +/* +** Describes the current operation: +** - if reading, the buffer contains read-buffered data +** - if writing, the buffer contains write-buffered data +*/ +enum stream_io_operation +{ + STREAM_READING = 0, + STREAM_WRITING, +}; + +/* +** Controls when to flush the buffer: +** - when unbuffered, flush every time a character is written +** - when buffered, flush when the buffer is full +** - when line buffered, flush when the buffer is full or when a \n +** character is written +*/ +enum stream_buffering +{ + STREAM_UNBUFFERED = 0, + STREAM_LINE_BUFFERED, + STREAM_BUFFERED, +}; + +struct stream +{ + /* the flags passed to open */ + int flags; + + /* + ** Initially, this variable is 0. + ** When a function such as fgetc fails, it is set to 1 to indicate + ** something went wrong. This is useful to make the difference between + ** reaching the end of file and read errors while using fgetc and + ** some others. + ** It is often referred to as the error indicator. + */ + int error; + + /* the file descriptor, as returned by open(2) */ + int fd; + + /* + ** the kind of data stored by the buffer. + ** The default value shouldn't matter. + */ + enum stream_io_operation io_operation; + + /* + ** defines when to flush **output**. + ** This field does not control input buffering (which is always fully + ** buffered). + ** + ** The default value is LINE_BUFFERED if isatty(fd), BUFFERED otherwise. + */ + enum stream_buffering buffering_mode; + + /* the amount of used bytes in the buffer */ + size_t buffered_size; + + /* + ** /!\ This field only makes sense when io_operation is STREAM_READING /!\ + ** the amount of data already read from the buffer by the user. + */ + size_t already_read; + + /* + ** buffer + ** --------------> + ** +==============+====================+---------------------+ + ** | already_read | remaining_buffered | unused_buffer_space | + ** +==============+====================+---------------------+ + ** \_______________________________/ + ** buffered_size + ** + ** /!\ The buffer can contain either read-buffered or write-buffered data, + ** depending on the value of io_operation /!\ + */ + char buffer[LBS_BUFFER_SIZE]; +}; + +/* +** These functions are defined in a header for optimization reasons: +** each .c file that includes this header will get its own copy of the +** function's code, thus easily make optimizations. +** +** ``static`` means each compilation unit (.c file) will have its own copy +** of the function without them clashing. +** +** ``inline`` means the content of the function should be "copy pasted" +** where it's called. It also tells the compiler not to complain when the +** function isn't used. +** +** They're just like a macro, except the type of arguments is checked. +*/ + +static inline size_t stream_remaining_buffered(struct stream *stream) +{ + return stream->buffered_size - stream->already_read; +} + +static inline size_t stream_unused_buffer_space(struct stream *stream) +{ + return sizeof(stream->buffer) - stream->buffered_size; +} + +static inline bool stream_readable(struct stream *stream) +{ + int access_mode = stream->flags & O_ACCMODE; + if (access_mode == O_RDWR) + return true; + return access_mode == O_RDONLY; +} + +static inline bool stream_writable(struct stream *stream) +{ + int access_mode = stream->flags & O_ACCMODE; + if (access_mode == O_RDWR) + return true; + return access_mode == O_WRONLY; +} + +static inline int lbs_ferror(struct stream *stream) +{ + return stream->error; +} + +static inline void lbs_clearerr(struct stream *stream) +{ + stream->error = 0; +} + +static inline void lbs_setbufmode(struct stream *stream, + enum stream_buffering mode) +{ + stream->buffering_mode = mode; +} + +struct stream *lbs_fopen(const char *path, const char *mode); +struct stream *lbs_fdopen(int fd, const char *mode); +int lbs_fflush(struct stream *stream); +int lbs_fclose(struct stream *stream); +int lbs_fputc(int c, struct stream *stream); +int lbs_fgetc(struct stream *stream); + +#endif /* !LIBSTREAM_H */ diff --git a/graphs/piscine/tinylibstream/src/tinylibstream.c b/graphs/piscine/tinylibstream/src/tinylibstream.c new file mode 100644 index 0000000..dca1c01 --- /dev/null +++ b/graphs/piscine/tinylibstream/src/tinylibstream.c @@ -0,0 +1,221 @@ +#include <stdlib.h> +#include <string.h> + +#include "../include/libstream.h" + +int get_flags(const char *mode) +{ + int flags; + if (strcmp(mode, "r") == 0) + { + flags = O_RDONLY; + } + else if (strcmp(mode, "r+") == 0) + { + flags = O_RDWR; + } + else if (strcmp(mode, "w") == 0) + { + flags = O_WRONLY | O_TRUNC | O_CREAT; + } + else + { + flags = O_RDWR | O_TRUNC | O_CREAT; + } + + return flags; +} + +struct stream *lbs_fopen(const char *path, const char *mode) +{ + int fd = open(path, get_flags(mode)); + + return lbs_fdopen(fd, mode); +} + +struct stream *lbs_fdopen(int fd, const char *mode) +{ + if (fd == -1) + { + return NULL; + } + + struct stream *s = malloc(sizeof(struct stream)); + if (s == NULL) + { + return NULL; + } + + s->flags = get_flags(mode); + s->error = 0; + s->fd = fd; + if (isatty(fd)) + { + s->buffering_mode = STREAM_LINE_BUFFERED; + } + else + { + s->buffering_mode = STREAM_BUFFERED; + } + s->buffered_size = 0; + s->already_read = 0; + + return s; +} + +int lbs_fflush(struct stream *stream) +{ + if (stream == NULL || stream->buffered_size == 0) + { + return 0; + } + + if (stream->io_operation == STREAM_READING) + { + if (!stream_readable(stream)) + { + stream->error = 1; + return LBS_EOF; + } + if (stream_remaining_buffered(stream) != 0 + && lseek(stream->fd, -stream_remaining_buffered(stream), SEEK_CUR) + == -1) + { + stream->error = 1; + return LBS_EOF; + } + stream->buffered_size = 0; + stream->already_read = 0; + } + else + { + if (!stream_writable(stream)) + { + stream->error = 1; + return LBS_EOF; + } + ssize_t w; + if ((w = write(stream->fd, stream->buffer, stream->buffered_size)) + == -1) + { + stream->error = 1; + return LBS_EOF; + } + stream->buffered_size = 0; + stream->already_read = 0; + } + return 0; +} + +int lbs_fclose(struct stream *stream) +{ + if (stream == NULL) + { + return 1; + } + + lbs_fflush(stream); + if (close(stream->fd) == -1) + { + return 1; + } + + free(stream); + + return 0; +} + +int lbs_fputc(int c, struct stream *stream) +{ + if (!stream_writable(stream)) + { + stream->error = 1; + return -1; + } + + if (stream->io_operation == STREAM_READING) + { + if (lbs_fflush(stream) != 0) + { + return -1; + } + stream->buffered_size = 0; + stream->already_read = 0; + } + stream->io_operation = STREAM_WRITING; + + if (stream_unused_buffer_space(stream) == 0 + || stream->buffering_mode == STREAM_UNBUFFERED) + { + if (lbs_fflush(stream) != 0) + { + return -1; + } + } + + stream->buffer[stream->buffered_size] = c; + stream->buffered_size++; + if (stream_unused_buffer_space(stream) == 0 + || stream->buffering_mode == STREAM_UNBUFFERED + || (stream->buffering_mode == STREAM_LINE_BUFFERED && c == '\n')) + { + if (lbs_fflush(stream) != 0) + { + return -1; + } + } + + return c; +} + +int refill_buffer(struct stream *stream) +{ + stream->already_read = 0; + ssize_t r; + if ((r = read(stream->fd, stream->buffer, LBS_BUFFER_SIZE)) == -1) + { + stream->error = 1; + return -1; + } + if (r == 0) + { + return -1; + } + stream->buffered_size = r; + return r; +} + +int lbs_fgetc(struct stream *stream) +{ + if (!stream_readable(stream)) + { + stream->error = 1; + return -1; + } + if (stream->io_operation == STREAM_WRITING) + { + if (lbs_fflush(stream) != 0) + { + stream->error = 1; + return -1; + } + stream->already_read = 0; + } + stream->io_operation = STREAM_READING; + + if (stream_remaining_buffered(stream) == 0) + { + int r; + if ((r = refill_buffer(stream)) == -1) + { + stream->error = 1; + return -1; + } + } + + int res = stream->buffer[stream->already_read++]; + + unsigned char c = res; + + return c; +} diff --git a/graphs/piscine/tinylibstream/stdin_buffering_test.c b/graphs/piscine/tinylibstream/stdin_buffering_test.c new file mode 100644 index 0000000..6d3361b --- /dev/null +++ b/graphs/piscine/tinylibstream/stdin_buffering_test.c @@ -0,0 +1,70 @@ +#define _GNU_SOURCE +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +struct slow_cookie +{ + int fd; +}; + +static ssize_t slow_read(void *vcookie, char *buf, size_t count) +{ + struct slow_cookie *cookie = vcookie; + usleep(500000); // sleep for half of a second + + ssize_t res; + + while ((res = read(cookie->fd, buf, count)) < 0) + if (errno != EINTR && errno != EAGAIN) + break; + + return res; +} + +static int slow_close(void *vcookie) +{ + struct slow_cookie *cookie = vcookie; + return close(cookie->fd); +} + +cookie_io_functions_t slow_stdio = { + .read = slow_read, + .close = slow_close, +}; + +int main(void) +{ + /* setup a custom stdin stream with a slow read function */ + struct slow_cookie cookie = { + .fd = STDIN_FILENO, + }; + + FILE *input_stream = fopencookie(&cookie, "r", slow_stdio); + + /* change the buffer size to the one given by stdbuf. + ** it doesn't work out of the box as stdbuf only does + ** this for the already existing stdin stream. + */ + char *buffer = NULL; + char *buffer_size = getenv("_STDBUF_I"); + if (buffer_size) + { + size_t size = atoi(buffer_size); + buffer = malloc(size); + setvbuf(input_stream, buffer, _IOFBF, size); + } + + /* forward all characters from stdin to stdout */ + int c; + while ((c = fgetc(input_stream)) != EOF) + { + fputc(c, stdout); + fflush(stdout); + } + + fclose(input_stream); + free(buffer); + return 0; +} diff --git a/graphs/piscine/tinylibstream/stdout_buffering_test.c b/graphs/piscine/tinylibstream/stdout_buffering_test.c new file mode 100644 index 0000000..45c0a83 --- /dev/null +++ b/graphs/piscine/tinylibstream/stdout_buffering_test.c @@ -0,0 +1,13 @@ +#define _XOPEN_SOURCE 500 +#include <stdio.h> +#include <unistd.h> + +int main(void) +{ + const char test_string[] = "Robin\nloves\nBatman\n"; + for (size_t i = 0; test_string[i]; i++) + { + usleep(100000); // wait a tenth of a second + putchar(test_string[i]); + } +} diff --git a/graphs/piscine/tinyprintf/Makefile b/graphs/piscine/tinyprintf/Makefile new file mode 100644 index 0000000..6a07d90 --- /dev/null +++ b/graphs/piscine/tinyprintf/Makefile @@ -0,0 +1,17 @@ +CC=gcc +CFLAGS=-std=c99 -Wall -Wextra -Werror -Wvla -pedantic +LDLIBS=-lcriterion + +all: src/tinyprintf.o + +check: src/tinyprintf.o + $(CC) $(CFLAGS) -o tinytests src/tinyprintf.o tests/tests.c $(LDLIBS) + ./tinytests + +src/tinyprintf.o: src/tinyprintf.c + $(CC) $(CFLAGS) -c -o src/tinyprintf.o src/tinyprintf.c + +.PHONY: clean + +clean: + rm src/tinyprintf.o tinytests diff --git a/graphs/piscine/tinyprintf/src/tinyprintf.c b/graphs/piscine/tinyprintf/src/tinyprintf.c new file mode 100644 index 0000000..d005db7 --- /dev/null +++ b/graphs/piscine/tinyprintf/src/tinyprintf.c @@ -0,0 +1,251 @@ +#include "tinyprintf.h" + +#include <stdio.h> +#include <stdlib.h> + +int tinyprintf(const char *format, ...) +{ + if (format == NULL || *format == '\0') + { + return 0; + } + + va_list ap; + va_start(ap, format); + int res = 0; + + size_t i = 0; + while (format[i]) + { + if (format[i] != '%') + { + putchar(format[i]); + res++; + } + else + { + dispatch(format[i + 1], ap, &res); + format++; + } + format++; + } + va_end(ap); + return res; +} + +void dispatch(char c, va_list ap, int *res) +{ + switch (c) + { + case '%': + putchar('%'); + (*res)++; + break; + case 'd': + handle_d(va_arg(ap, int), res); + break; + case 'u': + handle_u(va_arg(ap, unsigned int), res); + break; + case 'x': + handle_x(va_arg(ap, unsigned int), res); + break; + case 'o': + handle_o(va_arg(ap, unsigned int), res); + break; + case 'c': + putchar(va_arg(ap, int)); + (*res)++; + break; + case 's': + handle_s(va_arg(ap, char *), res); + break; + default: + putchar('%'); + putchar(c); + *res += 2; + break; + } +} + +void handle_d(int val, int *res) +{ + if (val < 0) + { + putchar('-'); + (*res)++; + val = -val; + } + + if (val == 0) + { + putchar('0'); + (*res)++; + } + + int t = val; + int n = 0; + while (t > 0) + { + t /= 10; + n++; + } + + char *s = malloc(n * sizeof(char)); + int m = n; + if (s == NULL) + { + return; + } + n--; + for (; n >= 0; n--) + { + s[n] = val % 10 + '0'; + val /= 10; + } + + // actual printing + for (int i = 0; i < m; i++) + { + putchar(s[i]); + (*res)++; + } + free(s); +} + +void handle_s(char *s, int *res) +{ + if (s == NULL) + { + char *text = "(null)"; + for (; *text; text++) + { + putchar(*text); + (*res)++; + } + return; + } + for (; *s; s++) + { + putchar(*s); + (*res)++; + } +} + +void handle_u(unsigned int val, int *res) +{ + if (val == 0) + { + putchar('0'); + (*res)++; + } + + unsigned int t = val; + int n = 0; + while (t > 0) + { + t /= 10; + n++; + } + + char *s = malloc(n * sizeof(char)); + int m = n; + if (s == NULL) + { + return; + } + n--; + for (; n >= 0; n--) + { + s[n] = val % 10 + '0'; + val /= 10; + } + + // actual printing + for (int i = 0; i < m; i++) + { + putchar(s[i]); + (*res)++; + } + free(s); +} + +void handle_x(unsigned int val, int *res) +{ + if (val == 0) + { + putchar('0'); + (*res)++; + } + + unsigned int t = val; + int n = 0; + while (t > 0) + { + t /= 16; + n++; + } + + char *s = malloc(n * sizeof(char)); + int m = n; + if (s == NULL) + { + return; + } + n--; + for (; n >= 0; n--) + { + s[n] = val % 16 + '0'; + if (s[n] > '9') + { + s[n] = (s[n] - '0') % 10 + 'a'; + } + val /= 16; + } + + // actual printing + for (int i = 0; i < m; i++) + { + putchar(s[i]); + (*res)++; + } + free(s); +} + +void handle_o(unsigned int val, int *res) +{ + if (val == 0) + { + putchar('0'); + (*res)++; + } + + unsigned int t = val; + int n = 0; + while (t > 0) + { + t /= 8; + n++; + } + + char *s = malloc(n * sizeof(char)); + int m = n; + if (s == NULL) + { + return; + } + n--; + for (; n >= 0; n--) + { + s[n] = val % 8 + '0'; + val /= 8; + } + + // actual printing + for (int i = 0; i < m; i++) + { + putchar(s[i]); + (*res)++; + } + free(s); +} diff --git a/graphs/piscine/tinyprintf/src/tinyprintf.h b/graphs/piscine/tinyprintf/src/tinyprintf.h new file mode 100644 index 0000000..fd1f0b4 --- /dev/null +++ b/graphs/piscine/tinyprintf/src/tinyprintf.h @@ -0,0 +1,15 @@ +#ifndef TINYPRINTF_H +#define TINYPRINTF_H + +#include <stdarg.h> +#include <stddef.h> + +int tinyprintf(const char *format, ...); +void handle_d(int val, int *res); +void handle_u(unsigned int val, int *res); +void handle_x(unsigned int val, int *res); +void handle_o(unsigned int val, int *res); +void handle_s(char *s, int *res); +void dispatch(char c, va_list ap, int *res); + +#endif /* ! TINYPRINTF_H */ diff --git a/graphs/piscine/tinyprintf/tests/tests.c b/graphs/piscine/tinyprintf/tests/tests.c new file mode 100644 index 0000000..4235203 --- /dev/null +++ b/graphs/piscine/tinyprintf/tests/tests.c @@ -0,0 +1,213 @@ +#include <criterion/criterion.h> +#include <criterion/assert.h> +#include <criterion/redirect.h> +#include <stdio.h> + +#include "../src/tinyprintf.h" + +TestSuite(TestHandleD); + +Test(TestHandleD, handle_d42, .init = cr_redirect_stdout) +{ + int res = 0; + handle_d(42, &res); + fflush(stdout); + cr_assert_stdout_eq_str("42"); + cr_expect(res == 2, "Expected: %d. Got: %d", 2, res); +} + +Test(TestHandleD, handle_d0, .init = cr_redirect_stdout) +{ + int res = 0; + handle_d(0, &res); + fflush(stdout); + cr_assert_stdout_eq_str("0"); + cr_expect(res == 1, "Expected: %d. Got: %d", 1, res); +} + +Test(TestHandleD, handle_dminus42, .init = cr_redirect_stdout) +{ + int res = 0; + handle_d(-42, &res); + fflush(stdout); + cr_assert_stdout_eq_str("-42"); + cr_expect(res == 3, "Expected: %d. Got: %d", 3, res); +} + +Test(TestHandleD, simple_print, .init = cr_redirect_stdout) +{ + int retval = tinyprintf("%s [%d] %s", "Hello", 42, "world!"); + fflush(stdout); + cr_assert_stdout_eq_str("Hello [42] world!"); + cr_expect(retval == 17, "Expected: %d. Got: %d", 17, retval); +} + +TestSuite(TestHandleX); + +Test(TestHandleX, handle_x42, .init = cr_redirect_stdout) +{ + int res = 0; + handle_x(42, &res); + fflush(stdout); + cr_assert_stdout_eq_str("2a"); + cr_expect(res == 2, "Expected: %d. Got: %d", 2, res); +} + +Test(TestHandleX, handle_x0, .init = cr_redirect_stdout) +{ + int res = 0; + handle_x(0, &res); + fflush(stdout); + cr_assert_stdout_eq_str("0"); + cr_expect(res == 1, "Expected: %d. Got: %d", 1, res); +} + +Test(TestHandleX, handle_x15, .init = cr_redirect_stdout) +{ + int res = 0; + handle_x(15, &res); + fflush(stdout); + cr_assert_stdout_eq_str("f"); + cr_expect(res == 1, "Expected: %d. Got: %d", 1, res); +} + +Test(TestHandleX, handle_0xdeadc0de, .init = cr_redirect_stdout) +{ + int res = 0; + handle_x(0xdeadc0de, &res); + fflush(stdout); + cr_assert_stdout_eq_str("deadc0de"); + cr_expect(res == 8, "Expected: %d. Got: %d", 8, res); +} + +Test(TestHandleX, simple_print_hexa, .init = cr_redirect_stdout) +{ + int retval = tinyprintf("%s [%x] %s", "Hello", 42, "world!"); + fflush(stdout); + cr_assert_stdout_eq_str("Hello [2a] world!"); + cr_expect(retval == 17, "Expected: %d. Got: %d", 17, retval); +} + +TestSuite(TestHandleU); + +Test(TestHandleU, handle_u42, .init = cr_redirect_stdout) +{ + int res = 0; + handle_u(42, &res); + fflush(stdout); + cr_assert_stdout_eq_str("42"); + cr_expect(res == 2, "Expected: %d. Got: %d", 2, res); +} + +Test(TestHandleU, handle_u0, .init = cr_redirect_stdout) +{ + int res = 0; + handle_u(0, &res); + fflush(stdout); + cr_assert_stdout_eq_str("0"); + cr_expect(res == 1, "Expected: %d. Got: %d", 1, res); +} + +Test(TestHandleU, handle_u15, .init = cr_redirect_stdout) +{ + int res = 0; + handle_u(15, &res); + fflush(stdout); + cr_assert_stdout_eq_str("15"); + cr_expect(res == 2, "Expected: %d. Got: %d", 2, res); +} + +Test(TestHandleU, simple_print_unsigned, .init = cr_redirect_stdout) +{ + int retval = tinyprintf("%s [%u] %s", "Hello", 42, "world!"); + fflush(stdout); + cr_assert_stdout_eq_str("Hello [42] world!"); + cr_expect(retval == 17, "Expected: %d. Got: %d", 17, retval); +} + +TestSuite(TestHandleO); + +Test(TestHandleO, handle_o42, .init = cr_redirect_stdout) +{ + int res = 0; + handle_o(42, &res); + fflush(stdout); + cr_assert_stdout_eq_str("52"); + cr_expect(res == 2, "Expected: %d. Got: %d", 2, res); +} + +Test(TestHandleO, handle_o0, .init = cr_redirect_stdout) +{ + int res = 0; + handle_o(0, &res); + fflush(stdout); + cr_assert_stdout_eq_str("0"); + cr_expect(res == 1, "Expected: %d. Got: %d", 1, res); +} + +Test(TestHandleO, handle_o7, .init = cr_redirect_stdout) +{ + int res = 0; + handle_o(7, &res); + fflush(stdout); + cr_assert_stdout_eq_str("7"); + cr_expect(res == 1, "Expected: %d. Got: %d", 1, res); +} + +Test(TestHandleO, simple_print_octal, .init = cr_redirect_stdout) +{ + int retval = tinyprintf("%s [%o] %s", "Hello", 42, "world!"); + fflush(stdout); + cr_assert_stdout_eq_str("Hello [52] world!"); + cr_expect(retval == 17, "Expected: %d. Got: %d", 17, retval); +} + +TestSuite(TestPrint); + +Test(TestPrint, print_percent, .init = cr_redirect_stdout) +{ + int retval = tinyprintf("%%s", "in your head"); + fflush(stdout); + cr_assert_stdout_eq_str("%s"); + cr_expect(retval == 2, "Expected: %d. Got: %d", 2, retval); +} + +Test(TestPrint, print_unknown_option, .init = cr_redirect_stdout) +{ + int retval = tinyprintf("Good morning ACU! %t Tinyprintf is cool", 12); + fflush(stdout); + cr_assert_stdout_eq_str("Good morning ACU! %t Tinyprintf is cool"); + cr_expect(retval == 39, "Expected: %d. Got: %d", 39, retval); +} + +Test(TestPrint, print_tricky, .init = cr_redirect_stdout) +{ + int retval = tinyprintf("%c%c is %s... %d too.", '4', '2', "the answer", '*'); + fflush(stdout); + cr_assert_stdout_eq_str("42 is the answer... 42 too."); + cr_expect(retval == 27, "Expected: %d. Got: %d", 27, retval); +} + +Test(TestPrint, print_null, .init = cr_redirect_stdout) +{ + int retval = tinyprintf("%c%c is %s... %d too.", '4', '2', NULL, '*'); + fflush(stdout); + cr_assert_stdout_eq_str("42 is (null)... 42 too."); + cr_expect(retval == 23, "Expected: %d. Got: %d", 23, retval); +} + +Test(TestPrint, print_null_fmt, .init = cr_redirect_stdout) +{ + int retval = tinyprintf(NULL, '4', '2', NULL, '*'); + fflush(stdout); + cr_assert_stdout_eq_str(""); + cr_expect(retval == 0, "Expected: %d. Got: %d", 0, retval); +} + +Test(TestPrint, print_empty_fmt, .init = cr_redirect_stdout) +{ + int retval = tinyprintf("", '4', '2', NULL, '*'); + fflush(stdout); + cr_assert_stdout_eq_str(""); + cr_expect(retval == 0, "Expected: %d. Got: %d", 0, retval); +} diff --git a/graphs/piscine/traffic_lights/traffic_lights.c b/graphs/piscine/traffic_lights/traffic_lights.c new file mode 100644 index 0000000..76ea94f --- /dev/null +++ b/graphs/piscine/traffic_lights/traffic_lights.c @@ -0,0 +1,38 @@ +#include "traffic_lights.h" + +void init(unsigned char *lights) +{ + *lights <<= 4; +} + +void turn_on(unsigned char *lights, unsigned char light_num) +{ + *lights |= 1 << (light_num - 1); +} + +void turn_off(unsigned char *lights, unsigned char light_num) +{ + *lights &= ~(1 << (light_num - 1)); +} + +void next_step(unsigned char *lights) +{ + *lights <<= 1; + *lights += *lights >> 4; +} + +void reverse(unsigned char *lights) +{ + *lights = ~*lights; +} + +void swap(unsigned char *lights_1, unsigned char *lights_2) +{ + if (lights_1 == lights_2) + { + return; + } + *lights_1 = *lights_2 ^ *lights_1; + *lights_2 = *lights_1 ^ *lights_2; + *lights_1 = *lights_2 ^ *lights_1; +} diff --git a/graphs/piscine/traffic_lights/traffic_lights.h b/graphs/piscine/traffic_lights/traffic_lights.h new file mode 100644 index 0000000..7c803ea --- /dev/null +++ b/graphs/piscine/traffic_lights/traffic_lights.h @@ -0,0 +1,11 @@ +#ifndef TRAFFIC_LIGHTS_H +#define TRAFFIC_LIGHTS_H + +void init(unsigned char *lights); +void turn_on(unsigned char *lights, unsigned char light_num); +void turn_off(unsigned char *lights, unsigned char light_num); +void next_step(unsigned char *lights); +void reverse(unsigned char *lights); +void swap(unsigned char *lights_1, unsigned char *lights_2); + +#endif /* !TRAFFIC_LIGHTS_H */ diff --git a/graphs/piscine/user_ids/get_ids.sh b/graphs/piscine/user_ids/get_ids.sh new file mode 100644 index 0000000..2a1668b --- /dev/null +++ b/graphs/piscine/user_ids/get_ids.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +cut --delimiter=: --fields=3 -s /etc/passwd | sort -rgu diff --git a/graphs/piscine/using_special_variables/print.sh b/graphs/piscine/using_special_variables/print.sh new file mode 100755 index 0000000..c24bebd --- /dev/null +++ b/graphs/piscine/using_special_variables/print.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +echo $# +echo $* +echo $1 +echo $2 +echo $3 +echo ${13} +echo $0 diff --git a/graphs/piscine/variant/variant.c b/graphs/piscine/variant/variant.c new file mode 100644 index 0000000..eb2f8a8 --- /dev/null +++ b/graphs/piscine/variant/variant.c @@ -0,0 +1,96 @@ +#include "variant.h" + +#include <stdio.h> +#include <string.h> + +void variant_display(const struct variant *e) +{ + switch (e->type) + { + case (TYPE_INT): + printf("%d\n", e->value.int_v); + break; + case (TYPE_FLOAT): + printf("%f\n", e->value.float_v); + break; + case (TYPE_CHAR): + printf("%c\n", e->value.char_v); + break; + default: + printf("%s\n", e->value.str_v); + break; + } +} + +bool variant_equal(const struct variant *left, const struct variant *right) +{ + if (left == NULL || right == NULL) + { + return true; + } + switch (left->type) + { + case (TYPE_INT): + if (right->type != TYPE_INT) + { + return false; + } + return left->value.int_v == right->value.int_v; + case (TYPE_FLOAT): + if (right->type != TYPE_FLOAT) + { + return false; + } + return left->value.float_v == right->value.float_v; + case (TYPE_CHAR): + if (right->type != TYPE_CHAR) + { + return false; + } + return left->value.char_v == right->value.char_v; + default: + if (right->type != TYPE_STRING) + { + return false; + } + return strcmp(left->value.str_v, right->value.str_v) == 0; + } +} + +int variant_find(const struct variant *array, size_t len, enum type type, + union type_any value) +{ + size_t i; + struct variant cmp = { type, value }; + for (i = 0; i < len && variant_equal(array + i, &cmp) == false; i++) + { + continue; + } + + if (i == len) + { + return -1; + } + return i; +} + +float variant_sum(const struct variant *array, size_t len) +{ + if (array == NULL) + { + return 0; + } + float sum = 0; + for (size_t i = 0; i < len; i++) + { + if (array[i].type == TYPE_FLOAT) + { + sum += array[i].value.float_v; + } + else if (array[i].type == TYPE_INT) + { + sum += array[i].value.int_v; + } + } + return sum; +} diff --git a/graphs/piscine/variant/variant.h b/graphs/piscine/variant/variant.h new file mode 100644 index 0000000..9983bc1 --- /dev/null +++ b/graphs/piscine/variant/variant.h @@ -0,0 +1,35 @@ +#ifndef VARIANT_H +#define VARIANT_H + +#include <stdbool.h> +#include <stddef.h> + +enum type +{ + TYPE_INT, + TYPE_FLOAT, + TYPE_CHAR, + TYPE_STRING +}; + +union type_any +{ + int int_v; + float float_v; + char char_v; + const char *str_v; +}; + +struct variant +{ + enum type type; + union type_any value; +}; + +void variant_display(const struct variant *e); +bool variant_equal(const struct variant *left, const struct variant *right); +int variant_find(const struct variant *array, size_t len, enum type type, + union type_any value); +float variant_sum(const struct variant *array, size_t len); + +#endif /* !VARIANT_H */ diff --git a/graphs/piscine/vector/Makefile b/graphs/piscine/vector/Makefile new file mode 100644 index 0000000..744241f --- /dev/null +++ b/graphs/piscine/vector/Makefile @@ -0,0 +1,13 @@ +CC = gcc +CFLAGS = -Wall -Werror -Wvla -Wextra -std=c99 -pedantic + +.PHONY: library clean + +library: vector.o + ar csr libvector.a vector.o + +vector.o: vector.c + $(CC) $(CFLAGS) -c -o vector.o vector.c + +clean: + $(RM) libvector.a vector.o diff --git a/graphs/piscine/vector/vector.c b/graphs/piscine/vector/vector.c new file mode 100644 index 0000000..cbd19aa --- /dev/null +++ b/graphs/piscine/vector/vector.c @@ -0,0 +1,152 @@ +#include "vector.h" + +#include <stdio.h> +#include <stdlib.h> + +struct vector *vector_init(size_t n) +{ + struct vector *res = malloc(sizeof(struct vector)); + if (res == NULL) + { + return NULL; + } + + res->size = 0; + res->capacity = n; + res->data = malloc(n * sizeof(int)); + if (res->data == NULL) + { + return NULL; + } + return res; +} + +void vector_destroy(struct vector *v) +{ + if (v) + { + free(v->data); + free(v); + } +} + +struct vector *vector_resize(struct vector *v, size_t n) +{ + if (!v) + { + return NULL; + } + if (n == v->capacity) + { + return v; + } + if (v) + { + int *tmp = realloc(v->data, n * sizeof(int)); + if (tmp == NULL) + { + return NULL; + } + v->data = tmp; + + if (n < v->size) + { + v->size = n; + } + v->capacity = n; + return v; + } + return NULL; +} + +struct vector *vector_append(struct vector *v, int elt) +{ + if (v == NULL) + { + return NULL; + } + + if (v->size == v->capacity) + { + if (vector_resize(v, v->capacity * 2) == NULL) + { + return NULL; + } + } + v->data[v->size] = elt; + v->size++; + return v; +} + +void vector_print(const struct vector *v) +{ + if (v == NULL || v->size == 0) + { + printf("\n"); + return; + } + for (size_t i = 0; i < v->size - 1; i++) + { + printf("%d,", v->data[i]); + } + printf("%d\n", v->data[v->size - 1]); +} + +struct vector *vector_reset(struct vector *v, size_t n) +{ + if (vector_resize(v, n) == NULL) + { + return NULL; + } + + v->size = 0; + return v; +} + +struct vector *vector_insert(struct vector *v, size_t i, int elt) +{ + if (v == NULL || i > v->size) + return NULL; + if (i == v->size) + { + return vector_append(v, elt); + } + if (v->size == v->capacity) + { + if (vector_resize(v, v->capacity * 2) == NULL) + { + return NULL; + } + } + for (size_t j = v->size; j > i; j--) + { + v->data[j] = v->data[j - 1]; + } + v->size++; + + v->data[i] = elt; + return v; +} + +struct vector *vector_remove(struct vector *v, size_t i) +{ + if (v == NULL || v->size == 0 || i >= v->size) + { + return NULL; + } + for (size_t j = i; j < v->size - 1; j++) + { + v->data[j] = v->data[j + 1]; + } + + v->size--; + + if (v->size < v->capacity / 2) + { + if (vector_resize(v, v->capacity / 2) == NULL) + { + return NULL; + } + } + return v; +} diff --git a/graphs/piscine/vector/vector.h b/graphs/piscine/vector/vector.h new file mode 100644 index 0000000..5afada7 --- /dev/null +++ b/graphs/piscine/vector/vector.h @@ -0,0 +1,64 @@ +#ifndef VECTOR_H +#define VECTOR_H + +#include <stddef.h> + +struct vector +{ + // The number of elements in the vector + size_t size; + // The maximum number of elements in the vector + size_t capacity; + // The elements themselves + int *data; +}; + +/* +** Initialize the vector with `n` capacity. +** Returns `NULL` if an error occured. +*/ +struct vector *vector_init(size_t n); + +/* +** Release the memory used by the vector. +** Does nothing if `v` is `NULL`. +*/ +void vector_destroy(struct vector *v); + +/* +** Resize the vector to `n` capacity. +** Returns `NULL` if an error occured. +*/ +struct vector *vector_resize(struct vector *v, size_t n); + +/* +** Append an element to the end of the vector. Expand the vector if needed. +** Returns `NULL` if an error occured. +*/ +struct vector *vector_append(struct vector *v, int elt); + +/* +** Display the vector contents on `stdout`. +** Displays `\n` if `v` is `NULL`. +*/ +void vector_print(const struct vector *v); + +/* +** Remove all the elements of the vector, and resize it to `n` capacity. +** Returns `NULL` if an error occured. +*/ +struct vector *vector_reset(struct vector *v, size_t n); + +/* +** Insert `n` at the index `i`. Expand the vector if needed. +** Returns `NULL` if an error occured. +*/ +struct vector *vector_insert(struct vector *v, size_t i, int elt); + +/* +** Remove the element at the index `i`. +** Returns `NULL` if an error occured. +*/ +struct vector *vector_remove(struct vector *v, size_t i); + +#endif /* !VECTOR_H */ diff --git a/graphs/sql/a_new_dawn/req01.sql b/graphs/sql/a_new_dawn/req01.sql new file mode 100644 index 0000000..78015ec --- /dev/null +++ b/graphs/sql/a_new_dawn/req01.sql @@ -0,0 +1,66 @@ +CREATE SCHEMA nexus; +CREATE SCHEMA nexus_it; +CREATE SCHEMA techwave; +CREATE SCHEMA nexus_food; +CREATE SCHEMA guardforce; +CREATE TYPE nexus.position AS ENUM ( + 'JUNIOR', + 'SENIOR', + 'MANAGER', + 'DIRECTOR' +); +CREATE TYPE nexus.relationship_type AS ENUM ( + 'PARENT', + 'SUBSIDIARY', + 'AFFILIATE' +); +CREATE TYPE nexus_food.nutriscore AS ENUM ( + 'A', + 'B', + 'C', + 'D', + 'E' +); +CREATE TABLE nexus.employees +( + id SERIAL PRIMARY KEY, + first_name VARCHAR(25), + last_name VARCHAR(25), + employee_position nexus.position, + salary NUMERIC(10, 2) +); +CREATE TABLE nexus.nexus_relations +( + id SERIAL PRIMARY KEY, + parent_company VARCHAR(25), + child_company VARCHAR(25), + relationship_type nexus.relationship_type +); +CREATE TABLE nexus_it.software_assets +( + id SERIAL PRIMARY KEY, + software_name VARCHAR(50), + license_key UUID, + expiration_date DATE +); +CREATE TABLE techwave.project_milestones +( + id SERIAL PRIMARY KEY, + milestone_name VARCHAR(50), + due_date DATE, + completion_status BOOLEAN +); +CREATE TABLE nexus_food.products +( + id SERIAL PRIMARY KEY, + product_name VARCHAR(25), + product_nutriscore nexus_food.nutriscore +); +CREATE TABLE guardforce.incident_reports +( + id SERIAL PRIMARY KEY, + incident_description TEXT, + incident_date TIMESTAMP, + incident_location VARCHAR(50), + reported_by VARCHAR(50) +); diff --git a/graphs/sql/a_new_dawn/req02.sql b/graphs/sql/a_new_dawn/req02.sql new file mode 100644 index 0000000..6c705da --- /dev/null +++ b/graphs/sql/a_new_dawn/req02.sql @@ -0,0 +1,8 @@ +ALTER TABLE nexus.employees +ADD email VARCHAR(50); +ALTER TABLE nexus_it.software_assets +DROP IF EXISTS license_key; +ALTER TABLE nexus_food.products +RENAME COLUMN product_name TO product_title; +ALTER TABLE nexus.employees +ALTER COLUMN salary TYPE INTEGER; diff --git a/graphs/sql/a_new_dawn/req03.sql b/graphs/sql/a_new_dawn/req03.sql new file mode 100644 index 0000000..ef8c903 --- /dev/null +++ b/graphs/sql/a_new_dawn/req03.sql @@ -0,0 +1,6 @@ +DROP TABLE nexus.employees; +DROP TABLE nexus.nexus_relations; +DROP TABLE nexus_it.software_assets; +DROP TABLE techwave.project_milestones; +DROP TABLE nexus_food.products; +DROP TABLE guardforce.incident_reports; diff --git a/graphs/sql/a_new_dawn/req04.sql b/graphs/sql/a_new_dawn/req04.sql new file mode 100644 index 0000000..e3eb7cf --- /dev/null +++ b/graphs/sql/a_new_dawn/req04.sql @@ -0,0 +1,3 @@ +DROP TYPE nexus.position; +DROP TYPE nexus.relationship_type; +DROP TYPE nexus_food.nutriscore; diff --git a/graphs/sql/a_new_dawn/req05.sql b/graphs/sql/a_new_dawn/req05.sql new file mode 100644 index 0000000..d99e6e8 --- /dev/null +++ b/graphs/sql/a_new_dawn/req05.sql @@ -0,0 +1,5 @@ +DROP SCHEMA nexus; +DROP SCHEMA nexus_it; +DROP SCHEMA techwave; +DROP SCHEMA nexus_food; +DROP SCHEMA guardforce; diff --git a/graphs/sql/a_new_dawn/req06.sql b/graphs/sql/a_new_dawn/req06.sql new file mode 100644 index 0000000..87eb6e3 --- /dev/null +++ b/graphs/sql/a_new_dawn/req06.sql @@ -0,0 +1,5 @@ +DROP SCHEMA IF EXISTS nexus CASCADE; +DROP SCHEMA IF EXISTS nexus_it CASCADE; +DROP SCHEMA IF EXISTS nexus_food CASCADE; +DROP SCHEMA IF EXISTS techwave CASCADE; +DROP SCHEMA IF EXISTS guardforce CASCADE; diff --git a/graphs/sql/battle_plan/req01.sql b/graphs/sql/battle_plan/req01.sql new file mode 100644 index 0000000..8adb788 --- /dev/null +++ b/graphs/sql/battle_plan/req01.sql @@ -0,0 +1,19 @@ +EXPLAIN (ANALYZE, COSTS, BUFFERS, VERBOSE, FORMAT YAML) +WITH RECURSIVE fib AS ( + SELECT + 1 AS n, + 1::bigint AS fibn, + 1::bigint AS fibn_1 + UNION ALL + SELECT + n + 1 AS n, + fibn_1 AS fibn, + fibn + fibn_1 AS fibn_1 + FROM fib + WHERE n < 80 +) + +SELECT + n, + fibn +FROM fib; diff --git a/graphs/sql/battle_plan/req02.sql b/graphs/sql/battle_plan/req02.sql new file mode 100644 index 0000000..a9d8e9b --- /dev/null +++ b/graphs/sql/battle_plan/req02.sql @@ -0,0 +1,8 @@ +SELECT * +FROM ( + VALUES + ('a', 2), + ('b', 3), + ('b', 4), + ('c', 1) +) AS answers(question, choice); diff --git a/graphs/sql/battle_plan/req03.sql b/graphs/sql/battle_plan/req03.sql new file mode 100644 index 0000000..5a3ba51 --- /dev/null +++ b/graphs/sql/battle_plan/req03.sql @@ -0,0 +1,17 @@ +SELECT + people.first_name, + people.last_name, + gusto_tables.number_of_seats AS guest_number, + round(reservations.bill_total::numeric, 2) AS bill_total +FROM gusto_reservations AS reservations, + gusto_tables, + gusto_guests AS guests, + people +WHERE reservations.table_id = gusto_tables.id + AND reservations.id = guests.reservation_id + AND reservations.cancelled = FALSE + AND guests.guest_id = people.id + AND people.last_name LIKE concat(reservations.reservation_name, '%') +ORDER BY + gusto_tables.number_of_seats ASC, reservations.bill_total DESC NULLS LAST +LIMIT 10; diff --git a/graphs/sql/battle_plan/req04.sql b/graphs/sql/battle_plan/req04.sql new file mode 100644 index 0000000..33988c6 --- /dev/null +++ b/graphs/sql/battle_plan/req04.sql @@ -0,0 +1,8 @@ +SELECT * +FROM ( + VALUES + ('a', 1), + ('b', 1), + ('b', 3), + ('c', 1) +) AS answers(question, choice); diff --git a/graphs/sql/corrupted_friends/req01.sql b/graphs/sql/corrupted_friends/req01.sql new file mode 100644 index 0000000..bc759f7 --- /dev/null +++ b/graphs/sql/corrupted_friends/req01.sql @@ -0,0 +1,18 @@ +CREATE TYPE public.prefix AS ENUM ( + 'MRS', + 'MS', + 'MR', + 'DR' +); + +CREATE TABLE dtf.madelines_contacts +( + id INTEGER PRIMARY KEY, + title public.prefix, + first_name TEXT, + last_name TEXT, + phone TEXT, + email TEXT, + favorite BOOLEAN, + created_at TIMESTAMP +); diff --git a/graphs/sql/corrupted_friends/req02.sql b/graphs/sql/corrupted_friends/req02.sql new file mode 100644 index 0000000..11f9947 --- /dev/null +++ b/graphs/sql/corrupted_friends/req02.sql @@ -0,0 +1,41 @@ +INSERT INTO dtf.madelines_contacts +SELECT +id, +upper(split_part(regexp_replace(trim(full_name), '([^[[:ascii:]]]*)|([[:digit:]]*)', '', 'g'), ' ', 1))::public.prefix AS title, +initcap(split_part(regexp_replace(trim(full_name), '([^[[:ascii:]]]*)|([[:digit:]]*)', '', 'g'), ' ', 2)) AS first_name, +initcap(split_part(regexp_replace(trim(full_name), '([^[[:ascii:]]]*)|([[:digit:]]*)', '', 'g'), ' ', 3)) AS last_name, +concat( + lpad( + regexp_replace( + regexp_replace(phone, '[^0-9\.\-]', '', 'g'), + '(.?.?.?)[\.\-].*', + '\1', + 'g' + ), + 3, '0' + ), + '.', + lpad( + regexp_replace( + regexp_replace(phone, '[^0-9\.\-]', '', 'g'), + '.*[\.\-](.?.?.?)[\.\-].*', + '\1', + 'g' + ), + 3, '0' + ), + '.', + lpad( + regexp_replace( + regexp_replace(phone, '[^0-9\.\-]', '', 'g'), + '.*[\.\-](.?.?.?)', + '\1', + 'g' + ), + 3, '0' + ) +) AS phone, +regexp_replace(trim(email), '[^[[:ascii:]]]', '', 'g') AS email, +trim(favorite) LIKE '1' AS favorite, +created_at::timestamp AS created_at +FROM dtf.madelines_contacts_corrupted AS c diff --git a/graphs/sql/corrupted_friends/req03.sql b/graphs/sql/corrupted_friends/req03.sql new file mode 100644 index 0000000..baa5863 --- /dev/null +++ b/graphs/sql/corrupted_friends/req03.sql @@ -0,0 +1,2 @@ +UPDATE dtf.madelines_contacts +SET email = concat(lower(first_name), '.', lower(last_name),'@roger_roger.com'); diff --git a/graphs/sql/daily_gazette/req01.sql b/graphs/sql/daily_gazette/req01.sql new file mode 100644 index 0000000..35ce8b8 --- /dev/null +++ b/graphs/sql/daily_gazette/req01.sql @@ -0,0 +1,14 @@ +CREATE SCHEMA rr_times; +CREATE TABLE rr_times.locales +( + language_code VARCHAR(2), + country_code VARCHAR(2), + name VARCHAR(50) UNIQUE NOT NULL, + PRIMARY KEY (language_code, country_code) +); +CREATE TABLE rr_times.translated_articles +( + id SERIAL PRIMARY KEY, + title TEXT NOT NULL, + body TEXT NOT NULL +); diff --git a/graphs/sql/daily_gazette/req02.sql b/graphs/sql/daily_gazette/req02.sql new file mode 100644 index 0000000..57eeb94 --- /dev/null +++ b/graphs/sql/daily_gazette/req02.sql @@ -0,0 +1,16 @@ +CREATE TABLE rr_times.translated_headlines +( + id SERIAL PRIMARY KEY, + title TEXT NOT NULL, + subtitle TEXT +); +CREATE TABLE rr_times.issues +( + id SERIAL PRIMARY KEY, + issued_at DATE NOT NULL, + language VARCHAR(2), + country VARCHAR(2), + FOREIGN KEY (language, country) REFERENCES rr_times.locales (language_code, country_code) ON DELETE SET NULL, + translated_headline_id INTEGER NOT NULL, + FOREIGN KEY (translated_headline_id) REFERENCES rr_times.translated_headlines (id) ON DELETE RESTRICT +); diff --git a/graphs/sql/daily_gazette/req03.sql b/graphs/sql/daily_gazette/req03.sql new file mode 100644 index 0000000..f0173c8 --- /dev/null +++ b/graphs/sql/daily_gazette/req03.sql @@ -0,0 +1,28 @@ +CREATE TYPE rr_times.rubric_theme AS ENUM +( + 'TECHNOLOGY', + 'ECONOMY', + 'HEALTH', + 'SPORT', + 'CULTURE', + 'POLITICS', + 'SCIENCE', + 'TRAVEL', + 'SOCIETY', + 'ENVIRONMENT', + 'EDUCATION', + 'MEDIA', + 'FASHION', + 'ARCHITECTURE', + 'BUSINESS', + 'SPACE' +); +CREATE TABLE rr_times.rubrics +( + id SERIAL UNIQUE NOT NULL, + theme rr_times.rubric_theme NOT NULL, + nb_columns INTEGER NOT NULL, + issue_id INTEGER NOT NULL, + FOREIGN KEY (issue_id) REFERENCES rr_times.issues (id) ON DELETE CASCADE, + PRIMARY KEY (id, theme, issue_id) +); diff --git a/graphs/sql/daily_gazette/req04.sql b/graphs/sql/daily_gazette/req04.sql new file mode 100644 index 0000000..a8e3eff --- /dev/null +++ b/graphs/sql/daily_gazette/req04.sql @@ -0,0 +1,11 @@ +CREATE TABLE rr_times.articles +( + id SERIAL PRIMARY KEY, + translated_article_id INTEGER NOT NULL, + rubric_id INTEGER NOT NULL, + language VARCHAR(2) NOT NULL, + country VARCHAR(2) NOT NULL, + FOREIGN KEY (language, country) REFERENCES rr_times.locales (language_code, country_code) ON DELETE CASCADE, + FOREIGN KEY (rubric_id) REFERENCES rr_times.rubrics (id) ON DELETE CASCADE, + FOREIGN KEY (translated_article_id) REFERENCES rr_times.translated_articles (id) ON DELETE CASCADE +); diff --git a/graphs/sql/daily_gazette/req05.sql b/graphs/sql/daily_gazette/req05.sql new file mode 100644 index 0000000..da15caa --- /dev/null +++ b/graphs/sql/daily_gazette/req05.sql @@ -0,0 +1,2 @@ +ALTER TABLE rr_times.translated_articles ADD UNIQUE (title); +ALTER TABLE rr_times.rubrics ADD CHECK (nb_columns >= 0); diff --git a/graphs/sql/fast_and_murderous/req01.sql b/graphs/sql/fast_and_murderous/req01.sql new file mode 100644 index 0000000..ac044ad --- /dev/null +++ b/graphs/sql/fast_and_murderous/req01.sql @@ -0,0 +1,2 @@ +SELECT person_id,case_id,content FROM justice.testimonies +WHERE content LIKE '%Nexus N%' diff --git a/graphs/sql/fast_and_murderous/req02.sql b/graphs/sql/fast_and_murderous/req02.sql new file mode 100644 index 0000000..2caffa9 --- /dev/null +++ b/graphs/sql/fast_and_murderous/req02.sql @@ -0,0 +1,2 @@ +SELECT person_id,case_id,content FROM justice.testimonies +WHERE content LIKE '%Nexus __%' diff --git a/graphs/sql/fast_and_murderous/req03.sql b/graphs/sql/fast_and_murderous/req03.sql new file mode 100644 index 0000000..4ae4836 --- /dev/null +++ b/graphs/sql/fast_and_murderous/req03.sql @@ -0,0 +1,3 @@ +SELECT T.person_id,C.id,T.content,C.description FROM justice.testimonies AS T,justice.cases AS C +WHERE T.content LIKE '%Nexus N3%' + AND C.description SIMILAR TO '%(speeding|speed|fast|reckless)%' AND T.case_id = C.id diff --git a/graphs/sql/fast_and_murderous/req04.sql b/graphs/sql/fast_and_murderous/req04.sql new file mode 100644 index 0000000..d2f6e0c --- /dev/null +++ b/graphs/sql/fast_and_murderous/req04.sql @@ -0,0 +1,2 @@ +SELECT name FROM nexus_stores.products +WHERE name ILIKE '%apple%' diff --git a/graphs/sql/fast_and_murderous/req05.sql b/graphs/sql/fast_and_murderous/req05.sql new file mode 100644 index 0000000..4dc8233 --- /dev/null +++ b/graphs/sql/fast_and_murderous/req05.sql @@ -0,0 +1,2 @@ +SELECT I.receipt_id,P.name,I.quantity,P.price FROM nexus_stores.products AS P,nexus_stores.receipt_items AS I +WHERE I.quantity > 10 AND P.name ILIKE '%apple%' AND I.product_id = P.id diff --git a/graphs/sql/fast_and_murderous/req06.sql b/graphs/sql/fast_and_murderous/req06.sql new file mode 100644 index 0000000..5f9f7af --- /dev/null +++ b/graphs/sql/fast_and_murderous/req06.sql @@ -0,0 +1,5 @@ +SELECT DISTINCT R.purchase_date,R.first_name,R.last_name,R.email,P.name,P.price,P.category FROM nexus_stores.receipts as R,nexus_stores.products AS P,nexus_stores.receipt_items AS I +WHERE R.email SIMILAR TO 's(a|e)m[a-z]{3,6}\_w[a-z]{6}[0-9]*@roger\_[a-z]+.[a-z]{3}' +AND I.receipt_id = R.id +AND I.product_id = P.id +AND P.name ILIKE '%apple%' diff --git a/graphs/sql/file_archaeology/req01.sql b/graphs/sql/file_archaeology/req01.sql new file mode 100644 index 0000000..9a9d059 --- /dev/null +++ b/graphs/sql/file_archaeology/req01.sql @@ -0,0 +1,2 @@ +SELECT MIN(size) FILTER (WHERE filename ILIKE '%secret%') AS smallest_secret_file_size, MIN(size) AS smallest_file_size +FROM dtf.madelines_files diff --git a/graphs/sql/file_archaeology/req02.sql b/graphs/sql/file_archaeology/req02.sql new file mode 100644 index 0000000..c4cf1d3 --- /dev/null +++ b/graphs/sql/file_archaeology/req02.sql @@ -0,0 +1,9 @@ +SELECT + filename, + size +FROM dtf.madelines_files +WHERE + size = (SELECT MAX(size) FROM dtf.madelines_files WHERE created_at BETWEEN '2059-12-03 23:59:59'::timestamp - interval '1 week' AND '2059-12-03 23:59:59'::timestamp) + AND created_at BETWEEN '2059-12-03 23:59:59'::timestamp + - interval '1 week' AND '2059-12-03 23:59:59'::timestamp +ORDER BY filename diff --git a/graphs/sql/file_archaeology/req03.sql b/graphs/sql/file_archaeology/req03.sql new file mode 100644 index 0000000..7e84aa1 --- /dev/null +++ b/graphs/sql/file_archaeology/req03.sql @@ -0,0 +1,7 @@ +SELECT + filename, + size +FROM dtf.madelines_files +WHERE + size >= (SELECT 0.75 * AVG(size) FROM dtf.madelines_files) +ORDER BY size DESC,filename diff --git a/graphs/sql/file_archaeology/req04.sql b/graphs/sql/file_archaeology/req04.sql new file mode 100644 index 0000000..57d86d3 --- /dev/null +++ b/graphs/sql/file_archaeology/req04.sql @@ -0,0 +1,7 @@ +SELECT + parent_id AS folder_id, + COUNT(filename) FILTER (WHERE permissions LIKE '%__x%') AS nb_executables +FROM dtf.madelines_files +GROUP BY parent_id +HAVING COUNT(filename) FILTER (WHERE permissions LIKE '%__x%') >= 3 +ORDER BY parent_id ASC NULLS FIRST diff --git a/graphs/sql/file_archaeology/req05.sql b/graphs/sql/file_archaeology/req05.sql new file mode 100644 index 0000000..a53e4de --- /dev/null +++ b/graphs/sql/file_archaeology/req05.sql @@ -0,0 +1,14 @@ +SELECT + owner, + COUNT(filename) AS num_files +FROM dtf.madelines_files +GROUP BY owner +HAVING + COUNT(filename) + = ( + SELECT MIN(test) + FROM + (SELECT COUNT(filename) AS test FROM dtf.madelines_files GROUP BY owner + ) AS n + ) +ORDER BY owner diff --git a/graphs/sql/following_you/req01.sql b/graphs/sql/following_you/req01.sql new file mode 100644 index 0000000..bbbff29 --- /dev/null +++ b/graphs/sql/following_you/req01.sql @@ -0,0 +1,9 @@ +SELECT p.id,first_name,last_name +FROM public.people AS p +WHERE EXISTS ( + SELECT * + FROM transport.metro_usage_logs, transport.metro_stations AS s + WHERE p.id = person_id + AND s.id = station_id + AND s.name = 'Morgane Abeille' +) diff --git a/graphs/sql/following_you/req02.sql b/graphs/sql/following_you/req02.sql new file mode 100644 index 0000000..0498e4e --- /dev/null +++ b/graphs/sql/following_you/req02.sql @@ -0,0 +1,7 @@ +SELECT id,street_id,created_at,person_id +FROM backup.street_logs +WHERE id NOT IN ( + SELECT id + FROM public.street_logs +) +-- INTERSECT diff --git a/graphs/sql/following_you/req03.sql b/graphs/sql/following_you/req03.sql new file mode 100644 index 0000000..a4cb4bf --- /dev/null +++ b/graphs/sql/following_you/req03.sql @@ -0,0 +1,3 @@ +SELECT * +FROM +((SELECT * FROM public.street_logs) INTERSECT (SELECT * FROM backup.street_logs)) AS res diff --git a/graphs/sql/following_you/req04.sql b/graphs/sql/following_you/req04.sql new file mode 100644 index 0000000..9cb46ed --- /dev/null +++ b/graphs/sql/following_you/req04.sql @@ -0,0 +1,25 @@ +SELECT + place_type, + entries, + place_id +FROM + ( + ( + SELECT + 'metro' AS place_type, + station_id AS place_id, + COUNT(DISTINCT person_id) AS entries + FROM transport.metro_usage_logs + GROUP BY station_id + ) + UNION + ( + SELECT + 'shop' AS place_type, + shop_id AS place_id, + COUNT(DISTINCT person_id) AS entries + FROM public.shop_entrance_logs + GROUP BY shop_id + ) + ) AS res +ORDER BY entries DESC, place_id ASC, place_type DESC diff --git a/graphs/sql/following_you/req05.sql b/graphs/sql/following_you/req05.sql new file mode 100644 index 0000000..691442b --- /dev/null +++ b/graphs/sql/following_you/req05.sql @@ -0,0 +1,51 @@ +SELECT * +FROM + ( + ( + ( + SELECT + person_id, + p.first_name AS person_first_name, + p.last_name AS person_last_name, + created_at, + 'metro' AS place, + station_id AS place_id + FROM transport.metro_usage_logs + INNER JOIN public.people AS p + ON p.id = person_id + WHERE + created_at BETWEEN timestamp '2059-12-03 17:00:00' AND timestamp '2059-12-03 21:59:59' + ) + UNION + ( + SELECT + person_id, + p.first_name AS person_first_name, + p.last_name AS person_last_name, + created_at, + 'shop' AS place, + shop_id AS place_id + FROM public.shop_entrance_logs + INNER JOIN public.people AS p + ON p.id = person_id + WHERE + created_at BETWEEN timestamp '2059-12-03 17:00:00' AND timestamp '2059-12-03 21:59:59' + ) + ) + UNION + ( + SELECT + person_id, + p.first_name AS person_first_name, + p.last_name AS person_last_name, + created_at, + 'street' AS place, + street_id AS place_id + FROM public.street_logs + INNER JOIN public.people AS p + ON p.id = person_id + WHERE + created_at BETWEEN timestamp '2059-12-03 17:00:00' AND timestamp '2059-12-03 21:59:59' + ) + ) AS res +ORDER BY created_at ASC, person_id ASC diff --git a/graphs/sql/following_you/req06.sql b/graphs/sql/following_you/req06.sql new file mode 100644 index 0000000..a8b0558 --- /dev/null +++ b/graphs/sql/following_you/req06.sql @@ -0,0 +1,15 @@ +SELECT person_id,validation,created_at +FROM( + ( + SELECT person_id,validation,created_at + FROM transport.metro_usage_logs + WHERE created_at BETWEEN timestamp '2059-12-03 12:00:00' AND timestamp '2059-12-03 13:59:59' +) +UNION +( + SELECT person_id,validation,created_at + FROM transport.metro_usage_logs + WHERE created_at BETWEEN timestamp '2059-12-03 20:00:00' AND timestamp '2059-12-03 21:59:59' + LIMIT 10 +)) AS res +ORDER BY created_at DESC, person_id ASC diff --git a/graphs/sql/gluttonous_order/req01.sql b/graphs/sql/gluttonous_order/req01.sql new file mode 100644 index 0000000..bd13ae6 --- /dev/null +++ b/graphs/sql/gluttonous_order/req01.sql @@ -0,0 +1,2 @@ +SELECT S.id FROM public.scrooge_eats_accounts AS S,public.companies AS C +WHERE C.name = 'DTF' AND S.company_id = C.id diff --git a/graphs/sql/gluttonous_order/req02.sql b/graphs/sql/gluttonous_order/req02.sql new file mode 100644 index 0000000..d695cff --- /dev/null +++ b/graphs/sql/gluttonous_order/req02.sql @@ -0,0 +1,7 @@ +INSERT INTO public.scrooge_eats_orders +SELECT 10000,ID.id,now(),0 +FROM +( + SELECT S.id FROM public.scrooge_eats_accounts AS S,public.companies AS C + WHERE C.name = 'DTF' AND S.company_id = C.id +) AS ID diff --git a/graphs/sql/gluttonous_order/req03.sql b/graphs/sql/gluttonous_order/req03.sql new file mode 100644 index 0000000..bfd5e83 --- /dev/null +++ b/graphs/sql/gluttonous_order/req03.sql @@ -0,0 +1,7 @@ +INSERT INTO public.scrooge_eats_basket_items ( order_id,item_id,quantity ) +SELECT 10000,I.id,1 +FROM +( + SELECT id FROM public.scrooge_eats_items + WHERE name = 'Kinder Bueno White' +) AS I diff --git a/graphs/sql/gluttonous_order/req04.sql b/graphs/sql/gluttonous_order/req04.sql new file mode 100644 index 0000000..0967a4a --- /dev/null +++ b/graphs/sql/gluttonous_order/req04.sql @@ -0,0 +1,7 @@ +INSERT INTO public.scrooge_eats_basket_items ( order_id,item_id,quantity ) +SELECT DISTINCT 10000,I.id,1 +FROM +( + SELECT id FROM public.scrooge_eats_items + WHERE name SIMILAR TO '(Kinder Bueno White)|(Tacos)|(Coca-Cola)' +) AS I diff --git a/graphs/sql/gluttonous_order/req05.sql b/graphs/sql/gluttonous_order/req05.sql new file mode 100644 index 0000000..e8bb1c3 --- /dev/null +++ b/graphs/sql/gluttonous_order/req05.sql @@ -0,0 +1,14 @@ +INSERT INTO public.scrooge_eats_orders +SELECT 10001,ID.id,now(),0 +FROM +( + SELECT S.id FROM public.scrooge_eats_accounts AS S,public.companies AS C + WHERE C.name = 'DTF' AND S.company_id = C.id +) AS ID; +INSERT INTO public.scrooge_eats_basket_items ( order_id,item_id,quantity ) +SELECT 10001,I.id,1 +FROM +( + SELECT id,price FROM public.scrooge_eats_items + WHERE name SIMILAR TO '(Paella)|(Cider)' +) AS I diff --git a/graphs/sql/gustos_night/req01.sql b/graphs/sql/gustos_night/req01.sql new file mode 100644 index 0000000..33c00aa --- /dev/null +++ b/graphs/sql/gustos_night/req01.sql @@ -0,0 +1,2 @@ +SELECT reservation_name,bill_total FROM gusto_reservations +WHERE bill_total < 100 diff --git a/graphs/sql/gustos_night/req02.sql b/graphs/sql/gustos_night/req02.sql new file mode 100644 index 0000000..cf05f88 --- /dev/null +++ b/graphs/sql/gustos_night/req02.sql @@ -0,0 +1,2 @@ +SELECT reservation_name,reservation_date,bill_total,table_id FROM gusto_reservations +WHERE reservation_name != 'Whitman' diff --git a/graphs/sql/gustos_night/req03.sql b/graphs/sql/gustos_night/req03.sql new file mode 100644 index 0000000..a3ae8e2 --- /dev/null +++ b/graphs/sql/gustos_night/req03.sql @@ -0,0 +1,2 @@ +SELECT name FROM gusto_menu_items +WHERE price = 12.99 OR price = 10.99 OR price > 42.44 diff --git a/graphs/sql/gustos_night/req04.sql b/graphs/sql/gustos_night/req04.sql new file mode 100644 index 0000000..91cb955 --- /dev/null +++ b/graphs/sql/gustos_night/req04.sql @@ -0,0 +1,2 @@ +SELECT id,reservation_name,reservation_date FROM gusto_reservations +WHERE reservation_date >= '2059-12-03 18:00:00' AND reservation_date < '2059-12-03 21:00:00' AND cancelled = FALSE diff --git a/graphs/sql/hello_roger_roger/req01.sql b/graphs/sql/hello_roger_roger/req01.sql new file mode 100644 index 0000000..525d95e --- /dev/null +++ b/graphs/sql/hello_roger_roger/req01.sql @@ -0,0 +1 @@ +SELECT 'Hello Roger Roger!' diff --git a/graphs/sql/hello_roger_roger/req02.sql b/graphs/sql/hello_roger_roger/req02.sql new file mode 100644 index 0000000..72f10ac --- /dev/null +++ b/graphs/sql/hello_roger_roger/req02.sql @@ -0,0 +1 @@ +SELECT * FROM tests diff --git a/graphs/sql/job_hunt/req01.sql b/graphs/sql/job_hunt/req01.sql new file mode 100644 index 0000000..c1d362d --- /dev/null +++ b/graphs/sql/job_hunt/req01.sql @@ -0,0 +1 @@ +SELECT * FROM public.jobs diff --git a/graphs/sql/job_hunt/req02.sql b/graphs/sql/job_hunt/req02.sql new file mode 100644 index 0000000..d5af78e --- /dev/null +++ b/graphs/sql/job_hunt/req02.sql @@ -0,0 +1 @@ +SELECT job_id,contract_type,start_date FROM public.job_offers diff --git a/graphs/sql/job_hunt/req03.sql b/graphs/sql/job_hunt/req03.sql new file mode 100644 index 0000000..4e8f291 --- /dev/null +++ b/graphs/sql/job_hunt/req03.sql @@ -0,0 +1 @@ +SELECT DISTINCT contract_type FROM public.job_offers diff --git a/graphs/sql/maas/correct_values.sql b/graphs/sql/maas/correct_values.sql new file mode 100644 index 0000000..3c9efbd --- /dev/null +++ b/graphs/sql/maas/correct_values.sql @@ -0,0 +1,41 @@ +INSERT INTO "memorin"."zoned_devices_logs" ( + "device_serial", + "version_id", + "zone_id", + "lat", + "long", + "temp", + "battery", + "signal_strength" +) +SELECT + -- The device should not be deactivated + ( + SELECT "serial_number" + FROM "memorin"."devices" + WHERE "deactivated_at" IS NULL + ORDER BY random() + LIMIT 1 + ), + -- The version should only exist + ( + SELECT "id" + FROM "memorin"."device_versions" + ORDER BY random() + LIMIT 1 + ), + "zone"."id" AS "zone_id", + -- Latitude and Longitude should be in the boundary box of the zone + random() * ("zone"."max_latitude" - "zone"."min_latitude") + + "zone"."min_latitude" AS "lat", + random() * ("zone"."max_longitude" - "zone"."min_longitude") + + "zone"."min_longitude" AS "long", + -- Temperature should be between 34 and 45 + floor(random() * (45 - 34 + 1) + 34) AS "temp", + -- Battery percentage should be between 0 and 100 + floor(random() * (100 + 1)) AS "battery", + -- Signal strength should be between 0 and 5 + floor(random() * (5 + 1)) AS "signal_strength" +FROM + "memorin"."geographic_zones" AS "zone" +ORDER BY random() LIMIT 1; diff --git a/graphs/sql/maas/incorrect_values.sql b/graphs/sql/maas/incorrect_values.sql new file mode 100644 index 0000000..07ec90d --- /dev/null +++ b/graphs/sql/maas/incorrect_values.sql @@ -0,0 +1,19 @@ +INSERT INTO "memorin"."zoned_devices_logs" ( + "device_serial", + "version_id", + "zone_id", + "lat", + "long", + "temp", + "battery", + "signal_strength" +) VALUES ( + 'W4JGVEMW51LE', + '0.0.0', + 39, + -12.3, + 0, + 2, + 290, + 12 +); diff --git a/graphs/sql/maas/req01.sql b/graphs/sql/maas/req01.sql new file mode 100644 index 0000000..d017c93 --- /dev/null +++ b/graphs/sql/maas/req01.sql @@ -0,0 +1,15 @@ +CREATE VIEW memorin.devices_summary AS + SELECT + total_devices, + active_devices, + total_devices - active_devices AS inactive_devices + FROM + ( + SELECT COUNT(*) AS total_devices + FROM memorin.devices + ) AS d, + ( + SELECT COUNT(*) AS active_devices + FROM memorin.devices + WHERE deactivated_at IS NULL + ) AS a; diff --git a/graphs/sql/maas/req02.sql b/graphs/sql/maas/req02.sql new file mode 100644 index 0000000..1d95021 --- /dev/null +++ b/graphs/sql/maas/req02.sql @@ -0,0 +1,22 @@ +CREATE TEMPORARY VIEW devices_metrics AS ( + SELECT + device_serial, + version_id, + logs.id AS log_id, + latitude AS lat, + longitude AS long, + temperature AS temp, + battery_percentage AS battery, + signal_strength + FROM + ( + SELECT serial_number + FROM memorin.devices + WHERE deactivated_at IS NULL + ) AS active, + memorin.device_logs AS logs + INNER JOIN memorin.device_versions AS v + ON version_id = v.id + WHERE serial_number = device_serial + ORDER BY device_serial, v.released_at DESC, log_id +); diff --git a/graphs/sql/maas/req03.sql b/graphs/sql/maas/req03.sql new file mode 100644 index 0000000..9b724cc --- /dev/null +++ b/graphs/sql/maas/req03.sql @@ -0,0 +1,47 @@ +CREATE VIEW memorin.zoned_devices_logs AS + SELECT + device_serial, + version_id, + zone_id, + latitude AS lat, + longitude AS long, + temperature AS temp, + battery_percentage AS battery, + signal_strength + FROM + memorin.device_logs AS logs + WHERE + device_serial IN ( + SELECT serial_number + FROM memorin.devices + WHERE deactivated_at IS NULL + ) + AND version_id IN ( + SELECT id + FROM memorin.device_versions + WHERE id = logs.version_id + ) + AND temperature BETWEEN 34 AND 45 + AND signal_strength BETWEEN 0 AND 5 + AND battery_percentage BETWEEN 0 AND 100 + AND longitude BETWEEN ( + SELECT min_longitude + FROM memorin.geographic_zones + WHERE id = logs.zone_id + ) + AND ( + SELECT max_longitude + FROM memorin.geographic_zones + WHERE id = logs.zone_id + ) + AND latitude BETWEEN ( + SELECT min_latitude + FROM memorin.geographic_zones + WHERE id = logs.zone_id + ) + AND ( + SELECT max_latitude + FROM memorin.geographic_zones + WHERE id = logs.zone_id + ) + WITH CHECK OPTION; diff --git a/graphs/sql/maas/req04_select.sql b/graphs/sql/maas/req04_select.sql new file mode 100644 index 0000000..8829df5 --- /dev/null +++ b/graphs/sql/maas/req04_select.sql @@ -0,0 +1,4 @@ +REFRESH MATERIALIZED VIEW memorin.outdated_devices; +SELECT * +FROM memorin.outdated_devices +ORDER BY versions_behind DESC, serial_number diff --git a/graphs/sql/maas/req04_view.sql b/graphs/sql/maas/req04_view.sql new file mode 100644 index 0000000..bd00c7d --- /dev/null +++ b/graphs/sql/maas/req04_view.sql @@ -0,0 +1,21 @@ +CREATE MATERIALIZED VIEW memorin.outdated_devices AS + SELECT + serial_number, + version_id, + released_at, + eol_timestamp, + ( + SELECT COUNT(*) AS versions_behind + FROM memorin.device_versions AS vs + WHERE vs.released_at > v.released_at + ) AS versions_behind + FROM + memorin.devices AS d, + memorin.device_versions AS v + WHERE eol_timestamp IS NOT NULL + AND v.id = version_id + AND serial_number IN ( + SELECT serial_number + FROM memorin.devices + WHERE deactivated_at IS NULL + ); diff --git a/graphs/sql/maas/req05_select.sql b/graphs/sql/maas/req05_select.sql new file mode 100644 index 0000000..2a8e816 --- /dev/null +++ b/graphs/sql/maas/req05_select.sql @@ -0,0 +1,12 @@ +SELECT + name AS zone_name, + COUNT(DISTINCT data_center_id) AS data_center_count, + COUNT(DISTINCT sh.id) AS total_servers, + SUM(core_count) AS total_cores, + SUM(ram) AS total_ram, + SUM(storage) AS total_storage +FROM memorin.server_hierarchy AS sh +INNER JOIN memorin.geographic_zones AS z +ON z.id = zone_id +GROUP BY name +ORDER BY data_center_count DESC, total_servers DESC, zone_name diff --git a/graphs/sql/maas/req05_view.sql b/graphs/sql/maas/req05_view.sql new file mode 100644 index 0000000..b6e792f --- /dev/null +++ b/graphs/sql/maas/req05_view.sql @@ -0,0 +1,22 @@ +CREATE RECURSIVE VIEW memorin.server_hierarchy (id,zone_id,core_count,ram,storage,data_center_id) AS ( + SELECT + id, + zone_id, + core_count, + ram, + storage, + id AS data_center_id + FROM memorin.servers + WHERE master_id IS NULL + UNION ALL + SELECT + servers.id, + servers.zone_id, + servers.core_count, + servers.ram, + servers.storage, + sh.data_center_id + FROM memorin.servers + INNER JOIN server_hierarchy AS sh + ON sh.id = servers.master_id +); diff --git a/graphs/sql/memory_leaks/req01.sql b/graphs/sql/memory_leaks/req01.sql new file mode 100644 index 0000000..50e15f8 --- /dev/null +++ b/graphs/sql/memory_leaks/req01.sql @@ -0,0 +1,2 @@ +CREATE INDEX subconscious_memories +ON memorin_test.memories (title) diff --git a/graphs/sql/memory_leaks/req02.sql b/graphs/sql/memory_leaks/req02.sql new file mode 100644 index 0000000..d4919c9 --- /dev/null +++ b/graphs/sql/memory_leaks/req02.sql @@ -0,0 +1,5 @@ +CREATE INDEX specific_vitals_index +ON memorin_test.vitals (heart_rate, respiratory_rate); + +CREATE INDEX vitals_in_index +ON memorin_test.memories (vitals_id, created_at) diff --git a/graphs/sql/memory_leaks/req03.sql b/graphs/sql/memory_leaks/req03.sql new file mode 100644 index 0000000..8a7fd22 --- /dev/null +++ b/graphs/sql/memory_leaks/req03.sql @@ -0,0 +1,7 @@ +CREATE INDEX meme +ON memorin_test.memories (id) +WHERE created_at +BETWEEN '2059-12-03 16:00:00' AND '2059-12-04 00:00:00'; + +CREATE UNIQUE INDEX emote +ON memorin_test.emotions (emotion_type,memory_id) diff --git a/graphs/sql/memory_leaks/req04.sql b/graphs/sql/memory_leaks/req04.sql new file mode 100644 index 0000000..c08affa --- /dev/null +++ b/graphs/sql/memory_leaks/req04.sql @@ -0,0 +1,3 @@ +CREATE INDEX memid +ON memorin_test.emotions (memory_id) +WHERE level >= 4; diff --git a/graphs/sql/memory_leaks/req05.sql b/graphs/sql/memory_leaks/req05.sql new file mode 100644 index 0000000..e0a55c7 --- /dev/null +++ b/graphs/sql/memory_leaks/req05.sql @@ -0,0 +1,2 @@ +CREATE INDEX description +ON memorin_test.memories (length(description)) diff --git a/graphs/sql/outsourcing/req01.sql b/graphs/sql/outsourcing/req01.sql new file mode 100644 index 0000000..caf3c1f --- /dev/null +++ b/graphs/sql/outsourcing/req01.sql @@ -0,0 +1,6 @@ +SELECT T.id AS trial_id,case_id,classification,description +INTO public.definitive_trials +FROM justice.trials AS T, justice.cases AS C +WHERE T.case_id = C.id +AND T.status = 'FINISHED' +ORDER BY classification, case_id diff --git a/graphs/sql/outsourcing/req02.sql b/graphs/sql/outsourcing/req02.sql new file mode 100644 index 0000000..1c2dd3d --- /dev/null +++ b/graphs/sql/outsourcing/req02.sql @@ -0,0 +1,6 @@ +SELECT person_id,first_name,last_name,birth_date,O.created_at::date AS conviction_date,serving_time,(date '2059-12-03' <= T.created_at::date - concat(serving_time, ' month')::interval) AS could_be_released +INTO public.outcome_status +FROM justice.defendants AS D, public.people AS P, justice.trials as T, justice.outcomes AS O, justice.cases AS C +WHERE D.person_id = P.id AND D.trial_id = T.id AND T.id = O.trial_id AND T.case_id = C.id +AND O.outcome = 'GUILTY' +AND C.classification = 'CRIME' diff --git a/graphs/sql/outsourcing/req03.sql b/graphs/sql/outsourcing/req03.sql new file mode 100644 index 0000000..226a7e1 --- /dev/null +++ b/graphs/sql/outsourcing/req03.sql @@ -0,0 +1,5 @@ +SELECT person_id, first_name, last_name, birth_date, classification, description +INTO TEMPORARY TABLE pg_temp.not_guilty +FROM justice.trials AS T, justice.cases AS C, justice.outcomes AS O, public.people AS P, justice.defendants AS D +WHERE T.case_id = C.id AND O.trial_id = T.id AND D.trial_id = T.id AND D.person_id = P.id +AND O.outcome = 'NOT_GUILTY' diff --git a/graphs/sql/outsourcing/req04.sql b/graphs/sql/outsourcing/req04.sql new file mode 100644 index 0000000..badca1a --- /dev/null +++ b/graphs/sql/outsourcing/req04.sql @@ -0,0 +1,47 @@ + SELECT + person_id, + first_name, + last_name, + o.created_at, + serving_time, + o.created_at::timestamp + + concat(serving_time, ' month')::interval AS release_date + INTO TEMPORARY TABLE a + FROM justice.trials AS t, justice.cases AS c, justice.defendants AS d, + public.people AS p, justice.outcomes AS o, + justice.sentence_reductions AS r + WHERE + t.case_id = c.id + AND t.id = d.trial_id + AND d.person_id = p.id + AND o.trial_id = t.id + AND r.outcome_id != o.id + AND o.outcome = 'GUILTY'; + + SELECT + person_id, + first_name, + last_name, + o.created_at, + serving_time, + o.created_at + concat(serving_time - r.amount, ' month')::interval AS release_date + INTO TEMPORARY TABLE b + FROM justice.trials AS t, justice.cases AS c, justice.defendants AS d, + public.people AS p, justice.outcomes AS o, + justice.sentence_reductions AS r + WHERE + t.case_id = c.id + AND t.id = d.trial_id + AND d.person_id = p.id + AND o.trial_id = t.id + AND r.outcome_id = o.id + AND o.outcome = 'GUILTY'; + +INSERT INTO b +SELECT DISTINCT * FROM a +WHERE NOT EXISTS (SELECT * FROM b WHERE a.person_id = b.person_id); + +SELECT DISTINCT * +INTO public.release_dates +FROM b +ORDER BY b.release_date DESC, serving_time DESC diff --git a/graphs/sql/red_flag/req01.sql b/graphs/sql/red_flag/req01.sql new file mode 100644 index 0000000..cbafe43 --- /dev/null +++ b/graphs/sql/red_flag/req01.sql @@ -0,0 +1,8 @@ +BEGIN; + + DELETE FROM public.epix_posts + WHERE id = 836; + + SELECT * FROM public.epix_posts WHERE id BETWEEN 830 AND 840 ORDER BY id; + +COMMIT; diff --git a/graphs/sql/red_flag/req02.sql b/graphs/sql/red_flag/req02.sql new file mode 100644 index 0000000..3c379db --- /dev/null +++ b/graphs/sql/red_flag/req02.sql @@ -0,0 +1,7 @@ +BEGIN; + + UPDATE public.epix_posts + SET downvotes = upvotes * ((SELECT SUM((downvotes::numeric/upvotes::numeric)::numeric)::numeric FROM public.epix_posts WHERE author_id = 1056 AND id != 139)::numeric / (SELECT COUNT(*) FROM public.epix_posts WHERE author_id = 1056 AND id != 139)::numeric) + WHERE id = 139; + +COMMIT; diff --git a/graphs/sql/red_flag/req03.sql b/graphs/sql/red_flag/req03.sql new file mode 100644 index 0000000..c13cc56 --- /dev/null +++ b/graphs/sql/red_flag/req03.sql @@ -0,0 +1,4 @@ +DELETE FROM public.epix_posts AS p +USING public.epix_hashtags AS h,public.people AS pp, public.epix_accounts AS a +WHERE h.id = p.hashtag_id AND h.name = 'EndSurveillance' AND pp.id = a.person_id AND p.author_id = a.id +RETURNING first_name,last_name,username,p.body AS post_content; diff --git a/graphs/sql/red_flag/req04.sql b/graphs/sql/red_flag/req04.sql new file mode 100644 index 0000000..35b998f --- /dev/null +++ b/graphs/sql/red_flag/req04.sql @@ -0,0 +1,5 @@ +BEGIN; + UPDATE public.epix_hashtags + SET deleted_at = localtimestamp + WHERE name = 'EndSurveillance'; + COMMIT; diff --git a/graphs/sql/safe_haven/req01.sql b/graphs/sql/safe_haven/req01.sql new file mode 100644 index 0000000..4c0d403 --- /dev/null +++ b/graphs/sql/safe_haven/req01.sql @@ -0,0 +1,11 @@ +CREATE TABLE banking_transactions_poc +( + id serial PRIMARY KEY, + sender varchar(22) NOT NULL, + receiver varchar(22) NOT NULL, + amount numeric(16, 2) NOT NULL, + CHECK (sender SIMILAR TO 'RR[0-9]{2}[A-Z]{4}[0-9]{14}'), + CHECK (receiver SIMILAR TO 'RR[0-9]{2}[A-Z]{4}[0-9]{14}'), + CHECK (sender != receiver), + CHECK (amount > 0) +); diff --git a/graphs/sql/socially_unfit/req01.sql b/graphs/sql/socially_unfit/req01.sql new file mode 100644 index 0000000..cd0c60b --- /dev/null +++ b/graphs/sql/socially_unfit/req01.sql @@ -0,0 +1,2 @@ +SELECT * FROM public.people +LIMIT 100 diff --git a/graphs/sql/socially_unfit/req02.sql b/graphs/sql/socially_unfit/req02.sql new file mode 100644 index 0000000..2178826 --- /dev/null +++ b/graphs/sql/socially_unfit/req02.sql @@ -0,0 +1,2 @@ +SELECT id,first_name,last_name FROM public.people +LIMIT 100 OFFSET 42 diff --git a/graphs/sql/socially_unfit/req03.sql b/graphs/sql/socially_unfit/req03.sql new file mode 100644 index 0000000..4f1d62d --- /dev/null +++ b/graphs/sql/socially_unfit/req03.sql @@ -0,0 +1,3 @@ +SELECT DISTINCT first_name,last_name,death_date,social_credit_balance FROM public.people +WHERE death_date IS NOT NULL +ORDER BY death_date DESC,social_credit_balance DESC LIMIT 100 diff --git a/graphs/sql/socially_unfit/req04.sql b/graphs/sql/socially_unfit/req04.sql new file mode 100644 index 0000000..a11948a --- /dev/null +++ b/graphs/sql/socially_unfit/req04.sql @@ -0,0 +1,6 @@ +SELECT first_name,last_name,birth_date,job_id,social_credit_balance +FROM public.people +WHERE job_id IS NOT NULL +AND social_credit_balance > 0 +AND death_date IS NULL +ORDER BY social_credit_balance DESC,birth_date,job_id LIMIT 100 OFFSET 200 diff --git a/graphs/sql/socially_unfit/req05.sql b/graphs/sql/socially_unfit/req05.sql new file mode 100644 index 0000000..45029d8 --- /dev/null +++ b/graphs/sql/socially_unfit/req05.sql @@ -0,0 +1,5 @@ +SELECT id,person_id,credits_change,action_description +FROM public.social_credit_history +WHERE date >= '2059-12-03 17:00' AND date <= '2059-12-03 22:00' +ORDER BY credits_change,id +LIMIT 10 diff --git a/graphs/sql/traffic_offense/req01.sql b/graphs/sql/traffic_offense/req01.sql new file mode 100644 index 0000000..3258fef --- /dev/null +++ b/graphs/sql/traffic_offense/req01.sql @@ -0,0 +1,2 @@ +SELECT * FROM public.traffic_violations +WHERE license_plate LIKE 'AZ__36_' diff --git a/graphs/sql/traffic_offense/req02.sql b/graphs/sql/traffic_offense/req02.sql new file mode 100644 index 0000000..d775b0c --- /dev/null +++ b/graphs/sql/traffic_offense/req02.sql @@ -0,0 +1,4 @@ +SELECT * FROM public.traffic_violations +WHERE license_plate LIKE 'AZ__36_' +AND violation_date >= timestamp '2059-12-03 21:00:00' - interval '1 h' +AND violation_date <= timestamp '2059-12-03 21:00:00' + interval '1 h' diff --git a/graphs/sql/traffic_offense/req03.sql b/graphs/sql/traffic_offense/req03.sql new file mode 100644 index 0000000..daebf4d --- /dev/null +++ b/graphs/sql/traffic_offense/req03.sql @@ -0,0 +1,8 @@ +SELECT * FROM public.traffic_violations +WHERE license_plate LIKE 'AZ__36_' +AND violation_date >= timestamp '2059-12-03 21:00:00' - interval '1 h' +AND violation_date <= timestamp '2059-12-03 21:00:00' + interval '1 h' +AND ( + description = 'SPEED_AND_TRAFFIC_VIOLATION' + OR description = 'RECKLESS_AND_DANGEROUS_DRIVING' +) diff --git a/graphs/sql/traffic_offense/req04.sql b/graphs/sql/traffic_offense/req04.sql new file mode 100644 index 0000000..f616e3a --- /dev/null +++ b/graphs/sql/traffic_offense/req04.sql @@ -0,0 +1,9 @@ +SELECT V2.id,V2.description,V2.violation_date,V2.street_id,V2.license_plate FROM public.traffic_violations AS V1,public.traffic_violations AS V2 +WHERE V1.license_plate LIKE 'AZ__36_' +AND V1.violation_date >= timestamp '2059-12-03 21:00:00' - interval '1 h' +AND V1.violation_date <= timestamp '2059-12-03 21:00:00' + interval '1 h' +AND ( + V1.description = 'SPEED_AND_TRAFFIC_VIOLATION' + OR V1.description = 'RECKLESS_AND_DANGEROUS_DRIVING' +) +AND V1.license_plate = V2.license_plate diff --git a/graphs/sql/traffic_offense/req05.sql b/graphs/sql/traffic_offense/req05.sql new file mode 100644 index 0000000..41aaebd --- /dev/null +++ b/graphs/sql/traffic_offense/req05.sql @@ -0,0 +1,10 @@ +SELECT V2.id,V2.description,V2.violation_date,V2.street_id,V2.license_plate FROM public.traffic_violations AS V1,public.traffic_violations AS V2 +WHERE V1.license_plate LIKE 'AZ__36_' +AND V1.violation_date >= timestamp '2059-12-03 21:00:00' - interval '1 h' +AND V1.violation_date <= timestamp '2059-12-03 21:00:00' + interval '1 h' +AND ( + V1.description = 'SPEED_AND_TRAFFIC_VIOLATION' + OR V1.description = 'RECKLESS_AND_DANGEROUS_DRIVING' +) +AND V1.license_plate = V2.license_plate +AND V2.violation_date::date = '2059-12-03 21:00:00'::date diff --git a/graphs/sql/vault_cataloging/req01.sql b/graphs/sql/vault_cataloging/req01.sql new file mode 100644 index 0000000..25394d0 --- /dev/null +++ b/graphs/sql/vault_cataloging/req01.sql @@ -0,0 +1,12 @@ +SELECT + F.id, + F.filename, + CASE + WHEN F.decrypted THEN 'File was successfully decrypted.' + WHEN P.decrypted THEN 'File was successfully decrypted because its containing folder was successfully decrypted.' + ELSE 'File remains encrypted.' + END AS decryption_status +FROM dtf.madelines_files_results AS F +LEFT JOIN dtf.madelines_files_results AS P +ON P.id = F.parent_id +ORDER BY F.id diff --git a/graphs/sql/vault_cataloging/req02.sql b/graphs/sql/vault_cataloging/req02.sql new file mode 100644 index 0000000..bdfecaa --- /dev/null +++ b/graphs/sql/vault_cataloging/req02.sql @@ -0,0 +1,14 @@ +SELECT + id, + madelines_files_results.size AS stored_size, + d.decrypted, + COALESCE(madelines_files_results.size, d.size) AS calculated_size +FROM dtf.madelines_files_results +LEFT JOIN +( + SELECT decrypted,AVG(size)::bigint AS size FROM dtf.madelines_files_results + WHERE parent_id IS NOT NULL + GROUP BY decrypted +) AS d ON madelines_files_results.decrypted = d.decrypted +WHERE parent_id IS NOT NULL +ORDER BY madelines_files_results.id diff --git a/graphs/sql/vault_cataloging/req03.sql b/graphs/sql/vault_cataloging/req03.sql new file mode 100644 index 0000000..12dd9cf --- /dev/null +++ b/graphs/sql/vault_cataloging/req03.sql @@ -0,0 +1,11 @@ +SELECT + filename, + LEAST(rsa_time,hyper_pulse_time,quantum_x_time,aes_time,d_crypt_time) AS best_time, + GREATEST(rsa_time,hyper_pulse_time,quantum_x_time,aes_time,d_crypt_time) AS worst_time +FROM dtf.madelines_files_results +ORDER BY ( + CASE + WHEN filename LIKE '.%' THEN 1 + ELSE 2 + END +),filename diff --git a/graphs/sql/vault_cataloging/req04.sql b/graphs/sql/vault_cataloging/req04.sql new file mode 100644 index 0000000..9276b1c --- /dev/null +++ b/graphs/sql/vault_cataloging/req04.sql @@ -0,0 +1,32 @@ +WITH filtered_times AS ( + SELECT + COALESCE( + NULLIF(rsa_time,0), + (SELECT MAX(rsa_time) FROM dtf.madelines_files_results) + ) AS rsa_time, + COALESCE( + NULLIF(hyper_pulse_time,0), + (SELECT MAX(hyper_pulse_time) FROM dtf.madelines_files_results) + ) AS hyper_pulse_time, + COALESCE( + NULLIF(quantum_x_time,0), + (SELECT MAX(quantum_x_time) FROM dtf.madelines_files_results) + ) AS quantum_x_time, + COALESCE( + NULLIF(aes_time,0), + (SELECT MAX(aes_time) FROM dtf.madelines_files_results) + ) AS aes_time, + COALESCE( + NULLIF(d_crypt_time,0), + (SELECT MAX(d_crypt_time) FROM dtf.madelines_files_results) + ) AS d_crypt_time + FROM dtf.madelines_files_results +) + +SELECT + AVG(rsa_time)::numeric(10,2) AS avg_rsa_time, + AVG(hyper_pulse_time)::numeric(10,2) AS avg_hyper_pulse_time, + AVG(quantum_x_time)::numeric(10,2) AS avg_quantum_x_time, + AVG(aes_time)::numeric(10,2) AS avg_aes_time, + AVG(d_crypt_time)::numeric(10,2) AS avg_d_crypt_time +FROM filtered_times diff --git a/graphs/sql/where_is_waldo/req01.sql b/graphs/sql/where_is_waldo/req01.sql new file mode 100644 index 0000000..9ab6dfb --- /dev/null +++ b/graphs/sql/where_is_waldo/req01.sql @@ -0,0 +1,8 @@ +SELECT sales.id AS sales_id,product_id,sales.checkout_id,sale_timestamp,cashier_shifts.id AS shift_id,employee_id,start_timestamp AS shift_start_timestamp,end_timestamp AS shift_end_timestamp +INTO dtf.shifts_and_sales_78 +FROM nexus_stores.sales +INNER JOIN nexus_stores.cashier_shifts ON sales.checkout_id = cashier_shifts.checkout_id +AND sales.store_id = 78 +AND start_timestamp = timestamp '2059-12-01 13:00:00' +AND sale_timestamp >= start_timestamp +AND sale_timestamp < end_timestamp diff --git a/graphs/sql/where_is_waldo/req02.sql b/graphs/sql/where_is_waldo/req02.sql new file mode 100644 index 0000000..d7064a4 --- /dev/null +++ b/graphs/sql/where_is_waldo/req02.sql @@ -0,0 +1,6 @@ +SELECT * +FROM nexus_stores.cashier_shifts AS s +FULL JOIN nexus_stores.cashier_shifts as c +ON s.id = c.id +WHERE s.employee_id IS NOT NULL +AND s.store_id IS NOT NULL diff --git a/graphs/sql/where_is_waldo/req03.sql b/graphs/sql/where_is_waldo/req03.sql new file mode 100644 index 0000000..70a712a --- /dev/null +++ b/graphs/sql/where_is_waldo/req03.sql @@ -0,0 +1,4 @@ +SELECT COUNT(s.*) AS store_id_null_count,COUNT(c.*) AS employee_id_null_count +FROM (SELECT * FROM nexus_stores.cashier_shifts WHERE store_id IS NULL) AS s +FULL JOIN (SELECT * FROM nexus_stores.cashier_shifts WHERE employee_id IS NULL) AS c +ON s.id = c.id diff --git a/graphs/sql/where_is_waldo/req04.sql b/graphs/sql/where_is_waldo/req04.sql new file mode 100644 index 0000000..3c83d6f --- /dev/null +++ b/graphs/sql/where_is_waldo/req04.sql @@ -0,0 +1,4 @@ +SELECT s.id,checkout_id,employee_id,s.store_id AS shift_store_id,c.store_id AS checkout_store_id,start_timestamp,end_timestamp +FROM nexus_stores.cashier_shifts AS s +INNER JOIN nexus_stores.checkouts AS c +ON c.id = s.checkout_id diff --git a/graphs/sql/where_is_waldo/req05.sql b/graphs/sql/where_is_waldo/req05.sql new file mode 100644 index 0000000..8a03061 --- /dev/null +++ b/graphs/sql/where_is_waldo/req05.sql @@ -0,0 +1,14 @@ +INSERT INTO nexus_stores.cashier_shifts +VALUES +( + 30000, + '68cdd3ec', + NULL, + 78, + timestamp '2059-12-01 13:00:00', + timestamp '2059-12-01 15:00:00' +); +INSERT INTO nexus_stores.sales +SELECT 325000, id AS product_id,'68cdd3ec',78,timestamp '2059-12-01 14:47:07' +FROM nexus_stores.products +WHERE name = 'Golden Apple'; diff --git a/graphs/sql/where_is_waldo/req06.sql b/graphs/sql/where_is_waldo/req06.sql new file mode 100644 index 0000000..8a7a35e --- /dev/null +++ b/graphs/sql/where_is_waldo/req06.sql @@ -0,0 +1,20 @@ +SELECT + e.id AS employee_id, + person_id, + first_name, + last_name +FROM nexus_stores.employees AS e +INNER JOIN public.people AS p + ON e.person_id = p.id +WHERE + e.id NOT IN ( + SELECT employee_id + FROM nexus_stores.cashier_shifts + INNER JOIN nexus_stores.employees + ON employee_id = employees.id AND position = 'CASHIER' + WHERE + start_timestamp = timestamp '2059-12-01 13:00:00' + AND cashier_shifts.store_id = 78 + ) + AND e.position = 'CASHIER' + AND e.store_id = 78 |
