PHẦN 1: TÌM HIỂU VÀ CHUẨN BỊ DỮ LIỆU
library(tidyverse)
library(dplyr)
library(knitr)
data <- read.csv(file = "C:/Users/Admin/Downloads/Supermarket Transactions.csv", header = T)
#hiển thị cấu trúc dữ liệu
str(data)
## 'data.frame': 14059 obs. of 16 variables:
## $ X : int 1 2 3 4 5 6 7 8 9 10 ...
## $ PurchaseDate : chr "2007-12-18" "2007-12-20" "2007-12-21" "2007-12-21" ...
## $ CustomerID : int 7223 7841 8374 9619 1900 6696 9673 354 1293 7938 ...
## $ Gender : chr "F" "M" "F" "M" ...
## $ MaritalStatus : chr "S" "M" "M" "M" ...
## $ Homeowner : chr "Y" "Y" "N" "Y" ...
## $ Children : int 2 5 2 3 3 3 2 2 3 1 ...
## $ AnnualIncome : chr "$30K - $50K" "$70K - $90K" "$50K - $70K" "$30K - $50K" ...
## $ City : chr "Los Angeles" "Los Angeles" "Bremerton" "Portland" ...
## $ StateorProvince : chr "CA" "CA" "WA" "OR" ...
## $ Country : chr "USA" "USA" "USA" "USA" ...
## $ ProductFamily : chr "Food" "Food" "Food" "Food" ...
## $ ProductDepartment: chr "Snack Foods" "Produce" "Snack Foods" "Snacks" ...
## $ ProductCategory : chr "Snack Foods" "Vegetables" "Snack Foods" "Candy" ...
## $ UnitsSold : int 5 5 3 4 4 3 4 6 1 2 ...
## $ Revenue : num 27.38 14.9 5.52 4.44 14 ...
Dữ liệu Supermarket Transactions là một bộ dữ liệu bao gồm
14059 quan sát và 16 biến, cụ thể:
4 dữ liệu là số nguyên (int) bao gồm: Số thứ tự
(X), mã khách hàng (Customer ID), Số con cái (Chilren), Doanh số bán
hàng theo đơn vị (Units Sold).
1 dữ liệu là số (num), bao gồm: Doanh thu
(Revenue).
11 dữ liệu là chuỗi kí tự (chr), bao gồm: ngày
mua hàng (Purchase Date), giới tính (Gender), tình trạng hôn nhân
(Marital Status), sở hữu nhà riêng (Homeowner), thu nhập hàng năm
(Annual Income), thành phố (city), mã bang (Stateor Province), đất nước
(country), nhóm sản phẩm (Product Family), nhóm sản phẩm chi tiết
(Product Department) và danh mục sản phẩm (Product Category).
Trong đó, các biến định tính là:
Gender: Giới tính, F (Female) - nữ và M (Male) -
nam
MaritalStatus: Tình trạng hôn nhân, S (Single) -
độc thân và M(Married) - đã kết hôn
Homeowner: Sở hữu nhà riêng, Y (Yes) - đã có nhà
và N (No) - chưa có nhà
AnnualIncome: Thu nhập hàng năm
City: Thành phố đang sống
StateorProvince: Mã kí hiệu của bang
Country: Đất nước
ProductFamily: Nhóm sản phẩm, Food: Thực phẩm,
Drink: Đồ uống và Non-Consumable: Hàng không tiêu dùng
ProductDepartment: Nhóm sản phẩm chi
tiết
ProductCategory: Danh mục sản phẩm
#hiển thị một vài dòng đầu
head(data)
## X PurchaseDate CustomerID Gender MaritalStatus Homeowner Children
## 1 1 2007-12-18 7223 F S Y 2
## 2 2 2007-12-20 7841 M M Y 5
## 3 3 2007-12-21 8374 F M N 2
## 4 4 2007-12-21 9619 M M Y 3
## 5 5 2007-12-22 1900 F S Y 3
## 6 6 2007-12-22 6696 F M Y 3
## AnnualIncome City StateorProvince Country ProductFamily
## 1 $30K - $50K Los Angeles CA USA Food
## 2 $70K - $90K Los Angeles CA USA Food
## 3 $50K - $70K Bremerton WA USA Food
## 4 $30K - $50K Portland OR USA Food
## 5 $130K - $150K Beverly Hills CA USA Drink
## 6 $10K - $30K Beverly Hills CA USA Food
## ProductDepartment ProductCategory UnitsSold Revenue
## 1 Snack Foods Snack Foods 5 27.38
## 2 Produce Vegetables 5 14.90
## 3 Snack Foods Snack Foods 3 5.52
## 4 Snacks Candy 4 4.44
## 5 Beverages Carbonated Beverages 4 14.00
## 6 Deli Side Dishes 3 4.37
#hiển thị một vài dòng cuối
tail(data)
## X PurchaseDate CustomerID Gender MaritalStatus Homeowner Children
## 14054 14054 2009-12-29 2032 F M N 3
## 14055 14055 2009-12-29 9102 F M Y 2
## 14056 14056 2009-12-29 4822 F M Y 3
## 14057 14057 2009-12-31 250 M S Y 1
## 14058 14058 2009-12-31 6153 F S N 4
## 14059 14059 2009-12-31 3656 M S N 3
## AnnualIncome City StateorProvince Country ProductFamily
## 14054 $10K - $30K Yakima WA USA Non-Consumable
## 14055 $10K - $30K Bremerton WA USA Food
## 14056 $10K - $30K Walla Walla WA USA Food
## 14057 $30K - $50K Portland OR USA Drink
## 14058 $50K - $70K Spokane WA USA Drink
## 14059 $50K - $70K Portland OR USA Non-Consumable
## ProductDepartment ProductCategory UnitsSold Revenue
## 14054 Household Paper Products 5 14.50
## 14055 Baking Goods Baking Goods 3 9.64
## 14056 Frozen Foods Vegetables 3 7.45
## 14057 Beverages Pure Juice Beverages 4 3.24
## 14058 Dairy Dairy 2 4.00
## 14059 Household Electrical 5 25.53
#các biến định tính cần kiểm tra dữ liệu NA
dinhtinh <- c('Gender', 'MaritalStatus', 'Homeowner', 'AnnualIncome', 'City', 'StateorProvince', 'Country', 'ProductFamily', 'ProductDepartment', 'ProductCategory')
data_dinhtinh <- data[,dinhtinh]
#kiểm tra dữ liệu NA của các biến định tính
sum(is.na(data_dinhtinh))
## [1] 0
colSums(is.na(data_dinhtinh))
## Gender MaritalStatus Homeowner AnnualIncome
## 0 0 0 0
## City StateorProvince Country ProductFamily
## 0 0 0 0
## ProductDepartment ProductCategory
## 0 0
Kết quả trả về cho ta thấy rằng, với 10 dữ liệu định tính, không có
dữ liệu trống (NA).
Sau đó, chúng ta sẽ kiểm tra xem các biến định tính có phải là factor
hay không. Nếu chúng không phải là factor thì ta sẽ chuyển đổi chúng
sang dạng factor.
#kiểm tra các biến định tính có phải là factor hay chưa
cat("Kiểm tra factor của từng biến \n")
## Kiểm tra factor của từng biến
for (i in 1:ncol(data_dinhtinh)) {
a <- is.factor(data_dinhtinh[,i])
cat(colnames(data_dinhtinh)[i],":",a,"\n")
}
## Gender : FALSE
## MaritalStatus : FALSE
## Homeowner : FALSE
## AnnualIncome : FALSE
## City : FALSE
## StateorProvince : FALSE
## Country : FALSE
## ProductFamily : FALSE
## ProductDepartment : FALSE
## ProductCategory : FALSE
Kết quả kiểm tra cho ta thấy rằng, 10 biến định tính đang không phải
là factor. Vì vậy, ta tiến hành chuyển 10 biến này về dạng factor, như
sau:
# Chuyển về dạng factor
for (i in 1:ncol(data_dinhtinh)) {
data_dinhtinh[,i] <- as.factor(data_dinhtinh[,i])
}
# Kiểm tra lại
cat("Kiểm tra lại factor của từng biến \n")
## Kiểm tra lại factor của từng biến
for (i in 1:ncol(data_dinhtinh)) {
a <- is.factor(data_dinhtinh[,i])
cat(colnames(data_dinhtinh)[i],":",a,"\n")
}
## Gender : TRUE
## MaritalStatus : TRUE
## Homeowner : TRUE
## AnnualIncome : TRUE
## City : TRUE
## StateorProvince : TRUE
## Country : TRUE
## ProductFamily : TRUE
## ProductDepartment : TRUE
## ProductCategory : TRUE
Lúc này, kết quả đã cho ra 10 biến định tính đã là factor. Việc
chuyển đổi này sẽ giúp R hiểu rõ bản chất của biến phân loại và hỗ trợ
tốt hơn cho quá trình trực quan hóa dữ liệu.
PHẦN 2: PHÂN TÍCH MÔ TẢ MỘT BIẾN ĐỊNH TÍNH
2.1. Biến Gender (giới tính)
Đầu tiên chúng ta sẽ tạo bảng mô tả thống kê của biến
Gender bao gồm tần suất và phần
trăm như sau:
#Tạo bảng mô tả thống kê biến Gender
tansuat.gender <- table(data$Gender)
phantram.gender <- prop.table(tansuat.gender) * 100
gender <- data.frame(Gender = names(tansuat.gender), TanSuat = as.vector(tansuat.gender), PhanTram = as.vector(phantram.gender))
kable(gender, caption = "Bảng 1: Mô tả thống kê của biến Gender")
Bảng 1: Mô tả thống kê của biến Gender
| F |
7170 |
50.99936 |
| M |
6889 |
49.00064 |
Tiếp đến, chúng ta tiếp tục vẽ biểu đồ để có thể trực quan hóa dữ
liệu tốt hơn:
# Biểu đồ biến Gender
data %>% group_by(Gender) %>% summarise(n = n()) %>%
mutate(percentage = n / sum(n) * 100) %>%
ggplot(aes(x = '', y = n,fill = Gender)) +
geom_col(color = 'black') +
coord_polar('y') +
geom_text(aes(x = 1.3, label = paste(round(percentage, 1), "%")),position = position_stack(vjust = .5)) +
theme_void() +
labs(title = 'Hình 1: Biểu đồ tròn thể hiện số lượng khách theo giới tính', x = ' ', y = ' ')

Kết quả từ bảng 1 và hình 1 cho
thấy có 7.170 khách hàng nữ (chiếm 51%) và 6.889 khách hàng nam (chiếm
49%). Cửa hàng nhận được sự ủng hộ nhiều hơn từ khách hàng nữ, nhưng sự
khác biệt giữa hai giới tính là không lớn, chỉ khoảng 2%.
2.2. Biến MaritalStatus (Tình trạng hôn nhân)
#Tạo bảng mô tả thống kê biến MaritalStatus
tansuat.marital.status <- table(data$MaritalStatus)
phantram.marital.status <- prop.table(tansuat.marital.status) * 100
marital.status <- data.frame(MaritalStatus = names(tansuat.marital.status), TanSuat = as.vector(tansuat.marital.status), PhanTram = as.vector(phantram.marital.status))
kable(marital.status, caption = "Bảng 2: Mô tả thống kê của biến MaritalStatus")
Bảng 2: Mô tả thống kê của biến MaritalStatus
| M |
6866 |
48.83704 |
| S |
7193 |
51.16296 |
# Biểu đồ biến MaritalStatus
data %>% group_by(MaritalStatus ) %>% summarise(n = n()) %>%
mutate(percentage = n / sum(n) * 100) %>%
ggplot(aes(x = '', y = n,fill = MaritalStatus)) +
geom_col(color = 'black') +
coord_polar('y') +
geom_text(aes(x = 1.3, label = paste(round(percentage, 1), "%")),position = position_stack(vjust = .5)) +
scale_fill_manual(values = c("M" = "#7FFFD4", "S" = "#CAFF70")) +
theme_void() +
labs(title = 'Hình 2: Biểu đồ tròn thể hiện tình trạng hôn nhân của mỗi khách hàng', x = ' ', y = ' ')

Từ kết quả của bảng 2 và hình
2 cho thấy rằng, tình trạng hôn nhân của khách hàng phân
bố khá đồng đều giữa hai nhóm đã kết hôn (M) và độc thân (S). Cụ thể,
nhóm độc thân chiếm tỷ lệ nhỉnh hơn với 7193 người (51.2%), trong khi
nhóm đã kết hôn là 6866 người (48.8%). Điều này cho thấy rằng không có
sự chênh lệch lớn giữa hai nhóm về mặt số lượng, tuy nhiên việc nhóm độc
thân chiếm tỷ lệ cao hơn một chút có thể gợi ý rằng đối tượng khách hàng
chưa lập gia đình đang chiếm ưu thế nhẹ trong tệp khách hàng hiện
tại.
2.3. Biến Homeowner (Sở hữu nhà riêng)
#Tạo bảng mô tả thống kê biến Homeowner
tansuat.homeowner <- table(data$Homeowner)
kable(tansuat.homeowner, caption = "Bảng 3: Mô tả thống kê của biến Homeowner")
Bảng 3: Mô tả thống kê của biến Homeowner
| N |
5615 |
| Y |
8444 |
# Biểu đồ biến Homeowner
data %>% group_by(Homeowner) %>% summarise(n = n()) %>%
mutate(percentage = n / sum(n) * 100) %>%
ggplot(aes(x = '', y = n,fill = Homeowner)) +
geom_col(color = 'black') +
coord_polar('y') +
geom_text(aes(x = 1.3, label = paste0(round(percentage, 1), "%")),position = position_stack(vjust = .5)) +
scale_fill_manual(values = c("Y" = "pink", "N" = "lightgreen")) +
theme_void() +
labs(title = 'Hình 3: Biểu đồ tròn thể hiện tình trạng sở hữu nhà riêng của mỗi khách hàng', x = ' ', y = ' ')

Kết quả thống kê cho biến Homeowner từ bảng
3 và hình 3 cho thấy rằng có
60,1% khách hàng sở hữu nhà riêng, trong khi 39,9% còn lại không sở hữu
nhà. Tỷ lệ sở hữu nhà cao hơn cho thấy phần lớn khách hàng trong tập dữ
liệu có mức độ ổn định nhất định về mặt tài chính hoặc đang ở giai đoạn
đời sống đã tích lũy được tài sản cố định. Điều này có thể là yếu tố ảnh
hưởng đến hành vi tiêu dùng, nhu cầu vay vốn hoặc xu hướng đầu tư tài
chính của họ.
2.4. Biến AnnualIncome (Thu nhập hàng năm)
#Tạo bảng mô tả thống kê biến AnnualIncome
tansuat.annualincome <- table(data$AnnualIncome)
kable(tansuat.annualincome, caption = "Bảng 4: Mô tả thống kê của biến Annua Income")
Bảng 4: Mô tả thống kê của biến Annua Income
| $10K - $30K |
3090 |
| $110K - $130K |
643 |
| $130K - $150K |
760 |
| $150K + |
273 |
| $30K - $50K |
4601 |
| $50K - $70K |
2370 |
| $70K - $90K |
1709 |
| $90K - $110K |
613 |
# Biểu đồ biến Homeowner
counts <- data %>%
group_by(AnnualIncome) %>%
summarise(Count = n())
ggplot(counts, aes(x = AnnualIncome, y = Count)) +
geom_bar(stat = "identity", fill = 'skyblue') +
geom_text(aes(label = Count), vjust = -0.5, size = 4) +
labs(
title = "Hình 4: Biểu đồ cột thể hiện thu nhập hàng năm",
x = 'Thu nhập hàng năm',
y = 'Số lượng khách hàng'
) +
theme_minimal()

