Collaborative github



github for collaboration (in RStudio)



github & science

"The need for a logical way to organize and control revisions has existed for almost as long as writing has existed, but revision control became much more important, and complicated, when the era of computing began."


version control


.


http://billmills.github.io/scienceXpython/


modern science workflows

can be overwhelming


succesful modern science workflows

can be extremely powerful



github for science

ideal for managing the full suite of research outputs such as datasets, statistical code, figures, lab notes, and manuscripts.

Rstudio for r users

invest in next generation science skills





empowering collaboration

repos

centralising information e.g. ROpenSci / rfishbase


issues

project management


commits

project tracking




fostering reproducibility

commits

traceability



entire process of project evolution reproducible




PRACTICALS


Practical 1: Github & Rstusio for version control

Code Cafe Style tutorial by Mike Croucher

Practical 2: Github & Rstusio for collaborative coding

In this exercise, each participant will be forking a repo in order to create and contribute a trendline for the evolution of a trait in an imaginary species.

We’ll use github to collate the trendlines for all our species and plot them up all together!



fork repo

github: make your own copy of the repository** on github

  • fork are linked and traceable


github: Github makes a copy into your account


github: clone it: copy repo link to initiate Rstudio project



create new project in Rstudio

rstudio: Create new project**


rstudio: Checkout from version control repository


rstudio: Clone project from a git repository


rstudio: Paste repo link copied from Github into Repository URL field. Click Create Project.


rstudio: Rstudio project now contains all files from the github repo.



make a change to the repo

rstudio: open params/params_tmpl.R


rstudio: save as new .R script in params/ folder. Use species name of your choice to name new file


rstudio: edit file with parameters of your choice and save.



commit changes locally to git

rstudio: in the git tab, select the new file you created and click Commit


rstudio: write an informative commit message and click Commit


rstudio: your new file has now been commited



push changes to Github

rstudio: on the git tab click ⇧ to push changes to Github


rstudio: changes have now been updated on Github repo



create pull request

github: in your repository, create new pull request to merge fork to master repo (ie the original repo you forked)


github: github checkes whether your requested merge creates any coflicts. If all is good, click on Create pull request


github: write an informative message, explaining your changes to the master repo administrators. Click on Create pull request


github: check original repo to see your merged changes




exercise

your mission

We’ll merge all contributions and plot them together at the end!

resources

link to presentation handout

Karthik Ram’s article: ‘Git can facilitate greater reproducibility and increased transparency in science’

Getting started with GitHub from materials for a software carpentry course at UBC

Slides for lecture Karl Broman gave on git/github, with notes

joeyklee’s friendly github intro. Mozilla Science Lab workshop

