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=