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

Bộ dữ liệu Diamonds là một bộ dữ liệu phổ biến trong lĩnh vực khoa học dữ liệu. Bộ dữ liệu bao gồm những thuộc tính và những thông tin liên quan về những viên kim cương. Bộ dữ liệu gồm có 53940 quan sát tương đương với 53940 viên kim cương và 10 đối tương đương với 10 thuộc tính.

Ý nghĩa từng đối tượng:

  • carat: Trọng lượng của kim cương, đơn vị là carat.

  • cut: Chất lượng cắt của kim cương. Có thể là ‘Fair’, ‘Good’, ‘Very Good’, ‘Premium’, hoặc ‘Ideal’.

  • color: Màu sắc của kim cương, từ J (kém nhất) đến D (tốt nhất).

  • clarity: Độ tinh khiết của kim cương. Có thể là ‘I1’ (kém nhất), ‘SI2’, ‘SI1’, ‘VS2’, ‘VS1’, ‘VVS2’, ‘VVS1’, hoặc ‘IF’ (tốt nhất).

  • depth: Tỉ lệ giữa chiều cao và chiều rộng của kim cương, được tính bằng phần trăm.

  • table: Tỉ lệ giữa chiều rộng của mặt trên cùng (bàn) và chiều rộng tổng thể của kim cương, được tính bằng phần trăm.

  • price: Giá của kim cương, đơn vị là USD.

  • x: Chiều dài của kim cương, đơn vị là mm.

  • y: Chiều rộng của kim cương, đơn vị là mm.

  • z: Chiều cao của kim cương, đơn vị là mm.

2 Vẽ biểu đồ

Sau đây là 30 biểu đồ được tạo nên từ bộ dữ liệu Diamonds

2.1 Biểu đồ 1

tmp <- diamonds
tmp %>% ggplot(aes(x = color)) +
    geom_bar() +
    labs(x = 'Màu', y = 'Số lượng')

Biểu đồ 1 thể hiện số lượng viên kim cương theo từng màu. Ta thấy màu G có số lượng nhiều nhất và ít nhất là màu J.

2.2 Biểu đồ 2

library(tidyverse)
library(scales)
tmp <- diamonds
tmp %>% ggplot(aes(x = clarity)) +
    geom_bar(fill='lightblue') +
    labs(x = 'Độ tinh khiết', y = 'Số lượng')

Biểu đồ 2 thể hiện số lượng viên kim cương theo từng độ tinh khiết. Ta thấy rằng SI1 có số lượng nhiều nhất còn I1 là ít nhất.

2.3 Biểu đồ 3

tmp %>% group_by(color) %>% summarise(n = n()) %>%
  ggplot(aes(color,n)) +
    geom_col(fill='blue') +
    geom_text(aes(label = percent(n/length(tmp$carat))),vjust = 1, color = 'yellow') +
    labs(x = 'Màu', y = 'Số lượng')

Biểu đồ 3 thể hiện số lượng và tỉ lệ phần trăm của từng màu. Ta thấy màu G có số lượng lớn nhất với 20.93% và ít nhất là màu J với 5.21%.

2.4 Biểu đồ 4

tmp %>% group_by(clarity) %>% summarise(n = n()) %>%
  ggplot(aes(clarity,n)) +
    geom_col(fill='darkblue') +
    geom_text(aes(label = percent(n/length(tmp$carat))),vjust = 1, color = 'yellow') +
    labs(x = 'Độ tinh khiết', y = 'Số lượng')

Biểu đồ 4 thể hiện số lượng và tỉ lệ phần trăm của từng độ tinh khiết. Ta thấy SI1 có số lượng nhiều nhất với 24.2 % và I1 ít nhất với 1.4%.

2.5 Biểu đồ 5

tmp %>% group_by(clarity,color) %>% summarise(n=n()) %>%
  ggplot(aes(x = clarity,y = n)) +
    geom_col(position = 'dodge') +
    geom_col(fill='red') +
    facet_wrap(~color) +
    geom_text(aes(label = n),vjust = 0.5, color = 'darkgreen') +
    labs(x = 'Độ tinh khiết', y = 'Số lượng')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Biểu đồ 5 là tập hợp của những biểu đồ nhỏ thể hiện số lượng theo độ tinh khiết của từng màu. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta có thể thấy số lượng viên kim cương màu D có độ tinh khiết I1 là 42, số lượng viên kim cương màu D có độ tinh khiết SI2 là 1370,…

2.6 Biểu đồ 6

