Valtteri Ahola - 135131

I am uploading the data to my workspace

sub<-readRDS("Substatnive.RData")

I end up with the sub object in my “sub” object.

Translate column names into English:

Aging_en<-sub$Aging
colnames(Aging_en)<-c("LP","Nr","Account Name","Type","Wn_Dr","Ma_Cr","Turnover Dr","Turnover Cr","Saldo_Balance","Current","<30","31_60","61_90","90_180","180_360",">1Y","PD","LGD","EAD")
BankAcc_en<-sub$BankAcc
colnames(BankAcc_en)<-c("Date","Account_DR.1.35700.","Account_CR.1.35700.","Value.1.35700.","Details.1.35700.")
ChOA_en<-sub$ChOA
colnames(ChOA_en)<-c("Section","Number","Account name","Class","Type")
Journal_en<-sub$Journal
colnames(Journal_en)<-c("Date","Account_DR.1.35700.","Account_CR.1.35700.","Value.1.35700.","Explanation.1.35700.")
Counter<-sub$Kontr
colnames(Counter)<-c("LP","Nr","Name","Type","Wn_Dr","Ma_Cr","OB._WN_DR","OB._MA_CR","Saldo_Balance")
TB_en<-sub$TB
colnames(TB_en)<-c("Nr","Class","NR.1","Account name","State","Subclass","Opening Balance","Debit bookings","Credit bookings","Closing balance")
ZPK_en<-sub$ZPK
colnames(ZPK_en)<-c("Section","Number","Account name","State","Account type")
CC_PL_en<-sub$CC_PL
CC_BS_en<-sub$CC_BS
FAR_RST_Final_en<-sub$FAR_RST_Final
colnames(FAR_RST_Final_en)<-c("LP","Date","Name","City","Depreciation rate","Gross value","Acc.depreciation","Depreciation","Sold","Type","NAME")
  1. Reconcile the turnover to the T&E: -let’s start by checking which accounts are related to turnover and which T&E:
View(ChOA_en %>% filter(Class == 'Revenue', Type == 'Resulting'))
View(ChOA_en %>% filter(Class == 'Cost', Type == 'Resulting'))

According to chart of accounts, revenue related accounts are accounts 701, 702, 730, 740, 750 and 760. T&E account is account number 406 “business travel”

Check the bookings from journal in whose account 406 has been either in the credit or debit side to analyze the bookings related to that account:

View(Journal_en %>% filter(Account_DR.1.35700. == '406'))
View(Journal_en %>% filter(Account_CR.1.35700. == '406'))

Do the same with the accounts 701, 702, 730, 740, 750 and 760:

View(Journal_en %>% filter(Account_CR.1.35700. %in% c('701', '702', '730', '740', '750', '760')))
View(Journal_en %>% filter(Account_DR.1.35700. %in% c('701', '702', '730', '740', '750', '760')))

After this the T&E bookings should be compared to turnover to make sure that all of the expenses are related to business travelling and entertainment(like hospitality for clients). Check that there is actual invoice for every expense and that they have been approved. Look that the expenses are related to clients and thus, are related to revenue-generating events. Compare the sum of account for the previous years to find any unexpected anomalies. The T&E expenses should be related to exisiting client’s of company:

View(Counter)

however, based on the data obtained we couldn’t make the actual deep analysis since the explanations regarding each booking in the journal spreadsheet were not detailed enough to obtain full review of the bookings in the T&E and revenue accounts

  1. Make an analytical review of fixed assets B/O + Increases - Decreases Reclassification BZ for gross and net worth. Analytically check the accrual for the reasonableness of the depreciation charge:

Retrieve the movement of fixed assets in the balance sheet:

fixed_assets_movement <- CC_BS_en[2,2] - CC_BS_en[2,3]

fixed_assets_movement

It seems that the fixed assets have increased amount 88152 compared to previous year

Next, let’s go to trial balance to calculate the opening balance, movement and closing balance of all fixed assets related accounts to find if they reconcile with the balance sheet figures:

I couldn’t identify all the accounts related to fixed assets so let’s assume that the accounts 10, 20, 30, 40 and 80 in the TB are related to fixed assets:

rows_to_sum <- c(1, 2, 3, 4, 10)

ob_fixed_assets <- sum(TB_en[rows_to_sum,7])

cb_fixed_assets <- sum(TB_en[rows_to_sum,10])

movement_of_fixed_assets <- cb_fixed_assets - ob_fixed_assets

increases_to_fx_assets <- sum(TB_en[rows_to_sum,8])
decreases_to_fx_assets <- sum(TB_en[rows_to_sum,9])

by analyzing, whether the closing balance of fixed asset accounts in trial balance equals to fixed assets amount at the end of current financial year and whether movement in fixed asset tb accounts equals to difference of fixed assets between current and previous financial year, we can analytically review if balance sheet figures are in line with tb. The difference should be traced if it exceeds the materiality limits. Increases (debit bookings to fixed asset accounts) and decreases (credit bookings to fixed asset accounts) can also be retrieved from trial balance.

From the fixed assets register, we can check the depreciation charge and compare it to the depreciation charge on the P&L statement:

depreciation_charge <- sum(FAR_RST_Final_en[,8])

Also, we can calculate the average depreciation rate from fixed asset register and then multiplying it with the accrued fixed asset from previous financial year and compare this to the depreciation charge on the financial statement and if material differences are detected, this should be noted:

average_depreciation_rate <- sum(FAR_RST_Final_en[1:113,5]) / 113

analytical_depreciation <- ob_fixed_assets * average_depreciation_rate
  1. check the fixed assets register for arithmetic accuracy:

first, let’s extract the most important columns from fixed asset register to recalculate depreciation:

fixed_asset_analysis <- FAR_RST_Final_en[,c(11,2,5,6,7,8)]

then, let’s add new column which contains manually calculated depreciation (gross value * depreciation rate)

fixed_asset_analysis$check = fixed_asset_analysis$`Gross value` * fixed_asset_analysis$`Depreciation rate`

let’s compare the values of this new column to the depreciation column:

fixed_asset_analysis$difference = fixed_asset_analysis$Depreciation - fixed_asset_analysis$check

sum(fixed_asset_analysis$difference)

it seems, that the sum of the difference column is 0 which means that the depreciation in the fixed asset register is correctly calculated

next, let’s calculate the current value of fixed assets based on fixed asset register:

sum(fixed_asset_analysis$`Gross value`) - sum(fixed_asset_analysis$Depreciation)

According to this calculation, the value of fixed assets should be 14096382. The value should be the same in the balance sheet.

  1. lnvalidate the provision for receivables. Prospective and retrospective:

Let’s extract aging accounts of customers from aging account:

Aging_customer <- Aging_en[Aging_en$Type=="Odbiorca",]
View(Aging_customer)

let’s calculate current receivables

Aging_customer$Current_receivables <- rowSums(Aging_customer[,10])
sum(Aging_customer$Current_receivables)

current receivables are -24180153 which means that there are no receivables, instead payables in total and no provision needed to be constructed.

let’s calculate prospective receivables:

Aging_customer$Prosepctive_receivables <- rowSums(Aging_customer[,11:16])
sum(Aging_customer$Prosepctive_receivables)

they are 12474179

let’s calculate expected losses for prospective receivables:

Aging_customer$Expected_losses <- Aging_customer$PD * Aging_customer$LGD * Aging_customer$EAD

sum(Aging_customer$Expected_losses)

expected losses for prospective receivables are 188186.3

let’s compare expected losses for provisions in the balance sheet

Provisions <- CC_BS_en[59,]
sum(Provisions[,2])

sum of provisions on the balance sheet is 102714

let’s calculate the difference between expected losses and provisions on the balance sheet:

Diff <- sum(Aging_customer$Expected_losses) - sum(Provisions[,2])

the difference is 85472,34 which means that expected losses in the future are expected to be greater than provision in the balance sheet so the provisions should be increased.

  1. reconcile the equity position to the KRS extract:

let’s extract equity related accounts from TB:

Equity_in_TB <- TB_en[c(99, 100, 101, 102, 103,109), c(4, 7, 10)]

According to those accounts, let’s calculate equity at the end of current financial year:

Equity_current_fy <- sum(Equity_in_TB[,3])

result is 210460.1

Also, let’s calculate equity at the end of previous financial year:

Equity_previous_fy <- sum(Equity_in_TB[,2])

Equity_previous_fy

result is 217083.6

let’s compare the results to the equity in the balance sheet:

Equity_in_BS <- CC_BS_en[c(50), c(1, 2, 3)]

BS_Equity_current_BS <- sum(Equity_in_BS[,2])

BS_Equity_current_BS #current financial year

BS_Equity_previous_BS <- sum(Equity_in_BS[,3])

BS_Equity_previous_BS #previous financial year

In the balance sheet equity at the end of current financial year is 656190 and at the end of previous financial year 644387.

let compare the BS and TB figures:

Current_year_difference <- BS_Equity_current_BS - Equity_current_fy

Current_year_difference

Previous_year_difference <- BS_Equity_previous_BS - Equity_previous_fy

Previous_year_difference

The difference between equity figures in BS and TB at the end of current financial year is: 445729.9 and at the end of previous financial year: 427303.3

So after the reconciliation of equity position between BS and TB it has been recognized a major difference which is mandatory to be investigated further.

  1. take a sample of fixed assets and check the calculation of depreciation:

let’s assume that the assurance control of the company is on relatively low level which means that to achieve low detection risk the sample size must be large. There is 113 items in fixed asset register so let’s pick at randomly 30 items to check the calculation of deprectiation:

random_numbers <- sample(1:113, 40)

random numbers picked are: 39 93 57 98 43 14 63 107 15 94 48 2 9 71 41 8 76 1 82 49 10 21 17 18 19 73 25 74 100 105 16 90 56 3 24 112 27 84 99 50

let’s calculate the depreciation of the chose items:

first, let’s extarct sample from fixed asset register

Fixed_assets_sample <- FAR_RST_Final_en %>% filter(LP %in% c(39, 93, 57, 98, 43, 14, 63, 107, 15, 94, 48, 2, 9, 71, 41, 8, 76, 1, 82, 49, 10, 21, 17, 18, 19, 73, 25, 74, 100, 105, 16, 90, 56, 3, 24, 112, 27, 84, 99, 50))

then, calculate the depreciation for each item in the sample:

Fixed_assets_sample$Calulated_sample_depreciation <- Fixed_assets_sample$`Gross value` * Fixed_assets_sample$`Depreciation rate`

calculated_depreciation <- sum(Fixed_assets_sample$Calulated_sample_depreciation)

then, calculate the original depreciation for each item:

original_depreciation <- sum(Fixed_assets_sample$Depreciation)

then, let’s check if they differ:

difference <- calculated_depreciation - original_depreciation

difference

the difference is zero which indicates that the current year depreciation for the sample is calculated correctly.

Next, let’s calculate the accumulated depreciation

first, let’s adjust new column to fixed asset sample where the last year of fy is included:

