Giới thiệu về phương pháp Monte Carlo

Phương pháp Monte Carlo là một phương pháp tính toán dựa trên việc xây dựng mô hình toán học và sử dụng số ngẫu nhiên để mô phỏng các giá trị đầu vào của mô hình. Kết quả của các phép tính được thực hiện trên các giá trị này được sử dụng để tính toán giá trị đầu ra của vấn đề.

Thị trường chứng khoán trở thành một đề tài được quan tâm bởi tính biến động khó lường.Vì vậy, ứng dụng phương pháp Monte Carlo trong phân tích cổ phiếu đóng vai trò quan trọng giúp đưa ra các dự báo về giá cổ phiếu dựa trên một mô hình toán học chính xác, đồng thời, giúp các nhà đầu tư đưa ra các quyết định đầu tư thông minh hơn. Tuy nhiên, cần lưu ý rằng các dự báo này chỉ là ước tính và không đảm bảo rằng kết quả thực tế sẽ diễn ra theo dự báo.

Mỗi loại mô phỏng Monte Carlo đều có các bước thực hiện sau đây:

Bài toán mô phỏng lợi nhuận cổ phiếu

Một trong những bài toán về cổ phiếu có thể ứng dụng phương pháp Monte Carlo để giải quyết chính là đưa ra các dự báo về lợi nhuận trong tương lai. Ta có thể tạo ra mô hình toán học của giá trị lợi nhuận dựa trên các yếu tố lịch sử theo thời gian của mã cổ phiếu. Mô hình này có thể là một mô hình ngẫu nhiên, trong đó các giá trị của các yếu tố ảnh hưởng được tạo ra bằng cách sử dụng số ngẫu nhiên.

Kết quả của mô phỏng Monte Carlo này sẽ cung cấp cho chúng ta một cái nhìn về khả năng xảy ra lợi nhuận của cổ phiếu trong tương lai, giúp ta đưa ra quyết định đầu tư thông minh hơn. Những câu hỏi phương pháp này có thể trả lời bao gồm:

Thiết lập phương pháp Monte Carlo mô phỏng giá trị lợi nhuận

Trong ứng dụng này, mã cổ phiếu được lựa chọn phân tích từ tệp dữ liệu là mã DVN trong 120 ngày tới. Dữ liệu bao gồm lịch sử các mã cổ phiếu từ 04/01/2021 tới 30/12/2022 và được tải xuống dưới định dạng file csv. Link file dữ liệu: https://bom.so/6FlMwf

#Tải xuống các packages sau
install.packages("tidyquant")
install.packages("quantmod")
install.packages("zoo")

#Sử dụng các thư viện sau
library(tidyquant)
library(quantmod)
library(zoo)

Trước khi bắt đầu phân tích dữ liệu cổ phiếu, ta cần tải xuống các gói thư viện liên quan phục vụ cho quá trình sử dụng sau này.

#Thay đổi thư mục làm việc phù hợp với thư mục đang sử dụng hiện tại
setwd("D:/KPIM/PVI")

#Tải dữ liệu lên R
Stock <- read.csv("StockData.csv", header = TRUE)

#Lọc dữ liệu với mã cổ phiếu mong muốn phân tích
DVN <- Stock[Stock$ma == "DVN",]

#Định dạng ngày của dữ liệu
DVN$ngay <- as.Date(DVN$ngay)

#Chuyển đổi dữ liệu của mã cổ phiếu thành dữ liệu theo chuỗi thời gian và chọn giá đóng cửa làm giá trị phân tích lợi nhuận hàng ngày
DVN_xts <- xts(DVN$gia_dong_cua, start = min(DVN$ngay), end = max(DVN$ngay), order.by = DVN$ngay, frequency = 1)

Để tải dữ liệu vào sử dụng, cần thiết lập thư mục làm việc hiện tại và tất cả tệp dữ liệu cần được lưu trong thư mục này.

#Tính lợi nhuận hàng ngày
daily_returns <- dailyReturn(DVN_xts)

# Tính giá trị trung bình của lợi nhuận hàng ngày
daily_mean <- mean(daily_returns)

# Tính độ lệch chuẩn của lợi nhuận hàng ngày
daily_std_dev <- sd(daily_returns)

Trong mô phỏng này, lợi nhuận thị trường cổ phiếu được giả định là phân phối chuẩn và các thông số được tính toán như lợi nhuận hàng ngày, giá trị trung bình của lợi nhuận hàng ngày, độ lệch chuẩn của lợi nhuận. Các thông số này sẽ được sử dụng để tạo ra các biến ngẫu nhiên trong mô hình.

# Xác định số ngày cần mô phỏng
no_of_days <- 120

# Xác định giá khởi điểm của quá trình mô phỏng
starting_price <- last(DVN$gia_dong_cua)[[1]]

Dữ liệu sẽ được mô phỏng trong 120 ngày tới và giá khởi điểm của ngày đầu tiên trong thời điểm mô phỏng sẽ là giá đóng cửa cuối cùng trong dữ liệu giá lịch sử của mã cổ phiếu.

Lợi nhuận hàng ngày được tạo bằng cách sử dụng phân phối chuẩn với giá trị trung bình và độ lệch chuẩn đã được tính toán trước đó. Để tính giá của cổ phiếu, cần thực hiện tính tích lũy của lợi nhuận và giá khởi điểm. Kết quả dưới đây là biểu đồ thể hiện giá mô phỏng của mã cổ phiếu trong 120 ngày tới.

# Tạo cơ sở số lượng các mẫu ngẫu nhiên sẽ được tạo
set.seed(101)

# Tính giá trị lợi nhuận dựa trên các giá trị ngẫu nhiên
returns <- 1+rnorm(no_of_days, mean=daily_mean, sd=daily_std_dev)

# Tính giá cổ phiếu thông qua tích lũy của giá khởi điểm và lợi nhuận
prices <- cumprod(c(starting_price, returns))

# Vẽ biểu đồ thể hiện mô phỏng của giá cổ phiếu trong tương lai
plot(prices, type='l', ylab="Giá cổ phiếu", xlab="Số ngày", main = "Mô phỏng giá của mã cổ phiếu DVN")

Tuy nhiên, chỉ chạy một mô phỏng sẽ không đủ để đưa ra kết luận. Vì vậy, để đưa ra kết quả sát với thực tế nhất, ta sẽ thực hiện chạy 1001 mô phỏng trong 120 ngày với mỗi mô phỏng. Dữ liệu được lưu trữ hai chiều dưới dạng ma trận và 50 mô phỏng đầu tiên được biểu diễn trong đồ thị dưới đây.

