Required packages
library(readr) #Useful for importing data
library(readxl) #Useful for importing excel sheets
library(foreign) #Useful for importing SPSS, SAS, STATA etc. data files
library(gdata) #useful for providing various tools for data manipulation
library(rvest) #Useful for scraping HTML data
library(tidyr) #Useful for tidying data
library(dplyr) #Useful for data manipulation
library(deductive) #Useful for deductive data correction and Imputation
library(validate) #Useful for data validation
library(Hmisc) #Useful in recoding missing values
library(stringr) #Useful for sampling character vectors for string manipulations
library(lubridate) #Useful for working with dates and times
library(outliers) #Useful in removing outliers
library(MVN) #Useful for multivariate normality tests
library(infotheo) #Useful for implementing measures of information theory based on several entropy estimators
library(MASS) #Useful to support Venables and Ripley
library(caret) #Useful for model training process for complex regression & classification problems
library(mlr) #Useful for providing unified interface for machine learning tasks in R
library(ggplot2) #Useful for creating graphics based on 'The Grammar of graphics'
library(knitr) #Useful for creating nice tables
library(raster) #Useful in creating functions
library(mosaic) #Useful for Descriptive Statistics
Executive Summary
The two datasets ‘races’ and ‘runs’ have been imported to R and then merged to form Racing_data. Furthermore, inspected the variable and the data structure of this combined dataset.Factorized the horse country variable and changed its labels. Since, the dataset was already following the tidy data principles, there was no need to tidy steps performed. Four new columns have been mutated, i.e,
1.Ratio of win to place-to check the probability of the horse in a particular race. Higher the Ratio of win to place, higher will be the chances of the horse to win the race. Although other factors also play a crucial role in deriving a probability of the winning horse like the speed of the horse, track condition, jockey weight,trainer of the horse and handicapped weights on the horse etc.
2.Horse weight-to get the measured weight of the horse subtracted the actual weight (jockey weight+ handicapped weight on the horse) from the declared weight (horse weight+ jockey weight+ handicapped weight on the horse).
3.Ratio of horse weight to actual weight-to calculate the proportion of the horse weight to the actual weight in a particular race, this affects the speed of the horse.
4.Average horse speed-to get the average speed of the horse in a race with respect to the length of the race track.
After this, scanned for the NA values and inconsistencies which were removed from the data. Although, many numeric columns are present in the dataset, but performing outlier treatment for all those columns is not relevant, as few of these columns are ID’s of a race, horse, jockey and trainer etc. Detected and removed the outlier, firstly plotted a boxplot for the length behind column to determine the length by which the horse is lagging behind from the winning horse. Next, in order to compare a quantitative variable with a qualitative variable, bivariate boxplot was plotted for horse weight and going (track condition). In addition to that, a scatter plot was plotted for horse weight and actual weight variables. Moreover, a multivariate outlier treatment is performed on a particular class of the race with horse weight and actual weight variables. Lastly, tranformed the data by using Log and Square root transformation for reducing the skewness, on the variables ratio of horse to actual weight and declared weight, respectively.
Data
- The datasets contain data of thoroughbred horse racing in Hong Kong. Horse racing being a massive business in Hong Kong, resulting in betting pools bigger than all racetracks in US combined.
- There are two datasets i.e
races and runs, presented in CSV format. *races.csv represents data on condition of each race that includes distance, track condition, distance and dividends paid. Whereas, runs.csv represents data of each horse running in each of the races mentioned in races.csv.
- In
runs.csv, each line describes the characteristics of one horse run, in one of the races given in races.csv, and it contains the following variables-
1. race_id- unique identifier for the race
2. horse_no- the number assigned to this horse, in the race
3. horse_id- unique identifier for this horse
4. result- finishing position of this horse in the race
5. won- whether horse won (1) or otherwise (0)
6. lenghts_behind- finishing position, as the number of horse lengths behind the winner
7. horse_age- current age of this horse at the time of the race
8. horse_country- country of origin of the horse
9. horse_type- sex of the horse, e.g. Gelding,Mare,Horse,Rig,Colt,Filly
10.horse_rating- rating number assigned by HKJC to this horse at the time of the race
11.declared_weight- declared weight of the horse and jockey, in lbs
12.actual_weight- actual weight carried by the horse, in lbs
13.draw- post position number of the horse in this race
14.finish_time- finishing time of the horse in this race (in sec)
15.win_odds- win odds for this horse at start of race
16.place_odds- place odds for this horse at start of race (finishing in 1st, 2nd or 3rd position)
17.trainer_id- unique identifier of the horse’s trainer at the time of the race
18.jockey_id- unique identifier of the jockey riding the horse in this race
- In
races.csv, the condition of an individual race is described in each line, and it contains the following variables-
1. race_id- unique identifier for the race
2. date- date of the race, in YYYY-MM-DD format.
3. venue- a 2-character string, representing which of the 2 race courses this race took place at: ST = Shatin,HV = Happy Valley
4. race_no- race number of the race in the day’s meeting
5. config- race track configuration, mostly related to the position of the inside rail
6. surface- a number representing the type of race track surface: 1 = dirt, 0 = turf
7. distance- distance of the race, in metres
8. going- track condition
9. horse_ratings- range of horse ratings that may participate in this race
10.prize- the winning prize, in HK Dollars
11.race_class- a number representing the class of the race
12.place_combination1- placing horse no. 1st
13.place_combination2- placing horse no. 2nd
14.place_combination3- placing horse no. 3rd
15.place_dividend1- placing dividend paid (for place_combination1)
16.place_dividend2- placing dividend paid (for place_combination2)
17.place_dividend3- placing dividend paid (for place_combination3)
18.win_combination1- winning horse number
Source: https://www.kaggle.com/gdaley/hkracing https://ev.turnitin.com/app/carta/en_us/?student_user=1&lang=en_us&o=955457124&u=1072354159
Read/Import Data
- Data has been imported to R, by using
read.csv() function, from the package readr,using the argument stringsAsFactors = FALSE as by default read.csv converts strings to factors.
- Imported datasets are saved as
Race and Run.
Race and Run are then merged using the key variable race_id.
- Using the generic function
left_join, Race is added to the Run dataframe and the combined dataframe is renamed as Racing_data.
- Validated the first few rows of the dataframes using the generic function
head().
getwd()
[1] "C:/Users/Ritwick Dev/Documents/Data Preprocessing"
setwd("C:\\Users\\Ritwick Dev\\Documents\\Data Preprocessing")
Race <- read.csv("races.csv", stringsAsFactors = FALSE)
Run <- read.csv("runs.csv", stringsAsFactors = FALSE)
head(Race)
head(Run)
Racing_data <- Run %>% left_join(Race , by = "race_id")
head(Racing_data)
Understand
- The base R function
class() returned the $names, $row_names and $class of Racing_data.
- The base R function
length() is used to check the number of columns in Racing_data dataframe.
- Using the base R function
dim() returned the dimensions of the dataframe Racing_data.
- Generic function
str() is used to see the detailed structure of the dataframe Racing_data.
- Using the base R function
factor() changed the labels for the columnhorse_country.
- Moreover, ordered the levels using the argument
ordered=TRUE for Racing_data$horse_country.
levels() is used to check levels for the column horse_country.
dmy() function is from the package lubridateis used to change the datatype from character to date.
class(Racing_data)
[1] "tbl_df" "tbl" "data.frame"
length(Racing_data)
[1] 35
dim(Racing_data)
[1] 79447 35
str(Racing_data)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 79447 obs. of 35 variables:
$ race_id : int 0 0 0 0 0 0 0 0 0 0 ...
$ horse_no : int 1 2 3 4 5 6 7 8 9 10 ...
$ horse_id : int 3917 2157 858 1853 2796 3296 911 2170 1730 2998 ...
$ result : int 10 8 7 9 6 3 12 1 13 14 ...
$ won : int 0 0 0 0 0 0 0 1 0 0 ...
$ lengths_behind : num 8 5.75 4.75 6.25 3.75 1.25 9.5 0 9.75 999 ...
$ horse_age : int 3 3 3 3 3 3 3 3 3 3 ...
$ horse_country : chr "AUS" "NZ" "NZ" "SAF" ...
$ horse_type : chr "Gelding" "Gelding" "Gelding" "Gelding" ...
$ horse_rating : int 60 60 60 60 60 60 60 60 60 60 ...
$ declared_weight : int 1020 980 1082 1118 972 1114 978 1170 1126 1072 ...
$ actual_weight : int 133 133 132 127 131 127 123 128 123 125 ...
$ draw : int 7 12 8 13 14 5 11 2 6 9 ...
$ finish_time : num 83.9 83.6 83.4 83.6 83.2 ...
$ win_odds : num 9.7 16 3.5 39 50 7 99 12 38 39 ...
$ place_odds : num 3.7 4.9 1.5 11 14 1.8 28 3.6 13 12 ...
$ trainer_id : int 118 164 137 80 9 54 55 47 75 109 ...
$ jockey_id : int 2 57 18 59 154 34 149 183 131 145 ...
$ date : chr "2/06/1997" "2/06/1997" "2/06/1997" "2/06/1997" ...
$ venue : chr "ST" "ST" "ST" "ST" ...
$ race_no : int 1 1 1 1 1 1 1 1 1 1 ...
$ config : chr "A" "A" "A" "A" ...
$ surface : int 0 0 0 0 0 0 0 0 0 0 ...
$ distance : int 1400 1400 1400 1400 1400 1400 1400 1400 1400 1400 ...
$ going : chr "GOOD TO FIRM" "GOOD TO FIRM" "GOOD TO FIRM" "GOOD TO FIRM" ...
$ horse_ratings : chr "40-15" "40-15" "40-15" "40-15" ...
$ prize : int 485000 485000 485000 485000 485000 485000 485000 485000 485000 485000 ...
$ race_class : int 5 5 5 5 5 5 5 5 5 5 ...
$ place_combination1: int 8 8 8 8 8 8 8 8 8 8 ...
$ place_combination2: int 11 11 11 11 11 11 11 11 11 11 ...
$ place_combination3: int 6 6 6 6 6 6 6 6 6 6 ...
$ place_dividend1 : num 36 36 36 36 36 36 36 36 36 36 ...
$ place_dividend2 : num 25 25 25 25 25 25 25 25 25 25 ...
$ place_dividend3 : num 18 18 18 18 18 18 18 18 18 18 ...
$ win_combination1 : int 8 8 8 8 8 8 8 8 8 8 ...
attributes(Racing_data)
$class
[1] "tbl_df" "tbl" "data.frame"
$row.names
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
[26] 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
[51] 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
[76] 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
[101] 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
[126] 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
[151] 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
[176] 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
[201] 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
[226] 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
[251] 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
[276] 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
[301] 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
[326] 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
[351] 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
[376] 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
[401] 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
[426] 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
[451] 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
[476] 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
[501] 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
[526] 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
[551] 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
[576] 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
[601] 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
[626] 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
[651] 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675
[676] 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700
[701] 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725
[726] 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750
[751] 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
[776] 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800
[801] 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
[826] 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
[851] 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
[876] 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900
[901] 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925
[926] 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950
[951] 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975
[976] 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
[ reached getOption("max.print") -- omitted 78447 entries ]
$names
[1] "race_id" "horse_no" "horse_id" "result" "won" "lengths_behind"
[7] "horse_age" "horse_country" "horse_type" "horse_rating" "declared_weight" "actual_weight"
[13] "draw" "finish_time" "win_odds" "place_odds" "trainer_id" "jockey_id"
[19] "date" "venue" "race_no" "config" "surface" "distance"
[25] "going" "horse_ratings" "prize" "race_class" "place_combination1" "place_combination2"
[31] "place_combination3" "place_dividend1" "place_dividend2" "place_dividend3" "win_combination1"
Racing_data$horse_country <- factor(Racing_data$horse_country,levels = c("AUS","NZ","SAF","GB","USA","IRE","FR","CAN"),labels = c("AUSTRALIA","NEWZEALAND","SOUTHAFRICA","GREATBRITAIN","UNITEDSTATESAMERICA","IRELAND","FRANCE","CANADA"), ordered = TRUE)
levels(Racing_data$horse_country)
[1] "AUSTRALIA" "NEWZEALAND" "SOUTHAFRICA" "GREATBRITAIN" "UNITEDSTATESAMERICA"
[6] "IRELAND" "FRANCE" "CANADA"
Racing_data$date <- dmy(Racing_data$date)
head(Racing_data)
Tidy & Manipulate Data I
- Tidying the data is not required as the dataframe is already conforming the tidy data principles that is-
- Each variable has its own column.
- Each observation has its own row.
- Each value has its own cell.
Tidy & Manipulate Data II
- Mutated the column
Ratio_of_win_to_place and ratio_of_horse_to_actual by dividing the column win_odds by place_odds and horse_weight by actual_weight, respectively.
- Calculated
Average_horse_speed by didviding distance by finish_time
- Created
horse_weight by substracting actual_weight from declared_weight..
Racing_Data_mutate <- Racing_data %>% mutate(Ratio_of_win_to_place = win_odds / place_odds ,
horse_weight = declared_weight - actual_weight ,
Average_horse_speed = distance/finish_time,
ratio_of_horse_to_actual = horse_weight / actual_weight)
head(Racing_Data_mutate)
Scan I
- Subsetted the dataframe
Racing_Data_mutate using subset by column numbers on and named it RDC.
- Calculated the column mean of price for winning horse and named it
col_means, got the index for each NA values and stored it in the variable Index and finally replaced the NA values with mean.
- Deleted the column price from the
Racing_Data_mutate.
- Created a new variable
Racing_Data_New by adding RDC to Racing_Data_mutate using the function left_join.
- Deleted the duplicate values from the dataframe
Racing_Data_New.
- Performed these above steps as
impute() function, from the package hmisc, was throwing an error.
- Imputed the variables
declared_weight, horse_weight, ratio_of_horse_to_actual using the argument fun=mean and for variables horse_country and horse_type using fun=mode.
- Inspected the dataframe
Racing_Data_New for NA values by using the function is.na() and calculated the total sum of NA values.
- Moreover created a custom function to check for any inconsistencies and special values.
RDC <- Racing_Data_mutate[,c(1,27)]
col_means <- colMeans(RDC[,-1], na.rm = TRUE)
Index <- which(is.na(RDC), arr.ind = TRUE)
RDC[Index] <- col_means[Index[,2]-1]
Racing_Data_mutate[,27] <- NULL
Racing_Data_New <- Racing_Data_mutate %>% left_join(RDC , by = "race_id")
Racing_Data_New <- Racing_Data_New[!duplicated(Racing_Data_New[,]),]
Racing_Data_New$declared_weight <- impute(Racing_Data_New$declared_weight, fun = mean)
Racing_Data_New$horse_weight <- impute(Racing_Data_New$horse_weight, fun = mean)
Racing_Data_New$ratio_of_horse_to_actual <- impute(Racing_Data_New$ratio_of_horse_to_actual, fun = mean)
Racing_Data_New$horse_country <- impute (Racing_Data_New$horse_country , fun = mode)
Racing_Data_New$horse_country <- impute (Racing_Data_New$horse_type , fun = mode)
sum(is.na(Racing_Data_New$horse_type))
[1] 0
is.special <- function(x)
{if (is.numeric(x)) !is.finite(x)
else is.na(x)
}
sum(sapply(Racing_Data_New, is.special))
[1] 0
Scan II
- Using the
Racing_Data_New dataframe, inspected the variable lengths_behind for outlier in by plotting a boxplot.
- Using the function
favstats, calculated the descriptive statistics like mean, standard deviation and quartile values.
- Calculated the upper fence (Q3 + 1.5(IQR)) and lower fence (Q1 - 1.5(IQR)) using the Quartile values.
- Created a subset of the dataframe
Racing_Data_New by removing the univariate outliers using the upper fence values and named it Racing_Data_New_subset.
- Plotted a boxplot for the variable
lengths_behind again for dataframe Racing_Data_New_subset.
- A bivariate box plot is illustrated, by using a quantitative variable
horse_weight and a qualitative variable goingin the dataset Racing_Data_New.
- In order to get the scatter plot,
plot() function is used and outliers in horse_weight and actual_weight have been detected from the dataframe Racing_Data_New. To detect multivariate outliers, firstly subsetted the Racing_Data_New data, which is race class=13 with the two variables horse_weight and actual weight. Then, mvn() function is used to detect multivariate outliers with argument multivariateOutlierMethod="quan" and showOutliers= TRUE, using the chi-square distribution critical value approach and represent them on a plot.
boxplot(Racing_Data_New$lengths_behind , main="Boxplot of Horse lagging behind the winner before removing outlier", horizontal= TRUE , col="light pink" , xlab = "Lenghts Behind in meter" ,ylim=c(0,200))

