L11.8 - L11.12. Measuring and explaining exchange rate movements

Explanations Ahead

In this section we will be measuring and explaining exchange rate movements. In order to better understand this phenomena we will have to take into account certain concepts.

Currency fluctuation

When we talk about current fluctuation, we are referring to the change in the relative value of one against the other. In other words, is the change in the equivalencies of the value of the currencies.

Exchange Rates

Exchange Rates are the numerical representation of the currency fluctuation. That is the value of one currency against the other in an specific moment. Exchange Rates fluctuate and are great economical indicators. There are several reasons for the fluctuation of exchange rates, such as interest rates, general macroeconomic data of each country, political policies and stability, inflation rates, data and policy, and foreign investments. Another factor that creates fluctuation in exchange rates is the speculation.

Effects

The fluctuations in currency (and exchange rates) have an impact in several aspects of the economy. 1. International trade. A weak currency easily benefits from exports, while a strong one may reduce their export capability.
2. Inflation. A strong currency will have a lot of import capability and will be able to keep inflation stable. However, a weak currency will have higher import costs and will overall increase domestic inflation. 3. Investment. The stability or strengthen of a currency usually indicate an stable/strong economy and political situation. Therefore, it will be much more attractive to make an investment in those countries with a strong currency. Oppositely, a weak currency (or a constantly changing one) will indicate weakness and instability. 4. Economic stability and growth. Impacts in GDP, investment, inflation and international trade all contribute towards the economy of a country, whether making in stable and strong or weak a unstable.

Before the exercises

Load Packages

# Load required packages
library(quantmod)
Aviso: package ‘quantmod’ was built under R version 4.4.2Cargando paquete requerido: xts
Cargando paquete requerido: zoo

Adjuntando el paquete: ‘zoo’

The following objects are masked from ‘package:base’:

    as.Date, as.Date.numeric

Cargando paquete requerido: TTR
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
library(lubridate)
Aviso: package ‘lubridate’ was built under R version 4.4.2
Adjuntando el paquete: ‘lubridate’

The following objects are masked from ‘package:base’:

    date, intersect, setdiff, union
library(PerformanceAnalytics)
Aviso: package ‘PerformanceAnalytics’ was built under R version 4.4.2
Adjuntando el paquete: ‘PerformanceAnalytics’

The following object is masked from ‘package:graphics’:

    legend

Define Beginning and End of Term Dates

# Define Beginning of Term (BoT) and End of Term (EoT) dates
BoT_date <- as.Date("2024-05-01")
EoT_date <- as.Date("2024-09-30")

L11.8 Determining the Percentage Change in the Value of the British Pound

Retrieve GPB/USD Exchange Rate Data

# Get GBP/USD exchange rate data
getSymbols("GBPUSD=X", src = "yahoo", from = BoT_date - 7, to = EoT_date + 7, auto.assign = TRUE)
[1] "GBPUSD=X"
# Assign data to a variable
gbp_usd_data <- `GBPUSD=X`

Get exchange Rates at BoT and EoT

# Function to get the exchange rate on a specific date
get_rate_on_date <- function(data, date) {
  index(data) <- as.Date(index(data))
  
  available_dates <- index(data)[index(data) <= date]
  
  if (length(available_dates) == 0) {
    warning(paste("No data available on or before", date))
    return(list(Rate = NA, Date = NA))
  }
  
  date_used <- max(available_dates)
  
  rate <- as.numeric(Cl(data[date_used]))
  
  return(list(
    Rate = rate,
    Date = as.Date(date_used)
  ))
}

# Get rates at BoT and EoT
gbp_rate_BoT <- get_rate_on_date(gbp_usd_data, BoT_date)
gbp_rate_EoT <- get_rate_on_date(gbp_usd_data, EoT_date)

# Print the exchange rates
cat("GBP/USD Rate at BoT (", gbp_rate_BoT$Date, "): ", round(gbp_rate_BoT$Rate, 4), "\n", sep = "")
GBP/USD Rate at BoT (19844): 1.2539
cat("GBP/USD Rate at EoT (", gbp_rate_EoT$Date, "): ", round(gbp_rate_EoT$Rate, 4), "\n", sep = "")
GBP/USD Rate at EoT (19996): 1.3376

Calculate the Percentage Change

# Calculate the percentage change
gbp_percentage_change <- (gbp_rate_EoT$Rate - gbp_rate_BoT$Rate) / gbp_rate_BoT$Rate * 100

# Print the result
cat("Percentage Change in GBP/USD: ", round(gbp_percentage_change, 2), "%\n", sep = "")
Percentage Change in GBP/USD: 6.67%

Determine Appreciation or Depreciation

if (gbp_percentage_change > 0) {
  gbp_result <- "appreciated"
} else if (gbp_percentage_change < 0) {
  gbp_result <- "depreciated"
} else {
  gbp_result <- "remained the same"
}

cat("The British pound has ", gbp_result, " against the US dollar over the school term.\n", sep = "")
The British pound has appreciated against the US dollar over the school term.

Analysis

The appreciation of the British pound against the US dollar may indicate, as we have previously explained, an strengthening of UK’s economy against the US. Although we cannot be certain without much further analysis of what may have caused this notorious appreciation of the currency, we can presume is a mix of several factors that have been already explained. This could include favorable GDP data for the UK, an aggressive monetary policy from the Bank of England with higher interest rates, or the stabilization of certain aspects regarding Brexit. On the other side, the US may have become somewhat less attractive for investors who look for riskier opportunities, slow inflation with a less aggressive monetary policy or overall discontent with the political situation. The upcoming USA Presidential Elections may have risen certain concerns and created a sense of instability that has been portrayed in the exchange rate against the British Pound.

L11.9 Determining the Percentage Change in the Value of the Japanese Yen

Retrieve USD/JPY Exchange Rate Data

# Get USD/JPY exchange rate data
getSymbols("JPY=X", src = "yahoo", from = BoT_date - 7, to = EoT_date + 7, auto.assign = TRUE)
[1] "JPY=X"
# Assign data to a variable
usd_jpy_data <- `JPY=X`

Get Exchange Rates at BoT and EoT