# Số lượng thực hiện vòng lặp mô phỏng
no_of_sims <- 1001

# Danh sách giá trị của lợi nhuận
returns_list <- matrix(0, nrow = no_of_sims, ncol = no_of_days)

# Danh sách giá của cổ phiếu
prices_list <- matrix(0, nrow = no_of_sims, ncol = no_of_days+1) 

# Vòng lặp thực hiện mô phỏng trong số ngày được chỉ định
for(i in 1:no_of_sims) {
  returns_list[i,] <- rnorm(no_of_days, mean=daily_mean, sd=daily_std_dev)
  prices_list[i,] <- cumprod(c(starting_price, 1+returns_list[i,]))
  }

# Biểu diễn dưới dạng đồ thị 50 mô phỏng đầu tiên
plot(prices_list[1,], type='l', ylab="Giá cổ phiếu", xlab="Số ngày", main = "Mô phỏng giá của mã cổ phiếu DVN", ylim=c(10000, 50000))
for(i in 1:50) {
  lines(prices_list[i, ], type = 'l', col=i)
}

Như chúng ta có thể thấy, kết quả của các mô phỏng có sự đa dạng khác nhau. Một số kết thúc dưới điểm bắt đầu và một số tăng rất nhanh. Dựa trên 50 mô phỏng đầu tiên, mã cổ phiếu có xu hướng lợi nhuận âm trong thời gian tới. Để xem xét cụ thể hơn, ta sẽ tính tổng lợi nhuận thu về:

# Tạo mảng đa chiều chứa dữ liệu của lợi nhuận
total_returns <- array(NA, dim= no_of_sims, dimnames=NULL)

# Vòng lặp nhằm tính giá trị của tổng lợi nhuận với mỗi mô phỏng
for (i in 1:no_of_sims) {
  total_returns[i] <- (prices_list[i, 121]-prices_list[i, 1])/prices_list[i,1]
}

# Thống kê kết quả của lợi nhuận thu về
summary(total_returns)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
-0.69017 -0.27815 -0.12232 -0.10020  0.03253  0.96066 

Kết luận cho thấy mô phỏng có xu hướng lợi nhuận âm, hơn 50% kết quả mô phỏng cho ra giá trị < 0 bởi giá trị trung vị, giá trị trung bình và phân vị thứ nhất đều thể hiện điều này. Để trực quan hóa kết quả, ta có thể xem xét 1 số biểu đồ sau:

par(mfrow=c(1,3))
hist(total_returns, col="blue")
boxplot(total_returns, col="yellow")
plot(density(total_returns))

Các giá trị ngoại lai của biểu đồ Boxplot thường thể hiện mặt dương của lợi nhuận và biểu đồ thể hiện sự phân phối lệch phải rõ rệt. Điều này có thể xác nhận dựa trên thông số độ lệch dưới đây:

# Tính độ lệch của dữ liệu lợi nhuận
skewness(total_returns)
[1] 0.7771115

Để hiển thị biểu đồ dễ đọc hơn, sẽ chỉ có ba mô phỏng sẽ được đưa vào: giá trị trung bình, giá trị tối thiểu và giá trị tối đa. Các dữ liệu này được lấy từ phân tích dữ liệu với biểu đồ phía trên. Tiếp tục thực hiện với sự lặp lại của 1001 mô phỏng.

# Tìm vị trí giá trị lớn nhất của lợi nhuận
max <- which.max(total_returns)

# Tìm vị trí giá trị nhỏ nhất của lợi nhuận
min <- which.min(total_returns)

# Tìm vị trí của giá trị trung vị
if (no_of_sims %% 2 != 0) {med <- match(median(total_returns), total_returns)}

# Biểu diễn đồ thị với 3 giá trị trên
plot(prices_list[min,], type='l', ylab="Giá cổ phiếu", xlab="Số ngày", main ="Mô phỏng giá của mã cổ phiếu DVN", ylim=c(9000, 60000), col="red")
if (no_of_sims %% 2 != 0) {lines(prices_list[med, ], type = 'l', col='yellow')}
lines(prices_list[max, ], type = 'l', col='green')

Qua đó, chúng ta có thể dễ dàng nhìn thấy trường hợp giá trị mô phỏng tốt nhất, xấu nhất và trung bình. Để trả lời câu hỏi đầu tiên, dựa trên các biểu đồ và dữ liệu, ta có thể kỳ vọng mức lợi nhuận nằm trong khoảng từ -69.02% đến 96.07%.

# Tính giá trị lợi nhuận có thể đạt được lớn nhất
max_return <- max(total_returns)
max_return
[1] 0.960663
# Tính giá trị lợi nhuận có thể đạt được nhỏ nhất
min_return <- min(total_returns)
min_return
[1] -0.6901731

Để trả lời 2 câu hỏi cuối, ta sẽ thực hiện tính xác suất nhằm đạt được kết quả mong muốn.

# Mức lợi nhuận cần lớn hơn
condition1 <- sum(total_returns > 0.12)

# Mức lợi nhuận cần nhỏ hơn
condition2 <- sum(total_returns < -0.2)

# Xác suất xảy ra các trường hợp
probability1 <- condition1/no_of_sims
probability2 <- condition2/no_of_sims

# Kết quả đạt được
cat("Xác suất để đạt được lợi nhuận tối thiểu 12% là: ", probability1*100, "%", ". Xác suất để lỗ nhiều hơn 20% khoản đầu tư là: ", probability2*100, "%")
Xác suất để đạt được lợi nhuận tối thiểu 12% là:  17.08292 % . Xác suất để lỗ nhiều hơn 20% khoản đầu tư là:  37.66234 %

Kết luận

Phương pháp này đã cung cấp nhiều hiểu biết sâu sắc về thị trường chứng khoán mà rất khó để tính toán theo cách khác. Ví dụ này minh họa rằng Mô phỏng Monte Carlo có thể được ứng dụng thực tiễn bởi các nhà đầu tư, quỹ phòng hộ và các tổ chức tài chính khác vào quá trình ra quyết định của họ.

