Author: Lakshmi Prathyusha Mandadi
Course: Business Forecasting, ECON-6635-07
Published: December 13, 2024

Introduction

Diffusion Index is an analytical tool for evaluating the depth and scope of trends in different financial markets or economic sectors. Using important economic data, this research seeks to develop and evaluate a diffusion index for the US that offers a thorough understanding of economic activity. This indicator aids analysts in determining the strength or weakness of economic cycles or market trends.It measures the proportion of individual components in a dataset that are showing positive changes in relation to the total number of components. It is important for trend analysis and decision making.

The three economic indicators to create diffusion index I have chosen are Retail Sales (RSAFSNA), Unemployment Rate (UNRATE) and Inflation (CPIAUCSL).

Retail Sales: The health of consumer spending is indicated by the Census Bureau’s monthly report on retail and food services sales. Retail sales in a variety of industries, including department stores, furniture stores, and home furnishings stores, are shown in this report.

Unemployment Rate: The unemployment rate is one of the main indicator of labor market health and overall economic activity. A lower unemployment rate denotes economic expansion and higher consumer spending, whereas an increase in it denotes an economic recession.

Inflation: The overall increase in prices for goods and services within an economy is known as inflation. While extremely low inflation may be a sign of a coming recession, excessive inflation may indicate that the economy is excessive.

Data Collection

The Initial step in creating diffusion index is data collection and we will obtain the data from the Federal Reserve Economic Data (FRED) database.

# Pick 3 pertinent economic variables for the US
getSymbols(c("RSAFSNA", "UNRATE", "CPIAUCSL"), 
           freq = "monthly", 
           src = "FRED", return.class = 'xts',
           index.class  = 'Date',
           from = "2010-01-01",
           to = Sys.Date(),
           auto.assign = TRUE)
[1] "RSAFSNA"  "UNRATE"   "CPIAUCSL"
# Convert data into a single time-series dataset
data <- merge(RSAFSNA, UNRATE, CPIAUCSL)
colnames(data) <- c("Retail_Sales", "Unemployment_Rate", "Inflation_Rate")

data$date <- index(data)

Data Transformation and Standardization

We must transform and standardize these metrics so that they are comparable. Standardization guarantees that the diffusion index is not skewed by scale variations among the variables.

data[is.na(data)] <- 0

# Standardize each series to ensure comparability
scale_data <- data %>%
  na.omit() %>%
  scale() %>%
  as.xts()

Create Custom Diffusion Index

First, for each of the three indicators, determine if it is improving or declining compared to the previous period. Then calculate the Diffusion Index as the average of these improves or declines. By aggregating these indicators, we can gain a broader picture of the general economic trends.


data <- as.data.frame(scale_data)

# Calculate if each variable is improving (1) or declining (-1) from the previous period
 data = data %>%
  mutate(
    unemployment_diff = ifelse(Unemployment_Rate < lag(Unemployment_Rate, default = first(Unemployment_Rate)), 1, -1),
    sales_diff = ifelse(Retail_Sales > lag(Retail_Sales, default = first(Retail_Sales)), 1, -1),
    inflation_diff = ifelse(Inflation_Rate > lag(Inflation_Rate, default = first(Inflation_Rate)), 1, -1)
  )

# Constructing a diffusion index by averaging standardized variables
data$diffusion_index <- rowMeans(data[, c("unemployment_diff", "sales_diff", "inflation_diff")])
data <- xts(data, order.by = date)

Plotting Diffusion Index

The following plot visualizes the diffusion index over time, with a loess smoother added to highlight the overall trend.

This plot shows the proportion of the selected economic variables (unemployment rate, inflation rate, and Retail sales) that are increasing over time.

library(ggplot2)

head(data)
           Retail_Sales Unemployment_Rate Inflation_Rate unemployment_diff sales_diff
2010-01-01        -1.55              1.78          -1.29                -1         -1
2010-02-01        -1.58              1.78          -1.30                -1         -1
2010-03-01        -1.17              1.83          -1.29                -1          1
2010-04-01        -1.20              1.83          -1.29                -1         -1
2010-05-01        -1.13              1.69          -1.30                 1          1
2010-06-01        -1.19              1.60          -1.30                 1         -1
           inflation_diff diffusion_index
2010-01-01             -1          -1.000
2010-02-01             -1          -1.000
2010-03-01              1           0.333
2010-04-01              1          -0.333
2010-05-01             -1           0.333
2010-06-01             -1          -0.333
# Plotting the Diffusion Index with ggplot
ggplot(data, aes(x = date, y = diffusion_index)) +
  geom_line(color = "purple") + 
  geom_smooth(method = "loess", color = "orange", se = TRUE) +
  labs(title = "Diffusion Index Over Time", x = "Date", y = "Diffusion Index") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

A value close to 1 indicates that most variables are increasing, suggesting strong economic activity.

A value close to -1 indicates that most variables are decreasing, suggesting weak economic activity.

The diffusion index highlights key factors in economy. After 2020, the shaded confidence interval slightly widens, indicating a rise in uncertainty or greater fluctuation in the economy over this time. The trend’s flattening after 2020 is consistent with more general economic difficulties such as the COVID-19 pandemic and the instability that followed the recovery. While the purple variations serve to indicate times of economic volatility, keeping an eye on the orange trend line can reveal insights into economic turning moments.It shows a smoother upward trend over the long run.

Comparison of Chicago Fed National Activity Index (CFNAI) with Custom Diffustion Index