# Get rates at BoT and EoT
jpy_rate_BoT <- get_rate_on_date(usd_jpy_data, BoT_date)
jpy_rate_EoT <- get_rate_on_date(usd_jpy_data, EoT_date)

# Print the exchange rates
cat("USD/JPY Rate at BoT (", jpy_rate_BoT$Date, "): ", round(jpy_rate_BoT$Rate, 4), "\n", sep = "")
USD/JPY Rate at BoT (19844): 155.704
cat("USD/JPY Rate at EoT (", jpy_rate_EoT$Date, "): ", round(jpy_rate_EoT$Rate, 4), "\n", sep = "")
USD/JPY Rate at EoT (19996): 143.71

Calculate the Percentage Rate

# Invert the rates to get JPY per USD
jpy_per_usd_BoT <- 1 / jpy_rate_BoT$Rate
jpy_per_usd_EoT <- 1 / jpy_rate_EoT$Rate

# Calculate the percentage change
jpy_percentage_change <- (jpy_per_usd_EoT - jpy_per_usd_BoT) / jpy_per_usd_BoT * 100

# Print the result
cat("Percentage Change in JPY/USD: ", round(jpy_percentage_change, 2), "%\n", sep = "")
Percentage Change in JPY/USD: 8.35%

Determine Appreciation or Depreciation

if (jpy_percentage_change > 0) {
  jpy_result <- "appreciated"
} else if (jpy_percentage_change < 0) {
  jpy_result <- "depreciated"
} else {
  jpy_result <- "remained the same"
}

cat("The Japanese yen has ", jpy_result, " against the US dollar over the school term.\n", sep = "")
The Japanese yen has appreciated against the US dollar over the school term.

Analysis

Just as we have explained in the previous question. the US may have faced a period of instability and slowness that could have caused a lower demand for US dollars. Conversely, the Bank of Japan, may have adopted a more strict regulation (in opposition with its traditional approach) due to high inflation or due to normalization strategies, which may have caused a reaction in the currency markets. Japan may have also had positive reports or a recovery in its trade balance.

L11.10 Determining the Percentage Change in the Value of the Mexican Peso

Retrieve USD/MXN Exchange Rate Data

# Get USD/MXN exchange rate data
getSymbols("MXN=X", src = "yahoo", from = BoT_date - 7, to = EoT_date + 7, auto.assign = TRUE)
[1] "MXN=X"
# Assign data to a variable
usd_mxn_data <- `MXN=X`

Get Exchange Rates at BoT and EoT

# Get rates at BoT and EoT
mxn_rate_BoT <- get_rate_on_date(usd_mxn_data, BoT_date)
mxn_rate_EoT <- get_rate_on_date(usd_mxn_data, EoT_date)

# Print the exchange rates
cat("USD/MXN Rate at BoT (", mxn_rate_BoT$Date, "): ", round(mxn_rate_BoT$Rate, 4), "\n", sep = "")
USD/MXN Rate at BoT (19844): 16.9286
cat("USD/MXN Rate at EoT (", mxn_rate_EoT$Date, "): ", round(mxn_rate_EoT$Rate, 4), "\n", sep = "")
USD/MXN Rate at EoT (19996): 19.6636

Calculate the Percentage Change

# Invert the rates to get MXN per USD
mxn_per_usd_BoT <- 1 / mxn_rate_BoT$Rate
mxn_per_usd_EoT <- 1 / mxn_rate_EoT$Rate

# Calculate the percentage change
mxn_percentage_change <- (mxn_per_usd_EoT - mxn_per_usd_BoT) / mxn_per_usd_BoT * 100

# Print the result
cat("Percentage Change in MXN/USD: ", round(mxn_percentage_change, 2), "%\n", sep = "")
Percentage Change in MXN/USD: -13.91%

Determine Appreciation or Depreciation

if (mxn_percentage_change > 0) {
  mxn_result <- "appreciated"
} else if (mxn_percentage_change < 0) {
  mxn_result <- "depreciated"
} else {
  mxn_result <- "remained the same"
}

cat("The Mexican peso has ", mxn_result, " against the US dollar over the school term.\n", sep = "")
The Mexican peso has depreciated against the US dollar over the school term.

Analysis

Have we not seen the previous results, we might have had the initial thought that these results are the manifestation of a strong US Dollar, which strengthens against the Mexican Peso. However, we already know that the USD had weakened against the other two currencies analyzed, so we may assume that this is not the outcome of an strong USA but rather a really worsened Mexico. If we take a look into Mexico’s politics during the Term Period, we will notice that Presidential Elections took place, with the victory of Claudia Sheinbaum. The difference in positions with the USA in several international matters may have pushed this drop in the Mexican Peso, which has not yet stopped as of today, although our End of Term Date only dates until September.

L11.11 Determining the Per Unit Gain or Loss for British Pound Futures

Determine the per unit gain or loss if you had purchased British pound futures at the beginning of the term and sold them at the end of the term. Use GPB/USD Exchange rates as Proxy.

Calculate the Per Unit Gain or Loss

# Calculate the per unit gain or loss
per_unit_gain_loss <- gbp_rate_EoT$Rate - gbp_rate_BoT$Rate

# Print the result
cat("Per Unit Gain/Loss for GBP Futures: $", round(per_unit_gain_loss, 4), " per GBP\n", sep = "")
Per Unit Gain/Loss for GBP Futures: $0.0837 per GBP

In this exercise we have determined the gain per GPB for the futures contract.

L11.12 Determining the Dollar Amount of Your Gain or Loss on the Futures Contract

Given that a single futures contract on British pounds represents 62,500 pounds, determine the dollar amount of your gain or loss.

# Number of pounds per futures contract
contract_size <- 62500

# Total gain or loss
total_gain_loss <- per_unit_gain_loss * contract_size

# Print the result
cat("Total Gain/Loss on Futures Contract: $", round(total_gain_loss, 2), "\n", sep = "")
Total Gain/Loss on Futures Contract: $5229.96

Determine if you Gained or Lost

if (total_gain_loss > 0) {
  futures_result <- "gained"
} else if (total_gain_loss < 0) {
  futures_result <- "lost"
} else {
  futures_result <- "broke even"
}

