Submission Steps:

1 . Prepare Assignment 2 report using this R Markdown template. Feel free to DELETE the instructional text provided in the template.

Once you finalise your report, run all R chunks and Preview your notebook in HTML (by clicking Preview). Make sure your code and outputs are visible.

2 . Upload the report as a PDF file via the File Upload tab under the Assignment 2 page in CANVAS (see instructions file for details) after you attach the file click Submit assignment.

The easiest way to produce a PDF file from the RMarkdown is to Run all R chunks, then Preview your notebook in HTML (by clicking Preview) → Open in Browser (Chrome) → Right click on the report in Chrome → Click Print and Select the Destination Option to Save as PDF.

3 . Publish the report to RPubs (see here) and enter your report’s RPubs URL into the Website URL tab under Assignment 2 RPubs Link Submission page in Canvas (see instructions file for details) and submit this too. This online version of the report will be used for marking. Failure to submit your link will delay your feedback and risk late penalties.

If you have any questions regarding the assignment instructions and the R Markdown template, please post it on discussion board.

Required packages

Provide the packages required to reproduce the report. Make sure you fulfilled the minimum requirement #10.

# This is the R chunk for the required packages
library(tidyr)

library(dplyr)

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(editrules)
Loading required package: igraph

Attaching package: ‘igraph’

The following objects are masked from ‘package:dplyr’:

    as_data_frame, groups, union

The following object is masked from ‘package:tidyr’:

    crossing

The following objects are masked from ‘package:stats’:

    decompose, spectrum

The following object is masked from ‘package:base’:

    union


Attaching package: ‘editrules’

The following objects are masked from ‘package:igraph’:

    blocks, normalize

The following object is masked from ‘package:dplyr’:

    contains

The following objects are masked from ‘package:tidyr’:

    contains, separate
library(deducorrect)

library(outliers)

Executive Summary

In your own words, provide a brief summary of the preprocessing. Explain the steps that you have taken to preprocess your data. Write this section last after you have performed all data preprocessing. (Word count Max: 300 words)

Data

A clear description of data sets, their sources, and variable descriptions should be provided. In this section, you must also provide the R codes with outputs (head of data sets) that you used to import/read/scrape the data set. You need to fulfil the minimum requirement #1 and merge at least two data sets to create the one you are going to work on. In addition to the R codes and outputs, you need to explain the steps that you have taken.

# This is the R chunk for the Data Section

## Executive Summary
#This report provides the preprocessing of 2 datasets, which contains methods to merge datasets, convert variable type, label factor variable, reshape data into a tidy format, mutate new variable, scan outliers for numeric variables, transform data, scan errors (missing values, special values, obvious errors, and inconsistency) and use the technique to deal with errors (missing values, special values, obvious errors, and inconsistency) by only using packages of tidyr, dplyr, editrules, deducorrect, and outliers. This report aims to provide a sample of how to preprocess datasets, the source of datasets is all come from the government of VIC https://www.vic.gov.au/, they are all open and have a Creative Commons Licence. 


## Data

#Import dataset from website, this dataset is from the government of victoria and it's source website is: https://discover.data.vic.gov.au/dataset/all-schools-fte-enrolments-feb-2015. This dataset contains information collected from the February 2014 school census of Victorian schools until February 2015. This dataset contains 54 variables but we are going to subset to 9 variables otherwise it will be too large and when we merge variables together or merge two datasets together, R will reports Error: vector memory exhausted (limit reached?). After we subset the data set, there will be 9 variables left: 

#"Education_Sector":It refers to educational sector.
#"Entity_Type":It refers to type of school district.       
#"School_No":It refers to the code that represent the school.
#"School_Name":It refers to the name of school.         
#"School_Type":It refers to the type of school.         
#"School_Status":It refers to the status of school.
#"Prep.Males.Total..":It refers to the total number of preparatory male student.
#"Prep.Females.Total..":It refers to the total number of preparatory female student.
#"Prep.Total..":It refers to the total number of preparatory student. 

#Import dataset from website.
url <- "http://www.education.vic.gov.au/Documents/about/research/datavic/dv171-Feb2015FTEenrolments.csv"
All_Schools_FTE_enrolments_Feb_2015 <- read.csv(url, stringsAsFactors = FALSE)

#We need to subset data because this dataset is too big, if we don't subset dataset, then when we merge variables together or merge two datasets together, R will reports Error: vector memory exhausted (limit reached?).
All_Schools_FTE_enrolments_Feb_2015 <- subset(All_Schools_FTE_enrolments_Feb_2015, select = Education_Sector:Prep.Total..)

head(All_Schools_FTE_enrolments_Feb_2015)



#Import dataset from another website, this dataset is from the government of victoria and it's source website is: https://discover.data.vic.gov.au/dataset/all-schools-fte-enrolments-feb-2016. This dataset contains information collected from the February 2015 school census of Victorian schools until February 2016. This dataset also contains 54 variables but we are going to subset to 9 variables due to the problem of large dataset. And these 9 variables are the same as the previous dataset, it means that they have the same variable and also those variables have the same meaning.

#Import dataset from website.
url <- "http://www.education.vic.gov.au/Documents/about/research/datavic/dv214-allschoolsfetenrolfeb2016.csv"
All_Schools_FTE_enrolments_Feb_2016 <- read.csv(url, stringsAsFactors = FALSE)

#We use anti_join() function to obtain the different data from student enrolments in 2015 (New data), because we woudl like merge additional data from student enrolments in 2016 with student enrolments in 2016 in next step.
New_All_Schools_FTE_enrolments_Feb_2016 <- anti_join(All_Schools_FTE_enrolments_Feb_2016, All_Schools_FTE_enrolments_Feb_2015, by = "School_Name")

#The same situation in this one, we have to minimize data otherwise, R will generate error when merge 2 dataset because they are too large.
New_All_Schools_FTE_enrolments_Feb_2016 <- subset(New_All_Schools_FTE_enrolments_Feb_2016, select = Education_Sector:Prep.Total..)

head(New_All_Schools_FTE_enrolments_Feb_2016)

#We use bind_rows() function to merge two datasets because they have the same variables.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students <- bind_rows(All_Schools_FTE_enrolments_Feb_2015, New_All_Schools_FTE_enrolments_Feb_2016)

head(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students)

Tidy & Manipulate Data I

Explain why your data (or one of the data sets) doesn’t conform the tidy data principles (minimum requirement #5). Apply the required steps to reshape the data into a tidy format. In addition to the R codes and outputs, explain everything that you do in this step.

# This is the R chunk for the Tidy & Manipulate Data I 

#We put this part (Tidy & Manipulate Data I) prior to the (Understand) part is because there will be some variables created after we tidy this dataset and it is better to convert variable type, rename variable, rearrange variables after we set down the dataset. 



#The problem of this dataset is that the column names are not names of variables, but values of a variable. In this case, the column names "Prep.Males.Total..", and "Prep.Females.Total.." represent values of the gender variable, and each row represents two observations, not one. 
head(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students)

#Therefore, we use gather() function to merge two variables into a factor variable and also create a new variable which is called "Number_of_students".
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2 <- All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students %>%
gather(`Prep.Males.Total..`, `Prep.Females.Total..`, key = "Gender", value = "Number_of_students")

head(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2)
NA
NA

Understand

Summarise the types of variables and data structures, check the attributes in the data and apply proper data type conversions. In addition to the R codes and outputs, explain briefly the steps that you have taken. In this section, show that you have fulfilled minimum requirements 2-4.

# This is the R chunk for the Understand Section

#Rearrange and rename and rearrange variables
#We first check the order of variables. 
str(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2)
'data.frame':   4502 obs. of  9 variables:
 $ Education_Sector  : chr  "Catholic" "Catholic" "Catholic" "Catholic" ...
 $ Entity_Type       : int  2 2 2 2 2 2 2 2 2 2 ...
 $ School_No         : int  20 25 26 28 29 30 33 35 60 77 ...
 $ School_Name       : chr  "Parade College" "Simonds Catholic College" "Christian Brothers' College St Kilda" "St Patrick's College Ballarat" ...
 $ School_Type       : chr  "Secondary" "Secondary" "Secondary" "Secondary" ...
 $ School_Status     : chr  "O" "O" "O" "O" ...
 $ Prep.Total..      : num  0 0 0 0 34 44 0 0 38 39 ...
 $ Gender            : chr  "Prep.Males.Total.." "Prep.Males.Total.." "Prep.Males.Total.." "Prep.Males.Total.." ...
 $ Number_of_students: num  0 0 0 0 15 19 0 0 22 15 ...
#We use select() function to rearrange the order of variables.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2 <- All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2 %>% select(School_Name, School_No, School_Type, School_Status, Education_Sector, Entity_Type, Gender, Number_of_students, Prep.Total..)

#Given that we gather two variables together to build up a factor variable "Gender". We should rename the levels of "Gender".
#Then, use levels() function to check the level name of this variable.
levels(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Gender)
NULL
#We use label() function to re-label the name of levels in a factor variable.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Gender <- factor(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Gender,levels = c("Prep.Females.Total..","Prep.Males.Total.."),
                                                                                     labels = c("Female","Male"))

#We also notice that the variable name of "Prep.Total.." doesn't look good (because there are some ".." in the name) and "Number_of_students" should actually be "Number_of_pre.student".
#We use rename() function to rename variables.                              
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2 <- All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2 %>% 
  rename(
    Total_number_of_pre.student_for_school = Prep.Total..
    , Number_of_pre.student = Number_of_students
  )

#Check the variables and order again, this also prove that this dataset contains multiple data types (numerics, characters, factors).
str(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2)
'data.frame':   4502 obs. of  9 variables:
 $ School_Name                           : chr  "Parade College" "Simonds Catholic College" "Christian Brothers' College St Kilda" "St Patrick's College Ballarat" ...
 $ School_No                             : int  20 25 26 28 29 30 33 35 60 77 ...
 $ School_Type                           : chr  "Secondary" "Secondary" "Secondary" "Secondary" ...
 $ School_Status                         : chr  "O" "O" "O" "O" ...
 $ Education_Sector                      : chr  "Catholic" "Catholic" "Catholic" "Catholic" ...
 $ Entity_Type                           : int  2 2 2 2 2 2 2 2 2 2 ...
 $ Gender                                : Factor w/ 2 levels "Female","Male": 2 2 2 2 2 2 2 2 2 2 ...
 $ Number_of_pre.student                 : num  0 0 0 0 15 19 0 0 22 15 ...
 $ Total_number_of_pre.student_for_school: num  0 0 0 0 34 44 0 0 38 39 ...
#Convert variable type
#Notice that "Education_Sector" has some values are the same, so try to covert it into factor variable.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Education_Sector <- as.factor(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Education_Sector)

is.factor(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Education_Sector)
[1] TRUE
#Check the levels of this variable, and the result is that there are only 3 levels. This confirms my guess and this variable should actually be a factor variable.
levels(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Education_Sector)
[1] "Catholic"    "Government"  "Independent"
#Entity_Type is obviously a factor variable but R indicate that as int. So, we need to convert it into factor variable.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Entity_Type <- as.factor(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Entity_Type)

is.factor(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Entity_Type)
[1] TRUE
#To ensure that this variable is a factor variable, we check the levels for this variable and the result is that there are only 2 levels. This confirms my guess and this variable should actually be a factor variable.
levels(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Entity_Type)
[1] "1" "2"
#School_Type is obviously a factor variable but R indicate that as chr. So, we need to convert it into factor variable.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$School_Type <- as.factor(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$School_Type)

is.factor(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$School_Type)
[1] TRUE
#To ensure that this variable is a factor variable, we check the levels for this variable and the result is that there are only 5 levels. This confirms my guess and this variable should actually be a factor variable.
levels(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$School_Type)
[1] "Language"  "Pri/Sec"   "Primary"   "Secondary" "Special"  
#Notice that "School_Status" has some values are the same, so try to covert it into factor variable.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$School_Status <- as.factor(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$School_Status)

is.factor(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$School_Status)
[1] TRUE
#Check the levels of this variable, and the result is that there are only 2 levels. This confirms my guess and this variable should actually be a factor variable.
levels(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$School_Status)
[1] "O" "U"
#This variable has to be integer because it can't be half student.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Number_of_pre.student <- as.integer(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Number_of_pre.student)
is.integer(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Number_of_pre.student)
[1] TRUE
#This variable has to be integer because it can't be half student.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Total_number_of_pre.student_for_school <- as.integer(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Total_number_of_pre.student_for_school)
is.integer(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2$Total_number_of_pre.student_for_school)
[1] TRUE
#Check the varibale type again to make sure everything is good. 
str(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2)
'data.frame':   4502 obs. of  9 variables:
 $ School_Name                           : chr  "Parade College" "Simonds Catholic College" "Christian Brothers' College St Kilda" "St Patrick's College Ballarat" ...
 $ School_No                             : int  20 25 26 28 29 30 33 35 60 77 ...
 $ School_Type                           : Factor w/ 5 levels "Language","Pri/Sec",..: 4 4 4 4 3 3 4 4 3 3 ...
 $ School_Status                         : Factor w/ 2 levels "O","U": 1 1 1 1 1 1 1 1 1 1 ...
 $ Education_Sector                      : Factor w/ 3 levels "Catholic","Government",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ Entity_Type                           : Factor w/ 2 levels "1","2": 2 2 2 2 2 2 2 2 2 2 ...
 $ Gender                                : Factor w/ 2 levels "Female","Male": 2 2 2 2 2 2 2 2 2 2 ...
 $ Number_of_pre.student                 : int  0 0 0 0 15 19 0 0 22 15 ...
 $ Total_number_of_pre.student_for_school: int  0 0 0 0 34 44 0 0 38 39 ...

Tidy & Manipulate Data II

Create/mutate at least one variable from the existing variables (minimum requirement #6). In addition to the R codes and outputs, explain everything that you do in this step.

# This is the R chunk for the Tidy & Manipulate Data II 

#Mutate new variable
#Use mutate() function to create a new variable. This new variable is the sex proportion in terms of male and female for each school. And it's formula is: Sex_proportion_for_the_pre.student_in_school = Number_of_pre.student / Total_number_of_pre.student_for_school.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2 <- mutate(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2,
Sex_proportion_for_the_pre.student_in_school = Number_of_pre.student / Total_number_of_pre.student_for_school
)

#Check if we create "Sex_proportion_for_the_pre.student_in_school" successfully.
str(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2)
'data.frame':   4502 obs. of  10 variables:
 $ School_Name                                 : chr  "Parade College" "Simonds Catholic College" "Christian Brothers' College St Kilda" "St Patrick's College Ballarat" ...
 $ School_No                                   : int  20 25 26 28 29 30 33 35 60 77 ...
 $ School_Type                                 : Factor w/ 5 levels "Language","Pri/Sec",..: 4 4 4 4 3 3 4 4 3 3 ...
 $ School_Status                               : Factor w/ 2 levels "O","U": 1 1 1 1 1 1 1 1 1 1 ...
 $ Education_Sector                            : Factor w/ 3 levels "Catholic","Government",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ Entity_Type                                 : Factor w/ 2 levels "1","2": 2 2 2 2 2 2 2 2 2 2 ...
 $ Gender                                      : Factor w/ 2 levels "Female","Male": 2 2 2 2 2 2 2 2 2 2 ...
 $ Number_of_pre.student                       : int  0 0 0 0 15 19 0 0 22 15 ...
 $ Total_number_of_pre.student_for_school      : int  0 0 0 0 34 44 0 0 38 39 ...
 $ Sex_proportion_for_the_pre.student_in_school: num  NaN NaN NaN NaN 0.441 ...

Scan I

Scan the data for missing values, special values and obvious errors (i.e. inconsistencies). In this step, you should fulfil the minimum requirement #7. In addition to the R codes and outputs, explain your methodology (i.e. explain why you have chosen that methodology and the actions that you have taken to handle these values) and communicate your results clearly.

# This is the R chunk for the Scan I

#Sometimes dataset can have obious errors. For example, sex proportion cannot be negative or beyond 1. For checking these inconsistency, we would like to apply rules to check whether this dataset violates the rule by using editfile() function. And also, we could also apply rules to correct errors by using correctionRules() function. When the number of rules increase, it is better to manage the rules separate from the data. The function of editrules() can check which rules are obeyed or not and allows one to find the minimal set of variables to adapt so that all rules can be obeyed. In addition,correctionRules() function force variables to follow it's constraints so that, it is very helpful when correcting data. In this part, we are going to using editrules() and correctionRules() to deal with inconsistency.

#The first thing is to check the consistency of "Total_number_of_pre.student_for_school" = "Number_of_pre.student" for male + "Number_of_pre.student" for female.
#It is more convenient to check the consistency of "Total_number_of_pre.student_for_school" = "Number_of_pre.student" for male + "Number_of_pre.student" for female by spreading the "Gender" out.
#We find out that there is a variable prevent us to spread "Gender" out in "All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2", which is called "Sex_proportion_for_the_pre.student_in_school". 
#That is because "Sex_proportion_for_the_pre.student_in_school" = "Number_of_pre.student"/"Total_number_of_pre.student_for_school". And when we spread "Gender" out, it will produce many NaN values.
#And this is why we should exclude "Sex_proportion_for_the_pre.student_in_school" first and then spread "Gender" out.
Data_for_checking_inconsistency1 = subset(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2, select = -Sex_proportion_for_the_pre.student_in_school )

#And then we use spread() function to spread it out.
Data_for_checking_inconsistency2 <- spread(Data_for_checking_inconsistency1, key = Gender, value = Number_of_pre.student)

#Import rules into R
Rules1 <- editfile("/Users/macbook/Documents/RMIT-Master of Analytics/Data wrangling/editrules2.txt", type = "all")

Rules1

Edit set:
num1 : Female + Male == Total_number_of_pre.student_for_school 
#Check which value violates the rules, but the weakness is that the data size is too large and R automatically omit some rows.
violatedEdits(Rules1, Data_for_checking_inconsistency2)
      edit
