Background

What is Nearshoring?

Nearshoring is a business practice where companies choose to relocate their manufacturing or service operations from their home country to a nearby country, looking for one that is in close proximity to their target market. One of the main goals of nearshoring is to optimize production supply chains and minimize costs while maintaining operational efficiency.

The COVID-19 pandemic highlighted companies’ dependence on China and compromised their supply chains. In addition, the trade war between China and the United States, due to the restrictions imposed on imports from that country, intensified these challenges. (El Economista, 2022)

Mexico and its attractiveness for nearshoring is an interesting case of study due its proximity to United States, one of the larger consumer markets in the world. Be.sides, the free trade agreement between Canada, United States and the analized country in this case, not mentioning its human cheap and competitive capital.

What is Predictive Analytics?

Predictive analytics is typically employed to predict what might happen in future events or outcomes. This approach leverages data analysis and machine learning techniques to make predictions based on historical data. The process of predictive analytics involves gathering and preprocessing data, constructing predictive models, and using these models to make forecasts about future occurrences.

One of the most useful predictive analytics tool is regression analysis, which can determine the relationship between two or more independent variables and a dependent variable, which is going to be predicted. The relationships between variables are written as a mathematical equation that can help predict the outcome should one variable change. (Harvard Business School Online, 2021)

Regression Analysis and its relation with nearshoring in Mexico.

Regression analysis can assist in predicting the occurrence of “Nearshoring” for the Mexican case by exploring and analyzing the relationships among independent variables, which encompass the factors that influence nearshoring decisions, and a single dependent variable representing the outcome probability for nearshoring to occur (in this case, Foreign Direct Investment).

To sum up, regression analysis provides a fact-based knowledge to assess the influence of multiple factors on nearshoring in Mexico, enabling the possibility to make predictions and find insights about which conditions or variables are more likely to attract foreign investment and drive nearshoring activities in the country.

Problem Situation

What is the problem situation and how to adress it?

With all the context provided previously, it is time to understand the problem situation. The attractiveness of Mexico for nearshoring is a case that could bring many benefits to the Mexican economy and the country’s growth prospects. As mentioned earlier, Mexico boasts numerous attributes that can attract significant investments from large companies, promising a host of advantages for the nation.

In summary, the problem situation involves the analysis of the provided data to comprehend and assess the relationships among the variables within the dataset (which will be presented and explained below) and Foreign Direct Investment (FDI) flows.

To tackle this problem effectively, it is essential to gain insights through the testing of regression models. These models will guide the country’s efforts toward the targeted development of factors that can attract FDI-driven nearshoring.

Data and Methodology

Exploratory Data Analysis (EDA)

Data Description

Importing DataSet

data <- read.csv("C:\\Users\\danyb\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Docs\\Documentos\\Business Intelligence\\Quinto Semestre\\Introduction to Econometrics\\data_sp.csv")
  • Period: Year
  • IED_Flows: Refers to foreign direct investment flows in Million Dollars. Understand “FDI” as Foreign Direct Investment.
  • Exports: Pertains to non-oil exports, including export values from the Export Manufacturing Industry in Million Dollars.
  • Employment: Represents the percentage of the economically active population that is employed in percentage Rate.
  • Education: Indicates the average years of education of the population in years.
  • Daily_Salary: Refers to the minimum wage in pesos per day.
  • Innovation: Reflects the number of patents filed in Mexico per 100,000 inhabitants.
  • Insecurity_Robbery: Involves violent robberies in various categories, such as households, vehicles, pedestrians, public transportation, banking institutions, businesses, cattle theft, machinery, auto parts, primarily. It is measured in robbery Rate per 100,000 inhabitants
  • Insecurity_Homicide: Represents the number of homicides per 100,000 inhabitants.
  • Exchange_Rate: Indicates the FIX exchange rate between the Mexican peso and the US dollar.
  • Road_Density: Measures the length of paved roads per square kilometer of territorial surface.
  • Population_Density: Reflects the population density, calculated by dividing the total population by the territorial extension of Mexico in square kilometers.
  • CO2_Emissions: Indicates carbon dioxide emissions per capita.
  • GDP_Per_Capita: Refers to the Gross Domestic Product (GDP) divided by the population. Its value is adjusted for the prices of the year 2013.
  • CPI: Price Index | Refers to the National Consumer Price Index (CPI) based on the year 2018, with a base value of 100.
library(dlookr)
library(kableExtra)
library(effects)
library(visdat)
library(foreign)
library(dplyr)        # data manipulation 
library(forcats)      # to work with categorical variables
library(ggplot2)      # data visualization 
library(readr)        # read specific csv files
library(janitor)      # data exploration and cleaning 
library(Hmisc)        # several useful functions for data analysis 
library(psych)        # functions for multivariate analysis 
library(naniar)       # summaries and visualization of missing values NAs
library(dlookr)       # summaries and visualization of missing values NAs
library(corrplot)     # correlation plots
library(jtools)       # presentation of regression analysis 
library(lmtest)       # diagnostic checks - linear regression analysis 
library(car)          # diagnostic checks - linear regression analysis
library(kableExtra)   # HTML table attributes
library(tidyverse)
library(caret)
library(glmnet)
library(Metrics)

Descriptive Data Analysis

Data Structure

str(data)
## 'data.frame':    26 obs. of  16 variables:
##  $ Period             : int  1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 ...
##  $ IED_Flows          : num  12146 8374 13960 18249 30057 ...
##  $ Exports            : num  9088 9875 10990 12483 11300 ...
##  $ Employment         : num  NA NA NA 97.8 97.4 ...
##  $ Education          : num  7.2 7.31 7.43 7.56 7.68 7.8 7.93 8.04 8.14 8.26 ...
##  $ Daily_Salary       : num  24.3 31.9 31.9 35.1 37.6 ...
##  $ Innovation         : num  11.3 11.4 12.5 13.2 13.5 ...
##  $ Insecurity_Robbery : num  267 315 273 217 215 ...
##  $ Insecurity_Homicide: num  14.6 14.3 12.6 10.9 10.2 ...
##  $ Exchange_Rate      : num  8.06 9.94 9.52 9.6 9.17 ...
##  $ Road_Density       : num  0.05 0.05 0.06 0.06 0.06 0.06 0.06 0.06 0.06 0.06 ...
##  $ Population_Density : num  47.4 48.8 49.5 50.6 51.3 ...
##  $ CO2_Emissions      : num  3.68 3.85 3.69 3.87 3.81 3.82 3.95 3.98 4.1 4.19 ...
##  $ GPD_PER_CAPITA     : num  127570 126739 129165 130875 128083 ...
##  $ CPI                : num  33.3 39.5 44.3 48.3 50.4 ...
##  $ Financial_Crisis   : int  0 0 0 0 0 0 0 0 0 0 ...

This data set only contains numeric fields, it could make the analysis more interesting.

Identifying Missing Values (NAs)

sum(is.na(data))
## [1] 12

There are 12 missing values in the data set. It is necessary to identify them.

colSums(is.na(data))
##              Period           IED_Flows             Exports          Employment 
##                   0                   0                   0                   3 
##           Education        Daily_Salary          Innovation  Insecurity_Robbery 
##                   3                   0                   2                   0 
## Insecurity_Homicide       Exchange_Rate        Road_Density  Population_Density 
##                   1                   0                   0                   0 
##       CO2_Emissions      GPD_PER_CAPITA                 CPI    Financial_Crisis 
##                   3                   0                   0                   0
gg_miss_var(data)

It can be observed that the missing values are located in four differente variables: Employment, Education, CO2_Emmissions, Innovation and Insecurity_Homicide. It is time to fix it.

Transforming Variables.

#Replacing Missing Values with Median Values.
data <- data %>%
  mutate_all(~ replace_na(., median(., na.rm = TRUE)))
#Checking the replacing
colSums(is.na(data))
##              Period           IED_Flows             Exports          Employment 
##                   0                   0                   0                   0 
##           Education        Daily_Salary          Innovation  Insecurity_Robbery 
##                   0                   0                   0                   0 
## Insecurity_Homicide       Exchange_Rate        Road_Density  Population_Density 
##                   0                   0                   0                   0 
##       CO2_Emissions      GPD_PER_CAPITA                 CPI    Financial_Crisis 
##                   0                   0                   0                   0

Foreign Direct Investment Flows and Exports are given in million dollars (USD), while the other variables are in Mexican pesos (MXN)

#It would be necessary to change the IED and the Exports to MXN
data$IED_FlowsMXN <- ((data$IED_Flows * data$Exchange_Rate) / data$CPI) * 100
data$Exports_MXN <- ((data$Exports * data$Exchange_Rate) / data$CPI) * 100
#Eliminate the original columns, they will not be necessary.
data <- subset(data, select = -c(IED_Flows, Exports))
#Confirm changes
colnames(data)
##  [1] "Period"              "Employment"          "Education"          
##  [4] "Daily_Salary"        "Innovation"          "Insecurity_Robbery" 
##  [7] "Insecurity_Homicide" "Exchange_Rate"       "Road_Density"       
## [10] "Population_Density"  "CO2_Emissions"       "GPD_PER_CAPITA"     
## [13] "CPI"                 "Financial_Crisis"    "IED_FlowsMXN"       
## [16] "Exports_MXN"

Descriptive Statistics

summary(data)
##      Period       Employment      Education      Daily_Salary   
##  Min.   :1997   Min.   :95.06   Min.   :7.200   Min.   : 24.30  
##  1st Qu.:2003   1st Qu.:96.08   1st Qu.:7.957   1st Qu.: 41.97  
##  Median :2010   Median :96.53   Median :8.460   Median : 54.48  
##  Mean   :2010   Mean   :96.48   Mean   :8.428   Mean   : 65.16  
##  3rd Qu.:2016   3rd Qu.:97.01   3rd Qu.:8.925   3rd Qu.: 72.31  
##  Max.   :2022   Max.   :97.83   Max.   :9.580   Max.   :172.87  
##    Innovation    Insecurity_Robbery Insecurity_Homicide Exchange_Rate  
##  Min.   :11.28   Min.   :120.5      Min.   : 8.04       Min.   : 8.06  
##  1st Qu.:12.60   1st Qu.:148.3      1st Qu.:10.40       1st Qu.:10.75  
##  Median :13.09   Median :181.8      Median :16.93       Median :13.02  
##  Mean   :13.10   Mean   :185.4      Mean   :17.28       Mean   :13.91  
##  3rd Qu.:13.61   3rd Qu.:209.9      3rd Qu.:22.34       3rd Qu.:18.49  
##  Max.   :15.11   Max.   :314.8      Max.   :29.59       Max.   :20.66  
##   Road_Density     Population_Density CO2_Emissions   GPD_PER_CAPITA  
##  Min.   :0.05000   Min.   :47.44      Min.   :3.590   Min.   :126739  
##  1st Qu.:0.06000   1st Qu.:52.77      1st Qu.:3.842   1st Qu.:130964  
##  Median :0.07000   Median :58.09      Median :3.930   Median :136845  
##  Mean   :0.07115   Mean   :57.33      Mean   :3.943   Mean   :138550  
##  3rd Qu.:0.08000   3rd Qu.:61.39      3rd Qu.:4.090   3rd Qu.:146148  
##  Max.   :0.09000   Max.   :65.60      Max.   :4.220   Max.   :153236  
##       CPI         Financial_Crisis   IED_FlowsMXN     Exports_MXN    
##  Min.   : 33.28   Min.   :0.00000   Min.   :210876   Min.   :205483  
##  1st Qu.: 56.15   1st Qu.:0.00000   1st Qu.:368560   1st Qu.:262337  
##  Median : 73.35   Median :0.00000   Median :497054   Median :366294  
##  Mean   : 75.17   Mean   :0.07692   Mean   :493596   Mean   :433856  
##  3rd Qu.: 91.29   3rd Qu.:0.00000   3rd Qu.:578606   3rd Qu.:632356  
##  Max.   :126.48   Max.   :1.00000   Max.   :754438   Max.   :785655

Examining this summary of the data provides insight into the nature of the data values. It can be observed that the independent variables “Exports_MXN” and “Daily_Salary” exhibit outliers due to the significant spread between their minimum and maximum values. Addressing these inconsistencies may be necessary if these variables are to be utilized in the regression models. Additionally, these variables display a substantial disparity between their mean and median values, implying potential unreliability in central tendency measures. #### Measures of dispersion

describe(data)
##                     vars  n      mean        sd    median   trimmed       mad
## Period                 1 26   2009.50      7.65   2009.50   2009.50      9.64
## Employment             2 26     96.48      0.72     96.53     96.48      0.76
## Education              3 26      8.43      0.68      8.46      8.44      0.76
## Daily_Salary           4 26     65.16     35.85     54.48     60.16     22.51
## Innovation             5 26     13.10      1.07     13.09     13.09      0.79
## Insecurity_Robbery     6 26    185.42     47.67    181.83    181.16     47.06
## Insecurity_Homicide    7 26     17.28      7.12     16.93     16.98      9.31
## Exchange_Rate          8 26     13.91      4.15     13.02     13.78      4.25
## Road_Density           9 26      0.07      0.01      0.07      0.07      0.01
## Population_Density    10 26     57.33      5.41     58.09     57.44      6.68
## CO2_Emissions         11 26      3.94      0.18      3.93      3.95      0.17
## GPD_PER_CAPITA        12 26 138550.10   8861.10 136845.30 138255.64  11080.42
## CPI                   13 26     75.17     24.81     73.35     74.45     27.14
## Financial_Crisis      14 26      0.08      0.27      0.00      0.00      0.00
## IED_FlowsMXN          15 26 493596.02 143849.16 497053.70 494270.03 183243.92
## Exports_MXN           16 26 433855.52 195018.66 366293.83 423610.02 184264.93
##                           min       max     range  skew kurtosis       se
## Period                1997.00   2022.00     25.00  0.00    -1.34     1.50
## Employment              95.06     97.83      2.77 -0.17    -0.73     0.14
## Education                7.20      9.58      2.38 -0.12    -1.05     0.13
## Daily_Salary            24.30    172.87    148.57  1.43     1.44     7.03
## Innovation              11.28     15.11      3.83  0.12    -0.70     0.21
## Insecurity_Robbery     120.49    314.78    194.29  0.89     0.30     9.35
## Insecurity_Homicide      8.04     29.59     21.55  0.38    -1.28     1.40
## Exchange_Rate            8.06     20.66     12.60  0.44    -1.39     0.81
## Road_Density             0.05      0.09      0.04  0.19    -1.41     0.00
## Population_Density      47.44     65.60     18.16 -0.19    -1.24     1.06
## CO2_Emissions            3.59      4.22      0.63 -0.11    -0.96     0.04
## GPD_PER_CAPITA      126738.75 153235.73  26496.98  0.28    -1.41  1737.81
## CPI                     33.28    126.48     93.20  0.26    -0.95     4.87
## Financial_Crisis         0.00      1.00      1.00  2.99     7.25     0.05
## IED_FlowsMXN        210875.58 754437.47 543561.89 -0.01    -1.00 28211.14
## Exports_MXN         205482.92 785654.49 580171.58  0.48    -1.40 38246.31

