Overview
This is the first lab of Economic Demography (Econ/Demog C175). Our goals in this first lab are:
To get everyone started programming and doing their assignments with R, RStudio, and bCourses.
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:
[1] "Hello, world"
[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:
[1] 4
To assign the value 4 to a variable named “x”:
[1] 4
The output of a chunk is only shown when you tell it to be. For example,
[1] 3
[1] 4
[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
N.1900 <- 1650
N.2000 <- 6127
print(N.2000)
[1] 6127
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
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
| | | | |
---|
-8000 | 5 | | | |
1 | 200 | | | |
1000 | 400 | | | |
1500 | 458 | | | |
1600 | 580 | | | |
1700 | 682 | | | |
1750 | 791 | | | |
1800 | 1000 | | | |
1850 | 1262 | | | |
1900 | 1650 | | | |
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
year.vec <- dat$year
names(N.vec) <- year.vec
Let’s look at both of these
[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
-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,
[1] 1 2
We’ll formulate this as the slope of the graph of log population sizes
rise.vec <- diff(log.N.vec)
run.vec <- diff(year.vec)
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),
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 )
- [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.
Thousands of years of essentially zero growth, followed by a one time increase in growth rates.
Alternating lengthy periods of positive and negative growth.
- [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.
[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.)
[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.
[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.)
- 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.)
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 |
What size population gives Sauvy’s economic optimum?
What size population gives Sauvy’s power optimum?
What size population is the “maximum” sustainable population?
- [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