favstats(~lengths_behind , data = Racing_Data_New)
Upper_fence <- (6.75 + (3/2)*(6.75 - 1.75)) #q3 + (3/2)(q3-q1)
Upper_fence
[1] 14.25
Lower_fence <- (1.75 - (3/2)*(6.75 - 1.75)) #q1 - (3/2)(q3-q1)
Lower_fence
[1] -5.75
Racing_Data_New_subset <- subset(Racing_Data_New , (lengths_behind < Upper_fence))
boxplot(Racing_Data_New_subset$lengths_behind , main="Boxplot of Horse lagging behind the winner after removing outlier", horizontal= TRUE , col="light blue" , xlab = "Lenghts Behind in meter" ,ylim=c(0,20))

boxplot(Racing_Data_New$horse_weight ~ Racing_Data_New$going, main = "Boxplot of horse weight by type of racing track before removing Outlier", ylab = "Horse Weight", xlab = "Type of Racing Track",col = "red")

Racing_Data_New %>% plot(horse_weight ~ actual_weight,data=., ylab="Horse weight", xlab="Weight on the horse", main ="Boxplot of horse weight by Weignt on the horse")

Racing_subset_for_mvn <- Racing_Data_New %>% filter( race_class == 13) %>% dplyr::select(horse_weight, actual_weight)
head(Racing_subset_for_mvn)
Mahalanobis_distance_QQ_plot <- mvn(data = Racing_subset_for_mvn, multivariateOutlierMethod = "quan", showOutliers = TRUE)

Transform
- By plotting histogram using the generic function
hist(), it is noticed that ratio_of_horse_to_actual weight and declared_weightis slightly skewed to the right.
- Log and square root transformation is performed to reduce the skewness and named it as
Log_ratio_of_horse_to_actual and Square_Root respectively.
- Plotted a histogram for
Log_ratio_of_horse_to_actual and Square_Root using the function hist() with the argument prob = TRUE which plots a density function instead of frequency.
- Calculated the mean and standard deviation for Log_ratio_of_horse_to_actual and Square_Root, saved it as Mean, Sd and Mean1, S1 respectively.
- Created a sequence using the function
seq and minimum & maximum values in the data set for Log_ratio_of_horse_to_actual and Square_Root.
- Using the function
dnorm we calculated the density of the Log_ratio_of_horse_to_actual and Square_Rootwith the mean and standard deviation that we calculated for them respectively.
- Plotted a sequence of points at the specified coordinates using the generic function
points() with a normal distribution overlay over the histogram.
hist(Racing_Data_New$ratio_of_horse_to_actual,main = "Histogram of declared to actual weight before transformation" , xlab = "Ratio of declared to actual weight", col = "grey")

