Overview

Has the FED been able to fulfill the mandate given to it by Congress?

Story - 2 : Can the FED Control Inflation and Maintain Full Employment

The Federal Reserve’s mandate from Congress is to control inflation and to maintain low unemployment. These seem to be contradictory objectives. For this story you will need to source the following data for the last 25 years; The Consumer Price Index (CPI) (Bureau of Labor Statistics)

The FED Funds Rate (FRED) (Federal Reserve Board)

Unemployment Rate (Bureau of Labor Statistics)

Loading packages

# Load libraries
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.2.3
library(httr)
## Warning: package 'httr' was built under R version 4.2.3
library(fredr)
## Warning: package 'fredr' was built under R version 4.2.3
#Seting API key
fredr_set_key("131e426d3e90b22277da7f01827483d7")

#Fetching CPI data
cpi_data <- fredr(series_id = "CPIAUCNS")

#Print the fetched data
print(cpi_data)
## # A tibble: 1,333 × 5
##    date       series_id value realtime_start realtime_end
##    <date>     <chr>     <dbl> <date>         <date>      
##  1 1913-01-01 CPIAUCNS    9.8 2024-02-18     2024-02-18  
##  2 1913-02-01 CPIAUCNS    9.8 2024-02-18     2024-02-18  
##  3 1913-03-01 CPIAUCNS    9.8 2024-02-18     2024-02-18  
##  4 1913-04-01 CPIAUCNS    9.8 2024-02-18     2024-02-18  
##  5 1913-05-01 CPIAUCNS    9.7 2024-02-18     2024-02-18  
##  6 1913-06-01 CPIAUCNS    9.8 2024-02-18     2024-02-18  
##  7 1913-07-01 CPIAUCNS    9.9 2024-02-18     2024-02-18  
##  8 1913-08-01 CPIAUCNS    9.9 2024-02-18     2024-02-18  
##  9 1913-09-01 CPIAUCNS   10   2024-02-18     2024-02-18  
## 10 1913-10-01 CPIAUCNS   10   2024-02-18     2024-02-18  
## # ℹ 1,323 more rows
#Using API key
fredr_set_key("131e426d3e90b22277da7f01827483d7")

#Fetching CPI data
cpi_data <- fredr(series_id = "CPIAUCNS")

#Fetching FED Funds Rate data
fed_funds_data <- fredr(series_id = "FEDFUNDS")

#Fetching Unemployment Rate data
unemployment_data <- fredr(series_id = "UNRATE")

#Printing the fetched data
print(cpi_data)
## # A tibble: 1,333 × 5
##    date       series_id value realtime_start realtime_end
##    <date>     <chr>     <dbl> <date>         <date>      
##  1 1913-01-01 CPIAUCNS    9.8 2024-02-18     2024-02-18  
##  2 1913-02-01 CPIAUCNS    9.8 2024-02-18     2024-02-18  
##  3 1913-03-01 CPIAUCNS    9.8 2024-02-18     2024-02-18  
##  4 1913-04-01 CPIAUCNS    9.8 2024-02-18     2024-02-18  
##  5 1913-05-01 CPIAUCNS    9.7 2024-02-18     2024-02-18  
##  6 1913-06-01 CPIAUCNS    9.8 2024-02-18     2024-02-18  
##  7 1913-07-01 CPIAUCNS    9.9 2024-02-18     2024-02-18  
##  8 1913-08-01 CPIAUCNS    9.9 2024-02-18     2024-02-18  
##  9 1913-09-01 CPIAUCNS   10   2024-02-18     2024-02-18  
## 10 1913-10-01 CPIAUCNS   10   2024-02-18     2024-02-18  
## # ℹ 1,323 more rows
print(fed_funds_data)
## # A tibble: 835 × 5
##    date       series_id value realtime_start realtime_end
##    <date>     <chr>     <dbl> <date>         <date>      
##  1 1954-07-01 FEDFUNDS   0.8  2024-02-18     2024-02-18  
##  2 1954-08-01 FEDFUNDS   1.22 2024-02-18     2024-02-18  
##  3 1954-09-01 FEDFUNDS   1.07 2024-02-18     2024-02-18  
##  4 1954-10-01 FEDFUNDS   0.85 2024-02-18     2024-02-18  
##  5 1954-11-01 FEDFUNDS   0.83 2024-02-18     2024-02-18  
##  6 1954-12-01 FEDFUNDS   1.28 2024-02-18     2024-02-18  
##  7 1955-01-01 FEDFUNDS   1.39 2024-02-18     2024-02-18  
##  8 1955-02-01 FEDFUNDS   1.29 2024-02-18     2024-02-18  
##  9 1955-03-01 FEDFUNDS   1.35 2024-02-18     2024-02-18  
## 10 1955-04-01 FEDFUNDS   1.43 2024-02-18     2024-02-18  
## # ℹ 825 more rows
print(unemployment_data)
## # A tibble: 913 × 5
##    date       series_id value realtime_start realtime_end
##    <date>     <chr>     <dbl> <date>         <date>      
##  1 1948-01-01 UNRATE      3.4 2024-02-18     2024-02-18  
##  2 1948-02-01 UNRATE      3.8 2024-02-18     2024-02-18  
##  3 1948-03-01 UNRATE      4   2024-02-18     2024-02-18  
##  4 1948-04-01 UNRATE      3.9 2024-02-18     2024-02-18  
##  5 1948-05-01 UNRATE      3.5 2024-02-18     2024-02-18  
##  6 1948-06-01 UNRATE      3.6 2024-02-18     2024-02-18  
##  7 1948-07-01 UNRATE      3.6 2024-02-18     2024-02-18  
##  8 1948-08-01 UNRATE      3.9 2024-02-18     2024-02-18  
##  9 1948-09-01 UNRATE      3.8 2024-02-18     2024-02-18  
## 10 1948-10-01 UNRATE      3.7 2024-02-18     2024-02-18  
## # ℹ 903 more rows
#Using library dplyr
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.2.3
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
#Filtering data for the last 25 years
cpi_data <- cpi_data %>% filter(date >= Sys.Date() - 365 * 25)
fed_funds_data <- fed_funds_data %>% filter(date >= Sys.Date() - 365 * 25)
unemployment_data <- unemployment_data %>% filter(date >= Sys.Date() - 365 * 25)

