Section 1 - Loading the Data

1.1

How many rows of data (observations) are in this dataset?

D=read.csv("C:/bussiness analytics/data/mvtWeek1.csv")
nrow(D)
[1] 191641

nrow()觀察列的數量

1.2

How many variables are in this dataset?

ncol(D)
[1] 11

ncol()觀察行的數量

1.3

Using the “max” function, what is the maximum value of the variable “ID”?

max(D$ID)
[1] 9181151

$是指定的意思

1.4

What is the minimum value of the variable “Beat”?

min(D$Beat)
[1] 111

1.5

How many observations have value TRUE in the Arrest variable (this is the number of crimes for which an arrest was made)?

sum(D$Arrest==TRUE)
[1] 15536

==是等於的意思

1.6

How many observations have a LocationDescription value of ALLEY?

sum(D$LocationDescription=="ALLEY")
[1] 2308

sum for 個數, mean for ratio mean(D$LocationDescription==“ALLEY”) 會出現比率

Section 2 - Understanding Dates in R

In many datasets, like this one, you have a date field. Unfortunately, R does not automatically recognize entries that look like dates. We need to use a function in R to extract the date and time. Take a look at the first entry of Date (remember to use square brackets when looking at a certain entry of a variable).

2.1

In what format are the entries in the variable Date?

  • Month/Day/Year Hour:Minute
  • Day/Month/Year Hour:Minute
  • Hour:Minute Month/Day/Year
  • Hour:Minute Day/Month/Year
D$Date = as.character(D$Date)
head(D$Date,5)
[1] "12/31/12 23:15" "12/31/12 22:00" "12/31/12 22:00" "12/31/12 22:00"
[5] "12/31/12 21:30"
# Month/Day/Year Hour:Minute

head()整串數列中預設值為前六項,但若加“,”在加“數字”,則僅出現受指定的前幾項數字

2.2

Now, let’s convert these characters into a Date object in R. In your R console, type

DateConvert = as.Date(strptime(mvt$Date, "%m/%d/%y %H:%M"))

This converts the variable “Date” into a Date object in R. Take a look at the variable DateConvert using the summary function.

What is the month and year of the median date in our dataset? Enter your answer as “Month Year”, without the quotes. (Ex: if the answer was 2008-03-28, you would give the answer “March 2008”, without the quotes.)

ts = as.POSIXct(D$Date, format="%m/%d/%y %H:%M")
median(ts)
[1] "2006-05-21 12:30:00 CST"

as.POSIXct(x, format=指定的時間格式)是處理時間->精準到日月年 時分

as.Date()是處理時間->僅能到天數

ts是指設定完as.POSIXct()後要放置的位置

median()計算中位數的函數

2.3

Now, let’s extract the month and the day of the week, and add these variables to our data frame mvt. We can do this with two simple functions. Type the following commands in R:

mvt$Month = months(DateConvert)

mvt$Weekday = weekdays(DateConvert)

This creates two new variables in our data frame, Month and Weekday, and sets them equal to the month and weekday values that we can extract from the Date object. Lastly, replace the old Date variable with DateConvert by typing:

mvt$Date = DateConvert

Using the table command, answer the following questions.

D$Month = format(ts, "%m")
D$Weekday = format(ts, "%w")

指定D當中的Month->D\(Month -> 在定義D\)Month=format(ts,“%m”) 指定D當中的Weekday->D\(Weekday->在定義D\)Weekday=format(ts,“%w”)

In which month did the fewest motor vehicle thefts occur?

sort(table(D$Month))

   02    04    03    06    05    01    09    11    12    08    07    10 
13511 15280 15758 16002 16035 16047 16060 16063 16426 16572 16801 17086 

table()將數列字串表格化,才能看出最少的 sort()以遞增的方式排列字串

2.4

On which weekday did the most motor vehicle thefts occur?

sort(table(D$Weekday))

    0     2     6     4     1     3     5 
26316 26791 27118 27319 27397 27416 29284 

2.5

Each observation in the dataset represents a motor vehicle theft, and the Arrest variable indicates whether an arrest was later made for this theft. Which month has the largest number of motor vehicle thefts for which an arrest was made?

library(dplyr)
package 愼㸱愼㸵dplyr愼㸱愼㸶 was built under R version 3.5.1
Attaching package: 愼㸱愼㸵dplyr愼㸱愼㸶

The following objects are masked from 愼㸱愼㸵package:stats愼㸱愼㸶:

    filter, lag

The following objects are masked from 愼㸱愼㸵package:base愼㸱愼㸶:

    intersect, setdiff, setequal, union

library(dplyr) 是可以做為更有效率地作資料處理

tapply(D$Arrest, D$Month, sum) %>% sort 
  05   06   02   09   04   11   03   07   08   10   12   01 
1187 1230 1238 1248 1252 1256 1298 1324 1329 1342 1397 1435 

tapply()是the sum of Arrest by month 或the mean of Arrest by month %>%是第二層 或第三層括號的意思

