NHIỆM VỤ 2.1


I. ĐỌC DỮ LIỆU TỪ FILE

Với File CSV

Để đọc dữ liệu từ một tệp CSV vào trong R, ta có thể thực hiện bằng các cách sau:

Cách 1: Đọc dữ liệu bằng cách sử dụng file.choose() để chọn file từ hộp thoại:

d <- read.csv(file.choose(), header = T)

Cách 2: Đọc dữ liệu từ đường dẫn cụ thể:

read.csv(file = ’./data/abc.csv)

Với File Excel

Để đọc dữ liệu từ một tệp Excel vào trong R, ta thực hiện các bước sau:

  • Bước 1: Cài đặt và load gói xlsx (nếu chưa được cài đặt) bằng lệnh install.packages(‘xlsx’)

  • Bước 2: Đọc dữ liệu file xlsx với câu lệnh read.xlsx()

Cách 1: Đọc dữ liệu bằng cách sử dụng file.choose() để chọn file từ hộp thoại:

read.xlsx(file.choose(), sheetIndex = 1, header = T)

Cách 2: Đọc dữ liệu từ đường dẫn cụ thể:

read.xlsx(file = ‘./data/abc.xlsx’)

Ví dụ

library('xlsx') 
d <- read.xlsx(file = 'C:/Users/HP/Downloads/TelcoCustomerChurn.xlsx', sheetIndex = 1, header = T)

II. SỬ DỤNG DỮ LIỆU CÓ SẴN TRONG R

Datasets hay ggplot2 là một gói package bao gồm nhiều bộ dữ liệu mà ta có thể sử dụng sẵn trong R, để sử dụng ta thực hiện theo các bước sau:

BƯỚC 1: Load package và load datasets.

Load package bằng lệnh library()

Hiển thị danh sách các datasets có sẵn trong package bằng lệnh data(package = ’’)

Lưu ý: Nếu chưa được cài đặt thì cài đặt bằng lệnh install.packages(’’)

Ví dụ

library('datasets') 
data(package = 'datasets')

BƯỚC 2: Gán dữ liệu cho 1 đối tượng để làm việc.

Gán dữ liệu từ package ’’ cho đối tượng a bằng cách a <- (tên bộ dữ liệu)

