Compare commits

...

1219 Commits

Author SHA1 Message Date
Michele Sessa 1bc3b5d6dd docs(middle-day): update deprecated method 1 year ago
davhojt 5832f09413
fix(own_and_return): convert rust exercise to snake case 1 year ago
davhojt dbaa66fe41
fix(check_user_name): convert rust exercise to snake case 1 year ago
davhojt 45918794ea
docs: replace betting review process 1 year ago
lee 629c2369ea fix(public/subjects): change css sentence all dom subjects 1 year ago
lee 97d7414484 refactor(public): format DOM exercises for better user experience 1 year ago
eslopfer b75b93b83d docs(dir-info): fix typo 1 year ago
eslopfer 9b7c1f3e2b docs(dir-info): add description for exercise 1 year ago
eslopfer cb024df579 chore(dir-info): make comment accurate 1 year ago
eslopfer 23beb48880 feat(dir-info): add solution for exercise 1 year ago
eslopfer f7491d2e00 test(dir-info): add tests for exercise 1 year ago
Harry Vasanth 5a98fe519e fix(configure): add runner v2 support 1 year ago
Zouhair AMAZZAL a8e4b56e84 docs(deep-in-system) add pictures to the repo 1 year ago
eslopfer a2572a5d27 chore(largest): add line at eof 1 year ago
eslopfer 4608e50e83 chore(largest-dir): delete folder 1 year ago
eslopfer 8f7ba8f6cd test(largest): create the folders and remove them when running the test 1 year ago
eslopfer 36234cdbbe docs(largest): add periods 1 year ago
nprimo 06dc3ff388 feat(largest): add new bash exercise 1 year ago
eslopfer 27b4d9995e docs(make-your-game): add missing question 1 year ago
Michele Sessa 7de1b3a977 style(candidates_checker): improve second example style and prittify 1 year ago
Michele Sessa 21553c4a25 docs(candidates_checker): add requirement to check number of arguments 1 year ago
Michele Sessa 66c7258e6b feat(candidates_checker): add new py exercise to scripting piscine 1 year ago
nprimo c92b34b7e9 feat(skip_secrets): add subject 1 year ago
miguel 36f079db98 docs(grades): fix test and error message 1 year ago
miguel 1f9b277887 fix(grades): fix and add more tests 1 year ago
miguel 8182d373d2 fix(grades):change the test to be more flexible 1 year ago
miguel bc64c2cf03 fixing readme solution and test 1 year ago
miguel a1b76b0f0b feat(grades): add subject, test and solution for the exercise 1 year ago
Whovillage 89305e4358 Update README.md 1 year ago
eslopfer b3beafe586 docs(string_tokenizer_count): highlight file 1 year ago
eslopfer 61901120ad docs(string_tokenizer_count): add example of how to sort dict 1 year ago
eslopfer 675b689c38 docs(string_tokenizer_count): highlight filenames 1 year ago
eslopfer 8f93971d9b docs(string_tokenizer_count): fix inaccurate usage section 1 year ago
eslopfer 3eeb99dc38 docs(string_tokenizer_count): add description for exercise 1 year ago
nprimo 3152d76b75 docs(object_to_json): fix small grammar/format issues 1 year ago
nprimo 13cd960199 docs(object_to_json): improve subject 1 year ago
nprimo 75ace2da2f docs(object_to_json): make subject coherent with solution 1 year ago
nprimo 338ad35a46 feat(object_to_json): add new exercise 1 year ago
eslopfer 9c82f65d21 docs(keras2): add missing exercise to the description 1 year ago
miguel 212c7a749f docs(read_file): change file to file name 1 year ago
miguel 1dbc49abbb docs(read_file): fixing the readme 1 year ago
miguel 9c0f53dbeb feat(read_file): add subject for the new exercise 1 year ago
miguel f9f8f1810b docs(write_file): fixing the readme 1 year ago
miguel 07e3a84b7c docs(write_file): fix the hashes 1 year ago
miguel 76b3de083d feat(write_file): add subject for the new exercise 1 year ago
eslopfer 314138a026 docs(flexible_function): improve usage example 1 year ago
eslopfer 8e6cb6a558 docs(flexible_function): rename title 1 year ago
eslopfer c6e6d78b66 docs(flexible_function): add description for exercise 1 year ago
eslopfer dad3fd234a docs(credentials_searches): replace single quotes for backticks 1 year ago
eslopfer 3e7cd64c92 docs(isinstance): add hint to use isinstance 1 year ago
eslopfer 78f854bc92 docs(credentials_searches): put file name between quotes 1 year ago
eslopfer b1973d138e docs(credentials_searches): add description of exercise 1 year ago
eslopfer b5266d8c8c docs(clean_the_list): capitalize string 1 year ago
eslopfer 0809920ba6 docs(clean_the_list): use current name of the file in usage example 1 year ago
eslopfer f845339383 docs(clean_the_list): rename file to submit 1 year ago
eslopfer 12f7343ad8 docs(clean_the_list): specify what to return 1 year ago
eslopfer 97b32f5721 docs(clean_the_list): add context to usage 1 year ago
eslopfer 4f3ea55b33 docs(clean_the_list): add method to the names 1 year ago
eslopfer 21003c08d9 docs(clean_the_list): highlight function name 1 year ago
eslopfer 8d3597565b docs(clean_the_list): add line after each bullet point 1 year ago
eslopfer b338d80e6f docs(clean_the_list): make description more formal 1 year ago
eslopfer e5fba187a8 docs(clean_the_list): modify h2 1 year ago
eslopfer f3ed3aa389 docs(clean_the_list): make the output acccurate 1 year ago
eslopfer 7e21117858 chore(clean_the_list): move to right repository 1 year ago
eslopfer a7487162b8 chore(shopping): move to right repository 1 year ago
eslopfer da556a6082 test(clean_the_list): fix wrong test 1 year ago
eslopfer 59941b69bb fix(clean_the_list): remove file submitted by mistake 1 year ago
eslopfer da345c7f5a docs(clean_the_list): add subject description 1 year ago
eslopfer ed8474e3cc test(clean_the_list): fix wrong test output 1 year ago
eslopfer 349398405a test(clen_the_list): add tests for exercise 1 year ago
eslopfer d8e84c349e feat(clean_the_list): add solution for exercise 1 year ago
eslopfer e083c4db52 docs(concat-string): fix typo 1 year ago
eslopfer b0e3471c2f docs(concat_string): add missing line for consistency 1 year ago
eslopfer 2459ecb941 docs(concat_string): rephrase usage and description 1 year ago
eslopfer 47b1f92881 docs(concat_string): specify right output 1 year ago
eslopfer 21f63d3e4d docs(concat_string): add lines to usage example 1 year ago
eslopfer 818bb420c2 chore(concat_string): make folder snake case 1 year ago
eslopfer 1e0f29a661 chore(concat_string_test): move to right repository 1 year ago
eslopfer dd81c5c8a6 chore(concat_string): move to right repository 1 year ago
eslopfer 165515d247 test(concat_string): add tests for exercise 1 year ago
eslopfer 8460a1140c feat(concat_string): add solution for exercise 1 year ago
eslopfer 6f6e70ccb2 docs(concat_string): add subject description 1 year ago
Remington Smith d88afa7ddc Update README.md 1 year ago
Michele Sessa 937c38f0bd docs(merge_two): add extra line at EOF and more details about the type of values 1 year ago
Michele Sessa 7e5a55eb5e docs(merge_two): add the exit condition for inputs 1 year ago
Michele Sessa ada74ada7b docs(merge_two): use stdin to generate the second dictionary 1 year ago
Michele Sessa 891d18251f feat(merge_two): add json manipulation to the subject 1 year ago
Michele Sessa cdcac95cc6 docs(merge_two): fix typo in subject 1 year ago
Michele Sessa 0deb60289f feat(merge_two): add new py exercise to scripting piscine 1 year ago
miguel 663fea6e38 docs(days-and-numbers): fixing the readme 1 year ago
miguel d8e0daac01 docs: change notion to references 1 year ago
miguel 75e0a216a6 feat(days-and-numbers): add subject for the new exercise 1 year ago
eslopfer 91a37b1a2d test(sunny-sunday): rename test 1 year ago
eslopfer 27cb454673 refactor(sunny-sunday): rename directory 1 year ago
eslopfer 571173983c docs(bloody-sunday): replace bloody for sunny 1 year ago
eslopfer 119f624f44 refactor(bloody-sunday): replace bloody for sunny 1 year ago
eslopfer af780cabea
DEV-4309 race bring issue from public (#1748) 1 year ago
davhojt 41fc91e649 docs(local-node): clarify empty file sumission 1 year ago
davhojt d441a78d1a docs(lineup): fix path, to match reference object 1 year ago
xalava a4c3f8db8a adapted subjects to recent test changes 1 year ago
nprimo 2a9823cfee docs(shopping): update subject 1 year ago
nprimo 32660b2aa0 feat(shopping): add new exercise 1 year ago
miguel 07b35e898d docs(string_tokenizer) typos 1 year ago
miguel 4c09ccd4b7 feat(string_tokenizer): add subject for the new exercise 1 year ago
davhojt a08e196886
fix(race_test.js): ensure Promise.race is available for test.mjs 1 year ago
Michele Sessa 84c56a4741 docs(numerical_operations_the_return): change example command from python to python3 1 year ago
Michele Sessa f8201da931 chore(numerical_operations_the_return): add subject for new py exercise in scripting piscine 1 year ago
Michele Sessa 0ff5b55ec5 feat(numerical-operations-the-return): add new python exercise to scripting piscine 1 year ago
Michele Sessa c4ea506acf docs(numerical_operations): change position of optional section 1 year ago
miguel 169a5dfb35 fix(dockerfile): add apt-utils so that the actions pass in public 1 year ago
Michele Sessa a720947c82 chore(numerical_operations): add subject for new py exercise in scripting piscine 1 year ago
Michele Sessa 77a5a1821e docs(punishment): improve references section 1 year ago
Michele Sessa 4c05e7d7fb chore(punishment): move tests and solutions to another repo 1 year ago
Michele Sessa 41dccb6469 docs(punishment): apply linter to subject 1 year ago
Michele Sessa d0f04efdaf feat(punishment): add new python exercise to scripting piscine 1 year ago
Michele Sessa 1984891870 feat(hello_python): add new exercise subject for scripting piscine 1 year ago
Michele Sessa 01eaea466d feat(hello_python): add new py exercise to scripting piscine 1 year ago
eslopfer 38f9bcb87f docs(invert): clarify what to return 1 year ago
Zouhair AMAZZAL b49b41fc18 DEV-4293 add SHA1 check 1 year ago
Zouhair AMAZZAL 0e1ce974df DEV-4293 fix audit docs format 1 year ago
Zouhair AMAZZAL c4a415e456 DEV-4293 fix subject docs format 1 year ago
miguel 35aa7fea5e docs(scripting-piscine): fix naming of the hello-devops exercise 1 year ago
miguel ac848c2249 docs(devops): add info to readmes in the scripting piscine 1 year ago
davhojt 149278fa1d style(deep-in-system): prettify 1 year ago
Zouhair AMAZZAL 83d72ea9e8 docs(deep-in-system) fix the subject header 1 year ago
Zouhair AMAZZAL 5557be9f3d docs(deep-in-system) fix the subject 1 year ago
Zouhair AMAZZAL 8f261d03fd DEV-4191 docs(deep-in-system) fix audit headers 1 year ago
Zouhair AMAZZAL 4df23a5b8d DEV-4191 docs(deep-in-system) add audit 1 year ago
Zouhair AMAZZAL 1225dc0d6a DEV-4191 docs(deep-in-system) change subject name to kebabcase 1 year ago
Zouhair AMAZZAL 875f2aa59e DEV-4191 add(DeepInSystem) add new subject for devops project DeepInSystem 1 year ago
miguel 2235a8b1d0 docs(in-the-dark):remove echo from the test 1 year ago
miguel 8ce0dfcac1 fix(devops): fix folder in the hard-perm exercise 1 year ago
eslopfer b1db3597f9 docs(visualizations): replace incorrect audit questions with the right ones 1 year ago
miguel 7db7b01db8 docs(append-output): moving files to the resources folder 1 year ago
miguel de6caf07f3 fix(append-output): fix test and solution in order to create the file results.txt with some text inside already 1 year ago
miguel 748344f23d fix(append-output): fixing test readme and solution 1 year ago
miguel 0456bc5b5d feat(append-output): add subject, test and solution for the exercise 1 year ago
miguel 992e531434 docs(details): fix the readme 1 year ago
miguel e298d48ed9 feat(details): add subject, test and solution for the exercise 1 year ago
Toussaint Louis a997271b03 Update README.md 1 year ago
eslopfer a1a27fe0f5 test(file-cheker): create test folder and delete it from test file 1 year ago
eslopfer 22068682cb test(file-cheker): remove test files 1 year ago
eslopfer 35cbdf6c85 docs(file-checker): be specific about what behaviour need to be tested 1 year ago
eslopfer ef79658c09 test(file-cheker): set permissions when running the tests 1 year ago
eslopfer 43d7bb21a9 docs(file-checker): add ls command to usage example 1 year ago
eslopfer 666cc027fc test(file-checker): recreated files with right permissions again 1 year ago
eslopfer a2e42772e5 test(file-checker): remove files to create them from scratch 1 year ago
eslopfer 168fa94c2b test(file-checker): refactor test for robustness 1 year ago
eslopfer 8904b74cd3 test(file-checker): fix permissions in test files 1 year ago
eslopfer c63702c971 test(file-checker): add files to test 1 year ago
eslopfer 0af1b9f161 test(file-checker): fix wrong file to test and wrong variables 1 year ago
eslopfer ed41ff6929 fix(file-checker): change permission to make the file executable 1 year ago
eslopfer 8ec5b5023c fix(file-checker): change permission to make it executable 1 year ago
eslopfer 1fe8893aaf test(file-checker): add test for exercise 1 year ago
eslopfer 5558a83c62 feat(file-checker): add solution for exercise 1 year ago
eslopfer c8511651ff docs(file-checker): add description of subject 1 year ago
miguel a72333ab76 fix(devops): fixing typos and changing perms in the exercise hard-perm 1 year ago
Michele dc8002d92e
DEV-3951-calculator (#1706) 1 year ago
miguel 01857cd9cc fix(Dockerfile): adding the tree command to fix a bug with the scripting tests 1 year ago
sagarishere b7ad774a68 new line in the beginning of output removed 1 year ago
eslopfer f88cee4371 docs(numpy): replace expected solution in audit 1 year ago
Michele Sessa 1d5db2e77c test(joker-num): remove unused variable in tester 1 year ago
Michele Sessa d657d1461a docs(joker-num): add a hint for empty string check 1 year ago
Michele Sessa d39254e5d4 test(joker-num): add bash unofficial strict mode 1 year ago
Michele Sessa 3f21c5d32e feat(joker-num): add new exercise to scripting piscine 1 year ago
eslopfer 9025836ce8 test(joker-num): add provisional tests 1 year ago
eslopfer b6e041ea3f docs(joker-num): add description of subject 1 year ago
eslopfer 1cdf6cb27c fix(joker-num): remove unnecessary flag 1 year ago
eslopfer ed02670e16 feat(joker-num): add solution to exercise 1 year ago
Falusvampen 87abec3e1d Changed note to > as requested 1 year ago
Falusvampen 01297625c4 Fix small mistake 1 year ago
Toussaint Louis 4cd69e4cb9 Update README.md 1 year ago
miguel 107d7ac4ad fix(in-back-ground): add check for the nohup command 1 year ago
miguel 9d0f9d4506 fix(): fixing the test 1 year ago
miguel da685d8b85 fix(in-back-ground): fixing the test ang improving subject 1 year ago
miguel a97ca4ed40 fix(in-back-ground): remove echos 1 year ago
miguel ab2fea635f fix(in-back-ground):fixing test and adding info to the readme 1 year ago
miguel f66634c212 feat(in-back-ground): add subject, test and solution for the exercise 1 year ago
nprimo 9bdb8f1217 feat(remake): clarify exercise 1 year ago
nprimo 48993bb471 docs(remake): improve subject 1 year ago
nprimo f1a7dd0d2b feat(remake): add subject, tests and solution 1 year ago
miguel 6536303937 docs(left): remove unnecessaary file and adding backticks on the readme 1 year ago
miguel 5f517ea08f fix(left): fixing test 1 year ago
miguel 8995643d53 feat(left): add subject, test and solution for the exercise 1 year ago
miguel 594a8329d6 docs(burial): adding improvement to readme 1 year ago
miguel 6ce50f2bde feat(burial): add subject, test and solution for the exercise 1 year ago
miguel 74c7460405 fix(hard-conditions): creating the files in the test and removing unnecessary folder 1 year ago
miguel 9eb5d849d5 fix(hard-conditions): adding test case for nos executable 1 year ago
miguel 737ec808b1 feat(hard-conditions): add subject, test and solution for the exercise 1 year ago
Michele Sessa ed054578b9 docs(input-redirection): fix naming inconsistencies 1 year ago
Michele Sessa f3739b2357 docs(input-redirection): apply prettier to subject 1 year ago
Michele Sessa 0549bcf421 feat(input-redirection): add new exercise to scripting piscine 1 year ago
miguel 5ffb2348f5 fix(right) fixing the test, readme and solution 1 year ago
miguel 21a6aace01 docs(right): typo 1 year ago
miguel 5245101b91 feat(right): add subject, test and solution for the exercise 1 year ago
miguel 15a88f5137 feat(in-the-dark): add subject, test and solution for the exercise 1 year ago
miguel 5f8365c19c fix(easy-conditions): Fixing exercise due to misunderstanding of the objective 1 year ago
miguel 9becc5396a feat(easy-conditions): add subject, test and solution for the exercise 1 year ago
nprimo 001dc38237 docs(ispowerof2): improve subject 1 year ago
nprimo ac9cf757a1 docs(ispowerof2): make subject clearer 1 year ago
Zouhair AMAZZAL 2b77c87031
DEV-3919-my-ls (#1660) 1 year ago
nprimo ce6ef6d186 refactor(array-selector): refactor test 1 year ago
nprimo c231898bca fix(array-selector): remove exit command from solution 1 year ago
nprimo c9f0245673 fix(array-selector): add execute mode to test script 1 year ago
nprimo 3d6b963da9 docs(array-selector): improve subject clarity 1 year ago
nprimo 7e4375aa1e feat(array-selector): add subject 1 year ago
nprimo 595c044136 feat(array-selector): add test 1 year ago
nprimo 9038c5b3dd feat(array-selector): add solution 1 year ago
miguel 04e90aa8be fix(comparator):fixing the test 1 year ago
miguel fb239fd7d2 fix(comparator):fixing test and adding info to the readme 1 year ago
miguel d07a43ebe8 feat(comparator): add subject, test and solution for the exercise 1 year ago
miguel eb6e281da0 feat(file-details): add subject, test and solution for the exercise 1 year ago
nprimo ad0ea7ea91 fix(auto-exec-bin): fix test bug 1 year ago
Zouhair AMAZZAL 60deacdbb2 DEV-3918 test(auto-exec-bin) fix the test, uncorrect condition to check if bin already exists 1 year ago
Zouhair AMAZZAL d1295b02a8 DEV-3918 feat(auto-exec-bin) add new subject and tests for auto-exec-bin exercise 1 year ago
Michele Sessa 3d0e7cb960 test(bin-status): fix tests always returning success 1 year ago
Zouhair AMAZZAL f6f7831722 DEV-3916 docs(bin-status) add the requested changes for the PR:1650 1 year ago
Zouhair AMAZZAL 95509fae9a DEV-3916 feat(bin-status) add subject and tests for bin-status exercise 1 year ago
miguel ab5b82d1bd docs(greatest-of-all): correct typos 1 year ago
miguel 447de57f08 fix(): correcting typos in readme 1 year ago
miguel 962b6217b4 feat(greatest-of-all): add subject, test and solution for the exercise 1 year ago
Harry f3538e2633
feat(docker-image): bump docker\login-action to v2.1.0 1 year ago
Michele Sessa 5a2cd55a02 docs(check-user): add more hints and details about getent 1 year ago
Michele Sessa ebc79e5a13 chore(check-user): make the solution executable 1 year ago
Michele Sessa fd80d337d2 style(check-user): apply autoformat to tests 1 year ago
Michele Sessa b7197ba49c feat(check-user): add new exercise for scripting piscine 1 year ago
davhojt c1c5edba98
docs(cl-camp1): explictly state that results are without spaces 1 year ago
davhojt d3f8c485a1
docs(introduction): fix typo 1 year ago
eslopfer 8bf61c6a45 refactor(division): modify solution to avoid having to exit 1 year ago
eslopfer 596e6bc683 fix(division): refactor to exit with 0 1 year ago
eslopfer 82751669c2 test(division: add check for test command) 1 year ago
eslopfer cf304b85d4 fix(division): remove wrong file pushed 1 year ago
eslopfer 08c8ce153b test(division): add condition to work with one argument 1 year ago
eslopfer 981ebfd3d4 test(division): add test case 1 year ago
eslopfer 97a9250dd5 docs(division): specify what to do when there is a remainder 1 year ago
eslopfer 46ab89401a fix(division): output numbers in the short version 1 year ago
eslopfer 820ae81915 fix(division): make file executable 1 year ago
eslopfer 238aee7edc fix(division): make file executable 1 year ago
eslopfer d50afde56a test(division): fix tests 1 year ago
eslopfer 4575754057 test(division): add tests for exercise 1 year ago
eslopfer 52e77c4e57 feat(division): add solution for exercise 1 year ago
eslopfer 1d93072feb docs(divide): add description of subject 1 year ago
davhojt 2d57018134
docs(intro): fix caps of Hello, world! 1 year ago
Harry af8a7c5bc5
fix(bug_report): update details 1 year ago
Harry a1fed73e76
fix(feature_request): update details 1 year ago
Harry 91fb38d886
fix(feature_request): update details 1 year ago
Harry d41fea9c13
Update bug_report.md 1 year ago
Harry cc94a1807a
fix(feature_request): add details 1 year ago
Harry 9af7ad3e5a
fix(bug_report): add details 1 year ago
Harry 75ce933bb7
fix(feature_request): content 1 year ago
Harry de7bd6fef3
fix(bug_report): content 1 year ago
eslopfer 19abec613b fix(plus): change permissions of file 1 year ago
eslopfer 37a411afa9 fix(plus_test): change permissions of file 1 year ago
eslopfer b236264e84 docs(plus): remove cat -e 1 year ago
eslopfer 4ba8a4bb8a docs(plus): give exact name of file 1 year ago
eslopfer b0168a28a7 docs(plus): replace notions with references 1 year ago
eslopfer f848501332 fix(plus): wrong shebang 1 year ago
eslopfer 28572ca566 docs(plus): remove new line from output to terminal 1 year ago
eslopfer 18b2cfabf6 fix(plus): move to right folder 1 year ago
eslopfer 285680e9a7 docs(plus): remove end of line from terminal output 1 year ago
eslopfer 8316ebd171 test(plus): add tests 1 year ago
eslopfer cf4815901f feat(plus): add solution 1 year ago
eslopfer 7b771e1742 docs(plus): add description of subject 1 year ago
eslopfer 02755bed78 docs(groupie-tracker-search-bar): make audit question accurate 1 year ago
eslopfer 00129a7a3c docs(friend-support): update link to resource 1 year ago
eslopfer 5660faa45f docs(gatecrashers): update link to resource 1 year ago
eslopfer f85c056f72 docs(uninvited): update link to resource 1 year ago
eslopfer ccd46489a6 docs(tell-me-how-many): update link to resource 1 year ago
eslopfer eb20cf5956 chore(guests): cleanup, move resource to its own folder 1 year ago
eslopfer 52bc2d7040 docs(uninvited): update link to guests folder 1 year ago
eslopfer 46067ab226 docs(tell-me-how-many): update link to guests folder 1 year ago
eslopfer f74f6fbe3b docs(gatecrashers): update link to guests folder 1 year ago
eslopfer a6183a6820 docs(friend-support): update link to guests folder 1 year ago
eslopfer c46a20e583 chore:(guests): move folder to public 1 year ago
nprimo 21ff0467e4 docs(veterinary): improve subject 1 year ago
nprimo 8d76f63f5c feat(veterinary): add tests 1 year ago
nprimo 7e594e9177 docs(veterinary): add subject 1 year ago
davhojt 4328e8f3dc chore(mobile-dev): move resources closer to each project 1 year ago
davhojt 88283b4c47 chore(mobile-branch): add resources from foreign repo 1 year ago
davhojt 9f8e0a66dc style: prettier 1 year ago
davhojt b672ee8715 docs(twenty-forty-eight): add new subject and audit 1 year ago
davhojt 1a3f95ea2b docs(map-markers): rename from 01-map 1 year ago
Zouhair AMAZZAL 5c1077c6ce DEV-3920 docs(auto-jobs) fix grammer in readme file 1 year ago
Zouhair AMAZZAL 75d318f5d9 DEV-3920 fix(auto-jobs) fix solution for task3 1 year ago
Zouhair AMAZZAL 944e43772c DEV-3920 feat(auto-jobs) add subject and tests for auto-jobs exercise 1 year ago
eslopfer 2cc7a8a432
Dev 3747 new exercise about handling different http request methods (#1624) 1 year ago
eslopfer 73af4b4d43 docs(natural-language-processing-with-spacy): remove repetition 1 year ago
eslopfer f8fae31cf0 docs(ai-audits): fix format errors, rephrase, and typos 1 year ago
eslopfer d06c09c080 docs(classification-with-scikit-learn): fix audits format 1 year ago
eslopfer 47baef625c docs(visualizations): remove space 1 year ago
eslopfer af6a512da9 docs(visualizations): fix audits format 1 year ago
eslopfer 6469482d44 docs(train-evaluate-machine-learning-models): fix audits format 1 year ago
eslopfer 1574f97c6b docs(time-series-with-pandas): fix audits format 1 year ago
eslopfer e530bcf634 docs(sp500-strategies): fix audits format 1 year ago
eslopfer 2d937d14cb docs(pandas): fix audits format 1 year ago
eslopfer 4aaa6ccedb docs(numpy): fix audits format 1 year ago
eslopfer c4b718443d docs(nlp-scraper): fix audits format 1 year ago
eslopfer a301f988dd docs(neural-networks): make example more neutral 1 year ago
eslopfer 25707e9e94 docs(natural-language-processing-with-spacy): fix audits format 1 year ago
eslopfer 40c8c11ed4 docs(natural-language-processing): fix audits format 1 year ago
eslopfer 820e926b2c docs(model-selection-methodology): fix audits format 1 year ago
eslopfer bfd02c9484 docs(machine-learning-pipeline): prettier 1 year ago
eslopfer 6e6b8bba86 docs(machine-learning-pipeline): fix audits format 1 year ago
eslopfer d5359345f3 docs(linear-regression-with-scikit-learn): fix audits format 1 year ago
eslopfer dcca22eeaa docs(linear-regression-with-scikit-learn): fix audits format 1 year ago
eslopfer 92307d767c docs(keras-2): fix audits format 1 year ago
eslopfer 421baa3c50 docs(keras): fix audits format 1 year ago
eslopfer d20690dc51 docs(kaggle-titanic): fix audits format 1 year ago
eslopfer 628ceb1f20 docs(forest-cover-type-prediction): fix audits format 1 year ago
eslopfer 8fb6444113 docs(credit-scoring): fix prompt format 1 year ago
eslopfer 14a685edec docs(emotions-detector): fix prompt format 1 year ago
eslopfer bc3d8db02e docs(emotions-detector): fix audits format 1 year ago
eslopfer cefa4d59f2 docs(data-wrangling-with-pandas): fix audits format 1 year ago
eslopfer c8c3eb5a76 docs(credit-scoring): fix audits format 1 year ago
eslopfer 204db46fdf docs(clasification-with-scikit-learn): fix audits format 1 year ago
eslopfer 4faa4927bf docs(backtesting): make audit file comply with audit format, fix typos and grammar mistakes 1 year ago
davhojt 48293448a3 docs(backtesting-sp500): rename path to match ref 1 year ago
davhojt 6737972d63 docs(forest-prediction): rename path to match ref 1 year ago
davhojt 10e8cea472 docs(nlp-spacy): rename path to match ref 1 year ago
davhojt 1c1ff5e557 docs(data-wrangling): rename path to match ref 1 year ago
davhojt b59a56713e docs(time-series): rename path to match ref 1 year ago
davhojt 5fe9a8b0ce docs(linear-regression): rename path to match ref 1 year ago
davhojt dc51eadafa docs(classification): rename path to match ref 1 year ago
davhojt 991c7b41b8 docs(pipeline): rename path to match ref 1 year ago
davhojt 90309db9be docs(training): rename path to match ref 1 year ago
davhojt abc4d7fcf8 docs(model-selection): rename path to match ref 1 year ago
davhojt d068c9a012 docs(nlp): rename path to match ref 1 year ago
miguel df1b00c454 fix(easy-perms): fix test to check only the perms 1 year ago
miguel bbee4a7248 fix(easy-perm): fixing the test 1 year ago
miguel 0c7c439360 docs(easy-perms): typo 1 year ago
miguel 88eee63db2 feat(easy-perms): add subject, test and solution for the exercise 1 year ago
miguel 526f60501c fix(hard-perms): fix test to check only the perms 1 year ago
miguel 1d78af2f7a fix(hard-perm): fixing the test 1 year ago
miguel 9b975fdf0f feat(hard-perms): add subject, test and solution for the exercise 1 year ago
miguel 8166812c3c docs(set-internal-vars): add hints 1 year ago
miguel 9a75202406 feat(set-internal-vars): add subject, test and solution for the exercise 1 year ago
miguel 497b331f9d docs(set-env-vars): add hints, fixx the test to block echo and fix solution 1 year ago
miguel 13435eb8f1 docs(set-env-vars): add hints, fixx the test to block echo and fix solution 1 year ago
miguel b2c81baa39 feat(set-env-vars): add subject, test and solution for the exercise 1 year ago
jrosendo 7d092df38d fix(blockchain): fix typo in name 1 year ago
Michele Sessa cc657aa7c3 docs(blockchain): improve audit style and titles 1 year ago
Michele Sessa 8259ea702e fix(tracking-network): fix audit headers 1 year ago
Michele Sessa 077f7c4c9b fix(sign-service): fix audit headers 1 year ago
Michele Sessa 4654dc12cd fix(payment-channel): fix audit headers 1 year ago
Michele Sessa c5a8038e32 docs(non-fungible-cats): fix some typos in the audit 1 year ago
Michele Sessa b8a5834205 fix(node-dashboard): fix audit headers 1 year ago
Michele Sessa 7d5f51e374 fix(nft-marketplace): fix audit headers 1 year ago
Michele Sessa e0dbd353a3 fix(financial-instruments): fix audit headers 1 year ago
Michele Sessa cd2cd98f84 docs(decentralised-finance): fix typo in the name and check audit 1 year ago
Michele Sessa 0f1f13149b refactor(trading-platform, benchmarking-tool): rename respectively to financial-instruments and node-dashboard 1 year ago
nprimo b7b8e4795d docs(passive): correct small typos 1 year ago
nprimo a1843c47f7 docs(obfuscator): make audit gender neutral 1 year ago
nprimo 09a07b5ea4 docs(malware): correct grammar 1 year ago
nprimo d6c0b8e3ec docs(mal-track): improve format and correct grammar 1 year ago
nprimo d382111703 docs(inspector-image): correct grammar 1 year ago
nprimo c522b283b2 docs(mal-track): restore hyperlink 1 year ago
nprimo de978aee29 docs(web-hack): restore hyperlink 1 year ago
nprimo e6742b2897 docs(evasion): restore hyperlink 1 year ago
nprimo 6366d196c5 docs(active): add spacing between bullet list 1 year ago
nprimo e9853b2346 docs(local): add hyperlink where possible 1 year ago
nprimo 44e4ff870c docs(inspector-image): improve audit format 1 year ago
nprimo 97512f9066 docs(hole-in-bin): improve audit format 1 year ago
nprimo 2f9154f891 docs(obfuscator): improve audit format 1 year ago
nprimo 51e06fa543 docs(mal-track): improve audit format 1 year ago
nprimo d8371b697c docs(web-hack): improve audit format 1 year ago
nprimo 65a0a88171 docs(injector): improve audit format 1 year ago
nprimo 8585bc2a71 docs(malware): improve audit format 1 year ago
nprimo f20ce6c407 docs(passive): improve audit format 1 year ago
nprimo 4a42d8f1db docs(evasion): improve audit format 1 year ago
nprimo 829ec0e43f docs(active): improve audit format 1 year ago
nprimo 7520b25427 docs(local): improve audit format 1 year ago
Tiago Collot ecc6bf9943 docs(sumthemall): upgrade instructions 1 year ago
estlop a96274cdab docs: correct typo 1 year ago
estlop 8dc30ed978 docs: clarify instructions 1 year ago
estlop 360304de01 Add error handling when not a number as sugested 1 year ago
estlop 067acad4bb docs: Add readme for sumthemall subject 1 year ago
davhojt 12aa1223ad chore(gaming): move projects inside gaming branch directory 1 year ago
nprimo cd332eec28 docs(favorite-images): improve audit format 1 year ago
nprimo 69ac2320d6 docs(secure-notes): improve audit format 1 year ago
nprimo fa4628109a docs(stock-market): improve audit format 1 year ago
nprimo ecf94f76ed docs(bloc-counter): improve audit format 1 year ago
nprimo 814f380aff docs(hacker-news): improve audit format 1 year ago
nprimo b92f3a36eb docs(movie-list): improve audit formats 1 year ago
nprimo f9c6335c75 docs(bizz-card): improve audit format 1 year ago
nprimo b32ef63889 docs(quizz-app): improve audit format 1 year ago
nprimo b13336b953 docs(01-maps): improve audit format 1 year ago
nprimo aa5c04cc0f docs(bouncer): improve audit format 1 year ago
nprimo a35bf4f4f7 docs(sky-map): improve audit format 1 year ago
nprimo 0dae786e3a docs(packate): improve audit format 1 year ago
Roberto Catini b85a77b28d remove spurious blank lines in examples 1 year ago
nprimo 70ee6a2109 docs(ascii-art-color): update audit 1 year ago
nprimo b7a11a3fe4 docs(ascii-art): fix examples spacing 1 year ago
davhojt 966796fcae docs(shop): remove leading spaces 1 year ago
xalava d043ac37a8 Last blockchain projects 1 year ago
eslopfer 90a0e60450 docs(cat): fix inconsistency on example 1 year ago
miguel 93288bcdfd docs(quadchecker): changing the word raid to quad in the readme and audit 1 year ago
nprimo fc2d986a5d docs(ascii-art-web): make audit coherent with subject 1 year ago
Michele Sessa c53584ed35 docs(gatecrashers): remove non neutral content 1 year ago
miguel 2e6747da72 feat(env-format): add subject, test and solution for the exercise 1 year ago
miguel 53aa0b3f92 docs(master-the-ls): add .sh in the readme 1 year ago
miguel fc197de5fd docs(master-the-ls): fix readme and change to script instead of a file 1 year ago
miguel 3112b89373 fix(master-the-ls): fixing readme and test 1 year ago
miguel 1fcd020884 docs(master-the-ls): moving the subject to the folder devops and fix readme 1 year ago
miguel 9dbebae756 feat(master-the-ls): add subject, test and solution for the exercise master-the-ls 1 year ago
miguel fe31b9677d docs(count-files): adding info on th wc command 1 year ago
miguel 22355f3441 docs(count-files): adding examples 1 year ago
miguel 3d7497b538 docs(count-files): moving the subject to the folder devops and fix readme 1 year ago
miguel 7849dc44fb feat(count-files): add subject, test and solution for the exercise count-files 1 year ago
miguel 18a21bfe6d docs(change struct): fixing test and removing folders 1 year ago
miguel 3049697bf4 docs(change-struct): remove repeated info of the Readme 1 year ago
miguel 232bbf2b5c docs(change-struct): moving the subject to the folder devops 1 year ago
miguel fcf7432c49 Adding empty folders 1 year ago
miguel ae0847fbcd feat(change-struct): add subject, test and solution for new a exercise 1 year ago
miguel d8e7a606f0 docs(file-struct): fixing test and removing folders 1 year ago
miguel 2ee882e8a2 docs(file-struct): adding info on the Readme 1 year ago
miguel daafc5d465 docs(file-struct): moving the subject to the folder devops 1 year ago
miguel cc2dd1c36e Adding empty folders 1 year ago
miguel e3d8cd9516 feat(file-struct): add subject, test and solution for new a exercise 1 year ago
miguel 8230ba16ee docs(strange-files): fixing readme 1 year ago
miguel 3410c9ee5a docs(strange-files): moving the subject to the folder devops 1 year ago
miguel e06b028697 feat(strange-files): add subject, test and solution for new a exercise 1 year ago
Zouhair AMAZZAL 23d56da262 fix(hello-devops) fix subject and tests name 1 year ago
Zouhair AMAZZAL 6cf269c441 DEV-3896 feat(hello_devops) add subject and tests for into exercise to teach student how to push in gitea repo 1 year ago
Christopher Fremond fc263a8d09
feat(dom test image): correct the DOM image tag 1 year ago
Michele Sessa 82d6ce3933 docs(lem-in): clarify expected behavior for tunnels in the subject 1 year ago
Michele Sessa 504350a830 docs(lem-in): clarify expected behavior for tunnels 1 year ago
jrosendo ceee355156 chore(blockchain): remove tip exercise 1 year ago
miguel 4da285b07f docs(skip-lines): moving the subject to the folder devops and fix readme 1 year ago
miguel 4b02c825b7 feat(skip-lines): add subject, test and solution for the exercise skip-line 1 year ago
miguel 5d6875d0a8 feat(file-researcher): add subject, test and solution for the exercise file-researcher 1 year ago
jrosendo 73fda016e5 docs(ai): add ai branch subjects to public 1 year ago
jrosendo 53af9f2ecb docs(mobile-dev): add mobile branch subjects to public 1 year ago
jrosendo 7a960f7d00 docs(blockchain): add blockchain branch subjects to public 1 year ago
jrosendo 52b4b5545b docs(cibersecurity): add cibersecurity branch subjects to public 1 year ago
Chris dff9dd77ad feat(public repo)makes building step independent from the success or failure or each other 1 year ago
Chris 02f28b9695 feat(public repo)log in the 01-edu repository prior to executing the other actions 1 year ago
Chris 9731c7c0ca feat(publicrepo):automates builds and add all images of the public repo to github registry 1 year ago
Michele Sessa 96817e90fa fix(matrix_mult): fix package name mismatch 1 year ago
Michele Sessa 6d2677e0f0 fix(matrix_op): fix package name mismatch 1 year ago
Michele Sessa e1fab8e3ea docs(gatecrashers): add explicit quote to previous exercise behavior 2 years ago
Michele Sessa e2a8dc2bbd refactor(gatecrashers): remove code repetition, consistent use of eq and fail for test checks 2 years ago
Michele Sessa 52c167a390 refactor(gatecrashers): use fs/promises for file access in tests, remove unused imports 2 years ago
Michele Sessa e3e7058507 feat(gatecrashers): add test names, start/kill server for each test, add test for file created and POST answers 2 years ago
Michele Sessa 73d7b44898 docs(gatecrashers): change example, now content-type is application/json 2 years ago
Michele Sessa 9a2a1b7e9d feat(gatecrashers): add a new exercise to js node quest 2 years ago
Zouhair AMAZZAL 266d7dd0ee docs(find-files): fix grammer error 2 years ago
Zouhair AMAZZAL 80706806e6 docs(find-files): explain what everything means and all files in the exercise Instructions 2 years ago
Zouhair AMAZZAL a60c16dcaf docs(find-files): fix grammer error 2 years ago
Zouhair AMAZZAL abc65b2eb2 test(find-files): check if the submitted file is correct and check if echo is used 2 years ago
Zouhair AMAZZAL b864a26525 docs(find-files): fix grammer error 2 years ago
Zouhair AMAZZAL 692e383ff0 docs(find-files): move subject to devops dir 2 years ago
Zouhair AMAZZAL e2e32458af docs(find-files): add pipe and && reminder in doc 2 years ago
Zouhair AMAZZAL cabe2e248f feat(find-files): add subject, test and solution for new a exercise 2 years ago
Zouhair AMAZZAL 6b9d5c478b docs(json-researcher): fix grammer error 2 years ago
Zouhair AMAZZAL 0f7814fc4a docs(json-researcher): fix grammer error 2 years ago
Zouhair AMAZZAL 0dea7a8945 test(json-researcher): check echo is used 2 years ago
Zouhair AMAZZAL 3531d1b12f test(json-researcher): check if the submitted file name is correct 2 years ago
Zouhair AMAZZAL d0e9b91f73 docs(json-researcher): move subject to devops dir 2 years ago
Zouhair AMAZZAL c2e80f1033 test(json-researcher): add shell type exec && fix permission to scripts 2 years ago
Zouhair AMAZZAL b1762c3aac feat(json-researcher): add subject, test and solution for new a exercise 2 years ago
Zouhair AMAZZAL 51c804a135 docs(head-and-tail): fix grammer error 2 years ago
Zouhair AMAZZAL 0e0f86dfed docs(head-and-tail): fix grammer error 2 years ago
Zouhair AMAZZAL 6467fd10fa test(head-and-tail): check if the submitted file is correct and check if echo is used 2 years ago
Zouhair AMAZZAL 47aa2ae008 docs(head-and-tail): move subject to devops dir 2 years ago
Zouhair AMAZZAL abf236eac3 test(head-and-tail): add shell type exec && fix permission to scripts 2 years ago
Zouhair AMAZZAL 75dc52bec5 docs(head-and-tail): add google and man reminder in doc 2 years ago
Zouhair AMAZZAL cbdc5c4a6f feat(head-and-tail): add subject, test and solution for new a exercise 2 years ago
Zouhair AMAZZAL 40395c5dac docs(find-files-extension): fix grammer error 2 years ago
Zouhair AMAZZAL 6712ad9dea test(find-files-extension): check if the submitted file is correct and check if echo is used 2 years ago
Zouhair AMAZZAL ebde98d95d docs(find-files-extension): move subject to devops dir 2 years ago
Zouhair AMAZZAL 1f284b5c43 feat(find-files-extention): add subject, test and solution for new a exercise 2 years ago
nprimo 7f769ef487 docs(manipulate-entries): fix typo 2 years ago
nprimo 722edd9e69 docs(manipulate-entries): add usage section 2 years ago
jrosendo 0cb639701a docs(checknumber): added subject 2 years ago
jrosendo 6802353d6e docs(countalpha): ran prettier 2 years ago
jotapero 3e36a8e0e8 docs(countalpha): fix subject 2 years ago
jotapero 60f5e0bfd4 docs(countalpha): fix subject 2 years ago
hamza a4c46c3378 docs(countAlpha): add subject 2 years ago
jrosendo 2bd32ad039 docs(removeDuplicate): fixed subject 2 years ago
jotapero e7d839f162 docs(removeDuplicate): fix subject 2 years ago
hamza 73ea4f4110 DEV-3451 docs(removeDuplicate):add subject 2 years ago
jrosendo 099e1d68ae fix(binarycheck): fix branch 2 years ago
jrosendo 29209baacc fix(printifnot): fix branch 2 years ago
Roberto Catini 2cc1009564 rephrase presentation of the input file 2 years ago
jrosendo 9bbefc7f89 fix(countcharacter): added count character 2 years ago
jrosendo 3a08d55a2f fix(binarycheck): fix branch 2 years ago
jrosendo b499b84ce3 fix(getascii): replaced wrong exercise 2 years ago
jrosendo 2f46d7e8c6 chore(getascii): fixing conflicts 2 years ago
nprimo f659ea6d86 docs(ascii-art): implement suggestions 2 years ago
nprimo d58f8e8e38 docs(ascii-art): add details to make audits consistent 2 years ago
jotapero 189ad964c3 docs(displayP): created new subject 2 years ago
jrosendo b1960dc26b docs(only1): fixed subject 2 years ago
hamza 36ffad787d DEV-3387 fix the title 2 years ago
hamza 9c280eaff1 DEV-3387 docs(only1):add subject 2 years ago
jrosendo 816f05e228 docs(getascii): ran prettier format 2 years ago
jrosendo d72e8f3c1f fix(getAlpha): removed unnecessary file 2 years ago
jrosendo 5abc1e59a8 docs(getAlpha): fixed subject 2 years ago
jotapero 256b470992 docs(getAlpha): fix subjects 2 years ago
jotapero 7942764119 fix(getAlpha): fix removed file 2 years ago
jrosendo 76155b8086 docs(sliceadd): ran prettier format 2 years ago
jrosendo 2e886a02cd docs(sliceAdd): fixed subject 2 years ago
jotapero 44e4eb1dfe docs(sliceAdd): fix subject 2 years ago
hamza 27302761e8 DEV-3414 docs(SliceAdd):add subject 2 years ago
jrosendo 4dd8e9ccca docs(removeslice): ran prettier format 2 years ago
jrosendo a28ac1ea50 docs(sliceRemove): fixed subject 2 years ago
jotapero 0fe2165844 docs(sliceRemove): fix subject 2 years ago
hamza 85bec091bb DEV3415 docs(sliceRemove):add subject 2 years ago
nprimo de95b3b572 refactor(friend-support): improve single test clarity 2 years ago
nprimo ab38fc622a refactor(friend-support): start and kill server for each test 2 years ago
nprimo d3fa6a5355 feat(friend-support): add random factor to tests 2 years ago
nprimo 446924e348 refactor(friend-support): implement suggested changes 2 years ago
nprimo d189e1deea docs(fried-support): clarify subject 2 years ago
nprimo e2ece47510 feat(Dockerfile): update apline version use 2 years ago
nprimo 380ad0dc3e feat(friend-support_test): update tests 2 years ago
nprimo 50c73c0af3 feat(friend-support): add draft test 2 years ago
nprimo f179d6e09f feat(tests): update script to use fetch in node tests 2 years ago
nprimo 3f07f9dc5f feat(friend-support): add subject for new exercise 2 years ago
jrosendo be637efb0d chore(returna): testing prettier 2 years ago
jrosendo 740da8eef8 chore(returna): testing prettier 2 years ago
jrosendo 4a514e6f3a chore(returna): testing prettier 2 years ago
jrosendo c189bdd64d chore(returna): testing prettier 2 years ago
jrosendo 08cedb74d3 docs(returna): created a subject for returna exercise 2 years ago
jrosendo a8cae3aa7c docs(byebyefirst): ran prettier format 2 years ago
jrosendo 3bfd1de5a8 docs(byebyefirst): fix typo 2 years ago
jrosendo 1e09e6b367 fix(byebyefirst): fix folder 2 years ago
estlop 493375231a docs: Write readme for byebyefirst subject 2 years ago
jrosendo 5c8be6373d docs(issamestring): fix typo 2 years ago
Mohamed Zaboub d601a9ff55 chore: replace spaces by tabulation 2 years ago
Mohamed Zaboub be7ac7ee70 add(subjects): issamestring subject 2 years ago
jrosendo 9962ae8f5b docs(rectperimeter): added output example 2 years ago
jrosendo f6de74789c docs(rectperimeter): fix subject 2 years ago
MOHAMED a8ddec8fc3 fix: remove number backticks 2 years ago
Mohamed Zaboub 1982384bbb add(subject): rectperimeter exercise 2 years ago
jrosendo 61f2b9550f docs(sumascii): ran prettier format 2 years ago
jrosendo 6ad8474527 docs(sumascii): fix subject 2 years ago
jrosendo 1cb6a5ea01 docs(sumascii): fix subject 2 years ago
estlop e202c2ca27 docs: Address example of usage as per review 2 years ago
estlop ab36a0cd88 Add readme file for sumascii subject 2 years ago
jrosendo 118766b2d7 docs(multorsum): ran prettier format 2 years ago
jrosendo 3d8156f44c docs(multorsum): rephrase one sentence 2 years ago
jrosendo 82ac6cd676 docs(multorsum): fix subject 2 years ago
estlop 2c324911d5 docs: fix typo 2 years ago
estlop c98b517c71 docs: Add returning type 2 years ago
estlop d438e5f04a docs: Write readme for multorsum subject 2 years ago
jrosendo 39c8bd1683 docs(replaceeven): ran prettier format 2 years ago
jrosendo b57752f5f9 docs(replaceeven): fix typos 2 years ago
jrosendo 420d54d1cc docs(replaceeven): fix subject 2 years ago
Mohamed Zaboub 3f986cebc1 add(replaceeven): subject 2 years ago
jrosendo 2b02ed5fbd docs(cameltosnakecase): ran prettier format 2 years ago
jrosendo 257d088144 docs(cameltosnake): added output case 2 years ago
jrosendo a0de7068d6 docs(cameltosnakecase): fix subject 2 years ago
Hamza elkhatri 88ff699bc1 docs(camelToSnakeCase) : rewrite the description 2 years ago
Hamza elkhatri 10c2f1501d docs(CamelTosnackCase): rewrite description and fix output console 2 years ago
Hamza elkhatri 04bf6eb2b4 rewrite description 2 years ago
Hamza elkhatri 346cadb3d9 Update README.md 2 years ago
Hamza elkhatri 88d99aaa97 Update README.md 2 years ago
Hamza elkhatri b260bda961 fix:rewrite description , and change the output 2 years ago
Hamza elkhatri d404e2dc12 Update README.md 2 years ago
Hamza elkhatri 292e9b8bae Update README.md 2 years ago
hamza 82762eaac7 subject(camelTosnackCase): add readme 2 years ago
jrosendo 06c15846ef docs(weareunique): fix typos 2 years ago
jrosendo 8450a159e4 docs(weareunique): fixed subject 2 years ago
MSilva95 6ea5f04a3b remove $ to avoid confusion 2 years ago
zainab Dnaya 52cb3a902d Update README.md 2 years ago
zainab Dnaya 1431f1512c Update README.md 2 years ago
zainab Dnaya 7f43129173 Update README.md 2 years ago
zainabdnaya 379a0543eb corrected 2 years ago
zainabdnaya ebf4c17716 corrected 2 years ago
zainabdnaya 1b9ffc115f corrected 2 years ago
zainabdnaya 8ebe3d1739 correcte output 2 years ago
zainabdnaya d272fe67aa weareunique subject 2 years ago
jrosendo e519af63e1 docs(argSort): fixed subject 2 years ago
jrosendo e5928b32f2 docs(isSorted): fixed subject 2 years ago
MSilva95 13ccbfb416 typo 2 years ago
zainab Dnaya 2b964e5a5a Update README.md 2 years ago
zainab Dnaya 1652945c13 Update README.md 2 years ago
zainabdnaya ffe99b1c56 corrected 2 years ago
zainabdnaya cb249fb62f corrected 2 years ago
zainabdnaya f0dede7d26 corrected 2 years ago
zainabdnaya 9e48168481 corrected 2 years ago
zainabdnaya aad7414b31 corrected 2 years ago
zainabdnaya 2cb93a8948 corrected 2 years ago
zainabdnaya 7f5ed6e2a4 add test 2 years ago
zainabdnaya ae54d0242e corrected 2 years ago
zainabdnaya da3072dbcc corrected 2 years ago
zainabdnaya a9aefbd204 subject argsort 2 years ago
zainabdnaya 175b79f1ed argsort subject 2 years ago
zainabdnaya 1e31c9e1ba argsort subject 2 years ago
zainabdnaya 5d501ff8be issirted subject 2 years ago
zainabdnaya 8913aa6410 issirted subject 2 years ago
jrosendo fb90a96eec docs(frontback): ran prettier format 2 years ago
jrosendo d5a8d222e7 docs(frontback): added paragraph 2 years ago
jrosendo c18f05927c docs(frontback): fixed subject 2 years ago
Hamza elkhatri e9193c30b7 Update README.md 2 years ago
Hamza elkhatri 7fd30876e7 Update README.md 2 years ago
hamza 814fbd2c0e fix(name):replace name of file by frontback 2 years ago
Hamza elkhatri c86e37cef7 Update README.md 2 years ago
Hamza elkhatri 9bff4b857b Update README.md 2 years ago
Hamza elkhatri 7ae7dc15d8 Update README.md 2 years ago
Hamza elkhatri adc4ca30c6 Remove one level of bullet points 2 years ago
Hamza elkhatri 79dac93e46 Update README.md 2 years ago
hamza da9488a80c add inscrutions title and edit title 2 years ago
hamza c17271b4f7 remove duplicated title 2 years ago
hamza a4b8953fa7 fix(bracket): add bracket to \n 2 years ago
hamza 6322b1f4e0 feat: add new exam exercise 2 years ago
jrosendo 4fad8d25ca docs(canyoucount): ran prettier format 2 years ago
jrosendo f6a0cc925c docs(canyoucount): fix subject 2 years ago
estlop 8d36aa1317 Add more examples of tests as per review 2 years ago
estlop 1d0cf358fc docs: Add readme for canyoucount subject #1258 2 years ago
Harry 139270b565
fix(deploy): server directory path 2 years ago
jrosendo 76739f7d83 docs(displayS): fixed subject 2 years ago
jotapero fee07c8249 docs(displayS): fix subject console output 2 years ago
hamza 304c928293 DEV-3389 docs(DisplayS):typo 2 years ago
hamza de6cfddda6 DEV-3389 rename the dir and title 2 years ago
hamza 00e8903bc1 DEV-3389 docs(onlys):add subject 2 years ago
jrosendo 2afc50179b style(reversesecondhalf): ran Prettier 2 years ago
jrosendo 8d11216438 docs(reversesecondhalf): made subject more clear 2 years ago
jrosendo ab2e4628b0 docs(reverseSecondHalf): fix subject 2 years ago
jotapero 3a26f0a94c docs(reverseSecondHalf): fix subject 2 years ago
zainab Dnaya 0429578368 Correct the Subject 2 years ago
zainab Dnaya cdf5ac7892 Update README.md 2 years ago
zainab Dnaya d8b5cb4e2d Update README.md 2 years ago
zainab Dnaya 4fff8bd5c9 Update README.md 2 years ago
zainabdnaya b3fb448f62 feat: subject of ReverseSecondHalf 2 years ago
zainabdnaya 29524526c4 feat: subject of ReverseSecondHalf 2 years ago
jrosendo b07d713253 docs(onlyB): fix subject 2 years ago
jrosendo 8906eab7b6 docs(onlyB): fix subject 2 years ago
Hamza elkhatri e02dce6987 fix the title 2 years ago
hamza 2fcf16d697 DEV-3386 docs(onlyB) : add subject 2 years ago
hamza 792b2f9b6f DEV-3386 docs(onlyb):add subject 2 years ago
jrosendo 7dea33670b docs(onlyF): fixed subject 2 years ago
jrosendo 8ad42033d8 docs(onlyF): fixed subject 2 years ago
Hamza elkhatri cf5dd2d70d Update README.md 2 years ago
hamza 79c96d1a7d DEV-3385 docs(onlyf):add subject 2 years ago
davhojt d94c1c3f4f docs(go-reloaded): add list of valid vowels 2 years ago
eslopfer b391949bfb docs(printstr): clarify and make accurate usage example 2 years ago
eslopfer 00177d71b4 docs(piscine-go): remove extra new line being printed in the example 2 years ago
Dani 0c771833ba Incorrect table for B donation: B can't donate to O+, O- 2 years ago
Dias Kappassov 29532816bd Update README.md 2 years ago
eslopfer 4f0e84fed5 docs(own-and-return): split long comment in two lines 2 years ago
eslopfer 3dd925866f docs(own-and-return): add commas 2 years ago
eslopfer 64274236fb docs(own-and-return): remove space 2 years ago
eslopfer 800c6067f0 docs(own-and-return): make usage example clearer 2 years ago
eslopfer 0f50a371e1 docs(own-and-return): modify as per review 2 years ago
eslopfer bb0661422d refactor(own-and-return): rename according to what is being asked to do now 2 years ago
eslopfer 0fc87521e6 docs(print-and-consume): add description of exercise 2 years ago
eslopfer 36fe2fd393 docs(print-and-consume): write partial description of subject 2 years ago
eslopfer 4c837d150e refactor(print-and-consume): change name to follow conventions 2 years ago
eslopfer 982c87d34d docs(print_and_consume): description of exam exercise 2 years ago
Michele Sessa c6a2e5d80a chore(office_worker): add an extra empty line for prettier 2 years ago
Michele Sessa dba6a14d2c docs(office_worker): specify expected behaviour for invalid in puts 2 years ago
mikysett ccc0a2dc0a feat(office_worker): add new exercise for rust exams 2 years ago
miguel fa28c2e03d docs(zappy): adding clarifications to the readme 2 years ago
eslopfer bff08d50d9 docs(subjects): add link to official docs 2 years ago
Michele Sessa 1910f00925 docs(drop_the_blog): make subject prettier compliant 2 years ago
Michele Sessa f47d73dd23 feat(drop_the_blog): add exercise for rust exams 2 years ago
nprimo be03753c56 fix(ascii-art-justify): fix audit request 2 years ago
Maxim Mihajlov c66a05c621 docs(ascii-art-justify): fix audit 2 years ago
nprimo 75da5b3fcd docs(prime_checker): update subject 2 years ago
nprimo 5e828aa968 docs(prime_checker): update subject 2 years ago
nprimo a17977de9b feat(prime_checker): simplify example main 2 years ago
nprimo 92d91c30f8 feat(prime_checker): add new rust exercise 2 years ago
nprimo 6becf34972 docs(get_document_id): update subject 2 years ago
nprimo 6e10678bbc docs(get_document_id): make main function consistent with instructions 2 years ago
nprimo 8270fab4d1 docs(get_document_id): update expected function and structures 2 years ago
nprimo a769381cbd feat(get_document_id): add new rust exercise 2 years ago
nprimo 97e68708b6 docs(lucas_number): improve subject 2 years ago
nprimo 6edb6f640e feat(lucas_number): add new rust exercise 2 years ago
Michele Sessa 0af2665526 docs(car_rental): make the goals more clear 2 years ago
Michele Sessa fc14783654 feat(car_rental): add new exercise for rust exams 2 years ago
Bakdaulet Ye b3508822d0 More clear instructions 2 years ago
eslopfer 548ee49fef docs(check-user-name): fix typo 2 years ago
eslopfer d2bb07b78f refactor(check-user-name): change name to keep consistency with the naming convention 2 years ago
eslopfer ca51a72877 docs(check_user_name): highlight word for better readability 2 years ago
eslopfer a9e1218ff4 docs(check_user_name): fix incoherent number 2 years ago
eslopfer 4b9922772f docs(check_user_name): fix typo 2 years ago
eslopfer 3cfd4b2844 docs(check_user_name): fix typo 2 years ago
eslopfer 67c543130c docs(check_user_name): dont include chec_user_name as associated as per the review 2 years ago
eslopfer 7483b922e8 docs(check_user_name): use backticks instead of asterisks` 2 years ago
eslopfer c7f50f5d24 docs(check_user_name): fix typo 2 years ago
eslopfer 6fec3d5899 docs(check_user_name): rename to keep conventions 2 years ago
eslopfer b1e2b3029a docs(check_user_name): fix typo 2 years ago
eslopfer 1c1966f536 docs(check_user_name): implement description of exercise 2 years ago
Michele Sessa f1656004ed feat(format_me): add new exercise for rust exams 2 years ago
Michele Sessa ae3772b29f chore(moving_targets): remove spaces in empty line 2 years ago
mikysett 9d8f2678c4 feat(moving_targets): add new exercise for rust exams 2 years ago
nprimo 40007e2650 docs(dress_code): improve subject style 2 years ago
nprimo 4b22362c2b docs(dress_code): improve subject format 2 years ago
nprimo f99f57537f feat(dres_code): add new rust exercise 2 years ago
eslopfer f579e040dc docs(smallest): specify what to do when the hashmap is empty 2 years ago
eslopfer 71a2c55a83 docs(smallest): remove positive numbers constraint 2 years ago
eslopfer f6251d8dfe docs(smallest): add readme with description of subject 2 years ago
eslopfer dc80b79745 docs(public/subjects): add alt text for images 2 years ago
eslopfer 3703c92b28 docs(public/subjects): add document on how to lint markdown files to keep consistency 2 years ago
mikysett 53f7ded2f2 refactor(negative_spelling): improve function name readability 2 years ago
mikysett 2d8f1bb160 feat(negative_spelling): create new exam exercise for rust 2 years ago
eslopfer 15f5814f33 docs(modify_letter): remove reference to what to do on edge cases 2 years ago
eslopfer b4b9480eec docs(modify_leter): modify example strings to make them different as in previous exercises 2 years ago
eslopfer 24329d91b2 docs(modify_letter): Add missing . 2 years ago
eslopfer aaf6fed9d9 docs(modify_letter): specify what to do when there is an empty string or an empty letter 2 years ago
eslopfer b587916143 docs(modify_letter): correct incorrect examples 2 years ago
eslopfer 812e336480 docs(modify_letter): fix wrong syntax to refer to a char value 2 years ago
eslopfer 0a83ac648b docs(modify_letter): add description of the subject 2 years ago
miguel da871819d9 docs(zappy): giving a tip instead of a command 2 years ago
miguel e6b8fe1edd docs(zappy): fixing the subject in zappy 2 years ago
miguel 1e49439dd3 docs(zappy): fixing the subject in zappy 2 years ago
miguel 54c0c3b19d docs(zappy): fixing the subject in zappy 2 years ago
miguel 84392f8ebb docs(zappy): fixing the subject and audit in zappy 2 years ago
miguel 595368a3ca docs(zappy): fixing the subject in zappy 2 years ago
miguel cbbc175648 docs(zappy): fixing the audit in zappy 2 years ago
miguel 987a440971 docs(zappy): fixing the audit in zappy 2 years ago
miguel 5bb3cf72f2 docs(zappy): changing zappy subject 2 years ago
miguel 434c117b17 docs(zappy): adding an image as an example to the subject 2 years ago
miguel f2fc936e2f docs(zappy): minor changes and corrections to the audit and subject 2 years ago
miguel 9cfef991a1 docs(zappy): fixing the audit and subject 2 years ago
Hamza elkhatri dea5debfeb fix typo 2 years ago
zainabdnaya 2e8125f4c8 typo modification 2 years ago
zainabdnaya 0a4373f6af typo modification 2 years ago
hamza cd549fbe74 add audit and fix typo 2 years ago
zainabdnaya 4894db9f47 Zappy Project 2 years ago
nprimo c0d3cddadc fix(keycodes-symphony-dom test): redefine function 2 years ago
mikysett 61673c3614 feat(organize_garage): add new exercise for rust exams 2 years ago
nprimo c46c81e469 docs(count_factorial_steps): improve subject readibility 2 years ago
nprimo 5fd392a741 feat(count_factorial_steps): add new rust exercise 2 years ago
nprimo 6c11610c4f docs(matrix_multiplication): update subject 2 years ago
nprimo ac61045fd4 feat(matrix_multiplication): add new rust exam exercise 2 years ago
nprimo f1728e8f8c docs(min_and_max): make example and output given coherent 2 years ago
nprimo eb8c882ba8 fix(min_and_max): correct placeholder in example 2 years ago
nprimo e3d0f81d6a refactor(min_and_max): simplify example 2 years ago
nprimo 118cf8457f docs(min_and_max): add new rust exam exercise 2 years ago
mikysett 286d6f09b6 feat(scytale_decoder): add new exercise for rust exams 2 years ago
Harry 406fe7f6b8
fix(preseed): use single ssh key 2 years ago
eslopfer 4e13857c4d docs(reduce): fix inconsistency in the number of functions 2 years ago
Tiago Collot c0792d627f docs(shoppinglistsort): fix instructions 2 years ago
Harry Vasanth 43129a46ca fix(configure): add check for valid FQDN 2 years ago
Harry Vasanth 38666ae0c6 fix(configure): add more options to accomodate various prod/pre-prod environments 2 years ago
Harry Vasanth 8d9f1d2e89 fix(configure): add interactive options 2 years ago
Harry Vasanth 9cbae89ef5 fix(configure): add --deploy option and additional features 2 years ago
Harry Vasanth f4ce8ea0b8 fix(configure): add packages, perform check and enable passing arguments 2 years ago
Michele Sessa d2fbdeffd9 docs(pig_latin): add edge case in usage 2 years ago
mikysett 51bf67e5d7 docs(pig_latin): small typo fixed 2 years ago
mikysett 1e7ae325ac feat(borrow_me_the_reference): remove need for meval 2 years ago
Michele Sessa 7e04c7ff10 docs(easy_traits): fix prototype error and add pub where necessary 2 years ago
mikysett 5c8406d6d0 docs(how_many_references): improve variables names 2 years ago
Michele Sessa 799ca8670b docs(error_types): fix typo 2 years ago
Michele Sessa 0a3572d111 docs(error_types): fix typo 2 years ago
mikysett 12b99d2315 fix(error_types): update console output example) 2 years ago
mikysett a87cb5c5e4 feat(error_types): improve style and names 2 years ago
Michele Sessa 31e7b8dcd6 docs(cipher): fix typos and remove useless notions 2 years ago
Michele Sessa 9425070b2e feat(simple_hash): rewrite exercise completely 2 years ago
mikysett 6e969f8b3f feat(simple_hash): refactor completely the exercise, work in progress 2 years ago
mikysett 187028562b docs(circle): improve functions prototypes consistency 2 years ago
Michele Sessa ad42d04a89 refactor(tic_tac_toe): all results are now lowercase 2 years ago
Tiago Collot 13b4b0fbf7 docs(shoppinglistsort): fix subject 2 years ago
Tiago Collot 38868a8403 docs(shoppinglistsort): indentation fix 2 years ago
Tiago Collot 4d13d88fa7 docs(shoppinglistsort): fix subject information 2 years ago
Tiago Collot 7991881a01 fix(shoppinglistsort): miss import piscine and add second # to the title 2 years ago
Tiago Collot 7736e2d02e style(shoppinglistsort): formatting header from exercise title 2 years ago
Tiago Collot e84cda90f9 style(shoppinglistsort): formatting 2 years ago
Tiago Collot 3e64e028d8 feat(pisicine-go): add README.md for new exercise shoppinglistsort 2 years ago
Michele Sessa 31833e4418 refactor(tuples_refs): change id type for more idiomatic rust 2 years ago
Tiago Collot 000ba6542c docs(jumpover): fix indentation 2 years ago
Tiago Collot 1b29753470 style(jumpover): formatting 2 years ago
Tiago Collot 490176cc08 fix(jumpover): add missing import piscine and add second # to the title 2 years ago
Tiago Collot 087a16d8ba docs(loafofbread): indentation fix 2 years ago
Tiago Collot aacf91b934 style(loafofbread): add backticks 2 years ago
Tiago Collot 57ab470299 fix(loafofbread): add missing import piscine and add second # to the title 2 years ago
Tiago Collot 27ef0d2782 docs(rockandroll): upgrade instructions 2 years ago
Tiago Collot f6d0cc58a7 docs(rockandroll): fix console 2 years ago
Tiago Collot 05f680e5d7 fix(rockandroll): change console name from 'go' to 'console' 2 years ago
Tiago Collot a420b1f6d5 fix(rockandroll): miss import piscine and add second # to the title 2 years ago
Tiago Collot 103a6b5192 style(descendappendrange): formatting header from exercise title and format text 2 years ago
Tiago Collot ad99c887eb style(piscine-go): correct text format 2 years ago
Tiago Collot b26ab24c0e feat(piscine-go): add README.md for new go exercise rockandroll 2 years ago
Harry d2b3bdbd2f
fix(podiumposition): re-format golang codeblock 2 years ago
miguel 943ce127ce fix(ascii-art): remove merge message from the audit 2 years ago
miguel efaf2d0595 fix(graphql): removing unnecessary data from the table 2 years ago
miguel 219e7b4cbd fix(projects): replace satori/uuid in some projects because it is unmaintained and vulnurable 2 years ago
miguel b11528ec4b fix(ascii-art): fixing the way to use the flag on the optional projects 2 years ago
mikysett 50ae92c2bd docs(localhost): make it clear project will be tested with siege 2 years ago
Michele Sessa 8d1b0b182a docs(localhost): add note to clarifiy auditor should check source code 2 years ago
Michele Sessa 9b9f6aed67 docs(localhost): add notice on how to use siege tool 2 years ago
Michele Sessa 5b8b954d75 docs(localhost): give more clarity in the subject goals 2 years ago
Michele Sessa 0f4fb751a5 docs(localhost): improve audit consistency 2 years ago
mikysett 60f5aa31c6 feat(localhost): change to Rust-only project 2 years ago
mikysett 755249bbb6 docs(localhost): fix a typo in audit 2 years ago
mikysett 71e671c5e5 fix(localhost): fix audit formatting using preview 2 years ago
mikysett f048c0fa87 feat(localhost): subject and audit ready for review 2 years ago
Tiago Collot 1b8355eac1 docs(stringtointslice): fix indentation 2 years ago
Tiago Collot bf3fcb6f50 docs(stringtointslice): fix the console name from 'go' to 'console' 2 years ago
Tiago Collot abe64ca1b3 docs(stringtointslice): Rename file and rename README.md functions to stringtointslice 2 years ago
Tiago Collot ded101b86c style(stringtointarray): formatting 2 years ago
Tiago Collot ee8732c9de fix(stringtointarray): miss import piscine and add second # to the title 2 years ago
Tiago Collot c34d3141bf style(stringtointarray): formatting header from exercise title 2 years ago
Tiago Collot c6e150901e feat(piscine-go): add README.md for new go exercise stringtointarray 2 years ago
Tiago Collot 8647521af3 docs(dealapackofcards): refactor instructions, fix indentation 2 years ago
Tiago Collot d771054ccc fix(dealapackofcards): miss import piscine and add second # to the title 2 years ago
Tiago Collot 378181a995 style(dealapackofcards): formatting header from exercise title 2 years ago
Tiago Collot b36a5f98f2 feat(piscine-go): add README.md for new go exercise dealapackofcards 2 years ago
Tiago Collot a527e3f2ea docs(fooddeliverytime): refactor instructions and fix indentation 2 years ago
Tiago Collot a46cf4285b fix(fooddeliverytime): miss import piscine and add second # to the title 2 years ago
Tiago Collot 9cd626d8b6 feat(piscine-go): add README.md for new go exercise fooddeliverytime 2 years ago
Tiago Collot d1233266f9 docs(shoppingsummarycounter): indentation fix 2 years ago
Tiago Collot 43291628d3 docs(shoppingsummarycounter): fix indentation 2 years ago
Tiago Collot 5084471315 fix(shoppingsummarycounter): miss import piscine and add second # to the title 2 years ago
Tiago Collot 4dd857f8e9 style(shoppingsummarycounter): formatting header from exercise title 2 years ago
Tiago Collot 54addda494 feat(piscine-go): add README.md for new go exercise shoppingsummarycounter 2 years ago
Tiago Collot 7a4af4d164 docs(reversemenuindex): change the markdown instructions 2 years ago
Tiago Collot 460754b7b3 fix(reversemenuindex): miss import piscine and add second # to the title 2 years ago
Tiago Collot 024d17a2c6 style(reversemenuindex): formatting header from exercise title and format text 2 years ago
Tiago Collot b2c998ea8f style(reversemenuindex): formatting 2 years ago
Tiago Collot aa08580a4d feat(piscine-go): add README.md for new go exercise reversemenuindex 2 years ago
Tiago Collot e62a381533 docs(descendappendrange): fix indentation 2 years ago
Tiago Collot 7f9f275547 docs(descendappendrange): fix instructions 2 years ago
Tiago Collot 3102b64701 docs(descendappendrange): fix console, missing 'cat -e' 2 years ago
Tiago Collot a2b515bb38 docs(descendappendrange): fixed the exercise instruction in order to match the expected output 2 years ago
Tiago Collot a31d4a2e8c docs(descendappendrange): change subject instructions 2 years ago
Tiago Collot cf679aa068 style(descendappendrange): add second # to the title 2 years ago
Tiago Collot 23349eea08 style(descendappendrange): formatting header from exercise title 2 years ago
Tiago Collot cf5befdec6 style(descendappendrange): formatting and missing bacticks 2 years ago
Tiago Collot 8bd3f6c935 feat(piscine-go): Add README.md for new go exercise descendappendrange 2 years ago
Tiago Collot 194ccbb8fe fix(podiumposition): change 'go' to 'console' 2 years ago
Tiago Collot b2499e54a5 style(podiumposition): format text 2 years ago
Tiago Collot fd4bedd973 style(podiumposition): add second # to the title 2 years ago
Tiago Collot cc7fbdf495 fix(podiumposition): miss import piscine 2 years ago
Tiago Collot e2629667d5 style(podiumposition): formatting header from exercise title 2 years ago
Tiago Collot 7e65c830e3 style(podiumposition): formmating 2 years ago
Tiago Collot 4bf53c9baf feat(piscine-go): add README.md for new go exercise podiumposition 2 years ago
Tiago Collot 79dbc1738a docs(descendcomb): delete folder/file in wrong branch 2 years ago
Tiago Collot c2d0c4f0c1 style(descendcomb): add second # to the title 2 years ago
Tiago Collot abdf7a39a1 style(descendcomb): remove two dots 2 years ago
Tiago Collot c111c07e3c style(descendcomb): remove two dots 2 years ago
Tiago Collot e8af487cc6 style(descendcomb): formatting header from exercise title 2 years ago
Tiago Collot 15004789f6 feat(piscine-go): add README.md for new go exercise descendcomb 2 years ago
nprimo b4fa7403d3 docs(ascii-art-optionals): clarify subjects 2 years ago
Michele Sessa 361430938f docs(road-intersection): fix typo 2 years ago
Michele Sessa 6f65a96a2e docs(net-cat): make bonus title visible in the subject 2 years ago
Michele Sessa 99b9025e19 docs(borrow_bow): clarify functions expected behavior 2 years ago
Michele Sessa 43c2a6dedc docs(diamond_creation): improve code example clarity 2 years ago
Michele Sessa 47001cd118 feat(shopping_mall): remove not neutral function 2 years ago
Michele Sessa 2e2f1eab45 docs(does_it_fit): introduce functions arguments more explicitly 2 years ago
Michele Sessa 9fff5aa95f docs(box_recursion): add derive debug for necessary structures 2 years ago
Michele Sessa 0c9296dbcf docs(box_recursion): change functions and arguments names 2 years ago
Maxim Mihajlov 61c1fd1ac1 docs(ascii-art-output): audit quote fix 2 years ago
Maxim Mihajlov 1ba87d145a docs(ascii-art-fs): audit quote fix 2 years ago
miguel 074f4c25ac fix(filler): placing the bonus questions inside a bonus part 2 years ago
Michele Sessa ba521bbfb0 fix(card-deck): fix prototype of winner_card 2 years ago
nprimo 68a7268733 docs(crossword): add suggestion for bonus in audit 2 years ago
nprimo 689fd07a48 docs(crossword): fix grammar in audit 2 years ago
nprimo 6e2c985149 docs(crossword): fix grammar and add details to subject 2 years ago
nprimo 8d2d144070 docs(crossword): update subject and audit 2 years ago
nprimo d976bd6796 docs(crossword): Add audit 2 years ago
nprimo 286a81b3c6 docs(crossword): Add subject for new piscine-js raid 1 2 years ago
miguel ba63d23d05 fix(ztail): adding console in usage to solve a bug when the platform tries to display the readme 2 years ago
zoevig 9120b07fb0
Delete setup_of_external_repo.md 2 years ago
davhojt 7643f31e6b docs(ascii-art-color): convert final question to bonus 2 years ago
Michele Sessa 28bccd6e59 1460-DEV-3511 feat(iterators): improve consistency and clarity 2 years ago
Michele Sessa cd2b00b135 refactor(borrow_box): better args names for new() 2 years ago
Michele Sessa f01fd7ed5e fix: remove incrementing nbr_of_games 2 years ago
davhojt 9934ff22b8 docs(ascii-art-justify): fix typo 2 years ago
nprimo 6a74ef19df docs(ascii-art-justify): add escape char for question mark 2 years ago
nprimo f49d01e325 docs(ascii-art-justify): remove double quotes 2 years ago
davhojt d6c61dc527 docs(ascii-art-color): improve readability 2 years ago
davhojt ac86faff7d fix(ascii-art-color): remove question syntax from last example 2 years ago
eslopfer 26b1e904d2 docs(piscine-rust): Remove extra directive 2 years ago
eslopfer c0d5dfda49 chore(piscine-rust): Prettier 2 years ago
eslopfer 751bdf7ba4 docs(piscine-rust): Fix expected functions and usage to make it accurate 2 years ago
eslopfer de30084743 docs(piscine-rust) Add missing "s" 2 years ago
zoevig cd5258398a
Delete pc-requirements.md 2 years ago
zoevig 585fdcefbd
Delete server-installation.md 2 years ago
zoevig 1d27d04bd4
Delete server-requirements.md 2 years ago
zoevig 6d92bd0223
Delete ubuntu-installation.md 2 years ago
zoevig 1c2bdf399b
Delete ubuntu-persistent-installation.md 2 years ago
eslopfer e133e63658 docs: correct usage example to print new line 2 years ago
eslopfer e236f59390 docs: correct example to add new line 2 years ago
eslopfer 33c0a1c1dd docs: correct usage example to print new line 2 years ago
eslopfer 8566d590e2 docs: correct example to add new line 2 years ago
eslopfer 0a329ec69b docs: correct innacurate instructions, it prints a new line instead of nothing 2 years ago
davhojt 2dac643de9 docs(alter-ego): fix typo 2 years ago
nprimo fb0b19c3b5 docs(asci-art-justify): update text for coherence with audit 2 years ago
nprimo 9afdda465c docs(ascii-art-justify): update subject to keep consistency between subject and audit 2 years ago
Michele Sessa 850821bd2b DEV-3473 docs(commits_stats): correct a typo 2 years ago
Michele Sessa c977023596 fix(commits_stats): add the expected attachment file 2 years ago
Michele Sessa 88d3857a61 1448 fix(sales): remove inconsistency in expected output 2 years ago
Michele Sessa 3a5196a8a6 DEV-3503 docs(sales): fix two typos 2 years ago
nprimo 8f6fec1675 docs(iterators): update notion link to english source 2 years ago
miguel 6539b5ee88 docs(filler): filler subject and audit 2 years ago
Christopher Fremond 78e4da15db
Update preseed.cfg 2 years ago
Michele Sessa 519604891e docs(unwrap-or-expect): add cargo run for console output 2 years ago
mikysett dcea19a5d7 docs(unwrap_or_expect): rewrite the subject 2 years ago
Michele Sessa 0b3538bcca docs(box_it): clarify the subject 2 years ago
Michele Sessa dca05bee11 docs(traits): clarify fat_content meaning 2 years ago
Michele Sessa 0eaaa00196 docs(matrix_ops): remove typo 2 years ago
miguel 412d887403 docs(go-reloaded):removing the newlines that were there for clarification but it's creating confusion 2 years ago
miguel 6cfb5518b3 docs():fix typo and adding a missing new line in the usage 2 years ago
davhojt 2d9309a87f docs(multiplayer-fps): fix typo 2 years ago
davhojt 13d8066e11 docs(multiplayer-fps): rename project 2 years ago
eslopfer f9067b837f Docs: specify what is considered a vowel in this exercise 2 years ago
davhojt c91da2f110 docs(easy_trait): fix typo 2 years ago
Michele Sessa 79fa31ce91 1413-shopping_mall-subject fix: functions names 2 years ago
davhojt a542c738da docs(ascii-art): escape exclamation marks 2 years ago
Tiago Collot 4a9b929176 fix(go-reloaded audit): change part of header 6 to code block to render correctly 2 years ago
Tiago Collot 65f302e578 style: formatting 2 years ago
Tiago Collot 0797dd68db style(pisicine-go): fix white-space and formatting 2 years ago
Tiago Collot 606cb972c3 feat: add new README.md for loafofbread exercise 2 years ago
nprimo b624bf8290 docs(letter-space-number): Add examples 2 years ago
nprimo daa52c1fd8 docs(cut-corners): Clarify subject 2 years ago
nprimo 2f4900d8d2 test(primitives): Add new tests to check if variables are constant 2 years ago
nprimo ec55a11e80 test(declarations): Add new tests to check if variables are constat 2 years ago
nprimo e52e60a612 docs(pick-and-click): Add details to clarify the subjects 2 years ago
nprimo 7f220e4b03 docs(is): Add examples 2 years ago
eslopfer 26503936d4 docs(where-do-we-go): Fix format of bullet points depending if they are after a ":" 2 years ago
eslopfer affd3c6c82 docs(keycodes-symphony): Remove the "s" from displays 2 years ago
eslopfer 7af4701427 docs(pimp-my-style-dom): Fix wrong closing tags in examples 2 years ago
eslopfer bb91a6ce17 docs(pimp-my-style): Fix wrong closing tags in examples 2 years ago
eslopfer e92b0d5369 docs(flow): Add missing word to the description 2 years ago
eslopfer 37b2b29f22 docs(using-map): Fix broken markdown 2 years ago
eslopfer 7db94af256 docs(greedy-url): Fix broken markdown 2 years ago
eslopfer 383fb91a63 docs(interpolation): Remove semicolon 2 years ago
eslopfer 9a6a883829 docs(build-brick-and-break): Replace "E" with "W" 2 years ago
eslopfer 949c2cbd5e docs(pick-and-click): Add missing "be" word 2 years ago
eslopfer 4b3b53ad11 docs(curry-entries): Fix typo, add missing "m" 2 years ago
Tiago Collot c9ee2ca990 style(piscine-go): fix white-space 2 years ago
Tiago Collot 6eeff20876 feat: add README.md of new go exercise jumpover 2 years ago
zoevig 615c418bc6
Delete README_ru.md 2 years ago
zoevig 59af6a3a59
Delete README.md 2 years ago
zoevig 439cb401de
Delete addition_of_exercise_draft.md 2 years ago
zoevig dd3d57b8e4
Delete reviews.md 2 years ago
zoevig 6f4f3b96b3
Delete modular-steps-management.md 2 years ago
zoevig f55508f76d
Delete metrics.md 2 years ago
zoevig c6d8047775
Delete event-management.md 2 years ago
zoevig bb2473a509
Delete grand-prix-go-curriculum.md 2 years ago
zoevig ef28463f0d
Delete objects.md 2 years ago
zoevig 9ba9326a66
Delete object-edit.md 2 years ago
zoevig c3e8f2975e
Delete object-creation.md 2 years ago
zoevig 18c21520af
Delete object-child-creation.md 2 years ago
zoevig 02a2cd7ffc
Delete object-attribute-system.md 2 years ago
zoevig a42d27570a
Delete unreal-engine-setup.md 2 years ago
zoevig 4faf75699b
Delete piscine-go-curriculum.md 2 years ago
zoevig 45780f9aee
Delete piscine-rust-curriculum.md 2 years ago
miguel f2f2d2e06c test(to-git-or-not-to-git):Adding the exit status to the test 2 years ago
miguel e97279e9df Docs(changing the note to a warning) 2 years ago
miguel fb268fa9ca Docs(change a sentence for better clarification) 2 years ago
miguel b30b47227e Fix(removing unnecessary code) 2 years ago
miguel 072f1b6b3c Fix(removing echos from the solution) 2 years ago
MSilva95 e9995f5f87 remove changes i did in printstr 2 years ago
miguel a140e10bd7 Fix (to-git-or-not-to-git test, empty solutions) 2 years ago
Michele a1ebd06180
Merge pull request #1396 from 01-edu/DEV-3170-looping-useless-complexity 2 years ago
mikysett 020b1b50a9 docs(looping): Removing one edge case 2 years ago
Andres Sulg abda457eda Update README.md 2 years ago
Michele 5b870400ba
Merge pull request #1372 from 01-edu/DEV-3155-inconsistent-style-in-examples 2 years ago
Harry a25112fabb fix(script): update debian configuration script 2 years ago
Harry 0dced086f3 fix(script): update debian configuration script 2 years ago
Christopher Fremond 92294a7f4d
Update bring-it-to-life-dom_test.mjs 2 years ago
MSilva95 77c58b0ee1 adding a space. 2 years ago
Hamza elkhatri 6572a3d247 docs(reverseString):replace comma with point and capitalaze the first letter 2 years ago
hamza fd4ab85798 add subject 2 years ago
MSilva95 33b0883b42 highlight 2 years ago
zainabdnaya 2bede0ba82 corrected 2 years ago
Hamza elkhatri 12a28bb3c2 Update README.md 2 years ago
zainabdnaya 22a98fb3c1 numofdegit 2 years ago
zainabdnaya 5c9af6e07b numofdegit 2 years ago
zainabdnaya 1a3f9ae1fb Correcting number of digits 2 years ago
zainabdnaya 2b073bc319 Correcting number of digits 2 years ago
zainabdnaya b2ddd18a79 Correcting number of digita 2 years ago
zainabdnaya 81a5c8bdee feat Add numofdigits subject 2 years ago
zainabdnaya 0a78c83149 corrected 2 years ago
zainabdnaya 891a4fc8ad Corrected 2 years ago
zainabdnaya 733dda0c22 count starst correction 2 years ago
zainabdnaya 40ca316ba0 👌 IMPROVE 2 years ago
zainabdnaya 806176c71b Corecting CountStar Subject 2 years ago
zainabdnaya f4b184fd3b Corecting CountStar Subject 2 years ago
zainabdnaya fb3636dff2 CountStars subject 2 years ago
zainabdnaya f7ff499198 CountStars subject 2 years ago
MSilva95 4fe6da41eb add quotation mark 2 years ago
zainabdnaya 24540b242b corrected 2 years ago
zainabdnaya a0fa67d699 correctedd 2 years ago
zainabdnaya 99f3cb92ed Corrected 2 years ago
zainabdnaya fa657e75a0 corrected 2 years ago
zainabdnaya 822ffb2746 corrected 2 years ago
zainabdnaya 2ce0f93133 corrected 2 years ago
zainabdnaya e12c0a9c5f Correct Same Case 2 years ago
zainabdnaya 3d66c9f78f subject correction 2 years ago
zainabdnaya a3350ff8d4 feat : add samecase sunject 2 years ago
zainabdnaya e8f3b57009 Merge branch 'vowels-index' 2 years ago
MSilva95 4ff540dcdd small typo 2 years ago
zainabdnaya 54585ff591 corrected 2 years ago
zainabdnaya 7446208834 corrected 2 years ago
zainabdnaya 23117c2764 Correction 2 years ago
zainabdnaya b20ea0e7fa add test 2 years ago
zainabdnaya dc76a3aa38 feat: subject strisnegative 2 years ago
MSilva95 4901cfa9bc highlight 2 years ago
MSilva95 d3e7be78d1 remove repetitions 2 years ago
zainabdnaya e0dfa67526 corrected 2 years ago
zainabdnaya f32d1a5091 corrected 2 years ago
zainabdnaya 4e86e826c5 corrected 2 years ago
zainabdnaya eb6a195100 correct format 2 years ago
zainabdnaya 8cc2239037 buzzinga 2 years ago
zainabdnaya 08a24c947f feat: correct the BuzZinga subject 2 years ago
zainabdnaya 53d1fdbddf freat: new Function (buzzinga) 2 years ago
zainabdnaya 2a2f77d8de freat: new Function (buzzinga) 2 years ago
Michele Sessa 067b3d6f42 docs(copy, tic_tac_toe): Improve code example and console output 2 years ago
hamza f9654289c6 Subject(remove-odd):add readmed 2 years ago
zainab Dnaya 6d2a7bb7f2 Update README.md 2 years ago
zainab Dnaya 2307966747 Update README.md 2 years ago
zainab Dnaya bc85ef828d Update README.md 2 years ago
zainab Dnaya c99147f091 Update README.md 2 years ago
zainabdnaya 7713f3bd2b corrected 2 years ago
zainabdnaya 3192df2360 corrected 2 years ago
zainabdnaya 8679377f37 corrected 2 years ago
zainabdnaya 4f34cffaf9 corrected 2 years ago
zainabdnaya d8a72d0e05 corrected 2 years ago
zainabdnaya 96436abe98 corrected 2 years ago
zainabdnaya 4264d33019 subject 2 years ago
zainabdnaya 607270bb38 add test 2 years ago
zainabdnaya e779196218 add test 2 years ago
zainabdnaya c9b0d66ebf add test 2 years ago
zainabdnaya eac91965a8 add test 2 years ago
zainabdnaya 267b10d31d subject 2 years ago
zainabdnaya 9bd0487d9e add test 2 years ago
zainabdnaya f02ddea763 Unzipstring function 2 years ago
zainabdnaya 245c0f0785 Unzipstring function 2 years ago
Hamza elkhatri 2f765363af add condition 2 years ago
hamza 1395d56768 fix:typo 2 years ago
hamza 8ff8f1b311 fix:rename the folder 2 years ago
Hamza elkhatri 1e5c576514 Update README.md 2 years ago
Hamza elkhatri 13f6181c6c Update README.md 2 years ago
Hamza elkhatri fe0dfb38eb Update README.md 2 years ago
Hamza elkhatri ae49b05728 Update README.md 2 years ago
hamza 7986c7b800 fix(subject):rename the subject 2 years ago
hamza f5161c6f3b subject(skip-the-line):add readme 2 years ago
Hamza elkhatri 21a3749dcc Update README.md 2 years ago
Hamza elkhatri f81cc27798 Update README.md 2 years ago
Hamza elkhatri 3c5fb469e0 change usage and rewrite subjects 2 years ago
Hamza elkhatri 40c2d65b0c Update README.md 2 years ago
Hamza elkhatri 594cef3d46 Update README.md 2 years ago
Hamza elkhatri f9383e2fc4 Update README.md 2 years ago
Hamza elkhatri 8f788a3830 Update README.md 2 years ago
Hamza elkhatri 4fc920469f Update README.md 2 years ago
hamza e46d48db59 subject(swapName):add readme 2 years ago
hamza 46f8f3ecc7 rename the dir 2 years ago
Hamza elkhatri 7050516707 Update README.md 2 years ago
Hamza elkhatri c5193e9d82 change name of function and name of subject 2 years ago
Hamza elkhatri b529e6ecf7 rewrite description 2 years ago
Hamza elkhatri 11b0dd1e55 Update README.md 2 years ago
Hamza elkhatri 3137eb63ef Update README.md 2 years ago
hamza 1aee0b2871 subject(is-the-square-a-child): add readmed 2 years ago
davhojt 91ac481d9f docs(fibonacci2): correct typo in usage heading 2 years ago
davhojt 9848384faa docs(scalar): fix typo 2 years ago
davhojt 31b4331600 docs(fibonacci2): correct typo 2 years ago
estlop 975ea7272b fix: Change FIFO to LIFO 2 years ago
Christopher Fremond 5cca789fd1
Update bring-it-to-life-dom_test.mjs 2 years ago
Christopher Fremond 88c3cc52a9
Update bring-it-to-life-dom_test.mjs 2 years ago
Christopher Fremond c726f13e09
Update bring-it-to-life-dom_test.mjs 2 years ago
MSilva95 6a3e1be365
Merge pull request #1344 from rcatini/patch-2 2 years ago
MSilva95 9ce366c5d4
Merge pull request #1343 from rcatini/patch-1 2 years ago
MSilva95 f82c13034d
fix name 2 years ago
MSilva95 182a0f0f92
Merge pull request #1342 from 01-edu/public-issues 2 years ago
rcatini a5e8ad8d10
Fix the example to match the expected output 2 years ago
rcatini 58c92312e9
Fix unused import 2 years ago
miguel 5bd0efff7f issues in public 2 years ago
Christopher Fremond 61e9bcda0f
Update bring-it-to-life-dom_test.mjs 2 years ago
eslopfer c2ba93a8b4 docs: Be more specific with text to be printed 2 years ago
estlop 14bff2fbb7 docs: Be more accurate with the description of what needs to be returned 2 years ago
estlop bbe0038638 docs: Correct description 2 years ago
Christopher Fremond 2d0a9a04c7
Update bring-it-to-life-dom_test.mjs 2 years ago
MSilva95 e164bf6767
Merge pull request #1321 from 01-edu/DEV-3120-issues-on-public 2 years ago
Christopher Fremond 5dbc369084
Update bring-it-to-life-dom_test.mjs 2 years ago
Christopher Fremond c8e0689e1a
Update bring-it-to-life-dom_test.mjs 2 years ago
Clément d3a3888d53
Remove unescessary test for JS files 2 years ago
Clément 722e7b670a
Add safety semicolon 2 years ago
estlop 3e50722419 docs: Be more specific with the instructions 2 years ago
estlop 2e97385c73 docs: Correct instructions about what to return 2 years ago
davhojt 266a3a941d docs(go quest 11): correct grammar of NodeI exercises 2 years ago
Clement Denis 4c65e9e273 fix(js): replace base64 url trick by temp file 2 years ago
zainabdnaya c0903b687f corrected 2 years ago
zainabdnaya 875846bbdf corrected 2 years ago
Hamza elkhatri 888d46713e Update README.md 2 years ago
zainabdnaya ea8573457b square roost 2 years ago
zainabdnaya f3a1b74bd9 squareroot 2 years ago
hamza 2cc3501e17 subject(square-root): add readmed 2 years ago
estlop c19bfb50ea docs: Correct when to display ping and pong 2 years ago
estlop 0bcc0ddfb7 Correct markdown highlighting 2 years ago
estlop 5a878eb40c docs: Reword instructions 2 years ago
estlop 2155f4b6fc docs: Add description of pingpong subject 2 years ago
estlop 7d9f6eb3e5 docs: Remove piscine imports as per review 2 years ago
estlop cf5f8e6c1e docs: fix wrong sintax in usage 2 years ago
estlop e1d2392997 Write readme for delete subject 2 years ago
estlop 5ab429e996 docs: Explain what to do when slice is empty or there are no even elements as per review 2 years ago
estlop aab618949e docs: fix wrong syntax on usage 2 years ago
estlop b974a12074 docs: Add readme file for evenlength subject 2 years ago
estlop 402b138983 docs: Rephrase instructions and remove import as per review 2 years ago
estlop 5ebf4a257a Rephrase to make clear the expected input to handle 2 years ago
estlop 2dc5d68381 fix: Fix typo 2 years ago
estlop 31ded86687 docs: Add readme for sum subject 2 years ago
estlop 2ae3ef00fd docs: Correct typo 2 years ago
estlop cf26a508d3 Add usage examples and be more specific with the instructions as reviewed 2 years ago
estlop f8b2b6aed0 docs: Add readme for subject concatenate 2 years ago
Hamza elkhatri 20b24a334a fix : delete `!` in usage part and rewrite the description 2 years ago
Hamza elkhatri 17e70838ea Update README.md 2 years ago
hamza 9f0ee07524 subject(swapargs):add readme 2 years ago
MSilva95 55529af70a small fix 2 years ago
Hamza elkhatri e39eaca456 remove `piscine` header and fix typo 2 years ago
Hamza elkhatri ae450bee6c rewrite description 2 years ago
Hamza elkhatri cd276d5ee5 Update README.md 2 years ago
Hamza elkhatri 4ae7091b8e Update README.md 2 years ago
Hamza elkhatri d0463615cb Update README.md 2 years ago
hamza cf0941bf95 add(subject):printrange 2 years ago
MSilva95 c9790ce688 small fix 2 years ago
estlop 7ed376c50c Remove piscine from imports as commented by Miguel 2 years ago
estlop bcc4be2d63 Specify what to do when the slice is empty 2 years ago
estlop a7e0232720 Add missing brackets 2 years ago
estlop a7c012310c docs: Add type to declaration in usage 2 years ago
estlop 5a4d2a6387 docs: Add spaces between elements of slice 2 years ago
estlop c496f96630 docs: Add readme for popint subject 2 years ago
Hamza elkhatri f1fc133bb3 add test case 2 years ago
Hamza elkhatri 5d18e844ab Update README.md 2 years ago
hamza 5ce527c2d4 add(subject):print-middle 2 years ago
Hamza elkhatri 6a53d215e6 Update README.md 2 years ago
hamza e5914c14bc add(subject): add rev-args subject 2 years ago
MSilva95 404c163609 fix extra space in the flag 2 years ago
estlop df8917a7d1 docs: Add example of usage as per review 2 years ago
estlop 34966f26d6 docs: add readme for printevenarguments subject 2 years ago
zainabdnaya 3a6168c881 corrected 2 years ago
estlop 042298332e docs: Explain what to do when slice is empty or there are no odd elements as per review 2 years ago
estlop 6468a3614b docs: Add description for oddlength 2 years ago
MSilva95 6574814741 add single arg 2 years ago
hamza 5c11b6e9ec subject(argrot1): add readme 2 years ago
miguel 12d57a2f64 Dav corrections 2 years ago
davidrobert99 b9fb4c6157 update borrow_box 2 years ago
davidrobert99 260ae8c7da update borrow_box 2 years ago
miguel 2e9a1d7998 correcting errors found by students 2 years ago
Clement Denis 8573f049f2 Create a copy of the dom tests to js image 2 years ago
Clement Denis 711dabdb12 create editor version of init/hello-there for the origin piscine 2 years ago
MSilva95 eb95584405 small fix 2 years ago
Hamza elkhatri 3bdf80b9c6 Update README.md 2 years ago
Hamza elkhatri 216b1a9efa rewrite description 2 years ago
hamza e0693e278a add(subject):getarea 2 years ago
davhojt 25400daa15 docs(ultimatedivmod): correct grammar 2 years ago
estlop 7e4af38af0 chore: Format with prettier 2 years ago
estlop 7c304d8b30 docs: Update audit file to include example with contiguous new line characters 2 years ago
estlop f740ba0a03 docs: Update description to include example with contiguous new line characters 2 years ago
estlop 3097cd47f3 docs: Add what to do when string is empty as per review 2 years ago
estlop f5679a6ca6 docs: Add readme for ascii subject 2 years ago
Dav Hojt fcc042a38e
Update README.md 2 years ago
davhojt c84959b8ba docs(manipulate-values): fix typo 2 years ago
Hamza elkhatri 5cbf005b3b Update README.md 2 years ago
Hamza elkhatri fbb90f82d2 Update README.md 2 years ago
hamza 66624b671d add(subject): print-ascii 2 years ago
Hamza elkhatri 69b19b2269 Update README.md 2 years ago
hamza 69245b40ba fix name of file 2 years ago
hamza 016714770e fix output 2 years ago
hamza 3266406fb2 subject(communmultiple):add readme 2 years ago
Hamza elkhatri 54c5214072 Update README.md 2 years ago
hamza 1d8cacc5c6 subject(Count-Negative):add readme 2 years ago
davhojt 9fd8117c3b docs(clonernews): correct audit grammar 2 years ago
davhojt 36a9dc25e2 docs(clonernews): correct subject grammar 2 years ago
davhojt 9e13f453a6 docs(race): correct grammar 2 years ago
davhojt 8e1024a6a3 docs(series): correct grammar 2 years ago
davhojt 0eb520dad0 docs(all): correct grammar 2 years ago
davhojt 44cfb248db docs(gougle-search): correct grammar 2 years ago
davhojt 5e8ef51a75 docs(is-winner): correct grammar 2 years ago
hamza f8a9d72f0a Subject(rot-arg-n):add README 2 years ago
Hamza elkhatri abbfbd4031 Update README.md 2 years ago
Hamza elkhatri ad23781b3b Update README.md 2 years ago
hamza 1fb9df9b5b add(subject):leap year 2 years ago
Hamza elkhatri 2e04c1e2ba Update README.md 2 years ago
Hamza elkhatri e8a3809405 Update README.md 2 years ago
Hamza elkhatri 6f590b8f6e Update README.md 2 years ago
Hamza elkhatri 2f7f49f495 Update README.md 2 years ago
hamza 6b4208a56e add usage 2 years ago
hamza 89394634fd subject(binaryaddition):add readmed 2 years ago
zainabdnaya 241dcf3b70 Devisors 2 years ago
zainabdnaya c7e4e42d0a devisors 2 years ago
zainabdnaya 310d16d23d feat:Add test cases 2 years ago
zainabdnaya 294315a72b feat : Add devisors subject 2 years ago
Hamza elkhatri fbb007535d Update README.md 2 years ago
Hamza elkhatri 745609bf47 Update README.md 2 years ago
Hamza elkhatri d6544fb2db Update README.md 2 years ago
hamza 9fc547d843 subject(param_range):add Readme 2 years ago
Hamza elkhatri 4ed04e41ec Update README.md 2 years ago
Hamza elkhatri c8f6198854 Update README.md 2 years ago
hamza ba97b8f27b subject(SumArray):add readme 2 years ago
Hamza elkhatri 084e1decc3 Update README.md 2 years ago
Hamza elkhatri 0344c096fd Update README.md 2 years ago
hamza bedf3d69ff subject(Add-if-positive):add readme 2 years ago
Hamza elkhatri 3130318a76 Update README.md 2 years ago
Hamza elkhatri d66915e3b0 Update README.md 2 years ago
Hamza elkhatri 1727ae0d86 Update README.md 2 years ago
hamza 270e1f370b add(subject): add subject betweenus 2 years ago
Hamza elkhatri 9fed0ac66a Update README.md 2 years ago
Hamza elkhatri d119045dc5 Update README.md 2 years ago
hamza 97464fd121 add(subject): alphaPostion 2 years ago
zoevig 2cc51d266a
Small typo correction 2 years ago
davidrobert99 3d7ff3c1d3 update ref_cell 2 years ago
davhojt bf06961810 docs(get-json): correct grammar 2 years ago
davhojt a55dccefd6 docs(keep-trying-or-giveup): correct grammar 2 years ago
davhojt 6327a1e6bb docs(interpolation): correct grammar 2 years ago
davhojt 1ec58a46e4 docs(throttle): correct grammar 2 years ago
davhojt d043c1544d docs(debounce): correct grammar 2 years ago
zainabdnaya c52e070e8f VowelsIndex 2 years ago
davhojt 3b53b3dfca docs(events): make small changes to @Zewasik #1225 2 years ago
Zewasik e7dde746f6 updated description to fit the task 2 years ago
Maxim Mihajlov 7a0e6fcdc0 Update README.md for roman_numbers_iter 2 years ago
zainabdnaya cd1dee9ab3 Correcting Vowels-Index subject 2 years ago
zainabdnaya 46b7df8c9e Correcting Vowels-Index subject 2 years ago
zainabdnaya 15f6559845 Correcting Vowels-Index subject 2 years ago
zainabdnaya a43fa3abd3 feat: add soubject of VowelsIndex.go 2 years ago
zainabdnaya 4717e47416 feat: add soubject of vowelsindex.go 2 years ago
zainabdnaya cd65a41d33 feat: add solution of vowelsindex.go 2 years ago
zainabdnaya 7b677f1ab8 feat: add vowels-index 2 years ago
zainabdnaya 10d16dad52 feat: add vowels-index 2 years ago
zainabdnaya d209193a50 feat: add vowels-index 2 years ago
zainabdnaya 4df40dfcf0 feat: add vowels-index 2 years ago
Hamza elkhatri ef8a775e68
Delete README.md 2 years ago
zainab Dnaya 17fc8ccb9b
Update README.md 2 years ago
zainabdnaya 82b6dd1443 feat: add vowels-index 2 years ago
zainabdnaya fef4b725e3 freat: new Function (buzzinga) 2 years ago
zainabdnaya 8467b73de6 freat: new Function (buzzinga) 2 years ago
  1. 57
      .github/ISSUE_TEMPLATE/bug_report.md
  2. 21
      .github/ISSUE_TEMPLATE/feature_request.md
  3. 46
      .github/workflows/docker-images.yml
  4. 2
      README.md
  5. 278
      docs/addition_of_exercise_draft.md
  6. 92
      docs/audits-at-home/README.md
  7. 83
      docs/audits-at-home/README_ru.md
  8. 190
      docs/event-management.md
  9. 330
      docs/grand-prix-go-curriculum.md
  10. 65
      docs/metrics.md
  11. 244
      docs/modular-steps-management.md
  12. 165
      docs/object-attribute-system.md
  13. 40
      docs/object-child-creation.md
  14. 58
      docs/object-creation.md
  15. 34
      docs/object-edit.md
  16. 29
      docs/objects.md
  17. 28
      docs/pc-requirements.md
  18. 330
      docs/piscine-go-curriculum.md
  19. 150
      docs/piscine-rust-curriculum.md
  20. 2
      docs/reviews.md
  21. 62
      docs/server-installation.md
  22. 25
      docs/server-requirements.md
  23. 140
      docs/setup_of_external_repo.md
  24. 67
      docs/ubuntu-installation.md
  25. 61
      docs/ubuntu-persistent-installation.md
  26. 39
      docs/unreal-engine-setup.md
  27. 19
      js/tests/Dockerfile
  28. 45
      js/tests/action-reaction-dom_test.mjs
  29. 18
      js/tests/bloody-sunday_test.js
  30. 31
      js/tests/bring-it-to-life-dom_test.mjs
  31. 109
      js/tests/build-brick-and-break-dom_test.mjs
  32. 36
      js/tests/class-that-dom_test.mjs
  33. 12
      js/tests/declarations_test.js
  34. 71
      js/tests/fifty-shades-of-cold-dom_test.mjs
  35. 46
      js/tests/first-words-dom_test.mjs
  36. 135
      js/tests/friend-support_test.mjs
  37. 147
      js/tests/gatecrashers_test.mjs
  38. 127
      js/tests/get-them-all-dom_test.mjs
  39. 123
      js/tests/gossip-grid-dom_test.mjs
  40. 67
      js/tests/harder-bigger-bolder-stronger-dom_test.mjs
  41. 18
      js/tests/hello-there-editor.json
  42. 23
      js/tests/hello-there_test.js
  43. 56
      js/tests/keycodes-symphony-dom_test.mjs
  44. 122
      js/tests/mouse-trap-dom_test.mjs
  45. 90
      js/tests/nesting-organs-dom_test.mjs
  46. 110
      js/tests/pick-and-click-dom_test.mjs
  47. 36
      js/tests/pimp-my-style-dom_test.mjs
  48. 13
      js/tests/primitives_test.js
  49. 1
      js/tests/race_test.js
  50. 49
      js/tests/select-and-style-dom_test.mjs
  51. 25
      js/tests/skeleton-dom_test.mjs
  52. 18
      js/tests/sunny-sunday_test.js
  53. 164
      js/tests/test.mjs
  54. 19
      js/tests/the-calling-dom_test.mjs
  55. 197
      js/tests/uninvited_test.mjs
  56. 4
      js/tests/verydisco-forever_test.mjs
  57. 37
      js/tests/veterinary_test.js
  58. 174
      js/tests/where-do-we-go-dom_test.mjs
  59. 373
      sh/debian/configure.sh
  60. 2
      sh/debian/preseed.cfg
  61. 2
      sh/tests/Dockerfile
  62. 99
      sh/tests/append-output_test.sh
  63. 30
      sh/tests/array-selector_test.sh
  64. 54
      sh/tests/auto-exec-bin_test.sh
  65. 20
      sh/tests/auto-jobs_test.sh
  66. 34
      sh/tests/bin-status_test.sh
  67. 28
      sh/tests/burial_test.sh
  68. 86
      sh/tests/calculator_test.sh
  69. 16
      sh/tests/change-struct_test.sh
  70. 28
      sh/tests/check-user_test.sh
  71. 27
      sh/tests/comparator_test.sh
  72. 18
      sh/tests/count-files_test.sh
  73. 11
      sh/tests/custom-ls/folder1/.hidden
  74. 1
      sh/tests/custom-ls/folder1/asd
  75. 199
      sh/tests/custom-ls/folder1/hello
  76. 1
      sh/tests/custom-ls/folder1/ls-test
  77. 42
      sh/tests/custom-ls_test.sh
  78. 18
      sh/tests/details_test.sh
  79. 44
      sh/tests/dir-info_test.sh
  80. 37
      sh/tests/division_test.sh
  81. 15
      sh/tests/easy-conditions_test.sh
  82. 12
      sh/tests/easy-perm/example.txt
  83. 16
      sh/tests/easy-perm/example2.txt
  84. 17
      sh/tests/easy-perm_test.sh
  85. 28
      sh/tests/env-format_test.sh
  86. 38
      sh/tests/file-checker_test.sh
  87. 17
      sh/tests/file-details_test.sh
  88. 127
      sh/tests/file-researcher/facts.txt
  89. 28
      sh/tests/file-researcher_test.sh
  90. 16
      sh/tests/file-struct_test.sh
  91. 0
      sh/tests/find-files-extension/folder1/file1.txt
  92. 0
      sh/tests/find-files-extension/folder1/file2.txt
  93. 0
      sh/tests/find-files-extension/folder1/file3.txt
  94. 0
      sh/tests/find-files-extension/folder1/test4.sh
  95. 0
      sh/tests/find-files-extension/folder2/fileInsideAfolder4.txt
  96. 0
      sh/tests/find-files-extension/folder2/test.sh
  97. 0
      sh/tests/find-files-extension/folder2/testtxt/fileInsideAfolder5.txt
  98. 0
      sh/tests/find-files-extension/folder2/testtxt/test/fileInsideAfolder6.txt
  99. 0
      sh/tests/find-files-extension/folder2/testtxt/test/lol.sh
  100. 35
      sh/tests/find-files-extension_test.sh
  101. Some files were not shown because too many files changed in this diff diff.show_more

57
.github/ISSUE_TEMPLATE/bug_report.md

@ -1,32 +1,53 @@
### Environment
---
name: 🐛 Bug report
about: Create a report to help us improve
title: "[BUG] "
labels: "🐛 bug"
assignees: ""
---
Device (web, mobile):
**Describe the bug**
A clear and concise description of what the bug/error is.
Operating system (Windows, macOS, Linux):
**Users**
Usernames of students/admin that are affected by the issue:
Browser (Chrome, Firefox, Safari, Brave):
**Severity**
Choose the severity label (❗minor), (‼ major), or (⚠ critical).
### Steps to reproduce the issue = what action results in the issue
**Type**
Choose the label (🖌 ui), (⚙ functionality), (🗂 documentation), or (🔐 security)
URL of the page:
**To Reproduce**
Steps to reproduce the behavior:
Steps to follow:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
1.
2.
**Workarounds**
Any known workarounds for the issue:
Usernames of students that are affected by the issue:
**Expected behavior**
A clear and concise description of what you expected to happen.
### Expected Result = How the software should have performed
**Attachments**
If applicable, add screenshots/videos/logs to help explain your problem.
<sub>Using tools like [Loom](https://chrome.google.com/webstore/detail/loom-for-chrome/liecbddmkiiihnedobmlmillhodjkdmb)</sub>
What was the expected outcome of the action taken in `step 3` ?
**Desktop (please complete the following information):**
### Actual Result = How the software actually performed
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
Actual outcome of the action taken in `step 3`
**Smartphone (please complete the following information):**
Error message that appears (if applicable)
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
### Visual Proof
Screenshots & Videos (using [Loom](https://chrome.google.com/webstore/detail/loom-for-chrome/liecbddmkiiihnedobmlmillhodjkdmb))
**Additional context**
Add any other context about the problem here.

21
.github/ISSUE_TEMPLATE/feature_request.md

@ -1,11 +1,28 @@
---
name: 🪄 Feature request
about: Suggest a feature or an enhancement for this project
title: "[FEATURE] "
labels: "🪄 feature"
assignees: ""
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Type**
Choose the label (🖌 ui), (⚙ functionality), (🗂 documentation), or (🔐 security)
**Expected benefit**
A clear and concise description of the expected benefit of the feature, including any relevant metrics or data to support its value:
**Target audience**
Who will benefit from this feature (e.g. users, developers, administrators):
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
**Additional context & attachments**
Add any other context, screenshots, or additional attachments, such as mockups or prototypes, to provide more context for the feature.

46
.github/workflows/docker-images.yml

@ -0,0 +1,46 @@
name: Docker Image CI
on:
push:
branches: ['master']
pull_request:
branches: ['master']
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to docker.01-edu.org Registry
uses: docker/login-action@v2.1.0
with:
registry: docker.01-edu.org
username: ${{ secrets.USER_DOCKER_01EDU_ORG }}
password: ${{ secrets.SECRET_DOCKER_01EDU_ORG }}
- name: Build the Sh Docker image
if: always()
run: |
docker build sh/tests/ --file sh/tests/Dockerfile --tag ghcr.io/01-edu/test-sh:latest
docker push ghcr.io/01-edu/test-sh:latest
- name: Build the JS Docker image
if: always()
run: |
docker build js/tests/ --file js/tests/Dockerfile --tag ghcr.io/01-edu/test-js:latest
docker push ghcr.io/01-edu/test-js:latest
- name: Build the DOM Docker image
if: always()
run: |
docker build . --file dom/Dockerfile --tag ghcr.io/01-edu/test-dom:latest
docker push ghcr.io/01-edu/test-dom:latest

2
README.md

@ -1,4 +1,4 @@
### Welcome to the Public Repository of 01 Edu System
### Welcome to the Public Repository of the 01 Edu System
Our courses are meticulously studied in order to provide you with quality projects.
Please take into account our approach before making **Issues**

278
docs/addition_of_exercise_draft.md

@ -1,278 +0,0 @@
# THE ADDITION OF EXERCISE PROCEDURE
**Needs to be updated since the refactor**
##### This is for a go exercise in the piscine-go
## **1. Writing the subject and / or writing the solution**
Always address each exceptional cases.
Example: [fprime](https://github.com/01-edu/public/blob/master/subjects/fprime.en.md).
The exceptional cases in the `usage` part.
```console
$ go run . 225225
3*3*5*5*7*11*13
$ go run . 8333325
3*3*5*5*7*11*13*37
...
$ go run . 0
$ go run . 1
1
$
```
The subject states that only **positive integer** will be tested, however, 0 and 1 are not primes.
The subject writer made a mistake because of forgetting that fact.
During the exam, the test was testing the `1` case and expecting a `1\n` to be printed. The real result should only have been a `\n`.
Some students found this mistake. An update of the subject during the exam treating that special case was immediately necessary.
1. Try to avoid the “you” and contracted “language”
2. Always check the formating md
---
### fprime <span style="color:#ff3234">(Title of the exercise)</span>
#### Instructions <span style="color:#ff3234">(Instructions of the exercise)</span>
Write a program that takes a positive `int` and displays its prime factors, followed by a newline (`'\n'`). <span style="color:#ff3234">(general guidelines, notice the imperative style tense and the avoidance of “you”. “You” is authorized in the case of a presence of a back story where the player is immersed)</span>
- Factors must be displayed in ascending order and separated by `*`. <span style="color:#ff3234">(formating requirement) </span>
- If the number of arguments is different from 1, the program displays a newline. <span style="color:#ff3234">(special case requirement, this case will need to be tested)</span>
- The input, when there is one, will always be valid. <span style="color:#ff3234">(Clarification on what the tester will do, hence giving the student guidelines on the cases to be handled, the tests have to reflect this instruction as well)</span>
- In this exercise the primes factor of 1 is considered as 1. <span style="color:#ff3234">(Handling of exceptional case: THIS Happens to be a mistake, we will see uses this example for the “UPDATING A SUBJECT/TEST PROCEDURE”)</sapn>
### Usage
```console
$ go run . 225225
3*3*5*5*7*11*13
$ go run . 8333325
3*3*5*5*7*11*13*37
$ go run . 9539
9539
$ go run . 804577
804577
$ go run . 42
2*3*7
$ go run . a
$ go run . 0
$ go run . 1
1
$
```
---
## **2. Creating the files for tests (4 main cases)**
### always in -> _all/tests/go/_
### **Folder organization**
- Function exercise in a Quest `(strlen)`
- 2 files:
- strlen_test.go
- solutions/strlen.goz
```console
go
| strlen_test.go
|
| __ solutions
| |-strlen.go (package solutions)
|
| __ student (the same thing as the solutions, just run "cp -aT solutions/ student/")
```
- Program exercise in a Quest `(doop)`
- 2 files
- doop_test.go
- solutions/doop/main.go
```console
go
| doop_test.go
|
|
| __ solutions
| |__doop
| |-main.go (package main)
|
| __ student (the same thing as the solutions, just run "cp -aT solutions/ student/")
```
- Program exercise in the exam `(dooprog)`
- 2 files
- solutions/doopprog/main.go
- solutions/doopprog/doopprog_test.go
```console
go
|
| __ solutions
| | __ doopprog
| |-main.go (package main)
| |-doopprog_test.go
|
| __ student (the same thing as the solutions, just run "cp -aT solutions/ student/")
```
- Function exercise in the exam `(atoiprog)`
- 3 files
- solutions/atoi.go
- solutions/atoiprog/main.go
- solutions/atoiprog/atoiprog_test.go
```console
go
|
| __ solutions
| |
| |-atoi.go (package solutions)
| |__atoiprog
| |-main.go (package main)(func main(){} stays empty)
| |-atoiprog_test.go
|
| __ student (the same thing as the solutions, just run "cp -aT solutions/ student/")
```
---
## **3. Writing a file_test.go (test file for go)**
### <span style="color:#00bae6">**RULE 1**</span>
- Make the test as independent as possible (no self-made functions imported)
- **If** the source is not in the import section, copy and paste the function, with **lowercase** for the first letter of its name.
- Example: addprimesum_test.go
![isaprime](isaprime.png)
The func isAPrime is fully copied to the file.
### <span style="color:#00bae6">**RULE 2**</span>
Every special case in the subject should be tested. Preferably first. Before the randoms tests
### <span style="color:#00bae6">**RULE 3**</span>
Whenever possible do at least 1 random test! This is to avoid cheating by predictability of the tests. If the tests are fixed, then the student may create a forest of ifs program to bypass the tester.
### z01.functions to be used by tester
- Function exercise in a Quest (strlen) ![z01sl](strlenz01.png)
```go
z01.Challenge(t, studentSol, studentStu) // if the program doesn’t have arguments
z01.Challenge(t, studentSol, studentStu, args...) //if the program has arguments
```
- Program exercise in a Quest (doop) ![z01doop](doopz01.png)<- Screenshots to be added.
```go
z01.ChallengeMain(t) // if the program doesn’t have arguments
z01.ChallengeMain(t, args...) // if the program has arguments
```
- Program exercise in the exam (dooprog) Screenshots to be added.
```go
z01.ChallengeMainExam(t) // if the program doesn’t have arguments
z01.ChallengeMainExam (t, args...) // if the program has arguments
```
- Function exercise in the exam (Atoiprog) Screenshots to be added.
```go
z01.Challenge(t, studentSol, studentStu) // if the program doesn’t have arguments
z01.Challenge(t, studentSol, studentStu, args...) //if the program has arguments
```
---
## **4. Testing locally (`go test` or `go test -run=Test\<nameOfTheFunction\>`)**
### you do -run=... because you have many test files, so you need to run just one
### Before every PR : a go test has to be executed (in several situations) in the folder(s) of the exercise(s) worked on
**First thing first**
```console
rm -r student
cp -aT solutions/ student
```
### Execute a go test in the appropriate folder
- Function exercise in a Quest `(strlen)` ![](image.png)
`all/test/go`
```console
go test -run=TestStrlen
```
- Program exercise in a Quest `(doop)` ![](image.png)<- Screenshots to be added.
`all/test/go/`
```console
go test -run=TestDoop
```
- Program exercise in the exam `(dooprog)` Screenshots to be added.
Here you can do just _go test_, because there's only one test file
`all/test/go/student/dooprog`
```console
go test
```
- Function exercise in the exam `(atoiprog)` Screenshots to be added.
`all/test/go/student/atoiprog`
```console
go test
```
### **NOTE:** If a go test gives a (cached) result, use this type of command (example with raid3):
`go test count=1 raid3_test.go`
The result should be an OK message:
- This means that the test is running correctly when the correct solution is given. If this does not work, the test file is likely to have errors inside.
- Time should be under 5-6 seconds. If longer, remove some of the iteration of the random tests (for example, less random tests)
- Be watchful of exercises with challenge function: Always test a copy of the variable and not the same variable for both the student and the solution function.
- Introduce errors in the student solution.go file in order to see the errors message and compare them to the subject examples.
- Error messages for structures exercises (linked lists, binary trees) need to be tailored accordingly.

92
docs/audits-at-home/README.md

@ -1,92 +0,0 @@
## How to do an audit from home
### Introduction
A little reminder first,
Audits, as we have told you many times, are an essential part of leveling up and truly acquiring your skills
and knowledge.
Normally, they must be done with your physical presence.
The idea is that they encourage the exchange between the auditors and the members of the group.
If the project fails, the whole group will learn why. And then after all your audits are done you will retry.
During all those extra audits, you, as a group, will discuss about your failures with the auditors.
If the project succeed, you will be an inspiration for the auditors.
In both of those cases you will learn or you will teach. The roles will keep reversing almost every time.
It is, ultimaly, those interactions that are essential for really learning;
To give and receive feedback, but also to see what you really know as an individual and what you do not.
This will increase your capacity to solve problems and your capacity to adapt, which is one of the most important
skill of a good programmer.
Today, once again, we must adapt...
Knowledge is important but not as essential as health.
We really wish all of you to stay safe and healthy at home.
This is why we created a little guideline in how to conduct your audit from home.
There is a video here : [youtube.com/watch?v=J8g8P-IJLJw](https://www.youtube.com/watch?v=J8g8P-IJLJw)
But we are also going to summarize the process.
So here we go.
### Prerequisites for the team captain and the auditor
- A program to communicate and livestream installed (like Discord [discordapp.com](https://discordapp.com/) )
- A program to allows the auditor to take charge of the computer
of the team captain installed (like teamViewer [teamviewer.com](https://www.teamviewer.com/) )
### Prerequisite for the team captain
The team captain must communicate :
- The contact of his or her teammates to the auditor
- The git repository of the project to be reviewed (the link must be public or accessible for the auditor)
- The team captain must be logged in in his or her session to allow the auditor to start its audit
### Prerequisite for the auditor
- The auditor will need to create the group on the communication program
- The auditor will need to download the project repository
- The auditor, if the internet bandwith allows it, will livestream the process
### Instructions
1. Let the auditor establish the communication with the group members and the captain.
2. Once all prequisites are done from the team captain and the auditor let the audit begin.
3. If possible, the auditor starts the stream.
4. The captain, after checking that the login is done on his or her computer, allows the auditor
to take control of its computer (with teamViewer for example)
5. The auditor now has the control to start the audit on the computer of the captain.
The organization of the windows by the auditor might be the tricky part. We suggest
to see how we did it in the video if you find it difficult.
6. The auditor conducts the audit, if the auditor can not live stream its audits, he or she
will then explain by voice (or writing in the chat) what he or she is doing to the rest of the group.
7. The audit is conducted until all questions are validated or until a mistake is made.
8. If a mistake is made the auditor can copy paste the commands that detected the mistakes.
9. The group discusses as much as needed until the audit is completed.
10. Once the audit is completed, all programs can be closed up. Say bye and thank you for your time and make the
necessary conclusions among the members of the group.
### Conclusion
Thank you for reading until the end. Stay safe.
### Bonus
Did you know that there is a nice `Live Share` extension on `vscode`?
This allows to do remote group programming easily. It might be an alternative solution
to the livestream if necessary.
Try it out!
Stay safe everyone! Happy coding!

83
docs/audits-at-home/README_ru.md

@ -1,83 +0,0 @@
## Как проводить аудиты удаленно
Сначала небольшое напоминание,
Аудиты, как мы неоднократно говорили, являются неотъемлемой частью вашего обучения и получения реальных навыков.
Обычно они должны проводиться оффлайн.
Идея состоит в том, что это способствует обмену знаний между аудиторами и членами группы.
Если проект провалится, вся группа будет знать точную причину. И после того, как все ваши проверки будут выполнены, вы попытаетесь сдать еще раз, с новообретенными знаниями.
Во время всех этих дополнительных проверок вы, как группа, будете обсуждать с аудиторами ваши недочеты.
Если проект будет успешным, вы будете вдохновлять аудиторов.
В любом случае вы будете либо учиться или либо учить кого-то. Роли учителя/ученика меняются почти каждый раз.
Это, в конечном счете, те взаимодействия, которые необходимы для реального обучения;
Давать и получать отзывы, а также видеть то, что ты действительно знаешь, а что нет.
Это улучшит вашу способность решать проблемы, вашу способность адаптироваться, что является одним из наиболее важных навыков хорошего программиста.
Сегодня мы снова должны адаптироваться ...
Иметь знания конечно хорошо, но здоровье важнее.
Мы действительно желаем всем вам оставаться дома в безопасности.
Поэтому мы разработали небольшое руководство по проведению аудита из дома.
Ссылка на видео: [youtube.com/watch?v=J8g8P-IJLJw](https://www.youtube.com/watch?v=J8g8P-IJLJw)
Также, можете прочесть:
### Необходимые вещи для коммуникации аудитора и капитана команды
- Программы для коммуникации и стрима (Discord подойдет)
- teamViewer или что-то похожее чтобы дать аудитору доступ к вашему компьютеру
### Что нужно сделать капитану:
- Собрать команду перед аудитом.
- Дать аудитору доступ к git, либо сделав репу публичной, либо сделав аудитора коллаборатором
- Залогиниться в платформе чтобы аудитор начал проверку
### Что нужно сделать аудитору:
- Договориться с командой на счет времени проверки
- Скачать репу проекта
- Стримить процесс проверки команде
### Инструкции
1. Аудитор договаривается на счет времени проверки с командой
2. Как только все будет готово, начинает проверку
3. Если возможно, аудитор запускает стрим, чтобы команда видела саму проверку.
4. Капитан, зайдя на платформу, разрешает аудитору взять под контроль свой компьютер (TeamViewer)
5. Теперь аудитор может запустить проверку на компьютере капитана.
Организация окон со стороны аудитора может быть сложной частью. Мы предлагаем
посмотреть видео, и узнать как мы это сделали.
6. Аудитор проводит проверку, если аудитор не может в прямом эфире транслировать свою проверку, он или она
затем объяснит голосом (или в чате), что он или она делает и как проверяет.
7. Аудит проводится до тех пор, пока все вопросы не верны или пока не будет допущена ошибка.
8. Если проект сломался на каком-либо тесте, аудитор может показать команде при каком тесте произошла ошибка.
9. Группа обсуждает потенциальное место ошибки столько, сколько необходимо, до завершения аудита.
10. После завершения аудита все программы могут быть закрыты. Скажите пока и спасибо за ваше время и сделайте
необходимые выводы среди членов группы.
### Conclusion
Спасибо, что дочитали до конца. Оставайтесь в безопасности.
### Bonus
Знаете ли вы, что есть хорошее расширение `Live Share` в` vscode`?
Это позволяет легко выполнять дистанционное групповое программирование. Это может быть альтернативным решением
для прямого эфира, если это необходимо.
Попробуйте!
Будьте в безопасности! Удачного кодинга!

190
docs/event-management.md

@ -1,190 +0,0 @@
# Events management
## Usage
An event is associated to an object when the usage of this object implies:
- a limited capacity of people
- a limited time
Event management require:
- Edition of the attributes of the object on which the event is based
- Creation and settings of the event associated to the reference object
> Events are used for: `piscines`, `check-in`, `exams`, `rushes`, `hackatons`, `conferences`.
## Settings for the reference object
Important indications:
- Objects that doesn't have required attributes for event creation will not be open to event creation.
| name | fullfillment |
| -------------------- | ------------ |
| capacity | **required** |
| eventDuration | **required** |
| registrationDuration | **required** |
| description | optionnal |
| eventStartDelay | optionnal |
- All the attributes filled in the object are used as values by default for event's creation; it can be overloaded for each event related to the reference object.
- If the reference object has a child or children which are events itself, settings are also required for each event child.
#### Edit the object attributes:
> in _Object attributes_
<img width="1073" alt="Capture d’écran 2019-08-22 à 11 40 34" src="img/63525316-64e0da80-c4f5-11e9-9e61-57d5a73da9b1.png">
- Add a new key **capacity** of type `Number` with the maximum number of persons you want for events related to the object by default
- Add a new key **eventDuration** of type `Number` with the duration in minutes you want for events related to the object by default
- Add a new key **registrationDuration** of type `Number` with the duration in minutes you want to allow to people to register to the event by default
- Add a new key **eventStartDelay** of type `Number`, if you want a default delay between the end of registration and the beginning of the event. This duration is expressed in minutes.
- Add a new key **description** of type `String`, if you need to associate some informations to your event (description, location, access, documents to provide, etc.)
#### Edit the children
> in _Children_
<img width="609" alt="Capture d’écran 2019-08-22 à 15 43 43" src="img/63525543-c86b0800-c4f5-11e9-8820-60d9ff33994f.png">
- Add a new key **startAfter** of type `Number`, with the default delay you want between the beginning of the event and the beginning of the child event. This duration is expressed in minutes.
##### Example
Here is an example of the `Piscine Go` settings. It presents the settings of the object attributes `Piscine Go`, the settings of one of its child which is an event and the settings of the child object attributes itself.
> NB : this object settings are provided in the admin, in the curses section: 'Piscine Go' and in the exams section 'Exam 01'.
**Piscine Go**
_Object attributes_
```json
{
"capacity": 400,
"eventDuration": 37440,
"registrationDuration": 43200,
"eventStartDelay": 240
}
```
This piscine object attributes look like this:
![piscine-object-attributes](img/piscine-object-attributes.png)
_Children_
> In the `Piscine Go`, children of type _exam_ and _rush_ have events itself.
> A **startAfter** key has to be defined for each of them, in their parent object `Piscine Go`. For example, the exam-01 gets this key:
```json
{
"startAfter": 8160
}
```
This child attributes look like this:
![piscine children attributes](img/63525543-c86b0800-c4f5-11e9-8820-60d9ff33994f.png)
**Exam 01**
> The object `Exam 01`, which is a child of `Piscine Go`, has its own _Object Attributes_ filled in the child object.
_Object attributes_
```json
{
"eventDuration": 240,
"registrationDuration": 2160,
"eventStartDelay": 60
}
```
> NB: the **capacity** attribute is herited from the parent object `Piscine Go` here.
This exam object attributes look like this:
![exam-object-attributes](img/exam-object-attributes.png)
## Create the event
### Create a new event for your object
> (in _Admin_ > _Manage events_ > _Add new event_)
<img width="788" alt="Capture d’écran 2019-08-22 à 11 37 13" src="img/63532891-9d87b080-c503-11e9-8ff2-46c7a5b19c12.png">
<img width="789" alt="Capture d’écran 2019-08-22 à 11 37 35" src="img/63533088-02430b00-c504-11e9-9675-bcab7bec825c.png">
<img width="787" alt="Capture d’écran 2019-08-22 à 11 38 07" src="img/63533145-21419d00-c504-11e9-8e80-fb4f53d93b00.png">
- The **reference object** of your event is the object for which you need to create an event: `Check`, `Piscine Go`, etc.
- The **registration starts at** indicates when registration of the event begins.
- The **registration ends at** indicates when registration of the event ends.
- The **event starts at** indicates when the event begins.
> NB:
>
> - End of registration can't be before its beginning.
> - Start of event can't be before end of registration.
> - Date and Time input is not yet working in firefox but should be added soon by mozilla. In the mean while use chrome for adding events
### Settings for you event
> In the event you have created, 3 categories must be checked:
>
> 1. General settings
> 2. Registration's settings
> 3. Event's settings
#### General settings
<img width="785" alt="Capture d’écran 2019-08-22 à 11 39 26" src="img/63533589-015ea900-c505-11e9-8b77-b45b620cd171.png">
General settings of your event can be set after creation of the event. By default, it is the values indicated in the **reference object**.
- **Capacity**
- During the regitration, the capacity doesn't apply. When registration ends, we register the amount defined by the **capacity** to the event _(ordered by registration date)_.
- If someone unregister to the event during a registration, it release one place.
- During a registration, users can see if their place is guaranteed or if they are in waiting list.
- If the event has children which are event themselves, they will use by default the capacity of the parent event
if no capacity was defined on this child.
- **Description** (facultative)
- It can be used to describe the topic of the event, or to add some practical informations: location, documents to provide, accessibility, etc.
#### Registration
<img width="761" alt="Capture d’écran 2019-08-22 à 11 39 37" src="img/63533613-0facc500-c505-11e9-90e8-94254cef5ce3.png">
- End of registration can't be after start of registration.
- Dates can't be updated after it's passed.
- The **registration duration** indicated in the **reference object** is reminded under the inputs to help you fill the informations.
- Same for the **event start delay**.
- The list of users in the registration, pending or accepeted, is accessible by clicking on the link 'N users registered', at the left bottom of this categrory.
#### Event
<img width="740" alt="Capture d’écran 2019-08-22 à 11 39 49" src="img/63533641-1d624a80-c505-11e9-9cd1-e1d156dd7fc4.png">
- End of event can't be after start of event.
- Dates can't be updated after it's passed.
- The **end of event** is calculated by default by adding the **event duration** indicated in the **reference object** to the **start of event** date.
- If the event contains other events, the **end of event** can't be before the end of the last child event.
- The **event duration** indicated in the **reference object** is reminded under the inputs to help you fill the informations.
- If the event contains other events, the **minimum end of event** is indicated under the inputs to help you fill the informations.
- The list of users selected for the event at its creation is accessible by clicking on the link 'N users registered', at the left bottom of this categrory.
#### Children (facultative)
<img width="1009" alt="Capture d’écran 2019-08-22 à 18 24 49" src="img/63535788-29044000-c50a-11e9-835c-f8378558962c.png">
This category appears only if the event has children which are events itself.
- Children settings can't be overloaded.
- Each event child presents:
- Its **Start** and **end** (according to the children settings of the **reference object**)
- Its **capacity**
- Its **groups size**
- Reminder: in `hackatons` or `rushes`, candidates or students registered to the are divided in groups of N persons.

330
docs/grand-prix-go-curriculum.md

@ -1,330 +0,0 @@
# Grand Prix Go curriculum
---
## Week One (Lundi 02/12/19 au DImanche 08/12/19)
### Sprint 1
#### Introduction to shell
Notions: basic usage and interaction with a command line terminal.
Videos:
- 1-2 `curl` with the GitHub api and Example of shell file | https://www.youtube.com/watch?v=A0Mqc215igw
- 1-3 `touch`, `chmod` and `echo` | https://www.youtube.com/watch?v=21h-vsuXgDU
- 1-4 `find` and `grep` | https://www.youtube.com/watch?v=7a1JSWHhJlM
- 1-5 `cut`, `sed` and `tr` | https://www.youtube.com/watch?v=Nil7rVP3eMI
- 1-6 `jq` and `wc` | https://www.youtube.com/watch?v=cQmcaOseuiA&
Exercices:
- introduction | https://public.01-edu.org/subjects/introduction.en
- make-it-better | https://public.01-edu.org/subjects/make-it-better.en
- to-git-or-not-to-git | https://public.01-edu.org/subjects/to-git-or-not-to-git.en
- who-are-you | https://public.01-edu.org/subjects/who-are-you.en
- cl-camp1 | https://public.01-edu.org/subjects/cl-camp1.en
- cl-camp2 | https://public.01-edu.org/subjects/cl-camp2.en
- cl-camp3 | https://public.01-edu.org/subjects/cl-camp3.en
- cl-camp4 | https://public.01-edu.org/subjects/cl-camp4.en
- cl-camp5 | https://public.01-edu.org/subjects/cl-camp5.en
- cl-camp6 | https://public.01-edu.org/subjects/cl-camp6.en
- cl-camp7 | https://public.01-edu.org/subjects/cl-camp7.en
- cl-camp8 | https://public.01-edu.org/subjects/cl-camp8.en
- now-get-to-work | https://public.01-edu.org/subjects/now-get-to-work.en
### Sprint 2
#### Introduction to Go Lang and basic programmation concepts
Notions: Variables declaration, Loops, if and else statement, usage of z01.PrintRune function.
Videos:
- 02-01-If and Else Statements in Go | https://www.youtube.com/watch?v=rnF1_SfeGE4
- 02-02-ForLoops | https://www.youtube.com/watch?v=Bt47lx6q2-4
- 02-03-PrintRune function | https://www.youtube.com/watch?v=o8JrvI3jqoM
- 02-04-Variables Declaration and ascii | https://www.youtube.com/watch?v=RCNOV8m0hJQ
Exercices:
- printalphabet | https://public.01-edu.org/subjects/printalphabet.en
- printreversealphabet | https://public.01-edu.org/subjects/printreversealphabet.en
- prindigits | https://public.01-edu.org/subjects/printdigits.en
- isnegative | https://public.01-edu.org/subjects/isnegative.en
- printcomb | https://public.01-edu.org/subjects/printcomb.en
- printcomb2 | https://public.01-edu.org/subjects/printcomb2.en
- printnbr | https://public.01-edu.org/subjects/printnbr.en
- printcombn | https://public.01-edu.org/subjects/printcombn.en
### Sprint 3
#### Introduction to Go Lang and basic programmation concepts II
Notions: String Manupulation, Range Loops, Pointers, Modulo and Division relative to computer science.
Videos:
- 03-01-StringsManipulation | https://www.youtube.com/watch?v=8LplJN_8iOU
- 03-02-RangeLoop | https://www.youtube.com/watch?v=i89N4cjh1-g
- 03-03-Pointers on variables | https://www.youtube.com/watch?v=owVPa5b1BMc
- 03-04-Modulo and Division | https://www.youtube.com/watch?v=NVan-9-Ioec
Exercices:
- pointone | https://public.01-edu.org/subjects/pointone.en
- ultimatepointone | https://public.01-edu.org/subjects/ultimatepointone.en
- divmod | https://public.01-edu.org/subjects/divmod.en
- ultimatedivmod | https://public.01-edu.org/subjects/ultimatedivmod.en
- printstr | https://public.01-edu.org/subjects/printstr.en
- strlen | https://public.01-edu.org/subjects/strlen.en
- swap | https://public.01-edu.org/subjects/swap.en
- strrev | https://public.01-edu.org/subjects/strrev.en
- basicatoi | https://public.01-edu.org/subjects/basicatoi.en
- basicatoi2 | https://public.01-edu.org/subjects/basicatoi2.en
- atoi | https://public.01-edu.org/subjects/atoi.en
- sortintegerable | https://public.01-edu.org/subjects/sortintegertable.en
### Checkpoint 1 (4hours)
#### Basic functions and programs skills evaluation, based on Sprint 2 and Sprint 3
### CLM (Contre La Montre) 1 - Rectangle Drawing
#### First Group project. Problem resolution. Usage of first knowledge (loop and if/else)
---
## Week Two (Lundi 09/12/2019 à Dimanche 15/12/2019)
### Sprint 4
#### Algorithm concepts
Notions: Iterative and recursive programmation
Videos:
- 04-01-Iterativity and Recursivity | https://www.youtube.com/watch?v=oCZDdAID5Ik
Exercices:
- iterativefactorial | https://public.01-edu.org/subjects/iterativefactorial.en
- recursivefactorial | https://public.01-edu.org/subjects/recursivefactorial.en
- iterativepower | https://public.01-edu.org/subjects/iterativepower.en
- recursivepower | https://public.01-edu.org/subjects/recursivepower.en
- fibonacci | https://public.01-edu.org/subjects/fibonacci.en
- sqrt | https://public.01-edu.org/subjects/sqrt.en
- isprime | https://public.01-edu.org/subjects/isprime.en
- findnextprime | https://public.01-edu.org/subjects/findnextprime.en
- eightqueens | https://public.01-edu.org/subjects/eightqueens.en
### Sprint 5
#### Application of previously viewed concepts.
Notions: String Manipulation and medium-advanced algorithms
Videos:
- 05-01-Runes, Bytes and Strings | https://www.youtube.com/watch?v=-eIU5ISID64
Exercices:
- firstrune | https://public.01-edu.org/subjects/firstrune.en
- nrune | https://public.01-edu.org/subjects/nrune.en
- lastrune | https://public.01-edu.org/subjects/lastrune.en
- index | https://public.01-edu.org/subjects/index.en
- compare | https://public.01-edu.org/subjects/compare.en
- toupper | https://public.01-edu.org/subjects/toupper.en
- tolower | https://public.01-edu.org/subjects/tolower.en
- capitalize | https://public.01-edu.org/subjects/capitalize.en
- isalpha | https://public.01-edu.org/subjects/isalpha.en
- isnumeric | https://public.01-edu.org/subjects/isnumeric.en
- islower | https://public.01-edu.org/subjects/islower.en
- isupper | https://public.01-edu.org/subjects/isupper.en
- isprintable | https://public.01-edu.org/subjects/isprintable.en
- concat | https://public.01-edu.org/subjects/concat.en
- basicjoin | https://public.01-edu.org/subjects/basicjoin.en
- join | https://public.01-edu.org/subjects/join.en
- printnbrbase | https://public.01-edu.org/subjects/printnbrbase.en
- atoibase | https://public.01-edu.org/subjects/atoibase.en
### Sprint 6
#### Usage of OS.Args
Notions: Arguments manipulation in programs
Videos:
- 06-01-Os.Args | https://www.youtube.com/watch?v=I1xt_TLRhF0
Exercices:
- printprogramname | https://public.01-edu.org/subjects/printprogramname.en
- printparams | https://public.01-edu.org/subjects/printparams.en
- revparams | https://public.01-edu.org/subjects/revparams.en
- sortparams | https://public.01-edu.org/subjects/sortparams.en
### Sprint 7
#### The Memory Allocation in GoLang
Notions: Usage of Make and Append
Videos:
- 07-01-Make and Append methods | https://www.youtube.com/watch?v=2HHVUM0YQuI
Exercices:
- appendrange | https://public.01-edu.org/subjects/apprendrange.en
- makerange | https://public.01-edu.org/subjects/makerange.en
- concatparams | https://public.01-edu.org/subjects/concatparams.en
- splitwhitespaces | https://public.01-edu.org/subjects/splitwhitespaces.en
- printwordstables | https://public.01-edu.org/subjects/printwordstables.en
- convertbase | https://public.01-edu.org/subjects/converbase.en
- split | https://public.01-edu.org/subjects/split.en
### Checkpoint 2 (4hours)
#### Basic functions and programs skills evaluation, based on Sprint 2 and Sprint 6
### CLM (Contre La Montre) 2 - Sudoku
#### Second Group project. Problem resolution. Usage of Memory manipulation tools
---
## Week Three + Holiday project (Lundi 16/12/2019 à dimache 05/01/2020 )
### Sprint 8
#### Introduction to Structures and advanced types in GoLang
Notions: Creation of struct types and file manipulation (Open, Read, Close methods)
Videos:
- 08-01-Structures in Go | https://www.youtube.com/watch?v=-24M7r7VuLY
- 08-02-File Manipulation in go | https://www.youtube.com/watch?v=8vUgchQGhcQ
Exercices:
- bool | https://public.01-edu.org/subjects/bool.en
- point | https://public.01-edu.org/subjects/point.en
- displayfile | https://public.01-edu.org/subjects/displayfile.en
- cat | https://public.01-edu.org/subjects/cat.en
- ztail | https://public.01-edu.org/subjects/ztail.en
### Sprint 9
#### Functions as argument
Notions: Advance function prototyping
Videos:
- 09-01-Functions as Arguments | https://www.youtube.com/watch?v=lw8jUwsluAE
Exercices:
- foreach | https://public.01-edu.org/subjects/foreach.en
- map | https://public.01-edu.org/subjects/map.en
- any | https://public.01-edu.org/subjects/any.en
- countif | https://public.01-edu.org/subjects/countif.en
- issorted | https://public.01-edu.org/subjects/issorted.en
- doop | https://public.01-edu.org/subjects/doop.en
- sortwordarr | https://public.01-edu.org/subjects/sortwordarr.en
- advancedsortwordarr | https://public.01-edu.org/subjects/advancedsortwordarr.en
### Sprint 10
#### Hackathon
Notions: All previously viewed concepts in team work
Exercices:
- rot14 | https://public.01-edu.org/subjects/rot14.en
- abort | https://public.01-edu.org/subjects/abort.en
- collatzcountdown | https://public.01-edu.org/subjects/collatzcountdown.en
- comcheck | https://public.01-edu.org/subjects/comcheck.en
- enigma | https://public.01-edu.org/subjects/enigma.en
- pilot | https://public.01-edu.org/subjects/pilot.en
- fixthemain | https://public.01-edu.org/subjects/fixthemain.en
- compact | https://public.01-edu.org/subjects/compact.en
- activebits | https://public.01-edu.org/subjects/activebits.en
- max | https://public.01-edu.org/subjects/max.en
- join | https://public.01-edu.org/subjects/join.en
- unmatch | https://public.01-edu.org/subjects/unmatch.en
### Checkpoint 3 (4hours)
#### Basic functions and programs skills evaluation, based on Sprint 2 and Sprint 8
### CLM (Contre La Montre) 3 - File Reader ( Projet pour les 2 semaines de vacances)
#### Second Group project. Problem resolution. File manipulation based on CLM (Contre La Montre) 1
---
## Week Four (lundi 06/01/2020 à vendredi 10/01/2020)
### Sprint 11
#### Linked lists in GoLang
Notions: Pointers manipulation and data structure
Videos:
- 11-01-Linked Lists Introduction | https://www.youtube.com/watch?v=EPICVEbylU0
Exercices:
- listpushback | https://public.01-edu.org/subjects/listpushback.en
- listpushfront | https://public.01-edu.org/subjects/listpushfront.en
- listsize | https://public.01-edu.org/subjects/listsize.en
- listlast | https://public.01-edu.org/subjects/listlast.en
- listclear | https://public.01-edu.org/subjects/listclear.en
- listat | https://public.01-edu.org/subjects/listat.en
- listreverse | https://public.01-edu.org/subjects/listreverse.en
- listforeach | https://public.01-edu.org/subjects/listforeach.en
- listforeachif | https://public.01-edu.org/subjects/listforeachif.en
- listfind | https://public.01-edu.org/subjects/listfind.en
- listremoveif | https://public.01-edu.org/subjects/listremoveif.en
- listmerge | https://public.01-edu.org/subjects/listmerge.en
- listsort | https://public.01-edu.org/subjects/listsort.en
- sortlistinsert | https://public.01-edu.org/subjects/sortlistinsert.en
- sortedlistmerge | https://public.01-edu.org/subjects/sortedlistmerge.en
### Sprint 12
#### Binary Trees
Notions: Advanced Data Structure using binary trees
Videos:
- 12-01-Introduction to Binary Trees | https://www.youtube.com/watch?v=3g2WCqWNIVs
Exercices:
- btreeinsertdata | https://public.01-edu.org/subjects/btreeinsertdata.en
- btreeapplyinorder | https://public.01-edu.org/subjects/btreeapplyinorder.en
- btreeapplypreorder | https://public.01-edu.org/subjects/btreeapplypreorder.en
- btreesearchitem | https://public.01-edu.org/subjects/btreesearchitem.en
- btreelevelcount | https://public.01-edu.org/subjects/btreelevelcount.en
- btreeisbinary | https://public.01-edu.org/subjects/btreeisbinary.en
- btreeapplylevel | https://public.01-edu.org/subjects/btreeapplylevel.en
- btreemax | https://public.01-edu.org/subjects/btreemax.en
- btreemin | https://public.01-edu.org/subjects/btreemin.en
- btreetransplant | https://public.01-edu.org/subjects/btreetransplant.en
- btreedeletenode | https://public.01-edu.org/subjects/btreedeletenode.en
### Checkpoint 4 - Final Checkpoint (8hours)
#### Functions and programs skills evaluation, based on Sprint 2 and Sprint 11

65
docs/metrics.md

@ -1,65 +0,0 @@
## Metrics card - Export of students' results
### Where to find the data
Metrics for students from a given campus can be found in the Metrics card in the Admin dashboard.
### Important information
- Data can be exported in csv and json formats
- Data is filtered by campus, exports include all historical data for that campus.
- We will later develop a feature that enables filtering information before downloading it
- Data is updated every hour
- The download link is valid for 24 hours
- We recommend sharing the downloaded document itself instead of the download link as the link contains the admin’s authorisation token
### Description of the data included in the exports
| Field | Example | Description |
| --------------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **user** | MarieMalarme | Student’s github username |
| **first_name** | Marie | Student’s first name |
| **last_name** | Malarme | Student’s last name |
| **object** | who-are-you | Name of the object for which a result is given |
| **type** | exercise | There are 3 object types: <br/> - exercise (for quests and exams) <br/> - raid <br/> - project |
| **parent** | Quest 01 | The object’s hierarchical parent: <br/> - If the object is an exercise, the parent will be either a quest or an exam. <br/> - If the object is a raid or a project, the parent will be the module (piscine or div) |
| **module** | piscine-go | The part of the curriculum in which the object is included, either a piscine (piscine Go, piscine JS, piscine Rust) or the main curriculum (Div01) |
| **path** | /madere/piscine-go/quest-01/who-are-you | The url to that object, which outlines the path and hence the hierarchical structure to that object |
| **attempts** | 2 | Number of submission attempts made by the student |
| **status** | succeeded | Current status of the student's work on the object: <br/> - "available" indicates that the student has started working on the object but either hasn't submitted it yet to be corrected, or is waiting for the auditing process to be completed <br/> - "succeeded" and "failed" are attributed once the object has been corrected |
| **xp** | 325 | Number of XPs gained by the student for succeeding |
| **base_xp** | 325 | Maximum number of XPs the student can get for succeeding for that object |
| **grade** | 1 | The student’s score for that object is a number between 0 (failed) and 1 (succeeded). If the object is a project, the grade can be superior to 1 when the student successfully passes bonus questions |
| **last_update** | 2020-07-27T15:39:46.368Z | Date and time of the student’s latest activity for that object |
### Explanation of the XP and Grade calculation
#### Exercises within quests
- _Test mode_: automatic tester
- _XPs_: fixed value. Students get all the points when succeeding at the exercise, no matter how many attempts they made.
- _Grade_: 0 (failure) or 1 (success)
#### Exercises within exams
- _Contextual information_:
- Exams consist of many exercises which are grouped by difficulty levels. The student is randomly assigned an exercise from each level and has to succeed in order to move on to the next exercise level.
- Each exercise level has a maximum amount of XPs which grows according to the level’s difficulty.
- Exams are limited in time so students have to successfully complete as many exams as they can as fast as they can with the least amount of errors.
- _Test mode_: automatic tester
- _XPs_: variable value. Students get the maximum amount of points when they succeed at the first attempt. Each failed submission reduces the amount of XPs the student can get for that level.
- _Grade_: 0 (failure) or 1 (success)
#### Raids
- _Test mode_: projects are evaluated by a jury panel in 2 steps:
- First the jury evaluates the code through an audit, a series of pass / fail questions to be answered by the auditor. Succeeding the audit gives students a certain amount of XPs.
- The jury then interviews students and can decide to give them bonus / malus XPs based on their evaluation of the code and the students’ answers to their questions.
- _XPs_: variable value calculated as a fixed value for succeeding the project plus / minus XPs attributed by the jury at their discretion
- _Grade_: 0 (failure) or 1 (success)
#### Projects
- _Test mode_: audits, which are peer-to-peer evaluations based on a series of pass/fail questions to be answered by the auditor
- _XPs_: variable value. Students can get more than the maximum value of XPs if they complete bonus exercises. They get no XPs at all if they fail at least one of the questions in the audit
- _Grade_: number between 0 and 1, proportionate to the number of questions successfully passed in the audit. The grade can be higher than 1 if the student completed bonus exercises.

244
docs/modular-steps-management.md

@ -1,244 +0,0 @@
# Sign up & onboarding's Administration section - Modular steps management
## Usage
After their first authentication in the app, every candidate has to do his **sign up** and his **onboarding**. The steps that compose the **sign up** and the **administration** section of the onboarding are either:
- Forms (identification, medical information, etc.)
- Documents to sign (general conditions, charts, regulations, etc.)
All the sections are modular: you can add, update, delete and order them as you wish.
This documentation explains how to manage these steps.
## Create your step child object
### Create a new object for your step in the admin
> Information is available for object's creation: [Object creation](object-creation.md)
- This object must have the same type as its future parent object (_signup_ or _onboarding_).
> Your step is then available in the _Admin_. You can find it in the section of its type (_SignUp_ or _Onboarding_) or thanks to the search bar of the cursus object's page.
### Add this new object as a child of your parent's object
- Edit the parent object: _Sign up_ or _Administration_
> Information is available for object's creation: [Child object creation](object-child-creation.md)
## Settings for a `form` step
In the step object you have created, 2 attributes must be filled:
1. Subtype
2. Form
### Description
#### Edit the step object you have created :
> in _Object attributes_
<img width="1073" alt="Capture d’écran 2019-04-22 à 15 59 33" src="img/56507445-3936ef00-6519-11e9-90c8-d85056e9330b.png">
- Add a new key **subtype** of type `String` with the exact value 'form-step'
- Add a new key **form** of type `Object`
- Form can have several sections. Each section is displayed with a title, and its inputs.
> NB: The submission of the form will check the required inputs of all the sections created for the form.
- To create a section, add a new key to the form object, of type `Object`, that contains:
- A **title** key of type `String`. The value of this property will be the title displayed in the top of the form section.
> If there is only one section in the form step, and no section title is needed, this property can be ignored.
- An **inputs** key of type `Object`, which will contain all the inputs of the section. For each wanted input, add a new `Object` element in the "inputs" object.
> The key of this object will be used as the "name" attribute of your input.
> The values will be considered as the properties of your input.
#### Defining an input:
- A **type** key of type `String` must be declared. It defines the type of the input : `tel`, `text`, `date`, `select`, `radio`, `switch`, `checkbox`, `textarea`, `countries`.
- All other attributes needed for the input can be added to the object, according to the input type: `placeholder`, `id`, `required`, `label`, `items`, `emptyItems`, `index`, etc...
#### Important indication:
- The **index** property is used to order the inputs. It will not be passed onto the input. Be mindful not to set the same index twice.
- The **type** property is required. It will be used to determine the kind of input should be generated. It is passed onto the input only if the input type attribute is required (type 'tel' or 'text' for example, but not for type 'select' - in this case, we will generate a select element)
- A special type 'countries' has been added to the classicals. It generate a `Select` (containing all the countries) with a search bar. 'Items' property is handled by the app.
- It's recommended to add 'min' and 'max' properties to input type 'date' (no default value are set).
- `onChange` prop are ignored as the event is handled by the app.
- For `switch` and `checkbox` input types, the default value has to be set as a boolean property named **value**.
- More information for each inputs is available in the design documentation:
- [textInput documentation](<https://((DOMAIN))/docs/Components/FormInputs/TextInput>) - used for inputs type 'text', 'tel', and 'date'
- [textArea documentation](<https://((DOMAIN))/docs/Components/FormInputs/TextArea>)
- [select documentation](<https://((DOMAIN))/docs/Components/FormControls/Select>)
- [radio button documentation](<https://((DOMAIN))/docs/Components/FormControls/Radio>)
- [switch documentation](<https://((DOMAIN))/docs/Components/FormControls/Switch>)
- [checkbox documentation](<https://((DOMAIN))/docs/Components/FormControls/Checkbox>)
### Examples
Here is an example of the form step's attributes. It presents a form with two sections, and an example of each kind of input type.
> NB : this example object is provided in the admin, in the onboarding section: 'Form step example'.
```json
{
"subtype": "form-step",
"form": {
"identification": {
"title": "Identification",
"inputs": {
"firstName": {
"index": 0,
"placeholder": "First name",
"maxLength": 50,
"type": "text",
"required": true
},
"tel": {
"index": 1,
"required": true,
"type": "tel",
"label": "Phone number",
"placeholder": "+333 33 33 33 33",
"pattern": "[+][3][0-9]{2}[0-9]{2}[0-9]{2}[0-9]{2}[0-9]{2}"
},
"medicalInfo": {
"label": "Medical informations",
"placeholder": "Your medical Informations",
"index": 7,
"maxLength": 250,
"type": "textarea"
},
"dateOfBirth": {
"index": 2,
"required": true,
"type": "date",
"label": "Date of birth",
"min": "1621-07-08",
"max": "1900-01-01",
"value": "2000-01-01"
},
"country": {
"index": 4,
"id": "countries",
"type": "countries",
"required": true,
"emptyItem": { "label": "Select your country label" }
},
"gender": {
"index": 3,
"type": "select",
"id": "genders",
"required": true,
"emptyItem": { "label": "Select your gender" },
"items": [
{ "label": "Male", "data": "male" },
{ "label": "Female", "data": "female" }
]
},
"environment": {
"index": 5,
"type": "radio",
"required": true,
"label": "Which environment do you live in ?",
"inlineBlock": true,
"items": [
{ "label": "City", "data": "city" },
{ "label": "Countryside", "data": "countryside" }
]
},
"programmingAbilities": {
"index": 6,
"type": "switch",
"label": "I am new in programming",
"value": true
},
"generalConditions": {
"index": 8,
"type": "checkbox",
"label": "I have read and I accept the general conditions",
"value": false
}
}
},
"moreAboutYou": {
"title": "More about you",
"inputs": {
"favoriteColor": {
"index": 0,
"placeholder": "Your favorite color",
"type": "text",
"required": true
}
}
}
}
}
```
This 'form' step would look like this:
![form-step-example](img/form-step-example.png)
## Settings for a `document to sign` step
The newly created child can be customized with these attributes :
| name | fullfillment |
| ---------- | ------------ |
| subtype | **required** |
| text | **required** |
| buttonText | optionnal |
| checkbox | optionnal |
### Description
#### To set up the child object you have created with these elements:
1. Edit you step object
2. Go to _Object attributes_
3. Add the following attributes:
- Add a new key **subtype** of type `String` with the exact value 'sign-step'
- Add a new key **text** of type `String` with the text of your document to sign as value
- Add a new key **buttonText** of type `String` with the text that you want to display in the submit button of your step. Default value for this attribute is 'Sign'.
- Add a new key **checkbox** of type `Object`, if the user has to be forced to click on a checkbox before validating his document (ex: 'I have read and accepted the conditions'). In the checkbox object, the following attributes should be defined:
- A **label** key of type `String`, for the text associated to the checkbox
- A **required** key of type `Boolean`, set at true if the user has to check it
- A **name** key of type `String`
- All other attributes wanted for the checkbox.
- Add a new key **link** of type `Object`, if a link must be added to the step (ex: download of a .pdf version of the document to sign). In the link object, the following attributes should be defined:
- A **href** key of type `String`, with the link you want to add to the step
- A **label** key of type `String`, for the text displayed for the link (by default, '> Link to the document' is displayed)
- All other attributes wanted for the link.
### Examples
Here is an example of the structure a 'document to sign' step could have:
```json
{
"subtype": "sign-step",
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent ornare non sem eu pretium. Integer porttitor risus eget nibh iaculis, ac lacinia orci dictum. Nunc ullamcorper consequat enim in posuere. Aliquam volutpat est odio, vel maximus arcu maximus sit amet. Donec ultricies faucibus magna id luctus. Duis et dapibus elit. In vestibulum ipsum erat, at commodo tortor convallis vel. Nunc ut ultrices nulla. Etiam lorem justo, consequat a consectetur a, porttitor non turpis. Mauris eu mollis nisl, id dignissim quam. Curabitur condimentum sollicitudin rutrum. Aenean blandit, arcu nec ullamcorper rhoncus, lectus sem lacinia lorem, venenatis dignissim velit mi et sapien. Nullam posuere augue ut magna ullamcorper dignissim. Ut rhoncus sapien vel nulla commodo finibus. Cras non leo vel urna finibus volutpat. Praesent et ex eget diam tincidunt suscipit. Phasellus bibendum neque vel placerat iaculis. Vestibulum bibendum ultrices ipsum, non sodales lectus. Cras eget orci eget elit blandit scelerisque at ut nulla. Integer ligula eros, eleifend quis sodales a, porttitor sit amet neque. Fusce mollis magna at lectus varius, quis suscipit mi cursus. Etiam id imperdiet metus, in malesuada quam. Aliquam facilisis nunc non sapien condimentum, quis iaculis nisl auctor. Nunc lorem sapien, interdum vel efficitur ac, dapibus a diam. Ut ante urna, sodales in bibendum vel, lacinia ut mauris. In vel placerat leo. In libero dui, tincidunt at sem id, faucibus sollicitudin elit.",
"buttonText": "Sign chart",
"checkbox": {
"name": "acceptChart",
"label": "I have read and accepted the Chart 01",
"required": true
},
"link": {
"label": "Download Chart 01",
"href": "https://help.github.com/en/articles/creating-an-issue",
"download": true,
"target": "_blank"
}
}
```
NB : `target` & `download` are forwarded to the a html element as they are valid html properties
This 'document to sign' step would look like this:
![document-to-sign-step-example](img/document-to-sign-step-example.png)

165
docs/object-attribute-system.md

@ -1,165 +0,0 @@
# Object Attributes System
> This document cover two notions, the edition of attributes and the impact it has relatively to the others Objects.
## Edition of Attributes
> There is no limit to how many attributes can be defined to an Object.
In the "Object Attributes" section of the "Object Edit" Page, the first row is a form to create and append a new attribute. It requires two elements, the name of the attribute and its type (`String`, `Number`, `Boolean`, `Array`, `Object`, `Function`, `Null`). Click 'Add' to create the attribute.
> Within a same Object, each attribute's name must be unique.
Once created, the new attributes appears right below and the ability to associate a value to it is now available. Depending on the type of the attribute, the interface will vary.
- String value input is type String.
- Number value input is type Number.
- Booleans value input appears as a switch, true by default.
- Arrays and Objects content are hidable / showable via the "Show/Hide content" button on the right of the attribute. There is no limit on the depth of Object/Array, however, after a certain level, the interface will start to feel narrow.
- String value input is type String.
- Null will not display any input.
- Function will offer to select from all available functions, save on select.
Any attribute can be delete by clicking on the 'trash' icon on the right hand of it.
Here an example of how the section looks like.
![object-attributes](img/object-attributes.png)
## Attributes and RelationShips
When an attributes is set to an Object, other Objects, associated to this particular Object, will have access to it. Which means that, if an Object A is added as a child of an Object B, A will embed its attributes within the instance of B.
Object's attributes follow a hierarchy when associated to an other Object.
The **defaults attributes** of a child, the ones defined in the original Object are the weakest ones. A **children attribute** is applied to all the children and override the default attributes. Finally, **relation attribute** is the strongest one, it override Default Attributes and Children Attributes.
When an object and its relationship are resolved, the three structures (`attrs`, `childrenAttrs`, `childAttrs`) are merged.
The following json shows how the object would be represented:
```json
{
"children": {
"printalphabet": {
"duration": 3600,
"xp": 800,
"isBonus": true
}
}
}
```
Children
![children](img/children.png)
Child
![child-capture](img/child-capture.png)
## Detailed example
Let's create a few `exercises` objects
> swap
```js
{
"id": 12344,
"title": "swap",
"attrs": {
"language": "go",
"duration": 7200
}
}
```
> printalphabet
```js
{
"id": 12345,
"title": "printalphabet-v2",
"attrs": {
"language": "go",
"duration": 3600
}
}
```
We can now create a parent object that will reference them and link them.
This allow you to specify the structuration of your pedagogical content.
I'll make a quest that regroup those 2 exercises:
> quest-03
```js
{
"id": 12346,
"title": "quest-03",
"attrs": {},
"childrenAttrs": {
"xp": 800,
"duration": 4800,
},
"children": {
"printalphabet": {
"ref": 12345,
"index": 0,
"attrs": {
"duration": 7200
}
},
"swap": {
"ref": 12344,
"index": 1,
"attrs": {}
}
}
}
```
All done, now when rendering an object, attributes are merged like so:
> rendered quest object
```js
{
"id": 12346,
"title": "quest-03",
"attrs": {},
"children": {
"printalphabet": {
"ref": 12345,
"index": 0,
"attrs": {
"language": "go",
"xp": 800,
"duration": 7200
}
},
"swap": {
"ref": 12344,
"index": 1,
"attrs": {
"language": "go",
"xp": 800,
"duration": 4800
}
}
}
}
```
First we apply the **default attributes** from the referenced object.
> Here `duration` and `language` are applied.
Then we apply the **children attributes** to every child.
> In this case we override every `duration` to 4800 and add the new `xp` attribute.
After that we apply the **relation attributes**, that are the most specific and as such,
override all others attributes.
> In this case only the `printalphabet` relation had attributes and so we apply
> the given `duration` to the final merged object.

40
docs/object-child-creation.md

@ -1,40 +0,0 @@
# Admin object's management - create a child object
## Usage
Objects of the Admin can be configured :
- By setting particular **attributes** to the object
- By associating **children** to the object
Children can be added, deleted, reordered in the list. Also, it's possible to configure it in a special way for the parent object, by setting children attributes for all the children.
This documentation explains how to associate a child to a parent object.
### Create a new object for your child in the admin
> Information is available for object's creation: [Object Creation](object-creation.md)
### Add this new object as a child of your parent's object
#### 1. Edit the parent object
<img width="640" alt="Capture d’écran 2019-04-22 à 19 24 23" src="img/56517407-cb98bc00-6534-11e9-98d6-a2b1c0193a38.png">
<img width="640" alt="Capture d’écran 2019-04-22 à 19 24 10" src="img/56517421-d0f60680-6534-11e9-86ef-97fb9e59786e.png">
#### 2. Go to _Children_ > _Add a child_
![add-child-to-parent-object](img/add-child-to-parent-object.png)
#### 3. Set up the new child:
- Enter its name in the input "Add a child name"
- Select your step object in the select input
- Click on "ADD"
Your step is then related to its parent. You can see it in the _Children_ section of the parent's object. There, you can now:
- Delete the child from its parent (the actual object of your child will not be deleted).
- Reorder it in the children's list, by dragging it to the place you want.
- Update its original settings by clicking on the eye icon of its reference (redirection to object edit page of the child).
<img width="1229" alt="Capture d’écran 2019-04-22 à 19 51 12" src="img/56518936-a1e19400-6538-11e9-81c7-520ffd365cff.png">

58
docs/object-creation.md

@ -1,58 +0,0 @@
# Admin object's management - create an object
## Usage
Elements of the app are managed through objects in _Admin_.
Objects of the Admin are first created and defined:
- By their **title**,
- By their **type**.
Then it can be configured through:
- Attributes,
- Children.
> This documentation explains how to create an object.
### Create a new object in the admin
> (in _Admin_ > _Add new object_)
<img width="664" alt="Capture d’écran 2019-04-22 à 15 57 37" src="img/56507169-6505a500-6518-11e9-89bb-04c7fd9b41ca.png">
<img width="450" alt="Capture d’écran 2019-04-22 à 15 58 21" src="img/56507180-6afb8600-6518-11e9-97a5-4dcff8f0a069.png">
- The **title** of your object will be the title displayed to your candidates. Use an intellegible title for your user.
> NB: you can always edit it in the _Admin_
- The **type** depends on the nature of your object:
- **Campus** is used to declare a school.
- Examples: _Alem_, _Madeira_, etc.
- Campus can contains cursus: _Alem_ contains for example _01-classical_ and _Piscine Go_.
- **Cursus** is used to declare a course.
- Examples: _01-classical_, _Piscine Go_, etc.
- Cursuses can contains cursuses: the main cursus _01-classical_, for example, contains cursuses like _Piscine Go_, but also all the branches that the student have access to, as _Web_, _Security_, _Algorythm_, _Design_, etc.
- Cursuses can contains quests: _Piscine Go_ of _01-classical_ contains quests like _Quest 1_ or _Quest 2_.
- **Quest** is used to declare a project.
- Examples: _Quest 1_, _Quest 2_, etc.
- Quest contains exercises: _Quest 1_ of _Piscine Go_ contains exercises like _printalphabet_ or _printcomb_.
- Exercise is used to declare exercises
- Examples: _printalphabet_, _printcomb_, _atoi_, etc.
- Exercises doesn't contains any children.
- Signup is used to declare steps of the registration.
- Examples: _Using our services_, _Tell us more about you_, etc.
- One major object _Sign up_ contains all the sign up's modular steps : _Using our services_, _Tell us more about you_, etc.
- Onbaording is used to declare steps of the onbaording.
- Examples: _Toad_, _Administration_, _Additional Informations_, _Chart 01_, etc.
- Three main objects define the major steps of the onboarding : _Toad_, _Administration_, _Piscine_.
- _Administration_ contains modular steps: _Additional Informations_, _Chart 01_, etc.
The child object is then available in the _Admin_. It can be found in the section of its type or thanks to the search bar of the cursus object's page.
More information is available:
- for setting attributes of an object: (soon available)
- for setting children of an object: [Child object creation](object-child-creation.md)
- for creation of modular steps in Sign up and onboarding's Administration object: [Modular step management](modular-steps-management.md)

34
docs/object-edit.md

@ -1,34 +0,0 @@
# Objects Edition
> Allow you to edit an object, see and manage its relations.
## Page Composition
![object-edit-overview](img/object-edit-overview.png)
### Pin 1
- Link back to the "Objects" page ;
- Editable name field, hit 'enter' or 'cmd + s' or click on the floppy-disk icon to save ;
- Major dependencies visualisation, (where my object is used as a child), click the label to navigate to the dependence ;
- External URL, this is an optional parameter, it's use to point at an other source of content or information needed by the object. We generaly use to point at a Git repository ;
### Pin 2
- Delete Button, Warning there, it will destroy your object! ;
- Type of your Object (`organisation`, `campus`, `onboarding`, `cursus`, `quest`, `exercise`), save on select ;
- Status of your Object (`draft`, `online`, `offline`), save on select ;
- The first and last name of the original author ;
### Pin 3
- Object Attribute edition area, manage all the attributes relative to this Object. These attributes will be exposed to its relationship ;
### Pin 4
- Object Children edition area ;
- Children Attributes edition area, these attributes impact and overload all the following children. Works the same way as standard attributes ;
- Add a child, allows to add a child to the children list, more information here -> [Object Child creation](object-child-creation.md) ;
- Children List, allows you to reorganise, delete and edit child. Each child can be overload with its own attributes, the edition works the same way as the original attributes ;
More informations about attribute overload system [here](object-attribute-system.md)

29
docs/objects.md

@ -1,29 +0,0 @@
# Objects
> Allow you to create, manage and organize your pedagical and onboarding content.
## Definition
An Object is an highly customizable element, which can be use in many situations. We use it to compose cursuses and onboarding processes.
Objects can be associated together and then share a vertical or horizontal relationship, which allows to build complex structure of multiple objects.
It structure can be visualized in two parts. The first one is the definition of the object itself and attributes, called `attrs`. The second part is the definition of minor relationships, called `children` and attributes applied to them, called `childrenAttrs`.
This is the minimal structure of an object:
- name
- type (`organisation`, `campus`, `onboarding`, `cursus`, `quest`, `exercise`)
- status (`draft`, `online`, `offline`)
- attrs {}
- childrenAttrs {}
- children {}
## Browse Objects:
To access your Objects, go to the admin dashboard and then click on the _manage object_ link within the "Object" card.
![go-to-objects](img/go-to-objects.png)
Objects are sorted by type in different sections. This page offer a search bar that allow you query the objects by name. In the top-right corner, click the _add a new object_ button to create a new object. Fill a name, select a type and click _create_ to validate your creation. You will be redirected to the Object Edition page (document is here).
![all-object-page](img/all-object-page.png)

28
docs/pc-requirements.md

@ -1,28 +0,0 @@
# PC requirements (Minimum)
Features required:
- **Compatibility with Linux (Ubuntu/Debian x64)**
| Component | Specifications |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Processor | 4 threads x86-64 (64 bits), [2200 single thread performance](https://www.cpubenchmark.net/singleThread.html) / [1000 single-core score](https://browser.geekbench.com/processor-benchmarks) |
| Memory | 8 GB DDR4 |
| Storage | 120 GB SSD |
| Display | 14" Full HD (flicker-free) |
# PC requirements (Recommended)
Features required:
- **Compatibility with Linux (Ubuntu/Debian x64)**
| Component | Specifications |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Processor | 6 threads x86-64 (64 bits), [2600 single thread performance](https://www.cpubenchmark.net/singleThread.html) / [1200 single-core score](https://browser.geekbench.com/processor-benchmarks) |
| Memory | 16 GB DDR4 |
| Storage | 120 GB SSD |
| Display | 17" Full HD (flicker-free) |
|**For comfort:**| An additional display : 24" Full HD (flicker-free). Pivotable to 90 degrees.|
**Important**: Please note that the above requirements do not cover the Game Engine specific branches.

330
docs/piscine-go-curriculum.md

@ -1,330 +0,0 @@
# Piscine Go curriculum
---
## Week One
### Quest 1
#### Introduction to shell
Notions: basic usage and interaction with a command line terminal.
Videos:
- [1-2](https://www.youtube.com/watch?v=A0Mqc215igw) `curl` with the GitHub api and Example of shell file
- [1-3](https://www.youtube.com/watch?v=21h-vsuXgDU) `touch`, `chmod` and `echo`
- [1-4](https://www.youtube.com/watch?v=7a1JSWHhJlM) `find` and `grep`
- [1-5](https://www.youtube.com/watch?v=Nil7rVP3eMI) `cut`, `sed` and `tr`
- [1-6](https://www.youtube.com/watch?v=cQmcaOseuiA&) `jq` and `wc`
Exercices:
- [introduction](https://github.com/01-edu/public/tree/master/subjects/introduction/README.md)
- [make-it-better](https://github.com/01-edu/public/tree/master/subjects/make-it-better/README.md)
- [to-git-or-not-to-git](https://github.com/01-edu/public/tree/master/subjects/to-git-or-not-to-git/README.md)
- [who-are-you](https://github.com/01-edu/public/tree/master/subjects/who-are-you/README.md)
- [cl-camp1](https://github.com/01-edu/public/tree/master/subjects/cl-camp1/README.md)
- [cl-camp2](https://github.com/01-edu/public/tree/master/subjects/cl-camp2/README.md)
- [cl-camp3](https://github.com/01-edu/public/tree/master/subjects/cl-camp3/README.md)
- [cl-camp4](https://github.com/01-edu/public/tree/master/subjects/cl-camp4/README.md)
- [cl-camp5](https://github.com/01-edu/public/tree/master/subjects/cl-camp5/README.md)
- [cl-camp6](https://github.com/01-edu/public/tree/master/subjects/cl-camp6/README.md)
- [cl-camp7](https://github.com/01-edu/public/tree/master/subjects/cl-camp7/README.md)
- [cl-camp8](https://github.com/01-edu/public/tree/master/subjects/cl-camp8/README.md)
- [now-get-to-work](https://github.com/01-edu/public/tree/master/subjects/now-get-to-work/README.md)
### Quest 2
#### Introduction to Go Lang and basic programmation concepts
Notions: Variables declaration, Loops, if and else statement, usage of z01.PrintRune function.
Videos:
- [02-01-If](https://www.youtube.com/watch?v=rnF1_SfeGE4) and Else Statements in Go
- [02-02-ForLoops](https://www.youtube.com/watch?v=Bt47lx6q2-4)
- [02-03-PrintRune](https://www.youtube.com/watch?v=o8JrvI3jqoM) function
- [02-04-Variables](https://www.youtube.com/watch?v=RCNOV8m0hJQ) Declaration and ascii
Exercices:
- [printalphabet](https://github.com/01-edu/public/tree/master/subjects/printalphabet/README.md)
- [printreversealphabet](https://github.com/01-edu/public/tree/master/subjects/printreversealphabet/README.md)
- [prindigits](https://github.com/01-edu/public/tree/master/subjects/printdigits/README.md)
- [isnegative](https://github.com/01-edu/public/tree/master/subjects/isnegative/README.md)
- [printcomb](https://github.com/01-edu/public/tree/master/subjects/printcomb/README.md)
- [printcomb2](https://github.com/01-edu/public/tree/master/subjects/printcomb2/README.md)
- [printnbr](https://github.com/01-edu/public/tree/master/subjects/printnbr/README.md)
- [printcombn](https://github.com/01-edu/public/tree/master/subjects/printcombn/README.md)
### Quest 3
#### Introduction to Go Lang and basic programmation concepts II
Notions: String Manupulation, Range Loops, Pointers, Modulo and Division relative to computer science.
Videos:
- [03-01-StringsManipulation](https://www.youtube.com/watch?v=8LplJN_8iOU)
- [03-02-RangeLoop](https://www.youtube.com/watch?v=i89N4cjh1-g)
- [03-03-Pointers](https://www.youtube.com/watch?v=owVPa5b1BMc) on variables
- [03-04-Modulo](https://www.youtube.com/watch?v=NVan-9-Ioec) and Division
Exercices:
- [pointone](https://github.com/01-edu/public/tree/master/subjects/pointone/README.md)
- [ultimatepointone](https://github.com/01-edu/public/tree/master/subjects/ultimatepointone/README.md)
- [divmod](https://github.com/01-edu/public/tree/master/subjects/divmod/README.md)
- [ultimatedivmod](https://github.com/01-edu/public/tree/master/subjects/ultimatedivmod/README.md)
- [printstr](https://github.com/01-edu/public/tree/master/subjects/printstr/README.md)
- [strlen](https://github.com/01-edu/public/tree/master/subjects/strlen/README.md)
- [swap](https://github.com/01-edu/public/tree/master/subjects/swap/README.md)
- [strrev](https://github.com/01-edu/public/tree/master/subjects/strrev/README.md)
- [basicatoi](https://github.com/01-edu/public/tree/master/subjects/basicatoi/README.md)
- [basicatoi2](https://github.com/01-edu/public/tree/master/subjects/basicatoi2/README.md)
- [atoi](https://github.com/01-edu/public/tree/master/subjects/atoi/README.md)
- [sortintegerable](https://github.com/01-edu/public/tree/master/subjects/sortintegertable/README.md)
### Exam 1 (4hours)
#### Basic functions and programs skills evaluation, based on Quest 2 and Quest 3
### Raid 1 - Square Drawing
#### First Group project. Problem resolution. Usage of first knowledge (loop and if/else)
---
## Week Two
### Quest 4
#### Algorithm concepts
Notions: Iterative and recursive programmation
Videos:
- [04-01-Iterativity and Recursivity](https://www.youtube.com/watch?v=oCZDdAID5Ik)
Exercices:
- [iterativefactorial](https://github.com/01-edu/public/tree/master/subjects/iterativefactorial/README.md)
- [recursivefactorial](https://github.com/01-edu/public/tree/master/subjects/recursivefactorial/README.md)
- [iterativepower](https://github.com/01-edu/public/tree/master/subjects/iterativepower/README.md)
- [recursivepower](https://github.com/01-edu/public/tree/master/subjects/recursivepower/README.md)
- [fibonacci](https://github.com/01-edu/public/tree/master/subjects/fibonacci/README.md)
- [sqrt](https://github.com/01-edu/public/tree/master/subjects/sqrt/README.md)
- [isprime](https://github.com/01-edu/public/tree/master/subjects/isprime/README.md)
- [findnextprime](https://github.com/01-edu/public/tree/master/subjects/findnextprime/README.md)
- [eightqueens](https://github.com/01-edu/public/tree/master/subjects/eightqueens/README.md)
### Quest 5
#### Application of previously viewed concepts.
Notions: String Manipulation and medium-advanced algorithms
Videos:
- [05-01-Runes](https://www.youtube.com/watch?v=-eIU5ISID64), Bytes and Strings
Exercices:
- [firstrune](https://github.com/01-edu/public/tree/master/subjects/firstrune/README.md)
- [nrune](https://github.com/01-edu/public/tree/master/subjects/nrune/README.md)
- [lastrune](https://github.com/01-edu/public/tree/master/subjects/lastrune/README.md)
- [index](https://github.com/01-edu/public/tree/master/subjects/index/README.md)
- [compare](https://github.com/01-edu/public/tree/master/subjects/compare/README.md)
- [toupper](https://github.com/01-edu/public/tree/master/subjects/toupper/README.md)
- [tolower](https://github.com/01-edu/public/tree/master/subjects/tolower/README.md)
- [capitalize](https://github.com/01-edu/public/tree/master/subjects/capitalize/README.md)
- [isalpha](https://github.com/01-edu/public/tree/master/subjects/isalpha/README.md)
- [isnumeric](https://github.com/01-edu/public/tree/master/subjects/isnumeric/README.md)
- [islower](https://github.com/01-edu/public/tree/master/subjects/islower/README.md)
- [isupper](https://github.com/01-edu/public/tree/master/subjects/isupper/README.md)
- [isprintable](https://github.com/01-edu/public/tree/master/subjects/isprintable/README.md)
- [concat](https://github.com/01-edu/public/tree/master/subjects/concat/README.md)
- [basicjoin](https://github.com/01-edu/public/tree/master/subjects/basicjoin/README.md)
- [join](https://github.com/01-edu/public/tree/master/subjects/join/README.md)
- [printnbrbase](https://github.com/01-edu/public/tree/master/subjects/printnbrbase/README.md)
- [atoibase](https://github.com/01-edu/public/tree/master/subjects/atoibase/README.md)
### Quest 6
#### Usage of OS.Args
Notions: Arguments manipulation in programs
Videos:
- [06-01-Os.Args](https://www.youtube.com/watch?v=I1xt_TLRhF0)
Exercices:
- [printprogramname](https://github.com/01-edu/public/tree/master/subjects/printprogramname/README.md)
- [printparams](https://github.com/01-edu/public/tree/master/subjects/printparams/README.md)
- [revparams](https://github.com/01-edu/public/tree/master/subjects/revparams/README.md)
- [sortparams](https://github.com/01-edu/public/tree/master/subjects/sortparams/README.md)
### Quest 7
#### The Memory Allocation in GoLang
Notions: Usage of Make and Append
Videos:
- [07-01-Make](https://www.youtube.com/watch?v=2HHVUM0YQuI) and Append methods
Exercices:
- [appendrange](https://github.com/01-edu/public/tree/master/subjects/apprendrange/README.md)
- [makerange](https://github.com/01-edu/public/tree/master/subjects/makerange/README.md)
- [concatparams](https://github.com/01-edu/public/tree/master/subjects/concatparams/README.md)
- [splitwhitespaces](https://github.com/01-edu/public/tree/master/subjects/splitwhitespaces/README.md)
- [printwordstables](https://github.com/01-edu/public/tree/master/subjects/printwordstables/README.md)
- [convertbase](https://github.com/01-edu/public/tree/master/subjects/converbase/README.md)
- [split](https://github.com/01-edu/public/tree/master/subjects/split/README.md)
### Exam 2 (4hours)
#### Basic functions and programs skills evaluation, based on all the quests from 2 to 6
### Raid 2 - Sudoku
#### Second Group project. Problem resolution. Usage of Memory manipulation tools
---
## Week Three
### Quest 8
#### Introduction to Structures and advanced types in GoLang
Notions: Creation of struct types and file manipulation (Open, Read, Close methods)
Videos:
- [08-01-Structures](https://www.youtube.com/watch?v=-24M7r7VuLY) in Go
- [08-02-File](https://www.youtube.com/watch?v=8vUgchQGhcQ) Manipulation in go
Exercices:
- [bool](https://github.com/01-edu/public/tree/master/subjects/bool/README.md)
- [point](https://github.com/01-edu/public/tree/master/subjects/point/README.md)
- [displayfile](https://github.com/01-edu/public/tree/master/subjects/displayfile/README.md)
- [cat](https://github.com/01-edu/public/tree/master/subjects/cat/README.md)
- [ztail](https://github.com/01-edu/public/tree/master/subjects/ztail/README.md)
### Quest 9
#### Functions as argument
Notions: Advance function prototyping
Videos:
- [09-01-Functions](https://www.youtube.com/watch?v=lw8jUwsluAE) as Arguments
Exercices:
- [foreach](https://github.com/01-edu/public/tree/master/subjects/foreach/README.md)
- [map](https://github.com/01-edu/public/tree/master/subjects/map/README.md)
- [any](https://github.com/01-edu/public/tree/master/subjects/any/README.md)
- [countif](https://github.com/01-edu/public/tree/master/subjects/countif/README.md)
- [issorted](https://github.com/01-edu/public/tree/master/subjects/issorted/README.md)
- [doop](https://github.com/01-edu/public/tree/master/subjects/doop/README.md)
- [sortwordarr](https://github.com/01-edu/public/tree/master/subjects/sortwordarr/README.md)
- [advancedsortwordarr](https://github.com/01-edu/public/tree/master/subjects/advancedsortwordarr/README.md)
### Quest 10
#### Hackathon
Notions: All previously viewed concepts in team work
Exercices:
- [rot14](https://github.com/01-edu/public/tree/master/subjects/rot14/README.md)
- [abort](https://github.com/01-edu/public/tree/master/subjects/abort/README.md)
- [collatzcountdown](https://github.com/01-edu/public/tree/master/subjects/collatzcountdown/README.md)
- [comcheck](https://github.com/01-edu/public/tree/master/subjects/comcheck/README.md)
- [enigma](https://github.com/01-edu/public/tree/master/subjects/enigma/README.md)
- [pilot](https://github.com/01-edu/public/tree/master/subjects/pilot/README.md)
- [fixthemain](https://github.com/01-edu/public/tree/master/subjects/fixthemain/README.md)
- [compact](https://github.com/01-edu/public/tree/master/subjects/compact/README.md)
- [activebits](https://github.com/01-edu/public/tree/master/subjects/activebits/README.md)
- [max](https://github.com/01-edu/public/tree/master/subjects/max/README.md)
- [join](https://github.com/01-edu/public/tree/master/subjects/join/README.md)
- [unmatch](https://github.com/01-edu/public/tree/master/subjects/unmatch/README.md)
### Exam 3 (4hours)
#### Basic functions and programs skills evaluation, based on all the quests from 2 to 8
### Raid 3 - File Reader
#### Second Group project. Problem resolution. File manipulation based on Raid 1
---
## Week Four
### Quest 11
#### Linked lists in GoLang
Notions: Pointers manipulation and data structure
Videos:
- [11-01-Linked](https://www.youtube.com/watch?v=EPICVEbylU0) Lists Introduction
Exercices:
- [listpushback](https://github.com/01-edu/public/tree/master/subjects/listpushback/README.md)
- [listpushfront](https://github.com/01-edu/public/tree/master/subjects/listpushfront/README.md)
- [listsize](https://github.com/01-edu/public/tree/master/subjects/listsize/README.md)
- [listlast](https://github.com/01-edu/public/tree/master/subjects/listlast/README.md)
- [listclear](https://github.com/01-edu/public/tree/master/subjects/listclear/README.md)
- [listat](https://github.com/01-edu/public/tree/master/subjects/listat/README.md)
- [listreverse](https://github.com/01-edu/public/tree/master/subjects/listreverse/README.md)
- [listforeach](https://github.com/01-edu/public/tree/master/subjects/listforeach/README.md)
- [listforeachif](https://github.com/01-edu/public/tree/master/subjects/listforeachif/README.md)
- [listfind](https://github.com/01-edu/public/tree/master/subjects/listfind/README.md)
- [listremoveif](https://github.com/01-edu/public/tree/master/subjects/listremoveif/README.md)
- [listmerge](https://github.com/01-edu/public/tree/master/subjects/listmerge/README.md)
- [listsort](https://github.com/01-edu/public/tree/master/subjects/listsort/README.md)
- [sortlistinsert](https://github.com/01-edu/public/tree/master/subjects/sortlistinsert/README.md)
- [sortedlistmerge](https://github.com/01-edu/public/tree/master/subjects/sortedlistmerge/README.md)
### Quest 12
#### Binary Trees
Notions: Advanced Data Structure using binary trees
Videos:
- [12-01-Introduction](https://www.youtube.com/watch?v=3g2WCqWNIVs) to Binary Trees
Exercices:
- [btreeinsertdata](https://github.com/01-edu/public/tree/master/subjects/btreeinsertdata/README.md)
- [btreeapplyinorder](https://github.com/01-edu/public/tree/master/subjects/btreeapplyinorder/README.md)
- [btreeapplypreorder](https://github.com/01-edu/public/tree/master/subjects/btreeapplypreorder/README.md)
- [btreesearchitem](https://github.com/01-edu/public/tree/master/subjects/btreesearchitem/README.md)
- [btreelevelcount](https://github.com/01-edu/public/tree/master/subjects/btreelevelcount/README.md)
- [btreeisbinary](https://github.com/01-edu/public/tree/master/subjects/btreeisbinary/README.md)
- [btreeapplylevel](https://github.com/01-edu/public/tree/master/subjects/btreeapplylevel/README.md)
- [btreemax](https://github.com/01-edu/public/tree/master/subjects/btreemax/README.md)
- [btreemin](https://github.com/01-edu/public/tree/master/subjects/btreemin/README.md)
- [btreetransplant](https://github.com/01-edu/public/tree/master/subjects/btreetransplant/README.md)
- [btreedeletenode](https://github.com/01-edu/public/tree/master/subjects/btreedeletenode/README.md)
### Exam 4 - Final Exam (8hours)
#### Functions and programs skills evaluation, based on all the quests from 2 to 11

150
docs/piscine-rust-curriculum.md

@ -1,150 +0,0 @@
# Piscine Rust curriculum
---
## Week One
### Quest 01-rust
Exercises:
- fibonacci2 | https://github.com/01-edu/public/tree/master/subjects/fibonacci2
- scalar | https://github.com/01-edu/public/tree/master/subjects/scalar
- temperature_conv | https://github.com/01-edu/public/tree/master/subjects/temperature_conv
- looping | https://github.com/01-edu/public/tree/master/subjects/looping
- speed_transformation | https://github.com/01-edu/public/tree/master/subjects/speed_transformation
- groceries | https://github.com/01-edu/public/tree/master/subjects/groceries
- reverse_string | https://github.com/01-edu/public/tree/master/subjects/reverse_string
- find_factorial | https://github.com/01-edu/public/tree/master/subjects/find_factorial
- matrix_transposition | https://github.com/01-edu/public/tree/master/subjects/matrix_transposition
- division_and_remainder | https://github.com/01-edu/public/tree/master/subjects/division_and_remainder
- tuples | https://github.com/01-edu/public/tree/master/subjects/tuples
### Quest 02-rust
Exercices:
- ownership | https://github.com/01-edu/public/tree/master/subjects/ownership
- copy | https://github.com/01-edu/public/tree/master/subjects/copy
- borrow | https://github.com/01-edu/public/tree/master/subjects/borrow
- doubtful | https://github.com/01-edu/public/tree/master/subjects/doubtful
- borrow_me_the_reference | https://github.com/01-edu/public/tree/master/subjects/borrow_me_the_reference
- changes | https://github.com/01-edu/public/tree/master/subjects/changes
- string_literals | https://github.com/01-edu/public/tree/master/subjects/string_literals
- name_initials | https://github.com/01-edu/public/tree/master/subjects/name_initials
- arrange_it | https://github.com/01-edu/public/tree/master/subjects/arrange_it
- tic_tac_toe | https://github.com/01-edu/public/tree/master/subjects/tic_tac_toe
### Quest 03-rust
Exercices:
- circle | https://github.com/01-edu/public/tree/master/subjects/circle
- card_deck | https://github.com/01-edu/public/tree/master/subjects/card_deck
- arrays | https://github.com/01-edu/public/tree/master/subjects/arrays
- strings | https://github.com/01-edu/public/tree/master/subjects/strings
- edit_distance | https://github.com/01-edu/public/tree/master/subjects/edit_distance
- to_url | https://github.com/01-edu/public/tree/master/subjects/to_url
- capitalizing | https://github.com/01-edu/public/tree/master/subjects/capitalizing
- hashing | https://github.com/01-edu/public/tree/master/subjects/hashing
- string_permutation | https://github.com/01-edu/public/tree/master/subjects/string_permutation
- bigger | https://github.com/01-edu/public/tree/master/subjects/bigger
- simple_hash | https://github.com/01-edu/public/tree/master/subjects/simple_hash
- collect | https://github.com/01-edu/public/tree/master/subjects/collect
---
## Week Two
## Quest 04-rust
Exercices:
- unwrap_or_expect | https://github.com/01-edu/public/tree/master/subjects/unwrap_or_expect
- panic | https://github.com/01-edu/public/tree/master/subjects/panic
- handling | https://github.com/01-edu/public/tree/master/subjects/handling
- profanity_filter | https://github.com/01-edu/public/tree/master/subjects/profanity_filter
- question_mark | https://github.com/01-edu/public/tree/master/subjects/question_mark
- banner | https://github.com/01-edu/public/tree/master/subjects/banner
- cipher | https://github.com/01-edu/public/tree/master/subjects/cipher
- error_types | https://github.com/01-edu/public/tree/master/subjects/error_types
- boxing_todo | https://github.com/01-edu/public/tree/master/subjects/boxing_todo
## Quest 05-rust
Exercices:
- middle_day | https://github.com/01-edu/public/tree/master/subjects/middle_day
- does_it_fit | https://github.com/01-edu/public/tree/master/subjects/does_it_fit
- macro_calculator | https://github.com/01-edu/public/tree/master/subjects/macro_calculator
- shopping_mall | https://github.com/01-edu/public/tree/master/subjects/shopping_mall
- expected_variable | https://github.com/01-edu/public/tree/master/subjects/expected_variable
- mobs | https://github.com/01-edu/public/tree/master/subjects/mobs
## Quest 06-rust
Exercices:
- traits | https://github.com/01-edu/public/tree/master/subjects/traits
- lifetimes | https://github.com/01-edu/public/tree/master/subjects/lifetimes
- lalgebra_scalar | https://github.com/01-edu/public/tree/master/subjects/lalgebra_scalar
- matrix | https://github.com/01-edu/public/tree/master/subjects/matrix
- matrix_ops | https://github.com/01-edu/public/tree/master/subjects/matrix_ops
- matrix_mult | https://github.com/01-edu/public/tree/master/subjects/matrix_mult
- lalgebra_vector | https://github.com/01-edu/public/tree/master/subjects/lalgebra_vector
- blood_types | https://github.com/01-edu/public/tree/master/subjects/blood_types
- border_cross | https://github.com/01-edu/public/tree/master/subjects/border_cross
- roman_numbers | https://github.com/01-edu/public/tree/master/subjects/roman_numbers
- generics | https://github.com/01-edu/public/tree/master/subjects/generics
- roman_numbers_iter | https://github.com/01-edu/public/tree/master/subjects/roman_numbers_iter
- vectors_operations | https://github.com/01-edu/public/tree/master/subjects/vector_operations
- events | https://github.com/01-edu/public/tree/master/subjects/events
- delete_prefix | https://github.com/01-edu/public/tree/master/subjects/delete_prefix
- commits_stats | https://github.com/01-edu/public/tree/master/subjects/commits_stats
---
## Week Three
## Quest 07-rust
Exercices:
- box_it | https://github.com/01-edu/public/tree/master/subjects/box_it
- borrow_box | https://github.com/01-edu/public/tree/master/subjects/borrow_box
- box_recursion | https://github.com/01-edu/public/tree/master/subjects/box_recursion
- how_many_references | https://github.com/01-edu/public/tree/master/subjects/how_many_references
- ref_cell | https://github.com/01-edu/public/tree/master/subjects/ref_cell
- drop_the_thread | https://github.com/01-edu/public/tree/master/subjects/drop_the_thread
## Quest 08-rust
Exercices:
- closures | https://github.com/01-edu/public/tree/master/subjects/closures
- sales | https://github.com/01-edu/public/tree/master/subjects/sales
- adding | https://github.com/01-edu/public/tree/master/subjects/adding
- adding_twice | https://github.com/01-edu/public/tree/master/subjects/adding_twice
- get_products | https://github.com/01-edu/public/tree/master/subjects/get_products
- highest | https://github.com/01-edu/public/tree/master/subjects/highest
- iterators | https://github.com/01-edu/public/tree/master/subjects/iterators
- slices_to_map | https://github.com/01-edu/public/tree/master/subjects/slices_to_map
- step_iterator | https://github.com/01-edu/public/tree/master/subjects/step_iterator
- project_motion | https://github.com/01-edu/public/tree/master/subjects/project_motion
## Quest 09-rust
Exercices:
- stars | https://github.com/01-edu/public/tree/master/subjects/stars
- ordinal | https://github.com/01-edu/public/tree/master/subjects/ordinal
- pangram | https://github.com/01-edu/public/tree/master/subjects/pangram
- diamond_creation | https://github.com/01-edu/public/tree/master/subjects/diamond_creation
- scores | https://github.com/01-edu/public/tree/master/subjects/scores
- talking | https://github.com/01-edu/public/tree/master/subjects/talking
- searching | https://github.com/01-edu/public/tree/master/subjects/searching
- logic_number | https://github.com/01-edu/public/tree/master/subjects/logic_number
- rot | https://github.com/01-edu/public/tree/master/subjects/rot
- pig_latin | https://github.com/01-edu/public/tree/master/subjects/pig_latin
- spelling | https://github.com/01-edu/public/tree/master/subjects/spelling
- rgb_match | https://github.com/01-edu/public/tree/master/subjects/rgb_match

2
docs/reviews.md

@ -47,4 +47,4 @@ You can have those 4 cases :
| fail | failed | **succeeded** |
| fail | succeeded | **failed** |
| succeed | succeeded | **succeeded** |
| succeed | failed | **failed** |
| succeed | failed | **failed** |

62
docs/server-installation.md

@ -1,62 +0,0 @@
# Server installation
## 🌐 DNS Configuration
The following DNS records should be configured in your domain's [zone file](https://en.wikipedia.org/wiki/Zone_file) or through the web interface of your dns provider/domain registrar.
- A _domain/subdomain_ pointing to the public IP address (using `A Record`) of your [dedicated server](server-requirements.md).
- A _subdomain_ called `git` pointing to the above mentioned *domain/subdomain* (using `CNAME Record`) or it's IP address (using `A Record`).
Your newly configured DNS records should look like this:
| FQDN | Record type | Target |
| -------------- | ----------- | ------------- |
| ((DOMAIN)) | A | X.X.X.X |
| git.((DOMAIN)) | CNAME | ((DOMAIN)) |
Here is an _example_ of the DNS records for the domain `example.org` with the public IP address of `93.184.216.34`:
| FQDN | Record type | Target |
| -------------- | ----------- | ------------- |
| example.org | A | 93.184.216.34 |
| git.example.org | CNAME | example.org |
## 🛠 Network Configuration
### ➡ Inbound
| Port | Protocol(s) | Service/Application |
| ----------- | ----------- | ------------------- |
| 80 | TCP | HTTP/(1.1, 2, 3) |
| 443 | TCP | HTTP(S)/(1.1, 2, 3) |
| 521 | TCP | SSH |
| 8080 - 8090 | TCP | HTTP/(1.1, 2, 3) |
### ⬅ Outbound
| Port | Protocol(s) | Service/Application |
| ----------- | ----------- | -------------------- |
| 587 | TCP | SMTP |
| 8080 - 8090 | TCP | HTTP/(1.1, 2, 3) |
## 💿 OS installation
1. Download and boot the `amd64` variant of the [Debian](https://www.debian.org/distrib/netinst) ISO image.
2. Select :
- "**Advanced options ...**"
- "**... Automated install**"
3. The network is automatically configured using your DHCP server. Additionally, you can also configure it manually to suit your preference.
4. At the prompt "Location of initial preconfiguration file:", please enter the following URL :
```console
raw.githubusercontent.com/01-edu/public/master/sh/debian/preseed.cfg
```
5. Then select "**Continue**" and follow the on-screen instructions.
## 🏁 Finishing up
Once the server is ready to be accessed remotely, please let us know via approriate communication channels and we will proceed with configuring the server.

25
docs/server-requirements.md

@ -1,25 +0,0 @@
# Server requirements (Minimum)
Features required:
- Dedicated hardware components (kept in **data centre** conditions)
- Compatibility with **Linux (Debian x64)**
| Component | Specification |
| --------- | ---------------------------------------------------------------------------------- |
| Processor | 8 threads x86-64 (64 bits), [2200 single thread performance](https://www.cpubenchmark.net/singleThread.html) / [1000 single-core score](https://browser.geekbench.com/processor-benchmarks) |
| Memory | 16 GB DDR4 |
| Storage | 2 x 500 GB SSD (`RAID 1` for _redundancy_ or `RAID 0` for _performance/capacity_) |
# Server requirements (Recommended)
Features required:
- Dedicated hardware components (kept in **data centre** environment)
- Compatibility with **Linux (Debian x64)**
| Component | Specification |
| --------- | ---------------------------------------------------------------------------------- |
| Processor | 10 threads x86-64 (64 bits), [2600 single thread performance](https://www.cpubenchmark.net/singleThread.html) / [1200 single-core score](https://browser.geekbench.com/processor-benchmarks) |
| Memory | 32 GB ECC DDR4 |
| Storage | 2 x 500 GB SSD (`RAID 1` for _redundancy_ or `RAID 0` for _performance/capacity_) |

140
docs/setup_of_external_repo.md

@ -1,140 +0,0 @@
# Addition of repository procedure
## Introduction
This document is a guide on how to add your own repository to store your projects and exercises.
This guide assumes that you have understood the files structures of the repository [public](https://github.com/01-edu/public).
It will only address the settings part of this task.
The addition of projects will be treated first as it does not require the knowledge of Docker.
However being familiar with Docker is **mandatory** for adding your own exercises with your own tests.
## Prerequisites
- A GitHub account where your exercises repository will be stored [https://github.com](https://github.com)
- A Docker Hub account [https://hub.docker.com](https://hub.docker.com)
## Setup of GitHub repository
### Create your own public repository
Once logged into your GitHub account, click on the creation of new repository:
It is the button `New` (the button is on the top corner right side).
### Git clone your repository and prepare an example for the folder structure for projects
- Create a folder called `subjects`.
- Inside this folder create a folder called what you wish (example: `firstproject`).
- Inside the folder `firstproject` create a `README.md` file which you will use as the subject content of your first project.
- After the subject content `README.md` is created, create a folder `audit` inside the `firstproject` directory.
- Inside the `audit` folder create a `README.md` that respect the audit type of file. We advise you to take an example such as the
ascii-art audit `README.md` file. Here is the [link](https://raw.githubusercontent.com/01-edu/public/master/subjects/ascii-art/audit/README.md) to the raw file.
- Once all those files are done, git push them to your new repository.
### Publish the repository on GitHub pages
- Go to the settings tab of your projects repository.
- On the option page find the GitHub Pages section.
- Please see below the settings to follow.
(Please not that it might take up to 10 mins for your page to be published)
![screenshot 1](img/adding-exercises-repository/1.png)
- You will notice that a message says Your site is published at “https://yourgithublogin.github.io/nameofyourrepo”
### Configuration of Docker image (if exercises tests need to be added)
The container runs with the following settings (options of `docker run`) :
- `--read-only`
- Mount the container's root filesystem as read only
- `--network none`
- Connect a container to a network without Internet
- `--memory 500M`
- Memory limit
- `--cpus 2.0`
- Number of CPUs
- `--user 1000:1000`
- Username or UID (format: <name|uid>[:<group|gid>])
- `--env EXERCISE=hello-world`
- Exercise name
- `--env USERNAME=aeinstein`
- Student's login
- `--env HOME=/jail`
- Home directory of the container
- `--env TMPDIR=/jail`
- Temporary directory of the container
- `--workdir /jail`
- Working directory inside the container
- `--tmpfs /jail:size=100M,noatime,exec,nodev,nosuid,uid=1000,gid=1000,nr_inodes=5k,mode=1700`
- Mount a tmpfs directory on `/jail`, 100 MB writable.
- `--volume volume_containing_student_repository:/jail/student:ro`
- Bind mount a volume containing the student repository.
Example of a [Dockerfile](https://github.com/01-edu/public/blob/master/js/tests/Dockerfile) and its [entrypoint](https://github.com/01-edu/public/blob/master/js/tests/entrypoint.sh).
## The addition of a custom project
**Take note of the paths of a project subject you added and add them to the attributes**
Example:
If user Frenchris, added an exercise to the nameofyourrepo called `firstproject`
This is the path where the README.md subject would be.
https://frenchris.github.io/nameofyourrepo/subjects/firstproject/
Note that you do not keep the README.md at the end of the path but you do keep the `/`.
This path should be added to the attribute “subject” of type string in the object attribute of the new exercise.
Additionally the README.md audit path would be.
https://frenchris.github.io/nameofyourrepo/subjects/firstproject/audit/
This path should be added to the attribute “subject” of type string in the object attribute of the new exercise.
- Once both those path are noted, create your project on your server.
- Add the regular attributes (`groupMin`, `groupMax`, `language`, `exerciseType`).
- Add the optional attributes to test if your wish (`auditsRatio`, `auditsRequired`) both set to 1.
- And add the `audit` and `subject` attributes (of type `string`) with the previously noted paths.
Now that the attributes are filled.
- Create a module, called `Div-custom` for example. Add its standard attributes.
- Add `firstproject` as a child to `Div-custom`.
**Note**: If you do not wish students from other events to be selected for matches in this new event.
in the children attributes of the module,
- Add `matchWhere` as a `FUNCTION`.
- Set its value to `USERINEVENT`.
This attribute will isole the event during matches to the user of the event.
- Add this `Div-custom` as a child in your campus object.
- Go to event, and launch the event `yourcampus/Div-custom`.
- Add yourself and other testing accounts to the newly launched event.
- Test your subject by creating a group and launching an audit
If the paths are correctly inputed and your repository is correctly publicly published on GitHub pages, you will see your subject and your audit in the platform.
## Setup of your Docker repository
1. Sign in your Docker Hub account and link it to your repository.
2. In your account, go to your settings and link your GitHub account.
3. Create a repository named “test” and make sure that your GitHub account is linked.
If you see this image,
![screenshot 2](img/adding-exercises-repository/2.png)
It means your GitHub account is correctly linked.
4. In the Builds tab configure the automated build settings as below (for the go tests).
![screenshot 3](img/adding-exercises-repository/3.png)
5. Once the build is complete (it can take 5 to 15 mins). Go back to the attributes of the exercise:
- Add the attribute **testImage (type string)**.
The `testImage` attribute is the name of the [Docker](https://docs.docker.com/get-started) image used to run the container responsible for testing the student's code.
- Fill it with the name of the repository,
**in this example: frenchris/test**
6. Once your exercise has both the attributes completed correctly, the exercise is viable and can be tested on the server which was selected for its addition.
7. As a reminder to test the exercise it is suggested to follow these steps:
- `Create` a custom `Quest-test` object
- `Adding` the new `exercise` object as a child to the newly created `Quest-test` object
- `Create` a `Piscine-test` object
- `Adding` the new `Quest-test` as a child to the newly created `Piscine-test` object
- `Adding` the `Piscine-test` to the `campus` object as **first child**
- Go to the event page and launch the newly created `Piscine-test`. (You may need to refresh the page 2-3 times before the `campus/Piscine-test` option appears)
- Once the event is launched, use the event page to add yourself as a student in the launched event `Piscine-test`
- You can now try the exercise. If everything is well set, the subject should be loaded and, when you submit a correct solution, the exercise should pass.

67
docs/ubuntu-installation.md

@ -1,67 +0,0 @@
# Ubuntu
## OS Installation
Download and boot the [latest Ubuntu release](https://releases.ubuntu.com/21.04/ubuntu-21.04-desktop-amd64.iso).
Follow the steps with these customizations:
![img1](img/ubuntu-installation/1.png)
![img2](img/ubuntu-installation/2.png)
![img3](img/ubuntu-installation/3.png)
The partitioning is:
1. 256 MB : EFI partition
2. 20 GB : system partition
![img4](img/ubuntu-installation/4.png)
![img5](img/ubuntu-installation/5.png)
Remove the installation disk and then reboot.
Skip the welcoming window.
Don't install updates if Ubuntu asks to. The scripts will.
## Admin access
You can add your public SSH key to access the administrator account later:
```shell
unset HISTFILE
sudo mkdir /root/.ssh
sudo wget github.com/xpetit.keys --output-document !$/authorized_keys
sudo chmod 400 !$
```
## OS configuration
Run a terminal and type these commands:
```shell
unset HISTFILE
sudo apt -y install git
git clone https://github.com/01-edu/public.git
public/sh/debian/ubuntu/setup.sh
```
The script will ask for student user password (which will be deleted after) and then after a long configuration process it will restart the computer.
The system is now read-only, every data is written to a temporary partition.
The session is password-less.
To gain a superuser terminal, use SSH:
```console
user@remote:~$ ssh -p512 root@IP_ADDRESS
```
To gain access with read/write access to the filesystem, use this command:
```console
root@ubuntu:~# overlayroot-chroot
INFO: Chrooting into [/media/root-ro]
root@ubuntu:/#
```

61
docs/ubuntu-persistent-installation.md

@ -1,61 +0,0 @@
# Ubuntu
## OS Installation
Install the latest version of [Virtual Box](https://www.virtualbox.org/wiki/Downloads).
> The text instructions are more important than the screenshots
Screenshots of the installation of Ubuntu in Virtual Box are [here](https://github.com/xpetit/vbox-ubuntu-install/blob/master/README.md).
Download and boot the [last Ubuntu release](http://releases.ubuntu.com/19.10/ubuntu-19.10-desktop-amd64.iso).
- Create a new virtual machine named "Ubuntu" with at least 4096 MB of RAM
- Use the fixed size storage allocation (to have more performance)
- In the settings of the VM
- System -> Motherboard : check "Enable EFI"
- System -> Processor : Select at least 2 processors
- Display -> Screen : Put "Video Memory" to the maximum
- Enable 3D acceleration
- Storage
- Remove IDE controller
- Add Optical Drive to the SATA controller
- Choose your Ubuntu ISO image
- Close the settings (click OK)
- Run the VM
Follow the screenshots (some settings can be personalized, such as keyboard layout, location, password, login automatically, but **do not change the username**)
Skip the welcoming window.
Don't install updates if Ubuntu asks to. The scripts will.
## OS customization
You can overwrite the files of the folder `system` by setting an environment variable named `OVERWRITE` with the format : `Destination folder;Git URL`.
For example to write the content of the repository [github.com/xpetit/custom](https://github.com/xpetit/custom) in the system folder :
```shell
export OVERWRITE='.;https://github.com/xpetit/custom.git'
```
## OS configuration
Run a terminal and type these commands :
```shell
unset HISTFILE
sudo apt-get -y install git
export PERSISTENT=
git clone https://github.com/01-edu/public.git
public/scripts/setup.sh
```
After reboot you should install Virtual Box additions (and reboot again) :
```shell
sudo apt -y install virtualbox-guest-x11
```
Then it is advised to use the virtual machine in full screen mode (Host key - F)

39
docs/unreal-engine-setup.md

@ -1,39 +0,0 @@
## Setup Guide
This is a guide with all steps to install the Epic Games Launcher and Unreal Engine to get ready to work.
First up you will need to register on [Epic Games](https://www.epicgames.com/id/register?redirect_uri=https%3A%2F%2Fwww.epicgames.com%2Fstore%2Fen-US%2F&client_id=875a3b57d3a640a6b7f9b4e883463ab4).
Then depending on your operating system, you will need the following steps:
### Windows
- On the [Epic Games main page](https://www.epicgames.com/store/en-US/) click on the top right corner button (`Get Epic Games`).
- A download pop up box should appear, then proceed to download the installer.
- After going through all the steps to install the Epic Games Launcher, open it and sign in using your account.
### Linux
- First of all, install `wine` to run Windows programs on Linux systems.
- If you have a 64-bit Linux system use: `sudo apt install wine64`
- If you have a 32-bit Linux system use: `sudo apt install wine32`
- Check if it is installed correctly with: `wine --version`
- Then, install `Lutris` in order to download Epic Games with the following commands:
```sh
sudo add-apt-repository ppa:lutris-team/lutris
sudo apt update
sudo apt install lutris
```
- After `Lutris` is installed, open it and on the top bar, search for `Epic Games` and you will see the result `Epic Games Store`. Go ahead and click on `install`.
- After installing it, open it and sign in with your account.
### Unreal Engine
- Once the Epic Games Launcher is opened, go to the `Unreal Engine` tab and select the Library tab.
- Click on the plus icon to add `Unreal Engine 4` and choose the version to install by clicking on the dropdown list. Then click on install.
- After installing the Unreal Engine, you can click on `Launch` and prepare for the next adventure.

19
js/tests/Dockerfile

@ -1,4 +1,21 @@
FROM node:14.16.0-alpine3.12
FROM docker.01-edu.org/alpine:3.17.0
# Installs latest Chromium package.
RUN apk add --no-cache \
chromium \
nss \
freetype \
harfbuzz \
ca-certificates \
ttf-freefont \
nodejs \
yarn
# Tell Puppeteer to skip installing Chrome. We'll be using the installed package.
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
RUN yarn add puppeteer@15.3.2
WORKDIR /app
COPY . .

45
js/tests/action-reaction-dom_test.mjs

@ -0,0 +1,45 @@
export const tests = []
tests.push(async ({ eq, page }) => {
// check the initial class name of the eye left
const eyeLeft = await page.$eval('#eye-left', (node) => node.className)
eq(eyeLeft, 'eye')
// check that the text of the button says 'close'
const buttonText = await page.$eval('button', (node) => node.textContent)
eq(buttonText, 'Click to close the left eye')
})
tests.push(async ({ eq, page }) => {
// click the button to close the left eye
const button = await page.$('button')
button.click()
// check that the class has been added
await page.waitForSelector('#eye-left.eye.eye-closed', { timeout: 150 })
// check the background color has changed
await eq.$('#eye-left.eye.eye-closed', {
style: { backgroundColor: 'black' },
})
// check that the text of the button changed to 'open'
await eq.$('button', { textContent: 'Click to open the left eye' })
})
tests.push(async ({ eq, page }) => {
// click the button a second time to open the left eye
const button = await page.$('button')
button.click()
// check that the class has been removed
await page.waitForSelector('#eye-left.eye:not(.eye-closed)', { timeout: 150 })
// check the background color has changed
await eq.$('#eye-left.eye:not(.eye-closed)', {
style: { backgroundColor: 'red' },
})
// check that the text of the button changed to 'close'
await eq.$('button', { textContent: 'Click to close the left eye' })
})

18
js/tests/bloody-sunday_test.js

@ -1,18 +0,0 @@
export const tests = []
const t = (f) => tests.push(f)
t(() => bloodySunday(new Date('0001-01-01')) === 'Monday')
t(() => bloodySunday(new Date('0001-01-02')) === 'Tuesday')
t(() => bloodySunday(new Date('0001-01-03')) === 'Wednesday')
t(() => bloodySunday(new Date('0001-01-04')) === 'Thursday')
t(() => bloodySunday(new Date('0001-01-05')) === 'Friday')
t(() => bloodySunday(new Date('0001-01-06')) === 'Saturday')
t(() => bloodySunday(new Date('0001-01-07')) === 'Monday')
t(() => bloodySunday(new Date('0001-12-01')) === 'Friday')
t(() => bloodySunday(new Date('1664-08-09')) === 'Saturday')
t(() => bloodySunday(new Date('2020-01-01')) === 'Monday')
t(() => bloodySunday(new Date('2048-12-08')) === 'Thursday')
Object.freeze(tests)

31
js/tests/bring-it-to-life-dom_test.mjs

@ -0,0 +1,31 @@
export const tests = []
tests.push(async ({ eq, page }) => {
// check the class 'eye-closed' has been added in the CSS
eq.css('.eye-closed', {
height: '4px',
padding: '0px 5px',
borderRadius: '10px',
})
})
// tests.push(async ({ eq, page }) => {
// check the class of left eye before the JS is loaded
// await page.setJavaScriptEnabled(false)
// await page.reload()
// await eq.$('p#eye-left', { className: 'eye' })
// })
tests.push(async ({ eq, page }) => {
// check the class of left eye has been updated after the JS is loaded
// await page.setJavaScriptEnabled(true)
// await page.reload()
await eq.$('p#eye-left', { className: 'eye eye-closed' })
// check the background color of left eye has changed after the JS is loaded
const eyeLeftBg = await page.$eval(
'#eye-left',
(node) => node.style.backgroundColor,
)
eq(eyeLeftBg, 'black')
})

109
js/tests/build-brick-and-break-dom_test.mjs

@ -0,0 +1,109 @@
export const tests = []
export const setup = async ({ page }) => ({
getBricksIds: async () =>
await page.$$eval('div', (nodes) =>
nodes.filter((node) => node.id.includes('brick')).map((n) => n.id),
),
})
const between = (expected, min, max) => expected >= min && expected <= max
tests.push(async ({ page, eq }) => {
// check that the brick divs are built at a regular interval of 100ms
// the average of the divs built every 100ms must be close to 10
let repeat = 0
let buildSteps = []
while (repeat < 3) {
const divs = await page.$$eval('div', (nodes) => nodes.length)
console.log(`step ${repeat + 1}: ${divs} bricks`)
buildSteps.push(divs)
await page.waitForTimeout(1000)
repeat++
}
const diff1 = buildSteps[1] - buildSteps[0]
const diff2 = buildSteps[2] - buildSteps[1]
const average = Math.round((diff1 + diff2) / 2)
if (average < 9) {
console.log('average too low --> new bricks built / sec:', average)
} else if (average > 11) {
console.log('average too high --> new bricks built / sec:', average)
} else {
console.log('good average of new bricks built / sec')
}
eq(between(average, 9, 11), between(10, 9, 11))
})
const allBricksIds = [...Array(54).keys()].map((i) => `brick-${i + 1}`)
tests.push(async ({ page, eq, ctx }) => {
// check that all the bricks are here and have the correct id
await page.waitForTimeout(3000)
const bricksIds = await ctx.getBricksIds()
eq(bricksIds, allBricksIds)
})
tests.push(async ({ page, eq }) => {
// check that the middle column bricks have the `foundation` attribute to `true`
const expectedIds = allBricksIds.filter(
(b) => b.replace('brick-', '') % 3 === 2,
)
const middleBricksIds = await page.$$eval('div', (nodes) =>
nodes
.filter((node) => node.id.includes('brick') && node.dataset.foundation)
.map((n) => n.id),
)
eq(middleBricksIds, expectedIds)
})
tests.push(async ({ page, eq }) => {
// check that the bricks to repair have the right repaired attribute
const hammer = await page.$('#hammer')
await hammer.click()
const expectedRepairedIds = await page.$eval('body', (body) => {
const getIdInt = (str) => str.replace('brick-', '')
return body.dataset.reparations
.split(',')
.sort((a, b) => getIdInt(b) - getIdInt(a))
.map((id) => {
const isMiddleBrick = getIdInt(id) % 3 === 2
const status = isMiddleBrick ? 'in progress' : 'repaired'
return `${id}_${status}`
})
})
const repairedIds = await page.$$eval('div', (nodes) => {
const getIdInt = (str) => str.replace('brick-', '')
return nodes
.filter(
(node) =>
node.dataset.repaired === 'true' ||
node.dataset.repaired === 'in progress',
)
.sort((a, b) => getIdInt(b.id) - getIdInt(a.id))
.map(({ id }) => {
const isMiddleBrick = getIdInt(id) % 3 === 2
const status = isMiddleBrick ? 'in progress' : 'repaired'
return `${id}_${status}`
})
})
eq(repairedIds, expectedRepairedIds)
})
tests.push(async ({ page, eq, getBricksIds }) => {
// check that the last brick is removed on each dynamite click
const dynamite = await page.$('#dynamite')
for (const i of allBricksIds.keys()) {
await dynamite.click()
const { length } = allBricksIds
const expectedRemainingBricks = allBricksIds.slice(0, length - (i + 1))
eq(await getBricksIds(), expectedRemainingBricks)
}
})

36
js/tests/class-that-dom_test.mjs

@ -0,0 +1,36 @@
export const tests = []
tests.push(async ({ page, eq }) => {
// check the class 'eye' has been declared properly in the CSS
eq.css('.eye', {
width: '60px',
height: '60px',
backgroundColor: 'red',
borderRadius: '50%',
})
})
tests.push(async ({ page, eq }) => {
// check the class 'arm' has been declared properly in the CSS
eq.css('.arm', { backgroundColor: 'aquamarine' })
})
tests.push(async ({ page, eq }) => {
// check the class 'leg' has been declared properly in the CSS
eq.css('.leg', { backgroundColor: 'dodgerblue' })
})
tests.push(async ({ page, eq }) => {
// check the class 'body-member' has been declared properly in the CSS
eq.css('.body-member', { width: '50px', margin: '30px' })
})
tests.push(async ({ page, eq }) => {
// check that the targetted elements have the correct class names
await eq.$('p#eye-left', { className: 'eye' })
await eq.$('p#eye-right', { className: 'eye' })
await eq.$('div#arm-left', { className: 'arm body-member' })
await eq.$('div#arm-right', { className: 'arm body-member' })
await eq.$('div#leg-left', { className: 'leg body-member' })
await eq.$('div#leg-right', { className: 'leg body-member' })
})

12
js/tests/declarations_test.js

@ -1,5 +1,13 @@
export const tests = []
const t = (f) => tests.push(f)
const isConst = (name) => {
try {
eval(`${name} = 'm'`)
return false
} catch (err) {
return true
}
}
// escapeStr
// is declared and of type string
@ -72,4 +80,8 @@ t(() => nested.obj.update === undefined)
t(() => cantEdit(() => nested.arr.push('hot stuff')))
t(() => nested.arr.length === 3)
// check if all variable are const
t(() => ['escapeStr', 'arr', 'obj', 'nested']
.every(isConst))
Object.freeze(tests)

71
js/tests/fifty-shades-of-cold-dom_test.mjs

@ -0,0 +1,71 @@
import { colors } from '../subjects/fifty-shades-of-cold/fifty-shades-of-cold.data.js'
colors.sort()
const cold = ['aqua', 'blue', 'turquoise', 'green', 'purple', 'cyan', 'navy']
const isCold = color => cold.some(coldColor => color.includes(coldColor))
const toClass = (a, b) => `.${a} { background: ${b} }`
const toDiv = (a, b) => `<div class="${a}">${b}</div>`
export const tests = []
tests.push(async ({ page, eq }) => {
// check that the css is properly generated
const style = await page.$$eval('style', nodes => nodes[1].innerHTML)
const classes = style
.split('}')
.map(s => s.replace(/(\.|{|:|;|\s+)/g, ''))
.filter(Boolean)
.sort()
for (const [i, c] of colors.entries()) {
if (!classes[i]) throw Error(`Not enough class (expected: ${c})`)
const [a, b] = classes[i].split('background')
eq(toClass(a, b), toClass(c, c))
}
})
tests.push(async ({ page, eq }) => {
// check that the divs are properly generated
const values = await page.$$eval('div', nodes =>
nodes.map(n => [n.className, n.textContent]),
)
const divs = values.map(v => toDiv(...v)).sort()
let skipped = 0
for (const [i, c] of colors.entries()) {
if (isCold(c)) {
if (!values[i - skipped]) throw Error(`Not enough div (expected: ${c})`)
eq(divs[i - skipped], toDiv(c, c))
continue
}
skipped++
if (divs.includes(toDiv(c, c))) {
throw Error(`div ${toDiv(c, c)} is not very cold`)
}
}
})
tests.push(async ({ page, eq }) => {
// test that clicking update the color accordingly
const coldColors = colors.filter(isCold)
for (const c of coldColors) {
await page.$$eval(
'div',
(nodes, c) => nodes.find(n => n.textContent === c).click(),
c,
)
const count = await page.$$eval(
'div',
(nodes, c) => nodes.filter(n => n.className === c).length,
c,
)
eq(count, coldColors.length)
}
})

46
js/tests/first-words-dom_test.mjs

@ -0,0 +1,46 @@
export const tests = []
tests.push(async ({ eq, page }) => {
// check the class words has been added in the CSS
await eq.css('.words', { textAlign: 'center', fontFamily: 'sans-serif' })
})
tests.push(async ({ eq, page }) => {
// check the torso element is initially empty
const isEmpty = await page.$eval('#torso', (node) => !node.children.length)
eq(isEmpty, true)
})
tests.push(async ({ eq, page }) => {
// click on the button
const button = await page.$('button#speak-button')
await button.click()
// check a new text element is added in the torso
const torsoChildren = await page.$eval('#torso', (node) =>
[...node.children].map((child) => ({
tag: child.tagName,
text: child.textContent,
class: child.className,
})),
)
eq(torsoChildren, [textNode])
})
tests.push(async ({ eq, page }) => {
// click a second time on the button
const button = await page.$('button#speak-button')
await button.click()
// check a second new text element is added in the torso
const torsoChildren = await page.$eval('#torso', (node) =>
[...node.children].map((child) => ({
tag: child.tagName,
text: child.textContent,
class: child.className,
})),
)
eq(torsoChildren, [textNode, textNode])
})
const textNode = { tag: 'DIV', text: 'Hello there!', class: 'words' }

135
js/tests/friend-support_test.mjs

@ -0,0 +1,135 @@
import { once } from 'node:events'
import { spawn } from 'node:child_process'
import { mkdir, writeFile, chmod } from 'fs/promises'
import { join } from 'path'
export const tests = []
const fetch = _fetch // to redefine the real fetch
const port = 5000
export const setup = async ({ randStr }) => {
const dir = '.'
await mkdir(`${dir}/guests`, { recursive: true })
const randLastName = randStr()
const createFilesIn = ({ files, dirPath }) => {
Promise.all(
files.map(([fileName, content]) =>
writeFile(`${dirPath}/${fileName}`, JSON.stringify(content)),
),
)
}
const sendRequest = async (path, options) => {
const response = await fetch(`http://localhost:${port}${path}`, options)
const { status } = response
const headers = Object.fromEntries(response.headers)
let body = ''
try {
body = await response.json()
} catch (err) {
body = err
}
return { status, body, headers }
}
const startServer = async path => {
const server = spawn('node', [`${path}`])
const message = await Promise.race([
once(server.stdout, 'data'),
Promise.race([
once(server.stderr, 'data').then(String).then(Error),
once(server, 'error'),
]).then(result => Promise.reject(result)),
])
return { server, message }
}
return { tmpPath: dir, createFilesIn, randLastName, sendRequest, startServer }
}
const isServerRunningWell = async ({ path, ctx }) => {
const { server, message } = await ctx.startServer(path)
server.kill()
return message[0].toString().includes(port)
}
const testOneGuest = async ({ path, eq, ctx, randStr }) => {
const { server } = await ctx.startServer(path)
const randMsg = randStr()
const expBody = { message: randMsg }
const files = [[`mario_${ctx.randLastName}.json`, expBody]]
const dirName = 'guests'
const dirPath = join(ctx.tmpPath, dirName)
await ctx.createFilesIn({ dirPath, files })
const { status, body, headers } = await ctx.sendRequest(
`/mario_${ctx.randLastName}`,
{
method: 'GET',
},
)
server.kill()
return eq(
{
status: status,
body: body,
contentType: headers['content-type'],
},
{
status: 200,
body: expBody,
contentType: 'application/json',
},
)
}
const testServerFail = async ({ path, eq, ctx }) => {
const { server } = await ctx.startServer(path)
await chmod(`${ctx.tmpPath}/guests/mario_${ctx.randLastName}.json`, 0)
const { status, body, headers } = await ctx.sendRequest(
`/mario_${ctx.randLastName}`,
{
method: 'GET',
},
)
server.kill()
return eq(
{
status: status,
body: body,
contentType: headers['content-type'],
},
{
status: 500,
body: { error: 'server failed' },
contentType: 'application/json',
},
)
}
const testGuestNotThere = async ({ path, eq, ctx }) => {
const { server } = await ctx.startServer(path)
const { status, body, headers } = await ctx.sendRequest('/andrea_bianchi', {
method: 'GET',
})
server.kill()
return eq(
{
status: status,
body: body,
contentType: headers['content-type'],
},
{
status: 404,
body: { error: 'guest not found' },
contentType: 'application/json',
},
)
}
tests.push(isServerRunningWell, testOneGuest, testServerFail, testGuestNotThere)
Object.freeze(tests)

147
js/tests/gatecrashers_test.mjs

@ -0,0 +1,147 @@
import { once } from 'node:events'
import { spawn } from 'node:child_process'
import { mkdir, writeFile, access } from 'fs/promises'
import { join } from 'path'
export const tests = []
const fetch = _fetch // to redefine the real fetch
const port = 5000
export const setup = async ({}) => {
const dir = '.'
await mkdir(`${dir}/guests`, { recursive: true })
const createFilesIn = ({ files, dirPath }) =>
Promise.all(
files.map(([fileName, content]) =>
writeFile(`${dirPath}/${fileName}`, JSON.stringify(content)),
),
)
const sendRequest = async (path, options) => {
const response = await fetch(`http://localhost:${port}${path}`, options)
const { status } = response
const headers = Object.fromEntries(response.headers)
let body = ''
try {
body = await response.json()
} catch (err) {
body = err
}
return { status, body, headers }
}
const sendRequestWithAuth = async (guestName, auth, body) => {
let options = {
method: 'POST',
headers: {
body: JSON.stringify(body),
},
}
if (auth.len !== 0) {
options.headers.authorization =
'Basic ' + Buffer.from(auth).toString('base64')
}
return sendRequest(guestName, options)
}
const startServer = async path => {
const server = spawn('node', [`${path}`])
const message = await Promise.race([
once(server.stdout, 'data'),
Promise.race([
once(server.stderr, 'data').then(String).then(Error),
once(server, 'error'),
]).then(result => Promise.reject(result)),
])
return { server, message }
}
return {
tmpPath: dir,
createFilesIn,
sendRequest,
sendRequestWithAuth,
startServer,
}
}
const isServerRunningWell = async ({ path, ctx }) => {
const { server, message } = await ctx.startServer(path)
server.kill()
return message[0].toString().includes(port)
}
const testGoodRequests = async ({ path, eq, fail, ctx }) => {
const expectedBody = {
answer: 'yes',
drink: 'juice',
food: 'pizza',
}
const dirName = 'guests'
const dirPath = join(ctx.tmpPath, dirName)
const { server } = await ctx.startServer(path)
const newGuestNames = ['Ana_Riber', 'Rob_Frie', 'George_Harl']
const auths = [
'Caleb_Squires:abracadabra',
'Tyrique_Dalton:abracadabra',
'Rahima_Young:abracadabra',
]
for (var i = 0; i < 3; i++) {
const { status, body, headers } = await ctx.sendRequestWithAuth(
`/${newGuestNames[i]}`,
`${auths[i]}`,
expectedBody,
)
fail(await access(`${dirPath}/${newGuestNames[i]}.json`))
eq(
{ status: status, contentType: headers['content-type'], body: body },
{ status: 200, contentType: 'application/json', body: expectedBody },
)
}
server.kill()
return true
}
const testUnauthorizedRequests = async ({ path, eq, ctx }) => {
const body = {
answer: 'yes',
drink: 'juice',
food: 'pizza',
}
const { server } = await ctx.startServer(path)
const newGuestNames = [
'Super_Mario',
'Super_Mario',
'Super_Mario',
'Super_Mario',
]
const auths = [
'',
'LetMePass',
'Rahima_Young:wrongpass',
'Anonymus:abracadabra',
]
for (var i = 0; i < 3; i++) {
const { status } = await ctx.sendRequestWithAuth(
`/${newGuestNames[i]}`,
`${auths[i]}`,
body,
)
eq({ status: status }, { status: 401 })
}
server.kill()
return true
}
tests.push(isServerRunningWell, testGoodRequests, testUnauthorizedRequests)
Object.freeze(tests)

127
js/tests/get-them-all-dom_test.mjs

@ -0,0 +1,127 @@
import { people } from './subjects/get-them-all/get-them-all.data.js'
const getIds = predicate =>
people
.filter(predicate)
.map(e => e.id)
.sort((a, b) => a.localeCompare(b))
const architects = getIds(p => p.tag === 'a')
const notArchitects = getIds(p => p.tag !== 'a')
const classical = getIds(p => p.classe === 'classical')
const notClassical = getIds(p => p.tag === 'a' && p.classe !== 'classical')
const active = getIds(p => p.classe === 'classical' && p.active)
const notActive = getIds(
p => p.tag === 'a' && p.classe === 'classical' && p.active === false,
)
const bonanno = people.find(p => p.id === 'BonannoPisano').id
const notBonanno = getIds(
p =>
p.tag === 'a' &&
p.classe === 'classical' &&
p.active &&
p.id !== 'BonannoPisano',
)
export const tests = []
tests.push(async ({ eq, page }) => {
// get architects
const btnArchitect = await page.$(`#btnArchitect`)
btnArchitect.click()
await page.waitForTimeout(150)
const selected = await page.$$eval('a', nodes =>
nodes
.filter(node => node.textContent === 'Architect')
.map(node => node.id)
.sort((a, b) => a.localeCompare(b)),
)
eq(selected, architects)
const eliminated = await page.$$eval('span', nodes =>
nodes
.filter(node => node.style.opacity === '0.2')
.map(node => node.id)
.sort((a, b) => a.localeCompare(b)),
)
eq(eliminated, notArchitects)
})
tests.push(async ({ page, eq }) => {
// get classical
const btnClassical = await page.$(`#btnClassical`)
btnClassical.click()
await page.waitForTimeout(150)
const selected = await page.$$eval('.classical', nodes =>
nodes
.filter(node => node.textContent === 'Classical')
.map(node => node.id)
.sort((a, b) => a.localeCompare(b)),
)
eq(selected, classical)
const eliminated = await page.$$eval('a:not(.classical)', nodes =>
nodes
.filter(node => node.style.opacity === '0.2')
.map(node => node.id)
.sort((a, b) => a.localeCompare(b)),
)
eq(eliminated, notClassical)
})
tests.push(async ({ page, eq }) => {
// check active
const btnActive = await page.$(`#btnActive`)
btnActive.click()
await page.waitForTimeout(150)
const selected = await page.$$eval('.classical.active', nodes =>
nodes
.filter(node => node.textContent === 'Active')
.map(node => node.id)
.sort((a, b) => a.localeCompare(b)),
)
eq(selected, active)
const eliminated = await page.$$eval('.classical:not(.active)', nodes =>
nodes
.filter(node => node.style.opacity === '0.2')
.map(node => node.id)
.sort((a, b) => a.localeCompare(b)),
)
eq(eliminated, notActive)
})
tests.push(async ({ page, eq }) => {
// get bonanno
const btnBonanno = await page.$(`#btnBonanno`)
btnBonanno.click()
await page.waitForTimeout(150)
const selected = await page.$eval('#BonannoPisano', node => {
if (node.textContent === 'Bonanno Pisano') return node.id
})
eq(`bonanno: ${selected}`, `bonanno: ${bonanno}`)
const eliminated = await page.$$eval(
'a.classical.active:not(#BonannoPisano)',
nodes =>
nodes
.filter(node => node.style.opacity === '0.2')
.map(node => node.id)
.sort((a, b) => a.localeCompare(b)),
)
eq(eliminated, notBonanno)
})

123
js/tests/gossip-grid-dom_test.mjs

@ -0,0 +1,123 @@
import { gossips } from './subjects/gossip-grid/gossip-grid.data.js'
export const tests = []
tests.push(async ({ page, eq }) => {
// test that the grid is properly generated
const content = await page.$$eval('.gossip', nodes => nodes.map(n => n.textContent))
eq(content, ['Share gossip!', ...gossips])
})
tests.push(async ({ page, eq }) => {
// test that you can add a gossip
const rand = Math.random().toString(36).slice(2)
await page.type('textarea', `coucou ${rand}`)
await page.click('.gossip button')
const content = await page.$eval('div.gossip', n => n.textContent)
eq(content, `coucou ${rand}`)
})
const getStyle = (nodes, key) => nodes.map(n => n.style[key])
tests.push(async ({ page, eq }) => {
// test that you can change the width to the min
const min = await page.$eval('#width', n => {
n.value = n.min
n.dispatchEvent(new Event('input'))
return Number(n.min)
})
eq(min, 200)
const values = await page.$$eval('div.gossip', getStyle, 'width')
eq(Array(gossips.length + 1).fill(`${min}px`), values)
})
tests.push(async ({ page, eq }) => {
// test that you can change the width to the max
const max = await page.$eval('#width', n => {
n.value = n.max
n.dispatchEvent(new Event('input'))
return Number(n.max)
})
eq(max, 800)
const values = await page.$$eval('div.gossip', getStyle, 'width')
eq(Array(gossips.length + 1).fill(`${max}px`), values)
})
tests.push(async ({ page, eq }) => {
// test that you can change the font-size to the min
const min = await page.$eval('#fontSize', n => {
n.value = n.min
n.dispatchEvent(new Event('input'))
return Number(n.min)
})
eq(min, 20)
const values = await page.$$eval('div.gossip', getStyle, 'fontSize')
eq(Array(gossips.length + 1).fill(`${min}px`), values)
})
tests.push(async ({ page, eq }) => {
// test that you can change the font-size to the max
const max = await page.$eval('#fontSize', n => {
n.value = n.max
n.dispatchEvent(new Event('input'))
return Number(n.max)
})
eq(max, 40)
const values = await page.$$eval('div.gossip', getStyle, 'fontSize')
eq(Array(gossips.length + 1).fill(`${max}px`), values)
})
const getBackground = (nodes, key) => nodes.map(n => n.style.background || n.style.backgroundColor)
tests.push(async ({ page, eq, rgbToHsl }) => {
// test that you can change the background to the darkest
const min = await page.$eval('#background', n => {
n.value = n.min
n.dispatchEvent(new Event('input'))
return Number(n.min)
})
eq(min, 20)
const values = await page.$$eval('div.gossip', getBackground)
const lightness = values.map(rgbToHsl).map(([h,s,l]) => l)
eq(Array(gossips.length + 1).fill(min), lightness)
})
tests.push(async ({ page, eq, rgbToHsl }) => {
// test that you can change the background to the darkest
const max = await page.$eval('#background', n => {
n.value = n.max
n.dispatchEvent(new Event('input'))
return Number(n.max)
})
eq(max, 75)
const values = await page.$$eval('div.gossip', getBackground)
const lightness = values.map(rgbToHsl).map(([h,s,l]) => Math.round(l))
eq(Array(gossips.length + 1).fill(max), lightness)
})

67
js/tests/harder-bigger-bolder-stronger-dom_test.mjs

@ -0,0 +1,67 @@
export const tests = []
export const setup = async ({ page }) => ({
content: await page.$$eval('div', nodes => nodes.map(n => ({
text: n.textContent,
size: Number((n.style.fontSize || '').slice(0, -2)),
weight: Number(n.style.fontWeight),
})))
})
tests.push(({ eq, ctx }) => {
// should contain 120 items
eq(ctx.content.length, 120)
})
tests.push(({ eq, ctx }) => {
// ctx.content should only be one letter long
eq(ctx.content.reduce((total, { text }) => total + text.length, 0), 120)
})
tests.push(({ eq, ctx }) => {
// we expect random to yield at least 10 different letters
eq(new Set(ctx.content).size > 10, true)
})
tests.push(({ eq, ctx }) => {
// only letters from 'A' to 'Z'
eq(ctx.content.every(({ text }) => text >= 'A' && text <= 'Z'), true)
})
tests.push(({ eq, ctx }) => {
// letter size should grow
// first should be 11
eq(ctx.content[0].size, 11)
// last should be 120
eq(ctx.content[119].size, 130)
// each letter should be bigger than the previous
let prev = 0
for (const { size } of ctx.content) {
if (prev >= size) {
throw Error('Letters should grow')
}
}
})
tests.push(({ eq, ctx }) => {
// letter weight should increase in thirds
const third = n => ({ weight }) => weight === n
// first third should be 300
eq(ctx.content[0].weight, 300)
eq(ctx.content[39].weight, 300)
eq(ctx.content.slice(0, 40).every(third(300)), true)
// second third should be 400
eq(ctx.content[40].weight, 400)
eq(ctx.content[79].weight, 400)
eq(ctx.content.slice(40, 80).every(third(400)), true)
// last third should be 600
eq(ctx.content[80].weight, 600)
eq(ctx.content[119].weight, 600)
eq(ctx.content.slice(80).every(third(600)), true)
})

18
js/tests/hello-there-editor.json

@ -0,0 +1,18 @@
[
{
"description": "Log a number in the console",
"code": "// If you see this code, it means that you failed the first tests.\n// each tests have it's own code to be tested that will appear if\n// your solution doesn't pass it, it is not here to help you.\n// While sometimes it may clarify the instructions\n// this specific test is complex and will most likely confuse you.\n\n// This is to save all the values that you console.log'd\nconst args = saveArguments(console, 'log')\n\n// This comment below will be replaced by your code\n// Your code\n\n// This is where we check that the value are expected.\n// It's pretty advanced code, you don't have to understand it\n// Do not try to use it for the solution, it will not help you.\nconst typeOfLoggedValues = args.flat().map((v) => typeof v)\nif (!typeOfLoggedValues.includes('number')) {\n // this is where we create the error message you see:\n throw Error('you must log a number')\n // that's what you should focus on trying to understand\n // the message, not `throw` or `Error` don't worry about\n // that, worry about showing a number in the console !\n}"
},
{
"description": "Log a boolean in the console",
"code": "const args = saveArguments(console, 'log')\n\n// Your code\n\nconst typeOfLoggedValues = args.flat().map((v) => typeof v)\nif (!typeOfLoggedValues.includes('boolean')) {\n throw Error('you must log a boolean')\n}"
},
{
"description": "Log a string in the console",
"code": "const args = saveArguments(console, 'log')\n\n// Your code\n\nconst typeOfLoggedValues = args.flat().map((v) => typeof v)\nif (!typeOfLoggedValues.includes('string')) {\n throw Error('you must log a string')\n}"
},
{
"description": "Log the string Hello There ! in the console",
"code": "const args = saveArguments(console, 'log')\n\n// Your code\n\nconst loggedValues = args.flat().join(' ')\nif (!loggedValues.includes('Hello There !')) {\n throw Error('you must log the text Hello There !')\n}"
}
]

23
js/tests/hello-there_test.js

@ -1,23 +0,0 @@
import { readFileSync as read } from 'fs'
// /*/ // ⚡
export const tests = [
({ eq, path }) => // code must use console.log
read(path, 'utf8').trim().includes('console.log'),
async ({ eq, code }) => {
// console.log must have been called with the right value
const log = console.log.bind(console)
const args = []
console.log = (..._args) => {
args.push(..._args)
log(..._args)
}
const b64 = Buffer.from(code).toString("base64")
const url = `data:text/javascript;base64,${b64}`
await import(url)
console.log = log
return eq(args.join(' ').trim(), 'Hello There')
},
]

56
js/tests/keycodes-symphony-dom_test.mjs

@ -0,0 +1,56 @@
export const tests = []
export const setup = async () => {
const getNotes = async (page) =>
await page.$$eval('.note', (nodes) => {
return nodes.map((note) => note.textContent)
})
return { getNotes }
}
const characters = `didyouhandlethekeydowneventcorrectly`
tests.push(async ({ page, eq, ctx }) => {
// check that a note is created and matches the right letter when a key is pressed
for (const [i, character] of characters.split('').entries()) {
await page.keyboard.down(character)
const typed = characters.slice(0, i + 1).split('')
eq(await ctx.getNotes(page), typed)
}
})
tests.push(async ({ page, eq, ctx }) => {
// check that the last note is removed when Backspace key is pressed
let step = 1
while (step < 10) {
await page.keyboard.down('Backspace')
const typed = characters.slice(0, characters.length - step).split('')
eq(await ctx.getNotes(page), typed)
step++
}
})
tests.push(async ({ page, eq, ctx }) => {
// check that all the notes are cleared when Escape key is pressed
await page.keyboard.down('Escape')
const cleared = (await ctx.getNotes(page)).length === 0
eq(cleared, true)
})
tests.push(async ({ page, eq }) => {
// check that notes have different background colors
const test = 'abcdefghijklmnopqrstuvwxyz'
let step = 0
while (step < test.length) {
await page.keyboard.down(test[step])
step++
}
const getNotesBg = await page.$$eval('.note', (nodes) => {
return nodes.map((note) => note.style.backgroundColor)
})
const colors = [...new Set(getNotesBg)]
const allDifferent = colors.length === test.length
eq(allDifferent, true)
})

122
js/tests/mouse-trap-dom_test.mjs

@ -0,0 +1,122 @@
export const tests = []
export const setup = async ({ page }) => ({
getCirclesPos: () =>
page.$$eval('.circle', nodes => {
const circleRadius = 25
const formatPos = pos => Number(pos.replace('px', '')) + circleRadius
return nodes.map(node => [
formatPos(node.style.left),
formatPos(node.style.top),
])
}),
})
tests.push(async ({ page, eq, ctx }) => {
// check that a circle is created on click at the mouse position
const { width, height } = await page.evaluate(() => ({
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
}))
const clicks = [...Array(10).keys()].map(e => [random(width), random(height)])
for (const [i, click] of clicks.entries()) {
const [posX, posY] = click
await page.mouse.click(posX, posY)
const currentCircle = (await ctx.getCirclesPos())[i]
eq(currentCircle, click)
}
})
tests.push(async ({ page, eq, ctx }) => {
// check that the last created circle moves along the mouse
let move = 0
while (move < 100) {
move++
const x = move
const y = move * 2
await page.mouse.move(x, y)
const circles = await ctx.getCirclesPos()
const currentCirclePos = circles[circles.length - 1]
eq(currentCirclePos, [x, y])
}
})
tests.push(async ({ page, eq, ctx }) => {
// check that a circle is trapped and purple when inside the box
const box = await page.$eval('.box', box => ({
top: box.getBoundingClientRect().top,
right: box.getBoundingClientRect().right,
left: box.getBoundingClientRect().left,
bottom: box.getBoundingClientRect().bottom,
}))
await page.mouse.click(200, 200)
let move = 200
let hasEntered = false
while (move < 500) {
const x = move + 50
const y = move
await page.mouse.move(x, y)
const circles = await ctx.getCirclesPos()
const currentCircle = circles[circles.length - 1]
const circleRadius = 25
const bg = await page.$$eval(
'.circle',
nodes => nodes[nodes.length - 1].style.background,
)
const insideX = x > box.left + circleRadius && x < box.right - circleRadius
const insideY = y > box.top + circleRadius && y < box.bottom - circleRadius
const isInside = insideX && insideY
// check that the background is set to the right color
if (isInside) {
hasEntered = true
eq(bg, 'var(--purple)')
} else {
eq(bg, hasEntered ? 'var(--purple)' : 'white')
}
// check that the mouse is trapped inside the box
if (hasEntered) {
if (insideY) {
eq(currentCircle[1], y)
} else {
const maxY =
currentCircle[1] === box.top + circleRadius + 1 ||
currentCircle[1] === box.top + circleRadius ||
currentCircle[1] === box.bottom - circleRadius ||
currentCircle[1] === box.bottom - circleRadius - 1
eq(maxY, true)
}
if (insideX) {
eq(currentCircle[0], x)
} else {
const maxX =
currentCircle[0] === box.left + circleRadius ||
currentCircle[0] === box.left + circleRadius + 1 ||
currentCircle[0] === box.right - circleRadius ||
currentCircle[0] === box.right - circleRadius - 1
eq(maxX, true)
}
}
move++
}
})
const random = (min, max) => {
if (!max) {
max = min
min = 0
}
min = Math.ceil(min)
max = Math.floor(max)
return Math.floor(Math.random() * (max - min + 1)) + min
}

90
js/tests/nesting-organs-dom_test.mjs

@ -0,0 +1,90 @@
export const tests = []
tests.push(async ({ page, eq }) => {
// check that the HTML structure is correct & elements are nested properly
const elements = await page.$$eval('body', (nodes) => {
const toNode = (el) => {
const node = {}
node.tag = el.tagName.toLowerCase()
node.id = el.id
if (el.children.length) {
node.children = [...el.children].map(toNode)
}
return node
}
return [...nodes[0].children].map(toNode)
})
eq(expectedStructure, elements)
})
tests.push(async ({ page, eq }) => {
// check the section selector style has been updated properly
eq.css('section', {
display: 'flex',
justifyContent: 'center',
})
})
tests.push(async ({ page, eq }) => {
// check if the provided CSS has been correctly copy pasted
eq.css('div, p', {
border: '1px solid black',
padding: '10px',
margin: '0px',
borderRadius: '30px',
})
eq.css('#face', { alignItems: 'center' })
eq.css('#eyes', {
display: 'flex',
backgroundColor: 'yellow',
justifyContent: 'space-between',
alignItems: 'center',
borderRadius: '50px',
width: '200px',
})
eq.css('#torso', {
width: '200px',
backgroundColor: 'violet',
})
})
const expectedStructure = [
{
tag: 'section',
id: 'face',
children: [
{
tag: 'div',
id: 'eyes',
children: [
{ tag: 'p', id: 'eye-left' },
{ tag: 'p', id: 'eye-right' },
],
},
],
},
{
tag: 'section',
id: 'upper-body',
children: [
{ tag: 'div', id: 'arm-left' },
{ tag: 'div', id: 'torso' },
{ tag: 'div', id: 'arm-right' },
],
},
{
tag: 'section',
id: 'lower-body',
children: [
{ tag: 'div', id: 'leg-left' },
{ tag: 'div', id: 'leg-right' },
],
},
]

110
js/tests/pick-and-click-dom_test.mjs

@ -0,0 +1,110 @@
export const tests = []
const between = (expected, min, max) => expected >= min && expected <= max
export const setup = async ({ page, rgbToHsl }) => ({
bodyBgRgb: async () =>
rgbToHsl(await page.$eval('body', (body) => body.style.background)),
})
tests.push(async ({ page, eq }) => {
// check that the background color is changing on mouse move
// by simulating 20 moves, so there must be 20 different background colors
let move = 50
let bgs = []
while (move < 250) {
move += 10
const x = move
const y = move * 2
await page.mouse.move(x, y)
const bodyBg = await page.$eval('body', (body) => body.style.background)
const validColor = bodyBg.includes('rgb')
if (!validColor) continue
bgs.push(bodyBg)
}
const differentBgs = [...new Set(bgs)].length
eq(differentBgs, 20)
})
const near = (a, b) => a < b + 2.5 && a > b - 2.5
const numVal = (n) => n.textContent.replace(/[^0-9,]/g, '')
const generateCoords = (random) => [
[random(125, 500), random(125, 400)],
[random(125, 500), random(125, 400)],
[random(125, 500), random(125, 400)],
]
tests.push(async ({ page, eq, bodyBgRgb, random }) => {
// check that the hsl value displayed matches the current background color
for (const move of generateCoords(random)) {
await page.mouse.move(...move)
const a = await bodyBgRgb()
const b = (await page.$eval('.hsl', numVal)).split(',')
if (a.every((v, i) => near(v, Number(b[i])))) continue
throw Error(`hsl(${a.map(Math.round)}) to far from hsl(${b})`)
}
})
tests.push(async ({ page, eq, bodyBgRgb, random }) => {
// check that the hue value displayed matches the current background color
for (const move of generateCoords(random)) {
await page.mouse.move(...move)
const [h] = await bodyBgRgb()
const hue = await page.$eval('.hue', numVal)
if (!near(h, Number(hue))) {
console.log({ h, hue, c: near(h, Number(hue)) })
throw Error(`hue ${Math.round(h)} to far from ${hue}`)
}
}
})
tests.push(async ({ page, eq, bodyBgRgb, random }) => {
// check that the luminosity value displayed matches the current background color
for (const move of generateCoords(random)) {
await page.mouse.move(...move)
const [, , l] = await bodyBgRgb()
const lum = await page.$eval('.luminosity', numVal)
if (!near(l, Number(lum))) {
throw Error(`luminosity ${Math.round(l)} to far from ${lum}`)
}
}
})
tests.push(async ({ page, eq, bodyBgRgb, random }) => {
// check that the hsl value is copied in the clipboard on click
// Override readText if writeText is used due to a puppeteer bug
await page.evaluate(() => {
window.navigator.clipboard.writeText = async (text) => {
window.navigator.clipboard.readText = async () => text
}
})
for (const move of generateCoords(random)) {
await page.mouse.click(...move)
const clipboard = await page.evaluate(() =>
window.navigator.clipboard.readText()
)
const hslValue = await page.$eval('.hsl', (hsl) => hsl.textContent)
eq(hslValue, clipboard)
}
})
tests.push(async ({ page, eq, bodyBgRgb, random }) => {
// check that each svg axis is following the mouse
const [[mouseX, mouseY]] = generateCoords(random)
await page.mouse.move(mouseX, mouseY)
const axisX = await page.$eval('#axisX', (line) => [
line.getAttribute('x1'),
line.getAttribute('x2'),
])
const axisY = await page.$eval('#axisY', (line) => [
line.getAttribute('y1'),
line.getAttribute('y2'),
])
const checkAxisCoords = (coords) => Number([...new Set(coords)].join())
eq(checkAxisCoords(axisX), mouseX)
eq(checkAxisCoords(axisY), mouseY)
})

36
js/tests/pimp-my-style-dom_test.mjs

@ -0,0 +1,36 @@
import { styles } from './subjects/pimp-my-style/pimp-my-style.data.js'
export const tests = []
const formatClass = (limit, unpimp) =>
['button', ...styles.slice(0, limit), unpimp && 'unpimp'].filter(Boolean)
const max = styles.length - 1
export const setup = async ({ page }) => {
const btn = await page.$('.button')
return {
btn,
getClass: async () =>
(await (await btn.getProperty('className')).jsonValue()).split(' '),
}
}
tests.push(async ({ page, eq, btn, getClass }) => {
// pimp
for (const i of styles.keys()) {
console.log('pimp click', i + 1)
await btn.click()
eq(formatClass(i + 1, i === max), await getClass())
}
})
tests.push(async ({ page, eq, btn, getClass }) => {
// unpimp !
for (const i of styles.keys()) {
console.log('unpimp click', i + 1)
await btn.click()
eq(formatClass(max - i, i !== max), await getClass())
}
})

13
js/tests/primitives_test.js

@ -1,5 +1,14 @@
export const tests = []
const isConst = (name) => {
try {
eval(`${name} = 'm'`)
return false
} catch (err) {
return true
}
}
const t = (f) => tests.push(f)
// str is declared and of type string
t(() => typeof str === 'string')
@ -12,4 +21,8 @@ t(() => typeof bool === 'boolean')
// undef is declared and of type undefined
t(() => undef === undefined)
// check if all variables are const
t(() => ['str', 'num', 'bool', 'undef']
.every(isConst))
Object.freeze(tests)

1
js/tests/race_test.js

@ -1,4 +1,3 @@
Promise.race = undefined
// /*/ // ⚡
export const tests = []
const t = (f) => tests.push(f)

49
js/tests/select-and-style-dom_test.mjs

@ -0,0 +1,49 @@
export const tests = []
// this test is commented out because it will not work for editor mode
// tests.push(async ({ eq }) => {
// // check the CSS stylesheet is linked in the head tag
//
// await eq.$('head link', {
// rel: 'stylesheet',
// href: 'http://localhost:9898/select-and-style/select-and-style.css',
// })
// })
tests.push(async ({ eq }) => {
// check the universal selector has been declared properly
await eq.css('*', {
margin: '0px',
opacity: '0.85',
boxSizing: 'border-box',
})
})
tests.push(async ({ eq }) => {
// check that the body was styled
await eq.css('body', { height: '100vh' })
})
tests.push(async ({ eq }) => {
// check that sections elements are styled
await eq.css('section', {
padding: '20px',
width: '100%',
height: 'calc(33.3333%)',
})
})
tests.push(async ({ eq }) => {
// check that the individual sections are styled
await eq.css('#face', { backgroundColor: 'cyan' })
await eq.css('#upper-body', { backgroundColor: 'blueviolet' })
await eq.css('#lower-body', { backgroundColor: 'lightsalmon' })
})

25
js/tests/skeleton-dom_test.mjs

@ -0,0 +1,25 @@
export const tests = []
tests.push(async ({ page, eq }) => {
// check that the title tag is present & is set with some text
const title = await page.$eval('title', (node) => node.textContent)
if (!title.length) throw Error('missing title')
})
tests.push(async ({ page, eq }) => {
// check the face
return eq.$('section:nth-child(1)', { textContent: 'face' })
})
tests.push(async ({ page, eq }) => {
// check the upper-body
return eq.$('section:nth-child(2)', { textContent: 'upper-body' })
})
tests.push(async ({ page, eq }) => {
// check the lower-body, my favorite part
return eq.$('section:nth-child(3)', { textContent: 'lower-body' })
})

18
js/tests/sunny-sunday_test.js

@ -0,0 +1,18 @@
export const tests = []
const t = (f) => tests.push(f)
t(() => sunnySunday(new Date('0001-01-01')) === 'Monday')
t(() => sunnySunday(new Date('0001-01-02')) === 'Tuesday')
t(() => sunnySunday(new Date('0001-01-03')) === 'Wednesday')
t(() => sunnySunday(new Date('0001-01-04')) === 'Thursday')
t(() => sunnySunday(new Date('0001-01-05')) === 'Friday')
t(() => sunnySunday(new Date('0001-01-06')) === 'Saturday')
t(() => sunnySunday(new Date('0001-01-07')) === 'Monday')
t(() => sunnySunday(new Date('0001-12-01')) === 'Friday')
t(() => sunnySunday(new Date('1664-08-09')) === 'Saturday')
t(() => sunnySunday(new Date('2020-01-01')) === 'Monday')
t(() => sunnySunday(new Date('2048-12-08')) === 'Thursday')
Object.freeze(tests)

164
js/tests/test.mjs

@ -1,10 +1,14 @@
import puppeteer from 'puppeteer'
import { join as joinPath, dirname, extname } from 'path'
import { fileURLToPath } from 'url'
import { readFile, writeFile } from 'fs/promises'
import { deepStrictEqual } from 'assert'
import * as fs from 'fs'
const { readFile, writeFile } = fs.promises
import { fileURLToPath } from 'url'
import { tmpdir } from 'os'
import http from 'http'
import fs from 'fs'
global.window = global
global._fetch = fetch
global.fetch = url => {
// this is a fake implementation of fetch for the tester
// -> refer to https://devdocs.io/javascript/global_objects/fetch
@ -21,6 +25,12 @@ global.fetch = url => {
const wait = delay => new Promise(s => setTimeout(s, delay))
const fail = fn => { try { fn() } catch (err) { return true } }
const upperFirst = (str) => str[0].toUpperCase() + str.slice(1)
const randStr = (n = 7) => Math.random().toString(36).slice(2, n)
const between = (min, max) => {
max || (max = min, min = 0)
return Math.floor(Math.random() * (max - min) + min)
}
const props = [String,Array]
.flatMap(({ prototype }) =>
@ -38,6 +48,8 @@ const eq = (a, b) => {
}
const [solutionPath, name] = process.argv.slice(2)
const tools = { eq, fail, wait, randStr, between, upperFirst }
const fatal = (...args) => {
console.error(...args)
process.exit(1)
@ -75,7 +87,7 @@ const any = arr =>
f(firstError)
})
const testNode = async ({ name }) => {
const testNode = async () => {
const path = `${solutionPath}/${name}.mjs`
return {
path,
@ -84,7 +96,7 @@ const testNode = async ({ name }) => {
}
}
const runInlineTests = async ({ json, name }) => {
const runInlineTests = async ({ json }) => {
const restore = new Set()
const equal = deepStrictEqual
const saveArguments = (src, key) => {
@ -103,12 +115,11 @@ const runInlineTests = async ({ json, name }) => {
const logs = []
console.log = (...args) => logs.push(args)
const die = (...args) => {
logs.forEach((args) => console.info(...args))
console.error(...args)
process.exit(1)
logs.forEach((logArgs) => console.info(...logArgs))
fatal(...args)
}
const solution = await loadAndSanitizeSolution(name)
const solution = await loadAndSanitizeSolution()
for (const { description, code } of JSON.parse(json)) {
logs.length = 0
const [provided, tests] = code.includes('// Your code')
@ -130,14 +141,15 @@ ${tests.trim()}`.trim()
console.info(`${description}:`, 'PASS')
} catch (err) {
console.info(`${description}:`, 'FAIL')
console.info(`\n======= Code ======= \n${fullCode}`)
console.info('\n======= Error ======')
die(' ->', err.message)
console.info(' ->', err.message, '\n')
console.info('\n======= Code =======')
die(fullCode)
}
}
}
const loadAndSanitizeSolution = async name => {
const loadAndSanitizeSolution = async () => {
const path = `${solutionPath}/${name}.js`
const rawCode = await read(path, "student solution")
@ -151,18 +163,15 @@ const loadAndSanitizeSolution = async name => {
const runTests = async ({ url, path, code }) => {
const { setup, tests } = await import(url).catch(err =>
fatal(`Unable to execute ${name} solution, error:\n${stackFmt(err, url)}`),
fatal(`Unable to execute ${name}, error:\n${stackFmt(err, url)}`),
)
const randStr = (n = 7) => Math.random().toString(36).slice(2, n)
const between = (min, max) => {
max || (max = min, min = 0)
return Math.floor(Math.random() * (max - min) + min)
}
const upperFirst = (str) => str[0].toUpperCase() + str.slice(1)
const tools = { eq, fail, wait, code, path, randStr, between, upperFirst }
Object.assign(tools, { code, path })
tools.ctx = (await (setup && setup(tools))) || {}
const isDOM = name.endsWith('-dom')
if (isDOM) {
Object.assign(tools, await prepareForDOM({ code }))
}
let timeout
for (const [i, t] of tests.entries()) {
try {
@ -171,20 +180,108 @@ const runTests = async ({ url, path, code }) => {
new Promise((s, f) => {
timeout = setTimeout(f, 60000, Error('Time limit reached (1min)'))
}),
])
if (!(await waitWithTimeout)) {
])
if (!(await waitWithTimeout) && !isDOM) {
throw Error('Test failed')
}
} catch (err) {
console.log(`test #${i+1} failed:\n${t.toString()}\n\nError:`)
console.info(`test #${i+1} failed:\n${t.toString()}\n`)
fatal(stackFmt(err, url))
} finally {
clearTimeout(timeout)
}
}
console.log(`${name} passed (${tests.length} tests)`)
console.info(`${name} passed (${tests.length} tests)`)
}
// add puppeteer tests as JS language:
const PORT = 9898
const config = {
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
// This will write shared memory files into /tmp instead of /dev/shm,
// because Docker’s default for /dev/shm is 64MB
'--disable-dev-shm-usage',
],
headless: !process.env.DEBUG_PUPPETTEER,
}
// LEGACY random, use between instead (only used by dom exercise, to be replaced)
const random = (min, max = min) => {
max === min && (min = 0)
min = Math.ceil(min)
return Math.floor(Math.random() * (Math.floor(max) - min + 1)) + min
}
const rgbToHsl = rgbStr => {
const [r, g, b] = rgbStr.slice(4, -1).split(',').map(Number)
const max = Math.max(r, g, b)
const min = Math.min(r, g, b)
const l = (max + min) / ((0xff * 2) / 100)
if (max === min) return [0, 0, l]
const d = max - min
const s = (d / (l > 50 ? 0xff * 2 - max - min : max + min)) * 100
if (max === r) return [((g - b) / d + (g < b && 6)) * 60, s, l]
return max === g
? [((b - r) / d + 2) * 60, s, l]
: [((r - g) / d + 4) * 60, s, l]
}
const prepareForDOM = ({ code }, server) => new Promise((s, f) => (server = http
.createServer(({ url, method }, response) => {
console.info(method + ' ' + url)
// Loading either the `index.html` or the js code (student solution)
response.setHeader('Content-Type', 'text/html')
return response.end(`<script type="module">${code}</script>`)
}))
.listen(PORT, async listenErr => {
if (listenErr) return f(listenErr)
try {
const browser = await puppeteer.launch(config)
const [page] = await browser.pages()
await page.goto(`http://localhost:${PORT}/index.html`)
deepStrictEqual.$ = async (selector, props) => {
const keys = Object.keys(props)
const extractProps = (node, props) => {
const fromProps = (a, b) => Object.fromEntries(Object.keys(b).map(k => [
k,
typeof b[k] === 'object' ? fromProps(a[k], b[k]) : a[k],
]))
return fromProps(node, props)
}
const domProps = await page.$eval(selector, extractProps, props)
return deepStrictEqual(props, domProps)
}
deepStrictEqual.css = async (selector, props) => {
const cssProps = await page.evaluate((selector, props) => {
const styles = Object.fromEntries([...document.styleSheets]
.flatMap(({ cssRules }) => [...cssRules].map(r => [r.selectorText, r.style])))
if (!styles[selector]) {
throw Error(`css ${selector} did not match any declarations`)
}
return Object.fromEntries(Object.keys(props).map(k => [k, styles[selector][k]]))
}, selector, props)
return deepStrictEqual(props, cssProps)
}
browser
.defaultBrowserContext()
.overridePermissions(`http://localhost:${PORT}`, ['clipboard-read'])
s({ page, browser, random, rgbToHsl, eq: deepStrictEqual, server })
} catch (err) {
f(err)
}
}))
const main = async () => {
const { test, mode } = await any([
readTest(joinPath(root, `${name}.json`)),
@ -192,19 +289,22 @@ const main = async () => {
readTest(joinPath(root, `${name}_test.mjs`)),
]).catch(ifNoEnt((err) => fatal(`Missing test for ${name}`)))
if (mode === "node") return runTests(await testNode({ test, name }))
if (mode === "inline") return runInlineTests({ json: test, name })
if (mode === "node") return runTests(await testNode())
if (mode === "inline") return runInlineTests({ json: test })
const { rawCode, code, path } = await loadAndSanitizeSolution(name)
const { rawCode, code, path } = await loadAndSanitizeSolution()
const parts = test.split("// /*/ // ⚡")
const [inject, testCode] = parts.length < 2 ? ["", test] : parts
const combined = `${inject.trim()}\n${rawCode
.replace(inject.trim(), "")
.trim()}\n${testCode.trim()}\n`
.trim()}\n;${testCode.trim()}\n`
const b64 = Buffer.from(combined).toString("base64")
const url = `data:text/javascript;base64,${b64}`
const url = `${tmpdir()}/${name}.mjs`
await writeFile(url, combined)
return runTests({ path, code, url })
}
main().catch(err => fatal(err.stack))
main().then(
() => process.exit(0),
err => fatal(err?.stack || Error('').stack),
)

19
js/tests/the-calling-dom_test.mjs

@ -0,0 +1,19 @@
export const tests = []
tests.push(async ({ page, eq }) => {
// check the face
return eq.$('section#face', { textContent: '' })
})
tests.push(async ({ page, eq }) => {
// check the upper-body
return eq.$('section#upper-body', { textContent: '' })
})
tests.push(async ({ page, eq }) => {
// check the lower-body, my favorite part
return eq.$('section#lower-body', { textContent: '' })
})

197
js/tests/uninvited_test.mjs

@ -0,0 +1,197 @@
import { once } from 'node:events'
import { spawn } from 'node:child_process'
import { mkdir, writeFile, chmod } from 'fs/promises'
import { join } from 'path'
import fs from 'node:fs/promises'
export const tests = []
const fetch = _fetch // to redefine the real fetch
const port = 5000
export const setup = async ({ randStr }) => {
const dir = '.'
await mkdir(`${dir}/guests`, { recursive: true })
const randomName = randStr()
const createFilesIn = ({ files, dirPath }) => {
Promise.all(
files.map(([fileName, content]) =>
writeFile(`${dirPath}/${fileName}`, JSON.stringify(content), {
flag: 'wx',
}),
),
).catch(reason => console.log(reason))
return true
}
const sendRequest = async (path, options) => {
const response = await fetch(`http://localhost:${port}${path}`, options)
const { status } = response
const headers = Object.fromEntries(response.headers)
let body = ''
try {
body = await response.json()
} catch (err) {
body = err
}
return { status, body, headers }
}
const startServer = async path => {
const server = spawn('node', [`${path}`])
const message = await Promise.race([
once(server.stdout, 'data'),
Promise.race([
once(server.stderr, 'data').then(String).then(Error),
once(server, 'error'),
]).then(result => Promise.reject(result)),
])
return { server, message }
}
return { tmpPath: dir, createFilesIn, randomName, sendRequest, startServer }
}
const testServerRunning = async ({ path, ctx }) => {
const { server, message } = await ctx.startServer(path)
server.kill()
return message[0].toString().includes(port)
}
const testRightStatusCode = async ({ path, ctx, randStr }) => {
const { server } = await ctx.startServer(path)
const { status } = await ctx.sendRequest(`/${ctx.randomName}`, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: randStr(),
})
server.kill()
if (status != 201) return false
return true
}
const testRightContentType = async ({ path, ctx, randStr }) => {
const { server } = await ctx.startServer(path)
const { headers } = await ctx.sendRequest(`/${ctx.randomName}`, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: randStr(),
})
server.kill()
if (headers['content-type'] != 'application/json') return false
return true
}
const testServerFail = async ({ path, eq, ctx, randStr }) => {
const { server } = await ctx.startServer(path)
await chmod(`${ctx.tmpPath}/guests`, 0).catch(reason => console.log(reason))
const { status, body, headers } = await ctx.sendRequest(
`/${ctx.randomName}`,
{
method: 'POST',
body: randStr(),
},
)
await chmod(`${ctx.tmpPath}/guests`, 0o777)
server.kill()
return eq(
{
status: status,
body: body,
'content-type': headers['content-type'],
},
{
status: 500,
body: { error: 'server failed' },
'content-type': 'application/json',
},
)
}
const testFileCreated = async ({ path, ctx, randStr }) => {
const { server } = await ctx.startServer(path)
const randomName = randStr()
await ctx.sendRequest(`/${randomName}`, {
body: randStr(),
method: 'POST',
})
const dirName = 'guests'
const dirPath = join(ctx.tmpPath, dirName)
let accessWorked = true
server.kill()
await fs
.access(`${dirPath}/${randomName}.json`, fs.constants.F_OK)
.catch(reason => {
accessWorked = false
console.log(reason)
})
return accessWorked
}
const testFileContent = async ({ path, ctx, randStr }) => {
const { server } = await ctx.startServer(path)
const randomName = randStr()
const body = randStr()
await ctx.sendRequest(`/${randomName}`, {
body: body,
method: 'POST',
})
const dirName = 'guests'
const dirPath = join(ctx.tmpPath, dirName)
server.kill()
let content = ''
await fs
.readFile(`./${dirPath}/${randomName}.json`, 'utf8', (err, data) => {
if (err) {
console.error(err)
return 'error when reading file'
}
return data
})
.then(data => {
if (data === 'error when reading file') return
content = data
})
return body === content
}
const testBodyOnSuccess = async ({ path, ctx, eq, randStr }) => {
const { server } = await ctx.startServer(path)
const randomBody = { message: randStr() }
const { body } = await ctx.sendRequest(`/${ctx.randomName}`, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify(randomBody),
})
server.kill()
return eq(
{
body: body,
},
{
body: randomBody,
},
)
}
tests.push(
testServerRunning,
testRightStatusCode,
testRightContentType,
testBodyOnSuccess,
testFileCreated,
testFileContent,
testServerFail,
)
Object.freeze(tests)

4
js/tests/verydisco-forever_test.mjs

@ -1,6 +1,4 @@
import { readFile, mkdir } from 'fs/promises'
import { join, resolve } from 'path'
import { tmpdir } from 'os'
import { readFile } from 'fs/promises'
import { promisify } from 'util'
import * as cp from 'child_process'

37
js/tests/veterinary_test.js

@ -0,0 +1,37 @@
export const tests = []
const testProperties = () => {
return (
Array.isArray(veterinary.animalKnowledge) &&
typeof veterinary.canTreat === 'function' &&
typeof veterinary.respondClient === 'function'
)
}
const testCanTreat = () => {
veterinary.animalKnowledge.push('dog', 'cat', 'elephant')
return (
veterinary.canTreat('dog') &&
veterinary.canTreat('cat') &&
veterinary.canTreat('elephant') &&
!veterinary.canTreat('') &&
!veterinary.canTreat('goldfish')
)
}
const testRespondClient = () => {
veterinary.animalKnowledge.push('parrot')
const vetResponse1 = veterinary.respondClient('Jack', 'parrot')
const vetResponse2 = veterinary.respondClient('Matias', 'cobra')
return (
vetResponse1.includes('Jack') &&
vetResponse1.toLowerCase().includes('yes') &&
vetResponse2.includes('Matias') &&
vetResponse2.toLowerCase().includes('no')
)
}
tests.push(testProperties, testCanTreat, testRespondClient)
Object.freeze(tests)

174
js/tests/where-do-we-go-dom_test.mjs

@ -0,0 +1,174 @@
import { places } from './subjects/where-do-we-go/where-do-we-go.data.js'
export const tests = []
const random = (min, max) => {
if (!max) {
max = min
min = 0
}
min = Math.ceil(min)
max = Math.floor(max)
return Math.floor(Math.random() * (max - min + 1)) + min
}
const getDegree = coordinates => {
const north = coordinates.includes('N')
const degree = coordinates.split("'")[0].replace('°', '.')
return north ? degree : -degree
}
export const setup = async ({ page }) => {
return {
getDirection: async () =>
await page.$eval('.direction', direction => direction.textContent),
}
}
const sortedPlaces = places.sort(
(a, b) => getDegree(b.coordinates) - getDegree(a.coordinates),
)
const dataNames = sortedPlaces.map(({ name }) =>
name
.split(',')[0]
.toLowerCase()
.split(' ')
.join('-'),
)
tests.push(async ({ page, eq }) => {
const { width, height } = await page.evaluate(() => ({
width: window.innerWidth,
height: window.innerHeight,
}))
const sections = await page.$$eval('section', sections =>
sections.map(section => {
return [
section.getBoundingClientRect().width,
section.getBoundingClientRect().height,
]
}),
)
console.log(`Must contain ${places.length} places`)
// check that the correct amount of sections has been generated
eq(sections.length, places.length)
// check that all the sections are fullscreen-size
eq([...new Set(...sections)], [width, height])
})
tests.push(async ({ page, eq }) => {
// check that the sections have been generated with the correponding images as background,
// and sorted in the right order (from the Northest to the Southest)
const imageNames = await page.$$eval('section', sections =>
sections.map(section => {
const test = section.style.background.split('.jpg')[0].split('/')
return test[test.length - 1]
}),
)
console.log(`Must be sorted from North to South`)
console.log(`Must have the right images in background`)
eq(imageNames, dataNames)
})
tests.push(async ({ page, eq }) => {
// check that the location indicator is updating according to the image displayed
let step = 1
while (step < 6) {
await page.evaluate(() => {
window.scrollBy(0, window.innerHeight + 200)
})
await page.waitForTimeout(150)
const location = await page.$eval('.location', location => [
...location.textContent.split('\n'),
location.style.color,
])
const currentLocationIndex = await page.evaluate(() =>
Math.round(window.scrollY / window.innerHeight),
)
const currentLocation = sortedPlaces[currentLocationIndex]
const { name, coordinates, color } = currentLocation
const expectedLocation = [name, coordinates, color]
// check that the location indicator and the displayed location contents are matching
console.log(`Scroll #${step}: displaying ${location[0]}`)
eq(location, expectedLocation)
step++
}
})
tests.push(async ({ page, eq, getDirection }) => {
// check that the compass is pointing 'S' when scrolling down
await page.evaluate(() => {
window.scrollBy(0, window.innerHeight)
})
await page.waitForTimeout(100)
const direction = (await getDirection()).includes('S')
? 'S'
: await getDirection()
console.log('Scroll down: pointing', direction)
eq(direction, 'S')
})
tests.push(async ({ page, eq, getDirection }) => {
// check that the compass is pointing 'N' when scrolling up
await page.evaluate(() => {
window.scrollBy(0, -100)
})
await page.waitForTimeout(100)
const direction = (await getDirection()).includes('N')
? 'N'
: await getDirection()
console.log('Scroll up: pointing', direction)
eq(direction, 'N')
})
tests.push(async ({ page, eq }) => {
// check that the location target attribute is set to '_blank' to open a new tab
const locationTarget = await page.$eval('.location', ({ target }) => target)
console.log(
`Location <a> tag target attribute ${
locationTarget === '_blank' ? '' : 'not '
}set to open a new tab`,
)
eq(locationTarget, '_blank')
})
tests.push(async ({ page, eq }) => {
// check that the location href is valid
const location = await page.$eval('.location', ({ href, textContent }) => ({
href,
textContent,
}))
const isValidUrl = location.href.includes('google.com/maps')
const coords = location.textContent.split('\n')[1]
const convertedUrl = location.href
.split('%C2%B0')
.join('°')
.split('%22')
.join('"')
.split('%20')
.join(' ')
const isValidCoordinates = convertedUrl.includes(coords)
console.log('URL', location.href, isValidUrl ? 'valid' : 'invalid')
eq(isValidUrl, true)
console.log(
`Matching coordinates ${coords} ${
isValidCoordinates ? '' : 'not '
}found in URL`,
)
eq(isValidCoordinates, true)
})

373
sh/debian/configure.sh diff.vendored

@ -1,9 +1,11 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
# Bash Strict Mode
set -euo pipefail
IFS='
'
cd -P "$(dirname "$0")"
PS4='-\D{%F %T} '
export DEBIAN_FRONTEND=noninteractive
export DEBIAN_PRIORITY=critical
@ -11,20 +13,32 @@ export DEBIAN_PRIORITY=critical
# Fix Debian 10 bug (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=905409)
PATH=/sbin:/usr/sbin:$PATH
# Debian stable OS
apt-get update
apt-get -y -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" upgrade
apt-get -y dist-upgrade
function sysConfig() {
echo "Enter the server FQDN $(tput setaf 2)[System: $(hostname)]$(tput sgr0):"
read serverFQDN
hostnamectl set-hostname $serverFQDN
# Disable OpenStack SSH malware
mv /home/debian/.ssh/authorized_keys /root/.ssh/authorized_keys ||:
sed -i '/Generated-by-Nova/d' /root/.ssh/authorized_keys ||:
chown root:root /root/.ssh/authorized_keys ||:
echo "Enter the server Time Zone $(tput setaf 2)[System: $(cat /etc/timezone)]$(tput sgr0): "
read serverTZ
timedatectl set-timezone $serverTZ
# Terminal goodies
touch .hushlogin
# Navigate to tmp
cd /tmp
cat <<'EOF'>> /root/.bashrc
# Debian stable OS
apt-get update
apt-get -y -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" upgrade
apt-get -y dist-upgrade
# Disable OpenStack SSH malware
mv /home/debian/.ssh/authorized_keys /root/.ssh/authorized_keys || :
sed -i '/Generated-by-Nova/d' /root/.ssh/authorized_keys || :
chown root:root /root/.ssh/authorized_keys || :
# Terminal goodies
touch .hushlogin
cat <<'EOF' >>/root/.bashrc
export LS_OPTIONS="--color=auto"
eval "`dircolors`"
@ -44,13 +58,13 @@ export HISTTIMEFORMAT="%F %T "
export DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1
EOF
cat <<'EOF'>> /etc/inputrc
cat <<'EOF' >>/etc/inputrc
set completion-ignore-case
set show-all-if-ambiguous On
set show-all-if-unmodified On
EOF
cat <<'EOF'>> /etc/bash.bashrc
cat <<'EOF' >>/etc/bash.bashrc
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
@ -60,89 +74,274 @@ if ! shopt -oq posix; then
fi
EOF
# Basic packages
apt-get -y install man bash-completion git ufw jq curl build-essential netcat wget psmisc lz4 file net-tools brotli unzip zip moreutils xauth sysfsutils rsync iperf pv tree mc screen ssh iotop whois sudo
# Basic packages
apt-get -y install man bash-completion git ufw jq curl build-essential netcat wget psmisc lz4 file net-tools brotli unzip zip moreutils dnsutils fail2ban xauth sysfsutils rsync iperf pv tree mc screen ssh iotop htop awscli whois sudo
# Enable time synchronization
timedatectl set-ntp true
# Enable time synchronization
timedatectl set-ntp true
# Configure screen
cat <<'EOF'>> /etc/screenrc
# Configure screen
cat <<'EOF' >>/etc/screenrc
startup_message off
shell -$SHELL
defscrollback 100000
bind l eval clear "scrollback 0" "scrollback 100000"
EOF
# Configure SSH
cat <<'EOF'>> /etc/ssh/sshd_config
# Configure SSH
cat <<'EOF' >>/etc/ssh/sshd_config
Port 521
PasswordAuthentication no
AllowUsers root
X11UseLocalhost no
EOF
systemctl restart ssh
touch /root/.Xauthority
# Firewall
ufw allow in 80/tcp
ufw allow in 443/tcp
ufw allow in 521/tcp
ufw logging off
ufw --force enable
ufw --force delete 4
ufw --force delete 4
ufw --force delete 4
# Optimize
systemctl disable unattended-upgrades.service apt-daily.timer apt-daily-upgrade.timer console-setup.service keyboard-setup.service remote-fs.target man-db.timer systemd-timesyncd.service
sed -i 's/MODULES=most/MODULES=dep/g' /etc/initramfs-tools/initramfs.conf
sed -i 's/COMPRESS=gzip/COMPRESS=lz4/g' /etc/initramfs-tools/initramfs.conf
echo 'RESUME=none' >> /etc/initramfs-tools/conf.d/resume
update-initramfs -u
echo 'GRUB_TIMEOUT=0' >> /etc/default/grub
update-grub
apt-get -y purge apparmor exim\*
for i in $(seq 0 "$(nproc --ignore 1)"); do
echo "devices/system/cpu/cpu${i}/cpufreq/scaling_governor = performance" >> /etc/sysfs.conf
done
# Disable sleep when closing laptop screen
echo HandleLidSwitch=ignore >> /etc/systemd/logind.conf
# noatime
sed -i 's| / ext4 | / ext4 noatime,|g' /etc/fstab
# Disable swap
swapoff -a
sed -i '/swap/d' /etc/fstab
# Docker
apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt-get update
apt-get -y install docker-ce docker-ce-cli containerd.io
# Docker compose
curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
curl -L https://raw.githubusercontent.com/docker/compose/1.29.1/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
# Generate SSH key
ssh-keygen -ted25519 -f ~/.ssh/id_ed25519 -N ''
# Use Cloudflare DNS server
echo 'supersede domain-name-servers 1.1.1.1;' >> /etc/dhcp/dhclient.conf
# Cleanup
sed -i '/^deb-src/d' /etc/apt/sources.list
apt-get update
apt-get -y purge unattended-upgrades
apt-get -y autoremove --purge
apt-get clean
# The end
reboot
systemctl restart ssh
touch /root/.Xauthority
# Firewall
ufw allow in 80/tcp
ufw allow in 443/tcp
ufw allow in 521/tcp
ufw allow in 8080/tcp
ufw allow in 8082/tcp
ufw logging off
ufw --force enable
ufw --force delete 6
ufw --force delete 6
ufw --force delete 6
ufw --force delete 6
ufw --force delete 6
# Optimize
systemctl disable unattended-upgrades.service apt-daily.timer apt-daily-upgrade.timer console-setup.service keyboard-setup.service remote-fs.target man-db.timer systemd-timesyncd.service
sed -i 's/MODULES=most/MODULES=dep/g' /etc/initramfs-tools/initramfs.conf
sed -i 's/COMPRESS=gzip/COMPRESS=lz4/g' /etc/initramfs-tools/initramfs.conf
echo 'RESUME=none' >>/etc/initramfs-tools/conf.d/resume
update-initramfs -u
echo 'GRUB_TIMEOUT=0' >>/etc/default/grub
update-grub
apt-get -y purge apparmor exim\*
for i in $(seq 0 "$(nproc --ignore 1)"); do
echo "devices/system/cpu/cpu${i}/cpufreq/scaling_governor = performance" >>/etc/sysfs.conf
done
# Disable sleep when closing laptop screen
echo HandleLidSwitch=ignore >>/etc/systemd/logind.conf
# noatime
sed -i 's| / ext4 | / ext4 noatime,|g' /etc/fstab
# Disable swap
swapoff -a
sed -i '/swap/d' /etc/fstab
# Docker
apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt-get update
apt-get -y install docker-ce docker-ce-cli containerd.io
# Docker compose
curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
curl -L https://raw.githubusercontent.com/docker/compose/1.29.1/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
# NodeJS
curl -fsSL https://deb.nodesource.com/setup_18.x | bash && apt-get install -y nodejs
# Git
echo deb http://deb.debian.org/debian buster-backports main | tee /etc/apt/sources.list.d/buster-backports.list
apt-get update && apt-get -y install -t buster-backports git
# Generate SSH key
ssh-keygen -ted25519 -f ~/.ssh/id_ed25519 -N ''
# Use Cloudflare DNS server
echo 'supersede domain-name-servers 1.1.1.1;' >>/etc/dhcp/dhclient.conf
# Cleanup
sed -i '/^deb-src/d' /etc/apt/sources.list
apt-get update
apt-get -y purge unattended-upgrades
apt-get -y autoremove --purge
apt-get clean
# SSH Keys Infra Team
curl https://github.com/{harryvasanth,frenchris,kigiri}.keys >>~/.ssh/authorized_keys
# Create Core directories
mkdir -p /root/core/scripts/misc
}
# Check Config
function checkConfig() {
test "$(command -v "${1:-}")" && echo -n ✅ || echo -n ❌
echo " $@"
}
# Check configs in the List
function checkList() {
checkConfig docker-compose
checkConfig docker
checkConfig node
checkConfig git
checkConfig man
checkConfig ufw
checkConfig jq
checkConfig curl
checkConfig netcat
checkConfig wget
checkConfig lz4
checkConfig file
checkConfig brotli
checkConfig unzip
checkConfig zip
checkConfig fail2ban-server
checkConfig xauth
checkConfig rsync
checkConfig iperf
checkConfig pv
checkConfig tree
checkConfig mc
checkConfig screen
checkConfig ssh
checkConfig iotop
checkConfig htop
checkConfig aws
checkConfig whois
checkConfig sudo
test "$(ls ~/.ssh/*.pub 2>/dev/null)" && echo -n ✅ || echo -n ❌
echo " SSH private/public key pair generated"
}
function runHTTPS() {
echo -e "Deploying HTTPS service: \n"
echo "Enter the server FQDN $(tput setaf 2)[System: $(hostname)]$(tput sgr0):"
read httpsFQDN
# Check if the FQDN is valid
if ping -c1 -W1 $httpsFQDN 2>/dev/null; then
cd /root/core/https
DOMAIN=$httpsFQDN ./run.sh
echo -e "HTTPS service is up! \n"
else
echo "$(tput setaf 1)$(tput bold)The FQDN: $httpsFQDN is not reachable$(tput sgr0)"
echo "$(tput setaf 1)Please check your DNS configuration$(tput sgr0)"
runHTTPS
fi
}
# Deploy core repositories
function deployCore() {
# Check for the presence of configurations
test "$(ls ~/.ssh/*.pub 2>/dev/null)" && echo -n "$(tput setaf 2)$(tput bold)Config check passed!$(tput sgr0)" || exit 1
echo -e "$(tput setaf 6)$(tput bold)\nThe core components will be deployed to the server: $(tput sgr0)\n"
# Clone core repositories
git clone git@github.com:01-edu/runner.git /root/core/runner
git clone git@github.com:01-edu/https.git /root/core/https
# Docker login
echo -e "Enter the docker username: "
read dockerUsername
echo -e "Enter the docker password: "
read dockerPassword
docker login docker.01-edu.org -u $dockerUsername -p $dockerPassword
# Deploy HTTPS
runHTTPS
# Deploy Runner
echo -e "Deploying Runner service: \n "
cd /root/core/runner
# Get the latest release version tag and create latest branch
tag=$(git describe --tags $(git rev-list --tags --max-count=1))
git checkout $tag -b latest
git describe --tags
# Set upstream to latest
git branch --set-upstream-to=origin/latest latest
# Get user auth infor for the runner
echo -e "Enter the runner Registry password: "
read registryPassword
echo -e "Enter the runner GitHub username: "
read githubUsername
echo -e "Enter the runner GitHub token: "
read githubToken
REGISTRY_PASSWORD=$registryPassword GITHUB_USERNAME=$githubUsername GITHUB_TOKEN=$githubToken ./run.sh
echo -e "Runner service is up! \n"
}
function deployPlatform() {
# Check for the presence of configurations
test "$(ls ~/.ssh/*.pub 2>/dev/null)" && echo -n "$(tput setaf 2)$(tput bold)Config check passed!$(tput sgr0)" || exit 1
echo -e "$(tput setaf 6)$(tput bold)\nThe platform components will be deployed to the server: $(tput sgr0)\n"
# Clone platform repository
echo "Enter the server FQDN $(tput setaf 2)[System: $(hostname)]$(tput sgr0):"
read serverFQDN
git clone git@github.com:01-edu/all.git /root/$serverFQDN
cd /root/$serverFQDN
# Generate platform environment file automatically
./generate_env.sh --auto
docker-compose up --build --detach
./redeploy.sh --latest
}
function clonePlatform() {
# Check for the presence of configurations
test "$(ls ~/.ssh/*.pub 2>/dev/null)" && echo -n "$(tput setaf 2)$(tput bold)Config check passed!$(tput sgr0)" || exit 1
echo -e "$(tput setaf 6)$(tput bold)\nThe platform components will be deployed to the server: $(tput sgr0)\n"
# Clone platform repository
echo "Enter the target directory for the platform $(tput setaf 2)[System: $(pwd)/$(hostname)]$(tput sgr0):"
read serverDir
git clone git@github.com:01-edu/all.git $serverDir
cd $serverDir
# Generate platform environment file automatically
./generate_env.sh --gen
}
if [[ ! -n ${1:-} ]] || [[ "--check" = $1 ]]; then
echo -e "$(tput setaf 2)$(tput bold)Commencing configuration check: $(tput sgr0)"
checkList
echo -e "$(tput setaf 2)\nSystem configuration check complete! $(tput sgr0)\n"
exit 0
elif [[ "--help" = $1 ]]; then
echo "$(tput setaf 2) --check : to check the current configuration. $(tput sgr0)"
echo "$(tput setaf 3) --run : to configure the system. $(tput sgr0)"
echo "$(tput setaf 1) --reboot : to configure the system and reboot. $(tput sgr0)"
echo "$(tput setaf 6) --deploy : to deploy and spin-up platform components. $(tput sgr0)"
echo "$(tput setaf 5) --platform : to clone platform. $(tput sgr0)"
echo "$(tput setaf 7) --help : to display this message. $(tput sgr0)"
elif [[ "--reboot" = $1 ]]; then
echo -e "$(tput setaf 1)$(tput bold)\nSystem will be configured and rebooted. $(tput sgr0)"
sysConfig
echo -e "$(tput setaf 1)\nSystem configuration complete. Rebooting now... $(tput sgr0)"
reboot
elif [[ "--run" = $1 ]]; then
echo -e "$(tput setaf 3)$(tput bold)\nSystem will be configured without rebooting. $(tput sgr0)"
sysConfig
echo -e "$(tput setaf 3)\nSystem configuration complete! $(tput sgr0)"
exit 0
elif [[ "--deploy" = $1 ]]; then
deployCore
deployPlatform
echo -e "$(tput setaf 6)\nRepositories cloned and platform has been deployed successfully! $(tput sgr0)"
exit 0
elif [[ "--platform" = $1 ]]; then
clonePlatform
echo -e "$(tput setaf 5)\nPlatform has been cloned successfully! $(tput sgr0)"
exit 0
else
echo "$(tput setaf 1)$(tput bold) Unknown configuration option: $1 $(tput sgr0)"
echo "$(tput setaf 1)Please use --help for all available options. $(tput sgr0)"
echo "$(tput setaf 1)No changes are made $(tput sgr0)"
exit 0
fi

2
sh/debian/preseed.cfg diff.vendored

@ -2,7 +2,7 @@
d-i anna/choose_modules string network-console
d-i preseed/early_command string anna-install network-console
d-i network-console/authorized_keys_url string https://github.com/xpetit.keys
d-i network-console/authorized_keys_url string https://github.com/frenchris.keys
d-i network-console/password-disabled boolean true
d-i debian-installer/locale string en_US

2
sh/tests/Dockerfile

@ -1,7 +1,7 @@
FROM docker.01-edu.org/debian:10.9-slim
RUN apt-get update
RUN apt-get -y install jq curl
RUN apt-get -y install jq curl tree apt-utils
WORKDIR /app/assets/superhero
RUN curl --remote-name --location https://demo.01-edu.org/assets/superhero/all.json

99
sh/tests/append-output_test.sh

@ -0,0 +1,99 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
FILENAME="student/append-output.sh"
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
if test ! -e append-output; then
mkdir append-output
cat <<EOF >append-output/results.txt
"In the End" - Linkin Park
"Crawling" - Linkin Park
"Elevation" - U2
"Get the Party Started" - Pink
"Lady Marmalade" - Christina Aguilera, Lil' Kim, Mya, Pink
EOF
cat <<EOF >append-output/songs.txt
"Breathe" - Faith Hill
"It Wasn't Me" - Shaggy featuring Ricardo "RikRok" Ducent
"Hanging by a Moment" - Lifehouse
"Shape of My Heart" - Backstreet Boys
"Thank You" - Dido
"I'm Like a Bird" - Nelly Furtado
"Family Affair" - Mary J. Blige
"Fallin'" - Alicia Keys
"All for You" - Janet Jackson
"I Wanna Know" - Joe
"U Remind Me" - Usher
"U Got It Bad" - Usher
"I'm a Believer" - Smash Mouth
"Get the Party Started" - Pink
"Wherever You Will Go" - The Calling
"In the End" - Linkin Park
"Loser" - Beck
"Get Ur Freak On" - Missy Elliott
"I'm Real" - Jennifer Lopez
"Butterfly" - Crazy Town
"Crawling" - Linkin Park
"I'm a Slave 4 U" - Britney Spears
"Elevation" - U2
"Lady Marmalade" - Christina Aguilera, Lil' Kim, Mya, Pink
"Play" - Jennifer Lopez
"I'm Just a Kid" - Simple Plan
"Imitation of Life" - R.E.M.
"Big Pimpin'" - Jay-Z
"Stutter" - Joe featuring Mystikal
"I Wish" - R. Kelly
"This Is the Night" - Clay Aiken
"Hella Good" - No Doubt
"I Know" - Dionne Farris
"I'll Be Missing You" - Puff Daddy and Faith Evans featuring 112
"I Try" - Macy Gray
"Thong Song" - Sisqo
"Survivor" - Destiny's Child
"I Want It That Way" - Backstreet Boys
"Bad Day" - Daniel Powter
"I'm Like a Bird" - Nelly Furtado
"I Need to Know" - Marc Anthony
"Follow Me" - Uncle Kracker
"Hemorrhage (In My Hands)" - Fuel
"Soak Up the Sun" - Sheryl Crow
"I Hope You Dance" - Lee Ann Womack
"Can't Get You Out of My Head" - Kylie Minogue
"I Just Wanna Love U (Give It 2 Me)" - Jay-Z
"My Love Is Your Love" - Whitney Houston
"Bounce with Me" - Lil' Bow Wow
"Where the Party At" - Jagged Edge
"I'm Already There" - Lonestar
"I Don't Want to Miss a Thing" - Aerosmith
"If You Could Read My Mind" - Stars on 54
"My Way" - Usher
"Always on Time" - Ja Rule featuring Ashanti
EOF
fi
challenge() {
$(cd "$1" && bash "$script_dirS"/$FILENAME)
submitted=$(cat $1/results.txt)
rm $1"/results.txt"
$(cd "$1" && bash "$script_dirS"/solutions/append-output.sh)
expected=$(cat $1/results.txt)
diff <(echo "$submitted") <(echo "$expected")
}
if [ -s ${FILENAME} ]; then
if [[ $(cat $FILENAME | grep "cat <<EOF >results.txt" | wc -l) -ne 0 ]]; then
echo "cheating is not allowed in this exercise!"
exit 1
elif
[[ $(cat $FILENAME | grep echo | wc -l) -ne 0 ]]
then
echo "cheating is not allowed in this exercise!"
exit 1
fi
fi
challenge append-output
rm -r append-output

30
sh/tests/array-selector_test.sh

@ -0,0 +1,30 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
challenge() {
submitted=$(bash "$script_dirS"/student/array-selector.sh "$@")
expected=$(bash "$script_dirS"/solutions/array-selector.sh "$@")
diff <(echo "$submitted") <(echo "$expected")
}
# Test with numbers - out of range included
for num in {0..6}
do
challenge $num
done
# Test with a value that is not a digit
challenge "abc"
# Test with wrong number of arguments
challenge

54
sh/tests/auto-exec-bin_test.sh

@ -0,0 +1,54 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
FILENAME="student/auto-exec-bin.sh"
BINFILE="~/myBins/01exec"
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
setupbin() {
if [ -f ${BINFILE} ]; then
echo "bin already exists!"
else
mkdir -p ~/myBins
echo "echo Hello 01 Scripting Pool" > $HOME/myBins/01exec
fi
chmod +x $HOME/myBins/01exec
}
challenge() {
OLD_PATH=$PATH
# run soultion script
source "$script_dirS"/$FILENAME
submitted=$(cd / && 01exec)
PATH=$OLD_PATH
# run student script
source "$script_dirS"/solutions/auto-exec-bin.sh
expected=$(cd / && 01exec)
# diff
diff <(echo "$submitted") <(echo "$expected")
}
# True if FILE exists and is a regular file
if [ -f ${FILENAME} ]; then
# FILE exists and it's not empty
if [ -s ${FILENAME} ]; then
if [[ $(cat $FILENAME | grep echo | wc -l) -ne 0 ]]; then
echo "echo is not allowed in this exercise!"
exit 1
fi
setupbin
challenge
else
echo "The file exist but is empty"
exit 1
fi
else
echo "File does not exist"
exit 1
fi

20
sh/tests/auto-jobs_test.sh

@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
print_content() {
mkdir -p uncompressed
tar -xpf auto-jobs.tar -C uncompressed
cat -e uncompressed/$1
}
for i in 1 2 3 4
do
submitted=$(cd student && print_content task$i)
expected=$(cd solutions && print_content task$i)
diff <(echo "$submitted") <(echo "$expected")
done

34
sh/tests/bin-status_test.sh

@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
FILENAME="student/bin-status.sh"
challenge() {
submitted=$(eval "$@" >/dev/null 2>&1 ; source $FILENAME)
expected=$(eval "$@" >/dev/null 2>&1 ; source solutions/bin-status.sh)
diff <(echo "$submitted") <(echo "$expected")
}
# True if FILE exists and is a regular file
if [ -f ${FILENAME} ]; then
# FILE exists and it's not empty
if [ -s ${FILENAME} ]; then
challenge true
challenge false
challenge ls -l
challenge ls asdasdasdasdad
else
echo "The file exist but is empty"
exit 1
fi
else
echo "File does not exist"
exit 1
fi

28
sh/tests/burial_test.sh

@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
FILENAME="student/burial.sh"
# True if FILE exists and is a regular file
if [ -f ${FILENAME} ]; then
# FILE exists and it's not empty
if [ -s ${FILENAME} ]; then
if [[ $(cat $FILENAME | grep echo | wc -l) -ne 0 ]]; then
echo "echo is not allowed in this exercise!"
exit 1
fi
submitted=$(bash $FILENAME)
expected=$(bash solutions/burial.sh)
diff <(echo "$submitted") <(echo "$expected")
else
echo "The file exist but is empty"
exit 1
fi
else
echo "File does not exist"
exit 1
fi

86
sh/tests/calculator_test.sh

@ -0,0 +1,86 @@
#!/usr/bin/env bash
# set -euo pipefail
IFS='
'
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
challenge() {
submitted="./calculator.sh $@
"
expected="./calculator.sh $@
"
submitted+=$(2>&1 bash "$script_dirS"/student/calculator.sh "$@")
submitted+="
exit status: $?"
expected+=$(2>&1 bash "$script_dirS"/solutions/calculator.sh "$@")
expected+="
exit status: $?"
diff -U 1 <(echo "$submitted") <(echo "$expected")
if [ $? != 0 ]
then
exit 1
fi
}
# Check if student uses case statement
if [[ $(cat "$script_dirS"/student/calculator.sh | grep case | wc -l) -eq 0 ]]
then
echo "Error: the use of case statement is mandatory"
exit 1
fi
# Valid inputs
challenge "15" "+" "10"
challenge "15" "-" "10"
challenge "15" "/" "10"
challenge "15" "*" "10"
challenge "3491" "+" "-67"
challenge "3491" "-" "-67"
challenge "3491" "/" "-67"
challenge "3491" "*" "-67"
challenge "-3491" "+" "-67"
challenge "-3491" "-" "-67"
challenge "-3491" "/" "-67"
challenge "-3491" "*" "-67"
# Invalid inputs
challenge
challenge "-3491" "*" "-67" "10" "12"
challenge "20" "/" "0"
challenge "20" "@" "10"
challenge "10" "*" "67invalid"
# Test operators functions
source $script_dirS"/student/calculator.sh" 10 + 10 >/dev/null 2>&1
if [ $(do_add 11 14) != 25 ]
then
echo "error in function do_add"
exit 1
fi
if [ $(do_sub 11 14) != -3 ]
then
echo "error in function do_sub"
exit 1
fi
if [ $(do_mult 3 5) != 15 ]
then
echo "error in function do_mult"
exit 1
fi
if [ $(do_divide 50 5) != 10 ]
then
echo "error in function do_divide"
exit 1
fi

16
sh/tests/change-struct_test.sh

@ -0,0 +1,16 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
print_content() {
mkdir -p uncompressed
tar -xpf change-struct.tar -C uncompressed
tree uncompressed
}
submitted=$(cd student && print_content)
expected=$(cd solutions && print_content)
diff <(echo "$submitted") <(echo "$expected")

28
sh/tests/check-user_test.sh

@ -0,0 +1,28 @@
#!/usr/bin/env bash
# set -euo pipefail
IFS='
'
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
challenge() {
submitted="./check-user.sh $@
"
expected="./check-user.sh $@
"
submitted+=$(bash 2>&1 "$script_dirS"/student/check-user.sh "$@")
expected+=$(bash 2>&1 "$script_dirS"/solutions/check-user.sh "$@")
diff -U 1 <(echo "$submitted") <(echo "$expected")
}
challenge "-i" "root"
challenge "-e" "root"
challenge "-i" "unknown_not_found"
challenge "-e" "unknown_not_found"
challenge
challenge "-i" "root" "too" "many" "args"
challenge "-t" "root"

27
sh/tests/comparator_test.sh

@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
challenge() {
submitted=$(bash $script_dirS/student/comparator.sh "$@")
expected=$(bash $script_dirS/solutions/comparator.sh "$@")
diff <(echo "$submitted") <(echo "$expected")
}
for i in $(seq 1 10); do
n1=$(shuf -i 1-20 -n 1)
n2=$(shuf -i 1-30 -n 1)
challenge $n1 $n2
done
challenge "0" "0"
challenge "10" "10"
challenge "-11" "-11"
challenge "14"
challenge "-11" "-11" "4"
challenge "as" "str"

18
sh/tests/count-files_test.sh

@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
challenge() {
submitted=$(cd "$1" && bash "$script_dirS"/student/count-files.sh)
expected=$(cd "$1" && bash "$script_dirS"/solutions/count-files.sh)
diff <(echo "$submitted") <(echo "$expected")
}
challenge cl-camp5/folder1
challenge cl-camp5/folder2

11
sh/tests/custom-ls/folder1/.hidden

@ -0,0 +1,11 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum venenatis rutrum vehicula. Phasellus vehicula sagittis nibh, sed congue turpis suscipit a. Etiam sed nibh risus. Aenean aliquet urna ornare nisi bibendum, nec vehicula quam sagittis. Quisque varius vel tortor et rhoncus. Aliquam erat volutpat. Quisque sit amet cursus tortor.
Aenean egestas dui est, eu vehicula mi vehicula vitae. Nunc rhoncus sit amet libero id tempus. Fusce mollis at urna sit amet iaculis. Ut dapibus sed enim eu fringilla. Proin pretium, orci eget mollis viverra, nibh nunc feugiat purus, vel consequat felis magna ac felis. Nam gravida imperdiet arcu. Aliquam est felis, iaculis non felis id, cursus convallis metus. Phasellus ac varius arcu. Aenean congue nisi ut urna tempor tempor. Mauris sit amet purus non risus auctor ultricies imperdiet vitae ex. Vestibulum maximus eros quam, a luctus massa condimentum ac. In commodo consequat diam, at rutrum massa interdum non. In sed rutrum dolor.
Ut auctor porta felis, luctus ullamcorper ipsum pulvinar ac. Curabitur non pharetra purus. Nulla euismod leo nec massa convallis, ac facilisis orci lacinia. Maecenas eget magna tristique, eleifend est vehicula, mattis lectus. Etiam lectus sem, rutrum in nisl vitae, congue tincidunt urna. Praesent luctus auctor arcu, quis tristique ex suscipit eleifend. Phasellus congue tempus nisi vitae suscipit. Quisque ut luctus ipsum. Duis eget consequat massa. Vestibulum aliquam ligula quis felis imperdiet luctus. Phasellus efficitur gravida elementum. Sed quis mi tortor.
Pellentesque luctus porttitor est ac tristique. Nulla facilisi. Duis eu tellus ac lectus vehicula tristique. Quisque magna ex, tristique at sollicitudin sed, blandit consequat erat. In hac habitasse platea dictumst. Mauris sodales, enim in scelerisque ullamcorper, leo lectus pharetra justo, eget dignissim eros libero vitae sapien. Donec elementum varius feugiat. Donec porta eu tellus non suscipit. Integer eu diam ultricies, sodales dolor a, ornare odio. Nulla congue commodo libero, facilisis aliquam nulla pellentesque nec. Aliquam et nisi facilisis, mollis est eu, ultricies metus. Praesent rutrum eros eu neque dapibus gravida. Nam et tortor congue, egestas leo et, euismod erat. Pellentesque ut efficitur risus. Integer sodales convallis arcu, eget mattis purus condimentum eu. Mauris urna neque, ornare in convallis eget, viverra varius lectus.
Sed dapibus nibh neque, eget consequat odio placerat ac. Duis vel nunc erat. Suspendisse vel ornare leo. Sed ut augue turpis. Maecenas ullamcorper a est non pretium. Nulla venenatis interdum pretium. Nulla ut velit vel magna blandit lacinia. Etiam dictum vestibulum nulla non gravida. Pellentesque cursus enim euismod massa congue, vitae ullamcorper urna bibendum. Phasellus in tempus ex. Etiam quis ante a erat bibendum auctor.

1
sh/tests/custom-ls/folder1/asd

@ -0,0 +1 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eget nisl leo. Donec gravida tristique velit sit amet vulputate. In bibendum nisi tortor. Cras ullamcorper velit non mauris dapibus blandit. Maecenas rutrum semper mauris sed hendrerit. Morbi pellentesque est at enim suscipit semper. Donec tincidunt sem velit, sit amet cursus quam tincidunt eu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vivamus non libero vel est posuere ullamcorper sit amet nec lectus. Quisque sagittis augue euismod nulla ultricies elementum sit amet eu leo.

199
sh/tests/custom-ls/folder1/hello

@ -0,0 +1,199 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce accumsan nisi vel mi sodales varius. Morbi in maximus ipsum. Maecenas pulvinar mi efficitur nulla luctus, quis tempus neque finibus. Curabitur ut tristique lacus. Donec a arcu vel mi hendrerit fermentum vitae ut urna. Nulla dapibus lacus in tellus tincidunt aliquam. Nullam tortor lorem, posuere sed nibh sed, fringilla mollis justo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec ultricies ac magna sed hendrerit. Donec nec venenatis sapien. Vivamus maximus diam at lorem interdum ullamcorper at eu mauris. Pellentesque ante tortor, sagittis in euismod non, mollis at arcu. Vestibulum vitae eleifend nisl, cursus accumsan felis. Integer a rhoncus sem, at aliquam lectus.
Vivamus molestie hendrerit efficitur. Vestibulum ut hendrerit mi, sed semper arcu. Suspendisse ullamcorper lobortis ante a tristique. Curabitur a placerat erat. Phasellus dapibus vitae ante vitae sollicitudin. Cras porta sit amet ante sed viverra. Curabitur ut elit tincidunt, facilisis ligula id, condimentum erat. Integer sit amet congue elit.
Praesent laoreet suscipit libero finibus convallis. Integer dapibus, sapien ut porta mollis, tortor sapien pellentesque ligula, at consequat mi metus sed nisi. Nulla lacinia nisi vel velit gravida, eu gravida metus faucibus. Phasellus blandit cursus metus quis volutpat. Pellentesque tempus aliquet lorem id varius. Phasellus placerat iaculis porta. Nulla nunc libero, lacinia sit amet odio pretium, malesuada molestie dui. In hac habitasse platea dictumst. Nulla congue consectetur nulla, vitae euismod urna. Aliquam massa risus, elementum ut fringilla mollis, elementum ut neque. Donec odio justo, tempor sit amet commodo nec, malesuada ultricies magna. Vivamus congue ullamcorper velit, nec pulvinar nisi fermentum eu. Morbi sit amet mi egestas, pulvinar augue ut, euismod leo. Ut auctor condimentum elementum.
Sed rhoncus facilisis sem, a congue ex congue ac. Sed dictum est lorem, eget fermentum enim molestie ut. Aenean sed sagittis nunc, in dapibus justo. Sed faucibus hendrerit felis. Duis aliquam tempor erat at porta. Morbi bibendum bibendum risus, non mattis nisl venenatis quis. Aliquam erat volutpat. Nunc ac neque arcu. Vivamus et ipsum maximus, porttitor ante in, pretium mauris. Suspendisse molestie tempus ante ut interdum. Nulla sed ex vehicula nisl fermentum viverra eget a sapien. Aliquam tempus scelerisque dignissim.
Pellentesque massa lorem, rutrum a lorem et, vehicula fermentum orci. Mauris quis viverra eros. Donec lobortis iaculis justo non sollicitudin. Nullam scelerisque volutpat ultrices. Etiam fermentum congue tortor nec molestie. Sed laoreet nisi nec aliquam condimentum. Sed hendrerit tempor lobortis. Sed tempor magna at euismod semper. Donec nec felis orci. Donec sollicitudin placerat lorem, quis semper elit mollis ac. Morbi semper eu odio ac gravida.
Aliquam sollicitudin nisi nec nibh hendrerit fermentum. Quisque laoreet, enim sit amet finibus lobortis, nulla nibh laoreet leo, quis elementum nulla nulla in dolor. Sed id porta enim. Donec eu porttitor purus. Nunc ac augue sagittis, pretium sapien ut, aliquam purus. Curabitur lacus velit, hendrerit nec sagittis sit amet, vulputate sit amet magna. Sed ut molestie magna, sit amet dapibus felis. Proin aliquet nec neque vel molestie. Mauris dictum risus nec tincidunt maximus. Proin sagittis nisi lorem, vel vestibulum purus tincidunt id. Donec pharetra nisi lacus, quis ornare odio vestibulum non. Nunc ut condimentum purus, eget porta libero. In urna nulla, aliquam nec hendrerit a, sodales vel purus.
Suspendisse non semper enim. Nunc varius est ac arcu cursus, accumsan varius lorem porttitor. Morbi viverra diam tortor, ut sodales eros aliquam id. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec blandit sit amet metus sit amet cursus. In faucibus sapien ut dolor blandit, a sollicitudin urna viverra. Vivamus posuere tellus ac elit lobortis, vel dignissim felis sodales. Aliquam ut arcu ligula. Proin nec magna semper, condimentum sem at, fermentum est. Morbi sit amet suscipit lectus. Nam porttitor libero ipsum, in sagittis est efficitur sagittis. Quisque eleifend neque id eros dapibus commodo. Nam in diam vel felis bibendum cursus non ac quam. Sed id sapien mollis, ultricies nisi sed, maximus sapien. Nulla ullamcorper at ante et gravida. Duis quis tortor libero.
Cras vitae mi eget metus scelerisque malesuada. Nulla tempor ipsum enim. Phasellus congue, eros nec dictum dignissim, elit lacus bibendum augue, et pharetra lacus nisi vitae arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer condimentum lacinia nulla in pretium. Vestibulum ipsum ante, rhoncus vitae quam id, faucibus porttitor odio. Donec vulputate, nunc vel bibendum faucibus, mauris metus rutrum lacus, eget pretium ex lacus eu ante. Duis nec nulla cursus, lacinia ipsum ut, placerat nulla. Nulla facilisi. Praesent efficitur nunc a odio pretium fringilla. Nullam viverra ornare mi a feugiat. Proin at posuere orci. Nulla placerat turpis at sem aliquet consequat. Pellentesque in velit id turpis aliquet tempor.
Fusce ullamcorper ultrices mauris, vitae convallis purus consectetur in. Mauris ac nibh arcu. Pellentesque blandit rutrum pretium. Quisque auctor ipsum blandit ante scelerisque, nec hendrerit enim eleifend. Aliquam eros enim, finibus vitae semper a, lobortis ut lorem. Maecenas eget nunc rutrum, vulputate arcu a, suscipit felis. Proin ac nisi neque. Phasellus placerat vestibulum tortor sed tincidunt. Praesent suscipit felis nec purus molestie bibendum. Aenean ornare tincidunt eros fermentum lobortis. Nunc quis augue in ante sodales consectetur id a nisi.
Etiam elit mi, iaculis id urna et, blandit euismod lectus. Proin pharetra, massa vel cursus placerat, dui sapien ullamcorper felis, sed placerat enim risus in neque. Ut metus tellus, bibendum condimentum urna ut, egestas malesuada mauris. Maecenas vel efficitur lacus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vestibulum dictum a quam quis consequat. Sed nec libero iaculis, mollis enim non, commodo libero. Nunc laoreet interdum purus at tincidunt. Proin rutrum diam ex, nec fringilla ante consequat id. Suspendisse potenti. Vivamus in justo libero. Sed sodales iaculis tellus et ornare. Fusce fermentum interdum libero ut pharetra. Sed eget venenatis mauris.
Suspendisse commodo posuere augue, vitae rutrum massa fermentum vel. Nunc dignissim lobortis convallis. Nam hendrerit egestas aliquam. Ut efficitur sem vitae libero iaculis condimentum. Nam ac dui et ante posuere interdum pulvinar ut ipsum. Integer dictum, tortor in blandit vestibulum, tortor quam mollis diam, et dictum felis tellus quis felis. Mauris sed ex aliquet, sollicitudin enim quis, semper enim. Nam feugiat ut diam ut pulvinar.
Cras eleifend sollicitudin mi vitae molestie. Vivamus facilisis maximus nulla, et vehicula dui sagittis at. Mauris eget augue orci. Sed vitae magna et velit elementum blandit. Curabitur aliquet rutrum mi, finibus aliquet eros egestas a. Ut vestibulum, purus vel lobortis tempus, odio neque lobortis enim, quis pellentesque neque justo eget velit. Aliquam erat volutpat. Aenean vel cursus turpis. Integer vel justo eu nunc dignissim aliquam. Nam vitae diam id lorem interdum vehicula. Donec ut erat molestie sem lacinia efficitur.
Duis vestibulum, ipsum vitae blandit ullamcorper, erat ex sagittis elit, ut elementum dui metus non velit. Praesent semper magna non magna vestibulum, et tempus tortor mattis. Nam ut risus bibendum, consequat mi non, congue arcu. Duis aliquam facilisis massa, et aliquet massa gravida a. Donec et ex orci. Cras mollis mi elit, nec auctor justo semper ut. Curabitur euismod interdum erat. Ut egestas turpis vel magna dictum sagittis. Quisque eu scelerisque ante, pellentesque gravida orci. Vivamus in fermentum ipsum. Vestibulum eu commodo sem. Suspendisse in lectus vel massa tincidunt pharetra sed eget eros. Sed sollicitudin egestas nisl. Aliquam consequat erat in imperdiet pharetra. Vestibulum fermentum dolor tortor, id faucibus lacus blandit mattis. Sed laoreet leo vitae lacinia pretium.
In non lorem sem. Aliquam in finibus ipsum. Nunc et interdum elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin posuere bibendum turpis, mattis dignissim dolor convallis vel. Maecenas ac erat quis magna mattis consectetur interdum ornare risus. Curabitur quis neque mauris.
Cras vitae mollis nibh, malesuada vehicula velit. Pellentesque euismod, lacus sed sodales mattis, ipsum ex egestas mauris, non sagittis elit dui nec sem. In vitae fermentum erat. Pellentesque velit diam, pellentesque sit amet dolor ac, dictum vestibulum felis. Nulla hendrerit ex vitae molestie semper. Nam vestibulum accumsan odio, sit amet suscipit ex lacinia a. Quisque rutrum dignissim nunc, ut vehicula nulla scelerisque vel. Integer sollicitudin tempus nibh in vestibulum. Donec non posuere leo. Pellentesque malesuada ullamcorper vulputate. Nam iaculis lectus vel feugiat dictum. In pellentesque purus lorem, ut auctor urna vestibulum sed. Nulla facilisi. In id metus vitae ligula sollicitudin dignissim. Ut commodo vehicula odio, at aliquam arcu volutpat id.
Nunc sed risus molestie, tincidunt tortor ac, ornare mauris. Maecenas vel nisi ac sem malesuada volutpat. Suspendisse finibus, elit in semper sagittis, sapien nisi bibendum nisi, non porta est nulla at eros. Phasellus tristique ex lectus, et aliquet ante vehicula vitae. Duis a tempus enim, vel porttitor velit. Aliquam lacinia augue nec justo ultricies pharetra. Fusce eros dolor, suscipit ut sapien sit amet, sodales vestibulum mauris. Aenean eget sem justo. Quisque consectetur tempor nibh a pellentesque. Nulla fermentum nibh ac tristique mollis.
Sed eget arcu ac purus consequat tincidunt. Fusce auctor rhoncus magna eget bibendum. Cras tempor imperdiet lacus id vehicula. Pellentesque ornare augue nec eros dictum, at ultrices justo suscipit. Aliquam consequat, ex sit amet gravida ultrices, arcu odio finibus tellus, vitae iaculis purus est a est. Fusce vulputate nisi at neque facilisis rutrum. Curabitur sed consectetur sapien, et dapibus mi.
Nunc arcu lorem, pharetra quis mattis non, iaculis vel magna. Phasellus consectetur elit nec iaculis pellentesque. Phasellus lobortis ex ex, sed imperdiet ante posuere a. Phasellus volutpat dui ut orci placerat, id laoreet libero sagittis. Nulla dignissim accumsan arcu, a pellentesque mauris ultricies ut. Ut in metus dolor. Vivamus blandit odio urna, sed euismod ex scelerisque elementum. Nunc lobortis efficitur nunc eget suscipit. Nunc at nisi diam. Fusce blandit, est a condimentum placerat, elit nisl malesuada tellus, sit amet aliquet quam enim sed eros. Morbi eget placerat lorem. Nunc ultrices odio nisl, suscipit porttitor est congue eu. Nunc rhoncus risus eleifend, ultrices nisi nec, laoreet felis.
Phasellus consectetur odio id pellentesque sollicitudin. Pellentesque volutpat sem quis malesuada pretium. Vestibulum a felis sit amet nulla lobortis efficitur consectetur at justo. Sed ut arcu vitae nibh eleifend pulvinar nec vulputate est. Donec pretium, elit sed commodo commodo, metus elit volutpat tortor, eleifend bibendum metus augue vel elit. Fusce placerat justo luctus purus condimentum sollicitudin. Donec magna erat, vehicula eget lectus a, dapibus fringilla enim. Donec varius felis at libero ultricies tempus. Donec ligula lacus, fringilla non metus sed, pellentesque malesuada eros. Aliquam vel libero vitae turpis gravida condimentum sed tristique nunc. Maecenas aliquam urna nec dolor vulputate congue. Morbi mattis purus quis nisi dictum, eu ultricies risus euismod. Pellentesque mi velit, imperdiet a cursus nec, consequat ac dui. Suspendisse ullamcorper elit quis turpis porta, non blandit dui auctor. Nullam et diam facilisis, consequat augue pulvinar, molestie orci.
Etiam ac scelerisque nulla. Cras at justo vel enim lacinia sagittis sit amet nec tellus. Nunc convallis commodo pretium. Maecenas condimentum nulla suscipit, commodo neque sit amet, fermentum enim. Curabitur dui diam, gravida in tellus vitae, luctus feugiat nibh. Vestibulum in aliquam tellus. Nunc tempus odio vel lectus vehicula, sit amet lobortis libero condimentum.
Nam dictum, erat at hendrerit tincidunt, nulla lectus convallis sem, a pretium lectus nunc non nulla. Nulla gravida vulputate justo, eu viverra felis laoreet vel. Suspendisse arcu eros, rutrum sit amet molestie vitae, cursus sed lorem. Fusce orci metus, aliquam vel ex sed, rhoncus commodo augue. Donec a eros a nibh feugiat blandit. Proin venenatis pretium pretium. Praesent nec arcu leo. Fusce lacus turpis, porttitor vitae commodo id, hendrerit eget sem. Etiam cursus tincidunt eros ut venenatis. Vestibulum ultricies consectetur leo, eu imperdiet leo ultricies quis. Donec in enim sit amet mi imperdiet dignissim. In egestas interdum risus, sit amet egestas orci lobortis eu. Cras cursus euismod nisi sit amet euismod. Curabitur malesuada venenatis sem ac maximus. Donec mattis viverra euismod. Curabitur aliquet enim tempus dapibus porttitor.
Nulla sit amet volutpat enim. Nam gravida mauris erat, at sagittis odio iaculis quis. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse dapibus id velit ac viverra. Nullam diam massa, condimentum in velit at, eleifend finibus nisi. Aliquam ut tellus non massa semper blandit. Maecenas condimentum venenatis sagittis. Sed quis ante a orci mollis dictum. Etiam interdum tempus purus at aliquam. Vestibulum cursus pulvinar est vitae lacinia. Quisque nibh risus, cursus id scelerisque vitae, elementum quis diam. Aliquam pharetra massa a ex ultrices maximus. Morbi laoreet iaculis leo, vitae maximus odio.
Fusce volutpat, lacus non porttitor venenatis, nulla enim consectetur lorem, vel fermentum leo tellus non ex. Quisque pellentesque magna nec nibh blandit tincidunt. Nulla facilisi. Etiam at vulputate metus. Etiam posuere imperdiet urna, non dictum dui finibus laoreet. Vivamus vitae fringilla velit. Suspendisse tortor odio, malesuada eget nibh in, lacinia placerat felis. Fusce id lobortis ipsum, eu posuere erat. Donec vel justo erat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris molestie gravida tellus, vel suscipit neque accumsan sed. Duis ac felis in mi venenatis rutrum non ac massa. Vivamus orci velit, efficitur non arcu quis, cursus gravida quam. Curabitur elementum felis luctus lobortis laoreet.
Donec pellentesque, lorem a imperdiet faucibus, leo lectus porttitor nulla, eget consequat neque ex ut est. Aenean massa tortor, iaculis id libero in, gravida sagittis justo. Duis sit amet placerat sapien, vel dictum quam. Proin maximus quam libero, a dictum mi tincidunt ultrices. Duis lobortis nisi tempor mauris egestas, in condimentum augue rutrum. Vivamus eget libero eu lorem malesuada tincidunt eu vitae nunc. Nam justo diam, eleifend id enim sit amet, eleifend facilisis purus. Phasellus convallis quam vitae augue auctor pretium. Vivamus et tristique arcu. Maecenas et urna porta, varius dui a, scelerisque mi. Fusce eget ex aliquam, commodo augue sed, ornare lacus. Quisque congue dapibus nisl.
Morbi pretium ac arcu nec accumsan. Nullam non cursus neque. Etiam eget mauris congue, faucibus felis sed, bibendum sapien. In efficitur ipsum eget bibendum pharetra. Aliquam gravida, leo ac dapibus feugiat, turpis ante ornare dui, sit amet consequat metus nunc sed nibh. Morbi pellentesque magna a justo vulputate, sed convallis turpis volutpat. Nulla accumsan odio sed nibh vulputate vulputate in quis tellus. Ut quis dolor cursus, accumsan tellus sed, condimentum mauris. Nam ullamcorper nulla in pellentesque aliquet.
Morbi vulputate finibus odio vitae vulputate. Quisque et imperdiet magna. Suspendisse sem nunc, pulvinar ac cursus sed, finibus vitae est. Suspendisse convallis, erat ornare tincidunt eleifend, turpis orci dapibus dolor, vitae mattis massa lectus ac lacus. Nunc id sem tincidunt, dapibus enim eget, tristique ex. In eu dictum enim. Curabitur ut efficitur enim. Integer ac eros mi. Pellentesque tempus hendrerit nunc, quis placerat quam lobortis at. Ut euismod ornare urna efficitur rhoncus. Duis in lorem enim.
In hac habitasse platea dictumst. Curabitur tincidunt sollicitudin lacus, id interdum velit auctor at. Proin eget risus est. Nunc enim mi, vestibulum ac risus sit amet, tristique rutrum tortor. Fusce quis nulla mattis, fermentum dolor in, semper nulla. Pellentesque vel lectus magna. Nam eget arcu suscipit, varius justo a, ornare quam. Donec vitae sollicitudin nibh, eget iaculis felis. Nullam commodo purus et magna finibus, vitae finibus ipsum aliquam. Vestibulum condimentum dui dolor, ut dictum mi maximus eu. Nunc et pretium sem. Etiam accumsan eu felis in convallis. Nullam pulvinar vestibulum tellus nec rutrum. Suspendisse semper, velit vitae vulputate posuere, nunc dolor egestas neque, at efficitur turpis metus nec leo. Etiam bibendum massa condimentum iaculis vestibulum. Morbi ipsum purus, efficitur eget maximus ac, mattis id massa.
Nam volutpat velit sed nulla ullamcorper facilisis. Sed commodo non turpis sed imperdiet. Pellentesque malesuada nibh eget commodo accumsan. Curabitur iaculis eget sapien ac aliquam. Etiam sed ex lectus. Vivamus et urna erat. Nunc quis efficitur felis. Nulla sagittis lacus a ex tristique, vehicula vulputate enim suscipit. Pellentesque pulvinar vitae leo pellentesque gravida. Sed efficitur pretium interdum. Aenean non rutrum ligula. Etiam ultrices nisl nec tempor efficitur.
Nulla eget nulla dictum, elementum lacus vitae, congue tellus. Proin sit amet pellentesque mauris, sit amet aliquet dolor. Etiam eget nulla ligula. Vestibulum imperdiet pretium mauris, ac tempus erat eleifend at. Ut condimentum fringilla ex ut faucibus. Cras eros nunc, iaculis et maximus vitae, auctor sed sapien. Fusce eu odio non ipsum posuere sagittis. Praesent nunc arcu, vestibulum ut condimentum eu, aliquam eu orci. Fusce in arcu ultricies, dictum enim consequat, facilisis turpis. Pellentesque nunc nisi, ultrices et leo et, consequat tincidunt lorem.
Pellentesque sed faucibus ex. Suspendisse ultrices vulputate dolor. Nam eu dolor suscipit, vehicula sapien non, tempus orci. Quisque eget porta nisi, id tincidunt tellus. Fusce sodales purus et ligula consequat, quis sodales metus tempor. Sed dictum libero placerat nibh tincidunt, eget aliquam orci feugiat. Suspendisse ullamcorper sapien quis porttitor sagittis. Integer vel laoreet elit. Mauris convallis viverra sapien eget accumsan. In hac habitasse platea dictumst. Sed et arcu nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Curabitur quis dictum tortor, at imperdiet lorem.
Sed pulvinar nisi eu ante condimentum rutrum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed malesuada mauris nec dui rhoncus lacinia. Curabitur tincidunt ullamcorper felis ac ullamcorper. Suspendisse dolor est, suscipit ac ligula a, molestie dapibus lectus. Morbi semper, tortor nec tincidunt elementum, nisl tortor consectetur massa, in sodales urna leo sit amet justo. Fusce eu sem eget diam blandit venenatis vel in odio. Vivamus volutpat feugiat sem, sit amet pellentesque orci molestie sed. Proin tincidunt hendrerit nibh, in blandit lacus. Maecenas mattis finibus odio, nec scelerisque ligula aliquam id. Quisque viverra velit eget sem suscipit dapibus. Integer pretium, turpis non commodo condimentum, est felis gravida arcu, vitae elementum lorem erat sed sapien.
Mauris sed urna eu lacus sagittis rhoncus. Sed eleifend id erat quis vestibulum. Suspendisse mattis tempor neque, in vestibulum nisl molestie sit amet. Nulla blandit lectus semper dui accumsan molestie. Ut in dui non augue laoreet imperdiet vitae a orci. Quisque a leo hendrerit, ultrices sem vel, rhoncus augue. Donec quis facilisis enim, ut efficitur enim. Donec finibus libero vitae sem fringilla, at pharetra arcu volutpat. Duis ut mollis dolor. Vestibulum maximus justo nisi, id euismod risus sodales vel.
Sed ut interdum quam, quis mollis lorem. Quisque eget arcu nec justo porta malesuada quis sed odio. Proin tempus enim ac neque efficitur sollicitudin. Fusce a venenatis dui, eget tincidunt sapien. Aliquam sodales hendrerit turpis sit amet commodo. Donec id dui in enim dignissim dignissim a ut lacus. Donec varius bibendum urna sollicitudin aliquet. In hac habitasse platea dictumst.
Donec suscipit cursus porta. Integer interdum ante eget suscipit egestas. Donec ultricies dignissim lectus, a aliquet diam auctor nec. Curabitur sapien turpis, facilisis eleifend metus id, euismod ultricies leo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus rutrum nisi vel leo vulputate dapibus. Fusce sit amet massa sed velit fermentum maximus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ante ligula, sollicitudin sit amet facilisis quis, consequat id ex. Sed imperdiet venenatis tellus, vel gravida metus tempor molestie. Phasellus eleifend, neque eu fringilla fermentum, diam odio luctus lacus, ullamcorper viverra urna elit euismod metus.
Vestibulum sed arcu purus. Quisque sed tellus mattis, convallis ipsum eget, finibus turpis. Nulla quis accumsan sapien. Nam risus felis, finibus at sapien ac, commodo pharetra turpis. Vestibulum vel arcu dictum, gravida purus in, volutpat nisi. Vivamus risus felis, faucibus et erat in, tristique mollis nisi. Morbi sollicitudin ipsum vel diam placerat vestibulum. Morbi dictum velit et posuere tincidunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec scelerisque risus eu hendrerit pharetra.
Fusce accumsan tempor est, nec fermentum augue posuere et. Etiam aliquam ullamcorper tortor iaculis condimentum. Aenean vel ullamcorper leo. Quisque consequat sit amet sapien id sodales. Vestibulum pretium dui a eros mollis volutpat. Quisque ac sodales felis. In hac habitasse platea dictumst.
Nullam placerat vestibulum ex sed porta. Pellentesque vel est iaculis, pretium neque eu, condimentum elit. Mauris vitae congue sem. Praesent molestie commodo orci a viverra. Donec consectetur tempus imperdiet. Aenean sed elit at turpis consequat ultricies. Curabitur consequat a orci sit amet feugiat. Donec fringilla, risus sed lobortis efficitur, arcu arcu elementum lorem, eu pulvinar elit eros at massa.
Mauris nec molestie turpis. Sed porttitor, orci vel rutrum accumsan, risus arcu pellentesque ante, a pretium libero sem sed lectus. Quisque ornare ipsum id libero sagittis scelerisque in nec lorem. Nunc sagittis eros diam, in elementum enim mattis vel. Duis rhoncus volutpat aliquam. Mauris hendrerit ex aliquam faucibus vestibulum. In viverra lobortis magna. Nullam tincidunt nunc id neque efficitur, et commodo dolor bibendum.
Duis fermentum massa vitae nisi accumsan, et volutpat libero porttitor. Quisque a nibh et mauris lobortis pharetra nec ac diam. Donec ultricies, tellus nec feugiat porta, felis quam accumsan ipsum, vitae laoreet sapien sem id ligula. Mauris vel erat at sapien consectetur dignissim. Aenean placerat tellus in leo fringilla, non condimentum magna placerat. Ut at justo maximus, tristique quam id, euismod orci. Morbi eget metus erat. Donec ultrices odio eget velit accumsan, vitae blandit leo dignissim. Vivamus quis auctor ipsum. Etiam placerat auctor rhoncus. Curabitur lacus justo, rutrum vitae placerat in, hendrerit ultricies augue. Integer vestibulum bibendum magna vehicula hendrerit. Nulla vehicula leo ut est feugiat imperdiet et id lorem. Maecenas quis lacus lobortis, viverra dui et, dapibus eros.
Fusce ac sapien ut odio blandit pellentesque vitae nec mauris. Aliquam a ipsum id urna condimentum dictum. Proin vehicula bibendum ligula vitae consectetur. Nullam id erat mattis, vehicula velit eu, finibus nisl. Fusce lorem neque, vehicula sed diam non, viverra venenatis ligula. Fusce fermentum turpis at volutpat mollis. Praesent nec lobortis ligula. Nulla magna nulla, consectetur vitae tincidunt ut, eleifend eu nulla. Pellentesque mollis erat et interdum vulputate.
Sed tincidunt pretium dui, et pellentesque ex interdum vitae. Mauris non pretium lectus. Etiam in aliquam dui, nec porttitor turpis. Quisque sagittis, tellus in tincidunt pellentesque, arcu urna fringilla sem, a dictum libero metus ac enim. Mauris mollis nibh quis dui finibus, eu porta arcu efficitur. Vivamus neque ipsum, vulputate a efficitur ut, laoreet eu dui. Sed in nisl mattis, tincidunt orci nec, finibus dui. Donec lobortis vitae nibh eget lobortis. Integer at fringilla dui, consectetur fringilla libero. Pellentesque magna augue, dignissim non sodales nec, convallis quis tellus. Proin tristique, mi et malesuada bibendum, tortor diam consequat felis, et rhoncus quam ante a tellus. Aenean gravida, justo eu fermentum ultricies, elit turpis vehicula felis, nec viverra lorem velit id lorem.
Aenean luctus scelerisque odio at mattis. Suspendisse sit amet malesuada leo. Nunc nec condimentum enim. Maecenas finibus massa diam. Morbi blandit scelerisque enim, id lobortis odio pellentesque in. In quis mi dui. In dignissim, leo et aliquam placerat, erat urna placerat purus, venenatis convallis ligula nibh euismod urna. Ut interdum eget turpis vel tincidunt. Nulla facilisi. Integer scelerisque augue nunc, nec pharetra purus volutpat id. Aliquam bibendum ac enim et tempor. Vivamus sit amet nisi vel lacus tristique euismod at eu eros. Fusce sed nisi ipsum. Aenean felis magna, condimentum non sapien in, pharetra maximus dui. Sed neque felis, sodales sed nisi sollicitudin, congue congue nulla.
Mauris consectetur dolor ac leo luctus venenatis. Proin blandit commodo lacus sed mollis. Nam vel est at justo laoreet finibus vitae vel turpis. Donec at augue libero. Sed accumsan justo sed est tempus blandit. Cras eros diam, pellentesque fermentum tempor in, malesuada non velit. Cras volutpat ante diam. Vivamus luctus tempus nisi, sit amet elementum massa tincidunt vitae. Suspendisse hendrerit, tortor sit amet venenatis interdum, tortor neque dictum nibh, sit amet interdum dui lacus quis lectus. Sed nisi sem, rhoncus sed aliquet sed, finibus et ante. Nulla blandit orci eu nibh ullamcorper porta. Praesent id magna id neque cursus facilisis.
Proin convallis, ligula eu fringilla tempus, risus felis sagittis quam, in tempor nisi magna ac risus. Sed imperdiet accumsan magna. Mauris maximus diam eget tincidunt luctus. Duis libero risus, molestie vitae orci consectetur, elementum tristique nisl. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Duis quis diam nunc. Praesent iaculis lacus ut diam tristique consectetur. Vivamus dui ante, mattis eget eros a, tincidunt lacinia risus. Ut ultrices porttitor odio, ac scelerisque enim efficitur id. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam vehicula accumsan erat, id mollis nisl accumsan eu. Nunc ipsum sapien, egestas et sem congue, consequat consectetur nunc. Vivamus pretium est ipsum, eget condimentum est bibendum sed. Donec lobortis blandit est, sit amet consectetur arcu. Vivamus sapien est, convallis sed laoreet eget, ornare eget tellus.
Sed condimentum, magna gravida dignissim hendrerit, nisl nunc vehicula justo, ut vehicula ipsum purus non dolor. Curabitur quis tellus porttitor, venenatis tortor eu, interdum justo. Suspendisse bibendum orci sit amet malesuada tincidunt. Sed maximus feugiat tempus. Nullam in ante ante. Nullam convallis arcu quis sapien facilisis, id dignissim sapien malesuada. Cras tempor, enim in consequat vestibulum, dui nisi maximus nulla, et dignissim justo odio non orci.
Suspendisse fringilla turpis sed tortor efficitur, a placerat nisi vestibulum. Etiam convallis lacus vitae dignissim tempor. Suspendisse id mauris a risus bibendum maximus. Nullam dignissim sit amet ligula ac lobortis. Nullam feugiat est quis tortor fermentum lobortis eget eget libero. Donec non suscipit nulla. Sed ac lacus neque. Nunc imperdiet mi ut metus sagittis mollis. Sed varius sodales accumsan. Donec auctor elementum sagittis. Donec odio mauris, faucibus quis mollis nec, efficitur at eros. Maecenas massa ligula, fringilla eget mi quis, placerat vehicula lacus. Maecenas leo nibh, bibendum ac sem sed, dignissim iaculis nibh.
Donec in tincidunt arcu. Quisque commodo rutrum ornare. Aenean eu purus pretium, faucibus justo eget, pharetra urna. Fusce pharetra facilisis sapien sed luctus. Cras non elit vestibulum, rutrum lectus ut, bibendum erat. Duis vitae est eu libero vehicula viverra at vitae ipsum. Nunc justo ligula, tempor vitae ex sit amet, consectetur placerat ex. Aenean ligula dui, fermentum vel semper sed, semper eu orci. Etiam gravida sagittis eros, et pellentesque justo. Curabitur et pulvinar velit. In semper odio leo, ut pharetra nunc accumsan nec. Sed velit augue, ultrices in ante blandit, feugiat pretium massa. Maecenas bibendum, nibh eget suscipit ultrices, elit felis auctor risus, nec dictum nibh neque ac diam. Sed consequat arcu id nibh tristique sodales. Phasellus vulputate placerat velit sed condimentum.
Nulla facilisis leo nec efficitur venenatis. Phasellus ac interdum ligula. Curabitur pharetra laoreet ipsum, ac porta nunc tristique eu. Morbi mollis varius massa ac egestas. Vivamus sed nibh tellus. Pellentesque auctor sapien aliquet nunc semper venenatis. Aenean dignissim venenatis feugiat.
Donec ut tincidunt sapien, ut consequat felis. Morbi luctus orci in elit luctus blandit. Proin fringilla odio vel elit tristique tincidunt. Integer tellus metus, vestibulum eu eleifend eu, finibus id velit. Curabitur nec turpis accumsan, aliquam nibh nec, luctus velit. Curabitur id velit eget quam scelerisque pretium et a mauris. Suspendisse vel felis lectus. Maecenas a augue lectus. Sed viverra maximus nisl, at tempor lectus ornare ut. Donec ac semper velit. Nunc hendrerit sapien et tellus fermentum sagittis.
Sed malesuada enim et est tincidunt, a tristique mi porttitor. Sed interdum, orci non sagittis sagittis, ipsum enim aliquet erat, quis pharetra sapien lacus vel tellus. Nunc dictum nunc sed suscipit tempus. In hac habitasse platea dictumst. Maecenas gravida vestibulum faucibus. Nam eget tempus odio. Maecenas a eleifend massa, ut efficitur odio.
Integer fermentum lacus turpis, at aliquet diam convallis non. Ut ac arcu vitae felis dapibus porttitor a sit amet orci. Suspendisse nisl libero, fringilla non posuere vel, pharetra nec nisl. Pellentesque et euismod nibh, eget ornare urna. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In viverra faucibus purus, a congue felis interdum ut. Aliquam vitae tellus sed felis mattis elementum. Fusce eleifend lorem ut ex euismod euismod. Donec ac consectetur augue. Cras posuere neque massa, sed euismod urna mattis ac. Mauris nec sollicitudin lacus. Sed eu massa et lorem viverra bibendum sed sit amet arcu. Vivamus gravida hendrerit mi, cursus iaculis nunc imperdiet a. Quisque purus mauris, viverra sit amet euismod sit amet, rutrum id nibh. Donec dignissim diam nibh, quis rhoncus nulla suscipit at. Mauris dapibus, tellus et efficitur aliquet, tellus diam vehicula enim, ac fermentum ante justo nec turpis.
Nullam sapien orci, pharetra a elit eu, interdum interdum libero. Ut eu pulvinar ipsum. Aliquam hendrerit elit arcu, vel volutpat nisl convallis id. In maximus justo sed magna euismod sagittis. Morbi fermentum ante nisi, id volutpat nisl congue a. Praesent sed efficitur turpis. Pellentesque eu turpis nec massa semper semper. Donec tincidunt ac lacus eget maximus. Quisque vel tortor eros. Nam vitae urna a mi maximus vestibulum.
Phasellus et eros lectus. Mauris luctus diam a dolor sagittis, quis lacinia odio euismod. Ut sed porttitor sem. Mauris faucibus vitae ex et malesuada. Nullam quis tincidunt diam, et lobortis ipsum. Pellentesque scelerisque metus vel luctus porttitor. Donec eu vehicula erat, ornare efficitur elit. Praesent ullamcorper est sit amet odio finibus malesuada. Nulla molestie id odio quis semper. In ultrices, massa quis consequat placerat, mi magna porttitor enim, sed blandit nulla nunc nec nunc. Duis suscipit, mauris sit amet aliquet sodales, arcu massa efficitur enim, et sollicitudin urna nisi sed mi.
Nunc tempus dolor lorem, consectetur semper dolor feugiat in. In imperdiet ullamcorper erat id accumsan. Sed at molestie sem. Phasellus sagittis consequat orci, in feugiat odio imperdiet ac. Aliquam auctor eros vulputate dolor rhoncus, ac hendrerit enim lacinia. Morbi augue orci, sollicitudin sed consequat fermentum, hendrerit sed velit. Sed a turpis aliquet, fringilla elit eu, dictum libero. Donec aliquam urna mauris, vel interdum urna congue vel. Sed ex tellus, consectetur sed imperdiet at, finibus efficitur nisl. Phasellus aliquam semper libero finibus rhoncus. Pellentesque dolor augue, porta eu urna eu, ultricies lacinia metus. Praesent cursus ante dapibus, volutpat nunc id, pharetra diam. Nam iaculis enim non faucibus dapibus. Vivamus est augue, aliquam ac ipsum eget, vestibulum commodo lorem. Proin porttitor nibh vitae est fermentum, id suscipit dolor elementum.
Praesent tempor fermentum tellus, vitae tincidunt turpis mattis a. Etiam eu magna et eros iaculis ullamcorper. Pellentesque pharetra turpis metus, nec bibendum leo fermentum et. Sed arcu nulla, gravida nec leo quis, efficitur suscipit libero. Quisque purus mi, auctor vitae quam quis, tincidunt porta sapien. Proin eu facilisis orci, at eleifend lectus. Aenean blandit viverra nulla non tempor. Duis venenatis tortor nec finibus interdum.
Duis sed tortor nulla. Donec scelerisque sem purus, id varius risus lobortis ut. Proin velit ipsum, vulputate vitae viverra ac, viverra quis ante. Maecenas eget sapien non sem volutpat elementum finibus eu nunc. Pellentesque non ex quis leo gravida malesuada quis mollis eros. Fusce mollis nunc eget risus vehicula eleifend in sed lorem. In hac habitasse platea dictumst. Nulla quis pretium nisl. Vivamus dignissim, nibh in luctus ornare, nunc risus commodo enim, et aliquet libero neque ut orci. Suspendisse sed quam eget urna viverra porta. Aenean ligula ligula, congue vel ullamcorper et, vehicula quis tortor. Sed dictum nec nulla eget sollicitudin. Aliquam molestie ligula justo, sit amet faucibus dolor ultricies eget.
Aliquam et risus posuere, malesuada nibh id, malesuada sapien. Curabitur lacus ex, ullamcorper id pharetra at, maximus vel augue. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec varius felis quis tortor laoreet volutpat. Quisque iaculis posuere enim, tincidunt rhoncus erat sodales vel. Etiam sit amet purus suscipit, tempus lacus non, semper tellus. Pellentesque in aliquet urna. Vivamus a justo bibendum, tristique tellus pretium, fringilla eros.
Cras eget arcu condimentum, varius eros vel, fermentum quam. Duis ut turpis ut erat laoreet pulvinar et non lectus. Nam mattis libero quis congue pharetra. In vulputate quis massa quis eleifend. Donec eu velit ac urna tempor blandit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Etiam sed lobortis mi. Etiam porttitor, leo sed dictum rutrum, justo massa semper tortor, vel lobortis urna elit a felis. Aliquam odio augue, pellentesque sed ex sed, bibendum pellentesque turpis. Morbi viverra nulla ac ipsum mattis, non auctor tortor condimentum. Vestibulum pretium nec nulla vitae sollicitudin. Integer scelerisque libero id blandit pharetra.
Ut aliquet libero id commodo mattis. Nulla ut ex malesuada, tincidunt nisl in, lacinia nisl. Pellentesque scelerisque semper mauris, nec tincidunt urna bibendum id. Nulla facilisi. Nulla facilisi. Sed id fringilla odio. Fusce tempus egestas mauris nec accumsan. Integer dictum, elit vehicula molestie ultrices, purus sapien luctus enim, nec suscipit felis neque sit amet mi. Nulla sed fermentum orci.
Donec id lorem euismod, posuere leo in, pharetra velit. Nullam sed blandit mauris. Proin vitae congue neque, quis tristique ante. Donec consectetur a velit sed congue. Sed finibus dui luctus, maximus metus et, tempor sapien. Quisque vulputate molestie arcu eu malesuada. Ut consectetur rutrum diam eu viverra. Suspendisse interdum ipsum mattis neque pulvinar posuere. Donec dolor erat, bibendum vitae malesuada ac, hendrerit quis metus. Duis vitae urna orci. Sed lobortis nisl ut tortor eleifend malesuada. Curabitur dapibus ex vitae ante ornare, et aliquet orci bibendum.
Quisque sollicitudin metus turpis, vitae condimentum metus semper id. Duis pharetra facilisis leo vel egestas. Vivamus ut magna justo. Sed quis vehicula turpis, sed dictum augue. Praesent erat tellus, fermentum non vestibulum vitae, commodo in lectus. Integer eu rutrum nibh. Sed pellentesque lacinia mauris, et varius orci laoreet ut. Nulla condimentum ante eros, sed aliquam augue gravida nec. Integer auctor nisl nec mauris vulputate laoreet eget nec lorem. Suspendisse convallis dui a nisi dapibus egestas sit amet non quam. Cras vulputate sapien sit amet lacinia scelerisque. Quisque justo ante, tincidunt in risus ut, dapibus maximus mauris. Vivamus eget lectus nec mi eleifend viverra. Fusce efficitur turpis vel erat auctor aliquam. Nunc volutpat felis massa, sit amet egestas libero mollis non.
In in tempus sapien, sit amet lacinia lacus. Phasellus vehicula sodales cursus. Pellentesque at mollis sapien. Quisque sollicitudin, lorem nec condimentum fringilla, velit arcu vehicula dui, at porttitor turpis leo nec nunc. Mauris elementum eros purus, malesuada consectetur orci sodales eu. Fusce suscipit, turpis vel mattis finibus, leo lacus maximus nibh, ac aliquet nunc enim et lectus. Donec nec nulla est. Duis porta id dolor a vehicula. Mauris accumsan arcu eget metus scelerisque, eget consequat mi rutrum. Aenean placerat tristique feugiat.
Mauris in odio neque. In pretium libero condimentum urna fermentum cursus. Vivamus tincidunt tincidunt volutpat. Aenean sed faucibus dui, tincidunt egestas eros. Nunc velit velit, aliquam eget purus eu, dictum ullamcorper eros. Vestibulum molestie interdum pulvinar. In ac mauris non metus consectetur luctus sed in risus. Sed eget consequat augue. Nulla posuere ligula augue, eu pretium ipsum placerat a. Mauris quis ullamcorper metus, at egestas tellus.
Ut consectetur placerat mauris vel placerat. Nam volutpat sapien ut ornare congue. Vestibulum cursus magna at scelerisque venenatis. Nullam ac lacus quis sapien lobortis ullamcorper eu in libero. Quisque semper vitae urna vitae dictum. Mauris pretium elementum turpis, vel varius odio ullamcorper in. Vestibulum efficitur malesuada est, eu venenatis mauris iaculis sed. Sed suscipit egestas lacus, at porta risus cursus et. Aenean nec augue tempor est elementum bibendum vitae non nisl. Proin molestie porttitor dolor vitae laoreet. Ut sagittis, dui quis pulvinar ultrices, neque tortor auctor nibh, sed ornare mauris mauris vel lacus. Nunc sed ullamcorper lorem. Maecenas facilisis arcu non diam feugiat rhoncus.
Mauris dictum iaculis molestie. Duis viverra pellentesque volutpat. Proin id felis velit. Morbi sed tellus sed ligula molestie ultricies. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque at lobortis ex. Integer pharetra nibh diam, vehicula scelerisque mi vehicula sit amet. Proin lobortis at augue non bibendum. Morbi porttitor varius tortor, et tristique nibh cursus vitae. Maecenas cursus facilisis tortor, aliquet volutpat ante convallis eget. Nunc odio turpis, pellentesque sed enim sit amet, posuere eleifend magna. Duis ultrices felis ipsum, eu ornare ex iaculis et. Curabitur metus diam, rutrum sit amet rhoncus et, imperdiet sit amet neque. Cras nec dui laoreet magna condimentum fringilla vel quis orci. Morbi sit amet nisi luctus, commodo lacus et, aliquam felis.
Integer pharetra lacinia metus, ut gravida enim varius nec. Proin in risus augue. Aenean vel urna elit. Cras sed erat molestie enim fringilla posuere sed vel lorem. Suspendisse mauris massa, tempus quis tortor ut, placerat egestas ligula. Nam eu massa dictum, fermentum est nec, lacinia felis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Pellentesque tellus quam, placerat commodo tincidunt id, tincidunt ut lectus. Integer ut blandit diam. Duis quis rutrum augue. Nulla ex elit, malesuada vel interdum in, commodo a turpis. Quisque pharetra neque at imperdiet ornare. Cras tincidunt arcu tellus, sit amet ultricies nisi congue nec. Curabitur vel est sed dolor euismod tempus. Praesent at sagittis risus, id viverra neque.
Donec augue leo, pellentesque eu volutpat quis, suscipit in mi. Aenean placerat libero id ornare vestibulum. Maecenas nec faucibus nisi. Curabitur elementum aliquam congue. Maecenas nec lobortis purus. Nam aliquam justo erat, in placerat magna rutrum suscipit. Vestibulum non sem et ipsum lobortis consectetur. Sed sed commodo dui, in feugiat ipsum. Proin mattis gravida lectus, non placerat magna fringilla sit amet.
Integer erat sem, hendrerit id venenatis quis, vestibulum in orci. Praesent sed nisl in sem euismod suscipit. Vivamus in lectus est. Nulla sed neque ut dui posuere interdum sed in mi. Maecenas tincidunt porta ornare. Quisque id sapien aliquet eros consectetur ultrices. In dui turpis, tincidunt ac consectetur vel, scelerisque id arcu. Curabitur sed auctor tellus, sit amet congue ex. Vestibulum accumsan, diam id interdum feugiat, ex turpis fermentum enim, nec tristique ante lacus in sem. Fusce vel ante luctus, mollis ante quis, porttitor leo.
Morbi luctus cursus sapien, accumsan pulvinar urna euismod id. Duis fermentum mi a sapien sollicitudin, ac laoreet magna vestibulum. Integer faucibus diam id dui lacinia, et egestas felis faucibus. Vestibulum efficitur quam at condimentum vulputate. Donec et orci mauris. Cras sit amet dictum nulla, eu vestibulum lacus. Suspendisse rhoncus nibh neque, sit amet semper leo eleifend vel. In tortor tellus, ornare a risus at, malesuada porttitor massa. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nam urna nunc, ultrices at nulla sit amet, cursus malesuada lacus. Integer nec sem faucibus, placerat sapien ac, placerat sapien. Cras molestie arcu imperdiet nisi accumsan luctus. In in interdum turpis. Aliquam posuere volutpat pharetra. Aenean pharetra volutpat tempor. Aenean quis turpis ut libero interdum gravida. Maecenas ac scelerisque velit. Morbi non nulla dignissim, maximus lacus sit amet, vestibulum metus. Nunc convallis elit non tincidunt ultricies. Suspendisse aliquet vel lectus a facilisis. Nulla sit amet venenatis odio.
Suspendisse magna nisi, varius luctus ipsum et, imperdiet consequat lacus. Nulla quis congue augue. Proin vehicula mi leo, suscipit dignissim ex egestas eu. Quisque interdum erat quis quam facilisis, in feugiat felis tincidunt. Donec orci odio, porttitor vitae pellentesque eu, rhoncus ac risus. Aliquam faucibus commodo orci. Sed eu arcu sed diam venenatis vulputate a ut sem. Integer nec dapibus dolor. Aenean fringilla malesuada quam, non sagittis libero venenatis ac. Integer blandit neque eget leo auctor lobortis. Donec at tincidunt nunc, a efficitur purus. Vestibulum et orci lobortis, cursus lorem dapibus, malesuada nisi. Nunc in ipsum quis ipsum malesuada lacinia eu non tortor. Mauris ac vehicula tellus.
Nullam ut aliquet ipsum, vitae porttitor sapien. Curabitur eleifend sem id venenatis elementum. Nullam non augue eu arcu posuere finibus sit amet eget lorem. Sed vehicula lectus a justo ultrices, eget pharetra augue eleifend. Pellentesque tempor turpis sed leo viverra tempus. Duis volutpat non urna sit amet dictum. Mauris eu orci pellentesque, rhoncus purus a, fermentum dui. Cras accumsan commodo euismod. In suscipit aliquet ex, a scelerisque tortor ultrices ac. Donec ipsum dui, vulputate non gravida et, vulputate ac dolor. Curabitur et hendrerit arcu, et hendrerit erat. Vivamus suscipit risus eu orci sollicitudin, vel convallis enim ultricies. Cras vehicula consequat risus ac gravida. Duis venenatis nisi vel leo pulvinar bibendum. Mauris elementum et quam eu elementum.
Aliquam erat volutpat. Sed a dapibus diam. Quisque laoreet sit amet tortor sodales interdum. Duis congue venenatis odio, suscipit dignissim justo pretium non. Nunc eu arcu ullamcorper, placerat nisl a, euismod libero. Phasellus molestie mi quis est egestas, ac venenatis justo malesuada. Fusce et nisi ullamcorper, pharetra risus non, venenatis libero. In et sodales ante. Ut quis odio at diam interdum laoreet non nec odio. Morbi rutrum metus nisl, sit amet finibus ipsum accumsan vitae. Praesent fringilla rhoncus erat id ultrices. Aenean ut erat non nisl blandit bibendum ac sit amet lectus. Pellentesque scelerisque dui nec fermentum eleifend. Nulla rhoncus magna non orci sollicitudin fermentum. Nullam consequat orci vitae ullamcorper laoreet. Nam congue tincidunt ligula condimentum ultricies.
Donec nec eros vitae ante commodo scelerisque. Donec felis ex, ornare ut neque a, volutpat blandit enim. Fusce a mi a nunc facilisis semper. Fusce mollis justo eu mi tempor eleifend. Sed ultrices urna quis ipsum cursus, et elementum ante posuere. Praesent viverra vestibulum iaculis. Praesent vel faucibus erat. Integer et diam dapibus, convallis arcu quis, pharetra nulla. Mauris enim arcu, fringilla in tincidunt non, suscipit eu erat. Etiam quis ante euismod, gravida nisl vel, tincidunt libero. Vivamus ac eleifend arcu. Mauris egestas, eros ut porttitor vehicula, erat ligula faucibus elit, ut suscipit massa augue ut est. Aliquam dapibus efficitur purus eu pretium. Donec pulvinar turpis orci. Mauris nisl velit, pharetra sed nisl at, pellentesque convallis felis. Etiam vitae lectus lectus.
Aenean eu ligula interdum, feugiat lacus quis, feugiat tortor. Etiam mattis massa vel augue ullamcorper egestas. Vivamus in orci magna. Vivamus a dictum nisl, vitae ornare justo. Sed libero tellus, dapibus in auctor et, porta vel augue. Nullam scelerisque tellus pretium nibh varius vestibulum. Sed et neque turpis. Proin malesuada nisl ut felis iaculis, ac aliquam lorem euismod. Vestibulum pretium sapien sit amet enim egestas elementum. Cras eget est luctus, mollis sapien ac, porta ex. Praesent venenatis dapibus lacus, ut efficitur lacus fringilla non. Integer eu rutrum magna. Integer iaculis venenatis blandit. Vestibulum euismod vitae leo tincidunt dignissim. Interdum et malesuada fames ac ante ipsum primis in faucibus.
Proin sodales neque dui, at sagittis magna fermentum vel. Cras id metus id sapien cursus rhoncus. In hendrerit augue dictum, gravida augue vel, consectetur lorem. Vivamus sollicitudin pellentesque pulvinar. Donec consectetur sem quis odio scelerisque elementum. Ut luctus enim nec nunc venenatis mattis vitae ac lorem. Nullam aliquam nulla et ornare interdum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam sollicitudin lacinia tellus et suscipit.
Ut eget orci non est luctus mattis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vel magna ligula. Donec eu sem ut odio ullamcorper ornare. Sed blandit, felis pellentesque laoreet cursus, diam sem viverra nunc, in auctor orci diam sit amet enim. Maecenas sit amet commodo turpis, nec tristique lectus. Maecenas dictum leo nec rhoncus faucibus. Vestibulum augue quam, varius ac facilisis vitae, commodo in quam. Aenean suscipit tellus non tincidunt viverra. Integer eu ipsum non nibh bibendum euismod id at erat.
Mauris non malesuada sapien. Pellentesque vitae mi nulla. Curabitur laoreet, sapien et facilisis varius, est est dapibus leo, dapibus auctor erat urna vel enim. In vehicula, nisl ac pharetra finibus, tellus ipsum vestibulum mi, venenatis pulvinar ante sem nec risus. Phasellus porta porttitor lectus, id consectetur justo commodo a. Donec in dui ut tellus ultricies aliquet. Praesent ac mi metus. Integer lobortis purus eu justo lobortis, vel imperdiet ex hendrerit. Aliquam erat volutpat. Proin ut ligula nisl. Sed pretium porttitor varius. Nam iaculis ac orci sed pulvinar. Donec mattis orci non dui vehicula, at lobortis nibh efficitur. Vestibulum varius erat ornare posuere convallis.
Vivamus gravida massa feugiat scelerisque maximus. Nam bibendum facilisis vehicula. Vivamus id lacinia nisl. Sed tempus, orci in tincidunt dignissim, nulla nibh fringilla magna, et rutrum erat sapien ac turpis. Curabitur laoreet id mi in luctus. Vestibulum nec erat et nunc bibendum feugiat vitae nec eros. Morbi vitae convallis neque, vitae faucibus leo. Suspendisse sem justo, vestibulum eget nulla varius, molestie vestibulum nibh. Nullam eleifend arcu enim, et porta felis pretium id. Cras eu sapien quis lacus feugiat venenatis.
Sed diam turpis, interdum vel felis imperdiet, posuere venenatis augue. Maecenas sapien nulla, consectetur vitae mattis in, finibus id lorem. Quisque consequat euismod vestibulum. Maecenas congue velit lorem, tincidunt tristique lorem consectetur quis. Proin vulputate porta convallis. Cras id tincidunt nulla. Proin sit amet turpis imperdiet turpis aliquet feugiat sit amet eu augue. Donec ut consequat neque. Morbi laoreet leo eu augue ullamcorper, ut porttitor lectus pulvinar.
Vivamus vitae nisi eu libero vestibulum sollicitudin vitae in metus. Ut nec massa justo. Phasellus euismod consequat massa id tempor. Vestibulum et imperdiet quam. In ipsum nibh, consectetur quis posuere vitae, laoreet et ante. Maecenas cursus eros vel ante tempor, vel tristique neque tincidunt. Ut eget erat vitae sapien posuere luctus. Donec a finibus erat.
Quisque at ligula sit amet arcu molestie feugiat commodo sit amet nisi. Aenean aliquet hendrerit metus vitae lacinia. Pellentesque pulvinar luctus ipsum non condimentum. In fringilla ac dui a fermentum. Nulla sollicitudin, nisl a fermentum rutrum, eros diam posuere nunc, eget luctus risus eros nec ligula. Suspendisse sit amet ante porta, semper est tempor, pulvinar odio. Cras dictum elit sed orci lacinia aliquet. Ut consectetur, nisl sit amet lacinia finibus, leo eros tempus risus, at lacinia nulla nisi vel tellus. Aliquam at nisl egestas, auctor est a, congue diam. Proin fringilla pellentesque arcu sit amet aliquet.
Morbi a lectus ultricies nibh efficitur scelerisque ac ac urna. Nunc molestie risus vitae ipsum ornare vestibulum. Vivamus molestie tincidunt tempus. Maecenas tristique luctus augue ut lobortis. In risus turpis, condimentum mattis posuere eget, sodales ut lorem. Sed vulputate tempor diam in ullamcorper. Aenean aliquet lectus vitae massa laoreet, nec vehicula odio porta.
Aliquam tristique ut nisi sit amet luctus. Quisque nulla mi, vulputate at lobortis vitae, fermentum at lacus. Curabitur non massa in nunc tempus dignissim. Suspendisse erat velit, molestie non vulputate in, lobortis quis purus. Pellentesque quis placerat nisl. In posuere vestibulum nisl eget egestas. Sed non dui posuere, pharetra est eu, ullamcorper mauris. Pellentesque dictum varius erat at condimentum. Sed nisi enim, pellentesque quis enim molestie, imperdiet volutpat arcu. Aenean commodo finibus vulputate. Fusce ornare scelerisque urna, vitae tempus neque vehicula eu.
Fusce lacinia augue id tristique rutrum. Aenean ut elementum augue. Nulla ut lectus tellus. Pellentesque et libero et mauris facilisis rutrum a pharetra dolor. Vivamus lobortis lacus eu ante suscipit, vel commodo nisi venenatis. Sed gravida gravida congue. Aliquam rutrum dictum orci ac condimentum. Aenean ac ex eu diam dapibus venenatis id ut lacus.
Maecenas non porttitor orci. Donec dapibus rhoncus consectetur. Cras porta sagittis magna, at convallis eros consequat non. Quisque consectetur sem in sagittis sollicitudin. Maecenas id eros porta, tristique sem mollis, sagittis enim. Praesent mollis dapibus commodo. Etiam bibendum lacus nec iaculis eleifend. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam vitae finibus erat. Fusce sollicitudin eleifend elit in hendrerit. Quisque fermentum rhoncus pulvinar. In lobortis libero ac nisi euismod venenatis sit amet sed ipsum. Nam id molestie quam, eu bibendum diam.
Etiam non augue volutpat, fermentum nunc non, sodales lectus. Curabitur elementum euismod ex, quis porttitor erat tempus accumsan. Morbi fringilla nisl nec hendrerit cursus. Suspendisse egestas massa in nisl gravida sollicitudin. Maecenas maximus, tortor sed lacinia consectetur, nisi magna tincidunt lorem, vel maximus dolor sem in eros. Sed a vulputate nunc. Integer egestas, tortor vitae imperdiet cursus, massa enim pellentesque felis, sit amet sollicitudin velit arcu id lorem.
Nullam nec diam convallis, fermentum quam id, pulvinar velit. Pellentesque ultricies semper metus, cursus pulvinar tortor consectetur vel. Fusce suscipit urna sem, vitae ultrices lacus aliquet vel. Pellentesque tempor tristique mi, quis rhoncus lacus fringilla a. Interdum et malesuada fames ac ante ipsum primis in faucibus. Morbi neque risus, malesuada at lacinia non, posuere elementum mauris. Pellentesque eget egestas est, nec congue leo. Nunc faucibus mi id vulputate sodales. Cras ornare eget justo eu blandit. Fusce id magna lorem. Nunc sit amet dolor placerat, ornare metus non, ultricies augue.
Ut sed auctor dui, ullamcorper pretium sapien. Sed ut felis id nunc mollis consectetur et in nunc. Nunc volutpat nec urna nec facilisis. Ut sagittis ipsum nec aliquam interdum. Donec rutrum dolor eget neque euismod vestibulum. Nulla condimentum neque neque, eget ullamcorper risus cursus scelerisque. Sed bibendum luctus dolor eget dignissim. Etiam non nulla enim. Vestibulum eget semper odio. Sed semper vulputate ipsum ac maximus. Nullam sed libero pellentesque quam rhoncus sagittis vitae sed ipsum.
Sed vitae ex vulputate, scelerisque sapien quis, mattis massa. Duis rutrum neque ante, a vestibulum massa congue at. Nam tincidunt ex luctus ultricies laoreet. Duis cursus magna eu diam malesuada ultricies. Cras porttitor sagittis tellus, eget mollis enim molestie eu. Nunc tristique semper massa. Nullam varius velit sit amet velit suscipit, a bibendum odio facilisis. Nunc et arcu bibendum, fermentum odio id, congue lectus. Phasellus malesuada volutpat justo ut sodales. Integer interdum et nibh non blandit. Nam a vulputate tellus.
Quisque auctor commodo nisl, ut semper lectus tincidunt sed. Integer cursus finibus est. Vivamus dui dui, feugiat nec leo eu, vestibulum interdum nunc. Nam massa dolor, tempor sit amet congue et, maximus at elit. In blandit at nibh et porta. Curabitur elementum efficitur elit, vel sagittis tellus eleifend lacinia. Sed tincidunt elit eu purus fermentum finibus. Aenean egestas dignissim tellus vel semper.
Nulla id condimentum lorem. Donec vitae dui quam. Maecenas sapien dui, facilisis sed tellus sit amet, pharetra iaculis ligula. Fusce sagittis, odio sed aliquam feugiat, nunc ipsum ultrices lorem, vel pellentesque nibh orci finibus leo. Proin a urna tincidunt, porttitor sapien ac, fringilla velit. Suspendisse in vehicula risus. Morbi mattis cursus cursus. Nam vel varius nisi, blandit malesuada lacus.
Nullam laoreet nibh quis erat dictum fringilla. Quisque a tortor dolor. Curabitur pulvinar molestie lectus, eget dapibus nisl tristique id. Nullam pulvinar accumsan arcu, euismod auctor nunc dignissim ac. Vivamus pulvinar massa at metus sollicitudin, dictum convallis arcu vestibulum. Suspendisse at leo nec sem sollicitudin luctus sit amet vitae nisi. Duis lobortis risus id odio luctus, sit amet feugiat mauris ullamcorper. Donec iaculis suscipit nunc eu dictum. Quisque ut lobortis elit. Cras eget auctor lacus. Donec mattis vitae nisi a porta. Morbi quis eros sed ante pharetra euismod. Nullam varius bibendum magna a cursus.
Aenean vestibulum leo magna, sit amet varius eros eleifend mollis. Aenean tempor ullamcorper velit vel sagittis. Aenean maximus enim nulla, nec pellentesque elit ullamcorper eget. Duis tincidunt, dolor id euismod rhoncus, orci dolor auctor augue, eu molestie odio tellus nec sem. Donec gravida arcu ac ex ultrices rhoncus. Nulla tincidunt gravida neque id dictum. Sed lectus lectus, rhoncus ac odio vitae, porttitor elementum nunc. Morbi gravida, leo id sollicitudin iaculis, mi elit volutpat eros, quis venenatis massa dui pharetra neque. Cras sit amet dignissim mi. Donec in lectus sed risus congue consequat. Duis ut malesuada metus. Praesent maximus ac tortor eget feugiat. Nulla in nunc eget quam sodales sagittis.
Nam eu porta enim. Fusce pretium elit sapien, a feugiat nibh tempor a. Etiam feugiat dui nec neque malesuada, quis tristique sapien vestibulum. Sed volutpat eget nulla id imperdiet. Morbi sodales tortor ac ligula vulputate tincidunt. Aliquam placerat orci sem, id fringilla orci facilisis eu. Nullam aliquet odio eget ante placerat blandit. Morbi ut justo cursus, ullamcorper purus id, scelerisque neque. Donec a nisi pellentesque, commodo magna efficitur, feugiat neque. Maecenas at quam eleifend, ornare sem non, pretium ante. Pellentesque eget fringilla ligula. Donec massa arcu, viverra auctor sem at, ultricies blandit odio. Proin sed leo quam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce elementum efficitur blandit. Morbi tincidunt porttitor odio nec placerat.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec vel libero pharetra, euismod nulla sit amet, volutpat lorem. Maecenas blandit magna ornare mi imperdiet luctus. Fusce congue risus et enim placerat ornare. Aenean ac magna eget risus rhoncus molestie at et leo. Cras mattis erat lectus, sed dignissim enim pulvinar vel. Donec turpis libero, condimentum sit amet rutrum id, blandit in diam. Praesent tincidunt malesuada lorem, at posuere nisi. Ut rutrum turpis vel mi blandit congue. Aenean viverra metus quis erat hendrerit, nec egestas diam placerat. Praesent vel ipsum enim. Praesent eget sollicitudin dui. Donec semper turpis id magna molestie, sit amet interdum odio lacinia. Curabitur ut mollis metus. Duis luctus leo velit, id accumsan risus sodales non.
Nullam ut arcu sed justo tempus consequat. Donec nisl ante, lacinia ac convallis ac, bibendum sed diam. Duis viverra dolor sed ex convallis, vel facilisis ligula maximus. Pellentesque eu pulvinar nulla. In ante risus, viverra a euismod et, laoreet a dui. In hac habitasse platea dictumst. Nunc ullamcorper tellus non viverra pharetra. Aenean dapibus dolor sit amet dui facilisis placerat. In hac habitasse platea dictumst. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec ac efficitur enim, ac placerat dui. Donec vitae vestibulum leo.
Aliquam vestibulum dictum metus, eget commodo ipsum sollicitudin et. Nam volutpat efficitur magna eu vestibulum. Donec dolor purus, aliquet quis orci ut, finibus molestie sapien. Mauris in libero in lorem pretium commodo eu sit amet justo. Integer eu elit sit amet orci cursus sagittis ac a ligula. Curabitur ac eleifend ante. Nulla placerat lacus eu molestie hendrerit.
Proin eu dignissim ante. Fusce lobortis eu ante sed finibus. Vivamus sed dictum turpis. Ut tristique vitae nibh at laoreet. Nullam eget interdum metus, sit amet porttitor nibh. Maecenas dignissim, lacus ac facilisis volutpat, ante nibh vehicula dui, nec facilisis enim turpis vel turpis. Proin risus tortor, vehicula sit amet congue eget, accumsan a magna. Suspendisse potenti. Praesent lacinia mollis feugiat. Donec a nunc ac nibh tincidunt volutpat. Proin nec urna eros. Sed vitae elit fringilla, congue sem non, mattis arcu. Maecenas euismod neque metus, consectetur vestibulum neque rutrum non.
Morbi magna metus, congue nec lacus id, semper mattis augue. Pellentesque vel dolor eu turpis luctus volutpat. Donec consectetur maximus commodo. Quisque erat elit, iaculis vel leo quis, volutpat mollis quam. Sed dui lectus, pretiu

1
sh/tests/custom-ls/folder1/ls-test

@ -0,0 +1 @@
hello

42
sh/tests/custom-ls_test.sh

@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
shopt -s expand_aliases
FILENAME="student/custom-ls.sh"
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
challenge() {
source "$script_dirS"/$FILENAME
submitted=$(cd "$1" && custom-ls)
unalias custom-ls
source "$script_dirS"/solutions/custom-ls.sh
expected=$(cd "$1" && custom-ls)
unalias custom-ls
diff <(echo "$submitted") <(echo "$expected")
}
# True if FILE exists and is a regular file
if [ -f ${FILENAME} ]; then
# FILE exists and it's not empty
if [ -s ${FILENAME} ]; then
if [[ $(cat $FILENAME | grep echo | wc -l) -ne 0 ]]; then
echo "echo is not allowed in this exercise!"
exit 1
fi
challenge custom-ls/folder1
else
echo "The file exist but is empty"
exit 1
fi
else
echo "File does not exist"
exit 1
fi

18
sh/tests/details_test.sh

@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
challenge() {
touch file1.txt
submitted=$(bash "$script_dirS"/student/details.sh && ls -l file1.txt | awk '{print $1, $2, $5, $6, $7, $8, $9}')
expected=$(bash "$script_dirS"/solutions/details.sh && ls -l file1.txt | awk '{print $1, $2, $5, $6, $7, $8, $9}')
diff <(echo "$submitted") <(echo "$expected")
stat file1.txt
}
challenge
rm file1.txt

44
sh/tests/dir-info_test.sh

@ -0,0 +1,44 @@
#!/usr/bin/env bash
set -euo pipefail
IFS='
'
FILENAME="student/dir-info.sh"
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
rm -rf student/dir-info-files
mkdir student/dir-info-files
cd student/dir-info-files
directories=(folder1 folder2/aa folder2/ba/aa folder2/aa/ba)
for dir in "${directories[@]}"; do
mkdir -p "$dir"
done
files=(.abc 34 folder1/ab 4 folder1/ac 2 folder1/az 3 folder1/bz 3 \
folder1/cz 9 folder1/.hello 21 folder1/za! 3 folder2/ab 7 folder2/ac 0 \
folder2/alphabet 0 folder2/az 0 folder2/bz 4 folder2/cz 0 folder2/za! 28 \
folder2/aa/aa 3 folder2/aa/az 4 folder2/aa/.salut 7 folder2/aa/ba/ab 0 \
folder2/aa/ba/bz 0 folder2/ba/ac 0 folder2/ba/alphabetz 0 folder2/ba/.ola 17 \
folder2/ba/aa/alphabetz! 0 folder2/ba/aa/.ciao 7 folder2/ba/aa/cz 0 \
folder2/ba/aa/za! 0)
for ((i=0; i<${#files[@]}; i+=2)) do
dd if=/dev/zero of="${files[i]}" bs=1 count="${files[i + 1]}" 2> /dev/null
done
cd ../
challenge () {
submitted=$(bash "$script_dirS"/"$FILENAME" < <(echo "$1"))
expected=$(bash "$script_dirS"/solutions/dir-info.sh < <(echo "$1"))
diff <(echo "$submitted") <(echo "$expected")
}
challenge "dir-info-files/folder1"
challenge "dir-info-files/folder2"
challenge "dir-info-files"
rm -rf dir-info-files

37
sh/tests/division_test.sh

@ -0,0 +1,37 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
challenge() {
# Test if test command was used
if grep -q "test" "$script_dirS"/student/division.sh
then
echo "Error: the test command cannot be used in the student script"
return
fi
# Test with one or two arguments
if [ $# -eq 1 ]
then
submitted=$(bash "$script_dirS"/student/division.sh $1)
expected=$(bash "$script_dirS"/solutions/division.sh $1)
else
submitted=$(bash "$script_dirS"/student/division.sh $1 $2)
expected=$(bash "$script_dirS"/solutions/division.sh $1 $2)
fi
diff <(echo "$submitted") <(echo "$expected")
}
challenge "10" "2"
challenge "4" "2"
challenge "0.5" "0.5"
challenge "5" "2"
challenge "0.5"
challenge "foo" "bar"
challenge "1" "0"
challenge "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "2"

15
sh/tests/easy-conditions_test.sh

@ -0,0 +1,15 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
for i in $(seq 1 5); do
export X=$(shuf -i 1-20 -n 1)
export Y=$(shuf -i 1-30 -n 1)
submitted=$(bash "$script_dirS"/student/easy-conditions.sh)
expected=$(bash "$script_dirS"/solutions/easy-conditions.sh)
diff <(echo "$submitted") <(echo "$expected")
done

12
sh/tests/easy-perm/example.txt

@ -0,0 +1,12 @@
Q. How did the programmer die in the shower?
A. He read the shampoo bottle instructions: Lather. Rinse. Repeat.
~~~~~~~~~~~~~~~~~~~~~~~~~
How many programmers does it take to change a light bulb?
None – It’s a hardware problem
~~~~~~~~~~~~~~~~~~~~~~~~~
Why do programmers always mix up Halloween and Christmas?
Because Oct 31 equals Dec 25.

16
sh/tests/easy-perm/example2.txt

@ -0,0 +1,16 @@
“The best TDD can do, is assure that code does what the programmer thinks it should do. That is pretty good BTW.”
“Simply put, things always had to be in a production-ready state: if you wrote it, you darn well had to be there to get it running!”
“If you think it’s expensive to hire a professional, wait until you hire an amateur.”
“Programming is not a zero-sum game. Teaching something to a fellow programmer doesn’t take it away from you.”
“A phased approach to continuous delivery is not only preferable, it’s infinitely more manageable.”
“So, what do you do?”
“I’m lean”
“What?”
“I’m agile”
“What?”
“Fine. I make websites.”

17
sh/tests/easy-perm_test.sh

@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
chmod 303 easy-perm/*
challenge() {
submitted=$(bash "$script_dirS"/student/easy-perm.sh && ls -l "$1" | awk '{print $1}')
expected=$(bash "$script_dirS"/solutions/easy-perm.sh && ls -l "$1" | awk '{print $1}')
diff <(echo "$submitted") <(echo "$expected")
}
challenge easy-perm/

28
sh/tests/env-format_test.sh

@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
FILENAME="student/env-format.sh"
# True if FILE exists and is a regular file
if [ -f ${FILENAME} ]; then
# FILE exists and it's not empty
if [ -s ${FILENAME} ]; then
if [[ $(cat $FILENAME | grep echo | wc -l) -ne 0 ]]; then
echo "echo is not allowed in this exercise!"
exit 1
fi
submitted=$(bash $FILENAME)
expected=$(bash solutions/env-format.sh)
diff <(echo "$submitted") <(echo "$expected")
else
echo "The file exist but is empty"
exit 1
fi
else
echo "File does not exist"
exit 1
fi

38
sh/tests/file-checker_test.sh

@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -euo pipefail
IFS='
'
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
# check that test command was not used
if grep -q "test" "$script_dirS"/student/file-checker.sh
then
echo "The 'test' command is not allowed in this exercise"
exit 1
fi
if test ! -e file-checker; then
mkdir file-checker
cd file-checker
touch readable-and-writable readable-only readable-and-executable readable-writable-executable
chmod -x "$script_dirS/file-checker/readable-and-writable"
chmod -xw "$script_dirS/file-checker/readable-only"
chmod -w "$script_dirS/file-checker/readable-and-executable"
chmod +x "$script_dirS/file-checker/readable-and-executable"
chmod +x "$script_dirS/file-checker/readable-writable-executable"
cd ..
fi
challenge() {
submitted=$(bash "$script_dirS"/student/file-checker.sh "$1")
expected=$(bash "$script_dirS"/solutions/file-checker.sh "$1")
diff <(echo "$submitted") <(echo "$expected")
}
challenge "$script_dirS/file-checker/readable-only"
challenge "$script_dirS/file-checker/readable-and-writable"
challenge "$script_dirS/file-checker/readable-and-executable"
challenge "$script_dirS/file-checker/readable-writable-executable"
rm -rf file-checker

17
sh/tests/file-details_test.sh

@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
challenge() {
submitted=$(cd "$1" && bash "$script_dirS"/student/file-details.sh)
expected=$(cd "$1" && bash "$script_dirS"/solutions/file-details.sh)
diff <(echo "$submitted") <(echo "$expected")
}
challenge hard-perm

127
sh/tests/file-researcher/facts.txt

@ -0,0 +1,127 @@
Indonesia consists only of islands - 13,667 total
During World War II, the very first bomb dropped on Berlin by the Allies killed the only elephant in the Berlin Zoo
People who ride on roller coasters have a higher chance of having a blood clot in the brain
The tallest freestanding sculpture in the world is Chief Crazy Horse in South Dakota, USA
Marie Curie, the Nobel prize winning scientist who discovered radium, died of radiation poisoning
898 tornadoes were recorded to have occurred in the United States in the year 2000.
The word Popcorn is derived from the middle English word "poppe," which means "explosive sound"
The food that is digested in your stomach is called "chyme."
Alcohol beverages have all 13 minerals necessary for human life
The sentence "The quick brown fox jumps over the lazy dog." uses every letter in the alphabet. (Developed by Western Union to Test telex/twxcommunications)
The word housekeeping was invented by Shakespeare
The only two days of the year in which there are no professional sports games (MLB, NBA, NHL, or NFL) are the day before and the day after theMajorLeague All-Star Game.
In the great fire of London in 1666 half of London was burnt down but only 6 people were injured
Lack of sleep can affect your immune system and reduce your ability to fight infections
All dogs are the descendant of the wolf. These wolves lived in eastern Asia about 15,000 years ago
It is not possible to tickle yourself. The cerebellum, a part of the brain, warns the rest of the brain that you are about to tickle yourself. Since your brain knows this, it ignores the resulting sensation
Parma ham is only Parma ham if it is made in the Parma region of Italy. The British chain supermarket Asda, made and packaged its own "Parma ham" and was successfully sued by the real Parma ham people (Parma Ham Trade Association)
With winds of 50 miles per hour, The Statue of Liberty sways three inches and the torch sways five inches
A famous bullfighter, Lagarijo, killed 4,867 bulls in the 19th century.
Police detectives have used snapping turtles to help them locate dead bodies
In most advertisements, including newspapers, the time displayed on a watch is 10:10
The national sport of Japan is sumo wrestling
The early occurrence of a fetus yawning is at eleven weeks after conception
In a month, a fingernail grows an eighth of an inch
Edward VIII did not officially become the King of England as he abdicated the throne to marry an American divorcee
The book "Little Red Riding Hood" was banned in 1990 by two school districts in California. They did this because in the book there was a picture of a basket that had a bottle of wine in it
The reason why golf balls have dimples on them is because it helps in the ball to move a farther distance by reducing drag
Americans consume the most peanut butter in the world
Celtic warriors sometimes fought their battles naked, their bodies dyed blue from head to toe
To make butter more attractive in color, carrot juice was used by people in the Middle Ages
Early hockey games allowed as many as 30 players a side on the ice
Most fleas do not live past a year old
It takes seven to ten days to make a jelly belly jellybean
Some asteroids have other asteroids orbiting them
Maine is the only state whose name is just one syllable
The male praying mantis cannot copulate while its head is attached to its body. The female initiates sex by ripping the males head off
There is enough concrete in the Hoover Dam to pave a two lane highway from San Francisco to New York
Americans on the average eat 18 acres of pizza every day
Every 238 years, the orbits of Neptune and Pluto change making Neptune at times the farthest planet from the sun
There is a certain species of kangaroo that is only 2.5 centimeters long when it is born
In a lifetime, the average house cat spends approximately 10,950 hours purring
The real name of Toto the dog in "The Wizard Of Oz" was Terry
Stannous fluoride, which is the cavity fighter found in toothpaste is made from recycled tin
It takes 12 honeybees to make one teaspoon of honey
Thomas Watson, who was the chairman of IBM in 1943 predicted that their would probably only be a world market for five computers.
The largest hamburger cooked in the world weighed in at 6,040 pounds
The first lighthouse was in Alexandria in 290 B.C
Heinz first started making ketchup in 1876 and the recipe has remained the same ever since
The largest wedding chapel in Las Vegas is the Viva Las Vegas Chapel, which can seat 100 people
The most popular name for a pet in the United States is Max
Spiral staircases in medieval castles are running clockwise. This is because all knights used to be right-handed. When the intruding army would climb the stairs they would not be able to use their right hand which was holding the sword because of the difficulties of climbing the stairs. Left-handed knights would have had no troubles, except left-handed people could never become knights because it was assumed that they were descendants of the devil
The largest shopping mall in the world is the West Edmonton Mall located in Edmonton, Alberta, Canada
The CN Tower located in Toronto, Ontario Canada took a total construction time of 40 months to complete at an original cost of $63 million
The 20th president of the United States, James Garfield, was able to write Greek with one hand and Latin with the other at the same time
The country of Andorra has a zero percent unemployment rate
In Los Angeles, there are fewer people than there are automobiles
A woman has approximately 4.5 litres of blood in her body, while men have 5.6 litres
In India, pickled ginger, minced mutton and a cottage cheese like substance are popular pizza toppings
Oral-B were the first toothbrushes to go to the moon when they were aboard the Apollo 11 mission
A maple tree is usually tapped when the tree is at least 45 years old and has a diameter of 12 inches
In 1998, a law passed in the U.S. state of Virginia allows drivers to keep their road kill, as long as they report it within 12 hours. updated
A language becomes extinct in this world every two weeks
An acre of trees can remove about 13 tons of dust and gases every year from the surrounding environment
The decomposition point of Olive Oil is 220 degrees Celsius
Ten radishes only contain eight calories
Annually a thousand people are killed by scorpions in Mexico
Every year, 100 million sharks are killed by people
Tug of war was an Olympic event from 1900-1920
Of all the countries, Brazil has the most plant species, with over 56,000
One female mouse can produce up to 100 babies a year
Impotence is grounds for divorce in 26 U.S. states
Women who are romance novel readers are reported to make love 74% more often with their partners than women who do not read romance novels.
The average lifespan of a human taste bud is ten days
The monogram "RR" for Rolls-Royce has never been altered, except for when Sir Henry Royce passed away in 1933. Then it was changed from red to black.
People with darker skin will not wrinkle as fast as people with lighter skin
Fido means faithful in Latin
Pebbles cereal was actually named after the shape of the cereal and not the Pebbles Flintstone character
A group of kangaroos is called a mob
Cat's urine glows under a blacklight.
Every three seconds, a new baby is born
More than 260,000 people have been killed by volcanic activity since 1700 AD.
The only predator that polar bears have are humans
Many insects can carry 50 times their own body weight
The last land battle of the U.S. Civil War was fought in Texas
Annually 7 million tons of textiles and clothing is thrown out. Out of this, only 12% is used again or recycled
A scorpion can have up to 12 eyes
A snake charmer in Bangladesh once found 3,500 poisonous cobras and their eggs hidden underneath the floors of two suburban homes
The IRS employees tax manual has instructions for collecting taxes after a nuclear war
There are approximately fifty Bibles sold each minute across the world
The pectin that is found in apples aids in lowering cholesterol levels
Post-It Notes, which are adhesive notes, were invented while looking for a way to improve the acrylate adhesive found in tapes
Crayola Crayons currently has over 120 different crayon colors
Odontophobia is the fear of teeth
The width of a tornado can range from less than ten yards to more than a mile.
In Johannesburg, the average car will be involved in an accident once every four years.
The youngest actress to be nominated as best actress is Keisha Castle-Hughes who was nominated at just 13 years old
The Taj Mahal was actually built for use as a tomb
According to studies, an average roll of toilet paper lasts about five days in the bathroom
Almonds are members of the peach family
The oldest known disease in the world is leprosy
A fall of 30 feet can be survived my most cats
The largest member of the dolphin family are orcas
In 1477, the first diamond engagement ring was given to Mary of Burgundy by Archduke Maximillian of Austria
The hormone replacement drug "Premarin" is made from the urine of pregnant horses
TWIX Caramel Cookie Bars were first introduced in 1979
Nintendo was first establish in 1889 and they started out making special playing cards
People over the age of fifty will start to lose their dislike for foods that taste bitter
In Kentucky, 50 percent of the people who get married for the first time are teenagers
Elephants have been known to learn up to 60 commands
On average 1,668 gallons of water are used by each person in the United States daily
Copper is the second most used metal in the world.
Milton Bradley originally wanted to name the game Twister, Pretzel; but he could not since the name was copyrighted
According to studies, men prefer to have white bedrooms and women prefer to have blue bedrooms
If someone was to fly once around the surface of the moon, it would be equal to a round trip from New York to London
St. Patrick never really drove out any snakes from Ireland. This story was an analogy of how he drove paganism out of Ireland
Fat is important for the development of children and normal growth
The most common seasonings found in American homes are chili powder, cinnamon, and seasoned salts
People who have eaten beetles say that it tastes like apples
Montreal was named after a local mountain "Mont Royal."
Millie the White House dog earned more than 4 times as much as President Bush in 1991. And, rightfully so
In an average lifetime, a person will spend 4 years traveling in an automobile and six months waiting at a red light.
A small drip from a faucet can waste up to 50 gallons of water daily, which is enough water to run a dishwasher twice on a full cycle
Kotex was first manufactured as bandages, during W.W.I
The longest Monopoly game ever played was 1,680 hours long, which is seventy straight days
The first known contraceptive was crocodile dung, used by Egyptians in 2000 B.C
Over 1,600 people in North America have been victims of trunk entrapment (being locked inside of a car trunk)
A rhinoceros horn is made of compacted hair

28
sh/tests/file-researcher_test.sh

@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
FILENAME="student/file-researcher.sh"
# True if FILE exists and is a regular file
if [ -f ${FILENAME} ]; then
# FILE exists and it's not empty
if [ -s ${FILENAME} ]; then
if [[ $(cat $FILENAME | grep echo | wc -l) -ne 0 ]]; then
echo "echo is not allowed in this exercise!"
exit 1
fi
submitted=$(bash $FILENAME)
expected=$(bash solutions/file-researcher.sh)
diff <(echo "$submitted") <(echo "$expected")
else
echo "The file exist but is empty"
exit 1
fi
else
echo "File does not exist"
exit 1
fi

16
sh/tests/file-struct_test.sh

@ -0,0 +1,16 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
print_content() {
mkdir -p uncompressed
tar -xpf file-struct.tar -C uncompressed
tree uncompressed
}
submitted=$(cd student && print_content)
expected=$(cd solutions && print_content)
diff <(echo "$submitted") <(echo "$expected")

0
sh/tests/find-files-extension/folder1/file1.txt

0
sh/tests/find-files-extension/folder1/file2.txt

0
sh/tests/find-files-extension/folder1/file3.txt

0
sh/tests/find-files-extension/folder1/test4.sh

0
sh/tests/find-files-extension/folder2/fileInsideAfolder4.txt

0
sh/tests/find-files-extension/folder2/test.sh

0
sh/tests/find-files-extension/folder2/testtxt/fileInsideAfolder5.txt

0
sh/tests/find-files-extension/folder2/testtxt/test/fileInsideAfolder6.txt

0
sh/tests/find-files-extension/folder2/testtxt/test/lol.sh

35
sh/tests/find-files-extension_test.sh

@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
FILENAME="student/find-files-extension.sh"
script_dirS=$(cd -P "$(dirname "$BASH_SOURCE")" &>/dev/null && pwd)
challenge() {
submitted=$(cd "$1" && bash "$script_dirS"/$FILENAME)
expected=$(cd "$1" && bash "$script_dirS"/solutions/find-files-extension.sh)
diff <(echo "$submitted") <(echo "$expected")
}
# True if FILE exists and is a regular file
if [ -f ${FILENAME} ]; then
# FILE exists and it's not empty
if [ -s ${FILENAME} ]; then
if [[ $(cat $FILENAME | grep echo | wc -l) -ne 0 ]]; then
echo "echo is not allowed in this exercise!";
exit 1
fi
challenge find-files-extension/folder1
challenge find-files-extension/folder2
else
echo "The file exist but is empty"
exit 1
fi
else
echo "File does not exist"
exit 1
fi

Some files were not shown because too many files changed in this diff diff.show_more

Loading…
Cancel
Save