ITESM CAMPUS QRO FINANCIAL PROGRAMMING
Data Management
# Load all packages
library(readxl)
library(dplyr)
library(quadprog)
library(xts)
library(zoo)
library(psych)
library(tseries)
library(forecast)
library(lmtest)
library(astsa)
library(quantmod)
library(wbstats)
library(PerformanceAnalytics)
library(fPortfolio)
library(plotly)
library(ggplot2)
library(PortfolioAnalytics)
library(plm)
library(statar)
library(IntroCompFinR)
library(readxl)
us2022q2a <- read_excel("C:/Users/Stefan Schweitzer/Downloads/Finance Programing/us2022q2a.xlsx")
data.df<-read_excel("us2022q2a.xlsx",sheet = "data")
firm.df <-read_excel("us2022q2a.xlsx",sheet = "firms")
dicdatos.df <- read_excel("us2022q2a.xlsx",sheet = "DicDatos")
Main Descriptive Statistics for Important Variables such as Total
Assets, Revenue, Market Value
# selecting a company from our sample
MICROSOFT = data.df%>%
select(firm,q,revenue, totalassets, fiscalmonth) %>% #seleccionar columnas
filter (firm=="MSFT")
# mutate revenue values
MICROSOFT = data.df%>%
select(firm,q,revenue, totalassets, fiscalmonth) %>%
filter (firm=="MSFT") %>%
mutate(revenue = revenue/1000 )
# filtering for last quarter
data.df$q= as.Date(data.df$q)
d22q2= data.df %>%
filter (q =="2022-04-01")
# simplyfing column names
names(firm.df) = c("firm","Company","N", "IndustryNAICS", "Exchange", "Industryeconomatica", "NAICS3", "SParticipation")
firms= firm.df %>%
select (firm,Company,IndustryNAICS, Industryeconomatica)
# lets merge our tables
d22q2= merge(d22q2,firms, by="firm")
data.df = merge(data.df,firms, by="firm")
# using mutate, we can compute variable transformations so we can calculate market cap, EBIT and Book Value
d22q2 <- d22q2 %>%
mutate (mktcap = sharesoutstanding*originalprice,
EBIT = revenue-cogs-sgae,
bookv = totalassets - totalliabilities)
data.df <- data.df %>%
mutate (mktcap = sharesoutstanding*originalprice,
EBIT = revenue-cogs-sgae,
bookv = totalassets - totalliabilities)
data.df %>%
#we found that the excel file had a lot of empty cells, so to manage our environment we'll use NA.RM to omit blank cells
summarize(num_firms=n(),
median_mktcap= median (mktcap, na.rm= TRUE),
median_totalassets= median (totalassets, na.rm= TRUE),
median_bookvalue= median (bookv, na.rm= TRUE))
# lets organize our table by industry to find out the number of companies, their market value mean and revenue info.
data.df %>%
group_by(IndustryNAICS) %>%
summarize(num_firms= n(),
median_mktcap= median (mktcap, na.rm= TRUE),
median_revenue= median (revenue, na.rm= TRUE))
# So we've got data on the companies as well as their descriptive statistics, but we need to merge this info with the market data. Using SP500, we'll merge the data but first we must transform monthly returns into quarterly returns.
getSymbols("^GSPC", from="2000-01-01", to= "2022-07-01", periodicty="monthly" , src="yahoo")
[1] "^GSPC"
# Lets change adj prices from monthly to quarterly
GSPCQ= to.quarterly(GSPC, indexAt= 'startof')
GSPCQ=Ad(GSPCQ)
# Then calculate returns
GSPReturn= diff(log(GSPCQ),)
names(GSPReturn)= c("S&Preturn")
# Finally we'll save the returns from the last quarter to compare it with the d22q2 table.
RetGSPCQ2 <- -0.1796662303
GSPCQ.df=data.frame(q=index(GSPReturn), coredata (GSPReturn))
data.df=merge(data.df, GSPCQ.df, by="q")
data.df= pdata.frame(data.df,index=c("firm", "q" ))
data.df$returnstocks= diff(log(data.df$adjprice), )
data.df$best=ifelse(data.df$returnstocks>data.df$S.Preturn,1,0)
# Now, we will show how the US stock market has grown over time
data.df <- data.df %>%
mutate (mktcap = sharesoutstanding*originalprice)
stockmarketr = data.df %>%
group_by(q) |>
summarize(
marketv=sum(mktcap,na.rm=TRUE))
stockmarketr
ggplot(stockmarketr, aes(x=q, y=marketv,))+ geom_col()

WE CAN SEE A GROWTH TREND SINCE THE YEAR 2000 WITH A NOTORIOUS FALL
IN 2021.
BASIC FUNDAMENTAL ANALYSIS
You have to select 4 financial ratios/variables that might be related
to the probability that a stock return beats the market return. You have
to provide references for the justification of using your financial
ratios/variables.
- RETURN ON EQUITY (ROE): FOR THE FIRST RATIO WE WILL USE THE RETURN
ON EQUITY, ROE IS THE FINANCIAL PROFITABILITY OF A COMPANY, WITH THIS WE
CAN TELL WHETHER THE COMPANY HAS A DESIRED PERFORMANCE (BETTER THAN THE
MARKET) FIRST WE MUST CALCULATE THE NET INCOME
data.df$netincome <- data.df$ebitda - data.df$finexp - data.df$depreciationamor - data.df$incometax
WITH THE NET INCOME WE CAN CALCULATE OUR FIRST RATIO
data.df$roe <- data.df$netincome / data.df$stockholderequity
hist(data.df$roe, main = "Return on Equity", col = "GREEN")

DUE TO THE EXTREME VALUES IN THE GRAPH, WE CAN GO AHEAD AND
WINDSORIZE OUR RESULTS
data.df$roe <- winsorize(data.df$roe,probs = c(0.01,0.99))
0.42 % observations replaced at the bottom
0.42 % observations replaced at the top
hist(data.df$roe, main = "Return on Equity", col = "GREEN")

WE USE THE ROE SINCE WE WANT TO KNOW IF THE RETURNS ARE GREATER THAN
0, THANKS TO THE ROE WE CAN KNOW THAT MOST OF THE RETURNS OF THE
COMPANIES DURING THE PERIOD WERE POSITIVE WHICH CAN HELP US KNOW IF
THESE COMPANIES REALLY PERFORM BETTER THAN THE MARKET IN THOSE
PERIODS.
–
- BOOK TO MARKET RATIO (BMR): FOR THE SECOND RATIO WE WILL USE THE
BOOK TO MARKET RATIO SINCE THIS HELPS US TO COMPARE THE VALUE OF THE
COMPANY’S BOOKS WITH ITS MARKET VALUE WE ALREADY CALCULATED PREVIOUSLY
THE BOOKV OF THE STOCKS ONLY THE OTHER PART OF THE CALCULATION IS
MISSING
data.df$Marketvq2 <- data.df$originalprice * data.df$sharesoutstanding
# WE CAN NOTICE THAT BOTH VALUES CONTAIN THE SAME NUMBER OF DATA THEREFORE WE CAN CONTINUE TO CALCULATE THE BOOK TO MARKET RATIO
data.df$BMR <- data.df$bookv/data.df$Marketvq2
data.df$BMR
A-2001-10-01 A-2002-04-01 A-2002-07-01 A-2002-10-01
0.428065188 0.467054176 0.820484475 0.551637239
A-2003-04-01 A-2003-07-01 A-2003-10-01 A-2004-04-01
0.455936800 0.258715608 0.202835689 0.226078316
A-2004-07-01 A-2004-10-01 A-2005-04-01 A-2005-07-01
0.317818915 0.304188143 0.342055400 0.243939597
A-2007-10-01 A-2008-04-01 A-2008-07-01 A-2008-10-01
0.236962029 0.246596265 0.300339194 0.465149382
A-2009-04-01 A-2009-07-01 A-2009-10-01 A-2010-04-01
0.346883702 0.259150205 0.231219466 0.265981409
A-2010-07-01 A-2010-10-01 A-2011-04-01 A-2011-07-01
0.243113684 0.224702840 0.222670859 0.387080792
A-2012-10-01 A-2013-04-01 A-2013-07-01 A-2013-10-01
0.364001668 0.360358036 0.282544378 0.278718607
A-2014-04-01 A-2014-07-01 A-2014-10-01 A-2015-04-01
0.294057624 0.296786562 0.386143007 0.323698921
A-2015-07-01 A-2015-10-01 A-2016-04-01 A-2016-07-01
0.360901264 0.300257813 0.288432054 0.284512005
A-2018-10-01 A-2019-04-01 A-2019-07-01 A-2019-10-01
0.212721006 0.217204977 0.200172821 0.179428818
A-2020-04-01 A-2020-07-01 A-2020-10-01 A-2021-04-01
0.174737409 0.160053857 0.134026061 0.107241731
A-2021-07-01 A-2021-10-01 A-2022-04-01 AA-2001-10-01
0.103716033 0.111771524 0.144372967 NA
AA-2002-04-01 AA-2002-07-01 AA-2002-10-01 AA-2003-04-01
NA NA NA NA
AA-2003-07-01 AA-2003-10-01 AA-2004-04-01 AA-2004-07-01
NA NA NA NA
AA-2004-10-01 AA-2005-04-01 AA-2005-07-01 AA-2007-10-01
NA NA NA NA
AA-2008-04-01 AA-2008-07-01 AA-2008-10-01 AA-2009-04-01
NA NA NA NA
AA-2009-07-01 AA-2009-10-01 AA-2010-04-01 AA-2010-07-01
NA NA NA NA
AA-2010-10-01 AA-2011-04-01 AA-2011-07-01 AA-2012-10-01
NA NA NA NA
AA-2013-04-01 AA-2013-07-01 AA-2013-10-01 AA-2014-04-01
NA NA NA NA
AA-2014-07-01 AA-2014-10-01 AA-2015-04-01 AA-2015-07-01
NA NA NA NA
AA-2015-10-01 AA-2016-04-01 AA-2016-07-01 AA-2018-10-01
NA NA NA 1.491624443
AA-2019-04-01 AA-2019-07-01 AA-2019-10-01 AA-2020-04-01
1.579189448 1.721414676 1.474569521 2.547700429
AA-2020-07-01 AA-2020-10-01 AA-2021-04-01 AA-2021-07-01
2.321140059 1.170410194 0.787621394 0.597141919
AA-2021-10-01 AA-2022-04-01 AAIC-2001-10-01 AAIC-2002-04-01
0.563708502 0.867354774 NA NA
AAIC-2002-07-01 AAIC-2002-10-01 AAIC-2003-04-01 AAIC-2003-07-01
NA NA 0.610312455 0.442074874
AAIC-2003-10-01 AAIC-2004-04-01 AAIC-2004-07-01 AAIC-2004-10-01
0.404259534 0.429943223 0.479663865 0.482581144
AAIC-2005-04-01 AAIC-2005-07-01 AAIC-2007-10-01 AAIC-2008-04-01
0.619022836 0.795755435 0.825449332 1.436473201
AAIC-2008-07-01 AAIC-2008-10-01 AAIC-2009-04-01 AAIC-2009-07-01
0.840931094 0.501378899 1.517719155 1.758377835
AAIC-2009-10-01 AAIC-2010-04-01 AAIC-2010-07-01 AAIC-2010-10-01
1.243652952 1.219975554 1.039588705 1.174350946
AAIC-2011-04-01 AAIC-2011-07-01 AAIC-2012-10-01 AAIC-2013-04-01
0.874903341 1.005867831 1.702203043 1.220587288
AAIC-2013-07-01 AAIC-2013-10-01 AAIC-2014-04-01 AAIC-2014-07-01
1.341290645 1.259515192 1.158641244 1.395427730
AAIC-2014-10-01 AAIC-2015-04-01 AAIC-2015-07-01 AAIC-2015-10-01
1.050537312 1.214049542 1.481686665 1.588912293
AAIC-2016-04-01 AAIC-2016-07-01 AAIC-2018-10-01 AAIC-2019-04-01
1.446764216 1.277477524 1.249162065 1.288806570
AAIC-2019-07-01 AAIC-2019-10-01 AAIC-2020-04-01 AAIC-2020-07-01
1.531244368 1.598456441 2.185648966 2.382043341
AAIC-2020-10-01 AAIC-2021-04-01 AAIC-2021-07-01 AAIC-2021-10-01
1.860579858 1.609042335 1.734145354 1.828751680
AAIC-2022-04-01 AAL-2001-10-01 AAL-2002-04-01 AAL-2002-07-01
1.877784289 NA NA NA
AAL-2002-10-01 AAL-2003-04-01 AAL-2003-07-01 AAL-2003-10-01
NA NA NA NA
AAL-2004-04-01 AAL-2004-07-01 AAL-2004-10-01 AAL-2005-04-01
NA NA NA NA
AAL-2005-07-01 AAL-2007-10-01 AAL-2008-04-01 AAL-2008-07-01
NA NA NA NA
AAL-2008-10-01 AAL-2009-04-01 AAL-2009-07-01 AAL-2009-10-01
NA NA NA NA
AAL-2010-04-01 AAL-2010-07-01 AAL-2010-10-01 AAL-2011-04-01
NA NA NA NA
AAL-2011-07-01 AAL-2012-10-01 AAL-2013-04-01 AAL-2013-07-01
NA NA NA NA
AAL-2013-10-01 AAL-2014-04-01 AAL-2014-07-01 AAL-2014-10-01
-0.510181207 0.132063636 0.194565411 0.052538751
AAL-2015-04-01 AAL-2015-07-01 AAL-2015-10-01 AAL-2016-04-01
0.131420473 0.144210904 0.211093860 0.263440187
AAL-2016-07-01 AAL-2018-10-01 AAL-2019-04-01 AAL-2019-07-01
0.226338709 -0.011427203 -0.001516606 0.013323408
AAL-2019-10-01 AAL-2020-04-01 AAL-2020-07-01 AAL-2020-10-01
-0.009392285 -0.569085040 -0.884449335 -0.856114523
AAL-2021-04-01 AAL-2021-07-01 AAL-2021-10-01 AAL-2022-04-01
-0.563595175 -0.559769120 -0.631161086 -1.022602617
AAME-2001-10-01 AAME-2002-04-01 AAME-2002-07-01 AAME-2002-10-01
NA NA NA NA
AAME-2003-04-01 AAME-2003-07-01 AAME-2003-10-01 AAME-2004-04-01
NA NA NA NA
AAME-2004-07-01 AAME-2004-10-01 AAME-2005-04-01 AAME-2005-07-01
NA NA NA NA
AAME-2007-10-01 AAME-2008-04-01 AAME-2008-07-01 AAME-2008-10-01
NA NA NA NA
AAME-2009-04-01 AAME-2009-07-01 AAME-2009-10-01 AAME-2010-04-01
NA NA NA NA
AAME-2010-07-01 AAME-2010-10-01 AAME-2011-04-01 AAME-2011-07-01
NA NA NA 2.252503571
AAME-2012-10-01 AAME-2013-04-01 AAME-2013-07-01 AAME-2013-10-01
1.619013055 1.184172855 1.124285283 1.163924477
AAME-2014-04-01 AAME-2014-07-01 AAME-2014-10-01 AAME-2015-04-01
1.331794078 1.239925522 1.253742641 1.417137630
AAME-2015-07-01 AAME-2015-10-01 AAME-2016-04-01 AAME-2016-07-01
1.240611341 0.999613040 1.336228591 1.642309093
AAME-2018-10-01 AAME-2019-04-01 AAME-2019-07-01 AAME-2019-10-01
2.083524837 2.285130563 2.084515931 2.934567456
AAME-2020-04-01 AAME-2020-07-01 AAME-2020-10-01 AAME-2021-04-01
3.662740111 3.129338852 3.449422619 1.614298974
AAME-2021-07-01 AAME-2021-10-01 AAME-2022-04-01 AAOI-2001-10-01
1.652742474 2.829822609 2.003176889 NA
AAOI-2002-04-01 AAOI-2002-07-01 AAOI-2002-10-01 AAOI-2003-04-01
NA NA NA NA
AAOI-2003-07-01 AAOI-2003-10-01 AAOI-2004-04-01 AAOI-2004-07-01
NA NA NA NA
AAOI-2004-10-01 AAOI-2005-04-01 AAOI-2005-07-01 AAOI-2007-10-01
NA NA NA NA
AAOI-2008-04-01 AAOI-2008-07-01 AAOI-2008-10-01 AAOI-2009-04-01
NA NA NA NA
AAOI-2009-07-01 AAOI-2009-10-01 AAOI-2010-04-01 AAOI-2010-07-01
NA NA NA NA
AAOI-2010-10-01 AAOI-2011-04-01 AAOI-2011-07-01 AAOI-2012-10-01
NA NA NA NA
AAOI-2013-04-01 AAOI-2013-07-01 AAOI-2013-10-01 AAOI-2014-04-01
NA NA 0.332750033 0.325879295
AAOI-2014-07-01 AAOI-2014-10-01 AAOI-2015-04-01 AAOI-2015-07-01
0.477512168 0.691859195 0.469979524 0.573589516
AAOI-2015-10-01 AAOI-2016-04-01 AAOI-2016-07-01 AAOI-2018-10-01
0.572531669 0.877919219 0.492635061 1.077254148
AAOI-2019-04-01 AAOI-2019-07-01 AAOI-2019-10-01 AAOI-2020-04-01
1.520714121 1.345135434 1.145923474 1.164475800
AAOI-2020-07-01 AAOI-2020-10-01 AAOI-2021-04-01 AAOI-2021-07-01
1.034967481 1.421234853 1.218744296 1.354550198
AAOI-2021-10-01 AAOI-2022-04-01 AAON-2001-10-01 AAON-2002-04-01
1.814340897 5.126768763 NA NA
AAON-2002-07-01 AAON-2002-10-01 AAON-2003-04-01 AAON-2003-07-01
NA NA NA NA
AAON-2003-10-01 AAON-2004-04-01 AAON-2004-07-01 AAON-2004-10-01
NA NA NA NA
AAON-2005-04-01 AAON-2005-07-01 AAON-2007-10-01 AAON-2008-04-01
NA NA NA NA
AAON-2008-07-01 AAON-2008-10-01 AAON-2009-04-01 AAON-2009-07-01
NA NA NA NA
AAON-2009-10-01 AAON-2010-04-01 AAON-2010-07-01 AAON-2010-10-01
NA NA NA NA
AAON-2011-04-01 AAON-2011-07-01 AAON-2012-10-01 AAON-2013-04-01
NA 0.322525390 0.269876632 0.188265083
AAON-2013-07-01 AAON-2013-10-01 AAON-2014-04-01 AAON-2014-07-01
0.166003389 0.139770047 0.144761514 0.191334844
AAON-2014-10-01 AAON-2015-04-01 AAON-2015-07-01 AAON-2015-10-01
0.142716210 0.153735169 0.188747188 0.142446578
AAON-2016-04-01 AAON-2016-07-01 AAON-2018-10-01 AAON-2019-04-01
0.133672511 0.134253662 0.135509379 0.101168051
AAON-2019-07-01 AAON-2019-10-01 AAON-2020-04-01 AAON-2020-07-01
0.116788049 0.112713308 0.114236735 0.109532433
AAON-2020-10-01 AAON-2021-04-01 AAON-2021-07-01 AAON-2021-10-01
0.100797474 0.116921296 0.116901868 0.111942814
AAON-2022-04-01 AAP-2001-10-01 AAP-2002-04-01 AAP-2002-07-01
0.168780456 NA 0.204883401 0.242526627
AAP-2002-10-01 AAP-2003-04-01 AAP-2003-07-01 AAP-2003-10-01
0.268342520 0.219707468 0.229559275 0.210107153
AAP-2004-04-01 AAP-2004-07-01 AAP-2004-10-01 AAP-2005-04-01
0.210285153 0.294997363 0.224895250 0.164247310
AAP-2005-07-01 AAP-2007-10-01 AAP-2008-04-01 AAP-2008-07-01
0.205570811 0.272271938 0.256942596 0.278742355
AAP-2008-10-01 AAP-2009-04-01 AAP-2009-07-01 AAP-2009-10-01
0.337427501 0.298567108 0.336891435 0.334762428
AAP-2010-04-01 AAP-2010-07-01 AAP-2010-10-01 AAP-2011-04-01
0.252900429 0.215674194 0.186934252 0.197184918
AAP-2011-07-01 AAP-2012-10-01 AAP-2013-04-01 AAP-2013-07-01
0.178404759 0.228093249 0.214526898 0.243740516
AAP-2013-10-01 AAP-2014-04-01 AAP-2014-07-01 AAP-2014-10-01
0.188090115 0.169320763 0.202498629 0.172271089
AAP-2015-04-01 AAP-2015-07-01 AAP-2015-10-01 AAP-2016-04-01
0.184152774 0.164959761 0.223231758 0.221142980
AAP-2016-07-01 AAP-2018-10-01 AAP-2019-04-01 AAP-2019-07-01
0.250327055 0.309362341 0.320797307 0.292607993
AAP-2019-10-01 AAP-2020-04-01 AAP-2020-07-01 AAP-2020-10-01
0.319950764 0.359327492 0.354540174 0.333045389
AAP-2021-04-01 AAP-2021-07-01 AAP-2021-10-01 AAP-2022-04-01
0.260841265 0.250874514 0.209141678 0.277214097
AAPL-2001-10-01 AAPL-2002-04-01 AAPL-2002-07-01 AAPL-2002-10-01
0.514882833 0.645088862 0.786918040 0.799780369
AAPL-2003-04-01 AAPL-2003-07-01 AAPL-2003-10-01 AAPL-2004-04-01
0.602420587 0.562240610 0.550996011 0.389113378
AAPL-2004-07-01 AAPL-2004-10-01 AAPL-2005-04-01 AAPL-2005-07-01
0.337677443 0.223616654 0.224900205 0.167823748
AAPL-2007-10-01 AAPL-2008-04-01 AAPL-2008-07-01 AAPL-2008-10-01
0.096893784 0.132923351 0.208861710 0.301948267
AAPL-2009-04-01 AAPL-2009-07-01 AAPL-2009-10-01 AAPL-2010-04-01
0.203741125 0.167622627 0.188449238 0.188358976
AAPL-2010-07-01 AAPL-2010-10-01 AAPL-2011-04-01 AAPL-2011-07-01
0.184362166 0.184753227 0.223389942 0.216721456
AAPL-2012-10-01 AAPL-2013-04-01 AAPL-2013-07-01 AAPL-2013-10-01
0.254381253 0.331416377 0.285249594 0.256916496
AAPL-2014-04-01 AAPL-2014-07-01 AAPL-2014-10-01 AAPL-2015-04-01
0.215834417 0.184901611 0.190508839 0.173928823
AAPL-2015-07-01 AAPL-2015-10-01 AAPL-2016-04-01 AAPL-2016-07-01
0.189750489 0.218565150 0.241655637 0.210532975
AAPL-2018-10-01 AAPL-2019-04-01 AAPL-2019-07-01 AAPL-2019-10-01
0.157496119 0.105920556 0.089400819 0.068618499
AAPL-2020-04-01 AAPL-2020-07-01 AAPL-2020-10-01 AAPL-2021-04-01
0.045714382 0.032988754 0.029355012 0.028124670
AAPL-2021-07-01 AAPL-2021-10-01 AAPL-2022-04-01 AAT-2001-10-01
0.026972852 0.024691037 0.026259040 NA
AAT-2002-04-01 AAT-2002-07-01 AAT-2002-10-01 AAT-2003-04-01
NA NA NA NA
AAT-2003-07-01 AAT-2003-10-01 AAT-2004-04-01 AAT-2004-07-01
NA NA NA NA
AAT-2004-10-01 AAT-2005-04-01 AAT-2005-07-01 AAT-2007-10-01
NA NA NA NA
AAT-2008-04-01 AAT-2008-07-01 AAT-2008-10-01 AAT-2009-04-01
NA NA NA NA
AAT-2009-07-01 AAT-2009-10-01 AAT-2010-04-01 AAT-2010-07-01
NA NA NA NA
AAT-2010-10-01 AAT-2011-04-01 AAT-2011-07-01 AAT-2012-10-01
NA NA 0.979194129 0.619566693
AAT-2013-04-01 AAT-2013-07-01 AAT-2013-10-01 AAT-2014-04-01
0.568406898 0.560167774 0.540070342 0.509154439
AAT-2014-07-01 AAT-2014-10-01 AAT-2015-04-01 AAT-2015-07-01
0.548723082 0.441497278 0.471580056 0.453689457
AAT-2015-10-01 AAT-2016-04-01 AAT-2016-07-01 AAT-2018-10-01
0.476660365 0.418208020 0.413474498 0.423040576
AAT-2019-04-01 AAT-2019-07-01 AAT-2019-10-01 AAT-2020-04-01
0.571127398 0.465077612 0.470080029 0.763317087
AAT-2020-07-01 AAT-2020-10-01 AAT-2021-04-01 AAT-2021-07-01
0.874791941 0.719946517 0.544186127 0.538561150
AAT-2021-10-01 AAT-2022-04-01 AAWW-2001-10-01 AAWW-2002-04-01
0.533207380 0.667574341 NA NA
AAWW-2002-07-01 AAWW-2002-10-01 AAWW-2003-04-01 AAWW-2003-07-01
NA NA NA NA
AAWW-2003-10-01 AAWW-2004-04-01 AAWW-2004-07-01 AAWW-2004-10-01
NA NA NA NA
AAWW-2005-04-01 AAWW-2005-07-01 AAWW-2007-10-01 AAWW-2008-04-01
NA NA NA NA
AAWW-2008-07-01 AAWW-2008-10-01 AAWW-2009-04-01 AAWW-2009-07-01
NA NA NA NA
AAWW-2009-10-01 AAWW-2010-04-01 AAWW-2010-07-01 AAWW-2010-10-01
NA NA NA NA
AAWW-2011-04-01 AAWW-2011-07-01 AAWW-2012-10-01 AAWW-2013-04-01
0.696531579 1.263826048 1.099089881 1.104931936
AAWW-2013-07-01 AAWW-2013-10-01 AAWW-2014-04-01 AAWW-2014-07-01
1.107753354 1.283193446 1.457903492 1.645113530
AAWW-2014-10-01 AAWW-2015-04-01 AAWW-2015-07-01 AAWW-2015-10-01
1.159370084 1.102691440 1.718058927 1.428126011
AAWW-2016-04-01 AAWW-2016-07-01 AAWW-2018-10-01 AAWW-2019-04-01
1.441965406 1.395696507 1.915394298 1.843216221
AAWW-2019-07-01 AAWW-2019-10-01 AAWW-2020-04-01 AAWW-2020-07-01
3.362397916 2.512658597 1.717063371 1.267476615
AAWW-2020-10-01 AAWW-2021-04-01 AAWW-2021-07-01 AAWW-2021-10-01
1.506895641 1.263825360 1.106932837 1.028254106
AAWW-2022-04-01 ABBV-2001-10-01 ABBV-2002-04-01 ABBV-2002-07-01
1.646654069 NA NA NA
ABBV-2002-10-01 ABBV-2003-04-01 ABBV-2003-07-01 ABBV-2003-10-01
NA NA NA NA
ABBV-2004-04-01 ABBV-2004-07-01 ABBV-2004-10-01 ABBV-2005-04-01
NA NA NA NA
ABBV-2005-07-01 ABBV-2007-10-01 ABBV-2008-04-01 ABBV-2008-07-01
NA NA NA NA
ABBV-2008-10-01 ABBV-2009-04-01 ABBV-2009-07-01 ABBV-2009-10-01
NA NA NA NA
ABBV-2010-04-01 ABBV-2010-07-01 ABBV-2010-10-01 ABBV-2011-04-01
NA NA NA NA
ABBV-2011-07-01 ABBV-2012-10-01 ABBV-2013-04-01 ABBV-2013-07-01
NA NA 0.054286113 0.050267535
ABBV-2013-10-01 ABBV-2014-04-01 ABBV-2014-07-01 ABBV-2014-10-01
0.053467653 0.058083943 0.050474313 0.016707703
ABBV-2015-04-01 ABBV-2015-07-01 ABBV-2015-10-01 ABBV-2016-04-01
0.049488385 0.054673266 0.040736286 0.055939585
ABBV-2016-07-01 ABBV-2018-10-01 ABBV-2019-04-01 ABBV-2019-07-01
0.062981828 -0.060905563 -0.079680522 -0.073478709
ABBV-2019-10-01 ABBV-2020-04-01 ABBV-2020-07-01 ABBV-2020-10-01
-0.062412733 0.101609425 0.098905599 0.069233828
ABBV-2021-04-01 ABBV-2021-07-01 ABBV-2021-10-01 ABBV-2022-04-01
0.063303201 0.071223523 0.064485669 0.054269235
ABC-2001-10-01 ABC-2002-04-01 ABC-2002-07-01 ABC-2002-10-01
0.441820274 0.400216698 0.438485362 0.588831456
ABC-2003-04-01 ABC-2003-07-01 ABC-2003-10-01 ABC-2004-04-01
0.507775233 0.662235686 0.654467075 0.654409285
ABC-2004-07-01 ABC-2004-10-01 ABC-2005-04-01 ABC-2005-07-01
0.718495792 0.682918600 0.580677305 0.533478111
ABC-2007-10-01 ABC-2008-04-01 ABC-2008-07-01 ABC-2008-10-01
0.382832057 0.423045528 0.454242608 0.487512690
ABC-2009-04-01 ABC-2009-07-01 ABC-2009-10-01 ABC-2010-04-01
0.519730210 0.408330937 0.364943476 0.326776398
ABC-2010-07-01 ABC-2010-10-01 ABC-2011-04-01 ABC-2011-07-01
0.345566086 0.314138352 0.282407287 0.285680375
ABC-2012-10-01 ABC-2013-04-01 ABC-2013-07-01 ABC-2013-10-01
0.229865410 0.187579598 0.164425526 0.138980069
ABC-2014-04-01 ABC-2014-07-01 ABC-2014-10-01 ABC-2015-04-01
0.121048882 0.112824025 0.089685184 0.067445728
ABC-2015-07-01 ABC-2015-10-01 ABC-2016-04-01 ABC-2016-07-01
0.030623335 0.060958795 0.109762941 0.122758871
ABC-2018-10-01 ABC-2019-04-01 ABC-2019-07-01 ABC-2019-10-01
0.200707936 0.173395720 0.174516324 0.175300886
ABC-2020-04-01 ABC-2020-07-01 ABC-2020-10-01 ABC-2021-04-01
0.193587887 -0.042437102 -0.025619088 0.017367555
ABC-2021-07-01 ABC-2021-10-01 ABC-2022-04-01 ABCB-2001-10-01
0.023545809 0.021733411 0.017474758 NA
ABCB-2002-04-01 ABCB-2002-07-01 ABCB-2002-10-01 ABCB-2003-04-01
NA NA NA NA
ABCB-2003-07-01 ABCB-2003-10-01 ABCB-2004-04-01 ABCB-2004-07-01
NA NA NA NA
ABCB-2004-10-01 ABCB-2005-04-01 ABCB-2005-07-01 ABCB-2007-10-01
NA NA NA NA
ABCB-2008-04-01 ABCB-2008-07-01 ABCB-2008-10-01 ABCB-2009-04-01
NA NA NA NA
ABCB-2009-07-01 ABCB-2009-10-01 ABCB-2010-04-01 ABCB-2010-07-01
NA NA NA NA
ABCB-2010-10-01 ABCB-2011-04-01 ABCB-2011-07-01 ABCB-2012-10-01
NA NA 1.422313089 0.937868774
ABCB-2013-04-01 ABCB-2013-07-01 ABCB-2013-10-01 ABCB-2014-04-01
0.715290137 0.661023071 0.627567527 0.633098082
ABCB-2014-07-01 ABCB-2014-10-01 ABCB-2015-04-01 ABCB-2015-07-01
0.602870585 0.506937496 0.598028368 0.542669857
ABCB-2015-10-01 ABCB-2016-04-01 ABCB-2016-07-01 ABCB-2018-10-01
0.470380476 0.605046656 0.527219538 0.968088018
ABCB-2019-04-01 ABCB-2019-07-01 ABCB-2019-10-01 ABCB-2020-04-01
0.824251789 0.865322616 0.833367489 1.501842406
ABCB-2020-07-01 ABCB-2020-10-01 ABCB-2021-04-01 ABCB-2021-07-01
1.620216307 1.000598341 0.803569555 0.801432676
ABCB-2021-10-01 ABCB-2022-04-01 ABEO-2001-10-01 ABEO-2002-04-01
0.857485571 1.101596255 NA NA
ABEO-2002-07-01 ABEO-2002-10-01 ABEO-2003-04-01 ABEO-2003-07-01
NA NA NA NA
ABEO-2003-10-01 ABEO-2004-04-01 ABEO-2004-07-01 ABEO-2004-10-01
NA NA NA NA
ABEO-2005-04-01 ABEO-2005-07-01 ABEO-2007-10-01 ABEO-2008-04-01
NA NA NA NA
ABEO-2008-07-01 ABEO-2008-10-01 ABEO-2009-04-01 ABEO-2009-07-01
NA NA NA NA
ABEO-2009-10-01 ABEO-2010-04-01 ABEO-2010-07-01 ABEO-2010-10-01
NA NA NA NA
ABEO-2011-04-01 ABEO-2011-07-01 ABEO-2012-10-01 ABEO-2013-04-01
NA -0.986718167 -2.940479488 -1.040376364
ABEO-2013-07-01 ABEO-2013-10-01 ABEO-2014-04-01 ABEO-2014-07-01
-1.150215376 -2.311978403 -3.688183123 -4.145104281
ABEO-2014-10-01 ABEO-2015-04-01 ABEO-2015-07-01 ABEO-2015-10-01
2.601510707 0.488197913 0.551923572 0.615745368
ABEO-2016-04-01 ABEO-2016-07-01 ABEO-2018-10-01 ABEO-2019-04-01
0.794337217 0.315415460 0.391573903 0.456010508
ABEO-2020-04-01 ABEO-2020-07-01 ABEO-2020-10-01 ABEO-2021-04-01
0.496164718 1.331173964 0.662951566 0.544368409
ABEO-2021-07-01 ABEO-2021-10-01 ABEO-2022-04-01 ABG-2001-10-01
0.703369557 1.495792695 0.657146085 NA
ABG-2002-04-01 ABG-2002-07-01 ABG-2002-10-01 ABG-2003-04-01
0.900160009 1.448534454 1.503515386 0.989368168
ABG-2003-07-01 ABG-2003-10-01 ABG-2004-04-01 ABG-2004-07-01
0.842115157 0.746698375 0.891625374 1.064957248
ABG-2004-10-01 ABG-2005-04-01 ABG-2005-07-01 ABG-2007-10-01
1.070131251 1.004083714 0.942604944 1.229217575
ABG-2008-04-01 ABG-2008-07-01 ABG-2008-10-01 ABG-2009-04-01
1.444107751 1.605770786 1.525142754 0.708385333
ABG-2009-07-01 ABG-2009-10-01 ABG-2010-04-01 ABG-2010-07-01
0.589361943 0.654560178 0.770252981 0.605145440
ABG-2010-10-01 ABG-2011-04-01 ABG-2011-07-01 ABG-2012-10-01
0.474584859 0.510865559 0.587969535 0.399110203
ABG-2013-04-01 ABG-2013-07-01 ABG-2013-10-01 ABG-2014-04-01
0.362940880 0.284389564 0.294892552 0.250921138
ABG-2014-07-01 ABG-2014-10-01 ABG-2015-04-01 ABG-2015-07-01
0.268007120 0.196851437 0.148913940 0.145508127
ABG-2015-10-01 ABG-2016-04-01 ABG-2016-07-01 ABG-2018-10-01
0.183728044 0.187967539 0.207154432 0.362149567
ABG-2019-04-01 ABG-2019-07-01 ABG-2019-10-01 ABG-2020-04-01
0.339930093 0.303044014 0.299510799 0.478051245
ABG-2020-07-01 ABG-2020-10-01 ABG-2021-04-01 ABG-2021-07-01
0.431918067 0.322164517 0.346481206 0.341977427
ABG-2021-10-01 ABG-2022-04-01 ABM-2001-10-01 ABM-2002-04-01
0.633246763 0.643165348 NA NA
ABM-2002-07-01 ABM-2002-10-01 ABM-2003-04-01 ABM-2003-07-01
NA NA NA NA
ABM-2003-10-01 ABM-2004-04-01 ABM-2004-07-01 ABM-2004-10-01
NA NA NA NA
ABM-2005-04-01 ABM-2005-07-01 ABM-2007-10-01 ABM-2008-04-01
NA NA NA NA
ABM-2008-07-01 ABM-2008-10-01 ABM-2009-04-01 ABM-2009-07-01
NA NA NA NA
ABM-2009-10-01 ABM-2010-04-01 ABM-2010-07-01 ABM-2010-10-01
NA NA NA NA
ABM-2011-04-01 ABM-2011-07-01 ABM-2012-10-01 ABM-2013-04-01
NA 0.772610683 0.783392823 0.651998908
ABM-2013-07-01 ABM-2013-10-01 ABM-2014-04-01 ABM-2014-07-01
0.609290884 0.577989349 0.622654171 0.665922051
ABM-2014-10-01 ABM-2015-04-01 ABM-2015-07-01 ABM-2015-10-01
0.606547601 0.539363423 0.643071507 0.631120518
ABM-2016-04-01 ABM-2016-07-01 ABM-2018-10-01 ABM-2019-04-01
0.486346837 0.450820997 0.686065226 0.558149722
ABM-2019-07-01 ABM-2019-10-01 ABM-2020-04-01 ABM-2020-07-01
0.623328529 0.614118012 0.576533567 0.593639627
ABM-2020-10-01 ABM-2021-04-01 ABM-2021-07-01 ABM-2021-10-01
0.593908178 0.537337279 0.522150244 0.585176523
ABM-2022-04-01 ABMD-2001-10-01 ABMD-2002-04-01 ABMD-2002-07-01
0.575735912 NA NA NA
ABMD-2002-10-01 ABMD-2003-04-01 ABMD-2003-07-01 ABMD-2003-10-01
NA NA NA NA
ABMD-2004-04-01 ABMD-2004-07-01 ABMD-2004-10-01 ABMD-2005-04-01
NA NA NA NA
ABMD-2005-07-01 ABMD-2007-10-01 ABMD-2008-04-01 ABMD-2008-07-01
NA NA NA NA
ABMD-2008-10-01 ABMD-2009-04-01 ABMD-2009-07-01 ABMD-2009-10-01
NA NA NA NA
ABMD-2010-04-01 ABMD-2010-07-01 ABMD-2010-10-01 ABMD-2011-04-01
NA NA NA 0.178342513
ABMD-2011-07-01 ABMD-2012-10-01 ABMD-2013-04-01 ABMD-2013-07-01
0.262167075 0.255160865 0.169200899 0.201282770
ABMD-2013-10-01 ABMD-2014-04-01 ABMD-2014-07-01 ABMD-2014-10-01
0.152092731 0.169711487 0.174715399 0.125746303
ABMD-2015-04-01 ABMD-2015-07-01 ABMD-2015-10-01 ABMD-2016-04-01
0.112288996 0.084876008 0.090229427 0.080789025
ABMD-2016-07-01 ABMD-2018-10-01 ABMD-2019-04-01 ABMD-2019-07-01
0.072007120 0.058166017 0.085294103 0.122825719
ABMD-2019-10-01 ABMD-2020-04-01 ABMD-2020-07-01 ABMD-2020-10-01
0.135903110 0.101461141 0.094738280 0.086101896
ABMD-2021-04-01 ABMD-2021-07-01 ABMD-2021-10-01 ABMD-2022-04-01
0.092487208 0.093727778 0.087687948 0.136217416
ABNB-2001-10-01 ABNB-2002-04-01 ABNB-2002-07-01 ABNB-2002-10-01
NA NA NA NA
ABNB-2003-04-01 ABNB-2003-07-01 ABNB-2003-10-01 ABNB-2004-04-01
NA NA NA NA
ABNB-2004-07-01 ABNB-2004-10-01 ABNB-2005-04-01 ABNB-2005-07-01
NA NA NA NA
ABNB-2007-10-01 ABNB-2008-04-01 ABNB-2008-07-01 ABNB-2008-10-01
NA NA NA NA
ABNB-2009-04-01 ABNB-2009-07-01 ABNB-2009-10-01 ABNB-2010-04-01
NA NA NA NA
ABNB-2010-07-01 ABNB-2010-10-01 ABNB-2011-04-01 ABNB-2011-07-01
NA NA NA NA
ABNB-2012-10-01 ABNB-2013-04-01 ABNB-2013-07-01 ABNB-2013-10-01
NA NA NA NA
ABNB-2014-04-01 ABNB-2014-07-01 ABNB-2014-10-01 ABNB-2015-04-01
NA NA NA NA
ABNB-2015-07-01 ABNB-2016-04-01 ABNB-2016-07-01 ABNB-2018-10-01
NA NA NA NA
ABNB-2019-04-01 ABNB-2019-07-01 ABNB-2020-04-01 ABNB-2020-07-01
NA NA NA NA
ABNB-2021-04-01 ABNB-2021-07-01 ABNB-2021-10-01 ABNB-2022-04-01
0.036423949 0.042814633 0.045808354 0.092511146
ABOS-2001-10-01 ABOS-2002-04-01 ABOS-2002-07-01 ABOS-2002-10-01
NA NA NA NA
ABOS-2003-04-01 ABOS-2003-07-01 ABOS-2003-10-01 ABOS-2004-04-01
NA NA NA NA
ABOS-2004-07-01 ABOS-2004-10-01 ABOS-2005-04-01 ABOS-2005-07-01
NA NA NA NA
ABOS-2007-10-01 ABOS-2008-04-01 ABOS-2008-07-01 ABOS-2008-10-01
NA NA NA NA
ABOS-2009-04-01 ABOS-2009-07-01 ABOS-2009-10-01 ABOS-2010-04-01
NA NA NA NA
ABOS-2010-07-01 ABOS-2010-10-01 ABOS-2011-04-01 ABOS-2011-07-01
NA NA NA NA
ABOS-2012-10-01 ABOS-2013-04-01 ABOS-2013-07-01 ABOS-2013-10-01
NA NA NA NA
ABOS-2014-04-01 ABOS-2014-07-01 ABOS-2014-10-01 ABOS-2015-04-01
NA NA NA NA
ABOS-2015-07-01 ABOS-2015-10-01 ABOS-2016-04-01 ABOS-2016-07-01
NA NA NA NA
ABOS-2018-10-01 ABOS-2019-04-01 ABOS-2019-07-01 ABOS-2019-10-01
NA NA NA NA
ABOS-2020-04-01 ABOS-2020-07-01 ABOS-2020-10-01 ABOS-2021-04-01
NA NA NA NA
ABOS-2021-07-01 ABOS-2021-10-01 ABOS-2022-04-01 ABR-2001-10-01
0.388056473 0.823099304 1.084909826 NA
ABR-2002-04-01 ABR-2002-07-01 ABR-2002-10-01 ABR-2003-04-01
NA NA NA NA
ABR-2003-07-01 ABR-2003-10-01 ABR-2004-04-01 ABR-2004-07-01
NA NA NA NA
ABR-2004-10-01 ABR-2005-04-01 ABR-2005-07-01 ABR-2007-10-01
NA NA NA NA
ABR-2008-04-01 ABR-2008-07-01 ABR-2008-10-01 ABR-2009-04-01
NA NA NA NA
ABR-2009-07-01 ABR-2009-10-01 ABR-2010-04-01 ABR-2010-07-01
NA NA NA NA
ABR-2010-10-01 ABR-2011-04-01 ABR-2011-07-01 ABR-2012-10-01
NA NA 2.055681277 1.235482377
ABR-2013-04-01 ABR-2013-07-01 ABR-2013-10-01 ABR-2014-04-01
1.466311452 1.496747290 1.337201555 1.367757085
ABR-2014-07-01 ABR-2014-10-01 ABR-2015-04-01 ABR-2015-07-01
1.570075317 1.566889990 1.615166417 1.745221571
ABR-2015-10-01 ABR-2016-04-01 ABR-2016-07-01 ABR-2018-10-01
1.550819721 1.531195870 1.902771132 1.253966154
ABR-2019-04-01 ABR-2019-07-01 ABR-2019-10-01 ABR-2020-04-01
1.138460126 0.968939824 0.966693381 1.234659604
ABR-2020-07-01 ABR-2020-10-01 ABR-2021-04-01 ABR-2021-07-01
1.028088689 0.900376620 0.825269517 0.810659918
ABR-2021-10-01 ABR-2022-04-01 ABSI-2001-10-01 ABSI-2002-04-01
0.973320175 1.386973912 NA NA
ABSI-2002-07-01 ABSI-2002-10-01 ABSI-2003-04-01 ABSI-2003-07-01
NA NA NA NA
ABSI-2003-10-01 ABSI-2004-04-01 ABSI-2004-07-01 ABSI-2004-10-01
NA NA NA NA
ABSI-2005-04-01 ABSI-2005-07-01 ABSI-2007-10-01 ABSI-2008-04-01
NA NA NA NA
ABSI-2008-07-01 ABSI-2008-10-01 ABSI-2009-04-01 ABSI-2009-07-01
NA NA NA NA
[ reached getOption("max.print") -- omitted 168109 entries ]
NEVER MIND ALL THAT DATA, LETS DO A HISTOGRAM
# OUR X AXIS WAS HUGE SO WE DECIDED TO TUNE IT DOWN WITH THE WINSORIZE FUNCTION
hist(data.df$BMR, col="bluE")

