Executive Summary

The purpose of this documentation is to outline my data exploration process to determine the research potential of the 2017 residential building stock assessment (RBSA) dataset completed by the Northwest Energy Efficiency Association (NEEA). Results from the exploratory data analysis suggest that the RBSA data is a valuable dataset for identifying energy consumption and equity issues. The RBSA allows researchers to identify energy efficiency opportunities, the efficiency of specific appliances, and much more. The RBSA dataset includes residential demographic data, allowing researchers to disaggregate energy efficiency by family size, income, education level, age, and other demographic constructs. However, the RBSA demographic dataframe does not provide race/ethnicity nor gender data. More research opportunities become available when the RBSA data is merged with other dataframes. For example, Buylova (2020) was able to identify which regions in Oregon and racial/ethnic groups were more susceptible to high energy burden by combining the RBSA data with the American Community Survey (ACS) data.

This document loosely follows the methods Buylova employed to conduct her analysis. Buylova’s analysis included housing variables and household characteristic variables (see Appendix A for more information). My data exploration includes cleaning and wrangling the RBSA data to create the same variables Buylova used and more. As aforementioned, Buylova (2020) used the RBSA data completed by the NEEA in 2017 and the 2012-2017 ACS data to investigate the dynamics between energy use and socio-demographic characteristics in spatial modeling of residential energy consumption. The underlying research inquiry guiding my exploratory analysis of the RBSA data is the confluence of energy cost and housing burden.

The Department of Housing and Urban Development (HUD) considers people spending more than 30% of their income on housing as housing burdened. Housing costs include rent, mortgage payment, property taxes, utilities, and housing insurance (Lin, 2018). There has recently been a focus on how energy prices, i.e., utilities, contribute to housing burden. Energy bills of more than 6-10% of income are considered unaffordable (Hernandez & Bird, 2010; Heindl, 2015; Kontokosta et al., 2019). Previous research demonstrates that the energy cost burden disproportionately affects lower-income households because they are most at risk for living in substandard and inefficient housing (Hernandez & Phillips, 2015). Energy upgrades can help alleviate energy cost burden and potentially housing burden by saving a low-income multi-family household up to $1,500 per year per household (Kontokosta et al., 2019).

Energy cost burden is a function of both income and energy consumption. Drehobl and Ross (2016) found that an average low-income household energy burden was 7.2% higher than an average higher-income household energy burden of 2.3%. Findings from a federal energy assistance program evaluation determined that low-income households represent 92% of all households with an energy burden of 10% (APPRISE, 2005). The Federal Low-Income Home Energy Assistance Program designs its funding distribution mechanism based on energy burden levels; income is used as the primary qualifier for this program.

This document is organized into five sections to illustrate the potential of the RBSA data. Section 1 describes the data; section 2 outlines the data cleaning and wrangling process; section 3 examines ethical considerations for using the data; section 4 suggests inferential and machine learning models that can be done with the data. Finally, section 5 concludes by providing uses of the RBSA data when merged with other data.

Suggested Readings:

Buylova, A. (2020). Spotlight on energy efficiency in Oregon: Investigating dynamics between energy use and socio-demographic characteristics in spatial modeling of residential energy consumption. Energy Policy, 140, 111439.

Kontokosta, C. E., Reina, V. J., & Bonczak, B. (2020). Energy cost burdens for low-income and minority households: Evidence from energy benchmarking and audit data in five US cities. Journal of the American Planning Association, 86(1), 89-105.


Packages

#packages used in this analysis

if(!require(readr)){
    install.packages("readr", dependencies = TRUE)
    library(readr)
}
if(!require(ggplot2)){
    install.packages("ggplot2", dependencies = TRUE)
    library(ggplot2)
}
if(!require(dplyr)){
    install.packages("dplyr", dependencies = TRUE)
    library(dplyr)
}
if(!require(tidyr)){
    install.packages("tidyr", dependencies = TRUE)
    library(tidyr)
}
if(!require(janitor)){
    install.packages("janitor", dependencies = TRUE)
    library(janitor)
}
if(!require(forcats)){
    install.packages("forcats", dependencies = TRUE)
    library(forcats)
}

if(!require(DataExplorer)){
    install.packages("DataExplorer", dependencies = TRUE)
    library(DataExplorer)
}

if(!require(stringr)){
    install.packages("stringr", dependencies = TRUE)
    library(stringr)
}

if(!require(lubridate)){
    install.packages("lubridate", dependencies = TRUE)
    library(lubridate)
}

Section 1: Data Description

Key Steps

  1. Explored and discovered existing data documentation
  2. Identified data frames of interest
  3. Discerned relationship between dataframes

This data is from the Residential Building Stock Assessment (RBSA) conducted in 2016-17 (the specific data collection months are unclear, the 2022 RBSA data collection is scheduled for June and July). It includes a representative sample of single-family, multi-family, and manufactured homes gathered across the Northwest region. It has 47 comma-separated variable (CSV) tabular dataframes that includes a representative sample of 1,130 single-family, 230 multi-family, and 550 manufactured homes gathered across the Northwest region. Participants are recruited based on a random selection of single-family residential USPS addresses for the single-family component. For the multi-family component, the study recruited multi-family buildings to participate in the survey and then identified tenants in those buildings willing to participate. Two auditors performed each site visit. Audits lasted approximately two hours and covered all of the major components of the homes that can be linked to the household’s overall energy use, including building envelope, HVAC systems, lighting, appliances, electronics, and water technologies. In addition, the RBSA audit data was combined with self-reported home characteristics and demographics data collected in the phone survey during the recruitment of an on-site sample. Supporting documentation of the RBSA data can be found here.

The RBSA dataset comprises 49 files: 47 CSV files, one .txt ReadMe, and an excel spreadsheet with unique dataset values. One of the CSV tables is a data dictionary that describes the column names in each CSV table. The size of the CSV files ranges from 2 KB to 16.6 MB. The smallest table contains 11 columns and 14 rows/observations, while the largest has 249 columns and 15561 rows/observations. The ReadMe details changes to the RBSA dataset; changes and updates are numbered and organized by date. Each row in a table has a unique primary key (PK), making it possible to reference that specific object and may include other relational keys (CKs) that make it possible to relate to other tables in the dataset. Most tables/dataframes can be joined using the CK_SiteID and the CK_RoomID.

The RBSA dataset houses data for manufactured homes, single-family homes, and multi-family residences. Within the dataset, data are attributed to a Site or a Building. Building data include information collected for nonresidential portions of a multi-family building. Site data include data collected for the entirety of a single-family or manufactured home and for residences visited at a multi-family building. The dataset denotes data associated with a Site by a CK_SiteID or PK_SiteID beginning with “SITE”; the dataset denotes data associated with a Building by a CK_SiteID or PK_SiteID beginning with “BLDG.”

#Import the RBSA dataframes of interest

ols_df <- read_csv("RBSA-II-Combined-Database/One Line Summary.csv")

demog <- read_csv("RBSA-II-Combined-Database/SiteInterview_Demographics.csv")

energyuse_df <- read_csv("RBSA-II-Combined-Database/SiteInterview_HomeEnergyUse.csv") #has data on energy use and energy star appliances

Section 2: Data Journey

Key Steps

  1. Explored the data
  2. Identified and merged dataframes of interest
  3. Subset the data for the region of interest
  4. Explored data and selected variables of interest
    1. explanatory variables based on Buylova paper
  5. Recoded and reclassified data
  6. Transformed variables of interest
  7. Created EUI variable
    1. response variable based on Buylova paper

The data cleaning and wrangling process took place in RStudio, using base R and Tidyverse syntax. The data cleaning and wrangling process included 1) removing unwanted variables, 2) checking data for accuracy, 3) handling missing data, 4) ensuring consistency across variable types, and 5) checking validity – does the data make sense? The first step in the cleaning process involved identifying useful variables within the RBSA dataset to replicate Buylova’s methods. The “One Line Summary” and “Site Interview Demographics” dataframes had the necessary variables to recreate the regression model conducted by Buylova.

Dplyr from the Tidyverse was used to merge the “Site Interview Demographics” to the “One Line Summary” dataframe. The “One Line Summary” dataframe has energy consumption, geographic location, and building information. The primary key for the merger was the “DB_SiteID” and “CK_SiteID.” The “Site Interview Demographics” dataframe included demographic information, such as resident’s income, age, and ownership status (renter or buyer).

After the merger, the dataframe was subsetted for the “Puget Sound” region. Next, housing and household characteristic variables, as outlined by the Buylova (2020) paper, were selected to create the analytical dataframe (refer to Appendix A to learn more about the housing and household characteristic variables). The EUI, the response variable, was created by dividing the total annual energy consumption (which is in British Thermal Units (kBTU)) by the conditioned living area of the home (sq. foot). Variables with kBTU units were identified and summed to create a total annual energy use variable. Once the analytic dataframe had all the necessary variables, I checked for missingness.

The first attempt to check for missing data resulted in 7301 missing data. Upon further examination, I noticed there was missing data in the RBSA dataset coded as “unknown,” “prefer not to say,” and as the character value “N/A.” I recoded variables with those observations as NA (missing). Many variables needed to be transformed to replicate the Buylova (2020) model, such as age, income, and the total occupants. The income variable was a character variable that provided an income range. I split the income variable into low_end and high_end income variables then took the average of the low_end and high_end income to create an average income variable. Finally, I used the “janitor” package to make every variable consistent - lowercase and snake case.

#Explore the one line summary dataframe
introduce(ols_df)
#Explore the demographic dataframe 
introduce(demog)
#Merge ols_df to demog
  ols_demog <- left_join(ols_df, demog, by = c("DB_SiteID" = "CK_SiteID"))

# Only get sites in Puget Sound Region
pug_sound_ols <- ols_demog %>%
  filter(Region == "Puget Sound")
#Explore the Puget Sound Data
introduce(pug_sound_ols)
#Select variables of interest
pug_short <- pug_sound_ols %>%
  select(`Cadmus ID`, State, County,Region, `Home Type - FMP Detailed`, `Home Type - Final`, `Year Built`,`Primary Heating System`, `Qty Bedrooms`,`Reported Income`, `Do you own or rent your home`, Ownership, `Qty Occupants Between 65 Years or Older`, `Qty Occupants Between Less than 1 Year`, `Qty Occupants Between 6 and 10 Years`, `Qty Occupants.x`, `Qty Occupants.y`, `Qty Occupants Between Less than 1 Year`, `Qty Occupants Between 1 and 5 Years`, `Qty Occupants Between 6 and 10 Years`, `Qty Occupants Between 11 and 18 Years`, `Qty Occupants Between 19 and 45 Years`, `Qty Occupants Between 46 and 64 Years`, `Qty Occupants Between 65 Years or Older`, `Conditioned Area`, contains("kBtu"))
#Explore the Pug_short Data
introduce(pug_short)
#Data Cleaning and wrangling

# Change "prefer not say", "Unkown", and N/A to NAs
pug_short[pug_short == "Unknown" | pug_short == "Prefer not to say" | pug_short == "N/A"] <- NA

#Change year built variable into a date variable, instead of character 
pug_short$`Year Built` <- as.Date(as.character(pug_short$`Year Built`), format = "%Y")
pug_short$`Year Built` <- year(pug_short$`Year Built`)

#Make a variable to get the decade each building was built 
pug_short <- pug_short %>%
  mutate(year_built_decade = 10*(`Year Built` %/% 10),
         year_built_decade = factor(year_built_decade))

##Turn Certain variables into factors
pug_short_clean <- pug_short %>%
  mutate(across(c(`Home Type - FMP Detailed`, `Primary Heating System`,`Home Type - Final`,`Do you own or rent your home`:Ownership, County),as.factor))

#Transform a age variables to the following: 1) less than 1 to 5, 2) 6-18, 3) 19-64, 4) 65 and up
pug_short_clean_age <- pug_short_clean %>%
  rowwise() %>%
  mutate(
    age_zero_to_five = sum(`Qty Occupants Between Less than 1 Year`, `Qty Occupants Between 1 and 5 Years`),
    age_six_to_eighteen = sum(`Qty Occupants Between 6 and 10 Years`, `Qty Occupants Between 11 and 18 Years`),
    age_nineteen_to_sixtyfour = sum(`Qty Occupants Between 19 and 45 Years`, `Qty Occupants Between 46 and 64 Years`),
    age_sixtyfive_plus = `Qty Occupants Between 65 Years or Older`,
    total_occupants = `Qty Occupants.x`)

#Remove original age columns
pug_short_clean_age_short <- pug_short_clean_age %>%
  select(-c(11,13:21))

#Make categorial variable for # of occupants, as done in the Buylova paper
pug_short_occupant <- pug_short_clean_age_short %>%
  mutate(household_size = case_when(
    total_occupants == 1 ~ "one-person",
    total_occupants == 2 ~ "two people",
    total_occupants == 3 ~ "three people",
    total_occupants >= 4 ~ "four or more"))

#Turn household size variable into a factor
pug_short_occupant$household_size <- factor(pug_short_occupant$household_size, levels = c("one-person", "two people", "three people", "four or more"))


# Make a binary children and elderly variable, elderly is anyone who is 65 and older, children is anyone 0-18 years old
pug_short_elder <- pug_short_occupant %>%
  mutate(elderly = if_else(age_sixtyfive_plus >= 1, "yes", "no")) %>%
  mutate( children = if_else(age_zero_to_five | age_six_to_eighteen >= 1, "yes", "no"))

#Set factor levels for elderly and children binary variables
pug_short_elder$elderly <- factor(pug_short_elder$elderly, levels = c("yes", "no"))
pug_short_elder$children <- factor(pug_short_elder$children, levels = c("yes", "no"))

#Change character variables to numeric
pug_short_elder$`Annual Electric Usage (kBtu)` <- as.numeric(pug_short_elder$`Annual Electric Usage (kBtu)`)
pug_short_elder$`Annual Gas Usage (kBtu)` <- as.numeric(pug_short_elder$`Annual Gas Usage (kBtu)`)
pug_short_elder$`Conditioned Area` <- as.numeric(pug_short_elder$`Conditioned Area`)

#Ceate EUI variable
#pug_short_eui <- 
pug_short_eui <- pug_short_elder %>%
  rowwise() %>% 
  mutate(annual_energy_use = sum(c_across(contains("kBtu")), na.rm = TRUE)) %>% 
  mutate(annual_energy_use = na_if(annual_energy_use, 0)) %>% 
  mutate(eui = annual_energy_use/`Conditioned Area`)

#Tranform the income variable and take the average of the lower-end income and the higher-end income
pug_eui_income <- pug_short_eui %>% 
  mutate(Reported_Income = str_replace(`Reported Income`, "\\s", "_")) %>% 
  separate(Reported_Income, into = c("lower_income", "higher_income"), sep = "_") %>% 
  mutate(lower_income = parse_number(lower_income),
         higher_income = parse_number(higher_income)) %>%
  mutate(lower_income = if_else(is.na(lower_income), higher_income, lower_income),
         higher_income = if_else(is.na(higher_income), lower_income, higher_income)) %>% 
  mutate(Average_Reported_Income = (lower_income+higher_income)/2) %>% 
  clean_names()

# Create Socioeconomic Status (SES) Variable based on average income and household size 
# the low-wage income was based on the Washington State Low-Income Weatherization Program, https://www.commerce.wa.gov/wp-content/uploads/2021/02/2021-WA-Low-Income-Eligiblity-Guidelines.pdf 

# Middle class numbers were derived from DSHS State Median Income Charts. Multiplying monthly income by 11 (months).  https://www.dshs.wa.gov/esa/eligibility-z-manual-ea-z/state-median-income-chart 

#Note that the income numbers are for 2021 and the data is from 2016. More research should be done to better reflect SES in the data

pug_eui <- pug_eui_income %>% 
  mutate(ses = case_when(
    average_reported_income < 31752 ~ "low",
    average_reported_income <= 41521 & total_occupants == 2 ~ "low",
    average_reported_income <= 51291 & total_occupants == 3 ~ "low",
    average_reported_income <= 61061 & total_occupants >= 4 ~ "low",
    average_reported_income = 4454*11 & average_reported_income < 5825*11 & (total_occupants == 1) ~ "middle",
    average_reported_income = 5825*11 & average_reported_income < 7195*11 & (total_occupants >= 2) ~ "middle",
    average_reported_income = 7195*11 & average_reported_income < 8566*11 & (total_occupants >= 3) ~ "middle",
    average_reported_income = 8566*11 & average_reported_income < 9936*11 & (total_occupants >= 4) ~ "middle",
    TRUE ~ "high")) %>%
  mutate(ses = ifelse(is.na(average_reported_income), NA, ses)) %>% 
  mutate(ses = factor(ses, levels = c("low", "middle", "high")))
#Final Analytical Dataframe 
psych::describe(pug_eui, fast = TRUE)

Section 3: Data Assessment

Key Steps

  1. Examined RBSA data affordances and limitations
  2. Read literature on data ethics
  3. Explored data for identifiability
  4. Identified potential data mergers that may raise privacy concerns

