library(tidyverse)
library(scales)
library(FinCal)
library(kableExtra)

theme_set(theme_bw())

Входни данни

Разглеждаме проект със следните технико-икономически показатели


# Параметри проект

Inv <- 1000000 # в лева
Rep_Period <- 48 # в месеци
Savings <- Inv/Rep_Period # в лева

EPC_time <- 6 # в месеци
  • Размер на инвестицията: 1 000 000 лв.

  • Срок на изплащане: 48 месеца

  • Икономия: 20 833 лв.

  • Срок на изпълнение: 6 месеца

Разглеждаме изпълнение на проекта, използвайки ЕСКО механизъм, при следните допускания

  • Срок на договора = Срок на изплащане

  • Срокът на изпълнение стартира веднага, без паразитни изчаквания на административни срокове и процедури

  • Управлението и изпълнението на проекта се поемат изцяло от ЕСКО компанията

  • Икономията е с гарантиран резултат - 100%

Разглеждаме изпълнение на проекта, използвайки грантова програма, при следните допускания


# Параметри ГРАНТ

Intensity <- 0.5 # интензитет на помощта в проценти
Intensity_amount <- Intensity * Inv # интензитет на помощта в лева
        
SelfPart <- Inv - Intensity * Inv # самоучастие в лева

AppForm_rate <- 0.01 # разработка на КП в проценти
AppForm_amount <- AppForm_rate * Inv # разработка на КП в лева

ProjMngmnt_rate <- 0.03 # управление на проекта в проценти
ProjMngmnt_amount <- ProjMngmnt_rate * Inv # упралвние на проекта в лева

Sanction_rate <- 0.05 # санкция в проценти
Sanction <- Sanction_rate * Intensity_amount # санкция в лева

Losts_rate <- 0.06 # загуби от икономии в проценти
Losts <- Losts_rate * Savings # загуби от икономии в лева на месец

# Параметри кредит самоучастие

credit_int_rate <- 0.05/12 # в проценти на месец
credit_period <- 60 # в месеци
credit_payment <- pmt(r = credit_int_rate, 
                      n = credit_period, 
                      pv = SelfPart, 
                      fv = 0)

# Време на бездействие

t_toOpening <- 6 # в месеци
t_toClosing <- 3 # в месеци
t_toRanking <- 3 # в месеци
t_toSigning <- 2 # в месеци
t_toAdminOverhead <- 2 # в месеци

t_Total <- 
        t_toOpening +
        t_toClosing +
        t_toRanking +
        t_toSigning +
        t_toAdminOverhead

# Дисконтов процент

disc_rate <- 0.05/12 # в проценти на месец
  • Интензитет на помощта: 50%

  • Разход за разработка на кандидатски проект (КП), в % от размера на инвестицията: 1%

  • Разход за управление на проекта, в % от размера на инвестицията: 3%

  • Наложени санкции за административни и други пропуски, в % от размера на грантовия компонент: 5%

  • Загуби в икономии поради липса на гарантиран резултат, в % от пълния възможен размер: 6%

  • Използване на кредит за обезпечаване на самоучастието при срок 60 месеца и годишен лихвен процент 5.00%

  • Времето на бездействие от 16 месеца се формира от:
    + отваряне на грантовата програма: 6;
    + за прием на проектни предложения: 3;
    + за оценяване на проектни предложения: 3;
    + за получаване на покана за подписване на договор 2;
    + за допълнителни забавяния във връзка с иксания на документи, корекции и други: 2

Сравнителен Паричен поток - Таблица


n_periods_ESCO <- EPC_time + Rep_Period
n_periods_GRANT <- t_Total + EPC_time + credit_period
n_periods <- if_else(n_periods_GRANT > n_periods_ESCO, n_periods_GRANT, n_periods_ESCO)

tbl_CashFlow <- tibble(
        Month = 1:n_periods,
        
        Payment_AppForm_GRANT = if_else(Month == t_toOpening + 1, -AppForm_amount, 0),
        Payment_ProjMngmnt_GRANT = if_else(Month > t_Total & Month <= t_Total + EPC_time, 
                                     -ProjMngmnt_amount/EPC_time, 
                                     0),
        #Payment_Utility_GRANT = if_else(Month <= t_Total + EPC_time, -Savings, 0),
        Payment_Sanction_GRANT = if_else(Month == t_Total + EPC_time, -Sanction, 0),
        Payment_Credit_GRANT = if_else(Month > t_Total + EPC_time & Month <= t_Total + EPC_time + credit_period,
                                        credit_payment,
                                        0),
        Losts_GRANT = if_else(Month > t_Total + EPC_time, -Losts, 0),
        Saving_GRANT = if_else(Month > t_Total + EPC_time, Savings, 0),
        Net_GRANT = Payment_AppForm_GRANT + 
                Payment_ProjMngmnt_GRANT + 
                #Payment_Utility_GRANT +
                Payment_Sanction_GRANT +
                Payment_Credit_GRANT +
                Losts_GRANT +
                Saving_GRANT,
                
                
        
        Payment_ESCO = if_else(Month <= EPC_time | Month > n_periods_ESCO, 0, -Savings),
        #Payment_Utility_ESCO = if_else(Month <= EPC_time, -Savings, 0),
        Saving_ESCO = if_else(Month <= EPC_time, 0, Savings),
        Net_ESCO = Saving_ESCO + Payment_ESCO #+ Payment_Utility_ESCO
)
                
