1 Chương 1: Giới thiệu

1.1 Đặt vấn đề

Trên thế giới mỗi người đều nhiều hoạt động riêng của mình như học tập, du lịch, vui chơi, làm việc,… Nhưng có một vài hoạt động mà bất kỳ người nào cũng phải thực hiên là ăn uống và đi ngủ. Trong bài tiểu luận này tôi tìm hiêu và giấc ngủ của con người. Nhưng chúng ta đã biết ngủ là một trong trạng thái nghỉ ngơi tạm thời của cơ thể và nó thường xảy ra khi mỗi chúng ta cảm thấy mệt mỏi hay kiệt sức. Hay đúng hơn là một ngày 24 giờ thì chúng ta sẽ dành 8 tiếng ban đêm để ngủ để giúp mọi bộ phận trên cơ thể được thả lỏng. Nhưng nhìn dưới góc độ khoa học, thì ngủ chính là lúc não bộ của chúng ta thực hiện một số công việc quan trọng nhất. Khi ngủ có thể giúp ta điều hòa đồng hồ sinh học của cơ thể, giúp não bộ được nghỉ ngơi, loại bỏ căng thẳng mệt mỏi, tăng cường khả năng tập trung, trí nhớ và sự minh mẫn. Trong lúc này, hoạt động của tim giảm dần và nhịp điệu của hệ tuần hoàn ổn định hơn….Cũng là khi ngủ các cơ quan nội tiêt của con người tiến hành đào tải các độc tốt tích tự lại trong cơ thể.Có thể nói, việc ngủ sẽ trở thành liều thuốc bổ tốt nhất mỗi ngày. Nhưng khi chúng ta mất ngủ (tình trạng rối loạn giấc ngữ) thì sẽ có tác động xấu đến cơ thể dẫn đến nguy cơ mắc một số bệnh ung thư cao hơn, làm vết thương trên da khó lành và da cũng dễ lão hóa hơn, làm tăng nguy cơ mắc bệnh tim và tiểu đường, dễ mắc bệnh hơn vì hệ miễn dịch không hoạt động tốt khi bạn mệt mỏi, buồn ngủ sẽ khiến bạn khó chịu và cáu kỉnh. Và khi tiến hành tìm hiêu, tôi đã tìm ra bộ dữ liệu ‘Sleep Health and Lifestyle’ nói về hoạt động, thối quen và các biểu hiện của tình trạng rối loạn giấc ngủ. Tôi sẽ đi tiến hành phân tích các biến trong bộ dữ liệu này và xem xét các yếu tố ảnh hưởng đến giấc ngủ.

1.2 Tổng quan về bộ dữ liệu:

1.2.1 Mô tả dữ liệu

Bộ dữ liệu có tên là ‘Sleep Health and Lifestyle’ bao gồm 374 hàng và 13 cột, tương đương với 374 khảo sát và 13 biến. Dữ liệu có nhiều biến liên quan đến giấc ngủ và thói quen hàng ngày. Nó bao gồm các chi tiết như giới tính, tuổi tác, nghề nghiệp, thời gian ngủ, chất lượng giấc ngủ, mức độ hoạt động thể chất, mức độ căng thẳng, chỉ số BMI, huyết áp, nhịp tim, số bước hàng ngày và tình trạng rối loạn giấc ngủ có hay không.

  • Các tính năng chính của bộ dữ liệu

Số liệu toàn diện về giấc ngủ: Khám phá thời lượng, chất lượng giấc ngủ và các yếu tố ảnh hưởng đến kiểu ngủ.

Các yếu tố lối sống: Phân tích mức độ hoạt động thể chất, mức độ căng thẳng và các loại BMI.

Sức khỏe tim mạch: Kiểm tra các phép đo huyết áp và nhịp tim.

Phân tích rối loạn giấc ngủ: Xác định sự xuất hiện của các rối loạn giấc ngủ như mất ngủ và ngưng thở khi ngủ.

1.2.2 Mô tả các biến

Biến ‘Person ID’: Mã định danh cho mỗi cá nhân.

Biến ‘Grender’: Giới tính của người đó (male/female).

Biến ‘Age’: Tuổi nghề của người tính theo năm.

Biến ‘Occupation’: Nghề nghiệp hoặc nghề nghiệp của người đó. Trong dữ liệu đã quan sát trên 11 ngành nghề:

  • Accountant: nghề kế toán.

  • Doctor: nghề bác sĩ.

  • Engineer: nghề kỹ sư.

  • Lawyer: nghề luật sư.

  • Manager: người quản lí.

  • Nurse: y tá.

  • Sales Representative: đại diện kinh doanh.

  • Salesperson: nhân viên bán hàng.

  • Scientist: nhà khoa học.

  • Software Engineer: kỹ sư phần mềm.

  • Teacher: nghề giáo viên.

Biến ’ Sleep Duration’ (giờ): Số giờ một người ngủ mỗi ngày.

Biến ‘Quality of Sleep’: Đánh giá về chất lượng giấc ngủ của người tham gia khảo sát, với thang điểm từ 1 đến 10.

Biến ‘Physical Activity Level’: Số phút một người tham gia hoạt động thể chất hàng ngày( tính theo phút/ngày).

Biến ‘Stress Level’: Đánh giá chủ quan về mức độ căng thẳng mà một người trải qua, với thang điểm từ 1 đến 10.

Biến ‘BMI Category’: Hạng mục BMI của một người. Với các biểu hiện như là ‘Underweight’ là thiếu cân, ‘Normal hay Normal Weight’ là bình thường, ‘Overweight hay Obese’ là thừa cân).

Biến ‘Boold Pressure’: Đo huyết áp của một người, được biểu thị là huyết áp tâm thu trên huyết áp tâm trương (được viết tâm thu/tâm trương).

Biến ‘Heart Rate’: Nhịp tim khi nghỉ ngơi của một người tính bằng nhịp mỗi phút.

Biến ‘Daily Steps’: Số bước một người thực hiện mỗi ngày.

Biến ‘Sleep Disorder’: Sự hiện diện của chứng rối loạn giấc ngủ ở người đó. Với các biểu hiện như sau:

  • None: Cá nhân không biểu hiện bất kỳ rối loạn giấc ngủ cụ thể nào.

  • Insomnia: Cá nhân cảm thấy khó đi vào giấc ngủ hoặc duy trì giấc ngủ, dẫn đến giấc ngủ không đủ hoặc kém chất lượng.

  • Sleep Apnea: Cá nhân bị ngừng thở trong khi ngủ, dẫn đến giấc ngủ bị gián đoạn và nguy cơ sức khỏe tiềm ẩn.

1.3 Quan sát dữ liệu

Đọc dữ liệu:

dlptdldt <- read_csv('2023/dlptdldt.csv')
## Rows: 374 Columns: 13
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (5): Gender, Occupation, BMI Category, Blood Pressure, Sleep Disorder
## dbl (8): Person ID, Age, Sleep Duration, Quality of Sleep, Physical Activity...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
d <- dlptdldt

Xem cấu trúc của dữ liệu:

str(dlptdldt)
## spc_tbl_ [374 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ Person ID              : num [1:374] 1 2 3 4 5 6 7 8 9 10 ...
##  $ Gender                 : chr [1:374] "Male" "Male" "Male" "Male" ...
##  $ Age                    : num [1:374] 27 28 28 28 28 28 29 29 29 29 ...
##  $ Occupation             : chr [1:374] "Software Engineer" "Doctor" "Doctor" "Sales Representative" ...
##  $ Sleep Duration         : num [1:374] 6.1 6.2 6.2 5.9 5.9 5.9 6.3 7.8 7.8 7.8 ...
##  $ Quality of Sleep       : num [1:374] 6 6 6 4 4 4 6 7 7 7 ...
##  $ Physical Activity Level: num [1:374] 42 60 60 30 30 30 40 75 75 75 ...
##  $ Stress Level           : num [1:374] 6 8 8 8 8 8 7 6 6 6 ...
##  $ BMI Category           : chr [1:374] "Overweight" "Normal" "Normal" "Obese" ...
##  $ Blood Pressure         : chr [1:374] "126/83" "125/80" "125/80" "140/90" ...
##  $ Heart Rate             : num [1:374] 77 75 75 85 85 85 82 70 70 70 ...
##  $ Daily Steps            : num [1:374] 4200 10000 10000 3000 3000 3000 3500 8000 8000 8000 ...
##  $ Sleep Disorder         : chr [1:374] "None" "None" "None" "Sleep Apnea" ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   `Person ID` = col_double(),
##   ..   Gender = col_character(),
##   ..   Age = col_double(),
##   ..   Occupation = col_character(),
##   ..   `Sleep Duration` = col_double(),
##   ..   `Quality of Sleep` = col_double(),
##   ..   `Physical Activity Level` = col_double(),
##   ..   `Stress Level` = col_double(),
##   ..   `BMI Category` = col_character(),
##   ..   `Blood Pressure` = col_character(),
##   ..   `Heart Rate` = col_double(),
##   ..   `Daily Steps` = col_double(),
##   ..   `Sleep Disorder` = col_character()
##   .. )
##  - attr(*, "problems")=<externalptr>

Quan sát bảng dữ liệu:

datatable(dlptdldt)
d <- dlptdldt

2 Chương 2: Chọn biến phụ thuộc

2.1 Phân loại dữ liệu

Trong quá trình mô tả dữ liệu và tìm hiểu về các biến. Sau đây, tôi tiến hành xác định tính chất của biến rồi dựa vào các tiêu thức thống kê (đơn vị của tổng thể) và chia các biến của dữ liệu thành hai loại:

  • Tiêu thức thuộc tính (biến định tính): là loại tiêu thức không được biểu hiện trực tiếp bàng các con số, mang tính chất giúp chúng ta giải thích hay chứng minh. Trong bộ đữ liệu này các biến định tính là các biến như sau: ‘Gender’ chỉ giới tính,‘Occupation’ là nghề nghiệp, ‘BMI Category’ là chỉ số BMI, ‘Blood Pressure’ là nhịp tim, ‘Sleep Discorder’ là chứng rối loạn giấc ngử.

  • Tiêu thức số lượng (biến định lượng): là loại tiêu thức có biểu hiện trực tiếp bằng các con số mang tính chất giải đáp các câu hỏi. Các biến như sau trong bộ dữ liệu là định lượng: ‘Person ID’ là mã định danh ‘Age’ thể hiện tuổi, ‘Sleep Duration’ thể hiện số giờ đi ngủ, ‘Quality of Sleep’ là điểm đánh giá giấc ngủ, ‘Physical Activity Leverl’ là thời gian hoạt động, ‘Stress Level’ thể hiện độ căn thẳng, ‘Daily Steps’ là số bước đi trong ngày.

Nhìn chung, khi tiến hành phân các dữ liệu thành hai loại qua tiêu thức chủa chúng. Cho thấy trong 13 biến của bộ dưx liệu có 5 biến định tính và 7 biến định lượng.

Có thể nói một giấc ngủ tốt là rất quan trọng đối với mỗi con người, nhưng không phải ai cũng có những giấc ngủ vẹn. Nên với dữ liệu hiện tại tôi sẽ chon một biến định lượng và một biến định tính làm biến phụ thuộc để có tiến hành phân tích và đánh giá giấc ngủ của người tham gia khảo sát. Biến phụ thuôc được chọn phải là liến có liên quan đên thực trạng về giấc ngủ của những người tham giá khảo sát. Từ đấy, tôi có thể tiến hành phân tích tác động mà các biến khác lên giấc ngủ.

2.2 Chọn biến phụ thuộc

Một trong những vấn đề dẫn đến con người không có giấc ngủ ngon có thể là do người đó đang có tình trạng rối loạn giâc ngủ như cảm thấy khó đi vào giấc ngủ hoặc duy trì giấc ngủ, dẫn đến giấc ngủ không đủ hoặc kém chất lượng hay bị ngừng thở trong khi ngủ, làm cho giấc ngủ bị gián đoạn. Nên tôi chọn biến ‘Sleep Disorder’ làm biến phụ thuộc để xem xét các nguyên nhân dẫn đên tình trạng này.

2.2.1 Thông kê mô tả

table(d$`Sleep Disorder`)
## 
##    Insomnia        None Sleep Apnea 
##          77         219          78
d  |> ggplot(aes(x = `Sleep Disorder`, y = after_stat(count))) + geom_bar(fill = 'blue') + geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), stat = 'count', color = 'red', vjust = - .5) + theme_classic() + labs(x = 'Giấc ngủ', y = 'Số người')

Đế thuận tiện hơn cho việc sử dụng bộ dữ liệu, tôi thực hiện việc gán toàn bộ dữ liệu cho một biến tên d. Sau đó, thông quan việc lâp bảng và mô tả dữ liệu bằng biểu đồ cột đưng ta có thể thấy hơn 40% người có các biểu hiện rối loạn giấc ngủ. Cụ thể, người ngủ không đủ giấc (biểu hiện là Insomnia) chiếm 20,59% tương đương 77 người, người có giấc ngủ bị gián đoạn (biểu hiện là Sleep Apnea) là 20,86% có 78 người. Suy ra phần trăm người có hai triệu trứng trên là gần như bằng nhau. Còn lại, 219 người chiếm 58,56% là không có biểu hiện.

2.2.2 Mô phỏng biến có phân phối Nhị Thức

Trong bài tiểu luận này tôi tiến hành nghiên cứu giấc ngủ nên ta tạo ra một biến mới có tên Sleep và thiết lập hai biến thành hai biẻu hiện là:

  • Không có triệu chứng mất ngủ là no

  • Người có triệu chứng mất ngủ là yes: Biểu hiện này được gộp từ việc cảm thấy khó ngủ(kí hiệu là Insomnia) và gián đoạn gián đoạn giấc ngủ (kí hiệu là Sleep Apnea) của biến biến‘Sleep Disorder’

Sleep <- mapvalues(d$`Sleep Disorder`, from= c('Insomnia', 'None', 'Sleep Apnea' ), to=c('yes', 'no','yes'))
table(Sleep)
## Sleep
##  no yes 
## 219 155
d <- data.frame(d, Sleep)

Theo thống kê người có triệu chứng là 155 người và không có triệu chứng là 219 người

2.2.3 Mục tiêu

  • Các tình trạng mất ngủ có phải là cị ảnh hưởng bởi giới tính không?

  • Số lần tim người dập khi ngũ có quan ảnh hưởng thể nào đến những người mất ngủ?

  • Người cân ngủ bao lâu để không bị rối loạn giấc ngủ không?

  • Mức dộ căng thẳng nào là một mất

3 Chương 3: Thống kê mô tả cho một biến

3.1 Thống kê mô tả cho một biến

3.1.1 Thống kê cho biến định Lượng

3.1.1.1 Biến Age (tuổi nghề)

summary(d$Age)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    27.0    35.2    43.0    42.2    50.0    59.0
ggplot(data = d, mapping = aes(x = Age)) + geom_density(size = 1, alpha = 0.2, colour="#E69F00")+ labs(title = "Độ tuổi")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

First quartile = 2 có nghĩa là 25% đối tượng nghiên cứu có độ tuổi bằng hoặc nhỏ hơn 2 năm. Tương tự, Third quartile = 6 có nghĩa là 75% đối tượng có độ tuổi bằng hoặc thấp hơn 6 năm. Tất nhiên số trung vị (median) 4 cũng có nghĩa là 50% đối tượng có năm đi làm 4,77 trở xuống

3.1.1.2 Biến Sleep Duration (thời gian ngủ)

summary(d$Sleep.Duration)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    5.80    6.40    7.20    7.13    7.80    8.50
plot(d$Sleep.Duration, type='l',col = '#9C0824', axes=FALSE, xlab='', ylab='', ,main='')
box(col='#BCCFB4')
mtext('Biểu đồ thời gian ngủ', adj=0, side=3)
axis(side=1, at=c(0,50, 150, 250, 350))

Câu lệnh summary() cho biến Sleep Duration (đánh giá về mức độ căng thẳng trong công việc) của những người tham gia khảo sát, ta có thể nhận thấy người ngủ ít nhất là 5,8 h, cao nhất là điểm 8,5h, trung bình điểm số là 7,13, có 25% số người có điểm là 6,4, 50% người 7,2h, thêm vào đó có 75% người nhỏ hơn điểm 7,8.

3.1.1.3 Biến ‘Physical Activity Level’ ( hoạt động thể chất)

h <- d %>% group_by(Physical.Activity.Level) %>%  reframe(n = n()) %>%  mutate(table(d$Physical.Activity.Level), per = n/sum(n)) 
d %>% group_by(Physical.Activity.Level) %>%  reframe(n = n()) %>% mutate(table(d$Physical.Activity.Level), per = n/sum(n)) |> ggplot(aes(x = '', y = per, fill = Physical.Activity.Level)) + geom_col()

datatable(h)

Nhìn vào bản hầu hết mọi người đều tham gia các hoạt động thể chất từ 30 -90 phút 1 ngày nhưng nhiều nhất là hoạt động 60 phút mỗi ngày.

3.1.1.4 Biến ‘Quality of Sleep’(đánh giá chất lượng giấc ngủ)

summary(d$Quality.of.Sleep)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    4.00    6.00    7.00    7.31    8.00    9.00
table(d$Quality.of.Sleep)
## 
##   4   5   6   7   8   9 
##   5   7 105  77 109  71
d |> ggplot(aes(x = Quality.of.Sleep, y = after_stat(count))) + geom_bar(fill = 'skyblue') + geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), stat = 'count', color = 'magenta', vjust = - .5) + theme_classic() + labs(x = 'Điểm đánh giá giấc ngủ', y = 'Số người') + coord_flip()

Theo việc thực hiện câu lệnh summary() cho biến ‘Quality of Sleep’ (số điểm đánh giá giấc ngủ) của những người tham gia khảo sát, ta có thể nhận thấy người thấp điểm nhất là 4, cao nhất là điểm 8, trung bình điểm số là 7,31, có 25% số người có điểm là 6 năm, 50% người 7 điểm, thêm vào đó có 75% người nhỏ hơn điểm 9.

Sau đó, để biển chính xác về điểm của từng người ta có thể quan sát dữ liệu trên bản và biểu đồ cột ngang tôi nhình thấy:

  • Có 5 người 4 điểm khoảng 1,34%

  • Có 7 người 5 điểm khoảng 1,87%

  • Có 105 người 6 điểm khoảng 28,07%

  • Có 77 người 7 điểm khoảng 20,59%

  • Có 109 người 8 điểm khoảng 29,14%

  • Có 71 người 9 điểm khoảng 18,98%

Phần đông người tham gia được 7-9 điểm, nhiều nhất là người 9 điêm, trong khi đó người giấc ngủ 4 điểm là rất thấp chỉ hơn 1% trên tổng số người tham gia khảo sát.

3.1.1.5 Biến Stress Level(mức độ căng thẳng)

tmp <- table(d$Stress.Level)
w <- d |> group_by(Stress.Level) |> reframe(n = n()) |> mutate(tmp, per = n/sum(n))
datatable(w)
w |> ggplot(aes(x = '', y = per,fill = Stress.Level)) + geom_col() + coord_polar('y')

Nhìn quan các mức độ căng thẳng trong công việc của sáu cấp độ từ 3 đến 6 gần bằng nhau. Trong biến có thể thấy nhiều nhất là những người căng thẳng ở mức 3 có 71 người khoảng 18,98%, ít nhất là ở mức 6 chiếm 12,3%.

3.1.1.6 Biến Heart Rate (nhịp tim)

table(d$Heart.Rate)
## 
## 65 67 68 69 70 72 73 74 75 76 77 78 80 81 82 83 84 85 86 
## 67  2 94  2 76 69  2  2 36  2  2  5  3  2  1  2  2  3  2
table(d$Heart.Rate)/sum(table(d$Heart.Rate))
## 
##       65       67       68       69       70       72       73       74 
## 0.179144 0.005348 0.251337 0.005348 0.203209 0.184492 0.005348 0.005348 
##       75       76       77       78       80       81       82       83 
## 0.096257 0.005348 0.005348 0.013369 0.008021 0.005348 0.002674 0.005348 
##       84       85       86 
## 0.005348 0.008021 0.005348
plot(d$Heart.Rate, type='l', col = 'blue', axes=FALSE,xlab='', ylab='')
box(col='red')
mtext('Biểu đồ nhịp tim', adj=1, side=3)
axis(side=1)

Trong bảng hai chiều ta thấy, người tham gia khảo sát có nhịp tim phân bố từ 65 đến 86 nhịp/ phút. Phần lớn người tham gia khảo sát có nhịp tim ở khức đâu (65-68)nhịp/ phút.

3.1.1.7 Biến ‘Daily Steps’(số bước đi lại)

table(d$Daily.Steps)
## 
##  3000  3300  3500  3700  4000  4100  4200  4800  5000  5200  5500  5600  6000 
##     3     2     3     2     3     2     2     2    68     2     4     2    68 
##  6200  6800  7000  7300  7500  8000 10000 
##     1     3    66     2     2   101    36
mean(d$Daily.Steps)
## [1] 6817
sd <- sd(d$Daily.Steps)
sd
## [1] 1618
sd/sqrt(length(d$Daily.Steps)) 
## [1] 83.66
ggplot(data = d, aes(x = Daily.Steps)) + geom_histogram(binwidth = 1000, color = "red", fill = "blue", alpha = 0.1)

Nhìn vào thống kê ta thấy có 20 biển hiện trong biến với số bước đi trung bình là 6817 bước. Hàm sd() có kết quả 1618 được dùng để tính sai số chuẩn và độ lệch chuẩn của biến tính ra được là 83,66

3.1.1.8 Thống kê cùng lúc nhiều biến

Với với biến định lượng ta có thể thống kê các chỉ đơn giản cùng một lúc bằng lệnh summary :

fd <- data.frame(d$Age,d$Sleep.Duration,d$Quality.of.Sleep,d$Physical.Activity.Level,d$Stress.Level,d$Blood.Pressure,d$Heart.Rate,d$Daily.Steps) 
summary(fd)
##      d.Age      d.Sleep.Duration d.Quality.of.Sleep d.Physical.Activity.Level
##  Min.   :27.0   Min.   :5.80     Min.   :4.00       Min.   :30.0             
##  1st Qu.:35.2   1st Qu.:6.40     1st Qu.:6.00       1st Qu.:45.0             
##  Median :43.0   Median :7.20     Median :7.00       Median :60.0             
##  Mean   :42.2   Mean   :7.13     Mean   :7.31       Mean   :59.2             
##  3rd Qu.:50.0   3rd Qu.:7.80     3rd Qu.:8.00       3rd Qu.:75.0             
##  Max.   :59.0   Max.   :8.50     Max.   :9.00       Max.   :90.0             
##  d.Stress.Level d.Blood.Pressure    d.Heart.Rate  d.Daily.Steps  
##  Min.   :3.00   Length:374         Min.   :65.0   Min.   : 3000  
##  1st Qu.:4.00   Class :character   1st Qu.:68.0   1st Qu.: 5600  
##  Median :5.00   Mode  :character   Median :70.0   Median : 7000  
##  Mean   :5.38                      Mean   :70.2   Mean   : 6817  
##  3rd Qu.:7.00                      3rd Qu.:72.0   3rd Qu.: 8000  
##  Max.   :8.00                      Max.   :86.0   Max.   :10000

Nói chung, kết quả này đơn giản và các viết tắt cũng có thể dễ hiểu. Chú ý, trong kết quả trên, có hai chỉ số “1st Qu” và “3rd Qu” có nghĩa là first quartile (tương đương với vị trí 25%) và third quartile (tương đương với vị trí 75%) của một biến số. Với dữ liệu định tính t còn có thể thống tính về sai số chuẩn và độ lệch chuẩn. Đê tính tón đồng thời ta có thể thiết kêt một hàm như sau:

ham <- function(x){
 sd <- sd(x)
 se <- sd/sqrt(length(x))
 c(`Sai sô chuẩn`=sd,`Độ lệch chuẩn`=se)
} 
ham(d$Age)
##  Sai sô chuẩn Độ lệch chuẩn 
##        8.6731        0.4485
ham(d$Sleep.Duration)
##  Sai sô chuẩn Độ lệch chuẩn 
##       0.79566       0.04114
ham(d$Quality.of.Sleep)
##  Sai sô chuẩn Độ lệch chuẩn 
##       1.19696       0.06189
ham(d$Physical.Activity.Level)
##  Sai sô chuẩn Độ lệch chuẩn 
##        20.831         1.077
ham(d$Stress.Level)
##  Sai sô chuẩn Độ lệch chuẩn 
##       1.77453       0.09176
ham(d$Heart.Rate)
##  Sai sô chuẩn Độ lệch chuẩn 
##        4.1357        0.2139
ham(d$Daily.Steps)
##  Sai sô chuẩn Độ lệch chuẩn 
##       1617.92         83.66

Tôi cung ding hàm đẻ tiên hành vễ biểu đồ dạng bánh cho các biến:

Biểu đồ bánh

mytabl <- function(x, group) {
  tmp <- table(x$group)
  w <- x %>% 
    group_by({{group}}) %>% 
    reframe(n = n()) %>%
    mutate(tmp, per = n/sum(n)) 
  dt <- w |> ggplot(aes(x = '', y = per)) + geom_col(aes(fill={{group}}), stat = "identity", params = list(na.rm = FALSE))+ coord_polar('y') 
  list( `Đồ thị bánh`=dt)
}

mytabl(d, Age)
## Warning in geom_col(aes(fill = {: Ignoring unknown parameters: `stat` and
## `params`
## $`Đồ thị bánh`

mytabl(d, Sleep.Duration) 
## Warning in geom_col(aes(fill = {: Ignoring unknown parameters: `stat` and
## `params`
## $`Đồ thị bánh`

mytabl(d, Quality.of.Sleep)
## Warning in geom_col(aes(fill = {: Ignoring unknown parameters: `stat` and
## `params`
## $`Đồ thị bánh`

mytabl(d, Physical.Activity.Level)
## Warning in geom_col(aes(fill = {: Ignoring unknown parameters: `stat` and
## `params`
## $`Đồ thị bánh`

mytabl(d, Stress.Level)
## Warning in geom_col(aes(fill = {: Ignoring unknown parameters: `stat` and
## `params`
## $`Đồ thị bánh`

mytabl(d, Heart.Rate)
## Warning in geom_col(aes(fill = {: Ignoring unknown parameters: `stat` and
## `params`
## $`Đồ thị bánh`

mytabl(d, Daily.Steps)
## Warning in geom_col(aes(fill = {: Ignoring unknown parameters: `stat` and
## `params`
## $`Đồ thị bánh`

Ngoài ra, tôi còn tiên hành vẽ thêm các đường mật độ cho biến :

h1 <- ggplot(data = d, mapping = aes(x = Age)) + geom_density(size = 1, alpha = 0.2, colour="#E69F00")+ labs(title = "Độ tuổi")
h2 <- ggplot(data = d, mapping = aes(x = Sleep.Duration)) + geom_density(size = 1, alpha = 0.2, colour="#56B4E9")+ labs(title = "Thời gian ngủ")
h3 <- ggplot(data = d, mapping = aes(x = Quality.of.Sleep)) + geom_density(size = 1, alpha = 0.2, colour="#56B4E9")+ labs(title = "Chất lượng gian ngủ")
h4 <- ggplot(data = d, mapping = aes(x = Physical.Activity.Level)) + geom_density(size = 1, alpha = 0.2, colour="#F0E442")+ labs(title = "Hoạt động")
h5 <- ggplot(data = d, mapping = aes(x = Stress.Level)) + geom_density(size = 1, alpha = 0.2, colour="#0072B2")+ labs(title = "Căng thẳng")
h6 <- ggplot(data = d, mapping = aes(x = Heart.Rate)) + geom_density(size = 1, alpha = 0.2, colour="#D55E00")+ labs(title = "Nhịp tim")
h7 <- ggplot(data = d, mapping = aes(x = Daily.Steps)) + geom_density(size = 1, alpha = 0.2, colour="#CC79A7")+ labs(title = "Đi bộ")
plot_grid(h1, h2, h3, h4, h5, h6, h7, labels = c('A', 'B', 'C', 'D', 'E', 'F', 'G'),  size = 10)
## Warning in as_grob.default(plot): Cannot convert object of class numeric into a
## grob.

3.1.2 Thống kê cho biến định tính

3.1.2.1 Biến Grender (giới tính)

table(d$Gender)
## 
## Female   Male 
##    185    189
table(d$Gender)/sum(table(d$Gender))
## 
## Female   Male 
## 0.4947 0.5053
d |> ggplot(aes(x = Gender, y = after_stat(count))) + geom_bar(fill = 'blue') + geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), stat = 'count', color = 'magenta', vjust = - .5) + theme_classic() + labs(x = 'Giới tính', y = 'Số người') + coord_flip()

Biến gander là biến định tính, thực hiện một phép đếm đơn giản ta thấy có 185 (chiếm 50,5%) người nam và 189 người nữ (chiếm 49,5%) tham gia vào cuộc khảo sát.

3.1.2.2 Biến occupation (nghề nghiệp)

table(d$Occupation)
## 
##           Accountant               Doctor             Engineer 
##                   37                   71                   63 
##               Lawyer              Manager                Nurse 
##                   47                    1                   73 
## Sales Representative          Salesperson            Scientist 
##                    2                   32                    4 
##    Software Engineer              Teacher 
##                    4                   40
x <-  c(37, 71, 63, 47, 1, 73, 2, 32, 4, 4, 40)
labels <-  c('Accountant', 'Doctor', 'Engineer', 'Lawyer','Manager', 'Nurse', 'Sales Representative', 'Salesperson', 'Scientist', 'Software Engineer', 'Teacher')
piepercent<- round(100*x/sum(x), 1)
pie(x, labels = piepercent, main = 'Biểu đồ nghề nghiệp',col = rainbow(length(x)))
legend('topright', c('Accountant', 'Doctor', 'Engineer', 'Lawyer','Manager', 'Nurse', 'Sales Representative', 'Salesperson', 'Scientist', 'Software Engineer', 'Teacher'), cex = 0.8, fill = rainbow(length(x)))

Trong 11 ngành được ghi nhận trong bộ dữ liệu ta có thể nhận thấy ngành đại diện kinh doanh Sales Representative là nhiều nhât có 73 người (19,5%),tiếp là ngành bác sĩ Doctor với 70 người (19%), ít nhất là người quản lí Manager chỉ 1 người (0,3%)

3.1.2.3 Biến BMI Category (chỉ số cân nặng)

table(d$BMI.Category)
## 
##        Normal Normal Weight         Obese    Overweight 
##           195            21            10           148
d |> ggplot(aes(x =BMI.Category, y = after_stat(count))) + geom_bar(fill = 'green') + geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), stat = 'count', color = 'blue', vjust = - .4)  + theme_classic() + labs(title = 'Đồ Thị thể hiện thể trọng', x = 'Thể trọng', y = 'Số người')

Thống kê theo biến ‘BMI Category’: Hạng mục BMI của một người. ta thấy có 4 biểu hiện Normal, Normal Weight, Obese, Overweight. Normal là biểu hiện nhiều nhất hơn 52% #### Biến Boold Pressure (huyết áp)

table(d$Blood.Pressure)
## 
## 115/75 115/78 117/76 118/75 118/76 119/77 120/80 121/79 122/80 125/80 125/82 
##     32      2      2      2      1      2     45      1      1     65      4 
## 126/83 128/84 128/85 129/84 130/85 130/86 131/86 132/87 135/88 135/90 139/91 
##      2      2      3      2     99      2      2      3      2     27      2 
## 140/90 140/95 142/92 
##      4     65      2
ggplot(data = d) + geom_bar(mapping = aes(x = Blood.Pressure, fill = Blood.Pressure))

Có thể nói đat là biến nhiều biểu hiện nhất của bộ dữ liệu với hai 25 nhóm huyêt áp khác nhau của người tham gia khảo sát ta có thể biết nhóm nhiều nhất có 99 người có huyết áp là 130/85.

4 Chương 4: Thống kê mô tả và thống kê suy diễn cho hai biến

Sau đây, tôi tiến hành thống kê mô tả làn lượt các biến độc lập với biến phụ thục ‘Sleep Disorder’( nói chính xác hơn là biến đã được mô phỏng thành phân phối Nhị thức Sleep)

4.1 Quan hệ giữa giới tính và giấc ngủ (Sleep - Gender)

4.1.1 Đồ thị và bảng tần số

d |> ggplot(aes(x = Sleep , y = after_stat(count))) + geom_bar(fill = 'blue') + geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), stat = 'count', color = 'red', vjust = - .5) + facet_grid(. ~ Gender) + labs(x = 'Giấy ngủ', y = 'Số người')

ds <- table(d$Sleep,d$Gender)
ds
##      
##       Female Male
##   no      82  137
##   yes    103   52
ds1 <- prop.table(ds)
ds1
##      
##       Female   Male
##   no  0.2193 0.3663
##   yes 0.2754 0.1390
addmargins(ds1)
##      
##       Female   Male    Sum
##   no  0.2193 0.3663 0.5856
##   yes 0.2754 0.1390 0.4144
##   Sum 0.4947 0.5053 1.0000

Khi tiến hành nhận xét giấc ngủ và giới tính của những người tham gia khảo sát. Người đều có triệu chứng mất ngủ là nữ giới cao hơn nam giới chênh lệch nhau khoảng 14%.

4.1.2 Tỷ lệ chênh (Odd Ratio)

epitab(ds, method = 'oddsratio')
## $tab
##      
##       Female     p0 Male     p1 oddsratio  lower  upper   p.value
##   no      82 0.4432  137 0.7249    1.0000     NA     NA        NA
##   yes    103 0.5568   52 0.2751    0.3022 0.1963 0.4651 3.903e-08
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Giá trị chênh lệch cho chúng ta biết nữ giới có triệt chứng mất ngủ khoảng 55,68% với nữ giới khi không có triệt chứng mất ngủ.

4.1.3 Khoảng ước lượng cho tỉ lệ của 2 tổng thể

Thực hiện bài toán kiểm định giả thuyết sự bằng nhau về tỷ lệ ở các biến với 2 tổng thể của biến Sleep, nghĩa là chúng ta thực hiện bài toán:

Kiểm định \(H_0\):p1=p2

Ước lượng sự chênh lệch về tỷ lệ một người nam có giới tính về giấc ngủ giữa thấp và cao

tmpm <- d[d$Sleep == 'yes',]
tmpf <- d[d$Sleep == 'no',]

tmpm3 <- tmpm[tmpm$Gender == 'Male',]
tmpf3 <- tmpf[tmpf$Gender == 'Male',]

a <- c(nrow(tmpm), nrow(tmpf))
b <- c(nrow(tmpm3), nrow(tmpf3))

prop.test(b,a)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  b out of a
## X-squared = 29, df = 1, p-value = 6e-08
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.3937 -0.1864
## sample estimates:
## prop 1 prop 2 
## 0.3355 0.6256

Khoảng ước lượng tỷ lệ những người nam có “ Có triệu chứng mất ngủ” với độ tin cậy 95% là: \(-0.3937 < p < -0.1864\)

4.1.4 Kiểm định tính độc lập - kiểm định chi bình phương

Giả thuyết H0: X,Y độc lâp;

Đối thuyết H1: X,Y không độc lập

Ta tiến hành kiểm định tính độc lập của biến Sleep(X) và biến Gender(Y) sau bằng R theo các bước được kết quả:

chisq.test(ds)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  ds
## X-squared = 29, df = 1, p-value = 6e-08

Từ bảng kết quả ta có p-value = \(6.10^{-8}\) < 0,05: Bác bỏ H0

Kết luận, điểm đánh giá giấc ngủ với với giới tính của những người thực hiện khảo sát có liên hệ với nhau, với mức ý nghĩa 5%

4.2 Quan hệ giữa số tuổi và giấy ngủ

4.2.1 Đồ thị và bảng tần số

ge <- table(d$Sleep,d$Age)
ge
##      
##       27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 48 49 50 51 52
##   no   1  2  9 11 17 17 12  0 11  8 20 18 13  4 11  6 15  2  3  0  1  2  5  3
##   yes  0  3  4  2  1  0  1  2  1  4  0  2  2  0  1  3 19 28 11  3 10 18  3  6
##      
##       53 54 55 56 57 58 59
##   no  16  7  0  2  1  0  2
##   yes  1  0  2  0  8  6 14
ge1 <- prop.table(ge)
ge1
##      
##             27       28       29       30       31       32       33       34
##   no  0.002674 0.005348 0.024064 0.029412 0.045455 0.045455 0.032086 0.000000
##   yes 0.000000 0.008021 0.010695 0.005348 0.002674 0.000000 0.002674 0.005348
##      
##             35       36       37       38       39       40       41       42
##   no  0.029412 0.021390 0.053476 0.048128 0.034759 0.010695 0.029412 0.016043
##   yes 0.002674 0.010695 0.000000 0.005348 0.005348 0.000000 0.002674 0.008021
##      
##             43       44       45       48       49       50       51       52
##   no  0.040107 0.005348 0.008021 0.000000 0.002674 0.005348 0.013369 0.008021
##   yes 0.050802 0.074866 0.029412 0.008021 0.026738 0.048128 0.008021 0.016043
##      
##             53       54       55       56       57       58       59
##   no  0.042781 0.018717 0.000000 0.005348 0.002674 0.000000 0.005348
##   yes 0.002674 0.000000 0.005348 0.000000 0.021390 0.016043 0.037433
ggplot(data=d,aes(x=Age,fill=Sleep)) + geom_bar(position = "fill") +  scale_color_colorblind() + ggthemes::scale_fill_colorblind()

Trong khảo các, ta thấy độ tuổi củ người từ (27-59) tuổi. Theo biểu đồ thể hiện thì càng lớn tuổi mật độ cảu nhựng nguòi có triệu chứng mất ngủ sẽ càng cao.

4.2.2 Tỷ lệ chênh (Odd Ratio)

logistic.display(glm(factor(Sleep)~Age,family=binomial, data =d))
## 
## Logistic regression predicting factor(Sleep) : yes vs no 
##  
##                  OR(95%CI)         P(Wald's test) P(LR-test)
## Age (cont. var.) 1.12 (1.09,1.16)  < 0.001        < 0.001   
##                                                             
## Log-likelihood = -216.6794
## No. of observations = 374
## AIC value = 437.3589

Tỉ lệ chênh lệch giữa tuổi và các triệu chứng mất ngủ là 1,12 giao động trong khoảng (1.09,1.16)

4.2.3 Kiểm định chi bình phương

Giả thuyết H0: X,Y độc lâp;

Đối thuyết H1: X,Y không độc lập