Log_ratio_of_horse_to_actual <- log(Racing_Data_New$ratio_of_horse_to_actual)
hist(Log_ratio_of_horse_to_actual ,xlim = c(1.8,2.4),ylim = c(0,5),prob = TRUE, main = "Histogram for log of horse weight to actual weight after transformation" , xlab = "Log ratio of horse weight to actual weight", col = "orange" )
Mean <- mean(Log_ratio_of_horse_to_actual)
Sd <- sd(Log_ratio_of_horse_to_actual)
X <- seq(min(Log_ratio_of_horse_to_actual) , max(Log_ratio_of_horse_to_actual),0.01)
Y <- dnorm(X,Mean,Sd)
points(X,Y,type = "l", col = "blue",lwd = 2)

hist(Racing_Data_New$declared_weight,main = "Histogram of declared weight before transformation" , xlab = "Declared weight", col = "grey")

Square_Root <- sqrt(Racing_Data_New$declared_weight)
hist(Square_Root,xlim = c(30,37),ylim=c(0,0.5),prob = TRUE , main = "Histogram for Square root of declared after transformation",
xlab = "Square root of declared weight" , col = "light blue")
Mean1 <- mean(Square_Root)
Sd1 <- sd(Square_Root)
X1 <- seq(min(Square_Root) , max(Square_Root),0.01)
Y1 <- dnorm(X1,Mean1,Sd1)
points(X1,Y1,type = "l", col = "orange",lwd = 2)

