summaryrefslogtreecommitdiff
path: root/graphs
diff options
context:
space:
mode:
authorMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:08:27 +0200
committerMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:08:27 +0200
commitc9b6b9a5ca082fe7c1b6f58d7713f785a9eb6a5c (patch)
tree3e4f42f93c7ae89a364e4d51fff6e5cec4e55fa9 /graphs
add: graphs et rushs
Diffstat (limited to 'graphs')
-rw-r--r--graphs/cpp/.clang-format80
-rw-r--r--graphs/cpp/.gitignore6
-rw-r--r--graphs/cpp/CMakeLists.txt12
-rw-r--r--graphs/cpp/address_book/address_book.cc75
-rw-r--r--graphs/cpp/address_book/address_book.hh25
-rw-r--r--graphs/cpp/address_book/contact_details.cc38
-rw-r--r--graphs/cpp/address_book/contact_details.hh15
-rw-r--r--graphs/cpp/address_book/main.cc42
-rw-r--r--graphs/cpp/antagonist/CMakeLists.txt20
-rw-r--r--graphs/cpp/antagonist/include/libbeaver/beaver.hh18
-rw-r--r--graphs/cpp/antagonist/src/CMakeLists.txt19
-rw-r--r--graphs/cpp/antagonist/src/beaver/CMakeLists.txt6
-rw-r--r--graphs/cpp/antagonist/src/beaver/beaver.cc12
-rw-r--r--graphs/cpp/antagonist/src/beaver/beaver_impl.cc24
-rw-r--r--graphs/cpp/antagonist/src/beaver/beaver_impl.hh21
-rw-r--r--graphs/cpp/antagonist/src/video_player/CMakeLists.txt6
-rw-r--r--graphs/cpp/antagonist/src/video_player/video_player.cc59
-rw-r--r--graphs/cpp/antagonist/src/video_player/video_player.hh12
-rw-r--r--graphs/cpp/antagonist/test/CMakeLists.txt10
-rw-r--r--graphs/cpp/antagonist/test/main.cc10
-rw-r--r--graphs/cpp/antagonist/test/video/video.mp4bin0 -> 533288 bytes
-rw-r--r--graphs/cpp/bimap/bimap.hh36
-rw-r--r--graphs/cpp/bimap/bimap.hxx74
-rw-r--r--graphs/cpp/bimap/bimap_example.cc26
-rw-r--r--graphs/cpp/cartesian_vector/format_numerical_data.cc13
-rw-r--r--graphs/cpp/cartesian_vector/format_numerical_data.hh22
-rw-r--r--graphs/cpp/cartesian_vector/state_saver.cc11
-rw-r--r--graphs/cpp/cartesian_vector/state_saver.hh20
-rw-r--r--graphs/cpp/cartesian_vector/vector.cc69
-rw-r--r--graphs/cpp/cartesian_vector/vector.hh29
-rw-r--r--graphs/cpp/cartesian_vector/vector_test.cc27
-rw-r--r--graphs/cpp/caste_or_cast/Makefile15
-rw-r--r--graphs/cpp/caste_or_cast/ant.cc87
-rw-r--r--graphs/cpp/caste_or_cast/ant.hh70
-rw-r--r--graphs/cpp/caste_or_cast/colony.cc116
-rw-r--r--graphs/cpp/caste_or_cast/colony.hh43
-rw-r--r--graphs/cpp/caste_or_cast/main_example.cc37
-rw-r--r--graphs/cpp/caste_or_cast/nurturer.cc98
-rw-r--r--graphs/cpp/caste_or_cast/nurturer.hh27
-rw-r--r--graphs/cpp/caste_or_cast/provider.cc47
-rw-r--r--graphs/cpp/caste_or_cast/provider.hh29
-rw-r--r--graphs/cpp/caste_or_cast/queen.cc30
-rw-r--r--graphs/cpp/caste_or_cast/queen.hh32
-rw-r--r--graphs/cpp/caste_or_cast/worker.cc28
-rw-r--r--graphs/cpp/caste_or_cast/worker.hh30
-rw-r--r--graphs/cpp/chain_of_responsibility/director.cc10
-rw-r--r--graphs/cpp/chain_of_responsibility/handler.cc19
-rw-r--r--graphs/cpp/chain_of_responsibility/president.cc10
-rw-r--r--graphs/cpp/chain_of_responsibility/vice_president.cc10
-rw-r--r--graphs/cpp/closer_to/closer_to.cc15
-rw-r--r--graphs/cpp/closer_to/closer_to.hh11
-rw-r--r--graphs/cpp/closer_to/closer_to_test.cc29
-rw-r--r--graphs/cpp/const-td/CMakeLists.txt6
-rw-r--r--graphs/cpp/const-td/main.cc25
-rw-r--r--graphs/cpp/const/CMakeLists.txt6
-rw-r--r--graphs/cpp/const/person.cc25
-rw-r--r--graphs/cpp/const/person.hh17
-rw-r--r--graphs/cpp/const/test_person.cc20
-rw-r--r--graphs/cpp/directories_infos/directory_info.cc34
-rw-r--r--graphs/cpp/directories_infos/directory_info.hh24
-rw-r--r--graphs/cpp/directories_infos/main_example.cc32
-rw-r--r--graphs/cpp/directories_infos/read_info.cc39
-rw-r--r--graphs/cpp/directories_infos/read_info.hh7
-rw-r--r--graphs/cpp/doubly_linked_list/CMakeLists.txt8
-rw-r--r--graphs/cpp/doubly_linked_list/list.cc88
-rw-r--r--graphs/cpp/doubly_linked_list/list.hh24
-rw-r--r--graphs/cpp/doubly_linked_list/main.cc36
-rw-r--r--graphs/cpp/doubly_linked_list/node.cc29
-rw-r--r--graphs/cpp/doubly_linked_list/node.hh23
-rw-r--r--graphs/cpp/exception/Makefile14
-rw-r--r--graphs/cpp/exception/game.cc23
-rw-r--r--graphs/cpp/exception/game.hh14
-rw-r--r--graphs/cpp/exception/invalid_argument.cc9
-rw-r--r--graphs/cpp/exception/invalid_argument.hh15
-rw-r--r--graphs/cpp/exception/main.cc80
-rw-r--r--graphs/cpp/exception/player.cc34
-rw-r--r--graphs/cpp/exception/player.hh26
-rw-r--r--graphs/cpp/exist_functor/example.cc24
-rw-r--r--graphs/cpp/exist_functor/exist.hh14
-rw-r--r--graphs/cpp/exist_functor/exist.hxx15
-rw-r--r--graphs/cpp/for_each/for_each.hh6
-rw-r--r--graphs/cpp/for_each/for_each.hxx9
-rw-r--r--graphs/cpp/for_each/main.cc10
-rw-r--r--graphs/cpp/forward_multiplication/forward_multiplication.cc7
-rw-r--r--graphs/cpp/forward_multiplication/forward_multiplication.hh7
-rw-r--r--graphs/cpp/forward_multiplication/forward_multiplication_test.cc21
-rw-r--r--graphs/cpp/hello_world/hello_world.cc6
-rw-r--r--graphs/cpp/hot_potato/bomb.cc28
-rw-r--r--graphs/cpp/hot_potato/bomb.hh11
-rw-r--r--graphs/cpp/hot_potato/game.cc48
-rw-r--r--graphs/cpp/hot_potato/game.hh17
-rw-r--r--graphs/cpp/hot_potato/main.cc20
-rw-r--r--graphs/cpp/hot_potato/player.cc63
-rw-r--r--graphs/cpp/hot_potato/player.hh25
-rw-r--r--graphs/cpp/implements/implements.hh47
-rw-r--r--graphs/cpp/int_container/int_container.cc83
-rw-r--r--graphs/cpp/int_container/int_container.hh45
-rw-r--r--graphs/cpp/is_prime/is_prime.hh5
-rw-r--r--graphs/cpp/is_prime/is_prime.hxx21
-rw-r--r--graphs/cpp/logger/CMakeLists.txt8
-rw-r--r--graphs/cpp/logger/logger.cc73
-rw-r--r--graphs/cpp/logger/logger.hh47
-rw-r--r--graphs/cpp/logger/main.cc13
-rw-r--r--graphs/cpp/lookup_table/fibo.cc15
-rw-r--r--graphs/cpp/lookup_table/fibo.hh12
-rw-r--r--graphs/cpp/lookup_table/lookup_table.cc14
-rw-r--r--graphs/cpp/lookup_table/lookup_table.hh14
-rw-r--r--graphs/cpp/lookup_table/lookup_table_test.cc9
-rw-r--r--graphs/cpp/merge_sort/merge_sort.cc12
-rw-r--r--graphs/cpp/merge_sort/merge_sort.hh16
-rw-r--r--graphs/cpp/my_nfts/auction.cc45
-rw-r--r--graphs/cpp/my_nfts/auction.hh34
-rw-r--r--graphs/cpp/my_nfts/main.cc37
-rw-r--r--graphs/cpp/my_nfts/nft.hh15
-rw-r--r--graphs/cpp/my_nfts/nft.hxx11
-rw-r--r--graphs/cpp/my_nfts/person.cc61
-rw-r--r--graphs/cpp/my_nfts/person.hh39
-rw-r--r--graphs/cpp/path/path.cc10
-rw-r--r--graphs/cpp/path/path.hh25
-rw-r--r--graphs/cpp/path/path_example.cc22
-rw-r--r--graphs/cpp/path/unix_path.cc25
-rw-r--r--graphs/cpp/path/unix_path.hh13
-rw-r--r--graphs/cpp/path/windows_path.cc37
-rw-r--r--graphs/cpp/path/windows_path.hh14
-rw-r--r--graphs/cpp/point/CMakeLists.txt7
-rw-r--r--graphs/cpp/point/main.cc7
-rw-r--r--graphs/cpp/point/point.cc14
-rw-r--r--graphs/cpp/point/point.hh12
-rw-r--r--graphs/cpp/ref_swap/main.cc17
-rw-r--r--graphs/cpp/ref_swap/ref_swap.cc18
-rw-r--r--graphs/cpp/ref_swap/ref_swap.hh5
-rw-r--r--graphs/cpp/replace/inputfile1
-rw-r--r--graphs/cpp/replace/replace.cc39
-rw-r--r--graphs/cpp/replace/replace.hh6
-rw-r--r--graphs/cpp/replace/test_replace.cc16
-rw-r--r--graphs/cpp/singleton/singleton.cc21
-rw-r--r--graphs/cpp/singleton/singleton.hh33
-rw-r--r--graphs/cpp/singleton/singleton.hxx9
-rw-r--r--graphs/cpp/smtptr/main.cc20
-rw-r--r--graphs/cpp/smtptr/shared_pointer.hh166
-rw-r--r--graphs/cpp/smtptr/shared_pointer.hxx144
-rw-r--r--graphs/cpp/smtptr/shared_pointer_is_a.cc47
-rw-r--r--graphs/cpp/stdin_to_file/stdin_to_file.cc20
-rw-r--r--graphs/cpp/stdin_to_file/stdin_to_file.hh6
-rw-r--r--graphs/cpp/stdin_to_file/stdin_to_file_example.cc10
-rw-r--r--graphs/cpp/visitor/compute_visitor.cc62
-rw-r--r--graphs/cpp/visitor/compute_visitor.hh26
-rw-r--r--graphs/cpp/visitor/print_visitor.cc58
-rw-r--r--graphs/cpp/visitor/print_visitor.hh25
-rw-r--r--graphs/cpp/war/assassin.cc5
-rw-r--r--graphs/cpp/war/assassin.hh8
-rw-r--r--graphs/cpp/war/knight.cc5
-rw-r--r--graphs/cpp/war/knight.hh8
-rw-r--r--graphs/cpp/war/regiment.cc38
-rw-r--r--graphs/cpp/war/regiment.hh17
-rw-r--r--graphs/cpp/war/soldier.cc24
-rw-r--r--graphs/cpp/war/soldier.hh16
-rw-r--r--graphs/java/.gitignore81
-rw-r--r--graphs/java/classics/.gitignore38
-rw-r--r--graphs/java/classics/pom.xml133
-rw-r--r--graphs/java/classics/src/main/java/fr/epita/assistants/classics/Classics.java104
-rw-r--r--graphs/java/creatureInterface/.gitignore38
-rw-r--r--graphs/java/creatureInterface/pom.xml134
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/BaseHuman.java51
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Creature.java28
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Dragon.java74
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Fish.java27
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/FlyingInterface.java12
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Human.java8
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Mage.java59
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/MagicalInterface.java56
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Mermaid.java110
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SpeakableInterface.java47
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/Spell.java48
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SpellType.java11
-rw-r--r--graphs/java/creatureInterface/src/main/java/fr/epita/assistants/creatureInterface/SwimmingInterface.java25
-rw-r--r--graphs/java/drawing/.gitignore38
-rw-r--r--graphs/java/drawing/pom.xml139
-rw-r--r--graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Circle.java27
-rw-r--r--graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Entity.java20
-rw-r--r--graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/IDrawable.java5
-rw-r--r--graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Rectangle.java31
-rw-r--r--graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Sharp.java9
-rw-r--r--graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Square.java7
-rw-r--r--graphs/java/drawing/src/main/java/fr/epita/assistants/drawing/Triangle.java33
-rw-r--r--graphs/java/embedFiles/.gitignore38
-rw-r--r--graphs/java/embedFiles/pom.xml133
-rw-r--r--graphs/java/embedFiles/src/main/java/fr/epita/assistants/embedfiles/DisplayEmbedFile.java27
-rw-r--r--graphs/java/embedFiles/src/main/resources/other-sample.txt539
-rw-r--r--graphs/java/embedFiles/src/main/resources/sample.txt1
-rw-r--r--graphs/java/fgen/.gitignore38
-rw-r--r--graphs/java/fgen/pom.xml133
-rw-r--r--graphs/java/fgen/src/main/java/fr/epita/assistants/fgen/FGen.java105
-rw-r--r--graphs/java/fgen/src/main/resources/example.txt3
-rw-r--r--graphs/java/grades/.gitignore38
-rw-r--r--graphs/java/grades/pom.xml139
-rw-r--r--graphs/java/grades/src/main/java/fr/epita/assistants/grades/EntryNotFoundException.java13
-rw-r--r--graphs/java/grades/src/main/java/fr/epita/assistants/grades/GradeHandler.java98
-rw-r--r--graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Activity.java4
-rw-r--r--graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Grade.java4
-rw-r--r--graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Student.java8
-rw-r--r--graphs/java/grades/src/main/java/fr/epita/assistants/grades/model/Subject.java8
-rw-r--r--graphs/java/helloWorld/pom.xml133
-rw-r--r--graphs/java/helloWorld/src/main/java/fr/epita/assistants/helloworld/HelloWorld.java12
-rw-r--r--graphs/java/linkedList/.gitignore38
-rw-r--r--graphs/java/linkedList/pom.xml31
-rw-r--r--graphs/java/linkedList/src/main/java/fr/epita/assistants/linkedlist/LinkedList.java99
-rw-r--r--graphs/java/linkedList/src/test/java/fr/epita/assistants/linkedlist/LinkedListTests.java38
-rw-r--r--graphs/java/loggingBasics/.gitignore38
-rw-r--r--graphs/java/loggingBasics/pom.xml146
-rw-r--r--graphs/java/loggingBasics/src/main/java/fr/epita/assistants/loggingbasics/Trombinoscope.java43
-rw-r--r--graphs/java/myKitten/.gitignore38
-rw-r--r--graphs/java/myKitten/assembly.xml20
-rw-r--r--graphs/java/myKitten/pom.xml138
-rw-r--r--graphs/java/myKitten/src/main/java/fr/epita/assistants/mykitten/MyKitten.java64
-rw-r--r--graphs/java/mySet/.gitignore38
-rw-r--r--graphs/java/mySet/pom.xml133
-rw-r--r--graphs/java/mySet/src/main/java/fr/epita/assistants/myset/GenericSet.java83
-rw-r--r--graphs/java/mySet/src/main/java/fr/epita/assistants/myset/IntegerSet.java83
-rw-r--r--graphs/java/notifyMe/.gitignore38
-rw-r--r--graphs/java/notifyMe/pom.xml133
-rw-r--r--graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/notify/INotificationSender.java10
-rw-r--r--graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/notify/ShellNotifier.java22
-rw-r--r--graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/user/IMultiNotificationSender.java26
-rw-r--r--graphs/java/notifyMe/src/main/java/fr/epita/assistants/notifyme/user/User.java41
-rw-r--r--graphs/java/nucBatlle/.gitignore38
-rw-r--r--graphs/java/nucBattle/.gitignore38
-rw-r--r--graphs/java/nucBattle/pom.xml150
-rw-r--r--graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Battle.java18
-rw-r--r--graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/BattleManager.java101
-rw-r--r--graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Nuc.java20
-rw-r--r--graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Packet.java20
-rw-r--r--graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Report.java18
-rw-r--r--graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/ReportType.java14
-rw-r--r--graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/Turn.java18
-rw-r--r--graphs/java/nucBattle/src/main/java/fr/epita/assistants/nucbattle/TurnDeserializer.java30
-rw-r--r--graphs/java/nucBattle/src/main/resources/exampleBattle1.json66
-rw-r--r--graphs/java/observer/.gitignore38
-rw-r--r--graphs/java/observer/pom.xml133
-rw-r--r--graphs/java/observer/src/main/java/fr/epita/assistants/observer/Lifeguard.java21
-rw-r--r--graphs/java/observer/src/main/java/fr/epita/assistants/observer/Observable.java55
-rw-r--r--graphs/java/observer/src/main/java/fr/epita/assistants/observer/Person.java15
-rw-r--r--graphs/java/observer/src/main/java/fr/epita/assistants/observer/Swimmer.java55
-rw-r--r--graphs/java/observer/src/main/java/fr/epita/assistants/observer/SwimmerStatus.java11
-rw-r--r--graphs/java/pizzaStreams/.gitignore38
-rw-r--r--graphs/java/pizzaStreams/pom.xml138
-rw-r--r--graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Dough.java16
-rw-r--r--graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Pizza.java47
-rw-r--r--graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/PizzaStreams.java60
-rw-r--r--graphs/java/pizzaStreams/src/main/java/fr/epita/assistants/pizzastreams/Topping.java82
-rw-r--r--graphs/java/practiceLombok/.gitignore38
-rw-r--r--graphs/java/practiceLombok/pom.xml139
-rw-r--r--graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Falcon.java10
-rw-r--r--graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Horse.java13
-rw-r--r--graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Shark.java10
-rw-r--r--graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Spider.java7
-rw-r--r--graphs/java/practiceLombok/src/main/java/fr/epita/assistants/practicelombok/Tiger.java11
-rw-r--r--graphs/java/rockPaperScissors/.gitignore38
-rw-r--r--graphs/java/rockPaperScissors/pom.xml124
-rw-r--r--graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Bot.java18
-rw-r--r--graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/HandShape.java26
-rw-r--r--graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Match.java52
-rw-r--r--graphs/java/rockPaperScissors/src/main/java/fr/epita/assistants/rockPaperScissors/Player.java23
-rw-r--r--graphs/java/scheduler/.gitignore38
-rw-r--r--graphs/java/scheduler/pom.xml146
-rw-r--r--graphs/java/scheduler/src/main/java/fr/epita/assistants/scheduler/MyTask.java48
-rw-r--r--graphs/java/scheduler/src/main/java/fr/epita/assistants/scheduler/Task.java75
-rw-r--r--graphs/java/seq/.gitignore38
-rw-r--r--graphs/java/seq/pom.xml133
-rw-r--r--graphs/java/seq/src/main/java/fr/epita/assistants/seq/ExtendedStream.java204
-rw-r--r--graphs/java/seq/src/main/java/fr/epita/assistants/seq/Seq.java413
-rw-r--r--graphs/java/seq/src/test/java/fr/epita/assistants/seq/ExtendedStreamTest.java244
-rw-r--r--graphs/java/singleton/.gitignore38
-rw-r--r--graphs/java/singleton/pom.xml141
-rw-r--r--graphs/java/singleton/src/main/java/fr/epita/assistants/logger/Logger.java62
-rw-r--r--graphs/java/singleton/src/main/java/fr/epita/assistants/singleton/SingletonEnumLogger.java49
-rw-r--r--graphs/java/singleton/src/main/java/fr/epita/assistants/singleton/StaticSingletonLogger.java54
-rw-r--r--graphs/java/streamStudent/.gitignore38
-rw-r--r--graphs/java/streamStudent/pom.xml138
-rw-r--r--graphs/java/streamStudent/src/main/java/fr/epita/assistants/streamstudent/Pair.java67
-rw-r--r--graphs/java/streamStudent/src/main/java/fr/epita/assistants/streamstudent/Streamer.java58
-rw-r--r--graphs/java/streamStudent/src/test/java/fr/epita/assistants/streamstudent/StreamStudentTest.java63
-rw-r--r--graphs/java/test1/.gitignore38
-rw-r--r--graphs/java/test1/pom.xml141
-rw-r--r--graphs/java/test1/src/main/java/fr/epita/assistants/maths/Matrix.java33
-rw-r--r--graphs/java/test1/src/test/java/fr/epita/assistants/maths/MatrixTests.java113
-rw-r--r--graphs/java/test2/pom.xml141
-rw-r--r--graphs/java/test2/src/main/java/fr/epita/assistants/server/MyServer.java42
-rw-r--r--graphs/java/test2/src/main/java/fr/epita/assistants/test2/Test2.java48
-rw-r--r--graphs/java/test2/src/test/java/fr/epita/assistants/test2/Test2Test.java105
-rw-r--r--graphs/java/threadForkJoin/.gitignore38
-rw-r--r--graphs/java/threadForkJoin/pom.xml133
-rw-r--r--graphs/java/threadForkJoin/src/main/java/fr/epita/assistants/forkjoin/MyRecursiveTask.java49
-rw-r--r--graphs/java/threadForkJoin/src/test/java/fr/epita/assistants/forkjoin/RecursiveTaskTest.java34
-rw-r--r--graphs/java/throwback/.gitignore38
-rw-r--r--graphs/java/throwback/pom.xml133
-rw-r--r--graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/IntegerException.java7
-rw-r--r--graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/LongStringException.java7
-rw-r--r--graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/NegativeIntegerException.java7
-rw-r--r--graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/Pitcher.java21
-rw-r--r--graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/PositiveIntegerException.java7
-rw-r--r--graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/ShortStringException.java7
-rw-r--r--graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/StringException.java7
-rw-r--r--graphs/java/throwback/src/main/java/fr/epita/assistants/throwback/UnknownException.java7
-rw-r--r--graphs/java/travel/.gitignore38
-rw-r--r--graphs/java/travel/pom.xml138
-rw-r--r--graphs/java/travel/src/main/java/fr/epita/assistants/travel/Country.java44
-rw-r--r--graphs/java/travel/src/main/java/fr/epita/assistants/travel/Travel.java13
-rw-r--r--graphs/java/travel/src/main/resources/travel_times.csv29
-rw-r--r--graphs/java/triad/flake.nix29
-rw-r--r--graphs/java/triad/pom.xml133
-rw-r--r--graphs/java/triad/src/main/java/fr/epita/assistants/triad/FixMyMistake.java9
-rw-r--r--graphs/java/triad/src/main/java/fr/epita/assistants/triad/UglyClass.java36
-rw-r--r--graphs/java/triad/src/main/java/fr/epita/assistants/triad/WriteGettersAndConstructorForMe.java98
-rw-r--r--graphs/java/war/.gitignore38
-rw-r--r--graphs/java/war/pom.xml133
-rw-r--r--graphs/java/war/src/main/java/fr/epita/assistants/war/Assassin.java9
-rw-r--r--graphs/java/war/src/main/java/fr/epita/assistants/war/Combatant.java12
-rw-r--r--graphs/java/war/src/main/java/fr/epita/assistants/war/Knight.java9
-rw-r--r--graphs/java/war/src/main/java/fr/epita/assistants/war/Soldier.java38
-rw-r--r--graphs/java/war/src/main/java/fr/epita/assistants/war/Vehicle.java32
-rw-r--r--graphs/js/.gitignore54
-rw-r--r--graphs/js/.prettierrc.cjs6
-rw-r--r--graphs/js/accountConstraints/account.js42
-rw-r--r--graphs/js/accountConstraints/accountError.js23
-rw-r--r--graphs/js/advancedCommunication/client.js26
-rw-r--r--graphs/js/advancedCommunication/server.js88
-rw-r--r--graphs/js/armstrongNumber/armstrongNumber.js17
-rw-r--r--graphs/js/coordinatesDisplay/coordinates.js123
-rw-r--r--graphs/js/coordinatesDisplay/index.html20
-rwxr-xr-xgraphs/js/coordinatesDisplay/resources/logo.svg63
-rw-r--r--graphs/js/coordinatesDisplay/server.js92
-rw-r--r--graphs/js/counter/counter.js12
-rw-r--r--graphs/js/counter/index.html20
-rw-r--r--graphs/js/counter/style.css31
-rw-r--r--graphs/js/deepCopyAndEquality/deepCopyAndEquality.js41
-rw-r--r--graphs/js/epiTinder/data.json118
-rw-r--r--graphs/js/epiTinder/epiTinder.js114
-rw-r--r--graphs/js/epiTinderDB/epiTinderDB.js204
-rw-r--r--graphs/js/epiTinderDB/provided.sql17
-rw-r--r--graphs/js/eslint/fibo.js31
-rw-r--r--graphs/js/foodTruck/data.js70
-rw-r--r--graphs/js/foodTruck/dirtyFoodTruck.js172
-rw-r--r--graphs/js/foodTruck/foodTruck.js124
-rw-r--r--graphs/js/foodTruck/index.html40
-rw-r--r--graphs/js/foodTruck/sleep.js11
-rw-r--r--graphs/js/foodTruck/static/failedOnload.js9
-rw-r--r--graphs/js/foodTruck/static/index.js78
-rw-r--r--graphs/js/foodTruck/static/style.css200
-rw-r--r--graphs/js/gallery/gallery.js54
-rw-r--r--graphs/js/helloWorld/helloWorld.js7
-rw-r--r--graphs/js/inspectAndFuse/inspectAndFuse.js77
-rw-r--r--graphs/js/intergalactic/destinations.js47
-rw-r--r--graphs/js/intergalactic/travelers.js40
-rw-r--r--graphs/js/jestBasic/fibo.js29
-rw-r--r--graphs/js/jestBasic/fibo.test.js37
-rw-r--r--graphs/js/logMeIn/logMeIn.js59
-rw-r--r--graphs/js/modularLogger/modularLogger.js76
-rw-r--r--graphs/js/myCompany/boss.js30
-rw-r--r--graphs/js/myCompany/company.js77
-rw-r--r--graphs/js/myCompany/employee.js21
-rw-r--r--graphs/js/notSoFast/articles.json74
-rw-r--r--graphs/js/notSoFast/notSoFast.js33
-rw-r--r--graphs/js/notSoFast/server.js147
-rw-r--r--graphs/js/oidc/complete/epita/index.html35
-rw-r--r--graphs/js/oidc/complete/epita/index.js40
-rw-r--r--graphs/js/oidc/main.html27
-rw-r--r--graphs/js/oidc/redirect.js17
-rw-r--r--graphs/js/oidc/server.js33
-rw-r--r--graphs/js/oidc/style.css116
-rw-r--r--graphs/js/replace/replace.js8
-rw-r--r--graphs/js/storageWars/index.html23
-rw-r--r--graphs/js/storageWars/storageWars.js80
-rw-r--r--graphs/js/throttleDebounce/throttleDebounce.js48
-rw-r--r--graphs/js/todoList/index.html17
-rw-r--r--graphs/js/todoList/style.css64
-rw-r--r--graphs/js/todoList/todoList.js27
-rwxr-xr-xgraphs/piscine/80cols/80cols.sh11
-rw-r--r--graphs/piscine/80cols_grep/80cols.grep1
-rwxr-xr-xgraphs/piscine/a.outbin0 -> 15816 bytes
-rw-r--r--graphs/piscine/add_int_ptr/add_int_ptr.c7
-rw-r--r--graphs/piscine/alphabet/alphabet.c13
-rwxr-xr-xgraphs/piscine/alphanum/alphanum.sh53
-rw-r--r--graphs/piscine/array_max_min/array_max_min.c23
-rw-r--r--graphs/piscine/ascii_carousel/rot_x.c26
-rwxr-xr-xgraphs/piscine/ascii_house/ascii_house.sh9
-rw-r--r--graphs/piscine/assignment_operator/assignment_operator.c37
-rw-r--r--graphs/piscine/binary_search_ptr/bsearch.c38
-rw-r--r--graphs/piscine/binary_search_ptr/bsearch.h16
-rw-r--r--graphs/piscine/binary_tree_dynamic/Makefile15
-rw-r--r--graphs/piscine/binary_tree_dynamic/binary_tree.c95
-rw-r--r--graphs/piscine/binary_tree_dynamic/binary_tree.h22
-rw-r--r--graphs/piscine/binary_tree_dynamic/binary_tree_print.c40
-rw-r--r--graphs/piscine/bit_rotation/rol.c5
-rw-r--r--graphs/piscine/bubble_sort/bubble_sort.c25
-rw-r--r--graphs/piscine/bubble_sort/bubble_sort.h8
-rw-r--r--graphs/piscine/check_alphabet/check_alphabet.c25
-rw-r--r--graphs/piscine/check_alphabet/check_alphabet.h6
-rw-r--r--graphs/piscine/clang-format/.clang-format79
-rw-r--r--graphs/piscine/clang-format/zaza.c78
-rwxr-xr-xgraphs/piscine/create_files/create_files.sh34
-rw-r--r--graphs/piscine/cut_csv/test.csv15
-rwxr-xr-xgraphs/piscine/cut_csv/with_cut.sh23
-rwxr-xr-xgraphs/piscine/cut_csv/with_sed.sh24
-rw-r--r--graphs/piscine/digit/digit.c13
-rw-r--r--graphs/piscine/display_square/display_square.c44
-rw-r--r--graphs/piscine/dlist/Makefile15
-rw-r--r--graphs/piscine/dlist/dlist-1.c78
-rw-r--r--graphs/piscine/dlist/dlist-2.c113
-rw-r--r--graphs/piscine/dlist/dlist-3.c83
-rw-r--r--graphs/piscine/dlist/dlist-4.c97
-rw-r--r--graphs/piscine/dlist/dlist.h44
-rw-r--r--graphs/piscine/element_count/element_count.c10
-rw-r--r--graphs/piscine/element_count/element_count.h8
-rw-r--r--graphs/piscine/evalexpr/Makefile23
-rw-r--r--graphs/piscine/evalexpr/src/evalexpr.c93
-rw-r--r--graphs/piscine/evalexpr/src/evalexpr.h43
-rw-r--r--graphs/piscine/evalexpr/src/evalrpn.c145
-rw-r--r--graphs/piscine/evalexpr/src/fifo.h29
-rw-r--r--graphs/piscine/evalexpr/src/fifo_access.c61
-rw-r--r--graphs/piscine/evalexpr/src/fifo_setup_destroy.c44
-rw-r--r--graphs/piscine/evalexpr/src/shunting_yard.c199
-rw-r--r--graphs/piscine/evalexpr/src/stack.c57
-rw-r--r--graphs/piscine/evalexpr/src/stack.h20
-rw-r--r--graphs/piscine/evalexpr/src/stack_struct.h10
-rwxr-xr-xgraphs/piscine/evalexpr/tests/tests.sh82
-rw-r--r--graphs/piscine/evalexpr/tests/unit_tests.c208
-rw-r--r--graphs/piscine/fact/fact.c8
-rwxr-xr-xgraphs/piscine/facto/facto.sh10
-rw-r--r--graphs/piscine/fibo/fibo.c8
-rw-r--r--graphs/piscine/fibo_iter/fibo_iter.c21
-rw-r--r--graphs/piscine/fifo/Makefile16
-rw-r--r--graphs/piscine/fifo/fifo.h28
-rw-r--r--graphs/piscine/fifo/fifo_access.c66
-rw-r--r--graphs/piscine/fifo/fifo_setup_destroy.c39
-rwxr-xr-xgraphs/piscine/find_ascii/find_ascii.sh5
-rw-r--r--graphs/piscine/freq_analysis/freq_analysis.c28
-rw-r--r--graphs/piscine/functional_programming/foldl.c11
-rw-r--r--graphs/piscine/functional_programming/foldr.c10
-rw-r--r--graphs/piscine/functional_programming/functional_programming.h10
-rw-r--r--graphs/piscine/functional_programming/map.c9
-rwxr-xr-xgraphs/piscine/generate_files/generate_files.sh32
-rw-r--r--graphs/piscine/generic_void_list/list.c36
-rw-r--r--graphs/piscine/generic_void_list/list.h31
-rwxr-xr-xgraphs/piscine/glob_easy/glob_easy.sh3
-rwxr-xr-xgraphs/piscine/glob_remove_shell/glob_remove_shell.sh7
-rw-r--r--graphs/piscine/grade/grade.c29
-rw-r--r--graphs/piscine/greatest_divisor/greatest_divisor.c15
-rw-r--r--graphs/piscine/hacker_news/input.html147
-rw-r--r--graphs/piscine/hacker_news/news.sed1
-rw-r--r--graphs/piscine/hacker_news/output.txt90
-rw-r--r--graphs/piscine/handling_complex/complex.c51
-rw-r--r--graphs/piscine/handling_complex/complex.h20
-rw-r--r--graphs/piscine/hanoi/hanoi.c31
-rw-r--r--graphs/piscine/hash_map/hash.c13
-rw-r--r--graphs/piscine/hash_map/hash_map.c177
-rw-r--r--graphs/piscine/hash_map/hash_map.h29
-rw-r--r--graphs/piscine/heap/Makefile14
-rw-r--r--graphs/piscine/heap/add.c39
-rw-r--r--graphs/piscine/heap/create.c19
-rw-r--r--graphs/piscine/heap/del.c9
-rw-r--r--graphs/piscine/heap/heap.h20
-rw-r--r--graphs/piscine/heap/pop.c49
-rw-r--r--graphs/piscine/heap/print.c27
-rw-r--r--graphs/piscine/hello_friends/hello.c13
-rw-r--r--graphs/piscine/hello_world/hello.c7
-rwxr-xr-xgraphs/piscine/hello_world_shebang/hello.sh3
-rw-r--r--graphs/piscine/hill_array/hill_array.c43
-rw-r--r--graphs/piscine/hill_array/hill_array.h8
-rw-r--r--graphs/piscine/insertion_sort/insertion_sort.c20
-rw-r--r--graphs/piscine/insertion_sort/insertion_sort.h8
-rwxr-xr-xgraphs/piscine/inside/inside.sh15
-rwxr-xr-xgraphs/piscine/inside_noif/inside_noif.sh6
-rw-r--r--graphs/piscine/int_palindrome/int_palindrome.c18
-rw-r--r--graphs/piscine/int_sqrt/int_sqrt.c20
-rw-r--r--graphs/piscine/io_count_words/count_words.c33
-rw-r--r--graphs/piscine/io_merge_files/merge_files.c31
-rw-r--r--graphs/piscine/io_replace_line/replace_line.c50
-rw-r--r--graphs/piscine/levenshtein/levenshtein.c72
-rw-r--r--graphs/piscine/levenshtein/levenshtein.h8
-rw-r--r--graphs/piscine/main.c15
-rw-r--r--graphs/piscine/my_abs/my_abs.c11
-rw-r--r--graphs/piscine/my_atoi/my_atoi.c61
-rw-r--r--graphs/piscine/my_atoi/my_atoi.h8
-rw-r--r--graphs/piscine/my_atoi_base/my_atoi_base.c86
-rw-r--r--graphs/piscine/my_atoi_base/my_atoi_base.h8
-rwxr-xr-xgraphs/piscine/my_bc/my_bc.sh7
-rw-r--r--graphs/piscine/my_c_tail/main.c10
-rw-r--r--graphs/piscine/my_c_tail/my_c_tail.c46
-rw-r--r--graphs/piscine/my_c_tail/my_c_tail.h6
-rw-r--r--graphs/piscine/my_calloc/my_calloc.c11
-rw-r--r--graphs/piscine/my_calloc/my_calloc.h8
-rwxr-xr-xgraphs/piscine/my_file/my_file.sh11
-rwxr-xr-xgraphs/piscine/my_first_variable/create.sh5
-rwxr-xr-xgraphs/piscine/my_first_variable/edit.sh9
-rwxr-xr-xgraphs/piscine/my_first_variable/use.sh3
-rw-r--r--graphs/piscine/my_itoa/my_itoa.c38
-rw-r--r--graphs/piscine/my_itoa/my_itoa.h6
-rw-r--r--graphs/piscine/my_itoa_base/my_itoa_base.c49
-rw-r--r--graphs/piscine/my_itoa_base/my_itoa_base.h6
-rw-r--r--graphs/piscine/my_memcmp/my_memcmp.c18
-rw-r--r--graphs/piscine/my_memcmp/my_memcmp.h8
-rw-r--r--graphs/piscine/my_memcpy/my_memcpy.c28
-rw-r--r--graphs/piscine/my_memcpy/my_memcpy.h8
-rw-r--r--graphs/piscine/my_memmove/my_memmove.c23
-rw-r--r--graphs/piscine/my_memmove/my_memmove.h8
-rw-r--r--graphs/piscine/my_memset/my_memset.c12
-rw-r--r--graphs/piscine/my_memset/my_memset.h6
-rw-r--r--graphs/piscine/my_pow/my_pow.c13
-rw-r--r--graphs/piscine/my_round/my_round.c6
-rw-r--r--graphs/piscine/my_strcmp/my_strcmp.c11
-rw-r--r--graphs/piscine/my_strcmp/my_strcmp.h6
-rw-r--r--graphs/piscine/my_strcpy/my_strcpy.c13
-rw-r--r--graphs/piscine/my_strlen/my_strlen.c12
-rw-r--r--graphs/piscine/my_strlen/my_strlen.h6
-rw-r--r--graphs/piscine/my_strlowcase/my_strlowcase.c13
-rw-r--r--graphs/piscine/my_strlowcase/my_strlowcase.h8
-rw-r--r--graphs/piscine/my_strspn/my_strspn.c26
-rw-r--r--graphs/piscine/my_strspn/my_strspn.h8
-rw-r--r--graphs/piscine/my_strstr/my_strstr.c34
-rw-r--r--graphs/piscine/my_strstr/my_strstr.h6
-rw-r--r--graphs/piscine/my_strtok_r/my_strtok_r.c51
-rw-r--r--graphs/piscine/my_strtok_r/my_strtok_r.h6
-rw-r--r--graphs/piscine/null_terminated_arrays/null_terminated_arrays.c50
-rw-r--r--graphs/piscine/null_terminated_arrays/null_terminated_arrays.h6
-rw-r--r--graphs/piscine/number_digits_rec/number_digits_rec.c8
-rw-r--r--graphs/piscine/palindrome/palindrome.c47
-rw-r--r--graphs/piscine/palindrome/palindrome.h6
-rw-r--r--graphs/piscine/pine/pine.c36
-rw-r--r--graphs/piscine/pointer_swap/pointer_swap.c6
-rwxr-xr-xgraphs/piscine/prototypes/prototypes.sh3
-rw-r--r--graphs/piscine/quick_sort/quick_sort.c18
-rw-r--r--graphs/piscine/quick_sort/quick_sort_example.c19
-rw-r--r--graphs/piscine/repeat/repeat.c11
-rw-r--r--graphs/piscine/right_tarball/my_tarball.tar.gzbin0 -> 340 bytes
-rw-r--r--graphs/piscine/rotx/rotx.c59
-rw-r--r--graphs/piscine/sed_trailing_whitespaces/whitespaces.sed1
-rw-r--r--graphs/piscine/selection_sort/selection_sort.c30
-rwxr-xr-xgraphs/piscine/seq/seq.sh33
-rw-r--r--graphs/piscine/sieve_eratosthenes_advanced/Makefile13
-rw-r--r--graphs/piscine/sieve_eratosthenes_advanced/sieve.c39
-rw-r--r--graphs/piscine/simple_fnmatch/simple_fnmatch.c46
-rw-r--r--graphs/piscine/simple_fnmatch/simple_fnmatch.h8
-rw-r--r--graphs/piscine/stack/stack.c30
-rw-r--r--graphs/piscine/stack/stack.h14
-rw-r--r--graphs/piscine/str_revert/str_revert.c25
-rw-r--r--graphs/piscine/str_revert/str_revert.h6
-rw-r--r--graphs/piscine/test.txt3
-rw-r--r--graphs/piscine/test_a_bit/is_set.c6
-rw-r--r--graphs/piscine/test_a_bit/is_set.h6
-rw-r--r--graphs/piscine/test_a_bit/test.c11
-rw-r--r--graphs/piscine/tinylibstream/Makefile13
-rw-r--r--graphs/piscine/tinylibstream/include/libstream.h167
-rw-r--r--graphs/piscine/tinylibstream/src/tinylibstream.c221
-rw-r--r--graphs/piscine/tinylibstream/stdin_buffering_test.c70
-rw-r--r--graphs/piscine/tinylibstream/stdout_buffering_test.c13
-rw-r--r--graphs/piscine/tinyprintf/Makefile17
-rw-r--r--graphs/piscine/tinyprintf/src/tinyprintf.c251
-rw-r--r--graphs/piscine/tinyprintf/src/tinyprintf.h15
-rw-r--r--graphs/piscine/tinyprintf/tests/tests.c213
-rw-r--r--graphs/piscine/traffic_lights/traffic_lights.c38
-rw-r--r--graphs/piscine/traffic_lights/traffic_lights.h11
-rw-r--r--graphs/piscine/user_ids/get_ids.sh3
-rwxr-xr-xgraphs/piscine/using_special_variables/print.sh9
-rw-r--r--graphs/piscine/variant/variant.c96
-rw-r--r--graphs/piscine/variant/variant.h35
-rw-r--r--graphs/piscine/vector/Makefile13
-rw-r--r--graphs/piscine/vector/vector.c152
-rw-r--r--graphs/piscine/vector/vector.h64
-rw-r--r--graphs/sql/a_new_dawn/req01.sql66
-rw-r--r--graphs/sql/a_new_dawn/req02.sql8
-rw-r--r--graphs/sql/a_new_dawn/req03.sql6
-rw-r--r--graphs/sql/a_new_dawn/req04.sql3
-rw-r--r--graphs/sql/a_new_dawn/req05.sql5
-rw-r--r--graphs/sql/a_new_dawn/req06.sql5
-rw-r--r--graphs/sql/battle_plan/req01.sql19
-rw-r--r--graphs/sql/battle_plan/req02.sql8
-rw-r--r--graphs/sql/battle_plan/req03.sql17
-rw-r--r--graphs/sql/battle_plan/req04.sql8
-rw-r--r--graphs/sql/corrupted_friends/req01.sql18
-rw-r--r--graphs/sql/corrupted_friends/req02.sql41
-rw-r--r--graphs/sql/corrupted_friends/req03.sql2
-rw-r--r--graphs/sql/daily_gazette/req01.sql14
-rw-r--r--graphs/sql/daily_gazette/req02.sql16
-rw-r--r--graphs/sql/daily_gazette/req03.sql28
-rw-r--r--graphs/sql/daily_gazette/req04.sql11
-rw-r--r--graphs/sql/daily_gazette/req05.sql2
-rw-r--r--graphs/sql/fast_and_murderous/req01.sql2
-rw-r--r--graphs/sql/fast_and_murderous/req02.sql2
-rw-r--r--graphs/sql/fast_and_murderous/req03.sql3
-rw-r--r--graphs/sql/fast_and_murderous/req04.sql2
-rw-r--r--graphs/sql/fast_and_murderous/req05.sql2
-rw-r--r--graphs/sql/fast_and_murderous/req06.sql5
-rw-r--r--graphs/sql/file_archaeology/req01.sql2
-rw-r--r--graphs/sql/file_archaeology/req02.sql9
-rw-r--r--graphs/sql/file_archaeology/req03.sql7
-rw-r--r--graphs/sql/file_archaeology/req04.sql7
-rw-r--r--graphs/sql/file_archaeology/req05.sql14
-rw-r--r--graphs/sql/following_you/req01.sql9
-rw-r--r--graphs/sql/following_you/req02.sql7
-rw-r--r--graphs/sql/following_you/req03.sql3
-rw-r--r--graphs/sql/following_you/req04.sql25
-rw-r--r--graphs/sql/following_you/req05.sql51
-rw-r--r--graphs/sql/following_you/req06.sql15
-rw-r--r--graphs/sql/gluttonous_order/req01.sql2
-rw-r--r--graphs/sql/gluttonous_order/req02.sql7
-rw-r--r--graphs/sql/gluttonous_order/req03.sql7
-rw-r--r--graphs/sql/gluttonous_order/req04.sql7
-rw-r--r--graphs/sql/gluttonous_order/req05.sql14
-rw-r--r--graphs/sql/gustos_night/req01.sql2
-rw-r--r--graphs/sql/gustos_night/req02.sql2
-rw-r--r--graphs/sql/gustos_night/req03.sql2
-rw-r--r--graphs/sql/gustos_night/req04.sql2
-rw-r--r--graphs/sql/hello_roger_roger/req01.sql1
-rw-r--r--graphs/sql/hello_roger_roger/req02.sql1
-rw-r--r--graphs/sql/job_hunt/req01.sql1
-rw-r--r--graphs/sql/job_hunt/req02.sql1
-rw-r--r--graphs/sql/job_hunt/req03.sql1
-rw-r--r--graphs/sql/maas/correct_values.sql41
-rw-r--r--graphs/sql/maas/incorrect_values.sql19
-rw-r--r--graphs/sql/maas/req01.sql15
-rw-r--r--graphs/sql/maas/req02.sql22
-rw-r--r--graphs/sql/maas/req03.sql47
-rw-r--r--graphs/sql/maas/req04_select.sql4
-rw-r--r--graphs/sql/maas/req04_view.sql21
-rw-r--r--graphs/sql/maas/req05_select.sql12
-rw-r--r--graphs/sql/maas/req05_view.sql22
-rw-r--r--graphs/sql/memory_leaks/req01.sql2
-rw-r--r--graphs/sql/memory_leaks/req02.sql5
-rw-r--r--graphs/sql/memory_leaks/req03.sql7
-rw-r--r--graphs/sql/memory_leaks/req04.sql3
-rw-r--r--graphs/sql/memory_leaks/req05.sql2
-rw-r--r--graphs/sql/outsourcing/req01.sql6
-rw-r--r--graphs/sql/outsourcing/req02.sql6
-rw-r--r--graphs/sql/outsourcing/req03.sql5
-rw-r--r--graphs/sql/outsourcing/req04.sql47
-rw-r--r--graphs/sql/red_flag/req01.sql8
-rw-r--r--graphs/sql/red_flag/req02.sql7
-rw-r--r--graphs/sql/red_flag/req03.sql4
-rw-r--r--graphs/sql/red_flag/req04.sql5
-rw-r--r--graphs/sql/safe_haven/req01.sql11
-rw-r--r--graphs/sql/socially_unfit/req01.sql2
-rw-r--r--graphs/sql/socially_unfit/req02.sql2
-rw-r--r--graphs/sql/socially_unfit/req03.sql3
-rw-r--r--graphs/sql/socially_unfit/req04.sql6
-rw-r--r--graphs/sql/socially_unfit/req05.sql5
-rw-r--r--graphs/sql/traffic_offense/req01.sql2
-rw-r--r--graphs/sql/traffic_offense/req02.sql4
-rw-r--r--graphs/sql/traffic_offense/req03.sql8
-rw-r--r--graphs/sql/traffic_offense/req04.sql9
-rw-r--r--graphs/sql/traffic_offense/req05.sql10
-rw-r--r--graphs/sql/vault_cataloging/req01.sql12
-rw-r--r--graphs/sql/vault_cataloging/req02.sql14
-rw-r--r--graphs/sql/vault_cataloging/req03.sql11
-rw-r--r--graphs/sql/vault_cataloging/req04.sql32
-rw-r--r--graphs/sql/where_is_waldo/req01.sql8
-rw-r--r--graphs/sql/where_is_waldo/req02.sql6
-rw-r--r--graphs/sql/where_is_waldo/req03.sql4
-rw-r--r--graphs/sql/where_is_waldo/req04.sql4
-rw-r--r--graphs/sql/where_is_waldo/req05.sql14
-rw-r--r--graphs/sql/where_is_waldo/req06.sql20
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
new file mode 100644
index 0000000..7b788c6
--- /dev/null
+++ b/graphs/cpp/antagonist/test/video/video.mp4
Binary files differ
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 @@
+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
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
new file mode 100755
index 0000000..33e84ed
--- /dev/null
+++ b/graphs/piscine/a.out
Binary files differ
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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28943869">1&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28926775">14&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28930157">4&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28943611">3&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28933391">119&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28938551">41&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28940507">119&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28933663">771&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28933981">161&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28943645">2&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28934624">81&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28929639">242&nbsp;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&amp;how=up&amp;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&amp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28926582">528&nbsp;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&amp;how=up&amp;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&amp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28936324">5&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28940197">78&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28943066">5&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28940258">9&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28921244">441&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28942594">3&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28940705">2&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28903383">268&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28937484">52&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28921083">179&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28934715">400&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28939407">73&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28940334">2&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28929840">86&nbsp;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&amp;how=up&amp;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&amp;goto=news%3Fp%3D2">hide</a> | <a href="https://news.ycombinator.com/item?id=28934833">27&nbsp;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
new file mode 100644
index 0000000..eb6acfc
--- /dev/null
+++ b/graphs/piscine/right_tarball/my_tarball.tar.gz
Binary files differ
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