The Chicago Fed National Activity Index (CFNAI) is a measure of national economic activity. We can evaluate the degree to which our chosen indicators reflect general economic trends by contrasting our diffusion index with the CFNAI. We will compare our custom diffusion index with the CFNAI Diffusion Index by calculating the correlation coefficient and plotting both series side by side.

# Comparing with Chicago Fed National Activity Index: Diffusion Index (CFNAIDIFF)
getSymbols("CFNAIDIFF", src = "FRED", return.class = 'xts', index.class  = 'Date', from = "2010-01-01", to = Sys.Date(), auto.assign = TRUE)
[1] "CFNAIDIFF"
CFNAIDIFF$date <- index(CFNAIDIFF)
# Aligning both datasets to the same date range to avoid invalid time issues


# Merge both indexes for comparison
comparison_data <- merge(data$diffusion_index, CFNAIDIFF$CFNAIDIFF, join = "inner")

colnames(comparison_data) <- c("Diffusion_Index", "CFNAIDIFF_Index")

head(comparison_data)
           Diffusion_Index CFNAIDIFF_Index
2010-01-01          -1.000            0.05
2010-02-01          -1.000           -0.09
2010-03-01           0.333            0.09
2010-04-01          -0.333            0.25
2010-05-01           0.333            0.44
2010-06-01          -0.333            0.25

Correlation Analysis

The correlation coefficient measures the linear relationship between diffusion index and the CFNAI Diffusion Index. Similar economic trends are indicated by a high positive correlation, which implies that the two indexes move in synchronization.

# Calculating correlation
correlation <- cor(comparison_data$Diffusion_Index, comparison_data$CFNAIDIFF_Index, use = "complete.obs")
print(paste("Correlation Coefficient: ", round(correlation, 3)))
[1] "Correlation Coefficient:  0.195"

The correlation coefficient we got is 0.195 which is considered weak and indicates that both indexes are not entirely in synch. While a weak positive correlation means there is some relationship, it’s not strong enough to conclude that the indicators are in sync or consistently reflect the same economic trends.

ggplot of both Indexes

Below, we plot both indexes side by side to visualize their similarities or differences over time.

# Now plot the Diffusion Index and Chicago Fed Index
ggplot(comparison_data) +
  geom_line(aes(x = index(comparison_data), y = Diffusion_Index), color = "cyan", alpha = 0.6) +
  geom_line(aes(x = index(comparison_data), y = CFNAIDIFF_Index), color = "blue", alpha = 0.6) +
  labs(title = "Comparison of Diffusion Index and CFNAIDIFF", x = "Date", y = "Index Value") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotate x-axis labels if needed

NA
NA

When the two indices move in sync in the comparison plot, it indicates that the economic trends they represent are strongly aligned. Variations among the indexes could indicate variations in each index’s reaction to particular economic occurrences or crises. Similar to the diffusion index, it indicates the proportion of these indicators that are increasing.

Table of Key Metrics:

Metric Custom Diffusion Index CFNAIDIFF
Time Period Jan 2010 – Sep 2024 Jan 2010 – Sep 2024
Correlation (Custom vs CFNAI) 0.195 0.195
Average Value ~0.02 ~-0.10
Standard Deviation 0.21 0.45

Insights

1.Unpredictable Nature of Economy:

Compared to the custom diffusion index, the CFNAIDIFF is more sensitive to underlying data inputs or economic shocks, as evidenced by its strong fluctuations.

2.Indicator of Financial Crisis:

As of the most recent statistics in September 2024, the fall in both indicators can indicate decreasing economic momentum.

3.Custom Index Stability:

The custom index’s smoother trend might suggest a more comprehensive and insensitive view of the state of the economy.

Although there are noticeable differences in frequency and magnitude, both indices show comparable periodic oscillations.In contrast to the custom index, which moves more smoothly, the CFNAIDIFF is more volatile, exhibiting strong spikes and falls. As the series draws to a close (September 2024 for CFNAIDIFF), both indexes show a declining tendency. This implies that current economic activity may be slowing down or facing difficulties. In certain economic cycles, there are parallel movements despite the modest correlation (0.195), suggesting partial alignment.

Conclusion:

According to the comparison, the CFNAIDIFF records more recent developments, whereas the custom diffusion index offers a more comprehensive picture of economic stability. Both indices point to a possible slowdown in the economy as of September 2024; additional observation of upcoming data is necessary to validate these indicators.

Lakshmi Prathyusha Mandadi, Guidance by Prof Dr A.E. Rodriguez, Pompea College of Business, University of New Haven

