1 Giới thiệu bộ dữ liệu

Bộ dữ liệu này bao gồm các cột sau:

  • weight: Cân nặng của gà con, được đo trong các đơn vị không xác định (thường là đồ chơi hoặc gram).

  • Time: Thời gian theo ngày hoặc tuần trong thí nghiệm. Đây là thời gian khi mẫu gà con được đo cân nặng.

  • Chick: Mã số của gà con. Mỗi con gà trong thí nghiệm được gán một mã số duy nhất để theo dõi.

  • Diet: Loại thức ăn được cung cấp cho gà con. Đây có thể là biến phân loại mô tả các loại thức ăn khác nhau được sử dụng trong thí nghiệm.

  • Mục tiêu của bộ dữ liệu này có thể là để nghiên cứu sự ảnh hưởng của chế độ ăn uống (các loại thức ăn khác nhau) đến tăng trưởng và phát triển của gà con. Các nhà nghiên cứu có thể sử dụng bộ dữ liệu này để thực hiện các phân tích thống kê hoặc mô hình hóa dữ liệu để hiểu rõ hơn về cách chế độ ăn uống ảnh hưởng đến sự phát triển của gà con.

2 Các biểu đồ

2.1 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 đồ cho ta thấy số lượng gà con của từng loại dinh dưỡng nhưng ở dạng Pie chart

  • với loại 1 là 220 con là lớn nhất và loại 4 là ít nhất với 118 con

2.2 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

2.3 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.

2.4 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).

2.5 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.

2.6 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

2.7 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

2.8 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

2.9 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ể

2.10 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

2.11 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.

2.12 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

2.13 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

2.14 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

2.15 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”.

2.16 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.

2.17 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

2.18 Đồ 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 đồ.

2.19 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==