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ấtphầ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
Gender TanSuat PhanTram
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 1hì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
MaritalStatus TanSuat PhanTram
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 2hì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
Var1 Freq
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 3hì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
Var1 Freq
$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 4hì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$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
City Frequency Percentage
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, YakimaWalla 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
stateorprovince Fequency Percentage
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
Var1 Freq
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 7hì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
Var1 Freq
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 8hì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
Var1 Freq
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
Var1 Freq
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 10hì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
Gender ProductFamily Frequency Percentage
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 GenderProductFamily 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
MaritalStatus Homeowner Frequency Percentage
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 12hì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
AnnualIncome Country Frequency Percentage
$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.


PHẦN 5: TỔNG KẾT VÀ THẢO LUẬN

5.1. Tóm tắt những phát hiện chính

Dựa trên các phân tích định tính đã thực hiện, một số đặc điểm nổi bật về khách hàng và hành vi mua sắm đã được làm rõ:

  • Giới tính: Nhóm khách hàng có tỷ lệ nam giới cao hơn nữ giới một cách rõ rệt, đặc biệt trong nhóm tiêu dùng các dòng sản phẩm công nghệ và thể thao.

  • Sự khác biệt giữa các nhóm độ tuổi cũng cho thấy xu hướng tiêu dùng riêng biệt, với nhóm trung niên (35–50 tuổi) có tỷ lệ mua hàng cao hơn ở nhiều danh mục sản phẩm.

  • Về mặt địa lý, người tiêu dùng tại Hoa Kỳ chiếm tỷ trọng áp đảo trong hầu hết các nhóm thu nhập, phản ánh thị trường rộng lớn và ổn định của quốc gia này. Trong khi đó, Mexico và Canada có tỷ lệ thấp hơn, song thể hiện sự tập trung ở các nhóm thu nhập trung bình.

  • Mối quan hệ giữa thu nhập và danh mục sản phẩm cũng cho thấy rằng người có thu nhập cao có xu hướng quan tâm đến các sản phẩm thuộc nhóm cao cấp hoặc công nghệ.

5.2. Hạn chế của phân tích

  • Chỉ dùng biến định tính, không phân tích được chi tiêu thực tế.

  • Không có dữ liệu hành vi online (clicks, browsing) – bỏ lỡ nhiều insight quan trọng về hành trình khách hàng.

  • Một số phân nhóm quá nhỏ, ví dụ như thu nhập cao tại Canada, dẫn đến khó đưa ra khuyến nghị chắc chắn.

5.3. Đề xuất

  • Tối ưu hóa ngân sách marketing tại Mỹ, tập trung vào nhóm thu nhập cao và trung bình – sử dụng thông điệp về giá trị và chất lượng.

  • Tại Mexico và Canada, nên nhấn mạnh yếu tố chi phí – triển khai nhiều chương trình khuyến mãi hoặc sản phẩm giá tốt.

  • Phân khúc theo độ tuổi + giới tính để cá nhân hóa nội dung: quảng cáo thể thao/công nghệ cho nam 35–50, quảng cáo làm đẹp cho nữ trẻ tuổi,…

  • Xem xét mở rộng danh mục sản phẩm hoặc dịch vụ phù hợp hơn với từng quốc gia – ví dụ: sản phẩm gia dụng cho thị trường Mexico.

5.4. Câu hỏi mở/Hướng nghiên cứu tiếp theo

  • Những yếu tố nào ngoài thu nhập ảnh hưởng đến quyết định mua? Ví dụ: trình độ học vấn, tình trạng hôn nhân, số con,…

  • Nếu có thêm dữ liệu định lượng, có thể xây dựng mô hình dự đoán hành vi mua hàng để cá nhân hóa marketing hiệu quả hơn.

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