IyMgKipDb2xsYWJvcmF0aXZlIGBnaXRodWJgKioKPGJyPgo8YnI+CgojIyMgKipBbm5hIEtyeXN0YWxsaSoqCiMjIyMjICoqKkluc3RpdHV0byBkZSBFY29sb2fDrWEsIFVOQU0gMSBTZXAuIDIwMTYqKioKCjxicj4KCiMjIyMjIyA8aHR0cHM6Ly9hbm5ha3J5c3RhbGxpLmdpdGh1Yi5pby9VTkFNL2NvbGxhYl9naF9pbnRyby5uYi5odG1sPgoKIyMjIyMjIFtcQGFubmFrcnlzdGFsbGldKGh0dHBzOi8vdHdpdHRlci5jb20vYW5uYWtyeXN0YWxsaSkgfCBhbm5ha3J5c3RhbGxpQGdvb2dsZW1haWwuY29tCgo8YnI+Cjxicj4KCiMjIAoKIyMjICoqZ2l0aHViIGZvciBjb2xsYWJvcmF0aW9uIChpbiBSU3R1ZGlvKSoqCgo8aW1nIHNyYz0iaHR0cDovL3d3dy5wYWxlcm1vLmVkdS9BcmNoaXZvc19jb250ZW50L2luZ2VuaWVyaWEvdG9wLzEzMDcxMl9naXRfZ2l0aHViX3RvcGRlbm90YTEuanBnIiBoZWlnaHQ9IjMwMHB4IiAvPgoKCjxicj4KPGJyPgoKCiMjICoqZ2l0aHViICYgc2NpZW5jZSoqCgo+IFwiKlRoZSBuZWVkIGZvciBhIGxvZ2ljYWwgd2F5IHRvIG9yZ2FuaXplIGFuZCBjb250cm9sIHJldmlzaW9ucyBoYXMgZXhpc3RlZCBmb3IgYWxtb3N0IGFzIGxvbmcgYXMgd3JpdGluZyBoYXMgZXhpc3RlZCwgYnV0IHJldmlzaW9uIGNvbnRyb2wgYmVjYW1lIG11Y2ggbW9yZSBpbXBvcnRhbnQsIGFuZCBjb21wbGljYXRlZCwgd2hlbiB0aGUgZXJhIG9mIGNvbXB1dGluZyBiZWdhbi4qXCIKCjxicj4KCiMjICoqdmVyc2lvbiBjb250cm9sKioKCi0gKipsb25nIGJlZW4gdXNlZCB0byBtYWludGFpbiBjb2RlIHJlcG9zaXRvcmllcyBpbiB0aGUgc29mdHdhcmUgaW5kdXN0cnkqKgoKICAgICA+IGVzcGVjaWFsbHkgaW4gb3BlbiBzb3VyY2Ugc29mdHdhcmUKICAgIAotICoqc2NpZW5jZSBpbmNyZWFzaW5nbHkgY29tcHV0YXRpb25hbCoqCgogICAgPiBkZW1hbmRzIGZvciBpbmNyZWFzZWQgb3Blbm5lc3MKCjxicj4KCgoKCiMjIHtkYXRhLWJhY2tncm91bmQtaWZyYW1lPSJodHRwOi8vYmlsbG1pbGxzLmdpdGh1Yi5pby9zY2llbmNlWHB5dGhvbi8ifQoKLgo8YnI+Cjxicj4KPGJyPgoKPGh0dHA6Ly9iaWxsbWlsbHMuZ2l0aHViLmlvL3NjaWVuY2VYcHl0aG9uLz4KCjxicj4KCiMjIG1vZGVybiBzY2llbmNlIHdvcmtmbG93cwoKKioqY2FuIGJlIG92ZXJ3aGVsbWluZyoqKgoKPGltZyBzcmM9ImltYWdlcy93b3JrZmxvd3MucG5nIiB3aWR0aD0iNTAwcHgiIC8+Cgo8YnI+CgojIyBzdWNjZXNmdWwgbW9kZXJuIHNjaWVuY2Ugd29ya2Zsb3dzCgoqKipjYW4gYmUgZXh0cmVtZWx5IHBvd2VyZnVsKioqCgo8aW1nIHNyYz0iaW1hZ2VzL2NvbGxhYi5wbmciIHdpZHRoPSI1MDBweCIgLz4KCjxicj4KPGJyPgoKIyMgZ2l0aHViIGZvciBzY2llbmNlCgpbIVtdKGltYWdlcy9naXQ0c2NpLnBuZyldKGh0dHA6Ly9zY2ZibS5iaW9tZWRjZW50cmFsLmNvbS9hcnRpY2xlcy8xMC4xMTg2LzE3NTEtMDQ3My04LTcpCgoKPiBpZGVhbCBmb3IgbWFuYWdpbmcgdGhlIGZ1bGwgc3VpdGUgb2YgcmVzZWFyY2ggb3V0cHV0cyBzdWNoIGFzIGRhdGFzZXRzLCBzdGF0aXN0aWNhbCBjb2RlLCBmaWd1cmVzLCBsYWIgbm90ZXMsIGFuZCBtYW51c2NyaXB0cy4KCiMjIyMgZS5nIFsqKipNeSByZXNlYXJjaCB3b3JrZmxvdywgYmFzZWQgb24gR2l0aHViKioqXShodHRwczovL3N0YXR1cy5naXRodWIuY29tL2ltYWdlcy9pbnZlcnRvY2F0LnBuZykgYnkgWypDYXJsIEJvZXR0aWdlcipdKGh0dHBzOi8vdHdpdHRlci5jb20vY2JvZXR0aWcpCgoKPGJyPgoKIyMgUnN0dWRpbyBmb3IgciB1c2VycyAKCiFbXShodHRwczovL3N0YXR1cy5naXRodWIuY29tL2ltYWdlcy9pbnZlcnRvY2F0LnBuZykKCjxpbWcgc3JjPSJodHRwczovL3Bicy50d2ltZy5jb20vcHJvZmlsZV9pbWFnZXMvNDg3Mjc3MDk1NjgxMTUwOTc2L2FFcDJ2bEp5LnBuZyIgd2lkdGg9IjIwMHB4IiAvPgoKCgojIyAqKmludmVzdCBpbiBuZXh0IGdlbmVyYXRpb24gc2NpZW5jZSBza2lsbHMqKgoKPGJyPgoKLSAuLi5hbmQgc3VwZXItY2hhcmdlIHlvdXIgdGVhbXMhCgotIC4uLm9yIGdldCBsZWZ0IGJlaGluZAoKPGJyPgo8YnI+CgoqKioKCiMgKiplbXBvd2VyaW5nIGNvbGxhYm9yYXRpb24qKgoKIyMgcmVwb3MKCmNlbnRyYWxpc2luZyBpbmZvcm1hdGlvbiBlLmcuIFsqKlJPcGVuU2NpIC8gcmZpc2hiYXNlKipdKGh0dHBzOi8vZ2l0aHViLmNvbS9yb3BlbnNjaS9yZmlzaGJhc2UpCgo8aW1nIHNyYz0iaW1hZ2VzL3JlcG8tMS5wbmciIHdpZHRoPSI1MDBweCIvPgoKCgoKPGJyPgoKIyMgaXNzdWVzCgpwcm9qZWN0IG1hbmFnZW1lbnQKCls8aW1nIHNyYz0iaW1hZ2VzL2lzc3Vlcy0xLnBuZyIgd2lkdGg9IjUwMHB4Ii8+XShodHRwczovL2dpdGh1Yi5jb20vcm9wZW5zY2kvcmZpc2hiYXNlL2lzc3VlcykKCjxicj4KCiMjIGNvbW1pdHMgCgpwcm9qZWN0IHRyYWNraW5nCgpbPGltZyBzcmM9ImltYWdlcy90cmFjay0xLnBuZyIgd2lkdGg9IjUwMHB4Ii8+XShodHRwczovL2dpdGh1Yi5jb20vcm9wZW5zY2kvcmZpc2hiYXNlL25ldHdvcmspCgo8YnI+Cjxicj4KCioqKgoKIyAqKmZvc3RlcmluZyByZXByb2R1Y2liaWxpdHkqKgoKIyMgY29tbWl0cwoKdHJhY2VhYmlsaXR5CgpbPGltZyBzcmM9ImltYWdlcy9jb21taXRzLTEucG5nIiB3aWR0aD0iNTAwcHgiLz5dKGh0dHBzOi8vZ2l0aHViLmNvbS9yb3BlbnNjaS9yZmlzaGJhc2UvY29tbWl0cy9tYXN0ZXIpCgo8YnI+Cjxicj4KCiMjICoqZW50aXJlIHByb2Nlc3Mgb2YgcHJvamVjdCBldm9sdXRpb24gcmVwcm9kdWNpYmxlKioKCjxicj4KPGJyPgoKKioqCgojICoqUFJBQ1RJQ0FMUyoqCgo8YnI+CgojIyAqKlByYWN0aWNhbCAxOiBHaXRodWIgJiBSc3R1c2lvIGZvciB2ZXJzaW9uIGNvbnRyb2wqKgoKQ29kZSBDYWZlIFN0eWxlIHR1dG9yaWFsIGJ5IFtNaWtlIENyb3VjaGVyXShodHRwOi8vd3d3LndhbGtpbmdyYW5kb21seS5jb20vKQoKIyMjIFsqKkVudGVyIFByYWN0aWNhbCoqXShodHRwczovL2dpdGh1Yi5jb20vbWlrZWNyb3VjaGVyL0lTQkVfU3ltcG9zaXVtKQoKCjxicj4KPGJyPgo8YnI+CgoKIyMgKipQcmFjdGljYWwgMjogR2l0aHViICYgUnN0dXNpbyBmb3IgY29sbGFib3JhdGl2ZSBjb2RpbmcqKgoKSW4gdGhpcyBleGVyY2lzZSwgZWFjaCBwYXJ0aWNpcGFudCB3aWxsIGJlIGZvcmtpbmcgYSByZXBvIGluIG9yZGVyIHRvIGNyZWF0ZSBhbmQgY29udHJpYnV0ZSBhICoqdHJlbmRsaW5lIGZvciB0aGUgZXZvbHV0aW9uIG9mIGEgdHJhaXQqKiBpbiBhbiBpbWFnaW5hcnkgc3BlY2llcy4KCldlJ2xsIHVzZSBnaXRodWIgdG8gY29sbGF0ZSB0aGUgdHJlbmRsaW5lcyBmb3IgYWxsIG91ciBzcGVjaWVzIGFuZCBwbG90IHRoZW0gdXAgYWxsIHRvZ2V0aGVyIQoKPGJyPgo8YnI+CgoKIyMgKipnaXRodWI6IHN0YXJ0IHdpdGggYSByZXBvKioKCjxodHRwczovL2dpdGh1Yi5jb20vUlNFLVNoZWZmaWVsZC9jb2xsYWJvcmF0aXZlX2dpdGh1Yl9leGVyY2lzZT4KCjxpbWcgc3JjPSJpbWFnZXMvcmVwby5wbmciIHdpZHRoPSI1MDBweCIgLz4KCjxicj4KCiMjICoqZm9yayByZXBvKioKCioqZ2l0aHViOiBtYWtlIHlvdXIgKipvd24gY29weSBvZiB0aGUgcmVwb3NpdG9yeSoqIG9uIGdpdGh1YgoKLSBmb3JrIGFyZSBsaW5rZWQgYW5kIHRyYWNlYWJsZQoKPGltZyBzcmM9ImltYWdlcy9mb3JrLTEucG5nIiB3aWR0aD0iNTAwcHgiIC8+IAoKPGJyPgoKIyMKCioqZ2l0aHViOioqIEdpdGh1YiBtYWtlcyBhICoqY29weSBpbnRvIHlvdXIgYWNjb3VudCoqCgo8aW1nIHNyYz0iaW1hZ2VzL2ZvcmstMi5wbmciIHdpZHRoPSI1MDBweCIgLz4KIAo8YnI+CgojIyAKICAgICAgICAKKipnaXRodWI6IGNsb25lIGl0OiBjb3B5IHJlcG8gbGluayoqIHRvIGluaXRpYXRlIFJzdHVkaW8gcHJvamVjdAogICAgCjxpbWcgc3JjPSJpbWFnZXMvZm9yay0zLnBuZyIgd2lkdGg9IjUwMHB4IiAvPgoKPGJyPgo8YnI+CgoKIyMgKipjcmVhdGUgbmV3IHByb2plY3QgaW4gUnN0dWRpbyoqCgoKIyMKKipyc3R1ZGlvOiBDcmVhdGUgKipuZXcgcHJvamVjdCoqCgo8aW1nIHNyYz0iaW1hZ2VzL25ld3Byb2otMS5wbmciIHdpZHRoPSI1MDBweCIgLz4KCjxicj4KCiMjCioqcnN0dWRpbzoqKiBDaGVja291dCBmcm9tICoqdmVyc2lvbiBjb250cm9sIHJlcG9zaXRvcnkqKgoKPGltZyBzcmM9ImltYWdlcy9uZXdwcm9qLTIucG5nIiB3aWR0aD0iNTAwcHgiIC8+Cgo8YnI+CgojIwoqKnJzdHVkaW86KiogQ2xvbmUgcHJvamVjdCBmcm9tIGEgKipnaXQqKiByZXBvc2l0b3J5Cgo8aW1nIHNyYz0iaW1hZ2VzL25ld3Byb2otMy5wbmciIHdpZHRoPSI1MDBweCIgLz4KCjxicj4KCgojIwoqKnJzdHVkaW86KiogUGFzdGUgKipyZXBvIGxpbmsgY29waWVkIGZyb20gR2l0aHViKiogaW50byAqKlJlcG9zaXRvcnkgVVJMKiogZmllbGQuIENsaWNrICoqYENyZWF0ZSBQcm9qZWN0YCoqLiAKCjxpbWcgc3JjPSJpbWFnZXMvbmV3cHJvai00LnBuZyIgd2lkdGg9IjUwMHB4IiAvPgoKPGJyPgoKIyMKKipyc3R1ZGlvOioqIFJzdHVkaW8gcHJvamVjdCBub3cgKipjb250YWlucyBhbGwgZmlsZXMgZnJvbSB0aGUgZ2l0aHViIHJlcG8uKioKCjxpbWcgc3JjPSJpbWFnZXMvbmV3cHJvai01LnBuZyIgd2lkdGg9IjUwMHB4IiAvPgoKPGJyPgo8YnI+CgoKCgojIyAqKm1ha2UgYSBjaGFuZ2UgdG8gdGhlIHJlcG8qKgoKCgoqKnJzdHVkaW86Kiogb3BlbiAqKmBwYXJhbXMvcGFyYW1zX3RtcGwuUmAqKgoKPGltZyBzcmM9ImltYWdlcy9lZGl0LTEucG5nIiB3aWR0aD0iNTAwcHgiIC8+Cgo8YnI+CgojIwoKCioqcnN0dWRpbzoqKiBzYXZlIGFzIG5ldyBgLlJgIHNjcmlwdCBpbiAqKmBwYXJhbXMvYCoqIGZvbGRlci4gVXNlIHNwZWNpZXMgbmFtZSBvZiB5b3VyIGNob2ljZSB0byBuYW1lIG5ldyBmaWxlCgo8aW1nIHNyYz0iaW1hZ2VzL2VkaXQtMi5wbmciIHdpZHRoPSI1MDBweCIgLz4KCjxicj4KCiMjCgoKKipyc3R1ZGlvOioqIGVkaXQgZmlsZSB3aXRoIHBhcmFtZXRlcnMgb2YgeW91ciBjaG9pY2UgYW5kIHNhdmUuCgo8aW1nIHNyYz0iaW1hZ2VzL2VkaXQtMy5wbmciIHdpZHRoPSI1MDBweCIgLz4KCjxicj4KCjxicj4KCgojIyBjb21taXQgY2hhbmdlcyBsb2NhbGx5IHRvIGdpdAoKKipyc3R1ZGlvOioqIGluIHRoZSAqZ2l0KiB0YWIsIHNlbGVjdCB0aGUgKipuZXcgZmlsZSoqIHlvdSBjcmVhdGVkIGFuZCBjbGljayAqKmBDb21taXRgKioKCjxpbWcgc3JjPSJpbWFnZXMvY29tbWl0LTEucG5nIiB3aWR0aD0iNTAwcHgiIC8+Cgo8YnI+CgojIwoKKipyc3R1ZGlvOioqIHdyaXRlIGFuIGluZm9ybWF0aXZlIGNvbW1pdCBtZXNzYWdlIGFuZCBjbGljayAqKmBDb21taXRgKiogIAoKPGltZyBzcmM9ImltYWdlcy9jb21taXQtMi5wbmciIHdpZHRoPSI1MDBweCIgLz4KCjxicj4KCiMjCgoqKnJzdHVkaW86KiogeW91ciBuZXcgZmlsZSBoYXMgbm93IGJlZW4gY29tbWl0ZWQgIAoKPGltZyBzcmM9ImltYWdlcy9jb21taXQtMy5wbmciIHdpZHRoPSI1MDBweCIgLz4KCjxicj4KPGJyPgoKIyMgcHVzaCBjaGFuZ2VzIHRvIEdpdGh1YgoKKipyc3R1ZGlvOioqIG9uIHRoZSAqZ2l0KiB0YWIgY2xpY2sg4oenICB0byAqKnB1c2ggY2hhbmdlcyB0byBHaXRodWIqKgoKPGltZyBzcmM9ImltYWdlcy9wdXNoLTEucG5nIiB3aWR0aD0iNTAwcHgiIC8+Cgo8YnI+CgojIwoKKipyc3R1ZGlvOioqIGNoYW5nZXMgaGF2ZSBub3cgYmVlbiB1cGRhdGVkIG9uICoqR2l0aHViIHJlcG8qKgoKPGltZyBzcmM9ImltYWdlcy9wdXNoLTIucG5nIiB3aWR0aD0iNTAwcHgiIC8+Cgo8YnI+Cjxicj4KCiMjIGNyZWF0ZSBwdWxsIHJlcXVlc3QKCioqZ2l0aHViOioqIGluIHlvdXIgcmVwb3NpdG9yeSwgY3JlYXRlICoqYG5ldyBwdWxsIHJlcXVlc3RgKiogdG8gbWVyZ2UgZm9yayB0byBtYXN0ZXIgcmVwbyAoaWUgdGhlIG9yaWdpbmFsIHJlcG8geW91IGZvcmtlZCkKCjxpbWcgc3JjPSJpbWFnZXMvbWVyZ2UtMS5wbmciIHdpZHRoPSI1MDBweCIgLz4KCjxicj4KCiMjCgoqKmdpdGh1YjoqKiBnaXRodWIgY2hlY2tlcyB3aGV0aGVyIHlvdXIgcmVxdWVzdGVkIG1lcmdlIGNyZWF0ZXMgYW55IGNvZmxpY3RzLiBJZiBhbGwgaXMgZ29vZCwgY2xpY2sgb24gKipgQ3JlYXRlIHB1bGwgcmVxdWVzdGAqKgoKPGltZyBzcmM9ImltYWdlcy9tZXJnZS0yLnBuZyIgd2lkdGg9IjUwMHB4IiAvPgoKPGJyPgoKIyMKCioqZ2l0aHViOioqIHdyaXRlIGFuIGluZm9ybWF0aXZlIG1lc3NhZ2UsIGV4cGxhaW5pbmcgeW91ciBjaGFuZ2VzIHRvIHRoZSBtYXN0ZXIgcmVwbyBhZG1pbmlzdHJhdG9ycy4gQ2xpY2sgb24gKipgQ3JlYXRlIHB1bGwgcmVxdWVzdGAqKgoKPGltZyBzcmM9ImltYWdlcy9tZXJnZS0zLnBuZyIgd2lkdGg9IjUwMHB4IiAvPgoKPGJyPgoKIyMKCioqZ2l0aHViOioqIGNoZWNrIG9yaWdpbmFsIHJlcG8gdG8gc2VlICoqeW91ciBtZXJnZWQgY2hhbmdlcyoqCgo8aW1nIHNyYz0iaW1hZ2VzL21lcmdlZC5wbmciIHdpZHRoPSI1MDBweCIgLz4KCjxicj4KPGJyPgo8YnI+CgojIGV4ZXJjaXNlCgojIyB5b3VyIG1pc3Npb24KCi0gZm9yayB0aGUgcmVwbzogPGh0dHBzOi8vZ2l0aHViLmNvbS9SU0UtU2hlZmZpZWxkL2NvbGxhYm9yYXRpdmVfZ2l0aHViX2V4ZXJjaXNlPgotIGxpbmsgaXQgdXAgdG8gYSBuZXcgUnN0dWRpbyBwcm9qZWN0Ci0gY3JlYXRlIGEgbmV3IHBhcmFtcyBgLlJgIHNjcmlwdC4gTmFtZSBpdCB1c2luZyB5b3VyIHNlbGVjdGVkIHNwZWNpZXMgbmFtZS4KLSBlbnRlciBwYXJhbWV0ZXJzIGZvciB5b3VyIHNwZWNpZXMuCi0gY29tbWl0ICYgcHVzaCB5b3VyIGNoYW5nZXMKLSBjcmVhdGUgYSBwdWxsIHJlcXVlc3QgdG8gdGhlIG1hc3RlciByZXBvCgpXZSdsbCBtZXJnZSBhbGwgY29udHJpYnV0aW9ucyBhbmQgW3Bsb3QgdGhlbSB0b2dldGhlciBhdCB0aGUgZW5kIV0oaHR0cDovL3JwdWJzLmNvbS9hbm5ha3J5c3RhbGxpLzIwNTc1NikgCgoKIyMgcmVzb3VyY2VzCgpbbGluayB0byBwcmVzZW50YXRpb24gaGFuZG91dF0oaHR0cHM6Ly9naXRodWIuY29tL2FubmFrcnlzdGFsbGkvSVNCRV9zeW1wb3NpdW0vYmxvYi9tYXN0ZXIvQ29sbGFib3JhdGl2ZV9naXRodWJfdGVzdC9jb2xsYWJfZ2hfaW50by5tZCkKCltLYXJ0aGlrIFJhbSdzIGFydGljbGU6XShodHRwOi8vc2NmYm0uYmlvbWVkY2VudHJhbC5jb20vYXJ0aWNsZXMvMTAuMTE4Ni8xNzUxLTA0NzMtOC03KSAqJ0dpdCBjYW4gZmFjaWxpdGF0ZSBncmVhdGVyIHJlcHJvZHVjaWJpbGl0eSBhbmQgaW5jcmVhc2VkIHRyYW5zcGFyZW5jeSBpbiBzY2llbmNlJyoKCltHZXR0aW5nIHN0YXJ0ZWQgd2l0aCBHaXRIdWJdKGh0dHA6Ly9qZW5ueWJjLmdpdGh1Yi5pby8yMDE0LTA1LTEyLXViYy91YmMtci9zZXNzaW9uMi40X2dpdGh1Yi5odG1sKSBmcm9tIG1hdGVyaWFscyBmb3IgYSBbc29mdHdhcmUgY2FycGVudHJ5IGNvdXJzZSBhdCBVQkNdKGh0dHA6Ly9qZW5ueWJjLmdpdGh1Yi5pby8yMDE0LTA1LTEyLXViYy8pCgpbU2xpZGVzIGZvciBsZWN0dXJlXShodHRwOi8va2Jyb21hbi5vcmcvVG9vbHM0UlIvYXNzZXRzL2xlY3R1cmVzLzA0X2dpdF93aXRobm90ZXMucGRmKSAgS2FybCBCcm9tYW4gZ2F2ZSBvbiBnaXQvZ2l0aHViLCB3aXRoIG5vdGVzCgpbam9leWtsZWUncyBmcmllbmRseSBnaXRodWIgaW50cm9dKGh0dHBzOi8vZ2l0aHViLmNvbS9qb2V5a2xlZS9mcmllbmRseS1naXRodWItaW50cm8pLiAqTW96aWxsYSBTY2llbmNlIExhYiogd29ya3Nob3AKCgoK