1 Đọc dữ liệu

hoangtinhdulieu là bộ dữ liệu chứa thông tin tổng hợp về nhân khẩu học và đặc điểm kinh tế xã hội của khoảng 25.000 người đang sinh sống và làm việc tại Mỹ. Dữ liệu được xây dựng dựa trên nguồn gốc từ Current Population Survey (CPS) – một chương trình khảo sát dân số uy tín được thực hiện hàng năm bởi Cục điều tra dân số Hoa Kỳ (U.S. Census Bureau) phối hợp với Bureau of Labor Statistics.

Bộ dữ liệu đã được trích lọc, xử lý và tái cấu trúc nhằm phục vụ cho mục tiêu phân tích và huấn luyện mô hình học máy trong các nghiên cứu liên quan đến kinh tế học, hành vi lao động và bất bình đẳng thu nhập.

1.1 Đọc file

d <-read.csv(file.choose(), header=T)

Dòng lệnh d <- read.csv(file.choose(), header = TRUE) dùng để đọc dữ liệu từ một file CSV chọn trên máy tính.

  • file.choose() mở hộp thoại chọn file.
  • read.csv(...) đọc file CSV và trả về dạng bảng dữ liệu (data frame).
  • header = TRUE nghĩa là dòng đầu tiên của file là tên các cột.
  • Kết quả được lưu vào biến d để sử dụng cho các phân tích tiếp theo.

1.2 Hiển thị cấu trúc của dữ liệu

str(d)
## 'data.frame':    25998 obs. of  12 variables:
##  $ age                : int  21 33 19 41 52 49 32 28 54 43 ...
##  $ CensusWeight       : int  433330 278514 236940 112507 89041 189498 323055 31935 88019 69758 ...
##  $ learningLevel      : chr  "Some-college" "HS-grad" "HS-grad" "10th" ...
##  $ learningLevel.num  : int  10 9 9 6 9 9 9 10 10 12 ...
##  $ PartneringState    : chr  "Never-married" "Divorced" "Never-married" "Married-civ-spouse" ...
##  $ FamilyRole         : chr  "Unmarried" "Own-child" "Own-child" "Husband" ...
##  $ Ethnicity          : chr  "White" "White" "White" "White" ...
##  $ Gender             : chr  "Male" "Female" "Male" "Male" ...
##  $ NegativeCapitalFlow: int  0 0 0 0 0 0 0 0 0 0 ...
##  $ WeeklyHours        : int  40 42 40 60 40 50 40 40 55 40 ...
##  $ Nationality        : chr  "United-States" "United-States" "United-States" "United-States" ...
##  $ EarningClass       : chr  "<=50K" "<=50K" "<=50K" "<=50K" ...
  • str(...) là viết tắt của structure – dùng để kiểm tra nhanh thông tin về số dòng, số cột, tên biến và kiểu dữ liệu của từng biến.

  • Khi dùng str(d), bạn sẽ biết được:

  • d có bao nhiêu quan sát (rows) và biến (columns)

  • Tên của các biến

  • Kiểu dữ liệu của từng biến (vd: int, chr, factor, num…)

=> Dữ liệu bao gồm: 25998 quan sát và 12 biến, trong đó có 7 biến định tính

variable_explain <- data.frame(
  Ten_Bien = c("age", "CensusWeight", "learningLevel", "learningLevel.num", "PartneringState", 
               "FamilyRole", "Ethnicity", "Gender", "NegativeCapitalFlow", "WeeklyHours", 
               "Nationality", "EarningClass"),
  Y_Nghia = c(
"Độ tuổi của người được khảo sát",
"Đại diện của cá nhân trong mẫu điều tra dân số",
"Trình độ học vấn chính thức (ví dụ: Tốt nghiệp cấp 3, Đại học chưa hoàn thành)",
"Số năm học tập chính quy tương đương với trình độ học vấn",
"Tình trạng hôn nhân hiện tại (Đã kết hôn, Ly thân, Góa vợ/chồng...)",
"Vai trò trong hộ gia đình (ví dụ: Con cái, Không thuộc hộ gia đình)",
"Chủng tộc hoặc nhóm dân tộc (Người da trắng, Châu Á, v.v.)",
"Giới tính của cá nhân (Nam hoặc Nữ)",
"Mức lỗ tài sản phát sinh từ hoạt động đầu tư vốn",
"Số giờ làm việc trung bình trong một tuần",
"Quốc gia nơi cá nhân sinh sống hoặc khai báo là nơi sinh",
"Thu nhập cá nhân mỗi năm"
  )
)

library(knitr)
## Warning: package 'knitr' was built under R version 4.3.3
kable(variable_explain, caption = "Giải thích các biến trong bộ dữ liệu")
Giải thích các biến trong bộ dữ liệu
Ten_Bien Y_Nghia
age Độ tuổi của người được khảo sát
CensusWeight Đại diện của cá nhân trong mẫu điều tra dân số
learningLevel Trình độ học vấn chính thức (ví dụ: Tốt nghiệp cấp 3, Đại học chưa hoàn thành)
learningLevel.num Số năm học tập chính quy tương đương với trình độ học vấn
PartneringState Tình trạng hôn nhân hiện tại (Đã kết hôn, Ly thân, Góa vợ/chồng…)
FamilyRole Vai trò trong hộ gia đình (ví dụ: Con cái, Không thuộc hộ gia đình)
Ethnicity Chủng tộc hoặc nhóm dân tộc (Người da trắng, Châu Á, v.v.)
Gender Giới tính của cá nhân (Nam hoặc Nữ)
NegativeCapitalFlow Mức lỗ tài sản phát sinh từ hoạt động đầu tư vốn
WeeklyHours Số giờ làm việc trung bình trong một tuần
Nationality Quốc gia nơi cá nhân sinh sống hoặc khai báo là nơi sinh
EarningClass Thu nhập cá nhân mỗi năm
  • variable_explain <- data.frame(...) : Tạo một bảng dữ liệu (data frame) gồm 2 cột

  • Ten_Bien: Tên biến trong bộ dữ liệu.

  • Y_Nghia: Ý nghĩa mô tả của từng biến đó.

  • kable(variable_explain, caption = "Giải thích các biến"): Hàm kable() dùng để hiển thị bảng mô tả trên dưới dạng trình bày rõ ràng, dễ đọc.

  • caption = "Giải thích các biến" đặt tiêu đề cho bảng là “Giải thích các biến”.

1.3 Hiển thị một vài dòng đầu và cuối của dữ liệu

  • head(d): Hiển thị 6 dòng đầu của bộ dữ liệu
# Hiển thị 6 dòng đầu của bộ dữ liệu
head(d)
##   age CensusWeight learningLevel learningLevel.num    PartneringState
## 1  21       433330  Some-college                10      Never-married
## 2  33       278514       HS-grad                 9           Divorced
## 3  19       236940       HS-grad                 9      Never-married
## 4  41       112507          10th                 6 Married-civ-spouse
## 5  52        89041       HS-grad                 9 Married-civ-spouse
## 6  49       189498       HS-grad                 9 Married-civ-spouse
##   FamilyRole Ethnicity Gender NegativeCapitalFlow WeeklyHours   Nationality
## 1  Unmarried     White   Male                   0          40 United-States
## 2  Own-child     White Female                   0          42 United-States
## 3  Own-child     White   Male                   0          40 United-States
## 4    Husband     White   Male                   0          60 United-States
## 5    Husband     White   Male                   0          40 United-States
## 6    Husband     White   Male                   0          50 United-States
##   EarningClass
## 1        <=50K
## 2        <=50K
## 3        <=50K
## 4        <=50K
## 5        <=50K
## 6         >50K
  • tail(d): Hiển thị 6 dòng cuối của bộ dữ liệu
# Hiển thị 6 dòng cuối của bộ dữ liệu
tail(d)
##       age CensusWeight learningLevel learningLevel.num PartneringState
## 25993  34       216864       HS-grad                 9        Divorced
## 25994  41       264663  Some-college                10       Separated
## 25995  54       140359       7th-8th                 4        Divorced
## 25996  66       186061  Some-college                10         Widowed
## 25997  82       132870       HS-grad                 9         Widowed
## 25998  90        77053       HS-grad                 9         Widowed
##          FamilyRole Ethnicity Gender NegativeCapitalFlow WeeklyHours
## 25993     Unmarried     White Female                3770          45
## 25994     Own-child     White Female                3900          40
## 25995     Unmarried     White Female                3900          40
## 25996     Unmarried     Black Female                4356          40
## 25997 Not-in-family     White Female                4356          18
## 25998 Not-in-family     White Female                4356          40
##         Nationality EarningClass
## 25993 United-States        <=50K
## 25994 United-States        <=50K
## 25995 United-States        <=50K
## 25996 United-States        <=50K
## 25997 United-States        <=50K
## 25998 United-States        <=50K

1.4 Kiểm tra giá trị thiếu

sum(is.na(d))
## [1] 0
  • sum(is.na(d)): Kiểm tra tổng số giá trị NA trong toàn bộ bảng.

=> Kết quả: Trong bộ dữ liệu không có giá trị thiếu (NA).

1.5 Chuyển đổi các biến cần thiết

# Đọc dữ liệu
d <- read.csv("hoangtinhdulieu.csv")

# Danh sách các biến định tính (categorical variables)
cols_to_factor <- c("learningLevel", "PartneringState", "FamilyRole",
                    "Ethnicity", "Gender", "Nationality", "EarningClass")

# Chuyển các cột đó sang factor
d[cols_to_factor] <- lapply(d[cols_to_factor], as.factor)

# Kiểm tra lại cấu trúc dữ liệu
str(d)
## 'data.frame':    25998 obs. of  12 variables:
##  $ age                : int  21 33 19 41 52 49 32 28 54 43 ...
##  $ CensusWeight       : int  433330 278514 236940 112507 89041 189498 323055 31935 88019 69758 ...
##  $ learningLevel      : Factor w/ 16 levels "10th","11th",..: 16 12 12 1 12 12 12 16 16 8 ...
##  $ learningLevel.num  : int  10 9 9 6 9 9 9 10 10 12 ...
##  $ PartneringState    : Factor w/ 7 levels "Divorced","Married-AF-spouse",..: 5 1 5 3 3 3 3 1 1 3 ...
##  $ FamilyRole         : Factor w/ 6 levels "Husband","Not-in-family",..: 5 4 4 1 1 1 1 2 2 1 ...
##  $ Ethnicity          : Factor w/ 5 levels "Amer-Indian-Eskimo",..: 5 5 5 5 5 5 5 5 5 2 ...
##  $ Gender             : Factor w/ 2 levels "Female","Male": 2 1 2 2 2 2 2 1 2 2 ...
##  $ NegativeCapitalFlow: int  0 0 0 0 0 0 0 0 0 0 ...
##  $ WeeklyHours        : int  40 42 40 60 40 50 40 40 55 40 ...
##  $ Nationality        : Factor w/ 42 levels "?","Cambodia",..: 40 40 40 40 40 40 40 40 40 40 ...
##  $ EarningClass       : Factor w/ 2 levels "<=50K",">50K": 1 1 1 1 1 2 1 1 1 1 ...

Đầu tiên, cần xác định các biến có giá trị rời rạc và mang tính phân loại, thường dùng để biểu diễn thông tin định tính như giới tính, học vấn, tình trạng hôn nhân, v.v. Danh sách này sẽ được sử dụng để chuyển sang kiểu dữ liệu factor.

Sau đó, áp dụng hàm lapply(…, as.factor) để chuyển đổi từng biến trong danh sách thành kiểu factor.

Cuối cùng, cập nhật bảng dữ liệu d với các cột đã được chuyển đổi sang dạng phân loại.

Các biến định tính bao gồm:

learningLevel: biểu thị trình độ học vấn với 16 cấp độ khác nhau (ví dụ: HS-grad, Bachelors, Some-college…)

PartneringState: thể hiện tình trạng quan hệ như Married, Divorced, Widowed, Separated, Never-married

FamilyRole: mô tả vị trí của cá nhân trong hộ gia đình, như Own-child, Not-in-family, Husband, Wife…

Ethnicity: gồm 5 nhóm chủng tộc chính trong dữ liệu

Gender: 2 giá trị (Male, Female)

Nationality: quốc gia xuất xứ, với hơn 30 quốc gia (phần lớn là United-States)

EarningClass: phân loại thu nhập cá nhân thành 2 nhóm (<=50K, >50K)

2 Phân tích Mô tả Một biến Định tính

# Danh sách biến định tính thực tế trong file
tbdt <- c("learningLevel", "PartneringState", "FamilyRole",
          "Ethnicity", "Gender", "Nationality", "EarningClass")

# Tạo bảng con chỉ gồm các biến định tính
dq <- d[, tbdt]

# Kiểm tra
str(dq)
## 'data.frame':    25998 obs. of  7 variables:
##  $ learningLevel  : Factor w/ 16 levels "10th","11th",..: 16 12 12 1 12 12 12 16 16 8 ...
##  $ PartneringState: Factor w/ 7 levels "Divorced","Married-AF-spouse",..: 5 1 5 3 3 3 3 1 1 3 ...
##  $ FamilyRole     : Factor w/ 6 levels "Husband","Not-in-family",..: 5 4 4 1 1 1 1 2 2 1 ...
##  $ Ethnicity      : Factor w/ 5 levels "Amer-Indian-Eskimo",..: 5 5 5 5 5 5 5 5 5 2 ...
##  $ Gender         : Factor w/ 2 levels "Female","Male": 2 1 2 2 2 2 2 1 2 2 ...
##  $ Nationality    : Factor w/ 42 levels "?","Cambodia",..: 40 40 40 40 40 40 40 40 40 40 ...
##  $ EarningClass   : Factor w/ 2 levels "<=50K",">50K": 1 1 1 1 1 2 1 1 1 1 ...
  • Đây là danh sách (vector) chứa tên các cột – đều là biến định tính.

  • Lấy toàn bộ các cột trong danh sách tbdt từ bảng dữ liệu d, và tạo ra một bảng mới tên là dq.

=> Kết quả là bảng dq chỉ chứa các biến định tính.

2.1 Biến learningLevel

2.1.1 Giải thích biến

# Tạo bảng giải thích các mức của biến learningLevel
learningLevel_levels <- data.frame(
  Gia_tri = c("Preschool", "1st-4th", "5th-6th", "7th-8th", "9th", "10th",
              "11th", "12th", "HS-grad", "Some-college", "Assoc-acdm", 
              "Assoc-voc", "Bachelors", "Masters", "Prof-school", "Doctorate"),
  Y_nghia = c(
    "Trình độ mầm non",
    "Học hết lớp 1 đến lớp 4",
    "Học hết lớp 5 hoặc lớp 6",
    "Học hết lớp 7 hoặc lớp 8",
    "Học hết lớp 9",
    "Học hết lớp 10",
    "Học hết lớp 11",
    "Học hết lớp 12 nhưng không tốt nghiệp",
    "Tốt nghiệp trung học phổ thông (HS-grad)",
    "Học đại học/cao đẳng nhưng chưa có bằng",
    "Bằng cao đẳng học thuật (Associate in Academic Program)",
    "Bằng cao đẳng nghề (Associate in Vocational Program)",
    "Bằng cử nhân (Đại học)",
    "Bằng thạc sĩ",
    "Bằng chuyên ngành sau đại học (luật, y khoa…)",
    "Bằng tiến sĩ"
  )
)

# Hiển thị bảng
knitr::kable(learningLevel_levels, caption = "Giải thích các mức độ trong biến learningLevel")
Giải thích các mức độ trong biến learningLevel
Gia_tri Y_nghia
Preschool Trình độ mầm non
1st-4th Học hết lớp 1 đến lớp 4
5th-6th Học hết lớp 5 hoặc lớp 6
7th-8th Học hết lớp 7 hoặc lớp 8
9th Học hết lớp 9
10th Học hết lớp 10
11th Học hết lớp 11
12th Học hết lớp 12 nhưng không tốt nghiệp
HS-grad Tốt nghiệp trung học phổ thông (HS-grad)
Some-college Học đại học/cao đẳng nhưng chưa có bằng
Assoc-acdm Bằng cao đẳng học thuật (Associate in Academic Program)
Assoc-voc Bằng cao đẳng nghề (Associate in Vocational Program)
Bachelors Bằng cử nhân (Đại học)
Masters Bằng thạc sĩ
Prof-school Bằng chuyên ngành sau đại học (luật, y khoa…)
Doctorate Bằng tiến sĩ
  • learningLevel_levels <- data.frame(…): Tạo một bảng dữ liệu có hai cột: Gia_tri (giá trị gốc trong biến learningLevel) và Y_nghia (ý nghĩa tiếng Việt tương ứng).

  • Gia_tri = c(…): Tập hợp 16 mức trình độ học vấn được mã hoá trong dữ liệu, ví dụ “Preschool”, “Bachelors”, “Doctorate”…

  • Y_nghia = c(…): Cung cấp giải thích tiếng Việt cho từng mức trong Gia_tri. Ví dụ “Preschool” tương ứng với “Trình độ mầm non”, “Bachelors” là “Bằng cử nhân”…

  • knitr::kable(learningLevel_levels, caption = “Giải thích các mức độ trong biến learningLevel”): Dùng hàm kable() để in bảng ra đẹp hơn khi tạo báo cáo R Markdown. caption là tiêu đề hiển thị trên bảng.

2.1.2 Thống kê tần suất

# Tạo bảng tần suất cho learningLevel
ts_edu <- table(d$learningLevel)

# Tạo bảng dữ liệu
ts_edu_df <- data.frame(
  Gia_tri = names(ts_edu),
  Tan_so = as.vector(ts_edu),
  Ty_le = round((as.vector(ts_edu) / sum(ts_edu)) * 100, 2)
)

# Hiển thị kết quả
ts_edu_df
##         Gia_tri Tan_so Ty_le
## 1          10th    734  2.82
## 2          11th    926  3.56
## 3          12th    328  1.26
## 4       1st-4th    125  0.48
## 5       5th-6th    251  0.97
## 6       7th-8th    506  1.95
## 7           9th    401  1.54
## 8    Assoc-acdm    831  3.20
## 9     Assoc-voc   1104  4.25
## 10    Bachelors   4377 16.84
## 11    Doctorate    342  1.32
## 12      HS-grad   8360 32.16
## 13      Masters   1406  5.41
## 14    Preschool     37  0.14
## 15  Prof-school    482  1.85
## 16 Some-college   5788 22.26
  • Gia_tri = names(ts_edu): Lấy tên các mức giá trị (mức học vấn) từ bảng tần suất ts_edu, ví dụ: “Preschool”, “Bachelors”, “Doctorate”…

  • Tan_so = as.vector(ts_edu): Chuyển bảng tần suất thành vector để lưu số lượng xuất hiện của từng mức học vấn.

  • Ty_le = round((as.vector(ts_edu) / sum(ts_edu)) * 100, 2): Tính tỷ lệ phần trăm của mỗi mức học vấn so với tổng toàn bộ (dựa trên tần suất), rồi làm tròn đến 2 chữ số thập phân.

  • ts_edu_df: Hiển thị bảng kết quả ts_edu_df, gồm tên mức học vấn, tần suất và tỷ lệ phần trăm tương ứng.

Bộ dữ liệu này ghi nhận nhiều mức trình độ học vấn khác nhau của người tham gia. Trong đó:

3 mức đầu tiên gồm:

10th: 734 người (chiếm 2.82%),

11th: 926 người (chiếm 3.56%),

12th: 328 người (chiếm 1.26%).

3 mức cuối cùng gồm:

Some-college: 5788 người (chiếm 22.26%),

Preschool: 37 người (chiếm 0.14%),

Prof-school: 482 người (chiếm 1.85%).

2.1.3 Trực quan hóa