LS0tDQp0aXRsZTogIk3DtCBwaOG7j25nIGzhu6NpIG5odeG6rW4gY+G7lSBwaGnhur91IHPhu60gZOG7pW5nIHBoxrDGoW5nIHBow6FwIE1vbnRlIENhcmxvIg0KYXV0aG9yOiAiTGFuIFBoYW0iDQpkYXRlOiAiMjAyMy0wNC0xMCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMjIEdp4bubaSB0aGnhu4d1IHbhu4EgcGjGsMahbmcgcGjDoXAgTW9udGUgQ2FybG8NClBoxrDGoW5nIHBow6FwIE1vbnRlIENhcmxvIGzDoCBt4buZdCBwaMawxqFuZyBwaMOhcCB0w61uaCB0b8OhbiBk4buxYSB0csOqbiB2aeG7h2MgeMOieSBk4buxbmcgbcO0IGjDrG5oIHRvw6FuIGjhu41jIHbDoCBz4butIGThu6VuZyBz4buRIG5n4bqrdSBuaGnDqm4gxJHhu4MgbcO0IHBo4buPbmcgY8OhYyBnacOhIHRy4buLIMSR4bqndSB2w6BvIGPhu6dhIG3DtCBow6xuaC4gS+G6v3QgcXXhuqMgY+G7p2EgY8OhYyBwaMOpcCB0w61uaCDEkcaw4bujYyB0aOG7sWMgaGnhu4duIHRyw6puIGPDoWMgZ2nDoSB0cuG7iyBuw6B5IMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHTDrW5oIHRvw6FuIGdpw6EgdHLhu4sgxJHhuqd1IHJhIGPhu6dhIHbhuqVuIMSR4buBLg0KDQpUaOG7iyB0csaw4budbmcgY2jhu6luZyBraG/DoW4gdHLhu58gdGjDoG5oIG3hu5l0IMSR4buBIHTDoGkgxJHGsOG7o2MgcXVhbiB0w6JtIGLhu59pIHTDrW5oIGJp4bq/biDEkeG7mW5nIGtow7MgbMaw4budbmcuVsOsIHbhuq15LCDhu6luZyBk4bulbmcgcGjGsMahbmcgcGjDoXAgTW9udGUgQ2FybG8gdHJvbmcgcGjDom4gdMOtY2ggY+G7lSBwaGnhur91IMSRw7NuZyB2YWkgdHLDsiBxdWFuIHRy4buNbmcgZ2nDunAgxJHGsGEgcmEgY8OhYyBk4buxIGLDoW8gduG7gSBnacOhIGPhu5UgcGhp4bq/dSBk4buxYSB0csOqbiBt4buZdCBtw7QgaMOsbmggdG/DoW4gaOG7jWMgY2jDrW5oIHjDoWMsIMSR4buTbmcgdGjhu51pLCBnacO6cCBjw6FjIG5ow6AgxJHhuqd1IHTGsCDEkcawYSByYSBjw6FjIHF1eeG6v3QgxJHhu4tuaCDEkeG6p3UgdMawIHRow7RuZyBtaW5oIGjGoW4uIFR1eSBuaGnDqm4sIGPhuqduIGzGsHUgw70gcuG6sW5nIGPDoWMgZOG7sSBiw6FvIG7DoHkgY2jhu4kgbMOgIMaw4bubYyB0w61uaCB2w6Aga2jDtG5nIMSR4bqjbSBi4bqjbyBy4bqxbmcga+G6v3QgcXXhuqMgdGjhu7FjIHThur8gc+G6vSBkaeG7hW4gcmEgdGhlbyBk4buxIGLDoW8uDQoNCk3hu5dpIGxv4bqhaSBtw7QgcGjhu49uZyBNb250ZSBDYXJsbyDEkeG7gXUgY8OzIGPDoWMgYsaw4bubYyB0aOG7sWMgaGnhu4duIHNhdSDEkcOieToNCg0KLSBYw6FjIMSR4buLbmggbeG7mXQgdOG6rXAgaOG7o3AgY8OhYyDEkeG6p3UgdsOgbyBjw7MgdGjhu4MgdsOgIHBow6JuIGLhu5EgY+G7p2EgY2jDum5nDQoNCi0gVOG6oW8gcmEgY8OhYyDEkeG6p3UgdsOgbyBuZ+G6q3Ugbmhpw6puIHThu6sgbeG7mXQgcGjDom4gYuG7kSB4w6FjIHN14bqldA0KDQotIFRo4buxYyBoaeG7h24gdMOtbmggdG/DoW4geMOhYyDEkeG7i25oDQoNCi0gUGjDom4gdMOtY2gga+G6v3QgcXXhuqMNCg0KIyMgQsOgaSB0b8OhbiBtw7QgcGjhu49uZyBs4bujaSBuaHXhuq1uIGPhu5UgcGhp4bq/dQ0KTeG7mXQgdHJvbmcgbmjhu69uZyBiw6BpIHRvw6FuIHbhu4EgY+G7lSBwaGnhur91IGPDsyB0aOG7gyDhu6luZyBk4bulbmcgcGjGsMahbmcgcGjDoXAgTW9udGUgQ2FybG8gxJHhu4MgZ2nhuqNpIHF1eeG6v3QgY2jDrW5oIGzDoCDEkcawYSByYSBjw6FjIGThu7EgYsOhbyB24buBIGzhu6NpIG5odeG6rW4gdHJvbmcgdMawxqFuZyBsYWkuIFRhIGPDsyB0aOG7gyB04bqhbyByYSBtw7QgaMOsbmggdG/DoW4gaOG7jWMgY+G7p2EgZ2nDoSB0cuG7iyBs4bujaSBuaHXhuq1uIGThu7FhIHRyw6puIGPDoWMgeeG6v3UgdOG7kSBs4buLY2ggc+G7rSB0aGVvIHRo4budaSBnaWFuIGPhu6dhIG3DoyBj4buVIHBoaeG6v3UuIE3DtCBow6xuaCBuw6B5IGPDsyB0aOG7gyBsw6AgbeG7mXQgbcO0IGjDrG5oIG5n4bqrdSBuaGnDqm4sIHRyb25nIMSRw7MgY8OhYyBnacOhIHRy4buLIGPhu6dhIGPDoWMgeeG6v3UgdOG7kSDhuqNuaCBoxrDhu59uZyDEkcaw4bujYyB04bqhbyByYSBi4bqxbmcgY8OhY2ggc+G7rSBk4bulbmcgc+G7kSBuZ+G6q3Ugbmhpw6puLg0KDQpL4bq/dCBxdeG6oyBj4bunYSBtw7QgcGjhu49uZyBNb250ZSBDYXJsbyBuw6B5IHPhur0gY3VuZyBj4bqlcCBjaG8gY2jDum5nIHRhIG3hu5l0IGPDoWkgbmjDrG4gduG7gSBraOG6oyBuxINuZyB44bqjeSByYSBs4bujaSBuaHXhuq1uIGPhu6dhIGPhu5UgcGhp4bq/dSB0cm9uZyB0xrDGoW5nIGxhaSwgZ2nDunAgdGEgxJHGsGEgcmEgcXV54bq/dCDEkeG7i25oIMSR4bqndSB0xrAgdGjDtG5nIG1pbmggaMahbi4gTmjhu69uZyBjw6J1IGjhu49pIHBoxrDGoW5nIHBow6FwIG7DoHkgY8OzIHRo4buDIHRy4bqjIGzhu51pIGJhbyBn4buTbTogDQoNCi0gTOG7o2kgbmh14bqtbiBr4buzIHbhu41uZyB0csOqbiB0aOG7iyB0csaw4budbmcgY+G7lSBwaGnhur91IHRyb25nIG3hu5l0IGtob+G6o25nIHRo4budaSBnaWFuIHThu5tpPw0KKFbDrSBk4bulOiBM4bujaSBuaHXhuq1uIGvhu7MgduG7jW5nIGPDsyB0aOG7gyDEkeG6oXQgxJHGsOG7o2MgdHJvbmcgdsOybmcgMTIwIG5nw6B5IHThu5tpIGzDoCBiYW8gbmhpw6p1PykNCg0KLSBYw6FjIHN14bqldCBj4bunYSB2aeG7h2MgdOG6oW8gbsOqbiBt4buZdCBnacOhIHRy4buLIGzhu6NpIG5odeG6rW4gbmjhuqV0IMSR4buLbmggdHJvbmcgbeG7mXQga2hv4bqjbmcgdGjhu51pIGdpYW4gdOG7m2k/DQooVsOtIGThu6U6IFjDoWMgc3XhuqV0IGPhu6dhIHZp4buHYyDEkeG6oXQgMTIlIGzhu6NpIG5odeG6rW4gdHJvbmcgMTIwIG5nw6B5IHThu5tpIGzDoCBiYW8gbmhpw6p1PykNCg0KLSBYw6FjIHN14bqldCBj4bunYSB2aeG7h2MgbeG6pXQgbmhp4buBdSBoxqFuIG3hu5l0IGdpw6EgdHLhu4sgxJHhuqd1IHTGsCBuaOG6pXQgxJHhu4tuaCB0cm9uZyBt4buZdCBraG/huqNuZyB0aOG7nWkgZ2lhbiB04bubaT8NCihWw60gZOG7pTogWMOhYyBzdeG6pXQgY+G7p2Egdmnhu4djIGzhu5cgbmhp4buBdSBoxqFuIDIwJSBraG/huqNuIMSR4bqndSB0xrAgdHJvbmcgdsOybmcgMTIwIG5nw6B5IHThu5tpIGzDoCBiYW8gbmhpw6p1PykNCg0KIyMgVGhp4bq/dCBs4bqtcCBwaMawxqFuZyBwaMOhcCBNb250ZSBDYXJsbyBtw7QgcGjhu49uZyBnacOhIHRy4buLIGzhu6NpIG5odeG6rW4NClRyb25nIOG7qW5nIGThu6VuZyBuw6B5LCBtw6MgY+G7lSBwaGnhur91IMSRxrDhu6NjIGzhu7FhIGNo4buNbiBwaMOibiB0w61jaCB04burIHThu4dwIGThu68gbGnhu4d1IGzDoCBtw6MgRFZOIHRyb25nIDEyMCBuZ8OgeSB04bubaS4gROG7ryBsaeG7h3UgYmFvIGfhu5NtIGzhu4tjaCBz4butIGPDoWMgbcOjIGPhu5UgcGhp4bq/dSB04burIDA0LzAxLzIwMjEgdOG7m2kgMzAvMTIvMjAyMiB2w6AgxJHGsOG7o2MgdOG6o2kgeHXhu5FuZyBkxrDhu5tpIMSR4buLbmggZOG6oW5nIGZpbGUgY3N2LiBMaW5rIGZpbGUgZOG7ryBsaeG7h3U6IGh0dHBzOi8vYm9tLnNvLzZGbE13Zg0KDQpgYGB7cn0NCiNU4bqjaSB4deG7kW5nIGPDoWMgcGFja2FnZXMgc2F1DQppbnN0YWxsLnBhY2thZ2VzKCJ0aWR5cXVhbnQiKQ0KaW5zdGFsbC5wYWNrYWdlcygicXVhbnRtb2QiKQ0KaW5zdGFsbC5wYWNrYWdlcygiem9vIikNCg0KI1Phu60gZOG7pW5nIGPDoWMgdGjGsCB2aeG7h24gc2F1DQpsaWJyYXJ5KHRpZHlxdWFudCkNCmxpYnJhcnkocXVhbnRtb2QpDQpsaWJyYXJ5KHpvbykNCmBgYA0KVHLGsOG7m2Mga2hpIGLhuq90IMSR4bqndSBwaMOibiB0w61jaCBk4buvIGxp4buHdSBj4buVIHBoaeG6v3UsIHRhIGPhuqduIHThuqNpIHh14buRbmcgY8OhYyBnw7NpIHRoxrAgdmnhu4duIGxpw6puIHF1YW4gcGjhu6VjIHbhu6UgY2hvIHF1w6EgdHLDrG5oIHPhu60gZOG7pW5nIHNhdSBuw6B5Lg0KDQpgYGB7cn0NCiNUaGF5IMSR4buVaSB0aMawIG3hu6VjIGzDoG0gdmnhu4djIHBow7kgaOG7o3AgduG7m2kgdGjGsCBt4bulYyDEkWFuZyBz4butIGThu6VuZyBoaeG7h24gdOG6oWkNCnNldHdkKCJEOi9LUElNL1BWSSIpDQoNCiNU4bqjaSBk4buvIGxp4buHdSBsw6puIFINClN0b2NrIDwtIHJlYWQuY3N2KCJTdG9ja0RhdGEuY3N2IiwgaGVhZGVyID0gVFJVRSkNCg0KI0zhu41jIGThu68gbGnhu4d1IHbhu5tpIG3DoyBj4buVIHBoaeG6v3UgbW9uZyBtdeG7kW4gcGjDom4gdMOtY2gNCkRWTiA8LSBTdG9ja1tTdG9jayRtYSA9PSAiRFZOIixdDQoNCiPEkOG7i25oIGThuqFuZyBuZ8OgeSBj4bunYSBk4buvIGxp4buHdQ0KRFZOJG5nYXkgPC0gYXMuRGF0ZShEVk4kbmdheSkNCg0KI0NodXnhu4NuIMSR4buVaSBk4buvIGxp4buHdSBj4bunYSBtw6MgY+G7lSBwaGnhur91IHRow6BuaCBk4buvIGxp4buHdSB0aGVvIGNodeG7l2kgdGjhu51pIGdpYW4gdsOgIGNo4buNbiBnacOhIMSRw7NuZyBj4butYSBsw6BtIGdpw6EgdHLhu4sgcGjDom4gdMOtY2ggbOG7o2kgbmh14bqtbiBow6BuZyBuZ8OgeQ0KRFZOX3h0cyA8LSB4dHMoRFZOJGdpYV9kb25nX2N1YSwgc3RhcnQgPSBtaW4oRFZOJG5nYXkpLCBlbmQgPSBtYXgoRFZOJG5nYXkpLCBvcmRlci5ieSA9IERWTiRuZ2F5LCBmcmVxdWVuY3kgPSAxKQ0KYGBgDQrEkOG7gyB04bqjaSBk4buvIGxp4buHdSB2w6BvIHPhu60gZOG7pW5nLCBj4bqnbiB0aGnhur90IGzhuq1wIHRoxrAgbeG7pWMgbMOgbSB2aeG7h2MgaGnhu4duIHThuqFpIHbDoCB04bqldCBj4bqjIHThu4dwIGThu68gbGnhu4d1IGPhuqduIMSRxrDhu6NjIGzGsHUgdHJvbmcgdGjGsCBt4bulYyBuw6B5Lg0KDQpgYGB7cn0NCiNUw61uaCBs4bujaSBuaHXhuq1uIGjDoG5nIG5nw6B5DQpkYWlseV9yZXR1cm5zIDwtIGRhaWx5UmV0dXJuKERWTl94dHMpDQoNCiMgVMOtbmggZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBs4bujaSBuaHXhuq1uIGjDoG5nIG5nw6B5DQpkYWlseV9tZWFuIDwtIG1lYW4oZGFpbHlfcmV0dXJucykNCg0KIyBUw61uaCDEkeG7mSBs4buHY2ggY2h14bqpbiBj4bunYSBs4bujaSBuaHXhuq1uIGjDoG5nIG5nw6B5DQpkYWlseV9zdGRfZGV2IDwtIHNkKGRhaWx5X3JldHVybnMpDQpgYGANClRyb25nIG3DtCBwaOG7j25nIG7DoHksIGzhu6NpIG5odeG6rW4gdGjhu4sgdHLGsOG7nW5nIGPhu5UgcGhp4bq/dSDEkcaw4bujYyBnaeG6oyDEkeG7i25oIGzDoCBwaMOibiBwaOG7kWkgY2h14bqpbiB2w6AgY8OhYyB0aMO0bmcgc+G7kSDEkcaw4bujYyB0w61uaCB0b8OhbiBuaMawIGzhu6NpIG5odeG6rW4gaMOgbmcgbmfDoHksIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgbOG7o2kgbmh14bqtbiBow6BuZyBuZ8OgeSwgxJHhu5kgbOG7h2NoIGNodeG6qW4gY+G7p2EgbOG7o2kgbmh14bqtbi4gQ8OhYyB0aMO0bmcgc+G7kSBuw6B5IHPhur0gxJHGsOG7o2Mgc+G7rSBk4bulbmcgxJHhu4MgdOG6oW8gcmEgY8OhYyBiaeG6v24gbmfhuqt1IG5oacOqbiB0cm9uZyBtw7QgaMOsbmguIA0KDQoNCmBgYHtyfQ0KIyBYw6FjIMSR4buLbmggc+G7kSBuZ8OgeSBj4bqnbiBtw7QgcGjhu49uZw0Kbm9fb2ZfZGF5cyA8LSAxMjANCg0KIyBYw6FjIMSR4buLbmggZ2nDoSBraOG7n2kgxJFp4buDbSBj4bunYSBxdcOhIHRyw6xuaCBtw7QgcGjhu49uZw0Kc3RhcnRpbmdfcHJpY2UgPC0gbGFzdChEVk4kZ2lhX2RvbmdfY3VhKVtbMV1dDQpgYGANCkThu68gbGnhu4d1IHPhur0gxJHGsOG7o2MgbcO0IHBo4buPbmcgdHJvbmcgMTIwIG5nw6B5IHThu5tpIHbDoCBnacOhIGto4bufaSDEkWnhu4NtIGPhu6dhIG5nw6B5IMSR4bqndSB0acOqbiB0cm9uZyB0aOG7nWkgxJFp4buDbSBtw7QgcGjhu49uZyBz4bq9IGzDoCBnacOhIMSRw7NuZyBj4butYSBjdeG7kWkgY8O5bmcgdHJvbmcgZOG7ryBsaeG7h3UgZ2nDoSBs4buLY2ggc+G7rSBj4bunYSBtw6MgY+G7lSBwaGnhur91Lg0KDQpM4bujaSBuaHXhuq1uIGjDoG5nIG5nw6B5IMSRxrDhu6NjIHThuqFvIGLhurFuZyBjw6FjaCBz4butIGThu6VuZyBwaMOibiBwaOG7kWkgY2h14bqpbiB24bubaSBnacOhIHRy4buLIHRydW5nIGLDrG5oIHbDoCDEkeG7mSBs4buHY2ggY2h14bqpbiDEkcOjIMSRxrDhu6NjIHTDrW5oIHRvw6FuIHRyxrDhu5tjIMSRw7MuIMSQ4buDIHTDrW5oIGdpw6EgY+G7p2EgY+G7lSBwaGnhur91LCBj4bqnbiB0aOG7sWMgaGnhu4duIHTDrW5oIHTDrWNoIGzFqXkgY+G7p2EgbOG7o2kgbmh14bqtbiB2w6AgZ2nDoSBraOG7n2kgxJFp4buDbS4gS+G6v3QgcXXhuqMgZMaw4bubaSDEkcOieSBsw6AgYmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBnacOhIG3DtCBwaOG7j25nIGPhu6dhIG3DoyBj4buVIHBoaeG6v3UgdHJvbmcgMTIwIG5nw6B5IHThu5tpLg0KYGBge3J9DQojIFThuqFvIGPGoSBz4bufIHPhu5EgbMaw4bujbmcgY8OhYyBt4bqrdSBuZ+G6q3Ugbmhpw6puIHPhur0gxJHGsOG7o2MgdOG6oW8NCnNldC5zZWVkKDEwMSkNCg0KIyBUw61uaCBnacOhIHRy4buLIGzhu6NpIG5odeG6rW4gZOG7sWEgdHLDqm4gY8OhYyBnacOhIHRy4buLIG5n4bqrdSBuaGnDqm4NCnJldHVybnMgPC0gMStybm9ybShub19vZl9kYXlzLCBtZWFuPWRhaWx5X21lYW4sIHNkPWRhaWx5X3N0ZF9kZXYpDQoNCiMgVMOtbmggZ2nDoSBj4buVIHBoaeG6v3UgdGjDtG5nIHF1YSB0w61jaCBsxal5IGPhu6dhIGdpw6Ega2jhu59pIMSRaeG7g20gdsOgIGzhu6NpIG5odeG6rW4NCnByaWNlcyA8LSBjdW1wcm9kKGMoc3RhcnRpbmdfcHJpY2UsIHJldHVybnMpKQ0KDQojIFbhur0gYmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBtw7QgcGjhu49uZyBj4bunYSBnacOhIGPhu5UgcGhp4bq/dSB0cm9uZyB0xrDGoW5nIGxhaQ0KcGxvdChwcmljZXMsIHR5cGU9J2wnLCB5bGFiPSJHacOhIGPhu5UgcGhp4bq/dSIsIHhsYWI9IlPhu5EgbmfDoHkiLCBtYWluID0gIk3DtCBwaOG7j25nIGdpw6EgY+G7p2EgbcOjIGPhu5UgcGhp4bq/dSBEVk4iKQ0KYGBgDQoNClR1eSBuaGnDqm4sIGNo4buJIGNo4bqheSBt4buZdCBtw7QgcGjhu49uZyBz4bq9IGtow7RuZyDEkeG7pyDEkeG7gyDEkcawYSByYSBr4bq/dCBsdeG6rW4uIFbDrCB24bqteSwgxJHhu4MgxJHGsGEgcmEga+G6v3QgcXXhuqMgc8OhdCB24bubaSB0aOG7sWMgdOG6vyBuaOG6pXQsIHRhIHPhur0gdGjhu7FjIGhp4buHbiBjaOG6oXkgMTAwMSBtw7QgcGjhu49uZyB0cm9uZyAxMjAgbmfDoHkgduG7m2kgbeG7l2kgbcO0IHBo4buPbmcuIEThu68gbGnhu4d1IMSRxrDhu6NjIGzGsHUgdHLhu68gaGFpIGNoaeG7gXUgZMaw4bubaSBk4bqhbmcgbWEgdHLhuq1uIHbDoCA1MCBtw7QgcGjhu49uZyDEkeG6p3UgdGnDqm4gxJHGsOG7o2MgYmnhu4N1IGRp4buFbiB0cm9uZyDEkeG7kyB0aOG7iyBkxrDhu5tpIMSRw6J5Lg0KYGBge3J9DQojIFPhu5EgbMaw4bujbmcgdGjhu7FjIGhp4buHbiB2w7JuZyBs4bq3cCBtw7QgcGjhu49uZw0Kbm9fb2Zfc2ltcyA8LSAxMDAxDQoNCiMgRGFuaCBzw6FjaCBnacOhIHRy4buLIGPhu6dhIGzhu6NpIG5odeG6rW4NCnJldHVybnNfbGlzdCA8LSBtYXRyaXgoMCwgbnJvdyA9IG5vX29mX3NpbXMsIG5jb2wgPSBub19vZl9kYXlzKQ0KDQojIERhbmggc8OhY2ggZ2nDoSBj4bunYSBj4buVIHBoaeG6v3UNCnByaWNlc19saXN0IDwtIG1hdHJpeCgwLCBucm93ID0gbm9fb2Zfc2ltcywgbmNvbCA9IG5vX29mX2RheXMrMSkgDQoNCiMgVsOybmcgbOG6t3AgdGjhu7FjIGhp4buHbiBtw7QgcGjhu49uZyB0cm9uZyBz4buRIG5nw6B5IMSRxrDhu6NjIGNo4buJIMSR4buLbmgNCmZvcihpIGluIDE6bm9fb2Zfc2ltcykgew0KICByZXR1cm5zX2xpc3RbaSxdIDwtIHJub3JtKG5vX29mX2RheXMsIG1lYW49ZGFpbHlfbWVhbiwgc2Q9ZGFpbHlfc3RkX2RldikNCiAgcHJpY2VzX2xpc3RbaSxdIDwtIGN1bXByb2QoYyhzdGFydGluZ19wcmljZSwgMStyZXR1cm5zX2xpc3RbaSxdKSkNCiAgfQ0KDQojIEJp4buDdSBkaeG7hW4gZMaw4bubaSBk4bqhbmcgxJHhu5MgdGjhu4sgNTAgbcO0IHBo4buPbmcgxJHhuqd1IHRpw6puDQpwbG90KHByaWNlc19saXN0WzEsXSwgdHlwZT0nbCcsIHlsYWI9Ikdpw6EgY+G7lSBwaGnhur91IiwgeGxhYj0iU+G7kSBuZ8OgeSIsIG1haW4gPSAiTcO0IHBo4buPbmcgZ2nDoSBj4bunYSBtw6MgY+G7lSBwaGnhur91IERWTiIsIHlsaW09YygxMDAwMCwgNTAwMDApKQ0KZm9yKGkgaW4gMTo1MCkgew0KICBsaW5lcyhwcmljZXNfbGlzdFtpLCBdLCB0eXBlID0gJ2wnLCBjb2w9aSkNCn0NCmBgYA0KTmjGsCBjaMO6bmcgdGEgY8OzIHRo4buDIHRo4bqleSwga+G6v3QgcXXhuqMgY+G7p2EgY8OhYyBtw7QgcGjhu49uZyBjw7Mgc+G7sSDEkWEgZOG6oW5nIGtow6FjIG5oYXUuIE3hu5l0IHPhu5Ega+G6v3QgdGjDumMgZMaw4bubaSDEkWnhu4NtIGLhuq90IMSR4bqndSB2w6AgbeG7mXQgc+G7kSB0xINuZyBy4bqldCBuaGFuaC4gROG7sWEgdHLDqm4gNTAgbcO0IHBo4buPbmcgxJHhuqd1IHRpw6puLCBtw6MgY+G7lSBwaGnhur91IGPDsyB4dSBoxrDhu5tuZyBs4bujaSBuaHXhuq1uIMOibSB0cm9uZyB0aOG7nWkgZ2lhbiB04bubaS4gxJDhu4MgeGVtIHjDqXQgY+G7pSB0aOG7gyBoxqFuLCB0YSBz4bq9IHTDrW5oIHThu5VuZyBs4bujaSBuaHXhuq1uIHRodSB24buBOg0KDQpgYGB7cn0NCiMgVOG6oW8gbeG6o25nIMSRYSBjaGnhu4F1IGNo4bupYSBk4buvIGxp4buHdSBj4bunYSBs4bujaSBuaHXhuq1uDQp0b3RhbF9yZXR1cm5zIDwtIGFycmF5KE5BLCBkaW09IG5vX29mX3NpbXMsIGRpbW5hbWVzPU5VTEwpDQoNCiMgVsOybmcgbOG6t3AgbmjhurFtIHTDrW5oIGdpw6EgdHLhu4sgY+G7p2EgdOG7lW5nIGzhu6NpIG5odeG6rW4gduG7m2kgbeG7l2kgbcO0IHBo4buPbmcNCmZvciAoaSBpbiAxOm5vX29mX3NpbXMpIHsNCiAgdG90YWxfcmV0dXJuc1tpXSA8LSAocHJpY2VzX2xpc3RbaSwgMTIxXS1wcmljZXNfbGlzdFtpLCAxXSkvcHJpY2VzX2xpc3RbaSwxXQ0KfQ0KDQojIFRo4buRbmcga8OqIGvhur90IHF14bqjIGPhu6dhIGzhu6NpIG5odeG6rW4gdGh1IHbhu4ENCnN1bW1hcnkodG90YWxfcmV0dXJucykNCmBgYA0KS+G6v3QgbHXhuq1uIGNobyB0aOG6pXkgbcO0IHBo4buPbmcgY8OzIHh1IGjGsOG7m25nIGzhu6NpIG5odeG6rW4gw6JtLCBoxqFuIDUwJSBr4bq/dCBxdeG6oyBtw7QgcGjhu49uZyBjaG8gcmEgZ2nDoSB0cuG7iyA8IDAgYuG7n2kgZ2nDoSB0cuG7iyB0cnVuZyB24buLLCBnacOhIHRy4buLIHRydW5nIGLDrG5oIHbDoCBwaMOibiB24buLIHRo4bupIG5o4bqldCDEkeG7gXUgdGjhu4MgaGnhu4duIMSRaeG7gXUgbsOgeS4gxJDhu4MgdHLhu7FjIHF1YW4gaMOzYSBr4bq/dCBxdeG6oywgdGEgY8OzIHRo4buDIHhlbSB4w6l0IDEgc+G7kSBiaeG7g3UgxJHhu5Mgc2F1Og0KYGBge3J9DQpwYXIobWZyb3c9YygxLDMpKQ0KaGlzdCh0b3RhbF9yZXR1cm5zLCBjb2w9ImJsdWUiKQ0KYm94cGxvdCh0b3RhbF9yZXR1cm5zLCBjb2w9InllbGxvdyIpDQpwbG90KGRlbnNpdHkodG90YWxfcmV0dXJucykpDQpgYGANCkPDoWMgZ2nDoSB0cuG7iyBuZ2/huqFpIGxhaSBj4bunYSBiaeG7g3UgxJHhu5MgQm94cGxvdCB0aMaw4budbmcgdGjhu4MgaGnhu4duIG3hurd0IGTGsMahbmcgY+G7p2EgbOG7o2kgbmh14bqtbiB2w6AgYmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBz4buxIHBow6JuIHBo4buRaSBs4buHY2ggcGjhuqNpIHLDtSBy4buHdC4gxJBp4buBdSBuw6B5IGPDsyB0aOG7gyB4w6FjIG5o4bqtbiBk4buxYSB0csOqbiB0aMO0bmcgc+G7kSDEkeG7mSBs4buHY2ggZMaw4bubaSDEkcOieToNCg0KYGBge3J9DQojIFTDrW5oIMSR4buZIGzhu4djaCBj4bunYSBk4buvIGxp4buHdSBs4bujaSBuaHXhuq1uDQpza2V3bmVzcyh0b3RhbF9yZXR1cm5zKQ0KYGBgDQoNCsSQ4buDIGhp4buDbiB0aOG7iyBiaeG7g3UgxJHhu5MgZOG7hSDEkeG7jWMgaMahbiwgc+G6vSBjaOG7iSBjw7MgYmEgbcO0IHBo4buPbmcgc+G6vSDEkcaw4bujYyDEkcawYSB2w6BvOiBnacOhIHRy4buLIHRydW5nIGLDrG5oLCBnacOhIHRy4buLIHThu5FpIHRoaeG7g3UgdsOgIGdpw6EgdHLhu4sgdOG7kWkgxJFhLiBDw6FjIGThu68gbGnhu4d1IG7DoHkgxJHGsOG7o2MgbOG6pXkgdOG7qyBwaMOibiB0w61jaCBk4buvIGxp4buHdSB24bubaSBiaeG7g3UgxJHhu5MgcGjDrWEgdHLDqm4uIFRp4bq/cCB04bulYyB0aOG7sWMgaGnhu4duIHbhu5tpIHPhu7EgbOG6t3AgbOG6oWkgY+G7p2EgMTAwMSBtw7QgcGjhu49uZy4NCmBgYHtyfQ0KIyBUw6xtIHbhu4sgdHLDrSBnacOhIHRy4buLIGzhu5tuIG5o4bqldCBj4bunYSBs4bujaSBuaHXhuq1uDQptYXggPC0gd2hpY2gubWF4KHRvdGFsX3JldHVybnMpDQoNCiMgVMOsbSB24buLIHRyw60gZ2nDoSB0cuG7iyBuaOG7jyBuaOG6pXQgY+G7p2EgbOG7o2kgbmh14bqtbg0KbWluIDwtIHdoaWNoLm1pbih0b3RhbF9yZXR1cm5zKQ0KDQojIFTDrG0gduG7iyB0csOtIGPhu6dhIGdpw6EgdHLhu4sgdHJ1bmcgduG7iw0KaWYgKG5vX29mX3NpbXMgJSUgMiAhPSAwKSB7bWVkIDwtIG1hdGNoKG1lZGlhbih0b3RhbF9yZXR1cm5zKSwgdG90YWxfcmV0dXJucyl9DQoNCiMgQmnhu4N1IGRp4buFbiDEkeG7kyB0aOG7iyB24bubaSAzIGdpw6EgdHLhu4sgdHLDqm4NCnBsb3QocHJpY2VzX2xpc3RbbWluLF0sIHR5cGU9J2wnLCB5bGFiPSJHacOhIGPhu5UgcGhp4bq/dSIsIHhsYWI9IlPhu5EgbmfDoHkiLCBtYWluID0iTcO0IHBo4buPbmcgZ2nDoSBj4bunYSBtw6MgY+G7lSBwaGnhur91IERWTiIsIHlsaW09Yyg5MDAwLCA2MDAwMCksIGNvbD0icmVkIikNCmlmIChub19vZl9zaW1zICUlIDIgIT0gMCkge2xpbmVzKHByaWNlc19saXN0W21lZCwgXSwgdHlwZSA9ICdsJywgY29sPSd5ZWxsb3cnKX0NCmxpbmVzKHByaWNlc19saXN0W21heCwgXSwgdHlwZSA9ICdsJywgY29sPSdncmVlbicpDQpgYGANCg0KUXVhIMSRw7MsIGNow7puZyB0YSBjw7MgdGjhu4MgZOG7hSBkw6BuZyBuaMOsbiB0aOG6pXkgdHLGsOG7nW5nIGjhu6NwIGdpw6EgdHLhu4sgbcO0IHBo4buPbmcgdOG7kXQgbmjhuqV0LCB44bqldSBuaOG6pXQgdsOgIHRydW5nIGLDrG5oLiDEkOG7gyB0cuG6oyBs4budaSBjw6J1IGjhu49pIMSR4bqndSB0acOqbiwgZOG7sWEgdHLDqm4gY8OhYyBiaeG7g3UgxJHhu5MgdsOgIGThu68gbGnhu4d1LCB0YSBjw7MgdGjhu4Mga+G7syB24buNbmcgbeG7qWMgbOG7o2kgbmh14bqtbiBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIC02OS4wMiUgxJHhur9uIDk2LjA3JS4NCmBgYHtyfQ0KIyBUw61uaCBnacOhIHRy4buLIGzhu6NpIG5odeG6rW4gY8OzIHRo4buDIMSR4bqhdCDEkcaw4bujYyBs4bubbiBuaOG6pXQNCm1heF9yZXR1cm4gPC0gbWF4KHRvdGFsX3JldHVybnMpDQptYXhfcmV0dXJuDQoNCiMgVMOtbmggZ2nDoSB0cuG7iyBs4bujaSBuaHXhuq1uIGPDsyB0aOG7gyDEkeG6oXQgxJHGsOG7o2Mgbmjhu48gbmjhuqV0DQptaW5fcmV0dXJuIDwtIG1pbih0b3RhbF9yZXR1cm5zKQ0KbWluX3JldHVybg0KYGBgDQrEkOG7gyB0cuG6oyBs4budaSAyIGPDonUgaOG7j2kgY3Xhu5FpLCB0YSBz4bq9IHRo4buxYyBoaeG7h24gdMOtbmggeMOhYyBzdeG6pXQgbmjhurFtIMSR4bqhdCDEkcaw4bujYyBr4bq/dCBxdeG6oyBtb25nIG114buRbi4NCmBgYHtyfQ0KIyBN4bupYyBs4bujaSBuaHXhuq1uIGPhuqduIGzhu5tuIGjGoW4NCmNvbmRpdGlvbjEgPC0gc3VtKHRvdGFsX3JldHVybnMgPiAwLjEyKQ0KDQojIE3hu6ljIGzhu6NpIG5odeG6rW4gY+G6p24gbmjhu48gaMahbg0KY29uZGl0aW9uMiA8LSBzdW0odG90YWxfcmV0dXJucyA8IC0wLjIpDQoNCiMgWMOhYyBzdeG6pXQgeOG6o3kgcmEgY8OhYyB0csaw4budbmcgaOG7o3ANCnByb2JhYmlsaXR5MSA8LSBjb25kaXRpb24xL25vX29mX3NpbXMNCnByb2JhYmlsaXR5MiA8LSBjb25kaXRpb24yL25vX29mX3NpbXMNCg0KIyBL4bq/dCBxdeG6oyDEkeG6oXQgxJHGsOG7o2MNCmNhdCgiWMOhYyBzdeG6pXQgxJHhu4MgxJHhuqF0IMSRxrDhu6NjIGzhu6NpIG5odeG6rW4gdOG7kWkgdGhp4buDdSAxMiUgbMOgOiAiLCBwcm9iYWJpbGl0eTEqMTAwLCAiJSIsICIuIFjDoWMgc3XhuqV0IMSR4buDIGzhu5cgbmhp4buBdSBoxqFuIDIwJSBraG/huqNuIMSR4bqndSB0xrAgbMOgOiAiLCBwcm9iYWJpbGl0eTIqMTAwLCAiJSIpDQpgYGANCiMjIEvhur90IGx14bqtbg0KUGjGsMahbmcgcGjDoXAgbsOgeSDEkcOjIGN1bmcgY+G6pXAgbmhp4buBdSBoaeG7g3UgYmnhur90IHPDonUgc+G6r2MgduG7gSB0aOG7iyB0csaw4budbmcgY2jhu6luZyBraG/DoW4gbcOgIHLhuqV0IGtow7MgxJHhu4MgdMOtbmggdG/DoW4gdGhlbyBjw6FjaCBraMOhYy4gVsOtIGThu6UgbsOgeSBtaW5oIGjhu41hIHLhurFuZyBNw7QgcGjhu49uZyBNb250ZSBDYXJsbyBjw7MgdGjhu4MgxJHGsOG7o2Mg4bupbmcgZOG7pW5nIHRo4buxYyB0aeG7hW4gYuG7n2kgY8OhYyBuaMOgIMSR4bqndSB0xrAsIHF14bu5IHBow7JuZyBo4buZIHbDoCBjw6FjIHThu5UgY2jhu6ljIHTDoGkgY2jDrW5oIGtow6FjIHbDoG8gcXXDoSB0csOsbmggcmEgcXV54bq/dCDEkeG7i25oIGPhu6dhIGjhu40uDQo=