record  num1
  1    FALSE
  2    FALSE
  3    FALSE
  4    FALSE
  5    FALSE
  6    FALSE
  7    FALSE
  8    FALSE
  9    FALSE
  10   FALSE
  11   FALSE
  12   FALSE
  13   FALSE
  14   FALSE
  15   FALSE
  16   FALSE
  17   FALSE
  18   FALSE
  19   FALSE
  20   FALSE
  21   FALSE
  22   FALSE
  23   FALSE
  24   FALSE
  25   FALSE
  26   FALSE
  27   FALSE
  28   FALSE
  29   FALSE
  30   FALSE
  31   FALSE
  32   FALSE
  33   FALSE
  34   FALSE
  35   FALSE
  36   FALSE
  37   FALSE
  38   FALSE
  39   FALSE
  40   FALSE
  41   FALSE
  42   FALSE
  43   FALSE
  44   FALSE
  45   FALSE
  46   FALSE
  47   FALSE
  48   FALSE
  49   FALSE
  50   FALSE
  51   FALSE
  52   FALSE
  53   FALSE
  54   FALSE
  55   FALSE
  56   FALSE
  57   FALSE
  58   FALSE
  59   FALSE
  60   FALSE
  61   FALSE
  62   FALSE
  63   FALSE
  64   FALSE
  65   FALSE
  66   FALSE
  67   FALSE
  68   FALSE
  69   FALSE
  70   FALSE
  71   FALSE
  72   FALSE
  73   FALSE
  74   FALSE
  75   FALSE
  76   FALSE
  77   FALSE
  78   FALSE
  79   FALSE
  80   FALSE
  81   FALSE
  82   FALSE
  83   FALSE
  84   FALSE
  85   FALSE
  86   FALSE
  87   FALSE
  88   FALSE
  89   FALSE
  90   FALSE
  91   FALSE
  92   FALSE
  93   FALSE
  94   FALSE
  95   FALSE
  96   FALSE
  97   FALSE
  98   FALSE
  99   FALSE
  100  FALSE
  101  FALSE
  102  FALSE
  103  FALSE
  104  FALSE
  105  FALSE
  106  FALSE
  107  FALSE
  108  FALSE
  109  FALSE
  110  FALSE
  111  FALSE
  112  FALSE
  113  FALSE
  114  FALSE
  115  FALSE
  116  FALSE
  117  FALSE
  118  FALSE
  119  FALSE
  120  FALSE
  121  FALSE
  122  FALSE
  123  FALSE
  124  FALSE
  125  FALSE
  126  FALSE
  127  FALSE
  128  FALSE
  129  FALSE
  130  FALSE
  131  FALSE
  132  FALSE
  133  FALSE
  134  FALSE
  135  FALSE
  136  FALSE
  137  FALSE
  138  FALSE
  139  FALSE
  140  FALSE
  141  FALSE
  142  FALSE
  143  FALSE
  144  FALSE
  145  FALSE
  146  FALSE
  147  FALSE
  148  FALSE
  149  FALSE
  150  FALSE
  151  FALSE
  152  FALSE
  153  FALSE
  154  FALSE
  155  FALSE
  156  FALSE
  157  FALSE
  158  FALSE
  159  FALSE
  160  FALSE
  161  FALSE
  162  FALSE
  163  FALSE
  164  FALSE
  165  FALSE
  166  FALSE
  167  FALSE
  168  FALSE
  169  FALSE
  170  FALSE
  171  FALSE
  172  FALSE
  173  FALSE
  174  FALSE
  175  FALSE
  176  FALSE
  177  FALSE
  178  FALSE
  179  FALSE
  180  FALSE
  181  FALSE
  182  FALSE
  183  FALSE
  184  FALSE
  185  FALSE
  186  FALSE
  187  FALSE
  188  FALSE
  189  FALSE
  190  FALSE
  191  FALSE
  192  FALSE
  193  FALSE
  194  FALSE
  195  FALSE
  196  FALSE
  197  FALSE
  198  FALSE
  199  FALSE
  200  FALSE
  201  FALSE
  202  FALSE
  203  FALSE
  204  FALSE
  205  FALSE
  206  FALSE
  207  FALSE
  208  FALSE
  209  FALSE
  210  FALSE
  211  FALSE
  212  FALSE
  213  FALSE
  214  FALSE
  215  FALSE
  216  FALSE
  217  FALSE
  218  FALSE
  219  FALSE
  220  FALSE
  221  FALSE
  222  FALSE
  223  FALSE
  224  FALSE
  225  FALSE
  226  FALSE
  227  FALSE
  228  FALSE
  229  FALSE
  230  FALSE
  231  FALSE
  232  FALSE
  233  FALSE
  234  FALSE
  235  FALSE
  236  FALSE
  237  FALSE
  238  FALSE
  239  FALSE
  240  FALSE
  241  FALSE
  242  FALSE
  243  FALSE
  244  FALSE
  245  FALSE
  246  FALSE
  247  FALSE
  248  FALSE
  249  FALSE
  250  FALSE
  251  FALSE
  252  FALSE
  253  FALSE
  254  FALSE
  255  FALSE
  256  FALSE
  257  FALSE
  258  FALSE
  259  FALSE
  260  FALSE
  261  FALSE
  262  FALSE
  263  FALSE
  264  FALSE
  265  FALSE
  266  FALSE
  267  FALSE
  268  FALSE
  269  FALSE
  270  FALSE
  271  FALSE
  272  FALSE
  273  FALSE
  274  FALSE
  275  FALSE
  276  FALSE
  277  FALSE
  278  FALSE
  279  FALSE
  280  FALSE
  281  FALSE
  282  FALSE
  283  FALSE
  284  FALSE
  285  FALSE
  286  FALSE
  287  FALSE
  288  FALSE
  289  FALSE
  290  FALSE
  291  FALSE
  292  FALSE
  293  FALSE
  294  FALSE
  295  FALSE
  296  FALSE
  297  FALSE
  298  FALSE
  299  FALSE
  300  FALSE
  301  FALSE
  302  FALSE
  303  FALSE
  304  FALSE
  305  FALSE
  306  FALSE
  307  FALSE
  308  FALSE
  309  FALSE
  310  FALSE
  311  FALSE
  312  FALSE
  313  FALSE
  314  FALSE
  315  FALSE
  316  FALSE
  317  FALSE
  318  FALSE
  319  FALSE
  320  FALSE
  321  FALSE
  322  FALSE
  323  FALSE
  324  FALSE
  325  FALSE
  326  FALSE
  327  FALSE
  328  FALSE
  329  FALSE
  330  FALSE
  331  FALSE
  332  FALSE
  333  FALSE
  334  FALSE
  335  FALSE
  336  FALSE
  337  FALSE
  338  FALSE
  339  FALSE
  340  FALSE
  341  FALSE
  342  FALSE
  343  FALSE
  344  FALSE
  345  FALSE
  346  FALSE
  347  FALSE
  348  FALSE
  349  FALSE
  350  FALSE
  351  FALSE
  352  FALSE
  353  FALSE
  354  FALSE
  355  FALSE
  356  FALSE
  357  FALSE
  358  FALSE
  359  FALSE
  360  FALSE
  361  FALSE
  362  FALSE
  363  FALSE
  364  FALSE
  365  FALSE
  366  FALSE
  367  FALSE
  368  FALSE
  369  FALSE
  370  FALSE
  371  FALSE
  372  FALSE
  373  FALSE
  374  FALSE
  375  FALSE
  376  FALSE
  377  FALSE
  378  FALSE
  379  FALSE
  380  FALSE
  381  FALSE
  382  FALSE
  383  FALSE
  384  FALSE
  385  FALSE
  386  FALSE
  387  FALSE
  388  FALSE
  389  FALSE
  390  FALSE
  391  FALSE
  392  FALSE
  393  FALSE
  394  FALSE
  395  FALSE
  396  FALSE
  397  FALSE
  398  FALSE
  399  FALSE
  400  FALSE
  401  FALSE
  402  FALSE
  403  FALSE
  404  FALSE
  405  FALSE
  406  FALSE
  407  FALSE
  408  FALSE
  409  FALSE
  410  FALSE
  411  FALSE
  412  FALSE
  413  FALSE
  414  FALSE
  415  FALSE
  416  FALSE
  417  FALSE
  418  FALSE
  419  FALSE
  420  FALSE
  421  FALSE
  422  FALSE
  423  FALSE
  424  FALSE
  425  FALSE
  426  FALSE
  427  FALSE
  428  FALSE
  429  FALSE
  430  FALSE
  431  FALSE
  432  FALSE
  433  FALSE
  434  FALSE
  435  FALSE
  436  FALSE
  437  FALSE
  438  FALSE
  439  FALSE
  440  FALSE
  441  FALSE
  442  FALSE
  443  FALSE
  444  FALSE
  445  FALSE
  446  FALSE
  447  FALSE
  448  FALSE
  449  FALSE
  450  FALSE
  451  FALSE
  452  FALSE
  453  FALSE
  454  FALSE
  455  FALSE
  456  FALSE
  457  FALSE
  458  FALSE
  459  FALSE
  460  FALSE
  461  FALSE
  462  FALSE
  463  FALSE
  464  FALSE
  465  FALSE
  466  FALSE
  467  FALSE
  468  FALSE
  469  FALSE
  470  FALSE
  471  FALSE
  472  FALSE
  473  FALSE
  474  FALSE
  475  FALSE
  476  FALSE
  477  FALSE
  478  FALSE
  479  FALSE
  480  FALSE
  481  FALSE
  482  FALSE
  483  FALSE
  484  FALSE
  485  FALSE
  486  FALSE
  487  FALSE
  488  FALSE
  489  FALSE
  490  FALSE
  491  FALSE
  492  FALSE
  493  FALSE
  494  FALSE
  495  FALSE
  496  FALSE
  497  FALSE
  498  FALSE
  499  FALSE
  500  FALSE
  501  FALSE
  502  FALSE
  503  FALSE
  504  FALSE
  505  FALSE
  506  FALSE
  507  FALSE
  508  FALSE
  509  FALSE
  510  FALSE
  511  FALSE
  512  FALSE
  513  FALSE
  514  FALSE
  515  FALSE
  516  FALSE
  517  FALSE
  518  FALSE
  519  FALSE
  520  FALSE
  521  FALSE
  522  FALSE
  523  FALSE
  524  FALSE
  525  FALSE
  526  FALSE
  527  FALSE
  528  FALSE
  529  FALSE
  530  FALSE
  531  FALSE
  532  FALSE
  533  FALSE
  534  FALSE
  535  FALSE
  536  FALSE
  537  FALSE
  538  FALSE
  539  FALSE
  540   TRUE
  541  FALSE
  542  FALSE
  543  FALSE
  544  FALSE
  545  FALSE
  546  FALSE
  547  FALSE
  548  FALSE
  549  FALSE
  550  FALSE
  551  FALSE
  552  FALSE
  553  FALSE
  554  FALSE
  555  FALSE
  556  FALSE
  557  FALSE
  558  FALSE
  559  FALSE
  560  FALSE
  561  FALSE
  562  FALSE
  563  FALSE
  564  FALSE
  565  FALSE
  566  FALSE
  567  FALSE
  568  FALSE
  569  FALSE
  570  FALSE
  571  FALSE
  572  FALSE
  573  FALSE
  574  FALSE
  575  FALSE
  576  FALSE
  577  FALSE
  578  FALSE
  579  FALSE
  580  FALSE
  581  FALSE
  582  FALSE
  583  FALSE
  584  FALSE
  585  FALSE
  586  FALSE
  587  FALSE
  588  FALSE
  589  FALSE
  590  FALSE
  591  FALSE
  592  FALSE
  593  FALSE
  594  FALSE
  595  FALSE
  596  FALSE
  597  FALSE
  598  FALSE
  599  FALSE
  600  FALSE
  601  FALSE
  602  FALSE
  603  FALSE
  604  FALSE
  605  FALSE
  606  FALSE
  607  FALSE
  608  FALSE
  609  FALSE
  610  FALSE
  611  FALSE
  612  FALSE
  613  FALSE
  614  FALSE
  615  FALSE
  616  FALSE
  617  FALSE
  618  FALSE
  619  FALSE
  620  FALSE
  621  FALSE
  622  FALSE
  623  FALSE
  624  FALSE
  625  FALSE
  626  FALSE
  627  FALSE
  628  FALSE
  629  FALSE
  630  FALSE
  631  FALSE
  632  FALSE
  633  FALSE
  634  FALSE
  635  FALSE
  636  FALSE
  637  FALSE
  638  FALSE
  639  FALSE
  640  FALSE
  641  FALSE
  642  FALSE
  643  FALSE
  644  FALSE
  645  FALSE
  646  FALSE
  647  FALSE
  648  FALSE
  649  FALSE
  650  FALSE
  651  FALSE
  652  FALSE
  653  FALSE
  654  FALSE
  655  FALSE
  656  FALSE
  657  FALSE
  658  FALSE
  659  FALSE
  660  FALSE
  661  FALSE
  662  FALSE
  663  FALSE
  664  FALSE
  665  FALSE
  666  FALSE
  667  FALSE
  668  FALSE
  669  FALSE
  670  FALSE
  671  FALSE
  672  FALSE
  673  FALSE
  674  FALSE
  675  FALSE
  676  FALSE
  677  FALSE
  678  FALSE
  679  FALSE
  680  FALSE
  681  FALSE
  682  FALSE
  683  FALSE
  684  FALSE
  685  FALSE
  686  FALSE
  687  FALSE
  688  FALSE
  689  FALSE
  690  FALSE
  691  FALSE
  692  FALSE
  693  FALSE
  694  FALSE
  695  FALSE
  696  FALSE
  697  FALSE
  698  FALSE
  699  FALSE
  700  FALSE
  701  FALSE
  702  FALSE
  703  FALSE
  704  FALSE
  705  FALSE
  706  FALSE
  707  FALSE
  708  FALSE
  709  FALSE
  710  FALSE
  711  FALSE
  712  FALSE
  713  FALSE
  714  FALSE
  715  FALSE
  716  FALSE
  717  FALSE
  718  FALSE
  719  FALSE
  720  FALSE
  721  FALSE
  722  FALSE
  723  FALSE
  724  FALSE
  725  FALSE
  726  FALSE
  727  FALSE
  728  FALSE
  729  FALSE
  730  FALSE
  731  FALSE
  732  FALSE
  733  FALSE
  734  FALSE
  735  FALSE
  736  FALSE
  737  FALSE
  738  FALSE
  739  FALSE
  740  FALSE
  741  FALSE
  742  FALSE
  743  FALSE
  744  FALSE
  745  FALSE
  746  FALSE
  747  FALSE
  748  FALSE
  749  FALSE
  750  FALSE
  751  FALSE
  752  FALSE
  753  FALSE
  754  FALSE
  755  FALSE
  756  FALSE
  757  FALSE
  758  FALSE
  759  FALSE
  760  FALSE
  761  FALSE
  762  FALSE
  763  FALSE
  764  FALSE
  765  FALSE
  766  FALSE
  767  FALSE
  768  FALSE
  769  FALSE
  770  FALSE
  771  FALSE
  772  FALSE
  773  FALSE
  774  FALSE
  775  FALSE
  776  FALSE
  777  FALSE
  778  FALSE
  779  FALSE
  780  FALSE
  781  FALSE
  782  FALSE
  783  FALSE
  784  FALSE
  785  FALSE
  786  FALSE
  787  FALSE
  788  FALSE
  789  FALSE
  790  FALSE
  791  FALSE
  792  FALSE
  793  FALSE
  794  FALSE
  795  FALSE
  796  FALSE
  797  FALSE
  798  FALSE
  799  FALSE
  800  FALSE
  801  FALSE
  802  FALSE
  803  FALSE
  804  FALSE
  805  FALSE
  806  FALSE
  807  FALSE
  808  FALSE
  809  FALSE
  810  FALSE
  811  FALSE
  812  FALSE
  813  FALSE
  814  FALSE
  815  FALSE
  816  FALSE
  817  FALSE
  818  FALSE
  819  FALSE
  820  FALSE
  821  FALSE
  822  FALSE
  823  FALSE
  824  FALSE
  825  FALSE
  826  FALSE
  827  FALSE
  828  FALSE
  829  FALSE
  830  FALSE
  831  FALSE
  832  FALSE
  833  FALSE
  834  FALSE
  835  FALSE
  836  FALSE
  837  FALSE
  838  FALSE
  839  FALSE
  840  FALSE
  841  FALSE
  842  FALSE
  843  FALSE
  844  FALSE
  845  FALSE
  846  FALSE
  847  FALSE
  848  FALSE
  849  FALSE
  850  FALSE
  851  FALSE
  852  FALSE
  853  FALSE
  854  FALSE
  855  FALSE
  856  FALSE
  857  FALSE
  858  FALSE
  859  FALSE
  860  FALSE
  861  FALSE
  862  FALSE
  863  FALSE
  864  FALSE
  865  FALSE
  866  FALSE
  867  FALSE
  868  FALSE
  869  FALSE
  870  FALSE
  871  FALSE
  872  FALSE
  873  FALSE
  874  FALSE
  875  FALSE
  876  FALSE
  877  FALSE
  878  FALSE
  879  FALSE
  880  FALSE
  881  FALSE
  882  FALSE
  883  FALSE
  884  FALSE
  885  FALSE
  886  FALSE
  887  FALSE
  888  FALSE
  889  FALSE
  890  FALSE
  891  FALSE
  892  FALSE
  893  FALSE
  894  FALSE
  895  FALSE
  896  FALSE
  897  FALSE
  898  FALSE
  899  FALSE
  900  FALSE
  901  FALSE
  902  FALSE
  903  FALSE
  904  FALSE
  905  FALSE
  906  FALSE
  907  FALSE
  908  FALSE
  909  FALSE
  910  FALSE
  911  FALSE
  912  FALSE
  913  FALSE
  914  FALSE
  915  FALSE
  916  FALSE
  917  FALSE
  918  FALSE
  919  FALSE
  920  FALSE
  921  FALSE
  922  FALSE
  923  FALSE
  924  FALSE
  925  FALSE
  926  FALSE
  927  FALSE
  928  FALSE
  929  FALSE
  930  FALSE
  931  FALSE
  932  FALSE
  933  FALSE
  934  FALSE
  935  FALSE
  936  FALSE
  937  FALSE
  938  FALSE
  939  FALSE
  940  FALSE
  941  FALSE
  942  FALSE
  943  FALSE
  944  FALSE
  945  FALSE
  946  FALSE
  947  FALSE
  948  FALSE
  949  FALSE
  950  FALSE
  951  FALSE
  952  FALSE
  953  FALSE
  954  FALSE
  955  FALSE
  956  FALSE
  957  FALSE
  958  FALSE
  959  FALSE
  960  FALSE
  961  FALSE
  962  FALSE
  963  FALSE
  964  FALSE
  965  FALSE
  966  FALSE
  967  FALSE
  968  FALSE
  969  FALSE
  970  FALSE
  971  FALSE
  972  FALSE
  973  FALSE
  974  FALSE
  975  FALSE
  976  FALSE
  977  FALSE
  978  FALSE
  979  FALSE
  980  FALSE
  981  FALSE
  982  FALSE
  983  FALSE
  984  FALSE
  985  FALSE
  986  FALSE
  987  FALSE
  988  FALSE
  989  FALSE
  990  FALSE
  991  FALSE
  992  FALSE
  993  FALSE
  994  FALSE
  995  FALSE
  996  FALSE
  997  FALSE
  998  FALSE
  999  FALSE
  1000 FALSE
 [ reached getOption("max.print") -- omitted 1251 rows ]
#To deal with the problem of "large data size", we could use summary() function.
Violated1 <- violatedEdits(Rules1, Data_for_checking_inconsistency2)

summary(Violated1)
Edit violations, 2251 observations, 0 completely missing (0%):

Edit violations per record:
#The result shows that this data does have some errors.



#To correct those errors, we import rules for correction.
Rules2 <- correctionRules("/Users/macbook/Documents/RMIT-Master of Analytics/Data wrangling/editrules3.txt")

#Apply rules into the data that contains errors.
cor <- correctWithRules(Rules2, Data_for_checking_inconsistency2)

cor
$corrected

$corrections
#This is the data after correction.
cor$corrected

#And then, check it again whether we successfully correct errors.
violatedEdits(Rules1, cor$corrected)
      edit