LS0tDQp0aXRsZTogIkRpZmZ1c2lvbiBDb25mdXNpb24iDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KDQogICAgICBvcHRpb25zKGRpZ2l0cyA9IDMsIHNjaXBlbiA9IDk5OTksIHN0cmluZ2FzRmFjdG9ycyA9IEZBTFNFKQ0KICAgICAgcmVtb3ZlKGxpc3QgPSBscygpKQ0KICAgICAgZ3JhcGhpY3Mub2ZmKCkNCg0KI0xvYWQgbGlicmFyaWVzID09PT09PT09PT09PT09PT09PT09PT0NCnN1cHByZXNzV2FybmluZ3Moew0KICBzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoew0KICAgIGxpYnJhcnkodGlkeXZlcnNlKQ0KICAgIGxpYnJhcnkobHVicmlkYXRlKQ0KICAgIGxpYnJhcnkoZ2d0aGVtZXMpDQogICAgbGlicmFyeShjb3dwbG90KQ0KICAgIGxpYnJhcnkodHNib3gpICNjb252ZXJ0IHh0cyB0byB0c2liYmxlDQogICAgbGlicmFyeShUU3N0dWRpbykNCiAgICBsaWJyYXJ5KHRzdXRpbHMpDQogICAgbGlicmFyeShyaW8pDQogICAgbGlicmFyeShyZWFkeGwpDQogICAgbGlicmFyeShmb3JlY2FzdCkNCiAgICBsaWJyYXJ5KHF1YW50bW9kKQ0KICAgIGxpYnJhcnkoVFNzdHVkaW8pDQogICAgbGlicmFyeShsdWJyaWRhdGUpDQogICAgbGlicmFyeShkeWdyYXBocykNCiAgICBsaWJyYXJ5KHRzZXJpZXMpDQogICAgIyBTZWNvbmRhcnkgcGFja2FnZXMgICAgICAgIA0KICAgIGxpYnJhcnkodHNpYmJsZSkNCiAgICBsaWJyYXJ5KGZhYmxlKQ0KICAgIGxpYnJhcnkodHNpYmJsZWRhdGEpDQogICAgbGlicmFyeShmZWFzdHMpDQogICAgbGlicmFyeShmcHAyKQ0KICAgIGxpYnJhcnkoZnBwMykNCiAgICBsaWJyYXJ5KHh0cykNCiAgICBsaWJyYXJ5KHpvbykNCiAgICBsaWJyYXJ5KHZhcnMpDQogICAgbGlicmFyeShzdGFyZ2F6ZXIpDQogICAgbGlicmFyeShDYXVzYWxJbXBhY3QpDQogIH0pDQp9KQ0KDQoNCmBgYA0KDQoqQXV0aG9yOiBMYWtzaG1pIFByYXRoeXVzaGEgTWFuZGFkaSogICANCipDb3Vyc2U6IEJ1c2luZXNzIEZvcmVjYXN0aW5nLCBFQ09OLTY2MzUtMDcqICANCipQdWJsaXNoZWQ6IERlY2VtYmVyIDEzLCAyMDI0Kg0KDQojIyBJbnRyb2R1Y3Rpb24NCg0KRGlmZnVzaW9uIEluZGV4IGlzIGFuIGFuYWx5dGljYWwgdG9vbCBmb3IgZXZhbHVhdGluZyB0aGUgZGVwdGggYW5kIHNjb3BlIG9mIHRyZW5kcyBpbiBkaWZmZXJlbnQgZmluYW5jaWFsIG1hcmtldHMgb3IgZWNvbm9taWMgc2VjdG9ycy4gVXNpbmcgaW1wb3J0YW50IGVjb25vbWljIGRhdGEsIHRoaXMgcmVzZWFyY2ggc2Vla3MgdG8gZGV2ZWxvcCBhbmQgZXZhbHVhdGUgYSBkaWZmdXNpb24gaW5kZXggZm9yIHRoZSBVUyB0aGF0IG9mZmVycyBhIHRob3JvdWdoIHVuZGVyc3RhbmRpbmcgb2YgZWNvbm9taWMgYWN0aXZpdHkuIFRoaXMgaW5kaWNhdG9yIGFpZHMgYW5hbHlzdHMgaW4gZGV0ZXJtaW5pbmcgdGhlIHN0cmVuZ3RoIG9yIHdlYWtuZXNzIG9mIGVjb25vbWljIGN5Y2xlcyBvciBtYXJrZXQgdHJlbmRzLkl0IG1lYXN1cmVzIHRoZSBwcm9wb3J0aW9uIG9mIGluZGl2aWR1YWwgY29tcG9uZW50cyBpbiBhIGRhdGFzZXQgdGhhdCBhcmUgc2hvd2luZyBwb3NpdGl2ZSBjaGFuZ2VzIGluIHJlbGF0aW9uIHRvIHRoZSB0b3RhbCBudW1iZXIgb2YgY29tcG9uZW50cy4gSXQgaXMgaW1wb3J0YW50IGZvciB0cmVuZCBhbmFseXNpcyBhbmQgZGVjaXNpb24gIG1ha2luZy4NCg0KVGhlIHRocmVlIGVjb25vbWljIGluZGljYXRvcnMgdG8gY3JlYXRlIGRpZmZ1c2lvbiBpbmRleCBJIGhhdmUgY2hvc2VuIGFyZSBSZXRhaWwgU2FsZXMgKFJTQUZTTkEpLCBVbmVtcGxveW1lbnQgUmF0ZSAoVU5SQVRFKSBhbmQgSW5mbGF0aW9uIChDUElBVUNTTCkuDQoNCioqUmV0YWlsIFNhbGVzOioqIFRoZSBoZWFsdGggb2YgY29uc3VtZXIgc3BlbmRpbmcgaXMgaW5kaWNhdGVkIGJ5IHRoZSBDZW5zdXMgQnVyZWF1J3MgbW9udGhseSByZXBvcnQgb24gcmV0YWlsIGFuZCBmb29kIHNlcnZpY2VzIHNhbGVzLiBSZXRhaWwgc2FsZXMgaW4gYSB2YXJpZXR5IG9mIGluZHVzdHJpZXMsIGluY2x1ZGluZyBkZXBhcnRtZW50IHN0b3JlcywgZnVybml0dXJlIHN0b3JlcywgYW5kIGhvbWUgZnVybmlzaGluZ3Mgc3RvcmVzLCBhcmUgc2hvd24gaW4gdGhpcyByZXBvcnQuICANCg0KKipVbmVtcGxveW1lbnQgUmF0ZToqKiBUaGUgdW5lbXBsb3ltZW50IHJhdGUgaXMgb25lIG9mIHRoZSBtYWluIGluZGljYXRvciBvZiBsYWJvciBtYXJrZXQgaGVhbHRoIGFuZCBvdmVyYWxsIGVjb25vbWljIGFjdGl2aXR5LiBBIGxvd2VyIHVuZW1wbG95bWVudCByYXRlIGRlbm90ZXMgZWNvbm9taWMgZXhwYW5zaW9uIGFuZCBoaWdoZXIgY29uc3VtZXIgc3BlbmRpbmcsIHdoZXJlYXMgYW4gaW5jcmVhc2UgaW4gaXQgZGVub3RlcyBhbiBlY29ub21pYyByZWNlc3Npb24uICANCg0KKipJbmZsYXRpb246KiogVGhlIG92ZXJhbGwgaW5jcmVhc2UgaW4gcHJpY2VzIGZvciBnb29kcyBhbmQgc2VydmljZXMgd2l0aGluIGFuIGVjb25vbXkgaXMga25vd24gYXMgaW5mbGF0aW9uLiBXaGlsZSBleHRyZW1lbHkgbG93IGluZmxhdGlvbiBtYXkgYmUgYSBzaWduIG9mIGEgY29taW5nIHJlY2Vzc2lvbiwgZXhjZXNzaXZlIGluZmxhdGlvbiBtYXkgaW5kaWNhdGUgdGhhdCB0aGUgZWNvbm9teSBpcyBleGNlc3NpdmUuDQoNCiMjIERhdGEgQ29sbGVjdGlvbg0KDQpUaGUgSW5pdGlhbCBzdGVwIGluIGNyZWF0aW5nIGRpZmZ1c2lvbiBpbmRleCBpcyBkYXRhIGNvbGxlY3Rpb24gYW5kIHdlIHdpbGwgb2J0YWluIHRoZSBkYXRhIGZyb20gdGhlIEZlZGVyYWwgUmVzZXJ2ZSBFY29ub21pYyBEYXRhIChGUkVEKSBkYXRhYmFzZS4NCg0KYGBge3J9DQojIE9idGFpbiAzIGVjb25vbWljIEluZGljYXRvcnMgZGF0YSBmcm9tIEZSRUQNCmdldFN5bWJvbHMoYygiUlNBRlNOQSIsICJVTlJBVEUiLCAiQ1BJQVVDU0wiKSwgDQogICAgICAgICAgIGZyZXEgPSAibW9udGhseSIsIA0KICAgICAgICAgICBzcmMgPSAiRlJFRCIsIHJldHVybi5jbGFzcyA9ICd4dHMnLA0KICAgICAgICAgICBpbmRleC5jbGFzcyAgPSAnRGF0ZScsDQogICAgICAgICAgIGZyb20gPSAiMjAxMC0wMS0wMSIsDQogICAgICAgICAgIHRvID0gU3lzLkRhdGUoKSwNCiAgICAgICAgICAgYXV0by5hc3NpZ24gPSBUUlVFKQ0KDQoNCiMgQ3JlYXRlIGEgc2luZ2xlIHRpbWUtc2VyaWVzIGRhdGFzZXQgZnJvbSB0aGUgZGF0YQ0KZGF0YSA8LSBtZXJnZShSU0FGU05BLCBVTlJBVEUsIENQSUFVQ1NMKQ0KY29sbmFtZXMoZGF0YSkgPC0gYygiUmV0YWlsX1NhbGVzIiwgIlVuZW1wbG95bWVudF9SYXRlIiwgIkluZmxhdGlvbl9SYXRlIikNCg0KZGF0YSRkYXRlIDwtIGluZGV4KGRhdGEpDQoNCmBgYA0KDQoNCiMjIERhdGEgVHJhbnNmb3JtYXRpb24gYW5kIFN0YW5kYXJkaXphdGlvbg0KDQpXZSBtdXN0IHRyYW5zZm9ybSBhbmQgc3RhbmRhcmRpemUgdGhlc2UgbWV0cmljcyBzbyB0aGF0IHRoZXkgYXJlIGNvbXBhcmFibGUuIFN0YW5kYXJkaXphdGlvbiBndWFyYW50ZWVzIHRoYXQgdGhlIGRpZmZ1c2lvbiBpbmRleCBpcyBub3Qgc2tld2VkIGJ5IHNjYWxlIHZhcmlhdGlvbnMgYW1vbmcgdGhlIHZhcmlhYmxlcy4gDQoNCmBgYHtyfQ0KZGF0YVtpcy5uYShkYXRhKV0gPC0gMA0KDQojIFN0YW5kYXJkaXplIHNlcmllcw0Kc2NhbGVfZGF0YSA8LSBkYXRhICU+JQ0KICBuYS5vbWl0KCkgJT4lDQogIHNjYWxlKCkgJT4lDQogIGFzLnh0cygpDQoNCmBgYA0KDQoNCiMjIENyZWF0ZSBDdXN0b20gRGlmZnVzaW9uIEluZGV4DQoNCkZpcnN0LCBmb3IgZWFjaCBvZiB0aGUgdGhyZWUgaW5kaWNhdG9ycywgZGV0ZXJtaW5lIGlmIGl0IGlzIGltcHJvdmluZyBvciBkZWNsaW5pbmcgY29tcGFyZWQgdG8gdGhlIHByZXZpb3VzIHBlcmlvZC4gVGhlbiBjYWxjdWxhdGUgdGhlIERpZmZ1c2lvbiBJbmRleCBhcyB0aGUgYXZlcmFnZSBvZiB0aGVzZSBpbXByb3ZlcyBvciBkZWNsaW5lcy4gQnkgYWdncmVnYXRpbmcgdGhlc2UgaW5kaWNhdG9ycywgd2UgY2FuIGdhaW4gYSBicm9hZGVyIHBpY3R1cmUgb2YgdGhlIGdlbmVyYWwgZWNvbm9taWMgdHJlbmRzLg0KDQpgYGB7cn0NCg0KZGF0YSA8LSBhcy5kYXRhLmZyYW1lKHNjYWxlX2RhdGEpDQoNCiMgQ2FsY3VsYXRlIGlmIGVhY2ggdmFyaWFibGUgaXMgaW5jcmVhc2luZyAoMSkgb3IgZGVjbGluaW5nICgtMSkgZnJvbSB0aGUgcHJldmlvdXMgcGVyaW9kDQogZGF0YSA9IGRhdGEgJT4lDQogIG11dGF0ZSgNCiAgICB1bmVtcGxveW1lbnRfZGlmZiA9IGlmZWxzZShVbmVtcGxveW1lbnRfUmF0ZSA8IGxhZyhVbmVtcGxveW1lbnRfUmF0ZSwgZGVmYXVsdCA9IGZpcnN0KFVuZW1wbG95bWVudF9SYXRlKSksIDEsIC0xKSwNCiAgICBzYWxlc19kaWZmID0gaWZlbHNlKFJldGFpbF9TYWxlcyA+IGxhZyhSZXRhaWxfU2FsZXMsIGRlZmF1bHQgPSBmaXJzdChSZXRhaWxfU2FsZXMpKSwgMSwgLTEpLA0KICAgIGluZmxhdGlvbl9kaWZmID0gaWZlbHNlKEluZmxhdGlvbl9SYXRlID4gbGFnKEluZmxhdGlvbl9SYXRlLCBkZWZhdWx0ID0gZmlyc3QoSW5mbGF0aW9uX1JhdGUpKSwgMSwgLTEpDQogICkNCg0KIyBDb25zdHJ1Y3QgZGlmZnVzaW9uIGluZGV4OiBhdmVyYWdlIHVzaW5nIHJvd01lYW5zIA0KZGF0YSRkaWZmdXNpb25faW5kZXggPC0gcm93TWVhbnMoZGF0YVssIGMoInVuZW1wbG95bWVudF9kaWZmIiwgInNhbGVzX2RpZmYiLCAiaW5mbGF0aW9uX2RpZmYiKV0pDQpkYXRhIDwtIHh0cyhkYXRhLCBvcmRlci5ieSA9IGRhdGUpDQoNCg0KYGBgDQoNCg0KIyMgUGxvdHRpbmcgRGlmZnVzaW9uIEluZGV4DQoNClRoZSBmb2xsb3dpbmcgcGxvdCB2aXN1YWxpemVzIHRoZSBkaWZmdXNpb24gaW5kZXggb3ZlciB0aW1lLCB3aXRoIGEgbG9lc3Mgc21vb3RoZXIgYWRkZWQgdG8gaGlnaGxpZ2h0IHRoZSBvdmVyYWxsIHRyZW5kLg0KDQpUaGlzIHBsb3Qgc2hvd3MgdGhlIHByb3BvcnRpb24gb2YgdGhlIHNlbGVjdGVkIGVjb25vbWljIHZhcmlhYmxlcyAodW5lbXBsb3ltZW50IHJhdGUsIGluZmxhdGlvbiByYXRlLCBhbmQgUmV0YWlsIHNhbGVzKSB0aGF0IGFyZSBpbmNyZWFzaW5nIG92ZXIgdGltZS4NCg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCg0KaGVhZChkYXRhKQ0KDQojIFBsb3QgRGlmZnVzaW9uIEluZGV4DQpnZ3Bsb3QoZGF0YSwgYWVzKHggPSBkYXRlLCB5ID0gZGlmZnVzaW9uX2luZGV4KSkgKw0KICBnZW9tX2xpbmUoY29sb3IgPSAicHVycGxlIikgKyANCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgY29sb3IgPSAib3JhbmdlIiwgc2UgPSBUUlVFKSArDQogIGxhYnModGl0bGUgPSAiRGlmZnVzaW9uIEluZGV4IE92ZXIgVGltZSIsIHggPSAiRGF0ZSIsIHkgPSAiRGlmZnVzaW9uIEluZGV4IikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQpgYGANCg0KDQpBIHZhbHVlIGNsb3NlIHRvIDEgaW5kaWNhdGVzIHRoYXQgbW9zdCB2YXJpYWJsZXMgYXJlIGluY3JlYXNpbmcsIHN1Z2dlc3Rpbmcgc3Ryb25nIGVjb25vbWljIGFjdGl2aXR5Lg0KDQpBIHZhbHVlIGNsb3NlIHRvIC0xIGluZGljYXRlcyB0aGF0IG1vc3QgdmFyaWFibGVzIGFyZSBkZWNyZWFzaW5nLCBzdWdnZXN0aW5nIHdlYWsgZWNvbm9taWMgYWN0aXZpdHkuDQoNClRoZSBkaWZmdXNpb24gaW5kZXggaGlnaGxpZ2h0cyBrZXkgZmFjdG9ycyBpbiBlY29ub215LiBBZnRlciAyMDIwLCB0aGUgc2hhZGVkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgc2xpZ2h0bHkgd2lkZW5zLCBpbmRpY2F0aW5nIGEgcmlzZSBpbiB1bmNlcnRhaW50eSBvciBncmVhdGVyIGZsdWN0dWF0aW9uIGluIHRoZSBlY29ub215IG92ZXIgdGhpcyB0aW1lLg0KVGhlIHRyZW5kJ3MgZmxhdHRlbmluZyBhZnRlciAyMDIwIGlzIGNvbnNpc3RlbnQgd2l0aCBtb3JlIGdlbmVyYWwgZWNvbm9taWMgZGlmZmljdWx0aWVzIHN1Y2ggYXMgdGhlIENPVklELTE5IHBhbmRlbWljIGFuZCB0aGUgaW5zdGFiaWxpdHkgdGhhdCBmb2xsb3dlZCB0aGUgcmVjb3ZlcnkuDQpXaGlsZSB0aGUgcHVycGxlIHZhcmlhdGlvbnMgc2VydmUgdG8gaW5kaWNhdGUgdGltZXMgb2YgZWNvbm9taWMgdm9sYXRpbGl0eSwga2VlcGluZyBhbiBleWUgb24gdGhlIG9yYW5nZSB0cmVuZCBsaW5lIGNhbiByZXZlYWwgaW5zaWdodHMgaW50byBlY29ub21pYyB0dXJuaW5nIG1vbWVudHMuSXQgc2hvd3MgYSBzbW9vdGhlciB1cHdhcmQgdHJlbmQgb3ZlciB0aGUgbG9uZyBydW4uDQoNCiMjIENvbXBhcmlzb24gb2YgQ2hpY2FnbyBGZWQgTmF0aW9uYWwgQWN0aXZpdHkgSW5kZXggKENGTkFJKSB3aXRoIEN1c3RvbSBEaWZmdXN0aW9uIEluZGV4DQoNClRoZSBDaGljYWdvIEZlZCBOYXRpb25hbCBBY3Rpdml0eSBJbmRleCAoQ0ZOQUkpIGlzIGEgbWVhc3VyZSBvZiBuYXRpb25hbCBlY29ub21pYyBhY3Rpdml0eS4gV2UgY2FuIGV2YWx1YXRlIHRoZSBkZWdyZWUgdG8gd2hpY2ggb3VyIGNob3NlbiBpbmRpY2F0b3JzIHJlZmxlY3QgZ2VuZXJhbCBlY29ub21pYyB0cmVuZHMgYnkgY29udHJhc3Rpbmcgb3VyIGRpZmZ1c2lvbiBpbmRleCB3aXRoIHRoZSBDRk5BSS4gV2Ugd2lsbCBjb21wYXJlIG91ciBjdXN0b20gZGlmZnVzaW9uIGluZGV4IHdpdGggdGhlIENGTkFJIERpZmZ1c2lvbiBJbmRleCBieSBjYWxjdWxhdGluZyB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQgYW5kIHBsb3R0aW5nIGJvdGggc2VyaWVzIHNpZGUgYnkgc2lkZS4NCg0KYGBge3J9DQojIENvbXBhcmUgQ0ZOQUlESUZGIEluZGV4IHdpdGggRGlmZnVzaW9uIEluZGV4DQpnZXRTeW1ib2xzKCJDRk5BSURJRkYiLCBzcmMgPSAiRlJFRCIsIHJldHVybi5jbGFzcyA9ICd4dHMnLCBpbmRleC5jbGFzcyAgPSAnRGF0ZScsIGZyb20gPSAiMjAxMC0wMS0wMSIsIHRvID0gU3lzLkRhdGUoKSwgYXV0by5hc3NpZ24gPSBUUlVFKQ0KDQpDRk5BSURJRkYkZGF0ZSA8LSBpbmRleChDRk5BSURJRkYpDQoNCmBgYA0KDQpgYGB7cn0NCg0KIyBNZXJnZSBib3RoIGluZGV4ZXMNCmNvbXBhcmlzb25fZGF0YSA8LSBtZXJnZShkYXRhJGRpZmZ1c2lvbl9pbmRleCwgQ0ZOQUlESUZGJENGTkFJRElGRiwgam9pbiA9ICJpbm5lciIpDQoNCmNvbG5hbWVzKGNvbXBhcmlzb25fZGF0YSkgPC0gYygiRGlmZnVzaW9uX0luZGV4IiwgIkNGTkFJRElGRl9JbmRleCIpDQoNCmhlYWQoY29tcGFyaXNvbl9kYXRhKQ0KYGBgDQoNCg0KIyMgQ29ycmVsYXRpb24gQW5hbHlzaXMNCg0KVGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IG1lYXN1cmVzIHRoZSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gZGlmZnVzaW9uIGluZGV4IGFuZCB0aGUgQ0ZOQUkgRGlmZnVzaW9uIEluZGV4LiBTaW1pbGFyIGVjb25vbWljIHRyZW5kcyBhcmUgaW5kaWNhdGVkIGJ5IGEgaGlnaCBwb3NpdGl2ZSBjb3JyZWxhdGlvbiwgd2hpY2ggaW1wbGllcyB0aGF0IHRoZSB0d28gaW5kZXhlcyBtb3ZlIGluIHN5bmNocm9uaXphdGlvbi4NCg0KYGBge3J9DQojIENhbGN1bGF0ZSBjb3JyZWxhdGlvbg0KY29ycmVsYXRpb24gPC0gY29yKGNvbXBhcmlzb25fZGF0YSREaWZmdXNpb25fSW5kZXgsIGNvbXBhcmlzb25fZGF0YSRDRk5BSURJRkZfSW5kZXgsIHVzZSA9ICJjb21wbGV0ZS5vYnMiKQ0KcHJpbnQocGFzdGUoIkNvcnJlbGF0aW9uIENvZWZmaWNpZW50OiAiLCByb3VuZChjb3JyZWxhdGlvbiwgMykpKQ0KYGBgDQoNClRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCB3ZSBnb3QgaXMgMC4xOTUgd2hpY2ggaXMgY29uc2lkZXJlZCB3ZWFrIGFuZCBpbmRpY2F0ZXMgdGhhdCBib3RoIGluZGV4ZXMgYXJlIG5vdCBlbnRpcmVseSBpbiBzeW5jaC4gV2hpbGUgYSB3ZWFrIHBvc2l0aXZlIGNvcnJlbGF0aW9uIG1lYW5zIHRoZXJlIGlzIHNvbWUgcmVsYXRpb25zaGlwLCBpdOKAmXMgbm90IHN0cm9uZyBlbm91Z2ggdG8gY29uY2x1ZGUgdGhhdCB0aGUgaW5kaWNhdG9ycyBhcmUgaW4gc3luYyBvciBjb25zaXN0ZW50bHkgcmVmbGVjdCB0aGUgc2FtZSBlY29ub21pYyB0cmVuZHMuDQoNCiMjIGdncGxvdCBvZiBib3RoIEluZGV4ZXMNCg0KQmVsb3csIHdlIHBsb3QgYm90aCBpbmRleGVzIHNpZGUgYnkgc2lkZSB0byB2aXN1YWxpemUgdGhlaXIgc2ltaWxhcml0aWVzIG9yIGRpZmZlcmVuY2VzIG92ZXIgdGltZS4NCg0KYGBge3J9DQojIHBsb3QgRGlmZnVzaW9uIEluZGV4IGFuZCBDaGljYWdvIEZlZCBJbmRleA0KZ2dwbG90KGNvbXBhcmlzb25fZGF0YSkgKw0KICBnZW9tX2xpbmUoYWVzKHggPSBpbmRleChjb21wYXJpc29uX2RhdGEpLCB5ID0gRGlmZnVzaW9uX0luZGV4KSwgY29sb3IgPSAiY3lhbiIsIGFscGhhID0gMC42KSArDQogIGdlb21fbGluZShhZXMoeCA9IGluZGV4KGNvbXBhcmlzb25fZGF0YSksIHkgPSBDRk5BSURJRkZfSW5kZXgpLCBjb2xvciA9ICJibHVlIiwgYWxwaGEgPSAwLjYpICsNCiAgbGFicyh0aXRsZSA9ICJDb21wYXJpc29uIG9mIERpZmZ1c2lvbiBJbmRleCBhbmQgQ0ZOQUlESUZGIiwgeCA9ICJEYXRlIiwgeSA9ICJJbmRleCBWYWx1ZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgICMgUm90YXRlIHgtYXhpcyBsYWJlbHMgaWYgbmVlZGVkDQoNCg0KYGBgDQoNCg0KV2hlbiB0aGUgdHdvIGluZGljZXMgbW92ZSBpbiBzeW5jIGluIHRoZSBjb21wYXJpc29uIHBsb3QsIGl0IGluZGljYXRlcyB0aGF0IHRoZSBlY29ub21pYyB0cmVuZHMgdGhleSByZXByZXNlbnQgYXJlIHN0cm9uZ2x5IGFsaWduZWQuIFZhcmlhdGlvbnMgYW1vbmcgdGhlIGluZGV4ZXMgY291bGQgaW5kaWNhdGUgdmFyaWF0aW9ucyBpbiBlYWNoIGluZGV4J3MgcmVhY3Rpb24gdG8gcGFydGljdWxhciBlY29ub21pYyBvY2N1cnJlbmNlcyBvciBjcmlzZXMuIFNpbWlsYXIgdG8gdGhlIGRpZmZ1c2lvbiBpbmRleCwgaXQgaW5kaWNhdGVzIHRoZSBwcm9wb3J0aW9uIG9mIHRoZXNlIGluZGljYXRvcnMgdGhhdCBhcmUgaW5jcmVhc2luZy4NCg0KIyMgVGFibGUgb2YgS2V5IE1ldHJpY3M6DQoNCjx0YWJsZT4NCg0KTWV0cmljCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBDdXN0b20gRGlmZnVzaW9uIEluZGV4ICAgCUNGTkFJRElGRg0KLS0tLS0tLS0tLS0tLS0tLS0gICAgICAgICAgICAgICAgICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gICAtLS0tLS0tLS0tLS0tLS0tDQoqKlRpbWUgUGVyaW9kKioJICAgICAgICAgICAgICAgICAgICBKYW4gMjAxMCDigJMgU2VwIDIwMjQJICAgICAgSmFuIDIwMTAg4oCTIFNlcCAyMDI0ICANCioqQ29ycmVsYXRpb24gKEN1c3RvbSB2cyBDRk5BSSkqKgkgIDAuMTk1CSAgICAgICAgICAgICAgICAgICAgMC4xOTUgIA0KKipBdmVyYWdlIFZhbHVlKioJICAgICAgICAgICAgICAgICAgfjAuMDIJICAgICAgICAgICAgICAgICAgICB+LTAuMTAgIA0KKipTdGFuZGFyZCBEZXZpYXRpb24qKgkgICAgICAgICAgICAwLjIxCSAgICAgICAgICAgICAgICAgICAgMC40NSAgDQoNCjwvdGFibGU+DQoNCiMjIEluc2lnaHRzDQoNCjEuVW5wcmVkaWN0YWJsZSBOYXR1cmUgb2YgRWNvbm9teToNCg0KQ29tcGFyZWQgdG8gdGhlIGN1c3RvbSBkaWZmdXNpb24gaW5kZXgsIHRoZSBDRk5BSURJRkYgaXMgbW9yZSBzZW5zaXRpdmUgdG8gdW5kZXJseWluZyBkYXRhIGlucHV0cyBvciBlY29ub21pYyBzaG9ja3MsIGFzIGV2aWRlbmNlZCBieSBpdHMgc3Ryb25nIGZsdWN0dWF0aW9ucy4NCg0KMi5JbmRpY2F0b3Igb2YgRmluYW5jaWFsIENyaXNpczoNCg0KQXMgb2YgdGhlIG1vc3QgcmVjZW50IHN0YXRpc3RpY3MgaW4gU2VwdGVtYmVyIDIwMjQsIHRoZSBmYWxsIGluIGJvdGggaW5kaWNhdG9ycyBjYW4gaW5kaWNhdGUgZGVjcmVhc2luZyBlY29ub21pYyBtb21lbnR1bS4NCg0KMy5DdXN0b20gSW5kZXggU3RhYmlsaXR5Og0KDQpUaGUgY3VzdG9tIGluZGV4J3Mgc21vb3RoZXIgdHJlbmQgbWlnaHQgc3VnZ2VzdCBhIG1vcmUgY29tcHJlaGVuc2l2ZSBhbmQgaW5zZW5zaXRpdmUgdmlldyBvZiB0aGUgc3RhdGUgb2YgdGhlIGVjb25vbXkuDQoNCkFsdGhvdWdoIHRoZXJlIGFyZSBub3RpY2VhYmxlIGRpZmZlcmVuY2VzIGluIGZyZXF1ZW5jeSBhbmQgbWFnbml0dWRlLCBib3RoIGluZGljZXMgc2hvdyBjb21wYXJhYmxlIHBlcmlvZGljIG9zY2lsbGF0aW9ucy5JbiBjb250cmFzdCB0byB0aGUgY3VzdG9tIGluZGV4LCB3aGljaCBtb3ZlcyBtb3JlIHNtb290aGx5LCB0aGUgQ0ZOQUlESUZGIGlzIG1vcmUgdm9sYXRpbGUsIGV4aGliaXRpbmcgc3Ryb25nIHNwaWtlcyBhbmQgZmFsbHMuIEFzIHRoZSBzZXJpZXMgZHJhd3MgdG8gYSBjbG9zZSAoU2VwdGVtYmVyIDIwMjQgZm9yIENGTkFJRElGRiksIGJvdGggaW5kZXhlcyBzaG93IGEgZGVjbGluaW5nIHRlbmRlbmN5LiBUaGlzIGltcGxpZXMgdGhhdCBjdXJyZW50IGVjb25vbWljIGFjdGl2aXR5IG1heSBiZSBzbG93aW5nIGRvd24gb3IgZmFjaW5nIGRpZmZpY3VsdGllcy7CoEluIGNlcnRhaW4gZWNvbm9taWMgY3ljbGVzLCB0aGVyZSBhcmUgcGFyYWxsZWwgbW92ZW1lbnRzIGRlc3BpdGUgdGhlIG1vZGVzdCBjb3JyZWxhdGlvbiAoMC4xOTUpLCBzdWdnZXN0aW5nIHBhcnRpYWwgYWxpZ25tZW50Lg0KDQojIyBDb25jbHVzaW9uOg0KDQpBY2NvcmRpbmcgdG8gdGhlIGNvbXBhcmlzb24sIHRoZSBDRk5BSURJRkYgcmVjb3JkcyBtb3JlIHJlY2VudCBkZXZlbG9wbWVudHMsIHdoZXJlYXMgdGhlIGN1c3RvbSBkaWZmdXNpb24gaW5kZXggb2ZmZXJzIGEgbW9yZSBjb21wcmVoZW5zaXZlIHBpY3R1cmUgb2YgZWNvbm9taWMgc3RhYmlsaXR5LiBCb3RoIGluZGljZXMgcG9pbnQgdG8gYSBwb3NzaWJsZSBzbG93ZG93biBpbiB0aGUgZWNvbm9teSBhcyBvZiBTZXB0ZW1iZXIgMjAyNDsgYWRkaXRpb25hbCBvYnNlcnZhdGlvbiBvZiB1cGNvbWluZyBkYXRhIGlzIG5lY2Vzc2FyeSB0byB2YWxpZGF0ZSB0aGVzZSBpbmRpY2F0b3JzLg0KDQoqTGFrc2htaSBQcmF0aHl1c2hhIE1hbmRhZGksIEd1aWRhbmNlIGJ5IFByb2YgRHIgQS5FLiBSb2RyaWd1ZXosIFBvbXBlYSBDb2xsZWdlIG9mIEJ1c2luZXNzLCBVbml2ZXJzaXR5IG9mIE5ldyBIYXZlbioNCg0KbG1hbmQ2QHVuaC5uZXdoYXZlbi5lZHUNCg0K