library(readxl)
Warning: пакет ‘readxl’ был собран под R версии 4.1.3
library(dplyr)
Warning: пакет ‘dplyr’ был собран под R версии 4.1.3

Присоединяю пакет: ‘dplyr’

Следующие объекты скрыты от ‘package:stats’:

    filter, lag

Следующие объекты скрыты от ‘package:base’:

    intersect, setdiff, setequal, union
library(dplyr)
library(lubridate)
Warning: пакет ‘lubridate’ был собран под R версии 4.1.3

Присоединяю пакет: ‘lubridate’

Следующие объекты скрыты от ‘package:base’:

    date, intersect, setdiff, union
library(zoo)

Присоединяю пакет: ‘zoo’

Следующие объекты скрыты от ‘package:base’:

    as.Date, as.Date.numeric
library(forecast)
Warning: пакет ‘forecast’ был собран под R версии 4.1.3
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
library(vars)
Warning: пакет ‘vars’ был собран под R версии 4.1.3
Загрузка требуемого пакета: MASS
Warning: пакет ‘MASS’ был собран под R версии 4.1.3

Присоединяю пакет: ‘MASS’

Следующий объект скрыт от ‘package:dplyr’:

    select

Загрузка требуемого пакета: strucchange
Warning: пакет ‘strucchange’ был собран под R версии 4.1.3
Загрузка требуемого пакета: sandwich
Warning: пакет ‘sandwich’ был собран под R версии 4.1.2
Загрузка требуемого пакета: urca
Загрузка требуемого пакета: lmtest
library(mFilter)
Warning: пакет ‘mFilter’ был собран под R версии 4.1.3

    ‘mFilter’ version: 0.1-5

    ‘mFilter’ is a package for time series filtering

    See ‘library(help="mFilter")’ for details

    Author: Mehmet Balcilar, mbalcilar@yahoo.com
library(BVAR)

Присоединяю пакет: ‘BVAR’

Следующие объекты скрыты от ‘package:vars’:

    fevd, irf

Загружаю все необходимые данные У нас четыре ряда: 1. ВРП в постоянных ценах 2021 года 2. Инфляция QoQ 3. Доходы и расходы консолидированного бюджета РФ 4. Ключевая ставка

Поработаем с каждым рядом в отдельности ВРП


gdp <- read_excel("Data.xlsx", sheet = "gdp")

gdp_ts <- ts(
  gdp[[3]],
  start     = c(gdp[1,1],gdp[1,2]),
  frequency = 4
)

stl_fit <- stl(gdp_ts, s.window = "periodic")
plot(stl_fit)

gdp_des <- seasadj(stl_fit)

print(gdp_des)
         Qtr1     Qtr2     Qtr3     Qtr4
2011 29374790 29699724 29405983 29103405
2012 30884122 31088974 30459373 29883111
2013 31200582 31605718 30930875 30725560
2014 31187188 31775282 31376305 31040339
2015 30755552 30826995 30829847 30493341
2016 30698104 30922544 30848395 30674723
2017 31062182 31621384 31682481 31027194
2018 31783917 32455003 32537220 32136064
2019 32184890 32880952 33459004 33220945
2020 32628803 30554215 32319770 32746924
2021 32812182 33671479 33702711 34541093
2022 33821834 32464353 32689511 33817238
2023 33547342 34137063 34753998 35775839
2024 35188344 35558511 35929569 37542363
plot(gdp_des, main = "GDP(ts)", ylab = "GDP", xlab = "Time")

Теперь займемся рядом по бюджетным показателям

budget <- read_excel("Data.xlsx",sheet = "budget")

budget_q <- budget %>%
  arrange(year, quarter) %>%        
  group_by(year) %>%                 
  mutate(
    across(
      fed_revenue:cons_expend,      
      ~ . - lag(., default = 0),      
      .names = "{.col}_q"       
    )
  ) %>%
  ungroup()


idx <- with(budget_q, as.yearqtr(paste(year, quarter), "%Y %q"))

budget_ts <- zoo(
  cbind(
    fed_revenue_q = budget_q$fed_revenue_q,
    fed_expend_q  = budget_q$fed_expend_q,
    cons_revenue_q = budget_q$cons_revenue_q,
    cons_expend_q  = budget_q$cons_expend_q
  ),
  order.by = idx
)

plot(budget_ts)

Ключевая ставка

Инфляция QoQ

