In this worksheet, we’ll be exploring various plot types (i.e., geometric objects), only using the x and y aesthetics (and group).

  1. To get started, load the tidyverse and gapminder R packages.

Scatterplot

Let’s look at a scatterplot of gdpPercap vs. lifeExp.

  1. Fill out the grammar components below. Again, bold must be specified to make a ggplot2 plot.
    • We’ll ignore “coordinate system” and “facetting” after this.
Grammar Component Specification
data gapminder
aesthetic mapping
geometric object
scale
statistical transform
coordinate system
facetting
  1. Populate the data and aesthetic mapping in ggplot. What is returned? What’s missing?

  2. Add the missing component as a layer.

Notice the “metaprogramming” again!

  1. You must remember to put the aesthetic mappings in the aes function! What happens if you forget?

  2. Put the x-axis on a log scale, first by transforming the x variable.
    • Note: ggplot2 does some data wrangling and computations itself! We don’t always have to modify the data frame.
  3. Try again, this time by changing the scale (this way is better).

  4. The aesthetic mappings can be specified on the geom layer if you want, instead of the main ggplot call. Give it a try:

  5. Optional: git stage and commit

Uses of a scatterplot:

Histograms, and Kernel Density Plots

Let’s build a histogram of life expectancy.

  1. Fill out the grammar components below. Again, bold must be specified to make a ggplot2 plot.
Grammar Component Specification
data gapminder
aesthetic mapping
geometric object
scale
statistical transform
  1. Build the histogram of life expectancy.

  2. Change the number of bins to 50.

  3. Instead of a histogram, let’s create a kernel density plot.

  4. Optional: git stage and commit

Uses of a histogram: Explore the distribution of a single numeric variable.

Box plots, and violin plots

Let’s make box plots of population for each continent. Note: y-axis is much better on a log scale!

  1. Fill out the grammar components below. Again, bold must be specified to make a ggplot2 plot.
Grammar Component Specification
data gapminder
aesthetic mapping
geometric object
scale
statistical transform
  1. Initiate the ggplot call, with the log y scale, and store it in the variable a. Print out a.

  2. Add the boxplot geom to a.

  3. A violin plot is a kernel density on its side, made symmetric. Add that geom to a.
    • What’s better here, boxplots or violin plots? Why?
  4. Optional: git stage and commit

Use of boxplot: Visualize 1-dimensional distributions (of a single numeric variable).

Jitter plots

Let’s work up to the concept of a jitter plot. As above, let’s explore the population for each continent, but using points (again, with the y-axis on a log scale).

Let’s hold off on identifying the grammar.

  1. Initiate the ggplot call to make a scatterplot of continent vs pop; initiate the log y scale. Store the call in the variable b.

  2. Add the point geom to b. Why is this an ineffective plot?

  3. A solution is to jitter the points. Add the jitter geom. Re-run the command a few times – does the plot change? Why?

  4. How does the grammar differ from a box plot or violin plot?
    • ANSWER:
  5. We can add multiple geom layers to our plot. Put a jitterplot overtop of the violin plot, starting with our base b. Try vice-versa.

  6. Optional: git stage and commit

Uses of jitterplot: Visualize 1-dimensional distributions, AND get a sense of the sample size.

Time/Line Plots

Let’s make some time/line plot, starting with Canada’s life expectancy over time.

  1. Fill out the grammar components below. Again, bold must be specified to make a ggplot2 plot.
Grammar Component Specification
data gapminder
aesthetic mapping
geometric object
scale
statistical transform
  1. In one readable call, write code that:
    1. Filters the data to Canada only
    2. Pipes the filtered data into ggplot
    3. Makes the time plot of lifeExp over time
    4. Also displays the points
  2. Attempt to overlay line plots for all countries. That is, repeat the above code, but don’t filter. What’s wrong here?

  3. Use the group aesthetic to fix the problem.

  4. Optional: git stage and commit

Uses of time/line plots: Visualize trends of a numeric variable over time.

Path plots

Let’s see how Rwanda’s life expectancy and GDP per capita have evolved over time, using a path plot.

  1. Make a scatterplot. Store it in the variable c.

  2. We want to connect the dots from earliest point to latest. What happens if we add the “line” geom to c?

  3. Add the appropriate geom to c. In that geom, specify a property of the geom: arrow=arrow().

  4. Optional: git stage and commit