Results from the exploratory data analysis suggest that the RBSA data is a valuable dataset for identifying energy consumption and equity issues. The RBSA allows researchers to identify energy efficiency opportunities, the efficiency of specific appliances, and much more. The data includes the residential properties’ zip code, enabling researchers to determine census tracts for geospatial analyses. Furthermore, The RBSA dataset includes residential demographic data, allowing researchers to disaggregate energy efficiency by family size, income, education level, age, and other demographic constructs. However, this analysis only explored 2 of the 47 dataframes (these two were selected because of the richness of the data and its alignment to the Buylova paper). Researchers should conduct further analyses to determine the utility of the other dataframes for answering critical research questions. Lastly, the RBSA demographic dataframe does not provide race/ethnicity or gender data, which can inform racial and gender equity issues regarding housing and energy.

More research opportunities become available when the RBSA data is merged with other dataframes. For example, Buylova (2020) was able to identify which regions in Oregon and racial/ethnic groups were more susceptible to high energy burden by combining the RBSA data with the American Community Survey (ACS) data. Research questions concerning the actual energy cost for specific areas can be answered by determining the price per kWh and creating a regional map displaying the cost of energy and housing. Lastly, the RBSA data is limited in examining the temporal variation in the energy cost burden associated with changing energy prices. Additional datasets are needed to answer such questions. However, each new research question and analysis about housing and people’s geographic location warrants careful ethical considerations.

Data is not neutral. People use data to convey a narrative about individuals, organizations, institutions, and the environment. As a result, data has the power to shape people’s worldviews and influence their decisions. The depth and breadth of the RBSA data provide researchers and analysts with a myriad of analytical options and narratives they can tell. While data ought to be public and democratized, it can lead to bad actors using data to reify inequities. Users of the RBSA data should be mindful of the narrative they are telling with their data analysis and how their research can potentially be used to do harm.

Identifiability is becoming less of a binary and more of a continuum. In other words, privacy is not about private or public, but about how much information is disclosed, which can make certain groups and individuals more seen. The RBSA is publicly available data that does not disclose individual addresses or people’s names. However, a person’s zip code, type of house, annual income, and the age of the homeowners/residents can result in individual houses becoming more identifiable. Disclosure risks increase with dimensionality (more variables), linking multiple data sources, and using data analytics. This may run the risk of not adequately protecting vulnerable groups in the dataset. For example, if this data is merged with other data sets, someone can identify households comprised of only older adults or single people. This is a cause for concern for these vulnerable groups. Geospatial analyses need to be done with care to mitigate the potential for identifying people.

Suggested Readings:

Corti, L. & Bishop, L (year).Legal and ethical challenges surrounding big data: energy data

McKenna, E., Richardson, I., & Thomson, M. (2012). Smart meter data: Balancing consumer privacy concerns with legitimate applications. Energy Policy, 41, 807-814.

pug_eui %>%
  filter(!primary_heating_system %in% c("Geothermal Heat Pump", "Radiant Heat")) %>%
  filter(!(ses %in% NA )) %>% 
ggplot() + geom_bar(aes(primary_heating_system, eui, fill = ses), 
                    stat = "summary", 
                    fun.y = "mean",
                    position = "dodge") +
  labs(title= "Average Energy Use Intensity by Heating System", 
       subtitle = "Puget Sound Region", 
       x = "Primary Heating System", 
       y = "Energy Use Intensity (kBtu/ft2)",
       fill = "Socioeconomic Class") +
  theme_bw() +
  scale_fill_manual(values=c("#1b9e77","#d95f02","#7570b3")) +
  #theme(legend.position = "none") +
  coord_flip()

pug_eui %>%
  filter(!primary_heating_system %in% c("Geothermal Heat Pump", "Radiant Heat")) %>%
  filter(!(ses %in% NA )) %>% 
ggplot() + geom_bar(aes(primary_heating_system, conditioned_area, fill = ses), 
                    stat = "summary", 
                    fun.y = "mean",
                    position = "dodge") +
  labs(title= "Average Square Footage by Heating System", 
       subtitle = "Puget Sound Region", 
       x = "Primary Heating System", 
       y = "Conditioned Area (sq. ft)",
       fill = "Socioeconomic Class") +
  theme_bw() +
  scale_fill_manual(values=c("#1b9e77","#d95f02","#7570b3")) +
  coord_flip()

pug_eui %>%
  filter(!primary_heating_system %in% c("Geothermal Heat Pump", "Radiant Heat")) %>%
  filter(!(ses %in% NA )) %>% 
ggplot() + geom_bar(aes(primary_heating_system, annual_energy_use, fill = ses), 
                    stat = "summary", 
                    fun.y = "mean",
                    position = "dodge") +
  labs(title= "Average Energy Use Intensity by Heating System and Household Size", 
       subtitle = "Puget Sound Region", 
       x = "Primary Heating System", 
       y = "Annual Energy Use",
       fill = "Socioeconomic Class") +
  theme_bw() +
  scale_fill_manual(values=c("#1b9e77","#d95f02","#7570b3")) +
  #theme(legend.position = "none") +
  coord_flip() + 
  facet_wrap(~household_size)


Section 4: Modeling

Key Steps

  1. Replicated Buylova Model
  2. Provided alternative Models

The RBSA dataset was cleaned, wrangled, and explored to understand its potential to answer critical research questions centered on the intersection of energy use and equity. The data exploration was guided by the methods employed by Buylova’s (2020) paper, which used RBSA and ACS data to understand energy equity in Oregon. I used housing and household characteristic variables (Check Appendix A for more information) to replicate Buylova’s OLS regression model. The response variable in Buylova’s model was resident’s energy use intensity (EUI), calculated by dividing annual energy use by the home’s square footage. The model included several explanatory variables, such as income level.

Instead of creating the same income levels Buylova used, I developed a socioeconomic status (SES) variable indicating whether a person was in a low, middle, or high-income class. A person’s SES was calculated by determining income cutoff points based on household size and what is considered a livable wage in the Puget Sound Region for 2020. Future researchers should develop a more accurate measure of a livable wage in the Puget Sound Region for 2017 - when the data was collected. Additionally, the EUI variable had over 200 missing observations due to apartment buildings not reporting energy use in this dataframe. Further investigation should be done to account for the missing apartment EUI information or possibly conduct an imputation.

Future modeling may include a machine learning model to examine multicollinearity between variables and identify variables that have the most significant impact on energy use. Further, a machine learning regression model can be applied to determine which homes will most likely have a high energy use. The results can then be mapped to quickly identify which regions and groups of people in the Puget Sound are more susceptible to high energy use based on specific variables in the data.

#model  
lm(eui ~ home_type_final + year_built_decade + primary_heating_system + qty_bedrooms + average_reported_income + elderly + children + household_size + ownership, data = pug_eui) %>%
  broom::tidy()

lm(eui ~ home_type_final + year_built_decade + primary_heating_system + qty_bedrooms + average_reported_income + elderly + children + household_size + ownership, data = pug_eui) %>%
  broom::glance()

Section 5: Future work

Key Steps

  1. Identified secondary datasets
  2. Developed alternative research questions

The RBSA data exploration was guided by how Buylova (2020) used the RBSA data to investigate the dynamics between energy use and socio-demographic characteristics in spatial modeling of residential energy consumption. Buylova’s investigation was done by merging the RBSA data with ACS data. It has yet to be seen what other data sources researchers can use alongside the RBSA dataset and what questions they can answer. This section attempts to imagine innovative approaches to using the RBSA dataset to answer relevant and critical questions.

The RBSA data could potentially be paired with housing data, such as the Washington Merged Longitudinal Administrative Data (WMLAD) or Zillow data to illustrate a clearer picture of housing burden in Washington State or specifically the Puget Sound region. Housing burden measures include rent, transportation, and utilities. WMLAD provides rent and transportation, while RBSA provides utility data. Paired with existing housing data, like WMLAD, the RBSA data can create a latent variable for housing burden that may have policy implications. The latent housing burden variable may include a person’s monthly rent, commute, and energy costs. Combining this data could help make a case for more energy-efficient policies in the Puget Sound or promote other policy levers to mitigate housing burden.

During the RBSA data exploration, I found other datasets for further analysis. Specifically, data from the Residential Energy Consumption Survey (RECS) administered by the US Energy Information Administration (EIA). RECS is a nationally representative sample of housing. Since 1980, EIA has collected energy characteristics on housing units, usage patterns, and household demographics every four years. Researchers can create a longitudinal dataset with the RECS data to model historical state trends in energy consumption or build a robust model to predict energy consumption across the state of Washington. However, there are restrictions to the RECS data. Researchers could obtain full access to the RECS data by developing a data-sharing agreement.

Researchers can use local county assessor data to calculate the energy use of every building in a local area. For example, King County’s assessor’s office provides data on residential buildings’ appraisal history, taxes, property sales, condition, size, and much more for every building in King County. The estimates generated from the model with the RBSA data can be applied to these data to calculate housing affordability in a specific locality. King County’s Department of Assessment has buildings’ value history from 1997 to 2012. Future researchers should merge and analyze value history data to illustrate pricing and affordability trends in King County.

Energy consumption doesn’t just have a costly effect on individual households; it also has deleterious environmental implications. As a result, reducing energy consumption in densely populated areas is of great importance. Researchers should focus on residential energy consumption and commercial buildings’ energy consumption. The Building Energy Benchmarking dataset, constructed by Seattle’s Building Energy Benchmarking and Reporting Program, provides sufficient information to examine how residential and commercial buildings contribute to high energy use. The dataset contains data of the building’s EUI and physical conditions, including energy star scores.

There is a wealth of energy datasets with important information waiting to be analyzed. The Duke Initiative houses a collection of energy data and tools supported by the National Science Foundation. Some of the datasets contain information about renewable energy, electricity, the environment, buildings, transportation, and much more. The datasets and readings suggested throughout this document can be found in the Appendix.

Appendices

Appendix A: Buylova (2020) variables of interest

Housing Characteristics:

  1. Type of housing
  2. Year of construction
  3. Primary heating
  4. Number of bedrooms

Household Characteristics:

  1. Income
  2. Ownership
  3. Elderly - older than 65
  4. Children
  5. Household size

Appendix D: Git Resources

The GitHub reposiory for this analysis can be found here

Link: https://github.com/fosterj3/IDL.git