cpi <- read_excel("Data.xlsx", sheet = "cpi")

cpi_ts <- ts(
  cpi[[3]],
  start     = c(cpi[1,1],cpi[1,2]),
  frequency = 4
)
plot(cpi_ts, main = "CPI(ts)", ylab = "CPI", xlab = "Time")


stl_fit <- stl(cpi_ts, s.window = "periodic")
plot(stl_fit)

cpi_des <- seasadj(stl_fit)

plot(cpi_des,
     main = "Квартальный CPI без сезонности (STL)",
     ylab = "cpi", xlab = "Время")


gdp  <- window(gdp_des,  start = c(2013, 3), end = c(2023, 4))
infl    <- window(cpi_des,  start = c(2013, 3), end = c(2023, 4))
cons_re <- window(as.ts(budget_ts[,3]),  start = c(2013, 3), end = c(2023, 4)) 
cons_ex <- window(as.ts(budget_ts[,4]),  start = c(2013, 3), end = c(2023, 4)) 
key_rate<- window(key_rate_ts,  start = c(2013, 3), end = c(2023, 4)) 
balance_budget <- (cons_re - cons_ex)/gdp

##Проведем тест на едичные корни для GDP

Единичные корни -> поиск коинтеграции + модель коррекции ошибок (ECM)

Стационарность -> векторная регрессия

ADF

gdp_adf = ur.df(gdp, type = 'trend', selectlags = 'AIC')
summary(gdp_adf)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression trend 


Call:
lm(formula = z.diff ~ z.lag.1 + 1 + tt + z.diff.lag)

Residuals:
     Min       1Q   Median       3Q      Max 
-2072694  -288320   -10902   377264  1126294 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)   
(Intercept)  1.724e+07  5.245e+06   3.288  0.00226 **
z.lag.1     -5.713e-01  1.732e-01  -3.298  0.00220 **
tt           5.733e+04  1.724e+04   3.324  0.00205 **
z.diff.lag   2.556e-01  1.731e-01   1.477  0.14840   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 620900 on 36 degrees of freedom
Multiple R-squared:  0.2463,    Adjusted R-squared:  0.1835 
F-statistic: 3.922 on 3 and 36 DF,  p-value: 0.01605


Value of test-statistic is: -3.2981 4.4737 5.8687 

Critical values for test statistics: 
      1pct  5pct 10pct
tau3 -4.15 -3.50 -3.18
phi2  7.02  5.13  4.31
phi3  9.31  6.73  5.61

Гипотеза об единичном корне на уровне 10% отвергается (ADF), но не 5%. Необходимо првоести теcn KPSS Гипотеза о стационарности ряда отвергается (KPSS). Ряд нестационарен

KPSS:

gdp_kpss <- ur.kpss(gdp, type="mu", lags="short")
summary(gdp_kpss)

####################### 
# KPSS Unit Root Test # 
####################### 

Test is of type: mu with 3 lags. 

Value of test-statistic is: 1.0309 

Critical value for a significance level of: 
                10pct  5pct 2.5pct  1pct
critical values 0.347 0.463  0.574 0.739

##Проведем тест на едичные корни для Inflation

infl_adf = ur.df(infl, type = 'drift', selectlags = 'AIC')
summary(infl_adf)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression drift 


Call:
lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.7767 -0.6838 -0.2490  0.4300  4.4484 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept) 59.63801   18.67002   3.194  0.00286 **
z.lag.1     -0.58601    0.18354  -3.193  0.00287 **
z.diff.lag  -0.03715    0.16510  -0.225  0.82319   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.448 on 37 degrees of freedom
Multiple R-squared:  0.3016,    Adjusted R-squared:  0.2639 
F-statistic:  7.99 on 2 and 37 DF,  p-value: 0.001305


Value of test-statistic is: -3.1929 5.1062 

Critical values for test statistics: 
      1pct  5pct 10pct
tau2 -3.58 -2.93 -2.60
phi1  7.06  4.86  3.94
infl_kpss <- ur.kpss(infl, type="mu", lags="short")
summary(infl_kpss)

Гипотеза об единичном корне на уровне 10% отвергается (ADF), но не 5%. Необходимо првоести теcn KPSS Гипотеза о стационарности ряда отвергается (KPSS). Ряд нестационарен

##Проведем тест на едичные корни для key_rate

