Các biểu
đồ
Biểu đồ
1
library(datasets)
data("ChickWeight")
ga <- ChickWeight
diet_counts <- table(ga$Diet)
pie(diet_counts, labels = paste(names(diet_counts), " (", diet_counts, ")", sep = ""),
main = "Số lượng gà con theo Diet")

giải thích biểu đồ 1
Biểu đồ
2
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ggplot(ga, aes(x = weight, fill = factor(Diet))) +
geom_density(alpha = 0.5) +
labs(x = "Weight", y = "Density", fill = "Diet") +
ggtitle("Density plot của trọng lượng gà con theo loại khẩu phần")
giải thích biểu đồ 2
Biểu đồ cho ta thấy sự phân bố trọng lượng trong mỗi nhóm với
từng loại khẩu phần dinh dưỡng cho gà con riêng biệt
Mật độ loại một chiếm rất cao và dày trong khoảng từ 100 đến nửa
200g rồi làm giảm một cách rõ rệt, tiếp đó là loại 2 và xuống lần tới
loại 3,4
Khoang có sự chênh lệnh quá lớn từ khoảng nửa 100 đến 200g trở đi
của khẩu phần 1, 2, 3, Loại dinh dưỡng 4 ảnh hưởng lớn đến cân nặng từ
100 đến 200g của gà con
Biểu đồ
3
library(datasets)
data("ChickWeight")
ga <- ChickWeight
diet_proportions <- prop.table(table(ga$Diet)) * 100
pie(diet_proportions, labels = paste0(names(diet_proportions), ": ", round(diet_proportions, 2), "%"),
main = "Tỉ lệ dinh dưỡng theo Diet")

Giải thích biểu đồ 3
prop.table(table(chickweight$Diet)) * 100: Đầu tiên, chúng ta sử dụng
hàm table() để đếm số lượng mẫu trong từng loại thức ăn (Diet). Sau đó,
prop.table() được sử dụng để tính toán tỷ lệ phần trăm của mỗi loại thức
ăn. Cuối cùng, chúng ta nhân với 100 để chuyển đổi sang tỷ lệ phần
trăm.
labels = paste0(names(diet_proportions), “:”, round(diet_proportions,
2), “%”): Chúng ta sử dụng hàm paste0() để kết hợp tên của các loại thức
ăn với tỷ lệ phần trăm tương ứng, và định dạng số liệu với hai chữ số
thập phân. Điều này giúp hiển thị nhãn cho các phần trong biểu đồ pie
chart.
main = “Tỉ lệ dinh dưỡng theo Diet”: Đây là tiêu đề cho biểu đồ pie
chart, cho biết rằng biểu đồ này thể hiện tỷ lệ dinh dưỡng theo từng
loại thức ăn.
Biểu đồ
4
diet_proportions <- prop.table(table(ga$Diet)) * 100
barplot(diet_proportions,
main = "Tỉ lệ dinh dưỡng theo Diet",
xlab = "Diet",
ylab = "Tỷ lệ phần trăm")
Giải thích đồ thị 4
prop.table(table(ga$Diet)) * 100: Chúng ta sử dụng hàm table() để đếm
số lượng mẫu trong từng loại thức ăn (Diet). Sau đó, prop.table() được
sử dụng để tính toán tỷ lệ phần trăm của mỗi loại thức ăn. Cuối cùng,
chúng ta nhân với 100 để chuyển đổi sang tỷ lệ phần trăm.
barplot(diet_proportions, main = “Tỉ lệ dinh dưỡng theo Diet”, xlab =
“Diet”, ylab = “Tỷ lệ phần trăm”): Hàm barplot() được sử dụng để tạo
biểu đồ bar chart. Đối số đầu tiên là vector chứa tỷ lệ phần trăm của
từng loại thức ăn. Các đối số tiếp theo được sử dụng để đặt tiêu đề cho
biểu đồ (main), nhãn trục x (xlab) và nhãn trục y (ylab).
Biểu đồ
5
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ggplot(ga, aes(x = Time, y = weight, color = factor(Diet))) +
geom_point() +
labs(x = "Thời gian quan sát", y = "Cân nặng", color = "Diet") +
ggtitle("Tương quan giữa cân nặng và thời gian quan sát theo Diet")
Giải thích biểu đồ 5 Biểu đồ scatterplot mà chúng ta
vừa tạo thể hiện mối quan hệ giữa cân nặng của gà con và thời gian quan
sát, với sự phân biệt được thực hiện theo từng loại Diet khác nhau. Dưới
đây là giải thích ý nghĩa của biểu đồ này:
Trục X (Thời gian quan sát): Trục này biểu diễn thời gian quan sát gà
con. Mỗi điểm trên trục này đại diện cho một thời điểm cụ thể trong quá
trình quan sát.
Trục Y (Cân nặng): Trục này biểu diễn cân nặng của gà con tại thời
điểm tương ứng. Mỗi điểm trên trục này thể hiện cân nặng của một con gà
tại một thời điểm cụ thể.
Màu sắc (Diet): Biểu đồ sử dụng màu sắc để phân biệt các nhóm Diet
khác nhau. Mỗi màu đại diện cho một loại Diet. Điều này giúp chúng ta
nhận biết mối quan hệ giữa cân nặng và thời gian quan sát được phân loại
theo từng loại Diet.
Điểm (scatter points): Mỗi điểm trên biểu đồ đại diện cho một con gà
và vị trí của nó trên trục x và trục y thể hiện thời gian quan sát và
cân nặng của gà con tương ứng. Bằng cách này, chúng ta có thể quan sát
mối quan hệ giữa cân nặng và thời gian quan sát của gà con, và xem xét
liệu có sự khác biệt nào giữa các nhóm Diet hay không.
Biểu đồ scatterplot này giúp chúng ta nhận ra mối quan hệ giữa cân
nặng của gà con và thời gian quan sát, và liệu mối quan hệ này có sự
khác biệt giữa các nhóm Diet hay không.
Biểu đồ
6
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ga %>% ggplot(aes(x = weight, y = Time, color = Diet)) + #Sử dụng dữ liệu từ ck tạo một bảng dữ liệu mới trong gói ggplot, thiết lập trục x, y, phân loại các điểm theo từng loại dinh dưỡng và phân bố màu cho chúng
geom_point() + #Thêm các điểm vào biểu đồ, mỗi điểm là một quan sát được đối chiếu theo trục x và y
labs( x = 'cân nặng gà con', y = 'Thời gian quan sát', title = 'Tương quan giữa gà con và cân nặng theo loại dinh dưỡng') + #Đặt nhãn cho trục x và y, thiết lập lại tên tiêu đề mới cho vùng dữ liêụ
geom_smooth(method = 'lm', color = 'red') + #Thêm đường phù hợp tuyến tính, bằng phương pháp hồi quy tuyến tính
facet_wrap(~Diet) #Phân loại các bảng nhỏ hơn theo loại Diet
## `geom_smooth()` using formula = 'y ~ x'

Giải thích đồ thị 6
Cân nặng gà con tùy theo từng loại dinh dưỡng có xu hướng tăng theo
thời gian quan sát
Biểu đồ
7
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ga %>% group_by(Diet) %>% summarise(n=mean(weight)) %>%
ggplot(aes(x= '', y=n, fill = Diet))+
geom_col(color = 'green', width = 1) +
coord_polar('y') +
geom_text(aes(x = 1.3, label = round(n,2)), position = position_stack(vjust = .5)) +
labs( title = 'Trọng lượng trung bình') +
theme_void()
Giải thích biểu đồ 6
ga %>% group_by(Diet) %>% summarise(n=mean(weight)) %>% #Tạo
bảng dữ liệu mới các các cộng Diet và tính lượng trung bình
ggplot(aes(x= ’‘, y=n, fill = Diet))+ #Bắt đầu một biểu đồ sử dụng gói
ggplot với trục x không có dữ liệu, trục y là các phần tử n, và màu sắc
được thêm vào phân biệt các loại Diet geom_col(color = ’green’, width =
1) + #Thêm các cột vào biểu đồ, mỗi cột là một loại dinh dưỡng cũng như
độ rộng là 1 coord_polar(‘y’) + #Chuyển đổi biểu đồ thành hệ tọa độ cực,
biểu thị các phần tương đối trong một vòng tròn geom_text(aes(x = 1.3,
label = round(n,2)), position = position_stack(vjust = .5)) + #Các nhãn
sẽ đật ở vị trí 1.3 trên trục x, trục y, tính giá trị trung bình và lấy
hai giá trị sau đó, hiển thị số lượng và các nhãn được chồng với nhau
lên căn chỉnh ở vị trí .5 labs( title = ‘Trọng lượng trung bình’) +
#Thêm phần tiêu đề vào vùng vẽ biểu đồ theme_void() #Loại bỏ các phần
mặc định của giao diện của biểu đồ, chỉ hiển thị dữ liệu và các yếu tố
trực tiếp liên quan đến nó.
Biểu đồ thể hiện trọng lượng gà con trung bình theo từng loại dinh
dưỡng Loại 1 có trọng lượng trung bình là 102.65, loại 2 là 122.62, loại
3 là 142.95, loại 4 là 135.26
Biểu đồ
8
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ga %>% ggplot(aes(x = weight, y = Time, color = Diet)) +
geom_point() +
labs( x = 'cân nặng gà con', y = 'Thời gian quan sát', title = 'Tương quan giữa gà con và cân nặng theo loại dinh dưỡng') +
geom_smooth(method = 'lm', color = 'red')
## `geom_smooth()` using formula = 'y ~ x'
Giải thích đồ thị 8
ck %>% ggplot(aes(x = weight, y = Time, color = Diet)) + #Sử dụng
dữ liệu từ ck tạo một bảng dữ liệu mới trong gói ggplot, thiết lập trục
x, y, phân loại các điểm theo từng loại dinh dưỡng và phân bố màu cho
chúng geom_point() + #Thêm các điểm vào biểu đồ, mỗi điểm là một quan
sát được đối chiếu theo trục x và y labs( x = ‘cân nặng gà con’, y =
‘Thời gian quan sát’, title = ‘Tương quan giữa gà con và cân nặng theo
loại dinh dưỡng’) + #Đặt nhãn cho trục x và y, thiết lập lại tên tiêu đề
mới cho vùng dữ liêụ geom_smooth(method = ‘lm’, color = ‘black’)
Đường trend line có xu hướng lên trên, mối tương quan dương giữa các
dữ liệu Với cân nặng gà con lớn, phải bổ sung dinh dưỡng theo đó mà thời
gian quan sát cũng sẽ phải tăng lên
Biểu đồ
9
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ga %>% group_by(Diet) %>% summarise(n = n()) %>%
ggplot(aes(x = '', y = n,fill = Diet)) + #
geom_col( color = 'black' ) +
geom_text(aes(label = n),position = position_stack(vjust = 1)) +
labs( y = 'số lượng', title = 'số lượng gà con cho mỗi chế độ dinh dưỡng')

Giải thích biểu đồ 9
ck %>% group_by(Diet) %>% summarise(n = n()) %>% #Nhóm các
dòng dữ liệu của ck theo cột Diet, sau đó tính tổng số lượng cho mỗi
nhóm ggplot(aes(x = ’‘, y = n,fill = Diet)) + #Sử dụng dữ liệu từ bước
trước thiết lập biểu đồ với trục x là không có dữ liệu, y là n, màu sắc
đc ánh xạ vào Diet geom_col( color = ’black’ ) + #Thêm các cột vào biểu
đồ, với màu được thiết lập là màu đen geom_text(aes(label = n),position
= position_stack(vjust = 1)) + #Thêm nhãn vào biểu đồ, hiển thị số lượng
gà con trên mỗi cột, căn chỉnh vị trí dọc các nhãn, đặt trên cùng mỗi
cột labs( y = ‘số lượng’, title = ‘số lượng gà con cho mỗi chế độ dinh
dưỡng’) #Thiết lập nhãn cho trụ y, tiêu đề của vùng dữ liệu được vẽ
Biểu đồ thể hiện cho ta thấy số lượng gà con theo từng loại dinh
dưỡng, các số liệu được chồng theo một cột và tùy theo số lượng mà độ
dày khác nhau Loại dinh dưỡng 1 có độ dày chiếm ưu thế, số lượng nhiều
nhất, 3 loại kia không chênh lệch đáng kể
Biểu đồ
10
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ga %>% ggplot( aes(x = weight, fill = as.factor(Diet))) +
geom_density(alpha = 0.5) +
facet_wrap(~Diet) +
labs(title = "Density plot của trọng lượng gà con theo loại khẩu phần", x = "Trọng lượng (grams)", y = "Mật độ") +
scale_fill_discrete(name = "Loại khẩu phần")

