Abstract
For public sector jobs such as university professors, there are two
types of available retirement plans for their retirement package: The
Defined Contribution (DC) and the Defined Benefit (DB) plan. This
project will focus on the key differences between these plans, including
their structure, benefits, and risks. One critical factor to compare
these two plans is the Net Present Value (NPV). NPV is a way of
calculating the value of future payments or benefits in today’s dollars.
I will comparing the Net Present Value offered by the DC and DB plans
offered by the Illinois State University Retirement System to compare
which is better for the Employer. This will be done by creating a graph
of the two programs in the R Programming language.
Introduction
In the field of actuaries, discussion centers on which retirement
plan is better for the employee: The Defined Benefits (DB) or Defined
Contribution (DC) plan. Currently, many employees’ retirement plans are
determined by their employer, but there has been discussion on turning
Social Security into a DC plan called a Personal Retirement
Account.1 For those who get a choice in their retirement,
such as those under Illinois’s State University Retirement System
(SURS), those people would like to know how much their investments are
worth, and how much they expect to get out of retirement. Broadly, the
Defined Contribution and Defined Benefit plans can be described as
thus:
- Defined Contribution (DC):3 Retirement is in Form of an
Account that both the Employee and Employer contribute to annually. The
account is then invested in assets, whether that be bonds or stock.
Based on the Return on Investment, the employee earns a lump sum to live
off for the rest of their lives.
- Defined Benefits (DB):3 Retirement in the form of annual
payments from the employer. The amount paid is based on a percentage of
your highest-earning salary years determined by your duration of
service.
The goal of this research is to more accurately compare Defined
Benefits and Defined Contribution plans in general by using SURS’s
Retirement Savings Plan (RSP) and Traditional Plan (TRD), the DC and DB
plans respectively, to compare the total pensions of the plan in
different circumstances, such as with different Return Rates or Discount
Rates. This information will be displayed in a graph by R Programming by
following the format of Figure 2 of Which Teacher chooses Defined
Contribution Pension Plan? Evidence from the Florida Retirement
System.2
Methodology
To compare the Retirement Savings Plan (RSP) and the Traditional Plan
(TRD), the “Net Present Value of Benefits at Different Years of
Service”, a graph was created in R Programming to compare the total
value of the two plans over differing years of service. You can think of
the Net Present Value (NPV) as representing the current value of a
future investment. The Graph’s X-Axis represents the Age of Separation
from SURS employment, assumes that the employee’s Age of Enrollment is
32, and that the the employee’s years of employment is consecutive. The
Y-Axis will represent the Net Present Value of the pension of the given
Age of Separation at age 62.
Universal Parameters
To make comparison easier, the plots for both plans will use certain
shared parameters to more accurately compare the two plan. These
parameters are the following:
T: Duration of Service
m0: Initial Salary
a: Annual Salary Increase
T represents the Duration of Service, which will be used to create
the X-Axis’s represent the Duration of Service. This means that the
range for the Age of Separation from the SURS employer is 32 to 62,
which has been decided on to further adhere to Figure 2 of Which
Teacher chooses Defined Contribution Pension Plan? Evidence from the
Florida Retirement System.2
T = 30
m0 = 30000
a = 0.03
The $30,000 for initial salary and a 3% annual salary was chosen
based off of the typical starting university professor.(INSERT
CITATION HERE)
Both plans have variables that will change their annuities, and their
own unique ways to convert their total cash into into Net Present
Values, with the Retirement Savings Plan having a lump sum that an
employee is offered at the end of their employment, while the
Traditional Plan offers continuous annual payments up until the day the
employee dies. Thus, it is important that they have their own deep
dives
Defined Contribution Plan
For the Retirement Savings Plan, and many other Defined Contributions
Plans, money is put into an account at certain time intervals, and the
employer can then use the retirement account’s money to invest into
various stock portfolios so that the account can grow with the stock
market. At retirement, the employee gets a lump sum of money from said
investments to spend during retirement, with the option of purchasing a
retirement-like system. To model SURS’s Retirement Savings plan, I have
created a function called BalanceDC with the input
variables of T and ave.r.
DC Parameters
The following factors are relevant to the Defined Contribution
plan:
contribution: Annual contribution rate (including the
matching rate from the employer)
ave.r: Annual Rate of Return
The Contribution Rate for the RSP program is set to 15.6%, with with
8% being contributed by the employee’s paychecks and 7.6% being
contributed by the employer, which is why it isn’t an input parameter
for BalanceDC. The Rate of Return is average return on
investments in the Retirement Portfolio over all years of investment.
The rate of return for a typical investor is expected to be 5%, but to
adhere to the variability of the Supermarket, Return Rates of
ave.r =0.02 , ave.r = 0.05, and
ave.r = 0.08 will be graphed to display that
variability.
For the RSP’s initial parameters, their values are as shown:
contribution = 15.6/100
ave.r = 0.05
DC Code
To determine the Net Present Value of the RSP at age 62 for each Age
of Separation graphed, there are two time periods to consider: The
Duration of Service that the employee worked for SURS, and the Duration
after service up to age 62.
Duration of Service
The account balance at the start of the Duration of Service is 0. For
each month during the duration of service, the new account grows
naturally with the stock performance, M, but also from the
MonthlyDeposit. These two parameters are vital to
understanding how the RSP account grows.
Monthly Return Rate
The parameter of M represents the monthly Return Rate of
the retirement account, which is I set the parameter M as
my monthly Return Rate for the retirement account. The value of
M is represented by the following equation:
\[
M = (ln(\frac{1+ave.r}{12}))^e
\] Calculating the growth of the portfolio monthly instead of
annually was to more accurately display the natural growth of the
account’s stock portfolio.
Monthly Deposit
The contibution parameter only measures the percentage
of salary provided annually, so from the the year’s annual salary of
mT, the salary is divided by 12 to get the total deposit
that is put into the Account Balance every month. Adding deposits by
month allows said deposits to increase with M, which better
represents the growth of the stocks provided my the deposits.
Duration Before Retirement
After the Age of Separation, neither the Employee nor Employer make
contributions to the retirement account anymore, so the account only
grows based on the Return Rate. This is calculated by taking the current
account balance and multiplying it by the Return Rate raised to the
power the remaining years left until the age of 62. This means that the
rate of return is applied annually instead of monthly, since no payments
are being made to the account anymore.
BalanceDC = function(T, ave.r){
xValues = c(1:T) + 32
yValues = rep (0,T)
for (t in 1:T){
mT = m0
AccountBalance = 0
annualDeposit = mT * contribution
monthlyDeposit = annualDeposit / 12
for (j in 1:t){
M = exp(log(1+ave.r)/12)
for (m in 1:12){
AccountBalance = AccountBalance * M + monthlyDeposit
}
mT = mT * (1+a)
}
AccountBalance = AccountBalance * (1+ave.r)^ (T-t)
yValues[t] = AccountBalance
}
return(data.frame(x=xValues, y=yValues))
}
DC Plot
data2 = BalanceDC(T, 0.02)
data5 = BalanceDC(T, 0.05)
data8 = BalanceDC(T, 0.08)
xDC.min = min(data2$x)
xDC.max = max(data2$x)
x = data8$x
y = data8$y
yDC.min = 0
yDC.max = max(c(data2$y, data5$y, data8$y))
plot(c(xDC.min, xDC.max), c(yDC.min, yDC.max), type="n", yaxt="n",
xlab = "Years of Service",
ylab = "Pension Wealth (NPV Age 62)",
main = "Net Present Value of DC Benefits at age 62")
lines(data2$x, data2$y, lty=1)
points(data2$x, data2$y, pch =16)
lines(data5$x, data5$y, lty=1)
points(data5$x, data5$y, pch =15)
lines(data8$x, data8$y, lty=1)
points(data8$x, data8$y, pch =17)
ytick = (1:6) * 100000
axis(2, at = ytick, las = 2, cex.axis = 0.6,
labels = formatC(ytick, big.mark = ",", format="f", digits = 0))

The initial growth for the Defined Contribution plans are staggering.
From years one to five, the 5% Return Rate for the Retirement Savings
Plan jumps from $19701.08 all the way to $317996.60. This rapid growth
continues for around 15 years, where the account’s value stops
increasing as much. The range of expected Net Present Values at age 62
for SURS’s DC plan ranges from $191,592.76 for 2% Return Rate and
$549,334.73 for the 8% Return Rate.
Defined Benefits Plan
The SURS Defined Contribution Plan is known as the Traditions Plan.
This type of plan is also referred to as Pension. In this form of
retirement, annual payments from one’s employers is given to the
employee every year until they die. The amount paid per year is based on
a percentage of the employee’s highest-earning salary during their
duration of service. In terms of the TRD Plan, SURS provides 2.2% of
your averaged final salary.2 To model the TRD plan, I have
made function BalanceDB with the input parameters
T and discount.r.
DB Parameters
The following Factors are relevant to the Defined Contribution
plan:
pension: annual pension income
discount.r: Discount Rate
The formula for pension for the Pension plan, as well as
the calculations for the NPV of the TRD plan are complicated, so it will
be discussed in the code section.
The Discount Rate is the rate of interest that is applied to future
cash flows of an investment to calculate its present value. Essentially,
it gives an exact value of what a dollar you’ll in the future is worth
to someone currently.
The Discount Rate is a variable between different entities, and so
the two plots for DC rate will be discount.r = 0.00 and
discount.r = 0.04. The discount rate parameter actually
represents the difference between the discount rate and the annual
salary increase rate, meaning we are actually calculating with Discount
rates of 3% and 7% respectively. The discount rate represents the rate
of return used to discount future profits to calculate the current value
of an investment. This rate is offset by the salary increase rate ,
since (INSERT RESASON HERE). Companies suggest using a 3%
discount rate for their annuity, but many employees value their pension
less than the suggested rate, so a discount rate of 7% will better show
the discount rate of the average SURS employee.
The initial parameters are as shown.
pension.percent = 2.2/100
discount.r = 0.00
DB Code
For the TRD plan, the value of the pension parameter is
determined as the product of two values:
ave.m: Average salary over the final 5 years of
service. Since the model assumes that the salary increases by 3%
annually, we can essentially derive the final salary based on the age of
separation from the SURS system, which is why T is set as the graph’s
input.
pension.percent: the percentage of ave.m
that an employee receives annually as pension for their retirement.
Example: With a pension rate of 2.2%, after 16 years of service, an
employee gains 35.2% of their ave.m as their retirement
pension.
After computing pension, the Net Present Value must be
calculated. This is difficult, since pension is paid for several years
until you die. To do that, I computed the (expected)
NPV of the stream of pension income from age 63 to age 119 using the Actuarial Life
Table from Social Security Adminisration website; my mentors used
the complement of death rate to compute the survival probability,
averaged over male and female. The NPV formula is given below \[
\sum_{\text{age} = 63}^{119} ... = \sum_{t = 63-62}^{(119 - 62)}
\text{annual-pension-income} \times p_t \times v^{t - 0.5}
\] where \(v\) \[
v = \frac{1}{1 + \text{discount.rate}}
\] is the discount factor and \[
\begin{aligned}
p_t = & \mathbb{P}(\text{still alive at age} (62+t) \mid
\text{alive at age } 62) \\
= & \quad \mathbb{P}(\text{surve for a year} \mid \text{alive
at age } 62) \\
& \times \mathbb{P}(\text{surve for a year} \mid \text{alive
at age } 63) \times \\
& \times \cdots \times \mathbb{P}(\text{surve for a year} \mid
\text{alive at age } 62+t-1) \\
= & \prod_{j=1}^t \Big [ 1 - \mathbb{P} \big (\text{die within
a year } \mid \text{alive at age } (62 + j-1) \big ) \Big ].
\end{aligned}
\] The probabilities for the last row can be found in the Actuarial Life
Table’s .
setwd("C:/Users/16302/OneDrive - imsa.edu/Documents/R Scripts/")
data = read.table("mtable.txt", sep="\t")
names(data)
names(data) = c("Age", "m.prob", "m.lives", "m.exp", "f.prob", "f.lives", "f.exp")
head(data)
newdata = data.frame(Age = data$Age, prob = data$m.prob + data$f.prob)
probs = newdata$prob[newdata$Age >= 62]
rm("data", "newdata")
Then, using the methods listed above, I computed the NPV for the TRD
Plan.
BalanceDB = function(T, discount.r){
xValues = c(1:T) + 32
yValues = rep(0, T)
if (T < 6){
return(data.frame(x=xValues, y=yValues))
exit
}
pension = rep (0,T)
for(t in 6:T){
tmp = tail(1:t, 2)
ave.m = mean(m0*(1+a)^(tmp-0.5))
pension[t] = ave.m * pension.percent * t
if (pension.percent * t > 0.8){
pension[t] = ave.m * 0.8
}
}
pt = 1
v = 1 / (1+discount.r)
vt = v ^(-0.5)
for(t in 1:length(probs)){
pt = pt * (1-probs[t])
vt = vt * v
yValues = yValues + pension * pt * vt
}
return(data.frame(x = xValues, y = yValues))
}
DC Plot
dataDB0 = BalanceDB(T, 0)
dataDB4 = BalanceDB(T, 0.04)
x = dataDB0$x
y = dataDB0$y
plot(x, y, type="n", yaxt="n",
xlab = "Years of Service",
ylab = "Pension Wealth (NPV at age 62)",
main = "Net Present Value of DC Benefits at age 62")
ytick = (1:8) * 100000
axis(2, at = ytick, las = 2, cex.axis = 0.6,
labels = formatC(ytick, big.mark = ",", format="f", digits = 0))
lines(dataDB0$x, dataDB0$y, lty = 5)
lines(dataDB4$x, dataDB4$y, lty = 3)