key_rate_adf = ur.df(key_rate, type = 'none', selectlags = 'AIC')
summary(key_rate_adf)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression none 


Call:
lm(formula = z.diff ~ z.lag.1 - 1 + z.diff.lag)

Residuals:
    Min      1Q  Median      3Q     Max 
-5.1750 -0.4280  0.0566  0.5397  8.1310 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)
z.lag.1    -0.004416   0.038938  -0.113    0.910
z.diff.lag  0.189568   0.170515   1.112    0.273

Residual standard error: 2.163 on 38 degrees of freedom
Multiple R-squared:  0.03169,   Adjusted R-squared:  -0.01928 
F-statistic: 0.6218 on 2 and 38 DF,  p-value: 0.5424


Value of test-statistic is: -0.1134 

Critical values for test statistics: 
      1pct  5pct 10pct
tau1 -2.62 -1.95 -1.61
key_rate_kpss <- ur.kpss(key_rate, type="mu", lags="short")
summary(key_rate_kpss)

####################### 
# KPSS Unit Root Test # 
####################### 

Test is of type: mu with 3 lags. 

Value of test-statistic is: 0.1447 

Critical value for a significance level of: 
                10pct  5pct 2.5pct  1pct
critical values 0.347 0.463  0.574 0.739

Ряд точно нестационарный

##Проведем тест на едичные корни для Balance_Budget

autoplot(balance_budget)

budget_adf = ur.df(balance_budget, type = 'none', selectlags = 'AIC')
summary(budget_adf)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression none 


Call:
lm(formula = z.diff ~ z.lag.1 - 1 + z.diff.lag)

Residuals:
       Min         1Q     Median         3Q        Max 
-1.037e-04 -4.415e-05  3.766e-06  2.520e-05  7.344e-05 

Coefficients:
           Estimate Std. Error t value Pr(>|t|)    
z.lag.1     -0.8226     0.2228  -3.693 0.000694 ***
z.diff.lag  -0.1226     0.1661  -0.738 0.464963    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 4.408e-05 on 38 degrees of freedom
Multiple R-squared:  0.4638,    Adjusted R-squared:  0.4356 
F-statistic: 16.44 on 2 and 38 DF,  p-value: 7.187e-06


Value of test-statistic is: -3.6928 

Critical values for test statistics: 
      1pct  5pct 10pct
tau1 -2.62 -1.95 -1.61
budget_kpss <- ur.kpss(balance_budget, type="mu", lags="short")
summary(budget_kpss)

####################### 
# KPSS Unit Root Test # 
####################### 

Test is of type: mu with 3 lags. 

Value of test-statistic is: 0.1123 

Critical value for a significance level of: 
                10pct  5pct 2.5pct  1pct
critical values 0.347 0.463  0.574 0.739

Ряд стационарен по результатам обоих тестов.

# Разбиваем область на 2×2
par(mfrow = c(2, 2),    # 2 строки, 2 колонки
    mar   = c(4, 4, 2, 1))  # отступы: снизу, слева, сверху, справа

# 1-й график
plot(gdp,
     main = "ВВП SA",
     xlab = "", ylab = "млн. руб.")

# 2-й
plot(infl,
     main = "ИПЦ SA",
     xlab = "", ylab = "%")

# 3-й
plot(balance_budget,
     main = "Сальдо бюджета к ВВП",
     xlab = "Время", ylab = "%")

# 4-й
plot(key_rate,
     main = "Ключевая ставка ЦБ РФ",
     xlab = "Время", ylab = "%")

# Вернуть настройки по умолчанию (опционально)
par(mfrow = c(1,1))

