Overview

This is the first lab of Economic Demography (Econ/Demog C175). Our goals in this first lab are:

  1. To get everyone started programming and doing their assignments with R, RStudio, and bCourses.

  2. To use the exponential model to learn about world population history.

This document is written in the “R markdown” format and should be read and edited within RStudio. The notebook interface allows you to execute and display R-code within a single window. You can edit this notebook directly and save it. We recommend you save it with a different name (e.g., “world_lab_1_newname.Rmd”) to avoid overwriting your edits.

Viewing note: the labs are formatted using hard line-endings. Try resizing viewing window if lines are overflowing.

Writing and executing R commands

In the RStudio Notebook, we mix executable R commands in with regular written text by creating a “code chunk.” To open a code chunk, we type ““{r}" to start. To close the code chunk we type "”” to end. Here are some examples:

To print a string of text:

print("Hello, world")

You can hit the green “play” icon to execute the chunk of code. Try modifying the chunk so it prints: “Hello, Berkeley”. (Note the [1] just means that it is the first element of the displayed object. You can ignore this.)

To add 2 + 2:

2+2

To assign the value 4 to a variable named “x”:

x <- 4
print(x)

The output of a chunk is only shown when you tell it to be. For example,

x <- 3
print(x)
y <- 4
show(y)
## note: we don't tell R to show us the value of "y"
z <- 5
print(z)

Try to modify the above code chunk so it also prints the value the variable “y”

Using R to calculate exponential population growth rates

## comments (within code chunks) begin with hashtags. They are ignored
## by R.

## We start by inputting world population sizes by hand, assigning
## them to variables named "N.1900" and "N.2000" by using the assignment
## operator: "<-"

N.1900 <- 1650 # estimated world population in 1900 (in millions)
N.2000 <- 6127 # same for 2000

## we can display the value of the variable called N.1900 (hit the
## "play" button)
print(N.2000)
## We now calculate growth rate from 1900 to 2000, using our formula
## for the slope of the logarithm of population.

## in R when we write log(), this command will give us the natural log, which uses base e

R.twentieth.century <- ( log(N.2000) - log(N.1900) ) / (2000 - 1900)
R.twentieth.century

You should get “[1] 0.0131193”, or about 1.3 percent.

We can check this answer

N.2000.check <- N.1900 * exp(100 * 0.0131193)
N.2000.check

Which is “6127”, the correct value for the world population in 2000.

Now let’s calculate the exponential growth rate for the fifty years from 1850 to 1900. You need to alter the code below to get the right answer.

N.1850 <- 1262 # these are millions
## Note: We don't need to re-enter N.1900, since variables are saved
## across chunks.

## Now modify the code below to give the right answer. (Hint: you need
## to rename the variables N.2000 and N.1900 and change the dates
## "2000" and "1900".)
R.1850.to.1900 <- ( log(N.1900) - log(N.1850) ) / (1900 - 1850)
print( R.1850.to.1900 )

You should get \(0.00536155\), about 0.5 percent. (Hint: If you’re still getting 0.0131193, it means you haven’t modified the code and have assigned the new variable R.1850.to.1900 with the answer for 1900 to 2000.)

(Note: class demo ends about here.)

The complete history of world population

First we’re going to read in data from a file that we’ve placed on the course lab website.

dat <- read.table("/data175/world_population_data.txt", header = T)
dat

Look at the data set, which has the form of a table with two labeled columns “pop” and “year”. We’re going to extract the contents into our two vectors year.vec and N.vec. (You don’t need to understand this yet. We’ll be learning about why this works in later labs.)

million <- 1000000
N.vec <- dat$pop / 1000 ## converts millions to billions
year.vec <- dat$year
names(N.vec) <- year.vec

Let’s look at both of these

year.vec
N.vec

Our first plot

plot(x = year.vec,
     y = N.vec)

Wow, looks like world population is exploding.

Let’s see what is happening in terms of proportional changes (by taking logs)

log.N.vec <- log(N.vec)
plot(x = year.vec, y = log.N.vec)

Wow, it looks like even the proportional rate of growth has increased.

You can now guess-timate the exponential population growth rate by eye-ing the “slope” of the log rate of population growth. The slope is equal to the calculated growth rate. For example, the 8000 year period from -8000 to 0 saw an increase of about 4 in log-population size. The slope is thus about 4/8000 = 0.0005. We can check this with our calculations below.

Calculating growth rates through history

Calculate a vector of exponential growth rate.

Here we will use the diff() function in R, which tells us the differences between elements in a vector.

For example,

x = c(4, 5, 7) ## this is a vector with three elements.
diff(x) # gives us the differences between elements

We’ll formulate this as the slope of the graph of log population sizes

rise.vec <- diff(log.N.vec) # these are the "rise", the vertical distances between points
run.vec <- diff(year.vec) # these are "run", the horizontal distances between points
slope.vec <- rise.vec / run.vec
R.vec <- slope.vec
R.vec

Let’s make a bit more readable by expressing the growth rates in percentage points, and rounding them

