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")
- 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
- 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
- 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.
- 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.
- 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.
- 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.
- 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.
- Write the audit program for provisions.
1 Understanding and documenting the process
- Interview management and key personnel involved in the provision
estimation 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
- 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==