record  num1
  1    FALSE
  2    FALSE
  3    FALSE
  4    FALSE
  5    FALSE
  6    FALSE
  7    FALSE
  8    FALSE
  9    FALSE
  10   FALSE
  11   FALSE
  12   FALSE
  13   FALSE
  14   FALSE
  15   FALSE
  16   FALSE
  17   FALSE
  18   FALSE
  19   FALSE
  20   FALSE
  21   FALSE
  22   FALSE
  23   FALSE
  24   FALSE
  25   FALSE
  26   FALSE
  27   FALSE
  28   FALSE
  29   FALSE
  30   FALSE
  31   FALSE
  32   FALSE
  33   FALSE
  34   FALSE
  35   FALSE
  36   FALSE
  37   FALSE
  38   FALSE
  39   FALSE
  40   FALSE
  41   FALSE
  42   FALSE
  43   FALSE
  44   FALSE
  45   FALSE
  46   FALSE
  47   FALSE
  48   FALSE
  49   FALSE
  50   FALSE
  51   FALSE
  52   FALSE
  53   FALSE
  54   FALSE
  55   FALSE
  56   FALSE
  57   FALSE
  58   FALSE
  59   FALSE
  60   FALSE
  61   FALSE
  62   FALSE
  63   FALSE
  64   FALSE
  65   FALSE
  66   FALSE
  67   FALSE
  68   FALSE
  69   FALSE
  70   FALSE
  71   FALSE
  72   FALSE
  73   FALSE
  74   FALSE
  75   FALSE
  76   FALSE
  77   FALSE
  78   FALSE
  79   FALSE
  80   FALSE
  81   FALSE
  82   FALSE
  83   FALSE
  84   FALSE
  85   FALSE
  86   FALSE
  87   FALSE
  88   FALSE
  89   FALSE
  90   FALSE
  91   FALSE
  92   FALSE
  93   FALSE
  94   FALSE
  95   FALSE
  96   FALSE
  97   FALSE
  98   FALSE
  99   FALSE
  100  FALSE
  101  FALSE
  102  FALSE
  103  FALSE
  104  FALSE
  105  FALSE
  106  FALSE
  107  FALSE
  108  FALSE
  109  FALSE
  110  FALSE
  111  FALSE
  112  FALSE
  113  FALSE
  114  FALSE
  115  FALSE
  116  FALSE
  117  FALSE
  118  FALSE
  119  FALSE
  120  FALSE
  121  FALSE
  122  FALSE
  123  FALSE
  124  FALSE
  125  FALSE
  126  FALSE
  127  FALSE
  128  FALSE
  129  FALSE
  130  FALSE
  131  FALSE
  132  FALSE
  133  FALSE
  134  FALSE
  135  FALSE
  136  FALSE
  137  FALSE
  138  FALSE
  139  FALSE
  140  FALSE
  141  FALSE
  142  FALSE
  143  FALSE
  144  FALSE
  145  FALSE
  146  FALSE
  147  FALSE
  148  FALSE
  149  FALSE
  150  FALSE
  151  FALSE
  152  FALSE
  153  FALSE
  154  FALSE
  155  FALSE
  156  FALSE
  157  FALSE
  158  FALSE
  159  FALSE
  160  FALSE
  161  FALSE
  162  FALSE
  163  FALSE
  164  FALSE
  165  FALSE
  166  FALSE
  167  FALSE
  168  FALSE
  169  FALSE
  170  FALSE
  171  FALSE
  172  FALSE
  173  FALSE
  174  FALSE
  175  FALSE
  176  FALSE
  177  FALSE
  178  FALSE
  179  FALSE
  180  FALSE
  181  FALSE
  182  FALSE
  183  FALSE
  184  FALSE
  185  FALSE
  186  FALSE
  187  FALSE
  188  FALSE
  189  FALSE
  190  FALSE
  191  FALSE
  192  FALSE
  193  FALSE
  194  FALSE
  195  FALSE
  196  FALSE
  197  FALSE
  198  FALSE
  199  FALSE
  200  FALSE
  201  FALSE
  202  FALSE
  203  FALSE
  204  FALSE
  205  FALSE
  206  FALSE
  207  FALSE
  208  FALSE
  209  FALSE
  210  FALSE
  211  FALSE
  212  FALSE
  213  FALSE
  214  FALSE
  215  FALSE
  216  FALSE
  217  FALSE
  218  FALSE
  219  FALSE
  220  FALSE
  221  FALSE
  222  FALSE
  223  FALSE
  224  FALSE
  225  FALSE
  226  FALSE
  227  FALSE
  228  FALSE
  229  FALSE
  230  FALSE
  231  FALSE
  232  FALSE
  233  FALSE
  234  FALSE
  235  FALSE
  236  FALSE
  237  FALSE
  238  FALSE
  239  FALSE
  240  FALSE
  241  FALSE
  242  FALSE
  243  FALSE
  244  FALSE
  245  FALSE
  246  FALSE
  247  FALSE
  248  FALSE
  249  FALSE
  250  FALSE
  251  FALSE
  252  FALSE
  253  FALSE
  254  FALSE
  255  FALSE
  256  FALSE
  257  FALSE
  258  FALSE
  259  FALSE
  260  FALSE
  261  FALSE
  262  FALSE
  263  FALSE
  264  FALSE
  265  FALSE
  266  FALSE
  267  FALSE
  268  FALSE
  269  FALSE
  270  FALSE
  271  FALSE
  272  FALSE
  273  FALSE
  274  FALSE
  275  FALSE
  276  FALSE
  277  FALSE
  278  FALSE
  279  FALSE
  280  FALSE
  281  FALSE
  282  FALSE
  283  FALSE
  284  FALSE
  285  FALSE
  286  FALSE
  287  FALSE
  288  FALSE
  289  FALSE
  290  FALSE
  291  FALSE
  292  FALSE
  293  FALSE
  294  FALSE
  295  FALSE
  296  FALSE
  297  FALSE
  298  FALSE
  299  FALSE
  300  FALSE
  301  FALSE
  302  FALSE
  303  FALSE
  304  FALSE
  305  FALSE
  306  FALSE
  307  FALSE
  308  FALSE
  309  FALSE
  310  FALSE
  311  FALSE
  312  FALSE
  313  FALSE
  314  FALSE
  315  FALSE
  316  FALSE
  317  FALSE
  318  FALSE
  319  FALSE
  320  FALSE
  321  FALSE
  322  FALSE
  323  FALSE
  324  FALSE
  325  FALSE
  326  FALSE
  327  FALSE
  328  FALSE
  329  FALSE
  330  FALSE
  331  FALSE
  332  FALSE
  333  FALSE
  334  FALSE
  335  FALSE
  336  FALSE
  337  FALSE
  338  FALSE
  339  FALSE
  340  FALSE
  341  FALSE
  342  FALSE
  343  FALSE
  344  FALSE
  345  FALSE
  346  FALSE
  347  FALSE
  348  FALSE
  349  FALSE
  350  FALSE
  351  FALSE
  352  FALSE
  353  FALSE
  354  FALSE
  355  FALSE
  356  FALSE
  357  FALSE
  358  FALSE
  359  FALSE
  360  FALSE
  361  FALSE
  362  FALSE
  363  FALSE
  364  FALSE
  365  FALSE
  366  FALSE
  367  FALSE
  368  FALSE
  369  FALSE
  370  FALSE
  371  FALSE
  372  FALSE
  373  FALSE
  374  FALSE
  375  FALSE
  376  FALSE
  377  FALSE
  378  FALSE
  379  FALSE
  380  FALSE
  381  FALSE
  382  FALSE
  383  FALSE
  384  FALSE
  385  FALSE
  386  FALSE
  387  FALSE
  388  FALSE
  389  FALSE
  390  FALSE
  391  FALSE
  392  FALSE
  393  FALSE
  394  FALSE
  395  FALSE
  396  FALSE
  397  FALSE
  398  FALSE
  399  FALSE
  400  FALSE
  401  FALSE
  402  FALSE
  403  FALSE
  404  FALSE
  405  FALSE
  406  FALSE
  407  FALSE
  408  FALSE
  409  FALSE
  410  FALSE
  411  FALSE
  412  FALSE
  413  FALSE
  414  FALSE
  415  FALSE
  416  FALSE
  417  FALSE
  418  FALSE
  419  FALSE
  420  FALSE
  421  FALSE
  422  FALSE
  423  FALSE
  424  FALSE
  425  FALSE
  426  FALSE
  427  FALSE
  428  FALSE
  429  FALSE
  430  FALSE
  431  FALSE
  432  FALSE
  433  FALSE
  434  FALSE
  435  FALSE
  436  FALSE
  437  FALSE
  438  FALSE
  439  FALSE
  440  FALSE
  441  FALSE
  442  FALSE
  443  FALSE
  444  FALSE
  445  FALSE
  446  FALSE
  447  FALSE
  448  FALSE
  449  FALSE
  450  FALSE
  451  FALSE
  452  FALSE
  453  FALSE
  454  FALSE
  455  FALSE
  456  FALSE
  457  FALSE
  458  FALSE
  459  FALSE
  460  FALSE
  461  FALSE
  462  FALSE
  463  FALSE
  464  FALSE
  465  FALSE
  466  FALSE
  467  FALSE
  468  FALSE
  469  FALSE
  470  FALSE
  471  FALSE
  472  FALSE
  473  FALSE
  474  FALSE
  475  FALSE
  476  FALSE
  477  FALSE
  478  FALSE
  479  FALSE
  480  FALSE
  481  FALSE
  482  FALSE
  483  FALSE
  484  FALSE
  485  FALSE
  486  FALSE
  487  FALSE
  488  FALSE
  489  FALSE
  490  FALSE
  491  FALSE
  492  FALSE
  493  FALSE
  494  FALSE
  495  FALSE
  496  FALSE
  497  FALSE
  498  FALSE
  499  FALSE
  500  FALSE
  501  FALSE
  502  FALSE
  503  FALSE
  504  FALSE
  505  FALSE
  506  FALSE
  507  FALSE
  508  FALSE
  509  FALSE
  510  FALSE
  511  FALSE
  512  FALSE
  513  FALSE
  514  FALSE
  515  FALSE
  516  FALSE
  517  FALSE
  518  FALSE
  519  FALSE
  520  FALSE
  521  FALSE
  522  FALSE
  523  FALSE
  524  FALSE
  525  FALSE
  526  FALSE
  527  FALSE
  528  FALSE
  529  FALSE
  530  FALSE
  531  FALSE
  532  FALSE
  533  FALSE
  534  FALSE
  535  FALSE
  536  FALSE
  537  FALSE
  538  FALSE
  539  FALSE
  540  FALSE
  541  FALSE
  542  FALSE
  543  FALSE
  544  FALSE
  545  FALSE
  546  FALSE
  547  FALSE
  548  FALSE
  549  FALSE
  550  FALSE
  551  FALSE
  552  FALSE
  553  FALSE
  554  FALSE
  555  FALSE
  556  FALSE
  557  FALSE
  558  FALSE
  559  FALSE
  560  FALSE
  561  FALSE
  562  FALSE
  563  FALSE
  564  FALSE
  565  FALSE
  566  FALSE
  567  FALSE
  568  FALSE
  569  FALSE
  570  FALSE
  571  FALSE
  572  FALSE
  573  FALSE
  574  FALSE
  575  FALSE
  576  FALSE
  577  FALSE
  578  FALSE
  579  FALSE
  580  FALSE
  581  FALSE
  582  FALSE
  583  FALSE
  584  FALSE
  585  FALSE
  586  FALSE
  587  FALSE
  588  FALSE
  589  FALSE
  590  FALSE
  591  FALSE
  592  FALSE
  593  FALSE
  594  FALSE
  595  FALSE
  596  FALSE
  597  FALSE
  598  FALSE
  599  FALSE
  600  FALSE
  601  FALSE
  602  FALSE
  603  FALSE
  604  FALSE
  605  FALSE
  606  FALSE
  607  FALSE
  608  FALSE
  609  FALSE
  610  FALSE
  611  FALSE
  612  FALSE
  613  FALSE
  614  FALSE
  615  FALSE
  616  FALSE
  617  FALSE
  618  FALSE
  619  FALSE
  620  FALSE
  621  FALSE
  622  FALSE
  623  FALSE
  624  FALSE
  625  FALSE
  626  FALSE
  627  FALSE
  628  FALSE
  629  FALSE
  630  FALSE
  631  FALSE
  632  FALSE
  633  FALSE
  634  FALSE
  635  FALSE
  636  FALSE
  637  FALSE
  638  FALSE
  639  FALSE
  640  FALSE
  641  FALSE
  642  FALSE
  643  FALSE
  644  FALSE
  645  FALSE
  646  FALSE
  647  FALSE
  648  FALSE
  649  FALSE
  650  FALSE
  651  FALSE
  652  FALSE
  653  FALSE
  654  FALSE
  655  FALSE
  656  FALSE
  657  FALSE
  658  FALSE
  659  FALSE
  660  FALSE
  661  FALSE
  662  FALSE
  663  FALSE
  664  FALSE
  665  FALSE
  666  FALSE
  667  FALSE
  668  FALSE
  669  FALSE
  670  FALSE
  671  FALSE
  672  FALSE
  673  FALSE
  674  FALSE
  675  FALSE
  676  FALSE
  677  FALSE
  678  FALSE
  679  FALSE
  680  FALSE
  681  FALSE
  682  FALSE
  683  FALSE
  684  FALSE
  685  FALSE
  686  FALSE
  687  FALSE
  688  FALSE
  689  FALSE
  690  FALSE
  691  FALSE
  692  FALSE
  693  FALSE
  694  FALSE
  695  FALSE
  696  FALSE
  697  FALSE
  698  FALSE
  699  FALSE
  700  FALSE
  701  FALSE
  702  FALSE
  703  FALSE
  704  FALSE
  705  FALSE
  706  FALSE
  707  FALSE
  708  FALSE
  709  FALSE
  710  FALSE
  711  FALSE
  712  FALSE
  713  FALSE
  714  FALSE
  715  FALSE
  716  FALSE
  717  FALSE
  718  FALSE
  719  FALSE
  720  FALSE
  721  FALSE
  722  FALSE
  723  FALSE
  724  FALSE
  725  FALSE
  726  FALSE
  727  FALSE
  728  FALSE
  729  FALSE
  730  FALSE
  731  FALSE
  732  FALSE
  733  FALSE
  734  FALSE
  735  FALSE
  736  FALSE
  737  FALSE
  738  FALSE
  739  FALSE
  740  FALSE
  741  FALSE
  742  FALSE
  743  FALSE
  744  FALSE
  745  FALSE
  746  FALSE
  747  FALSE
  748  FALSE
  749  FALSE
  750  FALSE
  751  FALSE
  752  FALSE
  753  FALSE
  754  FALSE
  755  FALSE
  756  FALSE
  757  FALSE
  758  FALSE
  759  FALSE
  760  FALSE
  761  FALSE
  762  FALSE
  763  FALSE
  764  FALSE
  765  FALSE
  766  FALSE
  767  FALSE
  768  FALSE
  769  FALSE
  770  FALSE
  771  FALSE
  772  FALSE
  773  FALSE
  774  FALSE
  775  FALSE
  776  FALSE
  777  FALSE
  778  FALSE
  779  FALSE
  780  FALSE
  781  FALSE
  782  FALSE
  783  FALSE
  784  FALSE
  785  FALSE
  786  FALSE
  787  FALSE
  788  FALSE
  789  FALSE
  790  FALSE
  791  FALSE
  792  FALSE
  793  FALSE
  794  FALSE
  795  FALSE
  796  FALSE
  797  FALSE
  798  FALSE
  799  FALSE
  800  FALSE
  801  FALSE
  802  FALSE
  803  FALSE
  804  FALSE
  805  FALSE
  806  FALSE
  807  FALSE
  808  FALSE
  809  FALSE
  810  FALSE
  811  FALSE
  812  FALSE
  813  FALSE
  814  FALSE
  815  FALSE
  816  FALSE
  817  FALSE
  818  FALSE
  819  FALSE
  820  FALSE
  821  FALSE
  822  FALSE
  823  FALSE
  824  FALSE
  825  FALSE
  826  FALSE
  827  FALSE
  828  FALSE
  829  FALSE
  830  FALSE
  831  FALSE
  832  FALSE
  833  FALSE
  834  FALSE
  835  FALSE
  836  FALSE
  837  FALSE
  838  FALSE
  839  FALSE
  840  FALSE
  841  FALSE
  842  FALSE
  843  FALSE
  844  FALSE
  845  FALSE
  846  FALSE
  847  FALSE
  848  FALSE
  849  FALSE
  850  FALSE
  851  FALSE
  852  FALSE
  853  FALSE
  854  FALSE
  855  FALSE
  856  FALSE
  857  FALSE
  858  FALSE
  859  FALSE
  860  FALSE
  861  FALSE
  862  FALSE
  863  FALSE
  864  FALSE
  865  FALSE
  866  FALSE
  867  FALSE
  868  FALSE
  869  FALSE
  870  FALSE
  871  FALSE
  872  FALSE
  873  FALSE
  874  FALSE
  875  FALSE
  876  FALSE
  877  FALSE
  878  FALSE
  879  FALSE
  880  FALSE
  881  FALSE
  882  FALSE
  883  FALSE
  884  FALSE
  885  FALSE
  886  FALSE
  887  FALSE
  888  FALSE
  889  FALSE
  890  FALSE
  891  FALSE
  892  FALSE
  893  FALSE
  894  FALSE
  895  FALSE
  896  FALSE
  897  FALSE
  898  FALSE
  899  FALSE
  900  FALSE
  901  FALSE
  902  FALSE
  903  FALSE
  904  FALSE
  905  FALSE
  906  FALSE
  907  FALSE
  908  FALSE
  909  FALSE
  910  FALSE
  911  FALSE
  912  FALSE
  913  FALSE
  914  FALSE
  915  FALSE
  916  FALSE
  917  FALSE
  918  FALSE
  919  FALSE
  920  FALSE
  921  FALSE
  922  FALSE
  923  FALSE
  924  FALSE
  925  FALSE
  926  FALSE
  927  FALSE
  928  FALSE
  929  FALSE
  930  FALSE
  931  FALSE
  932  FALSE
  933  FALSE
  934  FALSE
  935  FALSE
  936  FALSE
  937  FALSE
  938  FALSE
  939  FALSE
  940  FALSE
  941  FALSE
  942  FALSE
  943  FALSE
  944  FALSE
  945  FALSE
  946  FALSE
  947  FALSE
  948  FALSE
  949  FALSE
  950  FALSE
  951  FALSE
  952  FALSE
  953  FALSE
  954  FALSE
  955  FALSE
  956  FALSE
  957  FALSE
  958  FALSE
  959  FALSE
  960  FALSE
  961  FALSE
  962  FALSE
  963  FALSE
  964  FALSE
  965  FALSE
  966  FALSE
  967  FALSE
  968  FALSE
  969  FALSE
  970  FALSE
  971  FALSE
  972  FALSE
  973  FALSE
  974  FALSE
  975  FALSE
  976  FALSE
  977  FALSE
  978  FALSE
  979  FALSE
  980  FALSE
  981  FALSE
  982  FALSE
  983  FALSE
  984  FALSE
  985  FALSE
  986  FALSE
  987  FALSE
  988  FALSE
  989  FALSE
  990  FALSE
  991  FALSE
  992  FALSE
  993  FALSE
  994  FALSE
  995  FALSE
  996  FALSE
  997  FALSE
  998  FALSE
  999  FALSE
  1000 FALSE
 [ reached getOption("max.print") -- omitted 1251 rows ]
#Use summary() function to avoid the problem of large data size.
Violated2 <- violatedEdits(Rules1, cor$corrected)

summary(Violated2)
No violations detected, 0 checks evaluated to NA
NULL
#And then, after correcting the data, we put "Sex_proportion_for_the_pre.student_in_school" back into the dataset.
#The first thing is to reshape the dataset of "Data_for_checking_inconsistency2".
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3 <- Data_for_checking_inconsistency2 %>%
  gather(`Male`, `Female`, key = "Gender", value = "Number_of_pre.student")

#And then, put "Sex_proportion_for_the_pre.student_in_school" back into the dataset.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3 <- mutate(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3,
                                                                              Sex_proportion_for_the_pre.student_in_school = Number_of_pre.student / Total_number_of_pre.student_for_school
)

#And then, rearrange the sequence of variables.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3 <- All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_2 %>% select(School_Name, School_No, School_Type, School_Status, Education_Sector, Entity_Type, Gender, Number_of_pre.student, Total_number_of_pre.student_for_school, Sex_proportion_for_the_pre.student_in_school)



#The second thing is to check inifite value, special value, and missing value. For convenience, we first build up a function to better deal with missing values, infinite values, and NaN values. We acutally would like to use sapply() function to look for errors but this function could not deal with NaN values. Thus, we should write up a function to deal with NaN values.
is.specialorNA <- function(x){
  if (is.numeric(x)) (is.infinite(x) | is.nan(x) | is.na(x))
}

#There are 932 na value for column "Sex_proportion_for_the_pre.student_in_school"
sapply(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3, function(x) sum( is.na(x) ))
                                 School_Name 
                                           0 
                                   School_No 
                                           0 
                                 School_Type 
                                           0 
                               School_Status 
                                           0 
                            Education_Sector 
                                           0 
                                 Entity_Type 
                                           0 
                                      Gender 
                                           0 
                       Number_of_pre.student 
                                           0 
      Total_number_of_pre.student_for_school 
                                           0 
Sex_proportion_for_the_pre.student_in_school 
                                         932 
#There are 0 infinite value for this dataset
sapply(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3, function(x) sum( is.infinite(x) ))
                                 School_Name 
                                           0 
                                   School_No 
                                           0 
                                 School_Type 
                                           0 
                               School_Status 
                                           0 
                            Education_Sector 
                                           0 
                                 Entity_Type 
                                           0 
                                      Gender 
                                           0 
                       Number_of_pre.student 
                                           0 
      Total_number_of_pre.student_for_school 
                                           0 
Sex_proportion_for_the_pre.student_in_school 
                                           0 
#There are 932 NaN value for column "Sex_proportion_for_the_pre.student_in_school"
sapply(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3, function(x) sum( is.nan(x) ))
                                 School_Name 
                                           0 
                                   School_No 
                                           0 
                                 School_Type 
                                           0 
                               School_Status 
                                           0 
                            Education_Sector 
                                           0 
                                 Entity_Type 
                                           0 
                                      Gender 
                                           0 
                       Number_of_pre.student 
                                           0 
      Total_number_of_pre.student_for_school 
                                           0 
Sex_proportion_for_the_pre.student_in_school 
                                         932 
#NaN means "not a number". When R generate NaN, it means that the value just makes a little sense. In this case, we find out a lot of NaNs in the variable of “Sex_proportion_for_the_pre.student_in_school”, which is calculated by the formula of:
#Sex_proportion_for_the_pre.student_in_school = Number_of_pre.student / Total_number_of_pre.student_for_school. 
#Number_of_pre.student can be 0 and Total_number_of_pre.student_for_school can be 0 either. The is the reason of NaN because when 0 divided by 0, it is meaningless and that’s why R generate NaN as the result. To fix this special value, we can just covert NaN to 0 directly. 
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3$Sex_proportion_for_the_pre.student_in_school[All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3$Sex_proportion_for_the_pre.student_in_school == "NaN" ] <- 0

#And then, check it again whether we eliminate all NaN values and Na values.
sapply(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3, function(x) sum( is.na(x) ))
                                 School_Name 
                                           0 
                                   School_No 
                                           0 
                                 School_Type 
                                           0 
                               School_Status 
                                           0 
                            Education_Sector 
                                           0 
                                 Entity_Type 
                                           0 
                                      Gender 
                                           0 
                       Number_of_pre.student 
                                           0 
      Total_number_of_pre.student_for_school 
                                           0 
Sex_proportion_for_the_pre.student_in_school 
                                           0 
sapply(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3, function(x) sum( is.nan(x) ))
                                 School_Name 
                                           0 
                                   School_No 
                                           0 
                                 School_Type 
                                           0 
                               School_Status 
                                           0 
                            Education_Sector 
                                           0 
                                 Entity_Type 
                                           0 
                                      Gender 
                                           0 
                       Number_of_pre.student 
                                           0 
      Total_number_of_pre.student_for_school 
                                           0 
Sex_proportion_for_the_pre.student_in_school 
                                           0 
#We successfully remove all NaN values and Na values.



#The third thing is to check incoensistency, and we do the same thing as what we done previously.
#Firts, we import rules into R.
Rules3 <- editfile("/Users/macbook/Documents/RMIT-Master of Analytics/Data wrangling/editrules.txt", type = "all")

Rules3

Data model:
dat1 : Education_Sector %in% c('Catholic', 'Government', 'Independent')
dat2 : Entity_Type %in% c('1', '2')
dat3 : Gender %in% c('Female', 'Male')
dat4 : School_Status %in% c('O', 'U')
dat5 : School_Type %in% c('Language', 'Pri/Sec', 'Primary', 'Secondary', 'Special') 