Looking at standard deviation for the variables mentioned above could confirm the spread of the values of this variables.

Data Visualization

ggplot(data, aes(x = Exchange_Rate, y = Exports_MXN)) +
  geom_point() +
  geom_smooth(method="lm",se= FALSE, color="steelblue")
## `geom_smooth()` using formula = 'y ~ x'

  labs(x = "Exchange Rate",
       y = "Exports_MXN",
       title = "Relation between variables") +
  theme_minimal()
## NULL

In this dispersion visualization, it can be observed a positive linear tendency between Exchange Rate and Exports. Taking this into account, it could be mentioned as the higher the exchange rate, the higher the Exports in the country. These types of visualizations are just to explore and understand the data, and this relation may be positive, but it could have variations.

 data %>% mutate(E_intervals=cut(Education,breaks=c(7,7.5,8,8.5,9,9.6))) %>%
  ggplot(aes(x=reorder(E_intervals,IED_FlowsMXN),y=IED_FlowsMXN, fill=E_intervals)) +
  geom_bar(stat="identity") + coord_flip()+
  scale_fill_brewer(palette="PuBu")+
    labs(x="Years of Education", y="Foreign Direct Investment MXN", color="Years of Education") +
  ggtitle("Foreign Direct Investment (MXN) by Years of population Education")

This bar graph shows different intervals of education years, and the value for Foreign Direct Investment flows for each of these intervals. Although it is a positive relation, it could be observed that the higher value of education years is not the higher value for FDI. This information may suggest that relation between these variables could not be totally lineal, and it will help to take decisions of transforming the variable by getting better results in the models.

 data %>% mutate(ER_intervals=cut(Exchange_Rate,breaks=c(8,10,12,14,16,18,20,22))) %>%
  ggplot(aes(x=reorder(ER_intervals,IED_FlowsMXN),y=IED_FlowsMXN, fill=ER_intervals)) +
  geom_bar(stat="identity") + coord_flip()+
  scale_fill_brewer(palette="PuBu")+
  labs(x="Exchange Rate Value", y="FDI (MXN)", color="Exchange Rate") +
  ggtitle("FDI by Exchange Rate Values")

This graph suggests some intriguing insights. The highest Foreign Direct Investment (FDI) values coincide with one of the highest exchange rate values, ranking second only to the top value. Interestingly, the lowest exchange rate values correspond to the second-highest FDI values after the previously mentioned below This observation prompts consideration of potential reasons.

It’s possible that a high exchange rate is more favorable for companies in the export sector, while conversely, it may be less advantageous for those in the import sector. However, it’s essential to note that this hypothesis can’t be definitively confirmed due to the limitations of the dataset. Nevertheless, considering these patterns is valuable for constructing regression models.

ggplot(data, aes(x= Period, y=(IED_FlowsMXN))) +
  geom_line(color="orange", linewidth=1) +
  labs(x= "Year", y= "Flow of Foreign Direct Investment MXN")+
  ggtitle("Flow of Foreign Direct Investment through the years")

This time series graph illustrates the behavior of the dependent variable FDI over time. It can be observed that its highest value was between 2010 and 2015, approximately in 2013. It also shows a decline in 2020, which could be because of pandemic for COVID-19.Despite experiencing this decline it’s also noticeable that it has been steadily rising in the years following that, however, there is not enough data to confidently assert this. In summary, and looking the data for the first years (2000-2010), it could be concluded that the values for FDI have experienced growth through the years.

dev.new()
hist(data$IED_FlowsMXN, prob=TRUE, col='steelblue', main='Histogram with Foreign Direct Investment')
lines(density(data$IED_Flows), col=3, lwd=4)

The histogram for the dependent variable shows the distribution of the values for FDI. It can be observed that the higher frequency is located between 5 and 6 million Mexican pesos (MXN). Despite the fact that the different ranges do not have the same frequency, it is similar.

par(mfrow=c(4, 4))

variables <- c("IED_FlowsMXN", "Period", "Exports_MXN", "Employment", "Education", 
               "Daily_Salary", "Innovation", "Insecurity_Robbery", 
               "Insecurity_Homicide", "Exchange_Rate", "Road_Density", 
               "Population_Density", "CO2_Emissions", "GPD_PER_CAPITA", "CPI")
for (variable in variables) {
  hist(data[[variable]], col="steelblue", main=variable)
}

In this part, an histogram for each variable was plotted, with the intention of observed its values behavior, and evaluate if they could need a transform or a change.

plot_normality(data,IED_FlowsMXN)

plot_normality(data,Period)

plot_normality(data,Exports_MXN)# log

plot_normality(data,Employment) #It could be log

plot_normality(data,Education)

plot_normality(data,Daily_Salary) #It could be log

plot_normality(data,Innovation) #It could be log

plot_normality(data,Insecurity_Robbery)

plot_normality(data,Insecurity_Homicide)

plot_normality(data,Exchange_Rate) #To square

plot_normality(data,Road_Density)

plot_normality(data,Population_Density)

plot_normality(data,CO2_Emissions)

plot_normality(data,GPD_PER_CAPITA)

plot_normality(data,CPI)

after that, normality diagnosis plots were plotted to see the differences between the original distribution frequency of values, and its possible changes.

data1<-data %>% select(Period,IED_FlowsMXN,Employment,Insecurity_Robbery,Insecurity_Homicide,CO2_Emissions,Financial_Crisis,Daily_Salary,Exchange_Rate,Exports_MXN,Road_Density,Population_Density,CPI,Innovation,Education,GPD_PER_CAPITA)
summary(data1)
##      Period      IED_FlowsMXN      Employment    Insecurity_Robbery
##  Min.   :1997   Min.   :210876   Min.   :95.06   Min.   :120.5     
##  1st Qu.:2003   1st Qu.:368560   1st Qu.:96.08   1st Qu.:148.3     
##  Median :2010   Median :497054   Median :96.53   Median :181.8     
##  Mean   :2010   Mean   :493596   Mean   :96.48   Mean   :185.4     
##  3rd Qu.:2016   3rd Qu.:578606   3rd Qu.:97.01   3rd Qu.:209.9     
##  Max.   :2022   Max.   :754438   Max.   :97.83   Max.   :314.8     
##  Insecurity_Homicide CO2_Emissions   Financial_Crisis   Daily_Salary   
##  Min.   : 8.04       Min.   :3.590   Min.   :0.00000   Min.   : 24.30  
##  1st Qu.:10.40       1st Qu.:3.842   1st Qu.:0.00000   1st Qu.: 41.97  
##  Median :16.93       Median :3.930   Median :0.00000   Median : 54.48  
##  Mean   :17.28       Mean   :3.943   Mean   :0.07692   Mean   : 65.16  
##  3rd Qu.:22.34       3rd Qu.:4.090   3rd Qu.:0.00000   3rd Qu.: 72.31  
##  Max.   :29.59       Max.   :4.220   Max.   :1.00000   Max.   :172.87  
##  Exchange_Rate    Exports_MXN      Road_Density     Population_Density
##  Min.   : 8.06   Min.   :205483   Min.   :0.05000   Min.   :47.44     
##  1st Qu.:10.75   1st Qu.:262337   1st Qu.:0.06000   1st Qu.:52.77     
##  Median :13.02   Median :366294   Median :0.07000   Median :58.09     
##  Mean   :13.91   Mean   :433856   Mean   :0.07115   Mean   :57.33     
##  3rd Qu.:18.49   3rd Qu.:632356   3rd Qu.:0.08000   3rd Qu.:61.39     
##  Max.   :20.66   Max.   :785655   Max.   :0.09000   Max.   :65.60     
##       CPI           Innovation      Education     GPD_PER_CAPITA  
##  Min.   : 33.28   Min.   :11.28   Min.   :7.200   Min.   :126739  
##  1st Qu.: 56.15   1st Qu.:12.60   1st Qu.:7.957   1st Qu.:130964  
##  Median : 73.35   Median :13.09   Median :8.460   Median :136845  
##  Mean   : 75.17   Mean   :13.10   Mean   :8.428   Mean   :138550  
##  3rd Qu.: 91.29   3rd Qu.:13.61   3rd Qu.:8.925   3rd Qu.:146148  
##  Max.   :126.48   Max.   :15.11   Max.   :9.580   Max.   :153236
corrplot(cor(data1), type = 'upper', order = 'hclust', addCoef.col = 'black', tl.cex = 0.5, tl.srt = 90, mar = c(0,0,0,0),number.cex=0.8)

Finally, this correlation plot visually represents the relationships between each variable, including the dependent variable, by showing their correlation coefficients. This can assist in identifying whether there is a positive or negative correlation between the variable of interest, ‘IED_FlowsMXN,’ and the independent variables.

Upon examining the plot, we can conclude that the variables with the highest correlation values concerning ‘IED_FlowsMXN’ are “Education”, “Innovation”, “Population_Density”, “Road_Density”, “CPI”, “Exports_MXN”, and “Exchange_Rate”. It’s worth noting that ‘Daily_Salary’ also shows a good (but lower) correlation value. ### Which is the estimation method to be used to estimate the linear regression model? The estimation method is Ordinary Least Squares (OLS).It is a common technique for estimating coefficients. “The OLS method aims to minimize the sum of square differences between the observed and predicted values”. (XLSTAT,2023)

Regression Models

Based on EDA, formulate and describe 3 hypotheses

  • H1: It might be expected a positive relation between Innovation and Foreign Direct Investment flows.

  • H2: It might be expected a positive relation between exchange_rate and Foreign Direct Investment flows.

  • H3: It might be expected a negative relation between financial crisis and Foreign Direct Investment flows.

Extra * H4: It might be expected a positive relation between Exports and Foreign Direct Investment flows.

#Constructing a model with variables mentioned below
model1<-lm(IED_FlowsMXN~ Exports_MXN  + Education + Daily_Salary + Innovation + Exchange_Rate+ Road_Density + Population_Density + CPI, data=data)
summary(model1)
## 
## Call:
## lm(formula = IED_FlowsMXN ~ Exports_MXN + Education + Daily_Salary + 
##     Innovation + Exchange_Rate + Road_Density + Population_Density + 
##     CPI, data = data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -126215  -33514     994   51433  161978 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)  
## (Intercept)         7.859e+05  2.029e+06   0.387   0.7033  
## Exports_MXN        -2.961e-01  5.643e-01  -0.525   0.6065  
## Education           2.579e+04  1.267e+05   0.204   0.8411  
## Daily_Salary       -3.230e+03  5.653e+03  -0.571   0.5753  
## Innovation          5.166e+04  1.942e+04   2.660   0.0165 *
## Exchange_Rate       1.229e+04  2.403e+04   0.512   0.6156  
## Road_Density        7.464e+06  7.199e+06   1.037   0.3144  
## Population_Density -4.406e+04  4.238e+04  -1.040   0.3131  
## CPI                 1.299e+04  1.898e+04   0.684   0.5030  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 84970 on 17 degrees of freedom
## Multiple R-squared:  0.7627, Adjusted R-squared:  0.6511 
## F-statistic: 6.831 on 8 and 17 DF,  p-value: 0.0004584

This model gives information about the relation between independent variables and the dependent variables (FDI). It is relevant to see that just one of the selected variables is statistically significant. To keep concluding, it will be necessary to do check tests for this model:

AIC(model1)
## [1] 672.9421

Value for AIC is to high. It will be compared with AIC for other regression models to see what is the best model, in order to make the prediction more accuracy.

vif(model1)
##        Exports_MXN          Education       Daily_Salary         Innovation 
##          41.929699          25.337811         142.214820           1.502321 
##      Exchange_Rate       Road_Density Population_Density                CPI 
##          34.447391          32.049259         182.117126         767.744362

Variables used in model 1 have very high values of Variance Inflation Factor (VIF), which can be interpreted as multicollinearity between variables in the model. It must show an incorrect prediction.

histogram(model1$residuals)