data.df$BMR <- winsorize(data.df$BMR,probs = c(0.01,0.99))
0.49 % observations replaced at the bottom
0.49 % observations replaced at the top
hist(data.df$BMR, main = "BMR", col = "blue")

MOST OF THE DATA OBTAINED BY THE BMR WERE POSITIVE AND ACCORDING TO
THE RATIO, A BMR GREATER THAN 1 TELLS US THAT SINCE THE BOOK VALUE OF
THE COMPANY IS GREATER THAN THE MARKET VALUE, IT IS CONSIDERED THAT THE
COMPANY’S BUSINESS IS UNDERVALUED THEN THE MOST OF THE COMPANIES IN THIS
PERIOD ARE SELLING THEIR ASSETS FOR A LOWER PRICE THAN THEY ARE REALLY
WORTH.
- EARNINGS PER SHARE (EPSP): AS WE KNOW EARNINGS PER SHARE IS THE
PROFIT THAT COMPANIES EARN PER SHARE, IN ORDER TO CALCULATE IT WE ONLY
NEED TO DIVIDE THE NET PROTFIT BY THE NUMBER OF SHARES THAT THE COMPANY
HAS, WE WILL DO THE DEFLATED BY PRICE WITH JUST DIVIDING ESPS ON THE
ORIGINAL PRICE OF THE SHARE SO THAT IT IS BETTER COMPARABLE BETWEEN
COMPANIES.
data.df$earninspershare <- data.df$EBIT/data.df$sharesoutstanding
data.df$EPSP <- data.df$earninspershare/data.df$originalprice
hist(data.df$EPSP, main = "Earnings Per Share Deflated by Price", col = "RED")

WE WILL GO AHEAD AND WINSORIZE ONCE AGAIN
data.df$EPSP <- winsorize(data.df$EPSP,probs = c(0.01,0.99))
0.49 % observations replaced at the bottom
0.49 % observations replaced at the top
hist(data.df$EPSP, main = "Earnings Per Share Deflated by Price", col = "RED")

WE NOTICE EPSP GREATER THAN 0% IN MOST OF THE OBSERVED DATA, WITH
SOME EXTREME VALUES TRENDING TOWARDS -0.3.
4.- SIZE OF THE COMPANY: THE SIZE OF THE COMPANY WILL HELP US A LOT
TO KNOW THE PROFITABILITY OF THE COMPANIES USING THEIR TOTAL ASSETS, WE
BELIEVE THAT THE SIZE OF THE COMPANY SHOULD BE CONSIDERED IN ORDER TO
BETTER ALLOCATE THE WEIGHTS IN THE INVESTMENT PORTFOLIO. IF DONE
CORRECTLY,WE MAY BE ABLE TO BEAT THE MARKET
data.df$size <- log(data.df$totalassets)
hist(data.df$size, main = "Size", col = "YELLOW")

