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.
# Obtain 3 economic Indicators data from FRED
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"
# Create a single time-series dataset from the data
data <- merge(RSAFSNA, UNRATE, CPIAUCSL)
colnames(data) <- c("Retail_Sales", "Unemployment_Rate", "Inflation_Rate")
data$date <- index(data)
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 increasing (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)
)
# Construct diffusion index: average using rowMeans
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
# Plot Diffusion Index
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.
# Compare CFNAIDIFF Index with Diffusion Index
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)
# Merge both indexes
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.
# Calculate correlation
corr <- cor(comparison_data$Diffusion_Index, comparison_data$CFNAIDIFF_Index, use = "complete.obs")
print(paste("Correlation Coefficient: ", round(corr, 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.
# plot 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:
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
lmand6@unh.newhaven.edu
LS0tDQp0aXRsZTogIkRpZmZ1c2lvbiBDb25mdXNpb24iDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KDQogICAgICBvcHRpb25zKGRpZ2l0cyA9IDMsIHNjaXBlbiA9IDk5OTksIHN0cmluZ2FzRmFjdG9ycyA9IEZBTFNFKQ0KICAgICAgcmVtb3ZlKGxpc3QgPSBscygpKQ0KICAgICAgZ3JhcGhpY3Mub2ZmKCkNCg0KI0xvYWQgbGlicmFyaWVzID09PT09PT09PT09PT09PT09PT09PT0NCnN1cHByZXNzV2FybmluZ3Moew0KICBzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoew0KICAgIGxpYnJhcnkodGlkeXZlcnNlKQ0KICAgIGxpYnJhcnkobHVicmlkYXRlKQ0KICAgIGxpYnJhcnkoZ2d0aGVtZXMpDQogICAgbGlicmFyeShjb3dwbG90KQ0KICAgIGxpYnJhcnkodHNib3gpICNjb252ZXJ0IHh0cyB0byB0c2liYmxlDQogICAgbGlicmFyeShUU3N0dWRpbykNCiAgICBsaWJyYXJ5KHRzdXRpbHMpDQogICAgbGlicmFyeShyaW8pDQogICAgbGlicmFyeShyZWFkeGwpDQogICAgbGlicmFyeShmb3JlY2FzdCkNCiAgICBsaWJyYXJ5KHF1YW50bW9kKQ0KICAgIGxpYnJhcnkoVFNzdHVkaW8pDQogICAgbGlicmFyeShsdWJyaWRhdGUpDQogICAgbGlicmFyeShkeWdyYXBocykNCiAgICBsaWJyYXJ5KHRzZXJpZXMpDQogICAgIyBTZWNvbmRhcnkgcGFja2FnZXMgICAgICAgIA0KICAgIGxpYnJhcnkodHNpYmJsZSkNCiAgICBsaWJyYXJ5KGZhYmxlKQ0KICAgIGxpYnJhcnkodHNpYmJsZWRhdGEpDQogICAgbGlicmFyeShmZWFzdHMpDQogICAgbGlicmFyeShmcHAyKQ0KICAgIGxpYnJhcnkoZnBwMykNCiAgICBsaWJyYXJ5KHh0cykNCiAgICBsaWJyYXJ5KHpvbykNCiAgICBsaWJyYXJ5KHZhcnMpDQogICAgbGlicmFyeShzdGFyZ2F6ZXIpDQogICAgbGlicmFyeShDYXVzYWxJbXBhY3QpDQogIH0pDQp9KQ0KDQoNCmBgYA0KDQoqQXV0aG9yOiBMYWtzaG1pIFByYXRoeXVzaGEgTWFuZGFkaSogICANCipDb3Vyc2U6IEJ1c2luZXNzIEZvcmVjYXN0aW5nLCBFQ09OLTY2MzUtMDcqICANCipQdWJsaXNoZWQ6IERlY2VtYmVyIDEzLCAyMDI0Kg0KDQojIyBJbnRyb2R1Y3Rpb24NCg0KRGlmZnVzaW9uIEluZGV4IGlzIGFuIGFuYWx5dGljYWwgdG9vbCBmb3IgZXZhbHVhdGluZyB0aGUgZGVwdGggYW5kIHNjb3BlIG9mIHRyZW5kcyBpbiBkaWZmZXJlbnQgZmluYW5jaWFsIG1hcmtldHMgb3IgZWNvbm9taWMgc2VjdG9ycy4gVXNpbmcgaW1wb3J0YW50IGVjb25vbWljIGRhdGEsIHRoaXMgcmVzZWFyY2ggc2Vla3MgdG8gZGV2ZWxvcCBhbmQgZXZhbHVhdGUgYSBkaWZmdXNpb24gaW5kZXggZm9yIHRoZSBVUyB0aGF0IG9mZmVycyBhIHRob3JvdWdoIHVuZGVyc3RhbmRpbmcgb2YgZWNvbm9taWMgYWN0aXZpdHkuIFRoaXMgaW5kaWNhdG9yIGFpZHMgYW5hbHlzdHMgaW4gZGV0ZXJtaW5pbmcgdGhlIHN0cmVuZ3RoIG9yIHdlYWtuZXNzIG9mIGVjb25vbWljIGN5Y2xlcyBvciBtYXJrZXQgdHJlbmRzLkl0IG1lYXN1cmVzIHRoZSBwcm9wb3J0aW9uIG9mIGluZGl2aWR1YWwgY29tcG9uZW50cyBpbiBhIGRhdGFzZXQgdGhhdCBhcmUgc2hvd2luZyBwb3NpdGl2ZSBjaGFuZ2VzIGluIHJlbGF0aW9uIHRvIHRoZSB0b3RhbCBudW1iZXIgb2YgY29tcG9uZW50cy4gSXQgaXMgaW1wb3J0YW50IGZvciB0cmVuZCBhbmFseXNpcyBhbmQgZGVjaXNpb24gIG1ha2luZy4NCg0KVGhlIHRocmVlIGVjb25vbWljIGluZGljYXRvcnMgdG8gY3JlYXRlIGRpZmZ1c2lvbiBpbmRleCBJIGhhdmUgY2hvc2VuIGFyZSBSZXRhaWwgU2FsZXMgKFJTQUZTTkEpLCBVbmVtcGxveW1lbnQgUmF0ZSAoVU5SQVRFKSBhbmQgSW5mbGF0aW9uIChDUElBVUNTTCkuDQoNCioqUmV0YWlsIFNhbGVzOioqIFRoZSBoZWFsdGggb2YgY29uc3VtZXIgc3BlbmRpbmcgaXMgaW5kaWNhdGVkIGJ5IHRoZSBDZW5zdXMgQnVyZWF1J3MgbW9udGhseSByZXBvcnQgb24gcmV0YWlsIGFuZCBmb29kIHNlcnZpY2VzIHNhbGVzLiBSZXRhaWwgc2FsZXMgaW4gYSB2YXJpZXR5IG9mIGluZHVzdHJpZXMsIGluY2x1ZGluZyBkZXBhcnRtZW50IHN0b3JlcywgZnVybml0dXJlIHN0b3JlcywgYW5kIGhvbWUgZnVybmlzaGluZ3Mgc3RvcmVzLCBhcmUgc2hvd24gaW4gdGhpcyByZXBvcnQuICANCg0KKipVbmVtcGxveW1lbnQgUmF0ZToqKiBUaGUgdW5lbXBsb3ltZW50IHJhdGUgaXMgb25lIG9mIHRoZSBtYWluIGluZGljYXRvciBvZiBsYWJvciBtYXJrZXQgaGVhbHRoIGFuZCBvdmVyYWxsIGVjb25vbWljIGFjdGl2aXR5LiBBIGxvd2VyIHVuZW1wbG95bWVudCByYXRlIGRlbm90ZXMgZWNvbm9taWMgZXhwYW5zaW9uIGFuZCBoaWdoZXIgY29uc3VtZXIgc3BlbmRpbmcsIHdoZXJlYXMgYW4gaW5jcmVhc2UgaW4gaXQgZGVub3RlcyBhbiBlY29ub21pYyByZWNlc3Npb24uICANCg0KKipJbmZsYXRpb246KiogVGhlIG92ZXJhbGwgaW5jcmVhc2UgaW4gcHJpY2VzIGZvciBnb29kcyBhbmQgc2VydmljZXMgd2l0aGluIGFuIGVjb25vbXkgaXMga25vd24gYXMgaW5mbGF0aW9uLiBXaGlsZSBleHRyZW1lbHkgbG93IGluZmxhdGlvbiBtYXkgYmUgYSBzaWduIG9mIGEgY29taW5nIHJlY2Vzc2lvbiwgZXhjZXNzaXZlIGluZmxhdGlvbiBtYXkgaW5kaWNhdGUgdGhhdCB0aGUgZWNvbm9teSBpcyBleGNlc3NpdmUuDQoNCiMjIERhdGEgQ29sbGVjdGlvbg0KDQpUaGUgSW5pdGlhbCBzdGVwIGluIGNyZWF0aW5nIGRpZmZ1c2lvbiBpbmRleCBpcyBkYXRhIGNvbGxlY3Rpb24gYW5kIHdlIHdpbGwgb2J0YWluIHRoZSBkYXRhIGZyb20gdGhlIEZlZGVyYWwgUmVzZXJ2ZSBFY29ub21pYyBEYXRhIChGUkVEKSBkYXRhYmFzZS4NCg0KYGBge3J9DQojIE9idGFpbiAzIGVjb25vbWljIEluZGljYXRvcnMgZGF0YSBmcm9tIEZSRUQNCmdldFN5bWJvbHMoYygiUlNBRlNOQSIsICJVTlJBVEUiLCAiQ1BJQVVDU0wiKSwgDQogICAgICAgICAgIGZyZXEgPSAibW9udGhseSIsIA0KICAgICAgICAgICBzcmMgPSAiRlJFRCIsIHJldHVybi5jbGFzcyA9ICd4dHMnLA0KICAgICAgICAgICBpbmRleC5jbGFzcyAgPSAnRGF0ZScsDQogICAgICAgICAgIGZyb20gPSAiMjAxMC0wMS0wMSIsDQogICAgICAgICAgIHRvID0gU3lzLkRhdGUoKSwNCiAgICAgICAgICAgYXV0by5hc3NpZ24gPSBUUlVFKQ0KDQoNCiMgQ3JlYXRlIGEgc2luZ2xlIHRpbWUtc2VyaWVzIGRhdGFzZXQgZnJvbSB0aGUgZGF0YQ0KZGF0YSA8LSBtZXJnZShSU0FGU05BLCBVTlJBVEUsIENQSUFVQ1NMKQ0KY29sbmFtZXMoZGF0YSkgPC0gYygiUmV0YWlsX1NhbGVzIiwgIlVuZW1wbG95bWVudF9SYXRlIiwgIkluZmxhdGlvbl9SYXRlIikNCg0KZGF0YSRkYXRlIDwtIGluZGV4KGRhdGEpDQoNCmBgYA0KDQoNCiMjIERhdGEgVHJhbnNmb3JtYXRpb24gYW5kIFN0YW5kYXJkaXphdGlvbg0KDQpXZSBtdXN0IHRyYW5zZm9ybSBhbmQgc3RhbmRhcmRpemUgdGhlc2UgbWV0cmljcyBzbyB0aGF0IHRoZXkgYXJlIGNvbXBhcmFibGUuIFN0YW5kYXJkaXphdGlvbiBndWFyYW50ZWVzIHRoYXQgdGhlIGRpZmZ1c2lvbiBpbmRleCBpcyBub3Qgc2tld2VkIGJ5IHNjYWxlIHZhcmlhdGlvbnMgYW1vbmcgdGhlIHZhcmlhYmxlcy4gDQoNCmBgYHtyfQ0KIyBUcmFuc2Zvcm0gZGF0YQ0KZGF0YVtpcy5uYShkYXRhKV0gPC0gMA0KDQojIFN0YW5kYXJkaXplIHNlcmllcw0Kc2NhbGVfZGF0YSA8LSBkYXRhICU+JQ0KICBuYS5vbWl0KCkgJT4lDQogIHNjYWxlKCkgJT4lDQogIGFzLnh0cygpDQoNCmBgYA0KDQoNCiMjIENyZWF0ZSBDdXN0b20gRGlmZnVzaW9uIEluZGV4DQoNCkZpcnN0LCBmb3IgZWFjaCBvZiB0aGUgdGhyZWUgaW5kaWNhdG9ycywgZGV0ZXJtaW5lIGlmIGl0IGlzIGltcHJvdmluZyBvciBkZWNsaW5pbmcgY29tcGFyZWQgdG8gdGhlIHByZXZpb3VzIHBlcmlvZC4gVGhlbiBjYWxjdWxhdGUgdGhlIERpZmZ1c2lvbiBJbmRleCBhcyB0aGUgYXZlcmFnZSBvZiB0aGVzZSBpbXByb3ZlcyBvciBkZWNsaW5lcy4gQnkgYWdncmVnYXRpbmcgdGhlc2UgaW5kaWNhdG9ycywgd2UgY2FuIGdhaW4gYSBicm9hZGVyIHBpY3R1cmUgb2YgdGhlIGdlbmVyYWwgZWNvbm9taWMgdHJlbmRzLg0KDQpgYGB7cn0NCg0KZGF0YSA8LSBhcy5kYXRhLmZyYW1lKHNjYWxlX2RhdGEpDQoNCiMgQ2FsY3VsYXRlIGlmIGVhY2ggdmFyaWFibGUgaXMgaW5jcmVhc2luZyAoMSkgb3IgZGVjbGluaW5nICgtMSkgZnJvbSB0aGUgcHJldmlvdXMgcGVyaW9kDQogZGF0YSA9IGRhdGEgJT4lDQogIG11dGF0ZSgNCiAgICB1bmVtcGxveW1lbnRfZGlmZiA9IGlmZWxzZShVbmVtcGxveW1lbnRfUmF0ZSA8IGxhZyhVbmVtcGxveW1lbnRfUmF0ZSwgZGVmYXVsdCA9IGZpcnN0KFVuZW1wbG95bWVudF9SYXRlKSksIDEsIC0xKSwNCiAgICBzYWxlc19kaWZmID0gaWZlbHNlKFJldGFpbF9TYWxlcyA+IGxhZyhSZXRhaWxfU2FsZXMsIGRlZmF1bHQgPSBmaXJzdChSZXRhaWxfU2FsZXMpKSwgMSwgLTEpLA0KICAgIGluZmxhdGlvbl9kaWZmID0gaWZlbHNlKEluZmxhdGlvbl9SYXRlID4gbGFnKEluZmxhdGlvbl9SYXRlLCBkZWZhdWx0ID0gZmlyc3QoSW5mbGF0aW9uX1JhdGUpKSwgMSwgLTEpDQogICkNCg0KIyBDb25zdHJ1Y3QgZGlmZnVzaW9uIGluZGV4OiBhdmVyYWdlIHVzaW5nIHJvd01lYW5zIA0KZGF0YSRkaWZmdXNpb25faW5kZXggPC0gcm93TWVhbnMoZGF0YVssIGMoInVuZW1wbG95bWVudF9kaWZmIiwgInNhbGVzX2RpZmYiLCAiaW5mbGF0aW9uX2RpZmYiKV0pDQpkYXRhIDwtIHh0cyhkYXRhLCBvcmRlci5ieSA9IGRhdGUpDQoNCg0KYGBgDQoNCg0KIyMgUGxvdHRpbmcgRGlmZnVzaW9uIEluZGV4DQoNClRoZSBmb2xsb3dpbmcgcGxvdCB2aXN1YWxpemVzIHRoZSBkaWZmdXNpb24gaW5kZXggb3ZlciB0aW1lLCB3aXRoIGEgbG9lc3Mgc21vb3RoZXIgYWRkZWQgdG8gaGlnaGxpZ2h0IHRoZSBvdmVyYWxsIHRyZW5kLg0KDQpUaGlzIHBsb3Qgc2hvd3MgdGhlIHByb3BvcnRpb24gb2YgdGhlIHNlbGVjdGVkIGVjb25vbWljIHZhcmlhYmxlcyAodW5lbXBsb3ltZW50IHJhdGUsIGluZmxhdGlvbiByYXRlLCBhbmQgUmV0YWlsIHNhbGVzKSB0aGF0IGFyZSBpbmNyZWFzaW5nIG92ZXIgdGltZS4NCg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCg0KaGVhZChkYXRhKQ0KDQojIFBsb3QgRGlmZnVzaW9uIEluZGV4DQpnZ3Bsb3QoZGF0YSwgYWVzKHggPSBkYXRlLCB5ID0gZGlmZnVzaW9uX2luZGV4KSkgKw0KICBnZW9tX2xpbmUoY29sb3IgPSAicHVycGxlIikgKyANCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgY29sb3IgPSAib3JhbmdlIiwgc2UgPSBUUlVFKSArDQogIGxhYnModGl0bGUgPSAiRGlmZnVzaW9uIEluZGV4IE92ZXIgVGltZSIsIHggPSAiRGF0ZSIsIHkgPSAiRGlmZnVzaW9uIEluZGV4IikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQpgYGANCg0KDQpBIHZhbHVlIGNsb3NlIHRvIDEgaW5kaWNhdGVzIHRoYXQgbW9zdCB2YXJpYWJsZXMgYXJlIGluY3JlYXNpbmcsIHN1Z2dlc3Rpbmcgc3Ryb25nIGVjb25vbWljIGFjdGl2aXR5Lg0KDQpBIHZhbHVlIGNsb3NlIHRvIC0xIGluZGljYXRlcyB0aGF0IG1vc3QgdmFyaWFibGVzIGFyZSBkZWNyZWFzaW5nLCBzdWdnZXN0aW5nIHdlYWsgZWNvbm9taWMgYWN0aXZpdHkuDQoNClRoZSBkaWZmdXNpb24gaW5kZXggaGlnaGxpZ2h0cyBrZXkgZmFjdG9ycyBpbiBlY29ub215LiBBZnRlciAyMDIwLCB0aGUgc2hhZGVkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgc2xpZ2h0bHkgd2lkZW5zLCBpbmRpY2F0aW5nIGEgcmlzZSBpbiB1bmNlcnRhaW50eSBvciBncmVhdGVyIGZsdWN0dWF0aW9uIGluIHRoZSBlY29ub215IG92ZXIgdGhpcyB0aW1lLg0KVGhlIHRyZW5kJ3MgZmxhdHRlbmluZyBhZnRlciAyMDIwIGlzIGNvbnNpc3RlbnQgd2l0aCBtb3JlIGdlbmVyYWwgZWNvbm9taWMgZGlmZmljdWx0aWVzIHN1Y2ggYXMgdGhlIENPVklELTE5IHBhbmRlbWljIGFuZCB0aGUgaW5zdGFiaWxpdHkgdGhhdCBmb2xsb3dlZCB0aGUgcmVjb3ZlcnkuDQpXaGlsZSB0aGUgcHVycGxlIHZhcmlhdGlvbnMgc2VydmUgdG8gaW5kaWNhdGUgdGltZXMgb2YgZWNvbm9taWMgdm9sYXRpbGl0eSwga2VlcGluZyBhbiBleWUgb24gdGhlIG9yYW5nZSB0cmVuZCBsaW5lIGNhbiByZXZlYWwgaW5zaWdodHMgaW50byBlY29ub21pYyB0dXJuaW5nIG1vbWVudHMuSXQgc2hvd3MgYSBzbW9vdGhlciB1cHdhcmQgdHJlbmQgb3ZlciB0aGUgbG9uZyBydW4uDQoNCiMjIENvbXBhcmlzb24gb2YgQ2hpY2FnbyBGZWQgTmF0aW9uYWwgQWN0aXZpdHkgSW5kZXggKENGTkFJKSB3aXRoIEN1c3RvbSBEaWZmdXN0aW9uIEluZGV4DQoNClRoZSBDaGljYWdvIEZlZCBOYXRpb25hbCBBY3Rpdml0eSBJbmRleCAoQ0ZOQUkpIGlzIGEgbWVhc3VyZSBvZiBuYXRpb25hbCBlY29ub21pYyBhY3Rpdml0eS4gV2UgY2FuIGV2YWx1YXRlIHRoZSBkZWdyZWUgdG8gd2hpY2ggb3VyIGNob3NlbiBpbmRpY2F0b3JzIHJlZmxlY3QgZ2VuZXJhbCBlY29ub21pYyB0cmVuZHMgYnkgY29udHJhc3Rpbmcgb3VyIGRpZmZ1c2lvbiBpbmRleCB3aXRoIHRoZSBDRk5BSS4gV2Ugd2lsbCBjb21wYXJlIG91ciBjdXN0b20gZGlmZnVzaW9uIGluZGV4IHdpdGggdGhlIENGTkFJIERpZmZ1c2lvbiBJbmRleCBieSBjYWxjdWxhdGluZyB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQgYW5kIHBsb3R0aW5nIGJvdGggc2VyaWVzIHNpZGUgYnkgc2lkZS4NCg0KYGBge3J9DQojIENvbXBhcmUgQ0ZOQUlESUZGIEluZGV4IHdpdGggRGlmZnVzaW9uIEluZGV4DQpnZXRTeW1ib2xzKCJDRk5BSURJRkYiLCBzcmMgPSAiRlJFRCIsIHJldHVybi5jbGFzcyA9ICd4dHMnLCBpbmRleC5jbGFzcyAgPSAnRGF0ZScsIGZyb20gPSAiMjAxMC0wMS0wMSIsIHRvID0gU3lzLkRhdGUoKSwgYXV0by5hc3NpZ24gPSBUUlVFKQ0KDQpDRk5BSURJRkYkZGF0ZSA8LSBpbmRleChDRk5BSURJRkYpDQoNCmBgYA0KDQpgYGB7cn0NCg0KIyBNZXJnZSBib3RoIGluZGV4ZXMNCmNvbXBhcmlzb25fZGF0YSA8LSBtZXJnZShkYXRhJGRpZmZ1c2lvbl9pbmRleCwgQ0ZOQUlESUZGJENGTkFJRElGRiwgam9pbiA9ICJpbm5lciIpDQoNCmNvbG5hbWVzKGNvbXBhcmlzb25fZGF0YSkgPC0gYygiRGlmZnVzaW9uX0luZGV4IiwgIkNGTkFJRElGRl9JbmRleCIpDQoNCmhlYWQoY29tcGFyaXNvbl9kYXRhKQ0KYGBgDQoNCg0KIyMgQ29ycmVsYXRpb24gQW5hbHlzaXMNCg0KVGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IG1lYXN1cmVzIHRoZSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gZGlmZnVzaW9uIGluZGV4IGFuZCB0aGUgQ0ZOQUkgRGlmZnVzaW9uIEluZGV4LiBTaW1pbGFyIGVjb25vbWljIHRyZW5kcyBhcmUgaW5kaWNhdGVkIGJ5IGEgaGlnaCBwb3NpdGl2ZSBjb3JyZWxhdGlvbiwgd2hpY2ggaW1wbGllcyB0aGF0IHRoZSB0d28gaW5kZXhlcyBtb3ZlIGluIHN5bmNocm9uaXphdGlvbi4NCg0KYGBge3J9DQojIENhbGN1bGF0ZSBjb3JyZWxhdGlvbg0KY29yciA8LSBjb3IoY29tcGFyaXNvbl9kYXRhJERpZmZ1c2lvbl9JbmRleCwgY29tcGFyaXNvbl9kYXRhJENGTkFJRElGRl9JbmRleCwgdXNlID0gImNvbXBsZXRlLm9icyIpDQpwcmludChwYXN0ZSgiQ29ycmVsYXRpb24gQ29lZmZpY2llbnQ6ICIsIHJvdW5kKGNvcnIsIDMpKSkNCmBgYA0KDQpUaGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQgd2UgZ290IGlzIDAuMTk1IHdoaWNoIGlzIGNvbnNpZGVyZWQgd2VhayBhbmQgaW5kaWNhdGVzIHRoYXQgYm90aCBpbmRleGVzIGFyZSBub3QgZW50aXJlbHkgaW4gc3luY2guIFdoaWxlIGEgd2VhayBwb3NpdGl2ZSBjb3JyZWxhdGlvbiBtZWFucyB0aGVyZSBpcyBzb21lIHJlbGF0aW9uc2hpcCwgaXTigJlzIG5vdCBzdHJvbmcgZW5vdWdoIHRvIGNvbmNsdWRlIHRoYXQgdGhlIGluZGljYXRvcnMgYXJlIGluIHN5bmMgb3IgY29uc2lzdGVudGx5IHJlZmxlY3QgdGhlIHNhbWUgZWNvbm9taWMgdHJlbmRzLg0KDQojIyBnZ3Bsb3Qgb2YgYm90aCBJbmRleGVzDQoNCkJlbG93LCB3ZSBwbG90IGJvdGggaW5kZXhlcyBzaWRlIGJ5IHNpZGUgdG8gdmlzdWFsaXplIHRoZWlyIHNpbWlsYXJpdGllcyBvciBkaWZmZXJlbmNlcyBvdmVyIHRpbWUuDQoNCmBgYHtyfQ0KIyBwbG90IERpZmZ1c2lvbiBJbmRleCBhbmQgQ2hpY2FnbyBGZWQgSW5kZXgNCmdncGxvdChjb21wYXJpc29uX2RhdGEpICsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gaW5kZXgoY29tcGFyaXNvbl9kYXRhKSwgeSA9IERpZmZ1c2lvbl9JbmRleCksIGNvbG9yID0gImN5YW4iLCBhbHBoYSA9IDAuNikgKw0KICBnZW9tX2xpbmUoYWVzKHggPSBpbmRleChjb21wYXJpc29uX2RhdGEpLCB5ID0gQ0ZOQUlESUZGX0luZGV4KSwgY29sb3IgPSAiYmx1ZSIsIGFscGhhID0gMC42KSArDQogIGxhYnModGl0bGUgPSAiQ29tcGFyaXNvbiBvZiBEaWZmdXNpb24gSW5kZXggYW5kIENGTkFJRElGRiIsIHggPSAiRGF0ZSIsIHkgPSAiSW5kZXggVmFsdWUiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCldoZW4gdGhlIHR3byBpbmRpY2VzIG1vdmUgaW4gc3luYyBpbiB0aGUgY29tcGFyaXNvbiBwbG90LCBpdCBpbmRpY2F0ZXMgdGhhdCB0aGUgZWNvbm9taWMgdHJlbmRzIHRoZXkgcmVwcmVzZW50IGFyZSBzdHJvbmdseSBhbGlnbmVkLiBWYXJpYXRpb25zIGFtb25nIHRoZSBpbmRleGVzIGNvdWxkIGluZGljYXRlIHZhcmlhdGlvbnMgaW4gZWFjaCBpbmRleCdzIHJlYWN0aW9uIHRvIHBhcnRpY3VsYXIgZWNvbm9taWMgb2NjdXJyZW5jZXMgb3IgY3Jpc2VzLiBTaW1pbGFyIHRvIHRoZSBkaWZmdXNpb24gaW5kZXgsIGl0IGluZGljYXRlcyB0aGUgcHJvcG9ydGlvbiBvZiB0aGVzZSBpbmRpY2F0b3JzIHRoYXQgYXJlIGluY3JlYXNpbmcuDQoNCiMjIFRhYmxlIG9mIEtleSBNZXRyaWNzOg0KDQo8dGFibGU+DQoNCk1ldHJpYwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3VzdG9tIERpZmZ1c2lvbiBJbmRleCAgIAlDRk5BSURJRkYNCi0tLS0tLS0tLS0tLS0tLS0tICAgICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICAgLS0tLS0tLS0tLS0tLS0tLQ0KKipUaW1lIFBlcmlvZCoqCSAgICAgICAgICAgICAgICAgICAgSmFuIDIwMTAg4oCTIFNlcCAyMDI0CSAgICAgIEphbiAyMDEwIOKAkyBTZXAgMjAyNCAgDQoqKkNvcnJlbGF0aW9uIChDdXN0b20gdnMgQ0ZOQUkpKioJICAwLjE5NQkgICAgICAgICAgICAgICAgICAgIDAuMTk1ICANCioqQXZlcmFnZSBWYWx1ZSoqCSAgICAgICAgICAgICAgICAgIH4wLjAyCSAgICAgICAgICAgICAgICAgICAgfi0wLjEwICANCioqU3RhbmRhcmQgRGV2aWF0aW9uKioJICAgICAgICAgICAgMC4yMQkgICAgICAgICAgICAgICAgICAgIDAuNDUgIA0KDQo8L3RhYmxlPg0KDQojIyBJbnNpZ2h0cw0KDQoxLlVucHJlZGljdGFibGUgTmF0dXJlIG9mIEVjb25vbXk6DQoNCkNvbXBhcmVkIHRvIHRoZSBjdXN0b20gZGlmZnVzaW9uIGluZGV4LCB0aGUgQ0ZOQUlESUZGIGlzIG1vcmUgc2Vuc2l0aXZlIHRvIHVuZGVybHlpbmcgZGF0YSBpbnB1dHMgb3IgZWNvbm9taWMgc2hvY2tzLCBhcyBldmlkZW5jZWQgYnkgaXRzIHN0cm9uZyBmbHVjdHVhdGlvbnMuDQoNCjIuSW5kaWNhdG9yIG9mIEZpbmFuY2lhbCBDcmlzaXM6DQoNCkFzIG9mIHRoZSBtb3N0IHJlY2VudCBzdGF0aXN0aWNzIGluIFNlcHRlbWJlciAyMDI0LCB0aGUgZmFsbCBpbiBib3RoIGluZGljYXRvcnMgY2FuIGluZGljYXRlIGRlY3JlYXNpbmcgZWNvbm9taWMgbW9tZW50dW0uDQoNCjMuQ3VzdG9tIEluZGV4IFN0YWJpbGl0eToNCg0KVGhlIGN1c3RvbSBpbmRleCdzIHNtb290aGVyIHRyZW5kIG1pZ2h0IHN1Z2dlc3QgYSBtb3JlIGNvbXByZWhlbnNpdmUgYW5kIGluc2Vuc2l0aXZlIHZpZXcgb2YgdGhlIHN0YXRlIG9mIHRoZSBlY29ub215Lg0KDQpBbHRob3VnaCB0aGVyZSBhcmUgbm90aWNlYWJsZSBkaWZmZXJlbmNlcyBpbiBmcmVxdWVuY3kgYW5kIG1hZ25pdHVkZSwgYm90aCBpbmRpY2VzIHNob3cgY29tcGFyYWJsZSBwZXJpb2RpYyBvc2NpbGxhdGlvbnMuSW4gY29udHJhc3QgdG8gdGhlIGN1c3RvbSBpbmRleCwgd2hpY2ggbW92ZXMgbW9yZSBzbW9vdGhseSwgdGhlIENGTkFJRElGRiBpcyBtb3JlIHZvbGF0aWxlLCBleGhpYml0aW5nIHN0cm9uZyBzcGlrZXMgYW5kIGZhbGxzLiBBcyB0aGUgc2VyaWVzIGRyYXdzIHRvIGEgY2xvc2UgKFNlcHRlbWJlciAyMDI0IGZvciBDRk5BSURJRkYpLCBib3RoIGluZGV4ZXMgc2hvdyBhIGRlY2xpbmluZyB0ZW5kZW5jeS4gVGhpcyBpbXBsaWVzIHRoYXQgY3VycmVudCBlY29ub21pYyBhY3Rpdml0eSBtYXkgYmUgc2xvd2luZyBkb3duIG9yIGZhY2luZyBkaWZmaWN1bHRpZXMuwqBJbiBjZXJ0YWluIGVjb25vbWljIGN5Y2xlcywgdGhlcmUgYXJlIHBhcmFsbGVsIG1vdmVtZW50cyBkZXNwaXRlIHRoZSBtb2Rlc3QgY29ycmVsYXRpb24gKDAuMTk1KSwgc3VnZ2VzdGluZyBwYXJ0aWFsIGFsaWdubWVudC4NCg0KIyMgQ29uY2x1c2lvbjoNCg0KQWNjb3JkaW5nIHRvIHRoZSBjb21wYXJpc29uLCB0aGUgQ0ZOQUlESUZGIHJlY29yZHMgbW9yZSByZWNlbnQgZGV2ZWxvcG1lbnRzLCB3aGVyZWFzIHRoZSBjdXN0b20gZGlmZnVzaW9uIGluZGV4IG9mZmVycyBhIG1vcmUgY29tcHJlaGVuc2l2ZSBwaWN0dXJlIG9mIGVjb25vbWljIHN0YWJpbGl0eS4gQm90aCBpbmRpY2VzIHBvaW50IHRvIGEgcG9zc2libGUgc2xvd2Rvd24gaW4gdGhlIGVjb25vbXkgYXMgb2YgU2VwdGVtYmVyIDIwMjQ7IGFkZGl0aW9uYWwgb2JzZXJ2YXRpb24gb2YgdXBjb21pbmcgZGF0YSBpcyBuZWNlc3NhcnkgdG8gdmFsaWRhdGUgdGhlc2UgaW5kaWNhdG9ycy4NCg0KKkxha3NobWkgUHJhdGh5dXNoYSBNYW5kYWRpLCBHdWlkYW5jZSBieSBQcm9mIERyIEEuRS4gUm9kcmlndWV6LCBQb21wZWEgQ29sbGVnZSBvZiBCdXNpbmVzcywgVW5pdmVyc2l0eSBvZiBOZXcgSGF2ZW4qDQoNCmxtYW5kNkB1bmgubmV3aGF2ZW4uZWR1DQoNCg==