This notebook is based loosely on this cheatsheet that shows some of the most basic functionality of R notebooks, including code, markdown, and Latex.

Code

Chunks

You can imbed chunks of R code right into the notebooks and run them. Why not beat that long-dead horse of demo data, the iris dataset?

head(iris)

If you print a dataframe, it automatically gets formatted in this nice way.

We can also look at the summary:

summary(iris)
  Sepal.Length    Sepal.Width     Petal.Length    Petal.Width          Species  
 Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100   setosa    :50  
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300   versicolor:50  
 Median :5.800   Median :3.000   Median :4.350   Median :1.300   virginica :50  
 Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199                  
 3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800                  
 Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500                  

And of course, you can use whatever libraries you like, as usual. We can set an option in this chunk to disable the messages that print to the console when you do things like load libraries. We could also turn off warnings, set options for error handling, or specify how we want results and code interleaved, or if we want the code in the output document at all. Setting the tidy argument to TRUE also spiffs up your code for you (cleaning up multiline expressions with indenting, for instance) in the output. So customizable!

library(dplyr) #We could also have set the quietly argument to TRUE, but where's the fun in that
(meanpetals <- group_by(iris, Species) %>%
               summarize(length = mean(Petal.Length), width = mean(Petal.Width)))

Boring old data demos never looked so fresh!

Inline

Inline code executes invisibly, so all you see is the output. For example, I can run a function right here and now to get the weekday:
Today is a Sunday.

You can also set global parameters in the header and reference them throughout the document.

This inline execution has various uses. If you need code primarily for its output, like getting the current date or weekday and adding it into text, then inline works really well and better than a chunk.

Displaying Data

If you’re writing up a tutorial or a report on results, you’ll more likely than not need to display data in the form of plots and tables. This is super easy in R Notebooks, and there are lots of options.

Plots

Let’s see what the sepal lengths in Iris are up to by species, just for kicks. I’ll do some more extensive data manipulation in a code chunk, just to show we can. Since I loaded dplyr in another code chunk further up, we’re good there.

library(ggplot2)
iris_plot <- ggplot(data=select(iris, Species, Sepal.Length), 
                    aes(x=Species, y=Sepal.Length, color=Species, fill=Species)) +
  geom_violin(alpha=.1) +
  geom_point(position=position_jitter(w=.2)) +
  geom_crossbar(stat='summary',fun.y=mean, fun.ymax=mean, fun.ymin=mean, fatten=2, width=.5) +
  theme_minimal()
print(iris_plot)

Fascinating, I guess!

The nice thing about this is that these plots are completely reproduceable–they’ll be generated everytime you run the notebook. You can keep the code cell that generates it in the output, so people can see it, or if you want a cleaner output with just the results, you can hide the generating code cell. You can tailor it to your options.

Tables

Tables can be a real pain-point when doing manuscripts, but these can be automated in R Notebooks, rendered right into text, and some look pretty good. Here’s what knitr will give you (it won’t look right until it’s rendered):

knitr::kable(meanpetals)
Species length width
setosa 1.462 0.246
versicolor 4.260 1.326
virginica 5.552 2.026

That looks alright!

There’s also xtable, which will make it easier to set the appearance of the table through HTML attributes. This won’t show up until it’s rendered, though.

print(xtable::xtable(as.data.frame(meanpetals, row.names=meanpetals$Species)), type='html', html.table.attributes='border=0  width=250')
Species length width
1 setosa 1.46 0.25
2 versicolor 4.26 1.33
3 virginica 5.55 2.03

Finally, here’s a table fron the stargazer package. Also lots of attributes we can set here. It’s designed mostly for pretty formatting of regression model results and summary stats, but we can get it to do direct output instead.

stargazer::stargazer(as.data.frame(meanpetals), type='html', summary=F)
Species length width
1 setosa 1.462 0.246
2 versicolor 4.260 1.326
3 virginica 5.552 2.026

If none of the formatting is quite to your liking, or you don’t have easily available options to set, you can tweak the appearance with your own CSS.

If none of this is satisfying, or it’s more informal, you can always just print the dataframe.

(meanpetals)