Fixed_assets_sample$current_date <- as.Date('2022-12-31', format = '%Y-%m-%d')

then, calculate the years from the purchase date of item to the end of current fy:

Fixed_assets_sample$years_since_purchase <- as.numeric(difftime(Fixed_assets_sample$current_date, Fixed_assets_sample$Date, units = "weeks")) / 52.25

then calulate the fixed asset sample yearly depreciation

Fixed_assets_sample$yearly_depreciation <- (Fixed_assets_sample$`Gross value`+ Fixed_assets_sample$Depreciation) * Fixed_assets_sample$`Depreciation rate`

then, let’s finish the acc.depreciation calculation:

Fixed_assets_sample$calculated_accum.depreciation <- Fixed_assets_sample$years_since_purchase * Fixed_assets_sample$yearly_depreciation

then, let’s sum the rows:

total_calulated_acc.depreciation <- sum(Fixed_assets_sample$calculated_accum.depreciation)

total_original_acc.depreciation <- sum(Fixed_assets_sample$Acc.depreciation)

let’s calculate the difference between calculation and original acc.deprectiation:

acc.depreciation_difference <- total_calulated_acc.depreciation - total_original_acc.depreciation

acc.depreciation_difference

according to the calculations the difference is 7908402 which indicates that there might be a significant error regarding accumulated depreciation in fixed asset register of which is important to check the calculation procedure and compare it the executed calculation done for the sample.

  1. Calculate the correctness of the calculation of interest on liabilities. Assume a rate of 8% pa:

First, let’s check the development of interest-bearing financial liabilities according to TB:

let’s extract them from the rest of the TB accounts

TB_interest_bearing_liabilities <- TB_en %>% filter(Nr %in% c(17, 18))

View(TB_interest_bearing_liabilities)

let’s recalculate the closing balance based on the op balance, credit and debit turnover:

TB_interest_bearing_liabilities$recalculated_closing_balance <- TB_interest_bearing_liabilities$`Opening Balance`- TB_interest_bearing_liabilities$`Debit bookings`+ TB_interest_bearing_liabilities$`Credit bookings`

TB_interest_bearing_liabilities$difference <- TB_interest_bearing_liabilities$`Closing balance`- TB_interest_bearing_liabilities$recalculated_closing_balance

sum(TB_interest_bearing_liabilities$difference)

according to recalculation, the difference is -15168.8 which means that the closing balance in the TB is 15168.8 smaller than the recalculated one. This is due to the fact that on TB it looks like that debit bookings are increasing the liabilities account balance and credit decreasing when it should be other way around. Let’s assume that the recalculated on is correct.

let’s assume that the increases in interest bearing liabilities has happened on average, in the middle of the year and use that information to calculate the interest for liabilities of the financial year:

interest_for_fy_according_TB <- sum(TB_interest_bearing_liabilities$`Opening Balance`) * 0.08 + (sum(TB_interest_bearing_liabilities$recalculated_closing_balance) - sum(TB_interest_bearing_liabilities$`Opening Balance`)) * (0.08/2)

interest_for_fy_according_TB

according to TB, the interest for liabilities should be 8509.094

let’s compare the result to interest expenses on the P&L:

interest_for_fy_in_PL <- CC_PL_en$`Amount at the end of current financial year`[27]

interest_difference <- interest_for_fy_in_PL - interest_for_fy_according_TB

interest_difference

Difference between interest in P&L and calculated interest is -1374.094 indicating that interest for liabilities in P&L might be understated.

  1. Write the audit program for provisions.

1 Understanding and documenting the process

-Obtain and document the entity’s policies and procedures for identifying, calculating, and recording provisions.

-Assess the design and implementation of key controls over the provision process.

2 Review provision estimates -Take the TB for the period being audited

-From the TB, choose the accounts to which provisions are booked.

-Analyze the opening balance of those accounts and closing balance to see the possible increase or decrease of provisions for the FY.

-Compare that the opening balance of provisions match with the provisions on the balance sheet of previous financial year and the the closing balance match with BS of current FY and that the difference with the changes for provisions on P&L.

-Compare provisions with industry benchmarks or similar entities, if available.

3 Testing the accuracy and completeness

-Calculate expected losses based on the counterpart aging for a sample of accounts: expected losses = PD * LGD * EAD

-Examine methods used to calculate the parameters

-Compare expected losses and provisions for sample accounts to reconcile that the provisions are in line with the expected losses.

-Inspect supporting documentation, such as contracts, agreements, or correspondence related to the provisions.

-Confirm completeness by reviewing minutes of board meetings, legal correspondence, and other relevant documents to identify potential provisions not recorded.

4 Review of Subsequent Events

-Review subsequent events up to the date of the auditor’s report to identify any events that might affect the provisions.

-Verify whether any adjustments or disclosures are necessary based on subsequent events.

5 Disclosures in Financial Statements

-Ensure that disclosures include a description of the nature of the provision, the uncertainties related to the amount or timing, and the expected timing of any resulting outflows.

-Compare disclosures with the requirements of the applicable financial reporting framework (e.g., IFRS, GAAP).

6 Finish the process

-Prepare audit working papers detailing the audit procedures performed, evidence obtained, and conclusions reached.

-Inform all the relevant parties including audit team and client for the results.

-Discuss with the management about the results and whether any changes are necessary and how the management is planning to do them

  1. Write a general audit program.

1 Determine the objective for the audit

2 Audit planning

2.1 Understand the Entity and Its Environment

-Obtain background information about the entity, including its industry, regulatory environment, and key stakeholders.

-Review prior year audit files and reports.

2.2 Assess Risks and Determine Materiality

-Identify and assess the risks of material misstatement at the financial statement and assertion levels.

-Determine materiality for the financial statements as a whole and performance materiality.

-Document risk assessment and materiality thresholds.

2.3 Develop Audit Strategy and Plan

-Develop an overall audit strategy, including the scope, timing, and direction of the audit.

-Prepare a detailed audit plan outlining specific audit procedures to be performed.

-Allocate audit resources and assign responsibilities to the audit team.

3 Internal Controls

3.1 Evaluate Design and Implementation of Internal Controls

-Obtain an understanding of the internal control system, including control activities, risk assessment, information and communication, monitoring, and control environment.

-Evaluate the design and implementation of key controls relevant to the audit.

-Perform walkthroughs to verify the implementation of controls.

3.2 Test Operating Effectiveness of Controls

-Select a sample of transactions and test the operating effectiveness of key controls.

-Document the results of control testing and assess whether controls are operating effectively.

-Modify the nature, timing, and extent of substantive procedures based on control testing results.

4 Substantive Procedures

4.1 Cash and Bank

-Perform bank reconciliations.

-Confirm bank balances and loans with financial institutions.

-Test cash transactions for accuracy and completeness.

4.2. Receivables

-Confirm accounts receivable with customers.

-Review subsequent receipts for collectability.

-Analyze aging of receivables and evaluate allowance for doubtful accounts.

4.3.Inventory

-Observe physical inventory count.

-Test inventory valuation and costing methods.

-Evaluate inventory obsolescence and write-downs.

4.4. Property, Plant, and Equipment

-Verify existence through physical inspection.

-Test additions and disposals for proper authorization and recording.

-Review depreciation calculations and assess useful lives.

4.5 Liabilities

-Confirm accounts payable with suppliers.

-Review subsequent payments and disbursements.

-Test accruals and provisions for completeness and accuracy.

4.6. Revenue and Expenses

-Test revenue recognition policies for compliance with accounting standards.

-Perform analytical procedures on revenue and expenses.

-Substantiate significant expenses and review supporting documentation.

5 Analytical Procedures

5.1 Perform Analytical Procedures

-Conduct ratio analysis and trend analysis.

-Compare current year financial data with prior periods and industry benchmarks.

-Investigate significant variances and unusual transactions.

6 Review and Reporting

6.1. Review Financial Statements

-Review the draft financial statements for compliance with the applicable financial reporting framework.

-Ensure that disclosures are complete and accurate.

6.2. Obtain Management Representations

-Obtain a management representation letter covering significant assertions made during the audit.

-Document representations obtained and evaluate their impact on the audit.

6.3. Finalize Audit Documentation

-Complete and review all audit working papers.

-Ensure that all audit evidence is appropriately documented and supports the audit opinion.

6.4. Issue Audit Report

-Prepare the draft audit report.

-Discuss audit findings and conclusions with management and those charged with governance.

-Issue the final audit report expressing the audit opinion.

