2 Data collection

2.2 Survey of Income and Program Participation (SIPP) Datasets

2.2.2 Read SIPP 2014 Panel Data

# `labels.csv` generated by manually copying and cleaning `Table of Contents` of `SIPP Public Use Metadata Report`:
# `https://www2.census.gov/programs-surveys/sipp/data/datasets/2014/w4/2014SIPP_W4_Metadata_AllSections.pdf`
labels = read.csv2('labels.csv')

# Select fields that we are interested in
col_sel = c(
  'ssuid', # Sample unit identifier. Basically household ID
  'shhadid', # Household address ID
  'pnum', # Person number.
  'wpfinwgt', # Final person weight
  'erelrpe', # Need to calculate household weight
  'monthcode', 
  'swave',
  'eresidenceid',
  'esex',
  'tage',
  'tprval', # Property value of primary residence
  'tprloanamt', # Principal owed on the first three mortgages and loans against the primary residence
  'tirakeoval',# Value of IRA and KEOGH accounts
  'tthr401val', # Value of 401k, 403b, 503b, and Thrift Savings Plan accounts
  'elife_type', # Type of life insurance policy owned, 1 Term, 2 Whole, 3 Both
  'tlife_cval',
  'tlife_fval',
  'tlifeamt', # What was the total amount of life insurance payments ... received
  'tsur7amt',
  'tpothinc',
  'thtotinc',
  'totcmdpay',
  'tmdpay'
) %>% union(labels$label[labels$category == 'Asset_Amount'] %>% tolower) %>%
  setdiff(c('tmhloan_num', 'tbus_inv_num')) ## 'tmhloan_num' and 'tbus_inv_num' are not included in all waves (and we don't need them)

time = Sys.time()
wealth16.all <- read_stata('SIPP/pu2014w4.dta', col_select = all_of(col_sel)) %>% distinct
# Use distinct in case of duplicate records
time - Sys.time()

wealth15.all <- read_stata('SIPP/pu2014w3.dta', col_select = all_of(col_sel)) %>% distinct
wealth14.all <- read_stata('SIPP/pu2014w2.dta', col_select = all_of(col_sel)) %>% distinct
wealth13.all <- read_stata('SIPP/pu2014w1.dta', col_select = all_of(col_sel)) %>% distinct

all_wave <- rbind(wealth13.all, wealth14.all, wealth15.all, wealth16.all)

# We only need year-level data, so extract month 12
# https://www2.census.gov/programs-surveys/sipp/Select_approp_wgt_2014SIPPpanel.pdf
all_wave_annual <- all_wave %>% filter(monthcode == 12) %>% select(-monthcode)

# Save intermediary dataset so that we don't need to read all the data each time
save(all_wave_annual, file = 'all_wave_annual.rda')

