GIỚI THIỆU

Bộ dữ liệu DIAMONS là bộ dữ liệu nằm trong packages tidyverse với hơn 50000 quan sát và 10 biến cho ta biết đầy đủ thông tin về các loại kim cương Và dưới đây là các biểu đồ biểu diễn những thông tin của bộ dữ liệu để dễ dàng thống kê và phân tích

library(ggplot2)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ lubridate 1.9.3     ✔ tibble    3.2.1
## ✔ purrr     1.0.2     ✔ tidyr     1.3.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(scales)
## 
## Attaching package: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
nth <- diamonds

I. Phân tích giá cả trung bình của một số loại kim cương

1. Hình 1.1: Biểu đồ thể hiện mức giá trung bình của kim cương có độ trong suốt VVS1 theo màu

Kim cương có độ trong suốt VVS1 khá ổn định với mức giá trung bình giữa các màu chênh lệch nhau không quá lớn nhưng so mức giá trung bình thấp nhất và cao nhất cũng còn khoảng cách khá xa (gần hai lần)

nth2 <- nth %>% group_by(color,clarity) %>% summarise(n = n(),meanP = mean(price),.groups = 'drop')
nth2 %>% ggplot(aes(x= color, y= meanP)) + geom_col(data = nth2 %>% filter(clarity == 'VVS1'), fill = 'purple')

2. Hình 1.2: Biểu đồ thể hiện mức giá trung bình của kim cương có độ trong suốt SI1 theo màu

Kim cương có độ trong suốt SI1 với mức giá giữa các màu có sự chênh lệch khá lớn , với màu I có mức giá trung bình cao nhất (hơn 5000) gần gấp đôi mức giá trung bình của kim cương có độ trong suốt thấp nhất màu D

nth2 %>% ggplot(aes(x= color, y= meanP)) + geom_col(data = nth2 %>% filter(clarity == 'SI1'), fill = 'yellow')

3. Hình 1.3: Biểu đồ thể hiện mức giá trung bình của kim cương có độ trong suốt IF theo màu

Màu D có mức giá trung bình cao đột biến so với tất cả các màu còn lại, cao hơn gấp từ hai đến ba lần

nth2 %>% ggplot(aes(x= color, y= meanP)) + geom_col(data = nth2 %>% filter(clarity == 'IF'), fill = 'darkcyan')

4. Hình 1.4: So sánh ba biểu đồ kim cương trên

Từ ba biểu đồ trên ta có thể thấy được mức giá trung bình của các loại kim cương khác nhau, để tìm hiểu rõ hơn sự thay đổi trong giá cả đối với các loại kim cương khác nhau ta so sánh ba biểu đồ trên: Cụ thể

  • Kim cương có độ trong suốt VVS1 nhìn chung có mức giá trung bình thấp hơn so với các loại khác nhưng khá ổn định giữa các màu

  • Kim cương có độ trong suốt IF màu D có mức giá cao nhất trong các loại, cao hơn gấp hai đến ba lần so với các loại khác, nhưng cũng là kim cương có độ trong suốt IF mà các màu khác thì mức giá trung bình lại thấp nhất trong các loại

  • Kim cương có độ trong suốt SI1 là oại có mức giá cao và ổn định giữa các màu.

nth3 <- nth %>% group_by(color,clarity) %>% summarise(meanP = mean(price), .groups = 'drop') %>% mutate(clarity= factor(clarity, levels = c("VVS1", "IF", "SI1")))

nth3 %>% ggplot(aes(x= color, y= meanP, fill= clarity)) + geom_col(position = position_dodge())

II. Khối lượng carat trung bình của kim cương theo các yếu tố các nhau

1. Hình 2.1: Biểu đồ khối lượng carat trung bình theo chất lượng chế tác

Khối lượng carat trung bình của mỗi viên kim cương được tổng hợp dưới đây theo chất lượng chế tác của chúng, cụ thể: với chất lượng Fair khối lượng carat trung bình mỗi viên là 1.05, chất lượng Good khối lượng carat trung bình mỗi viên là 0.85, với chất lượng Very Good khối lượng carat trung bình mỗi viên là0.81, với chất lượng Prenium khối lượng carat trung bình mỗi viên là0.89, với chất lượng Ideal khối lượng carat trung bình mỗi viên 0.7

nth %>% group_by(cut) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(fill='black') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'green') +
    labs(x = 'Loại', y = 'Mean')

2. Hình 2.2: Biểu đồ khối lượng carat trung bình theo màu

Mỗi loại màu của kim cương có khối lượng carat khác nhau tùy loại. Qua biểu đồ dưới ta thấy khối lượng carat trung bình của viên kim cương màu J lớn nhất 1.16 carat và màu có khối lượng carat bé nhất là màu D và E: 0.66 carat

nth %>% group_by(color) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(fill='black') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'green') +
    labs(x = 'Color', y = 'Mean')

3. Hình 2.3: Biểu đồ khối lượng carat trung bình theo độ trong suốt

Độ trong suốt của kim cương được chia làm 8 loại khác nhau và theo độ trong suốt mỗi loại có khối lượng carat trung bình được biểu diễn bằng biểu đồ dưới đây cụ thể: khối lượng carat trung bình của kim cương có độ trong suốt I1 cao nhất với 1.28, kim cương có độ trong suốt VVS1 thấp nhất với khối lượng carat trung binh là 0.5

nth %>% group_by(clarity) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(fill='black') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'green') +
    labs(x = 'Độ trong suốt', y = 'Mean')

III. Tổng hợp số lượng kim cương theo các biến khác nhau

1. Hình 3.1: Biểu đồ thể hiện số lượng kim cương theo màu

Qua biểu đồ dưới ta có thể tổng hợp được tất cả số lượng kim cương theo các loại màu khác nhau trong đó: cột cao nhất là kim cương có màu G tức màu G có số lượng kim cương nhiều nhất với hơn 10500 đv; cột thấp nhất là kim cương có màu J tức màu J có số lượng ít nhất với gần 3000 đv.

nth %>% ggplot(aes(x = color)) +
    geom_bar() +
    labs(x = 'Loại ', y = 'Số lượng' )+
    coord_flip()

Cũng như loại biểu đồ trên biểu đồ dưới đây tổng hợp số lương kim cương theo từng loại màu khác nhau nhưng với câu lệnh này ta có thể thông tin chi tiết về từng số lương kim cương như sau: kim cương màu G có số lượng nhiều nhất 11292 đv; kim cương màu J có số lượng ít nhất 2808.

nth %>% group_by(color) %>% summarise(n = n()) %>%
  ggplot(aes(color,n)) +
    geom_col(fill='orange') +
    geom_text(aes(label = n),vjust = 2, color = 'black') +
    labs(x = 'loại  ', y = 'Số lượng')

2. Hình 3.2: Biểu đồ thể hiện số lượng kim cương theo chất lượng chế tác

Qua biểu đồ dưới ta có thể tổng hợp được tất cả số lượng kim cương theo chất lượng chế tác khác nhau cụ thể: số lượng kim cương tăng dần theo mức độ chất lượng từ thấp đến cao, cột cao nhất với chất lượng Ideal có hơn 20000 đv kim cương; cột thấp nhất với chất lượng Fair có gần 2500 đv kim cương.

nth %>% ggplot(aes(x = cut)) +
    geom_bar() +
    labs(x = 'Loại', y = 'Số lượng')+
    coord_flip()

Cũng như loại biểu đồ trên biểu đồ dưới đây tổng hợp số lương kim cương theo chất lương chế tác nhưng với câu lệnh này ta có thể thông tin chi tiết về từng số lương kim cương như sau: kim cương có chất lượng Fair, Good, Very Good, Prenium, Ideal có số lượng lần lượt là 1610, 4906, 12082, 13791, 21551.Với số lượng tỉ lệ thuận với chất lượng chế tác của kim cương

nth %>% group_by(cut ) %>% summarise(n = n()) %>%
  ggplot(aes(cut,n)) +
    geom_col(fill='orange') +
    geom_text(aes(label = n),vjust = 2, color = 'black') +
    labs(x = 'loại ', y = 'Số lượng')

3. Hình 3.3: Biểu đồ thể hiện số lượng kim cương theo độ trong suốt

Qua biểu đồ dưới đây ta tổng hợp được số lượng kim cương theo mức độ trong suốt từng loại cụ thể: kim cương loại Sl1 có số lương cao nhất với hơn 15000 đv, kim cương loại I1 thấp nhất với gần 1250 đv.