Ta tiến hành kiểm định tính độc lập X và Y bằng R theo các bước được kết quả sau:

chisq.test(ge)
## Warning in chisq.test(ge): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  ge
## X-squared = 208, df = 30, p-value <2e-16

Từ bảng kết quả ta có p-value =\(2*10^{-6}\) <0,05: Bác bỏ H0

Kết luận, việc mất ngủ với số tuổi của những người thực hiện khảo sát là có quan hệ với nhau, với mức ý nghĩa 5%

4.2.4 Khoảng ước lượng cho tỉ lệ của 2 tổng thể

Thực hiện bài toán kiểm định giả thuyết sự bằng nhau về tỷ lệ ở các biến với 2 tổng thể của biến Sleep, nghĩa là chúng ta thực hiện bài toán:

Kiểm định \(H_0\):p1=p2

Ước lượng sự chênh lệch về tỷ lệ một người có thời gian ngủ trên 8h có tỉ lệ mất ngủ về giấc ngủ

tmpm3 <- tmpm[tmpm$Age > 40,]
tmpf3 <- tmpf[tmpf$Age > 40,]

a <- c(nrow(tmpm), nrow(tmpf))
b <- c(nrow(tmpm3), nrow(tmpf3))

prop.test(b,a)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  b out of a
## X-squared = 94, df = 1, p-value <2e-16
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  0.4219 0.6002
## sample estimates:
## prop 1 prop 2 
## 0.8581 0.3470

Khoảng ước lượng tỷ lệ những người có tuổi lớn hơn 40 và “ Triệu chứng mất ngủ ” có độ tin cậy 95% là:$ 0.4219 <p< 0.6002$

4.3 Quan hệ giữa nghề nghiệp và giấc ngủ

4.3.1 Đồ thị và bảng tần số

ggplot(d) + geom_bar(aes(Sleep, fill = Occupation),position =  'identity')

a <- table(d$Sleep,d$Occupation)
addmargins(a)
##      
##       Accountant Doctor Engineer Lawyer Manager Nurse Sales Representative
##   no          30     64       57     42       1     9                    0
##   yes          7      7        6      5       0    64                    2
##   Sum         37     71       63     47       1    73                    2
##      
##       Salesperson Scientist Software Engineer Teacher Sum
##   no            2         2                 3       9 219
##   yes          30         2                 1      31 155
##   Sum          32         4                 4      40 374
a1 <- prop.table(a)
a1
##      
##       Accountant   Doctor Engineer   Lawyer  Manager    Nurse
##   no    0.080214 0.171123 0.152406 0.112299 0.002674 0.024064
##   yes   0.018717 0.018717 0.016043 0.013369 0.000000 0.171123
##      
##       Sales Representative Salesperson Scientist Software Engineer  Teacher
##   no              0.000000    0.005348  0.005348          0.008021 0.024064
##   yes             0.005348    0.080214  0.005348          0.002674 0.082888

Nhìn vào bảng hai chiều và biểu đồ ta thấy y tá là nghề có nhiều triệu chứng mất ngủ nhất có 64/73 người. Trong khi đó kỉ sư là ngành có ít người bị mất ngủ có 6/63 người.

4.3.2 Kiểm định chi bình phương

Giả thuyết H0: X,Y độc lâp;

Đối thuyết H1: X,Y không độc lập

Ta tiến hành kiểm định tính độc lập X và Y bằng R theo các bước được kết quả sau:

chisq.test(a)
## Warning in chisq.test(a): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  a
## X-squared = 208, df = 10, p-value <2e-16

Từ bảng kết quả ta có p-value =\(2*10^{-6}\) <0,05: Bác bỏ H0

Kết luận, việc mất ngủ với nghề nghiệp của những người thực hiện khảo sát là có quan hệ với nhau, với mức ý nghĩa 5%

4.3.3 Khoảng ước lượng cho tỉ lệ của 2 tổng thể

Thực hiện bài toán kiểm định giả thuyết sự bằng nhau về tỷ lệ nghề y tá có bị mất ngủ không , nghĩa là chúng ta thực hiện bài toán kiểm định

Giả sử :H0:p1=p2

tmpm <- d[d$Sleep == 'yes',]
tmpf <- d[d$Sleep == 'no',]

tmpm3 <- tmpm[tmpm$Occupation == 'Nurse',]
tmpf3 <- tmpf[tmpf$Occupation == 'Nurse',]

a <- c(nrow(tmpm), nrow(tmpf))
b <- c(nrow(tmpm3), nrow(tmpf3))

prop.test(b,a)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  b out of a
## X-squared = 78, df = 1, p-value <2e-16
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  0.2845 0.4592
## sample estimates:
## prop 1 prop 2 
## 0.4129 0.0411

Ta được khoảng ước lượng tỷ lệ những người làm nghề y tá có “Tồn tại triệu chứng mất ngủ” với độ tin cậy 95% là: 0.4129< p < 0.0411

4.4 Quan hệ giữa thời gian ngủ và chứng mất ngủ (Sleep - Sleep.Duration)

4.4.1 Đồ thị và bảng tần số

ggplot(data=d,aes(x=Sleep.Duration,fill=Sleep)) + geom_histogram(binwidth = 2)   

f <- table(d$Sleep,d$Sleep.Duration)
f
##      
##       5.8 5.9  6 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.1 7.2 7.3 7.4 7.5 7.6
##   no    0   0 17  11   9   0   1   1   2   2   0   3  18  33  12   3   5   9
##   yes   2   4 14  14   3  13   8  25  18   3   5   0   1   3   2   2   0   1
##      
##       7.7 7.8 7.9  8 8.1 8.2 8.3 8.4 8.5
##   no   23  25   7  3   2   2   4  14  13
##   yes   1   3   0 10  13   9   1   0   0
f1 <- prop.table(f)
f1
##      
##            5.8      5.9        6      6.1      6.2      6.3      6.4      6.5
##   no  0.000000 0.000000 0.045455 0.029412 0.024064 0.000000 0.002674 0.002674
##   yes 0.005348 0.010695 0.037433 0.037433 0.008021 0.034759 0.021390 0.066845
##      
##            6.6      6.7      6.8      6.9      7.1      7.2      7.3      7.4
##   no  0.005348 0.005348 0.000000 0.008021 0.048128 0.088235 0.032086 0.008021
##   yes 0.048128 0.008021 0.013369 0.000000 0.002674 0.008021 0.005348 0.005348
##      
##            7.5      7.6      7.7      7.8      7.9        8      8.1      8.2
##   no  0.013369 0.024064 0.061497 0.066845 0.018717 0.008021 0.005348 0.005348
##   yes 0.000000 0.002674 0.002674 0.008021 0.000000 0.026738 0.034759 0.024064
##      
##            8.3      8.4      8.5
##   no  0.010695 0.037433 0.034759
##   yes 0.002674 0.000000 0.000000

Qua biểu đồ và bảng ta tiến hành nhận xét tình trạng giấc ngủ và thời gian ngủ của những người tham gia khảo sát cho thấy người ngủ nhiều sễ không có các triệu chứng trên,

4.4.2 Tỷ lệ chênh (Odd Ratio)

logistic.display(glm(factor(Sleep)~Sleep.Duration,family=binomial, data =d))
## 
## Logistic regression predicting factor(Sleep) : yes vs no 
##  
##                             OR(95%CI)         P(Wald's test) P(LR-test)
## Sleep.Duration (cont. var.) 0.39 (0.29,0.53)  < 0.001        < 0.001   
##                                                                        
## Log-likelihood = -231.4696
## No. of observations = 374
## AIC value = 466.9393

Tỉ lệ chênh lệch giữa thời gian ngủ và các triệu chứng mất ngủ là 0,39 giao động trong khoảng (0.29,0.53)

4.4.3 Khoảng ước lượng cho tỉ lệ của 2 tổng thể

Thực hiện bài toán kiểm định giả thuyết sự bằng nhau về tỷ lệ ở các biến với 2 tổng thể của biến Sleep, nghĩa là chúng ta thực hiện bài toán:

Kiểm định \(H_0\):p1=p2

Ước lượng sự chênh lệch về tỷ lệ một người có thời gian ngủ trên 8h có tỉ lệ mất ngủ về giấc ngủ

tmpm3 <- tmpm[tmpm$Sleep.Duration > 8,]
tmpf3 <- tmpf[tmpf$Sleep.Duration > 8,]

a <- c(nrow(tmpm), nrow(tmpf))
b <- c(nrow(tmpm3), nrow(tmpf3))

prop.test(b,a)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  b out of a
## X-squared = 0.024, df = 1, p-value = 0.9
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.09101  0.06815
## sample estimates:
## prop 1 prop 2 
## 0.1484 0.1598

Khoảng ước lượng tỷ lệ những người có tthời gian ngủ trên 8h và “ Triệu chứng mất ngủ ” có độ tin cậy 95% là:$ -0.09101 <p < 0.06815$

4.4.4 Kiểm định tính độc lập - kiểm định chi bình phương

Giả thuyết H0: X,Y độc lâp;

Đối thuyết H1: X,Y không độc lập

Ta tiến hành kiểm định tính độc lập của biến Sleep(X) và biến Sleep.Duration(Y) sau bằng R theo các bước được kết quả:

chisq.test(f)
## Warning in chisq.test(f): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  f
## X-squared = 215, df = 26, p-value <2e-16

Từ bảng kết quả ta có p-value = \(2*10^{-16}\)<0,05: Bác bỏ H0

Kết luận, điểm đánh giá giấc ngủ với thời gian ngủ của những người thực hiện khảo sát có liên hệ với nhau, với mức ý nghĩa 5%

4.5 Quan hệ với thời gian hoạt động

4.5.1 Đồ thị và bảng tần số

po <- table(d$Sleep,d$Physical.Activity.Level)
po
##      
##       30 32 35 40 42 45 47 50 55 60 65 70 75 80 85 90
##   no  60  0  0  2  2  6  1  4  6 64  0  3 36  2  0 33
##   yes  8  2  4  4  0 62  0  0  0  6  2  0 31  0  2 34
ggplot(d, aes(x=Physical.Activity.Level, fill=Sleep)) + geom_bar(position = "fill") +  scale_color_canva() + ggthemes::scale_fill_canva()

Người co các triệu chứng mất ngủ thường có số phút hoạt động là 45’ và 90’

4.5.2 Tỷ lệ chênh (Odd Ratio)

logistic.display(glm(factor(Sleep)~Physical.Activity.Level,family=binomial, data =d))
## 
## Logistic regression predicting factor(Sleep) : yes vs no 
##  
##                                      OR(95%CI)               P(Wald's test)
## Physical.Activity.Level (cont. var.) 1.0068 (0.9969,1.0169)  0.178         
##                                                                            
##                                      P(LR-test)
## Physical.Activity.Level (cont. var.) 0.177     
##                                                
## Log-likelihood = -252.8225
## No. of observations = 374
## AIC value = 509.6451

Tỉ lệ chênh lệch giữa thời gian hoạt động và các triệu chứng mất ngủ là 1.0068 giao động trong khoảng (0.9969,1.0169)

4.5.3 Khoảng ước lượng cho tỉ lệ của 2 tổng thể

Thực hiện bài toán kiểm định giả thuyết sự bằng nhau về tỷ lệ ở các biến với 2 tổng thể của biến Sleep, nghĩa là chúng ta thực hiện bài toán:

Kiểm định \(H_0\):p1=p2

Ước lượng sự chênh lệch về tỷ lệ một người có thời gian ngủ trên 8h có tỉ lệ mất ngủ về giấc ngủ

tmpm3 <- tmpm[tmpm$Physical.Activity.Level > 60,]
tmpf3 <- tmpf[tmpf$Physical.Activity.Level > 60,]

a <- c(nrow(tmpm), nrow(tmpf))
b <- c(nrow(tmpm3), nrow(tmpf3))

prop.test(b,a)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  b out of a
## X-squared = 4, df = 1, p-value = 0.05
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  0.001525 0.212999
## sample estimates:
## prop 1 prop 2 
## 0.4452 0.3379

Khoảng ước lượng tỷ lệ những người có thời gian hoạt động trên 60’ và “ Triệu chứng mất ngủ ” có độ tin cậy 95% là:\(0.001525<P< 0.212999\)

4.5.4 Kiểm định tính độc lập - kiểm định chi bình phương

Giả thuyết H0: X,Y độc lâp;

Đối thuyết H1: X,Y không độc lập

Ta tiến hành kiểm định tính độc lập của biến Sleep(X) và biến Sleep.Duration(Y) sau bằng R theo các bước được kết quả:

chisq.test(po)
## Warning in chisq.test(po): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  po
## X-squared = 157, df = 15, p-value <2e-16

Từ bảng kết quả ta có p-value = \(2*10^{-16}\)<0,05: Bác bỏ H0

Kết luận, điểm đánh giá giấc ngủ với thời gian ngủ của những người thực hiện khảo sát có liên hệ với nhau, với mức ý nghĩa 5%

4.6 Quan hệ triệu chứng mất ngủ với mức độ căn thẳng (Sleep - Stress.Level)

4.6.1 Đồ thị và bảng tần số

ggplot(d, aes(Sleep, Stress.Level, colour = Sleep)) + geom_boxplot(show.legend = F)

en <- table(d$Sleep,d$Stress.Level)
en
##      
##        3  4  5  6  7  8
##   no  40 43 57 43  3 33
##   yes 31 27 10  3 47 37
en1 <- prop.table(en)
en1
##      
##              3        4        5        6        7        8
##   no  0.106952 0.114973 0.152406 0.114973 0.008021 0.088235
##   yes 0.082888 0.072193 0.026738 0.008021 0.125668 0.098930

Khi tiến hành nhận xét điểm đánh giá giấc ngủ và mức độ căng thẳng của những người tham gia khảo sát. Cho thấy, toàn bộ người có mức độ căng thẳng thấp đều có điêm đánh giá cao.Còn lại là phần lớn người bị căng thẳng nhiều lại có điểm về giấc ngủ thấp.

4.6.2 Tỷ lệ chênh (Odd Ratio)

logistic.display(glm(factor(Sleep)~Stress.Level,family=binomial, data =d))
## 
## Logistic regression predicting factor(Sleep) : yes vs no 
##  
##                           OR(95%CI)        P(Wald's test) P(LR-test)
## Stress.Level (cont. var.) 1.24 (1.1,1.39)  < 0.001        < 0.001   
##                                                                     
## Log-likelihood = -247.5212
## No. of observations = 374
## AIC value = 499.0424

Tỉ lệ chênh lệch giữa mức độ căng thẳng và các triệu chứng mất ngủ là 1.24 giao động trong khoảng (1.1,1.39)

4.6.3 Khoảng ước lượng cho tỉ lệ của 2 tổng thể

Thực hiện bài toán kiểm định giả thuyết sự bằng nhau về tỷ lệ ở các biến với 2 tổng thể của biến Sleep, nghĩa là chúng ta thực hiện bài toán:

Kiểm định \(H_0\):p1=p2

Ước lượng sự chênh lệch về tỷ lệ một người có mức căn thẳng dưới 7 điêm có điểm đánh giá về giấc ngủ giữa thấp và cao

tmpm3 <- tmpm[tmpm$Stress.Level < 7,]
tmpf3 <- tmpf[tmpf$Stress.Level < 7,]

a <- c(nrow(tmpm), nrow(tmpf))
b <- c(nrow(tmpm3), nrow(tmpf3))

prop.test(b,a)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  b out of a
## X-squared = 58, df = 1, p-value = 3e-14
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.4756 -0.2795
## sample estimates:
## prop 1 prop 2 
## 0.4581 0.8356

Khoảng ước lượng tỷ lệ những người có mức căn thẳng dưới 7 điểm và “ Điểm đánh giá giấc ngủ thấp” có độ tin cậy 95% là: \(-0.4756<p< -0.2795\)

4.6.4 Kiểm định tính độc lập - kiểm định chi bình phương

Giả thuyết H0: X,Y độc lâp;

Đối thuyết H1: X,Y không độc lập

Ta tiến hành kiểm định tính độc lập của biến Sleep(X) và biến Stress.Level(Y) sau bằng R theo các bước được kết quả:

chisq.test(en)
## 
##  Pearson's Chi-squared test
## 
## data:  en
## X-squared = 104, df = 5, p-value <2e-16

Từ bảng kết quả ta có p-value =\(2*10^{-16}\)<0,05: Bác bỏ H0

Kết luận, điểm đánh giá giấc ngủ với mức đô căng thẳng của những người thực hiện khảo sát có liên hệ với nhau, với mức ý nghĩa 5%

4.7 Quan hệ với chỉ số BMI

4.7.1 Đồ thị và bảng tần số

ggplot(d) + geom_bar(aes(Sleep, fill = BMI.Category),position =  'dodge')

c <- table(d$Sleep,d$BMI.Category)
c
##      
##       Normal Normal Weight Obese Overweight
##   no     183            17     0         19
##   yes     12             4    10        129
c1 <- prop.table(c)
c1
##      
##        Normal Normal Weight   Obese Overweight
##   no  0.48930       0.04545 0.00000    0.05080
##   yes 0.03209       0.01070 0.02674    0.34492
addmargins(c1)
##      
##        Normal Normal Weight   Obese Overweight     Sum
##   no  0.48930       0.04545 0.00000    0.05080 0.58556
##   yes 0.03209       0.01070 0.02674    0.34492 0.41444
##   Sum 0.52139       0.05615 0.02674    0.39572 1.00000

Qua việc quan sát biểu đồ bảng hai chiều về thể trọng tính bằng BMI của người tham gia khảo sát với chức mất ngủ. Ta thấy, người người thừa cân có các triệt chứng mất ngủ có 139 người chiếm 37,16% gấp 8,7 lân người có cân nặng bình thường có các triệt chứng mất ngủ.

4.7.2 Khoảng ước lượng cho tỉ lệ của 2 tổng thể

Thực hiện bài toán kiểm định giả thuyết sự bằng nhau về tỷ lệ ở các biến với 2 tổng thể của biến Sleep, nghĩa là chúng ta thực hiện bài toán:

Kiểm định \(H_0\):p1=p2

Ước lượng sự chênh lệch về tỷ lệ BMI với triệu chứng mất ngủ.

tmpm3 <- tmpm[tmpm$BMI.Category == 'Normal',]
tmpf3 <- tmpf[tmpf$BMI.Category == 'Normal',]

a <- c(nrow(tmpm), nrow(tmpf))
b <- c(nrow(tmpm3), nrow(tmpf3))

prop.test(b,a)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  b out of a
## X-squared = 206, df = 1, p-value <2e-16
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.8284 -0.6880
## sample estimates:
##  prop 1  prop 2 
## 0.07742 0.83562

Khoảng ước lượng tỷ lệ những người chỉ số BMI là ‘Normal’ có “Tồn tại triệu chứng mất ngủ” với độ tin cậy 95% là:\(-0.8284<p< -0.6880\)

4.7.3 Kiểm định tính độc lập - kiểm định chi bình phương

Giả thuyết H0: X,Y độc lâp;

Đối thuyết H1: X,Y không độc lập

Ta tiến hành kiểm định tính độc lập của biến Sleep(X) và biến BMI.Category (Y) sau bằng R theo các bước được kết quả:

chisq.test(c)
## Warning in chisq.test(c): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  c
## X-squared = 246, df = 3, p-value <2e-16

Từ bảng kết quả ta có p-value =\(2*10^{-16}\) <0,05: Bác bỏ \(H_0\) Kết luận, việc mất ngủ với BMI bình thường của những người thực hiện khảo sát có liên hệ với nhau, với mức ý nghĩa 5%

4.8 Quan hệ với huyết áp

4.8.1 Đồ thị và bảng tần số

bl <- table(d$Sleep,d$Blood.Pressure)
bl
##      
##       115/75 115/78 117/76 118/75 118/76 119/77 120/80 121/79 122/80 125/80
##   no      30      2      2      2      1      2     43      1      1     63
##   yes      2      0      0      0      0      0      2      0      0      2
##      
##       125/82 126/83 128/84 128/85 129/84 130/85 130/86 131/86 132/87 135/88
##   no       4      2      2      3      0     54      0      0      0      0
##   yes      0      0      0      0      2     45      2      2      3      2
##      
##       135/90 139/91 140/90 140/95 142/92
##   no       2      0      0      5      0
##   yes     25      2      4     60      2
ggplot(d, aes(Blood.Pressure, fill = Sleep)) + geom_bar(position = 'dodge')

Người có huyết áp cao thì xác suất những người có triệu chứng mất ngủ càng lớn

4.8.2 Khoảng ước lượng cho tỉ lệ của 2 tổng thể

Thực hiện bài toán kiểm định giả thuyết sự bằng nhau về tỷ lệ ở các biến với 2 tổng thể của biến Sleep, nghĩa là chúng ta thực hiện bài toán:

Kiểm định \(H_0\):p1=p2

Ước lượng sự chênh lệch về tỷ lệ BMI với triệu chứng mất ngủ.

tmpm3 <- tmpm[tmpm$Blood.Pressure == '120/80',]
tmpf3 <- tmpf[tmpf$Blood.Pressure == '120/80',]

a <- c(nrow(tmpm), nrow(tmpf))
b <- c(nrow(tmpm3), nrow(tmpf3))

prop.test(b,a)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  b out of a
## X-squared = 27, df = 1, p-value = 2e-07
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.2445 -0.1224
## sample estimates:
## prop 1 prop 2 
## 0.0129 0.1963

Khoảng ước lượng tỷ lệ những người chỉ số huyét áp ‘120/80’ có “Tồn tại triệu chứng mất ngủ” với độ tin cậy 95% là:\(-0.2445<p< -0.1224\)

4.8.3 Kiểm định tính độc lập - kiểm định chi bình phương

Giả thuyết H0: X,Y độc lâp;

Đối thuyết H1: X,Y không độc lập

Ta tiến hành kiểm định tính độc lập của biến Sleep(X) và biến Blood.Pressure (Y) sau bằng R theo các bước được kết quả:

chisq.test(bl)
## Warning in chisq.test(bl): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  bl
## X-squared = 223, df = 24, p-value <2e-16

Từ bảng kết quả ta có p-value =\(2*10^{-16}\) <0,05: Bác bỏ \(H_0\) Kết luận, việc mất ngủ với huyết âp của những người thực hiện khảo sát có liên hệ với nhau, với mức ý nghĩa 5%

4.9 Quan hệ nhịp tim và việc mất ngủ (Sleep- Heart Rate )

4.9.1 Đồ thị và bảng tần số

b <- table(d$Sleep,d$Heart.Rate)
b
##      
##       65 67 68 69 70 72 73 74 75 76 77 78 80 81 82 83 84 85 86
##   no  41  2 62  2 70 30  2  0  6  2  2  0  0  0  0  0  0  0  0
##   yes 26  0 32  0  6 39  0  2 30  0  0  5  3  2  1  2  2  3  2
b1 <- prop.table(b)
b1
##      
##             65       67       68       69       70       72       73       74
##   no  0.109626 0.005348 0.165775 0.005348 0.187166 0.080214 0.005348 0.000000
##   yes 0.069519 0.000000 0.085561 0.000000 0.016043 0.104278 0.000000 0.005348
##      
##             75       76       77       78       80       81       82       83
##   no  0.016043 0.005348 0.005348 0.000000 0.000000 0.000000 0.000000 0.000000
##   yes 0.080214 0.000000 0.000000 0.013369 0.008021 0.005348 0.002674 0.005348
##      
##             84       85       86
##   no  0.000000 0.000000 0.000000
##   yes 0.005348 0.008021 0.005348
ggplot(data = d) + geom_histogram(aes(x=Heart.Rate,fill=factor(Sleep)),bins=10, position = 'stack',alpha = 0.5)

Và nhìn vào biểu đồ histogram và bảng ta có thể thấy bắt đầu từ 78 nhịp/phút trở đi người đều là những người có triệu chứng mất ngủ. Kết luận, nhịp tim có ảnh hưởng đến giấc ngủ.

ười chiếm 64,44% và nghười có nhịp tim đập nhanh (kí hiệu là nhiều) là 133 người có 35,56%.

4.9.2 Tỷ lệ chênh (Odd Ratio)

logistic.display(glm(factor(Sleep)~Heart.Rate,family=binomial, data =d))
## 
## Logistic regression predicting factor(Sleep) : yes vs no 
##  
##                         OR(95%CI)        P(Wald's test) P(LR-test)
## Heart.Rate (cont. var.) 1.2 (1.13,1.28)  < 0.001        < 0.001   
##                                                                   
## Log-likelihood = -232.2174
## No. of observations = 374
## AIC value = 468.4348

Tỉ lệ chênh lệch giữa nhịp tim và các triệu chứng mất ngủ là 1,2 giao động trong khoảng (1.13,1.28)

4.9.3 Khoảng ước lượng cho tỉ lệ của 2 tổng thể

Thực hiện bài toán kiểm định giả thuyết sự bằng nhau về tỷ lệ ở các biến với 2 tổng thể của biến Sleep, nghĩa là chúng ta thực hiện bài toán:

Kiểm định \(H_0\):p1=p2

Ước lượng sự chênh lệch về tỷ lệ nhịp tim đập hơn 69 nhịp/phút với triệu chứng mất ngủ.

tmpm3 <- tmpm[tmpm$Heart.Rate > 69,]
tmpf3 <- tmpf[tmpf$Heart.Rate > 69,]

a <- c(nrow(tmpm), nrow(tmpf))
b <- c(nrow(tmpm3), nrow(tmpf3))

prop.test(b,a)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  b out of a
## X-squared = 4.4, df = 1, p-value = 0.04
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  0.007953 0.220828
## sample estimates:
## prop 1 prop 2 
## 0.6258 0.5114

Khoảng ước lượng tỷ lệ những người nhịp tim có “Tồn tại triệu chứng mất ngủ” với độ tin cậy 95% là:0.007953 < p< 0.220828

4.9.4 Kiểm định tính độc lập - kiểm định chi bình phương

Giả thuyết H0: X,Y độc lâp;

Đối thuyết H1: X,Y không độc lập

Ta tiến hành kiểm định tính độc lập của biến Sleep(X) và biến Heart.Rate (Y) sau bằng R theo các bước được kết quả:

chisq.test(b)
## 
##  Chi-squared test for given probabilities
## 
## data:  b
## X-squared = 1.1, df = 1, p-value = 0.3

Từ bảng kết quả ta có p-value =\(7*10^{-15}\) <0,05: Bác bỏ \(H_0\) Kết luận, việc mất ngủ với nhịp tim khi ngủ của những người thực hiện khảo sát có liên hệ với nhau, với mức ý nghĩa 5%

4.10 Quan hệ với số bước đi hằng ngày

4.10.1 Đồ thị và bảng tần số

lo <- table(d$Sleep,d$Daily.Steps)
lo
##      
##       3000 3300 3500 3700 4000 4100 4200 4800 5000 5200 5500 5600 6000 6200
##   no     0    0    0    0    0    0    2    0   61    0    4    2    7    1
##   yes    3    2    3    2    3    2    0    2    7    2    0    0   61    0
##      
##       6800 7000 7300 7500 8000 10000
##   no     3   36    2    2   93     6
##   yes    0   30    0    0    8    30
ggplot(d, aes(x=Daily.Steps, fill=Sleep)) + geom_bar(position = "fill") +  scale_color_excel_new() + ggthemes::scale_fill_excel_new()

Theo thống kê và biểu đồ hàm mật độ cho thấy tât các những người hoạt động đi lại ít hơn 4200 bước đều có các triệu chứng mất ngủ

4.10.2 Tỷ lệ chênh (Odd Ratio)

logistic.display(glm(factor(Sleep)~Daily.Steps,family=binomial, data =d))
## 
## Logistic regression predicting factor(Sleep) : yes vs no 
##  
##                          OR(95%CI)          P(Wald's test) P(LR-test)
## Daily.Steps (cont. var.) 1 (0.9998,1.0001)  0.607          0.607     
##                                                                      
## Log-likelihood = -253.6019
## No. of observations = 374
## AIC value = 511.2038

Tỉ lệ chênh lệch giữa số bước đi trong ngày và các triệu chứng mất ngủ là 1 giao động trong khoảng (0.9998,1.0001)

4.10.3 Khoảng ước lượng cho tỉ lệ của 2 tổng thể

Thực hiện bài toán kiểm định giả thuyết sự bằng nhau về tỷ lệ ở các biến với 2 tổng thể của biến Sleep, nghĩa là chúng ta thực hiện bài toán:

Kiểm định \(H_0\):p1=p2

Ước lượng sự chênh lệch về tỷ lệ nhịp tim đập hơn 69 nhịp/phút với triệu chứng mất ngủ.

tmpm3 <- tmpm[tmpm$Daily.Steps > 5000,]
tmpf3 <- tmpf[tmpf$Daily.Steps > 5000,]

a <- c(nrow(tmpm), nrow(tmpf))
b <- c(nrow(tmpm3), nrow(tmpf3))

prop.test(b,a)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  b out of a
## X-squared = 8.2, df = 1, p-value = 0.004
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  0.04463 0.22103
## sample estimates:
## prop 1 prop 2 
## 0.8452 0.7123

Khoảng ước lượng tỷ lệ những người nhịp tim có “Tồn tại triệu chứng mất ngủ” với độ tin cậy 95% là:\(0.04463<p< 0.22103\)

4.10.4 Kiểm định tính độc lập - kiểm định chi bình phương

Giả thuyết H0: X,Y độc lâp;

Đối thuyết H1: X,Y không độc lập

chisq.test(lo)
## Warning in chisq.test(lo): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  lo
## X-squared = 204, df = 19, p-value <2e-16

Từ bảng kết quả ta có p-value =\(7*10^{-15}\) <0,05: Bác bỏ \(H_0\) Kết luận, việc mất ngủ với số bước đi của những người thực hiện khảo sát có liên hệ với nhau, với mức ý nghĩa 5%

5 Chương 5: Các mô hình hồi quy

5.1 Mô hìnhhình hồi quy cổ điển - đồ thị dạng scatter

ggplot(data = d, aes(x = Quality.of.Sleep, y = Sleep.Duration)) + geom_smooth(formula = y ~ x, method = 'lm', color = 'green') + geom_point(color = 'red')

ggplot(data = d, aes(x = Quality.of.Sleep, y = Stress.Level)) + geom_smooth(formula = y ~ x, method = 'lm', color = 'green') + geom_point(color = 'red')

ggplot(data = d) +
  geom_bin2d(mapping = aes(x = Stress.Level, y = Heart.Rate))

ggplot(data = d,mapping = aes(          x = Quality.of.Sleep,y = Daily.Steps, color = Stress.Level)) + geom_point( size = 1,alpha = 0.5) +geom_smooth(method = "lm",size = 2)
## `geom_smooth()` using formula = 'y ~ x'
## Warning: The following aesthetics were dropped during statistical transformation: colour
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

Qua biểu đồ ta thấy các biến như Quality.of.Sleep, Sleep.Duration ,Stress.Level, Heart.Rate, Daily.Steps đèu có liên kêt với nháu,

5.2 Hồi quy tuyến tính cho biến có dữ liệu nhị phân và các biến khác

5.2.1 Xây dựng và mục đích của mô hình

Thiết kế mô hình hồi quy về các yếu tố dẫn đền triệt chứng mất ngủ. Thông quan kiểm định Chi bình phương (Chi squared test, chisq.test) trong dữ liệu ta nhận ra biến phụ thuộc Sleep Disorder hiện tại là biến Sleep với dữ liệu nhị phân với các biến đều có liên quan đến nhau (trong dữ liệu còn có biến ID nhưng đây là biến dùng khai báo số thứ tự nên không có ý nghĩa thống kế).

Suy ra, hiện tại ta có các biến là:

  • Biến ‘Sleep Disorder’: biến phụ thuộc thể hiện triệu chứng mất ngủ

=> Biến ‘Sleep’: biến nhị phân nhận giá trị 1 ( là ‘yes’) tương đương với biểu hiện None , nhận giá trị 0(là ‘no’) tương đương với biểu hiện Insomnia và Sleep Apnea của biến ‘Sleep Disorder’.

  • Biến ‘Age’: Tuổi nghề của người tính theo năm.

  • Biến ’Gender: là biến định tính với kiểu dữ liệu kí tự với 2 biểu hiện có thể khai báo biến giả nhị phân như sau:“Female” nhận giá trị 0 và “Male” nhân giá trị 1.

  • Biến ‘Occupation’: thể hiện nghề nghiệp là dữ liệu định tính chỉ có thể hồi quy với dữ liệu chéo gộp

  • Biến ’ Sleep Duration’ (giờ): Số giờ một người ngủ mỗi ngày.

  • Biến ‘Quality of Sleep’: Đánh giá về chất lượng giấc ngủ

  • Biến ‘Quality of Sleep’: Đánh giá về chất lượng giấc ngủ

  • Biến ‘Stress Level’: Đánh giá chủ quan về mức độ căng thẳng

  • Biến ‘BMI Category’: BMI của một người là biến định lượng nhưng ở đây các biến nói về chỉ số thể trọng của cơ thể có thứ bậc nên có thể gán điểm số cho các thuộc tính.

  • Biến ‘Boold Pressure’: Đo huyết áp của một người. huyết áp được liệt kê theo thứ tự tăng dần nên có thể tiến hành gán điểm số cho các thuộc tính

  • Biến ‘Heart Rate’: là dữ liệu số nhịp tim

  • Biến ‘Daily Steps’: Số bước một người thực hiện mỗi ngày

Do sự khác biệt về tính chất sau đây tôi sẽ xây dựng 4 mô hình đa biến:

  • Mô hình logistic có biến giải thích là biến định tính như biến Sleep ~ Occupation +Age

  • Mô hình logistic có biến giải thích là biến định tính theo phương pháp gán điểm số cho các thuộc tính Khi biến định tính có các thuộc tính có thứ tự. Sleep ~ BMI Category + Quality of Sleep

  • Mô hình logistic có biến giải thích là biến định tính theo phương pháp gán điểm số cho các thuộc tính Khi biến định tính có các thuộc tính có mức độ so sánh. Sleep ~ Boold Pressure + Physical Activity Leverl

  • Hồi quy mô hình đa biến của của biến Sleep~ Gender+ Sleep.Duration +Stress.Level +Heart.Rate.

5.2.2 Mô hình logistic phương pháp dùng biến giả nhị phân biến Sleep ~ Occupation+ Age

Với biến định tính Occupation có k thuộc tính thì sử dụng k – 1 biến giả nhị phân:

\(D_1\) = {1 là ngành Dortor ; 0 nếu là ngành khác}

\(D_2\) = {1 là ngành Engineer ; 0 nếu là ngành khác}

\(D_3\) = {1 là ngành Lawyer ; 0 nếu là ngành khác}

\(D_4\) = {1 là ngành Manager ; 0 nếu là ngành khác}

\(D_5\) = {1 là ngành Nurse ; 0 nếu là ngành khác}

\(D_6\) = {1 là ngành Sales Representative ; 0 nếu là ngành khác}

\(D_7\) = {1 là ngành Salesperson ; 0 nếu là ngành khác}

\(D_8\) = {1 là ngành Scientist ; 0 nếu là ngành khác}

\(D_9\) = {1 là ngành Software Enginee ; 0 nếu là ngành khác}

\(D_{10}\) = {1 là ngành Teacher ; 0 nếu là ngành khác}

Hồi quy logistic về ảnh hưởng của nghề nghiêp , tuổi đối với sự việc xuất hiện các triệu chứng mất ngủ, trong đó biến nghề nghiệp được đại diện bởi 10 biến giả nhị phân

\(log(\frac{π}{1−π})= \beta_0+\beta1*x_1+c_1*D_1+c_2*D_2+c_3*D_3+.+..c_{10}*D_{10}\)

oc <- glm(factor(Sleep) ~ Age+Occupation, family = binomial(link = 'logit'), data = d )
oc
## 
## Call:  glm(formula = factor(Sleep) ~ Age + Occupation, family = binomial(link = "logit"), 
##     data = d)
## 
## Coefficients:
##                    (Intercept)                             Age  
##                        -6.0571                          0.1131  
##               OccupationDoctor              OccupationEngineer  
##                        -0.0576                         -1.6825  
##               OccupationLawyer               OccupationManager  
##                        -0.5451                        -14.5995  
##                OccupationNurse  OccupationSales Representative  
##                         2.4514                         18.4557  
##          OccupationSalesperson             OccupationScientist  
##                         3.8425                          2.2675  
##    OccupationSoftware Engineer               OccupationTeacher  
##                         1.3778                          2.6332  
## 
## Degrees of Freedom: 373 Total (i.e. Null);  362 Residual
## Null Deviance:       507 
## Residual Deviance: 254   AIC: 278

Từ đó nhận được mô hình hồi quy ước lượng:

\(log(\frac{π}{1−π})= -6.0517+0.1131x_1-0.0576c_1-1.6825c_2-0.5451c_3- 14.5995 c_4+ 2.4514c_5 +18.4557c_6 +3.8425c_7+2.2675 c_8+1.3778 * c_9+2.6332 * c_{1}\)

Mô hình ước lượng đối với những người làm Doctor là: \(log(\frac{π}{1−π})= -6.1147+ 0.1131 Age\)

  do đó xác suất mất của nhóm ngành bác sĩ trung bình ước tính là:

\(\pi(x_1,1)=[1 + exp (-6.1147+ 0.1131 Age])^{-1}\)

Mô hình ước lượng đối với những người làm Engineer là: \(log(\frac{π}{1−π})= -7.7342+ 0.1131 Age\)

  do đó xác suất mất của nhóm ngành Engineer ước tính là:

\(\pi(x_1,1)=[1 + exp (-7.7342+ 0.1131 Age])^{-1}\)

Mô hình ước lượng đối với những người làm Lawyer là: \(log(\frac{π}{1−π})= -6.5968+ 0.1131 Age\)

  do đó xác suất mất của nhóm ngành Lawyer ước tính là:

\(\pi(x_1,1)=[1 + exp (-6.5968+ 0.1131 Age])^{-1}\)

Mô hình ước lượng đối với những người làm Manager là: \(log(\frac{π}{1−π})= -20.6512+ 0.1131 Age\)

  do đó xác suất mất của nhóm ngành  Manager  ước tính là:

\(\pi(x_1,1)=[1 + exp (-20.6512+ 0.1131 Age])^{-1}\)

Mô hình ước lượng đối với những người làm Nurse là: \(log(\frac{π}{1−π})= -3.6003+ 0.1131 Age\)

  do đó xác suất mất của nhóm ngành y tá trung bình ước tính là:

\(\pi(x_1,1)=[1 + exp (-3.6003+ 0.1131 Age])^{-1}\)

Mô hình ước lượng đối với những người làm Sales Representative là: \(log(\frac{π}{1−π})= 12.404+ 0.1131 Age\)

  do đó xác suất mất của nhóm ngành Sales Representative ước tính là:

\(\pi(x_1,1)=[1 + exp (12.404+ 0.1131 Age])^{-1}\)

Mô hình ước lượng đối với những người làm Salesperson là: \(log(\frac{π}{1−π})= -2.2092+ 0.1131 Age\)

  do đó xác suất mất của nhóm ngành Salesperson ước tính là:

\(\pi(x_1,1)=[1 + exp (-2.2092+ 0.1131 Age])^{-1}\)

Mô hình ước lượng đối với những người làm Scientist là: \(log(\frac{π}{1−π})= -3.7842+ 0.1131 Age\)

  do đó xác suất mất của nhóm ngành Scientist  ước tính là:

\(\pi(x_1,1)=[1 + exp (-3.7842+ 0.1131 Age])^{-1}\)

Mô hình ước lượng đối với những người làm Software Engineer là: \(log(\frac{π}{1−π})= -4.6739+ 0.1131 Age\)

  do đó xác suất mất của nhóm ngành Software Engineer ước tính là:

\(\pi(x_1,1)=[1 + exp (-4.6739+ 0.1131 Age])^{-1}\)

Mô hình ước lượng đối với những người làm Teacher là: \(log(\frac{π}{1−π})= -3.4185+ 0.1131 Age\)

  do đó xác suất mất của nhóm ngành giáo viên trung bình ước tính là:

\(\pi(x_1,1)=[1 + exp (-3.4185+ 0.1131 Age])^{-1}\)

5.2.3 Mô hình hồi quy logistic với biến định tính có các thuộc tính

5.2.3.1 Biến định tính có các thuộc tính có thứ tự

Hồi quy logistic về ảnh hưởng của điểm đánh giá giấc ngủ Quality of Sleep, chỉ số BMI Category (biến định tính có cấp độ thứ tự) đối với sự xuất hiện triệu chứng mất ngủ.Trong đó biến BMI được gán điểm {1, 2, 3, 4} tăng dần theo thể trọng của cơ thể:

\(log(\frac{π}{1−π})= \beta_0+\beta1*x_1+\beta2*BMI\)

d$BMI.Category <- mapvalues(d$BMI.Category,from= c( 'Normal', 'Normal Weight', 'Obese', 'Overweight'),to=c('1','2','4','3'))

d$BMI.Category <- as.numeric(as.character(d$BMI.Category))

Chạy ước lượng cho ra mô hình hồi quy ước lượng:

log <- glm(factor(Sleep) ~ Quality.of.Sleep+ BMI.Category  , family = binomial(link = 'logit'), data = d )
log
## 
## Call:  glm(formula = factor(Sleep) ~ Quality.of.Sleep + BMI.Category, 
##     family = binomial(link = "logit"), data = d)
## 
## Coefficients:
##      (Intercept)  Quality.of.Sleep      BMI.Category  
##           -3.444            -0.233             2.302  
## 
## Degrees of Freedom: 373 Total (i.e. Null);  371 Residual
## Null Deviance:       507 
## Residual Deviance: 225   AIC: 231

\(log(\frac{π}{1−π})=-3.444 -0.233Quality.of.Sleep + 2.302 BMI.Category\)

Kết quả hồi quy cho thấy cả điểm đánh giá giấc ngủ Quality of Sleep, chỉ số BMI Category đều thực sự có ảnh hưởng đến xác suất có triệu chứng mất ngủ.\(B_2 = 2.302 > 0\) và từ cách gán điểm cho biến định tính BMI tăng dần theo thể trọng của cơ thể cho thấy xác có triệu chứng mất ngủ tằng khi BMI tăng