tmp %>% group_by(clarity,cut) %>% summarise(n=n()) %>%
  ggplot(aes(x = clarity,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut) +
    geom_col(fill='green') +
    geom_text(aes(label = n),vjust = 0.3, color = 'blue') +
    labs(x = 'Độ tinh khiết', y = 'Số lượng')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Biểu đồ 6 là tập hợp của những biểu đồ nhỏ thể hiện số lượng theo độ tinh khiết của từng loại. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta có thể thấy số lượng viên kim cương loại Fair có độ tinh khiết I1 là 210, số lượng viên kim cương màu D có độ tinh khiết SI2 là 466,…

2.7 Biểu đồ 7

tmp %>% group_by(color,cut) %>% summarise(n=n()) %>%
  ggplot(aes(x = color,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut) +
    geom_col(fill='lightgreen') +
    geom_text(aes(label = n),vjust = 0.3, color = 'red') +
    labs(x = 'Màu', y = 'Số lượng')
## `summarise()` has grouped output by 'color'. You can override using the
## `.groups` argument.

Biểu đồ 7 là tập hợp của những biểu đồ nhỏ thể hiện số lượng theo màu của từng loại. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta có thể thấy số lượng viên kim cương loại Fair có màu D là 163, số lượng viên kim cương loại Fair có màu E là 224,…

2.8 Biểu đồ 8

tmp %>% group_by(cut,clarity) %>% summarise(n=n()) %>%
  ggplot(aes(x = cut,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~clarity) +
    geom_col(fill='lightblue') +
    geom_text(aes(label = n),vjust = 0.3, color = 'red') +
    labs(x = 'Loại', y = 'Số lượng')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Biểu đồ 8 là tập hợp của những biểu đồ nhỏ thể hiện số lượng theo loại của từng độ tinh khiết. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta có thể thấy số lượng viên kim cương có độ tinh khiết I1 thuộc loại Fair là 210, số lượng viên kim cương có độ tinh khiết I1 thuộc loại Fair là 96,…

2.9 Biểu đồ 9

tmp %>% group_by(color,clarity) %>% summarise(n=n()) %>%
  ggplot(aes(x = color,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~clarity) +
    geom_col(fill='green') +
    geom_text(aes(label = n),vjust = 0.3, color = 'red') +
    labs(x = 'Màu', y = 'Số lượng')
## `summarise()` has grouped output by 'color'. You can override using the
## `.groups` argument.

Biểu đồ 9 là tập hợp của những biểu đồ nhỏ thể hiện số lượng theo màu của từng độ tinh khiết. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta có thể thấy số lượng viên kim cương có độ tinh khiết I1 màu D là 42, số lượng viên kim cương có độ tinh khiết I1 màu E là 102,…

2.10 Biểu đồ 10

tmp <- diamonds
tmp %>% group_by(color) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    geom_col(fill='lightblue') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'blue') +
    labs(x = 'Màu', y = 'Trọng lượng trung bình')

Biểu đồ 10 thể hiện trọng lượng trung bình của những viên kim cương theo màu. Ta thấy màu J có trọng lượng trung bình lớn nhất với 1.16 carat còn bé nhất là màu D và E với 0.66 carat

2.11 Biểu đồ 11

tmp <- diamonds
tmp %>% group_by(clarity) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge') +
    geom_col(fill='lightgreen') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'red') +
    labs(x = 'Độ tinh khiết', y = 'Trọng lượng trung bình')

Biểu đồ 11 thể hiện trọng lượng trung bình của những viên kim cương theo độ tinh khiết. Ta thấy màu I1 có trọng lượng trung bình lớn nhất với 1.28 carat còn bé nhất là VVS1 với 0.5 carat

2.12 Biểu đồ 12

tmp <- diamonds
tmp %>% group_by(cut) %>% summarise(m= mean(x)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge') +
    geom_col(fill='lightblue') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'blue') +
    labs(x = 'Loại', y = 'Chiều dài trung bình')

Biểu đồ 12 thể hiện chiều dài trung bình của những viên kim cương theo loại. Ta thấy loại Fair có chiều dài trung bình lớn nhất với 6.52 mm còn ngắn nhẩt là loại Ideal với 5.51 mm

2.13 Biểu đồ 13

tmp <- diamonds
tmp %>% group_by(color) %>% summarise(m= mean(x)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    geom_col(fill='orange') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'blue') +
    labs(x = 'Màu', y = 'Chiều dài trung bình')

Biểu đồ 13 thể hiện chiều dài trung bình của những viên kim cương theo màu. Ta thấy màu J có chiều dài trung bình lớn nhất với 6.52 mm còn ngắn nhẩt là màu E với 5.41 mm

2.14 Biểu đồ 14

tmp <- diamonds
tmp %>% group_by(clarity) %>% summarise(m= mean(x)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge') +
    geom_col(fill='lightgreen') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'blue') +
    labs(x = 'Độ tinh khiết', y = 'Chiều dài trung bình')

Biểu đồ 14 thể hiện chiều dài trung bình của những viên kim cương theo độ tinh khiết. Ta thấy I1 có chiều dài trung bình lớn nhất với 6.76 mm còn ngắn nhẩt là VVS1 với 4.96 mm

2.15 Biểu đồ 15

tmp <- diamonds
tmp %>% group_by(color) %>% summarise(m= mean(y)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    geom_col(fill='darkgreen') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'yellow') +
    labs(x = 'Màu', y = 'Chiều rộng trung bình')

Biểu đồ 15 thể hiện chiều rộng trung bình của những viên kim cương theo màu. Ta thấy màu J có chiều dài trung bình lớn nhất với 6.52 mm còn ngắn nhẩt là màu D và E với 5.42 mm

2.16 Biểu đồ 16

tmp <- diamonds
tmp %>% group_by(cut) %>% summarise(m= mean(y)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge') +
    geom_col(fill='lightblue') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'darkgreen') +
    labs(x = 'Loài', y = 'Chiều rộng trung bình')

Biểu đồ 16 thể hiện chiều rộng trung bình của những viên kim cương theo loại. Ta thấy loại Fair có chiều rộng trung bình lớn nhất với 6.18 mm còn ngắn nhất là loại Ideal với 5.52 mm

2.17 Biểu đồ 17

tmp <- diamonds
tmp %>% group_by(clarity) %>% summarise(m= mean(y)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge') +
    geom_col(fill='lightgreen') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'black') +
    labs(x = 'Độ tinh khiết', y = 'Chiều rộng trung bình')

Biểu đồ 17 thể hiện chiều rộng trung bình của những viên kim cương theo độ tinh khiết. Ta thấy loại I1 có chiều rộng trung bình lớn nhất với 6.71 mm còn ngắn nhất là loại VVS1 với 4.98 mm

2.18 Biểu đồ 18

tmp <- diamonds
tmp %>% group_by(cut) %>% summarise(m= mean(price)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge') +
    geom_col(fill='lightblue') +
    geom_text(aes(label = round(m,)), vjust = 2, color = 'blue') +
    labs(x = 'Loại', y = 'Mức giá trung bình')

Biểu đồ 18 thể hiện mức giá trung bình của những viên kim cương theo loại. Ta thấy loại Premium có mức giá trung bình cao nhất với 4584$ còn thấp nhất là loại Ideal với 3458$

2.19 Biểu đồ 19

tmp <- diamonds
tmp %>% group_by(color) %>% summarise(m= mean(price)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    geom_col(fill='gray') +
    geom_text(aes(label = round(m,)), vjust = 2, color = 'black') +
    labs(x = 'Màu', y = 'Mức giá trung bình')

Biểu đồ 19 thể hiện mức giá trung bình của những viên kim cương theo màu. Ta thấy màu J có mức giá trung bình cao nhất với 5324$ còn thấp nhất là màu E với 3077$

2.20 Biểu đồ 20

tmp <- diamonds
tmp %>% group_by(clarity) %>% summarise(m= mean(price)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge') +
    geom_col(fill='blue') +
    geom_text(aes(label = round(m,)), vjust = 2, color = 'white') +
    labs(x = 'Độ tinh khiết', y = 'Mức giá trung bình')

Biểu đồ 20 thể hiện mức giá trung bình của những viên kim cương theo độ tinh khiết. Ta thấy loại SI2 có mức giá trung bình cao nhất với 5063$ còn thấp nhất là VVS1 với 2523$

2.21 Biểu đồ 21

tmp <- diamonds
tmp %>% group_by(cut,clarity) %>% summarise(m = mean(price)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~clarity) +
    geom_col(fill='lightgreen') +
    geom_text(aes(label = round(m))) +
    labs(x = 'Loại', y = 'Mức giá trung bình')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Biểu đồ 21 là tập hợp của những biểu đồ nhỏ thể hiện mức giá trung bình theo loại của từng độ tinh khiết. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta thấy được mức giá trung bình của những viên kim cương có độ tinh khiết I1 loại Fair là 3704$, mức giá trung bình của những viên kim cương có độ tinh khiết I1 loại Good là 3597 $

2.22 Biểu đồ 22

tmp <- diamonds
tmp %>% group_by(color,clarity) %>% summarise(m = mean(price)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~clarity) +
    geom_col(fill='gray') +
    geom_text(aes(label = round(m))) +
    labs(x = 'Màu', y = 'Mức giá trung bình')
## `summarise()` has grouped output by 'color'. You can override using the
## `.groups` argument.

Biểu đồ 22 là tập hợp của những biểu đồ nhỏ thể hiện mức giá trung bình theo màu của từng độ tinh khiết. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta thấy được mức giá trung bình của những viên kim cương có độ tinh khiết I1 màu D là 3863$, mức giá trung bình của những viên kim cương có độ tinh khiết I1 màu E là 3488 $

2.23 Biểu đồ 23

tmp <- diamonds
tmp %>% group_by(color,cut) %>% summarise(m = mean(price)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut) +
    geom_col(fill='lightgreen') +
    geom_text(aes(label = round(m))) +
    labs(x = 'Màu', y = 'Mức giá trung bình')
## `summarise()` has grouped output by 'color'. You can override using the
## `.groups` argument.

Biểu đồ 23 là tập hợp của những biểu đồ nhỏ thể hiện mức giá trung bình theo màu của từng loại. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta thấy được mức giá trung bình của những viên kim cương loại Fair màu D là 4291$, mức giá trung bình của những viên kim cương loại Fair màu E là 3682 $

2.24 Biểu đồ 24

tmp <- diamonds
tmp %>% group_by(clarity,cut) %>% summarise(m = mean(price)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut) +
    geom_col(fill='lightblue') +
    geom_text(aes(label = round(m))) +
    labs(x = 'Độ tinh khiết', y = 'Mức giá trung bình')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Biểu đồ 24 là tập hợp của những biểu đồ nhỏ thể hiện mức giá trung bình theo độ tinh khiết của từng loại. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta thấy được mức giá trung bình của những viên kim cương loại Fair có độ tinh khiết I1 là 3704$, mức giá trung bình của những viên kim cương loại Fair có độ tinh khiết SI1 là 5174 $

2.25 Biểu đồ 25

tmp <- diamonds
tmp %>% group_by(clarity,color) %>% summarise(m = mean(price)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~color) +
    geom_col(fill='pink') +
    geom_text(aes(label = round(m))) +
    labs(x = 'Độ tinh khiết', y = 'Mức giá trung bình')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Biểu đồ 25 là tập hợp của những biểu đồ nhỏ thể hiện mức giá trung bình theo độ tinh khiết của từng màu. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta thấy được mức giá trung bình của những viên kim cương màu D có độ tinh khiết I1 là 3863$, mức giá trung bình của những viên kim cương màu D có độ tinh khiết SI1 là 3931 $

2.26 Biểu đồ 26

tmp <- diamonds
tmp %>% group_by(clarity,color) %>% summarise(m = mean(carat)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~color) +
    geom_col(fill='lightblue') +
    geom_text(aes(label = round(m,2)), color = 'darkblue') +
    labs(x = 'Độ tinh khiết', y = 'Trọng lượng trung bình')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Biểu đồ 26 là tập hợp của những biểu đồ nhỏ thể hiện trọng lượng trung bình theo độ tinh khiết của từng màu. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta thấy được trọng lượng trung bình của những viên kim cương màu D có độ tinh khiết I1 là 1.12 carat, trọng lượng trung bình của những viên kim cương màu D có độ tinh khiết SI1 là 0.87 carat

2.27 Biểu đồ 27

tmp <- diamonds
tmp %>% group_by(clarity,cut) %>% summarise(m = mean(carat)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut) +
    geom_col(fill='lightgreen') +
    geom_text(aes(label = round(m,2)), color = 'darkgreen') +
    labs(x = 'Độ tinh khiết', y = 'Trọng lượng trung bình')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Biểu đồ 27 là tập hợp của những biểu đồ nhỏ thể hiện trọng lượng trung bình theo độ tinh khiết của từng loại. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta thấy được trọng lượng trung bình của những viên kim cương loại FairFair có độ tinh khiết I1 là 1.36 carat, trọng lượng trung bình của những viên kim cương loại Fair có độ tinh khiết SI1 là 1.2 carat

2.28 Biểu đồ 28

tmp <- diamonds
tmp %>% group_by(cut,color) %>% summarise(m = mean(carat)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~color) +
    geom_col(fill='gray') +
    geom_text(aes(label = round(m,2)), color = 'darkred') +
    labs(x = 'loại', y = 'Trọng lượng trung bình')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Biểu đồ 28 là tập hợp của những biểu đồ nhỏ thể hiện trọng lượng trung bình theo loại của từng màu. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta thấy được trọng lượng trung bình của những viên kim cương màu D loại Fair là 0.92 carat, trọng lượng trung bình của những viên kim cương màu D loại Good là 0.74 carat

2.29 Biểu đồ 29

tmp <- diamonds
tmp %>% group_by(color,cut) %>% summarise(m = mean(carat)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut) +
    geom_col(fill='red') +
    geom_text(aes(label = round(m,2)), color = 'darkblue') +
    labs(x = 'Màu', y = 'Trọng lượng trung bình')
## `summarise()` has grouped output by 'color'. You can override using the
## `.groups` argument.

Biểu đồ 29 là tập hợp của những biểu đồ nhỏ thể hiện trọng lượng trung bình theo màu của từng loại. Ví dụ: nhìn vào biểu đồ nhỏ thứ nhất ta thấy được trọng lượng trung bình của những viên kim cương loại Fair màu D là 0.92 carat, trọng lượng trung bình của những viên kim cương loại fair màu E là 0.86 carat

2.30 Biểu đồ 30

tmp <- diamonds
tmp1 <- tmp %>% group_by(cut, color) %>% summarise(n = n())
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.
tmp1 %>% ggplot(aes(x = cut, y = n)) +
  geom_col(data = tmp1 %>% filter(color == 'H'), fill = 'green') +
  geom_col(data = tmp1 %>% filter(color == 'I'), fill = 'blue')

Biểu đồ 30 thể hiện số lượng viên kim cương màu H và màu I theo loại 1 cách tương quan. Nhìn vào đây ta thấy được số lượng viên kim cương màu H luôn nhiều hơn màu I nếu xét theo từng loại hay số lượng viên kim cương loại Fair màu H gần gấp đôi số viên kim cương loại Fair màu I

LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSA0Ig0KYXV0aG9yOiAiTmd1eeG7hW4gUXXhu5FjIEjhuqNpIg0KZGF0ZTogIjIwMjQtMDItMjgiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICB0b2M6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShzY2FsZXMpDQpgYGANCiMgKipHaeG7m2kgdGhp4buHdSBi4buZIGThu68gbGnhu4d1IGRpYW1vbmRzKioNCg0KQuG7mSBk4buvIGxp4buHdSBEaWFtb25kcyBsw6AgbeG7mXQgYuG7mSBk4buvIGxp4buHdSBwaOG7lSBiaeG6v24gdHJvbmcgbMSpbmggduG7sWMga2hvYSBo4buNYyBk4buvIGxp4buHdS4gQuG7mSBk4buvIGxp4buHdSBiYW8gZ+G7k20gbmjhu69uZyB0aHXhu5ljIHTDrW5oIHbDoCBuaOG7r25nIHRow7RuZyB0aW4gbGnDqm4gcXVhbiB24buBIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcuIELhu5kgZOG7ryBsaeG7h3UgZ+G7k20gY8OzIDUzOTQwIHF1YW4gc8OhdCB0xrDGoW5nIMSRxrDGoW5nIHbhu5tpIDUzOTQwIHZpw6puIGtpbSBjxrDGoW5nIHbDoCAxMCDEkeG7kWkgdMawxqFuZyDEkcawxqFuZyB24bubaSAxMCB0aHXhu5ljIHTDrW5oLg0KDQrDnSBuZ2jEqWEgdOG7q25nIMSR4buRaSB0xrDhu6NuZzoNCg0KLSBjYXJhdDogVHLhu41uZyBsxrDhu6NuZyBj4bunYSBraW0gY8awxqFuZywgxJHGoW4gduG7iyBsw6AgY2FyYXQuDQoNCi0gY3V0OiBDaOG6pXQgbMaw4bujbmcgY+G6r3QgY+G7p2Ega2ltIGPGsMahbmcuIEPDsyB0aOG7gyBsw6Ag4oCYRmFpcuKAmSwg4oCYR29vZOKAmSwg4oCYVmVyeSBHb29k4oCZLCDigJhQcmVtaXVt4oCZLCBob+G6t2Mg4oCYSWRlYWzigJkuDQoNCi0gY29sb3I6IE3DoHUgc+G6r2MgY+G7p2Ega2ltIGPGsMahbmcsIHThu6sgSiAoa8OpbSBuaOG6pXQpIMSR4bq/biBEICh04buRdCBuaOG6pXQpLg0KDQotIGNsYXJpdHk6IMSQ4buZIHRpbmgga2hp4bq/dCBj4bunYSBraW0gY8awxqFuZy4gQ8OzIHRo4buDIGzDoCDigJhJMeKAmSAoa8OpbSBuaOG6pXQpLCDigJhTSTLigJksIOKAmFNJMeKAmSwg4oCYVlMy4oCZLCDigJhWUzHigJksIOKAmFZWUzLigJksIOKAmFZWUzHigJksIGhv4bq3YyDigJhJRuKAmSAodOG7kXQgbmjhuqV0KS4NCg0KLSBkZXB0aDogVOG7iSBs4buHIGdp4buvYSBjaGnhu4F1IGNhbyB2w6AgY2hp4buBdSBy4buZbmcgY+G7p2Ega2ltIGPGsMahbmcsIMSRxrDhu6NjIHTDrW5oIGLhurFuZyBwaOG6p24gdHLEg20uDQoNCi0gdGFibGU6IFThu4kgbOG7hyBnaeG7r2EgY2hp4buBdSBy4buZbmcgY+G7p2EgbeG6t3QgdHLDqm4gY8O5bmcgKGLDoG4pIHbDoCBjaGnhu4F1IHLhu5luZyB04buVbmcgdGjhu4MgY+G7p2Ega2ltIGPGsMahbmcsIMSRxrDhu6NjIHTDrW5oIGLhurFuZyBwaOG6p24gdHLEg20uDQoNCi0gcHJpY2U6IEdpw6EgY+G7p2Ega2ltIGPGsMahbmcsIMSRxqFuIHbhu4sgbMOgIFVTRC4NCg0KLSB4OiBDaGnhu4F1IGTDoGkgY+G7p2Ega2ltIGPGsMahbmcsIMSRxqFuIHbhu4sgbMOgIG1tLg0KDQotIHk6IENoaeG7gXUgcuG7mW5nIGPhu6dhIGtpbSBjxrDGoW5nLCDEkcahbiB24buLIGzDoCBtbS4NCg0KLSB6OiBDaGnhu4F1IGNhbyBj4bunYSBraW0gY8awxqFuZywgxJHGoW4gduG7iyBsw6AgbW0uDQoNCiMgKipW4bq9IGJp4buDdSDEkeG7kyoqDQoNClNhdSDEkcOieSBsw6AgMzAgYmnhu4N1IMSR4buTIMSRxrDhu6NjIHThuqFvIG7Dqm4gdOG7qyBi4buZIGThu68gbGnhu4d1IERpYW1vbmRzDQoNCg0KIyMgKipCaeG7g3UgxJHhu5MgMSoqDQpgYGB7cn0NCnRtcCA8LSBkaWFtb25kcw0KdG1wICU+JSBnZ3Bsb3QoYWVzKHggPSBjb2xvcikpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KQmnhu4N1IMSR4buTIDEgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgdmnDqm4ga2ltIGPGsMahbmcgdGhlbyB04burbmcgbcOgdS4gVGEgdGjhuqV5IG3DoHUgRyBjw7Mgc+G7kSBsxrDhu6NuZyBuaGnhu4F1IG5o4bqldCB2w6Agw610IG5o4bqldCBsw6AgbcOgdSBKLg0KDQojIyAqKkJp4buDdSDEkeG7kyAyKioNCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc2NhbGVzKQ0KdG1wIDwtIGRpYW1vbmRzDQp0bXAgJT4lIGdncGxvdChhZXMoeCA9IGNsYXJpdHkpKSArDQogICAgZ2VvbV9iYXIoZmlsbD0nbGlnaHRibHVlJykgKw0KICAgIGxhYnMoeCA9ICfEkOG7mSB0aW5oIGtoaeG6v3QnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCkJp4buDdSDEkeG7kyAyIHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIHZpw6puIGtpbSBjxrDGoW5nIHRoZW8gdOG7q25nIMSR4buZIHRpbmgga2hp4bq/dC4gVGEgdGjhuqV5IHLhurFuZyBTSTEgY8OzIHPhu5EgbMaw4bujbmcgbmhp4buBdSBuaOG6pXQgY8OybiBJMSBsw6Agw610IG5o4bqldC4NCg0KIyMgKipCaeG7g3UgxJHhu5MgMyoqDQpgYGB7cn0NCnRtcCAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoY29sb3IsbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSdibHVlJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50KG4vbGVuZ3RoKHRtcCRjYXJhdCkpKSx2anVzdCA9IDEsIGNvbG9yID0gJ3llbGxvdycpICsNCiAgICBsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KQmnhu4N1IMSR4buTIDMgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgdsOgIHThu4kgbOG7hyBwaOG6p24gdHLEg20gY+G7p2EgdOG7q25nIG3DoHUuIFRhIHRo4bqleSBtw6B1IEcgY8OzIHPhu5EgbMaw4bujbmcgbOG7m24gbmjhuqV0IHbhu5tpIDIwLjkzJSB2w6Agw610IG5o4bqldCBsw6AgbcOgdSBKIHbhu5tpIDUuMjElLg0KDQojIyAqKkJp4buDdSDEkeG7kyA0KioNCmBgYHtyfQ0KdG1wICU+JSBncm91cF9ieShjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGNsYXJpdHksbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSdkYXJrYmx1ZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChuL2xlbmd0aCh0bXAkY2FyYXQpKSksdmp1c3QgPSAxLCBjb2xvciA9ICd5ZWxsb3cnKSArDQogICAgbGFicyh4ID0gJ8SQ4buZIHRpbmgga2hp4bq/dCcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KQmnhu4N1IMSR4buTIDQgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgdsOgIHThu4kgbOG7hyBwaOG6p24gdHLEg20gY+G7p2EgdOG7q25nIMSR4buZIHRpbmgga2hp4bq/dC4gVGEgdGjhuqV5IFNJMSBjw7Mgc+G7kSBsxrDhu6NuZyBuaGnhu4F1IG5o4bqldCB24bubaSAyNC4yICUgdsOgIEkxIMOtdCBuaOG6pXQgduG7m2kgMS40JS4NCg0KIyMgKipCaeG7g3UgxJHhu5MgNSoqDQpgYGB7cn0NCnRtcCAlPiUgZ3JvdXBfYnkoY2xhcml0eSxjb2xvcikgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG4pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZ2VvbV9jb2woZmlsbD0ncmVkJykgKw0KICAgIGZhY2V0X3dyYXAofmNvbG9yKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMC41LCBjb2xvciA9ICdkYXJrZ3JlZW4nKSArDQogICAgbGFicyh4ID0gJ8SQ4buZIHRpbmgga2hp4bq/dCcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KQmnhu4N1IMSR4buTIDUgbMOgIHThuq1wIGjhu6NwIGPhu6dhIG5o4buvbmcgYmnhu4N1IMSR4buTIG5o4buPIHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIHRoZW8gxJHhu5kgdGluaCBraGnhur90IGPhu6dhIHThu6tuZyBtw6B1LiBWw60gZOG7pTogbmjDrG4gdsOgbyBiaeG7g3UgxJHhu5Mgbmjhu48gdGjhu6kgbmjhuqV0IHRhIGPDsyB0aOG7gyB0aOG6pXkgc+G7kSBsxrDhu6NuZyB2acOqbiBraW0gY8awxqFuZyBtw6B1IEQgY8OzIMSR4buZIHRpbmgga2hp4bq/dCBJMSBsw6AgNDIsIHPhu5EgbMaw4bujbmcgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBEIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgU0kyIGzDoCAxMzcwLC4uLg0KDQojIyAqKkJp4buDdSDEkeG7kyA2KioNCmBgYHtyfQ0KdG1wICU+JSBncm91cF9ieShjbGFyaXR5LGN1dCkgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG4pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZmFjZXRfd3JhcCh+Y3V0KSArDQogICAgZ2VvbV9jb2woZmlsbD0nZ3JlZW4nKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMC4zLCBjb2xvciA9ICdibHVlJykgKw0KICAgIGxhYnMoeCA9ICfEkOG7mSB0aW5oIGtoaeG6v3QnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCkJp4buDdSDEkeG7kyA2IGzDoCB04bqtcCBo4bujcCBj4bunYSBuaOG7r25nIGJp4buDdSDEkeG7kyBuaOG7jyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyB0aGVvIMSR4buZIHRpbmgga2hp4bq/dCBj4bunYSB04burbmcgbG/huqFpLiBWw60gZOG7pTogbmjDrG4gdsOgbyBiaeG7g3UgxJHhu5Mgbmjhu48gdGjhu6kgbmjhuqV0IHRhIGPDsyB0aOG7gyB0aOG6pXkgc+G7kSBsxrDhu6NuZyB2acOqbiBraW0gY8awxqFuZyBsb+G6oWkgRmFpciBjw7MgxJHhu5kgdGluaCBraGnhur90IEkxIGzDoCAyMTAsIHPhu5EgbMaw4bujbmcgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBEIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgU0kyIGzDoCA0NjYsLi4uDQoNCiMjICoqQmnhu4N1IMSR4buTIDcqKg0KYGBge3J9DQp0bXAgJT4lIGdyb3VwX2J5KGNvbG9yLGN1dCkgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBuKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmN1dCkgKw0KICAgIGdlb21fY29sKGZpbGw9J2xpZ2h0Z3JlZW4nKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMC4zLCBjb2xvciA9ICdyZWQnKSArDQogICAgbGFicyh4ID0gJ03DoHUnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCkJp4buDdSDEkeG7kyA3IGzDoCB04bqtcCBo4bujcCBj4bunYSBuaOG7r25nIGJp4buDdSDEkeG7kyBuaOG7jyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyB0aGVvIG3DoHUgY+G7p2EgdOG7q25nIGxv4bqhaS4gVsOtIGThu6U6IG5ow6xuIHbDoG8gYmnhu4N1IMSR4buTIG5o4buPIHRo4bupIG5o4bqldCB0YSBjw7MgdGjhu4MgdGjhuqV5IHPhu5EgbMaw4bujbmcgdmnDqm4ga2ltIGPGsMahbmcgbG/huqFpIEZhaXIgY8OzIG3DoHUgRCBsw6AgMTYzLCBz4buRIGzGsOG7o25nIHZpw6puIGtpbSBjxrDGoW5nIGxv4bqhaSBGYWlyIGPDsyBtw6B1IEUgbMOgIDIyNCwuLi4NCg0KIyMgKipCaeG7g3UgxJHhu5MgOCoqDQpgYGB7cn0NCnRtcCAlPiUgZ3JvdXBfYnkoY3V0LGNsYXJpdHkpICU+JSBzdW1tYXJpc2Uobj1uKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjdXQseSA9IG4pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZmFjZXRfd3JhcCh+Y2xhcml0eSkgKw0KICAgIGdlb21fY29sKGZpbGw9J2xpZ2h0Ymx1ZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAwLjMsIGNvbG9yID0gJ3JlZCcpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQpCaeG7g3UgxJHhu5MgOCBsw6AgdOG6rXAgaOG7o3AgY+G7p2Egbmjhu69uZyBiaeG7g3UgxJHhu5Mgbmjhu48gdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgdGhlbyBsb+G6oWkgY+G7p2EgdOG7q25nIMSR4buZIHRpbmgga2hp4bq/dC4gVsOtIGThu6U6IG5ow6xuIHbDoG8gYmnhu4N1IMSR4buTIG5o4buPIHRo4bupIG5o4bqldCB0YSBjw7MgdGjhu4MgdGjhuqV5IHPhu5EgbMaw4bujbmcgdmnDqm4ga2ltIGPGsMahbmcgY8OzIMSR4buZIHRpbmgga2hp4bq/dCBJMSB0aHXhu5ljIGxv4bqhaSBGYWlyIGzDoCAyMTAsIHPhu5EgbMaw4bujbmcgdmnDqm4ga2ltIGPGsMahbmcgY8OzIMSR4buZIHRpbmgga2hp4bq/dCBJMSB0aHXhu5ljIGxv4bqhaSBGYWlyIGzDoCA5NiwuLi4NCg0KIyMgKipCaeG7g3UgxJHhu5MgOSoqDQpgYGB7cn0NCnRtcCAlPiUgZ3JvdXBfYnkoY29sb3IsY2xhcml0eSkgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBuKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmNsYXJpdHkpICsNCiAgICBnZW9tX2NvbChmaWxsPSdncmVlbicpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAwLjMsIGNvbG9yID0gJ3JlZCcpICsNCiAgICBsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCkJp4buDdSDEkeG7kyA5IGzDoCB04bqtcCBo4bujcCBj4bunYSBuaOG7r25nIGJp4buDdSDEkeG7kyBuaOG7jyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyB0aGVvIG3DoHUgY+G7p2EgdOG7q25nIMSR4buZIHRpbmgga2hp4bq/dC4gVsOtIGThu6U6IG5ow6xuIHbDoG8gYmnhu4N1IMSR4buTIG5o4buPIHRo4bupIG5o4bqldCB0YSBjw7MgdGjhu4MgdGjhuqV5IHPhu5EgbMaw4bujbmcgdmnDqm4ga2ltIGPGsMahbmcgY8OzIMSR4buZIHRpbmgga2hp4bq/dCBJMSBtw6B1IEQgbMOgIDQyLCBz4buRIGzGsOG7o25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgSTEgbcOgdSBFIGzDoCAxMDIsLi4uDQoNCiMjICoqQmnhu4N1IMSR4buTIDEwKioNCmBgYHtyfQ0KdG1wIDwtIGRpYW1vbmRzDQp0bXAgJT4lIGdyb3VwX2J5KGNvbG9yKSAlPiUgc3VtbWFyaXNlKG09IG1lYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZ2VvbV9jb2woZmlsbD0nbGlnaHRibHVlJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdibHVlJykgKw0KICAgIGxhYnMoeCA9ICdNw6B1JywgeSA9ICdUcuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oJykNCmBgYA0KDQpCaeG7g3UgxJHhu5MgMTAgdGjhu4MgaGnhu4duIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggY+G7p2Egbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyB0aGVvIG3DoHUuIFRhIHRo4bqleSBtw6B1IEogY8OzIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggbOG7m24gbmjhuqV0IHbhu5tpIDEuMTYgY2FyYXQgY8OybiBiw6kgbmjhuqV0IGzDoCBtw6B1IEQgdsOgIEUgduG7m2kgMC42NiBjYXJhdCANCg0KIyMgKipCaeG7g3UgxJHhu5MgMTEqKg0KYGBge3J9DQp0bXAgPC0gZGlhbW9uZHMNCnRtcCAlPiUgZ3JvdXBfYnkoY2xhcml0eSkgJT4lIHN1bW1hcmlzZShtPSBtZWFuKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZ2VvbV9jb2woZmlsbD0nbGlnaHRncmVlbicpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAncmVkJykgKw0KICAgIGxhYnMoeCA9ICfEkOG7mSB0aW5oIGtoaeG6v3QnLCB5ID0gJ1Ry4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmgnKQ0KYGBgDQoNCkJp4buDdSDEkeG7kyAxMSB0aOG7gyBoaeG7h24gdHLhu41uZyBsxrDhu6NuZyB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIHRoZW8gxJHhu5kgdGluaCBraGnhur90LiBUYSB0aOG6pXkgbcOgdSBJMSBjw7MgdHLhu41uZyBsxrDhu6NuZyB0cnVuZyBiw6xuaCBs4bubbiBuaOG6pXQgduG7m2kgMS4yOCBjYXJhdCBjw7JuIGLDqSBuaOG6pXQgbMOgIFZWUzEgduG7m2kgMC41IGNhcmF0DQoNCiMjICoqQmnhu4N1IMSR4buTIDEyKioNCmBgYHtyfQ0KdG1wIDwtIGRpYW1vbmRzDQp0bXAgJT4lIGdyb3VwX2J5KGN1dCkgJT4lIHN1bW1hcmlzZShtPSBtZWFuKHgpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY3V0LHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGdlb21fY29sKGZpbGw9J2xpZ2h0Ymx1ZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAnYmx1ZScpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdDaGnhu4F1IGTDoGkgdHJ1bmcgYsOsbmgnKQ0KYGBgDQoNCkJp4buDdSDEkeG7kyAxMiB0aOG7gyBoaeG7h24gY2hp4buBdSBkw6BpIHRydW5nIGLDrG5oIGPhu6dhIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgdGhlbyBsb+G6oWkuIFRhIHRo4bqleSBsb+G6oWkgRmFpciBjw7MgY2hp4buBdSBkw6BpIHRydW5nIGLDrG5oIGzhu5tuIG5o4bqldCB24bubaSA2LjUyIG1tIGPDsm4gbmfhuq9uIG5o4bqpdCBsw6AgbG/huqFpIElkZWFsIHbhu5tpIDUuNTEgbW0NCg0KIyMgKipCaeG7g3UgxJHhu5MgMTMqKg0KYGBge3J9DQp0bXAgPC0gZGlhbW9uZHMNCnRtcCAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobT0gbWVhbih4KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGdlb21fY29sKGZpbGw9J29yYW5nZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAnYmx1ZScpICsNCiAgICBsYWJzKHggPSAnTcOgdScsIHkgPSAnQ2hp4buBdSBkw6BpIHRydW5nIGLDrG5oJykNCmBgYA0KDQpCaeG7g3UgxJHhu5MgMTMgdGjhu4MgaGnhu4duIGNoaeG7gXUgZMOgaSB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIHRoZW8gbcOgdS4gVGEgdGjhuqV5IG3DoHUgSiBjw7MgY2hp4buBdSBkw6BpIHRydW5nIGLDrG5oIGzhu5tuIG5o4bqldCB24bubaSA2LjUyIG1tIGPDsm4gbmfhuq9uIG5o4bqpdCBsw6AgbcOgdSBFIHbhu5tpIDUuNDEgbW0NCg0KIyMgKipCaeG7g3UgxJHhu5MgMTQqKg0KYGBge3J9DQp0bXAgPC0gZGlhbW9uZHMNCnRtcCAlPiUgZ3JvdXBfYnkoY2xhcml0eSkgJT4lIHN1bW1hcmlzZShtPSBtZWFuKHgpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBnZW9tX2NvbChmaWxsPSdsaWdodGdyZWVuJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdibHVlJykgKw0KICAgIGxhYnMoeCA9ICfEkOG7mSB0aW5oIGtoaeG6v3QnLCB5ID0gJ0NoaeG7gXUgZMOgaSB0cnVuZyBiw6xuaCcpDQpgYGANCg0KQmnhu4N1IMSR4buTIDE0IHRo4buDIGhp4buHbiBjaGnhu4F1IGTDoGkgdHJ1bmcgYsOsbmggY+G7p2Egbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyB0aGVvIMSR4buZIHRpbmgga2hp4bq/dC4gVGEgdGjhuqV5IEkxIGPDsyBjaGnhu4F1IGTDoGkgdHJ1bmcgYsOsbmggbOG7m24gbmjhuqV0IHbhu5tpIDYuNzYgbW0gY8OybiBuZ+G6r24gbmjhuql0IGzDoCBWVlMxIHbhu5tpIDQuOTYgbW0NCg0KIyMgKipCaeG7g3UgxJHhu5MgMTUqKg0KYGBge3J9DQp0bXAgPC0gZGlhbW9uZHMNCnRtcCAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobT0gbWVhbih5KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGdlb21fY29sKGZpbGw9J2RhcmtncmVlbicpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAneWVsbG93JykgKw0KICAgIGxhYnMoeCA9ICdNw6B1JywgeSA9ICdDaGnhu4F1IHLhu5luZyB0cnVuZyBiw6xuaCcpDQpgYGANCg0KQmnhu4N1IMSR4buTIDE1IHRo4buDIGhp4buHbiBjaGnhu4F1IHLhu5luZyB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIHRoZW8gbcOgdS4gVGEgdGjhuqV5IG3DoHUgSiBjw7MgY2hp4buBdSBkw6BpIHRydW5nIGLDrG5oIGzhu5tuIG5o4bqldCB24bubaSA2LjUyIG1tIGPDsm4gbmfhuq9uIG5o4bqpdCBsw6AgbcOgdSBEIHbDoCBFIHbhu5tpIDUuNDIgbW0NCg0KIyMgKipCaeG7g3UgxJHhu5MgMTYqKg0KYGBge3J9DQp0bXAgPC0gZGlhbW9uZHMNCnRtcCAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG09IG1lYW4oeSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjdXQseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZ2VvbV9jb2woZmlsbD0nbGlnaHRibHVlJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdkYXJrZ3JlZW4nKSArDQogICAgbGFicyh4ID0gJ0xvw6BpJywgeSA9ICdDaGnhu4F1IHLhu5luZyB0cnVuZyBiw6xuaCcpDQpgYGANCg0KQmnhu4N1IMSR4buTIDE2IHRo4buDIGhp4buHbiBjaGnhu4F1IHLhu5luZyB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIHRoZW8gbG/huqFpLiBUYSB0aOG6pXkgbG/huqFpIEZhaXIgY8OzIGNoaeG7gXUgcuG7mW5nIHRydW5nIGLDrG5oIGzhu5tuIG5o4bqldCB24bubaSA2LjE4IG1tIGPDsm4gbmfhuq9uIG5o4bqldCBsw6AgbG/huqFpIElkZWFsIHbhu5tpIDUuNTIgbW0NCg0KIyMgKipCaeG7g3UgxJHhu5MgMTcqKg0KYGBge3J9DQp0bXAgPC0gZGlhbW9uZHMNCnRtcCAlPiUgZ3JvdXBfYnkoY2xhcml0eSkgJT4lIHN1bW1hcmlzZShtPSBtZWFuKHkpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBnZW9tX2NvbChmaWxsPSdsaWdodGdyZWVuJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnxJDhu5kgdGluaCBraGnhur90JywgeSA9ICdDaGnhu4F1IHLhu5luZyB0cnVuZyBiw6xuaCcpDQpgYGANCg0KQmnhu4N1IMSR4buTIDE3IHRo4buDIGhp4buHbiBjaGnhu4F1IHLhu5luZyB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIHRoZW8gxJHhu5kgdGluaCBraGnhur90LiBUYSB0aOG6pXkgbG/huqFpIEkxIGPDsyBjaGnhu4F1IHLhu5luZyB0cnVuZyBiw6xuaCBs4bubbiBuaOG6pXQgduG7m2kgNi43MSBtbSBjw7JuIG5n4bqvbiBuaOG6pXQgbMOgIGxv4bqhaSBWVlMxIHbhu5tpIDQuOTggbW0NCg0KIyMgKipCaeG7g3UgxJHhu5MgMTgqKg0KYGBge3J9DQp0bXAgPC0gZGlhbW9uZHMNCnRtcCAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG09IG1lYW4ocHJpY2UpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY3V0LHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGdlb21fY29sKGZpbGw9J2xpZ2h0Ymx1ZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdibHVlJykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ03hu6ljIGdpw6EgdHJ1bmcgYsOsbmgnKQ0KYGBgDQoNCkJp4buDdSDEkeG7kyAxOCB0aOG7gyBoaeG7h24gbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIHRoZW8gbG/huqFpLiBUYSB0aOG6pXkgbG/huqFpIFByZW1pdW0gY8OzIG3hu6ljIGdpw6EgdHJ1bmcgYsOsbmggY2FvIG5o4bqldCB24bubaSA0NTg0JCBjw7JuIHRo4bqlcCBuaOG6pXQgbMOgIGxv4bqhaSBJZGVhbCB24bubaSAzNDU4JA0KDQojIyAqKkJp4buDdSDEkeG7kyAxOSoqDQpgYGB7cn0NCnRtcCA8LSBkaWFtb25kcw0KdG1wICU+JSBncm91cF9ieShjb2xvcikgJT4lIHN1bW1hcmlzZShtPSBtZWFuKHByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGdlb21fY29sKGZpbGw9J2dyYXknKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sKSksIHZqdXN0ID0gMiwgY29sb3IgPSAnYmxhY2snKSArDQogICAgbGFicyh4ID0gJ03DoHUnLCB5ID0gJ03hu6ljIGdpw6EgdHJ1bmcgYsOsbmgnKQ0KYGBgDQoNCkJp4buDdSDEkeG7kyAxOSB0aOG7gyBoaeG7h24gbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIHRoZW8gbcOgdS4gVGEgdGjhuqV5IG3DoHUgSiBjw7MgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBjYW8gbmjhuqV0IHbhu5tpIDUzMjQkIGPDsm4gdGjhuqVwIG5o4bqldCBsw6AgbcOgdSBFIHbhu5tpIDMwNzckDQoNCiMjICoqQmnhu4N1IMSR4buTIDIwKioNCmBgYHtyfQ0KdG1wIDwtIGRpYW1vbmRzDQp0bXAgJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobT0gbWVhbihwcmljZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjbGFyaXR5LHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGdlb21fY29sKGZpbGw9J2JsdWUnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sKSksIHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ8SQ4buZIHRpbmgga2hp4bq/dCcsIHkgPSAnTeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCcpDQpgYGANCg0KQmnhu4N1IMSR4buTIDIwIHRo4buDIGhp4buHbiBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgdGhlbyDEkeG7mSB0aW5oIGtoaeG6v3QuIFRhIHRo4bqleSBsb+G6oWkgU0kyIGPDsyBt4bupYyBnacOhIHRydW5nIGLDrG5oIGNhbyBuaOG6pXQgduG7m2kgNTA2MyQgY8OybiB0aOG6pXAgbmjhuqV0IGzDoCBWVlMxIHbhu5tpIDI1MjMkDQoNCiMjICoqQmnhu4N1IMSR4buTIDIxKioNCmBgYHtyfQ0KdG1wIDwtIGRpYW1vbmRzDQp0bXAgJT4lIGdyb3VwX2J5KGN1dCxjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG0gPSBtZWFuKHByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBmYWNldF93cmFwKH5jbGFyaXR5KSArDQogICAgZ2VvbV9jb2woZmlsbD0nbGlnaHRncmVlbicpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSkpKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnTeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCcpDQpgYGANCg0KQmnhu4N1IMSR4buTIDIxIGzDoCB04bqtcCBo4bujcCBj4bunYSBuaOG7r25nIGJp4buDdSDEkeG7kyBuaOG7jyB0aOG7gyBoaeG7h24gbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCB0aGVvIGxv4bqhaSBj4bunYSB04burbmcgxJHhu5kgdGluaCBraGnhur90LiBWw60gZOG7pTogIG5ow6xuIHbDoG8gYmnhu4N1IMSR4buTIG5o4buPIHRo4bupIG5o4bqldCB0YSB0aOG6pXkgxJHGsOG7o2MgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgSTEgbG/huqFpIEZhaXIgbMOgIDM3MDQkLCBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgY8OzIMSR4buZIHRpbmgga2hp4bq/dCBJMSBsb+G6oWkgR29vZCBsw6AgMzU5NyAkDQoNCiMjICoqQmnhu4N1IMSR4buTIDIyKioNCmBgYHtyfQ0KdG1wIDwtIGRpYW1vbmRzDQp0bXAgJT4lIGdyb3VwX2J5KGNvbG9yLGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobSA9IG1lYW4ocHJpY2UpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZmFjZXRfd3JhcCh+Y2xhcml0eSkgKw0KICAgIGdlb21fY29sKGZpbGw9J2dyYXknKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0pKSkgKw0KICAgIGxhYnMoeCA9ICdNw6B1JywgeSA9ICdN4bupYyBnacOhIHRydW5nIGLDrG5oJykNCmBgYA0KDQpCaeG7g3UgxJHhu5MgMjIgbMOgIHThuq1wIGjhu6NwIGPhu6dhIG5o4buvbmcgYmnhu4N1IMSR4buTIG5o4buPIHRo4buDIGhp4buHbiBt4bupYyBnacOhIHRydW5nIGLDrG5oIHRoZW8gbcOgdSBj4bunYSB04burbmcgxJHhu5kgdGluaCBraGnhur90LiBWw60gZOG7pTogIG5ow6xuIHbDoG8gYmnhu4N1IMSR4buTIG5o4buPIHRo4bupIG5o4bqldCB0YSB0aOG6pXkgxJHGsOG7o2MgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgSTEgbcOgdSBEIGzDoCAzODYzJCwgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgSTEgbcOgdSBFIGzDoCAzNDg4ICQNCg0KIyMgKipCaeG7g3UgxJHhu5MgMjMqKg0KYGBge3J9DQp0bXAgPC0gZGlhbW9uZHMNCnRtcCAlPiUgZ3JvdXBfYnkoY29sb3IsY3V0KSAlPiUgc3VtbWFyaXNlKG0gPSBtZWFuKHByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmN1dCkgKw0KICAgIGdlb21fY29sKGZpbGw9J2xpZ2h0Z3JlZW4nKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0pKSkgKw0KICAgIGxhYnMoeCA9ICdNw6B1JywgeSA9ICdN4bupYyBnacOhIHRydW5nIGLDrG5oJykNCmBgYA0KDQpCaeG7g3UgxJHhu5MgMjMgbMOgIHThuq1wIGjhu6NwIGPhu6dhIG5o4buvbmcgYmnhu4N1IMSR4buTIG5o4buPIHRo4buDIGhp4buHbiBt4bupYyBnacOhIHRydW5nIGLDrG5oIHRoZW8gbcOgdSBj4bunYSB04burbmcgbG/huqFpLiBWw60gZOG7pTogIG5ow6xuIHbDoG8gYmnhu4N1IMSR4buTIG5o4buPIHRo4bupIG5o4bqldCB0YSB0aOG6pXkgxJHGsOG7o2MgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGxv4bqhaSBGYWlyIG3DoHUgRCBsw6AgNDI5MSQsIG3hu6ljIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2Egbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBsb+G6oWkgRmFpciBtw6B1IEUgbMOgIDM2ODIgJA0KDQojIyAqKkJp4buDdSDEkeG7kyAyNCoqDQpgYGB7cn0NCnRtcCA8LSBkaWFtb25kcw0KdG1wICU+JSBncm91cF9ieShjbGFyaXR5LGN1dCkgJT4lIHN1bW1hcmlzZShtID0gbWVhbihwcmljZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjbGFyaXR5LHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmN1dCkgKw0KICAgIGdlb21fY29sKGZpbGw9J2xpZ2h0Ymx1ZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSkpKSArDQogICAgbGFicyh4ID0gJ8SQ4buZIHRpbmgga2hp4bq/dCcsIHkgPSAnTeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCcpDQpgYGANCg0KQmnhu4N1IMSR4buTIDI0IGzDoCB04bqtcCBo4bujcCBj4bunYSBuaOG7r25nIGJp4buDdSDEkeG7kyBuaOG7jyB0aOG7gyBoaeG7h24gbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCB0aGVvIMSR4buZIHRpbmgga2hp4bq/dCBj4bunYSB04burbmcgbG/huqFpLiBWw60gZOG7pTogIG5ow6xuIHbDoG8gYmnhu4N1IMSR4buTIG5o4buPIHRo4bupIG5o4bqldCB0YSB0aOG6pXkgxJHGsOG7o2MgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGxv4bqhaSBGYWlyIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgSTEgbMOgIDM3MDQkLCBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgbG/huqFpIEZhaXIgY8OzIMSR4buZIHRpbmgga2hp4bq/dCBTSTEgbMOgIDUxNzQgJA0KDQojIyAqKkJp4buDdSDEkeG7kyAyNSoqDQpgYGB7cn0NCnRtcCA8LSBkaWFtb25kcw0KdG1wICU+JSBncm91cF9ieShjbGFyaXR5LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG0gPSBtZWFuKHByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZmFjZXRfd3JhcCh+Y29sb3IpICsNCiAgICBnZW9tX2NvbChmaWxsPSdwaW5rJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtKSkpICsNCiAgICBsYWJzKHggPSAnxJDhu5kgdGluaCBraGnhur90JywgeSA9ICdN4bupYyBnacOhIHRydW5nIGLDrG5oJykNCmBgYA0KDQpCaeG7g3UgxJHhu5MgMjUgbMOgIHThuq1wIGjhu6NwIGPhu6dhIG5o4buvbmcgYmnhu4N1IMSR4buTIG5o4buPIHRo4buDIGhp4buHbiBt4bupYyBnacOhIHRydW5nIGLDrG5oIHRoZW8gxJHhu5kgdGluaCBraGnhur90IGPhu6dhIHThu6tuZyBtw6B1LiBWw60gZOG7pTogIG5ow6xuIHbDoG8gYmnhu4N1IMSR4buTIG5o4buPIHRo4bupIG5o4bqldCB0YSB0aOG6pXkgxJHGsOG7o2MgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIG3DoHUgRCBjw7MgxJHhu5kgdGluaCBraGnhur90IEkxIGzDoCAzODYzJCwgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIG3DoHUgRCBjw7MgxJHhu5kgdGluaCBraGnhur90IFNJMSBsw6AgMzkzMSAkDQoNCiMjICoqQmnhu4N1IMSR4buTIDI2KioNCmBgYHtyfQ0KdG1wIDwtIGRpYW1vbmRzDQp0bXAgJT4lIGdyb3VwX2J5KGNsYXJpdHksY29sb3IpICU+JSBzdW1tYXJpc2UobSA9IG1lYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBmYWNldF93cmFwKH5jb2xvcikgKw0KICAgIGdlb21fY29sKGZpbGw9J2xpZ2h0Ymx1ZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIGNvbG9yID0gJ2RhcmtibHVlJykgKw0KICAgIGxhYnMoeCA9ICfEkOG7mSB0aW5oIGtoaeG6v3QnLCB5ID0gJ1Ry4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmgnKQ0KYGBgDQoNCkJp4buDdSDEkeG7kyAyNiBsw6AgdOG6rXAgaOG7o3AgY+G7p2Egbmjhu69uZyBiaeG7g3UgxJHhu5Mgbmjhu48gdGjhu4MgaGnhu4duIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggdGhlbyDEkeG7mSB0aW5oIGtoaeG6v3QgY+G7p2EgdOG7q25nIG3DoHUuIFbDrSBk4bulOiAgbmjDrG4gdsOgbyBiaeG7g3UgxJHhu5Mgbmjhu48gdGjhu6kgbmjhuqV0IHRhIHRo4bqleSDEkcaw4bujYyB0cuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oIGPhu6dhIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBEIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgSTEgbMOgIDEuMTIgY2FyYXQsIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggY+G7p2Egbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBtw6B1IEQgY8OzIMSR4buZIHRpbmgga2hp4bq/dCBTSTEgbMOgIDAuODcgY2FyYXQNCg0KIyMgKipCaeG7g3UgxJHhu5MgMjcqKg0KYGBge3J9DQp0bXAgPC0gZGlhbW9uZHMNCnRtcCAlPiUgZ3JvdXBfYnkoY2xhcml0eSxjdXQpICU+JSBzdW1tYXJpc2UobSA9IG1lYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBmYWNldF93cmFwKH5jdXQpICsNCiAgICBnZW9tX2NvbChmaWxsPSdsaWdodGdyZWVuJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDIpKSwgY29sb3IgPSAnZGFya2dyZWVuJykgKw0KICAgIGxhYnMoeCA9ICfEkOG7mSB0aW5oIGtoaeG6v3QnLCB5ID0gJ1Ry4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmgnKQ0KYGBgDQoNCkJp4buDdSDEkeG7kyAyNyBsw6AgdOG6rXAgaOG7o3AgY+G7p2Egbmjhu69uZyBiaeG7g3UgxJHhu5Mgbmjhu48gdGjhu4MgaGnhu4duIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggdGhlbyDEkeG7mSB0aW5oIGtoaeG6v3QgY+G7p2EgdOG7q25nIGxv4bqhaS4gVsOtIGThu6U6ICBuaMOsbiB2w6BvIGJp4buDdSDEkeG7kyBuaOG7jyB0aOG7qSBuaOG6pXQgdGEgdGjhuqV5IMSRxrDhu6NjIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggY+G7p2Egbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBsb+G6oWkgRmFpckZhaXIgY8OzIMSR4buZIHRpbmgga2hp4bq/dCBJMSBsw6AgMS4zNiBjYXJhdCwgdHLhu41uZyBsxrDhu6NuZyB0cnVuZyBiw6xuaCBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGxv4bqhaSBGYWlyIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgU0kxIGzDoCAxLjIgY2FyYXQNCg0KIyMgKipCaeG7g3UgxJHhu5MgMjgqKg0KYGBge3J9DQp0bXAgPC0gZGlhbW9uZHMNCnRtcCAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG0gPSBtZWFuKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBmYWNldF93cmFwKH5jb2xvcikgKw0KICAgIGdlb21fY29sKGZpbGw9J2dyYXknKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCBjb2xvciA9ICdkYXJrcmVkJykgKw0KICAgIGxhYnMoeCA9ICdsb+G6oWknLCB5ID0gJ1Ry4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmgnKQ0KYGBgDQoNCkJp4buDdSDEkeG7kyAyOCBsw6AgdOG6rXAgaOG7o3AgY+G7p2Egbmjhu69uZyBiaeG7g3UgxJHhu5Mgbmjhu48gdGjhu4MgaGnhu4duIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggdGhlbyBsb+G6oWkgY+G7p2EgdOG7q25nIG3DoHUuIFbDrSBk4bulOiAgbmjDrG4gdsOgbyBiaeG7g3UgxJHhu5Mgbmjhu48gdGjhu6kgbmjhuqV0IHRhIHRo4bqleSDEkcaw4bujYyB0cuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oIGPhu6dhIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBEIGxv4bqhaSBGYWlyIGzDoCAwLjkyIGNhcmF0LCB0cuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oIGPhu6dhIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBEIGxv4bqhaSBHb29kIGzDoCAwLjc0IGNhcmF0DQoNCiMjICoqQmnhu4N1IMSR4buTIDI5KioNCmBgYHtyfQ0KdG1wIDwtIGRpYW1vbmRzDQp0bXAgJT4lIGdyb3VwX2J5KGNvbG9yLGN1dCkgJT4lIHN1bW1hcmlzZShtID0gbWVhbihjYXJhdCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjb2xvcix5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBmYWNldF93cmFwKH5jdXQpICsNCiAgICBnZW9tX2NvbChmaWxsPSdyZWQnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCBjb2xvciA9ICdkYXJrYmx1ZScpICsNCiAgICBsYWJzKHggPSAnTcOgdScsIHkgPSAnVHLhu41uZyBsxrDhu6NuZyB0cnVuZyBiw6xuaCcpDQpgYGANCg0KQmnhu4N1IMSR4buTIDI5IGzDoCB04bqtcCBo4bujcCBj4bunYSBuaOG7r25nIGJp4buDdSDEkeG7kyBuaOG7jyB0aOG7gyBoaeG7h24gdHLhu41uZyBsxrDhu6NuZyB0cnVuZyBiw6xuaCB0aGVvIG3DoHUgY+G7p2EgdOG7q25nIGxv4bqhaS4gVsOtIGThu6U6ICBuaMOsbiB2w6BvIGJp4buDdSDEkeG7kyBuaOG7jyB0aOG7qSBuaOG6pXQgdGEgdGjhuqV5IMSRxrDhu6NjIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggY+G7p2Egbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBsb+G6oWkgRmFpciBtw6B1IEQgbMOgIDAuOTIgY2FyYXQsIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggY+G7p2Egbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBsb+G6oWkgZmFpciBtw6B1IEUgbMOgIDAuODYgY2FyYXQNCg0KIyMgKipCaeG7g3UgxJHhu5MgMzAqKg0KYGBge3J9DQp0bXAgPC0gZGlhbW9uZHMNCnRtcDEgPC0gdG1wICU+JSBncm91cF9ieShjdXQsIGNvbG9yKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpDQp0bXAxICU+JSBnZ3Bsb3QoYWVzKHggPSBjdXQsIHkgPSBuKSkgKw0KICBnZW9tX2NvbChkYXRhID0gdG1wMSAlPiUgZmlsdGVyKGNvbG9yID09ICdIJyksIGZpbGwgPSAnZ3JlZW4nKSArDQogIGdlb21fY29sKGRhdGEgPSB0bXAxICU+JSBmaWx0ZXIoY29sb3IgPT0gJ0knKSwgZmlsbCA9ICdibHVlJykNCmBgYA0KDQpCaeG7g3UgxJHhu5MgMzAgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBIIHbDoCBtw6B1IEkgdGhlbyBsb+G6oWkgMSBjw6FjaCB0xrDGoW5nIHF1YW4uIE5ow6xuIHbDoG8gxJHDonkgdGEgdGjhuqV5IMSRxrDhu6NjIHPhu5EgbMaw4bujbmcgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBIIGx1w7RuIG5oaeG7gXUgaMahbiBtw6B1IEkgbuG6v3UgeMOpdCB0aGVvIHThu6tuZyBsb+G6oWkgaGF5IHPhu5EgbMaw4bujbmcgdmnDqm4ga2ltIGPGsMahbmcgbG/huqFpIEZhaXIgbcOgdSBIIGfhuqduIGfhuqVwIMSRw7RpIHPhu5EgdmnDqm4ga2ltIGPGsMahbmcgbG/huqFpIEZhaXIgbcOgdSBJIA0KDQoNCg0KDQoNCg==