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

1.1 Mô tả:

Bộ dữ liệu “diamonds” là một tập dữ liệu được tích hợp sẵn trong RStudio, chứa thông tin về 53.940 viên kim cương cắt tròn. Dữ liệu bao gồm các thuộc tính quan trọng như giá, trọng lượng, chất lượng cắt, màu sắc, độ trong, kích thước và tỷ lệ.

1.2 Thông tin cơ bản:

  • Số lượng: 53.940 viên kim cương
  • Biến: 10
    • price: Giá (USD)
    • carat: Trọng lượng (carat)
    • cut: Chất lượng cắt (Khá, Tốt, Rất tốt, Đặc biệt, Lý tưởng)
    • color: Màu (J - kém nhất, D - tốt nhất)
    • clarity: Độ trong (I1 - kém nhất, IF - tốt nhất)
    • x: Chiều dài (mm)
    • y: Chiều rộng (mm)
    • z: Độ sâu (mm)
    • depth: Tỷ lệ phần trăm độ sâu
    • table: Chiều rộng đỉnh kim cương so với điểm rộng nhất

2 Biểu diễn bộ dữ liệu diamonds bằng đồ thị (Bar chart và Histogram)

Mục đích của việc biểu diễn bộ dữ liệu diamonds bằng đồ thị nhằm:

  • Trực quan hóa dữ liệu

  • So sánh dữ liệu

  • Phát hiện thông tin

  • Truyền tải thông tin

  • Tăng tính thuyết phục

2.1 Đồ thị thể hiện số lượng kim cương theo từng biến: color, cut, clarity

2.1.1 Đồ thị thể hiện số lượng kim cương theo biến color

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
a <- diamonds
table(diamonds$color)
## 
##     D     E     F     G     H     I     J 
##  6775  9797  9542 11292  8304  5422  2808
a %>% ggplot(aes(x= color)) + 
      geom_bar( )+
      labs(x = 'Màu', y= ' Số lượng')

  • Đồ thị thể hiện số lượng kim cương thuộc từng nhóm màu khác nhau trong bộ dữ liệu diamonds.

    • Trục x thể hiện các màu sắc của kim cương.
    • Trục y thể hiện số lượng kim cương tương ứng với mỗi màu.
    • Chiều cao của mỗi cột thể hiện số lượng kim cương thuộc màu đó.
  • Ví dụ:

    • Nếu cột màu “G” cao nhất, nghĩa là có nhiều kim cương thuộc màu “G” nhất trong bộ dữ liệu.
    • Nếu cột màu “J” thấp hơn các cột khác, nghĩa là có ít kim cương thuộc màu “J” hơn so với các màu khác.

2.1.2 Đồ thị thể hiện số lượng kim cương theo biến cut

a <- diamonds
table(diamonds$cut)
## 
##      Fair      Good Very Good   Premium     Ideal 
##      1610      4906     12082     13791     21551
a %>% ggplot(aes(x= cut)) + 
      geom_bar( )+
      labs(x = 'Chất lượng', y= ' Số lượng')


- Biểu đồ thể hiện số lượng kim cương thuộc từng cấp độ chất lượng khác nhau trong bộ dữ liệu diamonds. - Trục x thể hiện các cấp độ chất lượng kim cương, từ thấp đến cao (từ “Fair” đến “Ideal”). - Trục y thể hiện số lượng kim cương tương ứng với mỗi cấp độ chất lượng. - Chiều cao của mỗi cột thể hiện số lượng kim cương thuộc cấp độ chất lượng đó. - Ví dụ:

  • Nếu cột “Ideal” cao nhất, nghĩa là có nhiều kim cương có chất lượng “Ideal” nhất trong bộ dữ liệu.
  • Nếu cột “Very Good” thấp hơn các cột Premium và Ideal, nghĩa là có ít kim cương có chất lượng “Very Good” hơn so với các cấp độ Premium và Ideal.

2.1.3 Đồ thị thể hiện số lượng kim cương theo biến clarity

a <- diamonds
table(diamonds$clarity)
## 
##    I1   SI2   SI1   VS2   VS1  VVS2  VVS1    IF 
##   741  9194 13065 12258  8171  5066  3655  1790
a %>% ggplot(aes(x= clarity)) + 
      geom_bar( )+
      labs(x = 'Độ trong suốt', y= ' Số lượng')

  • Biểu đồ thể hiện số lượng kim cương thuộc từng cấp độ độ trong suốt khác nhau trong bộ dữ liệu diamonds.

    • Trục x thể hiện các cấp độ độ trong suốt kim cương, từ thấp đến cao (từ “I1” đến “IF”).
    • Trục y thể hiện số lượng kim cương tương ứng với mỗi cấp độ độ trong suốt.
    • Chiều cao của mỗi cột thể hiện số lượng kim cương thuộc cấp độ độ trong suốt đó.
  • Ví dụ:

    • Nếu cột “SI1” cao nhất, nghĩa là có nhiều kim cương có độ trong suốt “SI1” nhất trong bộ dữ liệu.
    • Nếu cột “I1” thấp nhất, nghĩa kim cương có độ trong suốt “I1” chiếm số lượng ít nhất trong bộ dữ liệu.

2.2 Biểu đồ cột với chú thích số lượng theo từng biến: cut, color, clarity

2.2.1 Biểu đồ thanh với chú thích số lượng theo màu sắc kim cương( biến color)

a <- diamonds
a %>% group_by(color) %>% summarise(k= n()) %>%
  ggplot(aes(color,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = k),vjust = 2, color = 'black') +
    labs(x = 'Màu', y = 'Số lượng')

  • Biểu đồ này tiếp tục thể hiện số lượng kim cương thuộc từng nhóm màu khác nhau trong bộ dữ liệu diamonds, tương tự như biểu đồ trước.

  • Điểm khác biệt:

    • Biểu đồ này sử dụng các cột hình chữ nhật (geom_col) thay vì các thanh (geom_bar).
    • Biểu đồ này thêm các chú thích (geom_text) hiển thị số lượng kim cương (biến k) tương ứng với mỗi màu.
  • Các thành phần của code:

    • group_by(color): Nhóm dữ liệu theo màu sắc.

    • summarise(k= n()): Tính tổng số kim cương (n()) cho mỗi nhóm màu, lưu trữ trong biến k.

    • aes(color,k): ánh xạ trục x cho màu sắc (color) và trục y cho số lượng (k).

    • geom_col(fill=‘skyblue’): Vẽ các cột màu xanh da trời (skyblue).

    • geom_text(aes(label = k), vjust = 2, color = ‘black’): Thêm chú thích hiển thị giá trị của biến k (số lượng) tại vị trí trên cùng mỗi cột (vjust=2), màu đen (black).

    • So với biểu đồ ban đầu (a %>% ggplot(aes(x= color)) + geom_bar( ) + labs(x = ‘Màu’, y= ’ Số lượng’)),

      • Biểu đồ này trực quan hơn do hiển thị chính xác số lượng kim cương cho mỗi màu sắc.
      • Mặc dù cả hai đều sử dụng các cột để thể hiện số lượng, việc thêm chú thích số lượng giúp người xem dễ dàng nắm bắt thông tin mà không cần ước lượng chiều cao của các cột.
  • Ví dụ: Khi quan sát biểu đồ ta thấy

    • Cột màu “G” cao nhất và G có số lượng 11292 viên kim cương, nghĩa là có nhiều kim cương thuộc màu “G” nhất trong bộ dữ liệu.
    • Tương tự, cột màu “J” thấp nhất và có số lượng viên kim cương là 2808 viên, nghĩa là có ít kim cương thuộc màu “J” nhất trong bộ dữ liệu.

2.2.2 Biểu đồ thanh với chú thích số lượng theo chất lượng cắt( biến cut)

a <- diamonds
a %>% group_by(cut) %>% summarise(k= n()) %>%
  ggplot(aes(cut,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = k),vjust = 2, color = 'black') +
    labs(x = 'Chất lượng cắt', y = 'Số lượng')

  • Biểu đồ này thể hiện số lượng kim cương thuộc từng cấp độ chất lượng cắt khác nhau trong bộ dữ liệu diamonds.

    • Trục x: Thể hiện các cấp độ chất lượng cắt kim cương (cut), từ “Fair” (kém) đến “Ideal” (hoàn hảo).

    • Trục y: Thể hiện số lượng kim cương (k) tương ứng với mỗi cấp độ chất lượng cắt.

    • Các cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột biểu thị tỷ lệ số lượng kim cương thuộc một cấp độ chất lượng cắt nhất định.

    • Chú thích văn bản màu đen (“black”): Hiển thị chính xác số lượng kim cương cho mỗi cấp độ chất lượng cắt, nằm trên đỉnh cột tương ứng.

    • So với biểu đồ ban đầu (a %>% ggplot(aes(x= cut)) + geom_bar( ) + labs(x = ‘Chất lượng’, y= ’ Số lượng’)),

      • Biểu đồ này cung cấp thêm thông tin chi tiết về số lượng chính xác kim cương ở mỗi cấp độ.
      • Mặc dù cả hai đều sử dụng các cột để thể hiện số lượng, việc thêm chú thích số lượng giúp người xem dễ dàng nắm bắt thông tin mà không cần ước lượng chiều cao của các cột.
  • VD: Quan sát biểu đồ trên ta thấy được

    • Số lượng kim cương nhiều nhất tương ứng với cấp độ chất lượng cắt ” Ideal” là 21551 viên và số lượng kim cương ít nhất tương ứng với cấp độ chất lượng cắt “Fair” là 1610 viên.

2.2.3 Biểu đồ thanh với chú thích số lượng theo độ trong suốt ( biến clarity)

a <- diamonds
a %>% group_by(clarity) %>% summarise(k= n()) %>%
  ggplot(aes(clarity,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = k),vjust = 2, color = 'black') +
    labs(x = 'Độ trong suốt', y = 'Số lượng')

  • Biểu đồ này thể hiện số lượng kim cương thuộc từng cấp độ độ trong suốt khác nhau trong bộ dữ liệu diamonds.

    • Trục x: Thể hiện các cấp độ độ trong suốt kim cương (clarity), từ “I1” (kém trong) đến “IF” (hoàn hảo không tì vết).

    • Trục y: Thể hiện số lượng kim cương (k) tương ứng với mỗi cấp độ độ trong suốt.

    • Các cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột biểu thị tỷ lệ số lượng kim cương thuộc một cấp độ độ trong suốt nhất định.

    • Chú thích văn bản màu đen (“black”): Hiển thị chính xác số lượng kim cương cho mỗi cấp độ độ trong suốt, nằm trên đỉnh cột tương ứng.

    • So với biểu đồ ban đầu (a %>% ggplot(aes(x= clarity)) + geom_bar( ) + labs(x = ‘Độ trong suốt’, y= ’ Số lượng’)),

      • Biểu đồ này cung cấp thêm thông tin chi tiết về số lượng chính xác kim cương ở mỗi cấp độ.
      • Mặc dù cả hai đều sử dụng các cột để thể hiện số lượng, việc thêm chú thích số lượng giúp người xem dễ dàng nắm bắt thông tin mà không cần ước lượng chiều cao của các cột.
  • VD: Quan sát biểu đồ trên ta thấy được

    • Độ trong suốt loại “SI1” chiếm số lượng lớn nhất- 13065 viên và chiếm số lượng kim cương ít nhất trong bộ dữ liệu tương ứng với độ trong suốt loại “I1”

2.3 Biểu đồ cột thể hiện giá trị trung bình trọng lượng carat theo các biến: cut, color, clarity

2.3.1 Biểu đồ cột thể hiện giá trị trung bình trọng lượng carat theo màu sắc kim cương

a <- diamonds
a %>% group_by(color) %>% summarise(k= mean(carat)) %>%
  ggplot(aes(color,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,2)),vjust = 1, color = 'black') +
    labs(x = 'Màu', y = 'Số lượng')

  • Biểu đồ này thể hiện giá trị trung bình trọng lượng carat của kim cương thuộc từng màu sắc khác nhau trong bộ dữ liệu diamonds.

    • Trục x: Thể hiện các màu sắc của kim cương.
    • Trục y: Thể hiện giá trị trung bình trọng lượng carat (k) được làm tròn đến 2 chữ số thập phân (round(k, 2)) của kim cương thuộc mỗi màu sắc.
    • Các cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột biểu thị giá trị trung bình trọng lượng carat của kim cương có màu sắc tương ứng.
    • Chú thích văn bản màu đen (“black”): Hiển thị giá trị trung bình chính xác ( được làm tròn) nằm trên đỉnh mỗi cột.
  • VD: Ta thấy cột có màu “J” cao nhất trong biểu đồ. Điều này có nghĩa là kim cương màu “J” có giá trị trung bình trọng lượng carat cao nhất trong số các màu sắc có trong bộ dữ liệu. Ví dụ, chú thích trên cột màu “J” có thể hiển thị giá trị 1.16 carat, cho biết kim cương “J” trung bình có trọng lượng 1.16 carat.

2.3.2 Biểu đồ cột thể hiện giá trị trung bình trọng lượng carat theo chất lượng cắt kim cương

a <- diamonds
a %>% group_by(cut) %>% summarise(k= mean(carat)) %>%
  ggplot(aes(cut,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,2)),vjust = 1, color = 'black') +
    labs(x = 'Chất lượng cắt', y = 'Số lượng')

  • Biểu đồ này thể hiện giá trị trung bình của trọng lượng carat theo từng chất lượng cắt của kim cương trong bộ dữ liệu diamonds.

    • Trục x: Thể hiện các chất lượng cắt khác nhau của kim cương, từ “Poor” (kém) đến “Ideal” (hoàn hảo).
    • Trục y: Thể hiện giá trị trung bình (k) trọng lượng carat, được làm tròn đến 2 chữ số thập phân (round(k, 2)), của kim cương thuộc mỗi chất lượng cắt.
    • Các cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột tỷ lệ thuận với giá trị trung bình trọng lượng carat của kim cương có chất lượng cắt tương ứng.
    • Chú thích văn bản màu đen (“black”): Hiển thị giá trị trung bình chính xác (được làm tròn) nằm trên đỉnh mỗi cột.
  • Ví dụ cụ thể:

    • Ta thấy cột “Fair” tương ứng với giá trị trung bình trọng lượng carat là 1.05, là cột cao nhất trong biểu đồ. Điều này có nghĩa là kim cương có chất lượng cắt “Fair” có giá trị trung bình trọng lượng carat cao nhất trong số các chất lượng cắt có trong bộ dữ liệu.

2.3.3 Biểu đồ cột thể hiện giá trị trung bình trọng lượng carat theo độ trong suốt của kim cương

a <- diamonds
a %>% group_by(clarity) %>% summarise(k= mean(carat)) %>%
  ggplot(aes(clarity,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,2)),vjust = 1, color = 'black') +
    labs(x = 'Màu', y = 'Số lượng')

  • Biểu đồ này thể hiện giá trị trung bình của trọng lượng carat theo từng độ trong suốt của kim cương trong bộ dữ liệu diamonds.

    • Trục x: Thể hiện các độ trong suốt khác nhau của kim cương, từ “I1” (kém trong) đến “IF” (hoàn hảo không tì vết).
    • Trục y: Thể hiện giá trị trung bình (k) trọng lượng carat, được làm tròn đến 2 chữ số thập phân (round(k, 2)), của kim cương thuộc mỗi độ trong suốt.
    • Các cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột tỷ lệ thuận với giá trị trung bình trọng lượng carat của kim cương có độ trong suốt tương ứng.
    • Chú thích văn bản màu đen (“black”): Hiển thị giá trị trung bình chính xác (được làm tròn) nằm trên đỉnh mỗi cột.
  • Ví dụ cụ thể:

Ta thấy cột “I1” có giá trị trung bình trọng lượng carat là 1.28, là cột cao nhất trong biểu đồ. Điều này có nghĩa là kim cương có độ trong suốt “I1” có giá trị trung bình rọng lượng carat cao nhất trong số các độ trong suốt có trong bộ dữ liệu.

2.4 Biểu đồ thể hiện giá trị trung bình giá bán theo biến: cut, color và clarity

2.4.1 Biểu đồ thể hiện giá trị trung bình giá bán theo màu sắc kim cương

a <- diamonds
a %>% group_by(color) %>% summarise(k= mean(price)) %>%
  ggplot(aes(color,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,2)),vjust = 1, color = 'black') +
    labs(x = 'Màu', y = 'Số lượng')

  • Biểu đồ này thể hiện giá trị trung bình của giá bán theo từng màu sắc của kim cương trong bộ dữ liệu diamonds.

    • Trục x: Thể hiện các màu sắc khác nhau của kim cương.
    • Trục y: Thể hiện giá trị trung bình (k) giá bán, được làm tròn đến 2 chữ số thập phân (round(k, 2)), của kim cương thuộc mỗi màu sắc.
    • Cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột tỷ lệ thuận với giá trị trung bình giá bán của kim cương có màu sắc tương ứng.
    • Chú thích văn bản màu đen (“black”): Hiển thị giá trị trung bình chính xác (được làm tròn) nằm trên đỉnh mỗi cột.
  • Ví dụ cụ thể:

    • Màu J cao nhất trong biểu đồ. Điều này có nghĩa là kim cương màu J có giá trị trung bình giá bán cao nhất trong số các màu sắc. Ví dụ, chú thích trên cột màu J có thể hiển thị giá trị 5323,82 USD, cho biết kim cương màu J trung bình có giá bán 5323,82 USD.

    • Màu E thấp nhất trong biểu đồ. Điều này có nghĩa là kim cương màu E có giá trị trung bình giá bán thấp nhất trong số các màu sắc. Ví dụ, chú thích trên cột màu M có thể hiển thị giá trị 3076,75 USD, cho biết kim cương màu M trung bình có giá bán 3076,75 USD.

2.4.2 Biểu đồ thể hiện giá trị trung bình giá bán theo chất lượng cắt

a <- diamonds
a %>% group_by(cut) %>% summarise(k= mean(price)) %>%
  ggplot(aes(cut,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,2)),vjust = 1, color = 'black') +
    labs(x = 'Chất lượng cắt', y = 'Số lượng')

  • Biểu đồ này thể hiện giá trị trung bình của giá bán theo từng chất lượng cắt của kim cương trong bộ dữ liệu diamonds.

    • Trục x: Thể hiện các chất lượng cắt khác nhau của kim cương, từ “Poor” (kém) đến “Ideal” (hoàn hảo).
    • Trục y: Thể hiện giá trị trung bình (k) giá bán, được làm tròn đến 2 chữ số thập phân (round(k, 2)), của kim cương thuộc mỗi chất lượng cắt.
    • Cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột tỷ lệ thuận với giá trị trung bình giá bán của kim cương có chất lượng cắt tương ứng.
    • Chú thích văn bản màu đen (“black”): Hiển thị giá trị trung bình chính xác (được làm tròn) nằm trên đỉnh mỗi cột.
  • Ví dụ cụ thể:

    • Chất lượng cắt “Premium” cao nhất trong biểu đồ. Điều này có nghĩa là kim cương có chất lượng cắt hoàn hảo có giá trị trung bình giá bán cao nhất trong số các chất lượng cắt. Ví dụ, chú thích trên cột “Premium” có thể hiển thị giá trị 4584,26 USD, cho biết kim cương có chất lượng cắt “Premium” trung bình có giá bán 4584,26 USD.

    • Chất lượng cắt ” Ideal” thấp nhất trong biểu đồ. Điều này có nghĩa là kim cương có chất lượng cắt “Ideal” có giá trị trung bình giá bán thấp nhất trong số các chất lượng cắt. Ví dụ, chú thích trên cột “Poor” có thể hiển thị giá trị 3457,54 USD, cho biết kim cương có chất lượng cắt kém trung bình có giá bán 3457,54 USD.

2.4.3 Biểu đồ thể hiện giá trị trung bình giá bán theo độ trong suốt

a <- diamonds
a %>% group_by(clarity) %>% summarise(k= mean(price)) %>%
  ggplot(aes(clarity,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,2)),vjust = 1, color = 'black') +
    labs(x = 'Độ trong suốt', y = 'Số lượng')

  • Biểu đồ này thể hiện giá trị trung bình của giá bán theo từng độ trong suốt của kim cương trong bộ dữ liệu diamonds.

    • Trục x: Thể hiện các độ trong suốt khác nhau của kim cương, từ “I1” (kém trong) đến “IF” (hoàn hảo không tì vết).
    • Trục y: Thể hiện giá trị trung bình (k) giá bán, được làm tròn đến 2 chữ số thập phân (round(k, 2)), của kim cương thuộc mỗi độ trong suốt.
    • Cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột tỷ lệ thuận với giá trị trung bình giá bán của kim cương có độ trong suốt tương ứng.
    • Chú thích văn bản màu đen (“black”): Hiển thị giá trị trung bình chính xác (được làm tròn) nằm trên đỉnh mỗi cột.
  • Ví dụ cụ thể:

    • Độ trong suốt “SI2” cao nhất trong biểu đồ. Điều này có nghĩa là kim cương có độ trong suốt “SI2” có giá trị trung bình giá bán cao nhất trong số các độ trong suốt. Ví dụ, chú thích trên cột “SI2” có thể hiển thị giá trị 5063,03 USD, cho biết kim cương có độ trong suốt “SI2” trung bình có giá bán 5063,03 USD

    • Độ trong suốt “WS1” thấp nhất trong biểu đồ. Điều này có nghĩa là kim cương có độ trong suốt “WS1” có giá trị trung bình giá bán thấp nhất trong số các độ trong suốt. Ví dụ, chú thích trên cột “WS1” có thể hiển thị giá trị 2523,11 USD, cho biết kim cương có độ trong suốt kém trong trung bình có giá bán 2523,11 USD.

2.5 Biểu đồ cột thể hiện phương sai giá bán theo các biens: cut, color và clarity.

2.5.1 Biểu đồ cột thể hiện phương sai giá bán theo màu sắc kim cương

a <- diamonds
a %>% group_by(color) %>% summarise(k= var(price)) %>%
  ggplot(aes(color,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,2)),vjust = 1, color = 'black') +
    labs(x = 'Màu', y = 'Số lượng')

  • Biểu đồ này thể hiện phương sai của giá bán theo từng màu sắc của kim cương trong bộ dữ liệu diamonds. Phương sai là một thước đo mức độ phân tán của dữ liệu.

    • Trục x: Thể hiện các màu sắc khác nhau của kim cương.
    • Trục y: Thể hiện phương sai (k) của giá bán (được làm tròn đến 2 chữ số thập phân (round(k, 2))), cho biết mức độ trải rộng của giá bán
    • Giá trị cao hơn trên trục y cho biết phương sai cao hơn, nghĩa là giá bán của kim cương có màu sắc đó phân tán rộng hơn xung quanh giá trung bình.
    • Giá trị thấp hơn menunjukkan phương sai thấp hơn, nghĩa là giá bán của kim cương có màu sắc đó ít phân tán hơn xung quanh giá trung bình.
    • Các cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột tỷ lệ thuận với phương sai giá bán của kim cương có màu sắc tương ứng.
    • Chú thích văn bản màu đen (“black”): Hiển thị phương sai chính xác (được làm tròn) nằm trên đỉnh mỗi cột.
  • Ví dụ cụ thể:

    • Màu “I” cao nhất trong biểu đồ. Điều này có nghĩa là giá bán của kim cương màu D có phương sai cao nhất, cho biết giá bán của chúng phân tán rộng nhất xung quanh giá trung bình. Ví dụ, chú thích trên cột màu I có thể hiển thị giá trị 22300944,68 USD^2, cho biết phương sai giá bán của kim cương màu I trung bình là 22300944,68 USD^2.

    • Màu E thấp nhất trong biểu đồ. Điều này có nghĩa là giá bán của kim cương màu E có phương sai thấp nhất, cho biết giá bán của chúng ít phân tán nhất xung quanh giá trung bình. Ví dụ, chú thích trên cột màu E có thể hiển thị giá trị 11183397,31 USD^2, cho biết phương sai giá bán của kim cương màu M trung bình là 11183397,31 USD^2.

2.5.2 Biểu đồ cột thể hiện phương sai giá bán theo chất lượng cắt

