Setup
# Load the necessary packages required to reproduce the report. For example:
library(kableExtra)
library(magrittr)
library(readr)
library(readxl)
library(dplyr)
Student names, numbers and percentage of
contributions
Group information
| Student name |
Student number |
Percentage of contribution |
| Brayden Smith |
S3717835 |
100% |
Executive Summary
After both data sets were imported, due to the way that the second
data set “lga_data” was formatted, one of the columns had to be renamed
before I could merge them, as there was no mutual variable to join them
by.
- The formatting of this data set continued to be problematic with all
of the usable columns needing to be renamed as their headers were
imported as cells in the data frame.
- After this, several conversions were made to change the variable
types of some variables.
- I then got rid of any unnecessary columns as the formatting of the
data set made it quite untidy and messy and was very limiting in its
workable capabilities
- We also then created a new variable describing the rate of crimes by
area in kilometers squared
- We then got rid of any N/A or missing values, followed by replacing
any outliers with their respective means
- Lastly we transformed one of the variables in an attempt to
normalize the data
Data
The first data set was downloaded from the Crime Statistics Agency :
https://www.crimestatistics.vic.gov.au/crime-statistics/latest-victorian-crime-data/download-data
The data set was originally titled “Data Tables LGA Recorded Offences
Year Ending June 2023”. In this very descriptive report, the details of
all recorded criminal offences are kept and seperated by many
categories, but mainly focused around the regional division by Local
Government Area (LGA)
The second data set was downloaded from the Australian Bureau of
Statistics: https://www.abs.gov.au/statistics/people/population/regional-population/latest-release
The data set was orginally titled “Population estimates and components
by LGA 2021 to 2022 - Revised. This data set describes different
demographic features of all Local Government Areas across Australia,
however we only used”Table 2” as that was the table used to described
Victorian LGAs.
# Import the data, provide your R codes here.
crime_data<- read_excel("Data_Tables_LGA_Recorded_Offences_Year_Ending_June_2023.xlsx",sheet = "Table 01")
lga_data<-read_excel("32180DS0002_2021-22r.xlsx",sheet = "Table 2")
lga_data<-lga_data %>%
rename("Local Government Area" = one_of("...2"))
all_data<-left_join(crime_data,lga_data, by = "Local Government Area")
head(all_data)
Understand
# This is the R chunk for the Understand Section
all_data<- all_data %>%
rename(
"2021 ERP" = "...3",
"2022 ERP" = "...4",
"ERP Change" = "...6",
"ERP Change Ratio" = "...7",
"Natural Increase" = "...9",
"Internal Migration" = "...10",
"External Migration" = "...11",
"Area (km2)" = "...13",
"Persons per km2" = "...14"
)
# str(all_data)
# Here there are some character variables that we should change to number
all_data$`2021 ERP`<-as.numeric(all_data$`2021 ERP`)
all_data$`2022 ERP`<-as.numeric(all_data$`2022 ERP`)
all_data$`ERP Change`<-as.numeric(all_data$`ERP Change`)
all_data$`ERP Change Ratio`<-as.numeric(all_data$`ERP Change Ratio`)
all_data$`Natural Increase`<-as.numeric(all_data$`Natural Increase`)
all_data$`Internal Migration`<-as.numeric(all_data$`Internal Migration`)
all_data$`External Migration`<-as.numeric(all_data$`External Migration`)
all_data$`Area (km2)`<-as.numeric(all_data$`Area (km2)`)
all_data$`Persons per km2`<-as.numeric(all_data$`Persons per km2`)
# We will also convert Police Region to factor variable
all_data$`Police Region`<-as.factor(all_data$`Police Region`)
str(all_data)
tibble [870 × 19] (S3: tbl_df/tbl/data.frame)
$ Year : num [1:870] 2023 2023 2023 2023 2023 ...
$ Year ending : chr [1:870] "June" "June" "June" "June" ...
$ Police Region : Factor w/ 6 levels "1 North West Metro",..: 1 1 1 1 1 1 1 1 1 1 ...
$ Local Government Area : chr [1:870] "Banyule" "Brimbank" "Darebin" "Hobsons Bay" ...
$ Offence Count : num [1:870] 7862 17122 13244 5647 18257 ...
$ Rate per 100,000 population : num [1:870] 6112 8732 8639 6079 7049 ...
$ Australian Bureau of Statistics: chr [1:870] "20660" "21180" "21890" "23110" ...
$ 2021 ERP : num [1:870] 127370 196631 150296 92267 246920 ...
$ 2022 ERP : num [1:870] 127348 193256 150483 91803 252987 ...
$ ...5 : logi [1:870] NA NA NA NA NA NA ...
$ ERP Change : num [1:870] -22 -3375 187 -464 6067 ...
$ ERP Change Ratio : num [1:870] 0 -1.7 0.1 -0.5 2.5 1.3 4.5 6.5 NA 0.1 ...
$ ...8 : logi [1:870] NA NA NA NA NA NA ...
$ Natural Increase : num [1:870] 435 784 556 480 2688 ...
$ Internal Migration : num [1:870] -1446 -6400 -2536 -1750 971 ...
$ External Migration : num [1:870] 989 2241 2167 806 2408 ...
$ ...12 : logi [1:870] NA NA NA NA NA NA ...
$ Area (km2) : num [1:870] 62.5 123.4 53.5 64.2 503.8 ...
$ Persons per km2 : num [1:870] 2036 1566 2814 1429 502 ...
After initially running the str() function we could see that almost
all of the variables had been read in as character variables. However
most of them were numeric which were changed using the as.numeric()
function as well as adjusting the “Police Region” to be a Factor
Variable. There were also several empty columns that were classified as
logical variables however these will all be removed in the next section
as they are all containing NA values.
Tidy & Manipulate Data I
# This is the R chunk for the Tidy & Manipulate Data I
# This data also represents crime from all years between 2014-2023, however we are only interested in 2021/2022.
# Since we have columns for 2021 data we will delete all rows except for those containing 2022 data
all_data<-all_data[all_data$Year == "2022",]
# All of these recordings were taken in June as well so we will eliminate the month column as it is no longer needed
all_data<- all_data%>%
select(-"Year ending",-"Australian Bureau of Statistics",-"...5",-"...8",-"...12")
# We will also delete any row that has "Total" as it does not represent a single Local Government Area
all_data<-all_data[!(all_data$`Local Government Area` %in% "Total"),]
Both of these datasets were initially quite messy when imported. To
begin with the first data set had a different row for each yearly
observation of the same data set where they should have been stored in
columns. Since we were only looking at 2021 and 2022 years which were
already stored in their own columns in the second data set, we deleted
all rows except for 2022. We also deleted many columns that were
designed to be line breaks in between the original data sheet in excel.
We then deleted the “Year ending” variable as every year had ended in
June so it was redundant to have that value in there. There were also
some rows that had “Total” which grouped the data by descriptive
statistics but was not needed and created more missing values in
adjacent columns so these were taken out as well.
Tidy & Manipulate Data II
# This is the R chunk for the Tidy & Manipulate Data II
# Here we will create a new column for the offence rate by area
all_data$"Offence Rate per KM2" <- numeric(nrow(all_data))
for (i in 1:nrow(all_data)){
all_data$`Offence Rate per KM2`[i]<-all_data$`Offence Count`[i]/all_data$`Area (km2)`[i]
}
Here to create a new variable we decided to look at the offence rate
by Area in squared kilometeres. I think that this gives valuable insight
when you look at larger regions having higher crime per citizen but
lower crime per km2 as they covered a lot of land that is not settled or
un-utilised.
Scan I
# This is the R chunk for the Scan I
empty_rows_df<-data.frame()
na_rows<-list()
for (i in 1:nrow(all_data)){
if (any(is.na(all_data[i,]))){
empty_rows_df<-rbind(empty_rows_df,all_data[i,])
na_rows<-c(na_rows,i)
}
}
print(empty_rows_df)
# Due to all of these rows containing unique data that is location specific, we should not substitute with other values
# As such we will delete each of these rows
all_data<-na.omit(all_data)
To identify that there are N/A values we search through and each row
to find rows that contain these NA or missing values. Since they are not
being used for calculations that we durastically affect any further
calculations, I have opted to omit these from the data set using
na.omit() function.
Scan II
# This is the R chunk for the Scan II
# Since none of these variables will alter later calculations durastically, we will imput the outliers with the mean value of the column
for (col_name in names(all_data)) {
if (col_name != "Local Government Area" && is.numeric(all_data[[col_name]])) {
col_data <- all_data[[col_name]]
col_mean <- mean(col_data)
col_sd <- sd(col_data)
threshold <- 3
outliers <- abs((col_data - col_mean) / col_sd) > threshold
col_data[outliers] <- col_mean
all_data[[col_name]] <- col_data
}
}
To identify outliers, I ran a for loop that scans through each column
and calculates the mean and standard deviation of each column. We then
calculate a z score and see if the absolute value of the z score is
greater than the outlier by checking it against a threshold of 3. The
most efficient way of dealing with outliers in this data set that has
very minimal instances of outliers and is not being used for intense
calculations, is to use the mean of each column to replace the outlier.
This is all stored in a smaller column and replaces the original column
in the data set at the end of the loop.
Link to Presentation
# This is the R chunk to provide the direct link to your video presentation recorded in Studio
# Please see below link to video
# https://rmit-arc.instructuremedia.com/embed/68dfbb5b-455d-4be0-9df9-6e017a85a5eb
LS0tDQp0aXRsZTogIkRhdGEgV3JhbmdsaW5nIChEYXRhIFByZXByb2Nlc3NpbmcpIg0KYXV0aG9yOiAiQnJheWRlbiBTbWl0aCBzMzcxNzgzNSIgDQpzdWJ0aXRsZTogUHJhY3RpY2FsIGFzc2Vzc21lbnQgMg0KZGF0ZTogIjE1LzEwLzIwMjMiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NCg0KIyMgKipTZXR1cCoqDQoNCmBgYHtyfQ0KDQojIExvYWQgdGhlIG5lY2Vzc2FyeSBwYWNrYWdlcyByZXF1aXJlZCB0byByZXByb2R1Y2UgdGhlIHJlcG9ydC4gRm9yIGV4YW1wbGU6DQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KG1hZ3JpdHRyKQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShkcGx5cikNCg0KYGBgDQoNCiMjICoqU3R1ZGVudCBuYW1lcywgbnVtYmVycyBhbmQgcGVyY2VudGFnZSBvZiBjb250cmlidXRpb25zKioNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KDQojIEFkZCB5b3VyIG5hbWVzLCBudW1iZXJzIGFuZCBwZXJjZW50YWdlIG9mIHlvdXIgY29udHJpYnV0aW9uIGhlcmUuDQpuYTwtIGMoIkJyYXlkZW4gU21pdGgiKQ0Kbm88LSBjKCIgUzM3MTc4MzUiKQ0KcGM8LSBjKCIxMDAlIikNCg0KczwtIGRhdGEuZnJhbWUoY2JpbmQobmEsbm8scGMpKQ0KY29sbmFtZXMocyk8LSBjKCJTdHVkZW50IG5hbWUiLCAiU3R1ZGVudCBudW1iZXIiLCAiUGVyY2VudGFnZSBvZiBjb250cmlidXRpb24iKQ0KDQpzICU+JSBrYmwoY2FwdGlvbiA9ICJHcm91cCBpbmZvcm1hdGlvbiIpICU+JQ0KICBrYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBGLCBodG1sX2ZvbnQgPSAiQ2FtYnJpYSIpDQoNCmBgYA0KDQoNCg0KIyMgKipFeGVjdXRpdmUgU3VtbWFyeSoqDQpBZnRlciBib3RoIGRhdGEgc2V0cyB3ZXJlIGltcG9ydGVkLCBkdWUgdG8gdGhlIHdheSB0aGF0IHRoZSBzZWNvbmQgZGF0YSBzZXQgImxnYV9kYXRhIiB3YXMgZm9ybWF0dGVkLCBvbmUgb2YgdGhlIGNvbHVtbnMgaGFkIHRvIGJlIHJlbmFtZWQgYmVmb3JlIEkgY291bGQgbWVyZ2UgdGhlbSwgYXMgdGhlcmUgd2FzIG5vIG11dHVhbCB2YXJpYWJsZSB0byBqb2luIHRoZW0gYnkuIA0KDQoqIFRoZSBmb3JtYXR0aW5nIG9mIHRoaXMgZGF0YSBzZXQgY29udGludWVkIHRvIGJlIHByb2JsZW1hdGljIHdpdGggYWxsIG9mIHRoZSB1c2FibGUgY29sdW1ucyBuZWVkaW5nIHRvIGJlIHJlbmFtZWQgYXMgdGhlaXIgaGVhZGVycyB3ZXJlIGltcG9ydGVkIGFzIGNlbGxzIGluIHRoZSBkYXRhIGZyYW1lLg0KKiBBZnRlciB0aGlzLCBzZXZlcmFsIGNvbnZlcnNpb25zIHdlcmUgbWFkZSB0byBjaGFuZ2UgdGhlIHZhcmlhYmxlIHR5cGVzIG9mIHNvbWUgdmFyaWFibGVzLg0KKiBJIHRoZW4gZ290IHJpZCBvZiBhbnkgdW5uZWNlc3NhcnkgY29sdW1ucyBhcyB0aGUgZm9ybWF0dGluZyBvZiB0aGUgZGF0YSBzZXQgbWFkZSBpdCBxdWl0ZSB1bnRpZHkgYW5kIG1lc3N5IGFuZCB3YXMgdmVyeSBsaW1pdGluZyBpbiBpdHMgd29ya2FibGUgY2FwYWJpbGl0aWVzDQoqIFdlIGFsc28gdGhlbiBjcmVhdGVkIGEgbmV3IHZhcmlhYmxlIGRlc2NyaWJpbmcgdGhlIHJhdGUgb2YgY3JpbWVzIGJ5IGFyZWEgaW4ga2lsb21ldGVycyBzcXVhcmVkDQoqIFdlIHRoZW4gZ290IHJpZCBvZiBhbnkgTi9BIG9yIG1pc3NpbmcgdmFsdWVzLCBmb2xsb3dlZCBieSByZXBsYWNpbmcgYW55IG91dGxpZXJzIHdpdGggdGhlaXIgcmVzcGVjdGl2ZSBtZWFucw0KKiBMYXN0bHkgd2UgdHJhbnNmb3JtZWQgb25lIG9mIHRoZSB2YXJpYWJsZXMgaW4gYW4gYXR0ZW1wdCB0byBub3JtYWxpemUgdGhlIGRhdGENCjxicj4NCjxicj4NCg0KIyMgKipEYXRhKioNCg0KVGhlIGZpcnN0IGRhdGEgc2V0IHdhcyBkb3dubG9hZGVkIGZyb20gdGhlIENyaW1lIFN0YXRpc3RpY3MgQWdlbmN5IDogaHR0cHM6Ly93d3cuY3JpbWVzdGF0aXN0aWNzLnZpYy5nb3YuYXUvY3JpbWUtc3RhdGlzdGljcy9sYXRlc3QtdmljdG9yaWFuLWNyaW1lLWRhdGEvZG93bmxvYWQtZGF0YQ0KVGhlIGRhdGEgc2V0IHdhcyBvcmlnaW5hbGx5IHRpdGxlZCAiRGF0YSBUYWJsZXMgTEdBIFJlY29yZGVkIE9mZmVuY2VzIFllYXIgRW5kaW5nIEp1bmUgMjAyMyIuIEluIHRoaXMgdmVyeSBkZXNjcmlwdGl2ZSByZXBvcnQsIHRoZSBkZXRhaWxzIG9mIGFsbCByZWNvcmRlZCBjcmltaW5hbCBvZmZlbmNlcyBhcmUga2VwdCBhbmQgc2VwZXJhdGVkIGJ5IG1hbnkgY2F0ZWdvcmllcywgYnV0IG1haW5seSBmb2N1c2VkIGFyb3VuZCB0aGUgcmVnaW9uYWwgZGl2aXNpb24gYnkgTG9jYWwgR292ZXJubWVudCBBcmVhIChMR0EpDQoNClRoZSBzZWNvbmQgZGF0YSBzZXQgd2FzIGRvd25sb2FkZWQgZnJvbSB0aGUgQXVzdHJhbGlhbiBCdXJlYXUgb2YgU3RhdGlzdGljczoNCmh0dHBzOi8vd3d3LmFicy5nb3YuYXUvc3RhdGlzdGljcy9wZW9wbGUvcG9wdWxhdGlvbi9yZWdpb25hbC1wb3B1bGF0aW9uL2xhdGVzdC1yZWxlYXNlIA0KVGhlIGRhdGEgc2V0IHdhcyBvcmdpbmFsbHkgdGl0bGVkICJQb3B1bGF0aW9uIGVzdGltYXRlcyBhbmQgY29tcG9uZW50cyBieSBMR0EgMjAyMSB0byAyMDIyIC0gUmV2aXNlZC4gVGhpcyBkYXRhIHNldCBkZXNjcmliZXMgZGlmZmVyZW50IGRlbW9ncmFwaGljIGZlYXR1cmVzIG9mIGFsbCBMb2NhbCBHb3Zlcm5tZW50IEFyZWFzIGFjcm9zcyBBdXN0cmFsaWEsIGhvd2V2ZXIgd2Ugb25seSB1c2VkICJUYWJsZSAyIiBhcyB0aGF0IHdhcyB0aGUgdGFibGUgdXNlZCB0byBkZXNjcmliZWQgVmljdG9yaWFuIExHQXMuDQoNCg0KYGBge3IsIHJlc3VsdHM9RkFMU0V9DQoNCiMgSW1wb3J0IHRoZSBkYXRhLCBwcm92aWRlIHlvdXIgUiBjb2RlcyBoZXJlLg0KY3JpbWVfZGF0YTwtIHJlYWRfZXhjZWwoIkRhdGFfVGFibGVzX0xHQV9SZWNvcmRlZF9PZmZlbmNlc19ZZWFyX0VuZGluZ19KdW5lXzIwMjMueGxzeCIsc2hlZXQgPSAiVGFibGUgMDEiKQ0KbGdhX2RhdGE8LXJlYWRfZXhjZWwoIjMyMTgwRFMwMDAyXzIwMjEtMjJyLnhsc3giLHNoZWV0ID0gIlRhYmxlIDIiKQ0KbGdhX2RhdGE8LWxnYV9kYXRhICU+JQ0KICByZW5hbWUoIkxvY2FsIEdvdmVybm1lbnQgQXJlYSIgPSBvbmVfb2YoIi4uLjIiKSkNCmFsbF9kYXRhPC1sZWZ0X2pvaW4oY3JpbWVfZGF0YSxsZ2FfZGF0YSwgYnkgPSAiTG9jYWwgR292ZXJubWVudCBBcmVhIikNCg0KaGVhZChhbGxfZGF0YSkNCmBgYA0KDQo8YnI+DQo8YnI+DQoNCiMjICoqVW5kZXJzdGFuZCoqIA0KDQpgYGB7cn0NCiMgVGhpcyBpcyB0aGUgUiBjaHVuayBmb3IgdGhlIFVuZGVyc3RhbmQgU2VjdGlvbg0KYWxsX2RhdGE8LSBhbGxfZGF0YSAlPiUNCiAgcmVuYW1lKA0KICAgICIyMDIxIEVSUCIgPSAiLi4uMyIsDQogICAgIjIwMjIgRVJQIiA9ICIuLi40IiwNCiAgICAiRVJQIENoYW5nZSIgPSAiLi4uNiIsDQogICAgIkVSUCBDaGFuZ2UgUmF0aW8iID0gIi4uLjciLA0KICAgICJOYXR1cmFsIEluY3JlYXNlIiA9ICIuLi45IiwNCiAgICAiSW50ZXJuYWwgTWlncmF0aW9uIiA9ICIuLi4xMCIsDQogICAgIkV4dGVybmFsIE1pZ3JhdGlvbiIgPSAiLi4uMTEiLA0KICAgICJBcmVhIChrbTIpIiA9ICIuLi4xMyIsDQogICAgIlBlcnNvbnMgcGVyIGttMiIgPSAiLi4uMTQiDQogICkNCiMgc3RyKGFsbF9kYXRhKQ0KDQojIEhlcmUgdGhlcmUgYXJlIHNvbWUgY2hhcmFjdGVyIHZhcmlhYmxlcyB0aGF0IHdlIHNob3VsZCBjaGFuZ2UgdG8gbnVtYmVyDQphbGxfZGF0YSRgMjAyMSBFUlBgPC1hcy5udW1lcmljKGFsbF9kYXRhJGAyMDIxIEVSUGApDQphbGxfZGF0YSRgMjAyMiBFUlBgPC1hcy5udW1lcmljKGFsbF9kYXRhJGAyMDIyIEVSUGApDQphbGxfZGF0YSRgRVJQIENoYW5nZWA8LWFzLm51bWVyaWMoYWxsX2RhdGEkYEVSUCBDaGFuZ2VgKQ0KYWxsX2RhdGEkYEVSUCBDaGFuZ2UgUmF0aW9gPC1hcy5udW1lcmljKGFsbF9kYXRhJGBFUlAgQ2hhbmdlIFJhdGlvYCkNCmFsbF9kYXRhJGBOYXR1cmFsIEluY3JlYXNlYDwtYXMubnVtZXJpYyhhbGxfZGF0YSRgTmF0dXJhbCBJbmNyZWFzZWApDQphbGxfZGF0YSRgSW50ZXJuYWwgTWlncmF0aW9uYDwtYXMubnVtZXJpYyhhbGxfZGF0YSRgSW50ZXJuYWwgTWlncmF0aW9uYCkNCmFsbF9kYXRhJGBFeHRlcm5hbCBNaWdyYXRpb25gPC1hcy5udW1lcmljKGFsbF9kYXRhJGBFeHRlcm5hbCBNaWdyYXRpb25gKQ0KYWxsX2RhdGEkYEFyZWEgKGttMilgPC1hcy5udW1lcmljKGFsbF9kYXRhJGBBcmVhIChrbTIpYCkNCmFsbF9kYXRhJGBQZXJzb25zIHBlciBrbTJgPC1hcy5udW1lcmljKGFsbF9kYXRhJGBQZXJzb25zIHBlciBrbTJgKQ0KDQojIFdlIHdpbGwgYWxzbyBjb252ZXJ0IFBvbGljZSBSZWdpb24gdG8gZmFjdG9yIHZhcmlhYmxlDQphbGxfZGF0YSRgUG9saWNlIFJlZ2lvbmA8LWFzLmZhY3RvcihhbGxfZGF0YSRgUG9saWNlIFJlZ2lvbmApDQoNCnN0cihhbGxfZGF0YSkNCmBgYA0KQWZ0ZXIgaW5pdGlhbGx5IHJ1bm5pbmcgdGhlIHN0cigpIGZ1bmN0aW9uIHdlIGNvdWxkIHNlZSB0aGF0IGFsbW9zdCBhbGwgb2YgdGhlIHZhcmlhYmxlcyBoYWQgYmVlbiByZWFkIGluIGFzIGNoYXJhY3RlciB2YXJpYWJsZXMuIEhvd2V2ZXIgbW9zdCBvZiB0aGVtIHdlcmUgbnVtZXJpYyB3aGljaCB3ZXJlIGNoYW5nZWQgdXNpbmcgdGhlIGFzLm51bWVyaWMoKSBmdW5jdGlvbiBhcyB3ZWxsIGFzIGFkanVzdGluZyB0aGUgIlBvbGljZSBSZWdpb24iIHRvIGJlIGEgRmFjdG9yIFZhcmlhYmxlLiBUaGVyZSB3ZXJlIGFsc28gc2V2ZXJhbCBlbXB0eSBjb2x1bW5zIHRoYXQgd2VyZSBjbGFzc2lmaWVkIGFzIGxvZ2ljYWwgdmFyaWFibGVzIGhvd2V2ZXIgdGhlc2Ugd2lsbCBhbGwgYmUgcmVtb3ZlZCBpbiB0aGUgbmV4dCBzZWN0aW9uIGFzIHRoZXkgYXJlIGFsbCBjb250YWluaW5nIE5BIHZhbHVlcy4NCg0KPGJyPg0KPGJyPg0KDQojIwkqKlRpZHkgJiBNYW5pcHVsYXRlIERhdGEgSSAqKg0KDQoNCmBgYHtyfQ0KIyBUaGlzIGlzIHRoZSBSIGNodW5rIGZvciB0aGUgVGlkeSAmIE1hbmlwdWxhdGUgRGF0YSBJIA0KDQojIFRoaXMgZGF0YSBhbHNvIHJlcHJlc2VudHMgY3JpbWUgZnJvbSBhbGwgeWVhcnMgYmV0d2VlbiAyMDE0LTIwMjMsIGhvd2V2ZXIgd2UgYXJlIG9ubHkgaW50ZXJlc3RlZCBpbiAyMDIxLzIwMjIuDQojIFNpbmNlIHdlIGhhdmUgY29sdW1ucyBmb3IgMjAyMSBkYXRhIHdlIHdpbGwgZGVsZXRlIGFsbCByb3dzIGV4Y2VwdCBmb3IgdGhvc2UgY29udGFpbmluZyAyMDIyIGRhdGENCmFsbF9kYXRhPC1hbGxfZGF0YVthbGxfZGF0YSRZZWFyID09ICIyMDIyIixdDQoNCiMgQWxsIG9mIHRoZXNlIHJlY29yZGluZ3Mgd2VyZSB0YWtlbiBpbiBKdW5lIGFzIHdlbGwgc28gd2Ugd2lsbCBlbGltaW5hdGUgdGhlIG1vbnRoIGNvbHVtbiBhcyBpdCBpcyBubyBsb25nZXIgbmVlZGVkDQphbGxfZGF0YTwtIGFsbF9kYXRhJT4lDQogIHNlbGVjdCgtIlllYXIgZW5kaW5nIiwtIkF1c3RyYWxpYW4gQnVyZWF1IG9mIFN0YXRpc3RpY3MiLC0iLi4uNSIsLSIuLi44IiwtIi4uLjEyIikNCg0KIyBXZSB3aWxsIGFsc28gZGVsZXRlIGFueSByb3cgdGhhdCBoYXMgIlRvdGFsIiBhcyBpdCBkb2VzIG5vdCByZXByZXNlbnQgYSBzaW5nbGUgTG9jYWwgR292ZXJubWVudCBBcmVhDQphbGxfZGF0YTwtYWxsX2RhdGFbIShhbGxfZGF0YSRgTG9jYWwgR292ZXJubWVudCBBcmVhYCAlaW4lICJUb3RhbCIpLF0NCg0KYGBgDQoNCkJvdGggb2YgdGhlc2UgZGF0YXNldHMgd2VyZSBpbml0aWFsbHkgcXVpdGUgbWVzc3kgd2hlbiBpbXBvcnRlZC4gVG8gYmVnaW4gd2l0aCB0aGUgZmlyc3QgZGF0YSBzZXQgaGFkIGEgZGlmZmVyZW50IHJvdyBmb3IgZWFjaCB5ZWFybHkgb2JzZXJ2YXRpb24gb2YgdGhlIHNhbWUgZGF0YSBzZXQgd2hlcmUgdGhleSBzaG91bGQgaGF2ZSBiZWVuIHN0b3JlZCBpbiBjb2x1bW5zLiBTaW5jZSB3ZSB3ZXJlIG9ubHkgbG9va2luZyBhdCAyMDIxIGFuZCAyMDIyIHllYXJzIHdoaWNoIHdlcmUgYWxyZWFkeSBzdG9yZWQgaW4gdGhlaXIgb3duIGNvbHVtbnMgaW4gdGhlIHNlY29uZCBkYXRhIHNldCwgd2UgZGVsZXRlZCBhbGwgcm93cyBleGNlcHQgZm9yIDIwMjIuIFdlIGFsc28gZGVsZXRlZCBtYW55IGNvbHVtbnMgdGhhdCB3ZXJlIGRlc2lnbmVkIHRvIGJlIGxpbmUgYnJlYWtzIGluIGJldHdlZW4gdGhlIG9yaWdpbmFsIGRhdGEgc2hlZXQgaW4gZXhjZWwuIFdlIHRoZW4gZGVsZXRlZCB0aGUgIlllYXIgZW5kaW5nIiB2YXJpYWJsZSBhcyBldmVyeSB5ZWFyIGhhZCBlbmRlZCBpbiBKdW5lIHNvIGl0IHdhcyByZWR1bmRhbnQgdG8gaGF2ZSB0aGF0IHZhbHVlIGluIHRoZXJlLiBUaGVyZSB3ZXJlIGFsc28gc29tZSByb3dzIHRoYXQgaGFkICJUb3RhbCIgd2hpY2ggZ3JvdXBlZCB0aGUgZGF0YSBieSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGJ1dCB3YXMgbm90IG5lZWRlZCBhbmQgY3JlYXRlZCBtb3JlIG1pc3NpbmcgdmFsdWVzIGluIGFkamFjZW50IGNvbHVtbnMgc28gdGhlc2Ugd2VyZSB0YWtlbiBvdXQgYXMgd2VsbC4NCg0KPGJyPg0KPGJyPg0KDQojIyAqKlRpZHkgJiBNYW5pcHVsYXRlIERhdGEgSUkqKiANCg0KYGBge3J9DQojIFRoaXMgaXMgdGhlIFIgY2h1bmsgZm9yIHRoZSBUaWR5ICYgTWFuaXB1bGF0ZSBEYXRhIElJIA0KDQojIEhlcmUgd2Ugd2lsbCBjcmVhdGUgYSBuZXcgY29sdW1uIGZvciB0aGUgb2ZmZW5jZSByYXRlIGJ5IGFyZWENCmFsbF9kYXRhJCJPZmZlbmNlIFJhdGUgcGVyIEtNMiIgPC0gbnVtZXJpYyhucm93KGFsbF9kYXRhKSkNCg0KZm9yIChpIGluIDE6bnJvdyhhbGxfZGF0YSkpew0KICBhbGxfZGF0YSRgT2ZmZW5jZSBSYXRlIHBlciBLTTJgW2ldPC1hbGxfZGF0YSRgT2ZmZW5jZSBDb3VudGBbaV0vYWxsX2RhdGEkYEFyZWEgKGttMilgW2ldDQp9DQoNCmBgYA0KDQpIZXJlIHRvIGNyZWF0ZSBhIG5ldyB2YXJpYWJsZSB3ZSBkZWNpZGVkIHRvIGxvb2sgYXQgdGhlIG9mZmVuY2UgcmF0ZSBieSBBcmVhIGluIHNxdWFyZWQga2lsb21ldGVyZXMuIEkgdGhpbmsgdGhhdCB0aGlzIGdpdmVzIHZhbHVhYmxlIGluc2lnaHQgd2hlbiB5b3UgbG9vayBhdCBsYXJnZXIgcmVnaW9ucyBoYXZpbmcgaGlnaGVyIGNyaW1lIHBlciBjaXRpemVuIGJ1dCBsb3dlciBjcmltZSBwZXIga20yIGFzIHRoZXkgY292ZXJlZCBhIGxvdCBvZiBsYW5kIHRoYXQgaXMgbm90IHNldHRsZWQgb3IgdW4tdXRpbGlzZWQuDQoNCjxicj4NCjxicj4NCg0KIyMJKipTY2FuIEkgKioNCg0KYGBge3J9DQojIFRoaXMgaXMgdGhlIFIgY2h1bmsgZm9yIHRoZSBTY2FuIEkNCmVtcHR5X3Jvd3NfZGY8LWRhdGEuZnJhbWUoKQ0KbmFfcm93czwtbGlzdCgpDQoNCmZvciAoaSBpbiAxOm5yb3coYWxsX2RhdGEpKXsNCiAgaWYgKGFueShpcy5uYShhbGxfZGF0YVtpLF0pKSl7DQogICAgZW1wdHlfcm93c19kZjwtcmJpbmQoZW1wdHlfcm93c19kZixhbGxfZGF0YVtpLF0pDQogICAgbmFfcm93czwtYyhuYV9yb3dzLGkpDQogIH0NCn0NCnByaW50KGVtcHR5X3Jvd3NfZGYpDQoNCg0KIyBEdWUgdG8gYWxsIG9mIHRoZXNlIHJvd3MgY29udGFpbmluZyB1bmlxdWUgZGF0YSB0aGF0IGlzIGxvY2F0aW9uIHNwZWNpZmljLCB3ZSBzaG91bGQgbm90IHN1YnN0aXR1dGUgd2l0aCBvdGhlciB2YWx1ZXMNCiMgQXMgc3VjaCB3ZSB3aWxsIGRlbGV0ZSBlYWNoIG9mIHRoZXNlIHJvd3MNCmFsbF9kYXRhPC1uYS5vbWl0KGFsbF9kYXRhKQ0KYGBgDQoNClRvIGlkZW50aWZ5IHRoYXQgdGhlcmUgYXJlIE4vQSB2YWx1ZXMgd2Ugc2VhcmNoIHRocm91Z2ggYW5kIGVhY2ggcm93IHRvIGZpbmQgcm93cyB0aGF0IGNvbnRhaW4gdGhlc2UgTkEgb3IgbWlzc2luZyB2YWx1ZXMuIFNpbmNlIHRoZXkgYXJlIG5vdCBiZWluZyB1c2VkIGZvciBjYWxjdWxhdGlvbnMgdGhhdCB3ZSBkdXJhc3RpY2FsbHkgYWZmZWN0IGFueSBmdXJ0aGVyIGNhbGN1bGF0aW9ucywgSSBoYXZlIG9wdGVkIHRvIG9taXQgdGhlc2UgZnJvbSB0aGUgZGF0YSBzZXQgdXNpbmcgbmEub21pdCgpIGZ1bmN0aW9uLg0KPGJyPg0KPGJyPg0KDQojIwkqKlNjYW4gSUkqKg0KDQpgYGB7cn0NCiMgVGhpcyBpcyB0aGUgUiBjaHVuayBmb3IgdGhlIFNjYW4gSUkNCg0KIyBTaW5jZSBub25lIG9mIHRoZXNlIHZhcmlhYmxlcyB3aWxsIGFsdGVyIGxhdGVyIGNhbGN1bGF0aW9ucyBkdXJhc3RpY2FsbHksIHdlIHdpbGwgaW1wdXQgdGhlIG91dGxpZXJzIHdpdGggdGhlIG1lYW4gdmFsdWUgb2YgdGhlIGNvbHVtbg0KDQpmb3IgKGNvbF9uYW1lIGluIG5hbWVzKGFsbF9kYXRhKSkgew0KICBpZiAoY29sX25hbWUgIT0gIkxvY2FsIEdvdmVybm1lbnQgQXJlYSIgJiYgaXMubnVtZXJpYyhhbGxfZGF0YVtbY29sX25hbWVdXSkpIHsNCiAgICBjb2xfZGF0YSA8LSBhbGxfZGF0YVtbY29sX25hbWVdXQ0KICAgIGNvbF9tZWFuIDwtIG1lYW4oY29sX2RhdGEpDQogICAgY29sX3NkIDwtIHNkKGNvbF9kYXRhKQ0KICAgIHRocmVzaG9sZCA8LSAzDQoNCiAgICBvdXRsaWVycyA8LSBhYnMoKGNvbF9kYXRhIC0gY29sX21lYW4pIC8gY29sX3NkKSA+IHRocmVzaG9sZA0KICAgIGNvbF9kYXRhW291dGxpZXJzXSA8LSBjb2xfbWVhbg0KICAgIA0KICAgIGFsbF9kYXRhW1tjb2xfbmFtZV1dIDwtIGNvbF9kYXRhDQogIH0NCn0NCg0KDQoNCmBgYA0KDQpUbyBpZGVudGlmeSBvdXRsaWVycywgSSByYW4gYSBmb3IgbG9vcCB0aGF0IHNjYW5zIHRocm91Z2ggZWFjaCBjb2x1bW4gYW5kIGNhbGN1bGF0ZXMgdGhlIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBlYWNoIGNvbHVtbi4gV2UgdGhlbiBjYWxjdWxhdGUgYSB6IHNjb3JlIGFuZCBzZWUgaWYgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSB6IHNjb3JlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgb3V0bGllciBieSBjaGVja2luZyBpdCBhZ2FpbnN0IGEgdGhyZXNob2xkIG9mIDMuIFRoZSBtb3N0IGVmZmljaWVudCB3YXkgb2YgZGVhbGluZyB3aXRoIG91dGxpZXJzIGluIHRoaXMgZGF0YSBzZXQgdGhhdCBoYXMgdmVyeSBtaW5pbWFsIGluc3RhbmNlcyBvZiBvdXRsaWVycyBhbmQgaXMgbm90IGJlaW5nIHVzZWQgZm9yIGludGVuc2UgY2FsY3VsYXRpb25zLCBpcyB0byB1c2UgdGhlIG1lYW4gb2YgZWFjaCBjb2x1bW4gdG8gcmVwbGFjZSB0aGUgb3V0bGllci4gVGhpcyBpcyBhbGwgc3RvcmVkIGluIGEgc21hbGxlciBjb2x1bW4gYW5kIHJlcGxhY2VzIHRoZSBvcmlnaW5hbCBjb2x1bW4gaW4gdGhlIGRhdGEgc2V0IGF0IHRoZSBlbmQgb2YgdGhlIGxvb3AuDQoNCjxicj4NCjxicj4NCg0KIyMJKipUcmFuc2Zvcm0gKioNCg0KYGBge3J9DQojIFRoaXMgaXMgdGhlIFIgY2h1bmsgZm9yIHRoZSBUcmFuc2Zvcm0gU2VjdGlvbg0KIyBUaGUgZGF0YSB0aGF0IHdlIHdvdWxkIGxpa2UgdG8gc2VlIGlzIHRoZSBncmFwaCBvZiB0aGUgUmF0ZSBwZXIgMTAwLDAwMA0KaGlzdChhbGxfZGF0YSRgUmF0ZSBwZXIgMTAwLDAwMCBwb3B1bGF0aW9uYCwgbWFpbiA9ICJSYXRlIG9mIGNyaW1lIHBlciAxMDAsMDAwIiwgeGxhYj0iT3JnaW5hbCBWYWx1ZXMiKQ0KDQojIFNpbmNlIHRoZSBkYXRhIGlzIHJpZ2h0IHNrZXdlZCwgd2Ugd2lsbCB1c2UgdGhlIHNxcnQgZnVuY3Rpb24gdG8gbm9ybWFsaXNlIHRoZSBkYXRhDQphbGxfZGF0YSRgUmF0ZSBwZXIgMTAwLDAwMCBwb3B1bGF0aW9uYDwtc3FydChhbGxfZGF0YSRgUmF0ZSBwZXIgMTAwLDAwMCBwb3B1bGF0aW9uYCkNCmhpc3QoYWxsX2RhdGEkYFJhdGUgcGVyIDEwMCwwMDAgcG9wdWxhdGlvbmAsIG1haW4gPSAiUmF0ZSBvZiBjcmltZSBwZXIgMTAwLDAwMCAtIE5vcm1hbGlzZWQiLCB4bGFiID0gIk5vcm1hbGlzZWQgVmFsdWVzIikNCmBgYA0KSGVyZSB3ZSB3aXNoIHRvIHBsb3QgYSBoaXN0b2dyYW0gb2YgdGhlIHJhdGUgb2Ygb2ZmZW5jZXMgcGVyIDEwMCwwMDAgY2l0aXplbnMgaW4gdGhlIGxvY2FsIGdvdmVybm1lbnQgYXJlYS4gV2UgY2FuIHNlZSBmcm9tIHRoZSBvcmlnaW5hbCB2aXN1YWwgdGhhdCB0aGUgZGF0YSBpcyByaWdodCBza2V3ZWQgYW5kIG5lZWRzIHRvIGJlIGNvcnJlY3RlZC4gVG8gZG8gdGhpcyB3ZSBpbml0aWFsbHkgdXNlZCB0aGUgbG9nKCkgZnVuY3Rpb24gaG93ZXZlciBpdCBkaWQgbm90IGdpdmUgdXMgdGhlIGRlc2lyZWQgb3V0Y29tZSwgc28gaW5zdGVhZCB3ZSBoYXZlIG9wdGVkIHdpdGggdGhlIHNxdWFyZSByb290IGZ1bmN0aW9uIHNxcnQoKSB3aGljaCBnaXZlcyB1cyBhIHZlcnkgbm9ybWFsaXNlZCBkYXRhIHNldCB3aGljaCB0YWtlcyB0aGUgc2hhcGUgb2YgYSB0eXBpY2FsIGJlbGwgY3VydmUuDQoNCjxicj4NCjxicj4NCg0KIyMJKipMaW5rIHRvIFByZXNlbnRhdGlvbiAqKg0KDQpgYGB7cn0NCiMgVGhpcyBpcyB0aGUgUiBjaHVuayB0byBwcm92aWRlIHRoZSBkaXJlY3QgbGluayB0byB5b3VyIHZpZGVvIHByZXNlbnRhdGlvbiByZWNvcmRlZCBpbiBTdHVkaW8NCiMgUGxlYXNlIHNlZSBiZWxvdyBsaW5rIHRvIHZpZGVvDQojIGh0dHBzOi8vcm1pdC1hcmMuaW5zdHJ1Y3R1cmVtZWRpYS5jb20vZW1iZWQvNjhkZmJiNWItNDU1ZC00YmUwLTlkZjktNmUwMTdhODVhNWViIA0KDQpgYGANCg0KPGJyPg0KPGJyPg==