Normal Distribution

Generate Data


cont_norm <- function(n, # sample size
                      mu1 = 0, # only one mu since the mean is the same for both distributions. 
                      mu2 = 0, # only one mu since the mean is the same for both distributions. 
                      sd1 = 1, # sd of the first Distribution 
                      sd2 = 100, # sd of the second Distribution
                      prob = 0.1 # contamination proportion
){

  data <-  rnorm(n, mean = mu1, sd = sd1)
  
  list_contamination <-  rnorm(round((n*prob)), mean = mu2, sd = sd2)
  
 # samplePos <- sample(1:n , round((n*prob)))

  
  data_contamination <- c(data, list_contamination) 
  #data_contamination[samplePos] <- list_contamination[samplePos]
  

  
   list(
     data = data,
     data_contamination = data_contamination
    )
   
}

Data Generations Factors

  1. sample size (30,50,100,500)
  2. variance (1)
  3. contamination (10% , 20% , 30%)

\(var_{contamination} = var_{original} * 2\)


generateData <- function(sampleSize , var , contamination ){
  
  
results = NULL
#create 1000 random sample with contamination
for(i in 1:2000){
  #generate data  
  data_with_contamination <-  cont_norm(sampleSize,
                                                  mu1 = 0, 
                                                  mu2 = 4, 
                                                  sd1 = var,
                                                  sd2 = var*2,
                                                  prob =contamination)$data_contamination
  

  
 
  
  #Code To Handling outlier 
  

  #Quantile based flooring and capping
  #In this technique, the outlier is capped at a certain value above the upper percentile value or floored   at a factor below the lower percentile value.
  
lower  = quantile(data_with_contamination  , c(.025))[["2.5%"]]
upper = quantile(data_with_contamination  , c(.975))[["97.5%"]]


outliers <- boxplot(data_with_contamination, plot=FALSE)$out
outliersPos <- which(data_with_contamination %in% outliers)
 
  
 
dataAfterHandling_Q_b_F_C <- data_with_contamination
dataAfterHandling_mean <- data_with_contamination
dataAfterHandling_median <- data_with_contamination
dataAfterHandling_mode <- data_with_contamination


dataAfterHandling_Q_b_F_C[dataAfterHandling_Q_b_F_C<lower] <- lower
dataAfterHandling_Q_b_F_C[dataAfterHandling_Q_b_F_C>upper] <- upper
x_bar_After_Handling_Q_b_F_C <- mean(dataAfterHandling_Q_b_F_C)
x_sd_After_Handling_Q_b_F_C <- sd(dataAfterHandling_Q_b_F_C)
# 
# 
mean = mean(dataAfterHandling_mean)
dataAfterHandling_mean[outliersPos] <- mean
# dataAfterHandling_mean[dataAfterHandling_mean>upper] <- mean
x_bar_After_mean <- mean(dataAfterHandling_mean)
x_sd_After_mean <- sd(dataAfterHandling_mean)
# 
# 
median = median(dataAfterHandling_median)
dataAfterHandling_median[outliersPos] <- median
# dataAfterHandling_median[dataAfterHandling_median>upper] <- median
x_bar_After_median <- mean(dataAfterHandling_median)
x_sd_After_median <- sd(dataAfterHandling_median)
# 
mode = getmode(dataAfterHandling_mode)
dataAfterHandling_mode[outliersPos] <- mode
# dataAfterHandling_mode[dataAfterHandling_mode>upper] <- mode
x_bar_After_mode <- mean(dataAfterHandling_mode)
x_sd_After_mode <- sd(dataAfterHandling_mode)




# Normality Test After Quantile based flooring and capping
NormalityTest_p_value_After_Q_b_F_C <- shapiro.test(dataAfterHandling_Q_b_F_C)$p.value
NormalityTest_p_value_After_mean <- shapiro.test(dataAfterHandling_mean)$p.value
NormalityTest_p_value_After_median <- shapiro.test(dataAfterHandling_median)$p.value
NormalityTest_p_value_After_mode <- shapiro.test(dataAfterHandling_mode)$p.value


 results = rbind(
   results,
   data.frame(
     i,
     
     NormalityTest_p_value_After_Q_b_F_C ,
     NormalityTest_p_value_After_mean ,
     NormalityTest_p_value_After_median ,
     NormalityTest_p_value_After_mode ,
     
     
     x_bar_After_Handling_Q_b_F_C,
     x_bar_After_mean,
     x_bar_After_median,
     x_bar_After_mode ,
     
     x_sd_After_Handling_Q_b_F_C,
     x_sd_After_mean,
     x_sd_After_median,
     x_sd_After_mode
     ))
}

results
}

# different sample size with sd = 1 and contamination=10%
data_30_1_10 <- generateData(30 , 1 , .1)
data_50_1_10 <- generateData(50 , 1 , .1)
data_100_1_10 <- generateData(100 , 1 , 0.1)
data_500_1_10 <- generateData(500 , 1 , 0.1)

# different sample size with sd = 1 and contamination=20%
data_30_1_20 <- generateData(30 , 1,0.2)
data_50_1_20 <- generateData(50 , 1,0.2)
data_100_1_20 <- generateData(100,1,0.2)
data_500_1_20 <- generateData(500,1,0.2)



# different sample size with sd = 1 and contamination=20%
data_30_1_30 <- generateData(30 , 1,0.3)
data_50_1_30 <- generateData(50 , 1,0.3)
data_100_1_30 <- generateData(100,1,0.3)
data_500_1_30 <- generateData(500,1,0.3)
  1. pValue > .05 for All methods (mean ,median ….)
  2. Biased mean between x_BarAfter and 0 >>>> sum(abs(xbar-0))/1000
  3. Biased sd >>> sum(abs(xsd-1))/1000
  4. Mse Mean = sum(xbar^2)/1000
  5. MSE SD = sum((xsd-1)^2)/1000