nth %>% ggplot(aes(x = clarity)) +
    geom_bar() +
    labs(x = 'Loại', y = 'Số lượng') +
    coord_flip()

Cũng như loại biểu đồ trên biểu đồ dưới đây tổng hợp số lương kim cương theo độ trong suốt nhưng với câu lệnh này ta có thể thông tin chi tiết về từng số lương kim cương như sau: kim cương có độ trong suốt Sl1 có số lượng nhiều nhất 13065 đv và kim cương có độ trong suốt I1 có số lượng ít nhất 741 đv.

nth %>% group_by(clarity ) %>% summarise(n = n()) %>%
  ggplot(aes(clarity,n)) +
    geom_col(fill='orange') +
    geom_text(aes(label = n),vjust = 2, color = 'black') +
    labs(x = 'Loại ', y = 'Số lượng')

IV. Phần trăm lượng kim cương theo các loại kim cương khác nhau

1. Hình 4.1 Biểu đồ tỉ lệ phần trăm kim cương theo màu

Biểu đồ dưới đây thể hiện tỉ lệ phần trăm số lượng kim cương theo màu cụ thể: kim cương màu D chiếm 12.56%, kim cương màu E chiếm 18.16.%, kim cương màu F chiếm 17.69%, kim cương màu G chiếm 20.93%, kim cương màu H chiếm 15.39%, kim cương màu I chiếm 10.05%, kim cương màu J chiếm thấp nhất 5.21%

nth %>% group_by(color) %>% summarise(n = n()) %>%
  ggplot(aes(color,n)) +
    geom_col(fill='dark blue') +
    geom_text(aes(label = percent(n/length(nth$carat))),vjust = 2, color = 'white') +
    labs(x = 'Loại', y = 'Số lượng')

2. Hình 4.2 Biểu đồ tỉ lệ phần trăm kim cương theo chất lượng chế tác

Biểu đồ dưới đây thể hiện tỉ lệ phần trăm số lượng kim cương theo chất lượng chế tác cụ thể: chiếm tỉ lệ cao nhất là số lương kim cương có chất lượng chế tác Ideal với 40%, thấp nhất là tỉ lệ số lượng kim cương có chất lượng chế tác fair 3%

nth %>% group_by(cut) %>% summarise(n = n()) %>%
  ggplot(aes(cut,n)) +
    geom_col(fill='dark blue') +
    geom_text(aes(label = percent(n/length(nth$carat))),vjust = 2, color = 'white') +
    labs(x = 'Loại', y = 'Số lượng')

3. Hình 4.3 Biểu đồ tỉ lệ phần trăm kim cương theo độ trong suốt

Biểu đồ dưới đây thể hiện tỉ lệ phần trăm số lượng kim cương theo độ trong suốt cụ thể: kim cương có độ trong suốt Sl1 cao nhất chiếm 24.2 %, và kim cương có độ trong suốt thấp nhất chỉ chiếm 1.4%

nth %>% group_by(clarity) %>% summarise(n = n()) %>%
  ggplot(aes(clarity,n)) +
    geom_col(fill='dark blue') +
    geom_text(aes(label = percent(n/length(nth$carat))),vjust = 2, color = 'white') +
    labs(x = 'Loại', y = 'Số lượng')

V. So sánh số lượng giữa các loại kim cương ngẫu nhiên

1. Hình 5.1: Biểu đồ so sánh số lượng kim cương theo chất tác có màu D và J

Qua biểu đồ ta thấy có sự chênh lệch khá lớn giữa hai màu kim cương ,cột màu vàng là kim cương màu D có số lượng gấp đôi kim cương màu J là cột màu đen theo từng laoij kim cương có độ chế tac khác nhau.

th <- nth %>% group_by(cut, color) %>% summarise(n = n(),.groups='drop')
th %>% ggplot(aes(x = cut, y = n)) + 
  geom_col(data = th %>% filter(color == 'D'), fill = 'yellow') +
  geom_col(data = th %>% filter(color == 'J'), fill = 'black')

2. Hình 5.2: Biểu đồ so sánh số lượng kim cương theo chất lượng chế tác có độ trong suốt VS2 và IF

Biểu đồ dưới đây thể hiện hai loại kim cương khác nhau: cột màu vàng thể hiện kim cương có độ trong suốt VS2, cột màu đen thể hiện kim cương có độ trong suốt IF được thống kê theo chất lương chế tác

Quan sát biểu đồ cho ta thấy rõ sự cách biệt lớn về số lượng của hai loại kim cương trên: kim cương có độ trong suốt VS2 có số lương gấp 6 đến 8 lần so với số lượng kim cương có độ trong suốt IF => chứng tỏ trên thị trường loại kim cương có độ trong suốt IF không đc phổ biến chiếm thị phần nhỏ trên tổng số.

th1 <- nth %>% group_by(cut, clarity) %>% summarise(n = n(),.groups='drop')
th1 %>% ggplot(aes(x = cut, y = n)) +
  geom_col(data = th1 %>% filter(clarity == 'VS2'), fill = 'yellow') +
  geom_col(data = th1 %>% filter(clarity == 'IF'), fill = 'black')

3. Hình 5.3: Biểu đồ so sánh số lượng kim cương theo màu có độ trong suốt VS1 và VS2

Theo các màu kim cương thống kê dưới đây cho thấy sự so sánh giữa hai loại kim cương có độ trong suốt VS1 và VS2.

So với các loại kim cương so sánh trước thì hai loại này có sự chênh lệch nhưng không cao . Giữa các màu khác nhau số lượng cũng khá đồng đều cả hai loại VS1 và VS2.

th2 <- nth %>% group_by(clarity, color) %>% summarise(n = n(), .groups='drop')
th2 %>% ggplot(aes(x = color, y = n)) +
  geom_col(data = th2 %>% filter(clarity == 'VS2'), fill = 'yellow') +
  geom_col(data = th2 %>% filter(clarity == 'VS1'), fill = 'black')

VI. So sánh theo nhóm kim cương theo số lượng

1. Hình 6.1: Biểu đồ so sánh nhóm kim cương theo màu và chất lượng chế tác

Bằng các câu lệnh dưới ta có nhóm biểu đồ thể hiện số lượng kim cương theo từng loại chế tác khác nhau từ đó có thể dễ dàng quan sát so sánh giữa các màu của loại chế tác này với màu của loại chế tác kia

nth %>% group_by(cut,color) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = color,y = n)) +
    geom_col(fill="pink") +
    facet_wrap(~cut) +
    labs(x = 'Loại', y = 'Số lượng')

Cũng như biểu đồ trên biểu đồ dưới đây cũng giúp ta quan sát và so sánh những vần đề trên nhưng với câu lệnh geom_text(aes(label = n),vjust = 2, color = ‘white’) ta có thể thấy rõ số liệu một cách cụ thể.

nth %>% group_by(cut,color) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = color,y = n)) +
    geom_col( fill= 'brown') +
    facet_wrap(~cut) +
    geom_text(aes(label = n),vjust = 2, color = 'white') +
    labs(x = 'Loại', y = 'Số lượng')

2. Hình 6.2: Biểu đồ so sánh nhóm kim cương theo độ trong suốt và chất lượng chế tác

Bằng các câu lệnh dưới ta có nhóm biểu đồ thể hiện số lượng kim cương theo từng loại chế tác khác nhau từ đó có thể dễ dàng quan sát so sánh giữa các loại độ trong suốt kim cương của loại chế tác này với các loại độ trong suốt của loại chế tác kia

nth %>% group_by(cut,clarity) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = clarity,y = n)) +
    geom_col(fill="pink") +
    facet_wrap(~cut) +
    labs(x = 'Loại', y = 'Số lượng')

Cũng như biểu đồ trên biểu đồ dưới đây cũng giúp ta quan sát và so sánh những vần đề trên nhưng với câu lệnh geom_text(aes(label = n),vjust = 2, color = ‘white’) ta có thể thấy rõ số liệu một cách cụ thể.

nth %>% group_by(clarity,cut) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = clarity,y = n)) +
    geom_col( fill= 'brown') +
    facet_wrap(~ cut) +
    geom_text(aes(label = n),vjust = 2, color = 'white') +
    labs(x = 'Loại', y = 'Số lượng')

3. Hình 6.3: Biểu đồ so sánh nhóm kim cương theo màu và độ trong suốt