The first five years of the Traditional Plan is dedicated to its
vesting period, meaning that the funds for the pension is still being
set up by the company and is not official yet. Only at 38, 6 years after
the age of separation, can the Net Present Value be accounted for. After
that, there is a steady exponential growth for the Net Present Value of
Benefits, as with the case of most defined contribution plans. The range
of expected Net Present Values for SURS’s DB plan after 30 years goes
from $510658.78 to $728559.35.
Results
With the functions BalanceDC and BalanceDB
set, it is now possible to create a graph of their Net Present Values
based on different periods of services that encompasses both graphs with
their input parameters.
dataDC2 = BalanceDC(T, 0.02)
dataDC5 = BalanceDC(T, 0.05)
dataDC8 = BalanceDC(T, 0.08)
dataDB0 = BalanceDB(T, 0)
dataDB4 = BalanceDB(T, 0.04)
x.min = min(dataDC2$x)
x.max = max(dataDC2$x)
y.min = 0
y.max = max(c(dataDC2$y, dataDC5$y, dataDC8$y, dataDB0$y, dataDB4$y))
plot(c(x.min, x.max), c(y.min, y.max), type ="n", xaxt="n", yaxt = "n",
xlab = "Years of Consecutive Service (Start at Age 32)",
ylab = "Pension Wealth (NPV at age 62)",
main = "Net Present Value of Reitrement Plans at Differnt Years of Service")
xtick = (1:30)+32
axis(1, at= xtick, las = 1, cex.axis = 0.6)
ytick = (1:8) * 100000
axis(2, at = ytick, las = 2, cex.axis = 0.55,
labels = formatC(ytick, big.mark = ",", format="f", digits = 0))
lines(dataDC2$x, dataDC2$y, lty=1)
points(dataDC2$x, dataDC2$y, pch =16)
lines(dataDC5$x, dataDC5$y, lty=1)
points(dataDC5$x, dataDC5$y, pch =15)
lines(dataDC8$x, dataDC8$y, lty=1)
points(dataDC8$x, dataDC8$y, pch =17)
lines(dataDB0$x, dataDB0$y, lty = 5)
lines(dataDB4$x, dataDB4$y, lty = 3)