#Printing the filtered data
print(cpi_data)
## # A tibble: 299 × 5
##    date       series_id value realtime_start realtime_end
##    <date>     <chr>     <dbl> <date>         <date>      
##  1 1999-03-01 CPIAUCNS   165  2024-02-18     2024-02-18  
##  2 1999-04-01 CPIAUCNS   166. 2024-02-18     2024-02-18  
##  3 1999-05-01 CPIAUCNS   166. 2024-02-18     2024-02-18  
##  4 1999-06-01 CPIAUCNS   166. 2024-02-18     2024-02-18  
##  5 1999-07-01 CPIAUCNS   167. 2024-02-18     2024-02-18  
##  6 1999-08-01 CPIAUCNS   167. 2024-02-18     2024-02-18  
##  7 1999-09-01 CPIAUCNS   168. 2024-02-18     2024-02-18  
##  8 1999-10-01 CPIAUCNS   168. 2024-02-18     2024-02-18  
##  9 1999-11-01 CPIAUCNS   168. 2024-02-18     2024-02-18  
## 10 1999-12-01 CPIAUCNS   168. 2024-02-18     2024-02-18  
## # ℹ 289 more rows
print(fed_funds_data)
## # A tibble: 299 × 5
##    date       series_id value realtime_start realtime_end
##    <date>     <chr>     <dbl> <date>         <date>      
##  1 1999-03-01 FEDFUNDS   4.81 2024-02-18     2024-02-18  
##  2 1999-04-01 FEDFUNDS   4.74 2024-02-18     2024-02-18  
##  3 1999-05-01 FEDFUNDS   4.74 2024-02-18     2024-02-18  
##  4 1999-06-01 FEDFUNDS   4.76 2024-02-18     2024-02-18  
##  5 1999-07-01 FEDFUNDS   4.99 2024-02-18     2024-02-18  
##  6 1999-08-01 FEDFUNDS   5.07 2024-02-18     2024-02-18  
##  7 1999-09-01 FEDFUNDS   5.22 2024-02-18     2024-02-18  
##  8 1999-10-01 FEDFUNDS   5.2  2024-02-18     2024-02-18  
##  9 1999-11-01 FEDFUNDS   5.42 2024-02-18     2024-02-18  
## 10 1999-12-01 FEDFUNDS   5.3  2024-02-18     2024-02-18  
## # ℹ 289 more rows
print(unemployment_data)
## # A tibble: 299 × 5
##    date       series_id value realtime_start realtime_end
##    <date>     <chr>     <dbl> <date>         <date>      
##  1 1999-03-01 UNRATE      4.2 2024-02-18     2024-02-18  
##  2 1999-04-01 UNRATE      4.3 2024-02-18     2024-02-18  
##  3 1999-05-01 UNRATE      4.2 2024-02-18     2024-02-18  
##  4 1999-06-01 UNRATE      4.3 2024-02-18     2024-02-18  
##  5 1999-07-01 UNRATE      4.3 2024-02-18     2024-02-18  
##  6 1999-08-01 UNRATE      4.2 2024-02-18     2024-02-18  
##  7 1999-09-01 UNRATE      4.2 2024-02-18     2024-02-18  
##  8 1999-10-01 UNRATE      4.1 2024-02-18     2024-02-18  
##  9 1999-11-01 UNRATE      4.1 2024-02-18     2024-02-18  
## 10 1999-12-01 UNRATE      4   2024-02-18     2024-02-18  
## # ℹ 289 more rows
#Filtering data for the last 25 years
start_date <- Sys.Date() - 25 * 365  #assuming each year is 365 days
cpi_data <- filter(cpi_data, date >= start_date)
fed_funds_data <- filter(fed_funds_data, date >= start_date)
unemployment_data <- filter(unemployment_data, date >= start_date)

#Plotting Consumer Price Index (CPI) over time
ggplot(cpi_data, aes(x = date, y = value)) +
  geom_line() +
  labs(title = "Consumer Price Index (CPI) Over the Last 25 Years",
       x = "Date",
       y = "CPI")

#Plotting FED Funds Rate over time
ggplot(fed_funds_data, aes(x = date, y = value)) +
  geom_line() +
  labs(title = "FED Funds Rate Over the Last 25 Years",
       x = "Date",
       y = "FED Funds Rate")

#Plotting Unemployment Rate over time
ggplot(unemployment_data, aes(x = date, y = value)) +
  geom_line() +
  labs(title = "Unemployment Rate Over the Last 25 Years",
       x = "Date",
       y = "Unemployment Rate")

Consumer Price Index (CPI) has been steadily increasing in a straight line over the last 25 years, which implies a persistent inflation. In this case it suggests a long-term increase in the general price level of goods and services as an increase of the cost of goods and services. Among other policy implications.

Funds rate (FED) Overall, the zig-zag pattern in the Federal Funds Rate reflects the FED’s efforts to navigate and respond to various economic challenges and changes in inflationary pressures over the years.For example, the significant peak in the early 2000s might have been associated with a period of economic expansion or 2020 Covid.