LS0tCnRpdGxlOiAiQXVkaXQgbGFiIC8gU3Vic3RhbnRpdmUgd29ya3Nob3AiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KClZhbHR0ZXJpIEFob2xhIC0gMTM1MTMxCgpJIGFtIHVwbG9hZGluZyB0aGUgZGF0YSB0byBteSB3b3Jrc3BhY2UKYGBge3J9CnN1YjwtcmVhZFJEUygiU3Vic3RhdG5pdmUuUkRhdGEiKQpgYGAKSSBlbmQgdXAgd2l0aCB0aGUgc3ViIG9iamVjdCBpbiBteSAic3ViIiBvYmplY3QuCgpUcmFuc2xhdGUgY29sdW1uIG5hbWVzIGludG8gRW5nbGlzaDoKYGBge3J9CkFnaW5nX2VuPC1zdWIkQWdpbmcKY29sbmFtZXMoQWdpbmdfZW4pPC1jKCJMUCIsIk5yIiwiQWNjb3VudCBOYW1lIiwiVHlwZSIsIlduX0RyIiwiTWFfQ3IiLCJUdXJub3ZlciBEciIsIlR1cm5vdmVyIENyIiwiU2FsZG9fQmFsYW5jZSIsIkN1cnJlbnQiLCI8MzAiLCIzMV82MCIsIjYxXzkwIiwiOTBfMTgwIiwiMTgwXzM2MCIsIj4xWSIsIlBEIiwiTEdEIiwiRUFEIikKQmFua0FjY19lbjwtc3ViJEJhbmtBY2MKY29sbmFtZXMoQmFua0FjY19lbik8LWMoIkRhdGUiLCJBY2NvdW50X0RSLjEuMzU3MDAuIiwiQWNjb3VudF9DUi4xLjM1NzAwLiIsIlZhbHVlLjEuMzU3MDAuIiwiRGV0YWlscy4xLjM1NzAwLiIpCkNoT0FfZW48LXN1YiRDaE9BCmNvbG5hbWVzKENoT0FfZW4pPC1jKCJTZWN0aW9uIiwiTnVtYmVyIiwiQWNjb3VudCBuYW1lIiwiQ2xhc3MiLCJUeXBlIikKSm91cm5hbF9lbjwtc3ViJEpvdXJuYWwKY29sbmFtZXMoSm91cm5hbF9lbik8LWMoIkRhdGUiLCJBY2NvdW50X0RSLjEuMzU3MDAuIiwiQWNjb3VudF9DUi4xLjM1NzAwLiIsIlZhbHVlLjEuMzU3MDAuIiwiRXhwbGFuYXRpb24uMS4zNTcwMC4iKQpDb3VudGVyPC1zdWIkS29udHIKY29sbmFtZXMoQ291bnRlcik8LWMoIkxQIiwiTnIiLCJOYW1lIiwiVHlwZSIsIlduX0RyIiwiTWFfQ3IiLCJPQi5fV05fRFIiLCJPQi5fTUFfQ1IiLCJTYWxkb19CYWxhbmNlIikKVEJfZW48LXN1YiRUQgpjb2xuYW1lcyhUQl9lbik8LWMoIk5yIiwiQ2xhc3MiLCJOUi4xIiwiQWNjb3VudCBuYW1lIiwiU3RhdGUiLCJTdWJjbGFzcyIsIk9wZW5pbmcgQmFsYW5jZSIsIkRlYml0IGJvb2tpbmdzIiwiQ3JlZGl0IGJvb2tpbmdzIiwiQ2xvc2luZyBiYWxhbmNlIikKWlBLX2VuPC1zdWIkWlBLCmNvbG5hbWVzKFpQS19lbik8LWMoIlNlY3Rpb24iLCJOdW1iZXIiLCJBY2NvdW50IG5hbWUiLCJTdGF0ZSIsIkFjY291bnQgdHlwZSIpCkNDX1BMX2VuPC1zdWIkQ0NfUEwKQ0NfQlNfZW48LXN1YiRDQ19CUwpGQVJfUlNUX0ZpbmFsX2VuPC1zdWIkRkFSX1JTVF9GaW5hbApjb2xuYW1lcyhGQVJfUlNUX0ZpbmFsX2VuKTwtYygiTFAiLCJEYXRlIiwiTmFtZSIsIkNpdHkiLCJEZXByZWNpYXRpb24gcmF0ZSIsIkdyb3NzIHZhbHVlIiwiQWNjLmRlcHJlY2lhdGlvbiIsIkRlcHJlY2lhdGlvbiIsIlNvbGQiLCJUeXBlIiwiTkFNRSIpCmBgYAoxLiBSZWNvbmNpbGUgdGhlIHR1cm5vdmVyIHRvIHRoZSBUJkU6Ci1sZXQncyBzdGFydCBieSBjaGVja2luZyB3aGljaCBhY2NvdW50cyBhcmUgcmVsYXRlZCB0byB0dXJub3ZlciBhbmQgd2hpY2ggVCZFOgpgYGB7cn0KVmlldyhDaE9BX2VuICU+JSBmaWx0ZXIoQ2xhc3MgPT0gJ1JldmVudWUnLCBUeXBlID09ICdSZXN1bHRpbmcnKSkKVmlldyhDaE9BX2VuICU+JSBmaWx0ZXIoQ2xhc3MgPT0gJ0Nvc3QnLCBUeXBlID09ICdSZXN1bHRpbmcnKSkKYGBgCkFjY29yZGluZyB0byBjaGFydCBvZiBhY2NvdW50cywgcmV2ZW51ZSByZWxhdGVkIGFjY291bnRzIGFyZSBhY2NvdW50cyA3MDEsIDcwMiwgNzMwLCA3NDAsIDc1MCBhbmQgNzYwLiBUJkUgYWNjb3VudCBpcyBhY2NvdW50IG51bWJlciA0MDYgImJ1c2luZXNzIHRyYXZlbCIKCkNoZWNrIHRoZSBib29raW5ncyBmcm9tIGpvdXJuYWwgaW4gd2hvc2UgYWNjb3VudCA0MDYgaGFzIGJlZW4gZWl0aGVyIGluIHRoZSBjcmVkaXQgb3IgZGViaXQgc2lkZSB0byBhbmFseXplIHRoZSBib29raW5ncyByZWxhdGVkIHRvIHRoYXQgYWNjb3VudDoKYGBge3J9ClZpZXcoSm91cm5hbF9lbiAlPiUgZmlsdGVyKEFjY291bnRfRFIuMS4zNTcwMC4gPT0gJzQwNicpKQpWaWV3KEpvdXJuYWxfZW4gJT4lIGZpbHRlcihBY2NvdW50X0NSLjEuMzU3MDAuID09ICc0MDYnKSkKYGBgCkRvIHRoZSBzYW1lIHdpdGggdGhlIGFjY291bnRzIDcwMSwgNzAyLCA3MzAsIDc0MCwgNzUwIGFuZCA3NjA6CmBgYHtyfQpWaWV3KEpvdXJuYWxfZW4gJT4lIGZpbHRlcihBY2NvdW50X0NSLjEuMzU3MDAuICVpbiUgYygnNzAxJywgJzcwMicsICc3MzAnLCAnNzQwJywgJzc1MCcsICc3NjAnKSkpClZpZXcoSm91cm5hbF9lbiAlPiUgZmlsdGVyKEFjY291bnRfRFIuMS4zNTcwMC4gJWluJSBjKCc3MDEnLCAnNzAyJywgJzczMCcsICc3NDAnLCAnNzUwJywgJzc2MCcpKSkKYGBgCkFmdGVyIHRoaXMgdGhlIFQmRSBib29raW5ncyBzaG91bGQgYmUgY29tcGFyZWQgdG8gdHVybm92ZXIgdG8gbWFrZSBzdXJlIHRoYXQgYWxsIG9mIHRoZSBleHBlbnNlcyBhcmUgcmVsYXRlZCB0byBidXNpbmVzcyB0cmF2ZWxsaW5nIGFuZCBlbnRlcnRhaW5tZW50KGxpa2UgaG9zcGl0YWxpdHkgZm9yIGNsaWVudHMpLiBDaGVjayB0aGF0IHRoZXJlIGlzIGFjdHVhbCBpbnZvaWNlIGZvciBldmVyeSBleHBlbnNlIGFuZCB0aGF0IHRoZXkgaGF2ZSBiZWVuIGFwcHJvdmVkLiBMb29rIHRoYXQgdGhlIGV4cGVuc2VzIGFyZSByZWxhdGVkIHRvIGNsaWVudHMgYW5kIHRodXMsIGFyZSByZWxhdGVkIHRvIHJldmVudWUtZ2VuZXJhdGluZyBldmVudHMuIENvbXBhcmUgdGhlIHN1bSBvZiBhY2NvdW50IGZvciB0aGUgcHJldmlvdXMgeWVhcnMgdG8gZmluZCBhbnkgdW5leHBlY3RlZCBhbm9tYWxpZXMuIFRoZSBUJkUgZXhwZW5zZXMgc2hvdWxkIGJlIHJlbGF0ZWQgdG8gZXhpc2l0aW5nIGNsaWVudCdzIG9mIGNvbXBhbnk6CmBgYHtyfQpWaWV3KENvdW50ZXIpCmBgYApob3dldmVyLCBiYXNlZCBvbiB0aGUgZGF0YSBvYnRhaW5lZCB3ZSBjb3VsZG4ndCBtYWtlIHRoZSBhY3R1YWwgZGVlcCBhbmFseXNpcyBzaW5jZSB0aGUgZXhwbGFuYXRpb25zIHJlZ2FyZGluZyBlYWNoIGJvb2tpbmcgaW4gdGhlIGpvdXJuYWwgc3ByZWFkc2hlZXQgd2VyZSBub3QgZGV0YWlsZWQgZW5vdWdoIHRvIG9idGFpbiBmdWxsIHJldmlldyBvZiB0aGUgYm9va2luZ3MgaW4gdGhlIFQmRSBhbmQgcmV2ZW51ZSBhY2NvdW50cwoKMi4gTWFrZSBhbiBhbmFseXRpY2FsIHJldmlldyBvZiBmaXhlZCBhc3NldHMgQi9PICsgSW5jcmVhc2VzIC0gRGVjcmVhc2VzIFJlY2xhc3NpZmljYXRpb24gQlogZm9yIGdyb3NzIGFuZCBuZXQgd29ydGguIEFuYWx5dGljYWxseSBjaGVjayB0aGUgYWNjcnVhbCBmb3IgdGhlIHJlYXNvbmFibGVuZXNzIG9mIHRoZSBkZXByZWNpYXRpb24gY2hhcmdlOgoKUmV0cmlldmUgdGhlIG1vdmVtZW50IG9mIGZpeGVkIGFzc2V0cyBpbiB0aGUgYmFsYW5jZSBzaGVldDoKCmBgYHtyfQpmaXhlZF9hc3NldHNfbW92ZW1lbnQgPC0gQ0NfQlNfZW5bMiwyXSAtIENDX0JTX2VuWzIsM10KCmZpeGVkX2Fzc2V0c19tb3ZlbWVudAoKYGBgCkl0IHNlZW1zIHRoYXQgdGhlIGZpeGVkIGFzc2V0cyBoYXZlIGluY3JlYXNlZCBhbW91bnQgODgxNTIgY29tcGFyZWQgdG8gcHJldmlvdXMgeWVhcgoKTmV4dCwgbGV0J3MgZ28gdG8gdHJpYWwgYmFsYW5jZSB0byBjYWxjdWxhdGUgdGhlIG9wZW5pbmcgYmFsYW5jZSwgbW92ZW1lbnQgYW5kIGNsb3NpbmcgYmFsYW5jZSBvZiBhbGwgZml4ZWQgYXNzZXRzIHJlbGF0ZWQgYWNjb3VudHMgdG8gZmluZCBpZiB0aGV5IHJlY29uY2lsZSB3aXRoIHRoZSBiYWxhbmNlIHNoZWV0IGZpZ3VyZXM6CgpJIGNvdWxkbid0IGlkZW50aWZ5IGFsbCB0aGUgYWNjb3VudHMgcmVsYXRlZCB0byBmaXhlZCBhc3NldHMgc28gbGV0J3MgYXNzdW1lIHRoYXQgdGhlIGFjY291bnRzIDEwLCAyMCwgMzAsIDQwIGFuZCA4MCBpbiB0aGUgVEIgYXJlIHJlbGF0ZWQgdG8gZml4ZWQgYXNzZXRzOgoKYGBge3J9CnJvd3NfdG9fc3VtIDwtIGMoMSwgMiwgMywgNCwgMTApCgpvYl9maXhlZF9hc3NldHMgPC0gc3VtKFRCX2VuW3Jvd3NfdG9fc3VtLDddKQoKY2JfZml4ZWRfYXNzZXRzIDwtIHN1bShUQl9lbltyb3dzX3RvX3N1bSwxMF0pCgptb3ZlbWVudF9vZl9maXhlZF9hc3NldHMgPC0gY2JfZml4ZWRfYXNzZXRzIC0gb2JfZml4ZWRfYXNzZXRzCgppbmNyZWFzZXNfdG9fZnhfYXNzZXRzIDwtIHN1bShUQl9lbltyb3dzX3RvX3N1bSw4XSkKZGVjcmVhc2VzX3RvX2Z4X2Fzc2V0cyA8LSBzdW0oVEJfZW5bcm93c190b19zdW0sOV0pCmBgYApieSBhbmFseXppbmcsIHdoZXRoZXIgdGhlIGNsb3NpbmcgYmFsYW5jZSBvZiBmaXhlZCBhc3NldCBhY2NvdW50cyBpbiB0cmlhbCBiYWxhbmNlIGVxdWFscyB0byBmaXhlZCBhc3NldHMgYW1vdW50IGF0IHRoZSBlbmQgb2YgY3VycmVudCBmaW5hbmNpYWwgeWVhciBhbmQgd2hldGhlciBtb3ZlbWVudCBpbiBmaXhlZCBhc3NldCB0YiBhY2NvdW50cyBlcXVhbHMgdG8gZGlmZmVyZW5jZSBvZiBmaXhlZCBhc3NldHMgYmV0d2VlbiBjdXJyZW50IGFuZCBwcmV2aW91cyBmaW5hbmNpYWwgeWVhciwgd2UgY2FuIGFuYWx5dGljYWxseSByZXZpZXcgaWYgYmFsYW5jZSBzaGVldCBmaWd1cmVzIGFyZSBpbiBsaW5lIHdpdGggdGIuIFRoZSBkaWZmZXJlbmNlIHNob3VsZCBiZSB0cmFjZWQgaWYgaXQgZXhjZWVkcyB0aGUgbWF0ZXJpYWxpdHkgbGltaXRzLiBJbmNyZWFzZXMgKGRlYml0IGJvb2tpbmdzIHRvIGZpeGVkIGFzc2V0IGFjY291bnRzKSBhbmQgZGVjcmVhc2VzIChjcmVkaXQgYm9va2luZ3MgdG8gZml4ZWQgYXNzZXQgYWNjb3VudHMpIGNhbiBhbHNvIGJlIHJldHJpZXZlZCBmcm9tIHRyaWFsIGJhbGFuY2UuIAoKRnJvbSB0aGUgZml4ZWQgYXNzZXRzIHJlZ2lzdGVyLCB3ZSBjYW4gY2hlY2sgdGhlIGRlcHJlY2lhdGlvbiBjaGFyZ2UgYW5kIGNvbXBhcmUgaXQgdG8gdGhlIGRlcHJlY2lhdGlvbiBjaGFyZ2Ugb24gdGhlIFAmTCBzdGF0ZW1lbnQ6CgpgYGB7cn0KZGVwcmVjaWF0aW9uX2NoYXJnZSA8LSBzdW0oRkFSX1JTVF9GaW5hbF9lblssOF0pCmBgYApBbHNvLCB3ZSBjYW4gY2FsY3VsYXRlIHRoZSBhdmVyYWdlIGRlcHJlY2lhdGlvbiByYXRlIGZyb20gZml4ZWQgYXNzZXQgcmVnaXN0ZXIgYW5kIHRoZW4gbXVsdGlwbHlpbmcgaXQgd2l0aCB0aGUgYWNjcnVlZCBmaXhlZCBhc3NldCBmcm9tIHByZXZpb3VzIGZpbmFuY2lhbCB5ZWFyIGFuZCBjb21wYXJlIHRoaXMgdG8gdGhlIGRlcHJlY2lhdGlvbiBjaGFyZ2Ugb24gdGhlIGZpbmFuY2lhbCBzdGF0ZW1lbnQgYW5kIGlmIG1hdGVyaWFsIGRpZmZlcmVuY2VzIGFyZSBkZXRlY3RlZCwgdGhpcyBzaG91bGQgYmUgbm90ZWQ6CgpgYGB7cn0KYXZlcmFnZV9kZXByZWNpYXRpb25fcmF0ZSA8LSBzdW0oRkFSX1JTVF9GaW5hbF9lblsxOjExMyw1XSkgLyAxMTMKCmFuYWx5dGljYWxfZGVwcmVjaWF0aW9uIDwtIG9iX2ZpeGVkX2Fzc2V0cyAqIGF2ZXJhZ2VfZGVwcmVjaWF0aW9uX3JhdGUKYGBgCgozLiBjaGVjayB0aGUgZml4ZWQgYXNzZXRzIHJlZ2lzdGVyIGZvciBhcml0aG1ldGljIGFjY3VyYWN5OgoKZmlyc3QsIGxldCdzIGV4dHJhY3QgdGhlIG1vc3QgaW1wb3J0YW50IGNvbHVtbnMgZnJvbSBmaXhlZCBhc3NldCByZWdpc3RlciB0byByZWNhbGN1bGF0ZSBkZXByZWNpYXRpb246CgpgYGB7cn0KZml4ZWRfYXNzZXRfYW5hbHlzaXMgPC0gRkFSX1JTVF9GaW5hbF9lblssYygxMSwyLDUsNiw3LDgpXQpgYGAKCnRoZW4sIGxldCdzIGFkZCBuZXcgY29sdW1uIHdoaWNoIGNvbnRhaW5zIG1hbnVhbGx5IGNhbGN1bGF0ZWQgZGVwcmVjaWF0aW9uIChncm9zcyB2YWx1ZSAqIGRlcHJlY2lhdGlvbiByYXRlKQoKYGBge3J9CmZpeGVkX2Fzc2V0X2FuYWx5c2lzJGNoZWNrID0gZml4ZWRfYXNzZXRfYW5hbHlzaXMkYEdyb3NzIHZhbHVlYCAqIGZpeGVkX2Fzc2V0X2FuYWx5c2lzJGBEZXByZWNpYXRpb24gcmF0ZWAKYGBgCgpsZXQncyBjb21wYXJlIHRoZSB2YWx1ZXMgb2YgdGhpcyBuZXcgY29sdW1uIHRvIHRoZSBkZXByZWNpYXRpb24gY29sdW1uOgoKYGBge3J9CmZpeGVkX2Fzc2V0X2FuYWx5c2lzJGRpZmZlcmVuY2UgPSBmaXhlZF9hc3NldF9hbmFseXNpcyREZXByZWNpYXRpb24gLSBmaXhlZF9hc3NldF9hbmFseXNpcyRjaGVjawoKc3VtKGZpeGVkX2Fzc2V0X2FuYWx5c2lzJGRpZmZlcmVuY2UpCmBgYAppdCBzZWVtcywgdGhhdCB0aGUgc3VtIG9mIHRoZSBkaWZmZXJlbmNlIGNvbHVtbiBpcyAwIHdoaWNoIG1lYW5zIHRoYXQgdGhlIGRlcHJlY2lhdGlvbiBpbiB0aGUgZml4ZWQgYXNzZXQgcmVnaXN0ZXIgaXMgY29ycmVjdGx5IGNhbGN1bGF0ZWQKCm5leHQsIGxldCdzIGNhbGN1bGF0ZSB0aGUgY3VycmVudCB2YWx1ZSBvZiBmaXhlZCBhc3NldHMgYmFzZWQgb24gZml4ZWQgYXNzZXQgcmVnaXN0ZXI6CgpgYGB7cn0Kc3VtKGZpeGVkX2Fzc2V0X2FuYWx5c2lzJGBHcm9zcyB2YWx1ZWApIC0gc3VtKGZpeGVkX2Fzc2V0X2FuYWx5c2lzJERlcHJlY2lhdGlvbikKYGBgCkFjY29yZGluZyB0byB0aGlzIGNhbGN1bGF0aW9uLCB0aGUgdmFsdWUgb2YgZml4ZWQgYXNzZXRzIHNob3VsZCBiZSAxNDA5NjM4Mi4gVGhlIHZhbHVlIHNob3VsZCBiZSB0aGUgc2FtZSBpbiB0aGUgYmFsYW5jZSBzaGVldC4gCgo0LiBsbnZhbGlkYXRlIHRoZSBwcm92aXNpb24gZm9yIHJlY2VpdmFibGVzLiBQcm9zcGVjdGl2ZSBhbmQgcmV0cm9zcGVjdGl2ZToKCkxldCdzIGV4dHJhY3QgYWdpbmcgYWNjb3VudHMgb2YgY3VzdG9tZXJzIGZyb20gYWdpbmcgYWNjb3VudDoKYGBge3J9CkFnaW5nX2N1c3RvbWVyIDwtIEFnaW5nX2VuW0FnaW5nX2VuJFR5cGU9PSJPZGJpb3JjYSIsXQpWaWV3KEFnaW5nX2N1c3RvbWVyKQpgYGAKbGV0J3MgY2FsY3VsYXRlIGN1cnJlbnQgcmVjZWl2YWJsZXMKYGBge3J9CkFnaW5nX2N1c3RvbWVyJEN1cnJlbnRfcmVjZWl2YWJsZXMgPC0gcm93U3VtcyhBZ2luZ19jdXN0b21lclssMTBdKQpzdW0oQWdpbmdfY3VzdG9tZXIkQ3VycmVudF9yZWNlaXZhYmxlcykKYGBgCmN1cnJlbnQgcmVjZWl2YWJsZXMgYXJlIC0yNDE4MDE1MyB3aGljaCBtZWFucyB0aGF0IHRoZXJlIGFyZSBubyByZWNlaXZhYmxlcywgaW5zdGVhZCBwYXlhYmxlcyBpbiB0b3RhbCBhbmQgbm8gcHJvdmlzaW9uIG5lZWRlZCB0byBiZSBjb25zdHJ1Y3RlZC4gCgpsZXQncyBjYWxjdWxhdGUgcHJvc3BlY3RpdmUgcmVjZWl2YWJsZXM6CgpgYGB7cn0KQWdpbmdfY3VzdG9tZXIkUHJvc2VwY3RpdmVfcmVjZWl2YWJsZXMgPC0gcm93U3VtcyhBZ2luZ19jdXN0b21lclssMTE6MTZdKQpzdW0oQWdpbmdfY3VzdG9tZXIkUHJvc2VwY3RpdmVfcmVjZWl2YWJsZXMpCmBgYAp0aGV5IGFyZSAxMjQ3NDE3OQoKbGV0J3MgY2FsY3VsYXRlIGV4cGVjdGVkIGxvc3NlcyBmb3IgcHJvc3BlY3RpdmUgcmVjZWl2YWJsZXM6CgpgYGB7cn0KQWdpbmdfY3VzdG9tZXIkRXhwZWN0ZWRfbG9zc2VzIDwtIEFnaW5nX2N1c3RvbWVyJFBEICogQWdpbmdfY3VzdG9tZXIkTEdEICogQWdpbmdfY3VzdG9tZXIkRUFECgpzdW0oQWdpbmdfY3VzdG9tZXIkRXhwZWN0ZWRfbG9zc2VzKQpgYGAKZXhwZWN0ZWQgbG9zc2VzIGZvciBwcm9zcGVjdGl2ZSByZWNlaXZhYmxlcyBhcmUgMTg4MTg2LjMKCmxldCdzIGNvbXBhcmUgZXhwZWN0ZWQgbG9zc2VzIGZvciBwcm92aXNpb25zIGluIHRoZSBiYWxhbmNlIHNoZWV0CmBgYHtyfQpQcm92aXNpb25zIDwtIENDX0JTX2VuWzU5LF0Kc3VtKFByb3Zpc2lvbnNbLDJdKQpgYGAKc3VtIG9mIHByb3Zpc2lvbnMgb24gdGhlIGJhbGFuY2Ugc2hlZXQgaXMgMTAyNzE0CgpsZXQncyBjYWxjdWxhdGUgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBleHBlY3RlZCBsb3NzZXMgYW5kIHByb3Zpc2lvbnMgb24gdGhlIGJhbGFuY2Ugc2hlZXQ6CmBgYHtyfQpEaWZmIDwtIHN1bShBZ2luZ19jdXN0b21lciRFeHBlY3RlZF9sb3NzZXMpIC0gc3VtKFByb3Zpc2lvbnNbLDJdKQpgYGAKdGhlIGRpZmZlcmVuY2UgaXMgODU0NzIsMzQgd2hpY2ggbWVhbnMgdGhhdCBleHBlY3RlZCBsb3NzZXMgaW4gdGhlIGZ1dHVyZSBhcmUgZXhwZWN0ZWQgdG8gYmUgZ3JlYXRlciB0aGFuIHByb3Zpc2lvbiBpbiB0aGUgYmFsYW5jZSBzaGVldCBzbyB0aGUgcHJvdmlzaW9ucyBzaG91bGQgYmUgaW5jcmVhc2VkLiAKCjYuIHJlY29uY2lsZSB0aGUgZXF1aXR5IHBvc2l0aW9uIHRvIHRoZSBLUlMgZXh0cmFjdDoKCmxldCdzIGV4dHJhY3QgZXF1aXR5IHJlbGF0ZWQgYWNjb3VudHMgZnJvbSBUQjoKYGBge3J9CkVxdWl0eV9pbl9UQiA8LSBUQl9lbltjKDk5LCAxMDAsIDEwMSwgMTAyLCAxMDMsMTA5KSwgYyg0LCA3LCAxMCldCmBgYAoKQWNjb3JkaW5nIHRvIHRob3NlIGFjY291bnRzLCBsZXQncyBjYWxjdWxhdGUgZXF1aXR5IGF0IHRoZSBlbmQgb2YgY3VycmVudCBmaW5hbmNpYWwgeWVhcjoKCmBgYHtyIGVjaG89VFJVRX0KRXF1aXR5X2N1cnJlbnRfZnkgPC0gc3VtKEVxdWl0eV9pbl9UQlssM10pCgpFcXVpdHlfY3VycmVudF9meQpgYGAKcmVzdWx0IGlzIDIxMDQ2MC4xCgpBbHNvLCBsZXQncyBjYWxjdWxhdGUgZXF1aXR5IGF0IHRoZSBlbmQgb2YgcHJldmlvdXMgZmluYW5jaWFsIHllYXI6CmBgYHtyfQpFcXVpdHlfcHJldmlvdXNfZnkgPC0gc3VtKEVxdWl0eV9pbl9UQlssMl0pCgpFcXVpdHlfcHJldmlvdXNfZnkKYGBgCnJlc3VsdCBpcyAyMTcwODMuNgoKbGV0J3MgY29tcGFyZSB0aGUgcmVzdWx0cyB0byB0aGUgZXF1aXR5IGluIHRoZSBiYWxhbmNlIHNoZWV0OgoKYGBge3J9CkVxdWl0eV9pbl9CUyA8LSBDQ19CU19lbltjKDUwKSwgYygxLCAyLCAzKV0KCkJTX0VxdWl0eV9jdXJyZW50X0JTIDwtIHN1bShFcXVpdHlfaW5fQlNbLDJdKQoKQlNfRXF1aXR5X2N1cnJlbnRfQlMgI2N1cnJlbnQgZmluYW5jaWFsIHllYXIKCkJTX0VxdWl0eV9wcmV2aW91c19CUyA8LSBzdW0oRXF1aXR5X2luX0JTWywzXSkKCkJTX0VxdWl0eV9wcmV2aW91c19CUyAjcHJldmlvdXMgZmluYW5jaWFsIHllYXIKYGBgCkluIHRoZSBiYWxhbmNlIHNoZWV0IGVxdWl0eSBhdCB0aGUgZW5kIG9mIGN1cnJlbnQgZmluYW5jaWFsIHllYXIgaXMgNjU2MTkwIGFuZCBhdCB0aGUgZW5kIG9mIHByZXZpb3VzIGZpbmFuY2lhbCB5ZWFyIDY0NDM4Ny4KCmxldCBjb21wYXJlIHRoZSBCUyBhbmQgVEIgZmlndXJlczoKCmBgYHtyfQpDdXJyZW50X3llYXJfZGlmZmVyZW5jZSA8LSBCU19FcXVpdHlfY3VycmVudF9CUyAtIEVxdWl0eV9jdXJyZW50X2Z5CgpDdXJyZW50X3llYXJfZGlmZmVyZW5jZQoKUHJldmlvdXNfeWVhcl9kaWZmZXJlbmNlIDwtIEJTX0VxdWl0eV9wcmV2aW91c19CUyAtIEVxdWl0eV9wcmV2aW91c19meQoKUHJldmlvdXNfeWVhcl9kaWZmZXJlbmNlCmBgYApUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGVxdWl0eSBmaWd1cmVzIGluIEJTIGFuZCBUQiBhdCB0aGUgZW5kIG9mIGN1cnJlbnQgZmluYW5jaWFsIHllYXIgaXM6IDQ0NTcyOS45IGFuZCBhdCB0aGUgZW5kIG9mIHByZXZpb3VzIGZpbmFuY2lhbCB5ZWFyOiA0MjczMDMuMwoKU28gYWZ0ZXIgdGhlIHJlY29uY2lsaWF0aW9uIG9mIGVxdWl0eSBwb3NpdGlvbiBiZXR3ZWVuIEJTIGFuZCBUQiBpdCBoYXMgYmVlbiByZWNvZ25pemVkIGEgbWFqb3IgZGlmZmVyZW5jZSB3aGljaCBpcyBtYW5kYXRvcnkgdG8gYmUgaW52ZXN0aWdhdGVkIGZ1cnRoZXIuIAoKNy4gdGFrZSBhIHNhbXBsZSBvZiBmaXhlZCBhc3NldHMgYW5kIGNoZWNrIHRoZSBjYWxjdWxhdGlvbiBvZiBkZXByZWNpYXRpb246CgpsZXQncyBhc3N1bWUgdGhhdCB0aGUgYXNzdXJhbmNlIGNvbnRyb2wgb2YgdGhlIGNvbXBhbnkgaXMgb24gcmVsYXRpdmVseSBsb3cgbGV2ZWwgd2hpY2ggbWVhbnMgdGhhdCB0byBhY2hpZXZlIGxvdyBkZXRlY3Rpb24gcmlzayB0aGUgc2FtcGxlIHNpemUgbXVzdCBiZSBsYXJnZS4gVGhlcmUgaXMgMTEzIGl0ZW1zIGluIGZpeGVkIGFzc2V0IHJlZ2lzdGVyIHNvIGxldCdzIHBpY2sgYXQgcmFuZG9tbHkgMzAgaXRlbXMgdG8gY2hlY2sgdGhlIGNhbGN1bGF0aW9uIG9mIGRlcHJlY3RpYXRpb246CgpgYGB7ciBlY2hvPVRSVUV9CnJhbmRvbV9udW1iZXJzIDwtIHNhbXBsZSgxOjExMywgNDApCgpyYW5kb21fbnVtYmVycwpgYGAKcmFuZG9tIG51bWJlcnMgcGlja2VkIGFyZTogMzkgIDkzICA1NyAgOTggIDQzICAxNCAgNjMKMTA3ICAxNSAgOTQgIDQ4ICAgMiAgIDkgIDcxCjQxICAgOCAgNzYgICAxICA4MiAgNDkgIDEwCjIxICAxNyAgMTggIDE5ICA3MyAgMjUgIDc0CjEwMCAxMDUgIDE2ICA5MCAgNTYgICAzICAyNAoxMTIgIDI3ICA4NCAgOTkgIDUwCgpsZXQncyBjYWxjdWxhdGUgdGhlIGRlcHJlY2lhdGlvbiBvZiB0aGUgY2hvc2UgaXRlbXM6CgpmaXJzdCwgbGV0J3MgZXh0YXJjdCBzYW1wbGUgZnJvbSBmaXhlZCBhc3NldCByZWdpc3RlcgpgYGB7cn0KRml4ZWRfYXNzZXRzX3NhbXBsZSA8LSBGQVJfUlNUX0ZpbmFsX2VuICU+JSBmaWx0ZXIoTFAgJWluJSBjKDM5LCA5MywgNTcsIDk4LCA0MywgMTQsIDYzLCAxMDcsIDE1LCA5NCwgNDgsIDIsIDksIDcxLCA0MSwgOCwgNzYsIDEsIDgyLCA0OSwgMTAsIDIxLCAxNywgMTgsIDE5LCA3MywgMjUsIDc0LCAxMDAsIDEwNSwgMTYsIDkwLCA1NiwgMywgMjQsIDExMiwgMjcsIDg0LCA5OSwgNTApKQpgYGAKCnRoZW4sIGNhbGN1bGF0ZSB0aGUgZGVwcmVjaWF0aW9uIGZvciBlYWNoIGl0ZW0gaW4gdGhlIHNhbXBsZToKYGBge3J9CkZpeGVkX2Fzc2V0c19zYW1wbGUkQ2FsdWxhdGVkX3NhbXBsZV9kZXByZWNpYXRpb24gPC0gRml4ZWRfYXNzZXRzX3NhbXBsZSRgR3Jvc3MgdmFsdWVgICogRml4ZWRfYXNzZXRzX3NhbXBsZSRgRGVwcmVjaWF0aW9uIHJhdGVgCgpjYWxjdWxhdGVkX2RlcHJlY2lhdGlvbiA8LSBzdW0oRml4ZWRfYXNzZXRzX3NhbXBsZSRDYWx1bGF0ZWRfc2FtcGxlX2RlcHJlY2lhdGlvbikKYGBgCgp0aGVuLCBjYWxjdWxhdGUgdGhlIG9yaWdpbmFsIGRlcHJlY2lhdGlvbiBmb3IgZWFjaCBpdGVtOgpgYGB7cn0Kb3JpZ2luYWxfZGVwcmVjaWF0aW9uIDwtIHN1bShGaXhlZF9hc3NldHNfc2FtcGxlJERlcHJlY2lhdGlvbikKYGBgCgp0aGVuLCBsZXQncyBjaGVjayBpZiB0aGV5IGRpZmZlcjoKCmBgYHtyfQpkaWZmZXJlbmNlIDwtIGNhbGN1bGF0ZWRfZGVwcmVjaWF0aW9uIC0gb3JpZ2luYWxfZGVwcmVjaWF0aW9uCgpkaWZmZXJlbmNlCmBgYAp0aGUgZGlmZmVyZW5jZSBpcyB6ZXJvIHdoaWNoIGluZGljYXRlcyB0aGF0IHRoZSBjdXJyZW50IHllYXIgZGVwcmVjaWF0aW9uIGZvciB0aGUgc2FtcGxlIGlzIGNhbGN1bGF0ZWQgY29ycmVjdGx5LiAKCk5leHQsIGxldCdzIGNhbGN1bGF0ZSB0aGUgYWNjdW11bGF0ZWQgZGVwcmVjaWF0aW9uCgpmaXJzdCwgbGV0J3MgYWRqdXN0IG5ldyBjb2x1bW4gdG8gZml4ZWQgYXNzZXQgc2FtcGxlIHdoZXJlIHRoZSBsYXN0IHllYXIgb2YgZnkgaXMgaW5jbHVkZWQ6CmBgYHtyfQpGaXhlZF9hc3NldHNfc2FtcGxlJGN1cnJlbnRfZGF0ZSA8LSBhcy5EYXRlKCcyMDIyLTEyLTMxJywgZm9ybWF0ID0gJyVZLSVtLSVkJykKYGBgCgp0aGVuLCBjYWxjdWxhdGUgdGhlIHllYXJzIGZyb20gdGhlIHB1cmNoYXNlIGRhdGUgb2YgaXRlbSB0byB0aGUgZW5kIG9mIGN1cnJlbnQgZnk6CgpgYGB7cn0KRml4ZWRfYXNzZXRzX3NhbXBsZSR5ZWFyc19zaW5jZV9wdXJjaGFzZSA8LSBhcy5udW1lcmljKGRpZmZ0aW1lKEZpeGVkX2Fzc2V0c19zYW1wbGUkY3VycmVudF9kYXRlLCBGaXhlZF9hc3NldHNfc2FtcGxlJERhdGUsIHVuaXRzID0gIndlZWtzIikpIC8gNTIuMjUKYGBgCgp0aGVuIGNhbHVsYXRlIHRoZSBmaXhlZCBhc3NldCBzYW1wbGUgeWVhcmx5IGRlcHJlY2lhdGlvbgpgYGB7cn0KRml4ZWRfYXNzZXRzX3NhbXBsZSR5ZWFybHlfZGVwcmVjaWF0aW9uIDwtIChGaXhlZF9hc3NldHNfc2FtcGxlJGBHcm9zcyB2YWx1ZWArIEZpeGVkX2Fzc2V0c19zYW1wbGUkRGVwcmVjaWF0aW9uKSAqIEZpeGVkX2Fzc2V0c19zYW1wbGUkYERlcHJlY2lhdGlvbiByYXRlYApgYGAKCnRoZW4sIGxldCdzIGZpbmlzaCB0aGUgYWNjLmRlcHJlY2lhdGlvbiBjYWxjdWxhdGlvbjoKCmBgYHtyfQpGaXhlZF9hc3NldHNfc2FtcGxlJGNhbGN1bGF0ZWRfYWNjdW0uZGVwcmVjaWF0aW9uIDwtIEZpeGVkX2Fzc2V0c19zYW1wbGUkeWVhcnNfc2luY2VfcHVyY2hhc2UgKiBGaXhlZF9hc3NldHNfc2FtcGxlJHllYXJseV9kZXByZWNpYXRpb24KYGBgCgp0aGVuLCBsZXQncyBzdW0gdGhlIHJvd3M6CmBgYHtyfQp0b3RhbF9jYWx1bGF0ZWRfYWNjLmRlcHJlY2lhdGlvbiA8LSBzdW0oRml4ZWRfYXNzZXRzX3NhbXBsZSRjYWxjdWxhdGVkX2FjY3VtLmRlcHJlY2lhdGlvbikKCnRvdGFsX29yaWdpbmFsX2FjYy5kZXByZWNpYXRpb24gPC0gc3VtKEZpeGVkX2Fzc2V0c19zYW1wbGUkQWNjLmRlcHJlY2lhdGlvbikKYGBgCgpsZXQncyBjYWxjdWxhdGUgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBjYWxjdWxhdGlvbiBhbmQgb3JpZ2luYWwgYWNjLmRlcHJlY3RpYXRpb246CmBgYHtyfQphY2MuZGVwcmVjaWF0aW9uX2RpZmZlcmVuY2UgPC0gdG90YWxfY2FsdWxhdGVkX2FjYy5kZXByZWNpYXRpb24gLSB0b3RhbF9vcmlnaW5hbF9hY2MuZGVwcmVjaWF0aW9uCgphY2MuZGVwcmVjaWF0aW9uX2RpZmZlcmVuY2UKYGBgCmFjY29yZGluZyB0byB0aGUgY2FsY3VsYXRpb25zIHRoZSBkaWZmZXJlbmNlIGlzIDc5MDg0MDIgd2hpY2ggaW5kaWNhdGVzIHRoYXQgdGhlcmUgbWlnaHQgYmUgYSBzaWduaWZpY2FudCBlcnJvciByZWdhcmRpbmcgYWNjdW11bGF0ZWQgZGVwcmVjaWF0aW9uIGluIGZpeGVkIGFzc2V0IHJlZ2lzdGVyIG9mIHdoaWNoIGlzIGltcG9ydGFudCB0byBjaGVjayB0aGUgY2FsY3VsYXRpb24gcHJvY2VkdXJlIGFuZCBjb21wYXJlIGl0IHRoZSBleGVjdXRlZCBjYWxjdWxhdGlvbiBkb25lIGZvciB0aGUgc2FtcGxlLiAKCjguIENhbGN1bGF0ZSB0aGUgY29ycmVjdG5lc3Mgb2YgdGhlIGNhbGN1bGF0aW9uIG9mIGludGVyZXN0IG9uIGxpYWJpbGl0aWVzLiBBc3N1bWUgYSByYXRlIG9mIDglIHBhOgoKRmlyc3QsIGxldCdzIGNoZWNrIHRoZSBkZXZlbG9wbWVudCBvZiBpbnRlcmVzdC1iZWFyaW5nIGZpbmFuY2lhbCBsaWFiaWxpdGllcyBhY2NvcmRpbmcgdG8gVEI6CgpsZXQncyBleHRyYWN0IHRoZW0gZnJvbSB0aGUgcmVzdCBvZiB0aGUgVEIgYWNjb3VudHMKYGBge3J9ClRCX2ludGVyZXN0X2JlYXJpbmdfbGlhYmlsaXRpZXMgPC0gVEJfZW4gJT4lIGZpbHRlcihOciAlaW4lIGMoMTcsIDE4KSkKClZpZXcoVEJfaW50ZXJlc3RfYmVhcmluZ19saWFiaWxpdGllcykKYGBgCgpsZXQncyByZWNhbGN1bGF0ZSB0aGUgY2xvc2luZyBiYWxhbmNlIGJhc2VkIG9uIHRoZSBvcCBiYWxhbmNlLCBjcmVkaXQgYW5kIGRlYml0IHR1cm5vdmVyOgoKYGBge3J9ClRCX2ludGVyZXN0X2JlYXJpbmdfbGlhYmlsaXRpZXMkcmVjYWxjdWxhdGVkX2Nsb3NpbmdfYmFsYW5jZSA8LSBUQl9pbnRlcmVzdF9iZWFyaW5nX2xpYWJpbGl0aWVzJGBPcGVuaW5nIEJhbGFuY2VgLSBUQl9pbnRlcmVzdF9iZWFyaW5nX2xpYWJpbGl0aWVzJGBEZWJpdCBib29raW5nc2ArIFRCX2ludGVyZXN0X2JlYXJpbmdfbGlhYmlsaXRpZXMkYENyZWRpdCBib29raW5nc2AKClRCX2ludGVyZXN0X2JlYXJpbmdfbGlhYmlsaXRpZXMkZGlmZmVyZW5jZSA8LSBUQl9pbnRlcmVzdF9iZWFyaW5nX2xpYWJpbGl0aWVzJGBDbG9zaW5nIGJhbGFuY2VgLSBUQl9pbnRlcmVzdF9iZWFyaW5nX2xpYWJpbGl0aWVzJHJlY2FsY3VsYXRlZF9jbG9zaW5nX2JhbGFuY2UKCnN1bShUQl9pbnRlcmVzdF9iZWFyaW5nX2xpYWJpbGl0aWVzJGRpZmZlcmVuY2UpCmBgYAphY2NvcmRpbmcgdG8gcmVjYWxjdWxhdGlvbiwgdGhlIGRpZmZlcmVuY2UgaXMgLTE1MTY4Ljggd2hpY2ggbWVhbnMgdGhhdCB0aGUgY2xvc2luZyBiYWxhbmNlIGluIHRoZSBUQiBpcyAxNTE2OC44IHNtYWxsZXIgdGhhbiB0aGUgcmVjYWxjdWxhdGVkIG9uZS4gVGhpcyBpcyBkdWUgdG8gdGhlIGZhY3QgdGhhdCBvbiBUQiBpdCBsb29rcyBsaWtlIHRoYXQgZGViaXQgYm9va2luZ3MgYXJlIGluY3JlYXNpbmcgdGhlIGxpYWJpbGl0aWVzIGFjY291bnQgYmFsYW5jZSBhbmQgY3JlZGl0IGRlY3JlYXNpbmcgd2hlbiBpdCBzaG91bGQgYmUgb3RoZXIgd2F5IGFyb3VuZC4gTGV0J3MgYXNzdW1lIHRoYXQgdGhlIHJlY2FsY3VsYXRlZCBvbiBpcyBjb3JyZWN0LgoKbGV0J3MgYXNzdW1lIHRoYXQgdGhlIGluY3JlYXNlcyBpbiBpbnRlcmVzdCBiZWFyaW5nIGxpYWJpbGl0aWVzIGhhcyBoYXBwZW5lZCBvbiBhdmVyYWdlLCBpbiB0aGUgbWlkZGxlIG9mIHRoZSB5ZWFyIGFuZCB1c2UgdGhhdCBpbmZvcm1hdGlvbiB0byBjYWxjdWxhdGUgdGhlIGludGVyZXN0IGZvciBsaWFiaWxpdGllcyBvZiB0aGUgZmluYW5jaWFsIHllYXI6CgpgYGB7cn0KaW50ZXJlc3RfZm9yX2Z5X2FjY29yZGluZ19UQiA8LSBzdW0oVEJfaW50ZXJlc3RfYmVhcmluZ19saWFiaWxpdGllcyRgT3BlbmluZyBCYWxhbmNlYCkgKiAwLjA4ICsgKHN1bShUQl9pbnRlcmVzdF9iZWFyaW5nX2xpYWJpbGl0aWVzJHJlY2FsY3VsYXRlZF9jbG9zaW5nX2JhbGFuY2UpIC0gc3VtKFRCX2ludGVyZXN0X2JlYXJpbmdfbGlhYmlsaXRpZXMkYE9wZW5pbmcgQmFsYW5jZWApKSAqICgwLjA4LzIpCgppbnRlcmVzdF9mb3JfZnlfYWNjb3JkaW5nX1RCCmBgYAphY2NvcmRpbmcgdG8gVEIsIHRoZSBpbnRlcmVzdCBmb3IgbGlhYmlsaXRpZXMgc2hvdWxkIGJlIDg1MDkuMDk0CgpsZXQncyBjb21wYXJlIHRoZSByZXN1bHQgdG8gaW50ZXJlc3QgZXhwZW5zZXMgb24gdGhlIFAmTDoKCmBgYHtyfQppbnRlcmVzdF9mb3JfZnlfaW5fUEwgPC0gQ0NfUExfZW4kYEFtb3VudCBhdCB0aGUgZW5kIG9mIGN1cnJlbnQgZmluYW5jaWFsIHllYXJgWzI3XQoKaW50ZXJlc3RfZGlmZmVyZW5jZSA8LSBpbnRlcmVzdF9mb3JfZnlfaW5fUEwgLSBpbnRlcmVzdF9mb3JfZnlfYWNjb3JkaW5nX1RCCgppbnRlcmVzdF9kaWZmZXJlbmNlCmBgYApEaWZmZXJlbmNlIGJldHdlZW4gaW50ZXJlc3QgaW4gUCZMIGFuZCBjYWxjdWxhdGVkIGludGVyZXN0IGlzIC0xMzc0LjA5NCBpbmRpY2F0aW5nIHRoYXQgaW50ZXJlc3QgZm9yIGxpYWJpbGl0aWVzIGluIFAmTCBtaWdodCBiZSB1bmRlcnN0YXRlZC4KCjkuIFdyaXRlIHRoZSBhdWRpdCBwcm9ncmFtIGZvciBwcm92aXNpb25zLgoKMSBVbmRlcnN0YW5kaW5nIGFuZCBkb2N1bWVudGluZyB0aGUgcHJvY2VzcwoKLSBJbnRlcnZpZXcgbWFuYWdlbWVudCBhbmQga2V5IHBlcnNvbm5lbCBpbnZvbHZlZCBpbiB0aGUgcHJvdmlzaW9uIGVzdGltYXRpb24gcHJvY2Vzcy4KCi1PYnRhaW4gYW5kIGRvY3VtZW50IHRoZSBlbnRpdHnigJlzIHBvbGljaWVzIGFuZCBwcm9jZWR1cmVzIGZvciBpZGVudGlmeWluZywgY2FsY3VsYXRpbmcsIGFuZCByZWNvcmRpbmcgcHJvdmlzaW9ucy4KCi1Bc3Nlc3MgdGhlIGRlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gb2Yga2V5IGNvbnRyb2xzIG92ZXIgdGhlIHByb3Zpc2lvbiBwcm9jZXNzLgoKMiBSZXZpZXcgcHJvdmlzaW9uIGVzdGltYXRlcwotVGFrZSB0aGUgVEIgZm9yIHRoZSBwZXJpb2QgYmVpbmcgYXVkaXRlZAoKLUZyb20gdGhlIFRCLCBjaG9vc2UgdGhlIGFjY291bnRzIHRvIHdoaWNoIHByb3Zpc2lvbnMgYXJlIGJvb2tlZC4gCgotQW5hbHl6ZSB0aGUgb3BlbmluZyBiYWxhbmNlIG9mIHRob3NlIGFjY291bnRzIGFuZCBjbG9zaW5nIGJhbGFuY2UgdG8gc2VlIHRoZSBwb3NzaWJsZSBpbmNyZWFzZSBvciBkZWNyZWFzZSBvZiBwcm92aXNpb25zIGZvciB0aGUgRlkuCgotQ29tcGFyZSB0aGF0IHRoZSBvcGVuaW5nIGJhbGFuY2Ugb2YgcHJvdmlzaW9ucyBtYXRjaCB3aXRoIHRoZSBwcm92aXNpb25zIG9uIHRoZSBiYWxhbmNlIHNoZWV0IG9mIHByZXZpb3VzIGZpbmFuY2lhbCB5ZWFyIGFuZCB0aGUgdGhlIGNsb3NpbmcgYmFsYW5jZSBtYXRjaCB3aXRoIEJTIG9mIGN1cnJlbnQgRlkgYW5kIHRoYXQgdGhlIGRpZmZlcmVuY2Ugd2l0aCB0aGUgY2hhbmdlcyBmb3IgcHJvdmlzaW9ucyBvbiBQJkwuCgotQ29tcGFyZSBwcm92aXNpb25zIHdpdGggaW5kdXN0cnkgYmVuY2htYXJrcyBvciBzaW1pbGFyIGVudGl0aWVzLCBpZiBhdmFpbGFibGUuCgozIFRlc3RpbmcgdGhlIGFjY3VyYWN5IGFuZCBjb21wbGV0ZW5lc3MKCi1DYWxjdWxhdGUgZXhwZWN0ZWQgbG9zc2VzIGJhc2VkIG9uIHRoZSBjb3VudGVycGFydCBhZ2luZyBmb3IgYSBzYW1wbGUgb2YgYWNjb3VudHM6IApleHBlY3RlZCBsb3NzZXMgPSBQRCAqIExHRCAqIEVBRAoKLUV4YW1pbmUgbWV0aG9kcyB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgcGFyYW1ldGVycwoKLUNvbXBhcmUgZXhwZWN0ZWQgbG9zc2VzIGFuZCBwcm92aXNpb25zIGZvciBzYW1wbGUgYWNjb3VudHMgdG8gcmVjb25jaWxlIHRoYXQgdGhlIHByb3Zpc2lvbnMgYXJlIGluIGxpbmUgd2l0aCB0aGUgZXhwZWN0ZWQgbG9zc2VzLiAKCi1JbnNwZWN0IHN1cHBvcnRpbmcgZG9jdW1lbnRhdGlvbiwgc3VjaCBhcyBjb250cmFjdHMsIGFncmVlbWVudHMsIG9yIGNvcnJlc3BvbmRlbmNlIHJlbGF0ZWQgdG8gdGhlIHByb3Zpc2lvbnMuCgotQ29uZmlybSBjb21wbGV0ZW5lc3MgYnkgcmV2aWV3aW5nIG1pbnV0ZXMgb2YgYm9hcmQgbWVldGluZ3MsIGxlZ2FsIGNvcnJlc3BvbmRlbmNlLCBhbmQgb3RoZXIgcmVsZXZhbnQgZG9jdW1lbnRzIHRvIGlkZW50aWZ5IHBvdGVudGlhbCBwcm92aXNpb25zIG5vdCByZWNvcmRlZC4KCjQgUmV2aWV3IG9mIFN1YnNlcXVlbnQgRXZlbnRzCgotUmV2aWV3IHN1YnNlcXVlbnQgZXZlbnRzIHVwIHRvIHRoZSBkYXRlIG9mIHRoZSBhdWRpdG9y4oCZcyByZXBvcnQgdG8gaWRlbnRpZnkgYW55IGV2ZW50cyB0aGF0IG1pZ2h0IGFmZmVjdCB0aGUgcHJvdmlzaW9ucy4KCi1WZXJpZnkgd2hldGhlciBhbnkgYWRqdXN0bWVudHMgb3IgZGlzY2xvc3VyZXMgYXJlIG5lY2Vzc2FyeSBiYXNlZCBvbiBzdWJzZXF1ZW50IGV2ZW50cy4KCjUgRGlzY2xvc3VyZXMgaW4gRmluYW5jaWFsIFN0YXRlbWVudHMKCi1FbnN1cmUgdGhhdCBkaXNjbG9zdXJlcyBpbmNsdWRlIGEgZGVzY3JpcHRpb24gb2YgdGhlIG5hdHVyZSBvZiB0aGUgcHJvdmlzaW9uLCB0aGUgdW5jZXJ0YWludGllcyByZWxhdGVkIHRvIHRoZSBhbW91bnQgb3IgdGltaW5nLCBhbmQgdGhlIGV4cGVjdGVkIHRpbWluZyBvZiBhbnkgcmVzdWx0aW5nIG91dGZsb3dzLgoKLUNvbXBhcmUgZGlzY2xvc3VyZXMgd2l0aCB0aGUgcmVxdWlyZW1lbnRzIG9mIHRoZSBhcHBsaWNhYmxlIGZpbmFuY2lhbCByZXBvcnRpbmcgZnJhbWV3b3JrIChlLmcuLCBJRlJTLCBHQUFQKS4KCjYgRmluaXNoIHRoZSBwcm9jZXNzCgotUHJlcGFyZSBhdWRpdCB3b3JraW5nIHBhcGVycyBkZXRhaWxpbmcgdGhlIGF1ZGl0IHByb2NlZHVyZXMgcGVyZm9ybWVkLCBldmlkZW5jZSBvYnRhaW5lZCwgYW5kIGNvbmNsdXNpb25zIHJlYWNoZWQuCgotSW5mb3JtIGFsbCB0aGUgcmVsZXZhbnQgcGFydGllcyBpbmNsdWRpbmcgYXVkaXQgdGVhbSBhbmQgY2xpZW50IGZvciB0aGUgcmVzdWx0cy4gCgotRGlzY3VzcyB3aXRoIHRoZSBtYW5hZ2VtZW50IGFib3V0IHRoZSByZXN1bHRzIGFuZCB3aGV0aGVyIGFueSBjaGFuZ2VzIGFyZSBuZWNlc3NhcnkgYW5kIGhvdyB0aGUgbWFuYWdlbWVudCBpcyBwbGFubmluZyB0byBkbyB0aGVtCgoxMC4gV3JpdGUgYSBnZW5lcmFsIGF1ZGl0IHByb2dyYW0uCgoxIERldGVybWluZSB0aGUgb2JqZWN0aXZlIGZvciB0aGUgYXVkaXQKCjIgQXVkaXQgcGxhbm5pbmcKCjIuMSBVbmRlcnN0YW5kIHRoZSBFbnRpdHkgYW5kIEl0cyBFbnZpcm9ubWVudAoKLU9idGFpbiBiYWNrZ3JvdW5kIGluZm9ybWF0aW9uIGFib3V0IHRoZSBlbnRpdHksIGluY2x1ZGluZyBpdHMgaW5kdXN0cnksIHJlZ3VsYXRvcnkgZW52aXJvbm1lbnQsIGFuZCBrZXkgc3Rha2Vob2xkZXJzLgoKLVJldmlldyBwcmlvciB5ZWFyIGF1ZGl0IGZpbGVzIGFuZCByZXBvcnRzLgoKMi4yIEFzc2VzcyBSaXNrcyBhbmQgRGV0ZXJtaW5lIE1hdGVyaWFsaXR5CgotSWRlbnRpZnkgYW5kIGFzc2VzcyB0aGUgcmlza3Mgb2YgbWF0ZXJpYWwgbWlzc3RhdGVtZW50IGF0IHRoZSBmaW5hbmNpYWwgc3RhdGVtZW50IGFuZCBhc3NlcnRpb24gbGV2ZWxzLgoKLURldGVybWluZSBtYXRlcmlhbGl0eSBmb3IgdGhlIGZpbmFuY2lhbCBzdGF0ZW1lbnRzIGFzIGEgd2hvbGUgYW5kIHBlcmZvcm1hbmNlIG1hdGVyaWFsaXR5LgoKLURvY3VtZW50IHJpc2sgYXNzZXNzbWVudCBhbmQgbWF0ZXJpYWxpdHkgdGhyZXNob2xkcy4KCjIuMyBEZXZlbG9wIEF1ZGl0IFN0cmF0ZWd5IGFuZCBQbGFuCgotRGV2ZWxvcCBhbiBvdmVyYWxsIGF1ZGl0IHN0cmF0ZWd5LCBpbmNsdWRpbmcgdGhlIHNjb3BlLCB0aW1pbmcsIGFuZCBkaXJlY3Rpb24gb2YgdGhlIGF1ZGl0LgoKLVByZXBhcmUgYSBkZXRhaWxlZCBhdWRpdCBwbGFuIG91dGxpbmluZyBzcGVjaWZpYyBhdWRpdCBwcm9jZWR1cmVzIHRvIGJlIHBlcmZvcm1lZC4KCi1BbGxvY2F0ZSBhdWRpdCByZXNvdXJjZXMgYW5kIGFzc2lnbiByZXNwb25zaWJpbGl0aWVzIHRvIHRoZSBhdWRpdCB0ZWFtLgoKMyBJbnRlcm5hbCBDb250cm9scwoKMy4xIEV2YWx1YXRlIERlc2lnbiBhbmQgSW1wbGVtZW50YXRpb24gb2YgSW50ZXJuYWwgQ29udHJvbHMKCi1PYnRhaW4gYW4gdW5kZXJzdGFuZGluZyBvZiB0aGUgaW50ZXJuYWwgY29udHJvbCBzeXN0ZW0sIGluY2x1ZGluZyBjb250cm9sIGFjdGl2aXRpZXMsIHJpc2sgYXNzZXNzbWVudCwgaW5mb3JtYXRpb24gYW5kIGNvbW11bmljYXRpb24sIG1vbml0b3JpbmcsIGFuZCBjb250cm9sIGVudmlyb25tZW50LgoKLUV2YWx1YXRlIHRoZSBkZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIG9mIGtleSBjb250cm9scyByZWxldmFudCB0byB0aGUgYXVkaXQuCgotUGVyZm9ybSB3YWxrdGhyb3VnaHMgdG8gdmVyaWZ5IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBjb250cm9scy4KCjMuMiBUZXN0IE9wZXJhdGluZyBFZmZlY3RpdmVuZXNzIG9mIENvbnRyb2xzCgotU2VsZWN0IGEgc2FtcGxlIG9mIHRyYW5zYWN0aW9ucyBhbmQgdGVzdCB0aGUgb3BlcmF0aW5nIGVmZmVjdGl2ZW5lc3Mgb2Yga2V5IGNvbnRyb2xzLgoKLURvY3VtZW50IHRoZSByZXN1bHRzIG9mIGNvbnRyb2wgdGVzdGluZyBhbmQgYXNzZXNzIHdoZXRoZXIgY29udHJvbHMgYXJlIG9wZXJhdGluZyBlZmZlY3RpdmVseS4KCi1Nb2RpZnkgdGhlIG5hdHVyZSwgdGltaW5nLCBhbmQgZXh0ZW50IG9mIHN1YnN0YW50aXZlIHByb2NlZHVyZXMgYmFzZWQgb24gY29udHJvbCB0ZXN0aW5nIHJlc3VsdHMuCgo0IFN1YnN0YW50aXZlIFByb2NlZHVyZXMKCjQuMSBDYXNoIGFuZCBCYW5rCgotUGVyZm9ybSBiYW5rIHJlY29uY2lsaWF0aW9ucy4KCi1Db25maXJtIGJhbmsgYmFsYW5jZXMgYW5kIGxvYW5zIHdpdGggZmluYW5jaWFsIGluc3RpdHV0aW9ucy4KCi1UZXN0IGNhc2ggdHJhbnNhY3Rpb25zIGZvciBhY2N1cmFjeSBhbmQgY29tcGxldGVuZXNzLgoKNC4yLiBSZWNlaXZhYmxlcwoKLUNvbmZpcm0gYWNjb3VudHMgcmVjZWl2YWJsZSB3aXRoIGN1c3RvbWVycy4KCi1SZXZpZXcgc3Vic2VxdWVudCByZWNlaXB0cyBmb3IgY29sbGVjdGFiaWxpdHkuCgotQW5hbHl6ZSBhZ2luZyBvZiByZWNlaXZhYmxlcyBhbmQgZXZhbHVhdGUgYWxsb3dhbmNlIGZvciBkb3VidGZ1bCBhY2NvdW50cy4KCjQuMy5JbnZlbnRvcnkKCi1PYnNlcnZlIHBoeXNpY2FsIGludmVudG9yeSBjb3VudC4KCi1UZXN0IGludmVudG9yeSB2YWx1YXRpb24gYW5kIGNvc3RpbmcgbWV0aG9kcy4KCi1FdmFsdWF0ZSBpbnZlbnRvcnkgb2Jzb2xlc2NlbmNlIGFuZCB3cml0ZS1kb3ducy4KCjQuNC4gUHJvcGVydHksIFBsYW50LCBhbmQgRXF1aXBtZW50CgotVmVyaWZ5IGV4aXN0ZW5jZSB0aHJvdWdoIHBoeXNpY2FsIGluc3BlY3Rpb24uCgotVGVzdCBhZGRpdGlvbnMgYW5kIGRpc3Bvc2FscyBmb3IgcHJvcGVyIGF1dGhvcml6YXRpb24gYW5kIHJlY29yZGluZy4KCi1SZXZpZXcgZGVwcmVjaWF0aW9uIGNhbGN1bGF0aW9ucyBhbmQgYXNzZXNzIHVzZWZ1bCBsaXZlcy4KCjQuNSBMaWFiaWxpdGllcwoKLUNvbmZpcm0gYWNjb3VudHMgcGF5YWJsZSB3aXRoIHN1cHBsaWVycy4KCi1SZXZpZXcgc3Vic2VxdWVudCBwYXltZW50cyBhbmQgZGlzYnVyc2VtZW50cy4KCi1UZXN0IGFjY3J1YWxzIGFuZCBwcm92aXNpb25zIGZvciBjb21wbGV0ZW5lc3MgYW5kIGFjY3VyYWN5LgoKNC42LiBSZXZlbnVlIGFuZCBFeHBlbnNlcwoKLVRlc3QgcmV2ZW51ZSByZWNvZ25pdGlvbiBwb2xpY2llcyBmb3IgY29tcGxpYW5jZSB3aXRoIGFjY291bnRpbmcgc3RhbmRhcmRzLgoKLVBlcmZvcm0gYW5hbHl0aWNhbCBwcm9jZWR1cmVzIG9uIHJldmVudWUgYW5kIGV4cGVuc2VzLgoKLVN1YnN0YW50aWF0ZSBzaWduaWZpY2FudCBleHBlbnNlcyBhbmQgcmV2aWV3IHN1cHBvcnRpbmcgZG9jdW1lbnRhdGlvbi4KCjUgQW5hbHl0aWNhbCBQcm9jZWR1cmVzCgo1LjEgUGVyZm9ybSBBbmFseXRpY2FsIFByb2NlZHVyZXMKCi1Db25kdWN0IHJhdGlvIGFuYWx5c2lzIGFuZCB0cmVuZCBhbmFseXNpcy4KCi1Db21wYXJlIGN1cnJlbnQgeWVhciBmaW5hbmNpYWwgZGF0YSB3aXRoIHByaW9yIHBlcmlvZHMgYW5kIGluZHVzdHJ5IGJlbmNobWFya3MuCgotSW52ZXN0aWdhdGUgc2lnbmlmaWNhbnQgdmFyaWFuY2VzIGFuZCB1bnVzdWFsIHRyYW5zYWN0aW9ucy4KCjYgUmV2aWV3IGFuZCBSZXBvcnRpbmcKCjYuMS4gUmV2aWV3IEZpbmFuY2lhbCBTdGF0ZW1lbnRzCgotUmV2aWV3IHRoZSBkcmFmdCBmaW5hbmNpYWwgc3RhdGVtZW50cyBmb3IgY29tcGxpYW5jZSB3aXRoIHRoZSBhcHBsaWNhYmxlIGZpbmFuY2lhbCByZXBvcnRpbmcgZnJhbWV3b3JrLgoKLUVuc3VyZSB0aGF0IGRpc2Nsb3N1cmVzIGFyZSBjb21wbGV0ZSBhbmQgYWNjdXJhdGUuCgo2LjIuIE9idGFpbiBNYW5hZ2VtZW50IFJlcHJlc2VudGF0aW9ucwoKLU9idGFpbiBhIG1hbmFnZW1lbnQgcmVwcmVzZW50YXRpb24gbGV0dGVyIGNvdmVyaW5nIHNpZ25pZmljYW50IGFzc2VydGlvbnMgbWFkZSBkdXJpbmcgdGhlIGF1ZGl0LgoKLURvY3VtZW50IHJlcHJlc2VudGF0aW9ucyBvYnRhaW5lZCBhbmQgZXZhbHVhdGUgdGhlaXIgaW1wYWN0IG9uIHRoZSBhdWRpdC4KCjYuMy4gRmluYWxpemUgQXVkaXQgRG9jdW1lbnRhdGlvbgoKLUNvbXBsZXRlIGFuZCByZXZpZXcgYWxsIGF1ZGl0IHdvcmtpbmcgcGFwZXJzLgoKLUVuc3VyZSB0aGF0IGFsbCBhdWRpdCBldmlkZW5jZSBpcyBhcHByb3ByaWF0ZWx5IGRvY3VtZW50ZWQgYW5kIHN1cHBvcnRzIHRoZSBhdWRpdCBvcGluaW9uLgoKNi40LiBJc3N1ZSBBdWRpdCBSZXBvcnQKCi1QcmVwYXJlIHRoZSBkcmFmdCBhdWRpdCByZXBvcnQuCgotRGlzY3VzcyBhdWRpdCBmaW5kaW5ncyBhbmQgY29uY2x1c2lvbnMgd2l0aCBtYW5hZ2VtZW50IGFuZCB0aG9zZSBjaGFyZ2VkIHdpdGggZ292ZXJuYW5jZS4KCi1Jc3N1ZSB0aGUgZmluYWwgYXVkaXQgcmVwb3J0IGV4cHJlc3NpbmcgdGhlIGF1ZGl0IG9waW5pb24uCg==