a <- diamonds
a %>% group_by(cut) %>% summarise(k= var(price)) %>%
  ggplot(aes(cut,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,2)),vjust = 1, color = 'black') +
    labs(x = 'Chất lượng cắt', y = 'Số lượng')

  • Biểu đồ này thể hiện phương sai của giá bán theo từng chất lượng cắt của kim cương trong bộ dữ liệu diamonds. Phương sai là một thước đo mức độ phân tán của dữ liệu.

    • Trục x: Thể hiện các chất lượng cắt khác nhau của kim cương, từ “Poor” (kém) đến “Ideal” (hoàn hảo).
    • Trục y: Thể hiện phương sai (k) của giá bán (được làm tròn đến 2 chữ số thập phân (round(k, 2))), cho biết mức độ trải rộng của giá bán
    • Giá trị cao hơn trên trục y cho biết phương sai cao hơn, nghĩa là giá bán của kim cương có chất lượng cắt đó phân tán rộng hơn xung quanh giá trung bình.
    • Giá trị thấp hơn menunjukkan phương sai thấp hơn, nghĩa là giá bán của kim cương có chất lượng cắt đó ít phân tán hơn xung quanh giá trung bình.
    • Các cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột tỷ lệ thuận với phương sai giá bán của kim cương có chất lượng cắt tương ứng.
    • Chú thích văn bản màu đen (“black”): Hiển thị phương sai chính xác (được làm tròn) nằm trên đỉnh mỗi cột.
  • Ví dụ cụ thể:

    • Chất lượng cắt “Premium” cao nhất trong biểu đồ. Điều này có nghĩa là giá bán của kim cương có chất lượng cắt “Premium” có phương sai cao nhất, cho biết giá bán của chúng phân tán rộng nhất xung quanh giá trung bình. Ví dụ, chú thích trên cột “Premium” có thể hiển thị giá trị 18915583,8 USD^2, cho biết phương sai giá bán của kim cương có chất lượng cắt hoàn hảo trung bình là 18915583,8 USD^2.

    • Chất lượng cắt “Fair” thấp nhất trong biểu đồ. Điều này có nghĩa là giá bán của kim cương có chất lượng cắt kém có phương sai thấp nhất, cho biết giá bán của chúng ít phân tán nhất xung quanh giá trung bình. Ví dụ, chú thích trên cột “Fair” có thể hiển thị giá trị 12676352,83 USD^2, cho biết phương sai giá bán của kim cương có chất lượng cắt kém trung bình là 12676352,83 USD^2

2.5.3 Biểu đồ cột thể hiện phương sai giá bán theo độ trong suốt

a <- diamonds
a %>% group_by(clarity) %>% summarise(k= var(price)) %>%
  ggplot(aes(clarity,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,2)),vjust = 0.85, color = 'black') +
    labs(x = 'Độ trong suốt', y = 'Số lượng')

  • Biểu đồ này thể hiện phương sai của giá bán theo từng độ trong suốt của kim cương trong bộ dữ liệu diamonds. Phương sai là một thước đo mức độ phân tán của dữ liệu.

    • Trục x: Thể hiện các độ trong suốt khác nhau của kim cương, từ “I1” (kém trong) đến “IF” (hoàn hảo không tì vết).
    • Trục y: Thể hiện phương sai (k) của giá bán (được làm tròn đến 2 chữ số thập phân (round(k, 2))), cho biết mức độ trải rộng của giá bán
    • Giá trị cao hơn trên trục y cho biết phương sai cao hơn, nghĩa là giá bán của kim cương có độ trong suốt đó phân tán rộng hơn xung quanh giá trung bình.
    • Giá trị thấp hơn menunjukkan phương sai thấp hơn, nghĩa là giá bán của kim cương có độ trong suốt đó ít phân tán hơn xung quanh giá trung bình.
    • Các cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột tỷ lệ thuận với phương sai giá bán của kim cương có độ trong suốt tương ứng.
    • Chú thích văn bản màu đen (“black”): Hiển thị phương sai chính xác (được làm tròn) nằm gần đỉnh mỗi cột, được điều chỉnh vị trí bằng vjust = 0.85 để tránh chồng chéo lên các cột.
  • Ví dụ cụ thể:

    • Độ trong suốt “SI2” cao nhất trong biểu đồ. Điều này có nghĩa là giá bán của kim cương có độ trong suốt “SI2” có phương sai cao nhất, cho biết giá bán của chúng phân tán rộng nhất xung quanh giá trung bình. Ví dụ, chú thích trên cột “SI2” có thể hiển thị giá trị 18151507,3 USD^2, cho biết phương sai giá bán của kim cương có độ trong suốt”SI2” trung bình là 18151507,3 USD^2.

    • Độ trong suốt “I1” thấp nhất trong biểu đồ. Điều này có nghĩa là giá bán của kim cương có độ trong suốt kém trong có phương sai thấp nhất, cho biết giá bán của chúng ít phân tán nhất xung quanh giá trung bình. Ví dụ, chú thích trên cột “I1” có thể hiển thị giá trị 7878004,26 USD^2, cho biết phương sai giá bán của kim cương có độ trong suốt kém trong trung bình là 7878004,26 USD^2.

2.6 Biểu đồ cột thể hiện phương sai trọng lượng carat theo các biến: Cut, color, clarity.

2.6.1 Biểu đồ cột thể hiện phương sai trọng lượng carat theo màu sắc kim cương

a <- diamonds
a %>% group_by(color) %>% summarise(k= var(carat)) %>%
  ggplot(aes(color,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,2)),vjust = 1, color = 'black') +
    labs(x = 'Màu', y = 'Số lượng')

  • Biểu đồ này thể hiện mức độ phân tán của trọng lượng carat (k) theo từng màu sắc của kim cương trong tập dữ liệu diamonds.

    • Trục x: Thể hiện các màu sắc khác nhau của kim cương.
    • Trục y: Thể hiện phương sai (k) của trọng lượng carat (đã được làm tròn đến 2 chữ số thập phân), cho biết mức độ trải rộng của trọng lượng carat:
    • Giá trị cao hơn trên trục y cho biết phương sai cao hơn, nghĩa là trọng lượng carat của kim cương có màu sắc đó phân tán rộng hơn xung quanh giá trị trung bình.
    • Giá trị thấp hơn cho biết phương sai thấp hơn, nghĩa là trọng lượng carat của kim cương có màu sắc đó ít phân tán hơn xung quanh giá trị trung bình. Cột màu xanh nhạt: Chiều cao của mỗi cột tỷ lệ thuận với phương sai trọng lượng carat của kim cương có màu sắc tương ứng.
    • Chú thích văn bản màu đen: Hiển thị phương sai chính xác (đã được làm tròn) nằm trên đỉnh mỗi cột.
  • Ví dụ:

    • Màu J cao nhất. Điều này có nghĩa là phương sai trọng lượng carat của kim cương màu J là cao nhất. Do đó, trọng lượng carat của kim cương màu J phân tán rộng xung quanh giá trị trung bình. Ví dụ, chú thích trên cột màu J có thể hiển thị giá trị 0.35 carat^2, cho biết phương sai là 0.35 carat^2.

    • Màu D thấp nhất. Điều này có nghĩa là phương sai trọng lượng carat của kim cương màu D là thấp nhất. Do đó, trọng lượng carat của kim cương màu D ít phân tán xung quanh giá trị trung bình. Ví dụ, chú thích trên cột màu D có thể hiển thị giá trị 0.13 carat^2, cho biết phương sai là 0.13 carat^2.

2.6.2 Biểu đồ cột thể hiện phương sai trọng lượng carat theo chất lượng cắt

a <- diamonds
a %>% group_by(cut) %>% summarise(k= var(carat)) %>%
  ggplot(aes(cut,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,3)),vjust = 1, color = 'black') +
    labs(x = 'Chất lượng cắt', y = 'Số lượng')

  • Biểu đồ này thể hiện phương sai của trọng lượng carat theo từng chất lượng cắt của kim cương trong bộ dữ liệu diamonds. Phương sai là một thước đo mức độ phân tán của dữ liệu.

    • Trục x: Thể hiện các chất lượng cắt khác nhau của kim cương, từ “Poor” (kém) đến “Ideal” (hoàn hảo).
    • Trục y: Thể hiện phương sai (k) của trọng lượng carat (được làm tròn đến 2 chữ số thập phân (round(k, 2))), cho biết mức độ trải rộng của trọng lượng carat
      • Giá trị cao hơn trên trục y cho biết phương sai cao hơn, nghĩa là trọng lượng carat của kim cương có chất lượng cắt đó phân tán rộng hơn xung quanh giá trị trung bình.
      • Giá trị thấp hơn trên trục y cho biết phương sai thấp hơn, nghĩa là trọng lượng carat của kim cương có chất lượng cắt đó ít phân tán hơn xung quanh giá trị trung bình.
    • Các cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột tỷ lệ thuận với phương sai trọng lượng carat của kim cương có chất lượng cắt tương ứng.
    • Chú thích văn bản màu đen (“black”): Hiển thị phương sai chính xác (được làm tròn) nằm trên đỉnh mỗi cột.
  • Ví dụ cụ thể:

    • Chất lượng cắt “Fair” cao nhất trong biểu đồ. Điều này có nghĩa là trọng lượng carat của kim cương có chất lượng cắt “Fair” có phương sai cao nhất, cho biết trọng lượng carat của chúng phân tán rộng nhất xung quanh giá trị trung bình. Ví dụ, chú thích trên cột “Fair” có thể hiển thị giá trị 0.267 carat^2, cho biết phương sai là 0.267 carat^2.

    • Chất lượng cắt “Good” thấp nhất trong biểu đồ. Điều này có nghĩa là trọng lượng carat của kim cương có chất lượng cắt Good có phương sai thấp nhất, cho biết trọng lượng carat của chúng ít phân tán nhất xung quanh giá trị trung bình. Ví dụ, chú thích trên cột “Good” có thể hiển thị giá trị 0.206 carat^2, cho biết phương sai là 0.206 carat^2.

2.6.3 Biểu đồ cột thể hiện phương sai trọng lượng carat theo độ trong suốt

a <- diamonds
a %>% group_by(clarity) %>% summarise(k= var(carat)) %>%
  ggplot(aes(clarity,k)) +
    geom_col(fill='skyblue') + 
    geom_text(aes(label = round(k,2)),vjust = 1, color = 'black') +
    labs(x = 'Độ trong suốt', y = 'Số lượng')

  • Biểu đồ này thể hiện phương sai của trọng lượng carat theo từng độ trong suốt của kim cương trong bộ dữ liệu diamonds. Phương sai là một thước đo mức độ phân tán của dữ liệu.

    • Trục x: Thể hiện các độ trong suốt khác nhau của kim cương, từ “I1” (kém trong) đến “IF” (hoàn hảo không tì vết).
    • Trục y: Thể hiện phương sai (k) của trọng lượng carat (được làm tròn đến 2 chữ số thập phân (round(k, 2))), cho biết mức độ trải rộng của trọng lượng carat
    • Giá trị cao hơn trên trục y cho biết phương sai cao hơn, nghĩa là trọng lượng carat của kim cương có độ trong suốt đó phân tán rộng hơn xung quanh giá trị trung bình.
    • Giá trị thấp hơn trên trục y cho biết phương sai thấp hơn, nghĩa là trọng lượng carat của kim cương có độ trong suốt đó ít phân tán hơn xung quanh giá trị trung bình.
    • Các cột màu xanh nhạt (“skyblue”): Chiều cao của mỗi cột tỷ lệ thuận với phương sai trọng lượng carat của kim cương có độ trong suốt tương ứng. Chú thích văn bản màu đen (“black”): Hiển thị phương sai chính xác (được làm tròn) nằm trên đỉnh mỗi cột.
  • Ví dụ cụ thể:

    • Độ trong suốt “I1” cao nhất trong biểu đồ. Điều này có nghĩa là trọng lượng carat của kim cương có độ trong suốt ” I1” có phương sai cao nhất, cho biết trọng lượng carat của chúng phân tán rộng nhất xung quanh giá trị trung bình. Ví dụ, chú thích trên cột “I1” có thể hiển thị giá trị 0.4 carat^2, cho biết phương sai là 0.4 carat^2.

    • Độ trong suốt “VVS1” thấp nhất trong biểu đồ. Điều này có nghĩa là trọng lượng carat của kim cương có độ trong suốt “VVS1” trong có phương sai thấp nhất, cho biết trọng lượng carat của chúng ít phân tán nhất xung quanh giá trị trung bình. Ví dụ, chú thích trên cột “VVS1” có thể hiển thị giá trị 0.09 carat^2, cho biết phương sai là 0.09 carat^2.

2.7 Biểu đồ cột kép thể hiện phân bố số lượng kim cương theo chất lượng cắt và màu sắc

2.7.1 Biểu đồ cột kép thể hiện phân bố số lượng kim cương theo chất lượng cắt và màu sắc của kim cương loại E và H

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

  • Biểu đồ này thể hiện số lượng kim cương theo từng chất lượng cắt (cut) và màu sắc (color) trong bộ dữ liệu diamonds.

    • Trục x: Thể hiện các chất lượng cắt khác nhau của kim cương, từ “Fair” (kém) đến “Ideal” (hoàn hảo).
    • Trục y: Thể hiện số lượng (n) kim cương.
    • Cột màu xanh nhạt (“skyblue”): Biểu thị số lượng kim cương có màu E theo từng chất lượng cắt.
    • Cột màu hồng (“pink”): Biểu thị số lượng kim cương có màu H theo từng chất lượng cắt.
  • Ví dụ:

    • Chất lượng cắt “Very Good”: Ta thấy trên cột “Very Good”, chiều cao của cột màu hồng cao hơn cột màu xanh nhạt. Điều này có nghĩa là có nhiều kim cương màu H hơn kim cương màu E có chất lượng cắt “Very Good”.

2.7.2 Biểu đồ cột kép thể hiện phân bố số lượng kim cương theo chất lượng cắt và màu sắc của kim cương loại E và H

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

  • Biểu đồ này thể hiện số lượng kim cương theo từng chất lượng cắt (cut) và màu sắc (color) trong bộ dữ liệu diamonds.

    • Trục x: Thể hiện các chất lượng cắt khác nhau của kim cương, từ “Fair” (kém) đến “Ideal” (hoàn hảo).
    • Trục y: Thể hiện số lượng (n) kim cương.
    • Cột màu xanh nhạt (“skyblue”): Biểu thị số lượng kim cương có màu E theo từng chất lượng cắt.
    • Cột màu hồng (“pink”): Biểu thị số lượng kim cương có màu I theo từng chất lượng cắt.
  • Ví dụ:

    • Chất lượng cắt “Premium”: Ta thấy trên cột “Premium”, chiều cao của cột màu hồng cao hơn cột màu xanh nhạt. Điều này có nghĩa là có nhiều kim cương màu I hơn kim cương màu E có chất lượng cắt “Premium”.

2.8 Biểu đồ thanh thể hiện phân bố chất lượng cắt kim cương

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

  labs(x= 'Chất lượng cắt')
## $x
## [1] "Chất lượng cắt"
## 
## attr(,"class")
## [1] "labels"
  • Biểu đồ này thể hiện phân bố của chất lượng cắt kim cương trong bộ dữ liệu diamonds.

    • Trục x: Thể hiện các chất lượng cắt được chia thành 5 nhóm: “rất nhỏ”, “nhỏ”, “vừa”, “lớn”, “rất lớn”.
    • Trục y: Thể hiện số lượng kim cương thuộc mỗi nhóm chất lượng cắt. Cột màu vàng: Biểu thị số lượng kim cương cho mỗi nhóm chất lượng cắt.

2.9 Biểu đồ cột kép theo mặt cắt (cut) phân tách theo màu sắc (color)

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

Biểu đồ này thể hiện phân bố số lượng kim cương theo chất lượng cắt (cut) được tách riêng theo màu sắc (color) trong bộ dữ liệu a.

Các thành phần:

  • Trục x: Thể hiện các chất lượng cắt khác nhau của kim cương, từ “Poor” (kém) đến “Ideal” (hoàn hảo).

  • Trục y: Thể hiện số lượng (n) kim cương.

  • Các mặt cắt (facets): Biểu đồ được chia thành hai mặt cắt theo màu sắc (color) của kim cương, được phân biệt bằng nhãn ở phía trên mỗi mặt cắt.

    • Mặt cắt D: Biểu thị phân bố số lượng kim cương theo chất lượng cắt cho màu sắc D.
    • Mặt cắt E: Biểu thị phân bố số lượng kim cương theo chất lượng cắt cho màu sắc E.
    • Mặt cắt F: Biểu thị phân bố số lượng kim cương theo chất lượng cắt cho màu sắc F.
    • Mặt cắt G: Biểu thị phân bố số lượng kim cương theo chất lượng cắt cho màu sắc G.
    • Mặt cắt H: Biểu thị phân bố số lượng kim cương theo chất lượng cắt cho màu sắc H.
    • Mặt cắt I: Biểu thị phân bố số lượng kim cương theo chất lượng cắt cho màu sắc I.
    • Mặt cắt J: Biểu thị phân bố số lượng kim cương theo chất lượng cắt cho màu sắc J.
  • Cột màu hồng (“pink”): Biểu thị số lượng kim cương cho mỗi chất lượng cắt trong mỗi mặt cắt.

  • Chú thích văn bản màu đen (“black”): Hiển thị số lượng kim cương chính xác (n) nằm trên đỉnh mỗi cột, được điều chỉnh vị trí bằng vjust = 0.65 để tránh chồng chéo lên các cột. Ví dụ:

  • Chất lượng cắt “Very Good”: Cột “Very Good” trên mặt cắt F có chiều cao cao hơn cột “Very Good” trên mặt cắt I . Điều này có nghĩa là có nhiều kim cương màu sắc F kim cương màu sắc I có chất lượng cắt “Very Good”. So sánh: Bạn có thể so sánh trực quan sự phân bố số lượng kim cương theo chất lượng cắt giữa hai màu sắc khác nhau bằng cách quan sát chiều cao tương đối của các cột trong cùng một nhóm chất lượng cắt trên hai mặt cắt riêng biệt.

2.10 Biểu đồ cột kép theo mặt cắt (cut) phân tách theo màu sắc (color), thể hiện giá trung bình

a <- diamonds
a %>% group_by(cut,color) %>% summarise(k =mean(price)) %>%
  ggplot(aes(x = cut,y = k)) +
    geom_col(position = 'dodge', fill= 'pink') +
    facet_wrap(~color) +
    geom_text(aes(label = round(k,1)),vjust = 0.25, color = 'black') +
    labs(x = 'Loại', y = 'Số lượng')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Biểu đồ này thể hiện giá trung bình của kim cương theo chất lượng cắt (cut) được tách riêng theo màu sắc (color) trong bộ dữ liệu a.

Các thành phần:

  • Trục x: Thể hiện các chất lượng cắt khác nhau của kim cương, từ “Poor” (kém) đến “Ideal” (hoàn hảo).

  • Trục y: Thể hiện giá trung bình (k) được làm tròn đến 1 chữ số thập phân (round(k, 1)).

  • Các mặt cắt (facets): Biểu đồ được chia thành hai mặt cắt theo màu sắc (color) của kim cương, được phân biệt bằng nhãn ở phía trên mỗi mặt cắt.

    • Mặt cắt D: Biểu thị giá trung bình của kim cương theo chất lượng cắt cho màu sắc D.
    • Mặt cắt E: Biểu thị giá trung bình của kim cương theo chất lượng cắt cho màu sắc E.
    • Mặt cắt F: Biểu thị giá trung bình của kim cương theo chất lượng cắt cho màu sắc F.
    • Mặt cắt G: Biểu thị giá trung bình của kim cương theo chất lượng cắt cho màu sắc G.
    • Mặt cắt H: Biểu thị giá trung bình của kim cương theo chất lượng cắt cho màu sắc H.
    • Mặt cắt I: Biểu thị giá trung bình của kim cương theo chất lượng cắt cho màu sắc I.
    • Mặt cắt J: Biểu thị giá trung bình của kim cương theo chất lượng cắt cho màu sắc J.
  • Cột màu hồng (“pink”): Biểu thị giá trung bình cho mỗi chất lượng cắt trong mỗi mặt cắt.

  • Chú thích văn bản màu đen (“black”): Hiển thị giá trung bình chính xác (được làm tròn) nằm trên đỉnh mỗi cột, được điều chỉnh vị trí bằng vjust = 0.25 để tránh chồng chéo lên các cột. Ví dụ:

  • Chất lượng cắt “Very Good”: Ta thấy “Very Good” trên mặt cắt J cao hơn cột “Very Good” trên mặt cắt G. Điều này có nghĩa là kim cương màu sắc J có giá trung bình khi chất lượng cắt là “Very Good” cao hơn kim cương màu sắc G. So sánh: Bạn có thể so sánh trực quan giá trung bình của kim cương theo chất lượng cắt giữa hai màu sắc khác nhau bằng cách quan sát chiều cao tương đối của các cột trong cùng một nhóm chất lượng cắt trên hai mặt cắt riêng biệt.

2.11 Biểu đồ cột kép theo mặt cắt (cut) phân tách theo màu sắc (color), thể hiện trọng lượng carat trung bình

a <- diamonds
a %>% group_by(cut,color) %>% summarise(k=mean(carat)) %>%
  ggplot(aes(x = cut,y = k)) +
    geom_col(position = 'dodge', fill= 'pink') +
    facet_wrap(~color) +
    geom_text(aes(label = round(k,2)),vjust = 0.65, color = 'black') +
    labs(x = 'Loại', y = 'Số lượng')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Biểu đồ này thể hiện trọng lượng carat trung bình của kim cương theo chất lượng cắt (cut) được tách riêng theo màu sắc (color) trong bộ dữ liệu a.

Các thành phần:

  • Trục x: Thể hiện các chất lượng cắt khác nhau của kim cương, từ “Poor” (kém) đến “Ideal” (hoàn hảo).

  • Trục y: Thể hiện trọng lượng carat trung bình (k) được làm tròn đến 2 chữ số thập phân (round(k, 2)).

  • Các mặt cắt (facets): Biểu đồ được chia thành hai mặt cắt theo màu sắc (color) của kim cương, được phân biệt bằng nhãn ở phía trên mỗi mặt cắt.

    • Mặt cắt D: Biểu thị trọng lượng carat trung bình của kim cương theo chất lượng cắt cho màu sắc D.
    • Mặt cắt E: Biểu thị trọng lượng carat trung bình của kim cương theo chất lượng cắt cho màu sắc E.
    • Mặt cắt F: Biểu thị trọng lượng carat trung bình của kim cương theo chất lượng cắt cho màu sắc F.
    • Mặt cắt G: Biểu thị trọng lượng carat trung bình của kim cương theo chất lượng cắt cho màu sắc G.
    • Mặt cắt H: Biểu thị trọng lượng carat trung bình của kim cương theo chất lượng cắt cho màu sắc H.
    • Mặt cắt I: Biểu thị trọng lượng carat trung bình của kim cương theo chất lượng cắt cho màu sắc I.
    • Mặt cắt J: Biểu thị trọng lượng carat trung bình của kim cương theo chất lượng cắt cho màu sắc J.
  • Cột màu hồng (“pink”): Biểu thị trọng lượng carat trung bình cho mỗi chất lượng cắt trong mỗi mặt cắt.

  • Chú thích văn bản màu đen (“black”): Hiển thị trọng lượng carat trung bình chính xác (được làm tròn) nằm trên đỉnh mỗi cột, được điều chỉnh vị trí bằng vjust = 0.65 để tránh chồng chéo lên các cột. Ví dụ:

  • Chất lượng cắt “Very Good”: Ta quan sat biểu đồ, cột “Very Good” trên mặt cắt J cao hơn cột “Very Good” trên mặt cắt G. Điều này có nghĩa là kim cương màu sắc J có trọng lượng carat trung bình khi chất lượng cắt là “Very Good” cao hơn kim cương màu sắc G.

2.12 Biểu đồ cột thể hiện trung vị trọng lượng carat theo các biến: cut, color, clarity

2.12.1 Biểu đồ cột thể hiện trung vị trọng lượng carat theo chất lượng cắt (cut)