Bằng các câu lệnh dưới ta có nhóm biểu đồ thể hiện số lượng kim cương theo từng loại trong suốt khác nhau từ đó có thể dễ dàng quan sát so sánh giữa các màu của loại trong suốt này với màu của loại trong suốt kia

nth %>% group_by(clarity,color) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = color,y = n)) +
    geom_col(fill="pink") +
    facet_wrap(~clarity) +
    labs(x = 'Loại', y = 'Số lượng')

Cũng như biểu đồ trên biểu đồ dưới đây cũng giúp ta quan sát và so sánh những vần đề trên nhưng với câu lệnh geom_text(aes(label = n),vjust = 2, color = ‘white’) ta có thể thấy rõ số liệu một cách cụ thể.

nth %>% group_by(clarity,color) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = color,y = n)) +
    geom_col( fill= 'brown') +
    facet_wrap(~clarity) +
    geom_text(aes(label = n),vjust = 2, color = 'white') +
    labs(x = 'Loại', y = 'Số lượng')

VII. So sánh nhóm kim cương theo mức giá trung bình

1. Hình 7.1: biểu đồ so sánh nhóm kim cương (màu và chất lượng chế tác)

Biểu đồ nhóm sau là thống kê mức giá trung bình của từng loại kim cương chế tác theo tất cả các màu có đầy đủ số liệu trên từng biểu đồ

nth %>% group_by(cut,color) %>% summarise(m = mean(price),.groups = 'drop') %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut ) +
    geom_text(aes(label = round(m))) +
    labs(x = 'Color ', y = 'Số lượng')

2. Hình 7.2: biểu đồ so sánh nhóm kim cương (độ trong suốt và chất lượng chế tác)

Biểu đồ nhóm sau là thống kê mức giá trung bình của từng loại kim cương chế tác theo tất cả các độ trong suốt có đầy đủ số liệu trên từng biểu đồ

nth %>% group_by(cut,clarity) %>% summarise(m = mean(price), .groups = 'drop') %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut ) +
    geom_text(aes(label = round(m))) +
    labs(x = 'clarity ', y = 'Số lượng')

3. Hình 7.3: biểu đồ so sánh nhóm kim cương (màu và độ trong suốt )

Biểu đồ nhóm sau là thống kê mức giá trung bình của từng loại kim cương có độ trong suốt khác nhau theo tất cả các màu có đầy đủ số liệu trên từng biểu đồ

nth %>% group_by(clarity,color) %>% summarise(m = mean(price), .groups='drop') %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~clarity) +
    geom_text(aes(label = round(m))) +
    labs(x = 'Color ', y = 'Số lượng')

VIII. Phân tích số lượng kim cương theo mức giá và khối lượng carat

1. Hình 8.1: BIểu đồ phân tích số lượng kim cương theo mức giá

Biểu đồ sau giúp ta phân chia khối lượng carat của kim cương thành 5 loại khác nhau theo mức độ từ bé đến lớn đồng thời từ đó thống kê số lượng theo nhóm cừa chia. Cụ thể: đối với các loại kim cương có khối lượng carat nhỏ nhất lại chiếm thị phần lớn nhất trong tổng số kim cương đặc biệt với hai loại là lớn và rất lớn lại không có trên thống kê.

Như vậy trên thị tường hiện nay thống kê số kim cương có khối lượng carat nhỏ khá phổ biến nhưng loại khối lượng carat lớn lại rất hiếm và hầu như không có.

nt <-nth %>% mutate(Carat = cut(carat,5, label = c('rất nhỏ', 'nhỏ','vừa','lớn','rất lớn')))
nt %>% ggplot(aes(x = Carat)) +
  geom_bar(fill = 'purple')

2. Hình 8.2: BIểu đồ phân tích số lượng kim cương theo mức giá

Với những câu lệnh sau ta có thể phân bổ mức gia thành 5 mức độ tăng dần và mỗi mức độ dưới đây đều được thống kê lại với số lượng khác nhau. Cụ thể: mức giá rất nhỏ chiếm phần lớn số lượng kim cương trên thị trường còn với mức giá lớn và rất lớn số lượng kim cương hiếm chiếm tỉ trọng rất nhỏ trên tổng số

nt1 <- nth %>% mutate(Price = cut(price,5, label = c('rất thấp ', 'thấp','tb','cao','rất cao')))
nt1 %>% ggplot(aes(x = Price)) +
  geom_bar(fill = 'purple')

