Chap 1 - Introduction: State of mind and Ressources

1 Goal

    1. Develop a mental model : how to think about programming, data analysis and data management so you can become independent learners
    1. Learn and understand the basics of data wrangling, exploration and visualization and analysis using R.
    1. Learn good practices of data analyses, including how to use R for version control with git and github.
    1. You should have learned enough to be able to use the additional resources and pointers provided in those documents to gain more knowledge about reproducible research and data analysis. You should now be able to work independently.
    1. You should have learn that coding is a TRIAL and ERROR process!. Don’t be afraid of doing anything wrong when coding! The rawdata will not be messed up! THIS IS THE NICE THING ABOUT PROGRAMMING! YOU WILL ALWAYS BE ABLE TO GO BACK TO YOU ORIGINAL DATA!

2 What to expect and the learning process

In programming for data analysis, there are some basic concepts to learn but afterwards we usually manage by finding the information we need when we need it. We never know it all, but we get better and better at finding information.

Humor and markdown way to insert images in markdown!
Humor and markdown way to insert images in markdown!

When you have a problem to solve, the solution is most certainly (99.999% of the cases) already available on internet. You will need to search for the answer. The resources for learning are not lacking. It might seem overwhelming.

What is lacking, is the time to explore it all, and know what to search for. How how can you search for something you do not know exists yet ? This is a continuous learning process and you will improve your skills a long the way.

2.1 What to expect about the code you produce

Learning to write code, is learning how to get up after stumbling… and there is a lot of stumbling. It is totally normal. No code is ever perfect, writing good code takes practice, experience, and a lot of trials and errors. Coding is a creative process to solve problems. Code does not need to be nice, nor perfect. It needs to do what you want it to do! However, documenting your intent is a very good practice so you in 3 months or any other person can understand what you were trying to do.

What to expect in code?
What to expect in code?

What should you aim for? (discussion)

2.2 What about using AI to help you code ?

AI, for sure can help you find resources and even to help you do some coding for you (eg. ChatGTP, GitHub Copilot, etc.). It can also to a certain extend help understand code.

BUT! Should you use it - I would not advise you to trust AI blindly; and I would not advise you to use it to write code for you, as the code it delivers could be wrong and it might be difficult to detect that it is wrong. Should you use AI, you still need to be certain you understand what the code does, this is your responsibility. Consequently, you need to have learned enough to be able to do so!

3 Some major ressources to further learn R and data analysis

Here I link several external resources. Some contain material that we have seen here but are presented differently. They will help you go further. This is far from being an exhaustive list.

Resources are available in different forms :

You will find also some additional resources through the course.

Note that this course will be greatly inspired from two core software carpentry lessons: - Programming with R - R for Reproducible Scientific Analysis

Back to Index