Giải thích biểu đồ 10
ga %>% ggplot( aes(x = weight, fill = as.factor(Diet))) +
geom_density(alpha = 0.5) + # Thiết lập độ mờ của các đường density
facet_wrap(~Diet) + #Phân tổ các biểu đồ nhỏ hơn theo Diet labs(title =
“Density plot của trọng lượng gà con theo loại khẩu phần”, x = “Trọng
lượng (grams)”, y = “Mật độ”) + scale_fill_discrete(name = “Loại khẩu
phần”) # Thêm chú thích cho fill
Tương tự như biểu đồ trên, mỗi phần nhỏ chỉ ra mật độ trọng lượng khi
cho các loại khẩu phần riêng biệt đối với gà con Loại khẩu phần 1 với
trọng lượng gà con 100g đổ lại rất nhiều
Biểu đồ
11
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ga %>% group_by(Diet) %>% summarise(avg = mean(weight)) %>%
ggplot(aes(x = as.factor(Diet), y = avg)) +
geom_col(fill = 'orange') +
geom_text(aes(label = round(avg,2)), vjust = 1, color = 'red') +
labs( x = 'loại Diet', y = 'Trọng lượng gà con trung bình (gram)', title = 'trọng lượng gà con trung bình theo Diet') +
coord_flip()

Giải thích biểu đồ 11 ga %>% group_by(Diet)
%>% summarise(avg = mean(weight)) %>% #Sử dụng dữ liệu từ ck nhóm
cột Diet cũng nhưng tính cân nặng trung bình của cột weight ggplot(aes(x
= as.factor(Diet), y = avg)) + #Bắt đầu một biểu đồ sử dụng gói ggplot
với trục x là Diet, trục y là lượng trung bình geom_col(fill = ‘orange’)
+ #Thêm các cột vào biểu đồ, thiết lập màu các cột là orange
geom_text(aes(label = round(avg,2)), vjust = 1, color = ‘red’) + #Thêm
nhãn về lượng trung bình vào mỗi cột, thiết lập sau dấu phẩy chỉ lấy 2
chữ số, căn chỉnh độ dọc của của nhãn cũng như màu sắc là đỏ labs( x =
‘loại Diet’, y = ‘Trọng lượng gà con trung bình (gram)’, title = ‘trọng
lượng gà con trung bình theo Diet’) + #Đặt nhãn cho trục x, y cũng như
tiêu đề của vùng dữ liệu được vẽ coord_flip() #Đảo ngược trục của biểu
đồ, từ dọc thành ngang và ngược lại
## Biểu đồ 12
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ggplot(ga, aes(x = Time, y = weight, color = factor(Diet))) +
geom_line() +
labs(x = "Thời gian", y = "Cân nặng", color = "Diet") +
ggtitle("Biểu đồ liên quan giữa thời gian và Diet")
Giải thích biểu đồ 12
Trục X (Thời gian): Trục này biểu diễn các đơn vị thời gian (ngày,
tuần, vv.) của quá trình quan sát gà con. Mỗi điểm trên trục này tương
ứng với một thời điểm cụ thể trong quá trình quan sát.
Trục Y (Cân nặng): Trục này biểu diễn cân nặng của gà con tại từng
thời điểm được quan sát. Mỗi điểm trên trục này thể hiện giá trị cân
nặng tại thời điểm tương ứng.
Màu sắc (Diet): Biểu đồ sử dụng màu sắc để phân biệt các nhóm Diet
khác nhau. Mỗi màu đại diện cho một loại Diet. Điều này giúp chúng ta
nhìn nhận mối quan hệ giữa thời gian và cân nặng được phân loại theo
từng nhóm Diet.
Đường (Lines): Mỗi đường trên biểu đồ thể hiện sự biến đổi của cân
nặng theo thời gian cho mỗi nhóm Diet. Điều này giúp chúng ta quan sát
xu hướng tăng/giảm của cân nặng trong từng nhóm Diet theo thời gian.
Biểu đồ này giúp chúng ta hiểu được mối quan hệ giữa thời gian và cân
nặng của gà con, đồng thời cho phép so sánh sự biến đổi của cân nặng
giữa các nhóm Diet khác nhau.
Biểu đồ
13
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ga %>% ggplot(aes(x = weight)) +
geom_histogram(binwidth = 50, fill = "blue", color = "black", aes(y=..count..)) +
labs(x = "Trọng lượng (g)", y = "Tần suất") +
ggtitle("Phân phối của trọng lượng gà con") +
theme_minimal()
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

giải thích biểu đồ 13
ck %>% ggplot(aes(x = weight)) + #Bắt đầu một biểu đồ ggplot với
trục x được thiết lập là cột “weight” geom_histogram(binwidth = 50, fill
= “skyblue”, color = “black”, aes(y=..count..)) + #Thiết lập dữ liệu
hiển thị dưới dạng histogram, đặt chiều rộng bin, màu nền và viền, sử
dụng tần suất tuyệt đối labs(x = “Trọng lượng (g)”, y = “Tần suất”) +
#Thiết lập nhãn cho trục x và trục y ggtitle(“Phân phối của trọng lượng
gà con”) + #Thiết lập tiêu đề cho biểu đồ theme_minimal() #Chọn giao
diện đơn giản, đường lưới cho biểu đồ
Biểu đồ cho thấy tần suất suất hiện các chỉ số trọng lượng gà con tần
suất xuất hiện của trọng lượng dưới 100g xuất hiện nhiều nhất hơn 200
lần và giảm dần
Biểu đồ
14
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ga %>% ggplot(aes(x = weight)) +
geom_histogram(binwidth = 50, fill = "green", color = "black", aes(y=..count..)) +
labs(x = "Trọng lượng (g)", y = "Tần suất") +
facet_wrap(~Diet) +
ggtitle("Phân phối của trọng lượng gà con")

Giiar thích đồ thị 14
ck %>% ggplot(aes(x = weight)) + #Bắt đầu một biểu đồ ggplot với
trục x được thiết lập là cột “weight” geom_histogram(binwidth = 50, fill
= “skyblue”, color = “black”, aes(y=..count..)) + #Thiết lập dữ liệu
hiển thị dưới dạng histogram, đặt chiều rộng bin, màu nền và viền, sử
dụng tần suất tuyệt đối labs(x = “Trọng lượng (g)”, y = “Tần suất”) +
#Thiết lập nhãn cho trục x và trục y facet_wrap(~Diet) + #Phân loại các
bảng nhỏ theo loại Diet ggtitle(“Phân phối của trọng lượng gà con”)
#Thiết lập tiêu đề cho biểu đồ
Biểu đồ cho ra thấy chỉ số xuất hiện của các chỉ số trọng lượng gà
con được phân ra theo loại dinh dưỡng
Biểu đồ
15
library(tidyverse)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
ga %>% ggplot(aes(x = Time)) +
geom_histogram(binwidth = 3, fill = "pink", color = "black", aes(y=..count..)) +
labs(x = "Thời gian (h)", y = "Tần suất") +
ggtitle("Phân phối của thời gian theo dõi gà con") +
theme_minimal()

Giải thích biểu đồ 15 ga %>% ggplot(aes(x =
Time)) + #Bắt đầu một biểu đồ ggplot với trục x được thiết lập là cột
“Time” geom_histogram(binwidth = 3, fill = “pink”, color = “black”,
aes(y=..count..)) + #Thiết lập dữ liệu hiển thị dưới dạng histogram, đặt
chiều rộng bin là 5, màu nền và màu viền labs(x = “Thời gian (h)”, y =
“Tần suất”) + #Thiết lập nhãn cho trục x và y ggtitle(“Phân phối của
thời gian theo dõi gà con”) + #Thiết lập tiêu đề cho biểu đồ
theme_minimal() #Giao diện dạng lưới
Biểu đố cho ta thấy các tần suất các khoảng thời gian xuất hiện
Khoảng thời gian xuất hiện nhiều nhất từ 0 đến 5 và giảm dần về 20
Biểu đồ
16
library(ggplot2)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
average_weight <- aggregate(weight ~ Time,ga, FUN = mean)
ggplot(average_weight, aes(x = Time, y = weight)) +
geom_line() +
labs(x = "Thời gian", y = "Trọng lượng tb") +
ggtitle("Biểu đồ trọng lượng tb qua các mốc thời gian")

Giải thích biểu đò 16
aggregate(weight ~ Time, data = chickweight, FUN = mean): Chúng ta sử
dụng hàm aggregate() để tính trọng lượng trung bình theo các mốc thời
gian. Đối số weight ~ Time chỉ định rằng chúng ta muốn tính trung bình
của trọng lượng theo thời gian. data = chickweight chỉ ra bộ dữ liệu, và
FUN = mean chỉ định rằng chúng ta muốn tính trung bình.
ggplot(average_weight, aes(x = Time, y = weight)): Đây là bước khởi
tạo biểu đồ sử dụng gói ggplot2. Chúng ta sử dụng bộ dữ liệu
average_weight (đã tính toán trước đó) và định nghĩa các mối quan hệ
aesthetics (mỹ phẩm) cho biểu đồ. Trục x là thời gian và trục y là trọng
lượng trung bình.
geom_line(): geom_line() được sử dụng để thêm các đường vào biểu đồ,
tạo thành biểu đồ line plot.
labs(x = “Thời gian”, y = “Trọng lượng trung bình”): Hàm labs() được
sử dụng để đặt tên cho các trục của biểu đồ. Trục x được gán là “Thời
gian”, và trục y được gán là “Trọng lượng trung bình”.
ggtitle(“Biểu đồ trọng lượng trung bình qua các mốc thời gian”): Hàm
ggtitle() được sử dụng để đặt tiêu đề cho biểu đồ. Trong trường hợp này,
tiêu đề được đặt là “Biểu đồ trọng lượng trung bình qua các mốc thời
gian”.
Biểu đồ
17
library(dplyr)
library(ggplot2)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
max_weight_by_diet <- ga %>%
group_by(Diet) %>%
summarise(max_weight = max(weight))
ggplot(max_weight_by_diet, aes(x = factor(Diet), y = max_weight, fill = factor(Diet))) +
geom_bar(stat = "identity") +
labs(x = "Diet", y = "Trọng lượng lớn nhất", fill = "Diet") +
ggtitle("Trọng lượng lớn nhất ở các loại dinh dưỡng")

Giải thích biểu đồ 17
Chúng ta sử dụng gói dplyr để tính toán trọng lượng lớn nhất theo mỗi
loại dinh dưỡng. Hàm group_by() được sử dụng để nhóm dữ liệu theo loại
dinh dưỡng, sau đó hàm summarise() tính toán trọng lượng lớn nhất cho
mỗi nhóm. Sau đó, chúng ta tạo biểu đồ cột sử dụng ggplot2. Trục x là
loại dinh dưỡng, trục y là trọng lượng lớn nhất, và màu sắc được sử dụng
để phân biệt các loại dinh dưỡng.
Biểu đồ
18
library(dplyr)
library(ggplot2)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
chickweight_time_20 <- ga %>%
filter(Time == 20)
average_weight_by_diet <- chickweight_time_20 %>%
group_by(Diet) %>%
summarise(average_weight = mean(weight))
ggplot(average_weight_by_diet, aes(x = factor(Diet), y = average_weight, fill = factor(Diet))) +
geom_bar(stat = "identity") +
labs(x = "Diet", y = "Trọng lượng trung bình", fill = "Diet") +
ggtitle("Trọng lượng trung bình ở thời điểm 20 của các loại dinh dưỡng")
giải thích biểu đồ 18
Đầu tiên, chúng ta lọc dữ liệu để chỉ giữ lại các quan sát tại thời
điểm 20 bằng cách sử dụng hàm filter() của gói dplyr. Tiếp theo, chúng
ta tính trọng lượng trung bình cho mỗi loại dinh dưỡng bằng cách sử dụng
hàm summarise() để tính toán giá trị trung bình cho từng nhóm. Cuối
cùng, chúng ta tạo biểu đồ cột sử dụng ggplot2, trong đó trục x là loại
dinh dưỡng, trục y là trọng lượng trung bình, và màu sắc được sử dụng để
phân biệt các loại dinh dưỡng
trọng lượng trung bình của dinh dưỡng loại 3 trong 20 ngày là tốt
nhất
Đồ thị
19
library(dplyr)
library(ggplot2)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
chickweight_weight_100 <- ga %>%
filter(weight == 100)
average_time_by_diet <- chickweight_weight_100 %>%
group_by(Diet) %>%
summarise(average_time = mean(Time))
# Tạo biểu đồ đường
ggplot(average_time_by_diet, aes(x = factor(Diet), y = average_time, group = 1)) +
geom_line() +
geom_point() +
labs(x = "Diet", y = "Thời gian trung bình (đạt trọng lượng 100)") +
ggtitle("Thời gian trung bình để đạt trọng lượng 100 theo loại dinh dưỡng")
Giải thích đồ thị 19
Chúng ta sử dụng gói dplyr để lọc dữ liệu và tính toán trung bình.
Đầu tiên, chúng ta lọc dữ liệu để chỉ giữ lại các quan sát có trọng
lượng bằng 100. Sau đó, chúng ta tính trung bình thời gian cho mỗi loại
dinh dưỡng bằng cách sử dụng hàm group_by() và summarise(). Tiếp theo,
chúng ta tạo biểu đồ đường sử dụng ggplot2. Trục x là loại dinh dưỡng,
trục y là thời gian trung bình (để đạt được trọng lượng 100), và chúng
ta sử dụng geom_line() và geom_point() để vẽ đường và điểm trên biểu
đồ.
Biểu đồ
20
library(dplyr)
library(ggplot2)
library(datasets)
data("ChickWeight")
ga <- ChickWeight
chick_counts_by_diet <- ga %>%
group_by(Diet) %>%
summarise(Count = n_distinct(Chick))
ggplot(chick_counts_by_diet, aes(x = factor(Diet), y = Count, fill = factor(Diet))) +
geom_bar(stat = "identity") +
labs(x = "Diet", y = "Số lượng Chick", fill = "Diet") +
ggtitle("Số lượng Chick theo Diet") +
theme_minimal()