R.vec.in.percent <- 100 * round(R.vec, 4)
R.vec.in.percent

We see that growth rates increased for nearly 10,000 years, but have recently begun to decrease a bit.

Plotting the growth rates

Let’s try a plot:

end.year.each.period.vec <- names(R.vec.in.percent)
plot(x = end.year.each.period.vec,
     y = R.vec.in.percent,
     main = "Exponential Growth Rates of World Population through the Ages",
     type = "l")

It looks like population growth rates have begun to decline. To see a bit better, we can graph only the more recent years

plot(x = end.year.each.period.vec,
     y = R.vec.in.percent,
     xlim = c(1900, 2020),              # limit the x-axis to 1900 to 2020
     main = "Exponential Growth Rates of World Population, since 1900",
     type = "o")

Congratulations

You’ve finished all of the computing for the first lab!

Graded Questions

(See the syllabus for instructions on submitting your answers at https://courses.demog.berkeley.edu/goldstein175/)

  1. [Multiple choice] Which of the following descriptions is best for the history of human population growth?

A. Constant exponential growth at a rate slighly larger than zero.

B. Thousands of years of near zero growth, followed by centuries of accelerating growth, with a recent slowing of growth.

  1. Thousands of years of essentially zero growth, followed by a one time increase in growth rates.

  2. Alternating lengthy periods of positive and negative growth.

  1. [A numerical answer] How large would the world population be today if annual growth rates had always been .0005 larger for the last 10,000 years?

Hint 1: The rules of exponents tell us

\[ exp( (R + d) * t) = exp(R * t) * exp( d*t ) \]

Hint 2: To calculate exp(10000 * .0005), you can use a calculator or any other tool. You don’t have to use R.

Hint 3: You should get a population roughly 150 time as large as today.

Note: Imagine we increased the reproduction rate of each generation by a tiny bit – so, for example, instead of each woman having on average 1 surviving daughter, imagine she had 1.015 surviving daughters. If generations were 30 years in length, then this would mean an increase in the growth rate by about log(1.015/1.00)/30 = .0005. So, the calculation we just did tells us what would have happened to the human population if fertility rates had always been just slightly, only 1.5 percent, higher.

  1. [A numerical answer] How large would the world population in 2115 be if current exponential growth rates continue? Use 7.3 billion as the population size in 2015 and assume $R = 0.01. You can do this calculation however you choose (with R, by hand with a calculator, or any other way.)

  2. [A short answer.] Do you think this estimate of the world population in 2115 is likely to be too high or too low? Explain your reasoning in a sentence.

  3. [Optimum Population Exercise] Imagine there’s an island that can only sustain a few people. The marginal product starts at 5 units for the first person and declines by 1 unit for each additional person until the MP of the 6th person is zero. Each person needs to consume 2 units per year to subsist.

    (Hint: if you are having trouble here with the definitions of the optimum populations, consult the lecture slides.)

    1. Fill in the Average Product row of the table below. (We recommend you do this by hand to enhance understanding.)

    (Hint: The average can be obtained by summing up the marginal product to produce the total product and then dividing by the number of people.)

    Population Size 1 2 3 4 5 6 7 8 9 10
    Marginal Product 5 4 3 2 1 0 0 0 0 0
    Average Product 5 4.5 4
    1. What size population gives Sauvy’s economic optimum?

    2. What size population gives Sauvy’s power optimum?

    3. What size population is the “maximum” sustainable population?

  4. [non-graded] About how much time (in hours and minutes) did it take you to complete this lab?

Congratulations! You have completed Lab 1.

LS0tCnRpdGxlOiAiRWNvbi9EZW1vZyBDMTc1IExhYiAxOiBXb3JsZCBQb3B1bGF0aW9uIEdyb3d0aCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBPdmVydmlldwoKVGhpcyBpcyB0aGUgZmlyc3QgbGFiIG9mIEVjb25vbWljIERlbW9ncmFwaHkgKEVjb24vRGVtb2cgQzE3NSkuIE91cgpnb2FscyBpbiB0aGlzIGZpcnN0IGxhYiBhcmU6CgoxLiBUbyBnZXQgZXZlcnlvbmUgc3RhcnRlZCBwcm9ncmFtbWluZyBhbmQgZG9pbmcgdGhlaXIgYXNzaWdubWVudHMKICAgd2l0aCBSLCBSU3R1ZGlvLCBhbmQgYkNvdXJzZXMuCgoyLiBUbyB1c2UgdGhlIGV4cG9uZW50aWFsIG1vZGVsIHRvIGxlYXJuIGFib3V0IHdvcmxkIHBvcHVsYXRpb24gaGlzdG9yeS4KCj4gVGhpcyBkb2N1bWVudCBpcyB3cml0dGVuIGluIHRoZSAiUiBtYXJrZG93biIgZm9ybWF0IGFuZCBzaG91bGQgYmUKPiByZWFkIGFuZCBlZGl0ZWQgd2l0aGluIFJTdHVkaW8uIFRoZSBub3RlYm9vayBpbnRlcmZhY2UgYWxsb3dzIHlvdSB0bwo+IGV4ZWN1dGUgYW5kIGRpc3BsYXkgUi1jb2RlIHdpdGhpbiBhIHNpbmdsZSB3aW5kb3cuIFlvdSBjYW4gZWRpdCB0aGlzCj4gbm90ZWJvb2sgZGlyZWN0bHkgYW5kIHNhdmUgaXQuIFdlIHJlY29tbWVuZCB5b3Ugc2F2ZSBpdCB3aXRoIGEKPiBkaWZmZXJlbnQgbmFtZSAoZS5nLiwgIndvcmxkX2xhYl8xX25ld25hbWUuUm1kIikgdG8gYXZvaWQgb3ZlcndyaXRpbmcKPiB5b3VyIGVkaXRzLgoKPiBWaWV3aW5nIG5vdGU6IHRoZSBsYWJzIGFyZSBmb3JtYXR0ZWQgdXNpbmcgaGFyZCBsaW5lLWVuZGluZ3MuIFRyeSAKPiByZXNpemluZyB2aWV3aW5nIHdpbmRvdyBpZiBsaW5lcyBhcmUgb3ZlcmZsb3dpbmcuCgojIFdyaXRpbmcgYW5kIGV4ZWN1dGluZyBSIGNvbW1hbmRzCgpJbiB0aGUgUlN0dWRpbyBOb3RlYm9vaywgd2UgbWl4IGV4ZWN1dGFibGUgUiBjb21tYW5kcyBpbiB3aXRoIHJlZ3VsYXIgCndyaXR0ZW4gdGV4dCBieSBjcmVhdGluZyBhICJjb2RlIGNodW5rLiIKVG8gb3BlbiBhIGNvZGUgY2h1bmssIHdlIHR5cGUgIiJgYGB7cn0iIHRvIHN0YXJ0LiBUbyBjbG9zZSB0aGUgY29kZQpjaHVuayB3ZSB0eXBlICJgYGAiIiB0byBlbmQuIEhlcmUgYXJlIHNvbWUgZXhhbXBsZXM6CgpUbyBwcmludCBhIHN0cmluZyBvZiB0ZXh0OgpgYGB7cn0KcHJpbnQoIkhlbGxvLCB3b3JsZCIpCmBgYAoKWW91IGNhbiBoaXQgdGhlIGdyZWVuICJwbGF5IiBpY29uIHRvIGV4ZWN1dGUgdGhlIGNodW5rIG9mIGNvZGUuIFRyeQptb2RpZnlpbmcgdGhlIGNodW5rIHNvIGl0IHByaW50czogIkhlbGxvLCBCZXJrZWxleSIuIChOb3RlIHRoZSBbMV0KanVzdCBtZWFucyB0aGF0IGl0IGlzIHRoZSBmaXJzdCBlbGVtZW50IG9mIHRoZSBkaXNwbGF5ZWQgb2JqZWN0LiBZb3UKY2FuIGlnbm9yZSB0aGlzLikKClRvIGFkZCAyICsgMjoKYGBge3J9CjIrMgpgYGAKClRvIGFzc2lnbiB0aGUgdmFsdWUgNCB0byBhIHZhcmlhYmxlIG5hbWVkICJ4IjoKYGBge3J9CnggPC0gNApwcmludCh4KQpgYGAKClRoZSBvdXRwdXQgb2YgYSBjaHVuayBpcyBvbmx5IHNob3duIHdoZW4geW91IHRlbGwgaXQgdG8gYmUuIEZvciBleGFtcGxlLApgYGB7cn0KeCA8LSAzCnByaW50KHgpCnkgPC0gNApzaG93KHkpCiMjIG5vdGU6IHdlIGRvbid0IHRlbGwgUiB0byBzaG93IHVzIHRoZSB2YWx1ZSBvZiAieSIKeiA8LSA1CnByaW50KHopCmBgYApUcnkgdG8gbW9kaWZ5IHRoZSBhYm92ZSBjb2RlIGNodW5rIHNvIGl0IGFsc28gcHJpbnRzIHRoZSB2YWx1ZSB0aGUKdmFyaWFibGUgInkiCgoKIyBVc2luZyBSIHRvIGNhbGN1bGF0ZSBleHBvbmVudGlhbCBwb3B1bGF0aW9uIGdyb3d0aCByYXRlcwoKYGBge3J9CiMjIGNvbW1lbnRzICh3aXRoaW4gY29kZSBjaHVua3MpIGJlZ2luIHdpdGggaGFzaHRhZ3MuIFRoZXkgYXJlIGlnbm9yZWQKIyMgYnkgUi4KCiMjIFdlIHN0YXJ0IGJ5IGlucHV0dGluZyB3b3JsZCBwb3B1bGF0aW9uIHNpemVzIGJ5IGhhbmQsIGFzc2lnbmluZwojIyB0aGVtIHRvIHZhcmlhYmxlcyBuYW1lZCAiTi4xOTAwIiBhbmQgIk4uMjAwMCIgYnkgdXNpbmcgdGhlIGFzc2lnbm1lbnQKIyMgb3BlcmF0b3I6ICI8LSIKCk4uMTkwMCA8LSAxNjUwICMgZXN0aW1hdGVkIHdvcmxkIHBvcHVsYXRpb24gaW4gMTkwMCAoaW4gbWlsbGlvbnMpCk4uMjAwMCA8LSA2MTI3ICMgc2FtZSBmb3IgMjAwMAoKIyMgd2UgY2FuIGRpc3BsYXkgdGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSBjYWxsZWQgTi4xOTAwIChoaXQgdGhlCiMjICJwbGF5IiBidXR0b24pCnByaW50KE4uMjAwMCkKYGBgCgpgYGB7cn0KIyMgV2Ugbm93IGNhbGN1bGF0ZSBncm93dGggcmF0ZSBmcm9tIDE5MDAgdG8gMjAwMCwgdXNpbmcgb3VyIGZvcm11bGEKIyMgZm9yIHRoZSBzbG9wZSBvZiB0aGUgbG9nYXJpdGhtIG9mIHBvcHVsYXRpb24uCgojIyBpbiBSIHdoZW4gd2Ugd3JpdGUgbG9nKCksIHRoaXMgY29tbWFuZCB3aWxsIGdpdmUgdXMgdGhlIG5hdHVyYWwgbG9nLCB3aGljaCB1c2VzIGJhc2UgZQoKUi50d2VudGlldGguY2VudHVyeSA8LSAoIGxvZyhOLjIwMDApIC0gbG9nKE4uMTkwMCkgKSAvICgyMDAwIC0gMTkwMCkKUi50d2VudGlldGguY2VudHVyeQpgYGAKWW91IHNob3VsZCBnZXQgIlsxXSAwLjAxMzExOTMiLCBvciBhYm91dCAxLjMgcGVyY2VudC4KCldlIGNhbiBjaGVjayB0aGlzIGFuc3dlcgpgYGB7cn0KTi4yMDAwLmNoZWNrIDwtIE4uMTkwMCAqIGV4cCgxMDAgKiAwLjAxMzExOTMpCk4uMjAwMC5jaGVjawpgYGAKV2hpY2ggaXMgIjYxMjciLCB0aGUgY29ycmVjdCB2YWx1ZSBmb3IgdGhlIHdvcmxkIHBvcHVsYXRpb24gaW4gMjAwMC4KCk5vdyBsZXQncyBjYWxjdWxhdGUgdGhlIGV4cG9uZW50aWFsIGdyb3d0aCByYXRlIGZvciB0aGUKZmlmdHkgeWVhcnMgZnJvbSAxODUwIHRvIDE5MDAuIFlvdSBuZWVkIHRvIGFsdGVyIHRoZSBjb2RlIGJlbG93IHRvCmdldCB0aGUgcmlnaHQgYW5zd2VyLgoKYGBge3J9Ck4uMTg1MCA8LSAxMjYyICMgdGhlc2UgYXJlIG1pbGxpb25zCiMjIE5vdGU6IFdlIGRvbid0IG5lZWQgdG8gcmUtZW50ZXIgTi4xOTAwLCBzaW5jZSB2YXJpYWJsZXMgYXJlIHNhdmVkCiMjIGFjcm9zcyBjaHVua3MuCgojIyBOb3cgbW9kaWZ5IHRoZSBjb2RlIGJlbG93IHRvIGdpdmUgdGhlIHJpZ2h0IGFuc3dlci4gKEhpbnQ6IHlvdSBuZWVkCiMjIHRvIHJlbmFtZSB0aGUgdmFyaWFibGVzIE4uMjAwMCBhbmQgTi4xOTAwIGFuZCBjaGFuZ2UgdGhlIGRhdGVzCiMjICIyMDAwIiBhbmQgIjE5MDAiLikKUi4xODUwLnRvLjE5MDAgPC0gKCBsb2coTi4xOTAwKSAtIGxvZyhOLjE4NTApICkgLyAoMTkwMCAtIDE4NTApCnByaW50KCBSLjE4NTAudG8uMTkwMCApCmBgYAoKWW91IHNob3VsZCBnZXQgJDAuMDA1MzYxNTUkLCBhYm91dCAwLjUgcGVyY2VudC4gKEhpbnQ6IElmIHlvdSdyZSBzdGlsbApnZXR0aW5nIDAuMDEzMTE5MywgaXQgbWVhbnMgeW91IGhhdmVuJ3QgbW9kaWZpZWQgdGhlIGNvZGUgYW5kIGhhdmUKYXNzaWduZWQgdGhlIG5ldyB2YXJpYWJsZSBSLjE4NTAudG8uMTkwMCB3aXRoIHRoZSBhbnN3ZXIgZm9yIDE5MDAgdG8KMjAwMC4pCgooTm90ZTogY2xhc3MgZGVtbyBlbmRzIGFib3V0IGhlcmUuKQoKCiMgVGhlICpjb21wbGV0ZSogaGlzdG9yeSBvZiB3b3JsZCBwb3B1bGF0aW9uCgpGaXJzdCB3ZSdyZSBnb2luZyB0byByZWFkIGluIGRhdGEgZnJvbSBhIGZpbGUgdGhhdCB3ZSd2ZSBwbGFjZWQgb24gdGhlIGNvdXJzZSBsYWIgd2Vic2l0ZS4KYGBge3J9CmRhdCA8LSByZWFkLnRhYmxlKCIvZGF0YTE3NS93b3JsZF9wb3B1bGF0aW9uX2RhdGEudHh0IiwgaGVhZGVyID0gVCkKZGF0CmBgYAoKTG9vayBhdCB0aGUgZGF0YSBzZXQsIHdoaWNoIGhhcyB0aGUgZm9ybSBvZiBhIHRhYmxlIHdpdGggdHdvIGxhYmVsZWQKY29sdW1ucyAicG9wIiBhbmQgInllYXIiLiBXZSdyZSBnb2luZyB0byBleHRyYWN0IHRoZSBjb250ZW50cyBpbnRvIG91cgp0d28gdmVjdG9ycyB5ZWFyLnZlYyBhbmQgTi52ZWMuIChZb3UgZG9uJ3QgbmVlZCB0byB1bmRlcnN0YW5kCnRoaXMgeWV0LiBXZSdsbCBiZSBsZWFybmluZyBhYm91dCB3aHkgdGhpcyB3b3JrcyBpbiBsYXRlciBsYWJzLikKCmBgYHtyfQptaWxsaW9uIDwtIDEwMDAwMDAKTi52ZWMgPC0gZGF0JHBvcCAvIDEwMDAgIyMgY29udmVydHMgbWlsbGlvbnMgdG8gYmlsbGlvbnMKeWVhci52ZWMgPC0gZGF0JHllYXIKbmFtZXMoTi52ZWMpIDwtIHllYXIudmVjCmBgYAoKTGV0J3MgbG9vayBhdCBib3RoIG9mIHRoZXNlCmBgYHtyfQp5ZWFyLnZlYwpgYGAKYGBge3J9Ck4udmVjCmBgYAoKIyMgT3VyIGZpcnN0IHBsb3QKCmBgYHtyfQpwbG90KHggPSB5ZWFyLnZlYywKICAgICB5ID0gTi52ZWMpCmBgYApXb3csIGxvb2tzIGxpa2Ugd29ybGQgcG9wdWxhdGlvbiBpcyBleHBsb2RpbmcuCgpMZXQncyBzZWUgd2hhdCBpcyBoYXBwZW5pbmcgaW4gdGVybXMgb2YgcHJvcG9ydGlvbmFsIGNoYW5nZXMgKGJ5CnRha2luZyBsb2dzKQoKYGBge3J9CmxvZy5OLnZlYyA8LSBsb2coTi52ZWMpCnBsb3QoeCA9IHllYXIudmVjLCB5ID0gbG9nLk4udmVjKQpgYGAKV293LCBpdCBsb29rcyBsaWtlIGV2ZW4gdGhlIHByb3BvcnRpb25hbCByYXRlIG9mIGdyb3d0aCBoYXMgaW5jcmVhc2VkLgoKWW91IGNhbiBub3cgZ3Vlc3MtdGltYXRlIHRoZSBleHBvbmVudGlhbCBwb3B1bGF0aW9uIGdyb3d0aCByYXRlIGJ5CmV5ZS1pbmcgdGhlICJzbG9wZSIgb2YgdGhlIGxvZyByYXRlIG9mIHBvcHVsYXRpb24gZ3Jvd3RoLiBUaGUgc2xvcGUKaXMgZXF1YWwgdG8gdGhlIGNhbGN1bGF0ZWQgZ3Jvd3RoIHJhdGUuIEZvciBleGFtcGxlLCB0aGUgODAwMCB5ZWFyIApwZXJpb2QgZnJvbSAtODAwMCB0byAwIHNhdyBhbiBpbmNyZWFzZSBvZiBhYm91dCA0IGluIGxvZy1wb3B1bGF0aW9uIApzaXplLiBUaGUgc2xvcGUgaXMgdGh1cyBhYm91dCA0LzgwMDAgPSAwLjAwMDUuIFdlIGNhbiBjaGVjayB0aGlzIHdpdGggb3VyCmNhbGN1bGF0aW9ucyBiZWxvdy4KCgojIyBDYWxjdWxhdGluZyBncm93dGggcmF0ZXMgdGhyb3VnaCBoaXN0b3J5CgpDYWxjdWxhdGUgYSB2ZWN0b3Igb2YgZXhwb25lbnRpYWwgZ3Jvd3RoIHJhdGUuCgpIZXJlIHdlIHdpbGwgdXNlIHRoZSBgZGlmZigpYCBmdW5jdGlvbiBpbiBSLCB3aGljaCB0ZWxscyB1cyB0aGUKZGlmZmVyZW5jZXMgYmV0d2VlbiBlbGVtZW50cyBpbiBhIHZlY3Rvci4KCkZvciBleGFtcGxlLApgYGB7cn0KeCA9IGMoNCwgNSwgNykgIyMgdGhpcyBpcyBhIHZlY3RvciB3aXRoIHRocmVlIGVsZW1lbnRzLgpkaWZmKHgpICMgZ2l2ZXMgdXMgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gZWxlbWVudHMKYGBgCgpXZSdsbCBmb3JtdWxhdGUgdGhpcyBhcyB0aGUgc2xvcGUgb2YgdGhlIGdyYXBoIG9mIGxvZyBwb3B1bGF0aW9uIHNpemVzCgpgYGB7cn0KcmlzZS52ZWMgPC0gZGlmZihsb2cuTi52ZWMpICMgdGhlc2UgYXJlIHRoZSAicmlzZSIsIHRoZSB2ZXJ0aWNhbCBkaXN0YW5jZXMgYmV0d2VlbiBwb2ludHMKcnVuLnZlYyA8LSBkaWZmKHllYXIudmVjKSAjIHRoZXNlIGFyZSAicnVuIiwgdGhlIGhvcml6b250YWwgZGlzdGFuY2VzIGJldHdlZW4gcG9pbnRzCnNsb3BlLnZlYyA8LSByaXNlLnZlYyAvIHJ1bi52ZWMKUi52ZWMgPC0gc2xvcGUudmVjClIudmVjCmBgYAoKTGV0J3MgbWFrZSBhIGJpdCBtb3JlIHJlYWRhYmxlIGJ5IGV4cHJlc3NpbmcgdGhlIGdyb3d0aCByYXRlcyBpbiBwZXJjZW50YWdlIHBvaW50cywgYW5kIHJvdW5kaW5nIHRoZW0KYGBge3J9ClIudmVjLmluLnBlcmNlbnQgPC0gMTAwICogcm91bmQoUi52ZWMsIDQpClIudmVjLmluLnBlcmNlbnQKYGBgCldlIHNlZSB0aGF0IGdyb3d0aCByYXRlcyBpbmNyZWFzZWQgZm9yIG5lYXJseSAxMCwwMDAgeWVhcnMsIGJ1dCBoYXZlCnJlY2VudGx5IGJlZ3VuIHRvIGRlY3JlYXNlIGEgYml0LgoKIyMgUGxvdHRpbmcgdGhlIGdyb3d0aCByYXRlcwoKTGV0J3MgdHJ5IGEgcGxvdDoKYGBge3J9CmVuZC55ZWFyLmVhY2gucGVyaW9kLnZlYyA8LSBuYW1lcyhSLnZlYy5pbi5wZXJjZW50KQpwbG90KHggPSBlbmQueWVhci5lYWNoLnBlcmlvZC52ZWMsCiAgICAgeSA9IFIudmVjLmluLnBlcmNlbnQsCiAgICAgbWFpbiA9ICJFeHBvbmVudGlhbCBHcm93dGggUmF0ZXMgb2YgV29ybGQgUG9wdWxhdGlvbiB0aHJvdWdoIHRoZSBBZ2VzIiwKICAgICB0eXBlID0gImwiKQpgYGAKCkl0IGxvb2tzIGxpa2UgcG9wdWxhdGlvbiBncm93dGggcmF0ZXMgaGF2ZSBiZWd1biB0byBkZWNsaW5lLiBUbyBzZWUgYQpiaXQgYmV0dGVyLCB3ZSBjYW4gZ3JhcGggb25seSB0aGUgbW9yZSByZWNlbnQgeWVhcnMKCmBgYHtyfQpwbG90KHggPSBlbmQueWVhci5lYWNoLnBlcmlvZC52ZWMsCiAgICAgeSA9IFIudmVjLmluLnBlcmNlbnQsCiAgICAgeGxpbSA9IGMoMTkwMCwgMjAyMCksICAgICAgICAgICAgICAjIGxpbWl0IHRoZSB4LWF4aXMgdG8gMTkwMCB0byAyMDIwCiAgICAgbWFpbiA9ICJFeHBvbmVudGlhbCBHcm93dGggUmF0ZXMgb2YgV29ybGQgUG9wdWxhdGlvbiwgc2luY2UgMTkwMCIsCiAgICAgdHlwZSA9ICJvIikKYGBgCgojIENvbmdyYXR1bGF0aW9ucwoKWW91J3ZlIGZpbmlzaGVkIGFsbCBvZiB0aGUgY29tcHV0aW5nIGZvciB0aGUgZmlyc3QgbGFiIQoKCiMgR3JhZGVkIFF1ZXN0aW9ucyAKCihTZWUgdGhlIHN5bGxhYnVzIGZvciBpbnN0cnVjdGlvbnMgb24gc3VibWl0dGluZyB5b3VyIGFuc3dlcnMgYXQgCmh0dHBzOi8vY291cnNlcy5kZW1vZy5iZXJrZWxleS5lZHUvZ29sZHN0ZWluMTc1LykKCgoxLiBbTXVsdGlwbGUgY2hvaWNlXSBXaGljaCBvZiB0aGUgZm9sbG93aW5nIGRlc2NyaXB0aW9ucyBpcyBiZXN0IGZvcgogICB0aGUgaGlzdG9yeSBvZiBodW1hbiBwb3B1bGF0aW9uIGdyb3d0aD8KCkEuIENvbnN0YW50IGV4cG9uZW50aWFsIGdyb3d0aCBhdCBhIHJhdGUgc2xpZ2hseSBsYXJnZXIgdGhhbiB6ZXJvLgoKQi4gVGhvdXNhbmRzIG9mIHllYXJzIG9mIG5lYXIgemVybyBncm93dGgsIGZvbGxvd2VkIGJ5IGNlbnR1cmllcyBvZgphY2NlbGVyYXRpbmcgZ3Jvd3RoLCB3aXRoIGEgcmVjZW50IHNsb3dpbmcgb2YgZ3Jvd3RoLgoKQy4gIFRob3VzYW5kcyBvZiB5ZWFycyBvZiBlc3NlbnRpYWxseSB6ZXJvIGdyb3d0aCwgZm9sbG93ZWQgYnkgYSBvbmUKdGltZSBpbmNyZWFzZSBpbiBncm93dGggcmF0ZXMuCgpELiAgQWx0ZXJuYXRpbmcgbGVuZ3RoeSBwZXJpb2RzIG9mIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBncm93dGguCgoKMi4gW0EgbnVtZXJpY2FsIGFuc3dlcl0gSG93IGxhcmdlIHdvdWxkIHRoZSB3b3JsZCBwb3B1bGF0aW9uIGJlIHRvZGF5CiAgIGlmIGFubnVhbCBncm93dGggcmF0ZXMgaGFkIGFsd2F5cyBiZWVuIC4wMDA1IGxhcmdlciBmb3IgdGhlIGxhc3QKICAgMTAsMDAwIHllYXJzPwoKSGludCAxOiBUaGUgcnVsZXMgb2YgZXhwb25lbnRzIHRlbGwgdXMKCiQkCmV4cCggKFIgKyBkKSAqIHQpID0gZXhwKFIgKiB0KSAqIGV4cCggZCp0ICkKJCQKCkhpbnQgMjogVG8gY2FsY3VsYXRlIGV4cCgxMDAwMCAqIC4wMDA1KSwgeW91IGNhbiB1c2UgYSBjYWxjdWxhdG9yIG9yCmFueSBvdGhlciB0b29sLiBZb3UgZG9uJ3QgaGF2ZSB0byB1c2UgUi4KCkhpbnQgMzogWW91IHNob3VsZCBnZXQgYSBwb3B1bGF0aW9uIHJvdWdobHkgMTUwIHRpbWUgYXMgbGFyZ2UgYXMgdG9kYXkuCgpOb3RlOiBJbWFnaW5lIHdlIGluY3JlYXNlZCB0aGUgcmVwcm9kdWN0aW9uIHJhdGUgb2YgZWFjaCBnZW5lcmF0aW9uIGJ5CmEgdGlueSBiaXQgLS0gc28sIGZvciBleGFtcGxlLCBpbnN0ZWFkIG9mIGVhY2ggd29tYW4gaGF2aW5nIG9uIGF2ZXJhZ2UKMSBzdXJ2aXZpbmcgZGF1Z2h0ZXIsIGltYWdpbmUgc2hlIGhhZCAxLjAxNSBzdXJ2aXZpbmcgZGF1Z2h0ZXJzLiBJZgpnZW5lcmF0aW9ucyB3ZXJlIDMwIHllYXJzIGluIGxlbmd0aCwgdGhlbiB0aGlzIHdvdWxkIG1lYW4gYW4gaW5jcmVhc2UKaW4gdGhlIGdyb3d0aCByYXRlIGJ5IGFib3V0IGxvZygxLjAxNS8xLjAwKS8zMCA9IC4wMDA1LiBTbywgdGhlCmNhbGN1bGF0aW9uIHdlIGp1c3QgZGlkIHRlbGxzIHVzIHdoYXQgd291bGQgaGF2ZSBoYXBwZW5lZCB0byB0aGUgaHVtYW4KcG9wdWxhdGlvbiBpZiBmZXJ0aWxpdHkgcmF0ZXMgaGFkIGFsd2F5cyBiZWVuIGp1c3Qgc2xpZ2h0bHksIG9ubHkgMS41CnBlcmNlbnQsIGhpZ2hlci4KCgozLiBbQSBudW1lcmljYWwgYW5zd2VyXSBIb3cgbGFyZ2Ugd291bGQgdGhlIHdvcmxkIHBvcHVsYXRpb24gaW4gMjExNQogICBiZSBpZiBjdXJyZW50IGV4cG9uZW50aWFsIGdyb3d0aCByYXRlcyBjb250aW51ZT8gVXNlIDcuMyBiaWxsaW9uIGFzCiAgIHRoZSBwb3B1bGF0aW9uIHNpemUgaW4gMjAxNSBhbmQgYXNzdW1lICRSID0gMC4wMS4gWW91IGNhbiBkbyB0aGlzCiAgIGNhbGN1bGF0aW9uIGhvd2V2ZXIgeW91IGNob29zZSAod2l0aCBSLCBieSBoYW5kIHdpdGggYSBjYWxjdWxhdG9yLAogICBvciBhbnkgb3RoZXIgd2F5LikKCjUuIFtBIHNob3J0IGFuc3dlci5dIERvIHlvdSB0aGluayB0aGlzIGVzdGltYXRlIG9mIHRoZSB3b3JsZAogICBwb3B1bGF0aW9uIGluIDIxMTUgaXMgbGlrZWx5IHRvIGJlIHRvbyBoaWdoIG9yIHRvbyBsb3c/IEV4cGxhaW4KICAgeW91ciByZWFzb25pbmcgaW4gYSBzZW50ZW5jZS4KCjYuIFtPcHRpbXVtIFBvcHVsYXRpb24gRXhlcmNpc2VdIEltYWdpbmUgdGhlcmUncyBhbiBpc2xhbmQgdGhhdCBjYW4KICAgb25seSBzdXN0YWluIGEgZmV3IHBlb3BsZS4gVGhlIG1hcmdpbmFsIHByb2R1Y3Qgc3RhcnRzIGF0IDUgdW5pdHMKICAgZm9yIHRoZSBmaXJzdCBwZXJzb24gYW5kIGRlY2xpbmVzIGJ5IDEgdW5pdCBmb3IgZWFjaCBhZGRpdGlvbmFsCiAgIHBlcnNvbiB1bnRpbCB0aGUgTVAgb2YgdGhlIDZ0aCBwZXJzb24gaXMgemVyby4gRWFjaCBwZXJzb24gbmVlZHMgdG8KICAgY29uc3VtZSAyIHVuaXRzIHBlciB5ZWFyIHRvIHN1YnNpc3QuCiAgIAogICAoSGludDogaWYgeW91IGFyZSBoYXZpbmcgdHJvdWJsZSBoZXJlIHdpdGggdGhlIGRlZmluaXRpb25zIG9mIHRoZQogICBvcHRpbXVtIHBvcHVsYXRpb25zLCBjb25zdWx0IHRoZSBsZWN0dXJlIHNsaWRlcy4pCiAgIAogICAKICAgKGEpIEZpbGwgaW4gdGhlIEF2ZXJhZ2UgUHJvZHVjdCByb3cgb2YgdGhlIHRhYmxlIGJlbG93LiAoV2UKICAgcmVjb21tZW5kIHlvdSBkbyB0aGlzIGJ5IGhhbmQgdG8gZW5oYW5jZSB1bmRlcnN0YW5kaW5nLikKCiAgIChIaW50OiBUaGUgYXZlcmFnZSBjYW4gYmUgb2J0YWluZWQgYnkgc3VtbWluZyB1cCB0aGUgbWFyZ2luYWwKICAgcHJvZHVjdCB0byBwcm9kdWNlIHRoZSB0b3RhbCBwcm9kdWN0IGFuZCB0aGVuIGRpdmlkaW5nIGJ5IHRoZQogICBudW1iZXIgb2YgcGVvcGxlLikKCgl8IFBvcHVsYXRpb24gU2l6ZSB8IDEgfCAyICB8IDMgfCA0IHwgNSB8IDYgfCA3IHwgOCB8IDkgfCAxMCB8CiAgfC0tLS0tLS0tLS0tLS0tLS0tfC0tLXwtLS0tfC0tLXwtLS18LS0tfC0tLXwtLS18LS0tfC0tLXwtLS0tfAoJfCBNYXJnaW5hbCBQcm9kdWN0fCA1IHwgNCAgfCAzIHwgMiB8IDEgfCAwIHwgMCB8IDAgfCAwIHwgMCAgfAoJfCBBdmVyYWdlIFByb2R1Y3QgfCA1IHwgNC41fCA0IHwgICB8ICAgfCAgIHwgICB8ICAgfCAgIHwgICAgfAoKICAgKGIpIFdoYXQgc2l6ZSBwb3B1bGF0aW9uIGdpdmVzIFNhdXZ5J3MgZWNvbm9taWMgb3B0aW11bT8KCQogICAoYykgV2hhdCBzaXplIHBvcHVsYXRpb24gZ2l2ZXMgU2F1dnkncyBwb3dlciBvcHRpbXVtPwoJCiAgIChkKSBXaGF0IHNpemUgcG9wdWxhdGlvbiBpcyB0aGUgIm1heGltdW0iIHN1c3RhaW5hYmxlIHBvcHVsYXRpb24/CgkKCjcuIFtub24tZ3JhZGVkXSBBYm91dCBob3cgbXVjaCB0aW1lIChpbiBob3VycyBhbmQgbWludXRlcykgZGlkIGl0IHRha2UgeW91IHRvIGNvbXBsZXRlIHRoaXMgbGFiPwoKCkNvbmdyYXR1bGF0aW9ucyEgWW91IGhhdmUgY29tcGxldGVkIExhYiAxLgoKCgoK