tbl_CashFlow

Паричен поток ЕСКО

Таблица

tbl_CashFlow_ESCO <-
        tbl_CashFlow %>%
        select(Month, Payment_ESCO, Saving_ESCO, Net_ESCO) #Payment_Utility_ESCO#,  

tbl_CashFlow_ESCO

Графика


tbl_CashFlow_ESCO %>%
        select(-Net_ESCO) %>%
        gather("Payment_ESCO", "Saving_ESCO",  # "Payment_Utility_ESCO"
               key = "CashFlow_Type", 
               value = "Amount" ) %>%
        
        ggplot() +
        geom_col(mapping = aes(x = Month, y = Amount, fill = CashFlow_Type)) +
        geom_hline(aes(yintercept = 0)) +
        scale_y_continuous(labels=function(x) format(x, big.mark = " ", scientific = FALSE) %>% str_c("лв.", sep = " ")) +
        scale_fill_manual(values=c("Red", "Green"),
                          name = "Вид Приход/Разход",
                          labels = c("Плащане към ЕСКО", "Икономии")
                          ) +
        ylab("Парични потоци - ЕСКО") +
        xlab("Месец")

Паричен поток ГРАНТ

Таблица

tbl_CashFlow_GRANT <-
        tbl_CashFlow %>%
        select(Month, 
               Payment_AppForm_GRANT, 
               Payment_ProjMngmnt_GRANT, 
              #Payment_Utility_GRANT,
               Payment_Sanction_GRANT,
               Payment_Credit_GRANT,
               Losts_GRANT,
               Saving_GRANT,
               Net_GRANT)

tbl_CashFlow_GRANT

Графика

tbl_CashFlow_GRANT %>%
        select(-Net_GRANT) %>%
        
        gather("Payment_AppForm_GRANT", 
               #"Payment_Utility_GRANT", 
               "Payment_Sanction_GRANT", 
               "Payment_ProjMngmnt_GRANT", 
               "Payment_Credit_GRANT",
               "Losts_GRANT",
               "Saving_GRANT",
               key = "CashFlow_Type", 
               value = "Amount" ) %>%
        #filter(CashFlow_Type != "Net_ESCO") %>%
        ggplot() +
        geom_col(mapping = aes(x = Month, y = Amount, fill = CashFlow_Type)) +
        geom_hline(aes(yintercept = 0)) +
        scale_y_continuous(labels=function(x) format(x, big.mark = " ", scientific = FALSE) %>% str_c("лв.", sep = " ")) +
        scale_fill_manual(values=c("Red", "Blue", "Orange", "Brown", "Yellow", "Green"),
                          name = "Вид Приход/Разход",
                          labels = c("Загуби", "Кандидатски проект", "Кредит", "Упралвние на проекта", "Санкции", "Икономии")) +
        
        #scale_color_manual(values=c("Red", "Blue", "Orange", "Yellow", "Brown", "Green")) +
        ylab("Парични потоци - ГРАНТ") +
        xlab("Месец")

Сравнение ЕСКО и ГРАНТ - NPV

tibble(
        `Механзъм` = c("ESCO", "GRANT"),
        NPV = c(
                npv(r = disc_rate, cf = tbl_CashFlow_ESCO %>% select(Net_ESCO) %>% pull()) %>%
                        round () %>%
                        format(big.mark = " ") %>%
                        str_c("лв.", sep = " "),
                npv(r = disc_rate, cf = tbl_CashFlow_GRANT %>% select(Net_GRANT) %>% pull()) %>%
                        round () %>%
                        format(big.mark = " ") %>%
                        str_c("лв.", sep = " ")
        )
) %>%
        kable() %>%
        kable_styling(full_width = F) %>%
        row_spec(0, bold = T) %>%
        row_spec(1, bold = T, color = "white", background = "Green") %>%
        row_spec(2, bold = T, color = "white", background = "Red")
Механзъм NPV
ESCO 440 829 лв.
GRANT 432 329 лв.

Калкулатор за изследване на други сценарии

https://kirilr.shinyapps.io/ESCO-vs-GRANT/

ESCO-vs-GRANT

ESCO-vs-GRANT