above_05 <- function(pValueList){
  percent <- mean(pValueList>.05)
  return (percent)
}

doCalculations <- function(data , sampleSize , contamination) {
  
   data %>% summarize(
  sampleSize = sampleSize ,
  contamination = contamination,
  bias_XBar_Q_b_F_C = bias(x_bar_After_Handling_Q_b_F_C , 0),
  bias_XBar_Mean = bias(x_bar_After_mean ,0),
  bias_XBar_Median = bias(x_bar_After_median , 0),
  bias_XBar_Mode = bias(x_bar_After_mode ,0) ,
  
  bias_SD_Q_b_F_C = bias(x_sd_After_Handling_Q_b_F_C , 1),
  bias_SD_Mean = bias(x_sd_After_mean ,1),
  bias_SD_Median = bias(x_sd_After_median , 1),
  bias_SD_Mode = bias(x_sd_After_mode ,1) ,
  
  
  MSE_XBar_Q_b_F_C  = MSE(x_bar_After_Handling_Q_b_F_C, 0),
  MSE_XBar_Mean  = MSE(x_bar_After_mean, 0),
  MSE_XBar_Median   = MSE(x_bar_After_median, 0),
  MSE_XBar_Mode  = MSE(x_bar_After_mode, 0),
  
  MSE_SD_Q_b_F_C  = MSE(x_sd_After_Handling_Q_b_F_C, 1),
  MSE_SD_Mean  = MSE(x_sd_After_mean, 1),
  MSE_SD_Median   = MSE(x_sd_After_median, 1),
  MSE_SD_Mode  = MSE(x_sd_After_mode, 1),
  
  
  above05_Q_b_F_C = above_05(NormalityTest_p_value_After_Q_b_F_C),
  above05_Mean  = above_05(NormalityTest_p_value_After_mean),
  above05_Median = above_05(NormalityTest_p_value_After_median),
  above05_Mode = above_05(NormalityTest_p_value_After_mode)
) 
}

 

finalResult <- NULL 

finalResult <- rbind(
  finalResult ,
                doCalculations(data_30_1_10 , 30,10),
                doCalculations(data_50_1_10 , 50,10),
                doCalculations(data_100_1_10 , 100,10),
                doCalculations(data_500_1_10 , 500,10),
  
                doCalculations(data_30_1_20 , 30,20),
                doCalculations(data_50_1_20 , 50,20),
                doCalculations(data_100_1_20 , 100,20),
                doCalculations(data_500_1_20 , 500,20),
     
                doCalculations(data_30_1_30 , 30,30),
                doCalculations(data_50_1_30 , 50,30),
                doCalculations(data_100_1_30 , 100,30),
                doCalculations(data_500_1_30 , 500,30)
                     )

finalResult %>% select(sampleSize , contamination , bias_XBar_Q_b_F_C , bias_XBar_Mean , bias_XBar_Median , bias_XBar_Mode)



finalResult %>% select(sampleSize , contamination , bias_SD_Q_b_F_C  , bias_SD_Mean , bias_SD_Median , bias_SD_Mode)


finalResult %>% select(sampleSize , contamination , MSE_XBar_Q_b_F_C  , MSE_XBar_Mean , MSE_XBar_Median , MSE_XBar_Mode)
 

finalResult %>% select(sampleSize , contamination , MSE_SD_Q_b_F_C  , MSE_SD_Mean , MSE_SD_Median , MSE_SD_Mode)


finalResult %>% select(sampleSize , contamination ,above05_Q_b_F_C  , above05_Mean , above05_Median , above05_Mode)
NA
NA

#Relation Between sample size and Biased in X bar for each method

finalResult %>% select( sampleSize , contamination, bias_XBar_Q_b_F_C , bias_XBar_Mean , bias_XBar_Median , bias_XBar_Mode) %>% gather("Method" , "Biased_X_Bar" ,
                       bias_XBar_Q_b_F_C , bias_XBar_Mean , bias_XBar_Median , bias_XBar_Mode ) %>% 
  ggplot(aes(x = as.factor(sampleSize) , y = Biased_X_Bar)) + 
  geom_point( aes(colour = as.factor(contamination))) + 
  facet_wrap(.~Method)




finalResult %>% select( sampleSize , contamination, bias_SD_Q_b_F_C , bias_SD_Mean , bias_SD_Median , bias_SD_Mode) %>% gather("Method" , "Biased_X_SD" ,
                       bias_SD_Q_b_F_C , bias_SD_Mean , bias_SD_Median , bias_SD_Mode ) %>% 
  ggplot(aes(x = as.factor(sampleSize) , y = Biased_X_SD)) + 
  geom_point( aes(colour = as.factor(contamination))) + 
  facet_wrap(.~Method)




finalResult %>% select( sampleSize , contamination, MSE_XBar_Q_b_F_C , MSE_XBar_Mean , MSE_XBar_Median , MSE_XBar_Mode) %>% gather("Method" , "MSE_XBar" ,
                       MSE_XBar_Q_b_F_C , MSE_XBar_Mean , MSE_XBar_Median , MSE_XBar_Mode ) %>% 
  ggplot(aes(x = as.factor(sampleSize) , y = MSE_XBar)) + 
  geom_point( aes(colour = as.factor(contamination))) + 
  facet_wrap(.~Method)