LS0tDQp0aXRsZTogIk5ISeG7hk0gVuG7pCA0Ig0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJUg6JU06JVMsICVkIC0gJW0gLSAlWScpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICBudW1iZXIgc2VjdGlvbjogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZSANCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KIyMgKipHSeG7mkkgVEhJ4buGVSoqIA0KQuG7mSBk4buvIGxp4buHdSAgRElBTU9OUyBsw6AgYuG7mSBk4buvIGxp4buHdSBu4bqxbSB0cm9uZyBwYWNrYWdlcyB0aWR5dmVyc2UgduG7m2kgaMahbiA1MDAwMCBxdWFuIHPDoXQgdsOgIDEwIGJp4bq/biBjaG8gdGEgYmnhur90IMSR4bqneSDEkeG7pyB0aMO0bmcgdGluIHbhu4EgY8OhYyBsb+G6oWkga2ltIGPGsMahbmcNClbDoCBkxrDhu5tpIMSRw6J5IGzDoCBjw6FjIGJp4buDdSDEkeG7kyBiaeG7g3UgZGnhu4VuIG5o4buvbmcgdGjDtG5nIHRpbiBj4bunYSBi4buZIGThu68gbGnhu4d1IMSR4buDIGThu4UgZMOgbmcgdGjhu5FuZyBrw6ogdsOgIHBow6JuIHTDrWNoIA0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShzY2FsZXMpDQpudGggPC0gZGlhbW9uZHMNCmBgYA0KDQojIyAqKkkuIFBow6JuIHTDrWNoIGdpw6EgY+G6oyB0cnVuZyBiw6xuaCBj4bunYSBt4buZdCBz4buRIGxv4bqhaSBraW0gY8awxqFuZyoqDQoNCiMjIyAqKjEuIEjDrG5oIDEuMTogQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgVlZTMSB0aGVvIG3DoHUqKg0KDQpLaW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IFZWUzEga2jDoSDhu5VuIMSR4buLbmggduG7m2kgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBnaeG7r2EgY8OhYyBtw6B1IGNow6puaCBs4buHY2ggbmhhdSBraMO0bmcgcXXDoSBs4bubbiBuaMawbmcgc28gbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCB0aOG6pXAgbmjhuqV0IHbDoCBjYW8gbmjhuqV0IGPFqW5nIGPDsm4ga2hv4bqjbmcgY8OhY2gga2jDoSB4YSAoZ+G6p24gaGFpIGzhuqduKQ0KDQpgYGB7cn0NCm50aDIgPC0gbnRoICU+JSBncm91cF9ieShjb2xvcixjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksbWVhblAgPSBtZWFuKHByaWNlKSwuZ3JvdXBzID0gJ2Ryb3AnKQ0KbnRoMiAlPiUgZ2dwbG90KGFlcyh4PSBjb2xvciwgeT0gbWVhblApKSArIGdlb21fY29sKGRhdGEgPSBudGgyICU+JSBmaWx0ZXIoY2xhcml0eSA9PSAnVlZTMScpLCBmaWxsID0gJ3B1cnBsZScpDQpgYGANCg0KIyMjICoqMi4gSMOsbmggMS4yOiBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIG3hu6ljIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBTSTEgdGhlbyBtw6B1KioNCg0KS2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBTSTEgduG7m2kgbeG7qWMgZ2nDoSBnaeG7r2EgY8OhYyBtw6B1IGPDsyBz4buxIGNow6puaCBs4buHY2gga2jDoSBs4bubbiAsIHbhu5tpIG3DoHUgSSBjw7MgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBjYW8gbmjhuqV0IChoxqFuIDUwMDApIGfhuqduIGfhuqVwIMSRw7RpIG3hu6ljIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCB0aOG6pXAgbmjhuqV0IG3DoHUgRCANCg0KYGBge3J9DQpudGgyICU+JSBnZ3Bsb3QoYWVzKHg9IGNvbG9yLCB5PSBtZWFuUCkpICsgZ2VvbV9jb2woZGF0YSA9IG50aDIgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdTSTEnKSwgZmlsbCA9ICd5ZWxsb3cnKQ0KYGBgDQoNCiMjIyAqKjMuIEjDrG5oIDEuMzogQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgSUYgdGhlbyBtw6B1KioNCg0KTcOgdSBEIGPDsyBt4bupYyBnacOhIHRydW5nIGLDrG5oIGNhbyDEkeG7mXQgYmnhur9uIHNvIHbhu5tpIHThuqV0IGPhuqMgY8OhYyBtw6B1IGPDsm4gbOG6oWksIGNhbyBoxqFuIGfhuqVwIHThu6sgIGhhaSDEkeG6v24gYmEgbOG6p24gDQoNCmBgYHtyfQ0KbnRoMiAlPiUgZ2dwbG90KGFlcyh4PSBjb2xvciwgeT0gbWVhblApKSArIGdlb21fY29sKGRhdGEgPSBudGgyICU+JSBmaWx0ZXIoY2xhcml0eSA9PSAnSUYnKSwgZmlsbCA9ICdkYXJrY3lhbicpDQpgYGANCg0KIyMjICoqNC4gSMOsbmggMS40OiBTbyBzw6FuaCBiYSBiaeG7g3UgxJHhu5Mga2ltIGPGsMahbmcgdHLDqm4qKg0KDQpU4burIGJhIGJp4buDdSDEkeG7kyB0csOqbiB0YSBjw7MgdGjhu4MgdGjhuqV5IMSRxrDhu6NjIG3hu6ljIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2EgY8OhYyBsb+G6oWkga2ltIGPGsMahbmcga2jDoWMgbmhhdSwgxJHhu4MgdMOsbSBoaeG7g3UgcsO1IGjGoW4gc+G7sSB0aGF5IMSR4buVaSB0cm9uZyBnacOhIGPhuqMgxJHhu5FpIHbhu5tpIGPDoWMgbG/huqFpIGtpbSBjxrDGoW5nIGtow6FjIG5oYXUgdGEgc28gc8OhbmggYmEgYmnhu4N1IMSR4buTIHRyw6puOiBD4bulIHRo4buDDQoNCiogS2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBWVlMxIG5ow6xuIGNodW5nIGPDsyBt4bupYyBnacOhIHRydW5nIGLDrG5oIHRo4bqlcCBoxqFuIHNvIHbhu5tpIGPDoWMgbG/huqFpIGtow6FjIG5oxrBuZyBraMOhIOG7lW4gxJHhu4tuaCBnaeG7r2EgY8OhYyBtw6B1IA0KDQoqIEtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgSUYgbcOgdSBEIGPDsyBt4bupYyBnacOhIGNhbyBuaOG6pXQgdHJvbmcgY8OhYyBsb+G6oWksIGNhbyBoxqFuIGfhuqVwIGhhaSDEkeG6v24gYmEgbOG6p24gc28gduG7m2kgY8OhYyBsb+G6oWkga2jDoWMsIG5oxrBuZyBjxaluZyBsw6Aga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBJRiBtw6AgY8OhYyBtw6B1IGtow6FjIHRow6wgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBs4bqhaSB0aOG6pXAgbmjhuqV0IHRyb25nIGPDoWMgbG/huqFpDQoNCiAqIEtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgU0kxIGzDoCBv4bqhaSBjw7MgbeG7qWMgZ2nDoSBjYW8gdsOgIOG7lW4gxJHhu4tuaCBnaeG7r2EgY8OhYyBtw6B1Lg0KDQoNCmBgYHtyfQ0KbnRoMyA8LSBudGggJT4lIGdyb3VwX2J5KGNvbG9yLGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobWVhblAgPSBtZWFuKHByaWNlKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIG11dGF0ZShjbGFyaXR5PSBmYWN0b3IoY2xhcml0eSwgbGV2ZWxzID0gYygiVlZTMSIsICJJRiIsICJTSTEiKSkpDQoNCm50aDMgJT4lIGdncGxvdChhZXMoeD0gY29sb3IsIHk9IG1lYW5QLCBmaWxsPSBjbGFyaXR5KSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpDQpgYGAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCg0KDQojIyAqKklJLiBLaOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBjw6FjIHnhur91IHThu5EgY8OhYyBuaGF1KioNCg0KIyMjICoqMS4gSMOsbmggMi4xOiBCaeG7g3UgxJHhu5Mga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIHRoZW8gY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMqKiANCkto4buRaSBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBj4bunYSBt4buXaSB2acOqbiBraW0gY8awxqFuZyDEkcaw4bujYyB04buVbmcgaOG7o3AgZMaw4bubaSDEkcOieSB0aGVvIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjIGPhu6dhIGNow7puZywgY+G7pSB0aOG7gzogduG7m2kgY2jhuqV0IGzGsOG7o25nIEZhaXIga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIG3hu5dpIHZpw6puIGzDoCAxLjA1LCBjaOG6pXQgbMaw4bujbmcgR29vZCBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggbeG7l2kgdmnDqm4gbMOgIDAuODUsIHbhu5tpIGNo4bqldCBsxrDhu6NuZyBWZXJ5IEdvb2Qga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIG3hu5dpIHZpw6puIGzDoDAuODEsIHbhu5tpIGNo4bqldCBsxrDhu6NuZyBQcmVuaXVtIGto4buRaSBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBt4buXaSB2acOqbiBsw6AwLjg5LCB24bubaSBjaOG6pXQgbMaw4bujbmcgSWRlYWwga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIG3hu5dpIHZpw6puICAwLjcNCg0KYGBge3J9DQpudGggJT4lIGdyb3VwX2J5KGN1dCkgJT4lIHN1bW1hcmlzZShtPSBtZWFuKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChmaWxsPSdibGFjaycpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAnZ3JlZW4nKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnTWVhbicpDQpgYGANCg0KIyMjICoqMi4gSMOsbmggMi4yOiBCaeG7g3UgxJHhu5Mga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIHRoZW8gbcOgdSAqKiANCk3hu5dpIGxv4bqhaSBtw6B1IGPhu6dhIGtpbSBjxrDGoW5nIGPDsyBraOG7kWkgbMaw4bujbmcgY2FyYXQga2jDoWMgbmhhdSB0w7l5IGxv4bqhaS4gUXVhIGJp4buDdSDEkeG7kyBkxrDhu5tpIHRhIHRo4bqleSBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBKIGzhu5tuIG5o4bqldCAxLjE2IGNhcmF0IHbDoCBtw6B1IGPDsyBraOG7kWkgbMaw4bujbmcgY2FyYXQgYsOpIG5o4bqldCBsw6AgbcOgdSBEIHbDoCBFOiAwLjY2IGNhcmF0ICANCg0KYGBge3J9DQpudGggJT4lIGdyb3VwX2J5KGNvbG9yKSAlPiUgc3VtbWFyaXNlKG09IG1lYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG0pKSArDQogICAgZ2VvbV9jb2woZmlsbD0nYmxhY2snKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ2dyZWVuJykgKw0KICAgIGxhYnMoeCA9ICdDb2xvcicsIHkgPSAnTWVhbicpDQpgYGANCg0KIyMjICoqMy4gSMOsbmggMi4zOiBCaeG7g3UgxJHhu5Mga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0ICoqIA0KxJDhu5kgdHJvbmcgc3Xhu5F0IGPhu6dhIGtpbSBjxrDGoW5nIMSRxrDhu6NjIGNoaWEgbMOgbSA4IGxv4bqhaSBraMOhYyBuaGF1IHbDoCB0aGVvIMSR4buZIHRyb25nIHN14buRdCBt4buXaSBsb+G6oWkgY8OzIGto4buRaSBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCDEkcaw4bujYyBiaeG7g3UgZGnhu4VuIGLhurFuZyBiaeG7g3UgxJHhu5MgZMaw4bubaSDEkcOieSBj4bulIHRo4buDOiBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBJMSBjYW8gbmjhuqV0IHbhu5tpIDEuMjgsICBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IFZWUzEgdGjhuqVwIG5o4bqldCB24bubaSBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYmluaCBsw6AgMC41IA0KDQpgYGB7cn0NCm50aCAlPiUgZ3JvdXBfYnkoY2xhcml0eSkgJT4lIHN1bW1hcmlzZShtPSBtZWFuKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG0pKSArDQogICAgZ2VvbV9jb2woZmlsbD0nYmxhY2snKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ2dyZWVuJykgKw0KICAgIGxhYnMoeCA9ICfEkOG7mSB0cm9uZyBzdeG7kXQnLCB5ID0gJ01lYW4nKQ0KYGBgDQoNCg0KIyMgKipJSUkuIFThu5VuZyBo4bujcCBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY8OhYyBiaeG6v24gIGtow6FjIG5oYXUqKg0KDQojIyMgKioxLiBIw6xuaCAzLjE6IEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIG3DoHUqKg0KUXVhIGJp4buDdSDEkeG7kyBkxrDhu5tpIHRhIGPDsyB0aOG7gyB04buVbmcgaOG7o3AgxJHGsOG7o2MgdOG6pXQgY+G6oyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY8OhYyBsb+G6oWkgbcOgdSBraMOhYyBuaGF1IHRyb25nIMSRw7M6IGPhu5l0IGNhbyBuaOG6pXQgbMOgIGtpbSBjxrDGoW5nIGPDsyBtw6B1IEcgdOG7qWMgbcOgdSBHIGPDsyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIG5oaeG7gXUgbmjhuqV0IHbhu5tpIGjGoW4gMTA1MDAgxJF2OyBj4buZdCB0aOG6pXAgbmjhuqV0IGzDoCBraW0gY8awxqFuZyBjw7MgbcOgdSBKIHThu6ljIG3DoHUgSiBjw7Mgc+G7kSBsxrDhu6NuZyDDrXQgbmjhuqV0IHbhu5tpIGfhuqduIDMwMDAgxJF2LiANCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KbnRoICU+JSBnZ3Bsb3QoYWVzKHggPSBjb2xvcikpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBsYWJzKHggPSAnTG/huqFpICcsIHkgPSAnU+G7kSBsxrDhu6NuZycgKSsNCiAgICBjb29yZF9mbGlwKCkNCmBgYCANCg0KQ8WpbmcgbmjGsCBsb+G6oWkgYmnhu4N1IMSR4buTIHRyw6puIGJp4buDdSDEkeG7kyBkxrDhu5tpIMSRw6J5IHThu5VuZyBo4bujcCBz4buRIGzGsMahbmcga2ltIGPGsMahbmcgdGhlbyB04burbmcgbG/huqFpIG3DoHUga2jDoWMgbmhhdSBuaMawbmcgduG7m2kgY8OidSBs4buHbmggbsOgeSB0YSBjw7MgdGjhu4MgdGjDtG5nIHRpbiBjaGkgdGnhur90IHbhu4EgdOG7q25nIHPhu5EgbMawxqFuZyBraW0gY8awxqFuZyBuaMawIHNhdToga2ltIGPGsMahbmcgbcOgdSBHIGPDsyBz4buRIGzGsOG7o25nIG5oaeG7gXUgbmjhuqV0IDExMjkyIMSRdjsga2ltIGPGsMahbmcgbcOgdSBKIGPDsyBz4buRIGzGsOG7o25nIMOtdCBuaOG6pXQgMjgwOC4gDQoNCmBgYHtyLCBlY2hvID0gVFJVRSB9DQpudGggJT4lIGdyb3VwX2J5KGNvbG9yKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGNvbG9yLG4pKSArDQogICAgZ2VvbV9jb2woZmlsbD0nb3JhbmdlJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDIsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICdsb+G6oWkgICcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQoNCmBgYA0KDQojIyMgKioyLiBIw6xuaCAzLjI6IEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjKioNClF1YSBiaeG7g3UgxJHhu5MgZMaw4bubaSB0YSBjw7MgdGjhu4MgdOG7lW5nIGjhu6NwIMSRxrDhu6NjIHThuqV0IGPhuqMgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjIGtow6FjIG5oYXUgY+G7pSB0aOG7gzogc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0xINuZyBk4bqnbiB0aGVvIG3hu6ljIMSR4buZIGNo4bqldCBsxrDhu6NuZyAgdOG7qyB0aOG6pXAgxJHhur9uIGNhbywgY+G7mXQgY2FvIG5o4bqldCB24bubaSBjaOG6pXQgbMaw4bujbmcgSWRlYWwgY8OzIGjGoW4gIDIwMDAwIMSRdiBraW0gY8awxqFuZzsgY+G7mXQgdGjhuqVwIG5o4bqldCB24bubaSBjaOG6pXQgbMaw4bujbmcgRmFpciBjw7MgZ+G6p24gMjUwMCDEkXYga2ltIGPGsMahbmcuDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ2dwbG90KGFlcyh4ID0gY3V0KSkgKw0KICAgIGdlb21fYmFyKCkgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKSsNCiAgICBjb29yZF9mbGlwKCkNCmBgYCANCg0KQ8WpbmcgbmjGsCBsb+G6oWkgYmnhu4N1IMSR4buTIHRyw6puIGJp4buDdSDEkeG7kyBkxrDhu5tpIMSRw6J5IHThu5VuZyBo4bujcCBz4buRIGzGsMahbmcga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMawxqFuZyBjaOG6vyB0w6FjIG5oxrBuZyB24bubaSBjw6J1IGzhu4duaCBuw6B5IHRhIGPDsyB0aOG7gyB0aMO0bmcgdGluIGNoaSB0aeG6v3QgduG7gSB04burbmcgc+G7kSBsxrDGoW5nIGtpbSBjxrDGoW5nIG5oxrAgc2F1OiBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIEZhaXIsIEdvb2QsIFZlcnkgR29vZCwgUHJlbml1bSwgSWRlYWwgY8OzIHPhu5EgbMaw4bujbmcgbOG6p24gbMaw4bujdCBsw6AgMTYxMCwgNDkwNiwgMTIwODIsIDEzNzkxLCAyMTU1MS5W4bubaSBz4buRIGzGsOG7o25nIHThu4kgbOG7hyB0aHXhuq1uIHbhu5tpIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjIGPhu6dhIGtpbSBjxrDGoW5nICANCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KbnRoICU+JSBncm91cF9ieShjdXQgKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGN1dCxuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J29yYW5nZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAyLCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnbG/huqFpICcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KDQojIyMgKiozLiBIw6xuaCAzLjM6IEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIMSR4buZIHRyb25nIHN14buRdCoqDQpRdWEgYmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgdGEgdOG7lW5nIGjhu6NwIMSRxrDhu6NjIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBt4bupYyDEkeG7mSB0cm9uZyBzdeG7kXQgdOG7q25nIGxv4bqhaSBj4bulIHRo4buDOiBraW0gY8awxqFuZyBsb+G6oWkgU2wxIGPDsyBz4buRIGzGsMahbmcgY2FvIG5o4bqldCB24bubaSBoxqFuIDE1MDAwIMSRdiwga2ltIGPGsMahbmcgbG/huqFpIEkxIHRo4bqlcCBuaOG6pXQgduG7m2kgZ+G6p24gMTI1MCDEkXYuDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSkpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykgKw0KICAgIGNvb3JkX2ZsaXAoKQ0KYGBgIA0KDQpDxaluZyBuaMawIGxv4bqhaSBiaeG7g3UgxJHhu5MgdHLDqm4gYmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgdOG7lW5nIGjhu6NwIHPhu5EgbMawxqFuZyBraW0gY8awxqFuZyB0aGVvIMSR4buZIHRyb25nIHN14buRdCBuaMawbmcgduG7m2kgY8OidSBs4buHbmggbsOgeSB0YSBjw7MgdGjhu4MgdGjDtG5nIHRpbiBjaGkgdGnhur90IHbhu4EgdOG7q25nIHPhu5EgbMawxqFuZyBraW0gY8awxqFuZyBuaMawIHNhdToga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBTbDEgY8OzIHPhu5EgbMaw4bujbmcgbmhp4buBdSBuaOG6pXQgMTMwNjUgxJF2IHbDoCBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IEkxIGPDsyBz4buRIGzGsOG7o25nIMOtdCBuaOG6pXQgNzQxIMSRdi4NCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KbnRoICU+JSBncm91cF9ieShjbGFyaXR5ICkgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyhjbGFyaXR5LG4pKSArDQogICAgZ2VvbV9jb2woZmlsbD0nb3JhbmdlJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDIsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWkgJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQojIyAqKklWLiBQaOG6p24gdHLEg20gbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjw6FjIGxv4bqhaSBraW0gY8awxqFuZyBraMOhYyBuaGF1KioNCg0KIyMjICoqMS4gSMOsbmggNC4xIEJp4buDdSDEkeG7kyB04buJIGzhu4cgcGjhuqduIHRyxINtIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSoqIA0KQmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgdGjhu4MgaGnhu4duIHThu4kgbOG7hyBwaOG6p24gdHLEg20gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIG3DoHUgY+G7pSB0aOG7gzoga2ltIGPGsMahbmcgbcOgdSBEIGNoaeG6v20gMTIuNTYlLCBraW0gY8awxqFuZyBtw6B1IEUgY2hp4bq/bSAxOC4xNi4lLCBraW0gY8awxqFuZyBtw6B1IEYgY2hp4bq/bSAxNy42OSUsIGtpbSBjxrDGoW5nIG3DoHUgRyBjaGnhur9tIDIwLjkzJSwga2ltIGPGsMahbmcgbcOgdSBIIGNoaeG6v20gMTUuMzklLCAga2ltIGPGsMahbmcgbcOgdSBJIGNoaeG6v20gMTAuMDUlLCBraW0gY8awxqFuZyBtw6B1IEogY2hp4bq/bSB0aOG6pXAgbmjhuqV0IDUuMjElIA0KDQpgYGB7ciwgZWNobyA9IFRSVUV9IA0KbnRoICU+JSBncm91cF9ieShjb2xvcikgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyhjb2xvcixuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J2RhcmsgYmx1ZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChuL2xlbmd0aChudGgkY2FyYXQpKSksdmp1c3QgPSAyLCBjb2xvciA9ICd3aGl0ZScpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQojIyMgKioyLiBIw6xuaCA0LjIgQmnhu4N1IMSR4buTIHThu4kgbOG7hyBwaOG6p24gdHLEg20ga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY2jhur8gdMOhYyoqIA0KQmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgdGjhu4MgaGnhu4duIHThu4kgbOG7hyBwaOG6p24gdHLEg20gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjIGPhu6UgdGjhu4M6IGNoaeG6v20gdOG7iSBs4buHIGNhbyBuaOG6pXQgbMOgIHPhu5EgbMawxqFuZyBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMgSWRlYWwgduG7m2kgNDAlLCB0aOG6pXAgbmjhuqV0IGzDoCB04buJIGzhu4cgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMgZmFpciAzJQ0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpudGggJT4lIGdyb3VwX2J5KGN1dCkgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyhjdXQsbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSdkYXJrIGJsdWUnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnQobi9sZW5ndGgobnRoJGNhcmF0KSkpLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KIyMjICoqMy4gSMOsbmggNC4zIEJp4buDdSDEkeG7kyB04buJIGzhu4cgcGjhuqduIHRyxINtIGtpbSBjxrDGoW5nIHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0KiogDQpCaeG7g3UgxJHhu5MgZMaw4bubaSDEkcOieSB0aOG7gyBoaeG7h24gdOG7iSBs4buHIHBo4bqnbiB0csSDbSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0IGPhu6UgdGjhu4M6IGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgU2wxIGNhbyBuaOG6pXQgY2hp4bq/bSAyNC4yICUsIHbDoCBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IHRo4bqlcCBuaOG6pXQgY2jhu4kgY2hp4bq/bSAxLjQlIA0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpudGggJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoY2xhcml0eSxuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J2RhcmsgYmx1ZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChuL2xlbmd0aChudGgkY2FyYXQpKSksdmp1c3QgPSAyLCBjb2xvciA9ICd3aGl0ZScpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQojIyAqKlYuIFNvIHPDoW5oIHPhu5EgbMaw4bujbmcgZ2nhu69hIGPDoWMgbG/huqFpICBraW0gY8awxqFuZyBuZ+G6q3Ugbmhpw6puKioNCg0KIyMjICoqMS4gSMOsbmggNS4xOiBCaeG7g3UgxJHhu5Mgc28gc8Ohbmggc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCB0w6FjIGPDsyBtw6B1IEQgdsOgIEoqKg0KDQpRdWEgYmnhu4N1IMSR4buTIHRhIHRo4bqleSBjw7Mgc+G7sSBjaMOqbmggbOG7h2NoIGtow6EgbOG7m24gZ2nhu69hIGhhaSBtw6B1IGtpbSBjxrDGoW5nICxj4buZdCBtw6B1IHbDoG5nIGzDoCBraW0gY8awxqFuZyBtw6B1IEQgY8OzIHPhu5EgbMaw4bujbmcgZ+G6pXAgxJHDtGkga2ltIGPGsMahbmcgIG3DoHUgSiBsw6AgY+G7mXQgbcOgdSDEkWVuIHRoZW8gdOG7q25nIGxhb2lqIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSBjaOG6vyB0YWMga2jDoWMgbmhhdS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KdGggPC0gbnRoICU+JSBncm91cF9ieShjdXQsIGNvbG9yKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksLmdyb3Vwcz0nZHJvcCcpDQp0aCAlPiUgZ2dwbG90KGFlcyh4ID0gY3V0LCB5ID0gbikpICsgDQogIGdlb21fY29sKGRhdGEgPSB0aCAlPiUgZmlsdGVyKGNvbG9yID09ICdEJyksIGZpbGwgPSAneWVsbG93JykgKw0KICBnZW9tX2NvbChkYXRhID0gdGggJT4lIGZpbHRlcihjb2xvciA9PSAnSicpLCBmaWxsID0gJ2JsYWNrJykNCmBgYA0KDQojIyMgKioyLiBIw6xuaCA1LjI6IEJp4buDdSDEkeG7kyBzbyBzw6FuaCBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMgY8OzIMSR4buZIHRyb25nIHN14buRdCBWUzIgdsOgIElGKioNCg0KQmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgdGjhu4MgaGnhu4duIGhhaSBsb+G6oWkga2ltIGPGsMahbmcga2jDoWMgbmhhdTogY+G7mXQgbcOgdSB2w6BuZyB0aOG7gyBoaeG7h24ga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBWUzIsIGPhu5l0IG3DoHUgxJFlbiB0aOG7gyBoaeG7h24ga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBJRiDEkcaw4bujYyB0aOG7kW5nIGvDqiB0aGVvIGNo4bqldCBsxrDGoW5nIGNo4bq/IHTDoWMgDQoNClF1YW4gc8OhdCBiaeG7g3UgxJHhu5MgY2hvIHRhIHRo4bqleSByw7Ugc+G7sSBjw6FjaCBiaeG7h3QgbOG7m24gduG7gSBz4buRIGzGsOG7o25nIGPhu6dhIGhhaSBsb+G6oWkga2ltIGPGsMahbmcgdHLDqm46IGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgVlMyIGPDsyBz4buRIGzGsMahbmcgZ+G6pXAgNiDEkeG6v24gOCBs4bqnbiBzbyB24bubaSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgSUYgPT4gY2jhu6luZyB04buPIHRyw6puIHRo4buLIHRyxrDhu51uZyBsb+G6oWkga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBJRiBraMO0bmcgxJFjIHBo4buVIGJp4bq/biBjaGnhur9tIHRo4buLIHBo4bqnbiBuaOG7jyB0csOqbiB04buVbmcgc+G7kS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KdGgxIDwtIG50aCAlPiUgZ3JvdXBfYnkoY3V0LCBjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksLmdyb3Vwcz0nZHJvcCcpDQp0aDEgJT4lIGdncGxvdChhZXMoeCA9IGN1dCwgeSA9IG4pKSArDQogIGdlb21fY29sKGRhdGEgPSB0aDEgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdWUzInKSwgZmlsbCA9ICd5ZWxsb3cnKSArDQogIGdlb21fY29sKGRhdGEgPSB0aDEgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdJRicpLCBmaWxsID0gJ2JsYWNrJykNCmBgYA0KDQojIyMgKiozLiBIw6xuaCA1LjM6IEJp4buDdSDEkeG7kyBzbyBzw6FuaCBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IFZTMSB2w6AgVlMyKioNCg0KVGhlbyBjw6FjIG3DoHUga2ltIGPGsMahbmcgdGjhu5FuZyBrw6ogZMaw4bubaSDEkcOieSBjaG8gdGjhuqV5IHPhu7Egc28gc8OhbmggZ2nhu69hIGhhaSBsb+G6oWkga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBWUzEgdsOgIFZTMi4NCg0KU28gduG7m2kgY8OhYyBsb+G6oWkga2ltIGPGsMahbmcgc28gc8OhbmggdHLGsOG7m2MgdGjDrCBoYWkgbG/huqFpIG7DoHkgY8OzIHPhu7EgY2jDqm5oIGzhu4djaCBuaMawbmcga2jDtG5nIGNhbyAuIEdp4buvYSBjw6FjIG3DoHUga2jDoWMgbmhhdSBz4buRIGzGsOG7o25nIGPFqW5nIGtow6EgxJHhu5NuZyDEkeG7gXUgY+G6oyBoYWkgbG/huqFpIFZTMSB2w6AgVlMyLiANCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KdGgyIDwtIG50aCAlPiUgZ3JvdXBfYnkoY2xhcml0eSwgY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSwgLmdyb3Vwcz0nZHJvcCcpDQp0aDIgJT4lIGdncGxvdChhZXMoeCA9IGNvbG9yLCB5ID0gbikpICsNCiAgZ2VvbV9jb2woZGF0YSA9IHRoMiAlPiUgZmlsdGVyKGNsYXJpdHkgPT0gJ1ZTMicpLCBmaWxsID0gJ3llbGxvdycpICsNCiAgZ2VvbV9jb2woZGF0YSA9IHRoMiAlPiUgZmlsdGVyKGNsYXJpdHkgPT0gJ1ZTMScpLCBmaWxsID0gJ2JsYWNrJykNCmBgYA0KDQojIyAqKlZJLiBTbyBzw6FuaCB0aGVvIG5ow7NtIGtpbSBjxrDGoW5nIHRoZW8gc+G7kSBsxrDhu6NuZyoqDQoNCiMjIyAqKjEuIEjDrG5oIDYuMTogQmnhu4N1IMSR4buTIHNvIHPDoW5oIG5ow7NtIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSB2w6AgY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMqKg0KDQpC4bqxbmcgY8OhYyBjw6J1IGzhu4duaCBkxrDhu5tpIHRhIGPDsyBuaMOzbSBiaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyB04burbmcgbG/huqFpIGNo4bq/IHTDoWMga2jDoWMgbmhhdSB04burIMSRw7MgY8OzIHRo4buDIGThu4UgZMOgbmcgcXVhbiBzw6F0IHNvIHPDoW5oIGdp4buvYSBjw6FjIG3DoHUgY+G7p2EgbG/huqFpIGNo4bq/IHTDoWMgbsOgeSB24bubaSBtw6B1IGPhu6dhIGxv4bqhaSBjaOG6vyB0w6FjIGtpYQ0KDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG49bigpLC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjb2xvcix5ID0gbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSJwaW5rIikgKw0KICAgIGZhY2V0X3dyYXAofmN1dCkgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCkPFqW5nIG5oxrAgYmnhu4N1IMSR4buTIHRyw6puIGJp4buDdSDEkeG7kyBkxrDhu5tpIMSRw6J5IGPFqW5nIGdpw7pwIHRhIHF1YW4gc8OhdCB2w6Agc28gc8Ohbmggbmjhu69uZyB24bqnbiDEkeG7gSB0csOqbiBuaMawbmcgduG7m2kgY8OidSBs4buHbmggKipnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAyLCBjb2xvciA9ICd3aGl0ZScpKiogdGEgY8OzIHRo4buDIHRo4bqleSByw7Ugc+G7kSBsaeG7h3UgbeG7mXQgY8OhY2ggY+G7pSB0aOG7gy4NCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KbnRoICU+JSBncm91cF9ieShjdXQsY29sb3IpICU+JSBzdW1tYXJpc2Uobj1uKCksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBuKSkgKw0KICAgIGdlb21fY29sKCBmaWxsPSAnYnJvd24nKSArDQogICAgZmFjZXRfd3JhcCh+Y3V0KSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KDQojIyMgKioyLiBIw6xuaCA2LjI6IEJp4buDdSDEkeG7kyBzbyBzw6FuaCBuaMOzbSBraW0gY8awxqFuZyB0aGVvIMSR4buZIHRyb25nIHN14buRdCB2w6AgY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMqKg0KDQpC4bqxbmcgY8OhYyBjw6J1IGzhu4duaCBkxrDhu5tpIHRhIGPDsyBuaMOzbSBiaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyB04burbmcgbG/huqFpIGNo4bq/IHTDoWMga2jDoWMgbmhhdSB04burIMSRw7MgY8OzIHRo4buDIGThu4UgZMOgbmcgcXVhbiBzw6F0IHNvIHPDoW5oIGdp4buvYSBjw6FjIGxv4bqhaSDEkeG7mSB0cm9uZyBzdeG7kXQga2ltIGPGsMahbmcgY+G7p2EgbG/huqFpIGNo4bq/IHTDoWMgbsOgeSB24bubaSBjw6FjIGxv4bqhaSDEkeG7mSB0cm9uZyBzdeG7kXQgY+G7p2EgbG/huqFpIGNo4bq/IHTDoWMga2lhDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY3V0LGNsYXJpdHkpICU+JSBzdW1tYXJpc2Uobj1uKCksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG4pKSArDQogICAgZ2VvbV9jb2woZmlsbD0icGluayIpICsNCiAgICBmYWNldF93cmFwKH5jdXQpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQpDxaluZyBuaMawIGJp4buDdSDEkeG7kyB0csOqbiBiaeG7g3UgxJHhu5MgZMaw4bubaSDEkcOieSBjxaluZyBnacO6cCB0YSBxdWFuIHPDoXQgdsOgIHNvIHPDoW5oIG5o4buvbmcgduG6p24gxJHhu4EgdHLDqm4gbmjGsG5nIHbhu5tpIGPDonUgbOG7h25oICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSoqIHRhIGPDsyB0aOG7gyB0aOG6pXkgcsO1IHPhu5EgbGnhu4d1IG3hu5l0IGPDoWNoIGPhu6UgdGjhu4MuDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY2xhcml0eSxjdXQpICU+JSBzdW1tYXJpc2Uobj1uKCksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG4pKSArDQogICAgZ2VvbV9jb2woIGZpbGw9ICdicm93bicpICsNCiAgICBmYWNldF93cmFwKH4gY3V0KSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KIyMjICoqMy4gSMOsbmggNi4zOiBCaeG7g3UgxJHhu5Mgc28gc8OhbmggbmjDs20ga2ltIGPGsMahbmcgdGhlbyBtw6B1IHbDoCDEkeG7mSB0cm9uZyBzdeG7kXQqKg0KDQpC4bqxbmcgY8OhYyBjw6J1IGzhu4duaCBkxrDhu5tpIHRhIGPDsyBuaMOzbSBiaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyB04burbmcgbG/huqFpIHRyb25nIHN14buRdCBraMOhYyBuaGF1IHThu6sgxJHDsyBjw7MgdGjhu4MgZOG7hSBkw6BuZyBxdWFuIHPDoXQgc28gc8OhbmggZ2nhu69hIGPDoWMgbcOgdSBj4bunYSBsb+G6oWkgdHJvbmcgc3Xhu5F0IG7DoHkgduG7m2kgbcOgdSBj4bunYSBsb+G6oWkgdHJvbmcgc3Xhu5F0IGtpYQ0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpudGggJT4lIGdyb3VwX2J5KGNsYXJpdHksY29sb3IpICU+JSBzdW1tYXJpc2Uobj1uKCksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9InBpbmsiKSArDQogICAgZmFjZXRfd3JhcCh+Y2xhcml0eSkgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCkPFqW5nIG5oxrAgYmnhu4N1IMSR4buTIHRyw6puIGJp4buDdSDEkeG7kyBkxrDhu5tpIMSRw6J5IGPFqW5nIGdpw7pwIHRhIHF1YW4gc8OhdCB2w6Agc28gc8Ohbmggbmjhu69uZyB24bqnbiDEkeG7gSB0csOqbiBuaMawbmcgduG7m2kgY8OidSBs4buHbmggKipnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAyLCBjb2xvciA9ICd3aGl0ZScpKiogdGEgY8OzIHRo4buDIHRo4bqleSByw7Ugc+G7kSBsaeG7h3UgbeG7mXQgY8OhY2ggY+G7pSB0aOG7gy4gDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY2xhcml0eSxjb2xvcikgJT4lIHN1bW1hcmlzZShuPW4oKSwuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG4pKSArDQogICAgZ2VvbV9jb2woIGZpbGw9ICdicm93bicpICsNCiAgICBmYWNldF93cmFwKH5jbGFyaXR5KSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KIyMgKipWSUkuIFNvIHPDoW5oIG5ow7NtIGtpbSBjxrDGoW5nIHRoZW8gbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCoqDQoNCiMjIyAqKjEuIEjDrG5oIDcuMTogYmnhu4N1IMSR4buTIHNvIHPDoW5oIG5ow7NtIGtpbSBjxrDGoW5nIChtw6B1IHbDoCBjaOG6pXQgbMaw4bujbmcgY2jhur8gdMOhYykqKg0KDQpCaeG7g3UgxJHhu5MgbmjDs20gc2F1IGzDoCB0aOG7kW5nIGvDqiBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIHThu6tuZyBsb+G6oWkga2ltIGPGsMahbmcgY2jhur8gdMOhYyB0aGVvIHThuqV0IGPhuqMgY8OhYyBtw6B1IGPDsyDEkeG6p3kgxJHhu6cgc+G7kSBsaeG7h3UgIHRyw6puIHThu6tuZyBiaeG7g3UgxJHhu5MgDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG0gPSBtZWFuKHByaWNlKSwuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZmFjZXRfd3JhcCh+Y3V0ICkgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtKSkpICsNCiAgICBsYWJzKHggPSAnQ29sb3IgJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQojIyMgKioyLiBIw6xuaCA3LjI6IGJp4buDdSDEkeG7kyBzbyBzw6FuaCBuaMOzbSBraW0gY8awxqFuZyAoxJHhu5kgdHJvbmcgc3Xhu5F0IHbDoCBjaOG6pXQgbMaw4bujbmcgY2jhur8gdMOhYykqKg0KDQpCaeG7g3UgxJHhu5MgbmjDs20gc2F1IGzDoCB0aOG7kW5nIGvDqiBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIHThu6tuZyBsb+G6oWkga2ltIGPGsMahbmcgY2jhur8gdMOhYyB0aGVvIHThuqV0IGPhuqMgY8OhYyDEkeG7mSB0cm9uZyBzdeG7kXQgIGPDsyDEkeG6p3kgxJHhu6cgc+G7kSBsaeG7h3UgIHRyw6puIHThu6tuZyBiaeG7g3UgxJHhu5MgDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY3V0LGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobSA9IG1lYW4ocHJpY2UpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBmYWNldF93cmFwKH5jdXQgKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0pKSkgKw0KICAgIGxhYnMoeCA9ICdjbGFyaXR5ICcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KIyMjICoqMy4gSMOsbmggNy4zOiBiaeG7g3UgxJHhu5Mgc28gc8OhbmggbmjDs20ga2ltIGPGsMahbmcgKG3DoHUgdsOgIMSR4buZIHRyb25nIHN14buRdCApKioNCg0KQmnhu4N1IMSR4buTIG5ow7NtIHNhdSBsw6AgdGjhu5FuZyBrw6ogbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSB04burbmcgbG/huqFpIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQga2jDoWMgbmhhdSB0aGVvIHThuqV0IGPhuqMgY8OhYyBtw6B1IGPDsyDEkeG6p3kgxJHhu6cgc+G7kSBsaeG7h3UgIHRyw6puIHThu6tuZyBiaeG7g3UgxJHhu5MgDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY2xhcml0eSxjb2xvcikgJT4lIHN1bW1hcmlzZShtID0gbWVhbihwcmljZSksIC5ncm91cHM9J2Ryb3AnKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZmFjZXRfd3JhcCh+Y2xhcml0eSkgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtKSkpICsNCiAgICBsYWJzKHggPSAnQ29sb3IgJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQojIyAqKlZJSUkuIFBow6JuIHTDrWNoIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyAgbeG7qWMgZ2nDoSB2w6Aga2jhu5FpIGzGsOG7o25nIGNhcmF0KioNCg0KIyMjICoqMS4gSMOsbmggOC4xOiBCSeG7g3UgxJHhu5MgcGjDom4gdMOtY2ggc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIG3hu6ljIGdpw6EqKg0KDQpCaeG7g3UgxJHhu5Mgc2F1IGdpw7pwIHRhIHBow6JuIGNoaWEga2jhu5FpIGzGsOG7o25nIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nIHRow6BuaCA1IGxv4bqhaSBraMOhYyBuaGF1IHRoZW8gbeG7qWMgxJHhu5kgdOG7qyBiw6kgxJHhur9uIGzhu5tuIMSR4buTbmcgdGjhu51pIHThu6sgxJHDsyB0aOG7kW5nIGvDqiBz4buRIGzGsOG7o25nIHRoZW8gbmjDs20gY+G7q2EgY2hpYS4gQ+G7pSB0aOG7gzogxJHhu5FpIHbhu5tpIGPDoWMgbG/huqFpIGtpbSBjxrDGoW5nIGPDsyBraOG7kWkgbMaw4bujbmcgY2FyYXQgbmjhu48gbmjhuqV0IGzhuqFpIGNoaeG6v20gdGjhu4sgcGjhuqduIGzhu5tuIG5o4bqldCB0cm9uZyB04buVbmcgc+G7kSBraW0gY8awxqFuZyDEkeG6t2MgYmnhu4d0IHbhu5tpIGhhaSBsb+G6oWkgbMOgIGzhu5tuIHbDoCBy4bqldCBs4bubbiBs4bqhaSBraMO0bmcgY8OzIHRyw6puIHRo4buRbmcga8OqLg0KDQpOaMawIHbhuq15IHRyw6puIHRo4buLIHTGsOG7nW5nIGhp4buHbiBuYXkgdGjhu5FuZyBrw6ogc+G7kSBraW0gY8awxqFuZyBjw7Mga2jhu5FpIGzGsOG7o25nIGNhcmF0IG5o4buPIGtow6EgcGjhu5UgYmnhur9uIG5oxrBuZyBsb+G6oWkga2jhu5FpIGzGsOG7o25nIGNhcmF0IGzhu5tuIGzhuqFpIHLhuqV0IGhp4bq/bSB2w6AgaOG6p3UgbmjGsCBraMO0bmcgY8OzLg0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpudCA8LW50aCAlPiUgbXV0YXRlKENhcmF0ID0gY3V0KGNhcmF0LDUsIGxhYmVsID0gYygncuG6pXQgbmjhu48nLCAnbmjhu48nLCd24burYScsJ2zhu5tuJywncuG6pXQgbOG7m24nKSkpDQpudCAlPiUgZ2dwbG90KGFlcyh4ID0gQ2FyYXQpKSArDQogIGdlb21fYmFyKGZpbGwgPSAncHVycGxlJykNCmBgYA0KDQojIyMgKioyLiBIw6xuaCA4LjI6IEJJ4buDdSDEkeG7kyBwaMOibiB0w61jaCBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gbeG7qWMgZ2nDoSoqDQoNClbhu5tpIG5o4buvbmcgY8OidSBs4buHbmggc2F1IHRhIGPDsyB0aOG7gyBwaMOibiBi4buVIG3hu6ljIGdpYSB0aMOgbmggNSBt4bupYyDEkeG7mSB0xINuZyBk4bqnbiB2w6AgbeG7l2kgbeG7qWMgxJHhu5kgZMaw4bubaSDEkcOieSDEkeG7gXUgxJHGsOG7o2MgdGjhu5FuZyBrw6ogbOG6oWkgduG7m2kgc+G7kSBsxrDhu6NuZyBraMOhYyBuaGF1LiBD4bulIHRo4buDOiBt4bupYyBnacOhIHLhuqV0IG5o4buPIGNoaeG6v20gcGjhuqduIGzhu5tuIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdHLDqm4gdGjhu4sgdHLGsOG7nW5nIGPDsm4gduG7m2kgbeG7qWMgZ2nDoSBs4bubbiB2w6AgcuG6pXQgbOG7m24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBoaeG6v20gY2hp4bq/bSB04buJIHRy4buNbmcgcuG6pXQgbmjhu48gdHLDqm4gdOG7lW5nIHPhu5EgDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50MSA8LSBudGggJT4lIG11dGF0ZShQcmljZSA9IGN1dChwcmljZSw1LCBsYWJlbCA9IGMoJ3LhuqV0IHRo4bqlcCAnLCAndGjhuqVwJywndGInLCdjYW8nLCdy4bqldCBjYW8nKSkpDQpudDEgJT4lIGdncGxvdChhZXMoeCA9IFByaWNlKSkgKw0KICBnZW9tX2JhcihmaWxsID0gJ3B1cnBsZScpDQoNCmBgYA0KDQo=