LS0tDQp0aXRsZTogItCm0LXQvdCw0YLQsCDQvdCwINCx0LXQt9C00LXQudGB0YLQstC40LXRgtC+ICAtINCV0KHQmtCeINC40LvQuCDQk9Cg0JDQndCiPyINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6IA0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KLS0tDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShGaW5DYWwpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQoNCnRoZW1lX3NldCh0aGVtZV9idygpKQ0KYGBgDQoNCg0KIyMg0JLRhdC+0LTQvdC4INC00LDQvdC90LgNCg0KIyMjINCg0LDQt9Cz0LvQtdC20LTQsNC80LUg0L/RgNC+0LXQutGCINGB0YrRgSDRgdC70LXQtNC90LjRgtC1INGC0LXRhdC90LjQutC+LdC40LrQvtC90L7QvNC40YfQtdGB0LrQuCDQv9C+0LrQsNC30LDRgtC10LvQuA0KDQpgYGB7cn0NCg0KIyDQn9Cw0YDQsNC80LXRgtGA0Lgg0L/RgNC+0LXQutGCDQoNCkludiA8LSAxMDAwMDAwICMg0LIg0LvQtdCy0LANClJlcF9QZXJpb2QgPC0gNDggIyDQsiDQvNC10YHQtdGG0LgNClNhdmluZ3MgPC0gSW52L1JlcF9QZXJpb2QgIyDQsiDQu9C10LLQsA0KDQpFUENfdGltZSA8LSA2ICMg0LIg0LzQtdGB0LXRhtC4DQoNCmBgYA0KDQoqINCg0LDQt9C80LXRgCDQvdCwINC40L3QstC10YHRgtC40YbQuNGP0YLQsDogKipgciBmb3JtYXQoSW52LCBiaWcubWFyayA9ICIgIiwgc2NpZW50aWZpYyA9IEYpICU+JSBzdHJfYygi0LvQsi4iLCBzZXAgPSAiICIpYCoqDQoNCiog0KHRgNC+0Log0L3QsCDQuNC30L/Qu9Cw0YnQsNC90LU6ICAqKmByIGZvcm1hdChSZXBfUGVyaW9kLCBiaWcubWFyayA9ICIgIiwgc2NpZW50aWZpYyA9IEYpICU+JSBzdHJfYygi0LzQtdGB0LXRhtCwIiwgc2VwID0gIiAiKWAqKg0KDQoqINCY0LrQvtC90L7QvNC40Y86ICoqYHIgU2F2aW5ncyAlPiUgcm91bmQoKSAlPiUgZm9ybWF0KFNhdmluZ3MsIGJpZy5tYXJrID0gIiAiLCBzY2llbnRpZmljID0gRikgJT4lIHN0cl9jKCLQu9CyLiIsIHNlcCA9ICIgIilgKioNCg0KKiDQodGA0L7QuiDQvdCwINC40LfQv9GK0LvQvdC10L3QuNC1OiAqKmByIGZvcm1hdChFUENfdGltZSwgYmlnLm1hcmsgPSAiICIsIHNjaWVudGlmaWMgPSBGKSAlPiUgc3RyX2MoItC80LXRgdC10YbQsCIsIHNlcCA9ICIgIilgKioNCg0KIyMjINCg0LDQt9Cz0LvQtdC20LTQsNC80LUg0LjQt9C/0YrQu9C90LXQvdC40LUg0L3QsCDQv9GA0L7QtdC60YLQsCwg0LjQt9C/0L7Qu9C30LLQsNC50LrQuCDQldCh0JrQniDQvNC10YXQsNC90LjQt9GK0LwsINC/0YDQuCDRgdC70LXQtNC90LjRgtC1INC00L7Qv9GD0YHQutCw0L3QuNGPDQoNCiog0KHRgNC+0Log0L3QsCDQtNC+0LPQvtCy0L7RgNCwID0g0KHRgNC+0Log0L3QsCDQuNC30L/Qu9Cw0YnQsNC90LUNCg0KKiDQodGA0L7QutGK0YIg0L3QsCDQuNC30L/RitC70L3QtdC90LjQtSDRgdGC0LDRgNGC0LjRgNCwICoq0LLQtdC00L3QsNCz0LAqKiwg0LHQtdC3INC/0LDRgNCw0LfQuNGC0L3QuCDQuNC30YfQsNC60LLQsNC90LjRjyDQvdCwINCw0LTQvNC40L3QuNGB0YLRgNCw0YLQuNCy0L3QuCDRgdGA0L7QutC+0LLQtSDQuCDQv9GA0L7RhtC10LTRg9GA0LgNCg0KKiDQo9C/0YDQsNCy0LvQtdC90LjQtdGC0L4g0Lgg0LjQt9C/0YrQu9C90LXQvdC40LXRgtC+INC90LAg0L/RgNC+0LXQutGC0LAg0YHQtSDQv9C+0LXQvNCw0YIg0LjQt9GG0Y/Qu9C+INC+0YIg0JXQodCa0J4g0LrQvtC80L/QsNC90LjRj9GC0LANCg0KKiDQmNC60L7QvdC+0LzQuNGP0YLQsCDQtSDRgSDQs9Cw0YDQsNC90YLQuNGA0LDQvSDRgNC10LfRg9C70YLQsNGCIC0gKioxMDAlKioNCg0KDQojIyMg0KDQsNC30LPQu9C10LbQtNCw0LzQtSDQuNC30L/RitC70L3QtdC90LjQtSDQvdCwINC/0YDQvtC10LrRgtCwLCDQuNC30L/QvtC70LfQstCw0LnQutC4INCz0YDQsNC90YLQvtCy0LAg0L/RgNC+0LPRgNCw0LzQsCwg0L/RgNC4INGB0LvQtdC00L3QuNGC0LUg0LTQvtC/0YPRgdC60LDQvdC40Y8NCg0KYGBge3J9DQoNCiMg0J/QsNGA0LDQvNC10YLRgNC4INCT0KDQkNCd0KINCg0KSW50ZW5zaXR5IDwtIDAuNSAjINC40L3RgtC10L3Qt9C40YLQtdGCINC90LAg0L/QvtC80L7RidGC0LAg0LIg0L/RgNC+0YbQtdC90YLQuA0KSW50ZW5zaXR5X2Ftb3VudCA8LSBJbnRlbnNpdHkgKiBJbnYgIyDQuNC90YLQtdC90LfQuNGC0LXRgiDQvdCwINC/0L7QvNC+0YnRgtCwINCyINC70LXQstCwDQogICAgICAgIA0KU2VsZlBhcnQgPC0gSW52IC0gSW50ZW5zaXR5ICogSW52ICMg0YHQsNC80L7Rg9GH0LDRgdGC0LjQtSDQsiDQu9C10LLQsA0KDQpBcHBGb3JtX3JhdGUgPC0gMC4wMSAjINGA0LDQt9GA0LDQsdC+0YLQutCwINC90LAg0JrQnyDQsiDQv9GA0L7RhtC10L3RgtC4DQpBcHBGb3JtX2Ftb3VudCA8LSBBcHBGb3JtX3JhdGUgKiBJbnYgIyDRgNCw0LfRgNCw0LHQvtGC0LrQsCDQvdCwINCa0J8g0LIg0LvQtdCy0LANCg0KUHJvak1uZ21udF9yYXRlIDwtIDAuMDMgIyDRg9C/0YDQsNCy0LvQtdC90LjQtSDQvdCwINC/0YDQvtC10LrRgtCwINCyINC/0YDQvtGG0LXQvdGC0LgNClByb2pNbmdtbnRfYW1vdW50IDwtIFByb2pNbmdtbnRfcmF0ZSAqIEludiAjINGD0L/RgNCw0LvQstC90LjQtSDQvdCwINC/0YDQvtC10LrRgtCwINCyINC70LXQstCwDQoNClNhbmN0aW9uX3JhdGUgPC0gMC4wNSAjINGB0LDQvdC60YbQuNGPINCyINC/0YDQvtGG0LXQvdGC0LgNClNhbmN0aW9uIDwtIFNhbmN0aW9uX3JhdGUgKiBJbnRlbnNpdHlfYW1vdW50ICMg0YHQsNC90LrRhtC40Y8g0LIg0LvQtdCy0LANCg0KTG9zdHNfcmF0ZSA8LSAwLjA2ICMg0LfQsNCz0YPQsdC4INC+0YIg0LjQutC+0L3QvtC80LjQuCDQsiDQv9GA0L7RhtC10L3RgtC4DQpMb3N0cyA8LSBMb3N0c19yYXRlICogU2F2aW5ncyAjINC30LDQs9GD0LHQuCDQvtGCINC40LrQvtC90L7QvNC40Lgg0LIg0LvQtdCy0LAg0L3QsCDQvNC10YHQtdGGDQoNCiMg0J/QsNGA0LDQvNC10YLRgNC4INC60YDQtdC00LjRgiDRgdCw0LzQvtGD0YfQsNGB0YLQuNC1DQoNCmNyZWRpdF9pbnRfcmF0ZSA8LSAwLjA1LzEyICMg0LIg0L/RgNC+0YbQtdC90YLQuCDQvdCwINC80LXRgdC10YYNCmNyZWRpdF9wZXJpb2QgPC0gNjAgIyDQsiDQvNC10YHQtdGG0LgNCmNyZWRpdF9wYXltZW50IDwtIHBtdChyID0gY3JlZGl0X2ludF9yYXRlLCANCiAgICAgICAgICAgICAgICAgICAgICBuID0gY3JlZGl0X3BlcmlvZCwgDQogICAgICAgICAgICAgICAgICAgICAgcHYgPSBTZWxmUGFydCwgDQogICAgICAgICAgICAgICAgICAgICAgZnYgPSAwKQ0KDQojINCS0YDQtdC80LUg0L3QsCDQsdC10LfQtNC10LnRgdGC0LLQuNC1DQoNCnRfdG9PcGVuaW5nIDwtIDYgIyDQsiDQvNC10YHQtdGG0LgNCnRfdG9DbG9zaW5nIDwtIDMgIyDQsiDQvNC10YHQtdGG0LgNCnRfdG9SYW5raW5nIDwtIDMgIyDQsiDQvNC10YHQtdGG0LgNCnRfdG9TaWduaW5nIDwtIDIgIyDQsiDQvNC10YHQtdGG0LgNCnRfdG9BZG1pbk92ZXJoZWFkIDwtIDIgIyDQsiDQvNC10YHQtdGG0LgNCg0KdF9Ub3RhbCA8LSANCiAgICAgICAgdF90b09wZW5pbmcgKw0KICAgICAgICB0X3RvQ2xvc2luZyArDQogICAgICAgIHRfdG9SYW5raW5nICsNCiAgICAgICAgdF90b1NpZ25pbmcgKw0KICAgICAgICB0X3RvQWRtaW5PdmVyaGVhZA0KDQojINCU0LjRgdC60L7QvdGC0L7QsiDQv9GA0L7RhtC10L3Rgg0KDQpkaXNjX3JhdGUgPC0gMC4wNS8xMiAjINCyINC/0YDQvtGG0LXQvdGC0Lgg0L3QsCDQvNC10YHQtdGGDQoNCmBgYA0KDQoqINCY0L3RgtC10L3Qt9C40YLQtdGCINC90LAg0L/QvtC80L7RidGC0LA6ICoqYHIgcGVyY2VudChJbnRlbnNpdHksIGFjY3VyYWN5ID0gMSlgKioNCg0KKiDQoNCw0LfRhdC+0LQg0LfQsCDRgNCw0LfRgNCw0LHQvtGC0LrQsCDQvdCwINC60LDQvdC00LjQtNCw0YLRgdC60Lgg0L/RgNC+0LXQutGCICjQmtCfKSwg0LIgJSDQvtGCINGA0LDQt9C80LXRgNCwINC90LAg0LjQvdCy0LXRgdGC0LjRhtC40Y/RgtCwOiAqKmByIHBlcmNlbnQoQXBwRm9ybV9yYXRlLCBhY2N1cmFjeSA9IDEpYCoqIA0KDQoqINCg0LDQt9GF0L7QtCDQt9CwINGD0L/RgNCw0LLQu9C10L3QuNC1INC90LAg0L/RgNC+0LXQutGC0LAsINCyICUg0L7RgiDRgNCw0LfQvNC10YDQsCDQvdCwINC40L3QstC10YHRgtC40YbQuNGP0YLQsDogKipgciBwZXJjZW50KFByb2pNbmdtbnRfcmF0ZSwgYWNjdXJhY3kgPSAxKWAqKiANCg0KKiDQndCw0LvQvtC20LXQvdC4INGB0LDQvdC60YbQuNC4INC30LAg0LDQtNC80LjQvdC40YHRgtGA0LDRgtC40LLQvdC4INC4INC00YDRg9Cz0Lgg0L/RgNC+0L/Rg9GB0LrQuCwg0LIgJSDQvtGCINGA0LDQt9C80LXRgNCwINC90LAg0LPRgNCw0L3RgtC+0LLQuNGPINC60L7QvNC/0L7QvdC10L3RgjogKipgciBwZXJjZW50KFNhbmN0aW9uX3JhdGUsIGFjY3VyYWN5ID0gMSlgKiogDQoNCiog0JfQsNCz0YPQsdC4INCyINC40LrQvtC90L7QvNC40Lgg0L/QvtGA0LDQtNC4INC70LjQv9GB0LAg0L3QsCDQs9Cw0YDQsNC90YLQuNGA0LDQvSDRgNC10LfRg9C70YLQsNGCLCDQsiAlINC+0YIg0L/RitC70L3QuNGPINCy0YrQt9C80L7QttC10L0g0YDQsNC30LzQtdGAOiAqKmByIHBlcmNlbnQoTG9zdHNfcmF0ZSwgYWNjdXJhY3kgPSAxKWAqKiANCg0KKiDQmNC30L/QvtC70LfQstCw0L3QtSDQvdCwINC60YDQtdC00LjRgiDQt9CwINC+0LHQtdC30L/QtdGH0LDQstCw0L3QtSDQvdCwINGB0LDQvNC+0YPRh9Cw0YHRgtC40LXRgtC+INC/0YDQuCDRgdGA0L7QuiAqKmByIGNyZWRpdF9wZXJpb2RgINC80LXRgdC10YbQsCoqINC4INCz0L7QtNC40YjQtdC9INC70LjRhdCy0LXQvSDQv9GA0L7RhtC10L3RgiAqKmByIHBlcmNlbnQoY3JlZGl0X2ludF9yYXRlICogMTIpYCoqDQoNCiog0JLRgNC10LzQtdGC0L4g0L3QsCDQsdC10LfQtNC10LnRgdGC0LLQuNC1INC+0YIgKipgciB0X1RvdGFsYCDQvNC10YHQtdGG0LAqKiDRgdC1INGE0L7RgNC80LjRgNCwINC+0YI6ICANCiAgICAgICAgKyDQvtGC0LLQsNGA0Y/QvdC1INC90LAg0LPRgNCw0L3RgtC+0LLQsNGC0LAg0L/RgNC+0LPRgNCw0LzQsDogKipgciB0X3RvT3BlbmluZ2AqKjsgIA0KICAgICAgICArINC30LAg0L/RgNC40LXQvCDQvdCwINC/0YDQvtC10LrRgtC90Lgg0L/RgNC10LTQu9C+0LbQtdC90LjRjzogKipgciB0X3RvQ2xvc2luZ2AqKjsgICANCiAgICAgICAgKyDQt9CwINC+0YbQtdC90Y/QstCw0L3QtSDQvdCwINC/0YDQvtC10LrRgtC90Lgg0L/RgNC10LTQu9C+0LbQtdC90LjRjzogKipgciB0X3RvUmFua2luZ2AqKjsgICANCiAgICAgICAgKyDQt9CwINC/0L7Qu9GD0YfQsNCy0LDQvdC1INC90LAg0L/QvtC60LDQvdCwINC30LAg0L/QvtC00L/QuNGB0LLQsNC90LUg0L3QsCDQtNC+0LPQvtCy0L7RgCAgKipgciB0X3RvU2lnbmluZ2AqKjsgICANCiAgICAgICAgKyDQt9CwINC00L7Qv9GK0LvQvdC40YLQtdC70L3QuCDQt9Cw0LHQsNCy0Y/QvdC40Y8g0LLRitCyINCy0YDRitC30LrQsCDRgSDQuNC60YHQsNC90LjRjyDQvdCwINC00L7QutGD0LzQtdC90YLQuCwg0LrQvtGA0LXQutGG0LjQuCDQuCDQtNGA0YPQs9C4OiAqKmByIHRfdG9BZG1pbk92ZXJoZWFkYCoqDQoNCg0KIyMg0KHRgNCw0LLQvdC40YLQtdC70LXQvSDQn9Cw0YDQuNGH0LXQvSDQv9C+0YLQvtC6IC0g0KLQsNCx0LvQuNGG0LANCg0KDQpgYGB7cn0NCg0Kbl9wZXJpb2RzX0VTQ08gPC0gRVBDX3RpbWUgKyBSZXBfUGVyaW9kDQpuX3BlcmlvZHNfR1JBTlQgPC0gdF9Ub3RhbCArIEVQQ190aW1lICsgY3JlZGl0X3BlcmlvZA0Kbl9wZXJpb2RzIDwtIGlmX2Vsc2Uobl9wZXJpb2RzX0dSQU5UID4gbl9wZXJpb2RzX0VTQ08sIG5fcGVyaW9kc19HUkFOVCwgbl9wZXJpb2RzX0VTQ08pDQoNCnRibF9DYXNoRmxvdyA8LSB0aWJibGUoDQogICAgICAgIE1vbnRoID0gMTpuX3BlcmlvZHMsDQogICAgICAgIA0KICAgICAgICBQYXltZW50X0FwcEZvcm1fR1JBTlQgPSBpZl9lbHNlKE1vbnRoID09IHRfdG9PcGVuaW5nICsgMSwgLUFwcEZvcm1fYW1vdW50LCAwKSwNCiAgICAgICAgUGF5bWVudF9Qcm9qTW5nbW50X0dSQU5UID0gaWZfZWxzZShNb250aCA+IHRfVG90YWwgJiBNb250aCA8PSB0X1RvdGFsICsgRVBDX3RpbWUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1Qcm9qTW5nbW50X2Ftb3VudC9FUENfdGltZSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCksDQogICAgICAgICNQYXltZW50X1V0aWxpdHlfR1JBTlQgPSBpZl9lbHNlKE1vbnRoIDw9IHRfVG90YWwgKyBFUENfdGltZSwgLVNhdmluZ3MsIDApLA0KICAgICAgICBQYXltZW50X1NhbmN0aW9uX0dSQU5UID0gaWZfZWxzZShNb250aCA9PSB0X1RvdGFsICsgRVBDX3RpbWUsIC1TYW5jdGlvbiwgMCksDQogICAgICAgIFBheW1lbnRfQ3JlZGl0X0dSQU5UID0gaWZfZWxzZShNb250aCA+IHRfVG90YWwgKyBFUENfdGltZSAmIE1vbnRoIDw9IHRfVG90YWwgKyBFUENfdGltZSArIGNyZWRpdF9wZXJpb2QsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlZGl0X3BheW1lbnQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCksDQogICAgICAgIExvc3RzX0dSQU5UID0gaWZfZWxzZShNb250aCA+IHRfVG90YWwgKyBFUENfdGltZSwgLUxvc3RzLCAwKSwNCiAgICAgICAgU2F2aW5nX0dSQU5UID0gaWZfZWxzZShNb250aCA+IHRfVG90YWwgKyBFUENfdGltZSwgU2F2aW5ncywgMCksDQogICAgICAgIE5ldF9HUkFOVCA9IFBheW1lbnRfQXBwRm9ybV9HUkFOVCArIA0KICAgICAgICAgICAgICAgIFBheW1lbnRfUHJvak1uZ21udF9HUkFOVCArIA0KICAgICAgICAgICAgICAgICNQYXltZW50X1V0aWxpdHlfR1JBTlQgKw0KICAgICAgICAgICAgICAgIFBheW1lbnRfU2FuY3Rpb25fR1JBTlQgKw0KICAgICAgICAgICAgICAgIFBheW1lbnRfQ3JlZGl0X0dSQU5UICsNCiAgICAgICAgICAgICAgICBMb3N0c19HUkFOVCArDQogICAgICAgICAgICAgICAgU2F2aW5nX0dSQU5ULA0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIA0KICAgICAgICANCiAgICAgICAgUGF5bWVudF9FU0NPID0gaWZfZWxzZShNb250aCA8PSBFUENfdGltZSB8IE1vbnRoID4gbl9wZXJpb2RzX0VTQ08sIDAsIC1TYXZpbmdzKSwNCiAgICAgICAgI1BheW1lbnRfVXRpbGl0eV9FU0NPID0gaWZfZWxzZShNb250aCA8PSBFUENfdGltZSwgLVNhdmluZ3MsIDApLA0KICAgICAgICBTYXZpbmdfRVNDTyA9IGlmX2Vsc2UoTW9udGggPD0gRVBDX3RpbWUsIDAsIFNhdmluZ3MpLA0KICAgICAgICBOZXRfRVNDTyA9IFNhdmluZ19FU0NPICsgUGF5bWVudF9FU0NPICMrIFBheW1lbnRfVXRpbGl0eV9FU0NPDQopDQogICAgICAgICAgICAgICAgDQp0YmxfQ2FzaEZsb3cNCmBgYA0KDQoNCiMjINCf0LDRgNC40YfQtdC9INC/0L7RgtC+0Log0JXQodCa0J4NCg0KDQojIyMg0KLQsNCx0LvQuNGG0LANCg0KDQpgYGB7cn0NCnRibF9DYXNoRmxvd19FU0NPIDwtDQogICAgICAgIHRibF9DYXNoRmxvdyAlPiUNCiAgICAgICAgc2VsZWN0KE1vbnRoLCBQYXltZW50X0VTQ08sIFNhdmluZ19FU0NPLCBOZXRfRVNDTykgI1BheW1lbnRfVXRpbGl0eV9FU0NPIywgIA0KDQp0YmxfQ2FzaEZsb3dfRVNDTw0KYGBgDQoNCg0KIyMjINCT0YDQsNGE0LjQutCwDQoNCg0KYGBge3J9DQoNCnRibF9DYXNoRmxvd19FU0NPICU+JQ0KICAgICAgICBzZWxlY3QoLU5ldF9FU0NPKSAlPiUNCiAgICAgICAgZ2F0aGVyKCJQYXltZW50X0VTQ08iLCAiU2F2aW5nX0VTQ08iLCAgIyAiUGF5bWVudF9VdGlsaXR5X0VTQ08iDQogICAgICAgICAgICAgICBrZXkgPSAiQ2FzaEZsb3dfVHlwZSIsIA0KICAgICAgICAgICAgICAgdmFsdWUgPSAiQW1vdW50IiApICU+JQ0KICAgICAgICANCiAgICAgICAgZ2dwbG90KCkgKw0KICAgICAgICBnZW9tX2NvbChtYXBwaW5nID0gYWVzKHggPSBNb250aCwgeSA9IEFtb3VudCwgZmlsbCA9IENhc2hGbG93X1R5cGUpKSArDQogICAgICAgIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSAwKSkgKw0KICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPWZ1bmN0aW9uKHgpIGZvcm1hdCh4LCBiaWcubWFyayA9ICIgIiwgc2NpZW50aWZpYyA9IEZBTFNFKSAlPiUgc3RyX2MoItC70LIuIiwgc2VwID0gIiAiKSkgKw0KICAgICAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiUmVkIiwgIkdyZWVuIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAi0JLQuNC0INCf0YDQuNGF0L7QtC/QoNCw0LfRhdC+0LQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCLQn9C70LDRidCw0L3QtSDQutGK0Lwg0JXQodCa0J4iLCAi0JjQutC+0L3QvtC80LjQuCIpDQogICAgICAgICAgICAgICAgICAgICAgICAgICkgKw0KICAgICAgICB5bGFiKCLQn9Cw0YDQuNGH0L3QuCDQv9C+0YLQvtGG0LggLSDQldCh0JrQniIpICsNCiAgICAgICAgeGxhYigi0JzQtdGB0LXRhiIpDQpgYGANCg0KDQojIyDQn9Cw0YDQuNGH0LXQvSDQv9C+0YLQvtC6INCT0KDQkNCd0KINCg0KDQojIyMg0KLQsNCx0LvQuNGG0LANCg0KDQpgYGB7cn0NCnRibF9DYXNoRmxvd19HUkFOVCA8LQ0KICAgICAgICB0YmxfQ2FzaEZsb3cgJT4lDQogICAgICAgIHNlbGVjdChNb250aCwgDQogICAgICAgICAgICAgICBQYXltZW50X0FwcEZvcm1fR1JBTlQsIA0KICAgICAgICAgICAgICAgUGF5bWVudF9Qcm9qTW5nbW50X0dSQU5ULCANCiAgICAgICAgICAgICAgI1BheW1lbnRfVXRpbGl0eV9HUkFOVCwNCiAgICAgICAgICAgICAgIFBheW1lbnRfU2FuY3Rpb25fR1JBTlQsDQogICAgICAgICAgICAgICBQYXltZW50X0NyZWRpdF9HUkFOVCwNCiAgICAgICAgICAgICAgIExvc3RzX0dSQU5ULA0KICAgICAgICAgICAgICAgU2F2aW5nX0dSQU5ULA0KICAgICAgICAgICAgICAgTmV0X0dSQU5UKQ0KDQp0YmxfQ2FzaEZsb3dfR1JBTlQNCmBgYA0KDQoNCiMjIyDQk9GA0LDRhNC40LrQsA0KDQoNCmBgYHtyfQ0KdGJsX0Nhc2hGbG93X0dSQU5UICU+JQ0KICAgICAgICBzZWxlY3QoLU5ldF9HUkFOVCkgJT4lDQogICAgICAgIA0KICAgICAgICBnYXRoZXIoIlBheW1lbnRfQXBwRm9ybV9HUkFOVCIsIA0KICAgICAgICAgICAgICAgIyJQYXltZW50X1V0aWxpdHlfR1JBTlQiLCANCiAgICAgICAgICAgICAgICJQYXltZW50X1NhbmN0aW9uX0dSQU5UIiwgDQogICAgICAgICAgICAgICAiUGF5bWVudF9Qcm9qTW5nbW50X0dSQU5UIiwgDQogICAgICAgICAgICAgICAiUGF5bWVudF9DcmVkaXRfR1JBTlQiLA0KICAgICAgICAgICAgICAgIkxvc3RzX0dSQU5UIiwNCiAgICAgICAgICAgICAgICJTYXZpbmdfR1JBTlQiLA0KICAgICAgICAgICAgICAga2V5ID0gIkNhc2hGbG93X1R5cGUiLCANCiAgICAgICAgICAgICAgIHZhbHVlID0gIkFtb3VudCIgKSAlPiUNCiAgICAgICAgI2ZpbHRlcihDYXNoRmxvd19UeXBlICE9ICJOZXRfRVNDTyIpICU+JQ0KICAgICAgICBnZ3Bsb3QoKSArDQogICAgICAgIGdlb21fY29sKG1hcHBpbmcgPSBhZXMoeCA9IE1vbnRoLCB5ID0gQW1vdW50LCBmaWxsID0gQ2FzaEZsb3dfVHlwZSkpICsNCiAgICAgICAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDApKSArDQogICAgICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHM9ZnVuY3Rpb24oeCkgZm9ybWF0KHgsIGJpZy5tYXJrID0gIiAiLCBzY2llbnRpZmljID0gRkFMU0UpICU+JSBzdHJfYygi0LvQsi4iLCBzZXAgPSAiICIpKSArDQogICAgICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJSZWQiLCAiQmx1ZSIsICJPcmFuZ2UiLCAiQnJvd24iLCAiWWVsbG93IiwgIkdyZWVuIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAi0JLQuNC0INCf0YDQuNGF0L7QtC/QoNCw0LfRhdC+0LQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCLQl9Cw0LPRg9Cx0LgiLCAi0JrQsNC90LTQuNC00LDRgtGB0LrQuCDQv9GA0L7QtdC60YIiLCAi0JrRgNC10LTQuNGCIiwgItCj0L/RgNCw0LvQstC90LjQtSDQvdCwINC/0YDQvtC10LrRgtCwIiwgItCh0LDQvdC60YbQuNC4IiwgItCY0LrQvtC90L7QvNC40LgiKSkgKw0KICAgICAgICANCiAgICAgICAgI3NjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiUmVkIiwgIkJsdWUiLCAiT3JhbmdlIiwgIlllbGxvdyIsICJCcm93biIsICJHcmVlbiIpKSArDQogICAgICAgIHlsYWIoItCf0LDRgNC40YfQvdC4INC/0L7RgtC+0YbQuCAtINCT0KDQkNCd0KIiKSArDQogICAgICAgIHhsYWIoItCc0LXRgdC10YYiKQ0KYGBgDQoNCg0KIyMg0KHRgNCw0LLQvdC10L3QuNC1INCV0KHQmtCeINC4INCT0KDQkNCd0KIgLSBOUFYNCg0KDQpgYGB7cn0NCnRpYmJsZSgNCiAgICAgICAgYNCc0LXRhdCw0L3Qt9GK0LxgID0gYygiRVNDTyIsICJHUkFOVCIpLA0KICAgICAgICBOUFYgPSBjKA0KICAgICAgICAgICAgICAgIG5wdihyID0gZGlzY19yYXRlLCBjZiA9IHRibF9DYXNoRmxvd19FU0NPICU+JSBzZWxlY3QoTmV0X0VTQ08pICU+JSBwdWxsKCkpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQgKCkgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQoYmlnLm1hcmsgPSAiICIpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgc3RyX2MoItC70LIuIiwgc2VwID0gIiAiKSwNCiAgICAgICAgICAgICAgICBucHYociA9IGRpc2NfcmF0ZSwgY2YgPSB0YmxfQ2FzaEZsb3dfR1JBTlQgJT4lIHNlbGVjdChOZXRfR1JBTlQpICU+JSBwdWxsKCkpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQgKCkgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQoYmlnLm1hcmsgPSAiICIpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgc3RyX2MoItC70LIuIiwgc2VwID0gIiAiKQ0KICAgICAgICApDQopICU+JQ0KICAgICAgICBrYWJsZSgpICU+JQ0KICAgICAgICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGKSAlPiUNCiAgICAgICAgcm93X3NwZWMoMCwgYm9sZCA9IFQpICU+JQ0KICAgICAgICByb3dfc3BlYygxLCBib2xkID0gVCwgY29sb3IgPSAid2hpdGUiLCBiYWNrZ3JvdW5kID0gIkdyZWVuIikgJT4lDQogICAgICAgIHJvd19zcGVjKDIsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSAiUmVkIikNCmBgYA0KDQoNCiMjINCa0LDQu9C60YPQu9Cw0YLQvtGAINC30LAg0LjQt9GB0LvQtdC00LLQsNC90LUg0L3QsCDQtNGA0YPQs9C4INGB0YbQtdC90LDRgNC40LgNCg0KDQpodHRwczovL2tpcmlsci5zaGlueWFwcHMuaW8vRVNDTy12cy1HUkFOVC8NCg0KDQoNCiFbRVNDTy12cy1HUkFOVF0oYXBwX3NjcmVlbl9zaG90LnBuZykNCg0KDQo=