library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.3.3
# Vẽ biểu đồ cột cho biến learningLevel
ggplot(ts_edu_df, aes(x = reorder(Gia_tri, -Tan_so), y = Tan_so, fill = Gia_tri)) +
  geom_col(color = "white", width = 0.7) +
  geom_text(aes(label = Tan_so),
            vjust = -0.5, size = 4, fontface = "bold", color = "lightblue") +
  labs(
    title = "Biểu đồ cột: Phân bố trình độ học vấn (learningLevel)",
    x = "Trình độ học vấn",
    y = "Tần số"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1)
  )

  • ```{r fig.width=12, fig.height=6}: Đây là phần mở đầu của một khối mã R trong R Markdown, thiết lập kích thước hình ảnh đầu ra: chiều rộng 12 đơn vị, chiều cao 6 đơn vị.

  • library(ggplot2): Nạp thư viện ggplot2 để sử dụng các hàm vẽ biểu đồ trong hệ thống đồ họa ggplot.

  • ggplot(ts_edu_df, aes(x = reorder(Gia_tri, -Tan_so), y = Tan_so, fill = Gia_tri)) : Khởi tạo biểu đồ cột từ bảng ts_edu_df. Trục x là biến Gia_tri (tên mức học vấn), được sắp xếp theo Tan_so giảm dần. Trục y là Tan_so. Màu sắc của từng cột được phân biệt theo Gia_tri.

  • geom_col(color = “white”, width = 0.7) : Vẽ các cột biểu đồ với viền trắng và độ rộng 0.7.

  • geom_text(aes(label = Tan_so), vjust = -0.5, size = 4, fontface = “bold”, color = “black”) : Thêm nhãn số liệu (giá trị tần số) trên đầu mỗi cột, canh chỉnh nhãn hơi cao hơn cột (vjust = -0.5), chữ đậm màu đen và cỡ 4.

  • labs(…) : Đặt tiêu đề biểu đồ là “Biểu đồ cột: Phân bố trình độ học vấn (learningLevel)”, trục x là “Trình độ học vấn” và trục y là “Tần số”.

  • theme_minimal(base_size = 12) : Áp dụng giao diện tối giản cho biểu đồ với cỡ chữ cơ bản là 12.

  • theme(…): Tuỳ chỉnh thêm cho biểu đồ:

  • plot.title = element_text(hjust = 0.5, face = “bold”): Căn giữa tiêu đề và in đậm.

  • axis.text.x = element_text(angle = 45, hjust = 1): Xoay nhãn trục x 45 độ, canh lề cho dễ đọc.

library(ggplot2)

# Vẽ biểu đồ cột cho tỷ lệ phần trăm trình độ học vấn
ggplot(ts_edu_df, aes(x = reorder(Gia_tri, -Ty_le), y = Ty_le, fill = Gia_tri)) +
  geom_col(color = "white", width = 0.7) +
  geom_text(aes(label = paste0(Ty_le, "%")),
            vjust = -0.5, size = 4, fontface = "bold", color = "lightblue") +
  labs(
    title = "Biểu đồ cột: Tỷ lệ trình độ học vấn (learningLevel)",
    x = "Trình độ học vấn",
    y = "Tỷ lệ (%)"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1)
  )

### Nhận xét

HS-grad (tốt nghiệp phổ thông) là trình độ học vấn phổ biến nhất với 10.501 người, chiếm ~32.3% tổng mẫu. Điều này cho thấy phần lớn người tham gia khảo sát chỉ dừng lại ở trình độ trung học.

Some-college (đã học đại học nhưng chưa tốt nghiệp) đứng thứ hai với 7.291 người, tương đương ~22.4%, phản ánh xu hướng khá nhiều người từng tiếp cận bậc học đại học nhưng không hoàn tất.

Bachelors (cử nhân) là trình độ học vấn đầy đủ cấp đại học phổ biến nhất với 5.355 người (~16.5%), cao hơn hẳn so với các trình độ sau đại học.

Các trình độ học vấn thấp như:

  • 11th (lớp 11) – 1.175 người

  • 10th (lớp 10) – 1.067 người

  • 7th-8th – 933 người

→ Những mức này cho thấy còn có một bộ phận dân số không hoàn thành bậc phổ thông.

Các cấp độ sau đại học như:

  • Masters (thạc sĩ) – 576 người (~1.8%)

  • Doctorate (tiến sĩ) – 413 người (~1.3%)

  • Prof-school (chuyên khoa như y, luật) – 514 người (~1.6%)

→ Tổng lại chỉ khoảng 1.500 người (~4.6%), chứng tỏ số người học cao học vẫn là thiểu số.

Các trình độ rất thấp như:

  • 1st-4th (lớp 1–4) – 168 người

  • Preschool (mẫu giáo) – 51 người

→ Cực kỳ hiếm gặp trong mẫu khảo sát (chưa đến 0.7% tổng số), thường thuộc nhóm người di cư hoặc cao tuổi.

Các trình độ ngắn hạn hoặc liên kết như:

  • Assoc-voc – 1.382 người

  • Assoc-acdm – 1.723 người

→ Chiếm khoảng 3.2% và 5.3% tương ứng, thể hiện mô hình giáo dục nghề/ngắn hạn có mặt nhưng không chiếm ưu thế.

2.2 Biến PartneringState

2.2.1 Giải thích biến

# Giải thích các mức của biến PartneringState
marital_levels <- data.frame(
  Gia_tri = c("Divorced", "Married-AF-spouse", "Married-civ-spouse",
              "Married-spouse-absent", "Never-married", "Separated", "Widowed"),
  Y_nghia = c(
    "Ly dị",
    "Kết hôn với người trong lực lượng vũ trang",
    "Đã kết hôn hợp pháp",
    "Kết hôn nhưng sống ly thân",
    "Chưa từng kết hôn",
    "Ly thân có pháp lý",
    "Góa"
  )
)

knitr::kable(marital_levels, caption = "Giải thích các mức trong biến PartneringState")
Giải thích các mức trong biến PartneringState
Gia_tri Y_nghia
Divorced Ly dị
Married-AF-spouse Kết hôn với người trong lực lượng vũ trang
Married-civ-spouse Đã kết hôn hợp pháp
Married-spouse-absent Kết hôn nhưng sống ly thân
Never-married Chưa từng kết hôn
Separated Ly thân có pháp lý
Widowed Góa

2.2.2 Thống kê Tần suất

# Tạo bảng tần suất cho PartneringState
ts_marital <- table(d$PartneringState)

# Tạo bảng dữ liệu
ts_marital_df <- data.frame(
  Gia_tri = names(ts_marital),
  Tan_so = as.vector(ts_marital),
  Ty_le = round((as.vector(ts_marital) / sum(ts_marital)) * 100, 2)
)

# Hiển thị kết quả
ts_marital_df
##                 Gia_tri Tan_so Ty_le
## 1              Divorced   3526 13.56
## 2     Married-AF-spouse     17  0.07
## 3    Married-civ-spouse  12115 46.60
## 4 Married-spouse-absent    334  1.28
## 5         Never-married   8398 32.30
## 6             Separated    812  3.12
## 7               Widowed    796  3.06
  • Đã ly dị (Divorced): có 3526 người (chiếm 13.56%).

  • Kết hôn với người trong quân đội (Married-AF-spouse): có 17 người (chiếm 0.07%).

  • Đã kết hôn hợp pháp (Married-civ-spouse): có 12115 người (chiếm 46.6%).

  • Ly thân (Married-spouse-absent): có 334 người (chiếm 1.28%).

  • Chưa từng kết hôn (Never-married): có 8398 người (chiếm 32.3%).

  • Ly thân có pháp lý (Separated): có 812 người (chiếm 3.12%).

  • Góa (Widowed): có 796 người (chiếm 3.06%).

2.2.3 Trực quan hóa

ggplot(ts_marital_df, aes(x = reorder(Gia_tri, -Tan_so), y = Tan_so, fill = Gia_tri)) +
  geom_col(width = 0.5, color = "pink") +
  geom_text(aes(label = Tan_so), vjust = -0.3, size = 4, fontface = "bold") +
  labs(
    title = "Biểu đồ cột: Tình trạng hôn nhân (PartneringState)",
    x = "Tình trạng hôn nhân",
    y = "Tần số"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    
  )

ggplot(ts_marital_df, aes(x = reorder(Gia_tri, Ty_le), y = Ty_le, fill = Gia_tri)) +
  geom_col(width = 0.6, color = "lightpink") +
  geom_text(aes(label = paste0(Ty_le, "%")),
            hjust = -0.1, size = 4, fontface = "bold", color = "lightyellow") +
  coord_flip() +
  labs(
    title = "Biểu đồ cột ngang: Tỷ lệ tình trạng hôn nhân (PartneringState)",
    x = "Tình trạng hôn nhân",
    y = "Tỷ lệ (%)"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold")
  )

  • ggplot(ts_marital_df, aes(x = reorder(Gia_tri, Tan_so), y = Tan_so, fill = Gia_tri)) : Tạo biểu đồ cột từ bảng ts_marital_df. Trục hoành (x) là biến Gia_tri – các mức của tình trạng hôn nhân – được sắp xếp tăng dần theo Tan_so. Trục tung (y) là tần số tương ứng. Mỗi cột có màu khác nhau theo giá trị của Gia_tri.

  • geom_col(width = 0.6, color = “white”): Vẽ các cột với chiều rộng là 0.6 và viền màu trắng, giúp cột tách biệt rõ ràng.

  • geom_text(aes(label = Tan_so), hjust = -0.1, size = 4, fontface = “bold”, color = “black”) : Thêm nhãn số liệu (Tan_so) cho từng cột. Nhãn được đặt hơi lệch trái (hjust = -0.1), cỡ chữ 4, in đậm và màu đen.

  • coord_flip() : Lật hệ trục tọa độ để biểu đồ hiển thị theo chiều ngang – tức là các cột sẽ nằm ngang thay vì dọc.

  • labs(…) : Đặt tiêu đề biểu đồ là “Biểu đồ cột ngang: Tình trạng hôn nhân (PartneringState)”, trục x là “Tình trạng hôn nhân”, trục y là “Tần số”.

  • theme_minimal(base_size = 13) : Áp dụng giao diện tối giản (minimal) cho biểu đồ với cỡ chữ mặc định là 13.

  • theme(plot.title = element_text(hjust = 0.5, face = “bold”), …) Tuỳ chỉnh tiêu đề biểu đồ để căn giữa (hjust = 0.5) và in đậm (face = “bold”).

2.2.4 Nhận xét

  • “Married-civ-spouse” (kết hôn hợp pháp) chiếm 43.94%, cao nhất trong toàn bộ dữ liệu – cho thấy cấu trúc gia đình truyền thống vẫn chiếm ưu thế.

  • “Never-married” đạt 32.81%, là nhóm lớn thứ hai, phản ánh sự hiện diện mạnh mẽ của người độc thân.

  • Các nhóm còn lại như “Divorced” (12.29%), “Married-spouse-absent” (4.79%), “Separated” (3.13%), và “Widowed” (3.05%) góp phần tạo nên tính đa dạng trong tình trạng hôn nhân, nhưng đều chiếm tỷ lệ thấp hơn

2.3 Biến FamilyRole

2.3.1 Giải thích biến

# Giải thích các mức của biến FamilyRole
FamilyRole_levels <- data.frame(
  Gia_tri = c("Husband", "Not-in-family", "Other-relative", 
              "Own-child", "Unmarried", "Wife"),
  Y_nghia = c(
    "Chồng",
    "Không cùng gia đình (bạn trọ, bạn bè)",
    "Họ hàng khác (cháu, cô, chú...)",
    "Con ruột",
    "Không kết hôn (độc thân, ly dị...)",
    "Vợ"
  )
)

knitr::kable(FamilyRole_levels, caption = "Giải thích các mức trong biến FamilyRole")
Giải thích các mức trong biến FamilyRole
Gia_tri Y_nghia
Husband Chồng
Not-in-family Không cùng gia đình (bạn trọ, bạn bè)
Other-relative Họ hàng khác (cháu, cô, chú…)
Own-child Con ruột
Unmarried Không kết hôn (độc thân, ly dị…)
Wife Vợ

2.3.2 Thống kê Tần suất

# Tạo bảng tần suất cho FamilyRole
ts_FamilyRole <- table(d$FamilyRole)

# Tạo bảng dữ liệu
ts_FamilyRole_df <- data.frame(
  Gia_tri = names(ts_FamilyRole),
  Tan_so = as.vector(ts_FamilyRole),
  Ty_le = round((as.vector(ts_FamilyRole) / sum(ts_FamilyRole)) * 100, 2)
)

# Hiển thị kết quả
ts_FamilyRole_df
##          Gia_tri Tan_so Ty_le
## 1        Husband  10660 41.00
## 2  Not-in-family   6628 25.49
## 3 Other-relative    747  2.87
## 4      Own-child   3979 15.31
## 5      Unmarried   2702 10.39
## 6           Wife   1282  4.93
  • Biến FamilyRole (mối quan hệ trong hộ gia đình) bao gồm 6 mức như sau:

    • Không trong gia đình (Not-in-family): có 6628 người (chiếm 25.49%).
  • Họ hàng khác (Other-relative): có 747 người (chiếm 2.87%).

  • Con ruột (Own-child): có 3979 người (chiếm 15.31%).

  • Độc thân (Unmarried): có 2702 người (chiếm 10.39%).

  • Vợ (Wife): có 1282 người (chiếm 4.93%).

2.3.3 Trực quan hóa

ggplot(ts_FamilyRole_df, aes(x = reorder(Gia_tri, -Tan_so), y = Tan_so, fill = Gia_tri)) +
  geom_col(width = 0.5, color = "skyblue") +
  geom_text(aes(label = Tan_so), vjust = -0.3, size = 4, fontface = "bold") +
  labs(
    title = "Biểu đồ cột: Mối quan hệ trong hộ (FamilyRole)",
    x = "Mối quan hệ",
    y = "Tần số"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
  
  )

ggplot(ts_FamilyRole_df, aes(x = "", y = Ty_le, fill = Gia_tri)) +
  geom_col(width = 1, color = "skyblue") +
  coord_polar(theta = "y") +
  scale_fill_brewer(palette = "Set2") +
  labs(title = "Biểu đồ tròn: Mối quan hệ trong hộ") +
  geom_text(aes(label = paste0(Ty_le, "%")),
            position = position_stack(vjust = 0.5),
            size = 4, color = "pink") +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    legend.title = element_blank()
  )

  • coord_polar(theta = “y”) : Chuyển biểu đồ cột thành biểu đồ tròn bằng cách sử dụng hệ tọa độ cực (polar coordinate system), trong đó phần trăm (Ty_le) được xoay theo trục y để tạo ra các phần hình quạt.

  • scale_fill_brewer(palette = “Set2”) : Áp dụng bảng màu “Set2” từ thư viện RColorBrewer để phân biệt trực quan các phần khác nhau của biểu đồ tròn bằng các màu sắc hài hòa.

  • theme_void() : Xóa tất cả thành phần nền của biểu đồ (trục, lưới, nhãn trục…), giúp biểu đồ tròn trông gọn gàng và nổi bật hơn.

  • legend.title = element_blank(): Ẩn tiêu đề của phần chú giải (legend) để giao diện biểu đồ trở nên đơn giản và dễ đọc hơn.

2.3.4 Nhận xét

  • Nhóm “Husband” chiếm tỷ lệ cao nhất với 38.1%, phản ánh vai trò trụ cột của nam giới trong hộ gia đình vẫn còn phổ biến. Điều này có thể liên quan đến thói quen khai báo người đứng đầu hộ là nam giới.

  • “Not-in-family” xếp thứ hai với 26.4%, cho thấy có nhiều cá nhân sống độc lập hoặc không thuộc hộ truyền thống – phản ánh xu hướng sống đơn thân trong xã hội hiện đại.

  • “Own-child” chiếm 15.7%, cho thấy tỷ lệ người phụ thuộc đáng kể trong hộ, trong khi “Wife” chỉ đạt 7.2%, có thể do nam giới là người được khảo sát nhiều hơn.

  • Các nhóm “Unmarried” (11.2%) và “Other-relative” (1.4%) có tỷ lệ thấp, nhưng góp phần làm rõ tính đa dạng trong cấu trúc hộ gia đình hiện nay. ## Biến Ethnicity

2.3.5 Giải thích biến

# Giải thích các mức của biến Ethnicity
Ethnicity_levels <- data.frame(
  Gia_tri = c("Amer-Indian-Eskimo", "Asian-Pac-Islander", "Black", "Other", "White"),
  Y_nghia = c(
    "Người da đỏ/Thổ dân Bắc Mỹ",
    "Người châu Á hoặc dân đảo Thái Bình Dương",
    "Người da đen",
    "Khác",
    "Người da trắng"
  )
)

knitr::kable(Ethnicity_levels, caption = "Giải thích các mức trong biến Ethnicity")
Giải thích các mức trong biến Ethnicity
Gia_tri Y_nghia
Amer-Indian-Eskimo Người da đỏ/Thổ dân Bắc Mỹ
Asian-Pac-Islander Người châu Á hoặc dân đảo Thái Bình Dương
Black Người da đen
Other Khác
White Người da trắng

2.3.6 Thống kê Tần suất

# Tạo bảng tần suất cho Ethnicity
ts_Ethnicity <- table(d$Ethnicity)

# Tạo bảng dữ liệu
ts_Ethnicity_df <- data.frame(
  Gia_tri = names(ts_Ethnicity),
  Tan_so = as.vector(ts_Ethnicity),
  Ty_le = round((as.vector(ts_Ethnicity) / sum(ts_Ethnicity)) * 100, 2)
)

# Hiển thị kết quả
ts_Ethnicity_df
##              Gia_tri Tan_so Ty_le
## 1 Amer-Indian-Eskimo    245  0.94
## 2 Asian-Pac-Islander    805  3.10
## 3              Black   2451  9.43
## 4              Other    221  0.85
## 5              White  22276 85.68
  • Biến Ethnicity (chủng tộc) có 5 nhóm như sau:

    • Người da đỏ/Thổ dân Bắc Mỹ (Amer-Indian-Eskimo): 245 người (chiếm 0.94%).
  • Người châu Á/Thái Bình Dương (Asian-Pac-Islander): 805 người (chiếm 3.1%).

  • Người da đen (Black): 2451 người (chiếm 9.43%).

  • Khác (Other): 221 người (chiếm 0.85%).

  • Người da trắng (White): 22276 người (chiếm 85.68%).

2.3.7 Trực quan hóa

ggplot(ts_Ethnicity_df, aes(x = reorder(Gia_tri, -Tan_so), y = Tan_so, fill = Gia_tri)) +
  geom_col(width = 0.5, color = "lightgreen") +
  geom_text(aes(label = Tan_so), vjust = -0.3, size = 4, fontface = "bold") +
  labs(
    title = "Biểu đồ cột: Chủng tộc (Ethnicity)",
    x = "Chủng tộc",
    y = "Tần số"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    
  )

ggplot(ts_Ethnicity_df, aes(x = reorder(Gia_tri, Ty_le), y = Ty_le, fill = Gia_tri)) +
  geom_col(width = 0.6, color = "white") +
  geom_text(aes(label = paste0(Ty_le, "%")), 
            hjust = -0.1, size = 4, fontface = "bold", color = "purple") +
  coord_flip() +
  scale_fill_brewer(palette = "Dark2") +
  labs(
    title = "Biểu đồ cột ngang: Tỷ lệ chủng tộc (Ethnicity)",
    x = "Chủng tộc",
    y = "Tỷ lệ (%)"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    
  )

2.3.8 Nhận xét

  • “White” là nhóm chiếm đa số áp đảo với 27.191 người (83.54%), thể hiện sự thống trị về số lượng trong mẫu khảo sát.

  • “Black” chiếm 2.830 người (8.69%), là nhóm thiểu số lớn nhất sau người da trắng.

  • Các nhóm “Asian-Pac-Islander”, “Amer-Indian-Eskimo”, và “Other” lần lượt có tỷ lệ thấp hơn nhiều, mỗi nhóm dưới 3%, cho thấy tính đa dạng chủng tộc có nhưng chưa thật sự cân bằng.

2.4 Biến Nationality

2.4.1 Giải thích biến

# Giải thích một số mức phổ biến trong biến Nationality
# (Nếu cần giải thích toàn bộ có thể mở rộng thêm)
country_levels <- data.frame(
  Gia_tri = c("United-States", "Mexico", "Philippines", "Vietnam", "Germany"),
  Y_nghia = c(
    "Hoa Kỳ",
    "Mexico",
    "Philippines",
    "Việt Nam",
    "Đức"
  )
)

knitr::kable(country_levels, caption = "Giải thích một số mức phổ biến trong biến Nationality")
Giải thích một số mức phổ biến trong biến Nationality
Gia_tri Y_nghia
United-States Hoa Kỳ
Mexico Mexico
Philippines Philippines
Vietnam Việt Nam
Germany Đức

2.4.2 Thống kê Tần suất

# Tạo bảng tần suất cho Nationality
ts_country <- table(d$Nationality)

# Tạo bảng dữ liệu
ts_country_df <- data.frame(
  Gia_tri = names(ts_country),
  Tan_so = as.vector(ts_country),
  Ty_le = round((as.vector(ts_country) / sum(ts_country)) * 100, 2)
)

# Hiển thị kết quả
ts_country_df
##                       Gia_tri Tan_so Ty_le
## 1                           ?    466  1.79
## 2                    Cambodia     16  0.06
## 3                      Canada    101  0.39
## 4                       China     61  0.23
## 5                    Columbia     48  0.18
## 6                        Cuba     75  0.29
## 7          Dominican-Republic     54  0.21
## 8                     Ecuador     19  0.07
## 9                 El-Salvador     77  0.30
## 10                    England     75  0.29
## 11                     France     22  0.08
## 12                    Germany    109  0.42
## 13                     Greece     24  0.09
## 14                  Guatemala     52  0.20
## 15                      Haiti     39  0.15
## 16         Holand-Netherlands      1  0.00
## 17                   Honduras      8  0.03
## 18                       Hong     12  0.05
## 19                    Hungary     11  0.04
## 20                      India     76  0.29
## 21                       Iran     36  0.14
## 22                    Ireland     19  0.07
## 23                      Italy     57  0.22
## 24                    Jamaica     61  0.23
## 25                      Japan     50  0.19
## 26                       Laos      8  0.03
## 27                     Mexico    499  1.92
## 28                  Nicaragua     25  0.10
## 29 Outlying-US(Guam-USVI-etc)      8  0.03
## 30                       Peru     23  0.09
## 31                Philippines    157  0.60
## 32                     Poland     53  0.20
## 33                   Portugal     28  0.11
## 34                Puerto-Rico     97  0.37
## 35                   Scotland     10  0.04
## 36                      South     65  0.25
## 37                     Taiwan     43  0.17
## 38                   Thailand     15  0.06
## 39            Trinadad&Tobago     12  0.05
## 40              United-States  23322 89.71
## 41                    Vietnam     53  0.20
## 42                 Yugoslavia     11  0.04
  • Biến Nationality (quốc gia xuất thân) có nhiều mức, dưới đây là một số mức phổ biến:

  • Hoa Kỳ (United-States): 23322 người (chiếm 89.71%).

  • Mexico: 499 người (chiếm 1.92%).

  • Philippines: 157 người (chiếm 0.6%).

  • Việt Nam: 53 người (chiếm 0.2%).

  • Đức (Germany): 109 người (chiếm 0.42%).

2.4.3 Trực quan hóa

library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.3
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
top_country <- ts_country_df %>% 
  arrange(desc(Tan_so)) %>% 
  slice(1:10)

ggplot(top_country, aes(x = reorder(Gia_tri, -Tan_so), y = Tan_so, fill = Gia_tri)) +
  geom_col(width = 0.5, color = "lightblue") +
  geom_text(aes(label = Tan_so), vjust = -0.3, size = 4, fontface = "bold") +
  labs(
    title = "Biểu đồ cột: 10 quốc gia phổ biến (Nationality)",
    x = "Quốc gia",
    y = "Tần số"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    
  )

library(dplyr)
library(ggplot2)

# Lấy top 10 quốc gia có tỷ lệ cao nhất
top_country <- ts_country_df %>% 
  arrange(desc(Ty_le)) %>% 
  slice(1:10)

# Vẽ biểu đồ
ggplot(top_country, aes(x = reorder(Gia_tri, Ty_le), y = Ty_le, fill = Gia_tri)) +
  geom_col(width = 0.6, color = "lightpink") +
  geom_text(aes(label = paste0(Ty_le, "%")), hjust = -0.1, size = 4, fontface = "bold") +
  coord_flip() +
  labs(
    title = "Biểu đồ cột ngang: Tỷ lệ 10 quốc gia phổ biến nhất (Nationality)",
    x = "Quốc gia",
    y = "Tỷ lệ (%)"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold")
  )

2.4.4 Nhận xét

  • “United-States” chiếm áp đảo với 89.59%, cho thấy phần lớn đối tượng khảo sát sống tại hoặc xuất thân từ Hoa Kỳ – phù hợp với việc dữ liệu này được thu thập từ hệ thống thống kê dân số Mỹ.

  • “Mexico” đứng thứ hai với 1.97%, là quốc gia gốc phổ biến tiếp theo, phản ánh sự hiện diện đáng kể của người nhập cư từ Mexico.

  • “Philippines” và “Germany” lần lượt chiếm 0.61% và 0.42%, là các quốc gia gốc ít phổ biến hơn.

  • Đặc biệt, có tới 1.79% giá trị là dấu hỏi “?” – nhiều khả năng là dữ liệu thiếu hoặc không xác định.

2.5 Biến Gender

2.5.1 Giải thích biến

# Giải thích các mức của biến Gender
Gender_levels <- data.frame(
  Gia_tri = c("Female", "Male"),
  Y_nghia = c("Nữ", "Nam")
)

knitr::kable(Gender_levels, caption = "Giải thích các mức trong biến Gender")
Giải thích các mức trong biến Gender
Gia_tri Y_nghia
Female Nữ
Male Nam

2.5.2 Thống kê Tần suất

# Tạo bảng tần suất cho Gender
ts_Gender <- table(d$Gender)

# Tạo bảng dữ liệu
ts_Gender_df <- data.frame(
  Gia_tri = names(ts_Gender),
  Y_nghia = c("Nam", "Nữ"),  # Male, Female
  Tan_so = as.vector(ts_Gender),
  Ty_le = round((as.vector(ts_Gender) / sum(ts_Gender)) * 100, 2)
)

# Hiển thị kết quả
ts_Gender_df
##   Gia_tri Y_nghia Tan_so Ty_le
## 1  Female     Nam   8515 32.75
## 2    Male      Nữ  17483 67.25
  • Biến Gender (giới tính) bao gồm 2 mức:

    • Nữ (Female): 8515 người (chiếm 32.75%).
  • Nam (Male): 17483 người (chiếm 67.25%).

2.5.3 Trực quan hóa

ggplot(ts_Gender_df, aes(x = Gia_tri, y = Tan_so, fill = Gia_tri)) +
  geom_col(width = 0.5, color = "white") +
  geom_text(aes(label = Tan_so), vjust = -0.3, size = 4, fontface = "bold") +
  labs(
    title = "Biểu đồ cột: Giới tính (Gender)",
    x = "Giới tính",
    y = "Tần số"
  ) +
  scale_fill_manual(values = c("red", "skyblue")) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
  
  )

Gender_colors <- c("Female" = "#FFB6C1", "Male" = "#87CEFA")  # màu tuỳ chỉnh

ggplot(ts_Gender_df, aes(x = "", y = Ty_le, fill = Gia_tri)) +
  geom_col(width = 1, color = "red") +
  coord_polar(theta = "y") +
  scale_fill_manual(values = Gender_colors) +
  labs(title = "Biểu đồ tròn: Giới tính") +
  geom_text(aes(label = paste0(Ty_le, "%")),
            position = position_stack(vjust = 0.5),
            size = 5, color = "blue") +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    legend.title = element_blank()
  )

2.6 Biến EarningClass

2.6.1 Giải thích biến

# Giải thích các mức của biến EarningClass
EarningClass_levels <- data.frame(
  Gia_tri = c("<=50K", ">50K"),
  Y_nghia = c("Thu nhập dưới hoặc bằng 50.000 USD/năm", "Thu nhập trên 50.000 USD/năm")
)

knitr::kable(EarningClass_levels, caption = "Giải thích các mức trong biến EarningClass")
Giải thích các mức trong biến EarningClass
Gia_tri Y_nghia
<=50K Thu nhập dưới hoặc bằng 50.000 USD/năm
>50K Thu nhập trên 50.000 USD/năm

2.6.2 Thống kê Tần suất

# Tạo bảng tần suất cho EarningClass
ts_EarningClass <- table(d$EarningClass)

# Tạo bảng dữ liệu
ts_EarningClass_df <- data.frame(
  Gia_tri = names(ts_EarningClass),
  Y_nghia = c("≤50K", ">50K"),
  Tan_so = as.vector(ts_EarningClass),
  Ty_le = round((as.vector(ts_EarningClass) / sum(ts_EarningClass)) * 100, 2)
)

# Hiển thị kết quả
ts_EarningClass_df
##   Gia_tri Y_nghia Tan_so Ty_le
## 1   <=50K    ≤50K  19415 74.68
## 2    >50K    >50K   6583 25.32
  • Biến EarningClass (thu nhập) có 2 mức:

    • Thu nhập dưới hoặc bằng 50K (<=50K): 19415 người (chiếm 74.68%).
  • Thu nhập trên 50K (>50K): 6583 người (chiếm 25.32%).

2.6.3 Trực quan hóa

ggplot(ts_EarningClass_df, aes(x = Gia_tri, y = Tan_so, fill = Gia_tri)) +
  geom_col(width = 0.5, color = "white") +
  geom_text(aes(label = Tan_so), vjust = -0.3, size = 4, fontface = "bold") +
  labs(
    title = "Biểu đồ cột: Thu nhập (EarningClass)",
    x = "Nhóm thu nhập",
    y = "Tần số"
  ) +
  scale_fill_manual(values = c("#6D597A", "#FFB703")) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    
  )

EarningClass_colors <- c("<=50K" = "#FDB863", ">50K" = "#5E3C99")

ggplot(ts_EarningClass_df, aes(x = "", y = Ty_le, fill = Gia_tri)) +
  geom_col(width = 1, color = "white") +
  coord_polar(theta = "y") +
  scale_fill_manual(values = EarningClass_colors) +
  labs(title = "Biểu đồ tròn: Thu nhập") +
  geom_text(aes(label = paste0(Ty_le, "%")),
            position = position_stack(vjust = 0.5),
            size = 5, color = "black") +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    legend.title = element_blank()
  )

3 Ước lượng Khoảng và Kiểm định Giả thuyết cho Tỷ lệ

3.1 Xác định Hạng mục Quan tâm

Ta chọn 3 hạng mục từ 3 biến trong danh sách các biến định tính, bao gồm:

  • Hạng mục “Never-married” của biến PartneringState – Tình trạng hôn nhân

  • Hạng mục “Male” của biến Gender – Giới tính

  • Hạng mục “Bachelors” của biến learningLevel – Trình độ học vấn

3.2 Ước lượng Khoảng Tin cậy và Kiểm định Giả thuyết

Ước lượng tỷ lệ (Proportion Estimation)

Ước lượng tỷ lệ là quá trình sử dụng dữ liệu từ một mẫu để suy luận về tỷ lệ tương ứng trong tổng thể. Trong thống kê mô tả, tỷ lệ mẫu (ký hiệu thường là p̂) được tính bằng số lượng các phần tử thỏa điều kiện chia cho tổng số phần tử trong mẫu. Đây được gọi là ước lượng điểm (point estimate) cho tỷ lệ tổng thể p. Tuy nhiên, do tính ngẫu nhiên của việc chọn mẫu, ước lượng điểm không thể đảm bảo phản ánh chính xác tỷ lệ thực sự trong tổng thể, do đó cần đi kèm với một khoảng tin cậy để đo lường độ bất định.

Khoảng tin cậy

Khoảng tin cậy là một khoảng giá trị cho ta biết giá trị thật của một tỷ lệ hay trung bình trong tổng thể có khả năng nằm trong khoảng đó. Nó được tính từ dữ liệu mẫu, và đi kèm với một mức độ tin tưởng – thường là 95%.

Mức ý nghĩa (Significance Level – α)

Mức ý nghĩa, ký hiệu là α (alpha), là xác suất chấp nhận sai lầm loại I – tức là xác suất bác bỏ giả thuyết không (H₀) khi nó thực sự đúng. Trong kiểm định giả thuyết thống kê, mức ý nghĩa thể hiện ngưỡng mà tại đó ta quyết định có bác bỏ H₀ hay không. Mức ý nghĩa phổ biến nhất là α = 0.05, nghĩa là ta chấp nhận 5% rủi ro cho việc kết luận sai. Kết quả kiểm định thường được đánh giá thông qua p-value, và so sánh với α để đưa ra quyết định:

Nếu p-value < α → bác bỏ H₀ (có bằng chứng thống kê).

Nếu p-value ≥ α → không bác bỏ H₀ (không đủ bằng chứng thống kê).

3.2.1 Hạng mục “Bachelors” của biến Trình độ học vấn (learningLevel)

Ta thực hiện khoảng ước lượng với độ tin cậy 95% cho tỷ lệ người có bằng cử nhân (Bachelors), ta thực hiện như sau:

# Số người có trình độ Bachelors
n_bachelors <- sum(d$learningLevel == "Bachelors")

# Tổng số quan sát
n_total <- nrow(d)

# Ước lượng khoảng tin cậy 95% cho tỷ lệ người có trình độ Bachelors
prop.test(n_bachelors, n_total, conf.level = 0.95)
## 
##  1-sample proportions test with continuity correction
## 
## data:  n_bachelors out of n_total, null probability 0.5
## X-squared = 11436, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.1638407 0.1729759
## sample estimates:
##         p 
## 0.1683591
  • n_bachelors <- sum(d$learningLevel == “Bachelors”): Tính tổng số người có trình độ học vấn là “Bachelors” (cử nhân) trong dữ liệu d, bằng cách đếm số dòng có giá trị “Bachelors” trong biến learningLevel.

  • n_total <- nrow(d): Lấy tổng số quan sát trong bộ dữ liệu d, tức là số hàng của bảng dữ liệu – dùng để làm mẫu số trong tính toán tỷ lệ.

  • prop.test(n_bachelors, n_total, conf.level = 0.95): Thực hiện phép ước lượng khoảng tin cậy cho tỷ lệ người có trình độ cử nhân, với độ tin cậy 95%. Hàm prop.test() trả về khoảng tin cậy và kiểm định giả thuyết tỷ lệ (nếu cần).

Phân tích kết quả

Phép kiểm định được thực hiện là kiểm định tỷ lệ một mẫu (1-sample proportion test) với chỉnh liên tục (continuity correction) – giúp cải thiện độ chính xác khi sử dụng phân phối xấp xỉ khi kích thước mẫu không hoàn toàn lớn.

Dữ liệu đầu vào gồm số người có trình độ học vấn là “Bachelors” (n_bachelors) trong tổng số quan sát (n_total). Giả thuyết không (H₀) đặt ra rằng tỷ lệ thực sự p = 0.5, tức là 50% dân số có bằng cử nhân.

Giá trị thống kê kiểm định là X-squared = 11436, với 1 bậc tự do (df = 1). Giá trị này rất lớn, cho thấy tỷ lệ mẫu quan sát được khác biệt đáng kể so với tỷ lệ giả định 50%.

Giá trị p-value < 2.2e-16, nghĩa là xác suất xảy ra chênh lệch lớn như vậy nếu H₀ đúng là gần như bằng 0. Do đó, kết quả kiểm định có ý nghĩa thống kê rất mạnh.

Giả thuyết đối H₁ là: tỷ lệ thực tế p ≠ 0.5, tức là đây là một kiểm định hai phía nhằm kiểm tra xem tỷ lệ có khác biệt rõ rệt so với 50% (có thể cao hơn hoặc thấp hơn).

Khoảng tin cậy 95% cho tỷ lệ người có trình độ học vấn Bachelors là từ [0.1638; 0.1730] – tức khoảng 16.38% đến 17.30%. Điều này cho thấy ta có thể tin tưởng rằng tỷ lệ thực sự trong tổng thể nằm trong khoảng này.

Tỷ lệ mẫu ước lượng được là khoảng 16.84%, tương đương với gần 17 người có bằng cử nhân trên mỗi 100 người, thấp hơn rất nhiều so với mức giả định 50%.

Bài toán kiểm định:

Giả thuyết kiểm định:

Giả thuyết không H₀: p = 0.5 (tỷ lệ người có bằng cử nhân bằng 50%)

Giả thuyết đối H₁: p ≠ 0.5 (tỷ lệ người có bằng cử nhân khác 50%)

Mức ý nghĩa: α = 0.05

Kết luận:

Với p-value < 2.2e-16 < 0.05, ta bác bỏ giả thuyết H₀. → Có bằng chứng thống kê cho thấy tỷ lệ người có bằng cử nhân khác 50%, với độ tin cậy 95%.

Tỷ lệ mẫu là 16.84%, với khoảng tin cậy nằm trong [16.38%; 17.30%]. → Mức chênh lệch hơn 33 điểm phần trăm so với giả định 50% cho thấy sự khác biệt là rõ ràng và có ý nghĩa thống kê.

3.2.2 Hạng mục “Never-married” của biến Tình trạng hôn nhân (PartneringState)

# Số người chưa từng kết hôn
n_never_married <- sum(d$PartneringState == "Never-married")

# Tổng số quan sát
n_total <- nrow(d)

# Ước lượng khoảng tin cậy 95% cho tỷ lệ người chưa từng kết hôn
prop.test(n_never_married, n_total, conf.level = 0.95)
## 
##  1-sample proportions test with continuity correction
## 
## data:  n_never_married out of n_total, null probability 0.5
## X-squared = 3256.3, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.3173478 0.3287543
## sample estimates:
##         p 
## 0.3230248

Phép kiểm định được sử dụng là kiểm định tỷ lệ một mẫu (1-sample proportions test) với chỉnh liên tục (continuity correction) – nhằm cải thiện độ chính xác khi sử dụng phân phối xấp xỉ trong thống kê.

Dữ liệu đầu vào: đang kiểm định tỷ lệ người có tình trạng “Never-married” (n_never_married) trong tổng số quan sát (n_total), với giả thuyết gốc H₀: p = 0.5 (tức 50% dân số chưa từng kết hôn).

Giá trị thống kê kiểm định là X-squared = 3256.3, với 1 bậc tự do (df = 1), cho thấy mức độ chênh lệch rất lớn giữa tỷ lệ quan sát được và tỷ lệ giả định.

Giá trị p-value < 2.2e-16, nghĩa là khả năng xảy ra sai lầm khi bác bỏ H₀ là cực kỳ nhỏ, gần như bằng 0. → Kết quả có ý nghĩa thống kê rất mạnh.

Giả thuyết đối (H₁): tỷ lệ thực tế khác 0.5 (kiểm định hai phía – kiểm tra xem có khác biệt rõ ràng hay không, dù là thấp hơn hay cao hơn).

Khoảng tin cậy 95% cho tỷ lệ người chưa kết hôn nằm trong khoảng [31.73%; 32.88%], phản ánh một mức tỷ lệ ổn định quanh mức ~32%.

Tỷ lệ mẫu ước lượng được là 32.30%, tức là khoảng 1/3 dân số trong mẫu khảo sát chưa từng kết hôn – con số này thấp hơn đáng kể so với giả định 50%.

📌 Bài toán kiểm định: Giả thuyết không H₀: p = 0.5 (tỷ lệ người chưa từng kết hôn bằng 50%)

Giả thuyết đối H₁: p ≠ 0.5 (tỷ lệ người chưa từng kết hôn khác 50%)

Mức ý nghĩa: α = 0.05

✅ Kết luận: Với p-value < 2.2e-16 < 0.05, ta bác bỏ giả thuyết H₀.

→ Có bằng chứng thống kê mạnh cho thấy tỷ lệ người chưa từng kết hôn khác 50%, với độ tin cậy 95%.

Tỷ lệ mẫu là 32.30%, nằm trong khoảng [31.73%; 32.88%]. → Mức chênh lệch gần 18 điểm phần trăm so với 50% cho thấy sự khác biệt là rõ ràng và có ý nghĩa thống kê.

3.2.3 Hạng mục “Male” của biến Giới tính (Gender)

# Số người là nam giới
n_male <- sum(d$Gender == "Male")

# Tổng số quan sát
n_total <- nrow(d)

# Ước lượng khoảng tin cậy 95% cho tỷ lệ nam giới
prop.test(n_male, n_total, conf.level = 0.95)
## 
##  1-sample proportions test with continuity correction
## 
## data:  n_male out of n_total, null probability 0.5
## X-squared = 3092.8, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.6667256 0.6781729
## sample estimates:
##         p 
## 0.6724748

Phân tích kết quả

Phân tích kết quả Phép kiểm định được sử dụng là kiểm định tỷ lệ một mẫu (1-sample proportions test) với chỉnh liên tục (continuity correction) nhằm đảm bảo kết quả chính xác hơn khi xử lý dữ liệu rời rạc.

Dữ liệu đầu vào: đang xét tỷ lệ người là “Male” trong tổng số quan sát, với giả thuyết gốc H₀: p = 0.5 (tức tỷ lệ nam giới là 50%).

Giá trị thống kê kiểm định là X-squared = 3092.8, với 1 bậc tự do (df = 1), cho thấy có sự chênh lệch lớn giữa tỷ lệ quan sát và tỷ lệ giả định.

p-value < 2.2e-16, cực kỳ nhỏ, cho thấy có bằng chứng thống kê rất mạnh để bác bỏ giả thuyết H₀.

Giả thuyết đối (H₁): tỷ lệ thực tế khác 0.5 – đây là kiểm định hai phía.

Khoảng tin cậy 95% cho tỷ lệ nam giới nằm trong khoảng [66.68%; 67.81%], cho thấy tỷ lệ này ổn định và cao hơn đáng kể so với mức giả định ban đầu.

Tỷ lệ mẫu ước lượng là 67.25%, tức là gần 2/3 người trong mẫu khảo sát là nam giới.

Bài toán kiểm định: Giả thuyết không H₀: p = 0.5 (tỷ lệ nam giới bằng 50%)

Giả thuyết đối H₁: p ≠ 0.5 (tỷ lệ nam giới khác 50%)

Mức ý nghĩa: α = 0.05

Kết luận: Với p-value < 2.2e-16 < 0.05, ta bác bỏ giả thuyết H₀.

→ Có bằng chứng thống kê rõ ràng cho thấy tỷ lệ nam giới khác 50%, với độ tin cậy 95%.

Tỷ lệ nam giới ước lượng là 67.25%, với khoảng tin cậy nằm trong [66.68%; 67.81%]. → Mức chênh lệch hơn 17 điểm phần trăm so với tỷ lệ giả định là đủ lớn để tạo ra ý nghĩa thống kê mạnh mẽ.

4 Phân tích Mối quan hệ giữa Hai biến Định tính (Bivariate Analysis)

Gender – EarningClass → Phân tích mối liên hệ giữa giới tính và mức thu nhập.

Câu hỏi đặt ra: Giới tính có ảnh hưởng đến khả năng thuộc nhóm thu nhập >50K không?

→ Tìm hiểu xem giới tính có liên quan đến thu nhập không.

Câu hỏi đặt ra: Tỷ lệ thu nhập >50K có chênh lệch rõ rệt giữa các nhóm giới tính không?

4.1 Gender - EarningClass

4.1.1 Bảng tần số chéo

# Bảng tần số chéo: giới tính và thu nhập
table_Gender_EarningClass <- table(d$Gender, d$EarningClass)
table_Gender_EarningClass
##         
##          <=50K  >50K
##   Female  7526   989
##   Male   11889  5594
# Tỷ lệ theo hàng (từng giới tính)
prop.table(table_Gender_EarningClass, margin = 1)
##         
##             <=50K     >50K
##   Female 0.883852 0.116148
##   Male   0.680032 0.319968

🔍 Trong số nam giới (Male): Có 11,889 người thu nhập ≤50K và 5,594 người thu nhập >50K → tỷ lệ >50K là khoảng 31.0%.

🔍 Trong số nữ giới (Female): Có 7,526 người thu nhập ≤50K và 989 người thu nhập >50K → tỷ lệ >50K là khoảng 11.6%.

📌 Kết luận: Nam giới có tỷ lệ thu nhập >50K cao gần gấp 3 lần nữ giới (31.0% so với 11.6%), cho thấy sự chênh lệch thu nhập rõ rệt giữa hai giới trong tập dữ liệu này.

4.1.2 Trực quan hóa

library(ggplot2)

# Tạo bảng dữ liệu từ bảng tần suất chéo
table_Gender_EarningClass <- table(d$Gender, d$EarningClass)
df_group <- as.data.frame(as.table(table_Gender_EarningClass))
colnames(df_group) <- c("Gender", "EarningClass", "Freq")  # Đổi tên cột

# Vẽ biểu đồ cột nhóm
ggplot(df_group, aes(x = EarningClass, y = Freq, fill = Gender)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.6) +
  geom_text(aes(label = Freq),
            position = position_dodge(width = 0.8),
            vjust = -0.4, size = 4, color = "white", fontface = "bold") +
  labs(title = "Biểu đồ cột nhóm: Gender vs EarningClass",
       x = "Mức thu nhập",
       y = "Tần số") +
  scale_fill_manual(
    values = c("Female" = "#FF9999", "Male" = "#6699CC"),
    name = "Giới tính",
    labels = c("Nữ", "Nam")
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    legend.position = "right"
  )

  • library(ggplot2): Nạp thư viện ggplot2 để sử dụng các chức năng vẽ biểu đồ.

  • table_Gender_EarningClass <- table(d\(Gender, d\)EarningClass): Tạo bảng tần suất chéo giữa hai biến định tính là giới tính (Gender) và thu nhập (EarningClass), cho biết số lượng từng tổ hợp.

  • df_group <- as.data.frame(as.table(table_Gender_EarningClass)): Chuyển bảng tần suất vừa tạo sang dạng bảng dữ liệu (data.frame) gồm ba cột.

  • colnames(df_group) <- c(“Gender”, “EarningClass”, “Freq”): Đặt tên cho ba cột là: giới tính (Gender), mức thu nhập (EarningClass) và tần số (Freq).

  • ggplot(df_group, aes(x = EarningClass, y = Freq, fill = Gender)): Khởi tạo biểu đồ cột, trục hoành là thu nhập, trục tung là tần số, các cột được tô màu theo giới tính.

  • geom_bar(stat = “identity”, position = position_dodge(width = 0.8), width = 0.6): Vẽ biểu đồ cột nhóm, đặt các cột nam và nữ cạnh nhau để dễ so sánh.

  • geom_text(…): Thêm nhãn số lượng lên mỗi cột để hiển thị giá trị Freq, đặt ở trên đầu cột.

  • labs(…): Thêm tiêu đề biểu đồ và nhãn cho các trục.

  • scale_fill_manual(…): Tùy chỉnh màu sắc của từng giới tính và thiết lập chú thích (legend).

  • theme_minimal(…) + theme(…): Áp dụng phong cách tối giản cho biểu đồ, căn giữa tiêu đề và đặt chú giải bên phải.

# Tạo bảng dữ liệu từ bảng tần suất chéo
table_Gender_EarningClass <- table(d$Gender, d$EarningClass)
df_stack <- as.data.frame(as.table(table_Gender_EarningClass))
colnames(df_stack) <- c("Gender", "EarningClass", "Freq")  # Đổi tên cột

# Vẽ biểu đồ cột chồng
ggplot(df_stack, aes(x = EarningClass, y = Freq, fill = Gender)) +
  geom_bar(stat = "identity", width = 0.6) +
  geom_text(aes(label = Freq),
            position = position_stack(vjust = 0.5),
            color = "green", size = 4, fontface = "bold") +
  scale_fill_manual(
    values = c("Female" = "red", "Male" = "lightblue"),
    name = "Giới tính",
    labels = c("Nữ", "Nam")
  ) +
  labs(title = "Biểu đồ cột chồng: Gender vs EarningClass",
       x = "Mức thu nhập",
       y = "Tần số") +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    legend.position = "right"
  )

  • geom_bar(stat = “identity”, width = 0.6): Vẽ biểu đồ cột chồng (stacked bar chart), trong đó mỗi nhóm thu nhập hiển thị một cột có phần chồng theo giới tính.

  • geom_text(position = position_stack(vjust = 0.5), …): Hiển thị nhãn số lượng (tần số) bên trong từng phần chồng của cột, tức là ở giữa mỗi khối màu.

Kết luận trực quan: Hai biểu đồ cho thấy sự chênh lệch thu nhập rõ rệt giữa hai giới:

Nam giới có xu hướng đạt thu nhập cao (>50K) nhiều hơn nữ giới.

Nữ giới chủ yếu tập trung ở nhóm thu nhập thấp, và gần như vắng mặt ở nhóm thu nhập cao.

Giới tính là yếu tố ảnh hưởng đáng kể đến phân phối thu nhập trong tập dữ liệu này. Biểu đồ trực quan phản ánh sự bất bình đẳng rõ nét về thu nhập giữa nam và nữ.

4.1.3 Kiểm định thống kê (Kiểm định Chi-bình phương)

Giả thuyết kiểm định:

H₀ (Giả thuyết không): Giới tính và mức thu nhập độc lập nhau.

H₁ (Giả thuyết đối):Giới tính và mức thu nhập có liên hệ..

# Thực hiện kiểm định Chi-bình phương
chisq.test(table_Gender_EarningClass)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table_Gender_EarningClass
## X-squared = 1256.9, df = 1, p-value < 2.2e-16

Kết quả kiểm định Chi-bình phương: Kết quả kiểm định Chi-bình phương:

Chi-squared = 1256.9 Bậc tự do (df) = 1 Giá trị p-value = < 2.2e-16

Kết luận thống kê: Với p-value gần như bằng 0, nhỏ hơn rất nhiều so với ngưỡng ý nghĩa 0.05, ta bác bỏ giả thuyết H₀. ⇒ Có bằng chứng thống kê mạnh mẽ cho thấy giới tính và mức thu nhập có liên hệ với nhau.

Thảo luận thêm về bản chất mối quan hệ:

Kết quả kiểm định cho thấy mối quan hệ giữa giới tính và thu nhập không phải ngẫu nhiên. Nói cách khác, giới tính có thể đóng vai trò như một yếu tố dự báo mức thu nhập, khi mà sự phân bố giữa nam và nữ ở hai nhóm thu nhập có sự khác biệt rõ rệt.

Quan sát biểu đồ cho thấy:

Tỷ lệ nam giới tăng mạnh ở nhóm thu nhập >50K, cho thấy họ có cơ hội cao hơn để đạt thu nhập cao. Trong khi đó, nữ giới tập trung nhiều ở nhóm thu nhập thấp, với số lượng giảm mạnh khi chuyển sang nhóm thu nhập cao.

Gợi ý bản chất sâu xa của mối liên hệ:

Sự khác biệt này có thể phản ánh các yếu tố xã hội như định kiến giới trong việc lựa chọn ngành nghề, khả năng tiếp cận các vị trí lương cao, hoặc thời gian tích lũy kinh nghiệm. Ngoài ra, còn có thể liên quan đến mức độ tham gia thị trường lao động hoặc sự phân chia vai trò trong gia đình.

→ Tóm lại: Không chỉ có sự liên hệ về mặt thống kê, mà kết quả còn phản ánh một bất bình đẳng mang tính hệ thống, trong đó nam giới có xu hướng được đại diện nhiều hơn trong nhóm thu nhập cao so với nữ giới.

4.1.4 Hiệu tỷ lệ

# Lập bảng tần số chéo giữa Gender và EarningClass
table_Gender_EarningClass <- table(d$Gender, d$EarningClass)

# Thêm tổng hàng và tổng cột
table_Gender_EarningClass_margins <- addmargins(table_Gender_EarningClass)

# Hiển thị bảng
table_Gender_EarningClass_margins
##         
##          <=50K  >50K   Sum
##   Female  7526   989  8515
##   Male   11889  5594 17483
##   Sum    19415  6583 25998

Tỷ lệ thu nhập cao theo giới tính được ký hiệu như sau:

  • \(p_1 = P(\text{EarningClass} = \text{">50K"} \mid \text{Gender} = \text{"Female"})\): Tỷ lệ nữ giới có thu nhập cao.
  • \(p_2 = P(\text{EarningClass} = \text{">50K"} \mid \text{Gender} = \text{"Male"})\): Tỷ lệ nam giới có thu nhập cao.

Giả thuyết kiểm định:

  • \(H_0: p_1 - p_2 = 0\): Không có sự khác biệt về tỷ lệ thu nhập cao giữa nam và nữ.
  • \(H_1: p_1 - p_2 < 0\): Tỷ lệ thu nhập cao ở nữ thấp hơn nam.
# Tạo bảng tần số chéo giữa Gender và EarningClass
table_Gender_EarningClass <- table(d$Gender, d$EarningClass)

# Số người có thu nhập >50K trong từng giới
counts_EarningClass_high <- c(table_Gender_EarningClass["Female", ">50K"], table_Gender_EarningClass["Male", ">50K"])

# Tổng số người theo từng giới
totals_EarningClass <- c(sum(table_Gender_EarningClass["Female", ]), sum(table_Gender_EarningClass["Male", ]))

# Kiểm định tỉ lệ một phía: p1 < p2
test_EarningClass_less <- prop.test(counts_EarningClass_high, totals_EarningClass, alternative = "less", correct = FALSE)

# Hiển thị kết quả
test_EarningClass_less
## 
##  2-sample test for equality of proportions without continuity correction
## 
## data:  counts_EarningClass_high out of totals_EarningClass
## X-squared = 1258, df = 1, p-value < 2.2e-16
## alternative hypothesis: less
## 95 percent confidence interval:
##  -1.0000000 -0.1956781
## sample estimates:
##   prop 1   prop 2 
## 0.116148 0.319968

Mục tiêu kiểm định: So sánh tỷ lệ người có thu nhập cao (biến EarningClass có giá trị “>50K”) giữa hai giới tính (Gender là “Female” và “Male”).

Định nghĩa:

p1 = P(EarningClass == “>50K” | Gender == “Female”): tỷ lệ nữ giới có thu nhập cao.

p2 = P(EarningClass == “>50K” | Gender == “Male”): tỷ lệ nam giới có thu nhập cao.

GĐịnh nghĩa:

p₁ = P(EarningClass == “>50K” | Gender == “Female”) → Tỷ lệ nữ giới có thu nhập cao

p₂ = P(EarningClass == “>50K” | Gender == “Male”) → Tỷ lệ nam giới có thu nhập cao

Giả thuyết kiểm định:

H₀: p₁ − p₂ = 0 → Không có sự khác biệt về tỷ lệ thu nhập cao giữa nam và nữ

H₁: p₁ − p₂ < 0 → Tỷ lệ thu nhập cao ở nữ thấp hơn ở nam

Tính toán dựa trên bảng dữ liệu:

Số nữ thu nhập >50K: 989 / Tổng số nữ: 8,515 → p₁ ≈ 11.61%

Số nam thu nhập >50K: 5,594 / Tổng số nam: 17,483 → p₂ ≈ 31.99%`