Second Screening- Alpha and Market Risk of the Stocks
WE WILL MAKE A LOGISTIC MODEL WITH THE INFO ALREADY GATHERED CREATING
A NEW VARIABLE DATAMODEL.
datamodel <-data.df %>%
select(firm,year,everything())
WE ARE NOW GOING TO COMPARE THE STOCK RETURNS AGAINST THE MARKET
RETURNS AND ASSIGN IT TO A NEW COLUMN, IF THE CONDITION IS MET THAT THE
STOCKSRETURNS ARE GREATER THAN THE MARKET RETURNS PREVIOUSLY CALCULATED
IN THE FIRST STEP
datamodel$higherR <- ifelse(datamodel$returnstocks > datamodel$S.Preturn, 1,0)
model1= glm(higherR ~ roe + BMR +EPSP + size, data= datamodel,family= "binomial", na.action = na.omit)
summary(model1)
Call:
glm(formula = higherR ~ roe + BMR + EPSP + size, family = "binomial",
data = datamodel, na.action = na.omit)
Deviance Residuals:
Min 1Q Median 3Q Max
-1.9438 -1.1926 -0.2677 1.1137 2.6383
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.25337 0.05718 -4.431 9.37e-06 ***
roe 0.28971 0.04001 7.241 4.44e-13 ***
BMR -0.64798 0.01825 -35.503 < 2e-16 ***
EPSP 4.78460 0.16961 28.209 < 2e-16 ***
size 0.03859 0.00402 9.600 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 94031 on 67828 degrees of freedom
Residual deviance: 90659 on 67824 degrees of freedom
(101280 observations deleted due to missingness)
AIC: 90669
Number of Fisher Scoring iterations: 3
OUR Z VALUES WERE ALL OVER THE PLACE, BUT THANKS TO THE PVALUES WE
CAN CONSIDER ROE BMR EPSP AND SIZE AS MEANINGFUL AND STATISTICALLY
SIGNIFICANT, THEREFORE: THE ODDS OF BEATING THE MARKET CAN BE EXPLAINED
BY EACH PORCENTUAL CHANGE IN RETURN OVER EQUITY.
IF WE TRULY WANT TO KNOW WHETHER WE CAN BEAT THE MARKET, WE’VE GOT TO
USE THE MOST RECENT DATA AVAILABLE, BEING THAT FOUND IN THE D22Q2
TABLE.
FIRMS <- datamodel %>%
select(q,firm,S.Preturn,roe,BMR,EPSP,size,year) %>%
group_by(q) |> filter( year== "2022") |>
as.data.frame()
THE PREDICT.GLM FUNCTION HELPS US TO OBTAIN PREDICTIONS FOR OUR
MODEL, IN THIS CASE WE WANT THE STOCKS TO BE GREATER THAN THE MEAN
PERFORMANCE SO LETS SEE WHAT HAPPENS.
FIRMS <- FIRMS %>%
mutate(prediction=predict.glm(model1,newdata=FIRMS,type=c("response")) )
FIRMS
NOW WE WILL GET THE TOP 50 FIRMS ARRANGING THEM FROM HIGHEST TO
LOWEST. THE PREDICTIONS WILL BE OBTAINED USING THE TIDIVERSE TOP_N
FUNCTION IN ORDER TO SELECT THE FIRST 50.
TOP50firms <- FIRMS %>%
arrange (desc(FIRMS$prediction)) %>%
top_n(50)
Selecting by prediction
TOP50firms
# LETS DISPLAY THE TOP 50 TICKERS
TICKERS<-as.vector(TOP50firms$firm)
TICKERS
[1] "PEI" "CYH" "CCO" "FAT" "AHT" "NCMI" "LYLT" "YELL" "SWN" "SUP"
[11] "NOG" "ATUS" "PBPB" "PARR" "FUN" "TUP" "CWH" "CRK" "WTI" "AMC"
[21] "DRCT" "OVV" "REAL" "PDCO" "LPI" "COMM" "PFGC" "WW" "ULCC" "ARCH"
[31] "PBI" "TSQ" "CAR" "UNIT" "SIX" "MPC" "CURV" "LEU" "DK" "BATL"
[41] "PLAY" "SNBR" "EMBC" "EGY" "CURO" "PRG" "JAKK" "VLO" "PRTS" "ALHC"
# WE WILL HAVE TO CREATE A FUNCTION THAT OBTAINS THE DATA FROM OUR TICKERLIST WHERE THE FIRST 50 ARE PRESENTED, CONSIDERING THE INFORMATION FROM THE LAST YEAR
for (t in TICKERS) {
try(getSymbols(t,
from = "2020-01-01", to = "2022-06-30",
periodicity = "monthly",
src = "yahoo") )
}
Warning: PBPB contains missing values. Some functions will not work if objects contain missing values in the middle of the series. Consider using na.omit(), na.approx(), na.fill(), etc to remove or replace them.Warning: incomplete final line found by readTableHeader on 'https://query1.finance.yahoo.com/v7/finance/download/DRCT?period1=1577836800&period2=1656547200&interval=1mo&events=history'Warning: UNIT contains missing values. Some functions will not work if objects contain missing values in the middle of the series. Consider using na.omit(), na.approx(), na.fill(), etc to remove or replace them.Warning: BATL contains missing values. Some functions will not work if objects contain missing values in the middle of the series. Consider using na.omit(), na.approx(), na.fill(), etc to remove or replace them.Warning: incomplete final line found by readTableHeader on 'https://query2.finance.yahoo.com/v7/finance/download/EMBC?period1=1577836800&period2=1656547200&interval=1mo&events=history'
list = c()
for(t in ls()) {
if (t %in% TICKERS){
list = c(list,t)
}}
TICKERS
[1] "PEI" "CYH" "CCO" "FAT" "AHT" "NCMI" "LYLT" "YELL" "SWN" "SUP"
[11] "NOG" "ATUS" "PBPB" "PARR" "FUN" "TUP" "CWH" "CRK" "WTI" "AMC"
[21] "DRCT" "OVV" "REAL" "PDCO" "LPI" "COMM" "PFGC" "WW" "ULCC" "ARCH"
[31] "PBI" "TSQ" "CAR" "UNIT" "SIX" "MPC" "CURV" "LEU" "DK" "BATL"
[41] "PLAY" "SNBR" "EMBC" "EGY" "CURO" "PRG" "JAKK" "VLO" "PRTS" "ALHC"
prices<- Ad(merge(AHT,ALHC,AMC,ARCH,ATUS,BATL,CAR,CCO,COMM,CRK,CURO,CURV,CWH,CYH,DK,DRCT,EGY,EMBC,FAT,FUN,JAKK,LEU,LPI,LYLT,MPC,NCMI,NOG,PARR,PBI,PBPB,PDCO,PEI,PFGC,PLAY,PRG,PRTS,REAL,SIX,SNBR,SUP,SWN,TSQ,TUP,ULCC,UNIT,VLO,WTI,WW,YELL))
prices
AHT.Adjusted ALHC.Adjusted AMC.Adjusted ARCH.Adjusted
2020-01-01 246.00 NA 6.480244 43.39984
2020-02-01 216.00 NA 6.221829 42.40602
2020-03-01 74.00 NA 3.140732 24.34030
2020-04-01 82.00 NA 4.920000 24.83113
2020-05-01 69.00 NA 5.130000 28.03816
2020-06-01 72.00 NA 4.290000 24.16760
2020-07-01 39.20 NA 4.040000 26.38786
2020-08-01 30.80 NA 5.880000 32.04483
2020-09-01 16.50 NA 4.710000 36.13657
2020-10-01 12.90 NA 2.360000 25.98805
2020-11-01 26.50 NA 4.270000 28.44649
2020-12-01 25.90 NA 2.120000 37.23393
2021-01-01 29.20 NA 13.260000 40.76422
2021-02-01 34.30 NA 8.010000 40.76422
2021-03-01 29.50 NA 10.210000 35.38797
2021-04-01 27.40 26.54 10.030000 37.77837
2021-05-01 40.50 25.23 26.120001 48.54788
2021-06-01 45.60 23.37 56.680000 48.47132
2021-07-01 16.20 20.83 37.020000 55.90620
2021-08-01 15.45 17.67 47.130001 64.38740
ATUS.Adjusted BATL.Adjusted CAR.Adjusted CCO.Adjusted
2020-01-01 27.36 11.020 32.80 2.73
2020-02-01 25.86 7.480 32.38 2.07
2020-03-01 22.29 4.675 13.90 0.64
2020-04-01 25.97 4.900 16.48 0.96
2020-05-01 25.72 5.790 21.53 0.97
2020-06-01 22.54 9.500 22.89 1.04
2020-07-01 26.99 8.630 25.90 0.92
2020-08-01 27.58 8.340 34.11 1.17
2020-09-01 26.00 7.900 26.32 1.00
2020-10-01 26.95 6.750 33.67 0.89
2020-11-01 33.92 7.660 35.17 1.51
2020-12-01 37.87 8.300 37.30 1.65
2021-01-01 35.57 7.350 41.34 1.99
2021-02-01 33.61 11.600 55.55 1.72
2021-03-01 32.53 10.880 72.54 1.80
2021-04-01 36.31 12.000 89.61 2.51
2021-05-01 36.06 12.400 87.82 2.39
2021-06-01 34.14 13.400 77.89 2.64
2021-07-01 30.73 12.910 82.77 2.66
2021-08-01 27.44 10.620 90.75 2.63
COMM.Adjusted CRK.Adjusted CURO.Adjusted CURV.Adjusted
2020-01-01 12.185 5.492453 9.567182 NA
2020-02-01 11.010 5.949329 8.482718 NA
2020-03-01 9.110 5.353403 4.890069 NA
2020-04-01 11.010 7.607990 8.599140 NA
2020-05-01 10.310 5.323607 6.172559 NA
2020-06-01 8.330 4.350261 7.601144 NA
2020-07-01 9.280 5.323607 6.503304 NA
2020-08-01 10.300 5.720891 7.163868 NA
2020-09-01 9.000 4.350261 6.604249 NA
2020-10-01 8.900 5.273946 7.016428 NA
2020-11-01 11.850 4.836934 8.093719 NA
2020-12-01 13.400 4.340328 13.512963 NA
2021-01-01 14.690 4.519106 13.701560 NA
2021-02-01 14.590 5.671230 13.644981 NA
2021-03-01 15.360 5.502385 13.807485 NA
2021-04-01 16.450 5.452724 13.551966 NA
2021-05-01 20.310 5.591774 15.624507 NA
2021-06-01 21.310 6.624712 16.213560 NA
2021-07-01 21.160 6.038718 15.040462 23.35
2021-08-01 15.800 5.869872 15.612705 23.11
CWH.Adjusted CYH.Adjusted DK.Adjusted DRCT.Adjusted
2020-01-01 13.006595 4.29 25.536520 NA
2020-02-01 11.427761 4.93 19.882406 NA
2020-03-01 4.753213 3.34 14.656068 NA
2020-04-01 7.601589 3.03 22.107376 NA
2020-05-01 18.151257 3.15 18.623217 NA
2020-06-01 23.276114 3.01 16.721933 NA
2020-07-01 31.611902 4.98 16.789169 NA
2020-08-01 25.085800 5.17 15.108329 NA
2020-09-01 25.681437 4.22 10.893687 NA
2020-10-01 22.934715 6.24 9.846405 NA
2020-11-01 26.586573 8.18 13.007825 NA
2020-12-01 22.596416 7.43 15.728799 NA
2021-01-01 30.710697 9.32 18.361685 NA
2021-02-01 28.139484 8.56 24.038538 NA
2021-03-01 32.706532 13.52 21.317564 NA
2021-04-01 39.359192 11.15 23.226162 NA
2021-05-01 40.127575 14.27 21.816736 NA
2021-06-01 37.261333 15.44 21.160961 NA
2021-07-01 36.008202 13.32 17.010984 NA
2021-08-01 36.538807 12.31 16.746717 NA
EGY.Adjusted EMBC.Adjusted FAT.Adjusted FUN.Adjusted
2020-01-01 2.187433 NA 4.199655 52.23162
2020-02-01 1.953065 NA 3.590273 44.07948
2020-03-01 0.880832 NA 2.050310 17.69354
2020-04-01 0.905246 NA 3.033530 28.43146
2020-05-01 0.968720 NA 2.910405 31.35939
2020-06-01 1.210900 NA 3.078141 27.11044
2020-07-01 1.123012 NA 2.855087 23.50229
2020-08-01 1.035124 NA 4.568141 29.13140
2020-09-01 0.976532 NA 5.032091 27.67237
2020-10-01 0.826146 NA 4.817960 25.64155
2020-11-01 1.562452 NA 5.433589 37.49128
2020-12-01 1.728462 NA 5.308677 38.78272
2021-01-01 2.128841 NA 6.040295 39.53195
2021-02-01 3.203027 NA 7.619514 48.47347
2021-03-01 2.187433 NA 6.745144 48.97624
2021-04-01 2.343678 NA 8.529574 48.65092
2021-05-01 2.695230 NA 9.180429 44.65829
2021-06-01 3.173731 NA 13.196301 44.19495
2021-07-01 2.783118 NA 10.567842 41.40504
2021-08-01 2.392505 NA 11.043212 43.55416
JAKK.Adjusted LEU.Adjusted LPI.Adjusted LYLT.Adjusted
2020-01-01 10.20 6.32 34.40 NA
2020-02-01 7.10 7.98 21.60 NA
2020-03-01 3.50 5.07 7.60 NA
2020-04-01 7.90 6.71 21.80 NA
2020-05-01 6.00 8.55 17.00 NA
2020-06-01 8.20 10.04 13.86 NA
2020-07-01 5.46 14.80 15.16 NA
2020-08-01 3.96 11.06 16.35 NA
2020-09-01 3.80 8.37 9.80 NA
2020-10-01 4.56 9.71 8.04 NA
2020-11-01 5.12 14.99 11.81 NA
2020-12-01 4.98 23.13 19.70 NA
2021-01-01 7.81 20.31 23.27 NA
2021-02-01 7.98 23.49 32.59 NA
2021-03-01 7.13 23.72 30.06 NA
2021-04-01 9.39 22.89 40.54 NA
2021-05-01 8.58 22.05 56.16 NA
2021-06-01 11.00 25.38 92.79 NA
2021-07-01 13.12 23.19 55.06 NA
2021-08-01 14.86 28.91 54.03 NA
MPC.Adjusted NCMI.Adjusted NOG.Adjusted PARR.Adjusted
2020-01-01 48.25416 5.976528 16.118214 20.12
2020-02-01 41.98555 6.227575 14.079165 16.59
2020-03-01 21.12313 2.640038 6.408447 7.10
2020-04-01 28.68882 2.740133 8.156205 9.72
2020-05-01 31.42534 2.283444 7.573619 9.29
2020-06-01 33.99266 2.530294 8.156205 8.99
2020-07-01 34.73835 2.104318 7.767815 7.41
2020-08-01 32.24665 3.075542 6.602643 8.68
2020-09-01 27.08773 2.370144 5.573406 6.77
2020-10-01 27.23545 1.734039 3.592614 6.44
2020-11-01 35.89540 2.936538 6.068605 11.39
2020-12-01 38.73664 3.316160 8.505757 13.98
2021-01-01 40.42247 3.717309 9.903965 13.28
2021-02-01 51.15559 4.207601 12.894571 17.67
2021-03-01 50.67979 4.118457 11.729400 14.12
2021-04-01 52.72631 3.841374 14.059744 15.19
2021-05-01 58.55321 4.354157 17.681488 13.92
2021-06-01 57.79054 4.612318 20.167187 16.82
2021-07-01 52.81685 3.165851 16.794699 16.38
2021-08-01 56.69060 2.328902 16.143139 16.49
PBI.Adjusted PBPB.Adjusted PDCO.Adjusted PEI.Adjusted
2020-01-01 3.298086 4.31 19.54100 53.42505
2020-02-01 3.015897 5.00 21.37687 32.00079
2020-03-01 1.821331 3.09 13.73906 13.42805
2020-04-01 3.151617 3.45 16.42577 14.90366
2020-05-01 2.115958 2.10 18.02633 16.67439
2020-06-01 2.370071 2.28 20.14115 20.40000
2020-07-01 3.044630 3.50 24.31587 17.70000
2020-08-01 5.004496 4.28 26.84025 16.50000
2020-09-01 4.882505 3.79 22.30674 8.25000
2020-10-01 4.882505 3.56 23.01914 7.50000
2020-11-01 5.241107 4.72 25.93823 16.50000
2020-12-01 5.712817 4.40 27.68551 15.00000
2021-01-01 8.661967 5.39 29.60097 39.30000
2021-02-01 7.864398 4.99 29.25080 30.00000
2021-03-01 7.684040 5.91 30.08896 28.80000
2021-04-01 6.965993 6.11 30.26789 28.50000
2021-05-01 7.814595 6.89 30.89127 31.35000
2021-06-01 8.230505 7.90 28.85021 37.35000
2021-07-01 7.507872 6.98 29.55271 30.45000
2021-08-01 7.010475 6.91 29.33771 28.95000
PFGC.Adjusted PLAY.Adjusted PRG.Adjusted PRTS.Adjusted
2020-01-01 51.79 43.98767 50.12101 2.55
2020-02-01 42.40 33.01000 33.20855 2.36
2020-03-01 24.72 13.08000 19.23445 1.75
2020-04-01 29.35 14.64000 27.00218 3.21
2020-05-01 26.65 13.19000 31.23318 6.97
2020-06-01 29.14 13.33000 38.41740 8.66
2020-07-01 28.02 12.34000 44.19348 13.75
2020-08-01 36.51 16.63000 47.33563 14.05
2020-09-01 34.62 15.16000 47.97931 10.81
2020-10-01 33.61 17.16000 44.29158 12.69
2020-11-01 43.38 25.32000 53.33466 15.07
2020-12-01 47.61 30.02000 53.87000 12.39
2021-01-01 46.88 34.02000 47.18000 15.71
2021-02-01 54.24 40.61000 50.00000 17.73
2021-03-01 57.61 47.90000 43.29000 14.28
2021-04-01 58.70 45.66000 50.94000 17.28
2021-05-01 50.13 42.28000 52.72000 16.34
2021-06-01 48.49 40.60000 48.13000 20.36
2021-07-01 45.82 33.28000 43.77000 17.61
2021-08-01 50.22 37.42000 47.32000 17.27
REAL.Adjusted SIX.Adjusted SNBR.Adjusted SUP.Adjusted
2020-01-01 14.47 37.75082 51.59 3.20
2020-02-01 13.99 25.02861 44.05 2.60
2020-03-01 7.01 12.41530 19.16 1.20
2020-04-01 11.74 20.01000 29.90 1.41
2020-05-01 13.41 22.98000 31.17 1.29
2020-06-01 12.79 19.21000 41.64 1.70
2020-07-01 13.64 17.39000 46.50 1.50
2020-08-01 16.06 21.73000 48.00 1.54
2020-09-01 14.47 20.30000 48.91 1.25
2020-10-01 12.59 21.62000 63.36 1.23
2020-11-01 13.85 30.73000 69.39 4.99
2020-12-01 19.54 34.10000 81.86 4.09
2021-01-01 23.68 34.20000 107.74 4.62
2021-02-01 25.54 44.60000 137.13 5.71
2021-03-01 22.63 46.47000 143.49 5.68
2021-04-01 24.77 46.98000 111.89 5.02
2021-05-01 17.47 45.43000 111.49 7.00
2021-06-01 19.76 43.28000 109.95 8.62
2021-07-01 16.51 41.55000 99.21 8.50
2021-08-01 12.44 42.24000 92.51 7.38
SWN.Adjusted TSQ.Adjusted TUP.Adjusted ULCC.Adjusted
2020-01-01 1.57 9.493004 6.26 NA
2020-02-01 1.42 8.765043 2.85 NA
2020-03-01 1.69 4.535000 1.62 NA
2020-04-01 3.23 4.820282 3.22 NA
2020-05-01 3.01 4.470000 3.23 NA
2020-06-01 2.56 4.470000 4.75 NA
2020-07-01 2.43 4.440000 15.43 NA
2020-08-01 2.78 4.650000 16.29 NA
2020-09-01 2.35 4.660000 20.16 NA
2020-10-01 2.67 4.520000 31.72 NA
2020-11-01 3.11 6.700000 33.65 NA
2020-12-01 2.98 6.660000 32.39 NA
2021-01-01 3.77 9.980000 30.08 NA
2021-02-01 4.05 10.900000 30.57 NA
2021-03-01 4.65 10.730000 26.41 NA
2021-04-01 4.27 10.300000 24.37 21.04
2021-05-01 5.17 13.830000 25.64 21.32
2021-06-01 5.67 12.750000 23.75 17.04
2021-07-01 4.71 12.290000 20.89 14.74
2021-08-01 4.55 12.860000 23.87 15.33
UNIT.Adjusted VLO.Adjusted WTI.Adjusted WW.Adjusted
2020-01-01 5.356181 72.37434 4.14 32.98
2020-02-01 8.258505 56.87108 2.60 30.00
2020-03-01 5.102333 39.39605 1.70 16.91
2020-04-01 6.139817 55.02071 2.77 25.51
2020-05-01 7.174716 57.87815 2.61 23.90
2020-06-01 8.131347 51.88916 2.28 25.38
2020-07-01 8.757591 49.60434 2.26 25.78
2020-08-01 8.686824 46.39325 2.23 23.48
2020-09-01 9.319314 38.89339 1.80 18.87
2020-10-01 7.925022 34.66468 1.40 21.16
2020-11-01 9.236875 48.27557 1.96 29.51
2020-12-01 10.539742 51.69956 2.17 24.40
2021-01-01 11.214087 51.57161 2.42 26.56
2021-02-01 10.849697 70.35235 3.29 29.49
2021-03-01 10.048039 66.44366 3.59 31.28
2021-04-01 10.529071 68.63371 3.29 27.74
2021-05-01 10.030326 74.60992 3.74 39.30
2021-06-01 9.780952 73.37299 4.85 36.14
2021-07-01 10.966441 62.93275 4.05 30.74
2021-08-01 12.240084 62.31254 3.26 21.65
YELL.Adjusted
2020-01-01 2.26
2020-02-01 2.12
2020-03-01 1.68
2020-04-01 1.72
2020-05-01 1.48
2020-06-01 1.85
2020-07-01 2.72
2020-08-01 4.17
2020-09-01 3.92
2020-10-01 3.92
2020-11-01 6.01
2020-12-01 4.43
2021-01-01 5.20
2021-02-01 5.97
2021-03-01 8.79
2021-04-01 9.17
2021-05-01 6.36
2021-06-01 6.51
2021-07-01 5.20
2021-08-01 6.09
[ reached getOption("max.print") -- omitted 10 rows ]
getSymbols("^GSPC",
from = "2020-01-01", to = "2022-06-30",
periodicity = "monthly",
src = "yahoo")
[1] "^GSPC"
HAVING OUR RETURNS BOTH FROM THE MARKET AND FROM THE STOCKS WE ARE
GOING TO CALCULATE THESE RETURNS BOTH FROM THE MARKET AND FROM THE TOP
50 SHARES.
returnsstock<-diff(log(Ad(prices)))
returnsmkt <-diff(log(Ad(GSPC)))
marketmodel <-function(returnsstock,returnsmkt) {
model<-lm(returnsstock ~ returnsmkt)
sm<-summary(model)
t_critical_value <- abs(qt(0.025,model$df.residual))
result.vector<-c(sm$coefficients[1,c(1,2)],
sm$coefficients[1,1]-t_critical_value*sm$coefficients[1,2],
sm$coefficients[1,1]+t_critical_value*sm$coefficients[1,2],
sm$coefficients[2,c(1,2)],
sm$coefficients[2,1]-t_critical_value*sm$coefficients[2,2],
sm$coefficients[2,1]+t_critical_value*sm$coefficients[2,2],
model$df.residual)
names(result.vector)<-c("b0","seb0","min95CIb0","max95CIb0","b1","seb1","min95CIb1","max95CIb1","N")
return(result.vector)
}
WE CREATE A TABLE FOR STOCK RETURNS WHERE WE KEEP BOTH THE ONE FOR
STOCKS AND ONE FOR THE MARKET AND THEN WE WILL MAKE A LOOP WITH ALL THE
SHARES.
returns.df<- as.data.frame(merge(returnsstock,returnsmkt))
matrixResults<-c()
for(i in 1:49) { #PLACE 2 TO START FROM THE 2ND POSITION
m <- marketmodel(returns.df[,i], returns.df [,50])
matrixResults<-rbind(matrixResults,m)
}
Warning: NaNs produced
WE RENAME THE COLUMNS AND ROWS OF OUR MATRIX
colnames(matrixResults)<-c("b0","seb0","min95CIb0","max95CIb0","b1","seb1","min95CIb1","max95CIb1","N")
rownames(matrixResults)<-TICKERS[2:length(TICKERS)]
matrixResults
b0 seb0 min95CIb0 max95CIb0 b1
CYH -0.1419537864 0.06399941 -0.27326973 -0.0106378415 2.4976175
CCO -0.0493003502 0.05800375 -0.17567967 0.0770789743 1.5481748
FAT 0.0087618663 0.09783052 -0.19196979 0.2094935211 3.0211061
AHT 0.0318790951 0.03226909 -0.03433161 0.0980898018 0.9895821
NCMI -0.0452989297 0.02119662 -0.08879079 -0.0018070674 1.4320989
LYLT -0.0250412796 0.04579577 -0.11935944 0.0692768778 1.8766116
YELL 0.0382686134 0.04343096 -0.05084437 0.1273815923 2.4414455
SWN -0.0540802211 0.03846778 -0.13300958 0.0248491402 3.9467373
SUP -0.0317468417 0.02566923 -0.08441575 0.0209220665 1.4496209
NOG 0.0246185819 0.04266896 -0.06293089 0.1121680557 0.4212653
ATUS -0.0320288049 0.03465191 -0.10312866 0.0390710504 2.2868049
PBPB -0.1558807474 0.06515665 -0.30327533 -0.0084861625 -0.1830671
PARR 0.0007919817 0.04511044 -0.09176699 0.0933509511 2.7528923
FUN -0.0145848443 0.04129652 -0.09931831 0.0701486240 1.8020985
TUP -0.0085271141 0.03082915 -0.07178330 0.0547290691 1.4847649
CWH -0.2386435590 0.24085026 -3.29893621 2.8216490952 2.8368230
CRK 0.0303594690 0.04532015 -0.06262980 0.1233487407 1.6336378
WTI -0.2052544692 NaN NaN NaN -2.5876558
AMC 0.0058596476 0.03266756 -0.06116865 0.0728879494 2.3097179
DRCT -0.0206632584 0.03175240 -0.08581381 0.0444872951 2.5705472
OVV -0.0026982214 0.05427240 -0.11405598 0.1086595400 1.8388274
REAL 0.0369873312 0.04013638 -0.04536573 0.1193403888 1.8273659
PDCO 0.0020110744 0.06067021 -0.12247391 0.1264960540 3.9790728
LPI -0.2572774562 0.21131909 -0.84399330 0.3294383870 2.5490468
COMM 0.0068600337 0.02544675 -0.04535239 0.0590724527 2.0089617
PFGC -0.0762451136 0.04819846 -0.17514019 0.0226499630 2.0116977
WW 0.0013934057 0.04023295 -0.08115779 0.0839445978 2.4492897
ULCC -0.0232708950 0.03523568 -0.09556854 0.0490267538 2.6227168
ARCH -0.0087862311 0.03615685 -0.08297397 0.0654015069 1.9902720
PBI -0.0144304767 0.04340263 -0.10469118 0.0758302278 1.5114620
TSQ 0.0076167453 0.01709564 -0.02746060 0.0426940911 1.2459092
CAR -0.1136801386 0.06120470 -0.23926182 0.0119015390 3.2952068
UNIT -0.0130566864 0.02490239 -0.06415218 0.0380388058 1.6223054
SIX -0.0241597313 0.03437526 -0.09469194 0.0463724799 2.5400575
MPC -0.0535456652 0.02432222 -0.10345074 -0.0036405911 2.7600043
CURV 0.0223090411 0.04288591 -0.06568557 0.1103036507 2.2133187
LEU -0.0741519767 0.03913853 -0.15445761 0.0061536532 2.4405340
DK -0.0353634536 0.02716883 -0.09110929 0.0203823814 2.9480729
BATL -0.0308007200 0.03708926 -0.10690159 0.0453001454 2.3883857
PLAY -0.0104932499 0.05545738 -0.12428239 0.1032958935 3.2168846
SNBR 0.0423150924 0.03567262 -0.03087908 0.1155092648 0.9644872
EMBC -0.0151415772 0.02907338 -0.07479523 0.0445120788 1.8210608
EGY -0.0158968693 0.06757812 -0.15455571 0.1227619699 2.9597106
CURO -0.0570248268 0.02388737 -0.10907093 -0.0049787263 0.1062374
PRG 0.0097375075 0.03063161 -0.05362880 0.0731038189 1.3683876
JAKK 0.0032877064 0.02517468 -0.04836647 0.0549418782 1.7068294
VLO -0.0093003772 0.04210337 -0.09568936 0.0770886057 1.9510561
PRTS -0.0670729822 0.03307249 -0.13493214 0.0007861707 1.8990660
ALHC -0.0040413029 0.04203140 -0.09028260 0.0821999975 2.3544551
seb1 min95CIb1 max95CIb1 N
CYH 1.0856289 0.27009107 4.725144 27
CCO 1.2151177 -1.09933925 4.195689 12
FAT 1.6595097 -0.38392651 6.426139 27
AHT 0.5473841 -0.13355724 2.112721 27
NCMI 0.3595605 0.69434177 2.169856 27
LYLT 0.7885278 0.25260822 3.500615 25
YELL 0.7367241 0.92981253 3.953079 27
SWN 0.6525330 2.60785010 5.285625 27
SUP 0.4354299 0.55619258 2.343049 27
NOG 0.7237981 -1.06384585 1.906376 27
ATUS 0.5878041 1.08073042 3.492879 27
PBPB 1.2297022 -2.96484678 2.598713 9
PARR 0.7652132 1.18280455 4.322980 27
FUN 0.7005174 0.36475564 3.239441 27
TUP 0.5229581 0.41174343 2.557786 27
CWH 3.2816831 -38.86091441 44.534560 1
CRK 0.7687706 0.05625078 3.211025 27
WTI NaN NaN NaN 0
AMC 0.5541434 1.17270963 3.446726 27
DRCT 0.5386195 1.46539141 3.675703 27
OVV 0.9206285 -0.05014627 3.727801 27
REAL 0.6808378 0.43040211 3.224330 27
PDCO 1.0291552 1.86742073 6.090725 27
LPI 3.5443807 -7.29173173 12.389825 4
COMM 0.4316560 1.12327685 2.894647 27
PFGC 0.8175957 0.33412987 3.689265 27
WW 0.6824758 1.04896493 3.849614 27
ULCC 0.5977067 1.39632408 3.849110 27
ARCH 0.6133326 0.73181746 3.248727 27
PBI 0.7384466 -0.02422179 3.047146 21
TSQ 0.2899951 0.65088845 1.840930 27
CAR 1.0382219 1.16495132 5.425462 27
UNIT 0.4224220 0.75556708 2.489044 27
SIX 0.5831113 1.34361208 3.736503 27
MPC 0.4125804 1.91345922 3.606549 27
CURV 0.7274782 0.72065669 3.705981 27
LEU 0.6639111 1.07830094 3.802767 27
DK 0.4608678 2.00245036 3.893696 27
BATL 0.6291490 1.09747854 3.679293 27
PLAY 0.9407295 1.28666714 5.147102 27
SNBR 0.6051185 -0.27711341 2.206088 27
EMBC 0.4931749 0.80914939 2.832972 27
EGY 1.1463348 0.60762586 5.311795 27
CURO 0.5004152 -0.98407367 1.196549 12
PRG 0.5103685 0.31260997 2.424165 23
JAKK 0.4270408 0.83061410 2.583045 27
VLO 0.7142040 0.48563050 3.416482 27
PRTS 0.5610123 0.74796393 3.050168 27
ALHC 0.7129831 0.89153465 3.817376 27
NOW WE HAVE OUR BETAS THAT WILL HELP US NOW SELECT THE 10 COMPANIES.
NEW DATA FRAME FOR THE RESULTS
results.df<-as.data.frame(matrixResults)
What do you need to know to estimate the market risk of each stock?
For your selection criteria, how would you use the beta and alpha
coefficients (along with their corresponding standard errors and p
values) to select the best stocks for your portfolio? Which are your
main arguments for your selection criteria? Clearly state your
assumptions about possible future market conditions, and also your line
of reasoning. You have to justify your criteria using 1 or 2 references.
Before we can list all of the things we need to know to estimate the
market risk of each stock we need to define market risk. Adam Hayes
Ph.D. defines market risk as “the possibility that an individual or
other entity will experience losses due to factors that affect the
overall performance of investments in the financial markets.” (A. Hayes,
06.30.22) Taking a step back, the possibility of experiencing loss is
given by the factors that affect the overall performance of investments
in financial markets. So what factors come into play? Remember that
market risk is the same as systematic risk, and this can’t be reduced by
diversifying. “Sources of market risk include recessions, political
turmoil, changes in interest rates, natural disasters, and terrorist
attacks. Systematic, or market risk, tends to influence the entire
market at the same time.” (A. Hayes, 06.30.22) So now we know what
variables are needed to take into account when calculating systematic
risk. But how would we use the beta and alpha coefficients along with
their standard errors and p values to select the best stocks for our
portfolio? Pretty easy, Beta (β) is a measure of systematic risk of a
portfolio compared to the market as a whole (usually taking S&P 500
into consideration). Stocks with betas higher than 1.0 can be
interpreted as more volatile than the S&P 500. We used Beta for the
Capital Asset Pricing Model, the CAPM explains the relationship between
systematic risk and expected return for assets. “CAPM is widely used as
a method for pricing risky securities and for generating estimates of
the expected returns of assets, considering both the risk of those
assets and the cost of capital.” (W. Kenton, 06.30.22) What about Alpha
coefficients? Alpha is a term used in investing to describe an
investment’s ability to beat the market. Alpha is thus referred to as
“excess return” or “abnormal rate of return,” which would imply that
markets are efficient, and so there is no way to systematically earn
returns that exceed the broad market as a whole. “Alpha is often used in
conjunction with beta (the Greek letter β), which measures the broad
market’s overall volatility or risk, known as systematic market risk.”
(J. Chen, 03.19.22) Alpha is one of the five popular technical
investment risk ratios. The others being Beta, Standard Deviation,
R-Squared and the Sharpe Ratio. These statistical measurements are used
in Modern Portfolio Theory. These past indicators are intended to help
investors determine the risk-return profile of an investment. Having
remembered this, we can say that finding a combination of low Beta
values, high Alpha values, and a P-Value that determines the likelihood
that our observed outcome is not the result of chance. Naturally, our
data tool ( R ) did most of the statistical work for us.
sOURCES: https://www.investopedia.com/terms/p/p-value.asp https://www.investopedia.com/terms/m/modernportfoliotheory.asp
https://www.investopedia.com/terms/a/alpha.asp#:~:text=Alpha%2C%20often%20considered%20the%20active,index%20is%20the%20investment’s%20alpha.
https://www.investopedia.com/terms/b/beta.asp https://www.investopedia.com/terms/m/marketrisk.asp
–
AUTOMATICALLY SELECTING STOCKS:
selection.df <-results.df[order(results.df$b0,decreasing=TRUE),]
selection.df <-selection.df[selection.df$N>20,]
selection.df <-selection.df[1:11,]
selection.df <-selection.df[1:11,]
uselection.df <-selection.df [-7,]
uselection.df
ALTHOUGH B0 DOESN’T LOOK AS TEMPTING ON AVERAGE, ITS THE MAX B0 THAT
LOOKS PROMISING WITH THIS SELECTION. ALMOST ALL COMPANIES ARE 4% ABOVE
MARKET RETURNS, WITH SOME GOING ALMOST 9% HIGHER RETURNS THAN THE
MARKET.
FIRST WE SELECT AND ORDER THE DATA FROM HIGHEST TO LOWEST ACCORDING
TO B0 SINCE THIS BETA REPRESENTS THE RETURNS OF THE SHARE WHEN MARKET
RETURNS ARE 0, THEN ANY DATA GREATER THAN 0, AFTER THIS WE ORDER THEM
FROM LOWEST TO HIGHEST DEPENDING ON B1 WHICH MEASURES THE RISK OF THE
ACTION BY COMPARISON WITH THE MARKET.
PORTAFOLIO OPTIMIZATION
stocksport <- as.list(rownames(uselection.df))
objstock <- lapply(stocksport,get)
prices <- do.call (merge, objstock)
prices1 <- Ad(prices)
na.omit(prices1)
SNBR.Adjusted YELL.Adjusted REAL.Adjusted AHT.Adjusted
2020-01-01 51.59 2.26 14.47 246.00
2020-02-01 44.05 2.12 13.99 216.00
2020-03-01 19.16 1.68 7.01 74.00
2020-04-01 29.90 1.72 11.74 82.00
2020-05-01 31.17 1.48 13.41 69.00
2020-06-01 41.64 1.85 12.79 72.00
2020-07-01 46.50 2.72 13.64 39.20
2020-08-01 48.00 4.17 16.06 30.80
2020-09-01 48.91 3.92 14.47 16.50
2020-10-01 63.36 3.92 12.59 12.90
2020-11-01 69.39 6.01 13.85 26.50
2020-12-01 81.86 4.43 19.54 25.90
2021-01-01 107.74 5.20 23.68 29.20
2021-02-01 137.13 5.97 25.54 34.30
2021-03-01 143.49 8.79 22.63 29.50
2021-04-01 111.89 9.17 24.77 27.40
2021-05-01 111.49 6.36 17.47 40.50
2021-06-01 109.95 6.51 19.76 45.60
2021-07-01 99.21 5.20 16.51 16.20
2021-08-01 92.51 6.09 12.44 15.45
2021-09-01 93.48 5.65 13.18 14.72
2021-10-01 88.34 8.75 13.03 14.13
2021-11-01 79.78 13.16 15.57 10.65
2021-12-01 76.60 12.59 11.61 9.60
2022-01-01 71.50 10.44 9.45 7.79
2022-02-01 65.70 9.01 8.91 8.61
2022-03-01 50.71 7.01 7.26 10.20
2022-04-01 40.56 4.48 5.42 7.05
2022-05-01 45.93 3.78 3.28 5.64
2022-06-01 30.95 2.93 2.49 5.98
CRK.Adjusted NOG.Adjusted PRG.Adjusted FAT.Adjusted
2020-01-01 5.492453 16.118214 50.12101 4.199655
2020-02-01 5.949329 14.079165 33.20855 3.590273
2020-03-01 5.353403 6.408447 19.23445 2.050310
2020-04-01 7.607990 8.156205 27.00218 3.033530
2020-05-01 5.323607 7.573619 31.23318 2.910405
2020-06-01 4.350261 8.156205 38.41740 3.078141
2020-07-01 5.323607 7.767815 44.19348 2.855087
2020-08-01 5.720891 6.602643 47.33563 4.568141
2020-09-01 4.350261 5.573406 47.97931 5.032091
2020-10-01 5.273946 3.592614 44.29158 4.817960
2020-11-01 4.836934 6.068605 53.33466 5.433589
2020-12-01 4.340328 8.505757 53.87000 5.308677
2021-01-01 4.519106 9.903965 47.18000 6.040295
2021-02-01 5.671230 12.894571 50.00000 7.619514
2021-03-01 5.502385 11.729400 43.29000 6.745144
2021-04-01 5.452724 14.059744 50.94000 8.529574
2021-05-01 5.591774 17.681488 52.72000 9.180429
2021-06-01 6.624712 20.167187 48.13000 13.196301
2021-07-01 6.038718 16.794699 43.77000 10.567842
2021-08-01 5.869872 16.143139 47.32000 11.043212
2021-09-01 10.279726 20.811037 42.01000 8.529235
2021-10-01 9.802984 22.571930 40.45000 9.233459
2021-11-01 8.035070 19.862518 45.12000 9.224217
2021-12-01 8.035070 20.057440 45.11000 9.900928
2022-01-01 7.727176 23.011507 39.81000 9.872880
2022-02-01 8.243645 24.537781 30.64000 6.890447
2022-03-01 12.961393 27.580544 28.77000 7.076088
2022-04-01 16.914370 24.562624 26.47000 5.628706
2022-05-01 19.168957 32.143803 29.19000 6.565248
2022-06-01 11.997979 24.837946 16.50000 7.203790
TSQ.Adjusted COMM.Adjusted
2020-01-01 9.493004 12.185
2020-02-01 8.765043 11.010
2020-03-01 4.535000 9.110
2020-04-01 4.820282 11.010
2020-05-01 4.470000 10.310
2020-06-01 4.470000 8.330
2020-07-01 4.440000 9.280
2020-08-01 4.650000 10.300
2020-09-01 4.660000 9.000
2020-10-01 4.520000 8.900
2020-11-01 6.700000 11.850
2020-12-01 6.660000 13.400
2021-01-01 9.980000 14.690
2021-02-01 10.900000 14.590
2021-03-01 10.730000 15.360
2021-04-01 10.300000 16.450
2021-05-01 13.830000 20.310
2021-06-01 12.750000 21.310
2021-07-01 12.290000 21.160
2021-08-01 12.860000 15.800
2021-09-01 13.070000 13.590
2021-10-01 13.320000 10.710
2021-11-01 12.650000 9.960
2021-12-01 13.330000 11.040
2022-01-01 13.180000 9.390
2022-02-01 11.410000 9.540
2022-03-01 12.790000 7.880
2022-04-01 10.900000 6.030
2022-05-01 9.850000 7.510
2022-06-01 8.190000 6.120
portReturns = exp(colMeans(prices1))-1
portReturns
SNBR.Adjusted YELL.Adjusted REAL.Adjusted AHT.Adjusted CRK.Adjusted
7.429415e+30 2.638067e+02 1.072317e+06 9.974715e+17 1.654729e+03
NOG.Adjusted PRG.Adjusted FAT.Adjusted TSQ.Adjusted COMM.Adjusted
4.261508e+06 4.238040e+17 7.828144e+02 1.150293e+04 1.430324e+05
NOW WE WILL GET THE COVARIANCE
COVport = var(prices1)
COVport
SNBR.Adjusted YELL.Adjusted REAL.Adjusted AHT.Adjusted
SNBR.Adjusted 1079.39384 58.3345192 145.941633 -481.959941
YELL.Adjusted 58.33452 10.0666024 3.799323 -83.759241
REAL.Adjusted 145.94163 3.7993226 34.035936 30.418805
AHT.Adjusted -481.95994 -83.7592408 30.418805 3135.682237
CRK.Adjusted -30.78002 0.9781159 -13.998539 -60.107896
NOG.Adjusted 18.43858 10.3127527 -20.126076 -98.930083
PRG.Adjusted 219.81018 10.5004403 45.349135 -2.901765
FAT.Adjusted 60.94383 6.3384828 3.103899 -69.364930
TSQ.Adjusted 68.23542 7.8210760 1.740048 -43.932897
COMM.Adjusted 101.73082 2.5702768 16.771052 8.446158
CRK.Adjusted NOG.Adjusted PRG.Adjusted FAT.Adjusted
SNBR.Adjusted -30.7800221 18.438575 219.810177 60.943826
YELL.Adjusted 0.9781159 10.312753 10.500440 6.338483
REAL.Adjusted -13.9985386 -20.126076 45.349135 3.103899
AHT.Adjusted -60.1078961 -98.930083 -2.901765 -69.364930
CRK.Adjusted 13.2416046 22.399819 -21.039507 1.695349
NOG.Adjusted 22.3998187 58.712845 -26.505718 12.272371
PRG.Adjusted -21.0395074 -26.505718 104.883352 9.560022
FAT.Adjusted 1.6953491 12.272371 9.560022 8.016268
TSQ.Adjusted 4.3244185 19.950317 6.000545 8.331720
COMM.Adjusted -6.5124593 -2.942257 25.307501 6.534060
TSQ.Adjusted COMM.Adjusted
SNBR.Adjusted 68.235423 101.730818
YELL.Adjusted 7.821076 2.570277
REAL.Adjusted 1.740048 16.771052
AHT.Adjusted -43.932897 8.446158
CRK.Adjusted 4.324419 -6.512459
NOG.Adjusted 19.950317 -2.942257
PRG.Adjusted 6.000545 25.307501
FAT.Adjusted 8.331720 6.534060
TSQ.Adjusted 11.956896 5.939122
COMM.Adjusted 5.939122 16.746720
AGGRESSIVE PORTFOLIO
FOR THIS CASE WE WILL USE THE TANGENCY PORTFOLIO FUNCTION BECAUSE IT
WOULD CALCULATE AN OPTIMAL PORTFOLIO BUT FIRST WE WILL NEED THE RISK
FREE RATE WHICH TODAY IS AT 4 TBILLS3MONTH.
getSymbols("TB3MS", periodicity = "monthly",src = "FRED")
[1] "TB3MS"
rfrate <- TB3MS
rfrate = rfrate/100/12
rfrate=(rfrate[index(GSPC)])
#["2020-01-01/2022-06-30",]
SINCE WE HAVE THE RFR MONTHLY, WE CAN CONTINUE WORKING ON THE AGGRO
PORTFOLIO
rfrate1 <-rfrate [nrow(rfrate),]
agrport <- tangency.portfolio(portReturns, COVport, 0.001241667, short=FALSE)
# WE TRIED TO INSERT THE VARIABLE FOR RFRATE 1 BUT IT LEFT US WITH AN ERROR, WE PUT THE RISK FREE AS DATA
agrport
Call:
tangency.portfolio(er = portReturns, cov.mat = COVport, risk.free = 0.001241667,
shorts = FALSE)
Portfolio expected return: -9.874955e+29
Portfolio standard deviation: 1.224806
Portfolio weights:
SNBR.Adjusted YELL.Adjusted REAL.Adjusted AHT.Adjusted CRK.Adjusted
-0.1329 -0.1274 0.5013 -0.0203 0.0384
NOG.Adjusted PRG.Adjusted FAT.Adjusted TSQ.Adjusted COMM.Adjusted
-0.0487 0.0130 -0.0539 0.7555 0.0750
Agrisk= (agrport$sd*sqrt(12))-4
Agrisk
[1] 0.2428526
AgrER= (agrport$er*12)*-1
AgrER
[1] 1.184995e+31
tanportweights<-getPortfolio(er=portReturns,cov.mat=COVport,weights=agrport$weights)
plot(tanportweights,col="purple")