colmname description
ssuid Sample unit identifier. This identifier is created by scrambling together PSU, S
swave Wave number of interview
erelrpe Household relationship (detailed categories)
wpfinwgt Final person weight
tirakeoval Value of IRA and KEOGH accounts as of the last day of the reference period.
tthr401val Value of 401k, 403b, 503b, and Thrift Savings Plan accounts as of the last day o
tlife_fval Face value of life insurance policies as of the last day of the reference period
tlife_cval Cash value of life insurance policies as of the last day of the reference period
tannval Value of equity in annuities as of the last day of the reference period.
tinc_bank Person-level sum of income earned over the reference period from interest-earnin
tval_bank Person-level sum of value of assets held at financial institutions (TJSICHKVAL,
tinc_stmf Person-level sum of income earned over the reference period from stocks and mutu
tval_stmf Person-level sum of value of stocks and mutual funds (TJSSTVAL, TJOSTVAL, TOSTVA
tinc_bond Person-level sum of income earned over the reference period from other interest-
tval_bond Person-level sum of value of other interest-earning assets (TJSGOVSVAL TJOGOVSVA
tinc_rent Person-level sum of net income from rental properties (TJSRPNETINC, TJORPNETINC,
tval_rent Person-level sum of value of rental properties (TJSRPVAL, TJORPVAL, TORPVAL).
teq_rent Person-level sum of equity in rental properties (TVAL_RENT, -TDEBT_RENT).
tval_re Person-level sum of value of other real estate (TJSREVAL, TJOREVAL, TOREVAL).
teq_re Person-level sum of equity in other real estate (TVAL_RE, -TDEBT_RE).
tinc_oth Person-level sum of income earned over the reference period from other assets (T
tval_oth Person-level sum of value of other assets (TOINVVAL, TANNVAL, TTRVAL, TLIFE_CVAL
tinc_ast Person-level sum of income earned over the reference period from all assets (TIN
tval_ret Person-level sum of value of retirement accounts (TTHR401VAL, TIRAKEOVAL).
tval_bus Person-level sum of value of businesses in which the person owns a share (TBSI(i
teq_bus Person-level sum of equity in businesses (TVAL_BUS, -TDEBT_BUS).
tval_home Person-level sum of value of primary residence (either TPROPVAL or TMHVAL) in wh
teq_home Person-level sum of equity in primary residence (TVAL_HOME -TDEBT_HOME)
tval_veh Person-level sum of value of all vehicles in which the person owns a share (as i
teq_veh Person-level sum of equity in vehicles (TVAL_VEH, -TDEBT_VEH).
tval_esav Person-level sum of value of educational savings accounts (TESAV(i)VAL for i=1,2
tval_rmu Person-level sum of rent, mortgage, and utility payments in December of the refe
tval_ast Person-level sum of all asset values (TVAL_BANK, TVAL_STMF, TVAL_BOND, TVAL_RENT
tnetworth Person-level net worth (TVAL_AST, -TDEBT_AST).

2.3 American Council of Life Insurers (ACLI) data

2.3.2 Join two ACLI data tables

2.4 National Association of Insurance Commissioners (NAIC) data

2.4.1 Read NAIC data from S&P Global Market Intelligence (2020)

# Data manually downloaded from `Financials, U.S. Life Statutory, NAIC Format`

# `Life Industry | LIFE ANALYSIS OF OPERATIONS BY LOB (PG. 6)`
NAICsurrender = read.csv2('surrender.csv') %>% as_tibble %>%
  filter(type %in% c('indl', 'ordinary', 'credit', 'group')) %>%
  gather(year, surrender_benefit, Y1996:Y2019) %>%
  mutate(surrender_benefit = as.numeric(surrender_benefit))

# Extracted field: Surrender Benefits, Withdrawals for Life Contracts ($000)
# Surrender benefits and withdrawals for life contracts includes all surrender 
# or other withdrawal benefit amounts incurred in connection with contract provisions for surrender or withdrawal.
# Excludes premium and annuity considerations for life contracts returned, 
# withdrawals on deposit-type contracts, 
# and amounts transferred to premium and annuity considerations,
# separate account or amounts redeposited.


# `Life Industry | LIFE EXHIBIT OF LIFE INSURANCE (PG. 25)`
NAICexhibits <- read.csv2('lifeexhibits.csv') %>% 
  as_tibble %>% 
  filter((nchar(category) > 1) & grepl('Lapsed|Surrendered', category)) %>%
  mutate_at(vars(paste0('Y', 1996:2019)), as.numeric)

NAICexhibits$category %<>% gsub('Policy & Cert', 'Policies', .)
NAICexhibits$category %<>% gsub('Certificates', 'Policies', .)

NAICexhibits <- NAICexhibits %>%
  group_by(type, category) %>%
  summarise_all(sum)

NAICexhibits <-  NAICexhibits %>% 
  gather(year, value, Y1996:Y2019) %>% 
  spread(category,value) %>%
  rename(
    lapse_face = `Insurance Lost: Lapsed`, 
    surrender_face = `Insurance Lost: Surrendered`,
    lapse_count = `Policies Lost: Lapsed`,
    surrender_count = `Policies Lost: Surrendered`) %>%
  mutate(
    terminated_face = lapse_face + surrender_face,
    terminated_count = lapse_count + surrender_count)

# Extracted field 1: Insurance Lost: Surrendered ($000)
# Surrender reports the cancellation from in force of the face amounts 
# (or adjusted amounts of insurance) 
# for policies that were surrendered by the owners for their cash value,
# or where a policy loan indebtedness 
# (loan principal plus accrued interest) 
# reached or exceeded the reserve value causing termination of insurance coverage.

# # Extracted field 2: Insurance Lost: Lapsed ($000)
# Lapse reports cancellation from in force of insurance without nonforfeiture provisions as the result of nonpayment of premiums prior to the normal expiration date of such insurance coverage.

2.4.2 Join two NAIC data tables

2.5 Life Insurance Marketing and Research Association (LIMRA) data

2.5.1 Read LIMRA data from LIMRA (2016)

2.6 National Health Expenditure (NHE) data

2.6.1 Read NHE data from U.S. Centers for Medicare & Medicaid Services (2019)

2.7 Federal Reserve data

2.7.1 Read Federal Reserve data from Board of Governors of the Federal Reserve System (US) (2020)

3 Data analysis

3.3 Life Insurance ownership at household level

3.5 Individual’s life Insurance value versus 401k value

person_data_bycash <- all_wave_annual[, c(
  'swave', 'wpfinwgt', 'tannval', 'tirakeoval', 'tthr401val', 'tlife_cval', 'tlife_fval',
  person_label$colmname)] %>%
  group_by(swave, havecashvalue = is.finite(tlife_cval)) %>% # Differentiate between the universe with cash value and the one without
  summarise_all(list(
    ~sum(., na.rm = T),
    ~weighted.sum(.,wpfinwgt)
  )) %>% 
  select(-wpfinwgt_weighted.sum) %>%
  mutate(cashratio = tlife_cval_weighted.sum/tlife_fval_weighted.sum) # Calculate cash_value:face_falue ratio by group (with ot without cash value)

person_data = person_data_bycash %>% 
  select(-c(havecashvalue,cashratio)) %>%
  group_by(swave) %>% 
  summarise_all(sum) %>%
  mutate(cashratio = tlife_cval_weighted.sum/tlife_fval_weighted.sum) # Calculate aggregate cash_value:face_falue ratio

swave_year = tibble(swave = as.numeric(1:4), year = 2013:2016)

ACLIdata = ACLIdata_all %>% 
  inner_join(swave_year) %>%
  full_join(person_data[, c('swave', 'cashratio')]) %>% # Add aggregate cash_value:face_falue ratio to the ACLI data
  mutate(evmultiplier = reserveratio/cashratio) # Calculate aggregate reserve:cash_value ratio


terminated_ins_ordind = NAICdata_all %>%
  full_join(swave_year) %>%
  filter(is.finite(swave) & (type %in% c('ordind'))) %>%
  select(-type) %>%
  full_join(person_data[, c('swave', 'cashratio')]) %>%
  mutate(
    surbenmultiplier = ben_ter_ratio/cashratio
  ) # Calculate aggregate surrender_benefit:cash_value ratio


person_with_cv <- person_data_bycash %>%
  filter(havecashvalue == T) %>% # Examine only the universe with cash value
  select(swave,
         wpfinwgt_sum, tthr401val_weighted.sum, tlife_cval_weighted.sum, tlife_fval_weighted.sum) %>%
  full_join(ACLIdata %>% filter(type == 'ordind') %>% select(swave, evmultiplier)) %>%
  full_join(terminated_ins_ordind) %>%
  mutate(
    meanfv = tlife_fval_weighted.sum/wpfinwgt_sum, # Mean face value life insurance
    meancv = tlife_cval_weighted.sum/wpfinwgt_sum, # Mean cash value life insurance
    meanev = meancv * evmultiplier, # Mean economic value life insurance
    meansb = meancv * surbenmultiplier, # Mean surrender benefit life insurance
    mean401k = tthr401val_weighted.sum/wpfinwgt_sum, # Mean 401k account value
    cashratio = tlife_cval_weighted.sum/tlife_fval_weighted.sum
  ) %>% 
  ungroup 

EVvs401 <- person_with_cv %>% 
  select(swave, meancv, meanev, meansb, mean401k, meanfv)

References

American Council of Life Insurers. 2019. “Life Insurers Fact Book.” https://www.acli.com/-/media/ACLI/Files/Fact-Books-Public/2019FLifeInsurersFactBook.ashx.

Board of Governors of the Federal Reserve System (US). 2020. “Households; Owner-Occupied Real Estate Including Vacant Land and Mobile Homes at Market Value, Market Value Levels.” https://fred.stlouisfed.org/series/HOOREVLMHMV.

Federal Reserve Board. 2018. “Survey of Consumer Finances (SCF).” https://www.federalreserve.gov/econres/scfindex.htm.

S&P Global Market Intelligence. 2020. “U.S. Life Industry Briefing Book.” https://platform.marketintelligence.spglobal.com/.

US Census Bureau. 2019. “Survey of Income and Program Participation Datasets 2014 Panel.” https://www.census.gov/programs-surveys/sipp/data/datasets.2014.html.

U.S. Centers for Medicare & Medicaid Services. 2019. “National Health Expenditure Data: Historical.” https://www.cms.gov/Research-Statistics-Data-and-Systems/Statistics-Trends-and-Reports/NationalHealthExpendData/NationalHealthAccountsHistorical.

LS0tCnRpdGxlOiAiVW5sb2NraW5nIHRoZSBWYWx1ZSBvZiBhIExpZmUgaW4gdGhlIFRpbWUgb2YgQ09WSUQtMTkiCmF1dGhvcjogIkFsZXhhbmRlciBCcmF1biwgTGF1cmVuIEguIENvaGVuLCBKaWFodWEgWHUiCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVCICVkLCAlWScpYCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBmaWdfY2FwdGlvbjogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGhpZ2hsaWdodDogdGFuZ28KICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBmaWdfY2FwdGlvbjogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OiB5ZXMKICB3b3JkX2RvY3VtZW50OgogICAgZmlnX2NhcHRpb246IHllcwogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgpsaW5rLWNpdGF0aW9uczogeWVzCmJpYmxpb2dyYXBoeTogbGlmZXNldHRsZW1lbnQuYmliCnN1YnRpdGxlOiBTdXBwbGVtZW50YXJ5IE1hdGVyaWFsCmJpYmxpby1zdHlsZTogYXBlbGlrZQotLS0KCiMgQmFzaWMgc2V0LXVwCgpgYGB7ciBzZXR1cCwgZWNobyA9IFQsIGVycm9yID0gRiwgY2FjaGUgPSBGLCBtZXNzYWdlID0gRiwgd2FybmluZyA9IEZ9CiMgTG9hZCBsaWJhcmllcwpsaWJyYXJ5KGRhdGEudGFibGUpCmxpYnJhcnkoZm9yZWlnbikKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeShyZWFkc3RhdGExMykKbGlicmFyeShoYXZlbikKbGlicmFyeSh0aWJibGUpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHJlc2hhcGUyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoYWxmcmVkKQpsaWJyYXJ5KGxvZG93bikKbGlicmFyeShzdXJ2ZXkpCmxpYnJhcnkobWl0b29scykKbGlicmFyeShrbml0cikgIyBmb3IgYG9wdHNfY2h1bmskc2V0YApsaWJyYXJ5KFIudXRpbHMpICMgZm9yIGBndW56aXBgCgojIyBHZW5lcmFsIHNldHRpbmdzIGZvciBjb2RlIGNodW5rcwpvcHRzX2NodW5rJHNldCgjZGV2PSd0aWt6JywgCiAgICAgICAgICAgICAgIGZpZy5wYXRoID0gJy4vZmlndXJlLycsIAogICAgICAgICAgICAgICBlY2hvID0gVCwKICAgICAgICAgICAgICAgZXJyb3IgPSBGLCBjYWNoZSA9IEYsIG1lc3NhZ2UgPSBGLCB3YXJuaW5nID0gRgogICAgICAgICAgICAgICAjICwKICAgICAgICAgICAgICAgIyByZXN1bHRzPSdoaWRlJywKICAgICAgICAgICAgICAgIyBhdXRvZGVwPVQsCiAgICAgICAgICAgICAgICMgZmlnLmhlaWdodD02CiAgICAgICAgICAgICAgICkKCm9wdGlvbnMoc3RyaW5nc0FzRmFjdG9ycyA9IEYpCgpvd25mcmFjdCA9IGZ1bmN0aW9uKHgsIHd0KXsKICBzdW0od3RbeCE9MF0pL3N1bSh3dCkKfQoKd2VpZ2h0ZWQuc3VtID0gZnVuY3Rpb24oeCwgd3QpewogIHN1bSh4Knd0LCBuYS5ybSA9IFQpCn0KYGBgCgojIERhdGEgY29sbGVjdGlvbgoKIyMgU3VydmV5IG9mIENvbnN1bWVyIEZpbmFuY2VzIChTQ0YpIGRhdGEKCiMjIyBEb3dubG9hZCBTQ0YgZGF0YSBmcm9tIEBGZWRlcmFsUmVzZXJ2ZUJvYXJkMjAxOAoKYGBge3IgR2V0X1NDRl9kYXRhLCBldmFsID0gRn0KIyBEb3dubG9hZCBhbGwgU0NGIGRhdGEgaW50byBkaXJlY3RvcnkgYFNDRmAKIyBJbnN0cnVjdGlvbnM6IGh0dHA6Ly9hc2RmcmVlLmNvbS9zdXJ2ZXktb2YtY29uc3VtZXItZmluYW5jZXMtc2NmLmh0bWwKbG9kb3duKCdzY2YnLCBvdXRwdXRfZGlyID0gJ1NDRicpICMgT25seSBuZWVkcyB0byBiZSBydW4gb25jZQpgYGAKCiMjIyBSZWFkIFNDRiBkYXRhCgpgYGB7ciBSZWFkX1NDRl9kYXRhLCBldmFsID0gVH0KIyBSZWFkIG9ubHkgMjAxNiBTQ0YgZGF0YQpzY2ZfaW1wIDwtIHJlYWRSRFMoJ1NDRi9zY2YgMjAxNi5yZHMnKQpzY2ZfcncgPC0gcmVhZFJEUygnU0NGL3NjZiAyMDE2IHJ3LnJkcycpCgpzY2ZfZGVzaWduIDwtIAogIHN2cmVwZGVzaWduKCAKICAgIHdlaWdodHMgPSB+d2d0LCAKICAgIHJlcHdlaWdodHMgPSBzY2ZfcndbLCAtMV0gLCAKICAgIGRhdGEgPSBpbXB1dGF0aW9uTGlzdChzY2ZfaW1wKSAsIAogICAgc2NhbGUgPSAxICwKICAgIHJzY2FsZXMgPSByZXAoIDEgLyA5OTgsIDk5OSkgLAogICAgbXNlID0gRiwKICAgIHR5cGUgPSAnb3RoZXInLAogICAgY29tYmluZWQud2VpZ2h0cyA9IFQKICApCmBgYAoKCiMjIFN1cnZleSBvZiBJbmNvbWUgYW5kIFByb2dyYW0gUGFydGljaXBhdGlvbiAoU0lQUCkgRGF0YXNldHMKCiMjIyBEb3dubG9hZCBTSVBQIDIwMTQgUGFuZWwgRGF0YSBmcm9tIEBVU0NlbnN1c0J1cmVhdTIwMTkKCmBgYHtyIEdldF9TSVBQX2RhdGEsIGV2YWwgPSBGfQojIEEgc2ltcGxlIGZ1bmN0aW9uIHRvIGRvd25sb2FkIGFuZCB1bnppcCBTSVBQIGRhdGEKZG93bmxvYWRfc2lwcCA8LSBmdW5jdGlvbih3YXZlKXsKICBmaWxlX25hbWUgPC0gcGFzdGUwKCdwdTIwMTR3Jyx3YXZlLCcuZHRhJykKICBnemlwX2ZpbGUgPC0gcGFzdGUwKGZpbGVfbmFtZSwgJy5neicpCiAgCiAgIyBEb3dubG9hZCBhbGwgU0lQUCBkYXRhIGludG8gZGlyZWN0b3J5IGBTSVBQYAogIGRlc3RfZmlsZSA8LSBwYXN0ZTAoJy4vU0lQUC8nLGd6aXBfZmlsZSkKICAKICBkb3dubG9hZC5maWxlKAogICAgdXJsID0gcGFzdGUwKCdodHRwczovL3d3dzIuY2Vuc3VzLmdvdi9wcm9ncmFtcy1zdXJ2ZXlzL3NpcHAvZGF0YS9kYXRhc2V0cy8yMDE0L3cnLCB3YXZlLCAnLycsIGd6aXBfZmlsZSksCiAgICBkZXN0ZmlsZSA9IGRlc3RfZmlsZQogICAgKQogIAogIGd1bnppcChkZXN0X2ZpbGUpCiAgCiAgIyBwcmludCB1bmNvbXByZXNzZWQgZmlsZSBzaXplCiAgcHJpbnQoCiAgICBwYXN0ZShmaWxlX25hbWUsICdzaXplOicsIHJvdW5kKGZpbGUuc2l6ZShmaWxlX25hbWUpLzFlOSksICdHJykKICApCn0KCgpkb3dubG9hZF9zaXBwKDQpICMgRG93bmxvYWQgYW5kIHVuemlwIHdhdmUgNCBkYXRhICh5ZWFyIDIwMTYpCmRvd25sb2FkX3NpcHAoMykgIyBEb3dubG9hZCBhbmQgdW56aXAgd2F2ZSAzIGRhdGEgKHllYXIgMjAxNSkKZG93bmxvYWRfc2lwcCgyKSAjIERvd25sb2FkIGFuZCB1bnppcCB3YXZlIDIgZGF0YSAoeWVhciAyMDE0KQpkb3dubG9hZF9zaXBwKDEpICMgRG93bmxvYWQgYW5kIHVuemlwIHdhdmUgMSBkYXRhICh5ZWFyIDIwMTMpCmBgYAoKIyMjIFJlYWQgU0lQUCAyMDE0IFBhbmVsIERhdGEKCmBgYHtyIFJlYWRfQ2Vuc3VzX0RhdGEsIGV2YWwgPSBGfQojIGBsYWJlbHMuY3N2YCBnZW5lcmF0ZWQgYnkgbWFudWFsbHkgY29weWluZyBhbmQgY2xlYW5pbmcgYFRhYmxlIG9mIENvbnRlbnRzYCBvZiBgU0lQUCBQdWJsaWMgVXNlIE1ldGFkYXRhIFJlcG9ydGA6CiMgYGh0dHBzOi8vd3d3Mi5jZW5zdXMuZ292L3Byb2dyYW1zLXN1cnZleXMvc2lwcC9kYXRhL2RhdGFzZXRzLzIwMTQvdzQvMjAxNFNJUFBfVzRfTWV0YWRhdGFfQWxsU2VjdGlvbnMucGRmYApsYWJlbHMgPSByZWFkLmNzdjIoJ2xhYmVscy5jc3YnKQoKIyBTZWxlY3QgZmllbGRzIHRoYXQgd2UgYXJlIGludGVyZXN0ZWQgaW4KY29sX3NlbCA9IGMoCiAgJ3NzdWlkJywgIyBTYW1wbGUgdW5pdCBpZGVudGlmaWVyLiBCYXNpY2FsbHkgaG91c2Vob2xkIElECiAgJ3NoaGFkaWQnLCAjIEhvdXNlaG9sZCBhZGRyZXNzIElECiAgJ3BudW0nLCAjIFBlcnNvbiBudW1iZXIuCiAgJ3dwZmlud2d0JywgIyBGaW5hbCBwZXJzb24gd2VpZ2h0CiAgJ2VyZWxycGUnLCAjIE5lZWQgdG8gY2FsY3VsYXRlIGhvdXNlaG9sZCB3ZWlnaHQKICAnbW9udGhjb2RlJywgCiAgJ3N3YXZlJywKICAnZXJlc2lkZW5jZWlkJywKICAnZXNleCcsCiAgJ3RhZ2UnLAogICd0cHJ2YWwnLCAjIFByb3BlcnR5IHZhbHVlIG9mIHByaW1hcnkgcmVzaWRlbmNlCiAgJ3RwcmxvYW5hbXQnLCAjIFByaW5jaXBhbCBvd2VkIG9uIHRoZSBmaXJzdCB0aHJlZSBtb3J0Z2FnZXMgYW5kIGxvYW5zIGFnYWluc3QgdGhlIHByaW1hcnkgcmVzaWRlbmNlCiAgJ3RpcmFrZW92YWwnLCMgVmFsdWUgb2YgSVJBIGFuZCBLRU9HSCBhY2NvdW50cwogICd0dGhyNDAxdmFsJywgIyBWYWx1ZSBvZiA0MDFrLCA0MDNiLCA1MDNiLCBhbmQgVGhyaWZ0IFNhdmluZ3MgUGxhbiBhY2NvdW50cwogICdlbGlmZV90eXBlJywgIyBUeXBlIG9mIGxpZmUgaW5zdXJhbmNlIHBvbGljeSBvd25lZCwgMSBUZXJtLCAyIFdob2xlLCAzIEJvdGgKICAndGxpZmVfY3ZhbCcsCiAgJ3RsaWZlX2Z2YWwnLAogICd0bGlmZWFtdCcsICMgV2hhdCB3YXMgdGhlIHRvdGFsIGFtb3VudCBvZiBsaWZlIGluc3VyYW5jZSBwYXltZW50cyAuLi4gcmVjZWl2ZWQKICAndHN1cjdhbXQnLAogICd0cG90aGluYycsCiAgJ3RodG90aW5jJywKICAndG90Y21kcGF5JywKICAndG1kcGF5JwopICU+JSB1bmlvbihsYWJlbHMkbGFiZWxbbGFiZWxzJGNhdGVnb3J5ID09ICdBc3NldF9BbW91bnQnXSAlPiUgdG9sb3dlcikgJT4lCiAgc2V0ZGlmZihjKCd0bWhsb2FuX251bScsICd0YnVzX2ludl9udW0nKSkgIyMgJ3RtaGxvYW5fbnVtJyBhbmQgJ3RidXNfaW52X251bScgYXJlIG5vdCBpbmNsdWRlZCBpbiBhbGwgd2F2ZXMgKGFuZCB3ZSBkb24ndCBuZWVkIHRoZW0pCgp0aW1lID0gU3lzLnRpbWUoKQp3ZWFsdGgxNi5hbGwgPC0gcmVhZF9zdGF0YSgnU0lQUC9wdTIwMTR3NC5kdGEnLCBjb2xfc2VsZWN0ID0gYWxsX29mKGNvbF9zZWwpKSAlPiUgZGlzdGluY3QKIyBVc2UgZGlzdGluY3QgaW4gY2FzZSBvZiBkdXBsaWNhdGUgcmVjb3Jkcwp0aW1lIC0gU3lzLnRpbWUoKQoKd2VhbHRoMTUuYWxsIDwtIHJlYWRfc3RhdGEoJ1NJUFAvcHUyMDE0dzMuZHRhJywgY29sX3NlbGVjdCA9IGFsbF9vZihjb2xfc2VsKSkgJT4lIGRpc3RpbmN0CndlYWx0aDE0LmFsbCA8LSByZWFkX3N0YXRhKCdTSVBQL3B1MjAxNHcyLmR0YScsIGNvbF9zZWxlY3QgPSBhbGxfb2YoY29sX3NlbCkpICU+JSBkaXN0aW5jdAp3ZWFsdGgxMy5hbGwgPC0gcmVhZF9zdGF0YSgnU0lQUC9wdTIwMTR3MS5kdGEnLCBjb2xfc2VsZWN0ID0gYWxsX29mKGNvbF9zZWwpKSAlPiUgZGlzdGluY3QKCmFsbF93YXZlIDwtIHJiaW5kKHdlYWx0aDEzLmFsbCwgd2VhbHRoMTQuYWxsLCB3ZWFsdGgxNS5hbGwsIHdlYWx0aDE2LmFsbCkKCiMgV2Ugb25seSBuZWVkIHllYXItbGV2ZWwgZGF0YSwgc28gZXh0cmFjdCBtb250aCAxMgojIGh0dHBzOi8vd3d3Mi5jZW5zdXMuZ292L3Byb2dyYW1zLXN1cnZleXMvc2lwcC9TZWxlY3RfYXBwcm9wX3dndF8yMDE0U0lQUHBhbmVsLnBkZgphbGxfd2F2ZV9hbm51YWwgPC0gYWxsX3dhdmUgJT4lIGZpbHRlcihtb250aGNvZGUgPT0gMTIpICU+JSBzZWxlY3QoLW1vbnRoY29kZSkKCiMgU2F2ZSBpbnRlcm1lZGlhcnkgZGF0YXNldCBzbyB0aGF0IHdlIGRvbid0IG5lZWQgdG8gcmVhZCBhbGwgdGhlIGRhdGEgZWFjaCB0aW1lCnNhdmUoYWxsX3dhdmVfYW5udWFsLCBmaWxlID0gJ2FsbF93YXZlX2FubnVhbC5yZGEnKQpgYGAKCmBgYHtyIExvYWRfQ2Vuc3VzX0RhdGEsIGVjaG8gPSBUfQojIExvYWQgZGF0YSBzYXZlZCBmcm9tIHByZXZpb3VzIGNodW5rCmxvYWQoJ2FsbF93YXZlX2FubnVhbC5yZGEnKQogICAgICAgICAKIyBleHRyYWN0IG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIGZpZWxkcyBjb2xsZWN0ZWQKY29sbmFtZV9sYWJlbCA8LSBhbGxfd2F2ZV9hbm51YWwgJT4lIAogIHNhcHBseShmdW5jdGlvbih4KSBhdHRyKHgsJ2xhYmVsJykpICU+JSAKICBhcy5kYXRhLnRhYmxlKGtlZXAucm93bmFtZXMgPSBUKSAlPiUgCiAgc2V0bmFtZXMoYygnY29sbW5hbWUnLCAnZGVzY3JpcHRpb24nKSkKCiMgZXh0cmFjdCBhbGwgUGVyc29uLWxldmVsIGZpZWxkcwpwZXJzb25fbGFiZWwgPC0gY29sbmFtZV9sYWJlbFsKICAhZ3JlcGwoJ2RlYnQnLCBjb2xtbmFtZSwgaWdub3JlLmNhc2UgPSBUKSAmCiAgZ3JlcGwoJ1BlcnNvbi1sZXZlbCAnLCBkZXNjcmlwdGlvbiwgaWdub3JlLmNhc2UgPSBUKQogIF0KCiMgdWx0aW1hdGUgZmllbGRzIHNlbGVjdGVkCmNvbF9zZWxfdWx0IDwtIGMoJ3N3YXZlJywgJ2VyZWxycGUnLCAnc3N1aWQnLCAnd3BmaW53Z3QnLCAndGFubnZhbCcsICd0aXJha2VvdmFsJywgJ3R0aHI0MDF2YWwnLCAndGxpZmVfY3ZhbCcsICd0bGlmZV9mdmFsJykgJT4lCiAgdW5pb24ocGVyc29uX2xhYmVsJGNvbG1uYW1lKQoKIyBmaWVsZCBjb2RlIGFuZCBkZXNjcmlwdGlvbgpjb2xuYW1lX2xhYmVsW2NvbG1uYW1lICVpbiUgY29sX3NlbF91bHRdICU+JSBrYWJsZQoKIyBzdWJzZXQgZGF0YQphbGxfd2F2ZV9hbm51YWwgPC0gYWxsX3dhdmVfYW5udWFsWywgY29sX3NlbF91bHRdCgphbGxfd2F2ZV9hbm51YWwKYGBgCgoKIyMgQW1lcmljYW4gQ291bmNpbCBvZiBMaWZlIEluc3VyZXJzIChBQ0xJKSBkYXRhCgojIyMgUmVhZCBBQ0xJIGRhdGEgZnJvbSBAQW1lcmljYW5Db3VuY2lsb2ZMaWZlSW5zdXJlcnMyMDE5CgpgYGB7ciBMb2FkX0FDTElfRGF0YX0KIyBTaGVldCBgRmFjZUluRm9yY2VgIGdlbmVyYXRlZCBieSBtYW51YWxseSBjb3B5aW5nIAojIFRhYmxlIDcuOSBMaWZlIEluc3VyYW5jZSBpbiBGb3JjZSBpbiB0aGUgVW5pdGVkIFN0YXRlcywgYnkgWWVhciAobWlsbGlvbnMpCmFjbGlfZmFjZSA8LSByZWFkX2V4Y2VsKCdhY2xpLnhsc3gnLCAKICAgICAgICAgICAgICAgICAgICAgICAgc2hlZXQgPSAnRmFjZUluRm9yY2UnLCAKICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gYygidGV4dCIsICJza2lwIiwgIm51bWVyaWMiLCAic2tpcCIsICJudW1lcmljIiwgInNraXAiLCAibnVtZXJpYyIsICJza2lwIiwgIm51bWVyaWMiKQogICAgICAgICAgICAgICAgICAgICAgICApICU+JQogIGFzX3RpYmJsZSAlPiUKICBnYXRoZXIodHlwZSwgZmFjZWluZm9yY2UsIG9yZGluZDp0b3RhbCkKCiMgU2hlZXQgYFJlc2VydmVgIGdlbmVyYXRlZCBieSBtYW51YWxseSBjb3B5aW5nIAojIFRhYmxlIDMuNyBMaWZlIEluc3VyYW5jZSBQb2xpY3kgUmVzZXJ2ZXMsIGJ5IFR5cGUgYW5kIFllYXIgKG1pbGxpb25zKQphY2xpX3Jlc2VydmUgPC0gcmVhZF9leGNlbCgiYWNsaS54bHN4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hlZXQgPSAiUmVzZXJ2ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBjKCJ0ZXh0IiwgIm51bWVyaWMiLCAibnVtZXJpYyIsICJudW1lcmljIiwgIm51bWVyaWMiKQogICAgICAgICAgICAgICAgICAgICAgICAgICApJT4lCiAgYXNfdGliYmxlICU+JQogIGdhdGhlcih0eXBlLCByZXNlcnZlLCBvcmRpbmQ6dG90YWwpCmBgYAoKIyMjIEpvaW4gdHdvIEFDTEkgZGF0YSB0YWJsZXMKCmBgYHtyIEpvaW5fQUNMSV9EYXRhLCBlY2hvID0gVH0KQUNMSWRhdGFfYWxsIDwtIGlubmVyX2pvaW4oYWNsaV9mYWNlLGFjbGlfcmVzZXJ2ZSkgJT4lCiAgbXV0YXRlKHllYXIgPSBhcy5pbnRlZ2VyKGdzdWIoJ1teMC05XScsICcnLFllYXIpKSkgJT4lCiAgc2VsZWN0KC1ZZWFyKSAlPiUgCiAgbXV0YXRlKHJlc2VydmVyYXRpbyA9IHJlc2VydmUvZmFjZWluZm9yY2UpCgoKQUNMSWRhdGFfYWxsICMgZG9sbGFyIGFtb3VudCBpbiBtaWxsaW9uICgkMDAwLDAwMCkKYGBgCgoKIyMgTmF0aW9uYWwgQXNzb2NpYXRpb24gb2YgSW5zdXJhbmNlIENvbW1pc3Npb25lcnMgKE5BSUMpIGRhdGEKCiMjIyBSZWFkIE5BSUMgZGF0YSBmcm9tIEBHbG9iYWxNYXJrZXRJbnRlbGxpZ2VuY2UyMDIwCgpgYGB7ciBMb2FkX05BSUNfRGF0YX0KIyBEYXRhIG1hbnVhbGx5IGRvd25sb2FkZWQgZnJvbSBgRmluYW5jaWFscywgVS5TLiBMaWZlIFN0YXR1dG9yeSwgTkFJQyBGb3JtYXRgCgojIGBMaWZlIEluZHVzdHJ5IHwgTElGRSBBTkFMWVNJUyBPRiBPUEVSQVRJT05TIEJZIExPQiAoUEcuIDYpYApOQUlDc3VycmVuZGVyID0gcmVhZC5jc3YyKCdzdXJyZW5kZXIuY3N2JykgJT4lIGFzX3RpYmJsZSAlPiUKICBmaWx0ZXIodHlwZSAlaW4lIGMoJ2luZGwnLCAnb3JkaW5hcnknLCAnY3JlZGl0JywgJ2dyb3VwJykpICU+JQogIGdhdGhlcih5ZWFyLCBzdXJyZW5kZXJfYmVuZWZpdCwgWTE5OTY6WTIwMTkpICU+JQogIG11dGF0ZShzdXJyZW5kZXJfYmVuZWZpdCA9IGFzLm51bWVyaWMoc3VycmVuZGVyX2JlbmVmaXQpKQoKIyBFeHRyYWN0ZWQgZmllbGQ6IFN1cnJlbmRlciBCZW5lZml0cywgV2l0aGRyYXdhbHMgZm9yIExpZmUgQ29udHJhY3RzICgkMDAwKQojIFN1cnJlbmRlciBiZW5lZml0cyBhbmQgd2l0aGRyYXdhbHMgZm9yIGxpZmUgY29udHJhY3RzIGluY2x1ZGVzIGFsbCBzdXJyZW5kZXIgCiMgb3Igb3RoZXIgd2l0aGRyYXdhbCBiZW5lZml0IGFtb3VudHMgaW5jdXJyZWQgaW4gY29ubmVjdGlvbiB3aXRoIGNvbnRyYWN0IHByb3Zpc2lvbnMgZm9yIHN1cnJlbmRlciBvciB3aXRoZHJhd2FsLgojIEV4Y2x1ZGVzIHByZW1pdW0gYW5kIGFubnVpdHkgY29uc2lkZXJhdGlvbnMgZm9yIGxpZmUgY29udHJhY3RzIHJldHVybmVkLCAKIyB3aXRoZHJhd2FscyBvbiBkZXBvc2l0LXR5cGUgY29udHJhY3RzLCAKIyBhbmQgYW1vdW50cyB0cmFuc2ZlcnJlZCB0byBwcmVtaXVtIGFuZCBhbm51aXR5IGNvbnNpZGVyYXRpb25zLAojIHNlcGFyYXRlIGFjY291bnQgb3IgYW1vdW50cyByZWRlcG9zaXRlZC4KCgojIGBMaWZlIEluZHVzdHJ5IHwgTElGRSBFWEhJQklUIE9GIExJRkUgSU5TVVJBTkNFIChQRy4gMjUpYApOQUlDZXhoaWJpdHMgPC0gcmVhZC5jc3YyKCdsaWZlZXhoaWJpdHMuY3N2JykgJT4lIAogIGFzX3RpYmJsZSAlPiUgCiAgZmlsdGVyKChuY2hhcihjYXRlZ29yeSkgPiAxKSAmIGdyZXBsKCdMYXBzZWR8U3VycmVuZGVyZWQnLCBjYXRlZ29yeSkpICU+JQogIG11dGF0ZV9hdCh2YXJzKHBhc3RlMCgnWScsIDE5OTY6MjAxOSkpLCBhcy5udW1lcmljKQoKTkFJQ2V4aGliaXRzJGNhdGVnb3J5ICU8PiUgZ3N1YignUG9saWN5ICYgQ2VydCcsICdQb2xpY2llcycsIC4pCk5BSUNleGhpYml0cyRjYXRlZ29yeSAlPD4lIGdzdWIoJ0NlcnRpZmljYXRlcycsICdQb2xpY2llcycsIC4pCgpOQUlDZXhoaWJpdHMgPC0gTkFJQ2V4aGliaXRzICU+JQogIGdyb3VwX2J5KHR5cGUsIGNhdGVnb3J5KSAlPiUKICBzdW1tYXJpc2VfYWxsKHN1bSkKCk5BSUNleGhpYml0cyA8LSAgTkFJQ2V4aGliaXRzICU+JSAKICBnYXRoZXIoeWVhciwgdmFsdWUsIFkxOTk2OlkyMDE5KSAlPiUgCiAgc3ByZWFkKGNhdGVnb3J5LHZhbHVlKSAlPiUKICByZW5hbWUoCiAgICBsYXBzZV9mYWNlID0gYEluc3VyYW5jZSBMb3N0OiBMYXBzZWRgLCAKICAgIHN1cnJlbmRlcl9mYWNlID0gYEluc3VyYW5jZSBMb3N0OiBTdXJyZW5kZXJlZGAsCiAgICBsYXBzZV9jb3VudCA9IGBQb2xpY2llcyBMb3N0OiBMYXBzZWRgLAogICAgc3VycmVuZGVyX2NvdW50ID0gYFBvbGljaWVzIExvc3Q6IFN1cnJlbmRlcmVkYCkgJT4lCiAgbXV0YXRlKAogICAgdGVybWluYXRlZF9mYWNlID0gbGFwc2VfZmFjZSArIHN1cnJlbmRlcl9mYWNlLAogICAgdGVybWluYXRlZF9jb3VudCA9IGxhcHNlX2NvdW50ICsgc3VycmVuZGVyX2NvdW50KQoKIyBFeHRyYWN0ZWQgZmllbGQgMTogSW5zdXJhbmNlIExvc3Q6IFN1cnJlbmRlcmVkICgkMDAwKQojIFN1cnJlbmRlciByZXBvcnRzIHRoZSBjYW5jZWxsYXRpb24gZnJvbSBpbiBmb3JjZSBvZiB0aGUgZmFjZSBhbW91bnRzIAojIChvciBhZGp1c3RlZCBhbW91bnRzIG9mIGluc3VyYW5jZSkgCiMgZm9yIHBvbGljaWVzIHRoYXQgd2VyZSBzdXJyZW5kZXJlZCBieSB0aGUgb3duZXJzIGZvciB0aGVpciBjYXNoIHZhbHVlLAojIG9yIHdoZXJlIGEgcG9saWN5IGxvYW4gaW5kZWJ0ZWRuZXNzIAojIChsb2FuIHByaW5jaXBhbCBwbHVzIGFjY3J1ZWQgaW50ZXJlc3QpIAojIHJlYWNoZWQgb3IgZXhjZWVkZWQgdGhlIHJlc2VydmUgdmFsdWUgY2F1c2luZyB0ZXJtaW5hdGlvbiBvZiBpbnN1cmFuY2UgY292ZXJhZ2UuCgojICMgRXh0cmFjdGVkIGZpZWxkIDI6IEluc3VyYW5jZSBMb3N0OiBMYXBzZWQgKCQwMDApCiMgTGFwc2UgcmVwb3J0cyBjYW5jZWxsYXRpb24gZnJvbSBpbiBmb3JjZSBvZiBpbnN1cmFuY2Ugd2l0aG91dCBub25mb3JmZWl0dXJlIHByb3Zpc2lvbnMgYXMgdGhlIHJlc3VsdCBvZiBub25wYXltZW50IG9mIHByZW1pdW1zIHByaW9yIHRvIHRoZSBub3JtYWwgZXhwaXJhdGlvbiBkYXRlIG9mIHN1Y2ggaW5zdXJhbmNlIGNvdmVyYWdlLgpgYGAKCiMjIyBKb2luIHR3byBOQUlDIGRhdGEgdGFibGVzCgpgYGB7ciBKb2luX05BSUNfRGF0YSwgZWNobyA9IFR9Ck5BSUNkYXRhX2FsbCA9IE5BSUNleGhpYml0cyAlPiUKICBmdWxsX2pvaW4oTkFJQ3N1cnJlbmRlcikgJT4lCiAgc2VsZWN0KHR5cGUsIHllYXIsIAogICAgICAgICBsYXBzZV9mYWNlLCBzdXJyZW5kZXJfZmFjZSwgdGVybWluYXRlZF9mYWNlLCAKICAgICAgICAgbGFwc2VfY291bnQsIHN1cnJlbmRlcl9jb3VudCwgdGVybWluYXRlZF9jb3VudCwKICAgICAgICAgc3VycmVuZGVyX2JlbmVmaXQpICU+JQogIGdhdGhlcihjYXRlZ29yeSwgdmFsdWUsIGxhcHNlX2ZhY2U6c3VycmVuZGVyX2JlbmVmaXQpICU+JSAKICBzcHJlYWQodHlwZSx2YWx1ZSkgJT4lCiAgbXV0YXRlKG9yZGluZCA9IGluZGwgKyBvcmRpbmFyeSkgJT4lICMgY29tYmluZSBgaW5kbGAgYW5kIGBvcmRpbmFyeWAgdG8gYWxpZ24gd2l0aCBBQ0xJIGRhdGEKICBzZWxlY3QoLWMoaW5kbCwgb3JkaW5hcnkpKSAlPiUKICBtdXRhdGUodG90YWwgPSBvcmRpbmQgKyBjcmVkaXQgKyBncm91cCkgJT4lICMgY2FsY3VsYXRlIHRvdGFsCiAgZ2F0aGVyKHR5cGUsIHZhbHVlLCBjcmVkaXQ6dG90YWwpICU+JSAKICBzcHJlYWQoY2F0ZWdvcnksIHZhbHVlKSAlPiUKICBtdXRhdGUoeWVhciA9IGFzLmludGVnZXIoZ3N1YignW14wLTldJywgJycsIHllYXIpKSwKICAgICAgICAgYmVuX3N1cl9yYXRpbyA9IHN1cnJlbmRlcl9iZW5lZml0L3N1cnJlbmRlcl9mYWNlLCAjIGNhbGN1bGF0ZSBiZW5lZml0OmZhY2UgcmF0aW8gZm9yIHN1cnJlbmRlcmVkIHBvbGljaWVzCiAgICAgICAgIGJlbl90ZXJfcmF0aW8gPSBzdXJyZW5kZXJfYmVuZWZpdC90ZXJtaW5hdGVkX2ZhY2UgIyBjYWxjdWxhdGUgYmVuZWZpdDpmYWNlIHJhdGlvIGZvciBhbGwgdGVybWluYXRlZCBwb2xpY2llcwogICAgICAgICApCgpOQUlDZGF0YV9hbGwgIyBkb2xsYXIgYW1vdW50IGluIHRob3VzYW5kICgkMDAwKQpgYGAKCgojIyBMaWZlIEluc3VyYW5jZSBNYXJrZXRpbmcgYW5kIFJlc2VhcmNoIEFzc29jaWF0aW9uIChMSU1SQSkgZGF0YQoKIyMjIFJlYWQgTElNUkEgZGF0YSBmcm9tIEBMSU1SQTIwMTYKCmBgYHtyIEdldF9MSU1SQV9EYXRhLCBlY2hvID0gVH0KIyBEYXRhIGRvd25sb2FkZWQgZnJvbSBgJ2h0dHBzOi8vcmVzZWFyY2gubGltcmEuY29tL3ZpenFsL3cvMjAxNk93bmVyc2hpcGluRm9jdXMvdi9IaXN0b3JpY2FsVHJlbmRzL3Z1ZC9zZXNzaW9ucy8wQzgxOTE0MzNDNkY0NjVDQTlCMkVFRjhFRTQwNUJCMi0xOjEvdmlld3MvNDEzMTM1MTUzOTAyMjI4OTgwM18zNzIyNTc2MDEwNDgzMDc2OTkyP2Nzdj10cnVlJnN1bW1hcnk9dHJ1ZWAKTElNUkFfZGF0YSA8LSByZWFkLmNzdjIoJ0NoYW5nZUluUmF0ZV9kYXRhLmNzdicpICU+JSBkYXRhLnRhYmxlCgpMSU1SQV9kYXRhCmBgYAoKIyMgTmF0aW9uYWwgSGVhbHRoIEV4cGVuZGl0dXJlIChOSEUpIGRhdGEKCiMjIyBSZWFkIE5IRSBkYXRhIGZyb20gQENNUzIwMTkKCmBgYHtyIEdldF9OSEVfRGF0YSwgZWNobyA9IFR9CiMgRGF0YSBkb3dubG9hZGVkIGZyb20gYGh0dHBzOi8vd3d3LmNtcy5nb3YvZmlsZXMvemlwL25oZS10YWJsZXMuemlwYApudXJzaW5nIDwtIHJlYWQuY3N2KCdOSEUyMDE4L05IRTIwMTguY3N2Jywgc2tpcCA9IDEpCm5hbWVzKG51cnNpbmcpWzFdID0gJ2V4cGVuZGl0dXJlJwpudXJzaW5nID0gbnVyc2luZ1sKICBudXJzaW5nJGV4cGVuZGl0dXJlID09ICdUb3RhbCBOdXJzaW5nIENhcmUgRmFjaWxpdGllcyBhbmQgQ29udGludWluZyBDYXJlIFJldGlyZW1lbnQgQ29tbXVuaXRpZXMnLAogICAgICAgICAgICAgICAgICBdICU+JQogIHQgJT4lCiAgYXNfdGliYmxlKHJvd25hbWVzID0gJ3llYXInKSAKCm5hbWVzKG51cnNpbmcpWzJdID0gJ251cnNfZXhwZW5zZScKCm51cnNpbmcgPC0gbnVyc2luZyAlPiUKICBtdXRhdGUoCiAgICB5ZWFyID0gZ3N1YignW14wLTldJywgJycseWVhcikgJT4lIGFzLm51bWVyaWMsCiAgICBudXJzX2V4cGVuc2UgPSBhcy5udW1lcmljKGdzdWIoJ1teMC05Ll0nLCAnJyxudXJzX2V4cGVuc2UpKSAvIDEwMDAKICAgICkgJT4lCiAgZmlsdGVyKGlzLmZpbml0ZSh5ZWFyKSkKCm51cnNpbmcgIyBkb2xsYXIgYW1vdW50IGluIGJpbGxpb24gKCQwMDAsMDAwLDAwMCkKYGBgCgoKIyMgRmVkZXJhbCBSZXNlcnZlIGRhdGEKCiMjIyBSZWFkIEZlZGVyYWwgUmVzZXJ2ZSBkYXRhIGZyb20gQGZyZWQyMDIwCgpgYGB7ciBHZXRfZnJlZF9EYXRhLCBlY2hvID0gVH0KIyBIb3VzZWhvbGRzOyBPd25lci1PY2N1cGllZCBSZWFsIEVzdGF0ZSBhdCBNYXJrZXQgVmFsdWUsIExldmVsCiMgaHR0cHM6Ly9mcmVkLnN0bG91aXNmZWQub3JnL3Nlcmllcy9CT0daMUZMMTU1MDM1MDEzUQpyZWFsX3N0YXRlIDwtIHJlYWQuY3N2KCdCT0daMUZMMTU1MDM1MDEzUS5jc3YnKSAlPiUKICBhc190aWJibGUgJT4lCiAgZmlsdGVyKERBVEUgPiAyMDAwLCBncmVwbCgnLTEwLTAxJywgREFURSkpICU+JSAjIEdldCBsYXN0IHF1YXJ0ZXIgb2YgdGhlIHllYXIgc2luY2UgMjAyMAogIHRyYW5zbXV0ZSgKICAgIGVuZF9vZl95ZWFyID0gREFURSAlPiUgYXMuRGF0ZSAlPiUgZm9ybWF0KCclWScpICU+JSBhcy5udW1lcmljLAogICAgYHJlYWxfZXN0YXRlX3ZhbHVlYCA9IGFzLm51bWVyaWMoQk9HWjFGTDE1NTAzNTAxM1EpLzFlNgogICAgKQoKCiMgIyBIb3VzZWhvbGRzOyBPd25lci1PY2N1cGllZCBSZWFsIEVzdGF0ZSAqSW5jbHVkaW5nIFZhY2FudCBMYW5kIGFuZCBNb2JpbGUgSG9tZXMgYXQgTWFya2V0IFZhbHVlLCBNYXJrZXQgVmFsdWUgTGV2ZWxzKgojICMgaHR0cHM6Ly9mcmVkLnN0bG91aXNmZWQub3JnL3Nlcmllcy9IT09SRVZMTUhNVgojIHJlYWxfc3RhdGUgPC0gcmVhZC5jc3YoJ0hPT1JFVkxNSE1WLmNzdicpICU+JQojICAgYXNfdGliYmxlICU+JQojICAgZmlsdGVyKERBVEUgPiAyMDAwLCBncmVwbCgnLTEwLTAxJywgREFURSkpICU+JSAjIEdldCBsYXN0IHF1YXJ0ZXIgb2YgdGhlIHllYXIgc2luY2UgMjAyMAojICAgdHJhbnNtdXRlKAojICAgICBlbmRfb2ZfeWVhciA9IERBVEUgJT4lIGFzLkRhdGUgJT4lIGZvcm1hdCgnJVknKSAlPiUgYXMubnVtZXJpYywKIyAgICAgYHJlYWxfZXN0YXRlX3ZhbHVlYCA9IGFzLm51bWVyaWMoSE9PUkVWTE1ITVYpLzFlMwojICAgICApCgoKcmVhbF9zdGF0ZSAjIGRvbGxhciBhbW91bnQgaW4gdHJpbGxpb24gKCQwMDAsMDAwLDAwMCwwMDApCmBgYAoKIyBEYXRhIGFuYWx5c2lzCgojIyBMaWZlIGluc3VyYW5jZSB0ZXJtaW5hdGlvbgoKYGBge3IgcnNsb3NzLCBlY2hvID0gVH0KcnNsb3NzIDwtIHJlYWxfc3RhdGUgJT4lIAogIGZpbHRlcihlbmRfb2ZfeWVhciAlaW4lIGMoMjAwNiwgMjAwOSkpICU+JSAjIGZpbmFjaWFsIGNyaXNpcyAyMDA3IChpLmUuIGVuZCBvZiAyMDA2KSB0byAyMDA5CiAgYXBwbHkoMiwgZGlmZikKCnBhc3RlMCgnTWFya2V0IGxvc3Mgb2YgaG91c2Vob2xkIHJlYWwgZXN0YXRlIHAuYS46ICcsIC1yb3VuZChyc2xvc3NbMl0vcnNsb3NzWzFdLDIpLAogICAgICAgJyB0cmlsbGlvbiBVU0QnKSAlPiUgcHJpbnQKYGBgCgojIyBIb3VzZWhvbGRzJyByZWFsIGVzdGF0ZSBtYXJrZXQgbG9zcyBkdXJpbmcgdGhlIGdsb2JhbCBmaW5hbmNpYWwgY3Jpc2lzIApgYGB7ciB0ZXJtaW5hdGlvbiwgZWNobyA9IFR9CnN0YXJ0X3llYXIgPSAyMDE3CnRlcm1pbmF0aW9uIDwtIE5BSUNkYXRhX2FsbCAlPiUKICBmaWx0ZXIodHlwZSA9PSAndG90YWwnICYgeWVhciA+PSBzdGFydF95ZWFyKSAlPiUKICBtdXRhdGUoCiAgICBgdGVybWluYXRlZF9jb3VudCAobWlsbGlvbilgID0gdGVybWluYXRlZF9jb3VudC8xZTYsCiAgICBgdGVybWluYXRlZF9mYWNlICh0cmlsbGlvbiBVU0QpYCA9IHRlcm1pbmF0ZWRfZmFjZS8xZTkKICAgICkgJT4lCiAgc2VsZWN0KHllYXIsIGB0ZXJtaW5hdGVkX2NvdW50IChtaWxsaW9uKWAsIGB0ZXJtaW5hdGVkX2ZhY2UgKHRyaWxsaW9uIFVTRClgKSAKCnBhc3RlMCgnVGVybWluYXRlZCBwb2xpY2llcyBlYWNoIHllYXIgc2luY2UgJywgc3RhcnRfeWVhciwgJzogJywgCiAgICAgICB0ZXJtaW5hdGlvbiRgdGVybWluYXRlZF9jb3VudCAobWlsbGlvbilgICU+JSBtaW4gJT4lIHJvdW5kLAogICAgICAgJyBtaWxsaW9uJykgJT4lIHByaW50CnBhc3RlMCgnVGVybWluYXRlZCBmYWNlIG9uIGF2ZXJhZ2UgZWFjaCB5ZWFyIHNpbmNlICcsIHN0YXJ0X3llYXIsICc6ICcsIAogICAgICAgdGVybWluYXRpb24kYHRlcm1pbmF0ZWRfZmFjZSAodHJpbGxpb24gVVNEKWAgJT4lIG1lYW4gJT4lIHJvdW5kKDIpLAogICAgICAgJyB0cmlsbGlvbiBVU0QnKSAlPiUgcHJpbnQKYGBgCgojIyBMaWZlIEluc3VyYW5jZSBvd25lcnNoaXAgYXQgaG91c2Vob2xkIGxldmVsCgojIyMgRXN0aW1hdGUgd2l0aCBMSU1SQSBkYXRhCmBgYHtyIExJTVJBX2VzdG1pYXRlLCBlY2hvID0gVH0KcGFzdGUwKCdMSU1SQSBlc3RtaWF0ZSAoMjAxNik6ICcsIAogICAgICAgTElNUkFfZGF0YVtPd25lcnNoaXAuVHlwZSA9PSAnT3ducyBBbnkgTGlmZScgJiBZZWFyID09IDIwMTZdJFBlcmNlbnQKICAgICAgICkgJT4lIHByaW50CmBgYAoKIyMjIEVzdGltYXRlIHdpdGggU0NGIGRhdGEKCmBgYHtyIFNDRl9lc3RtaWF0ZSwgZWNobyA9IFR9CiMgSW52ZXN0aWdhdGUgaW5zdXJhbmNlIG93bmVyc2hpcAojIHg0MDAxOiBEbyB5b3UgKG9yIGFueW9uZSBpbiB5b3VyIGZhbWlseSBsaXZpbmcgaGVyZSkgaGF2ZSBhbnkgbGlmZSBpbnN1cmFuY2U/IAojIDEuIFlFUwojIDUuIE5PCiMgaHR0cHM6Ly93d3cuZmVkZXJhbHJlc2VydmUuZ292L2FwcHMvc2NmY2IvZGV0YWlsLzI5NDgvbGlmZSUyMGluc3VyYW5jZQoKIyBodHRwOi8vYXNkZnJlZS5jb20vc3VydmV5LW9mLWNvbnN1bWVyLWZpbmFuY2VzLXNjZi5odG1sCiMgVW53ZWlnaHRlZCBjb3VudAojIHNjZl9kZXNpZ24gJT4lIHdpdGgoc3Z5Ynkofm9uZSAsIH54NDAwMSAsIHVud3RkLmNvdW50KSkgJT4lIHNjZl9NSWNvbWJpbmUKIyBHZXQgY2xvc2UgcmVzdWx0IHdpdGg6IHNjZl9kZXNpZ24kZGVzaWduc1tbMV1dJHZhcmlhYmxlcyR4NDAwMSAlPiUgdGFibGUKCiMgQ291bnQgdGhlIHdlaWdodGVkIHNpemUgb2YgdGhlIGdlbmVyYWxpemFibGUgcG9wdWxhdGlvbiBieSBncm91cCB4NDAwMToKcG9wX2J5X2xpZmVvd24gPSBzY2ZfZGVzaWduICU+JSAKICB3aXRoKHN2eWJ5KH5vbmUgLCB+eDQwMDEgLCBzdnl0b3RhbCkpICU+JQogIHNjZl9NSWNvbWJpbmUKCiMgRXh0cmFjdCB3ZWlnaHRlZCBjb3VudCBvZiBlYWNoIGFuc3dlciAoMS4gWUVTIC8gNS4gTk8pIApwb3BfYnlfbGlmZW93bl9yZXMgPSBwb3BfYnlfbGlmZW93biRjb2VmZmljaWVudHMKCiMgUHJvcG9ydGlvbiBvZiBsaWZlIGluc3VyYW5jZSBvd25lcnNoaXAKc2NmX2VzdCA8LSBwb3BfYnlfbGlmZW93bl9yZXNbMV0vc3VtKHBvcF9ieV9saWZlb3duX3JlcykKCnBhc3RlMCgnU0NGIGVzdG1pYXRlICgyMDE2KTogJywgcm91bmQoc2NmX2VzdCoxMDApLCAnJScpICU+JSBwcmludApgYGAKCiMjIyBFc3RpbWF0ZSB3aXRoIFNJUFAgZGF0YQoKYGBge3IgU0lQUF9lc3RtaWF0ZSwgZWNobyA9IFR9CmhoX2xpZmVvd24gPSBhbGxfd2F2ZV9hbm51YWwgJT4lIAogIHNlbGVjdChzd2F2ZSwgd3BmaW53Z3QsIHRsaWZlX2Z2YWwsIGVyZWxycGUsIHNzdWlkKSAlPiUKICBncm91cF9ieShzd2F2ZSwgc3N1aWQpICU+JQogIG11dGF0ZSh3aXRoX2xpZmVfaW5zID0gYW55KGlzLmZpbml0ZSh0bGlmZV9mdmFsKSkpICU+JSAjIHJldHVybiBgVHJ1ZWAgaWYgYW55Ym9keSBpbiB0aGUgaG91c2Vob2xkIGhhcyBsaWZlIGluc3VyYW5jZQogIGZpbHRlcigoZXJlbHJwZSA9PSAxIHwgZXJlbHJwZSA9PSAyKSAmIGlzLmZpbml0ZSh3cGZpbndndCkpICU+JSAjIHNlbGVjdCBob3VzZWhvbGRlcgogIGdyb3VwX2J5KHN3YXZlLHdpdGhfbGlmZV9pbnMpICU+JSAKICBzdW1tYXJpc2UoY291bnRfaG91c2Vob2xkID0gc3VtKHdwZmlud2d0KSkKCiMgT25seSBjb25zaWRlciAyMDE2IGRhdGEgdG8gYWxpZ24gd2l0aCBTQ0YKaGhfbGlmZW93bl8yMDE2IDwtIGhoX2xpZmVvd24gJT4lIGZpbHRlcihzd2F2ZSA9PSA0KQoKIyBQcm9wb3J0aW9uIG9mIGxpZmUgaW5zdXJhbmNlIG93bmVyc2hpcApzaXBwX2VzdCA8LSAoaGhfbGlmZW93bl8yMDE2ICU+JSBmaWx0ZXIod2l0aF9saWZlX2lucyA9PSBUKSAlPiUgLiRjb3VudF9ob3VzZWhvbGQpL3N1bShoaF9saWZlb3duXzIwMTYkY291bnRfaG91c2Vob2xkKQoKcGFzdGUwKCdTSVBQIGVzdG1pYXRlICgyMDE2KTogJywgcm91bmQoc2lwcF9lc3QqMTAwKSwgJyUnKSAlPiUgcHJpbnQKYGBgCgojIyMgRXN0aW1hdGUgd2l0aCBBQ0xJIGRhdGEKCmBgYHtyIEFDTElfZXN0bWlhdGUsIGVjaG8gPSBUfQojIENoYXB0ZXIgNyBMSUZFIElOU1VSQU5DRSAocC4gNjMpCiMgNzUgbWlsbGlvbiBob3VzZWhvbGRzIHJlbHkgb24gbGlmZSBpbnN1cmFuY2UgYW5kL29yIG5vbi1xdWFsaWZpZWQgYW5udWl0aWVzCgojIFRvdGFsIGhvdXNlaG9sZCBkYXRhCiMgYGh0dHBzOi8vd3d3Mi5jZW5zdXMuZ292L3Byb2dyYW1zLXN1cnZleXMvZGVtby90YWJsZXMvZmFtaWxpZXMvdGltZS1zZXJpZXMvaG91c2Vob2xkcy9oaDEueGxzYAojIFllYXIJVG90YWwgaG91c2Vob2xkcyAoTnVtYmVycyBpbiB0aG91c2FuZHMpCiMgMjAxOQkxMjgsNTc5CiMgMjAxOAkxMjcsNTg2CgpwYXN0ZTAoJ0FDTEkgZXN0bWlhdGUgKDIwMTgpOiAnLCByb3VuZCg3NS8xMjcuNTg2KjEwMCksICclJykgJT4lIHByaW50CmBgYAoKCiMjIExpZmUgaW5zdXJhbmNlIHByZW1pdW0KCmBgYHtyIHByZW1pdW0sIGVjaG8gPSBUfQoKIyBOZXQgUHJlbWl1bXMgJiBBbm51aXR5IENvbnNpZGVyYXRpb25zOiBMaWZlLCBBJkgsIDIwMTkgWSAoMzEvMTIvMjAxOSkKIyBMaWZlIEluZHVzdHJ5IHwgTElGRSBFWEhJQklUIDEgUEFSVCAxICYgMiAoUEcuIDksIDEwKQp0b3RhbF9wcmVtIDwtIHN1bSgKMTA3MDU1LCAjIEluZGwgTGlmZQoxMjExNzIxNzYsICMgT3JkaW5hcnkgTGlmZQoyOTc0NTk5OSwgIyBHcm91cCBMaWZlIEluc3VyYW5jZQo2Mzk5MjQgIyBDcmVkaXQgTGlmZQopLzFlNgoKIyBMaWZlIEluZHVzdHJ5IHwgTElGRSBJTkNPTUUgU1RBVEVNRU5UCiMgUmV2ZW51ZQojIExpZmUgSW5zdXJhbmNlIFByZW1pdW1zCiMgMTE1LDAzNCwyMjIgIzIwMTYgWQojIDEzNywxNDgsNjYzICMyMDE3IFkKIyAxNDUsMDkwLDUyNiAjMjAxOCBZCgpwYXN0ZTAoJ1RvdGFsIGxpZmUgaW5zdXJhbmNlIHByZW1pdW0gaW4gMjAxOTogJywgcm91bmQodG90YWxfcHJlbSksICcgYmlsbGlvbiBVU0QnKSAlPiUgcHJpbnQKYGBgCgoKIyMgSW5kaXZpZHVhbCdzIGxpZmUgSW5zdXJhbmNlIHZhbHVlIHZlcnN1cyA0MDFrIHZhbHVlCgpgYGB7ciBkYXRhLCBlY2hvID0gVH0KcGVyc29uX2RhdGFfYnljYXNoIDwtIGFsbF93YXZlX2FubnVhbFssIGMoCiAgJ3N3YXZlJywgJ3dwZmlud2d0JywgJ3Rhbm52YWwnLCAndGlyYWtlb3ZhbCcsICd0dGhyNDAxdmFsJywgJ3RsaWZlX2N2YWwnLCAndGxpZmVfZnZhbCcsCiAgcGVyc29uX2xhYmVsJGNvbG1uYW1lKV0gJT4lCiAgZ3JvdXBfYnkoc3dhdmUsIGhhdmVjYXNodmFsdWUgPSBpcy5maW5pdGUodGxpZmVfY3ZhbCkpICU+JSAjIERpZmZlcmVudGlhdGUgYmV0d2VlbiB0aGUgdW5pdmVyc2Ugd2l0aCBjYXNoIHZhbHVlIGFuZCB0aGUgb25lIHdpdGhvdXQKICBzdW1tYXJpc2VfYWxsKGxpc3QoCiAgICB+c3VtKC4sIG5hLnJtID0gVCksCiAgICB+d2VpZ2h0ZWQuc3VtKC4sd3BmaW53Z3QpCiAgKSkgJT4lIAogIHNlbGVjdCgtd3BmaW53Z3Rfd2VpZ2h0ZWQuc3VtKSAlPiUKICBtdXRhdGUoY2FzaHJhdGlvID0gdGxpZmVfY3ZhbF93ZWlnaHRlZC5zdW0vdGxpZmVfZnZhbF93ZWlnaHRlZC5zdW0pICMgQ2FsY3VsYXRlIGNhc2hfdmFsdWU6ZmFjZV9mYWx1ZSByYXRpbyBieSBncm91cCAod2l0aCBvdCB3aXRob3V0IGNhc2ggdmFsdWUpCgpwZXJzb25fZGF0YSA9IHBlcnNvbl9kYXRhX2J5Y2FzaCAlPiUgCiAgc2VsZWN0KC1jKGhhdmVjYXNodmFsdWUsY2FzaHJhdGlvKSkgJT4lCiAgZ3JvdXBfYnkoc3dhdmUpICU+JSAKICBzdW1tYXJpc2VfYWxsKHN1bSkgJT4lCiAgbXV0YXRlKGNhc2hyYXRpbyA9IHRsaWZlX2N2YWxfd2VpZ2h0ZWQuc3VtL3RsaWZlX2Z2YWxfd2VpZ2h0ZWQuc3VtKSAjIENhbGN1bGF0ZSBhZ2dyZWdhdGUgY2FzaF92YWx1ZTpmYWNlX2ZhbHVlIHJhdGlvCgpzd2F2ZV95ZWFyID0gdGliYmxlKHN3YXZlID0gYXMubnVtZXJpYygxOjQpLCB5ZWFyID0gMjAxMzoyMDE2KQoKQUNMSWRhdGEgPSBBQ0xJZGF0YV9hbGwgJT4lIAogIGlubmVyX2pvaW4oc3dhdmVfeWVhcikgJT4lCiAgZnVsbF9qb2luKHBlcnNvbl9kYXRhWywgYygnc3dhdmUnLCAnY2FzaHJhdGlvJyldKSAlPiUgIyBBZGQgYWdncmVnYXRlIGNhc2hfdmFsdWU6ZmFjZV9mYWx1ZSByYXRpbyB0byB0aGUgQUNMSSBkYXRhCiAgbXV0YXRlKGV2bXVsdGlwbGllciA9IHJlc2VydmVyYXRpby9jYXNocmF0aW8pICMgQ2FsY3VsYXRlIGFnZ3JlZ2F0ZSByZXNlcnZlOmNhc2hfdmFsdWUgcmF0aW8KCgp0ZXJtaW5hdGVkX2luc19vcmRpbmQgPSBOQUlDZGF0YV9hbGwgJT4lCiAgZnVsbF9qb2luKHN3YXZlX3llYXIpICU+JQogIGZpbHRlcihpcy5maW5pdGUoc3dhdmUpICYgKHR5cGUgJWluJSBjKCdvcmRpbmQnKSkpICU+JQogIHNlbGVjdCgtdHlwZSkgJT4lCiAgZnVsbF9qb2luKHBlcnNvbl9kYXRhWywgYygnc3dhdmUnLCAnY2FzaHJhdGlvJyldKSAlPiUKICBtdXRhdGUoCiAgICBzdXJiZW5tdWx0aXBsaWVyID0gYmVuX3Rlcl9yYXRpby9jYXNocmF0aW8KICApICMgQ2FsY3VsYXRlIGFnZ3JlZ2F0ZSBzdXJyZW5kZXJfYmVuZWZpdDpjYXNoX3ZhbHVlIHJhdGlvCgoKcGVyc29uX3dpdGhfY3YgPC0gcGVyc29uX2RhdGFfYnljYXNoICU+JQogIGZpbHRlcihoYXZlY2FzaHZhbHVlID09IFQpICU+JSAjIEV4YW1pbmUgb25seSB0aGUgdW5pdmVyc2Ugd2l0aCBjYXNoIHZhbHVlCiAgc2VsZWN0KHN3YXZlLAogICAgICAgICB3cGZpbndndF9zdW0sIHR0aHI0MDF2YWxfd2VpZ2h0ZWQuc3VtLCB0bGlmZV9jdmFsX3dlaWdodGVkLnN1bSwgdGxpZmVfZnZhbF93ZWlnaHRlZC5zdW0pICU+JQogIGZ1bGxfam9pbihBQ0xJZGF0YSAlPiUgZmlsdGVyKHR5cGUgPT0gJ29yZGluZCcpICU+JSBzZWxlY3Qoc3dhdmUsIGV2bXVsdGlwbGllcikpICU+JQogIGZ1bGxfam9pbih0ZXJtaW5hdGVkX2luc19vcmRpbmQpICU+JQogIG11dGF0ZSgKICAgIG1lYW5mdiA9IHRsaWZlX2Z2YWxfd2VpZ2h0ZWQuc3VtL3dwZmlud2d0X3N1bSwgIyBNZWFuIGZhY2UgdmFsdWUgbGlmZSBpbnN1cmFuY2UKICAgIG1lYW5jdiA9IHRsaWZlX2N2YWxfd2VpZ2h0ZWQuc3VtL3dwZmlud2d0X3N1bSwgIyBNZWFuIGNhc2ggdmFsdWUgbGlmZSBpbnN1cmFuY2UKICAgIG1lYW5ldiA9IG1lYW5jdiAqIGV2bXVsdGlwbGllciwgIyBNZWFuIGVjb25vbWljIHZhbHVlIGxpZmUgaW5zdXJhbmNlCiAgICBtZWFuc2IgPSBtZWFuY3YgKiBzdXJiZW5tdWx0aXBsaWVyLCAjIE1lYW4gc3VycmVuZGVyIGJlbmVmaXQgbGlmZSBpbnN1cmFuY2UKICAgIG1lYW40MDFrID0gdHRocjQwMXZhbF93ZWlnaHRlZC5zdW0vd3BmaW53Z3Rfc3VtLCAjIE1lYW4gNDAxayBhY2NvdW50IHZhbHVlCiAgICBjYXNocmF0aW8gPSB0bGlmZV9jdmFsX3dlaWdodGVkLnN1bS90bGlmZV9mdmFsX3dlaWdodGVkLnN1bQogICkgJT4lIAogIHVuZ3JvdXAgCgpFVnZzNDAxIDwtIHBlcnNvbl93aXRoX2N2ICU+JSAKICBzZWxlY3Qoc3dhdmUsIG1lYW5jdiwgbWVhbmV2LCBtZWFuc2IsIG1lYW40MDFrLCBtZWFuZnYpCmBgYAoKCmBgYHtyIHBsb3R9CiMgUHJlcGFyZSBkYXRhIGZyYW1lIGZvciBwbG90dGluZwpwbG90ZGYgPC0gKEVWdnM0MDEgJT4lIHNlbGVjdCgtc3dhdmUpICU+JSBjYmluZChudWwgPSBOQSkgJT4lIHQpLzEwMDAKCnBsb3RkZltjKCdtZWFuNDAxaycsICdtZWFuZXYnKSxdICU+JSByb3dNZWFucyAlPiUgCiAgd3JpdGUudGFibGUoJ2V2NDAxa3Bsb3QuY3N2JywgZGVjID0gJy4nLCBzZXAgPSAnOycsIHJvdy5uYW1lcyA9IEYpCgpiYXJwbG90KHBsb3RkZltjKCdtZWFuNDAxaycsICdtZWFuZXYnKSxdICU+JSByb3dNZWFucywKICAgICAgICBob3JpeiA9IFQsCiAgICAgICAgc3BhY2UgPSBjKDAuMSwwLjUpLAogICAgICAgIHlsaW0gPSBjKDAsNCkpCmBgYAoKYGBge3J9Cgp5bWF4ID0gbWF4KHBsb3RkZiwgbmEucm0gPSBUKSAlPiUgY2VpbGluZwoKYmFzZWNvbCA9IGMoJ3NwcmluZ2dyZWVuNCcsICdibHVlJywgJ29yYW5nZScsICdncmV5JywgJ3JlZCcpCmJvcmRlcmNvbCA9IGMoYmFzZWNvbFsxXSwgTkEsIE5BLCBiYXNlY29sWzRdLCBiYXNlY29sWzVdKQoKYWRqdXN0ZWRjb2wgPSBjKAogIGFkanVzdGNvbG9yKGJhc2Vjb2xbMV0sIGFscGhhLmYgPSAwLjcpLAogIGFkanVzdGNvbG9yKGJhc2Vjb2xbMl0sIGFscGhhLmYgPSAwLjgpLAogIGFkanVzdGNvbG9yKGJhc2Vjb2xbM10sIGFscGhhLmYgPSAxKSwKICBhZGp1c3Rjb2xvcihiYXNlY29sWzRdLCBhbHBoYS5mID0gMC42KSwKICBhZGp1c3Rjb2xvcihiYXNlY29sWzVdLCBhbHBoYS5mID0gMCkKKQoKZGVucyA9IDE3CgpwYXIoeHBkID0gVCwgbWFyID0gYygyLCA0LCA2LCAwLjQpLCBsdHkgPSAxLCBsd2QgPSAxLCBtZ3AgPSBjKDAsMC43NSwwKSkKCmJhcnBsb3QocGxvdGRmW2MoJ21lYW5ldicsICdtZWFuNDAxaycpLF0sIAogICAgICAgIHlsaW0gPSBjKDAsIHltYXgpLCAKICAgICAgICBiZXNpZGUgPSBULCAKICAgICAgICBuYW1lcy5hcmcgPSAyMDEzOjIwMTYsCiAgICAgICAgY29sID0gYWRqdXN0ZWRjb2xbYygxLDQpXSwKICAgICAgICBib3JkZXIgPSBiYXNlY29sW2MoMSw0KV0sCiAgICAgICAgc3BhY2UgPSBjKDAuMSwwLjkpKQp0aXRsZSgnQXZlcmFnZSBpbmRpdmlkdWFsIGhvbGRpbmdzIFxuVW5pdmVyc2U6IHBvbGljeWhvbGRlcnMgdy4gY2FzaCB2YWx1ZSA+IDAnLCAKICAgICAgbGluZSA9IDAuMiwgY2V4Lm1haW4gPSAwLjkpCmJhcnBsb3QocGxvdGRmW2MoJ21lYW5jdicsICdudWwnKSxdLCAKICAgICAgICBiZXNpZGUgPSBULCAKICAgICAgICBhZGQgPSBULAogICAgICAgIGRlbnNpdHkgPSBkZW5zLAogICAgICAgIGNvbCA9IGFkanVzdGVkY29sW2MoMiw0KV0sCiAgICAgICAgYm9yZGVyID0gYm9yZGVyY29sW2MoMiw0KV0sCiAgICAgICAgc3BhY2UgPSBjKDAuMSwwLjkpKQpiYXJwbG90KHBsb3RkZltjKCdtZWFuc2InLCAnbnVsJyksXSwgCiAgICAgICAgYmVzaWRlID0gVCwgCiAgICAgICAgYWRkID0gVCwKICAgICAgICBkZW5zaXR5ID0gYyhkZW5zLE5BKSwKICAgICAgICBhbmdsZSA9IDEzNSwKICAgICAgICBjb2wgPSBhZGp1c3RlZGNvbFtjKDMsNCldLAogICAgICAgIGJvcmRlciA9IGJvcmRlcmNvbFtjKDMsNCldLAogICAgICAgIHNwYWNlID0gYygwLjEsMC45KSkKCmxlZ2VuZCg4LjksIHltYXgqMS4zLCAKICAgICAgIGxlZ2VuZCA9IGMoJ0Vjb25vbWljIHZhbHVlJywgJ0Nhc2ggdmFsdWUnLCAnU3VycmVuZGVyIGJlbmVmaXQnLCAnNDAxayBhY2NvdW50IHZhbHVlJyksCiAgICAgICBmaWxsID0gYWRqdXN0ZWRjb2wsCiAgICAgICBib3JkZXIgPSBib3JkZXJjb2wsCiAgICAgICBkZW5zaXR5ID0gYyhOQSwgZGVucywgZGVucywgTkEpLAogICAgICAgYW5nbGUgPSBjKE5BLCA0NSwgMTM1LCBOQSksCiAgICAgICBjZXggPSAwLjgsIHlqdXN0ID0gMSwgYnR5ID0gJ24nKQoKcGFyKGx3ZD0wLjUsIGx0eSA9IDIpCgpiYXJwbG90KHBsb3RkZltjKCdtZWFuZnYnLCAnbnVsJyksXSwgCiAgICAgICAgYmVzaWRlID0gVCwgCiAgICAgICAgYWRkID0gVCwKICAgICAgICBkZW5zaXR5ID0gYyhkZW5zLE5BKSwKICAgICAgICBhbmdsZSA9IDEzNSwKICAgICAgICBjb2wgPSBhZGp1c3RlZGNvbFtjKDUsNCldLAogICAgICAgIGJvcmRlciA9IGJvcmRlcmNvbFtjKDUsNCldLAogICAgICAgIHNwYWNlID0gYygwLjEsMC45KSkKCmxlZ2VuZCg4LjksIHltYXgqMS4xMywgCiAgICAgICBsZWdlbmQgPSBjKCdGYWNlIGFtb3VudCcpLAogICAgICAgZmlsbCA9IE5BLAogICAgICAgYm9yZGVyID0gYm9yZGVyY29sWzVdLAogICAgICAgY2V4ID0gMC44LCBidHkgPSAnbicpCgp0ZXh0KHggPSAwLCB5ID0geW1heCwgJ3Rob3VzYW5kIFVTRCcsIGFkaiA9IGMoMSwwKSkKdGV4dCh4ID0gc2VxKDEuNCxsZW5ndGgub3V0ID0gNCwgYnkgPSAzKSwgCiAgICAgdChwbG90ZGZbYygnbWVhbmV2JyksIF0pICsgMC41LCAKICAgICBwbG90ZGZbYygnbWVhbmV2JyksIF0gJT4lIHQgJT4lIHJvdW5kLCAKICAgICBhZGogPSBjKDAuNSwwKSwgZm9udD0yKQp0ZXh0KHggPSBzZXEoMS40LGxlbmd0aC5vdXQgPSA0LCBieSA9IDMpLCAKICAgICB0KHBsb3RkZltjKCdtZWFuc2InLCAnbWVhbmN2JyksIF0pIC0gMC41LCAKICAgICBwbG90ZGZbYygnbWVhbnNiJywgJ21lYW5jdicpLCBdICU+JSB0ICU+JSByb3VuZCwgCiAgICAgYWRqID0gYygwLjUsMSksIGNleCA9IDAuOCkKdGV4dCh4ID0gc2VxKDIuNSxsZW5ndGgub3V0ID0gNCwgYnkgPSAzKSwgCiAgICAgdChwbG90ZGZbYygnbWVhbjQwMWsnKSwgXSkgKyAwLjUsIAogICAgIHBsb3RkZltjKCdtZWFuNDAxaycpLCBdICU+JSB0ICU+JSByb3VuZCwgCiAgICAgYWRqID0gYygwLjUsMCksIGZvbnQ9MikKCnRleHQoeCA9IHNlcSgxLjQsbGVuZ3RoLm91dCA9IDQsIGJ5ID0gMyksIAogICAgIHQocGxvdGRmW2MoJ21lYW5mdicpLCBdKSwgCiAgICAgcGxvdGRmW2MoJ21lYW5mdicpLCBdICU+JSB0ICU+JSByb3VuZCwgCiAgICAgYWRqID0gYygwLjUsMC41KSwgZm9udD0zLCBjb2wgPSAncmVkJywgY2V4ID0gMC45KQoKCnZhbHVlbG9zc19hbGwgPSBOQUlDZGF0YV9hbGwgJT4lIAogIGlubmVyX2pvaW4oQUNMSWRhdGFfYWxsKSAlPiUKICBtdXRhdGUoCiAgICB0b3RhbGV2ID0gdGVybWluYXRlZF9mYWNlICogcmVzZXJ2ZXJhdGlvLAogICAgdG90YWx2YWx1ZWxvc3MgPSB0b3RhbGV2IC0gc3VycmVuZGVyX2JlbmVmaXQKICApICU+JSAKICBmaWx0ZXIodHlwZSAhPSAndG90YWwnKSAlPiUKICBzZWxlY3QoeWVhciwgdHlwZSwgbGFwc2VfZmFjZSwgc3VycmVuZGVyX2ZhY2UsIHRlcm1pbmF0ZWRfZmFjZSwgdG90YWxldiwgc3VycmVuZGVyX2JlbmVmaXQsIHRvdGFsdmFsdWVsb3NzKSAlPiUKICBnYXRoZXIoY2F0ZWdvcnksIHZhbHVlLCBsYXBzZV9mYWNlOnRvdGFsdmFsdWVsb3NzKSAlPiUKICBncm91cF9ieSh5ZWFyLGNhdGVnb3J5KSAlPiUKICBzdW1tYXJpc2UodmFsdWUgPSBzdW0odmFsdWUpLzFlNikgJT4lCiAgc3ByZWFkKGNhdGVnb3J5LCB2YWx1ZSkgJT4lCiAgaW5uZXJfam9pbihudXJzaW5nKQoKdmFsdWVsb3NzX2FsbCAlPiUgCiAgc2VsZWN0KHllYXIsIHRvdGFsdmFsdWVsb3NzLCBudXJzX2V4cGVuc2UpICU+JQogIHdyaXRlLnRhYmxlKCd2YWx1ZWxvc3NfYWxsLmNzdicsIGRlYyA9ICcuJywgc2VwID0gJzsnLCByb3cubmFtZXMgPSBGKQoKIyMgcGxvdCB2YWx1ZSBsb3NzIC0tLS0KCnBhcih4cGQgPSBULCBtYXIgPSBjKDIsIDQuNSwgNiwgMS41KSwgbHR5ID0gMSwgbHdkID0gMSwgbWdwID0gYygwLDAuNzUsMCkpCnZsX2NvbCA9ICdyZWQnCmFkanVzdGVkX3ZsX2NvbCA9IGFkanVzdGNvbG9yKHZsX2NvbCwgYWxwaGEuZiA9IDAuNykKCnltYXggPSAyNTAKcGxvdCh2YWx1ZWxvc3NfYWxsJHllYXIsIAogICAgIHZhbHVlbG9zc19hbGwkdG90YWxldiwgCiAgICAgdHlwZSA9ICdsJywgCiAgICAgeWxpbSA9IGMoMCwgeW1heCksCiAgICAgeWF4cyA9ICdpJywKICAgICB4YXhzID0gJ2knLAogICAgIHhheHQgPSAnbicsCiAgICAgY29sID0gYmFzZWNvbFsxXSwKICAgICBsd2QgPSAyLAogICAgIGJ0eSA9ICdsJywKICAgICB5bGFiID0gJycsCiAgICAgeGxhYiA9ICcnLAogICAgIG1haW4gPSAnVVMgYWdncmVnYXRlJykKCmF4aXMoMSwgCiAgICAgYXQ9c2VxKHRvID0gMjAxOCwgYnkgPSAzLCBsZW5ndGgub3V0ID0gOCkpCgpwb2x5Z29uKAogIHZhbHVlbG9zc19hbGwkeWVhciAlPiUgYyhyZXYocmFuZ2UoLikpLCAuKSwKICBjKDAsMCx2YWx1ZWxvc3NfYWxsJHRvdGFsZXYpLAogIGNvbCA9IGFkanVzdGVkY29sWzFdLAogIGJvcmRlciA9IE5BCiAgKQoKbGluZXModmFsdWVsb3NzX2FsbCR5ZWFyLCAKICAgICAgdmFsdWVsb3NzX2FsbCRzdXJyZW5kZXJfYmVuZWZpdCwKICAgICAgbHdkID0gMiwKICAgICAgY29sID0gYmFzZWNvbFszXSkKCnBvbHlnb24oCiAgdmFsdWVsb3NzX2FsbCR5ZWFyICU+JSBjKHJldihyYW5nZSguKSksIC4pLAogIGMoMCwwLHZhbHVlbG9zc19hbGwkc3VycmVuZGVyX2JlbmVmaXQpLAogIGRlbnNpdHkgPSBkZW5zLAogIGFuZ2xlID0gMTM1LAogIGNvbCA9IGFkanVzdGVkY29sWzNdLAogIGJvcmRlciA9IE5BCikKCmxpbmVzKHZhbHVlbG9zc19hbGwkeWVhciwgCiAgICAgIHZhbHVlbG9zc19hbGwkdG90YWx2YWx1ZWxvc3MsCiAgICAgIGx3ZCA9IDIsCiAgICAgIGNvbCA9IGFkanVzdGVkX3ZsX2NvbCkKCmxpbmVzKHZhbHVlbG9zc19hbGwkeWVhciwgCiAgICAgIHZhbHVlbG9zc19hbGwkbnVyc19leHBlbnNlLAogICAgICBsd2QgPSAyLAogICAgICBsdHkgPSAyLAogICAgICBjb2wgPSAnZ3JleTMwJykKCmluZCA9IHNlcSh0byA9ICh2YWx1ZWxvc3NfYWxsJHllYXIgJT4lIHJhbmdlICU+JSBkaWZmKSArIDEsIGJ5ID0gNiwgbGVuZ3RoLm91dCA9IDQpCgp0ZXh0KHggPSAxOTk2LCB5ID0geW1heCoxLjEsICdiaWxsaW9uIFVTRCcsIGFkaiA9IGMoMSwwKSkKCnZhbHVlbG9zc19hbGwkdG90YWxldltpbmRdICU+JSAKICB0ZXh0KHZhbHVlbG9zc19hbGwkeWVhcltpbmRdLCAKICAgICAgIC4sCiAgICAgICByb3VuZCguKSwKICAgICAgIGNvbCA9IGJhc2Vjb2xbMV0sCiAgICAgICBhZGogPSBjKDAuNSwwKSkKCnZhbHVlbG9zc19hbGwkbnVyc19leHBlbnNlW2luZF0gJT4lIAogIHRleHQodmFsdWVsb3NzX2FsbCR5ZWFyW2luZF0sIAogICAgIC4sCiAgICAgcm91bmQoLiksCiAgICAgY29sID0gJ2dyZXkxMCcsCiAgICAgYWRqID0gYygwLDEpKQoKdmFsdWVsb3NzX2FsbCR0b3RhbHZhbHVlbG9zc1tpbmRdICU+JSAKICB0ZXh0KHZhbHVlbG9zc19hbGwkeWVhcltpbmRdLCAKICAgICAgIC4sCiAgICAgICByb3VuZCguKSwKICAgICAgIGNvbCA9IHZsX2NvbCwKICAgICAgIGFkaiA9IGMoMSwwKSkKCnZhbHVlbG9zc19hbGwkc3VycmVuZGVyX2JlbmVmaXRbaW5kXSAlPiUgCiAgdGV4dCh2YWx1ZWxvc3NfYWxsJHllYXJbaW5kXSwgCiAgICAgICAuLAogICAgICAgcm91bmQoLiksCiAgICAgICBjb2wgPSBiYXNlY29sWzNdLAogICAgICAgYWRqID0gYygwLjUsMCkpCgpsZWdlbmQoCiAgJ3RvcGxlZnQnLAogIGJ0eSA9ICduJywKICBsZWdlbmQgPSBjKCdFY29ub21pYyB2YWx1ZSBvZiB0ZXJtaW5hdGVkIHBvbGljaWVzIChFViknLAogICAgICAgICAgICAgJ1N1cnJlbmRlciBiZW5lZml0IG9mIHRlcm1pbmF0ZWQgcG9saWNpZXMgKFNCKScsCiAgICAgICAgICAgICAnVmFsdWUgbG9zcyBkdWUgdG8gdGVybWluYXRpb24gKEVWLVNCKScsCiAgICAgICAgICAgICAnTnVyc2luZyBjYXJlIHNwZW5kaW5nJyksCiAgbHR5ID0gYygxLDEsMSwyKSwKICBsd2QgPSAyLAogIGNvbCA9IGMoYmFzZWNvbFtjKDEsMyldLCB2bF9jb2wsICdncmV5MTAnKSwKICBjZXggPSAwLjgKKQpgYGAKCgojIFJlZmVyZW5jZXMgey19Cg==