For this graph, The DC plan’s Return Rate of 8% and the DB plan’s
Discount Rate of 3% represents ideal conditions for an employee to get
the most value out of their investments, with a Return Rate of 8%. While
the DB traditional plan is vesting, the DC has an obvious lead from
starting immediately, with the NPV of the 5% Return Rate netting
$89560.14. After vesting, both DB outpace the DC’s 2% Return Rate graph,
but a 2% Return Rate is unlikely to happen, as it’s an example of a
worst case scenario. Between ages 38 to 52, not much happens besides the
DC’s Return Rate of 5% getting outpaced by the DB’s discount rate of 3%.
After 21 years, by Age 53, the 7% Discount Rate DB plan of $273964.20
overtakes the 5% Return Rate DC plan of $265220.10, with the discount
rate continually increasing in size. Notably, however, the 3% Discount
Rate DB plan is only halfway between the 5% and 8% DC plan, which means
that the RSPs still have the possibility outperform the TRDs with decent
growth rates. By Age 57 with 24 years of service, the 3% discount rate
DB plan beats out the 8% Return Rate DC plan, with $523718.08 to
$520886.32.
At age 62, after 30 years of consecutive service, DB plans obviously
come out on top. The Best Case Scenario for the DC plan is at a 3%
discount rate with an NPV of $728559.35. Interestingly, the best case
scenario for the RSP plan, the 8% Return Rate DC Plan at $54,9334.73, is
only slightly ahead of the more conservative NVP of the 7% discount rate
DB Plan, whose NVP is $510658.78. The 8% Return Rate is best case
scenario, and even a more conservative Discount rate is shown to be
better after 30 years. The NPV for the 5% Return Rate DC plan is
$317996.60, and the 2% Return Rate DC plan is $191592.759, showing that
over long terms of time, the TRD plan will come close, if not outright
outpace RSP plan.
Discussion
For those who have the choice of Pension Plan, such as those in the
State University Retirement System in Illinois, knowing Net Present
Value of Defined Benefits vs. Defined Contribution Plans can help
employees make more educated investments with their retirement plans to
accrue retirement wealth more easily. Through the creation of
Figure 1, it has been determined that for long periods
of service, such as periods of service of 24 years and over, SURS’s
Traditional Plan has more value. This is due to most of the value of the
TRD plan being back loaded. For those under 25 years of service, DC
plans have more reliable values that they will accumulate at age 62,
especially for those very unsure of their SURS profession. Twenty years
of service to the same employer is quite a large ask, especially for
professors, whose skills and research could extend far beyond
universities to other testing facilities.
This, in part, could be a part of the explanation for the Annuity
Puzzle, a current problem in the the actuarial field.4
Currently, most educated, high-salaried professors that plan to stay
with the SURS System for a long time opt for the Defined Contribution
plan rather than the more reliable long-term often fo the Defined
Benefits plan.1 The Annuity Puzzle a very complicated problem
that current actuaries are trying to determine, so this project would
only serve only a small part of the explanation of this phenomenon.
For future research, other employers who offer both Defined
Contribution and Defined Benefits plans could be compared with SURS to
give a more holistic view of the comparison between the two plans, such
as Middle Tennessee State University. Additionally, the Net Present
Value of different starting ages retiring at 62 can be shown to take
into account the various ages that people can get into SURS jobs. In
addition, SURS has updated their Traditional Plan in 2011 to change the
pension value. This paper only covers the pension plans
that were created from July 7th, 1997, to Jan 1st, 2011. Another model
of more recent changes could me made in the future to show the net
presnt value of anyone who is looking to get into the field.
Reference
1: Jeffery Brown, Scott Weisbenner(2009). Who Chooses Defined
Contribution Plans? Social Security Policy in a Changing Environment, by
Jeffery Brown, Jeffery Liebman and David A. Wise.
2: Matthew Chingos, Martin West (2015). Which Teacher chooses
Defined Contribution Pension Plan? Evidence from the Florida Retirement
System. Education Finance and Policy, Vol. 10.
3: Zvi Bodie, Alan J. Marcus, Robert C. Merton (1988). Defined
Benefit versus Defined Contribution Pension Plans: What are the Real
Trade-offs? Pensions in the U.S. Economy, by Zvi Bodie, John B. Shoven,
and David A. 139.
4: Thaler, R. H. (2011, June 4). The annuity puzzle. https://www.nytimes.com/2011/06/05/business/economy/05view.html
5: Social Security Administration (2023). 2020 Actuarial Life
Table. https://www.ssa.gov/oact/STATS/table4c6.html#ss
LS0tDQp0aXRsZTogIkRlZmluZWQgQmVuZWZpdHMgdnMuIERlZmluZWQgQ29udHJpYnV0aW9ucyBQbGFuIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRoZW1lOiByZWFkYWJsZQ0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCi0tLQ0KIyMgQWJzdHJhY3QNCkZvciBwdWJsaWMgc2VjdG9yIGpvYnMgc3VjaCBhcyB1bml2ZXJzaXR5IHByb2Zlc3NvcnMsIHRoZXJlIGFyZSB0d28gdHlwZXMgb2YgYXZhaWxhYmxlIHJldGlyZW1lbnQgcGxhbnMgZm9yIHRoZWlyIHJldGlyZW1lbnQgcGFja2FnZTogVGhlIERlZmluZWQgQ29udHJpYnV0aW9uIChEQykgYW5kIHRoZSBEZWZpbmVkIEJlbmVmaXQgKERCKSBwbGFuLiBUaGlzIHByb2plY3Qgd2lsbCBmb2N1cyBvbiB0aGUga2V5IGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlc2UgcGxhbnMsIGluY2x1ZGluZyB0aGVpciBzdHJ1Y3R1cmUsIGJlbmVmaXRzLCBhbmQgcmlza3MuIE9uZSBjcml0aWNhbCBmYWN0b3IgdG8gY29tcGFyZSB0aGVzZSB0d28gcGxhbnMgaXMgdGhlIE5ldCBQcmVzZW50IFZhbHVlIChOUFYpLiBOUFYgaXMgYSB3YXkgb2YgY2FsY3VsYXRpbmcgdGhlIHZhbHVlIG9mIGZ1dHVyZSBwYXltZW50cyBvciBiZW5lZml0cyBpbiB0b2RheeKAmXMgZG9sbGFycy4gSSB3aWxsIGNvbXBhcmluZyB0aGUgTmV0IFByZXNlbnQgVmFsdWUgb2ZmZXJlZCBieSB0aGUgREMgYW5kIERCIHBsYW5zIG9mZmVyZWQgYnkgdGhlIElsbGlub2lzIFN0YXRlIFVuaXZlcnNpdHkgUmV0aXJlbWVudCBTeXN0ZW0gdG8gY29tcGFyZSB3aGljaCBpcyBiZXR0ZXIgZm9yIHRoZSBFbXBsb3llci4gVGhpcyB3aWxsIGJlIGRvbmUgYnkgY3JlYXRpbmcgYSBncmFwaCBvZiB0aGUgdHdvIHByb2dyYW1zIGluIHRoZSBSIFByb2dyYW1taW5nIGxhbmd1YWdlLg0KDQojIyBJbnRyb2R1Y3Rpb24NCg0KSW4gdGhlIGZpZWxkIG9mIGFjdHVhcmllcywgZGlzY3Vzc2lvbiBjZW50ZXJzIG9uIHdoaWNoIHJldGlyZW1lbnQgcGxhbiBpcyBiZXR0ZXIgZm9yIHRoZSBlbXBsb3llZTogVGhlIERlZmluZWQgQmVuZWZpdHMgKERCKSBvciBEZWZpbmVkIENvbnRyaWJ1dGlvbiAoREMpIHBsYW4uIEN1cnJlbnRseSwgbWFueSBlbXBsb3llZXPigJkgcmV0aXJlbWVudCBwbGFucyBhcmUgZGV0ZXJtaW5lZCBieSB0aGVpciBlbXBsb3llciwgYnV0IHRoZXJlIGhhcyBiZWVuIGRpc2N1c3Npb24gb24gdHVybmluZyBTb2NpYWwgU2VjdXJpdHkgaW50byBhIERDIHBsYW4gY2FsbGVkIGEgUGVyc29uYWwgUmV0aXJlbWVudCBBY2NvdW50Ll4xXiBGb3IgdGhvc2Ugd2hvIGdldCBhIGNob2ljZSBpbiB0aGVpciByZXRpcmVtZW50LCBzdWNoIGFzIHRob3NlIHVuZGVyIElsbGlub2lz4oCZcyBTdGF0ZSBVbml2ZXJzaXR5IFJldGlyZW1lbnQgU3lzdGVtIChTVVJTKSwgdGhvc2UgcGVvcGxlIHdvdWxkIGxpa2UgdG8ga25vdyBob3cgbXVjaCB0aGVpciBpbnZlc3RtZW50cyBhcmUgd29ydGgsIGFuZCBob3cgbXVjaCB0aGV5IGV4cGVjdCB0byBnZXQgb3V0IG9mIHJldGlyZW1lbnQuIEJyb2FkbHksIHRoZSBEZWZpbmVkIENvbnRyaWJ1dGlvbiBhbmQgRGVmaW5lZCBCZW5lZml0IHBsYW5zIGNhbiBiZSBkZXNjcmliZWQgYXMgdGh1czoNCg0KKiAgIERlZmluZWQgQ29udHJpYnV0aW9uIChEQyk6XjNeIFJldGlyZW1lbnQgaXMgaW4gRm9ybSBvZiBhbiBBY2NvdW50IHRoYXQgYm90aCB0aGUgRW1wbG95ZWUgYW5kIEVtcGxveWVyIGNvbnRyaWJ1dGUgdG8gYW5udWFsbHkuIFRoZSBhY2NvdW50IGlzIHRoZW4gaW52ZXN0ZWQgaW4gYXNzZXRzLCB3aGV0aGVyIHRoYXQgYmUgYm9uZHMgb3Igc3RvY2suIEJhc2VkIG9uIHRoZSBSZXR1cm4gb24gSW52ZXN0bWVudCwgdGhlIGVtcGxveWVlIGVhcm5zIGEgbHVtcCBzdW0gdG8gbGl2ZSBvZmYgZm9yIHRoZSByZXN0IG9mIHRoZWlyIGxpdmVzLg0KKiAgIERlZmluZWQgQmVuZWZpdHMgKERCKTpeM14gUmV0aXJlbWVudCBpbiB0aGUgZm9ybSBvZiBhbm51YWwgcGF5bWVudHMgZnJvbSB0aGUgZW1wbG95ZXIuIFRoZSBhbW91bnQgcGFpZCBpcyBiYXNlZCBvbiBhIHBlcmNlbnRhZ2Ugb2YgeW91ciBoaWdoZXN0LWVhcm5pbmcgc2FsYXJ5IHllYXJzIGRldGVybWluZWQgYnkgeW91ciBkdXJhdGlvbiBvZiBzZXJ2aWNlLg0KDQpUaGUgZ29hbCBvZiB0aGlzIHJlc2VhcmNoIGlzIHRvIG1vcmUgYWNjdXJhdGVseSBjb21wYXJlIERlZmluZWQgQmVuZWZpdHMgYW5kIERlZmluZWQgQ29udHJpYnV0aW9uIHBsYW5zIGluIGdlbmVyYWwgYnkgdXNpbmcgU1VSUydzIFJldGlyZW1lbnQgU2F2aW5ncyBQbGFuIChSU1ApIGFuZCBUcmFkaXRpb25hbCBQbGFuIChUUkQpLCB0aGUgREMgYW5kIERCIHBsYW5zIHJlc3BlY3RpdmVseSwgdG8gY29tcGFyZSB0aGUgdG90YWwgcGVuc2lvbnMgb2YgdGhlIHBsYW4gaW4gZGlmZmVyZW50IGNpcmN1bXN0YW5jZXMsIHN1Y2ggYXMgd2l0aCBkaWZmZXJlbnQgUmV0dXJuIFJhdGVzIG9yIERpc2NvdW50IFJhdGVzLiBUaGlzIGluZm9ybWF0aW9uIHdpbGwgYmUgZGlzcGxheWVkIGluIGEgZ3JhcGggYnkgUiBQcm9ncmFtbWluZyBieSBmb2xsb3dpbmcgdGhlIGZvcm1hdCBvZiBGaWd1cmUgMiBvZiAqV2hpY2ggVGVhY2hlciBjaG9vc2VzIERlZmluZWQgQ29udHJpYnV0aW9uIFBlbnNpb24gUGxhbj8gRXZpZGVuY2UgZnJvbSB0aGUgRmxvcmlkYSBSZXRpcmVtZW50IFN5c3RlbS4qXjJeIA0KDQojIyBNZXRob2RvbG9neQ0KVG8gY29tcGFyZSB0aGUgUmV0aXJlbWVudCBTYXZpbmdzIFBsYW4gKFJTUCkgYW5kIHRoZSBUcmFkaXRpb25hbCBQbGFuIChUUkQpLCB0aGUg4oCcTmV0IFByZXNlbnQgVmFsdWUgb2YgQmVuZWZpdHMgYXQgRGlmZmVyZW50IFllYXJzIG9mIFNlcnZpY2XigJ0sIGEgZ3JhcGggd2FzIGNyZWF0ZWQgaW4gUiBQcm9ncmFtbWluZyB0byBjb21wYXJlIHRoZSB0b3RhbCB2YWx1ZSBvZiB0aGUgdHdvIHBsYW5zIG92ZXIgZGlmZmVyaW5nIHllYXJzIG9mIHNlcnZpY2UuIFlvdSBjYW4gdGhpbmsgb2YgdGhlIE5ldCBQcmVzZW50IFZhbHVlIChOUFYpIGFzIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCB2YWx1ZSBvZiBhIGZ1dHVyZSBpbnZlc3RtZW50LiBUaGUgR3JhcGgncyBYLUF4aXMgcmVwcmVzZW50cyB0aGUgQWdlIG9mIFNlcGFyYXRpb24gZnJvbSBTVVJTIGVtcGxveW1lbnQsIGFzc3VtZXMgdGhhdCB0aGUgZW1wbG95ZWUncyBBZ2Ugb2YgRW5yb2xsbWVudCBpcyAzMiwgYW5kIHRoYXQgdGhlIHRoZSBlbXBsb3llZSdzIHllYXJzIG9mIGVtcGxveW1lbnQgaXMgY29uc2VjdXRpdmUuIFRoZSBZLUF4aXMgd2lsbCByZXByZXNlbnQgdGhlIE5ldCBQcmVzZW50IFZhbHVlIG9mIHRoZSBwZW5zaW9uIG9mIHRoZSBnaXZlbiBBZ2Ugb2YgU2VwYXJhdGlvbiBhdCBhZ2UgNjIuIA0KDQojIyMgVW5pdmVyc2FsIFBhcmFtZXRlcnMNClRvIG1ha2UgY29tcGFyaXNvbiBlYXNpZXIsIHRoZSBwbG90cyBmb3IgYm90aCBwbGFucyB3aWxsIHVzZSBjZXJ0YWluIHNoYXJlZCBwYXJhbWV0ZXJzIHRvIG1vcmUgYWNjdXJhdGVseSBjb21wYXJlIHRoZSB0d28gcGxhbi4gVGhlc2UgcGFyYW1ldGVycyBhcmUgdGhlIGZvbGxvd2luZzoNCg0KLSAgIGBUYDogRHVyYXRpb24gb2YgU2VydmljZQ0KLSAgIGBtMGA6IEluaXRpYWwgU2FsYXJ5DQotICAgYGFgOiBBbm51YWwgU2FsYXJ5IEluY3JlYXNlDQoNClQgcmVwcmVzZW50cyB0aGUgRHVyYXRpb24gb2YgU2VydmljZSwgd2hpY2ggd2lsbCBiZSB1c2VkIHRvIGNyZWF0ZSB0aGUgWC1BeGlzJ3MgcmVwcmVzZW50IHRoZSBEdXJhdGlvbiBvZiBTZXJ2aWNlLiAgVGhpcyBtZWFucyB0aGF0IHRoZSByYW5nZSBmb3IgdGhlIEFnZSBvZiBTZXBhcmF0aW9uIGZyb20gdGhlIFNVUlMgZW1wbG95ZXIgaXMgMzIgdG8gNjIsIHdoaWNoIGhhcyBiZWVuIGRlY2lkZWQgb24gdG8gZnVydGhlciBhZGhlcmUgdG8gRmlndXJlIDIgb2YgKldoaWNoIFRlYWNoZXIgY2hvb3NlcyBEZWZpbmVkIENvbnRyaWJ1dGlvbiBQZW5zaW9uIFBsYW4/IEV2aWRlbmNlIGZyb20gdGhlIEZsb3JpZGEgUmV0aXJlbWVudCBTeXN0ZW0uKl4yXiANCg0KYGBge3J9DQpUID0gMzANCm0wID0gMzAwMDANCmEgPSAwLjAzDQpgYGANClRoZSAkMzAsMDAwIGZvciBpbml0aWFsIHNhbGFyeSBhbmQgYSAzJSBhbm51YWwgc2FsYXJ5IHdhcyBjaG9zZW4gYmFzZWQgb2ZmIG9mIHRoZSB0eXBpY2FsIHN0YXJ0aW5nIHVuaXZlcnNpdHkgcHJvZmVzc29yLigqKklOU0VSVCBDSVRBVElPTiBIRVJFKiopDQoNCkJvdGggcGxhbnMgaGF2ZSB2YXJpYWJsZXMgdGhhdCB3aWxsIGNoYW5nZSB0aGVpciBhbm51aXRpZXMsIGFuZCB0aGVpciBvd24gdW5pcXVlIHdheXMgdG8gY29udmVydCB0aGVpciB0b3RhbCBjYXNoIGludG8gaW50byBOZXQgUHJlc2VudCBWYWx1ZXMsIHdpdGggdGhlIFJldGlyZW1lbnQgU2F2aW5ncyBQbGFuIGhhdmluZyBhIGx1bXAgc3VtIHRoYXQgYW4gZW1wbG95ZWUgaXMgb2ZmZXJlZCBhdCB0aGUgZW5kIG9mIHRoZWlyIGVtcGxveW1lbnQsIHdoaWxlIHRoZSBUcmFkaXRpb25hbCBQbGFuIG9mZmVycyBjb250aW51b3VzIGFubnVhbCBwYXltZW50cyB1cCB1bnRpbCB0aGUgZGF5IHRoZSBlbXBsb3llZSBkaWVzLiBUaHVzLCBpdCBpcyBpbXBvcnRhbnQgdGhhdCB0aGV5IGhhdmUgdGhlaXIgb3duIGRlZXAgZGl2ZXMNCg0KIyMjIERlZmluZWQgQ29udHJpYnV0aW9uIFBsYW4NCiAgRm9yIHRoZSBSZXRpcmVtZW50IFNhdmluZ3MgUGxhbiwgYW5kIG1hbnkgb3RoZXIgRGVmaW5lZCBDb250cmlidXRpb25zIFBsYW5zLCBtb25leSBpcyBwdXQgaW50byBhbiBhY2NvdW50IGF0IGNlcnRhaW4gdGltZSBpbnRlcnZhbHMsIGFuZCB0aGUgZW1wbG95ZXIgY2FuIHRoZW4gdXNlIHRoZSByZXRpcmVtZW50IGFjY291bnQncyBtb25leSB0byBpbnZlc3QgaW50byB2YXJpb3VzIHN0b2NrIHBvcnRmb2xpb3Mgc28gdGhhdCB0aGUgYWNjb3VudCBjYW4gZ3JvdyB3aXRoIHRoZSBzdG9jayBtYXJrZXQuIEF0IHJldGlyZW1lbnQsIHRoZSBlbXBsb3llZSBnZXRzIGEgbHVtcCBzdW0gb2YgbW9uZXkgZnJvbSBzYWlkIGludmVzdG1lbnRzIHRvIHNwZW5kIGR1cmluZyByZXRpcmVtZW50LCB3aXRoIHRoZSBvcHRpb24gb2YgcHVyY2hhc2luZyBhIHJldGlyZW1lbnQtbGlrZSBzeXN0ZW0uIFRvIG1vZGVsIFNVUlMncyBSZXRpcmVtZW50IFNhdmluZ3MgcGxhbiwgSSBoYXZlIGNyZWF0ZWQgYSBmdW5jdGlvbiBjYWxsZWQgYEJhbGFuY2VEQ2Agd2l0aCB0aGUgaW5wdXQgdmFyaWFibGVzIG9mIGBUYCBhbmQgYGF2ZS5yYC4gDQogIA0KIyMjIyBEQyBQYXJhbWV0ZXJzDQogIFRoZSBmb2xsb3dpbmcgZmFjdG9ycyBhcmUgcmVsZXZhbnQgdG8gdGhlIERlZmluZWQgQ29udHJpYnV0aW9uIHBsYW46DQogIA0KLSAgIGBjb250cmlidXRpb25gOiBBbm51YWwgY29udHJpYnV0aW9uIHJhdGUgKGluY2x1ZGluZyB0aGUgbWF0Y2hpbmcgcmF0ZSBmcm9tIHRoZSBlbXBsb3llcikNCi0gICBgYXZlLnJgOiBBbm51YWwgUmF0ZSBvZiBSZXR1cm4gDQoNCiAgVGhlIENvbnRyaWJ1dGlvbiBSYXRlIGZvciB0aGUgUlNQIHByb2dyYW0gaXMgc2V0IHRvIDE1LjYlLCB3aXRoIHdpdGggOCUgYmVpbmcgY29udHJpYnV0ZWQgYnkgdGhlIGVtcGxveWVlJ3MgcGF5Y2hlY2tzIGFuZCA3LjYlIGJlaW5nIGNvbnRyaWJ1dGVkIGJ5IHRoZSBlbXBsb3llciwgd2hpY2ggaXMgd2h5IGl0IGlzbid0IGFuIGlucHV0IHBhcmFtZXRlciBmb3IgYEJhbGFuY2VEQ2AuDQogIFRoZSBSYXRlIG9mIFJldHVybiBpcyBhdmVyYWdlIHJldHVybiBvbiBpbnZlc3RtZW50cyBpbiB0aGUgUmV0aXJlbWVudCBQb3J0Zm9saW8gb3ZlciBhbGwgeWVhcnMgb2YgaW52ZXN0bWVudC4gVGhlIHJhdGUgb2YgcmV0dXJuIGZvciBhIHR5cGljYWwgaW52ZXN0b3IgaXMgZXhwZWN0ZWQgdG8gYmUgNSUsIGJ1dCB0byBhZGhlcmUgdG8gdGhlIHZhcmlhYmlsaXR5IG9mIHRoZSBTdXBlcm1hcmtldCwgUmV0dXJuIFJhdGVzIG9mIGBhdmUuciA9MC4wMmAgLCBgYXZlLnIgPSAwLjA1YCwgYW5kIGBhdmUuciA9IDAuMDhgIHdpbGwgYmUgZ3JhcGhlZCB0byBkaXNwbGF5IHRoYXQgdmFyaWFiaWxpdHkuDQogIA0KICBGb3IgdGhlIFJTUCdzIGluaXRpYWwgcGFyYW1ldGVycywgdGhlaXIgdmFsdWVzIGFyZSBhcyBzaG93bjogDQpgYGB7cn0NCmNvbnRyaWJ1dGlvbiA9IDE1LjYvMTAwDQphdmUuciA9IDAuMDUNCmBgYA0KICANCiMjIyMgREMgQ29kZQ0KVG8gZGV0ZXJtaW5lIHRoZSBOZXQgUHJlc2VudCBWYWx1ZSBvZiB0aGUgUlNQIGF0IGFnZSA2MiBmb3IgZWFjaCBBZ2Ugb2YgU2VwYXJhdGlvbiBncmFwaGVkLCB0aGVyZSBhcmUgdHdvIHRpbWUgcGVyaW9kcyB0byBjb25zaWRlcjogVGhlIER1cmF0aW9uIG9mIFNlcnZpY2UgdGhhdCB0aGUgZW1wbG95ZWUgd29ya2VkIGZvciBTVVJTLCBhbmQgdGhlIER1cmF0aW9uIGFmdGVyIHNlcnZpY2UgdXAgdG8gYWdlIDYyLg0KDQojIyMjIyBEdXJhdGlvbiBvZiBTZXJ2aWNlDQogIFRoZSBhY2NvdW50IGJhbGFuY2UgYXQgdGhlIHN0YXJ0IG9mIHRoZSBEdXJhdGlvbiBvZiBTZXJ2aWNlIGlzIDAuIEZvciBlYWNoIG1vbnRoIGR1cmluZyB0aGUgZHVyYXRpb24gb2Ygc2VydmljZSwgdGhlIG5ldyBhY2NvdW50IGdyb3dzIG5hdHVyYWxseSB3aXRoIHRoZSBzdG9jayBwZXJmb3JtYW5jZSwgYE1gLCBidXQgYWxzbyBmcm9tIHRoZSBgTW9udGhseURlcG9zaXRgLiBUaGVzZSB0d28gcGFyYW1ldGVycyBhcmUgdml0YWwgdG8gdW5kZXJzdGFuZGluZyBob3cgdGhlIFJTUCBhY2NvdW50IGdyb3dzLiANCiAgDQojIyMjIyMgTW9udGhseSBSZXR1cm4gUmF0ZQ0KICBUaGUgcGFyYW1ldGVyIG9mIGBNYCByZXByZXNlbnRzIHRoZSBtb250aGx5IFJldHVybiBSYXRlIG9mIHRoZSByZXRpcmVtZW50IGFjY291bnQsIHdoaWNoIGlzDQogIEkgc2V0IHRoZSBwYXJhbWV0ZXIgYE1gIGFzIG15IG1vbnRobHkgUmV0dXJuIFJhdGUgZm9yIHRoZSByZXRpcmVtZW50IGFjY291bnQuIFRoZSB2YWx1ZSBvZiBgTWAgaXMgcmVwcmVzZW50ZWQgYnkgdGhlIGZvbGxvd2luZyBlcXVhdGlvbjogIA0KDQokJA0KIE0gPSAobG4oXGZyYWN7MSthdmUucn17MTJ9KSleZQ0KJCQNCiAgQ2FsY3VsYXRpbmcgdGhlIGdyb3d0aCBvZiB0aGUgcG9ydGZvbGlvIG1vbnRobHkgaW5zdGVhZCBvZiBhbm51YWxseSB3YXMgdG8gbW9yZSBhY2N1cmF0ZWx5IGRpc3BsYXkgdGhlIG5hdHVyYWwgZ3Jvd3RoIG9mIHRoZSBhY2NvdW50J3Mgc3RvY2sgcG9ydGZvbGlvLg0KICANCiMjIyMjIyBNb250aGx5IERlcG9zaXQNCiAgVGhlIGBjb250aWJ1dGlvbmAgcGFyYW1ldGVyIG9ubHkgbWVhc3VyZXMgdGhlIHBlcmNlbnRhZ2Ugb2Ygc2FsYXJ5IHByb3ZpZGVkIGFubnVhbGx5LCBzbyBmcm9tIHRoZSB0aGUgeWVhcidzIGFubnVhbCBzYWxhcnkgb2YgYG1UYCwgdGhlIHNhbGFyeSBpcyBkaXZpZGVkIGJ5IDEyIHRvIGdldCB0aGUgdG90YWwgZGVwb3NpdCB0aGF0IGlzIHB1dCBpbnRvIHRoZSBBY2NvdW50IEJhbGFuY2UgZXZlcnkgbW9udGguIEFkZGluZyBkZXBvc2l0cyBieSBtb250aCBhbGxvd3Mgc2FpZCBkZXBvc2l0cyB0byBpbmNyZWFzZSB3aXRoIGBNYCwgd2hpY2ggYmV0dGVyIHJlcHJlc2VudHMgdGhlIGdyb3d0aCBvZiB0aGUgc3RvY2tzIHByb3ZpZGVkIG15IHRoZSBkZXBvc2l0cy4gDQogIA0KIyMjIyMgRHVyYXRpb24gQmVmb3JlIFJldGlyZW1lbnQNCiAgQWZ0ZXIgdGhlIEFnZSBvZiBTZXBhcmF0aW9uLCBuZWl0aGVyIHRoZSBFbXBsb3llZSBub3IgRW1wbG95ZXIgbWFrZSBjb250cmlidXRpb25zIHRvIHRoZSByZXRpcmVtZW50IGFjY291bnQgYW55bW9yZSwgc28gdGhlIGFjY291bnQgb25seSBncm93cyBiYXNlZCBvbiB0aGUgUmV0dXJuIFJhdGUuIFRoaXMgaXMgY2FsY3VsYXRlZCBieSB0YWtpbmcgdGhlIGN1cnJlbnQgYWNjb3VudCBiYWxhbmNlIGFuZCBtdWx0aXBseWluZyBpdCBieSB0aGUgUmV0dXJuIFJhdGUgcmFpc2VkIHRvIHRoZSBwb3dlciB0aGUgcmVtYWluaW5nIHllYXJzIGxlZnQgdW50aWwgdGhlIGFnZSBvZiA2Mi4gVGhpcyBtZWFucyB0aGF0IHRoZSByYXRlIG9mIHJldHVybiBpcyBhcHBsaWVkIGFubnVhbGx5IGluc3RlYWQgb2YgbW9udGhseSwgc2luY2Ugbm8gcGF5bWVudHMgYXJlIGJlaW5nIG1hZGUgdG8gdGhlICBhY2NvdW50IGFueW1vcmUuDQoNCg0KYGBge3J9DQpCYWxhbmNlREMgPSBmdW5jdGlvbihULCBhdmUucil7DQogIHhWYWx1ZXMgPSBjKDE6VCkgKyAzMg0KICB5VmFsdWVzID0gcmVwICgwLFQpDQogIGZvciAodCBpbiAxOlQpew0KICAgIG1UID0gbTANCiAgICBBY2NvdW50QmFsYW5jZSA9IDANCiAgICBhbm51YWxEZXBvc2l0ID0gbVQgKiBjb250cmlidXRpb24NCiAgICBtb250aGx5RGVwb3NpdCA9IGFubnVhbERlcG9zaXQgLyAxMg0KICAgIGZvciAoaiBpbiAxOnQpew0KICAgICAgTSA9IGV4cChsb2coMSthdmUucikvMTIpDQogICAgICBmb3IgKG0gaW4gMToxMil7DQogICAgICAgIEFjY291bnRCYWxhbmNlID0gQWNjb3VudEJhbGFuY2UgKiBNICsgbW9udGhseURlcG9zaXQNCiAgICAgIH0NCiAgICBtVCA9IG1UICogKDErYSkNCiAgICB9DQogICAgQWNjb3VudEJhbGFuY2UgPSBBY2NvdW50QmFsYW5jZSAqICgxK2F2ZS5yKV4gKFQtdCkNCiAgICB5VmFsdWVzW3RdID0gQWNjb3VudEJhbGFuY2UNCiAgfQ0KICByZXR1cm4oZGF0YS5mcmFtZSh4PXhWYWx1ZXMsIHk9eVZhbHVlcykpDQp9DQpgYGANCg0KIyMjIyBEQyBQbG90DQoNCmBgYHtyfQ0KZGF0YTIgPSBCYWxhbmNlREMoVCwgMC4wMikNCmRhdGE1ID0gQmFsYW5jZURDKFQsIDAuMDUpDQpkYXRhOCA9IEJhbGFuY2VEQyhULCAwLjA4KQ0KeERDLm1pbiA9IG1pbihkYXRhMiR4KQ0KeERDLm1heCA9IG1heChkYXRhMiR4KQ0KeCA9IGRhdGE4JHgNCnkgPSBkYXRhOCR5DQp5REMubWluID0gMA0KeURDLm1heCA9IG1heChjKGRhdGEyJHksIGRhdGE1JHksIGRhdGE4JHkpKQ0KcGxvdChjKHhEQy5taW4sIHhEQy5tYXgpLCBjKHlEQy5taW4sIHlEQy5tYXgpLCB0eXBlPSJuIiwgeWF4dD0ibiIsDQogICAgIHhsYWIgPSAiWWVhcnMgb2YgU2VydmljZSAoU3RhcnQgYXQgQWdlIDMyIiwNCiAgICAgeWxhYiA9ICJQZW5zaW9uIFdlYWx0aCAoTlBWIEFnZSA2MikiLA0KICAgICBtYWluID0gIk5ldCBQcmVzZW50IFZhbHVlIG9mIERDIEJlbmVmaXRzIGF0IGFnZSA2MiIpDQoNCnl0aWNrID0gKDE6NikgKiAxMDAwMDANCmF4aXMoMiwgYXQgPSB5dGljaywgbGFzID0gMiwgY2V4LmF4aXMgPSAwLjYsDQogIGxhYmVscyA9IGZvcm1hdEMoeXRpY2ssIGJpZy5tYXJrID0gIiwiLCBmb3JtYXQ9ImYiLCBkaWdpdHMgPSAwKSkNCg0KbGluZXMoZGF0YTIkeCwgZGF0YTIkeSwgbHR5PTEpDQpwb2ludHMoZGF0YTIkeCwgZGF0YTIkeSwgcGNoID0xNikNCmxpbmVzKGRhdGE1JHgsIGRhdGE1JHksIGx0eT0xKQ0KcG9pbnRzKGRhdGE1JHgsIGRhdGE1JHksIHBjaCA9MTUpDQpsaW5lcyhkYXRhOCR4LCBkYXRhOCR5LCBsdHk9MSkNCnBvaW50cyhkYXRhOCR4LCBkYXRhOCR5LCBwY2ggPTE3KQ0KYGBgDQpUaGUgaW5pdGlhbCBncm93dGggZm9yIHRoZSBEZWZpbmVkIENvbnRyaWJ1dGlvbiBwbGFucyBhcmUgc3RhZ2dlcmluZy4gRnJvbSB5ZWFycyBvbmUgdG8gZml2ZSwgdGhlIDUlIFJldHVybiBSYXRlIGZvciB0aGUgUmV0aXJlbWVudCBTYXZpbmdzIFBsYW4ganVtcHMgZnJvbSAkMTk3MDEuMDggYWxsIHRoZSB3YXkgdG8gDQokMzE3OTk2LjYwLiBUaGlzIHJhcGlkIGdyb3d0aCBjb250aW51ZXMgZm9yIGFyb3VuZCAxNSB5ZWFycywgd2hlcmUgdGhlIGFjY291bnQncyB2YWx1ZSBzdG9wcyBpbmNyZWFzaW5nIGFzIG11Y2guIA0KVGhlIHJhbmdlIG9mIGV4cGVjdGVkIE5ldCBQcmVzZW50IFZhbHVlcyBhdCBhZ2UgNjIgZm9yIFNVUlMncyBEQyBwbGFuIHJhbmdlcyBmcm9tICQxOTEsNTkyLjc2IGZvciAyJSBSZXR1cm4gUmF0ZSBhbmQNCiQ1NDksMzM0LjczIGZvciB0aGUgOCUgUmV0dXJuIFJhdGUuDQoNCg0KDQojIyMgRGVmaW5lZCBCZW5lZml0cyBQbGFuDQogIFRoZSBTVVJTIERlZmluZWQgQ29udHJpYnV0aW9uIFBsYW4gaXMga25vd24gYXMgdGhlIFRyYWRpdGlvbnMgUGxhbi4gVGhpcyB0eXBlIG9mIHBsYW4gaXMgYWxzbyByZWZlcnJlZCB0byBhcyBQZW5zaW9uLiBJbiB0aGlzIGZvcm0gb2YgcmV0aXJlbWVudCwgYW5udWFsIHBheW1lbnRzIGZyb20gb25lJ3MgZW1wbG95ZXJzIGlzIGdpdmVuIHRvIHRoZSBlbXBsb3llZSBldmVyeSB5ZWFyIHVudGlsIHRoZXkgZGllLiBUaGUgYW1vdW50IHBhaWQgcGVyIHllYXIgaXMgYmFzZWQgb24gYSBwZXJjZW50YWdlIG9mIHRoZSBlbXBsb3llZSdzIGhpZ2hlc3QtZWFybmluZyBzYWxhcnkgZHVyaW5nIHRoZWlyIGR1cmF0aW9uIG9mIHNlcnZpY2UuIEluIHRlcm1zIG9mIHRoZSBUUkQgIFBsYW4sIFNVUlMgcHJvdmlkZXMgMi4yJSBvZiB5b3VyIGF2ZXJhZ2VkIGZpbmFsIHNhbGFyeS5eMl4gVG8gbW9kZWwgdGhlIFRSRCBwbGFuLCBJIGhhdmUgbWFkZSBmdW5jdGlvbiBgQmFsYW5jZURCYCB3aXRoIHRoZSBpbnB1dCBwYXJhbWV0ZXJzIGBUYCBhbmQgYGRpc2NvdW50LnJgLg0KICANCiMjIyMgREIgUGFyYW1ldGVycw0KICBUaGUgZm9sbG93aW5nIEZhY3RvcnMgYXJlIHJlbGV2YW50IHRvIHRoZSBEZWZpbmVkIENvbnRyaWJ1dGlvbiBwbGFuOg0KICANCi0gICBgcGVuc2lvbmA6IGFubnVhbCBwZW5zaW9uIGluY29tZQ0KLSAgIGBkaXNjb3VudC5yYDogRGlzY291bnQgUmF0ZSANCg0KVGhlIGZvcm11bGEgZm9yIGBwZW5zaW9uYCBmb3IgdGhlIFBlbnNpb24gcGxhbiwgYXMgd2VsbCBhcyB0aGUgY2FsY3VsYXRpb25zIGZvciB0aGUgTlBWIG9mIHRoZSBUUkQgcGxhbiBhcmUgY29tcGxpY2F0ZWQsIHNvIGl0IHdpbGwgYmUgZGlzY3Vzc2VkIGluIHRoZSBjb2RlIHNlY3Rpb24uIA0KDQogIFRoZSBEaXNjb3VudCBSYXRlIGlzIHRoZSByYXRlIG9mIGludGVyZXN0IHRoYXQgaXMgYXBwbGllZCB0byBmdXR1cmUgY2FzaCBmbG93cyBvZiBhbiBpbnZlc3RtZW50IHRvIGNhbGN1bGF0ZSBpdHMgcHJlc2VudCB2YWx1ZS4gRXNzZW50aWFsbHksIGl0IGdpdmVzIGFuIGV4YWN0IHZhbHVlIG9mIHdoYXQgYSBkb2xsYXIgeW91J2xsIGluIHRoZSBmdXR1cmUgaXMgd29ydGggdG8gc29tZW9uZSBjdXJyZW50bHkuIA0KICANCiAgVGhlIERpc2NvdW50IFJhdGUgaXMgYSB2YXJpYWJsZSBiZXR3ZWVuIGRpZmZlcmVudCBlbnRpdGllcywgYW5kIHNvIHRoZSB0d28gcGxvdHMgZm9yIERDIHJhdGUgd2lsbCBiZSBgZGlzY291bnQuciA9IDAuMDBgIGFuZCBgZGlzY291bnQuciA9IDAuMDRgLiBUaGUgZGlzY291bnQgcmF0ZSBwYXJhbWV0ZXIgYWN0dWFsbHkgcmVwcmVzZW50cyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBkaXNjb3VudCByYXRlIGFuZCB0aGUgYW5udWFsIHNhbGFyeSBpbmNyZWFzZSByYXRlLCBtZWFuaW5nIHdlIGFyZSBhY3R1YWxseSBjYWxjdWxhdGluZyB3aXRoIERpc2NvdW50IHJhdGVzIG9mIDMlIGFuZCA3JSByZXNwZWN0aXZlbHkuIFRoZSBkaXNjb3VudCByYXRlIHJlcHJlc2VudHMgdGhlIHJhdGUgb2YgcmV0dXJuIHVzZWQgdG8gZGlzY291bnQgZnV0dXJlIHByb2ZpdHMgdG8gY2FsY3VsYXRlIHRoZSBjdXJyZW50IHZhbHVlIG9mIGFuIGludmVzdG1lbnQuIFRoaXMgcmF0ZSBpcyBvZmZzZXQgYnkgdGhlIHNhbGFyeSBpbmNyZWFzZSByYXRlICwgc2luY2UgKCpJTlNFUlQgUkVTQVNPTiBIRVJFKikuIENvbXBhbmllcyBzdWdnZXN0IHVzaW5nIGEgMyUgZGlzY291bnQgcmF0ZSBmb3IgdGhlaXIgYW5udWl0eSwgYnV0IG1hbnkgZW1wbG95ZWVzIHZhbHVlIHRoZWlyIHBlbnNpb24gbGVzcyB0aGFuIHRoZSBzdWdnZXN0ZWQgcmF0ZSwgc28gYSBkaXNjb3VudCByYXRlIG9mIDclIHdpbGwgYmV0dGVyIHNob3cgdGhlIGRpc2NvdW50IHJhdGUgb2YgdGhlIGF2ZXJhZ2UgU1VSUyBlbXBsb3llZS4NCiAgDQpUaGUgaW5pdGlhbCBwYXJhbWV0ZXJzIGFyZSBhcyBzaG93bi4NCmBgYHtyfQ0KcGVuc2lvbi5wZXJjZW50ID0gMi4yLzEwMA0KZGlzY291bnQuciA9IDAuMDANCmBgYCAgDQoNCiMjIyMgREIgQ29kZQ0KRm9yIHRoZSBUUkQgcGxhbiwgdGhlIHZhbHVlIG9mIHRoZSBgcGVuc2lvbmAgcGFyYW1ldGVyIGlzIGRldGVybWluZWQgYXMgdGhlIHByb2R1Y3Qgb2YgdHdvIHZhbHVlczoNCg0KLSAgIGBhdmUubWA6IEF2ZXJhZ2Ugc2FsYXJ5IG92ZXIgdGhlIGZpbmFsIDUgeWVhcnMgb2Ygc2VydmljZS4gU2luY2UgdGhlIG1vZGVsIGFzc3VtZXMgdGhhdCAgdGhlIHNhbGFyeSBpbmNyZWFzZXMgYnkgMyUgYW5udWFsbHksIHdlIGNhbiBlc3NlbnRpYWxseSBkZXJpdmUgdGhlIGZpbmFsIHNhbGFyeSBiYXNlZCBvbiB0aGUgYWdlIG9mIHNlcGFyYXRpb24gZnJvbSB0aGUgU1VSUyBzeXN0ZW0sIHdoaWNoIGlzIHdoeSBUIGlzIHNldCBhcyB0aGUgZ3JhcGgncyBpbnB1dC4gDQotICAgYHBlbnNpb24ucGVyY2VudGA6IHRoZSBwZXJjZW50YWdlIG9mIGBhdmUubWAgdGhhdCBhbiBlbXBsb3llZSByZWNlaXZlcyBhbm51YWxseSBhcyBwZW5zaW9uIGZvciB0aGVpciByZXRpcmVtZW50LiBFeGFtcGxlOiBXaXRoIGEgcGVuc2lvbiByYXRlIG9mIDIuMiUsIGFmdGVyIDE2IHllYXJzIG9mIHNlcnZpY2UsIGFuIGVtcGxveWVlIGdhaW5zIDM1LjIlIG9mIHRoZWlyIGBhdmUubWAgYXMgdGhlaXIgcmV0aXJlbWVudCBwZW5zaW9uLiANCg0KQWZ0ZXIgY29tcHV0aW5nIGBwZW5zaW9uYCwgdGhlIE5ldCBQcmVzZW50IFZhbHVlIG11c3QgYmUgY2FsY3VsYXRlZC4gVGhpcyBpcyBkaWZmaWN1bHQsIHNpbmNlIHBlbnNpb24gaXMgcGFpZCBmb3Igc2V2ZXJhbCB5ZWFycyB1bnRpbCB5b3UgZGllLiANClRvIGRvIHRoYXQsIEkgY29tcHV0ZWQgdGhlICgqKmV4cGVjdGVkKiopIE5QViBvZiB0aGUgc3RyZWFtIG9mIHBlbnNpb24gaW5jb21lIGZyb20gYWdlIDYzIHRvIGFnZSAxMTkgdXNpbmcgdGhlIFtBY3R1YXJpYWwgTGlmZSBUYWJsZV0oaHR0cHM6Ly93d3cuc3NhLmdvdi9vYWN0L1NUQVRTL3RhYmxlNGM2Lmh0bWwjZm4xKSBmcm9tIFNvY2lhbCBTZWN1cml0eSBBZG1pbmlzcmF0aW9uIHdlYnNpdGU7IG15IG1lbnRvcnMgdXNlZCB0aGUgY29tcGxlbWVudCBvZiBkZWF0aCByYXRlIHRvIGNvbXB1dGUgdGhlIHN1cnZpdmFsIHByb2JhYmlsaXR5LCBhdmVyYWdlZCBvdmVyIG1hbGUgYW5kIGZlbWFsZS4gVGhlIE5QViBmb3JtdWxhIGlzIGdpdmVuIGJlbG93ICQkDQogICAgXHN1bV97XHRleHR7YWdlfSA9IDYzfV57MTE5fSAuLi4gID0gXHN1bV97dCA9IDYzLTYyfV57KDExOSAtIDYyKX0gXHRleHR7YW5udWFsLXBlbnNpb24taW5jb21lfSBcdGltZXMgcF90IFx0aW1lcyB2Xnt0IC0gMC41fQ0KICAgICQkIHdoZXJlICR2JCAkJCAgDQogICAgdiA9IFxmcmFjezF9ezEgKyBcdGV4dHtkaXNjb3VudC5yYXRlfX0NCiAgICAkJCBpcyB0aGUgZGlzY291bnQgZmFjdG9yIGFuZCAkJA0KICAgIFxiZWdpbnthbGlnbmVkfQ0KICAgIHBfdCAgPSAmIFxtYXRoYmJ7UH0oXHRleHR7c3RpbGwgYWxpdmUgYXQgYWdlfSAoNjIrdCkgXG1pZCBcdGV4dHthbGl2ZSBhdCBhZ2UgfSA2MikgXFwNCiAgICAgPSAmIFxxdWFkIFxtYXRoYmJ7UH0oXHRleHR7c3VydmUgZm9yIGEgeWVhcn0gXG1pZCAgXHRleHR7YWxpdmUgYXQgYWdlIH0gNjIpIFxcDQogICAgICYgXHRpbWVzICBcbWF0aGJie1B9KFx0ZXh0e3N1cnZlIGZvciBhIHllYXJ9IFxtaWQgXHRleHR7YWxpdmUgYXQgYWdlIH0gNjMpIFx0aW1lcyBcXA0KICAgICYgXHRpbWVzIFxjZG90cyBcdGltZXMgXG1hdGhiYntQfShcdGV4dHtzdXJ2ZSBmb3IgYSB5ZWFyfSBcbWlkIFx0ZXh0e2FsaXZlIGF0IGFnZSB9IDYyK3QtMSkgXFwNCiAgICA9ICYgXHByb2Rfe2o9MX1edCBcQmlnIFsgMSAtICBcbWF0aGJie1B9IFxiaWcgKFx0ZXh0e2RpZSB3aXRoaW4gYSB5ZWFyIH0gXG1pZCBcdGV4dHthbGl2ZSBhdCBhZ2UgfSAoNjIgKyBqLTEpIFxiaWcgKSBcQmlnIF0uDQogICAgXGVuZHthbGlnbmVkfQ0KICAgICQkDQogVGhlIHByb2JhYmlsaXRpZXMgZm9yIHRoZSBsYXN0IHJvdyBjYW4gYmUgZm91bmQgaW4gdGhlIFtBY3R1YXJpYWwgTGlmZSBUYWJsZSdzXShodHRwczovL3d3dy5zc2EuZ292L29hY3QvU1RBVFMvdGFibGU0YzYuaHRtbCNmbjEpIC4NCiANCmBgYHtyfQ0Kc2V0d2QoIkM6L1VzZXJzLzE2MzAyL09uZURyaXZlIC0gaW1zYS5lZHUvRG9jdW1lbnRzL1IgU2NyaXB0cy8iKQ0KZGF0YSA9IHJlYWQudGFibGUoIm10YWJsZS50eHQiLCBzZXA9Ilx0IikNCm5hbWVzKGRhdGEpDQpuYW1lcyhkYXRhKSA9IGMoIkFnZSIsICJtLnByb2IiLCAibS5saXZlcyIsICJtLmV4cCIsICJmLnByb2IiLCAiZi5saXZlcyIsICJmLmV4cCIpDQpoZWFkKGRhdGEpDQpuZXdkYXRhID0gZGF0YS5mcmFtZShBZ2UgPSBkYXRhJEFnZSwgIHByb2IgPSBkYXRhJG0ucHJvYiArIGRhdGEkZi5wcm9iKQ0KcHJvYnMgPSBuZXdkYXRhJHByb2JbbmV3ZGF0YSRBZ2UgPj0gNjJdDQpybSgiZGF0YSIsICJuZXdkYXRhIikNCmBgYA0KDQpUaGVuLCB1c2luZyB0aGUgbWV0aG9kcyBsaXN0ZWQgYWJvdmUsIEkgY29tcHV0ZWQgdGhlIE5QViBmb3IgdGhlIFRSRCBQbGFuLg0KDQpgYGB7cn0NCkJhbGFuY2VEQiA9IGZ1bmN0aW9uKFQsIGRpc2NvdW50LnIpew0KICB4VmFsdWVzID0gYygxOlQpICsgMzINCiAgeVZhbHVlcyA9IHJlcCgwLCBUKQ0KICBpZiAoVCA8IDYpew0KICAgIHJldHVybihkYXRhLmZyYW1lKHg9eFZhbHVlcywgeT15VmFsdWVzKSkNCiAgICBleGl0DQogIH0NCiAgcGVuc2lvbiA9IHJlcCAoMCxUKQ0KICBmb3IodCBpbiA2OlQpew0KICAgIHRtcCA9IHRhaWwoMTp0LCAyKQ0KICAgIGF2ZS5tID0gbWVhbihtMCooMSthKV4odG1wLTAuNSkpDQogICAgcGVuc2lvblt0XSA9IGF2ZS5tICogcGVuc2lvbi5wZXJjZW50ICogdA0KICAgIGlmIChwZW5zaW9uLnBlcmNlbnQgKiB0ID4gMC44KXsNCiAgICAgIHBlbnNpb25bdF0gPSBhdmUubSAqIDAuOA0KICAgIH0NCiAgfQ0KcHQgPSAxDQp2ID0gMSAvICgxK2Rpc2NvdW50LnIpDQp2dCA9IHYgXigtMC41KQ0KZm9yKHQgaW4gMTpsZW5ndGgocHJvYnMpKXsNCiAgcHQgPSBwdCAqICgxLXByb2JzW3RdKQ0KICB2dCA9IHZ0ICogdg0KICB5VmFsdWVzID0geVZhbHVlcyArIHBlbnNpb24gKiBwdCAqIHZ0DQogIH0NCiAgcmV0dXJuKGRhdGEuZnJhbWUoeCA9IHhWYWx1ZXMsIHkgPSB5VmFsdWVzKSkNCn0NCmBgYA0KDQoNCg0KIyMjIyBEQyBQbG90DQoNCmBgYHtyfQ0KZGF0YURCMCA9IEJhbGFuY2VEQihULCAwKQ0KZGF0YURCNCA9IEJhbGFuY2VEQihULCAwLjA0KQ0KeCA9IGRhdGFEQjAkeA0KeSA9IGRhdGFEQjAkeQ0KcGxvdCh4LCB5LCB0eXBlPSJuIiwgeWF4dD0ibiIsDQogICAgIHhsYWIgPSAiWWVhcnMgb2YgU2VydmljZSIsDQogICAgIHlsYWIgPSAiUGVuc2lvbiBXZWFsdGggKE5QViBhdCBhZ2UgNjIpIiwNCiAgICAgbWFpbiA9ICJOZXQgUHJlc2VudCBWYWx1ZSBvZiBEQyBCZW5lZml0cyBhdCBhZ2UgNjIiKQ0KeXRpY2sgPSAoMTo4KSAqIDEwMDAwMA0KYXhpcygyLCBhdCA9IHl0aWNrLCBsYXMgPSAyLCBjZXguYXhpcyA9IDAuNiwNCmxhYmVscyA9IGZvcm1hdEMoeXRpY2ssIGJpZy5tYXJrID0gIiwiLCBmb3JtYXQ9ImYiLCBkaWdpdHMgPSAwKSkNCmxpbmVzKGRhdGFEQjAkeCwgZGF0YURCMCR5LCBsdHkgPSA1KQ0KbGluZXMoZGF0YURCNCR4LCBkYXRhREI0JHksIGx0eSA9IDMpDQpgYGAgDQpUaGUgZmlyc3QgZml2ZSB5ZWFycyBvZiB0aGUgVHJhZGl0aW9uYWwgUGxhbiBpcyBkZWRpY2F0ZWQgdG8gaXRzIHZlc3RpbmcgcGVyaW9kLCBtZWFuaW5nIHRoYXQgdGhlIGZ1bmRzIGZvciB0aGUgcGVuc2lvbiBpcyBzdGlsbCBiZWluZyBzZXQgdXAgYnkgdGhlIGNvbXBhbnkgYW5kIGlzIG5vdCBvZmZpY2lhbCB5ZXQuIE9ubHkgYXQgMzgsIDYgeWVhcnMgYWZ0ZXIgdGhlIGFnZSBvZiBzZXBhcmF0aW9uLCBjYW4gdGhlIE5ldCBQcmVzZW50IFZhbHVlIGJlIGFjY291bnRlZCBmb3IuIEFmdGVyIHRoYXQsIHRoZXJlIGlzIGEgc3RlYWR5IGV4cG9uZW50aWFsIGdyb3d0aCBmb3IgdGhlIE5ldCBQcmVzZW50IFZhbHVlIG9mIEJlbmVmaXRzLCBhcyB3aXRoIHRoZSBjYXNlIG9mIG1vc3QgZGVmaW5lZCBjb250cmlidXRpb24gcGxhbnMuIFRoZSByYW5nZSBvZiBleHBlY3RlZCBOZXQgUHJlc2VudCBWYWx1ZXMgZm9yIFNVUlMncyBEQiBwbGFuIGFmdGVyIDMwIHllYXJzIGdvZXMgZnJvbSAkNTEwNjU4Ljc4IHRvIA0KJDcyODU1OS4zNS4NCg0KDQogDQoNCiMjIFJlc3VsdHMNCiAgV2l0aCB0aGUgZnVuY3Rpb25zIGBCYWxhbmNlRENgIGFuZCBgQmFsYW5jZURCYCBzZXQsIGl0IGlzIG5vdyBwb3NzaWJsZSB0byBjcmVhdGUgYSBncmFwaCBvZiB0aGVpciBOZXQgUHJlc2VudCBWYWx1ZXMgYmFzZWQgb24gZGlmZmVyZW50IHBlcmlvZHMgb2Ygc2VydmljZXMgdGhhdCBlbmNvbXBhc3NlcyBib3RoIGdyYXBocyB3aXRoIHRoZWlyIGlucHV0IHBhcmFtZXRlcnMuICANCg0KYGBge3J9DQpkYXRhREMyID0gQmFsYW5jZURDKFQsIDAuMDIpDQpkYXRhREM1ID0gQmFsYW5jZURDKFQsIDAuMDUpDQpkYXRhREM4ID0gQmFsYW5jZURDKFQsIDAuMDgpDQpkYXRhREIwID0gQmFsYW5jZURCKFQsIDApDQpkYXRhREI0ID0gQmFsYW5jZURCKFQsIDAuMDQpDQp4Lm1pbiA9IG1pbihkYXRhREMyJHgpDQp4Lm1heCA9IG1heChkYXRhREMyJHgpDQp5Lm1pbiA9IDANCnkubWF4ID0gbWF4KGMoZGF0YURDMiR5LCBkYXRhREM1JHksIGRhdGFEQzgkeSwgZGF0YURCMCR5LCBkYXRhREI0JHkpKQ0KcGxvdChjKHgubWluLCB4Lm1heCksIGMoeS5taW4sIHkubWF4KSwgdHlwZSA9Im4iLCB4YXh0PSJuIiwgeWF4dCA9ICJuIiwNCiAgICAgeGxhYiA9ICJBZ2Ugb2YgU2VwZXJhdGlvbiAoU3RhcnQgYXQgQWdlIDMyKSIsDQogICAgIHlsYWIgPSAiUGVuc2lvbiBXZWFsdGggKE5QViBhdCBhZ2UgNjIpIiwNCiAgICAgbWFpbiA9ICJOZXQgUHJlc2VudCBWYWx1ZSBvZiBSZWl0cmVtZW50IFBsYW5zIGF0IERpZmZlcm50IFllYXJzIG9mIFNlcnZpY2UiKQ0KDQp4dGljayA9ICgxOjMwKSszMg0KYXhpcygxLCBhdD0geHRpY2ssIGxhcyA9IDEsIGNleC5heGlzID0gMC42KQ0KeXRpY2sgPSAoMTo4KSAqIDEwMDAwMA0KYXhpcygyLCBhdCA9IHl0aWNrLCBsYXMgPSAyLCBjZXguYXhpcyA9IDAuNTUsDQpsYWJlbHMgPSBmb3JtYXRDKHl0aWNrLCBiaWcubWFyayA9ICIsIiwgZm9ybWF0PSJmIiwgZGlnaXRzID0gMCkpDQoNCmxpbmVzKGRhdGFEQzIkeCwgZGF0YURDMiR5LCBsdHk9MSkNCnBvaW50cyhkYXRhREMyJHgsIGRhdGFEQzIkeSwgcGNoID0xNikNCmxpbmVzKGRhdGFEQzUkeCwgZGF0YURDNSR5LCBsdHk9MSkNCnBvaW50cyhkYXRhREM1JHgsIGRhdGFEQzUkeSwgcGNoID0xNSkNCmxpbmVzKGRhdGFEQzgkeCwgZGF0YURDOCR5LCBsdHk9MSkNCnBvaW50cyhkYXRhREM4JHgsIGRhdGFEQzgkeSwgcGNoID0xNykNCmxpbmVzKGRhdGFEQjAkeCwgZGF0YURCMCR5LCBsdHkgPSA1KQ0KbGluZXMoZGF0YURCNCR4LCBkYXRhREI0JHksIGx0eSA9IDMpDQpgYGANCjxjZW50ZXI+DQoNCiFbKipGaWd1cmUgMS4qKiBOZXQgUHJlc2VudCBWYWx1ZSBvZiBSZXRpcmVtZW50IFBsYW5zIGF0IEFnZXMgb2YgU2VwZXJhdGlvbl0oTWFzdGVyUGxvdF9LZXkucG5nKQ0KDQo8L2NlbnRlcj4NCg0KDQpGb3IgdGhpcyBncmFwaCwgVGhlIERDIHBsYW7igJlzIFJldHVybiBSYXRlIG9mIDglIGFuZCB0aGUgREIgcGxhbuKAmXMgRGlzY291bnQgUmF0ZSBvZiAzJSByZXByZXNlbnRzIGlkZWFsIGNvbmRpdGlvbnMgZm9yIGFuIGVtcGxveWVlIHRvIGdldCB0aGUgbW9zdCB2YWx1ZSBvdXQgb2YgdGhlaXIgaW52ZXN0bWVudHMsIHdpdGggYSBSZXR1cm4gUmF0ZSBvZiA4JS4gV2hpbGUgdGhlIERCIHRyYWRpdGlvbmFsIHBsYW4gaXMgdmVzdGluZywgdGhlIERDIGhhcyBhbiBvYnZpb3VzIGxlYWQgZnJvbSBzdGFydGluZyBpbW1lZGlhdGVseSwgd2l0aCB0aGUgTlBWIG9mIHRoZSA1JSBSZXR1cm4gUmF0ZSBuZXR0aW5nICQ4OTU2MC4xNC4gQWZ0ZXIgdmVzdGluZywgYm90aCBEQiBvdXRwYWNlIHRoZSBEQydzIDIlIFJldHVybiBSYXRlIGdyYXBoLCBidXQgYSAyJSBSZXR1cm4gUmF0ZSBpcyB1bmxpa2VseSB0byBoYXBwZW4sIGFzIGl0J3MgYW4gZXhhbXBsZSBvZiBhIHdvcnN0IGNhc2Ugc2NlbmFyaW8uIEJldHdlZW4gYWdlcyAzOCB0byA1Miwgbm90IG11Y2ggaGFwcGVucyBiZXNpZGVzIHRoZSBEQydzIFJldHVybiBSYXRlIG9mIDUlIGdldHRpbmcgb3V0cGFjZWQgYnkgdGhlIERCJ3MgZGlzY291bnQgcmF0ZSBvZiAzJS4gDQpBZnRlciAyMSB5ZWFycywgYnkgQWdlIDUzLCB0aGUgNyUgRGlzY291bnQgUmF0ZSBEQiBwbGFuIG9mICQyNzM5NjQuMjAgDQpvdmVydGFrZXMgdGhlIDUlIFJldHVybiBSYXRlIERDIHBsYW4gb2YgJDI2NTIyMC4xMCwgd2l0aCB0aGUgZGlzY291bnQgcmF0ZSBjb250aW51YWxseSBpbmNyZWFzaW5nIGluIHNpemUuIE5vdGFibHksIGhvd2V2ZXIsIHRoZSAzJSBEaXNjb3VudCBSYXRlIERCIHBsYW4gaXMgb25seSBoYWxmd2F5IGJldHdlZW4gdGhlIDUlIGFuZCA4JSBEQyBwbGFuLCB3aGljaCBtZWFucyB0aGF0IHRoZSBSU1BzIHN0aWxsIGhhdmUgdGhlIHBvc3NpYmlsaXR5IG91dHBlcmZvcm0gdGhlIFRSRHMgd2l0aCBkZWNlbnQgZ3Jvd3RoIHJhdGVzLg0KQnkgQWdlIDU3IHdpdGggMjQgeWVhcnMgb2Ygc2VydmljZSwgdGhlIDMlIGRpc2NvdW50IHJhdGUgREIgcGxhbiBiZWF0cyBvdXQgdGhlIDglIFJldHVybiBSYXRlIERDIHBsYW4sIHdpdGggJDUyMzcxOC4wOCB0byANCiQ1MjA4ODYuMzIuIA0KDQpBdCBhZ2UgNjIsIGFmdGVyIDMwIHllYXJzIG9mIGNvbnNlY3V0aXZlIHNlcnZpY2UsIERCIHBsYW5zIG9idmlvdXNseSBjb21lIG91dCBvbiB0b3AuIFRoZSBCZXN0IENhc2UgU2NlbmFyaW8gZm9yIHRoZSBEQyBwbGFuIGlzIGF0IGEgMyUgZGlzY291bnQgcmF0ZSB3aXRoIGFuIE5QViBvZiAkNzI4NTU5LjM1Lg0KSW50ZXJlc3RpbmdseSwgdGhlIGJlc3QgY2FzZSBzY2VuYXJpbyBmb3IgdGhlIFJTUCBwbGFuLCB0aGUgOCUgUmV0dXJuIFJhdGUgREMgUGxhbiBhdCAkNTQsOTMzNC43MywgDQppcyBvbmx5IHNsaWdodGx5IGFoZWFkIG9mIHRoZSBtb3JlIGNvbnNlcnZhdGl2ZSBOVlAgb2YgdGhlIDclIGRpc2NvdW50IHJhdGUgREIgUGxhbiwgd2hvc2UgTlZQIGlzICQ1MTA2NTguNzguDQpUaGUgOCUgUmV0dXJuIFJhdGUgaXMgYmVzdCBjYXNlIHNjZW5hcmlvLCBhbmQgZXZlbiBhIG1vcmUgY29uc2VydmF0aXZlIERpc2NvdW50IHJhdGUgaXMgc2hvd24gdG8gYmUgYmV0dGVyIGFmdGVyIDMwIHllYXJzLiBUaGUgTlBWIGZvciB0aGUgNSUgUmV0dXJuIFJhdGUgREMgcGxhbiBpcyAkMzE3OTk2LjYwLA0KYW5kIHRoZSAyJSBSZXR1cm4gUmF0ZSBEQyBwbGFuIGlzICQxOTE1OTIuNzU5LCBzaG93aW5nIHRoYXQgb3ZlciBsb25nIHRlcm1zIG9mIHRpbWUsIHRoZSBUUkQgcGxhbiB3aWxsIGNvbWUgY2xvc2UsIGlmIG5vdCBvdXRyaWdodCBvdXRwYWNlIFJTUCBwbGFuLg0KDQoNCiMjIERpc2N1c3Npb24NCg0KRm9yIHRob3NlIHdobyBoYXZlIHRoZSBjaG9pY2Ugb2YgUGVuc2lvbiBQbGFuLCBzdWNoIGFzIHRob3NlIGluIHRoZSBTdGF0ZSBVbml2ZXJzaXR5IFJldGlyZW1lbnQgU3lzdGVtIGluIElsbGlub2lzLCBrbm93aW5nIE5ldCBQcmVzZW50IFZhbHVlIG9mIERlZmluZWQgQmVuZWZpdHMgdnMuIERlZmluZWQgQ29udHJpYnV0aW9uIFBsYW5zIGNhbiBoZWxwIGVtcGxveWVlcyBtYWtlIG1vcmUgZWR1Y2F0ZWQgaW52ZXN0bWVudHMgd2l0aCB0aGVpciByZXRpcmVtZW50IHBsYW5zIHRvIGFjY3J1ZSByZXRpcmVtZW50IHdlYWx0aCBtb3JlIGVhc2lseS4gVGhyb3VnaCB0aGUgY3JlYXRpb24gb2YgKipGaWd1cmUgMSoqLCBpdCBoYXMgYmVlbiBkZXRlcm1pbmVkIHRoYXQgZm9yIGxvbmcgcGVyaW9kcyBvZiBzZXJ2aWNlLCBzdWNoIGFzIHBlcmlvZHMgb2Ygc2VydmljZSBvZiAyNCB5ZWFycyBhbmQgb3ZlciwgU1VSUydzIFRyYWRpdGlvbmFsIFBsYW4gaGFzIG1vcmUgdmFsdWUuIFRoaXMgaXMgZHVlIHRvIG1vc3Qgb2YgdGhlIHZhbHVlIG9mIHRoZSBUUkQgcGxhbiBiZWluZyBiYWNrIGxvYWRlZC4gRm9yIHRob3NlIHVuZGVyIDI1IHllYXJzIG9mIHNlcnZpY2UsIERDIHBsYW5zIGhhdmUgbW9yZSByZWxpYWJsZSB2YWx1ZXMgdGhhdCB0aGV5IHdpbGwgYWNjdW11bGF0ZSBhdCBhZ2UgNjIsIGVzcGVjaWFsbHkgZm9yIHRob3NlIHZlcnkgdW5zdXJlIG9mIHRoZWlyIFNVUlMgcHJvZmVzc2lvbi4gVHdlbnR5IHllYXJzIG9mIHNlcnZpY2UgdG8gdGhlIHNhbWUgZW1wbG95ZXIgaXMgcXVpdGUgYSBsYXJnZSBhc2ssIGVzcGVjaWFsbHkgZm9yIHByb2Zlc3NvcnMsIHdob3NlIHNraWxscyBhbmQgcmVzZWFyY2ggY291bGQgZXh0ZW5kIGZhciBiZXlvbmQgdW5pdmVyc2l0aWVzIHRvIG90aGVyIHRlc3RpbmcgZmFjaWxpdGllcy4gDQoNClRoaXMsIGluIHBhcnQsIGNvdWxkIGJlIGEgcGFydCBvZiB0aGUgZXhwbGFuYXRpb24gZm9yIHRoZSBBbm51aXR5IFB1enpsZSwgYSBjdXJyZW50IHByb2JsZW0gaW4gdGhlIHRoZSBhY3R1YXJpYWwgZmllbGQuXjReIEN1cnJlbnRseSwgIG1vc3QgZWR1Y2F0ZWQsIGhpZ2gtc2FsYXJpZWQgcHJvZmVzc29ycyB0aGF0IHBsYW4gdG8gc3RheSB3aXRoIHRoZSBTVVJTIFN5c3RlbSBmb3IgYSBsb25nIHRpbWUgb3B0IGZvciB0aGUgRGVmaW5lZCBDb250cmlidXRpb24gcGxhbiByYXRoZXIgdGhhbiB0aGUgbW9yZSByZWxpYWJsZSBsb25nLXRlcm0gb2Z0ZW4gZm8gdGhlIERlZmluZWQgQmVuZWZpdHMgcGxhbi5eMV4gVGhlIEFubnVpdHkgUHV6emxlIGEgdmVyeSBjb21wbGljYXRlZCBwcm9ibGVtIHRoYXQgY3VycmVudCBhY3R1YXJpZXMgYXJlIHRyeWluZyB0byBkZXRlcm1pbmUsIHNvIHRoaXMgcHJvamVjdCB3b3VsZCBvbmx5IHNlcnZlIG9ubHkgYSBzbWFsbCBwYXJ0IG9mIHRoZSBleHBsYW5hdGlvbiBvZiB0aGlzIHBoZW5vbWVub24uDQoNCkZvciBmdXR1cmUgcmVzZWFyY2gsIG90aGVyIGVtcGxveWVycyB3aG8gb2ZmZXIgYm90aCBEZWZpbmVkIENvbnRyaWJ1dGlvbiBhbmQgRGVmaW5lZCBCZW5lZml0cyBwbGFucyBjb3VsZCBiZSBjb21wYXJlZCB3aXRoIFNVUlMgdG8gZ2l2ZSBhIG1vcmUgaG9saXN0aWMgdmlldyBvZiB0aGUgY29tcGFyaXNvbiBiZXR3ZWVuIHRoZSB0d28gcGxhbnMsIHN1Y2ggYXMgTWlkZGxlIFRlbm5lc3NlZSBTdGF0ZSBVbml2ZXJzaXR5LiANCkFkZGl0aW9uYWxseSwgdGhlIE5ldCBQcmVzZW50IFZhbHVlIG9mIGRpZmZlcmVudCBzdGFydGluZyBhZ2VzIHJldGlyaW5nIGF0IDYyIGNhbiBiZSBzaG93biB0byB0YWtlIGludG8gYWNjb3VudCB0aGUgdmFyaW91cyBhZ2VzIHRoYXQgcGVvcGxlIGNhbiBnZXQgaW50byBTVVJTIGpvYnMuDQpJbiBhZGRpdGlvbiwgU1VSUyBoYXMgdXBkYXRlZCB0aGVpciBUcmFkaXRpb25hbCBQbGFuIGluIDIwMTEgdG8gY2hhbmdlIHRoZSBgcGVuc2lvbmAgdmFsdWUuIFRoaXMgcGFwZXIgb25seSBjb3ZlcnMgdGhlIHBlbnNpb24gcGxhbnMgdGhhdCB3ZXJlIGNyZWF0ZWQgZnJvbSBKdWx5IDd0aCwgMTk5NywgdG8gSmFuIDFzdCwgMjAxMS4gQW5vdGhlciBtb2RlbCBvZiBtb3JlIHJlY2VudCBjaGFuZ2VzIGNvdWxkIG1lIG1hZGUgaW4gdGhlIGZ1dHVyZSB0byBzaG93IHRoZSBuZXQgcHJlc250IHZhbHVlIG9mIGFueW9uZSB3aG8gaXMgbG9va2luZyB0byBnZXQgaW50byB0aGUgZmllbGQuIA0KDQoNCiMjIFJlZmVyZW5jZQ0KLSAgIDE6IEplZmZlcnkgQnJvd24sIFNjb3R0IFdlaXNiZW5uZXIoMjAwOSkuIFdobyBDaG9vc2VzIERlZmluZWQgQ29udHJpYnV0aW9uIFBsYW5zPyBTb2NpYWwgU2VjdXJpdHkgUG9saWN5IGluIGEgQ2hhbmdpbmcgRW52aXJvbm1lbnQsIGJ5IEplZmZlcnkgQnJvd24sIEplZmZlcnkgTGllYm1hbiBhbmQgRGF2aWQgQS4gV2lzZS4NCg0KLSAgIDI6IE1hdHRoZXcgQ2hpbmdvcywgTWFydGluIFdlc3QgKDIwMTUpLiBXaGljaCBUZWFjaGVyIGNob29zZXMgRGVmaW5lZCBDb250cmlidXRpb24gUGVuc2lvbiBQbGFuPyBFdmlkZW5jZSBmcm9tIHRoZSBGbG9yaWRhIFJldGlyZW1lbnQgU3lzdGVtLiBFZHVjYXRpb24gRmluYW5jZSBhbmQgUG9saWN5LCBWb2wuICAxMC4NCg0KLSAgIDM6IFp2aSBCb2RpZSwgQWxhbiBKLiBNYXJjdXMsIFJvYmVydCBDLiBNZXJ0b24gKDE5ODgpLiBEZWZpbmVkIEJlbmVmaXQgdmVyc3VzIERlZmluZWQgQ29udHJpYnV0aW9uIFBlbnNpb24gUGxhbnM6IFdoYXQgYXJlIHRoZSBSZWFsIFRyYWRlLW9mZnM/IFBlbnNpb25zIGluIHRoZSBVLlMuIEVjb25vbXksIGJ5IFp2aSBCb2RpZSwgSm9obiBCLiBTaG92ZW4sIGFuZCBEYXZpZCBBLiAgMTM5Lg0KDQotICAgNDogVGhhbGVyLCBSLiBILiAoMjAxMSwgSnVuZSA0KS4gVGhlIGFubnVpdHkgcHV6emxlLiBodHRwczovL3d3dy5ueXRpbWVzLmNvbS8yMDExLzA2LzA1L2J1c2luZXNzL2Vjb25vbXkvMDV2aWV3Lmh0bWwgDQoNCi0gICA1OiBTb2NpYWwgU2VjdXJpdHkgQWRtaW5pc3RyYXRpb24gKDIwMjMpLiAyMDIwIEFjdHVhcmlhbCBMaWZlIFRhYmxlLiBodHRwczovL3d3dy5zc2EuZ292L29hY3QvU1RBVFMvdGFibGU0YzYuaHRtbCNzcw0K