GIVEN THE OBSERVATIONS, CONTEMPLATING BOTH THE RISK AND THE RETURN OF
THE AGGRESSIVE PORTFOLIO, WE CAN SAY THAT THIS PORTFOLIO IS 24% RISKIER
THAN THE MARKET AND OFFERS A POSITIVE 118% RETURN COMPARED TO THE MARKET
AVERAGE.
CONSERVATIVE PORTFOLIO
gm_portfolio = globalMin.portfolio(portReturns,COVport, shorts = FALSE)
gm_portfolio
Call:
globalMin.portfolio(er = portReturns, cov.mat = COVport, shorts = FALSE)
Portfolio expected return: 1.372022e+16
Portfolio standard deviation: 1.575464
Portfolio weights:
SNBR.Adjusted YELL.Adjusted REAL.Adjusted AHT.Adjusted CRK.Adjusted
0.0000 0.2192 0.1727 0.0138 0.4750
NOG.Adjusted PRG.Adjusted FAT.Adjusted TSQ.Adjusted COMM.Adjusted
0.0000 0.0000 0.0000 0.0000 0.1194
GMRISK= (gm_portfolio$sd*sqrt(12))-5.3
GMRISK
[1] 0.1575686
GMER = (gm_portfolio$er*12)
GMER
[1] 1.646426e+17
conserv_port_weights<-getPortfolio(er=portReturns,cov.mat=COVport,weights=gm_portfolio$weights)
plot(conserv_port_weights,col="BROWN")

GIVEN THE OBSERVATIONS, CONTEMPLATING BOTH THE RISK AND THE RETURN OF
THE CONSERVATIVE PORTFOLIO, WE CAN SAY THAT THIS PORTFOLIO A BIT MORE
RISKY COMPARED TO THE MARKET, BUT ONLY BY 15%. ON THE OTHER HAND, IT
OFFERS RETURNS 164% HIGHER THAN THE MARKET.
HOLDING PERIOD RETURN
for (t in stocksport) {
try(getSymbols(t,
from = "2021-06-01", to = "2022-06-01",
periodicity = "monthly",
src = "yahoo") )
}
portlist2 <- lapply(stocksport, get)
prices2 <- do.call(merge, portlist2)
bestlist2=as.list(stocksport)
do.call(rm,bestlist2)
prices2.df <- as.data.frame(Ad(prices2))
colnames(prices2.df)<- stocksport
HPR.df <- prices2.df[nrow(prices2.df),] / prices2.df[1,] - 1
HPR.df
# WE'LL CONVERT THE TABLE INTO A MATRIX
HPRm <-as.matrix(HPR.df)
LETS GO AHEAD AND USE OUR AGRO PORTFOLIO
AgrPortHPR<- t(agrport$weights ) %*% t(HPRm) + 1
AgrPortHPR
2022-05-01
[1,] 0.5757731
THE HPR OF THE PERIOD OF OUR AGGRESSIVE PERIOD WAS 57.5%
AND NOW OUR CONSERVATIVE PORTFOLIO
gmvPortHPR<- t(gm_portfolio$weights ) %*% t(HPRm)
gmvPortHPR
2022-05-01
[1,] 0.5740406
THE HPR OF OUR AGGRESIVE PORTFOLIO HAS BEEN THE BEST, WITH A RETURN
OF 57.5% ALTHOUGH THE CONSERVATIVE PORTFOLIO FOLLOWS CLOSELY AND HAS
LESSER RISK.
market.df <- as.data.frame(Ad(GSPC$GSPC.Adjusted))
HPRmkt<-last(market.df$GSPC.Adjusted)/first(market.df$GSPC.Adjusted) - 2
HPRmkt
[1] -0.826428
THE HOLDING PERIOD RETURN FOR THE MARKET IS WORSE THAN THE AGGRESIVE
PORTFOLIO BY 18%.
OPTIONS
In the derivatives market there are contracts that, due to their way
of operating, are divided into 2, standardized and non-standardized
contracts, among the standardized there are 3 forms of contracts
regularized by MEXDER, FUTURES, OPTIONS AND SWAPS, for the realization
In this essay we will focus on the options, what they are, what they are
for and how you can take advantage of these contracts when creating an
optimal portfolio.
What are they? Types of contracts:
Options are standardized contracts in which you have the right to buy
or sell a certain amount of a fixed-price asset over a certain period of
time, but you do not get the obligation to exchange an asset at a
certain price in a certain period of time. established. Within the
options there are more types of contracts with which specific strategies
can be formed depending on how the market fluctuates. Within these
contracts we find the CALL purchase option and the PUT purchase
option.
First let’s look at the CALL purchase option, where you have the
buyer and a seller, where the buyer has the right to buy and the seller
has the obligation to sell, in the same way there are positions called
LONG CALL, where this is covers the risk of the possible rise of the
underlying and the SHORT CALL where the possible fall of the underlying
is covered. Finally, it is necessary to mention the use of a PREMIUM in
these operations, where in the case of the buyer in a LONG CALL there is
a loss of the premium, which is the gain of the seller with a SHORT CALL
position.
Continuing we have the PUT sale option, where in the same way we have
2 positions called LONG PUT, where a possible risk of the fall of an
underlying is covered and a SHORT PUT where a possible risk of an
underlying rise is covered. In this case, the buyer has the right to
sell and the seller has the obligation to buy. In the case of the
premium, something similar to the CALL can be observed, having a loss of
the premium on the buyer’s side and a gain of the premium on the
seller’s position.
TYPES OF EXERCISE IN THE CLASSIFICATION OF OPTIONS: Within the
purchase operations (LONG CALL) and sales (LONG PUT) we have different
classifications of exercises depending on whether the exercise price
(STRIKE) is greater than, equal to or less than the underlying price
(SPOT), giving an example for a better understanding we have the
following data:
MATURITY RATE, BINOMINAL MODEL AND BLACK AND SCHOLES: The Black &
Scholes model allows obtaining theoretical values for EUROPEAN PUT AND
CALL OPTIONS on shares that do not pay dividends. The key argument is
that investors could safely offset long positions with short positions
in shares and continually adjust the coverage ratio (the delta value) if
necessary. Assuming that the underlying price follows a random process
and using stochastic calculation methods, the option price can be
calculated where there are no arbitrage possibilities.
Finally, the BINOMINAL model assumes that there are only two possible
values for the exchange rate in the next period: Up or Down. The
advantage is that valuation using the binomial model allows an easy
understanding of the logic behind option valuations. It also allows
laying the foundations for more complex valuations such as the
Black-Scholes. It can be used satisfactorily when the probabilities of
an increase in the exchange rate vary over time. Regarding its
limitations, it assumes that the variations in the exchange rate are
discrete in time.
INVESTMENT STRATEGIES FOR OPTIONS: Options trading strategies refer
to buying PUTS or CALLS or selling CALLS or PUTS or both together in
order to limit losses and make unlimited profits. Basically, it is about
using one or several combinations to obtain the best possible result
based on our defined parameters. Options trading strategies can be
classified as bullish, bearish, or neutral. To carry out this research,
we compiled 10 types of trading strategies in order to better mitigate
the risk in our portfolios.
To begin with, we will focus on bullish option strategies, the first
is called “BULL CALL SPREAD”, These option strategies involve buying an
“AT THE MONEY” option and selling an “OUT OF THE MONEY” option. ”, in
this strategy it is important to note that both call options must have
the same underlying stock and the same expiration date. Here you make a
profit when the underlying share price rises, which is equal to the
spread minus the net debit, and you make a loss when the share price
falls, which is equal to the net debit. The net debit is equal to the
premium paid for a lower strike minus the premium received for a higher
strike. The spread refers to the difference between the highest and
lowest strike price.
The second strategy is called BULL PUT SPREAD. This strategy is used
by option traders when they are less optimistic about the movement of
the underlying asset, in this strategy you buy a put option Out of the
money and sell 1 put option in the money. Here it is formed by a net
credit received that incurs a benefit at the time of the price increase
and on the other hand the potential loss and occurs when the share falls
below the exercise price of the long put option.
The third strategy refers to the CALL RATIO BACK SRPEAD, this
strategy is one of the easiest for the investing public, in this
strategy the operators can obtain good margins when the market is
bullish and in the same way when the market goes down, the loss can
occur only if the market is stable for a long time or within a specific
range. This strategy consists of buying 2 OTM options and selling one
ITM call option.
The fourth strategy is called Synthetic Call, this is one of the
bullish options strategies used for those who have an optimistic view of
stocks in the long term, but who are aware of the risk when they fall.
The strategy consists of buying put options on the stock that we have
and on which we have a bullish view. If the price of the underlying goes
up, we will make a profit, while if the price goes down, the loss will
be limited to the premium paid for the put option. This strategy is
similar to the strategy of protection put options.
Now we move on to the “BEARISH” or bearish options strategies, in the
first strategy that we will review will be the “BEAR CALL SPREAD”, this
strategy consists of buying an OTM call option or a higher exercise
price and selling an option of purchase at a lower strike price, both
call options must have the same underlying security and also the same
expiration date.
The following strategy is called “BEAR PUT SPREAD” and consists of
buying the ITM put option and selling the OTM put option. Note that both
put options must have the same underlying stock and the same expiration
date.
The seventh strategy is called “STRIP” It must be taken into account
that these options must be purchased on the same underlying, and also
with the same exercise price and the same expiration date, investors
obtain benefits when the underlying share price makes a strong move up
or down at expiration, but you usually make big profits when prices move
down.
“SYNTHETIC PUT” The benefits of this strategy are obtained when there
is a decrease in the price of the underlying stock, which is why this
strategy is also known as a synthetic long put. The synthetic long put
is so named because this strategy has the same profit potential as the
long put.
Now we go with the options strategies that are considered more
neutral when looking at the market, “long and short straddles.” This
strategy consists of buying the ATM Call and Put options. It must be
taken into account that both options must belong to the same underlying,
they must have the same expiration and also belong to the same
strike.
“LONG AND SHORT BUTTERFLY “This strategy consists of buying an ITM
call option, writing two ATM call options, and then buying an OTM call
option. “The short butterfly” consists of selling one call option
in-the-money, buying two call options at-the-money and selling one call
option out-of-the-money.
REFERENCES:
12 Powerful Options Strategies Every Trader Should Know. (2021,
September 3). https://www.elearnmarkets.com/blog/12-must-know-option-trading-strategies/
Downey, L. (2018, October 12). 10 options strategies to know.
Investopedia. https://www.investopedia.com/trading/options-strategies/
Best option trading strategies. (2022, July 14). Groww. https://groww.in/blog/best-option-trading-strategies
Options Strategy Using Black&Scholes Pricing Model in R
The Black Scholes model is an equation that is used to determine the
price of certain financial assets, WITH THE BLACK SCHOLES WE WILL BE
ABLE TO ESTIMATE THE CURRENT VALUE OF A EUROPEAN OPTION FOR THE PURCHASE
(CALL) OR SELL (PUT) OF SHARES AT A FUTURE DATE THAN VARIABLES NEEDED
FOR THE FUNCTION ARE:
S = Stock price
K = Strike price at expiration (European)
r = risk free rate
T = Time to maturity
sig = Volatility of the underlying asset (depends on the price,
evolution and price of another asset)
SINCE WE HAVE THESE 5 VARIABLES TO APPLY THE BLACK AND SCHOLES
FUNCTION WITH CONDITIONALS DEPENDING ON WHETHER IT WILL BE A CALL OR PUT
AND WE WILL CALCULATE 2 PARAMETERS ON D1 AND D2 FOR BOTH UNDERLYING
ASSETS
BlackScholes <- function(S, K, r, T, sig, type){
if(type=="C"){
d1 <- (log(S/K) + (r + sig^2/2)*T) / (sig*sqrt(T))
d2 <- d1 - sig*sqrt(T)
value <- S*pnorm(d1) - K*exp(-r*T)*pnorm(d2)
return(value)}
if(type=="P"){
d1 <- (log(S/K) + (r + sig^2/2)*T) / (sig*sqrt(T))
d2 <- d1 - sig*sqrt(T)
value <- (K*exp(-r*T)*pnorm(-d2) - S*pnorm(-d1))
return(value)}
}
WE USE THE PNORM COMMAND TO SIMULATE A NORMAL DISTRIBUTION FOR OUR
PARAMETERS d1 and d2 AND BE ABLE TO CALCULATE THE VALUES OF BOTH THE
CALL AND THE PUT NOW WE WILL USE THE DATA FROM OUR AGGRESSIVE PORTFOLIO
TO CALCULATE THIS, WE WILL USE OUR MOST RISKY STOCK IN THIS TABLE (SNBR)
AND WE WILL ASSIGN A LITTLE HIGHER STRIKE PRICE THAN THE STOCK
C <- BlackScholes(20.167,24,0.0412,1, 58.712847,"C")
P <- BlackScholes(20.167,24,0.0412,1, 58.712847,"P")
THE ESTIMATED CURRENT VALUES OF THE OPTION FOR THE PURCHASE IS 20.16
AND FOR THE SALE CAME 23.03
Options Strategy Using Sharpe Ratio
To cover the portfolio, we must choose three strongly related stocks.
Two independent actions have no way of protecting each other. Since
stocks in the same industry tend to have a stronger relationship, we
chose four stocks in the information technology industry, namely GOOGLe,
IBM, and Apple.
getSymbols("GOOGL",src="yahoo")
[1] "GOOGL"
getSymbols("IBM",src="yahoo")
[1] "IBM"
getSymbols("AAPL",src="yahoo")
[1] "AAPL"
barChart(GOOGL)

barChart(IBM)

barChart(AAPL)