X-squared = 1518.9, df = 1, p-value < 2.2e-16.

Khoảng tin cậy 95% cho p1 - p2: từ -1.0000000 đến -0.1891457.

Kết luận: Có bằng chứng thống kê mạnh để bác bỏ giả thuyết H0. Tỷ lệ nữ có thu nhập cao thấp hơn nam một cách có ý nghĩa thống kê.

4.1.5 Tỷ số nguy cơ

Liệu giới tính (nam/nữ) có ảnh hưởng đến thu nhập cao không (>50K)?

→ Mục tiêu: So sánh tỉ lệ có thu nhập cao ở nam giới so với nữ giới.

install.packages("epitools", repos = "https://cloud.r-project.org")
## Installing package into 'C:/Users/Tuyet Nhi/AppData/Local/R/win-library/4.3'
## (as 'lib' is unspecified)
## package 'epitools' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\Tuyet Nhi\AppData\Local\Temp\RtmpGEP2hj\downloaded_packages
library(epitools)

Tính Relative Risk

riskratio(table_Gender_EarningClass)
## $data
##         
##          <=50K >50K Total
##   Female  7526  989  8515
##   Male   11889 5594 17483
##   Total  19415 6583 25998
## 
## $measure
##         risk ratio with 95% C.I.
##          estimate    lower    upper
##   Female  1.00000       NA       NA
##   Male    2.75483 2.588052 2.932356
## 
## $p.value
##         two-sided
##          midp.exact  fisher.exact    chi.square
##   Female         NA            NA            NA
##   Male            0 3.875868e-303 1.532559e-275
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Nhận xét kết quả

$data: bảng dữ liệu chéo 2x2 Nữ: 8.515 người, trong đó 989 người (11.62%) có thu nhập >50K

Nam: 17.483 người, trong đó 5.594 người (32.00%) có thu nhập >50K

$measure: Tỷ số nguy cơ (Relative Risk – RR) RR = 2.75 → nam giới có nguy cơ đạt thu nhập >50K cao hơn 2.75 lần so với nữ giới

Khoảng tin cậy 95%: [2.59; 2.93] → không chứa 1 → kết quả có ý nghĩa thống kê

$p.value: P-value ≈ 0 → có đủ bằng chứng bác bỏ H₀ → Giới tính có ảnh hưởng rõ rệt đến khả năng đạt thu nhập cao

$p.value

# Cài gói nếu cần
install.packages("knitr")  # chỉ cần 1 lần nếu chưa cài
## Warning: package 'knitr' is in use and will not be installed
# Nạp thư viện
library(knitr)

# Tạo bảng dữ liệu
explanation <- data.frame(
  Cột = c("two-sided", "midp.exact", "fisher.exact", "chi.square"),
  Ý_nghĩa = c(
    "Kiểm định hai phía – kiểm tra xem RR có khác 1. Đây là loại kiểm định phổ biến nhất.",
    "Kiểm định chính xác – cho p-value chính xác dựa trên phân phối chính xác.",
    "Fisher’s exact test – dùng trong bảng 2x2 với cỡ mẫu nhỏ.",
    "Chi-squared test – kiểm định xấp xỉ phân phối chuẩn, dùng khi mẫu đủ lớn."
  )
)

# In bảng
kable(explanation, align = "l")
Cột Ý_nghĩa
two-sided Kiểm định hai phía – kiểm tra xem RR có khác 1. Đây là loại kiểm định phổ biến nhất.
midp.exact Kiểm định chính xác – cho p-value chính xác dựa trên phân phối chính xác.
fisher.exact Fisher’s exact test – dùng trong bảng 2x2 với cỡ mẫu nhỏ.
chi.square Chi-squared test – kiểm định xấp xỉ phân phối chuẩn, dùng khi mẫu đủ lớn.

Kết quả

Tỷ số nguy cơ (RR) = 2.75 → Nam giới có nguy cơ đạt thu nhập trên 50K cao gấp 2.75 lần so với nữ giới.

Khoảng tin cậy 95% = [2.59, 2.93] → Không bao gồm 1 → → sự khác biệt có ý nghĩa thống kê.

P-value ≈ 0 ở tất cả các phương pháp kiểm định (midp.exact, Fisher, chi-square) → Rất nhỏ hơn 0.05 → có bằng chứng thống kê mạnh về sự khác biệt giữa nam và nữ.

Kết luận Dựa trên kết quả phân tích, nam giới có xác suất đạt mức thu nhập cao (>50K) cao hơn đáng kể so với nữ giới trong bộ dữ liệu này. Tỷ số nguy cơ là 2.75 với khoảng tin cậy hẹp và giá trị p gần bằng 0 cho thấy sự khác biệt là rõ ràng và có ý nghĩa thống kê. Điều này cho thấy giới tính là một yếu tố có ảnh hưởng đáng kể đến khả năng đạt được mức thu nhập cao, ít nhất là trong phạm vi mẫu khảo sát được sử dụng.

4.1.6 Tỷ số Chênh (Odds Ratio - OR)

or_result2 <- oddsratio(table_Gender_EarningClass)
print(or_result2)
## $data
##         
##          <=50K >50K Total
##   Female  7526  989  8515
##   Male   11889 5594 17483
##   Total  19415 6583 25998
## 
## $measure
##         odds ratio with 95% C.I.
##          estimate    lower    upper
##   Female  1.00000       NA       NA
##   Male    3.57994 3.327669 3.854999
## 
## $p.value
##         two-sided
##          midp.exact  fisher.exact    chi.square
##   Female         NA            NA            NA
##   Male            0 3.875868e-303 1.532559e-275
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Kết quả phân tích Odds Ratio (tỷ số chênh) trong ảnh cho thấy mối liên hệ giữa giới tính (nam/nữ) và khả năng đạt mức thu nhập cao hơn 50K trong bộ dữ liệu. Dựa vào bảng tần số chéo, ta thấy trong tổng số 25.998 người được khảo sát, có 8.515 là nữ và 17.483 là nam. Trong đó, chỉ có 989 nữ giới có thu nhập trên 50K (chiếm khoảng 11.6%), trong khi 5.594 nam giới đạt được mức thu nhập này (chiếm khoảng 32%).

Dựa trên các con số này, phân tích Odds Ratio được thực hiện nhằm đo lường mức độ chênh lệch về khả năng có thu nhập cao giữa hai nhóm giới tính. Tỷ số chênh OR cho nam giới là 3.57994, với khoảng tin cậy 95% nằm trong khoảng [3.327669; 3.854999]. Điều này có nghĩa là nam giới có khả năng đạt mức thu nhập trên 50K cao gấp khoảng 3.58 lần so với nữ giới, sau khi so sánh tỷ lệ odds (xác suất xảy ra so với không xảy ra) trong từng nhóm. Trong khi đó, OR của nữ giới được cố định là 1 để làm mốc tham chiếu, do đây là nhóm cơ sở.

Khoảng tin cậy 95% cho OR của nam không bao gồm giá trị 1, cho thấy sự khác biệt giữa hai giới là có ý nghĩa thống kê. Bằng chứng cho điều này càng rõ ràng khi ta xét đến các giá trị p-value rất nhỏ: phương pháp midp.exact cho ra giá trị 3.875868e-303 và kiểm định chi bình phương (chi-square) cũng cho kết quả p-value 1.532559e-275 – đều nhỏ hơn rất nhiều so với mức ý nghĩa phổ biến là 0.05. Điều đó cho phép ta bác bỏ giả thuyết H₀ (rằng không có sự khác biệt về khả năng có thu nhập cao giữa nam và nữ) và chấp nhận giả thuyết H₁: giới tính thực sự có ảnh hưởng đến mức thu nhập cao trong mẫu khảo sát.

Một điểm quan trọng khác là kết quả này không áp dụng phương pháp hiệu chỉnh (correction = FALSE), đồng nghĩa với việc chưa điều chỉnh cho các yếu tố gây nhiễu hoặc sai số thiết kế. Tuy nhiên, với một p-value rất nhỏ như vậy và khoảng tin cậy khá hẹp, có thể nói rằng sự khác biệt này là mạnh mẽ và đáng tin cậy.

Từ kết quả trên, ta có thể rút ra nhận định rằng nam giới có nhiều khả năng đạt được mức thu nhập cao hơn nữ giới, xét trên dữ liệu hiện tại. Tuy nhiên, đây mới chỉ là phân tích đơn biến giữa giới tính và thu nhập. Trong bối cảnh nghiên cứu thực tế, để đi đến kết luận chính xác và khách quan hơn, ta nên thực hiện thêm các phân tích kiểm soát các biến nhiễu khác như trình độ học vấn, ngành nghề, giờ làm việc, và khu vực địa lý. Khi giảng dạy, giảng viên có thể dùng ví dụ này để giới thiệu cho sinh viên khái niệm odds, odds ratio, khoảng tin cậy và kiểm định giả thuyết, đồng thời nhấn mạnh tầm quan trọng của việc giải thích kết quả thống kê trong ngữ cảnh xã hội học và chính sách. Tóm tắt nhận xét Dữ liệu tóm tắt:

Nữ: 7526 người có thu nhập ≤50K, 989 người >50K.

Nam: 11.889 người ≤50K, 5.594 người >50K.

Tỷ số chênh (Odds Ratio – OR):

OR của nam so với nữ = 3.58, nghĩa là:

Nam giới có khả năng đạt thu nhập >50K cao gấp 3.58 lần so với nữ giới.

Khoảng tin cậy 95% (CI):

OR nằm trong khoảng [3.33; 3.85] → chắc chắn có sự chênh lệch thực sự giữa hai giới.

P-value rất nhỏ (≈ 0):

Có bằng chứng mạnh để bác bỏ giả thuyết H₀, khẳng định giới tính có ảnh hưởng đến thu nhập cao.

Giả sử ta có bảng dữ liệu như sau:

50K (Thu nhập cao) ≤50K (Thu nhập thấp) Nữ (Female) a = 989 b = 7526 Nam (Male) c = 5594 d = 11889

LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSBUdeG6p24gNCINCmF1dGhvcjogIlbDtSBIb8OgbmcgVMOtbmgiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclSDolTTolUywgJWQgLSAlbSAtICVZJylgIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDogDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdGhlbWU6ICJkZWZhdWx0Ig0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMg0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICB3b3JkX2RvY3VtZW50OiANCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDINCiAgcGRmX2RvY3VtZW50OiANCiAgICBsYXRleF9lbmdpbmU6IHhlbGF0ZXgNCi0tLQ0KDQpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9DQpjYXQoJzxzdHlsZT5wIHsgdGV4dC1hbGlnbjoganVzdGlmeTsgfTwvc3R5bGU+JykNCmBgYA0KDQojIMSQ4buNYyAgZOG7ryBsaeG7h3UNCg0KKipob2FuZ3RpbmhkdWxpZXUqKiBsw6AgYuG7mSBk4buvIGxp4buHdSBjaOG7qWEgdGjDtG5nIHRpbiB04buVbmcgaOG7o3AgduG7gSBuaMOibiBraOG6qXUgaOG7jWMgdsOgIMSR4bq3YyDEkWnhu4NtIGtpbmggdOG6vyB4w6MgaOG7mWkgY+G7p2Ega2hv4bqjbmcgMjUuMDAwIG5nxrDhu51pIMSRYW5nIHNpbmggc+G7kW5nIHbDoCBsw6BtIHZp4buHYyB04bqhaSBN4bu5LiBE4buvIGxp4buHdSDEkcaw4bujYyB4w6J5IGThu7FuZyBk4buxYSB0csOqbiBuZ3Xhu5NuIGfhu5FjIHThu6sgQ3VycmVudCBQb3B1bGF0aW9uIFN1cnZleSAoQ1BTKSDigJMgbeG7mXQgY2jGsMahbmcgdHLDrG5oIGto4bqjbyBzw6F0IGTDom4gc+G7kSB1eSB0w61uIMSRxrDhu6NjIHRo4buxYyBoaeG7h24gaMOgbmcgbsSDbSBi4bufaSBD4bulYyDEkWnhu4F1IHRyYSBkw6JuIHPhu5EgSG9hIEvhu7MgKFUuUy4gQ2Vuc3VzIEJ1cmVhdSkgcGjhu5FpIGjhu6NwIHbhu5tpIEJ1cmVhdSBvZiBMYWJvciBTdGF0aXN0aWNzLg0KDQpC4buZIGThu68gbGnhu4d1IMSRw6MgxJHGsOG7o2MgdHLDrWNoIGzhu41jLCB44butIGzDvSB2w6AgdMOhaSBj4bqldSB0csO6YyBuaOG6sW0gcGjhu6VjIHbhu6UgY2hvIG3hu6VjIHRpw6p1IHBow6JuIHTDrWNoIHbDoCBodeG6pW4gbHV54buHbiBtw7QgaMOsbmggaOG7jWMgbcOheSB0cm9uZyBjw6FjIG5naGnDqm4gY+G7qXUgbGnDqm4gcXVhbiDEkeG6v24ga2luaCB04bq/IGjhu41jLCBow6BuaCB2aSBsYW8gxJHhu5luZyB2w6AgYuG6pXQgYsOsbmggxJHhurNuZyB0aHUgbmjhuq1wLg0KDQoNCg0KIyMgIMSQ4buNYyBmaWxlDQpgYGB7cn0NCmQgPC1yZWFkLmNzdihmaWxlLmNob29zZSgpLCBoZWFkZXI9VCkNCmBgYA0KDQpEw7JuZyBs4buHbmggYGQgPC0gcmVhZC5jc3YoZmlsZS5jaG9vc2UoKSwgaGVhZGVyID0gVFJVRSlgIGTDuW5nIMSR4buDIMSR4buNYyBk4buvIGxp4buHdSB04burIG3hu5l0IGZpbGUgQ1NWIGNo4buNbiB0csOqbiBtw6F5IHTDrW5oLg0KDQoqIGBmaWxlLmNob29zZSgpYCBt4bufIGjhu5lwIHRob+G6oWkgY2jhu41uIGZpbGUuDQoqIGByZWFkLmNzdiguLi4pYCDEkeG7jWMgZmlsZSBDU1YgdsOgIHRy4bqjIHbhu4EgZOG6oW5nIGLhuqNuZyBk4buvIGxp4buHdSAoZGF0YSBmcmFtZSkuDQoqIGBoZWFkZXIgPSBUUlVFYCBuZ2jEqWEgbMOgIGTDsm5nIMSR4bqndSB0acOqbiBj4bunYSBmaWxlIGzDoCB0w6puIGPDoWMgY+G7mXQuDQoqIEvhur90IHF14bqjIMSRxrDhu6NjIGzGsHUgdsOgbyBiaeG6v24gYGRgIMSR4buDIHPhu60gZOG7pW5nIGNobyBjw6FjIHBow6JuIHTDrWNoIHRp4bq/cCB0aGVvLg0KDQojIyAgSGnhu4NuIHRo4buLIGPhuqV1IHRyw7pjIGPhu6dhIGThu68gbGnhu4d1DQoNCmBgYHtyfQ0Kc3RyKGQpDQpgYGANCg0KLSBgc3RyKC4uLilgIGzDoCB2aeG6v3QgdOG6r3QgY+G7p2Egc3RydWN0dXJlIOKAkyBkw7luZyDEkeG7gyBraeG7g20gdHJhIG5oYW5oIHRow7RuZyB0aW4gduG7gSBz4buRIGTDsm5nLCBz4buRIGPhu5l0LCB0w6puIGJp4bq/biB2w6Aga2nhu4N1IGThu68gbGnhu4d1IGPhu6dhIHThu6tuZyBiaeG6v24uDQoNCi0gS2hpIGTDuW5nIGBzdHIoZClgLCBi4bqhbiBz4bq9IGJp4bq/dCDEkcaw4bujYzoNCg0KKyBkIGPDsyBiYW8gbmhpw6p1IHF1YW4gc8OhdCAocm93cykgdsOgIGJp4bq/biAoY29sdW1ucykNCg0KKyBUw6puIGPhu6dhIGPDoWMgYmnhur9uDQoNCisgS2nhu4N1IGThu68gbGnhu4d1IGPhu6dhIHThu6tuZyBiaeG6v24gKHZkOiBpbnQsIGNociwgZmFjdG9yLCBudW0uLi4pDQoNCj0+IEThu68gbGnhu4d1IGJhbyBn4buTbTogMjU5OTggcXVhbiBzw6F0IHbDoCAxMiBiaeG6v24sIHRyb25nIMSRw7MgY8OzIDcgYmnhur9uIMSR4buLbmggdMOtbmgNCg0KYGBge3J9DQp2YXJpYWJsZV9leHBsYWluIDwtIGRhdGEuZnJhbWUoDQogIFRlbl9CaWVuID0gYygiYWdlIiwgIkNlbnN1c1dlaWdodCIsICJsZWFybmluZ0xldmVsIiwgImxlYXJuaW5nTGV2ZWwubnVtIiwgIlBhcnRuZXJpbmdTdGF0ZSIsIA0KICAgICAgICAgICAgICAgIkZhbWlseVJvbGUiLCAiRXRobmljaXR5IiwgIkdlbmRlciIsICJOZWdhdGl2ZUNhcGl0YWxGbG93IiwgIldlZWtseUhvdXJzIiwgDQogICAgICAgICAgICAgICAiTmF0aW9uYWxpdHkiLCAiRWFybmluZ0NsYXNzIiksDQogIFlfTmdoaWEgPSBjKA0KIsSQ4buZIHR14buVaSBj4bunYSBuZ8aw4budaSDEkcaw4bujYyBraOG6o28gc8OhdCIsDQoixJDhuqFpIGRp4buHbiBj4bunYSBjw6EgbmjDom4gdHJvbmcgbeG6q3UgxJFp4buBdSB0cmEgZMOibiBz4buRIiwNCiJUcsOsbmggxJHhu5kgaOG7jWMgduG6pW4gY2jDrW5oIHRo4bupYyAodsOtIGThu6U6IFThu5F0IG5naGnhu4dwIGPhuqVwIDMsIMSQ4bqhaSBo4buNYyBjaMawYSBob8OgbiB0aMOgbmgpIiwNCiJT4buRIG7Eg20gaOG7jWMgdOG6rXAgY2jDrW5oIHF1eSB0xrDGoW5nIMSRxrDGoW5nIHbhu5tpIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiIsDQoiVMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIGhp4buHbiB04bqhaSAoxJDDoyBr4bq/dCBow7RuLCBMeSB0aMOibiwgR8OzYSB24bujL2No4buTbmcuLi4pIiwNCiJWYWkgdHLDsiB0cm9uZyBo4buZIGdpYSDEkcOsbmggKHbDrSBk4bulOiBDb24gY8OhaSwgS2jDtG5nIHRodeG7mWMgaOG7mSBnaWEgxJHDrG5oKSIsDQoiQ2jhu6duZyB04buZYyBob+G6t2MgbmjDs20gZMOibiB04buZYyAoTmfGsOG7nWkgZGEgdHLhuq9uZywgQ2jDonUgw4EsIHYudi4pIiwNCiJHaeG7m2kgdMOtbmggY+G7p2EgY8OhIG5ow6JuIChOYW0gaG/hurdjIE7hu68pIiwNCiJN4bupYyBs4buXIHTDoGkgc+G6o24gcGjDoXQgc2luaCB04burIGhv4bqhdCDEkeG7mW5nIMSR4bqndSB0xrAgduG7kW4iLA0KIlPhu5EgZ2nhu50gbMOgbSB2aeG7h2MgdHJ1bmcgYsOsbmggdHJvbmcgbeG7mXQgdHXhuqduIiwNCiJRdeG7kWMgZ2lhIG7GoWkgY8OhIG5ow6JuIHNpbmggc+G7kW5nIGhv4bq3YyBraGFpIGLDoW8gbMOgIG7GoWkgc2luaCIsDQoiVGh1IG5o4bqtcCBjw6EgbmjDom4gbeG7l2kgbsSDbSINCiAgKQ0KKQ0KDQpsaWJyYXJ5KGtuaXRyKQ0Ka2FibGUodmFyaWFibGVfZXhwbGFpbiwgY2FwdGlvbiA9ICJHaeG6o2kgdGjDrWNoIGPDoWMgYmnhur9uIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UiKQ0KDQoNCmBgYA0KDQotIGB2YXJpYWJsZV9leHBsYWluIDwtIGRhdGEuZnJhbWUoLi4uKWAgOiBU4bqhbyBt4buZdCBi4bqjbmcgZOG7ryBsaeG7h3UgKGRhdGEgZnJhbWUpIGfhu5NtIDIgY+G7mXQNCg0KKyBUZW5fQmllbjogVMOqbiBiaeG6v24gdHJvbmcgYuG7mSBk4buvIGxp4buHdS4NCg0KKyBZX05naGlhOiDDnSBuZ2jEqWEgbcO0IHThuqMgY+G7p2EgdOG7q25nIGJp4bq/biDEkcOzLg0KDQotIGBrYWJsZSh2YXJpYWJsZV9leHBsYWluLCBjYXB0aW9uID0gIkdp4bqjaSB0aMOtY2ggY8OhYyBiaeG6v24iKWA6IEjDoG0ga2FibGUoKSBkw7luZyDEkeG7gyBoaeG7g24gdGjhu4sgYuG6o25nIG3DtCB04bqjIHRyw6puIGTGsOG7m2kgZOG6oW5nIHRyw6xuaCBiw6B5IHLDtSByw6BuZywgZOG7hSDEkeG7jWMuIA0KDQotIGBjYXB0aW9uID0gIkdp4bqjaSB0aMOtY2ggY8OhYyBiaeG6v24iYCDEkeG6t3QgdGnDqnUgxJHhu4EgY2hvIGLhuqNuZyBsw6AgIkdp4bqjaSB0aMOtY2ggY8OhYyBiaeG6v24iLg0KDQojIyAgSGnhu4NuIHRo4buLIG3hu5l0IHbDoGkgZMOybmcgxJHhuqd1IHbDoCBjdeG7kWkgY+G7p2EgZOG7ryBsaeG7h3UNCg0KLSBgaGVhZChkKWA6IEhp4buDbiB0aOG7iyA2IGTDsm5nIMSR4bqndSBj4bunYSBi4buZIGThu68gbGnhu4d1DQoNCmBgYHtyfQ0KIyBIaeG7g24gdGjhu4sgNiBkw7JuZyDEkeG6p3UgY+G7p2EgYuG7mSBk4buvIGxp4buHdQ0KaGVhZChkKQ0KYGBgDQoNCi0gYHRhaWwoZClgOiBIaeG7g24gdGjhu4sgNiBkw7JuZyBjdeG7kWkgY+G7p2EgYuG7mSBk4buvIGxp4buHdQ0KDQpgYGB7cn0NCiMgSGnhu4NuIHRo4buLIDYgZMOybmcgY3Xhu5FpIGPhu6dhIGLhu5kgZOG7ryBsaeG7h3UNCnRhaWwoZCkNCmBgYA0KDQojIyAgS2nhu4NtIHRyYSBnacOhIHRy4buLIHRoaeG6v3UNCg0KYGBge3J9DQpzdW0oaXMubmEoZCkpDQoNCmBgYA0KLSBgc3VtKGlzLm5hKGQpKWA6IEtp4buDbSB0cmEgdOG7lW5nIHPhu5EgZ2nDoSB0cuG7iyBOQSB0cm9uZyB0b8OgbiBi4buZIGLhuqNuZy4NCg0KPT4gS+G6v3QgcXXhuqM6IFRyb25nIGLhu5kgZOG7ryBsaeG7h3Uga2jDtG5nIGPDsyBnacOhIHRy4buLIHRoaeG6v3UgKE5BKS4NCg0KIyMgIENodXnhu4NuIMSR4buVaSBjw6FjIGJp4bq/biBj4bqnbiB0aGnhur90DQoNCmBgYHtyfQ0KIyDEkOG7jWMgZOG7ryBsaeG7h3UNCmQgPC0gcmVhZC5jc3YoImhvYW5ndGluaGR1bGlldS5jc3YiKQ0KDQojIERhbmggc8OhY2ggY8OhYyBiaeG6v24gxJHhu4tuaCB0w61uaCAoY2F0ZWdvcmljYWwgdmFyaWFibGVzKQ0KY29sc190b19mYWN0b3IgPC0gYygibGVhcm5pbmdMZXZlbCIsICJQYXJ0bmVyaW5nU3RhdGUiLCAiRmFtaWx5Um9sZSIsDQogICAgICAgICAgICAgICAgICAgICJFdGhuaWNpdHkiLCAiR2VuZGVyIiwgIk5hdGlvbmFsaXR5IiwgIkVhcm5pbmdDbGFzcyIpDQoNCiMgQ2h1eeG7g24gY8OhYyBj4buZdCDEkcOzIHNhbmcgZmFjdG9yDQpkW2NvbHNfdG9fZmFjdG9yXSA8LSBsYXBwbHkoZFtjb2xzX3RvX2ZhY3Rvcl0sIGFzLmZhY3RvcikNCg0KIyBLaeG7g20gdHJhIGzhuqFpIGPhuqV1IHRyw7pjIGThu68gbGnhu4d1DQpzdHIoZCkNCg0KDQpgYGANCg0KxJDhuqd1IHRpw6puLCBj4bqnbiB4w6FjIMSR4buLbmggY8OhYyBiaeG6v24gY8OzIGdpw6EgdHLhu4sgcuG7nWkgcuG6oWMgdsOgIG1hbmcgdMOtbmggcGjDom4gbG/huqFpLCB0aMaw4budbmcgZMO5bmcgxJHhu4MgYmnhu4N1IGRp4buFbiB0aMO0bmcgdGluIMSR4buLbmggdMOtbmggbmjGsCBnaeG7m2kgdMOtbmgsIGjhu41jIHbhuqVuLCB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4sIHYudi4gRGFuaCBzw6FjaCBuw6B5IHPhur0gxJHGsOG7o2Mgc+G7rSBk4bulbmcgxJHhu4MgY2h1eeG7g24gc2FuZyBraeG7g3UgZOG7ryBsaeG7h3UgZmFjdG9yLg0KDQpTYXUgxJHDsywgw6FwIGThu6VuZyBow6BtIGxhcHBseSguLi4sIGFzLmZhY3RvcikgxJHhu4MgY2h1eeG7g24gxJHhu5VpIHThu6tuZyBiaeG6v24gdHJvbmcgZGFuaCBzw6FjaCB0aMOgbmgga2nhu4N1IGZhY3Rvci4NCg0KQ3Xhu5FpIGPDuW5nLCBj4bqtcCBuaOG6rXQgYuG6o25nIGThu68gbGnhu4d1IGQgduG7m2kgY8OhYyBj4buZdCDEkcOjIMSRxrDhu6NjIGNodXnhu4NuIMSR4buVaSBzYW5nIGThuqFuZyBwaMOibiBsb+G6oWkuDQoNCkPDoWMgYmnhur9uIMSR4buLbmggdMOtbmggYmFvIGfhu5NtOg0KDQpsZWFybmluZ0xldmVsOiBiaeG7g3UgdGjhu4sgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIHbhu5tpIDE2IGPhuqVwIMSR4buZIGtow6FjIG5oYXUgKHbDrSBk4bulOiBIUy1ncmFkLCBCYWNoZWxvcnMsIFNvbWUtY29sbGVnZS4uLikNCg0KUGFydG5lcmluZ1N0YXRlOiB0aOG7gyBoaeG7h24gdMOsbmggdHLhuqFuZyBxdWFuIGjhu4cgbmjGsCBNYXJyaWVkLCBEaXZvcmNlZCwgV2lkb3dlZCwgU2VwYXJhdGVkLCBOZXZlci1tYXJyaWVkDQoNCkZhbWlseVJvbGU6IG3DtCB04bqjIHbhu4sgdHLDrSBj4bunYSBjw6EgbmjDom4gdHJvbmcgaOG7mSBnaWEgxJHDrG5oLCBuaMawIE93bi1jaGlsZCwgTm90LWluLWZhbWlseSwgSHVzYmFuZCwgV2lmZS4uLg0KDQpFdGhuaWNpdHk6IGfhu5NtIDUgbmjDs20gY2jhu6duZyB04buZYyBjaMOtbmggdHJvbmcgZOG7ryBsaeG7h3UNCg0KR2VuZGVyOiAyIGdpw6EgdHLhu4sgKE1hbGUsIEZlbWFsZSkNCg0KTmF0aW9uYWxpdHk6IHF14buRYyBnaWEgeHXhuqV0IHjhu6ksIHbhu5tpIGjGoW4gMzAgcXXhu5FjIGdpYSAocGjhuqduIGzhu5tuIGzDoCBVbml0ZWQtU3RhdGVzKQ0KDQpFYXJuaW5nQ2xhc3M6IHBow6JuIGxv4bqhaSB0aHUgbmjhuq1wIGPDoSBuaMOibiB0aMOgbmggMiBuaMOzbSAoPD01MEssID41MEspDQoNCg0KDQojICBQaMOibiB0w61jaCBNw7QgdOG6oyBN4buZdCBiaeG6v24gxJDhu4tuaCB0w61uaA0KDQoNCmBgYHtyfQ0KIyBEYW5oIHPDoWNoIGJp4bq/biDEkeG7i25oIHTDrW5oIHRo4buxYyB04bq/IHRyb25nIGZpbGUNCnRiZHQgPC0gYygibGVhcm5pbmdMZXZlbCIsICJQYXJ0bmVyaW5nU3RhdGUiLCAiRmFtaWx5Um9sZSIsDQogICAgICAgICAgIkV0aG5pY2l0eSIsICJHZW5kZXIiLCAiTmF0aW9uYWxpdHkiLCAiRWFybmluZ0NsYXNzIikNCg0KIyBU4bqhbyBi4bqjbmcgY29uIGNo4buJIGfhu5NtIGPDoWMgYmnhur9uIMSR4buLbmggdMOtbmgNCmRxIDwtIGRbLCB0YmR0XQ0KDQojIEtp4buDbSB0cmENCnN0cihkcSkNCg0KYGBgDQoNCi0gxJDDonkgbMOgIGRhbmggc8OhY2ggKHZlY3RvcikgY2jhu6lhIHTDqm4gY8OhYyBj4buZdCDigJMgxJHhu4F1IGzDoCBiaeG6v24gxJHhu4tuaCB0w61uaC4NCg0KLSBM4bqleSB0b8OgbiBi4buZIGPDoWMgY+G7mXQgdHJvbmcgZGFuaCBzw6FjaCB0YmR0IHThu6sgYuG6o25nIGThu68gbGnhu4d1IGQsIHbDoCB04bqhbyByYSBt4buZdCBi4bqjbmcgbeG7m2kgdMOqbiBsw6AgZHEuDQoNCj0+IEvhur90IHF14bqjIGzDoCBi4bqjbmcgZHEgY2jhu4kgY2jhu6lhIGPDoWMgYmnhur9uIMSR4buLbmggdMOtbmguDQoNCiMjICoqQmnhur9uIGxlYXJuaW5nTGV2ZWwqKg0KDQojIyMgR2nhuqNpIHRow61jaCBiaeG6v24NCg0KYGBge3J9DQojIFThuqFvIGLhuqNuZyBnaeG6o2kgdGjDrWNoIGPDoWMgbeG7qWMgY+G7p2EgYmnhur9uIGxlYXJuaW5nTGV2ZWwNCmxlYXJuaW5nTGV2ZWxfbGV2ZWxzIDwtIGRhdGEuZnJhbWUoDQogIEdpYV90cmkgPSBjKCJQcmVzY2hvb2wiLCAiMXN0LTR0aCIsICI1dGgtNnRoIiwgIjd0aC04dGgiLCAiOXRoIiwgIjEwdGgiLA0KICAgICAgICAgICAgICAiMTF0aCIsICIxMnRoIiwgIkhTLWdyYWQiLCAiU29tZS1jb2xsZWdlIiwgIkFzc29jLWFjZG0iLCANCiAgICAgICAgICAgICAgIkFzc29jLXZvYyIsICJCYWNoZWxvcnMiLCAiTWFzdGVycyIsICJQcm9mLXNjaG9vbCIsICJEb2N0b3JhdGUiKSwNCiAgWV9uZ2hpYSA9IGMoDQogICAgIlRyw6xuaCDEkeG7mSBt4bqnbSBub24iLA0KICAgICJI4buNYyBo4bq/dCBs4bubcCAxIMSR4bq/biBs4bubcCA0IiwNCiAgICAiSOG7jWMgaOG6v3QgbOG7m3AgNSBob+G6t2MgbOG7m3AgNiIsDQogICAgIkjhu41jIGjhur90IGzhu5twIDcgaG/hurdjIGzhu5twIDgiLA0KICAgICJI4buNYyBo4bq/dCBs4bubcCA5IiwNCiAgICAiSOG7jWMgaOG6v3QgbOG7m3AgMTAiLA0KICAgICJI4buNYyBo4bq/dCBs4bubcCAxMSIsDQogICAgIkjhu41jIGjhur90IGzhu5twIDEyIG5oxrBuZyBraMO0bmcgdOG7kXQgbmdoaeG7h3AiLA0KICAgICJU4buRdCBuZ2hp4buHcCB0cnVuZyBo4buNYyBwaOG7lSB0aMO0bmcgKEhTLWdyYWQpIiwNCiAgICAiSOG7jWMgxJHhuqFpIGjhu41jL2NhbyDEkeG6s25nIG5oxrBuZyBjaMawYSBjw7MgYuG6sW5nIiwNCiAgICAiQuG6sW5nIGNhbyDEkeG6s25nIGjhu41jIHRodeG6rXQgKEFzc29jaWF0ZSBpbiBBY2FkZW1pYyBQcm9ncmFtKSIsDQogICAgIkLhurFuZyBjYW8gxJHhurNuZyBuZ2jhu4EgKEFzc29jaWF0ZSBpbiBWb2NhdGlvbmFsIFByb2dyYW0pIiwNCiAgICAiQuG6sW5nIGPhu60gbmjDom4gKMSQ4bqhaSBo4buNYykiLA0KICAgICJC4bqxbmcgdGjhuqFjIHPEqSIsDQogICAgIkLhurFuZyBjaHV5w6puIG5nw6BuaCBzYXUgxJHhuqFpIGjhu41jIChsdeG6rXQsIHkga2hvYeKApikiLA0KICAgICJC4bqxbmcgdGnhur9uIHPEqSINCiAgKQ0KKQ0KDQojIEhp4buDbiB0aOG7iyBi4bqjbmcNCmtuaXRyOjprYWJsZShsZWFybmluZ0xldmVsX2xldmVscywgY2FwdGlvbiA9ICJHaeG6o2kgdGjDrWNoIGPDoWMgbeG7qWMgxJHhu5kgdHJvbmcgYmnhur9uIGxlYXJuaW5nTGV2ZWwiKQ0KYGBgDQoNCi0gbGVhcm5pbmdMZXZlbF9sZXZlbHMgPC0gZGF0YS5mcmFtZSguLi4pOiBU4bqhbyBt4buZdCBi4bqjbmcgZOG7ryBsaeG7h3UgY8OzIGhhaSBj4buZdDogR2lhX3RyaSAoZ2nDoSB0cuG7iyBn4buRYyB0cm9uZyBiaeG6v24gbGVhcm5pbmdMZXZlbCkgdsOgIFlfbmdoaWEgKMO9IG5naMSpYSB0aeG6v25nIFZp4buHdCB0xrDGoW5nIOG7qW5nKS4NCg0KLSBHaWFfdHJpID0gYyguLi4pOiBU4bqtcCBo4bujcCAxNiBt4bupYyB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gxJHGsOG7o2MgbcOjIGhvw6EgdHJvbmcgZOG7ryBsaeG7h3UsIHbDrSBk4bulICJQcmVzY2hvb2wiLCAiQmFjaGVsb3JzIiwgIkRvY3RvcmF0ZSIuLi4NCg0KLSBZX25naGlhID0gYyguLi4pOiBDdW5nIGPhuqVwIGdp4bqjaSB0aMOtY2ggdGnhur9uZyBWaeG7h3QgY2hvIHThu6tuZyBt4bupYyB0cm9uZyBHaWFfdHJpLiBWw60gZOG7pSAiUHJlc2Nob29sIiB0xrDGoW5nIOG7qW5nIHbhu5tpICJUcsOsbmggxJHhu5kgbeG6p20gbm9uIiwgIkJhY2hlbG9ycyIgbMOgICJC4bqxbmcgY+G7rSBuaMOibiIuLi4NCg0KLSBrbml0cjo6a2FibGUobGVhcm5pbmdMZXZlbF9sZXZlbHMsIGNhcHRpb24gPSAiR2nhuqNpIHRow61jaCBjw6FjIG3hu6ljIMSR4buZIHRyb25nIGJp4bq/biBsZWFybmluZ0xldmVsIik6IETDuW5nIGjDoG0ga2FibGUoKSDEkeG7gyBpbiBi4bqjbmcgcmEgxJHhurlwIGjGoW4ga2hpIHThuqFvIGLDoW8gY8OhbyBSIE1hcmtkb3duLiBjYXB0aW9uIGzDoCB0acOqdSDEkeG7gSBoaeG7g24gdGjhu4sgdHLDqm4gYuG6o25nLg0KDQojIyMgVGjhu5FuZyBrw6ogdOG6p24gc3XhuqV0DQpgYGB7cn0NCiMgVOG6oW8gYuG6o25nIHThuqduIHN14bqldCBjaG8gbGVhcm5pbmdMZXZlbA0KdHNfZWR1IDwtIHRhYmxlKGQkbGVhcm5pbmdMZXZlbCkNCg0KIyBU4bqhbyBi4bqjbmcgZOG7ryBsaeG7h3UNCnRzX2VkdV9kZiA8LSBkYXRhLmZyYW1lKA0KICBHaWFfdHJpID0gbmFtZXModHNfZWR1KSwNCiAgVGFuX3NvID0gYXMudmVjdG9yKHRzX2VkdSksDQogIFR5X2xlID0gcm91bmQoKGFzLnZlY3Rvcih0c19lZHUpIC8gc3VtKHRzX2VkdSkpICogMTAwLCAyKQ0KKQ0KDQojIEhp4buDbiB0aOG7iyBr4bq/dCBxdeG6ow0KdHNfZWR1X2RmDQoNCmBgYA0KDQotIEdpYV90cmkgPSBuYW1lcyh0c19lZHUpOg0KTOG6pXkgdMOqbiBjw6FjIG3hu6ljIGdpw6EgdHLhu4sgKG3hu6ljIGjhu41jIHbhuqVuKSB04burIGLhuqNuZyB04bqnbiBzdeG6pXQgdHNfZWR1LCB2w60gZOG7pTogIlByZXNjaG9vbCIsICJCYWNoZWxvcnMiLCAiRG9jdG9yYXRlIi4uLg0KDQotIFRhbl9zbyA9IGFzLnZlY3Rvcih0c19lZHUpOg0KQ2h1eeG7g24gYuG6o25nIHThuqduIHN14bqldCB0aMOgbmggdmVjdG9yIMSR4buDIGzGsHUgc+G7kSBsxrDhu6NuZyB4deG6pXQgaGnhu4duIGPhu6dhIHThu6tuZyBt4bupYyBo4buNYyB24bqlbi4NCg0KLSBUeV9sZSA9IHJvdW5kKChhcy52ZWN0b3IodHNfZWR1KSAvIHN1bSh0c19lZHUpKSAqIDEwMCwgMik6DQpUw61uaCB04bu3IGzhu4cgcGjhuqduIHRyxINtIGPhu6dhIG3hu5dpIG3hu6ljIGjhu41jIHbhuqVuIHNvIHbhu5tpIHThu5VuZyB0b8OgbiBi4buZIChk4buxYSB0csOqbiB04bqnbiBzdeG6pXQpLCBy4buTaSBsw6BtIHRyw7JuIMSR4bq/biAyIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuLg0KDQotIHRzX2VkdV9kZjoNCkhp4buDbiB0aOG7iyBi4bqjbmcga+G6v3QgcXXhuqMgdHNfZWR1X2RmLCBn4buTbSB0w6puIG3hu6ljIGjhu41jIHbhuqVuLCB04bqnbiBzdeG6pXQgdsOgIHThu7cgbOG7hyBwaOG6p24gdHLEg20gdMawxqFuZyDhu6luZy4NCg0KQuG7mSBk4buvIGxp4buHdSBuw6B5IGdoaSBuaOG6rW4gbmhp4buBdSBt4bupYyB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4ga2jDoWMgbmhhdSBj4bunYSBuZ8aw4budaSB0aGFtIGdpYS4gVHJvbmcgxJHDszoNCg0KMyBt4bupYyDEkeG6p3UgdGnDqm4gZ+G7k206DQoNCjEwdGg6IGByIHRzX2VkdV9kZiRUYW5fc29bdHNfZWR1X2RmJEdpYV90cmkgPT0gIjEwdGgiXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX2VkdV9kZiRUeV9sZVt0c19lZHVfZGYkR2lhX3RyaSA9PSAiMTB0aCJdLCAiJSIpYCksDQoNCjExdGg6IGByIHRzX2VkdV9kZiRUYW5fc29bdHNfZWR1X2RmJEdpYV90cmkgPT0gIjExdGgiXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX2VkdV9kZiRUeV9sZVt0c19lZHVfZGYkR2lhX3RyaSA9PSAiMTF0aCJdLCAiJSIpYCksDQoNCjEydGg6IGByIHRzX2VkdV9kZiRUYW5fc29bdHNfZWR1X2RmJEdpYV90cmkgPT0gIjEydGgiXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX2VkdV9kZiRUeV9sZVt0c19lZHVfZGYkR2lhX3RyaSA9PSAiMTJ0aCJdLCAiJSIpYCkuDQoNCjMgbeG7qWMgY3Xhu5FpIGPDuW5nIGfhu5NtOg0KDQpTb21lLWNvbGxlZ2U6IGByIHRzX2VkdV9kZiRUYW5fc29bdHNfZWR1X2RmJEdpYV90cmkgPT0gIlNvbWUtY29sbGVnZSJdYCBuZ8aw4budaSAoY2hp4bq/bSBgciBwYXN0ZTAodHNfZWR1X2RmJFR5X2xlW3RzX2VkdV9kZiRHaWFfdHJpID09ICJTb21lLWNvbGxlZ2UiXSwgIiUiKWApLA0KDQpQcmVzY2hvb2w6IGByIHRzX2VkdV9kZiRUYW5fc29bdHNfZWR1X2RmJEdpYV90cmkgPT0gIlByZXNjaG9vbCJdYCBuZ8aw4budaSAoY2hp4bq/bSBgciBwYXN0ZTAodHNfZWR1X2RmJFR5X2xlW3RzX2VkdV9kZiRHaWFfdHJpID09ICJQcmVzY2hvb2wiXSwgIiUiKWApLA0KDQpQcm9mLXNjaG9vbDogYHIgdHNfZWR1X2RmJFRhbl9zb1t0c19lZHVfZGYkR2lhX3RyaSA9PSAiUHJvZi1zY2hvb2wiXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX2VkdV9kZiRUeV9sZVt0c19lZHVfZGYkR2lhX3RyaSA9PSAiUHJvZi1zY2hvb2wiXSwgIiUiKWApLg0KDQojIyMgVHLhu7FjIHF1YW4gaMOzYQ0KDQpgYGB7ciBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9Nn0NCmxpYnJhcnkoZ2dwbG90MikNCg0KIyBW4bq9IGJp4buDdSDEkeG7kyBj4buZdCBjaG8gYmnhur9uIGxlYXJuaW5nTGV2ZWwNCmdncGxvdCh0c19lZHVfZGYsIGFlcyh4ID0gcmVvcmRlcihHaWFfdHJpLCAtVGFuX3NvKSwgeSA9IFRhbl9zbywgZmlsbCA9IEdpYV90cmkpKSArDQogIGdlb21fY29sKGNvbG9yID0gIndoaXRlIiwgd2lkdGggPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IFRhbl9zbyksDQogICAgICAgICAgICB2anVzdCA9IC0wLjUsIHNpemUgPSA0LCBmb250ZmFjZSA9ICJib2xkIiwgY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkJp4buDdSDEkeG7kyBj4buZdDogUGjDom4gYuG7kSB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gKGxlYXJuaW5nTGV2ZWwpIiwNCiAgICB4ID0gIlRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiIsDQogICAgeSA9ICJU4bqnbiBz4buRIg0KICApICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMikgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpDQogICkNCg0KDQpgYGANCg0KLSBgYGB7ciBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9Nn06DQrEkMOieSBsw6AgcGjhuqduIG3hu58gxJHhuqd1IGPhu6dhIG3hu5l0IGto4buRaSBtw6MgUiB0cm9uZyBSIE1hcmtkb3duLCB0aGnhur90IGzhuq1wIGvDrWNoIHRoxrDhu5tjIGjDrG5oIOG6o25oIMSR4bqndSByYTogY2hp4buBdSBy4buZbmcgMTIgxJHGoW4gduG7iywgY2hp4buBdSBjYW8gNiDEkcahbiB24buLLg0KDQotIGxpYnJhcnkoZ2dwbG90Mik6DQpO4bqhcCB0aMawIHZp4buHbiBnZ3Bsb3QyIMSR4buDIHPhu60gZOG7pW5nIGPDoWMgaMOgbSB24bq9IGJp4buDdSDEkeG7kyB0cm9uZyBo4buHIHRo4buRbmcgxJHhu5MgaOG7jWEgZ2dwbG90Lg0KDQotIGdncGxvdCh0c19lZHVfZGYsIGFlcyh4ID0gcmVvcmRlcihHaWFfdHJpLCAtVGFuX3NvKSwgeSA9IFRhbl9zbywgZmlsbCA9IEdpYV90cmkpKSA6IEto4bufaSB04bqhbyBiaeG7g3UgxJHhu5MgY+G7mXQgdOG7qyBi4bqjbmcgdHNfZWR1X2RmLiBUcuG7pWMgeCBsw6AgYmnhur9uIEdpYV90cmkgKHTDqm4gbeG7qWMgaOG7jWMgduG6pW4pLCDEkcaw4bujYyBz4bqvcCB44bq/cCB0aGVvIFRhbl9zbyBnaeG6o20gZOG6p24uIFRy4bulYyB5IGzDoCBUYW5fc28uIE3DoHUgc+G6r2MgY+G7p2EgdOG7q25nIGPhu5l0IMSRxrDhu6NjIHBow6JuIGJp4buHdCB0aGVvIEdpYV90cmkuDQoNCi0gZ2VvbV9jb2woY29sb3IgPSAid2hpdGUiLCB3aWR0aCA9IDAuNykgOg0KVuG6vSBjw6FjIGPhu5l0IGJp4buDdSDEkeG7kyB24bubaSB2aeG7gW4gdHLhuq9uZyB2w6AgxJHhu5kgcuG7mW5nIDAuNy4NCg0KLSBnZW9tX3RleHQoYWVzKGxhYmVsID0gVGFuX3NvKSwgdmp1c3QgPSAtMC41LCBzaXplID0gNCwgZm9udGZhY2UgPSAiYm9sZCIsIGNvbG9yID0gImJsYWNrIikgOg0KVGjDqm0gbmjDo24gc+G7kSBsaeG7h3UgKGdpw6EgdHLhu4sgdOG6p24gc+G7kSkgdHLDqm4gxJHhuqd1IG3hu5dpIGPhu5l0LCBjYW5oIGNo4buJbmggbmjDo24gaMahaSBjYW8gaMahbiBj4buZdCAodmp1c3QgPSAtMC41KSwgY2jhu68gxJHhuq1tIG3DoHUgxJFlbiB2w6AgY+G7oSA0Lg0KDQotIGxhYnMoLi4uKSA6DQrEkOG6t3QgdGnDqnUgxJHhu4EgYmnhu4N1IMSR4buTIGzDoCAiQmnhu4N1IMSR4buTIGPhu5l0OiBQaMOibiBi4buRIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiAobGVhcm5pbmdMZXZlbCkiLCB0cuG7pWMgeCBsw6AgIlRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiIgdsOgIHRy4bulYyB5IGzDoCAiVOG6p24gc+G7kSIuDQoNCi0gdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMikgOg0Kw4FwIGThu6VuZyBnaWFvIGRp4buHbiB04buRaSBnaeG6o24gY2hvIGJp4buDdSDEkeG7kyB24bubaSBj4buhIGNo4buvIGPGoSBi4bqjbiBsw6AgMTIuDQoNCi0gdGhlbWUoLi4uKTogVHXhu7MgY2jhu4luaCB0aMOqbSBjaG8gYmnhu4N1IMSR4buTOg0KDQotIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpOiBDxINuIGdp4buvYSB0acOqdSDEkeG7gSB2w6AgaW4gxJHhuq1tLg0KDQotIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSk6IFhvYXkgbmjDo24gdHLhu6VjIHggNDUgxJHhu5ksIGNhbmggbOG7gSBjaG8gZOG7hSDEkeG7jWMuDQoNCg0KYGBge3IgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTZ9DQpsaWJyYXJ5KGdncGxvdDIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgY2hvIHThu7cgbOG7hyBwaOG6p24gdHLEg20gdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuDQpnZ3Bsb3QodHNfZWR1X2RmLCBhZXMoeCA9IHJlb3JkZXIoR2lhX3RyaSwgLVR5X2xlKSwgeSA9IFR5X2xlLCBmaWxsID0gR2lhX3RyaSkpICsNCiAgZ2VvbV9jb2woY29sb3IgPSAid2hpdGUiLCB3aWR0aCA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKFR5X2xlLCAiJSIpKSwNCiAgICAgICAgICAgIHZqdXN0ID0gLTAuNSwgc2l6ZSA9IDQsIGZvbnRmYWNlID0gImJvbGQiLCBjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiQmnhu4N1IMSR4buTIGPhu5l0OiBU4bu3IGzhu4cgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIChsZWFybmluZ0xldmVsKSIsDQogICAgeCA9ICJUcsOsbmggxJHhu5kgaOG7jWMgduG6pW4iLA0KICAgIHkgPSAiVOG7tyBs4buHICglKSINCiAgKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTIpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKQ0KICApDQpgYGANCiMjIyBOaOG6rW4geMOpdCANCg0KSFMtZ3JhZCAodOG7kXQgbmdoaeG7h3AgcGjhu5UgdGjDtG5nKSBsw6AgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIHBo4buVIGJp4bq/biBuaOG6pXQgduG7m2kgMTAuNTAxIG5nxrDhu51pLCBjaGnhur9tIH4zMi4zJSB04buVbmcgbeG6q3UuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IHBo4bqnbiBs4bubbiBuZ8aw4budaSB0aGFtIGdpYSBraOG6o28gc8OhdCBjaOG7iSBk4burbmcgbOG6oWkg4bufIHRyw6xuaCDEkeG7mSB0cnVuZyBo4buNYy4NCg0KU29tZS1jb2xsZWdlICjEkcOjIGjhu41jIMSR4bqhaSBo4buNYyBuaMawbmcgY2jGsGEgdOG7kXQgbmdoaeG7h3ApIMSR4bupbmcgdGjhu6kgaGFpIHbhu5tpIDcuMjkxIG5nxrDhu51pLCB0xrDGoW5nIMSRxrDGoW5nIH4yMi40JSwgcGjhuqNuIMOhbmggeHUgaMaw4bubbmcga2jDoSBuaGnhu4F1IG5nxrDhu51pIHThu6tuZyB0aeG6v3AgY+G6rW4gYuG6rWMgaOG7jWMgxJHhuqFpIGjhu41jIG5oxrBuZyBraMO0bmcgaG/DoG4gdOG6pXQuDQoNCkJhY2hlbG9ycyAoY+G7rSBuaMOibikgbMOgIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiDEkeG6p3kgxJHhu6cgY+G6pXAgxJHhuqFpIGjhu41jIHBo4buVIGJp4bq/biBuaOG6pXQgduG7m2kgNS4zNTUgbmfGsOG7nWkgKH4xNi41JSksIGNhbyBoxqFuIGjhurNuIHNvIHbhu5tpIGPDoWMgdHLDrG5oIMSR4buZIHNhdSDEkeG6oWkgaOG7jWMuDQoNCkPDoWMgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIHRo4bqlcCBuaMawOg0KDQotIDExdGggKGzhu5twIDExKSDigJMgMS4xNzUgbmfGsOG7nWkNCg0KLSAxMHRoIChs4bubcCAxMCkg4oCTIDEuMDY3IG5nxrDhu51pDQoNCi0gN3RoLTh0aCDigJMgOTMzIG5nxrDhu51pDQoNCuKGkiBOaOG7r25nIG3hu6ljIG7DoHkgY2hvIHRo4bqleSBjw7JuIGPDsyBt4buZdCBi4buZIHBo4bqtbiBkw6JuIHPhu5Ega2jDtG5nIGhvw6BuIHRow6BuaCBi4bqtYyBwaOG7lSB0aMO0bmcuDQoNCkPDoWMgY+G6pXAgxJHhu5kgc2F1IMSR4bqhaSBo4buNYyBuaMawOg0KDQotIE1hc3RlcnMgKHRo4bqhYyBzxKkpIOKAkyA1NzYgbmfGsOG7nWkgKH4xLjglKQ0KDQotIERvY3RvcmF0ZSAodGnhur9uIHPEqSkg4oCTIDQxMyBuZ8aw4budaSAofjEuMyUpDQoNCi0gUHJvZi1zY2hvb2wgKGNodXnDqm4ga2hvYSBuaMawIHksIGx14bqtdCkg4oCTIDUxNCBuZ8aw4budaSAofjEuNiUpDQoNCuKGkiBU4buVbmcgbOG6oWkgY2jhu4kga2hv4bqjbmcgMS41MDAgbmfGsOG7nWkgKH40LjYlKSwgY2jhu6luZyB04buPIHPhu5EgbmfGsOG7nWkgaOG7jWMgY2FvIGjhu41jIHbhuqtuIGzDoCB0aGnhu4N1IHPhu5EuDQoNCkPDoWMgdHLDrG5oIMSR4buZIHLhuqV0IHRo4bqlcCBuaMawOg0KDQotIDFzdC00dGggKGzhu5twIDHigJM0KSDigJMgMTY4IG5nxrDhu51pDQoNCi0gUHJlc2Nob29sICht4bqrdSBnacOhbykg4oCTIDUxIG5nxrDhu51pDQoNCuKGkiBD4buxYyBr4buzIGhp4bq/bSBn4bq3cCB0cm9uZyBt4bqrdSBraOG6o28gc8OhdCAoY2jGsGEgxJHhur9uIDAuNyUgdOG7lW5nIHPhu5EpLCB0aMaw4budbmcgdGh14buZYyBuaMOzbSBuZ8aw4budaSBkaSBjxrAgaG/hurdjIGNhbyB0deG7lWkuDQoNCkPDoWMgdHLDrG5oIMSR4buZIG5n4bqvbiBo4bqhbiBob+G6t2MgbGnDqm4ga+G6v3QgbmjGsDoNCg0KLSBBc3NvYy12b2Mg4oCTIDEuMzgyIG5nxrDhu51pDQoNCi0gQXNzb2MtYWNkbSDigJMgMS43MjMgbmfGsOG7nWkNCg0K4oaSIENoaeG6v20ga2hv4bqjbmcgMy4yJSB2w6AgNS4zJSB0xrDGoW5nIOG7qW5nLCB0aOG7gyBoaeG7h24gbcO0IGjDrG5oIGdpw6FvIGThu6VjIG5naOG7gS9uZ+G6r24gaOG6oW4gY8OzIG3hurd0IG5oxrBuZyBraMO0bmcgY2hp4bq/bSDGsHUgdGjhur8uDQoNCg0KIyMgKipCaeG6v24gUGFydG5lcmluZ1N0YXRlKioNCg0KIyMjIEdp4bqjaSB0aMOtY2ggYmnhur9uDQoNCmBgYHtyfQ0KIyBHaeG6o2kgdGjDrWNoIGPDoWMgbeG7qWMgY+G7p2EgYmnhur9uIFBhcnRuZXJpbmdTdGF0ZQ0KbWFyaXRhbF9sZXZlbHMgPC0gZGF0YS5mcmFtZSgNCiAgR2lhX3RyaSA9IGMoIkRpdm9yY2VkIiwgIk1hcnJpZWQtQUYtc3BvdXNlIiwgIk1hcnJpZWQtY2l2LXNwb3VzZSIsDQogICAgICAgICAgICAgICJNYXJyaWVkLXNwb3VzZS1hYnNlbnQiLCAiTmV2ZXItbWFycmllZCIsICJTZXBhcmF0ZWQiLCAiV2lkb3dlZCIpLA0KICBZX25naGlhID0gYygNCiAgICAiTHkgZOG7iyIsDQogICAgIkvhur90IGjDtG4gduG7m2kgbmfGsOG7nWkgdHJvbmcgbOG7sWMgbMaw4bujbmcgdsWpIHRyYW5nIiwNCiAgICAixJDDoyBr4bq/dCBow7RuIGjhu6NwIHBow6FwIiwNCiAgICAiS+G6v3QgaMO0biBuaMawbmcgc+G7kW5nIGx5IHRow6JuIiwNCiAgICAiQ2jGsGEgdOG7q25nIGvhur90IGjDtG4iLA0KICAgICJMeSB0aMOibiBjw7MgcGjDoXAgbMO9IiwNCiAgICAiR8OzYSINCiAgKQ0KKQ0KDQprbml0cjo6a2FibGUobWFyaXRhbF9sZXZlbHMsIGNhcHRpb24gPSAiR2nhuqNpIHRow61jaCBjw6FjIG3hu6ljIHRyb25nIGJp4bq/biBQYXJ0bmVyaW5nU3RhdGUiKQ0KDQpgYGANCg0KIyMjIFRo4buRbmcga8OqIFThuqduIHN14bqldA0KYGBge3J9DQojIFThuqFvIGLhuqNuZyB04bqnbiBzdeG6pXQgY2hvIFBhcnRuZXJpbmdTdGF0ZQ0KdHNfbWFyaXRhbCA8LSB0YWJsZShkJFBhcnRuZXJpbmdTdGF0ZSkNCg0KIyBU4bqhbyBi4bqjbmcgZOG7ryBsaeG7h3UNCnRzX21hcml0YWxfZGYgPC0gZGF0YS5mcmFtZSgNCiAgR2lhX3RyaSA9IG5hbWVzKHRzX21hcml0YWwpLA0KICBUYW5fc28gPSBhcy52ZWN0b3IodHNfbWFyaXRhbCksDQogIFR5X2xlID0gcm91bmQoKGFzLnZlY3Rvcih0c19tYXJpdGFsKSAvIHN1bSh0c19tYXJpdGFsKSkgKiAxMDAsIDIpDQopDQoNCiMgSGnhu4NuIHRo4buLIGvhur90IHF14bqjDQp0c19tYXJpdGFsX2RmDQoNCg0KYGBgDQoNCi0gxJDDoyBseSBk4buLIChEaXZvcmNlZCk6IGPDsyBgciB0c19tYXJpdGFsX2RmJFRhbl9zb1t0c19tYXJpdGFsX2RmJEdpYV90cmkgPT0gIkRpdm9yY2VkIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19tYXJpdGFsX2RmJFR5X2xlW3RzX21hcml0YWxfZGYkR2lhX3RyaSA9PSAiRGl2b3JjZWQiXSwgIiUiKWApLg0KDQotIEvhur90IGjDtG4gduG7m2kgbmfGsOG7nWkgdHJvbmcgcXXDom4gxJHhu5lpIChNYXJyaWVkLUFGLXNwb3VzZSk6IGPDsyBgciB0c19tYXJpdGFsX2RmJFRhbl9zb1t0c19tYXJpdGFsX2RmJEdpYV90cmkgPT0gIk1hcnJpZWQtQUYtc3BvdXNlIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19tYXJpdGFsX2RmJFR5X2xlW3RzX21hcml0YWxfZGYkR2lhX3RyaSA9PSAiTWFycmllZC1BRi1zcG91c2UiXSwgIiUiKWApLg0KDQotIMSQw6Mga+G6v3QgaMO0biBo4bujcCBwaMOhcCAoTWFycmllZC1jaXYtc3BvdXNlKTogY8OzIGByIHRzX21hcml0YWxfZGYkVGFuX3NvW3RzX21hcml0YWxfZGYkR2lhX3RyaSA9PSAiTWFycmllZC1jaXYtc3BvdXNlIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19tYXJpdGFsX2RmJFR5X2xlW3RzX21hcml0YWxfZGYkR2lhX3RyaSA9PSAiTWFycmllZC1jaXYtc3BvdXNlIl0sICIlIilgKS4NCg0KLSBMeSB0aMOibiAoTWFycmllZC1zcG91c2UtYWJzZW50KTogY8OzIGByIHRzX21hcml0YWxfZGYkVGFuX3NvW3RzX21hcml0YWxfZGYkR2lhX3RyaSA9PSAiTWFycmllZC1zcG91c2UtYWJzZW50Il1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19tYXJpdGFsX2RmJFR5X2xlW3RzX21hcml0YWxfZGYkR2lhX3RyaSA9PSAiTWFycmllZC1zcG91c2UtYWJzZW50Il0sICIlIilgKS4NCg0KLSBDaMawYSB04burbmcga+G6v3QgaMO0biAoTmV2ZXItbWFycmllZCk6IGPDsyBgciB0c19tYXJpdGFsX2RmJFRhbl9zb1t0c19tYXJpdGFsX2RmJEdpYV90cmkgPT0gIk5ldmVyLW1hcnJpZWQiXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX21hcml0YWxfZGYkVHlfbGVbdHNfbWFyaXRhbF9kZiRHaWFfdHJpID09ICJOZXZlci1tYXJyaWVkIl0sICIlIilgKS4NCg0KLSBMeSB0aMOibiBjw7MgcGjDoXAgbMO9IChTZXBhcmF0ZWQpOiBjw7MgYHIgdHNfbWFyaXRhbF9kZiRUYW5fc29bdHNfbWFyaXRhbF9kZiRHaWFfdHJpID09ICJTZXBhcmF0ZWQiXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX21hcml0YWxfZGYkVHlfbGVbdHNfbWFyaXRhbF9kZiRHaWFfdHJpID09ICJTZXBhcmF0ZWQiXSwgIiUiKWApLg0KDQotIEfDs2EgKFdpZG93ZWQpOiBjw7MgYHIgdHNfbWFyaXRhbF9kZiRUYW5fc29bdHNfbWFyaXRhbF9kZiRHaWFfdHJpID09ICJXaWRvd2VkIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19tYXJpdGFsX2RmJFR5X2xlW3RzX21hcml0YWxfZGYkR2lhX3RyaSA9PSAiV2lkb3dlZCJdLCAiJSIpYCkuDQoNCg0KIyMjIFRy4buxYyBxdWFuIGjDs2ENCmBgYHtyIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02fQ0KZ2dwbG90KHRzX21hcml0YWxfZGYsIGFlcyh4ID0gcmVvcmRlcihHaWFfdHJpLCAtVGFuX3NvKSwgeSA9IFRhbl9zbywgZmlsbCA9IEdpYV90cmkpKSArDQogIGdlb21fY29sKHdpZHRoID0gMC41LCBjb2xvciA9ICJwaW5rIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gVGFuX3NvKSwgdmp1c3QgPSAtMC4zLCBzaXplID0gNCwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJCaeG7g3UgxJHhu5MgY+G7mXQ6IFTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiAoUGFydG5lcmluZ1N0YXRlKSIsDQogICAgeCA9ICJUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4iLA0KICAgIHkgPSAiVOG6p24gc+G7kSINCiAgKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTMpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICANCiAgKQ0KDQpgYGANCg0KYGBge3IgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTh9DQpnZ3Bsb3QodHNfbWFyaXRhbF9kZiwgYWVzKHggPSByZW9yZGVyKEdpYV90cmksIFR5X2xlKSwgeSA9IFR5X2xlLCBmaWxsID0gR2lhX3RyaSkpICsNCiAgZ2VvbV9jb2wod2lkdGggPSAwLjYsIGNvbG9yID0gImxpZ2h0cGluayIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChUeV9sZSwgIiUiKSksDQogICAgICAgICAgICBoanVzdCA9IC0wLjEsIHNpemUgPSA0LCBmb250ZmFjZSA9ICJib2xkIiwgY29sb3IgPSAibGlnaHR5ZWxsb3ciKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiQmnhu4N1IMSR4buTIGPhu5l0IG5nYW5nOiBU4bu3IGzhu4cgdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIChQYXJ0bmVyaW5nU3RhdGUpIiwNCiAgICB4ID0gIlTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiIsDQogICAgeSA9ICJU4bu3IGzhu4cgKCUpIg0KICApICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMykgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKQ0KICApDQoNCmBgYA0KDQotIGdncGxvdCh0c19tYXJpdGFsX2RmLCBhZXMoeCA9IHJlb3JkZXIoR2lhX3RyaSwgVGFuX3NvKSwgeSA9IFRhbl9zbywgZmlsbCA9IEdpYV90cmkpKSA6IFThuqFvIGJp4buDdSDEkeG7kyBj4buZdCB04burIGLhuqNuZyB0c19tYXJpdGFsX2RmLiBUcuG7pWMgaG/DoG5oICh4KSBsw6AgYmnhur9uIEdpYV90cmkg4oCTIGPDoWMgbeG7qWMgY+G7p2EgdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIOKAkyDEkcaw4bujYyBz4bqvcCB44bq/cCB0xINuZyBk4bqnbiB0aGVvIFRhbl9zby4gVHLhu6VjIHR1bmcgKHkpIGzDoCB04bqnbiBz4buRIHTGsMahbmcg4bupbmcuIE3hu5dpIGPhu5l0IGPDsyBtw6B1IGtow6FjIG5oYXUgdGhlbyBnacOhIHRy4buLIGPhu6dhIEdpYV90cmkuDQoNCi0gZ2VvbV9jb2wod2lkdGggPSAwLjYsIGNvbG9yID0gIndoaXRlIik6IFbhur0gY8OhYyBj4buZdCB24bubaSBjaGnhu4F1IHLhu5luZyBsw6AgMC42IHbDoCB2aeG7gW4gbcOgdSB0cuG6r25nLCBnacO6cCBj4buZdCB0w6FjaCBiaeG7h3QgcsO1IHLDoG5nLg0KDQotIGdlb21fdGV4dChhZXMobGFiZWwgPSBUYW5fc28pLCBoanVzdCA9IC0wLjEsIHNpemUgPSA0LCBmb250ZmFjZSA9ICJib2xkIiwgY29sb3IgPSAiYmxhY2siKSA6IFRow6ptIG5ow6NuIHPhu5EgbGnhu4d1IChUYW5fc28pIGNobyB04burbmcgY+G7mXQuIE5ow6NuIMSRxrDhu6NjIMSR4bq3dCBoxqFpIGzhu4djaCB0csOhaSAoaGp1c3QgPSAtMC4xKSwgY+G7oSBjaOG7ryA0LCBpbiDEkeG6rW0gdsOgIG3DoHUgxJFlbi4NCg0KLSBjb29yZF9mbGlwKCkgOiBM4bqtdCBo4buHIHRy4bulYyB04buNYSDEkeG7mSDEkeG7gyBiaeG7g3UgxJHhu5MgaGnhu4NuIHRo4buLIHRoZW8gY2hp4buBdSBuZ2FuZyDigJMgdOG7qWMgbMOgIGPDoWMgY+G7mXQgc+G6vSBu4bqxbSBuZ2FuZyB0aGF5IHbDrCBk4buNYy4NCg0KLSBsYWJzKC4uLikgOiDEkOG6t3QgdGnDqnUgxJHhu4EgYmnhu4N1IMSR4buTIGzDoCAiQmnhu4N1IMSR4buTIGPhu5l0IG5nYW5nOiBUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gKFBhcnRuZXJpbmdTdGF0ZSkiLCB0cuG7pWMgeCBsw6AgIlTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiIsIHRy4bulYyB5IGzDoCAiVOG6p24gc+G7kSIuDQoNCi0gdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMykgOiDDgXAgZOG7pW5nIGdpYW8gZGnhu4duIHThu5FpIGdp4bqjbiAobWluaW1hbCkgY2hvIGJp4buDdSDEkeG7kyB24bubaSBj4buhIGNo4buvIG3hurdjIMSR4buLbmggbMOgIDEzLg0KDQotIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpLCAuLi4pDQpUdeG7syBjaOG7iW5oIHRpw6p1IMSR4buBIGJp4buDdSDEkeG7kyDEkeG7gyBjxINuIGdp4buvYSAoaGp1c3QgPSAwLjUpIHbDoCBpbiDEkeG6rW0gKGZhY2UgPSAiYm9sZCIpLg0KDQoNCiMjIyBOaOG6rW4geMOpdA0KDQotICJNYXJyaWVkLWNpdi1zcG91c2UiIChr4bq/dCBow7RuIGjhu6NwIHBow6FwKSBjaGnhur9tIDQzLjk0JSwgY2FvIG5o4bqldCB0cm9uZyB0b8OgbiBi4buZIGThu68gbGnhu4d1IOKAkyBjaG8gdGjhuqV5IGPhuqV1IHRyw7pjIGdpYSDEkcOsbmggdHJ1eeG7gW4gdGjhu5FuZyB24bqrbiBjaGnhur9tIMawdSB0aOG6vy4NCg0KLSAiTmV2ZXItbWFycmllZCIgxJHhuqF0IDMyLjgxJSwgbMOgIG5ow7NtIGzhu5tuIHRo4bupIGhhaSwgcGjhuqNuIMOhbmggc+G7sSBoaeG7h24gZGnhu4duIG3huqFuaCBt4bq9IGPhu6dhIG5nxrDhu51pIMSR4buZYyB0aMOibi4NCg0KLSBDw6FjIG5ow7NtIGPDsm4gbOG6oWkgbmjGsCAiRGl2b3JjZWQiICgxMi4yOSUpLCAiTWFycmllZC1zcG91c2UtYWJzZW50IiAoNC43OSUpLCAiU2VwYXJhdGVkIiAoMy4xMyUpLCB2w6AgIldpZG93ZWQiICgzLjA1JSkgZ8OzcCBwaOG6p24gdOG6oW8gbsOqbiB0w61uaCDEkWEgZOG6oW5nIHRyb25nIHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiwgbmjGsG5nIMSR4buBdSBjaGnhur9tIHThu7cgbOG7hyB0aOG6pXAgaMahbg0KDQoNCiMjICoqQmnhur9uIEZhbWlseVJvbGUqKg0KDQojIyMgR2nhuqNpIHRow61jaCBiaeG6v24NCg0KYGBge3J9DQojIEdp4bqjaSB0aMOtY2ggY8OhYyBt4bupYyBj4bunYSBiaeG6v24gRmFtaWx5Um9sZQ0KRmFtaWx5Um9sZV9sZXZlbHMgPC0gZGF0YS5mcmFtZSgNCiAgR2lhX3RyaSA9IGMoIkh1c2JhbmQiLCAiTm90LWluLWZhbWlseSIsICJPdGhlci1yZWxhdGl2ZSIsIA0KICAgICAgICAgICAgICAiT3duLWNoaWxkIiwgIlVubWFycmllZCIsICJXaWZlIiksDQogIFlfbmdoaWEgPSBjKA0KICAgICJDaOG7k25nIiwNCiAgICAiS2jDtG5nIGPDuW5nIGdpYSDEkcOsbmggKGLhuqFuIHRy4buNLCBi4bqhbiBiw6gpIiwNCiAgICAiSOG7jSBow6BuZyBraMOhYyAoY2jDoXUsIGPDtCwgY2jDui4uLikiLA0KICAgICJDb24gcnXhu5l0IiwNCiAgICAiS2jDtG5nIGvhur90IGjDtG4gKMSR4buZYyB0aMOibiwgbHkgZOG7iy4uLikiLA0KICAgICJW4bujIg0KICApDQopDQoNCmtuaXRyOjprYWJsZShGYW1pbHlSb2xlX2xldmVscywgY2FwdGlvbiA9ICJHaeG6o2kgdGjDrWNoIGPDoWMgbeG7qWMgdHJvbmcgYmnhur9uIEZhbWlseVJvbGUiKQ0KYGBgDQoNCg0KIyMjIFRo4buRbmcga8OqIFThuqduIHN14bqldA0KYGBge3J9DQojIFThuqFvIGLhuqNuZyB04bqnbiBzdeG6pXQgY2hvIEZhbWlseVJvbGUNCnRzX0ZhbWlseVJvbGUgPC0gdGFibGUoZCRGYW1pbHlSb2xlKQ0KDQojIFThuqFvIGLhuqNuZyBk4buvIGxp4buHdQ0KdHNfRmFtaWx5Um9sZV9kZiA8LSBkYXRhLmZyYW1lKA0KICBHaWFfdHJpID0gbmFtZXModHNfRmFtaWx5Um9sZSksDQogIFRhbl9zbyA9IGFzLnZlY3Rvcih0c19GYW1pbHlSb2xlKSwNCiAgVHlfbGUgPSByb3VuZCgoYXMudmVjdG9yKHRzX0ZhbWlseVJvbGUpIC8gc3VtKHRzX0ZhbWlseVJvbGUpKSAqIDEwMCwgMikNCikNCg0KIyBIaeG7g24gdGjhu4sga+G6v3QgcXXhuqMNCnRzX0ZhbWlseVJvbGVfZGYNCg0KYGBgDQoNCi0gQmnhur9uIGBGYW1pbHlSb2xlYCAobeG7kWkgcXVhbiBo4buHIHRyb25nIGjhu5kgZ2lhIMSRw6xuaCkgYmFvIGfhu5NtIDYgbeG7qWMgbmjGsCBzYXU6DQoNCiAgLSAqKktow7RuZyB0cm9uZyBnaWEgxJHDrG5oKiogKGBOb3QtaW4tZmFtaWx5YCk6IGPDsyBgciB0c19GYW1pbHlSb2xlX2RmJFRhbl9zb1t0c19GYW1pbHlSb2xlX2RmJEdpYV90cmkgPT0gIk5vdC1pbi1mYW1pbHkiXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX0ZhbWlseVJvbGVfZGYkVHlfbGVbdHNfRmFtaWx5Um9sZV9kZiRHaWFfdHJpID09ICJOb3QtaW4tZmFtaWx5Il0sICIlIilgKS4NCg0KLSAqKkjhu40gaMOgbmcga2jDoWMqKiAoYE90aGVyLXJlbGF0aXZlYCk6IGPDsyBgciB0c19GYW1pbHlSb2xlX2RmJFRhbl9zb1t0c19GYW1pbHlSb2xlX2RmJEdpYV90cmkgPT0gIk90aGVyLXJlbGF0aXZlIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19GYW1pbHlSb2xlX2RmJFR5X2xlW3RzX0ZhbWlseVJvbGVfZGYkR2lhX3RyaSA9PSAiT3RoZXItcmVsYXRpdmUiXSwgIiUiKWApLg0KDQotICoqQ29uIHJ14buZdCoqIChgT3duLWNoaWxkYCk6IGPDsyBgciB0c19GYW1pbHlSb2xlX2RmJFRhbl9zb1t0c19GYW1pbHlSb2xlX2RmJEdpYV90cmkgPT0gIk93bi1jaGlsZCJdYCBuZ8aw4budaSAoY2hp4bq/bSBgciBwYXN0ZTAodHNfRmFtaWx5Um9sZV9kZiRUeV9sZVt0c19GYW1pbHlSb2xlX2RmJEdpYV90cmkgPT0gIk93bi1jaGlsZCJdLCAiJSIpYCkuDQoNCi0gKirEkOG7mWMgdGjDom4qKiAoYFVubWFycmllZGApOiBjw7MgYHIgdHNfRmFtaWx5Um9sZV9kZiRUYW5fc29bdHNfRmFtaWx5Um9sZV9kZiRHaWFfdHJpID09ICJVbm1hcnJpZWQiXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX0ZhbWlseVJvbGVfZGYkVHlfbGVbdHNfRmFtaWx5Um9sZV9kZiRHaWFfdHJpID09ICJVbm1hcnJpZWQiXSwgIiUiKWApLg0KDQotICoqVuG7oyoqIChgV2lmZWApOiBjw7MgYHIgdHNfRmFtaWx5Um9sZV9kZiRUYW5fc29bdHNfRmFtaWx5Um9sZV9kZiRHaWFfdHJpID09ICJXaWZlIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19GYW1pbHlSb2xlX2RmJFR5X2xlW3RzX0ZhbWlseVJvbGVfZGYkR2lhX3RyaSA9PSAiV2lmZSJdLCAiJSIpYCkuDQoNCg0KIyMjIFRy4buxYyBxdWFuIGjDs2ENCmBgYHtyIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02fQ0KZ2dwbG90KHRzX0ZhbWlseVJvbGVfZGYsIGFlcyh4ID0gcmVvcmRlcihHaWFfdHJpLCAtVGFuX3NvKSwgeSA9IFRhbl9zbywgZmlsbCA9IEdpYV90cmkpKSArDQogIGdlb21fY29sKHdpZHRoID0gMC41LCBjb2xvciA9ICJza3libHVlIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gVGFuX3NvKSwgdmp1c3QgPSAtMC4zLCBzaXplID0gNCwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJCaeG7g3UgxJHhu5MgY+G7mXQ6IE3hu5FpIHF1YW4gaOG7hyB0cm9uZyBo4buZIChGYW1pbHlSb2xlKSIsDQogICAgeCA9ICJN4buRaSBxdWFuIGjhu4ciLA0KICAgIHkgPSAiVOG6p24gc+G7kSINCiAgKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTMpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgDQogICkNCg0KYGBgDQoNCmBgYHtyIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02fQ0KZ2dwbG90KHRzX0ZhbWlseVJvbGVfZGYsIGFlcyh4ID0gIiIsIHkgPSBUeV9sZSwgZmlsbCA9IEdpYV90cmkpKSArDQogIGdlb21fY29sKHdpZHRoID0gMSwgY29sb3IgPSAic2t5Ymx1ZSIpICsNCiAgY29vcmRfcG9sYXIodGhldGEgPSAieSIpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikgKw0KICBsYWJzKHRpdGxlID0gIkJp4buDdSDEkeG7kyB0csOybjogTeG7kWkgcXVhbiBo4buHIHRyb25nIGjhu5kiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAoVHlfbGUsICIlIikpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksDQogICAgICAgICAgICBzaXplID0gNCwgY29sb3IgPSAicGluayIpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksDQogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpDQogICkNCg0KDQpgYGANCg0KLSBjb29yZF9wb2xhcih0aGV0YSA9ICJ5IikgOiBDaHV54buDbiBiaeG7g3UgxJHhu5MgY+G7mXQgdGjDoG5oIGJp4buDdSDEkeG7kyB0csOybiBi4bqxbmcgY8OhY2ggc+G7rSBk4bulbmcgaOG7hyB04buNYSDEkeG7mSBj4buxYyAocG9sYXIgY29vcmRpbmF0ZSBzeXN0ZW0pLCB0cm9uZyDEkcOzIHBo4bqnbiB0csSDbSAoVHlfbGUpIMSRxrDhu6NjIHhvYXkgdGhlbyB0cuG7pWMgeSDEkeG7gyB04bqhbyByYSBjw6FjIHBo4bqnbiBow6xuaCBxdeG6oXQuDQoNCi0gc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikgOiDDgXAgZOG7pW5nIGLhuqNuZyBtw6B1ICJTZXQyIiB04burIHRoxrAgdmnhu4duIFJDb2xvckJyZXdlciDEkeG7gyBwaMOibiBiaeG7h3QgdHLhu7FjIHF1YW4gY8OhYyBwaOG6p24ga2jDoWMgbmhhdSBj4bunYSBiaeG7g3UgxJHhu5MgdHLDsm4gYuG6sW5nIGPDoWMgbcOgdSBz4bqvYyBow6BpIGjDsmEuDQoNCi0gdGhlbWVfdm9pZCgpIDogWMOzYSB04bqldCBj4bqjIHRow6BuaCBwaOG6p24gbuG7gW4gY+G7p2EgYmnhu4N1IMSR4buTICh0cuG7pWMsIGzGsOG7m2ksIG5ow6NuIHRy4bulYy4uLiksIGdpw7pwIGJp4buDdSDEkeG7kyB0csOybiB0csO0bmcgZ+G7jW4gZ8OgbmcgdsOgIG7hu5VpIGLhuq10IGjGoW4uDQoNCi0gbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpOiDhuqhuIHRpw6p1IMSR4buBIGPhu6dhIHBo4bqnbiBjaMO6IGdp4bqjaSAobGVnZW5kKSDEkeG7gyBnaWFvIGRp4buHbiBiaeG7g3UgxJHhu5MgdHLhu58gbsOqbiDEkcahbiBnaeG6o24gdsOgIGThu4UgxJHhu41jIGjGoW4uDQoNCg0KIyMjIE5o4bqtbiB4w6l0DQoNCi0gTmjDs20gIkh1c2JhbmQiIGNoaeG6v20gdOG7tyBs4buHIGNhbyBuaOG6pXQgduG7m2kgMzguMSUsIHBo4bqjbiDDoW5oIHZhaSB0csOyIHRy4bulIGPhu5l0IGPhu6dhIG5hbSBnaeG7m2kgdHJvbmcgaOG7mSBnaWEgxJHDrG5oIHbhuqtuIGPDsm4gcGjhu5UgYmnhur9uLiDEkGnhu4F1IG7DoHkgY8OzIHRo4buDIGxpw6puIHF1YW4gxJHhur9uIHRow7NpIHF1ZW4ga2hhaSBiw6FvIG5nxrDhu51pIMSR4bupbmcgxJHhuqd1IGjhu5kgbMOgIG5hbSBnaeG7m2kuDQoNCi0gIk5vdC1pbi1mYW1pbHkiIHjhur9wIHRo4bupIGhhaSB24bubaSAyNi40JSwgY2hvIHRo4bqleSBjw7Mgbmhp4buBdSBjw6EgbmjDom4gc+G7kW5nIMSR4buZYyBs4bqtcCBob+G6t2Mga2jDtG5nIHRodeG7mWMgaOG7mSB0cnV54buBbiB0aOG7kW5nIOKAkyBwaOG6o24gw6FuaCB4dSBoxrDhu5tuZyBz4buRbmcgxJHGoW4gdGjDom4gdHJvbmcgeMOjIGjhu5lpIGhp4buHbiDEkeG6oWkuDQoNCi0gIk93bi1jaGlsZCIgY2hp4bq/bSAxNS43JSwgY2hvIHRo4bqleSB04bu3IGzhu4cgbmfGsOG7nWkgcGjhu6UgdGh14buZYyDEkcOhbmcga+G7gyB0cm9uZyBo4buZLCB0cm9uZyBraGkgIldpZmUiIGNo4buJIMSR4bqhdCA3LjIlLCBjw7MgdGjhu4MgZG8gbmFtIGdp4bubaSBsw6AgbmfGsOG7nWkgxJHGsOG7o2Mga2jhuqNvIHPDoXQgbmhp4buBdSBoxqFuLg0KDQotIEPDoWMgbmjDs20gIlVubWFycmllZCIgKDExLjIlKSB2w6AgIk90aGVyLXJlbGF0aXZlIiAoMS40JSkgY8OzIHThu7cgbOG7hyB0aOG6pXAsIG5oxrBuZyBnw7NwIHBo4bqnbiBsw6BtIHLDtSB0w61uaCDEkWEgZOG6oW5nIHRyb25nIGPhuqV1IHRyw7pjIGjhu5kgZ2lhIMSRw6xuaCBoaeG7h24gbmF5Lg0KIyMgKipCaeG6v24gRXRobmljaXR5KioNCg0KIyMjIEdp4bqjaSB0aMOtY2ggYmnhur9uDQoNCmBgYHtyfQ0KIyBHaeG6o2kgdGjDrWNoIGPDoWMgbeG7qWMgY+G7p2EgYmnhur9uIEV0aG5pY2l0eQ0KRXRobmljaXR5X2xldmVscyA8LSBkYXRhLmZyYW1lKA0KICBHaWFfdHJpID0gYygiQW1lci1JbmRpYW4tRXNraW1vIiwgIkFzaWFuLVBhYy1Jc2xhbmRlciIsICJCbGFjayIsICJPdGhlciIsICJXaGl0ZSIpLA0KICBZX25naGlhID0gYygNCiAgICAiTmfGsOG7nWkgZGEgxJHhu48vVGjhu5UgZMOibiBC4bqvYyBN4bu5IiwNCiAgICAiTmfGsOG7nWkgY2jDonUgw4EgaG/hurdjIGTDom4gxJHhuqNvIFRow6FpIELDrG5oIETGsMahbmciLA0KICAgICJOZ8aw4budaSBkYSDEkWVuIiwNCiAgICAiS2jDoWMiLA0KICAgICJOZ8aw4budaSBkYSB0cuG6r25nIg0KICApDQopDQoNCmtuaXRyOjprYWJsZShFdGhuaWNpdHlfbGV2ZWxzLCBjYXB0aW9uID0gIkdp4bqjaSB0aMOtY2ggY8OhYyBt4bupYyB0cm9uZyBiaeG6v24gRXRobmljaXR5IikNCmBgYA0KDQoNCiMjIyBUaOG7kW5nIGvDqiBU4bqnbiBzdeG6pXQNCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgdOG6p24gc3XhuqV0IGNobyBFdGhuaWNpdHkNCnRzX0V0aG5pY2l0eSA8LSB0YWJsZShkJEV0aG5pY2l0eSkNCg0KIyBU4bqhbyBi4bqjbmcgZOG7ryBsaeG7h3UNCnRzX0V0aG5pY2l0eV9kZiA8LSBkYXRhLmZyYW1lKA0KICBHaWFfdHJpID0gbmFtZXModHNfRXRobmljaXR5KSwNCiAgVGFuX3NvID0gYXMudmVjdG9yKHRzX0V0aG5pY2l0eSksDQogIFR5X2xlID0gcm91bmQoKGFzLnZlY3Rvcih0c19FdGhuaWNpdHkpIC8gc3VtKHRzX0V0aG5pY2l0eSkpICogMTAwLCAyKQ0KKQ0KDQojIEhp4buDbiB0aOG7iyBr4bq/dCBxdeG6ow0KdHNfRXRobmljaXR5X2RmDQoNCmBgYA0KDQotIEJp4bq/biBgRXRobmljaXR5YCAoY2jhu6duZyB04buZYykgY8OzIDUgbmjDs20gbmjGsCBzYXU6DQoNCiAgLSAqKk5nxrDhu51pIGRhIMSR4buPL1Ro4buVIGTDom4gQuG6r2MgTeG7uSoqIChgQW1lci1JbmRpYW4tRXNraW1vYCk6IGByIHRzX0V0aG5pY2l0eV9kZiRUYW5fc29bdHNfRXRobmljaXR5X2RmJEdpYV90cmkgPT0gIkFtZXItSW5kaWFuLUVza2ltbyJdYCBuZ8aw4budaSAoY2hp4bq/bSBgciBwYXN0ZTAodHNfRXRobmljaXR5X2RmJFR5X2xlW3RzX0V0aG5pY2l0eV9kZiRHaWFfdHJpID09ICJBbWVyLUluZGlhbi1Fc2tpbW8iXSwgIiUiKWApLg0KDQotICoqTmfGsOG7nWkgY2jDonUgw4EvVGjDoWkgQsOsbmggRMawxqFuZyoqIChgQXNpYW4tUGFjLUlzbGFuZGVyYCk6IGByIHRzX0V0aG5pY2l0eV9kZiRUYW5fc29bdHNfRXRobmljaXR5X2RmJEdpYV90cmkgPT0gIkFzaWFuLVBhYy1Jc2xhbmRlciJdYCBuZ8aw4budaSAoY2hp4bq/bSBgciBwYXN0ZTAodHNfRXRobmljaXR5X2RmJFR5X2xlW3RzX0V0aG5pY2l0eV9kZiRHaWFfdHJpID09ICJBc2lhbi1QYWMtSXNsYW5kZXIiXSwgIiUiKWApLg0KDQotICoqTmfGsOG7nWkgZGEgxJFlbioqIChgQmxhY2tgKTogYHIgdHNfRXRobmljaXR5X2RmJFRhbl9zb1t0c19FdGhuaWNpdHlfZGYkR2lhX3RyaSA9PSAiQmxhY2siXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX0V0aG5pY2l0eV9kZiRUeV9sZVt0c19FdGhuaWNpdHlfZGYkR2lhX3RyaSA9PSAiQmxhY2siXSwgIiUiKWApLg0KDQotICoqS2jDoWMqKiAoYE90aGVyYCk6IGByIHRzX0V0aG5pY2l0eV9kZiRUYW5fc29bdHNfRXRobmljaXR5X2RmJEdpYV90cmkgPT0gIk90aGVyIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19FdGhuaWNpdHlfZGYkVHlfbGVbdHNfRXRobmljaXR5X2RmJEdpYV90cmkgPT0gIk90aGVyIl0sICIlIilgKS4NCg0KLSAqKk5nxrDhu51pIGRhIHRy4bqvbmcqKiAoYFdoaXRlYCk6IGByIHRzX0V0aG5pY2l0eV9kZiRUYW5fc29bdHNfRXRobmljaXR5X2RmJEdpYV90cmkgPT0gIldoaXRlIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19FdGhuaWNpdHlfZGYkVHlfbGVbdHNfRXRobmljaXR5X2RmJEdpYV90cmkgPT0gIldoaXRlIl0sICIlIilgKS4NCg0KDQojIyMgVHLhu7FjIHF1YW4gaMOzYQ0KYGBge3IgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTZ9DQpnZ3Bsb3QodHNfRXRobmljaXR5X2RmLCBhZXMoeCA9IHJlb3JkZXIoR2lhX3RyaSwgLVRhbl9zbyksIHkgPSBUYW5fc28sIGZpbGwgPSBHaWFfdHJpKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDAuNSwgY29sb3IgPSAibGlnaHRncmVlbiIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IFRhbl9zbyksIHZqdXN0ID0gLTAuMywgc2l6ZSA9IDQsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiQmnhu4N1IMSR4buTIGPhu5l0OiBDaOG7p25nIHThu5ljIChFdGhuaWNpdHkpIiwNCiAgICB4ID0gIkNo4bunbmcgdOG7mWMiLA0KICAgIHkgPSAiVOG6p24gc+G7kSINCiAgKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTMpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICANCiAgKQ0KDQoNCmBgYA0KDQpgYGB7ciBmaWcud2lkdGg9MTMsIGZpZy5oZWlnaHQ9OH0NCmdncGxvdCh0c19FdGhuaWNpdHlfZGYsIGFlcyh4ID0gcmVvcmRlcihHaWFfdHJpLCBUeV9sZSksIHkgPSBUeV9sZSwgZmlsbCA9IEdpYV90cmkpKSArDQogIGdlb21fY29sKHdpZHRoID0gMC42LCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChUeV9sZSwgIiUiKSksIA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCBzaXplID0gNCwgZm9udGZhY2UgPSAiYm9sZCIsIGNvbG9yID0gInB1cnBsZSIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJCaeG7g3UgxJHhu5MgY+G7mXQgbmdhbmc6IFThu7cgbOG7hyBjaOG7p25nIHThu5ljIChFdGhuaWNpdHkpIiwNCiAgICB4ID0gIkNo4bunbmcgdOG7mWMiLA0KICAgIHkgPSAiVOG7tyBs4buHICglKSINCiAgKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTMpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksDQogICAgDQogICkNCg0KDQpgYGANCg0KIyMjIE5o4bqtbiB4w6l0DQoNCi0gIldoaXRlIiBsw6AgbmjDs20gY2hp4bq/bSDEkWEgc+G7kSDDoXAgxJHhuqNvIHbhu5tpIDI3LjE5MSBuZ8aw4budaSAoODMuNTQlKSwgdGjhu4MgaGnhu4duIHPhu7EgdGjhu5FuZyB0cuG7iyB24buBIHPhu5EgbMaw4bujbmcgdHJvbmcgbeG6q3Uga2jhuqNvIHPDoXQuDQoNCi0gIkJsYWNrIiBjaGnhur9tIDIuODMwIG5nxrDhu51pICg4LjY5JSksIGzDoCBuaMOzbSB0aGnhu4N1IHPhu5EgbOG7m24gbmjhuqV0IHNhdSBuZ8aw4budaSBkYSB0cuG6r25nLg0KDQotIEPDoWMgbmjDs20gIkFzaWFuLVBhYy1Jc2xhbmRlciIsICJBbWVyLUluZGlhbi1Fc2tpbW8iLCB2w6AgIk90aGVyIiBs4bqnbiBsxrDhu6N0IGPDsyB04bu3IGzhu4cgdGjhuqVwIGjGoW4gbmhp4buBdSwgbeG7l2kgbmjDs20gZMaw4bubaSAzJSwgY2hvIHRo4bqleSB0w61uaCDEkWEgZOG6oW5nIGNo4bunbmcgdOG7mWMgY8OzIG5oxrBuZyBjaMawYSB0aOG6rXQgc+G7sSBjw6JuIGLhurFuZy4NCg0KIyMgKipCaeG6v24gTmF0aW9uYWxpdHkqKg0KDQojIyMgR2nhuqNpIHRow61jaCBiaeG6v24NCg0KYGBge3IgfQ0KIyBHaeG6o2kgdGjDrWNoIG3hu5l0IHPhu5EgbeG7qWMgcGjhu5UgYmnhur9uIHRyb25nIGJp4bq/biBOYXRpb25hbGl0eQ0KIyAoTuG6v3UgY+G6p24gZ2nhuqNpIHRow61jaCB0b8OgbiBi4buZIGPDsyB0aOG7gyBt4bufIHLhu5luZyB0aMOqbSkNCmNvdW50cnlfbGV2ZWxzIDwtIGRhdGEuZnJhbWUoDQogIEdpYV90cmkgPSBjKCJVbml0ZWQtU3RhdGVzIiwgIk1leGljbyIsICJQaGlsaXBwaW5lcyIsICJWaWV0bmFtIiwgIkdlcm1hbnkiKSwNCiAgWV9uZ2hpYSA9IGMoDQogICAgIkhvYSBL4buzIiwNCiAgICAiTWV4aWNvIiwNCiAgICAiUGhpbGlwcGluZXMiLA0KICAgICJWaeG7h3QgTmFtIiwNCiAgICAixJDhu6ljIg0KICApDQopDQoNCmtuaXRyOjprYWJsZShjb3VudHJ5X2xldmVscywgY2FwdGlvbiA9ICJHaeG6o2kgdGjDrWNoIG3hu5l0IHPhu5EgbeG7qWMgcGjhu5UgYmnhur9uIHRyb25nIGJp4bq/biBOYXRpb25hbGl0eSIpDQpgYGANCg0KIyMjIFRo4buRbmcga8OqIFThuqduIHN14bqldCANCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgdOG6p24gc3XhuqV0IGNobyBOYXRpb25hbGl0eQ0KdHNfY291bnRyeSA8LSB0YWJsZShkJE5hdGlvbmFsaXR5KQ0KDQojIFThuqFvIGLhuqNuZyBk4buvIGxp4buHdQ0KdHNfY291bnRyeV9kZiA8LSBkYXRhLmZyYW1lKA0KICBHaWFfdHJpID0gbmFtZXModHNfY291bnRyeSksDQogIFRhbl9zbyA9IGFzLnZlY3Rvcih0c19jb3VudHJ5KSwNCiAgVHlfbGUgPSByb3VuZCgoYXMudmVjdG9yKHRzX2NvdW50cnkpIC8gc3VtKHRzX2NvdW50cnkpKSAqIDEwMCwgMikNCikNCg0KIyBIaeG7g24gdGjhu4sga+G6v3QgcXXhuqMNCnRzX2NvdW50cnlfZGYNCg0KYGBgDQoNCi0gQmnhur9uIGBOYXRpb25hbGl0eWAgKHF14buRYyBnaWEgeHXhuqV0IHRow6JuKSBjw7Mgbmhp4buBdSBt4bupYywgZMaw4bubaSDEkcOieSBsw6AgbeG7mXQgc+G7kSBt4bupYyBwaOG7lSBiaeG6v246DQoNCiAtICoqSG9hIEvhu7MqKiAoYFVuaXRlZC1TdGF0ZXNgKTogYHIgdHNfY291bnRyeV9kZiRUYW5fc29bdHNfY291bnRyeV9kZiRHaWFfdHJpID09ICJVbml0ZWQtU3RhdGVzIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19jb3VudHJ5X2RmJFR5X2xlW3RzX2NvdW50cnlfZGYkR2lhX3RyaSA9PSAiVW5pdGVkLVN0YXRlcyJdLCAiJSIpYCkuDQoNCi0gKipNZXhpY28qKjogYHIgdHNfY291bnRyeV9kZiRUYW5fc29bdHNfY291bnRyeV9kZiRHaWFfdHJpID09ICJNZXhpY28iXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX2NvdW50cnlfZGYkVHlfbGVbdHNfY291bnRyeV9kZiRHaWFfdHJpID09ICJNZXhpY28iXSwgIiUiKWApLg0KDQotICoqUGhpbGlwcGluZXMqKjogYHIgdHNfY291bnRyeV9kZiRUYW5fc29bdHNfY291bnRyeV9kZiRHaWFfdHJpID09ICJQaGlsaXBwaW5lcyJdYCBuZ8aw4budaSAoY2hp4bq/bSBgciBwYXN0ZTAodHNfY291bnRyeV9kZiRUeV9sZVt0c19jb3VudHJ5X2RmJEdpYV90cmkgPT0gIlBoaWxpcHBpbmVzIl0sICIlIilgKS4NCg0KLSAqKlZp4buHdCBOYW0qKjogYHIgdHNfY291bnRyeV9kZiRUYW5fc29bdHNfY291bnRyeV9kZiRHaWFfdHJpID09ICJWaWV0bmFtIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19jb3VudHJ5X2RmJFR5X2xlW3RzX2NvdW50cnlfZGYkR2lhX3RyaSA9PSAiVmlldG5hbSJdLCAiJSIpYCkuDQoNCi0gKirEkOG7qWMqKiAoYEdlcm1hbnlgKTogYHIgdHNfY291bnRyeV9kZiRUYW5fc29bdHNfY291bnRyeV9kZiRHaWFfdHJpID09ICJHZXJtYW55Il1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19jb3VudHJ5X2RmJFR5X2xlW3RzX2NvdW50cnlfZGYkR2lhX3RyaSA9PSAiR2VybWFueSJdLCAiJSIpYCkuDQoNCg0KDQojIyMgVHLhu7FjIHF1YW4gaMOzYQ0KDQpgYGB7ciBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9Nn0NCmxpYnJhcnkoZHBseXIpDQoNCnRvcF9jb3VudHJ5IDwtIHRzX2NvdW50cnlfZGYgJT4lIA0KICBhcnJhbmdlKGRlc2MoVGFuX3NvKSkgJT4lIA0KICBzbGljZSgxOjEwKQ0KDQpnZ3Bsb3QodG9wX2NvdW50cnksIGFlcyh4ID0gcmVvcmRlcihHaWFfdHJpLCAtVGFuX3NvKSwgeSA9IFRhbl9zbywgZmlsbCA9IEdpYV90cmkpKSArDQogIGdlb21fY29sKHdpZHRoID0gMC41LCBjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBUYW5fc28pLCB2anVzdCA9IC0wLjMsIHNpemUgPSA0LCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkJp4buDdSDEkeG7kyBj4buZdDogMTAgcXXhu5FjIGdpYSBwaOG7lSBiaeG6v24gKE5hdGlvbmFsaXR5KSIsDQogICAgeCA9ICJRdeG7kWMgZ2lhIiwNCiAgICB5ID0gIlThuqduIHPhu5EiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEzKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksDQogICAgDQogICkNCg0KYGBgDQoNCmBgYHtyIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02fQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCg0KIyBM4bqleSB0b3AgMTAgcXXhu5FjIGdpYSBjw7MgdOG7tyBs4buHIGNhbyBuaOG6pXQNCnRvcF9jb3VudHJ5IDwtIHRzX2NvdW50cnlfZGYgJT4lIA0KICBhcnJhbmdlKGRlc2MoVHlfbGUpKSAlPiUgDQogIHNsaWNlKDE6MTApDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MNCmdncGxvdCh0b3BfY291bnRyeSwgYWVzKHggPSByZW9yZGVyKEdpYV90cmksIFR5X2xlKSwgeSA9IFR5X2xlLCBmaWxsID0gR2lhX3RyaSkpICsNCiAgZ2VvbV9jb2wod2lkdGggPSAwLjYsIGNvbG9yID0gImxpZ2h0cGluayIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChUeV9sZSwgIiUiKSksIGhqdXN0ID0gLTAuMSwgc2l6ZSA9IDQsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiQmnhu4N1IMSR4buTIGPhu5l0IG5nYW5nOiBU4bu3IGzhu4cgMTAgcXXhu5FjIGdpYSBwaOG7lSBiaeG6v24gbmjhuqV0IChOYXRpb25hbGl0eSkiLA0KICAgIHggPSAiUXXhu5FjIGdpYSIsDQogICAgeSA9ICJU4bu3IGzhu4cgKCUpIg0KICApICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMykgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKQ0KICApDQoNCmBgYA0KDQojIyMgTmjhuq1uIHjDqXQNCg0KLSAiVW5pdGVkLVN0YXRlcyIgY2hp4bq/bSDDoXAgxJHhuqNvIHbhu5tpIDg5LjU5JSwgY2hvIHRo4bqleSBwaOG6p24gbOG7m24gxJHhu5FpIHTGsOG7o25nIGto4bqjbyBzw6F0IHPhu5FuZyB04bqhaSBob+G6t2MgeHXhuqV0IHRow6JuIHThu6sgSG9hIEvhu7Mg4oCTIHBow7kgaOG7o3AgduG7m2kgdmnhu4djIGThu68gbGnhu4d1IG7DoHkgxJHGsOG7o2MgdGh1IHRo4bqtcCB04burIGjhu4cgdGjhu5FuZyB0aOG7kW5nIGvDqiBkw6JuIHPhu5EgTeG7uS4NCg0KLSAiTWV4aWNvIiDEkeG7qW5nIHRo4bupIGhhaSB24bubaSAxLjk3JSwgbMOgIHF14buRYyBnaWEgZ+G7kWMgcGjhu5UgYmnhur9uIHRp4bq/cCB0aGVvLCBwaOG6o24gw6FuaCBz4buxIGhp4buHbiBkaeG7h24gxJHDoW5nIGvhu4MgY+G7p2EgbmfGsOG7nWkgbmjhuq1wIGPGsCB04burIE1leGljby4NCg0KLSAiUGhpbGlwcGluZXMiIHbDoCAiR2VybWFueSIgbOG6p24gbMaw4bujdCBjaGnhur9tIDAuNjElIHbDoCAwLjQyJSwgbMOgIGPDoWMgcXXhu5FjIGdpYSBn4buRYyDDrXQgcGjhu5UgYmnhur9uIGjGoW4uDQoNCi0gxJDhurdjIGJp4buHdCwgY8OzIHThu5tpIDEuNzklIGdpw6EgdHLhu4sgbMOgIGThuqV1IGjhu49pICI/IiDigJMgbmhp4buBdSBraOG6oyBuxINuZyBsw6AgZOG7ryBsaeG7h3UgdGhp4bq/dSBob+G6t2Mga2jDtG5nIHjDoWMgxJHhu4tuaC4NCg0KIyMgKipCaeG6v24gR2VuZGVyKioNCg0KIyMjIEdp4bqjaSB0aMOtY2ggYmnhur9uDQoNCmBgYHtyfQ0KIyBHaeG6o2kgdGjDrWNoIGPDoWMgbeG7qWMgY+G7p2EgYmnhur9uIEdlbmRlcg0KR2VuZGVyX2xldmVscyA8LSBkYXRhLmZyYW1lKA0KICBHaWFfdHJpID0gYygiRmVtYWxlIiwgIk1hbGUiKSwNCiAgWV9uZ2hpYSA9IGMoIk7hu68iLCAiTmFtIikNCikNCg0Ka25pdHI6OmthYmxlKEdlbmRlcl9sZXZlbHMsIGNhcHRpb24gPSAiR2nhuqNpIHRow61jaCBjw6FjIG3hu6ljIHRyb25nIGJp4bq/biBHZW5kZXIiKQ0KYGBgDQoNCiMjIyBUaOG7kW5nIGvDqiBU4bqnbiBzdeG6pXQNCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgdOG6p24gc3XhuqV0IGNobyBHZW5kZXINCnRzX0dlbmRlciA8LSB0YWJsZShkJEdlbmRlcikNCg0KIyBU4bqhbyBi4bqjbmcgZOG7ryBsaeG7h3UNCnRzX0dlbmRlcl9kZiA8LSBkYXRhLmZyYW1lKA0KICBHaWFfdHJpID0gbmFtZXModHNfR2VuZGVyKSwNCiAgWV9uZ2hpYSA9IGMoIk5hbSIsICJO4buvIiksICAjIE1hbGUsIEZlbWFsZQ0KICBUYW5fc28gPSBhcy52ZWN0b3IodHNfR2VuZGVyKSwNCiAgVHlfbGUgPSByb3VuZCgoYXMudmVjdG9yKHRzX0dlbmRlcikgLyBzdW0odHNfR2VuZGVyKSkgKiAxMDAsIDIpDQopDQoNCiMgSGnhu4NuIHRo4buLIGvhur90IHF14bqjDQp0c19HZW5kZXJfZGYNCg0KYGBgDQoNCg0KLSBCaeG6v24gYEdlbmRlcmAgKGdp4bubaSB0w61uaCkgYmFvIGfhu5NtIDIgbeG7qWM6DQoNCiAgLSAqKk7hu68qKiAoYEZlbWFsZWApOiBgciB0c19HZW5kZXJfZGYkVGFuX3NvW3RzX0dlbmRlcl9kZiRHaWFfdHJpID09ICJGZW1hbGUiXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX0dlbmRlcl9kZiRUeV9sZVt0c19HZW5kZXJfZGYkR2lhX3RyaSA9PSAiRmVtYWxlIl0sICIlIilgKS4NCg0KLSAqKk5hbSoqIChgTWFsZWApOiBgciB0c19HZW5kZXJfZGYkVGFuX3NvW3RzX0dlbmRlcl9kZiRHaWFfdHJpID09ICJNYWxlIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19HZW5kZXJfZGYkVHlfbGVbdHNfR2VuZGVyX2RmJEdpYV90cmkgPT0gIk1hbGUiXSwgIiUiKWApLg0KDQoNCiMjIyBUcuG7sWMgcXVhbiBow7NhDQoNCmBgYHtyIGZpZy53aWR0aD0xMn0NCmdncGxvdCh0c19HZW5kZXJfZGYsIGFlcyh4ID0gR2lhX3RyaSwgeSA9IFRhbl9zbywgZmlsbCA9IEdpYV90cmkpKSArDQogIGdlb21fY29sKHdpZHRoID0gMC41LCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IFRhbl9zbyksIHZqdXN0ID0gLTAuMywgc2l6ZSA9IDQsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiQmnhu4N1IMSR4buTIGPhu5l0OiBHaeG7m2kgdMOtbmggKEdlbmRlcikiLA0KICAgIHggPSAiR2nhu5tpIHTDrW5oIiwNCiAgICB5ID0gIlThuqduIHPhu5EiDQogICkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQiLCAic2t5Ymx1ZSIpKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTMpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksDQogIA0KICApDQoNCmBgYA0KDQpgYGB7ciBmaWcud2lkdGg9MTJ9DQpHZW5kZXJfY29sb3JzIDwtIGMoIkZlbWFsZSIgPSAiI0ZGQjZDMSIsICJNYWxlIiA9ICIjODdDRUZBIikgICMgbcOgdSB0deG7syBjaOG7iW5oDQoNCmdncGxvdCh0c19HZW5kZXJfZGYsIGFlcyh4ID0gIiIsIHkgPSBUeV9sZSwgZmlsbCA9IEdpYV90cmkpKSArDQogIGdlb21fY29sKHdpZHRoID0gMSwgY29sb3IgPSAicmVkIikgKw0KICBjb29yZF9wb2xhcih0aGV0YSA9ICJ5IikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBHZW5kZXJfY29sb3JzKSArDQogIGxhYnModGl0bGUgPSAiQmnhu4N1IMSR4buTIHRyw7JuOiBHaeG7m2kgdMOtbmgiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAoVHlfbGUsICIlIikpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksDQogICAgICAgICAgICBzaXplID0gNSwgY29sb3IgPSAiYmx1ZSIpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksDQogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpDQogICkNCg0KYGBgDQoNCg0KIyMgKipCaeG6v24gRWFybmluZ0NsYXNzKioNCg0KIyMjIEdp4bqjaSB0aMOtY2ggYmnhur9uDQoNCmBgYHtyfQ0KIyBHaeG6o2kgdGjDrWNoIGPDoWMgbeG7qWMgY+G7p2EgYmnhur9uIEVhcm5pbmdDbGFzcw0KRWFybmluZ0NsYXNzX2xldmVscyA8LSBkYXRhLmZyYW1lKA0KICBHaWFfdHJpID0gYygiPD01MEsiLCAiPjUwSyIpLA0KICBZX25naGlhID0gYygiVGh1IG5o4bqtcCBkxrDhu5tpIGhv4bq3YyBi4bqxbmcgNTAuMDAwIFVTRC9uxINtIiwgIlRodSBuaOG6rXAgdHLDqm4gNTAuMDAwIFVTRC9uxINtIikNCikNCg0Ka25pdHI6OmthYmxlKEVhcm5pbmdDbGFzc19sZXZlbHMsIGNhcHRpb24gPSAiR2nhuqNpIHRow61jaCBjw6FjIG3hu6ljIHRyb25nIGJp4bq/biBFYXJuaW5nQ2xhc3MiKQ0KYGBgDQoNCiMjIyBUaOG7kW5nIGvDqiBU4bqnbiBzdeG6pXQNCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgdOG6p24gc3XhuqV0IGNobyBFYXJuaW5nQ2xhc3MNCnRzX0Vhcm5pbmdDbGFzcyA8LSB0YWJsZShkJEVhcm5pbmdDbGFzcykNCg0KIyBU4bqhbyBi4bqjbmcgZOG7ryBsaeG7h3UNCnRzX0Vhcm5pbmdDbGFzc19kZiA8LSBkYXRhLmZyYW1lKA0KICBHaWFfdHJpID0gbmFtZXModHNfRWFybmluZ0NsYXNzKSwNCiAgWV9uZ2hpYSA9IGMoIuKJpDUwSyIsICI+NTBLIiksDQogIFRhbl9zbyA9IGFzLnZlY3Rvcih0c19FYXJuaW5nQ2xhc3MpLA0KICBUeV9sZSA9IHJvdW5kKChhcy52ZWN0b3IodHNfRWFybmluZ0NsYXNzKSAvIHN1bSh0c19FYXJuaW5nQ2xhc3MpKSAqIDEwMCwgMikNCikNCg0KIyBIaeG7g24gdGjhu4sga+G6v3QgcXXhuqMNCnRzX0Vhcm5pbmdDbGFzc19kZg0KDQpgYGANCg0KLSBCaeG6v24gYEVhcm5pbmdDbGFzc2AgKHRodSBuaOG6rXApIGPDsyAyIG3hu6ljOg0KDQogIC0gKipUaHUgbmjhuq1wIGTGsOG7m2kgaG/hurdjIGLhurFuZyA1MEsqKiAoYDw9NTBLYCk6IGByIHRzX0Vhcm5pbmdDbGFzc19kZiRUYW5fc29bdHNfRWFybmluZ0NsYXNzX2RmJEdpYV90cmkgPT0gIjw9NTBLIl1gIG5nxrDhu51pIChjaGnhur9tIGByIHBhc3RlMCh0c19FYXJuaW5nQ2xhc3NfZGYkVHlfbGVbdHNfRWFybmluZ0NsYXNzX2RmJEdpYV90cmkgPT0gIjw9NTBLIl0sICIlIilgKS4NCg0KLSAqKlRodSBuaOG6rXAgdHLDqm4gNTBLKiogKGA+NTBLYCk6IGByIHRzX0Vhcm5pbmdDbGFzc19kZiRUYW5fc29bdHNfRWFybmluZ0NsYXNzX2RmJEdpYV90cmkgPT0gIj41MEsiXWAgbmfGsOG7nWkgKGNoaeG6v20gYHIgcGFzdGUwKHRzX0Vhcm5pbmdDbGFzc19kZiRUeV9sZVt0c19FYXJuaW5nQ2xhc3NfZGYkR2lhX3RyaSA9PSAiPjUwSyJdLCAiJSIpYCkuDQoNCg0KIyMjIFRy4buxYyBxdWFuIGjDs2ENCmBgYHtyfQ0KZ2dwbG90KHRzX0Vhcm5pbmdDbGFzc19kZiwgYWVzKHggPSBHaWFfdHJpLCB5ID0gVGFuX3NvLCBmaWxsID0gR2lhX3RyaSkpICsNCiAgZ2VvbV9jb2wod2lkdGggPSAwLjUsIGNvbG9yID0gIndoaXRlIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gVGFuX3NvKSwgdmp1c3QgPSAtMC4zLCBzaXplID0gNCwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJCaeG7g3UgxJHhu5MgY+G7mXQ6IFRodSBuaOG6rXAgKEVhcm5pbmdDbGFzcykiLA0KICAgIHggPSAiTmjDs20gdGh1IG5o4bqtcCIsDQogICAgeSA9ICJU4bqnbiBz4buRIg0KICApICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzZENTk3QSIsICIjRkZCNzAzIikpICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMykgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwNCiAgICANCiAgKQ0KDQpgYGANCg0KYGBge3J9DQpFYXJuaW5nQ2xhc3NfY29sb3JzIDwtIGMoIjw9NTBLIiA9ICIjRkRCODYzIiwgIj41MEsiID0gIiM1RTNDOTkiKQ0KDQpnZ3Bsb3QodHNfRWFybmluZ0NsYXNzX2RmLCBhZXMoeCA9ICIiLCB5ID0gVHlfbGUsIGZpbGwgPSBHaWFfdHJpKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDEsIGNvbG9yID0gIndoaXRlIikgKw0KICBjb29yZF9wb2xhcih0aGV0YSA9ICJ5IikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBFYXJuaW5nQ2xhc3NfY29sb3JzKSArDQogIGxhYnModGl0bGUgPSAiQmnhu4N1IMSR4buTIHRyw7JuOiBUaHUgbmjhuq1wIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKFR5X2xlLCAiJSIpKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgc2l6ZSA9IDUsIGNvbG9yID0gImJsYWNrIikgKw0KICB0aGVtZV92b2lkKCkgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkNCiAgKQ0KYGBgDQoNCg0KIyDGr+G7m2MgbMaw4bujbmcgS2hv4bqjbmcgdsOgIEtp4buDbSDEkeG7i25oIEdp4bqjIHRodXnhur90IGNobyBU4bu3IGzhu4cNCg0KIyMgIFjDoWMgxJHhu4tuaCBI4bqhbmcgbeG7pWMgUXVhbiB0w6JtDQoNClRhIGNo4buNbiAzIGjhuqFuZyBt4bulYyB04burIDMgYmnhur9uIHRyb25nIGRhbmggc8OhY2ggY8OhYyBiaeG6v24gxJHhu4tuaCB0w61uaCwgYmFvIGfhu5NtOg0KDQotIEjhuqFuZyBt4bulYyDigJxOZXZlci1tYXJyaWVk4oCdIGPhu6dhIGJp4bq/biBQYXJ0bmVyaW5nU3RhdGUg4oCTIFTDrG5oIHRy4bqhbmcgaMO0biBuaMOibg0KDQotIEjhuqFuZyBt4bulYyDigJxNYWxl4oCdIGPhu6dhIGJp4bq/biBHZW5kZXIg4oCTIEdp4bubaSB0w61uaA0KDQotIEjhuqFuZyBt4bulYyDigJxCYWNoZWxvcnPigJ0gY+G7p2EgYmnhur9uIGxlYXJuaW5nTGV2ZWwg4oCTIFRyw6xuaCDEkeG7mSBo4buNYyB24bqlbg0KDQojIyAgxq/hu5tjIGzGsOG7o25nIEtob+G6o25nIFRpbiBj4bqteSB2w6AgS2nhu4NtIMSR4buLbmggR2nhuqMgdGh1eeG6v3QNCg0KKirGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIChQcm9wb3J0aW9uIEVzdGltYXRpb24pKioNCg0Kxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBsw6AgcXXDoSB0csOsbmggc+G7rSBk4bulbmcgZOG7ryBsaeG7h3UgdOG7qyBt4buZdCBt4bqrdSDEkeG7gyBzdXkgbHXhuq1uIHbhu4EgdOG7tyBs4buHIHTGsMahbmcg4bupbmcgdHJvbmcgdOG7lW5nIHRo4buDLiBUcm9uZyB0aOG7kW5nIGvDqiBtw7QgdOG6oywgdOG7tyBs4buHIG3huqt1IChrw70gaGnhu4d1IHRoxrDhu51uZyBsw6AgcMyCKSDEkcaw4bujYyB0w61uaCBi4bqxbmcgc+G7kSBsxrDhu6NuZyBjw6FjIHBo4bqnbiB04butIHRo4buPYSDEkWnhu4F1IGtp4buHbiBjaGlhIGNobyB04buVbmcgc+G7kSBwaOG6p24gdOG7rSB0cm9uZyBt4bqrdS4gxJDDonkgxJHGsOG7o2MgZ+G7jWkgbMOgIMaw4bubYyBsxrDhu6NuZyDEkWnhu4NtIChwb2ludCBlc3RpbWF0ZSkgY2hvIHThu7cgbOG7hyB04buVbmcgdGjhu4MgcC4gVHV5IG5oacOqbiwgZG8gdMOtbmggbmfhuqt1IG5oacOqbiBj4bunYSB2aeG7h2MgY2jhu41uIG3huqt1LCDGsOG7m2MgbMaw4bujbmcgxJFp4buDbSBraMO0bmcgdGjhu4MgxJHhuqNtIGLhuqNvIHBo4bqjbiDDoW5oIGNow61uaCB4w6FjIHThu7cgbOG7hyB0aOG7sWMgc+G7sSB0cm9uZyB04buVbmcgdGjhu4MsIGRvIMSRw7MgY+G6p24gxJFpIGvDqG0gduG7m2kgbeG7mXQga2hv4bqjbmcgdGluIGPhuq15IMSR4buDIMSRbyBsxrDhu51uZyDEkeG7mSBi4bqldCDEkeG7i25oLg0KDQoqKktob+G6o25nIHRpbiBj4bqteSoqDQoNCktob+G6o25nIHRpbiBj4bqteSBsw6AgbeG7mXQga2hv4bqjbmcgZ2nDoSB0cuG7iyBjaG8gdGEgYmnhur90IGdpw6EgdHLhu4sgdGjhuq10IGPhu6dhIG3hu5l0IHThu7cgbOG7hyBoYXkgdHJ1bmcgYsOsbmggdHJvbmcgdOG7lW5nIHRo4buDIGPDsyBraOG6oyBuxINuZyBu4bqxbSB0cm9uZyBraG/huqNuZyDEkcOzLiBOw7MgxJHGsOG7o2MgdMOtbmggdOG7qyBk4buvIGxp4buHdSBt4bqrdSwgdsOgIMSRaSBrw6htIHbhu5tpIG3hu5l0IG3hu6ljIMSR4buZIHRpbiB0xrDhu59uZyDigJMgdGjGsOG7nW5nIGzDoCA5NSUuDQoNCioqTeG7qWMgw70gbmdoxKlhIChTaWduaWZpY2FuY2UgTGV2ZWwg4oCTIM6xKSoqDQoNCk3hu6ljIMO9IG5naMSpYSwga8O9IGhp4buHdSBsw6AgzrEgKGFscGhhKSwgbMOgIHjDoWMgc3XhuqV0IGNo4bqlcCBuaOG6rW4gc2FpIGzhuqdtIGxv4bqhaSBJIOKAkyB04bupYyBsw6AgeMOhYyBzdeG6pXQgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IGtow7RuZyAoSOKCgCkga2hpIG7DsyB0aOG7sWMgc+G7sSDEkcO6bmcuIFRyb25nIGtp4buDbSDEkeG7i25oIGdp4bqjIHRodXnhur90IHRo4buRbmcga8OqLCBt4bupYyDDvSBuZ2jEqWEgdGjhu4MgaGnhu4duIG5nxrDhu6FuZyBtw6AgdOG6oWkgxJHDsyB0YSBxdXnhur90IMSR4buLbmggY8OzIGLDoWMgYuG7jyBI4oKAIGhheSBraMO0bmcuIE3hu6ljIMO9IG5naMSpYSBwaOG7lSBiaeG6v24gbmjhuqV0IGzDoCDOsSA9IDAuMDUsIG5naMSpYSBsw6AgdGEgY2jhuqVwIG5o4bqtbiA1JSBy4bunaSBybyBjaG8gdmnhu4djIGvhur90IGx14bqtbiBzYWkuIEvhur90IHF14bqjIGtp4buDbSDEkeG7i25oIHRoxrDhu51uZyDEkcaw4bujYyDEkcOhbmggZ2nDoSB0aMO0bmcgcXVhIHAtdmFsdWUsIHbDoCBzbyBzw6FuaCB24bubaSDOsSDEkeG7gyDEkcawYSByYSBxdXnhur90IMSR4buLbmg6DQoNCk7hur91IHAtdmFsdWUgPCDOsSDihpIgYsOhYyBi4buPIEjigoAgKGPDsyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqikuDQoNCk7hur91IHAtdmFsdWUg4omlIM6xIOKGkiBraMO0bmcgYsOhYyBi4buPIEjigoAgKGtow7RuZyDEkeG7pyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqikuDQoNCiMjIyAgSOG6oW5nIG3hu6VjIOKAnEJhY2hlbG9yc+KAnSBj4bunYSBiaeG6v24gVHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIChsZWFybmluZ0xldmVsKQ0KDQpUYSB0aOG7sWMgaGnhu4duIGtob+G6o25nIMaw4bubYyBsxrDhu6NuZyB24bubaSDEkeG7mSB0aW4gY+G6rXkgOTUlIGNobyB04bu3IGzhu4cgbmfGsOG7nWkgY8OzIGLhurFuZyBj4butIG5ow6JuIChCYWNoZWxvcnMpLCB0YSB0aOG7sWMgaGnhu4duIG5oxrAgc2F1Og0KDQpgYGB7cn0NCiMgU+G7kSBuZ8aw4budaSBjw7MgdHLDrG5oIMSR4buZIEJhY2hlbG9ycw0Kbl9iYWNoZWxvcnMgPC0gc3VtKGQkbGVhcm5pbmdMZXZlbCA9PSAiQmFjaGVsb3JzIikNCg0KIyBU4buVbmcgc+G7kSBxdWFuIHPDoXQNCm5fdG90YWwgPC0gbnJvdyhkKQ0KDQojIMav4bubYyBsxrDhu6NuZyBraG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyB04bu3IGzhu4cgbmfGsOG7nWkgY8OzIHRyw6xuaCDEkeG7mSBCYWNoZWxvcnMNCnByb3AudGVzdChuX2JhY2hlbG9ycywgbl90b3RhbCwgY29uZi5sZXZlbCA9IDAuOTUpDQoNCg0KYGBgDQoNCi0gbl9iYWNoZWxvcnMgPC0gc3VtKGQkbGVhcm5pbmdMZXZlbCA9PSAiQmFjaGVsb3JzIik6DQpUw61uaCB04buVbmcgc+G7kSBuZ8aw4budaSBjw7MgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIGzDoCAiQmFjaGVsb3JzIiAoY+G7rSBuaMOibikgdHJvbmcgZOG7ryBsaeG7h3UgZCwgYuG6sW5nIGPDoWNoIMSR4bq/bSBz4buRIGTDsm5nIGPDsyBnacOhIHRy4buLICJCYWNoZWxvcnMiIHRyb25nIGJp4bq/biBsZWFybmluZ0xldmVsLg0KDQotIG5fdG90YWwgPC0gbnJvdyhkKToNCkzhuqV5IHThu5VuZyBz4buRIHF1YW4gc8OhdCB0cm9uZyBi4buZIGThu68gbGnhu4d1IGQsIHThu6ljIGzDoCBz4buRIGjDoG5nIGPhu6dhIGLhuqNuZyBk4buvIGxp4buHdSDigJMgZMO5bmcgxJHhu4MgbMOgbSBt4bqrdSBz4buRIHRyb25nIHTDrW5oIHRvw6FuIHThu7cgbOG7hy4NCg0KLSBwcm9wLnRlc3Qobl9iYWNoZWxvcnMsIG5fdG90YWwsIGNvbmYubGV2ZWwgPSAwLjk1KToNClRo4buxYyBoaeG7h24gcGjDqXAgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteSBjaG8gdOG7tyBs4buHIG5nxrDhu51pIGPDsyB0csOsbmggxJHhu5kgY+G7rSBuaMOibiwgduG7m2kgxJHhu5kgdGluIGPhuq15IDk1JS4gSMOgbSBwcm9wLnRlc3QoKSB0cuG6oyB24buBIGtob+G6o25nIHRpbiBj4bqteSB2w6Aga2nhu4NtIMSR4buLbmggZ2nhuqMgdGh1eeG6v3QgdOG7tyBs4buHIChu4bq/dSBj4bqnbikuDQoNCipQaMOibiB0w61jaCBr4bq/dCBxdeG6oyoNCg0KUGjDqXAga2nhu4NtIMSR4buLbmggxJHGsOG7o2MgdGjhu7FjIGhp4buHbiBsw6Aga2nhu4NtIMSR4buLbmggdOG7tyBs4buHIG3hu5l0IG3huqt1ICgxLXNhbXBsZSBwcm9wb3J0aW9uIHRlc3QpIHbhu5tpIGNo4buJbmggbGnDqm4gdOG7pWMgKGNvbnRpbnVpdHkgY29ycmVjdGlvbikg4oCTIGdpw7pwIGPhuqNpIHRoaeG7h24gxJHhu5kgY2jDrW5oIHjDoWMga2hpIHPhu60gZOG7pW5nIHBow6JuIHBo4buRaSB44bqlcCB44buJIGtoaSBrw61jaCB0aMaw4bubYyBt4bqrdSBraMO0bmcgaG/DoG4gdG/DoG4gbOG7m24uDQoNCkThu68gbGnhu4d1IMSR4bqndSB2w6BvIGfhu5NtIHPhu5EgbmfGsOG7nWkgY8OzIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiBsw6Ag4oCcQmFjaGVsb3Jz4oCdIChuX2JhY2hlbG9ycykgdHJvbmcgdOG7lW5nIHPhu5EgcXVhbiBzw6F0IChuX3RvdGFsKS4gR2nhuqMgdGh1eeG6v3Qga2jDtG5nIChI4oKAKSDEkeG6t3QgcmEgcuG6sW5nIHThu7cgbOG7hyB0aOG7sWMgc+G7sSBwID0gMC41LCB04bupYyBsw6AgNTAlIGTDom4gc+G7kSBjw7MgYuG6sW5nIGPhu60gbmjDom4uDQoNCkdpw6EgdHLhu4sgdGjhu5FuZyBrw6oga2nhu4NtIMSR4buLbmggbMOgIFgtc3F1YXJlZCA9IDExNDM2LCB24bubaSAxIGLhuq1jIHThu7EgZG8gKGRmID0gMSkuIEdpw6EgdHLhu4sgbsOgeSBy4bqldCBs4bubbiwgY2hvIHRo4bqleSB04bu3IGzhu4cgbeG6q3UgcXVhbiBzw6F0IMSRxrDhu6NjIGtow6FjIGJp4buHdCDEkcOhbmcga+G7gyBzbyB24bubaSB04bu3IGzhu4cgZ2nhuqMgxJHhu4tuaCA1MCUuDQoNCkdpw6EgdHLhu4sgcC12YWx1ZSA8IDIuMmUtMTYsIG5naMSpYSBsw6AgeMOhYyBzdeG6pXQgeOG6o3kgcmEgY2jDqm5oIGzhu4djaCBs4bubbiBuaMawIHbhuq15IG7hur91IEjigoAgxJHDum5nIGzDoCBn4bqnbiBuaMawIGLhurFuZyAwLiBEbyDEkcOzLCBr4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIHLhuqV0IG3huqFuaC4NCg0KR2nhuqMgdGh1eeG6v3QgxJHhu5FpIEjigoEgbMOgOiB04bu3IGzhu4cgdGjhu7FjIHThur8gcCDiiaAgMC41LCB04bupYyBsw6AgxJHDonkgbMOgIG3hu5l0IGtp4buDbSDEkeG7i25oIGhhaSBwaMOtYSBuaOG6sW0ga2nhu4NtIHRyYSB4ZW0gdOG7tyBs4buHIGPDsyBraMOhYyBiaeG7h3QgcsO1IHLhu4d0IHNvIHbhu5tpIDUwJSAoY8OzIHRo4buDIGNhbyBoxqFuIGhv4bq3YyB0aOG6pXAgaMahbikuDQoNCktob+G6o25nIHRpbiBj4bqteSA5NSUgY2hvIHThu7cgbOG7hyBuZ8aw4budaSBjw7MgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIEJhY2hlbG9ycyBsw6AgdOG7qyBbMC4xNjM4OyAwLjE3MzBdIOKAkyB04bupYyBraG/huqNuZyAxNi4zOCUgxJHhur9uIDE3LjMwJS4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgdGEgY8OzIHRo4buDIHRpbiB0xrDhu59uZyBy4bqxbmcgdOG7tyBs4buHIHRo4buxYyBz4buxIHRyb25nIHThu5VuZyB0aOG7gyBu4bqxbSB0cm9uZyBraG/huqNuZyBuw6B5Lg0KDQpU4bu3IGzhu4cgbeG6q3UgxrDhu5tjIGzGsOG7o25nIMSRxrDhu6NjIGzDoCBraG/huqNuZyAxNi44NCUsIHTGsMahbmcgxJHGsMahbmcgduG7m2kgZ+G6p24gMTcgbmfGsOG7nWkgY8OzIGLhurFuZyBj4butIG5ow6JuIHRyw6puIG3hu5dpIDEwMCBuZ8aw4budaSwgdGjhuqVwIGjGoW4gcuG6pXQgbmhp4buBdSBzbyB24bubaSBt4bupYyBnaeG6oyDEkeG7i25oIDUwJS4NCg0KDQoNCg0KKipCw6BpIHRvw6FuIGtp4buDbSDEkeG7i25oOioqDQoNCkdp4bqjIHRodXnhur90IGtp4buDbSDEkeG7i25oOg0KDQpHaeG6oyB0aHV54bq/dCBraMO0bmcgSOKCgDogcCA9IDAuNSAodOG7tyBs4buHIG5nxrDhu51pIGPDsyBi4bqxbmcgY+G7rSBuaMOibiBi4bqxbmcgNTAlKQ0KDQpHaeG6oyB0aHV54bq/dCDEkeG7kWkgSOKCgTogcCDiiaAgMC41ICh04bu3IGzhu4cgbmfGsOG7nWkgY8OzIGLhurFuZyBj4butIG5ow6JuIGtow6FjIDUwJSkNCg0KTeG7qWMgw70gbmdoxKlhOiDOsSA9IDAuMDUNCg0KS+G6v3QgbHXhuq1uOg0KDQpW4bubaSBwLXZhbHVlIDwgMi4yZS0xNiA8IDAuMDUsIHRhIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKALg0K4oaSIEPDsyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiBjaG8gdGjhuqV5IHThu7cgbOG7hyBuZ8aw4budaSBjw7MgYuG6sW5nIGPhu60gbmjDom4ga2jDoWMgNTAlLCB24bubaSDEkeG7mSB0aW4gY+G6rXkgOTUlLg0KDQpU4bu3IGzhu4cgbeG6q3UgbMOgIDE2Ljg0JSwgduG7m2kga2hv4bqjbmcgdGluIGPhuq15IG7hurFtIHRyb25nIFsxNi4zOCU7IDE3LjMwJV0uDQrihpIgTeG7qWMgY2jDqm5oIGzhu4djaCBoxqFuIDMzIMSRaeG7g20gcGjhuqduIHRyxINtIHNvIHbhu5tpIGdp4bqjIMSR4buLbmggNTAlIGNobyB0aOG6pXkgc+G7sSBraMOhYyBiaeG7h3QgbMOgIHLDtSByw6BuZyB2w6AgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqi4NCg0KIyMjIEjhuqFuZyBt4bulYyDigJxOZXZlci1tYXJyaWVk4oCdIGPhu6dhIGJp4bq/biBUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gKFBhcnRuZXJpbmdTdGF0ZSkgDQoNCmBgYHtyfQ0KIyBT4buRIG5nxrDhu51pIGNoxrBhIHThu6tuZyBr4bq/dCBow7RuDQpuX25ldmVyX21hcnJpZWQgPC0gc3VtKGQkUGFydG5lcmluZ1N0YXRlID09ICJOZXZlci1tYXJyaWVkIikNCg0KIyBU4buVbmcgc+G7kSBxdWFuIHPDoXQNCm5fdG90YWwgPC0gbnJvdyhkKQ0KDQojIMav4bubYyBsxrDhu6NuZyBraG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyB04bu3IGzhu4cgbmfGsOG7nWkgY2jGsGEgdOG7q25nIGvhur90IGjDtG4NCnByb3AudGVzdChuX25ldmVyX21hcnJpZWQsIG5fdG90YWwsIGNvbmYubGV2ZWwgPSAwLjk1KQ0KDQpgYGANClBow6lwIGtp4buDbSDEkeG7i25oIMSRxrDhu6NjIHPhu60gZOG7pW5nIGzDoCBraeG7g20gxJHhu4tuaCB04bu3IGzhu4cgbeG7mXQgbeG6q3UgKDEtc2FtcGxlIHByb3BvcnRpb25zIHRlc3QpIHbhu5tpIGNo4buJbmggbGnDqm4gdOG7pWMgKGNvbnRpbnVpdHkgY29ycmVjdGlvbikg4oCTIG5o4bqxbSBj4bqjaSB0aGnhu4duIMSR4buZIGNow61uaCB4w6FjIGtoaSBz4butIGThu6VuZyBwaMOibiBwaOG7kWkgeOG6pXAgeOG7iSB0cm9uZyB0aOG7kW5nIGvDqi4NCg0KROG7ryBsaeG7h3UgxJHhuqd1IHbDoG86IMSRYW5nIGtp4buDbSDEkeG7i25oIHThu7cgbOG7hyBuZ8aw4budaSBjw7MgdMOsbmggdHLhuqFuZyDigJxOZXZlci1tYXJyaWVk4oCdIChuX25ldmVyX21hcnJpZWQpIHRyb25nIHThu5VuZyBz4buRIHF1YW4gc8OhdCAobl90b3RhbCksIHbhu5tpIGdp4bqjIHRodXnhur90IGfhu5FjIEjigoA6IHAgPSAwLjUgKHThu6ljIDUwJSBkw6JuIHPhu5EgY2jGsGEgdOG7q25nIGvhur90IGjDtG4pLg0KDQpHacOhIHRy4buLIHRo4buRbmcga8OqIGtp4buDbSDEkeG7i25oIGzDoCBYLXNxdWFyZWQgPSAzMjU2LjMsIHbhu5tpIDEgYuG6rWMgdOG7sSBkbyAoZGYgPSAxKSwgY2hvIHRo4bqleSBt4bupYyDEkeG7mSBjaMOqbmggbOG7h2NoIHLhuqV0IGzhu5tuIGdp4buvYSB04bu3IGzhu4cgcXVhbiBzw6F0IMSRxrDhu6NjIHbDoCB04bu3IGzhu4cgZ2nhuqMgxJHhu4tuaC4NCg0KR2nDoSB0cuG7iyBwLXZhbHVlIDwgMi4yZS0xNiwgbmdoxKlhIGzDoCBraOG6oyBuxINuZyB44bqjeSByYSBzYWkgbOG6p20ga2hpIGLDoWMgYuG7jyBI4oKAIGzDoCBj4buxYyBr4buzIG5o4buPLCBn4bqnbiBuaMawIGLhurFuZyAwLiDihpIgS+G6v3QgcXXhuqMgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiBy4bqldCBt4bqhbmguDQoNCkdp4bqjIHRodXnhur90IMSR4buRaSAoSOKCgSk6IHThu7cgbOG7hyB0aOG7sWMgdOG6vyBraMOhYyAwLjUgKGtp4buDbSDEkeG7i25oIGhhaSBwaMOtYSDigJMga2nhu4NtIHRyYSB4ZW0gY8OzIGtow6FjIGJp4buHdCByw7UgcsOgbmcgaGF5IGtow7RuZywgZMO5IGzDoCB0aOG6pXAgaMahbiBoYXkgY2FvIGjGoW4pLg0KDQpLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyB04bu3IGzhu4cgbmfGsOG7nWkgY2jGsGEga+G6v3QgaMO0biBu4bqxbSB0cm9uZyBraG/huqNuZyBbMzEuNzMlOyAzMi44OCVdLCBwaOG6o24gw6FuaCBt4buZdCBt4bupYyB04bu3IGzhu4cg4buVbiDEkeG7i25oIHF1YW5oIG3hu6ljIH4zMiUuDQoNClThu7cgbOG7hyBt4bqrdSDGsOG7m2MgbMaw4bujbmcgxJHGsOG7o2MgbMOgIDMyLjMwJSwgdOG7qWMgbMOgIGtob+G6o25nIDEvMyBkw6JuIHPhu5EgdHJvbmcgbeG6q3Uga2jhuqNvIHPDoXQgY2jGsGEgdOG7q25nIGvhur90IGjDtG4g4oCTIGNvbiBz4buRIG7DoHkgdGjhuqVwIGjGoW4gxJHDoW5nIGvhu4Mgc28gduG7m2kgZ2nhuqMgxJHhu4tuaCA1MCUuDQoNCvCfk4wgQsOgaSB0b8OhbiBraeG7g20gxJHhu4tuaDoNCkdp4bqjIHRodXnhur90IGtow7RuZyBI4oKAOiBwID0gMC41ICh04bu3IGzhu4cgbmfGsOG7nWkgY2jGsGEgdOG7q25nIGvhur90IGjDtG4gYuG6sW5nIDUwJSkNCg0KR2nhuqMgdGh1eeG6v3QgxJHhu5FpIEjigoE6IHAg4omgIDAuNSAodOG7tyBs4buHIG5nxrDhu51pIGNoxrBhIHThu6tuZyBr4bq/dCBow7RuIGtow6FjIDUwJSkNCg0KTeG7qWMgw70gbmdoxKlhOiDOsSA9IDAuMDUNCg0K4pyFIEvhur90IGx14bqtbjoNClbhu5tpIHAtdmFsdWUgPCAyLjJlLTE2IDwgMC4wNSwgdGEgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAuDQoNCuKGkiBDw7MgYuG6sW5nIGNo4bupbmcgdGjhu5FuZyBrw6ogbeG6oW5oIGNobyB0aOG6pXkgdOG7tyBs4buHIG5nxrDhu51pIGNoxrBhIHThu6tuZyBr4bq/dCBow7RuIGtow6FjIDUwJSwgduG7m2kgxJHhu5kgdGluIGPhuq15IDk1JS4NCg0KVOG7tyBs4buHIG3huqt1IGzDoCAzMi4zMCUsIG7hurFtIHRyb25nIGtob+G6o25nIFszMS43MyU7IDMyLjg4JV0uDQrihpIgTeG7qWMgY2jDqm5oIGzhu4djaCBn4bqnbiAxOCDEkWnhu4NtIHBo4bqnbiB0csSDbSBzbyB24bubaSA1MCUgY2hvIHRo4bqleSBz4buxIGtow6FjIGJp4buHdCBsw6AgcsO1IHLDoG5nIHbDoCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLg0KDQojIyMgSOG6oW5nIG3hu6VjIOKAnE1hbGXigJ0gY+G7p2EgYmnhur9uIEdp4bubaSB0w61uaCAoR2VuZGVyKQ0KYGBge3J9DQojIFPhu5EgbmfGsOG7nWkgbMOgIG5hbSBnaeG7m2kNCm5fbWFsZSA8LSBzdW0oZCRHZW5kZXIgPT0gIk1hbGUiKQ0KDQojIFThu5VuZyBz4buRIHF1YW4gc8OhdA0Kbl90b3RhbCA8LSBucm93KGQpDQoNCiMgxq/hu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteSA5NSUgY2hvIHThu7cgbOG7hyBuYW0gZ2nhu5tpDQpwcm9wLnRlc3Qobl9tYWxlLCBuX3RvdGFsLCBjb25mLmxldmVsID0gMC45NSkNCg0KYGBgDQoqUGjDom4gdMOtY2gga+G6v3QgcXXhuqMqDQoNCiBQaMOibiB0w61jaCBr4bq/dCBxdeG6ow0KUGjDqXAga2nhu4NtIMSR4buLbmggxJHGsOG7o2Mgc+G7rSBk4bulbmcgbMOgIGtp4buDbSDEkeG7i25oIHThu7cgbOG7hyBt4buZdCBt4bqrdSAoMS1zYW1wbGUgcHJvcG9ydGlvbnMgdGVzdCkgduG7m2kgY2jhu4luaCBsacOqbiB04bulYyAoY29udGludWl0eSBjb3JyZWN0aW9uKSBuaOG6sW0gxJHhuqNtIGLhuqNvIGvhur90IHF14bqjIGNow61uaCB4w6FjIGjGoW4ga2hpIHjhu60gbMO9IGThu68gbGnhu4d1IHLhu51pIHLhuqFjLg0KDQpE4buvIGxp4buHdSDEkeG6p3UgdsOgbzogxJFhbmcgeMOpdCB04bu3IGzhu4cgbmfGsOG7nWkgbMOgIOKAnE1hbGXigJ0gdHJvbmcgdOG7lW5nIHPhu5EgcXVhbiBzw6F0LCB24bubaSBnaeG6oyB0aHV54bq/dCBn4buRYyBI4oKAOiBwID0gMC41ICh04bupYyB04bu3IGzhu4cgbmFtIGdp4bubaSBsw6AgNTAlKS4NCg0KR2nDoSB0cuG7iyB0aOG7kW5nIGvDqiBraeG7g20gxJHhu4tuaCBsw6AgWC1zcXVhcmVkID0gMzA5Mi44LCB24bubaSAxIGLhuq1jIHThu7EgZG8gKGRmID0gMSksIGNobyB0aOG6pXkgY8OzIHPhu7EgY2jDqm5oIGzhu4djaCBs4bubbiBnaeG7r2EgdOG7tyBs4buHIHF1YW4gc8OhdCB2w6AgdOG7tyBs4buHIGdp4bqjIMSR4buLbmguDQoNCnAtdmFsdWUgPCAyLjJlLTE2LCBj4buxYyBr4buzIG5o4buPLCBjaG8gdGjhuqV5IGPDsyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiBy4bqldCBt4bqhbmggxJHhu4MgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAuDQoNCkdp4bqjIHRodXnhur90IMSR4buRaSAoSOKCgSk6IHThu7cgbOG7hyB0aOG7sWMgdOG6vyBraMOhYyAwLjUg4oCTIMSRw6J5IGzDoCBraeG7g20gxJHhu4tuaCBoYWkgcGjDrWEuDQoNCktob+G6o25nIHRpbiBj4bqteSA5NSUgY2hvIHThu7cgbOG7hyBuYW0gZ2nhu5tpIG7hurFtIHRyb25nIGtob+G6o25nIFs2Ni42OCU7IDY3LjgxJV0sIGNobyB0aOG6pXkgdOG7tyBs4buHIG7DoHkg4buVbiDEkeG7i25oIHbDoCBjYW8gaMahbiDEkcOhbmcga+G7gyBzbyB24bubaSBt4bupYyBnaeG6oyDEkeG7i25oIGJhbiDEkeG6p3UuDQoNClThu7cgbOG7hyBt4bqrdSDGsOG7m2MgbMaw4bujbmcgbMOgIDY3LjI1JSwgdOG7qWMgbMOgIGfhuqduIDIvMyBuZ8aw4budaSB0cm9uZyBt4bqrdSBraOG6o28gc8OhdCBsw6AgbmFtIGdp4bubaS4NCg0KIELDoGkgdG/DoW4ga2nhu4NtIMSR4buLbmg6DQpHaeG6oyB0aHV54bq/dCBraMO0bmcgSOKCgDogcCA9IDAuNSAodOG7tyBs4buHIG5hbSBnaeG7m2kgYuG6sW5nIDUwJSkNCg0KR2nhuqMgdGh1eeG6v3QgxJHhu5FpIEjigoE6IHAg4omgIDAuNSAodOG7tyBs4buHIG5hbSBnaeG7m2kga2jDoWMgNTAlKQ0KDQpN4bupYyDDvSBuZ2jEqWE6IM6xID0gMC4wNQ0KDQpL4bq/dCBsdeG6rW46DQpW4bubaSBwLXZhbHVlIDwgMi4yZS0xNiA8IDAuMDUsIHRhIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKALg0KDQrihpIgQ8OzIGLhurFuZyBjaOG7qW5nIHRo4buRbmcga8OqIHLDtSByw6BuZyBjaG8gdGjhuqV5IHThu7cgbOG7hyBuYW0gZ2nhu5tpIGtow6FjIDUwJSwgduG7m2kgxJHhu5kgdGluIGPhuq15IDk1JS4NCg0KVOG7tyBs4buHIG5hbSBnaeG7m2kgxrDhu5tjIGzGsOG7o25nIGzDoCA2Ny4yNSUsIHbhu5tpIGtob+G6o25nIHRpbiBj4bqteSBu4bqxbSB0cm9uZyBbNjYuNjglOyA2Ny44MSVdLg0K4oaSIE3hu6ljIGNow6puaCBs4buHY2ggaMahbiAxNyDEkWnhu4NtIHBo4bqnbiB0csSDbSBzbyB24bubaSB04bu3IGzhu4cgZ2nhuqMgxJHhu4tuaCBsw6AgxJHhu6cgbOG7m24gxJHhu4MgdOG6oW8gcmEgw70gbmdoxKlhIHRo4buRbmcga8OqIG3huqFuaCBt4bq9Lg0KDQojIFBow6JuIHTDrWNoIE3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgSGFpIGJp4bq/biDEkOG7i25oIHTDrW5oIChCaXZhcmlhdGUgQW5hbHlzaXMpDQoNCg0KDQogR2VuZGVyIOKAkyBFYXJuaW5nQ2xhc3MNCuKGkiBQaMOibiB0w61jaCBt4buRaSBsacOqbiBo4buHIGdp4buvYSBnaeG7m2kgdMOtbmggdsOgIG3hu6ljIHRodSBuaOG6rXAuDQoNCkPDonUgaOG7j2kgxJHhurd0IHJhOiBHaeG7m2kgdMOtbmggY8OzIOG6o25oIGjGsOG7n25nIMSR4bq/biBraOG6oyBuxINuZyB0aHXhu5ljIG5ow7NtIHRodSBuaOG6rXAgPjUwSyBraMO0bmc/DQoNCuKGkiBUw6xtIGhp4buDdSB4ZW0gZ2nhu5tpIHTDrW5oIGPDsyBsacOqbiBxdWFuIMSR4bq/biB0aHUgbmjhuq1wIGtow7RuZy4NCg0KQ8OidSBo4buPaSDEkeG6t3QgcmE6IFThu7cgbOG7hyB0aHUgbmjhuq1wID41MEsgY8OzIGNow6puaCBs4buHY2ggcsO1IHLhu4d0IGdp4buvYSBjw6FjIG5ow7NtIGdp4bubaSB0w61uaCBraMO0bmc/DQoNCg0KIyMgR2VuZGVyIC0gRWFybmluZ0NsYXNzDQoNCiMjIyAgQuG6o25nIHThuqduIHPhu5EgY2jDqW8NCmBgYHtyfQ0KIyBC4bqjbmcgdOG6p24gc+G7kSBjaMOpbzogZ2nhu5tpIHTDrW5oIHbDoCB0aHUgbmjhuq1wDQp0YWJsZV9HZW5kZXJfRWFybmluZ0NsYXNzIDwtIHRhYmxlKGQkR2VuZGVyLCBkJEVhcm5pbmdDbGFzcykNCnRhYmxlX0dlbmRlcl9FYXJuaW5nQ2xhc3MNCg0KIyBU4bu3IGzhu4cgdGhlbyBow6BuZyAodOG7q25nIGdp4bubaSB0w61uaCkNCnByb3AudGFibGUodGFibGVfR2VuZGVyX0Vhcm5pbmdDbGFzcywgbWFyZ2luID0gMSkNCg0KYGBgDQoNCvCflI0gVHJvbmcgc+G7kSBuYW0gZ2nhu5tpIChNYWxlKToNCkPDsyAxMSw4ODkgbmfGsOG7nWkgdGh1IG5o4bqtcCDiiaQ1MEsgdsOgIDUsNTk0IG5nxrDhu51pIHRodSBuaOG6rXAgPjUwSyDihpIgdOG7tyBs4buHID41MEsgbMOgIGtob+G6o25nIDMxLjAlLg0KDQrwn5SNIFRyb25nIHPhu5EgbuG7ryBnaeG7m2kgKEZlbWFsZSk6DQpDw7MgNyw1MjYgbmfGsOG7nWkgdGh1IG5o4bqtcCDiiaQ1MEsgdsOgIDk4OSBuZ8aw4budaSB0aHUgbmjhuq1wID41MEsg4oaSIHThu7cgbOG7hyA+NTBLIGzDoCBraG/huqNuZyAxMS42JS4NCg0K8J+TjCBL4bq/dCBsdeG6rW46DQpOYW0gZ2nhu5tpIGPDsyB04bu3IGzhu4cgdGh1IG5o4bqtcCA+NTBLIGNhbyBn4bqnbiBn4bqlcCAzIGzhuqduIG7hu68gZ2nhu5tpICgzMS4wJSBzbyB24bubaSAxMS42JSksIGNobyB0aOG6pXkgc+G7sSBjaMOqbmggbOG7h2NoIHRodSBuaOG6rXAgcsO1IHLhu4d0IGdp4buvYSBoYWkgZ2nhu5tpIHRyb25nIHThuq1wIGThu68gbGnhu4d1IG7DoHkuDQoNCg0KDQojIyMgIFRy4buxYyBxdWFuIGjDs2ENCmBgYHtyIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02fQ0KbGlicmFyeShnZ3Bsb3QyKQ0KDQojIFThuqFvIGLhuqNuZyBk4buvIGxp4buHdSB04burIGLhuqNuZyB04bqnbiBzdeG6pXQgY2jDqW8NCnRhYmxlX0dlbmRlcl9FYXJuaW5nQ2xhc3MgPC0gdGFibGUoZCRHZW5kZXIsIGQkRWFybmluZ0NsYXNzKQ0KZGZfZ3JvdXAgPC0gYXMuZGF0YS5mcmFtZShhcy50YWJsZSh0YWJsZV9HZW5kZXJfRWFybmluZ0NsYXNzKSkNCmNvbG5hbWVzKGRmX2dyb3VwKSA8LSBjKCJHZW5kZXIiLCAiRWFybmluZ0NsYXNzIiwgIkZyZXEiKSAgIyDEkOG7lWkgdMOqbiBj4buZdA0KDQojIFbhur0gYmnhu4N1IMSR4buTIGPhu5l0IG5ow7NtDQpnZ3Bsb3QoZGZfZ3JvdXAsIGFlcyh4ID0gRWFybmluZ0NsYXNzLCB5ID0gRnJlcSwgZmlsbCA9IEdlbmRlcikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjgpLCB3aWR0aCA9IDAuNikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcSksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC44KSwNCiAgICAgICAgICAgIHZqdXN0ID0gLTAuNCwgc2l6ZSA9IDQsIGNvbG9yID0gIndoaXRlIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgbGFicyh0aXRsZSA9ICJCaeG7g3UgxJHhu5MgY+G7mXQgbmjDs206IEdlbmRlciB2cyBFYXJuaW5nQ2xhc3MiLA0KICAgICAgIHggPSAiTeG7qWMgdGh1IG5o4bqtcCIsDQogICAgICAgeSA9ICJU4bqnbiBz4buRIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCgNCiAgICB2YWx1ZXMgPSBjKCJGZW1hbGUiID0gIiNGRjk5OTkiLCAiTWFsZSIgPSAiIzY2OTlDQyIpLA0KICAgIG5hbWUgPSAiR2nhu5tpIHTDrW5oIiwNCiAgICBsYWJlbHMgPSBjKCJO4buvIiwgIk5hbSIpDQogICkgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEzKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCINCiAgKQ0KDQpgYGANCg0KLSBsaWJyYXJ5KGdncGxvdDIpOiBO4bqhcCB0aMawIHZp4buHbiBnZ3Bsb3QyIMSR4buDIHPhu60gZOG7pW5nIGPDoWMgY2jhu6ljIG7Eg25nIHbhur0gYmnhu4N1IMSR4buTLg0KDQotIHRhYmxlX0dlbmRlcl9FYXJuaW5nQ2xhc3MgPC0gdGFibGUoZCRHZW5kZXIsIGQkRWFybmluZ0NsYXNzKTogVOG6oW8gYuG6o25nIHThuqduIHN14bqldCBjaMOpbyBnaeG7r2EgaGFpIGJp4bq/biDEkeG7i25oIHTDrW5oIGzDoCBnaeG7m2kgdMOtbmggKEdlbmRlcikgdsOgIHRodSBuaOG6rXAgKEVhcm5pbmdDbGFzcyksIGNobyBiaeG6v3Qgc+G7kSBsxrDhu6NuZyB04burbmcgdOG7lSBo4bujcC4NCg0KLSBkZl9ncm91cCA8LSBhcy5kYXRhLmZyYW1lKGFzLnRhYmxlKHRhYmxlX0dlbmRlcl9FYXJuaW5nQ2xhc3MpKTogQ2h1eeG7g24gYuG6o25nIHThuqduIHN14bqldCB24burYSB04bqhbyBzYW5nIGThuqFuZyBi4bqjbmcgZOG7ryBsaeG7h3UgKGRhdGEuZnJhbWUpIGfhu5NtIGJhIGPhu5l0Lg0KDQotIGNvbG5hbWVzKGRmX2dyb3VwKSA8LSBjKCJHZW5kZXIiLCAiRWFybmluZ0NsYXNzIiwgIkZyZXEiKTogxJDhurd0IHTDqm4gY2hvIGJhIGPhu5l0IGzDoDogZ2nhu5tpIHTDrW5oIChHZW5kZXIpLCBt4bupYyB0aHUgbmjhuq1wIChFYXJuaW5nQ2xhc3MpIHbDoCB04bqnbiBz4buRIChGcmVxKS4NCg0KLSBnZ3Bsb3QoZGZfZ3JvdXAsIGFlcyh4ID0gRWFybmluZ0NsYXNzLCB5ID0gRnJlcSwgZmlsbCA9IEdlbmRlcikpOiBLaOG7n2kgdOG6oW8gYmnhu4N1IMSR4buTIGPhu5l0LCB0cuG7pWMgaG/DoG5oIGzDoCB0aHUgbmjhuq1wLCB0cuG7pWMgdHVuZyBsw6AgdOG6p24gc+G7kSwgY8OhYyBj4buZdCDEkcaw4bujYyB0w7QgbcOgdSB0aGVvIGdp4bubaSB0w61uaC4NCg0KLSBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOCksIHdpZHRoID0gMC42KTogVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgbmjDs20sIMSR4bq3dCBjw6FjIGPhu5l0IG5hbSB2w6AgbuG7ryBj4bqhbmggbmhhdSDEkeG7gyBk4buFIHNvIHPDoW5oLg0KDQotIGdlb21fdGV4dCguLi4pOiBUaMOqbSBuaMOjbiBz4buRIGzGsOG7o25nIGzDqm4gbeG7l2kgY+G7mXQgxJHhu4MgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgRnJlcSwgxJHhurd0IOG7nyB0csOqbiDEkeG6p3UgY+G7mXQuDQoNCi0gbGFicyguLi4pOiBUaMOqbSB0acOqdSDEkeG7gSBiaeG7g3UgxJHhu5MgdsOgIG5ow6NuIGNobyBjw6FjIHRy4bulYy4NCg0KLSBzY2FsZV9maWxsX21hbnVhbCguLi4pOiBUw7l5IGNo4buJbmggbcOgdSBz4bqvYyBj4bunYSB04burbmcgZ2nhu5tpIHTDrW5oIHbDoCB0aGnhur90IGzhuq1wIGNow7ogdGjDrWNoIChsZWdlbmQpLg0KDQotIHRoZW1lX21pbmltYWwoLi4uKSArIHRoZW1lKC4uLik6IMOBcCBk4bulbmcgcGhvbmcgY8OhY2ggdOG7kWkgZ2nhuqNuIGNobyBiaeG7g3UgxJHhu5MsIGPEg24gZ2nhu69hIHRpw6p1IMSR4buBIHbDoCDEkeG6t3QgY2jDuiBnaeG6o2kgYsOqbiBwaOG6o2kuDQoNCmBgYHtyIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD02fQ0KIyBU4bqhbyBi4bqjbmcgZOG7ryBsaeG7h3UgdOG7qyBi4bqjbmcgdOG6p24gc3XhuqV0IGNow6lvDQp0YWJsZV9HZW5kZXJfRWFybmluZ0NsYXNzIDwtIHRhYmxlKGQkR2VuZGVyLCBkJEVhcm5pbmdDbGFzcykNCmRmX3N0YWNrIDwtIGFzLmRhdGEuZnJhbWUoYXMudGFibGUodGFibGVfR2VuZGVyX0Vhcm5pbmdDbGFzcykpDQpjb2xuYW1lcyhkZl9zdGFjaykgPC0gYygiR2VuZGVyIiwgIkVhcm5pbmdDbGFzcyIsICJGcmVxIikgICMgxJDhu5VpIHTDqm4gY+G7mXQNCg0KIyBW4bq9IGJp4buDdSDEkeG7kyBj4buZdCBjaOG7k25nDQpnZ3Bsb3QoZGZfc3RhY2ssIGFlcyh4ID0gRWFybmluZ0NsYXNzLCB5ID0gRnJlcSwgZmlsbCA9IEdlbmRlcikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC42KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBGcmVxKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgY29sb3IgPSAiZ3JlZW4iLCBzaXplID0gNCwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwoDQogICAgdmFsdWVzID0gYygiRmVtYWxlIiA9ICJyZWQiLCAiTWFsZSIgPSAibGlnaHRibHVlIiksDQogICAgbmFtZSA9ICJHaeG7m2kgdMOtbmgiLA0KICAgIGxhYmVscyA9IGMoIk7hu68iLCAiTmFtIikNCiAgKSArDQogIGxhYnModGl0bGUgPSAiQmnhu4N1IMSR4buTIGPhu5l0IGNo4buTbmc6IEdlbmRlciB2cyBFYXJuaW5nQ2xhc3MiLA0KICAgICAgIHggPSAiTeG7qWMgdGh1IG5o4bqtcCIsDQogICAgICAgeSA9ICJU4bqnbiBz4buRIikgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEzKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCINCiAgKQ0KDQoNCmBgYA0KDQotIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuNik6IFbhur0gYmnhu4N1IMSR4buTIGPhu5l0IGNo4buTbmcgKHN0YWNrZWQgYmFyIGNoYXJ0KSwgdHJvbmcgxJHDsyBt4buXaSBuaMOzbSB0aHUgbmjhuq1wIGhp4buDbiB0aOG7iyBt4buZdCBj4buZdCBjw7MgcGjhuqduIGNo4buTbmcgdGhlbyBnaeG7m2kgdMOtbmguDQoNCi0gZ2VvbV90ZXh0KHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCAuLi4pOiBIaeG7g24gdGjhu4sgbmjDo24gc+G7kSBsxrDhu6NuZyAodOG6p24gc+G7kSkgYsOqbiB0cm9uZyB04burbmcgcGjhuqduIGNo4buTbmcgY+G7p2EgY+G7mXQsIHThu6ljIGzDoCDhu58gZ2nhu69hIG3hu5dpIGto4buRaSBtw6B1Lg0KDQoNCkvhur90IGx14bqtbiB0cuG7sWMgcXVhbjoNCkhhaSBiaeG7g3UgxJHhu5MgY2hvIHRo4bqleSBz4buxIGNow6puaCBs4buHY2ggdGh1IG5o4bqtcCByw7UgcuG7h3QgZ2nhu69hIGhhaSBnaeG7m2k6DQoNCk5hbSBnaeG7m2kgY8OzIHh1IGjGsOG7m25nIMSR4bqhdCB0aHUgbmjhuq1wIGNhbyAoPjUwSykgbmhp4buBdSBoxqFuIG7hu68gZ2nhu5tpLg0KDQpO4buvIGdp4bubaSBjaOG7pyB54bq/dSB04bqtcCB0cnVuZyDhu58gbmjDs20gdGh1IG5o4bqtcCB0aOG6pXAsIHbDoCBn4bqnbiBuaMawIHbhuq9uZyBt4bq3dCDhu58gbmjDs20gdGh1IG5o4bqtcCBjYW8uDQoNCkdp4bubaSB0w61uaCBsw6AgeeG6v3UgdOG7kSDhuqNuaCBoxrDhu59uZyDEkcOhbmcga+G7gyDEkeG6v24gcGjDom4gcGjhu5FpIHRodSBuaOG6rXAgdHJvbmcgdOG6rXAgZOG7ryBsaeG7h3UgbsOgeS4gQmnhu4N1IMSR4buTIHRy4buxYyBxdWFuIHBo4bqjbiDDoW5oIHPhu7EgYuG6pXQgYsOsbmggxJHhurNuZyByw7UgbsOpdCB24buBIHRodSBuaOG6rXAgZ2nhu69hIG5hbSB2w6AgbuG7ry4NCg0KDQojIyMgIEtp4buDbSDEkeG7i25oIHRo4buRbmcga8OqIChLaeG7g20gxJHhu4tuaCBDaGktYsOsbmggcGjGsMahbmcpDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmg6KioNCg0KKipI4oKAIChHaeG6oyB0aHV54bq/dCBraMO0bmcpKio6IEdp4bubaSB0w61uaCB2w6AgbeG7qWMgdGh1IG5o4bqtcCDEkeG7mWMgbOG6rXAgbmhhdS4NCg0KKipI4oKBIChHaeG6oyB0aHV54bq/dCDEkeG7kWkpKio6R2nhu5tpIHTDrW5oIHbDoCBt4bupYyB0aHUgbmjhuq1wIGPDsyBsacOqbiBo4buHLi4NCg0KYGBge3J9DQojIFRo4buxYyBoaeG7h24ga2nhu4NtIMSR4buLbmggQ2hpLWLDrG5oIHBoxrDGoW5nDQpjaGlzcS50ZXN0KHRhYmxlX0dlbmRlcl9FYXJuaW5nQ2xhc3MpDQpgYGANCioqS+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmggQ2hpLWLDrG5oIHBoxrDGoW5nOioqDQpL4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaCBDaGktYsOsbmggcGjGsMahbmc6DQoNCkNoaS1zcXVhcmVkID0gMTI1Ni45DQpC4bqtYyB04buxIGRvIChkZikgPSAxDQpHacOhIHRy4buLIHAtdmFsdWUgPSA8IDIuMmUtMTYNCg0KS+G6v3QgbHXhuq1uIHRo4buRbmcga8OqOiBW4bubaSBwLXZhbHVlIGfhuqduIG5oxrAgYuG6sW5nIDAsIG5o4buPIGjGoW4gcuG6pXQgbmhp4buBdSBzbyB24bubaSBuZ8aw4buhbmcgw70gbmdoxKlhIDAuMDUsIHRhIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKALg0K4oeSIEPDsyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiBt4bqhbmggbeG6vSBjaG8gdGjhuqV5IGdp4bubaSB0w61uaCB2w6AgbeG7qWMgdGh1IG5o4bqtcCBjw7MgbGnDqm4gaOG7hyB24bubaSBuaGF1Lg0KDQpUaOG6o28gbHXhuq1uIHRow6ptIHbhu4EgYuG6o24gY2jhuqV0IG3hu5FpIHF1YW4gaOG7hzoNCg0KS+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmggY2hvIHRo4bqleSBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGdp4bubaSB0w61uaCB2w6AgdGh1IG5o4bqtcCBraMO0bmcgcGjhuqNpIG5n4bqrdSBuaGnDqm4uDQpOw7NpIGPDoWNoIGtow6FjLCBnaeG7m2kgdMOtbmggY8OzIHRo4buDIMSRw7NuZyB2YWkgdHLDsiBuaMawIG3hu5l0IHnhur91IHThu5EgZOG7sSBiw6FvIG3hu6ljIHRodSBuaOG6rXAsIGtoaSBtw6Agc+G7sSBwaMOibiBi4buRIGdp4buvYSBuYW0gdsOgIG7hu68g4bufIGhhaSBuaMOzbSB0aHUgbmjhuq1wIGPDsyBz4buxIGtow6FjIGJp4buHdCByw7UgcuG7h3QuDQoNClF1YW4gc8OhdCBiaeG7g3UgxJHhu5MgY2hvIHRo4bqleToNCg0KVOG7tyBs4buHIG5hbSBnaeG7m2kgdMSDbmcgbeG6oW5oIOG7nyBuaMOzbSB0aHUgbmjhuq1wID41MEssIGNobyB0aOG6pXkgaOG7jSBjw7MgY8ahIGjhu5lpIGNhbyBoxqFuIMSR4buDIMSR4bqhdCB0aHUgbmjhuq1wIGNhby4NClRyb25nIGtoaSDEkcOzLCBu4buvIGdp4bubaSB04bqtcCB0cnVuZyBuaGnhu4F1IOG7nyBuaMOzbSB0aHUgbmjhuq1wIHRo4bqlcCwgduG7m2kgc+G7kSBsxrDhu6NuZyBnaeG6o20gbeG6oW5oIGtoaSBjaHV54buDbiBzYW5nIG5ow7NtIHRodSBuaOG6rXAgY2FvLg0KDQpH4bujaSDDvSBi4bqjbiBjaOG6pXQgc8OidSB4YSBj4bunYSBt4buRaSBsacOqbiBo4buHOg0KDQpT4buxIGtow6FjIGJp4buHdCBuw6B5IGPDsyB0aOG7gyBwaOG6o24gw6FuaCBjw6FjIHnhur91IHThu5EgeMOjIGjhu5lpIG5oxrAgxJHhu4tuaCBraeG6v24gZ2nhu5tpIHRyb25nIHZp4buHYyBs4buxYSBjaOG7jW4gbmfDoG5oIG5naOG7gSwga2jhuqMgbsSDbmcgdGnhur9wIGPhuq1uIGPDoWMgduG7iyB0csOtIGzGsMahbmcgY2FvLCBob+G6t2MgdGjhu51pIGdpYW4gdMOtY2ggbMWpeSBraW5oIG5naGnhu4dtLg0KTmdvw6BpIHJhLCBjw7JuIGPDsyB0aOG7gyBsacOqbiBxdWFuIMSR4bq/biBt4bupYyDEkeG7mSB0aGFtIGdpYSB0aOG7iyB0csaw4budbmcgbGFvIMSR4buZbmcgaG/hurdjIHPhu7EgcGjDom4gY2hpYSB2YWkgdHLDsiB0cm9uZyBnaWEgxJHDrG5oLg0KDQrihpIgVMOzbSBs4bqhaTogS2jDtG5nIGNo4buJIGPDsyBz4buxIGxpw6puIGjhu4cgduG7gSBt4bq3dCB0aOG7kW5nIGvDqiwgbcOgIGvhur90IHF14bqjIGPDsm4gcGjhuqNuIMOhbmggbeG7mXQgYuG6pXQgYsOsbmggxJHhurNuZyBtYW5nIHTDrW5oIGjhu4cgdGjhu5FuZywgdHJvbmcgxJHDsyBuYW0gZ2nhu5tpIGPDsyB4dSBoxrDhu5tuZyDEkcaw4bujYyDEkeG6oWkgZGnhu4duIG5oaeG7gXUgaMahbiB0cm9uZyBuaMOzbSB0aHUgbmjhuq1wIGNhbyBzbyB24bubaSBu4buvIGdp4bubaS4NCg0KDQojIyMgSGnhu4d1IHThu7cgbOG7hyANCmBgYHtyfQ0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc+G7kSBjaMOpbyBnaeG7r2EgR2VuZGVyIHbDoCBFYXJuaW5nQ2xhc3MNCnRhYmxlX0dlbmRlcl9FYXJuaW5nQ2xhc3MgPC0gdGFibGUoZCRHZW5kZXIsIGQkRWFybmluZ0NsYXNzKQ0KDQojIFRow6ptIHThu5VuZyBow6BuZyB2w6AgdOG7lW5nIGPhu5l0DQp0YWJsZV9HZW5kZXJfRWFybmluZ0NsYXNzX21hcmdpbnMgPC0gYWRkbWFyZ2lucyh0YWJsZV9HZW5kZXJfRWFybmluZ0NsYXNzKQ0KDQojIEhp4buDbiB0aOG7iyBi4bqjbmcNCnRhYmxlX0dlbmRlcl9FYXJuaW5nQ2xhc3NfbWFyZ2lucw0KDQpgYGANClThu7cgbOG7hyB0aHUgbmjhuq1wIGNhbyB0aGVvIGdp4bubaSB0w61uaCDEkcaw4bujYyBrw70gaGnhu4d1IG5oxrAgc2F1Og0KDQotIFwoIHBfMSA9IFAoXHRleHR7RWFybmluZ0NsYXNzfSA9IFx0ZXh0eyI+NTBLIn0gXG1pZCBcdGV4dHtHZW5kZXJ9ID0gXHRleHR7IkZlbWFsZSJ9KSBcKTogVOG7tyBs4buHIG7hu68gZ2nhu5tpIGPDsyB0aHUgbmjhuq1wIGNhby4gIA0KLSBcKCBwXzIgPSBQKFx0ZXh0e0Vhcm5pbmdDbGFzc30gPSBcdGV4dHsiPjUwSyJ9IFxtaWQgXHRleHR7R2VuZGVyfSA9IFx0ZXh0eyJNYWxlIn0pIFwpOiBU4bu3IGzhu4cgbmFtIGdp4bubaSBjw7MgdGh1IG5o4bqtcCBjYW8uDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmg6KioNCg0KLSBcKCBIXzA6IHBfMSAtIHBfMiA9IDAgXCk6IEtow7RuZyBjw7Mgc+G7sSBraMOhYyBiaeG7h3QgduG7gSB04bu3IGzhu4cgdGh1IG5o4bqtcCBjYW8gZ2nhu69hIG5hbSB2w6AgbuG7ry4gIA0KLSBcKCBIXzE6IHBfMSAtIHBfMiA8IDAgXCk6IFThu7cgbOG7hyB0aHUgbmjhuq1wIGNhbyDhu58gbuG7ryB0aOG6pXAgaMahbiBuYW0uDQoNCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgdOG6p24gc+G7kSBjaMOpbyBnaeG7r2EgR2VuZGVyIHbDoCBFYXJuaW5nQ2xhc3MNCnRhYmxlX0dlbmRlcl9FYXJuaW5nQ2xhc3MgPC0gdGFibGUoZCRHZW5kZXIsIGQkRWFybmluZ0NsYXNzKQ0KDQojIFPhu5EgbmfGsOG7nWkgY8OzIHRodSBuaOG6rXAgPjUwSyB0cm9uZyB04burbmcgZ2nhu5tpDQpjb3VudHNfRWFybmluZ0NsYXNzX2hpZ2ggPC0gYyh0YWJsZV9HZW5kZXJfRWFybmluZ0NsYXNzWyJGZW1hbGUiLCAiPjUwSyJdLCB0YWJsZV9HZW5kZXJfRWFybmluZ0NsYXNzWyJNYWxlIiwgIj41MEsiXSkNCg0KIyBU4buVbmcgc+G7kSBuZ8aw4budaSB0aGVvIHThu6tuZyBnaeG7m2kNCnRvdGFsc19FYXJuaW5nQ2xhc3MgPC0gYyhzdW0odGFibGVfR2VuZGVyX0Vhcm5pbmdDbGFzc1siRmVtYWxlIiwgXSksIHN1bSh0YWJsZV9HZW5kZXJfRWFybmluZ0NsYXNzWyJNYWxlIiwgXSkpDQoNCiMgS2nhu4NtIMSR4buLbmggdOG7iSBs4buHIG3hu5l0IHBow61hOiBwMSA8IHAyDQp0ZXN0X0Vhcm5pbmdDbGFzc19sZXNzIDwtIHByb3AudGVzdChjb3VudHNfRWFybmluZ0NsYXNzX2hpZ2gsIHRvdGFsc19FYXJuaW5nQ2xhc3MsIGFsdGVybmF0aXZlID0gImxlc3MiLCBjb3JyZWN0ID0gRkFMU0UpDQoNCiMgSGnhu4NuIHRo4buLIGvhur90IHF14bqjDQp0ZXN0X0Vhcm5pbmdDbGFzc19sZXNzDQpgYGANCk3hu6VjIHRpw6p1IGtp4buDbSDEkeG7i25oOiBTbyBzw6FuaCB04bu3IGzhu4cgbmfGsOG7nWkgY8OzIHRodSBuaOG6rXAgY2FvIChiaeG6v24gRWFybmluZ0NsYXNzIGPDsyBnacOhIHRy4buLICI+NTBLIikgZ2nhu69hIGhhaSBnaeG7m2kgdMOtbmggKEdlbmRlciBsw6AgIkZlbWFsZSIgdsOgICJNYWxlIikuDQoNCsSQ4buLbmggbmdoxKlhOg0KDQpwMSA9IFAoRWFybmluZ0NsYXNzID09ICI+NTBLIiB8IEdlbmRlciA9PSAiRmVtYWxlIik6IHThu7cgbOG7hyBu4buvIGdp4bubaSBjw7MgdGh1IG5o4bqtcCBjYW8uDQoNCnAyID0gUChFYXJuaW5nQ2xhc3MgPT0gIj41MEsiIHwgR2VuZGVyID09ICJNYWxlIik6IHThu7cgbOG7hyBuYW0gZ2nhu5tpIGPDsyB0aHUgbmjhuq1wIGNhby4NCg0KR8SQ4buLbmggbmdoxKlhOg0KDQpw4oKBID0gUChFYXJuaW5nQ2xhc3MgPT0gIj41MEsiIHwgR2VuZGVyID09ICJGZW1hbGUiKSDihpIgVOG7tyBs4buHIG7hu68gZ2nhu5tpIGPDsyB0aHUgbmjhuq1wIGNhbw0KDQpw4oKCID0gUChFYXJuaW5nQ2xhc3MgPT0gIj41MEsiIHwgR2VuZGVyID09ICJNYWxlIikg4oaSIFThu7cgbOG7hyBuYW0gZ2nhu5tpIGPDsyB0aHUgbmjhuq1wIGNhbw0KDQpHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaDoNCg0KSOKCgDogcOKCgSDiiJIgcOKCgiA9IDAg4oaSIEtow7RuZyBjw7Mgc+G7sSBraMOhYyBiaeG7h3QgduG7gSB04bu3IGzhu4cgdGh1IG5o4bqtcCBjYW8gZ2nhu69hIG5hbSB2w6AgbuG7rw0KDQpI4oKBOiBw4oKBIOKIkiBw4oKCIDwgMCDihpIgVOG7tyBs4buHIHRodSBuaOG6rXAgY2FvIOG7nyBu4buvIHRo4bqlcCBoxqFuIOG7nyBuYW0NCg0KVMOtbmggdG/DoW4gZOG7sWEgdHLDqm4gYuG6o25nIGThu68gbGnhu4d1Og0KDQpT4buRIG7hu68gdGh1IG5o4bqtcCA+NTBLOiA5ODkgLyBU4buVbmcgc+G7kSBu4buvOiA4LDUxNSDihpIgcOKCgSDiiYggMTEuNjElDQoNClPhu5EgbmFtIHRodSBuaOG6rXAgPjUwSzogNSw1OTQgLyBU4buVbmcgc+G7kSBuYW06IDE3LDQ4MyDihpIgcOKCgiDiiYggMzEuOTklYA0KDQpYLXNxdWFyZWQgPSAxNTE4LjksIGRmID0gMSwgcC12YWx1ZSA8IDIuMmUtMTYuDQoNCktob+G6o25nIHRpbiBj4bqteSA5NSUgY2hvIHAxIC0gcDI6IHThu6sgLTEuMDAwMDAwMCDEkeG6v24gLTAuMTg5MTQ1Ny4NCg0KS+G6v3QgbHXhuq1uOiBDw7MgYuG6sW5nIGNo4bupbmcgdGjhu5FuZyBrw6ogbeG6oW5oIMSR4buDIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBIMC4gVOG7tyBs4buHIG7hu68gY8OzIHRodSBuaOG6rXAgY2FvIHRo4bqlcCBoxqFuIG5hbSBt4buZdCBjw6FjaCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLg0KDQojIyMgVOG7tyBz4buRIG5ndXkgY8ahDQoNCioqTGnhu4d1IGdp4bubaSB0w61uaCAobmFtL27hu68pIGPDsyDhuqNuaCBoxrDhu59uZyDEkeG6v24gdGh1IG5o4bqtcCBjYW8ga2jDtG5nICg+NTBLKT8qKiANCg0K4oaSIE3hu6VjIHRpw6p1OiBTbyBzw6FuaCB04buJIGzhu4cgY8OzIHRodSBuaOG6rXAgY2FvIOG7nyBuYW0gZ2nhu5tpIHNvIHbhu5tpIG7hu68gZ2nhu5tpLg0KDQpgYGB7cn0NCmluc3RhbGwucGFja2FnZXMoImVwaXRvb2xzIiwgcmVwb3MgPSAiaHR0cHM6Ly9jbG91ZC5yLXByb2plY3Qub3JnIikNCmxpYnJhcnkoZXBpdG9vbHMpDQpgYGANCg0KKipUw61uaCBSZWxhdGl2ZSBSaXNrKioNCg0KYGBge3J9DQpyaXNrcmF0aW8odGFibGVfR2VuZGVyX0Vhcm5pbmdDbGFzcykNCmBgYA0KKipOaOG6rW4geMOpdCBr4bq/dCBxdeG6oyoqDQoNCiRkYXRhOiBi4bqjbmcgZOG7ryBsaeG7h3UgY2jDqW8gMngyDQpO4buvOiA4LjUxNSBuZ8aw4budaSwgdHJvbmcgxJHDsyA5ODkgbmfGsOG7nWkgKDExLjYyJSkgY8OzIHRodSBuaOG6rXAgPjUwSw0KDQpOYW06IDE3LjQ4MyBuZ8aw4budaSwgdHJvbmcgxJHDsyA1LjU5NCBuZ8aw4budaSAoMzIuMDAlKSBjw7MgdGh1IG5o4bqtcCA+NTBLDQoNCiRtZWFzdXJlOiBU4bu3IHPhu5Egbmd1eSBjxqEgKFJlbGF0aXZlIFJpc2sg4oCTIFJSKQ0KUlIgPSAyLjc1IOKGkiBuYW0gZ2nhu5tpIGPDsyBuZ3V5IGPGoSDEkeG6oXQgdGh1IG5o4bqtcCA+NTBLIGNhbyBoxqFuIDIuNzUgbOG6p24gc28gduG7m2kgbuG7ryBnaeG7m2kNCg0KS2hv4bqjbmcgdGluIGPhuq15IDk1JTogWzIuNTk7IDIuOTNdIOKGkiBraMO0bmcgY2jhu6lhIDEg4oaSIGvhur90IHF14bqjIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6oNCg0KJHAudmFsdWU6DQpQLXZhbHVlIOKJiCAwIOKGkiBjw7MgxJHhu6cgYuG6sW5nIGNo4bupbmcgYsOhYyBi4buPIEjigoANCuKGkiBHaeG7m2kgdMOtbmggY8OzIOG6o25oIGjGsOG7n25nIHLDtSBy4buHdCDEkeG6v24ga2jhuqMgbsSDbmcgxJHhuqF0IHRodSBuaOG6rXAgY2FvDQoNCioqJHAudmFsdWUqKg0KDQpgYGB7cn0NCiMgQ8OgaSBnw7NpIG7hur91IGPhuqduDQppbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpICAjIGNo4buJIGPhuqduIDEgbOG6p24gbuG6v3UgY2jGsGEgY8OgaQ0KDQojIE7huqFwIHRoxrAgdmnhu4duDQpsaWJyYXJ5KGtuaXRyKQ0KDQojIFThuqFvIGLhuqNuZyBk4buvIGxp4buHdQ0KZXhwbGFuYXRpb24gPC0gZGF0YS5mcmFtZSgNCiAgQ+G7mXQgPSBjKCJ0d28tc2lkZWQiLCAibWlkcC5leGFjdCIsICJmaXNoZXIuZXhhY3QiLCAiY2hpLnNxdWFyZSIpLA0KICDDnV9uZ2jEqWEgPSBjKA0KICAgICJLaeG7g20gxJHhu4tuaCBoYWkgcGjDrWEg4oCTIGtp4buDbSB0cmEgeGVtIFJSIGPDsyBraMOhYyAxLiDEkMOieSBsw6AgbG/huqFpIGtp4buDbSDEkeG7i25oIHBo4buVIGJp4bq/biBuaOG6pXQuIiwNCiAgICAiS2nhu4NtIMSR4buLbmggY2jDrW5oIHjDoWMg4oCTIGNobyBwLXZhbHVlIGNow61uaCB4w6FjIGThu7FhIHRyw6puIHBow6JuIHBo4buRaSBjaMOtbmggeMOhYy4iLA0KICAgICJGaXNoZXLigJlzIGV4YWN0IHRlc3Qg4oCTIGTDuW5nIHRyb25nIGLhuqNuZyAyeDIgduG7m2kgY+G7oSBt4bqrdSBuaOG7jy4iLA0KICAgICJDaGktc3F1YXJlZCB0ZXN0IOKAkyBraeG7g20gxJHhu4tuaCB44bqlcCB44buJIHBow6JuIHBo4buRaSBjaHXhuqluLCBkw7luZyBraGkgbeG6q3UgxJHhu6cgbOG7m24uIg0KICApDQopDQoNCiMgSW4gYuG6o25nDQprYWJsZShleHBsYW5hdGlvbiwgYWxpZ24gPSAibCIpDQpgYGANCg0KKipL4bq/dCBxdeG6oyoqDQoNClThu7cgc+G7kSBuZ3V5IGPGoSAoUlIpID0gMi43NSDihpIgTmFtIGdp4bubaSBjw7Mgbmd1eSBjxqEgxJHhuqF0IHRodSBuaOG6rXAgdHLDqm4gNTBLIGNhbyBn4bqlcCAyLjc1IGzhuqduIHNvIHbhu5tpIG7hu68gZ2nhu5tpLg0KDQpLaG/huqNuZyB0aW4gY+G6rXkgOTUlID0gWzIuNTksIDIuOTNdIOKGkiBLaMO0bmcgYmFvIGfhu5NtIDEg4oaSIOKGkiBz4buxIGtow6FjIGJp4buHdCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLg0KDQpQLXZhbHVlIOKJiCAwIOG7nyB04bqldCBj4bqjIGPDoWMgcGjGsMahbmcgcGjDoXAga2nhu4NtIMSR4buLbmggKG1pZHAuZXhhY3QsIEZpc2hlciwgY2hpLXNxdWFyZSkg4oaSIFLhuqV0IG5o4buPIGjGoW4gMC4wNSDihpIgY8OzIGLhurFuZyBjaOG7qW5nIHRo4buRbmcga8OqIG3huqFuaCB24buBIHPhu7Ega2jDoWMgYmnhu4d0IGdp4buvYSBuYW0gdsOgIG7hu68uDQoNCioqS+G6v3QgbHXhuq1uKioNCkThu7FhIHRyw6puIGvhur90IHF14bqjIHBow6JuIHTDrWNoLCBuYW0gZ2nhu5tpIGPDsyB4w6FjIHN14bqldCDEkeG6oXQgbeG7qWMgdGh1IG5o4bqtcCBjYW8gKD41MEspIGNhbyBoxqFuIMSRw6FuZyBr4buDIHNvIHbhu5tpIG7hu68gZ2nhu5tpIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgbsOgeS4gVOG7tyBz4buRIG5ndXkgY8ahIGzDoCAyLjc1IHbhu5tpIGtob+G6o25nIHRpbiBj4bqteSBo4bq5cCB2w6AgZ2nDoSB0cuG7iyBwIGfhuqduIGLhurFuZyAwIGNobyB0aOG6pXkgc+G7sSBraMOhYyBiaeG7h3QgbMOgIHLDtSByw6BuZyB2w6AgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqi4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgZ2nhu5tpIHTDrW5oIGzDoCBt4buZdCB54bq/dSB04buRIGPDsyDhuqNuaCBoxrDhu59uZyDEkcOhbmcga+G7gyDEkeG6v24ga2jhuqMgbsSDbmcgxJHhuqF0IMSRxrDhu6NjIG3hu6ljIHRodSBuaOG6rXAgY2FvLCDDrXQgbmjhuqV0IGzDoCB0cm9uZyBwaOG6oW0gdmkgbeG6q3Uga2jhuqNvIHPDoXQgxJHGsOG7o2Mgc+G7rSBk4bulbmcuDQoNCg0KIyMjIFThu7cgc+G7kSBDaMOqbmggKE9kZHMgUmF0aW8gLSBPUikNCg0KYGBge3J9DQpvcl9yZXN1bHQyIDwtIG9kZHNyYXRpbyh0YWJsZV9HZW5kZXJfRWFybmluZ0NsYXNzKQ0KcHJpbnQob3JfcmVzdWx0MikNCg0KYGBgDQpL4bq/dCBxdeG6oyBwaMOibiB0w61jaCBPZGRzIFJhdGlvICh04bu3IHPhu5EgY2jDqm5oKSB0cm9uZyDhuqNuaCBjaG8gdGjhuqV5IG3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIGdp4bubaSB0w61uaCAobmFtL27hu68pIHbDoCBraOG6oyBuxINuZyDEkeG6oXQgbeG7qWMgdGh1IG5o4bqtcCBjYW8gaMahbiA1MEsgdHJvbmcgYuG7mSBk4buvIGxp4buHdS4gROG7sWEgdsOgbyBi4bqjbmcgdOG6p24gc+G7kSBjaMOpbywgdGEgdGjhuqV5IHRyb25nIHThu5VuZyBz4buRIDI1Ljk5OCBuZ8aw4budaSDEkcaw4bujYyBraOG6o28gc8OhdCwgY8OzIDguNTE1IGzDoCBu4buvIHbDoCAxNy40ODMgbMOgIG5hbS4gVHJvbmcgxJHDsywgY2jhu4kgY8OzIDk4OSBu4buvIGdp4bubaSBjw7MgdGh1IG5o4bqtcCB0csOqbiA1MEsgKGNoaeG6v20ga2hv4bqjbmcgMTEuNiUpLCB0cm9uZyBraGkgNS41OTQgbmFtIGdp4bubaSDEkeG6oXQgxJHGsOG7o2MgbeG7qWMgdGh1IG5o4bqtcCBuw6B5IChjaGnhur9tIGtob+G6o25nIDMyJSkuDQoNCkThu7FhIHRyw6puIGPDoWMgY29uIHPhu5EgbsOgeSwgcGjDom4gdMOtY2ggT2RkcyBSYXRpbyDEkcaw4bujYyB0aOG7sWMgaGnhu4duIG5o4bqxbSDEkW8gbMaw4budbmcgbeG7qWMgxJHhu5kgY2jDqm5oIGzhu4djaCB24buBIGto4bqjIG7Eg25nIGPDsyB0aHUgbmjhuq1wIGNhbyBnaeG7r2EgaGFpIG5ow7NtIGdp4bubaSB0w61uaC4gVOG7tyBz4buRIGNow6puaCBPUiBjaG8gbmFtIGdp4bubaSBsw6AgMy41Nzk5NCwgduG7m2kga2hv4bqjbmcgdGluIGPhuq15IDk1JSBu4bqxbSB0cm9uZyBraG/huqNuZyBbMy4zMjc2Njk7IDMuODU0OTk5XS4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIG5hbSBnaeG7m2kgY8OzIGto4bqjIG7Eg25nIMSR4bqhdCBt4bupYyB0aHUgbmjhuq1wIHRyw6puIDUwSyBjYW8gZ+G6pXAga2hv4bqjbmcgMy41OCBs4bqnbiBzbyB24bubaSBu4buvIGdp4bubaSwgc2F1IGtoaSBzbyBzw6FuaCB04bu3IGzhu4cgb2RkcyAoeMOhYyBzdeG6pXQgeOG6o3kgcmEgc28gduG7m2kga2jDtG5nIHjhuqN5IHJhKSB0cm9uZyB04burbmcgbmjDs20uIFRyb25nIGtoaSDEkcOzLCBPUiBj4bunYSBu4buvIGdp4bubaSDEkcaw4bujYyBj4buRIMSR4buLbmggbMOgIDEgxJHhu4MgbMOgbSBt4buRYyB0aGFtIGNoaeG6v3UsIGRvIMSRw6J5IGzDoCBuaMOzbSBjxqEgc+G7ny4NCg0KS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gT1IgY+G7p2EgbmFtIGtow7RuZyBiYW8gZ+G7k20gZ2nDoSB0cuG7iyAxLCBjaG8gdGjhuqV5IHPhu7Ega2jDoWMgYmnhu4d0IGdp4buvYSBoYWkgZ2nhu5tpIGzDoCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLiBC4bqxbmcgY2jhu6luZyBjaG8gxJFp4buBdSBuw6B5IGPDoG5nIHLDtSByw6BuZyBraGkgdGEgeMOpdCDEkeG6v24gY8OhYyBnacOhIHRy4buLIHAtdmFsdWUgcuG6pXQgbmjhu486IHBoxrDGoW5nIHBow6FwIG1pZHAuZXhhY3QgY2hvIHJhIGdpw6EgdHLhu4sgMy44NzU4NjhlLTMwMyB2w6Aga2nhu4NtIMSR4buLbmggY2hpIGLDrG5oIHBoxrDGoW5nIChjaGktc3F1YXJlKSBjxaluZyBjaG8ga+G6v3QgcXXhuqMgcC12YWx1ZSAxLjUzMjU1OWUtMjc1IOKAkyDEkeG7gXUgbmjhu48gaMahbiBy4bqldCBuaGnhu4F1IHNvIHbhu5tpIG3hu6ljIMO9IG5naMSpYSBwaOG7lSBiaeG6v24gbMOgIDAuMDUuIMSQaeG7gXUgxJHDsyBjaG8gcGjDqXAgdGEgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAgKHLhurFuZyBraMO0bmcgY8OzIHPhu7Ega2jDoWMgYmnhu4d0IHbhu4Ega2jhuqMgbsSDbmcgY8OzIHRodSBuaOG6rXAgY2FvIGdp4buvYSBuYW0gdsOgIG7hu68pIHbDoCBjaOG6pXAgbmjhuq1uIGdp4bqjIHRodXnhur90IEjigoE6IGdp4bubaSB0w61uaCB0aOG7sWMgc+G7sSBjw7Mg4bqjbmggaMaw4bufbmcgxJHhur9uIG3hu6ljIHRodSBuaOG6rXAgY2FvIHRyb25nIG3huqt1IGto4bqjbyBzw6F0Lg0KDQpN4buZdCDEkWnhu4NtIHF1YW4gdHLhu41uZyBraMOhYyBsw6Aga+G6v3QgcXXhuqMgbsOgeSBraMO0bmcgw6FwIGThu6VuZyBwaMawxqFuZyBwaMOhcCBoaeG7h3UgY2jhu4luaCAoY29ycmVjdGlvbiA9IEZBTFNFKSwgxJHhu5NuZyBuZ2jEqWEgduG7m2kgdmnhu4djIGNoxrBhIMSRaeG7gXUgY2jhu4luaCBjaG8gY8OhYyB54bq/dSB04buRIGfDonkgbmhp4buFdSBob+G6t2Mgc2FpIHPhu5EgdGhp4bq/dCBr4bq/LiBUdXkgbmhpw6puLCB24bubaSBt4buZdCBwLXZhbHVlIHLhuqV0IG5o4buPIG5oxrAgduG6rXkgdsOgIGtob+G6o25nIHRpbiBj4bqteSBraMOhIGjhurlwLCBjw7MgdGjhu4MgbsOzaSBy4bqxbmcgc+G7sSBraMOhYyBiaeG7h3QgbsOgeSBsw6AgbeG6oW5oIG3hur0gdsOgIMSRw6FuZyB0aW4gY+G6rXkuDQoNClThu6sga+G6v3QgcXXhuqMgdHLDqm4sIHRhIGPDsyB0aOG7gyByw7p0IHJhIG5o4bqtbiDEkeG7i25oIHLhurFuZyBuYW0gZ2nhu5tpIGPDsyBuaGnhu4F1IGto4bqjIG7Eg25nIMSR4bqhdCDEkcaw4bujYyBt4bupYyB0aHUgbmjhuq1wIGNhbyBoxqFuIG7hu68gZ2nhu5tpLCB4w6l0IHRyw6puIGThu68gbGnhu4d1IGhp4buHbiB04bqhaS4gVHV5IG5oacOqbiwgxJHDonkgbeG7m2kgY2jhu4kgbMOgIHBow6JuIHTDrWNoIMSRxqFuIGJp4bq/biBnaeG7r2EgZ2nhu5tpIHTDrW5oIHbDoCB0aHUgbmjhuq1wLiBUcm9uZyBi4buRaSBj4bqjbmggbmdoacOqbiBj4bupdSB0aOG7sWMgdOG6vywgxJHhu4MgxJFpIMSR4bq/biBr4bq/dCBsdeG6rW4gY2jDrW5oIHjDoWMgdsOgIGtow6FjaCBxdWFuIGjGoW4sIHRhIG7Dqm4gdGjhu7FjIGhp4buHbiB0aMOqbSBjw6FjIHBow6JuIHTDrWNoIGtp4buDbSBzb8OhdCBjw6FjIGJp4bq/biBuaGnhu4V1IGtow6FjIG5oxrAgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuLCBuZ8Ogbmggbmdo4buBLCBnaeG7nSBsw6BtIHZp4buHYywgdsOgIGtodSB24buxYyDEkeG7i2EgbMO9LiBLaGkgZ2nhuqNuZyBk4bqheSwgZ2nhuqNuZyB2acOqbiBjw7MgdGjhu4MgZMO5bmcgdsOtIGThu6UgbsOgeSDEkeG7gyBnaeG7m2kgdGhp4buHdSBjaG8gc2luaCB2acOqbiBraMOhaSBuaeG7h20gb2Rkcywgb2RkcyByYXRpbywga2hv4bqjbmcgdGluIGPhuq15IHbDoCBraeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dCwgxJHhu5NuZyB0aOG7nWkgbmjhuqVuIG3huqFuaCB04bqnbSBxdWFuIHRy4buNbmcgY+G7p2Egdmnhu4djIGdp4bqjaSB0aMOtY2gga+G6v3QgcXXhuqMgdGjhu5FuZyBrw6ogdHJvbmcgbmfhu68gY+G6o25oIHjDoyBo4buZaSBo4buNYyB2w6AgY2jDrW5oIHPDoWNoLg0KKipUw7NtIHThuq90IG5o4bqtbiB4w6l0KiogDQpE4buvIGxp4buHdSB0w7NtIHThuq90Og0KDQpO4buvOiA3NTI2IG5nxrDhu51pIGPDsyB0aHUgbmjhuq1wIOKJpDUwSywgOTg5IG5nxrDhu51pID41MEsuDQoNCk5hbTogMTEuODg5IG5nxrDhu51pIOKJpDUwSywgNS41OTQgbmfGsOG7nWkgPjUwSy4NCg0KVOG7tyBz4buRIGNow6puaCAoT2RkcyBSYXRpbyDigJMgT1IpOg0KDQpPUiBj4bunYSBuYW0gc28gduG7m2kgbuG7ryA9IDMuNTgsIG5naMSpYSBsw6A6DQoNCk5hbSBnaeG7m2kgY8OzIGto4bqjIG7Eg25nIMSR4bqhdCB0aHUgbmjhuq1wID41MEsgY2FvIGfhuqVwIDMuNTggbOG6p24gc28gduG7m2kgbuG7ryBnaeG7m2kuDQoNCktob+G6o25nIHRpbiBj4bqteSA5NSUgKENJKToNCg0KT1IgbuG6sW0gdHJvbmcga2hv4bqjbmcgWzMuMzM7IDMuODVdIOKGkiBjaOG6r2MgY2jhuq9uIGPDsyBz4buxIGNow6puaCBs4buHY2ggdGjhu7FjIHPhu7EgZ2nhu69hIGhhaSBnaeG7m2kuDQoNClAtdmFsdWUgcuG6pXQgbmjhu48gKOKJiCAwKToNCg0KQ8OzIGLhurFuZyBjaOG7qW5nIG3huqFuaCDEkeG7gyBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSOKCgCwga2jhurNuZyDEkeG7i25oIGdp4bubaSB0w61uaCBjw7Mg4bqjbmggaMaw4bufbmcgxJHhur9uIHRodSBuaOG6rXAgY2FvLg0KDQpHaeG6oyBz4butIHRhIGPDsyBi4bqjbmcgZOG7ryBsaeG7h3UgbmjGsCBzYXU6DQoNCj41MEsgKFRodSBuaOG6rXAgY2FvKQniiaQ1MEsgKFRodSBuaOG6rXAgdGjhuqVwKQ0KTuG7ryAoRmVtYWxlKQlhID0gOTg5CWIgPSA3NTI2DQpOYW0gKE1hbGUpCWMgPSA1NTk0CWQgPSAxMTg4OQ0K