Edit set:
num1 : Number_of_pre.student <= Total_number_of_pre.student_for_school
num2 : Sex_proportion_for_the_pre.student_in_school <= 1
num3 : 0 <= Sex_proportion_for_the_pre.student_in_school 
#Check which value violates the rules
violatedEdits(Rules3, All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3)
      edit
record  num1  num2  num3  dat1  dat2  dat3  dat4  dat5
  1    FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  2    FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  3    FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  4    FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  5    FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  6    FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  7    FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  8    FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  9    FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  10   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  11   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  12   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  13   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  14   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  15   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  16   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  17   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  18   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  19   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  20   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  21   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  22   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  23   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  24   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  25   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  26   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  27   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  28   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  29   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  30   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  31   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  32   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  33   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  34   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  35   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  36   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  37   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  38   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  39   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  40   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  41   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  42   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  43   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  44   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  45   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  46   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  47   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  48   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  49   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  50   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  51   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  52   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  53   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  54   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  55   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  56   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  57   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  58   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  59   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  60   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  61   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  62   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  63   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  64   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  65   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  66   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  67   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  68   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  69   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  70   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  71   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  72   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  73   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  74   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  75   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  76   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  77   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  78   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  79   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  80   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  81   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  82   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  83   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  84   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  85   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  86   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  87   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  88   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  89   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  90   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  91   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  92   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  93   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  94   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  95   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  96   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  97   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  98   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  99   FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  100  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  101  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  102  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  103  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  104  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  105  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  106  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  107  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  108  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  109  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  110  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  111  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  112  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  113  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  114  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  115  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  116  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  117  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  118  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  119  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  120  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  121  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  122  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  123  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  124  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  125  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [ reached getOption("max.print") -- omitted 4377 rows ]
#To deal with the problem of "large data size", we could use summary() function.
Violated3 <- violatedEdits(Rules3, All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3)

summary(Violated3)
No violations detected, 0 checks evaluated to NA
NULL
#Fortunately, we don't have any inconsistencies. 

Transform

Apply an appropriate transformation for at least one of the variables. In addition to the R codes and outputs, explain everything that you do in this step. In this step, you should fulfil the minimum requirement #9.

# This is the R chunk for the Transform Section


#7 Data transformation
#The reaosn to put "data transformation" prior to the "Scan II" is that we have data who has right-skewed distribution. And we decide to use z-scores method in order to locate where are the outliers. 
#Therefore, we have to transform data from right-skewed distribution to approximately normal distribution first. 
hist(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3$Sex_proportion_for_the_pre.student_in_school)


#Based on the variable "Sex_proportion_for_the_pre.student_in_school", it contains 0 values and it is right-skewed.
#We first try to use square root transformation to deal with this data because this data has 0 values and it is reight-skewed.
sqrt_salary <- sqrt(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3$Sex_proportion_for_the_pre.student_in_school)
hist(sqrt_salary)


#As result, it is still right skewed and still need to be improved.

#We note that this data contrains 0 values or 1 values, and it is because there are some all-male school or all-female school.
#When investigating sex porporion, it is meaningless to investigate what percentage of male student in a all-female school or what percentage of female student in all-male school.
#Therefore, we should remove 0 value and 1 value. 
subset_no_0_1 <- All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3 %>% filter(Sex_proportion_for_the_pre.student_in_school != "0" & Sex_proportion_for_the_pre.student_in_school !="1")

#Now, let's produce a histogram again. 
hist(subset_no_0_1$Sex_proportion_for_the_pre.student_in_school)


#As result, it is approximately normal distributed now.

Scan II

Scan the numeric data for outliers. In this step, you should fulfil the minimum requirement #8. In addition to the R codes and outputs, explain your methodology (i.e. explain why you have chosen that methodology and the actions that you have taken to handle these values) and communicate your results clearly.

# This is the R chunk for the Scan II

#We first check out which variable is numeric. 
str(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3)
'data.frame':   4502 obs. of  10 variables:
 $ School_Name                                 : chr  "Parade College" "Simonds Catholic College" "Christian Brothers' College St Kilda" "St Patrick's College Ballarat" ...
 $ School_No                                   : int  20 25 26 28 29 30 33 35 60 77 ...
 $ School_Type                                 : Factor w/ 5 levels "Language","Pri/Sec",..: 4 4 4 4 3 3 4 4 3 3 ...
 $ School_Status                               : Factor w/ 2 levels "O","U": 1 1 1 1 1 1 1 1 1 1 ...
 $ Education_Sector                            : Factor w/ 3 levels "Catholic","Government",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ Entity_Type                                 : Factor w/ 2 levels "1","2": 2 2 2 2 2 2 2 2 2 2 ...
 $ Gender                                      : Factor w/ 2 levels "Female","Male": 2 2 2 2 2 2 2 2 2 2 ...
 $ Number_of_pre.student                       : int  0 0 0 0 15 19 0 0 22 15 ...
 $ Total_number_of_pre.student_for_school      : int  0 0 0 0 34 44 0 0 38 39 ...
 $ Sex_proportion_for_the_pre.student_in_school: num  0 0 0 0 0.441 ...
#We could see that there are 4 numeric variables: 
#School_No, Number_of_pre.student, Total_number_of_pre.student_for_school, and Sex_proportion_for_the_pre.student_in_school
#However, School_No is not necessary to be scanned because it is just a code to represent a school and not a numeric number technically. 



#First, we are going to investigate outliers of "Sex_proportion_for_the_pre.student_in_school".
hist(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3$Sex_proportion_for_the_pre.student_in_school)


#And also, they are non-symmetric/ non-normal data distributions, it is right-skewed distribution.
#As we known, there are all-male school and all-female school, so we expect that there are some outliers is 0 or 1 in terms of sex proportion.
#So, we should use z-scores method to look for outliers. The reason is that we could know which values are outliers, and knowing how many outliers are there, and if there are just a samll acount of outliers we may choose to delete them.
#Given that we already normalize the right-skewed distribution of "Sex_proportion_for_the_pre.student_in_school"
#Now, we could directly apply z-scores method to look for outliers.

#We now calculate z scores:
z.scores <- subset_no_0_1$Sex_proportion_for_the_pre.student_in_school %>%  scores(type = "z")
z.scores %>% summary()
     Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-3.571547 -0.558508 -0.000538  0.000000  0.557432  3.570471 
#we can see that the maximum is 12.04. And we can find the locations of the z-scores whose absolute value is greater than 3 by using which().
which( abs(z.scores) >3 )
 [1]   24  120  154  641  701  708  774 1171 1287 1361 1374 1451 1489
[14] 1491 1708 1804 1838 2325 2385 2392 2458 2855 2971 3045 3058 3135
[27] 3173 3175 3349
#By using length() function, we can see that there are 29 outliers.
length (which( abs(z.scores) >3 ))
[1] 29
#It is still possible that those outliers are not the result of data entry errors, measurement errors, experimental errors, intentional errors, data processing errors or due to the sampling (i.e., sampling error) because very low sex proportion or very high sex proportion does happened in some school.
#But it is also possible that those outliers are actually errors.
#In this case, we should use capping technique to deal with outliers because we are not sure about whether there are errors. 
#Thus, we should use the safe way to deal with this data: Replacing the outliers with the nearest neighbours that are not outliers.

#First, we need to create our own function: cap. This means that we need to first find the value that are less than (quantiles 0.25)-1.5*IQR and then repalce it as (quantiles 0.05). Second, find the value that are bigger than (quantiles 0.75)+1.5*IQR and then repalce it as (quantiles 0.95).
cap <- function(x){
  quantiles <- quantile( x, c(.05, 0.25, 0.75, .95 ) )
  x[ x < quantiles[2] - 1.5*IQR(x) ] <- quantiles[1]
  x[ x > quantiles[3] + 1.5*IQR(x) ] <- quantiles[4]
  x
}

#And then, cap the outliers.
Sex_proportion_capped <- subset_no_0_1$Sex_proportion_for_the_pre.student_in_school %>% cap()

#Let's check outliers again.
z.scores <- Sex_proportion_capped %>%  scores(type = "z")
z.scores %>% summary()
      Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
-2.5208407 -0.6305411 -0.0004412  0.0000000  0.6296587  2.5199584 
#we can see that the maximum is 2.5199584. And we can find whcih value whose absolute Z-value is greater than 3 by using which().
which( abs(z.scores) >3 )
integer(0)
#By using length() function, we can see that there are 0 outliers.
length (which( abs(z.scores) >3 ))
[1] 0
#Second, we are going to ivestigate outliers of "Number_of_pre.student" in terms of "gender". 
#Given that they are one factor variable and one numeric variable. And also, they are non-symmetric/ non-normal data distributions.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3_male <-All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3 %>% filter(Gender == "Male")

hist(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3_male$Number_of_pre.student)


All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3_female <-All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3 %>% filter(Gender == "Female")

hist(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3_female$Number_of_pre.student)


#Thus, in this case, using the technique of "Bivariate box plot" is highly encouraged.

boxplot(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3$Number_of_pre.student ~ All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3$Gender, main="Number of pre.student by gender", ylab = "Number of pre.student", xlab = "Gender")


#Using the bivariate box plot approach, we can easily detect outliers in "Number_of_pre.student" for a given "Gender".
#However, these outliers are valuable becasue this variable (Number_of_pre.student) is used for collect information of the number of stduent for different gender in different school. 
#And, it is okay that some school have a lot of student (note that outliers are all beyond the upper fence for both male and female) because schools can be like all-male school or all-female school. 
#Moreover, school type is divided by "Language", "Pri/Sec", "Primary", "Secondary", and "Special", it is expected that there should be many pre-student for language school or special school, and less pre-student for Pri/Sec, Primary, and Secondary school.
#And, we could see that the Q1 is just around 0 and Q3 is around 30 for both male and female. Obviously, there are a lot of primary and secondary school who has 0 pre-student or only very samll number of pre-student in this datset.
#Therefore, it is possible that some "Language" and "Special" school have a lot of students and are defined as outliers in this plot. So, these outliers are explainable. 
#However, it is still possible that some outliers are errors such as measurement error or sampleing error.
#Thus, we should use the safe way to deal with this data: Replacing the outliers with the nearest neighbours that are not outliers.
#Given that we already have our own function: cap and we could just directly apply cap function into dataset.



#We first deal with the outliers for male.
Student_male_capped <- All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3_male$Number_of_pre.student %>% cap()

#Let's check outliers again.
z.scores2 <- Student_male_capped %>%  scores(type = "z")
z.scores2 %>% summary()
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-1.0015 -0.9418 -0.2859  0.0000  0.6086  2.9342 
#we can see that the maximum is 2.9342. And we can find whcih value whose absolute Z-value is greater than 3 by using which().
which( abs(z.scores2) >3 )
integer(0)
#By using length() function, we can see that there are 0 outliers.
length (which( abs(z.scores2) >3 ))
[1] 0
#And then, we deal with the outliers for female.
Student_female_capped <- All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3_female$Number_of_pre.student %>% cap()

#Let's check outliers again.
z.scores3 <- Student_female_capped %>%  scores(type = "z")
z.scores3 %>% summary()
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-1.0039 -0.9410 -0.3118  0.0000  0.6320  2.9602 
#we can see that the maximum is 2.9602. And we can find whcih value whose absolute Z-value is greater than 3 by using which().
which( abs(z.scores3) >3 )
integer(0)
#By using length() function, we can see that there are 0 outliers.
length (which( abs(z.scores3) >3 ))
[1] 0
#Third, we are going to investigate outliers of "Total_number_of_pre.student_for_school".
hist(All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3$Total_number_of_pre.student_for_school)


#And also, they are non-symmetric/ non-normal data distributions.
#Thus, in this case, using the technique of "Univariate box plot" is highly encouraged.
All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3$Total_number_of_pre.student_for_school %>%  boxplot(main="Box Plot of total number of pre.student for school", ylab="Total number of pre.student", col = "grey")


#This case is very similar to the previous case, outliers are all beyond the upper fence. As we can see in the plot, outliers are all in around 140 students to 250 student. It seems okay because some big school can have 250 pre-student. 
#And, we could see that the Q1 is just around 0 and Q3 is around 50. Obviously, this plot has the same situation with the previous one, there are a lot of primary and secondary school who has 0 pre-student only very samll number of pre-student in this datset.
#Therefore, it is possible that some "Language" and "Special" school have a lot of students and are defined as outliers in this plot. So, these outliers are explainable. 
#Outliers are valuable and explainable.
#However, it is still possible that some outliers are errors such as measurement error or sampleing error.
#Thus, we should use the safe way to deal with this data: Replacing the outliers with the nearest neighbours that are not outliers.
#Given that we already have our own function: cap and we could just directly apply cap function into dataset.



Total_tudent_capped <- All_Schools_FTE_enrolments_Feb_2015_Combine_2016_for_pre.students_3$Total_number_of_pre.student_for_school %>% cap()

#Let's check outliers again.
z.scores4 <- Total_tudent_capped %>%  scores(type = "z")
z.scores4 %>% summary()
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-1.0269 -0.9327 -0.2739  0.0000  0.6046  2.8948 
#we can see that the maximum is 2.8948. And we can find whcih value whose absolute Z-value is greater than 3 by using which().
which( abs(z.scores4) >3 )
integer(0)
#By using length() function, we can see that there are 0 outliers.
length (which( abs(z.scores4) >3 ))
[1] 0

NOTE: Note that sometimes the order of the tasks may be different than the order given here. For example, you may need to tidy the data sets first to be able to create the common key to merge. Therefore, for such cases you may have a different ordering of the sections. 

Any further or optional pre-processing tasks can be added to the template using an additional section in the R Markdown file. Make sure your code is visible (within the margin of the page). Do not use View() to show your data, instead give headers (using head() )