Unemployment rate (UN rate) the observed trend in the unemployment rate reflects the impact of the COVID-19 pandemic on the labor market and subsequent efforts to address the challenges posed by the crisis.

Inflation

Calculating the inflation rate based on the Consumer Price Index (CPI) data

#Filtering data for the last 25 years
start_date <- Sys.Date() - 25 * 365  # assuming each year is 365 days
cpi_data <- filter(cpi_data, date >= start_date)

#Calculating percentage change in CPI for the last 25 years
cpi_data <- arrange(cpi_data, date)
cpi_data <- mutate(cpi_data, inflation_rate = ((value / lag(value)) - 1) * 100)

#Filtering out the first row as it doesn't have a previous period
cpi_data <- cpi_data %>% filter(!is.na(inflation_rate))

#Printing or visualize the inflation rate for the last 25 years
print(cpi_data)
## # A tibble: 298 × 6
##    date       series_id value realtime_start realtime_end inflation_rate
##    <date>     <chr>     <dbl> <date>         <date>                <dbl>
##  1 1999-04-01 CPIAUCNS   166. 2024-02-18     2024-02-18           0.727 
##  2 1999-05-01 CPIAUCNS   166. 2024-02-18     2024-02-18           0     
##  3 1999-06-01 CPIAUCNS   166. 2024-02-18     2024-02-18           0     
##  4 1999-07-01 CPIAUCNS   167. 2024-02-18     2024-02-18           0.301 
##  5 1999-08-01 CPIAUCNS   167. 2024-02-18     2024-02-18           0.240 
##  6 1999-09-01 CPIAUCNS   168. 2024-02-18     2024-02-18           0.479 
##  7 1999-10-01 CPIAUCNS   168. 2024-02-18     2024-02-18           0.179 
##  8 1999-11-01 CPIAUCNS   168. 2024-02-18     2024-02-18           0.0595
##  9 1999-12-01 CPIAUCNS   168. 2024-02-18     2024-02-18           0     
## 10 2000-01-01 CPIAUCNS   169. 2024-02-18     2024-02-18           0.297 
## # ℹ 288 more rows
#Filtering data for the last 25 years
start_date <- Sys.Date() - 25 * 365  # assuming each year is 365 days
cpi_data <- filter(cpi_data, date >= start_date)
fed_funds_data <- filter(fed_funds_data, date >= start_date)
unemployment_data <- filter(unemployment_data, date >= start_date)

#Calculating percentage change in CPI for the last 25 years
cpi_data <- arrange(cpi_data, date)
cpi_data <- mutate(cpi_data, inflation_rate = ((value / lag(value)) - 1) * 100)

#Filtering out the first row as it doesn't have a previous period
cpi_data <- cpi_data %>% filter(!is.na(inflation_rate))

#Aligning the lengths before binding columns
min_length <- min(length(cpi_data$date), length(unemployment_data$date))
combined_data <- bind_cols(
  cpi_data %>% select(date, inflation_rate),
  unemployment_data %>% slice(1:min_length) %>% select(date, value),
  fed_funds_data %>% slice(1:min_length) %>% select(date, value)
)
## New names:
## • `date` -> `date...1`
## • `date` -> `date...3`
## • `value` -> `value...4`
## • `date` -> `date...5`
## • `value` -> `value...6`
#Printing or visualize the combined data
print(combined_data)
## # A tibble: 297 × 6
##    date...1   inflation_rate date...3   value...4 date...5   value...6
##    <date>              <dbl> <date>         <dbl> <date>         <dbl>
##  1 1999-05-01         0      1999-03-01       4.2 1999-03-01      4.81
##  2 1999-06-01         0      1999-04-01       4.3 1999-04-01      4.74
##  3 1999-07-01         0.301  1999-05-01       4.2 1999-05-01      4.74
##  4 1999-08-01         0.240  1999-06-01       4.3 1999-06-01      4.76
##  5 1999-09-01         0.479  1999-07-01       4.3 1999-07-01      4.99
##  6 1999-10-01         0.179  1999-08-01       4.2 1999-08-01      5.07
##  7 1999-11-01         0.0595 1999-09-01       4.2 1999-09-01      5.22
##  8 1999-12-01         0      1999-10-01       4.1 1999-10-01      5.2 
##  9 2000-01-01         0.297  1999-11-01       4.1 1999-11-01      5.42
## 10 2000-02-01         0.592  1999-12-01       4   1999-12-01      5.3 
## # ℹ 287 more rows

Checking columns names to make sure names and columns are in dataset

check_columns <- function(data) {
  if (!exists("data")) {
    stop("The 'data' variable does not exist.")
  }

  col_names <- colnames(data)

  if (length(col_names) == 0) {
    cat("The dataset has no columns.\n")
  } else {
    cat("Columns in the dataset:\n")
    for (col in col_names) {
      cat("-", col, "\n")
    }
  }
}

