LỜI CẢM ƠN

Em xin gửi lời cảm ơn chân thành và sự tri ân sâu sắc tới thầy Trần Mạnh Tường. Sự ủng hộ, hướng dẫn và tạo điều kiện của các thầy đã giúp em hoàn thành tốt bài tiểu luận này, thầy đã dành nhiều thời gian quý báu để hướng dẫn, giải đáp mọi thắc mắc và chỉ bảo tận tình cho em trong suốt quá trình thực hiện bài tiểu luận. Sự nghiêm khắc và nhiệt tình của thầy đã giúp em không chỉ hoàn thiện bài tiểu luận mà còn tích lũy được nhiều kiến thức và kỹ năng quý báu cho tương lai. Em xin chân thành cảm ơn.


LỜI CAM ĐOAN

Em tên Phan Nguyễn Quỳnh Hương, sinh viên trường Đại học Tài chính – Marketing, chuyên ngành Tài chính định lượng, lớp 22DTL01. Em xin cam đoan bài tiểu luận “Phân tich các yếu tố ảnh hưởng đến hành vi rời bỏ dịch vụ của khách hàng viễn thông” là bài báo em thực hiện dưới sự chỉ dẫn của ThS.Trần Mạnh Tường Các số liệu, tài liệu và nội dung có nguồn gốc rõ ràng được em trích dẫn trong phần tài liệu tham khảo và phụ lục. Em xin cam đoan và chịu trách nhiệm về mọi thông tin trong bài tiểu luận môn Phân tích dữ liệu định tính.


CHƯƠNG 1: PHẦN MỞ ĐẦU

1.1 Lý do chọn đề tài

Trong những năm gần đây, ngành viễn thông chứng kiến sự cạnh tranh ngày càng khốc liệt giữa các nhà cung cấp dịch vụ, không chỉ ở khía cạnh giá cả mà còn về chất lượng dịch vụ, độ phủ sóng, các gói khuyến mãi và chính sách chăm sóc khách hàng. Trong bối cảnh đó, việc giữ chân khách hàng cũ trở thành một yếu tố then chốt quyết định sự phát triển bền vững và lợi thế cạnh tranh của doanh nghiệp. Các công ty không chỉ cần mở rộng thị phần mà còn phải đối mặt với thách thức lớn hơn là giảm thiểu tỷ lệ rời bỏ dịch vụ một chỉ số quan trọng phản ánh mức độ hài lòng và trung thành của khách hàng.

Theo nghiên cứu của Harvard Business Review, chi phí để thu hút một khách hàng mới có thể cao gấp 5 đến 25 lần so với chi phí giữ chân một khách hàng hiện tại. Do đó, thay vì tập trung hoàn toàn vào việc mở rộng cơ sở khách hàng mới, nhiều doanh nghiệp đã và đang chuyển hướng sang đầu tư vào các giải pháp phân tích hành vi khách hàng, nhằm phát hiện sớm các tín hiệu cảnh báo về khả năng rời bỏ dịch vụ. Việc dự đoán chính xác khách hàng có nguy cơ rời bỏ cho phép doanh nghiệp chủ động can thiệp kịp thời thông qua các chương trình ưu đãi, tư vấn cá nhân hóa hoặc cải thiện chất lượng dịch vụ.

Bên cạnh ý nghĩa thực tiễn trong hoạt động quản trị và chăm sóc khách hàng, việc nghiên cứu về hành vi rời bỏ còn mở ra cơ hội ứng dụng các mô hình phân tích định lượng, đặc biệt là các thuật toán học máy trong lĩnh vực khoa học dữ liệu. Các mô hình này cho phép xử lý khối lượng lớn dữ liệu, phát hiện mối quan hệ tiềm ẩn giữa các biến và tối ưu hóa quá trình ra quyết định. Từ đó, doanh nghiệp có thể nâng cao hiệu quả hoạt động kinh doanh, đồng thời mang lại giá trị gia tăng bền vững.

Chính vì những lý do trên, việc lựa chọn đề tài “Phân tích và dự đoán khả năng rời bỏ khách hàng trong ngành viễn thông” không chỉ phản ánh tính cấp thiết của vấn đề trong thực tiễn mà còn thể hiện xu hướng nghiên cứu hiện đại, kết hợp giữa quản trị khách hàng và khoa học dữ liệu. Thông qua đề tài này, người nghiên cứu có cơ hội tiếp cận các phương pháp phân tích định lượng tiên tiến, đồng thời đề xuất các giải pháp có cơ sở nhằm nâng cao chất lượng dịch vụ và giảm thiểu tỷ lệ rời bỏ khách hàng cho doanh nghiệp viễn thông.

1.2 Mục tiêu nghiên cứu và câu hỏi nghiên cứu

Mục tiêu cụ thể của đề tài “Phân tích các yếu tố ảnh hưởng đến hành vi rời bỏ dịch vụ của khách hàng viễn thông” là xác định những yếu tố quan trọng tác động đến khả năng khách hàng quyết định rời bỏ dịch vụ, đồng thời xây dựng mô hình dự báo xác suất rời bỏ để hỗ trợ doanh nghiệp trong việc nhận diện nhóm khách hàng có nguy cơ cao. Thông qua việc sử dụng các mô hình hồi quy nhị phân như logit, probit và cloglog. Kết quả nghiên cứu không chỉ giúp đo lường mức độ ảnh hưởng của từng yếu tố mà còn cung cấp cơ sở để doanh nghiệp đưa ra các giải pháp giữ chân khách hàng hiệu quả hơn.

1.3 Đối tượng và phạm vi nghiên cứu

Đối tượng nghiên cứu của đề tài là hành vi rời bỏ dịch vụ (churn) của khách hàng trong lĩnh vực viễn thông.

Phạm vi nghiên cứu tập trung vào việc phân tích dữ liệu khách hàng của một doanh nghiệp viễn thông, bao gồm các thông tin như các loại hợp đồng,các loại hình dịch vụ Internet, khách hàng có người phụ thuộc, độ tuổi.

1.4 Phương pháp nghiên cứu

Nghiên cứu sử dụng phương pháp phân tích dữ liệu định tính kết hợp định lượng. Trước hết, phân tích định tính được áp dụng để tổng hợp cơ sở lý thuyết và các nghiên cứu liên quan nhằm xây dựng mô hình phân tích. Tiếp theo, nghiên cứu sử dụng thống kê mô tả để trình bày đặc điểm cơ bản của khách hàng và thống kê suy diễn để kiểm định mối quan hệ giữa các biến. Cuối cùng, ba mô hình hồi quy nhị phân gồm logit, probit và cloglog được áp dụng nhằm ước lượng xác suất rời bỏ dịch vụ của khách hàng, từ đó đánh giá mức độ ảnh hưởng của các yếu tố liên quan đến hành vi này.

1.5 Kết cấu bài nghiên cứu

Chương 1: Phần mở đầu Chương này giới thiệu tổng quan nghiên cứu, bao gồm: đặt vấn đề nghiên cứu, mục tiêu nghiên cứu, đối tượng nghiên cứu, phạm vi và phương pháp nghiên cứu và kết cấu bài nghiên cứu.

Chương 2: Cơ sở lý thuyết Ở chương này tổng quan về hành vi rời bỏ dịch vụ, các yếu tố tác động đến hành vi rời bỏ dịch vụ, các lý thuyết về mô hình hồi quy nhị phần và tổng quan nghiên cứu.

Chương 3: Kết quả nghiên cứu và kết luận Chương này thực hiện phân tích đơn biến đến hành vi rời bỏ dịch vụ viễn thông của khách hàng. Sau đó phân tích đa biến đến hành vi rời bỏ dịch vụ viễn thông của khách hàng rồi sau đó đưa kết luận về nghiên cứu.


CHƯƠNG 2: CƠ SỞ LÝ THUYẾT VÀ PHƯƠNG PHÁP NGHIÊN CỨU

2.1 Tổng quan về hành vi rời bỏ dịch vụ

Rời bỏ dịch vụ là tình trạng khách hàng ngừng sử dụng sản phẩm hoặc dịch vụ một doanh nghiệp hoặc chuyển sang nhà cung khác vì nhiều ký do khác nhau, chẳng hạn như chất lượng dịch vụ không đáp ứng kỳ vọng, giá cả không cạnh tranh hoặc có sự xuất hiện của các ưu đãi hấp dẫn từ đối thủ. Việc phân tích hành vì rời bỏ dịch vụ có ý nghĩa đặc biệt quan trong trong bối cảnh thị trường cạnh tranh gay gắt như hiện nya, khi chi phí để thu hút một khách hàng mới thường cao hơn nhiều so với chi phí duy trì khách hàng hiện tại. Điều này khiến cho doanh nghiệp, đặc bết trong ngành viễn thông luôn cần có chiến lược quản trị và dự báo khách hàng rời bỏ dịch vụ hiểu quả nhằm giảm thiểu tỷ lệ khách hàng rời bỏ.

Sự rời bỏ của khách hàng được chia thành hai dạng. Thứ nhất là dạng chủ động, khi khách hàng tự quyết định chấm dứt hợp đồng dịch vụ do không còn nhu cầu hoặc cảm thấy không hài lòng. Thứ hai là thụ động, xảy ra khi khách hàng không chủ động gia hạn hợp động hoặc dịch vụ một cách tự nhiên. Trong ngành viễn thông Việt Nam, tình trạng churn được ghi nhận khá phổ biến, một phần do sự cạnh tranh mạnh mẽ về giá cước, các chương trình khuyến mãi liên tục và sự khác biệt về chất lượng dịch vụ giữa các nhà mạng. Theo một số báo cáo ngành, tỷ lệ khách hàng rời bỏ dịch vụ viễn thông ở Việt Nam vẫn duy trì ở mức cao, đặc biệt trong phân khúc khách hàng sử dụng dịch vụ trả trước hoặc gói cước ngắn hạn.

Mục tiêu quản trị khách hàng rời bỏ dịch vụ không chỉ dừng lại ở việc nhận diện khách hàng có nguy cơ rời bỏ mà còn bao gồm việc xây dựng các mô hình dự báo nhằm đưa ra biện pháp giữ chân hiệu quả. Việc áp dụng các mô hình phân tích và dự báo churn giúp doanh nghiệp tối ưu hóa nguồn lực, tập trung vào nhóm khách hàng tiềm năng và xây dựng chính sách chăm sóc phù hợp, qua đó nâng cao sự hài lòng và lòng trung thành của khách hàng.

2.2 Các yếu tố tác động đến hành vi rời bỏ dịch vụ

Trong nghiên cứu này, bốn yếu tố được lựa chọn gồm: loại hợp đồng (Contract), tình trạng có người phụ thuộc (Dependents), độ tuổi khách hàng (Senior Citizen), và loại dịch vụ Internet (Internet Service). Các yếu tố này không chỉ đại diện cho đặc điểm nhân khẩu học và hành vi sử dụng dịch vụ của khách hàng, mà còn phản ánh những yếu tố chiến lược mà doanh nghiệp viễn thông có thể tác động để giảm tỷ lệ rời bỏ dịch vụ.

Thứ nhất, loại hợp đồng là yếu tố mang tính ràng buộc mạnh mẽ nhất đối với hành vi duy trì dịch vụ. Những khách hàng ký hợp đồng dài hạn, chẳng hạn hợp đồng 12 hoặc 24 tháng, thường ít rời bỏ dịch vụ do phải chịu phí phạt khi hủy ngang và được hưởng các ưu đãi đi kèm như giảm giá hoặc tặng thêm dịch vụ. Điều này tạo nên tâm lý gắn bó lâu dài. Ngược lại, khách hàng sử dụng hợp đồng trả trước hoặc hợp đồng tháng thường linh hoạt trong việc chuyển đổi nhà mạng khác khi phát hiện dịch vụ không đáp ứng nhu cầu hoặc khi đối thủ tung ra chương trình khuyến mãi hấp dẫn hơn. Do vậy, doanh nghiệp viễn thông thường tập trung vào việc thiết kế các gói hợp đồng dài hạn kết hợp với chính sách chăm sóc đặc biệt để giảm tỷ lệ churn.

Thứ hai, tình trạng có người phụ thuộc (Dependents) thể hiện trách nhiệm gia đình và nhu cầu sử dụng dịch vụ ổn định. Những khách hàng có người phụ thuộc (ví dụ: con nhỏ, người già, người thân cần chăm sóc) thường ưu tiên một dịch vụ viễn thông ổn định để phục vụ học tập trực tuyến, giải trí gia đình hoặc liên lạc. Họ có xu hướng ít rời bỏ dịch vụ hơn vì việc thay đổi nhà cung cấp có thể gây gián đoạn và ảnh hưởng đến các thành viên trong gia đình. Ngược lại, khách hàng độc thân hoặc không có người phụ thuộc có xu hướng linh hoạt hơn trong việc thay đổi dịch vụ để tối ưu chi phí, dẫn đến khả năng rời bỏ cao hơn. Điều này cho thấy, sự hiện diện của người phụ thuộc là một yếu tố làm tăng mức độ trung thành với dịch vụ viễn thông.

Thứ ba, độ tuổi khách hàng (Senior Citizen) là yếu tố nhân khẩu học quan trọng thể hiện sự khác biệt trong hành vi tiêu dùng. Khách hàng cao tuổi thường ít có nhu cầu thử nghiệm các gói dịch vụ mới và ưu tiên sự ổn định, nên tỷ lệ rời bỏ dịch vụ thấp hơn so với nhóm khách hàng trẻ tuổi. Họ cũng ít nhạy cảm hơn với các khuyến mãi giá rẻ và coi trọng chất lượng phục vụ, đặc biệt là sự hỗ trợ trực tiếp từ nhân viên chăm sóc khách hàng. Trong khi đó, nhóm khách hàng trẻ, đặc biệt là thế hệ Z hoặc Millennials, thường năng động, am hiểu công nghệ và sẵn sàng chuyển đổi dịch vụ nếu tìm thấy gói cước có tốc độ cao, tiện ích phong phú hoặc chi phí hợp lý hơn.

Cuối cùng, loại dịch vụ Internet (Internet Service) là yếu tố kỹ thuật then chốt ảnh hưởng đến quyết định duy trì dịch vụ. Khách hàng sử dụng công nghệ Fiber optic thường hài lòng hơn nhờ tốc độ truy cập cao và độ ổn định tốt, từ đó giảm khả năng rời bỏ. Ngược lại, những khách hàng vẫn sử dụng DSL hoặc các dịch vụ cũ dễ chuyển đổi sang nhà cung cấp khác khi nhận thấy dịch vụ không đáp ứng nhu cầu. Bên cạnh đó, nhóm khách hàng không đăng ký Internet từ nhà mạng (No Internet) có mức độ gắn kết thấp và dễ rời bỏ hơn vì họ không phụ thuộc vào dịch vụ chính của doanh nghiệp. Đối với các công ty viễn thông, việc nâng cấp hạ tầng mạng và cung cấp các gói Fiber optic giá hợp lý là giải pháp quan trọng để giữ chân khách hàng.

Việc phân tích bốn yếu tố trên giúp doanh nghiệp hiểu rõ hơn hành vi khách hàng, từ đó tối ưu chiến lược tiếp thị, thiết kế gói dịch vụ hợp lý và triển khai các chương trình chăm sóc nhằm giảm tỷ lệ rời bỏ. Đây cũng là nền tảng quan trọng để xây dựng các mô hình hồi quy nhị phân như logit, probit hoặc cloglog nhằm dự báo xác suất churn một cách chính xác.

2.3 Relative Risk và Odds Ratio

Trong phân tích dữ liệu định tính và định lượng, đặc biệt trong nghiên cứu hành vi khách hàng, việc đo lường sự khác biệt về khả năng xảy ra một sự kiện giữa các nhóm đối tượng là vô cùng quan trọng. Hai chỉ số phổ biến thường được sử dụng cho mục đích này là Relative Risk (RR) và Odds Ratio (OR). Các chỉ số này không chỉ giúp định lượng mức độ tác động của một đặc điểm đến hành vi, mà còn hỗ trợ diễn giải rõ ràng kết quả từ các mô hình thống kê như hồi quy logistic.

2.3.1 Relative Risk (RR)

Relative Risk (RR) hay còn gọi là nguy cơ tương đối so sánh xác suất xảy ra hành vi giữa hai nhóm:

\[ RR = \frac{P_1}{P_0} \]

Trong đó:

  • \(P_1\): Xác suất khách hàng có đặc điểm thực hiện hành vi

  • \(P_0\): Xác suất khách hàng không có đặc điểm thực hiện hành vi

Diễn giải:

  • RR = 1: Không có sự khác biệt giữa hai nhóm

  • RR > 1: Nhóm có đặc điểm có khả năng xảy ra hành vi cao hơn

  • RR < 1: Nhóm có đặc điểm có khả năng xảy ra hành vi thấp hơn

2.3.2 Odds Ratio (OR)

Odds Ratio (OR) đo lường tỷ lệ odds (khả năng xảy ra so với không xảy ra) giữa hai nhóm:

\[ OR = \frac{P_1 / (1 - P_1)}{P_0 / (1 - P_0)} = \frac{P_1 (1 - P_0)}{P_0 (1 - P_1)} \]

Diễn giải:

  • OR = 1: Không có sự khác biệt giữa hai nhóm

  • OR > 1: Nhóm có đặc điểm có odds vay cao hơn

  • OR < 1: Nhóm có đặc điểm có odds vay thấp hơn

2.3 Cơ sở lý thuyết về mô hình hồi quy nhị phân

2.3.1 Mô hình logit

Mô hình Logit là một trường hợp đặc biệt của mô hình hồi quy tổng quát (GLM), được sử dụng khi biến phụ thuộc \(Y\) là biến nhị phân, chỉ nhận giá trị 0 hoặc 1. Mô hình này mô tả xác suất xảy ra của một sự kiện thông qua hàm logistic, giúp đảm bảo giá trị dự đoán luôn nằm trong khoảng \([0, 1]\).

Ba thành phần của mô hình Logit

  • System component (Thành phần hệ thống):

    Mối quan hệ tuyến tính giữa các biến độc lập và log-odds của xác suất xảy ra sự kiện: \[ \eta = \beta_0 + \beta_1 X_1 + \cdots + \beta_k X_k, \] trong đó \(\eta = \ln\left(\frac{p}{1-p}\right)\)\(p = P(Y=1|X)\).

  • Link function (Hàm liên kết):

    Hàm logit liên kết xác suất với hàm tuyến tính: \[ g(p) = \ln\left(\frac{p}{1-p}\right) = \eta. \] Ngược lại, xác suất được tính bằng: \[ p = \frac{e^{\eta}}{1 + e^{\eta}} = \frac{e^{\beta_0 + \beta_1 X_1 + \cdots + \beta_k X_k}}{1 + e^{\beta_0 + \beta_1 X_1 + \cdots + \beta_k X_k}}. \]

  • Random component (Thành phần ngẫu nhiên):

    Biến phụ thuộc \(Y\) tuân theo phân phối nhị thức: \[ Y \sim \text{Binomial}(1, p) \] với \(E(Y) = p\)\(Var(Y) = p(1-p)\).

Ước lượng tham số

Các hệ số \(\beta_j\) được ước lượng bằng phương pháp tối đa hóa hàm hợp lý (Maximum Likelihood Estimation – MLE). Hệ số \(\beta_j\) cho biết log-odds của sự kiện \(Y=1\) thay đổi bao nhiêu đơn vị khi \(X_j\) tăng một đơn vị (giữ các biến khác cố định). Tỉ số \(e^{\beta_j}\) (odds ratio) cho biết khả năng xảy ra sự kiện tăng hoặc giảm bao nhiêu lần khi \(X_j\) tăng 1 đơn vị.

Ưu điểm

Mô hình Logit đảm bảo giá trị xác suất luôn nằm trong \([0, 1]\), dễ dàng diễn giải qua odds ratio và đặc biệt phù hợp với dữ liệu phân loại nhị phân.

2.3.2 Mô hình probit

Mô hình Probit là một dạng hồi quy nhị phân thuộc nhóm mô hình hồi quy tổng quát (GLM), được sử dụng khi biến phụ thuộc \(Y\) chỉ nhận giá trị 0 hoặc 1. Khác với logit, mô hình Probit sử dụng hàm liên kết dựa trên hàm phân phối tích lũy chuẩn chuẩn hóa (Standard Normal CDF) để mô tả xác suất xảy ra sự kiện.

Ba thành phần của mô hình Probit

  • System component (Thành phần hệ thống):

    Mối quan hệ giữa các biến độc lập và biến phụ thuộc được thể hiện qua hàm tuyến tính: \[ \eta = \beta_0 + \beta_1 X_1 + \cdots + \beta_k X_k \]

    trong đó \(\eta\) là biến tiềm ẩn liên quan đến xác suất \(p = P(Y=1|X)\).

  • Link function (Hàm liên kết):

    Trong Probit, hàm liên kết \(g(p)\) được định nghĩa là hàm nghịch đảo của hàm phân phối tích lũy chuẩn chuẩn hóa \(\Phi(\cdot)\): \[ g(p) = \Phi^{-1}(p) = \eta. \]

    Xác suất xảy ra sự kiện được tính như sau: \[ p = P(Y=1|X) = \Phi(\beta_0 + \beta_1 X_1 + \cdots + \beta_k X_k), \] với: \[ \Phi(z) = \int_{-\infty}^z \frac{1}{\sqrt{2\pi}} e^{-\frac{t^2}{2}} dt. \]

  • Random component (Thành phần ngẫu nhiên):

    Biến phụ thuộc \(Y\) tuân theo phân phối nhị thức: \[ Y \sim \text{Binomial}(1, p) \] với kỳ vọng \(E(Y) = p\) và phương sai \(Var(Y) = p(1-p)\).

Ước lượng và ý nghĩa

Các hệ số \(\beta_j\) được ước lượng bằng Maximum Likelihood Estimation (MLE). Tương tự như logit, \(\beta_j\) biểu thị tác động của \(X_j\) đến biến tiềm ẩn \(\eta\), tuy nhiên không có cách diễn giải trực tiếp theo odds ratio. Thay vào đó, ta có thể diễn giải qua việc tính xác suất bằng \(\Phi(\eta)\).

So sánh với Logit

Khác với logit (dùng hàm logistic), mô hình Probit sử dụng phân phối chuẩn. Hai mô hình thường cho kết quả khá tương đồng, nhưng Probit có đuôi phân phối mỏng hơn, phù hợp với dữ liệu có phân phối gần chuẩn.

2.3.3 Mô hình cloglog

Mô hình Cloglog (Complementary log-log) là một dạng của mô hình hồi quy tổng quát (GLM) được sử dụng khi biến phụ thuộc \(Y\) là nhị phân (0 hoặc 1). Khác với logit và probit, mô hình Cloglog sử dụng hàm liên kết không đối xứng, phù hợp với dữ liệu có xác suất xảy ra sự kiện rất thấp hoặc phân phối không đối xứng.

System component (Thành phần hệ thống)

Mối quan hệ giữa các biến giải thích và biến phụ thuộc được thể hiện qua hàm tuyến tính:

\[ \eta = \beta_0 + \beta_1 X_1 + \cdots + \beta_k X_k \]

Link function (Hàm liên kết)

Hàm liên kết trong mô hình Cloglog được định nghĩa như sau: \[ g(p) = \ln[-\ln(1 - p)] = \eta \] Ngược lại, xác suất xảy ra sự kiện \(Y=1\) được tính:

\[ p = 1 - e^{-e^{\eta}} = 1 - e^{-e^{\beta_0 + \beta_1 X_1 + \cdots + \beta_k X_k}} \]

Random component (Thành phần ngẫu nhiên)

Biến phụ thuộc \(Y\) tuân theo phân phối nhị thức: \[ Y \sim \text{Binomial}(1, p) \] với kỳ vọng \(E(Y) = p\) và phương sai \(Var(Y) = p(1-p)\).

2.4 Phương pháp ước lượng: Maximum Likelihood Estimation (MLE)

Các mô hình nhị phân như logit, probit và cloglog đều được ước lượng bằng phương pháp ước lượng hợp lý tối đa (MLE). Đây là phương pháp tìm giá trị tham số \(\beta\) sao cho xác suất tạo ra dữ liệu quan sát là cao nhất. Trong GLMs, hàm hợp lý được xây dựng dựa trên phân phối nhị thức và tối ưu hóa bằng các thuật toán như Newton-Raphson.

Trong các mô hình hồi quy nhị phân thuộc họ GLM như logit, probit và cloglog, tham số \(\beta\) không được ước lượng bằng phương pháp bình phương tối thiểu như trong hồi quy tuyến tính cổ điển, mà thay vào đó sử dụng phương pháp ước lượng hợp lý tối đa (Maximum Likelihood Estimation - MLE).

Phương pháp MLE tìm tập giá trị của \(\beta\) sao cho hàm hợp lý (likelihood function) đạt cực đại – nghĩa là, khả năng tạo ra bộ dữ liệu quan sát từ mô hình là cao nhất. Hàm hợp lý trong trường hợp nhị phân dựa trên phân phối nhị thức:

\[ L(\beta) = \prod_{i=1}^{n} [P_i]^{y_i} [1 - P_i]^{1 - y_i}, \quad \text{trong đó } P_i = G(X_i\beta) \]

Để đơn giản hóa tính toán, ta lấy log của hàm hợp lý để có log-likelihood:

\[ \log L(\beta) = \sum_{i=1}^{n} \left[ y_i \log P_i + (1 - y_i) \log(1 - P_i) \right] \]


CHƯƠNG 3: KẾT QUẢ NGHIÊN CỨU

library(tidyverse)
library(DT)
library(scales)
library(psych)
library(knitr)
library(kableExtra)
library(DescTools)
library(epitools)
library(AER)
library(dplyr)
library(xlsx)
library(readxl)  
library(caret)

3.1 Tổng quan về dữ liệu nghiên cứu

3.1.1 Giới thiệu bộ dữ liệu

Bộ dữ liệu Telco Customer Churn (Khách hàng rời bỏ dịch vụ viễn thông) bao gồm thông tin của 4832 khách hàng từ một công ty viễn thông, được sử dụng để phân tích và dự đoán khả năng rời bỏ dịch vụ (churn) của khách hàng. Dữ liệu chứa 21 biến, bao gồm các thông tin cá nhân (giới tính, tình trạng hôn nhân, người phụ thuộc), loại dịch vụ mà khách hàng sử dụng (dịch vụ điện thoại, internet, truyền hình, hỗ trợ kỹ thuật), thông tin về hợp đồng và phương thức thanh toán, cũng như các chỉ số tài chính như chi phí hàng tháng và tổng chi phí đã thanh toán. Biến mục tiêu Churn (Yes/No) cho biết khách hàng có rời bỏ dịch vụ hay không. Bộ dữ liệu này thường được áp dụng trong các bài toán phân tích dữ liệu, trực quan hóa và xây dựng mô hình dự đoán nhằm giúp doanh nghiệp hiểu rõ hành vi khách hàng và đưa ra chiến lược giữ chân hiệu quả.

vienthong <- read_excel("D:/HK2_PTDLDT_TMT/dlieuchinhthuc01.xlsx", sheet = 1)
datatable(vienthong,options = list(scrollX = TRUE))
vienthong <- vienthong %>% mutate(across(where(is.character), as.factor))

3.1.2 Cấu trúc bộ dữ liệu

Để có cái nhìn tổng quan về cấu trúc của bộ dữ liệu, bao gồm số lượng quan sát, số lượng biến, kiểu dữ liệu của từng biến và một số giá trị điển hình, ta sử dụng hàm str() như sau:

str(vienthong)
## tibble [4,832 × 21] (S3: tbl_df/tbl/data.frame)
##  $ customerID      : Factor w/ 4832 levels "0002-ORFBO","0003-MKNFE",..: 2724 1760 4458 4489 682 3843 3114 4712 3944 123 ...
##  $ gender          : Factor w/ 2 levels "Female","Male": 2 2 1 1 2 1 2 2 2 2 ...
##  $ SeniorCitizen   : num [1:4832] 0 0 0 0 0 0 0 0 0 0 ...
##  $ Partner         : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 2 1 2 2 1 ...
##  $ Dependents      : Factor w/ 2 levels "No","Yes": 1 1 1 1 2 1 2 2 1 1 ...
##  $ tenure          : num [1:4832] 34 2 2 8 22 28 62 13 58 49 ...
##  $ PhoneService    : Factor w/ 1 level "Yes": 1 1 1 1 1 1 1 1 1 1 ...
##  $ MultipleLines   : Factor w/ 2 levels "No","Yes": 1 1 1 2 2 2 1 1 2 2 ...
##  $ InternetService : Factor w/ 2 levels "DSL","Fiber optic": 1 1 2 2 2 2 1 1 2 2 ...
##  $ OnlineSecurity  : Factor w/ 2 levels "No","Yes": 2 2 1 1 1 1 2 2 1 1 ...
##  $ OnlineBackup    : Factor w/ 2 levels "No","Yes": 1 2 1 1 2 1 2 1 1 2 ...
##  $ DeviceProtection: Factor w/ 2 levels "No","Yes": 2 1 1 2 1 2 1 1 2 2 ...
##  $ TechSupport     : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 2 1 1 1 1 ...
##  $ StreamingTV     : Factor w/ 2 levels "No","Yes": 1 1 1 2 2 2 1 1 2 2 ...
##  $ StreamingMovies : Factor w/ 2 levels "No","Yes": 1 1 1 2 1 2 1 1 2 2 ...
##  $ Contract        : Factor w/ 3 levels "Month-to-month",..: 2 1 1 1 1 1 2 1 2 1 ...
##  $ PaperlessBilling: Factor w/ 2 levels "No","Yes": 1 2 2 2 2 2 1 2 1 2 ...
##  $ PaymentMethod   : Factor w/ 4 levels "Bank transfer (automatic)",..: 4 4 3 3 2 3 1 4 2 1 ...
##  $ MonthlyCharges  : num [1:4832] 5695 5385 707 9965 891 ...
##  $ TotalCharges    : num [1:4832] 18895 10815 15165 8205 19494 ...
##  $ Churn           : Factor w/ 2 levels "No","Yes": 1 2 2 2 1 2 1 1 1 2 ...

Qua kết quả của hàm str(), ta thấy bộ dữ liệu trong nghiên cứu là Telco Customer Churn (Khách hàng rời bỏ dịch vụ viễn thông), bao gồm thông tin của 4.832 khách hàng từ một công ty viễn thông. Dữ liệu được thu thập nhằm mục đích phân tích các yếu tố nhân khẩu học, loại dịch vụ và phương thức thanh toán có ảnh hưởng đến việc khách hàng rời bỏ dịch vụ (Churn). Tập dữ liệu chứa tổng cộng 21 biến,có 17 biến định tính và 4 định lượng cụ thể như sau:

Các biến định lượng

  • tenure: Số tháng gắn bó với dịch vụ (1 – 72 tháng).

  • MonthlyCharges: Chi phí dịch vụ hàng tháng.

  • TotalCharges: Tổng chi phí khách hàng đã thanh toán.

Các biến định tính

  • Gender: Giới tính (Male/Female).

  • Partner: Có bạn đời hay không (Yes/No).

  • Dependents: Người phụ thuộc (Yes/No).

  • PhoneService: Dịch vụ điện thoại (Yes/No).

  • MultipleLines: Nhiều đường dây (Yes/No).

  • InternetService: Loại dịch vụ Internet (DSL/Fiber optic).

  • OnlineSecurity: Bảo mật trực tuyến (Yes/No).

  • OnlineBackup: Sao lưu trực tuyến (Yes/No).

  • DeviceProtection: Bảo vệ thiết bị (Yes/No).

  • TechSupport: Hỗ trợ kỹ thuật (Yes/No).

  • StreamingTV: Dịch vụ truyền hình (Yes/No).

  • StreamingMovies: Dịch vụ xem phim (Yes/No).

  • Contract: Loại hợp đồng (Month-to-month/One year/Two year).

  • SeniorCitizen: Khách hàng thuộc nhóm cao tuổi (0/1).

  • PaperlessBilling: Hóa đơn điện tử (Yes/No).

  • PaymentMethod: Phương thức thanh toán (Mailed check, Electronic check, Bank transfer, Credit card).

  • Churn: Khách hàng có rời bỏ dịch vụ (Yes/No).

3.1.3 Hiển thị một vài dòng đầu và cuối của dữ liệu

Nhằm có được cái nhìn tổng quan về bộ dữ liệu ta sử dụng hàm head() và taid() để xem một số dòng đầu và dòng cuối của bộ dữ liệu Telco Customer Churn (Khách hàng rời bỏ dịch vụ viễn thông)

datatable(head(vienthong),options = list(scrollX = TRUE))#hiển thị vài dòng đầu
datatable(tail(vienthong),options = list(scrollX = TRUE))#hiển thị vào dòng cuối 

3.1.4 Kiểm tra giá trị thiếu

Nhằm đảm bảo chất lượng dữ liệu và tránh sai lệch trong quá trình phân tích, ta cần kiểm tra xem bộ dữ liệu có chứa giá trị thiếu (NA) hay không. Điều này giúp xác định liệu có cần xử lý hoặc làm sạch dữ liệu trước khi tiếp tục phân tích:

if (any(is.na(vienthong))) {
  cat("Có giá trị thiếu trong dữ liệu.\n")
} else {
  cat("Không có giá trị thiếu trong dữ liệu.\n")
}
## Không có giá trị thiếu trong dữ liệu.

Với đoạn code trên nếu trong bộ dữ liệu có bất kì dữ liệu nào thiếu thì kết quả sẽ nhận được là có giá trị thiếu trong dữ liệu và ngược lại.Với bộ dữ liệu được gán cho vienthong nhận được kết quả là Không có giá trị thiếu trong dữ liệu. Điều này cho thấy dữ liệu không có ô trống hay giá trị bị thiếu trong toàn bộ bộ dữ liệu. Đây là điều kiện để tiến hành các phân tích tiếp theo mà không cần thực hiện bước xử lý giá trị thiếu.

3.2 Phân tích sự tác động của loại hợp đồng đến việc khách hàng rời bỏ dịch vụ

3.2.1 Thống kê mô tả biến khách hàng rời bỏ dịch vụ (Churn) và biến các loại hợp đồng (Contract)

3.2.1.1 Biến khách hàng rời bỏ dịch vụ (Churn)

Trước tiên, tác giả tiến hành lập bảng tần số cho biến Churn nhằm xác định số lượng khách hàng rời bỏ dịch vụ (Yes) và không rời bỏ dịch vụ (No). Kết quả của bảng tần số giúp cung cấp cái nhìn tổng quan về số lượng khách hàng trong từng nhóm, qua đó hỗ trợ phân tích xu hướng rời bỏ dịch vụ trong bộ dữ liệu.

c<- table(vienthong$Churn) %>% addmargins() 
# Chuyển thành data frame với 3 cột: Churn | Số lượng | Sum (Tổng cộng)
df <- data.frame(
  Churn = c("No", "Yes", "Tổng cộng"),
  So_luong = as.numeric(c)
)

# In ra bảng đẹp, căn giữa
kable(df, align = "c", col.names = c("Churn", "Số lượng"))  %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14) %>%
  column_spec(1, width = "4cm") %>%  # Độ rộng cột 1
  column_spec(2, width = "3cm")      # Độ rộng cột 2
Churn Số lượng
No 3246
Yes 1586
Tổng cộng 4832
#lập bảng tần số của cột Churn trong bộ dữ liệu được tên vienthong và thêm cột tông vào cuối bảng

Để minh họa trực quan khách hàng rời bỏ và không rời bỏ dịch vụ, tác giả tiến hành vẽ biểu đồ cột thể hiện số lượng khách hàng theo từng giá trị của biến Churn.

c<- as.data.frame(table(vienthong$Churn)) 
colnames(c) <- c("Churn", "Count")
ggplot(c, aes(x = Churn, y = Count, fill = Churn)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = Count), vjust = -0.3, size = 3.5) +
  theme_minimal()

Dựa trên bảng tần số của biến Churn, có tổng cộng 4832 khách hàng trong bộ dữ liệu, trong đó 3246 khách hàng (chiếm đa số) vẫn tiếp tục sử dụng dịch vụ, trong khi 1.586 khách hàng đã rời bỏ dịch vụ. Số lượng khách hàng rời bỏ dịch vụ chiếm hơn 1/3 trên tổng khách hàng.

Ngoài ra tôi sẽ thực hiện tính tỷ lệ phần trăm cho từng nhóm và vẽ đồ thị cột của chúng để so sánh theo số liệu tương đối.

# Thêm cột phần trăm
c$Percentage <- round(prop.table(table(vienthong$Churn)) * 100, 2)
# BẢNG PHẦN TRĂM
kable(c, align = "c", col.names = c("Churn", "Số lượng", "Phần trăm (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14) %>%
  column_spec(1, width = "4cm") %>%
  column_spec(2, width = "3cm") %>%
  column_spec(3, width = "4cm")
Churn Số lượng Phần trăm (%)
No 3246 67.18
Yes 1586 32.82
ggplot(c, aes(x = "", y = Percentage, fill = Churn)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Dựa trên biểu đồ tròn thể hiện tỷ lệ phần trăm của biến Churn, ta nhận thấy nhóm khách hàng không rời bỏ dịch vụ (No) chiếm 67,18%, trong khi nhóm rời bỏ dịch vụ (Yes) chỉ chiếm 32,82%. Điều này cho thấy đa số khách hàng vẫn tiếp tục sử dụng dịch vụ. Tuy nhiên, tỷ lệ rời bỏ vẫn ở mức khá cao với mức chênh lệch khoảng 34,36% (67,18% – 32,82%) giữa hai nhóm. Kết quả này gợi ý doanh nghiệp cần tập trung phân tích sâu hơn nguyên nhân khiến 32,82% khách hàng rời bỏ dịch vụ, từ đó đưa ra các biện pháp cải thiện nhằm giảm tỷ lệ này.

3.2.1.2 Biến các loại hợp đồng (Contract)

Tác giả tiến hành lập bảng tần số cho biến Contract nhằm xác định số lượng khách hàng theo loại hợp đồng nào. Kết quả của bảng tần số giúp cung cấp cái nhìn tổng quan về số lượng hợp đồng trong từng nhóm.

vienthong$Contract2 <- ifelse(vienthong$Contract == "One year", "One year", "Khác")
vienthong$Contract2 <- factor(vienthong$Contract2, levels = c("One year", "Khác"))
table(vienthong$Contract2) 
## 
## One year     Khác 
##      964     3868
# In ra bảng đẹp, căn giữa
kable(table(vienthong$Contract2) , align = "c", col.names = c("Contract", "Số lượng"))  %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14) %>%
  column_spec(1, width = "4cm") %>%  # Độ rộng cột 1
  column_spec(2, width = "3cm")      # Độ rộng cột 2
Contract Số lượng
One year 964
Khác 3868

Trong nghiên cứu này, biến Contract được tái phân loại thành hai nhóm: One year và Khác nhằm thuận tiện cho việc phân tích. Kết quả thống kê mô tả cho thấy có 964 hợp đồng thuộc nhóm One year, trong khi 3.868 hợp đồng còn lại thuộc nhóm Khác. Dưới đây là biểu đồ thể hiện số lượng của các nhóm trong biến Contract.

# Tạo bảng tần số cho biến type
t <- as.data.frame(table(vienthong$Contract2) )
colnames(t) <- c("Contract2", "Count")

ggplot(t, aes(x = Contract2, y = Count, fill = Contract2)) +
  geom_bar(stat = "identity", width = 0.5) +
  geom_text(aes(label = Count), vjust = -0.5, size = 3.5) + # Hiển thị số liệu bên trên cột
  labs(title = "Đồ thị các loại hợp đồng", x = "Contract", y = "Frequency") +
  theme_minimal()

Mặt khác ta cũng cần thực hiện phân tích tỷ lệ phần trăm đối với từng loại hợp đồng và trực quan chúng bằng đồ thị tròn để có thể dễ dàng so sánh với nhau.

# Thêm cột phần trăm
t$Percentage <- (t$Count / sum(t$Count)) * 100
# BẢNG PHẦN TRĂM
kable(t, align = "c", col.names = c("Contract2", "Số lượng", "Phần trăm (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14) %>%
  column_spec(1, width = "4cm") %>%
  column_spec(2, width = "3cm") %>%
  column_spec(3, width = "4cm")
Contract2 Số lượng Phần trăm (%)
One year 964 19.95033
Khác 3868 80.04967
ggplot(t, aes(x = "", y = Percentage, fill = Contract2)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Kết quả thống kê cho thấy biến Contract đã được phân loại thành hai nhóm: One year và Khác, với 964 hợp đồng thuộc nhóm One year (chiếm 19,95%) và 3868 hợp đồng thuộc nhóm Khác (chiếm 80,05%). Biểu đồ thể hiện sự chênh lệch rõ rệt giữa hai nhóm, trong đó hợp đồng Khác chiếm tỷ trọng lớn.

3.2.2 Thống kê mô tả cho hai biến khách hàng rời bỏ dịch vụ và các loại hợp đồng

Trong trường hợp này, tác giả lập bảng tần số giữa hai biến Churn (khách hàng rời bỏ khách hàng) và Contract (các loại hợp đồng). Bảng tần số giúp chúng ta hiểu rõ hơn về sự phân bố khách hàng rời bỏ dịch vụ viễn thông theo từng loại hợp đồng.

table(vienthong$Contract2, vienthong$Churn) %>%  addmargins()
##           
##              No  Yes  Sum
##   One year  821  143  964
##   Khác     2425 1443 3868
##   Sum      3246 1586 4832

Vẽ đồ thị cột phân theo từng loại hợp đồng để đánh giá số lượng khách hàng rời bỏ dịch vụ viễn thông trong từng nhóm.

table_data <- table(vienthong$Contract2, vienthong$Churn)

# Chuyển bảng chéo sang định dạng dài
long_data <- as.data.frame(table_data)
colnames(long_data) <- c("Contract2", "Churn", "count")

# Vẽ biểu đồ cột
ggplot(long_data, aes(x = Churn, y = count, fill = Churn)) +
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_text(aes(label = count), vjust = 1, size = 2.5, position = position_dodge(1)) +
  facet_wrap(~ Contract2, scales = "free_y", nrow = 2) +
  labs(title = "Phân bố khách hàng rời bỏ dịch vụ theo loại hợp đồng",
       x = "Khách hàng rời bỏ hợp đồng",
       y = "Loại hợp đồng",
       fill = "Khách hàng rời bỏ hợp đồng") +
  theme_minimal()  

Dựa trên kết quả thống kê, biểu đồ cho thấy sự phân bố khách hàng rời bỏ dịch vụ theo loại hợp đồng. Đối với nhóm hợp đồng One Year có 821 khách hàng không rời bỏ dịch vụ, trong khi chỉ có 143 khách àng rời bỏ, chiếm 14.8%. Ngược lại, ở nhóm hợp đồng Khác số khách hàng rời bỏ dịch vụ lên tới 1443 cáo hơn đáng kể so với 2425 khách hàng tiếp tục sử dụng dịch vụ, tương ứng với 37.3%. Như vậy tỷ lệ rời bỏ dịch vụ của khách hàng ở nhóm Khác cao gần 3 lần so với nhóm One Year. Góp phần khẳng định vai trò của các hợp đồng 1 năm trong việc giữ chân khách hàng. Khuyến khích doanh nghiệp cần đẩy mạnh chính sách ưu đãi hoặc các gói dịch vụ cho hợp đồng “One year” nhằm có nhiều khách hàng chuyển sang loại hợp đồng này để giảm tỷ lệ rời bỏ dịch vụ.

Tiếp theo, lập bảng tần suất giữa hai biến khách hàng rời bỏ dịch vụ viễn thông và các loại hợp đồng. Từ đó vẽ đồ thì cột theo từng nhóm công việc như bên dưới đây.

table_data1 <- round(prop.table(table_data)*100,2) 
kable(table_data1, align = "c", col.names = c("Contract2", "No", "Yes")) %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14) %>%
  column_spec(1, width = "4cm") %>%
  column_spec(2, width = "3cm") %>%
  column_spec(3, width = "4cm")
Contract2 No Yes
One year 16.99 2.96
Khác 50.19 29.86
# Chuyển đổi dữ liệu thành dạng dài để dễ vẽ biểu đồ
table_data1 <- as.data.frame.table(table_data1)
colnames(table_data1) <- c("Group", "Level", "Percentage")

# Vẽ biểu đồ
ggplot(table_data1, aes(x = Level, y = Percentage, fill = Level)) +
  geom_bar(stat = "identity", position = "dodge") +
  geom_text(aes(label = Percentage), vjust = 1, size = 2.5, position = position_dodge(1)) +
  facet_wrap(~ Group, scales = "free_y", nrow = 2) +
  labs(title = "Đồ thị phần trăm theo biểu hiện yes, no của khách hàng từ bỏ dịch vụ và các loại hợp đồng",
       x = "Các loại hợp đồng",
       y = "Phần trăm",
       fill = "Biểu hiện") +
  scale_fill_manual(values = c("No" = "skyblue", "Yes" = "pink")) + 
  theme_minimal()

Dựa trên kết quả bảng tần suất và biểu đồ tần suất, có thể nhận thấy sự khác biệt rõ rệt về tỷ lệ khách hàng rời bỏ dịch vụ giữa hai nhóm hợp đồng One year và Khác. Cụ thể, trong nhóm One year, tỷ lệ khách hàng không rời bỏ dịch vụ chiếm 16,99%, trong khi chỉ có 2,96% khách hàng rời bỏ. Ngược lại, ở nhóm Khác, tỷ lệ khách hàng rời bỏ dịch vụ cao hơn nhiều, đạt 29,86% so với 50,19% khách hàng tiếp tục sử dụng.

3.2.3 Phân tích Relative Risk giữa các loại hợp đồng và khách hàng rời bỏ dịch vụ

Trong phần tiếp theo, tác giả sẽ tiến hành tính toán chỉ số rủi ro tương đối (Relative Risk – RR) nhằm đánh giá mức độ ảnh hưởng của từng loại hợp đồng đến khả năng khách hàng rời bỏ dịch vụ viễn thông.

rr1<- riskratio(table_data)
rr1
## $data
##           
##              No  Yes Total
##   One year  821  143   964
##   Khác     2425 1443  3868
##   Total    3246 1586  4832
## 
## $measure
##           risk ratio with 95% C.I.
##            estimate    lower   upper
##   One year 1.000000       NA      NA
##   Khác     2.514901 2.150192 2.94147
## 
## $p.value
##           two-sided
##            midp.exact fisher.exact   chi.square
##   One year         NA           NA           NA
##   Khác              0  1.70686e-44 2.500975e-40
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Chỉ số Relative Risk (RR) được sử dụng để đánh giá mức độ khác biệt về xác suất rời bỏ dịch vụ giữa hai nhóm hợp đồng One year và Khác. Công thức tính RR như sau:

\[ RR = \frac{P(\text{Yes | Khác})}{P(\text{Yes | One year})} \]

trong đó \(P(\text{Yes | Khác}) = \frac{1443}{3868} \approx 0,3733\)\(P(\text{Yes | One year}) = \frac{143}{964} \approx 0,1484\).

Thay các giá trị này vào công thức, ta thu được RR ≈ 2,51, tức là khách hàng sử dụng hợp đồng “Khác” có khả năng rời bỏ dịch vụ cao hơn khoảng 2,5 lần so với nhóm khách hàng sử dụng hợp đồng “One year”. Khoảng tin cậy 95% của RR là [2,15; 2,94], cho thấy kết quả ước lượng đáng tin cậy và không chứa giá trị 1, nghĩa là sự khác biệt giữa hai nhóm là có ý nghĩa thống kê. Đồng thời, giá trị p-value (1,71e-44) gần bằng 0 càng khẳng định sự khác biệt này là có ý nghĩa thống kê. Vì vậy, loại hợp đồng là một nhân tố quan trọng ảnh hưởng đến hành vi rời bỏ dịch vụ và các hợp đồng dài hạn như “One year” giúp giảm đáng kể tỷ lệ khách hàng rời bỏ. Doanh nghiệp viễn thông có thể dựa vào kết quả này để xây dựng chiến lược khuyến khích khách hàng chọn hợp đồng dài hạn, từ đó giảm churn và tăng tính ổn định trong doanh thu.

3.2.4 Phân tích Odd Ratio giữa các loại hợp đồng và khách hàng rời bỏ dịch vụ

Trong phần này, nghiên cứu sẽ tiến hành tính Odds Ratio giữa hai loại hợp đồng và biến khách hàng rời bỏ dịch vụ viễn thông (Churn). Việc tính toán OR sẽ giúp xác định loại hợp đồng nào làm tăng hoặc giảm khả năng rời bỏ dịch vụ, qua đó cung cấp thông tin quan trọng để doanh nghiệp đưa ra các chiến lược giữ chân khách hàng phù hợp.

or1 <- oddsratio(table_data)
or1
## $data
##           
##              No  Yes Total
##   One year  821  143   964
##   Khác     2425 1443  3868
##   Total    3246 1586  4832
## 
## $measure
##           odds ratio with 95% C.I.
##            estimate    lower    upper
##   One year 1.000000       NA       NA
##   Khác     3.412725 2.833104 4.137819
## 
## $p.value
##           two-sided
##            midp.exact fisher.exact   chi.square
##   One year         NA           NA           NA
##   Khác              0  1.70686e-44 2.500975e-40
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Dựa trên kết quả phân tích Odds Ratio (OR) giữa hai loại hợp đồng và hành vi rời bỏ dịch vụ, ta tính được OR = 3,41. Giá trị này được xác định từ công thức:

\[ OR = \frac{\frac{1443}{2425}}{\frac{143}{821}} \approx 3,41 \]

nghĩa là tỷ lệ rời bỏ dịch vụ của nhóm khách hàng sử dụng hợp đồng Khác cao gấp 3,41 lần so với nhóm One year. Khoảng tin cậy 95% của OR nằm trong khoảng [2,83; 4,14], không chứa giá trị 1, cho thấy sự khác biệt giữa hai nhóm là có ý nghĩa thống kê. Giá trị p-value (1,71e-44) cực kỳ nhỏ, khẳng định loại hợp đồng có ảnh hưởng đáng kể đến khả năng khách hàng rời bỏ dịch vụ. Kết quả này chứng tỏ rằng khách hàng sử dụng hợp đồng One year có mức độ gắn bó với dịch vụ cao hơn.

3.2.5 Thống kê suy diễn

3.2.5.1 Kiểm định tính độc lập

Để kiểm tra xem biến loại hợp đồng (Contract) và hành vi rời bỏ dịch vụ (Churn) có mối liên hệ với nhau hay không, nghiên cứu áp dụng kiểm định Chi-square.

Kiểm định này được thiết lập với giả thuyết:

\[ \left\{ \begin{array}{ll} H_0: & \text{Biến Churn (khách hàng từ bỏ dịch vụ) và biến Contract (các loại hợp đồng) không có mối quan hệ với nhau.} \\\\ H_1: & \text{Biến Churn (khách hàng từ bỏ dịch vụ) và biến Contract (các loại hợp đồng) có mối quan hệ với nhau.} \ \end{array} \right. \]

# Kiểm định
chisq_result1 <- chisq.test(table_data)
# In kết quả
chisq_result1
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table_data
## X-squared = 175.72, df = 1, p-value < 2.2e-16

Qua kết quả kiểm định: Với mức ý nghĩa 0.05, vì p-value = 2.2e-16 < 0.05, bác bỏ giả thuyết \(H_0\). Vậy giữa biến Churn và biến Contract tồn tại mối quan hệ.

3.2.5.2 Khoảng ước lượng tỷ lệ

Ước lượng tỷ lệ rời bỏ dịch vụ của nhóm khách hàng có hợp đồng One year

Trong phần này, tác giả sử dụng kiểm định tỷ lệ một mẫu (1-sample proportion test) để ước lượng tỷ lệ khách hàng rời bỏ dịch vụ trong nhóm hợp đồng One year, đồng thời so sánh với tỷ lệ giả định là 50% (p = 0.5). Phương pháp này giúp xác định xem tỷ lệ rời bỏ dịch vụ của nhóm hợp đồng này có khác biệt đáng kể so với tỷ lệ giả định hay không.

prop.test(x = table_data["One year", "Yes"], n = sum( table_data["One year", ]), p = 0.5, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  table_data["One year", "Yes"] out of sum(table_data["One year", ]), null probability 0.5
## X-squared = 475.45, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.1268153 0.1727210
## sample estimates:
##         p 
## 0.1483402

Kết quả kiểm định cho thấy tỷ lệ một mẫu cho nhóm hợp đồng One year cho thấy tỷ lệ rời bỏ dịch vụ thực tế chỉ khoảng 14,83%, thấp hơn nhiều so với tỷ lệ giả định 50%. Khoảng tin cậy 95% của tỷ lệ này nằm trong khoảng từ 12,68% đến 17,27% tỷ lệ rời bỏ dịch vụ của nhóm khách hàng One year ổn định quanh mức 15%. Giá trị p-value của kiểm định bằng < 2.2e-16 nhỏ hơn mức ý nghĩa 5%, bác bỏ giả thuyết H₀ rằng tỷ lệ rời bỏ là 50%.

Ước lượng tỷ lệ rời bỏ dịch vụ của nhóm khách hàng có hợp đồng Khác

Trong phần này tác giả sử dụng kiểm định tỷ lệ một mẫu (1-sample proportion test) để ước lượng tỷ lệ khách hàng rời bỏ dịch vụ trong nhóm hợp đồng khác, đồng thời so sánh với tỷ lệ giả định là 50% (p = 0.5). Phương pháp này giúp xác định xem tỷ lệ rời bỏ dịch vụ của nhóm hợp đồng này có khác biệt đáng kể so với tỷ lệ giả định hay không.

prop.test(x = table_data["Khác", "Yes"], n = sum( table_data["Khác", ]), p = 0.5, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  table_data["Khác", "Yes"] out of sum(table_data["Khác", ]), null probability 0.5
## X-squared = 248.8, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.3578251 0.3885509
## sample estimates:
##        p 
## 0.373061

Kết quả kiểm định tỷ lệ một mẫu đối với nhóm khách hàng có hợp đồng Khác cho thấy tỷ lệ rời bỏ dịch vụ ước lượng từ mẫu là 37,31%, với khoảng tin cậy 95% dao động từ 35,78% đến 38,85%. Giá trị p-value < 2.2e-16, nhỏ hơn mức ý nghĩa 0,05, bác bỏ giả thuyết H₀ rằng tỷ lệ rời bỏ dịch vụ của nhóm này bằng 50%. Như vậy, tỷ lệ rời bỏ dịch vụ của nhóm hợp đồng Khác thấp hơn đáng kể so với tỷ lệ giả định và ổn định quanh mức 37%. Điều này cũng cho thấy nhóm Khác có xu hướng rời bỏ dịch vụ cao hơn so với nhóm One year.

3.2.6 Mô hình hồi quy cho dữ liệu nhị phân

3.2.6.1 Mô hình logit

Để phân tích mối quan hệ giữa loại hợp đồng Contract2 và khách hàng rời bỏ dịch vụ Churn, tác giả sử dụng mô hình hồi quy logistic nhị phân (logit model). Mô hình này cho phép ước lượng xác suất rời bỏ dịch vụ thông qua hàm logit, giúp xác định mức độ ảnh hưởng của từng loại hợp đồng đến hành vi rời bỏ của khách hàng.

log1 <- glm(factor(Churn) ~ Contract2, data = vienthong, family = binomial(link = 'logit'))
summary(log1)
## 
## Call:
## glm(formula = factor(Churn) ~ Contract2, family = binomial(link = "logit"), 
##     data = vienthong)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)   -1.74768    0.09061  -19.29   <2e-16 ***
## Contract2Khác  1.22857    0.09652   12.73   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 5919.5  on 4830  degrees of freedom
## AIC: 5923.5
## 
## Number of Fisher Scoring iterations: 4

Ta có mô hình hồi quy như sau:

\[ \log\left( \frac{P(\text{Churn} = \text{"Yes"})}{1 - P(\text{Churn} = \text{"Yes"})} \right) = -1.74768 + 1.22857 \cdot \text{Contract2Khác} \]

  • \(\beta_0 = -1.74768\): Đây là log-odds rời bỏ dịch vụ của nhóm khách hàng “One year” (khi Contract2Khác = 0). Khi chuyển sang dạng odds, \(e^{-1.74768} \approx 0.174\), tương ứng với xác suất rời bỏ dịch vụ khoảng 17.4%, cho thấy nhóm này có mức độ gắn bó cao.

  • \(\beta_1 = 1.22857\): Đây là mức thay đổi log-odds khi khách hàng thuộc nhóm “Khác” so với “One year”. Vì \(\beta_1 > 0\), khả năng rời bỏ dịch vụ tăng lên. Giá trị \(e^{1.22857} \approx 3.42\) cho thấy odds rời bỏ dịch vụ của nhóm “Khác” cao gấp 3,42 lần so với nhóm “One year”.

Điều này khẳng định rằng khách hàng với hợp đồng không phải “One year” dễ rời bỏ dịch vụ hơn và doanh nghiệp cần tập trung vào nhóm này để giảm tỷ lệ rời bỏ.

3.2.6.2 Mô hình probit

Bên cạnh mô hình logit, tác giả còn sử dụng mô hình probit nhằm so sánh kết quả và kiểm tra tính ổn định của mối quan hệ giữa biến loại hợp đồng Contract2 và khả năng khách hàng rời bỏ dịch vụ Churn. Mô hình probit sử dụng hàm liên kết chuẩn tích lũy thay vì hàm logit, nhưng vẫn mang ý nghĩa tương tự trong việc ước lượng xác suất rời bỏ.

pro1 <- glm(factor(Churn) ~ Contract2, data = vienthong, family = binomial(link = 'probit'))
summary(pro1 )
## 
## Call:
## glm(formula = factor(Churn) ~ Contract2, family = binomial(link = "probit"), 
##     data = vienthong)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)   -1.04358    0.04947  -21.10   <2e-16 ***
## Contract2Khác  0.71982    0.05356   13.44   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 5919.5  on 4830  degrees of freedom
## AIC: 5923.5
## 
## Number of Fisher Scoring iterations: 4

Ta có mô hình hồi quy như sau:

\[ P(Y=1|Contract2) = \Phi(-1.04358 + 0.71982Contract2Khác) \] trong đó \(\Phi(\cdot)\) là hàm phân phối tích lũy chuẩn chuẩn hóa.

  • Với Contract2 = One year (\(Contract2Khác = 0\)): \[P(Y=1 | One\ year) = \Phi(-1.04358) \approx 0.149 \ (14.9\%).\]

  • Với Contract2 = Khác (\(Contract2Khác = 1\)): \[ P(Y=1 | Khác) = \Phi(-1.04358 + 0.71982) = \Phi(-0.32376) \approx 0.373 \ (37.3\%).\]

Kết quả ước lượng cho thấy biến Contract2 có ý nghĩa thống kê rất cao với \(p < 2e-16\), chứng tỏ loại hợp đồng ảnh hưởng mạnh đến khả năng khách hàng rời bỏ dịch vụ. Khi khách hàng sử dụng hợp đồng One year, xác suất rời bỏ dịch vụ chỉ ở mức 14.9%, trong khi với hợp đồng Khác, xác suất này tăng lên 37.3%. Điều này cho thấy khách hàng sử dụng hợp đồng “Khác” có nguy cơ rời bỏ dịch vụ cao gấp khoảng 2,5 lần so với nhóm One year.

3.2.6.3 Mô hình cloglog

Ngoài logit và probit, tác giả còn sử dụng mô hình hồi quy Complementary Log-Log (cloglog) để phân tích mối quan hệ giữa loại hợp đồng Contract2 và khả năng khách hàng rời bỏ dịch vụ Churn. Mô hình cloglog thường được áp dụng trong trường hợp xác suất xảy ra sự kiện rất nhỏ hoặc rất lớn, nhờ khả năng xử lý phân phối bất đối xứng tốt hơn so với logit hoặc probit. Mục tiêu của việc sử dụng cloglog là so sánh và đánh giá tính ổn định của kết quả ước lượng giữa các mô hình liên kết khác nhau.

clo1 <- glm(factor(Churn) ~ Contract2, data = vienthong, family = binomial(link = 'cloglog'))
summary(clo1)
## 
## Call:
## glm(formula = factor(Churn) ~ Contract2, family = binomial(link = "cloglog"), 
##     data = vienthong)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)   -1.82904    0.08371  -21.85   <2e-16 ***
## Contract2Khác  1.06741    0.08783   12.15   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 5919.5  on 4830  degrees of freedom
## AIC: 5923.5
## 
## Number of Fisher Scoring iterations: 5

Ta có mô hình hồi quy như sau:

\[ \log \left( -\log \left( 1 - P(\mathrm{Churn} = \mathrm{Yes}) \right) \right) = -1.82904 + 1.06741 \cdot \mathrm{Contract2Khac} \]

Kết quả của mô hình cloglog cho thấy hệ số chặn −1.82904 có ý nghĩa thống kê, tương ứng với xác suất khách hàng rời bỏ dịch vụ khoảng 14.8% khi họ sử dụng hợp đồng One year.

\[ p_{\text{OneYear}} = 1 - \exp \left( -\exp(-1.82904) \right) \approx 0.148 \, (14.8\%) \]

Trong khi đó, hệ số Contract2Khác = 1.06741 (p < 0.001) cho thấy khách hàng thuộc nhóm hợp đồng Khác có xác suất rời bỏ dịch vụ cao hơn rõ rệt, lên đến 37.3%.

\[ \eta = -1.82904 + 1.06741 = -0.76163, \]

và xác suất:

\[ p_{\text{Khac}} = 1 - \exp\left( -\exp(-0.76163) \right) \approx 0.373 \, (37.3\%). \] Như vậy, việc thay đổi loại hợp đồng từ One year sang Khác làm tăng đáng kể nguy cơ khách hàng rời bỏ dịch vụ.

3.2.7 Đánh giá mô hình

Sau khi tiến hành ước lượng ba mô hình hồi quy nhị phân gồm logit, probit và cloglog, bước tiếp theo là đánh giá và so sánh mức độ phù hợp của các mô hình này. Việc đánh giá được thực hiện dựa trên các chỉ tiêu thống kê như giá trị AIC, hệ số Brier Score và ma trận nhầm lẫn. Ngoài ra, khả năng dự báo xác suất của từng mô hình đối với các trường hợp giả định cụ thể cũng được xem xét để lựa chọn mô hình phù hợp nhất.

# Tạo bảng so sánh
model_eval <- data.frame(
  Mô_hình = c("Logit", "Probit", "Cloglog"),
  AIC = c(AIC(log1), AIC(pro1), AIC(clo1)),
  BIC = c(BIC(log1), BIC(pro1), BIC(clo1)),
  Brier_Score = c(BrierScore(log1), BrierScore(pro1), BrierScore(clo1))
)
kable(model_eval, align = "c", caption = "So sánh các chỉ số đánh giá mô hình") %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14)
So sánh các chỉ số đánh giá mô hình
Mô_hình AIC BIC Brier_Score
Logit 5923.54 5936.506 0.2124297
Probit 5923.54 5936.506 0.2124297
Cloglog 5923.54 5936.506 0.2124297

Các kết quả AIC, BIC và Brier Score cho thấy ba mô hình logit, probit và cloglog đều có mức độ phù hợp tương đương, với AIC = 5923.54, BIC = 5936.506 và Brier Score = 0.2124. Giá trị AIC và BIC ngang nhau chứng tỏ không có mô hình nào vượt trội về khả năng giải thích dữ liệu hoặc độ phức tạp. Đồng thời, Brier Score phản ánh khả năng dự đoán xác suất của cả ba mô hình đều tốt và tương đương nhau.

Ma trận nhầm lẫn

  • Mô hình logit
pred_logitlog <- ifelse(predict(log1, type = "response") >= 0.5, "Yes", "No")
actuallog <- vienthong$Churn
cm_logitlog <- confusionMatrix(factor(pred_logitlog), actuallog, positive = "Yes")
cm_logitlog
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 
  • Mô hình probit
pred_logitpro <- ifelse(predict(pro1, type = "response") >= 0.5, "Yes", "No")
actualpro <- vienthong$Churn
cm_logitpro <- confusionMatrix(factor(pred_logitpro), actualpro, positive = "Yes")
cm_logitpro
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 
  • Mô hình cloglog
pred_logitclo <- ifelse(predict(clo1, type = "response") >= 0.5, "Yes", "No")
actualclo <- vienthong$Churn
cm_logitclo <- confusionMatrix(factor(pred_logitclo), actualclo, positive = "Yes")
cm_logitclo
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 

Dựa vào ma trận nhầm lẫn của 3 mô hình (logit, probit, cloglog) và hình minh họa, ta có thể chi tiết như sau:

  • TP (True Positive = 0): Không có trường hợp nào khách hàng thực tế rời bỏ dịch vụ Yes mà mô hình dự đoán đúng là Yes.

  • TN (True Negative = 3246): Có 3246 trường hợp khách hàng không rời bỏ dịch vụ No và mô hình cũng dự đoán đúng là No.

  • FP (False Positive = 0): Không có trường hợp nào mô hình dự đoán Yes nhưng thực tế khách hàng lại ở nhóm No.

  • FN (False Negative = 1586): Có 1586 khách hàng thực tế rời bỏ dịch vụ Yes nhưng mô hình lại dự đoán là No.

Kết quả ma trận nhầm lẫn cho thấy cả ba mô hình logit, probit và cloglog đều dự đoán toàn bộ khách hàng là “No” (không rời bỏ dịch vụ), dẫn đến số lượng True Positive (TP) và False Positive (FP) đều bằng 0. Điều này khiến độ nhạy (Sensitivity) bằng 0%, nghĩa là mô hình hoàn toàn không phát hiện được khách hàng nào rời bỏ dịch vụ. Mặc dù độ chính xác (Accuracy) đạt 67,18%, nhưng con số này chỉ phản ánh tỷ lệ khách hàng “No” trong tập dữ liệu, không thể hiện năng lực phân loại đúng nhóm “Yes”. Nguyên nhân có thể do ngưỡng dự đoán 0.5 chưa phù hợp hoặc dữ liệu mất cân bằng khi nhóm “No” chiếm đa số.

3.3 Phân tích sự tác động của loại hình dịch vụ Internet đang sử dụng đến việc khách hàng rời bỏ dịch vụ

3.3.1 Thống kê mô tả biến loại hình dịch vụ Internet đang sử dụng

Để hiểu rõ hơn về đặc điểm khách hàng trong bộ dữ liệu, trước tiên cần phân tích loại hình dịch vụ Internet mà họ đang sử dụng. Biến InternetService phản ánh các gói dịch vụ chính như DSL và Fiber optic, từ đó giúp đánh giá xu hướng lựa chọn dịch vụ của khách hàng.

e<-table(vienthong$InternetService) 

# Chuyển thành data frame với 3 cột: Churn | Số lượng | Sum (Tổng cộng)
dfi <- data.frame(
   InternetService= c("DSL", "Fiber optic "),
  So_luong = as.numeric(e)
)

# In ra bảng đẹp, căn giữa
kable(dfi, align = "c", col.names = c("InternetService", "Số lượng"))  %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14) %>%
  column_spec(1, width = "4cm") %>%  # Độ rộng cột 1
  column_spec(2, width = "3cm")      # Độ rộng cột 2
InternetService Số lượng
DSL 1736
Fiber optic 3096
#lập bảng tần số của cột Churn trong bộ dữ liệu được tên vienthong và thêm cột tông vào cuối bảng

Để minh họa trực quan loại dịch vụ internet, tôi tiến hành vẽ biểu đồ cột thể hiện số lượng từng giá trị của nhóm InternetService.

# Tạo bảng tần số cho biến type
i <- as.data.frame(table(vienthong$InternetService) )
colnames(i) <- c("InternetService", "Count")

ggplot(i, aes(x = InternetService, y = Count, fill = InternetService)) +
  geom_bar(stat = "identity", width = 0.5) +
  geom_text(aes(label = Count), vjust = -0.5, size = 3.5) + # Hiển thị số liệu bên trên cột
  labs(title = "Đồ thị các loại hình dịch vụ InternetService", x = "InternetService", y = "Frequency") +
  theme_minimal()

Kết quả thống kê cho thấy dịch vụ Fiber optic được sử dụng nhiều hơn so với DSL. Cụ thể, có 3096 khách hàng sử dụng Fiber optic, trong khi DSL chỉ có 1736 khách hàng. Biểu đồ cột minh họa sự chênh lệch rõ rệt, khi số lượng khách hàng Fiber optic gần gấp đôi DSL. Điều này cho thấy Fiber optic đang là lựa chọn phổ biến hơn.

Ngoài ra tác giả sẽ thực hiện tính tỷ lệ phần trăm cho từng nhóm và vẽ đồ thị cột của chúng để so sánh theo số liệu tương đối.

# Thêm cột phần trăm
i$Percentage <- round(prop.table(table(vienthong$InternetService)) * 100, 2)
# BẢNG PHẦN TRĂM
kable(i, align = "c", col.names = c("Churn", "Số lượng", "Phần trăm (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14) %>%
  column_spec(1, width = "4cm") %>%
  column_spec(2, width = "3cm") %>%
  column_spec(3, width = "4cm")
Churn Số lượng Phần trăm (%)
DSL 1736 35.93
Fiber optic 3096 64.07
ggplot(i, aes(x = "", y = Percentage, fill = InternetService)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Biểu đồ tròn cho thấy dịch vụ Fiber optic chiếm tỷ lệ cao nhất với 64.07% tổng số khách hàng, trong khi dịch vụ DSL chiếm 35.93%. Điều này cho thấy khách hàng có xu hướng ưa chuộng Fiber optic hơn, gần gấp đôi so với DSL. Sự chênh lệch này có thể xuất phát từ ưu điểm về tốc độ truyền tải và chất lượng kết nối của Fiber optic.

3.3.2 Thống kê mô tả cho hai biến khách hàng rời bỏ dịch vụ và các loại hình dịch vụ Internet

Phần này nhằm mô tả tổng quan về tình trạng khách hàng rời bỏ dịch vụ (Churn) và loại hình dịch vụ Internet (InternetService) mà họ đang sử dụng. Việc thống kê hai biến này giúp nhận diện được xu hướng rời bỏ dịch vụ theo từng loại hình Internet, từ đó làm cơ sở cho các phân tích tiếp theo.

table(vienthong$InternetService, vienthong$Churn) %>%  addmargins()
##              
##                 No  Yes  Sum
##   DSL         1447  289 1736
##   Fiber optic 1799 1297 3096
##   Sum         3246 1586 4832

Vẽ đồ thị cột phân theo từng loại dịch vụ internet để đánh giá số lượng khách hàng rời bỏ dịch vụ viễn thông trong từng nhóm.

table_data <- table(vienthong$InternetService, vienthong$Churn)

# Chuyển bảng chéo sang định dạng dài
long_data2 <- as.data.frame(table_data)
colnames(long_data2) <- c("InternetService", "Churn", "count")

# Vẽ biểu đồ cột
ggplot(long_data2, aes(x = Churn, y = count, fill = Churn)) +
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_text(aes(label = count), vjust = 1, size = 2.5, position = position_dodge(1)) +
  facet_wrap(~ InternetService, scales = "free_y", nrow = 2) +
  labs(title = "Phân bố khách hàng rời bỏ dịch vụ theo các loại hình dịch vụ Internet",
       x = "Khách hàng rời bỏ hợp đồng",
       y = "Các loại hình dịch vụ Internet",
       fill = "Khách hàng rời bỏ hợp đồng") +
  theme_minimal()  

Biểu đồ cho thấy tỷ lệ khách hàng rời bỏ dịch vụ khác nhau rõ rệt giữa hai loại hình Internet. Với DSL, có 1447 khách hàng duy trì dịch vụ và 289 khách hàng rời bỏ, tương ứng tỷ lệ rời bỏ khoảng 16,7%. Trong khi đó, Fiber optic có số lượng khách hàng rời bỏ cao hơn nhiều với 1297 khách hàng, chiếm khoảng 41,9%. Điều này cho thấy khách hàng sử dụng Fiber optic có xu hướng rời bỏ dịch vụ nhiều hơn, mặc dù đây là loại hình được sử dụng phổ biến nhất.

table_data2 <- round(prop.table(table_data)*100,2) 
table_data2
##              
##                  No   Yes
##   DSL         29.95  5.98
##   Fiber optic 37.23 26.84
# Chuyển đổi dữ liệu thành dạng dài để dễ vẽ biểu đồ
table_data2 <- as.data.frame.table(table_data2)
colnames(table_data2) <- c("Group", "Level", "Percentage")

# Vẽ biểu đồ
ggplot(table_data2, aes(x = Level, y = Percentage, fill = Level)) +
  geom_bar(stat = "identity", position = "dodge") +
  geom_text(aes(label = Percentage), vjust = 1, size = 2.5, position = position_dodge(1)) +
  facet_wrap(~ Group, scales = "free_y", nrow = 2) +
  labs(title = "Đồ thị phần trăm theo biểu hiện yes, no của khách hàng từ bỏ dịch vụ và các laoij dịch vụ Internet",
       x = "Các loại dịch vụ Internet",
       y = "Phần trăm",
       fill = "Biểu hiện") +
  scale_fill_manual(values = c("No" = "lightgreen", "Yes" = "lightpink")) + 
  theme_minimal()

Biểu đồ tần suất cho thấy sự khác biệt rõ rệt về tỷ lệ khách hàng rời bỏ dịch vụ giữa hai loại hình Internet. Đối với DSL, tỷ lệ khách hàng duy trì dịch vụ chiếm 29,95%, trong khi tỷ lệ rời bỏ chỉ là 5,98%. Ngược lại, Fiber optic có tỷ lệ khách hàng duy trì là 37,23%, nhưng tỷ lệ rời bỏ cao hơn đáng kể, đạt 26,84%. Kết quả này cho thấy, mặc dù Fiber optic phổ biến hơn, khách hàng của dịch vụ này cũng có xu hướng rời bỏ nhiều hơn so với DSL.

3.3.3 Phân tích Relative Risk giữa các loại hình dịch vụ Internet và khách hàng rời bỏ dịch vụ

Trong phần tiếp theo, chúng tôi sẽ tiến hành tính toán chỉ số rủi ro tương đối (Relative Risk – RR) nhằm đánh giá mức độ ảnh hưởng của các loại dịch vụ Internet đến khả năng khách hàng rời bỏ dịch vụ viễn thông.

rr2<- riskratio(table_data)
rr2
## $data
##              
##                 No  Yes Total
##   DSL         1447  289  1736
##   Fiber optic 1799 1297  3096
##   Total       3246 1586  4832
## 
## $measure
##              risk ratio with 95% C.I.
##               estimate   lower    upper
##   DSL         1.000000      NA       NA
##   Fiber optic 2.516465 2.24727 2.817906
## 
## $p.value
##              two-sided
##               midp.exact fisher.exact  chi.square
##   DSL                 NA           NA          NA
##   Fiber optic          0 1.947323e-76 6.81095e-72
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Kết quả phân tích Relative Risk (RR) cho thấy nhóm DSL được xem như mốc tham chiếu với RR = 1.0. Trong khi đó, nhóm Fiber optic có RR = 2,52, tức là nguy cơ khách hàng rời bỏ dịch vụ cao gấp khoảng 2,5 lần so với DSL. Giá trị p-value gần bằng 0 (p < 0,001) từ các kiểm định Fisher và Chi-square khẳng định sự khác biệt này hoàn toàn có ý nghĩa thống kê. Điều này cho thấy nhóm khách hàng sử dụng Fiber optic dễ rời bỏ dịch vụ hơn, dù đây là loại hình phổ biến. Vì vậy, doanh nghiệp cần có chính sách chăm sóc và giữ chân khách hàng Fiber optic hiệu quả hơn.

3.3.4 Phân tích Odd Ratio giữa các loại hình dịch vụ Internet và khách hàng rời bỏ dịch vụ

Trong phần này, nghiên cứu sẽ tiến hành tính Odds Ratio giữa hai loại dịch vụ internet và biến khách hàng rời bỏ dịch vụ viễn thông (Churn). Việc tính toán OR sẽ giúp xác định loại hợp đồng nào làm tăng hoặc giảm khả năng rời bỏ dịch vụ.

or2 <- oddsratio(table_data)
or2
## $data
##              
##                 No  Yes Total
##   DSL         1447  289  1736
##   Fiber optic 1799 1297  3096
##   Total       3246 1586  4832
## 
## $measure
##              odds ratio with 95% C.I.
##               estimate    lower    upper
##   DSL         1.000000       NA       NA
##   Fiber optic 3.607595 3.124326 4.177066
## 
## $p.value
##              two-sided
##               midp.exact fisher.exact  chi.square
##   DSL                 NA           NA          NA
##   Fiber optic          0 1.947323e-76 6.81095e-72
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Kết quả phân tích odds ratio (OR) cho thấy nhóm khách hàng sử dụng DSL được chọn làm mốc tham chiếu với OR = 1.0. Trong khi đó, nhóm Fiber optic có OR = 3,61, tức là khả năng rời bỏ dịch vụ của họ cao gấp khoảng 3,6 lần so với khách hàng sử dụng dịch vụ DSL. Giá trị p-value gần bằng 0 (p < 0,001) từ các kiểm định Fisher và Chi-square chứng minh sự khác biệt này có ý nghĩa thống kê rất cao. Điều này cho thấy khách hàng Fiber optic dễ rời bỏ dịch vụ hơn, dù đây là loại hình chiếm tỷ trọng lớn trong dữ liệu. Doanh nghiệp cần ưu tiên các chính sách chăm sóc khách hàng và chiến lược giữ chân riêng cho nhóm Fiber optic nhằm giảm tỷ lệ rời bỏ.

3.3.5 Thống kê suy diễn

3.3.5.1 Kiểm định tính độc lập

Để kiểm tra xem biến dịch vụ internet (InternetService) và hành vi rời bỏ dịch vụ (Churn) có mối liên hệ với nhau hay không, nghiên cứu áp dụng kiểm định Chi-square.

Kiểm định này được thiết lập với giả thuyết:

\[ \left\{ \begin{array}{ll} H_0: & \text{Biến Churn (khách hàng từ bỏ dịch vụ) và biến InternetService (dịch vụ internet) không có mối quan hệ với nhau.} \\\\ H_1: & \text{Biến Churn (khách hàng từ bỏ dịch vụ) và biến InternetService (dịch vụ internet) có mối quan hệ với nhau.} \ \end{array} \right. \]

# Kiểm định
chisq_result <- chisq.test(table_data)
# In kết quả
chisq_result
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table_data
## X-squared = 320.36, df = 1, p-value < 2.2e-16

Qua kết quả kiểm định: Với mức ý nghĩa 0.05, vì p-value = 2.2e-16 < 0.05, bác bỏ giả thuyết \(H_0\). Vậy giữa biến Churn và biến InternetService tồn tại mối quan hệ.

3.3.5.2 Khoảng ước lượng tỷ lệ

Ước lượng tỷ lệ rời bỏ dịch vụ của nhóm khách hàng sử dụng dịch vụ Fiber optic

Trong phần này, tác giả sử dụng kiểm định tỷ lệ một mẫu (1-sample proportion test) để ước lượng tỷ lệ khách hàng rời bỏ dịch vụ trong nhóm sử dụng dịch vụ Fiber optic, đồng thời so sánh với tỷ lệ giả định là 50% (p = 0.5). Phương pháp này giúp xác định xem tỷ lệ rời bỏ dịch vụ của nhóm sử dụng dịch vụ Fiber optic có khác biệt đáng kể so với tỷ lệ giả định hay không.

prop.test(x = table_data["Fiber optic", "Yes"], n = sum( table_data["Fiber optic", ]), p = 0.5, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  table_data["Fiber optic", "Yes"] out of sum(table_data["Fiber optic", ]), null probability 0.5
## X-squared = 81.073, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.4014989 0.4365592
## sample estimates:
##         p 
## 0.4189276

Kết quả kiểm định tỷ lệ một mẫu cho thấy tỷ lệ rời bỏ dịch vụ (Churn) của nhóm khách hàng sử dụng Fiber optic được ước lượng khoảng 41,89% (p = 0.4189). Khoảng tin cậy 95% cho tỷ lệ này nằm trong khoảng 40,15% đến 43,66%, nghĩa là tỷ lệ thực sự của tổng thể gần như chắc chắn nằm trong khoảng này. Giá trị p-value < 2.2e-16 cho thấy sự khác biệt giữa tỷ lệ ước lượng và giá trị giả thuyết 0.5 (50%) là có ý nghĩa thống kê, tức là tỷ lệ rời bỏ của Fiber optic thấp hơn đáng kể 50%. Kết quả này phản ánh rằng cứ 10 khách hàng Fiber optic thì có khoảng 4 người rời bỏ dịch vụ.

Ước lượng tỷ lệ rời bỏ dịch vụ của nhóm khách hàng sử dụng dịch vụ DSL

Phần này nhằm xác định tỷ lệ khách hàng rời bỏ dịch vụ trong nhóm sử dụng DSL, đồng thời so sánh tỷ lệ ước lượng với mức giả thuyết 50% để kiểm tra ý nghĩa thống kê.

prop.test(x = table_data["DSL", "Yes"], n = sum( table_data["DSL", ]), p = 0.5, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  table_data["DSL", "Yes"] out of sum(table_data["DSL", ]), null probability 0.5
## X-squared = 771.11, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.1494167 0.1850296
## sample estimates:
##         p 
## 0.1664747

Kết quả kiểm định tỷ lệ một mẫu cho thấy tỷ lệ rời bỏ dịch vụ (Churn) của nhóm khách hàng sử dụng DSL được ước lượng khoảng 16,65% (p = 0.1665). Khoảng tin cậy 95% cho tỷ lệ này nằm trong khoảng 14,94% đến 18,50%, cho thấy tỷ lệ thực tế của tổng thể chắc chắn thấp hơn 20%. Giá trị p-value < 2.2e-16 khẳng định sự khác biệt giữa tỷ lệ ước lượng và mức giả thuyết 50% là có ý nghĩa thống kê rất cao. Như vậy, tỷ lệ rời bỏ dịch vụ của khách hàng DSL thấp hơn nhiều so với 50%, điều này thể hiện mức độ gắn bó cao hơn của nhóm này.

3.3.6 Mô hình hồi quy cho dữ liệu nhị phân

3.3.6.1 Mô hình logit

Để phân tích mối quan hệ giữa các dịch vụ internet (InternetService) và khách hàng rời bỏ dịch vụ (Churn), tác giả sử dụng mô hình hồi quy logistic nhị phân (logit model). Mô hình này cho phép ước lượng xác suất rời bỏ dịch vụ thông qua hàm logit, giúp xác định mức độ ảnh hưởng của từng loại dịch vụ internet đến hành vi rời bỏ của khách hàng.

log2 <- glm(factor(Churn) ~InternetService, data = vienthong, family = binomial(link = 'logit'))
summary(log2)
## 
## Call:
## glm(formula = factor(Churn) ~ InternetService, family = binomial(link = "logit"), 
##     data = vienthong)
## 
## Coefficients:
##                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                -1.61082    0.06443  -25.00   <2e-16 ***
## InternetServiceFiber optic  1.28364    0.07401   17.34   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 5773.5  on 4830  degrees of freedom
## AIC: 5777.5
## 
## Number of Fisher Scoring iterations: 4

Ta có mô hình hồi quy như sau:

\[ \log\left( \frac{P(\text{Churn} = \text{"Yes"})}{1 - P(\text{Churn} = \text{"Yes"})} \right) = -1.61082 + 1.28364 \cdot \text{InternetServiceFiber optic} \]

Kết quả ước lượng từ mô hình logit cho thấy hệ số chặn \(-1.61082\) và hệ số của biến InternetServiceFiber optic \(1.28364\) đều có ý nghĩa thống kê cao (p < 0.001). Điều này chứng tỏ loại hình dịch vụ internet có ảnh hưởng đáng kể đến xác suất rời bỏ dịch vụ của khách hàng. Hệ số dương của Fiber optic cho thấy khách hàng dùng dịch vụ này có khả năng rời bỏ cao hơn so với nhóm DSL (nhóm tham chiếu), với tỷ lệ khả năng xảy ra rời bỏ cao gấp \(e^{1.28364} \approx 3.61\) lần.

ta có xác suất rời bỏ của nhóm DSL: \[ p_{DSL} = \frac{e^{-1.61082}}{1 + e^{-1.61082}} \approx 0.166 \, (16.6\%), \] nghĩa là trung bình cứ 100 khách hàng DSL thì khoảng 17 khách sẽ rời bỏ dịch vụ. Với nhóm Fiber optic, logit là \(-1.61082 + 1.28364 = -0.32718\), nên: \[ p_{Fiber} = \frac{e^{-0.32718}}{1 + e^{-0.32718}} \approx 0.428 \, (42.8\%), \] tức là khoảng 43 trên 100 khách hàng Fiber optic có khả năng rời bỏ dịch vụ. Chỉ số AIC = 5777.5 cho thấy mô hình có độ phù hợp chấp nhận được với dữ liệu.

3.3.6.2 Mô hình probit

pro2 <- glm(factor(Churn) ~ InternetService, data = vienthong, family = binomial(link = 'probit'))
summary(pro2 )
## 
## Call:
## glm(formula = factor(Churn) ~ InternetService, family = binomial(link = "probit"), 
##     data = vienthong)
## 
## Coefficients:
##                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                -0.96819    0.03581  -27.04   <2e-16 ***
## InternetServiceFiber optic  0.76355    0.04240   18.01   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 5773.5  on 4830  degrees of freedom
## AIC: 5777.5
## 
## Number of Fisher Scoring iterations: 3

Ta có mô hình hồi quy như sau:

\[ P(\text{Churn} = Yes) = \Phi \big( -0.96819 + 0.76355 \cdot \text{InternetServiceFiber optic}) \]

Kết quả mô hình Probit cho thấy hệ số chặn -0.96819 và hệ số của biến InternetServiceFiber optic 0.76355 đều có ý nghĩa thống kê rất cao (p < 0.001), chứng tỏ loại hình dịch vụ internet ảnh hưởng mạnh đến khả năng rời bỏ dịch vụ. Hệ số dương của Fiber optic cho thấy khách hàng sử dụng dịch vụ này có xu hướng rời bỏ cao hơn nhóm DSL (nhóm tham chiếu). Dựa trên công thức: \[ p = \Phi(\beta_0 + \beta_1 X), \] xác suất rời bỏ của nhóm DSL là: \[ p_{DSL} = \Phi(-0.96819) \approx 0.166 \, (16.6\%), \] nghĩa là cứ 100 khách hàng DSL thì khoảng 17 người rời bỏ dịch vụ. Đối với nhóm Fiber optic, xác suất rời bỏ là: \[ p_{Fiber} = \Phi(-0.96819 + 0.76355) \approx 0.419 \, (41.9\%), \] tức gần 42 khách trên 100 có khả năng rời bỏ. Sự khác biệt này cho thấy Fiber optic làm tăng khả năng rời bỏ lên khoảng 2.5 lần so với DSL.

3.3.6.3 Mô hình cloglog

Để phân tích tác động của loại hình dịch vụ internet (InternetService) đến khả năng rời bỏ dịch vụ (Churn), tác giả sử dụng mô hình hồi quy nhị phân với hàm liên kết Complementary log-log (Cloglog).

clo2 <- glm(factor(Churn) ~ InternetService, data = vienthong, family = binomial(link = 'cloglog'))
summary(clo2)
## 
## Call:
## glm(formula = factor(Churn) ~ InternetService, family = binomial(link = "cloglog"), 
##     data = vienthong)
## 
## Coefficients:
##                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                -1.70325    0.05890  -28.91   <2e-16 ***
## InternetServiceFiber optic  1.09238    0.06527   16.74   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 5773.5  on 4830  degrees of freedom
## AIC: 5777.5
## 
## Number of Fisher Scoring iterations: 5

Mô hình Cloglog được sử dụng để phân tích mối quan hệ giữa loại dịch vụ internet và khả năng rời bỏ dịch vụ, với phương trình:

\[ \log \left[ -\log (1-p) \right] = -1.70325 + 1.09238 \cdot \text{InternetService\_Fiber\_optic} \] Kết quả cho thấy hệ số chặn \(-1.70325\) và hệ số InternetServiceFiber optic \(1.09238\) đều có ý nghĩa thống kê (p < 0.001), chứng tỏ loại dịch vụ internet ảnh hưởng mạnh đến hành vi rời bỏ. Dựa trên công thức \(p = 1 - \exp[-\exp(\eta)]\), xác suất rời bỏ của nhóm DSL là \(p_{DSL} \approx 0.166\) (16.6%), trong khi nhóm Fiber optic có xác suất \(p_{Fiber} \approx 0.422\) (42.2%). Điều này cho thấy khách hàng Fiber optic có khả năng rời bỏ cao gấp hơn 2.5 lần so với DSL.

3.3.7 Đánh giá mô hình

Sau khi tiến hành ước lượng ba mô hình hồi quy nhị phân gồm logit, probit và cloglog, bước tiếp theo là đánh giá và so sánh mức độ phù hợp của các mô hình này. Việc đánh giá được thực hiện dựa trên các chỉ tiêu thống kê như giá trị AIC, hệ số Brier Score và ma trận nhầm lẫn. Ngoài ra, khả năng dự báo xác suất của từng mô hình đối với các trường hợp giả định cụ thể cũng được xem xét để lựa chọn mô hình phù hợp nhất.

# Tạo bảng so sánh
model_eval1 <- data.frame(
  Mô_hình = c("Logit", "Probit", "Cloglog"),
  AIC = c(AIC(log2), AIC(pro2), AIC(clo2)),
  BIC = c(BIC(log2), BIC(pro2), BIC(clo2)),
  Brier_Score = c(BrierScore(log2), BrierScore(pro2), BrierScore(clo2))
)
kable(model_eval1, align = "c", caption = "So sánh các chỉ số đánh giá mô hình") %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14)
So sánh các chỉ số đánh giá mô hình
Mô_hình AIC BIC Brier_Score
Logit 5777.485 5790.451 0.2058236
Probit 5777.485 5790.451 0.2058236
Cloglog 5777.485 5790.451 0.2058236

Dựa trên kết quả so sánh các chỉ số đánh giá mô hình, cả ba mô hình logit, probit và cloglog đều cho ra giá trị AIC (5777.485), BIC (5790.451) và Brier Score (0.2058236) giống nhau. Điều này cho thấy mức độ phù hợp của các mô hình là tương đương và khả năng dự báo xác suất đúng không có sự khác biệt đáng kể.

Ma trận nhầm lẫn

  • Mô hình logit
pred_logitlog <- ifelse(predict(log2, type = "response") >= 0.5, "Yes", "No")
actuallog <- vienthong$Churn
cm_logitlog <- confusionMatrix(factor(pred_logitlog), actuallog, positive = "Yes")
cm_logitlog
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 
  • Mô hình probit
pred_logitpro <- ifelse(predict(pro2, type = "response") >= 0.5, "Yes", "No")
actualpro <- vienthong$Churn
cm_logitpro <- confusionMatrix(factor(pred_logitpro), actualpro, positive = "Yes")
cm_logitpro
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 
  • Mô hình cloglog
pred_logitclo <- ifelse(predict(clo2, type = "response") >= 0.5, "Yes", "No")
actualclo <- vienthong$Churn
cm_logitclo <- confusionMatrix(factor(pred_logitclo), actualclo, positive = "Yes")
cm_logitclo
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 

Ma trận nhầm lẫn cho thấy cả ba mô hình logit, probit và cloglog đều không dự đoán đúng được bất kỳ trường hợp khách hàng rời bỏ dịch vụ nào, với TP = 0. Đồng thời, FP = 0 cho thấy không có trường hợp khách hàng ở nhóm “No” nào bị dự đoán nhầm thành “Yes”, nhưng điều này phản ánh mô hình không hề đưa ra dự đoán “Yes”. Ngược lại, FN = 1586 cho thấy toàn bộ khách hàng rời bỏ dịch vụ đều bị phân loại sai thành “No”, dẫn đến độ nhạy (Sensitivity) bằng 0. Trong khi đó, TN = 3246 cho thấy toàn bộ khách hàng không rời bỏ dịch vụ được dự đoán chính xác, làm Specificity đạt 100%. Kết quả này cho thấy mô hình bị lệch hẳn về nhóm đa số “No”. Mặc dù độ chính xác tổng thể đạt 67,18%, nhưng điều này không phản ánh đúng hiệu quả phân loại.

3.4 Phân tích sự tác động độ tuổi đến việc khách hàng rời bỏ dịch vụ

3.4.1 Thống kê mô tả biến độ tuổi

Để phân tích tác động của độ tuổi (SeniorCitizen) đến khả năng khách hàng rời bỏ dịch vụ (Churn), trước tiên ta tiến hành thống kê mô tả biến SeniorCitizen trong bộ dữ liệu. Thống kê này cho biết tỷ lệ khách hàng thuộc nhóm người cao tuổi so với nhóm còn lại, từ đó hỗ trợ việc nhận định ban đầu về mối quan hệ giữa độ tuổi và hành vi rời bỏ dịch vụ.

s<-table(vienthong$SeniorCitizen) 
# Chuyển thành data frame với 3 cột: Churn | Số lượng | Sum (Tổng cộng)
dfs <- data.frame(
   SeniorCitizen= c("No", "Yes"),
  So_luong = as.numeric(s))
# In ra bảng đẹp, căn giữa
kable(dfs, align = "c", col.names = c("SeniorCitizen", "Số lượng"))  %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14) %>%
  column_spec(1, width = "4cm") %>%  # Độ rộng cột 1
  column_spec(2, width = "3cm")      # Độ rộng cột 2
SeniorCitizen Số lượng
No 3846
Yes 986
# Tạo bảng tần số cho biến type
s <- as.data.frame(table(vienthong$SeniorCitizen) )
colnames(s) <- c("SeniorCitizen", "Count")

# Đổi 0/1 thành No/Yes
s$SeniorCitizen <- ifelse(s$SeniorCitizen == "0", "No", "Yes")

# Vẽ biểu đồ
ggplot(s, aes(x = SeniorCitizen, y = Count, fill = SeniorCitizen)) +
  geom_bar(stat = "identity", width = 0.5) +
  geom_text(aes(label = Count), vjust = -0.5, size = 3.5) +  # Hiển thị số liệu bên trên cột
  labs(title = "Đồ thị về độ tuổi cao của khách hàng", 
       x = "SeniorCitizen", y = "Frequency") +
  theme_minimal()

Ngoài ra tác giả sẽ thực hiện tính tỷ lệ phần trăm cho từng nhóm và vẽ đồ thị cột của chúng để so sánh theo số liệu tương đối.

prop.table(table(vienthong$SeniorCitizen))*100
## 
##        0        1 
## 79.59437 20.40563
s$Percentage <- (s$Count / sum(s$Count)) * 100

ggplot(s, aes(x = "", y = Percentage, fill = SeniorCitizen)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Biểu đồ cho thấy nhóm không cao tuổi (No) chiếm khoảng 79,6% tổng số khách hàng (3.846/4.832), trong khi nhóm cao tuổi (Yes) chỉ chiếm khoảng 20,4% (986/4.832). Sự chênh lệch lớn này cho thấy cơ sở khách hàng chủ yếu thuộc nhóm không cao tuổi. Điều này có thể hàm ý rằng các chiến lược chăm sóc và giữ chân khách hàng nên tập trung nhiều hơn vào nhóm này để tối ưu hiệu quả kinh doanh. Tuy nhiên, nhóm khách hàng cao tuổi tuy chiếm tỷ lệ nhỏ nhưng có thể có nhu cầu và hành vi khác biệt, đòi hỏi doanh nghiệp cần các chính sách chăm sóc chuyên biệt để tránh rủi ro rời bỏ dịch vụ trong nhóm khách hàng tiềm ẩn này.

*3.4.2 Thống kê mô tả cho hai biến khách hàng rời bỏ dịch vụ và độ tuổi khách hàng**

Trong phần này, tác giả tiến hành thống kê mô tả hai biến quan trọng là Churn (khách hàng rời bỏ dịch vụ) và SeniorCitizen (độ tuổi cao của khách hàng). Việc phân tích tần suất và tỷ lệ của hai biến này giúp nhận diện sự phân bố của tập khách hàng theo hành vi rời bỏ dịch vụ cũng như yếu tố tuổi tác. Qua đó, chúng ta có thể đánh giá được mức độ chênh lệch giữa nhóm khách hàng cao tuổi và không cao tuổi, đồng thời quan sát mối liên hệ sơ bộ giữa độ tuổi và khả năng rời bỏ dịch vụ, làm cơ sở cho các phân tích hồi quy ở các phần tiếp theo.

table(vienthong$SeniorCitizen, vienthong$Churn) %>%  addmargins()
##      
##         No  Yes  Sum
##   0   2687 1159 3846
##   1    559  427  986
##   Sum 3246 1586 4832
table_data <- table(vienthong$SeniorCitizen, vienthong$Churn)

# Chuyển bảng chéo sang định dạng dài
long_data3 <- as.data.frame(table_data)
colnames(long_data3) <- c("SeniorCitizen", "Churn", "count")

# Vẽ biểu đồ cột
ggplot(long_data3, aes(x = Churn, y = count, fill = Churn)) +
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_text(aes(label = count), vjust = 1, size = 2.5, position = position_dodge(1)) +
  facet_wrap(~ SeniorCitizen, scales = "free_y", nrow = 2) +
  labs(title = "Phân bố khách hàng rời bỏ dịch vụ theo độ tuổi của khách hàng",
       x = "Khách hàng rời bỏ hợp đồng",
       y = "Độ tuổi của khách hàng",
       fill = "Khách hàng rời bỏ hợp đồng") +
  theme_minimal()  

Biểu đồ cho thấy sự phân bố khách hàng rời bỏ dịch vụ theo độ tuổi. Trong tổng số khách hàng không cao tuổi (SeniorCitizen = No), có 2.687 khách hàng không rời bỏ dịch vụ và 1.159 khách hàng rời bỏ dịch vụ. Trong khi đó, nhóm khách hàng cao tuổi (SeniorCitizen = Yes) có 559 khách hàng không rời bỏ dịch vụ và 427 khách hàng rời bỏ dịch vụ. Điều này cho thấy tỷ lệ rời bỏ dịch vụ của nhóm cao tuổi (≈ 43,3%) cao hơn đáng kể so với nhóm không cao tuổi (≈ 30,1%), chứng tỏ yếu tố tuổi tác có thể liên quan đến hành vi rời bỏ dịch vụ.

Để minh họa trực quan độ tuổi của khách hàng, tôi tiến hành vẽ biểu đồ cột thể hiện số lượng từng giá trị của nhóm SeniorCitizen.

table_data3 <- round(prop.table(table_data)*100,2) 
table_data3
##    
##        No   Yes
##   0 55.61 23.99
##   1 11.57  8.84
# Chuyển đổi dữ liệu thành dạng dài để dễ vẽ biểu đồ
table_data3 <- as.data.frame.table(table_data3)
colnames(table_data3) <- c("Group", "Level", "Percentage")

# Vẽ biểu đồ
ggplot(table_data3, aes(x = Level, y = Percentage, fill = Level)) +
  geom_bar(stat = "identity", position = "dodge") +
  geom_text(aes(label = Percentage), vjust = 1, size = 2.5, position = position_dodge(1)) +
  facet_wrap(~ Group, scales = "free_y", nrow = 2) +
  labs(title = "Đồ thị phần trăm theo biểu hiện yes, no của khách hàng từ bỏ dịch vụ và các loại hợp đồng",
       x = "Các loại hợp đồng",
       y = "Phần trăm",
       fill = "Biểu hiện") +
  scale_fill_manual(values = c("No" = "skyblue", "Yes" = "pink")) + 
  theme_minimal()

Biểu đồ minh họa tỷ lệ phần trăm rời bỏ dịch vụ giữa hai nhóm. Với nhóm không cao tuổi, tỷ lệ khách hàng duy trì dịch vụ (No) là 33,67%, trong khi tỷ lệ rời bỏ dịch vụ (Yes) là 22,56%. Ngược lại, trong nhóm cao tuổi, tỷ lệ duy trì dịch vụ chỉ đạt 33,51%, còn tỷ lệ rời bỏ là 10,26%. Nhìn chung, kết quả thống kê này cho thấy nhóm khách hàng cao tuổi có xu hướng rời bỏ dịch vụ nhiều hơn, là một chỉ báo quan trọng cần xem xét trong các mô hình phân tích Churn.

3.4.3 Phân tích Relative Risk giữa độ tuổi cao của khách hàng và khách hàng rời bỏ dịch vụ

Trong phần này, chỉ số Relative Risk (RR) được sử dụng để so sánh mức độ rủi ro rời bỏ dịch vụ giữa hai nhóm khách hàng: nhóm cao tuổi (SeniorCitizen = Yes) và nhóm không cao tuổi (SeniorCitizen = No

rr4<- riskratio(table_data)
rr4
## $data
##        
##           No  Yes Total
##   0     2687 1159  3846
##   1      559  427   986
##   Total 3246 1586  4832
## 
## $measure
##    risk ratio with 95% C.I.
##     estimate   lower    upper
##   0 1.000000      NA       NA
##   1 1.437066 1.31849 1.566306
## 
## $p.value
##    two-sided
##       midp.exact fisher.exact   chi.square
##   0           NA           NA           NA
##   1 1.065814e-14 1.273297e-14 3.908703e-15
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Bảng kết quả cho thấy Relative Risk (RR) của nhóm khách hàng cao tuổi (Yes) là 1.437. Điều này có nghĩa là khả năng rời bỏ dịch vụ của nhóm khách hàng cao tuổi cao gấp 1.437 lần so với nhóm khách hàng không cao tuổi.Nói cách khác, nhóm khách hàng cao tuổi có nguy cơ rời bỏ dịch vụ cao hơn đáng kể. Giá trị p-value của kiểm định Chi-square là 3.908703e-15, rất nhỏ (p < 0.001), chứng tỏ sự khác biệt giữa hai nhóm là có ý nghĩa thống kê. Điều này cho thấy biến SeniorCitizen có ảnh hưởng rõ rệt đến hành vi rời bỏ dịch vụ, và nhóm khách hàng cao tuổi là nhóm rời bỏ dịch vụ hơn.

3.4.4 Phân tích Odd Ratio giữa độ tuổi của khách hàng và khách hàng rời bỏ dịch vụ

Trong phần này, nghiên cứu sẽ tiến hành tính Odds Ratio giữa độ tuổi của khách hàng và biến khách hàng rời bỏ dịch vụ viễn thông (Churn). Việc tính toán OR sẽ giúp xác định độ tuổi nào làm tăng hoặc giảm khả năng rời bỏ dịch vụ, qua đó cung cấp thông tin quan trọng để doanh nghiệp đưa ra các chiến lược giữ chân khách hàng phù hợp.

or4 <- oddsratio(table_data)
or4
## $data
##        
##           No  Yes Total
##   0     2687 1159  3846
##   1      559  427   986
##   Total 3246 1586  4832
## 
## $measure
##    odds ratio with 95% C.I.
##     estimate    lower   upper
##   0 1.000000       NA      NA
##   1 1.770814 1.533554 2.04393
## 
## $p.value
##    two-sided
##       midp.exact fisher.exact   chi.square
##   0           NA           NA           NA
##   1 1.065814e-14 1.273297e-14 3.908703e-15
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Kết quả phân tích cho thấy Odds Ratio (OR) của nhóm khách hàng cao tuổi (1) là 1.77. Điều này có nghĩa là odds rời bỏ dịch vụ của khách hàng cao tuổi cao hơn khoảng 1.77 lần so với nhóm khách hàng không cao tuổi. Giá trị p-value rất nhỏ (p < 0.001), khẳng định sự khác biệt này có ý nghĩa thống kê. Nói cách khác, việc thuộc nhóm khách hàng cao tuổi làm tăng khả năng rời bỏ dịch vụ, và biến SeniorCitizen là một yếu tố đáng chú ý trong việc dự đoán hành vi khách hàng.

3.4.5 Thống kê suy diễn

3.4.5.1 Kiểm định tính độc lập

Để kiểm tra xem biến độ tuổi cao của khách hàng () và hành vi rời bỏ dịch vụ (Churn) có mối liên hệ với nhau hay không, nghiên cứu áp dụng kiểm định Chi-square.

Kiểm định này được thiết lập với giả thuyết:

\[ \left\{ \begin{array}{ll} H_0: & \text{Biến Churn (khách hàng từ bỏ dịch vụ) và biến SeniorCitizen (độ tuổi cao) không có mối quan hệ với nhau.} \\\\ H_1: & \text{Biến Churn (khách hàng từ bỏ dịch vụ) và biến SeniorCitizen (độ tuổi caot) có mối quan hệ với nhau.} \ \end{array} \right. \]

# Kiểm định
chisq_result <- chisq.test(table_data)

# In kết quả
chisq_result
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table_data
## X-squared = 61.149, df = 1, p-value = 5.29e-15

Qua kết quả kiểm định: Với mức ý nghĩa 0.05, vì p-value = 5.29e-15 < 0.05, bác bỏ giả thuyết \(H_0\). Vậy giữa biến Churn và biến SeniorCitizen tồn tại mối quan hệ.

3.4.5.2 Khoảng ước lượng tỷ lệ

Ước lượng tỷ lệ rời bỏ dịch vụ của nhóm khách hàng có độ tuổi cao

prop.test(x = table_data["1", "Yes"], n = sum( table_data["1", ]), p = 0.5, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  table_data["1", "Yes"] out of sum(table_data["1", ]), null probability 0.5
## X-squared = 17.405, df = 1, p-value = 3.021e-05
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.4019527 0.4647011
## sample estimates:
##         p 
## 0.4330629

Kết quả kiểm định tỷ lệ một mẫu cho thấy tỷ lệ rời bỏ dịch vụ (Churn) của nhóm khách hàng cao tuổi được ước lượng khoảng 43.30%. Khoảng tin cậy 95% cho tỷ lệ này nằm trong khoảng 40,19% đến 46.47%, nghĩa là tỷ lệ thực sự của tổng thể gần như chắc chắn nằm trong khoảng này. Giá trị p-value = 3.021e-05 cho thấy sự khác biệt giữa tỷ lệ ước lượng và giá trị giả thuyết 0.5 (50%) là có ý nghĩa thống kê, tức là tỷ lệ rời bỏ của khách hàng cao tuổi thấp hơn đáng kể 50%. Kết quả này phản ánh rằng cứ 10 khách hàng cao tuổi thì có khoảng 4 người rời bỏ dịch vụ.

prop.test(x = table_data["0", "Yes"], n = sum( table_data["0", ]), p = 0.5, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  table_data["0", "Yes"] out of sum(table_data["0", ]), null probability 0.5
## X-squared = 606.27, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.2869267 0.3161774
## sample estimates:
##         p 
## 0.3013521

Kết quả kiểm định tỷ lệ một mẫu cho thấy tỷ lệ rời bỏ dịch vụ (Churn) của nhóm khách hàng không cao tuổi được ước lượng khoảng 30.14%. Khoảng tin cậy 95% cho tỷ lệ này nằm trong khoảng 28.69% đến 31.62%, nghĩa là tỷ lệ thực sự của tổng thể gần như chắc chắn nằm trong khoảng này. Giá trị p-value < 2.2e-16 cho thấy sự khác biệt giữa tỷ lệ ước lượng và giá trị giả thuyết 0.5 (50%) là có ý nghĩa thống kê, tức là tỷ lệ rời bỏ của khách hàng không cao tuổi thấp hơn đáng kể 50%. Kết quả này phản ánh rằng cứ 10 khách hàng không cao tuổi thì có khoảng 3 người rời bỏ dịch vụ.

3.4.6 Mô hình hồi quy cho dữ liệu nhị phân

3.4.6.1 Mô hình logit

log5 <- glm(factor(Churn) ~SeniorCitizen, data = vienthong, family = binomial(link = 'logit'))
summary(log5)
## 
## Call:
## glm(formula = factor(Churn) ~ SeniorCitizen, family = binomial(link = "logit"), 
##     data = vienthong)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)   -0.84087    0.03514 -23.928  < 2e-16 ***
## SeniorCitizen  0.57150    0.07325   7.802  6.1e-15 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 6056.7  on 4830  degrees of freedom
## AIC: 6060.7
## 
## Number of Fisher Scoring iterations: 4

Kết quả mô hình logit cho thấy hệ số chặn \(-0.84087\) và hệ số của biến SeniorCitizen \(0.57150\) đều có ý nghĩa thống kê rất cao (p < 0.001). Hệ số dương của SeniorCitizen chỉ ra rằng khách hàng lớn tuổi (SeniorCitizen = 1) có khả năng rời bỏ dịch vụ cao hơn nhóm khách hàng trẻ (SeniorCitizen = 0). Tỷ lệ khả năng rời bỏ của nhóm khách hàng lớn tuổi cao hơn khoảng: \[ e^{0.57150} \approx 1.77 \, \text{lần}. \]

Dựa trên công thức xác suất: \[ p = \frac{e^{\eta}}{1 + e^{\eta}}, \] ta tính được xác suất rời bỏ của nhóm khách hàng trẻ: \[ p_{0} = \frac{e^{-0.84087}}{1 + e^{-0.84087}} \approx 0.301 \, (30.1\%), \] và của nhóm khách hàng lớn tuổi: \[ p_{1} = \frac{e^{-0.84087 + 0.57150}}{1 + e^{-0.84087 + 0.57150}} \approx 0.430 \, (43.0\%). \]

3.4.6.2 Mô hình probit

pro5<- glm(factor(Churn) ~ SeniorCitizen, data = vienthong, family = binomial(link = 'probit'))
summary(pro5 )
## 
## Call:
## glm(formula = factor(Churn) ~ SeniorCitizen, family = binomial(link = "probit"), 
##     data = vienthong)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)   -0.52052    0.02124 -24.510  < 2e-16 ***
## SeniorCitizen  0.35193    0.04539   7.753 8.99e-15 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 6056.7  on 4830  degrees of freedom
## AIC: 6060.7
## 
## Number of Fisher Scoring iterations: 4

Kết quả ước lượng mô hình Probit cho thấy biến SeniorCitizen có ảnh hưởng đáng kể đến khả năng khách hàng rời bỏ dịch vụ (Churn). Phương trình mô hình được mô tả như sau:

\[ P(Y=1|SeniorCitizen) = \Phi(-0.52052 + 0.35193 \cdot SeniorCitizen), \]

trong đó \(\Phi(\cdot)\) là hàm phân phối tích lũy chuẩn chuẩn hóa. Khi khách hàng không phải là người cao tuổi (SeniorCitizen = 0), giá trị tuyến tính là \(z = -0.52052\) và xác suất rời bỏ dịch vụ là:

\[ P(Y=1 | SeniorCitizen = 0) = \Phi(-0.52052) \approx 0.301 \ (30.1\%). \]

Ngược lại, khi khách hàng là người cao tuổi (SeniorCitizen = 1), giá trị \(z = -0.52052 + 0.35193 = -0.16859\), và xác suất rời bỏ dịch vụ tăng lên:

\[ P(Y=1 | SeniorCitizen = 1) = \Phi(-0.16859) \approx 0.433 \ (43.3\%). \]

Khách hàng là người cao tuổi (SeniorCitizen = 1) có xác suất rời bỏ dịch vụ cao hơn (43.3%) so với khách hàng không phải người cao tuổi (30.1%). Điều này cho thấy nhóm khách hàng cao tuổi có mức độ rủi ro rời bỏ dịch vụ cao hơn đáng kể.

3.4.6.3 Mô hình cloglog

clo5 <- glm(factor(Churn) ~ SeniorCitizen, data = vienthong, family = binomial(link = 'cloglog'))
summary(clo5)
## 
## Call:
## glm(formula = factor(Churn) ~ SeniorCitizen, family = binomial(link = "cloglog"), 
##     data = vienthong)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)   -1.02552    0.02953 -34.727  < 2e-16 ***
## SeniorCitizen  0.45902    0.05725   8.018 1.08e-15 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 6056.7  on 4830  degrees of freedom
## AIC: 6060.7
## 
## Number of Fisher Scoring iterations: 5

Kết quả ước lượng mô hình Complementary Log-Log (cloglog) cho thấy biến SeniorCitizen có ảnh hưởng đáng kể đến khả năng khách hàng rời bỏ dịch vụ Churn với mức ý nghĩa thống kê rất cao (\(p = 1.08e-15\)). Phương trình mô hình được xác định như sau:

\[ \ln[-\ln(1 - P(Y=1|SeniorCitizen))] = -1.02552 + 0.45902 \cdot SeniorCitizen. \] Khi khách hàng không phải là người cao tuổi (SeniorCitizen = 0), giá trị tuyến tính là \(\eta = -1.02552\) và xác suất rời bỏ dịch vụ là: \[ P(Y=1|SeniorCitizen=0) = 1 - \exp[-\exp(-1.02552)] \approx 0.266 \ (26.6\%). \] Trong khi đó, nếu khách hàng là người cao tuổi (SeniorCitizen = 1), giá trị \(\eta\) tăng lên \(-0.56650\) và xác suất rời bỏ dịch vụ tăng lên: \[ P(Y=1|SeniorCitizen=1) = 1 - \exp[-\exp(-0.56650)] \approx 0.368 \ (36.8\%). \] Hệ số dương \(0.45902\) khẳng định nhóm khách hàng cao tuổi có khả năng rời bỏ dịch vụ cao hơn so với nhóm khách hàng trẻ. Nhìn chung, kết quả này cho thấy biến SeniorCitizen là yếu tố quan trọng trong việc dự đoán khả năng rời bỏ dịch vụ, và mô hình cloglog phù hợp khi xác suất sự kiện không đối xứng.

3.4.7 Đánh giá mô hình

Sau khi tiến hành ước lượng ba mô hình hồi quy nhị phân gồm logit, probit và cloglog, bước tiếp theo là đánh giá và so sánh mức độ phù hợp của các mô hình này. Việc đánh giá được thực hiện dựa trên các chỉ tiêu thống kê như giá trị AIC, BIC, hệ số Brier Score và ma trận nhầm lẫn. Ngoài ra, khả năng dự báo xác suất của từng mô hình đối với các trường hợp giả định cụ thể cũng được xem xét để lựa chọn mô hình phù hợp nhất.

# Tạo bảng so sánh
model_eval4<- data.frame(
  Mô_hình = c("Logit", "Probit", "Cloglog"),
  AIC = c(AIC(log5), AIC(pro5), AIC(clo5)),
  BIC = c(BIC(log5), BIC(pro5), BIC(clo5)),
  Brier_Score = c(BrierScore(log5), BrierScore(pro5), BrierScore(clo5))
)
kable(model_eval4, align = "c", caption = "So sánh các chỉ số đánh giá mô hình") %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14)
So sánh các chỉ số đánh giá mô hình
Mô_hình AIC BIC Brier_Score
Logit 6060.708 6073.674 0.217677
Probit 6060.708 6073.674 0.217677
Cloglog 6060.708 6073.674 0.217677

Sau khi ước lượng ba mô hình logit, probit và cloglog, kết quả cho thấy các chỉ số AIC, BIC và Brier Score của ba mô hình hoàn toàn giống nhau (AIC = 6060.708, BIC = 6073.674, Brier Score = 0.2177), phản ánh mức độ phù hợp về mặt thống kê tương đương.

Ma trận nhầm lẫn

  • Mô hình logit
pred_logitlog <- ifelse(predict(log5, type = "response") >= 0.5, "Yes", "No")
actuallog <- vienthong$Churn
cm_logitlog <- confusionMatrix(factor(pred_logitlog), actuallog, positive = "Yes")
cm_logitlog
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 
  • Mô hình probit
pred_logitpro <- ifelse(predict(pro5, type = "response") >= 0.5, "Yes", "No")
actualpro <- vienthong$Churn
cm_logitpro <- confusionMatrix(factor(pred_logitpro), actualpro, positive = "Yes")
cm_logitpro
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 
  • Mô hình cloglog
pred_logitclo <- ifelse(predict(clo5, type = "response") >= 0.5, "Yes", "No")
actualclo <- vienthong$Churn
cm_logitclo <- confusionMatrix(factor(pred_logitclo), actualclo, positive = "Yes")
cm_logitclo
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 

3.5 Phân tích sự tác động của khách hàng có người phụ thuộc đến việc khách hàng rời bỏ dịch vụ

3.5.1 Thống kê mô tả biến có người phụ thuộc (Dependents)

Biến Dependents phản ánh tình trạng khách hàng có hay không người phụ thuộc (con cái hoặc người cần chăm sóc). Thống kê mô tả dưới đây cho thấy phân bố số lượng khách hàng theo hai nhóm: có người phụ thuộc và không có người phụ thuộc, giúp nhận diện tỷ lệ khách hàng thuộc từng nhóm và làm cơ sở đánh giá sự khác biệt về khả năng rời bỏ dịch vụ giữa các nhóm này.

d<-table(vienthong$Dependents) 
d
## 
##   No  Yes 
## 3574 1258
# Chuyển thành data frame với 3 cột: Churn | Số lượng | Sum (Tổng cộng)
dfd <- data.frame(
   InternetService= c("No", "Yes"),
  So_luong = as.numeric(d))

# In ra bảng đẹp, căn giữa
kable(dfd, align = "c", col.names = c("Dependents", "Số lượng"))  %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14) %>%
  column_spec(1, width = "4cm") %>%  # Độ rộng cột 1
  column_spec(2, width = "3cm")      # Độ rộng cột 2
Dependents Số lượng
No 3574
Yes 1258
#lập bảng tần số của cột Churn trong bộ dữ liệu được tên vienthong và thêm cột tông vào cuối bảng

Để minh họa trực quan tình trạng khách hàng có hay không người phụ thuộc, tôi tiến hành vẽ biểu đồ cột thể hiện số lượng từng giá trị của nhóm Dependents.

# Tạo bảng tần số cho biến type
d <- as.data.frame(table(vienthong$Dependents) )
colnames(d) <- c("Dependents", "Count")

ggplot(d, aes(x = Dependents, y = Count, fill = Dependents)) +
  geom_bar(stat = "identity", width = 0.5) +
  geom_text(aes(label = Count), vjust = -0.5, size = 3.5) + # Hiển thị số liệu bên trên cột
  labs(title = "Đồ thị thể hiện tình trạng khách hàng có hay không người phụ thuộc ", x = "Dependents", y = "Frequency") +
  theme_minimal()

Trong tổng số khách hàng khảo sát, có 3574 khách hàng không có người phụ thuộc chiếm đa số so với 1258 khách hàng có người phụ thuộc. Số lượng khách hàng không có người phụ thuộc cao gấp gần 3 lần so với nhóm có người phụ thuộc, cho thấy phần lớn khách hàng trong mẫu dữ liệu là những người độc lập hoặc không có trách nhiệm chăm sóc con cái hay người khác.

Ngoài ra tác giả sẽ thực hiện tính tỷ lệ phần trăm cho từng nhóm và vẽ đồ thị tròn của chúng để so sánh theo số liệu tương đối.

# Thêm cột phần trăm
d$Percentage <- round(prop.table(table(vienthong$Dependents)) * 100, 2)
# BẢNG PHẦN TRĂM
kable(d, align = "c", col.names = c("Dependents", "Số lượng", "Phần trăm (%)")) %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14) %>%
  column_spec(1, width = "4cm") %>%
  column_spec(2, width = "3cm") %>%
  column_spec(3, width = "4cm")
Dependents Số lượng Phần trăm (%)
No 3574 73.97
Yes 1258 26.03
ggplot(d, aes(x = "", y = Percentage, fill = Dependents)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Biểu đồ tròn cho thấy có sự chênh lệch rõ rệt giữa hai nhóm khách hàng: nhóm không có người phụ thuộc (73,97%) cao gần gấp 3 lần so với nhóm có người phụ thuộc (26,03%). Điều này cho thấy khách hàng không có người phụ thuộc chiếm ưu thế vượt trội trong bộ dữ liệu, tạo nên sự khác biệt đáng kể về tỷ trọng giữa hai nhóm.

3.5.2 Thống kê mô tả cho hai biến khách hàng rời bỏ dịch vụ và tình trạng kkhách hàng có người phụ thuộc

Phần này trình bày thống kê mô tả của hai biến: biến khách hàng rời bỏ dịch vụ (Churn) và biến tình trạng khách hàng có người phụ thuộc (Dependents). Thống kê này giúp xác định tỷ lệ khách hàng vẫn duy trì dịch vụ hoặc đã rời bỏ, đồng thời cho thấy sự phân bố giữa nhóm khách hàng có và không có người phụ thuộc. Đây là cơ sở để phân tích xem tình trạng người phụ thuộc có ảnh hưởng đến hành vi rời bỏ dịch vụ hay không.

table(vienthong$Dependents, vienthong$Churn) %>%  addmargins()
##      
##         No  Yes  Sum
##   No  2263 1311 3574
##   Yes  983  275 1258
##   Sum 3246 1586 4832

Vẽ đồ thị cột phân theo b tình trạng khách hàng có người phụ thuộc (Dependents) để đánh giá số lượng khách hàng rời bỏ dịch vụ viễn thông trong từng nhóm.

table_data <- table(vienthong$Dependents, vienthong$Churn)

# Chuyển bảng chéo sang định dạng dài
long_data2 <- as.data.frame(table_data)
colnames(long_data2) <- c("Dependents", "Churn", "count")

# Vẽ biểu đồ cột
ggplot(long_data2, aes(x = Churn, y = count, fill = Churn)) +
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_text(aes(label = count), vjust = 1, size = 2.5, position = position_dodge(1)) +
  facet_wrap(~ Dependents, scales = "free_y", nrow = 2) +
  labs(title = "Phân bố khách hàng rời bỏ dịch vụ theo tình trạng có người phụ thuộc hay không",
       x = "Khách hàng rời bỏ hợp đồng",
       y = "Tình trạng có người phụ thuộc hay không",
       fill = "Khách hàng rời bỏ hợp đồng") +
  theme_minimal()  

Ngoài ra tác giả sẽ thực hiện tính tỷ lệ phần trăm cho 2 biến vẽ đồ thị cột của chúng để so sánh theo số liệu tương đối.

table_data2 <- round(prop.table(table_data)*100,2) 
table_data2
##      
##          No   Yes
##   No  46.83 27.13
##   Yes 20.34  5.69
# Chuyển đổi dữ liệu thành dạng dài để dễ vẽ biểu đồ
table_data2 <- as.data.frame.table(table_data2)
colnames(table_data2) <- c("Group", "Level", "Percentage")

# Vẽ biểu đồ
ggplot(table_data2, aes(x = Level, y = Percentage, fill = Level)) +
  geom_bar(stat = "identity", position = "dodge") +
  geom_text(aes(label = Percentage), vjust = 1, size = 2.5, position = position_dodge(1)) +
  facet_wrap(~ Group, scales = "free_y", nrow = 2) +
  labs(title = "Tỷ lệ khách hàng rời bỏ dịch vụ theo tình trạng người phụ thuộc",
       x = "Tình trạng người phụ thuộc",
       y = "Phần trăm",
       fill = "Biểu hiện") +
  scale_fill_manual(values = c("No" = "lightgreen", "Yes" = "lightpink")) + 
  theme_minimal()

Trong tổng số 4832 khách hàng, có 3574 khách hàng không có người phụ thuộc và 1258 khách hàng có người phụ thuộc. Trong nhóm không có người phụ thuộc, có 2263 khách hàng không rời bỏ dịch vụ (chiếm khoảng 63,3%) và 1311 khách hàng rời bỏ dịch vụ (36,7%). Trong khi đó, ở nhóm có người phụ thuộc, số lượng khách hàng không rời bỏ dịch vụ chiếm ưu thế rõ rệt với 983 khách hàng (78,1%), chỉ có 275 khách hàng rời bỏ dịch vụ (21,9%). Điều này cho thấy nhóm khách hàng có người phụ thuộc có xu hướng trung thành với dịch vụ hơn nhóm không có người phụ thuộc.

3.5.3 Phân tích Relative Risk giữa biến khách hàng rời bỏ dịch vụ và tình trạng kkhách hàng có người phụ thuộc

Trong phần tiếp theo, tác giả sẽ tiến hành tính toán chỉ số rủi ro tương đối (Relative Risk – RR) nhằm đánh giá mức độ ảnh hưởng của tình trạng kkhách hàng có người phụ thuộc đến khả năng khách hàng rời bỏ dịch vụ viễn thông.

rr2<- riskratio(table_data)
rr2
## $data
##        
##           No  Yes Total
##   No    2263 1311  3574
##   Yes    983  275  1258
##   Total 3246 1586  4832
## 
## $measure
##      risk ratio with 95% C.I.
##        estimate    lower     upper
##   No  1.0000000       NA        NA
##   Yes 0.5959419 0.532262 0.6672405
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact   chi.square
##   No          NA           NA           NA
##   Yes          0 6.794174e-23 6.075757e-22
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Kết quả chỉ số Relative Risk cho thấy nhóm khách hàng có người phụ thuộc có nguy cơ rời bỏ dịch vụ chỉ bằng 59,6% so với nhóm không có người phụ thuộc. Khoảng tin cậy 95% hoàn toàn nhỏ hơn 1 và giá trị p rất nhỏ (p < 0,0001), chứng tỏ sự khác biệt về nguy cơ rời bỏ dịch vụ giữa hai nhóm là có ý nghĩa thống kê.

3.5.4 Phân tích Odd Ratio giữa tình trạng kkhách hàng có người phụ thuộc và khách hàng rời bỏ dịch vụ

Trong phần này, nghiên cứu sẽ tiến hành tính Odds Ratio giữa tình trạng kkhách hàng có người phụ thuộc đến khả năng khách hàng rời bỏ dịch vụ viễn thông. Việc tính toán OR sẽ giúp xác định loại hợp đồng nào làm tăng hoặc giảm khả năng rời bỏ dịch vụ.

or2 <- oddsratio(table_data)
or2
## $data
##        
##           No  Yes Total
##   No    2263 1311  3574
##   Yes    983  275  1258
##   Total 3246 1586  4832
## 
## $measure
##      odds ratio with 95% C.I.
##        estimate     lower     upper
##   No  1.0000000        NA        NA
##   Yes 0.4831432 0.4152523 0.5606655
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact   chi.square
##   No          NA           NA           NA
##   Yes          0 6.794174e-23 6.075757e-22
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Kết quả phân tích Odds Ratio (OR) cho thấy khách hàng có người phụ thuộc có odds rời bỏ dịch vụ chỉ bằng 48,3% so với khách hàng không có người phụ thuộc. Khoảng tin cậy 95% hoàn toàn nhỏ hơn 1 và giá trị p rất nhỏ (p < 0,0001), chứng tỏ sự khác biệt này có ý nghĩa thống kê. Điều đó đồng nghĩa với việc có người phụ thuộc là một yếu tố giúp giảm đáng kể khả năng rời bỏ dịch vụ. Kết quả này cung cấp thông tin quan trọng để nhà mạng xây dựng các chính sách chăm sóc khách hàng hiệu quả hơn, đặc biệt với nhóm không có người phụ thuộc vốn có nguy cơ rời bỏ cao hơn.

3.5.5 Thống kê suy diễn

3.5.5.1 Kiểm định tính độc lập

Để kiểm tra xem biến tình trạng kkhách hàng có người phụ thuộc (Dependents) và hành vi rời bỏ dịch vụ (Churn) có mối liên hệ với nhau hay không, nghiên cứu áp dụng kiểm định Chi-square.

Kiểm định này được thiết lập với giả thuyết:

\[ \left\{ \begin{array}{ll} H_0: & \text{Biến Churn (khách hàng từ bỏ dịch vụ) và biến Dependents (tình trạng kkhách hàng có người phụ thuộc) không có mối quan hệ với nhau.} \\\\ H_1: & \text{Biến Churn (khách hàng từ bỏ dịch vụ) và biến Dependents (tình trạng kkhách hàng có người phụ thuộc) có mối quan hệ với nhau.} \ \end{array} \right. \]

# Kiểm định
chisq_result <- chisq.test(table_data)
# In kết quả
chisq_result
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table_data
## X-squared = 92.032, df = 1, p-value < 2.2e-16

Qua kết quả kiểm định: Với mức ý nghĩa 0.05, vì p-value = 2.2e-16 < 0.05, bác bỏ giả thuyết \(H_0\). Vậy giữa biến Churn và biến Dependents tồn tại mối quan hệ.

3.5.5.2 Khoảng ước lượng tỷ lệ

Ước lượng tỷ lệ rời bỏ dịch vụ của nhóm khách hàng có người phụ thuộc

Trong phần này, tác giả sử dụng kiểm định tỷ lệ một mẫu (1-sample proportion test) để ước lượng tỷ lệ khách hàng rời bỏ dịch vụ trong nhóm khách hàng có người phụ thuộc, đồng thời so sánh với tỷ lệ giả định là 50% (p = 0.5). Phương pháp này giúp xác định xem tỷ lệ rời bỏ dịch vụ của nhóm có người phụ thuộc có khác biệt đáng kể so với tỷ lệ giả định hay không.

prop.test(x = table_data["Yes", "Yes"], n = sum( table_data["Yes", ]), p = 0.5, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  table_data["Yes", "Yes"] out of sum(table_data["Yes", ]), null probability 0.5
## X-squared = 397.34, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.1962563 0.2426887
## sample estimates:
##        p 
## 0.218601

Kết quả kiểm định tỷ lệ một mẫu cho thấy tỷ lệ khách hàng có người phụ thuộc rời bỏ dịch vụ được ước lượng là 21,86%, với khoảng tin cậy 95% nằm trong khoảng 19,63% đến 24,27%. Giá trị p rất nhỏ (p < 2,2e-16) khẳng định tỷ lệ này khác biệt có ý nghĩa thống kê so với tỷ lệ giả định 50%. Điều này chứng tỏ khách hàng có người phụ thuộc có tỷ lệ rời bỏ dịch vụ thấp hơn đáng kể so với mức trung bình giả định.

Ước lượng tỷ lệ rời bỏ dịch vụ của nhóm khách hàng không có người phụ thuộc

Phần này nhằm xác định tỷ lệ khách hàng rời bỏ dịch vụ trong nhóm khách hàng không có người phụ thuộc, đồng thời so sánh tỷ lệ ước lượng với mức giả thuyết 50% để kiểm tra ý nghĩa thống kê.

prop.test(x = table_data["No", "Yes"], n = sum( table_data["No", ]), p = 0.5, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  table_data["No", "Yes"] out of sum(table_data["No", ]), null probability 0.5
## X-squared = 253.05, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.3510281 0.3828922
## sample estimates:
##         p 
## 0.3668159

Kết quả kiểm định tỷ lệ một mẫu cho thấy tỷ lệ rời bỏ dịch vụ (Churn) của nhóm khách hàng không có người phụ thuộc được ước lượng khoảng 36.68%. Khoảng tin cậy 95% cho tỷ lệ này nằm trong khoảng 35.10% đến 385.29%. Giá trị p-value < 2.2e-16 khẳng định sự khác biệt giữa tỷ lệ ước lượng và mức giả thuyết 50% là có ý nghĩa thống kê rất cao. Như vậy, tỷ lệ rời bỏ dịch vụ của khách hàng không có người phụ thuộc thấp hơn nhiều so với 50%. Điều này cho thấy nhóm khách hàng không có người phụ thuộc có tỷ lệ rời bỏ dịch vụ cao hơn nhóm có người phụ thuộc.

3.5.6 Mô hình hồi quy cho dữ liệu nhị phân

3.5.6.1 Mô hình logit

Để phân tích mối quan hệ giữa khách hàng tình trạng người phụ thuộc (Dependents) và khách hàng rời bỏ dịch vụ (Churn), tác giả sử dụng mô hình hồi quy logistic nhị phân (logit model). Mô hình này cho phép ước lượng xác suất rời bỏ dịch vụ thông qua hàm logit, giúp xác định mức độ ảnh hưởng của tình trạng người phụ thuộc đến hành vi rời bỏ của khách hàng.

log5 <- glm(factor(Churn) ~ Dependents, data = vienthong, family = binomial(link = 'logit'))
summary(log5)
## 
## Call:
## glm(formula = factor(Churn) ~ Dependents, family = binomial(link = "logit"), 
##     data = vienthong)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)   -0.54590    0.03471 -15.728   <2e-16 ***
## DependentsYes -0.72794    0.07654  -9.511   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 6019.2  on 4830  degrees of freedom
## AIC: 6023.2
## 
## Number of Fisher Scoring iterations: 4

Ta có mô hình hồi quy như sau:

\[ \log\left( \frac{P(\text{Churn} = \text{"Yes"})}{1 - P(\text{Churn} = \text{"Yes"})} \right) = -0.54590 -0.72794 \cdot \text{DependentsYes} \]

Kết quả mô hình logit cho thấy biến Dependents có tác động đáng kể đến khả năng rời bỏ dịch vụ của khách hàng. Hệ số ước lượng của DependentsYes = -0,7279 (p < 0,001), cho thấy việc có người phụ thuộc làm giảm log-odds rời bỏ dịch vụ so với nhóm không có người phụ thuộc. Khi chuyển sang odds ratio, khách hàng có người phụ thuộc chỉ có odds rời bỏ dịch vụ bằng 48,3% so với nhóm không có người phụ thuộc. Điều này khẳng định có người phụ thuộc là một yếu tố làm giảm đáng kể khả năng rời bỏ dịch vụ

3.5.6.2 Mô hình probit

Bên cạnh mô hình logit, tác giả còn sử dụng mô hình probit nhằm so sánh kết quả và kiểm tra tính ổn định của mối quan hệ giữa biến tình trạng người phụ thuộc Dependents và khả năng khách hàng rời bỏ dịch vụ Churn. Mô hình probit sử dụng hàm liên kết chuẩn tích lũy thay vì hàm logit, nhưng vẫn mang ý nghĩa tương tự trong việc ước lượng xác suất rời bỏ.

pro5 <- glm(factor(Churn) ~ Dependents, data = vienthong, family = binomial(link = 'probit'))
summary(pro5)
## 
## Call:
## glm(formula = factor(Churn) ~ Dependents, family = binomial(link = "probit"), 
##     data = vienthong)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)   -0.34030    0.02141 -15.893   <2e-16 ***
## DependentsYes -0.43663    0.04493  -9.718   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 6019.2  on 4830  degrees of freedom
## AIC: 6023.2
## 
## Number of Fisher Scoring iterations: 4

Kết quả ước lượng mô hình Probit cho thấy biến Dependents có ảnh hưởng đáng kể đến xác suất khách hàng rời bỏ dịch vụ (Churn). Phương trình mô hình được xác định như sau:
\[ P(Y=1 | Dependents) = \Phi(-0.34030 - 0.43663 \cdot Dependents_{Yes}), \] trong đó \(\Phi(\cdot)\) là hàm phân phối tích lũy của phân phối chuẩn chuẩn hóa. Khi khách hàng không có người phụ thuộc (Dependents = No), giá trị tuyến tính là \(z = -0.34030\), dẫn đến xác suất rời bỏ dịch vụ ở mức \(P(Y=1|No) = \Phi(-0.34030) \approx 0.366\) (36.6%). Ngược lại, khi khách hàng có người phụ thuộc (Dependents = Yes), giá trị \(z\) giảm xuống còn \(-0.77693\), và xác suất rời bỏ dịch vụ giảm xuống còn \(P(Y=1|Yes) = \Phi(-0.77693) \approx 0.219\) (21.9%). Hệ số \(-0.43663\) của biến DependentsYes âm và có \(p < 2e-16\), cho thấy việc có người phụ thuộc làm giảm đáng kể khả năng rời bỏ dịch vụ. Nhìn chung, mô hình Probit này cho thấy yếu tố có người phụ thuộc là một biến quan trọng giúp giảm tỷ lệ rời bỏ dịch vụ của khách hàng.

3.5.6.3 Mô hình cloglog

Để phân tích ảnh hưởng của biến Dependents đến khả năng rời bỏ dịch vụ của khách hàng, mô hình hồi quy nhị phân với hàm liên kết Complementary Log-Log (cloglog) được áp dụng. Mô hình này phù hợp khi xác suất xảy ra sự kiện không đối xứng, đặc biệt khi xác suất cao hoặc thấp ở mức cực trị.

clo5 <- glm(factor(Churn) ~ Dependents, data = vienthong, family = binomial(link = 'cloglog'))
summary(clo5)
## 
## Call:
## glm(formula = factor(Churn) ~ Dependents, family = binomial(link = "cloglog"), 
##     data = vienthong)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)   -0.78308    0.02786 -28.108   <2e-16 ***
## DependentsYes -0.61662    0.06657  -9.263   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 6019.2  on 4830  degrees of freedom
## AIC: 6023.2
## 
## Number of Fisher Scoring iterations: 5

Ta có mô hình nghiên cứu như sau:

\[ \log \left[ - \log \left( 1 - p_i \right) \right] = -0.7831 - 0.6166 \cdot \text{DependentsYes}_{i} \]

Kết quả ước lượng mô hình Complementary Log-Log (cloglog) cho thấy hệ số chặn là −0.7831 và hệ số của biến DependentsYes là −0.6166, đều có p-value < 0.001, chứng tỏ chúng có ý nghĩa thống kê ở mức 5%. Khi tính toán xác suất, nhóm khách hàng không có người phụ thuộc có xác suất rời bỏ dịch vụ khoảng 31.9%, trong khi nhóm có người phụ thuộc chỉ khoảng 20.8%. Điều này cho thấy việc có người phụ thuộc giúp giảm đáng kể nguy cơ rời bỏ dịch vụ. Từ kết quả này, ta có thể kết luận rằng biến Dependents là một yếu tố quan trọng trong việc dự báo khả năng rời bỏ dịch vụ của khách hàng.

3.5.7 Đánh giá mô hình

Sau khi tiến hành ước lượng ba mô hình hồi quy nhị phân gồm logit, probit và cloglog, bước tiếp theo là đánh giá và so sánh mức độ phù hợp của các mô hình này. Việc đánh giá được thực hiện dựa trên các chỉ tiêu thống kê như giá trị AIC, BIC, hệ số BrierScore. Ngoài ra, khả năng dự báo xác suất của từng mô hình đối với các trường hợp giả định cụ thể cũng được xem xét để lựa chọn mô hình phù hợp nhất.

# Tạo bảng so sánh
model_eval3 <- data.frame(
  Mô_hình = c("Logit", "Probit", "Cloglog"),
  AIC = c(AIC(log5), AIC(pro5), AIC(clo5)),
  BIC = c(BIC(log5), BIC(pro5), BIC(clo5)),
  Brier_Score = c(BrierScore(log5), BrierScore(pro5), BrierScore(clo5))
)
kable(model_eval3, align = "c", caption = "So sánh các chỉ số đánh giá mô hình") %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14)
So sánh các chỉ số đánh giá mô hình
Mô_hình AIC BIC Brier_Score
Logit 6023.177 6036.143 0.2162643
Probit 6023.177 6036.143 0.2162643
Cloglog 6023.177 6036.143 0.2162643

Dựa trên kết quả so sánh các chỉ số đánh giá mô hình, cả ba mô hình logit, probit và cloglog đều cho ra giá trị AIC (6023.177), BIC (6036.143) và Brier Score (0.2163) giống nhau. Điều này cho thấy mức độ phù hợp của các mô hình là tương đương và khả năng dự báo xác suất đúng không có sự khác biệt đáng kể.

Ma trận nhầm lẫn

  • Mô hình logit
pred_logitlog <- ifelse(predict(log5, type = "response") >= 0.5, "Yes", "No")
actuallog <- vienthong$Churn
cm_logitlog <- confusionMatrix(factor(pred_logitlog), actuallog, positive = "Yes")
cm_logitlog
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 
  • Mô hình probit
pred_logitpro <- ifelse(predict(pro5, type = "response") >= 0.5, "Yes", "No")
actualpro <- vienthong$Churn
cm_logitpro <- confusionMatrix(factor(pred_logitpro), actualpro, positive = "Yes")
cm_logitpro
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 
  • Mô hình cloglog
pred_logitclo <- ifelse(predict(clo5, type = "response") >= 0.5, "Yes", "No")
actualclo <- vienthong$Churn
cm_logitclo <- confusionMatrix(factor(pred_logitclo), actualclo, positive = "Yes")
cm_logitclo
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  3246 1586
##        Yes    0    0
##                                          
##                Accuracy : 0.6718         
##                  95% CI : (0.6583, 0.685)
##     No Information Rate : 0.6718         
##     P-Value [Acc > NIR] : 0.5068         
##                                          
##                   Kappa : 0              
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.0000         
##             Specificity : 1.0000         
##          Pos Pred Value :    NaN         
##          Neg Pred Value : 0.6718         
##              Prevalence : 0.3282         
##          Detection Rate : 0.0000         
##    Detection Prevalence : 0.0000         
##       Balanced Accuracy : 0.5000         
##                                          
##        'Positive' Class : Yes            
## 

Ma trận nhầm lẫn cho thấy cả ba mô hình logit, probit và cloglog đều không dự đoán đúng được bất kỳ trường hợp khách hàng rời bỏ dịch vụ nào, với TP = 0. Đồng thời, FP = 0 cho thấy không có trường hợp khách hàng ở nhóm “No” nào bị dự đoán nhầm thành “Yes”, nhưng điều này phản ánh mô hình không hề đưa ra dự đoán “Yes”. Ngược lại, FN = 1586 cho thấy toàn bộ khách hàng rời bỏ dịch vụ đều bị phân loại sai thành “No”, dẫn đến độ nhạy (Sensitivity) bằng 0. Trong khi đó, TN = 3246 cho thấy toàn bộ khách hàng không rời bỏ dịch vụ được dự đoán chính xác, làm Specificity đạt 100%. Kết quả này cho thấy mô hình bị lệch hẳn về nhóm đa số “No”. Mặc dù độ chính xác tổng thể đạt 67,18%, nhưng điều này không phản ánh đúng hiệu quả phân loại.

3.6 Phân tích đa biến tác động đến khách hàng rời bỏ dịch vụ

Để đánh giá tác động đồng thời của nhiều yếu tố đến khả năng khách hàng rời bỏ dịch vụ (Churn), nhóm nghiên cứu sử dụng các mô hình hồi quy nhị phân, bao gồm: mô hình logit, mô hình probit, và mô hình cloglog. Các mô hình này giúp ước lượng xác suất rời bỏ dịch vụ của khách hàng dựa trên các biến giải thích như loại hợp đồng (Contract), dịch vụ Internet (InternetService), tình trạng hôn nhân/đối tác (Partner) và tình trạng người cao tuổi (SeniorCitizen). Việc phân tích đa biến không chỉ cung cấp cái nhìn tổng quan hơn về ảnh hưởng của từng yếu tố mà còn giúp so sánh hiệu quả dự báo giữa các mô hình thông qua các tiêu chí như AIC, BIC và ma trận nhầm lẫn.

3.6.1 Mô hình logit

Để phân tích xác suất khách hàng rời bỏ dịch vụ dựa trên các yếu tố ảnh hưởng, mô hình logit được sử dụng với biến phụ thuộc là Churn (Yes/No) và các biến độc lập gồm Contract2, InternetService, Partner và SeniorCitizen. Mô hình logit sử dụng hàm liên kết logit, giúp biến đổi xác suất (giới hạn trong [0,1]) thành dạng log-odds, từ đó khắc phục nhược điểm của mô hình xác suất tuyến tính. Lệnh dưới đây thực hiện việc ước lượng mô hình logit:

log4 <- glm(factor(Churn) ~ Contract2 + InternetService + Partner + SeniorCitizen , data = vienthong, family = binomial(link="logit"))
summary(log4)
## 
## Call:
## glm(formula = factor(Churn) ~ Contract2 + InternetService + Partner + 
##     SeniorCitizen, family = binomial(link = "logit"), data = vienthong)
## 
## Coefficients:
##                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                -2.22018    0.11340 -19.578  < 2e-16 ***
## Contract2Khác               1.07939    0.09974  10.822  < 2e-16 ***
## InternetServiceFiber optic  1.22449    0.07712  15.877  < 2e-16 ***
## PartnerYes                 -0.71812    0.06657 -10.788  < 2e-16 ***
## SeniorCitizen               0.31937    0.07863   4.062 4.87e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 5471.4  on 4827  degrees of freedom
## AIC: 5481.4
## 
## Number of Fisher Scoring iterations: 4

Dựa vào kết quả trên ta có mô hình hồi quy như sau:

\[ \log \left( \frac{P(\text{Churn} = \text{"Yes"})}{1 - P(\text{Churn} = \text{"Yes"})} \right) = -1.14079 -1.07939 \cdot \text{Contract2One year} +1.22449 \cdot \text{InternetServiceFiber optic} -0.71812 \cdot \text{PartnerYes} + 0.31937 \cdot \text{SeniorCitizen} \]

# Lấy kết quả hệ số
coef_logit <- summary(log4)$coefficients
odds_ratio <- exp(coef_logit[, "Estimate"])

# Tạo data frame với nhóm so sánh và diễn giải thủ công
result_table <- data.frame(
  Bien = c("Contract2", "InternetService", "Partner", "SeniorCitizen"),
  Nhom_so_sanh = c("One year vs. Khác", "Fiber optic vs. DSL",
                   "Yes vs. No", "1 (Cao tuổi) vs. 0 (Trẻ)"),
  He_so = round(coef_logit[-1, "Estimate"], 5),
  `p-value` = signif(coef_logit[-1, "Pr(>|z|)"], 3),
  Odds_Ratio = round(odds_ratio[-1], 2),
  Dien_giai = c(
    "Khách hàng ký hợp đồng “Khác” có khả năng rời bỏ dịch vụ cao hơn 2,94 lần so với nhóm ký hợp đồng “One year”. Nghĩa là hợp đồng 1 năm có tác dụng giảm mạnh nguy cơ khách hàng rời đi.",
    "Chỉ ra rằng khách hàng sử dụng dịch vụ Internet Fiber optic có khả năng rời bỏ dịch vụ cao gấp 3,4 lần so với khách hàng sử dụng dịch vụ DSL. Điều này có thể liên quan đến giá cước cao hoặc chất lượng dịch vụ chưa tương xứng, dẫn đến sự không hài lòng và quyết định rời bỏ dịch vụ của nhóm khách hàng này.",
    "Khách hàng có đối tác hoặc người thân cùng sử dụng dịch vụ có khả năng rời bỏ giảm 51% so với khách hàng không có đối tác. Điều này phản ánh yếu tố xã hội và sự ảnh hưởng của người thân trong việc duy trì dịch vụ, giúp nhà mạng giữ chân khách hàng hiệu quả hơn.",
    "Cho thấy khách hàng cao tuổi (SeniorCitizen = 1) có khả năng rời bỏ dịch vụ cao hơn 1,38 lần so với nhóm khách hàng trẻ tuổi. Điều này có thể do nhu cầu sử dụng dịch vụ viễn thông ở người cao tuổi ít hơn hoặc họ tìm kiếm các gói cước rẻ hơn ở nhà mạng khác."
  )
)

kable(result_table, align = "c",
      col.names = c("Biến", "Nhóm so sánh", "Hệ số (β)", "p-value", "Odds Ratio (e^β)", "Diễn giải chi tiết")) %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14) %>%
  row_spec(0, extra_css = "font-family: 'Times New Roman';") %>%
  column_spec(1:ncol(result_table), extra_css = "font-family: 'Times New Roman';")
Biến Nhóm so sánh Hệ số (β) p-value Odds Ratio (e^β) Diễn giải chi tiết
Contract2Khác Contract2 One year vs. Khác 1.07939 0.00e+00 2.94 Khách hàng ký hợp đồng “Khác” có khả năng rời bỏ dịch vụ cao hơn 2,94 lần so với nhóm ký hợp đồng “One year”. Nghĩa là hợp đồng 1 năm có tác dụng giảm mạnh nguy cơ khách hàng rời đi.
InternetServiceFiber optic InternetService Fiber optic vs. DSL 1.22449 0.00e+00 3.40 Chỉ ra rằng khách hàng sử dụng dịch vụ Internet Fiber optic có khả năng rời bỏ dịch vụ cao gấp 3,4 lần so với khách hàng sử dụng dịch vụ DSL. Điều này có thể liên quan đến giá cước cao hoặc chất lượng dịch vụ chưa tương xứng, dẫn đến sự không hài lòng và quyết định rời bỏ dịch vụ của nhóm khách hàng này.
PartnerYes Partner Yes vs. No -0.71812 0.00e+00 0.49 Khách hàng có đối tác hoặc người thân cùng sử dụng dịch vụ có khả năng rời bỏ giảm 51% so với khách hàng không có đối tác. Điều này phản ánh yếu tố xã hội và sự ảnh hưởng của người thân trong việc duy trì dịch vụ, giúp nhà mạng giữ chân khách hàng hiệu quả hơn.
SeniorCitizen SeniorCitizen 1 (Cao tuổi) vs. 0 (Trẻ) 0.31937 4.87e-05 1.38 Cho thấy khách hàng cao tuổi (SeniorCitizen = 1) có khả năng rời bỏ dịch vụ cao hơn 1,38 lần so với nhóm khách hàng trẻ tuổi. Điều này có thể do nhu cầu sử dụng dịch vụ viễn thông ở người cao tuổi ít hơn hoặc họ tìm kiếm các gói cước rẻ hơn ở nhà mạng khác.

Từ kết quả trên, có thể thấy các yếu tố về hợp đồng và mối quan hệ xã hội (Partner) giúp giảm tỷ lệ rời bỏ dịch vụ, trong khi yếu tố loại dịch vụ Internet (Fiber optic) và độ tuổi làm tăng khả năng khách hàng rời bỏ. Do đó, doanh nghiệp viễn thông cần tập trung vào khuyến khích khách hàng ký hợp đồng 1 năm, đồng thời cải thiện chất lượng dịch vụ Fiber optic và xây dựng các gói dịch vụ phù hợp với nhóm khách hàng cao tuổi.

Sau khi xây dựng và ước lượng mô hình logit, bước tiếp theo là sử dụng mô hình để dự báo xác suất khách hàng rời bỏ dịch vụ (Churn) cho 4 trường hợp giả định. Cụ thể, ta tạo ra một tập dữ liệu mới (new_data4) với các tổ hợp của biến Contract2, InternetService, Partner và SeniorCitizen, sau đó dùng hàm predict() để tính xác suất churn cho từng trường hợp.

new_data4 <- data.frame(
  Contract2 = factor(c("One year", "One year", "Khác", "Khác")),  # cần đúng tên levels
  InternetService = factor(c("Fiber optic", "DSL", "Fiber optic", "DSL")),
  Partner = factor(c("Yes", "No", "Yes", "No")),
  SeniorCitizen = c(1, 0, 1, 0)
)
# Dự đoán xác suất churn:
predict(log4, newdata = new_data4, type = "response")
##         1         2         3         4 
## 0.1987004 0.0979530 0.4218822 0.2421747

Dựa trên kết quả dự báo từ mô hình logit, ta có xác suất rời bỏ dịch vụ (Churn) của 4 trường hợp như sau:

Trường hợp 1 (One year, Fiber optic, Partner = Yes, SeniorCitizen = 1): Xác suất rời bỏ dịch vụ khoảng 19,87%, tương đối thấp nhờ hợp đồng 1 năm và có đối tác cùng sử dụng dịch vụ, dù khách hàng cao tuổi.

Trường hợp 2 (One year, DSL, Partner = No, SeniorCitizen = 0): Xác suất chỉ 9,79%, thấp nhất trong 4 trường hợp, cho thấy hợp đồng dài hạn và dịch vụ DSL có ảnh hưởng tích cực, mặc dù khách hàng không có đối tác.

Trường hợp 3 (Khác, Fiber optic, Partner = Yes, SeniorCitizen = 1): Xác suất lên tới 42,18%, cao nhất trong nhóm, nguyên nhân chính là loại hợp đồng không dài hạn và sử dụng dịch vụ Fiber optic – nhóm dịch vụ có tỷ lệ churn cao hơn.

Trường hợp 4 (Khác, DSL, Partner = No, SeniorCitizen = 0): Xác suất 24,21%, cao hơn 2 trường hợp đầu nhưng thấp hơn trường hợp 3, vì khách hàng không có đối tác và hợp đồng không dài hạn.

3.6.2 Mô hình probit

Bên cạnh mô hình logit, mô hình probit cũng được sử dụng nhằm phân tích xác suất khách hàng rời bỏ dịch vụ. Mô hình probit khác với logit ở chỗ nó sử dụng hàm liên kết (link function) là hàm phân phối tích lũy chuẩn (CDF) thay vì hàm logistic. Việc so sánh hai mô hình giúp kiểm tra tính ổn định và độ phù hợp của kết quả ước lượng.

pro4 <- glm(factor(Churn) ~ Contract2 + InternetService + Partner + SeniorCitizen , data = vienthong, family = binomial(link="probit"))
summary(pro4)
## 
## Call:
## glm(formula = factor(Churn) ~ Contract2 + InternetService + Partner + 
##     SeniorCitizen, family = binomial(link = "probit"), data = vienthong)
## 
## Coefficients:
##                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                -1.29190    0.06289 -20.542  < 2e-16 ***
## Contract2Khác               0.60838    0.05561  10.939  < 2e-16 ***
## InternetServiceFiber optic  0.72563    0.04433  16.369  < 2e-16 ***
## PartnerYes                 -0.43317    0.03967 -10.918  < 2e-16 ***
## SeniorCitizen               0.19366    0.04790   4.043 5.28e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 5474.4  on 4827  degrees of freedom
## AIC: 5484.4
## 
## Number of Fisher Scoring iterations: 4

Kết quả ước lượng từ mô hình probit cho thấy tất cả các biến độc lập bao gồm Contract2 (One year), InternetService (Fiber optic), Partner (Yes) và SeniorCitizen đều có ý nghĩa thống kê ở mức 1% (p-value < 0.01). Điều này chứng tỏ các yếu tố trên có tác động đáng kể đến xác suất khách hàng rời bỏ dịch vụ. Mô hình Probit được trình bày:

\[ P(\text{Churn} = Yes) = \Phi \big( -0.68353 - 0.60838 \cdot \text{Contract2}_{\text{One year}} + 0.72563 \cdot \text{InternetService}_{\text{Fiber optic}} - 0.43317 \cdot \text{Partner}_{\text{Yes}} + 0.19366 \cdot \text{SeniorCitizen} \big) \]

# Lấy hệ số và p-value từ mô hình probit, bỏ dòng Intercept
coef_pro <- summary(pro4)$coefficients
coef_pro <- coef_pro[-1, ]  # Bỏ dòng Intercept

# Tạo bảng kết quả
result_probit <- data.frame(
  Bien = rownames(coef_pro),
  He_so = round(coef_pro[, 1], 5),
  p_value = signif(coef_pro[, 4], 4),
  Dien_giai = c(
    "Hệ số âm chứng tỏ khách hàng ký hợp đồng 1 năm có xác suất rời bỏ dịch vụ thấp hơn so với những hợp đồng khác.",
    "Dấu dương cho thấy khách hàng sử dụng dịch vụ internet cáp quang (Fiber optic) có xác suất rời bỏ dịch vụ cao hơn so với khách hàng dùng DSL.",
    "Hàm ý rằng khách hàng có đối tác hoặc vợ chồng (Partner = Yes) có xác suất rời bỏ dịch vụ thấp hơn so với những người độc thân hoặc không có đối tác. ",
    "Dấu dương cho thấy người cao tuổi (SeniorCitizen = 1) có xác suất rời bỏ dịch vụ cao hơn so với người trẻ."
  )
)

# In bảng
kable(result_probit, align = "c",
      col.names = c("Biến", "Hệ số (β)", "p-value", "Diễn giải")) %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14)
Biến Hệ số (β) p-value Diễn giải
Contract2Khác Contract2Khác 0.60838 0.00e+00 Hệ số âm chứng tỏ khách hàng ký hợp đồng 1 năm có xác suất rời bỏ dịch vụ thấp hơn so với những hợp đồng khác.
InternetServiceFiber optic InternetServiceFiber optic 0.72563 0.00e+00 Dấu dương cho thấy khách hàng sử dụng dịch vụ internet cáp quang (Fiber optic) có xác suất rời bỏ dịch vụ cao hơn so với khách hàng dùng DSL.
PartnerYes PartnerYes -0.43317 0.00e+00 Hàm ý rằng khách hàng có đối tác hoặc vợ chồng (Partner = Yes) có xác suất rời bỏ dịch vụ thấp hơn so với những người độc thân hoặc không có đối tác.
SeniorCitizen SeniorCitizen 0.19366 5.28e-05 Dấu dương cho thấy người cao tuổi (SeniorCitizen = 1) có xác suất rời bỏ dịch vụ cao hơn so với người trẻ.

Sau khi xây dựng và ước lượng mô hình probit, bước tiếp theo là sử dụng mô hình để dự báo xác suất khách hàng rời bỏ dịch vụ (Churn) cho 4 trường hợp giả định. Cụ thể, ta tạo ra một tập dữ liệu mới (new_data5) với các tổ hợp của biến Contract2, InternetService, Partner và SeniorCitizen, sau đó dùng hàm predict() để tính xác suất churn cho từng trường hợp.

new_data5 <- data.frame(
  Contract2 = factor(c("One year", "One year", "Khác", "Khác")),  # cần đúng tên levels
  InternetService = factor(c("Fiber optic", "DSL", "Fiber optic", "DSL")),
  Partner = factor(c("Yes", "No", "Yes", "No")),
  SeniorCitizen = c(1, 0, 1, 0)
)

# Dự đoán xác suất churn:
predict(pro4, newdata = new_data5, type = "response")
##          1          2          3          4 
## 0.21018579 0.09819504 0.42175847 0.24713756

Trường hợp 1 (Contract = One year, InternetService = Fiber optic, Partner = Yes, SeniorCitizen = 1) có xác suất rời bỏ 0.2102 (khoảng 21.02%). Mặc dù khách hàng sử dụng dịch vụ Fiber optic (yếu tố làm tăng khả năng rời bỏ), nhưng việc có hợp đồng 1 năm và có đối tác giúp giảm đáng kể xác suất này.

Trường hợp 2 (Contract = One year, InternetService = DSL, Partner = No, SeniorCitizen = 0) có xác suất rời bỏ 0.0982 (khoảng 9.82%), thấp nhất trong 4 trường hợp. Điều này cho thấy hợp đồng dài hạn và dịch vụ DSL là các yếu tố ổn định, hạn chế khả năng rời bỏ dịch vụ.

Trường hợp 3 (Contract = Khác, InternetService = Fiber optic, Partner = Yes, SeniorCitizen = 1) có xác suất rời bỏ 0.4218 (khoảng 42.18%), cao nhất trong 4 trường hợp. Nguyên nhân là do khách hàng không sử dụng hợp đồng dài hạn và đang dùng dịch vụ Fiber optic, kết hợp với yếu tố cao tuổi, làm tăng nguy cơ rời bỏ.

Trường hợp 4 (Contract = Khác, InternetService = DSL, Partner = No, SeniorCitizen = 0) có xác suất rời bỏ 0.2471 (khoảng 24.71%). Mặc dù dịch vụ DSL làm giảm nguy cơ rời bỏ so với Fiber optic, nhưng việc không có hợp đồng dài hạn và không có đối tác khiến xác suất này vẫn khá cao.

Chênh lệch lớn nhất nằm giữa trường hợp 2 (9.82%) và trường hợp 3 (42.18%), cho thấy vai trò quan trọng của hợp đồng 1 năm và việc không sử dụng Fiber optic trong việc giữ chân khách hàng.

3.6.3 Mô hình cloglog

Tiếp theo, để phân tích xác suất khách hàng rời bỏ dịch vụ, mô hình hồi quy với hàm liên kết complementary log-log (cloglog) được xây dựng. Mô hình cloglog được sử dụng phổ biến trong các trường hợp mà xác suất xảy ra sự kiện (ở đây là khách hàng rời bỏ dịch vụ) không đối xứng, tức khi khả năng xảy ra sự kiện là rất thấp hoặc rất cao. Khác với logit và probit, cloglog sử dụng hàm liên kết dạng \(g(p) = \log(-\log(1-p))\). Mô hình này cho phép phân tích xác suất với tốc độ tăng không đồng đều, đặc biệt phù hợp cho dữ liệu với hiện tượng rời bỏ mang tính hiếm gặp hoặc tập trung mạnh. Dưới đây là kết quả ước lượng của mô hình cloglog.

clo4 <- glm(factor(Churn) ~ Contract2 + InternetService + Partner + SeniorCitizen , data = vienthong, family = binomial(link="cloglog"))
summary(clo4)
## 
## Call:
## glm(formula = factor(Churn) ~ Contract2 + InternetService + Partner + 
##     SeniorCitizen, family = binomial(link = "cloglog"), data = vienthong)
## 
## Coefficients:
##                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                -2.24206    0.10116 -22.164  < 2e-16 ***
## Contract2Khác               0.92648    0.08874  10.440  < 2e-16 ***
## InternetServiceFiber optic  1.01393    0.06628  15.299  < 2e-16 ***
## PartnerYes                 -0.55842    0.05296 -10.544  < 2e-16 ***
## SeniorCitizen               0.23803    0.05875   4.052 5.08e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 6116.5  on 4831  degrees of freedom
## Residual deviance: 5472.8  on 4827  degrees of freedom
## AIC: 5482.8
## 
## Number of Fisher Scoring iterations: 5

Tất cả các biến độc lập (Contract2One year, InternetServiceFiber optic, PartnerYes, SeniorCitizen) đều có p-value < 0.001 (ký hiệu ***). Điều này chứng tỏ tất cả các biến đều có ý nghĩa thống kê cao, ảnh hưởng rõ rệt đến xác suất khách hàng rời bỏ dịch vụ (Churn). Ta có mô hình cloglog như sau:

\[ \log(-\log(1-p)) = \ -1.31558 \ -0.92648 \cdot \text{Contract2One year} + 1.01393 \cdot \text{InternetServiceFiber optic} \ -0.55842\cdot \text{PartnerYes} + \ 0.23803\cdot \text{SeniorCitizen} \]

Kết quả mô hình hồi quy cloglog cho thấy cả bốn biến độc lập đều có ý nghĩa thống kê cao trong việc dự đoán khả năng khách hàng rời bỏ dịch vụ. Cụ thể, biến Contract2One year có hệ số âm (-0.92648), cho thấy khách hàng có hợp đồng một năm có xác suất rời bỏ dịch vụ thấp hơn so với nhóm còn lại ). Tương tự, khách hàng có người phụ thuộc (PartnerYes) cũng ít rời bỏ hơn, phản ánh qua hệ số âm -0.55842. Ngược lại, dịch vụ Internet cáp quang (Fiber optic) có hệ số dương cao (1.01393), cho thấy xác suất rời bỏ tăng mạnh nếu khách hàng sử dụng dịch vụ này, có thể do chất lượng hoặc chi phí chưa đáp ứng kỳ vọng. Biến SeniorCitizen với hệ số dương (0.23803) ngụ ý người cao tuổi có xu hướng rời bỏ dịch vụ nhiều hơn, dù mức độ tác động không lớn.

Sau khi xây dựng và ước lượng mô hình cloglog, bước tiếp theo là sử dụng mô hình để dự báo xác suất khách hàng rời bỏ dịch vụ (Churn) cho 4 trường hợp giả định. Cụ thể, ta tạo ra một tập dữ liệu mới (new_data6) với các tổ hợp của biến Contract2, InternetService, Partner và SeniorCitizen, sau đó dùng hàm predict() để tính xác suất churn cho từng trường hợp.

new_data6 <- data.frame(
  Contract2 = factor(c("One year", "One year", "Khác", "Khác")),  # cần đúng tên levels
  InternetService = factor(c("Fiber optic", "DSL", "Fiber optic", "DSL")),
  Partner = factor(c("Yes", "No", "Yes", "No")),
  SeniorCitizen = c(1, 0, 1, 0)
)

# Dự đoán xác suất churn:
predict(clo4, newdata = new_data6, type = "response")
##         1         2         3         4 
## 0.1914907 0.1007908 0.4154137 0.2353365

Trường hợp 1: Khách hàng ký hợp đồng 1 năm, sử dụng dịch vụ Internet cáp quang (Fiber optic), có vợ chồng và thuộc nhóm người cao tuổi có xác suất rời bỏ dịch vụ là 19,1%. Mặc dù việc ký hợp đồng dài hạn và có người thân sống cùng giúp giảm khả năng rời bỏ dịch vụ, nhưng yếu tố sử dụng Fiber optic và việc thuộc nhóm khách hàng cao tuổi lại là yếu làm tăng rủi ro khách hàng rời bỏ dịch vụ viễn thông. Điều này cho thấy nhóm khách hàng lớn tuổi và sử dụng dịch vụ tốc độ cao vẫn cần được duy trì chăm sóc và tạo các ưu đãi nhằm giảm tỷ lệ rời bỏ.

Trường hợp 2: Với khách hàng cũng ký hợp đồng 1 năm, nhưng sử dụng dịch vụ DSL, không có người thân sống cùng (Partner = No) và không thuộc nhóm người cao tuổi, xác suất rời bỏ dịch vụ chỉ ở mức 10,1%, thấp nhất trong bốn trường hợp. Kết quả này phản ánh vai trò quan trọng của hợp đồng dài hạn và loại dịch vụ DSL, vốn ít biến động và ít chịu ảnh hưởng từ yếu tố cạnh tranh. Đây là nhóm khách hàng có tính ổn định cao, nhưng vẫn cần chiến lược giữ chân cơ bản để duy trì mức độ hài lòng.

Trường hợp 3: Khách hàng không ký hợp đồng 1 năm, sử dụng Fiber optic, có người thân sống cùng và thuộc nhóm người cao tuổi, có xác suất rời bỏ dịch vụ cao nhất, lên đến 41,5%. Việc không có cam kết dài hạn khiến nhóm khách hàng này dễ dàng cân nhắc thay đổi nhà cung cấp, đặc biệt khi sử dụng dịch vụ tốc độ cao như Fiber optic, vốn thường có nhiều lựa chọn thay thế. Đây là nhóm khách hàng rủi ro cao nhất, đòi hỏi doanh nghiệp phải áp dụng các chiến lược giữ chân như khuyến mãi, giảm giá hoặc gói dịch vụ dài hạn hấp dẫn.

Trường hợp 4: Đối với khách hàng không ký hợp đồng 1 năm, sử dụng DSL, không có người thân sống cùng và không phải người cao tuổi, xác suất rời bỏ dịch vụ là 23,5%, cao hơn trường hợp 1 và 2 nhưng thấp hơn nhiều so với trường hợp 3. Mặc dù không ký hợp đồng dài hạn làm tăng khả năng rời bỏ, nhưng loại dịch vụ DSL và nhóm khách hàng trẻ tuổi giúp xác suất rời bỏ ở mức trung bình. Nhóm khách hàng này vẫn cần các chính sách khuyến khích gia hạn hợp đồng hoặc nâng cấp dịch vụ để giảm rủi ro rời bỏ.

3.6.4 Đánh giá mô hình

Sau khi tiến hành ước lượng ba mô hình hồi quy nhị phân gồm logit, probitcloglog, bước tiếp theo là đánh giá và so sánh mức độ phù hợp của các mô hình này. Việc đánh giá được thực hiện dựa trên các chỉ tiêu thống kê như giá trị AIC, BIC, Brier_Scorema trận nhầm lẫn. Ngoài ra, khả năng dự báo xác suất của từng mô hình đối với các trường hợp giả định cụ thể cũng được xem xét để lựa chọn mô hình phù hợp nhất.

# Tạo bảng so sánh
model_eval4 <- data.frame(
  Mô_hình = c("Logit", "Probit", "Cloglog"),
  AIC = c(AIC(log4), AIC(pro4), AIC(clo4)),
  BIC = c(BIC(log4), BIC(pro4), BIC(clo4)),
  Brier_Score = c(BrierScore(log4), BrierScore(pro4), BrierScore(clo4))
)
kable(model_eval4, align = "c", caption = "So sánh các chỉ số đánh giá mô hình") %>%
  kable_styling(full_width = FALSE, position = "center", font_size = 14)
So sánh các chỉ số đánh giá mô hình
Mô_hình AIC BIC Brier_Score
Logit 5481.412 5513.828 0.1926644
Probit 5484.394 5516.809 0.1927293
Cloglog 5482.755 5515.170 0.1927283

Mặc dù cả ba mô hình đều cho kết quả khá tương đương, mô hình Logit nổi bật hơn một cách toàn diện ở cả ba tiêu chí (AIC, BIC và Brier Score). Điều này cho thấy mô hình Logit là lựa chọn phù hợp nhất trong trường hợp này để phân tích xác suất rời bỏ dịch vụ của khách hàng.

Ma trận nhầm lẫn

  • Mô hình Logit
# Dự đoán xác suất
prob2 <- predict(log4, type = "response")

# Chuyển xác suất thành nhãn "Yes"/"No" với ngưỡng 0.5
predicted_class2 <- ifelse(prob2 >= 0.5, "Yes", "No")
# Chuyển về factor để thống nhất
predicted_class2 <- factor(predicted_class2, levels = c("No", "Yes"))
true_class2 <- factor(vienthong$Churn, levels = c("No", "Yes"))
confusionMatrix(data = predicted_class2, reference = true_class2, positive = "Yes")
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  2600  830
##        Yes  646  756
##                                           
##                Accuracy : 0.6945          
##                  95% CI : (0.6813, 0.7075)
##     No Information Rate : 0.6718          
##     P-Value [Acc > NIR] : 0.000371        
##                                           
##                   Kappa : 0.2861          
##                                           
##  Mcnemar's Test P-Value : 1.905e-06       
##                                           
##             Sensitivity : 0.4767          
##             Specificity : 0.8010          
##          Pos Pred Value : 0.5392          
##          Neg Pred Value : 0.7580          
##              Prevalence : 0.3282          
##          Detection Rate : 0.1565          
##    Detection Prevalence : 0.2901          
##       Balanced Accuracy : 0.6388          
##                                           
##        'Positive' Class : Yes             
## 
  • Mô hình probit
# Dự đoán xác suất
prob3 <- predict(pro4, type = "response")

# Chuyển xác suất thành nhãn "Yes"/"No" với ngưỡng 0.5
predicted_class3 <- ifelse(prob3>= 0.5, "Yes", "No")

# Chuyển về factor để thống nhất
predicted_class3 <- factor(predicted_class3, levels = c("No", "Yes"))
true_class3 <- factor(vienthong$Churn, levels = c("No", "Yes"))
confusionMatrix(data = predicted_class3, reference = true_class3, positive = "Yes")
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  2600  830
##        Yes  646  756
##                                           
##                Accuracy : 0.6945          
##                  95% CI : (0.6813, 0.7075)
##     No Information Rate : 0.6718          
##     P-Value [Acc > NIR] : 0.000371        
##                                           
##                   Kappa : 0.2861          
##                                           
##  Mcnemar's Test P-Value : 1.905e-06       
##                                           
##             Sensitivity : 0.4767          
##             Specificity : 0.8010          
##          Pos Pred Value : 0.5392          
##          Neg Pred Value : 0.7580          
##              Prevalence : 0.3282          
##          Detection Rate : 0.1565          
##    Detection Prevalence : 0.2901          
##       Balanced Accuracy : 0.6388          
##                                           
##        'Positive' Class : Yes             
## 
  • Mô hình cloglog
# Dự đoán xác suất
prob4<- predict(clo4, type = "response")

# Chuyển xác suất thành nhãn "Yes"/"No" với ngưỡng 0.5
predicted_class4 <- ifelse(prob4 >= 0.5, "Yes", "No")

# Chuyển về factor để thống nhất
predicted_class4 <- factor(predicted_class4, levels = c("No", "Yes"))
true_class4 <- factor(vienthong$Churn, levels = c("No", "Yes"))
confusionMatrix(data = predicted_class4, reference = true_class4, positive = "Yes")
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   No  Yes
##        No  2600  830
##        Yes  646  756
##                                           
##                Accuracy : 0.6945          
##                  95% CI : (0.6813, 0.7075)
##     No Information Rate : 0.6718          
##     P-Value [Acc > NIR] : 0.000371        
##                                           
##                   Kappa : 0.2861          
##                                           
##  Mcnemar's Test P-Value : 1.905e-06       
##                                           
##             Sensitivity : 0.4767          
##             Specificity : 0.8010          
##          Pos Pred Value : 0.5392          
##          Neg Pred Value : 0.7580          
##              Prevalence : 0.3282          
##          Detection Rate : 0.1565          
##    Detection Prevalence : 0.2901          
##       Balanced Accuracy : 0.6388          
##                                           
##        'Positive' Class : Yes             
## 

Dựa trên các ma trận nhầm lẫn trong kết quả trước và hình minh họa TP, FP, FN, TN, ta có:

  • TP (True Positive) = 756: Số khách hàng thực sự rời bỏ (Yes) và mô hình cũng dự đoán đúng là rời bỏ.

  • FP (False Positive) = 646: Số khách hàng thực tế không rời bỏ (No) nhưng mô hình dự đoán sai là rời bỏ.

  • FN (False Negative) = 830: Số khách hàng thực tế rời bỏ (Yes) nhưng mô hình dự đoán sai là không rời bỏ.

  • TN (True Negative) = 2600: Số khách hàng thực tế không rời bỏ (No) và mô hình cũng dự đoán đúng là không rời bỏ.

Mô hình dự đoán đúng 3.356 trong tổng số 4.832 khách hàng, đạt độ chính xác khoảng 69,45%.Trong khi khả năng nhận diện khách hàng không rời bỏ (Specificity) khá cao với 80,1%, mô hình chỉ dự đoán đúng 47,7% số khách hàng thực sự rời bỏ dịch vụ (Sensitivity). Khi dự đoán một khách hàng sẽ rời bỏ, tỷ lệ đúng chỉ đạt khoảng 53,9%, tức là trong 10 người được dự đoán rời bỏ chỉ có 5–6 người thực sự rời bỏ. Điều này cho thấy mô hình có xu hướng thiên về dự đoán “không rời bỏ” với Specificity cao (80,1%), trong khi khả năng nhận diện khách hàng rời bỏ (Sensitivity) còn thấp (47,7%). Khi mô hình dự đoán khách hàng sẽ rời bỏ, tỷ lệ dự đoán đúng chỉ đạt khoảng 53,9% (Precision). Nhìn chung, mô hình hoạt động ổn với nhóm khách hàng “không rời bỏ” nhưng cần cải thiện để phát hiện chính xác hơn nhóm khách hàng “rời bỏ”.

3.7 Kết luận và khuyến nghị

3.7.1 Kết luận

Kết quả phân tích cho thấy các yếu tố như loại hợp đồng, loại hình dịch vụ Internet, độ tuổi và tình trạng có người phụ thuộc hoặc đối tác đóng vai trò quan trọng trong việc định hình hành vi rời bỏ dịch vụ của khách hàng. Phân tích hành vi rời bỏ dịch vụ (churn) từ dữ liệu của 4.832 khách hàng cho thấy tỷ lệ rời bỏ tổng thể đạt 32,82%, phản ánh một thách thức đáng kể đối với doanh nghiệp trong việc duy trì khách hàng. Kết quả phân tích đơn biến và đa biến khẳng định các yếu tố quan trọng ảnh hưởng đến churn bao gồm loại hợp đồng (Contract), loại hình dịch vụ Internet (InternetService), độ tuổi (SeniorCitizen), tình trạng có người phụ thuộc (Dependents) và đối tác (Partner).

Đáng chú ý, hợp đồng dài hạn (“One year”) là yếu tố bảo vệ mạnh nhất, giúp giảm odds rời bỏ xuống 0,34 lần (theo mô hình logit), với tỷ lệ rời bỏ chỉ 14,83% (khoảng tin cậy 95%: 12,68%–17,27%), thấp hơn đáng kể so với 37,31% của nhóm hợp đồng “Khác” (RR = 2,51). Khách hàng có người phụ thuộc hoặc đối tác cũng thể hiện mức độ trung thành cao hơn, với tỷ lệ rời bỏ lần lượt là 21,86% và 23,99% (OR lần lượt là 0,483 và 0,49), so với 36,68% và 38,35% ở nhóm đối chứng.

Ngược lại, dịch vụ Fiber optic ghi nhận tỷ lệ rời bỏ cao nhất (41,89%, OR = 3,40), có thể do giá cước cao hoặc chất lượng dịch vụ chưa đáp ứng kỳ vọng. Nhóm khách hàng cao tuổi cũng có tỷ lệ rời bỏ vượt trội (43,3%, OR = 1,38), có thể xuất phát từ nhu cầu sử dụng thấp hoặc hạn chế về kỹ năng công nghệ. Phân tích đa biến cho thấy nhóm khách hàng lý tưởng nhất (có khả năng rời bỏ thấp nhất) là những người dùng hợp đồng “One year”, dịch vụ DSL, không cao tuổi và không có đối tác (9,79%–10,1%), trong khi nhóm có nguy cơ cao nhất là những người sử dụng hợp đồng “Khác”, Fiber optic, cao tuổi và có đối tác (41,5%–42,18%).

Tuy nhiên, các mô hình hồi quy (logit, probit, cloglog) vẫn gặp hạn chế trong dự đoán, với độ nhạy chỉ đạt 47,7% do dữ liệu mất cân bằng (67,18% không rời bỏ so với 32,82% rời bỏ), mặc dù logit có hiệu quả tốt nhất (AIC = 5481,412, Brier Score = 0,199). Điều này gợi mở nhu cầu cải thiện chất lượng dự đoán bằng các kỹ thuật cân bằng dữ liệu, bổ sung biến quan trọng (như chi phí hàng tháng hoặc thời gian sử dụng), hoặc áp dụng các thuật toán học máy hiện đại (Random Forest, XGBoost) để tăng độ chính xác.

Những phát hiện này mang ý nghĩa thực tiễn quan trọng: hợp đồng dài hạn và yếu tố gia đình (đối tác, người phụ thuộc) tăng cường sự gắn bó, trong khi dịch vụ Fiber optic và nhóm cao tuổi cần được cải thiện để giảm nguy cơ rời bỏ. Doanh nghiệp nên ưu tiên khuyến khích hợp đồng dài hạn qua ưu đãi, cải thiện chất lượng Fiber optic, xây dựng gói cước phù hợp cho khách hàng cao tuổi, và nhắm đến nhóm không có người phụ thuộc bằng các chiến lược marketing cá nhân hóa. Đồng thời, cải tiến mô hình dự đoán bằng cách cân bằng dữ liệu, bổ sung biến như chi phí hàng tháng hoặc thời gian sử dụng, và áp dụng các kỹ thuật học máy (như Random Forest) sẽ giúp nhận diện chính xác hơn khách hàng có nguy cơ rời bỏ, từ đó triển khai các biện pháp giữ chân hiệu quả, góp phần nâng cao sự hài lòng và củng cố vị thế cạnh tranh trên thị trường.

3.7.2 Khuyến nghị

Để giảm tỷ lệ rời bỏ dịch vụ và tăng cường sự gắn bó của khách hàng, doanh nghiệp nên xem xét các giải pháp sau:

Thứ nhất là khuyến khích ký hợp đồng dài hạn: Cung cấp các ưu đãi hấp dẫn như giảm giá, tặng thêm dịch vụ, hoặc các chương trình khách hàng thân thiết để khuyến khích khách hàng lựa chọn hợp đồng “One year”, từ đó tăng tính cam kết và giảm nguy cơ rời bỏ.

Thứ hai là cải thiện chất lượng dịch vụ Fiber optic: Xem xét điều chỉnh giá cước hoặc nâng cấp chất lượng dịch vụ Fiber optic để đáp ứng kỳ vọng của khách hàng, vì đây là nhóm có tỷ lệ rời bỏ cao nhất (41,89%). Các khảo sát phản hồi khách hàng có thể giúp xác định nguyên nhân cụ thể (giá cả, tốc độ, hoặc độ ổn định).

Thứ 3 là xây dựng gói dịch vụ phù hợp cho nhóm cao tuổi: Tạo các gói cước đơn giản, giá cả phải chăng, và dễ sử dụng cho khách hàng cao tuổi, đồng thời cung cấp hỗ trợ kỹ thuật thân thiện để đáp ứng nhu cầu của nhóm này, từ đó giảm tỷ lệ rời bỏ (43,3%).

Thứ 4 là tập trung vào nhóm khách hàng không có người phụ thuộc: Phát triển các chiến lược marketing nhắm đến nhóm này, chẳng hạn như các gói dịch vụ gia đình hoặc ưu đãi đặc biệt, để tăng tính gắn bó, vì nhóm này có tỷ lệ rời bỏ cao hơn (36,68%).

Thứ 5 là cải thiện mô hình dự đoán: Điều chỉnh ngưỡng dự đoán hoặc áp dụng các kỹ thuật cân bằng dữ liệu (như oversampling hoặc undersampling) để tăng độ nhạy của mô hình, từ đó cải thiện khả năng dự đoán khách hàng có nguy cơ rời bỏ và triển khai các biện pháp giữ chân kịp thời.

Cuối cùng là tăng cường chăm sóc khách hàng: Thiết lập các chương trình chăm sóc khách hàng cá nhân hóa, đặc biệt cho các nhóm có nguy cơ rời bỏ cao (Fiber optic, cao tuổi, không có người phụ thuộc), thông qua khảo sát định kỳ, hỗ trợ nhanh chóng, và các ưu đãi phù hợp.

LS0tDQp0aXRsZTogIlBIw4JOIFTDjUNIIEPDgUMgWeG6vlUgVOG7kCDhuqJOSCBIxq/hu55ORyDEkOG6vk4gSMOATkggVkkgUuG7nEkgQuG7jiBE4buKQ0ggVuG7pCBD4bumQSBLSMOBQ0ggSMOATkcgVknhu4ROIFRIw5RORyINCmF1dGhvcjogIlBoYW4gTmd1eeG7hW4gUXXhu7NuaCBIxrDGoW5nXzIyMjEwMDAzMDQiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclSDolTTolUywgJWQgLSAlbSAtICVZJylgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlICANCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDUNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IHRydWUNCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUNCiAgd29yZF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UpDQpgYGANCg0KDQpgYGB7Y3NzLGVjaG8gPSBGQUxTRX0NCmgxIHsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGZvbnQtc2l6ZTogMzJweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQNCiAgfQ0KDQpoMiB7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBmb250LXNpemU6IDI4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KIA0KfQ0KDQpoMyB7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBmb250LXNpemU6IDI0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LXN0eWxlOiBpdGFsaWM7DQp9DQoNCmg0IHtmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LXN0eWxlOiBpdGFsaWN9DQoNCmJvZHkgew0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgZm9udC1zaXplOiAxOHB4Ow0KICANCn0NCnA6bm90KGgxKTpub3QoaDIpOm5vdChoMyk6bm90KGg0KTpub3QoaDUpIHsNCiAgdGV4dC1pbmRlbnQ6IDJlbTt9DQpwIHsNCiAgdGV4dC1hbGlnbjoganVzdGlmeTsNCiAgfQ0KLnRvY2lmeS1oZWFkZXIgew0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KYGBgDQoNCiFbXShEOi9ISzJfUFRETERUX1RNVC9C4buYIFTDgEkgQ0jDjU5ILmpwZyl7d2l0aD0xNTAlfQ0KDQotLS0tLS0tLS0tDQoNCiMgKipM4bucSSBD4bqiTSDGoE4qKg0KDQpFbSB4aW4gZ+G7rWkgbOG7nWkgY+G6o20gxqFuIGNow6JuIHRow6BuaCB2w6Agc+G7sSB0cmkgw6JuIHPDonUgc+G6r2MgdOG7m2kgdGjhuqd5IFRy4bqnbiBN4bqhbmggVMaw4budbmcuIFPhu7Eg4bunbmcgaOG7mSwgaMaw4bubbmcgZOG6q24gdsOgIHThuqFvIMSRaeG7gXUga2nhu4duIGPhu6dhIGPDoWMgdGjhuqd5IMSRw6MgZ2nDunAgZW0gaG/DoG4gdGjDoG5oIHThu5F0IGLDoGkgdGnhu4N1IGx14bqtbiBuw6B5LCB0aOG6p3kgxJHDoyBkw6BuaCBuaGnhu4F1IHRo4budaSBnaWFuIHF1w70gYsOhdSDEkeG7gyBoxrDhu5tuZyBk4bqrbiwgZ2nhuqNpIMSRw6FwIG3hu41pIHRo4bqvYyBt4bqvYyB2w6AgY2jhu4kgYuG6o28gdOG6rW4gdMOsbmggY2hvIGVtIHRyb25nIHN14buRdCBxdcOhIHRyw6xuaCB0aOG7sWMgaGnhu4duIGLDoGkgdGnhu4N1IGx14bqtbi4gU+G7sSBuZ2hpw6ptIGto4bqvYyB2w6Agbmhp4buHdCB0w6xuaCBj4bunYSB0aOG6p3kgxJHDoyBnacO6cCBlbSBraMO0bmcgY2jhu4kgaG/DoG4gdGhp4buHbiBiw6BpIHRp4buDdSBsdeG6rW4gbcOgIGPDsm4gdMOtY2ggbMWpeSDEkcaw4bujYyBuaGnhu4F1IGtp4bq/biB0aOG7qWMgdsOgIGvhu7kgbsSDbmcgcXXDvSBiw6F1IGNobyB0xrDGoW5nIGxhaS4gDQpFbSB4aW4gY2jDom4gdGjDoG5oIGPhuqNtIMahbi4NCg0KLS0tLS0tLQ0KDQojICoqTOG7nEkgQ0FNIMSQT0FOKioNCg0KRW0gdMOqbiBQaGFuIE5ndXnhu4VuIFF14buzbmggSMawxqFuZywgc2luaCB2acOqbiB0csaw4budbmcgxJDhuqFpIGjhu41jIFTDoGkgY2jDrW5oIOKAkyBNYXJrZXRpbmcsIGNodXnDqm4gbmfDoG5oIFTDoGkgY2jDrW5oIMSR4buLbmggbMaw4bujbmcsIGzhu5twIDIyRFRMMDEuIEVtIHhpbiBjYW0gxJFvYW4gYsOgaSB0aeG7g3UgbHXhuq1uIOKAnFBow6JuIHRpY2ggY8OhYyB54bq/dSB04buRIOG6o25oIGjGsOG7n25nIMSR4bq/biBow6BuaCB2aSBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIGtow6FjaCBow6BuZyB2aeG7hW4gdGjDtG5n4oCdIGzDoCBiw6BpIGLDoW8gZW0gdGjhu7FjIGhp4buHbiBkxrDhu5tpIHPhu7EgY2jhu4kgZOG6q24gY+G7p2EgVGhTLlRy4bqnbiBN4bqhbmggVMaw4budbmcgQ8OhYyBz4buRIGxp4buHdSwgdMOgaSBsaeG7h3UgdsOgIG7hu5lpIGR1bmcgY8OzIG5ndeG7k24gZ+G7kWMgcsO1IHLDoG5nIMSRxrDhu6NjIGVtIHRyw61jaCBk4bqrbiB0cm9uZyBwaOG6p24gdMOgaSBsaeG7h3UgdGhhbSBraOG6o28gdsOgIHBo4bulIGzhu6VjLiBFbSB4aW4gY2FtIMSRb2FuIHbDoCBjaOG7i3UgdHLDoWNoIG5oaeG7h20gduG7gSBt4buNaSB0aMO0bmcgdGluIHRyb25nIGLDoGkgdGnhu4N1IGx14bqtbiBtw7RuIFBow6JuIHTDrWNoIGThu68gbGnhu4d1IMSR4buLbmggdMOtbmguDQoNCi0tLS0tDQoNCiMgKipDSMavxqBORyAxOiBQSOG6pk4gTeG7niDEkOG6plUqKg0KDQojIyAqKjEuMSBMw70gZG8gY2jhu41uIMSR4buBIHTDoGkqKg0KDQpUcm9uZyBuaOG7r25nIG7Eg20gZ+G6p24gxJHDonksIG5nw6BuaCB2aeG7hW4gdGjDtG5nIGNo4bupbmcga2nhur9uIHPhu7EgY+G6oW5oIHRyYW5oIG5nw6B5IGPDoG5nIGto4buRYyBsaeG7h3QgZ2nhu69hIGPDoWMgbmjDoCBjdW5nIGPhuqVwIGThu4tjaCB24bulLCBraMO0bmcgY2jhu4kg4bufIGtow61hIGPhuqFuaCBnacOhIGPhuqMgbcOgIGPDsm4gduG7gSBjaOG6pXQgbMaw4bujbmcgZOG7i2NoIHbhu6UsIMSR4buZIHBo4bunIHPDs25nLCBjw6FjIGfDs2kga2h1eeG6v24gbcOjaSB2w6AgY2jDrW5oIHPDoWNoIGNoxINtIHPDs2Mga2jDoWNoIGjDoG5nLiBUcm9uZyBi4buRaSBj4bqjbmggxJHDsywgdmnhu4djIGdp4buvIGNow6JuIGtow6FjaCBow6BuZyBjxakgdHLhu58gdGjDoG5oIG3hu5l0IHnhur91IHThu5EgdGhlbiBjaOG7kXQgcXV54bq/dCDEkeG7i25oIHPhu7EgcGjDoXQgdHJp4buDbiBi4buBbiB24buvbmcgdsOgIGzhu6NpIHRo4bq/IGPhuqFuaCB0cmFuaCBj4bunYSBkb2FuaCBuZ2hp4buHcC4gQ8OhYyBjw7RuZyB0eSBraMO0bmcgY2jhu4kgY+G6p24gbeG7nyBy4buZbmcgdGjhu4sgcGjhuqduIG3DoCBjw7JuIHBo4bqjaSDEkeG7kWkgbeG6t3QgduG7m2kgdGjDoWNoIHRo4bupYyBs4bubbiBoxqFuIGzDoCBnaeG6o20gdGhp4buDdSB04bu3IGzhu4cgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBt4buZdCBjaOG7iSBz4buRIHF1YW4gdHLhu41uZyBwaOG6o24gw6FuaCBt4bupYyDEkeG7mSBow6BpIGzDsm5nIHbDoCB0cnVuZyB0aMOgbmggY+G7p2Ega2jDoWNoIGjDoG5nLg0KDQpUaGVvIG5naGnDqm4gY+G7qXUgY+G7p2EgSGFydmFyZCBCdXNpbmVzcyBSZXZpZXcsIGNoaSBwaMOtIMSR4buDIHRodSBow7p0IG3hu5l0IGtow6FjaCBow6BuZyBt4bubaSBjw7MgdGjhu4MgY2FvIGfhuqVwIDUgxJHhur9uIDI1IGzhuqduIHNvIHbhu5tpIGNoaSBwaMOtIGdp4buvIGNow6JuIG3hu5l0IGtow6FjaCBow6BuZyBoaeG7h24gdOG6oWkuIERvIMSRw7MsIHRoYXkgdsOsIHThuq1wIHRydW5nIGhvw6BuIHRvw6BuIHbDoG8gdmnhu4djIG3hu58gcuG7mW5nIGPGoSBz4bufIGtow6FjaCBow6BuZyBt4bubaSwgbmhp4buBdSBkb2FuaCBuZ2hp4buHcCDEkcOjIHbDoCDEkWFuZyBjaHV54buDbiBoxrDhu5tuZyBzYW5nIMSR4bqndSB0xrAgdsOgbyBjw6FjIGdp4bqjaSBwaMOhcCBwaMOibiB0w61jaCBow6BuaCB2aSBraMOhY2ggaMOgbmcsIG5o4bqxbSBwaMOhdCBoaeG7h24gc+G7m20gY8OhYyB0w61uIGhp4buHdSBj4bqjbmggYsOhbyB24buBIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UuIFZp4buHYyBk4buxIMSRb8OhbiBjaMOtbmggeMOhYyBraMOhY2ggaMOgbmcgY8OzIG5ndXkgY8ahIHLhu51pIGLhu48gY2hvIHBow6lwIGRvYW5oIG5naGnhu4dwIGNo4bunIMSR4buZbmcgY2FuIHRoaeG7h3Aga+G7i3AgdGjhu51pIHRow7RuZyBxdWEgY8OhYyBjaMawxqFuZyB0csOsbmggxrB1IMSRw6NpLCB0xrAgduG6pW4gY8OhIG5ow6JuIGjDs2EgaG/hurdjIGPhuqNpIHRoaeG7h24gY2jhuqV0IGzGsOG7o25nIGThu4tjaCB24bulLg0KDQpCw6puIGPhuqFuaCDDvSBuZ2jEqWEgdGjhu7FjIHRp4buFbiB0cm9uZyBob+G6oXQgxJHhu5luZyBxdeG6o24gdHLhu4sgdsOgIGNoxINtIHPDs2Mga2jDoWNoIGjDoG5nLCB2aeG7h2MgbmdoacOqbiBj4bupdSB24buBIGjDoG5oIHZpIHLhu51pIGLhu48gY8OybiBt4bufIHJhIGPGoSBo4buZaSDhu6luZyBk4bulbmcgY8OhYyBtw7QgaMOsbmggcGjDom4gdMOtY2ggxJHhu4tuaCBsxrDhu6NuZywgxJHhurdjIGJp4buHdCBsw6AgY8OhYyB0aHXhuq10IHRvw6FuIGjhu41jIG3DoXkgdHJvbmcgbMSpbmggduG7sWMga2hvYSBo4buNYyBk4buvIGxp4buHdS4gQ8OhYyBtw7QgaMOsbmggbsOgeSBjaG8gcGjDqXAgeOG7rSBsw70ga2jhu5FpIGzGsOG7o25nIGzhu5tuIGThu68gbGnhu4d1LCBwaMOhdCBoaeG7h24gbeG7kWkgcXVhbiBo4buHIHRp4buBbSDhuqluIGdp4buvYSBjw6FjIGJp4bq/biB2w6AgdOG7kWkgxrB1IGjDs2EgcXXDoSB0csOsbmggcmEgcXV54bq/dCDEkeG7i25oLiBU4burIMSRw7MsIGRvYW5oIG5naGnhu4dwIGPDsyB0aOG7gyBuw6JuZyBjYW8gaGnhu4d1IHF14bqjIGhv4bqhdCDEkeG7mW5nIGtpbmggZG9hbmgsIMSR4buTbmcgdGjhu51pIG1hbmcgbOG6oWkgZ2nDoSB0cuG7iyBnaWEgdMSDbmcgYuG7gW4gduG7r25nLg0KDQpDaMOtbmggdsOsIG5o4buvbmcgbMO9IGRvIHRyw6puLCB2aeG7h2MgbOG7sWEgY2jhu41uIMSR4buBIHTDoGkg4oCcUGjDom4gdMOtY2ggdsOgIGThu7EgxJFvw6FuIGto4bqjIG7Eg25nIHLhu51pIGLhu48ga2jDoWNoIGjDoG5nIHRyb25nIG5nw6BuaCB2aeG7hW4gdGjDtG5n4oCdIGtow7RuZyBjaOG7iSBwaOG6o24gw6FuaCB0w61uaCBj4bqlcCB0aGnhur90IGPhu6dhIHbhuqVuIMSR4buBIHRyb25nIHRo4buxYyB0aeG7hW4gbcOgIGPDsm4gdGjhu4MgaGnhu4duIHh1IGjGsOG7m25nIG5naGnDqm4gY+G7qXUgaGnhu4duIMSR4bqhaSwga+G6v3QgaOG7o3AgZ2nhu69hIHF14bqjbiB0cuG7iyBraMOhY2ggaMOgbmcgdsOgIGtob2EgaOG7jWMgZOG7ryBsaeG7h3UuIFRow7RuZyBxdWEgxJHhu4EgdMOgaSBuw6B5LCBuZ8aw4budaSBuZ2hpw6puIGPhu6l1IGPDsyBjxqEgaOG7mWkgdGnhur9wIGPhuq1uIGPDoWMgcGjGsMahbmcgcGjDoXAgcGjDom4gdMOtY2ggxJHhu4tuaCBsxrDhu6NuZyB0acOqbiB0aeG6v24sIMSR4buTbmcgdGjhu51pIMSR4buBIHh14bqldCBjw6FjIGdp4bqjaSBwaMOhcCBjw7MgY8ahIHPhu58gbmjhurFtIG7Dom5nIGNhbyBjaOG6pXQgbMaw4bujbmcgZOG7i2NoIHbhu6UgdsOgIGdp4bqjbSB0aGnhu4N1IHThu7cgbOG7hyBy4budaSBi4buPIGtow6FjaCBow6BuZyBjaG8gZG9hbmggbmdoaeG7h3Agdmnhu4VuIHRow7RuZy4NCg0KIyMgKioxLjIgTeG7pWMgdGnDqnUgIG5naGnDqm4gY+G7qXUgdsOgIGPDonUgaOG7j2kgbmdoacOqbiBj4bupdSoqDQoNCk3hu6VjIHRpw6p1IGPhu6UgdGjhu4MgY+G7p2EgxJHhu4EgdMOgaSDigJxQaMOibiB0w61jaCBjw6FjIHnhur91IHThu5Eg4bqjbmggaMaw4bufbmcgxJHhur9uIGjDoG5oIHZpIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2Ega2jDoWNoIGjDoG5nIHZp4buFbiB0aMO0bmfigJ0gbMOgIHjDoWMgxJHhu4tuaCBuaOG7r25nIHnhur91IHThu5EgcXVhbiB0cuG7jW5nIHTDoWMgxJHhu5luZyDEkeG6v24ga2jhuqMgbsSDbmcga2jDoWNoIGjDoG5nIHF1eeG6v3QgxJHhu4tuaCBy4budaSBi4buPIGThu4tjaCB24bulLCDEkeG7k25nIHRo4budaSB4w6J5IGThu7FuZyBtw7QgaMOsbmggZOG7sSBiw6FvIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gxJHhu4MgaOG7lyB0cuG7oyBkb2FuaCBuZ2hp4buHcCB0cm9uZyB2aeG7h2Mgbmjhuq1uIGRp4buHbiBuaMOzbSBraMOhY2ggaMOgbmcgY8OzIG5ndXkgY8ahIGNhby4gVGjDtG5nIHF1YSB2aeG7h2Mgc+G7rSBk4bulbmcgY8OhYyBtw7QgaMOsbmggaOG7k2kgcXV5IG5o4buLIHBow6JuIG5oxrAgbG9naXQsIHByb2JpdCB2w6AgY2xvZ2xvZy4gS+G6v3QgcXXhuqMgbmdoacOqbiBj4bupdSBraMO0bmcgY2jhu4kgZ2nDunAgxJFvIGzGsOG7nW5nIG3hu6ljIMSR4buZIOG6o25oIGjGsOG7n25nIGPhu6dhIHThu6tuZyB54bq/dSB04buRIG3DoCBjw7JuIGN1bmcgY+G6pXAgY8ahIHPhu58gxJHhu4MgZG9hbmggbmdoaeG7h3AgxJHGsGEgcmEgY8OhYyBnaeG6o2kgcGjDoXAgZ2nhu68gY2jDom4ga2jDoWNoIGjDoG5nIGhp4buHdSBxdeG6oyBoxqFuLg0KDQojIyAqKjEuMyDEkOG7kWkgdMaw4bujbmcgdsOgIHBo4bqhbSB2aSBuZ2hpw6puIGPhu6l1KioNCg0KxJDhu5FpIHTGsOG7o25nIG5naGnDqm4gY+G7qXUgY+G7p2EgxJHhu4EgdMOgaSBsw6AgaMOgbmggdmkgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoY2h1cm4pIGPhu6dhIGtow6FjaCBow6BuZyB0cm9uZyBsxKluaCB24buxYyB2aeG7hW4gdGjDtG5nLg0KDQpQaOG6oW0gdmkgbmdoacOqbiBj4bupdSB04bqtcCB0cnVuZyB2w6BvIHZp4buHYyBwaMOibiB0w61jaCBk4buvIGxp4buHdSBraMOhY2ggaMOgbmcgY+G7p2EgbeG7mXQgZG9hbmggbmdoaeG7h3Agdmnhu4VuIHRow7RuZywgYmFvIGfhu5NtIGPDoWMgdGjDtG5nIHRpbiBuaMawIGPDoWMgbG/huqFpIGjhu6NwIMSR4buTbmcsY8OhYyBsb+G6oWkgaMOsbmggZOG7i2NoIHbhu6UgSW50ZXJuZXQsICBraMOhY2ggaMOgbmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMsIMSR4buZIHR14buVaS4NCg0KIyMgKioxLjQgUGjGsMahbmcgcGjDoXAgbmdoacOqbiBj4bupdSoqDQoNCk5naGnDqm4gY+G7qXUgc+G7rSBk4bulbmcgcGjGsMahbmcgcGjDoXAgcGjDom4gdMOtY2ggZOG7ryBsaeG7h3UgxJHhu4tuaCB0w61uaCBr4bq/dCBo4bujcCDEkeG7i25oIGzGsOG7o25nLiBUcsaw4bubYyBo4bq/dCwgcGjDom4gdMOtY2ggxJHhu4tuaCB0w61uaCDEkcaw4bujYyDDoXAgZOG7pW5nIMSR4buDIHThu5VuZyBo4bujcCBjxqEgc+G7nyBsw70gdGh1eeG6v3QgdsOgIGPDoWMgbmdoacOqbiBj4bupdSBsacOqbiBxdWFuIG5o4bqxbSB4w6J5IGThu7FuZyBtw7QgaMOsbmggcGjDom4gdMOtY2guIFRp4bq/cCB0aGVvLCBuZ2hpw6puIGPhu6l1IHPhu60gZOG7pW5nIHRo4buRbmcga8OqIG3DtCB04bqjIMSR4buDIHRyw6xuaCBiw6B5IMSR4bq3YyDEkWnhu4NtIGPGoSBi4bqjbiBj4bunYSBraMOhY2ggaMOgbmcgdsOgIHRo4buRbmcga8OqIHN1eSBkaeG7hW4gxJHhu4Mga2nhu4NtIMSR4buLbmggbeG7kWkgcXVhbiBo4buHIGdp4buvYSBjw6FjIGJp4bq/bi4gQ3Xhu5FpIGPDuW5nLCBiYSBtw7QgaMOsbmggaOG7k2kgcXV5IG5o4buLIHBow6JuIGfhu5NtIGxvZ2l0LCBwcm9iaXQgdsOgIGNsb2dsb2cgxJHGsOG7o2Mgw6FwIGThu6VuZyBuaOG6sW0gxrDhu5tjIGzGsOG7o25nIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2Ega2jDoWNoIGjDoG5nLCB04burIMSRw7MgxJHDoW5oIGdpw6EgbeG7qWMgxJHhu5kg4bqjbmggaMaw4bufbmcgY+G7p2EgY8OhYyB54bq/dSB04buRIGxpw6puIHF1YW4gxJHhur9uIGjDoG5oIHZpIG7DoHkuDQoNCiMjICoqMS41IEvhur90IGPhuqV1IGLDoGkgbmdoacOqbiBj4bupdSoqDQoNCkNoxrDGoW5nIDE6IFBo4bqnbiBt4bufIMSR4bqndSBDaMawxqFuZyBuw6B5IGdp4bubaSB0aGnhu4d1IHThu5VuZyBxdWFuIG5naGnDqm4gY+G7qXUsIGJhbyBn4buTbTogxJHhurd0IHbhuqVuIMSR4buBIG5naGnDqm4gY+G7qXUsIG3hu6VjIHRpw6p1IG5naGnDqm4gY+G7qXUsIMSR4buRaSB0xrDhu6NuZyBuZ2hpw6puIGPhu6l1LCBwaOG6oW0gdmkgdsOgIHBoxrDGoW5nIHBow6FwIG5naGnDqm4gY+G7qXUgdsOgIGvhur90IGPhuqV1IGLDoGkgbmdoacOqbiBj4bupdS4NCg0KQ2jGsMahbmcgMjogQ8ahIHPhu58gbMO9IHRodXnhur90IOG7niBjaMawxqFuZyBuw6B5IHThu5VuZyBxdWFuIHbhu4EgaMOgbmggdmkgcuG7nWkgYuG7jyBk4buLY2ggduG7pSwgY8OhYyB54bq/dSB04buRIHTDoWMgxJHhu5luZyDEkeG6v24gaMOgbmggdmkgcuG7nWkgYuG7jyBk4buLY2ggduG7pSwgY8OhYyBsw70gdGh1eeG6v3QgduG7gSBtw7QgaMOsbmggaOG7k2kgcXV5IG5o4buLIHBo4bqnbiB2w6AgdOG7lW5nIHF1YW4gbmdoacOqbiBj4bupdS4NCg0KQ2jGsMahbmcgMzogS+G6v3QgcXXhuqMgbmdoacOqbiBj4bupdSB2w6Aga+G6v3QgbHXhuq1uIENoxrDGoW5nIG7DoHkgdGjhu7FjIGhp4buHbiBwaMOibiB0w61jaCDEkcahbiBiaeG6v24gxJHhur9uIGjDoG5oIHZpIHLhu51pIGLhu48gZOG7i2NoIHbhu6Ugdmnhu4VuIHRow7RuZyBj4bunYSBraMOhY2ggaMOgbmcuIFNhdSDEkcOzIHBow6JuIHTDrWNoIMSRYSBiaeG6v24gxJHhur9uIGjDoG5oIHZpIHLhu51pIGLhu48gZOG7i2NoIHbhu6Ugdmnhu4VuIHRow7RuZyBj4bunYSBraMOhY2ggaMOgbmcgcuG7k2kgc2F1IMSRw7MgxJHGsGEga+G6v3QgbHXhuq1uIHbhu4EgbmdoacOqbiBj4bupdS4NCg0KLS0tLS0tDQoNCiMgKipDSMavxqBORyAyOiBDxqAgU+G7niBMw50gVEhVWeG6vlQgVsOAIFBIxq/GoE5HIFBIw4FQIE5HSEnDik4gQ+G7qFUqKg0KDQojIyAqKjIuMSBU4buVbmcgcXVhbiB24buBIGjDoG5oIHZpIHLhu51pIGLhu48gZOG7i2NoIHbhu6UqKg0KDQogICBS4budaSBi4buPIGThu4tjaCB24bulIGzDoCB0w6xuaCB0cuG6oW5nIGtow6FjaCBow6BuZyBuZ+G7q25nIHPhu60gZOG7pW5nIHPhuqNuIHBo4bqpbSBob+G6t2MgZOG7i2NoIHbhu6UgbeG7mXQgZG9hbmggbmdoaeG7h3AgaG/hurdjIGNodXnhu4NuIHNhbmcgbmjDoCBjdW5nIGtow6FjIHbDrCBuaGnhu4F1IGvDvSBkbyBraMOhYyBuaGF1LCBjaOG6s25nIGjhuqFuIG5oxrAgY2jhuqV0IGzGsOG7o25nIGThu4tjaCB24bulIGtow7RuZyDEkcOhcCDhu6luZyBr4buzIHbhu41uZywgZ2nDoSBj4bqjIGtow7RuZyBj4bqhbmggdHJhbmggaG/hurdjIGPDsyBz4buxIHh14bqldCBoaeG7h24gY+G7p2EgY8OhYyDGsHUgxJHDo2kgaOG6pXAgZOG6q24gdOG7qyDEkeG7kWkgdGjhu6cuIFZp4buHYyBwaMOibiB0w61jaCBow6BuaCB2w6wgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBjw7Mgw70gbmdoxKlhIMSR4bq3YyBiaeG7h3QgcXVhbiB0cm9uZyB0cm9uZyBi4buRaSBj4bqjbmggdGjhu4sgdHLGsOG7nW5nIGPhuqFuaCB0cmFuaCBnYXkgZ+G6r3QgbmjGsCBoaeG7h24gbnlhLCBraGkgY2hpIHBow60gxJHhu4MgdGh1IGjDunQgbeG7mXQga2jDoWNoIGjDoG5nIG3hu5tpIHRoxrDhu51uZyBjYW8gaMahbiBuaGnhu4F1IHNvIHbhu5tpIGNoaSBwaMOtIGR1eSB0csOsIGtow6FjaCBow6BuZyBoaeG7h24gdOG6oWkuIMSQaeG7gXUgbsOgeSBraGnhur9uIGNobyBkb2FuaCBuZ2hp4buHcCwgxJHhurdjIGLhur90IHRyb25nIG5nw6BuaCB2aeG7hW4gdGjDtG5nIGx1w7RuIGPhuqduIGPDsyBjaGnhur9uIGzGsOG7o2MgcXXhuqNuIHRy4buLIHbDoCBk4buxIGLDoW8ga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgaGnhu4N1IHF14bqjIG5o4bqxbSBnaeG6o20gdGhp4buDdSB04bu3IGzhu4cga2jDoWNoIGjDoG5nIHLhu51pIGLhu48uDQoNClPhu7EgcuG7nWkgYuG7jyBj4bunYSBraMOhY2ggaMOgbmcgxJHGsOG7o2MgY2hpYSB0aMOgbmggaGFpIGThuqFuZy4gVGjhu6kgbmjhuqV0IGzDoCBk4bqhbmcgY2jhu6cgxJHhu5luZywga2hpIGtow6FjaCBow6BuZyB04buxIHF1eeG6v3QgxJHhu4tuaCBjaOG6pW0gZOG7qXQgaOG7o3AgxJHhu5NuZyBk4buLY2ggduG7pSBkbyBraMO0bmcgY8OybiBuaHUgY+G6p3UgaG/hurdjIGPhuqNtIHRo4bqleSBraMO0bmcgaMOgaSBsw7JuZy4gVGjhu6kgaGFpIGzDoCB0aOG7pSDEkeG7mW5nLCB44bqjeSByYSBraGkga2jDoWNoIGjDoG5nIGtow7RuZyBjaOG7pyDEkeG7mW5nIGdpYSBo4bqhbiBo4bujcCDEkeG7mW5nIGhv4bq3YyBk4buLY2ggduG7pSBt4buZdCBjw6FjaCB04buxIG5oacOqbi4gVHJvbmcgbmfDoG5oIHZp4buFbiB0aMO0bmcgVmnhu4d0IE5hbSwgdMOsbmggdHLhuqFuZyBjaHVybiDEkcaw4bujYyBnaGkgbmjhuq1uIGtow6EgcGjhu5UgYmnhur9uLCBt4buZdCBwaOG6p24gZG8gc+G7sSBj4bqhbmggdHJhbmggbeG6oW5oIG3hur0gduG7gSBnacOhIGPGsOG7m2MsIGPDoWMgY2jGsMahbmcgdHLDrG5oIGtodXnhur9uIG3Do2kgbGnDqm4gdOG7pWMgdsOgIHPhu7Ega2jDoWMgYmnhu4d0IHbhu4EgY2jhuqV0IGzGsOG7o25nIGThu4tjaCB24bulIGdp4buvYSBjw6FjIG5ow6AgbeG6oW5nLiBUaGVvIG3hu5l0IHPhu5EgYsOhbyBjw6FvIG5nw6BuaCwgdOG7tyBs4buHIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIHZp4buFbiB0aMO0bmcg4bufIFZp4buHdCBOYW0gduG6q24gZHV5IHRyw6wg4bufIG3hu6ljIGNhbywgxJHhurdjIGJp4buHdCB0cm9uZyBwaMOibiBraMO6YyBraMOhY2ggaMOgbmcgc+G7rSBk4bulbmcgZOG7i2NoIHbhu6UgdHLhuqMgdHLGsOG7m2MgaG/hurdjIGfDs2kgY8aw4bubYyBuZ+G6r24gaOG6oW4uDQoNCk3hu6VjIHRpw6p1IHF14bqjbiB0cuG7iyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBraMO0bmcgY2jhu4kgZOG7q25nIGzhuqFpIOG7nyB2aeG7h2Mgbmjhuq1uIGRp4buHbiBraMOhY2ggaMOgbmcgY8OzIG5ndXkgY8ahIHLhu51pIGLhu48gbcOgIGPDsm4gYmFvIGfhu5NtIHZp4buHYyB4w6J5IGThu7FuZyBjw6FjIG3DtCBow6xuaCBk4buxIGLDoW8gbmjhurFtIMSRxrBhIHJhIGJp4buHbiBwaMOhcCBnaeG7ryBjaMOibiBoaeG7h3UgcXXhuqMuIFZp4buHYyDDoXAgZOG7pW5nIGPDoWMgbcO0IGjDrG5oIHBow6JuIHTDrWNoIHbDoCBk4buxIGLDoW8gY2h1cm4gZ2nDunAgZG9hbmggbmdoaeG7h3AgdOG7kWkgxrB1IGjDs2Egbmd14buTbiBs4buxYywgdOG6rXAgdHJ1bmcgdsOgbyBuaMOzbSBraMOhY2ggaMOgbmcgdGnhu4FtIG7Eg25nIHbDoCB4w6J5IGThu7FuZyBjaMOtbmggc8OhY2ggY2jEg20gc8OzYyBwaMO5IGjhu6NwLCBxdWEgxJHDsyBuw6JuZyBjYW8gc+G7sSBow6BpIGzDsm5nIHbDoCBsw7JuZyB0cnVuZyB0aMOgbmggY+G7p2Ega2jDoWNoIGjDoG5nLg0KDQojIyAqKjIuMiBDw6FjIHnhur91IHThu5EgdMOhYyDEkeG7mW5nIMSR4bq/biBow6BuaCB2aSBy4budaSBi4buPIGThu4tjaCB24bulKioNCg0KVHJvbmcgbmdoacOqbiBj4bupdSBuw6B5LCBi4buRbiB54bq/dSB04buRIMSRxrDhu6NjIGzhu7FhIGNo4buNbiBn4buTbTogbG/huqFpIGjhu6NwIMSR4buTbmcgKENvbnRyYWN0KSwgdMOsbmggdHLhuqFuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyAoRGVwZW5kZW50cyksIMSR4buZIHR14buVaSBraMOhY2ggaMOgbmcgKFNlbmlvciBDaXRpemVuKSwgdsOgIGxv4bqhaSBk4buLY2ggduG7pSBJbnRlcm5ldCAoSW50ZXJuZXQgU2VydmljZSkuIEPDoWMgeeG6v3UgdOG7kSBuw6B5IGtow7RuZyBjaOG7iSDEkeG6oWkgZGnhu4duIGNobyDEkeG6t2MgxJFp4buDbSBuaMOibiBraOG6qXUgaOG7jWMgdsOgIGjDoG5oIHZpIHPhu60gZOG7pW5nIGThu4tjaCB24bulIGPhu6dhIGtow6FjaCBow6BuZywgbcOgIGPDsm4gcGjhuqNuIMOhbmggbmjhu69uZyB54bq/dSB04buRIGNoaeG6v24gbMaw4bujYyBtw6AgZG9hbmggbmdoaeG7h3Agdmnhu4VuIHRow7RuZyBjw7MgdGjhu4MgdMOhYyDEkeG7mW5nIMSR4buDIGdp4bqjbSB04bu3IGzhu4cgcuG7nWkgYuG7jyBk4buLY2ggduG7pS4NCg0KVGjhu6kgbmjhuqV0LCBsb+G6oWkgaOG7o3AgxJHhu5NuZyBsw6AgeeG6v3UgdOG7kSBtYW5nIHTDrW5oIHLDoG5nIGJ14buZYyBt4bqhbmggbeG6vSBuaOG6pXQgxJHhu5FpIHbhu5tpIGjDoG5oIHZpIGR1eSB0csOsIGThu4tjaCB24bulLiBOaOG7r25nIGtow6FjaCBow6BuZyBrw70gaOG7o3AgxJHhu5NuZyBkw6BpIGjhuqFuLCBjaOG6s25nIGjhuqFuIGjhu6NwIMSR4buTbmcgMTIgaG/hurdjIDI0IHRow6FuZywgdGjGsOG7nW5nIMOtdCBy4budaSBi4buPIGThu4tjaCB24bulIGRvIHBo4bqjaSBjaOG7i3UgcGjDrSBwaOG6oXQga2hpIGjhu6d5IG5nYW5nIHbDoCDEkcaw4bujYyBoxrDhu59uZyBjw6FjIMawdSDEkcOjaSDEkWkga8OobSBuaMawIGdp4bqjbSBnacOhIGhv4bq3YyB04bq3bmcgdGjDqm0gZOG7i2NoIHbhu6UuIMSQaeG7gXUgbsOgeSB04bqhbyBuw6puIHTDom0gbMO9IGfhuq9uIGLDsyBsw6J1IGTDoGkuIE5nxrDhu6NjIGzhuqFpLCBraMOhY2ggaMOgbmcgc+G7rSBk4bulbmcgaOG7o3AgxJHhu5NuZyB0cuG6oyB0csaw4bubYyBob+G6t2MgaOG7o3AgxJHhu5NuZyB0aMOhbmcgdGjGsOG7nW5nIGxpbmggaG/huqF0IHRyb25nIHZp4buHYyBjaHV54buDbiDEkeG7lWkgbmjDoCBt4bqhbmcga2jDoWMga2hpIHBow6F0IGhp4buHbiBk4buLY2ggduG7pSBraMO0bmcgxJHDoXAg4bupbmcgbmh1IGPhuqd1IGhv4bq3YyBraGkgxJHhu5FpIHRo4bunIHR1bmcgcmEgY2jGsMahbmcgdHLDrG5oIGtodXnhur9uIG3Do2kgaOG6pXAgZOG6q24gaMahbi4gRG8gduG6rXksIGRvYW5oIG5naGnhu4dwIHZp4buFbiB0aMO0bmcgdGjGsOG7nW5nIHThuq1wIHRydW5nIHbDoG8gdmnhu4djIHRoaeG6v3Qga+G6vyBjw6FjIGfDs2kgaOG7o3AgxJHhu5NuZyBkw6BpIGjhuqFuIGvhur90IGjhu6NwIHbhu5tpIGNow61uaCBzw6FjaCBjaMSDbSBzw7NjIMSR4bq3YyBiaeG7h3QgxJHhu4MgZ2nhuqNtIHThu7cgbOG7hyBjaHVybi4NCg0KVGjhu6kgaGFpLCB0w6xuaCB0cuG6oW5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIChEZXBlbmRlbnRzKSB0aOG7gyBoaeG7h24gdHLDoWNoIG5oaeG7h20gZ2lhIMSRw6xuaCB2w6Agbmh1IGPhuqd1IHPhu60gZOG7pW5nIGThu4tjaCB24bulIOG7lW4gxJHhu4tuaC4gTmjhu69uZyBraMOhY2ggaMOgbmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgKHbDrSBk4bulOiBjb24gbmjhu48sIG5nxrDhu51pIGdpw6AsIG5nxrDhu51pIHRow6JuIGPhuqduIGNoxINtIHPDs2MpIHRoxrDhu51uZyDGsHUgdGnDqm4gbeG7mXQgZOG7i2NoIHbhu6Ugdmnhu4VuIHRow7RuZyDhu5VuIMSR4buLbmggxJHhu4MgcGjhu6VjIHbhu6UgaOG7jWMgdOG6rXAgdHLhu7FjIHR1eeG6v24sIGdp4bqjaSB0csOtIGdpYSDEkcOsbmggaG/hurdjIGxpw6puIGzhuqFjLiBI4buNIGPDsyB4dSBoxrDhu5tuZyDDrXQgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBoxqFuIHbDrCB2aeG7h2MgdGhheSDEkeG7lWkgbmjDoCBjdW5nIGPhuqVwIGPDsyB0aOG7gyBnw6J5IGdpw6FuIMSRb+G6oW4gdsOgIOG6o25oIGjGsOG7n25nIMSR4bq/biBjw6FjIHRow6BuaCB2acOqbiB0cm9uZyBnaWEgxJHDrG5oLiBOZ8aw4bujYyBs4bqhaSwga2jDoWNoIGjDoG5nIMSR4buZYyB0aMOibiBob+G6t2Mga2jDtG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGPDsyB4dSBoxrDhu5tuZyBsaW5oIGhv4bqhdCBoxqFuIHRyb25nIHZp4buHYyB0aGF5IMSR4buVaSBk4buLY2ggduG7pSDEkeG7gyB04buRaSDGsHUgY2hpIHBow60sIGThuqtuIMSR4bq/biBraOG6oyBuxINuZyBy4budaSBi4buPIGNhbyBoxqFuLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSwgc+G7sSBoaeG7h24gZGnhu4duIGPhu6dhIG5nxrDhu51pIHBo4bulIHRodeG7mWMgbMOgIG3hu5l0IHnhur91IHThu5EgbMOgbSB0xINuZyBt4bupYyDEkeG7mSB0cnVuZyB0aMOgbmggduG7m2kgZOG7i2NoIHbhu6Ugdmnhu4VuIHRow7RuZy4NCg0KVGjhu6kgYmEsIMSR4buZIHR14buVaSBraMOhY2ggaMOgbmcgKFNlbmlvciBDaXRpemVuKSBsw6AgeeG6v3UgdOG7kSBuaMOibiBraOG6qXUgaOG7jWMgcXVhbiB0cuG7jW5nIHRo4buDIGhp4buHbiBz4buxIGtow6FjIGJp4buHdCB0cm9uZyBow6BuaCB2aSB0acOqdSBkw7luZy4gS2jDoWNoIGjDoG5nIGNhbyB0deG7lWkgdGjGsOG7nW5nIMOtdCBjw7Mgbmh1IGPhuqd1IHRo4butIG5naGnhu4dtIGPDoWMgZ8OzaSBk4buLY2ggduG7pSBt4bubaSB2w6AgxrB1IHRpw6puIHPhu7Eg4buVbiDEkeG7i25oLCBuw6puIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIHRo4bqlcCBoxqFuIHNvIHbhu5tpIG5ow7NtIGtow6FjaCBow6BuZyB0cuG6uyB0deG7lWkuIEjhu40gY8Wpbmcgw610IG5o4bqheSBj4bqjbSBoxqFuIHbhu5tpIGPDoWMga2h1eeG6v24gbcOjaSBnacOhIHLhursgdsOgIGNvaSB0cuG7jW5nIGNo4bqldCBsxrDhu6NuZyBwaOG7pWMgduG7pSwgxJHhurdjIGJp4buHdCBsw6Agc+G7sSBo4buXIHRy4bujIHRy4buxYyB0aeG6v3AgdOG7qyBuaMOibiB2acOqbiBjaMSDbSBzw7NjIGtow6FjaCBow6BuZy4gVHJvbmcga2hpIMSRw7MsIG5ow7NtIGtow6FjaCBow6BuZyB0cuG6uywgxJHhurdjIGJp4buHdCBsw6AgdGjhur8gaOG7hyBaIGhv4bq3YyBNaWxsZW5uaWFscywgdGjGsOG7nW5nIG7Eg25nIMSR4buZbmcsIGFtIGhp4buDdSBjw7RuZyBuZ2jhu4cgdsOgIHPhurVuIHPDoG5nIGNodXnhu4NuIMSR4buVaSBk4buLY2ggduG7pSBu4bq/dSB0w6xtIHRo4bqleSBnw7NpIGPGsOG7m2MgY8OzIHThu5FjIMSR4buZIGNhbywgdGnhu4duIMOtY2ggcGhvbmcgcGjDuiBob+G6t2MgY2hpIHBow60gaOG7o3AgbMO9IGjGoW4uDQoNCkN14buRaSBjw7luZywgbG/huqFpIGThu4tjaCB24bulIEludGVybmV0IChJbnRlcm5ldCBTZXJ2aWNlKSBsw6AgeeG6v3UgdOG7kSBr4bu5IHRodeG6rXQgdGhlbiBjaOG7kXQg4bqjbmggaMaw4bufbmcgxJHhur9uIHF1eeG6v3QgxJHhu4tuaCBkdXkgdHLDrCBk4buLY2ggduG7pS4gS2jDoWNoIGjDoG5nIHPhu60gZOG7pW5nIGPDtG5nIG5naOG7hyBGaWJlciBvcHRpYyB0aMaw4budbmcgaMOgaSBsw7JuZyBoxqFuIG5o4budIHThu5FjIMSR4buZIHRydXkgY+G6rXAgY2FvIHbDoCDEkeG7mSDhu5VuIMSR4buLbmggdOG7kXQsIHThu6sgxJHDsyBnaeG6o20ga2jhuqMgbsSDbmcgcuG7nWkgYuG7jy4gTmfGsOG7o2MgbOG6oWksIG5o4buvbmcga2jDoWNoIGjDoG5nIHbhuqtuIHPhu60gZOG7pW5nIERTTCBob+G6t2MgY8OhYyBk4buLY2ggduG7pSBjxakgZOG7hSBjaHV54buDbiDEkeG7lWkgc2FuZyBuaMOgIGN1bmcgY+G6pXAga2jDoWMga2hpIG5o4bqtbiB0aOG6pXkgZOG7i2NoIHbhu6Uga2jDtG5nIMSRw6FwIOG7qW5nIG5odSBj4bqndS4gQsOqbiBj4bqhbmggxJHDsywgbmjDs20ga2jDoWNoIGjDoG5nIGtow7RuZyDEkcSDbmcga8O9IEludGVybmV0IHThu6sgbmjDoCBt4bqhbmcgKE5vIEludGVybmV0KSBjw7MgbeG7qWMgxJHhu5kgZ+G6r24ga+G6v3QgdGjhuqVwIHbDoCBk4buFIHLhu51pIGLhu48gaMahbiB2w6wgaOG7jSBraMO0bmcgcGjhu6UgdGh14buZYyB2w6BvIGThu4tjaCB24bulIGNow61uaCBj4bunYSBkb2FuaCBuZ2hp4buHcC4gxJDhu5FpIHbhu5tpIGPDoWMgY8O0bmcgdHkgdmnhu4VuIHRow7RuZywgdmnhu4djIG7Dom5nIGPhuqVwIGjhuqEgdOG6p25nIG3huqFuZyB2w6AgY3VuZyBj4bqlcCBjw6FjIGfDs2kgRmliZXIgb3B0aWMgZ2nDoSBo4bujcCBsw70gbMOgIGdp4bqjaSBwaMOhcCBxdWFuIHRy4buNbmcgxJHhu4MgZ2nhu68gY2jDom4ga2jDoWNoIGjDoG5nLg0KDQpWaeG7h2MgcGjDom4gdMOtY2ggYuG7kW4geeG6v3UgdOG7kSB0csOqbiBnacO6cCBkb2FuaCBuZ2hp4buHcCBoaeG7g3UgcsO1IGjGoW4gaMOgbmggdmkga2jDoWNoIGjDoG5nLCB04burIMSRw7MgdOG7kWkgxrB1IGNoaeG6v24gbMaw4bujYyB0aeG6v3AgdGjhu4ssIHRoaeG6v3Qga+G6vyBnw7NpIGThu4tjaCB24bulIGjhu6NwIGzDvSB2w6AgdHJp4buDbiBraGFpIGPDoWMgY2jGsMahbmcgdHLDrG5oIGNoxINtIHPDs2MgbmjhurFtIGdp4bqjbSB04bu3IGzhu4cgcuG7nWkgYuG7jy4gxJDDonkgY8WpbmcgbMOgIG7hu4FuIHThuqNuZyBxdWFuIHRy4buNbmcgxJHhu4MgeMOieSBk4buxbmcgY8OhYyBtw7QgaMOsbmggaOG7k2kgcXV5IG5o4buLIHBow6JuIG5oxrAgbG9naXQsIHByb2JpdCBob+G6t2MgY2xvZ2xvZyBuaOG6sW0gZOG7sSBiw6FvIHjDoWMgc3XhuqV0IGNodXJuIG3hu5l0IGPDoWNoIGNow61uaCB4w6FjLg0KDQojIyAqKjIuMyBSZWxhdGl2ZSBSaXNrIHbDoCBPZGRzIFJhdGlvKioNCg0KVHJvbmcgcGjDom4gdMOtY2ggZOG7ryBsaeG7h3UgxJHhu4tuaCB0w61uaCB2w6AgxJHhu4tuaCBsxrDhu6NuZywgxJHhurdjIGJp4buHdCB0cm9uZyBuZ2hpw6puIGPhu6l1IGjDoG5oIHZpIGtow6FjaCBow6BuZywgdmnhu4djIMSRbyBsxrDhu51uZyBz4buxIGtow6FjIGJp4buHdCB24buBIGto4bqjIG7Eg25nIHjhuqN5IHJhIG3hu5l0IHPhu7Ega2nhu4duIGdp4buvYSBjw6FjIG5ow7NtIMSR4buRaSB0xrDhu6NuZyBsw6AgdsO0IGPDuW5nIHF1YW4gdHLhu41uZy4gSGFpIGNo4buJIHPhu5EgcGjhu5UgYmnhur9uIHRoxrDhu51uZyDEkcaw4bujYyBz4butIGThu6VuZyBjaG8gbeG7pWMgxJHDrWNoIG7DoHkgbMOgIFJlbGF0aXZlIFJpc2sgKFJSKSB2w6AgT2RkcyBSYXRpbyAoT1IpLiBDw6FjIGNo4buJIHPhu5EgbsOgeSBraMO0bmcgY2jhu4kgZ2nDunAgxJHhu4tuaCBsxrDhu6NuZyBt4bupYyDEkeG7mSB0w6FjIMSR4buZbmcgY+G7p2EgbeG7mXQgxJHhurdjIMSRaeG7g20gxJHhur9uIGjDoG5oIHZpLCBtw6AgY8OybiBo4buXIHRy4bujIGRp4buFbiBnaeG6o2kgcsO1IHLDoG5nIGvhur90IHF14bqjIHThu6sgY8OhYyBtw7QgaMOsbmggdGjhu5FuZyBrw6ogbmjGsCBo4buTaSBxdXkgbG9naXN0aWMuDQoNCiMjIyAqKjIuMy4xIFJlbGF0aXZlIFJpc2sgKFJSKSoqDQoNCiBSZWxhdGl2ZSBSaXNrIChSUikgaGF5IGPDsm4gZ+G7jWkgbMOgIG5ndXkgY8ahIHTGsMahbmcgxJHhu5FpIHNvIHPDoW5oIHjDoWMgc3XhuqV0IHjhuqN5IHJhIGjDoG5oIHZpIGdp4buvYSBoYWkgbmjDs206DQogDQokJA0KUlIgPSBcZnJhY3tQXzF9e1BfMH0NCiQkDQoNClRyb25nIMSRw7M6ICANCg0KLSAkUF8xJDogWMOhYyBzdeG6pXQga2jDoWNoIGjDoG5nIGPDsyDEkeG6t2MgxJFp4buDbSB0aOG7sWMgaGnhu4duIGjDoG5oIHZpICANCg0KLSAkUF8wJDogWMOhYyBzdeG6pXQga2jDoWNoIGjDoG5nIGtow7RuZyBjw7MgxJHhurdjIMSRaeG7g20gdGjhu7FjIGhp4buHbiBow6BuaCB2aSAgDQoNCkRp4buFbiBnaeG6o2k6DQoNCi0gUlIgPSAxOiBLaMO0bmcgY8OzIHPhu7Ega2jDoWMgYmnhu4d0IGdp4buvYSBoYWkgbmjDs20gIA0KDQotIFJSID4gMTogTmjDs20gY8OzIMSR4bq3YyDEkWnhu4NtIGPDsyBraOG6oyBuxINuZyB44bqjeSByYSBow6BuaCB2aSBjYW8gaMahbiAgDQoNCi0gUlIgPCAxOiBOaMOzbSBjw7MgxJHhurdjIMSRaeG7g20gY8OzIGto4bqjIG7Eg25nIHjhuqN5IHJhIGjDoG5oIHZpIHRo4bqlcCBoxqFuDQoNCiMjIyAqKjIuMy4yIE9kZHMgUmF0aW8gKE9SKSoqDQoNCk9kZHMgUmF0aW8gKE9SKSDEkW8gbMaw4budbmcgdOG7tyBs4buHIG9kZHMgKGto4bqjIG7Eg25nIHjhuqN5IHJhIHNvIHbhu5tpIGtow7RuZyB44bqjeSByYSkgZ2nhu69hIGhhaSBuaMOzbToNCg0KJCQNCk9SID0gXGZyYWN7UF8xIC8gKDEgLSBQXzEpfXtQXzAgLyAoMSAtIFBfMCl9ID0gXGZyYWN7UF8xICgxIC0gUF8wKX17UF8wICgxIC0gUF8xKX0NCiQkDQoNCkRp4buFbiBnaeG6o2k6DQoNCi0gT1IgPSAxOiBLaMO0bmcgY8OzIHPhu7Ega2jDoWMgYmnhu4d0IGdp4buvYSBoYWkgbmjDs20gIA0KDQotIE9SID4gMTogTmjDs20gY8OzIMSR4bq3YyDEkWnhu4NtIGPDsyBvZGRzIHZheSBjYW8gaMahbiAgDQoNCi0gT1IgPCAxOiBOaMOzbSBjw7MgxJHhurdjIMSRaeG7g20gY8OzIG9kZHMgdmF5IHRo4bqlcCBoxqFuDQoNCiMjICoqMi4zIEPGoSBz4bufIGzDvSB0aHV54bq/dCB24buBIG3DtCBow6xuaCBo4buTaSBxdXkgbmjhu4sgcGjDom4qKg0KDQojIyMgKioyLjMuMSBNw7QgaMOsbmggbG9naXQqKg0KDQpNw7QgaMOsbmggTG9naXQgbMOgIG3hu5l0IHRyxrDhu51uZyBo4bujcCDEkeG6t2MgYmnhu4d0IGPhu6dhIG3DtCBow6xuaCBo4buTaSBxdXkgdOG7lW5nIHF1w6F0IChHTE0pLCDEkcaw4bujYyBz4butIGThu6VuZyBraGkgYmnhur9uIHBo4bulIHRodeG7mWMgXChZXCkgbMOgIGJp4bq/biBuaOG7iyBwaMOibiwgY2jhu4kgbmjhuq1uIGdpw6EgdHLhu4sgMCBob+G6t2MgMS4gTcO0IGjDrG5oIG7DoHkgbcO0IHThuqMgeMOhYyBzdeG6pXQgeOG6o3kgcmEgY+G7p2EgbeG7mXQgc+G7sSBraeG7h24gdGjDtG5nIHF1YSBow6BtIGxvZ2lzdGljLCBnacO6cCDEkeG6o20gYuG6o28gZ2nDoSB0cuG7iyBk4buxIMSRb8OhbiBsdcO0biBu4bqxbSB0cm9uZyBraG/huqNuZyBcKFswLCAxXVwpLg0KDQogKipCYSB0aMOgbmggcGjhuqduIGPhu6dhIG3DtCBow6xuaCBMb2dpdCoqDQoNCi0gKipTeXN0ZW0gY29tcG9uZW50IChUaMOgbmggcGjhuqduIGjhu4cgdGjhu5FuZyk6KioNCg0KICBN4buRaSBxdWFuIGjhu4cgdHV54bq/biB0w61uaCBnaeG7r2EgY8OhYyBiaeG6v24gxJHhu5ljIGzhuq1wIHbDoCBsb2ctb2RkcyBj4bunYSB4w6FjIHN14bqldCB44bqjeSByYSBz4buxIGtp4buHbjoNCiAgJCQNCiAgXGV0YSA9IFxiZXRhXzAgKyBcYmV0YV8xIFhfMSArIFxjZG90cyArIFxiZXRhX2sgWF9rLA0KICAkJA0KdHJvbmcgxJHDsyBcKFxldGEgPSBcbG5cbGVmdChcZnJhY3twfXsxLXB9XHJpZ2h0KVwpIHbDoCBcKHAgPSBQKFk9MXxYKVwpLg0KDQotICoqTGluayBmdW5jdGlvbiAoSMOgbSBsacOqbiBr4bq/dCk6KioNCg0KICBIw6BtIGxvZ2l0IGxpw6puIGvhur90IHjDoWMgc3XhuqV0IHbhu5tpIGjDoG0gdHV54bq/biB0w61uaDoNCiAgJCQNCiAgZyhwKSA9IFxsblxsZWZ0KFxmcmFje3B9ezEtcH1ccmlnaHQpID0gXGV0YS4NCiAgJCQNCiAgTmfGsOG7o2MgbOG6oWksIHjDoWMgc3XhuqV0IMSRxrDhu6NjIHTDrW5oIGLhurFuZzoNCiAgJCQNCiAgcCA9IFxmcmFje2Vee1xldGF9fXsxICsgZV57XGV0YX19ID0gXGZyYWN7ZV57XGJldGFfMCArIFxiZXRhXzEgWF8xICsgXGNkb3RzICsgXGJldGFfayBYX2t9fXsxICsgZV57XGJldGFfMCArIFxiZXRhXzEgWF8xICsgXGNkb3RzICsgXGJldGFfayBYX2t9fS4NCiAgJCQgDQoNCi0gKipSYW5kb20gY29tcG9uZW50IChUaMOgbmggcGjhuqduIG5n4bqrdSBuaGnDqm4pOioqDQoNCiAgQmnhur9uIHBo4bulIHRodeG7mWMgXChZXCkgdHXDom4gdGhlbyBwaMOibiBwaOG7kWkgbmjhu4sgdGjhu6ljOg0KICAkJA0KICBZIFxzaW0gXHRleHR7Qmlub21pYWx9KDEsIHApDQogICQkIA0KduG7m2kgXChFKFkpID0gcFwpIHbDoCBcKFZhcihZKSA9IHAoMS1wKVwpLg0KDQoqKsav4bubYyBsxrDhu6NuZyB0aGFtIHPhu5EqKg0KDQpDw6FjIGjhu4cgc+G7kSBcKFxiZXRhX2pcKSDEkcaw4bujYyDGsOG7m2MgbMaw4bujbmcgYuG6sW5nIHBoxrDGoW5nIHBow6FwIHThu5FpIMSRYSBow7NhIGjDoG0gaOG7o3AgbMO9IChNYXhpbXVtIExpa2VsaWhvb2QgRXN0aW1hdGlvbiDigJMgTUxFKS4gSOG7hyBz4buRIFwoXGJldGFfalwpIGNobyBiaeG6v3QgbG9nLW9kZHMgY+G7p2Egc+G7sSBraeG7h24gXChZPTFcKSB0aGF5IMSR4buVaSBiYW8gbmhpw6p1IMSRxqFuIHbhu4sga2hpIFwoWF9qXCkgdMSDbmcgbeG7mXQgxJHGoW4gduG7iyAoZ2nhu68gY8OhYyBiaeG6v24ga2jDoWMgY+G7kSDEkeG7i25oKS4gVOG7iSBz4buRIFwoZV57XGJldGFfan1cKSAob2RkcyByYXRpbykgY2hvIGJp4bq/dCBraOG6oyBuxINuZyB44bqjeSByYSBz4buxIGtp4buHbiB0xINuZyBob+G6t2MgZ2nhuqNtIGJhbyBuaGnDqnUgbOG6p24ga2hpIFwoWF9qXCkgdMSDbmcgMSDEkcahbiB24buLLg0KDQoqKsavdSDEkWnhu4NtKioNCg0KTcO0IGjDrG5oIExvZ2l0IMSR4bqjbSBi4bqjbyBnacOhIHRy4buLIHjDoWMgc3XhuqV0IGx1w7RuIG7hurFtIHRyb25nIFwoWzAsIDFdXCksIGThu4UgZMOgbmcgZGnhu4VuIGdp4bqjaSBxdWEgb2RkcyByYXRpbyB2w6AgxJHhurdjIGJp4buHdCBwaMO5IGjhu6NwIHbhu5tpIGThu68gbGnhu4d1IHBow6JuIGxv4bqhaSBuaOG7iyBwaMOibi4NCg0KIyMjICoqMi4zLjIgTcO0IGjDrG5oIHByb2JpdCoqDQoNCk3DtCBow6xuaCBQcm9iaXQgbMOgIG3hu5l0IGThuqFuZyBo4buTaSBxdXkgbmjhu4sgcGjDom4gdGh14buZYyBuaMOzbSBtw7QgaMOsbmggaOG7k2kgcXV5IHThu5VuZyBxdcOhdCAoR0xNKSwgxJHGsOG7o2Mgc+G7rSBk4bulbmcga2hpIGJp4bq/biBwaOG7pSB0aHXhu5ljIFwoWVwpIGNo4buJIG5o4bqtbiBnacOhIHRy4buLIDAgaG/hurdjIDEuIEtow6FjIHbhu5tpIGxvZ2l0LCBtw7QgaMOsbmggUHJvYml0IHPhu60gZOG7pW5nIGjDoG0gbGnDqm4ga+G6v3QgZOG7sWEgdHLDqm4gaMOgbSBwaMOibiBwaOG7kWkgdMOtY2ggbMWpeSBjaHXhuqluIGNodeG6qW4gaMOzYSAoU3RhbmRhcmQgTm9ybWFsIENERikgxJHhu4MgbcO0IHThuqMgeMOhYyBzdeG6pXQgeOG6o3kgcmEgc+G7sSBraeG7h24uDQoNCioqQmEgdGjDoG5oIHBo4bqnbiBj4bunYSBtw7QgaMOsbmggUHJvYml0KioNCg0KLSBTeXN0ZW0gY29tcG9uZW50IChUaMOgbmggcGjhuqduIGjhu4cgdGjhu5FuZyk6DQoNCiAgTeG7kWkgcXVhbiBo4buHIGdp4buvYSBjw6FjIGJp4bq/biDEkeG7mWMgbOG6rXAgdsOgIGJp4bq/biBwaOG7pSB0aHXhu5ljIMSRxrDhu6NjIHRo4buDIGhp4buHbiBxdWEgaMOgbSB0dXnhur9uIHTDrW5oOg0KICAkJA0KICBcZXRhID0gXGJldGFfMCArIFxiZXRhXzEgWF8xICsgXGNkb3RzICsgXGJldGFfayBYX2sNCiAgJCQgDQogIA0KICB0cm9uZyDEkcOzIFwoXGV0YVwpIGzDoCBiaeG6v24gdGnhu4FtIOG6qW4gbGnDqm4gcXVhbiDEkeG6v24geMOhYyBzdeG6pXQgXChwID0gUChZPTF8WClcKS4NCg0KLSBMaW5rIGZ1bmN0aW9uIChIw6BtIGxpw6puIGvhur90KToNCg0KICBUcm9uZyBQcm9iaXQsIGjDoG0gbGnDqm4ga+G6v3QgXChnKHApXCkgxJHGsOG7o2MgxJHhu4tuaCBuZ2jEqWEgbMOgIGjDoG0gbmdo4buLY2ggxJHhuqNvIGPhu6dhIGjDoG0gcGjDom4gcGjhu5FpIHTDrWNoIGzFqXkgY2h14bqpbiBjaHXhuqluIGjDs2EgXChcUGhpKFxjZG90KVwpOg0KICAkJA0KICBnKHApID0gXFBoaV57LTF9KHApID0gXGV0YS4NCiAgJCQNCiAgDQogIFjDoWMgc3XhuqV0IHjhuqN5IHJhIHPhu7Ega2nhu4duIMSRxrDhu6NjIHTDrW5oIG5oxrAgc2F1Og0KICAkJA0KICBwID0gUChZPTF8WCkgPSBcUGhpKFxiZXRhXzAgKyBcYmV0YV8xIFhfMSArIFxjZG90cyArIFxiZXRhX2sgWF9rKSwNCiAgJCQNCiAgduG7m2k6DQogICQkDQogIFxQaGkoeikgPSBcaW50X3stXGluZnR5fV56IFxmcmFjezF9e1xzcXJ0ezJccGl9fSBlXnstXGZyYWN7dF4yfXsyfX0gZHQuDQogICQkDQoNCi0gUmFuZG9tIGNvbXBvbmVudCAoVGjDoG5oIHBo4bqnbiBuZ+G6q3Ugbmhpw6puKToNCg0KICBCaeG6v24gcGjhu6UgdGh14buZYyBcKFlcKSB0dcOibiB0aGVvIHBow6JuIHBo4buRaSBuaOG7iyB0aOG7qWM6DQogICQkDQogIFkgXHNpbSBcdGV4dHtCaW5vbWlhbH0oMSwgcCkNCiAgJCQNCiAgduG7m2kga+G7syB24buNbmcgXChFKFkpID0gcFwpIHbDoCBwaMawxqFuZyBzYWkgXChWYXIoWSkgPSBwKDEtcClcKS4NCg0KICoqxq/hu5tjIGzGsOG7o25nIHbDoCDDvSBuZ2jEqWEqKg0KDQpDw6FjIGjhu4cgc+G7kSBcKFxiZXRhX2pcKSDEkcaw4bujYyDGsOG7m2MgbMaw4bujbmcgYuG6sW5nIE1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0aW9uIChNTEUpLiBUxrDGoW5nIHThu7EgbmjGsCBsb2dpdCwgXChcYmV0YV9qXCkgYmnhu4N1IHRo4buLIHTDoWMgxJHhu5luZyBj4bunYSBcKFhfalwpIMSR4bq/biBiaeG6v24gdGnhu4FtIOG6qW4gXChcZXRhXCksIHR1eSBuaGnDqm4ga2jDtG5nIGPDsyBjw6FjaCBkaeG7hW4gZ2nhuqNpIHRy4buxYyB0aeG6v3AgdGhlbyBvZGRzIHJhdGlvLiBUaGF5IHbDoG8gxJHDsywgdGEgY8OzIHRo4buDIGRp4buFbiBnaeG6o2kgcXVhIHZp4buHYyB0w61uaCB4w6FjIHN14bqldCBi4bqxbmcgXChcUGhpKFxldGEpXCkuDQoNCioqU28gc8OhbmggduG7m2kgTG9naXQqKg0KDQpLaMOhYyB24bubaSBsb2dpdCAoZMO5bmcgaMOgbSBsb2dpc3RpYyksIG3DtCBow6xuaCBQcm9iaXQgc+G7rSBk4bulbmcgcGjDom4gcGjhu5FpIGNodeG6qW4uIEhhaSBtw7QgaMOsbmggdGjGsOG7nW5nIGNobyBr4bq/dCBxdeG6oyBraMOhIHTGsMahbmcgxJHhu5NuZywgbmjGsG5nIFByb2JpdCBjw7MgxJF1w7RpIHBow6JuIHBo4buRaSBt4buPbmcgaMahbiwgcGjDuSBo4bujcCB24bubaSBk4buvIGxp4buHdSBjw7MgcGjDom4gcGjhu5FpIGfhuqduIGNodeG6qW4uDQoNCiMjIyAqKjIuMy4zIE3DtCBow6xuaCBjbG9nbG9nKioNCg0KTcO0IGjDrG5oIENsb2dsb2cgKENvbXBsZW1lbnRhcnkgbG9nLWxvZykgbMOgIG3hu5l0IGThuqFuZyBj4bunYSBtw7QgaMOsbmggaOG7k2kgcXV5IHThu5VuZyBxdcOhdCAoR0xNKSDEkcaw4bujYyBz4butIGThu6VuZyBraGkgYmnhur9uIHBo4bulIHRodeG7mWMgXChZXCkgbMOgIG5o4buLIHBow6JuICgwIGhv4bq3YyAxKS4gS2jDoWMgduG7m2kgbG9naXQgdsOgIHByb2JpdCwgbcO0IGjDrG5oIENsb2dsb2cgc+G7rSBk4bulbmcgaMOgbSBsacOqbiBr4bq/dCBraMO0bmcgxJHhu5FpIHjhu6luZywgcGjDuSBo4bujcCB24bubaSBk4buvIGxp4buHdSBjw7MgeMOhYyBzdeG6pXQgeOG6o3kgcmEgc+G7sSBraeG7h24gcuG6pXQgdGjhuqVwIGhv4bq3YyBwaMOibiBwaOG7kWkga2jDtG5nIMSR4buRaSB44bupbmcuDQoNCiAqKlN5c3RlbSBjb21wb25lbnQgKFRow6BuaCBwaOG6p24gaOG7hyB0aOG7kW5nKSoqDQoNCk3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgY8OhYyBiaeG6v24gZ2nhuqNpIHRow61jaCB2w6AgYmnhur9uIHBo4bulIHRodeG7mWMgxJHGsOG7o2MgdGjhu4MgaGnhu4duIHF1YSBow6BtIHR1eeG6v24gdMOtbmg6DQoNCiQkDQpcZXRhID0gXGJldGFfMCArIFxiZXRhXzEgWF8xICsgXGNkb3RzICsgXGJldGFfayBYX2sNCiQkDQoNCioqTGluayBmdW5jdGlvbiAoSMOgbSBsacOqbiBr4bq/dCkqKg0KDQpIw6BtIGxpw6puIGvhur90IHRyb25nIG3DtCBow6xuaCBDbG9nbG9nIMSRxrDhu6NjIMSR4buLbmggbmdoxKlhIG5oxrAgc2F1Og0KJCQNCmcocCkgPSBcbG5bLVxsbigxIC0gcCldID0gXGV0YQ0KJCQNCk5nxrDhu6NjIGzhuqFpLCB4w6FjIHN14bqldCB44bqjeSByYSBz4buxIGtp4buHbiBcKFk9MVwpIMSRxrDhu6NjIHTDrW5oOg0KDQokJA0KcCA9IDEgLSBlXnstZV57XGV0YX19ID0gMSAtIGVeey1lXntcYmV0YV8wICsgXGJldGFfMSBYXzEgKyBcY2RvdHMgKyBcYmV0YV9rIFhfa319DQokJA0KDQogKipSYW5kb20gY29tcG9uZW50IChUaMOgbmggcGjhuqduIG5n4bqrdSBuaGnDqm4pKioNCg0KQmnhur9uIHBo4bulIHRodeG7mWMgXChZXCkgdHXDom4gdGhlbyBwaMOibiBwaOG7kWkgbmjhu4sgdGjhu6ljOg0KJCQNClkgXHNpbSBcdGV4dHtCaW5vbWlhbH0oMSwgcCkNCiQkDQp24bubaSBr4buzIHbhu41uZyBcKEUoWSkgPSBwXCkgdsOgIHBoxrDGoW5nIHNhaSBcKFZhcihZKSA9IHAoMS1wKVwpLg0KDQojIyAqKjIuNCBQaMawxqFuZyBwaMOhcCDGsOG7m2MgbMaw4bujbmc6IE1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0aW9uIChNTEUpKioNCg0KQ8OhYyBtw7QgaMOsbmggbmjhu4sgcGjDom4gbmjGsCBsb2dpdCwgcHJvYml0IHbDoCBjbG9nbG9nIMSR4buBdSDEkcaw4bujYyDGsOG7m2MgbMaw4bujbmcgYuG6sW5nIHBoxrDGoW5nIHBow6FwIMaw4bubYyBsxrDhu6NuZyBo4bujcCBsw70gdOG7kWkgxJFhIChNTEUpLiDEkMOieSBsw6AgcGjGsMahbmcgcGjDoXAgdMOsbSBnacOhIHRy4buLIHRoYW0gc+G7kSAkXGJldGEkIHNhbyBjaG8geMOhYyBzdeG6pXQgdOG6oW8gcmEgZOG7ryBsaeG7h3UgcXVhbiBzw6F0IGzDoCBjYW8gbmjhuqV0LiBUcm9uZyBHTE1zLCBow6BtIGjhu6NwIGzDvSDEkcaw4bujYyB4w6J5IGThu7FuZyBk4buxYSB0csOqbiBwaMOibiBwaOG7kWkgbmjhu4sgdGjhu6ljIHbDoCB04buRaSDGsHUgaMOzYSBi4bqxbmcgY8OhYyB0aHXhuq10IHRvw6FuIG5oxrAgTmV3dG9uLVJhcGhzb24uDQoNClRyb25nIGPDoWMgbcO0IGjDrG5oIGjhu5NpIHF1eSBuaOG7iyBwaMOibiB0aHXhu5ljIGjhu40gR0xNIG5oxrAgbG9naXQsIHByb2JpdCB2w6AgY2xvZ2xvZywgdGhhbSBz4buRICRcYmV0YSQga2jDtG5nIMSRxrDhu6NjIMaw4bubYyBsxrDhu6NuZyBi4bqxbmcgcGjGsMahbmcgcGjDoXAgYsOsbmggcGjGsMahbmcgdOG7kWkgdGhp4buDdSBuaMawIHRyb25nIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oIGPhu5UgxJFp4buDbiwgbcOgIHRoYXkgdsOgbyDEkcOzIHPhu60gZOG7pW5nIHBoxrDGoW5nIHBow6FwIMaw4bubYyBsxrDhu6NuZyBo4bujcCBsw70gdOG7kWkgxJFhIChNYXhpbXVtIExpa2VsaWhvb2QgRXN0aW1hdGlvbiAtIE1MRSkuDQoNClBoxrDGoW5nIHBow6FwIE1MRSB0w6xtIHThuq1wIGdpw6EgdHLhu4sgY+G7p2EgJFxiZXRhJCBzYW8gY2hvIGjDoG0gaOG7o3AgbMO9IChsaWtlbGlob29kIGZ1bmN0aW9uKSDEkeG6oXQgY+G7sWMgxJHhuqFpIOKAkyBuZ2jEqWEgbMOgLCBraOG6oyBuxINuZyB04bqhbyByYSBi4buZIGThu68gbGnhu4d1IHF1YW4gc8OhdCB04burIG3DtCBow6xuaCBsw6AgY2FvIG5o4bqldC4gSMOgbSBo4bujcCBsw70gdHJvbmcgdHLGsOG7nW5nIGjhu6NwIG5o4buLIHBow6JuIGThu7FhIHRyw6puIHBow6JuIHBo4buRaSBuaOG7iyB0aOG7qWM6DQoNCiQkDQpMKFxiZXRhKSA9IFxwcm9kX3tpPTF9XntufSBbUF9pXV57eV9pfSBbMSAtIFBfaV1eezEgLSB5X2l9LCBccXVhZCBcdGV4dHt0cm9uZyDEkcOzIH0gUF9pID0gRyhYX2lcYmV0YSkNCiQkDQoNCsSQ4buDIMSRxqFuIGdp4bqjbiBow7NhIHTDrW5oIHRvw6FuLCB0YSBs4bqleSBsb2cgY+G7p2EgaMOgbSBo4bujcCBsw70gxJHhu4MgY8OzICoqbG9nLWxpa2VsaWhvb2QqKjoNCg0KJCQNClxsb2cgTChcYmV0YSkgPSBcc3VtX3tpPTF9XntufSBcbGVmdFsgeV9pIFxsb2cgUF9pICsgKDEgLSB5X2kpIFxsb2coMSAtIFBfaSkgXHJpZ2h0XQ0KJCQNCg0KLS0tLS0tDQoNCiMgKipDSMavxqBORyAzOiBL4bq+VCBRVeG6oiBOR0hJw4pOIEPhu6hVKioNCg0KYGBge3IsbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShEVCkNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShwc3ljaCkNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KERlc2NUb29scykNCmxpYnJhcnkoZXBpdG9vbHMpDQpsaWJyYXJ5KEFFUikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHhsc3gpDQpsaWJyYXJ5KHJlYWR4bCkgIA0KbGlicmFyeShjYXJldCkNCmBgYA0KDQojIyAqKjMuMSBU4buVbmcgcXVhbiB24buBIGThu68gbGnhu4d1IG5naGnDqm4gY+G7qXUqKg0KDQojIyMgKiozLjEuMSBHaeG7m2kgdGhp4buHdSBi4buZIGThu68gbGnhu4d1KioNCg0KQuG7mSBk4buvIGxp4buHdSBUZWxjbyBDdXN0b21lciBDaHVybiAoS2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6Ugdmnhu4VuIHRow7RuZykgYmFvIGfhu5NtIHRow7RuZyB0aW4gY+G7p2EgNDgzMiBraMOhY2ggaMOgbmcgdOG7qyBt4buZdCBjw7RuZyB0eSB2aeG7hW4gdGjDtG5nLCDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyBwaMOibiB0w61jaCB2w6AgZOG7sSDEkW/DoW4ga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoY2h1cm4pIGPhu6dhIGtow6FjaCBow6BuZy4gROG7ryBsaeG7h3UgY2jhu6lhIDIxIGJp4bq/biwgYmFvIGfhu5NtIGPDoWMgdGjDtG5nIHRpbiBjw6EgbmjDom4gKGdp4bubaSB0w61uaCwgdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuLCBuZ8aw4budaSBwaOG7pSB0aHXhu5ljKSwgbG/huqFpIGThu4tjaCB24bulIG3DoCBraMOhY2ggaMOgbmcgc+G7rSBk4bulbmcgKGThu4tjaCB24bulIMSRaeG7h24gdGhv4bqhaSwgaW50ZXJuZXQsIHRydXnhu4FuIGjDrG5oLCBo4buXIHRy4bujIGvhu7kgdGh14bqtdCksIHRow7RuZyB0aW4gduG7gSBo4bujcCDEkeG7k25nIHbDoCBwaMawxqFuZyB0aOG7qWMgdGhhbmggdG/DoW4sIGPFqW5nIG5oxrAgY8OhYyBjaOG7iSBz4buRIHTDoGkgY2jDrW5oIG5oxrAgY2hpIHBow60gaMOgbmcgdGjDoW5nIHbDoCB04buVbmcgY2hpIHBow60gxJHDoyB0aGFuaCB0b8Ohbi4gQmnhur9uIG3hu6VjIHRpw6p1IENodXJuIChZZXMvTm8pIGNobyBiaeG6v3Qga2jDoWNoIGjDoG5nIGPDsyBy4budaSBi4buPIGThu4tjaCB24bulIGhheSBraMO0bmcuIELhu5kgZOG7ryBsaeG7h3UgbsOgeSB0aMaw4budbmcgxJHGsOG7o2Mgw6FwIGThu6VuZyB0cm9uZyBjw6FjIGLDoGkgdG/DoW4gcGjDom4gdMOtY2ggZOG7ryBsaeG7h3UsIHRy4buxYyBxdWFuIGjDs2EgdsOgIHjDonkgZOG7sW5nIG3DtCBow6xuaCBk4buxIMSRb8OhbiBuaOG6sW0gZ2nDunAgZG9hbmggbmdoaeG7h3AgaGnhu4N1IHLDtSBow6BuaCB2aSBraMOhY2ggaMOgbmcgdsOgIMSRxrBhIHJhIGNoaeG6v24gbMaw4bujYyBnaeG7ryBjaMOibiBoaeG7h3UgcXXhuqMuIA0KDQpgYGB7cn0NCnZpZW50aG9uZyA8LSByZWFkX2V4Y2VsKCJEOi9ISzJfUFRETERUX1RNVC9kbGlldWNoaW5odGh1YzAxLnhsc3giLCBzaGVldCA9IDEpDQpkYXRhdGFibGUodmllbnRob25nLG9wdGlvbnMgPSBsaXN0KHNjcm9sbFggPSBUUlVFKSkNCnZpZW50aG9uZyA8LSB2aWVudGhvbmcgJT4lIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMuY2hhcmFjdGVyKSwgYXMuZmFjdG9yKSkNCmBgYA0KDQojIyMgKiozLjEuMiBD4bqldSB0csO6YyBi4buZIGThu68gbGnhu4d1KioNCg0KxJDhu4MgY8OzIGPDoWkgbmjDrG4gdOG7lW5nIHF1YW4gduG7gSBj4bqldSB0csO6YyBj4bunYSBi4buZIGThu68gbGnhu4d1LCBiYW8gZ+G7k20gc+G7kSBsxrDhu6NuZyBxdWFuIHPDoXQsIHPhu5EgbMaw4bujbmcgYmnhur9uLCBraeG7g3UgZOG7ryBsaeG7h3UgY+G7p2EgdOG7q25nIGJp4bq/biB2w6AgbeG7mXQgc+G7kSBnacOhIHRy4buLIMSRaeG7g24gaMOsbmgsIHRhIHPhu60gZOG7pW5nIGjDoG0gc3RyKCkgbmjGsCBzYXU6DQoNCmBgYHtyfQ0Kc3RyKHZpZW50aG9uZykNCmBgYA0KDQpRdWEga+G6v3QgcXXhuqMgY+G7p2EgaMOgbSBzdHIoKSwgdGEgdGjhuqV5IGLhu5kgZOG7ryBsaeG7h3UgdHJvbmcgbmdoacOqbiBj4bupdSBsw6AgVGVsY28gQ3VzdG9tZXIgQ2h1cm4gKEtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIHZp4buFbiB0aMO0bmcpLCBiYW8gZ+G7k20gdGjDtG5nIHRpbiBj4bunYSA0LjgzMiBraMOhY2ggaMOgbmcgdOG7qyBt4buZdCBjw7RuZyB0eSB2aeG7hW4gdGjDtG5nLiBE4buvIGxp4buHdSDEkcaw4bujYyB0aHUgdGjhuq1wIG5o4bqxbSBt4bulYyDEkcOtY2ggcGjDom4gdMOtY2ggY8OhYyB54bq/dSB04buRIG5ow6JuIGto4bqpdSBo4buNYywgbG/huqFpIGThu4tjaCB24bulIHbDoCBwaMawxqFuZyB0aOG7qWMgdGhhbmggdG/DoW4gY8OzIOG6o25oIGjGsOG7n25nIMSR4bq/biB2aeG7h2Mga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKENodXJuKS4gVOG6rXAgZOG7ryBsaeG7h3UgY2jhu6lhIHThu5VuZyBj4buZbmcgMjEgYmnhur9uLGPDsyAxNyBiaeG6v24gxJHhu4tuaCB0w61uaCB2w6AgNCDEkeG7i25oIGzGsOG7o25nIGPhu6UgdGjhu4MgbmjGsCBzYXU6DQoNCioqQ8OhYyBiaeG6v24gxJHhu4tuaCBsxrDhu6NuZyoqDQoNCiAtIHRlbnVyZTogU+G7kSB0aMOhbmcgZ+G6r24gYsOzIHbhu5tpIGThu4tjaCB24bulICgxIOKAkyA3MiB0aMOhbmcpLg0KDQogLSBNb250aGx5Q2hhcmdlczogIENoaSBwaMOtIGThu4tjaCB24bulIGjDoG5nIHRow6FuZy4NCg0KIC0gVG90YWxDaGFyZ2VzOiBU4buVbmcgY2hpIHBow60ga2jDoWNoIGjDoG5nIMSRw6MgdGhhbmggdG/DoW4uDQoNCioqQ8OhYyBiaeG6v24gxJHhu4tuaCB0w61uaCoqDQoNCi0gR2VuZGVyOiBHaeG7m2kgdMOtbmggKE1hbGUvRmVtYWxlKS4NCg0KLSBQYXJ0bmVyOiBDw7MgYuG6oW4gxJHhu51pIGhheSBraMO0bmcgKFllcy9ObykuDQoNCi0gRGVwZW5kZW50czogTmfGsOG7nWkgcGjhu6UgdGh14buZYyAoWWVzL05vKS4NCg0KLSBQaG9uZVNlcnZpY2U6IEThu4tjaCB24bulIMSRaeG7h24gdGhv4bqhaSAoWWVzL05vKS4NCg0KLSBNdWx0aXBsZUxpbmVzOiBOaGnhu4F1IMSRxrDhu51uZyBkw6J5IChZZXMvTm8pLg0KDQotIEludGVybmV0U2VydmljZTogTG/huqFpIGThu4tjaCB24bulIEludGVybmV0IChEU0wvRmliZXIgb3B0aWMpLg0KDQotIE9ubGluZVNlY3VyaXR5OiBC4bqjbyBt4bqtdCB0cuG7sWMgdHV54bq/biAoWWVzL05vKS4NCg0KLSBPbmxpbmVCYWNrdXA6IFNhbyBsxrB1IHRy4buxYyB0dXnhur9uIChZZXMvTm8pLg0KDQotIERldmljZVByb3RlY3Rpb246IELhuqNvIHbhu4cgdGhp4bq/dCBi4buLIChZZXMvTm8pLg0KDQotIFRlY2hTdXBwb3J0OiBI4buXIHRy4bujIGvhu7kgdGh14bqtdCAoWWVzL05vKS4NCg0KLSBTdHJlYW1pbmdUVjogROG7i2NoIHbhu6UgdHJ1eeG7gW4gaMOsbmggKFllcy9ObykuDQoNCi0gU3RyZWFtaW5nTW92aWVzOiBE4buLY2ggduG7pSB4ZW0gcGhpbSAoWWVzL05vKS4NCg0KLSBDb250cmFjdDogIExv4bqhaSBo4bujcCDEkeG7k25nIChNb250aC10by1tb250aC9PbmUgeWVhci9Ud28geWVhcikuDQogDQotIFNlbmlvckNpdGl6ZW46IEtow6FjaCBow6BuZyB0aHXhu5ljIG5ow7NtIGNhbyB0deG7lWkgKDAvMSkuDQoNCi0gUGFwZXJsZXNzQmlsbGluZzogSMOzYSDEkcahbiDEkWnhu4duIHThu60gKFllcy9ObykuDQoNCi0gUGF5bWVudE1ldGhvZDogUGjGsMahbmcgdGjhu6ljIHRoYW5oIHRvw6FuIChNYWlsZWQgY2hlY2ssIEVsZWN0cm9uaWMgY2hlY2ssIEJhbmsgdHJhbnNmZXIsIENyZWRpdCBjYXJkKS4NCg0KLSBDaHVybjogS2jDoWNoIGjDoG5nIGPDsyBy4budaSBi4buPIGThu4tjaCB24bulIChZZXMvTm8pLg0KDQojIyMgKiozLjEuMyBIaeG7g24gdGjhu4sgbeG7mXQgdsOgaSBkw7JuZyDEkeG6p3UgdsOgIGN14buRaSBj4bunYSBk4buvIGxp4buHdSoqDQoNCk5o4bqxbSBjw7MgxJHGsOG7o2MgY8OhaSBuaMOsbiB04buVbmcgcXVhbiB24buBIGLhu5kgZOG7ryBsaeG7h3UgdGEgc+G7rSBk4bulbmcgaMOgbSBoZWFkKCkgdsOgIHRhaWQoKSDEkeG7gyB4ZW0gbeG7mXQgc+G7kSBkw7JuZyDEkeG6p3UgdsOgIGTDsm5nIGN14buRaSBj4bunYSBi4buZIGThu68gbGnhu4d1IFRlbGNvIEN1c3RvbWVyIENodXJuIChLaMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB2aeG7hW4gdGjDtG5nKQ0KDQpgYGB7cn0NCmRhdGF0YWJsZShoZWFkKHZpZW50aG9uZyksb3B0aW9ucyA9IGxpc3Qoc2Nyb2xsWCA9IFRSVUUpKSNoaeG7g24gdGjhu4sgdsOgaSBkw7JuZyDEkeG6p3UNCmBgYA0KDQpgYGB7cn0NCmRhdGF0YWJsZSh0YWlsKHZpZW50aG9uZyksb3B0aW9ucyA9IGxpc3Qoc2Nyb2xsWCA9IFRSVUUpKSNoaeG7g24gdGjhu4sgdsOgbyBkw7JuZyBjdeG7kWkgDQpgYGANCg0KIyMjICoqMy4xLjQgS2nhu4NtIHRyYSBnacOhIHRy4buLIHRoaeG6v3UqKg0KDQpOaOG6sW0gxJHhuqNtIGLhuqNvIGNo4bqldCBsxrDhu6NuZyBk4buvIGxp4buHdSB2w6AgdHLDoW5oIHNhaSBs4buHY2ggdHJvbmcgcXXDoSB0csOsbmggcGjDom4gdMOtY2gsIHRhIGPhuqduIGtp4buDbSB0cmEgeGVtIGLhu5kgZOG7ryBsaeG7h3UgY8OzIGNo4bupYSBnacOhIHRy4buLIHRoaeG6v3UgKE5BKSBoYXkga2jDtG5nLiDEkGnhu4F1IG7DoHkgZ2nDunAgeMOhYyDEkeG7i25oIGxp4buHdSBjw7MgY+G6p24geOG7rSBsw70gaG/hurdjIGzDoG0gc+G6oWNoIGThu68gbGnhu4d1IHRyxrDhu5tjIGtoaSB0aeG6v3AgdOG7pWMgcGjDom4gdMOtY2g6DQoNCmBgYHtyfQ0KaWYgKGFueShpcy5uYSh2aWVudGhvbmcpKSkgew0KICBjYXQoIkPDsyBnacOhIHRy4buLIHRoaeG6v3UgdHJvbmcgZOG7ryBsaeG7h3UuXG4iKQ0KfSBlbHNlIHsNCiAgY2F0KCJLaMO0bmcgY8OzIGdpw6EgdHLhu4sgdGhp4bq/dSB0cm9uZyBk4buvIGxp4buHdS5cbiIpDQp9DQpgYGANCg0KVuG7m2kgxJFv4bqhbiBjb2RlIHRyw6puIG7hur91IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgY8OzIGLhuqV0IGvDrCBk4buvIGxp4buHdSBuw6BvIHRoaeG6v3UgdGjDrCBr4bq/dCBxdeG6oyBz4bq9IG5o4bqtbiDEkcaw4bujYyBsw6AgY8OzIGdpw6EgdHLhu4sgdGhp4bq/dSB0cm9uZyBk4buvIGxp4buHdSB2w6AgbmfGsOG7o2MgbOG6oWkuVuG7m2kgYuG7mSBk4buvIGxp4buHdSDEkcaw4bujYyBnw6FuIGNobyB2aWVudGhvbmcgbmjhuq1uIMSRxrDhu6NjIGvhur90IHF14bqjIGzDoCBLaMO0bmcgY8OzIGdpw6EgdHLhu4sgdGhp4bq/dSB0cm9uZyBk4buvIGxp4buHdS4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgZOG7ryBsaeG7h3UgIGtow7RuZyBjw7Mgw7QgdHLhu5FuZyBoYXkgZ2nDoSB0cuG7iyBi4buLIHRoaeG6v3UgdHJvbmcgdG/DoG4gYuG7mSBi4buZIGThu68gbGnhu4d1LiDEkMOieSBsw6AgxJFp4buBdSBraeG7h24gxJHhu4MgdGnhur9uIGjDoG5oIGPDoWMgcGjDom4gdMOtY2ggdGnhur9wIHRoZW8gbcOgIGtow7RuZyBj4bqnbiB0aOG7sWMgaGnhu4duIGLGsOG7m2MgeOG7rSBsw70gZ2nDoSB0cuG7iyB0aGnhur91Lg0KDQoNCiMjICoqMy4yIFBow6JuIHTDrWNoIHPhu7EgdMOhYyDEkeG7mW5nIGPhu6dhIGxv4bqhaSBo4bujcCDEkeG7k25nIMSR4bq/biB2aeG7h2Mga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UqKg0KDQojIyMgKiozLjIuMSBUaOG7kW5nIGvDqiBtw7QgdOG6oyBiaeG6v24ga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKENodXJuKSB2w6AgYmnhur9uIGPDoWMgbG/huqFpIGjhu6NwIMSR4buTbmcgKENvbnRyYWN0KSoqDQoNCiMjIyMgKiozLjIuMS4xIEJp4bq/biBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoQ2h1cm4pKioNCg0KVHLGsOG7m2MgdGnDqm4sIHTDoWMgZ2nhuqMgdGnhur9uIGjDoG5oIGzhuq1wIGLhuqNuZyB04bqnbiBz4buRIGNobyBiaeG6v24gQ2h1cm4gbmjhurFtIHjDoWMgxJHhu4tuaCBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIChZZXMpIHbDoCBraMO0bmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoTm8pLiBL4bq/dCBxdeG6oyBj4bunYSBi4bqjbmcgdOG6p24gc+G7kSBnacO6cCBjdW5nIGPhuqVwIGPDoWkgbmjDrG4gdOG7lW5nIHF1YW4gduG7gSBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyB0cm9uZyB04burbmcgbmjDs20sIHF1YSDEkcOzIGjhu5cgdHLhu6MgcGjDom4gdMOtY2ggeHUgaMaw4bubbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0cm9uZyBi4buZIGThu68gbGnhu4d1Lg0KDQpgYGB7cn0NCmM8LSB0YWJsZSh2aWVudGhvbmckQ2h1cm4pICU+JSBhZGRtYXJnaW5zKCkgDQojIENodXnhu4NuIHRow6BuaCBkYXRhIGZyYW1lIHbhu5tpIDMgY+G7mXQ6IENodXJuIHwgU+G7kSBsxrDhu6NuZyB8IFN1bSAoVOG7lW5nIGPhu5luZykNCmRmIDwtIGRhdGEuZnJhbWUoDQogIENodXJuID0gYygiTm8iLCAiWWVzIiwgIlThu5VuZyBj4buZbmciKSwNCiAgU29fbHVvbmcgPSBhcy5udW1lcmljKGMpDQopDQoNCiMgSW4gcmEgYuG6o25nIMSR4bq5cCwgY8SDbiBnaeG7r2ENCmthYmxlKGRmLCBhbGlnbiA9ICJjIiwgY29sLm5hbWVzID0gYygiQ2h1cm4iLCAiU+G7kSBsxrDhu6NuZyIpKSAgJT4lDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJjZW50ZXIiLCBmb250X3NpemUgPSAxNCkgJT4lDQogIGNvbHVtbl9zcGVjKDEsIHdpZHRoID0gIjRjbSIpICU+JSAgIyDEkOG7mSBy4buZbmcgY+G7mXQgMQ0KICBjb2x1bW5fc3BlYygyLCB3aWR0aCA9ICIzY20iKSAgICAgICMgxJDhu5kgcuG7mW5nIGPhu5l0IDINCg0KI2zhuq1wIGLhuqNuZyB04bqnbiBz4buRIGPhu6dhIGPhu5l0IENodXJuIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgxJHGsOG7o2MgdMOqbiB2aWVudGhvbmcgdsOgIHRow6ptIGPhu5l0IHTDtG5nIHbDoG8gY3Xhu5FpIGLhuqNuZw0KYGBgDQoNCsSQ4buDIG1pbmggaOG7jWEgdHLhu7FjIHF1YW4ga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gdsOgIGtow7RuZyBy4budaSBi4buPIGThu4tjaCB24bulLCB0w6FjIGdp4bqjIHRp4bq/biBow6BuaCB24bq9IGJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmcgdGhlbyB04burbmcgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gQ2h1cm4uDQoNCmBgYHtyfQ0KYzwtIGFzLmRhdGEuZnJhbWUodGFibGUodmllbnRob25nJENodXJuKSkgDQpjb2xuYW1lcyhjKSA8LSBjKCJDaHVybiIsICJDb3VudCIpDQpnZ3Bsb3QoYywgYWVzKHggPSBDaHVybiwgeSA9IENvdW50LCBmaWxsID0gQ2h1cm4pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBDb3VudCksIHZqdXN0ID0gLTAuMywgc2l6ZSA9IDMuNSkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpE4buxYSB0csOqbiBi4bqjbmcgdOG6p24gc+G7kSBj4bunYSBiaeG6v24gQ2h1cm4sIGPDsyB04buVbmcgY+G7mW5nIDQ4MzIga2jDoWNoIGjDoG5nIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UsIHRyb25nIMSRw7MgMzI0NiBraMOhY2ggaMOgbmcgKGNoaeG6v20gxJFhIHPhu5EpIHbhuqtuIHRp4bq/cCB04bulYyBz4butIGThu6VuZyBk4buLY2ggduG7pSwgdHJvbmcga2hpIDEuNTg2IGtow6FjaCBow6BuZyDEkcOjIHLhu51pIGLhu48gZOG7i2NoIHbhu6UuIFPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY2hp4bq/bSBoxqFuIDEvMyB0csOqbiB04buVbmcga2jDoWNoIGjDoG5nLiANCg0KTmdvw6BpIHJhIHTDtGkgc+G6vSB0aOG7sWMgaGnhu4duIHTDrW5oIHThu7cgbOG7hyBwaOG6p24gdHLEg20gY2hvIHThu6tuZyBuaMOzbSB2w6AgduG6vSDEkeG7kyB0aOG7iyBj4buZdCBj4bunYSBjaMO6bmcgxJHhu4Mgc28gc8OhbmggdGhlbyBz4buRIGxp4buHdSB0xrDGoW5nIMSR4buRaS4NCg0KYGBge3J9DQojIFRow6ptIGPhu5l0IHBo4bqnbiB0csSDbQ0KYyRQZXJjZW50YWdlIDwtIHJvdW5kKHByb3AudGFibGUodGFibGUodmllbnRob25nJENodXJuKSkgKiAxMDAsIDIpDQojIELhuqJORyBQSOG6pk4gVFLEgk0NCmthYmxlKGMsIGFsaWduID0gImMiLCBjb2wubmFtZXMgPSBjKCJDaHVybiIsICJT4buRIGzGsOG7o25nIiwgIlBo4bqnbiB0csSDbSAoJSkiKSkgJT4lDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJjZW50ZXIiLCBmb250X3NpemUgPSAxNCkgJT4lDQogIGNvbHVtbl9zcGVjKDEsIHdpZHRoID0gIjRjbSIpICU+JQ0KICBjb2x1bW5fc3BlYygyLCB3aWR0aCA9ICIzY20iKSAlPiUNCiAgY29sdW1uX3NwZWMoMywgd2lkdGggPSAiNGNtIikNCg0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGMsIGFlcyh4ID0gIiIsIHkgPSBQZXJjZW50YWdlLCBmaWxsID0gQ2h1cm4pKSArDQogIGdlb21fYmFyKHdpZHRoID0gMSwgc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgY29vcmRfcG9sYXIoInkiKSArDQogIGxhYnModGl0bGUgPSAiVOG7tyBs4buHIHBo4bqnbiB0csSDbSIsIHggPSAiIiwgeSA9ICIiKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZShyb3VuZChQZXJjZW50YWdlLCAyKSwgIiUiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemUgPSA0KQ0KYGBgDQoNCkThu7FhIHRyw6puIGJp4buDdSDEkeG7kyB0csOybiB0aOG7gyBoaeG7h24gdOG7tyBs4buHIHBo4bqnbiB0csSDbSBj4bunYSBiaeG6v24gQ2h1cm4sIHRhIG5o4bqtbiB0aOG6pXkgbmjDs20ga2jDoWNoIGjDoG5nIGtow7RuZyBy4budaSBi4buPIGThu4tjaCB24bulIChObykgY2hp4bq/bSA2NywxOCUsIHRyb25nIGtoaSBuaMOzbSBy4budaSBi4buPIGThu4tjaCB24bulIChZZXMpIGNo4buJIGNoaeG6v20gMzIsODIlLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSDEkWEgc+G7kSBraMOhY2ggaMOgbmcgduG6q24gdGnhur9wIHThu6VjIHPhu60gZOG7pW5nIGThu4tjaCB24bulLiBUdXkgbmhpw6puLCB04bu3IGzhu4cgcuG7nWkgYuG7jyB24bqrbiDhu58gbeG7qWMga2jDoSBjYW8gduG7m2kgbeG7qWMgY2jDqm5oIGzhu4djaCBraG/huqNuZyAzNCwzNiUgKDY3LDE4JSDigJMgMzIsODIlKSBnaeG7r2EgaGFpIG5ow7NtLiBL4bq/dCBxdeG6oyBuw6B5IGfhu6NpIMO9IGRvYW5oIG5naGnhu4dwIGPhuqduIHThuq1wIHRydW5nIHBow6JuIHTDrWNoIHPDonUgaMahbiBuZ3V5w6puIG5ow6JuIGtoaeG6v24gMzIsODIlIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulLCB04burIMSRw7MgxJHGsGEgcmEgY8OhYyBiaeG7h24gcGjDoXAgY+G6o2kgdGhp4buHbiBuaOG6sW0gZ2nhuqNtIHThu7cgbOG7hyBuw6B5Lg0KDQojIyMjICoqMy4yLjEuMiBCaeG6v24gY8OhYyBsb+G6oWkgaOG7o3AgxJHhu5NuZyAoQ29udHJhY3QpKioNCg0KVMOhYyBnaeG6oyB0aeG6v24gaMOgbmggbOG6rXAgYuG6o25nIHThuqduIHPhu5EgY2hvIGJp4bq/biBDb250cmFjdCBuaOG6sW0geMOhYyDEkeG7i25oIHPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIHRoZW8gbG/huqFpIGjhu6NwIMSR4buTbmcgbsOgby4gS+G6v3QgcXXhuqMgY+G7p2EgYuG6o25nIHThuqduIHPhu5EgZ2nDunAgY3VuZyBj4bqlcCBjw6FpIG5ow6xuIHThu5VuZyBxdWFuIHbhu4Egc+G7kSBsxrDhu6NuZyBo4bujcCDEkeG7k25nIHRyb25nIHThu6tuZyBuaMOzbS4NCg0KYGBge3J9DQp2aWVudGhvbmckQ29udHJhY3QyIDwtIGlmZWxzZSh2aWVudGhvbmckQ29udHJhY3QgPT0gIk9uZSB5ZWFyIiwgIk9uZSB5ZWFyIiwgIktow6FjIikNCnZpZW50aG9uZyRDb250cmFjdDIgPC0gZmFjdG9yKHZpZW50aG9uZyRDb250cmFjdDIsIGxldmVscyA9IGMoIk9uZSB5ZWFyIiwgIktow6FjIikpDQp0YWJsZSh2aWVudGhvbmckQ29udHJhY3QyKSANCiMgSW4gcmEgYuG6o25nIMSR4bq5cCwgY8SDbiBnaeG7r2ENCmthYmxlKHRhYmxlKHZpZW50aG9uZyRDb250cmFjdDIpICwgYWxpZ24gPSAiYyIsIGNvbC5uYW1lcyA9IGMoIkNvbnRyYWN0IiwgIlPhu5EgbMaw4bujbmciKSkgICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAiY2VudGVyIiwgZm9udF9zaXplID0gMTQpICU+JQ0KICBjb2x1bW5fc3BlYygxLCB3aWR0aCA9ICI0Y20iKSAlPiUgICMgxJDhu5kgcuG7mW5nIGPhu5l0IDENCiAgY29sdW1uX3NwZWMoMiwgd2lkdGggPSAiM2NtIikgICAgICAjIMSQ4buZIHLhu5luZyBj4buZdCAyDQoNCmBgYA0KDQpUcm9uZyBuZ2hpw6puIGPhu6l1IG7DoHksIGJp4bq/biBDb250cmFjdCDEkcaw4bujYyB0w6FpIHBow6JuIGxv4bqhaSB0aMOgbmggaGFpIG5ow7NtOiBPbmUgeWVhciB2w6AgS2jDoWMgbmjhurFtIHRodeG6rW4gdGnhu4duIGNobyB2aeG7h2MgcGjDom4gdMOtY2guIEvhur90IHF14bqjIHRo4buRbmcga8OqIG3DtCB04bqjIGNobyB0aOG6pXkgY8OzIDk2NCBo4bujcCDEkeG7k25nIHRodeG7mWMgbmjDs20gT25lIHllYXIsIHRyb25nIGtoaSAzLjg2OCBo4bujcCDEkeG7k25nIGPDsm4gbOG6oWkgdGh14buZYyBuaMOzbSBLaMOhYy4gRMaw4bubaSDEkcOieSBsw6AgYmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGPhu6dhIGPDoWMgbmjDs20gdHJvbmcgYmnhur9uIENvbnRyYWN0LiANCg0KYGBge3J9DQojIFThuqFvIGLhuqNuZyB04bqnbiBz4buRIGNobyBiaeG6v24gdHlwZQ0KdCA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHZpZW50aG9uZyRDb250cmFjdDIpICkNCmNvbG5hbWVzKHQpIDwtIGMoIkNvbnRyYWN0MiIsICJDb3VudCIpDQoNCmdncGxvdCh0LCBhZXMoeCA9IENvbnRyYWN0MiwgeSA9IENvdW50LCBmaWxsID0gQ29udHJhY3QyKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjUpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgdmp1c3QgPSAtMC41LCBzaXplID0gMy41KSArICMgSGnhu4NuIHRo4buLIHPhu5EgbGnhu4d1IGLDqm4gdHLDqm4gY+G7mXQNCiAgbGFicyh0aXRsZSA9ICLEkOG7kyB0aOG7iyBjw6FjIGxv4bqhaSBo4bujcCDEkeG7k25nIiwgeCA9ICJDb250cmFjdCIsIHkgPSAiRnJlcXVlbmN5IikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpN4bq3dCBraMOhYyB0YSBjxaluZyBj4bqnbiB0aOG7sWMgaGnhu4duIHBow6JuIHTDrWNoIHThu7cgbOG7hyBwaOG6p24gdHLEg20gxJHhu5FpIHbhu5tpIHThu6tuZyBsb+G6oWkgaOG7o3AgxJHhu5NuZyB2w6AgdHLhu7FjIHF1YW4gY2jDum5nIGLhurFuZyDEkeG7kyB0aOG7iyB0csOybiDEkeG7gyBjw7MgdGjhu4MgZOG7hSBkw6BuZyBzbyBzw6FuaCB24bubaSBuaGF1Lg0KDQpgYGB7cn0NCg0KIyBUaMOqbSBj4buZdCBwaOG6p24gdHLEg20NCnQkUGVyY2VudGFnZSA8LSAodCRDb3VudCAvIHN1bSh0JENvdW50KSkgKiAxMDANCiMgQuG6ok5HIFBI4bqmTiBUUsSCTQ0Ka2FibGUodCwgYWxpZ24gPSAiYyIsIGNvbC5uYW1lcyA9IGMoIkNvbnRyYWN0MiIsICJT4buRIGzGsOG7o25nIiwgIlBo4bqnbiB0csSDbSAoJSkiKSkgJT4lDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJjZW50ZXIiLCBmb250X3NpemUgPSAxNCkgJT4lDQogIGNvbHVtbl9zcGVjKDEsIHdpZHRoID0gIjRjbSIpICU+JQ0KICBjb2x1bW5fc3BlYygyLCB3aWR0aCA9ICIzY20iKSAlPiUNCiAgY29sdW1uX3NwZWMoMywgd2lkdGggPSAiNGNtIikNCg0KYGBgDQoNCg0KYGBge3J9DQpnZ3Bsb3QodCwgYWVzKHggPSAiIiwgeSA9IFBlcmNlbnRhZ2UsIGZpbGwgPSBDb250cmFjdDIpKSArDQogIGdlb21fYmFyKHdpZHRoID0gMSwgc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgY29vcmRfcG9sYXIoInkiKSArDQogIGxhYnModGl0bGUgPSAiVOG7tyBs4buHIHBo4bqnbiB0csSDbSIsIHggPSAiIiwgeSA9ICIiKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZShyb3VuZChQZXJjZW50YWdlLCAyKSwgIiUiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemUgPSA0KQ0KYGBgDQoNCkvhur90IHF14bqjIHRo4buRbmcga8OqIGNobyB0aOG6pXkgYmnhur9uIENvbnRyYWN0IMSRw6MgxJHGsOG7o2MgcGjDom4gbG/huqFpIHRow6BuaCBoYWkgbmjDs206IE9uZSB5ZWFyIHbDoCBLaMOhYywgduG7m2kgOTY0IGjhu6NwIMSR4buTbmcgdGh14buZYyBuaMOzbSBPbmUgeWVhciAoY2hp4bq/bSAxOSw5NSUpIHbDoCAzODY4IGjhu6NwIMSR4buTbmcgdGh14buZYyBuaMOzbSBLaMOhYyAoY2hp4bq/bSA4MCwwNSUpLiBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu7EgY2jDqm5oIGzhu4djaCByw7UgcuG7h3QgZ2nhu69hIGhhaSBuaMOzbSwgdHJvbmcgxJHDsyBo4bujcCDEkeG7k25nIEtow6FjIGNoaeG6v20gdOG7tyB0cuG7jW5nIGzhu5tuLiANCg0KIyMjICoqMy4yLjIgVGjhu5FuZyBrw6ogbcO0IHThuqMgY2hvIGhhaSBiaeG6v24ga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdsOgIGPDoWMgbG/huqFpIGjhu6NwIMSR4buTbmcqKg0KDQpUcm9uZyB0csaw4budbmcgaOG7o3AgbsOgeSwgdMOhYyBnaeG6oyBs4bqtcCBi4bqjbmcgdOG6p24gc+G7kSBnaeG7r2EgaGFpIGJp4bq/biBDaHVybiAoa2jDoWNoIGjDoG5nIHLhu51pIGLhu48ga2jDoWNoIGjDoG5nKSB2w6AgQ29udHJhY3QgKGPDoWMgbG/huqFpIGjhu6NwIMSR4buTbmcpLiBC4bqjbmcgdOG6p24gc+G7kSBnacO6cCBjaMO6bmcgdGEgaGnhu4N1IHLDtSBoxqFuIHbhu4Egc+G7sSBwaMOibiBi4buRIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIHZp4buFbiB0aMO0bmcgdGhlbyB04burbmcgbG/huqFpIGjhu6NwIMSR4buTbmcuDQoNCmBgYHtyfQ0KdGFibGUodmllbnRob25nJENvbnRyYWN0MiwgdmllbnRob25nJENodXJuKSAlPiUgIGFkZG1hcmdpbnMoKQ0KYGBgDQpW4bq9IMSR4buTIHRo4buLIGPhu5l0IHBow6JuIHRoZW8gdOG7q25nIGxv4bqhaSBo4bujcCDEkeG7k25nIMSR4buDIMSRw6FuaCBnacOhIHPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6Ugdmnhu4VuIHRow7RuZyB0cm9uZyB04burbmcgbmjDs20uDQoNCmBgYHtyfQ0KdGFibGVfZGF0YSA8LSB0YWJsZSh2aWVudGhvbmckQ29udHJhY3QyLCB2aWVudGhvbmckQ2h1cm4pDQoNCiMgQ2h1eeG7g24gYuG6o25nIGNow6lvIHNhbmcgxJHhu4tuaCBk4bqhbmcgZMOgaQ0KbG9uZ19kYXRhIDwtIGFzLmRhdGEuZnJhbWUodGFibGVfZGF0YSkNCmNvbG5hbWVzKGxvbmdfZGF0YSkgPC0gYygiQ29udHJhY3QyIiwgIkNodXJuIiwgImNvdW50IikNCg0KIyBW4bq9IGJp4buDdSDEkeG7kyBj4buZdA0KZ2dwbG90KGxvbmdfZGF0YSwgYWVzKHggPSBDaHVybiwgeSA9IGNvdW50LCBmaWxsID0gQ2h1cm4pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNvdW50KSwgdmp1c3QgPSAxLCBzaXplID0gMi41LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDEpKSArDQogIGZhY2V0X3dyYXAofiBDb250cmFjdDIsIHNjYWxlcyA9ICJmcmVlX3kiLCBucm93ID0gMikgKw0KICBsYWJzKHRpdGxlID0gIlBow6JuIGLhu5Ega2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdGhlbyBsb+G6oWkgaOG7o3AgxJHhu5NuZyIsDQogICAgICAgeCA9ICJLaMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBo4bujcCDEkeG7k25nIiwNCiAgICAgICB5ID0gIkxv4bqhaSBo4bujcCDEkeG7k25nIiwNCiAgICAgICBmaWxsID0gIktow6FjaCBow6BuZyBy4budaSBi4buPIGjhu6NwIMSR4buTbmciKSArDQogIHRoZW1lX21pbmltYWwoKSAgDQpgYGANCg0KROG7sWEgdHLDqm4ga+G6v3QgcXXhuqMgdGjhu5FuZyBrw6osIGJp4buDdSDEkeG7kyBjaG8gdGjhuqV5IHPhu7EgcGjDom4gYuG7kSBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0aGVvIGxv4bqhaSBo4bujcCDEkeG7k25nLiDEkOG7kWkgduG7m2kgbmjDs20gaOG7o3AgxJHhu5NuZyBPbmUgWWVhciBjw7MgODIxIGtow6FjaCBow6BuZyBraMO0bmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSwgdHJvbmcga2hpIGNo4buJIGPDsyAxNDMga2jDoWNoIMOgbmcgcuG7nWkgYuG7jywgY2hp4bq/bSAxNC44JS4gTmfGsOG7o2MgbOG6oWksIOG7nyBuaMOzbSBo4bujcCDEkeG7k25nIEtow6FjIHPhu5Ega2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgbMOqbiB04bubaSAxNDQzIGPDoW8gaMahbiDEkcOhbmcga+G7gyBzbyB24bubaSAyNDI1IGtow6FjaCBow6BuZyB0aeG6v3AgdOG7pWMgc+G7rSBk4bulbmcgZOG7i2NoIHbhu6UsIHTGsMahbmcg4bupbmcgduG7m2kgMzcuMyUuIE5oxrAgduG6rXkgdOG7tyBs4buHIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2Ega2jDoWNoIGjDoG5nIOG7nyBuaMOzbSBLaMOhYyBjYW8gZ+G6p24gMyBs4bqnbiBzbyB24bubaSBuaMOzbSBPbmUgWWVhci4gR8OzcCBwaOG6p24ga2jhurNuZyDEkeG7i25oIHZhaSB0csOyIGPhu6dhIGPDoWMgaOG7o3AgxJHhu5NuZyAxIG7Eg20gdHJvbmcgdmnhu4djIGdp4buvIGNow6JuIGtow6FjaCBow6BuZy4gS2h1eeG6v24ga2jDrWNoIGRvYW5oIG5naGnhu4dwIGPhuqduIMSR4bqpeSBt4bqhbmggY2jDrW5oIHPDoWNoIMawdSDEkcOjaSBob+G6t2MgY8OhYyBnw7NpIGThu4tjaCB24bulIGNobyBo4bujcCDEkeG7k25nICJPbmUgeWVhciIgbmjhurFtIGPDsyBuaGnhu4F1IGtow6FjaCBow6BuZyBjaHV54buDbiBzYW5nIGxv4bqhaSBo4bujcCDEkeG7k25nIG7DoHkgxJHhu4MgZ2nhuqNtIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulLg0KDQpUaeG6v3AgdGhlbywgbOG6rXAgYuG6o25nIHThuqduIHN14bqldCBnaeG7r2EgaGFpIGJp4bq/biBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB2aeG7hW4gdGjDtG5nIHbDoCBjw6FjIGxv4bqhaSBo4bujcCDEkeG7k25nLiBU4burIMSRw7MgduG6vSDEkeG7kyB0aMOsIGPhu5l0IHRoZW8gdOG7q25nIG5ow7NtIGPDtG5nIHZp4buHYyBuaMawIGLDqm4gZMaw4bubaSDEkcOieS4NCg0KYGBge3J9DQp0YWJsZV9kYXRhMSA8LSByb3VuZChwcm9wLnRhYmxlKHRhYmxlX2RhdGEpKjEwMCwyKSANCmthYmxlKHRhYmxlX2RhdGExLCBhbGlnbiA9ICJjIiwgY29sLm5hbWVzID0gYygiQ29udHJhY3QyIiwgIk5vIiwgIlllcyIpKSAlPiUNCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImNlbnRlciIsIGZvbnRfc2l6ZSA9IDE0KSAlPiUNCiAgY29sdW1uX3NwZWMoMSwgd2lkdGggPSAiNGNtIikgJT4lDQogIGNvbHVtbl9zcGVjKDIsIHdpZHRoID0gIjNjbSIpICU+JQ0KICBjb2x1bW5fc3BlYygzLCB3aWR0aCA9ICI0Y20iKQ0KDQpgYGANCmBgYHtyfQ0KIyBDaHV54buDbiDEkeG7lWkgZOG7ryBsaeG7h3UgdGjDoG5oIGThuqFuZyBkw6BpIMSR4buDIGThu4UgduG6vSBiaeG7g3UgxJHhu5MNCnRhYmxlX2RhdGExIDwtIGFzLmRhdGEuZnJhbWUudGFibGUodGFibGVfZGF0YTEpDQpjb2xuYW1lcyh0YWJsZV9kYXRhMSkgPC0gYygiR3JvdXAiLCAiTGV2ZWwiLCAiUGVyY2VudGFnZSIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MNCmdncGxvdCh0YWJsZV9kYXRhMSwgYWVzKHggPSBMZXZlbCwgeSA9IFBlcmNlbnRhZ2UsIGZpbGwgPSBMZXZlbCkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gUGVyY2VudGFnZSksIHZqdXN0ID0gMSwgc2l6ZSA9IDIuNSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgxKSkgKw0KICBmYWNldF93cmFwKH4gR3JvdXAsIHNjYWxlcyA9ICJmcmVlX3kiLCBucm93ID0gMikgKw0KICBsYWJzKHRpdGxlID0gIsSQ4buTIHRo4buLIHBo4bqnbiB0csSDbSB0aGVvIGJp4buDdSBoaeG7h24geWVzLCBubyBj4bunYSBraMOhY2ggaMOgbmcgdOG7qyBi4buPIGThu4tjaCB24bulIHbDoCBjw6FjIGxv4bqhaSBo4bujcCDEkeG7k25nIiwNCiAgICAgICB4ID0gIkPDoWMgbG/huqFpIGjhu6NwIMSR4buTbmciLA0KICAgICAgIHkgPSAiUGjhuqduIHRyxINtIiwNCiAgICAgICBmaWxsID0gIkJp4buDdSBoaeG7h24iKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIk5vIiA9ICJza3libHVlIiwgIlllcyIgPSAicGluayIpKSArIA0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpE4buxYSB0csOqbiBr4bq/dCBxdeG6oyBi4bqjbmcgdOG6p24gc3XhuqV0IHbDoCBiaeG7g3UgxJHhu5MgdOG6p24gc3XhuqV0LCBjw7MgdGjhu4Mgbmjhuq1uIHRo4bqleSBz4buxIGtow6FjIGJp4buHdCByw7UgcuG7h3QgduG7gSB04bu3IGzhu4cga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgZ2nhu69hIGhhaSBuaMOzbSBo4bujcCDEkeG7k25nIE9uZSB5ZWFyIHbDoCBLaMOhYy4gQ+G7pSB0aOG7gywgdHJvbmcgbmjDs20gT25lIHllYXIsIHThu7cgbOG7hyBraMOhY2ggaMOgbmcga2jDtG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY2hp4bq/bSAxNiw5OSUsIHRyb25nIGtoaSBjaOG7iSBjw7MgMiw5NiUga2jDoWNoIGjDoG5nIHLhu51pIGLhu48uIE5nxrDhu6NjIGzhuqFpLCDhu58gbmjDs20gS2jDoWMsIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBjYW8gaMahbiBuaGnhu4F1LCDEkeG6oXQgMjksODYlIHNvIHbhu5tpIDUwLDE5JSBraMOhY2ggaMOgbmcgdGnhur9wIHThu6VjIHPhu60gZOG7pW5nLiANCg0KDQojIyMgKiozLjIuMyBQaMOibiB0w61jaCBSZWxhdGl2ZSBSaXNrIGdp4buvYSBjw6FjIGxv4bqhaSBo4bujcCDEkeG7k25nIHbDoCBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSoqDQoNClRyb25nIHBo4bqnbiB0aeG6v3AgdGhlbywgdMOhYyBnaeG6oyBz4bq9IHRp4bq/biBow6BuaCB0w61uaCB0b8OhbiBjaOG7iSBz4buRIHLhu6dpIHJvIHTGsMahbmcgxJHhu5FpIChSZWxhdGl2ZSBSaXNrIOKAkyBSUikgbmjhurFtIMSRw6FuaCBnacOhIG3hu6ljIMSR4buZIOG6o25oIGjGsOG7n25nIGPhu6dhIHThu6tuZyBsb+G6oWkgaOG7o3AgxJHhu5NuZyDEkeG6v24ga2jhuqMgbsSDbmcga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6Ugdmnhu4VuIHRow7RuZy4NCg0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQpycjE8LSByaXNrcmF0aW8odGFibGVfZGF0YSkNCnJyMQ0KYGBgDQpDaOG7iSBz4buRIFJlbGF0aXZlIFJpc2sgKFJSKSDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyDEkcOhbmggZ2nDoSBt4bupYyDEkeG7mSBraMOhYyBiaeG7h3QgduG7gSB4w6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIGdp4buvYSBoYWkgbmjDs20gaOG7o3AgxJHhu5NuZyBPbmUgeWVhciB2w6AgS2jDoWMuIEPDtG5nIHRo4bupYyB0w61uaCBSUiBuaMawIHNhdToNCg0KJCQNClJSID0gXGZyYWN7UChcdGV4dHtZZXMgfCBLaMOhY30pfXtQKFx0ZXh0e1llcyB8IE9uZSB5ZWFyfSl9DQokJA0KDQp0cm9uZyDEkcOzIFwoIFAoXHRleHR7WWVzIHwgS2jDoWN9KSA9IFxmcmFjezE0NDN9ezM4Njh9IFxhcHByb3ggMCwzNzMzIFwpIHbDoCBcKCBQKFx0ZXh0e1llcyB8IE9uZSB5ZWFyfSkgPSBcZnJhY3sxNDN9ezk2NH0gXGFwcHJveCAwLDE0ODQgXCkuICANCg0KVGhheSBjw6FjIGdpw6EgdHLhu4sgbsOgeSB2w6BvIGPDtG5nIHRo4bupYywgdGEgdGh1IMSRxrDhu6NjIFJSIOKJiCAyLDUxLCB04bupYyBsw6Aga2jDoWNoIGjDoG5nIHPhu60gZOG7pW5nIGjhu6NwIMSR4buTbmcg4oCcS2jDoWPigJ0gY8OzIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY2FvIGjGoW4ga2hv4bqjbmcgMiw1IGzhuqduIHNvIHbhu5tpIG5ow7NtIGtow6FjaCBow6BuZyBz4butIGThu6VuZyBo4bujcCDEkeG7k25nIOKAnE9uZSB5ZWFy4oCdLiBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGPhu6dhIFJSIGzDoCBbMiwxNTsgMiw5NF0sIGNobyB0aOG6pXkga+G6v3QgcXXhuqMgxrDhu5tjIGzGsOG7o25nIMSRw6FuZyB0aW4gY+G6rXkgdsOgIGtow7RuZyBjaOG7qWEgZ2nDoSB0cuG7iyAxLCBuZ2jEqWEgbMOgIHPhu7Ega2jDoWMgYmnhu4d0IGdp4buvYSBoYWkgbmjDs20gbMOgIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouIMSQ4buTbmcgdGjhu51pLCBnacOhIHRy4buLIHAtdmFsdWUgKDEsNzFlLTQ0KSBn4bqnbiBi4bqxbmcgMCBjw6BuZyBraOG6s25nIMSR4buLbmggc+G7sSBraMOhYyBiaeG7h3QgbsOgeSBsw6AgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqi4gVsOsIHbhuq15LCBsb+G6oWkgaOG7o3AgxJHhu5NuZyBsw6AgbeG7mXQgbmjDom4gdOG7kSBxdWFuIHRy4buNbmcg4bqjbmggaMaw4bufbmcgxJHhur9uIGjDoG5oIHZpIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdsOgIGPDoWMgaOG7o3AgxJHhu5NuZyBkw6BpIGjhuqFuIG5oxrAg4oCcT25lIHllYXLigJ0gZ2nDunAgZ2nhuqNtIMSRw6FuZyBr4buDIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jy4gRG9hbmggbmdoaeG7h3Agdmnhu4VuIHRow7RuZyBjw7MgdGjhu4MgZOG7sWEgdsOgbyBr4bq/dCBxdeG6oyBuw6B5IMSR4buDIHjDonkgZOG7sW5nIGNoaeG6v24gbMaw4bujYyBraHV54bq/biBraMOtY2gga2jDoWNoIGjDoG5nIGNo4buNbiBo4bujcCDEkeG7k25nIGTDoGkgaOG6oW4sIHThu6sgxJHDsyBnaeG6o20gY2h1cm4gdsOgIHTEg25nIHTDrW5oIOG7lW4gxJHhu4tuaCB0cm9uZyBkb2FuaCB0aHUuDQoNCiMjIyAqKjMuMi40IFBow6JuIHTDrWNoIE9kZCBSYXRpbyBnaeG7r2EgY8OhYyBsb+G6oWkgaOG7o3AgxJHhu5NuZyB2w6Aga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UqKg0KDQpUcm9uZyBwaOG6p24gbsOgeSwgbmdoacOqbiBj4bupdSBz4bq9IHRp4bq/biBow6BuaCB0w61uaCBPZGRzIFJhdGlvIGdp4buvYSBoYWkgbG/huqFpIGjhu6NwIMSR4buTbmcgdsOgIGJp4bq/biBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB2aeG7hW4gdGjDtG5nIChDaHVybikuIFZp4buHYyB0w61uaCB0b8OhbiBPUiBz4bq9IGdpw7pwIHjDoWMgxJHhu4tuaCBsb+G6oWkgaOG7o3AgxJHhu5NuZyBuw6BvIGzDoG0gdMSDbmcgaG/hurdjIGdp4bqjbSBraOG6oyBuxINuZyBy4budaSBi4buPIGThu4tjaCB24bulLCBxdWEgxJHDsyBjdW5nIGPhuqVwIHRow7RuZyB0aW4gcXVhbiB0cuG7jW5nIMSR4buDIGRvYW5oIG5naGnhu4dwIMSRxrBhIHJhIGPDoWMgY2hp4bq/biBsxrDhu6NjIGdp4buvIGNow6JuIGtow6FjaCBow6BuZyBwaMO5IGjhu6NwLg0KDQpgYGB7cn0NCm9yMSA8LSBvZGRzcmF0aW8odGFibGVfZGF0YSkNCm9yMQ0KYGBgDQoNCkThu7FhIHRyw6puIGvhur90IHF14bqjIHBow6JuIHTDrWNoIE9kZHMgUmF0aW8gKE9SKSBnaeG7r2EgaGFpIGxv4bqhaSBo4bujcCDEkeG7k25nIHbDoCBow6BuaCB2aSBy4budaSBi4buPIGThu4tjaCB24bulLCB0YSB0w61uaCDEkcaw4bujYyBPUiA9IDMsNDEuIEdpw6EgdHLhu4sgbsOgeSDEkcaw4bujYyB4w6FjIMSR4buLbmggdOG7qyBjw7RuZyB0aOG7qWM6ICANCg0KJCQNCk9SID0gXGZyYWN7XGZyYWN7MTQ0M317MjQyNX19e1xmcmFjezE0M317ODIxfX0gXGFwcHJveCAzLDQxDQokJA0KDQpuZ2jEqWEgbMOgIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIG5ow7NtIGtow6FjaCBow6BuZyBz4butIGThu6VuZyBo4bujcCDEkeG7k25nIEtow6FjIGNhbyBn4bqlcCAzLDQxIGzhuqduIHNvIHbhu5tpIG5ow7NtIE9uZSB5ZWFyLiBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGPhu6dhIE9SIG7hurFtIHRyb25nIGtob+G6o25nIFsyLDgzOyA0LDE0XSwga2jDtG5nIGNo4bupYSBnacOhIHRy4buLIDEsIGNobyB0aOG6pXkgc+G7sSBraMOhYyBiaeG7h3QgZ2nhu69hIGhhaSBuaMOzbSBsw6AgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqi4gR2nDoSB0cuG7iyBwLXZhbHVlICgxLDcxZS00NCkgY+G7sWMga+G7syBuaOG7jywga2jhurNuZyDEkeG7i25oIGxv4bqhaSBo4bujcCDEkeG7k25nIGPDsyDhuqNuaCBoxrDhu59uZyDEkcOhbmcga+G7gyDEkeG6v24ga2jhuqMgbsSDbmcga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UuIEvhur90IHF14bqjIG7DoHkgY2jhu6luZyB04buPIHLhurFuZyBraMOhY2ggaMOgbmcgc+G7rSBk4bulbmcgaOG7o3AgxJHhu5NuZyBPbmUgeWVhciBjw7MgbeG7qWMgxJHhu5kgZ+G6r24gYsOzIHbhu5tpIGThu4tjaCB24bulIGNhbyBoxqFuLg0KDQojIyMgKiozLjIuNSBUaOG7kW5nIGvDqiBzdXkgZGnhu4VuKioNCg0KIyMjIyAgKiozLjIuNS4xIEtp4buDbSDEkeG7i25oIHTDrW5oIMSR4buZYyBs4bqtcCoqDQoNCsSQ4buDIGtp4buDbSB0cmEgeGVtIGJp4bq/biBsb+G6oWkgaOG7o3AgxJHhu5NuZyAoQ29udHJhY3QpIHbDoCBow6BuaCB2aSBy4budaSBi4buPIGThu4tjaCB24bulIChDaHVybikgY8OzIG3hu5FpIGxpw6puIGjhu4cgduG7m2kgbmhhdSBoYXkga2jDtG5nLCBuZ2hpw6puIGPhu6l1IMOhcCBk4bulbmcga2nhu4NtIMSR4buLbmggQ2hpLXNxdWFyZS4NCg0KS2nhu4NtIMSR4buLbmggbsOgeSDEkcaw4bujYyB0aGnhur90IGzhuq1wIHbhu5tpIGdp4bqjIHRodXnhur90OiANCg0KJCQNClxsZWZ0XHsNClxiZWdpbnthcnJheX17bGx9DQpIXzA6ICYgXHRleHR7Qmnhur9uIENodXJuIChraMOhY2ggaMOgbmcgdOG7qyBi4buPIGThu4tjaCB24bulKSB2w6AgYmnhur9uIENvbnRyYWN0IChjw6FjIGxv4bqhaSBo4bujcCDEkeG7k25nKSBraMO0bmcgY8OzIG3hu5FpIHF1YW4gaOG7hyB24bubaSBuaGF1Ln0gIFxcXFwNCkhfMTogJiBcdGV4dHtCaeG6v24gQ2h1cm4gKGtow6FjaCBow6BuZyB04burIGLhu48gZOG7i2NoIHbhu6UpIHbDoCBiaeG6v24gQ29udHJhY3QgKGPDoWMgbG/huqFpIGjhu6NwIMSR4buTbmcpIGPDsyBt4buRaSBxdWFuIGjhu4cgduG7m2kgbmhhdS59IFwNClxlbmR7YXJyYXl9DQpccmlnaHQuDQokJA0KDQpgYGB7cn0NCiMgS2nhu4NtIMSR4buLbmgNCmNoaXNxX3Jlc3VsdDEgPC0gY2hpc3EudGVzdCh0YWJsZV9kYXRhKQ0KIyBJbiBr4bq/dCBxdeG6ow0KY2hpc3FfcmVzdWx0MQ0KYGBgDQoNClF1YSBr4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaDogVuG7m2kgbeG7qWMgw70gbmdoxKlhIDAuMDUsIHbDrCBwLXZhbHVlID0gMi4yZS0xNiA8IDAuMDUsIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCAkSF8wJC4gVuG6rXkgZ2nhu69hIGJp4bq/biBDaHVybiB2w6AgYmnhur9uIENvbnRyYWN0IHThu5NuIHThuqFpIG3hu5FpIHF1YW4gaOG7hy4NCg0KIyMjIyAqKjMuMi41LjIgS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIHThu7cgbOG7hyoqDQoNCioqxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIG5ow7NtIGtow6FjaCBow6BuZyBjw7MgaOG7o3AgxJHhu5NuZyBPbmUgeWVhcioqIA0KDQpUcm9uZyBwaOG6p24gbsOgeSwgdMOhYyBnaeG6oyBz4butIGThu6VuZyBraeG7g20gxJHhu4tuaCB04bu3IGzhu4cgbeG7mXQgbeG6q3UgKDEtc2FtcGxlIHByb3BvcnRpb24gdGVzdCkgxJHhu4MgxrDhu5tjIGzGsOG7o25nIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0cm9uZyBuaMOzbSBo4bujcCDEkeG7k25nIE9uZSB5ZWFyLCDEkeG7k25nIHRo4budaSBzbyBzw6FuaCB24bubaSB04bu3IGzhu4cgZ2nhuqMgxJHhu4tuaCBsw6AgNTAlIChwID0gMC41KS4gUGjGsMahbmcgcGjDoXAgbsOgeSBnacO6cCB4w6FjIMSR4buLbmggeGVtIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIG5ow7NtIGjhu6NwIMSR4buTbmcgbsOgeSBjw7Mga2jDoWMgYmnhu4d0IMSRw6FuZyBr4buDIHNvIHbhu5tpIHThu7cgbOG7hyBnaeG6oyDEkeG7i25oIGhheSBraMO0bmcuIA0KDQoNCmBgYHtyfQ0KcHJvcC50ZXN0KHggPSB0YWJsZV9kYXRhWyJPbmUgeWVhciIsICJZZXMiXSwgbiA9IHN1bSggdGFibGVfZGF0YVsiT25lIHllYXIiLCBdKSwgcCA9IDAuNSwgY29ycmVjdCA9IFRSVUUpDQpgYGANCg0KS+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmggY2hvIHRo4bqleSB04bu3IGzhu4cgbeG7mXQgbeG6q3UgY2hvIG5ow7NtIGjhu6NwIMSR4buTbmcgIE9uZSB5ZWFyIGNobyB0aOG6pXkgdOG7tyBs4buHIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdGjhu7FjIHThur8gY2jhu4kga2hv4bqjbmcgMTQsODMlLCB0aOG6pXAgaMahbiBuaGnhu4F1IHNvIHbhu5tpIHThu7cgbOG7hyBnaeG6oyDEkeG7i25oIDUwJS4gS2hv4bqjbmcgdGluIGPhuq15IDk1JSBj4bunYSB04bu3IGzhu4cgbsOgeSBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDEyLDY4JSDEkeG6v24gMTcsMjclIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIG5ow7NtIGtow6FjaCBow6BuZyBPbmUgeWVhciDhu5VuIMSR4buLbmggcXVhbmggbeG7qWMgMTUlLiBHacOhIHRy4buLIHAtdmFsdWUgY+G7p2Ega2nhu4NtIMSR4buLbmggYuG6sW5nIDwgMi4yZS0xNiBuaOG7jyBoxqFuIG3hu6ljIMO9IG5naMSpYSA1JSwgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAgcuG6sW5nIHThu7cgbOG7hyBy4budaSBi4buPIGzDoCA1MCUuDQoNCioqxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIG5ow7NtIGtow6FjaCBow6BuZyBjw7MgaOG7o3AgxJHhu5NuZyBLaMOhYyoqIA0KDQpUcm9uZyBwaOG6p24gbsOgeSB0w6FjIGdp4bqjIHPhu60gZOG7pW5nIGtp4buDbSDEkeG7i25oIHThu7cgbOG7hyBt4buZdCBt4bqrdSAoMS1zYW1wbGUgcHJvcG9ydGlvbiB0ZXN0KSDEkeG7gyDGsOG7m2MgbMaw4bujbmcgdOG7tyBs4buHIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIHRyb25nIG5ow7NtIGjhu6NwIMSR4buTbmcga2jDoWMsIMSR4buTbmcgdGjhu51pIHNvIHPDoW5oIHbhu5tpIHThu7cgbOG7hyBnaeG6oyDEkeG7i25oIGzDoCA1MCUgKHAgPSAwLjUpLiBQaMawxqFuZyBwaMOhcCBuw6B5IGdpw7pwIHjDoWMgxJHhu4tuaCB4ZW0gdOG7tyBs4buHIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2EgbmjDs20gaOG7o3AgxJHhu5NuZyBuw6B5IGPDsyBraMOhYyBiaeG7h3QgxJHDoW5nIGvhu4Mgc28gduG7m2kgdOG7tyBs4buHIGdp4bqjIMSR4buLbmggaGF5IGtow7RuZy4gDQoNCmBgYHtyfQ0KcHJvcC50ZXN0KHggPSB0YWJsZV9kYXRhWyJLaMOhYyIsICJZZXMiXSwgbiA9IHN1bSggdGFibGVfZGF0YVsiS2jDoWMiLCBdKSwgcCA9IDAuNSwgY29ycmVjdCA9IFRSVUUpDQpgYGANCg0KS+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmggdOG7tyBs4buHIG3hu5l0IG3huqt1IMSR4buRaSB24bubaSBuaMOzbSBraMOhY2ggaMOgbmcgY8OzIGjhu6NwIMSR4buTbmcgS2jDoWMgY2hvIHRo4bqleSB04bu3IGzhu4cgcuG7nWkgYuG7jyBk4buLY2ggduG7pSDGsOG7m2MgbMaw4bujbmcgdOG7qyBt4bqrdSBsw6AgMzcsMzElLCB24bubaSBraG/huqNuZyB0aW4gY+G6rXkgOTUlIGRhbyDEkeG7mW5nIHThu6sgMzUsNzglIMSR4bq/biAzOCw4NSUuIEdpw6EgdHLhu4sgcC12YWx1ZSA8IDIuMmUtMTYsIG5o4buPIGjGoW4gbeG7qWMgw70gbmdoxKlhIDAsMDUsIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKAIHLhurFuZyB04bu3IGzhu4cgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBj4bunYSBuaMOzbSBuw6B5IGLhurFuZyA1MCUuIE5oxrAgduG6rXksIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIG5ow7NtIGjhu6NwIMSR4buTbmcgS2jDoWMgdGjhuqVwIGjGoW4gxJHDoW5nIGvhu4Mgc28gduG7m2kgdOG7tyBs4buHIGdp4bqjIMSR4buLbmggdsOgIOG7lW4gxJHhu4tuaCBxdWFuaCBt4bupYyAzNyUuIMSQaeG7gXUgbsOgeSBjxaluZyBjaG8gdGjhuqV5IG5ow7NtIEtow6FjIGPDsyB4dSBoxrDhu5tuZyBy4budaSBi4buPIGThu4tjaCB24bulIGNhbyBoxqFuIHNvIHbhu5tpIG5ow7NtIE9uZSB5ZWFyLg0KDQoNCiMjIyAqKjMuMi42IE3DtCBow6xuaCBo4buTaSBxdXkgY2hvIGThu68gbGnhu4d1IG5o4buLIHBow6JuKioNCg0KIyMjIyAqKjMuMi42LjEgTcO0IGjDrG5oIGxvZ2l0KioNCg0KxJDhu4MgcGjDom4gdMOtY2ggbeG7kWkgcXVhbiBo4buHIGdp4buvYSBsb+G6oWkgaOG7o3AgxJHhu5NuZyBDb250cmFjdDIgdsOgIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIENodXJuLCB0w6FjIGdp4bqjIHPhu60gZOG7pW5nIG3DtCBow6xuaCBo4buTaSBxdXkgbG9naXN0aWMgbmjhu4sgcGjDom4gKGxvZ2l0IG1vZGVsKS4gTcO0IGjDrG5oIG7DoHkgY2hvIHBow6lwIMaw4bubYyBsxrDhu6NuZyB4w6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIHRow7RuZyBxdWEgaMOgbSBsb2dpdCwgZ2nDunAgeMOhYyDEkeG7i25oIG3hu6ljIMSR4buZIOG6o25oIGjGsOG7n25nIGPhu6dhIHThu6tuZyBsb+G6oWkgaOG7o3AgxJHhu5NuZyDEkeG6v24gaMOgbmggdmkgcuG7nWkgYuG7jyBj4bunYSBraMOhY2ggaMOgbmcuIA0KDQpgYGB7cn0NCmxvZzEgPC0gZ2xtKGZhY3RvcihDaHVybikgfiBDb250cmFjdDIsIGRhdGEgPSB2aWVudGhvbmcsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkNCnN1bW1hcnkobG9nMSkNCmBgYA0KDQpUYSBjw7MgbcO0IGjDrG5oIGjhu5NpIHF1eSBuaMawIHNhdToNCg0KJCQNClxsb2dcbGVmdCggXGZyYWN7UChcdGV4dHtDaHVybn0gPSBcdGV4dHsiWWVzIn0pfXsxIC0gUChcdGV4dHtDaHVybn0gPSBcdGV4dHsiWWVzIn0pfSBccmlnaHQpID0gLTEuNzQ3NjggKyAxLjIyODU3ICBcY2RvdCBcdGV4dHtDb250cmFjdDJLaMOhY30NCiQkDQoNCi0gXChcYmV0YV8wID0gLTEuNzQ3NjhcKTogxJDDonkgbMOgIGxvZy1vZGRzIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIOKAnE9uZSB5ZWFy4oCdIChraGkgQ29udHJhY3QyS2jDoWMgPSAwKS4gS2hpIGNodXnhu4NuIHNhbmcgZOG6oW5nIG9kZHMsIFwoZV57LTEuNzQ3Njh9IFxhcHByb3ggMC4xNzRcKSwgdMawxqFuZyDhu6luZyB24bubaSB4w6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIGtob+G6o25nIDE3LjQlLCBjaG8gdGjhuqV5IG5ow7NtIG7DoHkgY8OzIG3hu6ljIMSR4buZIGfhuq9uIGLDsyBjYW8uIA0KDQotIFwoXGJldGFfMSA9IDEuMjI4NTdcKTogxJDDonkgbMOgIG3hu6ljIHRoYXkgxJHhu5VpIGxvZy1vZGRzIGtoaSBraMOhY2ggaMOgbmcgdGh14buZYyBuaMOzbSDigJxLaMOhY+KAnSBzbyB24bubaSDigJxPbmUgeWVhcuKAnS4gVsOsIFwoXGJldGFfMSA+IDBcKSwga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0xINuZyBsw6puLiBHacOhIHRy4buLIFwoZV57MS4yMjg1N30gXGFwcHJveCAzLjQyXCkgY2hvIHRo4bqleSBvZGRzIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2EgbmjDs20g4oCcS2jDoWPigJ0gY2FvIGfhuqVwIDMsNDIgbOG6p24gc28gduG7m2kgbmjDs20g4oCcT25lIHllYXLigJ0uDQoNCsSQaeG7gXUgbsOgeSBraOG6s25nIMSR4buLbmggcuG6sW5nIGtow6FjaCBow6BuZyB24bubaSBo4bujcCDEkeG7k25nIGtow7RuZyBwaOG6o2kg4oCcT25lIHllYXLigJ0gZOG7hSBy4budaSBi4buPIGThu4tjaCB24bulIGjGoW4gdsOgIGRvYW5oIG5naGnhu4dwIGPhuqduIHThuq1wIHRydW5nIHbDoG8gbmjDs20gbsOgeSDEkeG7gyBnaeG6o20gdOG7tyBs4buHIHLhu51pIGLhu48uDQoNCiMjIyMgKiozLjIuNi4yIE3DtCBow6xuaCBwcm9iaXQqKg0KDQpCw6puIGPhuqFuaCBtw7QgaMOsbmggbG9naXQsIHTDoWMgZ2nhuqMgY8OybiBz4butIGThu6VuZyBtw7QgaMOsbmggcHJvYml0IG5o4bqxbSBzbyBzw6FuaCBr4bq/dCBxdeG6oyB2w6Aga2nhu4NtIHRyYSB0w61uaCDhu5VuIMSR4buLbmggY+G7p2EgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBiaeG6v24gbG/huqFpIGjhu6NwIMSR4buTbmcgQ29udHJhY3QyIHbDoCBraOG6oyBuxINuZyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBDaHVybi4gTcO0IGjDrG5oIHByb2JpdCBz4butIGThu6VuZyBow6BtIGxpw6puIGvhur90IGNodeG6qW4gdMOtY2ggbMWpeSB0aGF5IHbDrCBow6BtIGxvZ2l0LCBuaMawbmcgduG6q24gbWFuZyDDvSBuZ2jEqWEgdMawxqFuZyB04buxIHRyb25nIHZp4buHYyDGsOG7m2MgbMaw4bujbmcgeMOhYyBzdeG6pXQgcuG7nWkgYuG7jy4gDQoNCmBgYHtyfQ0KcHJvMSA8LSBnbG0oZmFjdG9yKENodXJuKSB+IENvbnRyYWN0MiwgZGF0YSA9IHZpZW50aG9uZywgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdwcm9iaXQnKSkNCnN1bW1hcnkocHJvMSApDQpgYGANCg0KVGEgY8OzIG3DtCBow6xuaCBo4buTaSBxdXkgbmjGsCBzYXU6DQoNCiQkDQpQKFk9MXxDb250cmFjdDIpID0gXFBoaSgtMS4wNDM1OCArIDAuNzE5ODJDb250cmFjdDJLaMOhYykNCiQkDQp0cm9uZyDEkcOzIFwoXFBoaShcY2RvdClcKSBsw6AgaMOgbSBwaMOibiBwaOG7kWkgdMOtY2ggbMWpeSBjaHXhuqluIGNodeG6qW4gaMOzYS4NCg0KLSBW4bubaSBDb250cmFjdDIgPSBPbmUgeWVhciAoXChDb250cmFjdDJLaMOhYyA9IDBcKSk6IFxbUChZPTEgfCBPbmVcIHllYXIpID0gXFBoaSgtMS4wNDM1OCkgXGFwcHJveCAwLjE0OSBcICgxNC45XCUpLlxdDQoNCi0gVuG7m2kgQ29udHJhY3QyID0gS2jDoWMgKFwoQ29udHJhY3QyS2jDoWMgPSAxXCkpOiBcWyBQKFk9MSB8IEtow6FjKSA9IFxQaGkoLTEuMDQzNTggKyAwLjcxOTgyKSA9IFxQaGkoLTAuMzIzNzYpIFxhcHByb3ggMC4zNzMgXCAoMzcuM1wlKS5cXQ0KDQpL4bq/dCBxdeG6oyDGsOG7m2MgbMaw4bujbmcgY2hvIHRo4bqleSBiaeG6v24gQ29udHJhY3QyIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ogcuG6pXQgY2FvIHbhu5tpIFwocCA8IDJlLTE2XCksIGNo4bupbmcgdOG7jyBsb+G6oWkgaOG7o3AgxJHhu5NuZyDhuqNuaCBoxrDhu59uZyBt4bqhbmggxJHhur9uIGto4bqjIG7Eg25nIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulLiBLaGkga2jDoWNoIGjDoG5nIHPhu60gZOG7pW5nIGjhu6NwIMSR4buTbmcgT25lIHllYXIsIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY2jhu4kg4bufIG3hu6ljIDE0LjklLCB0cm9uZyBraGkgduG7m2kgaOG7o3AgxJHhu5NuZyBLaMOhYywgeMOhYyBzdeG6pXQgbsOgeSB0xINuZyBsw6puIDM3LjMlLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSBraMOhY2ggaMOgbmcgc+G7rSBk4bulbmcgaOG7o3AgxJHhu5NuZyAiS2jDoWMiIGPDsyBuZ3V5IGPGoSBy4budaSBi4buPIGThu4tjaCB24bulIGNhbyBn4bqlcCBraG/huqNuZyAyLDUgbOG6p24gc28gduG7m2kgbmjDs20gT25lIHllYXIuICANCg0KIyMjIyAqKjMuMi42LjMgTcO0IGjDrG5oIGNsb2dsb2cqKg0KDQpOZ2/DoGkgbG9naXQgdsOgIHByb2JpdCwgdMOhYyBnaeG6oyBjw7JuIHPhu60gZOG7pW5nIG3DtCBow6xuaCBo4buTaSBxdXkgQ29tcGxlbWVudGFyeSBMb2ctTG9nIChjbG9nbG9nKSDEkeG7gyBwaMOibiB0w61jaCBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGxv4bqhaSBo4bujcCDEkeG7k25nIENvbnRyYWN0MiB2w6Aga2jhuqMgbsSDbmcga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgQ2h1cm4uIE3DtCBow6xuaCBjbG9nbG9nIHRoxrDhu51uZyDEkcaw4bujYyDDoXAgZOG7pW5nIHRyb25nIHRyxrDhu51uZyBo4bujcCB4w6FjIHN14bqldCB44bqjeSByYSBz4buxIGtp4buHbiBy4bqldCBuaOG7jyBob+G6t2MgcuG6pXQgbOG7m24sIG5o4budIGto4bqjIG7Eg25nIHjhu60gbMO9IHBow6JuIHBo4buRaSBi4bqldCDEkeG7kWkgeOG7qW5nIHThu5F0IGjGoW4gc28gduG7m2kgbG9naXQgaG/hurdjIHByb2JpdC4gTeG7pWMgdGnDqnUgY+G7p2Egdmnhu4djIHPhu60gZOG7pW5nIGNsb2dsb2cgbMOgIHNvIHPDoW5oIHbDoCDEkcOhbmggZ2nDoSB0w61uaCDhu5VuIMSR4buLbmggY+G7p2Ega+G6v3QgcXXhuqMgxrDhu5tjIGzGsOG7o25nIGdp4buvYSBjw6FjIG3DtCBow6xuaCBsacOqbiBr4bq/dCBraMOhYyBuaGF1LiANCg0KYGBge3J9DQpjbG8xIDwtIGdsbShmYWN0b3IoQ2h1cm4pIH4gQ29udHJhY3QyLCBkYXRhID0gdmllbnRob25nLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gJ2Nsb2dsb2cnKSkNCnN1bW1hcnkoY2xvMSkNCmBgYA0KDQpUYSBjw7MgbcO0IGjDrG5oIGjhu5NpIHF1eSBuaMawIHNhdToNCg0KJCQNClxsb2cgXGxlZnQoIC1cbG9nIFxsZWZ0KCAxIC0gUChcbWF0aHJte0NodXJufSA9IFxtYXRocm17WWVzfSkgXHJpZ2h0KSBccmlnaHQpDQo9IC0xLjgyOTA0ICsgMS4wNjc0MSBcY2RvdCBcbWF0aHJte0NvbnRyYWN0MktoYWN9DQokJA0KDQpL4bq/dCBxdeG6oyBj4bunYSBtw7QgaMOsbmggY2xvZ2xvZyBjaG8gdGjhuqV5IGjhu4cgc+G7kSBjaOG6t24g4oiSMS44MjkwNCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLCB0xrDGoW5nIOG7qW5nIHbhu5tpIHjDoWMgc3XhuqV0IGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIGtob+G6o25nIDE0LjglIGtoaSBo4buNIHPhu60gZOG7pW5nIGjhu6NwIMSR4buTbmcgT25lIHllYXIuIA0KDQokJA0KcF97XHRleHR7T25lWWVhcn19ID0gMSAtIFxleHAgXGxlZnQoIC1cZXhwKC0xLjgyOTA0KSBccmlnaHQpIFxhcHByb3ggMC4xNDggXCwgKDE0LjhcJSkNCiQkDQoNClRyb25nIGtoaSDEkcOzLCBo4buHIHPhu5EgQ29udHJhY3QyS2jDoWMgPSAxLjA2NzQxIChwIDwgMC4wMDEpIGNobyB0aOG6pXkga2jDoWNoIGjDoG5nIHRodeG7mWMgbmjDs20gaOG7o3AgxJHhu5NuZyBLaMOhYyBjw7MgeMOhYyBzdeG6pXQgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBjYW8gaMahbiByw7UgcuG7h3QsIGzDqm4gxJHhur9uIDM3LjMlLiANCg0KJCQNClxldGEgPSAtMS44MjkwNCArIDEuMDY3NDEgPSAtMC43NjE2MywNCiQkDQoNCnbDoCB4w6FjIHN14bqldDoNCg0KJCQNCnBfe1x0ZXh0e0toYWN9fSA9IDEgLSBcZXhwXGxlZnQoIC1cZXhwKC0wLjc2MTYzKSBccmlnaHQpIFxhcHByb3ggMC4zNzMgXCwgKDM3LjNcJSkuDQokJA0KTmjGsCB24bqteSwgdmnhu4djIHRoYXkgxJHhu5VpIGxv4bqhaSBo4bujcCDEkeG7k25nIHThu6sgT25lIHllYXIgc2FuZyBLaMOhYyBsw6BtIHTEg25nIMSRw6FuZyBr4buDIG5ndXkgY8ahIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulLg0KDQojIyMgKiozLjIuNyDEkMOhbmggZ2nDoSBtw7QgaMOsbmgqKg0KDQpTYXUga2hpIHRp4bq/biBow6BuaCDGsOG7m2MgbMaw4bujbmcgYmEgbcO0IGjDrG5oIGjhu5NpIHF1eSBuaOG7iyBwaMOibiBn4buTbSBsb2dpdCwgcHJvYml0IHbDoCBjbG9nbG9nLCBixrDhu5tjIHRp4bq/cCB0aGVvIGzDoCDEkcOhbmggZ2nDoSB2w6Agc28gc8OhbmggbeG7qWMgxJHhu5kgcGjDuSBo4bujcCBj4bunYSBjw6FjIG3DtCBow6xuaCBuw6B5LiBWaeG7h2MgxJHDoW5oIGdpw6EgxJHGsOG7o2MgdGjhu7FjIGhp4buHbiBk4buxYSB0csOqbiBjw6FjIGNo4buJIHRpw6p1IHRo4buRbmcga8OqIG5oxrAgZ2nDoSB0cuG7iyBBSUMsIGjhu4cgc+G7kSBCcmllciBTY29yZSB2w6AgbWEgdHLhuq1uIG5o4bqnbSBs4bqrbi4gTmdvw6BpIHJhLCBraOG6oyBuxINuZyBk4buxIGLDoW8geMOhYyBzdeG6pXQgY+G7p2EgdOG7q25nIG3DtCBow6xuaCDEkeG7kWkgduG7m2kgY8OhYyB0csaw4budbmcgaOG7o3AgZ2nhuqMgxJHhu4tuaCBj4bulIHRo4buDIGPFqW5nIMSRxrDhu6NjIHhlbSB4w6l0IMSR4buDIGzhu7FhIGNo4buNbiBtw7QgaMOsbmggcGjDuSBo4bujcCBuaOG6pXQuDQoNCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgc28gc8OhbmgNCm1vZGVsX2V2YWwgPC0gZGF0YS5mcmFtZSgNCiAgTcO0X2jDrG5oID0gYygiTG9naXQiLCAiUHJvYml0IiwgIkNsb2dsb2ciKSwNCiAgQUlDID0gYyhBSUMobG9nMSksIEFJQyhwcm8xKSwgQUlDKGNsbzEpKSwNCiAgQklDID0gYyhCSUMobG9nMSksIEJJQyhwcm8xKSwgQklDKGNsbzEpKSwNCiAgQnJpZXJfU2NvcmUgPSBjKEJyaWVyU2NvcmUobG9nMSksIEJyaWVyU2NvcmUocHJvMSksIEJyaWVyU2NvcmUoY2xvMSkpDQopDQprYWJsZShtb2RlbF9ldmFsLCBhbGlnbiA9ICJjIiwgY2FwdGlvbiA9ICJTbyBzw6FuaCBjw6FjIGNo4buJIHPhu5EgxJHDoW5oIGdpw6EgbcO0IGjDrG5oIikgJT4lDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJjZW50ZXIiLCBmb250X3NpemUgPSAxNCkNCmBgYA0KDQoNCkPDoWMga+G6v3QgcXXhuqMgQUlDLCBCSUMgdsOgIEJyaWVyIFNjb3JlIGNobyB0aOG6pXkgYmEgbcO0IGjDrG5oIGxvZ2l0LCBwcm9iaXQgdsOgIGNsb2dsb2cgxJHhu4F1IGPDsyBt4bupYyDEkeG7mSBwaMO5IGjhu6NwIHTGsMahbmcgxJHGsMahbmcsIHbhu5tpIEFJQyA9IDU5MjMuNTQsIEJJQyA9IDU5MzYuNTA2IHbDoCBCcmllciBTY29yZSA9IDAuMjEyNC4gR2nDoSB0cuG7iyBBSUMgdsOgIEJJQyBuZ2FuZyBuaGF1IGNo4bupbmcgdOG7jyBraMO0bmcgY8OzIG3DtCBow6xuaCBuw6BvIHbGsOG7o3QgdHLhu5lpIHbhu4Ega2jhuqMgbsSDbmcgZ2nhuqNpIHRow61jaCBk4buvIGxp4buHdSBob+G6t2MgxJHhu5kgcGjhu6ljIHThuqFwLiDEkOG7k25nIHRo4budaSwgQnJpZXIgU2NvcmUgcGjhuqNuIMOhbmgga2jhuqMgbsSDbmcgZOG7sSDEkW/DoW4geMOhYyBzdeG6pXQgY+G7p2EgY+G6oyBiYSBtw7QgaMOsbmggxJHhu4F1IHThu5F0IHbDoCB0xrDGoW5nIMSRxrDGoW5nIG5oYXUuIA0KDQoqKk1hIHRy4bqtbiBuaOG6p20gbOG6q24qKg0KDQotIE3DtCBow6xuaCBsb2dpdA0KDQpgYGB7cn0NCnByZWRfbG9naXRsb2cgPC0gaWZlbHNlKHByZWRpY3QobG9nMSwgdHlwZSA9ICJyZXNwb25zZSIpID49IDAuNSwgIlllcyIsICJObyIpDQphY3R1YWxsb2cgPC0gdmllbnRob25nJENodXJuDQpjbV9sb2dpdGxvZyA8LSBjb25mdXNpb25NYXRyaXgoZmFjdG9yKHByZWRfbG9naXRsb2cpLCBhY3R1YWxsb2csIHBvc2l0aXZlID0gIlllcyIpDQpjbV9sb2dpdGxvZw0KYGBgDQotIE3DtCBow6xuaCBwcm9iaXQNCg0KYGBge3J9DQpwcmVkX2xvZ2l0cHJvIDwtIGlmZWxzZShwcmVkaWN0KHBybzEsIHR5cGUgPSAicmVzcG9uc2UiKSA+PSAwLjUsICJZZXMiLCAiTm8iKQ0KYWN0dWFscHJvIDwtIHZpZW50aG9uZyRDaHVybg0KY21fbG9naXRwcm8gPC0gY29uZnVzaW9uTWF0cml4KGZhY3RvcihwcmVkX2xvZ2l0cHJvKSwgYWN0dWFscHJvLCBwb3NpdGl2ZSA9ICJZZXMiKQ0KY21fbG9naXRwcm8NCmBgYA0KDQotIE3DtCBow6xuaCBjbG9nbG9nDQoNCmBgYHtyfQ0KcHJlZF9sb2dpdGNsbyA8LSBpZmVsc2UocHJlZGljdChjbG8xLCB0eXBlID0gInJlc3BvbnNlIikgPj0gMC41LCAiWWVzIiwgIk5vIikNCmFjdHVhbGNsbyA8LSB2aWVudGhvbmckQ2h1cm4NCmNtX2xvZ2l0Y2xvIDwtIGNvbmZ1c2lvbk1hdHJpeChmYWN0b3IocHJlZF9sb2dpdGNsbyksIGFjdHVhbGNsbywgcG9zaXRpdmUgPSAiWWVzIikNCmNtX2xvZ2l0Y2xvDQpgYGANCg0KROG7sWEgdsOgbyBtYSB0cuG6rW4gbmjhuqdtIGzhuqtuIGPhu6dhIDMgbcO0IGjDrG5oIChsb2dpdCwgcHJvYml0LCBjbG9nbG9nKSB2w6AgaMOsbmggbWluaCBo4buNYSwgdGEgY8OzIHRo4buDIGNoaSB0aeG6v3QgbmjGsCBzYXU6DQoNCi0gVFAgKFRydWUgUG9zaXRpdmUgPSAwKTogS2jDtG5nIGPDsyB0csaw4budbmcgaOG7o3AgbsOgbyBraMOhY2ggaMOgbmcgdGjhu7FjIHThur8gcuG7nWkgYuG7jyBk4buLY2ggduG7pSBZZXMgbcOgIG3DtCBow6xuaCBk4buxIMSRb8OhbiDEkcO6bmcgbMOgIFllcy4NCg0KLSBUTiAoVHJ1ZSBOZWdhdGl2ZSA9IDMyNDYpOiBDw7MgMzI0NiB0csaw4budbmcgaOG7o3Aga2jDoWNoIGjDoG5nIGtow7RuZyBy4budaSBi4buPIGThu4tjaCB24bulIE5vIHbDoCBtw7QgaMOsbmggY8WpbmcgZOG7sSDEkW/DoW4gxJHDum5nIGzDoCBOby4NCg0KLSBGUCAoRmFsc2UgUG9zaXRpdmUgPSAwKTogS2jDtG5nIGPDsyB0csaw4budbmcgaOG7o3AgbsOgbyBtw7QgaMOsbmggZOG7sSDEkW/DoW4gWWVzIG5oxrBuZyB0aOG7sWMgdOG6vyBraMOhY2ggaMOgbmcgbOG6oWkg4bufIG5ow7NtIE5vLg0KDQotIEZOIChGYWxzZSBOZWdhdGl2ZSA9IDE1ODYpOiBDw7MgMTU4NiBraMOhY2ggaMOgbmcgdGjhu7FjIHThur8gcuG7nWkgYuG7jyBk4buLY2ggduG7pSBZZXMgbmjGsG5nIG3DtCBow6xuaCBs4bqhaSBk4buxIMSRb8OhbiBsw6AgTm8uDQoNCkvhur90IHF14bqjIG1hIHRy4bqtbiBuaOG6p20gbOG6q24gY2hvIHRo4bqleSBj4bqjIGJhIG3DtCBow6xuaCBsb2dpdCwgcHJvYml0IHbDoCBjbG9nbG9nIMSR4buBdSBk4buxIMSRb8OhbiB0b8OgbiBi4buZIGtow6FjaCBow6BuZyBsw6Ag4oCcTm/igJ0gKGtow7RuZyBy4budaSBi4buPIGThu4tjaCB24bulKSwgZOG6q24gxJHhur9uIHPhu5EgbMaw4bujbmcgVHJ1ZSBQb3NpdGl2ZSAoVFApIHbDoCBGYWxzZSBQb3NpdGl2ZSAoRlApIMSR4buBdSBi4bqxbmcgMC4gxJBp4buBdSBuw6B5IGtoaeG6v24gxJHhu5kgbmjhuqF5IChTZW5zaXRpdml0eSkgYuG6sW5nIDAlLCBuZ2jEqWEgbMOgIG3DtCBow6xuaCBob8OgbiB0b8OgbiBraMO0bmcgcGjDoXQgaGnhu4duIMSRxrDhu6NjIGtow6FjaCBow6BuZyBuw6BvIHLhu51pIGLhu48gZOG7i2NoIHbhu6UuIE3hurdjIGTDuSDEkeG7mSBjaMOtbmggeMOhYyAoQWNjdXJhY3kpIMSR4bqhdCA2NywxOCUsIG5oxrBuZyBjb24gc+G7kSBuw6B5IGNo4buJIHBo4bqjbiDDoW5oIHThu7cgbOG7hyBraMOhY2ggaMOgbmcg4oCcTm/igJ0gdHJvbmcgdOG6rXAgZOG7ryBsaeG7h3UsIGtow7RuZyB0aOG7gyBoaeG7h24gbsSDbmcgbOG7sWMgcGjDom4gbG/huqFpIMSRw7puZyBuaMOzbSDigJxZZXPigJ0uIE5ndXnDqm4gbmjDom4gY8OzIHRo4buDIGRvIG5nxrDhu6FuZyBk4buxIMSRb8OhbiAwLjUgY2jGsGEgcGjDuSBo4bujcCBob+G6t2MgZOG7ryBsaeG7h3UgbeG6pXQgY8OibiBi4bqxbmcga2hpIG5ow7NtIOKAnE5v4oCdIGNoaeG6v20gxJFhIHPhu5EuIA0KDQoNCiMjICoqMy4zIFBow6JuIHTDrWNoIHPhu7EgdMOhYyDEkeG7mW5nIGPhu6dhIGxv4bqhaSBow6xuaCBk4buLY2ggduG7pSBJbnRlcm5ldCDEkWFuZyBz4butIGThu6VuZyDEkeG6v24gdmnhu4djIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulKiogDQoNCiMjIyAqKjMuMy4xIFRo4buRbmcga8OqIG3DtCB04bqjIGJp4bq/biBsb+G6oWkgaMOsbmggZOG7i2NoIHbhu6UgSW50ZXJuZXQgxJFhbmcgc+G7rSBk4bulbmcqKg0KDQrEkOG7gyBoaeG7g3UgcsO1IGjGoW4gduG7gSDEkeG6t2MgxJFp4buDbSBraMOhY2ggaMOgbmcgdHJvbmcgYuG7mSBk4buvIGxp4buHdSwgdHLGsOG7m2MgdGnDqm4gY+G6p24gcGjDom4gdMOtY2ggbG/huqFpIGjDrG5oIGThu4tjaCB24bulIEludGVybmV0IG3DoCBo4buNIMSRYW5nIHPhu60gZOG7pW5nLiBCaeG6v24gSW50ZXJuZXRTZXJ2aWNlIHBo4bqjbiDDoW5oIGPDoWMgZ8OzaSBk4buLY2ggduG7pSBjaMOtbmggbmjGsCBEU0wgdsOgIEZpYmVyIG9wdGljLCB04burIMSRw7MgZ2nDunAgxJHDoW5oIGdpw6EgeHUgaMaw4bubbmcgbOG7sWEgY2jhu41uIGThu4tjaCB24bulIGPhu6dhIGtow6FjaCBow6BuZy4NCg0KYGBge3J9DQplPC10YWJsZSh2aWVudGhvbmckSW50ZXJuZXRTZXJ2aWNlKSANCg0KIyBDaHV54buDbiB0aMOgbmggZGF0YSBmcmFtZSB24bubaSAzIGPhu5l0OiBDaHVybiB8IFPhu5EgbMaw4bujbmcgfCBTdW0gKFThu5VuZyBj4buZbmcpDQpkZmkgPC0gZGF0YS5mcmFtZSgNCiAgIEludGVybmV0U2VydmljZT0gYygiRFNMIiwgIkZpYmVyIG9wdGljICIpLA0KICBTb19sdW9uZyA9IGFzLm51bWVyaWMoZSkNCikNCg0KIyBJbiByYSBi4bqjbmcgxJHhurlwLCBjxINuIGdp4buvYQ0Ka2FibGUoZGZpLCBhbGlnbiA9ICJjIiwgY29sLm5hbWVzID0gYygiSW50ZXJuZXRTZXJ2aWNlIiwgIlPhu5EgbMaw4bujbmciKSkgICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAiY2VudGVyIiwgZm9udF9zaXplID0gMTQpICU+JQ0KICBjb2x1bW5fc3BlYygxLCB3aWR0aCA9ICI0Y20iKSAlPiUgICMgxJDhu5kgcuG7mW5nIGPhu5l0IDENCiAgY29sdW1uX3NwZWMoMiwgd2lkdGggPSAiM2NtIikgICAgICAjIMSQ4buZIHLhu5luZyBj4buZdCAyDQoNCiNs4bqtcCBi4bqjbmcgdOG6p24gc+G7kSBj4bunYSBj4buZdCBDaHVybiB0cm9uZyBi4buZIGThu68gbGnhu4d1IMSRxrDhu6NjIHTDqm4gdmllbnRob25nIHbDoCB0aMOqbSBj4buZdCB0w7RuZyB2w6BvIGN14buRaSBi4bqjbmcNCmBgYA0KDQrEkOG7gyBtaW5oIGjhu41hIHRy4buxYyBxdWFuIGxv4bqhaSBk4buLY2ggduG7pSBpbnRlcm5ldCwgdMO0aSB0aeG6v24gaMOgbmggduG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgdOG7q25nIGdpw6EgdHLhu4sgY+G7p2EgbmjDs20gSW50ZXJuZXRTZXJ2aWNlLg0KDQpgYGB7cn0NCiMgVOG6oW8gYuG6o25nIHThuqduIHPhu5EgY2hvIGJp4bq/biB0eXBlDQppIDwtIGFzLmRhdGEuZnJhbWUodGFibGUodmllbnRob25nJEludGVybmV0U2VydmljZSkgKQ0KY29sbmFtZXMoaSkgPC0gYygiSW50ZXJuZXRTZXJ2aWNlIiwgIkNvdW50IikNCg0KZ2dwbG90KGksIGFlcyh4ID0gSW50ZXJuZXRTZXJ2aWNlLCB5ID0gQ291bnQsIGZpbGwgPSBJbnRlcm5ldFNlcnZpY2UpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuNSkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjUsIHNpemUgPSAzLjUpICsgIyBIaeG7g24gdGjhu4sgc+G7kSBsaeG7h3UgYsOqbiB0csOqbiBj4buZdA0KICBsYWJzKHRpdGxlID0gIsSQ4buTIHRo4buLIGPDoWMgbG/huqFpIGjDrG5oIGThu4tjaCB24bulIEludGVybmV0U2VydmljZSIsIHggPSAiSW50ZXJuZXRTZXJ2aWNlIiwgeSA9ICJGcmVxdWVuY3kiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCkvhur90IHF14bqjIHRo4buRbmcga8OqIGNobyB0aOG6pXkgZOG7i2NoIHbhu6UgRmliZXIgb3B0aWMgxJHGsOG7o2Mgc+G7rSBk4bulbmcgbmhp4buBdSBoxqFuIHNvIHbhu5tpIERTTC4gQ+G7pSB0aOG7gywgY8OzIDMwOTYga2jDoWNoIGjDoG5nIHPhu60gZOG7pW5nIEZpYmVyIG9wdGljLCB0cm9uZyBraGkgRFNMIGNo4buJIGPDsyAxNzM2IGtow6FjaCBow6BuZy4gQmnhu4N1IMSR4buTIGPhu5l0IG1pbmggaOG7jWEgc+G7sSBjaMOqbmggbOG7h2NoIHLDtSBy4buHdCwga2hpIHPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIEZpYmVyIG9wdGljIGfhuqduIGfhuqVwIMSRw7RpIERTTC4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgRmliZXIgb3B0aWMgxJFhbmcgbMOgIGzhu7FhIGNo4buNbiBwaOG7lSBiaeG6v24gaMahbi4NCg0KTmdvw6BpIHJhIHTDoWMgZ2nhuqMgc+G6vSB0aOG7sWMgaGnhu4duIHTDrW5oIHThu7cgbOG7hyBwaOG6p24gdHLEg20gY2hvIHThu6tuZyBuaMOzbSB2w6AgduG6vSDEkeG7kyB0aOG7iyBj4buZdCBj4bunYSBjaMO6bmcgxJHhu4Mgc28gc8OhbmggdGhlbyBz4buRIGxp4buHdSB0xrDGoW5nIMSR4buRaS4NCg0KYGBge3J9DQojIFRow6ptIGPhu5l0IHBo4bqnbiB0csSDbQ0KaSRQZXJjZW50YWdlIDwtIHJvdW5kKHByb3AudGFibGUodGFibGUodmllbnRob25nJEludGVybmV0U2VydmljZSkpICogMTAwLCAyKQ0KIyBC4bqiTkcgUEjhuqZOIFRSxIJNDQprYWJsZShpLCBhbGlnbiA9ICJjIiwgY29sLm5hbWVzID0gYygiQ2h1cm4iLCAiU+G7kSBsxrDhu6NuZyIsICJQaOG6p24gdHLEg20gKCUpIikpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAiY2VudGVyIiwgZm9udF9zaXplID0gMTQpICU+JQ0KICBjb2x1bW5fc3BlYygxLCB3aWR0aCA9ICI0Y20iKSAlPiUNCiAgY29sdW1uX3NwZWMoMiwgd2lkdGggPSAiM2NtIikgJT4lDQogIGNvbHVtbl9zcGVjKDMsIHdpZHRoID0gIjRjbSIpDQoNCmBgYA0KDQpgYGB7cn0NCg0KZ2dwbG90KGksIGFlcyh4ID0gIiIsIHkgPSBQZXJjZW50YWdlLCBmaWxsID0gSW50ZXJuZXRTZXJ2aWNlKSkgKw0KICBnZW9tX2Jhcih3aWR0aCA9IDEsIHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGNvb3JkX3BvbGFyKCJ5IikgKw0KICBsYWJzKHRpdGxlID0gIlThu7cgbOG7hyBwaOG6p24gdHLEg20iLCB4ID0gIiIsIHkgPSAiIikgKw0KICB0aGVtZV92b2lkKCkgKyANCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArIA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUocm91bmQoUGVyY2VudGFnZSwgMiksICIlIikpLCANCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBzaXplID0gNCkNCmBgYA0KDQpCaeG7g3UgxJHhu5MgdHLDsm4gY2hvIHRo4bqleSBk4buLY2ggduG7pSBGaWJlciBvcHRpYyBjaGnhur9tIHThu7cgbOG7hyBjYW8gbmjhuqV0IHbhu5tpIDY0LjA3JSB04buVbmcgc+G7kSBraMOhY2ggaMOgbmcsIHRyb25nIGtoaSBk4buLY2ggduG7pSBEU0wgY2hp4bq/bSAzNS45MyUuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IGtow6FjaCBow6BuZyBjw7MgeHUgaMaw4bubbmcgxrBhIGNodeG7mW5nIEZpYmVyIG9wdGljIGjGoW4sIGfhuqduIGfhuqVwIMSRw7RpIHNvIHbhu5tpIERTTC4gU+G7sSBjaMOqbmggbOG7h2NoIG7DoHkgY8OzIHRo4buDIHh14bqldCBwaMOhdCB04burIMawdSDEkWnhu4NtIHbhu4EgdOG7kWMgxJHhu5kgdHJ1eeG7gW4gdOG6o2kgdsOgIGNo4bqldCBsxrDhu6NuZyBr4bq/dCBu4buRaSBj4bunYSBGaWJlciBvcHRpYy4gDQoNCiMjIyAqKjMuMy4yIFRo4buRbmcga8OqIG3DtCB04bqjIGNobyBoYWkgYmnhur9uIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIHbDoCBjw6FjIGxv4bqhaSBow6xuaCBk4buLY2ggduG7pSBJbnRlcm5ldCoqDQoNClBo4bqnbiBuw6B5IG5o4bqxbSBtw7QgdOG6oyB04buVbmcgcXVhbiB24buBIHTDrG5oIHRy4bqhbmcga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKENodXJuKSB2w6AgbG/huqFpIGjDrG5oIGThu4tjaCB24bulIEludGVybmV0IChJbnRlcm5ldFNlcnZpY2UpIG3DoCBo4buNIMSRYW5nIHPhu60gZOG7pW5nLiBWaeG7h2MgdGjhu5FuZyBrw6ogaGFpIGJp4bq/biBuw6B5IGdpw7pwIG5o4bqtbiBkaeG7h24gxJHGsOG7o2MgeHUgaMaw4bubbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0aGVvIHThu6tuZyBsb+G6oWkgaMOsbmggSW50ZXJuZXQsIHThu6sgxJHDsyBsw6BtIGPGoSBz4bufIGNobyBjw6FjIHBow6JuIHTDrWNoIHRp4bq/cCB0aGVvLg0KDQpgYGB7cn0NCnRhYmxlKHZpZW50aG9uZyRJbnRlcm5ldFNlcnZpY2UsIHZpZW50aG9uZyRDaHVybikgJT4lICBhZGRtYXJnaW5zKCkNCmBgYA0KDQpW4bq9IMSR4buTIHRo4buLIGPhu5l0IHBow6JuIHRoZW8gdOG7q25nIGxv4bqhaSBk4buLY2ggduG7pSBpbnRlcm5ldCDEkeG7gyDEkcOhbmggZ2nDoSBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIHZp4buFbiB0aMO0bmcgdHJvbmcgdOG7q25nIG5ow7NtLg0KDQpgYGB7cn0NCnRhYmxlX2RhdGEgPC0gdGFibGUodmllbnRob25nJEludGVybmV0U2VydmljZSwgdmllbnRob25nJENodXJuKQ0KDQojIENodXnhu4NuIGLhuqNuZyBjaMOpbyBzYW5nIMSR4buLbmggZOG6oW5nIGTDoGkNCmxvbmdfZGF0YTIgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZV9kYXRhKQ0KY29sbmFtZXMobG9uZ19kYXRhMikgPC0gYygiSW50ZXJuZXRTZXJ2aWNlIiwgIkNodXJuIiwgImNvdW50IikNCg0KIyBW4bq9IGJp4buDdSDEkeG7kyBj4buZdA0KZ2dwbG90KGxvbmdfZGF0YTIsIGFlcyh4ID0gQ2h1cm4sIHkgPSBjb3VudCwgZmlsbCA9IENodXJuKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgpKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb3VudCksIHZqdXN0ID0gMSwgc2l6ZSA9IDIuNSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgxKSkgKw0KICBmYWNldF93cmFwKH4gSW50ZXJuZXRTZXJ2aWNlLCBzY2FsZXMgPSAiZnJlZV95IiwgbnJvdyA9IDIpICsNCiAgbGFicyh0aXRsZSA9ICJQaMOibiBi4buRIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIHRoZW8gY8OhYyBsb+G6oWkgaMOsbmggZOG7i2NoIHbhu6UgSW50ZXJuZXQiLA0KICAgICAgIHggPSAiS2jDoWNoIGjDoG5nIHLhu51pIGLhu48gaOG7o3AgxJHhu5NuZyIsDQogICAgICAgeSA9ICJDw6FjIGxv4bqhaSBow6xuaCBk4buLY2ggduG7pSBJbnRlcm5ldCIsDQogICAgICAgZmlsbCA9ICJLaMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBo4bujcCDEkeG7k25nIikgKw0KICB0aGVtZV9taW5pbWFsKCkgIA0KYGBgDQoNCkJp4buDdSDEkeG7kyBjaG8gdGjhuqV5IHThu7cgbOG7hyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBraMOhYyBuaGF1IHLDtSBy4buHdCBnaeG7r2EgaGFpIGxv4bqhaSBow6xuaCBJbnRlcm5ldC4gVuG7m2kgRFNMLCBjw7MgMTQ0NyBraMOhY2ggaMOgbmcgZHV5IHRyw6wgZOG7i2NoIHbhu6UgdsOgIDI4OSBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jywgdMawxqFuZyDhu6luZyB04bu3IGzhu4cgcuG7nWkgYuG7jyBraG/huqNuZyAxNiw3JS4gVHJvbmcga2hpIMSRw7MsIEZpYmVyIG9wdGljIGPDsyBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyBy4budaSBi4buPIGNhbyBoxqFuIG5oaeG7gXUgduG7m2kgMTI5NyBraMOhY2ggaMOgbmcsIGNoaeG6v20ga2hv4bqjbmcgNDEsOSUuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IGtow6FjaCBow6BuZyBz4butIGThu6VuZyBGaWJlciBvcHRpYyBjw7MgeHUgaMaw4bubbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBuaGnhu4F1IGjGoW4sIG3hurdjIGTDuSDEkcOieSBsw6AgbG/huqFpIGjDrG5oIMSRxrDhu6NjIHPhu60gZOG7pW5nIHBo4buVIGJp4bq/biBuaOG6pXQuDQoNCmBgYHtyfQ0KdGFibGVfZGF0YTIgPC0gcm91bmQocHJvcC50YWJsZSh0YWJsZV9kYXRhKSoxMDAsMikgDQp0YWJsZV9kYXRhMg0KYGBgDQpgYGB7cn0NCiMgQ2h1eeG7g24gxJHhu5VpIGThu68gbGnhu4d1IHRow6BuaCBk4bqhbmcgZMOgaSDEkeG7gyBk4buFIHbhur0gYmnhu4N1IMSR4buTDQp0YWJsZV9kYXRhMiA8LSBhcy5kYXRhLmZyYW1lLnRhYmxlKHRhYmxlX2RhdGEyKQ0KY29sbmFtZXModGFibGVfZGF0YTIpIDwtIGMoIkdyb3VwIiwgIkxldmVsIiwgIlBlcmNlbnRhZ2UiKQ0KDQojIFbhur0gYmnhu4N1IMSR4buTDQpnZ3Bsb3QodGFibGVfZGF0YTIsIGFlcyh4ID0gTGV2ZWwsIHkgPSBQZXJjZW50YWdlLCBmaWxsID0gTGV2ZWwpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IFBlcmNlbnRhZ2UpLCB2anVzdCA9IDEsIHNpemUgPSAyLjUsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMSkpICsNCiAgZmFjZXRfd3JhcCh+IEdyb3VwLCBzY2FsZXMgPSAiZnJlZV95IiwgbnJvdyA9IDIpICsNCiAgbGFicyh0aXRsZSA9ICLEkOG7kyB0aOG7iyBwaOG6p24gdHLEg20gdGhlbyBiaeG7g3UgaGnhu4duIHllcywgbm8gY+G7p2Ega2jDoWNoIGjDoG5nIHThu6sgYuG7jyBk4buLY2ggduG7pSB2w6AgY8OhYyBsYW9paiBk4buLY2ggduG7pSBJbnRlcm5ldCIsDQogICAgICAgeCA9ICJDw6FjIGxv4bqhaSBk4buLY2ggduG7pSBJbnRlcm5ldCIsDQogICAgICAgeSA9ICJQaOG6p24gdHLEg20iLA0KICAgICAgIGZpbGwgPSAiQmnhu4N1IGhp4buHbiIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiTm8iID0gImxpZ2h0Z3JlZW4iLCAiWWVzIiA9ICJsaWdodHBpbmsiKSkgKyANCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KQmnhu4N1IMSR4buTIHThuqduIHN14bqldCBjaG8gdGjhuqV5IHPhu7Ega2jDoWMgYmnhu4d0IHLDtSBy4buHdCB24buBIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBnaeG7r2EgaGFpIGxv4bqhaSBow6xuaCBJbnRlcm5ldC4gxJDhu5FpIHbhu5tpIERTTCwgdOG7tyBs4buHIGtow6FjaCBow6BuZyBkdXkgdHLDrCBk4buLY2ggduG7pSBjaGnhur9tIDI5LDk1JSwgdHJvbmcga2hpIHThu7cgbOG7hyBy4budaSBi4buPIGNo4buJIGzDoCA1LDk4JS4gTmfGsOG7o2MgbOG6oWksIEZpYmVyIG9wdGljIGPDsyB04bu3IGzhu4cga2jDoWNoIGjDoG5nIGR1eSB0csOsIGzDoCAzNywyMyUsIG5oxrBuZyB04bu3IGzhu4cgcuG7nWkgYuG7jyBjYW8gaMahbiDEkcOhbmcga+G7gywgxJHhuqF0IDI2LDg0JS4gS+G6v3QgcXXhuqMgbsOgeSBjaG8gdGjhuqV5LCBt4bq3YyBkw7kgRmliZXIgb3B0aWMgcGjhu5UgYmnhur9uIGjGoW4sIGtow6FjaCBow6BuZyBj4bunYSBk4buLY2ggduG7pSBuw6B5IGPFqW5nIGPDsyB4dSBoxrDhu5tuZyBy4budaSBi4buPIG5oaeG7gXUgaMahbiBzbyB24bubaSBEU0wuDQoNCiMjIyAqKjMuMy4zIFBow6JuIHTDrWNoIFJlbGF0aXZlIFJpc2sgZ2nhu69hIGPDoWMgbG/huqFpIGjDrG5oIGThu4tjaCB24bulIEludGVybmV0IHbDoCBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSoqDQoNClRyb25nIHBo4bqnbiB0aeG6v3AgdGhlbywgY2jDum5nIHTDtGkgc+G6vSB0aeG6v24gaMOgbmggdMOtbmggdG/DoW4gY2jhu4kgc+G7kSBy4bunaSBybyB0xrDGoW5nIMSR4buRaSAoUmVsYXRpdmUgUmlzayDigJMgUlIpIG5o4bqxbSDEkcOhbmggZ2nDoSBt4bupYyDEkeG7mSDhuqNuaCBoxrDhu59uZyBj4bunYSBjw6FjIGxv4bqhaSBk4buLY2ggduG7pSBJbnRlcm5ldCDEkeG6v24ga2jhuqMgbsSDbmcga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6Ugdmnhu4VuIHRow7RuZy4NCg0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQpycjI8LSByaXNrcmF0aW8odGFibGVfZGF0YSkNCnJyMg0KYGBgDQoNCkvhur90IHF14bqjIHBow6JuIHTDrWNoIFJlbGF0aXZlIFJpc2sgKFJSKSBjaG8gdGjhuqV5IG5ow7NtIERTTCDEkcaw4bujYyB4ZW0gbmjGsCBt4buRYyB0aGFtIGNoaeG6v3UgduG7m2kgUlIgPSAxLjAuIFRyb25nIGtoaSDEkcOzLCBuaMOzbSBGaWJlciBvcHRpYyBjw7MgUlIgPSAyLDUyLCB04bupYyBsw6Agbmd1eSBjxqEga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY2FvIGfhuqVwIGtob+G6o25nIDIsNSBs4bqnbiBzbyB24bubaSBEU0wuIEdpw6EgdHLhu4sgcC12YWx1ZSBn4bqnbiBi4bqxbmcgMCAocCA8IDAsMDAxKSB04burIGPDoWMga2nhu4NtIMSR4buLbmggRmlzaGVyIHbDoCBDaGktc3F1YXJlIGto4bqzbmcgxJHhu4tuaCBz4buxIGtow6FjIGJp4buHdCBuw6B5IGhvw6BuIHRvw6BuIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IG5ow7NtIGtow6FjaCBow6BuZyBz4butIGThu6VuZyBGaWJlciBvcHRpYyBk4buFIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgaMahbiwgZMO5IMSRw6J5IGzDoCBsb+G6oWkgaMOsbmggcGjhu5UgYmnhur9uLiBWw6wgduG6rXksIGRvYW5oIG5naGnhu4dwIGPhuqduIGPDsyBjaMOtbmggc8OhY2ggY2jEg20gc8OzYyB2w6AgZ2nhu68gY2jDom4ga2jDoWNoIGjDoG5nIEZpYmVyIG9wdGljIGhp4buHdSBxdeG6oyBoxqFuLg0KDQojIyMgKiozLjMuNCBQaMOibiB0w61jaCBPZGQgUmF0aW8gZ2nhu69hIGPDoWMgbG/huqFpIGjDrG5oIGThu4tjaCB24bulIEludGVybmV0IHbDoCBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSoqDQoNClRyb25nIHBo4bqnbiBuw6B5LCBuZ2hpw6puIGPhu6l1IHPhur0gdGnhur9uIGjDoG5oIHTDrW5oIE9kZHMgUmF0aW8gZ2nhu69hIGhhaSBsb+G6oWkgZOG7i2NoIHbhu6UgaW50ZXJuZXQgdsOgIGJp4bq/biBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB2aeG7hW4gdGjDtG5nIChDaHVybikuIFZp4buHYyB0w61uaCB0b8OhbiBPUiBz4bq9IGdpw7pwIHjDoWMgxJHhu4tuaCBsb+G6oWkgaOG7o3AgxJHhu5NuZyBuw6BvIGzDoG0gdMSDbmcgaG/hurdjIGdp4bqjbSBraOG6oyBuxINuZyBy4budaSBi4buPIGThu4tjaCB24bulLg0KDQpgYGB7cn0NCm9yMiA8LSBvZGRzcmF0aW8odGFibGVfZGF0YSkNCm9yMg0KYGBgDQoNCkvhur90IHF14bqjIHBow6JuIHTDrWNoIG9kZHMgcmF0aW8gKE9SKSBjaG8gdGjhuqV5IG5ow7NtIGtow6FjaCBow6BuZyBz4butIGThu6VuZyBEU0wgxJHGsOG7o2MgY2jhu41uIGzDoG0gbeG7kWMgdGhhbSBjaGnhur91IHbhu5tpIE9SID0gMS4wLiBUcm9uZyBraGkgxJHDsywgbmjDs20gRmliZXIgb3B0aWMgY8OzIE9SID0gMyw2MSwgdOG7qWMgbMOgIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2EgaOG7jSBjYW8gZ+G6pXAga2hv4bqjbmcgMyw2IGzhuqduIHNvIHbhu5tpIGtow6FjaCBow6BuZyBz4butIGThu6VuZyBk4buLY2ggduG7pSBEU0wuIEdpw6EgdHLhu4sgcC12YWx1ZSBn4bqnbiBi4bqxbmcgMCAocCA8IDAsMDAxKSB04burIGPDoWMga2nhu4NtIMSR4buLbmggRmlzaGVyIHbDoCBDaGktc3F1YXJlIGNo4bupbmcgbWluaCBz4buxIGtow6FjIGJp4buHdCBuw6B5IGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ogcuG6pXQgY2FvLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSBraMOhY2ggaMOgbmcgRmliZXIgb3B0aWMgZOG7hSBy4budaSBi4buPIGThu4tjaCB24bulIGjGoW4sIGTDuSDEkcOieSBsw6AgbG/huqFpIGjDrG5oIGNoaeG6v20gdOG7tyB0cuG7jW5nIGzhu5tuIHRyb25nIGThu68gbGnhu4d1LiBEb2FuaCBuZ2hp4buHcCBj4bqnbiDGsHUgdGnDqm4gY8OhYyBjaMOtbmggc8OhY2ggY2jEg20gc8OzYyBraMOhY2ggaMOgbmcgdsOgIGNoaeG6v24gbMaw4bujYyBnaeG7ryBjaMOibiByacOqbmcgY2hvIG5ow7NtIEZpYmVyIG9wdGljIG5o4bqxbSBnaeG6o20gdOG7tyBs4buHIHLhu51pIGLhu48uDQoNCiMjIyAqKjMuMy41IFRo4buRbmcga8OqIHN1eSBkaeG7hW4qKg0KDQojIyMjICoqMy4zLjUuMSBLaeG7g20gxJHhu4tuaCB0w61uaCDEkeG7mWMgbOG6rXAqKg0KDQrEkOG7gyBraeG7g20gdHJhIHhlbSBiaeG6v24gZOG7i2NoIHbhu6UgaW50ZXJuZXQgKEludGVybmV0U2VydmljZSkgdsOgIGjDoG5oIHZpIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKENodXJuKSBjw7MgbeG7kWkgbGnDqm4gaOG7hyB24bubaSBuaGF1IGhheSBraMO0bmcsIG5naGnDqm4gY+G7qXUgw6FwIGThu6VuZyBraeG7g20gxJHhu4tuaCBDaGktc3F1YXJlLg0KDQpLaeG7g20gxJHhu4tuaCBuw6B5IMSRxrDhu6NjIHRoaeG6v3QgbOG6rXAgduG7m2kgZ2nhuqMgdGh1eeG6v3Q6IA0KDQokJA0KXGxlZnRcew0KXGJlZ2lue2FycmF5fXtsbH0NCkhfMDogJiBcdGV4dHtCaeG6v24gQ2h1cm4gKGtow6FjaCBow6BuZyB04burIGLhu48gZOG7i2NoIHbhu6UpIHbDoCBiaeG6v24gSW50ZXJuZXRTZXJ2aWNlIChk4buLY2ggduG7pSBpbnRlcm5ldCkga2jDtG5nIGPDsyBt4buRaSBxdWFuIGjhu4cgduG7m2kgbmhhdS59ICBcXFxcDQpIXzE6ICYgXHRleHR7Qmnhur9uIENodXJuIChraMOhY2ggaMOgbmcgdOG7qyBi4buPIGThu4tjaCB24bulKSB2w6AgYmnhur9uIEludGVybmV0U2VydmljZSAoZOG7i2NoIHbhu6UgaW50ZXJuZXQpIGPDsyBt4buRaSBxdWFuIGjhu4cgduG7m2kgbmhhdS59IFwNClxlbmR7YXJyYXl9DQpccmlnaHQuDQokJA0KDQpgYGB7cn0NCiMgS2nhu4NtIMSR4buLbmgNCmNoaXNxX3Jlc3VsdCA8LSBjaGlzcS50ZXN0KHRhYmxlX2RhdGEpDQojIEluIGvhur90IHF14bqjDQpjaGlzcV9yZXN1bHQNCmBgYA0KDQpRdWEga+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmg6IFbhu5tpIG3hu6ljIMO9IG5naMSpYSAwLjA1LCB2w6wgcC12YWx1ZSA9IDIuMmUtMTYgPCAwLjA1LCBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgJEhfMCQuIFbhuq15IGdp4buvYSBiaeG6v24gQ2h1cm4gdsOgIGJp4bq/biBJbnRlcm5ldFNlcnZpY2UgdOG7k24gdOG6oWkgbeG7kWkgcXVhbiBo4buHLg0KDQojIyMjICoqMy4zLjUuMiBLaG/huqNuZyDGsOG7m2MgbMaw4bujbmcgdOG7tyBs4buHKioNCg0KKirGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIHPhu60gZOG7pW5nIGThu4tjaCB24bulIEZpYmVyIG9wdGljICoqIA0KDQpUcm9uZyBwaOG6p24gbsOgeSwgdMOhYyBnaeG6oyBz4butIGThu6VuZyBraeG7g20gxJHhu4tuaCB04bu3IGzhu4cgbeG7mXQgbeG6q3UgKDEtc2FtcGxlIHByb3BvcnRpb24gdGVzdCkgxJHhu4MgxrDhu5tjIGzGsOG7o25nIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0cm9uZyBuaMOzbSBz4butIGThu6VuZyBk4buLY2ggduG7pSBGaWJlciBvcHRpYywgxJHhu5NuZyB0aOG7nWkgc28gc8OhbmggduG7m2kgdOG7tyBs4buHIGdp4bqjIMSR4buLbmggbMOgIDUwJSAocCA9IDAuNSkuIFBoxrDGoW5nIHBow6FwIG7DoHkgZ2nDunAgeMOhYyDEkeG7i25oIHhlbSB04bu3IGzhu4cgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBj4bunYSBuaMOzbSBz4butIGThu6VuZyBk4buLY2ggduG7pSBGaWJlciBvcHRpYyBjw7Mga2jDoWMgYmnhu4d0IMSRw6FuZyBr4buDIHNvIHbhu5tpIHThu7cgbOG7hyBnaeG6oyDEkeG7i25oIGhheSBraMO0bmcuIA0KDQpgYGB7cn0NCnByb3AudGVzdCh4ID0gdGFibGVfZGF0YVsiRmliZXIgb3B0aWMiLCAiWWVzIl0sIG4gPSBzdW0oIHRhYmxlX2RhdGFbIkZpYmVyIG9wdGljIiwgXSksIHAgPSAwLjUsIGNvcnJlY3QgPSBUUlVFKQ0KYGBgDQoNCkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oIHThu7cgbOG7hyBt4buZdCBt4bqrdSBjaG8gdGjhuqV5IHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIChDaHVybikgY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIHPhu60gZOG7pW5nIEZpYmVyIG9wdGljIMSRxrDhu6NjIMaw4bubYyBsxrDhu6NuZyBraG/huqNuZyA0MSw4OSUgKHAgPSAwLjQxODkpLiBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyB04bu3IGzhu4cgbsOgeSBu4bqxbSB0cm9uZyBraG/huqNuZyA0MCwxNSUgxJHhur9uIDQzLDY2JSwgbmdoxKlhIGzDoCB04bu3IGzhu4cgdGjhu7FjIHPhu7EgY+G7p2EgdOG7lW5nIHRo4buDIGfhuqduIG5oxrAgY2jhuq9jIGNo4bqvbiBu4bqxbSB0cm9uZyBraG/huqNuZyBuw6B5LiBHacOhIHRy4buLIHAtdmFsdWUgPCAyLjJlLTE2IGNobyB0aOG6pXkgc+G7sSBraMOhYyBiaeG7h3QgZ2nhu69hIHThu7cgbOG7hyDGsOG7m2MgbMaw4bujbmcgdsOgIGdpw6EgdHLhu4sgZ2nhuqMgdGh1eeG6v3QgMC41ICg1MCUpIGzDoCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLCB04bupYyBsw6AgdOG7tyBs4buHIHLhu51pIGLhu48gY+G7p2EgRmliZXIgb3B0aWMgdGjhuqVwIGjGoW4gxJHDoW5nIGvhu4MgNTAlLiBL4bq/dCBxdeG6oyBuw6B5IHBo4bqjbiDDoW5oIHLhurFuZyBj4bupIDEwIGtow6FjaCBow6BuZyBGaWJlciBvcHRpYyB0aMOsIGPDsyBraG/huqNuZyA0IG5nxrDhu51pIHLhu51pIGLhu48gZOG7i2NoIHbhu6UuDQoNCioqxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIG5ow7NtIGtow6FjaCBow6BuZyBz4butIGThu6VuZyBk4buLY2ggduG7pSBEU0wqKiANCg0KUGjhuqduIG7DoHkgbmjhurFtIHjDoWMgxJHhu4tuaCB04bu3IGzhu4cga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdHJvbmcgbmjDs20gc+G7rSBk4bulbmcgRFNMLCDEkeG7k25nIHRo4budaSBzbyBzw6FuaCB04bu3IGzhu4cgxrDhu5tjIGzGsOG7o25nIHbhu5tpIG3hu6ljIGdp4bqjIHRodXnhur90IDUwJSDEkeG7gyBraeG7g20gdHJhIMO9IG5naMSpYSB0aOG7kW5nIGvDqi4NCg0KYGBge3J9DQpwcm9wLnRlc3QoeCA9IHRhYmxlX2RhdGFbIkRTTCIsICJZZXMiXSwgbiA9IHN1bSggdGFibGVfZGF0YVsiRFNMIiwgXSksIHAgPSAwLjUsIGNvcnJlY3QgPSBUUlVFKQ0KYGBgDQoNCkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oIHThu7cgbOG7hyBt4buZdCBt4bqrdSBjaG8gdGjhuqV5IHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIChDaHVybikgY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIHPhu60gZOG7pW5nIERTTCDEkcaw4bujYyDGsOG7m2MgbMaw4bujbmcga2hv4bqjbmcgMTYsNjUlIChwID0gMC4xNjY1KS4gS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gdOG7tyBs4buHIG7DoHkgbuG6sW0gdHJvbmcga2hv4bqjbmcgMTQsOTQlIMSR4bq/biAxOCw1MCUsIGNobyB0aOG6pXkgdOG7tyBs4buHIHRo4buxYyB04bq/IGPhu6dhIHThu5VuZyB0aOG7gyBjaOG6r2MgY2jhuq9uIHRo4bqlcCBoxqFuIDIwJS4gR2nDoSB0cuG7iyBwLXZhbHVlIDwgMi4yZS0xNiBraOG6s25nIMSR4buLbmggc+G7sSBraMOhYyBiaeG7h3QgZ2nhu69hIHThu7cgbOG7hyDGsOG7m2MgbMaw4bujbmcgdsOgIG3hu6ljIGdp4bqjIHRodXnhur90IDUwJSBsw6AgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiBy4bqldCBjYW8uIE5oxrAgduG6rXksIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIGtow6FjaCBow6BuZyBEU0wgdGjhuqVwIGjGoW4gbmhp4buBdSBzbyB24bubaSA1MCUsIMSRaeG7gXUgbsOgeSB0aOG7gyBoaeG7h24gbeG7qWMgxJHhu5kgZ+G6r24gYsOzIGNhbyBoxqFuIGPhu6dhIG5ow7NtIG7DoHkuDQoNCiMjIyAqKjMuMy42IE3DtCBow6xuaCBo4buTaSBxdXkgY2hvIGThu68gbGnhu4d1IG5o4buLIHBow6JuKioNCg0KIyMjIyAqKjMuMy42LjEgTcO0IGjDrG5oIGxvZ2l0KioNCg0KxJDhu4MgcGjDom4gdMOtY2ggbeG7kWkgcXVhbiBo4buHIGdp4buvYSBjw6FjIGThu4tjaCB24bulIGludGVybmV0IChJbnRlcm5ldFNlcnZpY2UpIHbDoCBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoQ2h1cm4pLCB0w6FjIGdp4bqjIHPhu60gZOG7pW5nIG3DtCBow6xuaCBo4buTaSBxdXkgbG9naXN0aWMgbmjhu4sgcGjDom4gKGxvZ2l0IG1vZGVsKS4gTcO0IGjDrG5oIG7DoHkgY2hvIHBow6lwIMaw4bubYyBsxrDhu6NuZyB4w6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIHRow7RuZyBxdWEgaMOgbSBsb2dpdCwgZ2nDunAgeMOhYyDEkeG7i25oIG3hu6ljIMSR4buZIOG6o25oIGjGsOG7n25nIGPhu6dhIHThu6tuZyBsb+G6oWkgZOG7i2NoIHbhu6UgaW50ZXJuZXQgxJHhur9uIGjDoG5oIHZpIHLhu51pIGLhu48gY+G7p2Ega2jDoWNoIGjDoG5nLiANCg0KDQpgYGB7cn0NCmxvZzIgPC0gZ2xtKGZhY3RvcihDaHVybikgfkludGVybmV0U2VydmljZSwgZGF0YSA9IHZpZW50aG9uZywgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpKQ0Kc3VtbWFyeShsb2cyKQ0KYGBgDQpUYSBjw7MgbcO0IGjDrG5oIGjhu5NpIHF1eSBuaMawIHNhdToNCg0KJCQNClxsb2dcbGVmdCggXGZyYWN7UChcdGV4dHtDaHVybn0gPSBcdGV4dHsiWWVzIn0pfXsxIC0gUChcdGV4dHtDaHVybn0gPSBcdGV4dHsiWWVzIn0pfSBccmlnaHQpID0gIC0xLjYxMDgyICArIDEuMjgzNjQgIFxjZG90IFx0ZXh0e0ludGVybmV0U2VydmljZUZpYmVyIG9wdGljfQ0KJCQNCg0KS+G6v3QgcXXhuqMgxrDhu5tjIGzGsOG7o25nIHThu6sgbcO0IGjDrG5oIGxvZ2l0IGNobyB0aOG6pXkgaOG7hyBz4buRIGNo4bq3biBcKC0xLjYxMDgyXCkgdsOgIGjhu4cgc+G7kSBj4bunYSBiaeG6v24gSW50ZXJuZXRTZXJ2aWNlRmliZXIgb3B0aWMgXCgxLjI4MzY0XCkgxJHhu4F1IGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ogY2FvIChwIDwgMC4wMDEpLiDEkGnhu4F1IG7DoHkgY2jhu6luZyB04buPIGxv4bqhaSBow6xuaCBk4buLY2ggduG7pSBpbnRlcm5ldCBjw7Mg4bqjbmggaMaw4bufbmcgxJHDoW5nIGvhu4MgxJHhur9uIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2Ega2jDoWNoIGjDoG5nLiBI4buHIHPhu5EgZMawxqFuZyBj4bunYSBGaWJlciBvcHRpYyBjaG8gdGjhuqV5IGtow6FjaCBow6BuZyBkw7luZyBk4buLY2ggduG7pSBuw6B5IGPDsyBraOG6oyBuxINuZyBy4budaSBi4buPIGNhbyBoxqFuIHNvIHbhu5tpIG5ow7NtIERTTCAobmjDs20gdGhhbSBjaGnhur91KSwgduG7m2kgdOG7tyBs4buHIGto4bqjIG7Eg25nIHjhuqN5IHJhIHLhu51pIGLhu48gY2FvIGfhuqVwIFwoZV57MS4yODM2NH0gXGFwcHJveCAzLjYxXCkgbOG6p24uDQoNCnRhIGPDsyB4w6FjIHN14bqldCBy4budaSBi4buPIGPhu6dhIG5ow7NtICoqRFNMKio6DQpcWw0KcF97RFNMfSA9IFxmcmFje2Veey0xLjYxMDgyfX17MSArIGVeey0xLjYxMDgyfX0gXGFwcHJveCAwLjE2NiBcLCAoMTYuNlwlKSwNClxdDQpuZ2jEqWEgbMOgIHRydW5nIGLDrG5oIGPhu6kgMTAwIGtow6FjaCBow6BuZyBEU0wgdGjDrCBraG/huqNuZyAxNyBraMOhY2ggc+G6vSBy4budaSBi4buPIGThu4tjaCB24bulLiBW4bubaSBuaMOzbSBGaWJlciBvcHRpYywgbG9naXQgbMOgIFwoLTEuNjEwODIgKyAxLjI4MzY0ID0gLTAuMzI3MThcKSwgbsOqbjoNClxbDQpwX3tGaWJlcn0gPSBcZnJhY3tlXnstMC4zMjcxOH19ezEgKyBlXnstMC4zMjcxOH19IFxhcHByb3ggMC40MjggXCwgKDQyLjhcJSksDQpcXQ0KdOG7qWMgbMOgIGtob+G6o25nIDQzIHRyw6puIDEwMCBraMOhY2ggaMOgbmcgRmliZXIgb3B0aWMgY8OzIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UuIENo4buJIHPhu5EgQUlDID0gNTc3Ny41IGNobyB0aOG6pXkgbcO0IGjDrG5oIGPDsyDEkeG7mSBwaMO5IGjhu6NwIGNo4bqlcCBuaOG6rW4gxJHGsOG7o2MgduG7m2kgZOG7ryBsaeG7h3UuDQoNCiMjIyMgKiozLjMuNi4yIE3DtCBow6xuaCBwcm9iaXQqKg0KDQoNCmBgYHtyfQ0KcHJvMiA8LSBnbG0oZmFjdG9yKENodXJuKSB+IEludGVybmV0U2VydmljZSwgZGF0YSA9IHZpZW50aG9uZywgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdwcm9iaXQnKSkNCnN1bW1hcnkocHJvMiApDQpgYGANCg0KVGEgY8OzIG3DtCBow6xuaCBo4buTaSBxdXkgbmjGsCBzYXU6DQoNCiQkDQpQKFx0ZXh0e0NodXJufSA9IFllcykgPSBcUGhpIFxiaWcoIC0wLjk2ODE5ICsgMC43NjM1NSAgXGNkb3QgXHRleHR7SW50ZXJuZXRTZXJ2aWNlRmliZXIgb3B0aWN9KQ0KJCQNCg0KS+G6v3QgcXXhuqMgbcO0IGjDrG5oIFByb2JpdCBjaG8gdGjhuqV5IGjhu4cgc+G7kSBjaOG6t24gLTAuOTY4MTkgdsOgIGjhu4cgc+G7kSBj4bunYSBiaeG6v24gSW50ZXJuZXRTZXJ2aWNlRmliZXIgb3B0aWMgMC43NjM1NSDEkeG7gXUgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiBy4bqldCBjYW8gKHAgPCAwLjAwMSksIGNo4bupbmcgdOG7jyBsb+G6oWkgaMOsbmggZOG7i2NoIHbhu6UgaW50ZXJuZXQg4bqjbmggaMaw4bufbmcgbeG6oW5oIMSR4bq/biBraOG6oyBuxINuZyBy4budaSBi4buPIGThu4tjaCB24bulLiBI4buHIHPhu5EgZMawxqFuZyBj4bunYSBGaWJlciBvcHRpYyBjaG8gdGjhuqV5IGtow6FjaCBow6BuZyBz4butIGThu6VuZyBk4buLY2ggduG7pSBuw6B5IGPDsyB4dSBoxrDhu5tuZyBy4budaSBi4buPIGNhbyBoxqFuIG5ow7NtIERTTCAobmjDs20gdGhhbSBjaGnhur91KS4gROG7sWEgdHLDqm4gY8O0bmcgdGjhu6ljOg0KXFsNCnAgPSBcUGhpKFxiZXRhXzAgKyBcYmV0YV8xIFgpLA0KXF0NCnjDoWMgc3XhuqV0IHLhu51pIGLhu48gY+G7p2EgbmjDs20gRFNMIGzDoDoNClxbDQpwX3tEU0x9ID0gXFBoaSgtMC45NjgxOSkgXGFwcHJveCAwLjE2NiBcLCAoMTYuNlwlKSwNClxdDQpuZ2jEqWEgbMOgIGPhu6kgMTAwIGtow6FjaCBow6BuZyBEU0wgdGjDrCBraG/huqNuZyAxNyBuZ8aw4budaSBy4budaSBi4buPIGThu4tjaCB24bulLiDEkOG7kWkgduG7m2kgbmjDs20gRmliZXIgb3B0aWMsIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gbMOgOg0KXFsNCnBfe0ZpYmVyfSA9IFxQaGkoLTAuOTY4MTkgKyAwLjc2MzU1KSBcYXBwcm94IDAuNDE5IFwsICg0MS45XCUpLA0KXF0NCnThu6ljIGfhuqduIDQyIGtow6FjaCB0csOqbiAxMDAgY8OzIGto4bqjIG7Eg25nIHLhu51pIGLhu48uIFPhu7Ega2jDoWMgYmnhu4d0IG7DoHkgY2hvIHRo4bqleSBGaWJlciBvcHRpYyBsw6BtIHTEg25nIGto4bqjIG7Eg25nIHLhu51pIGLhu48gbMOqbiBraG/huqNuZyAyLjUgbOG6p24gc28gduG7m2kgRFNMLiANCg0KDQojIyMjICoqMy4zLjYuMyBNw7QgaMOsbmggY2xvZ2xvZyoqDQoNCsSQ4buDIHBow6JuIHTDrWNoIHTDoWMgxJHhu5luZyBj4bunYSBsb+G6oWkgaMOsbmggZOG7i2NoIHbhu6UgaW50ZXJuZXQgKEludGVybmV0U2VydmljZSkgxJHhur9uIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKENodXJuKSwgdMOhYyBnaeG6oyBz4butIGThu6VuZyBtw7QgaMOsbmggaOG7k2kgcXV5IG5o4buLIHBow6JuIHbhu5tpIGjDoG0gbGnDqm4ga+G6v3QgQ29tcGxlbWVudGFyeSBsb2ctbG9nIChDbG9nbG9nKS4gDQoNCmBgYHtyfQ0KY2xvMiA8LSBnbG0oZmFjdG9yKENodXJuKSB+IEludGVybmV0U2VydmljZSwgZGF0YSA9IHZpZW50aG9uZywgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdjbG9nbG9nJykpDQpzdW1tYXJ5KGNsbzIpDQpgYGANCg0KTcO0IGjDrG5oIENsb2dsb2cgxJHGsOG7o2Mgc+G7rSBk4bulbmcgxJHhu4MgcGjDom4gdMOtY2ggbeG7kWkgcXVhbiBo4buHIGdp4buvYSBsb+G6oWkgZOG7i2NoIHbhu6UgaW50ZXJuZXQgdsOgIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UsIHbhu5tpIHBoxrDGoW5nIHRyw6xuaDoNCg0KJCQNClxsb2cgXGxlZnRbIC1cbG9nICgxLXApIFxyaWdodF0gDQo9IC0xLjcwMzI1ICsgMS4wOTIzOCBcY2RvdCBcdGV4dHtJbnRlcm5ldFNlcnZpY2VcX0ZpYmVyXF9vcHRpY30NCiQkDQpL4bq/dCBxdeG6oyBjaG8gdGjhuqV5IGjhu4cgc+G7kSBjaOG6t24gXCgtMS43MDMyNVwpIHbDoCBo4buHIHPhu5EgSW50ZXJuZXRTZXJ2aWNlRmliZXIgb3B0aWMgXCgxLjA5MjM4XCkgxJHhu4F1IGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ogKHAgPCAwLjAwMSksIGNo4bupbmcgdOG7jyBsb+G6oWkgZOG7i2NoIHbhu6UgaW50ZXJuZXQg4bqjbmggaMaw4bufbmcgbeG6oW5oIMSR4bq/biBow6BuaCB2aSBy4budaSBi4buPLiBE4buxYSB0csOqbiBjw7RuZyB0aOG7qWMgXChwID0gMSAtIFxleHBbLVxleHAoXGV0YSldXCksIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gY+G7p2EgbmjDs20gRFNMIGzDoCBcKHBfe0RTTH0gXGFwcHJveCAwLjE2NlwpICgxNi42JSksIHRyb25nIGtoaSBuaMOzbSBGaWJlciBvcHRpYyBjw7MgeMOhYyBzdeG6pXQgXChwX3tGaWJlcn0gXGFwcHJveCAwLjQyMlwpICg0Mi4yJSkuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IGtow6FjaCBow6BuZyBGaWJlciBvcHRpYyBjw7Mga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBjYW8gZ+G6pXAgaMahbiAyLjUgbOG6p24gc28gduG7m2kgRFNMLiANCg0KIyMjICoqMy4zLjcgxJDDoW5oIGdpw6EgbcO0IGjDrG5oKioNCg0KU2F1IGtoaSB0aeG6v24gaMOgbmggxrDhu5tjIGzGsOG7o25nIGJhIG3DtCBow6xuaCBo4buTaSBxdXkgbmjhu4sgcGjDom4gZ+G7k20gbG9naXQsIHByb2JpdCB2w6AgY2xvZ2xvZywgYsaw4bubYyB0aeG6v3AgdGhlbyBsw6AgxJHDoW5oIGdpw6EgdsOgIHNvIHPDoW5oIG3hu6ljIMSR4buZIHBow7kgaOG7o3AgY+G7p2EgY8OhYyBtw7QgaMOsbmggbsOgeS4gVmnhu4djIMSRw6FuaCBnacOhIMSRxrDhu6NjIHRo4buxYyBoaeG7h24gZOG7sWEgdHLDqm4gY8OhYyBjaOG7iSB0acOqdSB0aOG7kW5nIGvDqiBuaMawIGdpw6EgdHLhu4sgQUlDLCBo4buHIHPhu5EgQnJpZXIgU2NvcmUgdsOgIG1hIHRy4bqtbiBuaOG6p20gbOG6q24uIE5nb8OgaSByYSwga2jhuqMgbsSDbmcgZOG7sSBiw6FvIHjDoWMgc3XhuqV0IGPhu6dhIHThu6tuZyBtw7QgaMOsbmggxJHhu5FpIHbhu5tpIGPDoWMgdHLGsOG7nW5nIGjhu6NwIGdp4bqjIMSR4buLbmggY+G7pSB0aOG7gyBjxaluZyDEkcaw4bujYyB4ZW0geMOpdCDEkeG7gyBs4buxYSBjaOG7jW4gbcO0IGjDrG5oIHBow7kgaOG7o3AgbmjhuqV0Lg0KDQpgYGB7cn0NCiMgVOG6oW8gYuG6o25nIHNvIHPDoW5oDQptb2RlbF9ldmFsMSA8LSBkYXRhLmZyYW1lKA0KICBNw7RfaMOsbmggPSBjKCJMb2dpdCIsICJQcm9iaXQiLCAiQ2xvZ2xvZyIpLA0KICBBSUMgPSBjKEFJQyhsb2cyKSwgQUlDKHBybzIpLCBBSUMoY2xvMikpLA0KICBCSUMgPSBjKEJJQyhsb2cyKSwgQklDKHBybzIpLCBCSUMoY2xvMikpLA0KICBCcmllcl9TY29yZSA9IGMoQnJpZXJTY29yZShsb2cyKSwgQnJpZXJTY29yZShwcm8yKSwgQnJpZXJTY29yZShjbG8yKSkNCikNCmthYmxlKG1vZGVsX2V2YWwxLCBhbGlnbiA9ICJjIiwgY2FwdGlvbiA9ICJTbyBzw6FuaCBjw6FjIGNo4buJIHPhu5EgxJHDoW5oIGdpw6EgbcO0IGjDrG5oIikgJT4lDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJjZW50ZXIiLCBmb250X3NpemUgPSAxNCkNCmBgYA0KDQpE4buxYSB0csOqbiBr4bq/dCBxdeG6oyBzbyBzw6FuaCBjw6FjIGNo4buJIHPhu5EgxJHDoW5oIGdpw6EgbcO0IGjDrG5oLCBj4bqjIGJhIG3DtCBow6xuaCBsb2dpdCwgcHJvYml0IHbDoCBjbG9nbG9nIMSR4buBdSBjaG8gcmEgZ2nDoSB0cuG7iyBBSUMgKDU3NzcuNDg1KSwgQklDICg1NzkwLjQ1MSkgdsOgIEJyaWVyIFNjb3JlICgwLjIwNTgyMzYpIGdp4buRbmcgbmhhdS4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgbeG7qWMgxJHhu5kgcGjDuSBo4bujcCBj4bunYSBjw6FjIG3DtCBow6xuaCBsw6AgdMawxqFuZyDEkcawxqFuZyB2w6Aga2jhuqMgbsSDbmcgZOG7sSBiw6FvIHjDoWMgc3XhuqV0IMSRw7puZyBraMO0bmcgY8OzIHPhu7Ega2jDoWMgYmnhu4d0IMSRw6FuZyBr4buDLiANCg0KKipNYSB0cuG6rW4gbmjhuqdtIGzhuqtuKioNCg0KLSBNw7QgaMOsbmggbG9naXQNCg0KYGBge3J9DQpwcmVkX2xvZ2l0bG9nIDwtIGlmZWxzZShwcmVkaWN0KGxvZzIsIHR5cGUgPSAicmVzcG9uc2UiKSA+PSAwLjUsICJZZXMiLCAiTm8iKQ0KYWN0dWFsbG9nIDwtIHZpZW50aG9uZyRDaHVybg0KY21fbG9naXRsb2cgPC0gY29uZnVzaW9uTWF0cml4KGZhY3RvcihwcmVkX2xvZ2l0bG9nKSwgYWN0dWFsbG9nLCBwb3NpdGl2ZSA9ICJZZXMiKQ0KY21fbG9naXRsb2cNCmBgYA0KLSBNw7QgaMOsbmggcHJvYml0DQoNCmBgYHtyfQ0KcHJlZF9sb2dpdHBybyA8LSBpZmVsc2UocHJlZGljdChwcm8yLCB0eXBlID0gInJlc3BvbnNlIikgPj0gMC41LCAiWWVzIiwgIk5vIikNCmFjdHVhbHBybyA8LSB2aWVudGhvbmckQ2h1cm4NCmNtX2xvZ2l0cHJvIDwtIGNvbmZ1c2lvbk1hdHJpeChmYWN0b3IocHJlZF9sb2dpdHBybyksIGFjdHVhbHBybywgcG9zaXRpdmUgPSAiWWVzIikNCmNtX2xvZ2l0cHJvDQpgYGANCg0KLSBNw7QgaMOsbmggY2xvZ2xvZw0KDQpgYGB7cn0NCnByZWRfbG9naXRjbG8gPC0gaWZlbHNlKHByZWRpY3QoY2xvMiwgdHlwZSA9ICJyZXNwb25zZSIpID49IDAuNSwgIlllcyIsICJObyIpDQphY3R1YWxjbG8gPC0gdmllbnRob25nJENodXJuDQpjbV9sb2dpdGNsbyA8LSBjb25mdXNpb25NYXRyaXgoZmFjdG9yKHByZWRfbG9naXRjbG8pLCBhY3R1YWxjbG8sIHBvc2l0aXZlID0gIlllcyIpDQpjbV9sb2dpdGNsbw0KYGBgDQoNCk1hIHRy4bqtbiBuaOG6p20gbOG6q24gY2hvIHRo4bqleSBj4bqjIGJhIG3DtCBow6xuaCBsb2dpdCwgcHJvYml0IHbDoCBjbG9nbG9nIMSR4buBdSBraMO0bmcgZOG7sSDEkW/DoW4gxJHDum5nIMSRxrDhu6NjIGLhuqV0IGvhu7MgdHLGsOG7nW5nIGjhu6NwIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIG7DoG8sIHbhu5tpIFRQID0gMC4gxJDhu5NuZyB0aOG7nWksIEZQID0gMCBjaG8gdGjhuqV5IGtow7RuZyBjw7MgdHLGsOG7nW5nIGjhu6NwIGtow6FjaCBow6BuZyDhu58gbmjDs20g4oCcTm/igJ0gbsOgbyBi4buLIGThu7EgxJFvw6FuIG5o4bqnbSB0aMOgbmgg4oCcWWVz4oCdLCBuaMawbmcgxJFp4buBdSBuw6B5IHBo4bqjbiDDoW5oIG3DtCBow6xuaCBraMO0bmcgaOG7gSDEkcawYSByYSBk4buxIMSRb8OhbiDigJxZZXPigJ0uIE5nxrDhu6NjIGzhuqFpLCBGTiA9IDE1ODYgY2hvIHRo4bqleSB0b8OgbiBi4buZIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIMSR4buBdSBi4buLIHBow6JuIGxv4bqhaSBzYWkgdGjDoG5oIOKAnE5v4oCdLCBk4bqrbiDEkeG6v24gxJHhu5kgbmjhuqF5IChTZW5zaXRpdml0eSkgYuG6sW5nIDAuIFRyb25nIGtoaSDEkcOzLCBUTiA9IDMyNDYgY2hvIHRo4bqleSB0b8OgbiBi4buZIGtow6FjaCBow6BuZyBraMO0bmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSDEkcaw4bujYyBk4buxIMSRb8OhbiBjaMOtbmggeMOhYywgbMOgbSBTcGVjaWZpY2l0eSDEkeG6oXQgMTAwJS4gS+G6v3QgcXXhuqMgbsOgeSBjaG8gdGjhuqV5IG3DtCBow6xuaCBi4buLIGzhu4djaCBo4bqzbiB24buBIG5ow7NtIMSRYSBz4buRIOKAnE5v4oCdLiBN4bq3YyBkw7kgxJHhu5kgY2jDrW5oIHjDoWMgdOG7lW5nIHRo4buDIMSR4bqhdCA2NywxOCUsIG5oxrBuZyDEkWnhu4F1IG7DoHkga2jDtG5nIHBo4bqjbiDDoW5oIMSRw7puZyBoaeG7h3UgcXXhuqMgcGjDom4gbG/huqFpLg0KDQojIyAqKjMuNCBQaMOibiB0w61jaCBz4buxIHTDoWMgxJHhu5luZyDEkeG7mSB0deG7lWkgxJHhur9uIHZp4buHYyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSoqDQoNCiMjIyAqKjMuNC4xIFRo4buRbmcga8OqIG3DtCB04bqjIGJp4bq/biDEkeG7mSB0deG7lWkqKg0KDQrEkOG7gyBwaMOibiB0w61jaCB0w6FjIMSR4buZbmcgY+G7p2EgxJHhu5kgdHXhu5VpIChTZW5pb3JDaXRpemVuKSDEkeG6v24ga2jhuqMgbsSDbmcga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKENodXJuKSwgdHLGsOG7m2MgdGnDqm4gdGEgdGnhur9uIGjDoG5oIHRo4buRbmcga8OqIG3DtCB04bqjIGJp4bq/biBTZW5pb3JDaXRpemVuIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UuIFRo4buRbmcga8OqIG7DoHkgY2hvIGJp4bq/dCB04bu3IGzhu4cga2jDoWNoIGjDoG5nIHRodeG7mWMgbmjDs20gbmfGsOG7nWkgY2FvIHR14buVaSBzbyB24bubaSBuaMOzbSBjw7JuIGzhuqFpLCB04burIMSRw7MgaOG7lyB0cuG7oyB2aeG7h2Mgbmjhuq1uIMSR4buLbmggYmFuIMSR4bqndSB24buBIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgxJHhu5kgdHXhu5VpIHbDoCBow6BuaCB2aSBy4budaSBi4buPIGThu4tjaCB24bulLg0KDQpgYGB7cn0NCnM8LXRhYmxlKHZpZW50aG9uZyRTZW5pb3JDaXRpemVuKSANCiMgQ2h1eeG7g24gdGjDoG5oIGRhdGEgZnJhbWUgduG7m2kgMyBj4buZdDogQ2h1cm4gfCBT4buRIGzGsOG7o25nIHwgU3VtIChU4buVbmcgY+G7mW5nKQ0KZGZzIDwtIGRhdGEuZnJhbWUoDQogICBTZW5pb3JDaXRpemVuPSBjKCJObyIsICJZZXMiKSwNCiAgU29fbHVvbmcgPSBhcy5udW1lcmljKHMpKQ0KIyBJbiByYSBi4bqjbmcgxJHhurlwLCBjxINuIGdp4buvYQ0Ka2FibGUoZGZzLCBhbGlnbiA9ICJjIiwgY29sLm5hbWVzID0gYygiU2VuaW9yQ2l0aXplbiIsICJT4buRIGzGsOG7o25nIikpICAlPiUNCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImNlbnRlciIsIGZvbnRfc2l6ZSA9IDE0KSAlPiUNCiAgY29sdW1uX3NwZWMoMSwgd2lkdGggPSAiNGNtIikgJT4lICAjIMSQ4buZIHLhu5luZyBj4buZdCAxDQogIGNvbHVtbl9zcGVjKDIsIHdpZHRoID0gIjNjbSIpICAgICAgIyDEkOG7mSBy4buZbmcgY+G7mXQgMg0KDQpgYGANCg0KYGBge3J9DQojIFThuqFvIGLhuqNuZyB04bqnbiBz4buRIGNobyBiaeG6v24gdHlwZQ0KcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHZpZW50aG9uZyRTZW5pb3JDaXRpemVuKSApDQpjb2xuYW1lcyhzKSA8LSBjKCJTZW5pb3JDaXRpemVuIiwgIkNvdW50IikNCg0KIyDEkOG7lWkgMC8xIHRow6BuaCBOby9ZZXMNCnMkU2VuaW9yQ2l0aXplbiA8LSBpZmVsc2UocyRTZW5pb3JDaXRpemVuID09ICIwIiwgIk5vIiwgIlllcyIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MNCmdncGxvdChzLCBhZXMoeCA9IFNlbmlvckNpdGl6ZW4sIHkgPSBDb3VudCwgZmlsbCA9IFNlbmlvckNpdGl6ZW4pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuNSkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjUsIHNpemUgPSAzLjUpICsgICMgSGnhu4NuIHRo4buLIHPhu5EgbGnhu4d1IGLDqm4gdHLDqm4gY+G7mXQNCiAgbGFicyh0aXRsZSA9ICLEkOG7kyB0aOG7iyB24buBIMSR4buZIHR14buVaSBjYW8gY+G7p2Ega2jDoWNoIGjDoG5nIiwgDQogICAgICAgeCA9ICJTZW5pb3JDaXRpemVuIiwgeSA9ICJGcmVxdWVuY3kiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCk5nb8OgaSByYSB0w6FjIGdp4bqjIHPhur0gdGjhu7FjIGhp4buHbiB0w61uaCB04bu3IGzhu4cgcGjhuqduIHRyxINtIGNobyB04burbmcgbmjDs20gdsOgIHbhur0gxJHhu5MgdGjhu4sgY+G7mXQgY+G7p2EgY2jDum5nIMSR4buDIHNvIHPDoW5oIHRoZW8gc+G7kSBsaeG7h3UgdMawxqFuZyDEkeG7kWkuDQoNCmBgYHtyfQ0KcHJvcC50YWJsZSh0YWJsZSh2aWVudGhvbmckU2VuaW9yQ2l0aXplbikpKjEwMA0KYGBgDQpgYGB7cn0NCnMkUGVyY2VudGFnZSA8LSAocyRDb3VudCAvIHN1bShzJENvdW50KSkgKiAxMDANCg0KZ2dwbG90KHMsIGFlcyh4ID0gIiIsIHkgPSBQZXJjZW50YWdlLCBmaWxsID0gU2VuaW9yQ2l0aXplbikpICsNCiAgZ2VvbV9iYXIod2lkdGggPSAxLCBzdGF0ID0gImlkZW50aXR5IikgKw0KICBjb29yZF9wb2xhcigieSIpICsNCiAgbGFicyh0aXRsZSA9ICJU4bu3IGzhu4cgcGjhuqduIHRyxINtIiwgeCA9ICIiLCB5ID0gIiIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlKHJvdW5kKFBlcmNlbnRhZ2UsIDIpLCAiJSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgc2l6ZSA9IDQpDQpgYGANCg0KQmnhu4N1IMSR4buTIGNobyB0aOG6pXkgbmjDs20ga2jDtG5nIGNhbyB0deG7lWkgKE5vKSBjaGnhur9tIGtob+G6o25nIDc5LDYlIHThu5VuZyBz4buRIGtow6FjaCBow6BuZyAoMy44NDYvNC44MzIpLCB0cm9uZyBraGkgbmjDs20gY2FvIHR14buVaSAoWWVzKSBjaOG7iSBjaGnhur9tIGtob+G6o25nIDIwLDQlICg5ODYvNC44MzIpLiBT4buxIGNow6puaCBs4buHY2ggbOG7m24gbsOgeSBjaG8gdGjhuqV5IGPGoSBz4bufIGtow6FjaCBow6BuZyBjaOG7pyB54bq/dSB0aHXhu5ljIG5ow7NtIGtow7RuZyBjYW8gdHXhu5VpLiDEkGnhu4F1IG7DoHkgY8OzIHRo4buDIGjDoG0gw70gcuG6sW5nIGPDoWMgY2hp4bq/biBsxrDhu6NjIGNoxINtIHPDs2MgdsOgIGdp4buvIGNow6JuIGtow6FjaCBow6BuZyBuw6puIHThuq1wIHRydW5nIG5oaeG7gXUgaMahbiB2w6BvIG5ow7NtIG7DoHkgxJHhu4MgdOG7kWkgxrB1IGhp4buHdSBxdeG6oyBraW5oIGRvYW5oLiBUdXkgbmhpw6puLCBuaMOzbSBraMOhY2ggaMOgbmcgY2FvIHR14buVaSB0dXkgY2hp4bq/bSB04bu3IGzhu4cgbmjhu48gbmjGsG5nIGPDsyB0aOG7gyBjw7Mgbmh1IGPhuqd1IHbDoCBow6BuaCB2aSBraMOhYyBiaeG7h3QsIMSRw7JpIGjhu49pIGRvYW5oIG5naGnhu4dwIGPhuqduIGPDoWMgY2jDrW5oIHPDoWNoIGNoxINtIHPDs2MgY2h1ecOqbiBiaeG7h3QgxJHhu4MgdHLDoW5oIHLhu6dpIHJvIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdHJvbmcgbmjDs20ga2jDoWNoIGjDoG5nIHRp4buBbSDhuqluIG7DoHkuDQoNCiMjIyAqMy40LjIgVGjhu5FuZyBrw6ogbcO0IHThuqMgY2hvIGhhaSBiaeG6v24ga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdsOgIMSR4buZIHR14buVaSBraMOhY2ggaMOgbmcqKiANCg0KVHJvbmcgcGjhuqduIG7DoHksIHTDoWMgZ2nhuqMgdGnhur9uIGjDoG5oIHRo4buRbmcga8OqIG3DtCB04bqjIGhhaSBiaeG6v24gcXVhbiB0cuG7jW5nIGzDoCBDaHVybiAoa2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UpIHbDoCBTZW5pb3JDaXRpemVuICjEkeG7mSB0deG7lWkgY2FvIGPhu6dhIGtow6FjaCBow6BuZykuIFZp4buHYyBwaMOibiB0w61jaCB04bqnbiBzdeG6pXQgdsOgIHThu7cgbOG7hyBj4bunYSBoYWkgYmnhur9uIG7DoHkgZ2nDunAgbmjhuq1uIGRp4buHbiBz4buxIHBow6JuIGLhu5EgY+G7p2EgdOG6rXAga2jDoWNoIGjDoG5nIHRoZW8gaMOgbmggdmkgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBjxaluZyBuaMawIHnhur91IHThu5EgdHXhu5VpIHTDoWMuIFF1YSDEkcOzLCBjaMO6bmcgdGEgY8OzIHRo4buDIMSRw6FuaCBnacOhIMSRxrDhu6NjIG3hu6ljIMSR4buZIGNow6puaCBs4buHY2ggZ2nhu69hIG5ow7NtIGtow6FjaCBow6BuZyBjYW8gdHXhu5VpIHbDoCBraMO0bmcgY2FvIHR14buVaSwgxJHhu5NuZyB0aOG7nWkgcXVhbiBzw6F0IG3hu5FpIGxpw6puIGjhu4cgc8ahIGLhu5kgZ2nhu69hIMSR4buZIHR14buVaSB2w6Aga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSwgbMOgbSBjxqEgc+G7nyBjaG8gY8OhYyBwaMOibiB0w61jaCBo4buTaSBxdXkg4bufIGPDoWMgcGjhuqduIHRp4bq/cCB0aGVvLg0KDQoNCmBgYHtyfQ0KdGFibGUodmllbnRob25nJFNlbmlvckNpdGl6ZW4sIHZpZW50aG9uZyRDaHVybikgJT4lICBhZGRtYXJnaW5zKCkNCmBgYA0KYGBge3J9DQp0YWJsZV9kYXRhIDwtIHRhYmxlKHZpZW50aG9uZyRTZW5pb3JDaXRpemVuLCB2aWVudGhvbmckQ2h1cm4pDQoNCiMgQ2h1eeG7g24gYuG6o25nIGNow6lvIHNhbmcgxJHhu4tuaCBk4bqhbmcgZMOgaQ0KbG9uZ19kYXRhMyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlX2RhdGEpDQpjb2xuYW1lcyhsb25nX2RhdGEzKSA8LSBjKCJTZW5pb3JDaXRpemVuIiwgIkNodXJuIiwgImNvdW50IikNCg0KIyBW4bq9IGJp4buDdSDEkeG7kyBj4buZdA0KZ2dwbG90KGxvbmdfZGF0YTMsIGFlcyh4ID0gQ2h1cm4sIHkgPSBjb3VudCwgZmlsbCA9IENodXJuKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgpKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb3VudCksIHZqdXN0ID0gMSwgc2l6ZSA9IDIuNSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgxKSkgKw0KICBmYWNldF93cmFwKH4gU2VuaW9yQ2l0aXplbiwgc2NhbGVzID0gImZyZWVfeSIsIG5yb3cgPSAyKSArDQogIGxhYnModGl0bGUgPSAiUGjDom4gYuG7kSBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0aGVvIMSR4buZIHR14buVaSBj4bunYSBraMOhY2ggaMOgbmciLA0KICAgICAgIHggPSAiS2jDoWNoIGjDoG5nIHLhu51pIGLhu48gaOG7o3AgxJHhu5NuZyIsDQogICAgICAgeSA9ICLEkOG7mSB0deG7lWkgY+G7p2Ega2jDoWNoIGjDoG5nIiwNCiAgICAgICBmaWxsID0gIktow6FjaCBow6BuZyBy4budaSBi4buPIGjhu6NwIMSR4buTbmciKSArDQogIHRoZW1lX21pbmltYWwoKSAgDQpgYGANCg0KQmnhu4N1IMSR4buTIGNobyB0aOG6pXkgc+G7sSBwaMOibiBi4buRIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIHRoZW8gxJHhu5kgdHXhu5VpLiBUcm9uZyB04buVbmcgc+G7kSBraMOhY2ggaMOgbmcga2jDtG5nIGNhbyB0deG7lWkgKFNlbmlvckNpdGl6ZW4gPSBObyksIGPDsyAyLjY4NyBraMOhY2ggaMOgbmcga2jDtG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdsOgIDEuMTU5IGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulLiBUcm9uZyBraGkgxJHDsywgbmjDs20ga2jDoWNoIGjDoG5nIGNhbyB0deG7lWkgKFNlbmlvckNpdGl6ZW4gPSBZZXMpIGPDsyA1NTkga2jDoWNoIGjDoG5nIGtow7RuZyBy4budaSBi4buPIGThu4tjaCB24bulIHbDoCA0Mjcga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIG5ow7NtIGNhbyB0deG7lWkgKOKJiCA0MywzJSkgY2FvIGjGoW4gxJHDoW5nIGvhu4Mgc28gduG7m2kgbmjDs20ga2jDtG5nIGNhbyB0deG7lWkgKOKJiCAzMCwxJSksIGNo4bupbmcgdOG7jyB54bq/dSB04buRIHR14buVaSB0w6FjIGPDsyB0aOG7gyBsacOqbiBxdWFuIMSR4bq/biBow6BuaCB2aSBy4budaSBi4buPIGThu4tjaCB24bulLg0KDQrEkOG7gyBtaW5oIGjhu41hIHRy4buxYyBxdWFuIMSR4buZIHR14buVaSBj4bunYSBraMOhY2ggaMOgbmcsIHTDtGkgdGnhur9uIGjDoG5oIHbhur0gYmnhu4N1IMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIHThu6tuZyBnacOhIHRy4buLIGPhu6dhIG5ow7NtIFNlbmlvckNpdGl6ZW4uDQoNCmBgYHtyfQ0KdGFibGVfZGF0YTMgPC0gcm91bmQocHJvcC50YWJsZSh0YWJsZV9kYXRhKSoxMDAsMikgDQp0YWJsZV9kYXRhMw0KYGBgDQpgYGB7cn0NCg0KIyBDaHV54buDbiDEkeG7lWkgZOG7ryBsaeG7h3UgdGjDoG5oIGThuqFuZyBkw6BpIMSR4buDIGThu4UgduG6vSBiaeG7g3UgxJHhu5MNCnRhYmxlX2RhdGEzIDwtIGFzLmRhdGEuZnJhbWUudGFibGUodGFibGVfZGF0YTMpDQpjb2xuYW1lcyh0YWJsZV9kYXRhMykgPC0gYygiR3JvdXAiLCAiTGV2ZWwiLCAiUGVyY2VudGFnZSIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MNCmdncGxvdCh0YWJsZV9kYXRhMywgYWVzKHggPSBMZXZlbCwgeSA9IFBlcmNlbnRhZ2UsIGZpbGwgPSBMZXZlbCkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gUGVyY2VudGFnZSksIHZqdXN0ID0gMSwgc2l6ZSA9IDIuNSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgxKSkgKw0KICBmYWNldF93cmFwKH4gR3JvdXAsIHNjYWxlcyA9ICJmcmVlX3kiLCBucm93ID0gMikgKw0KICBsYWJzKHRpdGxlID0gIsSQ4buTIHRo4buLIHBo4bqnbiB0csSDbSB0aGVvIGJp4buDdSBoaeG7h24geWVzLCBubyBj4bunYSBraMOhY2ggaMOgbmcgdOG7qyBi4buPIGThu4tjaCB24bulIHbDoCBjw6FjIGxv4bqhaSBo4bujcCDEkeG7k25nIiwNCiAgICAgICB4ID0gIkPDoWMgbG/huqFpIGjhu6NwIMSR4buTbmciLA0KICAgICAgIHkgPSAiUGjhuqduIHRyxINtIiwNCiAgICAgICBmaWxsID0gIkJp4buDdSBoaeG7h24iKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIk5vIiA9ICJza3libHVlIiwgIlllcyIgPSAicGluayIpKSArIA0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpCaeG7g3UgxJHhu5MgbWluaCBo4buNYSB04bu3IGzhu4cgcGjhuqduIHRyxINtIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgZ2nhu69hIGhhaSBuaMOzbS4gVuG7m2kgbmjDs20ga2jDtG5nIGNhbyB0deG7lWksIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgZHV5IHRyw6wgZOG7i2NoIHbhu6UgKE5vKSBsw6AgMzMsNjclLCB0cm9uZyBraGkgdOG7tyBs4buHIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKFllcykgbMOgIDIyLDU2JS4gTmfGsOG7o2MgbOG6oWksIHRyb25nIG5ow7NtIGNhbyB0deG7lWksIHThu7cgbOG7hyBkdXkgdHLDrCBk4buLY2ggduG7pSBjaOG7iSDEkeG6oXQgMzMsNTElLCBjw7JuIHThu7cgbOG7hyBy4budaSBi4buPIGzDoCAxMCwyNiUuIE5ow6xuIGNodW5nLCBr4bq/dCBxdeG6oyB0aOG7kW5nIGvDqiBuw6B5IGNobyB0aOG6pXkgbmjDs20ga2jDoWNoIGjDoG5nIGNhbyB0deG7lWkgY8OzIHh1IGjGsOG7m25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6Ugbmhp4buBdSBoxqFuLCBsw6AgbeG7mXQgY2jhu4kgYsOhbyBxdWFuIHRy4buNbmcgY+G6p24geGVtIHjDqXQgdHJvbmcgY8OhYyBtw7QgaMOsbmggcGjDom4gdMOtY2ggQ2h1cm4uDQoNCiMjIyAqKjMuNC4zIFBow6JuIHTDrWNoIFJlbGF0aXZlIFJpc2sgZ2nhu69hIMSR4buZIHR14buVaSBjYW8gY+G7p2Ega2jDoWNoIGjDoG5nIHbDoCBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSoqDQoNClRyb25nIHBo4bqnbiBuw6B5LCBjaOG7iSBz4buRIFJlbGF0aXZlIFJpc2sgKFJSKSDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyBzbyBzw6FuaCBt4bupYyDEkeG7mSBy4bunaSBybyBy4budaSBi4buPIGThu4tjaCB24bulIGdp4buvYSBoYWkgbmjDs20ga2jDoWNoIGjDoG5nOiBuaMOzbSBjYW8gdHXhu5VpIChTZW5pb3JDaXRpemVuID0gWWVzKSB2w6AgbmjDs20ga2jDtG5nIGNhbyB0deG7lWkgKFNlbmlvckNpdGl6ZW4gPSBObw0KDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnJyNDwtIHJpc2tyYXRpbyh0YWJsZV9kYXRhKQ0KcnI0DQpgYGANCg0KQuG6o25nIGvhur90IHF14bqjIGNobyB0aOG6pXkgUmVsYXRpdmUgUmlzayAoUlIpIGPhu6dhIG5ow7NtIGtow6FjaCBow6BuZyBjYW8gdHXhu5VpIChZZXMpIGzDoCAxLjQzNy4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIGNhbyB0deG7lWkgY2FvIGfhuqVwIDEuNDM3IGzhuqduIHNvIHbhu5tpIG5ow7NtIGtow6FjaCBow6BuZyBraMO0bmcgY2FvIHR14buVaS5Ow7NpIGPDoWNoIGtow6FjLCBuaMOzbSBraMOhY2ggaMOgbmcgY2FvIHR14buVaSBjw7Mgbmd1eSBjxqEgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBjYW8gaMahbiDEkcOhbmcga+G7gy4gR2nDoSB0cuG7iyBwLXZhbHVlIGPhu6dhIGtp4buDbSDEkeG7i25oIENoaS1zcXVhcmUgbMOgIDMuOTA4NzAzZS0xNSwgcuG6pXQgbmjhu48gKHAgPCAwLjAwMSksIGNo4bupbmcgdOG7jyBz4buxIGtow6FjIGJp4buHdCBnaeG7r2EgaGFpIG5ow7NtIGzDoCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSBiaeG6v24gU2VuaW9yQ2l0aXplbiBjw7Mg4bqjbmggaMaw4bufbmcgcsO1IHLhu4d0IMSR4bq/biBow6BuaCB2aSBy4budaSBi4buPIGThu4tjaCB24bulLCB2w6AgbmjDs20ga2jDoWNoIGjDoG5nIGNhbyB0deG7lWkgbMOgIG5ow7NtIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgaMahbi4NCg0KIyMjICoqMy40LjQgUGjDom4gdMOtY2ggT2RkIFJhdGlvIGdp4buvYSDEkeG7mSB0deG7lWkgY+G7p2Ega2jDoWNoIGjDoG5nIHbDoCBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSoqDQoNClRyb25nIHBo4bqnbiBuw6B5LCBuZ2hpw6puIGPhu6l1IHPhur0gdGnhur9uIGjDoG5oIHTDrW5oIE9kZHMgUmF0aW8gZ2nhu69hIMSR4buZIHR14buVaSBj4bunYSBraMOhY2ggaMOgbmcgdsOgIGJp4bq/biBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB2aeG7hW4gdGjDtG5nIChDaHVybikuIFZp4buHYyB0w61uaCB0b8OhbiBPUiBz4bq9IGdpw7pwIHjDoWMgxJHhu4tuaCDEkeG7mSB0deG7lWkgbsOgbyBsw6BtIHTEg25nIGhv4bq3YyBnaeG6o20ga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSwgcXVhIMSRw7MgY3VuZyBj4bqlcCB0aMO0bmcgdGluIHF1YW4gdHLhu41uZyDEkeG7gyBkb2FuaCBuZ2hp4buHcCDEkcawYSByYSBjw6FjIGNoaeG6v24gbMaw4bujYyBnaeG7ryBjaMOibiBraMOhY2ggaMOgbmcgcGjDuSBo4bujcC4NCg0KDQpgYGB7cn0NCm9yNCA8LSBvZGRzcmF0aW8odGFibGVfZGF0YSkNCm9yNA0KYGBgDQoNCkvhur90IHF14bqjIHBow6JuIHTDrWNoIGNobyB0aOG6pXkgT2RkcyBSYXRpbyAoT1IpIGPhu6dhIG5ow7NtIGtow6FjaCBow6BuZyBjYW8gdHXhu5VpICgxKSBsw6AgMS43Ny4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIG9kZHMgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBj4bunYSBraMOhY2ggaMOgbmcgY2FvIHR14buVaSBjYW8gaMahbiBraG/huqNuZyAxLjc3IGzhuqduIHNvIHbhu5tpIG5ow7NtIGtow6FjaCBow6BuZyBraMO0bmcgY2FvIHR14buVaS4gR2nDoSB0cuG7iyBwLXZhbHVlIHLhuqV0IG5o4buPIChwIDwgMC4wMDEpLCBraOG6s25nIMSR4buLbmggc+G7sSBraMOhYyBiaeG7h3QgbsOgeSBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLiBOw7NpIGPDoWNoIGtow6FjLCB2aeG7h2MgdGh14buZYyBuaMOzbSBraMOhY2ggaMOgbmcgY2FvIHR14buVaSBsw6BtIHTEg25nIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UsIHbDoCBiaeG6v24gU2VuaW9yQ2l0aXplbiBsw6AgbeG7mXQgeeG6v3UgdOG7kSDEkcOhbmcgY2jDuiDDvSB0cm9uZyB2aeG7h2MgZOG7sSDEkW/DoW4gaMOgbmggdmkga2jDoWNoIGjDoG5nLg0KDQojIyMgKiozLjQuNSBUaOG7kW5nIGvDqiBzdXkgZGnhu4VuKioNCg0KIyMjIyAqKjMuNC41LjEgS2nhu4NtIMSR4buLbmggdMOtbmggxJHhu5ljIGzhuq1wKioNCg0KxJDhu4Mga2nhu4NtIHRyYSB4ZW0gYmnhur9uIMSR4buZIHR14buVaSBjYW8gY+G7p2Ega2jDoWNoIGjDoG5nICgpIHbDoCBow6BuaCB2aSBy4budaSBi4buPIGThu4tjaCB24bulIChDaHVybikgY8OzIG3hu5FpIGxpw6puIGjhu4cgduG7m2kgbmhhdSBoYXkga2jDtG5nLCBuZ2hpw6puIGPhu6l1IMOhcCBk4bulbmcga2nhu4NtIMSR4buLbmggQ2hpLXNxdWFyZS4NCg0KS2nhu4NtIMSR4buLbmggbsOgeSDEkcaw4bujYyB0aGnhur90IGzhuq1wIHbhu5tpIGdp4bqjIHRodXnhur90OiANCg0KJCQNClxsZWZ0XHsNClxiZWdpbnthcnJheX17bGx9DQpIXzA6ICYgXHRleHR7Qmnhur9uIENodXJuIChraMOhY2ggaMOgbmcgdOG7qyBi4buPIGThu4tjaCB24bulKSB2w6AgYmnhur9uIFNlbmlvckNpdGl6ZW4gKMSR4buZIHR14buVaSBjYW8pIGtow7RuZyBjw7MgbeG7kWkgcXVhbiBo4buHIHbhu5tpIG5oYXUufSAgXFxcXA0KSF8xOiAmIFx0ZXh0e0Jp4bq/biBDaHVybiAoa2jDoWNoIGjDoG5nIHThu6sgYuG7jyBk4buLY2ggduG7pSkgdsOgIGJp4bq/biBTZW5pb3JDaXRpemVuICjEkeG7mSB0deG7lWkgY2FvdCkgY8OzIG3hu5FpIHF1YW4gaOG7hyB24bubaSBuaGF1Ln0gXA0KXGVuZHthcnJheX0NClxyaWdodC4NCiQkDQoNCmBgYHtyfQ0KIyBLaeG7g20gxJHhu4tuaA0KY2hpc3FfcmVzdWx0IDwtIGNoaXNxLnRlc3QodGFibGVfZGF0YSkNCg0KIyBJbiBr4bq/dCBxdeG6ow0KY2hpc3FfcmVzdWx0DQpgYGANCg0KUXVhIGvhur90IHF14bqjIGtp4buDbSDEkeG7i25oOiBW4bubaSBt4bupYyDDvSBuZ2jEqWEgMC4wNSwgdsOsIHAtdmFsdWUgPSA1LjI5ZS0xNSA8IDAuMDUsIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCAkSF8wJC4gVuG6rXkgZ2nhu69hIGJp4bq/biBDaHVybiB2w6AgYmnhur9uIFNlbmlvckNpdGl6ZW4gdOG7k24gdOG6oWkgbeG7kWkgcXVhbiBo4buHLg0KDQojIyMjICoqMy40LjUuMiBLaG/huqNuZyDGsOG7m2MgbMaw4bujbmcgdOG7tyBs4buHKioNCg0KKirGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIGPDsyDEkeG7mSB0deG7lWkgY2FvKiogDQoNCmBgYHtyfQ0KcHJvcC50ZXN0KHggPSB0YWJsZV9kYXRhWyIxIiwgIlllcyJdLCBuID0gc3VtKCB0YWJsZV9kYXRhWyIxIiwgXSksIHAgPSAwLjUsIGNvcnJlY3QgPSBUUlVFKQ0KYGBgDQoNCkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oIHThu7cgbOG7hyBt4buZdCBt4bqrdSBjaG8gdGjhuqV5IHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIChDaHVybikgY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIGNhbyB0deG7lWkgxJHGsOG7o2MgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIDQzLjMwJS4gS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gdOG7tyBs4buHIG7DoHkgbuG6sW0gdHJvbmcga2hv4bqjbmcgNDAsMTklIMSR4bq/biA0Ni40NyUsIG5naMSpYSBsw6AgdOG7tyBs4buHIHRo4buxYyBz4buxIGPhu6dhIHThu5VuZyB0aOG7gyBn4bqnbiBuaMawIGNo4bqvYyBjaOG6r24gbuG6sW0gdHJvbmcga2hv4bqjbmcgbsOgeS4gR2nDoSB0cuG7iyBwLXZhbHVlID0gMy4wMjFlLTA1IGNobyB0aOG6pXkgc+G7sSBraMOhYyBiaeG7h3QgZ2nhu69hIHThu7cgbOG7hyDGsOG7m2MgbMaw4bujbmcgdsOgIGdpw6EgdHLhu4sgZ2nhuqMgdGh1eeG6v3QgMC41ICg1MCUpIGzDoCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLCB04bupYyBsw6AgdOG7tyBs4buHIHLhu51pIGLhu48gY+G7p2Ega2jDoWNoIGjDoG5nIGNhbyB0deG7lWkgdGjhuqVwIGjGoW4gxJHDoW5nIGvhu4MgNTAlLiBL4bq/dCBxdeG6oyBuw6B5IHBo4bqjbiDDoW5oIHLhurFuZyBj4bupIDEwIGtow6FjaCBow6BuZyBjYW8gdHXhu5VpIHRow6wgY8OzIGtob+G6o25nIDQgbmfGsOG7nWkgcuG7nWkgYuG7jyBk4buLY2ggduG7pS4NCg0KYGBge3J9DQpwcm9wLnRlc3QoeCA9IHRhYmxlX2RhdGFbIjAiLCAiWWVzIl0sIG4gPSBzdW0oIHRhYmxlX2RhdGFbIjAiLCBdKSwgcCA9IDAuNSwgY29ycmVjdCA9IFRSVUUpDQpgYGANCg0KS+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmggdOG7tyBs4buHIG3hu5l0IG3huqt1IGNobyB0aOG6pXkgdOG7tyBs4buHIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKENodXJuKSBj4bunYSBuaMOzbSBraMOhY2ggaMOgbmcga2jDtG5nIGNhbyB0deG7lWkgxJHGsOG7o2MgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIDMwLjE0JS4gS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gdOG7tyBs4buHIG7DoHkgbuG6sW0gdHJvbmcga2hv4bqjbmcgMjguNjklIMSR4bq/biAzMS42MiUsIG5naMSpYSBsw6AgdOG7tyBs4buHIHRo4buxYyBz4buxIGPhu6dhIHThu5VuZyB0aOG7gyBn4bqnbiBuaMawIGNo4bqvYyBjaOG6r24gbuG6sW0gdHJvbmcga2hv4bqjbmcgbsOgeS4gR2nDoSB0cuG7iyBwLXZhbHVlIDwgMi4yZS0xNiBjaG8gdGjhuqV5IHPhu7Ega2jDoWMgYmnhu4d0IGdp4buvYSB04bu3IGzhu4cgxrDhu5tjIGzGsOG7o25nIHbDoCBnacOhIHRy4buLIGdp4bqjIHRodXnhur90IDAuNSAoNTAlKSBsw6AgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiwgdOG7qWMgbMOgIHThu7cgbOG7hyBy4budaSBi4buPIGPhu6dhIGtow6FjaCBow6BuZyBraMO0bmcgY2FvIHR14buVaSB0aOG6pXAgaMahbiDEkcOhbmcga+G7gyA1MCUuIEvhur90IHF14bqjIG7DoHkgcGjhuqNuIMOhbmggcuG6sW5nIGPhu6kgMTAga2jDoWNoIGjDoG5nIGtow7RuZyBjYW8gdHXhu5VpIHRow6wgY8OzIGtob+G6o25nIDMgbmfGsOG7nWkgcuG7nWkgYuG7jyBk4buLY2ggduG7pS4NCg0KIyMjICoqMy40LjYgTcO0IGjDrG5oIGjhu5NpIHF1eSBjaG8gZOG7ryBsaeG7h3Ugbmjhu4sgcGjDom4qKg0KDQojIyMjICoqMy40LjYuMSBNw7QgaMOsbmggbG9naXQqKg0KDQoNCmBgYHtyfQ0KbG9nNSA8LSBnbG0oZmFjdG9yKENodXJuKSB+U2VuaW9yQ2l0aXplbiwgZGF0YSA9IHZpZW50aG9uZywgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpKQ0Kc3VtbWFyeShsb2c1KQ0KYGBgDQoNCg0KS+G6v3QgcXXhuqMgbcO0IGjDrG5oIGxvZ2l0IGNobyB0aOG6pXkgaOG7hyBz4buRIGNo4bq3biBcKC0wLjg0MDg3XCkgdsOgIGjhu4cgc+G7kSBj4bunYSBiaeG6v24gU2VuaW9yQ2l0aXplbiBcKDAuNTcxNTBcKSDEkeG7gXUgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiBy4bqldCBjYW8gKHAgPCAwLjAwMSkuIEjhu4cgc+G7kSBkxrDGoW5nIGPhu6dhIFNlbmlvckNpdGl6ZW4gY2jhu4kgcmEgcuG6sW5nIGtow6FjaCBow6BuZyBs4bubbiB0deG7lWkgKFNlbmlvckNpdGl6ZW4gPSAxKSBjw7Mga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBjYW8gaMahbiBuaMOzbSBraMOhY2ggaMOgbmcgdHLhursgKFNlbmlvckNpdGl6ZW4gPSAwKS4gVOG7tyBs4buHIGto4bqjIG7Eg25nIHLhu51pIGLhu48gY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIGzhu5tuIHR14buVaSBjYW8gaMahbiBraG/huqNuZzoNClxbDQplXnswLjU3MTUwfSBcYXBwcm94IDEuNzcgXCwgXHRleHR7bOG6p259Lg0KXF0NCg0KROG7sWEgdHLDqm4gY8O0bmcgdGjhu6ljIHjDoWMgc3XhuqV0Og0KXFsNCnAgPSBcZnJhY3tlXntcZXRhfX17MSArIGVee1xldGF9fSwNClxdDQp0YSB0w61uaCDEkcaw4bujYyB4w6FjIHN14bqldCBy4budaSBi4buPIGPhu6dhIG5ow7NtIGtow6FjaCBow6BuZyB0cuG6uzoNClxbDQpwX3swfSA9IFxmcmFje2Veey0wLjg0MDg3fX17MSArIGVeey0wLjg0MDg3fX0gXGFwcHJveCAwLjMwMSBcLCAoMzAuMVwlKSwNClxdDQp2w6AgY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIGzhu5tuIHR14buVaToNClxbDQpwX3sxfSA9IFxmcmFje2Veey0wLjg0MDg3ICsgMC41NzE1MH19ezEgKyBlXnstMC44NDA4NyArIDAuNTcxNTB9fSBcYXBwcm94IDAuNDMwIFwsICg0My4wXCUpLg0KXF0NCg0KIyMjIyAqKjMuNC42LjIgTcO0IGjDrG5oIHByb2JpdCoqDQoNCmBgYHtyfQ0KcHJvNTwtIGdsbShmYWN0b3IoQ2h1cm4pIH4gU2VuaW9yQ2l0aXplbiwgZGF0YSA9IHZpZW50aG9uZywgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdwcm9iaXQnKSkNCnN1bW1hcnkocHJvNSApDQpgYGANCg0KS+G6v3QgcXXhuqMgxrDhu5tjIGzGsOG7o25nIG3DtCBow6xuaCBQcm9iaXQgY2hvIHRo4bqleSBiaeG6v24gKipTZW5pb3JDaXRpemVuKiogY8OzIOG6o25oIGjGsOG7n25nIMSRw6FuZyBr4buDIMSR4bq/biBraOG6oyBuxINuZyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoKipDaHVybioqKS4gUGjGsMahbmcgdHLDrG5oIG3DtCBow6xuaCDEkcaw4bujYyBtw7QgdOG6oyBuaMawIHNhdTogIA0KDQokJA0KUChZPTF8U2VuaW9yQ2l0aXplbikgPSBcUGhpKC0wLjUyMDUyICsgMC4zNTE5MyBcY2RvdCBTZW5pb3JDaXRpemVuKSwNCiQkDQoNCnRyb25nIMSRw7MgXChcUGhpKFxjZG90KVwpIGzDoCBow6BtIHBow6JuIHBo4buRaSB0w61jaCBsxal5IGNodeG6qW4gY2h14bqpbiBow7NhLiBLaGkga2jDoWNoIGjDoG5nIGtow7RuZyBwaOG6o2kgbMOgIG5nxrDhu51pIGNhbyB0deG7lWkgKFNlbmlvckNpdGl6ZW4gPSAwKSwgZ2nDoSB0cuG7iyB0dXnhur9uIHTDrW5oIGzDoCBcKHogPSAtMC41MjA1MlwpIHbDoCB4w6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIGzDoDogIA0KDQpcWw0KUChZPTEgfCBTZW5pb3JDaXRpemVuID0gMCkgPSBcUGhpKC0wLjUyMDUyKSBcYXBwcm94IDAuMzAxIFwgKDMwLjFcJSkuDQpcXQ0KDQpOZ8aw4bujYyBs4bqhaSwga2hpIGtow6FjaCBow6BuZyBsw6AgbmfGsOG7nWkgY2FvIHR14buVaSAoU2VuaW9yQ2l0aXplbiA9IDEpLCBnacOhIHRy4buLIFwoeiA9IC0wLjUyMDUyICsgMC4zNTE5MyA9IC0wLjE2ODU5XCksIHbDoCB4w6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIHTEg25nIGzDqm46ICANCg0KXFsNClAoWT0xIHwgU2VuaW9yQ2l0aXplbiA9IDEpID0gXFBoaSgtMC4xNjg1OSkgXGFwcHJveCAwLjQzMyBcICg0My4zXCUpLg0KXF0NCg0KS2jDoWNoIGjDoG5nIGzDoCBuZ8aw4budaSBjYW8gdHXhu5VpIChTZW5pb3JDaXRpemVuID0gMSkgY8OzIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY2FvIGjGoW4gKDQzLjMlKSBzbyB24bubaSBraMOhY2ggaMOgbmcga2jDtG5nIHBo4bqjaSBuZ8aw4budaSBjYW8gdHXhu5VpICgzMC4xJSkuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IG5ow7NtIGtow6FjaCBow6BuZyBjYW8gdHXhu5VpIGPDsyBt4bupYyDEkeG7mSBy4bunaSBybyBy4budaSBi4buPIGThu4tjaCB24bulIGNhbyBoxqFuIMSRw6FuZyBr4buDLg0KDQojIyMjICoqMy40LjYuMyBNw7QgaMOsbmggY2xvZ2xvZyoqDQoNCmBgYHtyfQ0KY2xvNSA8LSBnbG0oZmFjdG9yKENodXJuKSB+IFNlbmlvckNpdGl6ZW4sIGRhdGEgPSB2aWVudGhvbmcsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnY2xvZ2xvZycpKQ0Kc3VtbWFyeShjbG81KQ0KYGBgDQoNCkvhur90IHF14bqjIMaw4bubYyBsxrDhu6NuZyBtw7QgaMOsbmggQ29tcGxlbWVudGFyeSBMb2ctTG9nIChjbG9nbG9nKSBjaG8gdGjhuqV5IGJp4bq/biBTZW5pb3JDaXRpemVuIGPDsyDhuqNuaCBoxrDhu59uZyDEkcOhbmcga+G7gyDEkeG6v24ga2jhuqMgbsSDbmcga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgQ2h1cm4gduG7m2kgbeG7qWMgw70gbmdoxKlhIHRo4buRbmcga8OqIHLhuqV0IGNhbyAoXChwID0gMS4wOGUtMTVcKSkuIFBoxrDGoW5nIHRyw6xuaCBtw7QgaMOsbmggxJHGsOG7o2MgeMOhYyDEkeG7i25oIG5oxrAgc2F1OiAgDQoNCiQkDQpcbG5bLVxsbigxIC0gUChZPTF8U2VuaW9yQ2l0aXplbikpXSA9IC0xLjAyNTUyICsgMC40NTkwMiBcY2RvdCBTZW5pb3JDaXRpemVuLg0KJCQNCktoaSBraMOhY2ggaMOgbmcga2jDtG5nIHBo4bqjaSBsw6AgbmfGsOG7nWkgY2FvIHR14buVaSAoU2VuaW9yQ2l0aXplbiA9IDApLCBnacOhIHRy4buLIHR1eeG6v24gdMOtbmggbMOgIFwoXGV0YSA9IC0xLjAyNTUyXCkgdsOgIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgbMOgOg0KXFsNClAoWT0xfFNlbmlvckNpdGl6ZW49MCkgPSAxIC0gXGV4cFstXGV4cCgtMS4wMjU1MildIFxhcHByb3ggMC4yNjYgXCAoMjYuNlwlKS4NClxdDQpUcm9uZyBraGkgxJHDsywgbuG6v3Uga2jDoWNoIGjDoG5nIGzDoCBuZ8aw4budaSBjYW8gdHXhu5VpIChTZW5pb3JDaXRpemVuID0gMSksIGdpw6EgdHLhu4sgXChcZXRhXCkgdMSDbmcgbMOqbiBcKC0wLjU2NjUwXCkgdsOgIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdMSDbmcgbMOqbjoNClxbDQpQKFk9MXxTZW5pb3JDaXRpemVuPTEpID0gMSAtIFxleHBbLVxleHAoLTAuNTY2NTApXSBcYXBwcm94IDAuMzY4IFwgKDM2LjhcJSkuDQpcXQ0KSOG7hyBz4buRIGTGsMahbmcgXCgwLjQ1OTAyXCkga2jhurNuZyDEkeG7i25oIG5ow7NtIGtow6FjaCBow6BuZyBjYW8gdHXhu5VpIGPDsyBraOG6oyBuxINuZyBy4budaSBi4buPIGThu4tjaCB24bulIGNhbyBoxqFuIHNvIHbhu5tpIG5ow7NtIGtow6FjaCBow6BuZyB0cuG6uy4gTmjDrG4gY2h1bmcsIGvhur90IHF14bqjIG7DoHkgY2hvIHRo4bqleSBiaeG6v24gU2VuaW9yQ2l0aXplbiBsw6AgeeG6v3UgdOG7kSBxdWFuIHRy4buNbmcgdHJvbmcgdmnhu4djIGThu7EgxJFvw6FuIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UsIHbDoCBtw7QgaMOsbmggY2xvZ2xvZyBwaMO5IGjhu6NwIGtoaSB4w6FjIHN14bqldCBz4buxIGtp4buHbiBraMO0bmcgxJHhu5FpIHjhu6luZy4NCg0KIyMjICoqMy40LjcgxJDDoW5oIGdpw6EgbcO0IGjDrG5oKioNCg0KU2F1IGtoaSB0aeG6v24gaMOgbmggxrDhu5tjIGzGsOG7o25nIGJhIG3DtCBow6xuaCBo4buTaSBxdXkgbmjhu4sgcGjDom4gZ+G7k20gbG9naXQsIHByb2JpdCB2w6AgY2xvZ2xvZywgYsaw4bubYyB0aeG6v3AgdGhlbyBsw6AgxJHDoW5oIGdpw6EgdsOgIHNvIHPDoW5oIG3hu6ljIMSR4buZIHBow7kgaOG7o3AgY+G7p2EgY8OhYyBtw7QgaMOsbmggbsOgeS4gVmnhu4djIMSRw6FuaCBnacOhIMSRxrDhu6NjIHRo4buxYyBoaeG7h24gZOG7sWEgdHLDqm4gY8OhYyBjaOG7iSB0acOqdSB0aOG7kW5nIGvDqiBuaMawIGdpw6EgdHLhu4sgQUlDLCBCSUMsIGjhu4cgc+G7kSBCcmllciBTY29yZSB2w6AgbWEgdHLhuq1uIG5o4bqnbSBs4bqrbi4gTmdvw6BpIHJhLCBraOG6oyBuxINuZyBk4buxIGLDoW8geMOhYyBzdeG6pXQgY+G7p2EgdOG7q25nIG3DtCBow6xuaCDEkeG7kWkgduG7m2kgY8OhYyB0csaw4budbmcgaOG7o3AgZ2nhuqMgxJHhu4tuaCBj4bulIHRo4buDIGPFqW5nIMSRxrDhu6NjIHhlbSB4w6l0IMSR4buDIGzhu7FhIGNo4buNbiBtw7QgaMOsbmggcGjDuSBo4bujcCBuaOG6pXQuDQoNCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgc28gc8OhbmgNCm1vZGVsX2V2YWw0PC0gZGF0YS5mcmFtZSgNCiAgTcO0X2jDrG5oID0gYygiTG9naXQiLCAiUHJvYml0IiwgIkNsb2dsb2ciKSwNCiAgQUlDID0gYyhBSUMobG9nNSksIEFJQyhwcm81KSwgQUlDKGNsbzUpKSwNCiAgQklDID0gYyhCSUMobG9nNSksIEJJQyhwcm81KSwgQklDKGNsbzUpKSwNCiAgQnJpZXJfU2NvcmUgPSBjKEJyaWVyU2NvcmUobG9nNSksIEJyaWVyU2NvcmUocHJvNSksIEJyaWVyU2NvcmUoY2xvNSkpDQopDQprYWJsZShtb2RlbF9ldmFsNCwgYWxpZ24gPSAiYyIsIGNhcHRpb24gPSAiU28gc8OhbmggY8OhYyBjaOG7iSBz4buRIMSRw6FuaCBnacOhIG3DtCBow6xuaCIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAiY2VudGVyIiwgZm9udF9zaXplID0gMTQpDQpgYGANCg0KU2F1IGtoaSDGsOG7m2MgbMaw4bujbmcgYmEgbcO0IGjDrG5oIGxvZ2l0LCBwcm9iaXQgdsOgIGNsb2dsb2csIGvhur90IHF14bqjIGNobyB0aOG6pXkgY8OhYyBjaOG7iSBz4buRIEFJQywgQklDIHbDoCBCcmllciBTY29yZSBj4bunYSBiYSBtw7QgaMOsbmggaG/DoG4gdG/DoG4gZ2nhu5FuZyBuaGF1IChBSUMgPSA2MDYwLjcwOCwgQklDID0gNjA3My42NzQsIEJyaWVyIFNjb3JlID0gMC4yMTc3KSwgcGjhuqNuIMOhbmggbeG7qWMgxJHhu5kgcGjDuSBo4bujcCB24buBIG3hurd0IHRo4buRbmcga8OqIHTGsMahbmcgxJHGsMahbmcuDQoNCioqTWEgdHLhuq1uIG5o4bqnbSBs4bqrbioqDQoNCi0gTcO0IGjDrG5oIGxvZ2l0DQoNCmBgYHtyfQ0KcHJlZF9sb2dpdGxvZyA8LSBpZmVsc2UocHJlZGljdChsb2c1LCB0eXBlID0gInJlc3BvbnNlIikgPj0gMC41LCAiWWVzIiwgIk5vIikNCmFjdHVhbGxvZyA8LSB2aWVudGhvbmckQ2h1cm4NCmNtX2xvZ2l0bG9nIDwtIGNvbmZ1c2lvbk1hdHJpeChmYWN0b3IocHJlZF9sb2dpdGxvZyksIGFjdHVhbGxvZywgcG9zaXRpdmUgPSAiWWVzIikNCmNtX2xvZ2l0bG9nDQpgYGANCg0KLSBNw7QgaMOsbmggcHJvYml0DQoNCmBgYHtyfQ0KcHJlZF9sb2dpdHBybyA8LSBpZmVsc2UocHJlZGljdChwcm81LCB0eXBlID0gInJlc3BvbnNlIikgPj0gMC41LCAiWWVzIiwgIk5vIikNCmFjdHVhbHBybyA8LSB2aWVudGhvbmckQ2h1cm4NCmNtX2xvZ2l0cHJvIDwtIGNvbmZ1c2lvbk1hdHJpeChmYWN0b3IocHJlZF9sb2dpdHBybyksIGFjdHVhbHBybywgcG9zaXRpdmUgPSAiWWVzIikNCmNtX2xvZ2l0cHJvDQpgYGANCg0KLSBNw7QgaMOsbmggY2xvZ2xvZw0KDQpgYGB7cn0NCnByZWRfbG9naXRjbG8gPC0gaWZlbHNlKHByZWRpY3QoY2xvNSwgdHlwZSA9ICJyZXNwb25zZSIpID49IDAuNSwgIlllcyIsICJObyIpDQphY3R1YWxjbG8gPC0gdmllbnRob25nJENodXJuDQpjbV9sb2dpdGNsbyA8LSBjb25mdXNpb25NYXRyaXgoZmFjdG9yKHByZWRfbG9naXRjbG8pLCBhY3R1YWxjbG8sIHBvc2l0aXZlID0gIlllcyIpDQpjbV9sb2dpdGNsbw0KYGBgDQoNCg0KIyMgKiozLjUgUGjDom4gdMOtY2ggc+G7sSB0w6FjIMSR4buZbmcgY+G7p2Ega2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIMSR4bq/biB2aeG7h2Mga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UqKg0KDQojIyMgKiozLjUuMSBUaOG7kW5nIGvDqiBtw7QgdOG6oyBiaeG6v24gY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgKERlcGVuZGVudHMpKioNCg0KQmnhur9uIERlcGVuZGVudHMgcGjhuqNuIMOhbmggdMOsbmggdHLhuqFuZyBraMOhY2ggaMOgbmcgY8OzIGhheSBraMO0bmcgbmfGsOG7nWkgcGjhu6UgdGh14buZYyAoY29uIGPDoWkgaG/hurdjIG5nxrDhu51pIGPhuqduIGNoxINtIHPDs2MpLiBUaOG7kW5nIGvDqiBtw7QgdOG6oyBkxrDhu5tpIMSRw6J5IGNobyB0aOG6pXkgcGjDom4gYuG7kSBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyB0aGVvIGhhaSBuaMOzbTogY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgdsOgIGtow7RuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYywgZ2nDunAgbmjhuq1uIGRp4buHbiB04bu3IGzhu4cga2jDoWNoIGjDoG5nIHRodeG7mWMgdOG7q25nIG5ow7NtIHbDoCBsw6BtIGPGoSBz4bufIMSRw6FuaCBnacOhIHPhu7Ega2jDoWMgYmnhu4d0IHbhu4Ega2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBnaeG7r2EgY8OhYyBuaMOzbSBuw6B5Lg0KDQpgYGB7cn0NCmQ8LXRhYmxlKHZpZW50aG9uZyREZXBlbmRlbnRzKSANCmQNCiMgQ2h1eeG7g24gdGjDoG5oIGRhdGEgZnJhbWUgduG7m2kgMyBj4buZdDogQ2h1cm4gfCBT4buRIGzGsOG7o25nIHwgU3VtIChU4buVbmcgY+G7mW5nKQ0KZGZkIDwtIGRhdGEuZnJhbWUoDQogICBJbnRlcm5ldFNlcnZpY2U9IGMoIk5vIiwgIlllcyIpLA0KICBTb19sdW9uZyA9IGFzLm51bWVyaWMoZCkpDQoNCiMgSW4gcmEgYuG6o25nIMSR4bq5cCwgY8SDbiBnaeG7r2ENCmthYmxlKGRmZCwgYWxpZ24gPSAiYyIsIGNvbC5uYW1lcyA9IGMoIkRlcGVuZGVudHMiLCAiU+G7kSBsxrDhu6NuZyIpKSAgJT4lDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJjZW50ZXIiLCBmb250X3NpemUgPSAxNCkgJT4lDQogIGNvbHVtbl9zcGVjKDEsIHdpZHRoID0gIjRjbSIpICU+JSAgIyDEkOG7mSBy4buZbmcgY+G7mXQgMQ0KICBjb2x1bW5fc3BlYygyLCB3aWR0aCA9ICIzY20iKSAgICAgICMgxJDhu5kgcuG7mW5nIGPhu5l0IDINCg0KI2zhuq1wIGLhuqNuZyB04bqnbiBz4buRIGPhu6dhIGPhu5l0IENodXJuIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgxJHGsOG7o2MgdMOqbiB2aWVudGhvbmcgdsOgIHRow6ptIGPhu5l0IHTDtG5nIHbDoG8gY3Xhu5FpIGLhuqNuZw0KYGBgDQoNCsSQ4buDIG1pbmggaOG7jWEgdHLhu7FjIHF1YW4gdMOsbmggdHLhuqFuZyBraMOhY2ggaMOgbmcgY8OzIGhheSBraMO0bmcgbmfGsOG7nWkgcGjhu6UgdGh14buZYywgdMO0aSB0aeG6v24gaMOgbmggduG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgdOG7q25nIGdpw6EgdHLhu4sgY+G7p2EgbmjDs20gRGVwZW5kZW50cy4NCg0KYGBge3J9DQojIFThuqFvIGLhuqNuZyB04bqnbiBz4buRIGNobyBiaeG6v24gdHlwZQ0KZCA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHZpZW50aG9uZyREZXBlbmRlbnRzKSApDQpjb2xuYW1lcyhkKSA8LSBjKCJEZXBlbmRlbnRzIiwgIkNvdW50IikNCg0KZ2dwbG90KGQsIGFlcyh4ID0gRGVwZW5kZW50cywgeSA9IENvdW50LCBmaWxsID0gRGVwZW5kZW50cykpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC41KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBDb3VudCksIHZqdXN0ID0gLTAuNSwgc2l6ZSA9IDMuNSkgKyAjIEhp4buDbiB0aOG7iyBz4buRIGxp4buHdSBiw6puIHRyw6puIGPhu5l0DQogIGxhYnModGl0bGUgPSAixJDhu5MgdGjhu4sgdGjhu4MgaGnhu4duIHTDrG5oIHRy4bqhbmcga2jDoWNoIGjDoG5nIGPDsyBoYXkga2jDtG5nIG5nxrDhu51pIHBo4bulIHRodeG7mWMgIiwgeCA9ICJEZXBlbmRlbnRzIiwgeSA9ICJGcmVxdWVuY3kiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNClRyb25nIHThu5VuZyBz4buRIGtow6FjaCBow6BuZyBraOG6o28gc8OhdCwgY8OzIDM1NzQga2jDoWNoIGjDoG5nIGtow7RuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyBjaGnhur9tIMSRYSBz4buRIHNvIHbhu5tpIDEyNTgga2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljLiBT4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyBraMO0bmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgY2FvIGfhuqVwIGfhuqduIDMgbOG6p24gc28gduG7m2kgbmjDs20gY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMsIGNobyB0aOG6pXkgcGjhuqduIGzhu5tuIGtow6FjaCBow6BuZyB0cm9uZyBt4bqrdSBk4buvIGxp4buHdSBsw6Agbmjhu69uZyBuZ8aw4budaSDEkeG7mWMgbOG6rXAgaG/hurdjIGtow7RuZyBjw7MgdHLDoWNoIG5oaeG7h20gY2jEg20gc8OzYyBjb24gY8OhaSBoYXkgbmfGsOG7nWkga2jDoWMuDQoNCk5nb8OgaSByYSB0w6FjIGdp4bqjIHPhur0gdGjhu7FjIGhp4buHbiB0w61uaCB04bu3IGzhu4cgcGjhuqduIHRyxINtIGNobyB04burbmcgbmjDs20gdsOgIHbhur0gxJHhu5MgdGjhu4sgdHLDsm4gY+G7p2EgY2jDum5nIMSR4buDIHNvIHPDoW5oIHRoZW8gc+G7kSBsaeG7h3UgdMawxqFuZyDEkeG7kWkuDQoNCmBgYHtyfQ0KIyBUaMOqbSBj4buZdCBwaOG6p24gdHLEg20NCmQkUGVyY2VudGFnZSA8LSByb3VuZChwcm9wLnRhYmxlKHRhYmxlKHZpZW50aG9uZyREZXBlbmRlbnRzKSkgKiAxMDAsIDIpDQojIELhuqJORyBQSOG6pk4gVFLEgk0NCmthYmxlKGQsIGFsaWduID0gImMiLCBjb2wubmFtZXMgPSBjKCJEZXBlbmRlbnRzIiwgIlPhu5EgbMaw4bujbmciLCAiUGjhuqduIHRyxINtICglKSIpKSAlPiUNCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImNlbnRlciIsIGZvbnRfc2l6ZSA9IDE0KSAlPiUNCiAgY29sdW1uX3NwZWMoMSwgd2lkdGggPSAiNGNtIikgJT4lDQogIGNvbHVtbl9zcGVjKDIsIHdpZHRoID0gIjNjbSIpICU+JQ0KICBjb2x1bW5fc3BlYygzLCB3aWR0aCA9ICI0Y20iKQ0KDQpgYGANCg0KYGBge3J9DQoNCmdncGxvdChkLCBhZXMoeCA9ICIiLCB5ID0gUGVyY2VudGFnZSwgZmlsbCA9IERlcGVuZGVudHMpKSArDQogIGdlb21fYmFyKHdpZHRoID0gMSwgc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgY29vcmRfcG9sYXIoInkiKSArDQogIGxhYnModGl0bGUgPSAiVOG7tyBs4buHIHBo4bqnbiB0csSDbSIsIHggPSAiIiwgeSA9ICIiKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZShyb3VuZChQZXJjZW50YWdlLCAyKSwgIiUiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemUgPSA0KQ0KYGBgDQoNCkJp4buDdSDEkeG7kyB0csOybiBjaG8gdGjhuqV5IGPDsyBz4buxIGNow6puaCBs4buHY2ggcsO1IHLhu4d0IGdp4buvYSBoYWkgbmjDs20ga2jDoWNoIGjDoG5nOiBuaMOzbSBraMO0bmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgKDczLDk3JSkgY2FvIGfhuqduIGfhuqVwIDMgbOG6p24gc28gduG7m2kgbmjDs20gY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgKDI2LDAzJSkuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IGtow6FjaCBow6BuZyBraMO0bmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgY2hp4bq/bSDGsHUgdGjhur8gdsaw4bujdCB0cuG7mWkgdHJvbmcgYuG7mSBk4buvIGxp4buHdSwgdOG6oW8gbsOqbiBz4buxIGtow6FjIGJp4buHdCDEkcOhbmcga+G7gyB24buBIHThu7cgdHLhu41uZyBnaeG7r2EgaGFpIG5ow7NtLg0KDQojIyMgKiozLjUuMiBUaOG7kW5nIGvDqiBtw7QgdOG6oyBjaG8gaGFpIGJp4bq/biBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB2w6AgdMOsbmggdHLhuqFuZyBra2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljKioNCg0KUGjhuqduIG7DoHkgdHLDrG5oIGLDoHkgdGjhu5FuZyBrw6ogbcO0IHThuqMgY+G7p2EgaGFpIGJp4bq/bjogYmnhur9uIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIChDaHVybikgdsOgIGJp4bq/biB0w6xuaCB0cuG6oW5nIGtow6FjaCBow6BuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyAoRGVwZW5kZW50cykuIFRo4buRbmcga8OqIG7DoHkgZ2nDunAgeMOhYyDEkeG7i25oIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgduG6q24gZHV5IHRyw6wgZOG7i2NoIHbhu6UgaG/hurdjIMSRw6MgcuG7nWkgYuG7jywgxJHhu5NuZyB0aOG7nWkgY2hvIHRo4bqleSBz4buxIHBow6JuIGLhu5EgZ2nhu69hIG5ow7NtIGtow6FjaCBow6BuZyBjw7MgdsOgIGtow7RuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYy4gxJDDonkgbMOgIGPGoSBz4bufIMSR4buDIHBow6JuIHTDrWNoIHhlbSB0w6xuaCB0cuG6oW5nIG5nxrDhu51pIHBo4bulIHRodeG7mWMgY8OzIOG6o25oIGjGsOG7n25nIMSR4bq/biBow6BuaCB2aSBy4budaSBi4buPIGThu4tjaCB24bulIGhheSBraMO0bmcuDQoNCmBgYHtyfQ0KDQp0YWJsZSh2aWVudGhvbmckRGVwZW5kZW50cywgdmllbnRob25nJENodXJuKSAlPiUgIGFkZG1hcmdpbnMoKQ0KYGBgDQoNClbhur0gxJHhu5MgdGjhu4sgY+G7mXQgcGjDom4gdGhlbyBiIHTDrG5oIHRy4bqhbmcga2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIChEZXBlbmRlbnRzKSDEkeG7gyDEkcOhbmggZ2nDoSBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIHZp4buFbiB0aMO0bmcgdHJvbmcgdOG7q25nIG5ow7NtLg0KDQpgYGB7cn0NCnRhYmxlX2RhdGEgPC0gdGFibGUodmllbnRob25nJERlcGVuZGVudHMsIHZpZW50aG9uZyRDaHVybikNCg0KIyBDaHV54buDbiBi4bqjbmcgY2jDqW8gc2FuZyDEkeG7i25oIGThuqFuZyBkw6BpDQpsb25nX2RhdGEyIDwtIGFzLmRhdGEuZnJhbWUodGFibGVfZGF0YSkNCmNvbG5hbWVzKGxvbmdfZGF0YTIpIDwtIGMoIkRlcGVuZGVudHMiLCAiQ2h1cm4iLCAiY291bnQiKQ0KDQojIFbhur0gYmnhu4N1IMSR4buTIGPhu5l0DQpnZ3Bsb3QobG9uZ19kYXRhMiwgYWVzKHggPSBDaHVybiwgeSA9IGNvdW50LCBmaWxsID0gQ2h1cm4pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNvdW50KSwgdmp1c3QgPSAxLCBzaXplID0gMi41LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDEpKSArDQogIGZhY2V0X3dyYXAofiBEZXBlbmRlbnRzLCBzY2FsZXMgPSAiZnJlZV95IiwgbnJvdyA9IDIpICsNCiAgbGFicyh0aXRsZSA9ICJQaMOibiBi4buRIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIHRoZW8gdMOsbmggdHLhuqFuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyBoYXkga2jDtG5nIiwNCiAgICAgICB4ID0gIktow6FjaCBow6BuZyBy4budaSBi4buPIGjhu6NwIMSR4buTbmciLA0KICAgICAgIHkgPSAiVMOsbmggdHLhuqFuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyBoYXkga2jDtG5nIiwNCiAgICAgICBmaWxsID0gIktow6FjaCBow6BuZyBy4budaSBi4buPIGjhu6NwIMSR4buTbmciKSArDQogIHRoZW1lX21pbmltYWwoKSAgDQpgYGANCg0KTmdvw6BpIHJhIHTDoWMgZ2nhuqMgc+G6vSB0aOG7sWMgaGnhu4duIHTDrW5oIHThu7cgbOG7hyBwaOG6p24gdHLEg20gY2hvIDIgYmnhur9uIHbhur0gxJHhu5MgdGjhu4sgY+G7mXQgY+G7p2EgY2jDum5nIMSR4buDIHNvIHPDoW5oIHRoZW8gc+G7kSBsaeG7h3UgdMawxqFuZyDEkeG7kWkuDQoNCmBgYHtyfQ0KdGFibGVfZGF0YTIgPC0gcm91bmQocHJvcC50YWJsZSh0YWJsZV9kYXRhKSoxMDAsMikgDQp0YWJsZV9kYXRhMg0KYGBgDQpgYGB7cn0NCg0KIyBDaHV54buDbiDEkeG7lWkgZOG7ryBsaeG7h3UgdGjDoG5oIGThuqFuZyBkw6BpIMSR4buDIGThu4UgduG6vSBiaeG7g3UgxJHhu5MNCnRhYmxlX2RhdGEyIDwtIGFzLmRhdGEuZnJhbWUudGFibGUodGFibGVfZGF0YTIpDQpjb2xuYW1lcyh0YWJsZV9kYXRhMikgPC0gYygiR3JvdXAiLCAiTGV2ZWwiLCAiUGVyY2VudGFnZSIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MNCmdncGxvdCh0YWJsZV9kYXRhMiwgYWVzKHggPSBMZXZlbCwgeSA9IFBlcmNlbnRhZ2UsIGZpbGwgPSBMZXZlbCkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gUGVyY2VudGFnZSksIHZqdXN0ID0gMSwgc2l6ZSA9IDIuNSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgxKSkgKw0KICBmYWNldF93cmFwKH4gR3JvdXAsIHNjYWxlcyA9ICJmcmVlX3kiLCBucm93ID0gMikgKw0KICBsYWJzKHRpdGxlID0gIlThu7cgbOG7hyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0aGVvIHTDrG5oIHRy4bqhbmcgbmfGsOG7nWkgcGjhu6UgdGh14buZYyIsDQogICAgICAgeCA9ICJUw6xuaCB0cuG6oW5nIG5nxrDhu51pIHBo4bulIHRodeG7mWMiLA0KICAgICAgIHkgPSAiUGjhuqduIHRyxINtIiwNCiAgICAgICBmaWxsID0gIkJp4buDdSBoaeG7h24iKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIk5vIiA9ICJsaWdodGdyZWVuIiwgIlllcyIgPSAibGlnaHRwaW5rIikpICsgDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNClRyb25nIHThu5VuZyBz4buRIDQ4MzIga2jDoWNoIGjDoG5nLCBjw7MgMzU3NCBraMOhY2ggaMOgbmcga2jDtG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIHbDoCAxMjU4IGtow6FjaCBow6BuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYy4gVHJvbmcgbmjDs20ga2jDtG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljLCBjw7MgMjI2MyBraMOhY2ggaMOgbmcga2jDtG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKGNoaeG6v20ga2hv4bqjbmcgNjMsMyUpIHbDoCAxMzExIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulICgzNiw3JSkuIFRyb25nIGtoaSDEkcOzLCDhu58gbmjDs20gY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMsIHPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIGtow7RuZyBy4budaSBi4buPIGThu4tjaCB24bulIGNoaeG6v20gxrB1IHRo4bq/IHLDtSBy4buHdCB24bubaSA5ODMga2jDoWNoIGjDoG5nICg3OCwxJSksIGNo4buJIGPDsyAyNzUga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKDIxLDklKS4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgbmjDs20ga2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGPDsyB4dSBoxrDhu5tuZyB0cnVuZyB0aMOgbmggduG7m2kgZOG7i2NoIHbhu6UgaMahbiBuaMOzbSBraMO0bmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMuDQoNCiMjIyAqKjMuNS4zIFBow6JuIHTDrWNoIFJlbGF0aXZlIFJpc2sgZ2nhu69hIGJp4bq/biBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB2w6AgdMOsbmggdHLhuqFuZyBra2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljKioNCg0KVHJvbmcgcGjhuqduIHRp4bq/cCB0aGVvLCB0w6FjIGdp4bqjIHPhur0gdGnhur9uIGjDoG5oIHTDrW5oIHRvw6FuIGNo4buJIHPhu5EgcuG7p2kgcm8gdMawxqFuZyDEkeG7kWkgKFJlbGF0aXZlIFJpc2sg4oCTIFJSKSBuaOG6sW0gxJHDoW5oIGdpw6EgbeG7qWMgxJHhu5kg4bqjbmggaMaw4bufbmcgY+G7p2EgdMOsbmggdHLhuqFuZyBra2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIMSR4bq/biBraOG6oyBuxINuZyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB2aeG7hW4gdGjDtG5nLg0KDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnJyMjwtIHJpc2tyYXRpbyh0YWJsZV9kYXRhKQ0KcnIyDQpgYGANCg0KS+G6v3QgcXXhuqMgY2jhu4kgc+G7kSBSZWxhdGl2ZSBSaXNrIGNobyB0aOG6pXkgbmjDs20ga2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGPDsyBuZ3V5IGPGoSBy4budaSBi4buPIGThu4tjaCB24bulIGNo4buJIGLhurFuZyA1OSw2JSBzbyB24bubaSBuaMOzbSBraMO0bmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMuIEtob+G6o25nIHRpbiBj4bqteSA5NSUgaG/DoG4gdG/DoG4gbmjhu48gaMahbiAxIHbDoCBnacOhIHRy4buLIHAgcuG6pXQgbmjhu48gKHAgPCAwLDAwMDEpLCBjaOG7qW5nIHThu48gc+G7sSBraMOhYyBiaeG7h3QgduG7gSBuZ3V5IGPGoSBy4budaSBi4buPIGThu4tjaCB24bulIGdp4buvYSBoYWkgbmjDs20gbMOgIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouDQoNCg0KIyMjICoqMy41LjQgUGjDom4gdMOtY2ggT2RkIFJhdGlvIGdp4buvYSB0w6xuaCB0cuG6oW5nIGtraMOhY2ggaMOgbmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgdsOgIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulKioNCg0KVHJvbmcgcGjhuqduIG7DoHksIG5naGnDqm4gY+G7qXUgc+G6vSB0aeG6v24gaMOgbmggdMOtbmggT2RkcyBSYXRpbyBnaeG7r2EgdMOsbmggdHLhuqFuZyBra2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIMSR4bq/biBraOG6oyBuxINuZyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB2aeG7hW4gdGjDtG5nLiBWaeG7h2MgdMOtbmggdG/DoW4gT1Igc+G6vSBnacO6cCB4w6FjIMSR4buLbmggbG/huqFpIGjhu6NwIMSR4buTbmcgbsOgbyBsw6BtIHTEg25nIGhv4bq3YyBnaeG6o20ga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pS4NCg0KYGBge3J9DQpvcjIgPC0gb2Rkc3JhdGlvKHRhYmxlX2RhdGEpDQpvcjINCmBgYA0KDQpL4bq/dCBxdeG6oyBwaMOibiB0w61jaCBPZGRzIFJhdGlvIChPUikgY2hvIHRo4bqleSBraMOhY2ggaMOgbmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgY8OzIG9kZHMgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBjaOG7iSBi4bqxbmcgNDgsMyUgc28gduG7m2kga2jDoWNoIGjDoG5nIGtow7RuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYy4gS2hv4bqjbmcgdGluIGPhuq15IDk1JSBob8OgbiB0b8OgbiBuaOG7jyBoxqFuIDEgdsOgIGdpw6EgdHLhu4sgcCBy4bqldCBuaOG7jyAocCA8IDAsMDAwMSksIGNo4bupbmcgdOG7jyBz4buxIGtow6FjIGJp4buHdCBuw6B5IGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouIMSQaeG7gXUgxJHDsyDEkeG7k25nIG5naMSpYSB24bubaSB2aeG7h2MgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgbMOgIG3hu5l0IHnhur91IHThu5EgZ2nDunAgZ2nhuqNtIMSRw6FuZyBr4buDIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UuIEvhur90IHF14bqjIG7DoHkgY3VuZyBj4bqlcCB0aMO0bmcgdGluIHF1YW4gdHLhu41uZyDEkeG7gyBuaMOgIG3huqFuZyB4w6J5IGThu7FuZyBjw6FjIGNow61uaCBzw6FjaCBjaMSDbSBzw7NjIGtow6FjaCBow6BuZyBoaeG7h3UgcXXhuqMgaMahbiwgxJHhurdjIGJp4buHdCB24bubaSBuaMOzbSBraMO0bmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgduG7kW4gY8OzIG5ndXkgY8ahIHLhu51pIGLhu48gY2FvIGjGoW4uDQoNCiMjIyAqKjMuNS41IFRo4buRbmcga8OqIHN1eSBkaeG7hW4qKg0KDQojIyMjICoqMy41LjUuMSBLaeG7g20gxJHhu4tuaCB0w61uaCDEkeG7mWMgbOG6rXAqKg0KDQrEkOG7gyBraeG7g20gdHJhIHhlbSBiaeG6v24gdMOsbmggdHLhuqFuZyBra2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIChEZXBlbmRlbnRzKSB2w6AgaMOgbmggdmkgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoQ2h1cm4pIGPDsyBt4buRaSBsacOqbiBo4buHIHbhu5tpIG5oYXUgaGF5IGtow7RuZywgbmdoacOqbiBj4bupdSDDoXAgZOG7pW5nIGtp4buDbSDEkeG7i25oIENoaS1zcXVhcmUuDQoNCktp4buDbSDEkeG7i25oIG7DoHkgxJHGsOG7o2MgdGhp4bq/dCBs4bqtcCB24bubaSBnaeG6oyB0aHV54bq/dDogDQoNCiQkDQpcbGVmdFx7DQpcYmVnaW57YXJyYXl9e2xsfQ0KSF8wOiAmIFx0ZXh0e0Jp4bq/biBDaHVybiAoa2jDoWNoIGjDoG5nIHThu6sgYuG7jyBk4buLY2ggduG7pSkgdsOgIGJp4bq/biBEZXBlbmRlbnRzICh0w6xuaCB0cuG6oW5nIGtraMOhY2ggaMOgbmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMpIGtow7RuZyBjw7MgbeG7kWkgcXVhbiBo4buHIHbhu5tpIG5oYXUufSAgXFxcXA0KSF8xOiAmIFx0ZXh0e0Jp4bq/biBDaHVybiAoa2jDoWNoIGjDoG5nIHThu6sgYuG7jyBk4buLY2ggduG7pSkgdsOgIGJp4bq/biBEZXBlbmRlbnRzICh0w6xuaCB0cuG6oW5nIGtraMOhY2ggaMOgbmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMpIGPDsyBt4buRaSBxdWFuIGjhu4cgduG7m2kgbmhhdS59IFwNClxlbmR7YXJyYXl9DQpccmlnaHQuDQokJA0KDQpgYGB7cn0NCiMgS2nhu4NtIMSR4buLbmgNCmNoaXNxX3Jlc3VsdCA8LSBjaGlzcS50ZXN0KHRhYmxlX2RhdGEpDQojIEluIGvhur90IHF14bqjDQpjaGlzcV9yZXN1bHQNCmBgYA0KDQpRdWEga+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmg6IFbhu5tpIG3hu6ljIMO9IG5naMSpYSAwLjA1LCB2w6wgcC12YWx1ZSA9IDIuMmUtMTYgPCAwLjA1LCBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgJEhfMCQuIFbhuq15IGdp4buvYSBiaeG6v24gQ2h1cm4gdsOgIGJp4bq/biBEZXBlbmRlbnRzIHThu5NuIHThuqFpIG3hu5FpIHF1YW4gaOG7hy4NCg0KIyMjIyAqKjMuNS41LjIgS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIHThu7cgbOG7hyoqDQoNCioqxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIG5ow7NtIGtow6FjaCBow6BuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyAqKiANCg0KVHJvbmcgcGjhuqduIG7DoHksIHTDoWMgZ2nhuqMgc+G7rSBk4bulbmcga2nhu4NtIMSR4buLbmggdOG7tyBs4buHIG3hu5l0IG3huqt1ICgxLXNhbXBsZSBwcm9wb3J0aW9uIHRlc3QpIMSR4buDIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdHJvbmcgbmjDs20ga2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljLCDEkeG7k25nIHRo4budaSBzbyBzw6FuaCB24bubaSB04bu3IGzhu4cgZ2nhuqMgxJHhu4tuaCBsw6AgNTAlIChwID0gMC41KS4gUGjGsMahbmcgcGjDoXAgbsOgeSBnacO6cCB4w6FjIMSR4buLbmggeGVtIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIG5ow7NtIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGPDsyBraMOhYyBiaeG7h3QgxJHDoW5nIGvhu4Mgc28gduG7m2kgdOG7tyBs4buHIGdp4bqjIMSR4buLbmggaGF5IGtow7RuZy4gDQoNCmBgYHtyfQ0KcHJvcC50ZXN0KHggPSB0YWJsZV9kYXRhWyJZZXMiLCAiWWVzIl0sIG4gPSBzdW0oIHRhYmxlX2RhdGFbIlllcyIsIF0pLCBwID0gMC41LCBjb3JyZWN0ID0gVFJVRSkNCmBgYA0KS+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmggdOG7tyBs4buHIG3hu5l0IG3huqt1IGNobyB0aOG6pXkgdOG7tyBs4buHIGtow6FjaCBow6BuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyBy4budaSBi4buPIGThu4tjaCB24bulIMSRxrDhu6NjIMaw4bubYyBsxrDhu6NuZyBsw6AgMjEsODYlLCB24bubaSBraG/huqNuZyB0aW4gY+G6rXkgOTUlIG7hurFtIHRyb25nIGtob+G6o25nIDE5LDYzJSDEkeG6v24gMjQsMjclLiBHacOhIHRy4buLIHAgcuG6pXQgbmjhu48gKHAgPCAyLDJlLTE2KSBraOG6s25nIMSR4buLbmggdOG7tyBs4buHIG7DoHkga2jDoWMgYmnhu4d0IGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ogc28gduG7m2kgdOG7tyBs4buHIGdp4bqjIMSR4buLbmggNTAlLiDEkGnhu4F1IG7DoHkgY2jhu6luZyB04buPIGtow6FjaCBow6BuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyBjw7MgdOG7tyBs4buHIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdGjhuqVwIGjGoW4gxJHDoW5nIGvhu4Mgc28gduG7m2kgbeG7qWMgdHJ1bmcgYsOsbmggZ2nhuqMgxJHhu4tuaC4NCg0KKirGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIGtow7RuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyoqIA0KDQpQaOG6p24gbsOgeSBuaOG6sW0geMOhYyDEkeG7i25oIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0cm9uZyBuaMOzbSBraMOhY2ggaMOgbmcga2jDtG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljLCDEkeG7k25nIHRo4budaSBzbyBzw6FuaCB04bu3IGzhu4cgxrDhu5tjIGzGsOG7o25nIHbhu5tpIG3hu6ljIGdp4bqjIHRodXnhur90IDUwJSDEkeG7gyBraeG7g20gdHJhIMO9IG5naMSpYSB0aOG7kW5nIGvDqi4NCg0KYGBge3J9DQpwcm9wLnRlc3QoeCA9IHRhYmxlX2RhdGFbIk5vIiwgIlllcyJdLCBuID0gc3VtKCB0YWJsZV9kYXRhWyJObyIsIF0pLCBwID0gMC41LCBjb3JyZWN0ID0gVFJVRSkNCmBgYA0KDQpL4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaCB04bu3IGzhu4cgbeG7mXQgbeG6q3UgY2hvIHRo4bqleSB04bu3IGzhu4cgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoQ2h1cm4pIGPhu6dhIG5ow7NtIGtow6FjaCBow6BuZyBraMO0bmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgxJHGsOG7o2MgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIDM2LjY4JS4gS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gdOG7tyBs4buHIG7DoHkgbuG6sW0gdHJvbmcga2hv4bqjbmcgMzUuMTAlIMSR4bq/biAzODUuMjklLiBHacOhIHRy4buLIHAtdmFsdWUgPCAyLjJlLTE2IGto4bqzbmcgxJHhu4tuaCBz4buxIGtow6FjIGJp4buHdCBnaeG7r2EgdOG7tyBs4buHIMaw4bubYyBsxrDhu6NuZyB2w6AgbeG7qWMgZ2nhuqMgdGh1eeG6v3QgNTAlIGzDoCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIHLhuqV0IGNhby4gTmjGsCB24bqteSwgdOG7tyBs4buHIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2Ega2jDoWNoIGjDoG5nIGtow7RuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyB0aOG6pXAgaMahbiBuaGnhu4F1IHNvIHbhu5tpIDUwJS4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgbmjDs20ga2jDoWNoIGjDoG5nIGtow7RuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyBjw7MgdOG7tyBs4buHIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY2FvIGjGoW4gbmjDs20gY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMuDQoNCiMjIyAqKjMuNS42IE3DtCBow6xuaCBo4buTaSBxdXkgY2hvIGThu68gbGnhu4d1IG5o4buLIHBow6JuKioNCg0KIyMjIyAqKjMuNS42LjEgTcO0IGjDrG5oIGxvZ2l0KioNCg0KxJDhu4MgcGjDom4gdMOtY2ggbeG7kWkgcXVhbiBo4buHIGdp4buvYSBraMOhY2ggaMOgbmcgdMOsbmggdHLhuqFuZyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIChEZXBlbmRlbnRzKSB2w6Aga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKENodXJuKSwgdMOhYyBnaeG6oyBz4butIGThu6VuZyBtw7QgaMOsbmggaOG7k2kgcXV5IGxvZ2lzdGljIG5o4buLIHBow6JuIChsb2dpdCBtb2RlbCkuIE3DtCBow6xuaCBuw6B5IGNobyBwaMOpcCDGsOG7m2MgbMaw4bujbmcgeMOhYyBzdeG6pXQgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0aMO0bmcgcXVhIGjDoG0gbG9naXQsIGdpw7pwIHjDoWMgxJHhu4tuaCBt4bupYyDEkeG7mSDhuqNuaCBoxrDhu59uZyBj4bunYSB0w6xuaCB0cuG6oW5nIG5nxrDhu51pIHBo4bulIHRodeG7mWMgxJHhur9uIGjDoG5oIHZpIHLhu51pIGLhu48gY+G7p2Ega2jDoWNoIGjDoG5nLiANCg0KYGBge3J9DQpsb2c1IDwtIGdsbShmYWN0b3IoQ2h1cm4pIH4gRGVwZW5kZW50cywgZGF0YSA9IHZpZW50aG9uZywgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpKQ0Kc3VtbWFyeShsb2c1KQ0KYGBgDQpUYSBjw7MgbcO0IGjDrG5oIGjhu5NpIHF1eSBuaMawIHNhdToNCg0KJCQNClxsb2dcbGVmdCggXGZyYWN7UChcdGV4dHtDaHVybn0gPSBcdGV4dHsiWWVzIn0pfXsxIC0gUChcdGV4dHtDaHVybn0gPSBcdGV4dHsiWWVzIn0pfSBccmlnaHQpID0gIC0wLjU0NTkwIC0wLjcyNzk0ICBcY2RvdCBcdGV4dHtEZXBlbmRlbnRzWWVzfQ0KJCQNCg0KS+G6v3QgcXXhuqMgbcO0IGjDrG5oIGxvZ2l0IGNobyB0aOG6pXkgYmnhur9uIERlcGVuZGVudHMgY8OzIHTDoWMgxJHhu5luZyDEkcOhbmcga+G7gyDEkeG6v24ga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBj4bunYSBraMOhY2ggaMOgbmcuIEjhu4cgc+G7kSDGsOG7m2MgbMaw4bujbmcgY+G7p2EgRGVwZW5kZW50c1llcyA9IC0wLDcyNzkgKHAgPCAwLDAwMSksIGNobyB0aOG6pXkgdmnhu4djIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGzDoG0gZ2nhuqNtIGxvZy1vZGRzIHLhu51pIGLhu48gZOG7i2NoIHbhu6Ugc28gduG7m2kgbmjDs20ga2jDtG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljLiBLaGkgY2h1eeG7g24gc2FuZyBvZGRzIHJhdGlvLCBraMOhY2ggaMOgbmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgY2jhu4kgY8OzIG9kZHMgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBi4bqxbmcgNDgsMyUgc28gduG7m2kgbmjDs20ga2jDtG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljLiDEkGnhu4F1IG7DoHkga2jhurNuZyDEkeG7i25oIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGzDoCBt4buZdCB54bq/dSB04buRIGzDoG0gZ2nhuqNtIMSRw6FuZyBr4buDIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UNCg0KDQojIyMjICoqMy41LjYuMiBNw7QgaMOsbmggcHJvYml0KioNCg0KQsOqbiBj4bqhbmggbcO0IGjDrG5oIGxvZ2l0LCB0w6FjIGdp4bqjIGPDsm4gc+G7rSBk4bulbmcgbcO0IGjDrG5oIHByb2JpdCBuaOG6sW0gc28gc8Ohbmgga+G6v3QgcXXhuqMgdsOgIGtp4buDbSB0cmEgdMOtbmgg4buVbiDEkeG7i25oIGPhu6dhIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIHTDrG5oIHRy4bqhbmcgbmfGsOG7nWkgcGjhu6UgdGh14buZYyBEZXBlbmRlbnRzIHbDoCBraOG6oyBuxINuZyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBDaHVybi4gTcO0IGjDrG5oIHByb2JpdCBz4butIGThu6VuZyBow6BtIGxpw6puIGvhur90IGNodeG6qW4gdMOtY2ggbMWpeSB0aGF5IHbDrCBow6BtIGxvZ2l0LCBuaMawbmcgduG6q24gbWFuZyDDvSBuZ2jEqWEgdMawxqFuZyB04buxIHRyb25nIHZp4buHYyDGsOG7m2MgbMaw4bujbmcgeMOhYyBzdeG6pXQgcuG7nWkgYuG7jy4gDQoNCmBgYHtyfQ0KcHJvNSA8LSBnbG0oZmFjdG9yKENodXJuKSB+IERlcGVuZGVudHMsIGRhdGEgPSB2aWVudGhvbmcsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAncHJvYml0JykpDQpzdW1tYXJ5KHBybzUpDQpgYGANCg0KS+G6v3QgcXXhuqMgxrDhu5tjIGzGsOG7o25nIG3DtCBow6xuaCBQcm9iaXQgY2hvIHRo4bqleSBiaeG6v24gKipEZXBlbmRlbnRzKiogY8OzIOG6o25oIGjGsOG7n25nIMSRw6FuZyBr4buDIMSR4bq/biB4w6FjIHN14bqldCBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoQ2h1cm4pLiBQaMawxqFuZyB0csOsbmggbcO0IGjDrG5oIMSRxrDhu6NjIHjDoWMgxJHhu4tuaCBuaMawIHNhdTogIA0KJCQNClAoWT0xIHwgRGVwZW5kZW50cykgPSBcUGhpKC0wLjM0MDMwIC0gMC40MzY2MyBcY2RvdCBEZXBlbmRlbnRzX3tZZXN9KSwNCiQkDQp0cm9uZyDEkcOzIFwoXFBoaShcY2RvdClcKSBsw6AgaMOgbSBwaMOibiBwaOG7kWkgdMOtY2ggbMWpeSBj4bunYSBwaMOibiBwaOG7kWkgY2h14bqpbiBjaHXhuqluIGjDs2EuIEtoaSBraMOhY2ggaMOgbmcga2jDtG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIChEZXBlbmRlbnRzID0gTm8pLCBnacOhIHRy4buLIHR1eeG6v24gdMOtbmggbMOgIFwoeiA9IC0wLjM0MDMwXCksIGThuqtuIMSR4bq/biB4w6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIOG7nyBt4bupYyBcKFAoWT0xfE5vKSA9IFxQaGkoLTAuMzQwMzApIFxhcHByb3ggMC4zNjZcKSAoMzYuNiUpLiBOZ8aw4bujYyBs4bqhaSwga2hpIGtow6FjaCBow6BuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyAoRGVwZW5kZW50cyA9IFllcyksIGdpw6EgdHLhu4sgXCh6XCkgZ2nhuqNtIHh14buRbmcgY8OybiBcKC0wLjc3NjkzXCksIHbDoCB4w6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIGdp4bqjbSB4deG7kW5nIGPDsm4gXChQKFk9MXxZZXMpID0gXFBoaSgtMC43NzY5MykgXGFwcHJveCAwLjIxOVwpICgyMS45JSkuIEjhu4cgc+G7kSBcKC0wLjQzNjYzXCkgY+G7p2EgYmnhur9uIERlcGVuZGVudHNZZXMgw6JtIHbDoCBjw7MgXChwIDwgMmUtMTZcKSwgY2hvIHRo4bqleSB2aeG7h2MgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgbMOgbSBnaeG6o20gxJHDoW5nIGvhu4Mga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pS4gTmjDrG4gY2h1bmcsIG3DtCBow6xuaCBQcm9iaXQgbsOgeSBjaG8gdGjhuqV5IHnhur91IHThu5EgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgbMOgIG3hu5l0IGJp4bq/biBxdWFuIHRy4buNbmcgZ2nDunAgZ2nhuqNtIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIGtow6FjaCBow6BuZy4NCg0KDQojIyMjICoqMy41LjYuMyBNw7QgaMOsbmggY2xvZ2xvZyoqDQoNCsSQ4buDIHBow6JuIHTDrWNoIOG6o25oIGjGsOG7n25nIGPhu6dhIGJp4bq/biBEZXBlbmRlbnRzIMSR4bq/biBraOG6oyBuxINuZyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIGtow6FjaCBow6BuZywgbcO0IGjDrG5oIGjhu5NpIHF1eSBuaOG7iyBwaMOibiB24bubaSBow6BtIGxpw6puIGvhur90IENvbXBsZW1lbnRhcnkgTG9nLUxvZyAoY2xvZ2xvZykgxJHGsOG7o2Mgw6FwIGThu6VuZy4gTcO0IGjDrG5oIG7DoHkgcGjDuSBo4bujcCBraGkgeMOhYyBzdeG6pXQgeOG6o3kgcmEgc+G7sSBraeG7h24ga2jDtG5nIMSR4buRaSB44bupbmcsIMSR4bq3YyBiaeG7h3Qga2hpIHjDoWMgc3XhuqV0IGNhbyBob+G6t2MgdGjhuqVwIOG7nyBt4bupYyBj4buxYyB0cuG7iy4gDQoNCmBgYHtyfQ0KY2xvNSA8LSBnbG0oZmFjdG9yKENodXJuKSB+IERlcGVuZGVudHMsIGRhdGEgPSB2aWVudGhvbmcsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnY2xvZ2xvZycpKQ0Kc3VtbWFyeShjbG81KQ0KYGBgDQoNClRhIGPDsyBtw7QgaMOsbmggbmdoacOqbiBj4bupdSBuaMawIHNhdToNCg0KJCQNClxsb2cgXGxlZnRbIC0gXGxvZyBcbGVmdCggMSAtIHBfaSBccmlnaHQpIFxyaWdodF0gDQo9IC0wLjc4MzEgLSAwLjYxNjYgXGNkb3QgXHRleHR7RGVwZW5kZW50c1llc31fe2l9DQokJA0KDQpL4bq/dCBxdeG6oyDGsOG7m2MgbMaw4bujbmcgbcO0IGjDrG5oIENvbXBsZW1lbnRhcnkgTG9nLUxvZyAoY2xvZ2xvZykgY2hvIHRo4bqleSBo4buHIHPhu5EgY2jhurduIGzDoCDiiJIwLjc4MzEgdsOgIGjhu4cgc+G7kSBj4bunYSBiaeG6v24gRGVwZW5kZW50c1llcyBsw6Ag4oiSMC42MTY2LCDEkeG7gXUgY8OzIHAtdmFsdWUgPCAwLjAwMSwgY2jhu6luZyB04buPIGNow7puZyBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIOG7nyBt4bupYyA1JS4gS2hpIHTDrW5oIHRvw6FuIHjDoWMgc3XhuqV0LCBuaMOzbSBraMOhY2ggaMOgbmcga2jDtG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGPDsyB4w6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIGtob+G6o25nIDMxLjklLCB0cm9uZyBraGkgbmjDs20gY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgY2jhu4kga2hv4bqjbmcgMjAuOCUuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IHZp4buHYyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYyBnacO6cCBnaeG6o20gxJHDoW5nIGvhu4Mgbmd1eSBjxqEgcuG7nWkgYuG7jyBk4buLY2ggduG7pS4gVOG7qyBr4bq/dCBxdeG6oyBuw6B5LCB0YSBjw7MgdGjhu4Mga+G6v3QgbHXhuq1uIHLhurFuZyBiaeG6v24gRGVwZW5kZW50cyBsw6AgbeG7mXQgeeG6v3UgdOG7kSBxdWFuIHRy4buNbmcgdHJvbmcgdmnhu4djIGThu7EgYsOhbyBraOG6oyBuxINuZyBy4budaSBi4buPIGThu4tjaCB24bulIGPhu6dhIGtow6FjaCBow6BuZy4NCg0KIyMjICoqMy41LjcgxJDDoW5oIGdpw6EgbcO0IGjDrG5oKioNCg0KU2F1IGtoaSB0aeG6v24gaMOgbmggxrDhu5tjIGzGsOG7o25nIGJhIG3DtCBow6xuaCBo4buTaSBxdXkgbmjhu4sgcGjDom4gZ+G7k20gbG9naXQsIHByb2JpdCB2w6AgY2xvZ2xvZywgYsaw4bubYyB0aeG6v3AgdGhlbyBsw6AgxJHDoW5oIGdpw6EgdsOgIHNvIHPDoW5oIG3hu6ljIMSR4buZIHBow7kgaOG7o3AgY+G7p2EgY8OhYyBtw7QgaMOsbmggbsOgeS4gVmnhu4djIMSRw6FuaCBnacOhIMSRxrDhu6NjIHRo4buxYyBoaeG7h24gZOG7sWEgdHLDqm4gY8OhYyBjaOG7iSB0acOqdSB0aOG7kW5nIGvDqiBuaMawIGdpw6EgdHLhu4sgQUlDLCBCSUMsIGjhu4cgc+G7kSBCcmllclNjb3JlLiBOZ2/DoGkgcmEsIGto4bqjIG7Eg25nIGThu7EgYsOhbyB4w6FjIHN14bqldCBj4bunYSB04burbmcgbcO0IGjDrG5oIMSR4buRaSB24bubaSBjw6FjIHRyxrDhu51uZyBo4bujcCBnaeG6oyDEkeG7i25oIGPhu6UgdGjhu4MgY8WpbmcgxJHGsOG7o2MgeGVtIHjDqXQgxJHhu4MgbOG7sWEgY2jhu41uIG3DtCBow6xuaCBwaMO5IGjhu6NwIG5o4bqldC4NCg0KDQpgYGB7cn0NCiMgVOG6oW8gYuG6o25nIHNvIHPDoW5oDQptb2RlbF9ldmFsMyA8LSBkYXRhLmZyYW1lKA0KICBNw7RfaMOsbmggPSBjKCJMb2dpdCIsICJQcm9iaXQiLCAiQ2xvZ2xvZyIpLA0KICBBSUMgPSBjKEFJQyhsb2c1KSwgQUlDKHBybzUpLCBBSUMoY2xvNSkpLA0KICBCSUMgPSBjKEJJQyhsb2c1KSwgQklDKHBybzUpLCBCSUMoY2xvNSkpLA0KICBCcmllcl9TY29yZSA9IGMoQnJpZXJTY29yZShsb2c1KSwgQnJpZXJTY29yZShwcm81KSwgQnJpZXJTY29yZShjbG81KSkNCikNCmthYmxlKG1vZGVsX2V2YWwzLCBhbGlnbiA9ICJjIiwgY2FwdGlvbiA9ICJTbyBzw6FuaCBjw6FjIGNo4buJIHPhu5EgxJHDoW5oIGdpw6EgbcO0IGjDrG5oIikgJT4lDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJjZW50ZXIiLCBmb250X3NpemUgPSAxNCkNCmBgYA0KDQpE4buxYSB0csOqbiBr4bq/dCBxdeG6oyBzbyBzw6FuaCBjw6FjIGNo4buJIHPhu5EgxJHDoW5oIGdpw6EgbcO0IGjDrG5oLCBj4bqjIGJhIG3DtCBow6xuaCBsb2dpdCwgcHJvYml0IHbDoCBjbG9nbG9nIMSR4buBdSBjaG8gcmEgZ2nDoSB0cuG7iyBBSUMgKDYwMjMuMTc3KSwgQklDICg2MDM2LjE0MykgdsOgIEJyaWVyIFNjb3JlICgwLjIxNjMpIGdp4buRbmcgbmhhdS4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgbeG7qWMgxJHhu5kgcGjDuSBo4bujcCBj4bunYSBjw6FjIG3DtCBow6xuaCBsw6AgdMawxqFuZyDEkcawxqFuZyB2w6Aga2jhuqMgbsSDbmcgZOG7sSBiw6FvIHjDoWMgc3XhuqV0IMSRw7puZyBraMO0bmcgY8OzIHPhu7Ega2jDoWMgYmnhu4d0IMSRw6FuZyBr4buDLiANCg0KKipNYSB0cuG6rW4gbmjhuqdtIGzhuqtuKioNCg0KLSBNw7QgaMOsbmggbG9naXQNCg0KYGBge3J9DQpwcmVkX2xvZ2l0bG9nIDwtIGlmZWxzZShwcmVkaWN0KGxvZzUsIHR5cGUgPSAicmVzcG9uc2UiKSA+PSAwLjUsICJZZXMiLCAiTm8iKQ0KYWN0dWFsbG9nIDwtIHZpZW50aG9uZyRDaHVybg0KY21fbG9naXRsb2cgPC0gY29uZnVzaW9uTWF0cml4KGZhY3RvcihwcmVkX2xvZ2l0bG9nKSwgYWN0dWFsbG9nLCBwb3NpdGl2ZSA9ICJZZXMiKQ0KY21fbG9naXRsb2cNCmBgYA0KLSBNw7QgaMOsbmggcHJvYml0DQoNCmBgYHtyfQ0KcHJlZF9sb2dpdHBybyA8LSBpZmVsc2UocHJlZGljdChwcm81LCB0eXBlID0gInJlc3BvbnNlIikgPj0gMC41LCAiWWVzIiwgIk5vIikNCmFjdHVhbHBybyA8LSB2aWVudGhvbmckQ2h1cm4NCmNtX2xvZ2l0cHJvIDwtIGNvbmZ1c2lvbk1hdHJpeChmYWN0b3IocHJlZF9sb2dpdHBybyksIGFjdHVhbHBybywgcG9zaXRpdmUgPSAiWWVzIikNCmNtX2xvZ2l0cHJvDQpgYGANCg0KLSBNw7QgaMOsbmggY2xvZ2xvZw0KDQpgYGB7cn0NCnByZWRfbG9naXRjbG8gPC0gaWZlbHNlKHByZWRpY3QoY2xvNSwgdHlwZSA9ICJyZXNwb25zZSIpID49IDAuNSwgIlllcyIsICJObyIpDQphY3R1YWxjbG8gPC0gdmllbnRob25nJENodXJuDQpjbV9sb2dpdGNsbyA8LSBjb25mdXNpb25NYXRyaXgoZmFjdG9yKHByZWRfbG9naXRjbG8pLCBhY3R1YWxjbG8sIHBvc2l0aXZlID0gIlllcyIpDQpjbV9sb2dpdGNsbw0KYGBgDQoNCk1hIHRy4bqtbiBuaOG6p20gbOG6q24gY2hvIHRo4bqleSBj4bqjIGJhIG3DtCBow6xuaCBsb2dpdCwgcHJvYml0IHbDoCBjbG9nbG9nIMSR4buBdSBraMO0bmcgZOG7sSDEkW/DoW4gxJHDum5nIMSRxrDhu6NjIGLhuqV0IGvhu7MgdHLGsOG7nW5nIGjhu6NwIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIG7DoG8sIHbhu5tpIFRQID0gMC4gxJDhu5NuZyB0aOG7nWksIEZQID0gMCBjaG8gdGjhuqV5IGtow7RuZyBjw7MgdHLGsOG7nW5nIGjhu6NwIGtow6FjaCBow6BuZyDhu58gbmjDs20g4oCcTm/igJ0gbsOgbyBi4buLIGThu7EgxJFvw6FuIG5o4bqnbSB0aMOgbmgg4oCcWWVz4oCdLCBuaMawbmcgxJFp4buBdSBuw6B5IHBo4bqjbiDDoW5oIG3DtCBow6xuaCBraMO0bmcgaOG7gSDEkcawYSByYSBk4buxIMSRb8OhbiDigJxZZXPigJ0uIE5nxrDhu6NjIGzhuqFpLCBGTiA9IDE1ODYgY2hvIHRo4bqleSB0b8OgbiBi4buZIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIMSR4buBdSBi4buLIHBow6JuIGxv4bqhaSBzYWkgdGjDoG5oIOKAnE5v4oCdLCBk4bqrbiDEkeG6v24gxJHhu5kgbmjhuqF5IChTZW5zaXRpdml0eSkgYuG6sW5nIDAuIFRyb25nIGtoaSDEkcOzLCBUTiA9IDMyNDYgY2hvIHRo4bqleSB0b8OgbiBi4buZIGtow6FjaCBow6BuZyBraMO0bmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSDEkcaw4bujYyBk4buxIMSRb8OhbiBjaMOtbmggeMOhYywgbMOgbSBTcGVjaWZpY2l0eSDEkeG6oXQgMTAwJS4gS+G6v3QgcXXhuqMgbsOgeSBjaG8gdGjhuqV5IG3DtCBow6xuaCBi4buLIGzhu4djaCBo4bqzbiB24buBIG5ow7NtIMSRYSBz4buRIOKAnE5v4oCdLiBN4bq3YyBkw7kgxJHhu5kgY2jDrW5oIHjDoWMgdOG7lW5nIHRo4buDIMSR4bqhdCA2NywxOCUsIG5oxrBuZyDEkWnhu4F1IG7DoHkga2jDtG5nIHBo4bqjbiDDoW5oIMSRw7puZyBoaeG7h3UgcXXhuqMgcGjDom4gbG/huqFpLg0KDQojIyAqKjMuNiBQaMOibiB0w61jaCDEkWEgYmnhur9uIHTDoWMgxJHhu5luZyDEkeG6v24ga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UqKg0KDQrEkOG7gyDEkcOhbmggZ2nDoSB0w6FjIMSR4buZbmcgxJHhu5NuZyB0aOG7nWkgY+G7p2Egbmhp4buBdSB54bq/dSB04buRIMSR4bq/biBraOG6oyBuxINuZyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoQ2h1cm4pLCBuaMOzbSBuZ2hpw6puIGPhu6l1IHPhu60gZOG7pW5nIGPDoWMgbcO0IGjDrG5oIGjhu5NpIHF1eSBuaOG7iyBwaMOibiwgYmFvIGfhu5NtOiBtw7QgaMOsbmggbG9naXQsIG3DtCBow6xuaCBwcm9iaXQsIHbDoCBtw7QgaMOsbmggY2xvZ2xvZy4gQ8OhYyBtw7QgaMOsbmggbsOgeSBnacO6cCDGsOG7m2MgbMaw4bujbmcgeMOhYyBzdeG6pXQgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBj4bunYSBraMOhY2ggaMOgbmcgZOG7sWEgdHLDqm4gY8OhYyBiaeG6v24gZ2nhuqNpIHRow61jaCBuaMawIGxv4bqhaSBo4bujcCDEkeG7k25nIChDb250cmFjdCksIGThu4tjaCB24bulIEludGVybmV0IChJbnRlcm5ldFNlcnZpY2UpLCB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4vxJHhu5FpIHTDoWMgKFBhcnRuZXIpIHbDoCB0w6xuaCB0cuG6oW5nIG5nxrDhu51pIGNhbyB0deG7lWkgKFNlbmlvckNpdGl6ZW4pLiBWaeG7h2MgcGjDom4gdMOtY2ggxJFhIGJp4bq/biBraMO0bmcgY2jhu4kgY3VuZyBj4bqlcCBjw6FpIG5ow6xuIHThu5VuZyBxdWFuIGjGoW4gduG7gSDhuqNuaCBoxrDhu59uZyBj4bunYSB04burbmcgeeG6v3UgdOG7kSBtw6AgY8OybiBnacO6cCBzbyBzw6FuaCBoaeG7h3UgcXXhuqMgZOG7sSBiw6FvIGdp4buvYSBjw6FjIG3DtCBow6xuaCB0aMO0bmcgcXVhIGPDoWMgdGnDqnUgY2jDrSBuaMawIEFJQywgQklDIHbDoCBtYSB0cuG6rW4gbmjhuqdtIGzhuqtuLg0KDQojIyMgKiozLjYuMSBNw7QgaMOsbmggbG9naXQqKg0KDQrEkOG7gyBwaMOibiB0w61jaCB4w6FjIHN14bqldCBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBk4buxYSB0csOqbiBjw6FjIHnhur91IHThu5Eg4bqjbmggaMaw4bufbmcsIG3DtCBow6xuaCBsb2dpdCDEkcaw4bujYyBz4butIGThu6VuZyB24bubaSBiaeG6v24gcGjhu6UgdGh14buZYyBsw6AgQ2h1cm4gKFllcy9ObykgdsOgIGPDoWMgYmnhur9uIMSR4buZYyBs4bqtcCBn4buTbSBDb250cmFjdDIsIEludGVybmV0U2VydmljZSwgUGFydG5lciB2w6AgU2VuaW9yQ2l0aXplbi4gTcO0IGjDrG5oIGxvZ2l0IHPhu60gZOG7pW5nIGjDoG0gbGnDqm4ga+G6v3QgbG9naXQsIGdpw7pwIGJp4bq/biDEkeG7lWkgeMOhYyBzdeG6pXQgKGdp4bubaSBo4bqhbiB0cm9uZyBbMCwxXSkgdGjDoG5oIGThuqFuZyBsb2ctb2RkcywgdOG7qyDEkcOzIGto4bqvYyBwaOG7pWMgbmjGsOG7o2MgxJFp4buDbSBj4bunYSBtw7QgaMOsbmggeMOhYyBzdeG6pXQgdHV54bq/biB0w61uaC4gTOG7h25oIGTGsOG7m2kgxJHDonkgdGjhu7FjIGhp4buHbiB2aeG7h2MgxrDhu5tjIGzGsOG7o25nIG3DtCBow6xuaCBsb2dpdDoNCg0KYGBge3J9DQpsb2c0IDwtIGdsbShmYWN0b3IoQ2h1cm4pIH4gQ29udHJhY3QyICsgSW50ZXJuZXRTZXJ2aWNlICsgUGFydG5lciArIFNlbmlvckNpdGl6ZW4gLCBkYXRhID0gdmllbnRob25nLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rPSJsb2dpdCIpKQ0Kc3VtbWFyeShsb2c0KQ0KYGBgDQpE4buxYSB2w6BvIGvhur90IHF14bqjIHRyw6puIHRhIGPDsyBtw7QgaMOsbmggaOG7k2kgcXV5IG5oxrAgc2F1Og0KDQokJA0KXGxvZyBcbGVmdCggXGZyYWN7UChcdGV4dHtDaHVybn0gPSBcdGV4dHsiWWVzIn0pfXsxIC0gUChcdGV4dHtDaHVybn0gPSBcdGV4dHsiWWVzIn0pfSBccmlnaHQpID0gLTEuMTQwNzkgLTEuMDc5MzkgIFxjZG90IFx0ZXh0e0NvbnRyYWN0Mk9uZSB5ZWFyfSArMS4yMjQ0OSBcY2RvdCBcdGV4dHtJbnRlcm5ldFNlcnZpY2VGaWJlciBvcHRpY30gLTAuNzE4MTIgXGNkb3QgXHRleHR7UGFydG5lclllc30gKyAgMC4zMTkzNyBcY2RvdCBcdGV4dHtTZW5pb3JDaXRpemVufQ0KJCQNCg0KYGBge3J9DQojIEzhuqV5IGvhur90IHF14bqjIGjhu4cgc+G7kQ0KY29lZl9sb2dpdCA8LSBzdW1tYXJ5KGxvZzQpJGNvZWZmaWNpZW50cw0Kb2Rkc19yYXRpbyA8LSBleHAoY29lZl9sb2dpdFssICJFc3RpbWF0ZSJdKQ0KDQojIFThuqFvIGRhdGEgZnJhbWUgduG7m2kgbmjDs20gc28gc8OhbmggdsOgIGRp4buFbiBnaeG6o2kgdGjhu6cgY8O0bmcNCnJlc3VsdF90YWJsZSA8LSBkYXRhLmZyYW1lKA0KICBCaWVuID0gYygiQ29udHJhY3QyIiwgIkludGVybmV0U2VydmljZSIsICJQYXJ0bmVyIiwgIlNlbmlvckNpdGl6ZW4iKSwNCiAgTmhvbV9zb19zYW5oID0gYygiT25lIHllYXIgdnMuIEtow6FjIiwgIkZpYmVyIG9wdGljIHZzLiBEU0wiLA0KICAgICAgICAgICAgICAgICAgICJZZXMgdnMuIE5vIiwgIjEgKENhbyB0deG7lWkpIHZzLiAwIChUcuG6uykiKSwNCiAgSGVfc28gPSByb3VuZChjb2VmX2xvZ2l0Wy0xLCAiRXN0aW1hdGUiXSwgNSksDQogIGBwLXZhbHVlYCA9IHNpZ25pZihjb2VmX2xvZ2l0Wy0xLCAiUHIoPnx6fCkiXSwgMyksDQogIE9kZHNfUmF0aW8gPSByb3VuZChvZGRzX3JhdGlvWy0xXSwgMiksDQogIERpZW5fZ2lhaSA9IGMoDQogICAgIktow6FjaCBow6BuZyBrw70gaOG7o3AgxJHhu5NuZyDigJxLaMOhY+KAnSBjw7Mga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBjYW8gaMahbiAyLDk0IGzhuqduIHNvIHbhu5tpIG5ow7NtIGvDvSBo4bujcCDEkeG7k25nIOKAnE9uZSB5ZWFy4oCdLiBOZ2jEqWEgbMOgIGjhu6NwIMSR4buTbmcgMSBuxINtIGPDsyB0w6FjIGThu6VuZyBnaeG6o20gbeG6oW5oIG5ndXkgY8ahIGtow6FjaCBow6BuZyBy4budaSDEkWkuIiwNCiAgICAiQ2jhu4kgcmEgcuG6sW5nIGtow6FjaCBow6BuZyBz4butIGThu6VuZyBk4buLY2ggduG7pSBJbnRlcm5ldCBGaWJlciBvcHRpYyBjw7Mga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBjYW8gZ+G6pXAgMyw0IGzhuqduIHNvIHbhu5tpIGtow6FjaCBow6BuZyBz4butIGThu6VuZyBk4buLY2ggduG7pSBEU0wuIMSQaeG7gXUgbsOgeSBjw7MgdGjhu4MgbGnDqm4gcXVhbiDEkeG6v24gZ2nDoSBjxrDhu5tjIGNhbyBob+G6t2MgY2jhuqV0IGzGsOG7o25nIGThu4tjaCB24bulIGNoxrBhIHTGsMahbmcgeOG7qW5nLCBk4bqrbiDEkeG6v24gc+G7sSBraMO0bmcgaMOgaSBsw7JuZyB2w6AgcXV54bq/dCDEkeG7i25oIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIG7DoHkuIiwNCiAgICAiS2jDoWNoIGjDoG5nIGPDsyDEkeG7kWkgdMOhYyBob+G6t2MgbmfGsOG7nWkgdGjDom4gY8O5bmcgc+G7rSBk4bulbmcgZOG7i2NoIHbhu6UgY8OzIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZ2nhuqNtIDUxJSBzbyB24bubaSBraMOhY2ggaMOgbmcga2jDtG5nIGPDsyDEkeG7kWkgdMOhYy4gxJBp4buBdSBuw6B5IHBo4bqjbiDDoW5oIHnhur91IHThu5EgeMOjIGjhu5lpIHbDoCBz4buxIOG6o25oIGjGsOG7n25nIGPhu6dhIG5nxrDhu51pIHRow6JuIHRyb25nIHZp4buHYyBkdXkgdHLDrCBk4buLY2ggduG7pSwgZ2nDunAgbmjDoCBt4bqhbmcgZ2nhu68gY2jDom4ga2jDoWNoIGjDoG5nIGhp4buHdSBxdeG6oyBoxqFuLiIsDQogICAgIkNobyB0aOG6pXkga2jDoWNoIGjDoG5nIGNhbyB0deG7lWkgKFNlbmlvckNpdGl6ZW4gPSAxKSBjw7Mga2jhuqMgbsSDbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBjYW8gaMahbiAxLDM4IGzhuqduIHNvIHbhu5tpIG5ow7NtIGtow6FjaCBow6BuZyB0cuG6uyB0deG7lWkuIMSQaeG7gXUgbsOgeSBjw7MgdGjhu4MgZG8gbmh1IGPhuqd1IHPhu60gZOG7pW5nIGThu4tjaCB24bulIHZp4buFbiB0aMO0bmcg4bufIG5nxrDhu51pIGNhbyB0deG7lWkgw610IGjGoW4gaG/hurdjIGjhu40gdMOsbSBraeG6v20gY8OhYyBnw7NpIGPGsOG7m2MgcuG6uyBoxqFuIOG7nyBuaMOgIG3huqFuZyBraMOhYy4iDQogICkNCikNCg0Ka2FibGUocmVzdWx0X3RhYmxlLCBhbGlnbiA9ICJjIiwNCiAgICAgIGNvbC5uYW1lcyA9IGMoIkJp4bq/biIsICJOaMOzbSBzbyBzw6FuaCIsICJI4buHIHPhu5EgKM6yKSIsICJwLXZhbHVlIiwgIk9kZHMgUmF0aW8gKGVezrIpIiwgIkRp4buFbiBnaeG6o2kgY2hpIHRp4bq/dCIpKSAlPiUNCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImNlbnRlciIsIGZvbnRfc2l6ZSA9IDE0KSAlPiUNCiAgcm93X3NwZWMoMCwgZXh0cmFfY3NzID0gImZvbnQtZmFtaWx5OiAnVGltZXMgTmV3IFJvbWFuJzsiKSAlPiUNCiAgY29sdW1uX3NwZWMoMTpuY29sKHJlc3VsdF90YWJsZSksIGV4dHJhX2NzcyA9ICJmb250LWZhbWlseTogJ1RpbWVzIE5ldyBSb21hbic7IikNCmBgYA0KDQpU4burIGvhur90IHF14bqjIHRyw6puLCBjw7MgdGjhu4MgdGjhuqV5IGPDoWMgeeG6v3UgdOG7kSB24buBIGjhu6NwIMSR4buTbmcgdsOgIG3hu5FpIHF1YW4gaOG7hyB4w6MgaOG7mWkgKFBhcnRuZXIpIGdpw7pwIGdp4bqjbSB04bu3IGzhu4cgcuG7nWkgYuG7jyBk4buLY2ggduG7pSwgdHJvbmcga2hpIHnhur91IHThu5EgbG/huqFpIGThu4tjaCB24bulIEludGVybmV0IChGaWJlciBvcHRpYykgdsOgIMSR4buZIHR14buVaSBsw6BtIHTEg25nIGto4bqjIG7Eg25nIGtow6FjaCBow6BuZyBy4budaSBi4buPLiBEbyDEkcOzLCBkb2FuaCBuZ2hp4buHcCB2aeG7hW4gdGjDtG5nIGPhuqduIHThuq1wIHRydW5nIHbDoG8ga2h1eeG6v24ga2jDrWNoIGtow6FjaCBow6BuZyBrw70gaOG7o3AgxJHhu5NuZyAxIG7Eg20sIMSR4buTbmcgdGjhu51pIGPhuqNpIHRoaeG7h24gY2jhuqV0IGzGsOG7o25nIGThu4tjaCB24bulIEZpYmVyIG9wdGljIHbDoCB4w6J5IGThu7FuZyBjw6FjIGfDs2kgZOG7i2NoIHbhu6UgcGjDuSBo4bujcCB24bubaSBuaMOzbSBraMOhY2ggaMOgbmcgY2FvIHR14buVaS4NCg0KU2F1IGtoaSB4w6J5IGThu7FuZyB2w6AgxrDhu5tjIGzGsOG7o25nIG3DtCBow6xuaCBsb2dpdCwgYsaw4bubYyB0aeG6v3AgdGhlbyBsw6Agc+G7rSBk4bulbmcgbcO0IGjDrG5oIMSR4buDIGThu7EgYsOhbyB4w6FjIHN14bqldCBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoQ2h1cm4pIGNobyA0IHRyxrDhu51uZyBo4bujcCBnaeG6oyDEkeG7i25oLiBD4bulIHRo4buDLCB0YSB04bqhbyByYSBt4buZdCB04bqtcCBk4buvIGxp4buHdSBt4bubaSAobmV3X2RhdGE0KSB24bubaSBjw6FjIHThu5UgaOG7o3AgY+G7p2EgYmnhur9uIENvbnRyYWN0MiwgSW50ZXJuZXRTZXJ2aWNlLCBQYXJ0bmVyIHbDoCBTZW5pb3JDaXRpemVuLCBzYXUgxJHDsyBkw7luZyBow6BtIHByZWRpY3QoKSDEkeG7gyB0w61uaCB4w6FjIHN14bqldCBjaHVybiBjaG8gdOG7q25nIHRyxrDhu51uZyBo4bujcC4NCg0KDQpgYGB7cn0NCm5ld19kYXRhNCA8LSBkYXRhLmZyYW1lKA0KICBDb250cmFjdDIgPSBmYWN0b3IoYygiT25lIHllYXIiLCAiT25lIHllYXIiLCAiS2jDoWMiLCAiS2jDoWMiKSksICAjIGPhuqduIMSRw7puZyB0w6puIGxldmVscw0KICBJbnRlcm5ldFNlcnZpY2UgPSBmYWN0b3IoYygiRmliZXIgb3B0aWMiLCAiRFNMIiwgIkZpYmVyIG9wdGljIiwgIkRTTCIpKSwNCiAgUGFydG5lciA9IGZhY3RvcihjKCJZZXMiLCAiTm8iLCAiWWVzIiwgIk5vIikpLA0KICBTZW5pb3JDaXRpemVuID0gYygxLCAwLCAxLCAwKQ0KKQ0KIyBE4buxIMSRb8OhbiB4w6FjIHN14bqldCBjaHVybjoNCnByZWRpY3QobG9nNCwgbmV3ZGF0YSA9IG5ld19kYXRhNCwgdHlwZSA9ICJyZXNwb25zZSIpDQpgYGANCkThu7FhIHRyw6puIGvhur90IHF14bqjIGThu7EgYsOhbyB04burIG3DtCBow6xuaCBsb2dpdCwgdGEgY8OzIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKENodXJuKSBj4bunYSA0IHRyxrDhu51uZyBo4bujcCBuaMawIHNhdToNCg0KVHLGsOG7nW5nIGjhu6NwIDEgKE9uZSB5ZWFyLCBGaWJlciBvcHRpYywgUGFydG5lciA9IFllcywgU2VuaW9yQ2l0aXplbiA9IDEpOiBYw6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIGtob+G6o25nIDE5LDg3JSwgdMawxqFuZyDEkeG7kWkgdGjhuqVwIG5o4budIGjhu6NwIMSR4buTbmcgMSBuxINtIHbDoCBjw7MgxJHhu5FpIHTDoWMgY8O5bmcgc+G7rSBk4bulbmcgZOG7i2NoIHbhu6UsIGTDuSBraMOhY2ggaMOgbmcgY2FvIHR14buVaS4NCg0KVHLGsOG7nW5nIGjhu6NwIDIgKE9uZSB5ZWFyLCBEU0wsIFBhcnRuZXIgPSBObywgU2VuaW9yQ2l0aXplbiA9IDApOiBYw6FjIHN14bqldCBjaOG7iSA5LDc5JSwgdGjhuqVwIG5o4bqldCB0cm9uZyA0IHRyxrDhu51uZyBo4bujcCwgY2hvIHRo4bqleSBo4bujcCDEkeG7k25nIGTDoGkgaOG6oW4gdsOgIGThu4tjaCB24bulIERTTCBjw7Mg4bqjbmggaMaw4bufbmcgdMOtY2ggY+G7sWMsIG3hurdjIGTDuSBraMOhY2ggaMOgbmcga2jDtG5nIGPDsyDEkeG7kWkgdMOhYy4NCg0KVHLGsOG7nW5nIGjhu6NwIDMgKEtow6FjLCBGaWJlciBvcHRpYywgUGFydG5lciA9IFllcywgU2VuaW9yQ2l0aXplbiA9IDEpOiBYw6FjIHN14bqldCBsw6puIHThu5tpIDQyLDE4JSwgY2FvIG5o4bqldCB0cm9uZyBuaMOzbSwgbmd1ecOqbiBuaMOibiBjaMOtbmggbMOgIGxv4bqhaSBo4bujcCDEkeG7k25nIGtow7RuZyBkw6BpIGjhuqFuIHbDoCBz4butIGThu6VuZyBk4buLY2ggduG7pSBGaWJlciBvcHRpYyDigJMgbmjDs20gZOG7i2NoIHbhu6UgY8OzIHThu7cgbOG7hyBjaHVybiBjYW8gaMahbi4NCg0KVHLGsOG7nW5nIGjhu6NwIDQgKEtow6FjLCBEU0wsIFBhcnRuZXIgPSBObywgU2VuaW9yQ2l0aXplbiA9IDApOiBYw6FjIHN14bqldCAyNCwyMSUsIGNhbyBoxqFuIDIgdHLGsOG7nW5nIGjhu6NwIMSR4bqndSBuaMawbmcgdGjhuqVwIGjGoW4gdHLGsOG7nW5nIGjhu6NwIDMsIHbDrCBraMOhY2ggaMOgbmcga2jDtG5nIGPDsyDEkeG7kWkgdMOhYyB2w6AgaOG7o3AgxJHhu5NuZyBraMO0bmcgZMOgaSBo4bqhbi4NCg0KIyMjICoqMy42LjIgTcO0IGjDrG5oIHByb2JpdCoqDQoNCkLDqm4gY+G6oW5oIG3DtCBow6xuaCBsb2dpdCwgbcO0IGjDrG5oIHByb2JpdCBjxaluZyDEkcaw4bujYyBz4butIGThu6VuZyBuaOG6sW0gcGjDom4gdMOtY2ggeMOhYyBzdeG6pXQga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UuIE3DtCBow6xuaCBwcm9iaXQga2jDoWMgduG7m2kgbG9naXQg4bufIGNo4buXIG7DsyBz4butIGThu6VuZyBow6BtIGxpw6puIGvhur90IChsaW5rIGZ1bmN0aW9uKSBsw6AgaMOgbSBwaMOibiBwaOG7kWkgdMOtY2ggbMWpeSBjaHXhuqluIChDREYpIHRoYXkgdsOsIGjDoG0gbG9naXN0aWMuIFZp4buHYyBzbyBzw6FuaCBoYWkgbcO0IGjDrG5oIGdpw7pwIGtp4buDbSB0cmEgdMOtbmgg4buVbiDEkeG7i25oIHbDoCDEkeG7mSBwaMO5IGjhu6NwIGPhu6dhIGvhur90IHF14bqjIMaw4bubYyBsxrDhu6NuZy4NCg0KYGBge3J9DQpwcm80IDwtIGdsbShmYWN0b3IoQ2h1cm4pIH4gQ29udHJhY3QyICsgSW50ZXJuZXRTZXJ2aWNlICsgUGFydG5lciArIFNlbmlvckNpdGl6ZW4gLCBkYXRhID0gdmllbnRob25nLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rPSJwcm9iaXQiKSkNCnN1bW1hcnkocHJvNCkNCmBgYA0KDQpL4bq/dCBxdeG6oyDGsOG7m2MgbMaw4bujbmcgdOG7qyBtw7QgaMOsbmggcHJvYml0IGNobyB0aOG6pXkgdOG6pXQgY+G6oyBjw6FjIGJp4bq/biDEkeG7mWMgbOG6rXAgYmFvIGfhu5NtIENvbnRyYWN0MiAoT25lIHllYXIpLCBJbnRlcm5ldFNlcnZpY2UgKEZpYmVyIG9wdGljKSwgUGFydG5lciAoWWVzKSB2w6AgU2VuaW9yQ2l0aXplbiDEkeG7gXUgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiDhu58gbeG7qWMgMSUgKHAtdmFsdWUgPCAwLjAxKS4gxJBp4buBdSBuw6B5IGNo4bupbmcgdOG7jyBjw6FjIHnhur91IHThu5EgdHLDqm4gY8OzIHTDoWMgxJHhu5luZyDEkcOhbmcga+G7gyDEkeG6v24geMOhYyBzdeG6pXQga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UuIE3DtCBow6xuaCBQcm9iaXQgxJHGsOG7o2MgdHLDrG5oIGLDoHk6DQoNCiQkDQpQKFx0ZXh0e0NodXJufSA9IFllcykgPSBcUGhpIFxiaWcoIC0wLjY4MzUzIC0gMC42MDgzOCBcY2RvdCBcdGV4dHtDb250cmFjdDJ9X3tcdGV4dHtPbmUgeWVhcn19ICsgMC43MjU2MyBcY2RvdCBcdGV4dHtJbnRlcm5ldFNlcnZpY2V9X3tcdGV4dHtGaWJlciBvcHRpY319IC0gMC40MzMxNyBcY2RvdCBcdGV4dHtQYXJ0bmVyfV97XHRleHR7WWVzfX0gKyAwLjE5MzY2IFxjZG90IFx0ZXh0e1NlbmlvckNpdGl6ZW59IFxiaWcpDQokJA0KDQoNCmBgYHtyfQ0KIyBM4bqleSBo4buHIHPhu5EgdsOgIHAtdmFsdWUgdOG7qyBtw7QgaMOsbmggcHJvYml0LCBi4buPIGTDsm5nIEludGVyY2VwdA0KY29lZl9wcm8gPC0gc3VtbWFyeShwcm80KSRjb2VmZmljaWVudHMNCmNvZWZfcHJvIDwtIGNvZWZfcHJvWy0xLCBdICAjIELhu48gZMOybmcgSW50ZXJjZXB0DQoNCiMgVOG6oW8gYuG6o25nIGvhur90IHF14bqjDQpyZXN1bHRfcHJvYml0IDwtIGRhdGEuZnJhbWUoDQogIEJpZW4gPSByb3duYW1lcyhjb2VmX3BybyksDQogIEhlX3NvID0gcm91bmQoY29lZl9wcm9bLCAxXSwgNSksDQogIHBfdmFsdWUgPSBzaWduaWYoY29lZl9wcm9bLCA0XSwgNCksDQogIERpZW5fZ2lhaSA9IGMoDQogICAgIkjhu4cgc+G7kSDDom0gY2jhu6luZyB04buPIGtow6FjaCBow6BuZyBrw70gaOG7o3AgxJHhu5NuZyAxIG7Eg20gY8OzIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdGjhuqVwIGjGoW4gc28gduG7m2kgbmjhu69uZyBo4bujcCDEkeG7k25nIGtow6FjLiIsDQogICAgIkThuqV1IGTGsMahbmcgY2hvIHRo4bqleSBraMOhY2ggaMOgbmcgc+G7rSBk4bulbmcgZOG7i2NoIHbhu6UgaW50ZXJuZXQgY8OhcCBxdWFuZyAoRmliZXIgb3B0aWMpIGPDsyB4w6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIGNhbyBoxqFuIHNvIHbhu5tpIGtow6FjaCBow6BuZyBkw7luZyBEU0wuIiwNCiAgICAiSMOgbSDDvSBy4bqxbmcga2jDoWNoIGjDoG5nIGPDsyDEkeG7kWkgdMOhYyBob+G6t2MgduG7oyBjaOG7k25nIChQYXJ0bmVyID0gWWVzKSBjw7MgeMOhYyBzdeG6pXQgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0aOG6pXAgaMahbiBzbyB24bubaSBuaOG7r25nIG5nxrDhu51pIMSR4buZYyB0aMOibiBob+G6t2Mga2jDtG5nIGPDsyDEkeG7kWkgdMOhYy4gIiwNCiAgICAiROG6pXUgZMawxqFuZyBjaG8gdGjhuqV5IG5nxrDhu51pIGNhbyB0deG7lWkgKFNlbmlvckNpdGl6ZW4gPSAxKSBjw7MgeMOhYyBzdeG6pXQgcuG7nWkgYuG7jyBk4buLY2ggduG7pSBjYW8gaMahbiBzbyB24bubaSBuZ8aw4budaSB0cuG6uy4iDQogICkNCikNCg0KIyBJbiBi4bqjbmcNCmthYmxlKHJlc3VsdF9wcm9iaXQsIGFsaWduID0gImMiLA0KICAgICAgY29sLm5hbWVzID0gYygiQmnhur9uIiwgIkjhu4cgc+G7kSAozrIpIiwgInAtdmFsdWUiLCAiRGnhu4VuIGdp4bqjaSIpKSAlPiUNCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImNlbnRlciIsIGZvbnRfc2l6ZSA9IDE0KQ0KDQpgYGANCg0KDQoNClNhdSBraGkgeMOieSBk4buxbmcgdsOgIMaw4bubYyBsxrDhu6NuZyBtw7QgaMOsbmggcHJvYml0LCBixrDhu5tjIHRp4bq/cCB0aGVvIGzDoCBz4butIGThu6VuZyBtw7QgaMOsbmggxJHhu4MgZOG7sSBiw6FvIHjDoWMgc3XhuqV0IGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulIChDaHVybikgY2hvIDQgdHLGsOG7nW5nIGjhu6NwIGdp4bqjIMSR4buLbmguIEPhu6UgdGjhu4MsIHRhIHThuqFvIHJhIG3hu5l0IHThuq1wIGThu68gbGnhu4d1IG3hu5tpIChuZXdfZGF0YTUpIHbhu5tpIGPDoWMgdOG7lSBo4bujcCBj4bunYSBiaeG6v24gQ29udHJhY3QyLCBJbnRlcm5ldFNlcnZpY2UsIFBhcnRuZXIgdsOgIFNlbmlvckNpdGl6ZW4sIHNhdSDEkcOzIGTDuW5nIGjDoG0gcHJlZGljdCgpIMSR4buDIHTDrW5oIHjDoWMgc3XhuqV0IGNodXJuIGNobyB04burbmcgdHLGsOG7nW5nIGjhu6NwLg0KDQoNCmBgYHtyfQ0KbmV3X2RhdGE1IDwtIGRhdGEuZnJhbWUoDQogIENvbnRyYWN0MiA9IGZhY3RvcihjKCJPbmUgeWVhciIsICJPbmUgeWVhciIsICJLaMOhYyIsICJLaMOhYyIpKSwgICMgY+G6p24gxJHDum5nIHTDqm4gbGV2ZWxzDQogIEludGVybmV0U2VydmljZSA9IGZhY3RvcihjKCJGaWJlciBvcHRpYyIsICJEU0wiLCAiRmliZXIgb3B0aWMiLCAiRFNMIikpLA0KICBQYXJ0bmVyID0gZmFjdG9yKGMoIlllcyIsICJObyIsICJZZXMiLCAiTm8iKSksDQogIFNlbmlvckNpdGl6ZW4gPSBjKDEsIDAsIDEsIDApDQopDQoNCiMgROG7sSDEkW/DoW4geMOhYyBzdeG6pXQgY2h1cm46DQpwcmVkaWN0KHBybzQsIG5ld2RhdGEgPSBuZXdfZGF0YTUsIHR5cGUgPSAicmVzcG9uc2UiKQ0KYGBgDQoNClRyxrDhu51uZyBo4bujcCAxIChDb250cmFjdCA9IE9uZSB5ZWFyLCBJbnRlcm5ldFNlcnZpY2UgPSBGaWJlciBvcHRpYywgUGFydG5lciA9IFllcywgU2VuaW9yQ2l0aXplbiA9IDEpIGPDsyB4w6FjIHN14bqldCBy4budaSBi4buPIDAuMjEwMiAoa2hv4bqjbmcgMjEuMDIlKS4gTeG6t2MgZMO5IGtow6FjaCBow6BuZyBz4butIGThu6VuZyBk4buLY2ggduG7pSBGaWJlciBvcHRpYyAoeeG6v3UgdOG7kSBsw6BtIHTEg25nIGto4bqjIG7Eg25nIHLhu51pIGLhu48pLCBuaMawbmcgdmnhu4djIGPDsyBo4bujcCDEkeG7k25nIDEgbsSDbSB2w6AgY8OzIMSR4buRaSB0w6FjIGdpw7pwIGdp4bqjbSDEkcOhbmcga+G7gyB4w6FjIHN14bqldCBuw6B5Lg0KDQpUcsaw4budbmcgaOG7o3AgMiAoQ29udHJhY3QgPSBPbmUgeWVhciwgSW50ZXJuZXRTZXJ2aWNlID0gRFNMLCBQYXJ0bmVyID0gTm8sIFNlbmlvckNpdGl6ZW4gPSAwKSBjw7MgeMOhYyBzdeG6pXQgcuG7nWkgYuG7jyAwLjA5ODIgKGtob+G6o25nIDkuODIlKSwgdGjhuqVwIG5o4bqldCB0cm9uZyA0IHRyxrDhu51uZyBo4bujcC4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgaOG7o3AgxJHhu5NuZyBkw6BpIGjhuqFuIHbDoCBk4buLY2ggduG7pSBEU0wgbMOgIGPDoWMgeeG6v3UgdOG7kSDhu5VuIMSR4buLbmgsIGjhuqFuIGNo4bq/IGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UuDQoNClRyxrDhu51uZyBo4bujcCAzIChDb250cmFjdCA9IEtow6FjLCBJbnRlcm5ldFNlcnZpY2UgPSBGaWJlciBvcHRpYywgUGFydG5lciA9IFllcywgU2VuaW9yQ2l0aXplbiA9IDEpIGPDsyB4w6FjIHN14bqldCBy4budaSBi4buPIDAuNDIxOCAoa2hv4bqjbmcgNDIuMTglKSwgY2FvIG5o4bqldCB0cm9uZyA0IHRyxrDhu51uZyBo4bujcC4gTmd1ecOqbiBuaMOibiBsw6AgZG8ga2jDoWNoIGjDoG5nIGtow7RuZyBz4butIGThu6VuZyBo4bujcCDEkeG7k25nIGTDoGkgaOG6oW4gdsOgIMSRYW5nIGTDuW5nIGThu4tjaCB24bulIEZpYmVyIG9wdGljLCBr4bq/dCBo4bujcCB24bubaSB54bq/dSB04buRIGNhbyB0deG7lWksIGzDoG0gdMSDbmcgbmd1eSBjxqEgcuG7nWkgYuG7jy4NCg0KVHLGsOG7nW5nIGjhu6NwIDQgKENvbnRyYWN0ID0gS2jDoWMsIEludGVybmV0U2VydmljZSA9IERTTCwgUGFydG5lciA9IE5vLCBTZW5pb3JDaXRpemVuID0gMCkgY8OzIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gMC4yNDcxIChraG/huqNuZyAyNC43MSUpLiBN4bq3YyBkw7kgZOG7i2NoIHbhu6UgRFNMIGzDoG0gZ2nhuqNtIG5ndXkgY8ahIHLhu51pIGLhu48gc28gduG7m2kgRmliZXIgb3B0aWMsIG5oxrBuZyB2aeG7h2Mga2jDtG5nIGPDsyBo4bujcCDEkeG7k25nIGTDoGkgaOG6oW4gdsOgIGtow7RuZyBjw7MgxJHhu5FpIHTDoWMga2hp4bq/biB4w6FjIHN14bqldCBuw6B5IHbhuqtuIGtow6EgY2FvLg0KDQpDaMOqbmggbOG7h2NoIGzhu5tuIG5o4bqldCBu4bqxbSBnaeG7r2EgdHLGsOG7nW5nIGjhu6NwIDIgKDkuODIlKSB2w6AgdHLGsOG7nW5nIGjhu6NwIDMgKDQyLjE4JSksIGNobyB0aOG6pXkgdmFpIHRyw7IgcXVhbiB0cuG7jW5nIGPhu6dhIGjhu6NwIMSR4buTbmcgMSBuxINtIHbDoCB2aeG7h2Mga2jDtG5nIHPhu60gZOG7pW5nIEZpYmVyIG9wdGljIHRyb25nIHZp4buHYyBnaeG7ryBjaMOibiBraMOhY2ggaMOgbmcuDQoNCg0KIyMjICoqMy42LjMgTcO0IGjDrG5oIGNsb2dsb2cqKg0KDQpUaeG6v3AgdGhlbywgxJHhu4MgcGjDom4gdMOtY2ggeMOhYyBzdeG6pXQga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UsIG3DtCBow6xuaCBo4buTaSBxdXkgduG7m2kgaMOgbSBsacOqbiBr4bq/dCBjb21wbGVtZW50YXJ5IGxvZy1sb2cgKGNsb2dsb2cpIMSRxrDhu6NjIHjDonkgZOG7sW5nLiBNw7QgaMOsbmggY2xvZ2xvZyDEkcaw4bujYyBz4butIGThu6VuZyBwaOG7lSBiaeG6v24gdHJvbmcgY8OhYyB0csaw4budbmcgaOG7o3AgbcOgIHjDoWMgc3XhuqV0IHjhuqN5IHJhIHPhu7Ega2nhu4duICjhu58gxJHDonkgbMOgIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulKSBraMO0bmcgxJHhu5FpIHjhu6luZywgdOG7qWMga2hpIGto4bqjIG7Eg25nIHjhuqN5IHJhIHPhu7Ega2nhu4duIGzDoCBy4bqldCB0aOG6pXAgaG/hurdjIHLhuqV0IGNhby4gS2jDoWMgduG7m2kgbG9naXQgdsOgIHByb2JpdCwgY2xvZ2xvZyBz4butIGThu6VuZyBow6BtIGxpw6puIGvhur90IGThuqFuZyBcKCBnKHApID0gXGxvZygtXGxvZygxLXApKSBcKS4gTcO0IGjDrG5oIG7DoHkgY2hvIHBow6lwIHBow6JuIHTDrWNoIHjDoWMgc3XhuqV0IHbhu5tpIHThu5FjIMSR4buZIHTEg25nIGtow7RuZyDEkeG7k25nIMSR4buBdSwgxJHhurdjIGJp4buHdCBwaMO5IGjhu6NwIGNobyBk4buvIGxp4buHdSB24bubaSBoaeG7h24gdMaw4bujbmcgcuG7nWkgYuG7jyBtYW5nIHTDrW5oIGhp4bq/bSBn4bq3cCBob+G6t2MgdOG6rXAgdHJ1bmcgbeG6oW5oLiBExrDhu5tpIMSRw6J5IGzDoCBr4bq/dCBxdeG6oyDGsOG7m2MgbMaw4bujbmcgY+G7p2EgbcO0IGjDrG5oIGNsb2dsb2cuDQoNCmBgYHtyfQ0KY2xvNCA8LSBnbG0oZmFjdG9yKENodXJuKSB+IENvbnRyYWN0MiArIEludGVybmV0U2VydmljZSArIFBhcnRuZXIgKyBTZW5pb3JDaXRpemVuICwgZGF0YSA9IHZpZW50aG9uZywgZmFtaWx5ID0gYmlub21pYWwobGluaz0iY2xvZ2xvZyIpKQ0Kc3VtbWFyeShjbG80KQ0KYGBgDQoNClThuqV0IGPhuqMgY8OhYyBiaeG6v24gxJHhu5ljIGzhuq1wIChDb250cmFjdDJPbmUgeWVhciwgSW50ZXJuZXRTZXJ2aWNlRmliZXIgb3B0aWMsIFBhcnRuZXJZZXMsIFNlbmlvckNpdGl6ZW4pIMSR4buBdSBjw7MgcC12YWx1ZSA8IDAuMDAxIChrw70gaGnhu4d1ICoqKikuIMSQaeG7gXUgbsOgeSBjaOG7qW5nIHThu48gdOG6pXQgY+G6oyBjw6FjIGJp4bq/biDEkeG7gXUgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiBjYW8sIOG6o25oIGjGsOG7n25nIHLDtSBy4buHdCDEkeG6v24geMOhYyBzdeG6pXQga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKENodXJuKS4gVGEgY8OzIG3DtCBow6xuaCBjbG9nbG9nIG5oxrAgc2F1OiANCg0KJCQNClxsb2coLVxsb2coMS1wKSkgPSBcIC0xLjMxNTU4ICBcIC0wLjkyNjQ4IFxjZG90IFx0ZXh0e0NvbnRyYWN0Mk9uZSB5ZWFyfSANCisgMS4wMTM5MyAgXGNkb3QgXHRleHR7SW50ZXJuZXRTZXJ2aWNlRmliZXIgb3B0aWN9DQpcIC0wLjU1ODQyXGNkb3QgXHRleHR7UGFydG5lclllc30NCisgXCAwLjIzODAzXGNkb3QgXHRleHR7U2VuaW9yQ2l0aXplbn0NCiQkDQoNCkvhur90IHF14bqjIG3DtCBow6xuaCBo4buTaSBxdXkgY2xvZ2xvZyBjaG8gdGjhuqV5IGPhuqMgYuG7kW4gYmnhur9uIMSR4buZYyBs4bqtcCDEkeG7gXUgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiBjYW8gdHJvbmcgdmnhu4djIGThu7EgxJFvw6FuIGto4bqjIG7Eg25nIGtow6FjaCBow6BuZyBy4budaSBi4buPIGThu4tjaCB24bulLiBD4bulIHRo4buDLCBiaeG6v24gQ29udHJhY3QyT25lIHllYXIgY8OzIGjhu4cgc+G7kSDDom0gKC0wLjkyNjQ4KSwgY2hvIHRo4bqleSBraMOhY2ggaMOgbmcgY8OzIGjhu6NwIMSR4buTbmcgbeG7mXQgbsSDbSBjw7MgeMOhYyBzdeG6pXQgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB0aOG6pXAgaMahbiBzbyB24bubaSBuaMOzbSBjw7JuIGzhuqFpICkuIFTGsMahbmcgdOG7sSwga2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIChQYXJ0bmVyWWVzKSBjxaluZyDDrXQgcuG7nWkgYuG7jyBoxqFuLCBwaOG6o24gw6FuaCBxdWEgaOG7hyBz4buRIMOibSAtMC41NTg0Mi4gTmfGsOG7o2MgbOG6oWksIGThu4tjaCB24bulIEludGVybmV0IGPDoXAgcXVhbmcgKEZpYmVyIG9wdGljKSBjw7MgaOG7hyBz4buRIGTGsMahbmcgY2FvICgxLjAxMzkzKSwgY2hvIHRo4bqleSB4w6FjIHN14bqldCBy4budaSBi4buPIHTEg25nIG3huqFuaCBu4bq/dSBraMOhY2ggaMOgbmcgc+G7rSBk4bulbmcgZOG7i2NoIHbhu6UgbsOgeSwgY8OzIHRo4buDIGRvIGNo4bqldCBsxrDhu6NuZyBob+G6t2MgY2hpIHBow60gY2jGsGEgxJHDoXAg4bupbmcga+G7syB24buNbmcuIEJp4bq/biBTZW5pb3JDaXRpemVuIHbhu5tpIGjhu4cgc+G7kSBkxrDGoW5nICgwLjIzODAzKSBuZ+G7pSDDvSBuZ8aw4budaSBjYW8gdHXhu5VpIGPDsyB4dSBoxrDhu5tuZyBy4budaSBi4buPIGThu4tjaCB24bulIG5oaeG7gXUgaMahbiwgZMO5IG3hu6ljIMSR4buZIHTDoWMgxJHhu5luZyBraMO0bmcgbOG7m24uDQoNClNhdSBraGkgeMOieSBk4buxbmcgdsOgIMaw4bubYyBsxrDhu6NuZyBtw7QgaMOsbmggY2xvZ2xvZywgYsaw4bubYyB0aeG6v3AgdGhlbyBsw6Agc+G7rSBk4bulbmcgbcO0IGjDrG5oIMSR4buDIGThu7EgYsOhbyB4w6FjIHN14bqldCBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSAoQ2h1cm4pIGNobyA0IHRyxrDhu51uZyBo4bujcCBnaeG6oyDEkeG7i25oLiBD4bulIHRo4buDLCB0YSB04bqhbyByYSBt4buZdCB04bqtcCBk4buvIGxp4buHdSBt4bubaSAobmV3X2RhdGE2KSB24bubaSBjw6FjIHThu5UgaOG7o3AgY+G7p2EgYmnhur9uIENvbnRyYWN0MiwgSW50ZXJuZXRTZXJ2aWNlLCBQYXJ0bmVyIHbDoCBTZW5pb3JDaXRpemVuLCBzYXUgxJHDsyBkw7luZyBow6BtIHByZWRpY3QoKSDEkeG7gyB0w61uaCB4w6FjIHN14bqldCBjaHVybiBjaG8gdOG7q25nIHRyxrDhu51uZyBo4bujcC4NCg0KDQpgYGB7cn0NCm5ld19kYXRhNiA8LSBkYXRhLmZyYW1lKA0KICBDb250cmFjdDIgPSBmYWN0b3IoYygiT25lIHllYXIiLCAiT25lIHllYXIiLCAiS2jDoWMiLCAiS2jDoWMiKSksICAjIGPhuqduIMSRw7puZyB0w6puIGxldmVscw0KICBJbnRlcm5ldFNlcnZpY2UgPSBmYWN0b3IoYygiRmliZXIgb3B0aWMiLCAiRFNMIiwgIkZpYmVyIG9wdGljIiwgIkRTTCIpKSwNCiAgUGFydG5lciA9IGZhY3RvcihjKCJZZXMiLCAiTm8iLCAiWWVzIiwgIk5vIikpLA0KICBTZW5pb3JDaXRpemVuID0gYygxLCAwLCAxLCAwKQ0KKQ0KDQojIEThu7EgxJFvw6FuIHjDoWMgc3XhuqV0IGNodXJuOg0KcHJlZGljdChjbG80LCBuZXdkYXRhID0gbmV3X2RhdGE2LCB0eXBlID0gInJlc3BvbnNlIikNCmBgYA0KDQpUcsaw4budbmcgaOG7o3AgMTogS2jDoWNoIGjDoG5nIGvDvSBo4bujcCDEkeG7k25nIDEgbsSDbSwgc+G7rSBk4bulbmcgZOG7i2NoIHbhu6UgSW50ZXJuZXQgY8OhcCBxdWFuZyAoRmliZXIgb3B0aWMpLCBjw7MgduG7oyBjaOG7k25nIHbDoCB0aHXhu5ljIG5ow7NtIG5nxrDhu51pIGNhbyB0deG7lWkgY8OzIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgbMOgIDE5LDElLiBN4bq3YyBkw7kgdmnhu4djIGvDvSBo4bujcCDEkeG7k25nIGTDoGkgaOG6oW4gdsOgIGPDsyBuZ8aw4budaSB0aMOibiBz4buRbmcgY8O5bmcgZ2nDunAgZ2nhuqNtIGto4bqjIG7Eg25nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UsIG5oxrBuZyB54bq/dSB04buRIHPhu60gZOG7pW5nIEZpYmVyIG9wdGljIHbDoCB2aeG7h2MgdGh14buZYyBuaMOzbSBraMOhY2ggaMOgbmcgY2FvIHR14buVaSBs4bqhaSBsw6AgeeG6v3UgbMOgbSB0xINuZyBy4bunaSBybyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBk4buLY2ggduG7pSB2aeG7hW4gdGjDtG5nLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSBuaMOzbSBraMOhY2ggaMOgbmcgbOG7m24gdHXhu5VpIHbDoCBz4butIGThu6VuZyBk4buLY2ggduG7pSB04buRYyDEkeG7mSBjYW8gduG6q24gY+G6p24gxJHGsOG7o2MgZHV5IHRyw6wgY2jEg20gc8OzYyB2w6AgdOG6oW8gY8OhYyDGsHUgxJHDo2kgbmjhurFtIGdp4bqjbSB04bu3IGzhu4cgcuG7nWkgYuG7jy4NCg0KVHLGsOG7nW5nIGjhu6NwIDI6IFbhu5tpIGtow6FjaCBow6BuZyBjxaluZyBrw70gaOG7o3AgxJHhu5NuZyAxIG7Eg20sIG5oxrBuZyBz4butIGThu6VuZyBk4buLY2ggduG7pSBEU0wsIGtow7RuZyBjw7MgbmfGsOG7nWkgdGjDom4gc+G7kW5nIGPDuW5nIChQYXJ0bmVyID0gTm8pIHbDoCBraMO0bmcgdGh14buZYyBuaMOzbSBuZ8aw4budaSBjYW8gdHXhu5VpLCB4w6FjIHN14bqldCBy4budaSBi4buPIGThu4tjaCB24bulIGNo4buJIOG7nyBt4bupYyAxMCwxJSwgdGjhuqVwIG5o4bqldCB0cm9uZyBi4buRbiB0csaw4budbmcgaOG7o3AuIEvhur90IHF14bqjIG7DoHkgcGjhuqNuIMOhbmggdmFpIHRyw7IgcXVhbiB0cuG7jW5nIGPhu6dhIGjhu6NwIMSR4buTbmcgZMOgaSBo4bqhbiB2w6AgbG/huqFpIGThu4tjaCB24bulIERTTCwgduG7kW4gw610IGJp4bq/biDEkeG7mW5nIHbDoCDDrXQgY2jhu4t1IOG6o25oIGjGsOG7n25nIHThu6sgeeG6v3UgdOG7kSBj4bqhbmggdHJhbmguIMSQw6J5IGzDoCBuaMOzbSBraMOhY2ggaMOgbmcgY8OzIHTDrW5oIOG7lW4gxJHhu4tuaCBjYW8sIG5oxrBuZyB24bqrbiBj4bqnbiBjaGnhur9uIGzGsOG7o2MgZ2nhu68gY2jDom4gY8ahIGLhuqNuIMSR4buDIGR1eSB0csOsIG3hu6ljIMSR4buZIGjDoGkgbMOybmcuDQoNClRyxrDhu51uZyBo4bujcCAzOiBLaMOhY2ggaMOgbmcga2jDtG5nIGvDvSBo4bujcCDEkeG7k25nIDEgbsSDbSwgc+G7rSBk4bulbmcgRmliZXIgb3B0aWMsIGPDsyBuZ8aw4budaSB0aMOibiBz4buRbmcgY8O5bmcgdsOgIHRodeG7mWMgbmjDs20gbmfGsOG7nWkgY2FvIHR14buVaSwgY8OzIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY2FvIG5o4bqldCwgbMOqbiDEkeG6v24gNDEsNSUuIFZp4buHYyBraMO0bmcgY8OzIGNhbSBr4bq/dCBkw6BpIGjhuqFuIGtoaeG6v24gbmjDs20ga2jDoWNoIGjDoG5nIG7DoHkgZOG7hSBkw6BuZyBjw6JuIG5o4bqvYyB0aGF5IMSR4buVaSBuaMOgIGN1bmcgY+G6pXAsIMSR4bq3YyBiaeG7h3Qga2hpIHPhu60gZOG7pW5nIGThu4tjaCB24bulIHThu5FjIMSR4buZIGNhbyBuaMawIEZpYmVyIG9wdGljLCB24buRbiB0aMaw4budbmcgY8OzIG5oaeG7gXUgbOG7sWEgY2jhu41uIHRoYXkgdGjhur8uIMSQw6J5IGzDoCBuaMOzbSBraMOhY2ggaMOgbmcgcuG7p2kgcm8gY2FvIG5o4bqldCwgxJHDsmkgaOG7j2kgZG9hbmggbmdoaeG7h3AgcGjhuqNpIMOhcCBk4bulbmcgY8OhYyBjaGnhur9uIGzGsOG7o2MgZ2nhu68gY2jDom4gbmjGsCBraHV54bq/biBtw6NpLCBnaeG6o20gZ2nDoSBob+G6t2MgZ8OzaSBk4buLY2ggduG7pSBkw6BpIGjhuqFuIGjhuqVwIGThuqtuLg0KDQpUcsaw4budbmcgaOG7o3AgNDogxJDhu5FpIHbhu5tpIGtow6FjaCBow6BuZyBraMO0bmcga8O9IGjhu6NwIMSR4buTbmcgMSBuxINtLCBz4butIGThu6VuZyBEU0wsIGtow7RuZyBjw7MgbmfGsOG7nWkgdGjDom4gc+G7kW5nIGPDuW5nIHbDoCBraMO0bmcgcGjhuqNpIG5nxrDhu51pIGNhbyB0deG7lWksIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgbMOgIDIzLDUlLCBjYW8gaMahbiB0csaw4budbmcgaOG7o3AgMSB2w6AgMiBuaMawbmcgdGjhuqVwIGjGoW4gbmhp4buBdSBzbyB24bubaSB0csaw4budbmcgaOG7o3AgMy4gTeG6t2MgZMO5IGtow7RuZyBrw70gaOG7o3AgxJHhu5NuZyBkw6BpIGjhuqFuIGzDoG0gdMSDbmcga2jhuqMgbsSDbmcgcuG7nWkgYuG7jywgbmjGsG5nIGxv4bqhaSBk4buLY2ggduG7pSBEU0wgdsOgIG5ow7NtIGtow6FjaCBow6BuZyB0cuG6uyB0deG7lWkgZ2nDunAgeMOhYyBzdeG6pXQgcuG7nWkgYuG7jyDhu58gbeG7qWMgdHJ1bmcgYsOsbmguIE5ow7NtIGtow6FjaCBow6BuZyBuw6B5IHbhuqtuIGPhuqduIGPDoWMgY2jDrW5oIHPDoWNoIGtodXnhur9uIGtow61jaCBnaWEgaOG6oW4gaOG7o3AgxJHhu5NuZyBob+G6t2MgbsOibmcgY+G6pXAgZOG7i2NoIHbhu6UgxJHhu4MgZ2nhuqNtIHLhu6dpIHJvIHLhu51pIGLhu48uDQoNCg0KIyMjICoqMy42LjQgxJDDoW5oIGdpw6EgbcO0IGjDrG5oKioNCg0KU2F1IGtoaSB0aeG6v24gaMOgbmggxrDhu5tjIGzGsOG7o25nIGJhIG3DtCBow6xuaCBo4buTaSBxdXkgbmjhu4sgcGjDom4gZ+G7k20gKipsb2dpdCoqLCAqKnByb2JpdCoqIHbDoCAqKmNsb2dsb2cqKiwgYsaw4bubYyB0aeG6v3AgdGhlbyBsw6AgxJHDoW5oIGdpw6EgdsOgIHNvIHPDoW5oIG3hu6ljIMSR4buZIHBow7kgaOG7o3AgY+G7p2EgY8OhYyBtw7QgaMOsbmggbsOgeS4gVmnhu4djIMSRw6FuaCBnacOhIMSRxrDhu6NjIHRo4buxYyBoaeG7h24gZOG7sWEgdHLDqm4gY8OhYyBjaOG7iSB0acOqdSB0aOG7kW5nIGvDqiBuaMawICoqZ2nDoSB0cuG7iyBBSUMqKiwgKipCSUMqKiwgKipCcmllcl9TY29yZSoqIHbDoCAqKm1hIHRy4bqtbiBuaOG6p20gbOG6q24qKi4gTmdvw6BpIHJhLCBraOG6oyBuxINuZyBk4buxIGLDoW8geMOhYyBzdeG6pXQgY+G7p2EgdOG7q25nIG3DtCBow6xuaCDEkeG7kWkgduG7m2kgY8OhYyB0csaw4budbmcgaOG7o3AgZ2nhuqMgxJHhu4tuaCBj4bulIHRo4buDIGPFqW5nIMSRxrDhu6NjIHhlbSB4w6l0IMSR4buDIGzhu7FhIGNo4buNbiBtw7QgaMOsbmggcGjDuSBo4bujcCBuaOG6pXQuDQoNCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgc28gc8OhbmgNCm1vZGVsX2V2YWw0IDwtIGRhdGEuZnJhbWUoDQogIE3DtF9ow6xuaCA9IGMoIkxvZ2l0IiwgIlByb2JpdCIsICJDbG9nbG9nIiksDQogIEFJQyA9IGMoQUlDKGxvZzQpLCBBSUMocHJvNCksIEFJQyhjbG80KSksDQogIEJJQyA9IGMoQklDKGxvZzQpLCBCSUMocHJvNCksIEJJQyhjbG80KSksDQogIEJyaWVyX1Njb3JlID0gYyhCcmllclNjb3JlKGxvZzQpLCBCcmllclNjb3JlKHBybzQpLCBCcmllclNjb3JlKGNsbzQpKQ0KKQ0Ka2FibGUobW9kZWxfZXZhbDQsIGFsaWduID0gImMiLCBjYXB0aW9uID0gIlNvIHPDoW5oIGPDoWMgY2jhu4kgc+G7kSDEkcOhbmggZ2nDoSBtw7QgaMOsbmgiKSAlPiUNCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImNlbnRlciIsIGZvbnRfc2l6ZSA9IDE0KQ0KYGBgDQoNCk3hurdjIGTDuSBj4bqjIGJhIG3DtCBow6xuaCDEkeG7gXUgY2hvIGvhur90IHF14bqjIGtow6EgdMawxqFuZyDEkcawxqFuZywgbcO0IGjDrG5oIExvZ2l0IG7hu5VpIGLhuq10IGjGoW4gbeG7mXQgY8OhY2ggdG/DoG4gZGnhu4duIOG7nyBj4bqjIGJhIHRpw6p1IGNow60gKEFJQywgQklDIHbDoCBCcmllciBTY29yZSkuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IG3DtCBow6xuaCBMb2dpdCBsw6AgbOG7sWEgY2jhu41uIHBow7kgaOG7o3AgbmjhuqV0IHRyb25nIHRyxrDhu51uZyBo4bujcCBuw6B5IMSR4buDIHBow6JuIHTDrWNoIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2Ega2jDoWNoIGjDoG5nLg0KDQoqKk1hIHRy4bqtbiBuaOG6p20gbOG6q24qKg0KDQotIE3DtCBow6xuaCBMb2dpdCANCg0KYGBge3J9DQojIEThu7EgxJFvw6FuIHjDoWMgc3XhuqV0DQpwcm9iMiA8LSBwcmVkaWN0KGxvZzQsIHR5cGUgPSAicmVzcG9uc2UiKQ0KDQojIENodXnhu4NuIHjDoWMgc3XhuqV0IHRow6BuaCBuaMOjbiAiWWVzIi8iTm8iIHbhu5tpIG5nxrDhu6FuZyAwLjUNCnByZWRpY3RlZF9jbGFzczIgPC0gaWZlbHNlKHByb2IyID49IDAuNSwgIlllcyIsICJObyIpDQojIENodXnhu4NuIHbhu4EgZmFjdG9yIMSR4buDIHRo4buRbmcgbmjhuqV0DQpwcmVkaWN0ZWRfY2xhc3MyIDwtIGZhY3RvcihwcmVkaWN0ZWRfY2xhc3MyLCBsZXZlbHMgPSBjKCJObyIsICJZZXMiKSkNCnRydWVfY2xhc3MyIDwtIGZhY3Rvcih2aWVudGhvbmckQ2h1cm4sIGxldmVscyA9IGMoIk5vIiwgIlllcyIpKQ0KY29uZnVzaW9uTWF0cml4KGRhdGEgPSBwcmVkaWN0ZWRfY2xhc3MyLCByZWZlcmVuY2UgPSB0cnVlX2NsYXNzMiwgcG9zaXRpdmUgPSAiWWVzIikNCg0KYGBgDQoNCi0gTcO0IGjDrG5oIHByb2JpdCANCg0KYGBge3J9DQojIEThu7EgxJFvw6FuIHjDoWMgc3XhuqV0DQpwcm9iMyA8LSBwcmVkaWN0KHBybzQsIHR5cGUgPSAicmVzcG9uc2UiKQ0KDQojIENodXnhu4NuIHjDoWMgc3XhuqV0IHRow6BuaCBuaMOjbiAiWWVzIi8iTm8iIHbhu5tpIG5nxrDhu6FuZyAwLjUNCnByZWRpY3RlZF9jbGFzczMgPC0gaWZlbHNlKHByb2IzPj0gMC41LCAiWWVzIiwgIk5vIikNCg0KIyBDaHV54buDbiB24buBIGZhY3RvciDEkeG7gyB0aOG7kW5nIG5o4bqldA0KcHJlZGljdGVkX2NsYXNzMyA8LSBmYWN0b3IocHJlZGljdGVkX2NsYXNzMywgbGV2ZWxzID0gYygiTm8iLCAiWWVzIikpDQp0cnVlX2NsYXNzMyA8LSBmYWN0b3IodmllbnRob25nJENodXJuLCBsZXZlbHMgPSBjKCJObyIsICJZZXMiKSkNCmNvbmZ1c2lvbk1hdHJpeChkYXRhID0gcHJlZGljdGVkX2NsYXNzMywgcmVmZXJlbmNlID0gdHJ1ZV9jbGFzczMsIHBvc2l0aXZlID0gIlllcyIpDQoNCmBgYA0KDQotIE3DtCBow6xuaCBjbG9nbG9nIA0KDQpgYGB7cn0NCiMgROG7sSDEkW/DoW4geMOhYyBzdeG6pXQNCnByb2I0PC0gcHJlZGljdChjbG80LCB0eXBlID0gInJlc3BvbnNlIikNCg0KIyBDaHV54buDbiB4w6FjIHN14bqldCB0aMOgbmggbmjDo24gIlllcyIvIk5vIiB24bubaSBuZ8aw4buhbmcgMC41DQpwcmVkaWN0ZWRfY2xhc3M0IDwtIGlmZWxzZShwcm9iNCA+PSAwLjUsICJZZXMiLCAiTm8iKQ0KDQojIENodXnhu4NuIHbhu4EgZmFjdG9yIMSR4buDIHRo4buRbmcgbmjhuqV0DQpwcmVkaWN0ZWRfY2xhc3M0IDwtIGZhY3RvcihwcmVkaWN0ZWRfY2xhc3M0LCBsZXZlbHMgPSBjKCJObyIsICJZZXMiKSkNCnRydWVfY2xhc3M0IDwtIGZhY3Rvcih2aWVudGhvbmckQ2h1cm4sIGxldmVscyA9IGMoIk5vIiwgIlllcyIpKQ0KY29uZnVzaW9uTWF0cml4KGRhdGEgPSBwcmVkaWN0ZWRfY2xhc3M0LCByZWZlcmVuY2UgPSB0cnVlX2NsYXNzNCwgcG9zaXRpdmUgPSAiWWVzIikNCg0KYGBgDQoNCg0KROG7sWEgdHLDqm4gY8OhYyBtYSB0cuG6rW4gbmjhuqdtIGzhuqtuIHRyb25nIGvhur90IHF14bqjIHRyxrDhu5tjIHbDoCBow6xuaCBtaW5oIGjhu41hIFRQLCBGUCwgRk4sIFROLCB0YSBjw7M6DQoNCi0gVFAgKFRydWUgUG9zaXRpdmUpID0gNzU2OiBT4buRIGtow6FjaCBow6BuZyB0aOG7sWMgc+G7sSBy4budaSBi4buPIChZZXMpIHbDoCBtw7QgaMOsbmggY8WpbmcgZOG7sSDEkW/DoW4gxJHDum5nIGzDoCBy4budaSBi4buPLg0KDQotIEZQIChGYWxzZSBQb3NpdGl2ZSkgPSA2NDY6IFPhu5Ega2jDoWNoIGjDoG5nIHRo4buxYyB04bq/IGtow7RuZyBy4budaSBi4buPIChObykgbmjGsG5nIG3DtCBow6xuaCBk4buxIMSRb8OhbiBzYWkgbMOgIHLhu51pIGLhu48uDQoNCi0gRk4gKEZhbHNlIE5lZ2F0aXZlKSA9IDgzMDogU+G7kSBraMOhY2ggaMOgbmcgdGjhu7FjIHThur8gcuG7nWkgYuG7jyAoWWVzKSBuaMawbmcgbcO0IGjDrG5oIGThu7EgxJFvw6FuIHNhaSBsw6Aga2jDtG5nIHLhu51pIGLhu48uDQoNCi0gVE4gKFRydWUgTmVnYXRpdmUpID0gMjYwMDogU+G7kSBraMOhY2ggaMOgbmcgdGjhu7FjIHThur8ga2jDtG5nIHLhu51pIGLhu48gKE5vKSB2w6AgbcO0IGjDrG5oIGPFqW5nIGThu7EgxJFvw6FuIMSRw7puZyBsw6Aga2jDtG5nIHLhu51pIGLhu48uDQoNCk3DtCBow6xuaCBk4buxIMSRb8OhbiDEkcO6bmcgMy4zNTYgdHJvbmcgdOG7lW5nIHPhu5EgNC44MzIga2jDoWNoIGjDoG5nLCDEkeG6oXQgxJHhu5kgY2jDrW5oIHjDoWMga2hv4bqjbmcgNjksNDUlLlRyb25nIGtoaSBraOG6oyBuxINuZyBuaOG6rW4gZGnhu4duIGtow6FjaCBow6BuZyBraMO0bmcgcuG7nWkgYuG7jyAoU3BlY2lmaWNpdHkpIGtow6EgY2FvIHbhu5tpIDgwLDElLCBtw7QgaMOsbmggY2jhu4kgZOG7sSDEkW/DoW4gxJHDum5nIDQ3LDclIHPhu5Ega2jDoWNoIGjDoG5nIHRo4buxYyBz4buxIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgKFNlbnNpdGl2aXR5KS4gS2hpIGThu7EgxJFvw6FuIG3hu5l0IGtow6FjaCBow6BuZyBz4bq9IHLhu51pIGLhu48sIHThu7cgbOG7hyDEkcO6bmcgY2jhu4kgxJHhuqF0IGtob+G6o25nIDUzLDklLCB04bupYyBsw6AgdHJvbmcgMTAgbmfGsOG7nWkgxJHGsOG7o2MgZOG7sSDEkW/DoW4gcuG7nWkgYuG7jyBjaOG7iSBjw7MgNeKAkzYgbmfGsOG7nWkgdGjhu7FjIHPhu7EgcuG7nWkgYuG7jy4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgbcO0IGjDrG5oIGPDsyB4dSBoxrDhu5tuZyB0aGnDqm4gduG7gSBk4buxIMSRb8OhbiDigJxraMO0bmcgcuG7nWkgYuG7j+KAnSB24bubaSBTcGVjaWZpY2l0eSBjYW8gKDgwLDElKSwgdHJvbmcga2hpIGto4bqjIG7Eg25nIG5o4bqtbiBkaeG7h24ga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gKFNlbnNpdGl2aXR5KSBjw7JuIHRo4bqlcCAoNDcsNyUpLiBLaGkgbcO0IGjDrG5oIGThu7EgxJFvw6FuIGtow6FjaCBow6BuZyBz4bq9IHLhu51pIGLhu48sIHThu7cgbOG7hyBk4buxIMSRb8OhbiDEkcO6bmcgY2jhu4kgxJHhuqF0IGtob+G6o25nIDUzLDklIChQcmVjaXNpb24pLiBOaMOsbiBjaHVuZywgbcO0IGjDrG5oIGhv4bqhdCDEkeG7mW5nIOG7lW4gduG7m2kgbmjDs20ga2jDoWNoIGjDoG5nIOKAnGtow7RuZyBy4budaSBi4buP4oCdIG5oxrBuZyBj4bqnbiBj4bqjaSB0aGnhu4duIMSR4buDIHBow6F0IGhp4buHbiBjaMOtbmggeMOhYyBoxqFuIG5ow7NtIGtow6FjaCBow6BuZyDigJxy4budaSBi4buP4oCdLg0KDQojIyAqKjMuNyBL4bq/dCBsdeG6rW4gdsOgIGtodXnhur9uIG5naOG7iyoqDQoNCiMjIyAqKjMuNy4xIEvhur90IGx14bqtbioqDQoNCkvhur90IHF14bqjIHBow6JuIHTDrWNoIGNobyB0aOG6pXkgY8OhYyB54bq/dSB04buRIG5oxrAgbG/huqFpIGjhu6NwIMSR4buTbmcsIGxv4bqhaSBow6xuaCBk4buLY2ggduG7pSBJbnRlcm5ldCwgxJHhu5kgdHXhu5VpIHbDoCB0w6xuaCB0cuG6oW5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGhv4bq3YyDEkeG7kWkgdMOhYyDEkcOzbmcgdmFpIHRyw7IgcXVhbiB0cuG7jW5nIHRyb25nIHZp4buHYyDEkeG7i25oIGjDrG5oIGjDoG5oIHZpIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgY+G7p2Ega2jDoWNoIGjDoG5nLiBQaMOibiB0w61jaCBow6BuaCB2aSBy4budaSBi4buPIGThu4tjaCB24bulIChjaHVybikgdOG7qyBk4buvIGxp4buHdSBj4bunYSA0LjgzMiBraMOhY2ggaMOgbmcgY2hvIHRo4bqleSB04bu3IGzhu4cgcuG7nWkgYuG7jyB04buVbmcgdGjhu4MgxJHhuqF0IDMyLDgyJSwgcGjhuqNuIMOhbmggbeG7mXQgdGjDoWNoIHRo4bupYyDEkcOhbmcga+G7gyDEkeG7kWkgduG7m2kgZG9hbmggbmdoaeG7h3AgdHJvbmcgdmnhu4djIGR1eSB0csOsIGtow6FjaCBow6BuZy4gS+G6v3QgcXXhuqMgcGjDom4gdMOtY2ggxJHGoW4gYmnhur9uIHbDoCDEkWEgYmnhur9uIGto4bqzbmcgxJHhu4tuaCBjw6FjIHnhur91IHThu5EgcXVhbiB0cuG7jW5nIOG6o25oIGjGsOG7n25nIMSR4bq/biBjaHVybiBiYW8gZ+G7k20gbG/huqFpIGjhu6NwIMSR4buTbmcgKENvbnRyYWN0KSwgbG/huqFpIGjDrG5oIGThu4tjaCB24bulIEludGVybmV0IChJbnRlcm5ldFNlcnZpY2UpLCDEkeG7mSB0deG7lWkgKFNlbmlvckNpdGl6ZW4pLCB0w6xuaCB0cuG6oW5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIChEZXBlbmRlbnRzKSB2w6AgxJHhu5FpIHTDoWMgKFBhcnRuZXIpLg0KDQrEkMOhbmcgY2jDuiDDvSwgaOG7o3AgxJHhu5NuZyBkw6BpIGjhuqFuICgiT25lIHllYXIiKSBsw6AgeeG6v3UgdOG7kSBi4bqjbyB24buHIG3huqFuaCBuaOG6pXQsIGdpw7pwIGdp4bqjbSBvZGRzIHLhu51pIGLhu48geHXhu5FuZyAwLDM0IGzhuqduICh0aGVvIG3DtCBow6xuaCBsb2dpdCksIHbhu5tpIHThu7cgbOG7hyBy4budaSBi4buPIGNo4buJIDE0LDgzJSAoa2hv4bqjbmcgdGluIGPhuq15IDk1JTogMTIsNjgl4oCTMTcsMjclKSwgdGjhuqVwIGjGoW4gxJHDoW5nIGvhu4Mgc28gduG7m2kgMzcsMzElIGPhu6dhIG5ow7NtIGjhu6NwIMSR4buTbmcgIktow6FjIiAoUlIgPSAyLDUxKS4gS2jDoWNoIGjDoG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGhv4bq3YyDEkeG7kWkgdMOhYyBjxaluZyB0aOG7gyBoaeG7h24gbeG7qWMgxJHhu5kgdHJ1bmcgdGjDoG5oIGNhbyBoxqFuLCB24bubaSB04bu3IGzhu4cgcuG7nWkgYuG7jyBs4bqnbiBsxrDhu6N0IGzDoCAyMSw4NiUgdsOgIDIzLDk5JSAoT1IgbOG6p24gbMaw4bujdCBsw6AgMCw0ODMgdsOgIDAsNDkpLCBzbyB24bubaSAzNiw2OCUgdsOgIDM4LDM1JSDhu58gbmjDs20gxJHhu5FpIGNo4bupbmcuDQoNCk5nxrDhu6NjIGzhuqFpLCBk4buLY2ggduG7pSBGaWJlciBvcHRpYyBnaGkgbmjhuq1uIHThu7cgbOG7hyBy4budaSBi4buPIGNhbyBuaOG6pXQgKDQxLDg5JSwgT1IgPSAzLDQwKSwgY8OzIHRo4buDIGRvIGdpw6EgY8aw4bubYyBjYW8gaG/hurdjIGNo4bqldCBsxrDhu6NuZyBk4buLY2ggduG7pSBjaMawYSDEkcOhcCDhu6luZyBr4buzIHbhu41uZy4gTmjDs20ga2jDoWNoIGjDoG5nIGNhbyB0deG7lWkgY8WpbmcgY8OzIHThu7cgbOG7hyBy4budaSBi4buPIHbGsOG7o3QgdHLhu5lpICg0MywzJSwgT1IgPSAxLDM4KSwgY8OzIHRo4buDIHh14bqldCBwaMOhdCB04burIG5odSBj4bqndSBz4butIGThu6VuZyB0aOG6pXAgaG/hurdjIGjhuqFuIGNo4bq/IHbhu4Ega+G7uSBuxINuZyBjw7RuZyBuZ2jhu4cuIFBow6JuIHTDrWNoIMSRYSBiaeG6v24gY2hvIHRo4bqleSBuaMOzbSBraMOhY2ggaMOgbmcgbMO9IHTGsOG7n25nIG5o4bqldCAoY8OzIGto4bqjIG7Eg25nIHLhu51pIGLhu48gdGjhuqVwIG5o4bqldCkgbMOgIG5o4buvbmcgbmfGsOG7nWkgZMO5bmcgaOG7o3AgxJHhu5NuZyAiT25lIHllYXIiLCBk4buLY2ggduG7pSBEU0wsIGtow7RuZyBjYW8gdHXhu5VpIHbDoCBraMO0bmcgY8OzIMSR4buRaSB0w6FjICg5LDc5JeKAkzEwLDElKSwgdHJvbmcga2hpIG5ow7NtIGPDsyBuZ3V5IGPGoSBjYW8gbmjhuqV0IGzDoCBuaOG7r25nIG5nxrDhu51pIHPhu60gZOG7pW5nIGjhu6NwIMSR4buTbmcgIktow6FjIiwgRmliZXIgb3B0aWMsIGNhbyB0deG7lWkgdsOgIGPDsyDEkeG7kWkgdMOhYyAoNDEsNSXigJM0MiwxOCUpLg0KDQpUdXkgbmhpw6puLCBjw6FjIG3DtCBow6xuaCBo4buTaSBxdXkgKGxvZ2l0LCBwcm9iaXQsIGNsb2dsb2cpIHbhuqtuIGfhurdwIGjhuqFuIGNo4bq/IHRyb25nIGThu7EgxJFvw6FuLCB24bubaSDEkeG7mSBuaOG6oXkgY2jhu4kgxJHhuqF0IDQ3LDclIGRvIGThu68gbGnhu4d1IG3huqV0IGPDom4gYuG6sW5nICg2NywxOCUga2jDtG5nIHLhu51pIGLhu48gc28gduG7m2kgMzIsODIlIHLhu51pIGLhu48pLCBt4bq3YyBkw7kgbG9naXQgY8OzIGhp4buHdSBxdeG6oyB04buRdCBuaOG6pXQgKEFJQyA9IDU0ODEsNDEyLCBCcmllciBTY29yZSA9IDAsMTk5KS4gxJBp4buBdSBuw6B5IGfhu6NpIG3hu58gbmh1IGPhuqd1IGPhuqNpIHRoaeG7h24gY2jhuqV0IGzGsOG7o25nIGThu7EgxJFvw6FuIGLhurFuZyBjw6FjIGvhu7kgdGh14bqtdCBjw6JuIGLhurFuZyBk4buvIGxp4buHdSwgYuG7lSBzdW5nIGJp4bq/biBxdWFuIHRy4buNbmcgKG5oxrAgY2hpIHBow60gaMOgbmcgdGjDoW5nIGhv4bq3YyB0aOG7nWkgZ2lhbiBz4butIGThu6VuZyksIGhv4bq3YyDDoXAgZOG7pW5nIGPDoWMgdGh14bqtdCB0b8OhbiBo4buNYyBtw6F5IGhp4buHbiDEkeG6oWkgKFJhbmRvbSBGb3Jlc3QsIFhHQm9vc3QpIMSR4buDIHTEg25nIMSR4buZIGNow61uaCB4w6FjLg0KDQpOaOG7r25nIHBow6F0IGhp4buHbiBuw6B5IG1hbmcgw70gbmdoxKlhIHRo4buxYyB0aeG7hW4gcXVhbiB0cuG7jW5nOiBo4bujcCDEkeG7k25nIGTDoGkgaOG6oW4gdsOgIHnhur91IHThu5EgZ2lhIMSRw6xuaCAoxJHhu5FpIHTDoWMsIG5nxrDhu51pIHBo4bulIHRodeG7mWMpIHTEg25nIGPGsOG7nW5nIHPhu7EgZ+G6r24gYsOzLCB0cm9uZyBraGkgZOG7i2NoIHbhu6UgRmliZXIgb3B0aWMgdsOgIG5ow7NtIGNhbyB0deG7lWkgY+G6p24gxJHGsOG7o2MgY+G6o2kgdGhp4buHbiDEkeG7gyBnaeG6o20gbmd1eSBjxqEgcuG7nWkgYuG7jy4gRG9hbmggbmdoaeG7h3AgbsOqbiDGsHUgdGnDqm4ga2h1eeG6v24ga2jDrWNoIGjhu6NwIMSR4buTbmcgZMOgaSBo4bqhbiBxdWEgxrB1IMSRw6NpLCBj4bqjaSB0aGnhu4duIGNo4bqldCBsxrDhu6NuZyBGaWJlciBvcHRpYywgeMOieSBk4buxbmcgZ8OzaSBjxrDhu5tjIHBow7kgaOG7o3AgY2hvIGtow6FjaCBow6BuZyBjYW8gdHXhu5VpLCB2w6Agbmjhuq9tIMSR4bq/biBuaMOzbSBraMO0bmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMgYuG6sW5nIGPDoWMgY2hp4bq/biBsxrDhu6NjIG1hcmtldGluZyBjw6EgbmjDom4gaMOzYS4gxJDhu5NuZyB0aOG7nWksIGPhuqNpIHRp4bq/biBtw7QgaMOsbmggZOG7sSDEkW/DoW4gYuG6sW5nIGPDoWNoIGPDom4gYuG6sW5nIGThu68gbGnhu4d1LCBi4buVIHN1bmcgYmnhur9uIG5oxrAgY2hpIHBow60gaMOgbmcgdGjDoW5nIGhv4bq3YyB0aOG7nWkgZ2lhbiBz4butIGThu6VuZywgdsOgIMOhcCBk4bulbmcgY8OhYyBr4bu5IHRodeG6rXQgaOG7jWMgbcOheSAobmjGsCBSYW5kb20gRm9yZXN0KSBz4bq9IGdpw7pwIG5o4bqtbiBkaeG7h24gY2jDrW5oIHjDoWMgaMahbiBraMOhY2ggaMOgbmcgY8OzIG5ndXkgY8ahIHLhu51pIGLhu48sIHThu6sgxJHDsyB0cmnhu4NuIGtoYWkgY8OhYyBiaeG7h24gcGjDoXAgZ2nhu68gY2jDom4gaGnhu4d1IHF14bqjLCBnw7NwIHBo4bqnbiBuw6JuZyBjYW8gc+G7sSBow6BpIGzDsm5nIHbDoCBj4bunbmcgY+G7kSB24buLIHRo4bq/IGPhuqFuaCB0cmFuaCB0csOqbiB0aOG7iyB0csaw4budbmcuDQoNCg0KIyMjICoqMy43LjIgS2h1eeG6v24gbmdo4buLKioNCg0KxJDhu4MgZ2nhuqNtIHThu7cgbOG7hyBy4budaSBi4buPIGThu4tjaCB24bulIHbDoCB0xINuZyBjxrDhu51uZyBz4buxIGfhuq9uIGLDsyBj4bunYSBraMOhY2ggaMOgbmcsIGRvYW5oIG5naGnhu4dwIG7Dqm4geGVtIHjDqXQgY8OhYyBnaeG6o2kgcGjDoXAgc2F1Og0KDQpUaOG7qSBuaOG6pXQgbMOgIGtodXnhur9uIGtow61jaCBrw70gaOG7o3AgxJHhu5NuZyBkw6BpIGjhuqFuOiBDdW5nIGPhuqVwIGPDoWMgxrB1IMSRw6NpIGjhuqVwIGThuqtuIG5oxrAgZ2nhuqNtIGdpw6EsIHThurduZyB0aMOqbSBk4buLY2ggduG7pSwgaG/hurdjIGPDoWMgY2jGsMahbmcgdHLDrG5oIGtow6FjaCBow6BuZyB0aMOibiB0aGnhur90IMSR4buDIGtodXnhur9uIGtow61jaCBraMOhY2ggaMOgbmcgbOG7sWEgY2jhu41uIGjhu6NwIMSR4buTbmcgIk9uZSB5ZWFyIiwgdOG7qyDEkcOzIHTEg25nIHTDrW5oIGNhbSBr4bq/dCB2w6AgZ2nhuqNtIG5ndXkgY8ahIHLhu51pIGLhu48uDQoNClRo4bupIGhhaSBsw6AgY+G6o2kgdGhp4buHbiBjaOG6pXQgbMaw4bujbmcgZOG7i2NoIHbhu6UgRmliZXIgb3B0aWM6IFhlbSB4w6l0IMSRaeG7gXUgY2jhu4luaCBnacOhIGPGsOG7m2MgaG/hurdjIG7Dom5nIGPhuqVwIGNo4bqldCBsxrDhu6NuZyBk4buLY2ggduG7pSBGaWJlciBvcHRpYyDEkeG7gyDEkcOhcCDhu6luZyBr4buzIHbhu41uZyBj4bunYSBraMOhY2ggaMOgbmcsIHbDrCDEkcOieSBsw6AgbmjDs20gY8OzIHThu7cgbOG7hyBy4budaSBi4buPIGNhbyBuaOG6pXQgKDQxLDg5JSkuIEPDoWMga2jhuqNvIHPDoXQgcGjhuqNuIGjhu5NpIGtow6FjaCBow6BuZyBjw7MgdGjhu4MgZ2nDunAgeMOhYyDEkeG7i25oIG5ndXnDqm4gbmjDom4gY+G7pSB0aOG7gyAoZ2nDoSBj4bqjLCB04buRYyDEkeG7mSwgaG/hurdjIMSR4buZIOG7lW4gxJHhu4tuaCkuDQoNClRo4bupIDMgbMOgIHjDonkgZOG7sW5nIGfDs2kgZOG7i2NoIHbhu6UgcGjDuSBo4bujcCBjaG8gbmjDs20gY2FvIHR14buVaTogVOG6oW8gY8OhYyBnw7NpIGPGsOG7m2MgxJHGoW4gZ2nhuqNuLCBnacOhIGPhuqMgcGjhuqNpIGNoxINuZywgdsOgIGThu4Ugc+G7rSBk4bulbmcgY2hvIGtow6FjaCBow6BuZyBjYW8gdHXhu5VpLCDEkeG7k25nIHRo4budaSBjdW5nIGPhuqVwIGjhu5cgdHLhu6Mga+G7uSB0aHXhuq10IHRow6JuIHRoaeG7h24gxJHhu4MgxJHDoXAg4bupbmcgbmh1IGPhuqd1IGPhu6dhIG5ow7NtIG7DoHksIHThu6sgxJHDsyBnaeG6o20gdOG7tyBs4buHIHLhu51pIGLhu48gKDQzLDMlKS4NCg0KVGjhu6kgNCBsw6AgdOG6rXAgdHJ1bmcgdsOgbyBuaMOzbSBraMOhY2ggaMOgbmcga2jDtG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljOiBQaMOhdCB0cmnhu4NuIGPDoWMgY2hp4bq/biBsxrDhu6NjIG1hcmtldGluZyBuaOG6r20gxJHhur9uIG5ow7NtIG7DoHksIGNo4bqzbmcgaOG6oW4gbmjGsCBjw6FjIGfDs2kgZOG7i2NoIHbhu6UgZ2lhIMSRw6xuaCBob+G6t2MgxrB1IMSRw6NpIMSR4bq3YyBiaeG7h3QsIMSR4buDIHTEg25nIHTDrW5oIGfhuq9uIGLDsywgdsOsIG5ow7NtIG7DoHkgY8OzIHThu7cgbOG7hyBy4budaSBi4buPIGNhbyBoxqFuICgzNiw2OCUpLg0KDQpUaOG7qSA1IGzDoCBj4bqjaSB0aGnhu4duIG3DtCBow6xuaCBk4buxIMSRb8OhbjogxJBp4buBdSBjaOG7iW5oIG5nxrDhu6FuZyBk4buxIMSRb8OhbiBob+G6t2Mgw6FwIGThu6VuZyBjw6FjIGvhu7kgdGh14bqtdCBjw6JuIGLhurFuZyBk4buvIGxp4buHdSAobmjGsCBvdmVyc2FtcGxpbmcgaG/hurdjIHVuZGVyc2FtcGxpbmcpIMSR4buDIHTEg25nIMSR4buZIG5o4bqheSBj4bunYSBtw7QgaMOsbmgsIHThu6sgxJHDsyBj4bqjaSB0aGnhu4duIGto4bqjIG7Eg25nIGThu7EgxJFvw6FuIGtow6FjaCBow6BuZyBjw7Mgbmd1eSBjxqEgcuG7nWkgYuG7jyB2w6AgdHJp4buDbiBraGFpIGPDoWMgYmnhu4duIHBow6FwIGdp4buvIGNow6JuIGvhu4twIHRo4budaS4NCg0KQ3Xhu5FpIGPDuW5nIGzDoCB0xINuZyBjxrDhu51uZyBjaMSDbSBzw7NjIGtow6FjaCBow6BuZzogVGhp4bq/dCBs4bqtcCBjw6FjIGNoxrDGoW5nIHRyw6xuaCBjaMSDbSBzw7NjIGtow6FjaCBow6BuZyBjw6EgbmjDom4gaMOzYSwgxJHhurdjIGJp4buHdCBjaG8gY8OhYyBuaMOzbSBjw7Mgbmd1eSBjxqEgcuG7nWkgYuG7jyBjYW8gKEZpYmVyIG9wdGljLCBjYW8gdHXhu5VpLCBraMO0bmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMpLCB0aMO0bmcgcXVhIGto4bqjbyBzw6F0IMSR4buLbmgga+G7sywgaOG7lyB0cuG7oyBuaGFuaCBjaMOzbmcsIHbDoCBjw6FjIMawdSDEkcOjaSBwaMO5IGjhu6NwLg0KDQo=