Phân bố thu nhập hàng năm của khách hàng trong bảng
4 và hình 4 cho thấy sự phân bố
thu nhập hàng năm của khách hàng với sự chênh lệch rõ rệt giữa các nhóm.
Nhóm thu nhập từ $30K - $50K chiếm ưu thế vượt trội với
4,601 khách hàng, gấp nhiều lần so với các nhóm khác.
Theo sau là nhóm $10K - $30K và $50K -
$70K. Ngược lại, nhóm thu nhập trên $150K có
số lượng khách hàng thấp nhất (chỉ 273 người). Biểu đồ
cho thấy phân khúc khách hàng chủ yếu tập trung ở mức thu nhập trung
bình – thấp, phản ánh xu hướng phổ biến trong dữ liệu này.
2.5. Biến City (Thành phố)
#Tạo bảng mô tả thống kê biến City
tansuat.city <- table(data$City)
phantram.city <- prop.table(tansuat.city) * 100
bang.city <- data.frame(
City = names(tansuat.city),
Frequency = as.vector(tansuat.city),
Percentage = round(as.vector(phantram.city), 2)
)
kable(bang.city, caption = "Bảng 5: Mô tả thống kê của biến City")
Bảng 5: Mô tả thống kê của biến City
| Acapulco |
383 |
2.72 |
| Bellingham |
143 |
1.02 |
| Beverly Hills |
811 |
5.77 |
| Bremerton |
834 |
5.93 |
| Camacho |
452 |
3.22 |
| Guadalajara |
75 |
0.53 |
| Hidalgo |
845 |
6.01 |
| Los Angeles |
926 |
6.59 |
| Merida |
654 |
4.65 |
| Mexico City |
194 |
1.38 |
| Orizaba |
464 |
3.30 |
| Portland |
876 |
6.23 |
| Salem |
1386 |
9.86 |
| San Andres |
621 |
4.42 |
| San Diego |
866 |
6.16 |
| San Francisco |
130 |
0.92 |
| Seattle |
922 |
6.56 |
| Spokane |
875 |
6.22 |
| Tacoma |
1257 |
8.94 |
| Vancouver |
633 |
4.50 |
| Victoria |
176 |
1.25 |
| Walla Walla |
160 |
1.14 |
| Yakima |
376 |
2.67 |
# Biểu đồ biến City
counts <- data %>%
group_by(City) %>%
summarise(Count = n())
ggplot(counts, aes(x = City, y = Count)) +
geom_bar(stat = "identity", fill = 'darkorange') +
geom_text(aes(label = Count), vjust = -0.5, size = 4) +
labs(
title = "Hình 4: Biểu đồ cột thể hiện thu nhập hàng năm",
x = 'Thu nhập hàng năm',
y = 'Số lượng khách hàng'
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Biểu đồ cho thấy sự phân bố số lượng khách hàng theo từng thành phố
với sự chênh lệch rõ rệt. San Antonio là thành phố có
số lượng khách hàng cao nhất (1.386 người), theo sau là
Tacoma (1.257 người) và
Merida (926 người). Trong khi đó, một
số thành phố như Guadalajara, Yakima
và Walla Walla có số lượng khách hàng rất thấp, dưới
400 người. Điều này cho thấy dữ liệu tập trung mạnh ở
một số đô thị lớn, còn nhiều thành phố khác chỉ chiếm tỷ trọng nhỏ. Phân
bố không đồng đều này có thể phản ánh đặc điểm dân số hoặc mức độ tiếp
cận dịch vụ ở từng khu vực.
2.6. Biến StateorProvince (Mã kí hiệu của
bang)
#Tạo bảng mô tả thống kê biến StateorProvince
tansuat.stateorprovince <- table(data$StateorProvince)
phantram.stateorprovince <- prop.table(tansuat.stateorprovince) * 100
bang.stateorprovince <- data.frame(
stateorprovince = names(tansuat.stateorprovince),
Fequency = as.vector(tansuat.stateorprovince),
Percentage = round(as.vector(phantram.stateorprovince), 2)
)
kable(bang.stateorprovince, caption = "Bảng 6: Mô tả thống kê của biến Stateor Province")
Bảng 6: Mô tả thống kê của biến Stateor Province
| BC |
809 |
5.75 |
| CA |
2733 |
19.44 |
| DF |
815 |
5.80 |
| Guerrero |
383 |
2.72 |
| Jalisco |
75 |
0.53 |
| OR |
2262 |
16.09 |
| Veracruz |
464 |
3.30 |
| WA |
4567 |
32.48 |
| Yucatan |
654 |
4.65 |
| Zacatecas |
1297 |
9.23 |
# Biểu đồ biến StateorProvince
counts <- data %>%
group_by(StateorProvince) %>%
summarise(Count = n())
ggplot(counts, aes(x = StateorProvince, y = Count)) +
geom_bar(stat = "identity", fill = 'maroon') +
geom_text(aes(label = Count), vjust = -0.5, size = 4) +
labs(
title = "Hình 6: Số lượng mã bang của mỗi khách hàng",
x = "Mã bang",
y = "Số lượng khách hàng"
) +
theme_minimal()

Biến StateorProvince phản ánh phân bố khách hàng theo mã bang hoặc
tỉnh. Dữ liệu cho thấy sự chênh lệch đáng kể về tần suất khách hàng giữa
các khu vực. Cụ thể, bang Washington (WA) chiếm tỷ trọng lớn nhất với
4.567 khách hàng, tương ứng 32.48% tổng số, cho thấy đây là khu vực tập
trung đông đảo khách hàng nhất. Xếp sau là California (CA) với 2.733
khách hàng (19.44%) và Oregon (OR) với 2.262 khách hàng (16.09%). Ba
bang này chiếm tổng cộng gần 68% tổng số khách hàng, cho thấy mức độ
hiện diện hoặc hoạt động thương mại tập trung tại đây là khá cao.
Ngược lại, một số khu vực có số lượng khách hàng rất thấp như Jalisco
với chỉ 75 người, tương đương 0.53%, hay Guerrero và Veracruz chỉ chiếm
lần lượt 2.72% và 3.30%. Điều này cho thấy sự hiện diện khách hàng ở
những bang này còn khá hạn chế. Các bang còn lại như BC, DF, Yucatan và
Zacatecas dao động từ khoảng 4.65% đến 9.23%, phản ánh mức độ trung bình
trong phân bố khách hàng.
2.7. Biến Country (Đất nước)
#Tạo bảng mô tả thống kê biến Country
tansuat.country <- table(data$Country)
kable(tansuat.country, caption = "Bảng 7: Mô tả thống kê của biến Country")
Bảng 7: Mô tả thống kê của biến Country
| Canada |
809 |
| Mexico |
3688 |
| USA |
9562 |
# Biểu đồ biến Country
data %>% group_by(Country) %>% summarise(n = n()) %>%
mutate(percentage = n / sum(n) * 100) %>%
ggplot(aes(x = '', y = n,fill = Country)) +
geom_col(color = 'black') +
coord_polar('y') +
geom_text(aes(x = 1.3, label = paste0(round(percentage, 1), "%")),position = position_stack(vjust = .5)) +
scale_fill_manual(values = c("USA" = "#836FFF", "Mexico" = "#DDA0DD", "Canada" = "#AFEEEE")) +
theme_void() +
labs(title = 'Hình 7: Biểu đồ tròn thể hiện đất nước của mỗi khách hàng', x = ' ', y = ' ')

Từ bảng 7 và hình
7, biến Country phản ánh phân bố khách hàng theo quốc gia.
Kết quả cho thấy khách hàng chủ yếu tập trung tại Hoa Kỳ, chiếm tới 68%
tổng số quan sát, tương ứng 9.562 khách hàng. Đây là tỷ lệ vượt trội so
với hai quốc gia còn lại, thể hiện rõ ràng vai trò trung tâm của thị
trường Mỹ trong dữ liệu.
Mexico là quốc gia có lượng khách hàng đứng thứ hai với 3.688 người,
chiếm khoảng 26.2%, cho thấy sự hiện diện khá rõ nét của khách hàng tại
quốc gia láng giềng này. Trong khi đó, Canada chỉ đóng góp 809 khách
hàng, tương ứng 5.8%, là nhóm chiếm tỷ trọng nhỏ nhất trong ba quốc
gia.
2.8. Biến ProductFamily (Nhóm sản phẩm)
#Tạo bảng mô tả thống kê biến ProductFamily
tansuat.productfamily <- table(data$ProductFamily)
kable(tansuat.productfamily, caption = "Bảng 8: Mô tả thống kê của biến Product Family")
Bảng 8: Mô tả thống kê của biến Product Family
| Drink |
1250 |
| Food |
10153 |
| Non-Consumable |
2656 |
# Biểu đồ biến ProductFamily
data %>% group_by(ProductFamily) %>% summarise(n = n()) %>%
mutate(percentage = n / sum(n) * 100) %>%
ggplot(aes(x = '', y = n,fill = ProductFamily)) +
geom_col(color = 'black') +
coord_polar('y') +
geom_text(aes(x = 1.3, label = paste0(round(percentage, 1), "%")),position = position_stack(vjust = .5)) +
scale_fill_manual(values = c("Food" = "#98FB98", "Drink" = "#7CCD7C", "Non-Consumable" = "#548B54")) +
theme_void() +
labs(title = 'Hình 8: Biểu đồ tròn thể hiện nhóm sản phẩm mà mỗi khách hàng mua', x = ' ', y = ' ')

Dựa trên bảng 8 và hình
8, thống kê mô tả cho thấy sự phân bố rõ ràng trong các
danh mục sản phẩm mà khách hàng đã mua. Tổng cộng, có 10.153 sản phẩm
thuộc nhóm Thực phẩm (chiếm 72,2%), 1.250 sản phẩm thuộc nhóm Đồ uống
(8,9%), và 2.656 sản phẩm thuộc nhóm Không tiêu dùng (18,9%). Kết quả
này cho thấy Thực phẩm là nhóm sản phẩm chiếm ưu thế vượt trội, phản ánh
nhu cầu hoặc sở thích tiêu dùng thực phẩm cao của khách hàng. Trong khi
đó, Đồ uống và Không tiêu dùng có tỷ lệ thấp hơn, với nhóm Không tiêu
dùng nổi bật hơn Đồ uống một chút, có thể do tính đa dạng hoặc nhu cầu
thiết yếu của các sản phẩm không tiêu dùng trong đời sống hàng ngày.
2.9. ProductDepartment (Nhóm sản phẩm chi
tiết)
#Tạo bảng mô tả thống kê biến ProductDepartment
bang.productdepartment <- table(data$ProductDepartment)
kable(bang.productdepartment, caption = "Bảng 9: Mô tả thống kê của biến ProductDepartment")
Bảng 9: Mô tả thống kê của biến ProductDepartment
| Alcoholic Beverages |
356 |
| Baked Goods |
425 |
| Baking Goods |
1072 |
| Beverages |
680 |
| Breakfast Foods |
188 |
| Canned Foods |
977 |
| Canned Products |
109 |
| Carousel |
59 |
| Checkout |
82 |
| Dairy |
903 |
| Deli |
699 |
| Eggs |
198 |
| Frozen Foods |
1382 |
| Health and Hygiene |
893 |
| Household |
1420 |
| Meat |
89 |
| Periodicals |
202 |
| Produce |
1994 |
| Seafood |
102 |
| Snack Foods |
1600 |
| Snacks |
352 |
| Starchy Foods |
277 |
# Biểu đồ biến ProductDepartment
counts <- data %>%
group_by(ProductDepartment) %>%
summarise(Count = n())
ggplot(counts, aes(x = ProductDepartment, y = Count)) +
geom_bar(stat = "identity", fill = 'lightblue') +
geom_text(aes(label = Count), vjust = -0.5, size = 4) +
labs(
title = "Hình 9: Bảng đồ cột thể hiện nhóm sản phẩm chi tiết",
x = "nhóm sản phẩm chi tiết",
y = "Số lượng khách hàng"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Biểu đồ thể hiện sự phân bố số lượng khách hàng theo nhóm sản phẩm
chi tiết, trong đó Produce (rau củ quả) là nhóm được mua nhiều nhất với
1.994 khách hàng, theo sau là Snack Foods (1.600 người) và Household
(1.420 người). Ngược lại, các nhóm như Carousel, Checkout, và
Periodicals có số lượng khách hàng rất thấp, dưới 100 người. Sự chênh
lệch lớn này cho thấy khách hàng có xu hướng tập trung vào các mặt hàng
thiết yếu và tiêu dùng thường xuyên, trong khi ít quan tâm đến các nhóm
sản phẩm phụ hoặc chuyên biệt hơn.
2.10. Product Category (Danh mục sản phẩm)
#Tạo bảng mô tả thống kê biến ProductCategory
tansuat.productcategory <- table(data$ProductCategory)
kable(tansuat.productcategory, caption = "Bảng 9: Mô tả thống kê của biến ProductCategory")
Bảng 9: Mô tả thống kê của biến ProductCategory
| Baking Goods |
484 |
| Bathroom Products |
365 |
| Beer and Wine |
356 |
| Bread |
425 |
| Breakfast Foods |
417 |
| Candles |
45 |
| Candy |
352 |
| Canned Anchovies |
44 |
| Canned Clams |
53 |
| Canned Oysters |
35 |
| Canned Sardines |
40 |
| Canned Shrimp |
38 |
| Canned Soup |
404 |
| Canned Tuna |
87 |
| Carbonated Beverages |
154 |
| Cleaning Supplies |
189 |
| Cold Remedies |
93 |
| Dairy |
903 |
| Decongestants |
85 |
| Drinks |
135 |
| Eggs |
198 |
| Electrical |
355 |
| Frozen Desserts |
323 |
| Frozen Entrees |
118 |
| Fruit |
765 |
| Hardware |
129 |
| Hot Beverages |
226 |
| Hygiene |
197 |
| Jams and Jellies |
588 |
| Kitchen Products |
217 |
| Magazines |
202 |
| Meat |
761 |
| Miscellaneous |
42 |
| Packaged Vegetables |
48 |
| Pain Relievers |
192 |
| Paper Products |
345 |
| Pizza |
194 |
| Plastic Products |
141 |
| Pure Juice Beverages |
165 |
| Seafood |
102 |
| Side Dishes |
153 |
| Snack Foods |
1600 |
| Specialty |
289 |
| Starchy Foods |
277 |
| Vegetables |
1728 |
# Biểu đồ biến ProductCategory
counts <- data %>%
group_by(ProductCategory) %>%
summarise(Count = n())
ggplot(counts, aes(x = ProductCategory, y = Count)) +
geom_bar(stat = "identity", fill = 'brown') +
labs(
title = "Hình 9: Bảng đồ cột thể hiện nhóm sản phẩm chi tiết",
x = "nhóm sản phẩm chi tiết",
y = "Số lượng khách hàng"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 47, hjust = 1))

Dựa trên kết quả bảng 10 và
hình 10 phân tích thống kê mô tả cho thấy sự
phân bố không đồng đều và rõ rệt trong các danh mục sản phẩm mà khách
hàng đã lựa chọn trong thời gian khảo sát. Nhóm “Vegetables” (rau củ)
đứng đầu với tần suất cao nhất là 1.728 sản phẩm, phản ánh nhu cầu mạnh
mẽ đối với thực phẩm tươi sống, có thể do lợi ích dinh dưỡng và tính phổ
biến trong bữa ăn hàng ngày. Tiếp theo là “Snack Foods” (đồ ăn vặt) với
1.600 sản phẩm, cho thấy xu hướng tiêu dùng các sản phẩm tiện lợi và
nhanh chóng, phù hợp với lối sống bận rộn của nhiều người. Nhóm “Fruit”
(trái cây) với 765 sản phẩm cũng chiếm vị trí đáng kể, củng cố thêm xu
hướng ưu tiên các thực phẩm lành mạnh. Ngược lại, các nhóm như “Canned
Oysters” (35 sản phẩm), “Canned Shrimp” (38 sản phẩm), và “Candles” (45
sản phẩm) ghi nhận tần suất rất thấp, điều này có thể xuất phát từ việc
các sản phẩm này thuộc nhóm đặc sản hoặc ít được ưa chuộng trong thị
trường mục tiêu. Ngoài ra, các danh mục như “Canned Anchovies” (44 sản
phẩm) và “Miscellaneous” (42 sản phẩm) cũng cho thấy mức độ tiêu thụ hạn
chế, có thể do tính đặc thù hoặc sự cạnh tranh từ các sản phẩm khác. Kết
quả này không chỉ phản ánh sở thích tiêu dùng tập trung vào thực phẩm
thiết yếu và tiện lợi mà còn gợi ý rằng các sản phẩm chuyên biệt hoặc ít
phổ biến có thể cần chiến lược tiếp thị hoặc cải tiến để tăng sức hút
trong tương lai.
PHẦN 3: ƯỚC LƯỢNG KHOẢNG VÀ KIỂM ĐỊNH GIẢ THUYẾT CHO TỶ LỆ
(MỘT BIẾN)
3.1. Biến Gender - hạng mục “Nữ”
i) Hạng mục quan tâm
Trong biến Gender, hạng mục được quan tâm ở đây là F
(nữ)
#Tổng số quan sát
total <- nrow(data)
#Số lượng nữ
so.nu <- sum(data$Gender == "F")
ii) Ước lượng khoảng tin cậy
Khoảng ước lượng cho tỷ lệ nữ với mức ý nghĩa 95% là:
#với khoảng tin cậy 95%
prop.test(so.nu, total, conf.level = 0.95)
##
## 1-sample proportions test with continuity correction
##
## data: so.nu out of total, null probability 0.5
## X-squared = 5.5765, df = 1, p-value = 0.0182
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
## 0.5016931 0.5182886
## sample estimates:
## p
## 0.5099936
Với kết quả trên, ta có được khoảng tin cậy tỷ lệ khách hàng nữ trong
tổng thể nằm trong khoảng từ 50.17% đến
51.83%.
iii) Kiểm định giả thuyết
Giả thuyết kiểm định:
\(H_0\): Tỷ lệ nữ trong tổng số quan
sát bằng 50%
\(H_1\): Tỷ lệ nữ trong tổng số quan
sát khác 50%
# Kiểm định H0: p = 0.5
prop.test(so.nu, total, p = 0.5)
##
## 1-sample proportions test with continuity correction
##
## data: so.nu out of total, null probability 0.5
## X-squared = 5.5765, df = 1, p-value = 0.0182
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
## 0.5016931 0.5182886
## sample estimates:
## p
## 0.5099936
Với kết quả vừa kiểm định được, ta thấy rằng \(p-value = 0.0182 < 0.05\), ta bác bỏ giả
thuyết \(H_0\) và chấp nhận giả thuyết
\(H_1\), tức tỷ lệ nữ trong tổng số
quan sát khác 50% ở mức ý nghĩa 5%.
3.2. Biến MaritalStatus - hạng mục “Độc thân”
Trong biến MaritalStatus, hạng mục được quan tâm ở đây là
S (độc thân)
#Tổng số quan sát
total <- nrow(data)
#Số lượng độc thân
so.doc.than <- sum(data$MaritalStatus == "S")
ii) Ước lượng khoảng tin cậy
Khoảng ước lượng cho tỷ lệ độc thân với mức ý nghĩa 95% là:
#với khoảng tin cậy 95%
prop.test(so.doc.than, total, conf.level = 0.95)
##
## 1-sample proportions test with continuity correction
##
## data: so.doc.than out of total, null probability 0.5
## X-squared = 7.5593, df = 1, p-value = 0.00597
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
## 0.5033292 0.5199235
## sample estimates:
## p
## 0.5116296
Với kết quả trên, ta có được khoảng tin cậy tỷ lệ khách hàng nữ trong
tổng thể nằm trong khoảng từ 50.33% đến
51.99%.
iii) Kiểm định giả thuyết
Giả thuyết kiểm định:
\(H_0\): Tỷ lệ độc thân trong tổng
số quan sát bằng 50%
\(H_1\): Tỷ lệ độc thân trong tổng
số quan sát khác 50%
# Kiểm định H0: p = 0.5
prop.test(so.doc.than, total, p = 0.5)
##
## 1-sample proportions test with continuity correction
##
## data: so.doc.than out of total, null probability 0.5
## X-squared = 7.5593, df = 1, p-value = 0.00597
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
## 0.5033292 0.5199235
## sample estimates:
## p
## 0.5116296
Với kết quả vừa kiểm định được, ta thấy rằng \(p-value = 0.00597 < 0.05\), ta bác bỏ
giả thuyết \(H_0\) và chấp nhận giả
thuyết \(H_1\), tức tỷ lệ độc thân
trong tổng số quan sát khác 50% ở mức ý nghĩa 5%.
3.3. Biến ProductCategory - hạng mục “Candy”
Trong biến ProductCategory, hạng mục được quan tâm ở đây là
Candy (kẹo)
#Tổng số quan sát
total <- nrow(data)
#Số lượng độc thân
so.keo <- sum(data$ProductCategory == "Candy")
ii) Ước lượng khoảng tin cậy
Khoảng ước lượng cho tỷ lệ kẹo với mức ý nghĩa 95% là:
#với khoảng tin cậy 95%
prop.test(so.keo, total, conf.level = 0.95)
##
## 1-sample proportions test with continuity correction
##
## data: so.keo out of total, null probability 0.5
## X-squared = 12684, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
## 0.02254780 0.02778994
## sample estimates:
## p
## 0.02503734
Với kết quả trên, ta có được khoảng tin cậy tỷ lệ khách hàng nữ trong
tổng thể nằm trong khoảng từ 2.25% đến
2.78%.
iii) Kiểm định giả thuyết
Giả thuyết kiểm định:
\(H_0\): Tỷ lệ kẹo trong tổng số
quan sát bằng 50%
\(H_1\): Tỷ lệ kẹo trong tổng số
quan sát khác 50%
# Kiểm định H0: p = 0.5
prop.test(so.keo, total, p = 0.5)
##
## 1-sample proportions test with continuity correction
##
## data: so.keo out of total, null probability 0.5
## X-squared = 12684, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
## 0.02254780 0.02778994
## sample estimates:
## p
## 0.02503734
Với kết quả vừa kiểm định được, ta thấy rằng \(p-value < 2.2e-16 < 0.05\), ta bác bỏ
giả thuyết \(H_0\) và chấp nhận giả
thuyết \(H_1\), tức tỷ lệ kẹo trong
tổng số quan sát khác 50% ở mức ý nghĩa 5%.
PHẦN 4: PHÂN TÍCH MỖI QUAN HỆ GIỮA HAI BIẾN ĐỊNH TÍNH
(BIVARIATE ANALYSIS)
4.1. Biến Gender và ProductFamily
Bảng tần suất chéo và biểu đồ trực quan hóa cho mối quan hệ
giữa 2 biến:
# Bần suất giữa Gender và ProductFamily
tansuat1 <- table(data$Gender, data$ProductFamily)
phantram1 <- prop.table(tansuat1, margin = 1) * 100
bang1 <- as.data.frame(tansuat1)
bang1$Percentage <- round(as.vector(phantram1), 2)
colnames(bang1) <- c("Gender", "ProductFamily", "Frequency", "Percentage")
kable(bang1, caption = "Bảng 11: Mô tả thống kê của 2 biến Gender và ProductFamily")
Bảng 11: Mô tả thống kê của 2 biến Gender và
ProductFamily
| F |
Drink |
669 |
9.33 |
| M |
Drink |
581 |
8.43 |
| F |
Food |
5149 |
71.81 |
| M |
Food |
5004 |
72.64 |
| F |
Non-Consumable |
1352 |
18.86 |
| M |
Non-Consumable |
1304 |
18.93 |
#Trực quan hóa cho mối quan hệ giữa 2 biến
ggplot(bang1, aes(x = ProductFamily, y = Percentage, fill = Gender)) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = "Hình 11: Mối quan hệ giữa Gender và ProductFamily",
x = "Nhóm sản phẩm", y = "Tỷ lệ (%)", fill = "Giới tính") +
theme_minimal()

