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)

Figure 1. Net Present Value of Retirement Plans at Ages of Seperation

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