Thực hiện thao tác vẽ
biểu đồ trên bộ dữ liệu Diamonds.
Giới thiệu về
bộ dữ liệu diamonds
library(ggplot2)
str(diamonds)
## tibble [53,940 × 10] (S3: tbl_df/tbl/data.frame)
## $ carat : num [1:53940] 0.23 0.21 0.23 0.29 0.31 0.24 0.24 0.26 0.22 0.23 ...
## $ cut : Ord.factor w/ 5 levels "Fair"<"Good"<..: 5 4 2 4 2 3 3 3 1 3 ...
## $ color : Ord.factor w/ 7 levels "D"<"E"<"F"<"G"<..: 2 2 2 6 7 7 6 5 2 5 ...
## $ clarity: Ord.factor w/ 8 levels "I1"<"SI2"<"SI1"<..: 2 3 5 4 2 6 7 3 4 5 ...
## $ depth : num [1:53940] 61.5 59.8 56.9 62.4 63.3 62.8 62.3 61.9 65.1 59.4 ...
## $ table : num [1:53940] 55 61 65 58 58 57 57 55 61 61 ...
## $ price : int [1:53940] 326 326 327 334 335 336 336 337 337 338 ...
## $ x : num [1:53940] 3.95 3.89 4.05 4.2 4.34 3.94 3.95 4.07 3.87 4 ...
## $ y : num [1:53940] 3.98 3.84 4.07 4.23 4.35 3.96 3.98 4.11 3.78 4.05 ...
## $ z : num [1:53940] 2.43 2.31 2.31 2.63 2.75 2.48 2.47 2.53 2.49 2.39 ...
names(diamonds)
## [1] "carat" "cut" "color" "clarity" "depth" "table" "price"
## [8] "x" "y" "z"
Sau khi dùng lệnh lệnh str() và names(), ta thu được thông tin
của bộ dữ liệu Diamonds gồm có:
10 cột có tên lần lượt là: carat, cut, color, clarity, depth,
table, price, x, y, z.
53,940 quan sát
Công cụ vẽ đồ thị:
Dùng packages ggplot2.
Câu lệnh geom_bar: vẽ đồ thị dạng bar, tương tự với các dạng biểu
đồ column, histogram,…
+Labs: dùng để đặt tên, ví dụ như là các trục x,y và title: đặt tên cho
biểu đồ.
+Fill: chọn màu cho biểu đồ.
aes: xác định dữ liệu cần vẽ biểu đồ.
Vẽ biểu đồ
cột color theo dạng đồ thị bar.
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(magrittr)
library(scales)
r <- diamonds
r %>% ggplot(aes(x = color)) +
geom_bar(fill='green') +
labs(x = 'Loại', y = 'Số lượng', title = 'Color of Diamonds')

- Quan sát biểu đồ trên, ta thấy được:
- Tỷ lệ khoảng cách số lượng trên đồ thị là 1 đơn vị tương ứng với
1500.
- Đồ thị tên là Color of Diamonds.
- Cột x là Loại (D,E,F,G,H,I,J), cột y là Số lượng.
- Cột G là cột có số lượng nhiều nhất (gần 11500).
- Cột J là cột có số lượng nhỏ nhất (gần 3000).
Vẽ đồ thị cột
cut theo dạng đồ thị bar.
r %>% ggplot(aes(x = cut)) +
geom_bar(fill='pink') +
labs(x = 'Mặt cắt kim cương', y= 'Số lượng' , title = 'Cut of Diamonds')

- Quan sát đồ thị trên:
- Tỷ lệ khoảng cách số lượng trên đồ thị là 1 đơn vị tương ứng với
2500.
- Đồ thị tên là Cut of Diamonds.
- Cột x là Loại mặt cắt (Fair,Good, Very Good, Premium, Ideal), cột y
là Số lượng.
- Cột Ideal có số lượng nhiều nhất
- Cột Fair có số lượng ít nhất
- Nhìn vào biểu đồ ta thấy số lượng mỗi lại tăng dần theo thứ tự loại
mặt cắt.
Vẽ biểu đồ
cột carat theo dạng bar.
r %>% ggplot(aes(x = carat)) +
geom_bar(fill='purple') +
labs(x = 'carat', y= 'Số lượng' , title = 'Carat of Diamonds')