cat("You have ", futures_result, " $", abs(round(total_gain_loss, 2)), " on the futures contract.\n", sep = "")
You have gained $5229.96 on the futures contract.

With a gain per GPB of 0.0837 USD and an amount of 62500 pounds, we will have ended at the end of term with a total gain of 5229.96 USD. This has been possible, as we know, thanks to the appreciation of the GPB against the USD, which he have already analyzed previously.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCiMjIEwxMS44IC0gTDExLjEyLiBNZWFzdXJpbmcgYW5kIGV4cGxhaW5pbmcgZXhjaGFuZ2UgcmF0ZSBtb3ZlbWVudHMNCg0KIyMjIEV4cGxhbmF0aW9ucyBBaGVhZA0KDQpJbiB0aGlzIHNlY3Rpb24gd2Ugd2lsbCBiZSBtZWFzdXJpbmcgYW5kIGV4cGxhaW5pbmcgZXhjaGFuZ2UgcmF0ZSBtb3ZlbWVudHMuIEluIG9yZGVyIHRvIGJldHRlciB1bmRlcnN0YW5kIHRoaXMgcGhlbm9tZW5hIHdlIHdpbGwgaGF2ZSB0byB0YWtlIGludG8gYWNjb3VudCBjZXJ0YWluIGNvbmNlcHRzLiANCg0KIyMjIyBDdXJyZW5jeSBmbHVjdHVhdGlvbg0KV2hlbiB3ZSB0YWxrIGFib3V0IGN1cnJlbnQgZmx1Y3R1YXRpb24sIHdlIGFyZSByZWZlcnJpbmcgdG8gdGhlIGNoYW5nZSBpbiB0aGUgcmVsYXRpdmUgdmFsdWUgb2Ygb25lIGFnYWluc3QgdGhlIG90aGVyLiBJbiBvdGhlciB3b3JkcywgaXMgdGhlIGNoYW5nZSBpbiB0aGUgZXF1aXZhbGVuY2llcyBvZiB0aGUgdmFsdWUgb2YgdGhlIGN1cnJlbmNpZXMuIA0KDQojIyMjIEV4Y2hhbmdlIFJhdGVzDQpFeGNoYW5nZSBSYXRlcyBhcmUgdGhlIG51bWVyaWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVuY3kgZmx1Y3R1YXRpb24uIFRoYXQgaXMgdGhlIHZhbHVlIG9mIG9uZSBjdXJyZW5jeSBhZ2FpbnN0IHRoZSBvdGhlciBpbiBhbiBzcGVjaWZpYyBtb21lbnQuIEV4Y2hhbmdlIFJhdGVzIGZsdWN0dWF0ZSBhbmQgYXJlIGdyZWF0IGVjb25vbWljYWwgaW5kaWNhdG9ycy4gVGhlcmUgYXJlIHNldmVyYWwgcmVhc29ucyBmb3IgdGhlIGZsdWN0dWF0aW9uIG9mIGV4Y2hhbmdlIHJhdGVzLCBzdWNoIGFzIGludGVyZXN0IHJhdGVzLCBnZW5lcmFsIG1hY3JvZWNvbm9taWMgZGF0YSBvZiBlYWNoIGNvdW50cnksIHBvbGl0aWNhbCBwb2xpY2llcyBhbmQgc3RhYmlsaXR5LCBpbmZsYXRpb24gcmF0ZXMsIGRhdGEgYW5kIHBvbGljeSwgYW5kIGZvcmVpZ24gaW52ZXN0bWVudHMuIA0KQW5vdGhlciBmYWN0b3IgdGhhdCBjcmVhdGVzIGZsdWN0dWF0aW9uIGluIGV4Y2hhbmdlIHJhdGVzIGlzIHRoZSBzcGVjdWxhdGlvbi4gDQoNCiMjIyMgRWZmZWN0cw0KVGhlIGZsdWN0dWF0aW9ucyBpbiBjdXJyZW5jeSAoYW5kIGV4Y2hhbmdlIHJhdGVzKSBoYXZlIGFuIGltcGFjdCBpbiBzZXZlcmFsIGFzcGVjdHMgb2YgdGhlIGVjb25vbXkuIA0KICAxLiBJbnRlcm5hdGlvbmFsIHRyYWRlLiBBIHdlYWsgY3VycmVuY3kgZWFzaWx5IGJlbmVmaXRzIGZyb20gZXhwb3J0cywgd2hpbGUgYSBzdHJvbmcgb25lIG1heSByZWR1Y2UgdGhlaXIgZXhwb3J0IGNhcGFiaWxpdHkuICANCiAgMi4gSW5mbGF0aW9uLiBBIHN0cm9uZyBjdXJyZW5jeSB3aWxsIGhhdmUgYSBsb3Qgb2YgaW1wb3J0IGNhcGFiaWxpdHkgYW5kIHdpbGwgYmUgYWJsZSB0byBrZWVwIGluZmxhdGlvbiBzdGFibGUuIEhvd2V2ZXIsIGEgd2VhayBjdXJyZW5jeSB3aWxsIGhhdmUgaGlnaGVyIGltcG9ydCBjb3N0cyBhbmQgd2lsbCBvdmVyYWxsIGluY3JlYXNlIGRvbWVzdGljIGluZmxhdGlvbi4gDQogIDMuIEludmVzdG1lbnQuIFRoZSBzdGFiaWxpdHkgb3Igc3RyZW5ndGhlbiBvZiBhIGN1cnJlbmN5IHVzdWFsbHkgaW5kaWNhdGUgYW4gc3RhYmxlL3N0cm9uZyBlY29ub215IGFuZCBwb2xpdGljYWwgc2l0dWF0aW9uLiBUaGVyZWZvcmUsIGl0IHdpbGwgYmUgbXVjaCBtb3JlIGF0dHJhY3RpdmUgdG8gbWFrZSBhbiBpbnZlc3RtZW50IGluIHRob3NlIGNvdW50cmllcyB3aXRoIGEgc3Ryb25nIGN1cnJlbmN5LiBPcHBvc2l0ZWx5LCBhIHdlYWsgY3VycmVuY3kgKG9yIGEgY29uc3RhbnRseSBjaGFuZ2luZyBvbmUpIHdpbGwgaW5kaWNhdGUgd2Vha25lc3MgYW5kIGluc3RhYmlsaXR5LiANCiAgNC4gRWNvbm9taWMgc3RhYmlsaXR5IGFuZCBncm93dGguIEltcGFjdHMgaW4gR0RQLCBpbnZlc3RtZW50LCBpbmZsYXRpb24gYW5kIGludGVybmF0aW9uYWwgdHJhZGUgYWxsIGNvbnRyaWJ1dGUgdG93YXJkcyB0aGUgZWNvbm9teSBvZiBhIGNvdW50cnksIHdoZXRoZXIgbWFraW5nIGluIHN0YWJsZSBhbmQgc3Ryb25nIG9yIHdlYWsgYSB1bnN0YWJsZS4gDQoNCg0KIyMjIEJlZm9yZSB0aGUgZXhlcmNpc2VzDQoNCkxvYWQgUGFja2FnZXMNCg0KYGBge3J9DQojIExvYWQgcmVxdWlyZWQgcGFja2FnZXMNCmxpYnJhcnkocXVhbnRtb2QpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoUGVyZm9ybWFuY2VBbmFseXRpY3MpDQoNCmBgYA0KDQoNCkRlZmluZSBCZWdpbm5pbmcgYW5kIEVuZCBvZiBUZXJtIERhdGVzDQoNCmBgYHtyfQ0KIyBEZWZpbmUgQmVnaW5uaW5nIG9mIFRlcm0gKEJvVCkgYW5kIEVuZCBvZiBUZXJtIChFb1QpIGRhdGVzDQpCb1RfZGF0ZSA8LSBhcy5EYXRlKCIyMDI0LTA1LTAxIikNCkVvVF9kYXRlIDwtIGFzLkRhdGUoIjIwMjQtMDktMzAiKQ0KDQpgYGANCg0KDQojIyMgTDExLjggRGV0ZXJtaW5pbmcgdGhlIFBlcmNlbnRhZ2UgQ2hhbmdlIGluIHRoZSBWYWx1ZSBvZiB0aGUgQnJpdGlzaCBQb3VuZA0KDQoNClJldHJpZXZlIEdQQi9VU0QgRXhjaGFuZ2UgUmF0ZSBEYXRhDQoNCmBgYHtyfQ0KIyBHZXQgR0JQL1VTRCBleGNoYW5nZSByYXRlIGRhdGENCmdldFN5bWJvbHMoIkdCUFVTRD1YIiwgc3JjID0gInlhaG9vIiwgZnJvbSA9IEJvVF9kYXRlIC0gNywgdG8gPSBFb1RfZGF0ZSArIDcsIGF1dG8uYXNzaWduID0gVFJVRSkNCg0KIyBBc3NpZ24gZGF0YSB0byBhIHZhcmlhYmxlDQpnYnBfdXNkX2RhdGEgPC0gYEdCUFVTRD1YYA0KYGBgDQoNCg0KR2V0IGV4Y2hhbmdlIFJhdGVzIGF0IEJvVCBhbmQgRW9UDQoNCmBgYHtyfQ0KIyBGdW5jdGlvbiB0byBnZXQgdGhlIGV4Y2hhbmdlIHJhdGUgb24gYSBzcGVjaWZpYyBkYXRlDQpnZXRfcmF0ZV9vbl9kYXRlIDwtIGZ1bmN0aW9uKGRhdGEsIGRhdGUpIHsNCiAgaW5kZXgoZGF0YSkgPC0gYXMuRGF0ZShpbmRleChkYXRhKSkNCiAgDQogIGF2YWlsYWJsZV9kYXRlcyA8LSBpbmRleChkYXRhKVtpbmRleChkYXRhKSA8PSBkYXRlXQ0KICANCiAgaWYgKGxlbmd0aChhdmFpbGFibGVfZGF0ZXMpID09IDApIHsNCiAgICB3YXJuaW5nKHBhc3RlKCJObyBkYXRhIGF2YWlsYWJsZSBvbiBvciBiZWZvcmUiLCBkYXRlKSkNCiAgICByZXR1cm4obGlzdChSYXRlID0gTkEsIERhdGUgPSBOQSkpDQogIH0NCiAgDQogIGRhdGVfdXNlZCA8LSBtYXgoYXZhaWxhYmxlX2RhdGVzKQ0KICANCiAgcmF0ZSA8LSBhcy5udW1lcmljKENsKGRhdGFbZGF0ZV91c2VkXSkpDQogIA0KICByZXR1cm4obGlzdCgNCiAgICBSYXRlID0gcmF0ZSwNCiAgICBEYXRlID0gYXMuRGF0ZShkYXRlX3VzZWQpDQogICkpDQp9DQoNCiMgR2V0IHJhdGVzIGF0IEJvVCBhbmQgRW9UDQpnYnBfcmF0ZV9Cb1QgPC0gZ2V0X3JhdGVfb25fZGF0ZShnYnBfdXNkX2RhdGEsIEJvVF9kYXRlKQ0KZ2JwX3JhdGVfRW9UIDwtIGdldF9yYXRlX29uX2RhdGUoZ2JwX3VzZF9kYXRhLCBFb1RfZGF0ZSkNCg0KIyBQcmludCB0aGUgZXhjaGFuZ2UgcmF0ZXMNCmNhdCgiR0JQL1VTRCBSYXRlIGF0IEJvVCAoIiwgZ2JwX3JhdGVfQm9UJERhdGUsICIpOiAiLCByb3VuZChnYnBfcmF0ZV9Cb1QkUmF0ZSwgNCksICJcbiIsIHNlcCA9ICIiKQ0KY2F0KCJHQlAvVVNEIFJhdGUgYXQgRW9UICgiLCBnYnBfcmF0ZV9Fb1QkRGF0ZSwgIik6ICIsIHJvdW5kKGdicF9yYXRlX0VvVCRSYXRlLCA0KSwgIlxuIiwgc2VwID0gIiIpDQpgYGANCg0KDQpDYWxjdWxhdGUgdGhlIFBlcmNlbnRhZ2UgQ2hhbmdlDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdGhlIHBlcmNlbnRhZ2UgY2hhbmdlDQpnYnBfcGVyY2VudGFnZV9jaGFuZ2UgPC0gKGdicF9yYXRlX0VvVCRSYXRlIC0gZ2JwX3JhdGVfQm9UJFJhdGUpIC8gZ2JwX3JhdGVfQm9UJFJhdGUgKiAxMDANCg0KIyBQcmludCB0aGUgcmVzdWx0DQpjYXQoIlBlcmNlbnRhZ2UgQ2hhbmdlIGluIEdCUC9VU0Q6ICIsIHJvdW5kKGdicF9wZXJjZW50YWdlX2NoYW5nZSwgMiksICIlXG4iLCBzZXAgPSAiIikNCmBgYA0KDQoNCkRldGVybWluZSBBcHByZWNpYXRpb24gb3IgRGVwcmVjaWF0aW9uDQoNCmBgYHtyfQ0KaWYgKGdicF9wZXJjZW50YWdlX2NoYW5nZSA+IDApIHsNCiAgZ2JwX3Jlc3VsdCA8LSAiYXBwcmVjaWF0ZWQiDQp9IGVsc2UgaWYgKGdicF9wZXJjZW50YWdlX2NoYW5nZSA8IDApIHsNCiAgZ2JwX3Jlc3VsdCA8LSAiZGVwcmVjaWF0ZWQiDQp9IGVsc2Ugew0KICBnYnBfcmVzdWx0IDwtICJyZW1haW5lZCB0aGUgc2FtZSINCn0NCg0KY2F0KCJUaGUgQnJpdGlzaCBwb3VuZCBoYXMgIiwgZ2JwX3Jlc3VsdCwgIiBhZ2FpbnN0IHRoZSBVUyBkb2xsYXIgb3ZlciB0aGUgc2Nob29sIHRlcm0uXG4iLCBzZXAgPSAiIikNCmBgYA0KDQojIyMjIEFuYWx5c2lzDQpUaGUgYXBwcmVjaWF0aW9uIG9mIHRoZSBCcml0aXNoIHBvdW5kIGFnYWluc3QgdGhlIFVTIGRvbGxhciBtYXkgaW5kaWNhdGUsIGFzIHdlIGhhdmUgcHJldmlvdXNseSBleHBsYWluZWQsIGFuIHN0cmVuZ3RoZW5pbmcgb2YgVUsncyBlY29ub215IGFnYWluc3QgdGhlIFVTLiBBbHRob3VnaCB3ZSBjYW5ub3QgYmUgY2VydGFpbiB3aXRob3V0IG11Y2ggZnVydGhlciBhbmFseXNpcyBvZiB3aGF0IG1heSBoYXZlIGNhdXNlZCB0aGlzIG5vdG9yaW91cyBhcHByZWNpYXRpb24gb2YgdGhlIGN1cnJlbmN5LCB3ZSBjYW4gcHJlc3VtZSBpcyBhIG1peCBvZiBzZXZlcmFsIGZhY3RvcnMgdGhhdCBoYXZlIGJlZW4gYWxyZWFkeSBleHBsYWluZWQuIFRoaXMgY291bGQgaW5jbHVkZSBmYXZvcmFibGUgR0RQIGRhdGEgZm9yIHRoZSBVSywgYW4gYWdncmVzc2l2ZSBtb25ldGFyeSBwb2xpY3kgZnJvbSB0aGUgQmFuayBvZiBFbmdsYW5kIHdpdGggaGlnaGVyIGludGVyZXN0IHJhdGVzLCBvciB0aGUgc3RhYmlsaXphdGlvbiBvZiBjZXJ0YWluIGFzcGVjdHMgcmVnYXJkaW5nIEJyZXhpdC4gT24gdGhlIG90aGVyIHNpZGUsIHRoZSBVUyBtYXkgaGF2ZSBiZWNvbWUgc29tZXdoYXQgbGVzcyBhdHRyYWN0aXZlIGZvciBpbnZlc3RvcnMgd2hvIGxvb2sgZm9yIHJpc2tpZXIgb3Bwb3J0dW5pdGllcywgc2xvdyBpbmZsYXRpb24gd2l0aCBhIGxlc3MgYWdncmVzc2l2ZSBtb25ldGFyeSBwb2xpY3kgb3Igb3ZlcmFsbCBkaXNjb250ZW50IHdpdGggdGhlIHBvbGl0aWNhbCBzaXR1YXRpb24uIFRoZSB1cGNvbWluZyBVU0EgUHJlc2lkZW50aWFsIEVsZWN0aW9ucyBtYXkgaGF2ZSByaXNlbiBjZXJ0YWluIGNvbmNlcm5zIGFuZCBjcmVhdGVkIGEgc2Vuc2Ugb2YgaW5zdGFiaWxpdHkgdGhhdCBoYXMgYmVlbiBwb3J0cmF5ZWQgaW4gdGhlIGV4Y2hhbmdlIHJhdGUgYWdhaW5zdCB0aGUgQnJpdGlzaCBQb3VuZC4gDQoNCg0KIyMjIEwxMS45IERldGVybWluaW5nIHRoZSBQZXJjZW50YWdlIENoYW5nZSBpbiB0aGUgVmFsdWUgb2YgdGhlIEphcGFuZXNlIFllbg0KDQoNClJldHJpZXZlIFVTRC9KUFkgRXhjaGFuZ2UgUmF0ZSBEYXRhDQoNCmBgYHtyfQ0KIyBHZXQgVVNEL0pQWSBleGNoYW5nZSByYXRlIGRhdGENCmdldFN5bWJvbHMoIkpQWT1YIiwgc3JjID0gInlhaG9vIiwgZnJvbSA9IEJvVF9kYXRlIC0gNywgdG8gPSBFb1RfZGF0ZSArIDcsIGF1dG8uYXNzaWduID0gVFJVRSkNCg0KIyBBc3NpZ24gZGF0YSB0byBhIHZhcmlhYmxlDQp1c2RfanB5X2RhdGEgPC0gYEpQWT1YYA0KYGBgDQoNCg0KR2V0IEV4Y2hhbmdlIFJhdGVzIGF0IEJvVCBhbmQgRW9UDQoNCmBgYHtyfQ0KIyBHZXQgcmF0ZXMgYXQgQm9UIGFuZCBFb1QNCmpweV9yYXRlX0JvVCA8LSBnZXRfcmF0ZV9vbl9kYXRlKHVzZF9qcHlfZGF0YSwgQm9UX2RhdGUpDQpqcHlfcmF0ZV9Fb1QgPC0gZ2V0X3JhdGVfb25fZGF0ZSh1c2RfanB5X2RhdGEsIEVvVF9kYXRlKQ0KDQojIFByaW50IHRoZSBleGNoYW5nZSByYXRlcw0KY2F0KCJVU0QvSlBZIFJhdGUgYXQgQm9UICgiLCBqcHlfcmF0ZV9Cb1QkRGF0ZSwgIik6ICIsIHJvdW5kKGpweV9yYXRlX0JvVCRSYXRlLCA0KSwgIlxuIiwgc2VwID0gIiIpDQpjYXQoIlVTRC9KUFkgUmF0ZSBhdCBFb1QgKCIsIGpweV9yYXRlX0VvVCREYXRlLCAiKTogIiwgcm91bmQoanB5X3JhdGVfRW9UJFJhdGUsIDQpLCAiXG4iLCBzZXAgPSAiIikNCmBgYA0KDQoNCkNhbGN1bGF0ZSB0aGUgUGVyY2VudGFnZSBSYXRlDQoNCmBgYHtyfQ0KIyBJbnZlcnQgdGhlIHJhdGVzIHRvIGdldCBKUFkgcGVyIFVTRA0KanB5X3Blcl91c2RfQm9UIDwtIDEgLyBqcHlfcmF0ZV9Cb1QkUmF0ZQ0KanB5X3Blcl91c2RfRW9UIDwtIDEgLyBqcHlfcmF0ZV9Fb1QkUmF0ZQ0KDQojIENhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZSBjaGFuZ2UNCmpweV9wZXJjZW50YWdlX2NoYW5nZSA8LSAoanB5X3Blcl91c2RfRW9UIC0ganB5X3Blcl91c2RfQm9UKSAvIGpweV9wZXJfdXNkX0JvVCAqIDEwMA0KDQojIFByaW50IHRoZSByZXN1bHQNCmNhdCgiUGVyY2VudGFnZSBDaGFuZ2UgaW4gSlBZL1VTRDogIiwgcm91bmQoanB5X3BlcmNlbnRhZ2VfY2hhbmdlLCAyKSwgIiVcbiIsIHNlcCA9ICIiKQ0KYGBgDQoNCg0KRGV0ZXJtaW5lIEFwcHJlY2lhdGlvbiBvciBEZXByZWNpYXRpb24NCg0KYGBge3J9DQppZiAoanB5X3BlcmNlbnRhZ2VfY2hhbmdlID4gMCkgew0KICBqcHlfcmVzdWx0IDwtICJhcHByZWNpYXRlZCINCn0gZWxzZSBpZiAoanB5X3BlcmNlbnRhZ2VfY2hhbmdlIDwgMCkgew0KICBqcHlfcmVzdWx0IDwtICJkZXByZWNpYXRlZCINCn0gZWxzZSB7DQogIGpweV9yZXN1bHQgPC0gInJlbWFpbmVkIHRoZSBzYW1lIg0KfQ0KDQpjYXQoIlRoZSBKYXBhbmVzZSB5ZW4gaGFzICIsIGpweV9yZXN1bHQsICIgYWdhaW5zdCB0aGUgVVMgZG9sbGFyIG92ZXIgdGhlIHNjaG9vbCB0ZXJtLlxuIiwgc2VwID0gIiIpDQpgYGANCg0KIyMjIyBBbmFseXNpcw0KSnVzdCBhcyB3ZSBoYXZlIGV4cGxhaW5lZCBpbiB0aGUgcHJldmlvdXMgcXVlc3Rpb24uIHRoZSBVUyBtYXkgaGF2ZSBmYWNlZCBhIHBlcmlvZCBvZiBpbnN0YWJpbGl0eSBhbmQgc2xvd25lc3MgdGhhdCBjb3VsZCBoYXZlIGNhdXNlZCBhIGxvd2VyIGRlbWFuZCBmb3IgVVMgZG9sbGFycy4gQ29udmVyc2VseSwgdGhlIEJhbmsgb2YgSmFwYW4sIG1heSBoYXZlIGFkb3B0ZWQgYSBtb3JlIHN0cmljdCByZWd1bGF0aW9uIChpbiBvcHBvc2l0aW9uIHdpdGggaXRzIHRyYWRpdGlvbmFsIGFwcHJvYWNoKSBkdWUgdG8gaGlnaCBpbmZsYXRpb24gb3IgZHVlIHRvIG5vcm1hbGl6YXRpb24gc3RyYXRlZ2llcywgd2hpY2ggbWF5IGhhdmUgY2F1c2VkIGEgcmVhY3Rpb24gaW4gdGhlIGN1cnJlbmN5IG1hcmtldHMuIEphcGFuIG1heSBoYXZlIGFsc28gaGFkIHBvc2l0aXZlIHJlcG9ydHMgb3IgYSByZWNvdmVyeSBpbiBpdHMgdHJhZGUgYmFsYW5jZS4gDQoNCiMjIyBMMTEuMTAgRGV0ZXJtaW5pbmcgdGhlIFBlcmNlbnRhZ2UgQ2hhbmdlIGluIHRoZSBWYWx1ZSBvZiB0aGUgTWV4aWNhbiBQZXNvDQoNCg0KUmV0cmlldmUgVVNEL01YTiBFeGNoYW5nZSBSYXRlIERhdGENCg0KYGBge3J9DQojIEdldCBVU0QvTVhOIGV4Y2hhbmdlIHJhdGUgZGF0YQ0KZ2V0U3ltYm9scygiTVhOPVgiLCBzcmMgPSAieWFob28iLCBmcm9tID0gQm9UX2RhdGUgLSA3LCB0byA9IEVvVF9kYXRlICsgNywgYXV0by5hc3NpZ24gPSBUUlVFKQ0KDQojIEFzc2lnbiBkYXRhIHRvIGEgdmFyaWFibGUNCnVzZF9teG5fZGF0YSA8LSBgTVhOPVhgDQpgYGANCg0KDQpHZXQgRXhjaGFuZ2UgUmF0ZXMgYXQgQm9UIGFuZCBFb1QNCg0KYGBge3J9DQojIEdldCByYXRlcyBhdCBCb1QgYW5kIEVvVA0KbXhuX3JhdGVfQm9UIDwtIGdldF9yYXRlX29uX2RhdGUodXNkX214bl9kYXRhLCBCb1RfZGF0ZSkNCm14bl9yYXRlX0VvVCA8LSBnZXRfcmF0ZV9vbl9kYXRlKHVzZF9teG5fZGF0YSwgRW9UX2RhdGUpDQoNCiMgUHJpbnQgdGhlIGV4Y2hhbmdlIHJhdGVzDQpjYXQoIlVTRC9NWE4gUmF0ZSBhdCBCb1QgKCIsIG14bl9yYXRlX0JvVCREYXRlLCAiKTogIiwgcm91bmQobXhuX3JhdGVfQm9UJFJhdGUsIDQpLCAiXG4iLCBzZXAgPSAiIikNCmNhdCgiVVNEL01YTiBSYXRlIGF0IEVvVCAoIiwgbXhuX3JhdGVfRW9UJERhdGUsICIpOiAiLCByb3VuZChteG5fcmF0ZV9Fb1QkUmF0ZSwgNCksICJcbiIsIHNlcCA9ICIiKQ0KYGBgDQoNCg0KQ2FsY3VsYXRlIHRoZSBQZXJjZW50YWdlIENoYW5nZQ0KDQpgYGB7cn0NCiMgSW52ZXJ0IHRoZSByYXRlcyB0byBnZXQgTVhOIHBlciBVU0QNCm14bl9wZXJfdXNkX0JvVCA8LSAxIC8gbXhuX3JhdGVfQm9UJFJhdGUNCm14bl9wZXJfdXNkX0VvVCA8LSAxIC8gbXhuX3JhdGVfRW9UJFJhdGUNCg0KIyBDYWxjdWxhdGUgdGhlIHBlcmNlbnRhZ2UgY2hhbmdlDQpteG5fcGVyY2VudGFnZV9jaGFuZ2UgPC0gKG14bl9wZXJfdXNkX0VvVCAtIG14bl9wZXJfdXNkX0JvVCkgLyBteG5fcGVyX3VzZF9Cb1QgKiAxMDANCg0KIyBQcmludCB0aGUgcmVzdWx0DQpjYXQoIlBlcmNlbnRhZ2UgQ2hhbmdlIGluIE1YTi9VU0Q6ICIsIHJvdW5kKG14bl9wZXJjZW50YWdlX2NoYW5nZSwgMiksICIlXG4iLCBzZXAgPSAiIikNCmBgYA0KDQoNCkRldGVybWluZSBBcHByZWNpYXRpb24gb3IgRGVwcmVjaWF0aW9uDQoNCmBgYHtyfQ0KaWYgKG14bl9wZXJjZW50YWdlX2NoYW5nZSA+IDApIHsNCiAgbXhuX3Jlc3VsdCA8LSAiYXBwcmVjaWF0ZWQiDQp9IGVsc2UgaWYgKG14bl9wZXJjZW50YWdlX2NoYW5nZSA8IDApIHsNCiAgbXhuX3Jlc3VsdCA8LSAiZGVwcmVjaWF0ZWQiDQp9IGVsc2Ugew0KICBteG5fcmVzdWx0IDwtICJyZW1haW5lZCB0aGUgc2FtZSINCn0NCg0KY2F0KCJUaGUgTWV4aWNhbiBwZXNvIGhhcyAiLCBteG5fcmVzdWx0LCAiIGFnYWluc3QgdGhlIFVTIGRvbGxhciBvdmVyIHRoZSBzY2hvb2wgdGVybS5cbiIsIHNlcCA9ICIiKQ0KYGBgDQoNCiMjIyMgQW5hbHlzaXMNCkhhdmUgd2Ugbm90IHNlZW4gdGhlIHByZXZpb3VzIHJlc3VsdHMsIHdlIG1pZ2h0IGhhdmUgaGFkIHRoZSBpbml0aWFsIHRob3VnaHQgdGhhdCB0aGVzZSByZXN1bHRzIGFyZSB0aGUgbWFuaWZlc3RhdGlvbiBvZiBhIHN0cm9uZyBVUyBEb2xsYXIsIHdoaWNoIHN0cmVuZ3RoZW5zIGFnYWluc3QgdGhlIE1leGljYW4gUGVzby4gSG93ZXZlciwgd2UgYWxyZWFkeSBrbm93IHRoYXQgdGhlIFVTRCBoYWQgd2Vha2VuZWQgYWdhaW5zdCB0aGUgb3RoZXIgdHdvIGN1cnJlbmNpZXMgYW5hbHl6ZWQsIHNvIHdlIG1heSBhc3N1bWUgdGhhdCB0aGlzIGlzIG5vdCB0aGUgb3V0Y29tZSBvZiBhbiBzdHJvbmcgVVNBIGJ1dCByYXRoZXIgYSByZWFsbHkgd29yc2VuZWQgTWV4aWNvLiANCklmIHdlIHRha2UgYSBsb29rIGludG8gTWV4aWNvJ3MgcG9saXRpY3MgZHVyaW5nIHRoZSBUZXJtIFBlcmlvZCwgd2Ugd2lsbCBub3RpY2UgdGhhdCBQcmVzaWRlbnRpYWwgRWxlY3Rpb25zIHRvb2sgcGxhY2UsIHdpdGggdGhlIHZpY3Rvcnkgb2YgQ2xhdWRpYSBTaGVpbmJhdW0uIFRoZSBkaWZmZXJlbmNlIGluIHBvc2l0aW9ucyB3aXRoIHRoZSBVU0EgaW4gc2V2ZXJhbCBpbnRlcm5hdGlvbmFsIG1hdHRlcnMgbWF5IGhhdmUgcHVzaGVkIHRoaXMgZHJvcCBpbiB0aGUgTWV4aWNhbiBQZXNvLCB3aGljaCBoYXMgbm90IHlldCBzdG9wcGVkIGFzIG9mIHRvZGF5LCBhbHRob3VnaCBvdXIgRW5kIG9mIFRlcm0gRGF0ZSBvbmx5IGRhdGVzIHVudGlsIFNlcHRlbWJlci4gDQoNCiMjIyBMMTEuMTEgRGV0ZXJtaW5pbmcgdGhlIFBlciBVbml0IEdhaW4gb3IgTG9zcyBmb3IgQnJpdGlzaCBQb3VuZCBGdXR1cmVzDQoNCg0KRGV0ZXJtaW5lIHRoZSBwZXIgdW5pdCBnYWluIG9yIGxvc3MgaWYgeW91IGhhZCBwdXJjaGFzZWQgQnJpdGlzaCBwb3VuZCBmdXR1cmVzIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRlcm0gYW5kIHNvbGQgdGhlbSBhdCB0aGUgZW5kIG9mIHRoZSB0ZXJtLg0KVXNlIEdQQi9VU0QgRXhjaGFuZ2UgcmF0ZXMgYXMgUHJveHkuIA0KDQoNCkNhbGN1bGF0ZSB0aGUgUGVyIFVuaXQgR2FpbiBvciBMb3NzDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdGhlIHBlciB1bml0IGdhaW4gb3IgbG9zcw0KcGVyX3VuaXRfZ2Fpbl9sb3NzIDwtIGdicF9yYXRlX0VvVCRSYXRlIC0gZ2JwX3JhdGVfQm9UJFJhdGUNCg0KIyBQcmludCB0aGUgcmVzdWx0DQpjYXQoIlBlciBVbml0IEdhaW4vTG9zcyBmb3IgR0JQIEZ1dHVyZXM6ICQiLCByb3VuZChwZXJfdW5pdF9nYWluX2xvc3MsIDQpLCAiIHBlciBHQlBcbiIsIHNlcCA9ICIiKQ0KYGBgDQpJbiB0aGlzIGV4ZXJjaXNlIHdlIGhhdmUgZGV0ZXJtaW5lZCB0aGUgZ2FpbiBwZXIgR1BCIGZvciB0aGUgZnV0dXJlcyBjb250cmFjdC4NCg0KIyMjIEwxMS4xMiBEZXRlcm1pbmluZyB0aGUgRG9sbGFyIEFtb3VudCBvZiBZb3VyIEdhaW4gb3IgTG9zcyBvbiB0aGUgRnV0dXJlcyBDb250cmFjdA0KDQpHaXZlbiB0aGF0IGEgc2luZ2xlIGZ1dHVyZXMgY29udHJhY3Qgb24gQnJpdGlzaCBwb3VuZHMgcmVwcmVzZW50cyA2Miw1MDAgcG91bmRzLCBkZXRlcm1pbmUgdGhlIGRvbGxhciBhbW91bnQgb2YgeW91ciBnYWluIG9yIGxvc3MuDQpgYGB7cn0NCiMgTnVtYmVyIG9mIHBvdW5kcyBwZXIgZnV0dXJlcyBjb250cmFjdA0KY29udHJhY3Rfc2l6ZSA8LSA2MjUwMA0KDQojIFRvdGFsIGdhaW4gb3IgbG9zcw0KdG90YWxfZ2Fpbl9sb3NzIDwtIHBlcl91bml0X2dhaW5fbG9zcyAqIGNvbnRyYWN0X3NpemUNCg0KIyBQcmludCB0aGUgcmVzdWx0DQpjYXQoIlRvdGFsIEdhaW4vTG9zcyBvbiBGdXR1cmVzIENvbnRyYWN0OiAkIiwgcm91bmQodG90YWxfZ2Fpbl9sb3NzLCAyKSwgIlxuIiwgc2VwID0gIiIpDQpgYGANCg0KDQpEZXRlcm1pbmUgaWYgeW91IEdhaW5lZCBvciBMb3N0DQoNCmBgYHtyfQ0KaWYgKHRvdGFsX2dhaW5fbG9zcyA+IDApIHsNCiAgZnV0dXJlc19yZXN1bHQgPC0gImdhaW5lZCINCn0gZWxzZSBpZiAodG90YWxfZ2Fpbl9sb3NzIDwgMCkgew0KICBmdXR1cmVzX3Jlc3VsdCA8LSAibG9zdCINCn0gZWxzZSB7DQogIGZ1dHVyZXNfcmVzdWx0IDwtICJicm9rZSBldmVuIg0KfQ0KDQpjYXQoIllvdSBoYXZlICIsIGZ1dHVyZXNfcmVzdWx0LCAiICQiLCBhYnMocm91bmQodG90YWxfZ2Fpbl9sb3NzLCAyKSksICIgb24gdGhlIGZ1dHVyZXMgY29udHJhY3QuXG4iLCBzZXAgPSAiIikNCmBgYA0KDQpXaXRoIGEgZ2FpbiBwZXIgR1BCIG9mIDAuMDgzNyBVU0QgYW5kIGFuIGFtb3VudCBvZiA2MjUwMCBwb3VuZHMsIHdlIHdpbGwgaGF2ZSBlbmRlZCBhdCB0aGUgZW5kIG9mIHRlcm0gd2l0aCBhIHRvdGFsIGdhaW4gb2YgNTIyOS45NiBVU0QuIFRoaXMgaGFzIGJlZW4gcG9zc2libGUsIGFzIHdlIGtub3csIHRoYW5rcyB0byB0aGUgYXBwcmVjaWF0aW9uIG9mIHRoZSBHUEIgYWdhaW5zdCB0aGUgVVNELCB3aGljaCBoZSBoYXZlIGFscmVhZHkgYW5hbHl6ZWQgcHJldmlvdXNseS4gDQoNCg0KDQo=