Dựa trên bảng tần suất chéo và biểu đồ minh họa, có thể thấy mối quan
hệ giữa hai biến Gender và
ProductFamily là khá đồng đều. Cả nam và nữ đều có xu
hướng tiêu dùng tương tự nhau, trong đó nhóm sản phẩm
“Food” chiếm tỷ lệ cao nhất ở cả hai giới (trên 71%),
tiếp theo là “Non-Consumable” (khoảng 18%), và thấp
nhất là “Drink” (dưới 10%). Sự phân bố tương đối cân
bằng này cho thấy không có sự khác biệt rõ rệt giữa nam và nữ trong việc
lựa chọn nhóm sản phẩm. Do đó, qua quan sát, có vẻ như hai biến
này không có mối liên hệ mạnh, tuy nhiên để có kết luận chính
xác hơn, cần thực hiện kiểm định thống kê bằng phép kiểm Chi-bình
phương.
Kiểm định chi bình phương:
Giả thuyết kiểm định:
\(H_0\): Biến Gender (giới tính)
không ảnh hưởng đến biến ProductFamily (nhóm sản phẩm)
\(H_1\): Biến Gender (giới tính) có
ảnh hưởng đến biến ProductFamily (nhóm sản phẩm)
# Kiểm định Chi-bình phương
chi_test <- chisq.test(tansuat1)
chi_test
##
## Pearson's Chi-squared test
##
## data: tansuat1
## X-squared = 3.5185, df = 2, p-value = 0.1722
Với kết quả vừa kiểm định được, ta thấy rằng \(p-value = 0.1722 > 0.05\), ta không đủ
bằng chứng để bác bỏ giả thuyết \(H_0\). Như vậy, biến Gender (giới tính)
không ảnh hưởng đến biến ProductFamily (nhóm sản phẩm)ở mức ý nghĩa
5%.
4.2. Biến MaritalStatus và Homeowner
Bảng tần suất chéo và biểu đồ trực quan hóa cho mối quan hệ
giữa 2 biến:
# Bần suất giữa MaritalStatus và Homeowner
tansuat2 <- table(data$MaritalStatus, data$Homeowner)
phantram2 <- prop.table(tansuat2, margin = 1) * 100
bang2 <- as.data.frame(tansuat2)
bang2$Percentage <- round(as.vector(phantram2), 2)
colnames(bang2) <- c("MaritalStatus", "Homeowner", "Frequency", "Percentage")
kable(bang2, caption = "Bảng 12: Mô tả thống kê của 2 biến MaritalStatus và Homeowner")
Bảng 12: Mô tả thống kê của 2 biến MaritalStatus và
Homeowner
| M |
N |
1719 |
25.04 |
| S |
N |
3896 |
54.16 |
| M |
Y |
5147 |
74.96 |
| S |
Y |
3297 |
45.84 |
#Trực quan hóa cho mối quan hệ giữa 2 biến
ggplot(bang2, aes(x = Homeowner, y = Percentage, fill = MaritalStatus)) +
geom_bar(stat = "identity") + # hoặc thêm: position = "stack"
scale_fill_manual(values = c("S" = "#FF6F61", "M" = "#6B5B95")) +
labs(title = "Hình 12: Mối quan hệ giữa MaritalStatus và Homeowner",
x = "Tình trạng sở hữu nhà riêng", y = "Tỷ lệ (%)", fill = "Tình trạng hôn nhân") +
theme_minimal()

Dựa trên bảng 12 và hình
12, có thể thấy rằng tồn tại một mối liên hệ rõ rệt giữa
tình trạng hôn nhân và khả năng sở hữu nhà riêng. Cụ thể, trong nhóm đã
kết hôn (M), có tới 74.96% người sở hữu nhà, trong khi chỉ 25.04% không
sở hữu. Ngược lại, ở nhóm độc thân (S), tỷ lệ không sở hữu nhà là
54.16%, cao hơn tỷ lệ sở hữu nhà (45.84%). Biểu đồ cột chồng minh họa rõ
điều này khi phần màu đại diện cho người đã kết hôn chiếm ưu thế trong
nhóm sở hữu nhà, còn phần màu đại diện cho người độc thân lại nổi bật
hơn trong nhóm không sở hữu. Xu hướng này cho thấy người đã kết hôn
thường có xu hướng và khả năng sở hữu nhà riêng cao hơn so với người độc
thân, có thể do yếu tố tài chính ổn định hơn hoặc nhu cầu an cư khi lập
gia đình.
Kiểm định chi bình phương:
Giả thuyết kiểm định:
\(H_0\): Biến MaritalStatus (tình
trạng hôn nhân) không ảnh hưởng đến biến Homeowner (tình trạng sở hữu
nhà riêng)
\(H_1\): Biến MaritalStatus (tình
trạng hôn nhân) có ảnh hưởng đến biến Homeowner (tình trạng sở hữu nhà
riêng)
# Kiểm định Chi-bình phương
chi_test <- chisq.test(tansuat2)
chi_test
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: tansuat2
## X-squared = 1241.2, df = 1, p-value < 2.2e-16
Với kết quả vừa kiểm định được, ta thấy rằng \(p-value < 2.2e-16 < 0.05\), ta bác bỏ
giả thuyết \(H_0\) và chấp nhận giả
thuyết \(H_1\), tức biến MaritalStatus
(tình trạng hôn nhân) có ảnh hưởng đến biến Homeowner (tình trạng sở hữu
nhà riêng) ở mức ý nghĩa 5%.
4.3. Biến AnnualIncome và ProductCategory
Bảng tần suất chéo và biểu đồ trực quan hóa cho mối quan hệ
giữa 2 biến:
# Bần suất giữa AnnualIncome và Country
tansuat3 <- table(data$AnnualIncome, data$Country)
phantram3 <- prop.table(tansuat3, margin = 1) * 100
bang3 <- as.data.frame(tansuat3)
bang3$Percentage <- round(as.vector(phantram3), 2)
colnames(bang3) <- c("AnnualIncome", "Country", "Frequency", "Percentage")
kable(bang3, caption = "Bảng 13: Mô tả thống kê của 2 biến AnnualIncome và Country")
Bảng 13: Mô tả thống kê của 2 biến AnnualIncome và
Country
| $10K - $30K |
Canada |
172 |
5.57 |
| $110K - $130K |
Canada |
49 |
7.62 |
| $130K - $150K |
Canada |
45 |
5.92 |
| $150K + |
Canada |
16 |
5.86 |
| $30K - $50K |
Canada |
296 |
6.43 |
| $50K - $70K |
Canada |
126 |
5.32 |
| $70K - $90K |
Canada |
80 |
4.68 |
| $90K - $110K |
Canada |
25 |
4.08 |
| $10K - $30K |
Mexico |
800 |
25.89 |
| $110K - $130K |
Mexico |
178 |
27.68 |
| $130K - $150K |
Mexico |
210 |
27.63 |
| $150K + |
Mexico |
55 |
20.15 |
| $30K - $50K |
Mexico |
1191 |
25.89 |
| $50K - $70K |
Mexico |
607 |
25.61 |
| $70K - $90K |
Mexico |
483 |
28.26 |
| $90K - $110K |
Mexico |
164 |
26.75 |
| $10K - $30K |
USA |
2118 |
68.54 |
| $110K - $130K |
USA |
416 |
64.70 |
| $130K - $150K |
USA |
505 |
66.45 |
| $150K + |
USA |
202 |
73.99 |
| $30K - $50K |
USA |
3114 |
67.68 |
| $50K - $70K |
USA |
1637 |
69.07 |
| $70K - $90K |
USA |
1146 |
67.06 |
| $90K - $110K |
USA |
424 |
69.17 |
#Trực quan hóa cho mối quan hệ giữa 2 biến
ggplot(bang3, aes(x = Country, y = Percentage, fill = AnnualIncome)) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = "Hình 13: Mối quan hệ giữa AnnualIncome và Country",
x = "Quốc gia", y = "Tỷ lệ (%)", fill = "Thu nhập hàng tháng") +
theme_minimal()