It’s not hard to see that all three stocks experienced significant
gains after 2007.
Modern portfolio theory
Modern Portfolio Theory (MPT) is a theory of finance that attempts to
maximize expected portfolio return for a given amount of portfolio risk,
or equivalently, minimize risk for a given level of expected return by
carefully choosing the proportions of various assets.
If we have three risky assets and we want to put them in a portfolio
so that given a target return, risk is minimized, or given risk
preference, we maximize return. Both methods try to maximize the Sharpe
ratio.
Here we choose the first method, ie. the “Minimum Variation
Portfolio”.
Lagrange multipliers and minimum variance portfolio
In mathematical optimization, the Lagrange multipliers method (named
after Joseph Louis Lagrange) is a strategy for finding the local maxima
and minima of a function subject to equality constraints.
For example, consider the optimization problem
minimize var(portfolio(r1,r2,r3,cov,w1,w2,w3))
subject to
r1+r2+r3=target_return
w1+w2+w3=1
With R programming and Lagrange multipliers, we can solve the problem
with the following function. This function calculates the best ratios
between three stocks, given the target daily return, expected daily
returns, and the covariance matrix of the three stocks’ daily
returns.
min_variance_portfolio <-function(er, covmat, target.return)
{
# compute minimum variance portfolio subject to target return
#
# inputs:
# er N x 1 vector of expected returns
# covmat N x N covariance matrix of returns
# target.return scalar, target expected return
# compute efficient portfolio
#
ones <- rep(1, length(er))
top <- cbind(2*covmat, er, ones)
bot <- cbind(rbind(er, ones), matrix(0,2,2))
A <- rbind(top, bot)
b.target <- as.matrix(c(rep(0, length(er)), target.return, 1))
x <- solve(A, b.target)
w <- x[1:length(er)]
}
The output will be the optimal ratio that maximizes the Sharpe
ratio.
Trading Strategy
data_GOOGL<-data.frame(GOOGL)
data_GOOGL$Date<-as.Date(rownames(data_GOOGL))
data_GOOGL$Daily_Return=c(NA,diff(log(data_GOOGL$GOOGL.Close)))
names(data_GOOGL)<-c("Open","High","Low","Close","Volume","Date","Daily_Return")
rownames(data_GOOGL) <- NULL
data_GOOGL<-subset(data_GOOGL,Date>=as.Date("2018-10-01")&Date<=as.Date("2020-12-31"),select=c("Date","Open","Close","Daily_Return"))
data_IBM<-data.frame(IBM)
data_IBM$Date<-as.Date(rownames(data_IBM))
data_IBM$Daily_Return=c(NA,diff(log(data_IBM$IBM.Close)))
names(data_IBM)<-c("Open","High","Low","Close","Volume","Date","Daily_Return")
rownames(data_IBM) <- NULL
data_IBM<-subset(data_IBM,Date>=as.Date("2018-10-01")&Date<=as.Date("2020-12-31"),select=c("Date","Open","Close","Daily_Return"))
data_AAPL<-data.frame(AAPL)
data_AAPL$Date<-as.Date(rownames(data_AAPL))
data_AAPL$Daily_Return=c(NA,diff(log(data_AAPL$AAPL.Close)))
names(data_AAPL)<-c("Open","High","Low","Close","Volume","Date","Daily_Return")
rownames(data_AAPL) <- NULL
data_AAPL<-subset(data_AAPL,Date>=as.Date("2018-10-01")&Date<=as.Date("2020-12-31"),select=c("Date","Open","Close","Daily_Return"))
GOOGL1<-subset(data_GOOGL,Date>=as.Date("2018-01-01")&Date<=as.Date("2020-12-31"))
AAPL1<-subset(data_AAPL,Date>=as.Date("2018-01-01")&Date<=as.Date("2020-20-31"))
Error in charToDate(x) :
character string is not in a standard unambiguous format
This Sharpe Ratio proved to be equal to .85. Usually, a Sharpe Ratio
above of 1 is preferred as it implies it offers more returns than risk,
although arguably compared to the market this is a good number.
Dinamic Hedge
First of all, we need to define several functions to simplify the
calculation.
This function calculates the “target daily performance” that we want
to achieve in each day.
_target<-function(data_google,data_ibm,data_apple,date)
Error: unexpected symbol in "_target"
Esta función calcula el valor medio de la rentabilidad diaria de una
acción en los 30 días anteriores.
We can see that with the dynamic hedging strategy, the Sharpe ratio
increased significantly from 0.85 to 1.45.
Hedge Ratio
Since the topic of this part of theproject is finding the hedging
ratio, let’s take a look at how the ratio of the three stocks changed
with our hedging strategy.
In summary, the above coverage ratio significantly increased the
Sharpe ratio from 0.85 to 1.45, which experts would say is a good
value.
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQphdXRob3I6IFN0ZWZhbiBTY2h3ZWl0emVyDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpJVEVTTSBDQU1QVVMgUVJPDQpGSU5BTkNJQUwgUFJPR1JBTU1JTkcNCg0KIyMgRGF0YSBNYW5hZ2VtZW50DQpgYGB7cn0NCiMgTG9hZCBhbGwgcGFja2FnZXMNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocXVhZHByb2cpDQpsaWJyYXJ5KHh0cykNCmxpYnJhcnkoem9vKQ0KbGlicmFyeShwc3ljaCkNCmxpYnJhcnkodHNlcmllcykNCmxpYnJhcnkoZm9yZWNhc3QpDQpsaWJyYXJ5KGxtdGVzdCkNCmxpYnJhcnkoYXN0c2EpDQpsaWJyYXJ5KHF1YW50bW9kKQ0KbGlicmFyeSh3YnN0YXRzKQ0KbGlicmFyeShQZXJmb3JtYW5jZUFuYWx5dGljcykNCmxpYnJhcnkoZlBvcnRmb2xpbykNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShQb3J0Zm9saW9BbmFseXRpY3MpDQpsaWJyYXJ5KHBsbSkNCmxpYnJhcnkoc3RhdGFyKQ0KbGlicmFyeShJbnRyb0NvbXBGaW5SKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShyZWFkeGwpDQp1czIwMjJxMmEgPC0gcmVhZF9leGNlbCgiQzovVXNlcnMvU3RlZmFuIFNjaHdlaXR6ZXIvRG93bmxvYWRzL0ZpbmFuY2UgUHJvZ3JhbWluZy91czIwMjJxMmEueGxzeCIpDQpgYGANCg0KYGBge3J9DQpkYXRhLmRmPC1yZWFkX2V4Y2VsKCJ1czIwMjJxMmEueGxzeCIsc2hlZXQgPSAiZGF0YSIpDQpmaXJtLmRmIDwtcmVhZF9leGNlbCgidXMyMDIycTJhLnhsc3giLHNoZWV0ID0gImZpcm1zIikNCmRpY2RhdG9zLmRmIDwtIHJlYWRfZXhjZWwoInVzMjAyMnEyYS54bHN4IixzaGVldCA9ICJEaWNEYXRvcyIpDQpgYGANCg0KIyMgTWFpbiBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzIGZvciBJbXBvcnRhbnQgVmFyaWFibGVzIHN1Y2ggYXMgVG90YWwgQXNzZXRzLCBSZXZlbnVlLCBNYXJrZXQgVmFsdWUNCmBgYHtyfQ0KIyBzZWxlY3RpbmcgYSBjb21wYW55IGZyb20gb3VyIHNhbXBsZQ0KTUlDUk9TT0ZUID0gZGF0YS5kZiU+JQ0KICBzZWxlY3QoZmlybSxxLHJldmVudWUsIHRvdGFsYXNzZXRzLCBmaXNjYWxtb250aCkgJT4lICNzZWxlY2Npb25hciBjb2x1bW5hcyANCiAgZmlsdGVyIChmaXJtPT0iTVNGVCIpIA0KYGBgDQoNCmBgYHtyfQ0KIyBtdXRhdGUgcmV2ZW51ZSB2YWx1ZXMNCk1JQ1JPU09GVCA9IGRhdGEuZGYlPiUNCiAgc2VsZWN0KGZpcm0scSxyZXZlbnVlLCB0b3RhbGFzc2V0cywgZmlzY2FsbW9udGgpICU+JQ0KICBmaWx0ZXIgKGZpcm09PSJNU0ZUIikgICAlPiUNCiAgIG11dGF0ZShyZXZlbnVlID0gcmV2ZW51ZS8xMDAwICkgDQpgYGANCg0KYGBge3J9DQojIGZpbHRlcmluZyBmb3IgbGFzdCBxdWFydGVyDQpkYXRhLmRmJHE9IGFzLkRhdGUoZGF0YS5kZiRxKQ0KDQpkMjJxMj0gZGF0YS5kZiAlPiUNCiAgZmlsdGVyIChxID09IjIwMjItMDQtMDEiKQ0KYGBgDQoNCmBgYHtyfQ0KIyBzaW1wbHlmaW5nIGNvbHVtbiBuYW1lcw0KbmFtZXMoZmlybS5kZikgPSBjKCJmaXJtIiwiQ29tcGFueSIsIk4iLCAiSW5kdXN0cnlOQUlDUyIsICJFeGNoYW5nZSIsICJJbmR1c3RyeWVjb25vbWF0aWNhIiwgIk5BSUNTMyIsICJTUGFydGljaXBhdGlvbiIpDQpmaXJtcz0gZmlybS5kZiAlPiUNCiAgc2VsZWN0IChmaXJtLENvbXBhbnksSW5kdXN0cnlOQUlDUywgSW5kdXN0cnllY29ub21hdGljYSkNCmBgYA0KDQpgYGB7cn0NCiMgbGV0cyBtZXJnZSBvdXIgdGFibGVzDQpkMjJxMj0gbWVyZ2UoZDIycTIsZmlybXMsIGJ5PSJmaXJtIikgDQpgYGANCg0KYGBge3J9DQpkYXRhLmRmID0gbWVyZ2UoZGF0YS5kZixmaXJtcywgYnk9ImZpcm0iKQ0KYGBgDQoNCmBgYHtyfQ0KIyB1c2luZyBtdXRhdGUsIHdlIGNhbiBjb21wdXRlIHZhcmlhYmxlIHRyYW5zZm9ybWF0aW9ucyBzbyB3ZSBjYW4gY2FsY3VsYXRlIG1hcmtldCBjYXAsIEVCSVQgYW5kIEJvb2sgVmFsdWUNCmQyMnEyIDwtIGQyMnEyICU+JQ0KICBtdXRhdGUgKG1rdGNhcCA9IHNoYXJlc291dHN0YW5kaW5nKm9yaWdpbmFscHJpY2UsDQogICAgICAgICAgRUJJVCA9IHJldmVudWUtY29ncy1zZ2FlLA0KICAgICAgICAgIGJvb2t2ID0gdG90YWxhc3NldHMgLSB0b3RhbGxpYWJpbGl0aWVzKQ0KZGF0YS5kZiA8LSBkYXRhLmRmICU+JQ0KICBtdXRhdGUgKG1rdGNhcCA9IHNoYXJlc291dHN0YW5kaW5nKm9yaWdpbmFscHJpY2UsDQogICAgICAgICAgRUJJVCA9IHJldmVudWUtY29ncy1zZ2FlLA0KICAgICAgICAgIGJvb2t2ID0gdG90YWxhc3NldHMgLSB0b3RhbGxpYWJpbGl0aWVzKQ0KYGBgDQoNCmBgYHtyfQ0KZGF0YS5kZiAlPiUgIA0KI3dlIGZvdW5kIHRoYXQgdGhlIGV4Y2VsIGZpbGUgaGFkIGEgbG90IG9mIGVtcHR5IGNlbGxzLCBzbyB0byBtYW5hZ2Ugb3VyIGVudmlyb25tZW50IHdlJ2xsIHVzZSBOQS5STSB0byBvbWl0IGJsYW5rIGNlbGxzDQogIHN1bW1hcml6ZShudW1fZmlybXM9bigpLCANCiAgICAgICAgICAgIG1lZGlhbl9ta3RjYXA9IG1lZGlhbiAobWt0Y2FwLCBuYS5ybT0gVFJVRSksDQogICAgICAgICAgICAgbWVkaWFuX3RvdGFsYXNzZXRzPSBtZWRpYW4gKHRvdGFsYXNzZXRzLCBuYS5ybT0gVFJVRSksDQogICAgICAgICAgICAgbWVkaWFuX2Jvb2t2YWx1ZT0gbWVkaWFuIChib29rdiwgbmEucm09IFRSVUUpKQ0KYGBgDQoNCmBgYHtyfQ0KIyBsZXRzIG9yZ2FuaXplIG91ciB0YWJsZSBieSBpbmR1c3RyeSB0byBmaW5kIG91dCB0aGUgbnVtYmVyIG9mIGNvbXBhbmllcywgdGhlaXIgbWFya2V0IHZhbHVlIG1lYW4gYW5kIHJldmVudWUgaW5mby4NCmRhdGEuZGYgJT4lICANCiAgZ3JvdXBfYnkoSW5kdXN0cnlOQUlDUykgJT4lDQogIHN1bW1hcml6ZShudW1fZmlybXM9IG4oKSwgDQogICAgICAgICAgICBtZWRpYW5fbWt0Y2FwPSBtZWRpYW4gKG1rdGNhcCwgbmEucm09IFRSVUUpLA0KICAgICAgICAgICAgIG1lZGlhbl9yZXZlbnVlPSBtZWRpYW4gKHJldmVudWUsIG5hLnJtPSBUUlVFKSkNCmBgYA0KDQpgYGB7cn0NCiMgU28gd2UndmUgZ290IGRhdGEgb24gdGhlIGNvbXBhbmllcyBhcyB3ZWxsIGFzIHRoZWlyIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MsIGJ1dCB3ZSBuZWVkIHRvIG1lcmdlIHRoaXMgaW5mbyB3aXRoIHRoZSBtYXJrZXQgZGF0YS4gVXNpbmcgU1A1MDAsIHdlJ2xsIG1lcmdlIHRoZSBkYXRhIGJ1dCBmaXJzdCB3ZSBtdXN0IHRyYW5zZm9ybSBtb250aGx5IHJldHVybnMgaW50byBxdWFydGVybHkgcmV0dXJucy4NCmdldFN5bWJvbHMoIl5HU1BDIiwgZnJvbT0iMjAwMC0wMS0wMSIsIHRvPSAiMjAyMi0wNy0wMSIsIHBlcmlvZGljdHk9Im1vbnRobHkiICwgc3JjPSJ5YWhvbyIpDQpgYGANCg0KYGBge3J9DQojIExldHMgY2hhbmdlIGFkaiBwcmljZXMgZnJvbSBtb250aGx5IHRvIHF1YXJ0ZXJseQ0KR1NQQ1E9IHRvLnF1YXJ0ZXJseShHU1BDLCBpbmRleEF0PSAnc3RhcnRvZicpDQpHU1BDUT1BZChHU1BDUSkNCiMgVGhlbiBjYWxjdWxhdGUgcmV0dXJucw0KR1NQUmV0dXJuPSBkaWZmKGxvZyhHU1BDUSksKQ0KbmFtZXMoR1NQUmV0dXJuKT0gYygiUyZQcmV0dXJuIikNCiMgRmluYWxseSB3ZSdsbCBzYXZlIHRoZSByZXR1cm5zIGZyb20gdGhlIGxhc3QgcXVhcnRlciB0byBjb21wYXJlIGl0IHdpdGggdGhlIGQyMnEyIHRhYmxlLg0KUmV0R1NQQ1EyIDwtIC0wLjE3OTY2NjIzMDMNCmBgYA0KDQpgYGB7cn0NCkdTUENRLmRmPWRhdGEuZnJhbWUocT1pbmRleChHU1BSZXR1cm4pLCBjb3JlZGF0YSAoR1NQUmV0dXJuKSkNCmRhdGEuZGY9bWVyZ2UoZGF0YS5kZiwgR1NQQ1EuZGYsIGJ5PSJxIikNCmRhdGEuZGY9IHBkYXRhLmZyYW1lKGRhdGEuZGYsaW5kZXg9YygiZmlybSIsICJxIiApKQ0KZGF0YS5kZiRyZXR1cm5zdG9ja3M9IGRpZmYobG9nKGRhdGEuZGYkYWRqcHJpY2UpLCApDQpkYXRhLmRmJGJlc3Q9aWZlbHNlKGRhdGEuZGYkcmV0dXJuc3RvY2tzPmRhdGEuZGYkUy5QcmV0dXJuLDEsMCkNCmBgYA0KDQpgYGB7cn0NCiMgTm93LCB3ZSB3aWxsIHNob3cgaG93IHRoZSBVUyBzdG9jayBtYXJrZXQgaGFzIGdyb3duIG92ZXIgdGltZQ0KZGF0YS5kZiA8LSBkYXRhLmRmICU+JQ0KICBtdXRhdGUgKG1rdGNhcCA9IHNoYXJlc291dHN0YW5kaW5nKm9yaWdpbmFscHJpY2UpDQpgYGANCmBgYHtyfQ0Kc3RvY2ttYXJrZXRyID0gZGF0YS5kZiAlPiUNCiAgZ3JvdXBfYnkocSkgfD4NCiAgICAgICBzdW1tYXJpemUoDQogICAgICAgICAgICBtYXJrZXR2PXN1bShta3RjYXAsbmEucm09VFJVRSkpDQpzdG9ja21hcmtldHINCmBgYA0KDQpgYGB7cn0NCmdncGxvdChzdG9ja21hcmtldHIsIGFlcyh4PXEsIHk9bWFya2V0diwpKSsgZ2VvbV9jb2woKQ0KYGBgDQpXRSBDQU4gU0VFIEEgR1JPV1RIIFRSRU5EIFNJTkNFIFRIRSBZRUFSIDIwMDAgV0lUSCBBIE5PVE9SSU9VUyBGQUxMIElOIDIwMjEuDQoNCiMjIEJBU0lDIEZVTkRBTUVOVEFMIEFOQUxZU0lTDQpZb3UgaGF2ZSB0byBzZWxlY3QgNCBmaW5hbmNpYWwgcmF0aW9zL3ZhcmlhYmxlcyB0aGF0IG1pZ2h0IGJlIHJlbGF0ZWQgdG8gdGhlIHByb2JhYmlsaXR5IHRoYXQgYSBzdG9jayByZXR1cm4gYmVhdHMgdGhlIG1hcmtldCByZXR1cm4uIFlvdSBoYXZlIHRvIHByb3ZpZGUgcmVmZXJlbmNlcyBmb3IgdGhlIGp1c3RpZmljYXRpb24gb2YgdXNpbmcgeW91ciBmaW5hbmNpYWwgcmF0aW9zL3ZhcmlhYmxlcy4NCg0KMS4gUkVUVVJOIE9OIEVRVUlUWSAoUk9FKTogRk9SIFRIRSBGSVJTVCBSQVRJTyBXRSBXSUxMIFVTRSBUSEUgUkVUVVJOIE9OIEVRVUlUWSwgUk9FIElTIFRIRSBGSU5BTkNJQUwgUFJPRklUQUJJTElUWSBPRiBBIENPTVBBTlksIFdJVEggVEhJUyBXRSBDQU4gVEVMTCBXSEVUSEVSIFRIRSBDT01QQU5ZIEhBUyBBIERFU0lSRUQgUEVSRk9STUFOQ0UgKEJFVFRFUiBUSEFOIFRIRSBNQVJLRVQpIEZJUlNUIFdFIE1VU1QgQ0FMQ1VMQVRFIFRIRSBORVQgSU5DT01FDQoNCmBgYHtyfQ0KZGF0YS5kZiRuZXRpbmNvbWUgPC0gZGF0YS5kZiRlYml0ZGEgLSBkYXRhLmRmJGZpbmV4cCAtIGRhdGEuZGYkZGVwcmVjaWF0aW9uYW1vciAtIGRhdGEuZGYkaW5jb21ldGF4DQpgYGANCg0KV0lUSCBUSEUgTkVUIElOQ09NRSBXRSBDQU4gQ0FMQ1VMQVRFIE9VUiBGSVJTVCBSQVRJTw0KYGBge3J9DQpkYXRhLmRmJHJvZSA8LSBkYXRhLmRmJG5ldGluY29tZSAvIGRhdGEuZGYkc3RvY2tob2xkZXJlcXVpdHkNCmhpc3QoZGF0YS5kZiRyb2UsIG1haW4gPSAiUmV0dXJuIG9uIEVxdWl0eSIsIGNvbCA9ICJHUkVFTiIpDQpgYGANCkRVRSBUTyBUSEUgRVhUUkVNRSBWQUxVRVMgSU4gVEhFIEdSQVBILCBXRSBDQU4gR08gQUhFQUQgQU5EIFdJTkRTT1JJWkUgT1VSIFJFU1VMVFMNCg0KYGBge3J9DQpkYXRhLmRmJHJvZSA8LSB3aW5zb3JpemUoZGF0YS5kZiRyb2UscHJvYnMgPSBjKDAuMDEsMC45OSkpDQpgYGANCmBgYHtyfQ0KaGlzdChkYXRhLmRmJHJvZSwgbWFpbiA9ICJSZXR1cm4gb24gRXF1aXR5IiwgY29sID0gIkdSRUVOIikNCmBgYA0KV0UgVVNFIFRIRSBST0UgU0lOQ0UgV0UgV0FOVCBUTyBLTk9XIElGIFRIRSBSRVRVUk5TIEFSRSBHUkVBVEVSIFRIQU4gMCwgVEhBTktTIFRPIFRIRSBST0UgV0UgQ0FOIEtOT1cgVEhBVCBNT1NUIE9GIFRIRSBSRVRVUk5TIE9GIFRIRSBDT01QQU5JRVMgRFVSSU5HIFRIRSBQRVJJT0QgV0VSRSBQT1NJVElWRSBXSElDSCBDQU4gSEVMUCBVUyBLTk9XIElGIFRIRVNFIENPTVBBTklFUyBSRUFMTFkgUEVSRk9STSBCRVRURVIgVEhBTiBUSEUgTUFSS0VUIElOIFRIT1NFIFBFUklPRFMuDQoNCi0tDQoNCjIuIEJPT0sgVE8gTUFSS0VUIFJBVElPIChCTVIpOiBGT1IgVEhFIFNFQ09ORCBSQVRJTyBXRSBXSUxMIFVTRSBUSEUgQk9PSyBUTyBNQVJLRVQgUkFUSU8gU0lOQ0UgVEhJUyBIRUxQUyBVUyBUTyBDT01QQVJFIFRIRSBWQUxVRSBPRiBUSEUgQ09NUEFOWSdTIEJPT0tTIFdJVEggSVRTIE1BUktFVCBWQUxVRSBXRSBBTFJFQURZIENBTENVTEFURUQgUFJFVklPVVNMWSBUSEUgQk9PS1YgT0YgVEhFIFNUT0NLUyBPTkxZIFRIRSBPVEhFUiBQQVJUIE9GIFRIRSBDQUxDVUxBVElPTiBJUyBNSVNTSU5HDQoNCmBgYHtyfQ0KZGF0YS5kZiRNYXJrZXR2cTIgPC0gZGF0YS5kZiRvcmlnaW5hbHByaWNlICogZGF0YS5kZiRzaGFyZXNvdXRzdGFuZGluZw0KIyBXRSBDQU4gTk9USUNFIFRIQVQgQk9USCBWQUxVRVMgQ09OVEFJTiBUSEUgU0FNRSBOVU1CRVIgT0YgREFUQSBUSEVSRUZPUkUgV0UgQ0FOIENPTlRJTlVFIFRPIENBTENVTEFURSBUSEUgQk9PSyBUTyBNQVJLRVQgUkFUSU8NCmRhdGEuZGYkQk1SIDwtIGRhdGEuZGYkYm9va3YvZGF0YS5kZiRNYXJrZXR2cTINCmRhdGEuZGYkQk1SDQpgYGANCg0KTkVWRVIgTUlORCBBTEwgVEhBVCBEQVRBLCBMRVRTIERPIEEgSElTVE9HUkFNDQoNCmBgYHtyfQ0KIyBPVVIgWCBBWElTIFdBUyBIVUdFIFNPIFdFIERFQ0lERUQgVE8gVFVORSBJVCBET1dOIFdJVEggVEhFIFdJTlNPUklaRSBGVU5DVElPTg0KaGlzdChkYXRhLmRmJEJNUiwgY29sPSJibHVFIikNCmBgYA0KYGBge3J9DQpkYXRhLmRmJEJNUiA8LSB3aW5zb3JpemUoZGF0YS5kZiRCTVIscHJvYnMgPSBjKDAuMDEsMC45OSkpDQpgYGANCmBgYHtyfQ0KaGlzdChkYXRhLmRmJEJNUiwgbWFpbiA9ICJCTVIiLCBjb2wgPSAiYmx1ZSIpDQpgYGANCk1PU1QgT0YgVEhFIERBVEEgT0JUQUlORUQgQlkgVEhFIEJNUiBXRVJFIFBPU0lUSVZFIEFORCBBQ0NPUkRJTkcgVE8gVEhFIFJBVElPLCBBIEJNUiBHUkVBVEVSIFRIQU4gMSBURUxMUyBVUyBUSEFUIFNJTkNFIFRIRSBCT09LIFZBTFVFIE9GIFRIRSBDT01QQU5ZIElTIEdSRUFURVIgVEhBTiBUSEUgTUFSS0VUIFZBTFVFLCBJVCBJUyBDT05TSURFUkVEIFRIQVQgVEhFIENPTVBBTlknUyBCVVNJTkVTUyBJUyBVTkRFUlZBTFVFRCBUSEVOIFRIRSBNT1NUIE9GIFRIRSBDT01QQU5JRVMgSU4gVEhJUyBQRVJJT0QgQVJFIFNFTExJTkcgVEhFSVIgQVNTRVRTIEZPUiBBIExPV0VSIFBSSUNFIFRIQU4gVEhFWSBBUkUgUkVBTExZIFdPUlRILg0KDQozLiBFQVJOSU5HUyBQRVIgU0hBUkUgKEVQU1ApOiBBUyBXRSBLTk9XIEVBUk5JTkdTIFBFUiBTSEFSRSBJUyBUSEUgUFJPRklUIFRIQVQgQ09NUEFOSUVTIEVBUk4gUEVSIFNIQVJFLCBJTiBPUkRFUiBUTyBDQUxDVUxBVEUgSVQgV0UgT05MWSBORUVEIFRPIERJVklERSBUSEUgTkVUIFBST1RGSVQgQlkgVEhFIE5VTUJFUiBPRiBTSEFSRVMgVEhBVCBUSEUgQ09NUEFOWSBIQVMsIFdFIFdJTEwgRE8gVEhFIERFRkxBVEVEIEJZIFBSSUNFIFdJVEggSlVTVCBESVZJRElORyBFU1BTIE9OIFRIRSBPUklHSU5BTCBQUklDRSBPRiBUSEUgU0hBUkUgU08gVEhBVCBJVCBJUyBCRVRURVIgQ09NUEFSQUJMRSBCRVRXRUVOIENPTVBBTklFUy4NCg0KYGBge3J9DQpkYXRhLmRmJGVhcm5pbnNwZXJzaGFyZSA8LSBkYXRhLmRmJEVCSVQvZGF0YS5kZiRzaGFyZXNvdXRzdGFuZGluZw0KZGF0YS5kZiRFUFNQIDwtIGRhdGEuZGYkZWFybmluc3BlcnNoYXJlL2RhdGEuZGYkb3JpZ2luYWxwcmljZQ0KaGlzdChkYXRhLmRmJEVQU1AsIG1haW4gPSAiRWFybmluZ3MgUGVyIFNoYXJlIERlZmxhdGVkIGJ5IFByaWNlIiwgY29sID0gIlJFRCIpDQpgYGANCldFIFdJTEwgR08gQUhFQUQgQU5EIFdJTlNPUklaRSBPTkNFIEFHQUlODQoNCmBgYHtyfQ0KZGF0YS5kZiRFUFNQIDwtIHdpbnNvcml6ZShkYXRhLmRmJEVQU1AscHJvYnMgPSBjKDAuMDEsMC45OSkpDQpgYGANCmBgYHtyfQ0KaGlzdChkYXRhLmRmJEVQU1AsIG1haW4gPSAiRWFybmluZ3MgUGVyIFNoYXJlIERlZmxhdGVkIGJ5IFByaWNlIiwgY29sID0gIlJFRCIpDQpgYGANCldFIE5PVElDRSBFUFNQIEdSRUFURVIgVEhBTiAwJSBJTiBNT1NUIE9GIFRIRSBPQlNFUlZFRCBEQVRBLCBXSVRIIFNPTUUgRVhUUkVNRSBWQUxVRVMgVFJFTkRJTkcgVE9XQVJEUyAtMC4zLg0KDQo0Li0gU0laRSBPRiBUSEUgQ09NUEFOWTogVEhFIFNJWkUgT0YgVEhFIENPTVBBTlkgV0lMTCBIRUxQIFVTIEEgTE9UIFRPIEtOT1cgVEhFIFBST0ZJVEFCSUxJVFkgT0YgVEhFIENPTVBBTklFUyBVU0lORyBUSEVJUiBUT1RBTCBBU1NFVFMsIFdFIEJFTElFVkUgVEhBVCBUSEUgU0laRSBPRiBUSEUgQ09NUEFOWSBTSE9VTEQgQkUgQ09OU0lERVJFRCBJTiBPUkRFUiBUTyBCRVRURVIgQUxMT0NBVEUgVEhFIFdFSUdIVFMgSU4gVEhFIElOVkVTVE1FTlQgUE9SVEZPTElPLiBJRiBET05FIENPUlJFQ1RMWSxXRSBNQVkgQkUgQUJMRSBUTyBCRUFUIFRIRSBNQVJLRVQNCmBgYHtyfQ0KZGF0YS5kZiRzaXplIDwtIGxvZyhkYXRhLmRmJHRvdGFsYXNzZXRzKQ0KaGlzdChkYXRhLmRmJHNpemUsIG1haW4gPSAiU2l6ZSIsIGNvbCA9ICJZRUxMT1ciKQ0KYGBgDQoNCiMjIFNlY29uZCBTY3JlZW5pbmctIEFscGhhIGFuZCBNYXJrZXQgUmlzayBvZiB0aGUgU3RvY2tzDQoNCldFIFdJTEwgTUFLRSBBIExPR0lTVElDIE1PREVMIFdJVEggVEhFIElORk8gQUxSRUFEWSBHQVRIRVJFRCBDUkVBVElORyBBIE5FVyBWQVJJQUJMRSBEQVRBTU9ERUwuDQoNCmBgYHtyfQ0KZGF0YW1vZGVsIDwtZGF0YS5kZiAlPiUNCiAgc2VsZWN0KGZpcm0seWVhcixldmVyeXRoaW5nKCkpDQpgYGANCg0KV0UgQVJFIE5PVyBHT0lORyBUTyBDT01QQVJFIFRIRSBTVE9DSyBSRVRVUk5TIEFHQUlOU1QgVEhFIE1BUktFVCBSRVRVUk5TIEFORCBBU1NJR04gSVQgVE8gQSBORVcgQ09MVU1OLCBJRiBUSEUgQ09ORElUSU9OIElTIE1FVCBUSEFUIFRIRSBTVE9DS1NSRVRVUk5TIEFSRSBHUkVBVEVSIFRIQU4gVEhFIE1BUktFVCBSRVRVUk5TIFBSRVZJT1VTTFkgQ0FMQ1VMQVRFRCBJTiBUSEUgRklSU1QgU1RFUA0KDQpgYGB7cn0NCmRhdGFtb2RlbCRoaWdoZXJSIDwtIGlmZWxzZShkYXRhbW9kZWwkcmV0dXJuc3RvY2tzID4gZGF0YW1vZGVsJFMuUHJldHVybiwgMSwwKQ0KYGBgDQpgYGB7cn0NCm1vZGVsMT0gZ2xtKGhpZ2hlclIgfiByb2UgKyBCTVIgK0VQU1AgKyBzaXplLCBkYXRhPSBkYXRhbW9kZWwsZmFtaWx5PSAiYmlub21pYWwiLCBuYS5hY3Rpb24gPSBuYS5vbWl0KQ0Kc3VtbWFyeShtb2RlbDEpDQpgYGANCk9VUiBaIFZBTFVFUyBXRVJFIEFMTCBPVkVSIFRIRSBQTEFDRSwgQlVUIFRIQU5LUyBUTyBUSEUgUFZBTFVFUyBXRSBDQU4gQ09OU0lERVIgUk9FIEJNUiBFUFNQIEFORCBTSVpFIEFTIE1FQU5JTkdGVUwgQU5EIFNUQVRJU1RJQ0FMTFkgU0lHTklGSUNBTlQsIFRIRVJFRk9SRTogVEhFIE9ERFMgT0YgQkVBVElORyBUSEUgTUFSS0VUIENBTiBCRSBFWFBMQUlORUQgQlkgRUFDSCBQT1JDRU5UVUFMIENIQU5HRSBJTiBSRVRVUk4gT1ZFUiBFUVVJVFkuDQoNCklGIFdFIFRSVUxZIFdBTlQgVE8gS05PVyBXSEVUSEVSIFdFIENBTiBCRUFUIFRIRSBNQVJLRVQsIFdFJ1ZFIEdPVCBUTyBVU0UgVEhFIE1PU1QgUkVDRU5UIERBVEEgQVZBSUxBQkxFLCBCRUlORyBUSEFUIEZPVU5EIElOIFRIRSBEMjJRMiBUQUJMRS4NCmBgYHtyfQ0KRklSTVMgPC0gZGF0YW1vZGVsICU+JQ0KICAgICAgICAgIHNlbGVjdChxLGZpcm0sUy5QcmV0dXJuLHJvZSxCTVIsRVBTUCxzaXplLHllYXIpICU+JQ0KICBncm91cF9ieShxKSB8PiBmaWx0ZXIoIHllYXI9PSAiMjAyMiIpIHw+IA0KICAgICAgICAgIGFzLmRhdGEuZnJhbWUoKQ0KYGBgDQoNClRIRSBQUkVESUNULkdMTSBGVU5DVElPTiBIRUxQUyBVUyBUTyBPQlRBSU4gUFJFRElDVElPTlMgRk9SIE9VUiBNT0RFTCwgSU4gVEhJUyBDQVNFIFdFIFdBTlQgVEhFIFNUT0NLUyBUTyBCRSBHUkVBVEVSIFRIQU4gVEhFIE1FQU4gUEVSRk9STUFOQ0UgU08gTEVUUyBTRUUgV0hBVCBIQVBQRU5TLg0KYGBge3J9DQpGSVJNUyA8LSBGSVJNUyAlPiUgDQogIG11dGF0ZShwcmVkaWN0aW9uPXByZWRpY3QuZ2xtKG1vZGVsMSxuZXdkYXRhPUZJUk1TLHR5cGU9YygicmVzcG9uc2UiKSkgKQ0KRklSTVMNCmBgYA0KTk9XIFdFIFdJTEwgR0VUIFRIRSBUT1AgNTAgRklSTVMgQVJSQU5HSU5HIFRIRU0gRlJPTSBISUdIRVNUIFRPIExPV0VTVC4gVEhFIFBSRURJQ1RJT05TIFdJTEwgQkUgT0JUQUlORUQgVVNJTkcgVEhFIFRJRElWRVJTRSBUT1BfTiBGVU5DVElPTiBJTiBPUkRFUiBUTyBTRUxFQ1QgVEhFIEZJUlNUIDUwLg0KYGBge3J9DQpUT1A1MGZpcm1zIDwtIEZJUk1TICU+JQ0KICBhcnJhbmdlIChkZXNjKEZJUk1TJHByZWRpY3Rpb24pKSAlPiUNCiAgdG9wX24oNTApDQpgYGANCmBgYHtyfQ0KVE9QNTBmaXJtcw0KYGBgDQpgYGB7cn0NCiMgTEVUUyBESVNQTEFZIFRIRSBUT1AgNTAgVElDS0VSUw0KVElDS0VSUzwtYXMudmVjdG9yKFRPUDUwZmlybXMkZmlybSkNClRJQ0tFUlMNCmBgYA0KYGBge3J9DQojIFdFIFdJTEwgSEFWRSBUTyBDUkVBVEUgQSBGVU5DVElPTiBUSEFUIE9CVEFJTlMgVEhFIERBVEEgRlJPTSBPVVIgVElDS0VSTElTVCBXSEVSRSBUSEUgRklSU1QgNTAgQVJFIFBSRVNFTlRFRCwgQ09OU0lERVJJTkcgVEhFIElORk9STUFUSU9OIEZST00gVEhFIExBU1QgWUVBUg0KZm9yICh0IGluIFRJQ0tFUlMpIHsNCiAgdHJ5KGdldFN5bWJvbHModCwgDQogICAgICAgICAgICAgZnJvbSA9ICIyMDIwLTAxLTAxIiwgdG8gPSAiMjAyMi0wNi0zMCIsDQogICAgICAgICAgICAgcGVyaW9kaWNpdHkgPSAibW9udGhseSIsDQogICAgICAgICAgICAgc3JjID0gInlhaG9vIikgKQ0KfQ0KYGBgDQpgYGB7cn0NCmxpc3QgPSBjKCkNCmZvcih0IGluIGxzKCkpIHsNCiAgaWYgKHQgJWluJSBUSUNLRVJTKXsNCiAgICBsaXN0ID0gYyhsaXN0LHQpDQogIH19DQoNClRJQ0tFUlMNCmBgYA0KYGBge3J9DQpwcmljZXM8LSBBZChtZXJnZShBSFQsQUxIQyxBTUMsQVJDSCxBVFVTLEJBVEwsQ0FSLENDTyxDT01NLENSSyxDVVJPLENVUlYsQ1dILENZSCxESyxEUkNULEVHWSxFTUJDLEZBVCxGVU4sSkFLSyxMRVUsTFBJLExZTFQsTVBDLE5DTUksTk9HLFBBUlIsUEJJLFBCUEIsUERDTyxQRUksUEZHQyxQTEFZLFBSRyxQUlRTLFJFQUwsU0lYLFNOQlIsU1VQLFNXTixUU1EsVFVQLFVMQ0MsVU5JVCxWTE8sV1RJLFdXLFlFTEwpKQ0KcHJpY2VzDQpgYGANCmBgYHtyfQ0KZ2V0U3ltYm9scygiXkdTUEMiLA0KICAgICAgICAgICBmcm9tID0gIjIwMjAtMDEtMDEiLCB0byA9ICIyMDIyLTA2LTMwIiwNCiAgICAgICAgICAgcGVyaW9kaWNpdHkgPSAibW9udGhseSIsDQogICAgICAgICAgIHNyYyA9ICJ5YWhvbyIpDQpgYGANCkhBVklORyBPVVIgUkVUVVJOUyBCT1RIIEZST00gVEhFIE1BUktFVCBBTkQgRlJPTSBUSEUgU1RPQ0tTIFdFIEFSRSBHT0lORyBUTyBDQUxDVUxBVEUgVEhFU0UgUkVUVVJOUyBCT1RIIEZST00gVEhFIE1BUktFVCBBTkQgRlJPTSBUSEUgVE9QIDUwIFNIQVJFUy4NCg0KYGBge3J9DQpyZXR1cm5zc3RvY2s8LWRpZmYobG9nKEFkKHByaWNlcykpKQ0KcmV0dXJuc21rdCA8LWRpZmYobG9nKEFkKEdTUEMpKSkNCmBgYA0KYGBge3J9DQptYXJrZXRtb2RlbCA8LWZ1bmN0aW9uKHJldHVybnNzdG9jayxyZXR1cm5zbWt0KSB7DQoNCiAgbW9kZWw8LWxtKHJldHVybnNzdG9jayB+IHJldHVybnNta3QpDQogIA0KICBzbTwtc3VtbWFyeShtb2RlbCkNCiAgdF9jcml0aWNhbF92YWx1ZSA8LSBhYnMocXQoMC4wMjUsbW9kZWwkZGYucmVzaWR1YWwpKQ0KICANCiAgcmVzdWx0LnZlY3RvcjwtYyhzbSRjb2VmZmljaWVudHNbMSxjKDEsMildLA0KICAgICAgICAgICAgICAgICAgIHNtJGNvZWZmaWNpZW50c1sxLDFdLXRfY3JpdGljYWxfdmFsdWUqc20kY29lZmZpY2llbnRzWzEsMl0sDQogICAgICAgICAgICAgICAgICAgc20kY29lZmZpY2llbnRzWzEsMV0rdF9jcml0aWNhbF92YWx1ZSpzbSRjb2VmZmljaWVudHNbMSwyXSwNCiAgICAgICAgICAgICAgICAgICBzbSRjb2VmZmljaWVudHNbMixjKDEsMildLA0KICAgICAgICAgICAgICAgICAgIHNtJGNvZWZmaWNpZW50c1syLDFdLXRfY3JpdGljYWxfdmFsdWUqc20kY29lZmZpY2llbnRzWzIsMl0sDQogICAgICAgICAgICAgICAgICAgc20kY29lZmZpY2llbnRzWzIsMV0rdF9jcml0aWNhbF92YWx1ZSpzbSRjb2VmZmljaWVudHNbMiwyXSwNCiAgICAgICAgICAgICAgICAgICBtb2RlbCRkZi5yZXNpZHVhbCkNCiAgbmFtZXMocmVzdWx0LnZlY3Rvcik8LWMoImIwIiwic2ViMCIsIm1pbjk1Q0liMCIsIm1heDk1Q0liMCIsImIxIiwic2ViMSIsIm1pbjk1Q0liMSIsIm1heDk1Q0liMSIsIk4iKQ0KICByZXR1cm4ocmVzdWx0LnZlY3RvcikNCn0NCmBgYA0KDQpXRSBDUkVBVEUgQSBUQUJMRSBGT1IgU1RPQ0sgUkVUVVJOUyBXSEVSRSBXRSBLRUVQIEJPVEggVEhFIE9ORSBGT1IgU1RPQ0tTIEFORCBPTkUgRk9SIFRIRSBNQVJLRVQgQU5EIFRIRU4gV0UgV0lMTCBNQUtFIEEgTE9PUCBXSVRIIEFMTCBUSEUgU0hBUkVTLg0KYGBge3J9DQpyZXR1cm5zLmRmPC0gYXMuZGF0YS5mcmFtZShtZXJnZShyZXR1cm5zc3RvY2sscmV0dXJuc21rdCkpDQpgYGANCmBgYHtyfQ0KbWF0cml4UmVzdWx0czwtYygpDQpmb3IoaSBpbiAxOjQ5KSB7ICAjUExBQ0UgMiBUTyBTVEFSVCBGUk9NIFRIRSAyTkQgUE9TSVRJT04NCg0KICBtIDwtIG1hcmtldG1vZGVsKHJldHVybnMuZGZbLGldLCByZXR1cm5zLmRmIFssNTBdKQ0KDQogIG1hdHJpeFJlc3VsdHM8LXJiaW5kKG1hdHJpeFJlc3VsdHMsbSkNCn0NCmBgYA0KV0UgUkVOQU1FIFRIRSBDT0xVTU5TIEFORCBST1dTIE9GIE9VUiBNQVRSSVgNCmBgYHtyfQ0KY29sbmFtZXMobWF0cml4UmVzdWx0cyk8LWMoImIwIiwic2ViMCIsIm1pbjk1Q0liMCIsIm1heDk1Q0liMCIsImIxIiwic2ViMSIsIm1pbjk1Q0liMSIsIm1heDk1Q0liMSIsIk4iKQ0Kcm93bmFtZXMobWF0cml4UmVzdWx0cyk8LVRJQ0tFUlNbMjpsZW5ndGgoVElDS0VSUyldDQptYXRyaXhSZXN1bHRzDQpgYGANCk5PVyBXRSBIQVZFIE9VUiBCRVRBUyBUSEFUIFdJTEwgSEVMUCBVUyBOT1cgU0VMRUNUIFRIRSAxMCBDT01QQU5JRVMuIE5FVyBEQVRBIEZSQU1FIEZPUiBUSEUgUkVTVUxUUw0KYGBge3J9DQpyZXN1bHRzLmRmPC1hcy5kYXRhLmZyYW1lKG1hdHJpeFJlc3VsdHMpDQpgYGANCg0KV2hhdCBkbyB5b3UgbmVlZCB0byBrbm93IHRvIGVzdGltYXRlIHRoZSBtYXJrZXQgcmlzayBvZiBlYWNoIHN0b2NrPyBGb3IgeW91ciBzZWxlY3Rpb24gY3JpdGVyaWEsIGhvdyB3b3VsZCB5b3UgdXNlIHRoZSBiZXRhIGFuZCBhbHBoYSBjb2VmZmljaWVudHMgKGFsb25nIHdpdGggdGhlaXIgY29ycmVzcG9uZGluZyBzdGFuZGFyZCBlcnJvcnMgYW5kIHAgdmFsdWVzKSB0byBzZWxlY3QgdGhlIGJlc3Qgc3RvY2tzIGZvciB5b3VyIHBvcnRmb2xpbz8gV2hpY2ggYXJlIHlvdXIgbWFpbiBhcmd1bWVudHMgZm9yIHlvdXIgc2VsZWN0aW9uIGNyaXRlcmlhPyBDbGVhcmx5IHN0YXRlIHlvdXIgYXNzdW1wdGlvbnMgYWJvdXQgcG9zc2libGUgZnV0dXJlIG1hcmtldCBjb25kaXRpb25zLCBhbmQgYWxzbyB5b3VyIGxpbmUgb2YgcmVhc29uaW5nLiBZb3UgaGF2ZSB0byBqdXN0aWZ5IHlvdXIgY3JpdGVyaWEgdXNpbmcgMSBvciAyIHJlZmVyZW5jZXMuDQpCZWZvcmUgd2UgY2FuIGxpc3QgYWxsIG9mIHRoZSB0aGluZ3Mgd2UgbmVlZCB0byBrbm93IHRvIGVzdGltYXRlIHRoZSBtYXJrZXQgcmlzayBvZiBlYWNoIHN0b2NrIHdlIG5lZWQgdG8gZGVmaW5lIG1hcmtldCByaXNrLiBBZGFtIEhheWVzIFBoLkQuIGRlZmluZXMgbWFya2V0IHJpc2sgYXMg4oCcdGhlIHBvc3NpYmlsaXR5IHRoYXQgYW4gaW5kaXZpZHVhbCBvciBvdGhlciBlbnRpdHkgd2lsbCBleHBlcmllbmNlIGxvc3NlcyBkdWUgdG8gZmFjdG9ycyB0aGF0IGFmZmVjdCB0aGUgb3ZlcmFsbCBwZXJmb3JtYW5jZSBvZiBpbnZlc3RtZW50cyBpbiB0aGUgZmluYW5jaWFsIG1hcmtldHMu4oCdICAoQS4gSGF5ZXMsIDA2LjMwLjIyKQ0KVGFraW5nIGEgc3RlcCBiYWNrLCB0aGUgcG9zc2liaWxpdHkgb2YgZXhwZXJpZW5jaW5nIGxvc3MgaXMgZ2l2ZW4gYnkgdGhlIGZhY3RvcnMgdGhhdCBhZmZlY3QgdGhlIG92ZXJhbGwgcGVyZm9ybWFuY2Ugb2YgaW52ZXN0bWVudHMgaW4gZmluYW5jaWFsIG1hcmtldHMuIFNvIHdoYXQgZmFjdG9ycyBjb21lIGludG8gcGxheT8gUmVtZW1iZXIgdGhhdCBtYXJrZXQgcmlzayBpcyB0aGUgc2FtZSBhcyBzeXN0ZW1hdGljIHJpc2ssIGFuZCB0aGlzIGNhbuKAmXQgYmUgcmVkdWNlZCBieSBkaXZlcnNpZnlpbmcuIOKAnFNvdXJjZXMgb2YgbWFya2V0IHJpc2sgaW5jbHVkZSByZWNlc3Npb25zLCBwb2xpdGljYWwgdHVybW9pbCwgY2hhbmdlcyBpbiBpbnRlcmVzdCByYXRlcywgbmF0dXJhbCBkaXNhc3RlcnMsIGFuZCB0ZXJyb3Jpc3QgYXR0YWNrcy4gU3lzdGVtYXRpYywgb3IgbWFya2V0IHJpc2ssIHRlbmRzIHRvIGluZmx1ZW5jZSB0aGUgZW50aXJlIG1hcmtldCBhdCB0aGUgc2FtZSB0aW1lLuKAnSAgKEEuIEhheWVzLCAwNi4zMC4yMikgDQpTbyBub3cgd2Uga25vdyB3aGF0IHZhcmlhYmxlcyBhcmUgbmVlZGVkIHRvIHRha2UgaW50byBhY2NvdW50IHdoZW4gY2FsY3VsYXRpbmcgc3lzdGVtYXRpYyByaXNrLiBCdXQgaG93IHdvdWxkIHdlIHVzZSB0aGUgYmV0YSBhbmQgYWxwaGEgY29lZmZpY2llbnRzIGFsb25nIHdpdGggdGhlaXIgc3RhbmRhcmQgZXJyb3JzIGFuZCBwIHZhbHVlcyB0byBzZWxlY3QgdGhlIGJlc3Qgc3RvY2tzIGZvciBvdXIgcG9ydGZvbGlvPyBQcmV0dHkgZWFzeSwgQmV0YSAozrIpIGlzIGEgbWVhc3VyZSBvZiBzeXN0ZW1hdGljIHJpc2sgb2YgYSBwb3J0Zm9saW8gY29tcGFyZWQgdG8gdGhlIG1hcmtldCBhcyBhIHdob2xlICh1c3VhbGx5IHRha2luZyBTJlAgNTAwIGludG8gY29uc2lkZXJhdGlvbikuIFN0b2NrcyB3aXRoIGJldGFzIGhpZ2hlciB0aGFuIDEuMCBjYW4gYmUgaW50ZXJwcmV0ZWQgYXMgbW9yZSB2b2xhdGlsZSB0aGFuIHRoZSBTJlAgNTAwLiBXZSB1c2VkIEJldGEgZm9yIHRoZSBDYXBpdGFsIEFzc2V0IFByaWNpbmcgTW9kZWwsIHRoZSBDQVBNIGV4cGxhaW5zIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBzeXN0ZW1hdGljIHJpc2sgYW5kIGV4cGVjdGVkIHJldHVybiBmb3IgYXNzZXRzLiANCuKAnENBUE0gaXMgd2lkZWx5IHVzZWQgYXMgYSBtZXRob2QgZm9yIHByaWNpbmcgcmlza3kgc2VjdXJpdGllcyBhbmQgZm9yIGdlbmVyYXRpbmcgZXN0aW1hdGVzIG9mIHRoZSBleHBlY3RlZCByZXR1cm5zIG9mIGFzc2V0cywgY29uc2lkZXJpbmcgYm90aCB0aGUgcmlzayBvZiB0aG9zZSBhc3NldHMgYW5kIHRoZSBjb3N0IG9mIGNhcGl0YWwu4oCdICAoVy4gS2VudG9uLCAwNi4zMC4yMikNCldoYXQgYWJvdXQgQWxwaGEgY29lZmZpY2llbnRzPyBBbHBoYSBpcyBhIHRlcm0gdXNlZCBpbiBpbnZlc3RpbmcgdG8gZGVzY3JpYmUgYW4gaW52ZXN0bWVudOKAmXMgYWJpbGl0eSB0byBiZWF0IHRoZSBtYXJrZXQuIEFscGhhIGlzIHRodXMgcmVmZXJyZWQgdG8gYXMg4oCcZXhjZXNzIHJldHVybuKAnSBvciDigJxhYm5vcm1hbCByYXRlIG9mIHJldHVybizigJ0gd2hpY2ggd291bGQgaW1wbHkgdGhhdCBtYXJrZXRzIGFyZSBlZmZpY2llbnQsIGFuZCBzbyB0aGVyZSBpcyBubyB3YXkgdG8gc3lzdGVtYXRpY2FsbHkgZWFybiByZXR1cm5zIHRoYXQgZXhjZWVkIHRoZSBicm9hZCBtYXJrZXQgYXMgYSB3aG9sZS4g4oCcQWxwaGEgaXMgb2Z0ZW4gdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGJldGEgKHRoZSBHcmVlayBsZXR0ZXIgzrIpLCB3aGljaCBtZWFzdXJlcyB0aGUgYnJvYWQgbWFya2V0J3Mgb3ZlcmFsbCB2b2xhdGlsaXR5IG9yIHJpc2ssIGtub3duIGFzIHN5c3RlbWF0aWMgbWFya2V0IHJpc2su4oCdIChKLiBDaGVuLCAwMy4xOS4yMikNCkFscGhhIGlzIG9uZSBvZiB0aGUgZml2ZSBwb3B1bGFyIHRlY2huaWNhbCBpbnZlc3RtZW50IHJpc2sgcmF0aW9zLiBUaGUgb3RoZXJzIGJlaW5nIEJldGEsIFN0YW5kYXJkIERldmlhdGlvbiwgUi1TcXVhcmVkIGFuZCB0aGUgU2hhcnBlIFJhdGlvLiBUaGVzZSBzdGF0aXN0aWNhbCBtZWFzdXJlbWVudHMgYXJlIHVzZWQgaW4gTW9kZXJuIFBvcnRmb2xpbyBUaGVvcnkuIFRoZXNlIHBhc3QgaW5kaWNhdG9ycyBhcmUgaW50ZW5kZWQgdG8gaGVscCBpbnZlc3RvcnMgZGV0ZXJtaW5lIHRoZSByaXNrLXJldHVybiBwcm9maWxlIG9mIGFuIGludmVzdG1lbnQuDQogIEhhdmluZyByZW1lbWJlcmVkIHRoaXMsIHdlIGNhbiBzYXkgdGhhdCBmaW5kaW5nIGEgY29tYmluYXRpb24gb2YgbG93IEJldGEgdmFsdWVzLCBoaWdoIEFscGhhIHZhbHVlcywgYW5kIGEgUC1WYWx1ZSB0aGF0IGRldGVybWluZXMgdGhlIGxpa2VsaWhvb2QgdGhhdCBvdXIgb2JzZXJ2ZWQgb3V0Y29tZSBpcyBub3QgdGhlIHJlc3VsdCBvZiBjaGFuY2UuIE5hdHVyYWxseSwgb3VyIGRhdGEgdG9vbCAoIFIgKSBkaWQgbW9zdCBvZiB0aGUgc3RhdGlzdGljYWwgd29yayBmb3IgdXMuIA0KICANCnNPVVJDRVM6DQpodHRwczovL3d3dy5pbnZlc3RvcGVkaWEuY29tL3Rlcm1zL3AvcC12YWx1ZS5hc3ANCmh0dHBzOi8vd3d3LmludmVzdG9wZWRpYS5jb20vdGVybXMvbS9tb2Rlcm5wb3J0Zm9saW90aGVvcnkuYXNwDQpodHRwczovL3d3dy5pbnZlc3RvcGVkaWEuY29tL3Rlcm1zL2EvYWxwaGEuYXNwIzp+OnRleHQ9QWxwaGElMkMlMjBvZnRlbiUyMGNvbnNpZGVyZWQlMjB0aGUlMjBhY3RpdmUsaW5kZXglMjBpcyUyMHRoZSUyMGludmVzdG1lbnQncyUyMGFscGhhLg0KaHR0cHM6Ly93d3cuaW52ZXN0b3BlZGlhLmNvbS90ZXJtcy9iL2JldGEuYXNwDQpodHRwczovL3d3dy5pbnZlc3RvcGVkaWEuY29tL3Rlcm1zL20vbWFya2V0cmlzay5hc3ANCg0KLS0NCg0KQVVUT01BVElDQUxMWSBTRUxFQ1RJTkcgU1RPQ0tTOg0KDQpgYGB7cn0NCnNlbGVjdGlvbi5kZiA8LXJlc3VsdHMuZGZbb3JkZXIocmVzdWx0cy5kZiRiMCxkZWNyZWFzaW5nPVRSVUUpLF0NCg0Kc2VsZWN0aW9uLmRmIDwtc2VsZWN0aW9uLmRmW3NlbGVjdGlvbi5kZiROPjIwLF0NCg0Kc2VsZWN0aW9uLmRmIDwtc2VsZWN0aW9uLmRmWzE6MTEsXQ0KDQoNCnNlbGVjdGlvbi5kZiA8LXNlbGVjdGlvbi5kZlsxOjExLF0NCg0KdXNlbGVjdGlvbi5kZiA8LXNlbGVjdGlvbi5kZiBbLTcsXQ0KdXNlbGVjdGlvbi5kZg0KYGBgDQpBTFRIT1VHSCBCMCBET0VTTidUIExPT0sgQVMgVEVNUFRJTkcgT04gQVZFUkFHRSwgSVRTIFRIRSBNQVggQjAgVEhBVCBMT09LUyBQUk9NSVNJTkcgV0lUSCBUSElTIFNFTEVDVElPTi4gQUxNT1NUIEFMTCBDT01QQU5JRVMgQVJFIDQlIEFCT1ZFIE1BUktFVCBSRVRVUk5TLCBXSVRIIFNPTUUgR09JTkcgQUxNT1NUIDklIEhJR0hFUiBSRVRVUk5TIFRIQU4gVEhFIE1BUktFVC4gDQoNCkZJUlNUIFdFIFNFTEVDVCBBTkQgT1JERVIgVEhFIERBVEEgRlJPTSBISUdIRVNUIFRPIExPV0VTVCBBQ0NPUkRJTkcgVE8gQjAgU0lOQ0UgVEhJUyBCRVRBIFJFUFJFU0VOVFMgVEhFIFJFVFVSTlMgT0YgVEhFIFNIQVJFIFdIRU4gTUFSS0VUIFJFVFVSTlMgQVJFIDAsIFRIRU4gQU5ZIERBVEEgR1JFQVRFUiBUSEFOIDAsIEFGVEVSIFRISVMgV0UgT1JERVIgVEhFTSBGUk9NIExPV0VTVCBUTyBISUdIRVNUIERFUEVORElORyBPTiBCMSBXSElDSCBNRUFTVVJFUyBUSEUgUklTSyBPRiBUSEUgQUNUSU9OIEJZIENPTVBBUklTT04gV0lUSCBUSEUgTUFSS0VULiANCg0KIyMgUE9SVEFGT0xJTyBPUFRJTUlaQVRJT04NCmBgYHtyfQ0Kc3RvY2tzcG9ydCA8LSBhcy5saXN0KHJvd25hbWVzKHVzZWxlY3Rpb24uZGYpKQ0Kb2Jqc3RvY2sgPC0gbGFwcGx5KHN0b2Nrc3BvcnQsZ2V0KQ0KcHJpY2VzIDwtIGRvLmNhbGwgKG1lcmdlLCBvYmpzdG9jaykNCnByaWNlczEgPC0gQWQocHJpY2VzKQ0KbmEub21pdChwcmljZXMxKQ0KcG9ydFJldHVybnMgPSBleHAoY29sTWVhbnMocHJpY2VzMSkpLTENCnBvcnRSZXR1cm5zDQpgYGANCk5PVyBXRSBXSUxMIEdFVCBUSEUgQ09WQVJJQU5DRQ0KYGBge3J9DQpDT1Zwb3J0ID0gdmFyKHByaWNlczEpDQpDT1Zwb3J0DQpgYGANCg0KIyBBR0dSRVNTSVZFIFBPUlRGT0xJTw0KRk9SIFRISVMgQ0FTRSBXRSBXSUxMIFVTRSBUSEUgVEFOR0VOQ1kgUE9SVEZPTElPIEZVTkNUSU9OIEJFQ0FVU0UgSVQgV09VTEQgQ0FMQ1VMQVRFIEFOIE9QVElNQUwgUE9SVEZPTElPIEJVVCBGSVJTVCBXRSBXSUxMIE5FRUQgVEhFIFJJU0sgRlJFRSBSQVRFIFdISUNIIFRPREFZIElTIEFUIDQgVEJJTExTM01PTlRILg0KYGBge3J9DQpnZXRTeW1ib2xzKCJUQjNNUyIsIHBlcmlvZGljaXR5ID0gIm1vbnRobHkiLHNyYyA9ICJGUkVEIikNCmBgYA0KYGBge3J9DQpyZnJhdGUgPC0gVEIzTVMNCnJmcmF0ZSA9IHJmcmF0ZS8xMDAvMTINCnJmcmF0ZT0ocmZyYXRlW2luZGV4KEdTUEMpXSkNCiNbIjIwMjAtMDEtMDEvMjAyMi0wNi0zMCIsXQ0KYGBgDQoNClNJTkNFIFdFIEhBVkUgVEhFIFJGUiBNT05USExZLCBXRSBDQU4gQ09OVElOVUUgV09SS0lORyBPTiBUSEUgQUdHUk8gUE9SVEZPTElPDQpgYGB7cn0NCnJmcmF0ZTEgPC1yZnJhdGUgW25yb3cocmZyYXRlKSxdDQphZ3Jwb3J0IDwtIHRhbmdlbmN5LnBvcnRmb2xpbyhwb3J0UmV0dXJucywgQ09WcG9ydCwgMC4wMDEyNDE2NjcsIHNob3J0PUZBTFNFKQ0KIyBXRSBUUklFRCBUTyBJTlNFUlQgVEhFIFZBUklBQkxFIEZPUiBSRlJBVEUgMSBCVVQgSVQgTEVGVCBVUyBXSVRIIEFOIEVSUk9SLCBXRSBQVVQgVEhFIFJJU0sgRlJFRSBBUyBEQVRBDQphZ3Jwb3J0DQpgYGANCmBgYHtyfQ0KQWdyaXNrPSAoYWdycG9ydCRzZCpzcXJ0KDEyKSktNA0KQWdyaXNrDQpgYGANCmBgYHtyfQ0KQWdyRVI9IChhZ3Jwb3J0JGVyKjEyKSotMQ0KQWdyRVINCmBgYA0KYGBge3J9DQp0YW5wb3J0d2VpZ2h0czwtZ2V0UG9ydGZvbGlvKGVyPXBvcnRSZXR1cm5zLGNvdi5tYXQ9Q09WcG9ydCx3ZWlnaHRzPWFncnBvcnQkd2VpZ2h0cykgDQoNCnBsb3QodGFucG9ydHdlaWdodHMsY29sPSJwdXJwbGUiKQ0KYGBgDQpHSVZFTiBUSEUgT0JTRVJWQVRJT05TLCBDT05URU1QTEFUSU5HIEJPVEggVEhFIFJJU0sgQU5EIFRIRSBSRVRVUk4gT0YgVEhFIEFHR1JFU1NJVkUgUE9SVEZPTElPLCBXRSBDQU4gU0FZIFRIQVQgVEhJUyBQT1JURk9MSU8gSVMgMjQlIFJJU0tJRVIgVEhBTiBUSEUgTUFSS0VUIEFORCBPRkZFUlMgQSBQT1NJVElWRSAxMTglIFJFVFVSTiBDT01QQVJFRCBUTyBUSEUgTUFSS0VUIEFWRVJBR0UuDQoNCiMgQ09OU0VSVkFUSVZFIFBPUlRGT0xJTw0KYGBge3J9DQpnbV9wb3J0Zm9saW8gPSBnbG9iYWxNaW4ucG9ydGZvbGlvKHBvcnRSZXR1cm5zLENPVnBvcnQsIHNob3J0cyA9IEZBTFNFKQ0KZ21fcG9ydGZvbGlvDQpgYGANCmBgYHtyfQ0KR01SSVNLPSAoZ21fcG9ydGZvbGlvJHNkKnNxcnQoMTIpKS01LjMNCkdNUklTSw0KYGBgDQpgYGB7cn0NCkdNRVIgPSAoZ21fcG9ydGZvbGlvJGVyKjEyKQ0KR01FUg0KYGBgDQpgYGB7cn0NCmNvbnNlcnZfcG9ydF93ZWlnaHRzPC1nZXRQb3J0Zm9saW8oZXI9cG9ydFJldHVybnMsY292Lm1hdD1DT1Zwb3J0LHdlaWdodHM9Z21fcG9ydGZvbGlvJHdlaWdodHMpIA0KDQpwbG90KGNvbnNlcnZfcG9ydF93ZWlnaHRzLGNvbD0iQlJPV04iKQ0KYGBgDQoNCkdJVkVOIFRIRSBPQlNFUlZBVElPTlMsIENPTlRFTVBMQVRJTkcgQk9USCBUSEUgUklTSyBBTkQgVEhFIFJFVFVSTiBPRiBUSEUgQ09OU0VSVkFUSVZFIFBPUlRGT0xJTywgV0UgQ0FOIFNBWSBUSEFUIFRISVMgUE9SVEZPTElPIEEgQklUIE1PUkUgUklTS1kgQ09NUEFSRUQgVE8gVEhFIE1BUktFVCwgQlVUIE9OTFkgQlkgMTUlLiBPTiBUSEUgT1RIRVIgSEFORCwgSVQgT0ZGRVJTIFJFVFVSTlMgMTY0JSBISUdIRVIgVEhBTiBUSEUgTUFSS0VULg0KDQojIEhPTERJTkcgUEVSSU9EIFJFVFVSTg0KDQpgYGB7cn0NCmZvciAodCBpbiBzdG9ja3Nwb3J0KSB7DQogIHRyeShnZXRTeW1ib2xzKHQsIA0KICAgICAgICAgICAgIGZyb20gPSAiMjAyMS0wNi0wMSIsIHRvID0gIjIwMjItMDYtMDEiLA0KICAgICAgICAgICAgIHBlcmlvZGljaXR5ID0gIm1vbnRobHkiLA0KICAgICAgICAgICAgIHNyYyA9ICJ5YWhvbyIpICkNCn0NCmBgYA0KDQpgYGB7cn0NCnBvcnRsaXN0MiA8LSBsYXBwbHkoc3RvY2tzcG9ydCwgZ2V0KQ0KcHJpY2VzMiA8LSBkby5jYWxsKG1lcmdlLCBwb3J0bGlzdDIpDQoNCmJlc3RsaXN0Mj1hcy5saXN0KHN0b2Nrc3BvcnQpDQoNCmRvLmNhbGwocm0sYmVzdGxpc3QyKQ0KDQpwcmljZXMyLmRmIDwtIGFzLmRhdGEuZnJhbWUoQWQocHJpY2VzMikpICAgDQpjb2xuYW1lcyhwcmljZXMyLmRmKTwtIHN0b2Nrc3BvcnQNCg0KDQpIUFIuZGYgPC0gcHJpY2VzMi5kZltucm93KHByaWNlczIuZGYpLF0gLyBwcmljZXMyLmRmWzEsXSAtIDENCkhQUi5kZg0KYGBgDQoNCmBgYHtyfQ0KIyBXRSdMTCBDT05WRVJUIFRIRSBUQUJMRSBJTlRPIEEgTUFUUklYDQpIUFJtIDwtYXMubWF0cml4KEhQUi5kZikNCmBgYA0KDQpMRVRTIEdPIEFIRUFEIEFORCBVU0UgT1VSIEFHUk8gUE9SVEZPTElPDQpgYGB7cn0NCkFnclBvcnRIUFI8LSB0KGFncnBvcnQkd2VpZ2h0cyApICUqJSB0KEhQUm0pICsgMQ0KDQpBZ3JQb3J0SFBSDQpgYGANClRIRSBIUFIgT0YgVEhFIFBFUklPRCBPRiBPVVIgQUdHUkVTU0lWRSBQRVJJT0QgV0FTIDU3LjUlDQoNCkFORCBOT1cgT1VSIENPTlNFUlZBVElWRSBQT1JURk9MSU8NCmBgYHtyfQ0KZ212UG9ydEhQUjwtIHQoZ21fcG9ydGZvbGlvJHdlaWdodHMgKSAlKiUgdChIUFJtKQ0KZ212UG9ydEhQUg0KYGBgDQpUSEUgSFBSIE9GIE9VUiBBR0dSRVNJVkUgUE9SVEZPTElPIEhBUyBCRUVOIFRIRSBCRVNULCBXSVRIIEEgUkVUVVJOIE9GIDU3LjUlIEFMVEhPVUdIIFRIRSBDT05TRVJWQVRJVkUgUE9SVEZPTElPIEZPTExPV1MgQ0xPU0VMWSBBTkQgSEFTIExFU1NFUiBSSVNLLg0KDQpgYGB7cn0NCm1hcmtldC5kZiA8LSBhcy5kYXRhLmZyYW1lKEFkKEdTUEMkR1NQQy5BZGp1c3RlZCkpDQpIUFJta3Q8LWxhc3QobWFya2V0LmRmJEdTUEMuQWRqdXN0ZWQpL2ZpcnN0KG1hcmtldC5kZiRHU1BDLkFkanVzdGVkKSAtIDIgDQpIUFJta3QNCmBgYA0KVEhFIEhPTERJTkcgUEVSSU9EIFJFVFVSTiBGT1IgVEhFIE1BUktFVCBJUyBXT1JTRSBUSEFOIFRIRSBBR0dSRVNJVkUgUE9SVEZPTElPIEJZIDE4JS4gDQoNCiMjIE9QVElPTlMNCg0KSW4gdGhlIGRlcml2YXRpdmVzIG1hcmtldCB0aGVyZSBhcmUgY29udHJhY3RzIHRoYXQsIGR1ZSB0byB0aGVpciB3YXkgb2Ygb3BlcmF0aW5nLCBhcmUgZGl2aWRlZCBpbnRvIDIsIHN0YW5kYXJkaXplZCBhbmQgbm9uLXN0YW5kYXJkaXplZCBjb250cmFjdHMsIGFtb25nIHRoZSBzdGFuZGFyZGl6ZWQgdGhlcmUgYXJlIDMgZm9ybXMgb2YgY29udHJhY3RzIHJlZ3VsYXJpemVkIGJ5IE1FWERFUiwgRlVUVVJFUywgT1BUSU9OUyBBTkQgU1dBUFMsIGZvciB0aGUgcmVhbGl6YXRpb24gSW4gdGhpcyBlc3NheSB3ZSB3aWxsIGZvY3VzIG9uIHRoZSBvcHRpb25zLCB3aGF0IHRoZXkgYXJlLCB3aGF0IHRoZXkgYXJlIGZvciBhbmQgaG93IHlvdSBjYW4gdGFrZSBhZHZhbnRhZ2Ugb2YgdGhlc2UgY29udHJhY3RzIHdoZW4gY3JlYXRpbmcgYW4gb3B0aW1hbCBwb3J0Zm9saW8uDQoNCldoYXQgYXJlIHRoZXk/IFR5cGVzIG9mIGNvbnRyYWN0czoNCg0KT3B0aW9ucyBhcmUgc3RhbmRhcmRpemVkIGNvbnRyYWN0cyBpbiB3aGljaCB5b3UgaGF2ZSB0aGUgcmlnaHQgdG8gYnV5IG9yIHNlbGwgYSBjZXJ0YWluIGFtb3VudCBvZiBhIGZpeGVkLXByaWNlIGFzc2V0IG92ZXIgYSBjZXJ0YWluIHBlcmlvZCBvZiB0aW1lLCBidXQgeW91IGRvIG5vdCBnZXQgdGhlIG9ibGlnYXRpb24gdG8gZXhjaGFuZ2UgYW4gYXNzZXQgYXQgYSBjZXJ0YWluIHByaWNlIGluIGEgY2VydGFpbiBwZXJpb2Qgb2YgdGltZS4gZXN0YWJsaXNoZWQuIFdpdGhpbiB0aGUgb3B0aW9ucyB0aGVyZSBhcmUgbW9yZSB0eXBlcyBvZiBjb250cmFjdHMgd2l0aCB3aGljaCBzcGVjaWZpYyBzdHJhdGVnaWVzIGNhbiBiZSBmb3JtZWQgZGVwZW5kaW5nIG9uIGhvdyB0aGUgbWFya2V0IGZsdWN0dWF0ZXMuIFdpdGhpbiB0aGVzZSBjb250cmFjdHMgd2UgZmluZCB0aGUgQ0FMTCBwdXJjaGFzZSBvcHRpb24gYW5kIHRoZSBQVVQgcHVyY2hhc2Ugb3B0aW9uLg0KDQpGaXJzdCBsZXQncyBsb29rIGF0IHRoZSBDQUxMIHB1cmNoYXNlIG9wdGlvbiwgd2hlcmUgeW91IGhhdmUgdGhlIGJ1eWVyIGFuZCBhIHNlbGxlciwgd2hlcmUgdGhlIGJ1eWVyIGhhcyB0aGUgcmlnaHQgdG8gYnV5IGFuZCB0aGUgc2VsbGVyIGhhcyB0aGUgb2JsaWdhdGlvbiB0byBzZWxsLCBpbiB0aGUgc2FtZSB3YXkgdGhlcmUgYXJlIHBvc2l0aW9ucyBjYWxsZWQgTE9ORyBDQUxMLCB3aGVyZSB0aGlzIGlzIGNvdmVycyB0aGUgcmlzayBvZiB0aGUgcG9zc2libGUgcmlzZSBvZiB0aGUgdW5kZXJseWluZyBhbmQgdGhlIFNIT1JUIENBTEwgd2hlcmUgdGhlIHBvc3NpYmxlIGZhbGwgb2YgdGhlIHVuZGVybHlpbmcgaXMgY292ZXJlZC4gRmluYWxseSwgaXQgaXMgbmVjZXNzYXJ5IHRvIG1lbnRpb24gdGhlIHVzZSBvZiBhIFBSRU1JVU0gaW4gdGhlc2Ugb3BlcmF0aW9ucywgd2hlcmUgaW4gdGhlIGNhc2Ugb2YgdGhlIGJ1eWVyIGluIGEgTE9ORyBDQUxMIHRoZXJlIGlzIGEgbG9zcyBvZiB0aGUgcHJlbWl1bSwgd2hpY2ggaXMgdGhlIGdhaW4gb2YgdGhlIHNlbGxlciB3aXRoIGEgU0hPUlQgQ0FMTCBwb3NpdGlvbi4NCg0KQ29udGludWluZyB3ZSBoYXZlIHRoZSBQVVQgc2FsZSBvcHRpb24sIHdoZXJlIGluIHRoZSBzYW1lIHdheSB3ZSBoYXZlIDIgcG9zaXRpb25zIGNhbGxlZCBMT05HIFBVVCwgd2hlcmUgYSBwb3NzaWJsZSByaXNrIG9mIHRoZSBmYWxsIG9mIGFuIHVuZGVybHlpbmcgaXMgY292ZXJlZCBhbmQgYSBTSE9SVCBQVVQgd2hlcmUgYSBwb3NzaWJsZSByaXNrIG9mIGFuIHVuZGVybHlpbmcgcmlzZSBpcyBjb3ZlcmVkLiBJbiB0aGlzIGNhc2UsIHRoZSBidXllciBoYXMgdGhlIHJpZ2h0IHRvIHNlbGwgYW5kIHRoZSBzZWxsZXIgaGFzIHRoZSBvYmxpZ2F0aW9uIHRvIGJ1eS4gSW4gdGhlIGNhc2Ugb2YgdGhlIHByZW1pdW0sIHNvbWV0aGluZyBzaW1pbGFyIHRvIHRoZSBDQUxMIGNhbiBiZSBvYnNlcnZlZCwgaGF2aW5nIGEgbG9zcyBvZiB0aGUgcHJlbWl1bSBvbiB0aGUgYnV5ZXIncyBzaWRlIGFuZCBhIGdhaW4gb2YgdGhlIHByZW1pdW0gb24gdGhlIHNlbGxlcidzIHBvc2l0aW9uLg0KDQpUWVBFUyBPRiBFWEVSQ0lTRSBJTiBUSEUgQ0xBU1NJRklDQVRJT04NCk9GIE9QVElPTlM6DQpXaXRoaW4gdGhlIHB1cmNoYXNlIG9wZXJhdGlvbnMgKExPTkcgQ0FMTCkgYW5kIHNhbGVzIChMT05HIFBVVCkgd2UgaGF2ZSBkaWZmZXJlbnQgY2xhc3NpZmljYXRpb25zIG9mIGV4ZXJjaXNlcyBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgZXhlcmNpc2UgcHJpY2UgKFNUUklLRSkgaXMgZ3JlYXRlciB0aGFuLCBlcXVhbCB0byBvciBsZXNzIHRoYW4gdGhlIHVuZGVybHlpbmcgcHJpY2UgKFNQT1QpLCBnaXZpbmcgYW4gZXhhbXBsZSBmb3IgYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyB3ZSBoYXZlIHRoZSBmb2xsb3dpbmcgZGF0YToNCg0KTUFUVVJJVFkgUkFURSwgQklOT01JTkFMIE1PREVMIEFORCBCTEFDSyBBTkQgU0NIT0xFUzoNClRoZSBCbGFjayAmIFNjaG9sZXMgbW9kZWwgYWxsb3dzIG9idGFpbmluZyB0aGVvcmV0aWNhbCB2YWx1ZXMgZm9yIEVVUk9QRUFOIFBVVCBBTkQgQ0FMTCBPUFRJT05TIG9uIHNoYXJlcyB0aGF0IGRvIG5vdCBwYXkgZGl2aWRlbmRzLiBUaGUga2V5IGFyZ3VtZW50IGlzIHRoYXQgaW52ZXN0b3JzIGNvdWxkIHNhZmVseSBvZmZzZXQgbG9uZyBwb3NpdGlvbnMgd2l0aCBzaG9ydCBwb3NpdGlvbnMgaW4gc2hhcmVzIGFuZCBjb250aW51YWxseSBhZGp1c3QgdGhlIGNvdmVyYWdlIHJhdGlvICh0aGUgZGVsdGEgdmFsdWUpIGlmIG5lY2Vzc2FyeS4gQXNzdW1pbmcgdGhhdCB0aGUgdW5kZXJseWluZyBwcmljZSBmb2xsb3dzIGEgcmFuZG9tIHByb2Nlc3MgYW5kIHVzaW5nIHN0b2NoYXN0aWMgY2FsY3VsYXRpb24gbWV0aG9kcywgdGhlIG9wdGlvbiBwcmljZSBjYW4gYmUgY2FsY3VsYXRlZCB3aGVyZSB0aGVyZSBhcmUgbm8gYXJiaXRyYWdlIHBvc3NpYmlsaXRpZXMuDQoNCkZpbmFsbHksIHRoZSBCSU5PTUlOQUwgbW9kZWwgYXNzdW1lcyB0aGF0IHRoZXJlIGFyZSBvbmx5IHR3byBwb3NzaWJsZSB2YWx1ZXMgZm9yIHRoZSBleGNoYW5nZSByYXRlIGluIHRoZSBuZXh0IHBlcmlvZDogVXAgb3IgRG93bi4gVGhlIGFkdmFudGFnZSBpcyB0aGF0IHZhbHVhdGlvbiB1c2luZyB0aGUgYmlub21pYWwgbW9kZWwgYWxsb3dzIGFuIGVhc3kgdW5kZXJzdGFuZGluZyBvZiB0aGUgbG9naWMgYmVoaW5kIG9wdGlvbiB2YWx1YXRpb25zLiBJdCBhbHNvIGFsbG93cyBsYXlpbmcgdGhlIGZvdW5kYXRpb25zIGZvciBtb3JlIGNvbXBsZXggdmFsdWF0aW9ucyBzdWNoIGFzIHRoZSBCbGFjay1TY2hvbGVzLiBJdCBjYW4gYmUgdXNlZCBzYXRpc2ZhY3RvcmlseSB3aGVuIHRoZSBwcm9iYWJpbGl0aWVzIG9mIGFuIGluY3JlYXNlIGluIHRoZSBleGNoYW5nZSByYXRlIHZhcnkgb3ZlciB0aW1lLiBSZWdhcmRpbmcgaXRzIGxpbWl0YXRpb25zLCBpdCBhc3N1bWVzIHRoYXQgdGhlIHZhcmlhdGlvbnMgaW4gdGhlIGV4Y2hhbmdlIHJhdGUgYXJlIGRpc2NyZXRlIGluIHRpbWUuDQoNCklOVkVTVE1FTlQgU1RSQVRFR0lFUyBGT1IgT1BUSU9OUzoNCk9wdGlvbnMgdHJhZGluZyBzdHJhdGVnaWVzIHJlZmVyIHRvIGJ1eWluZyBQVVRTIG9yIENBTExTIG9yIHNlbGxpbmcgQ0FMTFMgb3IgUFVUUyBvciBib3RoIHRvZ2V0aGVyIGluIG9yZGVyIHRvIGxpbWl0IGxvc3NlcyBhbmQgbWFrZSB1bmxpbWl0ZWQgcHJvZml0cy4gQmFzaWNhbGx5LCBpdCBpcyBhYm91dCB1c2luZyBvbmUgb3Igc2V2ZXJhbCBjb21iaW5hdGlvbnMgdG8gb2J0YWluIHRoZSBiZXN0IHBvc3NpYmxlIHJlc3VsdCBiYXNlZCBvbiBvdXIgZGVmaW5lZCBwYXJhbWV0ZXJzLiBPcHRpb25zIHRyYWRpbmcgc3RyYXRlZ2llcyBjYW4gYmUgY2xhc3NpZmllZCBhcyBidWxsaXNoLCBiZWFyaXNoLCBvciBuZXV0cmFsLiBUbyBjYXJyeSBvdXQgdGhpcyByZXNlYXJjaCwgd2UgY29tcGlsZWQgMTAgdHlwZXMgb2YgdHJhZGluZyBzdHJhdGVnaWVzIGluIG9yZGVyIHRvIGJldHRlciBtaXRpZ2F0ZSB0aGUgcmlzayBpbiBvdXIgcG9ydGZvbGlvcy4NCg0KVG8gYmVnaW4gd2l0aCwgd2Ugd2lsbCBmb2N1cyBvbiBidWxsaXNoIG9wdGlvbiBzdHJhdGVnaWVzLCB0aGUgZmlyc3QgaXMgY2FsbGVkICJCVUxMIENBTEwgU1BSRUFEIiwgVGhlc2Ugb3B0aW9uIHN0cmF0ZWdpZXMgaW52b2x2ZSBidXlpbmcgYW4gIkFUIFRIRSBNT05FWSIgb3B0aW9uIGFuZCBzZWxsaW5nIGFuICJPVVQgT0YgVEhFIE1PTkVZIiBvcHRpb24uIOKAnSwgaW4gdGhpcyBzdHJhdGVneSBpdCBpcyBpbXBvcnRhbnQgdG8gbm90ZSB0aGF0IGJvdGggY2FsbCBvcHRpb25zIG11c3QgaGF2ZSB0aGUgc2FtZSB1bmRlcmx5aW5nIHN0b2NrIGFuZCB0aGUgc2FtZSBleHBpcmF0aW9uIGRhdGUuIEhlcmUgeW91IG1ha2UgYSBwcm9maXQgd2hlbiB0aGUgdW5kZXJseWluZyBzaGFyZSBwcmljZSByaXNlcywgd2hpY2ggaXMgZXF1YWwgdG8gdGhlIHNwcmVhZCBtaW51cyB0aGUgbmV0IGRlYml0LCBhbmQgeW91IG1ha2UgYSBsb3NzIHdoZW4gdGhlIHNoYXJlIHByaWNlIGZhbGxzLCB3aGljaCBpcyBlcXVhbCB0byB0aGUgbmV0IGRlYml0LiBUaGUgbmV0IGRlYml0IGlzIGVxdWFsIHRvIHRoZSBwcmVtaXVtIHBhaWQgZm9yIGEgbG93ZXIgc3RyaWtlIG1pbnVzIHRoZSBwcmVtaXVtIHJlY2VpdmVkIGZvciBhIGhpZ2hlciBzdHJpa2UuIFRoZSBzcHJlYWQgcmVmZXJzIHRvIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGhpZ2hlc3QgYW5kIGxvd2VzdCBzdHJpa2UgcHJpY2UuDQoNClRoZSBzZWNvbmQgc3RyYXRlZ3kgaXMgY2FsbGVkIEJVTEwgUFVUIFNQUkVBRC4gVGhpcyBzdHJhdGVneSBpcyB1c2VkIGJ5IG9wdGlvbiB0cmFkZXJzIHdoZW4gdGhleSBhcmUgbGVzcyBvcHRpbWlzdGljIGFib3V0IHRoZSBtb3ZlbWVudCBvZiB0aGUgdW5kZXJseWluZyBhc3NldCwgaW4gdGhpcyBzdHJhdGVneSB5b3UgYnV5IGEgcHV0IG9wdGlvbiBPdXQgb2YgdGhlIG1vbmV5IGFuZCBzZWxsIDEgcHV0IG9wdGlvbiBpbiB0aGUgbW9uZXkuIEhlcmUgaXQgaXMgZm9ybWVkIGJ5IGEgbmV0IGNyZWRpdCByZWNlaXZlZCB0aGF0IGluY3VycyBhIGJlbmVmaXQgYXQgdGhlIHRpbWUgb2YgdGhlIHByaWNlIGluY3JlYXNlIGFuZCBvbiB0aGUgb3RoZXIgaGFuZCB0aGUgcG90ZW50aWFsIGxvc3MgYW5kIG9jY3VycyB3aGVuIHRoZSBzaGFyZSBmYWxscyBiZWxvdyB0aGUgZXhlcmNpc2UgcHJpY2Ugb2YgdGhlIGxvbmcgcHV0IG9wdGlvbi4NCg0KVGhlIHRoaXJkIHN0cmF0ZWd5IHJlZmVycyB0byB0aGUgQ0FMTCBSQVRJTyBCQUNLIFNSUEVBRCwgdGhpcyBzdHJhdGVneSBpcyBvbmUgb2YgdGhlIGVhc2llc3QgZm9yIHRoZSBpbnZlc3RpbmcgcHVibGljLCBpbiB0aGlzIHN0cmF0ZWd5IHRoZSBvcGVyYXRvcnMgY2FuIG9idGFpbiBnb29kIG1hcmdpbnMgd2hlbiB0aGUgbWFya2V0IGlzIGJ1bGxpc2ggYW5kIGluIHRoZSBzYW1lIHdheSB3aGVuIHRoZSBtYXJrZXQgZ29lcyBkb3duLCB0aGUgbG9zcyBjYW4gb2NjdXIgb25seSBpZiB0aGUgbWFya2V0IGlzIHN0YWJsZSBmb3IgYSBsb25nIHRpbWUgb3Igd2l0aGluIGEgc3BlY2lmaWMgcmFuZ2UuIFRoaXMgc3RyYXRlZ3kgY29uc2lzdHMgb2YgYnV5aW5nIDIgT1RNIG9wdGlvbnMgYW5kIHNlbGxpbmcgb25lIElUTSBjYWxsIG9wdGlvbi4NCg0KVGhlIGZvdXJ0aCBzdHJhdGVneSBpcyBjYWxsZWQgU3ludGhldGljIENhbGwsIHRoaXMgaXMgb25lIG9mIHRoZSBidWxsaXNoIG9wdGlvbnMgc3RyYXRlZ2llcyB1c2VkIGZvciB0aG9zZSB3aG8gaGF2ZSBhbiBvcHRpbWlzdGljIHZpZXcgb2Ygc3RvY2tzIGluIHRoZSBsb25nIHRlcm0sIGJ1dCB3aG8gYXJlIGF3YXJlIG9mIHRoZSByaXNrIHdoZW4gdGhleSBmYWxsLiBUaGUgc3RyYXRlZ3kgY29uc2lzdHMgb2YgYnV5aW5nIHB1dCBvcHRpb25zIG9uIHRoZSBzdG9jayB0aGF0IHdlIGhhdmUgYW5kIG9uIHdoaWNoIHdlIGhhdmUgYSBidWxsaXNoIHZpZXcuIElmIHRoZSBwcmljZSBvZiB0aGUgdW5kZXJseWluZyBnb2VzIHVwLCB3ZSB3aWxsIG1ha2UgYSBwcm9maXQsIHdoaWxlIGlmIHRoZSBwcmljZSBnb2VzIGRvd24sIHRoZSBsb3NzIHdpbGwgYmUgbGltaXRlZCB0byB0aGUgcHJlbWl1bSBwYWlkIGZvciB0aGUgcHV0IG9wdGlvbi4gVGhpcyBzdHJhdGVneSBpcyBzaW1pbGFyIHRvIHRoZSBzdHJhdGVneSBvZiBwcm90ZWN0aW9uIHB1dCBvcHRpb25zLg0KDQpOb3cgd2UgbW92ZSBvbiB0byB0aGUgIkJFQVJJU0giIG9yIGJlYXJpc2ggb3B0aW9ucyBzdHJhdGVnaWVzLCBpbiB0aGUgZmlyc3Qgc3RyYXRlZ3kgdGhhdCB3ZSB3aWxsIHJldmlldyB3aWxsIGJlIHRoZSAiQkVBUiBDQUxMIFNQUkVBRCIsIHRoaXMgc3RyYXRlZ3kgY29uc2lzdHMgb2YgYnV5aW5nIGFuIE9UTSBjYWxsIG9wdGlvbiBvciBhIGhpZ2hlciBleGVyY2lzZSBwcmljZSBhbmQgc2VsbGluZyBhbiBvcHRpb24gb2YgcHVyY2hhc2UgYXQgYSBsb3dlciBzdHJpa2UgcHJpY2UsIGJvdGggY2FsbCBvcHRpb25zIG11c3QgaGF2ZSB0aGUgc2FtZSB1bmRlcmx5aW5nIHNlY3VyaXR5IGFuZCBhbHNvIHRoZSBzYW1lIGV4cGlyYXRpb24gZGF0ZS4NCg0KVGhlIGZvbGxvd2luZyBzdHJhdGVneSBpcyBjYWxsZWQg4oCcQkVBUiBQVVQgU1BSRUFE4oCdIGFuZCBjb25zaXN0cyBvZiBidXlpbmcgdGhlIElUTSBwdXQgb3B0aW9uIGFuZCBzZWxsaW5nIHRoZSBPVE0gcHV0IG9wdGlvbi4gTm90ZSB0aGF0IGJvdGggcHV0IG9wdGlvbnMgbXVzdCBoYXZlIHRoZSBzYW1lIHVuZGVybHlpbmcgc3RvY2sgYW5kIHRoZSBzYW1lIGV4cGlyYXRpb24gZGF0ZS4NCg0KVGhlIHNldmVudGggc3RyYXRlZ3kgaXMgY2FsbGVkICJTVFJJUCIgSXQgbXVzdCBiZSB0YWtlbiBpbnRvIGFjY291bnQgdGhhdCB0aGVzZSBvcHRpb25zIG11c3QgYmUgcHVyY2hhc2VkIG9uIHRoZSBzYW1lIHVuZGVybHlpbmcsIGFuZCBhbHNvIHdpdGggdGhlIHNhbWUgZXhlcmNpc2UgcHJpY2UgYW5kIHRoZSBzYW1lIGV4cGlyYXRpb24gZGF0ZSwgaW52ZXN0b3JzIG9idGFpbiBiZW5lZml0cyB3aGVuIHRoZSB1bmRlcmx5aW5nIHNoYXJlIHByaWNlIG1ha2VzIGEgc3Ryb25nIG1vdmUgdXAgb3IgZG93biBhdCBleHBpcmF0aW9uLCBidXQgeW91IHVzdWFsbHkgbWFrZSBiaWcgcHJvZml0cyB3aGVuIHByaWNlcyBtb3ZlIGRvd24uDQoNCuKAnFNZTlRIRVRJQyBQVVTigJ0gVGhlIGJlbmVmaXRzIG9mIHRoaXMgc3RyYXRlZ3kgYXJlIG9idGFpbmVkIHdoZW4gdGhlcmUgaXMgYSBkZWNyZWFzZSBpbiB0aGUgcHJpY2Ugb2YgdGhlIHVuZGVybHlpbmcgc3RvY2ssIHdoaWNoIGlzIHdoeSB0aGlzIHN0cmF0ZWd5IGlzIGFsc28ga25vd24gYXMgYSBzeW50aGV0aWMgbG9uZyBwdXQuIFRoZSBzeW50aGV0aWMgbG9uZyBwdXQgaXMgc28gbmFtZWQgYmVjYXVzZSB0aGlzIHN0cmF0ZWd5IGhhcyB0aGUgc2FtZSBwcm9maXQgcG90ZW50aWFsIGFzIHRoZSBsb25nIHB1dC4NCg0KTm93IHdlIGdvIHdpdGggdGhlIG9wdGlvbnMgc3RyYXRlZ2llcyB0aGF0IGFyZSBjb25zaWRlcmVkIG1vcmUgbmV1dHJhbCB3aGVuIGxvb2tpbmcgYXQgdGhlIG1hcmtldCwgImxvbmcgYW5kIHNob3J0IHN0cmFkZGxlcy4iIFRoaXMgc3RyYXRlZ3kgY29uc2lzdHMgb2YgYnV5aW5nIHRoZSBBVE0gQ2FsbCBhbmQgUHV0IG9wdGlvbnMuIEl0IG11c3QgYmUgdGFrZW4gaW50byBhY2NvdW50IHRoYXQgYm90aCBvcHRpb25zIG11c3QgYmVsb25nIHRvIHRoZSBzYW1lIHVuZGVybHlpbmcsIHRoZXkgbXVzdCBoYXZlIHRoZSBzYW1lIGV4cGlyYXRpb24gYW5kIGFsc28gYmVsb25nIHRvIHRoZSBzYW1lIHN0cmlrZS4NCg0K4oCcTE9ORyBBTkQgU0hPUlQgQlVUVEVSRkxZIOKAnFRoaXMgc3RyYXRlZ3kgY29uc2lzdHMgb2YgYnV5aW5nIGFuIElUTSBjYWxsIG9wdGlvbiwgd3JpdGluZyB0d28gQVRNIGNhbGwgb3B0aW9ucywgYW5kIHRoZW4gYnV5aW5nIGFuIE9UTSBjYWxsIG9wdGlvbi4g4oCcVGhlIHNob3J0IGJ1dHRlcmZseeKAnSBjb25zaXN0cyBvZiBzZWxsaW5nIG9uZSBjYWxsIG9wdGlvbiBpbi10aGUtbW9uZXksIGJ1eWluZyB0d28gY2FsbCBvcHRpb25zIGF0LXRoZS1tb25leSBhbmQgc2VsbGluZyBvbmUgY2FsbCBvcHRpb24gb3V0LW9mLXRoZS1tb25leS4NCg0KUkVGRVJFTkNFUzoNCg0KMTIgUG93ZXJmdWwgT3B0aW9ucyBTdHJhdGVnaWVzIEV2ZXJ5IFRyYWRlciBTaG91bGQgS25vdy4gKDIwMjEsIFNlcHRlbWJlciAzKS4gaHR0cHM6Ly93d3cuZWxlYXJubWFya2V0cy5jb20vYmxvZy8xMi1tdXN0LWtub3ctb3B0aW9uLXRyYWRpbmctc3RyYXRlZ2llcy8NCg0KRG93bmV5LCBMLiAoMjAxOCwgT2N0b2JlciAxMikuIDEwIG9wdGlvbnMgc3RyYXRlZ2llcyB0byBrbm93LiBJbnZlc3RvcGVkaWEuIGh0dHBzOi8vd3d3LmludmVzdG9wZWRpYS5jb20vdHJhZGluZy9vcHRpb25zLXN0cmF0ZWdpZXMvDQoNCkJlc3Qgb3B0aW9uIHRyYWRpbmcgc3RyYXRlZ2llcy4gKDIwMjIsIEp1bHkgMTQpLiBHcm93dy4gaHR0cHM6Ly9ncm93dy5pbi9ibG9nL2Jlc3Qtb3B0aW9uLXRyYWRpbmctc3RyYXRlZ2llcw0KDQojIyBPcHRpb25zIFN0cmF0ZWd5IFVzaW5nIEJsYWNrJlNjaG9sZXMgUHJpY2luZyBNb2RlbCBpbiBSDQpUaGUgQmxhY2sgU2Nob2xlcyBtb2RlbCBpcyBhbiBlcXVhdGlvbiB0aGF0IGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBwcmljZSBvZiBjZXJ0YWluIGZpbmFuY2lhbCBhc3NldHMsIFdJVEggVEhFIEJMQUNLIFNDSE9MRVMgV0UgV0lMTCBCRSBBQkxFIFRPIEVTVElNQVRFIFRIRSBDVVJSRU5UIFZBTFVFIE9GIEEgRVVST1BFQU4gT1BUSU9OIEZPUiBUSEUgUFVSQ0hBU0UgKENBTEwpIE9SIFNFTEwgKFBVVCkgT0YgU0hBUkVTIEFUIEEgRlVUVVJFIERBVEUgVEhBTiBWQVJJQUJMRVMgTkVFREVEIEZPUiBUSEUgRlVOQ1RJT04gQVJFOg0KDQpTID0gU3RvY2sgcHJpY2UNCg0KSyA9IFN0cmlrZSBwcmljZSBhdCBleHBpcmF0aW9uIChFdXJvcGVhbikNCg0KciA9IHJpc2sgZnJlZSByYXRlDQoNClQgPSBUaW1lIHRvIG1hdHVyaXR5DQoNCnNpZyA9IFZvbGF0aWxpdHkgb2YgdGhlIHVuZGVybHlpbmcgYXNzZXQgKGRlcGVuZHMgb24gdGhlIHByaWNlLCBldm9sdXRpb24gYW5kIHByaWNlIG9mIGFub3RoZXIgYXNzZXQpDQoNClNJTkNFIFdFIEhBVkUgVEhFU0UgNSBWQVJJQUJMRVMgVE8gQVBQTFkgVEhFIEJMQUNLIEFORCBTQ0hPTEVTIEZVTkNUSU9OIFdJVEggQ09ORElUSU9OQUxTIERFUEVORElORyBPTiBXSEVUSEVSIElUIFdJTEwgQkUgQSBDQUxMIE9SIFBVVCBBTkQgV0UgV0lMTCBDQUxDVUxBVEUgMiBQQVJBTUVURVJTIE9OIEQxIEFORCBEMiBGT1IgQk9USCBVTkRFUkxZSU5HIEFTU0VUUw0KDQpgYGB7cn0NCkJsYWNrU2Nob2xlcyA8LSBmdW5jdGlvbihTLCBLLCByLCBULCBzaWcsIHR5cGUpew0KICANCiAgaWYodHlwZT09IkMiKXsNCiAgZDEgPC0gKGxvZyhTL0spICsgKHIgKyBzaWdeMi8yKSpUKSAvIChzaWcqc3FydChUKSkNCiAgZDIgPC0gZDEgLSBzaWcqc3FydChUKQ0KICANCiAgdmFsdWUgPC0gUypwbm9ybShkMSkgLSBLKmV4cCgtcipUKSpwbm9ybShkMikNCiAgcmV0dXJuKHZhbHVlKX0NCiAgDQogIGlmKHR5cGU9PSJQIil7DQogIGQxIDwtIChsb2coUy9LKSArIChyICsgc2lnXjIvMikqVCkgLyAoc2lnKnNxcnQoVCkpDQogIGQyIDwtIGQxIC0gc2lnKnNxcnQoVCkNCiAgDQogIHZhbHVlIDwtICAoSypleHAoLXIqVCkqcG5vcm0oLWQyKSAtIFMqcG5vcm0oLWQxKSkNCiAgcmV0dXJuKHZhbHVlKX0NCn0NCmBgYA0KDQpXRSBVU0UgVEhFIFBOT1JNIENPTU1BTkQgVE8gU0lNVUxBVEUgQSBOT1JNQUwgRElTVFJJQlVUSU9OIEZPUiBPVVIgUEFSQU1FVEVSUyBkMSBhbmQgZDIgQU5EIEJFIEFCTEUgVE8gQ0FMQ1VMQVRFIFRIRSBWQUxVRVMgT0YgQk9USCBUSEUgQ0FMTCBBTkQgVEhFIFBVVCBOT1cgV0UgV0lMTCBVU0UgVEhFIERBVEEgRlJPTSBPVVIgQUdHUkVTU0lWRSBQT1JURk9MSU8gVE8gQ0FMQ1VMQVRFIFRISVMsIFdFIFdJTEwgVVNFIE9VUiBNT1NUIFJJU0tZIFNUT0NLIElOIFRISVMgVEFCTEUgKFNOQlIpIEFORCBXRSBXSUxMIEFTU0lHTiBBIExJVFRMRSBISUdIRVIgU1RSSUtFIFBSSUNFIFRIQU4gVEhFIFNUT0NLDQoNCmBgYHtyfQ0KQyA8LSBCbGFja1NjaG9sZXMoMjAuMTY3LDI0LDAuMDQxMiwxLCA1OC43MTI4NDcsIkMiKQ0KUCA8LSBCbGFja1NjaG9sZXMoMjAuMTY3LDI0LDAuMDQxMiwxLCA1OC43MTI4NDcsIlAiKQ0KYGBgDQpUSEUgRVNUSU1BVEVEIENVUlJFTlQgVkFMVUVTIE9GIFRIRSBPUFRJT04gRk9SIFRIRSBQVVJDSEFTRSBJUyAyMC4xNiBBTkQgRk9SIFRIRSBTQUxFIENBTUUgMjMuMDMNCg0KIyMgT3B0aW9ucyBTdHJhdGVneSBVc2luZyBTaGFycGUgUmF0aW8NClRvIGNvdmVyIHRoZSBwb3J0Zm9saW8sIHdlIG11c3QgY2hvb3NlIHRocmVlIHN0cm9uZ2x5IHJlbGF0ZWQgc3RvY2tzLiBUd28gaW5kZXBlbmRlbnQgYWN0aW9ucyBoYXZlIG5vIHdheSBvZiBwcm90ZWN0aW5nIGVhY2ggb3RoZXIuIFNpbmNlIHN0b2NrcyBpbiB0aGUgc2FtZSBpbmR1c3RyeSB0ZW5kIHRvIGhhdmUgYSBzdHJvbmdlciByZWxhdGlvbnNoaXAsIHdlIGNob3NlIGZvdXIgc3RvY2tzIGluIHRoZSBpbmZvcm1hdGlvbiB0ZWNobm9sb2d5IGluZHVzdHJ5LCBuYW1lbHkgR09PR0xlLCBJQk0sIGFuZCBBcHBsZS4NCg0KYGBge3J9DQpnZXRTeW1ib2xzKCJHT09HTCIsc3JjPSJ5YWhvbyIpDQpnZXRTeW1ib2xzKCJJQk0iLHNyYz0ieWFob28iKQ0KZ2V0U3ltYm9scygiQUFQTCIsc3JjPSJ5YWhvbyIpDQpgYGANCmBgYHtyfQ0KYmFyQ2hhcnQoR09PR0wpDQpiYXJDaGFydChJQk0pDQpiYXJDaGFydChBQVBMKQ0KYGBgDQoNCkl0J3Mgbm90IGhhcmQgdG8gc2VlIHRoYXQgYWxsIHRocmVlIHN0b2NrcyBleHBlcmllbmNlZCBzaWduaWZpY2FudCBnYWlucyBhZnRlciAyMDA3Lg0KDQojIE1vZGVybiBwb3J0Zm9saW8gdGhlb3J5DQpNb2Rlcm4gUG9ydGZvbGlvIFRoZW9yeSAoTVBUKSBpcyBhIHRoZW9yeSBvZiBmaW5hbmNlIHRoYXQgYXR0ZW1wdHMgdG8gbWF4aW1pemUgZXhwZWN0ZWQgcG9ydGZvbGlvIHJldHVybiBmb3IgYSBnaXZlbiBhbW91bnQgb2YgcG9ydGZvbGlvIHJpc2ssIG9yIGVxdWl2YWxlbnRseSwgbWluaW1pemUgcmlzayBmb3IgYSBnaXZlbiBsZXZlbCBvZiBleHBlY3RlZCByZXR1cm4gYnkgY2FyZWZ1bGx5IGNob29zaW5nIHRoZSBwcm9wb3J0aW9ucyBvZiB2YXJpb3VzIGFzc2V0cy4NCg0KSWYgd2UgaGF2ZSB0aHJlZSByaXNreSBhc3NldHMgYW5kIHdlIHdhbnQgdG8gcHV0IHRoZW0gaW4gYSBwb3J0Zm9saW8gc28gdGhhdCBnaXZlbiBhIHRhcmdldCByZXR1cm4sIHJpc2sgaXMgbWluaW1pemVkLCBvciBnaXZlbiByaXNrIHByZWZlcmVuY2UsIHdlIG1heGltaXplIHJldHVybi4gQm90aCBtZXRob2RzIHRyeSB0byBtYXhpbWl6ZSB0aGUgU2hhcnBlIHJhdGlvLg0KDQpIZXJlIHdlIGNob29zZSB0aGUgZmlyc3QgbWV0aG9kLCBpZS4gdGhlIOKAnE1pbmltdW0gVmFyaWF0aW9uIFBvcnRmb2xpb+KAnS4NCg0KIyBMYWdyYW5nZSBtdWx0aXBsaWVycyBhbmQgbWluaW11bSB2YXJpYW5jZSBwb3J0Zm9saW8NCkluIG1hdGhlbWF0aWNhbCBvcHRpbWl6YXRpb24sIHRoZSBMYWdyYW5nZSBtdWx0aXBsaWVycyBtZXRob2QgKG5hbWVkIGFmdGVyIEpvc2VwaCBMb3VpcyBMYWdyYW5nZSkgaXMgYSBzdHJhdGVneSBmb3IgZmluZGluZyB0aGUgbG9jYWwgbWF4aW1hIGFuZCBtaW5pbWEgb2YgYSBmdW5jdGlvbiBzdWJqZWN0IHRvIGVxdWFsaXR5IGNvbnN0cmFpbnRzLg0KDQpGb3IgZXhhbXBsZSwgY29uc2lkZXIgdGhlIG9wdGltaXphdGlvbiBwcm9ibGVtDQoNCm1pbmltaXplIHZhcihwb3J0Zm9saW8ocjEscjIscjMsY292LHcxLHcyLHczKSkNCg0Kc3ViamVjdCB0bw0KDQpyMStyMityMz10YXJnZXRfcmV0dXJuDQoNCncxK3cyK3czPTENCg0KV2l0aCBSIHByb2dyYW1taW5nIGFuZCBMYWdyYW5nZSBtdWx0aXBsaWVycywgd2UgY2FuIHNvbHZlIHRoZSBwcm9ibGVtIHdpdGggdGhlIGZvbGxvd2luZyBmdW5jdGlvbi4gVGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIHRoZSBiZXN0IHJhdGlvcyBiZXR3ZWVuIHRocmVlIHN0b2NrcywgZ2l2ZW4gdGhlIHRhcmdldCBkYWlseSByZXR1cm4sIGV4cGVjdGVkIGRhaWx5IHJldHVybnMsIGFuZCB0aGUgY292YXJpYW5jZSBtYXRyaXggb2YgdGhlIHRocmVlIHN0b2NrcycgZGFpbHkgcmV0dXJucy4NCg0KYGBge3J9DQptaW5fdmFyaWFuY2VfcG9ydGZvbGlvIDwtZnVuY3Rpb24oZXIsIGNvdm1hdCwgdGFyZ2V0LnJldHVybikNCnsNCiAgICAjIGNvbXB1dGUgbWluaW11bSB2YXJpYW5jZSBwb3J0Zm9saW8gc3ViamVjdCB0byB0YXJnZXQgcmV0dXJuDQogICAgIw0KICAgICMgaW5wdXRzOg0KICAgICMgZXIgICAgICAgICAgICAgICAgICAgICAgICBOIHggMSB2ZWN0b3Igb2YgZXhwZWN0ZWQgcmV0dXJucw0KICAgICMgY292bWF0ICAgICAgICAgICAgICBOIHggTiBjb3ZhcmlhbmNlIG1hdHJpeCBvZiByZXR1cm5zDQogICAgIyB0YXJnZXQucmV0dXJuICAgc2NhbGFyLCB0YXJnZXQgZXhwZWN0ZWQgcmV0dXJuDQogICAgDQogICAgIyBjb21wdXRlIGVmZmljaWVudCBwb3J0Zm9saW8NCiAgICAjDQogICAgb25lcyA8LSByZXAoMSwgbGVuZ3RoKGVyKSkNCiAgICB0b3AgPC0gY2JpbmQoMipjb3ZtYXQsIGVyLCBvbmVzKQ0KICAgIGJvdCA8LSBjYmluZChyYmluZChlciwgb25lcyksIG1hdHJpeCgwLDIsMikpDQogICAgQSA8LSByYmluZCh0b3AsIGJvdCkNCiAgICBiLnRhcmdldCA8LSBhcy5tYXRyaXgoYyhyZXAoMCwgbGVuZ3RoKGVyKSksIHRhcmdldC5yZXR1cm4sIDEpKQ0KICAgIHggPC0gc29sdmUoQSwgYi50YXJnZXQpDQogICAgdyA8LSB4WzE6bGVuZ3RoKGVyKV0NCn0NCmBgYA0KVGhlIG91dHB1dCB3aWxsIGJlIHRoZSBvcHRpbWFsIHJhdGlvIHRoYXQgbWF4aW1pemVzIHRoZSBTaGFycGUgcmF0aW8uDQoNCiMgVHJhZGluZyBTdHJhdGVneQ0KYGBge3J9DQpkYXRhX0dPT0dMPC1kYXRhLmZyYW1lKEdPT0dMKQ0KZGF0YV9HT09HTCREYXRlPC1hcy5EYXRlKHJvd25hbWVzKGRhdGFfR09PR0wpKQ0KZGF0YV9HT09HTCREYWlseV9SZXR1cm49YyhOQSxkaWZmKGxvZyhkYXRhX0dPT0dMJEdPT0dMLkNsb3NlKSkpDQpuYW1lcyhkYXRhX0dPT0dMKTwtYygiT3BlbiIsIkhpZ2giLCJMb3ciLCJDbG9zZSIsIlZvbHVtZSIsIkRhdGUiLCJEYWlseV9SZXR1cm4iKQ0Kcm93bmFtZXMoZGF0YV9HT09HTCkgPC0gTlVMTA0KZGF0YV9HT09HTDwtc3Vic2V0KGRhdGFfR09PR0wsRGF0ZT49YXMuRGF0ZSgiMjAxOC0xMC0wMSIpJkRhdGU8PWFzLkRhdGUoIjIwMjAtMTItMzEiKSxzZWxlY3Q9YygiRGF0ZSIsIk9wZW4iLCJDbG9zZSIsIkRhaWx5X1JldHVybiIpKQ0KDQpkYXRhX0lCTTwtZGF0YS5mcmFtZShJQk0pDQpkYXRhX0lCTSREYXRlPC1hcy5EYXRlKHJvd25hbWVzKGRhdGFfSUJNKSkNCmRhdGFfSUJNJERhaWx5X1JldHVybj1jKE5BLGRpZmYobG9nKGRhdGFfSUJNJElCTS5DbG9zZSkpKQ0KbmFtZXMoZGF0YV9JQk0pPC1jKCJPcGVuIiwiSGlnaCIsIkxvdyIsIkNsb3NlIiwiVm9sdW1lIiwiRGF0ZSIsIkRhaWx5X1JldHVybiIpDQpyb3duYW1lcyhkYXRhX0lCTSkgPC0gTlVMTA0KZGF0YV9JQk08LXN1YnNldChkYXRhX0lCTSxEYXRlPj1hcy5EYXRlKCIyMDE4LTEwLTAxIikmRGF0ZTw9YXMuRGF0ZSgiMjAyMC0xMi0zMSIpLHNlbGVjdD1jKCJEYXRlIiwiT3BlbiIsIkNsb3NlIiwiRGFpbHlfUmV0dXJuIikpDQoNCmRhdGFfQUFQTDwtZGF0YS5mcmFtZShBQVBMKQ0KZGF0YV9BQVBMJERhdGU8LWFzLkRhdGUocm93bmFtZXMoZGF0YV9BQVBMKSkNCmRhdGFfQUFQTCREYWlseV9SZXR1cm49YyhOQSxkaWZmKGxvZyhkYXRhX0FBUEwkQUFQTC5DbG9zZSkpKQ0KbmFtZXMoZGF0YV9BQVBMKTwtYygiT3BlbiIsIkhpZ2giLCJMb3ciLCJDbG9zZSIsIlZvbHVtZSIsIkRhdGUiLCJEYWlseV9SZXR1cm4iKQ0Kcm93bmFtZXMoZGF0YV9BQVBMKSA8LSBOVUxMDQpkYXRhX0FBUEw8LXN1YnNldChkYXRhX0FBUEwsRGF0ZT49YXMuRGF0ZSgiMjAxOC0xMC0wMSIpJkRhdGU8PWFzLkRhdGUoIjIwMjAtMTItMzEiKSxzZWxlY3Q9YygiRGF0ZSIsIk9wZW4iLCJDbG9zZSIsIkRhaWx5X1JldHVybiIpKQ0KYGBgDQoNCmBgYHtyfQ0KR09PR0wxPC1zdWJzZXQoZGF0YV9HT09HTCxEYXRlPj1hcy5EYXRlKCIyMDE4LTAxLTAxIikmRGF0ZTw9YXMuRGF0ZSgiMjAyMC0xMi0zMSIpKQ0KQUFQTDE8LXN1YnNldChkYXRhX0FBUEwsRGF0ZT49YXMuRGF0ZSgiMjAxOC0wMS0wMSIpJkRhdGU8PWFzLkRhdGUoIjIwMjAtMjAtMzEiKSkNCklCTTE8LXN1YnNldChkYXRhX0lCTSxEYXRlPj1hcy5EYXRlKCIyMDE4LTAxLTAxIikmRGF0ZTw9YXMuRGF0ZSgiMjAyMC0yMC0zMSIpKQ0KDQpHT09HTDEkU2hhcmU8LTMzMzMuMy9HT09HTDEkT3BlblsxXQ0KSUJNMSRTaGFyZTwtMzMzMy4zL0lCTTEkT3BlblsxXQ0KQUFQTDEkU2hhcmU8LTMzMzMuNC9BQVBMMSRPcGVuWzFdDQoNCkdPT0dMMSRWYWx1ZTwtR09PR0wxJFNoYXJlKkdPT0dMMSRDbG9zZQ0KSUJNMSRWYWx1ZTwtSUJNMSRTaGFyZSpJQk0xJENsb3NlDQpBQVBMMSRWYWx1ZTwtQUFQTDEkU2hhcmUqQUFQTDEkQ2xvc2UNCg0KVmFsdWU8LUdPT0dMMSRWYWx1ZStJQk0xJFZhbHVlK0FBUEwxJFZhbHVlDQoNCm1lYW4oZGlmZihsb2coVmFsdWUpKSkqMjUyLyhzZChkaWZmKGxvZyhWYWx1ZSkpKSpzcXJ0KDI1MikpDQpgYGANCg0KVGhpcyBTaGFycGUgUmF0aW8gcHJvdmVkIHRvIGJlIGVxdWFsIHRvIC44NS4gVXN1YWxseSwgYSBTaGFycGUgUmF0aW8gYWJvdmUgb2YgMSBpcyBwcmVmZXJyZWQgYXMgaXQgaW1wbGllcyBpdCBvZmZlcnMgbW9yZSByZXR1cm5zIHRoYW4gcmlzaywgYWx0aG91Z2ggYXJndWFibHkgY29tcGFyZWQgdG8gdGhlIG1hcmtldCB0aGlzIGlzIGEgZ29vZCBudW1iZXIuDQoNCiMgRGluYW1pYyBIZWRnZQ0KRmlyc3Qgb2YgYWxsLCB3ZSBuZWVkIHRvIGRlZmluZSBzZXZlcmFsIGZ1bmN0aW9ucyB0byBzaW1wbGlmeSB0aGUgY2FsY3VsYXRpb24uDQoNClRoaXMgZnVuY3Rpb24gY2FsY3VsYXRlcyB0aGUg4oCcdGFyZ2V0IGRhaWx5IHBlcmZvcm1hbmNl4oCdIHRoYXQgd2Ugd2FudCB0byBhY2hpZXZlIGluIGVhY2ggZGF5Lg0KYGBge3J9DQpfdGFyZ2V0PC1mdW5jdGlvbihkYXRhX2dvb2dsZSxkYXRhX2libSxkYXRhX2FwcGxlLGRhdGUpDQp7DQogICAgZDE8LXN1YnNldChkYXRhX2dvb2dsZSxEYXRlPj0oZGF0ZS0zMCkmRGF0ZTw9ZGF0ZSkNCiAgICBkMjwtc3Vic2V0KGRhdGFfaWJtLERhdGU+PShkYXRlLTMwKSZEYXRlPD1kYXRlKQ0KICAgIGQzPC1zdWJzZXQoZGF0YV9hcHBsZSxEYXRlPj0oZGF0ZS0zMCkmRGF0ZTw9ZGF0ZSkNCiAgICANCiAgICBkMSRTaGFyZTwtMzMzMy4zL2QxJE9wZW5bMV0NCiAgICBkMiRTaGFyZTwtMzMzMy4zL2QyJE9wZW5bMV0NCiAgICBkMyRTaGFyZTwtMzMzMy40L2QzJE9wZW5bMV0NCiAgICANCiAgICBkMSRWYWx1ZTwtZDEkU2hhcmUqZDEkQ2xvc2UNCiAgICBkMiRWYWx1ZTwtZDIkU2hhcmUqZDIkQ2xvc2UNCiAgICBkMyRWYWx1ZTwtZDMkU2hhcmUqZDMkQ2xvc2UNCiAgICBWYWx1ZTwtZDEkVmFsdWUrZDIkVmFsdWUrZDMkVmFsdWUNCiAgICANCiAgICBtZWFuKGRpZmYobG9nKFZhbHVlKSkpDQp9DQpgYGANCkVzdGEgZnVuY2nDs24gY2FsY3VsYSBlbCB2YWxvciBtZWRpbyBkZSBsYSByZW50YWJpbGlkYWQgZGlhcmlhIGRlIHVuYSBhY2Npw7NuIGVuIGxvcyAzMCBkw61hcyBhbnRlcmlvcmVzLg0KDQpgYGB7cn0NCnJldHVybl8zMDwtZnVuY3Rpb24oZGF0YV9zZXQsZGF0ZSkNCnsNCiAgICBkPC1zdWJzZXQoZGF0YV9zZXQsRGF0ZT49KGRhdGUtMzApJkRhdGU8PWRhdGUpDQogICAgZCREYWlseV9SZXR1cm4NCn0NCmBgYA0KDQpgYGB7cn0NCnN0YXJ0PW5yb3coc3Vic2V0KGRhdGFfQUFQTCxEYXRlPD1hcy5EYXRlKCIyMDE3LTEyLTMxIikpKSsxDQpkYXRhX0dPT0dMJHNoYXJlPC1OQQ0KZGF0YV9JQk0kc2hhcmU8LU5BDQpkYXRhX0FBUEwkc2hhcmU8LU5BDQp2YWx1ZT1yZXAoTkEsbnJvdyhkYXRhX0FBUEwpKQ0KdmFsdWVbc3RhcnQtMV09OTAwMA0KdzwtbGlzdChucm93KGRhdGFfQUFQTCktc3RhcnQrMSkNCmZvcihpIGluIHN0YXJ0Om5yb3coZGF0YV9BQVBMKSkNCiNFYWNoIHN0ZXAgb2YgdGhlIGZvci1sb29wIGlzIGEgdHJhZGluZyBkYXksIGFuZCB0aGUgaGVkZ2UgcmF0aW8gaXMgdXBkYXRlZCBvbiBldmVyeSBzdGVwLiANCnsNCiAgICBpZiAod2Vla2RheXMoZGF0YV9BQVBMJERhdGVbaV0pPT0iTW9uZGF5IikNCiAgICB7DQogICAgICAgIHJUYXJnZXQ8LXJfdGFyZ2V0KGRhdGFfR09PR0wsZGF0YV9JQk0sZGF0YV9BQVBMLGRhdGFfR09PR0wkRGF0ZVtpXSkNCiAgICAgICAgDQogICAgICAgICNIaXN0b3JpY2FsIHJldHVybnMNCiAgICAgICAgcjE9cmV0dXJuXzMwKGRhdGFfR09PR0wsZGF0YV9HT09HTCREYXRlW2ldKQ0KICAgICAgICByMj1yZXR1cm5fMzAoZGF0YV9JQk0sZGF0YV9JQk0kRGF0ZVtpXSkNCiAgICAgICAgcjM9cmV0dXJuXzMwKGRhdGFfQUFQTCxkYXRhX0FBUEwkRGF0ZVtpXSkNCiAgICAgICAgDQogICAgICAgICNFeHBlY3RlZCByZXR1cm5zDQogICAgICAgIHI9YyhtZWFuKHIxKSxtZWFuKHIyKSxtZWFuKHIzKSkNCiAgICAgICAgDQogICAgICAgICNDb3ZhcmlhbiBNYXRyaXgNCiAgICAgICAgY292X21hdHJpeD12YXIoY2JpbmQocjEscjIscjMpKQ0KICAgICAgICANCiAgICAgICAgI0ZpbmQgdGhlIGhlZGdlIHJhdGlvDQogICAgICAgIHdbW2ktc3RhcnQrMV1dPW1pbl92YXJpYW5jZV9wb3J0Zm9saW8ociwgY292X21hdHJpeCwgclRhcmdldCkNCiAgICAgICAgDQogICAgICAgIGRhdGFfR09PR0wkc2hhcmVbaV09dmFsdWVbaS0xXSp3W1tpLXN0YXJ0KzFdXVsxXS9kYXRhX0dPT0dMJE9wZW5baV0NCiAgICAgICAgZGF0YV9JQk0kc2hhcmVbaV09dmFsdWVbaS0xXSp3W1tpLXN0YXJ0KzFdXVsyXS9kYXRhX0lCTSRPcGVuW2ldDQogICAgICAgIGRhdGFfQUFQTCRzaGFyZVtpXT12YWx1ZVtpLTFdKndbW2ktc3RhcnQrMV1dWzNdL2RhdGFfQUFQTCRPcGVuW2ldDQogICAgICAgIA0KICAgICAgICB2YWx1ZVtpXT1kYXRhX0dPT0dMJHNoYXJlW2ldKmRhdGFfR09PR0wkQ2xvc2VbaV0rZGF0YV9JQk0kc2hhcmVbaV0qZGF0YV9JQk0kQ2xvc2VbaV0rZGF0YV9BQVBMJHNoYXJlW2ldKmRhdGFfQUFQTCRDbG9zZVtpXQ0KICAgIH1lbHNlDQogICAgew0KICAgICAgICBkYXRhX0dPT0dMJHNoYXJlW2ldPWRhdGFfR09PR0wkc2hhcmVbaS0xXQ0KICAgICAgICBkYXRhX0lCTSRzaGFyZVtpXT1kYXRhX0lCTSRzaGFyZVtpLTFdDQogICAgICAgIGRhdGFfQUFQTCRzaGFyZVtpXT1kYXRhX0FBUEwkc2hhcmVbaS0xXQ0KICAgICAgICB2YWx1ZVtpXT1kYXRhX0dPT0dMJHNoYXJlW2ldKmRhdGFfR09PR0wkQ2xvc2VbaV0rZGF0YV9JQk0kc2hhcmVbaV0qZGF0YV9JQk0kQ2xvc2VbaV0rZGF0YV9BQVBMJHNoYXJlW2ldKmRhdGFfQUFQTCRDbG9zZVtpXQ0KICAgICAgICB3W1tpLXN0YXJ0KzFdXT1jKGRhdGFfR09PR0wkc2hhcmVbaV0qZGF0YV9HT09HTCRPcGVuW2ldL3ZhbHVlW2ldLGRhdGFfSUJNJHNoYXJlW2ldKmRhdGFfSUJNJE9wZW5baV0vdmFsdWVbaV0sZGF0YV9BQVBMJHNoYXJlW2ldKmRhdGFfQUFQTCRPcGVuW2ldL3ZhbHVlW2ldKQ0KICAgIH0NCn0NCg0KbWVhbihkaWZmKGxvZyh2YWx1ZVshaXMubmEodmFsdWUpXSkpKSoyNTIvKHNkKGRpZmYobG9nKHZhbHVlWyFpcy5uYSh2YWx1ZSldKSkpKnNxcnQoMjUyKSkNCmBgYA0KDQpXZSBjYW4gc2VlIHRoYXQgd2l0aCB0aGUgZHluYW1pYyBoZWRnaW5nIHN0cmF0ZWd5LCB0aGUgU2hhcnBlIHJhdGlvIGluY3JlYXNlZCBzaWduaWZpY2FudGx5IGZyb20gMC44NSB0byAxLjQ1Lg0KDQojIEhlZGdlIFJhdGlvDQpTaW5jZSB0aGUgdG9waWMgb2YgdGhpcyBwYXJ0IG9mIHRoZXByb2plY3QgaXMgZmluZGluZyB0aGUgaGVkZ2luZyByYXRpbywgbGV0J3MgdGFrZSBhIGxvb2sgYXQgaG93IHRoZSByYXRpbyBvZiB0aGUgdGhyZWUgc3RvY2tzIGNoYW5nZWQgd2l0aCBvdXIgaGVkZ2luZyBzdHJhdGVneS4NCg0KYGBge3J9DQp3MTwtcmVwKDAsbGVuZ3RoKHN0YXJ0Om5yb3coZGF0YV9BQVBMKSkpDQp3MjwtcmVwKDAsbGVuZ3RoKHN0YXJ0Om5yb3coZGF0YV9BQVBMKSkpDQp3MzwtcmVwKDAsbGVuZ3RoKHN0YXJ0Om5yb3coZGF0YV9BQVBMKSkpDQoNCmZvcihpIGluIDE6bGVuZ3RoKHN0YXJ0Om5yb3coZGF0YV9BQVBMKSkpDQp7DQogIHcxW2ldPC13W1tpXV1bMV0NCiAgdzJbaV08LXdbW2ldXVsyXQ0KICB3M1tpXTwtd1tbaV1dWzNdDQp9DQpEYXRlPSBkYXRhX0FBUEwkRGF0ZVtzdGFydDpucm93KGRhdGFfQUFQTCldDQp0ZXN0X2RhdGEgPC0gZGF0YS5mcmFtZSh3MSx3Mix3MyxEYXRlKQ0KDQpnZ3Bsb3QodGVzdF9kYXRhLCBhZXMoRGF0ZSkpICsgDQogIGdlb21fbGluZShhZXMoeSA9IHcxLCBjb2xvdXIgPSAidzEiKSkgKyANCiAgZ2VvbV9saW5lKGFlcyh5ID0gdzIsIGNvbG91ciA9ICJ3MiIpKSArDQogIGdlb21fbGluZShhZXMoeSA9IHczLCBjb2xvdXIgPSAidzMiKSkgDQpgYGANCg0KSW4gc3VtbWFyeSwgdGhlIGFib3ZlIGNvdmVyYWdlIHJhdGlvIHNpZ25pZmljYW50bHkgaW5jcmVhc2VkIHRoZSBTaGFycGUgcmF0aW8gZnJvbSAwLjg1IHRvIDEuNDUsIHdoaWNoIGV4cGVydHMgd291bGQgc2F5IGlzIGEgZ29vZCB2YWx1ZS4=