#Example usage:
check_columns(cpi_data)
## Columns in the dataset:
## - date 
## - series_id 
## - value 
## - realtime_start 
## - realtime_end 
## - inflation_rate
check_columns(unemployment_data)
## Columns in the dataset:
## - date 
## - series_id 
## - value 
## - realtime_start 
## - realtime_end
check_columns(fed_funds_data)
## Columns in the dataset:
## - date 
## - series_id 
## - value 
## - realtime_start 
## - realtime_end
#Example usage:
check_columns(cpi_data)
## Columns in the dataset:
## - date 
## - series_id 
## - value 
## - realtime_start 
## - realtime_end 
## - inflation_rate
check_columns(unemployment_data)
## Columns in the dataset:
## - date 
## - series_id 
## - value 
## - realtime_start 
## - realtime_end
check_columns(fed_funds_data)
## Columns in the dataset:
## - date 
## - series_id 
## - value 
## - realtime_start 
## - realtime_end
library(lubridate)
## Warning: package 'lubridate' was built under R version 4.2.3
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
#Function to calculate percentage change from previous year
calculate_pct_change <- function(data) {
  data %>%
    arrange(date) %>%
    mutate(year = year(date)) %>%
    group_by(year) %>%
    summarise(value = mean(value, na.rm = TRUE)) %>%
    ungroup() %>%
    mutate(pct_change = (value / lag(value) - 1) * 100) %>%
    filter(!is.na(pct_change))
}

#Calculating percentage change for each dataset
cpi_pct_change <- calculate_pct_change(cpi_data)
fed_funds_pct_change <- calculate_pct_change(fed_funds_data)
unemployment_pct_change <- calculate_pct_change(unemployment_data)

#Combining the percentage change data
combined_pct_change <- bind_rows(
  cpi_pct_change %>% mutate(type = "Consumer Price Index"),
  fed_funds_pct_change %>% mutate(type = "FED Funds Rate"),
  unemployment_pct_change %>% mutate(type = "Unemployment Rate")
)

#Creating a single plot comparing CPI, FED Funds Rate, and Unemployment Rate
combined_plot <- ggplot(combined_pct_change, aes(x = year, y = pct_change, color = type)) +
  geom_line() +
  labs(title = "Yearly Percentage Change in Economic Indicators",
       x = "Year",
       y = "Percentage Change (%)",
       color = "Indicator Type") +
  theme_minimal()

#Displaying the combined plot
print(combined_plot)

Conclusion:

In conclusion, the intricate task of balancing economic stability with public health concerns poses a delicate challenge, particularly evident when steering the economy through global crises. The analysis of the graphs underscores the difficulties encountered by the FED Funds Rate in meeting the Congressional mandate from 2008 to 2022. This period was characterized by global economic recessions, unanticipated financial crises, and public health emergencies, notably the COVID-19 pandemic. The complexities involved in managing the economy amid unprecedented challenges underscore the formidable tasks faced by policymakers in navigating through multifaceted and unpredictable global scenarios.

References

Federal Reserve of Economic Data (FRED) package: https://github.com/sboysel/fredr https://fred.stlouisfed.org/docs/api/api_key.html