Giải thích biểu đồ 20
Chúng ta sử dụng group_by() và summarise() từ gói dplyr để tính số
lượng chick cho mỗi diet. Sau đó, chúng ta vẽ biểu đồ cột (bar chart)
bằng ggplot2, với trục x là loại diet, trục y là số lượng chick, và màu
sắc được sử dụng để phân biệt các diet.
LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSA1Ig0KYXV0aG9yOiAiTmhoYW8iDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclSDolTTolUywgJWQgLSAlbSAtICVZJylgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdG9jOiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQotLS0NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkYXRhc2V0cykNCmBgYA0KIA0KDQojICoqR2nhu5tpIHRoaeG7h3UgYuG7mSBk4buvIGxp4buHdSoqDQoNCkLhu5kgZOG7ryBsaeG7h3UgbsOgeSBiYW8gZ+G7k20gY8OhYyBj4buZdCBzYXU6DQoNCi0gd2VpZ2h0OiBDw6JuIG7hurduZyBj4bunYSBnw6AgY29uLCDEkcaw4bujYyDEkW8gdHJvbmcgY8OhYyDEkcahbiB24buLIGtow7RuZyB4w6FjIMSR4buLbmggKHRoxrDhu51uZyBsw6AgxJHhu5MgY2jGoWkgaG/hurdjIGdyYW0pLg0KDQotIFRpbWU6IFRo4budaSBnaWFuIHRoZW8gbmfDoHkgaG/hurdjIHR14bqnbiB0cm9uZyB0aMOtIG5naGnhu4dtLiDEkMOieSBsw6AgdGjhu51pIGdpYW4ga2hpIG3huqt1IGfDoCBjb24gxJHGsOG7o2MgxJFvIGPDom4gbuG6t25nLg0KDQotIENoaWNrOiBNw6Mgc+G7kSBj4bunYSBnw6AgY29uLiBN4buXaSBjb24gZ8OgIHRyb25nIHRow60gbmdoaeG7h20gxJHGsOG7o2MgZ8OhbiBt4buZdCBtw6Mgc+G7kSBkdXkgbmjhuqV0IMSR4buDIHRoZW8gZMO1aS4NCg0KLSBEaWV0OiBMb+G6oWkgdGjhu6ljIMSDbiDEkcaw4bujYyBjdW5nIGPhuqVwIGNobyBnw6AgY29uLiDEkMOieSBjw7MgdGjhu4MgbMOgIGJp4bq/biBwaMOibiBsb+G6oWkgbcO0IHThuqMgY8OhYyBsb+G6oWkgdGjhu6ljIMSDbiBraMOhYyBuaGF1IMSRxrDhu6NjIHPhu60gZOG7pW5nIHRyb25nIHRow60gbmdoaeG7h20uDQoNCi0gTeG7pWMgdGnDqnUgY+G7p2EgYuG7mSBk4buvIGxp4buHdSBuw6B5IGPDsyB0aOG7gyBsw6AgxJHhu4MgbmdoacOqbiBj4bupdSBz4buxIOG6o25oIGjGsOG7n25nIGPhu6dhIGNo4bq/IMSR4buZIMSDbiB14buRbmcgKGPDoWMgbG/huqFpIHRo4bupYyDEg24ga2jDoWMgbmhhdSkgxJHhur9uIHTEg25nIHRyxrDhu59uZyB2w6AgcGjDoXQgdHJp4buDbiBj4bunYSBnw6AgY29uLiBDw6FjIG5ow6AgbmdoacOqbiBj4bupdSBjw7MgdGjhu4Mgc+G7rSBk4bulbmcgYuG7mSBk4buvIGxp4buHdSBuw6B5IMSR4buDIHRo4buxYyBoaeG7h24gY8OhYyBwaMOibiB0w61jaCB0aOG7kW5nIGvDqiBob+G6t2MgbcO0IGjDrG5oIGjDs2EgZOG7ryBsaeG7h3UgxJHhu4MgaGnhu4N1IHLDtSBoxqFuIHbhu4EgY8OhY2ggY2jhur8gxJHhu5kgxINuIHXhu5FuZyDhuqNuaCBoxrDhu59uZyDEkeG6v24gc+G7sSBwaMOhdCB0cmnhu4NuIGPhu6dhIGfDoCBjb24uDQoNCiMgKipDw6FjIGJp4buDdSDEkeG7kyoqDQoNCiMjICoqQmnhu4N1IMSR4buTIDEqKg0KDQpgYGB7cn0NCmxpYnJhcnkoZGF0YXNldHMpDQpkYXRhKCJDaGlja1dlaWdodCIpDQpnYSA8LSBDaGlja1dlaWdodA0KZGlldF9jb3VudHMgPC0gdGFibGUoZ2EkRGlldCkNCnBpZShkaWV0X2NvdW50cywgbGFiZWxzID0gcGFzdGUobmFtZXMoZGlldF9jb3VudHMpLCAiICgiLCBkaWV0X2NvdW50cywgIikiLCBzZXAgPSAiIiksIA0KICAgIG1haW4gPSAiU+G7kSBsxrDhu6NuZyBnw6AgY29uIHRoZW8gRGlldCIpDQoNCmBgYA0KDQoqKmdp4bqjaSB0aMOtY2ggYmnhu4N1IMSR4buTIDEqKg0KDQotIEJp4buDdSDEkeG7kyBjaG8gdGEgdGjhuqV5IHPhu5EgbMaw4bujbmcgZ8OgIGNvbiBj4bunYSB04burbmcgbG/huqFpIGRpbmggZMaw4buhbmcgbmjGsG5nIOG7nyBk4bqhbmcgUGllIGNoYXJ0DQoNCi0gduG7m2kgbG/huqFpIDEgbMOgIDIyMCBjb24gbMOgIGzhu5tuIG5o4bqldCB2w6AgbG/huqFpIDQgbMOgIMOtdCBuaOG6pXQgduG7m2kgMTE4IGNvbg0KDQojIyAqKkJp4buDdSDEkeG7kyAyKioNCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZGF0YXNldHMpDQpkYXRhKCJDaGlja1dlaWdodCIpDQpnYSA8LSBDaGlja1dlaWdodA0KZ2dwbG90KGdhLCBhZXMoeCA9IHdlaWdodCwgZmlsbCA9IGZhY3RvcihEaWV0KSkpICsNCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC41KSArDQogIGxhYnMoeCA9ICJXZWlnaHQiLCB5ID0gIkRlbnNpdHkiLCBmaWxsID0gIkRpZXQiKSArDQogIGdndGl0bGUoIkRlbnNpdHkgcGxvdCBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24gdGhlbyBsb+G6oWkga2jhuql1IHBo4bqnbiIpDQoNCmBgYA0KKipnaeG6o2kgdGjDrWNoIGJp4buDdSDEkeG7kyAyKioNCg0KLSBCaeG7g3UgxJHhu5MgY2hvIHRhIHRo4bqleSBz4buxIHBow6JuIGLhu5EgdHLhu41uZyBsxrDhu6NuZyB0cm9uZyBt4buXaSBuaMOzbSB24bubaSB04burbmcgbG/huqFpIGto4bqpdSBwaOG6p24gZGluaCBkxrDhu6FuZyBjaG8gZ8OgIGNvbiByacOqbmcgYmnhu4d0DQoNCi0gTeG6rXQgxJHhu5kgbG/huqFpIG3hu5l0IGNoaeG6v20gcuG6pXQgY2FvIHbDoCBkw6B5IHRyb25nIGtob+G6o25nIHThu6sgMTAwIMSR4bq/biBu4butYSAyMDBnIHLhu5NpIGzDoG0gZ2nhuqNtIG3hu5l0IGPDoWNoIHLDtSBy4buHdCwgdGnhur9wIMSRw7MgbMOgIGxv4bqhaSAyIHbDoCB4deG7kW5nIGzhuqduIHThu5tpIGxv4bqhaSAzLDQNCg0KLSBLaG9hbmcgY8OzIHPhu7EgY2jDqm5oIGzhu4duaCBxdcOhIGzhu5tuIHThu6sga2hv4bqjbmcgbuG7rWEgMTAwIMSR4bq/biAyMDBnIHRy4bufIMSRaSBj4bunYSBraOG6qXUgcGjhuqduIDEsIDIsIDMsIExv4bqhaSBkaW5oIGTGsOG7oW5nIDQg4bqjbmggaMaw4bufbmcgbOG7m24gxJHhur9uIGPDom4gbuG6t25nIHThu6sgMTAwIMSR4bq/biAyMDBnIGPhu6dhIGfDoCBjb24NCg0KIyMgKipCaeG7g3UgxJHhu5MgMyoqDQoNCmBgYHtyfQ0KbGlicmFyeShkYXRhc2V0cykNCmRhdGEoIkNoaWNrV2VpZ2h0IikNCmdhIDwtIENoaWNrV2VpZ2h0DQpkaWV0X3Byb3BvcnRpb25zIDwtIHByb3AudGFibGUodGFibGUoZ2EkRGlldCkpICogMTAwDQoNCnBpZShkaWV0X3Byb3BvcnRpb25zLCBsYWJlbHMgPSBwYXN0ZTAobmFtZXMoZGlldF9wcm9wb3J0aW9ucyksICI6ICIsIHJvdW5kKGRpZXRfcHJvcG9ydGlvbnMsIDIpLCAiJSIpLCANCiAgICBtYWluID0gIlThu4kgbOG7hyBkaW5oIGTGsOG7oW5nIHRoZW8gRGlldCIpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIGJp4buDdSDEkeG7kyAzKioNCg0KcHJvcC50YWJsZSh0YWJsZShjaGlja3dlaWdodCREaWV0KSkgKiAxMDA6IMSQ4bqndSB0acOqbiwgY2jDum5nIHRhIHPhu60gZOG7pW5nIGjDoG0gdGFibGUoKSDEkeG7gyDEkeG6v20gc+G7kSBsxrDhu6NuZyBt4bqrdSB0cm9uZyB04burbmcgbG/huqFpIHRo4bupYyDEg24gKERpZXQpLiBTYXUgxJHDsywgcHJvcC50YWJsZSgpIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHTDrW5oIHRvw6FuIHThu7cgbOG7hyBwaOG6p24gdHLEg20gY+G7p2EgbeG7l2kgbG/huqFpIHRo4bupYyDEg24uIEN14buRaSBjw7luZywgY2jDum5nIHRhIG5ow6JuIHbhu5tpIDEwMCDEkeG7gyBjaHV54buDbiDEkeG7lWkgc2FuZyB04bu3IGzhu4cgcGjhuqduIHRyxINtLg0KDQpsYWJlbHMgPSBwYXN0ZTAobmFtZXMoZGlldF9wcm9wb3J0aW9ucyksICI6ICIsIHJvdW5kKGRpZXRfcHJvcG9ydGlvbnMsIDIpLCAiJSIpOiBDaMO6bmcgdGEgc+G7rSBk4bulbmcgaMOgbSBwYXN0ZTAoKSDEkeG7gyBr4bq/dCBo4bujcCB0w6puIGPhu6dhIGPDoWMgbG/huqFpIHRo4bupYyDEg24gduG7m2kgdOG7tyBs4buHIHBo4bqnbiB0csSDbSB0xrDGoW5nIOG7qW5nLCB2w6AgxJHhu4tuaCBk4bqhbmcgc+G7kSBsaeG7h3UgduG7m2kgaGFpIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuLiDEkGnhu4F1IG7DoHkgZ2nDunAgaGnhu4NuIHRo4buLIG5ow6NuIGNobyBjw6FjIHBo4bqnbiB0cm9uZyBiaeG7g3UgxJHhu5MgcGllIGNoYXJ0Lg0KDQptYWluID0gIlThu4kgbOG7hyBkaW5oIGTGsOG7oW5nIHRoZW8gRGlldCI6IMSQw6J5IGzDoCB0acOqdSDEkeG7gSBjaG8gYmnhu4N1IMSR4buTIHBpZSBjaGFydCwgY2hvIGJp4bq/dCBy4bqxbmcgYmnhu4N1IMSR4buTIG7DoHkgdGjhu4MgaGnhu4duIHThu7cgbOG7hyBkaW5oIGTGsOG7oW5nIHRoZW8gdOG7q25nIGxv4bqhaSB0aOG7qWMgxINuLg0KDQoNCiMjICoqQmnhu4N1IMSR4buTIDQqKg0KDQpgYGB7cn0NCmRpZXRfcHJvcG9ydGlvbnMgPC0gcHJvcC50YWJsZSh0YWJsZShnYSREaWV0KSkgKiAxMDANCmJhcnBsb3QoZGlldF9wcm9wb3J0aW9ucywgDQogICAgICAgIG1haW4gPSAiVOG7iSBs4buHIGRpbmggZMaw4buhbmcgdGhlbyBEaWV0IiwNCiAgICAgICAgeGxhYiA9ICJEaWV0IiwNCiAgICAgICAgeWxhYiA9ICJU4bu3IGzhu4cgcGjhuqduIHRyxINtIikNCmBgYA0KKipHaeG6o2kgdGjDrWNoIMSR4buTIHRo4buLIDQqKg0KDQpwcm9wLnRhYmxlKHRhYmxlKGdhJERpZXQpKSAqIDEwMDogQ2jDum5nIHRhIHPhu60gZOG7pW5nIGjDoG0gdGFibGUoKSDEkeG7gyDEkeG6v20gc+G7kSBsxrDhu6NuZyBt4bqrdSB0cm9uZyB04burbmcgbG/huqFpIHRo4bupYyDEg24gKERpZXQpLiBTYXUgxJHDsywgcHJvcC50YWJsZSgpIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHTDrW5oIHRvw6FuIHThu7cgbOG7hyBwaOG6p24gdHLEg20gY+G7p2EgbeG7l2kgbG/huqFpIHRo4bupYyDEg24uIEN14buRaSBjw7luZywgY2jDum5nIHRhIG5ow6JuIHbhu5tpIDEwMCDEkeG7gyBjaHV54buDbiDEkeG7lWkgc2FuZyB04bu3IGzhu4cgcGjhuqduIHRyxINtLg0KDQpiYXJwbG90KGRpZXRfcHJvcG9ydGlvbnMsIG1haW4gPSAiVOG7iSBs4buHIGRpbmggZMaw4buhbmcgdGhlbyBEaWV0IiwgeGxhYiA9ICJEaWV0IiwgeWxhYiA9ICJU4bu3IGzhu4cgcGjhuqduIHRyxINtIik6IEjDoG0gYmFycGxvdCgpIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHThuqFvIGJp4buDdSDEkeG7kyBiYXIgY2hhcnQuIMSQ4buRaSBz4buRIMSR4bqndSB0acOqbiBsw6AgdmVjdG9yIGNo4bupYSB04bu3IGzhu4cgcGjhuqduIHRyxINtIGPhu6dhIHThu6tuZyBsb+G6oWkgdGjhu6ljIMSDbi4gQ8OhYyDEkeG7kWkgc+G7kSB0aeG6v3AgdGhlbyDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyDEkeG6t3QgdGnDqnUgxJHhu4EgY2hvIGJp4buDdSDEkeG7kyAobWFpbiksIG5ow6NuIHRy4bulYyB4ICh4bGFiKSB2w6AgbmjDo24gdHLhu6VjIHkgKHlsYWIpLg0KDQojIyAqKkJp4buDdSDEkeG7kyA1KioNCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZGF0YXNldHMpDQpkYXRhKCJDaGlja1dlaWdodCIpDQpnYSA8LSBDaGlja1dlaWdodA0KZ2dwbG90KGdhLCBhZXMoeCA9IFRpbWUsIHkgPSB3ZWlnaHQsIGNvbG9yID0gZmFjdG9yKERpZXQpKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICBsYWJzKHggPSAiVGjhu51pIGdpYW4gcXVhbiBzw6F0IiwgeSA9ICJDw6JuIG7hurduZyIsIGNvbG9yID0gIkRpZXQiKSArDQogIGdndGl0bGUoIlTGsMahbmcgcXVhbiBnaeG7r2EgY8OibiBu4bq3bmcgdsOgIHRo4budaSBnaWFuIHF1YW4gc8OhdCB0aGVvIERpZXQiKQ0KDQpgYGANCioqR2nhuqNpIHRow61jaCBiaeG7g3UgxJHhu5MgNSoqDQpCaeG7g3UgxJHhu5Mgc2NhdHRlcnBsb3QgbcOgIGNow7puZyB0YSB24burYSB04bqhbyB0aOG7gyBoaeG7h24gbeG7kWkgcXVhbiBo4buHIGdp4buvYSBjw6JuIG7hurduZyBj4bunYSBnw6AgY29uIHbDoCB0aOG7nWkgZ2lhbiBxdWFuIHPDoXQsIHbhu5tpIHPhu7EgcGjDom4gYmnhu4d0IMSRxrDhu6NjIHRo4buxYyBoaeG7h24gdGhlbyB04burbmcgbG/huqFpIERpZXQga2jDoWMgbmhhdS4gRMaw4bubaSDEkcOieSBsw6AgZ2nhuqNpIHRow61jaCDDvSBuZ2jEqWEgY+G7p2EgYmnhu4N1IMSR4buTIG7DoHk6DQoNClRy4bulYyBYIChUaOG7nWkgZ2lhbiBxdWFuIHPDoXQpOiBUcuG7pWMgbsOgeSBiaeG7g3UgZGnhu4VuIHRo4budaSBnaWFuIHF1YW4gc8OhdCBnw6AgY29uLiBN4buXaSDEkWnhu4NtIHRyw6puIHRy4bulYyBuw6B5IMSR4bqhaSBkaeG7h24gY2hvIG3hu5l0IHRo4budaSDEkWnhu4NtIGPhu6UgdGjhu4MgdHJvbmcgcXXDoSB0csOsbmggcXVhbiBzw6F0Lg0KDQpUcuG7pWMgWSAoQ8OibiBu4bq3bmcpOiBUcuG7pWMgbsOgeSBiaeG7g3UgZGnhu4VuIGPDom4gbuG6t25nIGPhu6dhIGfDoCBjb24gdOG6oWkgdGjhu51pIMSRaeG7g20gdMawxqFuZyDhu6luZy4gTeG7l2kgxJFp4buDbSB0csOqbiB0cuG7pWMgbsOgeSB0aOG7gyBoaeG7h24gY8OibiBu4bq3bmcgY+G7p2EgbeG7mXQgY29uIGfDoCB04bqhaSBt4buZdCB0aOG7nWkgxJFp4buDbSBj4bulIHRo4buDLg0KDQpNw6B1IHPhuq9jIChEaWV0KTogQmnhu4N1IMSR4buTIHPhu60gZOG7pW5nIG3DoHUgc+G6r2MgxJHhu4MgcGjDom4gYmnhu4d0IGPDoWMgbmjDs20gRGlldCBraMOhYyBuaGF1LiBN4buXaSBtw6B1IMSR4bqhaSBkaeG7h24gY2hvIG3hu5l0IGxv4bqhaSBEaWV0LiDEkGnhu4F1IG7DoHkgZ2nDunAgY2jDum5nIHRhIG5o4bqtbiBiaeG6v3QgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBjw6JuIG7hurduZyB2w6AgdGjhu51pIGdpYW4gcXVhbiBzw6F0IMSRxrDhu6NjIHBow6JuIGxv4bqhaSB0aGVvIHThu6tuZyBsb+G6oWkgRGlldC4NCg0KxJBp4buDbSAoc2NhdHRlciBwb2ludHMpOiBN4buXaSDEkWnhu4NtIHRyw6puIGJp4buDdSDEkeG7kyDEkeG6oWkgZGnhu4duIGNobyBt4buZdCBjb24gZ8OgIHbDoCB24buLIHRyw60gY+G7p2EgbsOzIHRyw6puIHRy4bulYyB4IHbDoCB0cuG7pWMgeSB0aOG7gyBoaeG7h24gdGjhu51pIGdpYW4gcXVhbiBzw6F0IHbDoCBjw6JuIG7hurduZyBj4bunYSBnw6AgY29uIHTGsMahbmcg4bupbmcuIELhurFuZyBjw6FjaCBuw6B5LCBjaMO6bmcgdGEgY8OzIHRo4buDIHF1YW4gc8OhdCBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGPDom4gbuG6t25nIHbDoCB0aOG7nWkgZ2lhbiBxdWFuIHPDoXQgY+G7p2EgZ8OgIGNvbiwgdsOgIHhlbSB4w6l0IGxp4buHdSBjw7Mgc+G7sSBraMOhYyBiaeG7h3QgbsOgbyBnaeG7r2EgY8OhYyBuaMOzbSBEaWV0IGhheSBraMO0bmcuDQoNCkJp4buDdSDEkeG7kyBzY2F0dGVycGxvdCBuw6B5IGdpw7pwIGNow7puZyB0YSBuaOG6rW4gcmEgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBjw6JuIG7hurduZyBj4bunYSBnw6AgY29uIHbDoCB0aOG7nWkgZ2lhbiBxdWFuIHPDoXQsIHbDoCBsaeG7h3UgbeG7kWkgcXVhbiBo4buHIG7DoHkgY8OzIHPhu7Ega2jDoWMgYmnhu4d0IGdp4buvYSBjw6FjIG5ow7NtIERpZXQgaGF5IGtow7RuZy4NCg0KIyMgKipCaeG7g3UgxJHhu5MgNioqDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGRhdGFzZXRzKQ0KZGF0YSgiQ2hpY2tXZWlnaHQiKQ0KZ2EgPC0gQ2hpY2tXZWlnaHQNCmdhICU+JSBnZ3Bsb3QoYWVzKHggPSB3ZWlnaHQsIHkgPSBUaW1lLCBjb2xvciA9IERpZXQpKSArICNT4butIGThu6VuZyBk4buvIGxp4buHdSB04burIGNrIHThuqFvIG3hu5l0IGLhuqNuZyBk4buvIGxp4buHdSBt4bubaSB0cm9uZyBnw7NpIGdncGxvdCwgdGhp4bq/dCBs4bqtcCB0cuG7pWMgeCwgeSwgcGjDom4gbG/huqFpIGPDoWMgxJFp4buDbSB0aGVvIHThu6tuZyBsb+G6oWkgZGluaCBkxrDhu6FuZyB2w6AgcGjDom4gYuG7kSBtw6B1IGNobyBjaMO6bmcNCiAgZ2VvbV9wb2ludCgpICsgI1Row6ptIGPDoWMgxJFp4buDbSB2w6BvIGJp4buDdSDEkeG7kywgbeG7l2kgxJFp4buDbSBsw6AgbeG7mXQgcXVhbiBzw6F0IMSRxrDhu6NjIMSR4buRaSBjaGnhur91IHRoZW8gdHLhu6VjIHggdsOgIHkNCiAgbGFicyggeCA9ICdjw6JuIG7hurduZyBnw6AgY29uJywgeSA9ICdUaOG7nWkgZ2lhbiBxdWFuIHPDoXQnLCB0aXRsZSA9ICdUxrDGoW5nIHF1YW4gZ2nhu69hIGfDoCBjb24gdsOgIGPDom4gbuG6t25nIHRoZW8gbG/huqFpIGRpbmggZMaw4buhbmcnKSArICAjxJDhurd0IG5ow6NuIGNobyB0cuG7pWMgeCB2w6AgeSwgdGhp4bq/dCBs4bqtcCBs4bqhaSB0w6puIHRpw6p1IMSR4buBIG3hu5tpIGNobyB2w7luZyBk4buvIGxpw6rhu6UNCmdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yID0gJ3JlZCcpICsgI1Row6ptIMSRxrDhu51uZyBwaMO5IGjhu6NwIHR1eeG6v24gdMOtbmgsIGLhurFuZyBwaMawxqFuZyBwaMOhcCBo4buTaSBxdXkgdHV54bq/biB0w61uaA0KICBmYWNldF93cmFwKH5EaWV0KSAjUGjDom4gbG/huqFpIGPDoWMgYuG6o25nIG5o4buPIGjGoW4gdGhlbyBsb+G6oWkgRGlldA0KYGBgDQoNCioqR2nhuqNpIHRow61jaCDEkeG7kyB0aOG7iyA2KioNCg0KQ8OibiBu4bq3bmcgZ8OgIGNvbiB0w7l5IHRoZW8gdOG7q25nIGxv4bqhaSBkaW5oIGTGsOG7oW5nIGPDsyB4dSBoxrDhu5tuZyB0xINuZyB0aGVvIHRo4budaSBnaWFuIHF1YW4gc8OhdA0KDQojIyAqKkJp4buDdSDEkeG7kyA3KioNCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZGF0YXNldHMpDQpkYXRhKCJDaGlja1dlaWdodCIpDQpnYSA8LSBDaGlja1dlaWdodA0KZ2EgJT4lIGdyb3VwX2J5KERpZXQpICU+JSBzdW1tYXJpc2Uobj1tZWFuKHdlaWdodCkpICU+JSANCiAgZ2dwbG90KGFlcyh4PSAnJywgeT1uLCBmaWxsID0gRGlldCkpKyANCiAgZ2VvbV9jb2woY29sb3IgPSAnZ3JlZW4nLCB3aWR0aCA9IDEpICsgDQogIGNvb3JkX3BvbGFyKCd5JykgKyANCiAgZ2VvbV90ZXh0KGFlcyh4ID0gMS4zLCBsYWJlbCA9IHJvdW5kKG4sMikpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gLjUpKSArIA0KICBsYWJzKCB0aXRsZSA9ICdUcuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oJykgKyANCiAgdGhlbWVfdm9pZCgpIA0KYGBgDQoqKkdp4bqjaSB0aMOtY2ggYmnhu4N1IMSR4buTIDYqKg0KDQpnYSAlPiUgZ3JvdXBfYnkoRGlldCkgJT4lIHN1bW1hcmlzZShuPW1lYW4od2VpZ2h0KSkgJT4lICNU4bqhbyBi4bqjbmcgZOG7ryBsaeG7h3UgbeG7m2kgY8OhYyBjw6FjIGPhu5luZyBEaWV0IHbDoCB0w61uaCBsxrDhu6NuZyB0cnVuZyBiw6xuaCANCiAgZ2dwbG90KGFlcyh4PSAnJywgeT1uLCBmaWxsID0gRGlldCkpKyAjQuG6r3QgxJHhuqd1IG3hu5l0IGJp4buDdSDEkeG7kyBz4butIGThu6VuZyBnw7NpIGdncGxvdCB24bubaSB0cuG7pWMgeCBraMO0bmcgY8OzIGThu68gbGnhu4d1LCB0cuG7pWMgeSBsw6AgY8OhYyBwaOG6p24gdOG7rSBuLCB2w6AgbcOgdSBz4bqvYyDEkcaw4bujYyB0aMOqbSB2w6BvIHBow6JuIGJp4buHdCBjw6FjIGxv4bqhaSBEaWV0DQogIGdlb21fY29sKGNvbG9yID0gJ2dyZWVuJywgd2lkdGggPSAxKSArICNUaMOqbSBjw6FjIGPhu5l0IHbDoG8gYmnhu4N1IMSR4buTLCBt4buXaSBj4buZdCBsw6AgbeG7mXQgbG/huqFpIGRpbmggZMaw4buhbmcgY8WpbmcgbmjGsCDEkeG7mSBy4buZbmcgbMOgIDENCiAgY29vcmRfcG9sYXIoJ3knKSArICNDaHV54buDbiDEkeG7lWkgYmnhu4N1IMSR4buTIHRow6BuaCBo4buHIHThu41hIMSR4buZIGPhu7FjLCBiaeG7g3UgdGjhu4sgY8OhYyBwaOG6p24gdMawxqFuZyDEkeG7kWkgdHJvbmcgbeG7mXQgdsOybmcgdHLDsm4NCiAgZ2VvbV90ZXh0KGFlcyh4ID0gMS4zLCBsYWJlbCA9IHJvdW5kKG4sMikpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gLjUpKSArICNDw6FjIG5ow6NuIHPhur0gxJHhuq10IOG7nyB24buLIHRyw60gMS4zIHRyw6puIHRy4bulYyB4LCB0cuG7pWMgeSwgdMOtbmggZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCB2w6AgbOG6pXkgaGFpIGdpw6EgdHLhu4sgc2F1IMSRw7MsIGhp4buDbiB0aOG7iyBz4buRIGzGsOG7o25nIHbDoCAgY8OhYyBuaMOjbiDEkcaw4bujYyBjaOG7k25nIHbhu5tpIG5oYXUgbMOqbiBjxINuIGNo4buJbmgg4bufIHbhu4sgdHLDrSAuNQ0KICBsYWJzKCB0aXRsZSA9ICdUcuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oJykgKyAjVGjDqm0gcGjhuqduIHRpw6p1IMSR4buBIHbDoG8gdsO5bmcgduG6vSBiaeG7g3UgxJHhu5MNCiAgdGhlbWVfdm9pZCgpICNMb+G6oWkgYuG7jyBjw6FjIHBo4bqnbiBt4bq3YyDEkeG7i25oIGPhu6dhIGdpYW8gZGnhu4duIGPhu6dhIGJp4buDdSDEkeG7kywgY2jhu4kgaGnhu4NuIHRo4buLIGThu68gbGnhu4d1IHbDoCBjw6FjIHnhur91IHThu5EgdHLhu7FjIHRp4bq/cCBsacOqbiBxdWFuIMSR4bq/biBuw7MuIA0KDQpCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHRy4buNbmcgbMaw4bujbmcgZ8OgIGNvbiB0cnVuZyBiw6xuaCB0aGVvIHThu6tuZyBsb+G6oWkgZGluaCBkxrDhu6FuZw0KTG/huqFpIDEgY8OzIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggbMOgIDEwMi42NSwgbG/huqFpIDIgbMOgIDEyMi42MiwgbG/huqFpIDMgbMOgIDE0Mi45NSwgbG/huqFpIDQgbMOgIDEzNS4yNg0KDQojIyAqKkJp4buDdSDEkeG7kyA4KioNCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZGF0YXNldHMpDQpkYXRhKCJDaGlja1dlaWdodCIpDQpnYSA8LSBDaGlja1dlaWdodA0KZ2EgJT4lIGdncGxvdChhZXMoeCA9IHdlaWdodCwgeSA9IFRpbWUsIGNvbG9yID0gRGlldCkpICsNCiAgZ2VvbV9wb2ludCgpICsgDQogIGxhYnMoIHggPSAnY8OibiBu4bq3bmcgZ8OgIGNvbicsIHkgPSAnVGjhu51pIGdpYW4gcXVhbiBzw6F0JywgdGl0bGUgPSAnVMawxqFuZyBxdWFuIGdp4buvYSBnw6AgY29uIHbDoCBjw6JuIG7hurduZyB0aGVvIGxv4bqhaSBkaW5oIGTGsOG7oW5nJykgKyANCmdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yID0gJ3JlZCcpDQpgYGANCioqR2nhuqNpIHRow61jaCDEkeG7kyB0aOG7iyA4KioNCg0KY2sgJT4lIGdncGxvdChhZXMoeCA9IHdlaWdodCwgeSA9IFRpbWUsIGNvbG9yID0gRGlldCkpICsgI1Phu60gZOG7pW5nIGThu68gbGnhu4d1IHThu6sgY2sgdOG6oW8gbeG7mXQgYuG6o25nIGThu68gbGnhu4d1IG3hu5tpIHRyb25nIGfDs2kgZ2dwbG90LCB0aGnhur90IGzhuq1wIHRy4bulYyB4LCB5LCBwaMOibiBsb+G6oWkgY8OhYyDEkWnhu4NtIHRoZW8gdOG7q25nIGxv4bqhaSBkaW5oIGTGsOG7oW5nIHbDoCBwaMOibiBi4buRIG3DoHUgY2hvIGNow7puZw0KICBnZW9tX3BvaW50KCkgKyAjVGjDqm0gY8OhYyDEkWnhu4NtIHbDoG8gYmnhu4N1IMSR4buTLCBt4buXaSDEkWnhu4NtIGzDoCBt4buZdCBxdWFuIHPDoXQgxJHGsOG7o2MgxJHhu5FpIGNoaeG6v3UgdGhlbyB0cuG7pWMgeCB2w6AgeQ0KICBsYWJzKCB4ID0gJ2PDom4gbuG6t25nIGfDoCBjb24nLCB5ID0gJ1Ro4budaSBnaWFuIHF1YW4gc8OhdCcsIHRpdGxlID0gJ1TGsMahbmcgcXVhbiBnaeG7r2EgZ8OgIGNvbiB2w6AgY8OibiBu4bq3bmcgdGhlbyBsb+G6oWkgZGluaCBkxrDhu6FuZycpICsgICPEkOG6t3QgbmjDo24gY2hvIHRy4bulYyB4IHbDoCB5LCB0aGnhur90IGzhuq1wIGzhuqFpIHTDqm4gdGnDqnUgxJHhu4EgbeG7m2kgY2hvIHbDuW5nIGThu68gbGnDquG7pQ0KZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3IgPSAnYmxhY2snKQ0KDQrEkMaw4budbmcgdHJlbmQgbGluZSBjw7MgeHUgaMaw4bubbmcgbMOqbiB0csOqbiwgbeG7kWkgdMawxqFuZyBxdWFuIGTGsMahbmcgZ2nhu69hIGPDoWMgZOG7ryBsaeG7h3UNClbhu5tpIGPDom4gbuG6t25nIGfDoCBjb24gbOG7m24sIHBo4bqjaSBi4buVIHN1bmcgZGluaCBkxrDhu6FuZyB0aGVvIMSRw7MgbcOgIHRo4budaSBnaWFuIHF1YW4gc8OhdCBjxaluZyBz4bq9IHBo4bqjaSB0xINuZyBsw6puDQoNCiMjICoqQmnhu4N1IMSR4buTIDkqKg0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShkYXRhc2V0cykNCmRhdGEoIkNoaWNrV2VpZ2h0IikNCmdhIDwtIENoaWNrV2VpZ2h0DQpnYSAlPiUgZ3JvdXBfYnkoRGlldCkgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9ICcnLCB5ID0gbixmaWxsID0gRGlldCkpICsgIw0KICBnZW9tX2NvbCggY29sb3IgPSAnYmxhY2snICkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbikscG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDEpKSArIA0KICBsYWJzKCB5ID0gJ3Phu5EgbMaw4bujbmcnLCB0aXRsZSA9ICdz4buRIGzGsOG7o25nIGfDoCBjb24gY2hvIG3hu5dpIGNo4bq/IMSR4buZIGRpbmggZMaw4buhbmcnKSANCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggYmnhu4N1IMSR4buTIDkqKg0KDQpjayAlPiUgZ3JvdXBfYnkoRGlldCkgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUgI05ow7NtIGPDoWMgZMOybmcgZOG7ryBsaeG7h3UgY+G7p2EgY2sgdGhlbyBj4buZdCBEaWV0LCBzYXUgxJHDsyB0w61uaCB04buVbmcgc+G7kSBsxrDhu6NuZyBjaG8gbeG7l2kgbmjDs20NCiAgZ2dwbG90KGFlcyh4ID0gJycsIHkgPSBuLGZpbGwgPSBEaWV0KSkgKyAjU+G7rSBk4bulbmcgZOG7ryBsaeG7h3UgdOG7qyBixrDhu5tjIHRyxrDhu5tjIHRoaeG6v3QgbOG6rXAgYmnhu4N1IMSR4buTIHbhu5tpIHRy4bulYyB4IGzDoCBraMO0bmcgY8OzIGThu68gbGnhu4d1LCB5IGzDoCBuLCBtw6B1IHPhuq9jIMSRYyDDoW5oIHjhuqEgdsOgbyBEaWV0DQogIGdlb21fY29sKCBjb2xvciA9ICdibGFjaycgKSArICNUaMOqbSBjw6FjIGPhu5l0IHbDoG8gYmnhu4N1IMSR4buTLCB24bubaSBtw6B1IMSRxrDhu6NjIHRoaeG6v3QgbOG6rXAgbMOgIG3DoHUgxJFlbg0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbikscG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDEpKSArICNUaMOqbSBuaMOjbiB2w6BvIGJp4buDdSDEkeG7kywgaGnhu4NuIHRo4buLIHPhu5EgbMaw4bujbmcgZ8OgIGNvbiB0csOqbiBt4buXaSBj4buZdCwgY8SDbiBjaOG7iW5oIHbhu4sgdHLDrSBk4buNYyBjw6FjIG5ow6NuLCDEkeG6t3QgdHLDqm4gY8O5bmcgbeG7l2kgY+G7mXQNCiAgbGFicyggeSA9ICdz4buRIGzGsOG7o25nJywgdGl0bGUgPSAnc+G7kSBsxrDhu6NuZyBnw6AgY29uIGNobyBt4buXaSBjaOG6vyDEkeG7mSBkaW5oIGTGsOG7oW5nJykgI1RoaeG6v3QgbOG6rXAgbmjDo24gY2hvIHRy4bulIHksIHRpw6p1IMSR4buBIGPhu6dhIHbDuW5nIGThu68gbGnhu4d1IMSRxrDhu6NjIHbhur0NCg0KQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBjaG8gdGEgdGjhuqV5IHPhu5EgbMaw4bujbmcgZ8OgIGNvbiB0aGVvIHThu6tuZyBsb+G6oWkgZGluaCBkxrDhu6FuZywgY8OhYyBz4buRIGxp4buHdSDEkcaw4bujYyBjaOG7k25nIHRoZW8gbeG7mXQgY+G7mXQgdsOgIHTDuXkgdGhlbyBz4buRIGzGsOG7o25nIG3DoCDEkeG7mSBkw6B5IGtow6FjIG5oYXUNCkxv4bqhaSBkaW5oIGTGsOG7oW5nIDEgY8OzIMSR4buZIGTDoHkgY2hp4bq/bSDGsHUgdGjhur8sIHPhu5EgbMaw4bujbmcgbmhp4buBdSBuaOG6pXQsIDMgbG/huqFpIGtpYSBraMO0bmcgY2jDqm5oIGzhu4djaCDEkcOhbmcga+G7gw0KDQojIyAqKkJp4buDdSDEkeG7kyAxMCoqDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGRhdGFzZXRzKQ0KZGF0YSgiQ2hpY2tXZWlnaHQiKQ0KZ2EgPC0gQ2hpY2tXZWlnaHQNCmdhICU+JSBnZ3Bsb3QoIGFlcyh4ID0gd2VpZ2h0LCBmaWxsID0gYXMuZmFjdG9yKERpZXQpKSkgKw0KICBnZW9tX2RlbnNpdHkoYWxwaGEgPSAwLjUpICsgIA0KICBmYWNldF93cmFwKH5EaWV0KSArIA0KICBsYWJzKHRpdGxlID0gIkRlbnNpdHkgcGxvdCBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24gdGhlbyBsb+G6oWkga2jhuql1IHBo4bqnbiIsIHggPSAiVHLhu41uZyBsxrDhu6NuZyAoZ3JhbXMpIiwgeSA9ICJN4bqtdCDEkeG7mSIpICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lID0gIkxv4bqhaSBraOG6qXUgcGjhuqduIikgIA0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBiaeG7g3UgxJHhu5MgMTAqKg0KDQpnYSAlPiUgZ2dwbG90KCBhZXMoeCA9IHdlaWdodCwgZmlsbCA9IGFzLmZhY3RvcihEaWV0KSkpICsNCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC41KSArICAjIFRoaeG6v3QgbOG6rXAgxJHhu5kgbeG7nSBj4bunYSBjw6FjIMSRxrDhu51uZyBkZW5zaXR5DQogIGZhY2V0X3dyYXAofkRpZXQpICsgI1Bow6JuIHThu5UgY8OhYyBiaeG7g3UgxJHhu5Mgbmjhu48gaMahbiB0aGVvIERpZXQNCiAgbGFicyh0aXRsZSA9ICJEZW5zaXR5IHBsb3QgY+G7p2EgdHLhu41uZyBsxrDhu6NuZyBnw6AgY29uIHRoZW8gbG/huqFpIGto4bqpdSBwaOG6p24iLCB4ID0gIlRy4buNbmcgbMaw4bujbmcgKGdyYW1zKSIsIHkgPSAiTeG6rXQgxJHhu5kiKSArDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZSA9ICJMb+G6oWkga2jhuql1IHBo4bqnbiIpICAjIFRow6ptIGNow7ogdGjDrWNoIGNobyBmaWxsDQogIA0KICBUxrDGoW5nIHThu7EgbmjGsCBiaeG7g3UgxJHhu5MgdHLDqm4sIG3hu5dpIHBo4bqnbiBuaOG7jyBjaOG7iSByYSBt4bqtdCDEkeG7mSB0cuG7jW5nIGzGsOG7o25nIGtoaSBjaG8gY8OhYyBsb+G6oWkga2jhuql1IHBo4bqnbiByacOqbmcgYmnhu4d0IMSR4buRaSB24bubaSBnw6AgY29uDQpMb+G6oWkga2jhuql1IHBo4bqnbiAxIHbhu5tpIHRy4buNbmcgbMaw4bujbmcgZ8OgIGNvbiAxMDBnIMSR4buVIGzhuqFpIHLhuqV0IG5oaeG7gXUNCg0KIyMgKipCaeG7g3UgxJHhu5MgMTEqKg0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShkYXRhc2V0cykNCmRhdGEoIkNoaWNrV2VpZ2h0IikNCmdhIDwtIENoaWNrV2VpZ2h0DQpnYSAlPiUgZ3JvdXBfYnkoRGlldCkgJT4lIHN1bW1hcmlzZShhdmcgPSBtZWFuKHdlaWdodCkpICU+JSAgDQogICBnZ3Bsb3QoYWVzKHggPSBhcy5mYWN0b3IoRGlldCksIHkgPSBhdmcpKSArICANCiAgZ2VvbV9jb2woZmlsbCA9ICdvcmFuZ2UnKSArIA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQoYXZnLDIpKSwgdmp1c3QgPSAxLCBjb2xvciA9ICdyZWQnKSArICANCiAgbGFicyggeCA9ICdsb+G6oWkgRGlldCcsIHkgPSAnVHLhu41uZyBsxrDhu6NuZyBnw6AgY29uIHRydW5nIGLDrG5oICAoZ3JhbSknLCB0aXRsZSA9ICd0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24gdHJ1bmcgYsOsbmggdGhlbyBEaWV0JykgKyANCiAgY29vcmRfZmxpcCgpIA0KYGBgDQoNCg0KKipHaeG6o2kgdGjDrWNoIGJp4buDdSDEkeG7kyAxMSoqDQpnYSAlPiUgZ3JvdXBfYnkoRGlldCkgJT4lIHN1bW1hcmlzZShhdmcgPSBtZWFuKHdlaWdodCkpICU+JSAjU+G7rSBk4bulbmcgZOG7ryBsaeG7h3UgdOG7qyBjayBuaMOzbSBj4buZdCBEaWV0IGPFqW5nIG5oxrBuZyB0w61uaCBjw6JuIG7hurduZyB0cnVuZyBiw6xuaCBj4bunYSBj4buZdCB3ZWlnaHQNCiAgIGdncGxvdChhZXMoeCA9IGFzLmZhY3RvcihEaWV0KSwgeSA9IGF2ZykpICsgI0Lhuq90IMSR4bqndSBt4buZdCBiaeG7g3UgxJHhu5Mgc+G7rSBk4bulbmcgZ8OzaSBnZ3Bsb3QgduG7m2kgdHLhu6VjIHggbMOgIERpZXQsIHRy4bulYyB5IGzDoCBsxrDhu6NuZyB0cnVuZyBiw6xuaCANCiAgZ2VvbV9jb2woZmlsbCA9ICdvcmFuZ2UnKSArICNUaMOqbSBjw6FjIGPhu5l0IHbDoG8gYmnhu4N1IMSR4buTLCB0aGnhur90IGzhuq1wIG3DoHUgY8OhYyBj4buZdCBsw6Agb3JhbmdlDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChhdmcsMikpLCB2anVzdCA9IDEsIGNvbG9yID0gJ3JlZCcpICsgI1Row6ptIG5ow6NuIHbhu4EgbMaw4bujbmcgdHJ1bmcgYsOsbmggdsOgbyBt4buXaSBj4buZdCwgdGhp4bq/dCBs4bqtcCBzYXUgZOG6pXUgcGjhuql5IGNo4buJIGzhuqV5IDIgY2jhu68gc+G7kSwgY8SDbiBjaOG7iW5oIMSR4buZIGThu41jIGPhu6dhIGPhu6dhIG5ow6NuIGPFqW5nIG5oxrAgbcOgdSBz4bqvYyBsw6AgxJHhu48NCiAgbGFicyggeCA9ICdsb+G6oWkgRGlldCcsIHkgPSAnVHLhu41uZyBsxrDhu6NuZyBnw6AgY29uIHRydW5nIGLDrG5oICAoZ3JhbSknLCB0aXRsZSA9ICd0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24gdHJ1bmcgYsOsbmggdGhlbyBEaWV0JykgKyAjxJDhurd0IG5ow6NuIGNobyB0cuG7pWMgeCwgeSBjxaluZyBuaMawIHRpw6p1IMSR4buBIGPhu6dhIHbDuW5nIGThu68gbGnhu4d1IMSRxrDhu6NjIHbhur0NCiAgY29vcmRfZmxpcCgpICPEkOG6o28gbmfGsOG7o2MgdHLhu6VjIGPhu6dhIGJp4buDdSDEkeG7kywgdOG7qyBk4buNYyB0aMOgbmggbmdhbmcgdsOgIG5nxrDhu6NjIGzhuqFpDQogIA0KICAjIyAqKkJp4buDdSDEkeG7kyAxMioqDQogIA0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZGF0YXNldHMpDQpkYXRhKCJDaGlja1dlaWdodCIpDQpnYSA8LSBDaGlja1dlaWdodA0KZ2dwbG90KGdhLCBhZXMoeCA9IFRpbWUsIHkgPSB3ZWlnaHQsIGNvbG9yID0gZmFjdG9yKERpZXQpKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGxhYnMoeCA9ICJUaOG7nWkgZ2lhbiIsIHkgPSAiQ8OibiBu4bq3bmciLCBjb2xvciA9ICJEaWV0IikgKw0KICBnZ3RpdGxlKCJCaeG7g3UgxJHhu5MgbGnDqm4gcXVhbiBnaeG7r2EgdGjhu51pIGdpYW4gdsOgIERpZXQiKQ0KYGBgDQoqKkdp4bqjaSB0aMOtY2ggYmnhu4N1IMSR4buTIDEyKioNCg0KVHLhu6VjIFggKFRo4budaSBnaWFuKTogVHLhu6VjIG7DoHkgYmnhu4N1IGRp4buFbiBjw6FjIMSRxqFuIHbhu4sgdGjhu51pIGdpYW4gKG5nw6B5LCB0deG6p24sIHZ2LikgY+G7p2EgcXXDoSB0csOsbmggcXVhbiBzw6F0IGfDoCBjb24uIE3hu5dpIMSRaeG7g20gdHLDqm4gdHLhu6VjIG7DoHkgdMawxqFuZyDhu6luZyB24bubaSBt4buZdCB0aOG7nWkgxJFp4buDbSBj4bulIHRo4buDIHRyb25nIHF1w6EgdHLDrG5oIHF1YW4gc8OhdC4NCg0KVHLhu6VjIFkgKEPDom4gbuG6t25nKTogVHLhu6VjIG7DoHkgYmnhu4N1IGRp4buFbiBjw6JuIG7hurduZyBj4bunYSBnw6AgY29uIHThuqFpIHThu6tuZyB0aOG7nWkgxJFp4buDbSDEkcaw4bujYyBxdWFuIHPDoXQuIE3hu5dpIMSRaeG7g20gdHLDqm4gdHLhu6VjIG7DoHkgdGjhu4MgaGnhu4duIGdpw6EgdHLhu4sgY8OibiBu4bq3bmcgdOG6oWkgdGjhu51pIMSRaeG7g20gdMawxqFuZyDhu6luZy4NCg0KTcOgdSBz4bqvYyAoRGlldCk6IEJp4buDdSDEkeG7kyBz4butIGThu6VuZyBtw6B1IHPhuq9jIMSR4buDIHBow6JuIGJp4buHdCBjw6FjIG5ow7NtIERpZXQga2jDoWMgbmhhdS4gTeG7l2kgbcOgdSDEkeG6oWkgZGnhu4duIGNobyBt4buZdCBsb+G6oWkgRGlldC4gxJBp4buBdSBuw6B5IGdpw7pwIGNow7puZyB0YSBuaMOsbiBuaOG6rW4gbeG7kWkgcXVhbiBo4buHIGdp4buvYSB0aOG7nWkgZ2lhbiB2w6AgY8OibiBu4bq3bmcgxJHGsOG7o2MgcGjDom4gbG/huqFpIHRoZW8gdOG7q25nIG5ow7NtIERpZXQuDQoNCsSQxrDhu51uZyAoTGluZXMpOiBN4buXaSDEkcaw4budbmcgdHLDqm4gYmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBz4buxIGJp4bq/biDEkeG7lWkgY+G7p2EgY8OibiBu4bq3bmcgdGhlbyB0aOG7nWkgZ2lhbiBjaG8gbeG7l2kgbmjDs20gRGlldC4gxJBp4buBdSBuw6B5IGdpw7pwIGNow7puZyB0YSBxdWFuIHPDoXQgeHUgaMaw4bubbmcgdMSDbmcvZ2nhuqNtIGPhu6dhIGPDom4gbuG6t25nIHRyb25nIHThu6tuZyBuaMOzbSBEaWV0IHRoZW8gdGjhu51pIGdpYW4uDQoNCkJp4buDdSDEkeG7kyBuw6B5IGdpw7pwIGNow7puZyB0YSBoaeG7g3UgxJHGsOG7o2MgbeG7kWkgcXVhbiBo4buHIGdp4buvYSB0aOG7nWkgZ2lhbiB2w6AgY8OibiBu4bq3bmcgY+G7p2EgZ8OgIGNvbiwgxJHhu5NuZyB0aOG7nWkgY2hvIHBow6lwIHNvIHPDoW5oIHPhu7EgYmnhur9uIMSR4buVaSBj4bunYSBjw6JuIG7hurduZyBnaeG7r2EgY8OhYyBuaMOzbSBEaWV0IGtow6FjIG5oYXUuDQoNCg0KIyMgKipCaeG7g3UgxJHhu5MgMTMqKg0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShkYXRhc2V0cykNCmRhdGEoIkNoaWNrV2VpZ2h0IikNCmdhIDwtIENoaWNrV2VpZ2h0DQpnYSAlPiUgZ2dwbG90KGFlcyh4ID0gd2VpZ2h0KSkgKyANCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA1MCwgZmlsbCA9ICJibHVlIiwgY29sb3IgPSAiYmxhY2siLCBhZXMoeT0uLmNvdW50Li4pKSArIA0KICBsYWJzKHggPSAiVHLhu41uZyBsxrDhu6NuZyAoZykiLCB5ID0gIlThuqduIHN14bqldCIpICsgDQogIGdndGl0bGUoIlBow6JuIHBo4buRaSBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24iKSArIA0KICB0aGVtZV9taW5pbWFsKCkgDQpgYGANCg0KKipnaeG6o2kgdGjDrWNoIGJp4buDdSDEkeG7kyAxMyoqDQoNCmNrICU+JSBnZ3Bsb3QoYWVzKHggPSB3ZWlnaHQpKSArICNC4bqvdCDEkeG6p3UgbeG7mXQgYmnhu4N1IMSR4buTIGdncGxvdCB24bubaSB0cuG7pWMgeCDEkcaw4bujYyB0aGnhur90IGzhuq1wIGzDoCBj4buZdCAid2VpZ2h0Ig0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDUwLCBmaWxsID0gInNreWJsdWUiLCBjb2xvciA9ICJibGFjayIsIGFlcyh5PS4uY291bnQuLikpICsgI1RoaeG6v3QgbOG6rXAgZOG7ryBsaeG7h3UgaGnhu4NuIHRo4buLIGTGsOG7m2kgZOG6oW5nIGhpc3RvZ3JhbSwgxJHhurd0IGNoaeG7gXUgcuG7mW5nIGJpbiwgbcOgdSBu4buBbiB2w6Agdmnhu4FuLCBz4butIGThu6VuZyB04bqnbiBzdeG6pXQgdHV54buHdCDEkeG7kWkNCiAgbGFicyh4ID0gIlRy4buNbmcgbMaw4bujbmcgKGcpIiwgeSA9ICJU4bqnbiBzdeG6pXQiKSArICNUaGnhur90IGzhuq1wIG5ow6NuIGNobyB0cuG7pWMgeCB2w6AgdHLhu6VjIHkNCiAgZ2d0aXRsZSgiUGjDom4gcGjhu5FpIGPhu6dhIHRy4buNbmcgbMaw4bujbmcgZ8OgIGNvbiIpICsgI1RoaeG6v3QgbOG6rXAgdGnDqnUgxJHhu4EgY2hvIGJp4buDdSDEkeG7kw0KICB0aGVtZV9taW5pbWFsKCkgI0No4buNbiBnaWFvIGRp4buHbiDEkcahbiBnaeG6o24sIMSRxrDhu51uZyBsxrDhu5tpIGNobyBiaeG7g3UgxJHhu5MNCiAgDQogIEJp4buDdSDEkeG7kyBjaG8gdGjhuqV5IHThuqduIHN14bqldCBzdeG6pXQgaGnhu4duIGPDoWMgY2jhu4kgc+G7kSB0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24NCnThuqduIHN14bqldCB4deG6pXQgaGnhu4duIGPhu6dhIHRy4buNbmcgbMaw4bujbmcgZMaw4bubaSAxMDBnIHh14bqldCBoaeG7h24gbmhp4buBdSBuaOG6pXQgaMahbiAyMDAgbOG6p24gdsOgIGdp4bqjbSBk4bqnbg0KDQojIyAqKkJp4buDdSDEkeG7kyAxNCoqDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGRhdGFzZXRzKQ0KZGF0YSgiQ2hpY2tXZWlnaHQiKQ0KZ2EgPC0gQ2hpY2tXZWlnaHQNCmdhICU+JSBnZ3Bsb3QoYWVzKHggPSB3ZWlnaHQpKSArIA0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDUwLCBmaWxsID0gImdyZWVuIiwgY29sb3IgPSAiYmxhY2siLCBhZXMoeT0uLmNvdW50Li4pKSArIA0KICBsYWJzKHggPSAiVHLhu41uZyBsxrDhu6NuZyAoZykiLCB5ID0gIlThuqduIHN14bqldCIpICsgDQogIGZhY2V0X3dyYXAofkRpZXQpICsgDQogIGdndGl0bGUoIlBow6JuIHBo4buRaSBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24iKSAgDQpgYGANCg0KKipHaWlhciB0aMOtY2ggxJHhu5MgdGjhu4sgMTQqKg0KDQpjayAlPiUgZ2dwbG90KGFlcyh4ID0gd2VpZ2h0KSkgKyAjQuG6r3QgxJHhuqd1IG3hu5l0IGJp4buDdSDEkeG7kyBnZ3Bsb3QgduG7m2kgdHLhu6VjIHggxJHGsOG7o2MgdGhp4bq/dCBs4bqtcCBsw6AgY+G7mXQgIndlaWdodCINCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA1MCwgZmlsbCA9ICJza3libHVlIiwgY29sb3IgPSAiYmxhY2siLCBhZXMoeT0uLmNvdW50Li4pKSArICNUaGnhur90IGzhuq1wIGThu68gbGnhu4d1IGhp4buDbiB0aOG7iyBkxrDhu5tpIGThuqFuZyBoaXN0b2dyYW0sIMSR4bq3dCBjaGnhu4F1IHLhu5luZyBiaW4sIG3DoHUgbuG7gW4gdsOgIHZp4buBbiwgc+G7rSBk4bulbmcgdOG6p24gc3XhuqV0IHR1eeG7h3QgxJHhu5FpDQogIGxhYnMoeCA9ICJUcuG7jW5nIGzGsOG7o25nIChnKSIsIHkgPSAiVOG6p24gc3XhuqV0IikgKyAjVGhp4bq/dCBs4bqtcCBuaMOjbiBjaG8gdHLhu6VjIHggdsOgIHRy4bulYyB5DQogIGZhY2V0X3dyYXAofkRpZXQpICsgI1Bow6JuIGxv4bqhaSBjw6FjIGLhuqNuZyBuaOG7jyB0aGVvIGxv4bqhaSBEaWV0DQogIGdndGl0bGUoIlBow6JuIHBo4buRaSBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24iKSAgI1RoaeG6v3QgbOG6rXAgdGnDqnUgxJHhu4EgY2hvIGJp4buDdSDEkeG7kw0KDQpCaeG7g3UgxJHhu5MgY2hvIHJhIHRo4bqleSBjaOG7iSBz4buRIHh14bqldCBoaeG7h24gY+G7p2EgY8OhYyBjaOG7iSBz4buRIHRy4buNbmcgbMaw4bujbmcgZ8OgIGNvbiDEkcaw4bujYyBwaMOibiByYSB0aGVvIGxv4bqhaSBkaW5oIGTGsOG7oW5nDQoNCiMjICoqQmnhu4N1IMSR4buTIDE1KioNCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZGF0YXNldHMpDQpkYXRhKCJDaGlja1dlaWdodCIpDQpnYSA8LSBDaGlja1dlaWdodA0KZ2EgJT4lIGdncGxvdChhZXMoeCA9IFRpbWUpKSArIA0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDMsIGZpbGwgPSAicGluayIsIGNvbG9yID0gImJsYWNrIiwgYWVzKHk9Li5jb3VudC4uKSkgKyANCiAgbGFicyh4ID0gIlRo4budaSBnaWFuIChoKSIsIHkgPSAiVOG6p24gc3XhuqV0IikgKyANCiAgZ2d0aXRsZSgiUGjDom4gcGjhu5FpIGPhu6dhIHRo4budaSBnaWFuIHRoZW8gZMO1aSBnw6AgY29uIikgKw0KICB0aGVtZV9taW5pbWFsKCkgDQpgYGANCg0KDQoqKkdp4bqjaSB0aMOtY2ggYmnhu4N1IMSR4buTIDE1KioNCmdhICU+JSBnZ3Bsb3QoYWVzKHggPSBUaW1lKSkgKyAjQuG6r3QgxJHhuqd1IG3hu5l0IGJp4buDdSDEkeG7kyBnZ3Bsb3QgduG7m2kgdHLhu6VjIHggxJHGsOG7o2MgdGhp4bq/dCBs4bqtcCBsw6AgY+G7mXQgIlRpbWUiDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMywgZmlsbCA9ICJwaW5rIiwgY29sb3IgPSAiYmxhY2siLCBhZXMoeT0uLmNvdW50Li4pKSArICNUaGnhur90IGzhuq1wIGThu68gbGnhu4d1IGhp4buDbiB0aOG7iyBkxrDhu5tpIGThuqFuZyBoaXN0b2dyYW0sIMSR4bq3dCBjaGnhu4F1IHLhu5luZyBiaW4gbMOgIDUsIG3DoHUgbuG7gW4gdsOgIG3DoHUgdmnhu4FuDQogIGxhYnMoeCA9ICJUaOG7nWkgZ2lhbiAoaCkiLCB5ID0gIlThuqduIHN14bqldCIpICsgI1RoaeG6v3QgbOG6rXAgbmjDo24gY2hvIHRy4bulYyB4IHbDoCB5DQogIGdndGl0bGUoIlBow6JuIHBo4buRaSBj4bunYSB0aOG7nWkgZ2lhbiB0aGVvIGTDtWkgZ8OgIGNvbiIpICsgI1RoaeG6v3QgbOG6rXAgdGnDqnUgxJHhu4EgY2hvIGJp4buDdSDEkeG7kw0KICB0aGVtZV9taW5pbWFsKCkgI0dpYW8gZGnhu4duIGThuqFuZyBsxrDhu5tpDQoNCkJp4buDdSDEkeG7kSBjaG8gdGEgdGjhuqV5IGPDoWMgdOG6p24gc3XhuqV0IGPDoWMga2hv4bqjbmcgdGjhu51pIGdpYW4geHXhuqV0IGhp4buHbg0KS2hv4bqjbmcgdGjhu51pIGdpYW4geHXhuqV0IGhp4buHbiBuaGnhu4F1IG5o4bqldCB04burIDAgxJHhur9uIDUgdsOgIGdp4bqjbSBk4bqnbiB24buBIDIwDQoNCiMjICoqQmnhu4N1IMSR4buTIDE2KioNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkYXRhc2V0cykNCmRhdGEoIkNoaWNrV2VpZ2h0IikNCmdhIDwtIENoaWNrV2VpZ2h0DQphdmVyYWdlX3dlaWdodCA8LSBhZ2dyZWdhdGUod2VpZ2h0IH4gVGltZSxnYSwgRlVOID0gbWVhbikNCmdncGxvdChhdmVyYWdlX3dlaWdodCwgYWVzKHggPSBUaW1lLCB5ID0gd2VpZ2h0KSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGxhYnMoeCA9ICJUaOG7nWkgZ2lhbiIsIHkgPSAiVHLhu41uZyBsxrDhu6NuZyB0YiIpICsNCiAgZ2d0aXRsZSgiQmnhu4N1IMSR4buTIHRy4buNbmcgbMaw4bujbmcgdGIgcXVhIGPDoWMgbeG7kWMgdGjhu51pIGdpYW4iKQ0KDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIGJp4buDdSDEkcOyIDE2KioNCg0KYWdncmVnYXRlKHdlaWdodCB+IFRpbWUsIGRhdGEgPSBjaGlja3dlaWdodCwgRlVOID0gbWVhbik6IENow7puZyB0YSBz4butIGThu6VuZyBow6BtIGFnZ3JlZ2F0ZSgpIMSR4buDIHTDrW5oIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggdGhlbyBjw6FjIG3hu5FjIHRo4budaSBnaWFuLiDEkOG7kWkgc+G7kSB3ZWlnaHQgfiBUaW1lIGNo4buJIMSR4buLbmggcuG6sW5nIGNow7puZyB0YSBtdeG7kW4gdMOtbmggdHJ1bmcgYsOsbmggY+G7p2EgdHLhu41uZyBsxrDhu6NuZyB0aGVvIHRo4budaSBnaWFuLiBkYXRhID0gY2hpY2t3ZWlnaHQgY2jhu4kgcmEgYuG7mSBk4buvIGxp4buHdSwgdsOgIEZVTiA9IG1lYW4gY2jhu4kgxJHhu4tuaCBy4bqxbmcgY2jDum5nIHRhIG114buRbiB0w61uaCB0cnVuZyBiw6xuaC4NCg0KZ2dwbG90KGF2ZXJhZ2Vfd2VpZ2h0LCBhZXMoeCA9IFRpbWUsIHkgPSB3ZWlnaHQpKTogxJDDonkgbMOgIGLGsOG7m2Mga2jhu59pIHThuqFvIGJp4buDdSDEkeG7kyBz4butIGThu6VuZyBnw7NpIGdncGxvdDIuIENow7puZyB0YSBz4butIGThu6VuZyBi4buZIGThu68gbGnhu4d1IGF2ZXJhZ2Vfd2VpZ2h0ICjEkcOjIHTDrW5oIHRvw6FuIHRyxrDhu5tjIMSRw7MpIHbDoCDEkeG7i25oIG5naMSpYSBjw6FjIG3hu5FpIHF1YW4gaOG7hyBhZXN0aGV0aWNzICht4bu5IHBo4bqpbSkgY2hvIGJp4buDdSDEkeG7ky4gVHLhu6VjIHggbMOgIHRo4budaSBnaWFuIHbDoCB0cuG7pWMgeSBsw6AgdHLhu41uZyBsxrDhu6NuZyB0cnVuZyBiw6xuaC4NCg0KZ2VvbV9saW5lKCk6IGdlb21fbGluZSgpIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHRow6ptIGPDoWMgxJHGsOG7nW5nIHbDoG8gYmnhu4N1IMSR4buTLCB04bqhbyB0aMOgbmggYmnhu4N1IMSR4buTIGxpbmUgcGxvdC4NCg0KbGFicyh4ID0gIlRo4budaSBnaWFuIiwgeSA9ICJUcuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oIik6IEjDoG0gbGFicygpIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIMSR4bq3dCB0w6puIGNobyBjw6FjIHRy4bulYyBj4bunYSBiaeG7g3UgxJHhu5MuIFRy4bulYyB4IMSRxrDhu6NjIGfDoW4gbMOgICJUaOG7nWkgZ2lhbiIsIHbDoCB0cuG7pWMgeSDEkcaw4bujYyBnw6FuIGzDoCAiVHLhu41uZyBsxrDhu6NuZyB0cnVuZyBiw6xuaCIuDQoNCmdndGl0bGUoIkJp4buDdSDEkeG7kyB0cuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oIHF1YSBjw6FjIG3hu5FjIHRo4budaSBnaWFuIik6IEjDoG0gZ2d0aXRsZSgpIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIMSR4bq3dCB0acOqdSDEkeG7gSBjaG8gYmnhu4N1IMSR4buTLiBUcm9uZyB0csaw4budbmcgaOG7o3AgbsOgeSwgdGnDqnUgxJHhu4EgxJHGsOG7o2MgxJHhurd0IGzDoCAiQmnhu4N1IMSR4buTIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggcXVhIGPDoWMgbeG7kWMgdGjhu51pIGdpYW4iLg0KDQojIyAqKkJp4buDdSDEkeG7kyAxNyoqDQoNCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZGF0YXNldHMpDQpkYXRhKCJDaGlja1dlaWdodCIpDQpnYSA8LSBDaGlja1dlaWdodA0KbWF4X3dlaWdodF9ieV9kaWV0IDwtIGdhICU+JQ0KICBncm91cF9ieShEaWV0KSAlPiUNCiAgc3VtbWFyaXNlKG1heF93ZWlnaHQgPSBtYXgod2VpZ2h0KSkNCmdncGxvdChtYXhfd2VpZ2h0X2J5X2RpZXQsIGFlcyh4ID0gZmFjdG9yKERpZXQpLCB5ID0gbWF4X3dlaWdodCwgZmlsbCA9IGZhY3RvcihEaWV0KSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgbGFicyh4ID0gIkRpZXQiLCB5ID0gIlRy4buNbmcgbMaw4bujbmcgbOG7m24gbmjhuqV0IiwgZmlsbCA9ICJEaWV0IikgKw0KICBnZ3RpdGxlKCJUcuG7jW5nIGzGsOG7o25nIGzhu5tuIG5o4bqldCDhu58gY8OhYyBsb+G6oWkgZGluaCBkxrDhu6FuZyIpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIGJp4buDdSDEkeG7kyAxNyoqDQoNCkNow7puZyB0YSBz4butIGThu6VuZyBnw7NpIGRwbHlyIMSR4buDIHTDrW5oIHRvw6FuIHRy4buNbmcgbMaw4bujbmcgbOG7m24gbmjhuqV0IHRoZW8gbeG7l2kgbG/huqFpIGRpbmggZMaw4buhbmcuIEjDoG0gZ3JvdXBfYnkoKSDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyBuaMOzbSBk4buvIGxp4buHdSB0aGVvIGxv4bqhaSBkaW5oIGTGsOG7oW5nLCBzYXUgxJHDsyBow6BtIHN1bW1hcmlzZSgpIHTDrW5oIHRvw6FuIHRy4buNbmcgbMaw4bujbmcgbOG7m24gbmjhuqV0IGNobyBt4buXaSBuaMOzbS4NClNhdSDEkcOzLCBjaMO6bmcgdGEgdOG6oW8gYmnhu4N1IMSR4buTIGPhu5l0IHPhu60gZOG7pW5nIGdncGxvdDIuIFRy4bulYyB4IGzDoCBsb+G6oWkgZGluaCBkxrDhu6FuZywgdHLhu6VjIHkgbMOgIHRy4buNbmcgbMaw4bujbmcgbOG7m24gbmjhuqV0LCB2w6AgbcOgdSBz4bqvYyDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyBwaMOibiBiaeG7h3QgY8OhYyBsb+G6oWkgZGluaCBkxrDhu6FuZy4NCg0KIyMgKipCaeG7g3UgxJHhu5MgMTgqKg0KDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRhdGFzZXRzKQ0KZGF0YSgiQ2hpY2tXZWlnaHQiKQ0KZ2EgPC0gQ2hpY2tXZWlnaHQNCmNoaWNrd2VpZ2h0X3RpbWVfMjAgPC0gZ2EgJT4lDQogIGZpbHRlcihUaW1lID09IDIwKQ0KYXZlcmFnZV93ZWlnaHRfYnlfZGlldCA8LSBjaGlja3dlaWdodF90aW1lXzIwICU+JQ0KICBncm91cF9ieShEaWV0KSAlPiUNCiAgc3VtbWFyaXNlKGF2ZXJhZ2Vfd2VpZ2h0ID0gbWVhbih3ZWlnaHQpKQ0KZ2dwbG90KGF2ZXJhZ2Vfd2VpZ2h0X2J5X2RpZXQsIGFlcyh4ID0gZmFjdG9yKERpZXQpLCB5ID0gYXZlcmFnZV93ZWlnaHQsIGZpbGwgPSBmYWN0b3IoRGlldCkpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGxhYnMoeCA9ICJEaWV0IiwgeSA9ICJUcuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oIiwgZmlsbCA9ICJEaWV0IikgKw0KICBnZ3RpdGxlKCJUcuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oIOG7nyB0aOG7nWkgxJFp4buDbSAyMCBj4bunYSBjw6FjIGxv4bqhaSBkaW5oIGTGsOG7oW5nIikNCmBgYA0KKipnaeG6o2kgdGjDrWNoIGJp4buDdSDEkeG7kyAxOCoqDQoNCsSQ4bqndSB0acOqbiwgY2jDum5nIHRhIGzhu41jIGThu68gbGnhu4d1IMSR4buDIGNo4buJIGdp4buvIGzhuqFpIGPDoWMgcXVhbiBzw6F0IHThuqFpIHRo4budaSDEkWnhu4NtIDIwIGLhurFuZyBjw6FjaCBz4butIGThu6VuZyBow6BtIGZpbHRlcigpIGPhu6dhIGfDs2kgZHBseXIuDQpUaeG6v3AgdGhlbywgY2jDum5nIHRhIHTDrW5oIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggY2hvIG3hu5dpIGxv4bqhaSBkaW5oIGTGsOG7oW5nIGLhurFuZyBjw6FjaCBz4butIGThu6VuZyBow6BtIHN1bW1hcmlzZSgpIMSR4buDIHTDrW5oIHRvw6FuIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY2hvIHThu6tuZyBuaMOzbS4NCkN14buRaSBjw7luZywgY2jDum5nIHRhIHThuqFvIGJp4buDdSDEkeG7kyBj4buZdCBz4butIGThu6VuZyBnZ3Bsb3QyLCB0cm9uZyDEkcOzIHRy4bulYyB4IGzDoCBsb+G6oWkgZGluaCBkxrDhu6FuZywgdHLhu6VjIHkgbMOgIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmgsIHbDoCBtw6B1IHPhuq9jIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHBow6JuIGJp4buHdCBjw6FjIGxv4bqhaSBkaW5oIGTGsOG7oW5nDQoNCnRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggY+G7p2EgZGluaCBkxrDhu6FuZyBsb+G6oWkgMyB0cm9uZyAyMCBuZ8OgeSBsw6AgdOG7kXQgbmjhuqV0DQoNCiMjICoqxJDhu5MgdGjhu4sgMTkqKg0KDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRhdGFzZXRzKQ0KZGF0YSgiQ2hpY2tXZWlnaHQiKQ0KZ2EgPC0gQ2hpY2tXZWlnaHQNCmNoaWNrd2VpZ2h0X3dlaWdodF8xMDAgPC0gZ2EgJT4lDQogIGZpbHRlcih3ZWlnaHQgPT0gMTAwKQ0KYXZlcmFnZV90aW1lX2J5X2RpZXQgPC0gY2hpY2t3ZWlnaHRfd2VpZ2h0XzEwMCAlPiUNCiAgZ3JvdXBfYnkoRGlldCkgJT4lDQogIHN1bW1hcmlzZShhdmVyYWdlX3RpbWUgPSBtZWFuKFRpbWUpKQ0KDQojIFThuqFvIGJp4buDdSDEkeG7kyDEkcaw4budbmcNCmdncGxvdChhdmVyYWdlX3RpbWVfYnlfZGlldCwgYWVzKHggPSBmYWN0b3IoRGlldCksIHkgPSBhdmVyYWdlX3RpbWUsIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBnZW9tX3BvaW50KCkgKw0KICBsYWJzKHggPSAiRGlldCIsIHkgPSAiVGjhu51pIGdpYW4gdHJ1bmcgYsOsbmggKMSR4bqhdCB0cuG7jW5nIGzGsOG7o25nIDEwMCkiKSArDQogIGdndGl0bGUoIlRo4budaSBnaWFuIHRydW5nIGLDrG5oIMSR4buDIMSR4bqhdCB0cuG7jW5nIGzGsOG7o25nIDEwMCB0aGVvIGxv4bqhaSBkaW5oIGTGsOG7oW5nIikNCg0KYGBgDQoqKkdp4bqjaSB0aMOtY2ggxJHhu5MgdGjhu4sgMTkqKg0KDQpDaMO6bmcgdGEgc+G7rSBk4bulbmcgZ8OzaSBkcGx5ciDEkeG7gyBs4buNYyBk4buvIGxp4buHdSB2w6AgdMOtbmggdG/DoW4gdHJ1bmcgYsOsbmguIMSQ4bqndSB0acOqbiwgY2jDum5nIHRhIGzhu41jIGThu68gbGnhu4d1IMSR4buDIGNo4buJIGdp4buvIGzhuqFpIGPDoWMgcXVhbiBzw6F0IGPDsyB0cuG7jW5nIGzGsOG7o25nIGLhurFuZyAxMDAuIFNhdSDEkcOzLCBjaMO6bmcgdGEgdMOtbmggdHJ1bmcgYsOsbmggdGjhu51pIGdpYW4gY2hvIG3hu5dpIGxv4bqhaSBkaW5oIGTGsOG7oW5nIGLhurFuZyBjw6FjaCBz4butIGThu6VuZyBow6BtIGdyb3VwX2J5KCkgdsOgIHN1bW1hcmlzZSgpLg0KVGnhur9wIHRoZW8sIGNow7puZyB0YSB04bqhbyBiaeG7g3UgxJHhu5MgxJHGsOG7nW5nIHPhu60gZOG7pW5nIGdncGxvdDIuIFRy4bulYyB4IGzDoCBsb+G6oWkgZGluaCBkxrDhu6FuZywgdHLhu6VjIHkgbMOgIHRo4budaSBnaWFuIHRydW5nIGLDrG5oICjEkeG7gyDEkeG6oXQgxJHGsOG7o2MgdHLhu41uZyBsxrDhu6NuZyAxMDApLCB2w6AgY2jDum5nIHRhIHPhu60gZOG7pW5nIGdlb21fbGluZSgpIHbDoCBnZW9tX3BvaW50KCkgxJHhu4MgduG6vSDEkcaw4budbmcgdsOgIMSRaeG7g20gdHLDqm4gYmnhu4N1IMSR4buTLg0KDQojIyAqKkJp4buDdSDEkeG7kyAyMCoqDQoNCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZGF0YXNldHMpDQpkYXRhKCJDaGlja1dlaWdodCIpDQpnYSA8LSBDaGlja1dlaWdodA0KY2hpY2tfY291bnRzX2J5X2RpZXQgPC0gZ2EgJT4lDQogIGdyb3VwX2J5KERpZXQpICU+JQ0KICBzdW1tYXJpc2UoQ291bnQgPSBuX2Rpc3RpbmN0KENoaWNrKSkNCg0KZ2dwbG90KGNoaWNrX2NvdW50c19ieV9kaWV0LCBhZXMoeCA9IGZhY3RvcihEaWV0KSwgeSA9IENvdW50LCBmaWxsID0gZmFjdG9yKERpZXQpKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBsYWJzKHggPSAiRGlldCIsIHkgPSAiU+G7kSBsxrDhu6NuZyBDaGljayIsIGZpbGwgPSAiRGlldCIpICsNCiAgZ2d0aXRsZSgiU+G7kSBsxrDhu6NuZyBDaGljayB0aGVvIERpZXQiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIGJp4buDdSDEkeG7kyAyMCoqDQoNCkNow7puZyB0YSBz4butIGThu6VuZyBncm91cF9ieSgpIHbDoCBzdW1tYXJpc2UoKSB04burIGfDs2kgZHBseXIgxJHhu4MgdMOtbmggc+G7kSBsxrDhu6NuZyBjaGljayBjaG8gbeG7l2kgZGlldC4NClNhdSDEkcOzLCBjaMO6bmcgdGEgduG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgKGJhciBjaGFydCkgYuG6sW5nIGdncGxvdDIsIHbhu5tpIHRy4bulYyB4IGzDoCBsb+G6oWkgZGlldCwgdHLhu6VjIHkgbMOgIHPhu5EgbMaw4bujbmcgY2hpY2ssIHbDoCBtw6B1IHPhuq9jIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHBow6JuIGJp4buHdCBjw6FjIGRpZXQuDQoNCg0KDQoNCg0KDQoNCg==