Mô hình hồi quy logistic ước lượng đối với những BMI(Normal=1): \(log(\frac{π}{1−π})= -0.142 -0.233Quality.of.Sleep\) do đó xác suất mất ngủ của nhóm Normal được ước tính là: \(\pi(x_1,1)=[1 + exp (-0.142-0.233Quality.of.Sleep)^{-1}\)

Mô hình hồi quy logistic ước lượng đối với những BMI(Normal weight =2): \(log(\frac{π}{1−π})= 3.16 -0.233Quality.of.Sleep\) do đó xác suất mất ngủ của nhóm Normal weight được ước tính là: \(\pi(x_1,1)=[1 + exp (3.16-0.233Quality.of.Sleep)^{-1}\)

Mô hình hồi quy logistic ước lượng đối với những BMI(Overweight=3’): \(log(\frac{π}{1−π})= 6.462 -0.233Quality.of.Sleep\) do đó xác suất mất ngủ của nhóm Overweight được ước tính là: \(\pi(x_1,1)=[1 + exp (6.462-0.233Quality.of.Sleep)^{-1}\)

Mô hình hồi quy logistic ước lượng đối với những BMI (Obese=4): \(log(\frac{π}{1−π})= 9.764 -0.233Quality.of.Sleep\) do đó xác suất mất ngủ của nhóm Obese được ước tính là: \(\pi(x_1,1)=[1 + exp (9.764-0.233Quality.of.Sleep)^{-1}\)

5.2.3.2 Biến định tính có các thuộc tính có mức độ so sánh

Hồi quy logistic về ảnh hưởng của thời guan hoạt động Physical Activity Leverl, huyết áp Boold Pressure (biến định tính có cmức độ so sánh ) được viết tâm thu/tâm trương đối với sự xuất hiện triệu chứng mất ngủ.Trong đó biến huyết áp được gán điểm {1, 2, …,24, 25} tăng dần theo thể trọng của cơ thể:

d$Blood.Pressure <- mapvalues(d$Blood.Pressure, from = c('115/75', '115/78', '117/76', '118/75', '118/76', '119/77', '120/80', '121/79', '122/80', '125/80', '125/82', '126/83', '128/84', '128/85', '129/84', '130/85', '130/86', '131/86', '132/87', '135/88', '135/90', '139/91', '140/90', '140/95', '142/92'), to = c('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25'))
d$Blood.Pressure <- as.numeric(as.character(d$Blood.Pressure))

loge <- glm(factor(Sleep) ~ Physical.Activity.Level +Blood.Pressure , family = binomial(link = 'logit'), data = d )
loge
## 
## Call:  glm(formula = factor(Sleep) ~ Physical.Activity.Level + Blood.Pressure, 
##     family = binomial(link = "logit"), data = d)
## 
## Coefficients:
##             (Intercept)  Physical.Activity.Level           Blood.Pressure  
##                 -5.2986                  -0.0539                   0.5154  
## 
## Degrees of Freedom: 373 Total (i.e. Null);  371 Residual
## Null Deviance:       507 
## Residual Deviance: 232   AIC: 238

Chạy ước lượng cho ra mô hình hồi quy ước lượng:

\(log(\frac{π}{1−π})=-5.2986-0.0539 Physical.Activity.Level +0.5154 Blood.Pressure\)

Kết quả hồi quy cho thấy cả thời guan hoạt động Physical Activity Leverl, huyết áp Boold Pressure đều thực sự có ảnh hưởng đến xác suất có triệu chứng mất ngủ.\(B_2 = 0.5154 > 0\) và từ cách gán điểm cho biến định tính là huyết áp tăng dần theo thể trọng của cơ thể cho thấy xác có triệu chứng mất ngủ tăng khi huyết áp tăng

Mô hình hồi quy logistic ước lượng đối với những Boold Pressure =1: \(log(\frac{π}{1−π})= -4.7832-0.0539 Physical.Activity.Level\) do đó xác suất mất ngủ được ước tính là: \(\pi(x_1,1)=[1 + exp (-4.7832-0.0539 Physical.Activity.Level)^{-1}\)

Mô hình hồi quy logistic ước lượng đối với những Boold Pressure=2: \(log(\frac{π}{1−π})= -4.2678-0.0539 Physical.Activity.Level\) do đó xác suất mất ngủ được ước tính là: \(\pi(x_1,1)=[1 + exp (-4.2678-0.0539 Physical.Activity.Level)^{-1}\)

Mô hình hồi quy logistic ước lượng đối với những Boold Pressure=24: \(log(\frac{π}{1−π})= 7.071-0.0539 Physical.Activity.Level\) do đó xác suất mất ngủ được ước tính là: \(\pi(x_1,1)=[1 + exp (7.071-0.0539 Physical.Activity.Level)^{-1}\)

Mô hình hồi quy logistic ước lượng đối với những Boold Pressure2=5: \(log(\frac{π}{1−π})= 7.5864-0.0539 Physical.Activity.Level\) do đó xác suất mất ngủ được ước tính là: \(\pi(x_1,1)=[1 + exp (7.5864-0.0539 Physical.Activity.Level)^{-1}\)

5.2.4 Mô hình hồi quy đa biến với các hàm liên kết khác nhau

5.2.4.1 Mô hình Logit

Tại đây ta tiến hành hồi quy với hàm logit \(logit(π)=log(\frac{π}{1−π})\)

Mô hình hồi quy

loglin <- glm(factor(Sleep) ~ Gender+ Sleep.Duration +Stress.Level +Heart.Rate, family = binomial(link = 'logit'), data = d )
loglin
## 
## Call:  glm(formula = factor(Sleep) ~ Gender + Sleep.Duration + Stress.Level + 
##     Heart.Rate, family = binomial(link = "logit"), data = d)
## 
## Coefficients:
##    (Intercept)      GenderMale  Sleep.Duration    Stress.Level      Heart.Rate  
##         -5.795          -1.541          -1.384          -0.469           0.265  
## 
## Degrees of Freedom: 373 Total (i.e. Null);  369 Residual
## Null Deviance:       507 
## Residual Deviance: 382   AIC: 392

Kiểm định sự phù hợp của mô hình

Giả thuyết H0: Mô hình phù hợp. Tiêu chuẩn bác bỏ giả thuyết H0 của các thống kê này: p_vaule < 5%

pchisq(deviance(loglin), df = df.residual(loglin), lower.tail = F)
## [1] 0.3112

Từ bảng kết quả trên ta có p_vaule= 0,3112 > 0,05 ta chấp nhận H0. Vậy với mức ý nghĩa 5%, mô hình phù hợp

Chỉ số đánh giá mô hình

summary(loglin)
## 
## Call:
## glm(formula = factor(Sleep) ~ Gender + Sleep.Duration + Stress.Level + 
##     Heart.Rate, family = binomial(link = "logit"), data = d)
## 
## Deviance Residuals: 
##    Min      1Q  Median      3Q     Max  
## -2.594  -0.638  -0.471   0.960   2.181  
## 
## Coefficients:
##                Estimate Std. Error z value Pr(>|z|)    
## (Intercept)     -5.7951     3.8776   -1.49    0.135    
## GenderMale      -1.5412     0.3299   -4.67  3.0e-06 ***
## Sleep.Duration  -1.3844     0.3105   -4.46  8.3e-06 ***
## Stress.Level    -0.4690     0.1869   -2.51    0.012 *  
## Heart.Rate       0.2647     0.0571    4.64  3.6e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 507.47  on 373  degrees of freedom
## Residual deviance: 381.86  on 369  degrees of freedom
## AIC: 391.9
## 
## Number of Fisher Scoring iterations: 5
BrierScore(loglin)
## [1] 0.171
confusionMatrix(table(predict(loglin, type='response') >= 0.5 ,loglin$data$Sleep == 'yes'))
## Confusion Matrix and Statistics
## 
##        
##         FALSE TRUE
##   FALSE   173   72
##   TRUE     46   83
##                                         
##                Accuracy : 0.684         
##                  95% CI : (0.635, 0.731)
##     No Information Rate : 0.586         
##     P-Value [Acc > NIR] : 5.09e-05      
##                                         
##                   Kappa : 0.334         
##                                         
##  Mcnemar's Test P-Value : 0.0214        
##                                         
##             Sensitivity : 0.790         
##             Specificity : 0.535         
##          Pos Pred Value : 0.706         
##          Neg Pred Value : 0.643         
##              Prevalence : 0.586         
##          Detection Rate : 0.463         
##    Detection Prevalence : 0.655         
##       Balanced Accuracy : 0.663         
##                                         
##        'Positive' Class : FALSE         
## 

Kết quả ước lượng mô hình thì R mặc định sẽ ước lượng cho tần số của ô đầu tiên (1,1) trong bảng, nghĩa là ứng với kết quả này thì:

\(log(μ̂ )=-5.795-1.541 Gender -1.384 Sleep.Duration -0.469 Stress.Level + 0.265Heart.Rate\)

Các chỉ số đánh giá mô hình

  • Deviance: 381.86

  • AIC: 391.9

  • BrierScore: 0.171

-Confusion Matrix Có độ đặc hiệu: 0,684; độ nhạy: 0,79; độ chính xác toàn thể: 0,535

5.2.4.2 Mô hình Probit

Tại đây ta tiến hành hồi quy với hàm probit \(probit(π)=Φ^{−1}(π)\)

Mô hình hồi quy

ft1 <- glm(factor(Sleep) ~ Gender+ Sleep.Duration +Stress.Level +Heart.Rate, family = binomial(link = 'probit'), data = d )
ft1
## 
## Call:  glm(formula = factor(Sleep) ~ Gender + Sleep.Duration + Stress.Level + 
##     Heart.Rate, family = binomial(link = "probit"), data = d)
## 
## Coefficients:
##    (Intercept)      GenderMale  Sleep.Duration    Stress.Level      Heart.Rate  
##         -3.159          -0.932          -0.802          -0.255           0.149  
## 
## Degrees of Freedom: 373 Total (i.e. Null);  369 Residual
## Null Deviance:       507 
## Residual Deviance: 382   AIC: 392

Kiểm định sự phù hợp của mô hình

Giả thuyết H0: Mô hình phù hợp. Tiêu chuẩn bác bỏ giả thuyết H0 của các thống kê này: p_vaule < 5%

pchisq(deviance(ft1), df = df.residual(ft1), lower.tail = F)
## [1] 0.315

Từ bảng kết quả trên ta có p_vaule= 0,315 > 0,05 ta chấp nhận H0. Vậy với mức ý nghĩa 5%, mô hình phù hợp

Đánh giá mô hình

summary(ft1)
## 
## Call:
## glm(formula = factor(Sleep) ~ Gender + Sleep.Duration + Stress.Level + 
##     Heart.Rate, family = binomial(link = "probit"), data = d)
## 
## Deviance Residuals: 
##    Min      1Q  Median      3Q     Max  
## -2.663  -0.642  -0.459   0.983   2.211  
## 
## Coefficients:
##                Estimate Std. Error z value Pr(>|z|)    
## (Intercept)     -3.1591     2.1767   -1.45    0.147    
## GenderMale      -0.9315     0.1841   -5.06  4.2e-07 ***
## Sleep.Duration  -0.8024     0.1771   -4.53  5.9e-06 ***
## Stress.Level    -0.2547     0.1024   -2.49    0.013 *  
## Heart.Rate       0.1491     0.0294    5.07  4.0e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 507.47  on 373  degrees of freedom
## Residual deviance: 381.56  on 369  degrees of freedom
## AIC: 391.6
## 
## Number of Fisher Scoring iterations: 5
BrierScore(ft1)
## [1] 0.1708
confusionMatrix(table(predict(ft1, type='response') >= 0.5 ,ft1$data$Sleep == 'yes'))
## Confusion Matrix and Statistics
## 
##        
##         FALSE TRUE
##   FALSE   173   72
##   TRUE     46   83
##                                         
##                Accuracy : 0.684         
##                  95% CI : (0.635, 0.731)
##     No Information Rate : 0.586         
##     P-Value [Acc > NIR] : 5.09e-05      
##                                         
##                   Kappa : 0.334         
##                                         
##  Mcnemar's Test P-Value : 0.0214        
##                                         
##             Sensitivity : 0.790         
##             Specificity : 0.535         
##          Pos Pred Value : 0.706         
##          Neg Pred Value : 0.643         
##              Prevalence : 0.586         
##          Detection Rate : 0.463         
##    Detection Prevalence : 0.655         
##       Balanced Accuracy : 0.663         
##                                         
##        'Positive' Class : FALSE         
## 

Kết quả ước lượng mô hình thì R mặc định sẽ ước lượng cho tần số của ô đầu tiên (1,1) trong bảng, nghĩa là ứng với kết quả này thì:

\(probit(π)=-3.159 -0.932 Gender -0.802 Sleep.Duration -0.255 Stress.Level + 0.149Heart.Rate\)

Các chỉ số đánh giá mô hình

  • Deviance: 381.56

  • AIC: 391.6

  • BrierScore: 0.1708

  • Confusion Matrix Có độ đặc hiệu: 0,684; độ nhạy: 0,79; độ chính xác toàn thể: 0,535

5.2.4.3 Mô hình cloglog

Tại đây ta tiến hành hồi quy với hàm cloglog\(cloglog(π)=log(−log(1−π))\)

Mô hình hồi quy

ft2 <- glm(factor(Sleep) ~ factor(Gender)+ Sleep.Duration +Stress.Level +Heart.Rate, family = binomial(link = 'cloglog'), data = d )
ft2
## 
## Call:  glm(formula = factor(Sleep) ~ factor(Gender) + Sleep.Duration + 
##     Stress.Level + Heart.Rate, family = binomial(link = "cloglog"), 
##     data = d)
## 
## Coefficients:
##        (Intercept)  factor(Gender)Male      Sleep.Duration        Stress.Level  
##             -2.277              -1.011              -0.827              -0.211  
##         Heart.Rate  
##              0.129  
## 
## Degrees of Freedom: 373 Total (i.e. Null);  369 Residual
## Null Deviance:       507 
## Residual Deviance: 394   AIC: 404

Kiểm định sự phù hợp của mô hình

Giả thuyết H0: Mô hình phù hợp. Tiêu chuẩn bác bỏ giả thuyết H0 của các thống kê này: p_vaule < 5%

pchisq(deviance(ft2), df = df.residual(ft2), lower.tail = F)
## [1] 0.1783

Từ bảng kết quả trên ta có p_vaule= 0,1783 > 0,05 ta chấp nhận H0. Vậy với mức ý nghĩa 5%, mô hình phù hợp

Đánh giá mô hình

summary(ft2)
## 
## Call:
## glm(formula = factor(Sleep) ~ factor(Gender) + Sleep.Duration + 
##     Stress.Level + Heart.Rate, family = binomial(link = "cloglog"), 
##     data = d)
## 
## Deviance Residuals: 
##    Min      1Q  Median      3Q     Max  
## -2.785  -0.709  -0.575   1.020   1.979  
## 
## Coefficients:
##                    Estimate Std. Error z value Pr(>|z|)    
## (Intercept)         -2.2766     2.2109   -1.03  0.30316    
## factor(Gender)Male  -1.0111     0.1980   -5.11  3.3e-07 ***
## Sleep.Duration      -0.8272     0.2140   -3.87  0.00011 ***
## Stress.Level        -0.2109     0.1036   -2.04  0.04174 *  
## Heart.Rate           0.1291     0.0246    5.24  1.6e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 507.47  on 373  degrees of freedom
## Residual deviance: 393.92  on 369  degrees of freedom
## AIC: 403.9
## 
## Number of Fisher Scoring iterations: 9
BrierScore(ft2)
## [1] 0.175
confusionMatrix(table(predict(ft2, type='response') >= 0.5 ,ft2$data$Sleep == 'yes'))
## Confusion Matrix and Statistics
## 
##        
##         FALSE TRUE
##   FALSE   175   74
##   TRUE     44   81
##                                         
##                Accuracy : 0.684         
##                  95% CI : (0.635, 0.731)
##     No Information Rate : 0.586         
##     P-Value [Acc > NIR] : 5.09e-05      
##                                         
##                   Kappa : 0.331         
##                                         
##  Mcnemar's Test P-Value : 0.00759       
##                                         
##             Sensitivity : 0.799         
##             Specificity : 0.523         
##          Pos Pred Value : 0.703         
##          Neg Pred Value : 0.648         
##              Prevalence : 0.586         
##          Detection Rate : 0.468         
##    Detection Prevalence : 0.666         
##       Balanced Accuracy : 0.661         
##                                         
##        'Positive' Class : FALSE         
## 

Kết quả ước lượng mô hình thì R mặc định sẽ ước lượng cho tần số của ô đầu tiên (1,1) trong bảng, nghĩa là ứng với kết quả này thì:

\(cloglog(π)=-2.277 -1.011 Gender -0.827 Sleep.Duration -0.211 Stress.Level + 0.129 Heart.Rate\)

Các chỉ số đánh giá mô hình

  • Deviance: 393.92

  • AIC: 403.9

  • BrierScore: 0.175

-Confusion Matrix Có độ đặc hiệu: 0,684; độ nhạy: 0,799; độ chính xác toàn thể: 0,523

5.2.5 Chọn phù hợp của các mô hình

Các phân tích dữ liệu nhị phân theo 3 loại hàm liên kết là logit, probit, cloglog ta có các chỉ số đánh giá như sau:

logit probit cloglog
AIC 391.9 391.6 403.9
deviance 381.56 381.56 393.92
Brier Score 0.171 0.1708 0.175
Độ đặc hiệu 0,684 0,684 0,684
Độ nhạy 0,79 0,79 0,799
Độ chính xác toàn thể 0,535 0,535 0,523

Nhận xét:Khi nhìn vào các gái trị đuọc thống kê ở bảng ta nhân thấy hàm probit là hàm liên kết là tốt nhất vì có chỉ số AIC và Brier Score nhỏ nhất trong ba mô hình đã thống kê.

5.2.6 Ước lượng mô hình

Ta có mô hình Probit :

$probit(π)=-3.159 -0.932 Gender -0.802 Sleep.Duration -0.255 Stress.Level + 0.149Heart.Rate $

cho thấy nguy cơ mà người tham gia khảo sát có triệu chứng mất ngủ theo từng biến, theo đó:

ft1$coefficients
##    (Intercept)     GenderMale Sleep.Duration   Stress.Level     Heart.Rate 
##        -3.1591        -0.9315        -0.8024        -0.2547         0.1491

Xác suất có các triệu chứng mất ngủ của một người giới tính nữ (Female) ước đoán là:

\(\pi(1,x_2,x_3,x_4) = -3.159 -0.802 x_2 -0.255x_3+0.149 x_4\)

Xác suất có các triệu chứng mất ngủ của một người giới tính nam (Male) ước đoán là:

\(\pi(0,x_2,x_3,x_4) = -4.091 -0.802 x_2 -0.2547 x_3 + 0.1491 x_4\)

5.3 Mô hình Poisson

5.3.1 Kiểm định dãy số có phân phối Poisson

Kiểm định một dãy số có phân phối Poisson Với Giả thuyết H0:X

x <- length(d$Quality.of.Sleep)

poisson.test(x,r=8.5,alt="greater")
## 
##  Exact Poisson test
## 
## data:  x time base: 1
## number of events = 374, time base = 1, p-value <2e-16
## alternative hypothesis: true event rate is greater than 8.5
## 95 percent confidence interval:
##  342.8   Inf
## sample estimates:
## event rate 
##        374

Ta có \(p-value <2*10^{-6}<0.05\), chứng mình biến Quality.of.Sleep là dữu liệu Poisson

Ký hiệu u(x) là giá trị kỳ vọng cho biến ngẫu nhiên Poisson Y ứng với mức x của biến X tức là: u(x)=E(Y|X=x)

Để hồi quy mô hình: \(log[u(x)] =\alpha+\beta*x\)

5.3.2 Ước lượng và dự báo

Ước lượng hàm hồi quy cho dữ liệu Poisson là tìm giá trị kỳ vọng cho biến ngẫu nhiên Poisson là Quality.of.Sleep với các biến còn lại

fit <- glm(data = d, formula =Quality.of.Sleep  ~ Daily.Steps+ Sleep.Duration +Stress.Level+ Heart.Rate, family = poisson(link = 'log'))
fit
## 
## Call:  glm(formula = Quality.of.Sleep ~ Daily.Steps + Sleep.Duration + 
##     Stress.Level + Heart.Rate, family = poisson(link = "log"), 
##     data = d)
## 
## Coefficients:
##    (Intercept)     Daily.Steps  Sleep.Duration    Stress.Level      Heart.Rate  
##       1.82e+00        1.57e-05        8.37e-02       -5.11e-02       -3.82e-03  
## 
## Degrees of Freedom: 373 Total (i.e. Null);  369 Residual
## Null Deviance:       74.7 
## Residual Deviance: 7.88  AIC: 1450
summary(fit)
## 
## Call:
## glm(formula = Quality.of.Sleep ~ Daily.Steps + Sleep.Duration + 
##     Stress.Level + Heart.Rate, family = poisson(link = "log"), 
##     data = d)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -0.5852  -0.0536   0.0180   0.0649   0.3770  
## 
## Coefficients:
##                 Estimate Std. Error z value Pr(>|z|)    
## (Intercept)     1.82e+00   5.36e-01    3.39  0.00069 ***
## Daily.Steps     1.57e-05   1.32e-05    1.19  0.23389    
## Sleep.Duration  8.37e-02   4.14e-02    2.02  0.04294 *  
## Stress.Level   -5.11e-02   2.27e-02   -2.25  0.02443 *  
## Heart.Rate     -3.82e-03   6.61e-03   -0.58  0.56355    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for poisson family taken to be 1)
## 
##     Null deviance: 74.7384  on 373  degrees of freedom
## Residual deviance:  7.8764  on 369  degrees of freedom
## AIC: 1453
## 
## Number of Fisher Scoring iterations: 4

Kết quả ước lượng mô hình :

\(log(μ̂_{11} )= 1.82+1.57*10^{-5}Daily.Steps+8.37*10^{-2}Sleep.Duration-5.11*10^{-2}Stress.Level-3.82*10^{-2} Heart.Rate\)

Trước khi thực hiện việc ước lượng cho tần số kỳ vọng của các ô, sau đó thực hiện việc ước lượng tần số kỳ vọng cho các ô:

uocluong <- fitted(fit)
h <- cbind(Gender=d$Gender,Sleep.Duration=d$Sleep.Duration,Stress.Level=d$Stress.Level,Heart.Rate=d$Heart.Rate,uocluong)
head(h)
##   Gender Sleep.Duration Stress.Level Heart.Rate uocluong          
## 1 "Male" "6.1"          "6"          "77"       "6.00261568704486"
## 2 "Male" "6.2"          "8"          "75"       "6.03148831632381"
## 3 "Male" "6.2"          "8"          "75"       "6.03148831632381"
## 4 "Male" "5.9"          "8"          "85"       "5.0726412032818" 
## 5 "Male" "5.9"          "8"          "85"       "5.0726412032818" 
## 6 "Male" "5.9"          "8"          "85"       "5.0726412032818"

6 Chương 6: Kết quả

Với các biến độc lập đã thực hiện thống kê mô tả và hai biến phụ thuộc đã chọn, tôi tiến hành lập thống kê hai biến băng Thống kê mô tả và thống kê suy diễn cho hai biến và mô hình hồi quy đa biến cho dữ liệu, ta có các hàm hồi quy sau:

Mô hình logistic dùng biến giả nhị phân

\(log(\frac{π}{1−π})= -6.0517+0.1131x_1-0.0576c_1-1.6825c_2-0.5451c_3- 14.5995 c_4+ 2.4514c_5 +18.4557c_6 +3.8425c_7+2.2675 c_8+1.3778 * c_9+2.6332 * c_{1}\)

Mô hình logistic có thuộc tính thứ tự

\(log(\frac{π}{1−π})=-3.444 -0.233Quality.of.Sleep + 2.302 BMI.Category\)

Mô hình logistic có thuộc tính mức độ so sánh

\(log(\frac{π}{1−π})=-5.2986-0.0539 Physical.Activity.Level +0.5154 Blood.Pressure\)

Mô hình Probit

\(probit(π)=-3.159 -0.932 Gender -0.802 Sleep.Duration -0.255 Stress.Level + 0.149Heart.Rate\)

Mô hình Poisson:

\(log(μ̂_{11} )= 1.82+1.57*10^{-5}Daily.Steps+8.37*10^{-2}Sleep.Duration-5.11*10^{-2}Stress.Level-3.82*10^{-2} Heart.Rate\)

Xác định được những vấn đề sau:

  • Biến định tính là huyết áp tăng dần theo thể trọng của cơ thể cho thấy xác có triệu chứng mất ngủ tăng

  • Ta thấy, người có nhịp tim đập từ 70 nhịp/phút khi ngủ có các triệt chứng mất ngủ cao hơn người có nhịp tim đập 60-69 nhịp/phút khi ngủ rối không có các triệt chứng mất ngủ.

  • Người thừa cân có các triệt chứng mất ngủ gấp 8,7 lân người có cân nặng bình thường có các triệt chứng mất ngủ.

  • Triệu chứng mất ngủ tỉ lệ nghịch với điểm đánh giá giấc ngủ nhưng tỉ lệ thuận với mức độ căn thẵng của những người tham gian khảo sát.

  • Đa phần các triệu chứng của việc mất ngủ của nam giới, nữ giới có điểm khác biệt.

  • Với việc nghề nghiệp theo sự di chuyển ít hay nhiều trong quá trình làm việc. Kết quả nghề cần di chuyển nhiều có khả năng mất ngủ nhiều hơn người di chuyển ít.

  • Cho thấy, toàn bộ người có mức độ căng thẳng thấp đều có điêm đánh giá cao. Còn lại là phần lớn người bị căng thẳng nhiều lại có điểm về giấc ngủ thấp.

  • Người ngủ đủ thời gian trong một ngày đều có điêm đánh giá cao. Còn lại là phần lớn người ngủ không đủ lại có điểm về giấc ngủ thấp.

LS0tDQp0aXRsZTogJ1Rp4buDdSBsdeG6rW4gcGjDom4gdMOtY2ggZOG7ryBsaeG7h3UgxJHhu4tuaCB0w61uaCcNCmF1dGhvcjogJ0h14buzbmggVGjhu4sgVGjDuXkgRMawxqFuZycNCmRhdGU6ICcyMDIzLTA2LTI3Jw0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQogICAgdGhlbWU6IGNlcnVsZWFuDQogICAgaGlnaHRsaWdodDoga2F0ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIA0KLS0tDQpgYGB7ciBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZXBpdG9vbHMpDQpsaWJyYXJ5KERlc2NUb29scykNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KGVuZXJneSkNCmxpYnJhcnkoR0xNc0RhdGEpDQpsaWJyYXJ5KGNhcmV0KQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShwbHlyKQ0KbGlicmFyeShzdGF0cykNCmxpYnJhcnkoY293cGxvdCkNCmxpYnJhcnkocGF0Y2h3b3JrKQ0KbGlicmFyeShnZ3RoZW1lcykNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbGlicmFyeShlcGlEaXNwbGF5KQ0Kb3B0aW9ucyhkaWdpdHMgPSA0KQ0KYGBgDQoNCiMgQ2jGsMahbmcgMTogR2nhu5tpIHRoaeG7h3UgDQoNCiMjIMSQ4bq3dCB24bqlbiDEkeG7gQ0KDQpUcsOqbiB0aOG6vyBnaeG7m2kgbeG7l2kgbmfGsOG7nWkgxJHhu4F1IG5oaeG7gXUgaG/huqF0IMSR4buZbmcgcmnDqm5nIGPhu6dhIG3DrG5oIG5oxrAgaOG7jWMgdOG6rXAsIGR1IGzhu4tjaCwgdnVpIGNoxqFpLCBsw6BtIHZp4buHYywuLi4gTmjGsG5nIGPDsyBt4buZdCB2w6BpIGhv4bqhdCDEkeG7mW5nIG3DoCBi4bqldCBr4buzIG5nxrDhu51pIG7DoG8gY8WpbmcgcGjhuqNpIHRo4buxYyBoacOqbiBsw6AgxINuIHXhu5FuZyB2w6AgxJFpIG5n4bunLiBUcm9uZyBiw6BpIHRp4buDdSBsdeG6rW4gbsOgeSB0w7RpIHTDrG0gaGnDqnUgdsOgIGdp4bqlYyBuZ+G7pyBj4bunYSBjb24gbmfGsOG7nWkuIE5oxrBuZyBjaMO6bmcgdGEgxJHDoyBiaeG6v3Qgbmfhu6cgbMOgIG3hu5l0IHRyb25nIHRy4bqhbmcgdGjDoWkgbmdo4buJIG5nxqFpIHThuqFtIHRo4budaSBj4bunYSBjxqEgdGjhu4MgdsOgIG7DsyB0aMaw4budbmcgeOG6o3kgcmEga2hpIG3hu5dpIGNow7puZyB0YSBj4bqjbSB0aOG6pXkgbeG7h3QgbeG7j2kgaGF5IGtp4buHdCBz4bupYy4gSGF5IMSRw7puZyBoxqFuIGzDoCBt4buZdCBuZ8OgeSAyNCBnaeG7nSB0aMOsIGNow7puZyB0YSBz4bq9IGTDoG5oIDggdGnhur9uZyBiYW4gxJHDqm0gxJHhu4Mgbmfhu6cgxJHhu4MgZ2nDunAgbeG7jWkgYuG7mSBwaOG6rW4gdHLDqm4gY8ahIHRo4buDIMSRxrDhu6NjIHRo4bqjIGzhu49uZy4gTmjGsG5nIG5ow6xuIGTGsOG7m2kgZ8OzYyDEkeG7mSBraG9hIGjhu41jLCB0aMOsIG5n4bunIGNow61uaCBsw6AgbMO6YyBuw6NvIGLhu5kgY+G7p2EgY2jDum5nIHRhIHRo4buxYyBoaeG7h24gbeG7mXQgc+G7kSBjw7RuZyB2aeG7h2MgcXVhbiB0cuG7jW5nIG5o4bqldC4gS2hpIG5n4bunIGPDsyB0aOG7gyBnacO6cCB0YSDEkWnhu4F1IGjDsmEgxJHhu5NuZyBo4buTIHNpbmggaOG7jWMgY+G7p2EgY8ahIHRo4buDLCBnacO6cCBuw6NvIGLhu5kgxJHGsOG7o2Mgbmdo4buJIG5nxqFpLCBsb+G6oWkgYuG7jyBjxINuZyB0aOG6s25nIG3hu4d0IG3hu49pLCB0xINuZyBjxrDhu51uZyBraOG6oyBuxINuZyB04bqtcCB0cnVuZywgdHLDrSBuaOG7myB2w6Agc+G7sSBtaW5oIG3huqtuLiBUcm9uZyBsw7pjIG7DoHksIGhv4bqhdCDEkeG7mW5nIGPhu6dhIHRpbSBnaeG6o20gZOG6p24gdsOgIG5o4buLcCDEkWnhu4d1IGPhu6dhIGjhu4cgdHXhuqduIGhvw6BuIOG7lW4gxJHhu4tuaCBoxqFu4oCmLkPFqW5nIGzDoCBraGkgbmfhu6cgY8OhYyBjxqEgcXVhbiBu4buZaSB0acOqdCBj4bunYSBjb24gbmfGsOG7nWkgdGnhur9uIGjDoG5oIMSRw6BvIHThuqNpIGPDoWMgxJHhu5ljIHThu5F0IHTDrWNoIHThu7EgbOG6oWkgdHJvbmcgY8ahIHRo4buDLkPDsyB0aOG7gyBuw7NpLCB2aeG7h2Mgbmfhu6cgc+G6vSB0cuG7nyB0aMOgbmggbGnhu4F1IHRodeG7kWMgYuG7lSB04buRdCBuaOG6pXQgbeG7l2kgbmfDoHkuIE5oxrBuZyBraGkgY2jDum5nIHRhIG3huqV0IG5n4bunICh0w6xuaCB0cuG6oW5nIHLhu5FpIGxv4bqhbiBnaeG6pWMgbmfhu68pIHRow6wgc+G6vSBjw7MgdMOhYyDEkeG7mW5nIHjhuqV1IMSR4bq/biBjxqEgdGjhu4MgZOG6q24gxJHhur9uIG5ndXkgY8ahIG3huq9jIG3hu5l0IHPhu5EgYuG7h25oIHVuZyB0aMawIGNhbyBoxqFuLCBsw6BtIHbhur90IHRoxrDGoW5nIHRyw6puIGRhIGtow7MgbMOgbmggdsOgIGRhIGPFqW5nIGThu4UgbMOjbyBow7NhIGjGoW4sIGzDoG0gdMSDbmcgbmd1eSBjxqEgbeG6r2MgYuG7h25oIHRpbSB2w6AgdGnhu4N1IMSRxrDhu51uZywgZOG7hSBt4bqvYyBi4buHbmggaMahbiB2w6wgaOG7hyBtaeG7hW4gZOG7i2NoIGtow7RuZyBob+G6oXQgxJHhu5luZyB04buRdCBraGkgYuG6oW4gbeG7h3QgbeG7j2ksIGJ14buTbiBuZ+G7pyBz4bq9IGtoaeG6v24gYuG6oW4ga2jDsyBjaOG7i3UgdsOgIGPDoXUga+G7iW5oLiBWw6Aga2hpIHRp4bq/biBow6BuaCB0w6xtIGhpw6p1LCB0w7RpIMSRw6MgdMOsbSByYSBi4buZIGThu68gbGnhu4d1ICdTbGVlcCBIZWFsdGggYW5kIExpZmVzdHlsZScgbsOzaSB24buBIGhv4bqhdCDEkeG7mW5nLCB0aOG7kWkgcXVlbiB2w6AgY8OhYyBiaeG7g3UgaGnhu4duIGPhu6dhIHTDrG5oIHRy4bqhbmcgcuG7kWkgbG/huqFuIGdp4bqlYyBuZ+G7py4gVMO0aSBz4bq9IMSRaSB0aeG6v24gaMOgbmggcGjDom4gdMOtY2ggY8OhYyBiaeG6v24gdHJvbmcgYuG7mSBk4buvIGxp4buHdSBuw6B5IHbDoCB4ZW0geMOpdCBjw6FjIHnhur91IHThu5Eg4bqjbmggaMaw4bufbmcgxJHhur9uIGdp4bqlYyBuZ+G7py4gICANCg0KIyMgVOG7lW5nIHF1YW4gduG7gSBi4buZIGThu68gbGnhu4d1Og0KDQojIyMgIE3DtCB04bqjIGThu68gbGnhu4d1DQoNCg0KQuG7mSBk4buvIGxp4buHdSBjw7MgdMOqbiBsw6AgJ1NsZWVwIEhlYWx0aCBhbmQgTGlmZXN0eWxlJyBiYW8gZ+G7k20gMzc0IGjDoG5nIHbDoCAxMyBj4buZdCwgdMawxqFuZyDEkcawxqFuZyB24bubaSAzNzQga2jhuqNvIHPDoXQgdsOgIDEzIGJp4bq/bi4gROG7ryBsaeG7h3UgY8OzIG5oaeG7gXUgYmnhur9uIGxpw6puIHF1YW4gxJHhur9uIGdp4bqlYyBuZ+G7pyB2w6AgdGjDs2kgcXVlbiBow6BuZyBuZ8OgeS4gTsOzIGJhbyBn4buTbSBjw6FjIGNoaSB0aeG6v3QgbmjGsCBnaeG7m2kgdMOtbmgsIHR14buVaSB0w6FjLCBuZ2jhu4EgbmdoaeG7h3AsIHRo4budaSBnaWFuIG5n4bunLCBjaOG6pXQgbMaw4bujbmcgZ2nhuqVjIG5n4bunLCBt4bupYyDEkeG7mSBob+G6oXQgxJHhu5luZyB0aOG7gyBjaOG6pXQsIG3hu6ljIMSR4buZIGPEg25nIHRo4bqzbmcsIGNo4buJIHPhu5EgQk1JLCBodXnhur90IMOhcCwgbmjhu4twIHRpbSwgc+G7kSBixrDhu5tjIGjDoG5nIG5nw6B5IHbDoCB0w6xuaCB0cuG6oW5nIHLhu5FpIGxv4bqhbiBnaeG6pWMgbmfhu6cgY8OzIGhheSBraMO0bmcuDQoNCi0gQ8OhYyB0w61uaCBuxINuZyBjaMOtbmggY+G7p2EgYuG7mSBk4buvIGxp4buHdQ0KDQpT4buRIGxp4buHdSB0b8OgbiBkaeG7h24gduG7gSBnaeG6pWMgbmfhu6c6IEtow6FtIHBow6EgdGjhu51pIGzGsOG7o25nLCBjaOG6pXQgbMaw4bujbmcgZ2nhuqVjIG5n4bunIHbDoCBjw6FjIHnhur91IHThu5Eg4bqjbmggaMaw4bufbmcgxJHhur9uIGtp4buDdSBuZ+G7py4NCg0KQ8OhYyB54bq/dSB04buRIGzhu5FpIHPhu5FuZzogUGjDom4gdMOtY2ggbeG7qWMgxJHhu5kgaG/huqF0IMSR4buZbmcgdGjhu4MgY2jhuqV0LCBt4bupYyDEkeG7mSBjxINuZyB0aOG6s25nIHbDoCBjw6FjIGxv4bqhaSBCTUkuDQoNClPhu6ljIGto4buPZSB0aW0gbeG6oWNoOiBLaeG7g20gdHJhIGPDoWMgcGjDqXAgxJFvIGh1eeG6v3Qgw6FwIHbDoCBuaOG7i3AgdGltLg0KDQpQaMOibiB0w61jaCBy4buRaSBsb+G6oW4gZ2nhuqVjIG5n4bunOiBYw6FjIMSR4buLbmggc+G7sSB4deG6pXQgaGnhu4duIGPhu6dhIGPDoWMgcuG7kWkgbG/huqFuIGdp4bqlYyBuZ+G7pyBuaMawIG3huqV0IG5n4bunIHbDoCBuZ8awbmcgdGjhu58ga2hpIG5n4bunLg0KDQoNCiMjIyBNw7QgdOG6oyBjw6FjIGJp4bq/bg0KDQpCaeG6v24gJ1BlcnNvbiBJRCc6IE3DoyDEkeG7i25oIGRhbmggY2hvIG3hu5dpIGPDoSBuaMOibi4NCg0KQmnhur9uICdHcmVuZGVyJzogR2nhu5tpIHTDrW5oIGPhu6dhIG5nxrDhu51pIMSRw7MgKG1hbGUvZmVtYWxlKS4NCg0KQmnhur9uICdBZ2UnOiBUdeG7lWkgbmdo4buBIGPhu6dhIG5nxrDhu51pIHTDrW5oIHRoZW8gbsSDbS4NCg0KQmnhur9uICdPY2N1cGF0aW9uJzogTmdo4buBIG5naGnhu4dwIGhv4bq3YyBuZ2jhu4EgbmdoaeG7h3AgY+G7p2EgbmfGsOG7nWkgxJHDsy4gVHJvbmcgZOG7ryBsaeG7h3UgxJHDoyBxdWFuIHPDoXQgdHLDqm4gMTEgbmfDoG5oIG5naOG7gToNCg0KLSBBY2NvdW50YW50OiBuZ2jhu4Ega+G6vyB0b8Ohbi4NCg0KLSBEb2N0b3I6IG5naOG7gSBiw6FjIHPEqS4gIA0KDQotIEVuZ2luZWVyOiBuZ2jhu4Ega+G7uSBzxrAuDQoNCi0gTGF3eWVyOiBuZ2jhu4EgbHXhuq10IHPGsC4NCg0KLSBNYW5hZ2VyOiBuZ8aw4budaSBxdeG6o24gbMOtLiAgICAgICAgICAgICAgIA0KDQotIE51cnNlOiB5IHTDoS4NCg0KLSBTYWxlcyBSZXByZXNlbnRhdGl2ZTogxJHhuqFpIGRp4buHbiBraW5oIGRvYW5oLiAgICAgICAgDQoNCi0gU2FsZXNwZXJzb246IG5ow6JuIHZpw6puIGLDoW4gaMOgbmcuDQoNCi0gU2NpZW50aXN0OiBuaMOgIGtob2EgaOG7jWMuIA0KDQotIFNvZnR3YXJlIEVuZ2luZWVyOiBr4bu5IHPGsCBwaOG6p24gbeG7gW0uICAgICAgICAgICAgIA0KDQotIFRlYWNoZXI6IG5naOG7gSBnacOhbyB2acOqbi4gDQoNCkJp4bq/biAnIFNsZWVwIER1cmF0aW9uJyAoZ2nhu50pOiBT4buRIGdp4budIG3hu5l0IG5nxrDhu51pIG5n4bunIG3hu5dpIG5nw6B5Lg0KDQpCaeG6v24gJ1F1YWxpdHkgb2YgU2xlZXAnOiDEkMOhbmggZ2nDoSB24buBIGNo4bqldCBsxrDhu6NuZyBnaeG6pWMgbmfhu6cgY+G7p2EgbmfGsOG7nWkgdGhhbSBnaWEga2jhuqNvIHPDoXQsIHbhu5tpIHRoYW5nIMSRaeG7g20gdOG7qyAxIMSR4bq/biAxMC4NCg0KQmnhur9uICdQaHlzaWNhbCBBY3Rpdml0eSBMZXZlbCc6IFPhu5EgcGjDunQgbeG7mXQgbmfGsOG7nWkgdGhhbSBnaWEgaG/huqF0IMSR4buZbmcgdGjhu4MgY2jhuqV0IGjDoG5nIG5nw6B5KCB0w61uaCB0aGVvIHBow7p0L25nw6B5KS4NCg0KQmnhur9uICdTdHJlc3MgTGV2ZWwnOiDEkMOhbmggZ2nDoSBjaOG7pyBxdWFuIHbhu4EgbeG7qWMgxJHhu5kgY8SDbmcgdGjhurNuZyBtw6AgbeG7mXQgbmfGsOG7nWkgdHLhuqNpIHF1YSwgduG7m2kgdGhhbmcgxJFp4buDbSB04burIDEgxJHhur9uIDEwLg0KDQpCaeG6v24gJ0JNSSBDYXRlZ29yeSc6IEjhuqFuZyBt4bulYyBCTUkgY+G7p2EgbeG7mXQgbmfGsOG7nWkuIFbhu5tpIGPDoWMgYmnhu4N1IGhp4buHbiBuaMawICBsw6AgJ1VuZGVyd2VpZ2h0JyBsw6AgdGhp4bq/dSBjw6JuLCAnTm9ybWFsIGhheSBOb3JtYWwgV2VpZ2h0JyBsw6AgYsOsbmggdGjGsOG7nW5nLCAnT3ZlcndlaWdodCBoYXkgT2Jlc2UnICBsw6AgdGjhu6thIGPDom4pLg0KDQpCaeG6v24gJ0Jvb2xkIFByZXNzdXJlJzogxJBvIGh1eeG6v3Qgw6FwIGPhu6dhIG3hu5l0IG5nxrDhu51pLCDEkcaw4bujYyBiaeG7g3UgdGjhu4sgbMOgIGh1eeG6v3Qgw6FwIHTDom0gdGh1IHRyw6puIGh1eeG6v3Qgw6FwIHTDom0gdHLGsMahbmcgKMSRxrDhu6NjIHZp4bq/dCB0w6JtIHRodS90w6JtIHRyxrDGoW5nKS4NCg0KQmnhur9uICdIZWFydCBSYXRlJzogTmjhu4twIHRpbSBraGkgbmdo4buJIG5nxqFpIGPhu6dhIG3hu5l0IG5nxrDhu51pIHTDrW5oIGLhurFuZyBuaOG7i3AgbeG7l2kgcGjDunQuDQoNCkJp4bq/biAnRGFpbHkgU3RlcHMnOiBT4buRIGLGsOG7m2MgbeG7mXQgbmfGsOG7nWkgdGjhu7FjIGhp4buHbiBt4buXaSBuZ8OgeS4NCg0KQmnhur9uICdTbGVlcCBEaXNvcmRlcic6IFPhu7EgaGnhu4duIGRp4buHbiBj4bunYSBjaOG7qW5nIHLhu5FpIGxv4bqhbiBnaeG6pWMgbmfhu6cg4bufIG5nxrDhu51pIMSRw7MuIFbhu5tpIGPDoWMgYmnhu4N1IGhp4buHbiBuaMawIHNhdToNCg0KLSBOb25lOiBDw6EgbmjDom4ga2jDtG5nIGJp4buDdSBoaeG7h24gYuG6pXQga+G7syBy4buRaSBsb+G6oW4gZ2nhuqVjIG5n4bunIGPhu6UgdGjhu4MgbsOgby4NCg0KLSBJbnNvbW5pYTogQ8OhIG5ow6JuIGPhuqNtIHRo4bqleSBraMOzIMSRaSB2w6BvIGdp4bqlYyBuZ+G7pyBob+G6t2MgZHV5IHRyw6wgZ2nhuqVjIG5n4bunLCBk4bqrbiDEkeG6v24gZ2nhuqVjIG5n4bunIGtow7RuZyDEkeG7pyBob+G6t2Mga8OpbSBjaOG6pXQgbMaw4bujbmcuDQoNCi0gU2xlZXAgQXBuZWE6IEPDoSBuaMOibiBi4buLIG5n4burbmcgdGjhu58gdHJvbmcga2hpIG5n4bunLCBk4bqrbiDEkeG6v24gZ2nhuqVjIG5n4bunIGLhu4sgZ2nDoW4gxJFv4bqhbiB2w6Agbmd1eSBjxqEgc+G7qWMga2jhu49lIHRp4buBbSDhuqluLg0KDQogDQojIyBRdWFuIHPDoXQgZOG7ryBsaeG7h3UNCg0KxJDhu41jIGThu68gbGnhu4d1OiANCg0KYGBge3J9DQpkbHB0ZGxkdCA8LSByZWFkX2NzdignMjAyMy9kbHB0ZGxkdC5jc3YnKQ0KZCA8LSBkbHB0ZGxkdA0KYGBgDQoNClhlbSBj4bqldSB0csO6YyBj4bunYSBk4buvIGxp4buHdToNCg0KYGBge3J9DQpzdHIoZGxwdGRsZHQpDQpgYGANCg0KUXVhbiBzw6F0IGLhuqNuZyBk4buvIGxp4buHdToNCg0KYGBge3J9DQpkYXRhdGFibGUoZGxwdGRsZHQpDQpkIDwtIGRscHRkbGR0DQpgYGANCg0KIyBDaMawxqFuZyAyOiBDaOG7jW4gYmnhur9uIHBo4bulIHRodeG7mWMNCg0KIyMgUGjDom4gbG/huqFpIGThu68gbGnhu4d1DQoNClRyb25nIHF1w6EgdHLDrG5oIG3DtCB04bqjIGThu68gbGnhu4d1IHbDoCB0w6xtIGhp4buDdSB24buBIGPDoWMgYmnhur9uLiBTYXUgxJHDonksIHTDtGkgdGnhur9uIGjDoG5oIHjDoWMgxJHhu4tuaCB0w61uaCBjaOG6pXQgY+G7p2EgYmnhur9uIHLhu5NpIGThu7FhIHbDoG8gY8OhYyB0acOqdSB0aOG7qWMgdGjhu5FuZyBrw6ogKMSRxqFuIHbhu4sgY+G7p2EgdOG7lW5nIHRo4buDKSB2w6AgY2hpYSBjw6FjIGJp4bq/biBj4bunYSBk4buvIGxp4buHdSB0aMOgbmggaGFpIGxv4bqhaToNCg0KLSBUacOqdSB0aOG7qWMgdGh14buZYyB0w61uaCAoYmnhur9uIMSR4buLbmggdMOtbmgpOiBsw6AgbG/huqFpIHRpw6p1IHRo4bupYyBraMO0bmcgxJHGsOG7o2MgYmnhu4N1IGhp4buHbiB0cuG7sWMgdGnhur9wIGLDoG5nIGPDoWMgY29uIHPhu5EsIG1hbmcgdMOtbmggY2jhuqV0IGdpw7pwIGNow7puZyB0YSBnaeG6o2kgdGjDrWNoIGhheSBjaOG7qW5nIG1pbmguIFRyb25nIGLhu5kgxJHhu68gbGnhu4d1IG7DoHkgY8OhYyBiaeG6v24gxJHhu4tuaCB0w61uaCBsw6AgY8OhYyBiaeG6v24gbmjGsCBzYXU6ICdHZW5kZXInIGNo4buJIGdp4bubaSB0w61uaCwnT2NjdXBhdGlvbicgbMOgIG5naOG7gSBuZ2hp4buHcCwgJ0JNSSBDYXRlZ29yeScgbMOgIGNo4buJIHPhu5EgQk1JLCAnQmxvb2QgUHJlc3N1cmUnIGzDoCBuaOG7i3AgdGltLCAnU2xlZXAgRGlzY29yZGVyJyBsw6AgY2jhu6luZyBy4buRaSBsb+G6oW4gZ2nhuqVjIG5n4butLg0KDQotIFRpw6p1IHRo4bupYyBz4buRIGzGsOG7o25nIChiaeG6v24gxJHhu4tuaCBsxrDhu6NuZyk6IGzDoCBsb+G6oWkgdGnDqnUgdGjhu6ljIGPDsyBiaeG7g3UgaGnhu4duIHRy4buxYyB0aeG6v3AgYuG6sW5nIGPDoWMgY29uIHPhu5EgbWFuZyB0w61uaCBjaOG6pXQgZ2nhuqNpIMSRw6FwIGPDoWMgY8OidSBo4buPaS4gQ8OhYyBiaeG6v24gbmjGsCBzYXUgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBsw6AgxJHhu4tuaCBsxrDhu6NuZzogJ1BlcnNvbiBJRCcgbMOgIG3DoyDEkeG7i25oIGRhbmggJ0FnZScgdGjhu4MgaGnhu4duIHR14buVaSwgJ1NsZWVwIER1cmF0aW9uJyB0aOG7gyBoaeG7h24gc+G7kSBnaeG7nSDEkWkgbmfhu6csICdRdWFsaXR5IG9mIFNsZWVwJyBsw6AgxJFp4buDbSDEkcOhbmggZ2nDoSBnaeG6pWMgbmfhu6csICdQaHlzaWNhbCBBY3Rpdml0eSBMZXZlcmwnIGzDoCB0aOG7nWkgZ2lhbiBob+G6oXQgxJHhu5luZywgJ1N0cmVzcyBMZXZlbCcgdGjhu4MgaGnhu4duIMSR4buZIGPEg24gdGjhurNuZywgJ0RhaWx5IFN0ZXBzJyBsw6Agc+G7kSBixrDhu5tjIMSRaSB0cm9uZyBuZ8OgeS4NCg0KTmjDrG4gY2h1bmcsIGtoaSB0aeG6v24gaMOgbmggcGjDom4gY8OhYyBk4buvIGxp4buHdSB0aMOgbmggaGFpIGxv4bqhaSBxdWEgdGnDqnUgdGjhu6ljIGNo4bunYSBjaMO6bmcuIENobyB0aOG6pXkgdHJvbmcgMTMgYmnhur9uIGPhu6dhIGLhu5kgZMaweCBsaeG7h3UgY8OzIDUgYmnhur9uIMSR4buLbmggdMOtbmggdsOgIDcgYmnhur9uIMSR4buLbmggbMaw4bujbmcuDQoNCkPDsyB0aOG7gyBuw7NpIG3hu5l0IGdp4bqlYyBuZ+G7pyB04buRdCBsw6AgcuG6pXQgcXVhbiB0cuG7jW5nIMSR4buRaSB24bubaSBt4buXaSBjb24gbmfGsOG7nWksIG5oxrBuZyBraMO0bmcgcGjhuqNpIGFpIGPFqW5nIGPDsyBuaOG7r25nIGdp4bqlYyBuZ+G7pyB24bq5bi4gTsOqbiB24bubaSBk4buvIGxp4buHdSBoaeG7h24gdOG6oWkgdMO0aSBz4bq9IGNob24gbeG7mXQgYmnhur9uIMSR4buLbmggbMaw4bujbmcgdsOgIG3hu5l0IGJp4bq/biDEkeG7i25oIHTDrW5oIGzDoG0gYmnhur9uIHBo4bulIHRodeG7mWMgxJHhu4MgY8OzIHRp4bq/biBow6BuaCBwaMOibiB0w61jaCB2w6AgxJHDoW5oIGdpw6EgZ2nhuqVjIG5n4bunIGPhu6dhIG5nxrDhu51pIHRoYW0gZ2lhIGto4bqjbyBzw6F0LiBCaeG6v24gcGjhu6UgdGh1w7RjIMSRxrDhu6NjIGNo4buNbiBwaOG6o2kgbMOgIGxp4bq/biBjw7MgbGnDqm4gcXVhbiDEkcOqbiB0aOG7sWMgdHLhuqFuZyB24buBIGdp4bqlYyBuZ+G7pyBj4bunYSBuaOG7r25nIG5nxrDhu51pIHRoYW0gZ2nDoSBraOG6o28gc8OhdC4gVOG7qyDEkeG6pXksIHTDtGkgY8OzIHRo4buDIHRp4bq/biBow6BuaCBwaMOibiB0w61jaCB0w6FjIMSR4buZbmcgbcOgIGPDoWMgYmnhur9uIGtow6FjIGzDqm4gZ2nhuqVjIG5n4bunLiANCg0KIyMgQ2jhu41uIGJp4bq/biBwaOG7pSB0aHXhu5ljIA0KDQpN4buZdCB0cm9uZyBuaOG7r25nIHbhuqVuIMSR4buBIGThuqtuIMSR4bq/biBjb24gbmfGsOG7nWkga2jDtG5nIGPDsyBnaeG6pWMgbmfhu6cgbmdvbiBjw7MgdGjhu4MgbMOgIGRvIG5nxrDhu51pIMSRw7MgxJFhbmcgY8OzIHTDrG5oIHRy4bqhbmcgcuG7kWkgbG/huqFuIGdpw6JjIG5n4bunIG5oxrAgY+G6o20gdGjhuqV5IGtow7MgxJFpIHbDoG8gZ2nhuqVjIG5n4bunIGhv4bq3YyBkdXkgdHLDrCBnaeG6pWMgbmfhu6csIGThuqtuIMSR4bq/biBnaeG6pWMgbmfhu6cga2jDtG5nIMSR4bunIGhv4bq3YyBrw6ltIGNo4bqldCBsxrDhu6NuZyBoYXkgYuG7iyBuZ+G7q25nIHRo4bufIHRyb25nIGtoaSBuZ+G7pywgbMOgbSBjaG8gZ2nhuqVjIG5n4bunIGLhu4sgZ2nDoW4gxJFv4bqhbi4gTsOqbiB0w7RpIGNo4buNbiBiaeG6v24gJ1NsZWVwIERpc29yZGVyJyBsw6BtIGJp4bq/biBwaOG7pSB0aHXhu5ljIMSR4buDIHhlbSB4w6l0IGPDoWMgbmd1ecOqbiBuaMOibiBk4bqrbiDEkcOqbiB0w6xuaCB0cuG6oW5nIG7DoHkuDQoNCg0KIyMjIFRow7RuZyBrw6ogbcO0IHThuqMNCg0KYGBge3J9DQoNCnRhYmxlKGQkYFNsZWVwIERpc29yZGVyYCkNCmQgIHw+IGdncGxvdChhZXMoeCA9IGBTbGVlcCBEaXNvcmRlcmAsIHkgPSBhZnRlcl9zdGF0KGNvdW50KSkpICsgZ2VvbV9iYXIoZmlsbCA9ICdibHVlJykgKyBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSkpKSwgc3RhdCA9ICdjb3VudCcsIGNvbG9yID0gJ3JlZCcsIHZqdXN0ID0gLSAuNSkgKyB0aGVtZV9jbGFzc2ljKCkgKyBsYWJzKHggPSAnR2nhuqVjIG5n4bunJywgeSA9ICdT4buRIG5nxrDhu51pJykNCmBgYA0KDQoNCsSQ4bq/IHRodeG6rW4gdGnhu4duIGjGoW4gY2hvIHZp4buHYyBz4butIGThu6VuZyBi4buZIGThu68gbGnhu4d1LCB0w7RpIHRo4buxYyBoaeG7h24gdmnhu4djIGfDoW4gdG/DoG4gYuG7mSBk4buvIGxp4buHdSBjaG8gbeG7mXQgYmnhur9uIHTDqm4gYGRgLiBTYXUgxJHDsywgdGjDtG5nIHF1YW4gdmnhu4djIGzDonAgYuG6o25nIHbDoCBtw7QgdOG6oyBk4buvIGxp4buHdSBi4bqxbmcgYmnhu4N1IMSR4buTIGPhu5l0IMSRxrBuZyB0YSBjw7MgdGjhu4MgdGjhuqV5IGjGoW4gNDAlIG5nxrDhu51pIGPDsyBjw6FjIGJp4buDdSBoaeG7h24gcuG7kWkgbG/huqFuIGdp4bqlYyBuZ+G7py4gQ+G7pSB0aOG7gywgbmfGsOG7nWkgbmfhu6cga2jDtG5nIMSR4bunIGdp4bqlYyAoYmnhu4N1IGhp4buHbiBsw6AgSW5zb21uaWEpIGNoaeG6v20gMjAsNTklIHTGsMahbmcgxJHGsMahbmcgNzcgbmfGsOG7nWksIG5nxrDhu51pIGPDsyBnaeG6pWMgbmfhu6cgYuG7iyBnacOhbiDEkW/huqFuIChiaeG7g3UgaGnhu4duIGzDoCBTbGVlcCBBcG5lYSkgbMOgIDIwLDg2JSBjw7MgNzggbmfGsOG7nWkuIFN1eSByYSBwaOG6p24gdHLEg20gbmfGsOG7nWkgY8OzIGhhaSB0cmnhu4d1IHRy4bupbmcgdHLDqm4gbMOgIGfhuqduIG5oxrAgYuG6sW5nIG5oYXUuIEPDsm4gbOG6oWksIDIxOSBuZ8aw4budaSBjaGnhur9tIDU4LDU2JSBsw6Aga2jDtG5nIGPDsyBiaeG7g3UgaGnhu4duLg0KDQojIyMgTcO0IHBo4buPbmcgYmnhur9uIGPDsyBwaMOibiBwaOG7kWkgTmjhu4sgVGjhu6ljDQoNClRyb25nIGLDoGkgdGnhu4N1IGx14bqtbiBuw6B5IHTDtGkgdGnhur9uIGjDoG5oIG5naGnDqm4gY+G7qXUgZ2nhuqVjIG5n4bunIG7Dqm4gdGEgdOG6oW8gcmEgbeG7mXQgYmnhur9uIG3hu5tpIGPDsyB0w6puIGBTbGVlcGAgdsOgIHRoaeG6v3QgbOG6rXAgaGFpIGJp4bq/biB0aMOgbmggaGFpIGJp4bq7dSBoaeG7h24gbMOgOg0KDQotIEtow7RuZyBjw7MgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIGzDoCBgbm9gDQoNCi0gTmfGsOG7nWkgY8OzIHRyaeG7h3UgY2jhu6luZyBt4bqldCBuZ+G7pyBsw6AgYHllc2A6IEJp4buDdSBoaeG7h24gbsOgeSAgxJHGsOG7o2MgZ+G7mXAgdOG7qyB2aeG7h2MgY+G6o20gdGjhuqV5IGtow7Mgbmfhu6coa8OtIGhp4buHdSBsw6AgYEluc29tbmlhYCkgdsOgIGdpw6FuIMSRb+G6oW4gZ2nDoW4gxJFv4bqhbiBnaeG6pWMgbmfhu6cgKGvDrSBoaeG7h3UgbMOgIGBTbGVlcCBBcG5lYWApIGPhu6dhIGJp4bq/biBiaeG6v27igJhTbGVlcCBEaXNvcmRlcuKAmSAgDQoNCmBgYHtyfQ0KU2xlZXAgPC0gbWFwdmFsdWVzKGQkYFNsZWVwIERpc29yZGVyYCwgZnJvbT0gYygnSW5zb21uaWEnLCAnTm9uZScsICdTbGVlcCBBcG5lYScgKSwgdG89YygneWVzJywgJ25vJywneWVzJykpDQp0YWJsZShTbGVlcCkNCmQgPC0gZGF0YS5mcmFtZShkLCBTbGVlcCkNCmBgYA0KDQpUaGVvIHRo4buRbmcga8OqIG5nxrDhu51pIGPDsyB0cmnhu4d1IGNo4bupbmcgbMOgIDE1NSBuZ8aw4budaSB2w6Aga2jDtG5nIGPDsyB0cmnhu4d1IGNo4bupbmcgbMOgIDIxOSBuZ8aw4budaQ0KDQojIyMgTeG7pWMgdGnDqnUNCg0KLSBDw6FjIHTDrG5oIHRy4bqhbmcgbeG6pXQgbmfhu6cgY8OzIHBo4bqjaSBsw6AgY+G7iyDhuqNuaCBoxrDhu59uZyBi4bufaSBnaeG7m2kgdMOtbmgga2jDtG5nPyANCg0KLSBT4buRIGzhuqduIHRpbSBuZ8aw4budaSBk4bqtcCBraGkgbmfFqSBjw7MgcXVhbiDhuqNuaCBoxrDhu59uZyB0aOG7gyBuw6BvIMSR4bq/biBuaOG7r25nIG5nxrDhu51pIG3huqV0IG5n4bunPw0KDQotIE5nxrDhu51pIGPDom4gbmfhu6cgYmFvIGzDonUgxJHhu4Mga2jDtG5nIGLhu4sgcuG7kWkgbG/huqFuIGdp4bqlYyBuZ+G7pyBraMO0bmc/DQoNCi0gTeG7qWMgZOG7mSBjxINuZyB0aOG6s25nIG7DoG8gbMOgIG3hu5l0IG3huqV0DQoNCiMgQ2jGsMahbmcgMzogVGjhu5FuZyBrw6ogbcO0IHThuqMgY2hvIG3hu5l0IGJp4bq/bg0KDQojIyBUaOG7kW5nIGvDqiBtw7QgdOG6oyBjaG8gbeG7mXQgYmnhur9uDQoNCg0KIyMjIFRo4buRbmcga8OqIGNobyBiaeG6v24gxJHhu4tuaCBMxrDhu6NuZw0KDQojIyMjIEJp4bq/biBBZ2UgKHR14buVaSBuZ2jhu4EpDQoNCmBgYHtyfQ0Kc3VtbWFyeShkJEFnZSkNCmdncGxvdChkYXRhID0gZCwgbWFwcGluZyA9IGFlcyh4ID0gQWdlKSkgKyBnZW9tX2RlbnNpdHkoc2l6ZSA9IDEsIGFscGhhID0gMC4yLCBjb2xvdXI9IiNFNjlGMDAiKSsgbGFicyh0aXRsZSA9ICLEkOG7mSB0deG7lWkiKQ0KYGBgDQoNCkZpcnN0IHF1YXJ0aWxlID0gMiBjw7MgbmdoxKlhIGzDoCAyNSUgxJHhu5FpIHTGsOG7o25nIG5naGnDqm4gY+G7qXUgY8OzIMSR4buZIHR14buVaSBi4bqxbmcgaG/hurdjIG5o4buPIGjGoW4gMiBuxINtLiBUxrDGoW5nIHThu7EsIFRoaXJkIHF1YXJ0aWxlID0gNiBjw7MgbmdoxKlhIGzDoCA3NSUgxJHhu5FpIHTGsOG7o25nIGPDsyDEkeG7mSB0deG7lWkgYuG6sW5nIGhv4bq3YyB0aOG6pXAgaMahbiA2IG7Eg20uIFThuqV0IG5oacOqbiBz4buRIHRydW5nIHbhu4sgKG1lZGlhbikgNCBjxaluZyBjw7MgbmdoxKlhIGzDoCA1MCUgxJHhu5FpIHTGsOG7o25nIGPDsyBuxINtIMSRaSBsw6BtIDQsNzcgdHLhu58geHXhu5FuZw0KDQojIyMjIEJp4bq/biBTbGVlcCBEdXJhdGlvbiAodGjhu51pIGdpYW4gbmfhu6cpDQoNCmBgYHtyfQ0Kc3VtbWFyeShkJFNsZWVwLkR1cmF0aW9uKQ0KcGxvdChkJFNsZWVwLkR1cmF0aW9uLCB0eXBlPSdsJyxjb2wgPSAnIzlDMDgyNCcsIGF4ZXM9RkFMU0UsIHhsYWI9JycsIHlsYWI9JycsICxtYWluPScnKQ0KYm94KGNvbD0nI0JDQ0ZCNCcpDQptdGV4dCgnQmnhu4N1IMSR4buTIHRo4budaSBnaWFuIG5n4bunJywgYWRqPTAsIHNpZGU9MykNCmF4aXMoc2lkZT0xLCBhdD1jKDAsNTAsIDE1MCwgMjUwLCAzNTApKQ0KYGBgDQoNCg0KQ8OidSBs4buHbmggc3VtbWFyeSgpIGNobyBiaeG6v24gIGBTbGVlcCBEdXJhdGlvbmAgKMSRw6FuaCBnacOhIHbhu4EgbeG7qWMgxJHhu5kgY8SDbmcgdGjhurNuZyB0cm9uZyBjw7RuZyB2aeG7h2MpIGPhu6dhIG5o4buvbmcgbmfGsOG7nWkgdGhhbSBnaWEga2jhuqNvIHPDoXQsIHRhIGPDsyB0aOG7gyBuaOG6rW4gdGjhuqV5IG5nxrDhu51pIG5n4bunIMOtdCAgbmjhuqV0IGzDoCA1LDggaCwgY2FvIG5o4bqldCBsw6AgxJFp4buDbSA4LDVoLCB0cnVuZyBiw6xuaCDEkWnhu4NtIHPhu5EgbMOgIDcsMTMsIGPDsyAyNSUgc+G7kSBuZ8aw4budaSBjw7MgxJFp4buDbSBsw6AgNiw0LCA1MCUgbmfGsOG7nWkgNywyaCwgdGjDqm0gdsOgbyDEkcOzIGPDsyA3NSUgbmfGsOG7nWkgbmjhu48gaMahbiDEkWnhu4NtIDcsOC4NCg0KIyMjIyBCaeG6v24g4oCYUGh5c2ljYWwgQWN0aXZpdHkgTGV2ZWzigJkgKCBob+G6oXQgxJHhu5luZyB0aOG7gyBjaOG6pXQpDQoNCmBgYHtyfQ0KaCA8LSBkICU+JSBncm91cF9ieShQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCkgJT4lICByZWZyYW1lKG4gPSBuKCkpICU+JSAgbXV0YXRlKHRhYmxlKGQkUGh5c2ljYWwuQWN0aXZpdHkuTGV2ZWwpLCBwZXIgPSBuL3N1bShuKSkgDQpkICU+JSBncm91cF9ieShQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCkgJT4lICByZWZyYW1lKG4gPSBuKCkpICU+JSBtdXRhdGUodGFibGUoZCRQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCksIHBlciA9IG4vc3VtKG4pKSB8PiBnZ3Bsb3QoYWVzKHggPSAnJywgeSA9IHBlciwgZmlsbCA9IFBoeXNpY2FsLkFjdGl2aXR5LkxldmVsKSkgKyBnZW9tX2NvbCgpDQpkYXRhdGFibGUoaCkNCmBgYA0KDQpOaMOsbiB2w6BvIGLhuqNuIGjhuqd1IGjhur90IG3hu41pIG5nxrDhu51pIMSR4buBdSB0aGFtIGdpYSBjw6FjIGhv4bqhdCDEkeG7mW5nIHRo4buDIGNo4bqldCB04burIDMwIC05MCBwaMO6dCAxIG5nw6B5IG5oxrBuZyBuaGnhu4F1IG5o4bqldCBsw6AgaG/huqF0IMSR4buZbmcgNjAgcGjDunQgbeG7l2kgbmfDoHkuDQoNCiMjIyMgQmnhur9uIOKAmFF1YWxpdHkgb2YgU2xlZXDigJkoxJHDoW5oIGdpw6EgY2jhuqV0IGzGsOG7o25nIGdp4bqlYyBuZ+G7pykNCg0KYGBge3J9DQpzdW1tYXJ5KGQkUXVhbGl0eS5vZi5TbGVlcCkNCnRhYmxlKGQkUXVhbGl0eS5vZi5TbGVlcCkNCmQgfD4gZ2dwbG90KGFlcyh4ID0gUXVhbGl0eS5vZi5TbGVlcCwgeSA9IGFmdGVyX3N0YXQoY291bnQpKSkgKyBnZW9tX2JhcihmaWxsID0gJ3NreWJsdWUnKSArIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQoYWZ0ZXJfc3RhdChjb3VudC9zdW0oY291bnQpKSkpLCBzdGF0ID0gJ2NvdW50JywgY29sb3IgPSAnbWFnZW50YScsIHZqdXN0ID0gLSAuNSkgKyB0aGVtZV9jbGFzc2ljKCkgKyBsYWJzKHggPSAnxJBp4buDbSDEkcOhbmggZ2nDoSBnaeG6pWMgbmfhu6cnLCB5ID0gJ1Phu5EgbmfGsOG7nWknKSArIGNvb3JkX2ZsaXAoKQ0KYGBgDQoNClRoZW8gdmnhu4djIHRo4buxYyBoaeG7h24gY8OidSBs4buHbmggc3VtbWFyeSgpIGNobyBiaeG6v24gJ1F1YWxpdHkgb2YgU2xlZXAnIChz4buRIMSRaeG7g20gxJHDoW5oIGdpw6EgZ2nhuqVjIG5n4bunKSBj4bunYSBuaOG7r25nIG5nxrDhu51pIHRoYW0gZ2lhIGto4bqjbyBzw6F0LCB0YSBjw7MgdGjhu4Mgbmjhuq1uIHRo4bqleSBuZ8aw4budaSB0aOG6pXAgxJFp4buDbSBuaOG6pXQgbMOgIDQsIGNhbyBuaOG6pXQgbMOgIMSRaeG7g20gOCwgdHJ1bmcgYsOsbmggxJFp4buDbSBz4buRIGzDoCA3LDMxLCBjw7MgMjUlIHPhu5EgbmfGsOG7nWkgY8OzIMSRaeG7g20gbMOgIDYgbsSDbSwgNTAlIG5nxrDhu51pIDcgxJFp4buDbSwgdGjDqm0gdsOgbyDEkcOzIGPDsyA3NSUgbmfGsOG7nWkgbmjhu48gaMahbiDEkWnhu4NtIDkuDQoNClNhdSDEkcOzLCDEkeG7gyBiaeG7g24gY2jDrW5oIHjDoWMgduG7gSDEkWnhu4NtIGPhu6dhIHThu6tuZyBuZ8aw4budaSB0YSBjw7MgdGjhu4MgcXVhbiBzw6F0IGThu68gbGnhu4d1IHRyw6puIGLhuqNuIHbDoCBiaeG7g3UgxJHhu5MgY+G7mXQgbmdhbmcgdMO0aSBuaMOsbmggdGjhuqV5Og0KDQotIEPDsyA1IG5nxrDhu51pIDQgxJFp4buDbSBraG/huqNuZyAxLDM0JQ0KDQotIEPDsyA3IG5nxrDhu51pIDUgxJFp4buDbSBraG/huqNuZyAxLDg3JQ0KDQotIEPDsyAxMDUgbmfGsOG7nWkgNiDEkWnhu4NtIGtob+G6o25nIDI4LDA3JQ0KDQotIEPDsyA3NyBuZ8aw4budaSA3IMSRaeG7g20ga2hv4bqjbmcgMjAsNTklDQoNCi0gQ8OzIDEwOSBuZ8aw4budaSA4IMSRaeG7g20ga2hv4bqjbmcgMjksMTQlDQoNCi0gQ8OzIDcxIG5nxrDhu51pIDkgxJFp4buDbSBraG/huqNuZyAxOCw5OCUNCg0KUGjhuqduIMSRw7RuZyBuZ8aw4budaSB0aGFtIGdpYSDEkcaw4bujYyA3LTkgxJFp4buDbSwgbmhp4buBdSBuaOG6pXQgbMOgIG5nxrDhu51pIDkgxJFpw6ptLCB0cm9uZyBraGkgxJHDsyBuZ8aw4budaSBnaeG6pWMgbmfhu6cgNCDEkWnhu4NtIGzDoCBy4bqldCB0aOG6pXAgY2jhu4kgaMahbiAxJSB0csOqbiB04buVbmcgc+G7kSBuZ8aw4budaSB0aGFtIGdpYSBraOG6o28gc8OhdC4gDQoNCiMjIyMgQmnhur9uIFN0cmVzcyBMZXZlbCht4bupYyDEkeG7mSBjxINuZyB0aOG6s25nKQ0KDQpgYGB7cn0NCnRtcCA8LSB0YWJsZShkJFN0cmVzcy5MZXZlbCkNCncgPC0gZCB8PiBncm91cF9ieShTdHJlc3MuTGV2ZWwpIHw+IHJlZnJhbWUobiA9IG4oKSkgfD4gbXV0YXRlKHRtcCwgcGVyID0gbi9zdW0obikpDQpkYXRhdGFibGUodykNCncgfD4gZ2dwbG90KGFlcyh4ID0gJycsIHkgPSBwZXIsZmlsbCA9IFN0cmVzcy5MZXZlbCkpICsgZ2VvbV9jb2woKSArIGNvb3JkX3BvbGFyKCd5JykNCmBgYA0KDQoNCk5ow6xuIHF1YW4gY8OhYyBt4bupYyDEkeG7mSBjxINuZyB0aOG6s25nIHRyb25nIGPDtG5nIHZp4buHYyBj4bunYSBzw6F1IGPhuqVwIMSR4buZIHThu6sgMyDEkeG6v24gNiBn4bqnbiBi4bqxbmcgbmhhdS4gVHJvbmcgYmnhur9uIGPDsyB0aOG7gyB0aOG6pXkgbmhp4buBdSBuaOG6pXQgbMOgIG5o4buvbmcgbmfGsOG7nWkgY8SDbmcgdGjhurNuZyDhu58gbeG7qWMgMyBjw7MgNzEgbmfGsOG7nWkga2hv4bqjbmcgMTgsOTglLCDDrXQgbmjhuqV0IGzDoCDhu58gbeG7qWMgNiBjaGnhur9tIDEyLDMlLiAgDQoNCg0KIyMjIyBCaeG6v24gSGVhcnQgUmF0ZSAobmjhu4twIHRpbSkNCg0KYGBge3J9DQp0YWJsZShkJEhlYXJ0LlJhdGUpDQp0YWJsZShkJEhlYXJ0LlJhdGUpL3N1bSh0YWJsZShkJEhlYXJ0LlJhdGUpKQ0KcGxvdChkJEhlYXJ0LlJhdGUsIHR5cGU9J2wnLCBjb2wgPSAnYmx1ZScsIGF4ZXM9RkFMU0UseGxhYj0nJywgeWxhYj0nJykNCmJveChjb2w9J3JlZCcpDQptdGV4dCgnQmnhu4N1IMSR4buTIG5o4buLcCB0aW0nLCBhZGo9MSwgc2lkZT0zKQ0KYXhpcyhzaWRlPTEpDQpgYGANCg0KVHJvbmcgYuG6o25nIGhhaSBjaGnhu4F1IHRhIHRo4bqleSwgbmfGsOG7nWkgdGhhbSBnaWEga2jhuqNvIHPDoXQgY8OzIG5o4buLcCB0aW0gcGjDom4gYuG7kSB04burIDY1IMSR4bq/biA4NiBuaOG7i3AvIHBow7p0LiBQaOG6p24gbOG7m24gbmfGsOG7nWkgdGhhbSBnaWEga2jhuqNvIHPDoXQgY8OzIG5o4buLcCB0aW0g4bufIGto4bupYyDEkcOidSAoNjUtNjgpbmjhu4twLyBwaMO6dC4NCg0KIyMjIyBCaeG6v24g4oCYRGFpbHkgU3RlcHPigJkoc+G7kSBixrDhu5tjIMSRaSBs4bqhaSkNCg0KYGBge3J9DQp0YWJsZShkJERhaWx5LlN0ZXBzKQ0KbWVhbihkJERhaWx5LlN0ZXBzKQ0Kc2QgPC0gc2QoZCREYWlseS5TdGVwcykNCnNkDQpzZC9zcXJ0KGxlbmd0aChkJERhaWx5LlN0ZXBzKSkgDQpnZ3Bsb3QoZGF0YSA9IGQsIGFlcyh4ID0gRGFpbHkuU3RlcHMpKSArIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMTAwMCwgY29sb3IgPSAicmVkIiwgZmlsbCA9ICJibHVlIiwgYWxwaGEgPSAwLjEpDQpgYGANCk5ow6xuIHbDoG8gdGjhu5FuZyBrw6ogdGEgdGjhuqV5IGPDsyAyMCBiaeG7g24gaGnhu4duIHRyb25nIGJp4bq/biB24bubaSBz4buRIGLGsOG7m2MgxJFpIHRydW5nIGLDrG5oIGzDoCA2ODE3IGLGsOG7m2MuIEjDoG0gc2QoKSBjw7Mga+G6v3QgcXXhuqMgMTYxOCDEkcaw4bujYyBkw7luZyDEkeG7gyB0w61uaCBzYWkgc+G7kSBjaHXhuqluIHbDoCDEkeG7mSBs4buHY2ggY2h14bqpbiBj4bunYSBiaeG6v24gdMOtbmggcmEgxJHGsOG7o2MgbMOgIDgzLDY2IA0KDQoNCiMjIyMgVGjhu5FuZyBrw6ogY8O5bmcgbMO6YyBuaGnhu4F1IGJp4bq/biANCg0KVuG7m2kgduG7m2kgYmnhur9uIMSR4buLbmggbMaw4bujbmcgdGEgY8OzIHRo4buDIHRo4buRbmcga8OqIGPDoWMgY2jhu4kgxJHGoW4gZ2nhuqNuIGPDuW5nIG3hu5l0IGzDumMgYuG6sW5nIGzhu4duaCBzdW1tYXJ5IDoNCg0KYGBge3J9DQpmZCA8LSBkYXRhLmZyYW1lKGQkQWdlLGQkU2xlZXAuRHVyYXRpb24sZCRRdWFsaXR5Lm9mLlNsZWVwLGQkUGh5c2ljYWwuQWN0aXZpdHkuTGV2ZWwsZCRTdHJlc3MuTGV2ZWwsZCRCbG9vZC5QcmVzc3VyZSxkJEhlYXJ0LlJhdGUsZCREYWlseS5TdGVwcykgDQpzdW1tYXJ5KGZkKQ0KYGBgDQoNCk7Ds2kgY2h1bmcsIGvhur90IHF14bqjIG7DoHkgxJHGoW4gZ2nhuqNuIHbDoCBjw6FjIHZp4bq/dCB04bqvdCBjxaluZyBjw7MgdGjhu4MgZOG7hSBoaeG7g3UuIENow7ogw70sIHRyb25nIGvhur90IHF14bqjIHRyw6puLCBjw7MgaGFpIGNo4buJIHPhu5Eg4oCcMXN0IFF14oCdIHbDoCDigJwzcmQgUXXigJ0gY8OzIG5naMSpYSBsw6AgZmlyc3QgcXVhcnRpbGUgKHTGsMahbmcgxJHGsMahbmcgduG7m2kgduG7iyB0csOtIDI1JSkgdsOgIHRoaXJkIHF1YXJ0aWxlICh0xrDGoW5nIMSRxrDGoW5nIHbhu5tpIHbhu4sgdHLDrSA3NSUpIGPhu6dhIG3hu5l0IGJp4bq/biBz4buRLiBW4bubaSBk4buvIGxp4buHdSDEkeG7i25oIHTDrW5oIHQgY8OybiBjw7MgdGjhu4MgdGjhu5FuZyB0w61uaCB24buBIHNhaSBz4buRIGNodeG6qW4gdsOgICDEkeG7mSBs4buHY2ggY2h14bqpbi4gxJDDqiB0w61uaCB0w7NuIMSR4buTbmcgdGjhu51pIHRhIGPDsyB0aOG7gyB0aGnhur90IGvDqnQgbeG7mXQgaMOgbSBuaMawIHNhdToNCg0KYGBge3J9DQpoYW0gPC0gZnVuY3Rpb24oeCl7DQogc2QgPC0gc2QoeCkNCiBzZSA8LSBzZC9zcXJ0KGxlbmd0aCh4KSkNCiBjKGBTYWkgc8O0IGNodeG6qW5gPXNkLGDEkOG7mSBs4buHY2ggY2h14bqpbmA9c2UpDQp9IA0KaGFtKGQkQWdlKQ0KaGFtKGQkU2xlZXAuRHVyYXRpb24pDQpoYW0oZCRRdWFsaXR5Lm9mLlNsZWVwKQ0KaGFtKGQkUGh5c2ljYWwuQWN0aXZpdHkuTGV2ZWwpDQpoYW0oZCRTdHJlc3MuTGV2ZWwpDQpoYW0oZCRIZWFydC5SYXRlKQ0KaGFtKGQkRGFpbHkuU3RlcHMpDQpgYGANClTDtGkgY3VuZyBkaW5nIGjDoG0gxJHhursgdGnDqm4gaMOgbmggduG7hSBiaeG7g3UgxJHhu5MgZOG6oW5nIGLDoW5oIGNobyBjw6FjIGJp4bq/bjoNCg0KKipCaeG7g3UgxJHhu5MgYsOhbmgqKiANCg0KYGBge3J9DQpteXRhYmwgPC0gZnVuY3Rpb24oeCwgZ3JvdXApIHsNCiAgdG1wIDwtIHRhYmxlKHgkZ3JvdXApDQogIHcgPC0geCAlPiUgDQogICAgZ3JvdXBfYnkoe3tncm91cH19KSAlPiUgDQogICAgcmVmcmFtZShuID0gbigpKSAlPiUNCiAgICBtdXRhdGUodG1wLCBwZXIgPSBuL3N1bShuKSkgDQogIGR0IDwtIHcgfD4gZ2dwbG90KGFlcyh4ID0gJycsIHkgPSBwZXIpKSArIGdlb21fY29sKGFlcyhmaWxsPXt7Z3JvdXB9fSksIHN0YXQgPSAiaWRlbnRpdHkiLCBwYXJhbXMgPSBsaXN0KG5hLnJtID0gRkFMU0UpKSsgY29vcmRfcG9sYXIoJ3knKSANCiAgbGlzdCggYMSQ4buTIHRo4buLIGLDoW5oYD1kdCkNCn0NCg0KbXl0YWJsKGQsIEFnZSkNCm15dGFibChkLCBTbGVlcC5EdXJhdGlvbikgDQpteXRhYmwoZCwgUXVhbGl0eS5vZi5TbGVlcCkNCm15dGFibChkLCBQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCkNCm15dGFibChkLCBTdHJlc3MuTGV2ZWwpDQpteXRhYmwoZCwgSGVhcnQuUmF0ZSkNCm15dGFibChkLCBEYWlseS5TdGVwcykNCmBgYA0KDQpOZ2/DoGkgcmEsIHTDtGkgY8OybiB0acOqbiBow6BuaCB24bq9IHRow6ptIGPDoWMgxJHGsOG7nW5nIG3huq10IMSR4buZIGNobyBiaeG6v24gOg0KIA0KIA0KYGBge3J9DQpoMSA8LSBnZ3Bsb3QoZGF0YSA9IGQsIG1hcHBpbmcgPSBhZXMoeCA9IEFnZSkpICsgZ2VvbV9kZW5zaXR5KHNpemUgPSAxLCBhbHBoYSA9IDAuMiwgY29sb3VyPSIjRTY5RjAwIikrIGxhYnModGl0bGUgPSAixJDhu5kgdHXhu5VpIikNCmgyIDwtIGdncGxvdChkYXRhID0gZCwgbWFwcGluZyA9IGFlcyh4ID0gU2xlZXAuRHVyYXRpb24pKSArIGdlb21fZGVuc2l0eShzaXplID0gMSwgYWxwaGEgPSAwLjIsIGNvbG91cj0iIzU2QjRFOSIpKyBsYWJzKHRpdGxlID0gIlRo4budaSBnaWFuIG5n4bunIikNCmgzIDwtIGdncGxvdChkYXRhID0gZCwgbWFwcGluZyA9IGFlcyh4ID0gUXVhbGl0eS5vZi5TbGVlcCkpICsgZ2VvbV9kZW5zaXR5KHNpemUgPSAxLCBhbHBoYSA9IDAuMiwgY29sb3VyPSIjNTZCNEU5IikrIGxhYnModGl0bGUgPSAiQ2jhuqV0IGzGsOG7o25nIGdpYW4gbmfhu6ciKQ0KaDQgPC0gZ2dwbG90KGRhdGEgPSBkLCBtYXBwaW5nID0gYWVzKHggPSBQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCkpICsgZ2VvbV9kZW5zaXR5KHNpemUgPSAxLCBhbHBoYSA9IDAuMiwgY29sb3VyPSIjRjBFNDQyIikrIGxhYnModGl0bGUgPSAiSG/huqF0IMSR4buZbmciKQ0KaDUgPC0gZ2dwbG90KGRhdGEgPSBkLCBtYXBwaW5nID0gYWVzKHggPSBTdHJlc3MuTGV2ZWwpKSArIGdlb21fZGVuc2l0eShzaXplID0gMSwgYWxwaGEgPSAwLjIsIGNvbG91cj0iIzAwNzJCMiIpKyBsYWJzKHRpdGxlID0gIkPEg25nIHRo4bqzbmciKQ0KaDYgPC0gZ2dwbG90KGRhdGEgPSBkLCBtYXBwaW5nID0gYWVzKHggPSBIZWFydC5SYXRlKSkgKyBnZW9tX2RlbnNpdHkoc2l6ZSA9IDEsIGFscGhhID0gMC4yLCBjb2xvdXI9IiNENTVFMDAiKSsgbGFicyh0aXRsZSA9ICJOaOG7i3AgdGltIikNCmg3IDwtIGdncGxvdChkYXRhID0gZCwgbWFwcGluZyA9IGFlcyh4ID0gRGFpbHkuU3RlcHMpKSArIGdlb21fZGVuc2l0eShzaXplID0gMSwgYWxwaGEgPSAwLjIsIGNvbG91cj0iI0NDNzlBNyIpKyBsYWJzKHRpdGxlID0gIsSQaSBi4buZIikNCnBsb3RfZ3JpZChoMSwgaDIsIGgzLCBoNCwgaDUsIGg2LCBoNywgbGFiZWxzID0gYygnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycpLCAgc2l6ZSA9IDEwKQ0KYGBgDQoNCiMjIyBUaOG7kW5nIGvDqiBjaG8gYmnhur9uIMSR4buLbmggdMOtbmgNCg0KIyMjIyBCaeG6v24gR3JlbmRlciAoZ2nhu5tpIHTDrW5oKQ0KDQpgYGB7cn0NCnRhYmxlKGQkR2VuZGVyKQ0KdGFibGUoZCRHZW5kZXIpL3N1bSh0YWJsZShkJEdlbmRlcikpDQpkIHw+IGdncGxvdChhZXMoeCA9IEdlbmRlciwgeSA9IGFmdGVyX3N0YXQoY291bnQpKSkgKyBnZW9tX2JhcihmaWxsID0gJ2JsdWUnKSArIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQoYWZ0ZXJfc3RhdChjb3VudC9zdW0oY291bnQpKSkpLCBzdGF0ID0gJ2NvdW50JywgY29sb3IgPSAnbWFnZW50YScsIHZqdXN0ID0gLSAuNSkgKyB0aGVtZV9jbGFzc2ljKCkgKyBsYWJzKHggPSAnR2nhu5tpIHTDrW5oJywgeSA9ICdT4buRIG5nxrDhu51pJykgKyBjb29yZF9mbGlwKCkNCmBgYA0KDQpCaeG6v24gZ2FuZGVyIGzDoCBiaeG6v24gxJHhu4tuaCB0w61uaCwgdGjhu7FjIGhp4buHbiBt4buZdCBwaMOpcCDEkeG6v20gxJHGoW4gZ2nhuqNuIHRhIHRo4bqleSBjw7MgMTg1IChjaGnhur9tIDUwLDUlKSBuZ8aw4budaSBuYW0gdsOgIDE4OSBuZ8aw4budaSBu4buvIChjaGnhur9tIDQ5LDUlKSB0aGFtIGdpYSB2w6BvIGN14buZYyBraOG6o28gc8OhdC4NCg0KIyMjIyBCaeG6v24gb2NjdXBhdGlvbiAobmdo4buBIG5naGnhu4dwKQ0KDQpgYGB7cn0NCnRhYmxlKGQkT2NjdXBhdGlvbikNCnggPC0gIGMoMzcsIDcxLCA2MywgNDcsIDEsIDczLCAyLCAzMiwgNCwgNCwgNDApDQpsYWJlbHMgPC0gIGMoJ0FjY291bnRhbnQnLCAnRG9jdG9yJywgJ0VuZ2luZWVyJywgJ0xhd3llcicsJ01hbmFnZXInLCAnTnVyc2UnLCAnU2FsZXMgUmVwcmVzZW50YXRpdmUnLCAnU2FsZXNwZXJzb24nLCAnU2NpZW50aXN0JywgJ1NvZnR3YXJlIEVuZ2luZWVyJywgJ1RlYWNoZXInKQ0KcGllcGVyY2VudDwtIHJvdW5kKDEwMCp4L3N1bSh4KSwgMSkNCnBpZSh4LCBsYWJlbHMgPSBwaWVwZXJjZW50LCBtYWluID0gJ0Jp4buDdSDEkeG7kyBuZ2jhu4EgbmdoaeG7h3AnLGNvbCA9IHJhaW5ib3cobGVuZ3RoKHgpKSkNCmxlZ2VuZCgndG9wcmlnaHQnLCBjKCdBY2NvdW50YW50JywgJ0RvY3RvcicsICdFbmdpbmVlcicsICdMYXd5ZXInLCdNYW5hZ2VyJywgJ051cnNlJywgJ1NhbGVzIFJlcHJlc2VudGF0aXZlJywgJ1NhbGVzcGVyc29uJywgJ1NjaWVudGlzdCcsICdTb2Z0d2FyZSBFbmdpbmVlcicsICdUZWFjaGVyJyksIGNleCA9IDAuOCwgZmlsbCA9IHJhaW5ib3cobGVuZ3RoKHgpKSkNCmBgYA0KDQpUcm9uZyAxMSBuZ8OgbmggxJHGsOG7o2MgZ2hpIG5o4bqtbiB0cm9uZyBi4buZIGThu68gbGnhu4d1IHRhIGPDsyB0aOG7gyBuaOG6rW4gdGjhuqV5IG5nw6BuaCDEkeG6oWkgZGnhu4duIGtpbmggZG9hbmggYFNhbGVzIFJlcHJlc2VudGF0aXZlYCBsw6Agbmhp4buBdSBuaMOidCBjw7MgNzMgbmfGsOG7nWkgKDE5LDUlKSx0aeG6v3AgbMOgIG5nw6BuaCBiw6FjIHPEqSBgRG9jdG9yYCB24bubaSA3MCBuZ8aw4budaSAoMTklKSwgw610IG5o4bqldCBsw6AgbmfGsOG7nWkgcXXhuqNuIGzDrSBgTWFuYWdlcmAgY2jhu4kgMSBuZ8aw4budaSAoMCwzJSkNCg0KIyMjIyBCaeG6v24gQk1JIENhdGVnb3J5IChjaOG7iSBz4buRIGPDom4gbuG6t25nKQ0KDQpgYGB7cn0NCnRhYmxlKGQkQk1JLkNhdGVnb3J5KQ0KZCB8PiBnZ3Bsb3QoYWVzKHggPUJNSS5DYXRlZ29yeSwgeSA9IGFmdGVyX3N0YXQoY291bnQpKSkgKyBnZW9tX2JhcihmaWxsID0gJ2dyZWVuJykgKyBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSkpKSwgc3RhdCA9ICdjb3VudCcsIGNvbG9yID0gJ2JsdWUnLCB2anVzdCA9IC0gLjQpICArIHRoZW1lX2NsYXNzaWMoKSArIGxhYnModGl0bGUgPSAnxJDhu5MgVGjhu4sgdGjhu4MgaGnhu4duIHRo4buDIHRy4buNbmcnLCB4ID0gJ1Ro4buDIHRy4buNbmcnLCB5ID0gJ1Phu5EgbmfGsOG7nWknKQ0KYGBgDQoNClRo4buRbmcga8OqIHRoZW8gYmnhur9uIOKAmEJNSSBDYXRlZ29yeeKAmTogSOG6oW5nIG3hu6VjIEJNSSBj4bunYSBt4buZdCBuZ8aw4budaS4gdGEgdGjhuqV5IGPDsyA0IGJp4buDdSBoaeG7h24gTm9ybWFsLCBOb3JtYWwgV2VpZ2h0LCBPYmVzZSwgT3ZlcndlaWdodC4gTm9ybWFsIGzDoCBiaeG7g3UgaGnhu4duIG5oaeG7gXUgbmjhuqV0IGjGoW4gNTIlIA0KIyMjIyBCaeG6v24gQm9vbGQgUHJlc3N1cmUgKGh1eeG6v3Qgw6FwKQ0KDQpgYGB7cn0NCnRhYmxlKGQkQmxvb2QuUHJlc3N1cmUpDQpnZ3Bsb3QoZGF0YSA9IGQpICsgZ2VvbV9iYXIobWFwcGluZyA9IGFlcyh4ID0gQmxvb2QuUHJlc3N1cmUsIGZpbGwgPSBCbG9vZC5QcmVzc3VyZSkpDQpgYGANCg0KQ8OzIHRo4buDIG7Ds2kgxJFhdCBsw6AgYmnhur9uIG5oaeG7gXUgYmnhu4N1IGhp4buHbiBuaOG6pXQgY+G7p2EgYuG7mSBk4buvIGxp4buHdSB24bubaSBoYWkgMjUgbmjDs20gaHV5w6p0IMOhcCBraMOhYyBuaGF1IGPhu6dhIG5nxrDhu51pIHRoYW0gZ2lhIGto4bqjbyBzw6F0IHRhIGPDsyB0aOG7gyBiaeG6v3QgbmjDs20gbmhp4buBdSBuaOG6pXQgY8OzIDk5IG5nxrDhu51pIGPDsyBodXnhur90IMOhcCBsw6AgMTMwLzg1Lg0KDQojIENoxrDGoW5nIDQ6IFRo4buRbmcga8OqIG3DtCB04bqjIHbDoCB0aOG7kW5nIGvDqiBzdXkgZGnhu4VuIGNobyBoYWkgYmnhur9uDQoNCioqU2F1IMSRw6J5LCB0w7RpIHRp4bq/biBow6BuaCB0aOG7kW5nIGvDqiBtw7QgdOG6oyBsw6BuIGzGsOG7o3QgY8OhYyBiaeG6v24gxJHhu5ljIGzhuq1wIHbhu5tpIGJp4bq/biBwaOG7pSB0aOG7pWMg4oCYU2xlZXAgRGlzb3JkZXLigJkoIG7Ds2kgY2jDrW5oIHjDoWMgaMahbiBsw6AgYmnhur9uIMSRw6MgxJHGsOG7o2MgbcO0IHBo4buPbmcgdGjDoG5oIHBow6JuIHBo4buRaSBOaOG7iyB0aOG7qWMgYFNsZWVwYCkgKiogDQoNCiMjIFF1YW4gaOG7hyBnaeG7r2EgZ2nhu5tpIHTDrW5oIHbDoCBnaeG6pWMgbmfhu6cgKFNsZWVwIC0gR2VuZGVyKQ0KDQojIyMgxJDhu5MgdGjhu4sgdsOgIGLhuqNuZyB04bqnbiBz4buRIA0KDQoNCmBgYHtyfQ0KZCB8PiBnZ3Bsb3QoYWVzKHggPSBTbGVlcCAsIHkgPSBhZnRlcl9zdGF0KGNvdW50KSkpICsgZ2VvbV9iYXIoZmlsbCA9ICdibHVlJykgKyBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSkpKSwgc3RhdCA9ICdjb3VudCcsIGNvbG9yID0gJ3JlZCcsIHZqdXN0ID0gLSAuNSkgKyBmYWNldF9ncmlkKC4gfiBHZW5kZXIpICsgbGFicyh4ID0gJ0dp4bqleSBuZ+G7pycsIHkgPSAnU+G7kSBuZ8aw4budaScpDQpgYGANCg0KYGBge3J9DQpkcyA8LSB0YWJsZShkJFNsZWVwLGQkR2VuZGVyKQ0KZHMNCmRzMSA8LSBwcm9wLnRhYmxlKGRzKQ0KZHMxDQphZGRtYXJnaW5zKGRzMSkNCmBgYA0KDQpLaGkgdGnhur9uIGjDoG5oIG5o4bqtbiB4w6l0IGdp4bqlYyBuZ+G7pyB2w6AgZ2nhu5tpIHTDrW5oIGPhu6dhIG5o4buvbmcgbmfGsOG7nWkgdGhhbSBnaWEga2jhuqNvIHPDoXQuIE5nxrDhu51pIMSR4buBdSBjw7MgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIGzDoCBu4buvIGdp4bubaSBjYW8gaMahbiBuYW0gZ2nhu5tpIGNow6puaCBs4buHY2ggbmhhdSBraG/huqNuZyAxNCUuDQoNCiMjIyBU4bu3IGzhu4cgY2jDqm5oIChPZGQgUmF0aW8pDQoNCmBgYHtyfQ0KZXBpdGFiKGRzLCBtZXRob2QgPSAnb2Rkc3JhdGlvJykNCmBgYA0KDQpHacOhIHRy4buLIGNow6puaCBs4buHY2ggY2hvIGNow7puZyB0YSBiaeG6v3QgbuG7ryBnaeG7m2kgY8OzIHRyaeG7h3QgY2jhu6luZyBt4bqldCBuZ+G7pyBraG/huqNuZyA1NSw2OCUgduG7m2kgbuG7ryBnaeG7m2kga2hpIGtow7RuZyBjw7MgdHJp4buHdCBjaOG7qW5nIG3huqV0IG5n4bunLiANCg0KIyMjIEtob+G6o25nIMaw4bubYyBsxrDhu6NuZyBjaG8gdOG7iSBs4buHIGPhu6dhIDIgdOG7lW5nIHRo4buDIA0KDQpUaOG7sWMgaGnhu4duIGLDoGkgdG/DoW4ga2nhu4NtIMSR4buLbmggZ2nhuqMgdGh1eeG6v3Qgc+G7sSBi4bqxbmcgbmhhdSB24buBIHThu7cgbOG7hyDhu58gY8OhYyBiaeG6v24gduG7m2kgMiB04buVbmcgdGjhu4MgY+G7p2EgYmnhur9uIFNsZWVwLCBuZ2jEqWEgbMOgIGNow7puZyB0YSB0aOG7sWMgaGnhu4duIGLDoGkgdG/DoW46IA0KDQpLaeG7g20gxJHhu4tuaCAkSF8wJDpwMT1wMg0KDQrGr+G7m2MgbMaw4bujbmcgc+G7sSBjaMOqbmggbOG7h2NoIHbhu4EgdOG7tyBs4buHIG3hu5l0IG5nxrDhu51pIG5hbSBjw7MgZ2nhu5tpIHTDrW5oIHbhu4EgZ2nhuqVjIG5n4bunIGdp4buvYSB0aOG6pXAgdsOgIGNhbw0KDQpgYGB7cn0NCnRtcG0gPC0gZFtkJFNsZWVwID09ICd5ZXMnLF0NCnRtcGYgPC0gZFtkJFNsZWVwID09ICdubycsXQ0KDQp0bXBtMyA8LSB0bXBtW3RtcG0kR2VuZGVyID09ICdNYWxlJyxdDQp0bXBmMyA8LSB0bXBmW3RtcGYkR2VuZGVyID09ICdNYWxlJyxdDQoNCmEgPC0gYyhucm93KHRtcG0pLCBucm93KHRtcGYpKQ0KYiA8LSBjKG5yb3codG1wbTMpLCBucm93KHRtcGYzKSkNCg0KcHJvcC50ZXN0KGIsYSkNCmBgYA0KDQpLaG/huqNuZyDGsOG7m2MgbMaw4bujbmcgdOG7tyBs4buHIG5o4buvbmcgbmfGsOG7nWkgbmFtIGPDsyDigJwgQ8OzIHRyaeG7h3UgY2jhu6luZyBt4bqldCBuZ+G7p+KAnSB24bubaSDEkeG7mSB0aW4gY+G6rXkgOTUlIGzDoDogJC0wLjM5MzcgPCBwIDwgLTAuMTg2NCQNCg0KIyMjIEtp4buDbSDEkeG7i25oIHTDrW5oIMSR4buZYyBs4bqtcCAtIGtp4buDbSDEkeG7i25oIGNoaSBiw6xuaCBwaMawxqFuZw0KDQpHaeG6oyB0aHV54bq/dCBIMDogWCxZIMSR4buZYyBsw6JwOyANCg0KxJDhu5FpIHRodXnhur90IEgxOiBYLFkga2jDtG5nIMSR4buZYyBs4bqtcA0KDQpUYSB0aeG6v24gaMOgbmgga2nhu4NtIMSR4buLbmggdMOtbmggxJHhu5ljIGzhuq1wIGPhu6dhIGJp4bq/biBTbGVlcChYKSB2w6AgYmnhur9uIEdlbmRlcihZKSBzYXUgYuG6sW5nIFIgdGhlbyBjw6FjIGLGsOG7m2MgxJHGsOG7o2Mga+G6v3QgcXXhuqM6DQoNCmBgYHtyfQ0KY2hpc3EudGVzdChkcykNCmBgYA0KDQpU4burIGLhuqNuZyBr4bq/dCBxdeG6oyB0YSBjw7MgcC12YWx1ZSA9ICQ2LjEwXnstOH0kIDwgMCwwNTogQsOhYyBi4buPIEgwDQoNCkvhur90IGx14bqtbiwgxJFp4buDbSDEkcOhbmggZ2nDoSBnaeG6pWMgbmfhu6cgduG7m2kgduG7m2kgZ2nhu5tpIHTDrW5oIGPhu6dhIG5o4buvbmcgbmfGsOG7nWkgdGjhu7FjIGhp4buHbiBraOG6o28gc8OhdCBjw7MgbGnDqm4gaOG7hyB24bubaSBuaGF1LCB24bubaSBt4bupYyDDvSBuZ2jEqWEgNSUNCg0KIyMgUXVhbiBo4buHIGdp4buvYSBz4buRIHR14buVaSAgdsOgIGdp4bqleSBuZ+G7pw0KDQojIyMgxJDhu5MgdGjhu4sgdsOgIGLhuqNuZyB04bqnbiBz4buRDQoNCmBgYHtyfQ0KZ2UgPC0gdGFibGUoZCRTbGVlcCxkJEFnZSkNCmdlDQpnZTEgPC0gcHJvcC50YWJsZShnZSkNCmdlMQ0KDQpnZ3Bsb3QoZGF0YT1kLGFlcyh4PUFnZSxmaWxsPVNsZWVwKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKyAgc2NhbGVfY29sb3JfY29sb3JibGluZCgpICsgZ2d0aGVtZXM6OnNjYWxlX2ZpbGxfY29sb3JibGluZCgpDQpgYGANCg0KVHJvbmcga2jhuqNvIGPDoWMsIHRhIHRo4bqleSDEkeG7mSB0deG7lWkgY+G7pyBuZ8aw4budaSB04burICgyNy01OSkgdHXhu5VpLiBUaGVvIGJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gdGjDrCBjw6BuZyBs4bubbiB0deG7lWkgbeG6rXQgxJHhu5kgY+G6o3Ugbmjhu7FuZyBuZ3XDsmkgY8OzIHRyaeG7h3UgY2jhu6luZyBt4bqldCBuZ+G7pyBz4bq9IGPDoG5nIGNhby4NCg0KIyMjIFThu7cgbOG7hyBjaMOqbmggKE9kZCBSYXRpbykNCg0KYGBge3J9DQpsb2dpc3RpYy5kaXNwbGF5KGdsbShmYWN0b3IoU2xlZXApfkFnZSxmYW1pbHk9Ymlub21pYWwsIGRhdGEgPWQpKQ0KYGBgDQpU4buJIGzhu4cgY2jDqm5oIGzhu4djaCBnaeG7r2EgdHXhu5VpIHbDoCBjw6FjIHRyaeG7h3UgY2jhu6luZyBt4bqldCBuZ+G7pyBsw6AgMSwxMiBnaWFvIMSR4buZbmcgdHJvbmcga2hv4bqjbmcgKDEuMDksMS4xNikgDQoNCiMjIyBLaeG7g20gxJHhu4tuaCBjaGkgYsOsbmggcGjGsMahbmcgDQoNCkdp4bqjIHRodXnhur90IEgwOiBYLFkgxJHhu5ljIGzDonA7IA0KDQrEkOG7kWkgdGh1eeG6v3QgSDE6IFgsWSBraMO0bmcgxJHhu5ljIGzhuq1wDQoNClRhIHRp4bq/biBow6BuaCBraeG7g20gxJHhu4tuaCB0w61uaCDEkeG7mWMgbOG6rXAgWCB2w6AgWSBi4bqxbmcgUiB0aGVvIGPDoWMgYsaw4bubYyDEkcaw4bujYyBr4bq/dCBxdeG6oyBzYXU6DQoNCg0KYGBge3J9DQpjaGlzcS50ZXN0KGdlKQ0KYGBgDQoNClThu6sgYuG6o25nIGvhur90IHF14bqjIHRhIGPDsyBwLXZhbHVlID0kMioxMF57LTZ9JCA8MCwwNTogQsOhYyBi4buPIEgwDQoNCkvhur90IGx14bqtbiwgdmnhu4djIG3huqV0IG5n4bunIHbhu5tpIHPhu5EgdHXhu5VpIGPhu6dhIG5o4buvbmcgbmfGsOG7nWkgdGjhu7FjIGhp4buHbiBraOG6o28gc8OhdCAgbMOgIGPDsyBxdWFuIGjhu4cgduG7m2kgbmhhdSwgduG7m2kgbeG7qWMgw70gbmdoxKlhIDUlDQoNCiMjIyBLaG/huqNuZyDGsOG7m2MgbMaw4bujbmcgY2hvIHThu4kgbOG7hyBj4bunYSAyIHThu5VuZyB0aOG7gyANCg0KVGjhu7FjIGhp4buHbiBiw6BpIHRvw6FuIGtp4buDbSDEkeG7i25oIGdp4bqjIHRodXnhur90IHPhu7EgYuG6sW5nIG5oYXUgduG7gSB04bu3IGzhu4cg4bufIGPDoWMgYmnhur9uIHbhu5tpIDIgdOG7lW5nIHRo4buDIGPhu6dhIGJp4bq/biBTbGVlcCwgbmdoxKlhIGzDoCBjaMO6bmcgdGEgdGjhu7FjIGhp4buHbiBiw6BpIHRvw6FuOiANCg0KS2nhu4NtIMSR4buLbmggJEhfMCQ6cDE9cDINCg0Kxq/hu5tjIGzGsOG7o25nIHPhu7EgY2jDqm5oIGzhu4djaCB24buBIHThu7cgbOG7hyBt4buZdCBuZ8aw4budaSBjw7MgdGjhu51pIGdpYW4gbmfhu6cgdHLDqm4gOGggY8OzIHThu4kgbOG7hyBt4bqldCBuZ+G7pyB24buBIGdp4bqlYyBuZ+G7pyANCg0KYGBge3J9DQp0bXBtMyA8LSB0bXBtW3RtcG0kQWdlID4gNDAsXQ0KdG1wZjMgPC0gdG1wZlt0bXBmJEFnZSA+IDQwLF0NCg0KYSA8LSBjKG5yb3codG1wbSksIG5yb3codG1wZikpDQpiIDwtIGMobnJvdyh0bXBtMyksIG5yb3codG1wZjMpKQ0KDQpwcm9wLnRlc3QoYixhKQ0KYGBgDQoNCktob+G6o25nIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgdHXhu5VpIGzhu5tuIGjGoW4gNDAgdsOgIOKAnCBUcmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6cg4oCdIGPDsyDEkeG7mSB0aW4gY+G6rXkgOTUlIGzDoDokIDAuNDIxOSA8cDwgMC42MDAyJCANCg0KDQoNCiMjIFF1YW4gaOG7hyBnaeG7r2Egbmdo4buBIG5naGnhu4dwIHbDoCBnaeG6pWMgbmfhu6cNCg0KIyMjIMSQ4buTIHRo4buLIHbDoCBi4bqjbmcgdOG6p24gc+G7kSANCg0KYGBge3J9DQpnZ3Bsb3QoZCkgKyBnZW9tX2JhcihhZXMoU2xlZXAsIGZpbGwgPSBPY2N1cGF0aW9uKSxwb3NpdGlvbiA9ICAnaWRlbnRpdHknKQ0KYGBgDQoNCmBgYHtyfQ0KYSA8LSB0YWJsZShkJFNsZWVwLGQkT2NjdXBhdGlvbikNCmFkZG1hcmdpbnMoYSkNCmExIDwtIHByb3AudGFibGUoYSkNCmExDQpgYGANCk5ow6xuIHbDoG8gYuG6o25nIGhhaSBjaGnhu4F1IHbDoCBiaeG7g3UgxJHhu5MgdGEgdGjhuqV5IHkgdMOhIGzDoCBuZ2jhu4EgY8OzIG5oaeG7gXUgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIG5o4bqldCBjw7MgNjQvNzMgbmfGsOG7nWkuIFRyb25nIGtoaSDEkcOzIGvhu4kgc8awIGzDoCBuZ8OgbmggY8OzIMOtdCBuZ8aw4budaSBi4buLIG3huqV0IG5n4bunIGPDsyA2LzYzIG5nxrDhu51pLg0KDQoNCg0KIyMjIEtp4buDbSDEkeG7i25oIGNoaSBiw6xuaCBwaMawxqFuZyANCg0KR2nhuqMgdGh1eeG6v3QgSDA6IFgsWSDEkeG7mWMgbMOicDsgDQoNCsSQ4buRaSB0aHV54bq/dCBIMTogWCxZIGtow7RuZyDEkeG7mWMgbOG6rXANCg0KVGEgdGnhur9uIGjDoG5oIGtp4buDbSDEkeG7i25oIHTDrW5oIMSR4buZYyBs4bqtcCBYIHbDoCBZIGLhurFuZyBSIHRoZW8gY8OhYyBixrDhu5tjIMSRxrDhu6NjIGvhur90IHF14bqjIHNhdToNCg0KDQpgYGB7cn0NCmNoaXNxLnRlc3QoYSkNCmBgYA0KDQpU4burIGLhuqNuZyBr4bq/dCBxdeG6oyB0YSBjw7MgcC12YWx1ZSA9JDIqMTBeey02fSQgPDAsMDU6IELDoWMgYuG7jyBIMA0KDQpL4bq/dCBsdeG6rW4sIHZp4buHYyBt4bqldCBuZ+G7pyB24bubaSBuZ2jhu4EgbmdoaeG7h3AgY+G7p2Egbmjhu69uZyBuZ8aw4budaSB0aOG7sWMgaGnhu4duIGto4bqjbyBzw6F0ICBsw6AgY8OzIHF1YW4gaOG7hyB24bubaSBuaGF1LCB24bubaSBt4bupYyDDvSBuZ2jEqWEgNSUNCg0KIyMjIEtob+G6o25nIMaw4bubYyBsxrDhu6NuZyBjaG8gdOG7iSBs4buHIGPhu6dhIDIgdOG7lW5nIHRo4buDIA0KDQpUaOG7sWMgaGnhu4duIGLDoGkgdG/DoW4ga2nhu4NtIMSR4buLbmggZ2nhuqMgdGh1eeG6v3Qgc+G7sSBi4bqxbmcgbmhhdSB24buBIHThu7cgbOG7hyBuZ2jhu4EgeSB0w6EgY8OzIGLhu4sgIG3huqV0IG5n4bunIGtow7RuZyAsIG5naMSpYSBsw6AgY2jDum5nIHRhIHRo4buxYyBoaeG7h24gYsOgaSB0b8OhbiBraeG7g20gxJHhu4tuaCANCg0KR2nhuqMgc+G7rSA6SDA6cDE9cDINCg0KYGBge3J9DQp0bXBtIDwtIGRbZCRTbGVlcCA9PSAneWVzJyxdDQp0bXBmIDwtIGRbZCRTbGVlcCA9PSAnbm8nLF0NCg0KdG1wbTMgPC0gdG1wbVt0bXBtJE9jY3VwYXRpb24gPT0gJ051cnNlJyxdDQp0bXBmMyA8LSB0bXBmW3RtcGYkT2NjdXBhdGlvbiA9PSAnTnVyc2UnLF0NCg0KYSA8LSBjKG5yb3codG1wbSksIG5yb3codG1wZikpDQpiIDwtIGMobnJvdyh0bXBtMyksIG5yb3codG1wZjMpKQ0KDQpwcm9wLnRlc3QoYixhKQ0KYGBgDQoNClRhIMSRxrDhu6NjIGtob+G6o25nIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBsw6BtIG5naOG7gSB5IHTDoSBjw7Mg4oCcVOG7k24gdOG6oWkgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bun4oCdIHbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUgbMOgOiAwLjQxMjk8IHAgPCAwLjA0MTEgDQoNCg0KDQojIyBRdWFuIGjhu4cgZ2nhu69hIHRo4budaSBnaWFuIG5n4bunIHbDoCBjaOG7qW5nIG3huqV0IG5n4bunIChTbGVlcCAtIFNsZWVwLkR1cmF0aW9uKQ0KDQojIyMgxJDhu5MgdGjhu4sgdsOgIGLhuqNuZyB04bqnbiBz4buRIA0KDQpgYGB7cn0NCmdncGxvdChkYXRhPWQsYWVzKHg9U2xlZXAuRHVyYXRpb24sZmlsbD1TbGVlcCkpICsgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAyKSAgIA0KYGBgDQoNCmBgYHtyfQ0KZiA8LSB0YWJsZShkJFNsZWVwLGQkU2xlZXAuRHVyYXRpb24pDQpmDQpmMSA8LSBwcm9wLnRhYmxlKGYpDQpmMQ0KYGBgDQoNClF1YSBiaeG7g3UgxJHhu5MgdsOgIGLhuqNuZyB0YSB0aeG6v24gaMOgbmggbmjhuq1uIHjDqXQgdMOsbmggdHLhuqFuZyBnaeG6pWMgbmfhu6cgdsOgIHRo4budaSBnaWFuIG5n4bunIGPhu6dhIG5o4buvbmcgbmfGsOG7nWkgdGhhbSBnaWEga2jhuqNvIHPDoXQgY2hvIHRo4bqleSBuZ8aw4budaSBuZ+G7pyBuaGnhu4F1IHPhu4Uga2jDtG5nIGPDsyBjw6FjIHRyaeG7h3UgY2jhu6luZyB0csOqbiwNCg0KIyMjIFThu7cgbOG7hyBjaMOqbmggKE9kZCBSYXRpbykNCg0KYGBge3J9DQpsb2dpc3RpYy5kaXNwbGF5KGdsbShmYWN0b3IoU2xlZXApflNsZWVwLkR1cmF0aW9uLGZhbWlseT1iaW5vbWlhbCwgZGF0YSA9ZCkpDQpgYGANClThu4kgbOG7hyBjaMOqbmggbOG7h2NoIGdp4buvYSB0aOG7nWkgZ2lhbiBuZ+G7pyB2w6AgY8OhYyB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6cgbMOgIDAsMzkgZ2lhbyDEkeG7mW5nIHRyb25nIGtob+G6o25nICgwLjI5LDAuNTMpIA0KDQojIyMgS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIGNobyB04buJIGzhu4cgY+G7p2EgMiB04buVbmcgdGjhu4MgDQoNClRo4buxYyBoaeG7h24gYsOgaSB0b8OhbiBraeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dCBz4buxIGLhurFuZyBuaGF1IHbhu4EgdOG7tyBs4buHIOG7nyBjw6FjIGJp4bq/biB24bubaSAyIHThu5VuZyB0aOG7gyBj4bunYSBiaeG6v24gU2xlZXAsIG5naMSpYSBsw6AgY2jDum5nIHRhIHRo4buxYyBoaeG7h24gYsOgaSB0b8OhbjogDQoNCktp4buDbSDEkeG7i25oICRIXzAkOnAxPXAyDQoNCsav4bubYyBsxrDhu6NuZyBz4buxIGNow6puaCBs4buHY2ggduG7gSB04bu3IGzhu4cgbeG7mXQgbmfGsOG7nWkgY8OzIHRo4budaSBnaWFuIG5n4bunIHRyw6puIDhoIGPDsyB04buJIGzhu4cgbeG6pXQgbmfhu6cgduG7gSBnaeG6pWMgbmfhu6cgDQoNCmBgYHtyfQ0KdG1wbTMgPC0gdG1wbVt0bXBtJFNsZWVwLkR1cmF0aW9uID4gOCxdDQp0bXBmMyA8LSB0bXBmW3RtcGYkU2xlZXAuRHVyYXRpb24gPiA4LF0NCg0KYSA8LSBjKG5yb3codG1wbSksIG5yb3codG1wZikpDQpiIDwtIGMobnJvdyh0bXBtMyksIG5yb3codG1wZjMpKQ0KDQpwcm9wLnRlc3QoYixhKQ0KYGBgDQoNCktob+G6o25nIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgdHRo4budaSBnaWFuIG5n4bunIHRyw6puIDhoIHbDoCDigJwgVHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIOKAnSBjw7MgxJHhu5kgdGluIGPhuq15IDk1JSBsw6A6JCAtMC4wOTEwMSA8cCA8ICAwLjA2ODE1JCANCg0KIyMjIEtp4buDbSDEkeG7i25oIHTDrW5oIMSR4buZYyBs4bqtcCAtIGtp4buDbSDEkeG7i25oIGNoaSBiw6xuaCBwaMawxqFuZw0KDQpHaeG6oyB0aHV54bq/dCBIMDogWCxZIMSR4buZYyBsw6JwOyANCg0KxJDhu5FpIHRodXnhur90IEgxOiBYLFkga2jDtG5nIMSR4buZYyBs4bqtcA0KDQpUYSB0aeG6v24gaMOgbmgga2nhu4NtIMSR4buLbmggdMOtbmggxJHhu5ljIGzhuq1wIGPhu6dhIGJp4bq/biBTbGVlcChYKSB2w6AgYmnhur9uIFNsZWVwLkR1cmF0aW9uKFkpIHNhdSBi4bqxbmcgUiB0aGVvIGPDoWMgYsaw4bubYyDEkcaw4bujYyBr4bq/dCBxdeG6ozoNCg0KYGBge3J9DQpjaGlzcS50ZXN0KGYpDQpgYGANCg0KVOG7qyBi4bqjbmcga+G6v3QgcXXhuqMgdGEgY8OzIHAtdmFsdWUgPSAkMioxMF57LTE2fSQ8MCwwNTogQsOhYyBi4buPIEgwDQoNCkvhur90IGx14bqtbiwgxJFp4buDbSDEkcOhbmggZ2nDoSBnaeG6pWMgbmfhu6cgduG7m2kgdGjhu51pIGdpYW4gbmfhu6cgY+G7p2Egbmjhu69uZyBuZ8aw4budaSB0aOG7sWMgaGnhu4duIGto4bqjbyBzw6F0IGPDsyBsacOqbiBo4buHIHbhu5tpIG5oYXUsIHbhu5tpIG3hu6ljIMO9IG5naMSpYSA1JQ0KDQojIyBRdWFuIGjhu4cgduG7m2kgdGjhu51pIGdpYW4gaG/huqF0IMSR4buZbmcNCg0KIyMjIMSQ4buTIHRo4buLIHbDoCBi4bqjbmcgdOG6p24gc+G7kSANCg0KDQpgYGB7cn0NCnBvIDwtIHRhYmxlKGQkU2xlZXAsZCRQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCkNCnBvDQpnZ3Bsb3QoZCwgYWVzKHg9UGh5c2ljYWwuQWN0aXZpdHkuTGV2ZWwsIGZpbGw9U2xlZXApKSArIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArICBzY2FsZV9jb2xvcl9jYW52YSgpICsgZ2d0aGVtZXM6OnNjYWxlX2ZpbGxfY2FudmEoKQ0KYGBgDQoNCk5nxrDhu51pIGNvIGPDoWMgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIHRoxrDhu51uZyBjw7Mgc+G7kSBwaMO6dCBob+G6oXQgxJHhu5luZyBsw6AgNDUnIHbDoCA5MCcNCg0KIyMjIFThu7cgbOG7hyBjaMOqbmggKE9kZCBSYXRpbykNCg0KYGBge3J9DQpsb2dpc3RpYy5kaXNwbGF5KGdsbShmYWN0b3IoU2xlZXApflBoeXNpY2FsLkFjdGl2aXR5LkxldmVsLGZhbWlseT1iaW5vbWlhbCwgZGF0YSA9ZCkpDQpgYGANClThu4kgbOG7hyBjaMOqbmggbOG7h2NoIGdp4buvYSB0aOG7nWkgZ2lhbiBob+G6oXQgxJHhu5luZyB2w6AgY8OhYyB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6cgbMOgIDEuMDA2OCBnaWFvIMSR4buZbmcgdHJvbmcga2hv4bqjbmcgKDAuOTk2OSwxLjAxNjkpDQoNCg0KIyMjIEtob+G6o25nIMaw4bubYyBsxrDhu6NuZyBjaG8gdOG7iSBs4buHIGPhu6dhIDIgdOG7lW5nIHRo4buDIA0KDQpUaOG7sWMgaGnhu4duIGLDoGkgdG/DoW4ga2nhu4NtIMSR4buLbmggZ2nhuqMgdGh1eeG6v3Qgc+G7sSBi4bqxbmcgbmhhdSB24buBIHThu7cgbOG7hyDhu58gY8OhYyBiaeG6v24gduG7m2kgMiB04buVbmcgdGjhu4MgY+G7p2EgYmnhur9uIFNsZWVwLCBuZ2jEqWEgbMOgIGNow7puZyB0YSB0aOG7sWMgaGnhu4duIGLDoGkgdG/DoW46IA0KDQpLaeG7g20gxJHhu4tuaCAkSF8wJDpwMT1wMg0KDQrGr+G7m2MgbMaw4bujbmcgc+G7sSBjaMOqbmggbOG7h2NoIHbhu4EgdOG7tyBs4buHIG3hu5l0IG5nxrDhu51pIGPDsyB0aOG7nWkgZ2lhbiBuZ+G7pyB0csOqbiA4aCBjw7MgdOG7iSBs4buHIG3huqV0IG5n4bunIHbhu4EgZ2nhuqVjIG5n4bunIA0KDQpgYGB7cn0NCnRtcG0zIDwtIHRtcG1bdG1wbSRQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCA+IDYwLF0NCnRtcGYzIDwtIHRtcGZbdG1wZiRQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCA+IDYwLF0NCg0KYSA8LSBjKG5yb3codG1wbSksIG5yb3codG1wZikpDQpiIDwtIGMobnJvdyh0bXBtMyksIG5yb3codG1wZjMpKQ0KDQpwcm9wLnRlc3QoYixhKQ0KYGBgDQoNCktob+G6o25nIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgdGjhu51pIGdpYW4gaG/huqF0IMSR4buZbmcgdHLDqm4gNjAnIHbDoCDigJwgVHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIOKAnSBjw7MgxJHhu5kgdGluIGPhuq15IDk1JSBsw6A6JDAuMDAxNTI1PFA8IDAuMjEyOTk5JCANCg0KIyMjIEtp4buDbSDEkeG7i25oIHTDrW5oIMSR4buZYyBs4bqtcCAtIGtp4buDbSDEkeG7i25oIGNoaSBiw6xuaCBwaMawxqFuZw0KDQpHaeG6oyB0aHV54bq/dCBIMDogWCxZIMSR4buZYyBsw6JwOyANCg0KxJDhu5FpIHRodXnhur90IEgxOiBYLFkga2jDtG5nIMSR4buZYyBs4bqtcA0KDQpUYSB0aeG6v24gaMOgbmgga2nhu4NtIMSR4buLbmggdMOtbmggxJHhu5ljIGzhuq1wIGPhu6dhIGJp4bq/biBTbGVlcChYKSB2w6AgYmnhur9uIFNsZWVwLkR1cmF0aW9uKFkpIHNhdSBi4bqxbmcgUiB0aGVvIGPDoWMgYsaw4bubYyDEkcaw4bujYyBr4bq/dCBxdeG6ozoNCg0KYGBge3J9DQpjaGlzcS50ZXN0KHBvKQ0KYGBgDQoNClThu6sgYuG6o25nIGvhur90IHF14bqjIHRhIGPDsyBwLXZhbHVlID0gJDIqMTBeey0xNn0kPDAsMDU6IELDoWMgYuG7jyBIMA0KDQpL4bq/dCBsdeG6rW4sIMSRaeG7g20gxJHDoW5oIGdpw6EgZ2nhuqVjIG5n4bunIHbhu5tpIHRo4budaSBnaWFuIG5n4bunIGPhu6dhIG5o4buvbmcgbmfGsOG7nWkgdGjhu7FjIGhp4buHbiBraOG6o28gc8OhdCBjw7MgbGnDqm4gaOG7hyB24bubaSBuaGF1LCB24bubaSBt4bupYyDDvSBuZ2jEqWEgNSUNCg0KIyMgUXVhbiBo4buHIHRyaeG7h3UgY2jhu6luZyBt4bqldCBuZ+G7pyB24bubaSBt4bupYyDEkeG7mSBjxINuIHRo4bqzbmcgKFNsZWVwIC0gU3RyZXNzLkxldmVsKQ0KDQojIyMgxJDhu5MgdGjhu4sgdsOgIGLhuqNuZyB04bqnbiBz4buRIA0KDQpgYGB7cn0NCmdncGxvdChkLCBhZXMoU2xlZXAsIFN0cmVzcy5MZXZlbCwgY29sb3VyID0gU2xlZXApKSArIGdlb21fYm94cGxvdChzaG93LmxlZ2VuZCA9IEYpDQpgYGANCg0KYGBge3J9DQplbiA8LSB0YWJsZShkJFNsZWVwLGQkU3RyZXNzLkxldmVsKQ0KZW4NCmVuMSA8LSBwcm9wLnRhYmxlKGVuKQ0KZW4xDQpgYGANCg0KS2hpIHRp4bq/biBow6BuaCBuaOG6rW4geMOpdCDEkWnhu4NtIMSRw6FuaCBnacOhIGdp4bqlYyBuZ+G7pyB2w6AgbeG7qWMgxJHhu5kgY8SDbmcgdGjhurNuZyBj4bunYSBuaOG7r25nIG5nxrDhu51pIHRoYW0gZ2lhIGto4bqjbyBzw6F0LiBDaG8gdGjhuqV5LCB0b8OgbiBi4buZIG5nxrDhu51pIGPDsyBt4bupYyDEkeG7mSBjxINuZyB0aOG6s25nIHRo4bqlcCDEkeG7gXUgY8OzIMSRacOqbSDEkcOhbmggZ2nDoSBjYW8uQ8OybiBs4bqhaSBsw6AgcGjhuqduIGzhu5tuIG5nxrDhu51pIGLhu4sgY8SDbmcgdGjhurNuZyBuaGnhu4F1IGzhuqFpIGPDsyDEkWnhu4NtIHbhu4EgZ2nhuqVjIG5n4bunIHRo4bqlcC4NCg0KIyMjIFThu7cgbOG7hyBjaMOqbmggKE9kZCBSYXRpbykNCg0KYGBge3J9DQpsb2dpc3RpYy5kaXNwbGF5KGdsbShmYWN0b3IoU2xlZXApflN0cmVzcy5MZXZlbCxmYW1pbHk9Ymlub21pYWwsIGRhdGEgPWQpKQ0KYGBgDQpU4buJIGzhu4cgY2jDqm5oIGzhu4djaCBnaeG7r2EgbeG7qWMgxJHhu5kgY8SDbmcgdGjhurNuZyB2w6AgY8OhYyB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6cgbMOgIDEuMjQgZ2lhbyDEkeG7mW5nIHRyb25nIGtob+G6o25nICgxLjEsMS4zOSkgDQoNCg0KIyMjIEtob+G6o25nIMaw4bubYyBsxrDhu6NuZyBjaG8gdOG7iSBs4buHIGPhu6dhIDIgdOG7lW5nIHRo4buDIA0KDQpUaOG7sWMgaGnhu4duIGLDoGkgdG/DoW4ga2nhu4NtIMSR4buLbmggZ2nhuqMgdGh1eeG6v3Qgc+G7sSBi4bqxbmcgbmhhdSB24buBIHThu7cgbOG7hyDhu58gY8OhYyBiaeG6v24gduG7m2kgMiB04buVbmcgdGjhu4MgY+G7p2EgYmnhur9uIFNsZWVwLCBuZ2jEqWEgbMOgIGNow7puZyB0YSB0aOG7sWMgaGnhu4duIGLDoGkgdG/DoW46IA0KDQpLaeG7g20gxJHhu4tuaCAkSF8wJDpwMT1wMg0KDQrGr+G7m2MgbMaw4bujbmcgc+G7sSBjaMOqbmggbOG7h2NoIHbhu4EgdOG7tyBs4buHIG3hu5l0IG5nxrDhu51pIGPDsyBt4bupYyBjxINuIHRo4bqzbmcgZMaw4bubaSA3ICDEkWnDqm0gY8OzIMSRaeG7g20gxJHDoW5oIGdpw6EgduG7gSBnaeG6pWMgbmfhu6cgZ2nhu69hIHRo4bqlcCB2w6AgY2FvDQoNCmBgYHtyfQ0KdG1wbTMgPC0gdG1wbVt0bXBtJFN0cmVzcy5MZXZlbCA8IDcsXQ0KdG1wZjMgPC0gdG1wZlt0bXBmJFN0cmVzcy5MZXZlbCA8IDcsXQ0KDQphIDwtIGMobnJvdyh0bXBtKSwgbnJvdyh0bXBmKSkNCmIgPC0gYyhucm93KHRtcG0zKSwgbnJvdyh0bXBmMykpDQoNCnByb3AudGVzdChiLGEpDQpgYGANCg0KS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIHThu7cgbOG7hyBuaOG7r25nIG5nxrDhu51pIGPDsyBt4bupYyBjxINuIHRo4bqzbmcgZMaw4bubaSA3ICDEkWnhu4NtIHbDoCDigJwgxJBp4buDbSDEkcOhbmggZ2nDoSBnaeG6pWMgbmfhu6cgdGjhuqVw4oCdIGPDsyDEkeG7mSB0aW4gY+G6rXkgOTUlIGzDoDogJC0wLjQ3NTY8cDwgLTAuMjc5NSQNCg0KIyMjIEtp4buDbSDEkeG7i25oIHTDrW5oIMSR4buZYyBs4bqtcCAtIGtp4buDbSDEkeG7i25oIGNoaSBiw6xuaCBwaMawxqFuZw0KDQpHaeG6oyB0aHV54bq/dCBIMDogWCxZIMSR4buZYyBsw6JwOyANCg0KxJDhu5FpIHRodXnhur90IEgxOiBYLFkga2jDtG5nIMSR4buZYyBs4bqtcA0KDQpUYSB0aeG6v24gaMOgbmgga2nhu4NtIMSR4buLbmggdMOtbmggxJHhu5ljIGzhuq1wIGPhu6dhIGJp4bq/biBTbGVlcChYKSB2w6AgYmnhur9uIFN0cmVzcy5MZXZlbChZKSBzYXUgYuG6sW5nIFIgdGhlbyBjw6FjIGLGsOG7m2MgxJHGsOG7o2Mga+G6v3QgcXXhuqM6DQoNCg0KYGBge3J9DQpjaGlzcS50ZXN0KGVuKQ0KYGBgDQoNClThu6sgYuG6o25nIGvhur90IHF14bqjIHRhIGPDsyBwLXZhbHVlID0kMioxMF57LTE2fSQ8MCwwNTogQsOhYyBi4buPIEgwDQoNCkvhur90IGx14bqtbiwgxJFp4buDbSDEkcOhbmggZ2nDoSBnaeG6pWMgbmfhu6cgduG7m2kgbeG7qWMgxJHDtCBjxINuZyB0aOG6s25nIGPhu6dhIG5o4buvbmcgbmfGsOG7nWkgdGjhu7FjIGhp4buHbiBraOG6o28gc8OhdCBjw7MgbGnDqm4gaOG7hyB24bubaSBuaGF1LCB24bubaSBt4bupYyDDvSBuZ2jEqWEgNSUNCg0KIyMgUXVhbiBo4buHIHbhu5tpIGNo4buJIHPhu5EgQk1JDQoNCiMjIyDEkOG7kyB0aOG7iyB2w6AgYuG6o25nIHThuqduIHPhu5EgDQoNCg0KYGBge3J9DQpnZ3Bsb3QoZCkgKyBnZW9tX2JhcihhZXMoU2xlZXAsIGZpbGwgPSBCTUkuQ2F0ZWdvcnkpLHBvc2l0aW9uID0gICdkb2RnZScpDQoNCmMgPC0gdGFibGUoZCRTbGVlcCxkJEJNSS5DYXRlZ29yeSkNCmMNCmMxIDwtIHByb3AudGFibGUoYykNCmMxDQphZGRtYXJnaW5zKGMxKQ0KYGBgDQoNClF1YSB2aeG7h2MgcXVhbiBzw6F0IGJp4buDdSDEkeG7kyBi4bqjbmcgaGFpIGNoaeG7gXUgduG7gSB0aOG7gyB0cuG7jW5nIHTDrW5oIGLhurFuZyBCTUkgY+G7p2EgbmfGsOG7nWkgdGhhbSBnaWEga2jhuqNvIHPDoXQgduG7m2kgY2jhu6ljIG3huqV0IG5n4bunLiBUYSB0aOG6pXksIG5nxrDhu51pIG5nxrDhu51pIHRo4burYSBjw6JuIGPDsyBjw6FjIHRyaeG7h3QgY2jhu6luZyBt4bqldCBuZ+G7pyBjw7MgMTM5IG5nxrDhu51pIGNoaeG6v20gIDM3LDE2JSBn4bqlcCA4LDcgbMOibiBuZ8aw4budaSBjw7MgY8OibiBu4bq3bmcgYsOsbmggdGjGsOG7nW5nIGPDsyBjw6FjIHRyaeG7h3QgY2jhu6luZyBt4bqldCBuZ+G7py4NCg0KIyMjIEtob+G6o25nIMaw4bubYyBsxrDhu6NuZyBjaG8gdOG7iSBs4buHIGPhu6dhIDIgdOG7lW5nIHRo4buDIA0KDQpUaOG7sWMgaGnhu4duIGLDoGkgdG/DoW4ga2nhu4NtIMSR4buLbmggZ2nhuqMgdGh1eeG6v3Qgc+G7sSBi4bqxbmcgbmhhdSB24buBIHThu7cgbOG7hyDhu58gY8OhYyBiaeG6v24gduG7m2kgMiB04buVbmcgdGjhu4MgY+G7p2EgYmnhur9uIFNsZWVwLCBuZ2jEqWEgbMOgIGNow7puZyB0YSB0aOG7sWMgaGnhu4duIGLDoGkgdG/DoW46IA0KDQpLaeG7g20gxJHhu4tuaCAkSF8wJDpwMT1wMg0KDQrGr+G7m2MgbMaw4bujbmcgc+G7sSBjaMOqbmggbOG7h2NoIHbhu4EgdOG7tyBs4buHIEJNSSB24bubaSB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6cuDQoNCmBgYHtyfQ0KdG1wbTMgPC0gdG1wbVt0bXBtJEJNSS5DYXRlZ29yeSA9PSAnTm9ybWFsJyxdDQp0bXBmMyA8LSB0bXBmW3RtcGYkQk1JLkNhdGVnb3J5ID09ICdOb3JtYWwnLF0NCg0KYSA8LSBjKG5yb3codG1wbSksIG5yb3codG1wZikpDQpiIDwtIGMobnJvdyh0bXBtMyksIG5yb3codG1wZjMpKQ0KDQpwcm9wLnRlc3QoYixhKQ0KYGBgDQoNCktob+G6o25nIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjaOG7iSBz4buRIEJNSSBsw6AgJ05vcm1hbCcgY8OzIOKAnFThu5NuIHThuqFpIHRyaeG7h3UgY2jhu6luZyBt4bqldCBuZ+G7p+KAnSB24bubaSDEkeG7mSB0aW4gY+G6rXkgOTUlIGzDoDokLTAuODI4NDxwPCAtMC42ODgwJA0KDQojIyMgS2nhu4NtIMSR4buLbmggdMOtbmggxJHhu5ljIGzhuq1wIC0ga2nhu4NtIMSR4buLbmggY2hpIGLDrG5oIHBoxrDGoW5nDQoNCkdp4bqjIHRodXnhur90IEgwOiBYLFkgxJHhu5ljIGzDonA7IA0KDQrEkOG7kWkgdGh1eeG6v3QgSDE6IFgsWSBraMO0bmcgxJHhu5ljIGzhuq1wDQoNClRhIHRp4bq/biBow6BuaCBraeG7g20gxJHhu4tuaCB0w61uaCDEkeG7mWMgbOG6rXAgY+G7p2EgYmnhur9uIFNsZWVwKFgpIHbDoCBiaeG6v24gQk1JLkNhdGVnb3J5IChZKSBzYXUgYuG6sW5nIFIgdGhlbyBjw6FjIGLGsOG7m2MgxJHGsOG7o2Mga+G6v3QgcXXhuqM6DQoNCmBgYHtyfQ0KDQpjaGlzcS50ZXN0KGMpDQoNCmBgYA0KDQpU4burIGLhuqNuZyBr4bq/dCBxdeG6oyB0YSBjw7MgcC12YWx1ZSA9JDIqMTBeey0xNn0kIDwwLDA1OiBCw6FjIGLhu48gJEhfMCQNCkvhur90IGx14bqtbiwgdmnhu4djIG3huqV0IG5n4bunIHbhu5tpIEJNSSBiw6xuaCB0aMaw4budbmcgY+G7p2Egbmjhu69uZyBuZ8aw4budaSB0aOG7sWMgaGnhu4duIGto4bqjbyBzw6F0IGPDsyBsacOqbiBo4buHIHbhu5tpIG5oYXUsIHbhu5tpIG3hu6ljIMO9IG5naMSpYSA1JQ0KDQojIyBRdWFuIGjhu4cgduG7m2kgaHV54bq/dCDDoXAgDQoNCiMjIyDEkOG7kyB0aOG7iyB2w6AgYuG6o25nIHThuqduIHPhu5EgDQoNCg0KYGBge3J9DQpibCA8LSB0YWJsZShkJFNsZWVwLGQkQmxvb2QuUHJlc3N1cmUpDQpibA0KZ2dwbG90KGQsIGFlcyhCbG9vZC5QcmVzc3VyZSwgZmlsbCA9IFNsZWVwKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICdkb2RnZScpDQpgYGANCg0KDQpOZ8aw4budaSBjw7MgaHV54bq/dCDDoXAgY2FvIHRow6wgeMOhYyBzdeG6pXQgbmjhu69uZyBuZ8aw4budaSBjw7MgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIGPDoG5nIGzhu5tuDQoNCiMjIyBLaG/huqNuZyDGsOG7m2MgbMaw4bujbmcgY2hvIHThu4kgbOG7hyBj4bunYSAyIHThu5VuZyB0aOG7gyANCg0KVGjhu7FjIGhp4buHbiBiw6BpIHRvw6FuIGtp4buDbSDEkeG7i25oIGdp4bqjIHRodXnhur90IHPhu7EgYuG6sW5nIG5oYXUgduG7gSB04bu3IGzhu4cg4bufIGPDoWMgYmnhur9uIHbhu5tpIDIgdOG7lW5nIHRo4buDIGPhu6dhIGJp4bq/biBTbGVlcCwgbmdoxKlhIGzDoCBjaMO6bmcgdGEgdGjhu7FjIGhp4buHbiBiw6BpIHRvw6FuOiANCg0KS2nhu4NtIMSR4buLbmggJEhfMCQ6cDE9cDINCg0Kxq/hu5tjIGzGsOG7o25nIHPhu7EgY2jDqm5oIGzhu4djaCB24buBIHThu7cgbOG7hyBCTUkgduG7m2kgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunLg0KDQpgYGB7cn0NCnRtcG0zIDwtIHRtcG1bdG1wbSRCbG9vZC5QcmVzc3VyZSA9PSAnMTIwLzgwJyxdDQp0bXBmMyA8LSB0bXBmW3RtcGYkQmxvb2QuUHJlc3N1cmUgPT0gJzEyMC84MCcsXQ0KDQphIDwtIGMobnJvdyh0bXBtKSwgbnJvdyh0bXBmKSkNCmIgPC0gYyhucm93KHRtcG0zKSwgbnJvdyh0bXBmMykpDQoNCnByb3AudGVzdChiLGEpDQpgYGANCg0KS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIHThu7cgbOG7hyBuaOG7r25nIG5nxrDhu51pIGNo4buJIHPhu5EgaHV5w6l0IMOhcCAnMTIwLzgwJyBjw7Mg4oCcVOG7k24gdOG6oWkgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bun4oCdIHbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUgbMOgOiQtMC4yNDQ1PHA8IC0wLjEyMjQkDQoNCiMjIyBLaeG7g20gxJHhu4tuaCB0w61uaCDEkeG7mWMgbOG6rXAgLSBraeG7g20gxJHhu4tuaCBjaGkgYsOsbmggcGjGsMahbmcNCg0KR2nhuqMgdGh1eeG6v3QgSDA6IFgsWSDEkeG7mWMgbMOicDsgDQoNCsSQ4buRaSB0aHV54bq/dCBIMTogWCxZIGtow7RuZyDEkeG7mWMgbOG6rXANCg0KVGEgdGnhur9uIGjDoG5oIGtp4buDbSDEkeG7i25oIHTDrW5oIMSR4buZYyBs4bqtcCBj4bunYSBiaeG6v24gU2xlZXAoWCkgdsOgIGJp4bq/biBCbG9vZC5QcmVzc3VyZSAoWSkgc2F1IGLhurFuZyBSIHRoZW8gY8OhYyBixrDhu5tjIMSRxrDhu6NjIGvhur90IHF14bqjOg0KDQpgYGB7cn0NCmNoaXNxLnRlc3QoYmwpDQpgYGANCg0KVOG7qyBi4bqjbmcga+G6v3QgcXXhuqMgdGEgY8OzIHAtdmFsdWUgPSQyKjEwXnstMTZ9JCA8MCwwNTogQsOhYyBi4buPICRIXzAkDQpL4bq/dCBsdeG6rW4sIHZp4buHYyBt4bqldCBuZ+G7pyB24bubaSBodXnhur90IMOicCBj4bunYSBuaOG7r25nIG5nxrDhu51pIHRo4buxYyBoaeG7h24ga2jhuqNvIHPDoXQgY8OzIGxpw6puIGjhu4cgduG7m2kgbmhhdSwgduG7m2kgbeG7qWMgw70gbmdoxKlhIDUlDQoNCg0KIyMgUXVhbiBo4buHIG5o4buLcCB0aW0gdsOgIHZp4buHYyBt4bqldCBuZ+G7pyAgKFNsZWVwLSBIZWFydCBSYXRlICkNCg0KIyMjIMSQ4buTIHRo4buLIHbDoCBi4bqjbmcgdOG6p24gc+G7kSANCg0KYGBge3J9DQpiIDwtIHRhYmxlKGQkU2xlZXAsZCRIZWFydC5SYXRlKQ0KYg0KYjEgPC0gcHJvcC50YWJsZShiKQ0KYjENCmdncGxvdChkYXRhID0gZCkgKyBnZW9tX2hpc3RvZ3JhbShhZXMoeD1IZWFydC5SYXRlLGZpbGw9ZmFjdG9yKFNsZWVwKSksYmlucz0xMCwgcG9zaXRpb24gPSAnc3RhY2snLGFscGhhID0gMC41KQ0KYGBgDQpWw6AgbmjDrG4gdsOgbyBiaeG7g3UgxJHhu5MgaGlzdG9ncmFtIHbDoCBi4bqjbmcgdGEgY8OzIHRo4buDIHRo4bqleSBi4bqvdCDEkeG6p3UgdOG7qyA3OCBuaOG7i3AvcGjDunQgdHLhu58gxJFpIG5nxrDhu51pIMSR4buBdSBsw6Agbmjhu69uZyBuZ8aw4budaSBjw7MgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunLiBL4bq/dCBsdeG6rW4sIG5o4buLcCB0aW0gY8OzIOG6o25oIGjGsOG7n25nIMSR4bq/biBnaeG6pWMgbmfhu6cuDQoNCsaw4budaSBjaGnhur9tIDY0LDQ0JSB2w6AgbmdoxrDhu51pIGPDsyBuaOG7i3AgdGltIMSR4bqtcCBuaGFuaCAoa8OtIGhp4buHdSBsw6AgYG5oaeG7gXVgKSBsw6AgMTMzIG5nxrDhu51pIGPDsyAzNSw1NiUuDQoNCiMjIyBU4bu3IGzhu4cgY2jDqm5oIChPZGQgUmF0aW8pDQoNCmBgYHtyfQ0KbG9naXN0aWMuZGlzcGxheShnbG0oZmFjdG9yKFNsZWVwKX5IZWFydC5SYXRlLGZhbWlseT1iaW5vbWlhbCwgZGF0YSA9ZCkpDQpgYGANClThu4kgbOG7hyBjaMOqbmggbOG7h2NoIGdp4buvYSBuaOG7i3AgdGltIHbDoCBjw6FjIHRyaeG7h3UgY2jhu6luZyBt4bqldCBuZ+G7pyBsw6AgMSwyIGdpYW8gxJHhu5luZyB0cm9uZyBraG/huqNuZyAoMS4xMywxLjI4KSAgDQoNCiMjIyBLaG/huqNuZyDGsOG7m2MgbMaw4bujbmcgY2hvIHThu4kgbOG7hyBj4bunYSAyIHThu5VuZyB0aOG7gyANCg0KVGjhu7FjIGhp4buHbiBiw6BpIHRvw6FuIGtp4buDbSDEkeG7i25oIGdp4bqjIHRodXnhur90IHPhu7EgYuG6sW5nIG5oYXUgduG7gSB04bu3IGzhu4cg4bufIGPDoWMgYmnhur9uIHbhu5tpIDIgdOG7lW5nIHRo4buDIGPhu6dhIGJp4bq/biBTbGVlcCwgbmdoxKlhIGzDoCBjaMO6bmcgdGEgdGjhu7FjIGhp4buHbiBiw6BpIHRvw6FuOiANCg0KS2nhu4NtIMSR4buLbmggJEhfMCQ6cDE9cDINCg0Kxq/hu5tjIGzGsOG7o25nIHPhu7EgY2jDqm5oIGzhu4djaCB24buBIHThu7cgbOG7hyBuaOG7i3AgdGltIMSR4bqtcCBoxqFuIDY5IG5o4buLcC9waMO6dCB24bubaSB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6cuDQoNCmBgYHtyfQ0KdG1wbTMgPC0gdG1wbVt0bXBtJEhlYXJ0LlJhdGUgPiA2OSxdDQp0bXBmMyA8LSB0bXBmW3RtcGYkSGVhcnQuUmF0ZSA+IDY5LF0NCg0KYSA8LSBjKG5yb3codG1wbSksIG5yb3codG1wZikpDQpiIDwtIGMobnJvdyh0bXBtMyksIG5yb3codG1wZjMpKQ0KDQpwcm9wLnRlc3QoYixhKQ0KYGBgDQoNCktob+G6o25nIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBuaOG7i3AgdGltIGPDsyDigJxU4buTbiB04bqhaSB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6figJ0gduG7m2kgxJHhu5kgdGluIGPhuq15IDk1JSBsw6A6MC4wMDc5NTMgPCBwPCAwLjIyMDgyOA0KDQojIyMgS2nhu4NtIMSR4buLbmggdMOtbmggxJHhu5ljIGzhuq1wIC0ga2nhu4NtIMSR4buLbmggY2hpIGLDrG5oIHBoxrDGoW5nDQoNCkdp4bqjIHRodXnhur90IEgwOiBYLFkgxJHhu5ljIGzDonA7IA0KDQrEkOG7kWkgdGh1eeG6v3QgSDE6IFgsWSBraMO0bmcgxJHhu5ljIGzhuq1wDQoNClRhIHRp4bq/biBow6BuaCBraeG7g20gxJHhu4tuaCB0w61uaCDEkeG7mWMgbOG6rXAgY+G7p2EgYmnhur9uIFNsZWVwKFgpIHbDoCBiaeG6v24gSGVhcnQuUmF0ZSAoWSkgc2F1IGLhurFuZyBSIHRoZW8gY8OhYyBixrDhu5tjIMSRxrDhu6NjIGvhur90IHF14bqjOg0KDQpgYGB7cn0NCmNoaXNxLnRlc3QoYikNCmBgYA0KDQpU4burIGLhuqNuZyBr4bq/dCBxdeG6oyB0YSBjw7MgcC12YWx1ZSA9JDcqMTBeey0xNX0kIDwwLDA1OiBCw6FjIGLhu48gJEhfMCQNCkvhur90IGx14bqtbiwgdmnhu4djIG3huqV0IG5n4bunIHbhu5tpIG5o4buLcCB0aW0ga2hpIG5n4bunIGPhu6dhIG5o4buvbmcgbmfGsOG7nWkgdGjhu7FjIGhp4buHbiBraOG6o28gc8OhdCBjw7MgbGnDqm4gaOG7hyB24bubaSBuaGF1LCB24bubaSBt4bupYyDDvSBuZ2jEqWEgNSUNCg0KIyMgUXVhbiBo4buHIHbhu5tpIHPhu5EgYsaw4bubYyDEkWkgaOG6sW5nIG5nw6B5DQoNCiMjIyDEkOG7kyB0aOG7iyB2w6AgYuG6o25nIHThuqduIHPhu5EgDQoNCmBgYHtyfQ0KbG8gPC0gdGFibGUoZCRTbGVlcCxkJERhaWx5LlN0ZXBzKQ0KbG8NCmdncGxvdChkLCBhZXMoeD1EYWlseS5TdGVwcywgZmlsbD1TbGVlcCkpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsgIHNjYWxlX2NvbG9yX2V4Y2VsX25ldygpICsgZ2d0aGVtZXM6OnNjYWxlX2ZpbGxfZXhjZWxfbmV3KCkNCmBgYA0KDQpUaGVvIHRo4buRbmcga8OqIHbDoCBiaeG7g3UgxJHhu5MgaMOgbSBt4bqtdCDEkeG7mSBjaG8gdGjhuqV5IHTDonQgY8OhYyBuaOG7r25nIG5nxrDhu51pIGhv4bqhdCDEkeG7mW5nIMSRaSBs4bqhaSDDrXQgaMahbiA0MjAwIGLGsOG7m2MgxJHhu4F1IGPDsyBjw6FjIHRyaeG7h3UgY2jhu6luZyBt4bqldCBuZ+G7pw0KDQojIyMgVOG7tyBs4buHIGNow6puaCAoT2RkIFJhdGlvKQ0KDQpgYGB7cn0NCmxvZ2lzdGljLmRpc3BsYXkoZ2xtKGZhY3RvcihTbGVlcCl+RGFpbHkuU3RlcHMsZmFtaWx5PWJpbm9taWFsLCBkYXRhID1kKSkNCmBgYA0KVOG7iSBs4buHIGNow6puaCBs4buHY2ggZ2nhu69hIHPhu5EgYsaw4bubYyDEkWkgdHJvbmcgbmfDoHkgdsOgIGPDoWMgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIGzDoCAxIGdpYW8gxJHhu5luZyB0cm9uZyBraG/huqNuZyAoMC45OTk4LDEuMDAwMSkgDQoNCiMjIyBLaG/huqNuZyDGsOG7m2MgbMaw4bujbmcgY2hvIHThu4kgbOG7hyBj4bunYSAyIHThu5VuZyB0aOG7gyANCg0KVGjhu7FjIGhp4buHbiBiw6BpIHRvw6FuIGtp4buDbSDEkeG7i25oIGdp4bqjIHRodXnhur90IHPhu7EgYuG6sW5nIG5oYXUgduG7gSB04bu3IGzhu4cg4bufIGPDoWMgYmnhur9uIHbhu5tpIDIgdOG7lW5nIHRo4buDIGPhu6dhIGJp4bq/biBTbGVlcCwgbmdoxKlhIGzDoCBjaMO6bmcgdGEgdGjhu7FjIGhp4buHbiBiw6BpIHRvw6FuOiANCg0KS2nhu4NtIMSR4buLbmggJEhfMCQ6cDE9cDINCg0Kxq/hu5tjIGzGsOG7o25nIHPhu7EgY2jDqm5oIGzhu4djaCB24buBIHThu7cgbOG7hyBuaOG7i3AgdGltIMSR4bqtcCBoxqFuIDY5IG5o4buLcC9waMO6dCB24bubaSB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6cuDQoNCmBgYHtyfQ0KdG1wbTMgPC0gdG1wbVt0bXBtJERhaWx5LlN0ZXBzID4gNTAwMCxdDQp0bXBmMyA8LSB0bXBmW3RtcGYkRGFpbHkuU3RlcHMgPiA1MDAwLF0NCg0KYSA8LSBjKG5yb3codG1wbSksIG5yb3codG1wZikpDQpiIDwtIGMobnJvdyh0bXBtMyksIG5yb3codG1wZjMpKQ0KDQpwcm9wLnRlc3QoYixhKQ0KYGBgDQoNCktob+G6o25nIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBuaOG7i3AgdGltIGPDsyDigJxU4buTbiB04bqhaSB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6figJ0gduG7m2kgxJHhu5kgdGluIGPhuq15IDk1JSBsw6A6JDAuMDQ0NjM8cDwgMC4yMjEwMyQNCg0KIyMjIEtp4buDbSDEkeG7i25oIHTDrW5oIMSR4buZYyBs4bqtcCAtIGtp4buDbSDEkeG7i25oIGNoaSBiw6xuaCBwaMawxqFuZw0KDQpHaeG6oyB0aHV54bq/dCBIMDogWCxZIMSR4buZYyBsw6JwOyANCg0KxJDhu5FpIHRodXnhur90IEgxOiBYLFkga2jDtG5nIMSR4buZYyBs4bqtcA0KDQoNCmBgYHtyfQ0KY2hpc3EudGVzdChsbykNCmBgYA0KDQpU4burIGLhuqNuZyBr4bq/dCBxdeG6oyB0YSBjw7MgcC12YWx1ZSA9JDcqMTBeey0xNX0kIDwwLDA1OiBCw6FjIGLhu48gJEhfMCQNCkvhur90IGx14bqtbiwgdmnhu4djIG3huqV0IG5n4bunIHbhu5tpIHPhu5EgYsaw4bubYyDEkWkgY+G7p2Egbmjhu69uZyBuZ8aw4budaSB0aOG7sWMgaGnhu4duIGto4bqjbyBzw6F0IGPDsyBsacOqbiBo4buHIHbhu5tpIG5oYXUsIHbhu5tpIG3hu6ljIMO9IG5naMSpYSA1JQ0KDQoNCiMgQ2jGsMahbmcgNTogQ8OhYyBtw7QgaMOsbmggaOG7k2kgcXV5DQoNCiMjIE3DtCAgaMOsbmhow6xuaCBo4buTaSBxdXkgY+G7lSDEkWnhu4NuIC0gxJHhu5MgdGjhu4sgZOG6oW5nIHNjYXR0ZXINCg0KYGBge3J9DQoNCmdncGxvdChkYXRhID0gZCwgYWVzKHggPSBRdWFsaXR5Lm9mLlNsZWVwLCB5ID0gU2xlZXAuRHVyYXRpb24pKSArIGdlb21fc21vb3RoKGZvcm11bGEgPSB5IH4geCwgbWV0aG9kID0gJ2xtJywgY29sb3IgPSAnZ3JlZW4nKSArIGdlb21fcG9pbnQoY29sb3IgPSAncmVkJykNCmdncGxvdChkYXRhID0gZCwgYWVzKHggPSBRdWFsaXR5Lm9mLlNsZWVwLCB5ID0gU3RyZXNzLkxldmVsKSkgKyBnZW9tX3Ntb290aChmb3JtdWxhID0geSB+IHgsIG1ldGhvZCA9ICdsbScsIGNvbG9yID0gJ2dyZWVuJykgKyBnZW9tX3BvaW50KGNvbG9yID0gJ3JlZCcpDQpnZ3Bsb3QoZGF0YSA9IGQpICsNCiAgZ2VvbV9iaW4yZChtYXBwaW5nID0gYWVzKHggPSBTdHJlc3MuTGV2ZWwsIHkgPSBIZWFydC5SYXRlKSkNCmdncGxvdChkYXRhID0gZCxtYXBwaW5nID0gYWVzKCAgICAgICAgICB4ID0gUXVhbGl0eS5vZi5TbGVlcCx5ID0gRGFpbHkuU3RlcHMsIGNvbG9yID0gU3RyZXNzLkxldmVsKSkgKyBnZW9tX3BvaW50KCBzaXplID0gMSxhbHBoYSA9IDAuNSkgK2dlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsc2l6ZSA9IDIpDQpgYGANCg0KUXVhIGJp4buDdSDEkeG7kyB0YSB0aOG6pXkgY8OhYyBiaeG6v24gbmjGsCBRdWFsaXR5Lm9mLlNsZWVwLCBTbGVlcC5EdXJhdGlvbiAsU3RyZXNzLkxldmVsLCBIZWFydC5SYXRlLCBEYWlseS5TdGVwcyDEkcOodSBjw7MgbGnDqm4ga8OqdCB24bubaSBuaMOhdSwNCg0KIyMgSOG7k2kgcXV5IHR1eeG6v24gdMOtbmggY2hvIGJp4bq/biBjw7MgZOG7ryBsaeG7h3Ugbmjhu4sgcGjDom4gdsOgIGPDoWMgYmnhur9uIGtow6FjDQoNCiMjIyBYw6J5IGThu7FuZyB2w6AgbeG7pWMgxJHDrWNoIGPhu6dhIG3DtCBow6xuaCANCg0KVGhp4bq/dCBr4bq/IG3DtCBow6xuaCBo4buTaSBxdXkgduG7gSBjw6FjIHnhur91IHThu5EgZOG6q24gxJHhu4FuIHRyaeG7h3QgY2jhu6luZyBt4bqldCBuZ+G7py4gVGjDtG5nIHF1YW4ga2nhu4NtIMSR4buLbmggQ2hpIGLDrG5oIHBoxrDGoW5nIChDaGkgc3F1YXJlZCB0ZXN0LCBjaGlzcS50ZXN0KSB0cm9uZyBk4buvIGxp4buHdSB0YSBuaOG6rW4gcmEgYmnhur9uIHBo4bulIHRodeG7mWMgYFNsZWVwIERpc29yZGVyYCBoaeG7h24gdOG6oWkgbMOgIGJp4bq/biBgU2xlZXBgIHbhu5tpIGThu68gbGnhu4d1IG5o4buLIHBow6JuIHbhu5tpIGPDoWMgYmnhur9uIMSR4buBdSBjw7MgbGnDqm4gcXVhbiDEkeG6v24gbmhhdSAodHJvbmcgZOG7ryBsaeG7h3UgY8OybiBjw7MgYmnhur9uIElEIG5oxrBuZyDEkcOieSBsw6AgYmnhur9uIGTDuW5nIGtoYWkgYsOhbyBz4buRIHRo4bupIHThu7EgbsOqbiBraMO0bmcgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvhur8pLiANCg0KU3V5IHJhLCBoaeG7h24gdOG6oWkgdGEgY8OzIGPDoWMgYmnhur9uIGzDoDoNCg0KLSBCaeG6v24g4oCYU2xlZXAgRGlzb3JkZXLigJk6IGJp4bq/biBwaOG7pSB0aHXhu5ljIHRo4buDIGhp4buHbiB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6cgIA0KDQo9PiBCaeG6v24gJ1NsZWVwJzogYmnhur9uIG5o4buLIHBow6JuIG5o4bqtbiBnacOhIHRy4buLIDEgKCBsw6AgJ3llcycpIHTGsMahbmcgxJHGsMahbmcgduG7m2kgYmnhu4N1IGhp4buHbiBOb25lICwgIG5o4bqtbiBnacOhIHRy4buLIDAobMOgICdubycpIHTGsMahbmcgxJHGsMahbmcgduG7m2kgYmnhu4N1IGhp4buHbiBJbnNvbW5pYSB2w6AgU2xlZXAgQXBuZWEgY+G7p2EgYmnhur9uIOKAmFNsZWVwIERpc29yZGVy4oCZLg0KDQotIEJp4bq/biDigJhBZ2XigJk6IFR14buVaSBuZ2jhu4EgY+G7p2EgbmfGsOG7nWkgdMOtbmggdGhlbyBuxINtLg0KDQotIEJp4bq/biDigJhHZW5kZXI6IGzDoCBiaeG6v24gxJHhu4tuaCB0w61uaCB24bubaSBraeG7g3UgZOG7ryBsaeG7h3Uga8OtIHThu7EgduG7m2kgMiBiaeG7g3UgaGnhu4duIGPDsyB0aOG7gyBraGFpIGLDoW8gYmnhur9uIGdp4bqjIG5o4buLIHBow6JuIG5oxrAgc2F1OiJGZW1hbGUiIG5o4bqtbiBnacOhIHRy4buLIDAgdsOgICJNYWxlIiBuaMOibiBnacOhIHRy4buLIDEuDQoNCi0gQmnhur9uIOKAmE9jY3VwYXRpb27igJk6IHRo4buDIGhp4buHbiBuZ2jhu4EgbmdoaeG7h3AgbMOgIGThu68gbGnhu4d1IMSR4buLbmggdMOtbmggY2jhu4kgY8OzIHRo4buDIGjhu5NpIHF1eSB24bubaSBk4buvIGxp4buHdSBjaMOpbyBn4buZcCANCg0KLSBCaeG6v24g4oCZIFNsZWVwIER1cmF0aW9u4oCZIChnaeG7nSk6IFPhu5EgZ2nhu50gbeG7mXQgbmfGsOG7nWkgbmfhu6cgbeG7l2kgbmfDoHkuDQoNCi0gQmnhur9uIOKAmFF1YWxpdHkgb2YgU2xlZXDigJk6IMSQw6FuaCBnacOhIHbhu4EgY2jhuqV0IGzGsOG7o25nIGdp4bqlYyBuZ+G7pyANCg0KLSBCaeG6v24g4oCYUXVhbGl0eSBvZiBTbGVlcOKAmTogxJDDoW5oIGdpw6EgduG7gSBjaOG6pXQgbMaw4bujbmcgZ2nhuqVjIG5n4bunIA0KDQotIEJp4bq/biDigJhTdHJlc3MgTGV2ZWzigJk6IMSQw6FuaCBnacOhIGNo4bunIHF1YW4gduG7gSBt4bupYyDEkeG7mSBjxINuZyB0aOG6s25nDQoNCi0gQmnhur9uIOKAmEJNSSBDYXRlZ29yeeKAmTogIEJNSSBj4bunYSBt4buZdCBuZ8aw4budaSBsw6AgYmnhur9uIMSR4buLbmggbMaw4bujbmcgbmjGsG5nIOG7nyDEkcOieSBjw6FjIGJp4bq/biBuw7NpIHbhu4EgY2jhu4kgc+G7kSB0aOG7gyB0cuG7jW5nIGPhu6dhIGPGoSB0aOG7gyBjw7MgdGjhu6kgYuG6rWMgbsOqbiBjw7MgdGjhu4MgZ8OhbiDEkWnhu4NtIHPhu5EgY2hvIGPDoWMgdGh14buZYyB0w61uaC4NCg0KLSBCaeG6v24g4oCYQm9vbGQgUHJlc3N1cmXigJk6IMSQbyBodXnhur90IMOhcCBj4bunYSBt4buZdCBuZ8aw4budaS4gaHV54bq/dCDDoXAgxJHGsOG7o2MgbGnhu4d0IGvDqiB0aGVvIHRo4bupIHThu7EgdMSDbmcgZOG6p24gbsOqbiBjw7MgdGjhu4MgdGnhur9uIGjDoG5oIGfDoW4gxJFp4buDbSBz4buRIGNobyBjw6FjIHRodeG7mWMgdMOtbmgNCg0KLSBCaeG6v24g4oCYSGVhcnQgUmF0ZeKAmTogbMOgIGThu68gbGnhu4d1IHPhu5Egbmjhu4twIHRpbQ0KDQotIEJp4bq/biDigJhEYWlseSBTdGVwc+KAmTogU+G7kSBixrDhu5tjIG3hu5l0IG5nxrDhu51pIHRo4buxYyBoaeG7h24gbeG7l2kgbmfDoHkNCg0KRG8gc+G7sSBraMOhYyBiaeG7h3QgduG7gSB0w61uaCBjaOG6pXQgc2F1IMSRw6J5IHTDtGkgc+G6vSB4w6J5IGThu7FuZyA0IG3DtCBow6xuaCDEkWEgYmnhur9uOg0KDQotIE3DtCBow6xuaCBsb2dpc3RpYyBjw7MgYmnhur9uIGdp4bqjaSB0aMOtY2ggbMOgIGJp4bq/biDEkeG7i25oIHTDrW5oIG5oxrAgYmnhur9uIFNsZWVwIH4gT2NjdXBhdGlvbiArQWdlDQoNCi0gTcO0IGjDrG5oIGxvZ2lzdGljIGPDsyBiaeG6v24gZ2nhuqNpIHRow61jaCBsw6AgYmnhur9uIMSR4buLbmggdMOtbmggdGhlbyBwaMawxqFuZyBwaMOhcCBnw6FuIMSRaeG7g20gc+G7kSBjaG8gY8OhYyB0aHXhu5ljIHTDrW5oIEtoaSBiaeG6v24gxJHhu4tuaCB0w61uaCBjw7MgY8OhYyB0aHXhu5ljIHTDrW5oIGPDsyB0aOG7qSB04buxLiBTbGVlcCB+IEJNSSBDYXRlZ29yeSArIFF1YWxpdHkgb2YgU2xlZXANCg0KLSBNw7QgaMOsbmggbG9naXN0aWMgY8OzIGJp4bq/biBnaeG6o2kgdGjDrWNoIGzDoCBiaeG6v24gxJHhu4tuaCB0w61uaCB0aGVvIHBoxrDGoW5nIHBow6FwIGfDoW4gxJFp4buDbSBz4buRIGNobyBjw6FjIHRodeG7mWMgdMOtbmggS2hpIGJp4bq/biDEkeG7i25oIHTDrW5oIGPDsyBjw6FjIA0KdGh14buZYyB0w61uaCBjw7MgbeG7qWMgxJHhu5kgc28gc8OhbmguIFNsZWVwIH4gQm9vbGQgUHJlc3N1cmUgKyBQaHlzaWNhbCBBY3Rpdml0eSBMZXZlcmwNCg0KLSBI4buTaSBxdXkgbcO0IGjDrG5oIMSRYSBiaeG6v24gY+G7p2EgIGPhu6dhIGJp4bq/biBTbGVlcH4gR2VuZGVyKyBTbGVlcC5EdXJhdGlvbiArU3RyZXNzLkxldmVsICtIZWFydC5SYXRlLiANCg0KDQojIyMgTcO0IGjDrG5oIGxvZ2lzdGljIHBoxrDGoW5nIHBow6FwIGTDuW5nIGJp4bq/biBnaeG6oyBuaOG7iyBwaMOibiBiaeG6v24gU2xlZXAgfiBPY2N1cGF0aW9uKyBBZ2UNCg0KVuG7m2kgYmnhur9uIMSR4buLbmggdMOtbmggIE9jY3VwYXRpb24gY8OzIGsgdGh14buZYyB0w61uaCB0aMOsIHPhu60gZOG7pW5nIGsg4oCTIDEgYmnhur9uIGdp4bqjIG5o4buLIHBow6JuOg0KDQokRF8xJCA9IHsxIGzDoCBuZ8OgbmggRG9ydG9yIDsgMCBu4bq/dSBsw6AgbmfDoG5oIGtow6FjfQ0KDQokRF8yJCA9IHsxIGzDoCBuZ8OgbmggRW5naW5lZXIgOyAwIG7hur91IGzDoCBuZ8Ogbmgga2jDoWN9DQoNCiREXzMkID0gezEgbMOgIG5nw6BuaCBMYXd5ZXIgOyAwIG7hur91IGzDoCBuZ8Ogbmgga2jDoWN9DQoNCiREXzQkID0gezEgbMOgIG5nw6BuaCBNYW5hZ2VyIDsgMCBu4bq/dSBsw6AgbmfDoG5oIGtow6FjfQ0KDQokRF81JCA9IHsxIGzDoCBuZ8OgbmggTnVyc2UgOyAwIG7hur91IGzDoCBuZ8Ogbmgga2jDoWN9DQoNCiREXzYkID0gezEgbMOgIG5nw6BuaCBTYWxlcyBSZXByZXNlbnRhdGl2ZSA7IDAgbuG6v3UgbMOgIG5nw6BuaCBraMOhY30NCg0KJERfNyQgPSB7MSBsw6AgbmfDoG5oIFNhbGVzcGVyc29uIDsgMCBu4bq/dSBsw6AgbmfDoG5oIGtow6FjfQ0KDQokRF84JCA9IHsxIGzDoCBuZ8OgbmggU2NpZW50aXN0IDsgMCBu4bq/dSBsw6AgbmfDoG5oIGtow6FjfQ0KDQokRF85JCA9IHsxIGzDoCBuZ8OgbmggU29mdHdhcmUgRW5naW5lZSA7IDAgbuG6v3UgbMOgIG5nw6BuaCBraMOhY30NCg0KJERfezEwfSQgPSB7MSBsw6AgbmfDoG5oIFRlYWNoZXIgOyAwIG7hur91IGzDoCBuZ8Ogbmgga2jDoWN9DQoNCkjhu5NpIHF1eSBsb2dpc3RpYyB24buBIOG6o25oIGjGsOG7n25nIGPhu6dhICBuZ2jhu4EgbmdoacOqcCAsIHR14buVaSDEkeG7kWkgduG7m2kgc+G7sSB2aeG7h2MgeHXhuqV0IGhp4buHbiBjw6FjIHRyaeG7h3UgY2jhu6luZyBt4bqldCBuZ+G7pywgdHJvbmcgxJHDsyBiaeG6v24gbmdo4buBIG5naGnhu4dwIMSRxrDhu6NjIMSR4bqhaSBkaeG7h24gYuG7n2kgMTAgYmnhur9uIGdp4bqjIG5o4buLIHBow6JuDQoNCiRsb2coXGZyYWN7z4B9ezHiiJLPgH0pPSBcYmV0YV8wK1xiZXRhMSp4XzErY18xKkRfMStjXzIqRF8yK2NfMypEXzMrLisuLmNfezEwfSpEX3sxMH0kDQoNCmBgYHtyfQ0Kb2MgPC0gZ2xtKGZhY3RvcihTbGVlcCkgfiBBZ2UrT2NjdXBhdGlvbiwgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpLCBkYXRhID0gZCApDQpvYw0KYGBgDQoNClThu6sgxJHDsyBuaOG6rW4gxJHGsOG7o2MgbcO0IGjDrG5oIGjhu5NpIHF1eSDGsOG7m2MgbMaw4bujbmc6DQoNCiRsb2coXGZyYWN7z4B9ezHiiJLPgH0pPSAtNi4wNTE3KzAuMTEzMXhfMS0wLjA1NzZjXzEtMS42ODI1Y18yLTAuNTQ1MWNfMy0gMTQuNTk5NSBjXzQrIDIuNDUxNGNfNSArMTguNDU1N2NfNiArMy44NDI1Y183KzIuMjY3NSAgIGNfOCsxLjM3NzggKiBjXzkrMi42MzMyICogIGNfezF9JA0KDQpNw7QgaMOsbmggxrDhu5tjIGzGsOG7o25nIMSR4buRaSB24bubaSBuaOG7r25nIG5nxrDhu51pIGzDoG0gRG9jdG9yIGzDoDogDQogICRsb2coXGZyYWN7z4B9ezHiiJLPgH0pPSAtNi4xMTQ3KyAwLjExMzEgQWdlJCANCiAgDQogICAgICBkbyDEkcOzIHjDoWMgc3XhuqV0IG3huqV0IGPhu6dhIG5ow7NtIG5nw6BuaCBiw6FjIHPEqSB0cnVuZyBiw6xuaCDGsOG7m2MgdMOtbmggbMOgOg0KICAkXHBpKHhfMSwxKT1bMSArIGV4cCAoLTYuMTE0NysgMC4xMTMxIEFnZV0pXnstMX0kDQogIA0KTcO0IGjDrG5oIMaw4bubYyBsxrDhu6NuZyDEkeG7kWkgduG7m2kgbmjhu69uZyBuZ8aw4budaSBsw6BtIEVuZ2luZWVyIGzDoDoNCiRsb2coXGZyYWN7z4B9ezHiiJLPgH0pPSAtNy43MzQyKyAwLjExMzEgQWdlJCANCiAgDQogICAgICBkbyDEkcOzIHjDoWMgc3XhuqV0IG3huqV0IGPhu6dhIG5ow7NtIG5nw6BuaCBFbmdpbmVlciDGsOG7m2MgdMOtbmggbMOgOg0KICAkXHBpKHhfMSwxKT1bMSArIGV4cCAoLTcuNzM0MisgMC4xMTMxIEFnZV0pXnstMX0kDQogIA0KTcO0IGjDrG5oIMaw4bubYyBsxrDhu6NuZyDEkeG7kWkgduG7m2kgbmjhu69uZyBuZ8aw4budaSBsw6BtIExhd3llciBsw6A6DQokbG9nKFxmcmFje8+AfXsx4oiSz4B9KT0gLTYuNTk2OCsgMC4xMTMxIEFnZSQgDQogIA0KICAgICAgZG8gxJHDsyB4w6FjIHN14bqldCBt4bqldCBj4bunYSBuaMOzbSBuZ8OgbmggTGF3eWVyIMaw4bubYyB0w61uaCBsw6A6DQogICRccGkoeF8xLDEpPVsxICsgZXhwICgtNi41OTY4KyAwLjExMzEgQWdlXSleey0xfSQNCiAgDQpNw7QgaMOsbmggxrDhu5tjIGzGsOG7o25nIMSR4buRaSB24bubaSBuaOG7r25nIG5nxrDhu51pIGzDoG0gTWFuYWdlciBsw6A6DQokbG9nKFxmcmFje8+AfXsx4oiSz4B9KT0gLTIwLjY1MTIrIDAuMTEzMSBBZ2UkIA0KICANCiAgICAgIGRvIMSRw7MgeMOhYyBzdeG6pXQgbeG6pXQgY+G7p2EgbmjDs20gbmfDoG5oICBNYW5hZ2VyICDGsOG7m2MgdMOtbmggbMOgOg0KICAkXHBpKHhfMSwxKT1bMSArIGV4cCAoLTIwLjY1MTIrIDAuMTEzMSBBZ2VdKV57LTF9JA0KICANCk3DtCBow6xuaCDGsOG7m2MgbMaw4bujbmcgxJHhu5FpIHbhu5tpIG5o4buvbmcgbmfGsOG7nWkgbMOgbSBOdXJzZSBsw6A6DQokbG9nKFxmcmFje8+AfXsx4oiSz4B9KT0gLTMuNjAwMysgMC4xMTMxIEFnZSQgDQogIA0KICAgICAgZG8gxJHDsyB4w6FjIHN14bqldCBt4bqldCBj4bunYSBuaMOzbSBuZ8OgbmggeSB0w6EgdHJ1bmcgYsOsbmggxrDhu5tjIHTDrW5oIGzDoDoNCiAgJFxwaSh4XzEsMSk9WzEgKyBleHAgKC0zLjYwMDMrIDAuMTEzMSBBZ2VdKV57LTF9JA0KICANCk3DtCBow6xuaCDGsOG7m2MgbMaw4bujbmcgxJHhu5FpIHbhu5tpIG5o4buvbmcgbmfGsOG7nWkgbMOgbSBTYWxlcyBSZXByZXNlbnRhdGl2ZSBsw6A6DQokbG9nKFxmcmFje8+AfXsx4oiSz4B9KT0gMTIuNDA0KyAwLjExMzEgQWdlJCANCiAgDQogICAgICBkbyDEkcOzIHjDoWMgc3XhuqV0IG3huqV0IGPhu6dhIG5ow7NtIG5nw6BuaCBTYWxlcyBSZXByZXNlbnRhdGl2ZSDGsOG7m2MgdMOtbmggbMOgOg0KICAkXHBpKHhfMSwxKT1bMSArIGV4cCAoMTIuNDA0KyAwLjExMzEgQWdlXSleey0xfSQNCiAgDQpNw7QgaMOsbmggxrDhu5tjIGzGsOG7o25nIMSR4buRaSB24bubaSBuaOG7r25nIG5nxrDhu51pIGzDoG0gU2FsZXNwZXJzb24gbMOgOg0KJGxvZyhcZnJhY3vPgH17MeKIks+AfSk9IC0yLjIwOTIrIDAuMTEzMSBBZ2UkIA0KICANCiAgICAgIGRvIMSRw7MgeMOhYyBzdeG6pXQgbeG6pXQgY+G7p2EgbmjDs20gbmfDoG5oIFNhbGVzcGVyc29uIMaw4bubYyB0w61uaCBsw6A6DQogICRccGkoeF8xLDEpPVsxICsgZXhwICgtMi4yMDkyKyAwLjExMzEgQWdlXSleey0xfSQNCiAgDQpNw7QgaMOsbmggxrDhu5tjIGzGsOG7o25nIMSR4buRaSB24bubaSBuaOG7r25nIG5nxrDhu51pIGzDoG0gU2NpZW50aXN0IGzDoDoNCiRsb2coXGZyYWN7z4B9ezHiiJLPgH0pPSAtMy43ODQyKyAwLjExMzEgQWdlJCANCiAgDQogICAgICBkbyDEkcOzIHjDoWMgc3XhuqV0IG3huqV0IGPhu6dhIG5ow7NtIG5nw6BuaCBTY2llbnRpc3QgIMaw4bubYyB0w61uaCBsw6A6DQogICRccGkoeF8xLDEpPVsxICsgZXhwICgtMy43ODQyKyAwLjExMzEgQWdlXSleey0xfSQNCiAgDQpNw7QgaMOsbmggxrDhu5tjIGzGsOG7o25nIMSR4buRaSB24bubaSBuaOG7r25nIG5nxrDhu51pIGzDoG0gU29mdHdhcmUgRW5naW5lZXIgbMOgOg0KJGxvZyhcZnJhY3vPgH17MeKIks+AfSk9IC00LjY3MzkrIDAuMTEzMSBBZ2UkIA0KICANCiAgICAgIGRvIMSRw7MgeMOhYyBzdeG6pXQgbeG6pXQgY+G7p2EgbmjDs20gbmfDoG5oIFNvZnR3YXJlIEVuZ2luZWVyIMaw4bubYyB0w61uaCBsw6A6DQogICRccGkoeF8xLDEpPVsxICsgZXhwICgtNC42NzM5KyAwLjExMzEgQWdlXSleey0xfSQNCiAgDQpNw7QgaMOsbmggxrDhu5tjIGzGsOG7o25nIMSR4buRaSB24bubaSBuaOG7r25nIG5nxrDhu51pIGzDoG0gVGVhY2hlciBsw6A6DQokbG9nKFxmcmFje8+AfXsx4oiSz4B9KT0gLTMuNDE4NSsgMC4xMTMxIEFnZSQgDQogIA0KICAgICAgZG8gxJHDsyB4w6FjIHN14bqldCBt4bqldCBj4bunYSBuaMOzbSBuZ8OgbmggZ2nDoW8gdmnDqm4gdHJ1bmcgYsOsbmggxrDhu5tjIHTDrW5oIGzDoDoNCiAgJFxwaSh4XzEsMSk9WzEgKyBleHAgKC0zLjQxODUrIDAuMTEzMSBBZ2VdKV57LTF9JA0KDQoNCiMjIyBNw7QgaMOsbmggaOG7k2kgcXV5IGxvZ2lzdGljIHbhu5tpIGJp4bq/biDEkeG7i25oIHTDrW5oIGPDsyBjw6FjIHRodeG7mWMgdMOtbmggDQoNCiMjIyMgQmnhur9uIMSR4buLbmggdMOtbmggY8OzIGPDoWMgdGh14buZYyB0w61uaCBjw7MgdGjhu6kgdOG7sSANCg0KSOG7k2kgcXV5IGxvZ2lzdGljIHbhu4Eg4bqjbmggaMaw4bufbmcgY+G7p2EgxJFp4buDbSDEkcOhbmggZ2nDoSBnaeG6pWMgbmfhu6cgYFF1YWxpdHkgb2YgU2xlZXBgLCBjaOG7iSBz4buRIGBCTUkgQ2F0ZWdvcnlgIChiaeG6v24gxJHhu4tuaCB0w61uaCBjw7MgY+G6pXAgxJHhu5kgdGjhu6kgdOG7sSkgxJHhu5FpIHbhu5tpIHPhu7EgeHXhuqV0IGhp4buHbiB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6cuVHJvbmcgxJHDsyBiaeG6v24gQk1JIMSRxrDhu6NjIGfDoW4gxJFp4buDbSB7MSwgMiwgMywgNH0gdMSDbmcgZOG6p24gdGhlbyB0aOG7gyB0cuG7jW5nIGPhu6dhIGPGoSB0aOG7gzoNCg0KJGxvZyhcZnJhY3vPgH17MeKIks+AfSk9IFxiZXRhXzArXGJldGExKnhfMStcYmV0YTIqQk1JJA0KDQpgYGB7cn0NCmQkQk1JLkNhdGVnb3J5IDwtIG1hcHZhbHVlcyhkJEJNSS5DYXRlZ29yeSxmcm9tPSBjKCAnTm9ybWFsJywgJ05vcm1hbCBXZWlnaHQnLCAnT2Jlc2UnLCAnT3ZlcndlaWdodCcpLHRvPWMoJzEnLCcyJywnNCcsJzMnKSkNCg0KZCRCTUkuQ2F0ZWdvcnkgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZCRCTUkuQ2F0ZWdvcnkpKQ0KDQpgYGANCg0KQ2jhuqF5IMaw4bubYyBsxrDhu6NuZyBjaG8gcmEgbcO0IGjDrG5oIGjhu5NpIHF1eSDGsOG7m2MgbMaw4bujbmc6DQpgYGB7cn0NCmxvZyA8LSBnbG0oZmFjdG9yKFNsZWVwKSB+IFF1YWxpdHkub2YuU2xlZXArIEJNSS5DYXRlZ29yeSAgLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gJ2xvZ2l0JyksIGRhdGEgPSBkICkNCmxvZw0KYGBgDQoNCiRsb2coXGZyYWN7z4B9ezHiiJLPgH0pPS0zLjQ0NCAtMC4yMzNRdWFsaXR5Lm9mLlNsZWVwICsgMi4zMDIgIEJNSS5DYXRlZ29yeSQNCg0KS+G6v3QgcXXhuqMgaOG7k2kgcXV5IGNobyB0aOG6pXkgY+G6oyDEkWnhu4NtIMSRw6FuaCBnacOhIGdp4bqlYyBuZ+G7pyBgUXVhbGl0eSBvZiBTbGVlcGAsIGNo4buJIHPhu5EgYEJNSSBDYXRlZ29yeWAgIMSR4buBdSB0aOG7sWMgc+G7sSBjw7Mg4bqjbmggaMaw4bufbmcgxJHhur9uIHjDoWMgc3XhuqV0IGPDsyB0cmnhu4d1ICBjaOG7qW5nIG3huqV0IG5n4bunLiRCXzIgPSAyLjMwMiA+IDAkIHbDoCB04burIGPDoWNoIGfDoW4gxJFp4buDbSBjaG8gYmnhur9uIMSR4buLbmggdMOtbmggQk1JIHTEg25nIGThuqduIHRoZW8gdGjhu4MgdHLhu41uZyBj4bunYSBjxqEgdGjhu4MgY2hvIHRo4bqleSB4w6FjIGPDsyB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6cgdOG6sW5nIGtoaSBCTUkgdMSDbmcNCg0KTcO0IGjDrG5oIGjhu5NpIHF1eSBsb2dpc3RpYyDGsOG7m2MgbMaw4bujbmcgxJHhu5FpIHbhu5tpIG5o4buvbmcgQk1JKE5vcm1hbD0xKTogJGxvZyhcZnJhY3vPgH17MeKIks+AfSk9IC0wLjE0MiAtMC4yMzNRdWFsaXR5Lm9mLlNsZWVwJCANCiAgZG8gxJHDsyB4w6FjIHN14bqldCBt4bqldCBuZ+G7pyBj4bunYSBuaMOzbSBOb3JtYWwgxJHGsOG7o2MgxrDhu5tjIHTDrW5oIGzDoDogJFxwaSh4XzEsMSk9WzEgKyBleHAgKC0wLjE0Mi0wLjIzM1F1YWxpdHkub2YuU2xlZXApXnstMX0kDQoNCk3DtCBow6xuaCBo4buTaSBxdXkgbG9naXN0aWMgxrDhu5tjIGzGsOG7o25nIMSR4buRaSB24bubaSBuaOG7r25nIEJNSShOb3JtYWwgd2VpZ2h0ID0yKTogJGxvZyhcZnJhY3vPgH17MeKIks+AfSk9IDMuMTYgLTAuMjMzUXVhbGl0eS5vZi5TbGVlcCQgDQogIGRvIMSRw7MgeMOhYyBzdeG6pXQgbeG6pXQgbmfhu6cgY+G7p2EgbmjDs20gTm9ybWFsIHdlaWdodCDEkcaw4bujYyDGsOG7m2MgdMOtbmggbMOgOiAkXHBpKHhfMSwxKT1bMSArIGV4cCAoMy4xNi0wLjIzM1F1YWxpdHkub2YuU2xlZXApXnstMX0kDQoNCk3DtCBow6xuaCBo4buTaSBxdXkgbG9naXN0aWMgIMaw4bubYyBsxrDhu6NuZyDEkeG7kWkgduG7m2kgbmjhu69uZyBCTUkoT3ZlcndlaWdodD0zJyk6ICRsb2coXGZyYWN7z4B9ezHiiJLPgH0pPSA2LjQ2MiAtMC4yMzNRdWFsaXR5Lm9mLlNsZWVwJCANCiAgZG8gxJHDsyB4w6FjIHN14bqldCBt4bqldCBuZ+G7pyBj4bunYSBuaMOzbSBPdmVyd2VpZ2h0IMSRxrDhu6NjIMaw4bubYyB0w61uaCBsw6A6ICRccGkoeF8xLDEpPVsxICsgZXhwICg2LjQ2Mi0wLjIzM1F1YWxpdHkub2YuU2xlZXApXnstMX0kDQoNCk3DtCBow6xuaCBo4buTaSBxdXkgbG9naXN0aWMgxrDhu5tjIGzGsOG7o25nIMSR4buRaSB24bubaSBuaOG7r25nIEJNSSAoT2Jlc2U9NCk6ICRsb2coXGZyYWN7z4B9ezHiiJLPgH0pPSA5Ljc2NCAtMC4yMzNRdWFsaXR5Lm9mLlNsZWVwJCANCiAgZG8gxJHDsyB4w6FjIHN14bqldCBt4bqldCBuZ+G7pyBj4bunYSBuaMOzbSBPYmVzZSDEkcaw4bujYyDGsOG7m2MgdMOtbmggbMOgOiAkXHBpKHhfMSwxKT1bMSArIGV4cCAoOS43NjQtMC4yMzNRdWFsaXR5Lm9mLlNsZWVwKV57LTF9JA0KDQojIyMjIEJp4bq/biDEkeG7i25oIHTDrW5oIGPDsyBjw6FjIHRodeG7mWMgdMOtbmggY8OzIG3hu6ljIMSR4buZIHNvIHPDoW5oIA0KDQpI4buTaSBxdXkgbG9naXN0aWMgduG7gSDhuqNuaCBoxrDhu59uZyBj4bunYSB0aOG7nWkgZ3VhbiBob+G6oXQgxJHhu5luZyBQaHlzaWNhbCBBY3Rpdml0eSBMZXZlcmwsIGh1eeG6v3Qgw6FwIEJvb2xkIFByZXNzdXJlIChiaeG6v24gxJHhu4tuaCB0w61uaCBjw7MgY23hu6ljIMSR4buZIHNvIHPDoW5oICkgxJHGsOG7o2Mgdmnhur90IHTDom0gdGh1L3TDom0gdHLGsMahbmcgxJHhu5FpIHbhu5tpIHPhu7EgeHXhuqV0IGhp4buHbiB0cmnhu4d1IGNo4bupbmcgbeG6pXQgbmfhu6cuVHJvbmcgxJHDsyBiaeG6v24gaHV54bq/dCDDoXAgxJHGsOG7o2MgZ8OhbiDEkWnhu4NtIHsxLCAyLCAuLi4sMjQsIDI1fSB0xINuZyBk4bqnbiB0aGVvIHRo4buDIHRy4buNbmcgY+G7p2EgY8ahIHRo4buDOg0KDQpgYGB7cn0NCmQkQmxvb2QuUHJlc3N1cmUgPC0gbWFwdmFsdWVzKGQkQmxvb2QuUHJlc3N1cmUsIGZyb20gPSBjKCcxMTUvNzUnLCAnMTE1Lzc4JywgJzExNy83NicsICcxMTgvNzUnLCAnMTE4Lzc2JywgJzExOS83NycsICcxMjAvODAnLCAnMTIxLzc5JywgJzEyMi84MCcsICcxMjUvODAnLCAnMTI1LzgyJywgJzEyNi84MycsICcxMjgvODQnLCAnMTI4Lzg1JywgJzEyOS84NCcsICcxMzAvODUnLCAnMTMwLzg2JywgJzEzMS84NicsICcxMzIvODcnLCAnMTM1Lzg4JywgJzEzNS85MCcsICcxMzkvOTEnLCAnMTQwLzkwJywgJzE0MC85NScsICcxNDIvOTInKSwgdG8gPSBjKCcxJywnMicsJzMnLCc0JywnNScsJzYnLCc3JywnOCcsJzknLCcxMCcsJzExJywnMTInLCcxMycsJzE0JywnMTUnLCcxNicsJzE3JywnMTgnLCcxOScsJzIwJywnMjEnLCcyMicsJzIzJywnMjQnLCcyNScpKQ0KZCRCbG9vZC5QcmVzc3VyZSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihkJEJsb29kLlByZXNzdXJlKSkNCg0KbG9nZSA8LSBnbG0oZmFjdG9yKFNsZWVwKSB+IFBoeXNpY2FsLkFjdGl2aXR5LkxldmVsICtCbG9vZC5QcmVzc3VyZSAsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSwgZGF0YSA9IGQgKQ0KbG9nZQ0KYGBgDQpDaOG6oXkgxrDhu5tjIGzGsOG7o25nIGNobyByYSBtw7QgaMOsbmggaOG7k2kgcXV5IMaw4bubYyBsxrDhu6NuZzoNCg0KJGxvZyhcZnJhY3vPgH17MeKIks+AfSk9LTUuMjk4Ni0wLjA1MzkgUGh5c2ljYWwuQWN0aXZpdHkuTGV2ZWwgKzAuNTE1NCBCbG9vZC5QcmVzc3VyZSQNCg0KS+G6v3QgcXXhuqMgaOG7k2kgcXV5IGNobyB0aOG6pXkgY+G6oyB0aOG7nWkgZ3VhbiBob+G6oXQgxJHhu5luZyBQaHlzaWNhbCBBY3Rpdml0eSBMZXZlcmwsIGh1eeG6v3Qgw6FwIEJvb2xkIFByZXNzdXJlIMSR4buBdSB0aOG7sWMgc+G7sSBjw7Mg4bqjbmggaMaw4bufbmcgxJHhur9uIHjDoWMgc3XhuqV0IGPDsyB0cmnhu4d1ICBjaOG7qW5nIG3huqV0IG5n4bunLiRCXzIgPSAwLjUxNTQgPiAwJCB2w6AgdOG7qyBjw6FjaCBnw6FuIMSRaeG7g20gY2hvIGJp4bq/biDEkeG7i25oIHTDrW5oIGzDoCBodXnhur90IMOhcCB0xINuZyBk4bqnbiB0aGVvIHRo4buDIHRy4buNbmcgY+G7p2EgY8ahIHRo4buDIGNobyB0aOG6pXkgeMOhYyBjw7MgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIHTEg25nIGtoaSBodXnhur90IMOhcCB0xINuZw0KDQpNw7QgaMOsbmggaOG7k2kgcXV5IGxvZ2lzdGljIMaw4bubYyBsxrDhu6NuZyDEkeG7kWkgduG7m2kgbmjhu69uZyBCb29sZCBQcmVzc3VyZSA9MTogJGxvZyhcZnJhY3vPgH17MeKIks+AfSk9IC00Ljc4MzItMC4wNTM5IFBoeXNpY2FsLkFjdGl2aXR5LkxldmVsJCANCiAgZG8gxJHDsyB4w6FjIHN14bqldCBt4bqldCBuZ+G7pyDEkcaw4bujYyDGsOG7m2MgdMOtbmggbMOgOiAkXHBpKHhfMSwxKT1bMSArIGV4cCAoLTQuNzgzMi0wLjA1MzkgUGh5c2ljYWwuQWN0aXZpdHkuTGV2ZWwpXnstMX0kDQoNCk3DtCBow6xuaCBo4buTaSBxdXkgbG9naXN0aWMgxrDhu5tjIGzGsOG7o25nIMSR4buRaSB24bubaSBuaOG7r25nIEJvb2xkIFByZXNzdXJlPTI6ICRsb2coXGZyYWN7z4B9ezHiiJLPgH0pPSAtNC4yNjc4LTAuMDUzOSBQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCQgDQogIGRvIMSRw7MgeMOhYyBzdeG6pXQgbeG6pXQgbmfhu6cgxJHGsOG7o2MgxrDhu5tjIHTDrW5oIGzDoDogJFxwaSh4XzEsMSk9WzEgKyBleHAgKC00LjI2NzgtMC4wNTM5IFBoeXNpY2FsLkFjdGl2aXR5LkxldmVsKV57LTF9JA0KDQpNw7QgaMOsbmggaOG7k2kgcXV5IGxvZ2lzdGljIMaw4bubYyBsxrDhu6NuZyDEkeG7kWkgduG7m2kgbmjhu69uZyBCb29sZCBQcmVzc3VyZT0yNDogJGxvZyhcZnJhY3vPgH17MeKIks+AfSk9IDcuMDcxLTAuMDUzOSBQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCQgDQogIGRvIMSRw7MgeMOhYyBzdeG6pXQgbeG6pXQgbmfhu6cgxJHGsOG7o2MgxrDhu5tjIHTDrW5oIGzDoDogJFxwaSh4XzEsMSk9WzEgKyBleHAgKDcuMDcxLTAuMDUzOSBQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCleey0xfSQNCg0KTcO0IGjDrG5oIGjhu5NpIHF1eSBsb2dpc3RpYyDGsOG7m2MgbMaw4bujbmcgxJHhu5FpIHbhu5tpIG5o4buvbmcgQm9vbGQgUHJlc3N1cmUyPTU6ICRsb2coXGZyYWN7z4B9ezHiiJLPgH0pPSA3LjU4NjQtMC4wNTM5IFBoeXNpY2FsLkFjdGl2aXR5LkxldmVsJCANCiAgZG8gxJHDsyB4w6FjIHN14bqldCBt4bqldCBuZ+G7pyDEkcaw4bujYyDGsOG7m2MgdMOtbmggbMOgOiAkXHBpKHhfMSwxKT1bMSArIGV4cCAoNy41ODY0LTAuMDUzOSBQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCleey0xfSQNCg0KIyMjIE3DtCBow6xuaCBo4buTaSBxdXkgxJFhIGJp4bq/biB24bubaSBjw6FjIGjDoG0gbGnDqm4ga+G6v3Qga2jDoWMgbmhhdQ0KDQojIyMjIE3DtCBow6xuaCBMb2dpdA0KDQpU4bqhaSDEkcOieSB0YSB0aeG6v24gaMOgbmggaOG7k2kgcXV5IHbhu5tpIGjDoG0gbG9naXQNCiRsb2dpdCjPgCk9bG9nKFxmcmFje8+AfXsx4oiSz4B9KSQNCg0KKipNw7QgaMOsbmggaOG7k2kgcXV5KioNCg0KYGBge3J9DQpsb2dsaW4gPC0gZ2xtKGZhY3RvcihTbGVlcCkgfiBHZW5kZXIrIFNsZWVwLkR1cmF0aW9uICtTdHJlc3MuTGV2ZWwgK0hlYXJ0LlJhdGUsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSwgZGF0YSA9IGQgKQ0KbG9nbGluDQpgYGANCg0KKipLaeG7g20gxJHhu4tuaCBz4buxIHBow7kgaOG7o3AgY+G7p2EgbcO0IGjDrG5oKioNCg0KR2nhuqMgdGh1eeG6v3QgSDA6IE3DtCBow6xuaCBwaMO5IGjhu6NwLiANClRpw6p1IGNodeG6qW4gYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwIGPhu6dhIGPDoWMgdGjhu5FuZyBrw6ogbsOgeTogcF92YXVsZSA8IDUlDQoNCmBgYHtyfQ0KcGNoaXNxKGRldmlhbmNlKGxvZ2xpbiksIGRmID0gZGYucmVzaWR1YWwobG9nbGluKSwgbG93ZXIudGFpbCA9IEYpDQpgYGANCg0KVOG7qyBi4bqjbmcga+G6v3QgcXXhuqMgdHLDqm4gdGEgY8OzIHBfdmF1bGU9IDAsMzExMiA+IDAsMDUgdGEgY2jhuqVwIG5o4bqtbiANCkgwLiBW4bqteSB24bubaSBt4bupYyDDvSBuZ2jEqWEgNSUsIG3DtCBow6xuaCBwaMO5IGjhu6NwDQoNCioqQ2jhu4kgc+G7kSDEkcOhbmggZ2nDoSBtw7QgaMOsbmgqKg0KDQpgYGB7cn0NCnN1bW1hcnkobG9nbGluKQ0KQnJpZXJTY29yZShsb2dsaW4pDQpjb25mdXNpb25NYXRyaXgodGFibGUocHJlZGljdChsb2dsaW4sIHR5cGU9J3Jlc3BvbnNlJykgPj0gMC41ICxsb2dsaW4kZGF0YSRTbGVlcCA9PSAneWVzJykpDQpgYGANCg0KS+G6v3QgcXXhuqMgxrDhu5tjIGzGsOG7o25nIG3DtCBow6xuaCB0aMOsIFIgbeG6t2MgxJHhu4tuaCBz4bq9IMaw4bubYyBsxrDhu6NuZyBjaG8gdOG6p24gc+G7kSBj4bunYSDDtCDEkeG6p3UgdGnDqm4gKDEsMSkgdHJvbmcgYuG6o25nLCBuZ2jEqWEgbMOgIOG7qW5nIHbhu5tpIGvhur90IHF14bqjIG7DoHkgdGjDrDoNCg0KJGxvZyjOvMyCICk9LTUuNzk1LTEuNTQxICBHZW5kZXIgICAtMS4zODQgICBTbGVlcC5EdXJhdGlvbiAgICAgICAgICAgIC0wLjQ2OSAgIFN0cmVzcy5MZXZlbCArICAgICAgICAgICAgMC4yNjVIZWFydC5SYXRlJA0KIA0KQ8OhYyBjaOG7iSBz4buRIMSRw6FuaCBnacOhIG3DtCBow6xuaA0KDQotIERldmlhbmNlOiAzODEuODYgIA0KDQotIEFJQzogMzkxLjkNCg0KLSBCcmllclNjb3JlOiAwLjE3MQ0KDQogLUNvbmZ1c2lvbiBNYXRyaXggQ8OzIMSR4buZIMSR4bq3YyBoaeG7h3U6IDAsNjg0OyDEkeG7mSBuaOG6oXk6IDAsNzk7IMSR4buZIGNow61uaCB4w6FjIHRvw6BuIHRo4buDOiAwLDUzNQ0KDQojIyMjIE3DtCBow6xuaCBQcm9iaXQNCg0KVOG6oWkgxJHDonkgdGEgdGnhur9uIGjDoG5oIGjhu5NpIHF1eSB24bubaSBow6BtIHByb2JpdA0KJHByb2JpdCjPgCk9zqZee+KIkjF9KM+AKSQNCg0KKipNw7QgaMOsbmggaOG7k2kgcXV5KioNCg0KDQpgYGB7cn0NCmZ0MSA8LSBnbG0oZmFjdG9yKFNsZWVwKSB+IEdlbmRlcisgU2xlZXAuRHVyYXRpb24gK1N0cmVzcy5MZXZlbCArSGVhcnQuUmF0ZSwgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdwcm9iaXQnKSwgZGF0YSA9IGQgKQ0KZnQxDQpgYGANCg0KKipLaeG7g20gxJHhu4tuaCBz4buxIHBow7kgaOG7o3AgY+G7p2EgbcO0IGjDrG5oKioNCg0KR2nhuqMgdGh1eeG6v3QgSDA6IE3DtCBow6xuaCBwaMO5IGjhu6NwLiANClRpw6p1IGNodeG6qW4gYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwIGPhu6dhIGPDoWMgdGjhu5FuZyBrw6ogbsOgeTogcF92YXVsZSA8IDUlDQoNCmBgYHtyfQ0KcGNoaXNxKGRldmlhbmNlKGZ0MSksIGRmID0gZGYucmVzaWR1YWwoZnQxKSwgbG93ZXIudGFpbCA9IEYpDQpgYGANCg0KVOG7qyBi4bqjbmcga+G6v3QgcXXhuqMgdHLDqm4gdGEgY8OzIHBfdmF1bGU9IDAsMzE1ID4gMCwwNSB0YSBjaOG6pXAgbmjhuq1uIEgwLiBW4bqteSB24bubaSBt4bupYyDDvSBuZ2jEqWEgNSUsIG3DtCBow6xuaCBwaMO5IGjhu6NwDQoNCioqxJDDoW5oIGdpw6EgbcO0IGjDrG5oKioNCg0KYGBge3J9DQpzdW1tYXJ5KGZ0MSkNCkJyaWVyU2NvcmUoZnQxKQ0KY29uZnVzaW9uTWF0cml4KHRhYmxlKHByZWRpY3QoZnQxLCB0eXBlPSdyZXNwb25zZScpID49IDAuNSAsZnQxJGRhdGEkU2xlZXAgPT0gJ3llcycpKQ0KYGBgDQoNCkvhur90IHF14bqjIMaw4bubYyBsxrDhu6NuZyBtw7QgaMOsbmggdGjDrCBSIG3hurdjIMSR4buLbmggc+G6vSDGsOG7m2MgbMaw4bujbmcgY2hvIHThuqduIHPhu5EgY+G7p2Egw7QgxJHhuqd1IHRpw6puICgxLDEpIHRyb25nIGLhuqNuZywgbmdoxKlhIGzDoCDhu6luZyB24bubaSBr4bq/dCBxdeG6oyBuw6B5IHRow6w6DQoNCiRwcm9iaXQoz4ApPS0zLjE1OSAgIC0wLjkzMiBHZW5kZXIgIC0wLjgwMiAgU2xlZXAuRHVyYXRpb24gICAgICAgICAgICAtMC4yNTUgICBTdHJlc3MuTGV2ZWwgKyAgICAgICAgICAgIDAuMTQ5SGVhcnQuUmF0ZSQNCg0KQ8OhYyBjaOG7iSBz4buRIMSRw6FuaCBnacOhIG3DtCBow6xuaA0KDQotIERldmlhbmNlOiAzODEuNTYgICANCg0KLSBBSUM6IDM5MS42DQoNCi0gQnJpZXJTY29yZTogMC4xNzA4DQoNCi0gQ29uZnVzaW9uIE1hdHJpeCBDw7MgxJHhu5kgxJHhurdjIGhp4buHdTogMCw2ODQ7IMSR4buZIG5o4bqheTogMCw3OTsgxJHhu5kgY2jDrW5oIHjDoWMgdG/DoG4gdGjhu4M6IDAsNTM1DQogDQogDQojIyMjIE3DtCBow6xuaCBjbG9nbG9nDQoNCg0KVOG6oWkgxJHDonkgdGEgdGnhur9uIGjDoG5oIGjhu5NpIHF1eSB24bubaSBow6BtIGNsb2dsb2ckY2xvZ2xvZyjPgCk9bG9nKOKIkmxvZygx4oiSz4ApKSQNCg0KKipNw7QgaMOsbmggaOG7k2kgcXV5KioNCg0KDQpgYGB7cn0NCg0KDQpmdDIgPC0gZ2xtKGZhY3RvcihTbGVlcCkgfiBmYWN0b3IoR2VuZGVyKSsgU2xlZXAuRHVyYXRpb24gK1N0cmVzcy5MZXZlbCArSGVhcnQuUmF0ZSwgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdjbG9nbG9nJyksIGRhdGEgPSBkICkNCmZ0Mg0KYGBgDQoNCioqS2nhu4NtIMSR4buLbmggc+G7sSBwaMO5IGjhu6NwIGPhu6dhIG3DtCBow6xuaCoqDQoNCkdp4bqjIHRodXnhur90IEgwOiBNw7QgaMOsbmggcGjDuSBo4bujcC4gDQpUacOqdSBjaHXhuqluIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBIMCBj4bunYSBjw6FjIHRo4buRbmcga8OqIG7DoHk6IHBfdmF1bGUgPCA1JQ0KDQpgYGB7cn0NCnBjaGlzcShkZXZpYW5jZShmdDIpLCBkZiA9IGRmLnJlc2lkdWFsKGZ0MiksIGxvd2VyLnRhaWwgPSBGKQ0KYGBgDQoNClThu6sgYuG6o25nIGvhur90IHF14bqjIHRyw6puIHRhIGPDsyBwX3ZhdWxlPSAwLDE3ODMgPiAwLDA1IHRhIGNo4bqlcCBuaOG6rW4gDQpIMC4gVuG6rXkgduG7m2kgbeG7qWMgw70gbmdoxKlhIDUlLCBtw7QgaMOsbmggcGjDuSBo4bujcA0KDQoqKsSQw6FuaCBnacOhIG3DtCBow6xuaCoqDQoNCmBgYHtyfQ0Kc3VtbWFyeShmdDIpDQpCcmllclNjb3JlKGZ0MikNCmNvbmZ1c2lvbk1hdHJpeCh0YWJsZShwcmVkaWN0KGZ0MiwgdHlwZT0ncmVzcG9uc2UnKSA+PSAwLjUgLGZ0MiRkYXRhJFNsZWVwID09ICd5ZXMnKSkNCmBgYA0KDQpL4bq/dCBxdeG6oyDGsOG7m2MgbMaw4bujbmcgbcO0IGjDrG5oIHRow6wgUiBt4bq3YyDEkeG7i25oIHPhur0gxrDhu5tjIGzGsOG7o25nIGNobyB04bqnbiBz4buRIGPhu6dhIMO0IMSR4bqndSB0acOqbiAoMSwxKSB0cm9uZyBi4bqjbmcsIG5naMSpYSBsw6Ag4bupbmcgduG7m2kga+G6v3QgcXXhuqMgbsOgeSB0aMOsOg0KDQokY2xvZ2xvZyjPgCk9LTIuMjc3ICAgICAgICAgICAgICAtMS4wMTEgR2VuZGVyICAgICAgICAgICAgIC0wLjgyNyBTbGVlcC5EdXJhdGlvbiAgICAgICAgICAgICAtMC4yMTEgU3RyZXNzLkxldmVsICAgICAgICsgICAgICAgMC4xMjkgSGVhcnQuUmF0ZSQNCg0KQ8OhYyBjaOG7iSBz4buRIMSRw6FuaCBnacOhIG3DtCBow6xuaA0KDQotIERldmlhbmNlOiAzOTMuOTIgIA0KDQotIEFJQzogNDAzLjkNCg0KLSBCcmllclNjb3JlOiAwLjE3NQ0KDQogLUNvbmZ1c2lvbiBNYXRyaXggQ8OzIMSR4buZIMSR4bq3YyBoaeG7h3U6IDAsNjg0OyDEkeG7mSBuaOG6oXk6IDAsNzk5OyDEkeG7mSBjaMOtbmggeMOhYyB0b8OgbiB0aOG7gzogMCw1MjMNCg0KIyMjIENo4buNbiBwaMO5IGjhu6NwIGPhu6dhIGPDoWMgbcO0IGjDrG5oIA0KDQoNCkPDoWMgcGjDom4gdMOtY2ggZOG7ryBsaeG7h3Ugbmjhu4sgcGjDom4gdGhlbyAzIGxv4bqhaSBow6BtIGxpw6puIGvhur90IGzDoCBsb2dpdCwgcHJvYml0LCBjbG9nbG9nIHRhIGPDsyBjw6FjIGNo4buJIHPhu5EgxJHDoW5oIGdpw6EgbmjGsCBzYXU6DQoNCnwgICAgICAgICAgICAgfCBsb2dpdCAgIHwgcHJvYml0ICB8IGNsb2dsb2cgfA0KfCAtLS0tLS0tLS0tLSB8IC0tLS0tLS0gfCAtLS0tLS0tIHwgLS0tLS0tLSB8DQp8IEFJQyAgICAgICAgIHwgMzkxLjkgICB8IDM5MS42ICAgfCA0MDMuOSAgIHwNCnwgZGV2aWFuY2UgICAgfCAzODEuNTYgIHwgMzgxLjU2ICB8IDM5My45MiAgfCANCnwgQnJpZXIgU2NvcmUgfCAwLjE3MSAgIHwgMC4xNzA4ICB8IDAuMTc1ICAgfCANCnwgxJDhu5kgxJHhurdjIGhp4buHdSB8IDAsNjg0ICAgfCAwLDY4NCAgIHwgMCw2ODQgICB8DQp8IMSQ4buZIG5o4bqheSAgICAgfCAwLDc5ICAgIHwgMCw3OSAgICB8IDAsNzk5ICAgfA0KfCDEkOG7mSBjaMOtbmggeMOhYyB0b8OgbiB0aOG7gyB8IDAsNTM1ICAgfCAwLDUzNSAgIHwgMCw1MjMgICB8DQoNCk5o4bqtbiB4w6l0OktoaSBuaMOsbiB2w6BvIGPDoWMgZ8OhaSB0cuG7iyDEkXXhu41jIHRo4buRbmcga8OqIOG7nyBi4bqjbmcgdGEgbmjDom4gdGjhuqV5IGjDoG0gcHJvYml0IGzDoCBow6BtIGxpw6puIGvhur90IGzDoCB04buRdCBuaOG6pXQgdsOsIGPDsyBjaOG7iSBz4buRIEFJQyB2w6AgQnJpZXIgU2NvcmUgbmjhu48gbmjhuqV0IHRyb25nIGJhIG3DtCBow6xuaCDEkcOjIHRo4buRbmcga8OqLg0KDQojIyMgxq/hu5tjIGzGsOG7o25nIG3DtCBow6xuaA0KDQpUYSBjw7MgbcO0IGjDrG5oIFByb2JpdCA6DQoNCiRwcm9iaXQoz4ApPS0zLjE1OSAgIC0wLjkzMiBHZW5kZXIgIC0wLjgwMiAgU2xlZXAuRHVyYXRpb24gLTAuMjU1ICAgU3RyZXNzLkxldmVsICsgMC4xNDlIZWFydC5SYXRlICQNCg0KY2hvIHRo4bqleSBuZ3V5IGPGoSBtw6AgbmfGsOG7nWkgdGhhbSBnaWEga2jhuqNvIHPDoXQgY8OzIHRyaeG7h3UgY2jhu6luZyBt4bqldCBuZ+G7pyB0aGVvIHThu6tuZyBiaeG6v24sIHRoZW8gxJHDszoNCg0KYGBge3J9DQpmdDEkY29lZmZpY2llbnRzDQpgYGANCg0KWMOhYyBzdeG6pXQgY8OzIGPDoWMgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIGPhu6dhIG3hu5l0IG5nxrDhu51pIGdp4bubaSB0w61uaCBu4buvIChGZW1hbGUpIMaw4bubYyDEkW/DoW4gbMOgOg0KDQokXHBpKDEseF8yLHhfMyx4XzQpID0gLTMuMTU5IC0wLjgwMiB4XzIgLTAuMjU1eF8zKzAuMTQ5IHhfNCQNCg0KWMOhYyBzdeG6pXQgY8OzIGPDoWMgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIGPhu6dhIG3hu5l0IG5nxrDhu51pIGdp4bubaSB0w61uaCBuYW0gKE1hbGUpIMaw4bubYyDEkW/DoW4gbMOgOg0KDQokXHBpKDAseF8yLHhfMyx4XzQpID0gLTQuMDkxIC0wLjgwMiAgeF8yICAtMC4yNTQ3IHhfMyAgKyAgIDAuMTQ5MSB4XzQkDQoNCg0KIyMgTcO0IGjDrG5oIFBvaXNzb24NCg0KIyMjIEtp4buDbSDEkeG7i25oIGTDo3kgc+G7kSBjw7MgcGjDom4gcGjhu5FpIFBvaXNzb24NCg0KS2nhu4NtIMSR4buLbmggbeG7mXQgZMOjeSBz4buRIGPDsyBwaMOibiBwaOG7kWkgUG9pc3NvbiBW4bubaSBHaeG6oyB0aHV54bq/dCBIMDpYDQpgYGB7cn0NCnggPC0gbGVuZ3RoKGQkUXVhbGl0eS5vZi5TbGVlcCkNCg0KcG9pc3Nvbi50ZXN0KHgscj04LjUsYWx0PSJncmVhdGVyIikNCmBgYA0KDQpUYSBjw7MgJHAtdmFsdWUgPDIqMTBeey02fTwwLjA1JCwgY2jhu6luZyBtw6xuaCBiaeG6v24gUXVhbGl0eS5vZi5TbGVlcCBsw6AgZOG7r3UgbGnhu4d1IFBvaXNzb24NCg0KS8O9IGhp4buHdSAqdSh4KSogbMOgIGdpw6EgdHLhu4sga+G7syB24buNbmcgY2hvIGJp4bq/biBuZ+G6q3Ugbmhpw6puIFBvaXNzb24gWSDhu6luZyB24bubaSBt4bupYyB4IGPhu6dhIGJp4bq/biBYIHThu6ljIGzDoDogKnUoeCk9RShZfFg9eCkqDQoNCsSQ4buDIGjhu5NpIHF1eSBtw7QgaMOsbmg6ICRsb2dbdSh4KV0gPVxhbHBoYStcYmV0YSp4JA0KDQojIyMgxq/hu5tjIGzGsOG7o25nIHbDoCBk4buxIGLDoW8NCg0Kxq/hu5tjIGzGsOG7o25nIGjDoG0gaOG7k2kgcXV5IGNobyBk4buvIGxp4buHdSBQb2lzc29uIGzDoCB0w6xtIGdpw6EgdHLhu4sga+G7syB24buNbmcgY2hvIGJp4bq/biBuZ+G6q3Ugbmhpw6puIFBvaXNzb24gbMOgIFF1YWxpdHkub2YuU2xlZXAgduG7m2kgY8OhYyBiaeG6v24gY8OybiBs4bqhaQ0KDQpgYGB7cn0NCg0KZml0IDwtIGdsbShkYXRhID0gZCwgZm9ybXVsYSA9UXVhbGl0eS5vZi5TbGVlcCAgfiBEYWlseS5TdGVwcysgU2xlZXAuRHVyYXRpb24gK1N0cmVzcy5MZXZlbCsgSGVhcnQuUmF0ZSwgZmFtaWx5ID0gcG9pc3NvbihsaW5rID0gJ2xvZycpKQ0KZml0DQpzdW1tYXJ5KGZpdCkNCmBgYA0KDQpL4bq/dCBxdeG6oyDGsOG7m2MgbMaw4bujbmcgbcO0IGjDrG5oIDoNCg0KICRsb2cozrzMgl97MTF9ICk9ICAxLjgyKzEuNTcqMTBeey01fURhaWx5LlN0ZXBzKzguMzcqMTBeey0yfVNsZWVwLkR1cmF0aW9uLTUuMTEqMTBeey0yfVN0cmVzcy5MZXZlbC0zLjgyKjEwXnstMn0gSGVhcnQuUmF0ZSQNCiANClRyxrDhu5tjIGtoaSB0aOG7sWMgaGnhu4duIHZp4buHYyDGsOG7m2MgbMaw4bujbmcgY2hvIHThuqduIHPhu5Ega+G7syB24buNbmcgY+G7p2EgY8OhYyDDtCwgc2F1IMSRw7MgdGjhu7FjIGhp4buHbiB2aeG7h2MgxrDhu5tjIGzGsOG7o25nIHThuqduIHPhu5Ega+G7syB24buNbmcgY2hvIGPDoWMgw7Q6DQoNCmBgYHtyfQ0KdW9jbHVvbmcgPC0gZml0dGVkKGZpdCkNCmggPC0gY2JpbmQoR2VuZGVyPWQkR2VuZGVyLFNsZWVwLkR1cmF0aW9uPWQkU2xlZXAuRHVyYXRpb24sU3RyZXNzLkxldmVsPWQkU3RyZXNzLkxldmVsLEhlYXJ0LlJhdGU9ZCRIZWFydC5SYXRlLHVvY2x1b25nKQ0KaGVhZChoKQ0KYGBgDQoNCiMgQ2jGsMahbmcgNjogS+G6v3QgcXXhuqMNCg0KVuG7m2kgY8OhYyBiaeG6v24gxJHhu5ljIGzhuq1wIMSRw6MgdGjhu7FjIGhp4buHbiB0aOG7kW5nIGvDqiBtw7QgdOG6oyB2w6AgaGFpIGJp4bq/biBwaOG7pSB0aHXhu5ljIMSRw6MgY2jhu41uLCB0w7RpIHRp4bq/biBow6BuaCBs4bqtcCB0aOG7kW5nIGvDqiBoYWkgYmnhur9uIGLEg25nIFRo4buRbmcga8OqIG3DtCB04bqjIHbDoCB0aOG7kW5nIGvDqiBzdXkgZGnhu4VuIGNobyBoYWkgYmnhur9uIHbDoCBtw7QgaMOsbmggaOG7k2kgcXV5IMSRYSBiaeG6v24gY2hvIGThu68gbGnhu4d1LCB0YSBjw7MgY8OhYyBow6BtIGjhu5NpIHF1eSBzYXU6DQoNCioqTcO0IGjDrG5oIGxvZ2lzdGljIGTDuW5nIGJp4bq/biBnaeG6oyBuaOG7iyBwaMOibioqIA0KDQokbG9nKFxmcmFje8+AfXsx4oiSz4B9KT0gLTYuMDUxNyswLjExMzF4XzEtMC4wNTc2Y18xLTEuNjgyNWNfMi0wLjU0NTFjXzMtIDE0LjU5OTUgY180KyAyLjQ1MTRjXzUgKzE4LjQ1NTdjXzYgKzMuODQyNWNfNysyLjI2NzUgICBjXzgrMS4zNzc4ICogY185KzIuNjMzMiAqICBjX3sxfSQNCg0KKipNw7QgaMOsbmggbG9naXN0aWMgY8OzIHRodeG7mWMgdMOtbmggdGjhu6kgdOG7sSoqDQoNCiRsb2coXGZyYWN7z4B9ezHiiJLPgH0pPS0zLjQ0NCAtMC4yMzNRdWFsaXR5Lm9mLlNsZWVwICsgMi4zMDIgIEJNSS5DYXRlZ29yeSQNCg0KKipNw7QgaMOsbmggbG9naXN0aWMgY8OzIHRodeG7mWMgdMOtbmggbeG7qWMgxJHhu5kgc28gc8OhbmgqKg0KDQokbG9nKFxmcmFje8+AfXsx4oiSz4B9KT0tNS4yOTg2LTAuMDUzOSBQaHlzaWNhbC5BY3Rpdml0eS5MZXZlbCArMC41MTU0IEJsb29kLlByZXNzdXJlJA0KDQoqKk3DtCBow6xuaCBQcm9iaXQgKioNCg0KJHByb2JpdCjPgCk9LTMuMTU5ICAgLTAuOTMyIEdlbmRlciAgLTAuODAyICBTbGVlcC5EdXJhdGlvbiAgICAgICAgICAgIC0wLjI1NSAgIFN0cmVzcy5MZXZlbCArICAgICAgICAgICAgMC4xNDlIZWFydC5SYXRlJA0KDQoqKk3DtCBow6xuaCBQb2lzc29uOioqDQoNCiRsb2cozrzMgl97MTF9ICk9ICAxLjgyKzEuNTcqMTBeey01fURhaWx5LlN0ZXBzKzguMzcqMTBeey0yfVNsZWVwLkR1cmF0aW9uLTUuMTEqMTBeey0yfVN0cmVzcy5MZXZlbC0zLjgyKjEwXnstMn0gSGVhcnQuUmF0ZSQNCg0KWMOhYyDEkeG7i25oIMSRxrDhu6NjIG5o4buvbmcgduG6pW4gxJHhu4Egc2F1Og0KDQotIEJp4bq/biDEkeG7i25oIHTDrW5oIGzDoCBodXnhur90IMOhcCB0xINuZyBk4bqnbiB0aGVvIHRo4buDIHRy4buNbmcgY+G7p2EgY8ahIHRo4buDIGNobyB0aOG6pXkgeMOhYyBjw7MgdHJp4buHdSBjaOG7qW5nIG3huqV0IG5n4bunIHTEg25nIA0KDQotIFRhIHRo4bqleSwgbmfGsOG7nWkgY8OzIG5o4buLcCB0aW0gxJHhuq1wIHThu6sgNzAgbmjhu4twL3Bow7p0IGtoaSBuZ+G7pyBjw7MgY8OhYyB0cmnhu4d0IGNo4bupbmcgbeG6pXQgbmfhu6cgY2FvIGjGoW4gbmfGsOG7nWkgY8OzIG5o4buLcCB0aW0gxJHhuq1wIDYwLTY5IG5o4buLcC9waMO6dCBraGkgbmfhu6cgcuG7kWkga2jDtG5nIGPDsyBjw6FjIHRyaeG7h3QgY2jhu6luZyBt4bqldCBuZ+G7py4gDQoNCi0gTmfGsOG7nWkgdGjhu6thIGPDom4gY8OzIGPDoWMgdHJp4buHdCBjaOG7qW5nIG3huqV0IG5n4bunIGfhuqVwIDgsNyBsw6JuIG5nxrDhu51pIGPDsyBjw6JuIG7hurduZyBiw6xuaCB0aMaw4budbmcgY8OzIGPDoWMgdHJp4buHdCBjaOG7qW5nIG3huqV0IG5n4bunLg0KDQotIFRyaeG7h3UgY2jhu6luZyBt4bqldCBuZ+G7pyB04buJIGzhu4cgbmdo4buLY2ggduG7m2kgxJFp4buDbSDEkcOhbmggZ2nDoSBnaeG6pWMgbmfhu6cgbmjGsG5nIHThu4kgbOG7hyB0aHXhuq1uIHbhu5tpIG3hu6ljIMSR4buZIGPEg24gdGjhurVuZyBj4bunYSBuaOG7r25nIG5nxrDhu51pIHRoYW0gZ2lhbiBraOG6o28gc8OhdC4gDQoNCi0gxJBhIHBo4bqnbiBjw6FjIHRyaeG7h3UgY2jhu6luZyBj4bunYSB2aeG7h2MgbeG6pXQgbmfhu6cgY+G7p2EgbmFtIGdp4bubaSwgbuG7ryBnaeG7m2kgY8OzIMSRaeG7g20ga2jDoWMgYmnhu4d0Lg0KDQotIFbhu5tpIHZp4buHYyBuZ2jhu4EgbmdoaeG7h3AgdGhlbyBz4buxIGRpIGNodXnhu4NuIMOtdCBoYXkgbmhp4buBdSB0cm9uZyBxdcOhICB0csOsbmggbMOgbSB2aeG7h2MuIEvhur90IHF14bqjIG5naOG7gSBj4bqnbiBkaSBjaHV54buDbiBuaGnhu4F1IGPDsyBraOG6oyBuxINuZyBt4bqldCBuZ+G7pyBuaGnhu4F1IGjGoW4gbmfGsOG7nWkgZGkgY2h1eeG7g24gw610Lg0KDQotIENobyB0aOG6pXksIHRvw6BuIGLhu5kgbmfGsOG7nWkgY8OzIG3hu6ljIMSR4buZIGPEg25nIHRo4bqzbmcgdGjhuqVwIMSR4buBdSBjw7MgxJFpw6ptIMSRw6FuaCBnacOhIGNhby4gQ8OybiBs4bqhaSBsw6AgcGjhuqduIGzhu5tuIG5nxrDhu51pIGLhu4sgY8SDbmcgdGjhurNuZyBuaGnhu4F1IGzhuqFpIGPDsyDEkWnhu4NtIHbhu4EgZ2nhuqVjIG5n4bunIHRo4bqlcC4NCg0KLSBOZ8aw4budaSBuZ+G7pyDEkeG7pyB0aOG7nWkgZ2lhbiB0cm9uZyBt4buZdCBuZ8OgeSDEkeG7gXUgY8OzIMSRacOqbSDEkcOhbmggZ2nDoSBjYW8uIEPDsm4gbOG6oWkgbMOgIHBo4bqnbiBs4bubbiBuZ8aw4budaSBuZ+G7pyBraMO0bmcgxJHhu6cgbOG6oWkgY8OzIMSRaeG7g20gduG7gSBnaeG6pWMgbmfhu6cgdGjhuqVwLg0KDQoNCg0K