LS0tCnRpdGxlOiAiTUFUSDIzNDkgRGF0YSBXcmFuZ2xpbmciCmF1dGhvcjogIldlbnh1YW4gQ2hlbiAgIFMzNjEzNjM2IgpzdWJ0aXRsZTogQXNzaWdubWVudCAyCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQoKIyMgU3VibWlzc2lvbiBTdGVwczoKCioqMSoqIC4gUHJlcGFyZSBBc3NpZ25tZW50IDIgcmVwb3J0IHVzaW5nIHRoaXMgUiBNYXJrZG93biB0ZW1wbGF0ZS4gKipGZWVsIGZyZWUgdG8gREVMRVRFIHRoZSBpbnN0cnVjdGlvbmFsIHRleHQgcHJvdmlkZWQgaW4gdGhlIHRlbXBsYXRlLioqCgpPbmNlIHlvdSBmaW5hbGlzZSB5b3VyIHJlcG9ydCwgcnVuIGFsbCBSIGNodW5rcyBhbmQgUHJldmlldyB5b3VyIG5vdGVib29rIGluIEhUTUwgKGJ5IGNsaWNraW5nIFByZXZpZXcpLiBNYWtlIHN1cmUgeW91ciBjb2RlIGFuZCBvdXRwdXRzIGFyZSB2aXNpYmxlLgoKKioyKiogLiBVcGxvYWQgdGhlIHJlcG9ydCBhcyBhIFBERiBmaWxlIHZpYSB0aGUgKipGaWxlIFVwbG9hZCoqIHRhYiB1bmRlciB0aGUgQXNzaWdubWVudCAyIHBhZ2UgaW4gQ0FOVkFTIChzZWUgaW5zdHJ1Y3Rpb25zIGZpbGUgZm9yIGRldGFpbHMpIGFmdGVyIHlvdSBhdHRhY2ggdGhlIGZpbGUgY2xpY2sgKipTdWJtaXQgYXNzaWdubWVudCoqLgoKVGhlIGVhc2llc3Qgd2F5IHRvIHByb2R1Y2UgYSBQREYgZmlsZSBmcm9tIHRoZSBSTWFya2Rvd24gaXMgdG8gUnVuIGFsbCBSIGNodW5rcywgdGhlbiBQcmV2aWV3IHlvdXIgbm90ZWJvb2sgaW4gSFRNTCAoYnkgY2xpY2tpbmcgUHJldmlldykg4oaSIE9wZW4gaW4gQnJvd3NlciAoQ2hyb21lKSDihpIgUmlnaHQgY2xpY2sgb24gdGhlIHJlcG9ydCBpbiBDaHJvbWUg4oaSIENsaWNrIFByaW50IGFuZCBTZWxlY3QgdGhlIERlc3RpbmF0aW9uIE9wdGlvbiB0byBTYXZlIGFzIFBERi4gCgoqKjMqKiAuIFB1Ymxpc2ggdGhlIHJlcG9ydCB0byBSUHVicyAoc2VlIFtoZXJlXShodHRwczovL2FzdHJhbC10aGVvcnktMTU3NTEwLmFwcHNwb3QuY29tL3NlY3VyZWQvUkJvb3RjYW1wX0NvdXJzZV8wNC5odG1sI2NyZWF0aW5nX2FuX3JfbWFya2Rvd25fZG9jdW1lbnRfaW5fcl9zdHVkaW8pKSBhbmQgZW50ZXIgeW91ciByZXBvcnTigJlzIFJQdWJzIFVSTCBpbnRvIHRoZSAqKldlYnNpdGUgVVJMKiogdGFiIHVuZGVyIEFzc2lnbm1lbnQgMiBSUHVicyBMaW5rIFN1Ym1pc3Npb24gcGFnZSBpbiBDYW52YXMgKHNlZSBpbnN0cnVjdGlvbnMgZmlsZSBmb3IgZGV0YWlscykgYW5kIHN1Ym1pdCB0aGlzIHRvby4gVGhpcyBvbmxpbmUgdmVyc2lvbiBvZiB0aGUgcmVwb3J0IHdpbGwgYmUgdXNlZCBmb3IgbWFya2luZy4gRmFpbHVyZSB0byBzdWJtaXQgeW91ciBsaW5rIHdpbGwgZGVsYXkgeW91ciBmZWVkYmFjayBhbmQgcmlzayBsYXRlIHBlbmFsdGllcy4KCioqSWYgeW91IGhhdmUgYW55IHF1ZXN0aW9ucyByZWdhcmRpbmcgdGhlIGFzc2lnbm1lbnQgaW5zdHJ1Y3Rpb25zIGFuZCB0aGUgUiBNYXJrZG93biB0ZW1wbGF0ZSoqLCBwbGVhc2UgcG9zdCBpdCBvbiBkaXNjdXNzaW9uIGJvYXJkLiAKCgojIyBSZXF1aXJlZCBwYWNrYWdlcyAKCgpQcm92aWRlIHRoZSBwYWNrYWdlcyByZXF1aXJlZCB0byByZXByb2R1Y2UgdGhlIHJlcG9ydC4gTWFrZSBzdXJlIHlvdSBmdWxmaWxsZWQgdGhlIG1pbmltdW0gcmVxdWlyZW1lbnQgIzEwLgoKYGBge3J9CiMgVGhpcyBpcyB0aGUgUiBjaHVuayBmb3IgdGhlIHJlcXVpcmVkIHBhY2thZ2VzCmxpYnJhcnkodGlkeXIpCgpsaWJyYXJ5KGRwbHlyKQoKbGlicmFyeShlZGl0cnVsZXMpCgpsaWJyYXJ5KGRlZHVjb3JyZWN0KQoKbGlicmFyeShvdXRsaWVycykKYGBgCgojIyBFeGVjdXRpdmUgU3VtbWFyeSAKCgpJbiB5b3VyIG93biB3b3JkcywgcHJvdmlkZSBhIGJyaWVmIHN1bW1hcnkgb2YgdGhlIHByZXByb2Nlc3NpbmcuIEV4cGxhaW4gdGhlIHN0ZXBzIHRoYXQgeW91IGhhdmUgdGFrZW4gdG8gcHJlcHJvY2VzcyB5b3VyIGRhdGEuIFdyaXRlIHRoaXMgc2VjdGlvbiBsYXN0IGFmdGVyIHlvdSBoYXZlIHBlcmZvcm1lZCBhbGwgZGF0YSBwcmVwcm9jZXNzaW5nLiAoV29yZCBjb3VudCBNYXg6IDMwMCB3b3JkcykKCgojIyBEYXRhIAoKQSBjbGVhciBkZXNjcmlwdGlvbiBvZiBkYXRhIHNldHMsIHRoZWlyIHNvdXJjZXMsIGFuZCB2YXJpYWJsZSBkZXNjcmlwdGlvbnMgc2hvdWxkIGJlIHByb3ZpZGVkLiBJbiB0aGlzIHNlY3Rpb24sIHlvdSBtdXN0IGFsc28gcHJvdmlkZSB0aGUgUiBjb2RlcyB3aXRoIG91dHB1dHMgKGhlYWQgb2YgZGF0YSBzZXRzKSB0aGF0IHlvdSB1c2VkIHRvIGltcG9ydC9yZWFkL3NjcmFwZSB0aGUgZGF0YSBzZXQuIFlvdSBuZWVkIHRvIGZ1bGZpbCB0aGUgbWluaW11bSByZXF1aXJlbWVudCAjMSBhbmQgbWVyZ2UgYXQgbGVhc3QgdHdvIGRhdGEgc2V0cyB0byBjcmVhdGUgdGhlIG9uZSB5b3UgYXJlIGdvaW5nIHRvIHdvcmsgb24uIEluIGFkZGl0aW9uIHRvIHRoZSBSIGNvZGVzIGFuZCBvdXRwdXRzLCB5b3UgbmVlZCB0byBleHBsYWluIHRoZSBzdGVwcyB0aGF0IHlvdSBoYXZlIHRha2VuLgoKCmBgYHtyfQojIFRoaXMgaXMgdGhlIFIgY2h1bmsgZm9yIHRoZSBEYXRhIFNlY3Rpb24KCiMjIEV4ZWN1dGl2ZSBTdW1tYXJ5CiNUaGlzIHJlcG9ydCBwcm92aWRlcyB0aGUgcHJlcHJvY2Vzc2luZyBvZiAyIGRhdGFzZXRzLCB3aGljaCBjb250YWlucyBtZXRob2RzIHRvIG1lcmdlIGRhdGFzZXRzLCBjb252ZXJ0IHZhcmlhYmxlIHR5cGUsIGxhYmVsIGZhY3RvciB2YXJpYWJsZSwgcmVzaGFwZSBkYXRhIGludG8gYSB0aWR5IGZvcm1hdCwgbXV0YXRlIG5ldyB2YXJpYWJsZSwgc2NhbiBvdXRsaWVycyBmb3IgbnVtZXJpYyB2YXJpYWJsZXMsIHRyYW5zZm9ybSBkYXRhLCBzY2FuIGVycm9ycyAobWlzc2luZyB2YWx1ZXMsIHNwZWNpYWwgdmFsdWVzLCBvYnZpb3VzIGVycm9ycywgYW5kIGluY29uc2lzdGVuY3kpIGFuZCB1c2UgdGhlIHRlY2huaXF1ZSB0byBkZWFsIHdpdGggZXJyb3JzIChtaXNzaW5nIHZhbHVlcywgc3BlY2lhbCB2YWx1ZXMsIG9idmlvdXMgZXJyb3JzLCBhbmQgaW5jb25zaXN0ZW5jeSkgYnkgb25seSB1c2luZyBwYWNrYWdlcyBvZiB0aWR5ciwgZHBseXIsIGVkaXRydWxlcywgZGVkdWNvcnJlY3QsIGFuZCBvdXRsaWVycy4gVGhpcyByZXBvcnQgYWltcyB0byBwcm92aWRlIGEgc2FtcGxlIG9mIGhvdyB0byBwcmVwcm9jZXNzIGRhdGFzZXRzLCB0aGUgc291cmNlIG9mIGRhdGFzZXRzIGlzIGFsbCBjb21lIGZyb20gdGhlIGdvdmVybm1lbnQgb2YgVklDIGh0dHBzOi8vd3d3LnZpYy5nb3YuYXUvLCB0aGV5IGFyZSBhbGwgb3BlbiBhbmQgaGF2ZSBhIENyZWF0aXZlIENvbW1vbnMgTGljZW5jZS4gCgoKIyMgRGF0YQoKI0ltcG9ydCBkYXRhc2V0IGZyb20gd2Vic2l0ZSwgdGhpcyBkYXRhc2V0IGlzIGZyb20gdGhlIGdvdmVybm1lbnQgb2YgdmljdG9yaWEgYW5kIGl0J3Mgc291cmNlIHdlYnNpdGUgaXM6IGh0dHBzOi8vZGlzY292ZXIuZGF0YS52aWMuZ292LmF1L2RhdGFzZXQvYWxsLXNjaG9vbHMtZnRlLWVucm9sbWVudHMtZmViLTIwMTUuIFRoaXMgZGF0YXNldCBjb250YWlucyBpbmZvcm1hdGlvbiBjb2xsZWN0ZWQgZnJvbSB0aGUgRmVicnVhcnkgMjAxNCBzY2hvb2wgY2Vuc3VzIG9mIFZpY3RvcmlhbiBzY2hvb2xzIHVudGlsIEZlYnJ1YXJ5IDIwMTUuIFRoaXMgZGF0YXNldCBjb250YWlucyA1NCB2YXJpYWJsZXMgYnV0IHdlIGFyZSBnb2luZyB0byBzdWJzZXQgdG8gOSB2YXJpYWJsZXMgb3RoZXJ3aXNlIGl0IHdpbGwgYmUgdG9vIGxhcmdlIGFuZCB3aGVuIHdlIG1lcmdlIHZhcmlhYmxlcyB0b2dldGhlciBvciBtZXJnZSB0d28gZGF0YXNldHMgdG9nZXRoZXIsIFIgd2lsbCByZXBvcnRzIEVycm9yOiB2ZWN0b3IgbWVtb3J5IGV4aGF1c3RlZCAobGltaXQgcmVhY2hlZD8pLiBBZnRlciB3ZSBzdWJzZXQgdGhlIGRhdGEgc2V0LCB0aGVyZSB3aWxsIGJlIDkgdmFyaWFibGVzIGxlZnQ6IAoKIyJFZHVjYXRpb25fU2VjdG9yIjpJdCByZWZlcnMgdG8gZWR1Y2F0aW9uYWwgc2VjdG9yLgojIkVudGl0eV9UeXBlIjpJdCByZWZlcnMgdG8gdHlwZSBvZiBzY2hvb2wgZGlzdHJpY3QuICAgICAgIAojIlNjaG9vbF9ObyI6SXQgcmVmZXJzIHRvIHRoZSBjb2RlIHRoYXQgcmVwcmVzZW50IHRoZSBzY2hvb2wuCiMiU2Nob29sX05hbWUiOkl0IHJlZmVycyB0byB0aGUgbmFtZSBvZiBzY2hvb2wuICAgICAgICAgCiMiU2Nob29sX1R5cGUiOkl0IHJlZmVycyB0byB0aGUgdHlwZSBvZiBzY2hvb2wuICAgICAgICAgCiMiU2Nob29sX1N0YXR1cyI6SXQgcmVmZXJzIHRvIHRoZSBzdGF0dXMgb2Ygc2Nob29sLgojIlByZXAuTWFsZXMuVG90YWwuLiI6SXQgcmVmZXJzIHRvIHRoZSB0b3RhbCBudW1iZXIgb2YgcHJlcGFyYXRvcnkgbWFsZSBzdHVkZW50LgojIlByZXAuRmVtYWxlcy5Ub3RhbC4uIjpJdCByZWZlcnMgdG8gdGhlIHRvdGFsIG51bWJlciBvZiBwcmVwYXJhdG9yeSBmZW1hbGUgc3R1ZGVudC4KIyJQcmVwLlRvdGFsLi4iOkl0IHJlZmVycyB0byB0aGUgdG90YWwgbnVtYmVyIG9mIHByZXBhcmF0b3J5IHN0dWRlbnQuIAoKI0ltcG9ydCBkYXRhc2V0IGZyb20gd2Vic2l0ZS4KdXJsIDwtICJodHRwOi8vd3d3LmVkdWNhdGlvbi52aWMuZ292LmF1L0RvY3VtZW50cy9hYm91dC9yZXNlYXJjaC9kYXRhdmljL2R2MTcxLUZlYjIwMTVGVEVlbnJvbG1lbnRzLmNzdiIKQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTUgPC0gcmVhZC5jc3YodXJsLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCgojV2UgbmVlZCB0byBzdWJzZXQgZGF0YSBiZWNhdXNlIHRoaXMgZGF0YXNldCBpcyB0b28gYmlnLCBpZiB3ZSBkb24ndCBzdWJzZXQgZGF0YXNldCwgdGhlbiB3aGVuIHdlIG1lcmdlIHZhcmlhYmxlcyB0b2dldGhlciBvciBtZXJnZSB0d28gZGF0YXNldHMgdG9nZXRoZXIsIFIgd2lsbCByZXBvcnRzIEVycm9yOiB2ZWN0b3IgbWVtb3J5IGV4aGF1c3RlZCAobGltaXQgcmVhY2hlZD8pLgpBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNSA8LSBzdWJzZXQoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTUsIHNlbGVjdCA9IEVkdWNhdGlvbl9TZWN0b3I6UHJlcC5Ub3RhbC4uKQoKaGVhZChBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNSkKCgoKI0ltcG9ydCBkYXRhc2V0IGZyb20gYW5vdGhlciB3ZWJzaXRlLCB0aGlzIGRhdGFzZXQgaXMgZnJvbSB0aGUgZ292ZXJubWVudCBvZiB2aWN0b3JpYSBhbmQgaXQncyBzb3VyY2Ugd2Vic2l0ZSBpczogaHR0cHM6Ly9kaXNjb3Zlci5kYXRhLnZpYy5nb3YuYXUvZGF0YXNldC9hbGwtc2Nob29scy1mdGUtZW5yb2xtZW50cy1mZWItMjAxNi4gVGhpcyBkYXRhc2V0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGNvbGxlY3RlZCBmcm9tIHRoZSBGZWJydWFyeSAyMDE1IHNjaG9vbCBjZW5zdXMgb2YgVmljdG9yaWFuIHNjaG9vbHMgdW50aWwgRmVicnVhcnkgMjAxNi4gVGhpcyBkYXRhc2V0IGFsc28gY29udGFpbnMgNTQgdmFyaWFibGVzIGJ1dCB3ZSBhcmUgZ29pbmcgdG8gc3Vic2V0IHRvIDkgdmFyaWFibGVzIGR1ZSB0byB0aGUgcHJvYmxlbSBvZiBsYXJnZSBkYXRhc2V0LiBBbmQgdGhlc2UgOSB2YXJpYWJsZXMgYXJlIHRoZSBzYW1lIGFzIHRoZSBwcmV2aW91cyBkYXRhc2V0LCBpdCBtZWFucyB0aGF0IHRoZXkgaGF2ZSB0aGUgc2FtZSB2YXJpYWJsZSBhbmQgYWxzbyB0aG9zZSB2YXJpYWJsZXMgaGF2ZSB0aGUgc2FtZSBtZWFuaW5nLgoKI0ltcG9ydCBkYXRhc2V0IGZyb20gd2Vic2l0ZS4KdXJsIDwtICJodHRwOi8vd3d3LmVkdWNhdGlvbi52aWMuZ292LmF1L0RvY3VtZW50cy9hYm91dC9yZXNlYXJjaC9kYXRhdmljL2R2MjE0LWFsbHNjaG9vbHNmZXRlbnJvbGZlYjIwMTYuY3N2IgpBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNiA8LSByZWFkLmNzdih1cmwsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKCiNXZSB1c2UgYW50aV9qb2luKCkgZnVuY3Rpb24gdG8gb2J0YWluIHRoZSBkaWZmZXJlbnQgZGF0YSBmcm9tIHN0dWRlbnQgZW5yb2xtZW50cyBpbiAyMDE1IChOZXcgZGF0YSksIGJlY2F1c2Ugd2Ugd291ZGwgbGlrZSBtZXJnZSBhZGRpdGlvbmFsIGRhdGEgZnJvbSBzdHVkZW50IGVucm9sbWVudHMgaW4gMjAxNiB3aXRoIHN0dWRlbnQgZW5yb2xtZW50cyBpbiAyMDE2IGluIG5leHQgc3RlcC4KTmV3X0FsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE2IDwtIGFudGlfam9pbihBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNiwgQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTUsIGJ5ID0gIlNjaG9vbF9OYW1lIikKCiNUaGUgc2FtZSBzaXR1YXRpb24gaW4gdGhpcyBvbmUsIHdlIGhhdmUgdG8gbWluaW1pemUgZGF0YSBvdGhlcndpc2UsIFIgd2lsbCBnZW5lcmF0ZSBlcnJvciB3aGVuIG1lcmdlIDIgZGF0YXNldCBiZWNhdXNlIHRoZXkgYXJlIHRvbyBsYXJnZS4KTmV3X0FsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE2IDwtIHN1YnNldChOZXdfQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTYsIHNlbGVjdCA9IEVkdWNhdGlvbl9TZWN0b3I6UHJlcC5Ub3RhbC4uKQoKaGVhZChOZXdfQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTYpCgojV2UgdXNlIGJpbmRfcm93cygpIGZ1bmN0aW9uIHRvIG1lcmdlIHR3byBkYXRhc2V0cyBiZWNhdXNlIHRoZXkgaGF2ZSB0aGUgc2FtZSB2YXJpYWJsZXMuCkFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzIDwtIGJpbmRfcm93cyhBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNSwgTmV3X0FsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE2KQoKaGVhZChBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50cykKYGBgCgoKIyMJVGlkeSAmIE1hbmlwdWxhdGUgRGF0YSBJIAoKRXhwbGFpbiB3aHkgeW91ciBkYXRhIChvciBvbmUgb2YgdGhlIGRhdGEgc2V0cykgZG9lc27igJl0IGNvbmZvcm0gdGhlIHRpZHkgZGF0YSBwcmluY2lwbGVzIChtaW5pbXVtIHJlcXVpcmVtZW50ICM1KS4gQXBwbHkgdGhlIHJlcXVpcmVkIHN0ZXBzIHRvIHJlc2hhcGUgdGhlIGRhdGEgaW50byBhIHRpZHkgZm9ybWF0LiBJbiBhZGRpdGlvbiB0byB0aGUgUiBjb2RlcyBhbmQgb3V0cHV0cywgZXhwbGFpbiBldmVyeXRoaW5nIHRoYXQgeW91IGRvIGluIHRoaXMgc3RlcC4KCgpgYGB7cn0KIyBUaGlzIGlzIHRoZSBSIGNodW5rIGZvciB0aGUgVGlkeSAmIE1hbmlwdWxhdGUgRGF0YSBJIAoKI1dlIHB1dCB0aGlzIHBhcnQgKFRpZHkgJiBNYW5pcHVsYXRlIERhdGEgSSkgcHJpb3IgdG8gdGhlIChVbmRlcnN0YW5kKSBwYXJ0IGlzIGJlY2F1c2UgdGhlcmUgd2lsbCBiZSBzb21lIHZhcmlhYmxlcyBjcmVhdGVkIGFmdGVyIHdlIHRpZHkgdGhpcyBkYXRhc2V0IGFuZCBpdCBpcyBiZXR0ZXIgdG8gY29udmVydCB2YXJpYWJsZSB0eXBlLCByZW5hbWUgdmFyaWFibGUsIHJlYXJyYW5nZSB2YXJpYWJsZXMgYWZ0ZXIgd2Ugc2V0IGRvd24gdGhlIGRhdGFzZXQuIAoKCgojVGhlIHByb2JsZW0gb2YgdGhpcyBkYXRhc2V0IGlzIHRoYXQgdGhlIGNvbHVtbiBuYW1lcyBhcmUgbm90IG5hbWVzIG9mIHZhcmlhYmxlcywgYnV0IHZhbHVlcyBvZiBhIHZhcmlhYmxlLiBJbiB0aGlzIGNhc2UsIHRoZSBjb2x1bW4gbmFtZXMgIlByZXAuTWFsZXMuVG90YWwuLiIsIGFuZCAiUHJlcC5GZW1hbGVzLlRvdGFsLi4iIHJlcHJlc2VudCB2YWx1ZXMgb2YgdGhlIGdlbmRlciB2YXJpYWJsZSwgYW5kIGVhY2ggcm93IHJlcHJlc2VudHMgdHdvIG9ic2VydmF0aW9ucywgbm90IG9uZS4gCmhlYWQoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHMpCgojVGhlcmVmb3JlLCB3ZSB1c2UgZ2F0aGVyKCkgZnVuY3Rpb24gdG8gbWVyZ2UgdHdvIHZhcmlhYmxlcyBpbnRvIGEgZmFjdG9yIHZhcmlhYmxlIGFuZCBhbHNvIGNyZWF0ZSBhIG5ldyB2YXJpYWJsZSB3aGljaCBpcyBjYWxsZWQgIk51bWJlcl9vZl9zdHVkZW50cyIuCkFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIgPC0gQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHMgJT4lCmdhdGhlcihgUHJlcC5NYWxlcy5Ub3RhbC4uYCwgYFByZXAuRmVtYWxlcy5Ub3RhbC4uYCwga2V5ID0gIkdlbmRlciIsIHZhbHVlID0gIk51bWJlcl9vZl9zdHVkZW50cyIpCgpoZWFkKEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIpCgoKYGBgCgojIyBVbmRlcnN0YW5kIAoKU3VtbWFyaXNlIHRoZSB0eXBlcyBvZiB2YXJpYWJsZXMgYW5kIGRhdGEgc3RydWN0dXJlcywgY2hlY2sgdGhlIGF0dHJpYnV0ZXMgaW4gdGhlIGRhdGEgYW5kIGFwcGx5IHByb3BlciBkYXRhIHR5cGUgY29udmVyc2lvbnMuIEluIGFkZGl0aW9uIHRvIHRoZSBSIGNvZGVzIGFuZCBvdXRwdXRzLCBleHBsYWluIGJyaWVmbHkgdGhlIHN0ZXBzIHRoYXQgeW91IGhhdmUgdGFrZW4uIEluIHRoaXMgc2VjdGlvbiwgc2hvdyB0aGF0IHlvdSBoYXZlIGZ1bGZpbGxlZCBtaW5pbXVtIHJlcXVpcmVtZW50cyAyLTQuCgoKYGBge3J9CiMgVGhpcyBpcyB0aGUgUiBjaHVuayBmb3IgdGhlIFVuZGVyc3RhbmQgU2VjdGlvbgoKI1JlYXJyYW5nZSBhbmQgcmVuYW1lIGFuZCByZWFycmFuZ2UgdmFyaWFibGVzCiNXZSBmaXJzdCBjaGVjayB0aGUgb3JkZXIgb2YgdmFyaWFibGVzLiAKc3RyKEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIpCgojV2UgdXNlIHNlbGVjdCgpIGZ1bmN0aW9uIHRvIHJlYXJyYW5nZSB0aGUgb3JkZXIgb2YgdmFyaWFibGVzLgpBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yIDwtIEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIgJT4lIHNlbGVjdChTY2hvb2xfTmFtZSwgU2Nob29sX05vLCBTY2hvb2xfVHlwZSwgU2Nob29sX1N0YXR1cywgRWR1Y2F0aW9uX1NlY3RvciwgRW50aXR5X1R5cGUsIEdlbmRlciwgTnVtYmVyX29mX3N0dWRlbnRzLCBQcmVwLlRvdGFsLi4pCgojR2l2ZW4gdGhhdCB3ZSBnYXRoZXIgdHdvIHZhcmlhYmxlcyB0b2dldGhlciB0byBidWlsZCB1cCBhIGZhY3RvciB2YXJpYWJsZSAiR2VuZGVyIi4gV2Ugc2hvdWxkIHJlbmFtZSB0aGUgbGV2ZWxzIG9mICJHZW5kZXIiLgojVGhlbiwgdXNlIGxldmVscygpIGZ1bmN0aW9uIHRvIGNoZWNrIHRoZSBsZXZlbCBuYW1lIG9mIHRoaXMgdmFyaWFibGUuCmxldmVscyhBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yJEdlbmRlcikKCiNXZSB1c2UgbGFiZWwoKSBmdW5jdGlvbiB0byByZS1sYWJlbCB0aGUgbmFtZSBvZiBsZXZlbHMgaW4gYSBmYWN0b3IgdmFyaWFibGUuCkFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIkR2VuZGVyIDwtIGZhY3RvcihBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yJEdlbmRlcixsZXZlbHMgPSBjKCJQcmVwLkZlbWFsZXMuVG90YWwuLiIsIlByZXAuTWFsZXMuVG90YWwuLiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiRmVtYWxlIiwiTWFsZSIpKQoKI1dlIGFsc28gbm90aWNlIHRoYXQgdGhlIHZhcmlhYmxlIG5hbWUgb2YgIlByZXAuVG90YWwuLiIgZG9lc24ndCBsb29rIGdvb2QgKGJlY2F1c2UgdGhlcmUgYXJlIHNvbWUgIi4uIiBpbiB0aGUgbmFtZSkgYW5kICJOdW1iZXJfb2Zfc3R1ZGVudHMiIHNob3VsZCBhY3R1YWxseSBiZSAiTnVtYmVyX29mX3ByZS5zdHVkZW50Ii4KI1dlIHVzZSByZW5hbWUoKSBmdW5jdGlvbiB0byByZW5hbWUgdmFyaWFibGVzLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIApBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yIDwtIEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIgJT4lIAogIHJlbmFtZSgKICAgIFRvdGFsX251bWJlcl9vZl9wcmUuc3R1ZGVudF9mb3Jfc2Nob29sID0gUHJlcC5Ub3RhbC4uCiAgICAsIE51bWJlcl9vZl9wcmUuc3R1ZGVudCA9IE51bWJlcl9vZl9zdHVkZW50cwogICkKCiNDaGVjayB0aGUgdmFyaWFibGVzIGFuZCBvcmRlciBhZ2FpbiwgdGhpcyBhbHNvIHByb3ZlIHRoYXQgdGhpcyBkYXRhc2V0IGNvbnRhaW5zIG11bHRpcGxlIGRhdGEgdHlwZXMgKG51bWVyaWNzLCBjaGFyYWN0ZXJzLCBmYWN0b3JzKS4Kc3RyKEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIpCgoKCiNDb252ZXJ0IHZhcmlhYmxlIHR5cGUKI05vdGljZSB0aGF0ICJFZHVjYXRpb25fU2VjdG9yIiBoYXMgc29tZSB2YWx1ZXMgYXJlIHRoZSBzYW1lLCBzbyB0cnkgdG8gY292ZXJ0IGl0IGludG8gZmFjdG9yIHZhcmlhYmxlLgpBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yJEVkdWNhdGlvbl9TZWN0b3IgPC0gYXMuZmFjdG9yKEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIkRWR1Y2F0aW9uX1NlY3RvcikKCmlzLmZhY3RvcihBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yJEVkdWNhdGlvbl9TZWN0b3IpCgojQ2hlY2sgdGhlIGxldmVscyBvZiB0aGlzIHZhcmlhYmxlLCBhbmQgdGhlIHJlc3VsdCBpcyB0aGF0IHRoZXJlIGFyZSBvbmx5IDMgbGV2ZWxzLiBUaGlzIGNvbmZpcm1zIG15IGd1ZXNzIGFuZCB0aGlzIHZhcmlhYmxlIHNob3VsZCBhY3R1YWxseSBiZSBhIGZhY3RvciB2YXJpYWJsZS4KbGV2ZWxzKEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIkRWR1Y2F0aW9uX1NlY3RvcikKCgojRW50aXR5X1R5cGUgaXMgb2J2aW91c2x5IGEgZmFjdG9yIHZhcmlhYmxlIGJ1dCBSIGluZGljYXRlIHRoYXQgYXMgaW50LiBTbywgd2UgbmVlZCB0byBjb252ZXJ0IGl0IGludG8gZmFjdG9yIHZhcmlhYmxlLgpBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yJEVudGl0eV9UeXBlIDwtIGFzLmZhY3RvcihBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yJEVudGl0eV9UeXBlKQoKaXMuZmFjdG9yKEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIkRW50aXR5X1R5cGUpCgojVG8gZW5zdXJlIHRoYXQgdGhpcyB2YXJpYWJsZSBpcyBhIGZhY3RvciB2YXJpYWJsZSwgd2UgY2hlY2sgdGhlIGxldmVscyBmb3IgdGhpcyB2YXJpYWJsZSBhbmQgdGhlIHJlc3VsdCBpcyB0aGF0IHRoZXJlIGFyZSBvbmx5IDIgbGV2ZWxzLiBUaGlzIGNvbmZpcm1zIG15IGd1ZXNzIGFuZCB0aGlzIHZhcmlhYmxlIHNob3VsZCBhY3R1YWxseSBiZSBhIGZhY3RvciB2YXJpYWJsZS4KbGV2ZWxzKEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIkRW50aXR5X1R5cGUpCgoKCiNTY2hvb2xfVHlwZSBpcyBvYnZpb3VzbHkgYSBmYWN0b3IgdmFyaWFibGUgYnV0IFIgaW5kaWNhdGUgdGhhdCBhcyBjaHIuIFNvLCB3ZSBuZWVkIHRvIGNvbnZlcnQgaXQgaW50byBmYWN0b3IgdmFyaWFibGUuCkFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIkU2Nob29sX1R5cGUgPC0gYXMuZmFjdG9yKEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIkU2Nob29sX1R5cGUpCgppcy5mYWN0b3IoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMiRTY2hvb2xfVHlwZSkKCiNUbyBlbnN1cmUgdGhhdCB0aGlzIHZhcmlhYmxlIGlzIGEgZmFjdG9yIHZhcmlhYmxlLCB3ZSBjaGVjayB0aGUgbGV2ZWxzIGZvciB0aGlzIHZhcmlhYmxlIGFuZCB0aGUgcmVzdWx0IGlzIHRoYXQgdGhlcmUgYXJlIG9ubHkgNSBsZXZlbHMuIFRoaXMgY29uZmlybXMgbXkgZ3Vlc3MgYW5kIHRoaXMgdmFyaWFibGUgc2hvdWxkIGFjdHVhbGx5IGJlIGEgZmFjdG9yIHZhcmlhYmxlLgpsZXZlbHMoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMiRTY2hvb2xfVHlwZSkKCgoKI05vdGljZSB0aGF0ICJTY2hvb2xfU3RhdHVzIiBoYXMgc29tZSB2YWx1ZXMgYXJlIHRoZSBzYW1lLCBzbyB0cnkgdG8gY292ZXJ0IGl0IGludG8gZmFjdG9yIHZhcmlhYmxlLgpBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yJFNjaG9vbF9TdGF0dXMgPC0gYXMuZmFjdG9yKEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIkU2Nob29sX1N0YXR1cykKCmlzLmZhY3RvcihBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yJFNjaG9vbF9TdGF0dXMpCgojQ2hlY2sgdGhlIGxldmVscyBvZiB0aGlzIHZhcmlhYmxlLCBhbmQgdGhlIHJlc3VsdCBpcyB0aGF0IHRoZXJlIGFyZSBvbmx5IDIgbGV2ZWxzLiBUaGlzIGNvbmZpcm1zIG15IGd1ZXNzIGFuZCB0aGlzIHZhcmlhYmxlIHNob3VsZCBhY3R1YWxseSBiZSBhIGZhY3RvciB2YXJpYWJsZS4KbGV2ZWxzKEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIkU2Nob29sX1N0YXR1cykKCgoKI1RoaXMgdmFyaWFibGUgaGFzIHRvIGJlIGludGVnZXIgYmVjYXVzZSBpdCBjYW4ndCBiZSBoYWxmIHN0dWRlbnQuCkFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIkTnVtYmVyX29mX3ByZS5zdHVkZW50IDwtIGFzLmludGVnZXIoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMiROdW1iZXJfb2ZfcHJlLnN0dWRlbnQpCmlzLmludGVnZXIoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMiROdW1iZXJfb2ZfcHJlLnN0dWRlbnQpCgoKCiNUaGlzIHZhcmlhYmxlIGhhcyB0byBiZSBpbnRlZ2VyIGJlY2F1c2UgaXQgY2FuJ3QgYmUgaGFsZiBzdHVkZW50LgpBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yJFRvdGFsX251bWJlcl9vZl9wcmUuc3R1ZGVudF9mb3Jfc2Nob29sIDwtIGFzLmludGVnZXIoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMiRUb3RhbF9udW1iZXJfb2ZfcHJlLnN0dWRlbnRfZm9yX3NjaG9vbCkKaXMuaW50ZWdlcihBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yJFRvdGFsX251bWJlcl9vZl9wcmUuc3R1ZGVudF9mb3Jfc2Nob29sKQoKI0NoZWNrIHRoZSB2YXJpYmFsZSB0eXBlIGFnYWluIHRvIG1ha2Ugc3VyZSBldmVyeXRoaW5nIGlzIGdvb2QuIApzdHIoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMikKCmBgYAoKCiMjCVRpZHkgJiBNYW5pcHVsYXRlIERhdGEgSUkgCgpDcmVhdGUvbXV0YXRlIGF0IGxlYXN0IG9uZSB2YXJpYWJsZSBmcm9tIHRoZSBleGlzdGluZyB2YXJpYWJsZXMgKG1pbmltdW0gcmVxdWlyZW1lbnQgIzYpLiBJbiBhZGRpdGlvbiB0byB0aGUgUiBjb2RlcyBhbmQgb3V0cHV0cywgZXhwbGFpbiBldmVyeXRoaW5nIHRoYXQgeW91IGRvIGluIHRoaXMgc3RlcC4KCgpgYGB7cn0KIyBUaGlzIGlzIHRoZSBSIGNodW5rIGZvciB0aGUgVGlkeSAmIE1hbmlwdWxhdGUgRGF0YSBJSSAKCiNNdXRhdGUgbmV3IHZhcmlhYmxlCiNVc2UgbXV0YXRlKCkgZnVuY3Rpb24gdG8gY3JlYXRlIGEgbmV3IHZhcmlhYmxlLiBUaGlzIG5ldyB2YXJpYWJsZSBpcyB0aGUgc2V4IHByb3BvcnRpb24gaW4gdGVybXMgb2YgbWFsZSBhbmQgZmVtYWxlIGZvciBlYWNoIHNjaG9vbC4gQW5kIGl0J3MgZm9ybXVsYSBpczogU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2wgPSBOdW1iZXJfb2ZfcHJlLnN0dWRlbnQgLyBUb3RhbF9udW1iZXJfb2ZfcHJlLnN0dWRlbnRfZm9yX3NjaG9vbC4KQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMiA8LSBtdXRhdGUoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMiwKU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2wgPSBOdW1iZXJfb2ZfcHJlLnN0dWRlbnQgLyBUb3RhbF9udW1iZXJfb2ZfcHJlLnN0dWRlbnRfZm9yX3NjaG9vbAopCgojQ2hlY2sgaWYgd2UgY3JlYXRlICJTZXhfcHJvcG9ydGlvbl9mb3JfdGhlX3ByZS5zdHVkZW50X2luX3NjaG9vbCIgc3VjY2Vzc2Z1bGx5LgpzdHIoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMikKYGBgCgoKIyMJU2NhbiBJIAoKU2NhbiB0aGUgZGF0YSBmb3IgbWlzc2luZyB2YWx1ZXMsIHNwZWNpYWwgdmFsdWVzIGFuZCBvYnZpb3VzIGVycm9ycyAoaS5lLiBpbmNvbnNpc3RlbmNpZXMpLiBJbiB0aGlzIHN0ZXAsIHlvdSBzaG91bGQgZnVsZmlsIHRoZSBtaW5pbXVtIHJlcXVpcmVtZW50ICM3LiBJbiBhZGRpdGlvbiB0byB0aGUgUiBjb2RlcyBhbmQgb3V0cHV0cywgZXhwbGFpbiB5b3VyIG1ldGhvZG9sb2d5IChpLmUuIGV4cGxhaW4gd2h5IHlvdSBoYXZlIGNob3NlbiB0aGF0IG1ldGhvZG9sb2d5IGFuZCB0aGUgYWN0aW9ucyB0aGF0IHlvdSBoYXZlIHRha2VuIHRvIGhhbmRsZSB0aGVzZSB2YWx1ZXMpIGFuZCBjb21tdW5pY2F0ZSB5b3VyIHJlc3VsdHMgY2xlYXJseS4KCgpgYGB7cn0KIyBUaGlzIGlzIHRoZSBSIGNodW5rIGZvciB0aGUgU2NhbiBJCgojU29tZXRpbWVzIGRhdGFzZXQgY2FuIGhhdmUgb2Jpb3VzIGVycm9ycy4gRm9yIGV4YW1wbGUsIHNleCBwcm9wb3J0aW9uIGNhbm5vdCBiZSBuZWdhdGl2ZSBvciBiZXlvbmQgMS4gRm9yIGNoZWNraW5nIHRoZXNlIGluY29uc2lzdGVuY3ksIHdlIHdvdWxkIGxpa2UgdG8gYXBwbHkgcnVsZXMgdG8gY2hlY2sgd2hldGhlciB0aGlzIGRhdGFzZXQgdmlvbGF0ZXMgdGhlIHJ1bGUgYnkgdXNpbmcgZWRpdGZpbGUoKSBmdW5jdGlvbi4gQW5kIGFsc28sIHdlIGNvdWxkIGFsc28gYXBwbHkgcnVsZXMgdG8gY29ycmVjdCBlcnJvcnMgYnkgdXNpbmcgY29ycmVjdGlvblJ1bGVzKCkgZnVuY3Rpb24uIFdoZW4gdGhlIG51bWJlciBvZiBydWxlcyBpbmNyZWFzZSwgaXQgaXMgYmV0dGVyIHRvIG1hbmFnZSB0aGUgcnVsZXMgc2VwYXJhdGUgZnJvbSB0aGUgZGF0YS4gVGhlIGZ1bmN0aW9uIG9mIGVkaXRydWxlcygpIGNhbiBjaGVjayB3aGljaCBydWxlcyBhcmUgb2JleWVkIG9yIG5vdCBhbmQgYWxsb3dzIG9uZSB0byBmaW5kIHRoZSBtaW5pbWFsIHNldCBvZiB2YXJpYWJsZXMgdG8gYWRhcHQgc28gdGhhdCBhbGwgcnVsZXMgY2FuIGJlIG9iZXllZC4gSW4gYWRkaXRpb24sY29ycmVjdGlvblJ1bGVzKCkgZnVuY3Rpb24gZm9yY2UgdmFyaWFibGVzIHRvIGZvbGxvdyBpdCdzIGNvbnN0cmFpbnRzIHNvIHRoYXQsIGl0IGlzIHZlcnkgaGVscGZ1bCB3aGVuIGNvcnJlY3RpbmcgZGF0YS4gSW4gdGhpcyBwYXJ0LCB3ZSBhcmUgZ29pbmcgdG8gdXNpbmcgZWRpdHJ1bGVzKCkgYW5kIGNvcnJlY3Rpb25SdWxlcygpIHRvIGRlYWwgd2l0aCBpbmNvbnNpc3RlbmN5LgoKI1RoZSBmaXJzdCB0aGluZyBpcyB0byBjaGVjayB0aGUgY29uc2lzdGVuY3kgb2YgIlRvdGFsX251bWJlcl9vZl9wcmUuc3R1ZGVudF9mb3Jfc2Nob29sIiA9ICJOdW1iZXJfb2ZfcHJlLnN0dWRlbnQiIGZvciBtYWxlICsgIk51bWJlcl9vZl9wcmUuc3R1ZGVudCIgZm9yIGZlbWFsZS4KI0l0IGlzIG1vcmUgY29udmVuaWVudCB0byBjaGVjayB0aGUgY29uc2lzdGVuY3kgb2YgIlRvdGFsX251bWJlcl9vZl9wcmUuc3R1ZGVudF9mb3Jfc2Nob29sIiA9ICJOdW1iZXJfb2ZfcHJlLnN0dWRlbnQiIGZvciBtYWxlICsgIk51bWJlcl9vZl9wcmUuc3R1ZGVudCIgZm9yIGZlbWFsZSBieSBzcHJlYWRpbmcgdGhlICJHZW5kZXIiIG91dC4KI1dlIGZpbmQgb3V0IHRoYXQgdGhlcmUgaXMgYSB2YXJpYWJsZSBwcmV2ZW50IHVzIHRvIHNwcmVhZCAiR2VuZGVyIiBvdXQgaW4gIkFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIiLCB3aGljaCBpcyBjYWxsZWQgIlNleF9wcm9wb3J0aW9uX2Zvcl90aGVfcHJlLnN0dWRlbnRfaW5fc2Nob29sIi4gCiNUaGF0IGlzIGJlY2F1c2UgIlNleF9wcm9wb3J0aW9uX2Zvcl90aGVfcHJlLnN0dWRlbnRfaW5fc2Nob29sIiA9ICJOdW1iZXJfb2ZfcHJlLnN0dWRlbnQiLyJUb3RhbF9udW1iZXJfb2ZfcHJlLnN0dWRlbnRfZm9yX3NjaG9vbCIuIEFuZCB3aGVuIHdlIHNwcmVhZCAiR2VuZGVyIiBvdXQsIGl0IHdpbGwgcHJvZHVjZSBtYW55IE5hTiB2YWx1ZXMuCiNBbmQgdGhpcyBpcyB3aHkgd2Ugc2hvdWxkIGV4Y2x1ZGUgIlNleF9wcm9wb3J0aW9uX2Zvcl90aGVfcHJlLnN0dWRlbnRfaW5fc2Nob29sIiBmaXJzdCBhbmQgdGhlbiBzcHJlYWQgIkdlbmRlciIgb3V0LgpEYXRhX2Zvcl9jaGVja2luZ19pbmNvbnNpc3RlbmN5MSA9IHN1YnNldChBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18yLCBzZWxlY3QgPSAtU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2wgKQoKI0FuZCB0aGVuIHdlIHVzZSBzcHJlYWQoKSBmdW5jdGlvbiB0byBzcHJlYWQgaXQgb3V0LgpEYXRhX2Zvcl9jaGVja2luZ19pbmNvbnNpc3RlbmN5MiA8LSBzcHJlYWQoRGF0YV9mb3JfY2hlY2tpbmdfaW5jb25zaXN0ZW5jeTEsIGtleSA9IEdlbmRlciwgdmFsdWUgPSBOdW1iZXJfb2ZfcHJlLnN0dWRlbnQpCgojSW1wb3J0IHJ1bGVzIGludG8gUgpSdWxlczEgPC0gZWRpdGZpbGUoIi9Vc2Vycy9tYWNib29rL0RvY3VtZW50cy9STUlULU1hc3RlciBvZiBBbmFseXRpY3MvRGF0YSB3cmFuZ2xpbmcvZWRpdHJ1bGVzMi50eHQiLCB0eXBlID0gImFsbCIpCgpSdWxlczEKCiNDaGVjayB3aGljaCB2YWx1ZSB2aW9sYXRlcyB0aGUgcnVsZXMsIGJ1dCB0aGUgd2Vha25lc3MgaXMgdGhhdCB0aGUgZGF0YSBzaXplIGlzIHRvbyBsYXJnZSBhbmQgUiBhdXRvbWF0aWNhbGx5IG9taXQgc29tZSByb3dzLgp2aW9sYXRlZEVkaXRzKFJ1bGVzMSwgRGF0YV9mb3JfY2hlY2tpbmdfaW5jb25zaXN0ZW5jeTIpCgojVG8gZGVhbCB3aXRoIHRoZSBwcm9ibGVtIG9mICJsYXJnZSBkYXRhIHNpemUiLCB3ZSBjb3VsZCB1c2Ugc3VtbWFyeSgpIGZ1bmN0aW9uLgpWaW9sYXRlZDEgPC0gdmlvbGF0ZWRFZGl0cyhSdWxlczEsIERhdGFfZm9yX2NoZWNraW5nX2luY29uc2lzdGVuY3kyKQoKc3VtbWFyeShWaW9sYXRlZDEpCgojVGhlIHJlc3VsdCBzaG93cyB0aGF0IHRoaXMgZGF0YSBkb2VzIGhhdmUgc29tZSBlcnJvcnMuCgoKCiNUbyBjb3JyZWN0IHRob3NlIGVycm9ycywgd2UgaW1wb3J0IHJ1bGVzIGZvciBjb3JyZWN0aW9uLgpSdWxlczIgPC0gY29ycmVjdGlvblJ1bGVzKCIvVXNlcnMvbWFjYm9vay9Eb2N1bWVudHMvUk1JVC1NYXN0ZXIgb2YgQW5hbHl0aWNzL0RhdGEgd3JhbmdsaW5nL2VkaXRydWxlczMudHh0IikKCiNBcHBseSBydWxlcyBpbnRvIHRoZSBkYXRhIHRoYXQgY29udGFpbnMgZXJyb3JzLgpjb3IgPC0gY29ycmVjdFdpdGhSdWxlcyhSdWxlczIsIERhdGFfZm9yX2NoZWNraW5nX2luY29uc2lzdGVuY3kyKQoKY29yCgojVGhpcyBpcyB0aGUgZGF0YSBhZnRlciBjb3JyZWN0aW9uLgpjb3IkY29ycmVjdGVkCgojQW5kIHRoZW4sIGNoZWNrIGl0IGFnYWluIHdoZXRoZXIgd2Ugc3VjY2Vzc2Z1bGx5IGNvcnJlY3QgZXJyb3JzLgp2aW9sYXRlZEVkaXRzKFJ1bGVzMSwgY29yJGNvcnJlY3RlZCkKCiNVc2Ugc3VtbWFyeSgpIGZ1bmN0aW9uIHRvIGF2b2lkIHRoZSBwcm9ibGVtIG9mIGxhcmdlIGRhdGEgc2l6ZS4KVmlvbGF0ZWQyIDwtIHZpb2xhdGVkRWRpdHMoUnVsZXMxLCBjb3IkY29ycmVjdGVkKQoKc3VtbWFyeShWaW9sYXRlZDIpCgoKCiNBbmQgdGhlbiwgYWZ0ZXIgY29ycmVjdGluZyB0aGUgZGF0YSwgd2UgcHV0ICJTZXhfcHJvcG9ydGlvbl9mb3JfdGhlX3ByZS5zdHVkZW50X2luX3NjaG9vbCIgYmFjayBpbnRvIHRoZSBkYXRhc2V0LgojVGhlIGZpcnN0IHRoaW5nIGlzIHRvIHJlc2hhcGUgdGhlIGRhdGFzZXQgb2YgIkRhdGFfZm9yX2NoZWNraW5nX2luY29uc2lzdGVuY3kyIi4KQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMyA8LSBEYXRhX2Zvcl9jaGVja2luZ19pbmNvbnNpc3RlbmN5MiAlPiUKICBnYXRoZXIoYE1hbGVgLCBgRmVtYWxlYCwga2V5ID0gIkdlbmRlciIsIHZhbHVlID0gIk51bWJlcl9vZl9wcmUuc3R1ZGVudCIpCgojQW5kIHRoZW4sIHB1dCAiU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2wiIGJhY2sgaW50byB0aGUgZGF0YXNldC4KQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMyA8LSBtdXRhdGUoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2wgPSBOdW1iZXJfb2ZfcHJlLnN0dWRlbnQgLyBUb3RhbF9udW1iZXJfb2ZfcHJlLnN0dWRlbnRfZm9yX3NjaG9vbAopCgojQW5kIHRoZW4sIHJlYXJyYW5nZSB0aGUgc2VxdWVuY2Ugb2YgdmFyaWFibGVzLgpBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zIDwtIEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzIgJT4lIHNlbGVjdChTY2hvb2xfTmFtZSwgU2Nob29sX05vLCBTY2hvb2xfVHlwZSwgU2Nob29sX1N0YXR1cywgRWR1Y2F0aW9uX1NlY3RvciwgRW50aXR5X1R5cGUsIEdlbmRlciwgTnVtYmVyX29mX3ByZS5zdHVkZW50LCBUb3RhbF9udW1iZXJfb2ZfcHJlLnN0dWRlbnRfZm9yX3NjaG9vbCwgU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2wpCgoKCiNUaGUgc2Vjb25kIHRoaW5nIGlzIHRvIGNoZWNrIGluaWZpdGUgdmFsdWUsIHNwZWNpYWwgdmFsdWUsIGFuZCBtaXNzaW5nIHZhbHVlLiBGb3IgY29udmVuaWVuY2UsIHdlIGZpcnN0IGJ1aWxkIHVwIGEgZnVuY3Rpb24gdG8gYmV0dGVyIGRlYWwgd2l0aCBtaXNzaW5nIHZhbHVlcywgaW5maW5pdGUgdmFsdWVzLCBhbmQgTmFOIHZhbHVlcy4gV2UgYWN1dGFsbHkgd291bGQgbGlrZSB0byB1c2Ugc2FwcGx5KCkgZnVuY3Rpb24gdG8gbG9vayBmb3IgZXJyb3JzIGJ1dCB0aGlzIGZ1bmN0aW9uIGNvdWxkIG5vdCBkZWFsIHdpdGggTmFOIHZhbHVlcy4gVGh1cywgd2Ugc2hvdWxkIHdyaXRlIHVwIGEgZnVuY3Rpb24gdG8gZGVhbCB3aXRoIE5hTiB2YWx1ZXMuCmlzLnNwZWNpYWxvck5BIDwtIGZ1bmN0aW9uKHgpewogIGlmIChpcy5udW1lcmljKHgpKSAoaXMuaW5maW5pdGUoeCkgfCBpcy5uYW4oeCkgfCBpcy5uYSh4KSkKfQoKI1RoZXJlIGFyZSA5MzIgbmEgdmFsdWUgZm9yIGNvbHVtbiAiU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2wiCnNhcHBseShBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zLCBmdW5jdGlvbih4KSBzdW0oIGlzLm5hKHgpICkpCgojVGhlcmUgYXJlIDAgaW5maW5pdGUgdmFsdWUgZm9yIHRoaXMgZGF0YXNldApzYXBwbHkoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMywgZnVuY3Rpb24oeCkgc3VtKCBpcy5pbmZpbml0ZSh4KSApKQoKI1RoZXJlIGFyZSA5MzIgTmFOIHZhbHVlIGZvciBjb2x1bW4gIlNleF9wcm9wb3J0aW9uX2Zvcl90aGVfcHJlLnN0dWRlbnRfaW5fc2Nob29sIgpzYXBwbHkoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMywgZnVuY3Rpb24oeCkgc3VtKCBpcy5uYW4oeCkgKSkKCiNOYU4gbWVhbnMgIm5vdCBhIG51bWJlciIuIFdoZW4gUiBnZW5lcmF0ZSBOYU4sIGl0IG1lYW5zIHRoYXQgdGhlIHZhbHVlIGp1c3QgbWFrZXMgYSBsaXR0bGUgc2Vuc2UuIEluIHRoaXMgY2FzZSwgd2UgZmluZCBvdXQgYSBsb3Qgb2YgTmFOcyBpbiB0aGUgdmFyaWFibGUgb2Yg4oCcU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2zigJ0sIHdoaWNoIGlzIGNhbGN1bGF0ZWQgYnkgdGhlIGZvcm11bGEgb2Y6CiNTZXhfcHJvcG9ydGlvbl9mb3JfdGhlX3ByZS5zdHVkZW50X2luX3NjaG9vbCA9IE51bWJlcl9vZl9wcmUuc3R1ZGVudCAvIFRvdGFsX251bWJlcl9vZl9wcmUuc3R1ZGVudF9mb3Jfc2Nob29sLiAKI051bWJlcl9vZl9wcmUuc3R1ZGVudCBjYW4gYmUgMCBhbmQgVG90YWxfbnVtYmVyX29mX3ByZS5zdHVkZW50X2Zvcl9zY2hvb2wgY2FuIGJlIDAgZWl0aGVyLiBUaGUgaXMgdGhlIHJlYXNvbiBvZiBOYU4gYmVjYXVzZSB3aGVuIDAgZGl2aWRlZCBieSAwLCBpdCBpcyBtZWFuaW5nbGVzcyBhbmQgdGhhdOKAmXMgd2h5IFIgZ2VuZXJhdGUgTmFOIGFzIHRoZSByZXN1bHQuIFRvIGZpeCB0aGlzIHNwZWNpYWwgdmFsdWUsIHdlIGNhbiBqdXN0IGNvdmVydCBOYU4gdG8gMCBkaXJlY3RseS4gCkFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzMkU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2xbQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMyRTZXhfcHJvcG9ydGlvbl9mb3JfdGhlX3ByZS5zdHVkZW50X2luX3NjaG9vbCA9PSAiTmFOIiBdIDwtIDAKCiNBbmQgdGhlbiwgY2hlY2sgaXQgYWdhaW4gd2hldGhlciB3ZSBlbGltaW5hdGUgYWxsIE5hTiB2YWx1ZXMgYW5kIE5hIHZhbHVlcy4Kc2FwcGx5KEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzMsIGZ1bmN0aW9uKHgpIHN1bSggaXMubmEoeCkgKSkKCnNhcHBseShBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zLCBmdW5jdGlvbih4KSBzdW0oIGlzLm5hbih4KSApKQoKI1dlIHN1Y2Nlc3NmdWxseSByZW1vdmUgYWxsIE5hTiB2YWx1ZXMgYW5kIE5hIHZhbHVlcy4KCgoKI1RoZSB0aGlyZCB0aGluZyBpcyB0byBjaGVjayBpbmNvZW5zaXN0ZW5jeSwgYW5kIHdlIGRvIHRoZSBzYW1lIHRoaW5nIGFzIHdoYXQgd2UgZG9uZSBwcmV2aW91c2x5LgojRmlydHMsIHdlIGltcG9ydCBydWxlcyBpbnRvIFIuClJ1bGVzMyA8LSBlZGl0ZmlsZSgiL1VzZXJzL21hY2Jvb2svRG9jdW1lbnRzL1JNSVQtTWFzdGVyIG9mIEFuYWx5dGljcy9EYXRhIHdyYW5nbGluZy9lZGl0cnVsZXMudHh0IiwgdHlwZSA9ICJhbGwiKQoKUnVsZXMzCgojQ2hlY2sgd2hpY2ggdmFsdWUgdmlvbGF0ZXMgdGhlIHJ1bGVzCnZpb2xhdGVkRWRpdHMoUnVsZXMzLCBBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zKQoKI1RvIGRlYWwgd2l0aCB0aGUgcHJvYmxlbSBvZiAibGFyZ2UgZGF0YSBzaXplIiwgd2UgY291bGQgdXNlIHN1bW1hcnkoKSBmdW5jdGlvbi4KVmlvbGF0ZWQzIDwtIHZpb2xhdGVkRWRpdHMoUnVsZXMzLCBBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zKQoKc3VtbWFyeShWaW9sYXRlZDMpCgojRm9ydHVuYXRlbHksIHdlIGRvbid0IGhhdmUgYW55IGluY29uc2lzdGVuY2llcy4gCmBgYAoKCiMjCVRyYW5zZm9ybSAKCkFwcGx5IGFuIGFwcHJvcHJpYXRlIHRyYW5zZm9ybWF0aW9uIGZvciBhdCBsZWFzdCBvbmUgb2YgdGhlIHZhcmlhYmxlcy4gSW4gYWRkaXRpb24gdG8gdGhlIFIgY29kZXMgYW5kIG91dHB1dHMsIGV4cGxhaW4gZXZlcnl0aGluZyB0aGF0IHlvdSBkbyBpbiB0aGlzIHN0ZXAuIEluIHRoaXMgc3RlcCwgeW91IHNob3VsZCBmdWxmaWwgdGhlIG1pbmltdW0gcmVxdWlyZW1lbnQgIzkuCgoKYGBge3J9CiMgVGhpcyBpcyB0aGUgUiBjaHVuayBmb3IgdGhlIFRyYW5zZm9ybSBTZWN0aW9uCgoKIzcgRGF0YSB0cmFuc2Zvcm1hdGlvbgojVGhlIHJlYW9zbiB0byBwdXQgImRhdGEgdHJhbnNmb3JtYXRpb24iIHByaW9yIHRvIHRoZSAiU2NhbiBJSSIgaXMgdGhhdCB3ZSBoYXZlIGRhdGEgd2hvIGhhcyByaWdodC1za2V3ZWQgZGlzdHJpYnV0aW9uLiBBbmQgd2UgZGVjaWRlIHRvIHVzZSB6LXNjb3JlcyBtZXRob2QgaW4gb3JkZXIgdG8gbG9jYXRlIHdoZXJlIGFyZSB0aGUgb3V0bGllcnMuIAojVGhlcmVmb3JlLCB3ZSBoYXZlIHRvIHRyYW5zZm9ybSBkYXRhIGZyb20gcmlnaHQtc2tld2VkIGRpc3RyaWJ1dGlvbiB0byBhcHByb3hpbWF0ZWx5IG5vcm1hbCBkaXN0cmlidXRpb24gZmlyc3QuIApoaXN0KEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzMkU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2wpCgojQmFzZWQgb24gdGhlIHZhcmlhYmxlICJTZXhfcHJvcG9ydGlvbl9mb3JfdGhlX3ByZS5zdHVkZW50X2luX3NjaG9vbCIsIGl0IGNvbnRhaW5zIDAgdmFsdWVzIGFuZCBpdCBpcyByaWdodC1za2V3ZWQuCiNXZSBmaXJzdCB0cnkgdG8gdXNlIHNxdWFyZSByb290IHRyYW5zZm9ybWF0aW9uIHRvIGRlYWwgd2l0aCB0aGlzIGRhdGEgYmVjYXVzZSB0aGlzIGRhdGEgaGFzIDAgdmFsdWVzIGFuZCBpdCBpcyByZWlnaHQtc2tld2VkLgpzcXJ0X3NhbGFyeSA8LSBzcXJ0KEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzMkU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2wpCmhpc3Qoc3FydF9zYWxhcnkpCgojQXMgcmVzdWx0LCBpdCBpcyBzdGlsbCByaWdodCBza2V3ZWQgYW5kIHN0aWxsIG5lZWQgdG8gYmUgaW1wcm92ZWQuCgojV2Ugbm90ZSB0aGF0IHRoaXMgZGF0YSBjb250cmFpbnMgMCB2YWx1ZXMgb3IgMSB2YWx1ZXMsIGFuZCBpdCBpcyBiZWNhdXNlIHRoZXJlIGFyZSBzb21lIGFsbC1tYWxlIHNjaG9vbCBvciBhbGwtZmVtYWxlIHNjaG9vbC4KI1doZW4gaW52ZXN0aWdhdGluZyBzZXggcG9ycG9yaW9uLCBpdCBpcyBtZWFuaW5nbGVzcyB0byBpbnZlc3RpZ2F0ZSB3aGF0IHBlcmNlbnRhZ2Ugb2YgbWFsZSBzdHVkZW50IGluIGEgYWxsLWZlbWFsZSBzY2hvb2wgb3Igd2hhdCBwZXJjZW50YWdlIG9mIGZlbWFsZSBzdHVkZW50IGluIGFsbC1tYWxlIHNjaG9vbC4KI1RoZXJlZm9yZSwgd2Ugc2hvdWxkIHJlbW92ZSAwIHZhbHVlIGFuZCAxIHZhbHVlLiAKc3Vic2V0X25vXzBfMSA8LSBBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zICU+JSBmaWx0ZXIoU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2wgIT0gIjAiICYgU2V4X3Byb3BvcnRpb25fZm9yX3RoZV9wcmUuc3R1ZGVudF9pbl9zY2hvb2wgIT0iMSIpCgojTm93LCBsZXQncyBwcm9kdWNlIGEgaGlzdG9ncmFtIGFnYWluLiAKaGlzdChzdWJzZXRfbm9fMF8xJFNleF9wcm9wb3J0aW9uX2Zvcl90aGVfcHJlLnN0dWRlbnRfaW5fc2Nob29sKQoKI0FzIHJlc3VsdCwgaXQgaXMgYXBwcm94aW1hdGVseSBub3JtYWwgZGlzdHJpYnV0ZWQgbm93LgpgYGAKCiMjCVNjYW4gSUkKClNjYW4gdGhlIG51bWVyaWMgZGF0YSBmb3Igb3V0bGllcnMuIEluIHRoaXMgc3RlcCwgeW91IHNob3VsZCBmdWxmaWwgdGhlIG1pbmltdW0gcmVxdWlyZW1lbnQgIzguIEluIGFkZGl0aW9uIHRvIHRoZSBSIGNvZGVzIGFuZCBvdXRwdXRzLCBleHBsYWluIHlvdXIgbWV0aG9kb2xvZ3kgKGkuZS4gZXhwbGFpbiB3aHkgeW91IGhhdmUgY2hvc2VuIHRoYXQgbWV0aG9kb2xvZ3kgYW5kIHRoZSBhY3Rpb25zIHRoYXQgeW91IGhhdmUgdGFrZW4gdG8gaGFuZGxlIHRoZXNlIHZhbHVlcykgYW5kIGNvbW11bmljYXRlIHlvdXIgcmVzdWx0cyBjbGVhcmx5LgoKYGBge3J9CiMgVGhpcyBpcyB0aGUgUiBjaHVuayBmb3IgdGhlIFNjYW4gSUkKCiNXZSBmaXJzdCBjaGVjayBvdXQgd2hpY2ggdmFyaWFibGUgaXMgbnVtZXJpYy4gCnN0cihBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zKQoKI1dlIGNvdWxkIHNlZSB0aGF0IHRoZXJlIGFyZSA0IG51bWVyaWMgdmFyaWFibGVzOiAKI1NjaG9vbF9ObywgTnVtYmVyX29mX3ByZS5zdHVkZW50LCBUb3RhbF9udW1iZXJfb2ZfcHJlLnN0dWRlbnRfZm9yX3NjaG9vbCwgYW5kIFNleF9wcm9wb3J0aW9uX2Zvcl90aGVfcHJlLnN0dWRlbnRfaW5fc2Nob29sCiNIb3dldmVyLCBTY2hvb2xfTm8gaXMgbm90IG5lY2Vzc2FyeSB0byBiZSBzY2FubmVkIGJlY2F1c2UgaXQgaXMganVzdCBhIGNvZGUgdG8gcmVwcmVzZW50IGEgc2Nob29sIGFuZCBub3QgYSBudW1lcmljIG51bWJlciB0ZWNobmljYWxseS4gCgoKCiNGaXJzdCwgd2UgYXJlIGdvaW5nIHRvIGludmVzdGlnYXRlIG91dGxpZXJzIG9mICJTZXhfcHJvcG9ydGlvbl9mb3JfdGhlX3ByZS5zdHVkZW50X2luX3NjaG9vbCIuCmhpc3QoQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfMyRTZXhfcHJvcG9ydGlvbl9mb3JfdGhlX3ByZS5zdHVkZW50X2luX3NjaG9vbCkKCiNBbmQgYWxzbywgdGhleSBhcmUgbm9uLXN5bW1ldHJpYy8gbm9uLW5vcm1hbCBkYXRhIGRpc3RyaWJ1dGlvbnMsIGl0IGlzIHJpZ2h0LXNrZXdlZCBkaXN0cmlidXRpb24uCiNBcyB3ZSBrbm93biwgdGhlcmUgYXJlIGFsbC1tYWxlIHNjaG9vbCBhbmQgYWxsLWZlbWFsZSBzY2hvb2wsIHNvIHdlIGV4cGVjdCB0aGF0IHRoZXJlIGFyZSBzb21lIG91dGxpZXJzIGlzIDAgb3IgMSBpbiB0ZXJtcyBvZiBzZXggcHJvcG9ydGlvbi4KI1NvLCB3ZSBzaG91bGQgdXNlIHotc2NvcmVzIG1ldGhvZCB0byBsb29rIGZvciBvdXRsaWVycy4gVGhlIHJlYXNvbiBpcyB0aGF0IHdlIGNvdWxkIGtub3cgd2hpY2ggdmFsdWVzIGFyZSBvdXRsaWVycywgYW5kIGtub3dpbmcgaG93IG1hbnkgb3V0bGllcnMgYXJlIHRoZXJlLCBhbmQgaWYgdGhlcmUgYXJlIGp1c3QgYSBzYW1sbCBhY291bnQgb2Ygb3V0bGllcnMgd2UgbWF5IGNob29zZSB0byBkZWxldGUgdGhlbS4KI0dpdmVuIHRoYXQgd2UgYWxyZWFkeSBub3JtYWxpemUgdGhlIHJpZ2h0LXNrZXdlZCBkaXN0cmlidXRpb24gb2YgIlNleF9wcm9wb3J0aW9uX2Zvcl90aGVfcHJlLnN0dWRlbnRfaW5fc2Nob29sIgojTm93LCB3ZSBjb3VsZCBkaXJlY3RseSBhcHBseSB6LXNjb3JlcyBtZXRob2QgdG8gbG9vayBmb3Igb3V0bGllcnMuCgojV2Ugbm93IGNhbGN1bGF0ZSB6IHNjb3JlczoKei5zY29yZXMgPC0gc3Vic2V0X25vXzBfMSRTZXhfcHJvcG9ydGlvbl9mb3JfdGhlX3ByZS5zdHVkZW50X2luX3NjaG9vbCAlPiUgIHNjb3Jlcyh0eXBlID0gInoiKQp6LnNjb3JlcyAlPiUgc3VtbWFyeSgpCgojd2UgY2FuIHNlZSB0aGF0IHRoZSBtYXhpbXVtIGlzIDEyLjA0LiBBbmQgd2UgY2FuIGZpbmQgdGhlIGxvY2F0aW9ucyBvZiB0aGUgei1zY29yZXMgd2hvc2UgYWJzb2x1dGUgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIDMgYnkgdXNpbmcgd2hpY2goKS4Kd2hpY2goIGFicyh6LnNjb3JlcykgPjMgKQoKI0J5IHVzaW5nIGxlbmd0aCgpIGZ1bmN0aW9uLCB3ZSBjYW4gc2VlIHRoYXQgdGhlcmUgYXJlIDI5IG91dGxpZXJzLgpsZW5ndGggKHdoaWNoKCBhYnMoei5zY29yZXMpID4zICkpCgojSXQgaXMgc3RpbGwgcG9zc2libGUgdGhhdCB0aG9zZSBvdXRsaWVycyBhcmUgbm90IHRoZSByZXN1bHQgb2YgZGF0YSBlbnRyeSBlcnJvcnMsIG1lYXN1cmVtZW50IGVycm9ycywgZXhwZXJpbWVudGFsIGVycm9ycywgaW50ZW50aW9uYWwgZXJyb3JzLCBkYXRhIHByb2Nlc3NpbmcgZXJyb3JzIG9yIGR1ZSB0byB0aGUgc2FtcGxpbmcgKGkuZS4sIHNhbXBsaW5nIGVycm9yKSBiZWNhdXNlIHZlcnkgbG93IHNleCBwcm9wb3J0aW9uIG9yIHZlcnkgaGlnaCBzZXggcHJvcG9ydGlvbiBkb2VzIGhhcHBlbmVkIGluIHNvbWUgc2Nob29sLgojQnV0IGl0IGlzIGFsc28gcG9zc2libGUgdGhhdCB0aG9zZSBvdXRsaWVycyBhcmUgYWN0dWFsbHkgZXJyb3JzLgojSW4gdGhpcyBjYXNlLCB3ZSBzaG91bGQgdXNlIGNhcHBpbmcgdGVjaG5pcXVlIHRvIGRlYWwgd2l0aCBvdXRsaWVycyBiZWNhdXNlIHdlIGFyZSBub3Qgc3VyZSBhYm91dCB3aGV0aGVyIHRoZXJlIGFyZSBlcnJvcnMuIAojVGh1cywgd2Ugc2hvdWxkIHVzZSB0aGUgc2FmZSB3YXkgdG8gZGVhbCB3aXRoIHRoaXMgZGF0YTogUmVwbGFjaW5nIHRoZSBvdXRsaWVycyB3aXRoIHRoZSBuZWFyZXN0IG5laWdoYm91cnMgdGhhdCBhcmUgbm90IG91dGxpZXJzLgoKI0ZpcnN0LCB3ZSBuZWVkIHRvIGNyZWF0ZSBvdXIgb3duIGZ1bmN0aW9uOiBjYXAuIFRoaXMgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIGZpcnN0IGZpbmQgdGhlIHZhbHVlIHRoYXQgYXJlIGxlc3MgdGhhbiAocXVhbnRpbGVzIDAuMjUpLTEuNSpJUVIgYW5kIHRoZW4gcmVwYWxjZSBpdCBhcyAocXVhbnRpbGVzIDAuMDUpLiBTZWNvbmQsIGZpbmQgdGhlIHZhbHVlIHRoYXQgYXJlIGJpZ2dlciB0aGFuIChxdWFudGlsZXMgMC43NSkrMS41KklRUiBhbmQgdGhlbiByZXBhbGNlIGl0IGFzIChxdWFudGlsZXMgMC45NSkuCmNhcCA8LSBmdW5jdGlvbih4KXsKICBxdWFudGlsZXMgPC0gcXVhbnRpbGUoIHgsIGMoLjA1LCAwLjI1LCAwLjc1LCAuOTUgKSApCiAgeFsgeCA8IHF1YW50aWxlc1syXSAtIDEuNSpJUVIoeCkgXSA8LSBxdWFudGlsZXNbMV0KICB4WyB4ID4gcXVhbnRpbGVzWzNdICsgMS41KklRUih4KSBdIDwtIHF1YW50aWxlc1s0XQogIHgKfQoKI0FuZCB0aGVuLCBjYXAgdGhlIG91dGxpZXJzLgpTZXhfcHJvcG9ydGlvbl9jYXBwZWQgPC0gc3Vic2V0X25vXzBfMSRTZXhfcHJvcG9ydGlvbl9mb3JfdGhlX3ByZS5zdHVkZW50X2luX3NjaG9vbCAlPiUgY2FwKCkKCiNMZXQncyBjaGVjayBvdXRsaWVycyBhZ2Fpbi4Kei5zY29yZXMgPC0gU2V4X3Byb3BvcnRpb25fY2FwcGVkICU+JSAgc2NvcmVzKHR5cGUgPSAieiIpCnouc2NvcmVzICU+JSBzdW1tYXJ5KCkKCiN3ZSBjYW4gc2VlIHRoYXQgdGhlIG1heGltdW0gaXMgMi41MTk5NTg0LiBBbmQgd2UgY2FuIGZpbmQgd2hjaWggdmFsdWUgd2hvc2UgYWJzb2x1dGUgWi12YWx1ZSBpcyBncmVhdGVyIHRoYW4gMyBieSB1c2luZyB3aGljaCgpLgp3aGljaCggYWJzKHouc2NvcmVzKSA+MyApCgojQnkgdXNpbmcgbGVuZ3RoKCkgZnVuY3Rpb24sIHdlIGNhbiBzZWUgdGhhdCB0aGVyZSBhcmUgMCBvdXRsaWVycy4KbGVuZ3RoICh3aGljaCggYWJzKHouc2NvcmVzKSA+MyApKQoKCgojU2Vjb25kLCB3ZSBhcmUgZ29pbmcgdG8gaXZlc3RpZ2F0ZSBvdXRsaWVycyBvZiAiTnVtYmVyX29mX3ByZS5zdHVkZW50IiBpbiB0ZXJtcyBvZiAiZ2VuZGVyIi4gCiNHaXZlbiB0aGF0IHRoZXkgYXJlIG9uZSBmYWN0b3IgdmFyaWFibGUgYW5kIG9uZSBudW1lcmljIHZhcmlhYmxlLiBBbmQgYWxzbywgdGhleSBhcmUgbm9uLXN5bW1ldHJpYy8gbm9uLW5vcm1hbCBkYXRhIGRpc3RyaWJ1dGlvbnMuCkFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzNfbWFsZSA8LUFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzMgJT4lIGZpbHRlcihHZW5kZXIgPT0gIk1hbGUiKQoKaGlzdChBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zX21hbGUkTnVtYmVyX29mX3ByZS5zdHVkZW50KQoKQWxsX1NjaG9vbHNfRlRFX2Vucm9sbWVudHNfRmViXzIwMTVfQ29tYmluZV8yMDE2X2Zvcl9wcmUuc3R1ZGVudHNfM19mZW1hbGUgPC1BbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zICU+JSBmaWx0ZXIoR2VuZGVyID09ICJGZW1hbGUiKQoKaGlzdChBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zX2ZlbWFsZSROdW1iZXJfb2ZfcHJlLnN0dWRlbnQpCgojVGh1cywgaW4gdGhpcyBjYXNlLCB1c2luZyB0aGUgdGVjaG5pcXVlIG9mICJCaXZhcmlhdGUgYm94IHBsb3QiIGlzIGhpZ2hseSBlbmNvdXJhZ2VkLgoKYm94cGxvdChBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zJE51bWJlcl9vZl9wcmUuc3R1ZGVudCB+IEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzMkR2VuZGVyLCBtYWluPSJOdW1iZXIgb2YgcHJlLnN0dWRlbnQgYnkgZ2VuZGVyIiwgeWxhYiA9ICJOdW1iZXIgb2YgcHJlLnN0dWRlbnQiLCB4bGFiID0gIkdlbmRlciIpCgojVXNpbmcgdGhlIGJpdmFyaWF0ZSBib3ggcGxvdCBhcHByb2FjaCwgd2UgY2FuIGVhc2lseSBkZXRlY3Qgb3V0bGllcnMgaW4gIk51bWJlcl9vZl9wcmUuc3R1ZGVudCIgZm9yIGEgZ2l2ZW4gIkdlbmRlciIuCiNIb3dldmVyLCB0aGVzZSBvdXRsaWVycyBhcmUgdmFsdWFibGUgYmVjYXN1ZSB0aGlzIHZhcmlhYmxlIChOdW1iZXJfb2ZfcHJlLnN0dWRlbnQpIGlzIHVzZWQgZm9yIGNvbGxlY3QgaW5mb3JtYXRpb24gb2YgdGhlIG51bWJlciBvZiBzdGR1ZW50IGZvciBkaWZmZXJlbnQgZ2VuZGVyIGluIGRpZmZlcmVudCBzY2hvb2wuIAojQW5kLCBpdCBpcyBva2F5IHRoYXQgc29tZSBzY2hvb2wgaGF2ZSBhIGxvdCBvZiBzdHVkZW50IChub3RlIHRoYXQgb3V0bGllcnMgYXJlIGFsbCBiZXlvbmQgdGhlIHVwcGVyIGZlbmNlIGZvciBib3RoIG1hbGUgYW5kIGZlbWFsZSkgYmVjYXVzZSBzY2hvb2xzIGNhbiBiZSBsaWtlIGFsbC1tYWxlIHNjaG9vbCBvciBhbGwtZmVtYWxlIHNjaG9vbC4gCiNNb3Jlb3Zlciwgc2Nob29sIHR5cGUgaXMgZGl2aWRlZCBieSAiTGFuZ3VhZ2UiLCAiUHJpL1NlYyIsICJQcmltYXJ5IiwgIlNlY29uZGFyeSIsIGFuZCAiU3BlY2lhbCIsIGl0IGlzIGV4cGVjdGVkIHRoYXQgdGhlcmUgc2hvdWxkIGJlIG1hbnkgcHJlLXN0dWRlbnQgZm9yIGxhbmd1YWdlIHNjaG9vbCBvciBzcGVjaWFsIHNjaG9vbCwgYW5kIGxlc3MgcHJlLXN0dWRlbnQgZm9yIFByaS9TZWMsIFByaW1hcnksIGFuZCBTZWNvbmRhcnkgc2Nob29sLgojQW5kLCB3ZSBjb3VsZCBzZWUgdGhhdCB0aGUgUTEgaXMganVzdCBhcm91bmQgMCBhbmQgUTMgaXMgYXJvdW5kIDMwIGZvciBib3RoIG1hbGUgYW5kIGZlbWFsZS4gT2J2aW91c2x5LCB0aGVyZSBhcmUgYSBsb3Qgb2YgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IHNjaG9vbCB3aG8gaGFzIDAgcHJlLXN0dWRlbnQgb3Igb25seSB2ZXJ5IHNhbWxsIG51bWJlciBvZiBwcmUtc3R1ZGVudCBpbiB0aGlzIGRhdHNldC4KI1RoZXJlZm9yZSwgaXQgaXMgcG9zc2libGUgdGhhdCBzb21lICJMYW5ndWFnZSIgYW5kICJTcGVjaWFsIiBzY2hvb2wgaGF2ZSBhIGxvdCBvZiBzdHVkZW50cyBhbmQgYXJlIGRlZmluZWQgYXMgb3V0bGllcnMgaW4gdGhpcyBwbG90LiBTbywgdGhlc2Ugb3V0bGllcnMgYXJlIGV4cGxhaW5hYmxlLiAKI0hvd2V2ZXIsIGl0IGlzIHN0aWxsIHBvc3NpYmxlIHRoYXQgc29tZSBvdXRsaWVycyBhcmUgZXJyb3JzIHN1Y2ggYXMgbWVhc3VyZW1lbnQgZXJyb3Igb3Igc2FtcGxlaW5nIGVycm9yLgojVGh1cywgd2Ugc2hvdWxkIHVzZSB0aGUgc2FmZSB3YXkgdG8gZGVhbCB3aXRoIHRoaXMgZGF0YTogUmVwbGFjaW5nIHRoZSBvdXRsaWVycyB3aXRoIHRoZSBuZWFyZXN0IG5laWdoYm91cnMgdGhhdCBhcmUgbm90IG91dGxpZXJzLgojR2l2ZW4gdGhhdCB3ZSBhbHJlYWR5IGhhdmUgb3VyIG93biBmdW5jdGlvbjogY2FwIGFuZCB3ZSBjb3VsZCBqdXN0IGRpcmVjdGx5IGFwcGx5IGNhcCBmdW5jdGlvbiBpbnRvIGRhdGFzZXQuCgoKCiNXZSBmaXJzdCBkZWFsIHdpdGggdGhlIG91dGxpZXJzIGZvciBtYWxlLgpTdHVkZW50X21hbGVfY2FwcGVkIDwtIEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzNfbWFsZSROdW1iZXJfb2ZfcHJlLnN0dWRlbnQgJT4lIGNhcCgpCgojTGV0J3MgY2hlY2sgb3V0bGllcnMgYWdhaW4uCnouc2NvcmVzMiA8LSBTdHVkZW50X21hbGVfY2FwcGVkICU+JSAgc2NvcmVzKHR5cGUgPSAieiIpCnouc2NvcmVzMiAlPiUgc3VtbWFyeSgpCgojd2UgY2FuIHNlZSB0aGF0IHRoZSBtYXhpbXVtIGlzIDIuOTM0Mi4gQW5kIHdlIGNhbiBmaW5kIHdoY2loIHZhbHVlIHdob3NlIGFic29sdXRlIFotdmFsdWUgaXMgZ3JlYXRlciB0aGFuIDMgYnkgdXNpbmcgd2hpY2goKS4Kd2hpY2goIGFicyh6LnNjb3JlczIpID4zICkKCiNCeSB1c2luZyBsZW5ndGgoKSBmdW5jdGlvbiwgd2UgY2FuIHNlZSB0aGF0IHRoZXJlIGFyZSAwIG91dGxpZXJzLgpsZW5ndGggKHdoaWNoKCBhYnMoei5zY29yZXMyKSA+MyApKQoKCgojQW5kIHRoZW4sIHdlIGRlYWwgd2l0aCB0aGUgb3V0bGllcnMgZm9yIGZlbWFsZS4KU3R1ZGVudF9mZW1hbGVfY2FwcGVkIDwtIEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzNfZmVtYWxlJE51bWJlcl9vZl9wcmUuc3R1ZGVudCAlPiUgY2FwKCkKCiNMZXQncyBjaGVjayBvdXRsaWVycyBhZ2Fpbi4Kei5zY29yZXMzIDwtIFN0dWRlbnRfZmVtYWxlX2NhcHBlZCAlPiUgIHNjb3Jlcyh0eXBlID0gInoiKQp6LnNjb3JlczMgJT4lIHN1bW1hcnkoKQoKI3dlIGNhbiBzZWUgdGhhdCB0aGUgbWF4aW11bSBpcyAyLjk2MDIuIEFuZCB3ZSBjYW4gZmluZCB3aGNpaCB2YWx1ZSB3aG9zZSBhYnNvbHV0ZSBaLXZhbHVlIGlzIGdyZWF0ZXIgdGhhbiAzIGJ5IHVzaW5nIHdoaWNoKCkuCndoaWNoKCBhYnMoei5zY29yZXMzKSA+MyApCgojQnkgdXNpbmcgbGVuZ3RoKCkgZnVuY3Rpb24sIHdlIGNhbiBzZWUgdGhhdCB0aGVyZSBhcmUgMCBvdXRsaWVycy4KbGVuZ3RoICh3aGljaCggYWJzKHouc2NvcmVzMykgPjMgKSkKCgoKI1RoaXJkLCB3ZSBhcmUgZ29pbmcgdG8gaW52ZXN0aWdhdGUgb3V0bGllcnMgb2YgIlRvdGFsX251bWJlcl9vZl9wcmUuc3R1ZGVudF9mb3Jfc2Nob29sIi4KaGlzdChBbGxfU2Nob29sc19GVEVfZW5yb2xtZW50c19GZWJfMjAxNV9Db21iaW5lXzIwMTZfZm9yX3ByZS5zdHVkZW50c18zJFRvdGFsX251bWJlcl9vZl9wcmUuc3R1ZGVudF9mb3Jfc2Nob29sKQoKI0FuZCBhbHNvLCB0aGV5IGFyZSBub24tc3ltbWV0cmljLyBub24tbm9ybWFsIGRhdGEgZGlzdHJpYnV0aW9ucy4KI1RodXMsIGluIHRoaXMgY2FzZSwgdXNpbmcgdGhlIHRlY2huaXF1ZSBvZiAiVW5pdmFyaWF0ZSBib3ggcGxvdCIgaXMgaGlnaGx5IGVuY291cmFnZWQuCkFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzMkVG90YWxfbnVtYmVyX29mX3ByZS5zdHVkZW50X2Zvcl9zY2hvb2wgJT4lICBib3hwbG90KG1haW49IkJveCBQbG90IG9mIHRvdGFsIG51bWJlciBvZiBwcmUuc3R1ZGVudCBmb3Igc2Nob29sIiwgeWxhYj0iVG90YWwgbnVtYmVyIG9mIHByZS5zdHVkZW50IiwgY29sID0gImdyZXkiKQoKI1RoaXMgY2FzZSBpcyB2ZXJ5IHNpbWlsYXIgdG8gdGhlIHByZXZpb3VzIGNhc2UsIG91dGxpZXJzIGFyZSBhbGwgYmV5b25kIHRoZSB1cHBlciBmZW5jZS4gQXMgd2UgY2FuIHNlZSBpbiB0aGUgcGxvdCwgb3V0bGllcnMgYXJlIGFsbCBpbiBhcm91bmQgMTQwIHN0dWRlbnRzIHRvIDI1MCBzdHVkZW50LiBJdCBzZWVtcyBva2F5IGJlY2F1c2Ugc29tZSBiaWcgc2Nob29sIGNhbiBoYXZlIDI1MCBwcmUtc3R1ZGVudC4gCiNBbmQsIHdlIGNvdWxkIHNlZSB0aGF0IHRoZSBRMSBpcyBqdXN0IGFyb3VuZCAwIGFuZCBRMyBpcyBhcm91bmQgNTAuIE9idmlvdXNseSwgdGhpcyBwbG90IGhhcyB0aGUgc2FtZSBzaXR1YXRpb24gd2l0aCB0aGUgcHJldmlvdXMgb25lLCB0aGVyZSBhcmUgYSBsb3Qgb2YgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IHNjaG9vbCB3aG8gaGFzIDAgcHJlLXN0dWRlbnQgb25seSB2ZXJ5IHNhbWxsIG51bWJlciBvZiBwcmUtc3R1ZGVudCBpbiB0aGlzIGRhdHNldC4KI1RoZXJlZm9yZSwgaXQgaXMgcG9zc2libGUgdGhhdCBzb21lICJMYW5ndWFnZSIgYW5kICJTcGVjaWFsIiBzY2hvb2wgaGF2ZSBhIGxvdCBvZiBzdHVkZW50cyBhbmQgYXJlIGRlZmluZWQgYXMgb3V0bGllcnMgaW4gdGhpcyBwbG90LiBTbywgdGhlc2Ugb3V0bGllcnMgYXJlIGV4cGxhaW5hYmxlLiAKI091dGxpZXJzIGFyZSB2YWx1YWJsZSBhbmQgZXhwbGFpbmFibGUuCiNIb3dldmVyLCBpdCBpcyBzdGlsbCBwb3NzaWJsZSB0aGF0IHNvbWUgb3V0bGllcnMgYXJlIGVycm9ycyBzdWNoIGFzIG1lYXN1cmVtZW50IGVycm9yIG9yIHNhbXBsZWluZyBlcnJvci4KI1RodXMsIHdlIHNob3VsZCB1c2UgdGhlIHNhZmUgd2F5IHRvIGRlYWwgd2l0aCB0aGlzIGRhdGE6IFJlcGxhY2luZyB0aGUgb3V0bGllcnMgd2l0aCB0aGUgbmVhcmVzdCBuZWlnaGJvdXJzIHRoYXQgYXJlIG5vdCBvdXRsaWVycy4KI0dpdmVuIHRoYXQgd2UgYWxyZWFkeSBoYXZlIG91ciBvd24gZnVuY3Rpb246IGNhcCBhbmQgd2UgY291bGQganVzdCBkaXJlY3RseSBhcHBseSBjYXAgZnVuY3Rpb24gaW50byBkYXRhc2V0LgoKCgpUb3RhbF90dWRlbnRfY2FwcGVkIDwtIEFsbF9TY2hvb2xzX0ZURV9lbnJvbG1lbnRzX0ZlYl8yMDE1X0NvbWJpbmVfMjAxNl9mb3JfcHJlLnN0dWRlbnRzXzMkVG90YWxfbnVtYmVyX29mX3ByZS5zdHVkZW50X2Zvcl9zY2hvb2wgJT4lIGNhcCgpCgojTGV0J3MgY2hlY2sgb3V0bGllcnMgYWdhaW4uCnouc2NvcmVzNCA8LSBUb3RhbF90dWRlbnRfY2FwcGVkICU+JSAgc2NvcmVzKHR5cGUgPSAieiIpCnouc2NvcmVzNCAlPiUgc3VtbWFyeSgpCgojd2UgY2FuIHNlZSB0aGF0IHRoZSBtYXhpbXVtIGlzIDIuODk0OC4gQW5kIHdlIGNhbiBmaW5kIHdoY2loIHZhbHVlIHdob3NlIGFic29sdXRlIFotdmFsdWUgaXMgZ3JlYXRlciB0aGFuIDMgYnkgdXNpbmcgd2hpY2goKS4Kd2hpY2goIGFicyh6LnNjb3JlczQpID4zICkKCiNCeSB1c2luZyBsZW5ndGgoKSBmdW5jdGlvbiwgd2UgY2FuIHNlZSB0aGF0IHRoZXJlIGFyZSAwIG91dGxpZXJzLgpsZW5ndGggKHdoaWNoKCBhYnMoei5zY29yZXM0KSA+MyApKQoKYGBgCgpOT1RFOiBOb3RlIHRoYXQgc29tZXRpbWVzIHRoZSBvcmRlciBvZiB0aGUgdGFza3MgbWF5IGJlIGRpZmZlcmVudCB0aGFuIHRoZSBvcmRlciBnaXZlbiBoZXJlLiBGb3IgZXhhbXBsZSwgeW91IG1heSBuZWVkIHRvIHRpZHkgdGhlIGRhdGEgc2V0cyBmaXJzdCB0byBiZSBhYmxlIHRvIGNyZWF0ZSB0aGUgY29tbW9uIGtleSB0byBtZXJnZS4gVGhlcmVmb3JlLCBmb3Igc3VjaCBjYXNlcyB5b3UgbWF5IGhhdmUgYSBkaWZmZXJlbnQgb3JkZXJpbmcgb2YgdGhlIHNlY3Rpb25zLlwgIAoKQW55IGZ1cnRoZXIgb3Igb3B0aW9uYWwgcHJlLXByb2Nlc3NpbmcgdGFza3MgY2FuIGJlIGFkZGVkIHRvIHRoZSB0ZW1wbGF0ZSB1c2luZyBhbiBhZGRpdGlvbmFsIHNlY3Rpb24gaW4gdGhlIFIgTWFya2Rvd24gZmlsZS4gTWFrZSBzdXJlIHlvdXIgY29kZSBpcyB2aXNpYmxlICh3aXRoaW4gdGhlIG1hcmdpbiBvZiB0aGUgcGFnZSkuIERvIG5vdCB1c2UgVmlldygpIHRvIHNob3cgeW91ciBkYXRhLCBpbnN0ZWFkIGdpdmUgaGVhZGVycyAodXNpbmcgaGVhZCgpICkKCjxicj4KPGJyPgo=