LS0tDQp0aXRsZTogImByIHBhcmFtcyR0aXRsZWAiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiDQphdXRob3I6IEV2ZSBaZXlsIEZpc2tlYmVjayBhbmQgTWFkZWxhaW5lIE5vcnN0csO2bQ0KcGFyYW1zOg0KICB0aXRsZTogIkNoYXAgMSAtIEludHJvZHVjdGlvbjogU3RhdGUgb2YgbWluZCBhbmQgUmVzc291cmNlcyIgDQogIHNjcmlwdF9uYW1lOiAiMDEgLSBJbnRyb2R1Y3Rpb24gYW5kIEJhc2ljIFIgU2V0dXAiICANCiAgcHJvamVjdF9wYXRoOiAiYHIgaGVyZTo6aGVyZSgpYCINCiAgDQogIA0Ka25pdDogKGZ1bmN0aW9uKGlucHV0RmlsZSwgZW5jb2RpbmcpIHsNCiAgcm1hcmtkb3duOjpyZW5kZXIoaW5wdXRGaWxlLCBlbmNvZGluZyA9IGVuY29kaW5nLCBvdXRwdXRfZGlyID0gIi4uLy4uL2RvY3MiKSB9KQ0KICAgIA0Kb3V0cHV0OiANCiAgDQogIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOg0KICAgICAgY3NzOiAuLi9zdHlsZXMvc3R5bGUuY3NzDQogICAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQ0KICAgICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgICAgdG9jX2RlcHRoOiA0DQogICAgICBkZl9wcmludDogcGFnZWQNCiAgICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgICAgYXV0aG9yOiBwYXJhbXMkYXV0aG9yDQogICAgICBoaWdobGlnaHQ6IGVzcHJlc3NvDQogICAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICAgIA0KDQogIA0KZWRpdG9yX29wdGlvbnM6IA0KICBtYXJrZG93bjogDQogICAgd3JhcDogNzINCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQoNCiMgR29hbCANCg0KLSAxLiAqKkRldmVsb3AgYSBtZW50YWwgbW9kZWwgOiAgaG93IHRvIHRoaW5rIGFib3V0IHByb2dyYW1taW5nLCBkYXRhIGFuYWx5c2lzIGFuZCBkYXRhIG1hbmFnZW1lbnQqKg0Kc28geW91IGNhbiBiZWNvbWUgaW5kZXBlbmRlbnQgbGVhcm5lcnMgDQotIDIuIExlYXJuIGFuZCB1bmRlcnN0YW5kIHRoZSBiYXNpY3Mgb2YgZGF0YSB3cmFuZ2xpbmcsIGV4cGxvcmF0aW9uIGFuZCB2aXN1YWxpemF0aW9uIGFuZCBhbmFseXNpcyB1c2luZyBSLg0KLSAzLiBMZWFybiBnb29kIHByYWN0aWNlcyBvZiBkYXRhIGFuYWx5c2VzLCBpbmNsdWRpbmcgaG93IHRvIHVzZSBSIGZvciB2ZXJzaW9uIGNvbnRyb2wgd2l0aCBnaXQgYW5kIGdpdGh1Yi4NCi0gNC4gWW91IHNob3VsZCBoYXZlIGxlYXJuZWQgZW5vdWdoIHRvIGJlIGFibGUgdG8gdXNlIHRoZSBhZGRpdGlvbmFsIHJlc291cmNlcyBhbmQgcG9pbnRlcnMgcHJvdmlkZWQgaW4gdGhvc2UgZG9jdW1lbnRzIHRvIGdhaW4gbW9yZSBrbm93bGVkZ2UgYWJvdXQgcmVwcm9kdWNpYmxlIHJlc2VhcmNoIGFuZCBkYXRhIGFuYWx5c2lzLiBZb3Ugc2hvdWxkIG5vdyBiZSBhYmxlIHRvIHdvcmsgaW5kZXBlbmRlbnRseS4gDQotIDUuIFlvdSBzaG91bGQgaGF2ZSBsZWFybiB0aGF0ICoqY29kaW5nIGlzIGEgVFJJQUwgYW5kIEVSUk9SIHByb2Nlc3MhKiouIERvbid0IGJlIGFmcmFpZCBvZiBkb2luZyBhbnl0aGluZyB3cm9uZyB3aGVuIGNvZGluZyEgVGhlIHJhd2RhdGEgd2lsbCBub3QgYmUgbWVzc2VkIHVwISBUSElTIElTIFRIRSBOSUNFIFRISU5HIEFCT1VUIFBST0dSQU1NSU5HISBZT1UgV0lMTCBBTFdBWVMgQkUgQUJMRSBUTyBHTyBCQUNLIFRPIFlPVSBPUklHSU5BTCBEQVRBIQ0KDQoNCiMgV2hhdCB0byBleHBlY3QgYW5kIHRoZSBsZWFybmluZyBwcm9jZXNzICANCg0KSW4gcHJvZ3JhbW1pbmcgZm9yIGRhdGEgYW5hbHlzaXMsIHRoZXJlIGFyZSBzb21lIGJhc2ljIGNvbmNlcHRzIHRvIGxlYXJuIGJ1dCANCmFmdGVyd2FyZHMgd2UgdXN1YWxseSBtYW5hZ2UgYnkgZmluZGluZyB0aGUgaW5mb3JtYXRpb24gd2UgbmVlZCB3aGVuIHdlIG5lZWQgaXQuDQpXZSBuZXZlciBrbm93IGl0IGFsbCwgYnV0IHdlIGdldCBiZXR0ZXIgYW5kIGJldHRlciBhdCBmaW5kaW5nIGluZm9ybWF0aW9uLiANCg0KIVtIdW1vciBhbmQgbWFya2Rvd24gd2F5IHRvIGluc2VydCBpbWFnZXMgaW4gbWFya2Rvd24hXShodHRwczovL2kucmVkZC5pdC9tczh1M2JsMmt3MzUxLmpwZyl7d2lkdGg9NTAlIGhlaWdodD01MCV9DQoNCg0KV2hlbiB5b3UgaGF2ZSBhIHByb2JsZW0gdG8gc29sdmUsIHRoZSBzb2x1dGlvbiBpcyBtb3N0IGNlcnRhaW5seSAoOTkuOTk5JSBvZiB0aGUgDQpjYXNlcykgYWxyZWFkeSBhdmFpbGFibGUgb24gaW50ZXJuZXQuIFlvdSB3aWxsIG5lZWQgdG8gc2VhcmNoIGZvciB0aGUgYW5zd2VyLg0KVGhlIHJlc291cmNlcyBmb3IgbGVhcm5pbmcgYXJlIG5vdCBsYWNraW5nLiBJdCBtaWdodCBzZWVtIG92ZXJ3aGVsbWluZy4NCg0KV2hhdCBpcyBsYWNraW5nLCBpcyB0aGUgdGltZSB0byBleHBsb3JlIGl0IGFsbCwgYW5kIGtub3cgd2hhdCB0byBzZWFyY2ggZm9yLiBIb3cgaG93IGNhbiB5b3Ugc2VhcmNoIGZvciANCnNvbWV0aGluZyB5b3UgZG8gbm90IGtub3cgZXhpc3RzIHlldCA/IFRoaXMgaXMgYSBjb250aW51b3VzIGxlYXJuaW5nIHByb2Nlc3MgYW5kIHlvdSB3aWxsIGltcHJvdmUgeW91ciBza2lsbHMgYSBsb25nIHRoZSB3YXkuDQoNCiMjIFdoYXQgdG8gZXhwZWN0IGFib3V0IHRoZSBjb2RlIHlvdSBwcm9kdWNlDQoNCkxlYXJuaW5nIHRvIHdyaXRlIGNvZGUsIGlzIGxlYXJuaW5nIGhvdyB0byBnZXQgdXAgYWZ0ZXIgc3R1bWJsaW5nLi4uIGFuZCB0aGVyZSBpcw0KYSBsb3Qgb2Ygc3R1bWJsaW5nLiBJdCBpcyB0b3RhbGx5IG5vcm1hbC4gDQpObyBjb2RlIGlzIGV2ZXIgcGVyZmVjdCwgd3JpdGluZyBnb29kIGNvZGUgdGFrZXMgcHJhY3RpY2UsIGV4cGVyaWVuY2UsIGFuZCBhIGxvdA0Kb2YgdHJpYWxzIGFuZCBlcnJvcnMuIENvZGluZyBpcyBhIGNyZWF0aXZlIHByb2Nlc3MgdG8gc29sdmUgcHJvYmxlbXMuIA0KQ29kZSBkb2VzIG5vdCBuZWVkIHRvIGJlIG5pY2UsIG5vciBwZXJmZWN0LiBJdCBuZWVkcyB0byANCmRvIHdoYXQgeW91IHdhbnQgaXQgdG8gZG8hIEhvd2V2ZXIsIGRvY3VtZW50aW5nIHlvdXIgaW50ZW50IGlzIGEgdmVyeSBnb29kIHByYWN0aWNlDQpzbyB5b3UgaW4gMyBtb250aHMgb3IgYW55IG90aGVyIHBlcnNvbiBjYW4gdW5kZXJzdGFuZCB3aGF0IHlvdSB3ZXJlIHRyeWluZyB0byBkby4gDQo8IS0tIEkgYW0gbm90IHdyaXRpbmcgZ29vZCBjb2RlLCBidXQgaXQgdXN1YWxseSB3b3JrIGZvciB0aGUNCnNjaWVudGlmaWMgYW5hbHlzaXMgSSBkby4gLS0+IA0KDQohW1doYXQgdG8gZXhwZWN0IGluIGNvZGU/XShodHRwczovL21pcm8ubWVkaXVtLmNvbS92Mi9yZXNpemU6Zml0OjE0MDAvMCpfbGJma0gyUmRXdlF5TFNRLnBuZyl7d2lkdGg9ODAlIGhlaWdodD04MCV9DQoNCjx1PldoYXQgc2hvdWxkIHlvdSBhaW0gZm9yPyAgKGRpc2N1c3Npb24pIDwvdT4NCg0KDQojIyBXaGF0IGFib3V0IHVzaW5nIEFJIHRvIGhlbHAgeW91IGNvZGUgPw0KDQoNCkFJLCBmb3Igc3VyZSBjYW4gaGVscCB5b3UgZmluZCByZXNvdXJjZXMgYW5kIGV2ZW4gdG8gaGVscCB5b3UgZG8gc29tZSBjb2RpbmcgZm9yIA0KeW91IChlZy4gQ2hhdEdUUCwgR2l0SHViIENvcGlsb3QsIGV0Yy4pLiBJdCBjYW4gYWxzbyB0byBhIGNlcnRhaW4gZXh0ZW5kIGhlbHAgDQp1bmRlcnN0YW5kIGNvZGUuIA0KDQoqKkJVVCEqKiBTaG91bGQgeW91IHVzZSBpdCAtIEkgd291bGQgbm90IGFkdmlzZSB5b3UgdG8gdHJ1c3QgQUkgYmxpbmRseTsgDQphbmQgSSB3b3VsZCBub3QgYWR2aXNlIHlvdSB0byB1c2UgaXQgdG8gd3JpdGUgY29kZSBmb3IgeW91LCBhcyB0aGUgY29kZSBpdCANCmRlbGl2ZXJzIGNvdWxkIGJlIHdyb25nIGFuZCBpdCBtaWdodCBiZSBkaWZmaWN1bHQgdG8gZGV0ZWN0IHRoYXQgaXQgaXMgd3JvbmcuIA0KU2hvdWxkIHlvdSB1c2UgQUksIHlvdSBzdGlsbCBuZWVkIHRvIGJlIGNlcnRhaW4geW91IHVuZGVyc3RhbmQgd2hhdCB0aGUgY29kZSBkb2VzLA0KdGhpcyBpcyB5b3VyIHJlc3BvbnNpYmlsaXR5LiBDb25zZXF1ZW50bHksIHlvdSBuZWVkIHRvIGhhdmUgbGVhcm5lZA0KZW5vdWdoIHRvIGJlIGFibGUgdG8gZG8gc28hIA0KDQoNCiMgU29tZSBtYWpvciByZXNzb3VyY2VzIHRvIGZ1cnRoZXIgbGVhcm4gUiBhbmQgZGF0YSBhbmFseXNpcw0KDQpIZXJlIEkgbGluayBzZXZlcmFsIGV4dGVybmFsIHJlc291cmNlcy4gU29tZSBjb250YWluIG1hdGVyaWFsIHRoYXQgd2UgaGF2ZSBzZWVuIA0KaGVyZSBidXQgYXJlIHByZXNlbnRlZCBkaWZmZXJlbnRseS4gVGhleSB3aWxsIGhlbHAgeW91IGdvIGZ1cnRoZXIuIA0KVGhpcyBpcyBmYXIgZnJvbSBiZWluZyBhbiBleGhhdXN0aXZlIGxpc3QuDQoNClJlc291cmNlcyBhcmUgYXZhaWxhYmxlIGluIGRpZmZlcmVudCBmb3JtcyA6DQoNCi0gICBSIEJvb2tzIGZvciBzcGVjaWZpYyB0aGVtZXMgKGluY2wuLCBvbmxpbmUgYm9va3MpIHN1Y2ggYXMgW0FuDQogICAgSW50cm9kdWN0aW9uIHRvIFJdKGh0dHBzOi8vaW50cm8yci5jb20vKSBhbmQgW1IgZm9yIERhdGENCiAgICBTY2llbmNlXShodHRwczovL3I0ZHMuaGFkLmNvLm56LykuIE1hbnkgYm9va3MgdHJlYXQgdGhlIHNhbWUgdGhlbWUsDQogICAgZWcuIFtSIE1hcmtkb3duOiBUaGUgRGVmaW5pdGl2ZQ0KICAgIEd1aWRlXShSJTIwTWFya2Rvd246JTIwVGhlJTIwRGVmaW5pdGl2ZSUyMEd1aWRlKSBhbmQgW1IgbWFya2Rvd24NCiAgICBjb29rYm9va10oaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvcm1hcmtkb3duLWNvb2tib29rLykgYW5kIFtSIGJvb2tkb3duXSgNCiAgICBodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ib29rZG93bi8pIGFuZCB0aGUgYm9vayBmb3IgdGhlIG5pY2UgdmlzdWFsaXphdGlvbg0KICAgIHBsb3RzIFtnZ3Bsb3QyXShodHRwczovL2dncGxvdDItYm9vay5vcmcvKSwgYW5kIG1hbnkgb3RoZXJzIC4uLiANCiAgICB5b3UgKipjYW4ndCoqIHJlYWQgdGhlbSBhbGwhDQoNCi0gICBTdGF0aXN0aWNhbCBhbmFseXNpcyBib29rcyB3aGVyZSBSIGlzIHVzZWQgZm9yIHRoZSBhbmFseXNlczogZWcuDQogICAgW01vZGVybiBTdGF0aXN0aWNzIGZvciBNb2Rlcm4NCiAgICBCaW9sb2d5XShodHRwczovL3dlYi5zdGFuZm9yZC5lZHUvY2xhc3MvYmlvczIyMS9ib29rLykNCg0KLSAgIFR1dG9yaWFscyBlZy4gW1NldHRpbmcgdXAgYSByZXByb2R1Y2libGUNCiAgICBwcm9qZWN0XShodHRwczovL2FsZXhkMTA2LmdpdGh1Yi5pby9pbnRybzJSL3Byb2plY3Rfc2V0dXAuaHRtbCkgYW5kDQogICAgYWxyZWFkeSBtYWRlIGNvdXJzZXMgbWFkZSBlZy4gYnkgdGhlIFtDYXJwZW50aWVzDQogICAgY29tbXVuaXR5XShodHRwczovL2NhcnBlbnRyaWVzLm9yZy9jb21tdW5pdHktbGVzc29ucy8pLCBpbmNsLiBjb3Vyc2UNCiAgICBpbiBkZXZlbG9wbWVudCB3aGVyZSB5b3UgYWxzbyBjYW4gY29udHJpYnV0ZSBbQ2FycGVudHJpZXMNCiAgICBpbmN1YmF0b3JdKGh0dHBzOi8vY2FycGVudHJpZXMub3JnL2NvbW11bml0eS1sZXNzb25zLykgQU5EIEkgbWFuYWdlZA0KICAgIHRvIGZpbmQgb25lIHRyZWF0aW5nIEFNUiANCiAgICBbUiBmb3IgQU1SIGVwaWRlbWlvbG9neV0oaHR0cHM6Ly9naXRodWItcGFnZXMuYXJjLnVjbC5hYy51ay9yLWFtci1lcGlkZW1pb2xvZ3kvaW5kZXguaHRtbCkNCg0KLSAgIEJsb2dzIGVnLiBbUi1ibG9nZ2Vyc10oaHR0cHM6Ly93d3cuci1ibG9nZ2Vycy5jb20vKSBvciBvdGhlcg0KICAgIHdlYnNpdGVzIGVnLiBbUiBncmFwaCBHYWxsZXJ5XShodHRwczovL3ItZ3JhcGgtZ2FsbGVyeS5jb20vKSB3aGljaA0KICAgIGNhbiBwcm92aWRlIGVpdGhlciBpbnNwaXJhdGlvbiBvciBzbWFsbCBzb2x1dGlvbnMgdG8gcHJvYmxlbXMgeW91DQogICAgYXJlIGhhdmluZw0KDQotICAgRm9ydW1zIHdoZXJlIHlvdSBjYW4gYXNrIHNwZWNpZmljIHF1ZXN0aW9ucyBlZy4NCiAgICBbU3RhY2tvdmVyZmxvd10oaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS8pIG9yIFtSc3R1ZGlvDQogICAgY29tbXVuaXR5XShodHRwczovL2NvbW11bml0eS5yc3R1ZGlvLmNvbS8pLiBEbyBub3QgZm9yZ2V0IHRvIHJlYWQNCiAgICBob3cgeW91IHNob3VsZCBhc2sgcXVlc3Rpb25zIGVnLiBmb3INCiAgICBbc3RhdGNrb3ZlcmZsb3ddKGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vaGVscC9ob3ctdG8tYXNrKS4NCg0KLSAgIFJlcG9zaXRvcmllcyBhc3NvY2lhdGVkIHRvIHN0YXRpc3RpY2FsIGNvdXJzZXMgZWcuIHRoZSBvbmxpbmUNCiAgICBbU3RhdGlzdGljYWwgUmV0aGlua2luZw0KICAgIGNvdXJzZV0oaHR0cHM6Ly93d3cueW91dHViZS5jb20vcGxheWxpc3Q/bGlzdD1QTERjVU05VVM0WGRQei1LeEhNNFhIdDd1VVZHV1dWU3VzKQ0KICAgIGhhcyB0aGlzIFtjb2RlDQogICAgcmVwb3NpdG9yeV0oaHR0cHM6Ly9naXRodWIuY29tL3JtY2VscmVhdGgvc3RhdF9yZXRoaW5raW5nXzIwMjM/dGFiPXJlYWRtZS1vdi1maWxlKQ0KICAgIGFzc29jaWF0ZWQuDQoNCi0gICBTb21lIFIgcGFja2FnZXMgYWxzbyBoYXZlIHZpZ25ldHRlcyA8IS0tIGV4cGxhaW4gLS0+IHRoYXQgY2FuIHNob3cNCiAgICBleGFtcGxlcyBob3cgdG8gdXNlIHRoZWlyIGNvZGU7IGVnLiBwYWNrYWdlDQogICAgW3ByZXR0eWRvY10oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3ByZXR0eWRvYy92aWduZXR0ZXMvaHBzdHIuaHRtbCkgDQogICAgDQotICAgVGhlcmUgYXJlIG9mIGNvdXJzZSBvbmxpbmUgY291cnNlczogZWcgYXQgQ291cnNlcmFeMSAsIA0KICAgIGFuZCBbTUlUIE9wZW5Db3Vyc2VXYXJlXShodHRwczovL29jdy5taXQuZWR1LykuIA0KICAgIA0KLSAgIFNvbWUgdXNlZnVsIHRyaWNrcyBbaGVyZSBmb3IgUnN0dWRpb10oaHR0cHM6Ly9zd2NhcnBlbnRyeS5naXRodWIuaW8vZ2l0LW5vdmljZS9pbnN0cnVjdG9yLzA0LWNoYW5nZXMuaHRtbCkNCmFuZCBmb3IgDQpbUm1hcmtkb3duIGZhc3QgbGVhc3Nvbm0gaW5jbC4gc3ludGF4IHN1bW1hcnldKGh0dHBzOi8vdWNzYmNhcnBlbnRyeS5naXRodWIuaW8vUi1tYXJrZG93bi8wMS13aHkvaW5kZXguaHRtbCkNCiAgICANCi0gICAuLi4NCg0KDQpZb3Ugd2lsbCBmaW5kIGFsc28gc29tZSBhZGRpdGlvbmFsIHJlc291cmNlcyB0aHJvdWdoIHRoZSBjb3Vyc2UuICANCg0KDQpOb3RlIHRoYXQgdGhpcyBjb3Vyc2Ugd2lsbCBiZSBncmVhdGx5IGluc3BpcmVkIGZyb20gdHdvIGNvcmUgc29mdHdhcmUgY2FycGVudHJ5IA0KbGVzc29uczogDQotIFtQcm9ncmFtbWluZyB3aXRoIFJdKGh0dHBzOi8vc3djYXJwZW50cnkuZ2l0aHViLmlvL3Itbm92aWNlLWluZmxhbW1hdGlvbi8pDQotIFtSIGZvciBSZXByb2R1Y2libGUgU2NpZW50aWZpYyBBbmFseXNpc10oaHR0cHM6Ly9zd2NhcnBlbnRyeS5naXRodWIuaW8vci1ub3ZpY2UtZ2FwbWluZGVyLykNCg0KQmFjayB0byBbSW5kZXhdKGluZGV4Lmh0bWwpDQo=