Dựa trên bảng thống kê và biểu đồ trực quan, có thể nhận thấy sự phân
bố thu nhập hàng năm (AnnualIncome) giữa các quốc gia là rất khác biệt.
Tại Hoa Kỳ, tỷ lệ người tiêu dùng trong tất cả các nhóm thu nhập đều
chiếm tỷ lệ áp đảo, dao động từ khoảng 64% đến gần 74%, cho thấy phần
lớn người tiêu dùng trong tập dữ liệu đến từ Mỹ và có mức thu nhập khá
cao. Trong khi đó, tại Canada, tỷ lệ ở từng nhóm thu nhập chỉ dao động
từ khoảng 4% đến 7%, thấp hơn đáng kể. Mexico có tỷ lệ phân bố cao hơn
Canada, dao động từ 20% đến gần 28% ở các nhóm thu nhập, phản ánh số
lượng người tiêu dùng vừa phải và thu nhập tập trung vào nhóm trung
bình. Biểu đồ cột cũng thể hiện rõ ràng sự chênh lệch này, với các cột
biểu thị cho Mỹ luôn cao hơn đáng kể so với hai quốc gia còn lại ở tất
cả các nhóm thu nhập. Như vậy, có thể kết luận rằng Hoa Kỳ là thị trường
có tỷ trọng người tiêu dùng cao và thu nhập ổn định hơn, trong khi
Canada có tỷ trọng thấp hơn rõ rệt.
LS0tDQp0aXRsZTogIk5ISeG7hk0gVuG7pCAyIg0KYXV0aG9yOiAiTmd1eeG7hW4gUGjhuqFtIFRow7p5IEFuIC0gMjIyMTAwMDI5MCINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVIOiVNOiVTLCAlZCAtICVtIC0gJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQogICAgbnVtYmVyIHNlY3Rpb246IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPg0KX19fDQoNCiMgKipQSOG6pk4gMTogVMOMTSBISeG7glUgVsOAIENIVeG6qE4gQuG7iiBE4buuIExJ4buGVSoqDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShrbml0cikNCmBgYA0KDQoNCmBgYHtyfQ0KZGF0YSA8LSByZWFkLmNzdihmaWxlID0gIkM6L1VzZXJzL0FkbWluL0Rvd25sb2Fkcy9TdXBlcm1hcmtldCBUcmFuc2FjdGlvbnMuY3N2IiwgaGVhZGVyID0gVCkNCg0KI2hp4buDbiB0aOG7iyBj4bqldSB0csO6YyBk4buvIGxp4buHdQ0Kc3RyKGRhdGEpDQpgYGANCg0KROG7ryBsaeG7h3UgKlN1cGVybWFya2V0IFRyYW5zYWN0aW9ucyogbMOgIG3hu5l0IGLhu5kgZOG7ryBsaeG7h3UgYmFvIGfhu5NtIDE0MDU5IHF1YW4gc8OhdCB2w6AgMTYgYmnhur9uLCBj4bulIHRo4buDOg0KDQoqIDQgZOG7ryBsaeG7h3UgbMOgICoqc+G7kSBuZ3V5w6puIChpbnQpKiogYmFvIGfhu5NtOiBT4buRIHRo4bupIHThu7EgKFgpLCBtw6Mga2jDoWNoIGjDoG5nIChDdXN0b21lciBJRCksIFPhu5EgY29uIGPDoWkgKENoaWxyZW4pLCBEb2FuaCBz4buRIGLDoW4gaMOgbmcgdGhlbyDEkcahbiB24buLIChVbml0cyBTb2xkKS4NCg0KKiAxIGThu68gbGnhu4d1IGzDoCAqKnPhu5EgKG51bSkqKiwgYmFvIGfhu5NtOiBEb2FuaCB0aHUgKFJldmVudWUpLg0KDQoqIDExIGThu68gbGnhu4d1IGzDoCAqKmNodeG7l2kga8OtIHThu7EgKGNocikqKiwgYmFvIGfhu5NtOiBuZ8OgeSBtdWEgaMOgbmcgKFB1cmNoYXNlIERhdGUpLCBnaeG7m2kgdMOtbmggKEdlbmRlciksIHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiAoTWFyaXRhbCBTdGF0dXMpLCBz4bufIGjhu691IG5ow6AgcmnDqm5nIChIb21lb3duZXIpLCB0aHUgbmjhuq1wIGjDoG5nIG7Eg20gKEFubnVhbCBJbmNvbWUpLCB0aMOgbmggcGjhu5EgKGNpdHkpLCBtw6MgYmFuZyAoU3RhdGVvciBQcm92aW5jZSksIMSR4bqldCBuxrDhu5tjIChjb3VudHJ5KSwgbmjDs20gc+G6o24gcGjhuqltIChQcm9kdWN0IEZhbWlseSksIG5ow7NtIHPhuqNuIHBo4bqpbSBjaGkgdGnhur90IChQcm9kdWN0IERlcGFydG1lbnQpIHbDoCBkYW5oIG3hu6VjIHPhuqNuIHBo4bqpbSAoUHJvZHVjdCBDYXRlZ29yeSkuDQoNClRyb25nIMSRw7MsIGPDoWMgYmnhur9uIMSR4buLbmggdMOtbmggbMOgOg0KDQoqICoqR2VuZGVyKio6IEdp4bubaSB0w61uaCwgRiAoRmVtYWxlKSAtIG7hu68gdsOgIE0gKE1hbGUpIC0gbmFtDQoNCiogKipNYXJpdGFsU3RhdHVzKio6IFTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiwgUyAoU2luZ2xlKSAtIMSR4buZYyB0aMOibiB2w6AgTShNYXJyaWVkKSAtIMSRw6Mga+G6v3QgaMO0bg0KDQoqICoqSG9tZW93bmVyKio6IFPhu58gaOG7r3UgbmjDoCByacOqbmcsIFkgKFllcykgLSDEkcOjIGPDsyBuaMOgIHbDoCBOIChObykgLSBjaMawYSBjw7MgbmjDoA0KDQoqICoqQW5udWFsSW5jb21lKio6IFRodSBuaOG6rXAgaMOgbmcgbsSDbQ0KDQoqICoqQ2l0eSoqOiBUaMOgbmggcGjhu5EgxJFhbmcgc+G7kW5nDQoNCiogKipTdGF0ZW9yUHJvdmluY2UqKjogTcOjIGvDrSBoaeG7h3UgY+G7p2EgYmFuZw0KDQoqICoqQ291bnRyeSoqOiDEkOG6pXQgbsaw4bubYw0KDQoqICoqUHJvZHVjdEZhbWlseSoqOiBOaMOzbSBz4bqjbiBwaOG6qW0sIEZvb2Q6IFRo4buxYyBwaOG6qW0sIERyaW5rOiDEkOG7kyB14buRbmcgdsOgIE5vbi1Db25zdW1hYmxlOiBIw6BuZyBraMO0bmcgdGnDqnUgZMO5bmcNCg0KKiAqKlByb2R1Y3REZXBhcnRtZW50Kio6IE5ow7NtIHPhuqNuIHBo4bqpbSBjaGkgdGnhur90DQoNCiogKipQcm9kdWN0Q2F0ZWdvcnkqKjogRGFuaCBt4bulYyBz4bqjbiBwaOG6qW0NCg0KYGBge3J9DQojaGnhu4NuIHRo4buLIG3hu5l0IHbDoGkgZMOybmcgxJHhuqd1DQpoZWFkKGRhdGEpDQoNCiNoaeG7g24gdGjhu4sgbeG7mXQgdsOgaSBkw7JuZyBjdeG7kWkNCnRhaWwoZGF0YSkNCmBgYA0KDQpgYGB7cn0NCiNjw6FjIGJp4bq/biDEkeG7i25oIHTDrW5oIGPhuqduIGtp4buDbSB0cmEgZOG7ryBsaeG7h3UgTkENCmRpbmh0aW5oIDwtIGMoJ0dlbmRlcicsICdNYXJpdGFsU3RhdHVzJywgJ0hvbWVvd25lcicsICdBbm51YWxJbmNvbWUnLCAnQ2l0eScsICdTdGF0ZW9yUHJvdmluY2UnLCAnQ291bnRyeScsICdQcm9kdWN0RmFtaWx5JywgJ1Byb2R1Y3REZXBhcnRtZW50JywgJ1Byb2R1Y3RDYXRlZ29yeScpDQpkYXRhX2Rpbmh0aW5oIDwtIGRhdGFbLGRpbmh0aW5oXQ0KDQoja2nhu4NtIHRyYSBk4buvIGxp4buHdSBOQSBj4bunYSBjw6FjIGJp4bq/biDEkeG7i25oIHTDrW5oDQpzdW0oaXMubmEoZGF0YV9kaW5odGluaCkpDQoNCmNvbFN1bXMoaXMubmEoZGF0YV9kaW5odGluaCkpDQpgYGANCg0KS+G6v3QgcXXhuqMgdHLhuqMgduG7gSBjaG8gdGEgdGjhuqV5IHLhurFuZywgduG7m2kgMTAgZOG7ryBsaeG7h3UgxJHhu4tuaCB0w61uaCwga2jDtG5nIGPDsyBk4buvIGxp4buHdSB0cuG7kW5nIChOQSkuDQoNClNhdSDEkcOzLCBjaMO6bmcgdGEgc+G6vSBraeG7g20gdHJhIHhlbSBjw6FjIGJp4bq/biDEkeG7i25oIHTDrW5oIGPDsyBwaOG6o2kgbMOgIGZhY3RvciBoYXkga2jDtG5nLiBO4bq/dSBjaMO6bmcga2jDtG5nIHBo4bqjaSBsw6AgZmFjdG9yIHRow6wgdGEgc+G6vSBjaHV54buDbiDEkeG7lWkgY2jDum5nIHNhbmcgZOG6oW5nIGZhY3Rvci4gIA0KDQpgYGB7cn0NCiNraeG7g20gdHJhIGPDoWMgYmnhur9uIMSR4buLbmggdMOtbmggY8OzIHBo4bqjaSBsw6AgZmFjdG9yIGhheSBjaMawYQ0KY2F0KCJLaeG7g20gdHJhIGZhY3RvciBj4bunYSB04burbmcgYmnhur9uIFxuIikNCg0KZm9yIChpIGluIDE6bmNvbChkYXRhX2Rpbmh0aW5oKSkgew0KICBhIDwtIGlzLmZhY3RvcihkYXRhX2Rpbmh0aW5oWyxpXSkNCiAgY2F0KGNvbG5hbWVzKGRhdGFfZGluaHRpbmgpW2ldLCI6IixhLCJcbiIpDQp9DQpgYGANCg0KS+G6v3QgcXXhuqMga2nhu4NtIHRyYSBjaG8gdGEgdGjhuqV5IHLhurFuZywgMTAgYmnhur9uIMSR4buLbmggdMOtbmggxJFhbmcga2jDtG5nIHBo4bqjaSBsw6AgZmFjdG9yLiBWw6wgduG6rXksIHRhIHRp4bq/biBow6BuaCBjaHV54buDbiAxMCBiaeG6v24gbsOgeSB24buBIGThuqFuZyBmYWN0b3IsIG5oxrAgc2F1Og0KDQpgYGB7cn0NCiMgQ2h1eeG7g24gduG7gSBk4bqhbmcgZmFjdG9yIA0KDQpmb3IgKGkgaW4gMTpuY29sKGRhdGFfZGluaHRpbmgpKSB7DQogIGRhdGFfZGluaHRpbmhbLGldIDwtIGFzLmZhY3RvcihkYXRhX2Rpbmh0aW5oWyxpXSkNCn0NCg0KIyBLaeG7g20gdHJhIGzhuqFpIA0KY2F0KCJLaeG7g20gdHJhIGzhuqFpIGZhY3RvciBj4bunYSB04burbmcgYmnhur9uIFxuIikNCmZvciAoaSBpbiAxOm5jb2woZGF0YV9kaW5odGluaCkpIHsNCiAgYSA8LSBpcy5mYWN0b3IoZGF0YV9kaW5odGluaFssaV0pDQogIGNhdChjb2xuYW1lcyhkYXRhX2Rpbmh0aW5oKVtpXSwiOiIsYSwiXG4iKQ0KfQ0KDQpgYGANCg0KTMO6YyBuw6B5LCBr4bq/dCBxdeG6oyDEkcOjIGNobyByYSAxMCBiaeG6v24gxJHhu4tuaCB0w61uaCDEkcOjIGzDoCBmYWN0b3IuIFZp4buHYyBjaHV54buDbiDEkeG7lWkgbsOgeSBz4bq9IGdpw7pwIFIgaGnhu4N1IHLDtSBi4bqjbiBjaOG6pXQgY+G7p2EgYmnhur9uIHBow6JuIGxv4bqhaSB2w6AgaOG7lyB0cuG7oyB04buRdCBoxqFuIGNobyBxdcOhIHRyw6xuaCB0cuG7sWMgcXVhbiBow7NhIGThu68gbGnhu4d1Lg0KDQpfX18NCg0KIyAqKlBI4bqmTiAyOiBQSMOCTiBUw41DSCBNw5QgVOG6oiBN4buYVCBCSeG6vk4gxJDhu4pOSCBUw41OSCoqDQoNCiMjICoqMi4xLiBCaeG6v24gR2VuZGVyIChnaeG7m2kgdMOtbmgpKioNCg0KxJDhuqd1IHRpw6puIGNow7puZyB0YSBz4bq9IHThuqFvIGLhuqNuZyBtw7QgdOG6oyB0aOG7kW5nIGvDqiBj4bunYSBiaeG6v24gKioqR2VuZGVyKioqIGJhbyBn4buTbSAqdOG6p24gc3XhuqV0KiB2w6AgKnBo4bqnbiB0csSDbSogbmjGsCBzYXU6DQoNCmBgYHtyfQ0KI1ThuqFvIGLhuqNuZyBtw7QgdOG6oyB0aOG7kW5nIGvDqiBiaeG6v24gR2VuZGVyDQoNCnRhbnN1YXQuZ2VuZGVyIDwtIHRhYmxlKGRhdGEkR2VuZGVyKQ0KcGhhbnRyYW0uZ2VuZGVyIDwtIHByb3AudGFibGUodGFuc3VhdC5nZW5kZXIpICogMTAwDQoNCmdlbmRlciA8LSBkYXRhLmZyYW1lKEdlbmRlciA9IG5hbWVzKHRhbnN1YXQuZ2VuZGVyKSwgVGFuU3VhdCA9IGFzLnZlY3Rvcih0YW5zdWF0LmdlbmRlciksIFBoYW5UcmFtID0gYXMudmVjdG9yKHBoYW50cmFtLmdlbmRlcikpDQoNCmthYmxlKGdlbmRlciwgY2FwdGlvbiA9ICJC4bqjbmcgMTogTcO0IHThuqMgdGjhu5FuZyBrw6ogY+G7p2EgYmnhur9uIEdlbmRlciIpDQpgYGANCg0KVGnhur9wIMSR4bq/biwgY2jDum5nIHRhIHRp4bq/cCB04bulYyB24bq9IGJp4buDdSDEkeG7kyDEkeG7gyBjw7MgdGjhu4MgdHLhu7FjIHF1YW4gaMOzYSBk4buvIGxp4buHdSB04buRdCBoxqFuOg0KDQpgYGB7cn0NCiMgQmnhu4N1IMSR4buTIGJp4bq/biBHZW5kZXINCg0KZGF0YSAlPiUgZ3JvdXBfYnkoR2VuZGVyKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBtdXRhdGUocGVyY2VudGFnZSA9IG4gLyBzdW0obikgKiAxMDApICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSAnJywgeSA9IG4sZmlsbCA9IEdlbmRlcikpICsNCiAgICBnZW9tX2NvbChjb2xvciA9ICdibGFjaycpICsNCiAgICBjb29yZF9wb2xhcigneScpICsNCiAgICBnZW9tX3RleHQoYWVzKHggPSAxLjMsIGxhYmVsID0gcGFzdGUocm91bmQocGVyY2VudGFnZSwgMSksICIlIikpLHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAuNSkpICsNCiAgICB0aGVtZV92b2lkKCkgKw0KIGxhYnModGl0bGUgPSAnSMOsbmggMTogQmnhu4N1IMSR4buTIHRyw7JuIHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGtow6FjaCB0aGVvIGdp4bubaSB0w61uaCcsIHggPSAnICcsIHkgPSAnICcpDQpgYGANCg0KS+G6v3QgcXXhuqMgdOG7qyAqKmLhuqNuZyAxKiogdsOgICoqaMOsbmggMSoqIGNobyB0aOG6pXkgY8OzIDcuMTcwIGtow6FjaCBow6BuZyBu4buvIChjaGnhur9tIDUxJSkgdsOgIDYuODg5IGtow6FjaCBow6BuZyBuYW0gKGNoaeG6v20gNDklKS4gQ+G7rWEgaMOgbmcgbmjhuq1uIMSRxrDhu6NjIHPhu7Eg4bunbmcgaOG7mSBuaGnhu4F1IGjGoW4gdOG7qyBraMOhY2ggaMOgbmcgbuG7rywgbmjGsG5nIHPhu7Ega2jDoWMgYmnhu4d0IGdp4buvYSBoYWkgZ2nhu5tpIHTDrW5oIGzDoCBraMO0bmcgbOG7m24sIGNo4buJIGtob+G6o25nIDIlLg0KDQpfX18gDQoNCiMjICoqMi4yLiBCaeG6v24gTWFyaXRhbFN0YXR1cyAoVMOsbmggdHLhuqFuZyBow7RuIG5ow6JuKSoqDQoNCmBgYHtyfQ0KI1ThuqFvIGLhuqNuZyBtw7QgdOG6oyB0aOG7kW5nIGvDqiBiaeG6v24gTWFyaXRhbFN0YXR1cyANCg0KdGFuc3VhdC5tYXJpdGFsLnN0YXR1cyA8LSB0YWJsZShkYXRhJE1hcml0YWxTdGF0dXMpDQpwaGFudHJhbS5tYXJpdGFsLnN0YXR1cyA8LSBwcm9wLnRhYmxlKHRhbnN1YXQubWFyaXRhbC5zdGF0dXMpICogMTAwDQoNCm1hcml0YWwuc3RhdHVzIDwtIGRhdGEuZnJhbWUoTWFyaXRhbFN0YXR1cyA9IG5hbWVzKHRhbnN1YXQubWFyaXRhbC5zdGF0dXMpLCBUYW5TdWF0ID0gYXMudmVjdG9yKHRhbnN1YXQubWFyaXRhbC5zdGF0dXMpLCBQaGFuVHJhbSA9IGFzLnZlY3RvcihwaGFudHJhbS5tYXJpdGFsLnN0YXR1cykpDQoNCmthYmxlKG1hcml0YWwuc3RhdHVzLCBjYXB0aW9uID0gIkLhuqNuZyAyOiBNw7QgdOG6oyB0aOG7kW5nIGvDqiBj4bunYSBiaeG6v24gTWFyaXRhbFN0YXR1cyIpDQoNCiMgQmnhu4N1IMSR4buTIGJp4bq/biBNYXJpdGFsU3RhdHVzIA0KDQpkYXRhICU+JSBncm91cF9ieShNYXJpdGFsU3RhdHVzICkgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUNCiAgbXV0YXRlKHBlcmNlbnRhZ2UgPSBuIC8gc3VtKG4pICogMTAwKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gJycsIHkgPSBuLGZpbGwgPSBNYXJpdGFsU3RhdHVzKSkgKw0KICAgIGdlb21fY29sKGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGNvb3JkX3BvbGFyKCd5JykgKw0KICAgIGdlb21fdGV4dChhZXMoeCA9IDEuMywgbGFiZWwgPSBwYXN0ZShyb3VuZChwZXJjZW50YWdlLCAxKSwgIiUiKSkscG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IC41KSkgKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIk0iID0gIiM3RkZGRDQiLCAiUyIgPSAiI0NBRkY3MCIpKSArDQogICAgdGhlbWVfdm9pZCgpICsNCiBsYWJzKHRpdGxlID0gJ0jDrG5oIDI6IEJp4buDdSDEkeG7kyB0csOybiB0aOG7gyBoaeG7h24gdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIGPhu6dhIG3hu5dpIGtow6FjaCBow6BuZycsIHggPSAnICcsIHkgPSAnICcpDQpgYGANCg0KVOG7qyBr4bq/dCBxdeG6oyBj4bunYSAqKipi4bqjbmcgMioqKiB2w6AgKioqaMOsbmggMioqKiBjaG8gdGjhuqV5IHLhurFuZywgdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIGPhu6dhIGtow6FjaCBow6BuZyBwaMOibiBi4buRIGtow6EgxJHhu5NuZyDEkeG7gXUgZ2nhu69hIGhhaSBuaMOzbSDEkcOjIGvhur90IGjDtG4gKE0pIHbDoCDEkeG7mWMgdGjDom4gKFMpLiBD4bulIHRo4buDLCBuaMOzbSDEkeG7mWMgdGjDom4gY2hp4bq/bSB04bu3IGzhu4cgbmjhu4luaCBoxqFuIHbhu5tpIDcxOTMgbmfGsOG7nWkgKDUxLjIlKSwgdHJvbmcga2hpIG5ow7NtIMSRw6Mga+G6v3QgaMO0biBsw6AgNjg2NiBuZ8aw4budaSAoNDguOCUpLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSBy4bqxbmcga2jDtG5nIGPDsyBz4buxIGNow6puaCBs4buHY2ggbOG7m24gZ2nhu69hIGhhaSBuaMOzbSB24buBIG3hurd0IHPhu5EgbMaw4bujbmcsIHR1eSBuaGnDqm4gdmnhu4djIG5ow7NtIMSR4buZYyB0aMOibiBjaGnhur9tIHThu7cgbOG7hyBjYW8gaMahbiBt4buZdCBjaMO6dCBjw7MgdGjhu4MgZ+G7o2kgw70gcuG6sW5nIMSR4buRaSB0xrDhu6NuZyBraMOhY2ggaMOgbmcgY2jGsGEgbOG6rXAgZ2lhIMSRw6xuaCDEkWFuZyBjaGnhur9tIMawdSB0aOG6vyBuaOG6uSB0cm9uZyB04buHcCBraMOhY2ggaMOgbmcgaGnhu4duIHThuqFpLg0KDQpfX18NCg0KIyMgKioyLjMuIEJp4bq/biBIb21lb3duZXIgKFPhu58gaOG7r3UgbmjDoCByacOqbmcpKioNCg0KYGBge3J9DQojVOG6oW8gYuG6o25nIG3DtCB04bqjIHRo4buRbmcga8OqIGJp4bq/biBIb21lb3duZXINCg0KdGFuc3VhdC5ob21lb3duZXIgPC0gdGFibGUoZGF0YSRIb21lb3duZXIpDQoNCmthYmxlKHRhbnN1YXQuaG9tZW93bmVyLCBjYXB0aW9uID0gIkLhuqNuZyAzOiBNw7QgdOG6oyB0aOG7kW5nIGvDqiBj4bunYSBiaeG6v24gSG9tZW93bmVyIikNCg0KIyBCaeG7g3UgxJHhu5MgYmnhur9uIEhvbWVvd25lciANCg0KZGF0YSAlPiUgZ3JvdXBfYnkoSG9tZW93bmVyKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBtdXRhdGUocGVyY2VudGFnZSA9IG4gLyBzdW0obikgKiAxMDApICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSAnJywgeSA9IG4sZmlsbCA9IEhvbWVvd25lcikpICsNCiAgICBnZW9tX2NvbChjb2xvciA9ICdibGFjaycpICsNCiAgICBjb29yZF9wb2xhcigneScpICsNCiAgICBnZW9tX3RleHQoYWVzKHggPSAxLjMsIGxhYmVsID0gcGFzdGUwKHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSIpKSxwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gLjUpKSArDQogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiWSIgPSAicGluayIsICJOIiA9ICJsaWdodGdyZWVuIikpICsgDQogICAgdGhlbWVfdm9pZCgpICsNCiBsYWJzKHRpdGxlID0gJ0jDrG5oIDM6IEJp4buDdSDEkeG7kyB0csOybiB0aOG7gyBoaeG7h24gdMOsbmggdHLhuqFuZyBz4bufIGjhu691IG5ow6AgcmnDqm5nIGPhu6dhIG3hu5dpIGtow6FjaCBow6BuZycsIHggPSAnICcsIHkgPSAnICcpDQpgYGANCg0KS+G6v3QgcXXhuqMgdGjhu5FuZyBrw6ogY2hvIGJp4bq/biBIb21lb3duZXIgdOG7qyAqKipi4bqjbmcgMyoqKiB2w6AgKioqaMOsbmggMyoqKiBjaG8gdGjhuqV5IHLhurFuZyBjw7MgNjAsMSUga2jDoWNoIGjDoG5nIHPhu58gaOG7r3UgbmjDoCByacOqbmcsIHRyb25nIGtoaSAzOSw5JSBjw7JuIGzhuqFpIGtow7RuZyBz4bufIGjhu691IG5ow6AuIFThu7cgbOG7hyBz4bufIGjhu691IG5ow6AgY2FvIGjGoW4gY2hvIHRo4bqleSBwaOG6p24gbOG7m24ga2jDoWNoIGjDoG5nIHRyb25nIHThuq1wIGThu68gbGnhu4d1IGPDsyBt4bupYyDEkeG7mSDhu5VuIMSR4buLbmggbmjhuqV0IMSR4buLbmggduG7gSBt4bq3dCB0w6BpIGNow61uaCBob+G6t2MgxJFhbmcg4bufIGdpYWkgxJFv4bqhbiDEkeG7nWkgc+G7kW5nIMSRw6MgdMOtY2ggbMWpeSDEkcaw4bujYyB0w6BpIHPhuqNuIGPhu5EgxJHhu4tuaC4gxJBp4buBdSBuw6B5IGPDsyB0aOG7gyBsw6AgeeG6v3UgdOG7kSDhuqNuaCBoxrDhu59uZyDEkeG6v24gaMOgbmggdmkgdGnDqnUgZMO5bmcsIG5odSBj4bqndSB2YXkgduG7kW4gaG/hurdjIHh1IGjGsOG7m25nIMSR4bqndSB0xrAgdMOgaSBjaMOtbmggY+G7p2EgaOG7jS4gDQoNCl9fXw0KDQojIyAqKjIuNC4gQmnhur9uIEFubnVhbEluY29tZSAoVGh1IG5o4bqtcCBow6BuZyBuxINtKSoqDQoNCmBgYHtyfQ0KI1ThuqFvIGLhuqNuZyBtw7QgdOG6oyB0aOG7kW5nIGvDqiBiaeG6v24gQW5udWFsSW5jb21lDQp0YW5zdWF0LmFubnVhbGluY29tZSA8LSB0YWJsZShkYXRhJEFubnVhbEluY29tZSkNCg0Ka2FibGUodGFuc3VhdC5hbm51YWxpbmNvbWUsIGNhcHRpb24gPSAiQuG6o25nIDQ6IE3DtCB04bqjIHRo4buRbmcga8OqIGPhu6dhIGJp4bq/biBBbm51YSBJbmNvbWUiKQ0KDQojIEJp4buDdSDEkeG7kyBiaeG6v24gSG9tZW93bmVyDQoNCmNvdW50cyA8LSBkYXRhICU+JSANCiAgZ3JvdXBfYnkoQW5udWFsSW5jb21lKSAlPiUgDQogIHN1bW1hcmlzZShDb3VudCA9IG4oKSkNCg0KZ2dwbG90KGNvdW50cywgYWVzKHggPSBBbm51YWxJbmNvbWUsIHkgPSBDb3VudCkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAnc2t5Ymx1ZScpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgdmp1c3QgPSAtMC41LCBzaXplID0gNCkgKyAgDQogIGxhYnMoDQogICAgdGl0bGUgPSAiSMOsbmggNDogQmnhu4N1IMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiB0aHUgbmjhuq1wIGjDoG5nIG7Eg20iLA0KICAgIHggPSAnVGh1IG5o4bqtcCBow6BuZyBuxINtJywNCiAgICB5ID0gJ1Phu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nJw0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KUGjDom4gYuG7kSB0aHUgbmjhuq1wIGjDoG5nIG7Eg20gY+G7p2Ega2jDoWNoIGjDoG5nIHRyb25nICoqKmLhuqNuZyA0KioqIHbDoCAqKipow6xuaCA0KioqIGNobyB0aOG6pXkgc+G7sSBwaMOibiBi4buRIHRodSBuaOG6rXAgaMOgbmcgbsSDbSBj4bunYSBraMOhY2ggaMOgbmcgduG7m2kgc+G7sSBjaMOqbmggbOG7h2NoIHLDtSBy4buHdCBnaeG7r2EgY8OhYyBuaMOzbS4gTmjDs20gdGh1IG5o4bqtcCB04burICoqJDMwSyAtICQ1MEsqKiBjaGnhur9tIMawdSB0aOG6vyB2xrDhu6N0IHRy4buZaSB24bubaSAqKjQsNjAxIGtow6FjaCBow6BuZyoqLCBn4bqlcCBuaGnhu4F1IGzhuqduIHNvIHbhu5tpIGPDoWMgbmjDs20ga2jDoWMuIFRoZW8gc2F1IGzDoCBuaMOzbSAqKiQxMEsgLSAkMzBLKiogdsOgICoqJDUwSyAtICQ3MEsqKi4gTmfGsOG7o2MgbOG6oWksIG5ow7NtIHRodSBuaOG6rXAgdHLDqm4gKiokMTUwSyoqIGPDsyBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyB0aOG6pXAgbmjhuqV0IChjaOG7iSAqKjI3MyBuZ8aw4budaSoqKS4gQmnhu4N1IMSR4buTIGNobyB0aOG6pXkgcGjDom4ga2jDumMga2jDoWNoIGjDoG5nIGNo4bunIHnhur91IHThuq1wIHRydW5nIOG7nyBt4bupYyB0aHUgbmjhuq1wIHRydW5nIGLDrG5oIOKAkyB0aOG6pXAsIHBo4bqjbiDDoW5oIHh1IGjGsOG7m25nIHBo4buVIGJp4bq/biB0cm9uZyBk4buvIGxp4buHdSBuw6B5Lg0KDQpfX18NCg0KIyMgKioyLjUuIEJp4bq/biBDaXR5IChUaMOgbmggcGjhu5EpKioNCg0KYGBge3J9DQojVOG6oW8gYuG6o25nIG3DtCB04bqjIHRo4buRbmcga8OqIGJp4bq/biBDaXR5DQoNCnRhbnN1YXQuY2l0eSA8LSB0YWJsZShkYXRhJENpdHkpDQpwaGFudHJhbS5jaXR5IDwtIHByb3AudGFibGUodGFuc3VhdC5jaXR5KSAqIDEwMA0KDQpiYW5nLmNpdHkgPC0gZGF0YS5mcmFtZSgNCiAgQ2l0eSA9IG5hbWVzKHRhbnN1YXQuY2l0eSksDQogIEZyZXF1ZW5jeSA9IGFzLnZlY3Rvcih0YW5zdWF0LmNpdHkpLA0KICBQZXJjZW50YWdlID0gcm91bmQoYXMudmVjdG9yKHBoYW50cmFtLmNpdHkpLCAyKQ0KKQ0KICANCmthYmxlKGJhbmcuY2l0eSwgY2FwdGlvbiA9ICJC4bqjbmcgNTogTcO0IHThuqMgdGjhu5FuZyBrw6ogY+G7p2EgYmnhur9uIENpdHkiKQ0KDQojIEJp4buDdSDEkeG7kyBiaeG6v24gQ2l0eQ0KDQpjb3VudHMgPC0gZGF0YSAlPiUgDQogIGdyb3VwX2J5KENpdHkpICU+JSANCiAgc3VtbWFyaXNlKENvdW50ID0gbigpKQ0KDQpnZ3Bsb3QoY291bnRzLCBhZXMoeCA9IENpdHksIHkgPSBDb3VudCkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAnZGFya29yYW5nZScpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgdmp1c3QgPSAtMC41LCBzaXplID0gNCkgKyAgDQogIGxhYnMoDQogICAgdGl0bGUgPSAiSMOsbmggNDogQmnhu4N1IMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiB0aHUgbmjhuq1wIGjDoG5nIG7Eg20iLA0KICAgIHggPSAnVGh1IG5o4bqtcCBow6BuZyBuxINtJywNCiAgICB5ID0gJ1Phu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nJw0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQpCaeG7g3UgxJHhu5MgY2hvIHRo4bqleSBz4buxIHBow6JuIGLhu5Egc+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmcgdGhlbyB04burbmcgdGjDoG5oIHBo4buRIHbhu5tpIHPhu7EgY2jDqm5oIGzhu4djaCByw7UgcuG7h3QuICoqU2FuIEFudG9uaW8qKiBsw6AgdGjDoG5oIHBo4buRIGPDsyBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyBjYW8gbmjhuqV0ICgqKjEuMzg2IG5nxrDhu51pKiopLCB0aGVvIHNhdSBsw6AgKipUYWNvbWEqKiAoKioxLjI1NyBuZ8aw4budaSoqKSB2w6AgKipNZXJpZGEqKiAoKio5MjYgbmfGsOG7nWkqKikuIFRyb25nIGtoaSDEkcOzLCBt4buZdCBz4buRIHRow6BuaCBwaOG7kSBuaMawICoqR3VhZGFsYWphcmEqKiwgKipZYWtpbWEqKiB2w6AgKipXYWxsYSBXYWxsYSoqIGPDsyBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyBy4bqldCB0aOG6pXAsIGTGsOG7m2kgKio0MDAgbmfGsOG7nWkqKi4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgZOG7ryBsaeG7h3UgdOG6rXAgdHJ1bmcgbeG6oW5oIOG7nyBt4buZdCBz4buRIMSRw7QgdGjhu4sgbOG7m24sIGPDsm4gbmhp4buBdSB0aMOgbmggcGjhu5Ega2jDoWMgY2jhu4kgY2hp4bq/bSB04bu3IHRy4buNbmcgbmjhu48uIFBow6JuIGLhu5Ega2jDtG5nIMSR4buTbmcgxJHhu4F1IG7DoHkgY8OzIHRo4buDIHBo4bqjbiDDoW5oIMSR4bq3YyDEkWnhu4NtIGTDom4gc+G7kSBob+G6t2MgbeG7qWMgxJHhu5kgdGnhur9wIGPhuq1uIGThu4tjaCB24bulIOG7nyB04burbmcga2h1IHbhu7FjLg0KDQpfX18NCg0KIyMgKioyLjYuIEJp4bq/biBTdGF0ZW9yUHJvdmluY2UgKE3DoyBrw60gaGnhu4d1IGPhu6dhIGJhbmcpKioNCg0KYGBge3J9DQojVOG6oW8gYuG6o25nIG3DtCB04bqjIHRo4buRbmcga8OqIGJp4bq/biBTdGF0ZW9yUHJvdmluY2UNCg0KdGFuc3VhdC5zdGF0ZW9ycHJvdmluY2UgPC0gdGFibGUoZGF0YSRTdGF0ZW9yUHJvdmluY2UpDQpwaGFudHJhbS5zdGF0ZW9ycHJvdmluY2UgPC0gcHJvcC50YWJsZSh0YW5zdWF0LnN0YXRlb3Jwcm92aW5jZSkgKiAxMDANCiAgDQpiYW5nLnN0YXRlb3Jwcm92aW5jZSA8LSBkYXRhLmZyYW1lKA0KICBzdGF0ZW9ycHJvdmluY2UgPSBuYW1lcyh0YW5zdWF0LnN0YXRlb3Jwcm92aW5jZSksDQogIEZlcXVlbmN5ID0gYXMudmVjdG9yKHRhbnN1YXQuc3RhdGVvcnByb3ZpbmNlKSwNCiAgICBQZXJjZW50YWdlID0gcm91bmQoYXMudmVjdG9yKHBoYW50cmFtLnN0YXRlb3Jwcm92aW5jZSksIDIpDQopDQogICAgDQprYWJsZShiYW5nLnN0YXRlb3Jwcm92aW5jZSwgY2FwdGlvbiA9ICJC4bqjbmcgNjogTcO0IHThuqMgdGjhu5FuZyBrw6ogY+G7p2EgYmnhur9uIFN0YXRlb3IgUHJvdmluY2UiKQ0KDQojIEJp4buDdSDEkeG7kyBiaeG6v24gU3RhdGVvclByb3ZpbmNlDQoNCmNvdW50cyA8LSBkYXRhICU+JSANCiAgZ3JvdXBfYnkoU3RhdGVvclByb3ZpbmNlKSAlPiUgDQogIHN1bW1hcmlzZShDb3VudCA9IG4oKSkNCiAgDQpnZ3Bsb3QoY291bnRzLCBhZXMoeCA9IFN0YXRlb3JQcm92aW5jZSwgeSA9IENvdW50KSkgKw0KZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAnbWFyb29uJykgKw0KZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgdmp1c3QgPSAtMC41LCBzaXplID0gNCkgKw0KbGFicygNCiAgdGl0bGUgPSAiSMOsbmggNjogU+G7kSBsxrDhu6NuZyBtw6MgYmFuZyBj4bunYSBt4buXaSBraMOhY2ggaMOgbmciLA0KICB4ID0gIk3DoyBiYW5nIiwNCiAgeSA9ICJT4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyINCikgKw0KdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KQmnhur9uIFN0YXRlb3JQcm92aW5jZSBwaOG6o24gw6FuaCBwaMOibiBi4buRIGtow6FjaCBow6BuZyB0aGVvIG3DoyBiYW5nIGhv4bq3YyB04buJbmguIEThu68gbGnhu4d1IGNobyB0aOG6pXkgc+G7sSBjaMOqbmggbOG7h2NoIMSRw6FuZyBr4buDIHbhu4EgdOG6p24gc3XhuqV0IGtow6FjaCBow6BuZyBnaeG7r2EgY8OhYyBraHUgduG7sWMuIEPhu6UgdGjhu4MsIGJhbmcgV2FzaGluZ3RvbiAoV0EpIGNoaeG6v20gdOG7tyB0cuG7jW5nIGzhu5tuIG5o4bqldCB24bubaSA0LjU2NyBraMOhY2ggaMOgbmcsIHTGsMahbmcg4bupbmcgMzIuNDglIHThu5VuZyBz4buRLCBjaG8gdGjhuqV5IMSRw6J5IGzDoCBraHUgduG7sWMgdOG6rXAgdHJ1bmcgxJHDtG5nIMSR4bqjbyBraMOhY2ggaMOgbmcgbmjhuqV0LiBY4bq/cCBzYXUgbMOgIENhbGlmb3JuaWEgKENBKSB24bubaSAyLjczMyBraMOhY2ggaMOgbmcgKDE5LjQ0JSkgdsOgIE9yZWdvbiAoT1IpIHbhu5tpIDIuMjYyIGtow6FjaCBow6BuZyAoMTYuMDklKS4gQmEgYmFuZyBuw6B5IGNoaeG6v20gdOG7lW5nIGPhu5luZyBn4bqnbiA2OCUgdOG7lW5nIHPhu5Ega2jDoWNoIGjDoG5nLCBjaG8gdGjhuqV5IG3hu6ljIMSR4buZIGhp4buHbiBkaeG7h24gaG/hurdjIGhv4bqhdCDEkeG7mW5nIHRoxrDGoW5nIG3huqFpIHThuq1wIHRydW5nIHThuqFpIMSRw6J5IGzDoCBraMOhIGNhby4NCg0KTmfGsOG7o2MgbOG6oWksIG3hu5l0IHPhu5Ega2h1IHbhu7FjIGPDsyBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyBy4bqldCB0aOG6pXAgbmjGsCBKYWxpc2NvIHbhu5tpIGNo4buJIDc1IG5nxrDhu51pLCB0xrDGoW5nIMSRxrDGoW5nIDAuNTMlLCBoYXkgR3VlcnJlcm8gdsOgIFZlcmFjcnV6IGNo4buJIGNoaeG6v20gbOG6p24gbMaw4bujdCAyLjcyJSB2w6AgMy4zMCUuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IHPhu7EgaGnhu4duIGRp4buHbiBraMOhY2ggaMOgbmcg4bufIG5o4buvbmcgYmFuZyBuw6B5IGPDsm4ga2jDoSBo4bqhbiBjaOG6vy4gQ8OhYyBiYW5nIGPDsm4gbOG6oWkgbmjGsCBCQywgREYsIFl1Y2F0YW4gdsOgIFphY2F0ZWNhcyBkYW8gxJHhu5luZyB04burIGtob+G6o25nIDQuNjUlIMSR4bq/biA5LjIzJSwgcGjhuqNuIMOhbmggbeG7qWMgxJHhu5kgdHJ1bmcgYsOsbmggdHJvbmcgcGjDom4gYuG7kSBraMOhY2ggaMOgbmcuDQoNCl9fXw0KDQojIyAqKjIuNy4gQmnhur9uIENvdW50cnkgKMSQ4bqldCBuxrDhu5tjKSoqDQoNCmBgYHtyfQ0KI1ThuqFvIGLhuqNuZyBtw7QgdOG6oyB0aOG7kW5nIGvDqiBiaeG6v24gQ291bnRyeQ0KDQp0YW5zdWF0LmNvdW50cnkgPC0gdGFibGUoZGF0YSRDb3VudHJ5KQ0Ka2FibGUodGFuc3VhdC5jb3VudHJ5LCBjYXB0aW9uID0gIkLhuqNuZyA3OiBNw7QgdOG6oyB0aOG7kW5nIGvDqiBj4bunYSBiaeG6v24gQ291bnRyeSIpDQoNCiMgQmnhu4N1IMSR4buTIGJp4bq/biBDb3VudHJ5DQoNCmRhdGEgJT4lIGdyb3VwX2J5KENvdW50cnkpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIG11dGF0ZShwZXJjZW50YWdlID0gbiAvIHN1bShuKSAqIDEwMCkgJT4lDQogIGdncGxvdChhZXMoeCA9ICcnLCB5ID0gbixmaWxsID0gQ291bnRyeSkpICsNCiAgICBnZW9tX2NvbChjb2xvciA9ICdibGFjaycpICsNCiAgICBjb29yZF9wb2xhcigneScpICsNCiAgICBnZW9tX3RleHQoYWVzKHggPSAxLjMsIGxhYmVsID0gcGFzdGUwKHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSIpKSxwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gLjUpKSArDQogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiVVNBIiA9ICIjODM2RkZGIiwgIk1leGljbyIgPSAiI0REQTBERCIsICJDYW5hZGEiID0gIiNBRkVFRUUiKSkgKyANCiAgICB0aGVtZV92b2lkKCkgKw0KIGxhYnModGl0bGUgPSAnSMOsbmggNzogQmnhu4N1IMSR4buTIHRyw7JuIHRo4buDIGhp4buHbiDEkeG6pXQgbsaw4bubYyBj4bunYSBt4buXaSBraMOhY2ggaMOgbmcnLCB4ID0gJyAnLCB5ID0gJyAnKQ0KYGBgDQoNClThu6sgKioqYuG6o25nIDcqKiogdsOgICoqKmjDrG5oIDcqKiosIGJp4bq/biBDb3VudHJ5IHBo4bqjbiDDoW5oIHBow6JuIGLhu5Ega2jDoWNoIGjDoG5nIHRoZW8gcXXhu5FjIGdpYS4gS+G6v3QgcXXhuqMgY2hvIHRo4bqleSBraMOhY2ggaMOgbmcgY2jhu6cgeeG6v3UgdOG6rXAgdHJ1bmcgdOG6oWkgSG9hIEvhu7MsIGNoaeG6v20gdOG7m2kgNjglIHThu5VuZyBz4buRIHF1YW4gc8OhdCwgdMawxqFuZyDhu6luZyA5LjU2MiBraMOhY2ggaMOgbmcuIMSQw6J5IGzDoCB04bu3IGzhu4cgdsaw4bujdCB0cuG7mWkgc28gduG7m2kgaGFpIHF14buRYyBnaWEgY8OybiBs4bqhaSwgdGjhu4MgaGnhu4duIHLDtSByw6BuZyB2YWkgdHLDsiB0cnVuZyB0w6JtIGPhu6dhIHRo4buLIHRyxrDhu51uZyBN4bu5IHRyb25nIGThu68gbGnhu4d1Lg0KDQpNZXhpY28gbMOgIHF14buRYyBnaWEgY8OzIGzGsOG7o25nIGtow6FjaCBow6BuZyDEkeG7qW5nIHRo4bupIGhhaSB24bubaSAzLjY4OCBuZ8aw4budaSwgY2hp4bq/bSBraG/huqNuZyAyNi4yJSwgY2hvIHRo4bqleSBz4buxIGhp4buHbiBkaeG7h24ga2jDoSByw7UgbsOpdCBj4bunYSBraMOhY2ggaMOgbmcgdOG6oWkgcXXhu5FjIGdpYSBsw6FuZyBnaeG7gW5nIG7DoHkuIFRyb25nIGtoaSDEkcOzLCBDYW5hZGEgY2jhu4kgxJHDs25nIGfDs3AgODA5IGtow6FjaCBow6BuZywgdMawxqFuZyDhu6luZyA1LjglLCBsw6AgbmjDs20gY2hp4bq/bSB04bu3IHRy4buNbmcgbmjhu48gbmjhuqV0IHRyb25nIGJhIHF14buRYyBnaWEuDQoNCl9fXw0KDQojIyAqKjIuOC4gQmnhur9uIFByb2R1Y3RGYW1pbHkgKE5ow7NtIHPhuqNuIHBo4bqpbSkqKg0KDQpgYGB7cn0NCiNU4bqhbyBi4bqjbmcgbcO0IHThuqMgdGjhu5FuZyBrw6ogYmnhur9uIFByb2R1Y3RGYW1pbHkNCg0KdGFuc3VhdC5wcm9kdWN0ZmFtaWx5IDwtIHRhYmxlKGRhdGEkUHJvZHVjdEZhbWlseSkNCmthYmxlKHRhbnN1YXQucHJvZHVjdGZhbWlseSwgY2FwdGlvbiA9ICJC4bqjbmcgODogTcO0IHThuqMgdGjhu5FuZyBrw6ogY+G7p2EgYmnhur9uIFByb2R1Y3QgRmFtaWx5IikNCg0KIyBCaeG7g3UgxJHhu5MgYmnhur9uIFByb2R1Y3RGYW1pbHkNCg0KZGF0YSAlPiUgZ3JvdXBfYnkoUHJvZHVjdEZhbWlseSkgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUNCiAgbXV0YXRlKHBlcmNlbnRhZ2UgPSBuIC8gc3VtKG4pICogMTAwKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gJycsIHkgPSBuLGZpbGwgPSBQcm9kdWN0RmFtaWx5KSkgKw0KICAgIGdlb21fY29sKGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGNvb3JkX3BvbGFyKCd5JykgKw0KICAgIGdlb21fdGV4dChhZXMoeCA9IDEuMywgbGFiZWwgPSBwYXN0ZTAocm91bmQocGVyY2VudGFnZSwgMSksICIlIikpLHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAuNSkpICsNCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJGb29kIiA9ICIjOThGQjk4IiwgIkRyaW5rIiA9ICIjN0NDRDdDIiwgIk5vbi1Db25zdW1hYmxlIiA9ICIjNTQ4QjU0IikpICsgDQogICAgdGhlbWVfdm9pZCgpICsNCiBsYWJzKHRpdGxlID0gJ0jDrG5oIDg6IEJp4buDdSDEkeG7kyB0csOybiB0aOG7gyBoaeG7h24gbmjDs20gc+G6o24gcGjhuqltIG3DoCBt4buXaSBraMOhY2ggaMOgbmcgbXVhJywgeCA9ICcgJywgeSA9ICcgJykNCmBgYA0KDQpE4buxYSB0csOqbiAqKipi4bqjbmcgOCoqKiB2w6AgKioqaMOsbmggOCoqKiwgdGjhu5FuZyBrw6ogbcO0IHThuqMgY2hvIHRo4bqleSBz4buxIHBow6JuIGLhu5EgcsO1IHLDoG5nIHRyb25nIGPDoWMgZGFuaCBt4bulYyBz4bqjbiBwaOG6qW0gbcOgIGtow6FjaCBow6BuZyDEkcOjIG11YS4gVOG7lW5nIGPhu5luZywgY8OzIDEwLjE1MyBz4bqjbiBwaOG6qW0gdGh14buZYyBuaMOzbSBUaOG7sWMgcGjhuqltIChjaGnhur9tIDcyLDIlKSwgMS4yNTAgc+G6o24gcGjhuqltIHRodeG7mWMgbmjDs20gxJDhu5MgdeG7kW5nICg4LDklKSwgdsOgIDIuNjU2IHPhuqNuIHBo4bqpbSB0aHXhu5ljIG5ow7NtIEtow7RuZyB0acOqdSBkw7luZyAoMTgsOSUpLiBL4bq/dCBxdeG6oyBuw6B5IGNobyB0aOG6pXkgVGjhu7FjIHBo4bqpbSBsw6AgbmjDs20gc+G6o24gcGjhuqltIGNoaeG6v20gxrB1IHRo4bq/IHbGsOG7o3QgdHLhu5lpLCBwaOG6o24gw6FuaCBuaHUgY+G6p3UgaG/hurdjIHPhu58gdGjDrWNoIHRpw6p1IGTDuW5nIHRo4buxYyBwaOG6qW0gY2FvIGPhu6dhIGtow6FjaCBow6BuZy4gVHJvbmcga2hpIMSRw7MsIMSQ4buTIHXhu5FuZyB2w6AgS2jDtG5nIHRpw6p1IGTDuW5nIGPDsyB04bu3IGzhu4cgdGjhuqVwIGjGoW4sIHbhu5tpIG5ow7NtIEtow7RuZyB0acOqdSBkw7luZyBu4buVaSBi4bqtdCBoxqFuIMSQ4buTIHXhu5FuZyBt4buZdCBjaMO6dCwgY8OzIHRo4buDIGRvIHTDrW5oIMSRYSBk4bqhbmcgaG/hurdjIG5odSBj4bqndSB0aGnhur90IHnhur91IGPhu6dhIGPDoWMgc+G6o24gcGjhuqltIGtow7RuZyB0acOqdSBkw7luZyB0cm9uZyDEkeG7nWkgc+G7kW5nIGjDoG5nIG5nw6B5Lg0KDQpfX18NCg0KIyMgKioyLjkuIFByb2R1Y3REZXBhcnRtZW50IChOaMOzbSBz4bqjbiBwaOG6qW0gY2hpIHRp4bq/dCkqKg0KDQpgYGB7cn0NCiNU4bqhbyBi4bqjbmcgbcO0IHThuqMgdGjhu5FuZyBrw6ogYmnhur9uIFByb2R1Y3REZXBhcnRtZW50DQpiYW5nLnByb2R1Y3RkZXBhcnRtZW50IDwtIHRhYmxlKGRhdGEkUHJvZHVjdERlcGFydG1lbnQpDQprYWJsZShiYW5nLnByb2R1Y3RkZXBhcnRtZW50LCBjYXB0aW9uID0gIkLhuqNuZyA5OiBNw7QgdOG6oyB0aOG7kW5nIGvDqiBj4bunYSBiaeG6v24gUHJvZHVjdERlcGFydG1lbnQiKQ0KDQojIEJp4buDdSDEkeG7kyBiaeG6v24gUHJvZHVjdERlcGFydG1lbnQNCg0KY291bnRzIDwtIGRhdGEgJT4lIA0KICBncm91cF9ieShQcm9kdWN0RGVwYXJ0bWVudCkgJT4lIA0KICBzdW1tYXJpc2UoQ291bnQgPSBuKCkpDQogIA0KZ2dwbG90KGNvdW50cywgYWVzKHggPSBQcm9kdWN0RGVwYXJ0bWVudCwgeSA9IENvdW50KSkgKw0KZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAnbGlnaHRibHVlJykgKw0KZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgdmp1c3QgPSAtMC41LCBzaXplID0gNCkgKw0KbGFicygNCiAgdGl0bGUgPSAiSMOsbmggOTogQuG6o25nIMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiBuaMOzbSBz4bqjbiBwaOG6qW0gY2hpIHRp4bq/dCIsDQogIHggPSAibmjDs20gc+G6o24gcGjhuqltIGNoaSB0aeG6v3QiLA0KICB5ID0gIlPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIg0KKSArDQp0aGVtZV9taW5pbWFsKCkgKyANCnRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBz4buxIHBow6JuIGLhu5Egc+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmcgdGhlbyBuaMOzbSBz4bqjbiBwaOG6qW0gY2hpIHRp4bq/dCwgdHJvbmcgxJHDsyBQcm9kdWNlIChyYXUgY+G7pyBxdeG6oykgbMOgIG5ow7NtIMSRxrDhu6NjIG11YSBuaGnhu4F1IG5o4bqldCB24bubaSAxLjk5NCBraMOhY2ggaMOgbmcsIHRoZW8gc2F1IGzDoCBTbmFjayBGb29kcyAoMS42MDAgbmfGsOG7nWkpIHbDoCBIb3VzZWhvbGQgKDEuNDIwIG5nxrDhu51pKS4gTmfGsOG7o2MgbOG6oWksIGPDoWMgbmjDs20gbmjGsCBDYXJvdXNlbCwgQ2hlY2tvdXQsIHbDoCBQZXJpb2RpY2FscyBjw7Mgc+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmcgcuG6pXQgdGjhuqVwLCBkxrDhu5tpIDEwMCBuZ8aw4budaS4gU+G7sSBjaMOqbmggbOG7h2NoIGzhu5tuIG7DoHkgY2hvIHRo4bqleSBraMOhY2ggaMOgbmcgY8OzIHh1IGjGsOG7m25nIHThuq1wIHRydW5nIHbDoG8gY8OhYyBt4bq3dCBow6BuZyB0aGnhur90IHnhur91IHbDoCB0acOqdSBkw7luZyB0aMaw4budbmcgeHV5w6puLCB0cm9uZyBraGkgw610IHF1YW4gdMOibSDEkeG6v24gY8OhYyBuaMOzbSBz4bqjbiBwaOG6qW0gcGjhu6UgaG/hurdjIGNodXnDqm4gYmnhu4d0IGjGoW4uDQoNCl9fXw0KDQojIyAqKjIuMTAuIFByb2R1Y3QgQ2F0ZWdvcnkgKERhbmggbeG7pWMgc+G6o24gcGjhuqltKSoqDQoNCmBgYHtyfQ0KI1ThuqFvIGLhuqNuZyBtw7QgdOG6oyB0aOG7kW5nIGvDqiBiaeG6v24gUHJvZHVjdENhdGVnb3J5DQoNCnRhbnN1YXQucHJvZHVjdGNhdGVnb3J5IDwtIHRhYmxlKGRhdGEkUHJvZHVjdENhdGVnb3J5KQ0Ka2FibGUodGFuc3VhdC5wcm9kdWN0Y2F0ZWdvcnksIGNhcHRpb24gPSAiQuG6o25nIDk6IE3DtCB04bqjIHRo4buRbmcga8OqIGPhu6dhIGJp4bq/biBQcm9kdWN0Q2F0ZWdvcnkiKQ0KDQojIEJp4buDdSDEkeG7kyBiaeG6v24gUHJvZHVjdENhdGVnb3J5DQoNCmNvdW50cyA8LSBkYXRhICU+JSANCiAgZ3JvdXBfYnkoUHJvZHVjdENhdGVnb3J5KSAlPiUgDQogIHN1bW1hcmlzZShDb3VudCA9IG4oKSkNCiAgDQpnZ3Bsb3QoY291bnRzLCBhZXMoeCA9IFByb2R1Y3RDYXRlZ29yeSwgeSA9IENvdW50KSkgKw0KZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAnYnJvd24nKSArDQpsYWJzKA0KICB0aXRsZSA9ICJIw6xuaCA5OiBC4bqjbmcgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIG5ow7NtIHPhuqNuIHBo4bqpbSBjaGkgdGnhur90IiwNCiAgeCA9ICJuaMOzbSBz4bqjbiBwaOG6qW0gY2hpIHRp4bq/dCIsDQogIHkgPSAiU+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmciDQopICsNCnRoZW1lX21pbmltYWwoKSArIA0KdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NywgaGp1c3QgPSAxKSkNCmBgYA0KDQpE4buxYSB0csOqbiBr4bq/dCBxdeG6oyAqKipi4bqjbmcgMTAqKiogdsOgICoqKmjDrG5oIDEwKioqIHBow6JuIHTDrWNoIHRo4buRbmcga8OqIG3DtCB04bqjIGNobyB0aOG6pXkgc+G7sSBwaMOibiBi4buRIGtow7RuZyDEkeG7k25nIMSR4buBdSB2w6AgcsO1IHLhu4d0IHRyb25nIGPDoWMgZGFuaCBt4bulYyBz4bqjbiBwaOG6qW0gbcOgIGtow6FjaCBow6BuZyDEkcOjIGzhu7FhIGNo4buNbiB0cm9uZyB0aOG7nWkgZ2lhbiBraOG6o28gc8OhdC4gTmjDs20gIlZlZ2V0YWJsZXMiIChyYXUgY+G7pykgxJHhu6luZyDEkeG6p3UgduG7m2kgdOG6p24gc3XhuqV0IGNhbyBuaOG6pXQgbMOgIDEuNzI4IHPhuqNuIHBo4bqpbSwgcGjhuqNuIMOhbmggbmh1IGPhuqd1IG3huqFuaCBt4bq9IMSR4buRaSB24bubaSB0aOG7sWMgcGjhuqltIHTGsMahaSBz4buRbmcsIGPDsyB0aOG7gyBkbyBs4bujaSDDrWNoIGRpbmggZMaw4buhbmcgdsOgIHTDrW5oIHBo4buVIGJp4bq/biB0cm9uZyBi4buvYSDEg24gaMOgbmcgbmfDoHkuIFRp4bq/cCB0aGVvIGzDoCAiU25hY2sgRm9vZHMiICjEkeG7kyDEg24gduG6t3QpIHbhu5tpIDEuNjAwIHPhuqNuIHBo4bqpbSwgY2hvIHRo4bqleSB4dSBoxrDhu5tuZyB0acOqdSBkw7luZyBjw6FjIHPhuqNuIHBo4bqpbSB0aeG7h24gbOG7o2kgdsOgIG5oYW5oIGNow7NuZywgcGjDuSBo4bujcCB24bubaSBs4buRaSBz4buRbmcgYuG6rW4gcuG7mW4gY+G7p2Egbmhp4buBdSBuZ8aw4budaS4gTmjDs20gIkZydWl0IiAodHLDoWkgY8OieSkgduG7m2kgNzY1IHPhuqNuIHBo4bqpbSBjxaluZyBjaGnhur9tIHbhu4sgdHLDrSDEkcOhbmcga+G7gywgY+G7p25nIGPhu5EgdGjDqm0geHUgaMaw4bubbmcgxrB1IHRpw6puIGPDoWMgdGjhu7FjIHBo4bqpbSBsw6BuaCBt4bqhbmguIE5nxrDhu6NjIGzhuqFpLCBjw6FjIG5ow7NtIG5oxrAgIkNhbm5lZCBPeXN0ZXJzIiAoMzUgc+G6o24gcGjhuqltKSwgIkNhbm5lZCBTaHJpbXAiICgzOCBz4bqjbiBwaOG6qW0pLCB2w6AgIkNhbmRsZXMiICg0NSBz4bqjbiBwaOG6qW0pIGdoaSBuaOG6rW4gdOG6p24gc3XhuqV0IHLhuqV0IHRo4bqlcCwgxJFp4buBdSBuw6B5IGPDsyB0aOG7gyB4deG6pXQgcGjDoXQgdOG7qyB2aeG7h2MgY8OhYyBz4bqjbiBwaOG6qW0gbsOgeSB0aHXhu5ljIG5ow7NtIMSR4bq3YyBz4bqjbiBob+G6t2Mgw610IMSRxrDhu6NjIMawYSBjaHXhu5luZyB0cm9uZyB0aOG7iyB0csaw4budbmcgbeG7pWMgdGnDqnUuIE5nb8OgaSByYSwgY8OhYyBkYW5oIG3hu6VjIG5oxrAgIkNhbm5lZCBBbmNob3ZpZXMiICg0NCBz4bqjbiBwaOG6qW0pIHbDoCAiTWlzY2VsbGFuZW91cyIgKDQyIHPhuqNuIHBo4bqpbSkgY8WpbmcgY2hvIHRo4bqleSBt4bupYyDEkeG7mSB0acOqdSB0aOG7pSBo4bqhbiBjaOG6vywgY8OzIHRo4buDIGRvIHTDrW5oIMSR4bq3YyB0aMO5IGhv4bq3YyBz4buxIGPhuqFuaCB0cmFuaCB04burIGPDoWMgc+G6o24gcGjhuqltIGtow6FjLiBL4bq/dCBxdeG6oyBuw6B5IGtow7RuZyBjaOG7iSBwaOG6o24gw6FuaCBz4bufIHRow61jaCB0acOqdSBkw7luZyB04bqtcCB0cnVuZyB2w6BvIHRo4buxYyBwaOG6qW0gdGhp4bq/dCB54bq/dSB2w6AgdGnhu4duIGzhu6NpIG3DoCBjw7JuIGfhu6NpIMO9IHLhurFuZyBjw6FjIHPhuqNuIHBo4bqpbSBjaHV5w6puIGJp4buHdCBob+G6t2Mgw610IHBo4buVIGJp4bq/biBjw7MgdGjhu4MgY+G6p24gY2hp4bq/biBsxrDhu6NjIHRp4bq/cCB0aOG7iyBob+G6t2MgY+G6o2kgdGnhur9uIMSR4buDIHTEg25nIHPhu6ljIGjDunQgdHJvbmcgdMawxqFuZyBsYWkuDQoNCl9fXw0KDQojICoqUEjhuqZOIDM6IMav4buaQyBMxq/hu6JORyBLSE/huqJORyBWw4AgS0nhu4JNIMSQ4buKTkggR0nhuqIgVEhVWeG6vlQgQ0hPIFThu7YgTOG7hiAoTeG7mFQgQknhur5OKSoqDQoNCiMjICoqMy4xLiBCaeG6v24gR2VuZGVyIC0gaOG6oW5nIG3hu6VjICJO4buvIioqDQoNCioqaSkgSOG6oW5nIG3hu6VjIHF1YW4gdMOibSoqDQoNClRyb25nIGJp4bq/biBHZW5kZXIsIGjhuqFuZyBt4bulYyDEkcaw4bujYyBxdWFuIHTDom0g4bufIMSRw6J5IGzDoCAqKkYqKiAobuG7rykNCg0KYGBge3J9DQojVOG7lW5nIHPhu5EgcXVhbiBzw6F0DQoNCnRvdGFsIDwtIG5yb3coZGF0YSkNCg0KI1Phu5EgbMaw4bujbmcgbuG7rw0Kc28ubnUgPC0gc3VtKGRhdGEkR2VuZGVyID09ICJGIikNCmBgYA0KDQoqKmlpKSDGr+G7m2MgbMaw4bujbmcga2hv4bqjbmcgdGluIGPhuq15KioNCg0KS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIGNobyB04bu3IGzhu4cgbuG7ryB24bubaSBt4bupYyDDvSBuZ2jEqWEgOTUlIGzDoDoNCg0KYGBge3J9DQojduG7m2kga2hv4bqjbmcgdGluIGPhuq15IDk1JQ0KDQpwcm9wLnRlc3Qoc28ubnUsIHRvdGFsLCBjb25mLmxldmVsID0gMC45NSkNCmBgYA0KDQpW4bubaSBr4bq/dCBxdeG6oyB0csOqbiwgdGEgY8OzIMSRxrDhu6NjIGtob+G6o25nIHRpbiBj4bqteSB04bu3IGzhu4cga2jDoWNoIGjDoG5nIG7hu68gdHJvbmcgdOG7lW5nIHRo4buDIG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgKio1MC4xNyUqKiDEkeG6v24gKio1MS44MyUqKi4NCg0KKippaWkpIEtp4buDbSDEkeG7i25oIGdp4bqjIHRodXnhur90KioNCg0KR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmg6DQoNCiRIXzAkOiBU4bu3IGzhu4cgbuG7ryB0cm9uZyB04buVbmcgc+G7kSBxdWFuIHPDoXQgYuG6sW5nIDUwJQ0KDQokSF8xJDogVOG7tyBs4buHIG7hu68gdHJvbmcgdOG7lW5nIHPhu5EgcXVhbiBzw6F0IGtow6FjIDUwJQ0KDQpgYGB7cn0NCiMgS2nhu4NtIMSR4buLbmggSDA6IHAgPSAwLjUNCg0KcHJvcC50ZXN0KHNvLm51LCB0b3RhbCwgcCA9IDAuNSkNCmBgYA0KDQpW4bubaSBr4bq/dCBxdeG6oyB24burYSBraeG7g20gxJHhu4tuaCDEkcaw4bujYywgdGEgdGjhuqV5IHLhurFuZyAkcC12YWx1ZSA9IDAuMDE4MiA8IDAuMDUkLCB0YSBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgJEhfMCQgdsOgIGNo4bqlcCBuaOG6rW4gZ2nhuqMgdGh1eeG6v3QgJEhfMSQsIHThu6ljIHThu7cgbOG7hyBu4buvIHRyb25nIHThu5VuZyBz4buRIHF1YW4gc8OhdCBraMOhYyA1MCUg4bufIG3hu6ljIMO9IG5naMSpYSA1JS4NCg0KX19fDQoNCiMjICoqMy4yLiBCaeG6v24gTWFyaXRhbFN0YXR1cyAtIGjhuqFuZyBt4bulYyAixJDhu5ljIHRow6JuIioqDQoNClRyb25nIGJp4bq/biBNYXJpdGFsU3RhdHVzLCBo4bqhbmcgbeG7pWMgxJHGsOG7o2MgcXVhbiB0w6JtIOG7nyDEkcOieSBsw6AgKipTKiogKMSR4buZYyB0aMOibikNCg0KYGBge3J9DQojVOG7lW5nIHPhu5EgcXVhbiBzw6F0DQoNCnRvdGFsIDwtIG5yb3coZGF0YSkNCg0KI1Phu5EgbMaw4bujbmcgxJHhu5ljIHRow6JuDQpzby5kb2MudGhhbiA8LSBzdW0oZGF0YSRNYXJpdGFsU3RhdHVzID09ICJTIikNCmBgYA0KDQoqKmlpKSDGr+G7m2MgbMaw4bujbmcga2hv4bqjbmcgdGluIGPhuq15KioNCg0KS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIGNobyB04bu3IGzhu4cgxJHhu5ljIHRow6JuIHbhu5tpIG3hu6ljIMO9IG5naMSpYSA5NSUgbMOgOg0KDQpgYGB7cn0NCiN24bubaSBraG/huqNuZyB0aW4gY+G6rXkgOTUlDQoNCnByb3AudGVzdChzby5kb2MudGhhbiwgdG90YWwsIGNvbmYubGV2ZWwgPSAwLjk1KQ0KYGBgDQoNClbhu5tpIGvhur90IHF14bqjIHRyw6puLCB0YSBjw7MgxJHGsOG7o2Mga2hv4bqjbmcgdGluIGPhuq15IHThu7cgbOG7hyBraMOhY2ggaMOgbmcgbuG7ryB0cm9uZyB04buVbmcgdGjhu4MgbuG6sW0gdHJvbmcga2hv4bqjbmcgdOG7qyAqKjUwLjMzJSoqIMSR4bq/biAqKjUxLjk5JSoqLg0KDQoqKmlpaSkgS2nhu4NtIMSR4buLbmggZ2nhuqMgdGh1eeG6v3QqKg0KDQpHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaDoNCg0KJEhfMCQ6IFThu7cgbOG7hyDEkeG7mWMgdGjDom4gdHJvbmcgdOG7lW5nIHPhu5EgcXVhbiBzw6F0IGLhurFuZyA1MCUNCg0KJEhfMSQ6IFThu7cgbOG7hyDEkeG7mWMgdGjDom4gdHJvbmcgdOG7lW5nIHPhu5EgcXVhbiBzw6F0IGtow6FjIDUwJQ0KDQpgYGB7cn0NCiMgS2nhu4NtIMSR4buLbmggSDA6IHAgPSAwLjUNCg0KcHJvcC50ZXN0KHNvLmRvYy50aGFuLCB0b3RhbCwgcCA9IDAuNSkNCmBgYA0KDQpW4bubaSBr4bq/dCBxdeG6oyB24burYSBraeG7g20gxJHhu4tuaCDEkcaw4bujYywgdGEgdGjhuqV5IHLhurFuZyAkcC12YWx1ZSA9IDAuMDA1OTcgPCAwLjA1JCwgdGEgYsOhYyBi4buPIGdp4bqjIHRodXnhur90ICRIXzAkIHbDoCBjaOG6pXAgbmjhuq1uIGdp4bqjIHRodXnhur90ICRIXzEkLCB04bupYyB04bu3IGzhu4cgxJHhu5ljIHRow6JuIHRyb25nIHThu5VuZyBz4buRIHF1YW4gc8OhdCBraMOhYyA1MCUg4bufIG3hu6ljIMO9IG5naMSpYSA1JS4NCg0KX19fDQoNCiMjICoqMy4zLiBCaeG6v24gUHJvZHVjdENhdGVnb3J5IC0gaOG6oW5nIG3hu6VjICJDYW5keSIqKg0KDQpUcm9uZyBiaeG6v24gUHJvZHVjdENhdGVnb3J5LCBo4bqhbmcgbeG7pWMgxJHGsOG7o2MgcXVhbiB0w6JtIOG7nyDEkcOieSBsw6AgKipDYW5keSoqIChr4bq5bykNCg0KYGBge3J9DQojVOG7lW5nIHPhu5EgcXVhbiBzw6F0DQoNCnRvdGFsIDwtIG5yb3coZGF0YSkNCg0KI1Phu5EgbMaw4bujbmcgxJHhu5ljIHRow6JuDQpzby5rZW8gPC0gc3VtKGRhdGEkUHJvZHVjdENhdGVnb3J5ID09ICJDYW5keSIpDQpgYGANCg0KKippaSkgxq/hu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteSoqDQoNCktob+G6o25nIMaw4bubYyBsxrDhu6NuZyBjaG8gdOG7tyBs4buHIGvhurlvIHbhu5tpIG3hu6ljIMO9IG5naMSpYSA5NSUgbMOgOg0KDQpgYGB7cn0NCiN24bubaSBraG/huqNuZyB0aW4gY+G6rXkgOTUlDQoNCnByb3AudGVzdChzby5rZW8sIHRvdGFsLCBjb25mLmxldmVsID0gMC45NSkNCmBgYA0KDQpW4bubaSBr4bq/dCBxdeG6oyB0csOqbiwgdGEgY8OzIMSRxrDhu6NjIGtob+G6o25nIHRpbiBj4bqteSB04bu3IGzhu4cga2jDoWNoIGjDoG5nIG7hu68gdHJvbmcgdOG7lW5nIHRo4buDIG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgKioyLjI1JSoqIMSR4bq/biAqKjIuNzglKiouDQoNCioqaWlpKSBLaeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dCoqDQoNCkdp4bqjIHRodXnhur90IGtp4buDbSDEkeG7i25oOg0KDQokSF8wJDogVOG7tyBs4buHIGvhurlvIHRyb25nIHThu5VuZyBz4buRIHF1YW4gc8OhdCBi4bqxbmcgNTAlDQoNCiRIXzEkOiBU4bu3IGzhu4cga+G6uW8gdHJvbmcgdOG7lW5nIHPhu5EgcXVhbiBzw6F0IGtow6FjIDUwJQ0KDQpgYGB7cn0NCiMgS2nhu4NtIMSR4buLbmggSDA6IHAgPSAwLjUNCg0KcHJvcC50ZXN0KHNvLmtlbywgdG90YWwsIHAgPSAwLjUpDQpgYGANCg0KVuG7m2kga+G6v3QgcXXhuqMgduG7q2Ega2nhu4NtIMSR4buLbmggxJHGsOG7o2MsIHRhIHRo4bqleSBy4bqxbmcgJHAtdmFsdWUgPCAyLjJlLTE2IDwgMC4wNSQsIHRhIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCAkSF8wJCB2w6AgY2jhuqVwIG5o4bqtbiBnaeG6oyB0aHV54bq/dCAkSF8xJCwgdOG7qWMgdOG7tyBs4buHIGvhurlvIHRyb25nIHThu5VuZyBz4buRIHF1YW4gc8OhdCBraMOhYyA1MCUg4bufIG3hu6ljIMO9IG5naMSpYSA1JS4NCg0KX19fDQoNCiMgKipQSOG6pk4gNDogUEjDgk4gVMONQ0ggTeG7lkkgUVVBTiBI4buGIEdJ4buuQSBIQUkgQknhur5OIMSQ4buKTkggVMONTkggKEJJVkFSSUFURSBBTkFMWVNJUykqKg0KDQojIyAqKjQuMS4gQmnhur9uIEdlbmRlciB2w6AgUHJvZHVjdEZhbWlseSoqDQoNCioqQuG6o25nIHThuqduIHN14bqldCBjaMOpbyB2w6AgYmnhu4N1IMSR4buTIHRy4buxYyBxdWFuIGjDs2EgY2hvIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgMiBiaeG6v246KioNCg0KYGBge3J9DQojIELhuqduIHN14bqldCBnaeG7r2EgR2VuZGVyIHbDoCBQcm9kdWN0RmFtaWx5DQp0YW5zdWF0MSA8LSB0YWJsZShkYXRhJEdlbmRlciwgZGF0YSRQcm9kdWN0RmFtaWx5KSANCnBoYW50cmFtMSA8LSBwcm9wLnRhYmxlKHRhbnN1YXQxLCBtYXJnaW4gPSAxKSAqIDEwMA0KDQpiYW5nMSA8LSBhcy5kYXRhLmZyYW1lKHRhbnN1YXQxKQ0KYmFuZzEkUGVyY2VudGFnZSA8LSByb3VuZChhcy52ZWN0b3IocGhhbnRyYW0xKSwgMikNCg0KY29sbmFtZXMoYmFuZzEpIDwtIGMoIkdlbmRlciIsICJQcm9kdWN0RmFtaWx5IiwgIkZyZXF1ZW5jeSIsICJQZXJjZW50YWdlIikNCiAgICANCmthYmxlKGJhbmcxLCBjYXB0aW9uID0gIkLhuqNuZyAxMTogTcO0IHThuqMgdGjhu5FuZyBrw6ogY+G7p2EgMiBiaeG6v24gR2VuZGVyIHbDoCBQcm9kdWN0RmFtaWx5IikNCg0KI1Ry4buxYyBxdWFuIGjDs2EgY2hvIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgMiBiaeG6v24NCmdncGxvdChiYW5nMSwgYWVzKHggPSBQcm9kdWN0RmFtaWx5LCB5ID0gUGVyY2VudGFnZSwgZmlsbCA9IEdlbmRlcikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKHRpdGxlID0gIkjDrG5oIDExOiBN4buRaSBxdWFuIGjhu4cgZ2nhu69hIEdlbmRlciB2w6AgUHJvZHVjdEZhbWlseSIsDQogICAgICAgeCA9ICJOaMOzbSBz4bqjbiBwaOG6qW0iLCB5ID0gIlThu7cgbOG7hyAoJSkiLCBmaWxsID0gIkdp4bubaSB0w61uaCIpICsNCiAgdGhlbWVfbWluaW1hbCgpIA0KYGBgDQoNCkThu7FhIHRyw6puIGLhuqNuZyB04bqnbiBzdeG6pXQgY2jDqW8gdsOgIGJp4buDdSDEkeG7kyBtaW5oIGjhu41hLCBjw7MgdGjhu4MgdGjhuqV5IG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgaGFpIGJp4bq/biAqKkdlbmRlcioqIHbDoCAqKlByb2R1Y3RGYW1pbHkqKiBsw6Aga2jDoSDEkeG7k25nIMSR4buBdS4gQ+G6oyBuYW0gdsOgIG7hu68gxJHhu4F1IGPDsyB4dSBoxrDhu5tuZyB0acOqdSBkw7luZyB0xrDGoW5nIHThu7EgbmhhdSwgdHJvbmcgxJHDsyBuaMOzbSBz4bqjbiBwaOG6qW0gKioiRm9vZCIqKiBjaGnhur9tIHThu7cgbOG7hyBjYW8gbmjhuqV0IOG7nyBj4bqjIGhhaSBnaeG7m2kgKHRyw6puIDcxJSksIHRp4bq/cCB0aGVvIGzDoCAqKiJOb24tQ29uc3VtYWJsZSIqKiAoa2hv4bqjbmcgMTglKSwgdsOgIHRo4bqlcCBuaOG6pXQgbMOgICoqIkRyaW5rIioqIChkxrDhu5tpIDEwJSkuIFPhu7EgcGjDom4gYuG7kSB0xrDGoW5nIMSR4buRaSBjw6JuIGLhurFuZyBuw6B5IGNobyB0aOG6pXkga2jDtG5nIGPDsyBz4buxIGtow6FjIGJp4buHdCByw7UgcuG7h3QgZ2nhu69hIG5hbSB2w6AgbuG7ryB0cm9uZyB2aeG7h2MgbOG7sWEgY2jhu41uIG5ow7NtIHPhuqNuIHBo4bqpbS4gRG8gxJHDsywgcXVhIHF1YW4gc8OhdCwgY8OzIHbhursgbmjGsCAqKmhhaSBiaeG6v24gbsOgeSBraMO0bmcgY8OzIG3hu5FpIGxpw6puIGjhu4cgbeG6oW5oKiosIHR1eSBuaGnDqm4gxJHhu4MgY8OzIGvhur90IGx14bqtbiBjaMOtbmggeMOhYyBoxqFuLCBj4bqnbiB0aOG7sWMgaGnhu4duIGtp4buDbSDEkeG7i25oIHRo4buRbmcga8OqIGLhurFuZyBwaMOpcCBraeG7g20gQ2hpLWLDrG5oIHBoxrDGoW5nLg0KDQoqKktp4buDbSDEkeG7i25oIGNoaSBiw6xuaCBwaMawxqFuZzoqKg0KDQpHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaDoNCg0KJEhfMCQ6IEJp4bq/biBHZW5kZXIgKGdp4bubaSB0w61uaCkga2jDtG5nIOG6o25oIGjGsOG7n25nIMSR4bq/biBiaeG6v24gUHJvZHVjdEZhbWlseSAobmjDs20gc+G6o24gcGjhuqltKQ0KDQokSF8xJDogQmnhur9uIEdlbmRlciAoZ2nhu5tpIHTDrW5oKSBjw7Mg4bqjbmggaMaw4bufbmcgxJHhur9uIGJp4bq/biBQcm9kdWN0RmFtaWx5IChuaMOzbSBz4bqjbiBwaOG6qW0pDQoNCmBgYHtyfQ0KIyBLaeG7g20gxJHhu4tuaCBDaGktYsOsbmggcGjGsMahbmcNCmNoaV90ZXN0IDwtIGNoaXNxLnRlc3QodGFuc3VhdDEpDQpjaGlfdGVzdA0KYGBgDQoNClbhu5tpIGvhur90IHF14bqjIHbhu6thIGtp4buDbSDEkeG7i25oIMSRxrDhu6NjLCB0YSB0aOG6pXkgcuG6sW5nICRwLXZhbHVlID0gMC4xNzIyID4gMC4wNSQsIHRhIGtow7RuZyDEkeG7pyBi4bqxbmcgY2jhu6luZyDEkeG7gyBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgJEhfMCQuIE5oxrAgduG6rXksIGJp4bq/biBHZW5kZXIgKGdp4bubaSB0w61uaCkga2jDtG5nIOG6o25oIGjGsOG7n25nIMSR4bq/biBiaeG6v24gUHJvZHVjdEZhbWlseSAobmjDs20gc+G6o24gcGjhuqltKeG7nyBt4bupYyDDvSBuZ2jEqWEgNSUuDQoNCl9fXw0KDQojIyAqKjQuMi4gQmnhur9uIE1hcml0YWxTdGF0dXMgdsOgIEhvbWVvd25lcioqDQoNCioqQuG6o25nIHThuqduIHN14bqldCBjaMOpbyB2w6AgYmnhu4N1IMSR4buTIHRy4buxYyBxdWFuIGjDs2EgY2hvIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgMiBiaeG6v246KioNCg0KYGBge3J9DQojIELhuqduIHN14bqldCBnaeG7r2EgTWFyaXRhbFN0YXR1cyB2w6AgSG9tZW93bmVyDQp0YW5zdWF0MiA8LSB0YWJsZShkYXRhJE1hcml0YWxTdGF0dXMsIGRhdGEkSG9tZW93bmVyKSANCnBoYW50cmFtMiA8LSBwcm9wLnRhYmxlKHRhbnN1YXQyLCBtYXJnaW4gPSAxKSAqIDEwMA0KDQpiYW5nMiA8LSBhcy5kYXRhLmZyYW1lKHRhbnN1YXQyKQ0KYmFuZzIkUGVyY2VudGFnZSA8LSByb3VuZChhcy52ZWN0b3IocGhhbnRyYW0yKSwgMikNCg0KY29sbmFtZXMoYmFuZzIpIDwtIGMoIk1hcml0YWxTdGF0dXMiLCAiSG9tZW93bmVyIiwgIkZyZXF1ZW5jeSIsICJQZXJjZW50YWdlIikNCiAgICANCmthYmxlKGJhbmcyLCBjYXB0aW9uID0gIkLhuqNuZyAxMjogTcO0IHThuqMgdGjhu5FuZyBrw6ogY+G7p2EgMiBiaeG6v24gTWFyaXRhbFN0YXR1cyB2w6AgSG9tZW93bmVyIikNCg0KI1Ry4buxYyBxdWFuIGjDs2EgY2hvIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgMiBiaeG6v24NCmdncGxvdChiYW5nMiwgYWVzKHggPSBIb21lb3duZXIsIHkgPSBQZXJjZW50YWdlLCBmaWxsID0gTWFyaXRhbFN0YXR1cykpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsgICMgaG/hurdjIHRow6ptOiBwb3NpdGlvbiA9ICJzdGFjayINCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiUyIgPSAiI0ZGNkY2MSIsICJNIiA9ICIjNkI1Qjk1IikpICsNCiAgbGFicyh0aXRsZSA9ICJIw6xuaCAxMjogTeG7kWkgcXVhbiBo4buHIGdp4buvYSBNYXJpdGFsU3RhdHVzIHbDoCBIb21lb3duZXIiLA0KICAgICAgIHggPSAiVMOsbmggdHLhuqFuZyBz4bufIGjhu691IG5ow6AgcmnDqm5nIiwgeSA9ICJU4bu3IGzhu4cgKCUpIiwgZmlsbCA9ICJUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4iKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCkThu7FhIHRyw6puICoqKmLhuqNuZyAxMioqKiB2w6AgKioqaMOsbmggMTIqKiosIGPDsyB0aOG7gyB0aOG6pXkgcuG6sW5nIHThu5NuIHThuqFpIG3hu5l0IG3hu5FpIGxpw6puIGjhu4cgcsO1IHLhu4d0IGdp4buvYSB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gdsOgIGto4bqjIG7Eg25nIHPhu58gaOG7r3UgbmjDoCByacOqbmcuIEPhu6UgdGjhu4MsIHRyb25nIG5ow7NtIMSRw6Mga+G6v3QgaMO0biAoTSksIGPDsyB04bubaSA3NC45NiUgbmfGsOG7nWkgc+G7nyBo4buvdSBuaMOgLCB0cm9uZyBraGkgY2jhu4kgMjUuMDQlIGtow7RuZyBz4bufIGjhu691LiBOZ8aw4bujYyBs4bqhaSwg4bufIG5ow7NtIMSR4buZYyB0aMOibiAoUyksIHThu7cgbOG7hyBraMO0bmcgc+G7nyBo4buvdSBuaMOgIGzDoCA1NC4xNiUsIGNhbyBoxqFuIHThu7cgbOG7hyBz4bufIGjhu691IG5ow6AgKDQ1Ljg0JSkuIEJp4buDdSDEkeG7kyBj4buZdCBjaOG7k25nIG1pbmggaOG7jWEgcsO1IMSRaeG7gXUgbsOgeSBraGkgcGjhuqduIG3DoHUgxJHhuqFpIGRp4buHbiBjaG8gbmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuIGNoaeG6v20gxrB1IHRo4bq/IHRyb25nIG5ow7NtIHPhu58gaOG7r3UgbmjDoCwgY8OybiBwaOG6p24gbcOgdSDEkeG6oWkgZGnhu4duIGNobyBuZ8aw4budaSDEkeG7mWMgdGjDom4gbOG6oWkgbuG7lWkgYuG6rXQgaMahbiB0cm9uZyBuaMOzbSBraMO0bmcgc+G7nyBo4buvdS4gWHUgaMaw4bubbmcgbsOgeSBjaG8gdGjhuqV5IG5nxrDhu51pIMSRw6Mga+G6v3QgaMO0biB0aMaw4budbmcgY8OzIHh1IGjGsOG7m25nIHbDoCBraOG6oyBuxINuZyBz4bufIGjhu691IG5ow6AgcmnDqm5nIGNhbyBoxqFuIHNvIHbhu5tpIG5nxrDhu51pIMSR4buZYyB0aMOibiwgY8OzIHRo4buDIGRvIHnhur91IHThu5EgdMOgaSBjaMOtbmgg4buVbiDEkeG7i25oIGjGoW4gaG/hurdjIG5odSBj4bqndSBhbiBjxrAga2hpIGzhuq1wIGdpYSDEkcOsbmguDQoNCioqS2nhu4NtIMSR4buLbmggY2hpIGLDrG5oIHBoxrDGoW5nOioqDQoNCkdp4bqjIHRodXnhur90IGtp4buDbSDEkeG7i25oOg0KDQokSF8wJDogQmnhur9uIE1hcml0YWxTdGF0dXMgKHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibikga2jDtG5nIOG6o25oIGjGsOG7n25nIMSR4bq/biBiaeG6v24gSG9tZW93bmVyICh0w6xuaCB0cuG6oW5nIHPhu58gaOG7r3UgbmjDoCByacOqbmcpDQoNCiRIXzEkOiBCaeG6v24gTWFyaXRhbFN0YXR1cyAodMOsbmggdHLhuqFuZyBow7RuIG5ow6JuKSBjw7Mg4bqjbmggaMaw4bufbmcgxJHhur9uIGJp4bq/biBIb21lb3duZXIgKHTDrG5oIHRy4bqhbmcgc+G7nyBo4buvdSBuaMOgIHJpw6puZykNCg0KYGBge3J9DQojIEtp4buDbSDEkeG7i25oIENoaS1iw6xuaCBwaMawxqFuZw0KY2hpX3Rlc3QgPC0gY2hpc3EudGVzdCh0YW5zdWF0MikNCmNoaV90ZXN0DQpgYGANCg0KVuG7m2kga+G6v3QgcXXhuqMgduG7q2Ega2nhu4NtIMSR4buLbmggxJHGsOG7o2MsIHRhIHRo4bqleSBy4bqxbmcgJHAtdmFsdWUgPCAyLjJlLTE2IDwgMC4wNSQsIHRhIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCAkSF8wJCB2w6AgY2jhuqVwIG5o4bqtbiBnaeG6oyB0aHV54bq/dCAkSF8xJCwgdOG7qWMgYmnhur9uIE1hcml0YWxTdGF0dXMgKHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibikgY8OzIOG6o25oIGjGsOG7n25nIMSR4bq/biBiaeG6v24gSG9tZW93bmVyICh0w6xuaCB0cuG6oW5nIHPhu58gaOG7r3UgbmjDoCByacOqbmcpIOG7nyBt4bupYyDDvSBuZ2jEqWEgNSUuDQoNCl9fXw0KDQojIyAqKjQuMy4gQmnhur9uIEFubnVhbEluY29tZSB2w6AgUHJvZHVjdENhdGVnb3J5KioNCg0KKipC4bqjbmcgdOG6p24gc3XhuqV0IGNow6lvIHbDoCBiaeG7g3UgxJHhu5MgdHLhu7FjIHF1YW4gaMOzYSBjaG8gbeG7kWkgcXVhbiBo4buHIGdp4buvYSAyIGJp4bq/bjoqKg0KDQpgYGB7cn0NCiMgQuG6p24gc3XhuqV0IGdp4buvYSBBbm51YWxJbmNvbWUgdsOgIENvdW50cnkNCnRhbnN1YXQzIDwtIHRhYmxlKGRhdGEkQW5udWFsSW5jb21lLCBkYXRhJENvdW50cnkpIA0KcGhhbnRyYW0zIDwtIHByb3AudGFibGUodGFuc3VhdDMsIG1hcmdpbiA9IDEpICogMTAwDQoNCmJhbmczIDwtIGFzLmRhdGEuZnJhbWUodGFuc3VhdDMpDQpiYW5nMyRQZXJjZW50YWdlIDwtIHJvdW5kKGFzLnZlY3RvcihwaGFudHJhbTMpLCAyKQ0KDQpjb2xuYW1lcyhiYW5nMykgPC0gYygiQW5udWFsSW5jb21lIiwgIkNvdW50cnkiLCAiRnJlcXVlbmN5IiwgIlBlcmNlbnRhZ2UiKQ0KICAgIA0Ka2FibGUoYmFuZzMsIGNhcHRpb24gPSAiQuG6o25nIDEzOiBNw7QgdOG6oyB0aOG7kW5nIGvDqiBj4bunYSAyIGJp4bq/biBBbm51YWxJbmNvbWUgdsOgIENvdW50cnkiKQ0KDQojVHLhu7FjIHF1YW4gaMOzYSBjaG8gbeG7kWkgcXVhbiBo4buHIGdp4buvYSAyIGJp4bq/bg0KZ2dwbG90KGJhbmczLCBhZXMoeCA9IENvdW50cnksIHkgPSBQZXJjZW50YWdlLCBmaWxsID0gQW5udWFsSW5jb21lKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnModGl0bGUgPSAiSMOsbmggMTM6IE3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgQW5udWFsSW5jb21lIHbDoCBDb3VudHJ5IiwNCiAgICAgICB4ID0gIlF14buRYyBnaWEiLCB5ID0gIlThu7cgbOG7hyAoJSkiLCBmaWxsID0gIlRodSBuaOG6rXAgaMOgbmcgdGjDoW5nIikgKw0KICB0aGVtZV9taW5pbWFsKCkgDQpgYGANCg0KROG7sWEgdHLDqm4gYuG6o25nIHRo4buRbmcga8OqIHbDoCBiaeG7g3UgxJHhu5MgdHLhu7FjIHF1YW4sIGPDsyB0aOG7gyBuaOG6rW4gdGjhuqV5IHPhu7EgcGjDom4gYuG7kSB0aHUgbmjhuq1wIGjDoG5nIG7Eg20gKEFubnVhbEluY29tZSkgZ2nhu69hIGPDoWMgcXXhu5FjIGdpYSBsw6AgcuG6pXQga2jDoWMgYmnhu4d0LiBU4bqhaSBIb2EgS+G7sywgdOG7tyBs4buHIG5nxrDhu51pIHRpw6p1IGTDuW5nIHRyb25nIHThuqV0IGPhuqMgY8OhYyBuaMOzbSB0aHUgbmjhuq1wIMSR4buBdSBjaGnhur9tIHThu7cgbOG7hyDDoXAgxJHhuqNvLCBkYW8gxJHhu5luZyB04burIGtob+G6o25nIDY0JSDEkeG6v24gZ+G6p24gNzQlLCBjaG8gdGjhuqV5IHBo4bqnbiBs4bubbiBuZ8aw4budaSB0acOqdSBkw7luZyB0cm9uZyB04bqtcCBk4buvIGxp4buHdSDEkeG6v24gdOG7qyBN4bu5IHbDoCBjw7MgbeG7qWMgdGh1IG5o4bqtcCBraMOhIGNhby4gVHJvbmcga2hpIMSRw7MsIHThuqFpIENhbmFkYSwgdOG7tyBs4buHIOG7nyB04burbmcgbmjDs20gdGh1IG5o4bqtcCBjaOG7iSBkYW8gxJHhu5luZyB04burIGtob+G6o25nIDQlIMSR4bq/biA3JSwgdGjhuqVwIGjGoW4gxJHDoW5nIGvhu4MuIE1leGljbyBjw7MgdOG7tyBs4buHIHBow6JuIGLhu5EgY2FvIGjGoW4gQ2FuYWRhLCBkYW8gxJHhu5luZyB04burIDIwJSDEkeG6v24gZ+G6p24gMjglIOG7nyBjw6FjIG5ow7NtIHRodSBuaOG6rXAsIHBo4bqjbiDDoW5oIHPhu5EgbMaw4bujbmcgbmfGsOG7nWkgdGnDqnUgZMO5bmcgduG7q2EgcGjhuqNpIHbDoCB0aHUgbmjhuq1wIHThuq1wIHRydW5nIHbDoG8gbmjDs20gdHJ1bmcgYsOsbmguIEJp4buDdSDEkeG7kyBj4buZdCBjxaluZyB0aOG7gyBoaeG7h24gcsO1IHLDoG5nIHPhu7EgY2jDqm5oIGzhu4djaCBuw6B5LCB24bubaSBjw6FjIGPhu5l0IGJp4buDdSB0aOG7iyBjaG8gTeG7uSBsdcO0biBjYW8gaMahbiDEkcOhbmcga+G7gyBzbyB24bubaSBoYWkgcXXhu5FjIGdpYSBjw7JuIGzhuqFpIOG7nyB04bqldCBj4bqjIGPDoWMgbmjDs20gdGh1IG5o4bqtcC4gTmjGsCB24bqteSwgY8OzIHRo4buDIGvhur90IGx14bqtbiBy4bqxbmcgSG9hIEvhu7MgbMOgIHRo4buLIHRyxrDhu51uZyBjw7MgdOG7tyB0cuG7jW5nIG5nxrDhu51pIHRpw6p1IGTDuW5nIGNhbyB2w6AgdGh1IG5o4bqtcCDhu5VuIMSR4buLbmggaMahbiwgdHJvbmcga2hpIENhbmFkYSBjw7MgdOG7tyB0cuG7jW5nIHRo4bqlcCBoxqFuIHLDtSBy4buHdC4NCg0KX19fDQoNCiMgKipQSOG6pk4gNTogVOG7lE5HIEvhur5UIFbDgCBUSOG6ok8gTFXhuqxOKioNCg0KIyMgKio1LjEuIFTDs20gdOG6r3Qgbmjhu69uZyBwaMOhdCBoaeG7h24gY2jDrW5oKioNCg0KROG7sWEgdHLDqm4gY8OhYyBwaMOibiB0w61jaCDEkeG7i25oIHTDrW5oIMSRw6MgdGjhu7FjIGhp4buHbiwgbeG7mXQgc+G7kSDEkeG6t2MgxJFp4buDbSBu4buVaSBi4bqtdCB24buBIGtow6FjaCBow6BuZyB2w6AgaMOgbmggdmkgbXVhIHPhuq9tIMSRw6MgxJHGsOG7o2MgbMOgbSByw7U6DQoNCiogR2nhu5tpIHTDrW5oOiBOaMOzbSBraMOhY2ggaMOgbmcgY8OzIHThu7cgbOG7hyBuYW0gZ2nhu5tpIGNhbyBoxqFuIG7hu68gZ2nhu5tpIG3hu5l0IGPDoWNoIHLDtSBy4buHdCwgxJHhurdjIGJp4buHdCB0cm9uZyBuaMOzbSB0acOqdSBkw7luZyBjw6FjIGTDsm5nIHPhuqNuIHBo4bqpbSBjw7RuZyBuZ2jhu4cgdsOgIHRo4buDIHRoYW8uIA0KDQoqIFPhu7Ega2jDoWMgYmnhu4d0IGdp4buvYSBjw6FjIG5ow7NtIMSR4buZIHR14buVaSBjxaluZyBjaG8gdGjhuqV5IHh1IGjGsOG7m25nIHRpw6p1IGTDuW5nIHJpw6puZyBiaeG7h3QsIHbhu5tpIG5ow7NtIHRydW5nIG5pw6puICgzNeKAkzUwIHR14buVaSkgY8OzIHThu7cgbOG7hyBtdWEgaMOgbmcgY2FvIGjGoW4g4bufIG5oaeG7gXUgZGFuaCBt4bulYyBz4bqjbiBwaOG6qW0uIA0KDQoqIFbhu4EgbeG6t3QgxJHhu4thIGzDvSwgbmfGsOG7nWkgdGnDqnUgZMO5bmcgdOG6oWkgSG9hIEvhu7MgY2hp4bq/bSB04bu3IHRy4buNbmcgw6FwIMSR4bqjbyB0cm9uZyBo4bqndSBo4bq/dCBjw6FjIG5ow7NtIHRodSBuaOG6rXAsIHBo4bqjbiDDoW5oIHRo4buLIHRyxrDhu51uZyBy4buZbmcgbOG7m24gdsOgIOG7lW4gxJHhu4tuaCBj4bunYSBxdeG7kWMgZ2lhIG7DoHkuIFRyb25nIGtoaSDEkcOzLCBNZXhpY28gdsOgIENhbmFkYSBjw7MgdOG7tyBs4buHIHRo4bqlcCBoxqFuLCBzb25nIHRo4buDIGhp4buHbiBz4buxIHThuq1wIHRydW5nIOG7nyBjw6FjIG5ow7NtIHRodSBuaOG6rXAgdHJ1bmcgYsOsbmguIA0KDQoqIE3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgdGh1IG5o4bqtcCB2w6AgZGFuaCBt4bulYyBz4bqjbiBwaOG6qW0gY8WpbmcgY2hvIHRo4bqleSBy4bqxbmcgbmfGsOG7nWkgY8OzIHRodSBuaOG6rXAgY2FvIGPDsyB4dSBoxrDhu5tuZyBxdWFuIHTDom0gxJHhur9uIGPDoWMgc+G6o24gcGjhuqltIHRodeG7mWMgbmjDs20gY2FvIGPhuqVwIGhv4bq3YyBjw7RuZyBuZ2jhu4cuIA0KDQojIyAqKjUuMi4gSOG6oW4gY2jhur8gY+G7p2EgcGjDom4gdMOtY2gqKg0KDQoqIENo4buJIGTDuW5nIGJp4bq/biDEkeG7i25oIHTDrW5oLCBraMO0bmcgcGjDom4gdMOtY2ggxJHGsOG7o2MgY2hpIHRpw6p1IHRo4buxYyB04bq/Lg0KDQoqIEtow7RuZyBjw7MgZOG7ryBsaeG7h3UgaMOgbmggdmkgb25saW5lIChjbGlja3MsIGJyb3dzaW5nKSDigJMgYuG7jyBs4buhIG5oaeG7gXUgaW5zaWdodCBxdWFuIHRy4buNbmcgduG7gSBow6BuaCB0csOsbmgga2jDoWNoIGjDoG5nLg0KDQoqIE3hu5l0IHPhu5EgcGjDom4gbmjDs20gcXXDoSBuaOG7jywgdsOtIGThu6UgbmjGsCB0aHUgbmjhuq1wIGNhbyB04bqhaSBDYW5hZGEsIGThuqtuIMSR4bq/biBraMOzIMSRxrBhIHJhIGtodXnhur9uIG5naOG7iyBjaOG6r2MgY2jhuq9uLg0KDQojIyAqKjUuMy4gxJDhu4EgeHXhuqV0KioNCg0KKiBU4buRaSDGsHUgaMOzYSBuZ8OibiBzw6FjaCBtYXJrZXRpbmcgdOG6oWkgTeG7uSwgdOG6rXAgdHJ1bmcgdsOgbyBuaMOzbSB0aHUgbmjhuq1wIGNhbyB2w6AgdHJ1bmcgYsOsbmgg4oCTIHPhu60gZOG7pW5nIHRow7RuZyDEkWnhu4dwIHbhu4EgZ2nDoSB0cuG7iyB2w6AgY2jhuqV0IGzGsOG7o25nLg0KDQoqIFThuqFpIE1leGljbyB2w6AgQ2FuYWRhLCBuw6puIG5o4bqlbiBt4bqhbmggeeG6v3UgdOG7kSBjaGkgcGjDrSDigJMgdHJp4buDbiBraGFpIG5oaeG7gXUgY2jGsMahbmcgdHLDrG5oIGtodXnhur9uIG3Do2kgaG/hurdjIHPhuqNuIHBo4bqpbSBnacOhIHThu5F0Lg0KDQoqIFBow6JuIGtow7pjIHRoZW8gxJHhu5kgdHXhu5VpICsgZ2nhu5tpIHTDrW5oIMSR4buDIGPDoSBuaMOibiBow7NhIG7hu5lpIGR1bmc6IHF14bqjbmcgY8OhbyB0aOG7gyB0aGFvL2PDtG5nIG5naOG7hyBjaG8gbmFtIDM14oCTNTAsIHF14bqjbmcgY8OhbyBsw6BtIMSR4bq5cCBjaG8gbuG7ryB0cuG6uyB0deG7lWksLi4uDQoNCiogWGVtIHjDqXQgbeG7nyBy4buZbmcgZGFuaCBt4bulYyBz4bqjbiBwaOG6qW0gaG/hurdjIGThu4tjaCB24bulIHBow7kgaOG7o3AgaMahbiB24bubaSB04burbmcgcXXhu5FjIGdpYSDigJMgdsOtIGThu6U6IHPhuqNuIHBo4bqpbSBnaWEgZOG7pW5nIGNobyB0aOG7iyB0csaw4budbmcgTWV4aWNvLg0KDQojIyAqKjUuNC4gQ8OidSBo4buPaSBt4bufL0jGsOG7m25nIG5naGnDqm4gY+G7qXUgdGnhur9wIHRoZW8qKg0KDQoqIE5o4buvbmcgeeG6v3UgdOG7kSBuw6BvIG5nb8OgaSB0aHUgbmjhuq1wIOG6o25oIGjGsOG7n25nIMSR4bq/biBxdXnhur90IMSR4buLbmggbXVhPyBWw60gZOG7pTogdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuLCB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4sIHPhu5EgY29uLC4uLg0KDQoqIE7hur91IGPDsyB0aMOqbSBk4buvIGxp4buHdSDEkeG7i25oIGzGsOG7o25nLCBjw7MgdGjhu4MgeMOieSBk4buxbmcgbcO0IGjDrG5oIGThu7EgxJFvw6FuIGjDoG5oIHZpIG11YSBow6BuZyDEkeG7gyBjw6EgbmjDom4gaMOzYSBtYXJrZXRpbmcgaGnhu4d1IHF14bqjIGjGoW4uDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K