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

(Note: In addition to this introduction, make sure to read “The Rstudio 175 cloud server for Demog/Econ C175” by Carl Mason available at [https://courses.demog.berkeley.edu/goldstein175], which provides additional information.)

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")
[1] "Hello, world"
test <- "xd"
test
[1] "xd"

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
[1] 4

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

x <- 4
print(x)
[1] 4

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

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

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

Please answer the following question by Thursday night

Which of the following is true for you? (Please answer this on a [google forms] (https://docs.google.com/forms/d/e/1FAIpQLSe7qGmTz_b_rt2olxxeEHCquCPLo2nx5zdvH54O1q3iOeTv3A/viewform) for us – we’re doing it on google right now so as to give everyone access. The graded questions at the bottom of the lab will need to be answered on bCourses).

A. I was able to login to the Rstudio 175 cloud server and change my password and run a chunk of R.

B. I was able to login but am having problems. I know that I can come to office hours and get help. I also know that I can get help this Friday, January 19 from 1-3 in the Demography Dept at 2232 Piedmont Avenue (across from the stadium).

C. I was not able to login to the Rstudio 175 cloud server. I will come to get help on Friday (see B).

D. I was not able to login to the Rstudio 175 cloud server and I am one of very few people who can’t come to the Friday help session. I am emailing Dr. Mason at cmason@berkeley.edu for help.

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" 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)
[1] 6127
## We now calculate growth rate from 1900 to 2000, using our formula
## for the slope of the logarithm of population.
R.twentieth.century <- ( log(N.2000) - log(N.1900) ) / (2000 - 1900)
R.twentieth.century
[1] 0.0131193

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
[1] 6127

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 )
[1] 0.00536155

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
ABCDEFGHIJ0123456789
year
<int>
pop
<int>
-80005
1200
1000400
1500458
1600580
1700682
1750791
18001000
18501262
19001650

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 ## or 1e6
N.vec <- dat$pop / 1000 ## converts units from "in millions" to "in billions"
year.vec <- dat$year
names(N.vec) <- year.vec

Let’s look at both of these

year.vec
 [1] -8000     1  1000  1500  1600  1700  1750  1800  1850  1900  1950  1955  1960
[14]  1965  1970  1975  1980  1985  1990  1995  2000  2005  2010  2015
N.vec
-8000     1  1000  1500  1600  1700  1750  1800  1850  1900  1950  1955  1960 
0.005 0.200 0.400 0.458 0.580 0.682 0.791 1.000 1.262 1.650 2.525 2.758 3.018 
 1965  1970  1975  1980  1985  1990  1995  2000  2005  2010  2015 
3.322 3.682 4.061 4.440 4.853 5.310 5.735 6.127 6.520 6.930 7.349 

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 proportional rate of growth has increased.

You can now guess-timate the exponential population growth rate by eyeing the “slope” of the log rate of population growth 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
[1] 1 2

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
           1         1000         1500         1600         1700         1750 
0.0004610523 0.0006938410 0.0002708093 0.0023615892 0.0016200155 0.0029653662 
        1800         1850         1900         1950         1955         1960 
0.0046891462 0.0046539553 0.0053615505 0.0085093155 0.0176529433 0.0180177162 
        1965         1970         1975         1980         1985         1990 
0.0191945302 0.0205778143 0.0195946332 0.0178450255 0.0177885388 0.0179989530 
        1995         2000         2005         2010         2015 
0.0153991831 0.0132234966 0.0124338284 0.0121970875 0.0117408873 

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

R.vec.in.percent <- 100 * round(R.vec, 4)
R.vec.in.percent
   1 1000 1500 1600 1700 1750 1800 1850 1900 1950 1955 1960 1965 1970 1975 1980 
0.05 0.07 0.03 0.24 0.16 0.30 0.47 0.47 0.54 0.85 1.77 1.80 1.92 2.06 1.96 1.78 
1985 1990 1995 2000 2005 2010 2015 
1.78 1.80 1.54 1.32 1.24 1.22 1.17 

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

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

Graded Questions

(Use Gradescope to submit your answers. A guide to using Gradescope is available at https://courses.demog.berkeley.edu/goldstein175/GradescopeGuide.pdf )

  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(Rt)exp(dt)

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 x x x x x x x
  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?

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

Congratulations! You have completed Lab 1.

LS0tCnRpdGxlOiAiRWNvbi9EZW1vZyBDMTc1IExhYiAxOiBXb3JsZCBQb3B1bGF0aW9uIEdyb3d0aCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBPdmVydmlldwoKVGhpcyBpcyB0aGUgZmlyc3QgbGFiIG9mIEVjb25vbWljIERlbW9ncmFwaHkgKEVjb24vRGVtb2cgQzE3NSkuIE91cgpnb2FscyBpbiB0aGlzIGZpcnN0IGxhYiBhcmU6CgoxLiBUbyBnZXQgZXZlcnlvbmUgc3RhcnRlZCBwcm9ncmFtbWluZyBhbmQgZG9pbmcgdGhlaXIgYXNzaWdubWVudHMKICAgd2l0aCBSLCBSU3R1ZGlvLCBhbmQgYkNvdXJzZXMuCgoyLiBUbyB1c2UgdGhlIGV4cG9uZW50aWFsIG1vZGVsIHRvIGxlYXJuIGFib3V0IHdvcmxkIHBvcHVsYXRpb24gaGlzdG9yeQoKPiBUaGlzIGRvY3VtZW50IGlzIHdyaXR0ZW4gaW4gdGhlICJSIG1hcmtkb3duIiBmb3JtYXQgYW5kIHNob3VsZCBiZQo+IHJlYWQgYW5kIGVkaXRlZCB3aXRoaW4gUlN0dWRpby4gVGhlIG5vdGVib29rIGludGVyZmFjZSBhbGxvd3MgeW91IHRvCj4gZXhlY3V0ZSBhbmQgZGlzcGxheSBSLWNvZGUgd2l0aGluIGEgc2luZ2xlIHdpbmRvdy4gWW91IGNhbiBlZGl0IHRoaXMKPiBub3RlYm9vayBkaXJlY3RseSBhbmQgc2F2ZSBpdC4gV2UgcmVjb21tZW5kIHlvdSBzYXZlIGl0IHdpdGggYQo+IGRpZmZlcmVudCBuYW1lIChlLmcuLCAid29ybGRfbGFiXzFfbmV3bmFtZS5SbWQiKSB0byBhdm9pZCBvdmVyd3JpdGluZwo+IHlvdXIgZWRpdHMuCgo+IFZpZXdpbmcgbm90ZTogdGhlIGxhYnMgYXJlIGZvcm1hdHRlZCB1c2luZyBoYXJkIGxpbmUtZW5kaW5ncy4gVHJ5IAo+IHJlc2l6aW5nIHZpZXdpbmcgd2luZG93IGlmIGxpbmVzIGFyZSBvdmVyZmxvd2luZy4KCiMgV3JpdGluZyBhbmQgZXhlY3V0aW5nIFIgY29tbWFuZHMKCihOb3RlOiBJbiBhZGRpdGlvbiB0byB0aGlzIGludHJvZHVjdGlvbiwgbWFrZSBzdXJlIHRvIHJlYWQgIlRoZSBSc3R1ZGlvIAoxNzUgY2xvdWQgc2VydmVyIGZvciBEZW1vZy9FY29uIEMxNzUiIGJ5IENhcmwgTWFzb24gYXZhaWxhYmxlIGF0CltodHRwczovL2NvdXJzZXMuZGVtb2cuYmVya2VsZXkuZWR1L2dvbGRzdGVpbjE3NV0sIHdoaWNoIHByb3ZpZGVzCmFkZGl0aW9uYWwgaW5mb3JtYXRpb24uKQoKSW4gdGhlIFJTdHVkaW8gTm90ZWJvb2ssIHdlIG1peCBleGVjdXRhYmxlIFIgY29tbWFuZHMgaW4gd2l0aCByZWd1bGFyIAp3cml0dGVuIHRleHQgYnkgY3JlYXRpbmcgYSAiY29kZSBjaHVuay4iClRvIG9wZW4gYSBjb2RlIGNodW5rLCB3ZSB0eXBlICIiYGBge3J9IiB0byBzdGFydC4gVG8gY2xvc2UgdGhlIGNvZGUKY2h1bmsgd2UgdHlwZSAiYGBgIiIgdG8gZW5kLiBIZXJlIGFyZSBzb21lIGV4YW1wbGVzOgoKVG8gcHJpbnQgYSBzdHJpbmcgb2YgdGV4dDoKYGBge3J9CnByaW50KCJIZWxsbywgd29ybGQiKQpgYGAKCgpgYGB7cn0KdGVzdCA8LSAieGQiCnRlc3QKYGBgCgpZb3UgY2FuIGhpdCB0aGUgZ3JlZW4gInBsYXkiIGljb24gdG8gZXhlY3V0ZSB0aGUgY2h1bmsgb2YgY29kZS4gVHJ5Cm1vZGlmeWluZyB0aGUgY2h1bmsgc28gaXQgcHJpbnRzOiAiSGVsbG8sIEJlcmtlbGV5Ii4gKE5vdGUgdGhlIFsxXQpqdXN0IG1lYW5zIHRoYXQgaXQgaXMgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhlIGRpc3BsYXllZCBvYmplY3QuIFlvdQpjYW4gaWdub3JlIHRoaXMuKQoKVG8gYWRkIDIgKyAyOgpgYGB7cn0KMisyCmBgYAoKVG8gYXNzaWduIHRoZSB2YWx1ZSA0IHRvIGEgdmFyaWFibGUgbmFtZWQgIngiOgpgYGB7cn0KeCA8LSA0CnByaW50KHgpCmBgYAoKVGhlIG91dHB1dCBvZiBhIGNodW5rIGlzIG9ubHkgc2hvd24gd2hlbiB5b3UgdGVsbCBpdCB0byBiZS4gRm9yIGV4YW1wbGUsCmBgYHtyfQp4IDwtIDMKcHJpbnQoeCkKeSA8LSA0CnkKIyMgbm90ZTogd2UgZG9uJ3QgdGVsbCBSIHRvIHNob3cgdXMgdGhlIHZhbHVlIG9mICJ5Igp6IDwtIDUKcHJpbnQoeikKYGBgClRyeSB0byBtb2RpZnkgdGhlIGFib3ZlIGNvZGUgY2h1bmsgc28gaXQgYWxzbyBwcmludHMgdGhlIHZhbHVlIHRoZQp2YXJpYWJsZSAieSIKCgojIFBsZWFzZSBhbnN3ZXIgdGhlIGZvbGxvd2luZyBxdWVzdGlvbiBieSBUaHVyc2RheSBuaWdodAoKPiBXaGljaCBvZiB0aGUgZm9sbG93aW5nIGlzIHRydWUgZm9yIHlvdT8gKFBsZWFzZSBhbnN3ZXIgdGhpcyBvbiBhCj4gW2dvb2dsZSBmb3Jtc10KPiAoaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZm9ybXMvZC9lLzFGQUlwUUxTZTdxR21Uel9iX3J0Mm9seHhlRUhDcXVDUExvMm54NXpkdkg1NE8xcTNpT2VUdjNBL3ZpZXdmb3JtKQo+IGZvciB1cyAtLQo+IHdlJ3JlIGRvaW5nIGl0IG9uIGdvb2dsZSByaWdodCBub3cgc28gYXMgdG8gZ2l2ZSBldmVyeW9uZSBhY2Nlc3MuIFRoZQo+IGdyYWRlZCBxdWVzdGlvbnMgYXQgdGhlIGJvdHRvbSBvZiB0aGUgbGFiIHdpbGwgbmVlZCB0byBiZSBhbnN3ZXJlZCBvbgo+IGJDb3Vyc2VzKS4KCj4gQS4gSSB3YXMgYWJsZSB0byBsb2dpbiB0byB0aGUgUnN0dWRpbyAxNzUgY2xvdWQgc2VydmVyIGFuZCBjaGFuZ2UgbXkKPiBwYXNzd29yZCBhbmQgcnVuIGEgY2h1bmsgb2YgUi4KCj4gQi4gSSB3YXMgYWJsZSB0byBsb2dpbiBidXQgYW0gaGF2aW5nIHByb2JsZW1zLiBJIGtub3cgdGhhdCBJIGNhbiBjb21lCj4gdG8gb2ZmaWNlIGhvdXJzIGFuZCBnZXQgaGVscC4gSSBhbHNvIGtub3cgdGhhdCBJIGNhbiBnZXQgaGVscCB0aGlzCj4gRnJpZGF5LCBKYW51YXJ5IDE5IGZyb20gMS0zIGluIHRoZSBEZW1vZ3JhcGh5IERlcHQgYXQgMjIzMiBQaWVkbW9udAo+IEF2ZW51ZSAoYWNyb3NzIGZyb20gdGhlIHN0YWRpdW0pLgoKPiBDLiBJIHdhcyBub3QgYWJsZSB0byBsb2dpbiB0byB0aGUgUnN0dWRpbyAxNzUgY2xvdWQgc2VydmVyLiBJIHdpbGwKPiBjb21lIHRvIGdldCBoZWxwIG9uIEZyaWRheSAoc2VlIEIpLgoKPiBELiBJIHdhcyBub3QgYWJsZSB0byBsb2dpbiB0byB0aGUgUnN0dWRpbyAxNzUgY2xvdWQgc2VydmVyIGFuZCBJIGFtCj4gb25lIG9mIHZlcnkgZmV3IHBlb3BsZSB3aG8gY2FuJ3QgY29tZSB0byB0aGUgRnJpZGF5IGhlbHAgc2Vzc2lvbi4gSQo+IGFtIGVtYWlsaW5nIERyLiBNYXNvbiBhdCBjbWFzb25AYmVya2VsZXkuZWR1IGZvciBoZWxwLgoKIyBVc2luZyBSIHRvIGNhbGN1bGF0ZSBleHBvbmVudGlhbCBwb3B1bGF0aW9uIGdyb3d0aCByYXRlcwoKYGBge3J9CiMjIGNvbW1lbnRzICh3aXRoaW4gY29kZSBjaHVua3MpIGJlZ2luIHdpdGggaGFzaHRhZ3MuIFRoZXkgYXJlIGlnbm9yZWQKIyMgYnkgUi4KCiMjIFdlIHN0YXJ0IGJ5IGlucHV0dGluZyB3b3JsZCBwb3B1bGF0aW9uIHNpemVzIGJ5IGhhbmQsIGFzc2lnbmluZwojIyB0aGVtIHRvIHZhcmlhYmxlcyBuYW1lZCAiTi4xOTAwIiBhbmQgIk4uMjAwMCIgdXNpbmcgdGhlIGFzc2lnbm1lbnQKIyMgb3BlcmF0b3I6ICI8LSIKCk4uMTkwMCA8LSAxNjUwICMgZXN0aW1hdGVkIHdvcmxkIHBvcHVsYXRpb24gaW4gMTkwMCAoaW4gbWlsbGlvbnMpCk4uMjAwMCA8LSA2MTI3ICMgc2FtZSBmb3IgMjAwMAoKIyMgd2UgY2FuIGRpc3BsYXkgdGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSBjYWxsZWQgTi4xOTAwIChoaXQgdGhlCiMjICJwbGF5IiBidXR0b24pCnByaW50KE4uMjAwMCkKYGBgCgpgYGB7cn0KIyMgV2Ugbm93IGNhbGN1bGF0ZSBncm93dGggcmF0ZSBmcm9tIDE5MDAgdG8gMjAwMCwgdXNpbmcgb3VyIGZvcm11bGEKIyMgZm9yIHRoZSBzbG9wZSBvZiB0aGUgbG9nYXJpdGhtIG9mIHBvcHVsYXRpb24uClIudHdlbnRpZXRoLmNlbnR1cnkgPC0gKCBsb2coTi4yMDAwKSAtIGxvZyhOLjE5MDApICkgLyAoMjAwMCAtIDE5MDApClIudHdlbnRpZXRoLmNlbnR1cnkKYGBgCllvdSBzaG91bGQgZ2V0ICJbMV0gMC4wMTMxMTkzIiwgb3IgYWJvdXQgMS4zIHBlcmNlbnQuCgpXZSBjYW4gY2hlY2sgdGhpcyBhbnN3ZXIKYGBge3J9Ck4uMjAwMC5jaGVjayA8LSBOLjE5MDAgKiBleHAoMTAwICogMC4wMTMxMTkzKQpOLjIwMDAuY2hlY2sKYGBgCldoaWNoIGlzICI2MTI3IiwgdGhlIGNvcnJlY3QgdmFsdWUgZm9yIHRoZSB3b3JsZCBwb3B1bGF0aW9uIGluIDIwMDAuCgpOb3cgbGV0J3MgY2FsY3VsYXRlIHRoZSBleHBvbmVudGlhbCBncm93dGggcmF0ZSBmb3IgdGhlCmZpZnR5IHllYXJzIGZyb20gMTg1MCB0byAxOTAwLiBZb3UgbmVlZCB0byBhbHRlciB0aGUgY29kZSBiZWxvdyB0bwpnZXQgdGhlIHJpZ2h0IGFuc3dlci4KCmBgYHtyfQpOLjE4NTAgPC0gMTI2MiAjIHRoZXNlIGFyZSBtaWxsaW9ucwojIyBOb3RlOiBXZSBkb24ndCBuZWVkIHRvIHJlLWVudGVyIE4uMTkwMCwgc2luY2UgdmFyaWFibGVzIGFyZSBzYXZlZAojIyBhY3Jvc3MgY2h1bmtzLgoKIyMgTm93IG1vZGlmeSB0aGUgY29kZSBiZWxvdyB0byBnaXZlIHRoZSByaWdodCBhbnN3ZXIuIChIaW50OiB5b3UgbmVlZAojIyB0byByZW5hbWUgdGhlIHZhcmlhYmxlcyBOLjIwMDAgYW5kIE4uMTkwMCBhbmQgY2hhbmdlIHRoZSBkYXRlcwojIyAiMjAwMCIgYW5kICIxOTAwIi4pClIuMTg1MC50by4xOTAwIDwtICggbG9nKE4uMTkwMCkgLSBsb2coTi4xODUwKSApIC8gKDE5MDAgLSAxODUwKQpwcmludCggUi4xODUwLnRvLjE5MDAgKQpgYGAKCllvdSBzaG91bGQgZ2V0ICQwLjAwNTM2MTU1JCwgYWJvdXQgMC41IHBlcmNlbnQuIChIaW50OiBJZiB5b3UncmUgc3RpbGwKZ2V0dGluZyAwLjAxMzExOTMsIGl0IG1lYW5zIHlvdSBoYXZlbid0IG1vZGlmaWVkIHRoZSBjb2RlIGFuZCBoYXZlCmFzc2lnbmVkIHRoZSBuZXcgdmFyaWFibGUgUi4xODUwLnRvLjE5MDAgd2l0aCB0aGUgYW5zd2VyIGZvciAxOTAwIHRvCjIwMDAuKQoKKE5vdGU6IGNsYXNzIGRlbW8gZW5kcyBhYm91dCBoZXJlLikKCgojIFRoZSAqY29tcGxldGUqIGhpc3Rvcnkgb2Ygd29ybGQgcG9wdWxhdGlvbgoKRmlyc3Qgd2UncmUgZ29pbmcgdG8gcmVhZCBpbiBkYXRhIGZyb20gYSBmaWxlIHRoYXQgd2UndmUgcGxhY2VkIG9uIHRoZSBjb3Vyc2UgbGFiIHdlYnNpdGUuCmBgYHtyfQpkYXQgPC0gcmVhZC50YWJsZSgiL2RhdGExNzUvd29ybGRfcG9wdWxhdGlvbl9kYXRhLnR4dCIsIGhlYWRlciA9IFQpCmRhdApgYGAKCkxvb2sgYXQgdGhlIGRhdGEgc2V0LCB3aGljaCBoYXMgdGhlIGZvcm0gb2YgYSB0YWJsZSB3aXRoIHR3byBsYWJlbGVkCmNvbHVtbnMgInBvcCIgYW5kICJ5ZWFyIi4gV2UncmUgZ29pbmcgdG8gZXh0cmFjdCB0aGUgY29udGVudHMgaW50byBvdXIKdHdvIHZlY3RvcnMgeWVhci52ZWMgYW5kIE4udmVjLiAoWW91IGRvbid0IG5lZWQgdG8gdW5kZXJzdGFuZAp0aGlzIHlldC4gV2UnbGwgYmUgbGVhcm5pbmcgYWJvdXQgd2h5IHRoaXMgd29ya3MgaW4gbGF0ZXIgbGFicy4pCgpgYGB7cn0KbWlsbGlvbiA8LSAxMDAwMDAwICMjIG9yIDFlNgpOLnZlYyA8LSBkYXQkcG9wIC8gMTAwMCAjIyBjb252ZXJ0cyB1bml0cyBmcm9tICJpbiBtaWxsaW9ucyIgdG8gImluIGJpbGxpb25zIgp5ZWFyLnZlYyA8LSBkYXQkeWVhcgpuYW1lcyhOLnZlYykgPC0geWVhci52ZWMKYGBgCgpMZXQncyBsb29rIGF0IGJvdGggb2YgdGhlc2UKYGBge3J9CnllYXIudmVjCmBgYApgYGB7cn0KTi52ZWMKYGBgCgojIyBPdXIgZmlyc3QgcGxvdAoKYGBge3J9CnBsb3QoeCA9IHllYXIudmVjLAogICAgIHkgPSBOLnZlYykKYGBgCldvdywgbG9va3MgbGlrZSB3b3JsZCBwb3B1bGF0aW9uIGlzIGV4cGxvZGluZy4KCkxldCdzIHNlZSB3aGF0IGlzIGhhcHBlbmluZyBpbiB0ZXJtcyBvZiBwcm9wb3J0aW9uYWwgY2hhbmdlcyAoYnkKdGFraW5nIGxvZ3MpCgpgYGB7cn0KbG9nLk4udmVjIDwtIGxvZyhOLnZlYykKcGxvdCh4ID0geWVhci52ZWMsIHkgPSBsb2cuTi52ZWMpCmBgYApXb3csIGl0IGxvb2tzIGxpa2UgZXZlbiBwcm9wb3J0aW9uYWwgcmF0ZSBvZiBncm93dGggaGFzIGluY3JlYXNlZC4KCgpZb3UgY2FuIG5vdyBndWVzcy10aW1hdGUgdGhlIGV4cG9uZW50aWFsIHBvcHVsYXRpb24gZ3Jvd3RoIHJhdGUgYnkKZXllaW5nIHRoZSAic2xvcGUiIG9mIHRoZSBsb2cgcmF0ZSBvZiBwb3B1bGF0aW9uIGdyb3d0aCBpcyBlcXVhbCB0bwp0aGUgY2FsY3VsYXRlZCBncm93dGggcmF0ZS4gRm9yIGV4YW1wbGUsIHRoZSA4MDAwIHllYXIgcGVyaW9kIGZyb20KLTgwMDAgdG8gMCBzYXcgYW4gaW5jcmVhc2Ugb2YgYWJvdXQgNCBpbiBsb2ctcG9wdWxhdGlvbiBzaXplLiBUaGUKc2xvcGUgaXMgdGh1cyBhYm91dCA0LzgwMDAgPSAwLjAwMDUuIFdlIGNhbiBjaGVjayB0aGlzIHdpdGggb3VyCmNhbGN1bGF0aW9ucyBiZWxvdy4KCgojIyBDYWxjdWxhdGluZyBncm93dGggcmF0ZXMgdGhyb3VnaCBoaXN0b3J5CgpDYWxjdWxhdGUgYSB2ZWN0b3Igb2YgZXhwb25lbnRpYWwgZ3Jvd3RoIHJhdGUuCgpIZXJlIHdlIHdpbGwgdXNlIHRoZSBgZGlmZigpYCBmdW5jdGlvbiBpbiBSLCB3aGljaCB0ZWxscyB1cyB0aGUKZGlmZmVyZW5jZXMgYmV0d2VlbiBlbGVtZW50cyBpbiBhIHZlY3Rvci4KCkZvciBleGFtcGxlLApgYGB7cn0KeCA9IGMoNCwgNSwgNykgIyMgdGhpcyBpcyBhIHZlY3RvciB3aXRoIHRocmVlIGVsZW1lbnRzLgpkaWZmKHgpICMgZ2l2ZXMgdXMgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gZWxlbWVudHMKYGBgCgpXZSdsbCBmb3JtdWxhdGUgdGhpcyBhcyB0aGUgc2xvcGUgb2YgdGhlIGdyYXBoIG9mIGxvZyBwb3B1bGF0aW9uIHNpemVzCgpgYGB7cn0KcmlzZS52ZWMgPC0gZGlmZihsb2cuTi52ZWMpICMgdGhlc2UgYXJlIHRoZSAicmlzZSIsIHRoZSB2ZXJ0aWNhbCBkaXN0YW5jZXMgYmV0d2VlbiBwb2ludHMKcnVuLnZlYyA8LSBkaWZmKHllYXIudmVjKSAjIHRoZXNlIGFyZSAicnVuIiwgdGhlIGhvcml6b250YWwgZGlzdGFuY2VzIGJldHdlZW4gcG9pbnRzCnNsb3BlLnZlYyA8LSByaXNlLnZlYyAvIHJ1bi52ZWMKUi52ZWMgPC0gc2xvcGUudmVjClIudmVjCmBgYAoKCkxldCdzIG1ha2UgYSBiaXQgbW9yZSByZWFkYWJsZSBieSBleHByZXNzaW5nIGluIHBlcmNlbnRhZ2UgcG9pbnRzLCBhbmQgcm91bmRpbmcKYGBge3J9ClIudmVjLmluLnBlcmNlbnQgPC0gMTAwICogcm91bmQoUi52ZWMsIDQpClIudmVjLmluLnBlcmNlbnQKYGBgCldlIHNlZSB0aGF0IGdyb3d0aCByYXRlcyBpbmNyZWFzZWQgZm9yIG5lYXJseSAxMCwwMDAgeWVhcnMsIGJ1dCBoYXZlCnJlY2VudGx5IGJlZ3VuIHRvIGRlY3JlYXNlIGEgYml0LgoKIyMgUGxvdHRpbmcgdGhlIGdyb3d0aCByYXRlcwoKTGV0J3MgdHJ5IGEgcGxvdDoKYGBge3J9CmVuZC55ZWFyLmVhY2gucGVyaW9kLnZlYyA8LSBuYW1lcyhSLnZlYy5pbi5wZXJjZW50KQpwbG90KHggPSBlbmQueWVhci5lYWNoLnBlcmlvZC52ZWMsCiAgICAgeSA9IFIudmVjLmluLnBlcmNlbnQsCiAgICAgbWFpbiA9ICJFeHBvbmVudGlhbCBHcm93dGggUmF0ZXMgb2YgV29ybGQgUG9wdWxhdGlvbiB0aHJvdWdoIHRoZSBBZ2VzIiwKICAgICB0eXBlID0gImwiKQpgYGAKCgpJdCBsb29rcyBsaWtlIHBvcHVsYXRpb24gZ3Jvd3RoIHJhdGVzIGhhdmUgYmVndW4gdG8gZGVjbGluZS4gVG8gc2VlIGEKYml0IGJldHRlciwgd2UgY2FuIGdyYXBoIG9ubHkgdGhlIG1vcmUgcmVjZW50IHllYXJzCgpgYGB7cn0KcGxvdCh4ID0gZW5kLnllYXIuZWFjaC5wZXJpb2QudmVjLAogICAgIHkgPSBSLnZlYy5pbi5wZXJjZW50LAogICAgIHhsaW0gPSBjKDE5MDAsIDIwMjApLCAgICAgICAgICAgICAgIyBsaW1pdCB0aGUgeC1heGlzIHRvIDE5MDAgdG8gMjAyMAogICAgIG1haW4gPSAiRXhwb25lbnRpYWwgR3Jvd3RoIFJhdGVzIG9mIFdvcmxkIFBvcHVsYXRpb24sIHNpbmNlIDE5MDAiLAogICAgIHR5cGUgPSAibyIpCmBgYAoKCiMgQ29uZ3JhdHVsYXRpb25zCgpXZSd2ZSBmaW5pc2hlZCBhbGwgb2YgdGhlIGNvbXB1dGluZyBmb3IgdGhlIGZpcnN0IGxhYiEKCgojIEdyYWRlZCBRdWVzdGlvbnMgCgooVXNlIEdyYWRlc2NvcGUgdG8gc3VibWl0IHlvdXIgYW5zd2Vycy4gQSBndWlkZSB0bwp1c2luZyBHcmFkZXNjb3BlIGlzIGF2YWlsYWJsZSBhdApodHRwczovL2NvdXJzZXMuZGVtb2cuYmVya2VsZXkuZWR1L2dvbGRzdGVpbjE3NS9HcmFkZXNjb3BlR3VpZGUucGRmICkKCgoxLiBbTXVsdGlwbGUgY2hvaWNlXSBXaGljaCBvZiB0aGUgZm9sbG93aW5nIGRlc2NyaXB0aW9ucyBpcyBiZXN0IGZvcgogICB0aGUgaGlzdG9yeSBvZiBodW1hbiBwb3B1bGF0aW9uIGdyb3d0aD8KCkEuIENvbnN0YW50IGV4cG9uZW50aWFsIGdyb3d0aCBhdCBhIHJhdGUgc2xpZ2hseSBsYXJnZXIgdGhhbiB6ZXJvLgoKQi4gVGhvdXNhbmRzIG9mIHllYXJzIG9mIG5lYXIgemVybyBncm93dGgsIGZvbGxvd2VkIGJ5IGNlbnR1cmllcyBvZgphY2NlbGVyYXRpbmcgZ3Jvd3RoLCB3aXRoIGEgcmVjZW50IHNsb3dpbmcgb2YgZ3Jvd3RoLgoKQy4gIFRob3VzYW5kcyBvZiB5ZWFycyBvZiBlc3NlbnRpYWxseSB6ZXJvIGdyb3d0aCwgZm9sbG93ZWQgYnkgYSBvbmUKdGltZSBpbmNyZWFzZSBpbiBncm93dGggcmF0ZXMuCgpELiAgQWx0ZXJuYXRpbmcgbGVuZ3RoeSBwZXJpb2RzIG9mIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBncm93dGguCgoKMi4gW0EgbnVtZXJpY2FsIGFuc3dlcl0gSG93IGxhcmdlIHdvdWxkIHRoZSB3b3JsZCBwb3B1bGF0aW9uIGJlIHRvZGF5CiAgIGlmIGFubnVhbCBncm93dGggcmF0ZXMgaGFkIGFsd2F5cyBiZWVuIC4wMDA1IGxhcmdlciBmb3IgdGhlIGxhc3QKICAgMTAsMDAwIHllYXJzPwoKSGludCAxOiBUaGUgcnVsZXMgb2YgZXhwb25lbnRzIHRlbGwgdXMKCiQkCmV4cCggKFIgKyBkKSAqIHQpID0gZXhwKFIgKiB0KSAqIGV4cCggZCp0ICkKJCQKCkhpbnQgMjogVG8gY2FsY3VsYXRlIGV4cCgxMDAwMCAqIC4wMDA1KSwgeW91IGNhbiB1c2UgYSBjYWxjdWxhdG9yIG9yCmFueSBvdGhlciB0b29sLiBZb3UgZG9uJ3QgaGF2ZSB0byB1c2UgUi4KCkhpbnQgMzogWW91IHNob3VsZCBnZXQgYSBwb3B1bGF0aW9uIHJvdWdobHkgMTUwIHRpbWUgYXMgbGFyZ2UgYXMgdG9kYXkuCgpOb3RlOiBJbWFnaW5lIHdlIGluY3JlYXNlZCB0aGUgcmVwcm9kdWN0aW9uIHJhdGUgb2YgZWFjaCBnZW5lcmF0aW9uIGJ5CmEgdGlueSBiaXQgLS0gc28sIGZvciBleGFtcGxlLCBpbnN0ZWFkIG9mIGVhY2ggd29tYW4gaGF2aW5nIG9uIGF2ZXJhZ2UKMSBzdXJ2aXZpbmcgZGF1Z2h0ZXIsIGltYWdpbmUgc2hlIGhhZCAxLjAxNSBzdXJ2aXZpbmcgZGF1Z2h0ZXJzLiBJZgpnZW5lcmF0aW9ucyB3ZXJlIDMwIHllYXJzIGluIGxlbmd0aCwgdGhlbiB0aGlzIHdvdWxkIG1lYW4gYW4gaW5jcmVhc2UKaW4gdGhlIGdyb3d0aCByYXRlIGJ5IGFib3V0IGxvZygxLjAxNS8xLjAwKS8zMCA9IC4wMDA1LiBTbywgdGhlCmNhbGN1bGF0aW9uIHdlIGp1c3QgZGlkIHRlbGxzIHVzIHdoYXQgd291bGQgaGF2ZSBoYXBwZW5lZCB0byB0aGUgaHVtYW4KcG9wdWxhdGlvbiBpZiBmZXJ0aWxpdHkgcmF0ZXMgaGFkIGFsd2F5cyBiZWVuIGp1c3Qgc2xpZ2h0bHksIG9ubHkgMS41CnBlcmNlbnQsIGhpZ2hlci4KCgozLiBbQSBudW1lcmljYWwgYW5zd2VyXSBIb3cgbGFyZ2Ugd291bGQgdGhlIHdvcmxkIHBvcHVsYXRpb24gaW4gMjExNQogICBiZSBpZiBjdXJyZW50IGV4cG9uZW50aWFsIGdyb3d0aCByYXRlcyBjb250aW51ZT8gVXNlIDcuMyBiaWxsaW9uIGFzCiAgIHRoZSBwb3B1bGF0aW9uIHNpemUgaW4gMjAxNSBhbmQgYXNzdW1lICRSID0gMC4wMS4gWW91IGNhbiBkbyB0aGlzCiAgIGNhbGN1bGF0aW9uIGhvd2V2ZXIgeW91IGNob29zZSAod2l0aCBSLCBieSBoYW5kIHdpdGggYSBjYWxjdWxhdG9yLAogICBvciBhbnkgb3RoZXIgd2F5LikKCjUuIFtBIHNob3J0IGFuc3dlci5dIERvIHlvdSB0aGluayB0aGlzIGVzdGltYXRlIG9mIHRoZSB3b3JsZAogICBwb3B1bGF0aW9uIGluIDIxMTUgaXMgbGlrZWx5IHRvIGJlIHRvbyBoaWdoIG9yIHRvbyBsb3c/IEV4cGxhaW4KICAgeW91ciByZWFzb25pbmcgaW4gYSBzZW50ZW5jZS4KCjYuIFtPcHRpbXVtIFBvcHVsYXRpb24gRXhlcmNpc2VdIEltYWdpbmUgdGhlcmUncyBhbiBpc2xhbmQgdGhhdCBjYW4KICAgb25seSBzdXN0YWluIGEgZmV3IHBlb3BsZS4gVGhlIG1hcmdpbmFsIHByb2R1Y3Qgc3RhcnRzIGF0IDUgdW5pdHMKICAgZm9yIHRoZSBmaXJzdCBwZXJzb24gYW5kIGRlY2xpbmVzIGJ5IDEgdW5pdCBmb3IgZWFjaCBhZGRpdGlvbmFsCiAgIHBlcnNvbiB1bnRpbCB0aGUgTVAgb2YgdGhlIDZ0aCBwZXJzb24gaXMgemVyby4gRWFjaCBwZXJzb24gbmVlZHMgdG8KICAgY29uc3VtZSAyIHVuaXRzIHBlciB5ZWFyIHRvIHN1YnNpc3QuCiAgIAogICAoSGludDogaWYgeW91IGFyZSBoYXZpbmcgdHJvdWJsZSBoZXJlIHdpdGggdGhlIGRlZmluaXRpb25zIG9mIHRoZQogICBvcHRpbXVtIHBvcHVsYXRpb25zLCBjb25zdWx0IHRoZSBsZWN0dXJlIHNsaWRlcy4pCiAgIAogICAKICAgKGEpIEZpbGwgaW4gdGhlIEF2ZXJhZ2UgUHJvZHVjdCByb3cgb2YgdGhlIHRhYmxlIGJlbG93LiAoV2UKICAgcmVjb21tZW5kIHlvdSBkbyB0aGlzIGJ5IGhhbmQgdG8gZW5oYW5jZSB1bmRlcnN0YW5kaW5nLikKCiAgIChIaW50OiBUaGUgYXZlcmFnZSBjYW4gYmUgb2J0YWluZWQgYnkgc3VtbWluZyB1cCB0aGUgbWFyZ2luYWwKICAgcHJvZHVjdCB0byBwcm9kdWNlIHRoZSB0b3RhbCBwcm9kdWN0IGFuZCB0aGVuIGRpdmlkaW5nIGJ5IHRoZQogICBudW1iZXIgb2YgcGVvcGxlLikKCj4JfCBQb3B1bGF0aW9uIFNpemUgfCAxIHwgMiAgfCAzIHwgNCB8IDUgfCA2IHwgNyB8IDggfCA5IHwgMTAgfAo+IHwtLS0tLS0tLS0tLS0tLS0tLXwtLS18LS0tLXwtLS18LS0tfC0tLXwtLS18LS0tfC0tLXwtLS18LS0tLXwKPgl8IE1hcmdpbmFsIFByb2R1Y3R8IDUgfCA0ICB8IDMgfCAyIHwgMSB8IDAgfCAwIHwgMCB8IDAgfCAwICB8Cj4JfCBBdmVyYWdlIFByb2R1Y3QgfCA1IHwgNC41fCA0IHwgeCB8IHggfCB4IHwgeCB8IHggfCB4IHwgeCAgfAoKICAgKGIpIFdoYXQgc2l6ZSBwb3B1bGF0aW9uIGdpdmVzIFNhdXZ5J3MgZWNvbm9taWMgb3B0aW11bT8KCQogICAoYykgV2hhdCBzaXplIHBvcHVsYXRpb24gZ2l2ZXMgU2F1dnkncyBwb3dlciBvcHRpbXVtPwoJCiAgIChkKSBXaGF0IHNpemUgcG9wdWxhdGlvbiBpcyB0aGUgIm1heGltdW0iIHN1c3RhaW5hYmxlIHBvcHVsYXRpb24/CgkKCjcuIFtub24tZ3JhZGVkXSBBYm91dCBob3cgbXVjaCB0aW1lIChpbiBob3VycyBhbmQgbWludXRlcykgZGlkIGl0IHRha2UgeW91IHRvIGNvbXBsZXRlIHRoaXMgbGFiPwoKCkNvbmdyYXR1bGF0aW9ucyEgWW91IGhhdmUgY29tcGxldGVkIExhYiAxLgoKCgoK