LS0tDQp0aXRsZTogIlN0b3J5IDIiDQphdXRob3I6ICJMYXVyYSBQIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0OiBvcGVuaW50cm86OmxhYl9yZXBvcnQNCi0tLQ0KDQojIyBPdmVydmlldw0KSGFzIHRoZSBGRUQgYmVlbiBhYmxlIHRvIGZ1bGZpbGwgdGhlIG1hbmRhdGUgZ2l2ZW4gdG8gaXQgYnkgQ29uZ3Jlc3M/DQoNClN0b3J5IC0gMiA6IENhbiB0aGUgRkVEIENvbnRyb2wgSW5mbGF0aW9uIGFuZCBNYWludGFpbiBGdWxsIEVtcGxveW1lbnQNCg0KVGhlIEZlZGVyYWwgUmVzZXJ2ZSdzIG1hbmRhdGUgZnJvbSBDb25ncmVzcyBpcyB0byBjb250cm9sIGluZmxhdGlvbiBhbmQgdG8gbWFpbnRhaW4gbG93IHVuZW1wbG95bWVudC4gVGhlc2Ugc2VlbSB0byBiZSBjb250cmFkaWN0b3J5IG9iamVjdGl2ZXMuDQpGb3IgdGhpcyBzdG9yeSB5b3Ugd2lsbCBuZWVkIHRvIHNvdXJjZSB0aGUgZm9sbG93aW5nIGRhdGEgZm9yIHRoZSBsYXN0IDI1IHllYXJzOw0KVGhlIENvbnN1bWVyIFByaWNlIEluZGV4IChDUEkpIChCdXJlYXUgb2YgTGFib3IgU3RhdGlzdGljcykNCg0KVGhlIEZFRCBGdW5kcyBSYXRlIChGUkVEKSAoRmVkZXJhbCBSZXNlcnZlIEJvYXJkKQ0KDQpVbmVtcGxveW1lbnQgUmF0ZSAgKEJ1cmVhdSBvZiBMYWJvciBTdGF0aXN0aWNzKQ0KDQoNCg0KTG9hZGluZyBwYWNrYWdlcw0KYGBge3IgbG9hZC1wYWNrYWdlcywgbWVzc2FnZT1GQUxTRX0NCiMgTG9hZCBsaWJyYXJpZXMNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoaHR0cikNCmxpYnJhcnkoZnJlZHIpDQoNCmBgYA0KDQpgYGB7cn0NCiNTZXRpbmcgQVBJIGtleQ0KZnJlZHJfc2V0X2tleSgiMTMxZTQyNmQzZTkwYjIyMjc3ZGE3ZjAxODI3NDgzZDciKQ0KDQojRmV0Y2hpbmcgQ1BJIGRhdGENCmNwaV9kYXRhIDwtIGZyZWRyKHNlcmllc19pZCA9ICJDUElBVUNOUyIpDQoNCiNQcmludCB0aGUgZmV0Y2hlZCBkYXRhDQpwcmludChjcGlfZGF0YSkNCg0KYGBgDQoNCmBgYHtyfQ0KI1VzaW5nIEFQSSBrZXkNCmZyZWRyX3NldF9rZXkoIjEzMWU0MjZkM2U5MGIyMjI3N2RhN2YwMTgyNzQ4M2Q3IikNCg0KI0ZldGNoaW5nIENQSSBkYXRhDQpjcGlfZGF0YSA8LSBmcmVkcihzZXJpZXNfaWQgPSAiQ1BJQVVDTlMiKQ0KDQojRmV0Y2hpbmcgRkVEIEZ1bmRzIFJhdGUgZGF0YQ0KZmVkX2Z1bmRzX2RhdGEgPC0gZnJlZHIoc2VyaWVzX2lkID0gIkZFREZVTkRTIikNCg0KI0ZldGNoaW5nIFVuZW1wbG95bWVudCBSYXRlIGRhdGENCnVuZW1wbG95bWVudF9kYXRhIDwtIGZyZWRyKHNlcmllc19pZCA9ICJVTlJBVEUiKQ0KDQojUHJpbnRpbmcgdGhlIGZldGNoZWQgZGF0YQ0KcHJpbnQoY3BpX2RhdGEpDQpwcmludChmZWRfZnVuZHNfZGF0YSkNCnByaW50KHVuZW1wbG95bWVudF9kYXRhKQ0KDQpgYGANCg0KYGBge3J9DQojVXNpbmcgbGlicmFyeSBkcGx5cg0KbGlicmFyeShkcGx5cikNCg0KI0ZpbHRlcmluZyBkYXRhIGZvciB0aGUgbGFzdCAyNSB5ZWFycw0KY3BpX2RhdGEgPC0gY3BpX2RhdGEgJT4lIGZpbHRlcihkYXRlID49IFN5cy5EYXRlKCkgLSAzNjUgKiAyNSkNCmZlZF9mdW5kc19kYXRhIDwtIGZlZF9mdW5kc19kYXRhICU+JSBmaWx0ZXIoZGF0ZSA+PSBTeXMuRGF0ZSgpIC0gMzY1ICogMjUpDQp1bmVtcGxveW1lbnRfZGF0YSA8LSB1bmVtcGxveW1lbnRfZGF0YSAlPiUgZmlsdGVyKGRhdGUgPj0gU3lzLkRhdGUoKSAtIDM2NSAqIDI1KQ0KDQojUHJpbnRpbmcgdGhlIGZpbHRlcmVkIGRhdGENCnByaW50KGNwaV9kYXRhKQ0KcHJpbnQoZmVkX2Z1bmRzX2RhdGEpDQpwcmludCh1bmVtcGxveW1lbnRfZGF0YSkNCg0KYGBgDQoNCmBgYHtyfQ0KI0ZpbHRlcmluZyBkYXRhIGZvciB0aGUgbGFzdCAyNSB5ZWFycw0Kc3RhcnRfZGF0ZSA8LSBTeXMuRGF0ZSgpIC0gMjUgKiAzNjUgICNhc3N1bWluZyBlYWNoIHllYXIgaXMgMzY1IGRheXMNCmNwaV9kYXRhIDwtIGZpbHRlcihjcGlfZGF0YSwgZGF0ZSA+PSBzdGFydF9kYXRlKQ0KZmVkX2Z1bmRzX2RhdGEgPC0gZmlsdGVyKGZlZF9mdW5kc19kYXRhLCBkYXRlID49IHN0YXJ0X2RhdGUpDQp1bmVtcGxveW1lbnRfZGF0YSA8LSBmaWx0ZXIodW5lbXBsb3ltZW50X2RhdGEsIGRhdGUgPj0gc3RhcnRfZGF0ZSkNCg0KI1Bsb3R0aW5nIENvbnN1bWVyIFByaWNlIEluZGV4IChDUEkpIG92ZXIgdGltZQ0KZ2dwbG90KGNwaV9kYXRhLCBhZXMoeCA9IGRhdGUsIHkgPSB2YWx1ZSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIkNvbnN1bWVyIFByaWNlIEluZGV4IChDUEkpIE92ZXIgdGhlIExhc3QgMjUgWWVhcnMiLA0KICAgICAgIHggPSAiRGF0ZSIsDQogICAgICAgeSA9ICJDUEkiKQ0KDQojUGxvdHRpbmcgRkVEIEZ1bmRzIFJhdGUgb3ZlciB0aW1lDQpnZ3Bsb3QoZmVkX2Z1bmRzX2RhdGEsIGFlcyh4ID0gZGF0ZSwgeSA9IHZhbHVlKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGxhYnModGl0bGUgPSAiRkVEIEZ1bmRzIFJhdGUgT3ZlciB0aGUgTGFzdCAyNSBZZWFycyIsDQogICAgICAgeCA9ICJEYXRlIiwNCiAgICAgICB5ID0gIkZFRCBGdW5kcyBSYXRlIikNCg0KI1Bsb3R0aW5nIFVuZW1wbG95bWVudCBSYXRlIG92ZXIgdGltZQ0KZ2dwbG90KHVuZW1wbG95bWVudF9kYXRhLCBhZXMoeCA9IGRhdGUsIHkgPSB2YWx1ZSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIlVuZW1wbG95bWVudCBSYXRlIE92ZXIgdGhlIExhc3QgMjUgWWVhcnMiLA0KICAgICAgIHggPSAiRGF0ZSIsDQogICAgICAgeSA9ICJVbmVtcGxveW1lbnQgUmF0ZSIpDQoNCmBgYA0KDQpDb25zdW1lciBQcmljZSBJbmRleCAoQ1BJKSBoYXMgYmVlbiBzdGVhZGlseSBpbmNyZWFzaW5nIGluIGEgc3RyYWlnaHQgbGluZSBvdmVyIHRoZSBsYXN0IDI1IHllYXJzLCB3aGljaCBpbXBsaWVzIGEgcGVyc2lzdGVudCBpbmZsYXRpb24uIEluIHRoaXMgY2FzZSBpdCBzdWdnZXN0cyBhIGxvbmctdGVybSBpbmNyZWFzZSBpbiB0aGUgZ2VuZXJhbCBwcmljZSBsZXZlbCBvZiBnb29kcyBhbmQgc2VydmljZXMgYXMgYW4gaW5jcmVhc2Ugb2YgdGhlIGNvc3Qgb2YgZ29vZHMgYW5kIHNlcnZpY2VzLiBBbW9uZyBvdGhlciBwb2xpY3kgaW1wbGljYXRpb25zLiANCg0KRnVuZHMgcmF0ZSAoRkVEKSBPdmVyYWxsLCB0aGUgemlnLXphZyBwYXR0ZXJuIGluIHRoZSBGZWRlcmFsIEZ1bmRzIFJhdGUgcmVmbGVjdHMgdGhlIEZFRCdzIGVmZm9ydHMgdG8gbmF2aWdhdGUgYW5kIHJlc3BvbmQgdG8gdmFyaW91cyBlY29ub21pYyBjaGFsbGVuZ2VzIGFuZCBjaGFuZ2VzIGluIGluZmxhdGlvbmFyeSBwcmVzc3VyZXMgb3ZlciB0aGUgeWVhcnMuRm9yIGV4YW1wbGUsIHRoZSBzaWduaWZpY2FudCBwZWFrIGluIHRoZSBlYXJseSAyMDAwcyBtaWdodCBoYXZlIGJlZW4gYXNzb2NpYXRlZCB3aXRoIGEgcGVyaW9kIG9mIGVjb25vbWljIGV4cGFuc2lvbiBvciAyMDIwIENvdmlkLg0KDQpVbmVtcGxveW1lbnQgcmF0ZSAoVU4gcmF0ZSkgdGhlIG9ic2VydmVkIHRyZW5kIGluIHRoZSB1bmVtcGxveW1lbnQgcmF0ZSByZWZsZWN0cyB0aGUgaW1wYWN0IG9mIHRoZSBDT1ZJRC0xOSBwYW5kZW1pYyBvbiB0aGUgbGFib3IgbWFya2V0IGFuZCBzdWJzZXF1ZW50IGVmZm9ydHMgdG8gYWRkcmVzcyB0aGUgY2hhbGxlbmdlcyBwb3NlZCBieSB0aGUgY3Jpc2lzLg0KDQoNCiMjIEluZmxhdGlvbg0KDQpDYWxjdWxhdGluZyB0aGUgaW5mbGF0aW9uIHJhdGUgYmFzZWQgb24gdGhlIENvbnN1bWVyIFByaWNlIEluZGV4IChDUEkpIGRhdGENCg0KYGBge3J9DQojRmlsdGVyaW5nIGRhdGEgZm9yIHRoZSBsYXN0IDI1IHllYXJzDQpzdGFydF9kYXRlIDwtIFN5cy5EYXRlKCkgLSAyNSAqIDM2NSAgIyBhc3N1bWluZyBlYWNoIHllYXIgaXMgMzY1IGRheXMNCmNwaV9kYXRhIDwtIGZpbHRlcihjcGlfZGF0YSwgZGF0ZSA+PSBzdGFydF9kYXRlKQ0KDQojQ2FsY3VsYXRpbmcgcGVyY2VudGFnZSBjaGFuZ2UgaW4gQ1BJIGZvciB0aGUgbGFzdCAyNSB5ZWFycw0KY3BpX2RhdGEgPC0gYXJyYW5nZShjcGlfZGF0YSwgZGF0ZSkNCmNwaV9kYXRhIDwtIG11dGF0ZShjcGlfZGF0YSwgaW5mbGF0aW9uX3JhdGUgPSAoKHZhbHVlIC8gbGFnKHZhbHVlKSkgLSAxKSAqIDEwMCkNCg0KI0ZpbHRlcmluZyBvdXQgdGhlIGZpcnN0IHJvdyBhcyBpdCBkb2Vzbid0IGhhdmUgYSBwcmV2aW91cyBwZXJpb2QNCmNwaV9kYXRhIDwtIGNwaV9kYXRhICU+JSBmaWx0ZXIoIWlzLm5hKGluZmxhdGlvbl9yYXRlKSkNCg0KI1ByaW50aW5nIG9yIHZpc3VhbGl6ZSB0aGUgaW5mbGF0aW9uIHJhdGUgZm9yIHRoZSBsYXN0IDI1IHllYXJzDQpwcmludChjcGlfZGF0YSkNCg0KYGBgDQoNCmBgYHtyfQ0KI0ZpbHRlcmluZyBkYXRhIGZvciB0aGUgbGFzdCAyNSB5ZWFycw0Kc3RhcnRfZGF0ZSA8LSBTeXMuRGF0ZSgpIC0gMjUgKiAzNjUgICMgYXNzdW1pbmcgZWFjaCB5ZWFyIGlzIDM2NSBkYXlzDQpjcGlfZGF0YSA8LSBmaWx0ZXIoY3BpX2RhdGEsIGRhdGUgPj0gc3RhcnRfZGF0ZSkNCmZlZF9mdW5kc19kYXRhIDwtIGZpbHRlcihmZWRfZnVuZHNfZGF0YSwgZGF0ZSA+PSBzdGFydF9kYXRlKQ0KdW5lbXBsb3ltZW50X2RhdGEgPC0gZmlsdGVyKHVuZW1wbG95bWVudF9kYXRhLCBkYXRlID49IHN0YXJ0X2RhdGUpDQoNCiNDYWxjdWxhdGluZyBwZXJjZW50YWdlIGNoYW5nZSBpbiBDUEkgZm9yIHRoZSBsYXN0IDI1IHllYXJzDQpjcGlfZGF0YSA8LSBhcnJhbmdlKGNwaV9kYXRhLCBkYXRlKQ0KY3BpX2RhdGEgPC0gbXV0YXRlKGNwaV9kYXRhLCBpbmZsYXRpb25fcmF0ZSA9ICgodmFsdWUgLyBsYWcodmFsdWUpKSAtIDEpICogMTAwKQ0KDQojRmlsdGVyaW5nIG91dCB0aGUgZmlyc3Qgcm93IGFzIGl0IGRvZXNuJ3QgaGF2ZSBhIHByZXZpb3VzIHBlcmlvZA0KY3BpX2RhdGEgPC0gY3BpX2RhdGEgJT4lIGZpbHRlcighaXMubmEoaW5mbGF0aW9uX3JhdGUpKQ0KDQojQWxpZ25pbmcgdGhlIGxlbmd0aHMgYmVmb3JlIGJpbmRpbmcgY29sdW1ucw0KbWluX2xlbmd0aCA8LSBtaW4obGVuZ3RoKGNwaV9kYXRhJGRhdGUpLCBsZW5ndGgodW5lbXBsb3ltZW50X2RhdGEkZGF0ZSkpDQpjb21iaW5lZF9kYXRhIDwtIGJpbmRfY29scygNCiAgY3BpX2RhdGEgJT4lIHNlbGVjdChkYXRlLCBpbmZsYXRpb25fcmF0ZSksDQogIHVuZW1wbG95bWVudF9kYXRhICU+JSBzbGljZSgxOm1pbl9sZW5ndGgpICU+JSBzZWxlY3QoZGF0ZSwgdmFsdWUpLA0KICBmZWRfZnVuZHNfZGF0YSAlPiUgc2xpY2UoMTptaW5fbGVuZ3RoKSAlPiUgc2VsZWN0KGRhdGUsIHZhbHVlKQ0KKQ0KDQojUHJpbnRpbmcgb3IgdmlzdWFsaXplIHRoZSBjb21iaW5lZCBkYXRhDQpwcmludChjb21iaW5lZF9kYXRhKQ0KDQoNCmBgYA0KDQpDaGVja2luZyBjb2x1bW5zIG5hbWVzIHRvIG1ha2Ugc3VyZSBuYW1lcyBhbmQgY29sdW1ucyBhcmUgaW4gZGF0YXNldA0KYGBge3J9DQpjaGVja19jb2x1bW5zIDwtIGZ1bmN0aW9uKGRhdGEpIHsNCiAgaWYgKCFleGlzdHMoImRhdGEiKSkgew0KICAgIHN0b3AoIlRoZSAnZGF0YScgdmFyaWFibGUgZG9lcyBub3QgZXhpc3QuIikNCiAgfQ0KDQogIGNvbF9uYW1lcyA8LSBjb2xuYW1lcyhkYXRhKQ0KDQogIGlmIChsZW5ndGgoY29sX25hbWVzKSA9PSAwKSB7DQogICAgY2F0KCJUaGUgZGF0YXNldCBoYXMgbm8gY29sdW1ucy5cbiIpDQogIH0gZWxzZSB7DQogICAgY2F0KCJDb2x1bW5zIGluIHRoZSBkYXRhc2V0OlxuIikNCiAgICBmb3IgKGNvbCBpbiBjb2xfbmFtZXMpIHsNCiAgICAgIGNhdCgiLSIsIGNvbCwgIlxuIikNCiAgICB9DQogIH0NCn0NCg0KI0V4YW1wbGUgdXNhZ2U6DQpjaGVja19jb2x1bW5zKGNwaV9kYXRhKQ0KY2hlY2tfY29sdW1ucyh1bmVtcGxveW1lbnRfZGF0YSkNCmNoZWNrX2NvbHVtbnMoZmVkX2Z1bmRzX2RhdGEpDQoNCg0KYGBgDQpgYGB7cn0NCiNFeGFtcGxlIHVzYWdlOg0KY2hlY2tfY29sdW1ucyhjcGlfZGF0YSkNCmNoZWNrX2NvbHVtbnModW5lbXBsb3ltZW50X2RhdGEpDQpjaGVja19jb2x1bW5zKGZlZF9mdW5kc19kYXRhKQ0KDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCg0KI0Z1bmN0aW9uIHRvIGNhbGN1bGF0ZSBwZXJjZW50YWdlIGNoYW5nZSBmcm9tIHByZXZpb3VzIHllYXINCmNhbGN1bGF0ZV9wY3RfY2hhbmdlIDwtIGZ1bmN0aW9uKGRhdGEpIHsNCiAgZGF0YSAlPiUNCiAgICBhcnJhbmdlKGRhdGUpICU+JQ0KICAgIG11dGF0ZSh5ZWFyID0geWVhcihkYXRlKSkgJT4lDQogICAgZ3JvdXBfYnkoeWVhcikgJT4lDQogICAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkgJT4lDQogICAgdW5ncm91cCgpICU+JQ0KICAgIG11dGF0ZShwY3RfY2hhbmdlID0gKHZhbHVlIC8gbGFnKHZhbHVlKSAtIDEpICogMTAwKSAlPiUNCiAgICBmaWx0ZXIoIWlzLm5hKHBjdF9jaGFuZ2UpKQ0KfQ0KDQojQ2FsY3VsYXRpbmcgcGVyY2VudGFnZSBjaGFuZ2UgZm9yIGVhY2ggZGF0YXNldA0KY3BpX3BjdF9jaGFuZ2UgPC0gY2FsY3VsYXRlX3BjdF9jaGFuZ2UoY3BpX2RhdGEpDQpmZWRfZnVuZHNfcGN0X2NoYW5nZSA8LSBjYWxjdWxhdGVfcGN0X2NoYW5nZShmZWRfZnVuZHNfZGF0YSkNCnVuZW1wbG95bWVudF9wY3RfY2hhbmdlIDwtIGNhbGN1bGF0ZV9wY3RfY2hhbmdlKHVuZW1wbG95bWVudF9kYXRhKQ0KDQojQ29tYmluaW5nIHRoZSBwZXJjZW50YWdlIGNoYW5nZSBkYXRhDQpjb21iaW5lZF9wY3RfY2hhbmdlIDwtIGJpbmRfcm93cygNCiAgY3BpX3BjdF9jaGFuZ2UgJT4lIG11dGF0ZSh0eXBlID0gIkNvbnN1bWVyIFByaWNlIEluZGV4IiksDQogIGZlZF9mdW5kc19wY3RfY2hhbmdlICU+JSBtdXRhdGUodHlwZSA9ICJGRUQgRnVuZHMgUmF0ZSIpLA0KICB1bmVtcGxveW1lbnRfcGN0X2NoYW5nZSAlPiUgbXV0YXRlKHR5cGUgPSAiVW5lbXBsb3ltZW50IFJhdGUiKQ0KKQ0KDQojQ3JlYXRpbmcgYSBzaW5nbGUgcGxvdCBjb21wYXJpbmcgQ1BJLCBGRUQgRnVuZHMgUmF0ZSwgYW5kIFVuZW1wbG95bWVudCBSYXRlDQpjb21iaW5lZF9wbG90IDwtIGdncGxvdChjb21iaW5lZF9wY3RfY2hhbmdlLCBhZXMoeCA9IHllYXIsIHkgPSBwY3RfY2hhbmdlLCBjb2xvciA9IHR5cGUpKSArDQogIGdlb21fbGluZSgpICsNCiAgbGFicyh0aXRsZSA9ICJZZWFybHkgUGVyY2VudGFnZSBDaGFuZ2UgaW4gRWNvbm9taWMgSW5kaWNhdG9ycyIsDQogICAgICAgeCA9ICJZZWFyIiwNCiAgICAgICB5ID0gIlBlcmNlbnRhZ2UgQ2hhbmdlICglKSIsDQogICAgICAgY29sb3IgPSAiSW5kaWNhdG9yIFR5cGUiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQojRGlzcGxheWluZyB0aGUgY29tYmluZWQgcGxvdA0KcHJpbnQoY29tYmluZWRfcGxvdCkNCg0KYGBgDQoNCiMjIENvbmNsdXNpb246DQpJbiBjb25jbHVzaW9uLCB0aGUgaW50cmljYXRlIHRhc2sgb2YgYmFsYW5jaW5nIGVjb25vbWljIHN0YWJpbGl0eSB3aXRoIHB1YmxpYyBoZWFsdGggY29uY2VybnMgcG9zZXMgYSBkZWxpY2F0ZSBjaGFsbGVuZ2UsIHBhcnRpY3VsYXJseSBldmlkZW50IHdoZW4gc3RlZXJpbmcgdGhlIGVjb25vbXkgdGhyb3VnaCBnbG9iYWwgY3Jpc2VzLiBUaGUgYW5hbHlzaXMgb2YgdGhlIGdyYXBocyB1bmRlcnNjb3JlcyB0aGUgZGlmZmljdWx0aWVzIGVuY291bnRlcmVkIGJ5IHRoZSBGRUQgRnVuZHMgUmF0ZSBpbiBtZWV0aW5nIHRoZSBDb25ncmVzc2lvbmFsIG1hbmRhdGUgZnJvbSAyMDA4IHRvIDIwMjIuIFRoaXMgcGVyaW9kIHdhcyBjaGFyYWN0ZXJpemVkIGJ5IGdsb2JhbCBlY29ub21pYyByZWNlc3Npb25zLCB1bmFudGljaXBhdGVkIGZpbmFuY2lhbCBjcmlzZXMsIGFuZCBwdWJsaWMgaGVhbHRoIGVtZXJnZW5jaWVzLCBub3RhYmx5IHRoZSBDT1ZJRC0xOSBwYW5kZW1pYy4gVGhlIGNvbXBsZXhpdGllcyBpbnZvbHZlZCBpbiBtYW5hZ2luZyB0aGUgZWNvbm9teSBhbWlkIHVucHJlY2VkZW50ZWQgY2hhbGxlbmdlcyB1bmRlcnNjb3JlIHRoZSBmb3JtaWRhYmxlIHRhc2tzIGZhY2VkIGJ5IHBvbGljeW1ha2VycyBpbiBuYXZpZ2F0aW5nIHRocm91Z2ggbXVsdGlmYWNldGVkIGFuZCB1bnByZWRpY3RhYmxlIGdsb2JhbCBzY2VuYXJpb3MuDQoNCg0KIyMgUmVmZXJlbmNlcw0KRmVkZXJhbCBSZXNlcnZlIG9mIEVjb25vbWljIERhdGEgKEZSRUQpICBwYWNrYWdlOiANCmh0dHBzOi8vZ2l0aHViLmNvbS9zYm95c2VsL2ZyZWRyDQpodHRwczovL2ZyZWQuc3Rsb3Vpc2ZlZC5vcmcvZG9jcy9hcGkvYXBpX2tleS5odG1sDQoNCg0KDQoNCg==