shapiro.test(model1$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  model1$residuals
## W = 0.96741, p-value = 0.5575

In the histogram below it can be observed that residuals do follow a normal distribution, and it can be confirmed by getting a p-value higher than 0.05 or 5%.

#Estimating a model deleting some variables, and transforming some into "log variables" in order to achieve a normal distribution, and elevating some of these to square, due its possible non-linear relation with dependent variable.
model2<-lm(log(IED_FlowsMXN) ~ log(Exports_MXN)+#Try with log(Exports)
            I(Education^2)+ Daily_Salary + Innovation+
             I(Exchange_Rate^2)+Financial_Crisis, data = data)
summary(model2)
## 
## Call:
## lm(formula = log(IED_FlowsMXN) ~ log(Exports_MXN) + I(Education^2) + 
##     Daily_Salary + Innovation + I(Exchange_Rate^2) + Financial_Crisis, 
##     data = data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.29124 -0.09391  0.01387  0.09175  0.41664 
## 
## Coefficients:
##                     Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        20.313528   5.209725   3.899 0.000965 ***
## log(Exports_MXN)   -0.846135   0.450525  -1.878 0.075802 .  
## I(Education^2)      0.021731   0.008366   2.598 0.017675 *  
## Daily_Salary        0.004002   0.002568   1.558 0.135659    
## Innovation          0.110686   0.040107   2.760 0.012467 *  
## I(Exchange_Rate^2)  0.001912   0.001085   1.763 0.094010 .  
## Financial_Crisis   -0.176630   0.139169  -1.269 0.219704    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1837 on 19 degrees of freedom
## Multiple R-squared:  0.7455, Adjusted R-squared:  0.6651 
## F-statistic: 9.276 on 6 and 19 DF,  p-value: 8.088e-05

With the changes made between model 1 and 2, it can be observed some principal changes in the significance for some variables, but it needs to be tested before getting any prediction.

AIC(model2)
## [1] -6.483815

Value for AIC is low, but this is not the first parameter that must be considering in testing and evaluating regression models. It’s important to see if variables in this model have multicollinearity

vif(model2)
##   log(Exports_MXN)     I(Education^2)       Daily_Salary         Innovation 
##          30.065262           6.660979           6.279672           1.370449 
## I(Exchange_Rate^2)   Financial_Crisis 
##          13.394789           1.059659

It can be observed values above 10 in the variables “Exports_MXN” and “Exchange_Rate”. It suggests that predictions for this model may be incorrect due the multicollinearity in these variables.

histogram(model2$residuals)

shapiro.test(model2$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  model2$residuals
## W = 0.95953, p-value = 0.3824

In the histogram below it can be observed that residuals do follow a normal distribution, and it can be confirmed by getting a p-value higher than 0.05 or 5%. It can be concluded that the problem with the models is multicollinearity A transformation will be needing.

In the plotted histograms for variables before, it could be observed than the values for variable “Exports_MXN” did not have a normal distribution, nor using log transformation.

By analyzing these plots, along with the dispersion plot previously created for this variable, it can be concluded that there are significantly more values on the left side. Therefore, the transformation will involve replacing some of the values in the variable with the median of it, in an attempt to achieve a normal distribution, and eliminate multicollinearity

data1 <- data
data1$Exports_MXN[data1$Exports_MXN == max(data1$Exports_MXN)] <- median(data1$Exports_MXN)
model3<-lm(log(IED_FlowsMXN) ~ log(Exports_MXN)+
            I(Education^2)+ Daily_Salary + Innovation+
             I(Exchange_Rate^2)+Financial_Crisis, data = data1)
summary(model3)
## 
## Call:
## lm(formula = log(IED_FlowsMXN) ~ log(Exports_MXN) + I(Education^2) + 
##     Daily_Salary + Innovation + I(Exchange_Rate^2) + Financial_Crisis, 
##     data = data1)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.33898 -0.06667 -0.00561  0.06077  0.37666 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        13.3081392  3.3649076   3.955 0.000849 ***
## log(Exports_MXN)   -0.2396294  0.2911425  -0.823 0.420681    
## I(Education^2)      0.0149916  0.0085352   1.756 0.095119 .  
## Daily_Salary        0.0016523  0.0023016   0.718 0.481548    
## Innovation          0.1154369  0.0434346   2.658 0.015541 *  
## I(Exchange_Rate^2)  0.0007444  0.0008843   0.842 0.410359    
## Financial_Crisis   -0.1533275  0.1481751  -1.035 0.313767    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1965 on 19 degrees of freedom
## Multiple R-squared:  0.7086, Adjusted R-squared:  0.6166 
## F-statistic: 7.702 on 6 and 19 DF,  p-value: 0.0002676

With the imputation of median values, the variables with high level of significance changes, but it is necessary to test if this model do not present multicollinearity

AIC(model3)
## [1] -2.967193
vif(model3)
##   log(Exports_MXN)     I(Education^2)       Daily_Salary         Innovation 
##           9.884281           6.056573           4.405775           1.403972 
## I(Exchange_Rate^2)   Financial_Crisis 
##           7.778066           1.049286

Although AIC value is higher than the model 2 value, in this model the multicollinearity problem were solved, and predicting with this model may be more accuracy than doing it with the previous model.

histogram(model3$residuals)

shapiro.test(model3$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  model3$residuals
## W = 0.96515, p-value = 0.5029

Histogram shows a bit right-skewed distribution for the residuals of this model, but with shapiro test, due its p-value of 0.50, it can be concluded that statistical inference might be accurate.

Select the regression model that better fits the data. Please consider diagnostic tests in selecting the model.

The model selected based on the diagnostic tests is going to be model 3. It is important to based this decition taking into account that significant variables for model 2 could be incorrectly interpreted because of multicollinearity.

Interpret the regression results of selected regression model.

This model helps to evaluate the hypothesis made before. *For H1: It can be observed that the coefficient for variable “Innovation” is positive, so the hypothesis is accepted.

*For H2: Based on the regression results, it can be concluded that “Exchange_Rate” has a positive relationship with the dependent variable, so the hypothesis is accepted.

*For H3: Model 3 shows that the variable “Financial_Crisis” has a negative coefficient, so it might have a negative relation with the dependent variable, this is why the third hypothesis is accepted.

*For H4: It can be concluded, due the negative coefficient for “Exports_MXN” in model 3, that it has a negative relation with FDI, so the hypothesis is rejected.

• Show the predicted values of the dependent variable (e.g., effects plot)

plot(effect("Innovation",model3))

plot(effect("I(Exchange_Rate^2)",model3))

plot(effect("Financial_Crisis",model3))

plot(effect("Exports_MXN",model3))
## NOTE: Exports_MXN does not appear in the model

It is important to see how the effect plots illustrate the previous results and hypothesis testing obtained with model 3. Innovation and Exchange Rate shows a positive relation with Foreign Direct Investment, while Financial Crisis and Exports(MXN) show a negative relation.

Conclussion

Briefly summarize the main 4-6 insights from your data analysis in Parts 3-4.

  • In order to reduce multicollinearity, when having significant variables in the model, is useful to look for possible transformation that these variables could have.

  • Despite the fact that almost all the variables had high correlation values, not all of these variables where significant for regression model. It shows how correlation and regression is not the same thing.

  • It is interesting to see how exports has a negative impact in FDI, while exchange rate has a positive impact, though these two variables shown a positive relation between both.

  • It will be interesting to observe the behavior of the education variable due the result of the bar graph. This variable was elevated to square, had a positive coefficient, and significance statistic for the regression model.

  • To sum up: Exports: Negative relation, but not significant Education: Positive relation, and significant Daily_Salary: Positive relation, but not significant Innovation: Positive relation, and it is the most significant in the model Exchange_Rate: Positive relation, but not significant Financial_Crisis: Negative relation, but not significant. The impact they will have on dependent variable depends on its coefficient in regression model.

References:

Lázaro, E. (2022, November 10). ¿Qué es el nearshoring? El Economista; El Economista. https://www.eleconomista.com.mx/empresas/Que-es-el-nearshoring-20221108-0093.html

Ordinary Least Squares regression (OLS). (2023). XLSTAT, Your Data Analysis Solution. https://www.xlstat.com/en/solutions/features/ordinary-least-squares-regression-ols

What Is Predictive Analytics? 5 Examples | HBS Online. (2021, October 26). Business Insights Blog. https://online.hbs.edu/blog/post/predictive-analytics

ANEX

Box.test(model3$residuals, type = "Ljung-Box") #Residuales.)
## 
##  Box-Ljung test
## 
## data:  model3$residuals
## X-squared = 1.6638, df = 1, p-value = 0.1971
acf(model3$residuals) #Hacerlo de los residuales.

Seeing these results, it can be concluded that no correlation serial is identified in the model. It is possible to see that all the lines for residuals are inside de significance limits (blue lines).

#x<-model.matrix(log(IED_FlowsMXN) ~ log(Exports_MXN)+
          #  I(Education^2)+ Daily_Salary + Innovation+
           #  I(Exchange_Rate^2)+Financial_Crisis,train.data)[,-1] ### OLS model specification
# x<-model.matrix(Weekly_Sales~.,train.data)[,-1] ### matrix of independent variables X's
#y<-train.data$IED_FlowsMXN ### dependent variable 

# In estimating LASSO regression it is important to define the lambda that minimizes the prediction error rate. 
# Cross-validation ensures that every data / observation from the original dataset (datains) has a chance of appearing in train and test datasets.
# Find the best lambda using cross-validation.
#set.seed(123) 
#cv.lasso<-cv.glmnet(x,y,alpha=1) # alpha = 1 for LASSO

# Display the best lambda value
#cv.lasso$lambda.min                      ### lambda: a numeric value defining the amount of shrinkage. Why min? the higher the value of ?? , the more penalization there is

# Fit the final model on the training data
#lassomodel<-glmnet(x,y,alpha=1,lambda=cv.lasso$lambda.min)

# Display regression coefficients
#coef(lassomodel)

# Make predictions on the test data
#x.test=model.matrix(log(IED_FlowsMXN) ~ log(Exports_MXN)+
 #           I(Education^2)+ Daily_Salary + Innovation+
  #           I(Exchange_Rate^2)+Financial_Crisis,train.data)[,-1] ### OLS model specification
# x.test<-model.matrix(Weekly_Sales~.,test.data)[,-1]
#lassopredictions <- lassomodel %>% predict(x.test) %>% as.vector()

# Model Accuracy
#data.frame(
 # RMSE = RMSE(lassopredictions, test.data$IED_FlowsMXN),
  #Rsquare = R2(lassopredictions, test.data$IED_FlowsMXN))

#It never run

#lasso<-glmnet(scale(x),y,alpha=1)

#plot(lasso,xvar="lambda",label=T)
#DANIEL FARIAS LASO MODEL
LS0tDQp0aXRsZTogIk1leGljbyBhbmQgaXRzIGF0cmFjdGl2ZW5lc3MgZm9yIG5lYXJzaG9yaW5nIg0KYXV0aG9yOiAiRGFuaWVsIEZhcmlhcyINCmRhdGU6ICIyMDIzLTA5LTAxIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCi0tLQ0KIyBCYWNrZ3JvdW5kDQoNCiMjIFdoYXQgaXMgTmVhcnNob3Jpbmc/DQpOZWFyc2hvcmluZyBpcyBhIGJ1c2luZXNzIHByYWN0aWNlIHdoZXJlIGNvbXBhbmllcyBjaG9vc2UgdG8gcmVsb2NhdGUgdGhlaXIgbWFudWZhY3R1cmluZyBvciBzZXJ2aWNlIG9wZXJhdGlvbnMgZnJvbSB0aGVpciBob21lIGNvdW50cnkgdG8gYSBuZWFyYnkgY291bnRyeSwgbG9va2luZyBmb3Igb25lIHRoYXQgaXMgaW4gY2xvc2UgcHJveGltaXR5IHRvIHRoZWlyIHRhcmdldCBtYXJrZXQuIE9uZSBvZiB0aGUgbWFpbiBnb2FscyBvZiBuZWFyc2hvcmluZyBpcyB0byBvcHRpbWl6ZSBwcm9kdWN0aW9uIHN1cHBseSBjaGFpbnMgYW5kIG1pbmltaXplIGNvc3RzIHdoaWxlIG1haW50YWluaW5nIG9wZXJhdGlvbmFsIGVmZmljaWVuY3kuDQoNClRoZSBDT1ZJRC0xOSBwYW5kZW1pYyBoaWdobGlnaHRlZCBjb21wYW5pZXMnIGRlcGVuZGVuY2Ugb24gQ2hpbmEgYW5kIGNvbXByb21pc2VkIHRoZWlyIHN1cHBseSBjaGFpbnMuIEluIGFkZGl0aW9uLCB0aGUgdHJhZGUgd2FyIGJldHdlZW4gQ2hpbmEgYW5kIHRoZSBVbml0ZWQgU3RhdGVzLCBkdWUgdG8gdGhlIHJlc3RyaWN0aW9ucyBpbXBvc2VkIG9uIGltcG9ydHMgZnJvbSB0aGF0IGNvdW50cnksIGludGVuc2lmaWVkIHRoZXNlIGNoYWxsZW5nZXMuICooRWwgRWNvbm9taXN0YSwgMjAyMikqDQoNCk1leGljbyBhbmQgaXRzIGF0dHJhY3RpdmVuZXNzIGZvciBuZWFyc2hvcmluZyBpcyBhbiBpbnRlcmVzdGluZyBjYXNlIG9mIHN0dWR5IGR1ZSBpdHMgcHJveGltaXR5IHRvIFVuaXRlZCBTdGF0ZXMsIG9uZSBvZiB0aGUgbGFyZ2VyIGNvbnN1bWVyIG1hcmtldHMgaW4gdGhlIHdvcmxkLiBCZS5zaWRlcywgdGhlIGZyZWUgdHJhZGUgYWdyZWVtZW50IGJldHdlZW4gQ2FuYWRhLCBVbml0ZWQgU3RhdGVzIGFuZCB0aGUgYW5hbGl6ZWQgY291bnRyeSBpbiB0aGlzIGNhc2UsIG5vdCBtZW50aW9uaW5nIGl0cyBodW1hbiBjaGVhcCBhbmQgY29tcGV0aXRpdmUgY2FwaXRhbC4NCg0KDQojIyBXaGF0IGlzIFByZWRpY3RpdmUgQW5hbHl0aWNzPw0KUHJlZGljdGl2ZSBhbmFseXRpY3MgaXMgdHlwaWNhbGx5IGVtcGxveWVkIHRvIHByZWRpY3Qgd2hhdCBtaWdodCBoYXBwZW4gaW4gZnV0dXJlIGV2ZW50cyBvciBvdXRjb21lcy4gVGhpcyBhcHByb2FjaCBsZXZlcmFnZXMgZGF0YSBhbmFseXNpcyBhbmQgbWFjaGluZSBsZWFybmluZyB0ZWNobmlxdWVzIHRvIG1ha2UgcHJlZGljdGlvbnMgYmFzZWQgb24gaGlzdG9yaWNhbCBkYXRhLiBUaGUgcHJvY2VzcyBvZiBwcmVkaWN0aXZlIGFuYWx5dGljcyBpbnZvbHZlcyBnYXRoZXJpbmcgYW5kIHByZXByb2Nlc3NpbmcgZGF0YSwgY29uc3RydWN0aW5nIHByZWRpY3RpdmUgbW9kZWxzLCBhbmQgdXNpbmcgdGhlc2UgbW9kZWxzIHRvIG1ha2UgZm9yZWNhc3RzIGFib3V0IGZ1dHVyZSBvY2N1cnJlbmNlcy4NCg0KT25lIG9mIHRoZSBtb3N0IHVzZWZ1bCBwcmVkaWN0aXZlIGFuYWx5dGljcyB0b29sIGlzIHJlZ3Jlc3Npb24gYW5hbHlzaXMsIHdoaWNoIGNhbiBkZXRlcm1pbmUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHR3byBvciBtb3JlIGluZGVwZW5kZW50IHZhcmlhYmxlcyBhbmQgYSBkZXBlbmRlbnQgdmFyaWFibGUsIHdoaWNoIGlzIGdvaW5nIHRvIGJlIHByZWRpY3RlZC4gVGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB2YXJpYWJsZXMgYXJlIHdyaXR0ZW4gYXMgYSBtYXRoZW1hdGljYWwgZXF1YXRpb24gdGhhdCBjYW4gaGVscCBwcmVkaWN0IHRoZSBvdXRjb21lIHNob3VsZCBvbmUgdmFyaWFibGUgY2hhbmdlLiAqKEhhcnZhcmQgQnVzaW5lc3MgU2Nob29sIE9ubGluZSwgMjAyMSkqDQoNCg0KIyMgUmVncmVzc2lvbiBBbmFseXNpcyBhbmQgaXRzIHJlbGF0aW9uIHdpdGggbmVhcnNob3JpbmcgaW4gTWV4aWNvLg0KUmVncmVzc2lvbiBhbmFseXNpcyBjYW4gYXNzaXN0IGluIHByZWRpY3RpbmcgdGhlIG9jY3VycmVuY2Ugb2YgIk5lYXJzaG9yaW5nIiBmb3IgdGhlIE1leGljYW4gY2FzZSBieSBleHBsb3JpbmcgYW5kIGFuYWx5emluZyB0aGUgcmVsYXRpb25zaGlwcyBhbW9uZyBpbmRlcGVuZGVudCB2YXJpYWJsZXMsIHdoaWNoIGVuY29tcGFzcyB0aGUgZmFjdG9ycyB0aGF0IGluZmx1ZW5jZSBuZWFyc2hvcmluZyBkZWNpc2lvbnMsIGFuZCBhIHNpbmdsZSBkZXBlbmRlbnQgdmFyaWFibGUgcmVwcmVzZW50aW5nIHRoZSBvdXRjb21lIHByb2JhYmlsaXR5IGZvciBuZWFyc2hvcmluZyB0byBvY2N1ciAoaW4gdGhpcyBjYXNlLCBGb3JlaWduIERpcmVjdCBJbnZlc3RtZW50KS4NCg0KVG8gc3VtIHVwLCByZWdyZXNzaW9uIGFuYWx5c2lzIHByb3ZpZGVzIGEgZmFjdC1iYXNlZCBrbm93bGVkZ2UgdG8gYXNzZXNzIHRoZSBpbmZsdWVuY2Ugb2YgbXVsdGlwbGUgZmFjdG9ycyBvbiBuZWFyc2hvcmluZyBpbiBNZXhpY28sIGVuYWJsaW5nIHRoZSBwb3NzaWJpbGl0eSB0byBtYWtlIHByZWRpY3Rpb25zIGFuZCBmaW5kIGluc2lnaHRzIGFib3V0IHdoaWNoIGNvbmRpdGlvbnMgb3IgdmFyaWFibGVzIGFyZSBtb3JlIGxpa2VseSB0byBhdHRyYWN0IGZvcmVpZ24gaW52ZXN0bWVudCBhbmQgZHJpdmUgbmVhcnNob3JpbmcgYWN0aXZpdGllcyBpbiB0aGUgY291bnRyeS4NCg0KDQojIFByb2JsZW0gU2l0dWF0aW9uDQoNCiMjIFdoYXQgaXMgdGhlIHByb2JsZW0gc2l0dWF0aW9uIGFuZCBob3cgdG8gYWRyZXNzIGl0Pw0KV2l0aCBhbGwgdGhlIGNvbnRleHQgcHJvdmlkZWQgcHJldmlvdXNseSwgaXQgaXMgdGltZSB0byB1bmRlcnN0YW5kIHRoZSBwcm9ibGVtIHNpdHVhdGlvbi4gVGhlIGF0dHJhY3RpdmVuZXNzIG9mIE1leGljbyBmb3IgbmVhcnNob3JpbmcgaXMgYSBjYXNlIHRoYXQgY291bGQgYnJpbmcgbWFueSBiZW5lZml0cyB0byB0aGUgTWV4aWNhbiBlY29ub215IGFuZCB0aGUgY291bnRyeSdzIGdyb3d0aCBwcm9zcGVjdHMuIEFzIG1lbnRpb25lZCBlYXJsaWVyLCBNZXhpY28gYm9hc3RzIG51bWVyb3VzIGF0dHJpYnV0ZXMgdGhhdCBjYW4gYXR0cmFjdCBzaWduaWZpY2FudCBpbnZlc3RtZW50cyBmcm9tIGxhcmdlIGNvbXBhbmllcywgcHJvbWlzaW5nIGEgaG9zdCBvZiBhZHZhbnRhZ2VzIGZvciB0aGUgbmF0aW9uLiANCg0KSW4gc3VtbWFyeSwgdGhlIHByb2JsZW0gc2l0dWF0aW9uIGludm9sdmVzIHRoZSBhbmFseXNpcyBvZiB0aGUgcHJvdmlkZWQgZGF0YSB0byBjb21wcmVoZW5kIGFuZCBhc3Nlc3MgdGhlIHJlbGF0aW9uc2hpcHMgYW1vbmcgdGhlIHZhcmlhYmxlcyB3aXRoaW4gdGhlIGRhdGFzZXQgKHdoaWNoIHdpbGwgYmUgcHJlc2VudGVkIGFuZCBleHBsYWluZWQgYmVsb3cpIGFuZCBGb3JlaWduIERpcmVjdCBJbnZlc3RtZW50IChGREkpIGZsb3dzLg0KDQpUbyB0YWNrbGUgdGhpcyBwcm9ibGVtIGVmZmVjdGl2ZWx5LCBpdCBpcyBlc3NlbnRpYWwgdG8gZ2FpbiBpbnNpZ2h0cyB0aHJvdWdoIHRoZSB0ZXN0aW5nIG9mIHJlZ3Jlc3Npb24gbW9kZWxzLiBUaGVzZSBtb2RlbHMgd2lsbCBndWlkZSB0aGUgY291bnRyeSdzIGVmZm9ydHMgdG93YXJkIHRoZSB0YXJnZXRlZCBkZXZlbG9wbWVudCBvZiBmYWN0b3JzIHRoYXQgY2FuIGF0dHJhY3QgRkRJLWRyaXZlbiBuZWFyc2hvcmluZy4NCg0KDQojIERhdGEgYW5kIE1ldGhvZG9sb2d5DQoNCg0KIyMgRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcyAoRURBKQ0KDQojIyMgRGF0YSBEZXNjcmlwdGlvbg0KIyMjIEltcG9ydGluZyBEYXRhU2V0DQpgYGB7cn0NCmRhdGEgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcZGFueWJcXE9uZURyaXZlIC0gSW5zdGl0dXRvIFRlY25vbG9naWNvIHkgZGUgRXN0dWRpb3MgU3VwZXJpb3JlcyBkZSBNb250ZXJyZXlcXERvY3NcXERvY3VtZW50b3NcXEJ1c2luZXNzIEludGVsbGlnZW5jZVxcUXVpbnRvIFNlbWVzdHJlXFxJbnRyb2R1Y3Rpb24gdG8gRWNvbm9tZXRyaWNzXFxkYXRhX3NwLmNzdiIpDQpgYGANCg0KKiAqKlBlcmlvZDoqKiBZZWFyDQoqICoqSUVEX0Zsb3dzOioqIFJlZmVycyB0byBmb3JlaWduIGRpcmVjdCBpbnZlc3RtZW50IGZsb3dzIGluIE1pbGxpb24gRG9sbGFycy4gVW5kZXJzdGFuZCAiRkRJIiBhcyBGb3JlaWduIERpcmVjdCBJbnZlc3RtZW50Lg0KKiAqKkV4cG9ydHM6KiogUGVydGFpbnMgdG8gbm9uLW9pbCBleHBvcnRzLCBpbmNsdWRpbmcgZXhwb3J0IHZhbHVlcyBmcm9tIHRoZSBFeHBvcnQgTWFudWZhY3R1cmluZyBJbmR1c3RyeSBpbiBNaWxsaW9uIERvbGxhcnMuDQoqICoqRW1wbG95bWVudDoqKiBSZXByZXNlbnRzIHRoZSBwZXJjZW50YWdlIG9mIHRoZSBlY29ub21pY2FsbHkgYWN0aXZlIHBvcHVsYXRpb24gdGhhdCBpcyBlbXBsb3llZCBpbiBwZXJjZW50YWdlIFJhdGUuDQoqICoqRWR1Y2F0aW9uOioqIEluZGljYXRlcyB0aGUgYXZlcmFnZSB5ZWFycyBvZiBlZHVjYXRpb24gb2YgdGhlIHBvcHVsYXRpb24gaW4geWVhcnMuDQoqICoqRGFpbHlfU2FsYXJ5OioqIFJlZmVycyB0byB0aGUgbWluaW11bSB3YWdlIGluIHBlc29zIHBlciBkYXkuDQoqICoqSW5ub3ZhdGlvbjoqKiBSZWZsZWN0cyB0aGUgbnVtYmVyIG9mIHBhdGVudHMgZmlsZWQgaW4gTWV4aWNvIHBlciAxMDAsMDAwIGluaGFiaXRhbnRzLg0KKiAqKkluc2VjdXJpdHlfUm9iYmVyeToqKiBJbnZvbHZlcyB2aW9sZW50IHJvYmJlcmllcyBpbiB2YXJpb3VzIGNhdGVnb3JpZXMsIHN1Y2ggYXMgaG91c2Vob2xkcywgdmVoaWNsZXMsIHBlZGVzdHJpYW5zLCBwdWJsaWMgdHJhbnNwb3J0YXRpb24sIGJhbmtpbmcgaW5zdGl0dXRpb25zLCBidXNpbmVzc2VzLCBjYXR0bGUgdGhlZnQsIG1hY2hpbmVyeSwgYXV0byBwYXJ0cywgcHJpbWFyaWx5LiBJdCBpcyBtZWFzdXJlZCBpbiByb2JiZXJ5IFJhdGUgcGVyIDEwMCwwMDAgaW5oYWJpdGFudHMNCiogKipJbnNlY3VyaXR5X0hvbWljaWRlOioqIFJlcHJlc2VudHMgdGhlIG51bWJlciBvZiBob21pY2lkZXMgcGVyIDEwMCwwMDAgaW5oYWJpdGFudHMuDQoqICoqRXhjaGFuZ2VfUmF0ZToqKiBJbmRpY2F0ZXMgdGhlIEZJWCBleGNoYW5nZSByYXRlIGJldHdlZW4gdGhlIE1leGljYW4gcGVzbyBhbmQgdGhlIFVTIGRvbGxhci4NCiogKipSb2FkX0RlbnNpdHk6KiogTWVhc3VyZXMgdGhlIGxlbmd0aCBvZiBwYXZlZCByb2FkcyBwZXIgc3F1YXJlIGtpbG9tZXRlciBvZiB0ZXJyaXRvcmlhbCBzdXJmYWNlLg0KKiAqKlBvcHVsYXRpb25fRGVuc2l0eToqKiBSZWZsZWN0cyB0aGUgcG9wdWxhdGlvbiBkZW5zaXR5LCBjYWxjdWxhdGVkIGJ5IGRpdmlkaW5nIHRoZSB0b3RhbCBwb3B1bGF0aW9uIGJ5IHRoZSB0ZXJyaXRvcmlhbCBleHRlbnNpb24gb2YgTWV4aWNvIGluIHNxdWFyZSBraWxvbWV0ZXJzLg0KKiAqKkNPMl9FbWlzc2lvbnM6KiogSW5kaWNhdGVzIGNhcmJvbiBkaW94aWRlIGVtaXNzaW9ucyBwZXIgY2FwaXRhLg0KKiAqKkdEUF9QZXJfQ2FwaXRhOioqIFJlZmVycyB0byB0aGUgR3Jvc3MgRG9tZXN0aWMgUHJvZHVjdCAoR0RQKSBkaXZpZGVkIGJ5IHRoZSBwb3B1bGF0aW9uLiBJdHMgdmFsdWUgaXMgYWRqdXN0ZWQgZm9yIHRoZSBwcmljZXMgb2YgdGhlIHllYXIgMjAxMy4NCiogKipDUEk6KiogUHJpY2UgSW5kZXggfCBSZWZlcnMgdG8gdGhlIE5hdGlvbmFsIENvbnN1bWVyIFByaWNlIEluZGV4IChDUEkpIGJhc2VkIG9uIHRoZSB5ZWFyIDIwMTgsIHdpdGggYSBiYXNlIHZhbHVlIG9mIDEwMC4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcGFnZWQucHJpbnQ9RkFMU0V9DQpsaWJyYXJ5KGRsb29rcikNCmxpYnJhcnkoa2FibGVFeHRyYSkNCmxpYnJhcnkoZWZmZWN0cykNCmxpYnJhcnkodmlzZGF0KQ0KbGlicmFyeShmb3JlaWduKQ0KbGlicmFyeShkcGx5cikgICAgICAgICMgZGF0YSBtYW5pcHVsYXRpb24gDQpsaWJyYXJ5KGZvcmNhdHMpICAgICAgIyB0byB3b3JrIHdpdGggY2F0ZWdvcmljYWwgdmFyaWFibGVzDQpsaWJyYXJ5KGdncGxvdDIpICAgICAgIyBkYXRhIHZpc3VhbGl6YXRpb24gDQpsaWJyYXJ5KHJlYWRyKSAgICAgICAgIyByZWFkIHNwZWNpZmljIGNzdiBmaWxlcw0KbGlicmFyeShqYW5pdG9yKSAgICAgICMgZGF0YSBleHBsb3JhdGlvbiBhbmQgY2xlYW5pbmcgDQpsaWJyYXJ5KEhtaXNjKSAgICAgICAgIyBzZXZlcmFsIHVzZWZ1bCBmdW5jdGlvbnMgZm9yIGRhdGEgYW5hbHlzaXMgDQpsaWJyYXJ5KHBzeWNoKSAgICAgICAgIyBmdW5jdGlvbnMgZm9yIG11bHRpdmFyaWF0ZSBhbmFseXNpcyANCmxpYnJhcnkobmFuaWFyKSAgICAgICAjIHN1bW1hcmllcyBhbmQgdmlzdWFsaXphdGlvbiBvZiBtaXNzaW5nIHZhbHVlcyBOQXMNCmxpYnJhcnkoZGxvb2tyKSAgICAgICAjIHN1bW1hcmllcyBhbmQgdmlzdWFsaXphdGlvbiBvZiBtaXNzaW5nIHZhbHVlcyBOQXMNCmxpYnJhcnkoY29ycnBsb3QpICAgICAjIGNvcnJlbGF0aW9uIHBsb3RzDQpsaWJyYXJ5KGp0b29scykgICAgICAgIyBwcmVzZW50YXRpb24gb2YgcmVncmVzc2lvbiBhbmFseXNpcyANCmxpYnJhcnkobG10ZXN0KSAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMgDQpsaWJyYXJ5KGNhcikgICAgICAgICAgIyBkaWFnbm9zdGljIGNoZWNrcyAtIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzDQpsaWJyYXJ5KGthYmxlRXh0cmEpICAgIyBIVE1MIHRhYmxlIGF0dHJpYnV0ZXMNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShjYXJldCkNCmxpYnJhcnkoZ2xtbmV0KQ0KbGlicmFyeShNZXRyaWNzKQ0KYGBgDQoNCiMjIyBEZXNjcmlwdGl2ZSBEYXRhIEFuYWx5c2lzDQojIyMjIERhdGEgU3RydWN0dXJlDQpgYGB7cn0NCnN0cihkYXRhKQ0KYGBgDQpUaGlzIGRhdGEgc2V0IG9ubHkgY29udGFpbnMgbnVtZXJpYyBmaWVsZHMsIGl0IGNvdWxkIG1ha2UgdGhlIGFuYWx5c2lzIG1vcmUgaW50ZXJlc3RpbmcuDQoNCiMjIyMgSWRlbnRpZnlpbmcgTWlzc2luZyBWYWx1ZXMgKE5BcykNCmBgYHtyfQ0Kc3VtKGlzLm5hKGRhdGEpKQ0KYGBgDQpUaGVyZSBhcmUgMTIgbWlzc2luZyB2YWx1ZXMgaW4gdGhlIGRhdGEgc2V0LiBJdCBpcyBuZWNlc3NhcnkgdG8gaWRlbnRpZnkgdGhlbS4NCg0KYGBge3J9DQpjb2xTdW1zKGlzLm5hKGRhdGEpKQ0KYGBgDQpgYGB7cn0NCmdnX21pc3NfdmFyKGRhdGEpDQpgYGANCg0KSXQgY2FuIGJlIG9ic2VydmVkIHRoYXQgdGhlIG1pc3NpbmcgdmFsdWVzIGFyZSBsb2NhdGVkIGluIGZvdXIgZGlmZmVyZW50ZSB2YXJpYWJsZXM6IEVtcGxveW1lbnQsIEVkdWNhdGlvbiwgQ08yX0VtbWlzc2lvbnMsIElubm92YXRpb24gYW5kIEluc2VjdXJpdHlfSG9taWNpZGUuIEl0IGlzIHRpbWUgdG8gZml4IGl0Lg0KDQojIyMjIFRyYW5zZm9ybWluZyBWYXJpYWJsZXMuDQpgYGB7cn0NCiNSZXBsYWNpbmcgTWlzc2luZyBWYWx1ZXMgd2l0aCBNZWRpYW4gVmFsdWVzLg0KZGF0YSA8LSBkYXRhICU+JQ0KICBtdXRhdGVfYWxsKH4gcmVwbGFjZV9uYSguLCBtZWRpYW4oLiwgbmEucm0gPSBUUlVFKSkpDQojQ2hlY2tpbmcgdGhlIHJlcGxhY2luZw0KY29sU3Vtcyhpcy5uYShkYXRhKSkNCmBgYA0KRm9yZWlnbiBEaXJlY3QgSW52ZXN0bWVudCBGbG93cyBhbmQgRXhwb3J0cyBhcmUgZ2l2ZW4gaW4gbWlsbGlvbiBkb2xsYXJzIChVU0QpLCB3aGlsZSB0aGUgb3RoZXIgdmFyaWFibGVzIGFyZSBpbiBNZXhpY2FuIHBlc29zIChNWE4pDQoNCmBgYHtyfQ0KI0l0IHdvdWxkIGJlIG5lY2Vzc2FyeSB0byBjaGFuZ2UgdGhlIElFRCBhbmQgdGhlIEV4cG9ydHMgdG8gTVhODQpkYXRhJElFRF9GbG93c01YTiA8LSAoKGRhdGEkSUVEX0Zsb3dzICogZGF0YSRFeGNoYW5nZV9SYXRlKSAvIGRhdGEkQ1BJKSAqIDEwMA0KZGF0YSRFeHBvcnRzX01YTiA8LSAoKGRhdGEkRXhwb3J0cyAqIGRhdGEkRXhjaGFuZ2VfUmF0ZSkgLyBkYXRhJENQSSkgKiAxMDANCiNFbGltaW5hdGUgdGhlIG9yaWdpbmFsIGNvbHVtbnMsIHRoZXkgd2lsbCBub3QgYmUgbmVjZXNzYXJ5Lg0KZGF0YSA8LSBzdWJzZXQoZGF0YSwgc2VsZWN0ID0gLWMoSUVEX0Zsb3dzLCBFeHBvcnRzKSkNCiNDb25maXJtIGNoYW5nZXMNCmNvbG5hbWVzKGRhdGEpDQpgYGANCg0KIyMjIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpgYGB7cn0NCnN1bW1hcnkoZGF0YSkNCmBgYA0KDQpFeGFtaW5pbmcgdGhpcyBzdW1tYXJ5IG9mIHRoZSBkYXRhIHByb3ZpZGVzIGluc2lnaHQgaW50byB0aGUgbmF0dXJlIG9mIHRoZSBkYXRhIHZhbHVlcy4gSXQgY2FuIGJlIG9ic2VydmVkIHRoYXQgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlcyAiRXhwb3J0c19NWE4iIGFuZCAiRGFpbHlfU2FsYXJ5IiBleGhpYml0IG91dGxpZXJzIGR1ZSB0byB0aGUgc2lnbmlmaWNhbnQgc3ByZWFkIGJldHdlZW4gdGhlaXIgbWluaW11bSBhbmQgbWF4aW11bSB2YWx1ZXMuIEFkZHJlc3NpbmcgdGhlc2UgaW5jb25zaXN0ZW5jaWVzIG1heSBiZSBuZWNlc3NhcnkgaWYgdGhlc2UgdmFyaWFibGVzIGFyZSB0byBiZSB1dGlsaXplZCBpbiB0aGUgcmVncmVzc2lvbiBtb2RlbHMuIEFkZGl0aW9uYWxseSwgdGhlc2UgdmFyaWFibGVzIGRpc3BsYXkgYSBzdWJzdGFudGlhbCBkaXNwYXJpdHkgYmV0d2VlbiB0aGVpciBtZWFuIGFuZCBtZWRpYW4gdmFsdWVzLCBpbXBseWluZyBwb3RlbnRpYWwgdW5yZWxpYWJpbGl0eSBpbiBjZW50cmFsIHRlbmRlbmN5IG1lYXN1cmVzLg0KIyMjIyBNZWFzdXJlcyBvZiBkaXNwZXJzaW9uDQoNCmBgYHtyfQ0KZGVzY3JpYmUoZGF0YSkNCmBgYA0KTG9va2luZyBhdCBzdGFuZGFyZCBkZXZpYXRpb24gZm9yIHRoZSB2YXJpYWJsZXMgbWVudGlvbmVkIGFib3ZlIGNvdWxkIGNvbmZpcm0gdGhlIHNwcmVhZCBvZiB0aGUgdmFsdWVzIG9mIHRoaXMgdmFyaWFibGVzLg0KDQojIyMjIERhdGEgVmlzdWFsaXphdGlvbg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSwgYWVzKHggPSBFeGNoYW5nZV9SYXRlLCB5ID0gRXhwb3J0c19NWE4pKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLHNlPSBGQUxTRSwgY29sb3I9InN0ZWVsYmx1ZSIpDQogIGxhYnMoeCA9ICJFeGNoYW5nZSBSYXRlIiwNCiAgICAgICB5ID0gIkV4cG9ydHNfTVhOIiwNCiAgICAgICB0aXRsZSA9ICJSZWxhdGlvbiBiZXR3ZWVuIHZhcmlhYmxlcyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KSW4gdGhpcyBkaXNwZXJzaW9uIHZpc3VhbGl6YXRpb24sIGl0IGNhbiBiZSBvYnNlcnZlZCBhIHBvc2l0aXZlIGxpbmVhciB0ZW5kZW5jeSBiZXR3ZWVuIEV4Y2hhbmdlIFJhdGUgYW5kIEV4cG9ydHMuIFRha2luZyB0aGlzIGludG8gYWNjb3VudCwgaXQgY291bGQgYmUgbWVudGlvbmVkIGFzIHRoZSBoaWdoZXIgdGhlIGV4Y2hhbmdlIHJhdGUsIHRoZSBoaWdoZXIgdGhlIEV4cG9ydHMgaW4gdGhlIGNvdW50cnkuIFRoZXNlIHR5cGVzIG9mIHZpc3VhbGl6YXRpb25zIGFyZSBqdXN0IHRvIGV4cGxvcmUgYW5kIHVuZGVyc3RhbmQgdGhlIGRhdGEsIGFuZCB0aGlzIHJlbGF0aW9uIG1heSBiZSBwb3NpdGl2ZSwgYnV0IGl0IGNvdWxkIGhhdmUgdmFyaWF0aW9ucy4NCmBgYHtyfQ0KIGRhdGEgJT4lIG11dGF0ZShFX2ludGVydmFscz1jdXQoRWR1Y2F0aW9uLGJyZWFrcz1jKDcsNy41LDgsOC41LDksOS42KSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHg9cmVvcmRlcihFX2ludGVydmFscyxJRURfRmxvd3NNWE4pLHk9SUVEX0Zsb3dzTVhOLCBmaWxsPUVfaW50ZXJ2YWxzKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsgY29vcmRfZmxpcCgpKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJQdUJ1IikrDQogICAgbGFicyh4PSJZZWFycyBvZiBFZHVjYXRpb24iLCB5PSJGb3JlaWduIERpcmVjdCBJbnZlc3RtZW50IE1YTiIsIGNvbG9yPSJZZWFycyBvZiBFZHVjYXRpb24iKSArDQogIGdndGl0bGUoIkZvcmVpZ24gRGlyZWN0IEludmVzdG1lbnQgKE1YTikgYnkgWWVhcnMgb2YgcG9wdWxhdGlvbiBFZHVjYXRpb24iKQ0KYGBgDQoNClRoaXMgYmFyIGdyYXBoIHNob3dzIGRpZmZlcmVudCBpbnRlcnZhbHMgb2YgZWR1Y2F0aW9uIHllYXJzLCBhbmQgdGhlIHZhbHVlIGZvciBGb3JlaWduIERpcmVjdCBJbnZlc3RtZW50IGZsb3dzIGZvciBlYWNoIG9mIHRoZXNlIGludGVydmFscy4gQWx0aG91Z2ggaXQgaXMgYSBwb3NpdGl2ZSByZWxhdGlvbiwgaXQgY291bGQgYmUgb2JzZXJ2ZWQgdGhhdCB0aGUgaGlnaGVyIHZhbHVlIG9mIGVkdWNhdGlvbiB5ZWFycyBpcyBub3QgdGhlIGhpZ2hlciB2YWx1ZSBmb3IgRkRJLiBUaGlzIGluZm9ybWF0aW9uIG1heSBzdWdnZXN0IHRoYXQgcmVsYXRpb24gYmV0d2VlbiB0aGVzZSB2YXJpYWJsZXMgY291bGQgbm90IGJlIHRvdGFsbHkgbGluZWFsLCBhbmQgaXQgd2lsbCBoZWxwIHRvIHRha2UgZGVjaXNpb25zIG9mIHRyYW5zZm9ybWluZyB0aGUgdmFyaWFibGUgYnkgZ2V0dGluZyBiZXR0ZXIgcmVzdWx0cyBpbiB0aGUgbW9kZWxzLg0KDQpgYGB7cn0NCiBkYXRhICU+JSBtdXRhdGUoRVJfaW50ZXJ2YWxzPWN1dChFeGNoYW5nZV9SYXRlLGJyZWFrcz1jKDgsMTAsMTIsMTQsMTYsMTgsMjAsMjIpKSkgJT4lDQogIGdncGxvdChhZXMoeD1yZW9yZGVyKEVSX2ludGVydmFscyxJRURfRmxvd3NNWE4pLHk9SUVEX0Zsb3dzTVhOLCBmaWxsPUVSX2ludGVydmFscykpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArIGNvb3JkX2ZsaXAoKSsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZT0iUHVCdSIpKw0KICBsYWJzKHg9IkV4Y2hhbmdlIFJhdGUgVmFsdWUiLCB5PSJGREkgKE1YTikiLCBjb2xvcj0iRXhjaGFuZ2UgUmF0ZSIpICsNCiAgZ2d0aXRsZSgiRkRJIGJ5IEV4Y2hhbmdlIFJhdGUgVmFsdWVzIikNCmBgYA0KDQpUaGlzIGdyYXBoIHN1Z2dlc3RzIHNvbWUgaW50cmlndWluZyBpbnNpZ2h0cy4gVGhlIGhpZ2hlc3QgRm9yZWlnbiBEaXJlY3QgSW52ZXN0bWVudCAoRkRJKSB2YWx1ZXMgY29pbmNpZGUgd2l0aCBvbmUgb2YgdGhlIGhpZ2hlc3QgZXhjaGFuZ2UgcmF0ZSB2YWx1ZXMsIHJhbmtpbmcgc2Vjb25kIG9ubHkgdG8gdGhlIHRvcCB2YWx1ZS4gSW50ZXJlc3RpbmdseSwgdGhlIGxvd2VzdCBleGNoYW5nZSByYXRlIHZhbHVlcyBjb3JyZXNwb25kIHRvIHRoZSBzZWNvbmQtaGlnaGVzdCBGREkgdmFsdWVzIGFmdGVyIHRoZSBwcmV2aW91c2x5IG1lbnRpb25lZCBiZWxvdyBUaGlzIG9ic2VydmF0aW9uIHByb21wdHMgY29uc2lkZXJhdGlvbiBvZiBwb3RlbnRpYWwgcmVhc29ucy4NCg0KDQpJdCdzIHBvc3NpYmxlIHRoYXQgYSBoaWdoIGV4Y2hhbmdlIHJhdGUgaXMgbW9yZSBmYXZvcmFibGUgZm9yIGNvbXBhbmllcyBpbiB0aGUgZXhwb3J0IHNlY3Rvciwgd2hpbGUgY29udmVyc2VseSwgaXQgbWF5IGJlIGxlc3MgYWR2YW50YWdlb3VzIGZvciB0aG9zZSBpbiB0aGUgaW1wb3J0IHNlY3Rvci4gSG93ZXZlciwgaXQncyBlc3NlbnRpYWwgdG8gbm90ZSB0aGF0IHRoaXMgaHlwb3RoZXNpcyBjYW4ndCBiZSBkZWZpbml0aXZlbHkgY29uZmlybWVkIGR1ZSB0byB0aGUgbGltaXRhdGlvbnMgb2YgdGhlIGRhdGFzZXQuIE5ldmVydGhlbGVzcywgY29uc2lkZXJpbmcgdGhlc2UgcGF0dGVybnMgaXMgdmFsdWFibGUgZm9yIGNvbnN0cnVjdGluZyByZWdyZXNzaW9uIG1vZGVscy4NCg0KDQpgYGB7cn0NCmdncGxvdChkYXRhLCBhZXMoeD0gUGVyaW9kLCB5PShJRURfRmxvd3NNWE4pKSkgKw0KICBnZW9tX2xpbmUoY29sb3I9Im9yYW5nZSIsIGxpbmV3aWR0aD0xKSArDQogIGxhYnMoeD0gIlllYXIiLCB5PSAiRmxvdyBvZiBGb3JlaWduIERpcmVjdCBJbnZlc3RtZW50IE1YTiIpKw0KICBnZ3RpdGxlKCJGbG93IG9mIEZvcmVpZ24gRGlyZWN0IEludmVzdG1lbnQgdGhyb3VnaCB0aGUgeWVhcnMiKQ0KYGBgDQoNClRoaXMgdGltZSBzZXJpZXMgZ3JhcGggaWxsdXN0cmF0ZXMgdGhlIGJlaGF2aW9yIG9mIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgRkRJIG92ZXIgdGltZS4gSXQgY2FuIGJlIG9ic2VydmVkIHRoYXQgaXRzIGhpZ2hlc3QgdmFsdWUgd2FzIGJldHdlZW4gMjAxMCBhbmQgMjAxNSwgYXBwcm94aW1hdGVseSBpbiAyMDEzLiBJdCBhbHNvIHNob3dzIGEgZGVjbGluZSBpbiAyMDIwLCB3aGljaCBjb3VsZCBiZSBiZWNhdXNlIG9mIHBhbmRlbWljIGZvciBDT1ZJRC0xOS5EZXNwaXRlIGV4cGVyaWVuY2luZyB0aGlzIGRlY2xpbmUgaXQncyBhbHNvIG5vdGljZWFibGUgdGhhdCBpdCBoYXMgYmVlbiBzdGVhZGlseSByaXNpbmcgaW4gdGhlIHllYXJzIGZvbGxvd2luZyB0aGF0LCBob3dldmVyLCB0aGVyZSBpcyBub3QgZW5vdWdoIGRhdGEgdG8gY29uZmlkZW50bHkgYXNzZXJ0IHRoaXMuICBJbiBzdW1tYXJ5LCBhbmQgbG9va2luZyB0aGUgZGF0YSBmb3IgdGhlIGZpcnN0IHllYXJzICgyMDAwLTIwMTApLCBpdCBjb3VsZCBiZSBjb25jbHVkZWQgdGhhdCB0aGUgdmFsdWVzIGZvciBGREkgaGF2ZSBleHBlcmllbmNlZCBncm93dGggdGhyb3VnaCB0aGUgeWVhcnMuDQoNCg0KYGBge3J9DQpkZXYubmV3KCkNCmhpc3QoZGF0YSRJRURfRmxvd3NNWE4sIHByb2I9VFJVRSwgY29sPSdzdGVlbGJsdWUnLCBtYWluPSdIaXN0b2dyYW0gd2l0aCBGb3JlaWduIERpcmVjdCBJbnZlc3RtZW50JykNCmxpbmVzKGRlbnNpdHkoZGF0YSRJRURfRmxvd3MpLCBjb2w9MywgbHdkPTQpDQpgYGANCg0KVGhlIGhpc3RvZ3JhbSBmb3IgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBzaG93cyB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSB2YWx1ZXMgZm9yIEZESS4gSXQgY2FuIGJlIG9ic2VydmVkIHRoYXQgdGhlIGhpZ2hlciBmcmVxdWVuY3kgaXMgbG9jYXRlZCBiZXR3ZWVuIDUgYW5kIDYgbWlsbGlvbiBNZXhpY2FuIHBlc29zIChNWE4pLiBEZXNwaXRlIHRoZSBmYWN0IHRoYXQgdGhlIGRpZmZlcmVudCByYW5nZXMgZG8gbm90IGhhdmUgdGhlIHNhbWUgZnJlcXVlbmN5LCBpdCBpcyBzaW1pbGFyLg0KDQpgYGB7cn0NCnBhcihtZnJvdz1jKDQsIDQpKQ0KDQp2YXJpYWJsZXMgPC0gYygiSUVEX0Zsb3dzTVhOIiwgIlBlcmlvZCIsICJFeHBvcnRzX01YTiIsICJFbXBsb3ltZW50IiwgIkVkdWNhdGlvbiIsIA0KICAgICAgICAgICAgICAgIkRhaWx5X1NhbGFyeSIsICJJbm5vdmF0aW9uIiwgIkluc2VjdXJpdHlfUm9iYmVyeSIsIA0KICAgICAgICAgICAgICAgIkluc2VjdXJpdHlfSG9taWNpZGUiLCAiRXhjaGFuZ2VfUmF0ZSIsICJSb2FkX0RlbnNpdHkiLCANCiAgICAgICAgICAgICAgICJQb3B1bGF0aW9uX0RlbnNpdHkiLCAiQ08yX0VtaXNzaW9ucyIsICJHUERfUEVSX0NBUElUQSIsICJDUEkiKQ0KZm9yICh2YXJpYWJsZSBpbiB2YXJpYWJsZXMpIHsNCiAgaGlzdChkYXRhW1t2YXJpYWJsZV1dLCBjb2w9InN0ZWVsYmx1ZSIsIG1haW49dmFyaWFibGUpDQp9DQoNCmBgYA0KDQoNCkluIHRoaXMgcGFydCwgYW4gaGlzdG9ncmFtIGZvciBlYWNoIHZhcmlhYmxlIHdhcyBwbG90dGVkLCB3aXRoIHRoZSBpbnRlbnRpb24gb2Ygb2JzZXJ2ZWQgaXRzIHZhbHVlcyBiZWhhdmlvciwgYW5kIGV2YWx1YXRlIGlmIHRoZXkgY291bGQgbmVlZCBhIHRyYW5zZm9ybSBvciBhIGNoYW5nZS4NCmBgYHtyfQ0KcGxvdF9ub3JtYWxpdHkoZGF0YSxJRURfRmxvd3NNWE4pDQpwbG90X25vcm1hbGl0eShkYXRhLFBlcmlvZCkNCnBsb3Rfbm9ybWFsaXR5KGRhdGEsRXhwb3J0c19NWE4pIyBsb2cNCnBsb3Rfbm9ybWFsaXR5KGRhdGEsRW1wbG95bWVudCkgI0l0IGNvdWxkIGJlIGxvZw0KcGxvdF9ub3JtYWxpdHkoZGF0YSxFZHVjYXRpb24pDQpwbG90X25vcm1hbGl0eShkYXRhLERhaWx5X1NhbGFyeSkgI0l0IGNvdWxkIGJlIGxvZw0KcGxvdF9ub3JtYWxpdHkoZGF0YSxJbm5vdmF0aW9uKSAjSXQgY291bGQgYmUgbG9nDQpwbG90X25vcm1hbGl0eShkYXRhLEluc2VjdXJpdHlfUm9iYmVyeSkNCnBsb3Rfbm9ybWFsaXR5KGRhdGEsSW5zZWN1cml0eV9Ib21pY2lkZSkNCnBsb3Rfbm9ybWFsaXR5KGRhdGEsRXhjaGFuZ2VfUmF0ZSkgI1RvIHNxdWFyZQ0KcGxvdF9ub3JtYWxpdHkoZGF0YSxSb2FkX0RlbnNpdHkpDQpwbG90X25vcm1hbGl0eShkYXRhLFBvcHVsYXRpb25fRGVuc2l0eSkNCnBsb3Rfbm9ybWFsaXR5KGRhdGEsQ08yX0VtaXNzaW9ucykNCnBsb3Rfbm9ybWFsaXR5KGRhdGEsR1BEX1BFUl9DQVBJVEEpDQpwbG90X25vcm1hbGl0eShkYXRhLENQSSkNCmBgYA0KDQphZnRlciB0aGF0LCBub3JtYWxpdHkgZGlhZ25vc2lzIHBsb3RzIHdlcmUgcGxvdHRlZCB0byBzZWUgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIG9yaWdpbmFsIGRpc3RyaWJ1dGlvbiBmcmVxdWVuY3kgb2YgdmFsdWVzLCBhbmQgaXRzIHBvc3NpYmxlIGNoYW5nZXMuDQpgYGB7cn0NCmRhdGExPC1kYXRhICU+JSBzZWxlY3QoUGVyaW9kLElFRF9GbG93c01YTixFbXBsb3ltZW50LEluc2VjdXJpdHlfUm9iYmVyeSxJbnNlY3VyaXR5X0hvbWljaWRlLENPMl9FbWlzc2lvbnMsRmluYW5jaWFsX0NyaXNpcyxEYWlseV9TYWxhcnksRXhjaGFuZ2VfUmF0ZSxFeHBvcnRzX01YTixSb2FkX0RlbnNpdHksUG9wdWxhdGlvbl9EZW5zaXR5LENQSSxJbm5vdmF0aW9uLEVkdWNhdGlvbixHUERfUEVSX0NBUElUQSkNCnN1bW1hcnkoZGF0YTEpDQpjb3JycGxvdChjb3IoZGF0YTEpLCB0eXBlID0gJ3VwcGVyJywgb3JkZXIgPSAnaGNsdXN0JywgYWRkQ29lZi5jb2wgPSAnYmxhY2snLCB0bC5jZXggPSAwLjUsIHRsLnNydCA9IDkwLCBtYXIgPSBjKDAsMCwwLDApLG51bWJlci5jZXg9MC44KQ0KYGBgDQoNCkZpbmFsbHksIHRoaXMgY29ycmVsYXRpb24gcGxvdCB2aXN1YWxseSByZXByZXNlbnRzIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gZWFjaCB2YXJpYWJsZSwgaW5jbHVkaW5nIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUsIGJ5IHNob3dpbmcgdGhlaXIgY29ycmVsYXRpb24gY29lZmZpY2llbnRzLiBUaGlzIGNhbiBhc3Npc3QgaW4gaWRlbnRpZnlpbmcgd2hldGhlciB0aGVyZSBpcyBhIHBvc2l0aXZlIG9yIG5lZ2F0aXZlIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIHZhcmlhYmxlIG9mIGludGVyZXN0LCAnSUVEX0Zsb3dzTVhOLCcgYW5kIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXMuDQoNClVwb24gZXhhbWluaW5nIHRoZSBwbG90LCB3ZSBjYW4gY29uY2x1ZGUgdGhhdCB0aGUgdmFyaWFibGVzIHdpdGggdGhlIGhpZ2hlc3QgY29ycmVsYXRpb24gdmFsdWVzIGNvbmNlcm5pbmcgJ0lFRF9GbG93c01YTicgYXJlICoqIkVkdWNhdGlvbiIsICJJbm5vdmF0aW9uIiwgIlBvcHVsYXRpb25fRGVuc2l0eSIsICJSb2FkX0RlbnNpdHkiLCAiQ1BJIiwgIkV4cG9ydHNfTVhOIiwgYW5kICJFeGNoYW5nZV9SYXRlIioqLiBJdCdzIHdvcnRoIG5vdGluZyB0aGF0ICoqJ0RhaWx5X1NhbGFyeScqKiBhbHNvIHNob3dzIGEgZ29vZCAoYnV0IGxvd2VyKSBjb3JyZWxhdGlvbiB2YWx1ZS4NCiMjIyBXaGljaCBpcyB0aGUgZXN0aW1hdGlvbiBtZXRob2QgdG8gYmUgdXNlZCB0byBlc3RpbWF0ZSB0aGUgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWw/DQpUaGUgZXN0aW1hdGlvbiBtZXRob2QgaXMgKipPcmRpbmFyeSBMZWFzdCBTcXVhcmVzIChPTFMpKiouSXQgaXMgYSBjb21tb24gdGVjaG5pcXVlIGZvciBlc3RpbWF0aW5nIGNvZWZmaWNpZW50cy4gIlRoZSBPTFMgbWV0aG9kIGFpbXMgdG8gbWluaW1pemUgdGhlIHN1bSBvZiBzcXVhcmUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgb2JzZXJ2ZWQgYW5kIHByZWRpY3RlZCB2YWx1ZXMiLiAqKFhMU1RBVCwyMDIzKSoNCg0KDQoNCg0KIyBSZWdyZXNzaW9uIE1vZGVscw0KDQoNCiMjIEJhc2VkIG9uIEVEQSwgZm9ybXVsYXRlIGFuZCBkZXNjcmliZSAzIGh5cG90aGVzZXMNCg0KIA0KKiBIMTogSXQgbWlnaHQgYmUgZXhwZWN0ZWQgYSBwb3NpdGl2ZSByZWxhdGlvbiBiZXR3ZWVuIElubm92YXRpb24gYW5kIEZvcmVpZ24gRGlyZWN0IEludmVzdG1lbnQgZmxvd3MuDQoNCg0KKiBIMjogSXQgbWlnaHQgYmUgZXhwZWN0ZWQgYSBwb3NpdGl2ZSByZWxhdGlvbiBiZXR3ZWVuIGV4Y2hhbmdlX3JhdGUgYW5kIEZvcmVpZ24gRGlyZWN0IEludmVzdG1lbnQgZmxvd3MuDQoNCg0KKiBIMzogSXQgbWlnaHQgYmUgZXhwZWN0ZWQgYSBuZWdhdGl2ZSByZWxhdGlvbiBiZXR3ZWVuIGZpbmFuY2lhbCBjcmlzaXMgYW5kIEZvcmVpZ24gRGlyZWN0IEludmVzdG1lbnQgZmxvd3MuDQoNCioqRXh0cmEqKg0KKiBINDogSXQgbWlnaHQgYmUgZXhwZWN0ZWQgYSBwb3NpdGl2ZSByZWxhdGlvbiBiZXR3ZWVuIEV4cG9ydHMgYW5kIEZvcmVpZ24gRGlyZWN0IEludmVzdG1lbnQgZmxvd3MuDQoNCg0KYGBge3J9DQojQ29uc3RydWN0aW5nIGEgbW9kZWwgd2l0aCB2YXJpYWJsZXMgbWVudGlvbmVkIGJlbG93DQptb2RlbDE8LWxtKElFRF9GbG93c01YTn4gRXhwb3J0c19NWE4gICsgRWR1Y2F0aW9uICsgRGFpbHlfU2FsYXJ5ICsgSW5ub3ZhdGlvbiArIEV4Y2hhbmdlX1JhdGUrIFJvYWRfRGVuc2l0eSArIFBvcHVsYXRpb25fRGVuc2l0eSArIENQSSwgZGF0YT1kYXRhKQ0Kc3VtbWFyeShtb2RlbDEpDQoNCmBgYA0KDQpUaGlzIG1vZGVsIGdpdmVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSByZWxhdGlvbiBiZXR3ZWVuIGluZGVwZW5kZW50IHZhcmlhYmxlcyBhbmQgdGhlIGRlcGVuZGVudCB2YXJpYWJsZXMgKEZESSkuIEl0IGlzIHJlbGV2YW50IHRvIHNlZSB0aGF0IGp1c3Qgb25lIG9mIHRoZSBzZWxlY3RlZCB2YXJpYWJsZXMgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gVG8ga2VlcCBjb25jbHVkaW5nLCBpdCB3aWxsIGJlIG5lY2Vzc2FyeSB0byBkbyBjaGVjayB0ZXN0cyBmb3IgdGhpcyBtb2RlbDoNCmBgYHtyfQ0KQUlDKG1vZGVsMSkNCmBgYA0KDQpWYWx1ZSBmb3IgQUlDIGlzIHRvIGhpZ2guIEl0IHdpbGwgYmUgY29tcGFyZWQgd2l0aCBBSUMgZm9yIG90aGVyIHJlZ3Jlc3Npb24gbW9kZWxzIHRvIHNlZSB3aGF0IGlzIHRoZSBiZXN0IG1vZGVsLCBpbiBvcmRlciB0byBtYWtlIHRoZSBwcmVkaWN0aW9uIG1vcmUgYWNjdXJhY3kuDQoNCmBgYHtyfQ0KdmlmKG1vZGVsMSkNCmBgYA0KDQpWYXJpYWJsZXMgdXNlZCBpbiBtb2RlbCAxIGhhdmUgdmVyeSBoaWdoIHZhbHVlcyBvZiBWYXJpYW5jZSBJbmZsYXRpb24gRmFjdG9yIChWSUYpLCB3aGljaCBjYW4gYmUgaW50ZXJwcmV0ZWQgYXMgbXVsdGljb2xsaW5lYXJpdHkgYmV0d2VlbiB2YXJpYWJsZXMgaW4gdGhlIG1vZGVsLiBJdCBtdXN0IHNob3cgYW4gaW5jb3JyZWN0IHByZWRpY3Rpb24uIA0KDQpgYGB7cn0NCmhpc3RvZ3JhbShtb2RlbDEkcmVzaWR1YWxzKQ0KYGBgDQoNCmBgYHtyfQ0Kc2hhcGlyby50ZXN0KG1vZGVsMSRyZXNpZHVhbHMpDQpgYGANCg0KSW4gdGhlIGhpc3RvZ3JhbSBiZWxvdyBpdCBjYW4gYmUgb2JzZXJ2ZWQgdGhhdCByZXNpZHVhbHMgZG8gZm9sbG93IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgYW5kIGl0IGNhbiBiZSBjb25maXJtZWQgYnkgZ2V0dGluZyBhIHAtdmFsdWUgaGlnaGVyIHRoYW4gMC4wNSBvciA1JS4NCg0KYGBge3J9DQojRXN0aW1hdGluZyBhIG1vZGVsIGRlbGV0aW5nIHNvbWUgdmFyaWFibGVzLCBhbmQgdHJhbnNmb3JtaW5nIHNvbWUgaW50byAibG9nIHZhcmlhYmxlcyIgaW4gb3JkZXIgdG8gYWNoaWV2ZSBhIG5vcm1hbCBkaXN0cmlidXRpb24sIGFuZCBlbGV2YXRpbmcgc29tZSBvZiB0aGVzZSB0byBzcXVhcmUsIGR1ZSBpdHMgcG9zc2libGUgbm9uLWxpbmVhciByZWxhdGlvbiB3aXRoIGRlcGVuZGVudCB2YXJpYWJsZS4NCm1vZGVsMjwtbG0obG9nKElFRF9GbG93c01YTikgfiBsb2coRXhwb3J0c19NWE4pKyNUcnkgd2l0aCBsb2coRXhwb3J0cykNCiAgICAgICAgICAgIEkoRWR1Y2F0aW9uXjIpKyBEYWlseV9TYWxhcnkgKyBJbm5vdmF0aW9uKw0KICAgICAgICAgICAgIEkoRXhjaGFuZ2VfUmF0ZV4yKStGaW5hbmNpYWxfQ3Jpc2lzLCBkYXRhID0gZGF0YSkNCnN1bW1hcnkobW9kZWwyKQ0KYGBgDQoNCldpdGggdGhlIGNoYW5nZXMgbWFkZSBiZXR3ZWVuIG1vZGVsIDEgYW5kIDIsIGl0IGNhbiBiZSBvYnNlcnZlZCBzb21lIHByaW5jaXBhbCBjaGFuZ2VzIGluIHRoZSBzaWduaWZpY2FuY2UgZm9yIHNvbWUgdmFyaWFibGVzLCBidXQgaXQgbmVlZHMgdG8gYmUgdGVzdGVkIGJlZm9yZSBnZXR0aW5nIGFueSBwcmVkaWN0aW9uLg0KDQpgYGB7cn0NCkFJQyhtb2RlbDIpDQpgYGANCg0KVmFsdWUgZm9yIEFJQyBpcyBsb3csIGJ1dCB0aGlzIGlzIG5vdCB0aGUgZmlyc3QgcGFyYW1ldGVyIHRoYXQgbXVzdCBiZSBjb25zaWRlcmluZyBpbiB0ZXN0aW5nIGFuZCBldmFsdWF0aW5nIHJlZ3Jlc3Npb24gbW9kZWxzLiBJdCdzIGltcG9ydGFudCB0byBzZWUgaWYgdmFyaWFibGVzIGluIHRoaXMgbW9kZWwgaGF2ZSBtdWx0aWNvbGxpbmVhcml0eQ0KDQpgYGB7cn0NCnZpZihtb2RlbDIpDQpgYGANCg0KSXQgY2FuIGJlIG9ic2VydmVkIHZhbHVlcyBhYm92ZSAxMCBpbiB0aGUgdmFyaWFibGVzICJFeHBvcnRzX01YTiIgYW5kICJFeGNoYW5nZV9SYXRlIi4gSXQgc3VnZ2VzdHMgdGhhdCBwcmVkaWN0aW9ucyBmb3IgdGhpcyBtb2RlbCBtYXkgYmUgaW5jb3JyZWN0IGR1ZSB0aGUgbXVsdGljb2xsaW5lYXJpdHkgaW4gdGhlc2UgdmFyaWFibGVzLg0KDQpgYGB7cn0NCmhpc3RvZ3JhbShtb2RlbDIkcmVzaWR1YWxzKQ0KYGBgDQpgYGB7cn0NCnNoYXBpcm8udGVzdChtb2RlbDIkcmVzaWR1YWxzKQ0KYGBgDQoNCkluIHRoZSBoaXN0b2dyYW0gYmVsb3cgaXQgY2FuIGJlIG9ic2VydmVkIHRoYXQgcmVzaWR1YWxzIGRvIGZvbGxvdyBhIG5vcm1hbCBkaXN0cmlidXRpb24sIGFuZCBpdCBjYW4gYmUgY29uZmlybWVkIGJ5IGdldHRpbmcgYSBwLXZhbHVlIGhpZ2hlciB0aGFuIDAuMDUgb3IgNSUuIEl0IGNhbiBiZSBjb25jbHVkZWQgdGhhdCB0aGUgcHJvYmxlbSB3aXRoIHRoZSBtb2RlbHMgaXMgbXVsdGljb2xsaW5lYXJpdHkgQSB0cmFuc2Zvcm1hdGlvbiB3aWxsIGJlIG5lZWRpbmcuDQoNCg0KSW4gdGhlIHBsb3R0ZWQgaGlzdG9ncmFtcyBmb3IgdmFyaWFibGVzIGJlZm9yZSwgaXQgY291bGQgYmUgb2JzZXJ2ZWQgdGhhbiB0aGUgdmFsdWVzIGZvciB2YXJpYWJsZSAiRXhwb3J0c19NWE4iIGRpZCBub3QgaGF2ZSBhIG5vcm1hbCBkaXN0cmlidXRpb24sIG5vciB1c2luZyBsb2cgdHJhbnNmb3JtYXRpb24uDQoNCg0KQnkgYW5hbHl6aW5nIHRoZXNlIHBsb3RzLCBhbG9uZyB3aXRoIHRoZSBkaXNwZXJzaW9uIHBsb3QgcHJldmlvdXNseSBjcmVhdGVkIGZvciB0aGlzIHZhcmlhYmxlLCBpdCBjYW4gYmUgY29uY2x1ZGVkIHRoYXQgdGhlcmUgYXJlIHNpZ25pZmljYW50bHkgbW9yZSB2YWx1ZXMgb24gdGhlIGxlZnQgc2lkZS4gVGhlcmVmb3JlLCB0aGUgdHJhbnNmb3JtYXRpb24gd2lsbCBpbnZvbHZlIHJlcGxhY2luZyBzb21lIG9mIHRoZSB2YWx1ZXMgaW4gdGhlIHZhcmlhYmxlIHdpdGggdGhlIG1lZGlhbiBvZiBpdCwgaW4gYW4gYXR0ZW1wdCB0byBhY2hpZXZlIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgYW5kIGVsaW1pbmF0ZSBtdWx0aWNvbGxpbmVhcml0eQ0KDQpgYGB7cn0NCmRhdGExIDwtIGRhdGENCmRhdGExJEV4cG9ydHNfTVhOW2RhdGExJEV4cG9ydHNfTVhOID09IG1heChkYXRhMSRFeHBvcnRzX01YTildIDwtIG1lZGlhbihkYXRhMSRFeHBvcnRzX01YTikNCmBgYA0KDQoNCg0KDQoNCmBgYHtyfQ0KbW9kZWwzPC1sbShsb2coSUVEX0Zsb3dzTVhOKSB+IGxvZyhFeHBvcnRzX01YTikrDQogICAgICAgICAgICBJKEVkdWNhdGlvbl4yKSsgRGFpbHlfU2FsYXJ5ICsgSW5ub3ZhdGlvbisNCiAgICAgICAgICAgICBJKEV4Y2hhbmdlX1JhdGVeMikrRmluYW5jaWFsX0NyaXNpcywgZGF0YSA9IGRhdGExKQ0Kc3VtbWFyeShtb2RlbDMpDQpgYGANCg0KV2l0aCB0aGUgaW1wdXRhdGlvbiBvZiBtZWRpYW4gdmFsdWVzLCB0aGUgdmFyaWFibGVzIHdpdGggaGlnaCBsZXZlbCBvZiBzaWduaWZpY2FuY2UgY2hhbmdlcywgYnV0IGl0IGlzIG5lY2Vzc2FyeSB0byB0ZXN0IGlmIHRoaXMgbW9kZWwgZG8gbm90IHByZXNlbnQgbXVsdGljb2xsaW5lYXJpdHkNCg0KDQpgYGB7cn0NCkFJQyhtb2RlbDMpDQpgYGANCmBgYHtyfQ0KdmlmKG1vZGVsMykNCmBgYA0KDQpBbHRob3VnaCBBSUMgdmFsdWUgaXMgaGlnaGVyIHRoYW4gdGhlIG1vZGVsIDIgdmFsdWUsIGluIHRoaXMgbW9kZWwgdGhlIG11bHRpY29sbGluZWFyaXR5IHByb2JsZW0gd2VyZSBzb2x2ZWQsIGFuZCBwcmVkaWN0aW5nIHdpdGggdGhpcyBtb2RlbCBtYXkgYmUgbW9yZSBhY2N1cmFjeSB0aGFuIGRvaW5nIGl0IHdpdGggdGhlIHByZXZpb3VzIG1vZGVsLg0KDQpgYGB7cn0NCmhpc3RvZ3JhbShtb2RlbDMkcmVzaWR1YWxzKQ0KYGBgDQpgYGB7cn0NCnNoYXBpcm8udGVzdChtb2RlbDMkcmVzaWR1YWxzKQ0KYGBgDQoNCkhpc3RvZ3JhbSBzaG93cyBhIGJpdCByaWdodC1za2V3ZWQgZGlzdHJpYnV0aW9uIGZvciB0aGUgcmVzaWR1YWxzIG9mIHRoaXMgbW9kZWwsIGJ1dCB3aXRoIHNoYXBpcm8gdGVzdCwgZHVlIGl0cyBwLXZhbHVlIG9mIDAuNTAsIGl0IGNhbiBiZSBjb25jbHVkZWQgdGhhdCBzdGF0aXN0aWNhbCBpbmZlcmVuY2UgbWlnaHQgYmUgYWNjdXJhdGUuDQoNCiMjIyBTZWxlY3QgdGhlIHJlZ3Jlc3Npb24gbW9kZWwgdGhhdCBiZXR0ZXIgZml0cyB0aGUgZGF0YS4gUGxlYXNlIGNvbnNpZGVyIGRpYWdub3N0aWMgdGVzdHMgaW4gc2VsZWN0aW5nIHRoZSBtb2RlbC4NCg0KVGhlIG1vZGVsIHNlbGVjdGVkIGJhc2VkIG9uIHRoZSBkaWFnbm9zdGljIHRlc3RzIGlzIGdvaW5nIHRvIGJlIG1vZGVsIDMuIEl0IGlzIGltcG9ydGFudCB0byBiYXNlZCB0aGlzIGRlY2l0aW9uIHRha2luZyBpbnRvIGFjY291bnQgdGhhdCBzaWduaWZpY2FudCB2YXJpYWJsZXMgZm9yIG1vZGVsIDIgY291bGQgYmUgaW5jb3JyZWN0bHkgaW50ZXJwcmV0ZWQgYmVjYXVzZSBvZiBtdWx0aWNvbGxpbmVhcml0eS4NCg0KDQojIyMgSW50ZXJwcmV0IHRoZSByZWdyZXNzaW9uIHJlc3VsdHMgb2Ygc2VsZWN0ZWQgcmVncmVzc2lvbiBtb2RlbC4NClRoaXMgbW9kZWwgaGVscHMgdG8gZXZhbHVhdGUgdGhlIGh5cG90aGVzaXMgbWFkZSBiZWZvcmUuDQoqRm9yIEgxOiBJdCBjYW4gYmUgb2JzZXJ2ZWQgdGhhdCB0aGUgY29lZmZpY2llbnQgZm9yIHZhcmlhYmxlICJJbm5vdmF0aW9uIiBpcyBwb3NpdGl2ZSwgc28gdGhlIGh5cG90aGVzaXMgaXMgYWNjZXB0ZWQuDQoNCipGb3IgSDI6IEJhc2VkIG9uIHRoZSByZWdyZXNzaW9uIHJlc3VsdHMsIGl0IGNhbiBiZSBjb25jbHVkZWQgdGhhdCAiRXhjaGFuZ2VfUmF0ZSIgaGFzIGEgcG9zaXRpdmUgcmVsYXRpb25zaGlwIHdpdGggdGhlIGRlcGVuZGVudCB2YXJpYWJsZSwgc28gdGhlIGh5cG90aGVzaXMgaXMgYWNjZXB0ZWQuDQoNCipGb3IgSDM6IE1vZGVsIDMgc2hvd3MgdGhhdCB0aGUgdmFyaWFibGUgIkZpbmFuY2lhbF9DcmlzaXMiIGhhcyBhIG5lZ2F0aXZlIGNvZWZmaWNpZW50LCBzbyBpdCBtaWdodCBoYXZlIGEgbmVnYXRpdmUgcmVsYXRpb24gd2l0aCB0aGUgZGVwZW5kZW50IHZhcmlhYmxlLCB0aGlzIGlzIHdoeSB0aGUgdGhpcmQgaHlwb3RoZXNpcyBpcyBhY2NlcHRlZC4NCg0KKkZvciBINDogSXQgY2FuIGJlIGNvbmNsdWRlZCwgZHVlIHRoZSBuZWdhdGl2ZSBjb2VmZmljaWVudCBmb3IgIkV4cG9ydHNfTVhOIiBpbiBtb2RlbCAzLCB0aGF0IGl0IGhhcyBhIG5lZ2F0aXZlIHJlbGF0aW9uIHdpdGggRkRJLCBzbyB0aGUgaHlwb3RoZXNpcyBpcyByZWplY3RlZC4NCg0K4oCiIFNob3cgdGhlIHByZWRpY3RlZCB2YWx1ZXMgb2YgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSAoZS5nLiwgZWZmZWN0cyBwbG90KQ0KYGBge3J9DQpwbG90KGVmZmVjdCgiSW5ub3ZhdGlvbiIsbW9kZWwzKSkNCmBgYA0KYGBge3J9DQpwbG90KGVmZmVjdCgiSShFeGNoYW5nZV9SYXRlXjIpIixtb2RlbDMpKQ0KYGBgDQoNCmBgYHtyfQ0KcGxvdChlZmZlY3QoIkZpbmFuY2lhbF9DcmlzaXMiLG1vZGVsMykpDQpgYGANCg0KYGBge3J9DQpwbG90KGVmZmVjdCgiRXhwb3J0c19NWE4iLG1vZGVsMykpDQpgYGANCg0KSXQgaXMgaW1wb3J0YW50IHRvIHNlZSBob3cgdGhlIGVmZmVjdCBwbG90cyBpbGx1c3RyYXRlIHRoZSBwcmV2aW91cyByZXN1bHRzIGFuZCBoeXBvdGhlc2lzIHRlc3Rpbmcgb2J0YWluZWQgd2l0aCBtb2RlbCAzLiBJbm5vdmF0aW9uIGFuZCBFeGNoYW5nZSBSYXRlIHNob3dzIGEgcG9zaXRpdmUgcmVsYXRpb24gd2l0aCBGb3JlaWduIERpcmVjdCBJbnZlc3RtZW50LCB3aGlsZSBGaW5hbmNpYWwgQ3Jpc2lzIGFuZCBFeHBvcnRzKE1YTikgc2hvdyBhIG5lZ2F0aXZlIHJlbGF0aW9uLg0KDQoNCiMgQ29uY2x1c3Npb24NCiMjIEJyaWVmbHkgc3VtbWFyaXplIHRoZSBtYWluIDQtNiBpbnNpZ2h0cyBmcm9tIHlvdXIgZGF0YSBhbmFseXNpcyBpbiBQYXJ0cyAzLTQuDQoqIEluIG9yZGVyIHRvIHJlZHVjZSBtdWx0aWNvbGxpbmVhcml0eSwgd2hlbiBoYXZpbmcgc2lnbmlmaWNhbnQgdmFyaWFibGVzIGluIHRoZSBtb2RlbCwgaXMgdXNlZnVsIHRvIGxvb2sgZm9yIHBvc3NpYmxlIHRyYW5zZm9ybWF0aW9uIHRoYXQgdGhlc2UgdmFyaWFibGVzIGNvdWxkIGhhdmUuDQoNCiogRGVzcGl0ZSB0aGUgZmFjdCB0aGF0IGFsbW9zdCBhbGwgdGhlIHZhcmlhYmxlcyBoYWQgaGlnaCBjb3JyZWxhdGlvbiB2YWx1ZXMsIG5vdCBhbGwgb2YgdGhlc2UgdmFyaWFibGVzIHdoZXJlIHNpZ25pZmljYW50IGZvciByZWdyZXNzaW9uIG1vZGVsLiBJdCBzaG93cyBob3cgY29ycmVsYXRpb24gYW5kIHJlZ3Jlc3Npb24gaXMgbm90IHRoZSBzYW1lIHRoaW5nLg0KDQoqIEl0IGlzIGludGVyZXN0aW5nIHRvIHNlZSBob3cgZXhwb3J0cyBoYXMgYSBuZWdhdGl2ZSBpbXBhY3QgaW4gRkRJLCB3aGlsZSBleGNoYW5nZSByYXRlIGhhcyBhIHBvc2l0aXZlIGltcGFjdCwgdGhvdWdoIHRoZXNlIHR3byB2YXJpYWJsZXMgc2hvd24gYSBwb3NpdGl2ZSByZWxhdGlvbiBiZXR3ZWVuIGJvdGguDQoNCiogSXQgd2lsbCBiZSBpbnRlcmVzdGluZyB0byBvYnNlcnZlIHRoZSBiZWhhdmlvciBvZiB0aGUgZWR1Y2F0aW9uIHZhcmlhYmxlIGR1ZSB0aGUgcmVzdWx0IG9mIHRoZSBiYXIgZ3JhcGguIFRoaXMgdmFyaWFibGUgd2FzIGVsZXZhdGVkIHRvIHNxdWFyZSwgaGFkIGEgcG9zaXRpdmUgY29lZmZpY2llbnQsIGFuZCBzaWduaWZpY2FuY2Ugc3RhdGlzdGljIGZvciB0aGUgcmVncmVzc2lvbiBtb2RlbC4NCg0KKiBUbyBzdW0gdXA6DQpFeHBvcnRzOiBOZWdhdGl2ZSByZWxhdGlvbiwgYnV0IG5vdCBzaWduaWZpY2FudA0KRWR1Y2F0aW9uOiBQb3NpdGl2ZSByZWxhdGlvbiwgYW5kIHNpZ25pZmljYW50DQpEYWlseV9TYWxhcnk6IFBvc2l0aXZlIHJlbGF0aW9uLCBidXQgbm90IHNpZ25pZmljYW50DQpJbm5vdmF0aW9uOiBQb3NpdGl2ZSByZWxhdGlvbiwgYW5kIGl0IGlzIHRoZSBtb3N0IHNpZ25pZmljYW50IGluIHRoZSBtb2RlbA0KRXhjaGFuZ2VfUmF0ZTogUG9zaXRpdmUgcmVsYXRpb24sIGJ1dCBub3Qgc2lnbmlmaWNhbnQNCkZpbmFuY2lhbF9DcmlzaXM6IE5lZ2F0aXZlIHJlbGF0aW9uLCBidXQgbm90IHNpZ25pZmljYW50Lg0KVGhlIGltcGFjdCB0aGV5IHdpbGwgaGF2ZSBvbiBkZXBlbmRlbnQgdmFyaWFibGUgZGVwZW5kcyBvbiBpdHMgY29lZmZpY2llbnQgaW4gcmVncmVzc2lvbiBtb2RlbC4NCg0KDQojIFJlZmVyZW5jZXM6DQpMw6F6YXJvLCBFLiAoMjAyMiwgTm92ZW1iZXIgMTApLiDCv1F1w6kgZXMgZWwgbmVhcnNob3Jpbmc/IEVsIEVjb25vbWlzdGE7IEVsIEVjb25vbWlzdGEuIGh0dHBzOi8vd3d3LmVsZWNvbm9taXN0YS5jb20ubXgvZW1wcmVzYXMvUXVlLWVzLWVsLW5lYXJzaG9yaW5nLTIwMjIxMTA4LTAwOTMuaHRtbA0KDQpPcmRpbmFyeSBMZWFzdCBTcXVhcmVzIHJlZ3Jlc3Npb24gKE9MUykuICgyMDIzKS4gWExTVEFULCBZb3VyIERhdGEgQW5hbHlzaXMgU29sdXRpb24uIGh0dHBzOi8vd3d3Lnhsc3RhdC5jb20vZW4vc29sdXRpb25zL2ZlYXR1cmVzL29yZGluYXJ5LWxlYXN0LXNxdWFyZXMtcmVncmVzc2lvbi1vbHMNCg0KV2hhdCBJcyBQcmVkaWN0aXZlIEFuYWx5dGljcz8gNSBFeGFtcGxlcyB8IEhCUyBPbmxpbmUuICgyMDIxLCBPY3RvYmVyIDI2KS4gQnVzaW5lc3MgSW5zaWdodHMgQmxvZy4gaHR0cHM6Ly9vbmxpbmUuaGJzLmVkdS9ibG9nL3Bvc3QvcHJlZGljdGl2ZS1hbmFseXRpY3MNCg0KDQoNCiMgQU5FWA0KYGBge3J9DQpCb3gudGVzdChtb2RlbDMkcmVzaWR1YWxzLCB0eXBlID0gIkxqdW5nLUJveCIpICNSZXNpZHVhbGVzLikNCmFjZihtb2RlbDMkcmVzaWR1YWxzKSAjSGFjZXJsbyBkZSBsb3MgcmVzaWR1YWxlcy4NCg0KYGBgDQoNClNlZWluZyB0aGVzZSByZXN1bHRzLCBpdCBjYW4gYmUgY29uY2x1ZGVkIHRoYXQgbm8gY29ycmVsYXRpb24gc2VyaWFsIGlzIGlkZW50aWZpZWQgaW4gdGhlIG1vZGVsLiBJdCBpcyBwb3NzaWJsZSB0byBzZWUgdGhhdCBhbGwgdGhlIGxpbmVzIGZvciByZXNpZHVhbHMgYXJlIGluc2lkZSBkZSBzaWduaWZpY2FuY2UgbGltaXRzIChibHVlIGxpbmVzKS4NCg0KYGBge3J9DQojeDwtbW9kZWwubWF0cml4KGxvZyhJRURfRmxvd3NNWE4pIH4gbG9nKEV4cG9ydHNfTVhOKSsNCiAgICAgICAgICAjICBJKEVkdWNhdGlvbl4yKSsgRGFpbHlfU2FsYXJ5ICsgSW5ub3ZhdGlvbisNCiAgICAgICAgICAgIyAgSShFeGNoYW5nZV9SYXRlXjIpK0ZpbmFuY2lhbF9DcmlzaXMsdHJhaW4uZGF0YSlbLC0xXSAjIyMgT0xTIG1vZGVsIHNwZWNpZmljYXRpb24NCiMgeDwtbW9kZWwubWF0cml4KFdlZWtseV9TYWxlc34uLHRyYWluLmRhdGEpWywtMV0gIyMjIG1hdHJpeCBvZiBpbmRlcGVuZGVudCB2YXJpYWJsZXMgWCdzDQojeTwtdHJhaW4uZGF0YSRJRURfRmxvd3NNWE4gIyMjIGRlcGVuZGVudCB2YXJpYWJsZSANCg0KIyBJbiBlc3RpbWF0aW5nIExBU1NPIHJlZ3Jlc3Npb24gaXQgaXMgaW1wb3J0YW50IHRvIGRlZmluZSB0aGUgbGFtYmRhIHRoYXQgbWluaW1pemVzIHRoZSBwcmVkaWN0aW9uIGVycm9yIHJhdGUuIA0KIyBDcm9zcy12YWxpZGF0aW9uIGVuc3VyZXMgdGhhdCBldmVyeSBkYXRhIC8gb2JzZXJ2YXRpb24gZnJvbSB0aGUgb3JpZ2luYWwgZGF0YXNldCAoZGF0YWlucykgaGFzIGEgY2hhbmNlIG9mIGFwcGVhcmluZyBpbiB0cmFpbiBhbmQgdGVzdCBkYXRhc2V0cy4NCiMgRmluZCB0aGUgYmVzdCBsYW1iZGEgdXNpbmcgY3Jvc3MtdmFsaWRhdGlvbi4NCiNzZXQuc2VlZCgxMjMpIA0KI2N2Lmxhc3NvPC1jdi5nbG1uZXQoeCx5LGFscGhhPTEpICMgYWxwaGEgPSAxIGZvciBMQVNTTw0KDQojIERpc3BsYXkgdGhlIGJlc3QgbGFtYmRhIHZhbHVlDQojY3YubGFzc28kbGFtYmRhLm1pbiAgICAgICAgICAgICAgICAgICAgICAjIyMgbGFtYmRhOiBhIG51bWVyaWMgdmFsdWUgZGVmaW5pbmcgdGhlIGFtb3VudCBvZiBzaHJpbmthZ2UuIFdoeSBtaW4/IHRoZSBoaWdoZXIgdGhlIHZhbHVlIG9mID8/ICwgdGhlIG1vcmUgcGVuYWxpemF0aW9uIHRoZXJlIGlzDQoNCiMgRml0IHRoZSBmaW5hbCBtb2RlbCBvbiB0aGUgdHJhaW5pbmcgZGF0YQ0KI2xhc3NvbW9kZWw8LWdsbW5ldCh4LHksYWxwaGE9MSxsYW1iZGE9Y3YubGFzc28kbGFtYmRhLm1pbikNCg0KIyBEaXNwbGF5IHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzDQojY29lZihsYXNzb21vZGVsKQ0KDQojIE1ha2UgcHJlZGljdGlvbnMgb24gdGhlIHRlc3QgZGF0YQ0KI3gudGVzdD1tb2RlbC5tYXRyaXgobG9nKElFRF9GbG93c01YTikgfiBsb2coRXhwb3J0c19NWE4pKw0KICMgICAgICAgICAgIEkoRWR1Y2F0aW9uXjIpKyBEYWlseV9TYWxhcnkgKyBJbm5vdmF0aW9uKw0KICAjICAgICAgICAgICBJKEV4Y2hhbmdlX1JhdGVeMikrRmluYW5jaWFsX0NyaXNpcyx0cmFpbi5kYXRhKVssLTFdICMjIyBPTFMgbW9kZWwgc3BlY2lmaWNhdGlvbg0KIyB4LnRlc3Q8LW1vZGVsLm1hdHJpeChXZWVrbHlfU2FsZXN+Lix0ZXN0LmRhdGEpWywtMV0NCiNsYXNzb3ByZWRpY3Rpb25zIDwtIGxhc3NvbW9kZWwgJT4lIHByZWRpY3QoeC50ZXN0KSAlPiUgYXMudmVjdG9yKCkNCg0KIyBNb2RlbCBBY2N1cmFjeQ0KI2RhdGEuZnJhbWUoDQogIyBSTVNFID0gUk1TRShsYXNzb3ByZWRpY3Rpb25zLCB0ZXN0LmRhdGEkSUVEX0Zsb3dzTVhOKSwNCiAgI1JzcXVhcmUgPSBSMihsYXNzb3ByZWRpY3Rpb25zLCB0ZXN0LmRhdGEkSUVEX0Zsb3dzTVhOKSkNCg0KI0l0IG5ldmVyIHJ1bg0KDQojbGFzc288LWdsbW5ldChzY2FsZSh4KSx5LGFscGhhPTEpDQoNCiNwbG90KGxhc3NvLHh2YXI9ImxhbWJkYSIsbGFiZWw9VCkNCiNEQU5JRUwgRkFSSUFTIExBU08gTU9ERUwNCmBgYA0KDQoNCg0KDQoNCg0K