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.

  1. 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.

  1. 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.

  1. 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=