LS0tCnRpdGxlOiAiRW5lcmd5IEVxdWl0eSBQcm9qZWN0IgpzdWJ0aXRsZTogIkV4cGxvcmluZyB0aGUgdXRpbGl0eSBvZiBSQlNBIGRhdGEgZm9yIGEgRGF0YSBTY2llbmNlIGZvciBTb2NpYWwgR29vZCBQcm9qZWN0IgphdXRob3I6ICJKYW1lcyBMYW1hciBGb3N0ZXIiCgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRoZW1lOiBjb3NtbwogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCi0tLQoKPGhlYWQ+CiAgPGJhc2UgdGFyZ2V0PSJfdG9wIj4KPC9oZWFkPgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UgKQoKI2NsZWFyIG1lbW9yeQpybShsaXN0ID0gbHMoKSkKI3BlbmFsaXplIGV4Y2Vzc2l2ZSBzaWduaWZpY2FudCBmaWd1cmVzCm9wdGlvbnMoZGlnaXRzID0gMykKI3ByZXZlbnRpbmcgc2NpZW50aWZpYyBub3RhdGlvbgpvcHRpb25zKHNjaXBlbiA9IDEwKQpgYGAKCiFbXShlU2NpZW5jZS5wbmcpCgotLS0KCiMgRXhlY3V0aXZlIFN1bW1hcnkKVGhlIHB1cnBvc2Ugb2YgdGhpcyBkb2N1bWVudGF0aW9uIGlzIHRvIG91dGxpbmUgbXkgZGF0YSBleHBsb3JhdGlvbiBwcm9jZXNzIHRvIGRldGVybWluZSB0aGUgcmVzZWFyY2ggcG90ZW50aWFsIG9mIHRoZSAyMDE3IHJlc2lkZW50aWFsIGJ1aWxkaW5nIHN0b2NrIGFzc2Vzc21lbnQgKFJCU0EpIGRhdGFzZXQgY29tcGxldGVkIGJ5IHRoZSBOb3J0aHdlc3QgRW5lcmd5IEVmZmljaWVuY3kgQXNzb2NpYXRpb24gKE5FRUEpLiBSZXN1bHRzIGZyb20gdGhlIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMgc3VnZ2VzdCB0aGF0IHRoZSBSQlNBIGRhdGEgaXMgYSB2YWx1YWJsZSBkYXRhc2V0IGZvciBpZGVudGlmeWluZyBlbmVyZ3kgY29uc3VtcHRpb24gYW5kIGVxdWl0eSBpc3N1ZXMuIFRoZSBSQlNBIGFsbG93cyByZXNlYXJjaGVycyB0byBpZGVudGlmeSBlbmVyZ3kgZWZmaWNpZW5jeSBvcHBvcnR1bml0aWVzLCB0aGUgZWZmaWNpZW5jeSBvZiBzcGVjaWZpYyBhcHBsaWFuY2VzLCBhbmQgbXVjaCBtb3JlLiBUaGUgUkJTQSBkYXRhc2V0IGluY2x1ZGVzIHJlc2lkZW50aWFsIGRlbW9ncmFwaGljIGRhdGEsIGFsbG93aW5nIHJlc2VhcmNoZXJzIHRvIGRpc2FnZ3JlZ2F0ZSBlbmVyZ3kgZWZmaWNpZW5jeSBieSBmYW1pbHkgc2l6ZSwgaW5jb21lLCBlZHVjYXRpb24gbGV2ZWwsIGFnZSwgYW5kIG90aGVyIGRlbW9ncmFwaGljIGNvbnN0cnVjdHMuIEhvd2V2ZXIsIHRoZSBSQlNBIGRlbW9ncmFwaGljIGRhdGFmcmFtZSBkb2VzIG5vdCBwcm92aWRlIHJhY2UvZXRobmljaXR5IG5vciBnZW5kZXIgZGF0YS4gTW9yZSByZXNlYXJjaCBvcHBvcnR1bml0aWVzIGJlY29tZSBhdmFpbGFibGUgd2hlbiB0aGUgUkJTQSBkYXRhIGlzIG1lcmdlZCB3aXRoIG90aGVyIGRhdGFmcmFtZXMuIEZvciBleGFtcGxlLCBCdXlsb3ZhICgyMDIwKSB3YXMgYWJsZSB0byBpZGVudGlmeSB3aGljaCByZWdpb25zIGluIE9yZWdvbiBhbmQgcmFjaWFsL2V0aG5pYyBncm91cHMgd2VyZSBtb3JlIHN1c2NlcHRpYmxlIHRvIGhpZ2ggZW5lcmd5IGJ1cmRlbiBieSBjb21iaW5pbmcgdGhlIFJCU0EgZGF0YSB3aXRoIHRoZSBBbWVyaWNhbiBDb21tdW5pdHkgU3VydmV5IChBQ1MpIGRhdGEuCgpUaGlzIGRvY3VtZW50IGxvb3NlbHkgZm9sbG93cyB0aGUgbWV0aG9kcyBCdXlsb3ZhIGVtcGxveWVkIHRvIGNvbmR1Y3QgaGVyIGFuYWx5c2lzLiBCdXlsb3ZhJ3MgYW5hbHlzaXMgaW5jbHVkZWQgaG91c2luZyB2YXJpYWJsZXMgYW5kIGhvdXNlaG9sZCBjaGFyYWN0ZXJpc3RpYyB2YXJpYWJsZXMgKHNlZSBBcHBlbmRpeCBBIGZvciBtb3JlIGluZm9ybWF0aW9uKS4gTXkgZGF0YSBleHBsb3JhdGlvbiBpbmNsdWRlcyBjbGVhbmluZyBhbmQgd3JhbmdsaW5nIHRoZSBSQlNBIGRhdGEgdG8gY3JlYXRlIHRoZSBzYW1lIHZhcmlhYmxlcyBCdXlsb3ZhIHVzZWQgYW5kIG1vcmUuIEFzIGFmb3JlbWVudGlvbmVkLCBCdXlsb3ZhICgyMDIwKSB1c2VkIHRoZSBSQlNBIGRhdGEgY29tcGxldGVkIGJ5IHRoZSBORUVBIGluIDIwMTcgYW5kIHRoZSAyMDEyLTIwMTcgQUNTIGRhdGEgdG8gaW52ZXN0aWdhdGUgdGhlIGR5bmFtaWNzIGJldHdlZW4gZW5lcmd5IHVzZSBhbmQgc29jaW8tZGVtb2dyYXBoaWMgY2hhcmFjdGVyaXN0aWNzIGluIHNwYXRpYWwgbW9kZWxpbmcgb2YgcmVzaWRlbnRpYWwgZW5lcmd5IGNvbnN1bXB0aW9uLiBUaGUgdW5kZXJseWluZyByZXNlYXJjaCBpbnF1aXJ5IGd1aWRpbmcgbXkgZXhwbG9yYXRvcnkgYW5hbHlzaXMgb2YgdGhlIFJCU0EgZGF0YSBpcyB0aGUgY29uZmx1ZW5jZSBvZiBlbmVyZ3kgY29zdCBhbmQgaG91c2luZyBidXJkZW4uCgpUaGUgRGVwYXJ0bWVudCBvZiBIb3VzaW5nIGFuZCBVcmJhbiBEZXZlbG9wbWVudCAoSFVEKSBjb25zaWRlcnMgcGVvcGxlIHNwZW5kaW5nIG1vcmUgdGhhbiAzMCUgb2YgdGhlaXIgaW5jb21lIG9uIGhvdXNpbmcgYXMgaG91c2luZyBidXJkZW5lZC4gSG91c2luZyBjb3N0cyBpbmNsdWRlIHJlbnQsIG1vcnRnYWdlIHBheW1lbnQsIHByb3BlcnR5IHRheGVzLCB1dGlsaXRpZXMsIGFuZCBob3VzaW5nIGluc3VyYW5jZSAoTGluLCAyMDE4KS4gVGhlcmUgaGFzIHJlY2VudGx5IGJlZW4gYSBmb2N1cyBvbiBob3cgZW5lcmd5IHByaWNlcywgaS5lLiwgdXRpbGl0aWVzLCBjb250cmlidXRlIHRvIGhvdXNpbmcgYnVyZGVuLiBFbmVyZ3kgYmlsbHMgb2YgbW9yZSB0aGFuIDYtMTAlIG9mIGluY29tZSBhcmUgY29uc2lkZXJlZCB1bmFmZm9yZGFibGUgKEhlcm5hbmRleiAmIEJpcmQsIDIwMTA7IEhlaW5kbCwgMjAxNTsgS29udG9rb3N0YSBldCBhbC4sIDIwMTkpLiBQcmV2aW91cyByZXNlYXJjaCBkZW1vbnN0cmF0ZXMgdGhhdCB0aGUgZW5lcmd5IGNvc3QgYnVyZGVuIGRpc3Byb3BvcnRpb25hdGVseSBhZmZlY3RzIGxvd2VyLWluY29tZSBob3VzZWhvbGRzIGJlY2F1c2UgdGhleSBhcmUgbW9zdCBhdCByaXNrIGZvciBsaXZpbmcgaW4gc3Vic3RhbmRhcmQgYW5kIGluZWZmaWNpZW50IGhvdXNpbmcgKEhlcm5hbmRleiAmIFBoaWxsaXBzLCAyMDE1KS4gRW5lcmd5IHVwZ3JhZGVzIGNhbiBoZWxwIGFsbGV2aWF0ZSBlbmVyZ3kgY29zdCBidXJkZW4gYW5kIHBvdGVudGlhbGx5IGhvdXNpbmcgYnVyZGVuIGJ5IHNhdmluZyBhIGxvdy1pbmNvbWUgbXVsdGktZmFtaWx5IGhvdXNlaG9sZCB1cCB0byAkMSw1MDAgcGVyIHllYXIgcGVyIGhvdXNlaG9sZCAoS29udG9rb3N0YSBldCBhbC4sIDIwMTkpLgoKRW5lcmd5IGNvc3QgYnVyZGVuIGlzIGEgZnVuY3Rpb24gb2YgYm90aCBpbmNvbWUgYW5kIGVuZXJneSBjb25zdW1wdGlvbi4gRHJlaG9ibCBhbmQgUm9zcyAoMjAxNikgZm91bmQgdGhhdCBhbiBhdmVyYWdlIGxvdy1pbmNvbWUgaG91c2Vob2xkIGVuZXJneSBidXJkZW4gd2FzIDcuMiUgaGlnaGVyIHRoYW4gYW4gYXZlcmFnZSBoaWdoZXItaW5jb21lIGhvdXNlaG9sZCBlbmVyZ3kgYnVyZGVuIG9mIDIuMyUuIEZpbmRpbmdzIGZyb20gYSBmZWRlcmFsIGVuZXJneSBhc3Npc3RhbmNlIHByb2dyYW0gZXZhbHVhdGlvbiBkZXRlcm1pbmVkIHRoYXQgbG93LWluY29tZSBob3VzZWhvbGRzIHJlcHJlc2VudCA5MiUgb2YgYWxsIGhvdXNlaG9sZHMgd2l0aCBhbiBlbmVyZ3kgYnVyZGVuIG9mIDEwJSAoQVBQUklTRSwgMjAwNSkuIFRoZSBGZWRlcmFsIExvdy1JbmNvbWUgSG9tZSBFbmVyZ3kgQXNzaXN0YW5jZSBQcm9ncmFtIGRlc2lnbnMgaXRzIGZ1bmRpbmcgZGlzdHJpYnV0aW9uIG1lY2hhbmlzbSBiYXNlZCBvbiBlbmVyZ3kgYnVyZGVuIGxldmVsczsgaW5jb21lIGlzIHVzZWQgYXMgdGhlIHByaW1hcnkgcXVhbGlmaWVyIGZvciB0aGlzIHByb2dyYW0uCgpUaGlzIGRvY3VtZW50IGlzIG9yZ2FuaXplZCBpbnRvIGZpdmUgc2VjdGlvbnMgdG8gaWxsdXN0cmF0ZSB0aGUgcG90ZW50aWFsIG9mIHRoZSBSQlNBIGRhdGEuIFNlY3Rpb24gMSBkZXNjcmliZXMgdGhlIGRhdGE7IHNlY3Rpb24gMiBvdXRsaW5lcyB0aGUgZGF0YSBjbGVhbmluZyBhbmQgd3JhbmdsaW5nIHByb2Nlc3M7IHNlY3Rpb24gMyBleGFtaW5lcyBldGhpY2FsIGNvbnNpZGVyYXRpb25zIGZvciB1c2luZyB0aGUgZGF0YTsgc2VjdGlvbiA0IHN1Z2dlc3RzIGluZmVyZW50aWFsIGFuZCBtYWNoaW5lIGxlYXJuaW5nIG1vZGVscyB0aGF0IGNhbiBiZSBkb25lIHdpdGggdGhlIGRhdGEuIEZpbmFsbHksIHNlY3Rpb24gNSBjb25jbHVkZXMgYnkgcHJvdmlkaW5nIHVzZXMgb2YgdGhlIFJCU0EgZGF0YSB3aGVuIG1lcmdlZCB3aXRoIG90aGVyIGRhdGEuCgojIyMgU3VnZ2VzdGVkIFJlYWRpbmdzOgoKW0J1eWxvdmEsIEEuICgyMDIwKS4gU3BvdGxpZ2h0IG9uIGVuZXJneSBlZmZpY2llbmN5IGluIE9yZWdvbjogSW52ZXN0aWdhdGluZyBkeW5hbWljcyBiZXR3ZWVuIGVuZXJneSB1c2UgYW5kIHNvY2lvLWRlbW9ncmFwaGljIGNoYXJhY3RlcmlzdGljcyBpbiBzcGF0aWFsIG1vZGVsaW5nIG9mIHJlc2lkZW50aWFsIGVuZXJneSBjb25zdW1wdGlvbi4gRW5lcmd5IFBvbGljeSwgMTQwLCAxMTE0MzkuXShodHRwczovL3d3dy5zY2llbmNlZGlyZWN0LmNvbS9zY2llbmNlL2FydGljbGUvcGlpL1MwMzAxNDIxNTIwMzAxOTIwKQoKW0tvbnRva29zdGEsIEMuIEUuLCBSZWluYSwgVi4gSi4sICYgQm9uY3phaywgQi4gKDIwMjApLiBFbmVyZ3kgY29zdCBidXJkZW5zIGZvciBsb3ctaW5jb21lIGFuZCBtaW5vcml0eSBob3VzZWhvbGRzOiBFdmlkZW5jZSBmcm9tIGVuZXJneSBiZW5jaG1hcmtpbmcgYW5kIGF1ZGl0IGRhdGEgaW4gZml2ZSBVUyBjaXRpZXMuIEpvdXJuYWwgb2YgdGhlIEFtZXJpY2FuIFBsYW5uaW5nIEFzc29jaWF0aW9uLCA4NigxKSwgODktMTA1Ll0oaHR0cHM6Ly93d3cudGFuZGZvbmxpbmUuY29tL2RvaS9mdWxsLzEwLjEwODAvMDE5NDQzNjMuMjAxOS4xNjQ3NDQ2KQoKLS0tCgojIyMjIFBhY2thZ2VzIApgYGB7ciwgbWVzc2FnZT1GQUxTRX0KI3BhY2thZ2VzIHVzZWQgaW4gdGhpcyBhbmFseXNpcwoKaWYoIXJlcXVpcmUocmVhZHIpKXsKICAgIGluc3RhbGwucGFja2FnZXMoInJlYWRyIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKICAgIGxpYnJhcnkocmVhZHIpCn0KaWYoIXJlcXVpcmUoZ2dwbG90MikpewogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCiAgICBsaWJyYXJ5KGdncGxvdDIpCn0KaWYoIXJlcXVpcmUoZHBseXIpKXsKICAgIGluc3RhbGwucGFja2FnZXMoImRwbHlyIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKICAgIGxpYnJhcnkoZHBseXIpCn0KaWYoIXJlcXVpcmUodGlkeXIpKXsKICAgIGluc3RhbGwucGFja2FnZXMoInRpZHlyIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKICAgIGxpYnJhcnkodGlkeXIpCn0KaWYoIXJlcXVpcmUoamFuaXRvcikpewogICAgaW5zdGFsbC5wYWNrYWdlcygiamFuaXRvciIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCiAgICBsaWJyYXJ5KGphbml0b3IpCn0KaWYoIXJlcXVpcmUoZm9yY2F0cykpewogICAgaW5zdGFsbC5wYWNrYWdlcygiZm9yY2F0cyIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCiAgICBsaWJyYXJ5KGZvcmNhdHMpCn0KCmlmKCFyZXF1aXJlKERhdGFFeHBsb3JlcikpewogICAgaW5zdGFsbC5wYWNrYWdlcygiRGF0YUV4cGxvcmVyIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKICAgIGxpYnJhcnkoRGF0YUV4cGxvcmVyKQp9CgppZighcmVxdWlyZShzdHJpbmdyKSl7CiAgICBpbnN0YWxsLnBhY2thZ2VzKCJzdHJpbmdyIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKICAgIGxpYnJhcnkoc3RyaW5ncikKfQoKaWYoIXJlcXVpcmUobHVicmlkYXRlKSl7CiAgICBpbnN0YWxsLnBhY2thZ2VzKCJsdWJyaWRhdGUiLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQogICAgbGlicmFyeShsdWJyaWRhdGUpCn0KYGBgCgotLS0KCiMgU2VjdGlvbiAxOiBEYXRhIERlc2NyaXB0aW9uCgojIyBLZXkgU3RlcHMKCjEpIEV4cGxvcmVkIGFuZCBkaXNjb3ZlcmVkIGV4aXN0aW5nIGRhdGEgZG9jdW1lbnRhdGlvbiAKMikgSWRlbnRpZmllZCBkYXRhIGZyYW1lcyBvZiBpbnRlcmVzdCAKMykgRGlzY2VybmVkIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRhdGFmcmFtZXMgCgpUaGlzIGRhdGEgaXMgZnJvbSB0aGUgUmVzaWRlbnRpYWwgQnVpbGRpbmcgU3RvY2sgQXNzZXNzbWVudCBbKFJCU0EpXShodHRwczovL25lZWEub3JnL3Jlc291cmNlcy9yYnNhLWlpLWNvbWJpbmVkLWRhdGFiYXNlKSBjb25kdWN0ZWQgaW4gMjAxNi0xNyAodGhlIHNwZWNpZmljIGRhdGEgY29sbGVjdGlvbiBtb250aHMgYXJlIHVuY2xlYXIsIHRoZSAyMDIyIFJCU0EgZGF0YSBjb2xsZWN0aW9uIGlzIHNjaGVkdWxlZCBmb3IgSnVuZSBhbmQgSnVseSkuIEl0IGluY2x1ZGVzIGEgcmVwcmVzZW50YXRpdmUgc2FtcGxlIG9mIHNpbmdsZS1mYW1pbHksIG11bHRpLWZhbWlseSwgYW5kIG1hbnVmYWN0dXJlZCBob21lcyBnYXRoZXJlZCBhY3Jvc3MgdGhlIE5vcnRod2VzdCByZWdpb24uIEl0IGhhcyA0NyBjb21tYS1zZXBhcmF0ZWQgdmFyaWFibGUgKENTVikgdGFidWxhciBkYXRhZnJhbWVzIHRoYXQgaW5jbHVkZXMgYSByZXByZXNlbnRhdGl2ZSBzYW1wbGUgb2YgMSwxMzAgc2luZ2xlLWZhbWlseSwgMjMwIG11bHRpLWZhbWlseSwgYW5kIDU1MCBtYW51ZmFjdHVyZWQgaG9tZXMgZ2F0aGVyZWQgYWNyb3NzIHRoZSBOb3J0aHdlc3QgcmVnaW9uLiBQYXJ0aWNpcGFudHMgYXJlIHJlY3J1aXRlZCBiYXNlZCBvbiBhIHJhbmRvbSBzZWxlY3Rpb24gb2Ygc2luZ2xlLWZhbWlseSByZXNpZGVudGlhbCBVU1BTIGFkZHJlc3NlcyBmb3IgdGhlIHNpbmdsZS1mYW1pbHkgY29tcG9uZW50LiBGb3IgdGhlIG11bHRpLWZhbWlseSBjb21wb25lbnQsIHRoZSBzdHVkeSByZWNydWl0ZWQgbXVsdGktZmFtaWx5IGJ1aWxkaW5ncyB0byBwYXJ0aWNpcGF0ZSBpbiB0aGUgc3VydmV5IGFuZCB0aGVuIGlkZW50aWZpZWQgdGVuYW50cyBpbiB0aG9zZSBidWlsZGluZ3Mgd2lsbGluZyB0byBwYXJ0aWNpcGF0ZS4gVHdvIGF1ZGl0b3JzIHBlcmZvcm1lZCBlYWNoIHNpdGUgdmlzaXQuIEF1ZGl0cyBsYXN0ZWQgYXBwcm94aW1hdGVseSB0d28gaG91cnMgYW5kIGNvdmVyZWQgYWxsIG9mIHRoZSBtYWpvciBjb21wb25lbnRzIG9mIHRoZSBob21lcyB0aGF0IGNhbiBiZSBsaW5rZWQgdG8gdGhlIGhvdXNlaG9sZOKAmXMgb3ZlcmFsbCBlbmVyZ3kgdXNlLCBpbmNsdWRpbmcgYnVpbGRpbmcgZW52ZWxvcGUsIEhWQUMgc3lzdGVtcywgbGlnaHRpbmcsIGFwcGxpYW5jZXMsIGVsZWN0cm9uaWNzLCBhbmQgd2F0ZXIgdGVjaG5vbG9naWVzLiBJbiBhZGRpdGlvbiwgdGhlIFJCU0EgYXVkaXQgZGF0YSB3YXMgY29tYmluZWQgd2l0aCBzZWxmLXJlcG9ydGVkIGhvbWUgY2hhcmFjdGVyaXN0aWNzIGFuZCBkZW1vZ3JhcGhpY3MgZGF0YSBjb2xsZWN0ZWQgaW4gdGhlIHBob25lIHN1cnZleSBkdXJpbmcgdGhlIHJlY3J1aXRtZW50IG9mIGFuIG9uLXNpdGUgc2FtcGxlLiBTdXBwb3J0aW5nIGRvY3VtZW50YXRpb24gb2YgdGhlIFJCU0EgZGF0YSBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vbmVlYS5vcmcvZGF0YS9yZXNpZGVudGlhbC1idWlsZGluZy1zdG9jay1hc3Nlc3NtZW50KS4KClRoZSBSQlNBIGRhdGFzZXQgY29tcHJpc2VzIDQ5IGZpbGVzOiA0NyBDU1YgZmlsZXMsIG9uZSAudHh0IFJlYWRNZSwgYW5kIGFuIGV4Y2VsIHNwcmVhZHNoZWV0IHdpdGggdW5pcXVlIGRhdGFzZXQgdmFsdWVzLiBPbmUgb2YgdGhlIENTViB0YWJsZXMgaXMgYSBkYXRhIGRpY3Rpb25hcnkgdGhhdCBkZXNjcmliZXMgdGhlIGNvbHVtbiBuYW1lcyBpbiBlYWNoIENTViB0YWJsZS4gVGhlIHNpemUgb2YgdGhlIENTViBmaWxlcyByYW5nZXMgZnJvbSAyIEtCIHRvIDE2LjYgTUIuIFRoZSBzbWFsbGVzdCB0YWJsZSBjb250YWlucyAxMSBjb2x1bW5zIGFuZCAxNCByb3dzL29ic2VydmF0aW9ucywgd2hpbGUgdGhlIGxhcmdlc3QgaGFzIDI0OSBjb2x1bW5zIGFuZCAxNTU2MSByb3dzL29ic2VydmF0aW9ucy4gVGhlIFJlYWRNZSBkZXRhaWxzIGNoYW5nZXMgdG8gdGhlIFJCU0EgZGF0YXNldDsgY2hhbmdlcyBhbmQgdXBkYXRlcyBhcmUgbnVtYmVyZWQgYW5kIG9yZ2FuaXplZCBieSBkYXRlLiBFYWNoIHJvdyBpbiBhIHRhYmxlIGhhcyBhIHVuaXF1ZSBwcmltYXJ5IGtleSAoUEspLCBtYWtpbmcgaXQgcG9zc2libGUgdG8gcmVmZXJlbmNlIHRoYXQgc3BlY2lmaWMgb2JqZWN0IGFuZCBtYXkgaW5jbHVkZSBvdGhlciByZWxhdGlvbmFsIGtleXMgKENLcykgdGhhdCBtYWtlIGl0IHBvc3NpYmxlIHRvIHJlbGF0ZSB0byBvdGhlciB0YWJsZXMgaW4gdGhlIGRhdGFzZXQuIE1vc3QgdGFibGVzL2RhdGFmcmFtZXMgY2FuIGJlIGpvaW5lZCB1c2luZyB0aGUgQ0tfU2l0ZUlEIGFuZCB0aGUgQ0tfUm9vbUlELgoKVGhlIFJCU0EgZGF0YXNldCBob3VzZXMgZGF0YSBmb3IgbWFudWZhY3R1cmVkIGhvbWVzLCBzaW5nbGUtZmFtaWx5IGhvbWVzLCBhbmQgbXVsdGktZmFtaWx5IHJlc2lkZW5jZXMuIFdpdGhpbiB0aGUgZGF0YXNldCwgZGF0YSBhcmUgYXR0cmlidXRlZCB0byBhIFNpdGUgb3IgYSBCdWlsZGluZy4gQnVpbGRpbmcgZGF0YSBpbmNsdWRlIGluZm9ybWF0aW9uIGNvbGxlY3RlZCBmb3Igbm9ucmVzaWRlbnRpYWwgcG9ydGlvbnMgb2YgYSBtdWx0aS1mYW1pbHkgYnVpbGRpbmcuIFNpdGUgZGF0YSBpbmNsdWRlIGRhdGEgY29sbGVjdGVkIGZvciB0aGUgZW50aXJldHkgb2YgYSBzaW5nbGUtZmFtaWx5IG9yIG1hbnVmYWN0dXJlZCBob21lIGFuZCBmb3IgcmVzaWRlbmNlcyB2aXNpdGVkIGF0IGEgbXVsdGktZmFtaWx5IGJ1aWxkaW5nLiBUaGUgZGF0YXNldCBkZW5vdGVzIGRhdGEgYXNzb2NpYXRlZCB3aXRoIGEgU2l0ZSBieSBhIENLX1NpdGVJRCBvciBQS19TaXRlSUQgYmVnaW5uaW5nIHdpdGgg4oCcU0lUReKAnTsgdGhlIGRhdGFzZXQgZGVub3RlcyBkYXRhIGFzc29jaWF0ZWQgd2l0aCBhIEJ1aWxkaW5nIGJ5IGEgQ0tfU2l0ZUlEIG9yIFBLX1NpdGVJRCBiZWdpbm5pbmcgd2l0aCDigJxCTERHLuKAnQoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiNJbXBvcnQgdGhlIFJCU0EgZGF0YWZyYW1lcyBvZiBpbnRlcmVzdAoKb2xzX2RmIDwtIHJlYWRfY3N2KCJSQlNBLUlJLUNvbWJpbmVkLURhdGFiYXNlL09uZSBMaW5lIFN1bW1hcnkuY3N2IikKCmRlbW9nIDwtIHJlYWRfY3N2KCJSQlNBLUlJLUNvbWJpbmVkLURhdGFiYXNlL1NpdGVJbnRlcnZpZXdfRGVtb2dyYXBoaWNzLmNzdiIpCgplbmVyZ3l1c2VfZGYgPC0gcmVhZF9jc3YoIlJCU0EtSUktQ29tYmluZWQtRGF0YWJhc2UvU2l0ZUludGVydmlld19Ib21lRW5lcmd5VXNlLmNzdiIpICNoYXMgZGF0YSBvbiBlbmVyZ3kgdXNlIGFuZCBlbmVyZ3kgc3RhciBhcHBsaWFuY2VzCmBgYAoKLS0tCgojIFNlY3Rpb24gMjogRGF0YSBKb3VybmV5CgojIyBLZXkgU3RlcHMKCjEpIEV4cGxvcmVkIHRoZSBkYXRhIAoyKSBJZGVudGlmaWVkIGFuZCBtZXJnZWQgZGF0YWZyYW1lcyBvZiBpbnRlcmVzdAozKSBTdWJzZXQgdGhlIGRhdGEgZm9yIHRoZSByZWdpb24gb2YgaW50ZXJlc3QKNCkgRXhwbG9yZWQgZGF0YSBhbmQgc2VsZWN0ZWQgdmFyaWFibGVzIG9mIGludGVyZXN0CiAgICBhKSBleHBsYW5hdG9yeSB2YXJpYWJsZXMgYmFzZWQgb24gQnV5bG92YSBwYXBlcgo1KSBSZWNvZGVkIGFuZCByZWNsYXNzaWZpZWQgZGF0YQo2KSBUcmFuc2Zvcm1lZCB2YXJpYWJsZXMgb2YgaW50ZXJlc3QKNykgQ3JlYXRlZCBFVUkgdmFyaWFibGUgCiAgICBhKSByZXNwb25zZSB2YXJpYWJsZSBiYXNlZCBvbiBCdXlsb3ZhIHBhcGVyCiAgICAKVGhlIGRhdGEgY2xlYW5pbmcgYW5kIHdyYW5nbGluZyBwcm9jZXNzIHRvb2sgcGxhY2UgaW4gUlN0dWRpbywgdXNpbmcgYmFzZSBSIGFuZCBUaWR5dmVyc2Ugc3ludGF4LiBUaGUgZGF0YSBjbGVhbmluZyBhbmQgd3JhbmdsaW5nIHByb2Nlc3MgaW5jbHVkZWQgMSkgcmVtb3ZpbmcgdW53YW50ZWQgdmFyaWFibGVzLCAyKSBjaGVja2luZyBkYXRhIGZvciBhY2N1cmFjeSwgMykgaGFuZGxpbmcgbWlzc2luZyBkYXRhLCA0KSBlbnN1cmluZyBjb25zaXN0ZW5jeSBhY3Jvc3MgdmFyaWFibGUgdHlwZXMsIGFuZCA1KSBjaGVja2luZyB2YWxpZGl0eSDigJMgZG9lcyB0aGUgZGF0YSBtYWtlIHNlbnNlPyBUaGUgZmlyc3Qgc3RlcCBpbiB0aGUgY2xlYW5pbmcgcHJvY2VzcyBpbnZvbHZlZCBpZGVudGlmeWluZyB1c2VmdWwgdmFyaWFibGVzIHdpdGhpbiB0aGUgUkJTQSBkYXRhc2V0IHRvIHJlcGxpY2F0ZSBCdXlsb3Zh4oCZcyBtZXRob2RzLiBUaGUgIk9uZSBMaW5lIFN1bW1hcnkiIGFuZCAiU2l0ZSBJbnRlcnZpZXcgRGVtb2dyYXBoaWNzIiBkYXRhZnJhbWVzIGhhZCB0aGUgbmVjZXNzYXJ5IHZhcmlhYmxlcyB0byByZWNyZWF0ZSB0aGUgcmVncmVzc2lvbiBtb2RlbCBjb25kdWN0ZWQgYnkgQnV5bG92YS4KCkRwbHlyIGZyb20gdGhlIFRpZHl2ZXJzZSB3YXMgdXNlZCB0byBtZXJnZSB0aGUgIlNpdGUgSW50ZXJ2aWV3IERlbW9ncmFwaGljcyIgdG8gdGhlICJPbmUgTGluZSBTdW1tYXJ5IiBkYXRhZnJhbWUuIFRoZSAiT25lIExpbmUgU3VtbWFyeSIgZGF0YWZyYW1lIGhhcyBlbmVyZ3kgY29uc3VtcHRpb24sIGdlb2dyYXBoaWMgbG9jYXRpb24sIGFuZCBidWlsZGluZyBpbmZvcm1hdGlvbi4gVGhlIHByaW1hcnkga2V5IGZvciB0aGUgbWVyZ2VyIHdhcyB0aGUgIkRCX1NpdGVJRCIgYW5kICJDS19TaXRlSUQuIiBUaGUgIlNpdGUgSW50ZXJ2aWV3IERlbW9ncmFwaGljcyIgZGF0YWZyYW1lIGluY2x1ZGVkIGRlbW9ncmFwaGljIGluZm9ybWF0aW9uLCBzdWNoIGFzIHJlc2lkZW50J3MgaW5jb21lLCBhZ2UsIGFuZCBvd25lcnNoaXAgc3RhdHVzIChyZW50ZXIgb3IgYnV5ZXIpLiAKCkFmdGVyIHRoZSBtZXJnZXIsIHRoZSBkYXRhZnJhbWUgd2FzIHN1YnNldHRlZCBmb3IgdGhlICJQdWdldCBTb3VuZCIgcmVnaW9uLiBOZXh0LCBob3VzaW5nIGFuZCBob3VzZWhvbGQgY2hhcmFjdGVyaXN0aWMgdmFyaWFibGVzLCBhcyBvdXRsaW5lZCBieSB0aGUgQnV5bG92YSAoMjAyMCkgcGFwZXIsIHdlcmUgc2VsZWN0ZWQgdG8gY3JlYXRlIHRoZSBhbmFseXRpY2FsIGRhdGFmcmFtZSAocmVmZXIgdG8gQXBwZW5kaXggQSB0byBsZWFybiBtb3JlIGFib3V0IHRoZSBob3VzaW5nIGFuZCBob3VzZWhvbGQgY2hhcmFjdGVyaXN0aWMgdmFyaWFibGVzKS4gVGhlIEVVSSwgdGhlIHJlc3BvbnNlIHZhcmlhYmxlLCB3YXMgY3JlYXRlZCBieSBkaXZpZGluZyB0aGUgdG90YWwgYW5udWFsIGVuZXJneSBjb25zdW1wdGlvbiAod2hpY2ggaXMgaW4gQnJpdGlzaCBUaGVybWFsIFVuaXRzIChrQlRVKSkgYnkgdGhlIGNvbmRpdGlvbmVkIGxpdmluZyBhcmVhIG9mIHRoZSBob21lIChzcS4gZm9vdCkuIFZhcmlhYmxlcyB3aXRoIGtCVFUgdW5pdHMgd2VyZSBpZGVudGlmaWVkIGFuZCBzdW1tZWQgdG8gY3JlYXRlIGEgdG90YWwgYW5udWFsIGVuZXJneSB1c2UgdmFyaWFibGUuIE9uY2UgdGhlIGFuYWx5dGljIGRhdGFmcmFtZSBoYWQgYWxsIHRoZSBuZWNlc3NhcnkgdmFyaWFibGVzLCBJIGNoZWNrZWQgZm9yIG1pc3NpbmduZXNzLiAKClRoZSBmaXJzdCBhdHRlbXB0IHRvIGNoZWNrIGZvciBtaXNzaW5nIGRhdGEgcmVzdWx0ZWQgaW4gNzMwMSBtaXNzaW5nIGRhdGEuIFVwb24gZnVydGhlciBleGFtaW5hdGlvbiwgSSBub3RpY2VkIHRoZXJlIHdhcyBtaXNzaW5nIGRhdGEgaW4gdGhlIFJCU0EgZGF0YXNldCBjb2RlZCBhcyAidW5rbm93biwiICJwcmVmZXIgbm90IHRvIHNheSwiIGFuZCBhcyB0aGUgY2hhcmFjdGVyIHZhbHVlICJOL0EuIiBJIHJlY29kZWQgdmFyaWFibGVzIHdpdGggdGhvc2Ugb2JzZXJ2YXRpb25zIGFzIE5BIChtaXNzaW5nKS4gTWFueSB2YXJpYWJsZXMgbmVlZGVkIHRvIGJlIHRyYW5zZm9ybWVkIHRvIHJlcGxpY2F0ZSB0aGUgQnV5bG92YSAoMjAyMCkgbW9kZWwsIHN1Y2ggYXMgYWdlLCBpbmNvbWUsIGFuZCB0aGUgdG90YWwgb2NjdXBhbnRzLiBUaGUgaW5jb21lIHZhcmlhYmxlIHdhcyBhIGNoYXJhY3RlciB2YXJpYWJsZSB0aGF0IHByb3ZpZGVkIGFuIGluY29tZSByYW5nZS4gSSBzcGxpdCB0aGUgaW5jb21lIHZhcmlhYmxlIGludG8gbG93X2VuZCBhbmQgaGlnaF9lbmQgaW5jb21lIHZhcmlhYmxlcyB0aGVuIHRvb2sgdGhlIGF2ZXJhZ2Ugb2YgdGhlIGxvd19lbmQgYW5kIGhpZ2hfZW5kIGluY29tZSB0byBjcmVhdGUgYW4gYXZlcmFnZSBpbmNvbWUgdmFyaWFibGUuIEZpbmFsbHksIEkgdXNlZCB0aGUgImphbml0b3IiIHBhY2thZ2UgdG8gbWFrZSBldmVyeSB2YXJpYWJsZSBjb25zaXN0ZW50IC0gbG93ZXJjYXNlIGFuZCBzbmFrZSBjYXNlLgoKYGBge3J9CiNFeHBsb3JlIHRoZSBvbmUgbGluZSBzdW1tYXJ5IGRhdGFmcmFtZQppbnRyb2R1Y2Uob2xzX2RmKQpgYGAKCmBgYHtyfQojRXhwbG9yZSB0aGUgZGVtb2dyYXBoaWMgZGF0YWZyYW1lIAppbnRyb2R1Y2UoZGVtb2cpCmBgYAoKYGBge3J9CiNNZXJnZSBvbHNfZGYgdG8gZGVtb2cKICBvbHNfZGVtb2cgPC0gbGVmdF9qb2luKG9sc19kZiwgZGVtb2csIGJ5ID0gYygiREJfU2l0ZUlEIiA9ICJDS19TaXRlSUQiKSkKCiMgT25seSBnZXQgc2l0ZXMgaW4gUHVnZXQgU291bmQgUmVnaW9uCnB1Z19zb3VuZF9vbHMgPC0gb2xzX2RlbW9nICU+JQogIGZpbHRlcihSZWdpb24gPT0gIlB1Z2V0IFNvdW5kIikKYGBgCgpgYGB7cn0KI0V4cGxvcmUgdGhlIFB1Z2V0IFNvdW5kIERhdGEKaW50cm9kdWNlKHB1Z19zb3VuZF9vbHMpCmBgYAoKYGBge3J9CiNTZWxlY3QgdmFyaWFibGVzIG9mIGludGVyZXN0CnB1Z19zaG9ydCA8LSBwdWdfc291bmRfb2xzICU+JQogIHNlbGVjdChgQ2FkbXVzIElEYCwgU3RhdGUsIENvdW50eSxSZWdpb24sIGBIb21lIFR5cGUgLSBGTVAgRGV0YWlsZWRgLCBgSG9tZSBUeXBlIC0gRmluYWxgLCBgWWVhciBCdWlsdGAsYFByaW1hcnkgSGVhdGluZyBTeXN0ZW1gLCBgUXR5IEJlZHJvb21zYCxgUmVwb3J0ZWQgSW5jb21lYCwgYERvIHlvdSBvd24gb3IgcmVudCB5b3VyIGhvbWVgLCBPd25lcnNoaXAsIGBRdHkgT2NjdXBhbnRzIEJldHdlZW4gNjUgWWVhcnMgb3IgT2xkZXJgLCBgUXR5IE9jY3VwYW50cyBCZXR3ZWVuIExlc3MgdGhhbiAxIFllYXJgLCBgUXR5IE9jY3VwYW50cyBCZXR3ZWVuIDYgYW5kIDEwIFllYXJzYCwgYFF0eSBPY2N1cGFudHMueGAsIGBRdHkgT2NjdXBhbnRzLnlgLCBgUXR5IE9jY3VwYW50cyBCZXR3ZWVuIExlc3MgdGhhbiAxIFllYXJgLCBgUXR5IE9jY3VwYW50cyBCZXR3ZWVuIDEgYW5kIDUgWWVhcnNgLCBgUXR5IE9jY3VwYW50cyBCZXR3ZWVuIDYgYW5kIDEwIFllYXJzYCwgYFF0eSBPY2N1cGFudHMgQmV0d2VlbiAxMSBhbmQgMTggWWVhcnNgLCBgUXR5IE9jY3VwYW50cyBCZXR3ZWVuIDE5IGFuZCA0NSBZZWFyc2AsIGBRdHkgT2NjdXBhbnRzIEJldHdlZW4gNDYgYW5kIDY0IFllYXJzYCwgYFF0eSBPY2N1cGFudHMgQmV0d2VlbiA2NSBZZWFycyBvciBPbGRlcmAsIGBDb25kaXRpb25lZCBBcmVhYCwgY29udGFpbnMoImtCdHUiKSkKYGBgCgpgYGB7cn0KI0V4cGxvcmUgdGhlIFB1Z19zaG9ydCBEYXRhCmludHJvZHVjZShwdWdfc2hvcnQpCmBgYAoKYGBge3J9CiNEYXRhIENsZWFuaW5nIGFuZCB3cmFuZ2xpbmcKCiMgQ2hhbmdlICJwcmVmZXIgbm90IHNheSIsICJVbmtvd24iLCBhbmQgTi9BIHRvIE5BcwpwdWdfc2hvcnRbcHVnX3Nob3J0ID09ICJVbmtub3duIiB8IHB1Z19zaG9ydCA9PSAiUHJlZmVyIG5vdCB0byBzYXkiIHwgcHVnX3Nob3J0ID09ICJOL0EiXSA8LSBOQQoKI0NoYW5nZSB5ZWFyIGJ1aWx0IHZhcmlhYmxlIGludG8gYSBkYXRlIHZhcmlhYmxlLCBpbnN0ZWFkIG9mIGNoYXJhY3RlciAKcHVnX3Nob3J0JGBZZWFyIEJ1aWx0YCA8LSBhcy5EYXRlKGFzLmNoYXJhY3RlcihwdWdfc2hvcnQkYFllYXIgQnVpbHRgKSwgZm9ybWF0ID0gIiVZIikKcHVnX3Nob3J0JGBZZWFyIEJ1aWx0YCA8LSB5ZWFyKHB1Z19zaG9ydCRgWWVhciBCdWlsdGApCgojTWFrZSBhIHZhcmlhYmxlIHRvIGdldCB0aGUgZGVjYWRlIGVhY2ggYnVpbGRpbmcgd2FzIGJ1aWx0IApwdWdfc2hvcnQgPC0gcHVnX3Nob3J0ICU+JQogIG11dGF0ZSh5ZWFyX2J1aWx0X2RlY2FkZSA9IDEwKihgWWVhciBCdWlsdGAgJS8lIDEwKSwKICAgICAgICAgeWVhcl9idWlsdF9kZWNhZGUgPSBmYWN0b3IoeWVhcl9idWlsdF9kZWNhZGUpKQoKIyNUdXJuIENlcnRhaW4gdmFyaWFibGVzIGludG8gZmFjdG9ycwpwdWdfc2hvcnRfY2xlYW4gPC0gcHVnX3Nob3J0ICU+JQogIG11dGF0ZShhY3Jvc3MoYyhgSG9tZSBUeXBlIC0gRk1QIERldGFpbGVkYCwgYFByaW1hcnkgSGVhdGluZyBTeXN0ZW1gLGBIb21lIFR5cGUgLSBGaW5hbGAsYERvIHlvdSBvd24gb3IgcmVudCB5b3VyIGhvbWVgOk93bmVyc2hpcCwgQ291bnR5KSxhcy5mYWN0b3IpKQoKI1RyYW5zZm9ybSBhIGFnZSB2YXJpYWJsZXMgdG8gdGhlIGZvbGxvd2luZzogMSkgbGVzcyB0aGFuIDEgdG8gNSwgMikgNi0xOCwgMykgMTktNjQsIDQpIDY1IGFuZCB1cApwdWdfc2hvcnRfY2xlYW5fYWdlIDwtIHB1Z19zaG9ydF9jbGVhbiAlPiUKICByb3d3aXNlKCkgJT4lCiAgbXV0YXRlKAogICAgYWdlX3plcm9fdG9fZml2ZSA9IHN1bShgUXR5IE9jY3VwYW50cyBCZXR3ZWVuIExlc3MgdGhhbiAxIFllYXJgLCBgUXR5IE9jY3VwYW50cyBCZXR3ZWVuIDEgYW5kIDUgWWVhcnNgKSwKICAgIGFnZV9zaXhfdG9fZWlnaHRlZW4gPSBzdW0oYFF0eSBPY2N1cGFudHMgQmV0d2VlbiA2IGFuZCAxMCBZZWFyc2AsIGBRdHkgT2NjdXBhbnRzIEJldHdlZW4gMTEgYW5kIDE4IFllYXJzYCksCiAgICBhZ2VfbmluZXRlZW5fdG9fc2l4dHlmb3VyID0gc3VtKGBRdHkgT2NjdXBhbnRzIEJldHdlZW4gMTkgYW5kIDQ1IFllYXJzYCwgYFF0eSBPY2N1cGFudHMgQmV0d2VlbiA0NiBhbmQgNjQgWWVhcnNgKSwKICAgIGFnZV9zaXh0eWZpdmVfcGx1cyA9IGBRdHkgT2NjdXBhbnRzIEJldHdlZW4gNjUgWWVhcnMgb3IgT2xkZXJgLAogICAgdG90YWxfb2NjdXBhbnRzID0gYFF0eSBPY2N1cGFudHMueGApCgojUmVtb3ZlIG9yaWdpbmFsIGFnZSBjb2x1bW5zCnB1Z19zaG9ydF9jbGVhbl9hZ2Vfc2hvcnQgPC0gcHVnX3Nob3J0X2NsZWFuX2FnZSAlPiUKICBzZWxlY3QoLWMoMTEsMTM6MjEpKQoKI01ha2UgY2F0ZWdvcmlhbCB2YXJpYWJsZSBmb3IgIyBvZiBvY2N1cGFudHMsIGFzIGRvbmUgaW4gdGhlIEJ1eWxvdmEgcGFwZXIKcHVnX3Nob3J0X29jY3VwYW50IDwtIHB1Z19zaG9ydF9jbGVhbl9hZ2Vfc2hvcnQgJT4lCiAgbXV0YXRlKGhvdXNlaG9sZF9zaXplID0gY2FzZV93aGVuKAogICAgdG90YWxfb2NjdXBhbnRzID09IDEgfiAib25lLXBlcnNvbiIsCiAgICB0b3RhbF9vY2N1cGFudHMgPT0gMiB+ICJ0d28gcGVvcGxlIiwKICAgIHRvdGFsX29jY3VwYW50cyA9PSAzIH4gInRocmVlIHBlb3BsZSIsCiAgICB0b3RhbF9vY2N1cGFudHMgPj0gNCB+ICJmb3VyIG9yIG1vcmUiKSkKCiNUdXJuIGhvdXNlaG9sZCBzaXplIHZhcmlhYmxlIGludG8gYSBmYWN0b3IKcHVnX3Nob3J0X29jY3VwYW50JGhvdXNlaG9sZF9zaXplIDwtIGZhY3RvcihwdWdfc2hvcnRfb2NjdXBhbnQkaG91c2Vob2xkX3NpemUsIGxldmVscyA9IGMoIm9uZS1wZXJzb24iLCAidHdvIHBlb3BsZSIsICJ0aHJlZSBwZW9wbGUiLCAiZm91ciBvciBtb3JlIikpCgoKIyBNYWtlIGEgYmluYXJ5IGNoaWxkcmVuIGFuZCBlbGRlcmx5IHZhcmlhYmxlLCBlbGRlcmx5IGlzIGFueW9uZSB3aG8gaXMgNjUgYW5kIG9sZGVyLCBjaGlsZHJlbiBpcyBhbnlvbmUgMC0xOCB5ZWFycyBvbGQKcHVnX3Nob3J0X2VsZGVyIDwtIHB1Z19zaG9ydF9vY2N1cGFudCAlPiUKICBtdXRhdGUoZWxkZXJseSA9IGlmX2Vsc2UoYWdlX3NpeHR5Zml2ZV9wbHVzID49IDEsICJ5ZXMiLCAibm8iKSkgJT4lCiAgbXV0YXRlKCBjaGlsZHJlbiA9IGlmX2Vsc2UoYWdlX3plcm9fdG9fZml2ZSB8IGFnZV9zaXhfdG9fZWlnaHRlZW4gPj0gMSwgInllcyIsICJubyIpKQoKI1NldCBmYWN0b3IgbGV2ZWxzIGZvciBlbGRlcmx5IGFuZCBjaGlsZHJlbiBiaW5hcnkgdmFyaWFibGVzCnB1Z19zaG9ydF9lbGRlciRlbGRlcmx5IDwtIGZhY3RvcihwdWdfc2hvcnRfZWxkZXIkZWxkZXJseSwgbGV2ZWxzID0gYygieWVzIiwgIm5vIikpCnB1Z19zaG9ydF9lbGRlciRjaGlsZHJlbiA8LSBmYWN0b3IocHVnX3Nob3J0X2VsZGVyJGNoaWxkcmVuLCBsZXZlbHMgPSBjKCJ5ZXMiLCAibm8iKSkKCiNDaGFuZ2UgY2hhcmFjdGVyIHZhcmlhYmxlcyB0byBudW1lcmljCnB1Z19zaG9ydF9lbGRlciRgQW5udWFsIEVsZWN0cmljIFVzYWdlIChrQnR1KWAgPC0gYXMubnVtZXJpYyhwdWdfc2hvcnRfZWxkZXIkYEFubnVhbCBFbGVjdHJpYyBVc2FnZSAoa0J0dSlgKQpwdWdfc2hvcnRfZWxkZXIkYEFubnVhbCBHYXMgVXNhZ2UgKGtCdHUpYCA8LSBhcy5udW1lcmljKHB1Z19zaG9ydF9lbGRlciRgQW5udWFsIEdhcyBVc2FnZSAoa0J0dSlgKQpwdWdfc2hvcnRfZWxkZXIkYENvbmRpdGlvbmVkIEFyZWFgIDwtIGFzLm51bWVyaWMocHVnX3Nob3J0X2VsZGVyJGBDb25kaXRpb25lZCBBcmVhYCkKCiNDZWF0ZSBFVUkgdmFyaWFibGUKI3B1Z19zaG9ydF9ldWkgPC0gCnB1Z19zaG9ydF9ldWkgPC0gcHVnX3Nob3J0X2VsZGVyICU+JQogIHJvd3dpc2UoKSAlPiUgCiAgbXV0YXRlKGFubnVhbF9lbmVyZ3lfdXNlID0gc3VtKGNfYWNyb3NzKGNvbnRhaW5zKCJrQnR1IikpLCBuYS5ybSA9IFRSVUUpKSAlPiUgCiAgbXV0YXRlKGFubnVhbF9lbmVyZ3lfdXNlID0gbmFfaWYoYW5udWFsX2VuZXJneV91c2UsIDApKSAlPiUgCiAgbXV0YXRlKGV1aSA9IGFubnVhbF9lbmVyZ3lfdXNlL2BDb25kaXRpb25lZCBBcmVhYCkKCiNUcmFuZm9ybSB0aGUgaW5jb21lIHZhcmlhYmxlIGFuZCB0YWtlIHRoZSBhdmVyYWdlIG9mIHRoZSBsb3dlci1lbmQgaW5jb21lIGFuZCB0aGUgaGlnaGVyLWVuZCBpbmNvbWUKcHVnX2V1aV9pbmNvbWUgPC0gcHVnX3Nob3J0X2V1aSAlPiUgCiAgbXV0YXRlKFJlcG9ydGVkX0luY29tZSA9IHN0cl9yZXBsYWNlKGBSZXBvcnRlZCBJbmNvbWVgLCAiXFxzIiwgIl8iKSkgJT4lIAogIHNlcGFyYXRlKFJlcG9ydGVkX0luY29tZSwgaW50byA9IGMoImxvd2VyX2luY29tZSIsICJoaWdoZXJfaW5jb21lIiksIHNlcCA9ICJfIikgJT4lIAogIG11dGF0ZShsb3dlcl9pbmNvbWUgPSBwYXJzZV9udW1iZXIobG93ZXJfaW5jb21lKSwKICAgICAgICAgaGlnaGVyX2luY29tZSA9IHBhcnNlX251bWJlcihoaWdoZXJfaW5jb21lKSkgJT4lCiAgbXV0YXRlKGxvd2VyX2luY29tZSA9IGlmX2Vsc2UoaXMubmEobG93ZXJfaW5jb21lKSwgaGlnaGVyX2luY29tZSwgbG93ZXJfaW5jb21lKSwKICAgICAgICAgaGlnaGVyX2luY29tZSA9IGlmX2Vsc2UoaXMubmEoaGlnaGVyX2luY29tZSksIGxvd2VyX2luY29tZSwgaGlnaGVyX2luY29tZSkpICU+JSAKICBtdXRhdGUoQXZlcmFnZV9SZXBvcnRlZF9JbmNvbWUgPSAobG93ZXJfaW5jb21lK2hpZ2hlcl9pbmNvbWUpLzIpICU+JSAKICBjbGVhbl9uYW1lcygpCgojIENyZWF0ZSBTb2Npb2Vjb25vbWljIFN0YXR1cyAoU0VTKSBWYXJpYWJsZSBiYXNlZCBvbiBhdmVyYWdlIGluY29tZSBhbmQgaG91c2Vob2xkIHNpemUgCiMgdGhlIGxvdy13YWdlIGluY29tZSB3YXMgYmFzZWQgb24gdGhlIFdhc2hpbmd0b24gU3RhdGUgTG93LUluY29tZSBXZWF0aGVyaXphdGlvbiBQcm9ncmFtLCBodHRwczovL3d3dy5jb21tZXJjZS53YS5nb3Yvd3AtY29udGVudC91cGxvYWRzLzIwMjEvMDIvMjAyMS1XQS1Mb3ctSW5jb21lLUVsaWdpYmxpdHktR3VpZGVsaW5lcy5wZGYgCgojIE1pZGRsZSBjbGFzcyBudW1iZXJzIHdlcmUgZGVyaXZlZCBmcm9tIERTSFMgU3RhdGUgTWVkaWFuIEluY29tZSBDaGFydHMuIE11bHRpcGx5aW5nIG1vbnRobHkgaW5jb21lIGJ5IDExIChtb250aHMpLiAgaHR0cHM6Ly93d3cuZHNocy53YS5nb3YvZXNhL2VsaWdpYmlsaXR5LXotbWFudWFsLWVhLXovc3RhdGUtbWVkaWFuLWluY29tZS1jaGFydCAKCiNOb3RlIHRoYXQgdGhlIGluY29tZSBudW1iZXJzIGFyZSBmb3IgMjAyMSBhbmQgdGhlIGRhdGEgaXMgZnJvbSAyMDE2LiBNb3JlIHJlc2VhcmNoIHNob3VsZCBiZSBkb25lIHRvIGJldHRlciByZWZsZWN0IFNFUyBpbiB0aGUgZGF0YQoKcHVnX2V1aSA8LSBwdWdfZXVpX2luY29tZSAlPiUgCiAgbXV0YXRlKHNlcyA9IGNhc2Vfd2hlbigKICAgIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lIDwgMzE3NTIgfiAibG93IiwKICAgIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lIDw9IDQxNTIxICYgdG90YWxfb2NjdXBhbnRzID09IDIgfiAibG93IiwKICAgIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lIDw9IDUxMjkxICYgdG90YWxfb2NjdXBhbnRzID09IDMgfiAibG93IiwKICAgIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lIDw9IDYxMDYxICYgdG90YWxfb2NjdXBhbnRzID49IDQgfiAibG93IiwKICAgIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lID0gNDQ1NCoxMSAmIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lIDwgNTgyNSoxMSAmICh0b3RhbF9vY2N1cGFudHMgPT0gMSkgfiAibWlkZGxlIiwKICAgIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lID0gNTgyNSoxMSAmIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lIDwgNzE5NSoxMSAmICh0b3RhbF9vY2N1cGFudHMgPj0gMikgfiAibWlkZGxlIiwKICAgIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lID0gNzE5NSoxMSAmIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lIDwgODU2NioxMSAmICh0b3RhbF9vY2N1cGFudHMgPj0gMykgfiAibWlkZGxlIiwKICAgIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lID0gODU2NioxMSAmIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lIDwgOTkzNioxMSAmICh0b3RhbF9vY2N1cGFudHMgPj0gNCkgfiAibWlkZGxlIiwKICAgIFRSVUUgfiAiaGlnaCIpKSAlPiUKICBtdXRhdGUoc2VzID0gaWZlbHNlKGlzLm5hKGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lKSwgTkEsIHNlcykpICU+JSAKICBtdXRhdGUoc2VzID0gZmFjdG9yKHNlcywgbGV2ZWxzID0gYygibG93IiwgIm1pZGRsZSIsICJoaWdoIikpKQpgYGAKCgpgYGB7cn0KI0ZpbmFsIEFuYWx5dGljYWwgRGF0YWZyYW1lIApwc3ljaDo6ZGVzY3JpYmUocHVnX2V1aSwgZmFzdCA9IFRSVUUpCmBgYAoKLS0tCgojIFNlY3Rpb24gMzogRGF0YSBBc3Nlc3NtZW50CgojIyBLZXkgU3RlcHMKCjEpIEV4YW1pbmVkIFJCU0EgZGF0YSBhZmZvcmRhbmNlcyBhbmQgbGltaXRhdGlvbnMgCjIpIFJlYWQgbGl0ZXJhdHVyZSBvbiBkYXRhIGV0aGljcyAKMykgRXhwbG9yZWQgZGF0YSBmb3IgaWRlbnRpZmlhYmlsaXR5IAo0KSBJZGVudGlmaWVkIHBvdGVudGlhbCBkYXRhIG1lcmdlcnMgdGhhdCBtYXkgcmFpc2UgcHJpdmFjeSBjb25jZXJucwoKUmVzdWx0cyBmcm9tIHRoZSBleHBsb3JhdG9yeSBkYXRhIGFuYWx5c2lzIHN1Z2dlc3QgdGhhdCB0aGUgUkJTQSBkYXRhIGlzIGEgdmFsdWFibGUgZGF0YXNldCBmb3IgaWRlbnRpZnlpbmcgZW5lcmd5IGNvbnN1bXB0aW9uIGFuZCBlcXVpdHkgaXNzdWVzLiBUaGUgUkJTQSBhbGxvd3MgcmVzZWFyY2hlcnMgdG8gaWRlbnRpZnkgZW5lcmd5IGVmZmljaWVuY3kgb3Bwb3J0dW5pdGllcywgdGhlIGVmZmljaWVuY3kgb2Ygc3BlY2lmaWMgYXBwbGlhbmNlcywgYW5kIG11Y2ggbW9yZS4gVGhlIGRhdGEgaW5jbHVkZXMgdGhlIHJlc2lkZW50aWFsIHByb3BlcnRpZXMnIHppcCBjb2RlLCBlbmFibGluZyByZXNlYXJjaGVycyB0byBkZXRlcm1pbmUgY2Vuc3VzIHRyYWN0cyBmb3IgZ2Vvc3BhdGlhbCBhbmFseXNlcy4gRnVydGhlcm1vcmUsIFRoZSBSQlNBIGRhdGFzZXQgaW5jbHVkZXMgcmVzaWRlbnRpYWwgZGVtb2dyYXBoaWMgZGF0YSwgYWxsb3dpbmcgcmVzZWFyY2hlcnMgdG8gZGlzYWdncmVnYXRlIGVuZXJneSBlZmZpY2llbmN5IGJ5IGZhbWlseSBzaXplLCBpbmNvbWUsIGVkdWNhdGlvbiBsZXZlbCwgYWdlLCBhbmQgb3RoZXIgZGVtb2dyYXBoaWMgY29uc3RydWN0cy4gSG93ZXZlciwgdGhpcyBhbmFseXNpcyBvbmx5IGV4cGxvcmVkIDIgb2YgdGhlIDQ3IGRhdGFmcmFtZXMgKHRoZXNlIHR3byB3ZXJlIHNlbGVjdGVkIGJlY2F1c2Ugb2YgdGhlIHJpY2huZXNzIG9mIHRoZSBkYXRhIGFuZCBpdHMgYWxpZ25tZW50IHRvIHRoZSBCdXlsb3ZhIHBhcGVyKS4gUmVzZWFyY2hlcnMgc2hvdWxkIGNvbmR1Y3QgZnVydGhlciBhbmFseXNlcyB0byBkZXRlcm1pbmUgdGhlIHV0aWxpdHkgb2YgdGhlIG90aGVyIGRhdGFmcmFtZXMgZm9yIGFuc3dlcmluZyBjcml0aWNhbCByZXNlYXJjaCBxdWVzdGlvbnMuICBMYXN0bHksIHRoZSBSQlNBIGRlbW9ncmFwaGljIGRhdGFmcmFtZSBkb2VzIG5vdCBwcm92aWRlIHJhY2UvZXRobmljaXR5IG9yIGdlbmRlciBkYXRhLCB3aGljaCBjYW4gaW5mb3JtIHJhY2lhbCBhbmQgZ2VuZGVyIGVxdWl0eSBpc3N1ZXMgcmVnYXJkaW5nIGhvdXNpbmcgYW5kIGVuZXJneS4gCgpNb3JlIHJlc2VhcmNoIG9wcG9ydHVuaXRpZXMgYmVjb21lIGF2YWlsYWJsZSB3aGVuIHRoZSBSQlNBIGRhdGEgaXMgbWVyZ2VkIHdpdGggb3RoZXIgZGF0YWZyYW1lcy4gRm9yIGV4YW1wbGUsIEJ1eWxvdmEgKDIwMjApIHdhcyBhYmxlIHRvIGlkZW50aWZ5IHdoaWNoIHJlZ2lvbnMgaW4gT3JlZ29uIGFuZCByYWNpYWwvZXRobmljIGdyb3VwcyB3ZXJlIG1vcmUgc3VzY2VwdGlibGUgdG8gaGlnaCBlbmVyZ3kgYnVyZGVuIGJ5IGNvbWJpbmluZyB0aGUgUkJTQSBkYXRhIHdpdGggdGhlIEFtZXJpY2FuIENvbW11bml0eSBTdXJ2ZXkgKEFDUykgZGF0YS4gUmVzZWFyY2ggcXVlc3Rpb25zIGNvbmNlcm5pbmcgdGhlIGFjdHVhbCBlbmVyZ3kgY29zdCBmb3Igc3BlY2lmaWMgYXJlYXMgY2FuIGJlIGFuc3dlcmVkIGJ5IGRldGVybWluaW5nIHRoZSBwcmljZSBwZXIga1doIGFuZCBjcmVhdGluZyBhIHJlZ2lvbmFsIG1hcCBkaXNwbGF5aW5nIHRoZSBjb3N0IG9mIGVuZXJneSBhbmQgaG91c2luZy4gTGFzdGx5LCB0aGUgUkJTQSBkYXRhIGlzIGxpbWl0ZWQgaW4gZXhhbWluaW5nIHRoZSB0ZW1wb3JhbCB2YXJpYXRpb24gaW4gdGhlIGVuZXJneSBjb3N0IGJ1cmRlbiBhc3NvY2lhdGVkIHdpdGggY2hhbmdpbmcgZW5lcmd5IHByaWNlcy4gQWRkaXRpb25hbCBkYXRhc2V0cyBhcmUgbmVlZGVkIHRvIGFuc3dlciBzdWNoIHF1ZXN0aW9ucy4gSG93ZXZlciwgZWFjaCBuZXcgcmVzZWFyY2ggcXVlc3Rpb24gYW5kIGFuYWx5c2lzIGFib3V0IGhvdXNpbmcgYW5kIHBlb3BsZSdzIGdlb2dyYXBoaWMgbG9jYXRpb24gd2FycmFudHMgY2FyZWZ1bCBldGhpY2FsIGNvbnNpZGVyYXRpb25zLgoKRGF0YSBpcyBub3QgbmV1dHJhbC4gUGVvcGxlIHVzZSBkYXRhIHRvIGNvbnZleSBhIG5hcnJhdGl2ZSBhYm91dCBpbmRpdmlkdWFscywgb3JnYW5pemF0aW9ucywgaW5zdGl0dXRpb25zLCBhbmQgdGhlIGVudmlyb25tZW50LiBBcyBhIHJlc3VsdCwgZGF0YSBoYXMgdGhlIHBvd2VyIHRvIHNoYXBlIHBlb3BsZSdzIHdvcmxkdmlld3MgYW5kIGluZmx1ZW5jZSB0aGVpciBkZWNpc2lvbnMuIFRoZSBkZXB0aCBhbmQgYnJlYWR0aCBvZiB0aGUgUkJTQSBkYXRhIHByb3ZpZGUgcmVzZWFyY2hlcnMgYW5kIGFuYWx5c3RzIHdpdGggYSBteXJpYWQgb2YgYW5hbHl0aWNhbCBvcHRpb25zIGFuZCBuYXJyYXRpdmVzIHRoZXkgY2FuIHRlbGwuIFdoaWxlIGRhdGEgb3VnaHQgdG8gYmUgcHVibGljIGFuZCBkZW1vY3JhdGl6ZWQsIGl0IGNhbiBsZWFkIHRvIGJhZCBhY3RvcnMgdXNpbmcgZGF0YSB0byByZWlmeSBpbmVxdWl0aWVzLiBVc2VycyBvZiB0aGUgUkJTQSBkYXRhIHNob3VsZCBiZSBtaW5kZnVsIG9mIHRoZSBuYXJyYXRpdmUgdGhleSBhcmUgdGVsbGluZyB3aXRoIHRoZWlyIGRhdGEgYW5hbHlzaXMgYW5kIGhvdyB0aGVpciByZXNlYXJjaCBjYW4gcG90ZW50aWFsbHkgYmUgdXNlZCB0byBkbyBoYXJtLiAKCklkZW50aWZpYWJpbGl0eSBpcyBiZWNvbWluZyBsZXNzIG9mIGEgYmluYXJ5IGFuZCBtb3JlIG9mIGEgY29udGludXVtLiBJbiBvdGhlciB3b3JkcywgcHJpdmFjeSBpcyBub3QgYWJvdXQgcHJpdmF0ZSBvciBwdWJsaWMsIGJ1dCBhYm91dCBob3cgbXVjaCBpbmZvcm1hdGlvbiBpcyBkaXNjbG9zZWQsIHdoaWNoIGNhbiBtYWtlIGNlcnRhaW4gZ3JvdXBzIGFuZCBpbmRpdmlkdWFscyBtb3JlIHNlZW4uIFRoZSBSQlNBIGlzIHB1YmxpY2x5IGF2YWlsYWJsZSBkYXRhIHRoYXQgZG9lcyBub3QgZGlzY2xvc2UgaW5kaXZpZHVhbCBhZGRyZXNzZXMgb3IgcGVvcGxlJ3MgbmFtZXMuIEhvd2V2ZXIsIGEgcGVyc29uJ3MgemlwIGNvZGUsIHR5cGUgb2YgaG91c2UsIGFubnVhbCBpbmNvbWUsIGFuZCB0aGUgYWdlIG9mIHRoZSBob21lb3duZXJzL3Jlc2lkZW50cyBjYW4gcmVzdWx0IGluIGluZGl2aWR1YWwgaG91c2VzIGJlY29taW5nIG1vcmUgaWRlbnRpZmlhYmxlLiBEaXNjbG9zdXJlIHJpc2tzIGluY3JlYXNlIHdpdGggZGltZW5zaW9uYWxpdHkgKG1vcmUgdmFyaWFibGVzKSwgbGlua2luZyBtdWx0aXBsZSBkYXRhIHNvdXJjZXMsIGFuZCB1c2luZyBkYXRhIGFuYWx5dGljcy4gVGhpcyBtYXkgcnVuIHRoZSByaXNrIG9mIG5vdCBhZGVxdWF0ZWx5IHByb3RlY3RpbmcgdnVsbmVyYWJsZSBncm91cHMgaW4gdGhlIGRhdGFzZXQuIEZvciBleGFtcGxlLCBpZiB0aGlzIGRhdGEgaXMgbWVyZ2VkIHdpdGggb3RoZXIgZGF0YSBzZXRzLCBzb21lb25lIGNhbiBpZGVudGlmeSBob3VzZWhvbGRzIGNvbXByaXNlZCBvZiBvbmx5IG9sZGVyIGFkdWx0cyBvciBzaW5nbGUgcGVvcGxlLiBUaGlzIGlzIGEgY2F1c2UgZm9yIGNvbmNlcm4gZm9yIHRoZXNlIHZ1bG5lcmFibGUgZ3JvdXBzLiBHZW9zcGF0aWFsIGFuYWx5c2VzIG5lZWQgdG8gYmUgZG9uZSB3aXRoIGNhcmUgdG8gbWl0aWdhdGUgdGhlIHBvdGVudGlhbCBmb3IgaWRlbnRpZnlpbmcgcGVvcGxlLgoKIyMjIFN1Z2dlc3RlZCBSZWFkaW5nczoKCltDb3J0aSwgTC4gJiBCaXNob3AsIEwgKHllYXIpLkxlZ2FsIGFuZCBldGhpY2FsIGNoYWxsZW5nZXMgc3Vycm91bmRpbmcgYmlnIGRhdGE6IGVuZXJneSBkYXRhXShodHRwczovL2RhbS51a2RhdGFzZXJ2aWNlLmFjLnVrL21lZGlhLzYwNDk5OS91a2RzLWNhc2Utc3R1ZGllcy1ldGhpY2FsLnBkZikKCltNY0tlbm5hLCBFLiwgUmljaGFyZHNvbiwgSS4sICYgVGhvbXNvbiwgTS4gKDIwMTIpLiBTbWFydCBtZXRlciBkYXRhOiBCYWxhbmNpbmcgY29uc3VtZXIgcHJpdmFjeSBjb25jZXJucyB3aXRoIGxlZ2l0aW1hdGUgYXBwbGljYXRpb25zLiBFbmVyZ3kgUG9saWN5LCA0MSwgODA3LTgxNC5dKGh0dHBzOi8vd3d3LnNjaWVuY2VkaXJlY3QuY29tL3NjaWVuY2UvYXJ0aWNsZS9hYnMvcGlpL1MwMzAxNDIxNTExMDA5NDM4P2Nhc2FfdG9rZW49bDc4OVJoQ1pYQm9BQUFBQToxcm9HTkR5c0d0UEdZUlJMRlV0XzNoMWlXR0gwTHo5ME9jTjRRNVF4cVZtS3ZuT01TV0paeDVvMGFnT2p0MGUtc3FleHpibXZrdykKCgpgYGB7ciwgZWNobz0gRkFMU0UsIHdhcm5pbmc9IEZBTFNFLCBtZXNzYWdlPSBGQUxTRSwgZXZhbD0gRkFMU0V9CiNWaXN1YWxpemUgZXVpCnB1Z19ldWkgJT4lCiAgZmlsdGVyKCFwcmltYXJ5X2hlYXRpbmdfc3lzdGVtICVpbiUgYygiR2VvdGhlcm1hbCBIZWF0IFB1bXAiLCAiUmFkaWFudCBIZWF0IikpICU+JSAKICBnZ3Bsb3QoYWVzKGV1aSxjb25kaXRpb25lZF9hcmVhKSkgKyBnZW9tX3BvaW50KCkgKwogIHN0YXRfc21vb3RoKG1ldGhvZCA9IGxtKSArIGZhY2V0X3dyYXAofnByaW1hcnlfaGVhdGluZ19zeXN0ZW0pICsgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgTkEpKSArCiAgbGFicyh4ID0gIkVuZXJneSBVc2UgSW50ZW5zaXR5IChFVUkpIiwgeSA9ICJDb25kaXRpb25lZCBBcmVhIChzcXVhcmUgZmVldCkiLCAKICAgICAgIHRpdGxlID0gIkVuZXJneSBVc2UgSW50ZW5zaXR5IGFzIGEgZnVuY3Rpb24gb2YgQ29uZGl0aW9uZWQgQXJlYSIsIAogICAgICAgc3VidGl0bGUgPSAiYnkgcHJpbWFyeSBoZWF0aW5nIHNvdXJjZSIpCiAKYGBgCgpgYGB7cn0KcHVnX2V1aSAlPiUKICBmaWx0ZXIoIXByaW1hcnlfaGVhdGluZ19zeXN0ZW0gJWluJSBjKCJHZW90aGVybWFsIEhlYXQgUHVtcCIsICJSYWRpYW50IEhlYXQiKSkgJT4lCiAgZmlsdGVyKCEoc2VzICVpbiUgTkEgKSkgJT4lIApnZ3Bsb3QoKSArIGdlb21fYmFyKGFlcyhwcmltYXJ5X2hlYXRpbmdfc3lzdGVtLCBldWksIGZpbGwgPSBzZXMpLCAKICAgICAgICAgICAgICAgICAgICBzdGF0ID0gInN1bW1hcnkiLCAKICAgICAgICAgICAgICAgICAgICBmdW4ueSA9ICJtZWFuIiwKICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9ICJkb2RnZSIpICsKICBsYWJzKHRpdGxlPSAiQXZlcmFnZSBFbmVyZ3kgVXNlIEludGVuc2l0eSBieSBIZWF0aW5nIFN5c3RlbSIsIAogICAgICAgc3VidGl0bGUgPSAiUHVnZXQgU291bmQgUmVnaW9uIiwgCiAgICAgICB4ID0gIlByaW1hcnkgSGVhdGluZyBTeXN0ZW0iLCAKICAgICAgIHkgPSAiRW5lcmd5IFVzZSBJbnRlbnNpdHkgKGtCdHUvZnQyKSIsCiAgICAgICBmaWxsID0gIlNvY2lvZWNvbm9taWMgQ2xhc3MiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMxYjllNzciLCIjZDk1ZjAyIiwiIzc1NzBiMyIpKSArCiAgI3RoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIGNvb3JkX2ZsaXAoKQpgYGAKCgpgYGB7cn0KcHVnX2V1aSAlPiUKICBmaWx0ZXIoIXByaW1hcnlfaGVhdGluZ19zeXN0ZW0gJWluJSBjKCJHZW90aGVybWFsIEhlYXQgUHVtcCIsICJSYWRpYW50IEhlYXQiKSkgJT4lCiAgZmlsdGVyKCEoc2VzICVpbiUgTkEgKSkgJT4lIApnZ3Bsb3QoKSArIGdlb21fYmFyKGFlcyhwcmltYXJ5X2hlYXRpbmdfc3lzdGVtLCBjb25kaXRpb25lZF9hcmVhLCBmaWxsID0gc2VzKSwgCiAgICAgICAgICAgICAgICAgICAgc3RhdCA9ICJzdW1tYXJ5IiwgCiAgICAgICAgICAgICAgICAgICAgZnVuLnkgPSAibWVhbiIsCiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSAiZG9kZ2UiKSArCiAgbGFicyh0aXRsZT0gIkF2ZXJhZ2UgU3F1YXJlIEZvb3RhZ2UgYnkgSGVhdGluZyBTeXN0ZW0iLCAKICAgICAgIHN1YnRpdGxlID0gIlB1Z2V0IFNvdW5kIFJlZ2lvbiIsIAogICAgICAgeCA9ICJQcmltYXJ5IEhlYXRpbmcgU3lzdGVtIiwgCiAgICAgICB5ID0gIkNvbmRpdGlvbmVkIEFyZWEgKHNxLiBmdCkiLAogICAgICAgZmlsbCA9ICJTb2Npb2Vjb25vbWljIENsYXNzIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMWI5ZTc3IiwiI2Q5NWYwMiIsIiM3NTcwYjMiKSkgKwogIGNvb3JkX2ZsaXAoKQpgYGAKCmBgYHtyfQpwdWdfZXVpICU+JQogIGZpbHRlcighcHJpbWFyeV9oZWF0aW5nX3N5c3RlbSAlaW4lIGMoIkdlb3RoZXJtYWwgSGVhdCBQdW1wIiwgIlJhZGlhbnQgSGVhdCIpKSAlPiUKICBmaWx0ZXIoIShzZXMgJWluJSBOQSApKSAlPiUgCmdncGxvdCgpICsgZ2VvbV9iYXIoYWVzKHByaW1hcnlfaGVhdGluZ19zeXN0ZW0sIGFubnVhbF9lbmVyZ3lfdXNlLCBmaWxsID0gc2VzKSwgCiAgICAgICAgICAgICAgICAgICAgc3RhdCA9ICJzdW1tYXJ5IiwgCiAgICAgICAgICAgICAgICAgICAgZnVuLnkgPSAibWVhbiIsCiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSAiZG9kZ2UiKSArCiAgbGFicyh0aXRsZT0gIkF2ZXJhZ2UgRW5lcmd5IFVzZSBJbnRlbnNpdHkgYnkgSGVhdGluZyBTeXN0ZW0gYW5kIEhvdXNlaG9sZCBTaXplIiwgCiAgICAgICBzdWJ0aXRsZSA9ICJQdWdldCBTb3VuZCBSZWdpb24iLCAKICAgICAgIHggPSAiUHJpbWFyeSBIZWF0aW5nIFN5c3RlbSIsIAogICAgICAgeSA9ICJBbm51YWwgRW5lcmd5IFVzZSIsCiAgICAgICBmaWxsID0gIlNvY2lvZWNvbm9taWMgQ2xhc3MiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMxYjllNzciLCIjZDk1ZjAyIiwiIzc1NzBiMyIpKSArCiAgI3RoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIGNvb3JkX2ZsaXAoKSArIAogIGZhY2V0X3dyYXAofmhvdXNlaG9sZF9zaXplKQpgYGAKCi0tLQoKIyBTZWN0aW9uIDQ6IE1vZGVsaW5nCgojIyBLZXkgU3RlcHMKCjEpIFJlcGxpY2F0ZWQgQnV5bG92YSBNb2RlbCAKMikgUHJvdmlkZWQgYWx0ZXJuYXRpdmUgTW9kZWxzCgpUaGUgUkJTQSBkYXRhc2V0IHdhcyBjbGVhbmVkLCB3cmFuZ2xlZCwgYW5kIGV4cGxvcmVkIHRvIHVuZGVyc3RhbmQgaXRzIHBvdGVudGlhbCB0byBhbnN3ZXIgY3JpdGljYWwgcmVzZWFyY2ggcXVlc3Rpb25zIGNlbnRlcmVkIG9uIHRoZSBpbnRlcnNlY3Rpb24gb2YgZW5lcmd5IHVzZSBhbmQgZXF1aXR5LiBUaGUgZGF0YSBleHBsb3JhdGlvbiB3YXMgZ3VpZGVkIGJ5IHRoZSBtZXRob2RzIGVtcGxveWVkIGJ5IEJ1eWxvdmEncyAoMjAyMCkgcGFwZXIsIHdoaWNoIHVzZWQgUkJTQSBhbmQgQUNTIGRhdGEgdG8gdW5kZXJzdGFuZCBlbmVyZ3kgZXF1aXR5IGluIE9yZWdvbi4gSSB1c2VkIGhvdXNpbmcgYW5kIGhvdXNlaG9sZCBjaGFyYWN0ZXJpc3RpYyB2YXJpYWJsZXMgKENoZWNrIEFwcGVuZGl4IEEgZm9yIG1vcmUgaW5mb3JtYXRpb24pIHRvIHJlcGxpY2F0ZSBCdXlsb3ZhJ3MgT0xTIHJlZ3Jlc3Npb24gbW9kZWwuIFRoZSByZXNwb25zZSB2YXJpYWJsZSBpbiBCdXlsb3ZhJ3MgbW9kZWwgd2FzIHJlc2lkZW50J3MgZW5lcmd5IHVzZSBpbnRlbnNpdHkgKEVVSSksIGNhbGN1bGF0ZWQgYnkgZGl2aWRpbmcgYW5udWFsIGVuZXJneSB1c2UgYnkgdGhlIGhvbWUncyBzcXVhcmUgZm9vdGFnZS4gVGhlIG1vZGVsIGluY2x1ZGVkIHNldmVyYWwgZXhwbGFuYXRvcnkgdmFyaWFibGVzLCBzdWNoIGFzIGluY29tZSBsZXZlbC4gCgpJbnN0ZWFkIG9mIGNyZWF0aW5nIHRoZSBzYW1lIGluY29tZSBsZXZlbHMgQnV5bG92YSB1c2VkLCBJIGRldmVsb3BlZCBhIHNvY2lvZWNvbm9taWMgc3RhdHVzIChTRVMpIHZhcmlhYmxlIGluZGljYXRpbmcgd2hldGhlciBhIHBlcnNvbiB3YXMgaW4gYSBsb3csIG1pZGRsZSwgb3IgaGlnaC1pbmNvbWUgY2xhc3MuIEEgcGVyc29uJ3MgU0VTIHdhcyBjYWxjdWxhdGVkIGJ5IGRldGVybWluaW5nIGluY29tZSBjdXRvZmYgcG9pbnRzIGJhc2VkIG9uIGhvdXNlaG9sZCBzaXplIGFuZCB3aGF0IGlzIGNvbnNpZGVyZWQgYSBsaXZhYmxlIHdhZ2UgaW4gdGhlIFB1Z2V0IFNvdW5kIFJlZ2lvbiBmb3IgMjAyMC4gRnV0dXJlIHJlc2VhcmNoZXJzIHNob3VsZCBkZXZlbG9wIGEgbW9yZSBhY2N1cmF0ZSBtZWFzdXJlIG9mIGEgbGl2YWJsZSB3YWdlIGluIHRoZSBQdWdldCBTb3VuZCBSZWdpb24gZm9yIDIwMTcgLSB3aGVuIHRoZSBkYXRhIHdhcyBjb2xsZWN0ZWQuIEFkZGl0aW9uYWxseSwgdGhlIEVVSSB2YXJpYWJsZSBoYWQgb3ZlciAyMDAgbWlzc2luZyBvYnNlcnZhdGlvbnMgZHVlIHRvIGFwYXJ0bWVudCBidWlsZGluZ3Mgbm90IHJlcG9ydGluZyBlbmVyZ3kgdXNlIGluIHRoaXMgZGF0YWZyYW1lLiBGdXJ0aGVyIGludmVzdGlnYXRpb24gc2hvdWxkIGJlIGRvbmUgdG8gYWNjb3VudCBmb3IgdGhlIG1pc3NpbmcgYXBhcnRtZW50IEVVSSBpbmZvcm1hdGlvbiBvciBwb3NzaWJseSBjb25kdWN0IGFuIGltcHV0YXRpb24uCgpGdXR1cmUgbW9kZWxpbmcgbWF5IGluY2x1ZGUgYSBtYWNoaW5lIGxlYXJuaW5nIG1vZGVsIHRvIGV4YW1pbmUgbXVsdGljb2xsaW5lYXJpdHkgYmV0d2VlbiB2YXJpYWJsZXMgYW5kIGlkZW50aWZ5IHZhcmlhYmxlcyB0aGF0IGhhdmUgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIGVuZXJneSB1c2UuIEZ1cnRoZXIsIGEgbWFjaGluZSBsZWFybmluZyByZWdyZXNzaW9uIG1vZGVsIGNhbiBiZSBhcHBsaWVkIHRvIGRldGVybWluZSB3aGljaCBob21lcyB3aWxsIG1vc3QgbGlrZWx5IGhhdmUgYSBoaWdoIGVuZXJneSB1c2UuIFRoZSByZXN1bHRzIGNhbiB0aGVuIGJlIG1hcHBlZCB0byBxdWlja2x5IGlkZW50aWZ5IHdoaWNoIHJlZ2lvbnMgYW5kIGdyb3VwcyBvZiBwZW9wbGUgaW4gdGhlIFB1Z2V0IFNvdW5kIGFyZSBtb3JlIHN1c2NlcHRpYmxlIHRvIGhpZ2ggZW5lcmd5IHVzZSBiYXNlZCBvbiBzcGVjaWZpYyB2YXJpYWJsZXMgaW4gdGhlIGRhdGEuCgpgYGB7cn0KI21vZGVsICAKbG0oZXVpIH4gaG9tZV90eXBlX2ZpbmFsICsgeWVhcl9idWlsdF9kZWNhZGUgKyBwcmltYXJ5X2hlYXRpbmdfc3lzdGVtICsgcXR5X2JlZHJvb21zICsgYXZlcmFnZV9yZXBvcnRlZF9pbmNvbWUgKyBlbGRlcmx5ICsgY2hpbGRyZW4gKyBob3VzZWhvbGRfc2l6ZSArIG93bmVyc2hpcCwgZGF0YSA9IHB1Z19ldWkpICU+JQogIGJyb29tOjp0aWR5KCkKCmxtKGV1aSB+IGhvbWVfdHlwZV9maW5hbCArIHllYXJfYnVpbHRfZGVjYWRlICsgcHJpbWFyeV9oZWF0aW5nX3N5c3RlbSArIHF0eV9iZWRyb29tcyArIGF2ZXJhZ2VfcmVwb3J0ZWRfaW5jb21lICsgZWxkZXJseSArIGNoaWxkcmVuICsgaG91c2Vob2xkX3NpemUgKyBvd25lcnNoaXAsIGRhdGEgPSBwdWdfZXVpKSAlPiUKICBicm9vbTo6Z2xhbmNlKCkKYGBgCgotLS0KCiMgU2VjdGlvbiA1OiBGdXR1cmUgd29yawoKIyMgS2V5IFN0ZXBzCgoxKSBJZGVudGlmaWVkIHNlY29uZGFyeSBkYXRhc2V0cyAKMikgRGV2ZWxvcGVkIGFsdGVybmF0aXZlIHJlc2VhcmNoIHF1ZXN0aW9ucwoKVGhlIFJCU0EgZGF0YSBleHBsb3JhdGlvbiB3YXMgZ3VpZGVkIGJ5IGhvdyBCdXlsb3ZhICgyMDIwKSB1c2VkIHRoZSBSQlNBIGRhdGEgdG8gaW52ZXN0aWdhdGUgdGhlIGR5bmFtaWNzIGJldHdlZW4gZW5lcmd5IHVzZSBhbmQgc29jaW8tZGVtb2dyYXBoaWMgY2hhcmFjdGVyaXN0aWNzIGluIHNwYXRpYWwgbW9kZWxpbmcgb2YgcmVzaWRlbnRpYWwgZW5lcmd5IGNvbnN1bXB0aW9uLiBCdXlsb3ZhJ3MgaW52ZXN0aWdhdGlvbiB3YXMgZG9uZSBieSBtZXJnaW5nIHRoZSBSQlNBIGRhdGEgd2l0aCBBQ1MgZGF0YS4gSXQgaGFzIHlldCB0byBiZSBzZWVuIHdoYXQgb3RoZXIgZGF0YSBzb3VyY2VzIHJlc2VhcmNoZXJzIGNhbiB1c2UgYWxvbmdzaWRlIHRoZSBSQlNBIGRhdGFzZXQgYW5kIHdoYXQgcXVlc3Rpb25zIHRoZXkgY2FuIGFuc3dlci4gVGhpcyBzZWN0aW9uIGF0dGVtcHRzIHRvIGltYWdpbmUgaW5ub3ZhdGl2ZSBhcHByb2FjaGVzIHRvIHVzaW5nIHRoZSBSQlNBIGRhdGFzZXQgdG8gYW5zd2VyIHJlbGV2YW50IGFuZCBjcml0aWNhbCBxdWVzdGlvbnMuIAoKVGhlIFJCU0EgZGF0YSBjb3VsZCBwb3RlbnRpYWxseSBiZSBwYWlyZWQgd2l0aCBob3VzaW5nIGRhdGEsIHN1Y2ggYXMgdGhlIFdhc2hpbmd0b24gTWVyZ2VkIExvbmdpdHVkaW5hbCBBZG1pbmlzdHJhdGl2ZSBEYXRhIFsoV01MQUQpXShodHRwczovL3V3ZXNjaWVuY2UuZ2l0aHViLmlvL01pbldBL092ZXJ2aWV3Lykgb3IgW1ppbGxvd10oaHR0cHM6Ly93d3cuemlsbG93LmNvbS9yZXNlYXJjaC9kYXRhLykgZGF0YSB0byBpbGx1c3RyYXRlIGEgY2xlYXJlciBwaWN0dXJlIG9mIGhvdXNpbmcgYnVyZGVuIGluIFdhc2hpbmd0b24gU3RhdGUgb3Igc3BlY2lmaWNhbGx5IHRoZSBQdWdldCBTb3VuZCByZWdpb24uIEhvdXNpbmcgYnVyZGVuIG1lYXN1cmVzIGluY2x1ZGUgcmVudCwgdHJhbnNwb3J0YXRpb24sIGFuZCB1dGlsaXRpZXMuIFdNTEFEIHByb3ZpZGVzIHJlbnQgYW5kIHRyYW5zcG9ydGF0aW9uLCB3aGlsZSBSQlNBIHByb3ZpZGVzIHV0aWxpdHkgZGF0YS4gUGFpcmVkIHdpdGggZXhpc3RpbmcgaG91c2luZyBkYXRhLCBsaWtlIFdNTEFELCB0aGUgUkJTQSBkYXRhIGNhbiBjcmVhdGUgYSBsYXRlbnQgdmFyaWFibGUgZm9yIGhvdXNpbmcgYnVyZGVuIHRoYXQgbWF5IGhhdmUgcG9saWN5IGltcGxpY2F0aW9ucy4gVGhlIGxhdGVudCBob3VzaW5nIGJ1cmRlbiB2YXJpYWJsZSBtYXkgaW5jbHVkZSBhIHBlcnNvbuKAmXMgbW9udGhseSByZW50LCBjb21tdXRlLCBhbmQgZW5lcmd5IGNvc3RzLiBDb21iaW5pbmcgdGhpcyBkYXRhIGNvdWxkIGhlbHAgbWFrZSBhIGNhc2UgZm9yIG1vcmUgZW5lcmd5LWVmZmljaWVudCBwb2xpY2llcyBpbiB0aGUgUHVnZXQgU291bmQgb3IgcHJvbW90ZSBvdGhlciBwb2xpY3kgbGV2ZXJzIHRvIG1pdGlnYXRlIGhvdXNpbmcgYnVyZGVuLiAKCkR1cmluZyB0aGUgUkJTQSBkYXRhIGV4cGxvcmF0aW9uLCBJIGZvdW5kIG90aGVyIGRhdGFzZXRzIGZvciBmdXJ0aGVyIGFuYWx5c2lzLiBTcGVjaWZpY2FsbHksIGRhdGEgZnJvbSB0aGUgUmVzaWRlbnRpYWwgRW5lcmd5IENvbnN1bXB0aW9uIFN1cnZleSAoUkVDUykgYWRtaW5pc3RlcmVkIGJ5IHRoZSBVUyBFbmVyZ3kgSW5mb3JtYXRpb24gQWRtaW5pc3RyYXRpb24gKEVJQSkuIFJFQ1MgaXMgYSBuYXRpb25hbGx5IHJlcHJlc2VudGF0aXZlIHNhbXBsZSBvZiBob3VzaW5nLiBTaW5jZSAxOTgwLCBFSUEgaGFzIGNvbGxlY3RlZCBlbmVyZ3kgY2hhcmFjdGVyaXN0aWNzIG9uIGhvdXNpbmcgdW5pdHMsIHVzYWdlIHBhdHRlcm5zLCBhbmQgaG91c2Vob2xkIGRlbW9ncmFwaGljcyBldmVyeSBmb3VyIHllYXJzLiBSZXNlYXJjaGVycyBjYW4gY3JlYXRlIGEgbG9uZ2l0dWRpbmFsIGRhdGFzZXQgd2l0aCB0aGUgUkVDUyBkYXRhIHRvIG1vZGVsIGhpc3RvcmljYWwgc3RhdGUgdHJlbmRzIGluIGVuZXJneSBjb25zdW1wdGlvbiBvciBidWlsZCBhIHJvYnVzdCBtb2RlbCB0byBwcmVkaWN0IGVuZXJneSBjb25zdW1wdGlvbiBhY3Jvc3MgdGhlIHN0YXRlIG9mIFdhc2hpbmd0b24uIEhvd2V2ZXIsIHRoZXJlIGFyZSByZXN0cmljdGlvbnMgdG8gdGhlIFJFQ1MgZGF0YS4gUmVzZWFyY2hlcnMgY291bGQgb2J0YWluIGZ1bGwgYWNjZXNzIHRvIHRoZSBSRUNTIGRhdGEgYnkgZGV2ZWxvcGluZyBhIGRhdGEtc2hhcmluZyBhZ3JlZW1lbnQuIAoKUmVzZWFyY2hlcnMgY2FuIHVzZSBsb2NhbCBjb3VudHkgYXNzZXNzb3IgZGF0YSB0byBjYWxjdWxhdGUgdGhlIGVuZXJneSB1c2Ugb2YgZXZlcnkgYnVpbGRpbmcgaW4gYSBsb2NhbCBhcmVhLiBGb3IgZXhhbXBsZSwgS2luZyBDb3VudHkncyBhc3Nlc3NvcidzIG9mZmljZSBwcm92aWRlcyBkYXRhIG9uIHJlc2lkZW50aWFsIGJ1aWxkaW5ncycgYXBwcmFpc2FsIGhpc3RvcnksIHRheGVzLCBwcm9wZXJ0eSBzYWxlcywgY29uZGl0aW9uLCBzaXplLCBhbmQgbXVjaCBtb3JlIGZvciBldmVyeSBidWlsZGluZyBpbiBLaW5nIENvdW50eS4gVGhlIGVzdGltYXRlcyBnZW5lcmF0ZWQgZnJvbSB0aGUgbW9kZWwgd2l0aCB0aGUgUkJTQSBkYXRhIGNhbiBiZSBhcHBsaWVkIHRvIHRoZXNlIGRhdGEgdG8gY2FsY3VsYXRlIGhvdXNpbmcgYWZmb3JkYWJpbGl0eSBpbiBhIHNwZWNpZmljIGxvY2FsaXR5LiBLaW5nIENvdW50eSdzIERlcGFydG1lbnQgb2YgQXNzZXNzbWVudCBoYXMgYnVpbGRpbmdz4oCZIHZhbHVlIGhpc3RvcnkgZnJvbSAxOTk3IHRvIDIwMTIuIEZ1dHVyZSByZXNlYXJjaGVycyBzaG91bGQgbWVyZ2UgYW5kIGFuYWx5emUgdmFsdWUgaGlzdG9yeSBkYXRhIHRvIGlsbHVzdHJhdGUgcHJpY2luZyBhbmQgYWZmb3JkYWJpbGl0eSB0cmVuZHMgaW4gS2luZyBDb3VudHkuCgpFbmVyZ3kgY29uc3VtcHRpb24gZG9lc27igJl0IGp1c3QgaGF2ZSBhIGNvc3RseSBlZmZlY3Qgb24gaW5kaXZpZHVhbCBob3VzZWhvbGRzOyBpdCBhbHNvIGhhcyBkZWxldGVyaW91cyBlbnZpcm9ubWVudGFsIGltcGxpY2F0aW9ucy4gQXMgYSByZXN1bHQsIHJlZHVjaW5nIGVuZXJneSBjb25zdW1wdGlvbiBpbiBkZW5zZWx5IHBvcHVsYXRlZCBhcmVhcyBpcyBvZiBncmVhdCBpbXBvcnRhbmNlLiBSZXNlYXJjaGVycyBzaG91bGQgZm9jdXMgb24gcmVzaWRlbnRpYWwgZW5lcmd5IGNvbnN1bXB0aW9uIGFuZCBjb21tZXJjaWFsIGJ1aWxkaW5nc+KAmSBlbmVyZ3kgY29uc3VtcHRpb24uIFRoZSBCdWlsZGluZyBFbmVyZ3kgQmVuY2htYXJraW5nIGRhdGFzZXQsIGNvbnN0cnVjdGVkIGJ5IFNlYXR0bGXigJlzIEJ1aWxkaW5nIEVuZXJneSBCZW5jaG1hcmtpbmcgYW5kIFJlcG9ydGluZyBQcm9ncmFtLCBwcm92aWRlcyBzdWZmaWNpZW50IGluZm9ybWF0aW9uIHRvIGV4YW1pbmUgaG93IHJlc2lkZW50aWFsIGFuZCBjb21tZXJjaWFsIGJ1aWxkaW5ncyBjb250cmlidXRlIHRvIGhpZ2ggZW5lcmd5IHVzZS4gVGhlIGRhdGFzZXQgY29udGFpbnMgZGF0YSBvZiB0aGUgYnVpbGRpbmfigJlzIEVVSSBhbmQgcGh5c2ljYWwgY29uZGl0aW9ucywgaW5jbHVkaW5nIGVuZXJneSBzdGFyIHNjb3Jlcy4gCgpUaGVyZSBpcyBhIHdlYWx0aCBvZiBlbmVyZ3kgZGF0YXNldHMgd2l0aCBpbXBvcnRhbnQgaW5mb3JtYXRpb24gd2FpdGluZyB0byBiZSBhbmFseXplZC4gVGhlIER1a2UgSW5pdGlhdGl2ZSBob3VzZXMgYSBjb2xsZWN0aW9uIG9mIGVuZXJneSBkYXRhIGFuZCB0b29scyBzdXBwb3J0ZWQgYnkgdGhlIE5hdGlvbmFsIFNjaWVuY2UgRm91bmRhdGlvbi4gU29tZSBvZiB0aGUgZGF0YXNldHMgY29udGFpbiBpbmZvcm1hdGlvbiBhYm91dCByZW5ld2FibGUgZW5lcmd5LCBlbGVjdHJpY2l0eSwgdGhlIGVudmlyb25tZW50LCBidWlsZGluZ3MsIHRyYW5zcG9ydGF0aW9uLCBhbmQgbXVjaCBtb3JlLiBUaGUgZGF0YXNldHMgYW5kIHJlYWRpbmdzIHN1Z2dlc3RlZCB0aHJvdWdob3V0IHRoaXMgZG9jdW1lbnQgY2FuIGJlIGZvdW5kIGluIHRoZSBBcHBlbmRpeC4KCiMjIyBPdGhlciBEYXRhc2V0cyAKCltSZXNpZGVudGlhbCBFbmVyZ3kgQ29uc3VtcHRpb24gU3VydmV5IChSRUNTKV0oaHR0cHM6Ly93d3cuZWlhLmdvdi9jb25zdW1wdGlvbi9yZXNpZGVudGlhbC9pbmRleC5waHApCgpbS2luZyBDb3VudHkgQXNzZXNzbWVudCBEYXRhXShodHRwczovL2luZm8ua2luZ2NvdW50eS5nb3YvYXNzZXNzb3IvRGF0YURvd25sb2FkL2RlZmF1bHQuYXNweCkgCgpbU2VhdHRsZSBCdWlsZGluZyBFbmVyZ3kgQmVuY2htYXJraW5nXShodHRwczovL2RhdGEuc2VhdHRsZS5nb3YvZGF0YXNldC8yMDE1LUJ1aWxkaW5nLUVuZXJneS1CZW5jaG1hcmtpbmcvaDdybS1mejZtL2RhdGEpCgpbRHVrZSBFbmVyZ3kgSW5pdGlhdGl2ZSBEYXRhIFJlc291cmNlc10oaHR0cHM6Ly9lbmVyZ3kuZHVrZS5lZHUvcmVzZWFyY2gvZW5lcmd5LWRhdGEvcmVzb3VyY2VzKQoKLS0tCgojIEFwcGVuZGljZXMKCgojIyBBcHBlbmRpeCBBOiBCdXlsb3ZhICgyMDIwKSB2YXJpYWJsZXMgb2YgaW50ZXJlc3QKCioqSG91c2luZyBDaGFyYWN0ZXJpc3RpY3M6KiogCiAgCiAgMS4gVHlwZSBvZiBob3VzaW5nCiAgMi4gWWVhciBvZiBjb25zdHJ1Y3Rpb24KICAzLiBQcmltYXJ5IGhlYXRpbmcKICA0LiBOdW1iZXIgb2YgYmVkcm9vbXMKCioqSG91c2Vob2xkIENoYXJhY3RlcmlzdGljczoqKgoKICAxLiBJbmNvbWUKICAyLiBPd25lcnNoaXAKICAzLiBFbGRlcmx5IC0gb2xkZXIgdGhhbiA2NQogIDQuIENoaWxkcmVuCiAgNS4gSG91c2Vob2xkIHNpemUKCiMjIEFwcGVuZGl4IEI6IEFsbCBTdWdnZXN0ZWQgUmVhZGluZ3MgCgoxKSBbQWhuLCBZLiwgJiBTb2huLCBELiBXLiAoMjAxOSkuIFRoZSBlZmZlY3Qgb2YgbmVpZ2hib3VyaG9vZC1sZXZlbCB1cmJhbiBmb3JtIG9uIHJlc2lkZW50aWFsIGJ1aWxkaW5nIGVuZXJneSB1c2U6IEEgR0lTLWJhc2VkIG1vZGVsIHVzaW5nIGJ1aWxkaW5nIGVuZXJneSBiZW5jaG1hcmtpbmcgZGF0YSBpbiBTZWF0dGxlLiBFbmVyZ3kgYW5kIEJ1aWxkaW5ncywgMTk2LCAxMjQtMTMzLl0oaHR0cHM6Ly93d3cuc2NpZW5jZWRpcmVjdC5jb20vc2NpZW5jZS9hcnRpY2xlL3BpaS9TMDM3ODc3ODgxOTMwNjgwMj9jYXNhX3Rva2VuPUlqVXZpWUx5UFpFQUFBQUE6SVNlYndCNDkzTUlJMVl1cWNOSDNZV2RJT1VOZk5MbjU0aFY1ZjdyYkRGUjUtQ3VnYzhkdlBkQmQ0NWtyN24zOTFMZFN6a1kyeHcpCgoyKSBbQnV5bG92YSwgQS4gKDIwMjApLiBTcG90bGlnaHQgb24gZW5lcmd5IGVmZmljaWVuY3kgaW4gT3JlZ29uOiBJbnZlc3RpZ2F0aW5nIGR5bmFtaWNzIGJldHdlZW4gZW5lcmd5IHVzZSBhbmQgc29jaW8tZGVtb2dyYXBoaWMgY2hhcmFjdGVyaXN0aWNzIGluIHNwYXRpYWwgbW9kZWxpbmcgb2YgcmVzaWRlbnRpYWwgZW5lcmd5IGNvbnN1bXB0aW9uLiBFbmVyZ3kgUG9saWN5LCAxNDAsIDExMTQzOS5dKGh0dHBzOi8vd3d3LnNjaWVuY2VkaXJlY3QuY29tL3NjaWVuY2UvYXJ0aWNsZS9waWkvUzAzMDE0MjE1MjAzMDE5MjApCgozKSBbQ29ydGksIEwuICYgQmlzaG9wLCBMICh5ZWFyKS5MZWdhbCBhbmQgZXRoaWNhbCBjaGFsbGVuZ2VzIHN1cnJvdW5kaW5nIGJpZyBkYXRhOiBlbmVyZ3kgZGF0YV0oaHR0cHM6Ly9kYW0udWtkYXRhc2VydmljZS5hYy51ay9tZWRpYS82MDQ5OTkvdWtkcy1jYXNlLXN0dWRpZXMtZXRoaWNhbC5wZGYpCgoKNCkgW0tvbnRva29zdGEsIEMuIEUuLCBSZWluYSwgVi4gSi4sICYgQm9uY3phaywgQi4gKDIwMjApLiBFbmVyZ3kgY29zdCBidXJkZW5zIGZvciBsb3ctaW5jb21lIGFuZCBtaW5vcml0eSBob3VzZWhvbGRzOiBFdmlkZW5jZSBmcm9tIGVuZXJneSBiZW5jaG1hcmtpbmcgYW5kIGF1ZGl0IGRhdGEgaW4gZml2ZSBVUyBjaXRpZXMuIEpvdXJuYWwgb2YgdGhlIEFtZXJpY2FuIFBsYW5uaW5nIEFzc29jaWF0aW9uLCA4NigxKSwgODktMTA1Ll0oaHR0cHM6Ly93d3cudGFuZGZvbmxpbmUuY29tL2RvaS9mdWxsLzEwLjEwODAvMDE5NDQzNjMuMjAxOS4xNjQ3NDQ2KQoKNSkgW01jS2VubmEsIEUuLCBSaWNoYXJkc29uLCBJLiwgJiBUaG9tc29uLCBNLiAoMjAxMikuIFNtYXJ0IG1ldGVyIGRhdGE6IEJhbGFuY2luZyBjb25zdW1lciBwcml2YWN5IGNvbmNlcm5zIHdpdGggbGVnaXRpbWF0ZSBhcHBsaWNhdGlvbnMuIEVuZXJneSBQb2xpY3ksIDQxLCA4MDctODE0Ll0oaHR0cHM6Ly93d3cuc2NpZW5jZWRpcmVjdC5jb20vc2NpZW5jZS9hcnRpY2xlL2Ficy9waWkvUzAzMDE0MjE1MTEwMDk0Mzg/Y2FzYV90b2tlbj1sNzg5UmhDWlhCb0FBQUFBOjFyb0dORHlzR3RQR1lSUkxGVXRfM2gxaVdHSDBMejkwT2NONFE1UXhxVm1Ldm5PTVNXSlp4NW8wYWdPanQwZS1zcWV4emJtdmt3KQoKCiMjIEFwcGVuZGl4IEM6IEFkZGl0aW9uYWwgRGF0YXNldHMgCgoxKSBbRHVrZSBFbmVyZ3kgSW5pdGlhdGl2ZSBEYXRhIFJlc291cmNlc10oaHR0cHM6Ly9lbmVyZ3kuZHVrZS5lZHUvcmVzZWFyY2gvZW5lcmd5LWRhdGEvcmVzb3VyY2VzKQoKMikgW1Jlc2lkZW50aWFsIEVuZXJneSBDb25zdW1wdGlvbiBTdXJ2ZXkgKFJFQ1MpXShodHRwczovL3d3dy5laWEuZ292L2NvbnN1bXB0aW9uL3Jlc2lkZW50aWFsL2luZGV4LnBocCkKCjMpIFtTZWF0dGxlIEJ1aWxkaW5nIEVuZXJneSBCZW5jaG1hcmtpbmddKGh0dHBzOi8vZGF0YS5zZWF0dGxlLmdvdi9kYXRhc2V0LzIwMTUtQnVpbGRpbmctRW5lcmd5LUJlbmNobWFya2luZy9oN3JtLWZ6Nm0vZGF0YSkKCjQpIFtLaW5nIENvdW50eSBBc3Nlc3NtZW50IERhdGFdKGh0dHBzOi8vaW5mby5raW5nY291bnR5Lmdvdi9hc3Nlc3Nvci9EYXRhRG93bmxvYWQvZGVmYXVsdC5hc3B4KSAKCiMjIEFwcGVuZGl4IEQ6IEdpdCBSZXNvdXJjZXMgCgpUaGUgR2l0SHViIHJlcG9zaW9yeSBmb3IgdGhpcyBhbmFseXNpcyBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9mb3N0ZXJqMy9JREwuZ2l0KQoKTGluazogaHR0cHM6Ly9naXRodWIuY29tL2Zvc3RlcmozL0lETC5naXQK