- Nhận xét:
- Tỷ lệ khoảng cách số lượng trên đồ thị là 1 đơn vị tương ứng với
500.
- Đồ thị tên là Carat of Diamonds.
- Cột x là carat(0.23,0.,…), cột y là Số lượng.
- Cột khoảng từ 0 đến 0.5 có số lượng nhiều nhất
- Cột từ 4 đến5 có số lượng ít nhất
- Nhìn vào biểu đồ ta thấy số lượng mỗi lại giảm dần theo thứ tự loại
mặt cắt.
Vẽ biểu đồ
clarity theo dạng bar.
r %>% ggplot(aes(x = clarity)) +
geom_bar(fill='red') +
labs(x = 'độ trong', y= 'Số lượng' , title = 'Clarity of Diamonds')

- Quan sát đồ thị trên:
- Tỷ lệ khoảng cách số lượng trên đồ thị là 1 đơn vị tương ứng với
2500.
- Đồ thị tên là Clarity of Diamonds.
- Cột x là độ trong (I1,SI2,SI1,VS2,VS1,VVS@.VVS1.IF), cột y là Số
lượng.
- Cột SI1 có số lượng nhiều nhất
- Cột I1 có số lượng ít nhất
Vẽ biểu đồ
cột depth theo dạng bar.
r %>% ggplot(aes(x = depth)) +
geom_bar(fill='blue') +
labs(x = 'độ sâu', y= 'Số lượng' , title = 'Depth of Diamonds')

- Quan sát đồ thị trên:
- Tỷ lệ khoảng cách số lượng trên đồ thị là 1 đơn vị tương ứng với
500.
- Đồ thị tên là Depth of Diamonds.
- Cột x là độ sâu (50 ~ 80), cột y là Số lượng.
- Đa phần các giá trị có độ sâu từ 60 ~ 63.
- Các cột còn lại có các quan sát nhưng không nhiều.
Vẽ biểu đồ
cột table theo dạng bar.
r %>% ggplot(aes(x = table)) +
geom_bar(fill='black') +
labs(x = 'table', y= 'Số lượng' , title = 'table of Diamonds')

- Quan sát đồ thị trên:
- Tỷ lệ khoảng cách số lượng trên đồ thị là 1 đơn vị tương ứng với
2500.
- Đồ thị tên là Table of Diamonds.
- Cột x table, cột y là Số lượng.
- Đa phần các giá trị có độ sâu từ 50 ~ 60.
- Các cột còn lại có các quan sát nhưng không nhiều.
Vẽ biểu đồ
cột price theo dạng bar.
r %>% ggplot(aes(x = price)) +
geom_bar(fill='brown') +
labs(x = 'giá', y= 'Số lượng' , title = 'price of Diamonds')

- Quan sát đồ thị trên:
- Tỷ lệ khoảng cách số lượng trên đồ thị là 1 đơn vị tương ứng với
50.
- Đồ thị tên là Price of Diamonds.
- Cột x là giá, cột y là Số lượng.
- Đa phần các giá trị có độ sâu từ 1000 trở xuống.
- Giá càng tăng số lượng càng ít.
Vẽ biểu đồ
cột x theo dạng bar.
r %>% ggplot(aes(x = x)) +
geom_bar(fill='violet') +
labs(x = 'x', y= 'Số lượng' , title = 'X of Diamonds')