finalResult %>% select( sampleSize , contamination, MSE_SD_Q_b_F_C , MSE_SD_Mean , MSE_SD_Median , MSE_SD_Mode) %>% gather("Method" , "MSE_SD" ,
                       MSE_SD_Q_b_F_C , MSE_SD_Mean , MSE_SD_Median , MSE_SD_Mode ) %>% 
  ggplot(aes(x = as.factor(sampleSize) , y = MSE_SD)) + 
  geom_point( aes(colour = as.factor(contamination))) + 
  facet_wrap(.~Method)




finalResult %>% select( sampleSize , contamination, above05_Q_b_F_C , above05_Mean , above05_Median , above05_Mode) %>% gather("Method" , "PValue_above05" ,
                       above05_Q_b_F_C , above05_Mean , above05_Median , above05_Mode ) %>% 
  ggplot(aes(x = as.factor(sampleSize) , y = PValue_above05)) + 
  geom_point( aes(colour = as.factor(contamination))) + 
  facet_wrap(.~Method)

NA
NA
NA
NA
NA
NA
LS0tDQp0aXRsZTogIk91dGxpZXIgSGFuZGxpbmcgTWV0aG9kcyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyIGltcG9ydExpYnJhcnkgLCBlY2hvPUZBTFNFICwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkocm9idXN0KQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoTUxtZXRyaWNzICkNCmxpYnJhcnkoU2ltRGVzaWduKQ0KbGlicmFyeSh0aWR5cikNCg0KYGBgDQoNCg0KIyBOb3JtYWwgRGlzdHJpYnV0aW9uDQoNCg0KDQoNCiMjIEdlbmVyYXRlIERhdGEgDQoNCg0KYGBge3IgIGVjaG89RkFMU0UgLCB3YXJuaW5nPUZBTFNFfQ0KDQojIENyZWF0ZSB0aGUgZnVuY3Rpb24uDQpnZXRtb2RlIDwtIGZ1bmN0aW9uKGRhdGEpIHsNCiAgDQogICAgeDwtZGF0YQ0KICAgIGxpbS5pbmY9bWluKHgpLTE7IGxpbS5zdXA9bWF4KHgpKzENCg0KICAgIyBoaXN0KHgsZnJlcT1GQUxTRSxicmVha3M9c2VxKGxpbS5pbmYsbGltLnN1cCwwLjIpKQ0KICAgIHM8LWRlbnNpdHkoeCxmcm9tPWxpbS5pbmYsdG89bGltLnN1cCxidz0wLjIpDQogICAgbjwtbGVuZ3RoKHMkeSkNCiAgICB2MTwtcyR5WzE6KG4tMildOw0KICAgIHYyPC1zJHlbMjoobi0xKV07DQogICAgdjM8LXMkeVszOm5dDQogICAgaXg8LTErd2hpY2goKHYxPHYyKSYodjI+djMpKQ0KICAgIA0KICAgICNsaW5lcyhzJHgscyR5LGNvbD0icmVkIikNCiAgICAjcG9pbnRzKHMkeFtpeF0scyR5W2l4XSxjb2w9ImJsdWUiKQ0KICAgIA0KICAgIG1kIDwtIHMkeFt3aGljaChzJHk9PW1heChzJHkpKV0gDQoNCiAgICBtZA0KICB9DQoNCg0KIA0KDQpgYGANCg0KDQpgYGB7ciBGdW5jdGlvblVzZWRUb0dlbmVyYXRlRGF0YVdpdGhfY29udGFtaW5hdGlvbiAsZWNobz1UUlVFICwgd2FybmluZz1GQUxTRX0NCg0KY29udF9ub3JtIDwtIGZ1bmN0aW9uKG4sICMgc2FtcGxlIHNpemUNCiAgICAgICAgICAgICAgICAgICAgICBtdTEgPSAwLCAjIG9ubHkgb25lIG11IHNpbmNlIHRoZSBtZWFuIGlzIHRoZSBzYW1lIGZvciBib3RoIGRpc3RyaWJ1dGlvbnMuIA0KICAgICAgICAgICAgICAgICAgICAgIG11MiA9IDAsICMgb25seSBvbmUgbXUgc2luY2UgdGhlIG1lYW4gaXMgdGhlIHNhbWUgZm9yIGJvdGggZGlzdHJpYnV0aW9ucy4gDQogICAgICAgICAgICAgICAgICAgICAgc2QxID0gMSwgIyBzZCBvZiB0aGUgZmlyc3QgRGlzdHJpYnV0aW9uIA0KICAgICAgICAgICAgICAgICAgICAgIHNkMiA9IDEwMCwgIyBzZCBvZiB0aGUgc2Vjb25kIERpc3RyaWJ1dGlvbg0KICAgICAgICAgICAgICAgICAgICAgIHByb2IgPSAwLjEgIyBjb250YW1pbmF0aW9uIHByb3BvcnRpb24NCil7DQoNCiAgZGF0YSA8LSAgcm5vcm0obiwgbWVhbiA9IG11MSwgc2QgPSBzZDEpDQogIA0KICBsaXN0X2NvbnRhbWluYXRpb24gPC0gIHJub3JtKHJvdW5kKChuKnByb2IpKSwgbWVhbiA9IG11Miwgc2QgPSBzZDIpDQogIA0KICMgc2FtcGxlUG9zIDwtIHNhbXBsZSgxOm4gLCByb3VuZCgobipwcm9iKSkpDQoNCiAgDQogIGRhdGFfY29udGFtaW5hdGlvbiA8LSBjKGRhdGEsIGxpc3RfY29udGFtaW5hdGlvbikgDQogICNkYXRhX2NvbnRhbWluYXRpb25bc2FtcGxlUG9zXSA8LSBsaXN0X2NvbnRhbWluYXRpb25bc2FtcGxlUG9zXQ0KICANCg0KICANCiAgIGxpc3QoDQogICAgIGRhdGEgPSBkYXRhLA0KICAgICBkYXRhX2NvbnRhbWluYXRpb24gPSBkYXRhX2NvbnRhbWluYXRpb24NCiAgICApDQogICANCn0NCg0KYGBgDQoNCg0KDQojIyMgRGF0YSBHZW5lcmF0aW9ucyBGYWN0b3JzDQoNCjEuIHNhbXBsZSBzaXplICAoMzAsNTAsMTAwLDUwMCkgDQoyLiB2YXJpYW5jZSAgKDEpDQozLiBjb250YW1pbmF0aW9uICgxMCUgLCAyMCUgLCAzMCUpDQoNCiANCiR2YXJfe2NvbnRhbWluYXRpb259ID0gIHZhcl97b3JpZ2luYWx9ICogMiQNCmBgYHtyIGdlbmVyYXRlRGF0ZUZ1bmN0aW9uICx3YXJuaW5nPUZBTFNFfQ0KDQpnZW5lcmF0ZURhdGEgPC0gZnVuY3Rpb24oc2FtcGxlU2l6ZSAsIHZhciAsIGNvbnRhbWluYXRpb24gKXsNCiAgDQogIA0KcmVzdWx0cyA9IE5VTEwNCiNjcmVhdGUgMTAwMCByYW5kb20gc2FtcGxlIHdpdGggY29udGFtaW5hdGlvbg0KZm9yKGkgaW4gMToyMDAwKXsNCiAgI2dlbmVyYXRlIGRhdGEgIA0KICBkYXRhX3dpdGhfY29udGFtaW5hdGlvbiA8LSAgY29udF9ub3JtKHNhbXBsZVNpemUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11MSA9IDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdTIgPSA0LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2QxID0gdmFyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZDIgPSB2YXIqMiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvYiA9Y29udGFtaW5hdGlvbikkZGF0YV9jb250YW1pbmF0aW9uDQogIA0KDQogIA0KIA0KICANCiAgI0NvZGUgVG8gSGFuZGxpbmcgb3V0bGllciANCiAgDQoNCiAgI1F1YW50aWxlIGJhc2VkIGZsb29yaW5nIGFuZCBjYXBwaW5nDQogICNJbiB0aGlzIHRlY2huaXF1ZSwgdGhlIG91dGxpZXIgaXMgY2FwcGVkIGF0IGEgY2VydGFpbiB2YWx1ZSBhYm92ZSB0aGUgdXBwZXIgcGVyY2VudGlsZSB2YWx1ZSBvciBmbG9vcmVkICAgYXQgYSBmYWN0b3IgYmVsb3cgdGhlIGxvd2VyIHBlcmNlbnRpbGUgdmFsdWUuDQogIA0KbG93ZXIgID0gcXVhbnRpbGUoZGF0YV93aXRoX2NvbnRhbWluYXRpb24gICwgYyguMDI1KSlbWyIyLjUlIl1dDQp1cHBlciA9IHF1YW50aWxlKGRhdGFfd2l0aF9jb250YW1pbmF0aW9uICAsIGMoLjk3NSkpW1siOTcuNSUiXV0NCg0KDQpvdXRsaWVycyA8LSBib3hwbG90KGRhdGFfd2l0aF9jb250YW1pbmF0aW9uLCBwbG90PUZBTFNFKSRvdXQNCm91dGxpZXJzUG9zIDwtIHdoaWNoKGRhdGFfd2l0aF9jb250YW1pbmF0aW9uICVpbiUgb3V0bGllcnMpDQogDQogIA0KIA0KZGF0YUFmdGVySGFuZGxpbmdfUV9iX0ZfQyA8LSBkYXRhX3dpdGhfY29udGFtaW5hdGlvbg0KZGF0YUFmdGVySGFuZGxpbmdfbWVhbiA8LSBkYXRhX3dpdGhfY29udGFtaW5hdGlvbg0KZGF0YUFmdGVySGFuZGxpbmdfbWVkaWFuIDwtIGRhdGFfd2l0aF9jb250YW1pbmF0aW9uDQpkYXRhQWZ0ZXJIYW5kbGluZ19tb2RlIDwtIGRhdGFfd2l0aF9jb250YW1pbmF0aW9uDQoNCg0KZGF0YUFmdGVySGFuZGxpbmdfUV9iX0ZfQ1tkYXRhQWZ0ZXJIYW5kbGluZ19RX2JfRl9DPGxvd2VyXSA8LSBsb3dlcg0KZGF0YUFmdGVySGFuZGxpbmdfUV9iX0ZfQ1tkYXRhQWZ0ZXJIYW5kbGluZ19RX2JfRl9DPnVwcGVyXSA8LSB1cHBlcg0KeF9iYXJfQWZ0ZXJfSGFuZGxpbmdfUV9iX0ZfQyA8LSBtZWFuKGRhdGFBZnRlckhhbmRsaW5nX1FfYl9GX0MpDQp4X3NkX0FmdGVyX0hhbmRsaW5nX1FfYl9GX0MgPC0gc2QoZGF0YUFmdGVySGFuZGxpbmdfUV9iX0ZfQykNCiMgDQojIA0KbWVhbiA9IG1lYW4oZGF0YUFmdGVySGFuZGxpbmdfbWVhbikNCmRhdGFBZnRlckhhbmRsaW5nX21lYW5bb3V0bGllcnNQb3NdIDwtIG1lYW4NCiMgZGF0YUFmdGVySGFuZGxpbmdfbWVhbltkYXRhQWZ0ZXJIYW5kbGluZ19tZWFuPnVwcGVyXSA8LSBtZWFuDQp4X2Jhcl9BZnRlcl9tZWFuIDwtIG1lYW4oZGF0YUFmdGVySGFuZGxpbmdfbWVhbikNCnhfc2RfQWZ0ZXJfbWVhbiA8LSBzZChkYXRhQWZ0ZXJIYW5kbGluZ19tZWFuKQ0KIyANCiMgDQptZWRpYW4gPSBtZWRpYW4oZGF0YUFmdGVySGFuZGxpbmdfbWVkaWFuKQ0KZGF0YUFmdGVySGFuZGxpbmdfbWVkaWFuW291dGxpZXJzUG9zXSA8LSBtZWRpYW4NCiMgZGF0YUFmdGVySGFuZGxpbmdfbWVkaWFuW2RhdGFBZnRlckhhbmRsaW5nX21lZGlhbj51cHBlcl0gPC0gbWVkaWFuDQp4X2Jhcl9BZnRlcl9tZWRpYW4gPC0gbWVhbihkYXRhQWZ0ZXJIYW5kbGluZ19tZWRpYW4pDQp4X3NkX0FmdGVyX21lZGlhbiA8LSBzZChkYXRhQWZ0ZXJIYW5kbGluZ19tZWRpYW4pDQojIA0KbW9kZSA9IGdldG1vZGUoZGF0YUFmdGVySGFuZGxpbmdfbW9kZSkNCmRhdGFBZnRlckhhbmRsaW5nX21vZGVbb3V0bGllcnNQb3NdIDwtIG1vZGUNCiMgZGF0YUFmdGVySGFuZGxpbmdfbW9kZVtkYXRhQWZ0ZXJIYW5kbGluZ19tb2RlPnVwcGVyXSA8LSBtb2RlDQp4X2Jhcl9BZnRlcl9tb2RlIDwtIG1lYW4oZGF0YUFmdGVySGFuZGxpbmdfbW9kZSkNCnhfc2RfQWZ0ZXJfbW9kZSA8LSBzZChkYXRhQWZ0ZXJIYW5kbGluZ19tb2RlKQ0KDQoNCg0KDQojIE5vcm1hbGl0eSBUZXN0IEFmdGVyIFF1YW50aWxlIGJhc2VkIGZsb29yaW5nIGFuZCBjYXBwaW5nDQpOb3JtYWxpdHlUZXN0X3BfdmFsdWVfQWZ0ZXJfUV9iX0ZfQyA8LSBzaGFwaXJvLnRlc3QoZGF0YUFmdGVySGFuZGxpbmdfUV9iX0ZfQykkcC52YWx1ZQ0KTm9ybWFsaXR5VGVzdF9wX3ZhbHVlX0FmdGVyX21lYW4gPC0gc2hhcGlyby50ZXN0KGRhdGFBZnRlckhhbmRsaW5nX21lYW4pJHAudmFsdWUNCk5vcm1hbGl0eVRlc3RfcF92YWx1ZV9BZnRlcl9tZWRpYW4gPC0gc2hhcGlyby50ZXN0KGRhdGFBZnRlckhhbmRsaW5nX21lZGlhbikkcC52YWx1ZQ0KTm9ybWFsaXR5VGVzdF9wX3ZhbHVlX0FmdGVyX21vZGUgPC0gc2hhcGlyby50ZXN0KGRhdGFBZnRlckhhbmRsaW5nX21vZGUpJHAudmFsdWUNCg0KDQogcmVzdWx0cyA9IHJiaW5kKA0KICAgcmVzdWx0cywNCiAgIGRhdGEuZnJhbWUoDQogICAgIGksDQogICAgIA0KICAgICBOb3JtYWxpdHlUZXN0X3BfdmFsdWVfQWZ0ZXJfUV9iX0ZfQyAsDQogICAgIE5vcm1hbGl0eVRlc3RfcF92YWx1ZV9BZnRlcl9tZWFuICwNCiAgICAgTm9ybWFsaXR5VGVzdF9wX3ZhbHVlX0FmdGVyX21lZGlhbiAsDQogICAgIE5vcm1hbGl0eVRlc3RfcF92YWx1ZV9BZnRlcl9tb2RlICwNCiAgICAgDQogICAgIA0KICAgICB4X2Jhcl9BZnRlcl9IYW5kbGluZ19RX2JfRl9DLA0KICAgICB4X2Jhcl9BZnRlcl9tZWFuLA0KICAgICB4X2Jhcl9BZnRlcl9tZWRpYW4sDQogICAgIHhfYmFyX0FmdGVyX21vZGUgLA0KICAgICANCiAgICAgeF9zZF9BZnRlcl9IYW5kbGluZ19RX2JfRl9DLA0KICAgICB4X3NkX0FmdGVyX21lYW4sDQogICAgIHhfc2RfQWZ0ZXJfbWVkaWFuLA0KICAgICB4X3NkX0FmdGVyX21vZGUNCiAgICAgKSkNCn0NCg0KcmVzdWx0cw0KfQ0KDQoNCg0KDQpgYGANCg0KDQpgYGB7cn0NCg0KIyBkaWZmZXJlbnQgc2FtcGxlIHNpemUgd2l0aCBzZCA9IDEgYW5kIGNvbnRhbWluYXRpb249MTAlDQpkYXRhXzMwXzFfMTAgPC0gZ2VuZXJhdGVEYXRhKDMwICwgMSAsIC4xKQ0KZGF0YV81MF8xXzEwIDwtIGdlbmVyYXRlRGF0YSg1MCAsIDEgLCAuMSkNCmRhdGFfMTAwXzFfMTAgPC0gZ2VuZXJhdGVEYXRhKDEwMCAsIDEgLCAwLjEpDQpkYXRhXzUwMF8xXzEwIDwtIGdlbmVyYXRlRGF0YSg1MDAgLCAxICwgMC4xKQ0KDQojIGRpZmZlcmVudCBzYW1wbGUgc2l6ZSB3aXRoIHNkID0gMSBhbmQgY29udGFtaW5hdGlvbj0yMCUNCmRhdGFfMzBfMV8yMCA8LSBnZW5lcmF0ZURhdGEoMzAgLCAxLDAuMikNCmRhdGFfNTBfMV8yMCA8LSBnZW5lcmF0ZURhdGEoNTAgLCAxLDAuMikNCmRhdGFfMTAwXzFfMjAgPC0gZ2VuZXJhdGVEYXRhKDEwMCwxLDAuMikNCmRhdGFfNTAwXzFfMjAgPC0gZ2VuZXJhdGVEYXRhKDUwMCwxLDAuMikNCg0KDQoNCiMgZGlmZmVyZW50IHNhbXBsZSBzaXplIHdpdGggc2QgPSAxIGFuZCBjb250YW1pbmF0aW9uPTIwJQ0KZGF0YV8zMF8xXzMwIDwtIGdlbmVyYXRlRGF0YSgzMCAsIDEsMC4zKQ0KZGF0YV81MF8xXzMwIDwtIGdlbmVyYXRlRGF0YSg1MCAsIDEsMC4zKQ0KZGF0YV8xMDBfMV8zMCA8LSBnZW5lcmF0ZURhdGEoMTAwLDEsMC4zKQ0KZGF0YV81MDBfMV8zMCA8LSBnZW5lcmF0ZURhdGEoNTAwLDEsMC4zKQ0KDQoNCmBgYA0KDQoNCiANCjEuIHBWYWx1ZSA+IC4wNSBmb3IgQWxsIG1ldGhvZHMgKG1lYW4gLG1lZGlhbiAuLi4uKQ0KMi4gQmlhc2VkIG1lYW4gYmV0d2VlbiB4X0JhckFmdGVyIGFuZCAwICA+Pj4+IHN1bShhYnMoeGJhci0wKSkvMTAwMA0KMy4gQmlhc2VkIHNkID4+PiBzdW0oYWJzKHhzZC0xKSkvMTAwMA0KNC4gTXNlIE1lYW4gID0gc3VtKHhiYXJeMikvMTAwMA0KNS4gTVNFIFNEID0gc3VtKCh4c2QtMSleMikvMTAwMA0KDQoNCmBgYHtyIGNhbGN1bGF0aW9uRnVjdGlvbn0NCg0KYWJvdmVfMDUgPC0gZnVuY3Rpb24ocFZhbHVlTGlzdCl7DQogIHBlcmNlbnQgPC0gbWVhbihwVmFsdWVMaXN0Pi4wNSkNCiAgcmV0dXJuIChwZXJjZW50KQ0KfQ0KDQpkb0NhbGN1bGF0aW9ucyA8LSBmdW5jdGlvbihkYXRhICwgc2FtcGxlU2l6ZSAsIGNvbnRhbWluYXRpb24pIHsNCiAgDQogICBkYXRhICU+JSBzdW1tYXJpemUoDQogIHNhbXBsZVNpemUgPSBzYW1wbGVTaXplICwNCiAgY29udGFtaW5hdGlvbiA9IGNvbnRhbWluYXRpb24sDQogIGJpYXNfWEJhcl9RX2JfRl9DID0gYmlhcyh4X2Jhcl9BZnRlcl9IYW5kbGluZ19RX2JfRl9DICwgMCksDQogIGJpYXNfWEJhcl9NZWFuID0gYmlhcyh4X2Jhcl9BZnRlcl9tZWFuICwwKSwNCiAgYmlhc19YQmFyX01lZGlhbiA9IGJpYXMoeF9iYXJfQWZ0ZXJfbWVkaWFuICwgMCksDQogIGJpYXNfWEJhcl9Nb2RlID0gYmlhcyh4X2Jhcl9BZnRlcl9tb2RlICwwKSAsDQogIA0KICBiaWFzX1NEX1FfYl9GX0MgPSBiaWFzKHhfc2RfQWZ0ZXJfSGFuZGxpbmdfUV9iX0ZfQyAsIDEpLA0KICBiaWFzX1NEX01lYW4gPSBiaWFzKHhfc2RfQWZ0ZXJfbWVhbiAsMSksDQogIGJpYXNfU0RfTWVkaWFuID0gYmlhcyh4X3NkX0FmdGVyX21lZGlhbiAsIDEpLA0KICBiaWFzX1NEX01vZGUgPSBiaWFzKHhfc2RfQWZ0ZXJfbW9kZSAsMSkgLA0KICANCiAgDQogIE1TRV9YQmFyX1FfYl9GX0MgID0gTVNFKHhfYmFyX0FmdGVyX0hhbmRsaW5nX1FfYl9GX0MsIDApLA0KICBNU0VfWEJhcl9NZWFuICA9IE1TRSh4X2Jhcl9BZnRlcl9tZWFuLCAwKSwNCiAgTVNFX1hCYXJfTWVkaWFuICAgPSBNU0UoeF9iYXJfQWZ0ZXJfbWVkaWFuLCAwKSwNCiAgTVNFX1hCYXJfTW9kZSAgPSBNU0UoeF9iYXJfQWZ0ZXJfbW9kZSwgMCksDQogIA0KICBNU0VfU0RfUV9iX0ZfQyAgPSBNU0UoeF9zZF9BZnRlcl9IYW5kbGluZ19RX2JfRl9DLCAxKSwNCiAgTVNFX1NEX01lYW4gID0gTVNFKHhfc2RfQWZ0ZXJfbWVhbiwgMSksDQogIE1TRV9TRF9NZWRpYW4gICA9IE1TRSh4X3NkX0FmdGVyX21lZGlhbiwgMSksDQogIE1TRV9TRF9Nb2RlICA9IE1TRSh4X3NkX0FmdGVyX21vZGUsIDEpLA0KICANCiAgDQogIGFib3ZlMDVfUV9iX0ZfQyA9IGFib3ZlXzA1KE5vcm1hbGl0eVRlc3RfcF92YWx1ZV9BZnRlcl9RX2JfRl9DKSwNCiAgYWJvdmUwNV9NZWFuICA9IGFib3ZlXzA1KE5vcm1hbGl0eVRlc3RfcF92YWx1ZV9BZnRlcl9tZWFuKSwNCiAgYWJvdmUwNV9NZWRpYW4gPSBhYm92ZV8wNShOb3JtYWxpdHlUZXN0X3BfdmFsdWVfQWZ0ZXJfbWVkaWFuKSwNCiAgYWJvdmUwNV9Nb2RlID0gYWJvdmVfMDUoTm9ybWFsaXR5VGVzdF9wX3ZhbHVlX0FmdGVyX21vZGUpDQopIA0KfQ0KDQogDQpgYGANCiANCmBgYHtyIGNhbGxfQ2FsY3VsYXRpb25zRnVuY3Rpb24gICx3YXJuaW5nPUZBTFNFIH0NCg0KZmluYWxSZXN1bHQgPC0gTlVMTCANCg0KZmluYWxSZXN1bHQgPC0gcmJpbmQoDQogIGZpbmFsUmVzdWx0ICwNCiAgICAgICAgICAgICAgICBkb0NhbGN1bGF0aW9ucyhkYXRhXzMwXzFfMTAgLCAzMCwxMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV81MF8xXzEwICwgNTAsMTApLA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfMTAwXzFfMTAgLCAxMDAsMTApLA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfNTAwXzFfMTAgLCA1MDAsMTApLA0KICANCiAgICAgICAgICAgICAgICBkb0NhbGN1bGF0aW9ucyhkYXRhXzMwXzFfMjAgLCAzMCwyMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV81MF8xXzIwICwgNTAsMjApLA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfMTAwXzFfMjAgLCAxMDAsMjApLA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfNTAwXzFfMjAgLCA1MDAsMjApLA0KICAgICANCiAgICAgICAgICAgICAgICBkb0NhbGN1bGF0aW9ucyhkYXRhXzMwXzFfMzAgLCAzMCwzMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV81MF8xXzMwICwgNTAsMzApLA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfMTAwXzFfMzAgLCAxMDAsMzApLA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfNTAwXzFfMzAgLCA1MDAsMzApDQogICAgICAgICAgICAgICAgICAgICApDQoNCg0KDQoNCg0KYGBgDQogDQoNCmBgYHtyICB3YXJuaW5nPUZBTFNFfQ0KDQpmaW5hbFJlc3VsdCAlPiUgc2VsZWN0KHNhbXBsZVNpemUgLCBjb250YW1pbmF0aW9uICwgYmlhc19YQmFyX1FfYl9GX0MgLCBiaWFzX1hCYXJfTWVhbiAsIGJpYXNfWEJhcl9NZWRpYW4gLCBiaWFzX1hCYXJfTW9kZSkNCg0KDQoNCmZpbmFsUmVzdWx0ICU+JSBzZWxlY3Qoc2FtcGxlU2l6ZSAsIGNvbnRhbWluYXRpb24gLCBiaWFzX1NEX1FfYl9GX0MgICwgYmlhc19TRF9NZWFuICwgYmlhc19TRF9NZWRpYW4gLCBiaWFzX1NEX01vZGUpDQoNCg0KZmluYWxSZXN1bHQgJT4lIHNlbGVjdChzYW1wbGVTaXplICwgY29udGFtaW5hdGlvbiAsIE1TRV9YQmFyX1FfYl9GX0MgICwgTVNFX1hCYXJfTWVhbiAsIE1TRV9YQmFyX01lZGlhbiAsIE1TRV9YQmFyX01vZGUpDQogDQoNCmZpbmFsUmVzdWx0ICU+JSBzZWxlY3Qoc2FtcGxlU2l6ZSAsIGNvbnRhbWluYXRpb24gLCBNU0VfU0RfUV9iX0ZfQyAgLCBNU0VfU0RfTWVhbiAsIE1TRV9TRF9NZWRpYW4gLCBNU0VfU0RfTW9kZSkNCg0KDQpmaW5hbFJlc3VsdCAlPiUgc2VsZWN0KHNhbXBsZVNpemUgLCBjb250YW1pbmF0aW9uICxhYm92ZTA1X1FfYl9GX0MgICwgYWJvdmUwNV9NZWFuICwgYWJvdmUwNV9NZWRpYW4gLCBhYm92ZTA1X01vZGUpDQoNCg0KYGBgDQoNCg0KYGBge3IgUmVzdWx0VmlzdWFsaXphdGlvbn0NCg0KI1JlbGF0aW9uIEJldHdlZW4gc2FtcGxlIHNpemUgYW5kIEJpYXNlZCBpbiBYIGJhciBmb3IgZWFjaCBtZXRob2QNCg0KZmluYWxSZXN1bHQgJT4lIHNlbGVjdCggc2FtcGxlU2l6ZSAsIGNvbnRhbWluYXRpb24sIGJpYXNfWEJhcl9RX2JfRl9DICwgYmlhc19YQmFyX01lYW4gLCBiaWFzX1hCYXJfTWVkaWFuICwgYmlhc19YQmFyX01vZGUpICU+JSBnYXRoZXIoIk1ldGhvZCIgLCAiQmlhc2VkX1hfQmFyIiAsDQogICAgICAgICAgICAgICAgICAgICAgIGJpYXNfWEJhcl9RX2JfRl9DICwgYmlhc19YQmFyX01lYW4gLCBiaWFzX1hCYXJfTWVkaWFuICwgYmlhc19YQmFyX01vZGUgKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGFzLmZhY3RvcihzYW1wbGVTaXplKSAsIHkgPSBCaWFzZWRfWF9CYXIpKSArIA0KICBnZW9tX3BvaW50KCBhZXMoY29sb3VyID0gYXMuZmFjdG9yKGNvbnRhbWluYXRpb24pKSkgKyANCiAgZmFjZXRfd3JhcCgufk1ldGhvZCkNCg0KDQoNCmZpbmFsUmVzdWx0ICU+JSBzZWxlY3QoIHNhbXBsZVNpemUgLCBjb250YW1pbmF0aW9uLCBiaWFzX1NEX1FfYl9GX0MgLCBiaWFzX1NEX01lYW4gLCBiaWFzX1NEX01lZGlhbiAsIGJpYXNfU0RfTW9kZSkgJT4lIGdhdGhlcigiTWV0aG9kIiAsICJCaWFzZWRfWF9TRCIgLA0KICAgICAgICAgICAgICAgICAgICAgICBiaWFzX1NEX1FfYl9GX0MgLCBiaWFzX1NEX01lYW4gLCBiaWFzX1NEX01lZGlhbiAsIGJpYXNfU0RfTW9kZSApICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gYXMuZmFjdG9yKHNhbXBsZVNpemUpICwgeSA9IEJpYXNlZF9YX1NEKSkgKyANCiAgZ2VvbV9wb2ludCggYWVzKGNvbG91ciA9IGFzLmZhY3Rvcihjb250YW1pbmF0aW9uKSkpICsgDQogIGZhY2V0X3dyYXAoLn5NZXRob2QpDQoNCg0KDQpmaW5hbFJlc3VsdCAlPiUgc2VsZWN0KCBzYW1wbGVTaXplICwgY29udGFtaW5hdGlvbiwgTVNFX1hCYXJfUV9iX0ZfQyAsIE1TRV9YQmFyX01lYW4gLCBNU0VfWEJhcl9NZWRpYW4gLCBNU0VfWEJhcl9Nb2RlKSAlPiUgZ2F0aGVyKCJNZXRob2QiICwgIk1TRV9YQmFyIiAsDQogICAgICAgICAgICAgICAgICAgICAgIE1TRV9YQmFyX1FfYl9GX0MgLCBNU0VfWEJhcl9NZWFuICwgTVNFX1hCYXJfTWVkaWFuICwgTVNFX1hCYXJfTW9kZSApICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gYXMuZmFjdG9yKHNhbXBsZVNpemUpICwgeSA9IE1TRV9YQmFyKSkgKyANCiAgZ2VvbV9wb2ludCggYWVzKGNvbG91ciA9IGFzLmZhY3Rvcihjb250YW1pbmF0aW9uKSkpICsgDQogIGZhY2V0X3dyYXAoLn5NZXRob2QpDQoNCmZpbmFsUmVzdWx0ICU+JSBzZWxlY3QoIHNhbXBsZVNpemUgLCBjb250YW1pbmF0aW9uLCBNU0VfU0RfUV9iX0ZfQyAsIE1TRV9TRF9NZWFuICwgTVNFX1NEX01lZGlhbiAsIE1TRV9TRF9Nb2RlKSAlPiUgZ2F0aGVyKCJNZXRob2QiICwgIk1TRV9TRCIgLA0KICAgICAgICAgICAgICAgICAgICAgICBNU0VfU0RfUV9iX0ZfQyAsIE1TRV9TRF9NZWFuICwgTVNFX1NEX01lZGlhbiAsIE1TRV9TRF9Nb2RlICkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBhcy5mYWN0b3Ioc2FtcGxlU2l6ZSkgLCB5ID0gTVNFX1NEKSkgKyANCiAgZ2VvbV9wb2ludCggYWVzKGNvbG91ciA9IGFzLmZhY3Rvcihjb250YW1pbmF0aW9uKSkpICsgDQogIGZhY2V0X3dyYXAoLn5NZXRob2QpDQoNCg0KDQpmaW5hbFJlc3VsdCAlPiUgc2VsZWN0KCBzYW1wbGVTaXplICwgY29udGFtaW5hdGlvbiwgYWJvdmUwNV9RX2JfRl9DICwgYWJvdmUwNV9NZWFuICwgYWJvdmUwNV9NZWRpYW4gLCBhYm92ZTA1X01vZGUpICU+JSBnYXRoZXIoIk1ldGhvZCIgLCAiUFZhbHVlX2Fib3ZlMDUiICwNCiAgICAgICAgICAgICAgICAgICAgICAgYWJvdmUwNV9RX2JfRl9DICwgYWJvdmUwNV9NZWFuICwgYWJvdmUwNV9NZWRpYW4gLCBhYm92ZTA1X01vZGUgKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGFzLmZhY3RvcihzYW1wbGVTaXplKSAsIHkgPSBQVmFsdWVfYWJvdmUwNSkpICsgDQogIGdlb21fcG9pbnQoIGFlcyhjb2xvdXIgPSBhcy5mYWN0b3IoY29udGFtaW5hdGlvbikpKSArIA0KICBmYWNldF93cmFwKC5+TWV0aG9kKQ0KDQoNCg0KDQoNCg0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KIA==