LS0tDQp0aXRsZTogItCf0YDQvtC10LrRgiDQv9C+INCQ0JLQoC0yIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHpvbykNCmxpYnJhcnkoZm9yZWNhc3QpDQpsaWJyYXJ5KHZhcnMpDQpsaWJyYXJ5KG1GaWx0ZXIpDQpsaWJyYXJ5KEJWQVIpDQpgYGANCg0K0JfQsNCz0YDRg9C20LDRjiDQstGB0LUg0L3QtdC+0LHRhdC+0LTQuNC80YvQtSDQtNCw0L3QvdGL0LUNCtCjINC90LDRgSDRh9C10YLRi9GA0LUg0YDRj9C00LA6DQoxLiDQktCg0J8g0LIg0L/QvtGB0YLQvtGP0L3QvdGL0YUg0YbQtdC90LDRhSAyMDIxINCz0L7QtNCwDQoyLiDQmNC90YTQu9GP0YbQuNGPIFFvUSANCjMuINCU0L7RhdC+0LTRiyDQuCDRgNCw0YHRhdC+0LTRiyDQutC+0L3RgdC+0LvQuNC00LjRgNC+0LLQsNC90L3QvtCz0L4g0LHRjtC00LbQtdGC0LAg0KDQpA0KNC4g0JrQu9GO0YfQtdCy0LDRjyDRgdGC0LDQstC60LANCg0K0J/QvtGA0LDQsdC+0YLQsNC10Lwg0YEg0LrQsNC20LTRi9C8INGA0Y/QtNC+0Lwg0LIg0L7RgtC00LXQu9GM0L3QvtGB0YLQuA0K0JLQoNCfDQpgYGB7cn0NCg0KZ2RwIDwtIHJlYWRfZXhjZWwoIkRhdGEueGxzeCIsIHNoZWV0ID0gImdkcCIpDQoNCmdkcF90cyA8LSB0cygNCiAgZ2RwW1szXV0sDQogIHN0YXJ0ICAgICA9IGMoZ2RwWzEsMV0sZ2RwWzEsMl0pLA0KICBmcmVxdWVuY3kgPSA0DQopDQoNCnN0bF9maXQgPC0gc3RsKGdkcF90cywgcy53aW5kb3cgPSAicGVyaW9kaWMiKQ0KcGxvdChzdGxfZml0KQ0KZ2RwX2RlcyA8LSBzZWFzYWRqKHN0bF9maXQpDQoNCnByaW50KGdkcF9kZXMpDQpwbG90KGdkcF9kZXMsIG1haW4gPSAiR0RQKHRzKSIsIHlsYWIgPSAiR0RQIiwgeGxhYiA9ICJUaW1lIikNCmBgYA0K0KLQtdC/0LXRgNGMINC30LDQudC80LXQvNGB0Y8g0YDRj9C00L7QvCDQv9C+INCx0Y7QtNC20LXRgtC90YvQvCDQv9C+0LrQsNC30LDRgtC10LvRj9C8DQoNCmBgYHtyfQ0KYnVkZ2V0IDwtIHJlYWRfZXhjZWwoIkRhdGEueGxzeCIsc2hlZXQgPSAiYnVkZ2V0IikNCg0KYnVkZ2V0X3EgPC0gYnVkZ2V0ICU+JQ0KICBhcnJhbmdlKHllYXIsIHF1YXJ0ZXIpICU+JSAgICAgICAgDQogIGdyb3VwX2J5KHllYXIpICU+JSAgICAgICAgICAgICAgICAgDQogIG11dGF0ZSgNCiAgICBhY3Jvc3MoDQogICAgICBmZWRfcmV2ZW51ZTpjb25zX2V4cGVuZCwgICAgICANCiAgICAgIH4gLiAtIGxhZyguLCBkZWZhdWx0ID0gMCksICAgICAgDQogICAgICAubmFtZXMgPSAiey5jb2x9X3EiICAgICAgIA0KICAgICkNCiAgKSAlPiUNCiAgdW5ncm91cCgpDQoNCg0KaWR4IDwtIHdpdGgoYnVkZ2V0X3EsIGFzLnllYXJxdHIocGFzdGUoeWVhciwgcXVhcnRlciksICIlWSAlcSIpKQ0KDQpidWRnZXRfdHMgPC0gem9vKA0KICBjYmluZCgNCiAgICBmZWRfcmV2ZW51ZV9xID0gYnVkZ2V0X3EkZmVkX3JldmVudWVfcSwNCiAgICBmZWRfZXhwZW5kX3EgID0gYnVkZ2V0X3EkZmVkX2V4cGVuZF9xLA0KICAgIGNvbnNfcmV2ZW51ZV9xID0gYnVkZ2V0X3EkY29uc19yZXZlbnVlX3EsDQogICAgY29uc19leHBlbmRfcSAgPSBidWRnZXRfcSRjb25zX2V4cGVuZF9xDQogICksDQogIG9yZGVyLmJ5ID0gaWR4DQopDQoNCnBsb3QoYnVkZ2V0X3RzKQ0KDQpgYGANCg0K0JrQu9GO0YfQtdCy0LDRjyDRgdGC0LDQstC60LANCmBgYHtyfQ0Ka2V5X3JhdGUgPC0gcmVhZF9leGNlbCgiRGF0YS54bHN4Iiwgc2hlZXQgPSAia2V5X3JhdGUiKQ0KDQprZXlfcmF0ZV9xIDwtIGtleV9yYXRlICU+JQ0KICBtdXRhdGUoDQogICAgeWVhciAgPSB5ZWFyKGRhdGUpLA0KICAgIHF1YXJ0ZXIgPSBxdWFydGVyKGRhdGUpLA0KICAgIHllYXJxdHIgPSBwYXN0ZTAoeWVhciwgIiBRIiwgcXVhcnRlcikNCiAgKSAlPiUNCiAgZ3JvdXBfYnkoeWVhcnF0cikgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBrZXlfcmF0ZV9xID0gbWVhbihrZXlfcmF0ZSwgbmEucm0gPSBUUlVFKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiDQogICkNCg0KIyDQodC+0LfQtNCw0ZHQvCB6b28t0YDRj9C0INC4INC60L7QvdCy0LXRgNGC0LjRgNGD0LXQvCDQsiB0cw0Ka2V5X3JhdGVfdHMgPC0gdHMoa2V5X3JhdGVfcVtbMl1dLA0KICAgICAgICAgICAgICAgICAgZnJlcXVlbmN5ID0gNCwNCiAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gYygyMDEzLDMpIA0KICAgICAgICAgICAgICAgICAgKQ0KDQpwbG90KGtleV9yYXRlX3RzKQ0KYGBgDQrQmNC90YTQu9GP0YbQuNGPIFFvUQ0KDQpgYGB7cn0NCmNwaSA8LSByZWFkX2V4Y2VsKCJEYXRhLnhsc3giLCBzaGVldCA9ICJjcGkiKQ0KDQpjcGlfdHMgPC0gdHMoDQogIGNwaVtbM11dLA0KICBzdGFydCAgICAgPSBjKGNwaVsxLDFdLGNwaVsxLDJdKSwNCiAgZnJlcXVlbmN5ID0gNA0KKQ0KcGxvdChjcGlfdHMsIG1haW4gPSAiQ1BJKHRzKSIsIHlsYWIgPSAiQ1BJIiwgeGxhYiA9ICJUaW1lIikNCg0Kc3RsX2ZpdCA8LSBzdGwoY3BpX3RzLCBzLndpbmRvdyA9ICJwZXJpb2RpYyIpDQpwbG90KHN0bF9maXQpDQpjcGlfZGVzIDwtIHNlYXNhZGooc3RsX2ZpdCkNCg0KcGxvdChjcGlfZGVzLA0KICAgICBtYWluID0gItCa0LLQsNGA0YLQsNC70YzQvdGL0LkgQ1BJINCx0LXQtyDRgdC10LfQvtC90L3QvtGB0YLQuCAoU1RMKSIsDQogICAgIHlsYWIgPSAiY3BpIiwgeGxhYiA9ICLQktGA0LXQvNGPIikNCmBgYA0KYGBge3J9DQoNCmdkcCAgPC0gd2luZG93KGdkcF9kZXMsICBzdGFydCA9IGMoMjAxMywgMyksIGVuZCA9IGMoMjAyMywgNCkpDQppbmZsICAgIDwtIHdpbmRvdyhjcGlfZGVzLCAgc3RhcnQgPSBjKDIwMTMsIDMpLCBlbmQgPSBjKDIwMjMsIDQpKQ0KY29uc19yZSA8LSB3aW5kb3coYXMudHMoYnVkZ2V0X3RzWywzXSksICBzdGFydCA9IGMoMjAxMywgMyksIGVuZCA9IGMoMjAyMywgNCkpIA0KY29uc19leCA8LSB3aW5kb3coYXMudHMoYnVkZ2V0X3RzWyw0XSksICBzdGFydCA9IGMoMjAxMywgMyksIGVuZCA9IGMoMjAyMywgNCkpIA0Ka2V5X3JhdGU8LSB3aW5kb3coa2V5X3JhdGVfdHMsICBzdGFydCA9IGMoMjAxMywgMyksIGVuZCA9IGMoMjAyMywgNCkpIA0KYmFsYW5jZV9idWRnZXQgPC0gKGNvbnNfcmUgLSBjb25zX2V4KS9nZHANCg0KYGBgDQojI9Cf0YDQvtCy0LXQtNC10Lwg0YLQtdGB0YIg0L3QsCDQtdC00LjRh9C90YvQtSDQutC+0YDQvdC4INC00LvRjyBHRFANCg0K0JXQtNC40L3QuNGH0L3Ri9C1INC60L7RgNC90LggLT4g0L/QvtC40YHQuiDQutC+0LjQvdGC0LXQs9GA0LDRhtC40LggKyDQvNC+0LTQtdC70Ywg0LrQvtGA0YDQtdC60YbQuNC4INC+0YjQuNCx0L7QuiAoRUNNKQ0KDQrQodGC0LDRhtC40L7QvdCw0YDQvdC+0YHRgtGMIC0+INCy0LXQutGC0L7RgNC90LDRjyDRgNC10LPRgNC10YHRgdC40Y8NCg0KKioqQURGKioqDQpgYGB7cn0NCmdkcF9hZGYgPSB1ci5kZihnZHAsIHR5cGUgPSAndHJlbmQnLCBzZWxlY3RsYWdzID0gJ0FJQycpDQpzdW1tYXJ5KGdkcF9hZGYpDQpgYGANCtCT0LjQv9C+0YLQtdC30LAg0L7QsSDQtdC00LjQvdC40YfQvdC+0Lwg0LrQvtGA0L3QtSDQvdCwINGD0YDQvtCy0L3QtSAxMCUg0L7RgtCy0LXRgNCz0LDQtdGC0YHRjyAoQURGKSwg0L3QviDQvdC1IDUlLiDQndC10L7QsdGF0L7QtNC40LzQviDQv9GA0LLQvtC10YHRgtC4INGC0LVjbiBLUFNTDQrQk9C40L/QvtGC0LXQt9CwINC+INGB0YLQsNGG0LjQvtC90LDRgNC90L7RgdGC0Lgg0YDRj9C00LAg0L7RgtCy0LXRgNCz0LDQtdGC0YHRjyAoS1BTUykuINCg0Y/QtCDQvdC10YHRgtCw0YbQuNC+0L3QsNGA0LXQvQ0KDQoqKktQU1MqKjoNCmBgYHtyfQ0KZ2RwX2twc3MgPC0gdXIua3BzcyhnZHAsIHR5cGU9Im11IiwgbGFncz0ic2hvcnQiKQ0Kc3VtbWFyeShnZHBfa3BzcykNCmBgYA0KIyPQn9GA0L7QstC10LTQtdC8INGC0LXRgdGCINC90LAg0LXQtNC40YfQvdGL0LUg0LrQvtGA0L3QuCDQtNC70Y8gSW5mbGF0aW9uDQoNCmBgYHtyfQ0KaW5mbF9hZGYgPSB1ci5kZihpbmZsLCB0eXBlID0gJ2RyaWZ0Jywgc2VsZWN0bGFncyA9ICdBSUMnKQ0Kc3VtbWFyeShpbmZsX2FkZikNCg0KYGBgDQpgYGB7cn0NCmluZmxfa3BzcyA8LSB1ci5rcHNzKGluZmwsIHR5cGU9Im11IiwgbGFncz0ic2hvcnQiKQ0Kc3VtbWFyeShpbmZsX2twc3MpDQpgYGANCg0K0JPQuNC/0L7RgtC10LfQsCDQvtCxINC10LTQuNC90LjRh9C90L7QvCDQutC+0YDQvdC1INC90LAg0YPRgNC+0LLQvdC1IDEwJSDQvtGC0LLQtdGA0LPQsNC10YLRgdGPIChBREYpLCDQvdC+INC90LUgNSUuINCd0LXQvtCx0YXQvtC00LjQvNC+INC/0YDQstC+0LXRgdGC0Lgg0YLQtWNuIEtQU1MNCtCT0LjQv9C+0YLQtdC30LAg0L4g0YHRgtCw0YbQuNC+0L3QsNGA0L3QvtGB0YLQuCDRgNGP0LTQsCDQvtGC0LLQtdGA0LPQsNC10YLRgdGPIChLUFNTKS4g0KDRj9C0INC90LXRgdGC0LDRhtC40L7QvdCw0YDQtdC9DQoNCiMj0J/RgNC+0LLQtdC00LXQvCDRgtC10YHRgiDQvdCwINC10LTQuNGH0L3Ri9C1INC60L7RgNC90Lgg0LTQu9GPIGtleV9yYXRlDQoNCmBgYHtyfQ0Ka2V5X3JhdGVfYWRmID0gdXIuZGYoa2V5X3JhdGUsIHR5cGUgPSAnbm9uZScsIHNlbGVjdGxhZ3MgPSAnQUlDJykNCnN1bW1hcnkoa2V5X3JhdGVfYWRmKQ0KYGBgDQpgYGB7cn0NCmtleV9yYXRlX2twc3MgPC0gdXIua3BzcyhrZXlfcmF0ZSwgdHlwZT0ibXUiLCBsYWdzPSJzaG9ydCIpDQpzdW1tYXJ5KGtleV9yYXRlX2twc3MpDQpgYGANCtCg0Y/QtCDRgtC+0YfQvdC+INC90LXRgdGC0LDRhtC40L7QvdCw0YDQvdGL0LkNCg0KIyPQn9GA0L7QstC10LTQtdC8INGC0LXRgdGCINC90LAg0LXQtNC40YfQvdGL0LUg0LrQvtGA0L3QuCDQtNC70Y8gQmFsYW5jZV9CdWRnZXQNCg0KYXV0b3Bsb3QoYmFsYW5jZV9idWRnZXQpDQoNCmBgYHtyfQ0KYnVkZ2V0X2FkZiA9IHVyLmRmKGJhbGFuY2VfYnVkZ2V0LCB0eXBlID0gJ25vbmUnLCBzZWxlY3RsYWdzID0gJ0FJQycpDQpzdW1tYXJ5KGJ1ZGdldF9hZGYpDQpgYGANCmBgYHtyfQ0KYnVkZ2V0X2twc3MgPC0gdXIua3BzcyhiYWxhbmNlX2J1ZGdldCwgdHlwZT0ibXUiLCBsYWdzPSJzaG9ydCIpDQpzdW1tYXJ5KGJ1ZGdldF9rcHNzKQ0KYGBgDQrQoNGP0LQg0YHRgtCw0YbQuNC+0L3QsNGA0LXQvSDQv9C+INGA0LXQt9GD0LvRjNGC0LDRgtCw0Lwg0L7QsdC+0LjRhSDRgtC10YHRgtC+0LIuDQoNCmBgYHtyfQ0KIyDQoNCw0LfQsdC40LLQsNC10Lwg0L7QsdC70LDRgdGC0Ywg0L3QsCAyw5cyDQpwYXIobWZyb3cgPSBjKDIsIDIpLCAgDQogICAgbWFyICAgPSBjKDQsIDQsIDIsIDEpKSAgDQojIDEt0Lkg0LPRgNCw0YTQuNC6DQpwbG90KGdkcCwNCiAgICAgbWFpbiA9ICLQktCS0J8gU0EiLA0KICAgICB4bGFiID0gIiIsIHlsYWIgPSAi0LzQu9C9LiDRgNGD0LEuIikNCg0KIyAyLdC5DQpwbG90KGluZmwsDQogICAgIG1haW4gPSAi0JjQn9CmIFNBIiwNCiAgICAgeGxhYiA9ICIiLCB5bGFiID0gIiUiKQ0KDQojIDMt0LkNCnBsb3QoYmFsYW5jZV9idWRnZXQsDQogICAgIG1haW4gPSAi0KHQsNC70YzQtNC+INCx0Y7QtNC20LXRgtCwINC6INCS0JLQnyIsDQogICAgIHhsYWIgPSAi0JLRgNC10LzRjyIsIHlsYWIgPSAiJSIpDQoNCiMgNC3QuQ0KcGxvdChrZXlfcmF0ZSwNCiAgICAgbWFpbiA9ICLQmtC70Y7Rh9C10LLQsNGPINGB0YLQsNCy0LrQsCDQptCRINCg0KQiLA0KICAgICB4bGFiID0gItCS0YDQtdC80Y8iLCB5bGFiID0gIiUiKQ0KDQojINCS0LXRgNC90YPRgtGMINC90LDRgdGC0YDQvtC50LrQuCDQv9C+INGD0LzQvtC70YfQsNC90LjRjiAo0L7Qv9GG0LjQvtC90LDQu9GM0L3QvikNCnBhcihtZnJvdyA9IGMoMSwxKSkNCmBgYA0KDQoNCg0KDQoNCg==