- Quan sát đồ thị trên:
- Tỷ lệ khoảng cách số lượng trên đồ thị là 1 đơn vị tương ứng với
50.
- Đồ thị tên là X of Diamonds.
- Cột x là x, cột y là Số lượng.
- Cột có số lượng lớn nhất là khoảng 4.4.
Vẽ biểu đồ
cột y theo dạng bar.
r %>% ggplot(aes(x = y)) +
geom_bar(fill='salmon') +
labs(x = 'y', y= 'Số lượng' , title = 'Y of Diamonds')

- Quan sát đồ thị trên:
- Tỷ lệ khoảng cách số lượng trên đồ thị là 1 đơn vị tương ứng với
50.
- Đồ thị tên là Y of Diamonds.
- Cột x là y, cột y là Số lượng.
- Cột có số lượng nhiều là các cột từ 5 đến 10.
- Các cột còn lại có các quan sát nhưng không nhiều.
Vẽ biểu đồ
cột z theo dạng bar.
r %>% ggplot(aes(x = z)) +
geom_bar(fill='navy') +
labs(x = 'z', y= 'Số lượng' , title = 'Z of Diamonds')

- Quan sát đồ thị trên:
- Tỷ lệ khoảng cách số lượng trên đồ thị là 1 đơn vị tương ứng với
100.
- Đồ thị tên là Z of Diamonds.
- Cột x lad z, cột y là Số lượng.
- Đa phần các giá trị có độ sâu từ 2,5 đến 5.
- Các cột còn lại có các quan sát nhưng không nhiều.
LS0tDQp0aXRsZTogIm5oaeG7h20gduG7pSA0Ig0KYXV0aG9yOiAicG5taW5oY2hhdSINCmRhdGU6ICIyMDI0LTAyLTI5Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRoZW06ICJkZWZhdWx0Ig0KICAgIHRvY19kZXB0aDogMw0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KYGBgDQoNCiJgciBmb3JtYXQoU3lzLnRpbWUoKSwnJUg6JU06JVMsICVkIC0gJW0gLSAlWScpYCIgIA0KKioqDQoNCiMgVGjhu7FjIGhp4buHbiB0aGFvIHTDoWMgduG6vSBiaeG7g3UgxJHhu5MgdHLDqm4gYuG7mSBk4buvIGxp4buHdSBEaWFtb25kcy4NCg0KIyMgKipHaeG7m2kgdGhp4buHdSB24buBIGLhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMqKiAgDQoNCmBgYHtyLGVjaG89VFJVRX0NCmxpYnJhcnkoZ2dwbG90MikNCnN0cihkaWFtb25kcykNCm5hbWVzKGRpYW1vbmRzKQ0KYGBgDQoNCiogU2F1IGtoaSBkw7luZyBs4buHbmggbOG7h25oIHN0cigpIHbDoCBuYW1lcygpLCB0YSB0aHUgxJHGsOG7o2MgdGjDtG5nIHRpbiBj4bunYSBi4buZIGThu68gbGnhu4d1ICoqRGlhbW9uZHMqKiBn4buTbSBjw7M6ICANCisgMTAgY+G7mXQgY8OzIHTDqm4gbOG6p24gbMaw4bujdCBsw6A6IGNhcmF0LCBjdXQsIGNvbG9yLCBjbGFyaXR5LCBkZXB0aCwgdGFibGUsIHByaWNlLCB4LCB5LCB6LiAgDQorIDUzLDk0MCBxdWFuIHPDoXQgIA0KDQoqICoqQ8O0bmcgY+G7pSB24bq9IMSR4buTIHRo4buLOioqDQogKyBEw7luZyBwYWNrYWdlcyBnZ3Bsb3QyLiAgDQogKyBDw6J1IGzhu4duaCBnZW9tX2JhcjogduG6vSDEkeG7kyB0aOG7iyBk4bqhbmcgYmFyLCB0xrDGoW5nIHThu7EgduG7m2kgY8OhYyBk4bqhbmcgYmnhu4N1IMSR4buTIGNvbHVtbiwgaGlzdG9ncmFtLC4uLiAgDQogK0xhYnM6IGTDuW5nIMSR4buDIMSR4bq3dCB0w6puLCB2w60gZOG7pSBuaMawIGzDoCBjw6FjIHRy4bulYyB4LHkgdsOgIHRpdGxlOiDEkeG6t3QgdMOqbiBjaG8gYmnhu4N1IMSR4buTLiAgDQogK0ZpbGw6IGNo4buNbiBtw6B1IGNobyBiaeG7g3UgxJHhu5MuICANCiArIGFlczogeMOhYyDEkeG7i25oIGThu68gbGnhu4d1IGPhuqduIHbhur0gYmnhu4N1IMSR4buTLiAgDQoNCiMjICoqVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgY29sb3IgdGhlbyBk4bqhbmcgxJHhu5MgdGjhu4sgYmFyLioqIA0KDQpgYGB7cixlY2hvPVRSVUV9DQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShtYWdyaXR0cikNCmxpYnJhcnkoc2NhbGVzKQ0KciA8LSBkaWFtb25kcw0KciAlPiUgZ2dwbG90KGFlcyh4ID0gY29sb3IpKSArDQogICAgZ2VvbV9iYXIoZmlsbD0nZ3JlZW4nKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycsIHRpdGxlID0gJ0NvbG9yIG9mIERpYW1vbmRzJykNCmBgYA0KDQoqIFF1YW4gc8OhdCBiaeG7g3UgxJHhu5MgdHLDqm4sIHRhIHRo4bqleSDEkcaw4bujYzogICAgDQogICsgVOG7tyBs4buHIGtob+G6o25nIGPDoWNoIHPhu5EgbMaw4bujbmcgdHLDqm4gxJHhu5MgdGjhu4sgbMOgIDEgxJHGoW4gduG7iyB0xrDGoW5nIOG7qW5nIHbhu5tpIDE1MDAuICANCiAgKyDEkOG7kyB0aOG7iyB0w6puIGzDoCBDb2xvciBvZiBEaWFtb25kcy4gIA0KICArIEPhu5l0IHggbMOgIExv4bqhaSAoRCxFLEYsRyxILEksSiksIGPhu5l0IHkgbMOgIFPhu5EgbMaw4bujbmcuICANCiAgKyBD4buZdCBHIGzDoCBj4buZdCBjw7Mgc+G7kSBsxrDhu6NuZyBuaGnhu4F1IG5o4bqldCAoZ+G6p24gMTE1MDApLiAgDQogICsgQ+G7mXQgSiBsw6AgY+G7mXQgY8OzIHPhu5EgbMaw4bujbmcgbmjhu48gbmjhuqV0IChn4bqnbiAzMDAwKS4gDQoNCiAgDQojIyAqKlbhur0gxJHhu5MgdGjhu4sgY+G7mXQgY3V0IHRoZW8gZOG6oW5nIMSR4buTIHRo4buLIGJhci4qKg0KDQpgYGB7cixlY2hvPVRSVUV9DQoNCnIgJT4lIGdncGxvdChhZXMoeCA9IGN1dCkpICsNCiAgICBnZW9tX2JhcihmaWxsPSdwaW5rJykgKw0KICAgIGxhYnMoeCA9ICdN4bq3dCBj4bqvdCBraW0gY8awxqFuZycsIHk9ICdT4buRIGzGsOG7o25nJyAsIHRpdGxlID0gJ0N1dCBvZiBEaWFtb25kcycpDQpgYGANCg0KKiBRdWFuIHPDoXQgxJHhu5MgdGjhu4sgdHLDqm46ICAgDQogICsgVOG7tyBs4buHIGtob+G6o25nIGPDoWNoIHPhu5EgbMaw4bujbmcgdHLDqm4gxJHhu5MgdGjhu4sgbMOgIDEgxJHGoW4gduG7iyB0xrDGoW5nIOG7qW5nIHbhu5tpIDI1MDAuICANCiAgKyDEkOG7kyB0aOG7iyB0w6puIGzDoCBDdXQgb2YgRGlhbW9uZHMuICANCiAgKyBD4buZdCB4IGzDoCBMb+G6oWkgbeG6t3QgY+G6r3QgKEZhaXIsR29vZCwgVmVyeSBHb29kLCBQcmVtaXVtLCBJZGVhbCksIGPhu5l0IHkgbMOgIFPhu5EgbMaw4bujbmcuICANCiAgKyBD4buZdCBJZGVhbCBjw7Mgc+G7kSBsxrDhu6NuZyBuaGnhu4F1IG5o4bqldCAgIA0KICArIEPhu5l0IEZhaXIgY8OzIHPhu5EgbMaw4bujbmcgw610IG5o4bqldCAgDQogICsgTmjDrG4gdsOgbyBiaeG7g3UgxJHhu5MgdGEgdGjhuqV5IHPhu5EgbMaw4bujbmcgbeG7l2kgbOG6oWkgdMSDbmcgZOG6p24gdGhlbyB0aOG7qSB04buxIGxv4bqhaSBt4bq3dCBj4bqvdC4gIA0KDQojIyAqKlbhur0gYmnhu4N1IMSR4buTIGPhu5l0IGNhcmF0IHRoZW8gZOG6oW5nIGJhci4qKg0KDQpgYGB7cixlY2hvPVRSVUV9DQoNCnIgJT4lIGdncGxvdChhZXMoeCA9IGNhcmF0KSkgKw0KICAgIGdlb21fYmFyKGZpbGw9J3B1cnBsZScpICsNCiAgICBsYWJzKHggPSAnY2FyYXQnLCB5PSAnU+G7kSBsxrDhu6NuZycgLCB0aXRsZSA9ICdDYXJhdCBvZiBEaWFtb25kcycpDQpgYGANCg0KKiBOaOG6rW4geMOpdDogIA0KICArIFThu7cgbOG7hyBraG/huqNuZyBjw6FjaCBz4buRIGzGsOG7o25nIHRyw6puIMSR4buTIHRo4buLIGzDoCAxIMSRxqFuIHbhu4sgdMawxqFuZyDhu6luZyB24bubaSA1MDAuICANCiAgKyDEkOG7kyB0aOG7iyB0w6puIGzDoCBDYXJhdCBvZiBEaWFtb25kcy4gIA0KICArIEPhu5l0IHggbMOgIGNhcmF0KDAuMjMsMC4sLi4uKSwgY+G7mXQgeSBsw6AgU+G7kSBsxrDhu6NuZy4gIA0KICArIEPhu5l0IGtob+G6o25nIHThu6sgMCDEkeG6v24gMC41IGPDsyBz4buRIGzGsOG7o25nIG5oaeG7gXUgbmjhuqV0ICAgDQogICsgQ+G7mXQgdOG7qyA0IMSR4bq/bjUgY8OzIHPhu5EgbMaw4bujbmcgw610IG5o4bqldCAgDQogICsgTmjDrG4gdsOgbyBiaeG7g3UgxJHhu5MgdGEgdGjhuqV5IHPhu5EgbMaw4bujbmcgbeG7l2kgbOG6oWkgZ2nhuqNtIGThuqduIHRoZW8gdGjhu6kgdOG7sSBsb+G6oWkgbeG6t3QgY+G6r3QuICANCg0KIyMgKipW4bq9IGJp4buDdSDEkeG7kyBjbGFyaXR5IHRoZW8gZOG6oW5nIGJhci4qKiAgDQoNCmBgYHtyLGVjaG89VFJVRX0NCg0KciAlPiUgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSkpICsNCiAgICBnZW9tX2JhcihmaWxsPSdyZWQnKSArDQogICAgbGFicyh4ID0gJ8SR4buZIHRyb25nJywgeT0gJ1Phu5EgbMaw4bujbmcnICwgdGl0bGUgPSAnQ2xhcml0eSBvZiBEaWFtb25kcycpDQpgYGANCg0KKiBRdWFuIHPDoXQgxJHhu5MgdGjhu4sgdHLDqm46ICAgDQogICsgVOG7tyBs4buHIGtob+G6o25nIGPDoWNoIHPhu5EgbMaw4bujbmcgdHLDqm4gxJHhu5MgdGjhu4sgbMOgIDEgxJHGoW4gduG7iyB0xrDGoW5nIOG7qW5nIHbhu5tpIDI1MDAuICANCiAgKyDEkOG7kyB0aOG7iyB0w6puIGzDoCBDbGFyaXR5IG9mIERpYW1vbmRzLiAgDQogICsgQ+G7mXQgeCBsw6AgxJHhu5kgdHJvbmcgKEkxLFNJMixTSTEsVlMyLFZTMSxWVlNALlZWUzEuSUYpLCBj4buZdCB5IGzDoCBT4buRIGzGsOG7o25nLiAgDQogICsgQ+G7mXQgU0kxIGPDsyBz4buRIGzGsOG7o25nIG5oaeG7gXUgbmjhuqV0ICAgDQogICsgQ+G7mXQgSTEgY8OzIHPhu5EgbMaw4bujbmcgw610IG5o4bqldCAgDQogIA0KIyMgKipW4bq9IGJp4buDdSDEkeG7kyBj4buZdCBkZXB0aCB0aGVvIGThuqFuZyBiYXIuKioNCg0KYGBge3IsZWNobz1UUlVFfQ0KDQpyICU+JSBnZ3Bsb3QoYWVzKHggPSBkZXB0aCkpICsNCiAgICBnZW9tX2JhcihmaWxsPSdibHVlJykgKw0KICAgIGxhYnMoeCA9ICfEkeG7mSBzw6J1JywgeT0gJ1Phu5EgbMaw4bujbmcnICwgdGl0bGUgPSAnRGVwdGggb2YgRGlhbW9uZHMnKQ0KYGBgDQoNCiogUXVhbiBzw6F0IMSR4buTIHRo4buLIHRyw6puOiAgIA0KICArIFThu7cgbOG7hyBraG/huqNuZyBjw6FjaCBz4buRIGzGsOG7o25nIHRyw6puIMSR4buTIHRo4buLIGzDoCAxIMSRxqFuIHbhu4sgdMawxqFuZyDhu6luZyB24bubaSA1MDAuICANCiAgKyDEkOG7kyB0aOG7iyB0w6puIGzDoCBEZXB0aCBvZiBEaWFtb25kcy4gIA0KICArIEPhu5l0IHggbMOgIMSR4buZIHPDonUgKDUwIH4gODApLCBj4buZdCB5IGzDoCBT4buRIGzGsOG7o25nLiAgDQogICsgxJBhIHBo4bqnbiBjw6FjIGdpw6EgdHLhu4sgY8OzIMSR4buZIHPDonUgdOG7qyA2MCB+IDYzLiAgIA0KICArIEPDoWMgY+G7mXQgY8OybiBs4bqhaSBjw7MgY8OhYyBxdWFuIHPDoXQgbmjGsG5nIGtow7RuZyBuaGnhu4F1LiAgDQogIA0KIyMgKipW4bq9IGJp4buDdSDEkeG7kyBj4buZdCB0YWJsZSB0aGVvIGThuqFuZyBiYXIuKiogIA0KDQpgYGB7cixlY2hvPVRSVUV9DQoNCnIgJT4lIGdncGxvdChhZXMoeCA9IHRhYmxlKSkgKw0KICAgIGdlb21fYmFyKGZpbGw9J2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICd0YWJsZScsIHk9ICdT4buRIGzGsOG7o25nJyAsIHRpdGxlID0gJ3RhYmxlIG9mIERpYW1vbmRzJykNCmBgYA0KICANCg0KKiBRdWFuIHPDoXQgxJHhu5MgdGjhu4sgdHLDqm46ICAgDQogICsgVOG7tyBs4buHIGtob+G6o25nIGPDoWNoIHPhu5EgbMaw4bujbmcgdHLDqm4gxJHhu5MgdGjhu4sgbMOgIDEgxJHGoW4gduG7iyB0xrDGoW5nIOG7qW5nIHbhu5tpIDI1MDAuICANCiAgKyDEkOG7kyB0aOG7iyB0w6puIGzDoCBUYWJsZSBvZiBEaWFtb25kcy4gIA0KICArIEPhu5l0IHggdGFibGUsIGPhu5l0IHkgbMOgIFPhu5EgbMaw4bujbmcuICANCiAgKyDEkGEgcGjhuqduIGPDoWMgZ2nDoSB0cuG7iyBjw7MgxJHhu5kgc8OidSB04burIDUwIH4gNjAuICAgDQogICsgQ8OhYyBj4buZdCBjw7JuIGzhuqFpIGPDsyBjw6FjIHF1YW4gc8OhdCBuaMawbmcga2jDtG5nIG5oaeG7gXUuICANCiAgDQojIyAqKlbhur0gYmnhu4N1IMSR4buTIGPhu5l0IHByaWNlIHRoZW8gZOG6oW5nIGJhci4qKiAgDQoNCmBgYHtyLGVjaG89VFJVRX0NCg0KciAlPiUgZ2dwbG90KGFlcyh4ID0gcHJpY2UpKSArDQogICAgZ2VvbV9iYXIoZmlsbD0nYnJvd24nKSArDQogICAgbGFicyh4ID0gJ2dpw6EnLCB5PSAnU+G7kSBsxrDhu6NuZycgLCB0aXRsZSA9ICdwcmljZSBvZiBEaWFtb25kcycpDQpgYGANCiAgDQoNCiogUXVhbiBzw6F0IMSR4buTIHRo4buLIHRyw6puOiAgIA0KICArIFThu7cgbOG7hyBraG/huqNuZyBjw6FjaCBz4buRIGzGsOG7o25nIHRyw6puIMSR4buTIHRo4buLIGzDoCAxIMSRxqFuIHbhu4sgdMawxqFuZyDhu6luZyB24bubaSA1MC4gIA0KICArIMSQ4buTIHRo4buLIHTDqm4gbMOgIFByaWNlIG9mIERpYW1vbmRzLiAgDQogICsgQ+G7mXQgeCBsw6AgZ2nDoSwgY+G7mXQgeSBsw6AgU+G7kSBsxrDhu6NuZy4gIA0KICArIMSQYSBwaOG6p24gY8OhYyBnacOhIHRy4buLIGPDsyDEkeG7mSBzw6J1IHThu6sgMTAwMCB0cuG7nyB4deG7kW5nLiAgIA0KICArIEdpw6EgY8OgbmcgdMSDbmcgc+G7kSBsxrDhu6NuZyBjw6BuZyDDrXQuICAgDQoNCiMjICoqVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgeCB0aGVvIGThuqFuZyBiYXIuKiogIA0KDQpgYGB7cixlY2hvPVRSVUV9DQoNCnIgJT4lIGdncGxvdChhZXMoeCA9IHgpKSArDQogICAgZ2VvbV9iYXIoZmlsbD0ndmlvbGV0JykgKw0KICAgIGxhYnMoeCA9ICd4JywgeT0gJ1Phu5EgbMaw4bujbmcnICwgdGl0bGUgPSAnWCBvZiBEaWFtb25kcycpDQpgYGANCiAgDQoNCiogUXVhbiBzw6F0IMSR4buTIHRo4buLIHRyw6puOiAgIA0KICArIFThu7cgbOG7hyBraG/huqNuZyBjw6FjaCBz4buRIGzGsOG7o25nIHRyw6puIMSR4buTIHRo4buLIGzDoCAxIMSRxqFuIHbhu4sgdMawxqFuZyDhu6luZyB24bubaSA1MC4gIA0KICArIMSQ4buTIHRo4buLIHTDqm4gbMOgIFggb2YgRGlhbW9uZHMuICANCiAgKyBD4buZdCB4IGzDoCB4LCBj4buZdCB5IGzDoCBT4buRIGzGsOG7o25nLiAgDQogICsgQ+G7mXQgY8OzIHPhu5EgbMaw4bujbmcgbOG7m24gbmjhuqV0IGzDoCBraG/huqNuZyA0LjQuICAgDQoNCiMjICoqVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgeSB0aGVvIGThuqFuZyBiYXIuKiogIA0KDQpgYGB7cixlY2hvPVRSVUV9DQoNCnIgJT4lIGdncGxvdChhZXMoeCA9IHkpKSArDQogICAgZ2VvbV9iYXIoZmlsbD0nc2FsbW9uJykgKw0KICAgIGxhYnMoeCA9ICd5JywgeT0gJ1Phu5EgbMaw4bujbmcnICwgdGl0bGUgPSAnWSBvZiBEaWFtb25kcycpDQpgYGANCiAgDQoNCiogUXVhbiBzw6F0IMSR4buTIHRo4buLIHRyw6puOiAgIA0KICArIFThu7cgbOG7hyBraG/huqNuZyBjw6FjaCBz4buRIGzGsOG7o25nIHRyw6puIMSR4buTIHRo4buLIGzDoCAxIMSRxqFuIHbhu4sgdMawxqFuZyDhu6luZyB24bubaSA1MC4gIA0KICArIMSQ4buTIHRo4buLIHTDqm4gbMOgIFkgb2YgRGlhbW9uZHMuICANCiAgKyBD4buZdCB4IGzDoCB5LCBj4buZdCB5IGzDoCBT4buRIGzGsOG7o25nLiAgDQogICsgQ+G7mXQgY8OzIHPhu5EgbMaw4bujbmcgbmhp4buBdSBsw6AgY8OhYyBj4buZdCB04burIDUgxJHhur9uIDEwLiAgICAgDQogICsgQ8OhYyBj4buZdCBjw7JuIGzhuqFpIGPDsyBjw6FjIHF1YW4gc8OhdCBuaMawbmcga2jDtG5nIG5oaeG7gXUuICAgIA0KICANCiMjICoqVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgeiB0aGVvIGThuqFuZyBiYXIuKiogIA0KDQpgYGB7cixlY2hvPVRSVUV9DQoNCnIgJT4lIGdncGxvdChhZXMoeCA9IHopKSArDQogICAgZ2VvbV9iYXIoZmlsbD0nbmF2eScpICsNCiAgICBsYWJzKHggPSAneicsIHk9ICdT4buRIGzGsOG7o25nJyAsIHRpdGxlID0gJ1ogb2YgRGlhbW9uZHMnKQ0KYGBgDQogIA0KDQoqIFF1YW4gc8OhdCDEkeG7kyB0aOG7iyB0csOqbjogICANCiAgKyBU4bu3IGzhu4cga2hv4bqjbmcgY8OhY2ggc+G7kSBsxrDhu6NuZyB0csOqbiDEkeG7kyB0aOG7iyBsw6AgMSDEkcahbiB24buLIHTGsMahbmcg4bupbmcgduG7m2kgMTAwLiAgDQogICsgxJDhu5MgdGjhu4sgdMOqbiBsw6AgWiBvZiBEaWFtb25kcy4gIA0KICArIEPhu5l0IHggbGFkIHosIGPhu5l0IHkgbMOgIFPhu5EgbMaw4bujbmcuICANCiAgKyDEkGEgcGjhuqduIGPDoWMgZ2nDoSB0cuG7iyBjw7MgxJHhu5kgc8OidSB04burIDIsNSDEkeG6v24gNS4gICANCiAgKyBDw6FjIGPhu5l0IGPDsm4gbOG6oWkgY8OzIGPDoWMgcXVhbiBzw6F0IG5oxrBuZyBraMO0bmcgbmhp4buBdS4gIA==