LS0tDQp0aXRsZTogIk1BVEgyMzQ5IFNlbWVzdGVyIDEsIDIwMTgiDQphdXRob3I6ICJWYW1pa2EgUGFyZGVzaGktczM3MDEwMjQsIFJpdHdpY2sgRGV2LXMzNzAyMDQxIg0Kc3VidGl0bGU6IEFzc2lnbm1lbnQgMw0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQojIyBSZXF1aXJlZCBwYWNrYWdlcyANCmBgYHtyfQ0KbGlicmFyeShyZWFkcikgICAgICNVc2VmdWwgZm9yIGltcG9ydGluZyBkYXRhDQpsaWJyYXJ5KHJlYWR4bCkgICAgI1VzZWZ1bCBmb3IgaW1wb3J0aW5nIGV4Y2VsIHNoZWV0cw0KbGlicmFyeShmb3JlaWduKSAgICNVc2VmdWwgZm9yIGltcG9ydGluZyBTUFNTLCBTQVMsIFNUQVRBIGV0Yy4gZGF0YSBmaWxlcw0KbGlicmFyeShnZGF0YSkgICAgICN1c2VmdWwgZm9yIHByb3ZpZGluZyB2YXJpb3VzIHRvb2xzIGZvciBkYXRhIG1hbmlwdWxhdGlvbg0KbGlicmFyeShydmVzdCkgICAgICNVc2VmdWwgZm9yIHNjcmFwaW5nIEhUTUwgZGF0YQ0KbGlicmFyeSh0aWR5cikgICAgICNVc2VmdWwgZm9yIHRpZHlpbmcgZGF0YQ0KbGlicmFyeShkcGx5cikgICAgICNVc2VmdWwgZm9yIGRhdGEgbWFuaXB1bGF0aW9uDQpsaWJyYXJ5KGRlZHVjdGl2ZSkgI1VzZWZ1bCBmb3IgZGVkdWN0aXZlIGRhdGEgY29ycmVjdGlvbiBhbmQgSW1wdXRhdGlvbg0KbGlicmFyeSh2YWxpZGF0ZSkgICNVc2VmdWwgZm9yIGRhdGEgdmFsaWRhdGlvbg0KbGlicmFyeShIbWlzYykgICAgICNVc2VmdWwgaW4gcmVjb2RpbmcgbWlzc2luZyB2YWx1ZXMgDQpsaWJyYXJ5KHN0cmluZ3IpICAgI1VzZWZ1bCBmb3Igc2FtcGxpbmcgY2hhcmFjdGVyIHZlY3RvcnMgZm9yIHN0cmluZyBtYW5pcHVsYXRpb25zDQpsaWJyYXJ5KGx1YnJpZGF0ZSkgI1VzZWZ1bCBmb3Igd29ya2luZyB3aXRoIGRhdGVzIGFuZCB0aW1lcw0KbGlicmFyeShvdXRsaWVycykgICNVc2VmdWwgaW4gcmVtb3Zpbmcgb3V0bGllcnMNCmxpYnJhcnkoTVZOKSAgICAgICAjVXNlZnVsIGZvciBtdWx0aXZhcmlhdGUgbm9ybWFsaXR5IHRlc3RzDQpsaWJyYXJ5KGluZm90aGVvKSAgI1VzZWZ1bCBmb3IgaW1wbGVtZW50aW5nIG1lYXN1cmVzIG9mIGluZm9ybWF0aW9uIHRoZW9yeSBiYXNlZCBvbiBzZXZlcmFsIGVudHJvcHkgZXN0aW1hdG9ycw0KbGlicmFyeShNQVNTKSAgICAgICNVc2VmdWwgdG8gc3VwcG9ydCBWZW5hYmxlcyBhbmQgUmlwbGV5DQpsaWJyYXJ5KGNhcmV0KSAgICAgI1VzZWZ1bCBmb3IgbW9kZWwgdHJhaW5pbmcgcHJvY2VzcyBmb3IgY29tcGxleCByZWdyZXNzaW9uICYgY2xhc3NpZmljYXRpb24gcHJvYmxlbXMNCmxpYnJhcnkobWxyKSAgICAgICAjVXNlZnVsIGZvciBwcm92aWRpbmcgdW5pZmllZCBpbnRlcmZhY2UgZm9yIG1hY2hpbmUgbGVhcm5pbmcgdGFza3MgaW4gUg0KbGlicmFyeShnZ3Bsb3QyKSAgICNVc2VmdWwgZm9yIGNyZWF0aW5nIGdyYXBoaWNzIGJhc2VkIG9uICdUaGUgR3JhbW1hciBvZiBncmFwaGljcycNCmxpYnJhcnkoa25pdHIpICAgICAjVXNlZnVsIGZvciBjcmVhdGluZyBuaWNlIHRhYmxlcw0KbGlicmFyeShyYXN0ZXIpICAgICNVc2VmdWwgaW4gY3JlYXRpbmcgZnVuY3Rpb25zDQpsaWJyYXJ5KG1vc2FpYykgICAgI1VzZWZ1bCBmb3IgRGVzY3JpcHRpdmUgU3RhdGlzdGljcw0KYGBgDQoNCiMjIEV4ZWN1dGl2ZSBTdW1tYXJ5IA0KDQpUaGUgdHdvIGRhdGFzZXRzICdyYWNlcycgYW5kICdydW5zJyBoYXZlIGJlZW4gaW1wb3J0ZWQgdG8gUiBhbmQgdGhlbiBtZXJnZWQgdG8gZm9ybSBgUmFjaW5nX2RhdGFgLiBGdXJ0aGVybW9yZSwgaW5zcGVjdGVkIHRoZSB2YXJpYWJsZSBhbmQgdGhlIGRhdGEgc3RydWN0dXJlIG9mIHRoaXMgY29tYmluZWQgZGF0YXNldC5GYWN0b3JpemVkIHRoZSBob3JzZSBjb3VudHJ5IHZhcmlhYmxlIGFuZCBjaGFuZ2VkIGl0cyBsYWJlbHMuIFNpbmNlLCB0aGUgZGF0YXNldCB3YXMgYWxyZWFkeSBmb2xsb3dpbmcgdGhlIHRpZHkgZGF0YSBwcmluY2lwbGVzLCB0aGVyZSB3YXMgbm8gbmVlZCB0byB0aWR5IHN0ZXBzIHBlcmZvcm1lZC4gRm91ciBuZXcgY29sdW1ucyBoYXZlIGJlZW4gbXV0YXRlZCwgaS5lLDxicj4NCjxiPjEuUmF0aW8gb2Ygd2luIHRvIHBsYWNlPC9iPi10byBjaGVjayB0aGUgcHJvYmFiaWxpdHkgb2YgdGhlIGhvcnNlIGluIGEgcGFydGljdWxhciByYWNlLiBIaWdoZXIgdGhlIFJhdGlvIG9mIHdpbiB0byBwbGFjZSwgaGlnaGVyIHdpbGwgYmUgdGhlIGNoYW5jZXMgb2YgdGhlIGhvcnNlIHRvIHdpbiB0aGUgcmFjZS4gQWx0aG91Z2ggb3RoZXIgZmFjdG9ycyBhbHNvIHBsYXkgYSBjcnVjaWFsIHJvbGUgaW4gZGVyaXZpbmcgYSBwcm9iYWJpbGl0eSBvZiB0aGUgd2lubmluZyBob3JzZSBsaWtlIHRoZSBzcGVlZCBvZiB0aGUgaG9yc2UsIHRyYWNrIGNvbmRpdGlvbiwgam9ja2V5IHdlaWdodCx0cmFpbmVyIG9mIHRoZSBob3JzZSBhbmQgaGFuZGljYXBwZWQgd2VpZ2h0cyBvbiB0aGUgaG9yc2UgZXRjLjxicj4NCjxiPjIuSG9yc2Ugd2VpZ2h0PC9iPi10byBnZXQgdGhlIG1lYXN1cmVkIHdlaWdodCBvZiB0aGUgaG9yc2Ugc3VidHJhY3RlZCB0aGUgYWN0dWFsIHdlaWdodCAoam9ja2V5IHdlaWdodCsgaGFuZGljYXBwZWQgd2VpZ2h0IG9uIHRoZSBob3JzZSkgZnJvbSB0aGUgZGVjbGFyZWQgd2VpZ2h0IChob3JzZSB3ZWlnaHQrIGpvY2tleSB3ZWlnaHQrIGhhbmRpY2FwcGVkIHdlaWdodCBvbiB0aGUgaG9yc2UpLjxicj4NCjxiPjMuUmF0aW8gb2YgaG9yc2Ugd2VpZ2h0IHRvIGFjdHVhbCB3ZWlnaHQ8L2I+LXRvIGNhbGN1bGF0ZSB0aGUgcHJvcG9ydGlvbiBvZiB0aGUgaG9yc2Ugd2VpZ2h0IHRvIHRoZSBhY3R1YWwgd2VpZ2h0IGluIGEgcGFydGljdWxhciByYWNlLCB0aGlzIGFmZmVjdHMgdGhlIHNwZWVkIG9mIHRoZSBob3JzZS48YnI+DQo8Yj40LkF2ZXJhZ2UgaG9yc2Ugc3BlZWQ8L2I+LXRvIGdldCB0aGUgYXZlcmFnZSBzcGVlZCBvZiB0aGUgaG9yc2UgaW4gYSByYWNlIHdpdGggcmVzcGVjdCB0byB0aGUgbGVuZ3RoIG9mIHRoZSByYWNlIHRyYWNrLjxicj4NCkFmdGVyIHRoaXMsIHNjYW5uZWQgZm9yIHRoZSBOQSB2YWx1ZXMgYW5kIGluY29uc2lzdGVuY2llcyB3aGljaCB3ZXJlIHJlbW92ZWQgZnJvbSB0aGUgZGF0YS4gQWx0aG91Z2gsIG1hbnkgbnVtZXJpYyBjb2x1bW5zIGFyZSBwcmVzZW50IGluIHRoZSBkYXRhc2V0LCBidXQgcGVyZm9ybWluZyBvdXRsaWVyIHRyZWF0bWVudCBmb3IgYWxsIHRob3NlIGNvbHVtbnMgaXMgbm90IHJlbGV2YW50LCBhcyBmZXcgb2YgdGhlc2UgY29sdW1ucyBhcmUgSUQncyBvZiBhIHJhY2UsIGhvcnNlLCBqb2NrZXkgYW5kIHRyYWluZXIgZXRjLiBEZXRlY3RlZCBhbmQgcmVtb3ZlZCB0aGUgb3V0bGllciwgZmlyc3RseSBwbG90dGVkIGEgYm94cGxvdCBmb3IgdGhlIGxlbmd0aCBiZWhpbmQgY29sdW1uIHRvIGRldGVybWluZSB0aGUgbGVuZ3RoIGJ5IHdoaWNoIHRoZSBob3JzZSBpcyBsYWdnaW5nIGJlaGluZCBmcm9tIHRoZSB3aW5uaW5nIGhvcnNlLiBOZXh0LCBpbiBvcmRlciB0byBjb21wYXJlIGEgcXVhbnRpdGF0aXZlIHZhcmlhYmxlIHdpdGggYSBxdWFsaXRhdGl2ZSB2YXJpYWJsZSwgYml2YXJpYXRlIGJveHBsb3Qgd2FzIHBsb3R0ZWQgZm9yIGhvcnNlIHdlaWdodCBhbmQgZ29pbmcgKHRyYWNrIGNvbmRpdGlvbikuIEluIGFkZGl0aW9uIHRvIHRoYXQsIGEgc2NhdHRlciBwbG90IHdhcyBwbG90dGVkIGZvciBob3JzZSB3ZWlnaHQgYW5kIGFjdHVhbCB3ZWlnaHQgdmFyaWFibGVzLiBNb3Jlb3ZlciwgYSBtdWx0aXZhcmlhdGUgb3V0bGllciB0cmVhdG1lbnQgaXMgcGVyZm9ybWVkIG9uIGEgcGFydGljdWxhciBjbGFzcyBvZiB0aGUgcmFjZSB3aXRoIGhvcnNlIHdlaWdodCBhbmQgYWN0dWFsIHdlaWdodCB2YXJpYWJsZXMuIExhc3RseSwgdHJhbmZvcm1lZCB0aGUgZGF0YSBieSB1c2luZyBMb2cgYW5kIFNxdWFyZSByb290IHRyYW5zZm9ybWF0aW9uIGZvciByZWR1Y2luZyB0aGUgc2tld25lc3MsIG9uIHRoZSB2YXJpYWJsZXMgcmF0aW8gb2YgaG9yc2UgdG8gYWN0dWFsIHdlaWdodCBhbmQgZGVjbGFyZWQgd2VpZ2h0LCByZXNwZWN0aXZlbHkuDQoNCiMjIERhdGEgDQoNCiogVGhlIGRhdGFzZXRzIGNvbnRhaW4gZGF0YSBvZiB0aG9yb3VnaGJyZWQgaG9yc2UgcmFjaW5nIGluIEhvbmcgS29uZy4gSG9yc2UgcmFjaW5nIGJlaW5nIGEgbWFzc2l2ZSBidXNpbmVzcyBpbiBIb25nIEtvbmcsIHJlc3VsdGluZyBpbiBiZXR0aW5nIHBvb2xzIGJpZ2dlciB0aGFuIGFsbCByYWNldHJhY2tzIGluIFVTIGNvbWJpbmVkLg0KKiBUaGVyZSBhcmUgdHdvIGRhdGFzZXRzIGkuZSBgcmFjZXNgIGFuZCBgcnVuc2AsIHByZXNlbnRlZCBpbiBDU1YgZm9ybWF0Lg0KKmByYWNlcy5jc3ZgIHJlcHJlc2VudHMgZGF0YSBvbiBjb25kaXRpb24gb2YgZWFjaCByYWNlIHRoYXQgaW5jbHVkZXMgZGlzdGFuY2UsIHRyYWNrIGNvbmRpdGlvbiwgZGlzdGFuY2UgYW5kIGRpdmlkZW5kcyBwYWlkLiBXaGVyZWFzLCBgcnVucy5jc3ZgIHJlcHJlc2VudHMgZGF0YSBvZiBlYWNoIGhvcnNlIHJ1bm5pbmcgaW4gZWFjaCBvZiB0aGUgcmFjZXMgbWVudGlvbmVkIGluIGByYWNlcy5jc3ZgLg0KKiBJbiBgcnVucy5jc3ZgLCBlYWNoIGxpbmUgZGVzY3JpYmVzIHRoZSBjaGFyYWN0ZXJpc3RpY3Mgb2Ygb25lIGhvcnNlIHJ1biwgaW4gb25lIG9mIHRoZSByYWNlcyBnaXZlbiBpbiByYWNlcy5jc3YsIGFuZCBpdCBjb250YWlucyB0aGUgZm9sbG93aW5nIHZhcmlhYmxlcy08YnI+DQogIDxiPjEuIHJhY2VfaWQ8L2I+LSB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIHJhY2U8YnI+DQogIDxiPjIuIGhvcnNlX25vPC9iPi0gdGhlIG51bWJlciBhc3NpZ25lZCB0byB0aGlzIGhvcnNlLCBpbiB0aGUgcmFjZTxicj4NCiAgPGI+My4gaG9yc2VfaWQ8L2I+LSB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhpcyBob3JzZTxicj4NCiAgPGI+NC4gcmVzdWx0PC9iPi0gZmluaXNoaW5nIHBvc2l0aW9uIG9mIHRoaXMgaG9yc2UgaW4gdGhlIHJhY2U8YnI+DQogIDxiPjUuIHdvbjwvYj4tIHdoZXRoZXIgaG9yc2Ugd29uICgxKSBvciBvdGhlcndpc2UgKDApPGJyPg0KICA8Yj42LiBsZW5naHRzX2JlaGluZDwvYj4tIGZpbmlzaGluZyBwb3NpdGlvbiwgYXMgdGhlIG51bWJlciBvZiBob3JzZSBsZW5ndGhzIGJlaGluZCB0aGUgd2lubmVyPGJyPg0KICA8Yj43LiBob3JzZV9hZ2U8L2I+LSBjdXJyZW50IGFnZSBvZiB0aGlzIGhvcnNlIGF0IHRoZSB0aW1lIG9mIHRoZSByYWNlPGJyPg0KICA8Yj44LiBob3JzZV9jb3VudHJ5PC9iPi0gY291bnRyeSBvZiBvcmlnaW4gb2YgdGhlIGhvcnNlPGJyPg0KICA8Yj45LiBob3JzZV90eXBlPC9iPi0gc2V4IG9mIHRoZSBob3JzZSwgZS5nLiBgR2VsZGluZ2AsYE1hcmVgLGBIb3JzZWAsYFJpZ2AsYENvbHRgLGBGaWxseWA8YnI+DQogIDxiPjEwLmhvcnNlX3JhdGluZzwvYj4tIHJhdGluZyBudW1iZXIgYXNzaWduZWQgYnkgSEtKQyB0byB0aGlzIGhvcnNlIGF0IHRoZSB0aW1lIG9mIHRoZSByYWNlPGJyPg0KICA8Yj4xMS5kZWNsYXJlZF93ZWlnaHQ8L2I+LSBkZWNsYXJlZCB3ZWlnaHQgb2YgdGhlIGhvcnNlIGFuZCBqb2NrZXksIGluIGxiczxicj4NCiAgPGI+MTIuYWN0dWFsX3dlaWdodDwvYj4tIGFjdHVhbCB3ZWlnaHQgY2FycmllZCBieSB0aGUgaG9yc2UsIGluIGxiczxicj4NCiAgPGI+MTMuZHJhdzwvYj4tIHBvc3QgcG9zaXRpb24gbnVtYmVyIG9mIHRoZSBob3JzZSBpbiB0aGlzIHJhY2U8YnI+DQogIDxiPjE0LmZpbmlzaF90aW1lPC9iPi0gZmluaXNoaW5nIHRpbWUgb2YgdGhlIGhvcnNlIGluIHRoaXMgcmFjZSAoaW4gc2VjKTxicj4NCiAgPGI+MTUud2luX29kZHM8L2I+LSB3aW4gb2RkcyBmb3IgdGhpcyBob3JzZSBhdCBzdGFydCBvZiByYWNlPGJyPg0KICA8Yj4xNi5wbGFjZV9vZGRzPC9iPi0gcGxhY2Ugb2RkcyBmb3IgdGhpcyBob3JzZSBhdCBzdGFydCBvZiByYWNlIChmaW5pc2hpbmcgaW4gMXN0LCAybmQgb3IgM3JkIHBvc2l0aW9uKTxicj4NCiAgPGI+MTcudHJhaW5lcl9pZDwvYj4tIHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBob3JzZSdzIHRyYWluZXIgYXQgdGhlIHRpbWUgb2YgdGhlIHJhY2U8YnI+DQogIDxiPjE4LmpvY2tleV9pZDwvYj4tIHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBqb2NrZXkgcmlkaW5nIHRoZSBob3JzZSBpbiB0aGlzIHJhY2U8YnI+DQoqIEluIGByYWNlcy5jc3ZgLCB0aGUgY29uZGl0aW9uIG9mIGFuIGluZGl2aWR1YWwgcmFjZSBpcyBkZXNjcmliZWQgaW4gZWFjaCBsaW5lLCBhbmQgaXQgY29udGFpbnMgdGhlIGZvbGxvd2luZyB2YXJpYWJsZXMtPGJyPg0KICA8Yj4xLiByYWNlX2lkPC9iPi0gdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSByYWNlPGJyPg0KICA8Yj4yLiBkYXRlPC9iPi0gZGF0ZSBvZiB0aGUgcmFjZSwgaW4gWVlZWS1NTS1ERCBmb3JtYXQuPGJyPg0KICA8Yj4zLiB2ZW51ZTwvYj4tIGEgMi1jaGFyYWN0ZXIgc3RyaW5nLCByZXByZXNlbnRpbmcgd2hpY2ggb2YgdGhlIDIgcmFjZSBjb3Vyc2VzIHRoaXMgcmFjZSB0b29rIHBsYWNlIGF0OiBTVCA9IFNoYXRpbixIViA9IEhhcHB5IFZhbGxleTxicj4NCiAgPGI+NC4gcmFjZV9ubzwvYj4tIHJhY2UgbnVtYmVyIG9mIHRoZSByYWNlIGluIHRoZSBkYXkncyBtZWV0aW5nPGJyPg0KICA8Yj41LiBjb25maWc8L2I+LSByYWNlIHRyYWNrIGNvbmZpZ3VyYXRpb24sIG1vc3RseSByZWxhdGVkIHRvIHRoZSBwb3NpdGlvbiBvZiB0aGUgaW5zaWRlIHJhaWw8YnI+DQogIDxiPjYuIHN1cmZhY2U8L2I+LSBhIG51bWJlciByZXByZXNlbnRpbmcgdGhlIHR5cGUgb2YgcmFjZSB0cmFjayBzdXJmYWNlOiAxID0gZGlydCwgMCA9IHR1cmY8YnI+DQogIDxiPjcuIGRpc3RhbmNlPC9iPi0gIGRpc3RhbmNlIG9mIHRoZSByYWNlLCBpbiBtZXRyZXM8YnI+DQogIDxiPjguIGdvaW5nPC9iPi0gdHJhY2sgY29uZGl0aW9uPGJyPg0KICA8Yj45LiBob3JzZV9yYXRpbmdzPC9iPi0gcmFuZ2Ugb2YgaG9yc2UgcmF0aW5ncyB0aGF0IG1heSBwYXJ0aWNpcGF0ZSBpbiB0aGlzIHJhY2U8YnI+DQogIDxiPjEwLnByaXplPC9iPi0gdGhlIHdpbm5pbmcgcHJpemUsIGluIEhLIERvbGxhcnM8YnI+DQogIDxiPjExLnJhY2VfY2xhc3M8L2I+LSBhIG51bWJlciByZXByZXNlbnRpbmcgdGhlIGNsYXNzIG9mIHRoZSByYWNlPGJyPg0KICA8Yj4xMi5wbGFjZV9jb21iaW5hdGlvbjE8L2I+LSBwbGFjaW5nIGhvcnNlIG5vLiAxc3Q8YnI+DQogIDxiPjEzLnBsYWNlX2NvbWJpbmF0aW9uMjwvYj4tIHBsYWNpbmcgaG9yc2Ugbm8uIDJuZDxicj4NCiAgPGI+MTQucGxhY2VfY29tYmluYXRpb24zPC9iPi0gcGxhY2luZyBob3JzZSBuby4gM3JkPGJyPg0KICA8Yj4xNS5wbGFjZV9kaXZpZGVuZDE8L2I+LSBwbGFjaW5nIGRpdmlkZW5kIHBhaWQgKGZvciBwbGFjZV9jb21iaW5hdGlvbjEpPGJyPg0KICA8Yj4xNi5wbGFjZV9kaXZpZGVuZDI8L2I+LSBwbGFjaW5nIGRpdmlkZW5kIHBhaWQgKGZvciBwbGFjZV9jb21iaW5hdGlvbjIpPGJyPg0KICA8Yj4xNy5wbGFjZV9kaXZpZGVuZDM8L2I+LSBwbGFjaW5nIGRpdmlkZW5kIHBhaWQgKGZvciBwbGFjZV9jb21iaW5hdGlvbjMpPGJyPg0KICA8Yj4xOC53aW5fY29tYmluYXRpb24xPC9iPi0gd2lubmluZyBob3JzZSBudW1iZXI8YnI+DQogIA0KPGI+U291cmNlOjwvYj4gYGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZ2RhbGV5L2hrcmFjaW5nYCAgICAgICAgICAgYGh0dHBzOi8vZXYudHVybml0aW4uY29tL2FwcC9jYXJ0YS9lbl91cy8/c3R1ZGVudF91c2VyPTEmbGFuZz1lbl91cyZvPTk1NTQ1NzEyNCZ1PTEwNzIzNTQxNTlgICAgDQoNCiMjIFJlYWQvSW1wb3J0IERhdGENCg0KKiBEYXRhIGhhcyBiZWVuIGltcG9ydGVkIHRvIFIsIGJ5IHVzaW5nIGByZWFkLmNzdigpYCBmdW5jdGlvbiwgZnJvbSB0aGUgcGFja2FnZSBgcmVhZHJgLHVzaW5nIHRoZSBhcmd1bWVudCBgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFYCBhcyBieSBkZWZhdWx0IGByZWFkLmNzdmAgY29udmVydHMgc3RyaW5ncyB0byBmYWN0b3JzLg0KKiBJbXBvcnRlZCBkYXRhc2V0cyBhcmUgc2F2ZWQgYXMgYFJhY2VgIGFuZCBgUnVuYC4NCiogYFJhY2VgIGFuZCBgUnVuYCBhcmUgdGhlbiBtZXJnZWQgdXNpbmcgdGhlIGtleSB2YXJpYWJsZSBgcmFjZV9pZGAuDQoqIFVzaW5nIHRoZSBnZW5lcmljIGZ1bmN0aW9uIGBsZWZ0X2pvaW5gLCBgUmFjZWAgaXMgYWRkZWQgdG8gdGhlIGBSdW5gIGRhdGFmcmFtZSBhbmQgdGhlIGNvbWJpbmVkIGRhdGFmcmFtZSBpcyByZW5hbWVkIGFzIGBSYWNpbmdfZGF0YWAuDQoqIFZhbGlkYXRlZCB0aGUgZmlyc3QgZmV3IHJvd3Mgb2YgdGhlIGRhdGFmcmFtZXMgdXNpbmcgdGhlIGdlbmVyaWMgZnVuY3Rpb24gYGhlYWQoKWAuDQoNCmBgYHtyfQ0KZ2V0d2QoKQ0Kc2V0d2QoIkM6XFxVc2Vyc1xcUml0d2ljayBEZXZcXERvY3VtZW50c1xcRGF0YSBQcmVwcm9jZXNzaW5nIikNClJhY2UgPC0gcmVhZC5jc3YoInJhY2VzLmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNClJ1biA8LSByZWFkLmNzdigicnVucy5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpoZWFkKFJhY2UpDQpoZWFkKFJ1bikNClJhY2luZ19kYXRhIDwtIFJ1biAlPiUgbGVmdF9qb2luKFJhY2UgLCBieSA9ICJyYWNlX2lkIikNCmhlYWQoUmFjaW5nX2RhdGEpDQpgYGANCg0KIyMgVW5kZXJzdGFuZCANCg0KKiBUaGUgYmFzZSBSIGZ1bmN0aW9uIGBjbGFzcygpYCByZXR1cm5lZCB0aGUgIGAkbmFtZXNgLCBgJHJvd19uYW1lc2AgYW5kIGAkY2xhc3NgIG9mIGBSYWNpbmdfZGF0YWAuDQoqIFRoZSBiYXNlIFIgZnVuY3Rpb24gYGxlbmd0aCgpYCBpcyB1c2VkIHRvIGNoZWNrIHRoZSBudW1iZXIgb2YgY29sdW1ucyBpbiBgUmFjaW5nX2RhdGFgIGRhdGFmcmFtZS4NCiogVXNpbmcgdGhlIGJhc2UgUiBmdW5jdGlvbiBgZGltKClgIHJldHVybmVkIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBkYXRhZnJhbWUgYFJhY2luZ19kYXRhYC4NCiogR2VuZXJpYyBmdW5jdGlvbiBgc3RyKClgIGlzIHVzZWQgdG8gc2VlIHRoZSBkZXRhaWxlZCBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGFmcmFtZSBgUmFjaW5nX2RhdGFgLg0KKiBVc2luZyB0aGUgYmFzZSBSIGZ1bmN0aW9uIGBmYWN0b3IoKWAgY2hhbmdlZCB0aGUgbGFiZWxzIGZvciB0aGUgY29sdW1uYGhvcnNlX2NvdW50cnlgLg0KKiBNb3Jlb3Zlciwgb3JkZXJlZCB0aGUgbGV2ZWxzIHVzaW5nIHRoZSBhcmd1bWVudCBgb3JkZXJlZD1UUlVFYCBmb3IgYFJhY2luZ19kYXRhJGhvcnNlX2NvdW50cnlgLg0KKiBgbGV2ZWxzKClgIGlzIHVzZWQgdG8gY2hlY2sgbGV2ZWxzIGZvciB0aGUgY29sdW1uIGBob3JzZV9jb3VudHJ5YC4NCiogYGRteSgpYCBmdW5jdGlvbiBpcyBmcm9tIHRoZSBwYWNrYWdlIGBsdWJyaWRhdGVgaXMgdXNlZCB0byBjaGFuZ2UgdGhlIGRhdGF0eXBlIGZyb20gY2hhcmFjdGVyIHRvIGRhdGUuDQoNCmBgYHtyfQ0KY2xhc3MoUmFjaW5nX2RhdGEpDQpsZW5ndGgoUmFjaW5nX2RhdGEpDQpkaW0oUmFjaW5nX2RhdGEpDQpzdHIoUmFjaW5nX2RhdGEpDQphdHRyaWJ1dGVzKFJhY2luZ19kYXRhKQ0KUmFjaW5nX2RhdGEkaG9yc2VfY291bnRyeSA8LSBmYWN0b3IoUmFjaW5nX2RhdGEkaG9yc2VfY291bnRyeSxsZXZlbHMgPSBjKCJBVVMiLCJOWiIsIlNBRiIsIkdCIiwiVVNBIiwiSVJFIiwiRlIiLCJDQU4iKSxsYWJlbHMgPSBjKCJBVVNUUkFMSUEiLCJORVdaRUFMQU5EIiwiU09VVEhBRlJJQ0EiLCJHUkVBVEJSSVRBSU4iLCJVTklURURTVEFURVNBTUVSSUNBIiwiSVJFTEFORCIsIkZSQU5DRSIsIkNBTkFEQSIpLCBvcmRlcmVkID0gVFJVRSkNCmxldmVscyhSYWNpbmdfZGF0YSRob3JzZV9jb3VudHJ5KQ0KUmFjaW5nX2RhdGEkZGF0ZSA8LSBkbXkoUmFjaW5nX2RhdGEkZGF0ZSkNCmhlYWQoUmFjaW5nX2RhdGEpDQpgYGANCg0KIyMJVGlkeSAmIE1hbmlwdWxhdGUgRGF0YSBJIA0KDQoqIFRpZHlpbmcgdGhlIGRhdGEgaXMgbm90IHJlcXVpcmVkIGFzIHRoZSBkYXRhZnJhbWUgaXMgYWxyZWFkeSBjb25mb3JtaW5nIHRoZSB0aWR5IGRhdGEgcHJpbmNpcGxlcyB0aGF0IGlzLQ0KMS4gRWFjaCB2YXJpYWJsZSBoYXMgaXRzIG93biBjb2x1bW4uDQoyLiBFYWNoIG9ic2VydmF0aW9uIGhhcyBpdHMgb3duIHJvdy4NCjMuIEVhY2ggdmFsdWUgaGFzIGl0cyBvd24gY2VsbC4NCg0KYGBge3J9DQpgYGANCg0KIyMJVGlkeSAmIE1hbmlwdWxhdGUgRGF0YSBJSSANCg0KKiBNdXRhdGVkIHRoZSBjb2x1bW4gYFJhdGlvX29mX3dpbl90b19wbGFjZWAgYW5kIGByYXRpb19vZl9ob3JzZV90b19hY3R1YWxgIGJ5IGRpdmlkaW5nIHRoZSBjb2x1bW4gYHdpbl9vZGRzYCBieSBgcGxhY2Vfb2Rkc2AgYW5kIGBob3JzZV93ZWlnaHRgIGJ5IGBhY3R1YWxfd2VpZ2h0YCwgcmVzcGVjdGl2ZWx5Lg0KKiBDYWxjdWxhdGVkIGBBdmVyYWdlX2hvcnNlX3NwZWVkYCBieSBkaWR2aWRpbmcgYGRpc3RhbmNlYCBieSBgZmluaXNoX3RpbWVgDQoqIENyZWF0ZWQgYGhvcnNlX3dlaWdodGAgYnkgc3Vic3RyYWN0aW5nIGBhY3R1YWxfd2VpZ2h0YCBmcm9tIGBkZWNsYXJlZF93ZWlnaHRgLi4NCg0KYGBge3J9DQpSYWNpbmdfRGF0YV9tdXRhdGUgPC0gUmFjaW5nX2RhdGEgJT4lIG11dGF0ZShSYXRpb19vZl93aW5fdG9fcGxhY2UgPSB3aW5fb2RkcyAvIHBsYWNlX29kZHMgLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvcnNlX3dlaWdodCA9IGRlY2xhcmVkX3dlaWdodCAtIGFjdHVhbF93ZWlnaHQgLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXZlcmFnZV9ob3JzZV9zcGVlZCA9IGRpc3RhbmNlL2ZpbmlzaF90aW1lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF0aW9fb2ZfaG9yc2VfdG9fYWN0dWFsID0gaG9yc2Vfd2VpZ2h0IC8gYWN0dWFsX3dlaWdodCkNCmhlYWQoUmFjaW5nX0RhdGFfbXV0YXRlKQ0KYGBgDQoNCiMjCVNjYW4gSSANCg0KKiBTdWJzZXR0ZWQgdGhlIGRhdGFmcmFtZSBgUmFjaW5nX0RhdGFfbXV0YXRlYCB1c2luZyBzdWJzZXQgYnkgY29sdW1uIG51bWJlcnMgb24gYW5kIG5hbWVkIGl0IGBSRENgLg0KKiBDYWxjdWxhdGVkIHRoZSBjb2x1bW4gbWVhbiBvZiBwcmljZSBmb3Igd2lubmluZyBob3JzZSBhbmQgbmFtZWQgaXQgYGNvbF9tZWFuc2AsIGdvdCB0aGUgaW5kZXggZm9yIGVhY2ggTkEgdmFsdWVzIGFuZCBzdG9yZWQgaXQgaW4gdGhlIHZhcmlhYmxlIGBJbmRleGAgYW5kIGZpbmFsbHkgcmVwbGFjZWQgdGhlIE5BIHZhbHVlcyB3aXRoIG1lYW4uDQoqIERlbGV0ZWQgdGhlIGNvbHVtbiBwcmljZSBmcm9tIHRoZSBgUmFjaW5nX0RhdGFfbXV0YXRlYC4NCiogQ3JlYXRlZCBhIG5ldyB2YXJpYWJsZSBgUmFjaW5nX0RhdGFfTmV3YCBieSBhZGRpbmcgYFJEQ2AgdG8gYFJhY2luZ19EYXRhX211dGF0ZWAgdXNpbmcgdGhlIGZ1bmN0aW9uIGBsZWZ0X2pvaW5gLg0KKiBEZWxldGVkIHRoZSBkdXBsaWNhdGUgdmFsdWVzIGZyb20gdGhlIGRhdGFmcmFtZSBgUmFjaW5nX0RhdGFfTmV3YC4NCiogUGVyZm9ybWVkIHRoZXNlIGFib3ZlIHN0ZXBzIGFzIGBpbXB1dGUoKWAgZnVuY3Rpb24sIGZyb20gdGhlIHBhY2thZ2UgYGhtaXNjYCwgd2FzIHRocm93aW5nIGFuIGVycm9yLg0KKiBJbXB1dGVkIHRoZSB2YXJpYWJsZXMgYGRlY2xhcmVkX3dlaWdodGAsIGBob3JzZV93ZWlnaHRgLCBgcmF0aW9fb2ZfaG9yc2VfdG9fYWN0dWFsYCB1c2luZyB0aGUgYXJndW1lbnQgYGZ1bj1tZWFuYCBhbmQgZm9yIHZhcmlhYmxlcyBgaG9yc2VfY291bnRyeWAgYW5kIGBob3JzZV90eXBlYCB1c2luZyBgZnVuPW1vZGVgLg0KKiBJbnNwZWN0ZWQgdGhlIGRhdGFmcmFtZSBgUmFjaW5nX0RhdGFfTmV3YCBmb3IgTkEgdmFsdWVzIGJ5IHVzaW5nIHRoZSBmdW5jdGlvbiBgaXMubmEoKWAgYW5kIGNhbGN1bGF0ZWQgdGhlIHRvdGFsIHN1bSBvZiBOQSB2YWx1ZXMuDQoqIE1vcmVvdmVyIGNyZWF0ZWQgYSBjdXN0b20gZnVuY3Rpb24gdG8gY2hlY2sgZm9yIGFueSBpbmNvbnNpc3RlbmNpZXMgYW5kIHNwZWNpYWwgdmFsdWVzLg0KDQpgYGB7cn0NClJEQyA8LSBSYWNpbmdfRGF0YV9tdXRhdGVbLGMoMSwyNyldDQpjb2xfbWVhbnMgPC0gY29sTWVhbnMoUkRDWywtMV0sIG5hLnJtID0gVFJVRSkNCkluZGV4IDwtIHdoaWNoKGlzLm5hKFJEQyksIGFyci5pbmQgPSBUUlVFKQ0KUkRDW0luZGV4XSA8LSBjb2xfbWVhbnNbSW5kZXhbLDJdLTFdDQpSYWNpbmdfRGF0YV9tdXRhdGVbLDI3XSA8LSBOVUxMDQpSYWNpbmdfRGF0YV9OZXcgPC0gUmFjaW5nX0RhdGFfbXV0YXRlICU+JSBsZWZ0X2pvaW4oUkRDICwgYnkgPSAicmFjZV9pZCIpDQpSYWNpbmdfRGF0YV9OZXcgPC0gUmFjaW5nX0RhdGFfTmV3WyFkdXBsaWNhdGVkKFJhY2luZ19EYXRhX05ld1ssXSksXQ0KUmFjaW5nX0RhdGFfTmV3JGRlY2xhcmVkX3dlaWdodCA8LSBpbXB1dGUoUmFjaW5nX0RhdGFfTmV3JGRlY2xhcmVkX3dlaWdodCwgZnVuID0gbWVhbikNClJhY2luZ19EYXRhX05ldyRob3JzZV93ZWlnaHQgPC0gaW1wdXRlKFJhY2luZ19EYXRhX05ldyRob3JzZV93ZWlnaHQsIGZ1biA9IG1lYW4pDQpSYWNpbmdfRGF0YV9OZXckcmF0aW9fb2ZfaG9yc2VfdG9fYWN0dWFsIDwtIGltcHV0ZShSYWNpbmdfRGF0YV9OZXckcmF0aW9fb2ZfaG9yc2VfdG9fYWN0dWFsLCBmdW4gPSBtZWFuKQ0KUmFjaW5nX0RhdGFfTmV3JGhvcnNlX2NvdW50cnkgPC0gaW1wdXRlIChSYWNpbmdfRGF0YV9OZXckaG9yc2VfY291bnRyeSAsIGZ1biA9IG1vZGUpDQpSYWNpbmdfRGF0YV9OZXckaG9yc2VfY291bnRyeSA8LSBpbXB1dGUgKFJhY2luZ19EYXRhX05ldyRob3JzZV90eXBlICwgZnVuID0gbW9kZSkNCnN1bShpcy5uYShSYWNpbmdfRGF0YV9OZXckaG9yc2VfdHlwZSkpDQppcy5zcGVjaWFsIDwtIGZ1bmN0aW9uKHgpDQp7aWYgKGlzLm51bWVyaWMoeCkpICFpcy5maW5pdGUoeCkgDQogIGVsc2UgaXMubmEoeCkNCn0NCnN1bShzYXBwbHkoUmFjaW5nX0RhdGFfTmV3LCBpcy5zcGVjaWFsKSkNCmBgYA0KDQojIwlTY2FuIElJDQoNCiogVXNpbmcgdGhlIGBSYWNpbmdfRGF0YV9OZXdgIGRhdGFmcmFtZSwgaW5zcGVjdGVkIHRoZSB2YXJpYWJsZSBgbGVuZ3Roc19iZWhpbmRgIGZvciBvdXRsaWVyIGluIGJ5IHBsb3R0aW5nIGEgYm94cGxvdC4NCiogVXNpbmcgdGhlIGZ1bmN0aW9uIGBmYXZzdGF0c2AsIGNhbGN1bGF0ZWQgdGhlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MgbGlrZSBtZWFuLCBzdGFuZGFyZCBkZXZpYXRpb24gYW5kIHF1YXJ0aWxlIHZhbHVlcy4NCiogQ2FsY3VsYXRlZCB0aGUgdXBwZXIgZmVuY2UgKFEzICsgMS41KElRUikpIGFuZCBsb3dlciBmZW5jZSAoUTEgLSAxLjUoSVFSKSkgdXNpbmcgdGhlIFF1YXJ0aWxlIHZhbHVlcy4NCioJQ3JlYXRlZCBhIHN1YnNldCBvZiB0aGUgZGF0YWZyYW1lIGBSYWNpbmdfRGF0YV9OZXdgIGJ5IHJlbW92aW5nIHRoZSB1bml2YXJpYXRlIG91dGxpZXJzIHVzaW5nIHRoZSB1cHBlciBmZW5jZSB2YWx1ZXMgYW5kIG5hbWVkIGl0IGBSYWNpbmdfRGF0YV9OZXdfc3Vic2V0YC4NCioJUGxvdHRlZCBhIGJveHBsb3QgZm9yIHRoZSB2YXJpYWJsZSBgbGVuZ3Roc19iZWhpbmRgIGFnYWluIGZvciBkYXRhZnJhbWUgYFJhY2luZ19EYXRhX05ld19zdWJzZXRgLg0KKiBBIGJpdmFyaWF0ZSBib3ggcGxvdCBpcyBpbGx1c3RyYXRlZCwgYnkgdXNpbmcgYSBxdWFudGl0YXRpdmUgdmFyaWFibGVgaG9yc2Vfd2VpZ2h0YCBhbmQgYSBxdWFsaXRhdGl2ZSB2YXJpYWJsZSBgZ29pbmdgaW4gdGhlIGRhdGFzZXQgYFJhY2luZ19EYXRhX05ld2AuDQoqIEluIG9yZGVyIHRvIGdldCB0aGUgc2NhdHRlciBwbG90LCBgcGxvdCgpYCBmdW5jdGlvbiBpcyB1c2VkIGFuZCBvdXRsaWVycyBpbiBgaG9yc2Vfd2VpZ2h0YCBhbmQgYGFjdHVhbF93ZWlnaHRgIGhhdmUgYmVlbiBkZXRlY3RlZCBmcm9tIHRoZSBkYXRhZnJhbWUgYFJhY2luZ19EYXRhX05ld2AuDQoqVG8gZGV0ZWN0IG11bHRpdmFyaWF0ZSBvdXRsaWVycywgZmlyc3RseSBzdWJzZXR0ZWQgdGhlIGBSYWNpbmdfRGF0YV9OZXdgIGRhdGEsIHdoaWNoIGlzIGByYWNlIGNsYXNzPTEzYCB3aXRoIHRoZSB0d28gdmFyaWFibGVzIGBob3JzZV93ZWlnaHRgIGFuZCBgYWN0dWFsIHdlaWdodGAuDQoqVGhlbiwgYG12bigpYCBmdW5jdGlvbiBpcyB1c2VkIHRvIGRldGVjdCBtdWx0aXZhcmlhdGUgb3V0bGllcnMgd2l0aCBhcmd1bWVudCBgbXVsdGl2YXJpYXRlT3V0bGllck1ldGhvZD0icXVhbiJgIGFuZCBgc2hvd091dGxpZXJzPSBUUlVFYCwgdXNpbmcgdGhlIGNoaS1zcXVhcmUgZGlzdHJpYnV0aW9uIGNyaXRpY2FsIHZhbHVlIGFwcHJvYWNoIGFuZCByZXByZXNlbnQgdGhlbSBvbiBhIHBsb3QuIA0KDQpgYGB7cn0NCmJveHBsb3QoUmFjaW5nX0RhdGFfTmV3JGxlbmd0aHNfYmVoaW5kICwgbWFpbj0iQm94cGxvdCBvZiBIb3JzZSBsYWdnaW5nIGJlaGluZCB0aGUgd2lubmVyIGJlZm9yZSByZW1vdmluZyBvdXRsaWVyIiwgaG9yaXpvbnRhbD0gVFJVRSAsIGNvbD0ibGlnaHQgcGluayIgLCB4bGFiID0gIkxlbmdodHMgQmVoaW5kIGluIG1ldGVyIiAseWxpbT1jKDAsMjAwKSkNCmZhdnN0YXRzKH5sZW5ndGhzX2JlaGluZCAsIGRhdGEgPSBSYWNpbmdfRGF0YV9OZXcpDQpVcHBlcl9mZW5jZSA8LSAoNi43NSArICgzLzIpKig2Ljc1IC0gMS43NSkpICNxMyArICgzLzIpKHEzLXExKQ0KVXBwZXJfZmVuY2UNCkxvd2VyX2ZlbmNlIDwtICgxLjc1IC0gKDMvMikqKDYuNzUgLSAxLjc1KSkgI3ExIC0gKDMvMikocTMtcTEpDQpMb3dlcl9mZW5jZQ0KUmFjaW5nX0RhdGFfTmV3X3N1YnNldCA8LSBzdWJzZXQoUmFjaW5nX0RhdGFfTmV3ICwgKGxlbmd0aHNfYmVoaW5kIDwgVXBwZXJfZmVuY2UpKQ0KYm94cGxvdChSYWNpbmdfRGF0YV9OZXdfc3Vic2V0JGxlbmd0aHNfYmVoaW5kICwgbWFpbj0iQm94cGxvdCBvZiBIb3JzZSBsYWdnaW5nIGJlaGluZCB0aGUgd2lubmVyIGFmdGVyIHJlbW92aW5nIG91dGxpZXIiLCBob3Jpem9udGFsPSBUUlVFICwgY29sPSJsaWdodCBibHVlIiAsIHhsYWIgPSAiTGVuZ2h0cyBCZWhpbmQgaW4gbWV0ZXIiICx5bGltPWMoMCwyMCkpDQpib3hwbG90KFJhY2luZ19EYXRhX05ldyRob3JzZV93ZWlnaHQgfiBSYWNpbmdfRGF0YV9OZXckZ29pbmcsIG1haW4gPSAiQm94cGxvdCBvZiBob3JzZSB3ZWlnaHQgYnkgdHlwZSBvZiByYWNpbmcgdHJhY2sgYmVmb3JlIHJlbW92aW5nIE91dGxpZXIiLCB5bGFiID0gIkhvcnNlIFdlaWdodCIsIHhsYWIgPSAiVHlwZSBvZiBSYWNpbmcgVHJhY2siLGNvbCA9ICJyZWQiKQ0KUmFjaW5nX0RhdGFfTmV3ICU+JSBwbG90KGhvcnNlX3dlaWdodCB+IGFjdHVhbF93ZWlnaHQsZGF0YT0uLCB5bGFiPSJIb3JzZSB3ZWlnaHQiLCB4bGFiPSJXZWlnaHQgb24gdGhlIGhvcnNlIiwgbWFpbiA9IkJveHBsb3Qgb2YgaG9yc2Ugd2VpZ2h0IGJ5IFdlaWdudCBvbiB0aGUgaG9yc2UiKQ0KUmFjaW5nX3N1YnNldF9mb3JfbXZuIDwtIFJhY2luZ19EYXRhX05ldyAlPiUgZmlsdGVyKCByYWNlX2NsYXNzID09IDEzKSAlPiUgIGRwbHlyOjpzZWxlY3QoaG9yc2Vfd2VpZ2h0LCBhY3R1YWxfd2VpZ2h0KQ0KaGVhZChSYWNpbmdfc3Vic2V0X2Zvcl9tdm4pDQpNYWhhbGFub2Jpc19kaXN0YW5jZV9RUV9wbG90IDwtIG12bihkYXRhID0gUmFjaW5nX3N1YnNldF9mb3JfbXZuLCBtdWx0aXZhcmlhdGVPdXRsaWVyTWV0aG9kID0gInF1YW4iLCBzaG93T3V0bGllcnMgPSBUUlVFKQ0KYGBgDQoNCiMjCVRyYW5zZm9ybSANCg0KKiBCeSBwbG90dGluZyBoaXN0b2dyYW0gdXNpbmcgdGhlIGdlbmVyaWMgZnVuY3Rpb24gYGhpc3QoKWAsIGl0IGlzIG5vdGljZWQgdGhhdCBgcmF0aW9fb2ZfaG9yc2VfdG9fYWN0dWFsYCB3ZWlnaHQgYW5kIGBkZWNsYXJlZF93ZWlnaHRgaXMgc2xpZ2h0bHkgc2tld2VkIHRvIHRoZSByaWdodC4NCiogTG9nIGFuZCBzcXVhcmUgcm9vdCB0cmFuc2Zvcm1hdGlvbiBpcyBwZXJmb3JtZWQgdG8gcmVkdWNlIHRoZSBza2V3bmVzcyBhbmQgbmFtZWQgaXQgYXMgYExvZ19yYXRpb19vZl9ob3JzZV90b19hY3R1YWxgIGFuZCBgU3F1YXJlX1Jvb3RgIHJlc3BlY3RpdmVseS4NCiogUGxvdHRlZCBhIGhpc3RvZ3JhbSBmb3IgYExvZ19yYXRpb19vZl9ob3JzZV90b19hY3R1YWxgIGFuZCBgU3F1YXJlX1Jvb3RgIHVzaW5nIHRoZSBmdW5jdGlvbiBgaGlzdCgpYCB3aXRoIHRoZSBhcmd1bWVudCBgcHJvYiA9IFRSVUVgIHdoaWNoIHBsb3RzIGEgZGVuc2l0eSBmdW5jdGlvbiBpbnN0ZWFkIG9mIGZyZXF1ZW5jeS4NCiogQ2FsY3VsYXRlZCB0aGUgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIGZvciBMb2dfcmF0aW9fb2ZfaG9yc2VfdG9fYWN0dWFsIGFuZCBTcXVhcmVfUm9vdCwgc2F2ZWQgaXQgYXMgTWVhbiwgU2QgYW5kIE1lYW4xLCBTMSByZXNwZWN0aXZlbHkuDQoqIENyZWF0ZWQgYSBzZXF1ZW5jZSB1c2luZyB0aGUgZnVuY3Rpb24gYHNlcWAgYW5kIG1pbmltdW0gJiBtYXhpbXVtIHZhbHVlcyBpbiB0aGUgZGF0YSBzZXQgZm9yIGBMb2dfcmF0aW9fb2ZfaG9yc2VfdG9fYWN0dWFsYCBhbmQgYFNxdWFyZV9Sb290YC4NCiogVXNpbmcgdGhlIGZ1bmN0aW9uIGBkbm9ybWAgd2UgY2FsY3VsYXRlZCB0aGUgZGVuc2l0eSBvZiB0aGUgYExvZ19yYXRpb19vZl9ob3JzZV90b19hY3R1YWxgIGFuZCBgU3F1YXJlX1Jvb3Rgd2l0aCB0aGUgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIHRoYXQgd2UgY2FsY3VsYXRlZCBmb3IgdGhlbSByZXNwZWN0aXZlbHkuDQoqIFBsb3R0ZWQgYSBzZXF1ZW5jZSBvZiBwb2ludHMgYXQgdGhlIHNwZWNpZmllZCBjb29yZGluYXRlcyB1c2luZyB0aGUgZ2VuZXJpYyBmdW5jdGlvbiBgcG9pbnRzKClgIHdpdGggYSBub3JtYWwgZGlzdHJpYnV0aW9uIG92ZXJsYXkgb3ZlciB0aGUgaGlzdG9ncmFtLg0KDQpgYGB7cn0NCmhpc3QoUmFjaW5nX0RhdGFfTmV3JHJhdGlvX29mX2hvcnNlX3RvX2FjdHVhbCxtYWluID0gIkhpc3RvZ3JhbSBvZiBkZWNsYXJlZCB0byBhY3R1YWwgd2VpZ2h0IGJlZm9yZSB0cmFuc2Zvcm1hdGlvbiIgLCB4bGFiID0gIlJhdGlvIG9mIGRlY2xhcmVkIHRvIGFjdHVhbCB3ZWlnaHQiLCBjb2wgPSAiZ3JleSIpDQpMb2dfcmF0aW9fb2ZfaG9yc2VfdG9fYWN0dWFsIDwtIGxvZyhSYWNpbmdfRGF0YV9OZXckcmF0aW9fb2ZfaG9yc2VfdG9fYWN0dWFsKQ0KaGlzdChMb2dfcmF0aW9fb2ZfaG9yc2VfdG9fYWN0dWFsICx4bGltID0gYygxLjgsMi40KSx5bGltID0gYygwLDUpLHByb2IgPSBUUlVFLCBtYWluID0gIkhpc3RvZ3JhbSBmb3IgbG9nIG9mIGhvcnNlIHdlaWdodCB0byBhY3R1YWwgd2VpZ2h0IGFmdGVyIHRyYW5zZm9ybWF0aW9uIiAsIHhsYWIgPSAiTG9nIHJhdGlvIG9mIGhvcnNlIHdlaWdodCB0byBhY3R1YWwgd2VpZ2h0IiwgY29sID0gIm9yYW5nZSIgKQ0KTWVhbiA8LSBtZWFuKExvZ19yYXRpb19vZl9ob3JzZV90b19hY3R1YWwpDQpTZCA8LSBzZChMb2dfcmF0aW9fb2ZfaG9yc2VfdG9fYWN0dWFsKQ0KWCA8LSBzZXEobWluKExvZ19yYXRpb19vZl9ob3JzZV90b19hY3R1YWwpICwgbWF4KExvZ19yYXRpb19vZl9ob3JzZV90b19hY3R1YWwpLDAuMDEpDQpZIDwtIGRub3JtKFgsTWVhbixTZCkNCnBvaW50cyhYLFksdHlwZSA9ICJsIiwgY29sID0gImJsdWUiLGx3ZCA9IDIpDQpoaXN0KFJhY2luZ19EYXRhX05ldyRkZWNsYXJlZF93ZWlnaHQsbWFpbiA9ICJIaXN0b2dyYW0gb2YgZGVjbGFyZWQgd2VpZ2h0IGJlZm9yZSB0cmFuc2Zvcm1hdGlvbiIgLCB4bGFiID0gIkRlY2xhcmVkIHdlaWdodCIsIGNvbCA9ICJncmV5IikNClNxdWFyZV9Sb290IDwtIHNxcnQoUmFjaW5nX0RhdGFfTmV3JGRlY2xhcmVkX3dlaWdodCkNCmhpc3QoU3F1YXJlX1Jvb3QseGxpbSA9IGMoMzAsMzcpLHlsaW09YygwLDAuNSkscHJvYiA9IFRSVUUgLCBtYWluID0gIkhpc3RvZ3JhbSBmb3IgU3F1YXJlIHJvb3Qgb2YgZGVjbGFyZWQgYWZ0ZXIgdHJhbnNmb3JtYXRpb24iLA0KICAgICB4bGFiID0gIlNxdWFyZSByb290IG9mIGRlY2xhcmVkIHdlaWdodCIgLCBjb2wgPSAibGlnaHQgYmx1ZSIpDQpNZWFuMSA8LSBtZWFuKFNxdWFyZV9Sb290KQ0KU2QxIDwtIHNkKFNxdWFyZV9Sb290KQ0KWDEgPC0gc2VxKG1pbihTcXVhcmVfUm9vdCkgLCBtYXgoU3F1YXJlX1Jvb3QpLDAuMDEpDQpZMSA8LSBkbm9ybShYMSxNZWFuMSxTZDEpDQpwb2ludHMoWDEsWTEsdHlwZSA9ICJsIiwgY29sID0gIm9yYW5nZSIsbHdkID0gMikNCmBgYA0K