a %>% group_by(cut) %>% summarise(m= median(carat)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge', fill= 'brown') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'pink') +
    labs(x = 'cut', y = 'Median')

Biểu đồ này thể hiện trung vị của trọng lượng carat theo chất lượng cắt (cut) trong bộ dữ liệu a.

  • Các thành phần:

    • Trục x: Thể hiện các chất lượng cắt khác nhau của kim cương, từ “Fair” (kém) đến “Ideal” (hoàn hảo).
    • Trục y: Thể hiện trọng lượng carat trung vị (m) được làm tròn đến 2 chữ số thập phân (round(m, 2)).
    • Cột màu nâu (“brown”): Biểu thị trọng lượng carat trung vị cho mỗi chất lượng cắt.
    • Chú thích văn bản màu hồng (“pink”): Hiển thị trọng lượng carat trung vị chính xác (được làm tròn) nằm trên đỉnh mỗi cột, được điều chỉnh vị trí bằng vjust = 2 để tránh chồng chéo lên các cột.
    • Tựa đề “Median”: Thể hiện trên trục y, cho biết giá trị được hiển thị là trung vị.
      • Ý nghĩa:

        Trung vị (median) là giá trị ở giữa của một tập dữ liệu đã được sắp xếp theo thứ tự. So với trung bình cộng (mean), trung vị ít bị ảnh hưởng bởi các giá trị ngoại lai (outliers) - những giá trị nằm rất xa so với phần còn lại của dữ liệu. Do đó, biểu đồ này giúp hiểu rõ hơn về trọng lượng carat điển hình của kim cương theo chất lượng cắt, ít bị ảnh hưởng bởi những viên kim cương có trọng lượng rất cao hoặc rất thấp.

  • Ví dụ:

Từ biểu đồ ta thấy cột “Good” có chiều cao cao thứ ba trên trục y. Điều này có nghĩa là một nửa số viên kim cương có chất lượng cắt “Good” có trọng lượng carat dưới giá trị trung vị m, và một nửa có trọng lượng carat trên giá trị trung vị m. So sánh: Bạn có thể so sánh trực quan trọng lượng carat trung vị giữa các chất lượng cắt khác nhau bằng cách quan sát chiều cao tương đối của các cột.

2.12.2 Biểu đồ cột thể hiện trung vị trọng lượng carat theo màu sắc (color)

a %>% group_by(color) %>% summarise(m= median(carat)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge', fill= 'brown') +
    geom_text(aes(label = round(m,3)), vjust = 2, color = 'pink') +
    labs(x = 'color', y = 'Median')

Biểu đồ này thể hiện trung vị của trọng lượng carat theo màu sắc (color) trong bộ dữ liệu a.

Các thành phần:

  • Trục x: Thể hiện các màu sắc khác nhau của kim cương.
  • Trục y: Thể hiện trọng lượng carat trung vị (m) được làm tròn đến 2 chữ số thập phân (round(m, 2)).
  • Cột màu nâu (“brown”): Biểu thị trọng lượng carat trung vị cho mỗi màu sắc.
  • Chú thích văn bản màu hồng (“pink”): Hiển thị trọng lượng carat trung vị chính xác (được làm tròn) nằm trên đỉnh mỗi cột, được điều chỉnh vị trí bằng vjust = 2 để tránh chồng chéo lên các cột.
  • Tựa đề “Median”: Thể hiện trên trục y, cho biết giá trị được hiển thị là trung vị.
    • Ý nghĩa:
    Trung vị (median) là giá trị ở giữa của một tập dữ liệu đã được sắp xếp theo thứ tự. So với trung bình cộng (mean), trung vị ít bị ảnh hưởng bởi các giá trị ngoại lai (outliers) - những giá trị nằm rất xa so với phần còn lại của dữ liệu. Do đó, biểu đồ này giúp hiểu rõ hơn về trọng lượng carat điển hình của kim cương theo màu sắc, ít bị ảnh hưởng bởi những viên kim cương có trọng lượng rất cao hoặc rất thấp.

Ví dụ:

Quan sát biểu đồ ta thấy, cột “I” có chiều cao cao thứ hai trên trục y. Điều này có nghĩa là một nửa số viên kim cương có màu sắc “I” có trọng lượng carat dưới giá trị trung vị m, và một nửa có trọng lượng carat trên giá trị trung vị m.

2.12.3 Biểu đồ cột thể hiện trung vị trọng lượng carat theo độ tinh khiết (clarity)

a %>% group_by(clarity) %>% summarise(m= median(carat)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge', fill= 'brown') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'pink') +
    labs(x = 'clarity', y = 'Median')

Biểu đồ này thể hiện trung vị của trọng lượng carat theo độ tinh khiết (clarity) của kim cương trong bộ dữ liệu a.

  • Các thành phần:

    • Trục x: Thể hiện các mức độ tinh khiết khác nhau của kim cương, thường được ký hiệu bằng chữ cái (ví dụ: IF, VVS1, VS1, SI1, v.v.).
    • Trục y: Thể hiện trọng lượng carat trung vị (m) được làm tròn đến 2 chữ số thập phân (round(m, 2)).
    • Cột màu nâu (“brown”): Biểu thị trọng lượng carat trung vị cho mỗi mức độ tinh khiết.
    • Chú thích văn bản màu hồng (“pink”): Hiển thị trọng lượng carat trung vị chính xác (được làm tròn) nằm trên đỉnh mỗi cột, được điều chỉnh vị trí bằng vjust = 2 để tránh chồng chéo lên các cột.
    • Tựa đề “Median”: Thể hiện trên trục y, cho biết giá trị được hiển thị là trung vị.

Ví dụ:

Độ tinh khiết “VVS2” có chiều cao thứ tư trên trục y. Điều này có nghĩa là một nửa số viên kim cương có độ tinh khiết “VVS1” có trọng lượng carat dưới giá trị trung vị m, và một nửa có trọng lượng carat trên giá trị trung vị m.

2.13 Biểu đồ cột thể hiện trung vị giá của kim cương theo các biến: cut, color, clarity

2.13.1 Biểu đồ cột thể hiện trung vị giá của kim cương theo chất lượng cắt (cut)

a %>% group_by(cut) %>% summarise(m= median(price)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge', fill= 'brown') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'pink') +
    labs(x = 'cut', y = 'Median')

Biểu đồ này thể hiện trung vị của giá kim cương theo chất lượng cắt (cut) trong bộ dữ liệu a.

  • Các thành phần:

    • Trục x: Thể hiện các chất lượng cắt khác nhau của kim cương, từ “Fair” (kém) đến “Ideal” (hoàn hảo).
    • Trục y: Thể hiện trọng lượng carat trung vị (m) được làm tròn đến 2 chữ số thập phân (round(m, 2)).
    • Cột màu nâu (“brown”): Biểu thị trọng lượng carat trung vị cho mỗi chất lượng cắt.
    • Chú thích văn bản màu hồng (“pink”): Hiển thị giá kim cương trung vị chính xác (được làm tròn) nằm trên đỉnh mỗi cột, được điều chỉnh vị trí bằng vjust = 2 để tránh chồng chéo lên các cột.
    • Tựa đề “Median”: Thể hiện trên trục y, cho biết giá trị được hiển thị là trung vị.
  • Ví dụ:

Từ biểu đồ ta thấy cột “Good” có chiều cao cao thứ ba trên trục y. Điều này có nghĩa là một nửa số viên kim cương có chất lượng cắt “Good” có trọng lượng carat dưới giá trị trung vị m, và một nửa có trọng lượng carat trên giá trị trung vị m. So sánh: Bạn có thể so sánh trực quan trọng lượng carat trung vị giữa các chất lượng cắt khác nhau bằng cách quan sát chiều cao tương đối của các cột.

2.13.2 Biểu đồ cột thể hiện trung vị giá của kim cương theo màu sắc kim cương (color)

a %>% group_by(color) %>% summarise(m= median(price)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge', fill= 'brown') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'pink') +
    labs(x = 'color', y = 'Median')

Biểu đồ này thể hiện trung vị của giá kim cương theo màu sắc (color) trong bộ dữ liệu a.

Các thành phần:

  • Trục x: Thể hiện các màu sắc khác nhau của kim cương.
  • Trục y: Thể hiện giá kim cương trung vị (m) được làm tròn đến 2 chữ số thập phân (round(m, 2)).
  • Cột màu nâu (“brown”): Biểu thị trọng lượng carat trung vị cho mỗi màu sắc.
  • Chú thích văn bản màu hồng (“pink”): Hiển thị trọng lượng carat trung vị chính xác (được làm tròn) nằm trên đỉnh mỗi cột, được điều chỉnh vị trí bằng vjust = 2 để tránh chồng chéo lên các cột.
  • Tựa đề “Median”: Thể hiện trên trục y, cho biết giá trị được hiển thị là trung vị.

Ví dụ:

Quan sát biểu đồ ta thấy, cột “I” có chiều cao cao thứ hai trên trục y. Điều này có nghĩa là một nửa số viên kim cương có màu sắc “I” có trọng lượng carat dưới giá trị trung vị m, và một nửa có trọng lượng carat trên giá trị trung vị m.

2.13.3 Biểu đồ cột thể hiện trung vị giá của kim cương theo độ trong suốt (clarity)

a %>% group_by(clarity) %>% summarise(m= median(price)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge', fill= 'brown') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'pink') +
    labs(x = 'clarity', y = 'Median')

Biểu đồ này thể hiện trung vị giá kim cương carat theo độ tinh khiết (clarity) của kim cương trong bộ dữ liệu a.

  • Các thành phần:

    • Trục x: Thể hiện các mức độ tinh khiết khác nhau của kim cương, thường được ký hiệu bằng chữ cái (ví dụ: IF, VVS1, VS1, SI1, v.v.).
    • Trục y: Thể hiện giá kim cương trung vị (m) được làm tròn đến 2 chữ số thập phân (round(m, 2)).
    • Cột màu nâu (“brown”): Biểu thị giá kim cương trung vị cho mỗi mức độ tinh khiết.
    • Chú thích văn bản màu hồng (“pink”): Hiển thị trọng lượng carat trung vị chính xác (được làm tròn) nằm trên đỉnh mỗi cột, được điều chỉnh vị trí bằng vjust = 2 để tránh chồng chéo lên các cột.
    • Tựa đề “Median”: Thể hiện trên trục y, cho biết giá trị được hiển thị là trung vị.
  • Ví dụ:

Độ tinh khiết “VS2” có chiều cao thứ tư trên trục y. Điều này có nghĩa là một nửa số viên kim cương có độ tinh khiết “VS2” có trọng lượng carat dưới giá trị trung vị m, và một nửa có trọng lượng carat trên giá trị trung vị m.

LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSA0Ig0KYXV0aG9yOiAiSG9hbmcgUXV5ZW4iDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclSDolTTolUywgJWQgLSAlbSAtICVZJylgIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDogDQogICAgZGZfcHJpbnQ6IGthYmxlDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdG9jX2RlcHRoOiAyDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogJzInDQogIHBkZl9kb2N1bWVudDoNCiAgICBsYXRleF9lbmdpbmU6IHhlbGF0ZXgNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KIyAqKkdp4bubaSB0aGnhu4d1IHbhu4EgYuG7mSBk4buvIGxp4buHdSBkaWFtb25kczoqKiANCg0KIyMgTcO0IHThuqM6IA0KDQpC4buZIGThu68gbGnhu4d1ICJkaWFtb25kcyIgbMOgIG3hu5l0IHThuq1wIGThu68gbGnhu4d1IMSRxrDhu6NjIHTDrWNoIGjhu6NwIHPhurVuIHRyb25nIFJTdHVkaW8sIGNo4bupYSB0aMO0bmcgdGluIHbhu4EgNTMuOTQwIHZpw6puIGtpbSBjxrDGoW5nIGPhuq90IHRyw7JuLiBE4buvIGxp4buHdSBiYW8gZ+G7k20gY8OhYyB0aHXhu5ljIHTDrW5oIHF1YW4gdHLhu41uZyBuaMawIGdpw6EsIHRy4buNbmcgbMaw4bujbmcsIGNo4bqldCBsxrDhu6NuZyBj4bqvdCwgbcOgdSBz4bqvYywgxJHhu5kgdHJvbmcsIGvDrWNoIHRoxrDhu5tjIHbDoCB04bu3IGzhu4cuIA0KDQojIyBUaMO0bmcgdGluIGPGoSBi4bqjbjogDQoNCi0gU+G7kSBsxrDhu6NuZzogNTMuOTQwIHZpw6puIGtpbSBjxrDGoW5nDQotIEJp4bq/bjogMTANCiAgLSBwcmljZTogR2nDoSAoVVNEKQ0KICAtIGNhcmF0OiBUcuG7jW5nIGzGsOG7o25nIChjYXJhdCkNCiAgLSBjdXQ6IENo4bqldCBsxrDhu6NuZyBj4bqvdCAoS2jDoSwgVOG7kXQsIFLhuqV0IHThu5F0LCDEkOG6t2MgYmnhu4d0LCBMw70gdMaw4bufbmcpDQogIC0gY29sb3I6IE3DoHUgKEogLSBrw6ltIG5o4bqldCwgRCAtIHThu5F0IG5o4bqldCkNCiAgLSBjbGFyaXR5OiDEkOG7mSB0cm9uZyAoSTEgLSBrw6ltIG5o4bqldCwgSUYgLSB04buRdCBuaOG6pXQpDQogIC0geDogQ2hp4buBdSBkw6BpIChtbSkNCiAgLSB5OiBDaGnhu4F1IHLhu5luZyAobW0pDQogIC0gejogxJDhu5kgc8OidSAobW0pDQogIC0gZGVwdGg6IFThu7cgbOG7hyBwaOG6p24gdHLEg20gxJHhu5kgc8OidQ0KICAtIHRhYmxlOiBDaGnhu4F1IHLhu5luZyDEkeG7iW5oIGtpbSBjxrDGoW5nIHNvIHbhu5tpIMSRaeG7g20gcuG7mW5nIG5o4bqldCANCg0KIyAqKkJp4buDdSBkaeG7hW4gYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcyBi4bqxbmcgxJHhu5MgdGjhu4sgKEJhciBjaGFydCB2w6AgSGlzdG9ncmFtKSoqIA0KDQpN4bulYyDEkcOtY2ggY+G7p2Egdmnhu4djIGJp4buDdSBkaeG7hW4gYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcyBi4bqxbmcgxJHhu5MgdGjhu4sgbmjhurFtOiANCg0KLSBUcuG7sWMgcXVhbiBow7NhIGThu68gbGnhu4d1IA0KDQotIFNvIHPDoW5oIGThu68gbGnhu4d1IA0KDQotIFBow6F0IGhp4buHbiB0aMO0bmcgdGluIA0KDQotIFRydXnhu4FuIHThuqNpIHRow7RuZyB0aW4gDQoNCi0gVMSDbmcgdMOtbmggdGh1eeG6v3QgcGjhu6VjIA0KDQoNCiMjICrEkOG7kyB0aOG7iyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBiaeG6v246IGNvbG9yLCBjdXQsIGNsYXJpdHkqIA0KDQojIyMgKirEkOG7kyB0aOG7iyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGJp4bq/biBjb2xvcioqDQoNCg0KDQoNCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmEgPC0gZGlhbW9uZHMNCnRhYmxlKGRpYW1vbmRzJGNvbG9yKQ0KYSAlPiUgZ2dwbG90KGFlcyh4PSBjb2xvcikpICsgDQogICAgICBnZW9tX2JhciggKSsNCiAgICAgIGxhYnMoeCA9ICdNw6B1JywgeT0gJyBT4buRIGzGsOG7o25nJykNCg0KYGBgDQoNCi0gxJDhu5MgdGjhu4sgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGh14buZYyB04burbmcgbmjDs20gbcOgdSBraMOhYyBuaGF1IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMuIA0KDQogIC0gVHLhu6VjIHggdGjhu4MgaGnhu4duIGPDoWMgbcOgdSBz4bqvYyBj4bunYSBraW0gY8awxqFuZy4NCiAgLSBUcuG7pWMgeSB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0xrDGoW5nIOG7qW5nIHbhu5tpIG3hu5dpIG3DoHUuDQogIC0gQ2hp4buBdSBjYW8gY+G7p2EgbeG7l2kgY+G7mXQgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGh14buZYyBtw6B1IMSRw7MuDQotIFbDrSBk4bulOg0KDQogIC0gTuG6v3UgY+G7mXQgbcOgdSAiRyIgY2FvIG5o4bqldCwgbmdoxKlhIGzDoCBjw7Mgbmhp4buBdSBraW0gY8awxqFuZyB0aHXhu5ljIG3DoHUgIkciIG5o4bqldCB0cm9uZyBi4buZIGThu68gbGnhu4d1Lg0KICAtIE7hur91IGPhu5l0IG3DoHUgIkoiIHRo4bqlcCBoxqFuIGPDoWMgY+G7mXQga2jDoWMsIG5naMSpYSBsw6AgY8OzIMOtdCBraW0gY8awxqFuZyB0aHXhu5ljIG3DoHUgIkoiIGjGoW4gc28gduG7m2kgY8OhYyBtw6B1IGtow6FjLiANCiAgDQojIyMgKirEkOG7kyB0aOG7iyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGJp4bq/biBjdXQqKg0KDQpgYGB7cn0NCmEgPC0gZGlhbW9uZHMNCnRhYmxlKGRpYW1vbmRzJGN1dCkNCmEgJT4lIGdncGxvdChhZXMoeD0gY3V0KSkgKyANCiAgICAgIGdlb21fYmFyKCApKw0KICAgICAgbGFicyh4ID0gJ0No4bqldCBsxrDhu6NuZycsIHk9ICcgU+G7kSBsxrDhu6NuZycpDQoNCmBgYA0KXA0KLSBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGh14buZYyB04burbmcgY+G6pXAgxJHhu5kgY2jhuqV0IGzGsOG7o25nIGtow6FjIG5oYXUgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcy4NCiAgLSBUcuG7pWMgeCB0aOG7gyBoaeG7h24gY8OhYyBj4bqlcCDEkeG7mSBjaOG6pXQgbMaw4bujbmcga2ltIGPGsMahbmcsIHThu6sgdGjhuqVwIMSR4bq/biBjYW8gKHThu6sgIkZhaXIiIMSR4bq/biAiSWRlYWwiKS4NCiAgLSBUcuG7pWMgeSB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0xrDGoW5nIOG7qW5nIHbhu5tpIG3hu5dpIGPhuqVwIMSR4buZIGNo4bqldCBsxrDhu6NuZy4NCiAgLSBDaGnhu4F1IGNhbyBj4bunYSBt4buXaSBj4buZdCB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aHXhu5ljIGPhuqVwIMSR4buZIGNo4bqldCBsxrDhu6NuZyDEkcOzLg0KLSBWw60gZOG7pToNCg0KICAtIE7hur91IGPhu5l0ICJJZGVhbCIgY2FvIG5o4bqldCwgbmdoxKlhIGzDoCBjw7Mgbmhp4buBdSBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nICJJZGVhbCIgbmjhuqV0IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UuDQogIC0gTuG6v3UgY+G7mXQgIlZlcnkgR29vZCIgdGjhuqVwIGjGoW4gY8OhYyBj4buZdCBQcmVtaXVtIHbDoCBJZGVhbCwgbmdoxKlhIGzDoCBjw7Mgw610IGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgIlZlcnkgR29vZCIgaMahbiBzbyB24bubaSBjw6FjIGPhuqVwIMSR4buZIFByZW1pdW0gdsOgIElkZWFsLiANCiANCiMjIyAqKsSQ4buTIHRo4buLIHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gYmnhur9uIGNsYXJpdHkqKiANCg0KYGBge3J9DQphIDwtIGRpYW1vbmRzDQp0YWJsZShkaWFtb25kcyRjbGFyaXR5KQ0KYSAlPiUgZ2dwbG90KGFlcyh4PSBjbGFyaXR5KSkgKyANCiAgICAgIGdlb21fYmFyKCApKw0KICAgICAgbGFicyh4ID0gJ8SQ4buZIHRyb25nIHN14buRdCcsIHk9ICcgU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KLSBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGh14buZYyB04burbmcgY+G6pXAgxJHhu5kgxJHhu5kgdHJvbmcgc3Xhu5F0IGtow6FjIG5oYXUgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcy4NCiAgLSBUcuG7pWMgeCB0aOG7gyBoaeG7h24gY8OhYyBj4bqlcCDEkeG7mSDEkeG7mSB0cm9uZyBzdeG7kXQga2ltIGPGsMahbmcsIHThu6sgdGjhuqVwIMSR4bq/biBjYW8gKHThu6sgIkkxIiDEkeG6v24gIklGIikuDQogIC0gVHLhu6VjIHkgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdMawxqFuZyDhu6luZyB24bubaSBt4buXaSBj4bqlcCDEkeG7mSDEkeG7mSB0cm9uZyBzdeG7kXQuDQogIC0gQ2hp4buBdSBjYW8gY+G7p2EgbeG7l2kgY+G7mXQgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGh14buZYyBj4bqlcCDEkeG7mSDEkeG7mSB0cm9uZyBzdeG7kXQgxJHDsy4NCi0gVsOtIGThu6U6DQoNCiAgLSBO4bq/dSBj4buZdCAiU0kxIiBjYW8gbmjhuqV0LCBuZ2jEqWEgbMOgIGPDsyBuaGnhu4F1IGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgIlNJMSIgbmjhuqV0IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UuDQogIC0gTuG6v3UgY+G7mXQgIkkxIiB0aOG6pXAgbmjhuqV0LCBuZ2jEqWEga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCAiSTEiIGNoaeG6v20gc+G7kSBsxrDhu6NuZyDDrXQgbmjhuqV0IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UuIA0KDQojIyAqQmnhu4N1IMSR4buTIGPhu5l0IHbhu5tpIGNow7ogdGjDrWNoIHPhu5EgbMaw4bujbmcgdGhlbyB04burbmcgYmnhur9uOiBjdXQsIGNvbG9yLCBjbGFyaXR5KiANCg0KIyMjICoqQmnhu4N1IMSR4buTIHRoYW5oIHbhu5tpIGNow7ogdGjDrWNoIHPhu5EgbMaw4bujbmcgdGhlbyBtw6B1IHPhuq9jIGtpbSBjxrDGoW5nKCBiaeG6v24gY29sb3IpKioNCg0KDQoNCg0KYGBge3J9DQphIDwtIGRpYW1vbmRzDQphICU+JSBncm91cF9ieShjb2xvcikgJT4lIHN1bW1hcmlzZShrPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGNvbG9yLGspKSArDQogICAgZ2VvbV9jb2woZmlsbD0nc2t5Ymx1ZScpICsgDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGspLHZqdXN0ID0gMiwgY29sb3IgPSAnYmxhY2snKSArDQogICAgbGFicyh4ID0gJ03DoHUnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIG7DoHkgdGnhur9wIHThu6VjIHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRodeG7mWMgdOG7q25nIG5ow7NtIG3DoHUga2jDoWMgbmhhdSB0cm9uZyBi4buZIGThu68gbGnhu4d1IGRpYW1vbmRzLCB0xrDGoW5nIHThu7EgbmjGsCBiaeG7g3UgxJHhu5MgdHLGsOG7m2MuIA0KDQotIMSQaeG7g20ga2jDoWMgYmnhu4d0Og0KICAtIEJp4buDdSDEkeG7kyBuw6B5IHPhu60gZOG7pW5nIGPDoWMgY+G7mXQgaMOsbmggY2jhu68gbmjhuq10IChnZW9tX2NvbCkgdGhheSB2w6wgY8OhYyB0aGFuaCAgICAgICAgKGdlb21fYmFyKS4NCiAgLSBCaeG7g3UgxJHhu5MgbsOgeSB0aMOqbSBjw6FjIGNow7ogdGjDrWNoIChnZW9tX3RleHQpIGhp4buDbiB0aOG7iyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nICAgICAgICAoYmnhur9uIGspIHTGsMahbmcg4bupbmcgduG7m2kgbeG7l2kgbcOgdS4NCi0gQ8OhYyB0aMOgbmggcGjhuqduIGPhu6dhIGNvZGU6DQoNCiAgLSBncm91cF9ieShjb2xvcik6IE5ow7NtIGThu68gbGnhu4d1IHRoZW8gbcOgdSBz4bqvYy4NCiAgLSBzdW1tYXJpc2Uoaz0gbigpKTogVMOtbmggdOG7lW5nIHPhu5Ega2ltIGPGsMahbmcgKG4oKSkgY2hvIG3hu5dpIG5ow7NtIG3DoHUsIGzGsHUgdHLhu68gICAgIHRyb25nIGJp4bq/biBrLg0KICAtIGFlcyhjb2xvcixrKTogw6FuaCB44bqhIHRy4bulYyB4IGNobyBtw6B1IHPhuq9jIChjb2xvcikgdsOgIHRy4bulYyB5IGNobyBz4buRIGzGsOG7o25nICAgICAgICAoaykuDQogIC0gZ2VvbV9jb2woZmlsbD0nc2t5Ymx1ZScpOiBW4bq9IGPDoWMgY+G7mXQgbcOgdSB4YW5oIGRhIHRy4budaSAoc2t5Ymx1ZSkuDQogIC0gZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGspLCB2anVzdCA9IDIsIGNvbG9yID0gJ2JsYWNrJyk6IFRow6ptIGNow7ogdGjDrWNoIGhp4buDbiAgICAgdGjhu4sgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gayAoc+G7kSBsxrDhu6NuZykgdOG6oWkgduG7iyB0csOtIHRyw6puIGPDuW5nIG3hu5dpIGPhu5l0ICh2anVzdD0yKSwgICAgIG3DoHUgxJFlbiAoYmxhY2spLg0KICAtIFNvIHbhu5tpIGJp4buDdSDEkeG7kyBiYW4gxJHhuqd1IChhICU+JSBnZ3Bsb3QoYWVzKHg9IGNvbG9yKSkgKyBnZW9tX2JhciggKSArIGxhYnMoeCAgICAgPSAnTcOgdScsIHk9ICcgU+G7kSBsxrDhu6NuZycpKSwNCg0KICAgIC0gQmnhu4N1IMSR4buTIG7DoHkgdHLhu7FjIHF1YW4gaMahbiBkbyBoaeG7g24gdGjhu4sgY2jDrW5oIHjDoWMgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBjaG8gICAgICAgIG3hu5dpIG3DoHUgc+G6r2MuDQogICAgLSBN4bq3YyBkw7kgY+G6oyBoYWkgxJHhu4F1IHPhu60gZOG7pW5nIGPDoWMgY+G7mXQgxJHhu4MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcsIHZp4buHYyB0aMOqbSBjaMO6ICAgICAgICAgdGjDrWNoIHPhu5EgbMaw4bujbmcgZ2nDunAgbmfGsOG7nWkgeGVtIGThu4UgZMOgbmcgbuG6r20gYuG6r3QgdGjDtG5nIHRpbiBtw6Aga2jDtG5nIGPhuqduIMaw4bubYyAgICAgIGzGsOG7o25nIGNoaeG7gXUgY2FvIGPhu6dhIGPDoWMgY+G7mXQuDQotIFbDrSBk4bulOiBLaGkgcXVhbiBzw6F0IGJp4buDdSDEkeG7kyB0YSB0aOG6pXkNCiAgLSBD4buZdCBtw6B1ICJHIiBjYW8gbmjhuqV0IHbDoCBHIGPDsyBz4buRIGzGsOG7o25nIDExMjkyIHZpw6puIGtpbSBjxrDGoW5nLCBuZ2jEqWEgbMOgIGPDsyBuaGnhu4F1IGtpbSBjxrDGoW5nIHRodeG7mWMgbcOgdSAiRyIgbmjhuqV0IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UuDQogIC0gVMawxqFuZyB04buxLCBj4buZdCBtw6B1ICJKIiB0aOG6pXAgbmjhuqV0IHbDoCBjw7Mgc+G7kSBsxrDhu6NuZyB2acOqbiBraW0gY8awxqFuZyBsw6AgMjgwOCB2acOqbiwgbmdoxKlhIGzDoCBjw7Mgw610IGtpbSBjxrDGoW5nIHRodeG7mWMgbcOgdSAiSiIgbmjhuqV0IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UuIA0KICANCiMjIyAqKkJp4buDdSDEkeG7kyB0aGFuaCB24bubaSBjaMO6IHRow61jaCBz4buRIGzGsOG7o25nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90KCBiaeG6v24gY3V0KSoqDQoNCg0KYGBge3J9DQphIDwtIGRpYW1vbmRzDQphICU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2Uoaz0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyhjdXQsaykpICsNCiAgICBnZW9tX2NvbChmaWxsPSdza3libHVlJykgKyANCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gayksdmp1c3QgPSAyLCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnQ2jhuqV0IGzGsOG7o25nIGPhuq90JywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQotIEJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRodeG7mWMgdOG7q25nIGPhuqVwIMSR4buZIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBraMOhYyBuaGF1IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMuDQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgY+G6pXAgxJHhu5kgY2jhuqV0IGzGsOG7o25nIGPhuq90IGtpbSBjxrDGoW5nIChjdXQpLCB04burICJGYWlyIiAgICAgICAgIChrw6ltKSDEkeG6v24gIklkZWFsIiAoaG/DoG4gaOG6o28pLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyAoaykgdMawxqFuZyDhu6luZyB24bubaSBt4buXaSBj4bqlcCDEkeG7mSBjaOG6pXQgICAgICAgICBsxrDhu6NuZyBj4bqvdC4NCiAgLSBDw6FjIGPhu5l0IG3DoHUgeGFuaCBuaOG6oXQgKCJza3libHVlIik6IENoaeG7gXUgY2FvIGPhu6dhIG3hu5dpIGPhu5l0IGJp4buDdSB0aOG7iyB04bu3IGzhu4cgc+G7kSAgICAgbMaw4bujbmcga2ltIGPGsMahbmcgdGh14buZYyBt4buZdCBj4bqlcCDEkeG7mSBjaOG6pXQgbMaw4bujbmcgY+G6r3QgbmjhuqV0IMSR4buLbmguDQogIC0gQ2jDuiB0aMOtY2ggdsSDbiBi4bqjbiBtw6B1IMSRZW4gKCJibGFjayIpOiBIaeG7g24gdGjhu4sgY2jDrW5oIHjDoWMgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyAgICAgY2hvIG3hu5dpIGPhuqVwIMSR4buZIGNo4bqldCBsxrDhu6NuZyBj4bqvdCwgbuG6sW0gdHLDqm4gxJHhu4luaCBj4buZdCB0xrDGoW5nIOG7qW5nLg0KICAtIFNvIHbhu5tpIGJp4buDdSDEkeG7kyBiYW4gxJHhuqd1IChhICU+JSBnZ3Bsb3QoYWVzKHg9IGN1dCkpICsgZ2VvbV9iYXIoICkgKyBsYWJzKHggPSAgICAgJ0No4bqldCBsxrDhu6NuZycsIHk9ICcgU+G7kSBsxrDhu6NuZycpKSwNCg0KICAgIC0gQmnhu4N1IMSR4buTIG7DoHkgY3VuZyBj4bqlcCB0aMOqbSB0aMO0bmcgdGluIGNoaSB0aeG6v3QgduG7gSBz4buRIGzGsOG7o25nIGNow61uaCB4w6FjIGtpbSAgICAgICAgY8awxqFuZyDhu58gbeG7l2kgY+G6pXAgxJHhu5kuDQogICAgLSBN4bq3YyBkw7kgY+G6oyBoYWkgxJHhu4F1IHPhu60gZOG7pW5nIGPDoWMgY+G7mXQgxJHhu4MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcsIHZp4buHYyB0aMOqbSBjaMO6ICAgICAgICAgdGjDrWNoIHPhu5EgbMaw4bujbmcgZ2nDunAgbmfGsOG7nWkgeGVtIGThu4UgZMOgbmcgbuG6r20gYuG6r3QgdGjDtG5nIHRpbiBtw6Aga2jDtG5nIGPhuqduIMaw4bubYyAgICAgIGzGsOG7o25nIGNoaeG7gXUgY2FvIGPhu6dhIGPDoWMgY+G7mXQuDQotIFZEOiBRdWFuIHPDoXQgYmnhu4N1IMSR4buTIHRyw6puIHRhIHRo4bqleSDEkcaw4bujYw0KICAtIFPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgbmhp4buBdSBuaOG6pXQgdMawxqFuZyDhu6luZyB24bubaSBj4bqlcCDEkeG7mSBjaOG6pXQgbMaw4bujbmcgY+G6r3QgIiBJZGVhbCIgbMOgIDIxNTUxIHZpw6puIHbDoCBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIMOtdCBuaOG6pXQgdMawxqFuZyDhu6luZyB24bubaSBj4bqlcCDEkeG7mSBjaOG6pXQgbMaw4bujbmcgY+G6r3QgIkZhaXIiIGzDoCAxNjEwIHZpw6puLiANCg0KIyMjICoqQmnhu4N1IMSR4buTIHRoYW5oIHbhu5tpIGNow7ogdGjDrWNoIHPhu5EgbMaw4bujbmcgdGhlbyDEkeG7mSB0cm9uZyBzdeG7kXQgKCBiaeG6v24gY2xhcml0eSkqKg0KDQoNCmBgYHtyfQ0KYSA8LSBkaWFtb25kcw0KYSAlPiUgZ3JvdXBfYnkoY2xhcml0eSkgJT4lIHN1bW1hcmlzZShrPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGNsYXJpdHksaykpICsNCiAgICBnZW9tX2NvbChmaWxsPSdza3libHVlJykgKyANCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gayksdmp1c3QgPSAyLCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnxJDhu5kgdHJvbmcgc3Xhu5F0JywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQotIEJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRodeG7mWMgdOG7q25nIGPhuqVwIMSR4buZIMSR4buZIHRyb25nIHN14buRdCBraMOhYyBuaGF1IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMuDQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgY+G6pXAgxJHhu5kgxJHhu5kgdHJvbmcgc3Xhu5F0IGtpbSBjxrDGoW5nIChjbGFyaXR5KSwgdOG7qyAiSTEiICAgICAgICAoa8OpbSB0cm9uZykgxJHhur9uICJJRiIgKGhvw6BuIGjhuqNvIGtow7RuZyB0w6wgduG6v3QpLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyAoaykgdMawxqFuZyDhu6luZyB24bubaSBt4buXaSBj4bqlcCDEkeG7mSDEkeG7mSB0cm9uZyAgICAgc3Xhu5F0Lg0KICAtIEPDoWMgY+G7mXQgbcOgdSB4YW5oIG5o4bqhdCAoInNreWJsdWUiKTogQ2hp4buBdSBjYW8gY+G7p2EgbeG7l2kgY+G7mXQgYmnhu4N1IHRo4buLIHThu7cgbOG7hyBz4buRICAgICBsxrDhu6NuZyBraW0gY8awxqFuZyB0aHXhu5ljIG3hu5l0IGPhuqVwIMSR4buZIMSR4buZIHRyb25nIHN14buRdCBuaOG6pXQgxJHhu4tuaC4NCiAgLSBDaMO6IHRow61jaCB2xINuIGLhuqNuIG3DoHUgxJFlbiAoImJsYWNrIik6IEhp4buDbiB0aOG7iyBjaMOtbmggeMOhYyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nICAgICBjaG8gbeG7l2kgY+G6pXAgxJHhu5kgxJHhu5kgdHJvbmcgc3Xhu5F0LCBu4bqxbSB0csOqbiDEkeG7iW5oIGPhu5l0IHTGsMahbmcg4bupbmcuDQogIC0gU28gduG7m2kgYmnhu4N1IMSR4buTIGJhbiDEkeG6p3UgKGEgJT4lIGdncGxvdChhZXMoeD0gY2xhcml0eSkpICsgZ2VvbV9iYXIoICkgKyAgICAgICAgIGxhYnMoeCA9ICfEkOG7mSB0cm9uZyBzdeG7kXQnLCB5PSAnIFPhu5EgbMaw4bujbmcnKSksDQoNCiAgICAtIEJp4buDdSDEkeG7kyBuw6B5IGN1bmcgY+G6pXAgdGjDqm0gdGjDtG5nIHRpbiBjaGkgdGnhur90IHbhu4Egc+G7kSBsxrDhu6NuZyBjaMOtbmggeMOhYyBraW0gICAgICAgIGPGsMahbmcg4bufIG3hu5dpIGPhuqVwIMSR4buZLg0KICAgIC0gTeG6t2MgZMO5IGPhuqMgaGFpIMSR4buBdSBz4butIGThu6VuZyBjw6FjIGPhu5l0IMSR4buDIHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nLCB2aeG7h2MgdGjDqm0gY2jDuiAgICAgICAgIHRow61jaCBz4buRIGzGsOG7o25nIGdpw7pwIG5nxrDhu51pIHhlbSBk4buFIGTDoG5nIG7huq9tIGLhuq90IHRow7RuZyB0aW4gbcOgIGtow7RuZyBj4bqnbiDGsOG7m2MgICAgICBsxrDhu6NuZyBjaGnhu4F1IGNhbyBj4bunYSBjw6FjIGPhu5l0LiANCi0gVkQ6IFF1YW4gc8OhdCBiaeG7g3UgxJHhu5MgdHLDqm4gdGEgdGjhuqV5IMSRxrDhu6NjDQogIC0gxJDhu5kgdHJvbmcgc3Xhu5F0IGxv4bqhaSAiU0kxIiBjaGnhur9tIHPhu5EgbMaw4bujbmcgbOG7m24gbmjhuqV0LSAxMzA2NSB2acOqbiB2w6AgY2hp4bq/bSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIMOtdCBuaOG6pXQgdHJvbmcgYuG7mSBk4buvIGxp4buHdSB0xrDGoW5nIOG7qW5nIHbhu5tpIMSR4buZIHRyb25nIHN14buRdCBsb+G6oWkgIkkxIiANCiAgDQojIyAqQmnhu4N1IMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiBnacOhIHRy4buLIHRydW5nIGLDrG5oIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyBjw6FjIGJp4bq/bjogY3V0LCBjb2xvciwgY2xhcml0eSogDQoNCiMjIyAqKkJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRoZW8gbcOgdSBz4bqvYyBraW0gY8awxqFuZyoqIA0KDQoNCmBgYHtyfQ0KYSA8LSBkaWFtb25kcw0KYSAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2Uoaz0gbWVhbihjYXJhdCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGNvbG9yLGspKSArDQogICAgZ2VvbV9jb2woZmlsbD0nc2t5Ymx1ZScpICsgDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKGssMikpLHZqdXN0ID0gMSwgY29sb3IgPSAnYmxhY2snKSArDQogICAgbGFicyh4ID0gJ03DoHUnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIG7DoHkgdGjhu4MgaGnhu4duIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBj4bunYSBraW0gY8awxqFuZyB0aHXhu5ljIHThu6tuZyBtw6B1IHPhuq9jIGtow6FjIG5oYXUgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcy4NCg0KICAtIFRy4bulYyB4OiBUaOG7gyBoaeG7h24gY8OhYyBtw6B1IHPhuq9jIGPhu6dhIGtpbSBjxrDGoW5nLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IChrKSDEkcaw4bujYyBsw6BtIHRyw7JuICAgICDEkeG6v24gMiBjaOG7ryBz4buRIHRo4bqtcCBwaMOibiAocm91bmQoaywgMikpIGPhu6dhIGtpbSBjxrDGoW5nIHRodeG7mWMgbeG7l2kgbcOgdSBz4bqvYy4NCiAgLSBDw6FjIGPhu5l0IG3DoHUgeGFuaCBuaOG6oXQgKCJza3libHVlIik6IENoaeG7gXUgY2FvIGPhu6dhIG3hu5dpIGPhu5l0IGJp4buDdSB0aOG7iyBnacOhIHRy4buLICAgdHJ1bmcgYsOsbmggdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBj4bunYSBraW0gY8awxqFuZyBjw7MgbcOgdSBz4bqvYyB0xrDGoW5nIOG7qW5nLg0KICAtIENow7ogdGjDrWNoIHbEg24gYuG6o24gbcOgdSDEkWVuICgiYmxhY2siKTogSGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY2jDrW5oIHjDoWMgICAgKCDEkcaw4bujYyBsw6BtIHRyw7JuKSBu4bqxbSB0csOqbiDEkeG7iW5oIG3hu5dpIGPhu5l0Lg0KLSBWRDoNCiAgVGEgdGjhuqV5IGPhu5l0IGPDsyBtw6B1ICJKIiBjYW8gbmjhuqV0IHRyb25nIGJp4buDdSDEkeG7ky4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIGtpbSBjxrDGoW5nIG3DoHUgIkoiIGPDsyBnacOhIHRy4buLIHRydW5nIGLDrG5oIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgY2FvIG5o4bqldCB0cm9uZyBz4buRIGPDoWMgbcOgdSBz4bqvYyBjw7MgdHJvbmcgYuG7mSBk4buvIGxp4buHdS4gVsOtIGThu6UsIGNow7ogdGjDrWNoIHRyw6puIGPhu5l0IG3DoHUgIkoiIGPDsyB0aOG7gyBoaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyAxLjE2IGNhcmF0LCBjaG8gYmnhur90IGtpbSBjxrDGoW5nICJKIiB0cnVuZyBiw6xuaCBjw7MgdHLhu41uZyBsxrDhu6NuZyAxLjE2IGNhcmF0LiANCiAgDQpgYGB7cn0NCg0KDQpgYGANCg0KIA0KIyMjICoqQmnhu4N1IMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiBnacOhIHRy4buLIHRydW5nIGLDrG5oIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3Qga2ltIGPGsMahbmcqKg0KDQoNCmBgYHtyfQ0KYSA8LSBkaWFtb25kcw0KYSAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKGs9IG1lYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyhjdXQsaykpICsNCiAgICBnZW9tX2NvbChmaWxsPSdza3libHVlJykgKyANCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQoaywyKSksdmp1c3QgPSAxLCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnQ2jhuqV0IGzGsOG7o25nIGPhuq90JywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQotIEJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyB04burbmcgY2jhuqV0IGzGsOG7o25nIGPhuq90IGPhu6dhIGtpbSBjxrDGoW5nIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMuDQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgY2jhuqV0IGzGsOG7o25nIGPhuq90IGtow6FjIG5oYXUgY+G7p2Ega2ltIGPGsMahbmcsIHThu6sgIlBvb3IiICAgICAgICAoa8OpbSkgxJHhur9uICJJZGVhbCIgKGhvw6BuIGjhuqNvKS4NCiAgLSBUcuG7pWMgeTogVGjhu4MgaGnhu4duIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggKGspIHRy4buNbmcgbMaw4bujbmcgY2FyYXQsIMSRxrDhu6NjIGzDoG0gdHLDsm4gICAgICDEkeG6v24gMiBjaOG7ryBz4buRIHRo4bqtcCBwaMOibiAocm91bmQoaywgMikpLCBj4bunYSBraW0gY8awxqFuZyB0aHXhu5ljIG3hu5dpIGNo4bqldCBsxrDhu6NuZyAgICAgIGPhuq90Lg0KICAtIEPDoWMgY+G7mXQgbcOgdSB4YW5oIG5o4bqhdCAoInNreWJsdWUiKTogQ2hp4buBdSBjYW8gY+G7p2EgbeG7l2kgY+G7mXQgdOG7tyBs4buHIHRodeG6rW4gduG7m2kgICAgICBnacOhIHRy4buLIHRydW5nIGLDrG5oIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgY+G7p2Ega2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBj4bqvdCB0xrDGoW5nICAgICDhu6luZy4NCiAgLSBDaMO6IHRow61jaCB2xINuIGLhuqNuIG3DoHUgxJFlbiAoImJsYWNrIik6IEhp4buDbiB0aOG7iyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGNow61uaCB4w6FjICAgICAoxJHGsOG7o2MgbMOgbSB0csOybikgbuG6sW0gdHLDqm4gxJHhu4luaCBt4buXaSBj4buZdC4NCi0gVsOtIGThu6UgY+G7pSB0aOG7gzoNCg0KICAtIFRhIHRo4bqleSBj4buZdCAiRmFpciIgdMawxqFuZyDhu6luZyB24bubaSBnacOhIHRy4buLIHRydW5nIGLDrG5oIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgbMOgICAgICAgMS4wNSwgbMOgIGPhu5l0IGNhbyBuaOG6pXQgdHJvbmcgYmnhu4N1IMSR4buTLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6Aga2ltIGPGsMahbmcgY8OzICAgICAgICBjaOG6pXQgbMaw4bujbmcgY+G6r3QgIkZhaXIiIGPDsyBnacOhIHRy4buLIHRydW5nIGLDrG5oIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgY2FvIG5o4bqldCAgICAgICAgdHJvbmcgc+G7kSBjw6FjIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjw7MgdHJvbmcgYuG7mSBk4buvIGxp4buHdS4gDQoNCiMjIyAqKkJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0IGPhu6dhIGtpbSBjxrDGoW5nKioNCg0KYGBge3J9DQphIDwtIGRpYW1vbmRzDQphICU+JSBncm91cF9ieShjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKGs9IG1lYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyhjbGFyaXR5LGspKSArDQogICAgZ2VvbV9jb2woZmlsbD0nc2t5Ymx1ZScpICsgDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKGssMikpLHZqdXN0ID0gMSwgY29sb3IgPSAnYmxhY2snKSArDQogICAgbGFicyh4ID0gJ03DoHUnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIG7DoHkgdGjhu4MgaGnhu4duIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0aGVvIHThu6tuZyDEkeG7mSB0cm9uZyBzdeG7kXQgY+G7p2Ega2ltIGPGsMahbmcgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcy4NCg0KICAtIFRy4bulYyB4OiBUaOG7gyBoaeG7h24gY8OhYyDEkeG7mSB0cm9uZyBzdeG7kXQga2jDoWMgbmhhdSBj4bunYSBraW0gY8awxqFuZywgdOG7qyAiSTEiIChrw6ltICAgIHRyb25nKSDEkeG6v24gIklGIiAoaG/DoG4gaOG6o28ga2jDtG5nIHTDrCB24bq/dCkuDQogIC0gVHLhu6VjIHk6IFRo4buDIGhp4buHbiBnacOhIHRy4buLIHRydW5nIGLDrG5oIChrKSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0LCDEkcaw4bujYyBsw6BtIHRyw7JuICAgIMSR4bq/biAyIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuIChyb3VuZChrLCAyKSksIGPhu6dhIGtpbSBjxrDGoW5nIHRodeG7mWMgbeG7l2kgxJHhu5kgdHJvbmcgc3Xhu5F0Lg0KICAtIEPDoWMgY+G7mXQgbcOgdSB4YW5oIG5o4bqhdCAoInNreWJsdWUiKTogQ2hp4buBdSBjYW8gY+G7p2EgbeG7l2kgY+G7mXQgdOG7tyBs4buHIHRodeG6rW4gduG7m2kgICAgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgdMawxqFuZyAgICAg4bupbmcuDQogIC0gQ2jDuiB0aMOtY2ggdsSDbiBi4bqjbiBtw6B1IMSRZW4gKCJibGFjayIpOiBIaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBjaMOtbmggeMOhYyAgICAoxJHGsOG7o2MgbMOgbSB0csOybikgbuG6sW0gdHLDqm4gxJHhu4luaCBt4buXaSBj4buZdC4NCi0gVsOtIGThu6UgY+G7pSB0aOG7gzoNCg0KVGEgdGjhuqV5IGPhu5l0ICJJMSIgY8OzIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBsw6AgMS4yOCwgbMOgIGPhu5l0IGNhbyBuaOG6pXQgdHJvbmcgYmnhu4N1IMSR4buTLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6Aga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCAiSTEiIGPDsyBnacOhIHRy4buLIHRydW5nIGLDrG5oIHLhu41uZyBsxrDhu6NuZyBjYXJhdCBjYW8gbmjhuqV0IHRyb25nIHPhu5EgY8OhYyDEkeG7mSB0cm9uZyBzdeG7kXQgY8OzIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UuDQoNCiMjICpCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggZ2nDoSBiw6FuIHRoZW8gYmnhur9uOiBjdXQsIGNvbG9yIHbDoCBjbGFyaXR5KiANCg0KIyMjICoqQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBnacOhIHRy4buLIHRydW5nIGLDrG5oIGdpw6EgYsOhbiB0aGVvIG3DoHUgc+G6r2Mga2ltIGPGsMahbmcqKg0KDQpgYGB7cn0NCmEgPC0gZGlhbW9uZHMNCmEgJT4lIGdyb3VwX2J5KGNvbG9yKSAlPiUgc3VtbWFyaXNlKGs9IG1lYW4ocHJpY2UpKSAlPiUNCiAgZ2dwbG90KGFlcyhjb2xvcixrKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J3NreWJsdWUnKSArIA0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChrLDIpKSx2anVzdCA9IDEsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICdNw6B1JywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQotIEJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGdpw6EgYsOhbiB0aGVvIHThu6tuZyBtw6B1IHPhuq9jIGPhu6dhIGtpbSBjxrDGoW5nIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMuDQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgbcOgdSBz4bqvYyBraMOhYyBuaGF1IGPhu6dhIGtpbSBjxrDGoW5nLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCAoaykgZ2nDoSBiw6FuLCDEkcaw4bujYyBsw6BtIHRyw7JuIMSR4bq/biAyIGNo4buvICAgIHPhu5EgdGjhuq1wIHBow6JuIChyb3VuZChrLCAyKSksIGPhu6dhIGtpbSBjxrDGoW5nIHRodeG7mWMgbeG7l2kgbcOgdSBz4bqvYy4NCiAgLSBD4buZdCBtw6B1IHhhbmggbmjhuqF0ICgic2t5Ymx1ZSIpOiBDaGnhu4F1IGNhbyBj4bunYSBt4buXaSBj4buZdCB04bu3IGzhu4cgdGh14bqtbiB24bubaSBnacOhICAgIHRy4buLIHRydW5nIGLDrG5oIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZyBjw7MgbcOgdSBz4bqvYyB0xrDGoW5nIOG7qW5nLg0KICAtIENow7ogdGjDrWNoIHbEg24gYuG6o24gbcOgdSDEkWVuICgiYmxhY2siKTogSGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY2jDrW5oIHjDoWMgICjEkcaw4bujYyBsw6BtIHRyw7JuKSBu4bqxbSB0csOqbiDEkeG7iW5oIG3hu5dpIGPhu5l0Lg0KLSBWw60gZOG7pSBj4bulIHRo4buDOg0KDQogIC0gTcOgdSBKIGNhbyBuaOG6pXQgdHJvbmcgYmnhu4N1IMSR4buTLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6Aga2ltIGPGsMahbmcgbcOgdSBKIGPDsyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGdpw6EgYsOhbiBjYW8gbmjhuqV0IHRyb25nIHPhu5EgY8OhYyBtw6B1IHPhuq9jLiBWw60gZOG7pSwgY2jDuiB0aMOtY2ggdHLDqm4gY+G7mXQgbcOgdSBKIGPDsyB0aOG7gyBoaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyA1MzIzLDgyIFVTRCwgY2hvIGJp4bq/dCBraW0gY8awxqFuZyBtw6B1IEogdHJ1bmcgYsOsbmggY8OzIGdpw6EgYsOhbiA1MzIzLDgyIFVTRC4NCg0KICAtIE3DoHUgRSB0aOG6pXAgbmjhuqV0IHRyb25nIGJp4buDdSDEkeG7ky4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIGtpbSBjxrDGoW5nIG3DoHUgRSBjw7MgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBnacOhIGLDoW4gdGjhuqVwIG5o4bqldCB0cm9uZyBz4buRIGPDoWMgbcOgdSBz4bqvYy4gVsOtIGThu6UsIGNow7ogdGjDrWNoIHRyw6puIGPhu5l0IG3DoHUgTSBjw7MgdGjhu4MgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgMzA3Niw3NSBVU0QsIGNobyBiaeG6v3Qga2ltIGPGsMahbmcgbcOgdSBNIHRydW5nIGLDrG5oIGPDsyBnacOhIGLDoW4gMzA3Niw3NSBVU0QuDQoNCiMjIyAqKkJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBnacOhIGLDoW4gdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QqKg0KDQoNCmBgYHtyfQ0KYSA8LSBkaWFtb25kcw0KYSAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKGs9IG1lYW4ocHJpY2UpKSAlPiUNCiAgZ2dwbG90KGFlcyhjdXQsaykpICsNCiAgICBnZW9tX2NvbChmaWxsPSdza3libHVlJykgKyANCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQoaywyKSksdmp1c3QgPSAxLCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnQ2jhuqV0IGzGsOG7o25nIGPhuq90JywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQotIEJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGdpw6EgYsOhbiB0aGVvIHThu6tuZyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgY+G7p2Ega2ltIGPGsMahbmcgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcy4NCg0KICAtIFRy4bulYyB4OiBUaOG7gyBoaeG7h24gY8OhYyBjaOG6pXQgbMaw4bujbmcgY+G6r3Qga2jDoWMgbmhhdSBj4bunYSBraW0gY8awxqFuZywgdOG7qyAiUG9vciIgKGvDqW0pIMSR4bq/biAiSWRlYWwiIChob8OgbiBo4bqjbykuDQogIC0gVHLhu6VjIHk6IFRo4buDIGhp4buHbiBnacOhIHRy4buLIHRydW5nIGLDrG5oIChrKSBnacOhIGLDoW4sIMSRxrDhu6NjIGzDoG0gdHLDsm4gxJHhur9uIDIgY2jhu68gc+G7kSB0aOG6rXAgcGjDom4gKHJvdW5kKGssIDIpKSwgY+G7p2Ega2ltIGPGsMahbmcgdGh14buZYyBt4buXaSBjaOG6pXQgbMaw4bujbmcgY+G6r3QuDQogIC0gQ+G7mXQgbcOgdSB4YW5oIG5o4bqhdCAoInNreWJsdWUiKTogQ2hp4buBdSBjYW8gY+G7p2EgbeG7l2kgY+G7mXQgdOG7tyBs4buHIHRodeG6rW4gduG7m2kgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBj4bqvdCB0xrDGoW5nIOG7qW5nLg0KICAtIENow7ogdGjDrWNoIHbEg24gYuG6o24gbcOgdSDEkWVuICgiYmxhY2siKTogSGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY2jDrW5oIHjDoWMgKMSRxrDhu6NjIGzDoG0gdHLDsm4pIG7hurFtIHRyw6puIMSR4buJbmggbeG7l2kgY+G7mXQuDQotIFbDrSBk4bulIGPhu6UgdGjhu4M6DQoNCiAgLSBDaOG6pXQgbMaw4bujbmcgY+G6r3QgIlByZW1pdW0iIGNhbyBuaOG6pXQgdHJvbmcgYmnhu4N1IMSR4buTLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6Aga2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBob8OgbiBo4bqjbyBjw7MgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBnacOhIGLDoW4gY2FvIG5o4bqldCB0cm9uZyBz4buRIGPDoWMgY2jhuqV0IGzGsOG7o25nIGPhuq90LiBWw60gZOG7pSwgY2jDuiB0aMOtY2ggdHLDqm4gY+G7mXQgIlByZW1pdW0iIGPDsyB0aOG7gyBoaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyA0NTg0LDI2IFVTRCwgY2hvIGJp4bq/dCBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIGPhuq90ICJQcmVtaXVtIiB0cnVuZyBiw6xuaCBjw7MgZ2nDoSBiw6FuIDQ1ODQsMjYgVVNELg0KDQogIC0gQ2jhuqV0IGzGsOG7o25nIGPhuq90ICIgSWRlYWwiIHRo4bqlcCBuaOG6pXQgdHJvbmcgYmnhu4N1IMSR4buTLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6Aga2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBj4bqvdCAiSWRlYWwiIGPDsyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGdpw6EgYsOhbiB0aOG6pXAgbmjhuqV0IHRyb25nIHPhu5EgY8OhYyBjaOG6pXQgbMaw4bujbmcgY+G6r3QuIFbDrSBk4bulLCBjaMO6IHRow61jaCB0csOqbiBj4buZdCAiUG9vciIgY8OzIHRo4buDIGhp4buDbiB0aOG7iyBnacOhIHRy4buLIDM0NTcsNTQgVVNELCBjaG8gYmnhur90IGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgY+G6r3Qga8OpbSB0cnVuZyBiw6xuaCBjw7MgZ2nDoSBiw6FuIDM0NTcsNTQgVVNELiANCiAgDQoNCiMjIyAqKkJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBnacOhIGLDoW4gdGhlbyDEkeG7mSB0cm9uZyBzdeG7kXQqKg0KDQpgYGB7cn0NCmEgPC0gZGlhbW9uZHMNCmEgJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2Uoaz0gbWVhbihwcmljZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKGNsYXJpdHksaykpICsNCiAgICBnZW9tX2NvbChmaWxsPSdza3libHVlJykgKyANCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQoaywyKSksdmp1c3QgPSAxLCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnxJDhu5kgdHJvbmcgc3Xhu5F0JywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQotIEJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGdpw6EgYsOhbiB0aGVvIHThu6tuZyDEkeG7mSB0cm9uZyBzdeG7kXQgY+G7p2Ega2ltIGPGsMahbmcgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcy4NCg0KICAtIFRy4bulYyB4OiBUaOG7gyBoaeG7h24gY8OhYyDEkeG7mSB0cm9uZyBzdeG7kXQga2jDoWMgbmhhdSBj4bunYSBraW0gY8awxqFuZywgdOG7qyAiSTEiIChrw6ltIHRyb25nKSDEkeG6v24gIklGIiAoaG/DoG4gaOG6o28ga2jDtG5nIHTDrCB24bq/dCkuDQogIC0gVHLhu6VjIHk6IFRo4buDIGhp4buHbiBnacOhIHRy4buLIHRydW5nIGLDrG5oIChrKSBnacOhIGLDoW4sIMSRxrDhu6NjIGzDoG0gdHLDsm4gxJHhur9uIDIgY2jhu68gc+G7kSB0aOG6rXAgcGjDom4gKHJvdW5kKGssIDIpKSwgY+G7p2Ega2ltIGPGsMahbmcgdGh14buZYyBt4buXaSDEkeG7mSB0cm9uZyBzdeG7kXQuDQogIC0gQ+G7mXQgbcOgdSB4YW5oIG5o4bqhdCAoInNreWJsdWUiKTogQ2hp4buBdSBjYW8gY+G7p2EgbeG7l2kgY+G7mXQgdOG7tyBs4buHIHRodeG6rW4gduG7m2kgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCB0xrDGoW5nIOG7qW5nLg0KICAtIENow7ogdGjDrWNoIHbEg24gYuG6o24gbcOgdSDEkWVuICgiYmxhY2siKTogSGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY2jDrW5oIHjDoWMgKMSRxrDhu6NjIGzDoG0gdHLDsm4pIG7hurFtIHRyw6puIMSR4buJbmggbeG7l2kgY+G7mXQuDQotIFbDrSBk4bulIGPhu6UgdGjhu4M6DQoNCiAgLSDEkOG7mSB0cm9uZyBzdeG7kXQgIlNJMiIgY2FvIG5o4bqldCB0cm9uZyBiaeG7g3UgxJHhu5MuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0ICJTSTIiIGPDsyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGdpw6EgYsOhbiBjYW8gbmjhuqV0IHRyb25nIHPhu5EgY8OhYyDEkeG7mSB0cm9uZyBzdeG7kXQuIFbDrSBk4bulLCBjaMO6IHRow61jaCB0csOqbiBj4buZdCAiU0kyIiBjw7MgdGjhu4MgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgNTA2MywwMyBVU0QsIGNobyBiaeG6v3Qga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCAiU0kyIiB0cnVuZyBiw6xuaCBjw7MgZ2nDoSBiw6FuIDUwNjMsMDMgVVNEDQoNCiAgLSDEkOG7mSB0cm9uZyBzdeG7kXQgIldTMSIgdGjhuqVwIG5o4bqldCB0cm9uZyBiaeG7g3UgxJHhu5MuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0ICJXUzEiIGPDsyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGdpw6EgYsOhbiB0aOG6pXAgbmjhuqV0IHRyb25nIHPhu5EgY8OhYyDEkeG7mSB0cm9uZyBzdeG7kXQuIFbDrSBk4bulLCBjaMO6IHRow61jaCB0csOqbiBj4buZdCAiV1MxIiBjw7MgdGjhu4MgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgMjUyMywxMSBVU0QsIGNobyBiaeG6v3Qga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBrw6ltIHRyb25nIHRydW5nIGLDrG5oIGPDsyBnacOhIGLDoW4gMjUyMywxMSBVU0QuIA0KDQojIyAqQmnhu4N1IMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiBwaMawxqFuZyBzYWkgZ2nDoSBiw6FuIHRoZW8gY8OhYyBiaWVuczogY3V0LCBjb2xvciB2w6AgY2xhcml0eS4qDQoNCiMjIyAqKkJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gcGjGsMahbmcgc2FpIGdpw6EgYsOhbiB0aGVvIG3DoHUgc+G6r2Mga2ltIGPGsMahbmcqKg0KDQoNCmBgYHtyfQ0KYSA8LSBkaWFtb25kcw0KYSAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2Uoaz0gdmFyKHByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoY29sb3IsaykpICsNCiAgICBnZW9tX2NvbChmaWxsPSdza3libHVlJykgKyANCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQoaywyKSksdmp1c3QgPSAxLCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KLSBCaeG7g3UgxJHhu5MgbsOgeSB0aOG7gyBoaeG7h24gcGjGsMahbmcgc2FpIGPhu6dhIGdpw6EgYsOhbiB0aGVvIHThu6tuZyBtw6B1IHPhuq9jIGPhu6dhIGtpbSBjxrDGoW5nIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMuIFBoxrDGoW5nIHNhaSBsw6AgbeG7mXQgdGjGsOG7m2MgxJFvIG3hu6ljIMSR4buZIHBow6JuIHTDoW4gY+G7p2EgZOG7ryBsaeG7h3UuDQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgbcOgdSBz4bqvYyBraMOhYyBuaGF1IGPhu6dhIGtpbSBjxrDGoW5nLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gcGjGsMahbmcgc2FpIChrKSBj4bunYSBnacOhIGLDoW4gKMSRxrDhu6NjIGzDoG0gdHLDsm4gxJHhur9uIDIgY2jhu68gc+G7kSB0aOG6rXAgcGjDom4gKHJvdW5kKGssIDIpKSksIGNobyBiaeG6v3QgbeG7qWMgxJHhu5kgdHLhuqNpIHLhu5luZyBj4bunYSBnacOhIGLDoW4NCiAgLSBHacOhIHRy4buLIGNhbyBoxqFuIHRyw6puIHRy4bulYyB5IGNobyBiaeG6v3QgcGjGsMahbmcgc2FpIGNhbyBoxqFuLCBuZ2jEqWEgbMOgIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZyBjw7MgbcOgdSBz4bqvYyDEkcOzIHBow6JuIHTDoW4gcuG7mW5nIGjGoW4geHVuZyBxdWFuaCBnacOhIHRydW5nIGLDrG5oLg0KICAtIEdpw6EgdHLhu4sgdGjhuqVwIGjGoW4gbWVudW5qdWtrYW4gcGjGsMahbmcgc2FpIHRo4bqlcCBoxqFuLCBuZ2jEqWEgbMOgIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZyBjw7MgbcOgdSBz4bqvYyDEkcOzIMOtdCBwaMOibiB0w6FuIGjGoW4geHVuZyBxdWFuaCBnacOhIHRydW5nIGLDrG5oLg0KICAtIEPDoWMgY+G7mXQgbcOgdSB4YW5oIG5o4bqhdCAoInNreWJsdWUiKTogQ2hp4buBdSBjYW8gY+G7p2EgbeG7l2kgY+G7mXQgdOG7tyBs4buHIHRodeG6rW4gduG7m2kgcGjGsMahbmcgc2FpIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZyBjw7MgbcOgdSBz4bqvYyB0xrDGoW5nIOG7qW5nLg0KICAtIENow7ogdGjDrWNoIHbEg24gYuG6o24gbcOgdSDEkWVuICgiYmxhY2siKTogSGnhu4NuIHRo4buLIHBoxrDGoW5nIHNhaSBjaMOtbmggeMOhYyAoxJHGsOG7o2MgbMOgbSB0csOybikgbuG6sW0gdHLDqm4gxJHhu4luaCBt4buXaSBj4buZdC4NCi0gVsOtIGThu6UgY+G7pSB0aOG7gzoNCg0KICAtIE3DoHUgIkkiIGNhbyBuaOG6pXQgdHJvbmcgYmnhu4N1IMSR4buTLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgZ2nDoSBiw6FuIGPhu6dhIGtpbSBjxrDGoW5nIG3DoHUgRCBjw7MgcGjGsMahbmcgc2FpIGNhbyBuaOG6pXQsIGNobyBiaeG6v3QgZ2nDoSBiw6FuIGPhu6dhIGNow7puZyBwaMOibiB0w6FuIHLhu5luZyBuaOG6pXQgeHVuZyBxdWFuaCBnacOhIHRydW5nIGLDrG5oLiBWw60gZOG7pSwgY2jDuiB0aMOtY2ggdHLDqm4gY+G7mXQgbcOgdSBJIGPDsyB0aOG7gyBoaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyAyMjMwMDk0NCw2OCBVU0ReMiwgY2hvIGJp4bq/dCBwaMawxqFuZyBzYWkgZ2nDoSBiw6FuIGPhu6dhIGtpbSBjxrDGoW5nIG3DoHUgSSB0cnVuZyBiw6xuaCBsw6AgMjIzMDA5NDQsNjggVVNEXjIuDQoNCiAgLSBNw6B1IEUgdGjhuqVwIG5o4bqldCB0cm9uZyBiaeG7g3UgxJHhu5MuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcgbcOgdSBFIGPDsyBwaMawxqFuZyBzYWkgdGjhuqVwIG5o4bqldCwgY2hvIGJp4bq/dCBnacOhIGLDoW4gY+G7p2EgY2jDum5nIMOtdCBwaMOibiB0w6FuIG5o4bqldCB4dW5nIHF1YW5oIGdpw6EgdHJ1bmcgYsOsbmguIFbDrSBk4bulLCBjaMO6IHRow61jaCB0csOqbiBj4buZdCBtw6B1IEUgY8OzIHRo4buDIGhp4buDbiB0aOG7iyBnacOhIHRy4buLIDExMTgzMzk3LDMxIFVTRF4yLCBjaG8gYmnhur90IHBoxrDGoW5nIHNhaSBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcgbcOgdSBNIHRydW5nIGLDrG5oIGzDoCAxMTE4MzM5NywzMSBVU0ReMi4NCiAgDQojIyMgKipCaeG7g3UgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIHBoxrDGoW5nIHNhaSBnacOhIGLDoW4gdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QqKg0KDQoNCmBgYHtyfQ0KYSA8LSBkaWFtb25kcw0KYSAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKGs9IHZhcihwcmljZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKGN1dCxrKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J3NreWJsdWUnKSArIA0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChrLDIpKSx2anVzdCA9IDEsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICdDaOG6pXQgbMaw4bujbmcgY+G6r3QnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIG7DoHkgdGjhu4MgaGnhu4duIHBoxrDGoW5nIHNhaSBj4bunYSBnacOhIGLDoW4gdGhlbyB04burbmcgY2jhuqV0IGzGsOG7o25nIGPhuq90IGPhu6dhIGtpbSBjxrDGoW5nIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMuIFBoxrDGoW5nIHNhaSBsw6AgbeG7mXQgdGjGsOG7m2MgxJFvIG3hu6ljIMSR4buZIHBow6JuIHTDoW4gY+G7p2EgZOG7ryBsaeG7h3UuDQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgY2jhuqV0IGzGsOG7o25nIGPhuq90IGtow6FjIG5oYXUgY+G7p2Ega2ltIGPGsMahbmcsIHThu6sgIlBvb3IiIChrw6ltKSDEkeG6v24gIklkZWFsIiAoaG/DoG4gaOG6o28pLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gcGjGsMahbmcgc2FpIChrKSBj4bunYSBnacOhIGLDoW4gKMSRxrDhu6NjIGzDoG0gdHLDsm4gxJHhur9uIDIgY2jhu68gc+G7kSB0aOG6rXAgcGjDom4gKHJvdW5kKGssIDIpKSksIGNobyBiaeG6v3QgbeG7qWMgxJHhu5kgdHLhuqNpIHLhu5luZyBj4bunYSBnacOhIGLDoW4NCiAgLSBHacOhIHRy4buLIGNhbyBoxqFuIHRyw6puIHRy4bulYyB5IGNobyBiaeG6v3QgcGjGsMahbmcgc2FpIGNhbyBoxqFuLCBuZ2jEqWEgbMOgIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIGPhuq90IMSRw7MgcGjDom4gdMOhbiBy4buZbmcgaMahbiB4dW5nIHF1YW5oIGdpw6EgdHJ1bmcgYsOsbmguDQogIC0gR2nDoSB0cuG7iyB0aOG6pXAgaMahbiBtZW51bmp1a2thbiBwaMawxqFuZyBzYWkgdGjhuqVwIGjGoW4sIG5naMSpYSBsw6AgZ2nDoSBiw6FuIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgxJHDsyDDrXQgcGjDom4gdMOhbiBoxqFuIHh1bmcgcXVhbmggZ2nDoSB0cnVuZyBiw6xuaC4NCiAgLSBDw6FjIGPhu5l0IG3DoHUgeGFuaCBuaOG6oXQgKCJza3libHVlIik6IENoaeG7gXUgY2FvIGPhu6dhIG3hu5dpIGPhu5l0IHThu7cgbOG7hyB0aHXhuq1uIHbhu5tpIHBoxrDGoW5nIHNhaSBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBj4bqvdCB0xrDGoW5nIOG7qW5nLg0KICAtIENow7ogdGjDrWNoIHbEg24gYuG6o24gbcOgdSDEkWVuICgiYmxhY2siKTogSGnhu4NuIHRo4buLIHBoxrDGoW5nIHNhaSBjaMOtbmggeMOhYyAoxJHGsOG7o2MgbMOgbSB0csOybikgbuG6sW0gdHLDqm4gxJHhu4luaCBt4buXaSBj4buZdC4NCi0gVsOtIGThu6UgY+G7pSB0aOG7gzoNCg0KICAtIENo4bqldCBsxrDhu6NuZyBj4bqvdCAiUHJlbWl1bSIgY2FvIG5o4bqldCB0cm9uZyBiaeG7g3UgxJHhu5MuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBj4bqvdCAiUHJlbWl1bSIgY8OzIHBoxrDGoW5nIHNhaSBjYW8gbmjhuqV0LCBjaG8gYmnhur90IGdpw6EgYsOhbiBj4bunYSBjaMO6bmcgcGjDom4gdMOhbiBy4buZbmcgbmjhuqV0IHh1bmcgcXVhbmggZ2nDoSB0cnVuZyBiw6xuaC4gVsOtIGThu6UsIGNow7ogdGjDrWNoIHRyw6puIGPhu5l0ICJQcmVtaXVtIiBjw7MgdGjhu4MgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgMTg5MTU1ODMsOCBVU0ReMiwgY2hvIGJp4bq/dCBwaMawxqFuZyBzYWkgZ2nDoSBiw6FuIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgaG/DoG4gaOG6o28gdHJ1bmcgYsOsbmggbMOgIDE4OTE1NTgzLDggVVNEXjIuDQoNCiAgLSBDaOG6pXQgbMaw4bujbmcgY+G6r3QgIkZhaXIiIHRo4bqlcCBuaOG6pXQgdHJvbmcgYmnhu4N1IMSR4buTLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgZ2nDoSBiw6FuIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgY+G6r3Qga8OpbSBjw7MgcGjGsMahbmcgc2FpIHRo4bqlcCBuaOG6pXQsIGNobyBiaeG6v3QgZ2nDoSBiw6FuIGPhu6dhIGNow7puZyDDrXQgcGjDom4gdMOhbiBuaOG6pXQgeHVuZyBxdWFuaCBnacOhIHRydW5nIGLDrG5oLiBWw60gZOG7pSwgY2jDuiB0aMOtY2ggdHLDqm4gY+G7mXQgIkZhaXIiIGPDsyB0aOG7gyBoaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyAxMjY3NjM1Miw4MyBVU0ReMiwgY2hvIGJp4bq/dCBwaMawxqFuZyBzYWkgZ2nDoSBiw6FuIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgY+G6r3Qga8OpbSB0cnVuZyBiw6xuaCBsw6AgMTI2NzYzNTIsODMgVVNEXjIgDQogIA0KIyMjICoqQmnhu4N1IMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiBwaMawxqFuZyBzYWkgZ2nDoSBiw6FuIHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0KioNCg0KDQpgYGB7cn0NCmEgPC0gZGlhbW9uZHMNCmEgJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2Uoaz0gdmFyKHByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoY2xhcml0eSxrKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J3NreWJsdWUnKSArIA0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChrLDIpKSx2anVzdCA9IDAuODUsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICfEkOG7mSB0cm9uZyBzdeG7kXQnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIG7DoHkgdGjhu4MgaGnhu4duIHBoxrDGoW5nIHNhaSBj4bunYSBnacOhIGLDoW4gdGhlbyB04burbmcgxJHhu5kgdHJvbmcgc3Xhu5F0IGPhu6dhIGtpbSBjxrDGoW5nIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMuIFBoxrDGoW5nIHNhaSBsw6AgbeG7mXQgdGjGsOG7m2MgxJFvIG3hu6ljIMSR4buZIHBow6JuIHTDoW4gY+G7p2EgZOG7ryBsaeG7h3UuDQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgxJHhu5kgdHJvbmcgc3Xhu5F0IGtow6FjIG5oYXUgY+G7p2Ega2ltIGPGsMahbmcsIHThu6sgIkkxIiAoa8OpbSB0cm9uZykgxJHhur9uICJJRiIgKGhvw6BuIGjhuqNvIGtow7RuZyB0w6wgduG6v3QpLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gcGjGsMahbmcgc2FpIChrKSBj4bunYSBnacOhIGLDoW4gKMSRxrDhu6NjIGzDoG0gdHLDsm4gxJHhur9uIDIgY2jhu68gc+G7kSB0aOG6rXAgcGjDom4gKHJvdW5kKGssIDIpKSksIGNobyBiaeG6v3QgbeG7qWMgxJHhu5kgdHLhuqNpIHLhu5luZyBj4bunYSBnacOhIGLDoW4NCiAgLSBHacOhIHRy4buLIGNhbyBoxqFuIHRyw6puIHRy4bulYyB5IGNobyBiaeG6v3QgcGjGsMahbmcgc2FpIGNhbyBoxqFuLCBuZ2jEqWEgbMOgIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IMSRw7MgcGjDom4gdMOhbiBy4buZbmcgaMahbiB4dW5nIHF1YW5oIGdpw6EgdHJ1bmcgYsOsbmguDQogIC0gR2nDoSB0cuG7iyB0aOG6pXAgaMahbiBtZW51bmp1a2thbiBwaMawxqFuZyBzYWkgdGjhuqVwIGjGoW4sIG5naMSpYSBsw6AgZ2nDoSBiw6FuIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgxJHDsyDDrXQgcGjDom4gdMOhbiBoxqFuIHh1bmcgcXVhbmggZ2nDoSB0cnVuZyBiw6xuaC4NCiAgLSBDw6FjIGPhu5l0IG3DoHUgeGFuaCBuaOG6oXQgKCJza3libHVlIik6IENoaeG7gXUgY2FvIGPhu6dhIG3hu5dpIGPhu5l0IHThu7cgbOG7hyB0aHXhuq1uIHbhu5tpIHBoxrDGoW5nIHNhaSBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCB0xrDGoW5nIOG7qW5nLg0KICAtIENow7ogdGjDrWNoIHbEg24gYuG6o24gbcOgdSDEkWVuICgiYmxhY2siKTogSGnhu4NuIHRo4buLIHBoxrDGoW5nIHNhaSBjaMOtbmggeMOhYyAoxJHGsOG7o2MgbMOgbSB0csOybikgbuG6sW0gZ+G6p24gxJHhu4luaCBt4buXaSBj4buZdCwgxJHGsOG7o2MgxJFp4buBdSBjaOG7iW5oIHbhu4sgdHLDrSBi4bqxbmcgdmp1c3QgPSAwLjg1IMSR4buDIHRyw6FuaCBjaOG7k25nIGNow6lvIGzDqm4gY8OhYyBj4buZdC4NCi0gVsOtIGThu6UgY+G7pSB0aOG7gzoNCg0KICAtIMSQ4buZIHRyb25nIHN14buRdCAiU0kyIiBjYW8gbmjhuqV0IHRyb25nIGJp4buDdSDEkeG7ky4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0ICJTSTIiIGPDsyBwaMawxqFuZyBzYWkgY2FvIG5o4bqldCwgY2hvIGJp4bq/dCBnacOhIGLDoW4gY+G7p2EgY2jDum5nIHBow6JuIHTDoW4gcuG7mW5nIG5o4bqldCB4dW5nIHF1YW5oIGdpw6EgdHJ1bmcgYsOsbmguIFbDrSBk4bulLCBjaMO6IHRow61jaCB0csOqbiBj4buZdCAiU0kyIiBjw7MgdGjhu4MgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgMTgxNTE1MDcsMyBVU0ReMiwgY2hvIGJp4bq/dCBwaMawxqFuZyBzYWkgZ2nDoSBiw6FuIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQiU0kyIiB0cnVuZyBiw6xuaCBsw6AgMTgxNTE1MDcsMyBVU0ReMi4NCg0KICAtIMSQ4buZIHRyb25nIHN14buRdCAiSTEiIHRo4bqlcCBuaOG6pXQgdHJvbmcgYmnhu4N1IMSR4buTLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgZ2nDoSBiw6FuIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQga8OpbSB0cm9uZyBjw7MgcGjGsMahbmcgc2FpIHRo4bqlcCBuaOG6pXQsIGNobyBiaeG6v3QgZ2nDoSBiw6FuIGPhu6dhIGNow7puZyDDrXQgcGjDom4gdMOhbiBuaOG6pXQgeHVuZyBxdWFuaCBnacOhIHRydW5nIGLDrG5oLiBWw60gZOG7pSwgY2jDuiB0aMOtY2ggdHLDqm4gY+G7mXQgIkkxIiBjw7MgdGjhu4MgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgNzg3ODAwNCwyNiBVU0ReMiwgY2hvIGJp4bq/dCBwaMawxqFuZyBzYWkgZ2nDoSBiw6FuIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQga8OpbSB0cm9uZyB0cnVuZyBiw6xuaCBsw6AgNzg3ODAwNCwyNiBVU0ReMi4gDQogIA0KIyMgKkJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gcGjGsMahbmcgc2FpIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyBjw6FjIGJp4bq/bjogQ3V0LCBjb2xvciwgY2xhcml0eS4qDQoNCiMjIyAqKkJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gcGjGsMahbmcgc2FpIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyBtw6B1IHPhuq9jIGtpbSBjxrDGoW5nKiogDQoNCg0KYGBge3J9DQphIDwtIGRpYW1vbmRzDQphICU+JSBncm91cF9ieShjb2xvcikgJT4lIHN1bW1hcmlzZShrPSB2YXIoY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyhjb2xvcixrKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J3NreWJsdWUnKSArIA0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChrLDIpKSx2anVzdCA9IDEsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICdNw6B1JywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQotIEJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiBt4bupYyDEkeG7mSBwaMOibiB0w6FuIGPhu6dhIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgKGspIHRoZW8gdOG7q25nIG3DoHUgc+G6r2MgY+G7p2Ega2ltIGPGsMahbmcgdHJvbmcgdOG6rXAgZOG7ryBsaeG7h3UgZGlhbW9uZHMuDQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgbcOgdSBz4bqvYyBraMOhYyBuaGF1IGPhu6dhIGtpbSBjxrDGoW5nLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gcGjGsMahbmcgc2FpIChrKSBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0ICjEkcOjIMSRxrDhu6NjIGzDoG0gdHLDsm4gxJHhur9uIDIgY2jhu68gc+G7kSB0aOG6rXAgcGjDom4pLCBjaG8gYmnhur90IG3hu6ljIMSR4buZIHRy4bqjaSBy4buZbmcgY+G7p2EgdHLhu41uZyBsxrDhu6NuZyBjYXJhdDoNCiAgLSBHacOhIHRy4buLIGNhbyBoxqFuIHRyw6puIHRy4bulYyB5IGNobyBiaeG6v3QgcGjGsMahbmcgc2FpIGNhbyBoxqFuLCBuZ2jEqWEgbMOgIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgY+G7p2Ega2ltIGPGsMahbmcgY8OzIG3DoHUgc+G6r2MgxJHDsyBwaMOibiB0w6FuIHLhu5luZyBoxqFuIHh1bmcgcXVhbmggZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaC4NCiAgLSBHacOhIHRy4buLIHRo4bqlcCBoxqFuIGNobyBiaeG6v3QgcGjGsMahbmcgc2FpIHRo4bqlcCBoxqFuLCBuZ2jEqWEgbMOgIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgY+G7p2Ega2ltIGPGsMahbmcgY8OzIG3DoHUgc+G6r2MgxJHDsyDDrXQgcGjDom4gdMOhbiBoxqFuIHh1bmcgcXVhbmggZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaC4NCkPhu5l0IG3DoHUgeGFuaCBuaOG6oXQ6IENoaeG7gXUgY2FvIGPhu6dhIG3hu5dpIGPhu5l0IHThu7cgbOG7hyB0aHXhuq1uIHbhu5tpIHBoxrDGoW5nIHNhaSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nIGPDsyBtw6B1IHPhuq9jIHTGsMahbmcg4bupbmcuDQogIC0gQ2jDuiB0aMOtY2ggdsSDbiBi4bqjbiBtw6B1IMSRZW46IEhp4buDbiB0aOG7iyBwaMawxqFuZyBzYWkgY2jDrW5oIHjDoWMgKMSRw6MgxJHGsOG7o2MgbMOgbSB0csOybikgbuG6sW0gdHLDqm4gxJHhu4luaCBt4buXaSBj4buZdC4NCi0gVsOtIGThu6U6DQoNCiAgLSBNw6B1IEogY2FvIG5o4bqldC4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIHBoxrDGoW5nIHNhaSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nIG3DoHUgSiBsw6AgY2FvIG5o4bqldC4gRG8gxJHDsywgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBj4bunYSBraW0gY8awxqFuZyBtw6B1IEogcGjDom4gdMOhbiBy4buZbmcgeHVuZyBxdWFuaCBnacOhIHRy4buLIHRydW5nIGLDrG5oLiBWw60gZOG7pSwgY2jDuiB0aMOtY2ggdHLDqm4gY+G7mXQgbcOgdSBKIGPDsyB0aOG7gyBoaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyAwLjM1IGNhcmF0XjIsIGNobyBiaeG6v3QgcGjGsMahbmcgc2FpIGzDoCAwLjM1IGNhcmF0XjIuDQoNCiAgLSBNw6B1IEQgdGjhuqVwIG5o4bqldC4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIHBoxrDGoW5nIHNhaSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nIG3DoHUgRCBsw6AgdGjhuqVwIG5o4bqldC4gRG8gxJHDsywgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBj4bunYSBraW0gY8awxqFuZyBtw6B1IEQgw610IHBow6JuIHTDoW4geHVuZyBxdWFuaCBnacOhIHRy4buLIHRydW5nIGLDrG5oLiBWw60gZOG7pSwgY2jDuiB0aMOtY2ggdHLDqm4gY+G7mXQgbcOgdSBEIGPDsyB0aOG7gyBoaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyAwLjEzIGNhcmF0XjIsIGNobyBiaeG6v3QgcGjGsMahbmcgc2FpIGzDoCAwLjEzIGNhcmF0XjIuIA0KDQojIyMgKipCaeG7g3UgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIHBoxrDGoW5nIHNhaSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90KiogDQoNCg0KDQpgYGB7cn0NCmEgPC0gZGlhbW9uZHMNCmEgJT4lIGdyb3VwX2J5KGN1dCkgJT4lIHN1bW1hcmlzZShrPSB2YXIoY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyhjdXQsaykpICsNCiAgICBnZW9tX2NvbChmaWxsPSdza3libHVlJykgKyANCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQoaywzKSksdmp1c3QgPSAxLCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnQ2jhuqV0IGzGsOG7o25nIGPhuq90JywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQotIEJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiBwaMawxqFuZyBzYWkgY+G7p2EgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0aGVvIHThu6tuZyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgY+G7p2Ega2ltIGPGsMahbmcgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcy4gUGjGsMahbmcgc2FpIGzDoCBt4buZdCB0aMaw4bubYyDEkW8gbeG7qWMgxJHhu5kgcGjDom4gdMOhbiBj4bunYSBk4buvIGxp4buHdS4NCg0KICAtIFRy4bulYyB4OiBUaOG7gyBoaeG7h24gY8OhYyBjaOG6pXQgbMaw4bujbmcgY+G6r3Qga2jDoWMgbmhhdSBj4bunYSBraW0gY8awxqFuZywgdOG7qyAiUG9vciIgKGvDqW0pIMSR4bq/biAiSWRlYWwiIChob8OgbiBo4bqjbykuDQogIC0gVHLhu6VjIHk6IFRo4buDIGhp4buHbiBwaMawxqFuZyBzYWkgKGspIGPhu6dhIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgKMSRxrDhu6NjIGzDoG0gdHLDsm4gxJHhur9uIDIgY2jhu68gc+G7kSB0aOG6rXAgcGjDom4gKHJvdW5kKGssIDIpKSksIGNobyBiaeG6v3QgbeG7qWMgxJHhu5kgdHLhuqNpIHLhu5luZyBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0DQogICAgLSBHacOhIHRy4buLIGNhbyBoxqFuIHRyw6puIHRy4bulYyB5IGNobyBiaeG6v3QgcGjGsMahbmcgc2FpIGNhbyBoxqFuLCBuZ2jEqWEgbMOgIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgY+G7p2Ega2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBj4bqvdCDEkcOzIHBow6JuIHTDoW4gcuG7mW5nIGjGoW4geHVuZyBxdWFuaCBnacOhIHRy4buLIHRydW5nIGLDrG5oLg0KICAgIC0gR2nDoSB0cuG7iyB0aOG6pXAgaMahbiB0csOqbiB0cuG7pWMgeSBjaG8gYmnhur90IHBoxrDGoW5nIHNhaSB0aOG6pXAgaMahbiwgbmdoxKlhIGzDoCB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgxJHDsyDDrXQgcGjDom4gdMOhbiBoxqFuIHh1bmcgcXVhbmggZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaC4NCiAgLSBDw6FjIGPhu5l0IG3DoHUgeGFuaCBuaOG6oXQgKCJza3libHVlIik6IENoaeG7gXUgY2FvIGPhu6dhIG3hu5dpIGPhu5l0IHThu7cgbOG7hyB0aHXhuq1uIHbhu5tpIHBoxrDGoW5nIHNhaSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgdMawxqFuZyDhu6luZy4NCiAgLSBDaMO6IHRow61jaCB2xINuIGLhuqNuIG3DoHUgxJFlbiAoImJsYWNrIik6IEhp4buDbiB0aOG7iyBwaMawxqFuZyBzYWkgY2jDrW5oIHjDoWMgKMSRxrDhu6NjIGzDoG0gdHLDsm4pIG7hurFtIHRyw6puIMSR4buJbmggbeG7l2kgY+G7mXQuDQotIFbDrSBk4bulIGPhu6UgdGjhu4M6DQoNCiAgLSBDaOG6pXQgbMaw4bujbmcgY+G6r3QgIkZhaXIiIGNhbyBuaOG6pXQgdHJvbmcgYmnhu4N1IMSR4buTLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBj4bunYSBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIGPhuq90ICJGYWlyIiBjw7MgcGjGsMahbmcgc2FpIGNhbyBuaOG6pXQsIGNobyBiaeG6v3QgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBj4bunYSBjaMO6bmcgcGjDom4gdMOhbiBy4buZbmcgbmjhuqV0IHh1bmcgcXVhbmggZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaC4gVsOtIGThu6UsIGNow7ogdGjDrWNoIHRyw6puIGPhu5l0ICJGYWlyIiBjw7MgdGjhu4MgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgMC4yNjcgY2FyYXReMiwgY2hvIGJp4bq/dCBwaMawxqFuZyBzYWkgbMOgIDAuMjY3IGNhcmF0XjIuDQoNCiAgLSBDaOG6pXQgbMaw4bujbmcgY+G6r3QgIkdvb2QiIHRo4bqlcCBuaOG6pXQgdHJvbmcgYmnhu4N1IMSR4buTLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBj4bunYSBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIGPhuq90IEdvb2QgY8OzIHBoxrDGoW5nIHNhaSB0aOG6pXAgbmjhuqV0LCBjaG8gYmnhur90IHRy4buNbmcgbMaw4bujbmcgY2FyYXQgY+G7p2EgY2jDum5nIMOtdCBwaMOibiB0w6FuIG5o4bqldCB4dW5nIHF1YW5oIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmguIFbDrSBk4bulLCBjaMO6IHRow61jaCB0csOqbiBj4buZdCAiR29vZCIgY8OzIHRo4buDIGhp4buDbiB0aOG7iyBnacOhIHRy4buLIDAuMjA2IGNhcmF0XjIsIGNobyBiaeG6v3QgcGjGsMahbmcgc2FpIGzDoCAwLjIwNiBjYXJhdF4yLiANCg0KIyMjICoqQmnhu4N1IMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiBwaMawxqFuZyBzYWkgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0aGVvIMSR4buZIHRyb25nIHN14buRdCoqIA0KDQoNCmBgYHtyfQ0KYSA8LSBkaWFtb25kcw0KYSAlPiUgZ3JvdXBfYnkoY2xhcml0eSkgJT4lIHN1bW1hcmlzZShrPSB2YXIoY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyhjbGFyaXR5LGspKSArDQogICAgZ2VvbV9jb2woZmlsbD0nc2t5Ymx1ZScpICsgDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKGssMikpLHZqdXN0ID0gMSwgY29sb3IgPSAnYmxhY2snKSArDQogICAgbGFicyh4ID0gJ8SQ4buZIHRyb25nIHN14buRdCcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KLSBCaeG7g3UgxJHhu5MgbsOgeSB0aOG7gyBoaeG7h24gcGjGsMahbmcgc2FpIGPhu6dhIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyB04burbmcgxJHhu5kgdHJvbmcgc3Xhu5F0IGPhu6dhIGtpbSBjxrDGoW5nIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMuIFBoxrDGoW5nIHNhaSBsw6AgbeG7mXQgdGjGsOG7m2MgxJFvIG3hu6ljIMSR4buZIHBow6JuIHTDoW4gY+G7p2EgZOG7ryBsaeG7h3UuDQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgxJHhu5kgdHJvbmcgc3Xhu5F0IGtow6FjIG5oYXUgY+G7p2Ega2ltIGPGsMahbmcsIHThu6sgIkkxIiAoa8OpbSB0cm9uZykgxJHhur9uICJJRiIgKGhvw6BuIGjhuqNvIGtow7RuZyB0w6wgduG6v3QpLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gcGjGsMahbmcgc2FpIChrKSBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0ICjEkcaw4bujYyBsw6BtIHRyw7JuIMSR4bq/biAyIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuIChyb3VuZChrLCAyKSkpLCBjaG8gYmnhur90IG3hu6ljIMSR4buZIHRy4bqjaSBy4buZbmcgY+G7p2EgdHLhu41uZyBsxrDhu6NuZyBjYXJhdA0KICAtIEdpw6EgdHLhu4sgY2FvIGjGoW4gdHLDqm4gdHLhu6VjIHkgY2hvIGJp4bq/dCBwaMawxqFuZyBzYWkgY2FvIGjGoW4sIG5naMSpYSBsw6AgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBj4bunYSBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IMSRw7MgcGjDom4gdMOhbiBy4buZbmcgaMahbiB4dW5nIHF1YW5oIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmguDQogIC0gR2nDoSB0cuG7iyB0aOG6pXAgaMahbiB0csOqbiB0cuG7pWMgeSBjaG8gYmnhur90IHBoxrDGoW5nIHNhaSB0aOG6pXAgaMahbiwgbmdoxKlhIGzDoCB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgxJHDsyDDrXQgcGjDom4gdMOhbiBoxqFuIHh1bmcgcXVhbmggZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaC4NCiAgLSBDw6FjIGPhu5l0IG3DoHUgeGFuaCBuaOG6oXQgKCJza3libHVlIik6IENoaeG7gXUgY2FvIGPhu6dhIG3hu5dpIGPhu5l0IHThu7cgbOG7hyB0aHXhuq1uIHbhu5tpIHBoxrDGoW5nIHNhaSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgdMawxqFuZyDhu6luZy4NCkNow7ogdGjDrWNoIHbEg24gYuG6o24gbcOgdSDEkWVuICgiYmxhY2siKTogSGnhu4NuIHRo4buLIHBoxrDGoW5nIHNhaSBjaMOtbmggeMOhYyAoxJHGsOG7o2MgbMOgbSB0csOybikgbuG6sW0gdHLDqm4gxJHhu4luaCBt4buXaSBj4buZdC4NCi0gVsOtIGThu6UgY+G7pSB0aOG7gzoNCg0KICAtIMSQ4buZIHRyb25nIHN14buRdCAiSTEiIGNhbyBuaOG6pXQgdHJvbmcgYmnhu4N1IMSR4buTLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBj4bunYSBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0ICIgSTEiIGPDsyBwaMawxqFuZyBzYWkgY2FvIG5o4bqldCwgY2hvIGJp4bq/dCB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGPhu6dhIGNow7puZyBwaMOibiB0w6FuIHLhu5luZyBuaOG6pXQgeHVuZyBxdWFuaCBnacOhIHRy4buLIHRydW5nIGLDrG5oLiBWw60gZOG7pSwgY2jDuiB0aMOtY2ggdHLDqm4gY+G7mXQgIkkxIiBjw7MgdGjhu4MgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgMC40IGNhcmF0XjIsIGNobyBiaeG6v3QgcGjGsMahbmcgc2FpIGzDoCAwLjQgY2FyYXReMi4NCg0KICAtIMSQ4buZIHRyb25nIHN14buRdCAiVlZTMSIgdGjhuqVwIG5o4bqldCB0cm9uZyBiaeG7g3UgxJHhu5MuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgIlZWUzEiIHRyb25nIGPDsyBwaMawxqFuZyBzYWkgdGjhuqVwIG5o4bqldCwgY2hvIGJp4bq/dCB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGPhu6dhIGNow7puZyDDrXQgcGjDom4gdMOhbiBuaOG6pXQgeHVuZyBxdWFuaCBnacOhIHRy4buLIHRydW5nIGLDrG5oLiBWw60gZOG7pSwgY2jDuiB0aMOtY2ggdHLDqm4gY+G7mXQgIlZWUzEiIGPDsyB0aOG7gyBoaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyAwLjA5IGNhcmF0XjIsIGNobyBiaeG6v3QgcGjGsMahbmcgc2FpIGzDoCAwLjA5IGNhcmF0XjIuIA0KDQoNCiMjICpCaeG7g3UgxJHhu5MgY+G7mXQga8OpcCB0aOG7gyBoaeG7h24gcGjDom4gYuG7kSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IHbDoCBtw6B1IHPhuq9jKg0KDQojIyMgKipCaeG7g3UgxJHhu5MgY+G7mXQga8OpcCB0aOG7gyBoaeG7h24gcGjDom4gYuG7kSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IHbDoCBtw6B1IHPhuq9jIGPhu6dhIGtpbSBjxrDGoW5nIGxv4bqhaSBFIHbDoCBIKioNCg0KYGBge3J9DQphIDwtIGRpYW1vbmRzDQphIDwtIGEgJT4lIGdyb3VwX2J5KGN1dCwgY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkNCmEgJT4lIGdncGxvdChhZXMoeCA9IGN1dCwgeSA9IG4pKSArDQogIGdlb21fY29sKGRhdGEgPSBhICU+JSBmaWx0ZXIoY29sb3IgPT0gJ0UnKSwgZmlsbCA9ICdza3libHVlJykgKw0KICBnZW9tX2NvbChkYXRhID0gYSAlPiUgZmlsdGVyKGNvbG9yID09ICdIJyksIGZpbGwgPSAncGluaycpDQpgYGANCg0KLSBCaeG7g3UgxJHhu5MgbsOgeSB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgKGN1dCkgdsOgIG3DoHUgc+G6r2MgKGNvbG9yKSB0cm9uZyBi4buZIGThu68gbGnhu4d1IGRpYW1vbmRzLg0KDQogIC0gVHLhu6VjIHg6IFRo4buDIGhp4buHbiBjw6FjIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBraMOhYyBuaGF1IGPhu6dhIGtpbSBjxrDGoW5nLCB04burICJGYWlyIiAoa8OpbSkgxJHhur9uICJJZGVhbCIgKGhvw6BuIGjhuqNvKS4NCiAgLSBUcuG7pWMgeTogVGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgKG4pIGtpbSBjxrDGoW5nLg0KICAtIEPhu5l0IG3DoHUgeGFuaCBuaOG6oXQgKCJza3libHVlIik6IEJp4buDdSB0aOG7iyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIGPDsyBtw6B1IEUgdGhlbyB04burbmcgY2jhuqV0IGzGsOG7o25nIGPhuq90Lg0KICAtIEPhu5l0IG3DoHUgaOG7k25nICgicGluayIpOiBCaeG7g3UgdGjhu4sgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBjw7MgbcOgdSBIIHRoZW8gdOG7q25nIGNo4bqldCBsxrDhu6NuZyBj4bqvdC4NCi0gVsOtIGThu6U6DQoNCiAgLSBDaOG6pXQgbMaw4bujbmcgY+G6r3QgIlZlcnkgR29vZCI6IFRhIHRo4bqleSB0csOqbiBj4buZdCAiVmVyeSBHb29kIiwgY2hp4buBdSBjYW8gY+G7p2EgY+G7mXQgbcOgdSBo4buTbmcgY2FvIGjGoW4gY+G7mXQgbcOgdSB4YW5oIG5o4bqhdC4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIGPDsyBuaGnhu4F1IGtpbSBjxrDGoW5nIG3DoHUgSCBoxqFuIGtpbSBjxrDGoW5nIG3DoHUgRSBjw7MgY2jhuqV0IGzGsOG7o25nIGPhuq90ICJWZXJ5IEdvb2QiLg0KDQojIyMgKipCaeG7g3UgxJHhu5MgY+G7mXQga8OpcCB0aOG7gyBoaeG7h24gcGjDom4gYuG7kSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IHbDoCBtw6B1IHPhuq9jIGPhu6dhIGtpbSBjxrDGoW5nIGxv4bqhaSBFIHbDoCBIKioNCg0KYGBge3J9DQphIDwtIGRpYW1vbmRzDQphIDwtIGEgJT4lIGdyb3VwX2J5KGN1dCwgY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkNCmEgJT4lIGdncGxvdChhZXMoeCA9IGN1dCwgeSA9IG4pKSArDQogIGdlb21fY29sKGRhdGEgPSBhICU+JSBmaWx0ZXIoY29sb3IgPT0gJ0UnKSwgZmlsbCA9ICdza3libHVlJykgKw0KICBnZW9tX2NvbChkYXRhID0gYSAlPiUgZmlsdGVyKGNvbG9yID09ICdJJyksIGZpbGwgPSAncGluaycpDQpgYGANCg0KLSBCaeG7g3UgxJHhu5MgbsOgeSB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgKGN1dCkgdsOgIG3DoHUgc+G6r2MgKGNvbG9yKSB0cm9uZyBi4buZIGThu68gbGnhu4d1IGRpYW1vbmRzLg0KDQogIC0gVHLhu6VjIHg6IFRo4buDIGhp4buHbiBjw6FjIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBraMOhYyBuaGF1IGPhu6dhIGtpbSBjxrDGoW5nLCB04burICJGYWlyIiAoa8OpbSkgxJHhur9uICJJZGVhbCIgKGhvw6BuIGjhuqNvKS4NCiAgLSBUcuG7pWMgeTogVGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgKG4pIGtpbSBjxrDGoW5nLg0KICAtIEPhu5l0IG3DoHUgeGFuaCBuaOG6oXQgKCJza3libHVlIik6IEJp4buDdSB0aOG7iyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIGPDsyBtw6B1IEUgdGhlbyB04burbmcgY2jhuqV0IGzGsOG7o25nIGPhuq90Lg0KICAtIEPhu5l0IG3DoHUgaOG7k25nICgicGluayIpOiBCaeG7g3UgdGjhu4sgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBjw7MgbcOgdSBJIHRoZW8gdOG7q25nIGNo4bqldCBsxrDhu6NuZyBj4bqvdC4NCi0gVsOtIGThu6U6DQoNCiAgLSBDaOG6pXQgbMaw4bujbmcgY+G6r3QgIlByZW1pdW0iOiBUYSB0aOG6pXkgdHLDqm4gY+G7mXQgIlByZW1pdW0iLCBjaGnhu4F1IGNhbyBj4bunYSBj4buZdCBtw6B1IGjhu5NuZyBjYW8gaMahbiBj4buZdCBtw6B1IHhhbmggbmjhuqF0LiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgY8OzIG5oaeG7gXUga2ltIGPGsMahbmcgbcOgdSBJIGjGoW4ga2ltIGPGsMahbmcgbcOgdSBFIGPDsyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgIlByZW1pdW0iLg0KDQoNCiMjICpCaeG7g3UgxJHhu5MgdGhhbmggdGjhu4MgaGnhu4duIHBow6JuIGLhu5EgY2jhuqV0IGzGsOG7o25nIGPhuq90IGtpbSBjxrDGoW5nKg0KDQpgYGB7cn0NCmEgPC0gZGlhbW9uZHMgDQphIDwtIGEgJT4lIG11dGF0ZShjYXJhdEMgPSBjdXQoY2FyYXQsNSwgbGFiZWwgPSBjKCdy4bqldCBuaOG7jycsICduaOG7jycsJ3bhu6thJywnbOG7m24nLCdy4bqldCBs4bubbicpKSkNCmEgJT4lIGdncGxvdChhZXMoeCA9IGNhcmF0QykpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICd5ZWxsb3cnKQ0KICBsYWJzKHg9ICdDaOG6pXQgbMaw4bujbmcgY+G6r3QnKQ0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIG7DoHkgdGjhu4MgaGnhu4duIHBow6JuIGLhu5EgY+G7p2EgY2jhuqV0IGzGsOG7o25nIGPhuq90IGtpbSBjxrDGoW5nIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMuDQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgY2jhuqV0IGzGsOG7o25nIGPhuq90IMSRxrDhu6NjIGNoaWEgdGjDoG5oIDUgbmjDs206ICJy4bqldCBuaOG7jyIsICJuaOG7jyIsICJ24burYSIsICJs4bubbiIsICJy4bqldCBs4bubbiIuDQogIC0gVHLhu6VjIHk6IFRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRodeG7mWMgbeG7l2kgbmjDs20gY2jhuqV0IGzGsOG7o25nIGPhuq90Lg0KQ+G7mXQgbcOgdSB2w6BuZzogQmnhu4N1IHRo4buLIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgY2hvIG3hu5dpIG5ow7NtIGNo4bqldCBsxrDhu6NuZyBj4bqvdC4gDQoNCg0KIyMgKkJp4buDdSDEkeG7kyBj4buZdCBrw6lwIHRoZW8gbeG6t3QgY+G6r3QgKGN1dCkgcGjDom4gdMOhY2ggdGhlbyBtw6B1IHPhuq9jIChjb2xvcikqDQoNCg0KYGBge3J9DQphIDwtIGRpYW1vbmRzDQphICU+JSBncm91cF9ieShjdXQsY29sb3IpICU+JSBzdW1tYXJpc2UobiA9bigpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY3V0LHkgPSBuKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJywgZmlsbD0gJ3BpbmsnKSArDQogICAgZmFjZXRfd3JhcCh+Y29sb3IpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAwLjY1LCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQoNCkJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiBwaMOibiBi4buRIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgKGN1dCkgxJHGsOG7o2MgdMOhY2ggcmnDqm5nIHRoZW8gbcOgdSBz4bqvYyAoY29sb3IpIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgYS4NCg0KQ8OhYyB0aMOgbmggcGjhuqduOg0KDQogIC0gVHLhu6VjIHg6IFRo4buDIGhp4buHbiBjw6FjIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBraMOhYyBuaGF1IGPhu6dhIGtpbSBjxrDGoW5nLCB04burICJQb29yIiAoa8OpbSkgxJHhur9uICJJZGVhbCIgKGhvw6BuIGjhuqNvKS4NCiAgLSBUcuG7pWMgeTogVGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgKG4pIGtpbSBjxrDGoW5nLg0KICAtIEPDoWMgbeG6t3QgY+G6r3QgKGZhY2V0cyk6IEJp4buDdSDEkeG7kyDEkcaw4bujYyBjaGlhIHRow6BuaCBoYWkgbeG6t3QgY+G6r3QgdGhlbyBtw6B1IHPhuq9jIChjb2xvcikgY+G7p2Ega2ltIGPGsMahbmcsIMSRxrDhu6NjIHBow6JuIGJp4buHdCBi4bqxbmcgbmjDo24g4bufIHBow61hIHRyw6puIG3hu5dpIG3hurd0IGPhuq90Lg0KICAgIC0gTeG6t3QgY+G6r3QgRDogQmnhu4N1IHRo4buLIHBow6JuIGLhu5Egc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjaG8gbcOgdSBz4bqvYyBELg0KICAgIC0gTeG6t3QgY+G6r3QgRTogQmnhu4N1IHRo4buLIHBow6JuIGLhu5Egc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjaG8gbcOgdSBz4bqvYyBFLg0KICAgIC0gTeG6t3QgY+G6r3QgRjogQmnhu4N1IHRo4buLIHBow6JuIGLhu5Egc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjaG8gbcOgdSBz4bqvYyBGLg0KICAgIC0gTeG6t3QgY+G6r3QgRzogQmnhu4N1IHRo4buLIHBow6JuIGLhu5Egc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjaG8gbcOgdSBz4bqvYyBHLg0KICAgIC0gTeG6t3QgY+G6r3QgSDogQmnhu4N1IHRo4buLIHBow6JuIGLhu5Egc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjaG8gbcOgdSBz4bqvYyBILg0KICAgIC0gTeG6t3QgY+G6r3QgSTogQmnhu4N1IHRo4buLIHBow6JuIGLhu5Egc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjaG8gbcOgdSBz4bqvYyBJLiANCiAgICAtIE3hurd0IGPhuq90IEo6IEJp4buDdSB0aOG7iyBwaMOibiBi4buRIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgY2hvIG3DoHUgc+G6r2MgSi4NCiAgLSBD4buZdCBtw6B1IGjhu5NuZyAoInBpbmsiKTogQmnhu4N1IHRo4buLIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgY2hvIG3hu5dpIGNo4bqldCBsxrDhu6NuZyBj4bqvdCB0cm9uZyBt4buXaSBt4bq3dCBj4bqvdC4NCiAgLSBDaMO6IHRow61jaCB2xINuIGLhuqNuIG3DoHUgxJFlbiAoImJsYWNrIik6IEhp4buDbiB0aOG7iyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIGNow61uaCB4w6FjIChuKSBu4bqxbSB0csOqbiDEkeG7iW5oIG3hu5dpIGPhu5l0LCDEkcaw4bujYyDEkWnhu4F1IGNo4buJbmggduG7iyB0csOtIGLhurFuZyB2anVzdCA9IDAuNjUgxJHhu4MgdHLDoW5oIGNo4buTbmcgY2jDqW8gbMOqbiBjw6FjIGPhu5l0Lg0KVsOtIGThu6U6DQoNCiAgLSBDaOG6pXQgbMaw4bujbmcgY+G6r3QgIlZlcnkgR29vZCI6DQogICAgQ+G7mXQgIlZlcnkgR29vZCIgdHLDqm4gbeG6t3QgY+G6r3QgRiBjw7MgY2hp4buBdSBjYW8gY2FvIGjGoW4gY+G7mXQgIlZlcnkgR29vZCIgdHLDqm4gbeG6t3QgY+G6r3QgSSAuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBjw7Mgbmhp4buBdSBraW0gY8awxqFuZyBtw6B1IHPhuq9jIEYgXGjGoW4ga2ltIGPGsMahbmcgbcOgdSBz4bqvYyBJIGPDsyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgIlZlcnkgR29vZCIuDQogICAgU28gc8Ohbmg6IELhuqFuIGPDsyB0aOG7gyBzbyBzw6FuaCB0cuG7sWMgcXVhbiBz4buxIHBow6JuIGLhu5Egc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBnaeG7r2EgaGFpIG3DoHUgc+G6r2Mga2jDoWMgbmhhdSBi4bqxbmcgY8OhY2ggcXVhbiBzw6F0IGNoaeG7gXUgY2FvIHTGsMahbmcgxJHhu5FpIGPhu6dhIGPDoWMgY+G7mXQgdHJvbmcgY8O5bmcgbeG7mXQgbmjDs20gY2jhuqV0IGzGsOG7o25nIGPhuq90IHRyw6puIGhhaSBt4bq3dCBj4bqvdCByacOqbmcgYmnhu4d0LiANCg0KIyMgKkJp4buDdSDEkeG7kyBj4buZdCBrw6lwIHRoZW8gbeG6t3QgY+G6r3QgKGN1dCkgcGjDom4gdMOhY2ggdGhlbyBtw6B1IHPhuq9jIChjb2xvciksIHRo4buDIGhp4buHbiBnacOhIHRydW5nIGLDrG5oKiAgIA0KDQpgYGB7cn0NCmEgPC0gZGlhbW9uZHMNCmEgJT4lIGdyb3VwX2J5KGN1dCxjb2xvcikgJT4lIHN1bW1hcmlzZShrID1tZWFuKHByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gaykpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScsIGZpbGw9ICdwaW5rJykgKw0KICAgIGZhY2V0X3dyYXAofmNvbG9yKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKGssMSkpLHZqdXN0ID0gMC4yNSwgY29sb3IgPSAnYmxhY2snKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KDQpCaeG7g3UgxJHhu5MgbsOgeSB0aOG7gyBoaeG7h24gZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCAoY3V0KSDEkcaw4bujYyB0w6FjaCByacOqbmcgdGhlbyBtw6B1IHPhuq9jIChjb2xvcikgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBhLg0KDQpDw6FjIHRow6BuaCBwaOG6p246DQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgY2jhuqV0IGzGsOG7o25nIGPhuq90IGtow6FjIG5oYXUgY+G7p2Ega2ltIGPGsMahbmcsIHThu6sgIlBvb3IiIChrw6ltKSDEkeG6v24gIklkZWFsIiAoaG/DoG4gaOG6o28pLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gZ2nDoSB0cnVuZyBiw6xuaCAoaykgxJHGsOG7o2MgbMOgbSB0csOybiDEkeG6v24gMSBjaOG7ryBz4buRIHRo4bqtcCBwaMOibiAocm91bmQoaywgMSkpLg0KICAtIEPDoWMgbeG6t3QgY+G6r3QgKGZhY2V0cyk6IEJp4buDdSDEkeG7kyDEkcaw4bujYyBjaGlhIHRow6BuaCBoYWkgbeG6t3QgY+G6r3QgdGhlbyBtw6B1IHPhuq9jIChjb2xvcikgY+G7p2Ega2ltIGPGsMahbmcsIMSRxrDhu6NjIHBow6JuIGJp4buHdCBi4bqxbmcgbmjDo24g4bufIHBow61hIHRyw6puIG3hu5dpIG3hurd0IGPhuq90Lg0KICAgIC0gTeG6t3QgY+G6r3QgRDogQmnhu4N1IHRo4buLIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgY2hvIG3DoHUgc+G6r2MgRC4NCiAgICAtIE3hurd0IGPhuq90IEU6IEJp4buDdSB0aOG7iyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IGNobyBtw6B1IHPhuq9jIEUuDQogICAgLSBN4bq3dCBj4bqvdCBGOiBCaeG7g3UgdGjhu4sgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjaG8gbcOgdSBz4bqvYyBGLg0KICAgIC0gTeG6t3QgY+G6r3QgRzogQmnhu4N1IHRo4buLIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgY2hvIG3DoHUgc+G6r2MgRy4NCiAgICAtIE3hurd0IGPhuq90IEg6IEJp4buDdSB0aOG7iyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IGNobyBtw6B1IHPhuq9jIEguDQogICAgLSBN4bq3dCBj4bqvdCBJOiBCaeG7g3UgdGjhu4sgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjaG8gbcOgdSBz4bqvYyBJLiANCiAgICAtIE3hurd0IGPhuq90IEo6IEJp4buDdSB0aOG7iyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IGNobyBtw6B1IHPhuq9jIEouDQogIC0gQ+G7mXQgbcOgdSBo4buTbmcgKCJwaW5rIik6IEJp4buDdSB0aOG7iyBnacOhIHRydW5nIGLDrG5oIGNobyBt4buXaSBjaOG6pXQgbMaw4bujbmcgY+G6r3QgdHJvbmcgbeG7l2kgbeG6t3QgY+G6r3QuDQogIC0gQ2jDuiB0aMOtY2ggdsSDbiBi4bqjbiBtw6B1IMSRZW4gKCJibGFjayIpOiBIaeG7g24gdGjhu4sgZ2nDoSB0cnVuZyBiw6xuaCBjaMOtbmggeMOhYyAoxJHGsOG7o2MgbMOgbSB0csOybikgbuG6sW0gdHLDqm4gxJHhu4luaCBt4buXaSBj4buZdCwgxJHGsOG7o2MgxJFp4buBdSBjaOG7iW5oIHbhu4sgdHLDrSBi4bqxbmcgdmp1c3QgPSAwLjI1IMSR4buDIHRyw6FuaCBjaOG7k25nIGNow6lvIGzDqm4gY8OhYyBj4buZdC4NClbDrSBk4bulOg0KDQogIC0gQ2jhuqV0IGzGsOG7o25nIGPhuq90ICJWZXJ5IEdvb2QiOg0KICBUYSB0aOG6pXkgIlZlcnkgR29vZCIgdHLDqm4gbeG6t3QgY+G6r3QgSiBjYW8gaMahbiBj4buZdCAiVmVyeSBHb29kIiB0csOqbiBt4bq3dCBj4bqvdCBHLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6Aga2ltIGPGsMahbmcgbcOgdSBz4bqvYyBKIGPDsyBnacOhIHRydW5nIGLDrG5oIGtoaSBjaOG6pXQgbMaw4bujbmcgY+G6r3QgbMOgICJWZXJ5IEdvb2QiIGNhbyBoxqFuIGtpbSBjxrDGoW5nIG3DoHUgc+G6r2MgRy4NCiAgU28gc8Ohbmg6IELhuqFuIGPDsyB0aOG7gyBzbyBzw6FuaCB0cuG7sWMgcXVhbiBnacOhIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IGdp4buvYSBoYWkgbcOgdSBz4bqvYyBraMOhYyBuaGF1IGLhurFuZyBjw6FjaCBxdWFuIHPDoXQgY2hp4buBdSBjYW8gdMawxqFuZyDEkeG7kWkgY+G7p2EgY8OhYyBj4buZdCB0cm9uZyBjw7luZyBt4buZdCBuaMOzbSBjaOG6pXQgbMaw4bujbmcgY+G6r3QgdHLDqm4gaGFpIG3hurd0IGPhuq90IHJpw6puZyBiaeG7h3QuDQoNCiMjICpCaeG7g3UgxJHhu5MgY+G7mXQga8OpcCB0aGVvIG3hurd0IGPhuq90IChjdXQpIHBow6JuIHTDoWNoIHRoZW8gbcOgdSBz4bqvYyAoY29sb3IpLCB0aOG7gyBoaeG7h24gdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCogDQoNCg0KYGBge3J9DQphIDwtIGRpYW1vbmRzDQphICU+JSBncm91cF9ieShjdXQsY29sb3IpICU+JSBzdW1tYXJpc2Uoaz1tZWFuKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gaykpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScsIGZpbGw9ICdwaW5rJykgKw0KICAgIGZhY2V0X3dyYXAofmNvbG9yKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKGssMikpLHZqdXN0ID0gMC42NSwgY29sb3IgPSAnYmxhY2snKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KDQpCaeG7g3UgxJHhu5MgbsOgeSB0aOG7gyBoaeG7h24gdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCAoY3V0KSDEkcaw4bujYyB0w6FjaCByacOqbmcgdGhlbyBtw6B1IHPhuq9jIChjb2xvcikgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBhLg0KDQpDw6FjIHRow6BuaCBwaOG6p246DQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgY2jhuqV0IGzGsOG7o25nIGPhuq90IGtow6FjIG5oYXUgY+G7p2Ega2ltIGPGsMahbmcsIHThu6sgIlBvb3IiIChrw6ltKSDEkeG6v24gIklkZWFsIiAoaG/DoG4gaOG6o28pLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCAoaykgxJHGsOG7o2MgbMOgbSB0csOybiDEkeG6v24gMiBjaOG7ryBz4buRIHRo4bqtcCBwaMOibiAocm91bmQoaywgMikpLg0KICAtIEPDoWMgbeG6t3QgY+G6r3QgKGZhY2V0cyk6IEJp4buDdSDEkeG7kyDEkcaw4bujYyBjaGlhIHRow6BuaCBoYWkgbeG6t3QgY+G6r3QgdGhlbyBtw6B1IHPhuq9jIChjb2xvcikgY+G7p2Ega2ltIGPGsMahbmcsIMSRxrDhu6NjIHBow6JuIGJp4buHdCBi4bqxbmcgbmjDo24g4bufIHBow61hIHRyw6puIG3hu5dpIG3hurd0IGPhuq90Lg0KICAgIC0gTeG6t3QgY+G6r3QgRDogQmnhu4N1IHRo4buLIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgY2hvIG3DoHUgc+G6r2MgRC4NCiAgICAtIE3hurd0IGPhuq90IEU6IEJp4buDdSB0aOG7iyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IGNobyBtw6B1IHPhuq9jIEUuDQogICAgLSBN4bq3dCBj4bqvdCBGOiBCaeG7g3UgdGjhu4sgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjaG8gbcOgdSBz4bqvYyBGLg0KICAgIC0gTeG6t3QgY+G6r3QgRzogQmnhu4N1IHRo4buLIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgY2hvIG3DoHUgc+G6r2MgRy4NCiAgICAtIE3hurd0IGPhuq90IEg6IEJp4buDdSB0aOG7iyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IGNobyBtw6B1IHPhuq9jIEguDQogICAgLSBN4bq3dCBj4bqvdCBJOiBCaeG7g3UgdGjhu4sgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjaG8gbcOgdSBz4bqvYyBJLiANCiAgICAtIE3hurd0IGPhuq90IEo6IEJp4buDdSB0aOG7iyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IGNobyBtw6B1IHPhuq9jIEouDQogIC0gQ+G7mXQgbcOgdSBo4buTbmcgKCJwaW5rIik6IEJp4buDdSB0aOG7iyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIGNobyBt4buXaSBjaOG6pXQgbMaw4bujbmcgY+G6r3QgdHJvbmcgbeG7l2kgbeG6t3QgY+G6r3QuDQogIC0gQ2jDuiB0aMOtY2ggdsSDbiBi4bqjbiBtw6B1IMSRZW4gKCJibGFjayIpOiBIaeG7g24gdGjhu4sgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBjaMOtbmggeMOhYyAoxJHGsOG7o2MgbMOgbSB0csOybikgbuG6sW0gdHLDqm4gxJHhu4luaCBt4buXaSBj4buZdCwgxJHGsOG7o2MgxJFp4buBdSBjaOG7iW5oIHbhu4sgdHLDrSBi4bqxbmcgdmp1c3QgPSAwLjY1IMSR4buDIHRyw6FuaCBjaOG7k25nIGNow6lvIGzDqm4gY8OhYyBj4buZdC4NClbDrSBk4bulOg0KDQogIC0gQ2jhuqV0IGzGsOG7o25nIGPhuq90ICJWZXJ5IEdvb2QiOg0KICBUYSBxdWFuIHNhdCBiaeG7g3UgxJHhu5MsIGPhu5l0ICJWZXJ5IEdvb2QiIHRyw6puIG3hurd0IGPhuq90IEogY2FvIGjGoW4gY+G7mXQgIlZlcnkgR29vZCIgdHLDqm4gbeG6t3QgY+G6r3QgRy4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIGtpbSBjxrDGoW5nIG3DoHUgc+G6r2MgSiBjw7MgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBraGkgY2jhuqV0IGzGsOG7o25nIGPhuq90IGzDoCAiVmVyeSBHb29kIiBjYW8gaMahbiBraW0gY8awxqFuZyBtw6B1IHPhuq9jIEcuDQoNCiMjICpCaeG7g3UgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIHRydW5nIHbhu4sgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0aGVvIGPDoWMgYmnhur9uOiBjdXQsIGNvbG9yLCBjbGFyaXR5KiANCg0KIyMjICoqQmnhu4N1IMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiB0cnVuZyB24buLIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgKGN1dCkqKg0KDQpgYGB7cn0NCmEgJT4lIGdyb3VwX2J5KGN1dCkgJT4lIHN1bW1hcmlzZShtPSBtZWRpYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY3V0LHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJywgZmlsbD0gJ2Jyb3duJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdwaW5rJykgKw0KICAgIGxhYnMoeCA9ICdjdXQnLCB5ID0gJ01lZGlhbicpDQpgYGANCg0KDQpCaeG7g3UgxJHhu5MgbsOgeSB0aOG7gyBoaeG7h24gdHJ1bmcgduG7iyBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IChjdXQpIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgYS4NCg0KLSBDw6FjIHRow6BuaCBwaOG6p246DQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgY2jhuqV0IGzGsOG7o25nIGPhuq90IGtow6FjIG5oYXUgY+G7p2Ega2ltIGPGsMahbmcsIHThu6sgIkZhaXIiIChrw6ltKSDEkeG6v24gIklkZWFsIiAoaG/DoG4gaOG6o28pLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyB24buLIChtKSDEkcaw4bujYyBsw6BtIHRyw7JuIMSR4bq/biAyIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuIChyb3VuZChtLCAyKSkuDQogIC0gQ+G7mXQgbcOgdSBuw6J1ICgiYnJvd24iKTogQmnhu4N1IHRo4buLIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdHJ1bmcgduG7iyBjaG8gbeG7l2kgY2jhuqV0IGzGsOG7o25nIGPhuq90Lg0KICAtIENow7ogdGjDrWNoIHbEg24gYuG6o24gbcOgdSBo4buTbmcgKCJwaW5rIik6IEhp4buDbiB0aOG7iyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRydW5nIHbhu4sgY2jDrW5oIHjDoWMgKMSRxrDhu6NjIGzDoG0gdHLDsm4pIG7hurFtIHRyw6puIMSR4buJbmggbeG7l2kgY+G7mXQsIMSRxrDhu6NjIMSRaeG7gXUgY2jhu4luaCB24buLIHRyw60gYuG6sW5nIHZqdXN0ID0gMiDEkeG7gyB0csOhbmggY2jhu5NuZyBjaMOpbyBsw6puIGPDoWMgY+G7mXQuDQogIC0gVOG7sWEgxJHhu4EgIk1lZGlhbiI6IFRo4buDIGhp4buHbiB0csOqbiB0cuG7pWMgeSwgY2hvIGJp4bq/dCBnacOhIHRy4buLIMSRxrDhu6NjIGhp4buDbiB0aOG7iyBsw6AgdHJ1bmcgduG7iy4NCiAgICAtIMOdIG5naMSpYToNCg0KICAgICAgVHJ1bmcgduG7iyAobWVkaWFuKSBsw6AgZ2nDoSB0cuG7iyDhu58gZ2nhu69hIGPhu6dhIG3hu5l0IHThuq1wIGThu68gbGnhu4d1IMSRw6MgxJHGsOG7o2Mgc+G6r3AgeOG6v3AgdGhlbyB0aOG7qSB04buxLiBTbyB24bubaSB0cnVuZyBiw6xuaCBj4buZbmcgKG1lYW4pLCB0cnVuZyB24buLIMOtdCBi4buLIOG6o25oIGjGsOG7n25nIGLhu59pIGPDoWMgZ2nDoSB0cuG7iyBuZ2/huqFpIGxhaSAob3V0bGllcnMpIC0gbmjhu69uZyBnacOhIHRy4buLIG7hurFtIHLhuqV0IHhhIHNvIHbhu5tpIHBo4bqnbiBjw7JuIGzhuqFpIGPhu6dhIGThu68gbGnhu4d1LiBEbyDEkcOzLCBiaeG7g3UgxJHhu5MgbsOgeSBnacO6cCBoaeG7g3UgcsO1IGjGoW4gduG7gSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IMSRaeG7g24gaMOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QsDQrDrXQgYuG7iyDhuqNuaCBoxrDhu59uZyBi4bufaSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyB0cuG7jW5nIGzGsOG7o25nIHLhuqV0IGNhbyBob+G6t2MgcuG6pXQgdGjhuqVwLg0KDQotIFbDrSBk4bulOg0KDQogVOG7qyBiaeG7g3UgxJHhu5MgdGEgdGjhuqV5IGPhu5l0ICJHb29kIiBjw7MgY2hp4buBdSBjYW8gY2FvIHRo4bupIGJhIHRyw6puIHRy4bulYyB5LiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgbeG7mXQgbuG7rWEgc+G7kSB2acOqbiBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIGPhuq90ICJHb29kIiBjw7MgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBkxrDhu5tpIGdpw6EgdHLhu4sgdHJ1bmcgduG7iyBtLCB2w6AgbeG7mXQgbuG7rWEgY8OzIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdHLDqm4gZ2nDoSB0cuG7iyB0cnVuZyB24buLIG0uDQogIFNvIHPDoW5oOiBC4bqhbiBjw7MgdGjhu4Mgc28gc8OhbmggdHLhu7FjIHF1YW4gdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyB24buLIGdp4buvYSBjw6FjIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBraMOhYyBuaGF1IGLhurFuZyBjw6FjaCBxdWFuIHPDoXQgY2hp4buBdSBjYW8gdMawxqFuZyDEkeG7kWkgY+G7p2EgY8OhYyBj4buZdC4NCg0KIyMjICoqQmnhu4N1IMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiB0cnVuZyB24buLIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyBtw6B1IHPhuq9jIChjb2xvcikqKg0KDQoNCmBgYHtyfQ0KYSAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobT0gbWVkaWFuKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJywgZmlsbD0gJ2Jyb3duJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDMpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdwaW5rJykgKw0KICAgIGxhYnMoeCA9ICdjb2xvcicsIHkgPSAnTWVkaWFuJykNCmBgYA0KDQoNCkJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiB0cnVuZyB24buLIGPhu6dhIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyBtw6B1IHPhuq9jIChjb2xvcikgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBhLg0KDQpDw6FjIHRow6BuaCBwaOG6p246DQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgbcOgdSBz4bqvYyBraMOhYyBuaGF1IGPhu6dhIGtpbSBjxrDGoW5nLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyB24buLIChtKSDEkcaw4bujYyBsw6BtIHRyw7JuIMSR4bq/biAyIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuIChyb3VuZChtLCAyKSkuDQogIC0gQ+G7mXQgbcOgdSBuw6J1ICgiYnJvd24iKTogQmnhu4N1IHRo4buLIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdHJ1bmcgduG7iyBjaG8gbeG7l2kgbcOgdSBz4bqvYy4NCiAgLSBDaMO6IHRow61jaCB2xINuIGLhuqNuIG3DoHUgaOG7k25nICgicGluayIpOiBIaeG7g24gdGjhu4sgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyB24buLIGNow61uaCB4w6FjICjEkcaw4bujYyBsw6BtIHRyw7JuKSBu4bqxbSB0csOqbiDEkeG7iW5oIG3hu5dpIGPhu5l0LCDEkcaw4bujYyDEkWnhu4F1IGNo4buJbmggduG7iyB0csOtIGLhurFuZyB2anVzdCA9IDIgxJHhu4MgdHLDoW5oIGNo4buTbmcgY2jDqW8gbMOqbiBjw6FjIGPhu5l0Lg0KICAtIFThu7FhIMSR4buBICJNZWRpYW4iOiBUaOG7gyBoaeG7h24gdHLDqm4gdHLhu6VjIHksIGNobyBiaeG6v3QgZ2nDoSB0cuG7iyDEkcaw4bujYyBoaeG7g24gdGjhu4sgbMOgIHRydW5nIHbhu4suDQogICAgLSDDnSBuZ2jEqWE6DQoNCiAgICBUcnVuZyB24buLIChtZWRpYW4pIGzDoCBnacOhIHRy4buLIOG7nyBnaeG7r2EgY+G7p2EgbeG7mXQgdOG6rXAgZOG7ryBsaeG7h3UgxJHDoyDEkcaw4bujYyBz4bqvcCB44bq/cCB0aGVvIHRo4bupIHThu7EuIFNvIHbhu5tpIHRydW5nIGLDrG5oIGPhu5luZyAobWVhbiksIHRydW5nIHbhu4sgw610IGLhu4sg4bqjbmggaMaw4bufbmcgYuG7n2kgY8OhYyBnacOhIHRy4buLIG5nb+G6oWkgbGFpIChvdXRsaWVycykgLSBuaOG7r25nIGdpw6EgdHLhu4sgbuG6sW0gcuG6pXQgeGEgc28gduG7m2kgcGjhuqduIGPDsm4gbOG6oWkgY+G7p2EgZOG7ryBsaeG7h3UuIERvIMSRw7MsIGJp4buDdSDEkeG7kyBuw6B5IGdpw7pwIGhp4buDdSByw7UgaMahbiB24buBIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgxJFp4buDbiBow6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIG3DoHUgc+G6r2MsDQrDrXQgYuG7iyDhuqNuaCBoxrDhu59uZyBi4bufaSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyB0cuG7jW5nIGzGsOG7o25nIHLhuqV0IGNhbyBob+G6t2MgcuG6pXQgdGjhuqVwLg0KDQpWw60gZOG7pToNCg0KUXVhbiBzw6F0IGJp4buDdSDEkeG7kyB0YSB0aOG6pXksIGPhu5l0ICJJIiBjw7MgY2hp4buBdSBjYW8gY2FvIHRo4bupIGhhaSB0csOqbiB0cuG7pWMgeS4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIG3hu5l0IG7hu61hIHPhu5EgdmnDqm4ga2ltIGPGsMahbmcgY8OzIG3DoHUgc+G6r2MgIkkiIGPDsyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGTGsOG7m2kgZ2nDoSB0cuG7iyB0cnVuZyB24buLIG0sIHbDoCBt4buZdCBu4butYSBjw7MgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0csOqbiBnacOhIHRy4buLIHRydW5nIHbhu4sgbS4NCg0KDQojIyMgKipCaeG7g3UgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIHRydW5nIHbhu4sgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0aGVvIMSR4buZIHRpbmgga2hp4bq/dCAoY2xhcml0eSkqKg0KDQpgYGB7cn0NCmEgJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobT0gbWVkaWFuKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnLCBmaWxsPSAnYnJvd24nKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ3BpbmsnKSArDQogICAgbGFicyh4ID0gJ2NsYXJpdHknLCB5ID0gJ01lZGlhbicpDQpgYGANCg0KDQpCaeG7g3UgxJHhu5MgbsOgeSB0aOG7gyBoaeG7h24gdHJ1bmcgduG7iyBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRoZW8gxJHhu5kgdGluaCBraGnhur90IChjbGFyaXR5KSBj4bunYSBraW0gY8awxqFuZyB0cm9uZyBi4buZIGThu68gbGnhu4d1IGEuDQoNCi0gQ8OhYyB0aMOgbmggcGjhuqduOg0KDQogIC0gVHLhu6VjIHg6IFRo4buDIGhp4buHbiBjw6FjIG3hu6ljIMSR4buZIHRpbmgga2hp4bq/dCBraMOhYyBuaGF1IGPhu6dhIGtpbSBjxrDGoW5nLCB0aMaw4budbmcgxJHGsOG7o2Mga8O9IGhp4buHdSBi4bqxbmcgY2jhu68gY8OhaSAodsOtIGThu6U6IElGLCBWVlMxLCBWUzEsIFNJMSwgdi52LikuDQogIC0gVHLhu6VjIHk6IFRo4buDIGhp4buHbiB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRydW5nIHbhu4sgKG0pIMSRxrDhu6NjIGzDoG0gdHLDsm4gxJHhur9uIDIgY2jhu68gc+G7kSB0aOG6rXAgcGjDom4gKHJvdW5kKG0sIDIpKS4NCiAgLSBD4buZdCBtw6B1IG7DonUgKCJicm93biIpOiBCaeG7g3UgdGjhu4sgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyB24buLIGNobyBt4buXaSBt4bupYyDEkeG7mSB0aW5oIGtoaeG6v3QuDQogIC0gQ2jDuiB0aMOtY2ggdsSDbiBi4bqjbiBtw6B1IGjhu5NuZyAoInBpbmsiKTogSGnhu4NuIHRo4buLIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdHJ1bmcgduG7iyBjaMOtbmggeMOhYyAoxJHGsOG7o2MgbMOgbSB0csOybikgbuG6sW0gdHLDqm4gxJHhu4luaCBt4buXaSBj4buZdCwgxJHGsOG7o2MgxJFp4buBdSBjaOG7iW5oIHbhu4sgdHLDrSBi4bqxbmcgdmp1c3QgPSAyIMSR4buDIHRyw6FuaCBjaOG7k25nIGNow6lvIGzDqm4gY8OhYyBj4buZdC4NCiAgLSBU4buxYSDEkeG7gSAiTWVkaWFuIjogVGjhu4MgaGnhu4duIHRyw6puIHRy4bulYyB5LCBjaG8gYmnhur90IGdpw6EgdHLhu4sgxJHGsOG7o2MgaGnhu4NuIHRo4buLIGzDoCB0cnVuZyB24buLLg0KDQpWw60gZOG7pToNCg0KxJDhu5kgdGluaCBraGnhur90ICJWVlMyIiBjw7MgY2hp4buBdSBjYW8gdGjhu6kgdMawIHRyw6puIHRy4bulYyB5LiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgbeG7mXQgbuG7rWEgc+G7kSB2acOqbiBraW0gY8awxqFuZyBjw7MgxJHhu5kgdGluaCBraGnhur90ICJWVlMxIiBjw7MgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBkxrDhu5tpIGdpw6EgdHLhu4sgdHJ1bmcgduG7iyBtLCB2w6AgbeG7mXQgbuG7rWEgY8OzIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdHLDqm4gZ2nDoSB0cuG7iyB0cnVuZyB24buLIG0uDQoNCg0KIyMgKkJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gdHJ1bmcgduG7iyBnacOhIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gY8OhYyBiaeG6v246IGN1dCwgY29sb3IsIGNsYXJpdHkqDQoNCiMjIyAqKkJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gdHJ1bmcgduG7iyBnacOhIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IChjdXQpKioNCmBgYHtyfQ0KYSAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG09IG1lZGlhbihwcmljZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjdXQseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnLCBmaWxsPSAnYnJvd24nKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ3BpbmsnKSArDQogICAgbGFicyh4ID0gJ2N1dCcsIHkgPSAnTWVkaWFuJykNCmBgYA0KDQoNCkJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiB0cnVuZyB24buLIGPhu6dhIGdpw6Ega2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgKGN1dCkgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBhLg0KDQotIEPDoWMgdGjDoG5oIHBo4bqnbjoNCg0KICAtIFRy4bulYyB4OiBUaOG7gyBoaeG7h24gY8OhYyBjaOG6pXQgbMaw4bujbmcgY+G6r3Qga2jDoWMgbmhhdSBj4bunYSBraW0gY8awxqFuZywgdOG7qyAiRmFpciIgKGvDqW0pIMSR4bq/biAiSWRlYWwiIChob8OgbiBo4bqjbykuDQogIC0gVHLhu6VjIHk6IFRo4buDIGhp4buHbiB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRydW5nIHbhu4sgKG0pIMSRxrDhu6NjIGzDoG0gdHLDsm4gxJHhur9uIDIgY2jhu68gc+G7kSB0aOG6rXAgcGjDom4gKHJvdW5kKG0sIDIpKS4NCiAgLSBD4buZdCBtw6B1IG7DonUgKCJicm93biIpOiBCaeG7g3UgdGjhu4sgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyB24buLIGNobyBt4buXaSBjaOG6pXQgbMaw4bujbmcgY+G6r3QuDQogIC0gQ2jDuiB0aMOtY2ggdsSDbiBi4bqjbiBtw6B1IGjhu5NuZyAoInBpbmsiKTogSGnhu4NuIHRo4buLIGdpw6Ega2ltIGPGsMahbmcgdHJ1bmcgduG7iyBjaMOtbmggeMOhYyAoxJHGsOG7o2MgbMOgbSB0csOybikgbuG6sW0gdHLDqm4gxJHhu4luaCBt4buXaSBj4buZdCwgxJHGsOG7o2MgxJFp4buBdSBjaOG7iW5oIHbhu4sgdHLDrSBi4bqxbmcgdmp1c3QgPSAyIMSR4buDIHRyw6FuaCBjaOG7k25nIGNow6lvIGzDqm4gY8OhYyBj4buZdC4NCiAgLSBU4buxYSDEkeG7gSAiTWVkaWFuIjogVGjhu4MgaGnhu4duIHRyw6puIHRy4bulYyB5LCBjaG8gYmnhur90IGdpw6EgdHLhu4sgxJHGsOG7o2MgaGnhu4NuIHRo4buLIGzDoCB0cnVuZyB24buLLg0KICAgIA0KLSBWw60gZOG7pToNCg0KIFThu6sgYmnhu4N1IMSR4buTIHRhIHRo4bqleSBj4buZdCAiR29vZCIgY8OzIGNoaeG7gXUgY2FvIGNhbyB0aOG7qSBiYSB0csOqbiB0cuG7pWMgeS4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIG3hu5l0IG7hu61hIHPhu5EgdmnDqm4ga2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBj4bqvdCAiR29vZCIgY8OzIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgZMaw4bubaSBnacOhIHRy4buLIHRydW5nIHbhu4sgbSwgdsOgIG3hu5l0IG7hu61hIGPDsyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRyw6puIGdpw6EgdHLhu4sgdHJ1bmcgduG7iyBtLg0KICBTbyBzw6FuaDogQuG6oW4gY8OzIHRo4buDIHNvIHPDoW5oIHRy4buxYyBxdWFuIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdHJ1bmcgduG7iyBnaeG7r2EgY8OhYyBjaOG6pXQgbMaw4bujbmcgY+G6r3Qga2jDoWMgbmhhdSBi4bqxbmcgY8OhY2ggcXVhbiBzw6F0IGNoaeG7gXUgY2FvIHTGsMahbmcgxJHhu5FpIGPhu6dhIGPDoWMgY+G7mXQuDQoNCiMjIyAqKkJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gdHJ1bmcgduG7iyBnacOhIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSBz4bqvYyBraW0gY8awxqFuZyAoY29sb3IpKiogDQoNCmBgYHtyfQ0KYSAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobT0gbWVkaWFuKHByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJywgZmlsbD0gJ2Jyb3duJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdwaW5rJykgKw0KICAgIGxhYnMoeCA9ICdjb2xvcicsIHkgPSAnTWVkaWFuJykNCmBgYA0KDQoNCkJp4buDdSDEkeG7kyBuw6B5IHRo4buDIGhp4buHbiB0cnVuZyB24buLIGPhu6dhIGdpw6Ega2ltIGPGsMahbmcgdGhlbyBtw6B1IHPhuq9jIChjb2xvcikgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBhLg0KDQpDw6FjIHRow6BuaCBwaOG6p246DQoNCiAgLSBUcuG7pWMgeDogVGjhu4MgaGnhu4duIGPDoWMgbcOgdSBz4bqvYyBraMOhYyBuaGF1IGPhu6dhIGtpbSBjxrDGoW5nLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gZ2nDoSBraW0gY8awxqFuZyB0cnVuZyB24buLIChtKSDEkcaw4bujYyBsw6BtIHRyw7JuIMSR4bq/biAyIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuIChyb3VuZChtLCAyKSkuDQogIC0gQ+G7mXQgbcOgdSBuw6J1ICgiYnJvd24iKTogQmnhu4N1IHRo4buLIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdHJ1bmcgduG7iyBjaG8gbeG7l2kgbcOgdSBz4bqvYy4NCiAgLSBDaMO6IHRow61jaCB2xINuIGLhuqNuIG3DoHUgaOG7k25nICgicGluayIpOiBIaeG7g24gdGjhu4sgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0cnVuZyB24buLIGNow61uaCB4w6FjICjEkcaw4bujYyBsw6BtIHRyw7JuKSBu4bqxbSB0csOqbiDEkeG7iW5oIG3hu5dpIGPhu5l0LCDEkcaw4bujYyDEkWnhu4F1IGNo4buJbmggduG7iyB0csOtIGLhurFuZyB2anVzdCA9IDIgxJHhu4MgdHLDoW5oIGNo4buTbmcgY2jDqW8gbMOqbiBjw6FjIGPhu5l0Lg0KICAtIFThu7FhIMSR4buBICJNZWRpYW4iOiBUaOG7gyBoaeG7h24gdHLDqm4gdHLhu6VjIHksIGNobyBiaeG6v3QgZ2nDoSB0cuG7iyDEkcaw4bujYyBoaeG7g24gdGjhu4sgbMOgIHRydW5nIHbhu4suDQoNClbDrSBk4bulOg0KDQpRdWFuIHPDoXQgYmnhu4N1IMSR4buTIHRhIHRo4bqleSwgY+G7mXQgIkkiIGPDsyBjaGnhu4F1IGNhbyBjYW8gdGjhu6kgaGFpIHRyw6puIHRy4bulYyB5LiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgbeG7mXQgbuG7rWEgc+G7kSB2acOqbiBraW0gY8awxqFuZyBjw7MgbcOgdSBz4bqvYyAiSSIgY8OzIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgZMaw4bubaSBnacOhIHRy4buLIHRydW5nIHbhu4sgbSwgdsOgIG3hu5l0IG7hu61hIGPDsyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRyw6puIGdpw6EgdHLhu4sgdHJ1bmcgduG7iyBtLg0KDQojIyMgKipCaeG7g3UgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIHRydW5nIHbhu4sgZ2nDoSBj4bunYSBraW0gY8awxqFuZyB0aGVvIMSR4buZIHRyb25nIHN14buRdCAoY2xhcml0eSkqKg0KYGBge3J9DQphICU+JSBncm91cF9ieShjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG09IG1lZGlhbihwcmljZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjbGFyaXR5LHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJywgZmlsbD0gJ2Jyb3duJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdwaW5rJykgKw0KICAgIGxhYnMoeCA9ICdjbGFyaXR5JywgeSA9ICdNZWRpYW4nKQ0KYGBgDQoNCg0KQmnhu4N1IMSR4buTIG7DoHkgdGjhu4MgaGnhu4duIHRydW5nIHbhu4sgZ2nDoSBraW0gY8awxqFuZyBjYXJhdCB0aGVvIMSR4buZIHRpbmgga2hp4bq/dCAoY2xhcml0eSkgY+G7p2Ega2ltIGPGsMahbmcgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBhLg0KDQotIEPDoWMgdGjDoG5oIHBo4bqnbjoNCg0KICAtIFRy4bulYyB4OiBUaOG7gyBoaeG7h24gY8OhYyBt4bupYyDEkeG7mSB0aW5oIGtoaeG6v3Qga2jDoWMgbmhhdSBj4bunYSBraW0gY8awxqFuZywgdGjGsOG7nW5nIMSRxrDhu6NjIGvDvSBoaeG7h3UgYuG6sW5nIGNo4buvIGPDoWkgKHbDrSBk4bulOiBJRiwgVlZTMSwgVlMxLCBTSTEsIHYudi4pLg0KICAtIFRy4bulYyB5OiBUaOG7gyBoaeG7h24gZ2nDoSBraW0gY8awxqFuZyB0cnVuZyB24buLIChtKSDEkcaw4bujYyBsw6BtIHRyw7JuIMSR4bq/biAyIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuIChyb3VuZChtLCAyKSkuDQogIC0gQ+G7mXQgbcOgdSBuw6J1ICgiYnJvd24iKTogQmnhu4N1IHRo4buLIGdpw6Ega2ltIGPGsMahbmcgdHJ1bmcgduG7iyBjaG8gbeG7l2kgbeG7qWMgxJHhu5kgdGluaCBraGnhur90Lg0KICAtIENow7ogdGjDrWNoIHbEg24gYuG6o24gbcOgdSBo4buTbmcgKCJwaW5rIik6IEhp4buDbiB0aOG7iyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRydW5nIHbhu4sgY2jDrW5oIHjDoWMgKMSRxrDhu6NjIGzDoG0gdHLDsm4pIG7hurFtIHRyw6puIMSR4buJbmggbeG7l2kgY+G7mXQsIMSRxrDhu6NjIMSRaeG7gXUgY2jhu4luaCB24buLIHRyw60gYuG6sW5nIHZqdXN0ID0gMiDEkeG7gyB0csOhbmggY2jhu5NuZyBjaMOpbyBsw6puIGPDoWMgY+G7mXQuDQogIC0gVOG7sWEgxJHhu4EgIk1lZGlhbiI6IFRo4buDIGhp4buHbiB0csOqbiB0cuG7pWMgeSwgY2hvIGJp4bq/dCBnacOhIHRy4buLIMSRxrDhu6NjIGhp4buDbiB0aOG7iyBsw6AgdHJ1bmcgduG7iy4NCg0KLSBWw60gZOG7pToNCg0KxJDhu5kgdGluaCBraGnhur90ICJWUzIiIGPDsyBjaGnhu4F1IGNhbyB0aOG7qSB0xrAgdHLDqm4gdHLhu6VjIHkuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBt4buZdCBu4butYSBz4buRIHZpw6puIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgIlZTMiIgY8OzIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgZMaw4bubaSBnacOhIHRy4buLIHRydW5nIHbhu4sgbSwgdsOgIG3hu5l0IG7hu61hIGPDsyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRyw6puIGdpw6EgdHLhu4sgdHJ1bmcgduG7iyBtLg0K