I don’t know that this makes tables any less painless, but at least now there’s more than one option for the pain.

Formatting

If you’re writing up a report or manuscript, you also need your text to look nice, not just your data. This is where knowing a little bit of Markdown comes in handy.

Markdown

Just type to get pretty plaintext. To quote verbatim code without running anything, wrap it in backticks(`). This is distinct from inline code, which is prefaced with r within the ticks. I’ll do this throughout to demonstrate how to construct the effects you see.

To display a special character, like _underscores_ or asterisks *, escape them with a backslash (\).

To add a single linebreak without a blank line, end a line with two spaces...
Ta-da!

*italics*: italics
**bold**: bold
**_both_**: both
~~strikethrough~~: strikethrough
subscript~1~: subscript1
superscript^2^: superscript2

You can do bulleted lists:

* start with an asterisk, plus, or minus + then indent 4 spaces - then indent again * then more stuff

  • start with an asterisk, plus, or minus
    • then indent 4 spaces
      • then indent again
  • then more stuff

And ordered ones:

1. Big thing i) small thing \+ indent A. sub-small thing 2. Another big thing

  1. Big thing
    1. small thing + indent
      A. sub-small thing
  2. Another big thing

Oh, and footnotes… [^1] 1

#Header 1

Header 1

##Header 2

Header 2

###Header 3

Header 3

Add horizontal lines with at least three hyphens, asterisks, or underscores:

***


Tables are a little strange in the raw, but look nice once rendered.

| Right-aligned | Left-aligned | Centered | Default |
|-:|:-|:-:|-|
|1|1|1|1|
|12|12|12|12| 
|*1*|_2_|~~3~~|4^2^|
Right-aligned Left-aligned Centered Default
1 1 1 1
12 12 12 12
1 2 3 42

Images are easy, too.
![The adorabilis octopus, for your viewing pleasure](http://blogs.discovermagazine.com/d-brief/files/2015/06/octopus.jpg)

The adorabilis octopus, for your viewing pleasure

The adorabilis octopus, for your viewing pleasure

Latex and Equations

Math formatting can be done with the same notation used in Latex.

To do inline equations or mathematical notation, use single dollar signs: $f(x) = \frac{1}{x}$. \(f(x) = \frac{1}{x}\)

To do an equation block, use double dollar signs: $$-b \pm \sqrt{\frac{b^2 - 4ac}{2a}}$$
\[-b \pm \sqrt{\frac{b^2 - 4ac}{2a}}\]

We can do Greek letters: $\Sigma \; \alpha \; \gamma$: \(\Sigma \; \alpha \; \gamma\)

Sums, products, and integrals can be inline with inner limits: $\sum_{i=1}^{\infty}x_i$ \(\sum_{i=1}^{\infty}x_i\)
Or inline with outer limits: $\prod\limits_{i=1}^{\infty}\frac{1}{x_i}$ \(\prod\limits_{i=1}^{\infty}\frac{1}{x_i}\)

Or block: $$\int_{a}^{b}x^2dx$$ \[\int_{a}^{b}x^2dx\]

And matrices are lovely, too. With parens:

$\begin{pmatrix}  
1 & 2 & 3 \\ 
4 & 5 & 6
\end{pmatrix}$

\(\begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix}\)

Brackets:

$\begin{bmatrix}  
1 & 2 \\ 
4 & 5   
\end{bmatrix}$  

\(\begin{bmatrix} 1 & 2 \\ 4 & 5 \end{bmatrix}\)

Or itty-bitty(good for inline!):

$\left[\begin{smallmatrix}  
1 & 2 \\
4 & 5   
\end{smallmatrix}\right]$  

\(\left[\begin{smallmatrix} 1 & 2 \\ 4 & 5 \end{smallmatrix}\right]\)


  1. [^1]: Are pretty easy.

LS0tCnRpdGxlOiAiVHV0b3JpYWwgUiBOb3RlYm9vayIKYXV0aG9yOiAiS2F0aGVyaW5lIFdvb2QiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgZ2l0aHViX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQpUaGlzIG5vdGVib29rIGlzIGJhc2VkIGxvb3NlbHkgb24gW3RoaXMgY2hlYXRzaGVldF0oaHR0cHM6Ly93d3cucnN0dWRpby5jb20vd3AtY29udGVudC91cGxvYWRzLzIwMTYvMDMvcm1hcmtkb3duLWNoZWF0c2hlZXQtMi4wLnBkZikgdGhhdCBzaG93cyBzb21lIG9mIHRoZSBtb3N0IGJhc2ljIGZ1bmN0aW9uYWxpdHkgb2YgUiBub3RlYm9va3MsIGluY2x1ZGluZyBjb2RlLCBtYXJrZG93biwgYW5kIExhdGV4LgoKI0NvZGUKCiMjQ2h1bmtzCllvdSBjYW4gaW1iZWQgY2h1bmtzIG9mIFIgY29kZSByaWdodCBpbnRvIHRoZSBub3RlYm9va3MgYW5kIHJ1biB0aGVtLiBXaHkgbm90IGJlYXQgdGhhdCBsb25nLWRlYWQgaG9yc2Ugb2YgZGVtbyBkYXRhLCB0aGUgaXJpcyBkYXRhc2V0PwoKYGBge3J9CmhlYWQoaXJpcykKYGBgCgpJZiB5b3UgcHJpbnQgYSBkYXRhZnJhbWUsIGl0IGF1dG9tYXRpY2FsbHkgZ2V0cyBmb3JtYXR0ZWQgaW4gdGhpcyBuaWNlIHdheS4KCldlIGNhbiBhbHNvIGxvb2sgYXQgdGhlIHN1bW1hcnk6CmBgYHtyfQpzdW1tYXJ5KGlyaXMpCmBgYAoKQW5kIG9mIGNvdXJzZSwgeW91IGNhbiB1c2Ugd2hhdGV2ZXIgbGlicmFyaWVzIHlvdSBsaWtlLCBhcyB1c3VhbC4gV2UgY2FuIHNldCBhbiBvcHRpb24gaW4gdGhpcyBjaHVuayB0byBkaXNhYmxlIHRoZSBtZXNzYWdlcyB0aGF0IHByaW50IHRvIHRoZSBjb25zb2xlIHdoZW4geW91IGRvIHRoaW5ncyBsaWtlIGxvYWQgbGlicmFyaWVzLiBXZSBjb3VsZCBhbHNvIHR1cm4gb2ZmIHdhcm5pbmdzLCBzZXQgb3B0aW9ucyBmb3IgZXJyb3IgaGFuZGxpbmcsIG9yIHNwZWNpZnkgaG93IHdlIHdhbnQgcmVzdWx0cyBhbmQgY29kZSBpbnRlcmxlYXZlZCwgb3IgaWYgd2Ugd2FudCB0aGUgY29kZSBpbiB0aGUgb3V0cHV0IGRvY3VtZW50IGF0IGFsbC4gU2V0dGluZyB0aGUgYHRpZHlgIGFyZ3VtZW50IHRvIGBUUlVFYCBhbHNvIHNwaWZmcyB1cCB5b3VyIGNvZGUgZm9yIHlvdSAoY2xlYW5pbmcgdXAgbXVsdGlsaW5lIGV4cHJlc3Npb25zIHdpdGggaW5kZW50aW5nLCBmb3IgaW5zdGFuY2UpIGluIHRoZSBvdXRwdXQuIFNvIGN1c3RvbWl6YWJsZSEgCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoZHBseXIpICNXZSBjb3VsZCBhbHNvIGhhdmUgc2V0IHRoZSBxdWlldGx5IGFyZ3VtZW50IHRvIFRSVUUsIGJ1dCB3aGVyZSdzIHRoZSBmdW4gaW4gdGhhdAoobWVhbnBldGFscyA8LSBncm91cF9ieShpcmlzLCBTcGVjaWVzKSAlPiUKICAgICAgICAgICAgICAgc3VtbWFyaXplKGxlbmd0aCA9IG1lYW4oUGV0YWwuTGVuZ3RoKSwgd2lkdGggPSBtZWFuKFBldGFsLldpZHRoKSkpCmBgYApCb3Jpbmcgb2xkIGRhdGEgZGVtb3MgbmV2ZXIgbG9va2VkIHNvIGZyZXNoIQoKIyNJbmxpbmUKSW5saW5lIGNvZGUgZXhlY3V0ZXMgaW52aXNpYmx5LCBzbyBhbGwgeW91IHNlZSBpcyB0aGUgb3V0cHV0LiBGb3IgZXhhbXBsZSwgSSBjYW4gcnVuIGEgZnVuY3Rpb24gcmlnaHQgaGVyZSBhbmQgbm93IHRvIGdldCB0aGUgd2Vla2RheTogIApUb2RheSBpcyBhIGByIHdlZWtkYXlzKFN5cy50aW1lKCkpYC4KCllvdSBjYW4gYWxzbyBzZXQgZ2xvYmFsIHBhcmFtZXRlcnMgaW4gdGhlIGhlYWRlciBhbmQgcmVmZXJlbmNlIHRoZW0gdGhyb3VnaG91dCB0aGUgZG9jdW1lbnQuCgpUaGlzIGlubGluZSBleGVjdXRpb24gaGFzIHZhcmlvdXMgdXNlcy4gSWYgeW91IG5lZWQgY29kZSBwcmltYXJpbHkgZm9yIGl0cyBvdXRwdXQsIGxpa2UgZ2V0dGluZyB0aGUgY3VycmVudCBkYXRlIG9yIHdlZWtkYXkgYW5kIGFkZGluZyBpdCBpbnRvIHRleHQsIHRoZW4gaW5saW5lIHdvcmtzIHJlYWxseSB3ZWxsIGFuZCBiZXR0ZXIgdGhhbiBhIGNodW5rLgoKI0Rpc3BsYXlpbmcgRGF0YQoKSWYgeW91J3JlIHdyaXRpbmcgdXAgYSB0dXRvcmlhbCBvciBhIHJlcG9ydCBvbiByZXN1bHRzLCB5b3UnbGwgbW9yZSBsaWtlbHkgdGhhbiBub3QgbmVlZCB0byBkaXNwbGF5IGRhdGEgaW4gdGhlIGZvcm0gb2YgcGxvdHMgYW5kIHRhYmxlcy4gVGhpcyBpcyBzdXBlciBlYXN5IGluIFIgTm90ZWJvb2tzLCBhbmQgdGhlcmUgYXJlIGxvdHMgb2Ygb3B0aW9ucy4KCiMjUGxvdHMKTGV0J3Mgc2VlIHdoYXQgdGhlIHNlcGFsIGxlbmd0aHMgaW4gSXJpcyBhcmUgdXAgdG8gYnkgc3BlY2llcywganVzdCBmb3Iga2lja3MuIEknbGwgZG8gc29tZSBtb3JlIGV4dGVuc2l2ZSBkYXRhIG1hbmlwdWxhdGlvbiBpbiBhIGNvZGUgY2h1bmssIGp1c3QgdG8gc2hvdyB3ZSBjYW4uIFNpbmNlIEkgbG9hZGVkIGRwbHlyIGluIGFub3RoZXIgY29kZSBjaHVuayBmdXJ0aGVyIHVwLCB3ZSdyZSBnb29kIHRoZXJlLgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQppcmlzX3Bsb3QgPC0gZ2dwbG90KGRhdGE9c2VsZWN0KGlyaXMsIFNwZWNpZXMsIFNlcGFsLkxlbmd0aCksIAogICAgICAgICAgICAgICAgICAgIGFlcyh4PVNwZWNpZXMsIHk9U2VwYWwuTGVuZ3RoLCBjb2xvcj1TcGVjaWVzLCBmaWxsPVNwZWNpZXMpKSArCiAgZ2VvbV92aW9saW4oYWxwaGE9LjEpICsKICBnZW9tX3BvaW50KHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcih3PS4yKSkgKwogIGdlb21fY3Jvc3NiYXIoc3RhdD0nc3VtbWFyeScsZnVuLnk9bWVhbiwgZnVuLnltYXg9bWVhbiwgZnVuLnltaW49bWVhbiwgZmF0dGVuPTIsIHdpZHRoPS41KSArCiAgdGhlbWVfbWluaW1hbCgpCnByaW50KGlyaXNfcGxvdCkKYGBgCgpGYXNjaW5hdGluZywgSSBndWVzcyEKClRoZSBuaWNlIHRoaW5nIGFib3V0IHRoaXMgaXMgdGhhdCB0aGVzZSBwbG90cyBhcmUgY29tcGxldGVseSByZXByb2R1Y2VhYmxlLS10aGV5J2xsIGJlIGdlbmVyYXRlZCBldmVyeXRpbWUgeW91IHJ1biB0aGUgbm90ZWJvb2suIFlvdSBjYW4ga2VlcCB0aGUgY29kZSBjZWxsIHRoYXQgZ2VuZXJhdGVzIGl0IGluIHRoZSBvdXRwdXQsIHNvIHBlb3BsZSBjYW4gc2VlIGl0LCBvciBpZiB5b3Ugd2FudCBhIGNsZWFuZXIgb3V0cHV0IHdpdGgganVzdCB0aGUgcmVzdWx0cywgeW91IGNhbiBoaWRlIHRoZSBnZW5lcmF0aW5nIGNvZGUgY2VsbC4gWW91IGNhbiB0YWlsb3IgaXQgdG8geW91ciBvcHRpb25zLgoKIyNUYWJsZXMKClRhYmxlcyBjYW4gYmUgYSByZWFsIHBhaW4tcG9pbnQgd2hlbiBkb2luZyBtYW51c2NyaXB0cywgYnV0IHRoZXNlIGNhbiBiZSBhdXRvbWF0ZWQgaW4gUiBOb3RlYm9va3MsIHJlbmRlcmVkIHJpZ2h0IGludG8gdGV4dCwgYW5kIHNvbWUgbG9vayBwcmV0dHkgZ29vZC4gSGVyZSdzIHdoYXQgYGtuaXRyYCB3aWxsIGdpdmUgeW91IChpdCB3b24ndCBsb29rIHJpZ2h0IHVudGlsIGl0J3MgcmVuZGVyZWQpOgpgYGB7ciByZXN1bHRzPSdhc2lzJ30Ka25pdHI6OmthYmxlKG1lYW5wZXRhbHMpCmBgYAoKVGhhdCBsb29rcyBhbHJpZ2h0IQoKVGhlcmUncyBhbHNvIGB4dGFibGUsYCB3aGljaCB3aWxsIG1ha2UgaXQgZWFzaWVyIHRvIHNldCB0aGUgYXBwZWFyYW5jZSBvZiB0aGUgdGFibGUgdGhyb3VnaCBIVE1MIGF0dHJpYnV0ZXMuIFRoaXMgd29uJ3Qgc2hvdyB1cCB1bnRpbCBpdCdzIHJlbmRlcmVkLCB0aG91Z2guCmBgYHtyIHJlc3VsdHM9J2FzaXMnfQpwcmludCh4dGFibGU6Onh0YWJsZShtZWFucGV0YWxzKSwgdHlwZT0naHRtbCcsIGh0bWwudGFibGUuYXR0cmlidXRlcz0nYm9yZGVyPTAgIHdpZHRoPTI1MCcpCmBgYAoKRmluYWxseSwgaGVyZSdzIGEgdGFibGUgZnJvbiB0aGUgYHN0YXJnYXplcmAgcGFja2FnZS4gQWxzbyBsb3RzIG9mIGF0dHJpYnV0ZXMgd2UgY2FuIHNldCBoZXJlLiBJdCdzIGRlc2lnbmVkIG1vc3RseSBmb3IgcHJldHR5IGZvcm1hdHRpbmcgb2YgcmVncmVzc2lvbiBtb2RlbCByZXN1bHRzIGFuZCBzdW1tYXJ5IHN0YXRzLCBidXQgd2UgY2FuIGdldCBpdCB0byBkbyBkaXJlY3Qgb3V0cHV0IGluc3RlYWQuCmBgYHtyIHJlc3VsdHM9J2FzaXMnfQpzdGFyZ2F6ZXI6OnN0YXJnYXplcihhcy5kYXRhLmZyYW1lKG1lYW5wZXRhbHMpLCB0eXBlPSdodG1sJywgc3VtbWFyeT1GKQpgYGAKCklmIG5vbmUgb2YgdGhlIGZvcm1hdHRpbmcgaXMgcXVpdGUgdG8geW91ciBsaWtpbmcsIG9yIHlvdSBkb24ndCBoYXZlIGVhc2lseSBhdmFpbGFibGUgb3B0aW9ucyB0byBzZXQsIHlvdSBjYW4gdHdlYWsgdGhlIGFwcGVhcmFuY2Ugd2l0aCB5b3VyIFtvd24gQ1NTXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tL2h0bWxfZG9jdW1lbnRfZm9ybWF0Lmh0bWwjY3VzdG9tX2NzcykuCgpJZiBub25lIG9mIHRoaXMgaXMgc2F0aXNmeWluZywgb3IgaXQncyBtb3JlIGluZm9ybWFsLCB5b3UgY2FuIGFsd2F5cyBqdXN0IHByaW50IHRoZSBkYXRhZnJhbWUuCmBgYHtyfQoobWVhbnBldGFscykKYGBgCgpJIGRvbid0IGtub3cgdGhhdCB0aGlzIG1ha2VzIHRhYmxlcyBhbnkgbGVzcyBwYWlubGVzcywgYnV0IGF0IGxlYXN0IG5vdyB0aGVyZSdzIG1vcmUgdGhhbiBvbmUgb3B0aW9uIGZvciB0aGUgcGFpbi4KCiNGb3JtYXR0aW5nCgpJZiB5b3UncmUgd3JpdGluZyB1cCBhIHJlcG9ydCBvciBtYW51c2NyaXB0LCB5b3UgYWxzbyBuZWVkIHlvdXIgdGV4dCB0byBsb29rIG5pY2UsIG5vdCBqdXN0IHlvdXIgZGF0YS4gVGhpcyBpcyB3aGVyZSBrbm93aW5nIGEgbGl0dGxlIGJpdCBvZiBNYXJrZG93biBjb21lcyBpbiBoYW5keS4KCiMjTWFya2Rvd24KSnVzdCB0eXBlIHRvIGdldCBwcmV0dHkgcGxhaW50ZXh0LiBUbyBxdW90ZSBgdmVyYmF0aW0gY29kZWAgd2l0aG91dCBydW5uaW5nIGFueXRoaW5nLCB3cmFwIGl0IGluIGJhY2t0aWNrcyhcYCkuIFRoaXMgaXMgZGlzdGluY3QgZnJvbSBpbmxpbmUgY29kZSwgd2hpY2ggaXMgcHJlZmFjZWQgd2l0aCBgcmAgd2l0aGluIHRoZSB0aWNrcy4gSSdsbCBkbyB0aGlzIHRocm91Z2hvdXQgdG8gZGVtb25zdHJhdGUgaG93IHRvIGNvbnN0cnVjdCB0aGUgZWZmZWN0cyB5b3Ugc2VlLgoKVG8gZGlzcGxheSBhIHNwZWNpYWwgY2hhcmFjdGVyLCBsaWtlIFxfdW5kZXJzY29yZXNcXyBvciBhc3Rlcmlza3MgXCosIGVzY2FwZSB0aGVtIHdpdGggYSBiYWNrc2xhc2ggKFxcKS4KClRvIGFkZCBhIHNpbmdsZSBsaW5lYnJlYWsgd2l0aG91dCBhIGJsYW5rIGxpbmUsIGVuZCBhIGxpbmUgd2l0aCB0d28gc3BhY2VzLmAuLmAgIApUYS1kYSEKCmAqaXRhbGljcypgOiAqaXRhbGljcyogIApgKipib2xkKipgOiAqKmJvbGQqKiAgCmAqKl9ib3RoXyoqYDogKipfYm90aF8qKiAgCmB+fnN0cmlrZXRocm91Z2h+fmA6IH5+c3RyaWtldGhyb3VnaH5+ICAKYHN1YnNjcmlwdH4xfmA6IHN1YnNjcmlwdH4xfiAgCmBzdXBlcnNjcmlwdF4yXmA6IHN1cGVyc2NyaXB0XjJeICAKCllvdSBjYW4gZG8gYnVsbGV0ZWQgbGlzdHM6IAoKYCogc3RhcnQgd2l0aCBhbiBhc3RlcmlzaywgcGx1cywgb3IgbWludXMgYCAKYCAgICArIHRoZW4gaW5kZW50IDQgc3BhY2VzYApgICAgICAgICAtIHRoZW4gaW5kZW50IGFnYWluIGAKYCogdGhlbiBtb3JlIHN0dWZmYAoKKiBzdGFydCB3aXRoIGFuIGFzdGVyaXNrLCBwbHVzLCBvciBtaW51cyAgCiAgICArIHRoZW4gaW5kZW50IDQgc3BhY2VzCiAgICAgICAgLSB0aGVuIGluZGVudCBhZ2FpbiAKKiB0aGVuIG1vcmUgc3R1ZmYKCkFuZCBvcmRlcmVkIG9uZXM6CgpgMS4gQmlnIHRoaW5nYApgICAgIGkpIHNtYWxsIHRoaW5nIFwrIGluZGVudGAKYCAgICAgIEEuIHN1Yi1zbWFsbCB0aGluZ2AKYDIuIEFub3RoZXIgYmlnIHRoaW5nYAoKMS4gQmlnIHRoaW5nCiAgICBpKSBzbWFsbCB0aGluZyBcKyBpbmRlbnQgIAogICAgICBBLiBzdWItc21hbGwgdGhpbmcKMi4gQW5vdGhlciBiaWcgdGhpbmcKICAgICAgCk9oLCBhbmQgZm9vdG5vdGVzLi4uIGBbXjFdYCBbXjFdCgpbXjFdOiBgW14xXTpgIEFyZSBwcmV0dHkgZWFzeS4KCmAjSGVhZGVyIDFgCgojSGVhZGVyIDEKCmAjI0hlYWRlciAyYAoKIyNIZWFkZXIgMgoKYCMjI0hlYWRlciAzYCAgCgojIyNIZWFkZXIgMwoKQWRkIGhvcml6b250YWwgbGluZXMgd2l0aCBhdCBsZWFzdCB0aHJlZSBoeXBoZW5zLCBhc3Rlcmlza3MsIG9yIHVuZGVyc2NvcmVzOgoKYCoqKmAKCioqKgoKVGFibGVzIGFyZSBhIGxpdHRsZSBzdHJhbmdlIGluIHRoZSByYXcsIGJ1dCBsb29rIG5pY2Ugb25jZSByZW5kZXJlZC4KCmBgYAp8IFJpZ2h0LWFsaWduZWQgfCBMZWZ0LWFsaWduZWQgfCBDZW50ZXJlZCB8IERlZmF1bHQgfAp8LTp8Oi18Oi06fC18CnwxfDF8MXwxfAp8MTJ8MTJ8MTJ8MTJ8IAp8KjEqfF8yX3x+fjN+fnw0XjJefApgYGAKCnwgUmlnaHQtYWxpZ25lZCB8IExlZnQtYWxpZ25lZCB8IENlbnRlcmVkIHwgRGVmYXVsdCB8CnwtOnw6LXw6LTp8LXwKfDF8MXwxfDF8CnwxMnwxMnwxMnwxMnwKfCoxKnxfMl98fn4zfn58NF4yXnwKCkltYWdlcyBhcmUgZWFzeSwgdG9vLiAgCmAhW1RoZSBhZG9yYWJpbGlzIG9jdG9wdXMsIGZvciB5b3VyIHZpZXdpbmcgcGxlYXN1cmVdKGh0dHA6Ly9ibG9ncy5kaXNjb3Zlcm1hZ2F6aW5lLmNvbS9kLWJyaWVmL2ZpbGVzLzIwMTUvMDYvb2N0b3B1cy5qcGcpYAoKIVtUaGUgYWRvcmFiaWxpcyBvY3RvcHVzLCBmb3IgeW91ciB2aWV3aW5nIHBsZWFzdXJlXShodHRwOi8vYmxvZ3MuZGlzY292ZXJtYWdhemluZS5jb20vZC1icmllZi9maWxlcy8yMDE1LzA2L29jdG9wdXMuanBnKQoKCiMjTGF0ZXggYW5kIEVxdWF0aW9ucwpNYXRoIGZvcm1hdHRpbmcgY2FuIGJlIGRvbmUgd2l0aCB0aGUgc2FtZSBub3RhdGlvbiB1c2VkIGluIExhdGV4LgoKVG8gZG8gaW5saW5lIGVxdWF0aW9ucyBvciBtYXRoZW1hdGljYWwgbm90YXRpb24sIHVzZSBzaW5nbGUgZG9sbGFyIHNpZ25zOiBgJGYoeCkgPSBcZnJhY3sxfXt4fSRgLiAkZih4KSA9IFxmcmFjezF9e3h9JAoKVG8gZG8gYW4gZXF1YXRpb24gYmxvY2ssIHVzZSBkb3VibGUgZG9sbGFyIHNpZ25zOiBgJCQtYiBccG0gXHNxcnR7XGZyYWN7Yl4yIC0gNGFjfXsyYX19JCRgICAKJCQtYiBccG0gXHNxcnR7XGZyYWN7Yl4yIC0gNGFjfXsyYX19JCQKCldlIGNhbiBkbyBHcmVlayBsZXR0ZXJzOiBgJFxTaWdtYSBcOyBcYWxwaGEgXDsgXGdhbW1hJGA6ICRcU2lnbWEgXDsgXGFscGhhIFw7IFxnYW1tYSQKClN1bXMsIHByb2R1Y3RzLCBhbmQgaW50ZWdyYWxzIGNhbiBiZSBpbmxpbmUgd2l0aCBpbm5lciBsaW1pdHM6IGAkXHN1bV97aT0xfV57XGluZnR5fXhfaSRgICRcc3VtX3tpPTF9XntcaW5mdHl9eF9pJCAgCk9yIGlubGluZSB3aXRoIG91dGVyIGxpbWl0czogYCRccHJvZFxsaW1pdHNfe2k9MX1ee1xpbmZ0eX1cZnJhY3sxfXt4X2l9JGAgJFxwcm9kXGxpbWl0c197aT0xfV57XGluZnR5fVxmcmFjezF9e3hfaX0kCgpPciBibG9jazogYCQkXGludF97YX1ee2J9eF4yZHgkJGAgJCRcaW50X3thfV57Yn14XjJkeCQkCgpBbmQgbWF0cmljZXMgYXJlIGxvdmVseSwgdG9vLiBXaXRoIHBhcmVuczogIApgYGAKJFxiZWdpbntwbWF0cml4fSAgCjEgJiAyICYgMyBcXCAKNCAmIDUgJiA2ClxlbmR7cG1hdHJpeH0kCmBgYAokXGJlZ2lue3BtYXRyaXh9CjEgJiAyICYgMyBcXAo0ICYgNSAmIDYKXGVuZHtwbWF0cml4fSQgCgpCcmFja2V0czogIApgYGAKJFxiZWdpbntibWF0cml4fSAgCjEgJiAyIFxcIAo0ICYgNSAgIApcZW5ke2JtYXRyaXh9JCAgCmBgYAokXGJlZ2lue2JtYXRyaXh9CjEgJiAyIFxcCjQgJiA1IApcZW5ke2JtYXRyaXh9JCAgCgpPciBpdHR5LWJpdHR5KGdvb2QgZm9yIGlubGluZSEpOiAgCmBgYAokXGxlZnRbXGJlZ2lue3NtYWxsbWF0cml4fSAgCjEgJiAyIFxcCjQgJiA1ICAgClxlbmR7c21hbGxtYXRyaXh9XHJpZ2h0XSQgIApgYGAKJFxsZWZ0W1xiZWdpbntzbWFsbG1hdHJpeH0KMSAmIDIgXFwKNCAmIDUgClxlbmR7c21hbGxtYXRyaXh9XHJpZ2h0XSQK