LS0tDQp0aXRsZTogIkFTMS0xIEFuIEFuYWx5dGljYWwgRGV0ZWN0aXZlIg0KYXV0aG9yOiAiPG5hbWU+IDxzdHVkZW50IElEPiINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCi0gLSAtIA0KDQojIyMgU2VjdGlvbiAxIC0gTG9hZGluZyB0aGUgRGF0YQ0KDQojIyMjIDEuMSANCkhvdyBtYW55IHJvd3Mgb2YgZGF0YSAob2JzZXJ2YXRpb25zKSBhcmUgaW4gdGhpcyBkYXRhc2V0Pw0KDQpgYGB7cn0NCkQ9cmVhZC5jc3YoIkM6L2J1c3NpbmVzcyBhbmFseXRpY3MvZGF0YS9tdnRXZWVrMS5jc3YiKQ0KbnJvdyhEKQ0KYGBgDQpucm93KCnop4Dlr5/liJfnmoTmlbjph48NCg0KIyMjIyAxLjIgDQpIb3cgbWFueSB2YXJpYWJsZXMgYXJlIGluIHRoaXMgZGF0YXNldD8NCmBgYHtyfQ0KbmNvbChEKQ0KYGBgDQpuY29sKCnop4Dlr5/ooYznmoTmlbjph48NCg0KIyMjIyAxLjMgDQpVc2luZyB0aGUgIm1heCIgZnVuY3Rpb24sIHdoYXQgaXMgdGhlIG1heGltdW0gdmFsdWUgb2YgdGhlIHZhcmlhYmxlICJJRCI/DQoNCmBgYHtyfQ0KbWF4KEQkSUQpDQpgYGANCiTmmK/mjIflrprnmoTmhI/mgJ0NCg0KIyMjIyAxLjQgDQpXaGF0IGlzIHRoZSBtaW5pbXVtIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSAiQmVhdCI/DQpgYGB7cn0NCm1pbihEJEJlYXQpDQpgYGANCg0KIyMjIyAxLjUgDQpIb3cgbWFueSBvYnNlcnZhdGlvbnMgaGF2ZSB2YWx1ZSBUUlVFIGluIHRoZSBBcnJlc3QgdmFyaWFibGUgKHRoaXMgaXMgdGhlIG51bWJlciBvZiBjcmltZXMgZm9yIHdoaWNoIGFuIGFycmVzdCB3YXMgbWFkZSk/DQoNCmBgYHtyfQ0Kc3VtKEQkQXJyZXN0PT1UUlVFKQ0KYGBgDQo9PeaYr+etieaWvOeahOaEj+aAnQ0KDQoNCiMjIyMgMS42IA0KSG93IG1hbnkgb2JzZXJ2YXRpb25zIGhhdmUgYSBMb2NhdGlvbkRlc2NyaXB0aW9uIHZhbHVlIG9mIEFMTEVZPw0KDQpgYGB7cn0NCnN1bShEJExvY2F0aW9uRGVzY3JpcHRpb249PSJBTExFWSIpDQpgYGANCnN1bSBmb3Ig5YCL5pW477yMIG1lYW4gZm9yIHJhdGlvDQptZWFuKEQkTG9jYXRpb25EZXNjcmlwdGlvbj09IkFMTEVZIikg5pyD5Ye654++5q+U546HDQoNCiMjIyBTZWN0aW9uIDIgLSBVbmRlcnN0YW5kaW5nIERhdGVzIGluIFINCg0KDQpJbiBtYW55IGRhdGFzZXRzLCBsaWtlIHRoaXMgb25lLCB5b3UgaGF2ZSBhIGRhdGUgZmllbGQuIFVuZm9ydHVuYXRlbHksIFIgZG9lcyBub3QgYXV0b21hdGljYWxseSByZWNvZ25pemUgZW50cmllcyB0aGF0IGxvb2sgbGlrZSBkYXRlcy4gV2UgbmVlZCB0byB1c2UgYSBmdW5jdGlvbiBpbiBSIHRvIGV4dHJhY3QgdGhlIGRhdGUgYW5kIHRpbWUuIFRha2UgYSBsb29rIGF0IHRoZSBmaXJzdCBlbnRyeSBvZiBEYXRlIChyZW1lbWJlciB0byB1c2Ugc3F1YXJlIGJyYWNrZXRzIHdoZW4gbG9va2luZyBhdCBhIGNlcnRhaW4gZW50cnkgb2YgYSB2YXJpYWJsZSkuDQoNCiMjIyMgMi4xIA0KSW4gd2hhdCBmb3JtYXQgYXJlIHRoZSBlbnRyaWVzIGluIHRoZSB2YXJpYWJsZSBEYXRlPw0KDQorIE1vbnRoL0RheS9ZZWFyIEhvdXI6TWludXRlDQorIERheS9Nb250aC9ZZWFyIEhvdXI6TWludXRlDQorIEhvdXI6TWludXRlIE1vbnRoL0RheS9ZZWFyDQorIEhvdXI6TWludXRlIERheS9Nb250aC9ZZWFyDQoNCmBgYHtyfQ0KRCREYXRlID0gYXMuY2hhcmFjdGVyKEQkRGF0ZSkNCmhlYWQoRCREYXRlLDUpDQojIE1vbnRoL0RheS9ZZWFyIEhvdXI6TWludXRlDQpgYGANCmhlYWQoKeaVtOS4suaVuOWIl+S4remgkOioreWAvOeCuuWJjeWFremghe+8jOS9huiLpeWKoCIsIuWcqOWKoCLmlbjlrZci77yM5YmH5YOF5Ye654++5Y+X5oyH5a6a55qE5YmN5bm+6aCF5pW45a2XDQoNCg0KIyMjIyAyLjIgDQoNCk5vdywgbGV0J3MgY29udmVydCB0aGVzZSBjaGFyYWN0ZXJzIGludG8gYSBEYXRlIG9iamVjdCBpbiBSLiBJbiB5b3VyIFIgY29uc29sZSwgdHlwZQ0KDQogICAgRGF0ZUNvbnZlcnQgPSBhcy5EYXRlKHN0cnB0aW1lKG12dCREYXRlLCAiJW0vJWQvJXkgJUg6JU0iKSkNCg0KVGhpcyBjb252ZXJ0cyB0aGUgdmFyaWFibGUgIkRhdGUiIGludG8gYSBEYXRlIG9iamVjdCBpbiBSLiBUYWtlIGEgbG9vayBhdCB0aGUgdmFyaWFibGUgRGF0ZUNvbnZlcnQgdXNpbmcgdGhlIHN1bW1hcnkgZnVuY3Rpb24uDQoNCldoYXQgaXMgdGhlIG1vbnRoIGFuZCB5ZWFyIG9mIHRoZSBtZWRpYW4gZGF0ZSBpbiBvdXIgZGF0YXNldD8gRW50ZXIgeW91ciBhbnN3ZXIgYXMgIk1vbnRoIFllYXIiLCB3aXRob3V0IHRoZSBxdW90ZXMuIChFeDogaWYgdGhlIGFuc3dlciB3YXMgMjAwOC0wMy0yOCwgeW91IHdvdWxkIGdpdmUgdGhlIGFuc3dlciAiTWFyY2ggMjAwOCIsIHdpdGhvdXQgdGhlIHF1b3Rlcy4pDQoNCmBgYHtyfQ0KdHMgPSBhcy5QT1NJWGN0KEQkRGF0ZSwgZm9ybWF0PSIlbS8lZC8leSAlSDolTSIpDQptZWRpYW4odHMpDQpgYGANCmFzLlBPU0lYY3QoeCwgZm9ybWF0PeaMh+WumueahOaZgumWk+agvOW8jynmmK/omZXnkIbmmYLplpMtPueyvua6luWIsOaXpeaciOW5tCDmmYLliIYNCg0KYXMuRGF0ZSgp5piv6JmV55CG5pmC6ZaTLT7lg4Xog73liLDlpKnmlbgNCg0KdHPmmK/mjIfoqK3lrprlroxhcy5QT1NJWGN0KCnlvozopoHmlL7nva7nmoTkvY3nva4NCg0KbWVkaWFuKCnoqIjnrpfkuK3kvY3mlbjnmoTlh73mlbgNCg0KIyMjIyAyLjMNCk5vdywgbGV0J3MgZXh0cmFjdCB0aGUgbW9udGggYW5kIHRoZSBkYXkgb2YgdGhlIHdlZWssIGFuZCBhZGQgdGhlc2UgdmFyaWFibGVzIHRvIG91ciBkYXRhIGZyYW1lIG12dC4gV2UgY2FuIGRvIHRoaXMgd2l0aCB0d28gc2ltcGxlIGZ1bmN0aW9ucy4gVHlwZSB0aGUgZm9sbG93aW5nIGNvbW1hbmRzIGluIFI6DQoNCiAgICBtdnQkTW9udGggPSBtb250aHMoRGF0ZUNvbnZlcnQpDQoNCiAgICBtdnQkV2Vla2RheSA9IHdlZWtkYXlzKERhdGVDb252ZXJ0KQ0KDQpUaGlzIGNyZWF0ZXMgdHdvIG5ldyB2YXJpYWJsZXMgaW4gb3VyIGRhdGEgZnJhbWUsIE1vbnRoIGFuZCBXZWVrZGF5LCBhbmQgc2V0cyB0aGVtIGVxdWFsIHRvIHRoZSBtb250aCBhbmQgd2Vla2RheSB2YWx1ZXMgdGhhdCB3ZSBjYW4gZXh0cmFjdCBmcm9tIHRoZSBEYXRlIG9iamVjdC4gTGFzdGx5LCByZXBsYWNlIHRoZSBvbGQgRGF0ZSB2YXJpYWJsZSB3aXRoIERhdGVDb252ZXJ0IGJ5IHR5cGluZzoNCg0KICAgIG12dCREYXRlID0gRGF0ZUNvbnZlcnQNCg0KVXNpbmcgdGhlIHRhYmxlIGNvbW1hbmQsIGFuc3dlciB0aGUgZm9sbG93aW5nIHF1ZXN0aW9ucy4NCg0KYGBge3J9DQpEJE1vbnRoID0gZm9ybWF0KHRzLCAiJW0iKQ0KRCRXZWVrZGF5ID0gZm9ybWF0KHRzLCAiJXciKQ0KYGBgDQrmjIflrppE55W25Lit55qETW9udGgtPkQkTW9udGggLT4g5Zyo5a6a576pRCRNb250aD1mb3JtYXQodHMsIiVtIikNCuaMh+WumkTnlbbkuK3nmoRXZWVrZGF5LT5EJFdlZWtkYXktPuWcqOWumue+qUQkV2Vla2RheT1mb3JtYXQodHMsIiV3IikNCg0KDQpJbiB3aGljaCBtb250aCBkaWQgdGhlIGZld2VzdCBtb3RvciB2ZWhpY2xlIHRoZWZ0cyBvY2N1cj8NCg0KYGBge3J9DQpzb3J0KHRhYmxlKEQkTW9udGgpKQ0KIyAy5pyIDQpgYGANCnRhYmxlKCnlsIfmlbjliJflrZfkuLLooajmoLzljJbvvIzmiY3og73nnIvlh7rmnIDlsJHnmoQNCnNvcnQoKeS7pemBnuWinueahOaWueW8j+aOkuWIl+Wtl+S4sg0KDQoNCiMjIyMgMi40IA0KT24gd2hpY2ggd2Vla2RheSBkaWQgdGhlIG1vc3QgbW90b3IgdmVoaWNsZSB0aGVmdHMgb2NjdXI/DQoNCmBgYHtyfQ0Kc29ydCh0YWJsZShEJFdlZWtkYXkpKQ0KIyDmmJ/mnJ/kupQNCmBgYA0KDQojIyMjIDIuNSANCkVhY2ggb2JzZXJ2YXRpb24gaW4gdGhlIGRhdGFzZXQgcmVwcmVzZW50cyBhIG1vdG9yIHZlaGljbGUgdGhlZnQsIGFuZCB0aGUgQXJyZXN0IHZhcmlhYmxlIGluZGljYXRlcyB3aGV0aGVyIGFuIGFycmVzdCB3YXMgbGF0ZXIgbWFkZSBmb3IgdGhpcyB0aGVmdC4gV2hpY2ggbW9udGggaGFzIHRoZSBsYXJnZXN0IG51bWJlciBvZiBtb3RvciB2ZWhpY2xlIHRoZWZ0cyBmb3Igd2hpY2ggYW4gYXJyZXN0IHdhcyBtYWRlPw0KDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpgYGANCmxpYnJhcnkoZHBseXIpIOaYr+WPr+S7peWBmueCuuabtOacieaViOeOh+WcsOS9nOizh+aWmeiZleeQhg0KDQoNCmBgYHtyfQ0KdGFwcGx5KEQkQXJyZXN0LCBEJE1vbnRoLCBzdW0pICU+JSBzb3J0IA0KIyAx5pyIDQpgYGANCnRhcHBseSgp5pivdGhlIHN1bSBvZiBBcnJlc3QgYnkgbW9udGgNCiAgICAgICAg5oiWdGhlIG1lYW4gb2YgQXJyZXN0IGJ5IG1vbnRoDQolPiXmmK/nrKzkuozlsaQg5oiW56ys5LiJ5bGk5ous6Jmf55qE5oSP5oCdDQoNCiMjIyBTZWN0aW9uIDMgLSBWaXN1YWxpemluZyBDcmltZSBUcmVuZHMNCg0KIyMjIyAzLjENCg0KTm93LCBsZXQncyBtYWtlIHNvbWUgcGxvdHMgdG8gaGVscCB1cyBiZXR0ZXIgdW5kZXJzdGFuZCBob3cgY3JpbWUgaGFzIGNoYW5nZWQgb3ZlciB0aW1lIGluIENoaWNhZ28uIFRocm91Z2hvdXQgdGhpcyBwcm9ibGVtLCBhbmQgaW4gZ2VuZXJhbCwgeW91IGNhbiBzYXZlIHlvdXIgcGxvdCB0byBhIGZpbGUuIEZvciBtb3JlIGluZm9ybWF0aW9uLCB0aGlzIHdlYnNpdGUgdmVyeSBjbGVhcmx5IGV4cGxhaW5zIHRoZSBwcm9jZXNzLg0KDQpGaXJzdCwgbGV0J3MgbWFrZSBhIGhpc3RvZ3JhbSBvZiB0aGUgdmFyaWFibGUgRGF0ZS4gV2UnbGwgYWRkIGFuIGV4dHJhIGFyZ3VtZW50LCB0byBzcGVjaWZ5IHRoZSBudW1iZXIgb2YgYmFycyB3ZSB3YW50IGluIG91ciBoaXN0b2dyYW0uIEluIHlvdXIgUiBjb25zb2xlLCB0eXBlDQoNCmhpc3QobXZ0JERhdGUsIGJyZWFrcz0xMDApDQoNCmBgYHtyfQ0KcGFyKGNleD0wLjcpDQpoaXN0KHRzLCAieWVhciIsIGxhcz0yLCBtYWluPSJOby4gTW90b3IgQ3JpbWVzIGJ5IHllYXIiKQ0KYGBgDQpwYXIoKeS4i+e5quWcluaMh+S7pA0KY2V45piv5oyH6Kit572u5paH5pys5ZKM56ym5ZCI55qE5bC65bqmDQpoaXN0KCnnm7TmlrnlnJYNCljou7jnmoTml6XmnJ/lvp7msLTlubPorormiJDlnoLnm7TvvIzopoHkuIvku6XkuIvnmoTlkb3ku6QNCmxhcz0x5rC05bmzICBsYXM9MuWeguebtA0KWei7uOacieWFqeeoruWWruS9jURlbnNpdHnmjIfku6TkuItmcmVxPUblkoxGcmVxdWVuY3nmjIfku6TkuItmcmVxPVTvvIzpoJDoqK3ngrpEZW5zaXR55pys6aGM5pS55oiQRnJlcXVlbmN577yM5ZyoaGlzdCgp5Lit5LiLZnJlcT1UDQptYWluPSJOby4gTW90b3IgQ3JpbWVzIGJ5IFF1YXJ0ZXIi5LiL5ZyW5b2i5Li76aGMDQrliqDkuIrkuLvpoYznmoTnm7TmlrnlnJYNCmhpc3QodHMsICJEYXRlIiwgbGFzPTIsIGZyZXE9VCwgbWFpbj0iTm8uIE1vdG9yIENyaW1lcyBieSBRdWFydGVyIikNCg0KDQpMb29raW5nIGF0IHRoZSBoaXN0b2dyYW0sIGFuc3dlciB0aGUgZm9sbG93aW5nIHF1ZXN0aW9ucy4NCg0KSW4gZ2VuZXJhbCwgZG9lcyBpdCBsb29rIGxpa2UgY3JpbWUgaW5jcmVhc2VzIG9yIGRlY3JlYXNlcyBmcm9tIDIwMDIgLSAyMDEyPw0KDQorIEluY3JlYXNlcw0KKyBEZWNyZWFzZXMNCg0KYGBge3J9DQpoaXN0KHRzLCd5ZWFyJyxsYXM9MikNCiMgIERlY3JlYXNlcw0KYGBgDQoNCkluIGdlbmVyYWwsIGRvZXMgaXQgbG9vayBsaWtlIGNyaW1lIGluY3JlYXNlcyBvciBkZWNyZWFzZXMgZnJvbSAyMDA1IC0gMjAwOD8NCg0KKyBJbmNyZWFzZXMNCisgRGVjcmVhc2VzDQoNCmBgYHtyfQ0KaGlzdCh0cywneWVhcicsbGFzPTIpDQojICBEZWNyZWFzZXMNCmBgYA0KDQojIyMjIDMuMg0KTm93LCBsZXQncyBzZWUgaG93IGFycmVzdHMgaGF2ZSBjaGFuZ2VkIG92ZXIgdGltZS4gQ3JlYXRlIGEgYm94cGxvdCBvZiB0aGUgdmFyaWFibGUgIkRhdGUiLCBzb3J0ZWQgYnkgdGhlIHZhcmlhYmxlICJBcnJlc3QiIChpZiB5b3UgYXJlIG5vdCBmYW1pbGlhciB3aXRoIGJveHBsb3RzIGFuZCB3b3VsZCBsaWtlIHRvIGxlYXJuIG1vcmUsIGNoZWNrIG91dCB0aGlzIHR1dG9yaWFsKS4gSW4gYSBib3hwbG90LCB0aGUgYm9sZCBob3Jpem9udGFsIGxpbmUgaXMgdGhlIG1lZGlhbiB2YWx1ZSBvZiB0aGUgZGF0YSwgdGhlIGJveCBzaG93cyB0aGUgcmFuZ2Ugb2YgdmFsdWVzIGJldHdlZW4gdGhlIGZpcnN0IHF1YXJ0aWxlIGFuZCB0aGlyZCBxdWFydGlsZSwgYW5kIHRoZSB3aGlza2VycyAodGhlIGRvdHRlZCBsaW5lcyBleHRlbmRpbmcgb3V0c2lkZSB0aGUgYm94KSBzaG93IHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlcywgZXhjbHVkaW5nIGFueSBvdXRsaWVycyAod2hpY2ggYXJlIHBsb3R0ZWQgYXMgY2lyY2xlcykuIE91dGxpZXJzIGFyZSBkZWZpbmVkIGJ5IGZpcnN0IGNvbXB1dGluZyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBmaXJzdCBhbmQgdGhpcmQgcXVhcnRpbGUgdmFsdWVzLCBvciB0aGUgaGVpZ2h0IG9mIHRoZSBib3guIFRoaXMgbnVtYmVyIGlzIGNhbGxlZCB0aGUgSW50ZXItUXVhcnRpbGUgUmFuZ2UgKElRUikuIEFueSBwb2ludCB0aGF0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgdGhpcmQgcXVhcnRpbGUgcGx1cyB0aGUgSVFSIG9yIGxlc3MgdGhhbiB0aGUgZmlyc3QgcXVhcnRpbGUgbWludXMgdGhlIElRUiBpcyBjb25zaWRlcmVkIGFuIG91dGxpZXIuDQoNCg0KYGBge3J9DQpib3hwbG90KCB0cyB+IEQkQXJyZXN0ICkNCmBgYA0KYm94cGxvdCh0cyB+IEQkQXJyZXN0KeeUqGJveHBsb3TnlavlnJYNCg0KDQpEb2VzIGl0IGxvb2sgbGlrZSB0aGVyZSB3ZXJlIG1vcmUgY3JpbWVzIGZvciB3aGljaCBhcnJlc3RzIHdlcmUgbWFkZSBpbiB0aGUgZmlyc3QgaGFsZiBvZiB0aGUgdGltZSBwZXJpb2Qgb3IgdGhlIHNlY29uZCBoYWxmIG9mIHRoZSB0aW1lIHBlcmlvZD8gKE5vdGUgdGhhdCB0aGUgdGltZSBwZXJpb2QgaXMgZnJvbSAyMDAxIHRvIDIwMTIsIHNvIHRoZSBtaWRkbGUgb2YgdGhlIHRpbWUgcGVyaW9kIGlzIHRoZSBiZWdpbm5pbmcgb2YgMjAwNy4pDQoNCisgRmlyc3QgaGFsZg0KKyBTZWNvbmQgaGFsZg0KDQpgYGB7cn0NCnRhcHBseShEJEFycmVzdCwgdHMgPiBhcy5QT1NJWGN0KCIyMDA3LTAxLTAxIiksIHN1bSkNCmBgYA0KdGFwcGx5KEQkQXJyZXN0LCB0cyA+IGFzLlBPU0lYY3QoIjIwMDctMDEtMDEiKSwgc3VtKQ0KdHMgPiBhcy5QT1NJWGN0KCIyMDA3LTAxLTAxIinmib7lh7ros4fmlpnkuK3lpKfmlrwyMDA35bm055qE6ZaL5aeL55qE5pW46YePDQpzdW3liqDnuL0NCg0KDQojIyMjIDMuMw0KTGV0J3MgaW52ZXN0aWdhdGUgdGhpcyBmdXJ0aGVyLiBVc2UgdGhlIHRhYmxlIGZ1bmN0aW9uIGZvciB0aGUgbmV4dCBmZXcgcXVlc3Rpb25zLg0KDQpGb3Igd2hhdCBwcm9wb3J0aW9uIG9mIG1vdG9yIHZlaGljbGUgdGhlZnRzIGluIDIwMDEgd2FzIGFuIGFycmVzdCBtYWRlPw0KDQpOb3RlOiBpbiB0aGlzIHF1ZXN0aW9uIGFuZCBtYW55IG90aGVycyBpbiB0aGUgY291cnNlLCB3ZSBhcmUgYXNraW5nIGZvciBhbiBhbnN3ZXIgYXMgYSBwcm9wb3J0aW9uLiBUaGVyZWZvcmUsIHlvdXIgYW5zd2VyIHNob3VsZCB0YWtlIGEgdmFsdWUgYmV0d2VlbiAwIGFuZCAxLg0KDQpgYGB7cn0NCnRhYmxlKEQkQXJyZXN0LCBEJFllYXIpDQp0YXBwbHkoRCRBcnJlc3QsIEQkWWVhciwgbWVhbikgJT4lIHJvdW5kKDMpDQojIDAuMTA0DQpgYGANCuWFiOeUqHRhYmxl55Wr5Ye66KGo5qC8DQp0YXBwbHnmib7liLDmr5TnjofvvIzlho3nlKggJT4lDQpyb3VuZCgzKeioiOeul+Wwj+aVuOm7nuWIsOesrOS4ieS9jQ0KDQoNCiMjIyMgMy40DQpGb3Igd2hhdCBwcm9wb3J0aW9uIG9mIG1vdG9yIHZlaGljbGUgdGhlZnRzIGluIDIwMDcgd2FzIGFuIGFycmVzdCBtYWRlPw0KDQpgYGB7cn0NCiMgMC4wODUNCmBgYA0KDQojIyMjIDMuNQ0KRm9yIHdoYXQgcHJvcG9ydGlvbiBvZiBtb3RvciB2ZWhpY2xlIHRoZWZ0cyBpbiAyMDEyIHdhcyBhbiBhcnJlc3QgbWFkZT8NCg0KYGBge3J9DQojMC4wMzkNCg0KYGBgDQoNClNpbmNlIHRoZXJlIG1heSBzdGlsbCBiZSBvcGVuIGludmVzdGlnYXRpb25zIGZvciByZWNlbnQgY3JpbWVzLCB0aGlzIGNvdWxkIGV4cGxhaW4gdGhlIHRyZW5kIHdlIGFyZSBzZWVpbmcgaW4gdGhlIGRhdGEuIFRoZXJlIGNvdWxkIGFsc28gYmUgb3RoZXIgZmFjdG9ycyBhdCBwbGF5LCBhbmQgdGhpcyB0cmVuZCBzaG91bGQgYmUgaW52ZXN0aWdhdGVkIGZ1cnRoZXIuIEhvd2V2ZXIsIHNpbmNlIHdlIGRvbid0IGtub3cgd2hlbiB0aGUgYXJyZXN0cyB3ZXJlIGFjdHVhbGx5IG1hZGUsIG91ciBkZXRlY3RpdmUgd29yayBpbiB0aGlzIGFyZWEgaGFzIHJlYWNoZWQgYSBkZWFkIGVuZC4NCg0KIyMjIFNlY3Rpb24gNCAtIFBvcHVsYXIgTG9jYXRpb25zDQoNCiMjIyMgNC4xDQpBbmFseXppbmcgdGhpcyBkYXRhIGNvdWxkIGJlIHVzZWZ1bCB0byB0aGUgQ2hpY2FnbyBQb2xpY2UgRGVwYXJ0bWVudCB3aGVuIGRlY2lkaW5nIHdoZXJlIHRvIGFsbG9jYXRlIHJlc291cmNlcy4gSWYgdGhleSB3YW50IHRvIGluY3JlYXNlIHRoZSBudW1iZXIgb2YgYXJyZXN0cyB0aGF0IGFyZSBtYWRlIGZvciBtb3RvciB2ZWhpY2xlIHRoZWZ0cywgd2hlcmUgc2hvdWxkIHRoZXkgZm9jdXMgdGhlaXIgZWZmb3J0cz8NCg0KV2Ugd2FudCB0byBmaW5kIHRoZSB0b3AgZml2ZSBsb2NhdGlvbnMgd2hlcmUgbW90b3IgdmVoaWNsZSB0aGVmdHMgb2NjdXIuIElmIHlvdSBjcmVhdGUgYSB0YWJsZSBvZiB0aGUgTG9jYXRpb25EZXNjcmlwdGlvbiB2YXJpYWJsZSwgaXQgaXMgdW5mb3J0dW5hdGVseSB2ZXJ5IGhhcmQgdG8gcmVhZCBzaW5jZSB0aGVyZSBhcmUgNzggZGlmZmVyZW50IGxvY2F0aW9ucyBpbiB0aGUgZGF0YSBzZXQuIEJ5IHVzaW5nIHRoZSBzb3J0IGZ1bmN0aW9uLCB3ZSBjYW4gdmlldyB0aGlzIHNhbWUgdGFibGUsIGJ1dCBzb3J0ZWQgYnkgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgaW4gZWFjaCBjYXRlZ29yeS4gSW4geW91ciBSIGNvbnNvbGUsIHR5cGU6DQoNCiAgICBzb3J0KHRhYmxlKG12dCRMb2NhdGlvbkRlc2NyaXB0aW9uKSkNCg0KV2hpY2ggbG9jYXRpb25zIGFyZSB0aGUgdG9wIGZpdmUgbG9jYXRpb25zIGZvciBtb3RvciB2ZWhpY2xlIHRoZWZ0cywgZXhjbHVkaW5nIHRoZSAiT3RoZXIiIGNhdGVnb3J5PyBZb3Ugc2hvdWxkIHNlbGVjdCA1IG9mIHRoZSBmb2xsb3dpbmcgb3B0aW9ucy4NCg0KKyBCYW5rDQorIEdhcyBTdGF0aW9uDQorIEhvdGVsL01vdGVsDQorIFN0cmVldA0KKyBDYXIgV2FzaA0KKyBSZXN0YXVyYW50DQorIFBhcmtpbmcgTG90L0dhcmFnZSAoTm9uLVJlc2lkZW50aWFsKQ0KKyBBbGxleQ0KKyBEcml2ZXdheSAoUmVzaWRlbnRpYWwpDQorIFZhY2FudCBMb3QvTGFuZA0KDQpgYGB7cn0NCnRhYmxlKEQkTG9jYXRpb25EZXNjcmlwdGlvbikgJT4lIHNvcnQgJT4lIHRhaWwNCmBgYA0KdGFpbCgp5a2X5Liy5pW45YiX5Lit5pyA5b6M55qE5bm+6aCF77yM6Iul54Sh6Kit5a6a5pW45a2X77yM5YmH5pyD55So6aCQ6Kit5YC85YWt6aCF5ZGI54++DQoNCiMjIyMgNC4yIA0KQ3JlYXRlIGEgc3Vic2V0IG9mIHlvdXIgZGF0YSwgb25seSB0YWtpbmcgb2JzZXJ2YXRpb25zIGZvciB3aGljaCB0aGUgdGhlZnQgaGFwcGVuZWQgaW4gb25lIG9mIHRoZXNlIGZpdmUgbG9jYXRpb25zLCBhbmQgY2FsbCB0aGlzIG5ldyBkYXRhIHNldCAiVG9wNSIuIFRvIGRvIHRoaXMsIHlvdSBjYW4gdXNlIHRoZSB8IHN5bWJvbC4gSW4gbGVjdHVyZSwgd2UgdXNlZCB0aGUgJiBzeW1ib2wgdG8gdXNlIHR3byBjcml0ZXJpYSB0byBtYWtlIGEgc3Vic2V0IG9mIHRoZSBkYXRhLiBUbyBvbmx5IHRha2Ugb2JzZXJ2YXRpb25zIHRoYXQgaGF2ZSBhIGNlcnRhaW4gdmFsdWUgaW4gb25lIHZhcmlhYmxlIG9yIHRoZSBvdGhlciwgdGhlIHwgY2hhcmFjdGVyIGNhbiBiZSB1c2VkIGluIHBsYWNlIG9mIHRoZSAmIHN5bWJvbC4gVGhpcyBpcyBhbHNvIGNhbGxlZCBhIGxvZ2ljYWwgIm9yIiBvcGVyYXRpb24uDQoNCkFsdGVybmF0ZWx5LCB5b3UgY291bGQgY3JlYXRlIGZpdmUgZGlmZmVyZW50IHN1YnNldHMsIGFuZCB0aGVuIG1lcmdlIHRoZW0gdG9nZXRoZXIgaW50byBvbmUgZGF0YSBmcmFtZSB1c2luZyByYmluZC4NCg0KSG93IG1hbnkgb2JzZXJ2YXRpb25zIGFyZSBpbiBUb3A1Pw0KDQpgYGB7cn0NCihUb3A1PW5hbWVzKHRhYmxlKEQkTG9jYXRpb25EZXNjcmlwdGlvbikgJT4lIHNvcnQgJT4lIHRhaWwoNikpWy00XSkNCg0Kc3VtKEQkTG9jYXRpb25EZXNjcmlwdGlvbiAlaW4lIFRvcDUpDQojIDE3NzUxMA0KDQpgYGANCnN1YnNldCgpPSAlaW4lIOevqemBuOWtkOizh+aWme+8jOS+i+WmgkxvY2F0aW9uRGVzY3JpcHRpb27lkoxUb3BMb2NhdGlvbnMNCg0KDQojIyMjIDQuMw0KUiB3aWxsIHJlbWVtYmVyIHRoZSBvdGhlciBjYXRlZ29yaWVzIG9mIHRoZSBMb2NhdGlvbkRlc2NyaXB0aW9uIHZhcmlhYmxlIGZyb20gdGhlIG9yaWdpbmFsIGRhdGFzZXQsIHNvIHJ1bm5pbmcgdGFibGUoVG9wNSRMb2NhdGlvbkRlc2NyaXB0aW9uKSB3aWxsIGhhdmUgYSBsb3Qgb2YgdW5uZWNlc3Nhcnkgb3V0cHV0LiBUbyBtYWtlIG91ciB0YWJsZXMgYSBiaXQgbmljZXIgdG8gcmVhZCwgd2UgY2FuIHJlZnJlc2ggdGhpcyBmYWN0b3IgdmFyaWFibGUuIEluIHlvdXIgUiBjb25zb2xlLCB0eXBlOg0KDQogICAgVG9wNSRMb2NhdGlvbkRlc2NyaXB0aW9uID0gZmFjdG9yKFRvcDUkTG9jYXRpb25EZXNjcmlwdGlvbikNCg0KSWYgeW91IHJ1biB0aGUgc3RyIG9yIHRhYmxlIGZ1bmN0aW9uIG9uIFRvcDUgbm93LCB5b3Ugc2hvdWxkIHNlZSB0aGF0IExvY2F0aW9uRGVzY3JpcHRpb24gbm93IG9ubHkgaGFzIDUgdmFsdWVzLCBhcyB3ZSBleHBlY3QuDQoNClVzZSB0aGUgVG9wNSBkYXRhIGZyYW1lIHRvIGFuc3dlciB0aGUgcmVtYWluaW5nIHF1ZXN0aW9ucy4NCg0KT25lIG9mIHRoZSBsb2NhdGlvbnMgaGFzIGEgbXVjaCBoaWdoZXIgYXJyZXN0IHJhdGUgdGhhbiB0aGUgb3RoZXIgbG9jYXRpb25zLiBXaGljaCBpcyBpdD8gUGxlYXNlIGVudGVyIHRoZSB0ZXh0IGluIGV4YWN0bHkgdGhlIHNhbWUgd2F5IGFzIGhvdyBpdCBsb29rcyBpbiB0aGUgYW5zd2VyIG9wdGlvbnMgZm9yIFByb2JsZW0gNC4xLg0KDQpgYGB7cn0NClRvcDUgPSBzdWJzZXQoRCwgTG9jYXRpb25EZXNjcmlwdGlvbiAlaW4lIFRvcDUpDQp0YXBwbHkoVG9wNSRBcnJlc3QsIFRvcDUkTG9jYXRpb25EZXNjcmlwdGlvbiwgbWVhbikgJT4lIHNvcnQgJT4lIHJvdW5kKDMpDQoNCmBgYA0KYXMuY2hhcmFjdGVy5o+b5qC85byPDQoNCiMjIyMgNC40IA0KT24gd2hpY2ggZGF5IG9mIHRoZSB3ZWVrIGRvIHRoZSBtb3N0IG1vdG9yIHZlaGljbGUgdGhlZnRzIGF0IGdhcyBzdGF0aW9ucyBoYXBwZW4/DQooTW9uZGF5flN1bmRheSkNCg0KYGBge3J9DQp0c1tUb3A1JExvY2F0aW9uID09ICJHQVMgU1RBVElPTiJdICU+JSBmb3JtYXQoJyV3JykgJT4lIHRhYmxlICU+JSBzb3J0DQojIOaYn+acn+S6lA0KDQpgYGANCuWmguaenOimgeWcqOabtOikh+mbnOeahOWtkOmbhuWQiA0KdGFwcGx5KFRvcDUkQXJyZXN0LCBsaXN0KFRvcDUkTG9jYXRpb25EZXNjcmlwdGlvbiwgVG9wNSRXZWVrZGF5KSwgbWVhbikgJT4lIHJvdW5kKDMpDQoNCiMjIyMgNC41DQpPbiB3aGljaCBkYXkgb2YgdGhlIHdlZWsgZG8gdGhlIGZld2VzdCBtb3RvciB2ZWhpY2xlIHRoZWZ0cyBpbiByZXNpZGVudGlhbCBkcml2ZXdheXMgaGFwcGVuPyhNb25kYXl+U3VuZGF5KQ0KDQpgYGB7cn0NCnRzW1RvcDUkTG9jYXRpb24gPT0gIkRSSVZFV0FZIC0gUkVTSURFTlRJQUwiXSAlPiUgZm9ybWF0KCcldycpICU+JSB0YWJsZSAlPiUgc29ydA0KDQoj5pif5pyf5LqUDQpgYGANCg0KDQoNCg0KDQo=