Uses of path plots: The four “corners” of the plot usually indicate different qualities. This plot allows you to see how Rwanda (or some entity) evolves over these qualities.

Bar plots

How many countries are in each continent? Use the year 2007.

  1. Fill out the grammar components below. Again, bold must be specified to make a ggplot2 plot.
Grammar Component Specification
data gapminder
aesthetic mapping
geometric object
scale
statistical transform
  1. After filtering the gapminder data to 2007, make a bar chart of the number of countries in each continent. Store everything except the geom in the variable d.

  2. Notice the y-axis. Oddly, ggplot2 doesn’t make it obvious how to change to proportion. Try adding a y aesthetic: y=..count../sum(..count..).

  3. Optional: git stage, commit, and push!

Uses of bar plots: Get a sense of relative quantities of categories, or see the probability mass function of a categorical random variable.

LS0tCnRpdGxlOiAiY20wMDYgRXhlcmNpc2VzOiBFeHBsb3JpbmcgR2VvbWV0cmljIE9iamVjdHMiCm91dHB1dDogaHRtbF9ub3RlYm9vawplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCkluIHRoaXMgd29ya3NoZWV0LCB3ZSdsbCBiZSBleHBsb3JpbmcgdmFyaW91cyBwbG90IHR5cGVzIChpLmUuLCBnZW9tZXRyaWMgb2JqZWN0cyksIG9ubHkgdXNpbmcgdGhlIGB4YCBhbmQgYHlgIGFlc3RoZXRpY3MgKGFuZCBgZ3JvdXBgKS4KCjEuIFRvIGdldCBzdGFydGVkLCBsb2FkIHRoZSBgdGlkeXZlcnNlYCBhbmQgYGdhcG1pbmRlcmAgUiBwYWNrYWdlcy4gCgoKIyMgU2NhdHRlcnBsb3QKCkxldCdzIGxvb2sgYXQgYSBfc2NhdHRlcnBsb3RfIG9mIGBnZHBQZXJjYXBgIHZzLiBgbGlmZUV4cGAuIAoKMS4gRmlsbCBvdXQgdGhlIGdyYW1tYXIgY29tcG9uZW50cyBiZWxvdy4gQWdhaW4sIGJvbGQgX211c3RfIGJlIHNwZWNpZmllZCB0byBtYWtlIGEgYGdncGxvdDJgIHBsb3QuCiAgICAtIFdlJ2xsIGlnbm9yZSAiY29vcmRpbmF0ZSBzeXN0ZW0iIGFuZCAiZmFjZXR0aW5nIiBhZnRlciB0aGlzLgoKfCBHcmFtbWFyIENvbXBvbmVudCAgICAgfCBTcGVjaWZpY2F0aW9uIHwKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLXwKfCBfX2RhdGFfXyAgICAgICAgICAgICAgfCBgZ2FwbWluZGVyYCB8CnwgX19hZXN0aGV0aWMgbWFwcGluZ19fIHwgIHwKfCBfX2dlb21ldHJpYyBvYmplY3RfXyAgfCAgfAp8IHNjYWxlICAgICAgICAgICAgICAgICB8ICB8Cnwgc3RhdGlzdGljYWwgdHJhbnNmb3JtIHwgIHwKfCBjb29yZGluYXRlIHN5c3RlbSAgICAgfCAgfAp8IGZhY2V0dGluZyAgICAgICAgICAgICB8ICB8CgoyLiBQb3B1bGF0ZSB0aGUgZGF0YSBhbmQgYWVzdGhldGljIG1hcHBpbmcgaW4gYGdncGxvdGAuIFdoYXQgaXMgcmV0dXJuZWQ/IFdoYXQncyBtaXNzaW5nPwoKCgozLiBBZGQgdGhlIG1pc3NpbmcgY29tcG9uZW50IGFzIGEgX2xheWVyXy4KCgoKTm90aWNlIHRoZSAibWV0YXByb2dyYW1taW5nIiBhZ2FpbiEKCjQuIFlvdSBfbXVzdF8gcmVtZW1iZXIgdG8gcHV0IHRoZSBhZXN0aGV0aWMgbWFwcGluZ3MgaW4gdGhlIGBhZXNgIGZ1bmN0aW9uISBXaGF0IGhhcHBlbnMgaWYgeW91IGZvcmdldD8KCgoKNS4gUHV0IHRoZSB4LWF4aXMgb24gYSBsb2cgc2NhbGUsIGZpcnN0IGJ5IHRyYW5zZm9ybWluZyB0aGUgeCB2YXJpYWJsZS4gCiAgICAtIE5vdGU6IGBnZ3Bsb3QyYCBkb2VzIHNvbWUgZGF0YSB3cmFuZ2xpbmcgYW5kIGNvbXB1dGF0aW9ucyBpdHNlbGYhIFdlIGRvbid0IGFsd2F5cyBoYXZlIHRvIG1vZGlmeSB0aGUgZGF0YSBmcmFtZS4KCgoKNi4gVHJ5IGFnYWluLCB0aGlzIHRpbWUgYnkgY2hhbmdpbmcgdGhlIF9zY2FsZV8gKHRoaXMgd2F5IGlzIGJldHRlcikuCgoKCjcuIFRoZSBhZXN0aGV0aWMgbWFwcGluZ3MgY2FuIGJlIHNwZWNpZmllZCBvbiB0aGUgZ2VvbSBsYXllciBpZiB5b3Ugd2FudCwgaW5zdGVhZCBvZiB0aGUgbWFpbiBgZ2dwbG90YCBjYWxsLiBHaXZlIGl0IGEgdHJ5OgoKCjguIE9wdGlvbmFsOiBnaXQgc3RhZ2UgYW5kIGNvbW1pdAoKX19Vc2VzIG9mIGEgc2NhdHRlcnBsb3RfXzogCgotIFZpc3VhbGl6ZSAyLWRpbWVuc2lvbmFsIGRpc3RyaWJ1dGlvbnM7IGRlcGVuZGVuY2UuCi0gMiBudW1lcmljIHZhcmlhYmxlcwoKIyMgSGlzdG9ncmFtcywgYW5kIEtlcm5lbCBEZW5zaXR5IFBsb3RzCgpMZXQncyBidWlsZCBhIGhpc3RvZ3JhbSBvZiBsaWZlIGV4cGVjdGFuY3kuCgoxLiBGaWxsIG91dCB0aGUgZ3JhbW1hciBjb21wb25lbnRzIGJlbG93LiBBZ2FpbiwgYm9sZCBfbXVzdF8gYmUgc3BlY2lmaWVkIHRvIG1ha2UgYSBgZ2dwbG90MmAgcGxvdC4KCnwgR3JhbW1hciBDb21wb25lbnQgICAgIHwgU3BlY2lmaWNhdGlvbiB8CnwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS18CnwgX19kYXRhX18gICAgICAgICAgICAgIHwgYGdhcG1pbmRlcmAgfAp8IF9fYWVzdGhldGljIG1hcHBpbmdfXyB8ICB8CnwgX19nZW9tZXRyaWMgb2JqZWN0X18gIHwgIHwKfCBzY2FsZSAgICAgICAgICAgICAgICAgfCAgfAp8IHN0YXRpc3RpY2FsIHRyYW5zZm9ybSB8ICB8CgoyLiBCdWlsZCB0aGUgaGlzdG9ncmFtIG9mIGxpZmUgZXhwZWN0YW5jeS4KCgoKMy4gQ2hhbmdlIHRoZSBudW1iZXIgb2YgYmlucyB0byA1MC4KCgoKNC4gSW5zdGVhZCBvZiBhIGhpc3RvZ3JhbSwgbGV0J3MgY3JlYXRlIGEga2VybmVsIGRlbnNpdHkgcGxvdC4KCgoKNS4gT3B0aW9uYWw6IGdpdCBzdGFnZSBhbmQgY29tbWl0CgpfX1VzZXMgb2YgYSBoaXN0b2dyYW1fXzogRXhwbG9yZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGEgc2luZ2xlIG51bWVyaWMgdmFyaWFibGUuCgoKIyMgQm94IHBsb3RzLCBhbmQgdmlvbGluIHBsb3RzCgpMZXQncyBtYWtlIF9ib3ggcGxvdHNfIG9mIHBvcHVsYXRpb24gZm9yIGVhY2ggY29udGluZW50LiBOb3RlOiB5LWF4aXMgaXMgbXVjaCBiZXR0ZXIgb24gYSBsb2cgc2NhbGUhCgoxLiBGaWxsIG91dCB0aGUgZ3JhbW1hciBjb21wb25lbnRzIGJlbG93LiBBZ2FpbiwgYm9sZCBfbXVzdF8gYmUgc3BlY2lmaWVkIHRvIG1ha2UgYSBgZ2dwbG90MmAgcGxvdC4KCnwgR3JhbW1hciBDb21wb25lbnQgICAgIHwgU3BlY2lmaWNhdGlvbiB8CnwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS18CnwgX19kYXRhX18gICAgICAgICAgICAgIHwgYGdhcG1pbmRlcmAgfAp8IF9fYWVzdGhldGljIG1hcHBpbmdfXyB8ICB8CnwgX19nZW9tZXRyaWMgb2JqZWN0X18gIHwgIHwKfCBzY2FsZSAgICAgICAgICAgICAgICAgfCAgfAp8IHN0YXRpc3RpY2FsIHRyYW5zZm9ybSB8ICB8CgoyLiBJbml0aWF0ZSB0aGUgYGdncGxvdGAgY2FsbCwgd2l0aCB0aGUgbG9nIHkgc2NhbGUsIGFuZCBzdG9yZSBpdCBpbiB0aGUgdmFyaWFibGUgYGFgLiBQcmludCBvdXQgYGFgLgoKCgozLiBBZGQgdGhlIGJveHBsb3QgZ2VvbSB0byBgYWAuCgoKCjQuIEEgdmlvbGluIHBsb3QgaXMgYSBrZXJuZWwgZGVuc2l0eSBvbiBpdHMgc2lkZSwgbWFkZSBzeW1tZXRyaWMuIEFkZCB0aGF0IGdlb20gdG8gYGFgLgogICAgLSBXaGF0J3MgYmV0dGVyIGhlcmUsIGJveHBsb3RzIG9yIHZpb2xpbiBwbG90cz8gV2h5PwoKNS4gT3B0aW9uYWw6IGdpdCBzdGFnZSBhbmQgY29tbWl0CgpfX1VzZSBvZiBib3hwbG90X186IFZpc3VhbGl6ZSAxLWRpbWVuc2lvbmFsIGRpc3RyaWJ1dGlvbnMgKG9mIGEgc2luZ2xlIG51bWVyaWMgdmFyaWFibGUpLgoKIyMgSml0dGVyIHBsb3RzCgpMZXQncyB3b3JrIHVwIHRvIHRoZSBjb25jZXB0IG9mIGEgX2ppdHRlciBwbG90Xy4gQXMgYWJvdmUsIGxldCdzIGV4cGxvcmUgdGhlIHBvcHVsYXRpb24gZm9yIGVhY2ggY29udGluZW50LCBidXQgdXNpbmcgcG9pbnRzIChhZ2Fpbiwgd2l0aCB0aGUgeS1heGlzIG9uIGEgbG9nIHNjYWxlKS4KCkxldCdzIGhvbGQgb2ZmIG9uIGlkZW50aWZ5aW5nIHRoZSBncmFtbWFyLiAKCjEuIEluaXRpYXRlIHRoZSBgZ2dwbG90YCBjYWxsIHRvIG1ha2UgYSBzY2F0dGVycGxvdCBvZiBgY29udGluZW50YCB2cyBgcG9wYDsgaW5pdGlhdGUgdGhlIGxvZyB5IHNjYWxlLiBTdG9yZSB0aGUgY2FsbCBpbiB0aGUgdmFyaWFibGUgYGJgLgoKCgoyLiBBZGQgdGhlIHBvaW50IGdlb20gdG8gYGJgLiBXaHkgaXMgdGhpcyBhbiBpbmVmZmVjdGl2ZSBwbG90PwoKCgozLiBBIHNvbHV0aW9uIGlzIHRvIGppdHRlciB0aGUgcG9pbnRzLiBBZGQgdGhlIGppdHRlciBnZW9tLiBSZS1ydW4gdGhlIGNvbW1hbmQgYSBmZXcgdGltZXMgLS0gZG9lcyB0aGUgcGxvdCBjaGFuZ2U/IFdoeT8KCgoKNC4gSG93IGRvZXMgdGhlIGdyYW1tYXIgZGlmZmVyIGZyb20gYSBib3ggcGxvdCBvciB2aW9saW4gcGxvdD8KICAgIC0gQU5TV0VSOiAKCjUuIFdlIGNhbiBhZGQgbXVsdGlwbGUgZ2VvbSBfbGF5ZXJzXyB0byBvdXIgcGxvdC4gUHV0IGEgaml0dGVycGxvdCBvdmVydG9wIG9mIHRoZSB2aW9saW4gcGxvdCwgc3RhcnRpbmcgd2l0aCBvdXIgYmFzZSBgYmAuIFRyeSB2aWNlLXZlcnNhLiAKCgoKNi4gT3B0aW9uYWw6IGdpdCBzdGFnZSBhbmQgY29tbWl0CgpfX1VzZXMgb2Ygaml0dGVycGxvdF9fOiBWaXN1YWxpemUgMS1kaW1lbnNpb25hbCBkaXN0cmlidXRpb25zLCBBTkQgZ2V0IGEgc2Vuc2Ugb2YgdGhlIHNhbXBsZSBzaXplLgoKIyMgVGltZS9MaW5lIFBsb3RzCgpMZXQncyBtYWtlIHNvbWUgdGltZS9saW5lIHBsb3QsIHN0YXJ0aW5nIHdpdGggQ2FuYWRhJ3MgbGlmZSBleHBlY3RhbmN5IG92ZXIgdGltZS4KCjEuIEZpbGwgb3V0IHRoZSBncmFtbWFyIGNvbXBvbmVudHMgYmVsb3cuIEFnYWluLCBib2xkIF9tdXN0XyBiZSBzcGVjaWZpZWQgdG8gbWFrZSBhIGBnZ3Bsb3QyYCBwbG90LgoKfCBHcmFtbWFyIENvbXBvbmVudCAgICAgfCBTcGVjaWZpY2F0aW9uIHwKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLXwKfCBfX2RhdGFfXyAgICAgICAgICAgICAgfCBgZ2FwbWluZGVyYCB8CnwgX19hZXN0aGV0aWMgbWFwcGluZ19fIHwgIHwKfCBfX2dlb21ldHJpYyBvYmplY3RfXyAgfCAgfAp8IHNjYWxlICAgICAgICAgICAgICAgICB8ICB8Cnwgc3RhdGlzdGljYWwgdHJhbnNmb3JtIHwgIHwKCjIuIEluIG9uZSByZWFkYWJsZSBjYWxsLCB3cml0ZSBjb2RlIHRoYXQ6CiAgICAxLiBGaWx0ZXJzIHRoZSBkYXRhIHRvIENhbmFkYSBvbmx5CiAgICAyLiBQaXBlcyB0aGUgZmlsdGVyZWQgZGF0YSBpbnRvIGBnZ3Bsb3RgCiAgICAzLiBNYWtlcyB0aGUgdGltZSBwbG90IG9mIGBsaWZlRXhwYCBvdmVyIHRpbWUKICAgIDQuIEFsc28gZGlzcGxheXMgdGhlIHBvaW50cwoKCgozLiBBdHRlbXB0IHRvIG92ZXJsYXkgbGluZSBwbG90cyBmb3IgYWxsIGNvdW50cmllcy4gVGhhdCBpcywgcmVwZWF0IHRoZSBhYm92ZSBjb2RlLCBidXQgZG9uJ3QgZmlsdGVyLiBXaGF0J3Mgd3JvbmcgaGVyZT8KCgoKNC4gVXNlIHRoZSBgZ3JvdXBgIGFlc3RoZXRpYyB0byBmaXggdGhlIHByb2JsZW0uCgoKCjUuIE9wdGlvbmFsOiBnaXQgc3RhZ2UgYW5kIGNvbW1pdAoKX19Vc2VzIG9mIHRpbWUvbGluZSBwbG90c19fOiBWaXN1YWxpemUgdHJlbmRzIG9mIGEgbnVtZXJpYyB2YXJpYWJsZSBvdmVyIHRpbWUuCgojIyBQYXRoIHBsb3RzCgpMZXQncyBzZWUgaG93IFJ3YW5kYSdzIGxpZmUgZXhwZWN0YW5jeSBhbmQgR0RQIHBlciBjYXBpdGEgaGF2ZSBldm9sdmVkIG92ZXIgdGltZSwgdXNpbmcgYSBwYXRoIHBsb3QuCgoxLiBNYWtlIGEgc2NhdHRlcnBsb3QuIFN0b3JlIGl0IGluIHRoZSB2YXJpYWJsZSBgY2AuIAoKCgoyLiBXZSB3YW50IHRvIGNvbm5lY3QgdGhlIGRvdHMgZnJvbSBlYXJsaWVzdCBwb2ludCB0byBsYXRlc3QuIFdoYXQgaGFwcGVucyBpZiB3ZSBhZGQgdGhlICJsaW5lIiBnZW9tIHRvIGBjYD8KCgoKMy4gQWRkIHRoZSBhcHByb3ByaWF0ZSBnZW9tIHRvIGBjYC4gSW4gdGhhdCBnZW9tLCBzcGVjaWZ5IGEgcHJvcGVydHkgb2YgdGhlIGdlb206IGBhcnJvdz1hcnJvdygpYC4gCgoKNC4gT3B0aW9uYWw6IGdpdCBzdGFnZSBhbmQgY29tbWl0CgpfX1VzZXMgb2YgcGF0aCBwbG90c19fOiBUaGUgZm91ciAiY29ybmVycyIgb2YgdGhlIHBsb3QgdXN1YWxseSBpbmRpY2F0ZSBkaWZmZXJlbnQgcXVhbGl0aWVzLiBUaGlzIHBsb3QgYWxsb3dzIHlvdSB0byBzZWUgaG93IFJ3YW5kYSAob3Igc29tZSBlbnRpdHkpIGV2b2x2ZXMgb3ZlciB0aGVzZSBxdWFsaXRpZXMuCgojIyBCYXIgcGxvdHMKCkhvdyBtYW55IGNvdW50cmllcyBhcmUgaW4gZWFjaCBjb250aW5lbnQ/IFVzZSB0aGUgeWVhciAyMDA3LgoKMS4gRmlsbCBvdXQgdGhlIGdyYW1tYXIgY29tcG9uZW50cyBiZWxvdy4gQWdhaW4sIGJvbGQgX211c3RfIGJlIHNwZWNpZmllZCB0byBtYWtlIGEgYGdncGxvdDJgIHBsb3QuCgp8IEdyYW1tYXIgQ29tcG9uZW50ICAgICB8IFNwZWNpZmljYXRpb24gfAp8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tfAp8IF9fZGF0YV9fICAgICAgICAgICAgICB8IGBnYXBtaW5kZXJgIHwKfCBfX2Flc3RoZXRpYyBtYXBwaW5nX18gfCAgfAp8IF9fZ2VvbWV0cmljIG9iamVjdF9fICB8ICB8Cnwgc2NhbGUgICAgICAgICAgICAgICAgIHwgIHwKfCBzdGF0aXN0aWNhbCB0cmFuc2Zvcm0gfCAgfAoKMi4gQWZ0ZXIgZmlsdGVyaW5nIHRoZSBnYXBtaW5kZXIgZGF0YSB0byAyMDA3LCBtYWtlIGEgYmFyIGNoYXJ0IG9mIHRoZSBudW1iZXIgb2YgY291bnRyaWVzIGluIGVhY2ggY29udGluZW50LiBTdG9yZSBldmVyeXRoaW5nIGV4Y2VwdCB0aGUgZ2VvbSBpbiB0aGUgdmFyaWFibGUgYGRgLgoKCgozLiBOb3RpY2UgdGhlIHktYXhpcy4gT2RkbHksIGBnZ3Bsb3QyYCBkb2Vzbid0IG1ha2UgaXQgb2J2aW91cyBob3cgdG8gY2hhbmdlIHRvIHByb3BvcnRpb24uIFRyeSBhZGRpbmcgYSBgeWAgYWVzdGhldGljOiBgeT0uLmNvdW50Li4vc3VtKC4uY291bnQuLilgLgoKCgo0LiBPcHRpb25hbDogZ2l0IHN0YWdlLCBjb21taXQsIGFuZCBwdXNoIQoKX19Vc2VzIG9mIGJhciBwbG90c19fOiBHZXQgYSBzZW5zZSBvZiByZWxhdGl2ZSBxdWFudGl0aWVzIG9mIGNhdGVnb3JpZXMsIG9yIHNlZSB0aGUgcHJvYmFiaWxpdHkgbWFzcyBmdW5jdGlvbiBvZiBhIGNhdGVnb3JpY2FsIHJhbmRvbSB2YXJpYWJsZS4K