Hoặc đọc dữ liệu từ URL bằng lệnh a <- read.csv(“https://…csv”)

Ví dụ

a <- cars

Lấy dữ liệu từ World Bank

  • Load package library(WDI)

  • Tìm indicator về Total reserves trong World Bank bằng lệnh ind <- WDIsearch(‘Total reserves’)

  • Lấy dữ liệu về Total reserves cho Việt Nam: d <- WDI(indicator = ‘FI.RES.TOTL.MO’, country = c(‘VN’), extra = TRUE)

  • Chọn cột ‘year’ và ‘FI.RES.TOTL.MO’, xóa các hàng chứa giá trị NA

  • htp <- d %>% select(year, FI.RES.TOTL.MO)

  • htp <- na.omit(htp)

  • names(htp) <- c(‘year’, ‘DuTru’)

BƯỚC 3: Sử dụng bộ dữ liệu.

Giải thích các lệnh

is.data.frame(): Kiểm tra xem đây có phải là data frame không, True là phải, False là không phải.

length(): Kiếm tra độ dài của bộ dữ liệu (số cột).

names(): Tên của các cột trong bộ dự liễu.

dim(): Kích thước của bộ dữ liệu (số dòng và số cột).

library(): Hiển thị một bảng tổng quan về bộ dữ liệu.

skim(): Mô tả chi tiết các dữ liệu.

head(): Hiển thị 10 dòng đầu tiên của bộ dữ liệu.

tail(): Hiển thị 10 dòng cuối cùng của bộ dữ liệu.

str(): Hiển thị thông tin chi tiết về cấu trúc của bộ dữ.

is.na(): Kiểm tra xem có giá trị NA trong dữ liệu hay không, TRUE nếu tại vị trí tương ứng có giá trị NA, và FALSE nếu không.

sum(is.na()): Tính tổng số giá trị NA trong dữ liệu.

which(is.na()): Xác định vị trí của các giá trị NA trong dữ liệu.

Ví dụ

is.data.frame(a) 
## [1] TRUE
length(a) 
## [1] 2
names(a) 
## [1] "speed" "dist"
dim(a) 
## [1] 50  2
library(skimr) 
skim(a)
Data summary
Name a
Number of rows 50
Number of columns 2
_______________________
Column type frequency:
numeric 2
________________________
Group variables None

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
speed 0 1 15.40 5.29 4 12 15 19 25 ▂▅▇▇▃
dist 0 1 42.98 25.77 2 26 36 56 120 ▅▇▅▂▁
head(a,10) 
##    speed dist
## 1      4    2
## 2      4   10
## 3      7    4
## 4      7   22
## 5      8   16
## 6      9   10
## 7     10   18
## 8     10   26
## 9     10   34
## 10    11   17
tail(a,10) 
##    speed dist
## 41    20   52
## 42    20   56
## 43    20   64
## 44    22   66
## 45    23   54
## 46    24   70
## 47    24   92
## 48    24   93
## 49    24  120
## 50    25   85
str(a) 
## 'data.frame':    50 obs. of  2 variables:
##  $ speed: num  4 4 7 7 8 9 10 10 10 11 ...
##  $ dist : num  2 10 4 22 16 10 18 26 34 17 ...
is.na(a)
##       speed  dist
##  [1,] FALSE FALSE
##  [2,] FALSE FALSE
##  [3,] FALSE FALSE
##  [4,] FALSE FALSE
##  [5,] FALSE FALSE
##  [6,] FALSE FALSE
##  [7,] FALSE FALSE
##  [8,] FALSE FALSE
##  [9,] FALSE FALSE
## [10,] FALSE FALSE
## [11,] FALSE FALSE
## [12,] FALSE FALSE
## [13,] FALSE FALSE
## [14,] FALSE FALSE
## [15,] FALSE FALSE
## [16,] FALSE FALSE
## [17,] FALSE FALSE
## [18,] FALSE FALSE
## [19,] FALSE FALSE
## [20,] FALSE FALSE
## [21,] FALSE FALSE
## [22,] FALSE FALSE
## [23,] FALSE FALSE
## [24,] FALSE FALSE
## [25,] FALSE FALSE
## [26,] FALSE FALSE
## [27,] FALSE FALSE
## [28,] FALSE FALSE
## [29,] FALSE FALSE
## [30,] FALSE FALSE
## [31,] FALSE FALSE
## [32,] FALSE FALSE
## [33,] FALSE FALSE
## [34,] FALSE FALSE
## [35,] FALSE FALSE
## [36,] FALSE FALSE
## [37,] FALSE FALSE
## [38,] FALSE FALSE
## [39,] FALSE FALSE
## [40,] FALSE FALSE
## [41,] FALSE FALSE
## [42,] FALSE FALSE
## [43,] FALSE FALSE
## [44,] FALSE FALSE
## [45,] FALSE FALSE
## [46,] FALSE FALSE
## [47,] FALSE FALSE
## [48,] FALSE FALSE
## [49,] FALSE FALSE
## [50,] FALSE FALSE
sum(is.na(a))
## [1] 0
which(is.na(a))
## integer(0)

III. RÚT TRÍCH DỮ LIỆU

Trong một số trường hợp, chúng ta thu về là một dữ liệu lớn tuy nhiên ta lại không sử dụng hết. Để thuận tiện R hỗ trợ chức năng rút trích dữ liệu, ta thực hiện theo các bước sau:

BƯỚC 1: Đổi tên cho các biến để thuận tiện cho việc thao tác trên dữ liệu.

Giải thích các lệnh

names(): Đổi tên cho các biến để thuận tiện cho việc thao tác.Ví dụ đổi tên các cột trong bộ dữ liệu a thành ‘S’, ‘D’.

rename(): Sử dụng để đổi tên biến.

Ví dụ

names(a) <- c('S', 'D')

Sau bước này, chũng ta chỉ cần gọi là ‘S’ và ‘D’

BƯỚC 2: Thực hiện thao tác rút trích dữ liệu.

Giải thích các lệnh

a[x,y]: Rút trích giá trị tại hàng thứ x và cột thứ y.

a$X: Rút trích toàn bộ cột ‘X’.

a[,y]: Rút trích toàn bộ cột thú y.

a[x,]: Rút trích toàn bộ hàng thứ x.

a[,c(y1,y2)]: Rút trích toàn bộ cột thứ y1 và y2.

a[x1:x2,]: Rút trích hàng từ x1 đến x2.

a[c(x1,x3,x5,x7),]: Rút trích các hàng x1,x3,x5,x7.

a[c(x1,x3,x5,x7),c(y1,y3)]: Rút trích các hàng x1,x3,x5,x7 và các cột y1,y3.

a[a$H >=80,]: Tạo một bộ dữ liệu mới từ a chỉ với các dòng có giá trị ‘H’ lớn hơn hoặc bằng 80.

a[a\(X >=80 & a\)X <=86,]: Tạo một bộ dữ liệu mới từ a chỉ với các dòng có giá trị ‘X’ lớn hơn hoặc bằng 80 và nhỏ hơn hoặc bằng 86.

a[a\(X == 76 | a\)X == 80,]: Tạo một bộ dữ liệu mới từ a chỉ với các dòng có giá trị ‘X’ bằng 76 hoặc bằng 80.

Ví dụ

b <- a[7,2] 
S <- a$S 
c <- a[ ,1] 
e <- a[3:7, ] 
f <- a[c(2,4,6,8),c(1,2)] 
g <- a[a$D >=35 & a$D <=70, ] 
h <-a[a$D == 35 | a$D == 80, ] 
i <- a[S != 15, ] 

IV. MỘT SỐ BỘ DỮ LIỆU KHÁC

Ngoài các bộ dữ liệu mẫu có sẵn trong gói datasets trong R còn nhiều gói package khác như tidyverse, ggplot2 hay iris. Chúng ta có thể áp dụng rút trích dữ liệu như ở mục III cho những gói này một cách tương tự

Ngoài ra, đối với một số packgae còn có chức năng khác. Ví dụ như tidyverse.

Giải thích các lệnh

filter(d, color == ‘D’ | carat > 1): Lọc các hàng trong bộ dữ liệu diamonds có màu là ‘D’ hoặc có trọng lượng carat lớn hơn 1.

select(d1, color, carat, x, y, z): Chọn chỉ các cột ‘color’, ‘carat’, ‘x’, ‘y’, và ‘z’ từ bộ dữ liệu đã lọc (d1).

  • Sử dụng %>% để kết hợp lệnh filter và select:

d %>% filter(color == ‘D’ | carat > 1): Lọc các hàng trong bộ dữ liệu diamonds có màu là ‘D’ hoặc có trọng lượng carat lớn hơn 1.

d1 %>% select(color, carat, x, y, z): Chọn chỉ các cột ‘color’, ‘carat’, ‘x’, ‘y’, và ‘z’ từ bộ dữ liệu đã lọc (d1).

d %>% filter(color == ‘D’ | carat > 1) %>% select(color, carat, x, y, z): Kết hợp lệnh filter và select ngay từ đầu bằng cách sử dụng %>%. Lọc các hàng có màu là ‘D’ hoặc có trọng lượng carat lớn hơn 1 và sau đó chọn chỉ các cột ‘color’, ‘carat’, ‘x’, ‘y’, và ‘z’.

Ví dụ

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
m <- a %>% filter(S>15)

NHIỆM VỤ 2.2


DATASET: ĐÁNH GIÁ QUẦN ÁO THƯƠNG MẠI ĐIỆN TỬ DÀNH CHO NỮ

Đây là bộ dữ liệu Thương mại điện tử về Quần áo Phụ nữ, tập trung vào đánh giá của khách hàng. Chất lượng và đánh giá từ người tiêu dùng đóng vai trò quan trọng trong quyết định mua sắm trực tuyến. Chúng ta sẽ khám phá một bộ dữ liệu về đánh giá sản phẩm thời trang phụ nữ. Được thu thập từ thực tế thương mại, dữ liệu đã được ẩn danh và các tham chiếu đến công ty trong các đánh giá đã được thay thế bằng “nhà bán lẻ”.

MÔ TẢ VỀ BỘ DỮ LIỆU

Tập dữ liệu này bao gồm có 10 biến và 23486 quan sát. Mỗi hàng tương ứng với đánh giá của khách hàng và bao gồm các biến:

  • ID quần áo: Phân loại sản phẩm cụ thể đang xem xét.

  • Tuổi: Tuổi người đánh giá.

  • Tiêu đề: Tiêu đề đánh giá.

  • Văn bản đánh giá: Nội dung đánh giá.

  • Xếp hạng: Điểm sản phẩm từ 1 đến 5.

  • IND được đề xuất: - 1 (Có đề xuất), 0 (Không đề xuất).

  • Số lượng phản hồi tích cực: Số lượng phản hồi tích cực.

  • Tên cấp cao: Tên cấp cao của sản phẩm.

  • Tên bộ phận: Tên bộ phận sản phẩm.

  • Tên lớp: Tên lớp sản phẩm

BỘ DỮ LIỆU

NV2 <- read.csv(file.choose(), header = T)

Theo nguồn Kaggle.com

RÚT TRÍCH DỮ LIỆU

Yêu cầu rút trích dữ liệu: “Tìm kiếm thông tin về đánh giá quần áo thương mại điện tử dành cho nữ bao gồm ID quần áo, tuổi của người đánh giá, xếp hạng và số lượng phản hồi tích cực”.

NV2tuoi <- NV2[,c(1,2,3)]
NV2rate <- NV2[,c(1,2,6)]
NV2ph <- NV2[,c(1,2,8)]
NV2a <- NV2[7,2] 
NV2b <- NV2[ ,1] 
NV2c <- NV2[3:7, ] 
NV2d <- NV2[c(2,4,6,8),c(1,2)] 

Sau khi thực hiện quá trình rút trích dữ liệu từ bộ dữ liệu thương mại điện tử về quần áo phụ nữ, chúng ta đã có cơ hội khám phá những thông tin quan trọng về cách người tiêu dùng đánh giá sản phẩm. Những kết quả từ quá trình rút trích dữ liệu không chỉ là số liệu khô khan mà là nguồn thông tin quý báu để định hình chiến lược kinh doanh và tiếp thị. Những phân tích này cung cấp một cái nhìn sâu sắc vào tâm lý của người tiêu dùng, giúp doanh nghiệp hiểu rõ hơn về những yếu tố nào là quan trọng đối với khách hàng của họ.

TẠO BỘ DỮ LIỆU MỚI

Yêu cầu tạo dữ liệu mới: “Tạo mô phỏng điểm đánh giá của từng khách hàng, biết mỗi số sao trong lượt đánh giá tỉ lệ thuận với số lượt phản hồi tích cực. Ta có Điểm đánh giá = Số sao x Số lượt phản hồi tích cực

Một phần quan trọng của phân tích là tạo ra một mô hình điểm đánh giá dựa trên số lượng sao và số lượng phản hồi tích cực. Chúng ta sử dụng thư viện tidyverse trong R để tính điểm đánh giá:

library(tidyverse)
NV2$tich <- NV2$Rating*NV2$Positive.Feedback.Count

Với công thức này, chúng ta tạo ra một cột mới “tich” trong bộ dữ liệu, thể hiện điểm đánh giá dựa trên số sao và số lượng phản hồi tích cực. Điều này giúp chúng ta hiểu rõ hơn về cách mà người tiêu dùng đánh giá và tương tác với sản phẩm trên nền tảng thương mại điện tử.

Kết Luận

Qua việc phân tích dữ liệu và tạo mô hình điểm đánh giá, chúng ta đã có cái nhìn sâu sắc hơn về cách người tiêu dùng đánh giá quần áo phụ nữ trên nền tảng thương mại điện tử. Điều này có thể giúp các nhà bán lẻ và nhãn hiệu thời trang hiểu rõ hơn về nhu cầu và mong muốn của khách hàng, từ đó cải thiện trải nghiệm mua sắm trực tuyến.

LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSAyIC0gTcO0biBOZ8O0biBOZ+G7ryBM4bqtcCBUcsOsbmggVHJvbmcgUGjDom4gVMOtY2ggROG7ryBMaeG7h3UiDQphdXRob3I6ICJIb8OgbmcgVOG6pW4gUGjDoXQiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclSDolTTolUywgJWQgLSAlbSAtICVZJylgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIG51bWJlciBzZWN0aW9uOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHNlbGZfY29udGFpbmVkOiBmYWxzZQ0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KIyAqKk5ISeG7hk0gVuG7pCAyLjEqKg0KKioqDQoNCiMjICoqSS4gxJDhu4xDIEThu64gTEnhu4ZVIFThu6ogRklMRSoqDQoNCiMjIyAqKlbhu5tpIEZpbGUgQ1NWKioNCg0KxJDhu4MgxJHhu41jIGThu68gbGnhu4d1IHThu6sgbeG7mXQgdOG7h3AgQ1NWIHbDoG8gdHJvbmcgUiwgdGEgY8OzIHRo4buDIHRo4buxYyBoaeG7h24gYuG6sW5nIGPDoWMgY8OhY2ggc2F1Og0KDQoqKipDw6FjaCAxOioqKiANCirEkOG7jWMgZOG7ryBsaeG7h3UgYuG6sW5nIGPDoWNoIHPhu60gZOG7pW5nIGZpbGUuY2hvb3NlKCkgxJHhu4MgY2jhu41uIGZpbGUgdOG7qyBo4buZcCB0aG/huqFpOioNCg0KKmQgPC0gcmVhZC5jc3YoZmlsZS5jaG9vc2UoKSwgaGVhZGVyID0gVCkqDQoNCioqKkPDoWNoIDI6KioqDQoqxJDhu41jIGThu68gbGnhu4d1IHThu6sgxJHGsOG7nW5nIGThuqtuIGPhu6UgdGjhu4M6Kg0KDQoqcmVhZC5jc3YoZmlsZSA9ICcuL2RhdGEvYWJjLmNzdikqDQoNCiMjIyAqKlbhu5tpIEZpbGUgRXhjZWwqKg0KDQrEkOG7gyDEkeG7jWMgZOG7ryBsaeG7h3UgdOG7qyBt4buZdCB04buHcCBFeGNlbCB2w6BvIHRyb25nIFIsIHRhIHRo4buxYyBoaeG7h24gY8OhYyBixrDhu5tjIHNhdToNCg0KKiAqKkLGsOG7m2MgMToqKiANCioqQ8OgaSDEkeG6t3QgdsOgIGxvYWQgZ8OzaSB4bHN4IChu4bq/dSBjaMawYSDEkcaw4bujYyBjw6BpIMSR4bq3dCkgYuG6sW5nIGzhu4duaCBpbnN0YWxsLnBhY2thZ2VzKCd4bHN4JykqKg0KDQoqICoqQsaw4bubYyAyOioqIA0KKirEkOG7jWMgZOG7ryBsaeG7h3UgZmlsZSB4bHN4IHbhu5tpIGPDonUgbOG7h25oIHJlYWQueGxzeCgpKioNCg0KKioqQ8OhY2ggMToqKiogDQoqxJDhu41jIGThu68gbGnhu4d1IGLhurFuZyBjw6FjaCBz4butIGThu6VuZyBmaWxlLmNob29zZSgpIMSR4buDIGNo4buNbiBmaWxlIHThu6sgaOG7mXAgdGhv4bqhaToqDQoNCipyZWFkLnhsc3goZmlsZS5jaG9vc2UoKSwgc2hlZXRJbmRleCA9IDEsIGhlYWRlciA9IFQpKg0KDQoqKipDw6FjaCAyOioqKiANCirEkOG7jWMgZOG7ryBsaeG7h3UgdOG7qyDEkcaw4budbmcgZOG6q24gY+G7pSB0aOG7gzoqDQoNCipyZWFkLnhsc3goZmlsZSA9ICcuL2RhdGEvYWJjLnhsc3gnKSoNCg0KKioqVsOtIGThu6UqKioNCg0KYGBge3J9DQpsaWJyYXJ5KCd4bHN4JykgDQpkIDwtIHJlYWQueGxzeChmaWxlID0gJ0M6L1VzZXJzL0hQL0Rvd25sb2Fkcy9UZWxjb0N1c3RvbWVyQ2h1cm4ueGxzeCcsIHNoZWV0SW5kZXggPSAxLCBoZWFkZXIgPSBUKQ0KYGBgDQoNCiMjICoqSUkuIFPhu6wgROG7pE5HIEThu64gTEnhu4ZVIEPDkyBT4bq0TiBUUk9ORyBSKioNCg0KKipEYXRhc2V0cyoqIGhheSAqKmdncGxvdDIqKiBsw6AgbeG7mXQgZ8OzaSBwYWNrYWdlIGJhbyBn4buTbSBuaGnhu4F1IGLhu5kgZOG7ryBsaeG7h3UgbcOgIHRhIGPDsyB0aOG7gyBz4butIGThu6VuZyBz4bq1biB0cm9uZyBSLCDEkeG7gyBz4butIGThu6VuZyB0YSB0aOG7sWMgaGnhu4duIHRoZW8gY8OhYyBixrDhu5tjIHNhdToNCg0KIyMjICoqQsav4buaQyAxOiBMb2FkIHBhY2thZ2UgdsOgIGxvYWQgZGF0YXNldHMuKioNCg0KTG9hZCBwYWNrYWdlIGLhurFuZyBs4buHbmggDQoqbGlicmFyeSgpKg0KDQpIaeG7g24gdGjhu4sgZGFuaCBzw6FjaCBjw6FjIGRhdGFzZXRzIGPDsyBz4bq1biB0cm9uZyBwYWNrYWdlIGLhurFuZyBs4buHbmggDQoqZGF0YShwYWNrYWdlID0gJycpKg0KDQoqTMawdSDDvTogTuG6v3UgY2jGsGEgxJHGsOG7o2MgY8OgaSDEkeG6t3QgdGjDrCBjw6BpIMSR4bq3dCBi4bqxbmcgbOG7h25oIGluc3RhbGwucGFja2FnZXMoJycpKg0KDQoqKipWw60gZOG7pSoqKg0KDQpgYGB7cn0NCmxpYnJhcnkoJ2RhdGFzZXRzJykgDQpkYXRhKHBhY2thZ2UgPSAnZGF0YXNldHMnKQ0KYGBgDQoNCiMjIyAqKkLGr+G7mkMgMjogR8OhbiBk4buvIGxp4buHdSBjaG8gMSDEkeG7kWkgdMaw4bujbmcgxJHhu4MgbMOgbSB2aeG7h2MuKioNCg0KR8OhbiBk4buvIGxp4buHdSB04burIHBhY2thZ2UgJycgY2hvIMSR4buRaSB0xrDhu6NuZyBhIGLhurFuZyBjw6FjaCANCiphIDwtICh0w6puIGLhu5kgZOG7ryBsaeG7h3UpKg0KDQpIb+G6t2MgxJHhu41jIGThu68gbGnhu4d1IHThu6sgVVJMIGLhurFuZyBs4buHbmgNCiphIDwtIHJlYWQuY3N2KCJodHRwczovLy4uLmNzdiIpKg0KDQoqKipWw60gZOG7pSoqKg0KDQpgYGB7cn0NCmEgPC0gY2Fycw0KYGBgDQoNCioqTOG6pXkgZOG7ryBsaeG7h3UgdOG7qyBXb3JsZCBCYW5rKioNCg0KKiBMb2FkIHBhY2thZ2UgKmxpYnJhcnkoV0RJKSoNCg0KKiBUw6xtIGluZGljYXRvciB24buBIFRvdGFsIHJlc2VydmVzIHRyb25nIFdvcmxkIEJhbmsgYuG6sW5nIGzhu4duaCAqaW5kIDwtIFdESXNlYXJjaCgnVG90YWwgcmVzZXJ2ZXMnKSoNCg0KKiBM4bqleSBk4buvIGxp4buHdSB24buBIFRvdGFsIHJlc2VydmVzIGNobyBWaeG7h3QgTmFtOiAqZCA8LSBXREkoaW5kaWNhdG9yID0gJ0ZJLlJFUy5UT1RMLk1PJywgY291bnRyeSA9IGMoJ1ZOJyksIGV4dHJhID0gVFJVRSkqDQoNCiogKkNo4buNbiBj4buZdCAneWVhcicgdsOgICdGSS5SRVMuVE9UTC5NTycsIHjDs2EgY8OhYyBow6BuZyBjaOG7qWEgZ2nDoSB0cuG7iyBOQSoNCg0KKiBodHAgPC0gZCAlPiUgc2VsZWN0KHllYXIsIEZJLlJFUy5UT1RMLk1PKQ0KDQoqIGh0cCA8LSBuYS5vbWl0KGh0cCkNCg0KKiBuYW1lcyhodHApIDwtIGMoJ3llYXInLCAnRHVUcnUnKQ0KDQojIyMgKipCxq/hu5pDIDM6IFPhu60gZOG7pW5nIGLhu5kgZOG7ryBsaeG7h3UuKioNCg0KKkdp4bqjaSB0aMOtY2ggY8OhYyBs4buHbmgqDQoNCioqaXMuZGF0YS5mcmFtZSgpOioqIEtp4buDbSB0cmEgeGVtIMSRw6J5IGPDsyBwaOG6o2kgbMOgIGRhdGEgZnJhbWUga2jDtG5nLCAqVHJ1ZSogbMOgIHBo4bqjaSwgKkZhbHNlKiBsw6Aga2jDtG5nIHBo4bqjaS4NCg0KKipsZW5ndGgoKToqKiBLaeG6v20gdHJhIMSR4buZIGTDoGkgY+G7p2EgYuG7mSBk4buvIGxp4buHdSAoc+G7kSBj4buZdCkuDQoNCioqbmFtZXMoKToqKiBUw6puIGPhu6dhIGPDoWMgY+G7mXQgdHJvbmcgYuG7mSBk4buxIGxp4buFdS4NCg0KKipkaW0oKToqKiBLw61jaCB0aMaw4bubYyBj4bunYSBi4buZIGThu68gbGnhu4d1IChz4buRIGTDsm5nIHbDoCBz4buRIGPhu5l0KS4NCg0KKipsaWJyYXJ5KCk6KiogSGnhu4NuIHRo4buLIG3hu5l0IGLhuqNuZyB04buVbmcgcXVhbiB24buBIGLhu5kgZOG7ryBsaeG7h3UuDQoNCioqc2tpbSgpOioqIE3DtCB04bqjIGNoaSB0aeG6v3QgY8OhYyBk4buvIGxp4buHdS4NCg0KKipoZWFkKCk6KiogSGnhu4NuIHRo4buLIDEwIGTDsm5nIMSR4bqndSB0acOqbiBj4bunYSBi4buZIGThu68gbGnhu4d1Lg0KDQoqKnRhaWwoKToqKiBIaeG7g24gdGjhu4sgMTAgZMOybmcgY3Xhu5FpIGPDuW5nIGPhu6dhIGLhu5kgZOG7ryBsaeG7h3UuDQoNCioqc3RyKCk6KiogSGnhu4NuIHRo4buLIHRow7RuZyB0aW4gY2hpIHRp4bq/dCB24buBIGPhuqV1IHRyw7pjIGPhu6dhIGLhu5kgZOG7ry4NCg0KKippcy5uYSgpOioqIEtp4buDbSB0cmEgeGVtIGPDsyBnacOhIHRy4buLIE5BIHRyb25nIGThu68gbGnhu4d1IGhheSBraMO0bmcsICpUUlVFKiBu4bq/dSB04bqhaSB24buLIHRyw60gdMawxqFuZyDhu6luZyBjw7MgZ2nDoSB0cuG7iyBOQSwgdsOgICpGQUxTRSogbuG6v3Uga2jDtG5nLiANCg0KKipzdW0oaXMubmEoKSk6KiogVMOtbmggdOG7lW5nIHPhu5EgZ2nDoSB0cuG7iyBOQSB0cm9uZyBk4buvIGxp4buHdS4NCg0KKip3aGljaChpcy5uYSgpKToqKiBYw6FjIMSR4buLbmggduG7iyB0csOtIGPhu6dhIGPDoWMgZ2nDoSB0cuG7iyBOQSB0cm9uZyBk4buvIGxp4buHdS4NCg0KKioqVsOtIGThu6UqKioNCg0KYGBge3J9DQppcy5kYXRhLmZyYW1lKGEpIA0KbGVuZ3RoKGEpIA0KbmFtZXMoYSkgDQpkaW0oYSkgDQpsaWJyYXJ5KHNraW1yKSANCnNraW0oYSkNCmhlYWQoYSwxMCkgDQp0YWlsKGEsMTApIA0Kc3RyKGEpIA0KaXMubmEoYSkNCnN1bShpcy5uYShhKSkNCndoaWNoKGlzLm5hKGEpKQ0KYGBgDQoNCiMjICoqSUlJLiBSw5pUIFRSw41DSCBE4buuIExJ4buGVSoqDQoNClRyb25nIG3hu5l0IHPhu5EgdHLGsOG7nW5nIGjhu6NwLCBjaMO6bmcgdGEgdGh1IHbhu4EgbMOgIG3hu5l0IGThu68gbGnhu4d1IGzhu5tuIHR1eSBuaGnDqm4gdGEgbOG6oWkga2jDtG5nIHPhu60gZOG7pW5nIGjhur90LiDEkOG7gyB0aHXhuq1uIHRp4buHbiBSIGjhu5cgdHLhu6MgY2jhu6ljIG7Eg25nIHLDunQgdHLDrWNoIGThu68gbGnhu4d1LCB0YSB0aOG7sWMgaGnhu4duIHRoZW8gY8OhYyBixrDhu5tjIHNhdToNCg0KIyMjICoqQsav4buaQyAxOiDEkOG7lWkgdMOqbiBjaG8gY8OhYyBiaeG6v24gxJHhu4MgdGh14bqtbiB0aeG7h24gY2hvIHZp4buHYyB0aGFvIHTDoWMgdHLDqm4gZOG7ryBsaeG7h3UuKiogDQoNCipHaeG6o2kgdGjDrWNoIGPDoWMgbOG7h25oKg0KDQoqKm5hbWVzKCk6KiogxJDhu5VpIHTDqm4gY2hvIGPDoWMgYmnhur9uIMSR4buDIHRodeG6rW4gdGnhu4duIGNobyB2aeG7h2MgdGhhbyB0w6FjLlbDrSBk4bulIMSR4buVaSB0w6puIGPDoWMgY+G7mXQgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBhIHRow6BuaCAnUycsICdEJy4NCg0KKipyZW5hbWUoKToqKiBT4butIGThu6VuZyDEkeG7gyDEkeG7lWkgdMOqbiBiaeG6v24uDQoNCioqKlbDrSBk4bulKioqDQoNCmBgYHtyfQ0KbmFtZXMoYSkgPC0gYygnUycsICdEJykNCmBgYA0KDQpTYXUgYsaw4bubYyBuw6B5LCBjaMWpbmcgdGEgY2jhu4kgY+G6p24gZ+G7jWkgbMOgICdTJyB2w6AgJ0QnDQoNCiMjIyAqKkLGr+G7mkMgMjogVGjhu7FjIGhp4buHbiB0aGFvIHTDoWMgcsO6dCB0csOtY2ggZOG7ryBsaeG7h3UuKioNCg0KKkdp4bqjaSB0aMOtY2ggY8OhYyBs4buHbmgqDQoNCioqYVt4LHldOioqIFLDunQgdHLDrWNoIGdpw6EgdHLhu4sgdOG6oWkgaMOgbmcgdGjhu6kgeCB2w6AgY+G7mXQgdGjhu6kgeS4NCg0KKiphJFg6KiogUsO6dCB0csOtY2ggdG/DoG4gYuG7mSBj4buZdCAnWCcuDQoNCioqYVsseV06KiogUsO6dCB0csOtY2ggdG/DoG4gYuG7mSBj4buZdCB0aMO6IHkuDQoNCioqYVt4LF06KiogUsO6dCB0csOtY2ggdG/DoG4gYuG7mSBow6BuZyB0aOG7qSB4Lg0KDQoqKmFbLGMoeTEseTIpXToqKiBSw7p0IHRyw61jaCB0b8OgbiBi4buZIGPhu5l0IHRo4bupIHkxIHbDoCB5Mi4NCg0KKiphW3gxOngyLF06KiogUsO6dCB0csOtY2ggaMOgbmcgdOG7qyB4MSDEkeG6v24geDIuDQoNCioqYVtjKHgxLHgzLHg1LHg3KSxdOioqIFLDunQgdHLDrWNoIGPDoWMgaMOgbmcgeDEseDMseDUseDcuDQoNCioqYVtjKHgxLHgzLHg1LHg3KSxjKHkxLHkzKV06KiogUsO6dCB0csOtY2ggY8OhYyBow6BuZyB4MSx4Myx4NSx4NyB2w6AgY8OhYyBj4buZdCB5MSx5My4NCg0KKiphW2EkSCA+PTgwLF06KiogVOG6oW8gbeG7mXQgYuG7mSBk4buvIGxp4buHdSBt4bubaSB04burIGEgY2jhu4kgduG7m2kgY8OhYyBkw7JuZyBjw7MgZ2nDoSB0cuG7iyAnSCcgbOG7m24gaMahbiBob+G6t2MgYuG6sW5nIDgwLg0KDQoqKmFbYSRYID49ODAgJiBhJFggPD04NixdOioqIFThuqFvIG3hu5l0IGLhu5kgZOG7ryBsaeG7h3UgbeG7m2kgdOG7qyBhIGNo4buJIHbhu5tpIGPDoWMgZMOybmcgY8OzIGdpw6EgdHLhu4sgJ1gnIGzhu5tuIGjGoW4gaG/hurdjIGLhurFuZyA4MCB2w6Agbmjhu48gaMahbiBob+G6t2MgYuG6sW5nIDg2Lg0KDQoqKmFbYSRYID09IDc2IHwgYSRYID09IDgwLF06KiogVOG6oW8gbeG7mXQgYuG7mSBk4buvIGxp4buHdSBt4bubaSB04burIGEgY2jhu4kgduG7m2kgY8OhYyBkw7JuZyBjw7MgZ2nDoSB0cuG7iyAnWCcgYuG6sW5nIDc2IGhv4bq3YyBi4bqxbmcgODAuDQoNCioqKlbDrSBk4bulKioqDQoNCmBgYHtyfQ0KYiA8LSBhWzcsMl0gDQpTIDwtIGEkUyANCmMgPC0gYVsgLDFdIA0KZSA8LSBhWzM6NywgXSANCmYgPC0gYVtjKDIsNCw2LDgpLGMoMSwyKV0gDQpnIDwtIGFbYSREID49MzUgJiBhJEQgPD03MCwgXSANCmggPC1hW2EkRCA9PSAzNSB8IGEkRCA9PSA4MCwgXSANCmkgPC0gYVtTICE9IDE1LCBdIA0KYGBgDQoNCiMjICoqSVYuIE3hu5hUIFPhu5AgQuG7mCBE4buuIExJ4buGVSBLSMOBQyoqDQpOZ2/DoGkgY8OhYyBi4buZIGThu68gbGnhu4d1IG3huqt1IGPDsyBz4bq1biB0cm9uZyBnw7NpICoqZGF0YXNldHMqKiB0cm9uZyBSIGPDsm4gbmhp4buBdSBnw7NpIHBhY2thZ2Uga2jDoWMgbmjGsCAqKnRpZHl2ZXJzZSoqLCAqKmdncGxvdDIqKiBoYXkgKippcmlzKiouIENow7puZyB0YSBjw7MgdGjhu4Mgw6FwIGThu6VuZyByw7p0IHRyw61jaCBk4buvIGxp4buHdSBuaMawIOG7nyBt4bulYyBJSUkgY2hvIG5o4buvbmcgZ8OzaSBuw6B5IG3hu5l0IGPDoWNoIHTGsMahbmcgdOG7sQ0KDQpOZ2/DoGkgcmEsIMSR4buRaSB24bubaSBt4buZdCBz4buRIHBhY2tnYWUgY8OybiBjw7MgY2jhu6ljIG7Eg25nIGtow6FjLiBWw60gZOG7pSBuaMawICoqdGlkeXZlcnNlKiouDQoNCipHaeG6o2kgdGjDrWNoIGPDoWMgbOG7h25oKg0KDQoqKmZpbHRlcihkLCBjb2xvciA9PSAnRCcgfCBjYXJhdCA+IDEpOioqIEzhu41jIGPDoWMgaMOgbmcgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcyBjw7MgbcOgdSBsw6AgJ0QnIGhv4bq3YyBjw7MgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBs4bubbiBoxqFuIDEuDQoNCioqc2VsZWN0KGQxLCBjb2xvciwgY2FyYXQsIHgsIHksIHopOioqIENo4buNbiBjaOG7iSBjw6FjIGPhu5l0ICdjb2xvcicsICdjYXJhdCcsICd4JywgJ3knLCB2w6AgJ3onIHThu6sgYuG7mSBk4buvIGxp4buHdSDEkcOjIGzhu41jIChkMSkuDQoNCiogKipT4butIGThu6VuZyAlPiUgxJHhu4Mga+G6v3QgaOG7o3AgbOG7h25oIGZpbHRlciB2w6Agc2VsZWN0OioqDQoNCioqZCAlPiUgZmlsdGVyKGNvbG9yID09ICdEJyB8IGNhcmF0ID4gMSk6KiogTOG7jWMgY8OhYyBow6BuZyB0cm9uZyBi4buZIGThu68gbGnhu4d1IGRpYW1vbmRzIGPDsyBtw6B1IGzDoCAnRCcgaG/hurdjIGPDsyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGzhu5tuIGjGoW4gMS4NCg0KKipkMSAlPiUgc2VsZWN0KGNvbG9yLCBjYXJhdCwgeCwgeSwgeik6KiogQ2jhu41uIGNo4buJIGPDoWMgY+G7mXQgJ2NvbG9yJywgJ2NhcmF0JywgJ3gnLCAneScsIHbDoCAneicgdOG7qyBi4buZIGThu68gbGnhu4d1IMSRw6MgbOG7jWMgKGQxKS4NCg0KKipkICU+JSBmaWx0ZXIoY29sb3IgPT0gJ0QnIHwgY2FyYXQgPiAxKSAlPiUgc2VsZWN0KGNvbG9yLCBjYXJhdCwgeCwgeSwgeik6KiogS+G6v3QgaOG7o3AgbOG7h25oIGZpbHRlciB2w6Agc2VsZWN0IG5nYXkgdOG7qyDEkeG6p3UgYuG6sW5nIGPDoWNoIHPhu60gZOG7pW5nICU+JS4gTOG7jWMgY8OhYyBow6BuZyBjw7MgbcOgdSBsw6AgJ0QnIGhv4bq3YyBjw7MgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBs4bubbiBoxqFuIDEgdsOgIHNhdSDEkcOzIGNo4buNbiBjaOG7iSBjw6FjIGPhu5l0ICdjb2xvcicsICdjYXJhdCcsICd4JywgJ3knLCB2w6AgJ3onLg0KDQoqKipWw60gZOG7pSoqKg0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbSA8LSBhICU+JSBmaWx0ZXIoUz4xNSkNCmBgYA0KDQojICoqTkhJ4buGTSBW4bukIDIuMioqDQoqKioNCg0KIyMgKipEQVRBU0VUOiDEkMOBTkggR0nDgSBRVeG6pk4gw4FPIFRIxq/GoE5HIE3huqBJIMSQSeG7hk4gVOG7rCBEw4BOSCBDSE8gTuG7rioqIA0KxJDDonkgbMOgIGLhu5kgZOG7ryBsaeG7h3UgVGjGsMahbmcgbeG6oWkgxJFp4buHbiB04butIHbhu4EgUXXhuqduIMOhbyBQaOG7pSBu4buvLCB04bqtcCB0cnVuZyB2w6BvIMSRw6FuaCBnacOhIGPhu6dhIGtow6FjaCBow6BuZy4gDQpDaOG6pXQgbMaw4bujbmcgdsOgIMSRw6FuaCBnacOhIHThu6sgbmfGsOG7nWkgdGnDqnUgZMO5bmcgxJHDs25nIHZhaSB0csOyIHF1YW4gdHLhu41uZyB0cm9uZyBxdXnhur90IMSR4buLbmggbXVhIHPhuq9tIHRy4buxYyB0dXnhur9uLg0KQ2jDum5nIHRhIHPhur0ga2jDoW0gcGjDoSBt4buZdCBi4buZIGThu68gbGnhu4d1IHbhu4EgxJHDoW5oIGdpw6Egc+G6o24gcGjhuqltIHRo4budaSB0cmFuZyBwaOG7pSBu4buvLg0KxJDGsOG7o2MgdGh1IHRo4bqtcCB04burIHRo4buxYyB04bq/IHRoxrDGoW5nIG3huqFpLCBk4buvIGxp4buHdSDEkcOjIMSRxrDhu6NjIOG6qW4gZGFuaCB2w6AgY8OhYyB0aGFtIGNoaeG6v3UgxJHhur9uIGPDtG5nIHR5IHRyb25nIGPDoWMgxJHDoW5oIGdpw6EgxJHDoyDEkcaw4bujYyB0aGF5IHRo4bq/IGLhurFuZyAibmjDoCBiw6FuIGzhursiLg0KDQojIyMgKipNw5QgVOG6oiBW4buAIELhu5ggROG7riBMSeG7hlUqKg0KVOG6rXAgZOG7ryBsaeG7h3UgbsOgeSBiYW8gZ+G7k20gY8OzIDEwIGJp4bq/biB2w6AgMjM0ODYgcXVhbiBzw6F0LiBN4buXaSBow6BuZyB0xrDGoW5nIOG7qW5nIHbhu5tpIMSRw6FuaCBnacOhIGPhu6dhIGtow6FjaCBow6BuZyB2w6AgYmFvIGfhu5NtIGPDoWMgYmnhur9uOg0KDQoqICoqSUQgcXXhuqduIMOhbzoqKiBQaMOibiBsb+G6oWkgc+G6o24gcGjhuqltIGPhu6UgdGjhu4MgxJFhbmcgeGVtIHjDqXQuDQoNCiogKipUdeG7lWk6KiogVHXhu5VpIG5nxrDhu51pIMSRw6FuaCBnacOhLg0KDQoqICoqVGnDqnUgxJHhu4E6KiogVGnDqnUgxJHhu4EgxJHDoW5oIGdpw6EuDQoNCiogKipWxINuIGLhuqNuIMSRw6FuaCBnacOhOioqIE7hu5lpIGR1bmcgxJHDoW5oIGdpw6EuDQoNCiogKipY4bq/cCBo4bqhbmc6KiogxJBp4buDbSBz4bqjbiBwaOG6qW0gdOG7qyAxIMSR4bq/biA1Lg0KDQoqICoqSU5EIMSRxrDhu6NjIMSR4buBIHh14bqldDoqKiAtIDEgKEPDsyDEkeG7gSB4deG6pXQpLCAwIChLaMO0bmcgxJHhu4EgeHXhuqV0KS4NCg0KKiAqKlPhu5EgbMaw4bujbmcgcGjhuqNuIGjhu5NpIHTDrWNoIGPhu7FjOioqIFPhu5EgbMaw4bujbmcgcGjhuqNuIGjhu5NpIHTDrWNoIGPhu7FjLg0KDQoqICoqVMOqbiBj4bqlcCBjYW86KiogVMOqbiBj4bqlcCBjYW8gY+G7p2Egc+G6o24gcGjhuqltLg0KDQoqICoqVMOqbiBi4buZIHBo4bqtbjoqKiBUw6puIGLhu5kgcGjhuq1uIHPhuqNuIHBo4bqpbS4NCg0KKiAqKlTDqm4gbOG7m3A6KiogVMOqbiBs4bubcCBz4bqjbiBwaOG6qW0NCg0KIyMjIyAqKkLhu5ggROG7riBMSeG7hlUqKg0KDQpgYGB7cn0NCk5WMiA8LSByZWFkLmNzdihmaWxlLmNob29zZSgpLCBoZWFkZXIgPSBUKQ0KYGBgDQoNClRoZW8gbmd14buTbiBLYWdnbGUuY29tDQoNCiMjIyAqKlLDmlQgVFLDjUNIIEThu64gTEnhu4ZVKioNCg0KKipZw6p1IGPhuqd1IHLDunQgdHLDrWNoIGThu68gbGnhu4d1OioqICJUw6xtIGtp4bq/bSB0aMO0bmcgdGluIHbhu4EgxJHDoW5oIGdpw6EgcXXhuqduIMOhbyB0aMawxqFuZyBt4bqhaSDEkWnhu4duIHThu60gZMOgbmggY2hvIG7hu68gYmFvIGfhu5NtIElEIHF14bqnbiDDoW8sIHR14buVaSBj4bunYSBuZ8aw4budaSDEkcOhbmggZ2nDoSwgeOG6v3AgaOG6oW5nIHbDoCBz4buRIGzGsOG7o25nIHBo4bqjbiBo4buTaSB0w61jaCBj4buxYyIuDQoNCmBgYHtyfQ0KTlYydHVvaSA8LSBOVjJbLGMoMSwyLDMpXQ0KTlYycmF0ZSA8LSBOVjJbLGMoMSwyLDYpXQ0KTlYycGggPC0gTlYyWyxjKDEsMiw4KV0NCk5WMmEgPC0gTlYyWzcsMl0gDQpOVjJiIDwtIE5WMlsgLDFdIA0KTlYyYyA8LSBOVjJbMzo3LCBdIA0KTlYyZCA8LSBOVjJbYygyLDQsNiw4KSxjKDEsMildIA0KYGBgDQoNClNhdSBraGkgdGjhu7FjIGhp4buHbiBxdcOhIHRyw6xuaCByw7p0IHRyw61jaCBk4buvIGxp4buHdSB04burIGLhu5kgZOG7ryBsaeG7h3UgdGjGsMahbmcgbeG6oWkgxJFp4buHbiB04butIHbhu4EgcXXhuqduIMOhbyBwaOG7pSBu4buvLCBjaMO6bmcgdGEgxJHDoyBjw7MgY8ahIGjhu5lpIGtow6FtIHBow6Egbmjhu69uZyB0aMO0bmcgdGluIHF1YW4gdHLhu41uZyB24buBIGPDoWNoIG5nxrDhu51pIHRpw6p1IGTDuW5nIMSRw6FuaCBnacOhIHPhuqNuIHBo4bqpbS4NCk5o4buvbmcga+G6v3QgcXXhuqMgdOG7qyBxdcOhIHRyw6xuaCByw7p0IHRyw61jaCBk4buvIGxp4buHdSBraMO0bmcgY2jhu4kgbMOgIHPhu5EgbGnhu4d1IGtow7Qga2hhbiBtw6AgbMOgIG5ndeG7k24gdGjDtG5nIHRpbiBxdcO9IGLDoXUgxJHhu4MgxJHhu4tuaCBow6xuaCBjaGnhur9uIGzGsOG7o2Mga2luaCBkb2FuaCB2w6AgdGnhur9wIHRo4buLLiANCk5o4buvbmcgcGjDom4gdMOtY2ggbsOgeSBjdW5nIGPhuqVwIG3hu5l0IGPDoWkgbmjDrG4gc8OidSBz4bqvYyB2w6BvIHTDom0gbMO9IGPhu6dhIG5nxrDhu51pIHRpw6p1IGTDuW5nLCBnacO6cCBkb2FuaCBuZ2hp4buHcCBoaeG7g3UgcsO1IGjGoW4gduG7gSBuaOG7r25nIHnhur91IHThu5EgbsOgbyBsw6AgcXVhbiB0cuG7jW5nIMSR4buRaSB24bubaSBraMOhY2ggaMOgbmcgY+G7p2EgaOG7jS4NCg0KIyMjICoqVOG6oE8gQuG7mCBE4buuIExJ4buGVSBN4buaSSoqDQoNCioqWcOqdSBj4bqndSB04bqhbyBk4buvIGxp4buHdSBt4bubaToqKiAiVOG6oW8gbcO0IHBo4buPbmcgxJFp4buDbSDEkcOhbmggZ2nDoSBj4bunYSB04burbmcga2jDoWNoIGjDoG5nLCBiaeG6v3QgbeG7l2kgc+G7kSBzYW8gdHJvbmcgbMaw4bujdCDEkcOhbmggZ2nDoSB04buJIGzhu4cgdGh14bqtbiB24bubaSBz4buRIGzGsOG7o3QgcGjhuqNuIGjhu5NpIHTDrWNoIGPhu7FjLiBUYSBjw7MgKirEkGnhu4NtIMSRw6FuaCBnacOhID0gU+G7kSBzYW8geCBT4buRIGzGsOG7o3QgcGjhuqNuIGjhu5NpIHTDrWNoIGPhu7FjKioiDQoNCk3hu5l0IHBo4bqnbiBxdWFuIHRy4buNbmcgY+G7p2EgcGjDom4gdMOtY2ggbMOgIHThuqFvIHJhIG3hu5l0IG3DtCBow6xuaCDEkWnhu4NtIMSRw6FuaCBnacOhIGThu7FhIHRyw6puIHPhu5EgbMaw4bujbmcgc2FvIHbDoCBz4buRIGzGsOG7o25nIHBo4bqjbiBo4buTaSB0w61jaCBj4buxYy4gQ2jDum5nIHRhIHPhu60gZOG7pW5nIHRoxrAgdmnhu4duIHRpZHl2ZXJzZSB0cm9uZyBSIMSR4buDIHTDrW5oIMSRaeG7g20gxJHDoW5oIGdpw6E6DQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpOVjIkdGljaCA8LSBOVjIkUmF0aW5nKk5WMiRQb3NpdGl2ZS5GZWVkYmFjay5Db3VudA0KYGBgDQoNClbhu5tpIGPDtG5nIHRo4bupYyBuw6B5LCBjaMO6bmcgdGEgdOG6oW8gcmEgbeG7mXQgY+G7mXQgbeG7m2kgInRpY2giIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UsIHRo4buDIGhp4buHbiDEkWnhu4NtIMSRw6FuaCBnacOhIGThu7FhIHRyw6puIHPhu5Egc2FvIHbDoCBz4buRIGzGsOG7o25nIHBo4bqjbiBo4buTaSB0w61jaCBj4buxYy4gxJBp4buBdSBuw6B5IGdpw7pwIGNow7puZyB0YSBoaeG7g3UgcsO1IGjGoW4gduG7gSBjw6FjaCBtw6AgbmfGsOG7nWkgdGnDqnUgZMO5bmcgxJHDoW5oIGdpw6EgdsOgIHTGsMahbmcgdMOhYyB24bubaSBz4bqjbiBwaOG6qW0gdHLDqm4gbuG7gW4gdOG6o25nIHRoxrDGoW5nIG3huqFpIMSRaeG7h24gdOG7rS4NCg0KKipL4bq/dCBMdeG6rW4qKg0KDQpRdWEgdmnhu4djIHBow6JuIHTDrWNoIGThu68gbGnhu4d1IHbDoCB04bqhbyBtw7QgaMOsbmggxJFp4buDbSDEkcOhbmggZ2nDoSwgY2jDum5nIHRhIMSRw6MgY8OzIGPDoWkgbmjDrG4gc8OidSBz4bqvYyBoxqFuIHbhu4EgY8OhY2ggbmfGsOG7nWkgdGnDqnUgZMO5bmcgxJHDoW5oIGdpw6EgcXXhuqduIMOhbyBwaOG7pSBu4buvIHRyw6puIG7hu4FuIHThuqNuZyB0aMawxqFuZyBt4bqhaSDEkWnhu4duIHThu60uIA0KxJBp4buBdSBuw6B5IGPDsyB0aOG7gyBnacO6cCBjw6FjIG5ow6AgYsOhbiBs4bq7IHbDoCBuaMOjbiBoaeG7h3UgdGjhu51pIHRyYW5nIGhp4buDdSByw7UgaMahbiB24buBIG5odSBj4bqndSB2w6AgbW9uZyBtdeG7kW4gY+G7p2Ega2jDoWNoIGjDoG5nLCB04burIMSRw7MgY+G6o2kgdGhp4buHbiB0cuG6o2kgbmdoaeG7h20gbXVhIHPhuq9tIHRy4buxYyB0dXnhur9uLg==