1. TÓM TẮT NỘI DUNG SÁCH

“Generalized Linear Models with Examples in R” là một cuốn sách chuyên sâu về mô hình tuyến tính tổng quát (GLMs), được viết bởi hai chuyên gia thống kê là Peter K. Dunn và Gordon K. Smyth. Mục tiêu chính của cuốn sách là kết hợp chặt chẽ giữa lý thuyết và thực hành, giúp người học và người làm nghiên cứu hiểu rõ cấu trúc, phương pháp ước lượng, kiểm định và ứng dụng của GLMs, đồng thời thành thạo sử dụng phần mềm R để thực hiện các phân tích thống kê thực tế.

Chương 1: Statistical Models

Chương 1 giới thiệu các khái niệm nền tảng về mô hình thống kê, là cơ sở để hiểu được mô hình tuyến tính và mô hình tuyến tính tổng quát (GLMs). Mục đích là để hiểu rõ cách mô hình hóa mối quan hệ giữa các biến số trong một tập dữ liệu.

1.1. Khái niệm mô hình thống kê

  • Một mô hình thống kê mô tả mối quan hệ giữa biến phản hồi (response variable, thường ký hiệu là y) và một hay nhiều biến giải thích (covariates/predictors).
  • Mô hình gồm hai phần:
    • Thành phần hệ thống (systematic component): mô tả ảnh hưởng của các biến giải thích.
    • Thành phần ngẫu nhiên (random component): mô tả sự biến thiên không giải thích được (sai số).

1.2. Thành phần hệ thống và thành phần ngẫu nhiên

Thành phần hệ thống (Systematic Component)

Là phần có thể giải thích được của mô hình, thể hiện mối quan hệ tuyến tính hoặc phi tuyến giữa biến phụ thuộc và các biến giải thích (covariates).

Được biểu diễn thông qua một hàm tuyến tính của các biến giải thích, ví dụ:

\[\eta_i = \beta_0 + \beta_1 x_{1i} + \dots + \beta_p x_{pi}\] Trong đó: \(\eta_i\) là giá trị của hàm liên kết tại quan sát thứ i

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

Là phần không giải thích được của mô hình – thể hiện sự biến thiên tự nhiên, nhiễu đo lường hoặc các yếu tố không quan sát được.

Được mô tả bằng một phân phối xác suất phù hợp với loại dữ liệu:
  • Hồi quy tuyến tính: \(\varepsilon_i \sim N(0, \sigma^2)\)
  • GLMs: \(y_i\) tuân theo một phân phối trong họ exponential family (như Nhị phân, Poisson, Gamma, v.v.)

Phản ánh rằng ngay cả khi các biến giải thích giống nhau, kết quả đầu ra vẫn có thể khác do yếu tố ngẫu nhiên.

1.3. Mô hình hồi quy

  • Hồi quy đơn:
  • \[ y_i = \beta_0 + \beta_1 x_i + \varepsilon_i \]
  • Hồi quy đa biến
  • \[ y_i = \beta_0 + \beta_1 x_{1i} + \beta_2 x_{2i} + \cdots + \beta_p x_{pi} + \varepsilon_i \]
      Trong đó:
    • \(y_i\): giá trị quan sát của biến phụ thuộc
    • \(x_{ji}\): giá trị của biếnj giải thích thứ i
    • \(\beta_0\): hệ số chặn
    • \(\beta_j\): hệ số hồi quy
    • \(\varepsilon_i\):sai số ngẫu nhiên
  • Ý nghĩa các hệ số:

    • \(\beta_0\): giá trị trung bình của y khi tất cả \(x_j = 0\)
    • \(\beta_j\): thay đổi trung bình của y khi \(x_j\) tăng 1 đơn vị, khi các biến khác không đổi
    • \(\varepsilon\): biểu diễn sự nhiễu hoặc yếu tố chưa quan sát được, được giả định có trung bình bằng 0.

Chương 2: Linear Regression Models

Chương này giới thiệu mô hình hồi quy tuyến tính nói riêng và các mô hình hồi quy tuyến tính tổng quát nói chung. Nội dung bao gồm: định nghĩa, giả định cơ bản, ước lượng bình phương tối thiểu, sử dụng R để xây dựng và diễn giải mô hình, cùng với các phương pháp suy luận, phân tích phương sai và so sánh mô hình.

2.1. Giới thiệu mô hình hồi quy tuyến tính

Mô hình hồi quy tuyến tính là một phương pháp thống kê dùng để mô hình hóa mối quan hệ giữa một biến phụ thuộc (phản hồi) và một hoặc nhiều biến độc lập (giải thích).

2.2. Định nghĩa

Mô hình hồi quy tuyến tính tổng quát: \[ y_i = \beta_0 + \beta_1 x_{1i} + \beta_2 x_{2i} + \cdots + \beta_p x_{pi} + \varepsilon_i \] Trong đó:
  • \(y_i\): giá trị quan sát của biến phụ thuộc
  • \(x_{ji}\): giá trị của biếnj giải thích thứ i
  • \(\beta_0\): hệ số chặn
  • \(\beta_j\): hệ số hồi quy
  • \(\varepsilon_i\):sai số ngẫu nhiên
  • 2.3. Hồi quy đơn

    2.3.1. Ước lượng bình phương tối thiểu (Least-Squares Estimation)

    Mô hình hồi quy tuyến tính đơn được biểu diễn bằng: \[ y_i = \beta_0 + \beta_1 x_i + \varepsilon_i \] Trong đó - \(y_i\): giá trị quan sát của biến phụ thuộc tại điểm \(i\)
    - \(x_i\): giá trị quan sát của biến độc lập tại điểm \(i\)
    - \(\beta_0\): hệ số chặn (intercept)
    - \(\beta_1\): hệ số góc (slope)
    - \(\varepsilon_i\): sai số ngẫu nhiên, với giả định: \(\varepsilon_i \sim \mathcal{N}(0, \sigma^2)\)

    Các hệ số \(\beta_0\)\(\beta_1\) được ước lượng bằng cách tối thiểu hóa tổng bình phương sai số (SSE):

    \[ SSE = \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 \]

    Trong đó: \(\hat{y}_i = \hat{\beta}_0 + \hat{\beta}_1 x_i\) là giá trị dự đoán của \(y_i\).

    2.3.2 Coefficient Estimates

    Các ước lượng cho \(\beta_1\)\(\beta_0\) được tính như sau:

    \[ \hat{\beta}_1 = \frac{ \sum_{i=1}^{n} (x_i - \bar{x})(y_i - \bar{y}) }{ \sum_{i=1}^{n} (x_i - \bar{x})^2 } \]

    \[ \hat{\beta}_0 = \bar{y} - \hat{\beta}_1 \bar{x} \]

    Trong đó:

    \(\bar{x}\): giá trị trung bình của biến \(x\)
    \(\bar{y}\): giá trị trung bình của biến \(y\)

    2.3.3 Estimating the Variance \(\sigma^2\)

    Ước lượng không chệch của phương sai sai số \(\sigma^2\) được tính bằng:

    \[ \hat{\sigma}^2 = \frac{1}{n - 2} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 \]

    Trong đó:

    \(y_i\): giá trị quan sát của biến phụ thuộc
    \(\hat{y}_i\): giá trị dự đoán từ mô hình hồi quy
    \(n\): số lượng quan sát
    \(\hat{\sigma}^2\): phương sai sai số ước lượng
    Mẫu số \(n - 2\) là do đã ước lượng 2 tham số \(\hat{\beta}_0\)\(\hat{\beta}_1\)

    2.3.4 Standard Errors of the Coefficients

    Sai số chuẩn (Standard Error - SE) của các hệ số hồi quy được tính như sau:
    • Sai số chuẩn của \(\hat{\beta}_1\):
    • \[ SE(\hat{\beta}_1) = \sqrt{ \frac{ \hat{\sigma}^2 }{ \sum_{i=1}^{n} (x_i - \bar{x})^2 } } \]

    • Sai số chuẩn của \(\hat{\beta}_0\):
    • \[ SE(\hat{\beta}_0) = \sqrt{ \hat{\sigma}^2 \left( \frac{1}{n} + \frac{ \bar{x}^2 }{ \sum_{i=1}^{n} (x_i - \bar{x})^2 } \right) } \]

      Trong đó:
      • \(\hat{\sigma}^2\): phương sai sai số ước lượng
      • \(\bar{x}\): giá trị trung bình của biến \(x\)
      • \(n\): số lượng quan sát \(SE(\hat{\beta}_j)\): sai số chuẩn của hệ số \(\hat{\beta}_j\)

      Sai số chuẩn cho biết mức độ không chắc chắn trong ước lượng các hệ số hồi quy, và là cơ sở để tính khoảng tin cậy và kiểm định giả thuyết.

    2.3.5. Standard Errors of Fitted Values

    Sai số chuẩn (Standard Error) của giá trị dự đoán \(\hat{y}_g\) tại điểm \(x_g\) được tính như sau:

    \[ SE(\hat{\mu}_g)^2 = \hat{\sigma}^2 \left( w_i \left[ \frac{1}{n} + \frac{(x_g - \bar{x})^2}{SS_x} \right] \right) \]

    Trong đó:

    \(\hat{\mu}_g = \hat{\beta}_0 + \hat{\beta}_1 x_g\): là giá trị dự đoán tại điểm \(x_g\)

    \(\hat{\sigma}^2\): phương sai sai số ước lượng

    \(w_i\): trọng số cho quan sát \(i\) (nếu có, nếu không thì mặc định là 1)

    \(\bar{x}\): giá trị trung bình của biến \(x_i\)

    \(SS_x = \sum (x_i - \bar{x})^2\): tổng bình phương sai lệch của các giá trị \(x_i\) so với trung bình

    2.4. Hồi quy đa biến

    2.4.1 Coefficient Estimates

    Mô hình hồi quy tuyến tính bội (multiple linear regression) có dạng: \[ y_i = \beta_0 + \beta_1 x_{i1} + \beta_2 x_{i2} + \cdots + \beta_p x_{ip} + \varepsilon_i \] Viết gọn bằng ký hiệu ma trận: \[ \mathbf{y} = \mathbf{X} \boldsymbol{\beta} + \boldsymbol{\varepsilon} \] Trong đó:

    \(\mathbf{y}\): vector \(n \times 1\) chứa các giá trị quan sát của biến phụ thuộc
    \(\mathbf{X}\): ma trận thiết kế \(n \times (p + 1)\), trong đó cột đầu tiên là toàn 1 (tương ứng với hệ số chặn \(\beta_0\))
    \(\boldsymbol{\beta}\): vector \((p + 1) \times 1\) chứa các hệ số hồi quy
    \(\boldsymbol{\varepsilon}\): vector \(n \times 1\) chứa sai số ngẫu nhiên, với giả định \(\varepsilon_i \sim \mathcal{N}(0, \sigma^2)\)

    Ước lượng bình phương tối thiểu (OLS estimator) cho \(\boldsymbol{\beta}\): \[ \hat{\boldsymbol{\beta}} = (\mathbf{X}^\top \mathbf{X})^{-1} \mathbf{X}^\top \mathbf{y} \]

    2.4.2 Estimating the Variance \(\sigma^2\)

    Phần dư (residual) tại quan sát \(i\):

    \[ e_i = y_i - \hat{y}_i \]

    Tổng bình phương phần dư (RSS - Residual Sum of Squares):

    \[ RSS = \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 = \| \mathbf{y} - \hat{\mathbf{y}} \|^2 \]

    Ước lượng không chệch của phương sai \(\sigma^2\):

    \[ \hat{\sigma}^2 = \frac{RSS}{n - p - 1} \] Trong đó:

    • \(n\): số lượng quan sát
    • \(p\): số biến độc lập (không tính hệ số chặn \(\beta_0\))
    • \(p + 1\): tổng số tham số được ước lượng (bao gồm \(\beta_0\))
    • \(n - p - 1\): số bậc tự do (degrees of freedom)

    2.4.3 Standard Errors

    Phương sai của vector hệ số ước lượng \(\hat{\boldsymbol{\beta}}\):

    \[ \mathrm{Var}(\hat{\boldsymbol{\beta}}) = \hat{\sigma}^2 (\mathbf{X}^\top \mathbf{X})^{-1} \]

    Sai số chuẩn (Standard Error) của từng hệ số hồi quy:

    \[ SE(\hat{\beta}_j) = \sqrt{ \hat{\sigma}^2 \cdot \left[ (\mathbf{X}^\top \mathbf{X})^{-1} \right]_{jj} } \]

    Trong đó:
    • \(\hat{\sigma}^2\): Ước lượng của phương sai sai số
    • \(\mathbf{X}^\top \mathbf{X}\): Ma trận tích giữa ma trận thiết kế \(\mathbf{X}\) và chuyển vị của nó
    • \(\left[ (\mathbf{X}^\top \mathbf{X})^{-1} \right]_{jj}\): Phần tử hàng \(j\), cột \(j\) của ma trận nghịch đảo
    • \(SE(\hat{\beta}_j)\): Sai số chuẩn của hệ số hồi quy \(\hat{\beta}_j\)

    2.5 Fitting Linear Regression Models Using R

    Phần này hướng dẫn cách sử dụng R để ước lượng mô hình hồi quy tuyến tính bằng hàm lm(). \[model <- lm(y ~ x1 + x2 + ..., data = dataset)\] y: biến phụ thuộc (response variable).

    x1, x2, …: biến độc lập (predictors).

    dataset: bộ dữ liệu chứa các biến.

    Các hàm quan trọng trong phân tích hồi quy tuyến tính trong R

    Dưới đây là các hàm cơ bản thường dùng khi làm việc với mô hình hồi quy tuyến tính trong R (ví dụ mô hình đã được lưu trong biến model sau khi chạy lm()):

    • summary(model) in kết quả chi tiết bao gồm: hệ số hồi quy, sai số chuẩn, giá trị thống kê t, p-values, hệ số xác định \(R^2\), v.v.

    • coef(model) trả về các hệ số ước lượng \(\hat{\beta}_0, \hat{\beta}_1, \dots, \hat{\beta}_p\)

    • fitted(model) trả về giá trị dự đoán \(\hat{y}_i\) từ mô hình, theo công thức: \(\hat{y}_i = \hat{\beta}_0 + \hat{\beta}_1 x_{i1} + \hat{\beta}_2 x_{i2} + \cdots + \hat{\beta}_p x_{ip}\)

    • residuals(model) trả về phần dư (residual) \(e_i\), được tính theo công thức:\(e_i = y_i - \hat{y}_i\)

    • anova(model) tạo bảng phân tích phương sai (ANOVA table) cho mô hình, giúp kiểm định tổng thể ý nghĩa của mô hình.

    2.8 Inference for Linear Regression Models: t-Tests

    Mục này trình bày các bước suy luận thống kê đối với các hệ số hồi quy \(\beta_j\) trong mô hình tuyến tính, sử dụng kiểm định t và khoảng tin cậy.

    2.8.1 Normal Linear Regression Models

    Giả định: Sai số \(\varepsilon_i\) là độc lập và tuân theo phân phối chuẩn:

    \[ \varepsilon_i \sim \mathcal{N}(0, \sigma^2) \]

    Dưới giả định này, mô hình hồi quy tuyến tính có dạng:

    \[ y_i = \beta_0 + \beta_1 x_{i1} + \cdots + \beta_p x_{ip} + \varepsilon_i \]

    2.8.2 The Distribution of \(\hat{\beta}_j\)

    Với giả định sai số chuẩn, ước lượng \(\hat{\beta}_j\) có phân phối:

    \[ \hat{\beta}_j \sim \mathcal{N} \left( \beta_j,\ \operatorname{Var}(\hat{\beta}_j) \right) \]

    Khi thay thế \(\sigma^2\) bằng ước lượng \(s^2\), ta có thống kê:

    \[ t_j = \frac{ \hat{\beta}_j - \beta_j }{ \operatorname{SE}(\hat{\beta}_j) } \sim t_{n - p} \]

    Trong đó:
    • \(n\): số quan sát
    • \(p\): số hệ số trong mô hình (bao gồm cả hệ số chặn \(\beta_0\))

    2.8.3 Hypothesis Tests for \(\beta_j\)

    Mục tiêu kiểm định:

    \[ H_0: \beta_j = 0 \quad \text{vs} \quad H_1: \beta_j \neq 0 \]
    • Tính giá trị thống kê \(t_j\) như trên
    • So sánh với phân phối Student \(t_{n - p}\) hoặc tra p-value trong R.

    2.8.4 Confidence Intervals for \(\beta_j\)

    Khoảng tin cậy (CI) 95% cho \(\beta_j\):

    \[ \hat{\beta}_j \pm t_{n - p,\ \alpha/2} \cdot \operatorname{SE}(\hat{\beta}_j) \]

    2.8.5 Confidence Intervals for \(\mu = E(Y|x)\)

    Giá trị kỳ vọng của \(Y\) tại \(x = x_g\):

    \[ \mu_g = E(Y|x_g) = x_g^T \beta \]

    Khoảng tin cậy cho \(\mu_g\):

    \[ \hat{\mu}_g \pm t_{n - p,\ \alpha/2} \cdot \operatorname{SE}(\hat{\mu}_g) \]

    Trong đó phương sai của \(\hat{\mu}_g\) là:

    \[ \operatorname{Var}(\hat{\mu}_g) = \sigma^2 x_g^T (X^T X)^{-1} x_g \]

    2.9 Analysis of Variance for Regression Models

    Mục tiêu của phần này là phân tích tổng phương sai (ANOVA) nhằm đánh giá mức độ giải thích biến phụ thuộc bởi mô hình hồi quy tuyến tính.

    Tổng phương sai

    Tổng phương sai của biến phụ thuộc \(Y\) được chia thành:

    • Phương sai giải thích được bởi mô hình (SSR – Regression Sum of Squares)
    • Phương sai chưa giải thích (RSS – Residual Sum of Squares)

    Công thức:

    \[ \text{SST} = \sum_{i=1}^{n} (y_i - \bar{y})^2 = \text{SSR} + \text{RSS} \]

    Trong đó:

    • SST (Total Sum of Squares): Tổng phương sai
    • SSR (Sum of Squares for Regression): Phương sai giải thích bởi mô hình
    • RSS (Residual Sum of Squares): Phương sai của phần dư

    Hệ số xác định \(R^2\)

    \[ R^2 = \frac{\text{SSR}}{\text{SST}} = 1 - \frac{\text{RSS}}{\text{SST}} \]

    Ý nghĩa:

    • \(R^2 \in [0, 1]\)
    • \(R^2\) càng lớn → mô hình càng giải thích tốt biến phụ thuộc

    Kiểm định tổng thể mô hình (F-test)

    Giả thuyết:

    \[ H_0: \beta_1 = \beta_2 = \cdots = \beta_p = 0 \]

    (nghĩa là mô hình không giải thích gì được cho dữ liệu)

    Thống kê kiểm định:

    \[ F = \frac{\text{SSR} / p}{\text{RSS} / (n - p - 1)} = \frac{\text{MSR}}{\text{MSE}} \]

    Trong đó:

    • \(\text{MSR} = \text{SSR} / p\): phương sai trung bình của hồi quy
    • \(\text{MSE} = \text{RSS} / (n - p - 1)\): phương sai trung bình phần dư

    Phân phối của \(F\):

    \[ F \sim F_{p,\ n - p - 1} \]

    • Nếu giá trị \(F\) lớn và p-value nhỏ → bác bỏ \(H_0\)
    • Kết luận: mô hình có ý nghĩa thống kê

    R trong ANOVA

    Trong R, sử dụng hàm:anova(model)để in ra bảng phân tích phương sai, bao gồm:

    • Df (degrees of freedom)
    • Sum Sq (tổng bình phương)
    • Mean Sq (trung bình bình phương)
    • F value
    • Pr(>F) – p-value của kiểm định

    2.10 Comparing Nested Models

    Phần này giới thiệu cách so sánh hai mô hình hồi quy lồng nhau (nested models) để kiểm tra xem mô hình đầy đủ (full model) có cải thiện đáng kể so với mô hình rút gọn (reduced model) hay không.

    2.10.1 Analysis of Variance to Compare Two Nested Models

    Khái niệm:

    • Mô hình nhỏ hơn (reduced model) là một trường hợp đặc biệt của mô hình lớn hơn (full model), bằng cách gán một số hệ số bằng 0.
    • So sánh giữa:
      • Mô hình \(M_0\) với \(p_0\) tham số
      • Mô hình \(M_1\) với \(p_1\) tham số, trong đó \(p_1 > p_0\)

    Giả thuyết kiểm định:

    \[ H_0: \text{Các hệ số thêm vào bằng 0} \quad \text{vs} \quad H_a: \text{Ít nhất một hệ số thêm khác 0} \]

    Thống kê kiểm định:

    \[ F = \frac{(\text{RSS}_0 - \text{RSS}_1)/(p_1 - p_0)}{\text{RSS}_1 / (n - p_1)} \]

    Trong đó:

    • \(\text{RSS}_0\): residual sum of squares của mô hình nhỏ
    • \(\text{RSS}_1\): residual sum of squares của mô hình lớn
    • \(n\): số quan sát

    Kết luận: Nếu giá trị \(F\) lớn → mô hình đầy đủ cải thiện đáng kể → bác bỏ \(H_0\)

    2.10.2 Sequential Analysis of Variance (Type I SS)

    Ý tưởng: Đưa từng biến vào mô hình theo thứ tự cụ thể → đo lường mức độ đóng góp của từng biến.

    Ứng dụng:

    • Hữu ích khi thứ tự nhập biến có ý nghĩa (ví dụ: thiết kế thí nghiệm)

    • Cho phép kiểm tra biến thứ \(j\) sau khi đã đưa các biến từ 1 đến \(j-1\) vào mô hình

    2.10.3 Parallel and Independent Regressions

    So sánh hồi quy riêng biệt giữa các nhóm (ví dụ: nam/nữ, vùng miền…):

    • Mô hình chung: áp dụng cho tất cả nhóm
    • Mô hình riêng: hồi quy khác nhau cho từng nhóm

    Kiểm định:

    • Hệ số dốc có giống nhau giữa các nhóm?
    • Hệ số chặn có giống nhau không?

    Phương pháp:

    • Dùng biến giả (dummy) cho nhóm
    • Dùng biến tương tác (interaction terms) để kiểm tra sự khác biệt

    2.10.4 The Marginality Principle

    Nguyên tắc biên (marginality):

    • Nếu mô hình bao gồm một biến tương tác (như \(x_1 x_2\)), thì bắt buộc phải giữ cả hai biến chính \(x_1\)\(x_2\)

    • Không được bỏ biến chính khi giữ biến tương tác

    Mục tiêu: Đảm bảo mô hình có ý nghĩa thống kêdễ diễn giải

    2.11 Choosing Between Non-nested Models: AIC and BIC

    AIC – Akaike Information Criterion

    Công thức:

    \[ \text{AIC} = -2 \log(L) + 2p \]

    Trong đó:

    • \(L\): Hàm khả năng tối đa (likelihood) của mô hình
    • \(p\): Số lượng tham số trong mô hình (bao gồm cả intercept)

    Ý nghĩa:

    • AIC đo lường mức độ phù hợp của mô hình với dữ liệu, có phạt độ phức tạp để tránh overfitting.
    • AIC càng thấp → mô hình càng tốt.
    • Có sự đánh đổi giữa độ khớp (goodness of fit) và độ phức tạp (model complexity).

    BIC – Bayesian Information Criterion

    Công thức:

    \[ \text{BIC} = -2 \log(L) + p \log(n) \]

    Trong đó:

    • \(n\): Số lượng quan sát
    • \(L\): Hàm khả năng tối đa (likelihood) của mô hình
    • \(p\): Số lượng tham số trong mô hình (bao gồm cả intercept)

    Ý nghĩa:

    • BIC cũng đánh giá mô hình với yếu tố phạt cho độ phức tạp.
    • Tuy nhiên, BIC phạt mô hình phức tạp nặng hơn AIC, do hệ số phạt là \(\log(n)\) thay vì 2.
    • Dữ liệu càng lớn\(\log(n)\) càng lớn → BIC càng nghiêng về mô hình đơn giản hơn.

    So sánh AIC và BIC

    library(knitr)
    library(kableExtra)
    ## Warning: package 'kableExtra' was built under R version 4.3.3
    comparison <- data.frame(
      `Tiêu chí` = c("AIC", "BIC"),
      `Ưu điểm` = c("Linh hoạt, dùng cho dự đoán", 
                    "Chọn mô hình đơn giản hơn, gần với lý thuyết Bayes"),
      `Nhược điểm` = c("Có thể chọn mô hình quá phức tạp", 
                       "Có thể bỏ sót biến hữu ích trong mô hình nhỏ")
    )
    kable(comparison, caption = "So sánh AIC và BIC", format = "html") %>%
      kable_styling(bootstrap_options = c("striped", "hover", "bordered", "condensed"),
                    full_width = FALSE)
    So sánh AIC và BIC
    Tiêu.chí Ưu.điểm Nhược.điểm
    AIC Linh hoạt, dùng cho dự đoán Có thể chọn mô hình quá phức tạp
    BIC Chọn mô hình đơn giản hơn, gần với lý thuyết Bayes Có thể bỏ sót biến hữu ích trong mô hình nhỏ

    2.12 Tools to Assist in Model Selection

    2.12.1 Adding and Dropping Variables

    Đây là cách thủ công để xây dựng mô hình phù hợp: bắt đầu với mô hình nhỏ và thêm biến, hoặc bắt đầu với mô hình đầy đủ rồi loại bỏ biến.

    Cần xem xét ý nghĩa thống kê (p-value) và mặt thực tiễn (hiểu biết về biến đó).

    2.12.2 Automated Methods for Model Selection

    3 phương pháp chính tự động:

  • Forward Selection (Chọn tiến):
  • Bắt đầu từ mô hình không có biến nào.

    Thêm lần lượt từng biến sao cho cải thiện tiêu chí (AIC hoặc BIC).

  • Backward Elimination (Loại lùi):
  • Bắt đầu với mô hình đầy đủ (tất cả biến).

    Loại dần các biến không cần thiết (p-value lớn, không cải thiện tiêu chí).

  • Stepwise Regression (Bước tiến/lùi):
  • Kết hợp cả hai phương pháp trên: sau mỗi lần thêm, xem xét có cần loại biến nào đi không.

    2.12.3 Objections to Using Stepwise Procedures

  • Một số phản đối thường gặp với stepwise:
  • Tăng nguy cơ chọn sai mô hình (overfitting).
  • Không phản ánh đúng ý nghĩa thực tiễn của các biến.
  • Kết quả phụ thuộc thứ tự thêm/bớt biến.
  • Không đảm bảo chọn được mô hình tốt nhất toàn cục.
  • Chương 3: Linear Regression Models: Diagnostics and Model-Building

    3.1 Residuals for Normal Linear Regression Models

    Trong mô hình hồi quy tuyến tính thông thường, phần dư (residual) là hiệu giữa giá trị thực tế và giá trị dự đoán: \[ r_i = y_i - \hat{\mu}_i \]

    Trong đó:

    • \(r_i\): phần dư của quan sát thứ \(i\)
    • \(y_i\): giá trị quan sát thực tế
    • \(\hat{\mu}_i = \hat{y}_i\): giá trị dự đoán từ mô hình

    Các loại phần dư thường dùng:

    Phần dư thô (Raw residual):

    \[ r_i = y_i - \hat{y}_i \]

    Phần dư chuẩn hóa (Standardized residual):

    \[ r_{i,\text{std}} = \frac{r_i}{\hat{\sigma} \sqrt{1 - h_{ii}}} \]

    Phần dư Studentized:

    \[ t_i = \frac{r_i}{\hat{\sigma}_{(i)} \sqrt{1 - h_{ii}}} \]

    Trong đó:

    • \(r_i\): phần dư của quan sát thứ \(i\)
    • \(\hat{y}_i\): giá trị dự đoán
    • \(h_{ii}\): phần tử đường chéo của ma trận hat \(H = X(X^TX)^{-1}X^T\)
    • \(\hat{\sigma}\): sai số chuẩn ước lượng từ toàn bộ dữ liệu
    • \(\hat{\sigma}_{(i)}\): sai số chuẩn khi loại bỏ quan sát thứ \(i\)

    3.2. Residual Plots

    Residual plots được sử dụng để kiểm tra các giả định trong mô hình hồi quy tuyến tính thông qua phần dư \(r_i = y_i - \hat{\mu}_i\)

    3.2.1. Plot Residuals Against \(x_j\): Linearity

    Biểu đồ phần dư theo từng biến giải thích \(x_j\) để kiểm tra giả định tuyến tính giữa biến \(x_j\) và biến phụ thuộc. Nếu biểu đồ không có mẫu hoặc xu hướng rõ ràng, giả định tuyến tính được thỏa mãn.

    3.2.2. Partial Residual Plots

    Giúp đánh giá ảnh hưởng riêng biệt của biến \(x_j\) trong mô hình đa biến bằng cách tách phần dư liên quan đến biến này, hỗ trợ phát hiện mối quan hệ phi tuyến hoặc ảnh hưởng đặc biệt.

    3.2.3. Plot Residuals Against \(\hat{\mu}\): Constant Variance

    Biểu đồ phần dư theo giá trị dự đoán \(\hat{\mu}\) để kiểm tra giả định phương sai đồng nhất (homoscedasticity). Nếu phần dư phân bố đều, không có xu hướng thay đổi phương sai theo \(\hat{\mu}\), giả định được giữ.

    3.2.4. Q–Q Plots and Normality

    Sử dụng biểu đồ Q-Q để kiểm tra phân phối chuẩn của phần dư. Phần dư tuân theo phân phối chuẩn nếu các điểm gần thẳng hàng trên biểu đồ.

    3.2.5. Lag Plots and Dependence over Time

    Sử dụng biểu đồ lag để phát hiện sự phụ thuộc hoặc mẫu trong phần dư theo thời gian, giúp kiểm tra giả định độc lập của các sai số.

    3.3. Outliers and Influential Observations

    3.3.1. Giới thiệu

    • Outliers là các quan sát có phần dư lớn, có thể làm sai lệch kết quả hồi quy.

    • Influential observations là những điểm có ảnh hưởng lớn tới ước lượng mô hình, có thể không phải outlier về phần dư nhưng lại có leverage cao.

    3.3.2 Outliers and Studentized Residuals

    Phần dư studentized (studentized residuals) giúp phát hiện outliers bằng cách chuẩn hóa phần dư theo độ lệch chuẩn dự đoán. Công thức: \[ t_i = \frac{r_i}{\hat{\sigma} \sqrt{1 - h_{ii}}} \] Trong đó:

    • \(r_i = y_i - \hat{\mu}_i\) là phần dư quan sát thứ \(i\).

    • \(\hat{\sigma}\) là ước lượng độ lệch chuẩn sai số (residual standard error).

    • \(h_{ii}\) là leverage (giá trị trên đường chéo của ma trận \(H = X (X^T X)^{-1} X^T\)).

    Chú ý: Giá trị \(|t_i|\) lớn (thường > 2 hoặc > 3) cảnh báo quan sát đó có thể là outlier.

    3.3.3 Influential Observations

    Đánh giá mức độ ảnh hưởng của điểm dữ liệu dựa trên các chỉ số: - Leverage \(h_{ii}\): đo độ “xa” của điểm quan sát trên không gian biến độc lập

    • Cook’s Distance \(D_i\): đo sự thay đổi tổng thể của các ước lượng khi bỏ điểm \(i\). Công thức: \[ D_i = \frac{r_i^2}{p \hat{\sigma}^2} \cdot \frac{h_{ii}}{(1 - h_{ii})^2} \]

    Trong đó:

    • \(p\): là số biến trong mô hình (bao gồm cả hằng số intercept)
    • \(r_i\), \(\hat{\sigma}\), \(h_{ii}\): như đã định nghĩa ở trên

    Ghi chú: Quan sát có Cook’s Distance lớn (ví dụ \(D_i > 1\)) được xem là có ảnh hưởng mạnh đến mô hình và cần được xem xét kỹ lưỡng.

    Chương 4: Beyond Linear Regression - The Method of Maximum Likelihood

    4.1 Giới thiệu

    Khái quát về phương pháp Ước lượng Cực đại (Maximum Likelihood Estimation - MLE) như một phương pháp tổng quát cho các mô hình thống kê vượt ra ngoài hồi quy tuyến tính thông thường.

    4.2 The Need for Non-normal Regression Models

    Khi nào mô hình tuyến tính không phù hợp:

    • Biến phụ thuộc không phải là biến liên tục có phân phối chuẩn.
      • Ví dụ: dữ liệu nhị phân, đếm, hoặc giá trị dương liên tục.

    Các loại dữ liệu và mô hình phù hợp:

    • Dữ liệu nhị phân hoặc đếm nhị phân → mô hình Bernoulli, Binomial.
    • Dữ liệu đếm không giới hạn → Poisson hoặc Negative Binomial.
    • Dữ liệu liên tục dương → mô hình phân phối Gamma hoặc Inverse Gaussian.

    4.3 Generalizing the Normal Linear Model

    Mở rộng mô hình tuyến tính chuẩn sang mô hình tổng quát với phân phối khác (exponential family), chuẩn bị cho phương pháp MLE.

    4.4 The Idea of Likelihood Estimation

    Hàm Likelihood \(L(\theta)\):
    Xác suất đồng thời của quan sát dưới tham số \(\theta\): \[ L(\theta) = \prod_{i=1}^n f(y_i \mid \theta) \]

    Log-likelihood:
    Để tính toán dễ dàng hơn, lấy log hàm likelihood:

    \[ \ell(\theta) = \log L(\theta) = \sum_{i=1}^n \log f(y_i \mid \theta) \]

    • Ước lượng cực đại:
      Tìm \(\hat{\theta}\) sao cho \(\ell(\theta)\) đạt cực đại.

    4.5 Maximum Likelihood for Estimating One Parameter

    Phương trình score:
    Đạo hàm log-likelihood theo tham số:

    \[ U(\theta) = \frac{d\ell(\theta)}{d\theta} \]

    Giải \(U(\theta) = 0\) để tìm \(\hat{\theta}\).

    Hàm thông tin (Information):

    • Thông tin quan sát:

      \[ I(\theta) = - \frac{d^2 \ell(\theta)}{d\theta^2} \]

    • Thông tin kỳ vọng (Fisher Information):

      \[ \mathcal{I}(\theta) = \mathrm{E}\left[ I(\theta) \right] \]

    Độ lệch chuẩn của ước lượng:

    \[ \mathrm{SE}(\hat{\theta}) = \sqrt{\frac{1}{\mathcal{I}(\hat{\theta})}} \]

    4.6 Maximum Likelihood for More Than One Parameter

    Score vector:

    \[ U(\boldsymbol{\theta}) = \nabla \ell(\boldsymbol{\theta}) = \left(\frac{\partial \ell}{\partial \theta_1}, \ldots, \frac{\partial \ell}{\partial \theta_p} \right)^T \] Hessian matrix (Observed information):

    \[ I(\boldsymbol{\theta}) = -\nabla^2 \ell(\boldsymbol{\theta}) = - \left[\frac{\partial^2 \ell}{\partial \theta_i \partial \theta_j}\right] \]

    Ước lượng \(\hat{\boldsymbol{\theta}}\) tìm bằng giải hệ \(U(\boldsymbol{\theta}) = 0\).

    Độ lệch chuẩn tham số:
    Được tính từ ma trận nghịch đảo thông tin Fisher:

    \[ \mathrm{Cov}(\hat{\boldsymbol{\theta}}) \approx I(\hat{\boldsymbol{\theta}})^{-1} \]

    4.7 Maximum Likelihood Using Matrix Algebra (tóm tắt)

    • Sử dụng ký hiệu vector và ma trận để biểu diễn score và thông tin.

    • Phương trình score:

      \[ U(\boldsymbol{\theta}) = \mathbf{X}^T \mathbf{W}(\mathbf{y} - \boldsymbol{\mu}) \]

      với \(\mathbf{W}\) là ma trận trọng số tùy theo phân phối.

    • Thông tin Fisher quan sát:

      \[ I(\boldsymbol{\theta}) = \mathbf{X}^T \mathbf{W} \mathbf{X} \]

    4.8 Fisher Scoring for Computing MLEs

    • Thuật toán lặp dựa trên mở rộng Newton-Raphson, sử dụng Fisher Information để cập nhật tham số:

      \[ \boldsymbol{\theta}^{(t+1)} = \boldsymbol{\theta}^{(t)} + I(\boldsymbol{\theta}^{(t)})^{-1} U(\boldsymbol{\theta}^{(t)}) \]

    4.9 Properties of MLEs

    Tính chất:

    • Tính không chệch (asymptotically unbiased)
    • Hiệu quả (asymptotically efficient)
    • Phân phối xấp xỉ chuẩn khi mẫu lớn

    4.10 Hypothesis Testing: Large Sample Asymptotic Results

    • Các phương pháp kiểm định giả thuyết sử dụng MLE:

      • Kiểm định Wald
      • Kiểm định Likelihood Ratio
      • Kiểm định Score (Lagrange Multiplier)

    4.11 Confidence Intervals

    • Cách xây dựng khoảng tin cậy cho tham số dựa trên phân phối chuẩn của MLE:

      \[ \hat{\theta} \pm z_{\alpha/2} \cdot \mathrm{SE}(\hat{\theta}) \]

    4.12 Comparing Non-nested Models: The AIC and BIC

    AIC (Akaike Information Criterion):

    \[ \mathrm{AIC} = -2\ell(\hat{\theta}) + 2k \]

    với \(k\) là số tham số ước lượng.

    BIC (Bayesian Information Criterion):

    \[ \mathrm{BIC} = -2\ell(\hat{\theta}) + k \log n \]

    Dùng để so sánh các mô hình không lồng nhau, chọn mô hình có giá trị AIC hoặc BIC nhỏ hơn.

    Chương 5: Generalized Linear Models (GLMs) - Structure

    5.1 Giới thiệu

    Phần này trình bày mục đích và phạm vi của GLM như một khuôn khổ mở rộng cho hồi quy, giúp mô hình hóa các biến phụ thuộc không tuân theo phân phối chuẩn.

    5.2 The Two Components of Generalized Linear Models

    Hai thành phần chính của GLM

    • Random component (Thành phần ngẫu nhiên):Phân phối xác suất của biến phản hồi, thường thuộc họ Exponential Dispersion Models (EDMs).
    • Systematic component (Thành phần hệ thống): Mối liên hệ tuyến tính giữa biến độc lập với tham số trung bình \(\mu\) của phân phối.

    5.3. The Random Component: Exponential Dispersion Models (EDMs)

    Thành phần ngẫu nhiên: Mô hình phân phối EDM
    EDM là họ phân phối bao gồm nhiều phân phối phổ biến như chuẩn, Poisson, binomial.

    5.3.1. Definition of EDMs (Định nghĩa EDMs):

    Hàm mật độ xác suất được viết dưới dạng:

    \[ f(y; \theta, \phi) = a(y, \phi) \exp\left(\frac{y \theta - \kappa(\theta)}{\phi}\right) \]

    Trong đó:
    \(\theta\) là tham số tự nhiên,
    \(\phi\) là tham số phân tán (dispersion parameter),
    \(\kappa(\theta)\) là hàm cumulant liên quan đến trung bình và phương sai.

    5.3.2. Moment and Cumulant Functions (Hàm moment và cumulant):

    Trung bình và phương sai của biến \(Y\) được tính như sau:

    \[ \mathrm{E}[Y] = \kappa'(\theta) = \mu, \quad \mathrm{Var}[Y] = \phi \kappa''(\theta) = \phi V(\mu) \]

    Với \(V(\mu)\) gọi là hàm biến thiên (variance function), đặc trưng cho phân phối.

    5.3.3. The Variance Function (Hàm biến thiên):

    Xác định cách phương sai thay đổi theo trung bình \(\mu\), rất quan trọng trong GLM.

    5.4 EDMs in Dispersion Model Form

    Mô hình EDM theo dạng độ lệch (deviance)

    Độ lệch đơn vị (unit deviance) dùng để đo sự khác biệt giữa giá trị quan sát \(y\) và giá trị kỳ vọng \(\mu\):

    \[ d(y, \mu) = 2 \left[ \ell(y; y) - \ell(y; \mu) \right] \]

    \(\ell(\cdot)\) là hàm log-likelihood. Độ lệch này được dùng làm tiêu chí đánh giá mô hình.

    5.5 The Systematic Component

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

    Hàm liên kết kết nối trung bình \(\mu\) của biến phản hồi với predictor tuyến tính \(\eta\):

    \[ g(\mu_i) = \eta_i = x_i^T \beta \]

    \(g(\cdot)\) có thể là logit, log, identity,… tùy mô hình.

    Offsets (Thành phần bù trừ): Là phần thêm vào predictor mà không có tham số ước lượng, dùng để điều chỉnh mô hình.

    5.6 Generalized Linear Models Defined

    Định nghĩa tổng quát về GLM
    GLM là mô hình có 3 thành phần:

    • Phân phối thuộc EDM,
    • Predictor tuyến tính \(\eta = X \beta\),
    • Hàm liên kết \(g\).

    5.7 The Total Deviance

    Tổng độ lệch (deviance) của mô hình
    Độ lệch tổng hợp cho toàn bộ dữ liệu:

    \[ D = \sum_{i=1}^n d(y_i, \hat{\mu}_i) \]

    Dùng để đánh giá sự phù hợp của mô hình.

    5.8 Regression Transformations Approximate GLMs

    Các biến đổi hồi quy xấp xỉ mô hình GLM
    Phần này nói về cách các mô hình hồi quy truyền thống có thể được xem như xấp xỉ GLM thông qua biến đổi dữ liệu.

    Chương 6: Generalized Linear Models:Estimation

    6.1 Giới thiệu

    Chương này tập trung vào việc ước lượng tham số \(\beta\) trong GLM, chủ yếu dựa trên phương pháp Ước lượng Cực Đại (Maximum Likelihood Estimation - MLE).
    Mục tiêu là tìm bộ tham số \(\hat{\beta}\) sao cho mô hình phù hợp tốt nhất với dữ liệu quan sát.

    6.2 Likelihood Calculations for \(\beta\)

    6.2.1. Differentiating the Probability Function (Đạo hàm hàm xác suất)

    Hàm log-likelihood tổng quát cho dữ liệu \(y = (y_1, \dots, y_n)\) là:

    \[ \ell(\beta) = \sum_{i=1}^n \ell_i(\beta) = \sum_{i=1}^n \log f(y_i; \theta_i, \phi) \]

    Trong đó \(\theta_i\) phụ thuộc vào \(\beta\) thông qua predictor tuyến tính.

    6.2.2. Score Equations and Information for \(\beta\) (Phương trình score và ma trận thông tin)

    Đạo hàm bậc nhất của log-likelihood (score function):

    \[ U(\beta) = \frac{\partial \ell(\beta)}{\partial \beta} \]

    Ma trận Fisher information:

    \[ I(\beta) = -\mathbb{E} \left[ \frac{\partial^2 \ell(\beta)}{\partial \beta \partial \beta^T} \right] \]

    6.3. Computing Estimates of \(\beta\)

    Tính toán ước lượng \(\hat{\beta}\)
    Do phương trình score thường không giải được chính xác, ta dùng phương pháp lặp như Newton-Raphson hoặc Fisher Scoring để tìm nghiệm gần đúng của:

    \[ U(\beta) = 0 \]

    Phương pháp lặp cập nhật tham số:

    \[ \beta^{(t+1)} = \beta^{(t)} + \left[ I(\beta^{(t)}) \right]^{-1} U(\beta^{(t)}) \]

    6.4. The Residual Deviance

    Độ lệch dư (Residual Deviance)
    Là thước đo sự khác biệt giữa mô hình hiện tại với mô hình bão hòa (mô hình hoàn hảo):

    \[ D = 2 \sum_{i=1}^n \left[ \ell(y_i; y_i) - \ell(y_i; \hat{\mu}_i) \right] \]

    Độ lệch dư càng nhỏ thì mô hình càng phù hợp với dữ liệu.

    6.5. Standard Errors for \(\hat{\beta}\)

    Sai số chuẩn của ước lượng \(\hat{\beta}\)
    Được tính từ ma trận thông tin Fisher:

    \[ \text{Var}(\hat{\beta}) = I(\hat{\beta})^{-1} \]

    Sai số chuẩn cho từng tham số là căn bậc hai các phần tử trên đường chéo của ma trận này.

    6.6. Estimation of \(\beta\): Matrix Formulation

    Ước lượng \(\beta\) dưới dạng ma trận
    Cách trình bày toán học dùng ma trận để thuận tiện tính toán với dữ liệu lớn:

    \[ U(\beta) = X^T W (y - \mu) \]

    Trong đó:
    - \(X\) là ma trận thiết kế,
    - \(W\) là ma trận trọng số,
    - \(\mu = g^{-1}(X\beta)\).

    6.7. Estimation of GLMs Is Locally Like Linear Regression

    Ước lượng GLM tương tự hồi quy tuyến tính cục bộ
    Kỹ thuật ước lượng GLM thực chất là lặp lại các bước hồi quy tuyến tính với trọng số cập nhật từng vòng, gọi là Iteratively Reweighted Least Squares (IRLS).

    6.8. Estimating \(\phi\) — Ước lượng tham số phân tán \(\phi\)

    Trong GLM, tham số phân tán \(\phi\) (dispersion parameter) biểu thị mức độ biến động ngoài phần giải thích được bởi mô hình tuyến tính. Với một số phân phối (như Gaussian, Gamma) \(\phi\) là tham số quan trọng cần được ước lượng chính xác.

    6.8.1. Giới thiệu

    \(\phi\) là tham số đo độ phân tán (variance) trong gia đình phân phối của GLM, thể hiện mức độ phân tán của dữ liệu quanh giá trị kỳ vọng.

    • Với phân phối PoissonBernoulli, \(\phi\) thường được coi là bằng 1, không cần ước lượng.
    • Với phân phối Gaussian, \(\phi\) là phương sai của sai số.

    6.8.2. The Maximum Likelihood Estimator of \(\phi\)

    Ước lượng \(\phi\) theo phương pháp MLE

    Giả sử có \(n\) quan sát, tham số \(\beta\) đã được ước lượng. Hàm log-likelihood phụ thuộc vào \(\phi\) được dùng để tối đa hóa tìm \(\hat{\phi}\).

    Một công thức phổ biến cho \(\hat{\phi}_{\text{MLE}}\) là:

    \[ \hat{\phi}_{\text{MLE}} = \frac{1}{n} \sum_{i=1}^n d_i \]

    trong đó \(d_i\)unit deviance (độ lệch đơn vị) của quan sát thứ \(i\), thể hiện khoảng cách giữa quan sát và giá trị kỳ vọng mô hình dự đoán.

    6.8.3. Modified Profile Log-Likelihood Estimator of \(\phi\)

    Ước lượng dựa trên log-likelihood hiệu chỉnh

    Để cải thiện tính ổn định và tính chính xác của ước lượng, người ta dùng profile likelihood đã chỉnh sửa (modified profile log-likelihood).
    Phương pháp này giảm bias so với MLE.

    Công thức cụ thể phức tạp, thường dựa trên việc điều chỉnh hàm log-likelihood theo tham số \(\beta\) đã được ước lượng.

    6.8.4. Mean Deviance Estimator of \(\phi\)

    Ước lượng dựa trên độ lệch trung bình

    Phương pháp này tính \(\hat{\phi}\) dựa trên độ lệch dư (residual deviance) chia cho bậc tự do (degrees of freedom):

    \[ \hat{\phi}_{\text{deviance}} = \frac{D}{n - p} \]

    Trong đó:

    • \(D = \sum_{i=1}^n d_i\) là tổng độ lệch dư,
    • \(n\) là số quan sát,
    • \(p\) là số tham số được ước lượng (độ tự do của mô hình).

    6.8.5. Pearson Estimator of \(\phi\)

    Ước lượng dựa trên residuals Pearson

    Dùng tổng bình phương các residuals chuẩn hóa Pearson chia cho bậc tự do:

    \[ \hat{\phi}_{\text{Pearson}} = \frac{1}{n - p} \sum_{i=1}^n \frac{(y_i - \hat{\mu}_i)^2}{V(\hat{\mu}_i)} \]

    Trong đó:

    • \(y_i\) là quan sát thứ \(i\),
    • \(\hat{\mu}_i\) là giá trị kỳ vọng theo mô hình,
    • \(V(\hat{\mu}_i)\) là hàm phương sai ứng với mô hình (variance function).

    6.8.6. Which Estimator of \(\phi\) Is Best?

    So sánh và lựa chọn ước lượng tốt nhất

    • \(\hat{\phi}_{\text{MLE}}\) là ước lượng thiên vị (biased) nhưng nhất quán.
    • \(\hat{\phi}_{\text{deviance}}\)\(\hat{\phi}_{\text{Pearson}}\) thường được dùng trong thực tế vì dễ tính và có tính chất bất biến tốt hơn.

    Lựa chọn phương pháp tùy theo mục đích phân tích và đặc điểm dữ liệu.

    Chương 7: Inference and Model Assessment – Suy luận và đánh giá mô hình

    7.1. Giới thiệu

    Các phương pháp suy luận thống kê trong GLM, bao gồm kiểm định giả thuyết, ước lượng khoảng tin cậy cho hệ số hồi quy và giá trị kỳ vọng, và các phương pháp đánh giá độ phù hợp mô hình.

    7.2. Inference for Coefficients When 𝜙 Is Known

    Khi\(\phi\)đã biết (ví dụ trong mô hình nhị phân hoặc Poisson), các kiểm định suy luận được thực hiện như sau:

    7.2.1. Wald Tests for Single Regression Coefficients

    Kiểm định Wald cho từng hệ số hồi quy \(\beta_j\):

    \[ Z = \frac{\hat{\beta}_j}{SE(\hat{\beta}_j)} \sim N(0,1) \]

    Nếu \(|Z| > z_{\alpha/2}\), bác bỏ giả thuyết \(H_0: \beta_j = 0\).

    SE là sai số chuẩn của \(\hat{\beta}_j\), lấy từ ma trận phương sai–hiệp phương sai.

    7.2.2. Confidence Intervals for Individual Coefficients

    Khoảng tin cậy cho \(\beta_j\):

    \[ \hat{\beta}_j \pm z_{\alpha/2} \cdot SE(\hat{\beta}_j) \]

    7.2.3. Confidence Intervals for 𝜇

    Khoảng tin cậy cho \(\mu_i = E[Y_i]\):

    Ước lượng khoảng tin cậy cho \(\eta_i = x_i^T \hat{\beta}\)

    Sau đó chuyển sang \(\mu_i\) thông qua hàm liên kết nghịch đảo \(g^{-1}(\cdot)\):

    \[ g^{-1}\left(\hat{\eta}_i \pm z_{\alpha/2} \cdot SE(\hat{\eta}_i)\right) \]

    7.2.4. Likelihood Ratio Tests to Compare Nested Models: 𝜒² Tests

    Kiểm định tỉ số hợp lý:

    \[ \Lambda = -2\left[\ell(\hat{\beta}_{\text{reduced}}) - \ell(\hat{\beta}_{\text{full}})\right] \sim \chi^2_{df} \]

    Với \(df\) là số tham số bị ràng buộc.

    7.2.5. Analysis of Deviance Tables to Compare Nested Models

    Phân tích phương sai:

    \[ \Delta D = D_{\text{reduced}} - D_{\text{full}} \sim \chi^2_{df} \]

    7.2.6. Score Tests

    Dựa trên đạo hàm bậc nhất của log-likelihood:

    \[ U(\beta_0)^T I(\beta_0)^{-1} U(\beta_0) \sim \chi^2_1 \]

    7.3. Large Sample Asymptotics – Tiệm cận mẫu lớn

    Với kích thước mẫu lớn, các ước lượng \(\hat{\beta}\) xấp xỉ phân phối chuẩn, cho phép dùng kiểm định Wald, tỉ số hợp lý và score test.

    7.4. Goodness-of-Fit Tests with 𝜙 Known

    7.4.1. The Idea of Goodness-of-Fit

    So sánh mô hình dự đoán với dữ liệu thực, kiểm tra phần còn lại có phải là nhiễu ngẫu nhiên không.

    7.4.2. Deviance Goodness-of-Fit Test

    Dựa trên tổng deviance:

    \[ D \sim \chi^2_{n - p} \]

    Nếu \(D\) quá lớn, mô hình không phù hợp.

    7.4.3. Pearson Goodness-of-Fit Test

    Dựa trên thống kê Pearson:

    \[ X^2 = \sum_{i=1}^n \frac{(y_i - \hat{\mu}_i)^2}{V(\hat{\mu}_i)} \sim \chi^2_{n - p} \]

    7.5. Small Dispersion Asymptotics

    Khi \(\phi \rightarrow 0\), GLM xấp xỉ mô hình xác định, residuals nhỏ, kiểm định mạnh hơn.

    7.6. Inference for Coefficients When 𝜙 Is Unknown

    7.6.1. Wald Tests for Single Regression Coefficients

    Điều chỉnh SE bằng \(\hat{\phi}\):

    \[ t = \frac{\hat{\beta}_j}{\hat{\phi} \cdot \text{Var}(\hat{\beta}_j)} \sim t_{n - p} \]

    7.6.2. Confidence Intervals for Individual Coefficients

    \[ \hat{\beta}_j \pm t_{\alpha/2, n - p} \cdot \hat{\phi} \cdot \text{Var}(\hat{\beta}_j) \]

    7.6.3. Likelihood Ratio Tests to Compare Nested Models: F-Tests

    \[ F = \frac{(D_{\text{reduced}} - D_{\text{full}})/q}{\hat{\phi}} \sim F_{q, n - p} \]

    Với \(q\) là số bậc tự do thêm vào.

    7.7. Comparing Wald, Score and Likelihood Ratio Tests

    • Wald dễ tính nhưng không chính xác nếu \(\hat{\beta}\) gần biên.
    • Likelihood Ratio mạnh và phổ quát hơn.
    • Score phù hợp nếu chỉ ước lượng mô hình rút gọn.

    Chương 8: Generalized Linear Models:Diagnostics

    8.1 Giới thiệu và Tổng quan

    Mô hình GLM mở rộng hồi quy tuyến tính cổ điển để xử lý các dữ liệu có phân phối không chuẩn như nhị phân (binary), đếm (count), tỷ lệ,… Việc chẩn đoán giúp xác định xem mô hình có phù hợp với dữ liệu hay không, từ đó điều chỉnh hoặc cải tiến mô hình.

    8.2. Các giả định của GLMs

    • Dữ liệu \(y_i\) độc lập.

    • \(y_i\) thuộc họ phân phối hàm mũ (Exponential Family).

    • Có hàm liên kết:
      \[ g(\mu_i) = \eta_i = x_i^T \beta \]

    • Phương sai phụ thuộc vào trung bình:
      \[ \text{Var}(Y_i) = \phi V(\mu_i) \]

    Trong đó:
    - \(\phi\): hệ số phân tán (dispersion parameter).
    - \(V(\mu_i)\): hàm phương sai đặc trưng cho từng phân phối.

    8.3. Các loại phần dư (Residuals)

    8.3.1. Phần dư phản hồi (Response residuals)

    \[ r_i^{(R)} = y_i - \hat{\mu}_i \]

    → Không chuẩn hóa, ít được dùng trong GLMs vì phương sai thay đổi theo \(\mu_i\).

    8.3.2. Phần dư Pearson

    \[ r_i^{(P)} = \frac{y_i - \hat{\mu}_i}{\sqrt{\hat{V}(\hat{\mu}_i)}} \] Trong đó: - \(y_i\): giá trị quan sát thực tế.
    - \(\hat{\mu}_i\): giá trị dự đoán từ mô hình.
    - \(\hat{V}(\hat{\mu}_i)\): phương sai dự đoán từ hàm phương sai của GLM.

    → Thích hợp để kiểm tra phương sai và phát hiện quan sát bất thường.

    8.3.3. Phần dư Deviance

    \[ r_i^{(D)} = \text{sign}(y_i - \hat{\mu}_i) \cdot \sqrt{2 \left[ \ell(y_i; y_i) - \ell(y_i; \hat{\mu}_i) \right]} \]

    Trong đó \(\ell(y_i; \mu)\) là log-likelihood đơn.

    → Được dùng phổ biến để đánh giá tổng thể độ phù hợp của mô hình.

    8.3.4. Phần dư Quantile

    \[ r_i^{(Q)} = \Phi^{-1} \left( F_{Y_i}(y_i \mid \hat{\mu}_i, \hat{\phi}) \right) \]

    • \(F_{Y_i}\): hàm phân phối tích lũy (CDF) của biến phản hồi.
    • \(\Phi^{-1}\): phân phối chuẩn ngược (inverse standard normal CDF).

    → Nếu mô hình đúng, các phần dư này có phân phối chuẩn.

    8.4. Hệ số ảnh hưởng (Leverage)

    8.4.1. Hệ số leverage hiệu dụng (Working leverage)

    Leverage tại điểm \(i\) là phần tử đường chéo của ma trận mũ (hat matrix), ký hiệu là \(h_i\).

    8.4.2. Ma trận mũ (Hat matrix)

    GLM không có công thức đóng như hồi quy tuyến tính, nhưng nếu tuyến tính hóa mô hình tại bước lặp cuối thì:

    \[ H = W^{1/2} X (X^T W X)^{-1} X^T W^{1/2} \]

    Trong đó:

    \[ W: \text{ma trận trọng số (diagonal) với } w_i = \left( \frac{d\mu_i}{d\eta_i} \right)^2 / V(\mu_i) \]

    \(h_i = H_{ii}\)

    8.5. Phần dư chuẩn hóa theo leverage (Standardized residuals)

    \[ r_{i,\text{std}} = \frac{r_i}{\sqrt{1 - h_i}} \]

    → Dùng để phát hiện ngoại lệ có leverage cao.

    8.6. Khi nào dùng loại phần dư nào

    Loại phần dư Khi nào dùng
    Pearson Kiểm tra phương sai, phát hiện bất thường
    Deviance Đánh giá tổng thể mô hình
    Quantile So sánh với chuẩn, dùng để chẩn đoán trực quan
    Response Ít dùng trong GLMs

    8.7. Kiểm tra giả định mô hình

    8.7.1. Kiểm tra tính độc lập

    Vẽ phần dư theo độ trễ \(r_i\) vs \(r_{i-1}\).
    → Nếu có mẫu, có thể có hiện tượng tự tương quan.

    8.7.2. Kiểm tra thành phần hệ thống

    Vẽ \(r_i\) theo các biến dự báo (predictors) để phát hiện dạng sai hàm liên kết hoặc thiếu biến.

    8.7.3. Kiểm tra thành phần ngẫu nhiên

    Vẽ phần dư chuẩn hóa vs giá trị dự đoán \(\hat{\mu}_i\).
    → Nếu phân bố hình quạt → có hiện tượng phương sai không đồng nhất.

    8.8. Ngoại lệ và quan sát ảnh hưởng

    8.8.1. Phần dư Studentized

    \[ t_i = \frac{r_i}{\hat{\sigma} \sqrt{1 - h_i}} \]

    → Nếu \(|t_i| > 2\), có thể là ngoại lệ.

    8.8.2. Điểm ảnh hưởng lớn (Influential observations)

    Cook’s Distance:

    \[ D_i = \frac{r_i^2}{p \cdot \hat{\sigma}^2} \cdot \frac{h_i}{(1 - h_i)^2} \]

    → Nếu \(D_i > 1\) hoặc lớn bất thường so với phần còn lại ⇒ điểm ảnh hưởng mạnh.

    8.9. Cách xử lý vấn đề

    • Thay đổi hàm liên kết (ví dụ: từ log sang logit).
    • Biến đổi biến đầu vào hoặc đầu ra (log, square root,…).
    • Thay mô hình khác (Negative Binomial thay vì Poisson).
    • Loại bỏ hoặc gộp các điểm ngoại lệ nếu hợp lý về mặt dữ liệu.

    8.10. Quasi-likelihood và Extended Quasi-likelihood

    Khi phân phối của \(Y\) không thuộc họ exponential nhưng vẫn muốn dùng GLM:

    \[ \text{Var}(Y_i) = \phi V(\mu_i) \]

    → Không cần giả định hàm mật độ xác suất cụ thể, nhưng vẫn ước lượng được thông qua phương pháp quasi-likelihood.

    8.11. Đa cộng tuyến (Collinearity)

    Kiểm tra bằng VIF – Variance Inflation Factor:

    \[ \text{VIF}_j = \frac{1}{1 - R_j^2} \]

    → Nếu \(\text{VIF} > 5\) hoặc \(> 10\) thì có thể có đa cộng tuyến nghiêm trọng.

    Chương 9: ModelsforProportions:BinomialGLMs

    9.1. Giới Thiệu

    Mô hình tỷ lệ là một dạng đặc biệt của GLM khi biến phụ thuộc biểu diễn dữ liệu dưới dạng tỷ số hoặc tỷ lệ, được mô hình hóa bằng phân phối nhị phân (binomial).

    9.2. Mô Hình Tỷ Lệ

    • Dữ liệu gồm các cặp (số lần thành công, số lần thử nghiệm).
    • Phân phối: Binomial.
    • Hàm liên kết (tuỳ theo link): logit, probit, complementary log-log, …

    9.4. Phân Phối Dung Sai & Liên Kết Probit

    • Dựa trên giả định: cá nhân có ngưỡng dung sai.
    • Xác suất thành công: \(P(Y = 1 \mid x) = \Phi(x^T\beta)\)

    9.5. Odds, Odds Ratio & Logit

    • Tỷ lệ thành công: \(\mu\), tỷ số odds: \(\dfrac{\mu}{1 - \mu}\)
    • Odds ratio: \(\dfrac{\mu_1/(1 - \mu_1)}{\mu_0/(1 - \mu_0)}\)
    • Hàm logit giúp tuyến tính hoá odds ratio: \(\log\left(\dfrac{\mu}{1 - \mu}\right) = x^T \beta\)

    9.6. Liều Trung Vị Hiệu Quả (ED50)

    • \(ED_{50}\): mức \(x\) sao cho \(\mu = 0.5\)
    • Tính từ hàm nghịch: \(x = g^{-1}(0.5)\)

    9.7. Liên Kết Complementary Log-Log

    • Dùng khi xác suất rất gần 0 hoặc 1.
    • Tỷ lệ phù hợp cho mô hình lấy mẫu dạng assay sinh học.

    9.8. Overdispersion

    • Khi biến phụ thuộc biến thiên nhiều hơn mong đợi của Binomial.
    • Giải pháp: sử dụng phân phối quasibinomial, sai số sẽ lớn hơn.
    • Estimator: điều chỉnh phương sai với hệ số phân tán \(\phi\).

    9.9. Khi Wald Tests Thất Bại

    • Khi ước lượng \(\hat{\beta}\) có phần bổng, standard error cao.
    • Giải pháp: dùng Likelihood Ratio Test hoặc Score Test thay thế.

    9.10. Mở Rộng: Thiếu Kiểm Định Goodness-of-Fit

    • Khi dữ liệu chỉ là 0/1, không thể đánh giá chi tiết mức độ phù hợp.
    • Chỉ kiểm định thông qua các tiêu chí: AIC, BIC, deviance.

    Chương 10: Models for Counts:Poisson and Negative Binomial GLMs

    10.1. Giới thiệu

    Chương này tập trung vào việc mô hình hóa dữ liệu đếm (count data) bằng cách sử dụng Mô hình Tuyến tính Tổng quát (GLMs) với phân phối Poisson và Negative Binomial. Đây là những công cụ mạnh mẽ để phân tích các biến phản hồi rời rạc, chẳng hạn như số lần xảy ra sự kiện trong một khoảng thời gian hoặc không gian nhất định.

    10.2. Tóm tắt về Poisson GLMs

    Công thức mô hình Poisson:

    \[ \log(\mu_i) = \alpha + \beta_1 x_{1i} + \beta_2 x_{2i} + \cdots + \beta_p x_{pi} \]

    Công thức mô hình Poisson với biến offset (khi mô hình hóa tỷ lệ): \[ \log(\mu_i) = \alpha + \beta_1 x_{1i} + \cdots + \beta_p x_{pi} + \log(t_i) \]

    Trong đó: \(t_i\): Biến offset, thường đại diện cho thời gian quan sát hoặc mức độ phơi nhiễm (exposure) của quan sát thứ \(i\).

    10.3. Mô hình hóa Tỷ lệ

    Khi dữ liệu đếm liên quan đến các khoảng thời gian hoặc không gian khác nhau, việc sử dụng biến offset giúp điều chỉnh mô hình để phản ánh tỷ lệ xảy ra sự kiện.

    Công thức mô hình hóa tỷ lệ:

    \[ \log\left(\frac{\mu_i}{t_i}\right) = \alpha + \beta_1 x_{1i} + \cdots + \beta_p x_{pi} \] Trong đó: \(\frac{\mu_i}{t_i}\): Tỷ lệ kỳ vọng của sự kiện trên đơn vị thời gian hoặc không gian.

    10.4.Bảng Tần số – Mô hình Log-Linear

    10.4.1. Giới thiệu

    Mô hình log-linear được sử dụng để phân tích các bảng tần số, nơi tất cả các biến đều là biến phân loại. Trong mô hình này, biến phản hồi là số đếm trong mỗi ô của bảng, và các biến giải thích là các yếu tố phân loại.

    10.4.2. Bảng Hai Chiều: Thành phần Hệ thống

    Xét bảng tần số hai chiều với các biến phân loại \(A\)\(B\), số đếm trong ô \((i, j)\) được ký hiệu là \(n_{ij}\). Mô hình log-linear có dạng: \[ \log(\mu_{ij}) = \lambda + \lambda_i^A + \lambda_j^B + \lambda_{ij}^{AB} \] Trong đó:

    \(\mu_{ij} : \text{Kỳ vọng của số đếm trong ô } (i, j).\)

    \(\lambda : \text{Hằng số chung (intercept).}\)

    \(\lambda_i^A : \text{Hiệu ứng chính của mức thứ } i \text{ của biến } A.\)

    \(\lambda_j^B : \text{Hiệu ứng chính của mức thứ } j \text{ của biến } B.\)

    \(\lambda_{ij}^{AB} : \text{Hiệu ứng tương tác giữa mức } i \text{ của } A \text{ và mức } j \text{ của } B.\)

    Nếu \(\lambda_{ij}^{AB} = 0 \quad \text{cho mọi } i, j,\)thì mô hình biểu thị sự độc lập giữa \(A\)\(B\).

    10.4.3. Bảng Hai Chiều: Thành phần Ngẫu nhiên

    Trong mô hình log-linear, giả định rằng các số đếm \(n_{ij}\) tuân theo phân phối Poisson với kỳ vọng \(\mu_{ij}\):

    \[n_{ij} \sim \text{Poisson}(\mu_{ij})\] Điều này cho phép sử dụng mô hình tuyến tính tổng quát (GLM) với hàm liên kết log để ước lượng các tham số.

    10.4.4. Bảng Ba Chiều

    Khi mở rộng sang bảng ba chiều với các biến A, B, C, mô hình log-linear có thể bao gồm các hiệu ứng chính và tương tác hai chiều, ba chiều:

    \[\log(\mu_{ijk}) = \lambda + \lambda_i^A + \lambda_j^B + \lambda_k^C + \lambda_{ij}^{AB} + \lambda_{ik}^{AC} + \lambda_{jk}^{BC} + \lambda_{ijk}^{ABC}\] Trong đó:

    \(\mu_{ijk} : \text{Kỳ vọng của số đếm trong ô } (i,j,k).\)

    \(\lambda_{ijk}^{ABC} : \text{Hiệu ứng tương tác ba chiều giữa các mức } i, j, k \text{ của các biến } A, B, C.\)

    Việc bao gồm hoặc loại bỏ các hiệu ứng tương tác cho phép kiểm tra các giả thuyết về mối quan hệ giữa các biến.

    10.4.5. Nghịch lý Simpson

    Nghịch lý Simpson xảy ra khi một xu hướng xuất hiện trong từng nhóm con của dữ liệu nhưng biến mất hoặc đảo ngược khi các nhóm được kết hợp. Trong ngữ cảnh mô hình log-linear, điều này nhấn mạnh tầm quan trọng của việc xem xét các tương tác giữa các biến để tránh rút ra kết luận sai lầm từ dữ liệu tổng hợp.

    Ví dụ, trong một nghiên cứu về tuyển sinh đại học, có thể thấy rằng tỷ lệ chấp nhận của nam cao hơn nữ tổng thể, nhưng khi phân tích theo từng khoa, tỷ lệ chấp nhận của nữ lại cao hơn trong hầu hết các khoa. Điều này cho thấy sự cần thiết của việc mô hình hóa các tương tác giữa giới tính và khoa để hiểu đúng bản chất của dữ liệu.

    10.4.6. Tương đương giữa Mô hình Binomial và Poisson GLMs

    Trong một số trường hợp, mô hình log-linear Poisson có thể tương đương với mô hình hồi quy logistic (Binomial GLM), đặc biệt khi phân tích bảng tần số hai chiều. Cụ thể, khi mô hình hóa xác suất thành công trong mỗi ô của bảng, mô hình log-linear với phân phối Poisson và hàm liên kết log có thể cung cấp kết quả tương đương với mô hình logistic với phân phối nhị thức và hàm liên kết logit.

    10.4.7. Bảng bậc cao hơn

    Mô hình log-linear có thể được mở rộng để phân tích các bảng tần số với nhiều hơn ba chiều (bảng bậc cao hơn). Việc xây dựng mô hình bao gồm các hiệu ứng chính và tương tác giữa các biến, tùy thuộc vào giả thuyết nghiên cứu và cấu trúc của dữ liệu.

    10.4.8. Số không cấu trúc trong bảng tần số

    Trong một số bảng tần số, có thể xuất hiện các ô với số đếm bằng 0 do cấu trúc của dữ liệu hoặc các ràng buộc logic (structural zeros). Khi xây dựng mô hình log-linear, cần xử lý các ô này một cách cẩn thận, thường bằng cách loại trừ chúng khỏi mô hình hoặc áp dụng các kỹ thuật đặc biệt để đảm bảo ước lượng tham số chính xác.

    10.5. Overdispersion

    Overdispersion xảy ra khi phương sai của dữ liệu lớn hơn kỳ vọng theo mô hình Poisson, vi phạm giả định \(\mathrm{Var}(Y) = \mu\)

    10.5.1. Overdispersion trong Poisson GLMs

    Khi overdispersion xuất hiện, mô hình Poisson có thể không phù hợp, dẫn đến việc đánh giá sai lầm về ý nghĩa thống kê của các hệ số.

    10.5.2. Negative Binomial GLMs

    Mô hình Negative Binomial thêm một tham số phân tán \(\theta\) để điều chỉnh phương sai:

    \[\text{Var}(Y_i) = \mu_i + \theta \mu_i^2\]

    Trong đó:\(\theta\) tham số phân tán, điều chỉnh mức độ overdispersion.

    10.5.3. Mô hình Quasi-Poisson

    Mô hình Quasi-Poisson sử dụng một hệ số phân tán \(\phi\) để điều chỉnh phương sai: \[ \mathrm{Var}(Y_i) = \phi \mu_i \] Trong đó: \(\phi\) là hệ số phân tán

    Chương 11: Positive Continuous Data: Gamma and Inverse Gaussian GLMs

    11.1. Giới thiệu

    Chương này xem xét các mô hình tuyến tính tổng quát (GLMs) cho các biến phụ thuộc là liên tục và dương (ví dụ: thời gian sống, chi phí, tốc độ). Hai phân phối phổ biến trong nhóm này là Gamma và Inverse Gaussian.

    11.2. Mô hình hóa Dữ liệu Liên tục Dương

    Trong GLMs, ta giả định:

    • \(Y \sim \text{Gamma}(\mu, \phi)\) hoặc \(Y \sim \text{Inverse Gaussian}(\mu, \phi)\)
    • Với \(g(\mu) = \eta = \mathbf{x}^\top \boldsymbol{\beta}\)

    Tring đó:

    • \(Y\): Biến phản hồi (liên tục và dương).
    • \(\mu\): Kỳ vọng của \(Y\), \(\mu = \mathbb{E}(Y)\)
    • \(\eta\): Predictor tuyến tính
    • \(\mathbf{x}\): Vector các biến độc lập
    • \(\boldsymbol{\beta}\): Vector hệ số hồi quy
    • \(g(\cdot)\): Hàm liên kết (link function)
    • \(\phi\): Tham số phân tán (dispersion parameter)

    11.3. Phân phối Gamma

    Phân phối Gamma có hàm mật độ xác suất (PDF):

    \[ f(y; \mu, \phi) = \frac{1}{\Gamma(1/\phi)} \left( \frac{1}{\phi \mu} \right)^{1/\phi} y^{1/\phi - 1} \exp\left( -\frac{y}{\phi \mu} \right) \]

    Trong đó:

    • \(y > 0\): Giá trị quan sát
    • \(\mu\): Trung bình \(\mathbb{E}(Y)\)
    • \(\phi\): Tham số phân tán
    • \(\Gamma(\cdot)\): Hàm gamma

    Các hàm liên kết phổ biến:

    • Log link: \(\log(\mu) = \eta\)
    • Inverse link: \(\mu^{-1} = \eta\)
    • Identity link: \(\mu = \eta\)

    Phương sai của Gamma:

    \[ \text{Var}(Y) = \phi \mu^2 \]

    11.4. Phân phối Inverse Gaussian

    Phân phối Inverse Gaussian có hàm mật độ:

    \[ f(y; \mu, \phi) = \left( \frac{1}{2\pi \phi y^3} \right)^{1/2} \exp\left( -\frac{(y - \mu)^2}{2\phi \mu^2 y} \right) \]

    Trong đó:

    • \(y > 0\): Giá trị quan sát
    • \(\mu\): Kỳ vọng
    • \(\phi\): Tham số phân tán

    Phương sai của Inverse Gaussian:

    \[ \text{Var}(Y) = \phi \mu^3 \]

    11.6. Ước lượng Tham số Phân tán (Dispersion Parameter)

    GLMs với phân phối Gamma và Inverse Gaussian có tham số phân tán \(\phi\), cần được ước lượng từ dữ liệu.

    11.6.1. Ước lượng \(\phi\) cho Gamma

    \[ \hat{\phi} = \frac{1}{n - p} \sum_{i=1}^{n} \left( \frac{y_i - \hat{\mu}_i}{\hat{\mu}_i} \right)^2 \]

    Trong đó:

    • \(n\): Số quan sát
    • \(p\): Số tham số (bậc tự do)
    • \(y_i\): Quan sát thực tế
    • \(\hat{\mu}_i\): Dự đoán từ mô hình

    11.6.2. Ước lượng \(\phi\) cho Inverse Gaussian

    \[ \hat{\phi} = \frac{1}{n - p} \sum_{i=1}^{n} \frac{(y_i - \hat{\mu}_i)^2}{\hat{\mu}_i^3} \]

    Trong đó:

    • Các biến như trên
    • \(\hat{\mu}_i^3\): Phản ánh phương sai đặc trưng của Inverse Gaussian

    Chương 12: Tweedie GLMs

    12.1. Giới thiệu và Tổng quan

    Tweedie GLMs là mô hình mở rộng thuộc họ exponential dispersion models (EDMs), có thể xử lý nhiều kiểu dữ liệu khác nhau:

    • Liên tục dương
    • Dữ liệu có giá trị 0 và dương liên tục
    • Dữ liệu đếm

    Phù hợp với các trường hợp như: tổn thất bảo hiểm (nhiều giá trị 0 và một số giá trị dương lớn), dữ liệu sinh học,…

    12.2. Tweedie EDMs

    12.2.1. Giới thiệu phân phối Tweedie

    Tweedie EDMs là một lớp phân phối xác định bởi:

    • Hàm kỳ vọng \(\mu\)
    • Tham số phân tán \(\phi\)
    • Tham số chỉ số (index parameter) \(\xi\)

    Hàm phương sai có dạng:

    \[ \text{Var}(Y) = \phi \mu^\xi \]

    Trong đó

    • \(Y\): Biến phản hồi
    • \(\mu = \mathbb{E}(Y)\): Kỳ vọng
    • \(\phi\): Tham số phân tán
    • \(\xi\): Tham số chỉ số xác định dạng của phân phối Tweedie

    Một số giá trị đặc biệt của \(\xi\):

    • \(\xi = 0\): Normal
    • \(\xi = 1\): Poisson
    • \(\xi = 2\): Gamma
    • \(\xi = 3\): Inverse Gaussian
    • \(1 < \xi < 2\): Hỗn hợp giữa giá trị 0 và phân phối liên tục dương

    12.2.2. Cấu trúc của Tweedie EDMs

    Hàm mật độ xác suất không có biểu thức đóng, nhưng vẫn thuộc họ EDM nên có dạng:

    \[ f(y; \theta, \phi) = a(y, \phi) \exp\left( \frac{y \theta - \kappa(\theta)}{\phi} \right) \]

    Trong đó:

    • \(\theta\): Tham số tự nhiên (natural parameter)
    • \(\kappa(\theta)\): Hàm log-partition
    • \(a(y, \phi)\): Hàm chuẩn hóa

    12.2.3. Tweedie EDMs cho dữ liệu liên tục dương

    Dành cho các trường hợp chỉ có giá trị dương (như dữ liệu chi phí, thời gian, khoảng cách,…). Phân phối mô hình hóa biến dương với tính phân tán cao.

    12.2.4. Tweedie EDMs cho dữ liệu có số 0 và giá trị dương

    Đây là ứng dụng nổi bật: phân phối Tweedie với \(1 < \xi < 2\) có xác suất khác 0 tại điểm 0 (point mass at zero), nên phù hợp mô hình hóa dữ liệu có nhiều giá trị bằng 0 và phần còn lại là số dương liên tục.

    12.3. Tweedie GLMs

    12.3.1. Giới thiệu

    Ta xây dựng GLM với giả định \(Y \sim \text{Tweedie}(\mu, \phi, \xi)\) và:

    \[ g(\mu) = \eta = \mathbf{x}^\top \boldsymbol{\beta} \]

    Trong đó

    • \(g(\cdot)\): Hàm liên kết (thường là log)
    • \(\eta\): Predictor tuyến tính
    • \(\mathbf{x}\): Vector biến độc lập
    • \(\boldsymbol{\beta}\): Hệ số hồi quy

    12.3.2. Ước lượng tham số chỉ số \(\xi\)

    Tham số \(\xi\) không được ước lượng trực tiếp bằng MLE trong hàm GLM cơ bản, mà thường dùng:

    • Quét các giá trị từ 1 đến 2
    • Chọn giá trị tối đa hóa log-likelihood hoặc tối thiểu hóa AIC

    12.3.3. Ước lượng và Fit mô hình

    Mô hình Tweedie thường dùng link hàm log:

    \[ \log(\mu_i) = \mathbf{x}_i^\top \boldsymbol{\beta} \]

    Ước lượng mô hình bằng các gói phần mềm như:

    • R: statmod, tweedie, cplm
    • Python: pyGAM, statsmodels (có giới hạn)

    2. THỐNG KÊ MÔ TẢ

    2.1. Đọc dữ liệu

    supermarket <- read.csv2("D:/naaaaaa/PTDLDT/Supermarket Transactions.csv", stringsAsFactors = FALSE, fileEncoding = "UTF-8")
    # Xem cấu trúc dữ liệu
    str(supermarket)
    ## 'data.frame':    14059 obs. of  16 variables:
    ##  $ X                : int  1 2 3 4 5 6 7 8 9 10 ...
    ##  $ PurchaseDate     : chr  "18/12/2007" "20/12/2007" "21/12/2007" "21/12/2007" ...
    ##  $ CustomerID       : int  7223 7841 8374 9619 1900 6696 9673 354 1293 7938 ...
    ##  $ Gender           : chr  "F" "M" "F" "M" ...
    ##  $ MaritalStatus    : chr  "S" "M" "M" "M" ...
    ##  $ Homeowner        : chr  "Y" "Y" "N" "Y" ...
    ##  $ Children         : int  2 5 2 3 3 3 2 2 3 1 ...
    ##  $ AnnualIncome     : chr  "$30K - $50K" "$70K - $90K" "$50K - $70K" "$30K - $50K" ...
    ##  $ City             : chr  "Los Angeles" "Los Angeles" "Bremerton" "Portland" ...
    ##  $ StateorProvince  : chr  "CA" "CA" "WA" "OR" ...
    ##  $ Country          : chr  "USA" "USA" "USA" "USA" ...
    ##  $ ProductFamily    : chr  "Food" "Food" "Food" "Food" ...
    ##  $ ProductDepartment: chr  "Snack Foods" "Produce" "Snack Foods" "Snacks" ...
    ##  $ ProductCategory  : chr  "Snack Foods" "Vegetables" "Snack Foods" "Candy" ...
    ##  $ UnitsSold        : int  5 5 3 4 4 3 4 6 1 2 ...
    ##  $ Revenue          : chr  "27.38" "14.9" "5.52" "4.44" ...
    # Hiển thị vài dòng đầu
    head(supermarket)
    ##   X PurchaseDate CustomerID Gender MaritalStatus Homeowner Children
    ## 1 1   18/12/2007       7223      F             S         Y        2
    ## 2 2   20/12/2007       7841      M             M         Y        5
    ## 3 3   21/12/2007       8374      F             M         N        2
    ## 4 4   21/12/2007       9619      M             M         Y        3
    ## 5 5   22/12/2007       1900      F             S         Y        3
    ## 6 6   22/12/2007       6696      F             M         Y        3
    ##    AnnualIncome          City StateorProvince Country ProductFamily
    ## 1   $30K - $50K   Los Angeles              CA     USA          Food
    ## 2   $70K - $90K   Los Angeles              CA     USA          Food
    ## 3   $50K - $70K     Bremerton              WA     USA          Food
    ## 4   $30K - $50K      Portland              OR     USA          Food
    ## 5 $130K - $150K Beverly Hills              CA     USA         Drink
    ## 6   $10K - $30K Beverly Hills              CA     USA          Food
    ##   ProductDepartment      ProductCategory UnitsSold Revenue
    ## 1       Snack Foods          Snack Foods         5   27.38
    ## 2           Produce           Vegetables         5    14.9
    ## 3       Snack Foods          Snack Foods         3    5.52
    ## 4            Snacks                Candy         4    4.44
    ## 5         Beverages Carbonated Beverages         4      14
    ## 6              Deli          Side Dishes         3    4.37

    Tập dữ liệu “Supermarket Transactions” gồm tổng cộng 14.059 dòng dữ liệu, tương ứng với 14.059 giao dịch mua hàng được ghi nhận tại siêu thị. Mỗi dòng dữ liệu đại diện cho một giao dịch riêng lẻ và bao gồm thông tin chi tiết về khách hàng, sản phẩm, cũng như các đặc điểm liên quan đến hành vi tiêu dùng. Bộ dữ liệu này có tổng cộng 16 biến (cột), bao gồm cả biến định tính và định lượng, phản ánh đầy đủ các yếu tố nhân khẩu học, địa lý và kết quả kinh doanh từ mỗi giao dịch.

    2.2. Tổng quan dữ liệu

    # Tạo bảng mô tả các biến
    variable_summary <- data.frame(
      Variable = names(supermarket),  # cột tên biến
      DataType = sapply(supermarket, class),  # kiểu dữ liệu trong R
      UniqueValues = sapply(supermarket, function(x) length(unique(x))),
      MissingValues = sapply(supermarket, function(x) sum(is.na(x)))
    )
    
    # Gán loại biến theo kiểu định tính / định lượng
    variable_summary$VariableType <- ifelse(variable_summary$DataType %in% c("numeric", "integer"),
                                            "Định lượng", "Định tính")
    
    # In ra bảng gọn gàng
    print(variable_summary)
    ##                            Variable  DataType UniqueValues MissingValues
    ## X                                 X   integer        14059             0
    ## PurchaseDate           PurchaseDate character          742             0
    ## CustomerID               CustomerID   integer         5404             0
    ## Gender                       Gender character            2             0
    ## MaritalStatus         MaritalStatus character            2             0
    ## Homeowner                 Homeowner character            2             0
    ## Children                   Children   integer            6             0
    ## AnnualIncome           AnnualIncome character            8             0
    ## City                           City character           23             0
    ## StateorProvince     StateorProvince character           10             0
    ## Country                     Country character            3             0
    ## ProductFamily         ProductFamily character            3             0
    ## ProductDepartment ProductDepartment character           22             0
    ## ProductCategory     ProductCategory character           45             0
    ## UnitsSold                 UnitsSold   integer            8             0
    ## Revenue                     Revenue character         2846             0
    ##                   VariableType
    ## X                   Định lượng
    ## PurchaseDate         Định tính
    ## CustomerID          Định lượng
    ## Gender               Định tính
    ## MaritalStatus        Định tính
    ## Homeowner            Định tính
    ## Children            Định lượng
    ## AnnualIncome         Định tính
    ## City                 Định tính
    ## StateorProvince      Định tính
    ## Country              Định tính
    ## ProductFamily        Định tính
    ## ProductDepartment    Định tính
    ## ProductCategory      Định tính
    ## UnitsSold           Định lượng
    ## Revenue              Định tính
    install.packages("knitr")
    ## Warning: package 'knitr' is in use and will not be installed
    library(knitr)
    kable(variable_summary, caption = "Bảng mô tả các biến trong bộ dữ liệu Supermarket Transactions")
    Bảng mô tả các biến trong bộ dữ liệu Supermarket Transactions
    Variable DataType UniqueValues MissingValues VariableType
    X X integer 14059 0 Định lượng
    PurchaseDate PurchaseDate character 742 0 Định tính
    CustomerID CustomerID integer 5404 0 Định lượng
    Gender Gender character 2 0 Định tính
    MaritalStatus MaritalStatus character 2 0 Định tính
    Homeowner Homeowner character 2 0 Định tính
    Children Children integer 6 0 Định lượng
    AnnualIncome AnnualIncome character 8 0 Định tính
    City City character 23 0 Định tính
    StateorProvince StateorProvince character 10 0 Định tính
    Country Country character 3 0 Định tính
    ProductFamily ProductFamily character 3 0 Định tính
    ProductDepartment ProductDepartment character 22 0 Định tính
    ProductCategory ProductCategory character 45 0 Định tính
    UnitsSold UnitsSold integer 8 0 Định lượng
    Revenue Revenue character 2846 0 Định tính

    Dữ liệu được thu thập từ nhiều khách hàng khác nhau và chứa đa dạng các biến thuộc cả hai loại: biến định tính và biến định lượng.

    Cụ thể, các biến định tính bao gồm:

  • Giới tính (Gender),
  • Tình trạng hôn nhân (MaritalStatus),
  • Tình trạng sở hữu nhà (Homeowner),
  • Thu nhập hàng năm (AnnualIncome) — được mã hóa dưới dạng các khoảng thu nhập,
  • và các biến liên quan đến sản phẩm và địa lý như Thành phố (City), Tỉnh/Bang (StateOrProvince), Quốc gia (Country), Danh mục sản phẩm (ProductCategory),…
  • Các biến định lượng bao gồm:

  • Số con (Children) – cho biết số lượng con của khách hàng,
  • Mã khách hàng (CustomerID) – dùng để nhận dạng cá nhân,
  • Số lượng sản phẩm đã bán (UnitsSold),
  • và Doanh thu (Revenue) – thể hiện giá trị tiền tệ thu được từ mỗi giao dịch.
  • 2.3.Thống kê mô tả biến số

    2.3.1. Biến định tính

    library(knitr)
    library(kableExtra)
    
    # Tạo bảng dữ liệu với tên cột tiếng Việt, có check.names = FALSE để cho phép
    
    bien_dinh_tinh <- data.frame(
      "Tên biến" = c(
        "Gender", 
        "MaritalStatus", 
        "Homeowner", 
        "AnnualIncome",
        "City / StateorProvince / Country",
        "ProductFamily / ProductDepartment / ProductCategory"
      ),
      "Kiểu dữ liệu" = rep("Chuỗi ký tự", 6),
      "Số giá trị khác nhau" = c(2, 2, 2, 8, "Nhiều", "Nhiều"),
      "Nhận xét" = c(
        "Biến phân loại đơn giản gồm 2 giá trị: Nam và Nữ. Có thể dùng để phân tích hành vi theo giới.",
        "Gồm 'Single' và 'Married', phản ánh tình trạng hôn nhân. Có thể ảnh hưởng đến mức chi tiêu.",
        "Cho biết khách hàng có sở hữu nhà hay không, có thể liên quan đến thu nhập và chi tiêu.",
        "Là biến phân loại theo bậc thu nhập (ví dụ: '$25K-$50K'). Có thể chuyển thành bậc thang số để phân tích.",
        "Phân loại địa lý, phù hợp để phân tích theo khu vực, vùng miền.",
        "Phân loại sản phẩm — rất quan trọng trong phân tích doanh thu và xu hướng tiêu dùng."
      ),
      check.names = FALSE
    )
    
    # In bảng đẹp
    kable(bien_dinh_tinh, "html", align = "lccc", caption = "Bảng mô tả các biến định tính") %>%
      kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover", "condensed")) %>%
      column_spec(4, width = "30em", extra_css = "text-align: justify;")
    Bảng mô tả các biến định tính
    Tên biến Kiểu dữ liệu Số giá trị khác nhau Nhận xét
    Gender Chuỗi ký tự 2 Biến phân loại đơn giản gồm 2 giá trị: Nam và Nữ. Có thể dùng để phân tích hành vi theo giới.
    MaritalStatus Chuỗi ký tự 2 Gồm ‘Single’ và ‘Married’, phản ánh tình trạng hôn nhân. Có thể ảnh hưởng đến mức chi tiêu.
    Homeowner Chuỗi ký tự 2 Cho biết khách hàng có sở hữu nhà hay không, có thể liên quan đến thu nhập và chi tiêu.
    AnnualIncome Chuỗi ký tự 8 Là biến phân loại theo bậc thu nhập (ví dụ: ‘$25K-$50K’). Có thể chuyển thành bậc thang số để phân tích.
    City / StateorProvince / Country Chuỗi ký tự Nhiều Phân loại địa lý, phù hợp để phân tích theo khu vực, vùng miền.
    ProductFamily / ProductDepartment / ProductCategory Chuỗi ký tự Nhiều Phân loại sản phẩm — rất quan trọng trong phân tích doanh thu và xu hướng tiêu dùng.

    2.3.2 Biến định lượng

    library(knitr)
    library(kableExtra)
    
    # === 2. BẢNG BIẾN ĐỊNH LƯỢNG ===
    bien_dinh_luong <- data.frame(
      "Tên biến" = c( "Children", "UnitsSold", "Revenue"),
      "Kiểu dữ liệu" = c( "Số nguyên", "Số thực", "Số thực"),
      "Số giá trị khác nhau" = c( 6, "Nhiều", "Nhiều"),
      "Nhận xét" = c(
        "Số lượng con của khách hàng, có thể phân tích mối quan hệ với chi tiêu.",
        "Phản ánh số lượng sản phẩm được bán trong từng giao dịch.",
        "Biến mục tiêu chính thể hiện doanh thu – phù hợp để phân tích hiệu quả kinh doanh."
      ),
      check.names = FALSE  # Giữ nguyên tiêu đề cột
    )
    
    # In bảng
    kable(bien_dinh_luong, "html", align = "lccc", caption = "Bảng 2. Mô tả các biến định lượng") %>%
      kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover", "condensed")) %>%
      column_spec(4, width = "30em", extra_css = "text-align: justify;")
    Bảng 2. Mô tả các biến định lượng
    Tên biến Kiểu dữ liệu Số giá trị khác nhau Nhận xét
    Children Số nguyên 6 Số lượng con của khách hàng, có thể phân tích mối quan hệ với chi tiêu.
    UnitsSold Số thực Nhiều Phản ánh số lượng sản phẩm được bán trong từng giao dịch.
    Revenue Số thực Nhiều Biến mục tiêu chính thể hiện doanh thu – phù hợp để phân tích hiệu quả kinh doanh.

    2.4.Thống kê mô tả biến định tính

    2.4.1. Gender(Giới tính)

    # Tạo bảng tần suất
    gender_counts <- table(supermarket$Gender)
    print(gender_counts )
    ## 
    ##    F    M 
    ## 7170 6889
    # Tính phần trăm
    gender_percent <- round(prop.table(gender_counts) * 100, 1)
    
    # Gán nhãn với phần trăm
    labels <- paste(names(gender_counts), " (", gender_percent, "%)", sep="")
    
    # Vẽ biểu đồ tròn
    pie(gender_counts,
        labels = labels,
        col = c("#ff9999","#66b3ff"),
        main = "Tỷ lệ giới tính khách hàng")

    Biểu đồ tròn cho thấy cơ cấu giới tính khách hàng tại siêu thị tương đối đồng đều:

    • Nữ có 7.170 người, chiếm khoảng 51.0% tổng số khách hàng.

    • Nam có 6.889 người, chiếm khoảng 49.0% tổng số khách hàng.

    Tỷ lệ giới tính giữa nam và nữ khá cân bằng, không có sự chênh lệch lớn. Điều này cho thấy siêu thị thu hút được khách hàng ở cả hai giới với mức độ tương đương. Việc trình bày bằng biểu đồ tròn với màu sắc phân biệt và gán nhãn phần trăm rõ ràng giúp người xem dễ dàng nhận diện và so sánh thị phần của từng nhóm giới tính.

    2.4.2. MaritalStatus (Tình trạng hôn nhân)

    # Tạo bảng tần suất tình trạng hôn nhân
    marital_counts <- table(supermarket$MaritalStatus)
    print(marital_counts)
    ## 
    ##    M    S 
    ## 6866 7193
    # Tính phần trăm
    marital_percent <- round(prop.table(marital_counts) * 100, 1)
    
    # Gán nhãn với phần trăm
    labels <- paste(names(marital_counts), " (", marital_percent, "%)", sep="")
    
    # Vẽ biểu đồ tròn
    pie(marital_counts,
        labels = labels,
        col = c("#FF0000", "#00FF00"),
        main = "Tình trạng hôn nhân của khách hàng")

    Biểu đồ tròn thể hiện cơ cấu tình trạng hôn nhân của khách hàng tại siêu thị. Cụ thể:

    • Khách hàng độc thân (Single) có 7.193 người, chiếm khoảng 51.2%.

    • Khách hàng đã kết hôn (Married) có 6.866 người, chiếm khoảng 48.8%.

    Tỷ lệ giữa hai nhóm khách hàng là khá cân bằng, tuy nhiên nhóm độc thân có phần chiếm ưu thế nhẹ. Điều này cho thấy siêu thị thu hút được sự quan tâm của cả hai nhóm khách hàng, nhưng có thể cân nhắc thêm các chiến lược tiếp cận riêng biệt cho từng nhóm để tối ưu hiệu quả marketing.

    2.4.3. Homeowner (Tình trạng sở hữu nhà ở)

    # Tạo bảng tần suất theo tình trạng sở hữu nhà ở
    homeowner_counts <- table(supermarket$Homeowner)
    print(homeowner_counts)
    ## 
    ##    N    Y 
    ## 5615 8444
    # Tính phần trăm
    homeowner_percent <- round(prop.table(homeowner_counts) * 100, 1)
    
    # Gán nhãn với phần trăm
    labels <- paste(names(homeowner_counts), " (", homeowner_percent, "%)", sep="")
    
    # Vẽ biểu đồ tròn
    pie(homeowner_counts,
        labels = labels,
        col = c("#C0C0C0", "#ffcc99"),  # Yes - No
        main = "Tình trạng sở hữu nhà ở của khách hàng")

    Biểu đồ tròn thể hiện tình trạng sở hữu nhà ở của khách hàng tại siêu thị. Cụ thể:

    • Khách hàng có sở hữu nhà (Yes): 8.444 người, chiếm khoảng 60.0%

    • Khách hàng không sở hữu nhà (No): 5.615 người, chiếm khoảng 40.0%

    Kết quả cho thấy phần lớn khách hàng là người có sở hữu nhà, chiếm tỷ lệ cao hơn đáng kể so với nhóm không sở hữu. Điều này phản ánh đặc điểm nhân khẩu học ổn định về kinh tế – xã hội của phần lớn khách hàng tại siêu thị.

    2.4.4. AnnualIncome (Phân bố thu nhập hằng năm)

    # Tạo bảng tần suất
    income_counts <- table(supermarket$AnnualIncome)
    print(income_counts)
    ## 
    ##   $10K - $30K $110K - $130K $130K - $150K       $150K +   $30K - $50K 
    ##          3090           643           760           273          4601 
    ##   $50K - $70K   $70K - $90K  $90K - $110K 
    ##          2370          1709           613
    # Tăng margin dưới (tham số thứ 1, 2, 3, 4) – 4 là dưới
    par(mar = c(8, 4, 4, 2) + 0.1)  
    
    # Lưu vị trí các cột
    bar_pos <- barplot(income_counts,
                       col = c("#C0C0C0","#808080","#800000","#808000","#008000","#800080","#008080","#000080"),
                       main = "Phân bố thu nhập hàng năm của khách hàng",
                       xlab = "Nhóm thu nhập",
                       ylab = "Số lượng khách hàng",
                       names.arg = FALSE,  # Không hiển thị nhãn mặc định
                       border = NA)
    
    # Vẽ lại nhãn trục X ở vị trí thấp hơn
    text(x = bar_pos,
         y = -max(income_counts)*0.05,  # Dời xuống thấp hơn gốc toạ độ
         labels = names(income_counts),
         srt = 45,              # Xoay nhãn 45 độ
         adj = 1,               # Căn phải
         xpd = TRUE,            # Cho phép vẽ ra ngoài plot
         cex = 0.8)             # Cỡ chữ

    Dựa trên dữ liệu từ cột AnnualIncome, ta có thể thấy khách hàng được chia thành 8 nhóm thu nhập, từ dưới 30K đến trên 150K, với số lượng cụ thể như sau:

    • Nhóm chiếm tỷ lệ cao nhất là 30K - 50K với 4.601 khách hàng, tương đương khoảng 29.9% tổng số.

    • Nhóm thu nhập từ 10K - 30K cũng có tỷ lệ rất cao, 3.090 người (~20.1%).

    Phần lớn khách hàng (khoảng 50%) thuộc hai nhóm thu nhập từ 10K đến 50K, trong đó nhóm 30K - 50K chiếm tỷ lệ cao nhất, gần 1/3 tổng số khách hàng. Điều này cho thấy siêu thị đang thu hút chủ yếu là những người có mức thu nhập trung bình - thấp, có thể là người lao động, công nhân, sinh viên hoặc các hộ gia đình có ngân sách chi tiêu hạn chế.

    • Nhóm thu nhập từ 50K - 70K có tỷ lệ khá cao với 2,370 người chiếm tỉ lệ 15%.

    • Nhóm thu nhập từ 70K - 90K có 1,709 (~11%)

    Các nhóm từ 50K - 90K có số lượng khách hàng trung bình, chiếm khoảng 26% tổng số khách hàng. Đây có thể là nhóm nhân viên văn phòng, hộ gia đình trẻ có thu nhập ổn định.

    Ngược lại, các nhóm thu nhập cao như:

    • 150K+ chỉ có 273 người (~1.8%),

    • 130K - $150K có 760 người (~4.9%),

    • 110K - $130K có 643 người (~4.2%),

    Nhóm thu nhập từ 90K trở lên chiếm tỷ lệ khá nhỏ, chỉ khoảng 15% tổng khách hàng, trong đó nhóm cao nhất là 150K+ chỉ có 273 người, tương đương chưa đến 2%. Điều này phản ánh rằng khách hàng có thu nhập cao không phải là đối tượng chính của siêu thị.

    2.4.5. Country (Phân bố theo quốc gia)

    # Tạo bảng tần suất
    country_counts <- table(supermarket$Country)
    print(country_counts)
    ## 
    ## Canada Mexico    USA 
    ##    809   3688   9562
    # Tạo nhãn có phần trăm
    percent_labels <- round(100 * country_counts / sum(country_counts), 1)
    labels_with_pct <- paste(names(country_counts), "\n", percent_labels, "%")
    
    # Vẽ biểu đồ tròn
    pie(country_counts,
        labels = labels_with_pct,
        col = c("#FF9999", "#99CCFF", "#99FF99"),  # Màu cho từng country
        main = "Tỉ lệ khách hàng theo quốc gia")

    USA chiếm tỷ trọng áp đảo: Với hơn 63% tổng số khách hàng, thị trường Mỹ rõ ràng là trọng tâm chính của doanh nghiệp.

    Mexico là thị trường tiềm năng thứ hai: Với khoảng 30% khách hàng, đây là một thị trường đáng chú ý, có thể đang trong giai đoạn phát triển tốt.

    Canada có số lượng khách hàng thấp nhất: Chỉ chiếm khoảng 6.6%, có thể là do dân số thấp hơn, thói quen tiêu dùng khác, hoặc mức độ thâm nhập thị trường chưa cao.

    2.4.6. StateorProvince (Phân bố theo tiểu bang)

    # Tạo bảng tần suất theo StateorProvince
    state_counts <- table(supermarket$StateorProvince)
    print(state_counts)
    ## 
    ##        BC        CA        DF  Guerrero   Jalisco        OR  Veracruz        WA 
    ##       809      2733       815       383        75      2262       464      4567 
    ##   Yucatan Zacatecas 
    ##       654      1297
    # Sắp xếp giảm dần để đẹp hơn
    state_counts <- sort(state_counts, decreasing = TRUE)
    
    # Vẽ biểu đồ cột ngang
    barplot(state_counts,
            horiz = TRUE,
            las = 1,  # Xoay nhãn trục Y cho dễ đọc
            col = "#8da0cb",
            main = "Số lượng khách hàng theo State/Province",
            xlab = "Số lượng khách hàng",
            border = NA)

    Biểu đồ số lượng khách hàng cho thấy:

    • WA (Washington) là bang có số lượng khách hàng lớn nhất, chiếm đến 32.5%, cho thấy đây là thị trường trọng điểm.

    • Hai bang khác của Mỹ là CA (California) và OR (Oregon) cũng có lượng khách hàng rất cao (19.4% và 16.1%), khẳng định Mỹ là khu vực chủ lực về khách hàng.

    • Các tỉnh thành của Mexico như Zacatecas (9.2%), DF (5.8%), và Yucatan (4.6%) có sự hiện diện đáng kể.

    • Jalisco có số lượng khách hàng thấp nhất chỉ 0.5%, có thể cân nhắc lại việc tiếp cận hoặc đầu tư ở khu vực này.

    • Riêng Canada (BC) chiếm 5.8%, cho thấy sự hiện diện vừa phải, không quá nổi bật.

    2.4.7. City (Phân bố theo thành phố)

    # Tạo bảng tần suất theo thành phố
    city_counts <- sort(table(supermarket$City), decreasing = TRUE)
    print(city_counts)
    ## 
    ##         Salem        Tacoma   Los Angeles       Seattle      Portland 
    ##          1386          1257           926           922           876 
    ##       Spokane     San Diego       Hidalgo     Bremerton Beverly Hills 
    ##           875           866           845           834           811 
    ##        Merida     Vancouver    San Andres       Orizaba       Camacho 
    ##           654           633           621           464           452 
    ##      Acapulco        Yakima   Mexico City      Victoria   Walla Walla 
    ##           383           376           194           176           160 
    ##    Bellingham San Francisco   Guadalajara 
    ##           143           130            75
    # Tăng lề trái để chứa nhãn
    par(mar = c(4, 10, 4, 2) + 0.1)
    
    # Vẽ biểu đồ cột ngang
    barplot(city_counts,
            horiz = TRUE,
            las = 1,  # Xoay nhãn trục Y để dễ đọc
            col = "skyblue",
            main = "Số lượng khách hàng theo Thành phố",
            xlab = "Số lượng khách hàng",
            border = NA)

    Biểu đồ cho thấy phân bố khách hàng không đều: một vài thành phố chiếm phần lớn khách hàng, còn nhiều thành phố khác thì lượng khách thấp, thể hiện tập trung khách hàng vào một số thị trường chính.

    • Salem nổi bật nhất với cột cao hơn hẳn, chứng tỏ đây là thành phố có lượng khách hàng đông nhất.

    • Các thành phố lớn như Los Angeles, Portland, Spokane, San Diego cũng có cột cao, thể hiện thị trường khá mạnh.

    • Ở phía giữa biểu đồ, các thành phố như Merida, Vancouver, San Andres có số lượng khách trung bình, cột thấp hơn nhưng vẫn đáng kể.

    • Ở đầu biểu đồ, các thành phố như Guadalajara, Bellingham có cột thấp, nghĩa là lượng khách hàng ít, chiếm phần nhỏ trong tổng số.

    2.4.8. Product family (Phân loại sản phẩm gia đình)

    # Tạo bảng tần suất ProductFamily
    product_family_counts <- table(supermarket$ProductFamily)
    print(product_family_counts)
    ## 
    ##          Drink           Food Non-Consumable 
    ##           1250          10153           2656
    # Vẽ biểu đồ tròn
    pie(product_family_counts,
        main = "Phân bố theo ProductFamily",
        col = rainbow(length(product_family_counts)),
        cex = 0.8)
    
    # Thêm chú thích ngoài biểu đồ
    legend("topright", legend = names(product_family_counts), fill = rainbow(length(product_family_counts)), cex=0.7)

    Phân bố theo nhóm sản phẩm (ProductFamily):

    • Food (Thực phẩm) là nhóm lớn nhất với 10,153 sản phẩm, chiếm khoảng 70% tổng số. Đây là nhóm chủ đạo trong dữ liệu, cho thấy khách hàng mua nhiều nhất các sản phẩm thực phẩm.

    • Drink (Đồ uống) chiếm khoảng 8.6% với 1,250 sản phẩm. Đây cũng là một nhóm quan trọng nhưng nhỏ hơn nhiều so với thực phẩm.

    • Non-Consumable (Sản phẩm không tiêu thụ trực tiếp) có 2,656 sản phẩm, chiếm khoảng 18.4%. Nhóm này có thể gồm các vật dụng, dụng cụ hoặc sản phẩm dùng lâu dài, không phải tiêu thụ ngay.

    2.4.9. ProductDepartment (Phân loại sản phẩm cung cấp)

    library(dplyr)
    ## Warning: package 'dplyr' was built under R version 4.3.3
    ## 
    ## Attaching package: 'dplyr'
    ## The following object is masked from 'package:kableExtra':
    ## 
    ##     group_rows
    ## The following objects are masked from 'package:stats':
    ## 
    ##     filter, lag
    ## The following objects are masked from 'package:base':
    ## 
    ##     intersect, setdiff, setequal, union
    product_dept_counts <- table(supermarket$ProductDepartment)
    
    df_dept <- as.data.frame(product_dept_counts)
    colnames(df_dept) <- c("ProductDepartment", "Count")
    
    df_dept <- df_dept %>%
      mutate(Percent = round(Count / sum(Count) * 100, 2)) %>%
      arrange(desc(Count))
    
    print(df_dept)
    ##      ProductDepartment Count Percent
    ## 1              Produce  1994   14.18
    ## 2          Snack Foods  1600   11.38
    ## 3            Household  1420   10.10
    ## 4         Frozen Foods  1382    9.83
    ## 5         Baking Goods  1072    7.63
    ## 6         Canned Foods   977    6.95
    ## 7                Dairy   903    6.42
    ## 8   Health and Hygiene   893    6.35
    ## 9                 Deli   699    4.97
    ## 10           Beverages   680    4.84
    ## 11         Baked Goods   425    3.02
    ## 12 Alcoholic Beverages   356    2.53
    ## 13              Snacks   352    2.50
    ## 14       Starchy Foods   277    1.97
    ## 15         Periodicals   202    1.44
    ## 16                Eggs   198    1.41
    ## 17     Breakfast Foods   188    1.34
    ## 18     Canned Products   109    0.78
    ## 19             Seafood   102    0.73
    ## 20                Meat    89    0.63
    ## 21            Checkout    82    0.58
    ## 22            Carousel    59    0.42

    Bảng số liệu cho thấy:

    • Produce (1994), Snack Foods (1600), Household (1420) và Frozen Foods (1382) là các nhóm sản phẩm có số lượng lớn nhất, chiếm phần lớn trong tổng số sản phẩm. Đây có thể là nhóm khách hàng mua nhiều hoặc nhóm hàng chủ lực.

    • Các nhóm như Baking Goods (1072), Canned Foods (977), Dairy (903), và Health and Hygiene (893) cũng có số lượng khá cao, cho thấy nhu cầu đa dạng.

    • Một số nhóm như Carousel (59), Checkout (82), Meat (89), và Seafood (102) có số lượng thấp hơn, có thể là nhóm sản phẩm chuyên biệt hoặc ít phổ biến hơn.

    • Các nhóm còn lại nằm ở mức trung bình, phản ánh sự phân bố khá đa dạng trong các mặt hàng của siêu thị.

    2.4.10. ProductCategory (Phân loại danh mục sản phẩm)

    library(dplyr)
    
    # Tạo bảng tần suất đếm số lượng theo ProductCategory
    product_cat_counts <- supermarket %>%
      group_by(ProductCategory) %>%
      summarise(Count = n()) %>%
      arrange(desc(Count)) %>%
      mutate(Percentage = round(Count / sum(Count) * 100, 2))
    
    # In bảng kết quả
    print(product_cat_counts)
    ## # A tibble: 45 × 3
    ##    ProductCategory  Count Percentage
    ##    <chr>            <int>      <dbl>
    ##  1 Vegetables        1728      12.3 
    ##  2 Snack Foods       1600      11.4 
    ##  3 Dairy              903       6.42
    ##  4 Fruit              765       5.44
    ##  5 Meat               761       5.41
    ##  6 Jams and Jellies   588       4.18
    ##  7 Baking Goods       484       3.44
    ##  8 Bread              425       3.02
    ##  9 Breakfast Foods    417       2.97
    ## 10 Canned Soup        404       2.87
    ## # ℹ 35 more rows

    Khách hàng tập trung nhiều vào các nhóm thực phẩm tươi sống, đông lạnh, đồ ăn nhẹ, và các sản phẩm gia dụng. Các nhóm nhỏ hơn có thể là các mặt hàng đặc thù hoặc ít phổ biến hơn.

    Nhóm có số lượng cao nhất:

    • Produce (1994) — tức các loại rau củ quả tươi, rất được ưa chuộng.

    • Frozen Foods (1382) và Household (1420) cũng khá cao, cho thấy nhu cầu dùng thực phẩm đông lạnh và hàng gia dụng lớn.

    • Snack Foods (1600) và Baking Goods (1072) cũng nổi bật, phản ánh thị trường ăn vặt và làm bánh phát triển.

    Nhóm có số lượng thấp nhất:

    • Carousel (59), Checkout (82), Meat (89) có số lượng ít hơn, có thể do đặc thù sản phẩm hoặc cách phân loại.

    • Baking Goods thấp hơn nhiều nhóm, nhưng vẫn tương đối.

    2.5. Thống kê mô tả biến định lượng

    2.5.1. Children (Số con trong gia đình)

    children_counts <- table(supermarket$Children)
    children_counts
    ## 
    ##    0    1    2    3    4    5 
    ## 1344 2718 2839 2893 2826 1439
    children_percent <- prop.table(children_counts) * 100
    round(children_percent, 1)  # làm tròn 1 chữ số thập phân
    ## 
    ##    0    1    2    3    4    5 
    ##  9.6 19.3 20.2 20.6 20.1 10.2
    barplot(children_counts,
            main = "Số lượng con trong gia đình khách hàng",
            xlab = "Số con",
            ylab = "Số lượng gia đình",
            col = "skyblue")

    Biểu đồ thể hiện:

    • Gia đình không có con chiếm 1,344 hộ chiếm khoảng 8% tổng số (tôi sẽ tính % cụ thể bên dưới).

    • Các gia đình có từ 1 đến 4 con chiếm đa số (chiếm khoảng 80% tổng), và tỷ lệ phân bố khá đồng đều giữa các nhóm này, mỗi nhóm chiếm khoảng 16%-17%.

    • Gia đình có 5 con trở lên giảm còn 1,439 hộ khoảng 9%.

    2.5.2. UnitsSold (Sản phẩm bán ra)

    units_sold_counts <- table(supermarket$UnitsSold)
    print(units_sold_counts)
    ## 
    ##    1    2    3    4    5    6    7    8 
    ##   90 1130 3289 4379 3562 1439  168    2
    summary(supermarket$UnitsSold)
    ##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    ##   1.000   3.000   4.000   4.081   5.000   8.000
    sd(supermarket$UnitsSold)
    ## [1] 1.174421
    units_counts <- table(supermarket$UnitsSold)
    
    bar_positions <- barplot(
      units_counts,
      main = "Phân bố số lượng sản phẩm bán theo UnitsSold",
      xlab = "Số lượng sản phẩm bán (UnitsSold)",
      ylab = "Số lầ",
      col = "steelblue",
      border = "black"
    )
    
    # Thêm nhãn số lên trên mỗi cột
    text(
      x = bar_positions,
      y = units_counts,
      labels = units_counts,
      pos = 3,            # Vị trí trên đầu cột
      cex = 0.8,          # Kích cỡ chữ
      col = "black"
    )

    Phần lớn khách hàng trong dữ liệu chọn mua từ 3 đến 5 sản phẩm trong mỗi đơn hàng, thể hiện xu hướng mua hàng vừa phải, không quá ít cũng không quá nhiều. Mức mua cực thấp (1 sản phẩm) hoặc rất cao (7-8 sản phẩm) chỉ chiếm phần nhỏ trong tổng số đơn hàng.

    • Số lượng bán nhiều nhất rơi vào nhóm 4 sản phẩm, với 4379 đơn vị, chiếm tỷ trọng lớn nhất trong tổng phân bố.

    • Nhóm 3 và 5 sản phẩm cũng rất phổ biến, lần lượt có 3289 và 3562 đơn vị, chỉ thấp hơn nhóm 4 chút.

    • Nhóm 2 sản phẩm cũng có số lượng khá lớn, 1130 đơn vị.

    • Số lượng bán ở các nhóm nhỏ (1 sản phẩm) và nhóm lớn (7, 8 sản phẩm) rất ít, đặc biệt nhóm 8 chỉ có 2 đơn vị.

    2.5.3. Revenue (Doanh thu)

    # Chuyển Revenue sang numeric
    supermarket$Revenue <- as.numeric(supermarket$Revenue)
    
    # Nếu có NA do chuyển không thành công (ví dụ có ký tự lạ), loại bỏ NA khi tính
    revenue_clean <- na.omit(supermarket$Revenue)
    
    # Tính các thống kê
    summary(revenue_clean)
    ##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    ##    0.53    6.84   11.25   13.00   17.37   56.70
    sd(revenue_clean)
    ## [1] 8.215543
    min(revenue_clean)
    ## [1] 0.53
    max(revenue_clean)
    ## [1] 56.7
    median(revenue_clean)
    ## [1] 11.25
    mean(revenue_clean)
    ## [1] 13.00451
    • Min = 0.53: Có khách mua rất ít tiền, chỉ khoảng 53 cent (ví dụ mua món nhỏ, bánh kẹo).

    • Median = 11.25: Phần lớn giao dịch có giá trị khoảng 11.25 đô la (giá trị trung bình của một lần mua hàng).

    • Mean = 13.00: Trung bình mỗi lần mua là 13 đô la, có nghĩa có những giao dịch lớn hơn mức trung vị làm tăng trung bình.

    • Max = 56.7: Có những giao dịch mua khá lớn, có thể mua nhiều món hoặc hàng cao cấp.

    LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSB0deG6p24gMSINCmF1dGhvcjogIkh14buzbmggTmfhu41jIERp4buHcC0yMjIxMDAwMjk1Ig0KZGF0ZTogIjIwMjUtMDUtMTciDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICB0b2M6IHRydWUNCiAgcGRmX2RvY3VtZW50Og0KICAgIGxhdGV4X2VuZ2luZTogeGVsYXRleA0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KYGBgDQoNCjxzdHlsZT4NCmJvZHkgew0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIHNhbnMtc2VyaWY7DQogIGZvbnQtc2l6ZTogMTZweDsNCiAgdGV4dC1hbGlnbjoganVzdGlmeTsNCiAgbGluZS1oZWlnaHQ6IDEuNTsNCn0NCmgxIHsNCiAgY29sb3I6IHJlZDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCn0NCmgyIHsNCiAgY29sb3I6IGJsYWNrOw0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCmgzIHsNCiAgY29sb3I6IGJsYWNrOw0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCmg0IHsNCiAgY29sb3I6IGJsYWNrOw0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCjwvc3R5bGU+DQoNCiMgMS4gVMOTTSBU4bquVCBO4buYSSBEVU5HIFPDgUNIDQoNCuKAnEdlbmVyYWxpemVkIExpbmVhciBNb2RlbHMgd2l0aCBFeGFtcGxlcyBpbiBS4oCdIGzDoCBt4buZdCBjdeG7kW4gc8OhY2ggY2h1ecOqbiBzw6J1IHbhu4EgbcO0IGjDrG5oIHR1eeG6v24gdMOtbmggdOG7lW5nIHF1w6F0IChHTE1zKSwgxJHGsOG7o2Mgdmnhur90IGLhu59pIGhhaSBjaHV5w6puIGdpYSB0aOG7kW5nIGvDqiBsw6AgUGV0ZXIgSy4gRHVubiB2w6AgR29yZG9uIEsuIFNteXRoLiBN4bulYyB0acOqdSBjaMOtbmggY+G7p2EgY3Xhu5FuIHPDoWNoIGzDoCBr4bq/dCBo4bujcCBjaOG6t3QgY2jhur0gZ2nhu69hIGzDvSB0aHV54bq/dCB2w6AgdGjhu7FjIGjDoG5oLCBnacO6cCBuZ8aw4budaSBo4buNYyB2w6AgbmfGsOG7nWkgbMOgbSBuZ2hpw6puIGPhu6l1IGhp4buDdSByw7UgY+G6pXUgdHLDumMsIHBoxrDGoW5nIHBow6FwIMaw4bubYyBsxrDhu6NuZywga2nhu4NtIMSR4buLbmggdsOgIOG7qW5nIGThu6VuZyBj4bunYSBHTE1zLCDEkeG7k25nIHRo4budaSB0aMOgbmggdGjhuqFvIHPhu60gZOG7pW5nIHBo4bqnbiBt4buBbSBSIMSR4buDIHRo4buxYyBoaeG7h24gY8OhYyBwaMOibiB0w61jaCB0aOG7kW5nIGvDqiB0aOG7sWMgdOG6vy4NCg0KDQojIyBDaMawxqFuZyAxOiBTdGF0aXN0aWNhbCBNb2RlbHMgDQoNCkNoxrDGoW5nIDEgZ2nhu5tpIHRoaeG7h3UgY8OhYyBraMOhaSBuaeG7h20gbuG7gW4gdOG6o25nIHbhu4EgbcO0IGjDrG5oIHRo4buRbmcga8OqLCBsw6AgY8ahIHPhu58gxJHhu4MgaGnhu4N1IMSRxrDhu6NjIG3DtCBow6xuaCB0dXnhur9uIHTDrW5oIHbDoCBtw7QgaMOsbmggdHV54bq/biB0w61uaCB04buVbmcgcXXDoXQgKEdMTXMpLiBN4bulYyDEkcOtY2ggbMOgIMSR4buDIGhp4buDdSByw7UgY8OhY2ggbcO0IGjDrG5oIGjDs2EgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBjw6FjIGJp4bq/biBz4buRIHRyb25nIG3hu5l0IHThuq1wIGThu68gbGnhu4d1Lg0KDQojIyMgMS4xLiBLaMOhaSBuaeG7h20gbcO0IGjDrG5oIHRo4buRbmcga8OqDQo8dWw+DQo8bGk+IE3hu5l0IG3DtCBow6xuaCB0aOG7kW5nIGvDqiBtw7QgdOG6oyBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGJp4bq/biBwaOG6o24gaOG7k2kgKHJlc3BvbnNlIHZhcmlhYmxlLCB0aMaw4budbmcga8O9IGhp4buHdSBsw6AgDQoqeSopIHbDoCBt4buZdCBoYXkgbmhp4buBdSBiaeG6v24gZ2nhuqNpIHRow61jaCAoY292YXJpYXRlcy9wcmVkaWN0b3JzKS48L2xpPg0KPGxpPiBNw7QgaMOsbmggZ+G7k20gaGFpIHBo4bqnbjoNCjx1bD4NCg0KPGxpPlRow6BuaCBwaOG6p24gaOG7hyB0aOG7kW5nIChzeXN0ZW1hdGljIGNvbXBvbmVudCk6IG3DtCB04bqjIOG6o25oIGjGsOG7n25nIGPhu6dhIGPDoWMgYmnhur9uIGdp4bqjaSB0aMOtY2guPC9saT4NCg0KPGxpPlRow6BuaCBwaOG6p24gbmfhuqt1IG5oacOqbiAocmFuZG9tIGNvbXBvbmVudCk6IG3DtCB04bqjIHPhu7EgYmnhur9uIHRoacOqbiBraMO0bmcgZ2nhuqNpIHRow61jaCDEkcaw4bujYyAoc2FpIHPhu5EpLjwvbGk+DQo8L3VsPg0KPC9saT4NCjwvaWw+DQo8L3VsPg0KIyMjIDEuMi4gVGjDoG5oIHBo4bqnbiBo4buHIHRo4buRbmcgdsOgIHRow6BuaCBwaOG6p24gbmfhuqt1IG5oacOqbg0KKipUaMOgbmggcGjhuqduIGjhu4cgdGjhu5FuZyAoU3lzdGVtYXRpYyBDb21wb25lbnQpICoqDQoNCkzDoCBwaOG6p24gY8OzIHRo4buDIGdp4bqjaSB0aMOtY2ggxJHGsOG7o2MgY+G7p2EgbcO0IGjDrG5oLCB0aOG7gyBoaeG7h24gbeG7kWkgcXVhbiBo4buHIHR1eeG6v24gdMOtbmggaG/hurdjIHBoaSB0dXnhur9uIGdp4buvYSBiaeG6v24gcGjhu6UgdGh14buZYyB2w6AgY8OhYyBiaeG6v24gZ2nhuqNpIHRow61jaCAoY292YXJpYXRlcykuDQoNCsSQxrDhu6NjIGJp4buDdSBkaeG7hW4gdGjDtG5nIHF1YSBt4buZdCBow6BtIHR1eeG6v24gdMOtbmggY+G7p2EgY8OhYyBiaeG6v24gZ2nhuqNpIHRow61jaCwgdsOtIGThu6U6DQoNCiQkXGV0YV9pID0gXGJldGFfMCArIFxiZXRhXzEgeF97MWl9ICsgXGRvdHMgKyBcYmV0YV9wIHhfe3BpfSQkDQpUcm9uZyDEkcOzOiAkXGV0YV9pJCBsw6AgZ2nDoSB0cuG7iyBj4bunYSBow6BtIGxpw6puIGvhur90IHThuqFpIHF1YW4gc8OhdCB0aOG7qSAqaSoNCg0KKipUaMOgbmggcGjhuqduIG5n4bqrdSBuaGnDqm4gKFJhbmRvbSBDb21wb25lbnQpKioNCg0KTMOgIHBo4bqnbiBraMO0bmcgZ2nhuqNpIHRow61jaCDEkcaw4bujYyBj4bunYSBtw7QgaMOsbmgg4oCTIHRo4buDIGhp4buHbiBz4buxIGJp4bq/biB0aGnDqm4gdOG7sSBuaGnDqm4sIG5oaeG7hXUgxJFvIGzGsOG7nW5nIGhv4bq3YyBjw6FjIHnhur91IHThu5Ega2jDtG5nIHF1YW4gc8OhdCDEkcaw4bujYy4NCg0KxJDGsOG7o2MgbcO0IHThuqMgYuG6sW5nIG3hu5l0IHBow6JuIHBo4buRaSB4w6FjIHN14bqldCBwaMO5IGjhu6NwIHbhu5tpIGxv4bqhaSBk4buvIGxp4buHdToNCjx1bD4NCjxsaT4gSOG7k2kgcXV5IHR1eeG6v24gdMOtbmg6ICRcdmFyZXBzaWxvbl9pIFxzaW0gTigwLCBcc2lnbWFeMikkPC9saT4NCjxsaT4gR0xNczogJHlfaSQgdHXDom4gdGhlbyBt4buZdCBwaMOibiBwaOG7kWkgdHJvbmcgaOG7jSBleHBvbmVudGlhbCBmYW1pbHkgKG5oxrAgTmjhu4sgcGjDom4sIFBvaXNzb24sIEdhbW1hLCB2LnYuKTwvbGk+DQo8L3VsPg0KUGjhuqNuIMOhbmggcuG6sW5nIG5nYXkgY+G6oyBraGkgY8OhYyBiaeG6v24gZ2nhuqNpIHRow61jaCBnaeG7kW5nIG5oYXUsIGvhur90IHF14bqjIMSR4bqndSByYSB24bqrbiBjw7MgdGjhu4Mga2jDoWMgZG8geeG6v3UgdOG7kSBuZ+G6q3Ugbmhpw6puLg0KDQojIyMgMS4zLiBNw7QgaMOsbmggaOG7k2kgcXV5DQo8dWw+DQo8bGk+IEjhu5NpIHF1eSDEkcahbjo8L2xpPg0KJCQNCnlfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfaSArIFx2YXJlcHNpbG9uX2kNCiQkDQo8bGk+IEjhu5NpIHF1eSDEkWEgYmnhur9uIDwvbGk+DQokJA0KeV9pID0gXGJldGFfMCArIFxiZXRhXzEgeF97MWl9ICsgXGJldGFfMiB4X3syaX0gKyBcY2RvdHMgKyBcYmV0YV9wIHhfe3BpfSArIFx2YXJlcHNpbG9uX2kNCiQkDQo8dWw+DQpUcm9uZyDEkcOzOg0KPGxpPiR5X2kkOiBnacOhIHRy4buLIHF1YW4gc8OhdCBj4bunYSBiaeG6v24gcGjhu6UgdGh14buZYzwvbGk+DQo8bGk+JHhfe2ppfSQ6IGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uKmoqIGdp4bqjaSB0aMOtY2ggdGjhu6kgKmkqPC9saT4NCjxsaT4gJFxiZXRhXzAkOiBo4buHIHPhu5EgY2jhurduIDwvbGk+DQo8bGk+JFxiZXRhX2okOiBo4buHIHPhu5EgaOG7k2kgcXV5PC9saT4NCjxsaT4kXHZhcmVwc2lsb25faSQ6c2FpIHPhu5Egbmfhuqt1IG5oacOqbjwvbGk+DQo8L3VsPg0KPGxpPiDDnSBuZ2jEqWEgY8OhYyBo4buHIHPhu5E6DQoNCjx1bD4NCjxsaT4gJFxiZXRhXzAkOiBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhICp5KiBraGkgdOG6pXQgY+G6oyAkeF9qID0gMCQ8L2xpPg0KPGxpPiAkXGJldGFfaiQ6IHRoYXkgxJHhu5VpIHRydW5nIGLDrG5oIGPhu6dhICp5KiBraGkgJHhfaiQgdMSDbmcgMSDEkcahbiB24buLLCBraGkgY8OhYyBiaeG6v24ga2jDoWMga2jDtG5nIMSR4buVaTwvbGk+DQo8bGk+ICRcdmFyZXBzaWxvbiQ6IGJp4buDdSBkaeG7hW4gc+G7sSBuaGnhu4V1IGhv4bq3YyB54bq/dSB04buRIGNoxrBhIHF1YW4gc8OhdCDEkcaw4bujYywgxJHGsOG7o2MgZ2nhuqMgxJHhu4tuaCBjw7MgdHJ1bmcgYsOsbmggYuG6sW5nIDAuPC9saT4NCg0KIyMgQ2jGsMahbmcgMjogTGluZWFyIFJlZ3Jlc3Npb24gTW9kZWxzDQoNCkNoxrDGoW5nIG7DoHkgZ2nhu5tpIHRoaeG7h3UgbcO0IGjDrG5oIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oIG7Ds2kgcmnDqm5nIHbDoCBjw6FjIG3DtCBow6xuaCBo4buTaSBxdXkgdHV54bq/biB0w61uaCB04buVbmcgcXXDoXQgbsOzaSBjaHVuZy4gTuG7mWkgZHVuZyBiYW8gZ+G7k206IMSR4buLbmggbmdoxKlhLCBnaeG6oyDEkeG7i25oIGPGoSBi4bqjbiwgxrDhu5tjIGzGsOG7o25nIGLDrG5oIHBoxrDGoW5nIHThu5FpIHRoaeG7g3UsIHPhu60gZOG7pW5nIFIgxJHhu4MgeMOieSBk4buxbmcgdsOgIGRp4buFbiBnaeG6o2kgbcO0IGjDrG5oLCBjw7luZyB24bubaSBjw6FjIHBoxrDGoW5nIHBow6FwIHN1eSBsdeG6rW4sIHBow6JuIHTDrWNoIHBoxrDGoW5nIHNhaSB2w6Agc28gc8OhbmggbcO0IGjDrG5oLg0KDQojIyMgMi4xLiBHaeG7m2kgdGhp4buHdSBtw7QgaMOsbmggaOG7k2kgcXV5IHR1eeG6v24gdMOtbmgNCg0KTcO0IGjDrG5oIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oIGzDoCBt4buZdCBwaMawxqFuZyBwaMOhcCB0aOG7kW5nIGvDqiBkw7luZyDEkeG7gyBtw7QgaMOsbmggaMOzYSBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIG3hu5l0IGJp4bq/biBwaOG7pSB0aHXhu5ljIChwaOG6o24gaOG7k2kpIHbDoCBt4buZdCBob+G6t2Mgbmhp4buBdSBiaeG6v24gxJHhu5ljIGzhuq1wIChnaeG6o2kgdGjDrWNoKS4NCg0KIyMjIDIuMi4gxJDhu4tuaCBuZ2jEqWENCg0KTcO0IGjDrG5oIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oIHThu5VuZyBxdcOhdDoNCiQkDQp5X2kgPSBcYmV0YV8wICsgXGJldGFfMSB4X3sxaX0gKyBcYmV0YV8yIHhfezJpfSArIFxjZG90cyArIFxiZXRhX3AgeF97cGl9ICsgXHZhcmVwc2lsb25faQ0KJCQNClRyb25nIMSRw7M6DQo8bGk+JHlfaSQ6IGdpw6EgdHLhu4sgcXVhbiBzw6F0IGPhu6dhIGJp4bq/biBwaOG7pSB0aHXhu5ljPC9saT4NCjxsaT4keF97aml9JDogZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24qaiogZ2nhuqNpIHRow61jaCB0aOG7qSAqaSo8L2xpPg0KPGxpPiAkXGJldGFfMCQ6IGjhu4cgc+G7kSBjaOG6t24gPC9saT4NCjxsaT4kXGJldGFfaiQ6IGjhu4cgc+G7kSBo4buTaSBxdXk8L2xpPg0KPGxpPiRcdmFyZXBzaWxvbl9pJDpzYWkgc+G7kSBuZ+G6q3Ugbmhpw6puPC9saT4NCg0KIyMjIDIuMy4gSOG7k2kgcXV5IMSRxqFuDQojIyMjIDIuMy4xLiDGr+G7m2MgbMaw4bujbmcgYsOsbmggcGjGsMahbmcgdOG7kWkgdGhp4buDdSAoTGVhc3QtU3F1YXJlcyBFc3RpbWF0aW9uKQ0KTcO0IGjDrG5oIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oIMSRxqFuIMSRxrDhu6NjIGJp4buDdSBkaeG7hW4gYuG6sW5nOg0KJCQNCnlfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfaSArIFx2YXJlcHNpbG9uX2kNCiQkDQpUcm9uZyDEkcOzDQotIFwoIHlfaSBcKTogZ2nDoSB0cuG7iyBxdWFuIHPDoXQgY+G7p2EgYmnhur9uIHBo4bulIHRodeG7mWMgdOG6oWkgxJFp4buDbSBcKCBpIFwpICANCi0gXCggeF9pIFwpOiBnacOhIHRy4buLIHF1YW4gc8OhdCBj4bunYSBiaeG6v24gxJHhu5ljIGzhuq1wIHThuqFpIMSRaeG7g20gXCggaSBcKSAgDQotIFwoIFxiZXRhXzAgXCk6IGjhu4cgc+G7kSBjaOG6t24gKGludGVyY2VwdCkgIA0KLSBcKCBcYmV0YV8xIFwpOiBo4buHIHPhu5EgZ8OzYyAoc2xvcGUpICANCi0gXCggXHZhcmVwc2lsb25faSBcKTogc2FpIHPhu5Egbmfhuqt1IG5oacOqbiwgduG7m2kgZ2nhuqMgxJHhu4tuaDogJFx2YXJlcHNpbG9uX2kgXHNpbSBcbWF0aGNhbHtOfSgwLCBcc2lnbWFeMikkDQoNCkPDoWMgaOG7hyBz4buRIFwoIFxiZXRhXzAgXCkgdsOgIFwoIFxiZXRhXzEgXCkgxJHGsOG7o2MgxrDhu5tjIGzGsOG7o25nIGLhurFuZyBjw6FjaCB04buRaSB0aGnhu4N1IGjDs2EgdOG7lW5nIGLDrG5oIHBoxrDGoW5nIHNhaSBz4buRIChTU0UpOg0KDQokJA0KU1NFID0gXHN1bV97aT0xfV57bn0gKHlfaSAtIFxoYXR7eX1faSleMg0KJCQNCg0KVHJvbmcgxJHDszogJFxoYXR7eX1faSA9IFxoYXR7XGJldGF9XzAgKyBcaGF0e1xiZXRhfV8xIHhfaSQgbMOgIGdpw6EgdHLhu4sgZOG7sSDEkW/DoW4gY+G7p2EgXCggeV9pIFwpLg0KDQojIyMjIDIuMy4yIENvZWZmaWNpZW50IEVzdGltYXRlcw0KDQpDw6FjIMaw4bubYyBsxrDhu6NuZyBjaG8gXCggXGJldGFfMSBcKSB2w6AgXCggXGJldGFfMCBcKSDEkcaw4bujYyB0w61uaCBuaMawIHNhdToNCg0KJCQNClxoYXR7XGJldGF9XzEgPSBcZnJhY3sgXHN1bV97aT0xfV57bn0gKHhfaSAtIFxiYXJ7eH0pKHlfaSAtIFxiYXJ7eX0pIH17IFxzdW1fe2k9MX1ee259ICh4X2kgLSBcYmFye3h9KV4yIH0NCiQkDQoNCiQkDQpcaGF0e1xiZXRhfV8wID0gXGJhcnt5fSAtIFxoYXR7XGJldGF9XzEgXGJhcnt4fQ0KJCQNCg0KVHJvbmcgxJHDszoNCg0KXCggXGJhcnt4fSBcKTogZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBiaeG6v24gXCggeCBcKSAgDQpcKCBcYmFye3l9IFwpOiBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGJp4bq/biBcKCB5IFwpDQoNCiMjIyMgMi4zLjMgRXN0aW1hdGluZyB0aGUgVmFyaWFuY2UgXCggXHNpZ21hXjIgXCkNCg0Kxq/hu5tjIGzGsOG7o25nIGtow7RuZyBjaOG7h2NoIGPhu6dhIHBoxrDGoW5nIHNhaSBzYWkgc+G7kSBcKCBcc2lnbWFeMiBcKSDEkcaw4bujYyB0w61uaCBi4bqxbmc6DQoNCiQkDQpcaGF0e1xzaWdtYX1eMiA9IFxmcmFjezF9e24gLSAyfSBcc3VtX3tpPTF9XntufSAoeV9pIC0gXGhhdHt5fV9pKV4yDQokJA0KDQpUcm9uZyDEkcOzOg0KDQpcKCB5X2kgXCk6IGdpw6EgdHLhu4sgcXVhbiBzw6F0IGPhu6dhIGJp4bq/biBwaOG7pSB0aHXhu5ljICANClwoIFxoYXR7eX1faSBcKTogZ2nDoSB0cuG7iyBk4buxIMSRb8OhbiB04burIG3DtCBow6xuaCBo4buTaSBxdXkgIA0KXCggbiBcKTogc+G7kSBsxrDhu6NuZyBxdWFuIHPDoXQgIA0KXCggXGhhdHtcc2lnbWF9XjIgXCk6IHBoxrDGoW5nIHNhaSBzYWkgc+G7kSDGsOG7m2MgbMaw4bujbmcgIA0KTeG6q3Ugc+G7kSBcKCBuIC0gMiBcKSBsw6AgZG8gxJHDoyDGsOG7m2MgbMaw4bujbmcgMiB0aGFtIHPhu5EgXCggXGhhdHtcYmV0YX1fMCBcKSB2w6AgXCggXGhhdHtcYmV0YX1fMSBcKQ0KDQojIyMjIDIuMy40IFN0YW5kYXJkIEVycm9ycyBvZiB0aGUgQ29lZmZpY2llbnRzDQoNClNhaSBz4buRIGNodeG6qW4gKFN0YW5kYXJkIEVycm9yIC0gU0UpIGPhu6dhIGPDoWMgaOG7hyBz4buRIGjhu5NpIHF1eSDEkcaw4bujYyB0w61uaCBuaMawIHNhdToNCjx1bD4NCg0KPGxpPlNhaSBz4buRIGNodeG6qW4gY+G7p2EgXCggXGhhdHtcYmV0YX1fMSBcKTo8L2xpPg0KDQokJA0KU0UoXGhhdHtcYmV0YX1fMSkgPSBcc3FydHsgXGZyYWN7IFxoYXR7XHNpZ21hfV4yIH17IFxzdW1fe2k9MX1ee259ICh4X2kgLSBcYmFye3h9KV4yIH0gfQ0KJCQNCg0KPGxpPlNhaSBz4buRIGNodeG6qW4gY+G7p2EgXCggXGhhdHtcYmV0YX1fMCBcKTo8L2xpPg0KDQokJA0KU0UoXGhhdHtcYmV0YX1fMCkgPSBcc3FydHsgXGhhdHtcc2lnbWF9XjIgXGxlZnQoIFxmcmFjezF9e259ICsgXGZyYWN7IFxiYXJ7eH1eMiB9eyBcc3VtX3tpPTF9XntufSAoeF9pIC0gXGJhcnt4fSleMiB9IFxyaWdodCkgfQ0KJCQNCg0KVHJvbmcgxJHDszoNCjx1bD4NCjxsaT5cKCBcaGF0e1xzaWdtYX1eMiBcKTogcGjGsMahbmcgc2FpIHNhaSBz4buRIMaw4bubYyBsxrDhu6NuZyA8L2xpPiANCjxsaT5cKCBcYmFye3h9IFwpOiBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGJp4bq/biBcKCB4IFwpICAgPC9saT4gDQo8bGk+XCggbiBcKTogc+G7kSBsxrDhu6NuZyBxdWFuIHPDoXQgIFwoIFNFKFxoYXR7XGJldGF9X2opIFwpOiBzYWkgc+G7kSBjaHXhuqluIGPhu6dhIGjhu4cgc+G7kSBcKCBcaGF0e1xiZXRhfV9qIFwpIDwvbGk+IDwvdWw+DQoNClNhaSBz4buRIGNodeG6qW4gY2hvIGJp4bq/dCBt4bupYyDEkeG7mSBraMO0bmcgY2jhuq9jIGNo4bqvbiB0cm9uZyDGsOG7m2MgbMaw4bujbmcgY8OhYyBo4buHIHPhu5EgaOG7k2kgcXV5LCB2w6AgbMOgIGPGoSBz4bufIMSR4buDIHTDrW5oIGtob+G6o25nIHRpbiBj4bqteSB2w6Aga2nhu4NtIMSR4buLbmggZ2nhuqMgdGh1eeG6v3QuDQoNCiMjIyMgMi4zLjUuIFN0YW5kYXJkIEVycm9ycyBvZiBGaXR0ZWQgVmFsdWVzDQoNClNhaSBz4buRIGNodeG6qW4gKFN0YW5kYXJkIEVycm9yKSBj4bunYSBnacOhIHRy4buLIGThu7EgxJFvw6FuIFwoIFxoYXR7eX1fZyBcKSB04bqhaSDEkWnhu4NtIFwoIHhfZyBcKSDEkcaw4bujYyB0w61uaCBuaMawIHNhdToNCg0KJCQNClNFKFxoYXR7XG11fV9nKV4yID0gXGhhdHtcc2lnbWF9XjIgXGxlZnQoIHdfaSBcbGVmdFsgXGZyYWN7MX17bn0gKyBcZnJhY3soeF9nIC0gXGJhcnt4fSleMn17U1NfeH0gXHJpZ2h0XSBccmlnaHQpDQokJA0KDQpUcm9uZyDEkcOzOg0KDQpcKCBcaGF0e1xtdX1fZyA9IFxoYXR7XGJldGF9XzAgKyBcaGF0e1xiZXRhfV8xIHhfZyBcKTogbMOgIGdpw6EgdHLhu4sgZOG7sSDEkW/DoW4gdOG6oWkgxJFp4buDbSBcKCB4X2cgXCkNCg0KXCggXGhhdHtcc2lnbWF9XjIgXCk6IHBoxrDGoW5nIHNhaSBzYWkgc+G7kSDGsOG7m2MgbMaw4bujbmcNCg0KXCggd19pIFwpOiB0cuG7jW5nIHPhu5EgY2hvIHF1YW4gc8OhdCBcKCBpIFwpIChu4bq/dSBjw7MsIG7hur91IGtow7RuZyB0aMOsIG3hurdjIMSR4buLbmggbMOgIDEpDQoNClwoIFxiYXJ7eH0gXCk6IGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgYmnhur9uIFwoIHhfaSBcKQ0KDQpcKCBTU194ID0gXHN1bSAoeF9pIC0gXGJhcnt4fSleMiBcKTogdOG7lW5nIGLDrG5oIHBoxrDGoW5nIHNhaSBs4buHY2ggY+G7p2EgY8OhYyBnacOhIHRy4buLIFwoIHhfaSBcKSBzbyB24bubaSB0cnVuZyBiw6xuaA0KDQoNCiMjIyAyLjQuIEjhu5NpIHF1eSDEkWEgYmnhur9uDQoNCiMjIyMgMi40LjEgQ29lZmZpY2llbnQgRXN0aW1hdGVzDQoNCk3DtCBow6xuaCBo4buTaSBxdXkgdHV54bq/biB0w61uaCBi4buZaSAobXVsdGlwbGUgbGluZWFyIHJlZ3Jlc3Npb24pIGPDsyBk4bqhbmc6DQokJA0KeV9pID0gXGJldGFfMCArIFxiZXRhXzEgeF97aTF9ICsgXGJldGFfMiB4X3tpMn0gKyBcY2RvdHMgKyBcYmV0YV9wIHhfe2lwfSArIFx2YXJlcHNpbG9uX2kNCiQkDQpWaeG6v3QgZ+G7jW4gYuG6sW5nIGvDvSBoaeG7h3UgbWEgdHLhuq1uOg0KJCQNClxtYXRoYmZ7eX0gPSBcbWF0aGJme1h9IFxib2xkc3ltYm9se1xiZXRhfSArIFxib2xkc3ltYm9se1x2YXJlcHNpbG9ufQ0KJCQNClRyb25nIMSRw7M6DQoNClwoIFxtYXRoYmZ7eX0gXCk6IHZlY3RvciBcKCBuIFx0aW1lcyAxIFwpIGNo4bupYSBjw6FjIGdpw6EgdHLhu4sgcXVhbiBzw6F0IGPhu6dhIGJp4bq/biBwaOG7pSB0aHXhu5ljICANClwoIFxtYXRoYmZ7WH0gXCk6IG1hIHRy4bqtbiB0aGnhur90IGvhur8gXCggbiBcdGltZXMgKHAgKyAxKSBcKSwgdHJvbmcgxJHDsyBj4buZdCDEkeG6p3UgdGnDqm4gbMOgIHRvw6BuIDEgKHTGsMahbmcg4bupbmcgduG7m2kgaOG7hyBz4buRIGNo4bq3biBcKCBcYmV0YV8wIFwpKSAgDQpcKCBcYm9sZHN5bWJvbHtcYmV0YX0gXCk6IHZlY3RvciBcKCAocCArIDEpIFx0aW1lcyAxIFwpIGNo4bupYSBjw6FjIGjhu4cgc+G7kSBo4buTaSBxdXkgIA0KXCggXGJvbGRzeW1ib2x7XHZhcmVwc2lsb259IFwpOiB2ZWN0b3IgXCggbiBcdGltZXMgMSBcKSBjaOG7qWEgc2FpIHPhu5Egbmfhuqt1IG5oacOqbiwgduG7m2kgZ2nhuqMgxJHhu4tuaCBcKCBcdmFyZXBzaWxvbl9pIFxzaW0gXG1hdGhjYWx7Tn0oMCwgXHNpZ21hXjIpIFwpDQoNCioqxq/hu5tjIGzGsOG7o25nIGLDrG5oIHBoxrDGoW5nIHThu5FpIHRoaeG7g3UgKE9MUyBlc3RpbWF0b3IpIGNobyBcKCBcYm9sZHN5bWJvbHtcYmV0YX0gXCk6KioNCiQkDQpcaGF0e1xib2xkc3ltYm9se1xiZXRhfX0gPSAoXG1hdGhiZntYfV5cdG9wIFxtYXRoYmZ7WH0pXnstMX0gXG1hdGhiZntYfV5cdG9wIFxtYXRoYmZ7eX0NCiQkDQoNCiMjIyMgMi40LjIgRXN0aW1hdGluZyB0aGUgVmFyaWFuY2UgXCggXHNpZ21hXjIgXCkNCg0KKipQaOG6p24gZMawIChyZXNpZHVhbCkgdOG6oWkgcXVhbiBzw6F0IFwoIGkgXCk6KioNCg0KJCQNCmVfaSA9IHlfaSAtIFxoYXR7eX1faQ0KJCQNCg0KKipU4buVbmcgYsOsbmggcGjGsMahbmcgcGjhuqduIGTGsCAoUlNTIC0gUmVzaWR1YWwgU3VtIG9mIFNxdWFyZXMpOioqDQoNCiQkDQpSU1MgPSBcc3VtX3tpPTF9XntufSAoeV9pIC0gXGhhdHt5fV9pKV4yID0gXHwgXG1hdGhiZnt5fSAtIFxoYXR7XG1hdGhiZnt5fX0gXHxeMg0KJCQNCg0KKirGr+G7m2MgbMaw4bujbmcga2jDtG5nIGNo4buHY2ggY+G7p2EgcGjGsMahbmcgc2FpIFwoIFxzaWdtYV4yIFwpOioqDQoNCiQkDQpcaGF0e1xzaWdtYX1eMiA9IFxmcmFje1JTU317biAtIHAgLSAxfQ0KJCQNClRyb25nIMSRw7M6DQoNCi0gXCggbiBcKTogc+G7kSBsxrDhu6NuZyBxdWFuIHPDoXQgIA0KLSBcKCBwIFwpOiBz4buRIGJp4bq/biDEkeG7mWMgbOG6rXAgKGtow7RuZyB0w61uaCBo4buHIHPhu5EgY2jhurduIFwoIFxiZXRhXzAgXCkpICANCi0gXCggcCArIDEgXCk6IHThu5VuZyBz4buRIHRoYW0gc+G7kSDEkcaw4bujYyDGsOG7m2MgbMaw4bujbmcgKGJhbyBn4buTbSBcKCBcYmV0YV8wIFwpKSAgDQotIFwoIG4gLSBwIC0gMSBcKTogc+G7kSBi4bqtYyB04buxIGRvIChkZWdyZWVzIG9mIGZyZWVkb20pDQoNCg0KIyMjIyAyLjQuMyBTdGFuZGFyZCBFcnJvcnMNCg0KKipQaMawxqFuZyBzYWkgY+G7p2EgdmVjdG9yIGjhu4cgc+G7kSDGsOG7m2MgbMaw4bujbmcgXCggXGhhdHtcYm9sZHN5bWJvbHtcYmV0YX19IFwpOioqDQoNCiQkDQpcbWF0aHJte1Zhcn0oXGhhdHtcYm9sZHN5bWJvbHtcYmV0YX19KSA9IFxoYXR7XHNpZ21hfV4yIChcbWF0aGJme1h9Xlx0b3AgXG1hdGhiZntYfSleey0xfQ0KJCQNCg0KKipTYWkgc+G7kSBjaHXhuqluIChTdGFuZGFyZCBFcnJvcikgY+G7p2EgdOG7q25nIGjhu4cgc+G7kSBo4buTaSBxdXk6KioNCg0KJCQNClNFKFxoYXR7XGJldGF9X2opID0gXHNxcnR7IFxoYXR7XHNpZ21hfV4yIFxjZG90IFxsZWZ0WyAoXG1hdGhiZntYfV5cdG9wIFxtYXRoYmZ7WH0pXnstMX0gXHJpZ2h0XV97amp9IH0NCiQkDQoNClRyb25nIMSRw7M6DQo8dWw+DQo8bGk+DQpcKCBcaGF0e1xzaWdtYX1eMiBcKTogxq/hu5tjIGzGsOG7o25nIGPhu6dhIHBoxrDGoW5nIHNhaSBzYWkgc+G7kSAgPC9saT4NCjxsaT5cKCBcbWF0aGJme1h9Xlx0b3AgXG1hdGhiZntYfSBcKTogTWEgdHLhuq1uIHTDrWNoIGdp4buvYSBtYSB0cuG6rW4gdGhp4bq/dCBr4bq/IFwoIFxtYXRoYmZ7WH0gXCkgdsOgIGNodXnhu4NuIHbhu4sgY+G7p2EgbsOzICA8L2xpPg0KPGxpPlwoIFxsZWZ0WyAoXG1hdGhiZntYfV5cdG9wIFxtYXRoYmZ7WH0pXnstMX0gXHJpZ2h0XV97amp9IFwpOiBQaOG6p24gdOG7rSBow6BuZyBcKCBqIFwpLCBj4buZdCBcKCBqIFwpIGPhu6dhIG1hIHRy4bqtbiBuZ2jhu4tjaCDEkeG6o288L2xpPiAgDQo8bGk+XCggU0UoXGhhdHtcYmV0YX1faikgXCk6IFNhaSBz4buRIGNodeG6qW4gY+G7p2EgaOG7hyBz4buRIGjhu5NpIHF1eSBcKCBcaGF0e1xiZXRhfV9qIFwpPC9saT4NCjwvdWw+DQoNCiMjIyAyLjUgRml0dGluZyBMaW5lYXIgUmVncmVzc2lvbiBNb2RlbHMgVXNpbmcgUg0KUGjhuqduIG7DoHkgaMaw4bubbmcgZOG6q24gY8OhY2ggc+G7rSBk4bulbmcgUiDEkeG7gyDGsOG7m2MgbMaw4bujbmcgbcO0IGjDrG5oIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oIGLhurFuZyBow6BtIGxtKCkuDQokJG1vZGVsIDwtIGxtKHkgfiB4MSArIHgyICsgLi4uLCBkYXRhID0gZGF0YXNldCkkJA0KeTogYmnhur9uIHBo4bulIHRodeG7mWMgKHJlc3BvbnNlIHZhcmlhYmxlKS4NCg0KeDEsIHgyLCAuLi46IGJp4bq/biDEkeG7mWMgbOG6rXAgKHByZWRpY3RvcnMpLg0KDQpkYXRhc2V0OiBi4buZIGThu68gbGnhu4d1IGNo4bupYSBjw6FjIGJp4bq/bi4NCg0KKipDw6FjIGjDoG0gcXVhbiB0cuG7jW5nIHRyb25nIHBow6JuIHTDrWNoIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oIHRyb25nIFIqKg0KDQpExrDhu5tpIMSRw6J5IGzDoCBjw6FjIGjDoG0gY8ahIGLhuqNuIHRoxrDhu51uZyBkw7luZyBraGkgbMOgbSB2aeG7h2MgduG7m2kgbcO0IGjDrG5oIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oIHRyb25nIFIgKHbDrSBk4bulIG3DtCBow6xuaCDEkcOjIMSRxrDhu6NjIGzGsHUgdHJvbmcgYmnhur9uIGBtb2RlbGAgc2F1IGtoaSBjaOG6oXkgYGxtKClgKToNCg0KLSBgc3VtbWFyeShtb2RlbClgICBpbiBr4bq/dCBxdeG6oyBjaGkgdGnhur90IGJhbyBn4buTbTogaOG7hyBz4buRIGjhu5NpIHF1eSwgc2FpIHPhu5EgY2h14bqpbiwgZ2nDoSB0cuG7iyB0aOG7kW5nIGvDqiB0LCBwLXZhbHVlcywgaOG7hyBz4buRIHjDoWMgxJHhu4tuaCBcKCBSXjIgXCksIHYudi4NCg0KLSBgY29lZihtb2RlbClgIHRy4bqjIHbhu4EgY8OhYyBo4buHIHPhu5EgxrDhu5tjIGzGsOG7o25nIFwoIFxoYXR7XGJldGF9XzAsIFxoYXR7XGJldGF9XzEsIFxkb3RzLCBcaGF0e1xiZXRhfV9wIFwpDQoNCi0gYGZpdHRlZChtb2RlbClgICB0cuG6oyB24buBIGdpw6EgdHLhu4sgZOG7sSDEkW/DoW4gXCggXGhhdHt5fV9pIFwpIHThu6sgbcO0IGjDrG5oLCB0aGVvIGPDtG5nIHRo4bupYzogICRcaGF0e3l9X2kgPSBcaGF0e1xiZXRhfV8wICsgXGhhdHtcYmV0YX1fMSB4X3tpMX0gKyBcaGF0e1xiZXRhfV8yIHhfe2kyfSArIFxjZG90cyArIFxoYXR7XGJldGF9X3AgeF97aXB9JA0KDQotIGByZXNpZHVhbHMobW9kZWwpYCAgdHLhuqMgduG7gSBwaOG6p24gZMawIChyZXNpZHVhbCkgXCggZV9pIFwpLCDEkcaw4bujYyB0w61uaCB0aGVvIGPDtG5nIHRo4bupYzokZV9pID0geV9pIC0gXGhhdHt5fV9pJA0KDQotIGBhbm92YShtb2RlbClgICB04bqhbyBi4bqjbmcgcGjDom4gdMOtY2ggcGjGsMahbmcgc2FpIChBTk9WQSB0YWJsZSkgY2hvIG3DtCBow6xuaCwgZ2nDunAga2nhu4NtIMSR4buLbmggdOG7lW5nIHRo4buDIMO9IG5naMSpYSBj4bunYSBtw7QgaMOsbmguDQoNCg0KDQojIyMgMi44IEluZmVyZW5jZSBmb3IgTGluZWFyIFJlZ3Jlc3Npb24gTW9kZWxzOiAqdCotVGVzdHMNCg0KTeG7pWMgbsOgeSB0csOsbmggYsOgeSBjw6FjIGLGsOG7m2Mgc3V5IGx14bqtbiB0aOG7kW5nIGvDqiDEkeG7kWkgduG7m2kgY8OhYyBo4buHIHPhu5EgaOG7k2kgcXV5IFwoIFxiZXRhX2ogXCkgdHJvbmcgbcO0IGjDrG5oIHR1eeG6v24gdMOtbmgsIHPhu60gZOG7pW5nIGtp4buDbSDEkeG7i25oICp0KiB2w6Aga2hv4bqjbmcgdGluIGPhuq15Lg0KDQojIyMjIDIuOC4xIE5vcm1hbCBMaW5lYXIgUmVncmVzc2lvbiBNb2RlbHMNCg0KR2nhuqMgxJHhu4tuaDogU2FpIHPhu5EgXCggXHZhcmVwc2lsb25faSBcKSBsw6AgxJHhu5ljIGzhuq1wIHbDoCB0dcOibiB0aGVvIHBow6JuIHBo4buRaSBjaHXhuqluOg0KICANCiAgJCQNCiAgXHZhcmVwc2lsb25faSBcc2ltIFxtYXRoY2Fse059KDAsIFxzaWdtYV4yKQ0KICAkJA0KDQpExrDhu5tpIGdp4bqjIMSR4buLbmggbsOgeSwgbcO0IGjDrG5oIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oIGPDsyBk4bqhbmc6DQoNCiQkDQp5X2kgPSBcYmV0YV8wICsgXGJldGFfMSB4X3tpMX0gKyBcY2RvdHMgKyBcYmV0YV9wIHhfe2lwfSArIFx2YXJlcHNpbG9uX2kNCiQkDQoNCiMjIyMgMi44LjIgVGhlIERpc3RyaWJ1dGlvbiBvZiBcKCBcaGF0e1xiZXRhfV9qIFwpDQoNClbhu5tpIGdp4bqjIMSR4buLbmggc2FpIHPhu5EgY2h14bqpbiwgxrDhu5tjIGzGsOG7o25nIFwoIFxoYXR7XGJldGF9X2ogXCkgY8OzIHBow6JuIHBo4buRaToNCg0KJCQNClxoYXR7XGJldGF9X2ogXHNpbSBcbWF0aGNhbHtOfSBcbGVmdCggXGJldGFfaixcIFxvcGVyYXRvcm5hbWV7VmFyfShcaGF0e1xiZXRhfV9qKSBccmlnaHQpDQokJA0KDQpLaGkgdGhheSB0aOG6vyBcKCBcc2lnbWFeMiBcKSBi4bqxbmcgxrDhu5tjIGzGsOG7o25nIFwoIHNeMiBcKSwgdGEgY8OzIHRo4buRbmcga8OqOg0KDQokJA0KdF9qID0gXGZyYWN7IFxoYXR7XGJldGF9X2ogLSBcYmV0YV9qIH17IFxvcGVyYXRvcm5hbWV7U0V9KFxoYXR7XGJldGF9X2opIH0gXHNpbSB0X3tuIC0gcH0NCiQkDQoNClRyb25nIMSRw7M6DQo8dWw+DQo8bGk+XCggbiBcKTogc+G7kSBxdWFuIHPDoXQgIDwvbGk+DQo8bGk+XCggcCBcKTogc+G7kSBo4buHIHPhu5EgdHJvbmcgbcO0IGjDrG5oIChiYW8gZ+G7k20gY+G6oyBo4buHIHPhu5EgY2jhurduIFwoIFxiZXRhXzAgXCkpPC9saT4NCjwvdWw+DQojIyMjIDIuOC4zIEh5cG90aGVzaXMgVGVzdHMgZm9yIFwoIFxiZXRhX2ogXCkNCg0KTeG7pWMgdGnDqnUga2nhu4NtIMSR4buLbmg6DQoNCiQkDQpIXzA6IFxiZXRhX2ogPSAwIFxxdWFkIFx0ZXh0e3ZzfSBccXVhZCBIXzE6IFxiZXRhX2ogXG5lcSAwDQokJA0KPHVsPg0KPGxpPlTDrW5oIGdpw6EgdHLhu4sgdGjhu5FuZyBrw6ogXCggdF9qIFwpIG5oxrAgdHLDqm48L2xpPg0KPGxpPlNvIHPDoW5oIHbhu5tpIHBow6JuIHBo4buRaSBTdHVkZW50IFwoIHRfe24gLSBwfSBcKSBob+G6t2MgdHJhICpwKi12YWx1ZSB0cm9uZyBSLjwvbGk+DQoNCg0KDQojIyMjIDIuOC40IENvbmZpZGVuY2UgSW50ZXJ2YWxzIGZvciBcKCBcYmV0YV9qIFwpDQoNCktob+G6o25nIHRpbiBj4bqteSAoQ0kpIDk1JSBjaG8gXCggXGJldGFfaiBcKToNCg0KJCQNClxoYXR7XGJldGF9X2ogXHBtIHRfe24gLSBwLFwgXGFscGhhLzJ9IFxjZG90IFxvcGVyYXRvcm5hbWV7U0V9KFxoYXR7XGJldGF9X2opDQokJA0KDQoNCiMjIyMgMi44LjUgQ29uZmlkZW5jZSBJbnRlcnZhbHMgZm9yIFwoIFxtdSA9IEUoWXx4KSBcKQ0KDQpHacOhIHRy4buLIGvhu7MgduG7jW5nIGPhu6dhIFwoIFkgXCkgdOG6oWkgXCggeCA9IHhfZyBcKToNCg0KJCQNClxtdV9nID0gRShZfHhfZykgPSB4X2deVCBcYmV0YQ0KJCQNCg0KS2hv4bqjbmcgdGluIGPhuq15IGNobyBcKCBcbXVfZyBcKToNCg0KJCQNClxoYXR7XG11fV9nIFxwbSB0X3tuIC0gcCxcIFxhbHBoYS8yfSBcY2RvdCBcb3BlcmF0b3JuYW1le1NFfShcaGF0e1xtdX1fZykNCiQkDQoNClRyb25nIMSRw7MgcGjGsMahbmcgc2FpIGPhu6dhIFwoIFxoYXR7XG11fV9nIFwpIGzDoDoNCg0KJCQNClxvcGVyYXRvcm5hbWV7VmFyfShcaGF0e1xtdX1fZykgPSBcc2lnbWFeMiB4X2deVCAoWF5UIFgpXnstMX0geF9nDQokJA0KDQojIyMgMi45IEFuYWx5c2lzIG9mIFZhcmlhbmNlIGZvciBSZWdyZXNzaW9uIE1vZGVscw0KDQpN4bulYyB0acOqdSBj4bunYSBwaOG6p24gbsOgeSBsw6AgcGjDom4gdMOtY2ggdOG7lW5nIHBoxrDGoW5nIHNhaSAoQU5PVkEpIG5o4bqxbSDEkcOhbmggZ2nDoSBt4bupYyDEkeG7mSBnaeG6o2kgdGjDrWNoIGJp4bq/biBwaOG7pSB0aHXhu5ljIGLhu59pIG3DtCBow6xuaCBo4buTaSBxdXkgdHV54bq/biB0w61uaC4NCg0KDQoqKlThu5VuZyBwaMawxqFuZyBzYWkqKg0KDQpU4buVbmcgcGjGsMahbmcgc2FpIGPhu6dhIGJp4bq/biBwaOG7pSB0aHXhu5ljIFwoIFkgXCkgxJHGsOG7o2MgY2hpYSB0aMOgbmg6DQoNCi0gUGjGsMahbmcgc2FpIGdp4bqjaSB0aMOtY2ggxJHGsOG7o2MgYuG7n2kgbcO0IGjDrG5oIChTU1Ig4oCTIFJlZ3Jlc3Npb24gU3VtIG9mIFNxdWFyZXMpDQotIFBoxrDGoW5nIHNhaSBjaMawYSBnaeG6o2kgdGjDrWNoIChSU1Mg4oCTIFJlc2lkdWFsIFN1bSBvZiBTcXVhcmVzKQ0KDQpDw7RuZyB0aOG7qWM6DQoNCiQkDQpcdGV4dHtTU1R9ID0gXHN1bV97aT0xfV57bn0gKHlfaSAtIFxiYXJ7eX0pXjIgPSBcdGV4dHtTU1J9ICsgXHRleHR7UlNTfQ0KJCQNCg0KVHJvbmcgxJHDszoNCg0KLSAqKlNTVCoqICgqVG90YWwgU3VtIG9mIFNxdWFyZXMqKTogVOG7lW5nIHBoxrDGoW5nIHNhaQ0KLSAqKlNTUioqICgqU3VtIG9mIFNxdWFyZXMgZm9yIFJlZ3Jlc3Npb24qKTogUGjGsMahbmcgc2FpIGdp4bqjaSB0aMOtY2ggYuG7n2kgbcO0IGjDrG5oDQotICoqUlNTKiogKCpSZXNpZHVhbCBTdW0gb2YgU3F1YXJlcyopOiBQaMawxqFuZyBzYWkgY+G7p2EgcGjhuqduIGTGsA0KDQoNCioqSOG7hyBz4buRIHjDoWMgxJHhu4tuaCBcKCBSXjIgXCkqKg0KDQokJA0KUl4yID0gXGZyYWN7XHRleHR7U1NSfX17XHRleHR7U1NUfX0gPSAxIC0gXGZyYWN7XHRleHR7UlNTfX17XHRleHR7U1NUfX0NCiQkDQoNCsOdIG5naMSpYToNCg0KLSBcKCBSXjIgXGluIFswLCAxXSBcKQ0KLSBcKCBSXjIgXCkgY8OgbmcgbOG7m24g4oaSIG3DtCBow6xuaCBjw6BuZyBnaeG6o2kgdGjDrWNoIHThu5F0IGJp4bq/biBwaOG7pSB0aHXhu5ljDQoNCg0KKipLaeG7g20gxJHhu4tuaCB04buVbmcgdGjhu4MgbcO0IGjDrG5oIChGLXRlc3QpKioNCg0KR2nhuqMgdGh1eeG6v3Q6DQoNCiQkDQpIXzA6IFxiZXRhXzEgPSBcYmV0YV8yID0gXGNkb3RzID0gXGJldGFfcCA9IDANCiQkDQoNCihuZ2jEqWEgbMOgIG3DtCBow6xuaCBraMO0bmcgZ2nhuqNpIHRow61jaCBnw6wgxJHGsOG7o2MgY2hvIGThu68gbGnhu4d1KQ0KDQoqKlRo4buRbmcga8OqIGtp4buDbSDEkeG7i25oOioqDQoNCiQkDQpGID0gXGZyYWN7XHRleHR7U1NSfSAvIHB9e1x0ZXh0e1JTU30gLyAobiAtIHAgLSAxKX0gPSBcZnJhY3tcdGV4dHtNU1J9fXtcdGV4dHtNU0V9fQ0KJCQNCg0KVHJvbmcgxJHDszoNCg0KLSBcKCBcdGV4dHtNU1J9ID0gXHRleHR7U1NSfSAvIHAgXCk6IHBoxrDGoW5nIHNhaSB0cnVuZyBiw6xuaCBj4bunYSBo4buTaSBxdXkNCi0gXCggXHRleHR7TVNFfSA9IFx0ZXh0e1JTU30gLyAobiAtIHAgLSAxKSBcKTogcGjGsMahbmcgc2FpIHRydW5nIGLDrG5oIHBo4bqnbiBkxrANCg0KKipQaMOibiBwaOG7kWkgY+G7p2EgXCggRiBcKToqKg0KDQokJA0KRiBcc2ltIEZfe3AsXCBuIC0gcCAtIDF9DQokJA0KDQotIE7hur91IGdpw6EgdHLhu4sgXCggRiBcKSBs4bubbiB2w6AgKnAqLXZhbHVlIG5o4buPIOKGkiBiw6FjIGLhu48gXCggSF8wIFwpDQotIEvhur90IGx14bqtbjogbcO0IGjDrG5oIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6oNCg0KKipSIHRyb25nIEFOT1ZBKioNCg0KVHJvbmcgUiwgc+G7rSBk4bulbmcgaMOgbTpgYW5vdmEobW9kZWwpYMSR4buDIGluIHJhIGLhuqNuZyBwaMOibiB0w61jaCBwaMawxqFuZyBzYWksIGJhbyBn4buTbToNCg0KLSBEZiAoZGVncmVlcyBvZiBmcmVlZG9tKQ0KLSBTdW0gU3EgKHThu5VuZyBiw6xuaCBwaMawxqFuZykNCi0gTWVhbiBTcSAodHJ1bmcgYsOsbmggYsOsbmggcGjGsMahbmcpDQotIEYgdmFsdWUNCi0gUHIoPkYpIOKAkyAqcCotdmFsdWUgY+G7p2Ega2nhu4NtIMSR4buLbmgNCg0KDQojIyMgMi4xMCBDb21wYXJpbmcgTmVzdGVkIE1vZGVscw0KDQpQaOG6p24gbsOgeSBnaeG7m2kgdGhp4buHdSBjw6FjaCAqKnNvIHPDoW5oIGhhaSBtw7QgaMOsbmggaOG7k2kgcXV5IGzhu5NuZyBuaGF1IChuZXN0ZWQgbW9kZWxzKSoqIMSR4buDIGtp4buDbSB0cmEgeGVtIG3DtCBow6xuaCDEkeG6p3kgxJHhu6cgKGZ1bGwgbW9kZWwpIGPDsyBj4bqjaSB0aGnhu4duIMSRw6FuZyBr4buDIHNvIHbhu5tpIG3DtCBow6xuaCByw7p0IGfhu41uIChyZWR1Y2VkIG1vZGVsKSBoYXkga2jDtG5nLg0KDQoNCiMjIyMgMi4xMC4xIEFuYWx5c2lzIG9mIFZhcmlhbmNlIHRvIENvbXBhcmUgVHdvIE5lc3RlZCBNb2RlbHMNCg0KKipLaMOhaSBuaeG7h206KioNCg0KLSBNw7QgaMOsbmggbmjhu48gaMahbiAocmVkdWNlZCBtb2RlbCkgbMOgIG3hu5l0IHRyxrDhu51uZyBo4bujcCDEkeG6t2MgYmnhu4d0IGPhu6dhIG3DtCBow6xuaCBs4bubbiBoxqFuIChmdWxsIG1vZGVsKSwgYuG6sW5nIGPDoWNoIGfDoW4gbeG7mXQgc+G7kSBo4buHIHPhu5EgYuG6sW5nIDAuDQotIFNvIHPDoW5oIGdp4buvYToNCiAgLSBNw7QgaMOsbmggXCggTV8wIFwpIHbhu5tpIFwoIHBfMCBcKSB0aGFtIHPhu5ENCiAgLSBNw7QgaMOsbmggXCggTV8xIFwpIHbhu5tpIFwoIHBfMSBcKSB0aGFtIHPhu5EsIHRyb25nIMSRw7MgXCggcF8xID4gcF8wIFwpDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmg6KioNCg0KJCQNCkhfMDogXHRleHR7Q8OhYyBo4buHIHPhu5EgdGjDqm0gdsOgbyBi4bqxbmcgMH0gXHF1YWQgXHRleHR7dnN9IFxxdWFkIEhfYTogXHRleHR7w410IG5o4bqldCBt4buZdCBo4buHIHPhu5EgdGjDqm0ga2jDoWMgMH0NCiQkDQoNCioqVGjhu5FuZyBrw6oga2nhu4NtIMSR4buLbmg6KioNCg0KJCQNCkYgPSBcZnJhY3soXHRleHR7UlNTfV8wIC0gXHRleHR7UlNTfV8xKS8ocF8xIC0gcF8wKX17XHRleHR7UlNTfV8xIC8gKG4gLSBwXzEpfQ0KJCQNCg0KVHJvbmcgxJHDszoNCg0KLSBcKCBcdGV4dHtSU1N9XzAgXCk6IHJlc2lkdWFsIHN1bSBvZiBzcXVhcmVzIGPhu6dhIG3DtCBow6xuaCBuaOG7jw0KLSBcKCBcdGV4dHtSU1N9XzEgXCk6IHJlc2lkdWFsIHN1bSBvZiBzcXVhcmVzIGPhu6dhIG3DtCBow6xuaCBs4bubbg0KLSBcKCBuIFwpOiBz4buRIHF1YW4gc8OhdA0KDQoqKkvhur90IGx14bqtbjoqKiBO4bq/dSBnacOhIHRy4buLIFwoIEYgXCkgbOG7m24g4oaSIG3DtCBow6xuaCDEkeG6p3kgxJHhu6cgY+G6o2kgdGhp4buHbiDEkcOhbmcga+G7gyDihpIgYsOhYyBi4buPIFwoIEhfMCBcKQ0KDQoNCiMjIyMgMi4xMC4yIFNlcXVlbnRpYWwgQW5hbHlzaXMgb2YgVmFyaWFuY2UgKFR5cGUgSSBTUykNCg0KKirDnSB0xrDhu59uZzoqKiDEkMawYSB04burbmcgYmnhur9uIHbDoG8gbcO0IGjDrG5oIHRoZW8gdGjhu6kgdOG7sSBj4bulIHRo4buDIOKGkiDEkW8gbMaw4budbmcgbeG7qWMgxJHhu5kgxJHDs25nIGfDs3AgY+G7p2EgdOG7q25nIGJp4bq/bi4NCg0KKirhu6huZyBk4bulbmc6KioNCg0KLSBI4buvdSDDrWNoIGtoaSB0aOG7qSB04buxIG5o4bqtcCBiaeG6v24gY8OzIMO9IG5naMSpYSAodsOtIGThu6U6IHRoaeG6v3Qga+G6vyB0aMOtIG5naGnhu4dtKQ0KDQotIENobyBwaMOpcCBraeG7g20gdHJhIGJp4bq/biB0aOG7qSBcKCBqIFwpICoqc2F1IGtoaSoqIMSRw6MgxJHGsGEgY8OhYyBiaeG6v24gdOG7qyAxIMSR4bq/biBcKCBqLTEgXCkgdsOgbyBtw7QgaMOsbmgNCg0KDQojIyMjIDIuMTAuMyBQYXJhbGxlbCBhbmQgSW5kZXBlbmRlbnQgUmVncmVzc2lvbnMNCg0KKipTbyBzw6FuaCBo4buTaSBxdXkgcmnDqm5nIGJp4buHdCBnaeG7r2EgY8OhYyBuaMOzbSoqICh2w60gZOG7pTogbmFtL27hu68sIHbDuW5nIG1p4buBbi4uLik6DQoNCi0gTcO0IGjDrG5oIGNodW5nOiDDoXAgZOG7pW5nIGNobyB04bqldCBj4bqjIG5ow7NtDQotIE3DtCBow6xuaCByacOqbmc6IGjhu5NpIHF1eSBraMOhYyBuaGF1IGNobyB04burbmcgbmjDs20NCg0KKipLaeG7g20gxJHhu4tuaDoqKg0KDQotIEjhu4cgc+G7kSBk4buRYyBjw7MgZ2nhu5FuZyBuaGF1IGdp4buvYSBjw6FjIG5ow7NtPw0KLSBI4buHIHPhu5EgY2jhurduIGPDsyBnaeG7kW5nIG5oYXUga2jDtG5nPw0KDQoqKlBoxrDGoW5nIHBow6FwOioqDQoNCi0gRMO5bmcgYmnhur9uIGdp4bqjIChkdW1teSkgY2hvIG5ow7NtDQotIETDuW5nIGJp4bq/biB0xrDGoW5nIHTDoWMgKGludGVyYWN0aW9uIHRlcm1zKSDEkeG7gyBraeG7g20gdHJhIHPhu7Ega2jDoWMgYmnhu4d0DQoNCg0KIyMjIyAyLjEwLjQgVGhlIE1hcmdpbmFsaXR5IFByaW5jaXBsZQ0KDQoqKk5ndXnDqm4gdOG6r2MgYmnDqm4gKG1hcmdpbmFsaXR5KToqKg0KDQoNCi0gTuG6v3UgbcO0IGjDrG5oIGJhbyBn4buTbSBt4buZdCAqKmJp4bq/biB0xrDGoW5nIHTDoWMqKiAobmjGsCBcKCB4XzEgeF8yIFwpKSwgdGjDrCAqKmLhuq90IGJ14buZYyoqIHBo4bqjaSBnaeG7ryBj4bqjIGhhaSBiaeG6v24gY2jDrW5oIFwoIHhfMSBcKSB2w6AgXCggeF8yIFwpDQoNCi0gS2jDtG5nIMSRxrDhu6NjIGLhu48gYmnhur9uIGNow61uaCBraGkgZ2nhu68gYmnhur9uIHTGsMahbmcgdMOhYw0KDQoqKk3hu6VjIHRpw6p1OioqIMSQ4bqjbSBi4bqjbyBtw7QgaMOsbmggY8OzICoqw70gbmdoxKlhIHRo4buRbmcga8OqKiogdsOgICoqZOG7hSBkaeG7hW4gZ2nhuqNpKioNCg0KIyMjIDIuMTEgQ2hvb3NpbmcgQmV0d2VlbiBOb24tbmVzdGVkIE1vZGVsczogQUlDIGFuZCBCSUMNCg0KDQoqKkFJQyDigJMgQWthaWtlIEluZm9ybWF0aW9uIENyaXRlcmlvbioqDQoNCkPDtG5nIHRo4bupYzoNCg0KJCQNClx0ZXh0e0FJQ30gPSAtMiBcbG9nKEwpICsgMnANCiQkDQoNClRyb25nIMSRw7M6DQoNCi0gXCggTCBcKTogSMOgbSBraOG6oyBuxINuZyB04buRaSDEkWEgKGxpa2VsaWhvb2QpIGPhu6dhIG3DtCBow6xuaA0KLSBcKCBwIFwpOiBT4buRIGzGsOG7o25nIHRoYW0gc+G7kSB0cm9uZyBtw7QgaMOsbmggKGJhbyBn4buTbSBj4bqjIGludGVyY2VwdCkNCg0Kw50gbmdoxKlhOg0KDQotIEFJQyDEkW8gbMaw4budbmcgbeG7qWMgxJHhu5kgcGjDuSBo4bujcCBj4bunYSBtw7QgaMOsbmggduG7m2kgZOG7ryBsaeG7h3UsIGPDsyBwaOG6oXQgxJHhu5kgcGjhu6ljIHThuqFwIMSR4buDIHRyw6FuaCBvdmVyZml0dGluZy4NCi0gKipBSUMgY8OgbmcgdGjhuqVwKiog4oaSIG3DtCBow6xuaCBjw6BuZyB04buRdC4NCi0gQ8OzIHPhu7EgxJHDoW5oIMSR4buVaSBnaeG7r2EgxJHhu5kga2jhu5twIChnb29kbmVzcyBvZiBmaXQpIHbDoCDEkeG7mSBwaOG7qWMgdOG6oXAgKG1vZGVsIGNvbXBsZXhpdHkpLg0KDQoqKkJJQyDigJMgQmF5ZXNpYW4gSW5mb3JtYXRpb24gQ3JpdGVyaW9uKioNCg0KQ8O0bmcgdGjhu6ljOg0KDQokJA0KXHRleHR7QklDfSA9IC0yIFxsb2coTCkgKyBwIFxsb2cobikNCiQkDQoNClRyb25nIMSRw7M6DQoNCi0gXCggbiBcKTogU+G7kSBsxrDhu6NuZyBxdWFuIHPDoXQNCi0gXCggTCBcKTogSMOgbSBraOG6oyBuxINuZyB04buRaSDEkWEgKGxpa2VsaWhvb2QpIGPhu6dhIG3DtCBow6xuaA0KLSBcKCBwIFwpOiBT4buRIGzGsOG7o25nIHRoYW0gc+G7kSB0cm9uZyBtw7QgaMOsbmggKGJhbyBn4buTbSBj4bqjIGludGVyY2VwdCkNCg0Kw50gbmdoxKlhOg0KDQotIEJJQyBjxaluZyDEkcOhbmggZ2nDoSBtw7QgaMOsbmggduG7m2kgeeG6v3UgdOG7kSBwaOG6oXQgY2hvIMSR4buZIHBo4bupYyB04bqhcC4NCi0gVHV5IG5oacOqbiwgQklDIHBo4bqhdCBtw7QgaMOsbmggcGjhu6ljIHThuqFwIG7hurduZyBoxqFuIEFJQywgZG8gaOG7hyBz4buRIHBo4bqhdCBsw6AgXCggXGxvZyhuKSBcKSB0aGF5IHbDrCAyLg0KLSAqKkThu68gbGnhu4d1IGPDoG5nIGzhu5tuKiog4oaSIFwoIFxsb2cobikgXCkgY8OgbmcgbOG7m24g4oaSIEJJQyBjw6BuZyBuZ2hpw6puZyB24buBIG3DtCBow6xuaCDEkcahbiBnaeG6o24gaMahbi4NCg0KKipTbyBzw6FuaCBBSUMgdsOgIEJJQyoqDQoNCg0KYGBge3J9DQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KY29tcGFyaXNvbiA8LSBkYXRhLmZyYW1lKA0KICBgVGnDqnUgY2jDrWAgPSBjKCJBSUMiLCAiQklDIiksDQogIGDGr3UgxJFp4buDbWAgPSBjKCJMaW5oIGhv4bqhdCwgZMO5bmcgY2hvIGThu7EgxJFvw6FuIiwgDQogICAgICAgICAgICAgICAgIkNo4buNbiBtw7QgaMOsbmggxJHGoW4gZ2nhuqNuIGjGoW4sIGfhuqduIHbhu5tpIGzDvSB0aHV54bq/dCBCYXllcyIpLA0KICBgTmjGsOG7o2MgxJFp4buDbWAgPSBjKCJDw7MgdGjhu4MgY2jhu41uIG3DtCBow6xuaCBxdcOhIHBo4bupYyB04bqhcCIsIA0KICAgICAgICAgICAgICAgICAgICJDw7MgdGjhu4MgYuG7jyBzw7N0IGJp4bq/biBo4buvdSDDrWNoIHRyb25nIG3DtCBow6xuaCBuaOG7jyIpDQopDQprYWJsZShjb21wYXJpc29uLCBjYXB0aW9uID0gIlNvIHPDoW5oIEFJQyB2w6AgQklDIiwgZm9ybWF0ID0gImh0bWwiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiYm9yZGVyZWQiLCAiY29uZGVuc2VkIiksDQogICAgICAgICAgICAgICAgZnVsbF93aWR0aCA9IEZBTFNFKQ0KYGBgDQoNCg0KDQojIyMgMi4xMiBUb29scyB0byBBc3Npc3QgaW4gTW9kZWwgU2VsZWN0aW9uDQojIyMjIDIuMTIuMSBBZGRpbmcgYW5kIERyb3BwaW5nIFZhcmlhYmxlcw0KxJDDonkgbMOgIGPDoWNoIHRo4bunIGPDtG5nIMSR4buDIHjDonkgZOG7sW5nIG3DtCBow6xuaCBwaMO5IGjhu6NwOiBi4bqvdCDEkeG6p3UgduG7m2kgbcO0IGjDrG5oIG5o4buPIHbDoCB0aMOqbSBiaeG6v24sIGhv4bq3YyBi4bqvdCDEkeG6p3UgduG7m2kgbcO0IGjDrG5oIMSR4bqneSDEkeG7pyBy4buTaSBsb+G6oWkgYuG7jyBiaeG6v24uDQoNCkPhuqduIHhlbSB4w6l0IMO9IG5naMSpYSB0aOG7kW5nIGvDqiAocC12YWx1ZSkgdsOgIG3hurd0IHRo4buxYyB0aeG7hW4gKGhp4buDdSBiaeG6v3QgduG7gSBiaeG6v24gxJHDsykuDQoNCiMjIyMgMi4xMi4yIEF1dG9tYXRlZCBNZXRob2RzIGZvciBNb2RlbCBTZWxlY3Rpb24NCg0KMyBwaMawxqFuZyBwaMOhcCBjaMOtbmggdOG7sSDEkeG7mW5nOg0KDQo8bGk+Rm9yd2FyZCBTZWxlY3Rpb24gKENo4buNbiB0aeG6v24pOjwvbGk+DQpC4bqvdCDEkeG6p3UgdOG7qyBtw7QgaMOsbmgga2jDtG5nIGPDsyBiaeG6v24gbsOgby4NCg0KVGjDqm0gbOG6p24gbMaw4bujdCB04burbmcgYmnhur9uIHNhbyBjaG8gY+G6o2kgdGhp4buHbiB0acOqdSBjaMOtIChBSUMgaG/hurdjIEJJQykuDQoNCjxsaT5CYWNrd2FyZCBFbGltaW5hdGlvbiAoTG/huqFpIGzDuWkpOjwvbGk+DQpC4bqvdCDEkeG6p3UgduG7m2kgbcO0IGjDrG5oIMSR4bqneSDEkeG7pyAodOG6pXQgY+G6oyBiaeG6v24pLg0KDQpMb+G6oWkgZOG6p24gY8OhYyBiaeG6v24ga2jDtG5nIGPhuqduIHRoaeG6v3QgKHAtdmFsdWUgbOG7m24sIGtow7RuZyBj4bqjaSB0aGnhu4duIHRpw6p1IGNow60pLg0KDQo8bGk+U3RlcHdpc2UgUmVncmVzc2lvbiAoQsaw4bubYyB0aeG6v24vbMO5aSk6PC9saT4NCkvhur90IGjhu6NwIGPhuqMgaGFpIHBoxrDGoW5nIHBow6FwIHRyw6puOiBzYXUgbeG7l2kgbOG6p24gdGjDqm0sIHhlbSB4w6l0IGPDsyBj4bqnbiBsb+G6oWkgYmnhur9uIG7DoG8gxJFpIGtow7RuZy4NCg0KDQojIyMjIDIuMTIuMyBPYmplY3Rpb25zIHRvIFVzaW5nIFN0ZXB3aXNlIFByb2NlZHVyZXMNCg0KPGxpPk3hu5l0IHPhu5EgcGjhuqNuIMSR4buRaSB0aMaw4budbmcgZ+G6t3AgduG7m2kgc3RlcHdpc2U6PC9saT4NCg0KPGxpPlTEg25nIG5ndXkgY8ahIGNo4buNbiBzYWkgbcO0IGjDrG5oIChvdmVyZml0dGluZykuPC9saT4NCg0KPGxpPktow7RuZyBwaOG6o24gw6FuaCDEkcO6bmcgw70gbmdoxKlhIHRo4buxYyB0aeG7hW4gY+G7p2EgY8OhYyBiaeG6v24uPC9saT4NCg0KPGxpPkvhur90IHF14bqjIHBo4bulIHRodeG7mWMgdGjhu6kgdOG7sSB0aMOqbS9i4bubdCBiaeG6v24uPC9saT4NCg0KPGxpPktow7RuZyDEkeG6o20gYuG6o28gY2jhu41uIMSRxrDhu6NjIG3DtCBow6xuaCB04buRdCBuaOG6pXQgdG/DoG4gY+G7pWMuPC9saT4NCg0KIyMgQ2jGsMahbmcgMzogIExpbmVhciBSZWdyZXNzaW9uIE1vZGVsczogRGlhZ25vc3RpY3MgYW5kIE1vZGVsLUJ1aWxkaW5nDQoNCiMjIyAzLjEgUmVzaWR1YWxzIGZvciBOb3JtYWwgTGluZWFyIFJlZ3Jlc3Npb24gTW9kZWxzDQpUcm9uZyBtw7QgaMOsbmggaOG7k2kgcXV5IHR1eeG6v24gdMOtbmggdGjDtG5nIHRoxrDhu51uZywgcGjhuqduIGTGsCAocmVzaWR1YWwpIGzDoCBoaeG7h3UgZ2nhu69hIGdpw6EgdHLhu4sgdGjhu7FjIHThur8gdsOgIGdpw6EgdHLhu4sgZOG7sSDEkW/DoW46DQokJA0Kcl9pID0geV9pIC0gXGhhdHtcbXV9X2kNCiQkDQoNClRyb25nIMSRw7M6DQoNCi0gXCggcl9pIFwpOiBwaOG6p24gZMawIGPhu6dhIHF1YW4gc8OhdCB0aOG7qSBcKCBpIFwpICANCi0gXCggeV9pIFwpOiBnacOhIHRy4buLIHF1YW4gc8OhdCB0aOG7sWMgdOG6vyAgDQotIFwoIFxoYXR7XG11fV9pID0gXGhhdHt5fV9pIFwpOiBnacOhIHRy4buLIGThu7EgxJFvw6FuIHThu6sgbcO0IGjDrG5oDQoNCioqQ8OhYyBsb+G6oWkgcGjhuqduIGTGsCB0aMaw4budbmcgZMO5bmc6KioNCg0KUGjhuqduIGTGsCB0aMO0IChSYXcgcmVzaWR1YWwpOg0KDQokJA0Kcl9pID0geV9pIC0gXGhhdHt5fV9pDQokJA0KDQpQaOG6p24gZMawIGNodeG6qW4gaMOzYSAoU3RhbmRhcmRpemVkIHJlc2lkdWFsKToNCg0KJCQNCnJfe2ksXHRleHR7c3RkfX0gPSBcZnJhY3tyX2l9e1xoYXR7XHNpZ21hfSBcc3FydHsxIC0gaF97aWl9fX0NCiQkDQoNClBo4bqnbiBkxrAgU3R1ZGVudGl6ZWQ6DQoNCiQkDQp0X2kgPSBcZnJhY3tyX2l9e1xoYXR7XHNpZ21hfV97KGkpfSBcc3FydHsxIC0gaF97aWl9fX0NCiQkDQoNClRyb25nIMSRw7M6DQoNCi0gXCggcl9pIFwpOiBwaOG6p24gZMawIGPhu6dhIHF1YW4gc8OhdCB0aOG7qSBcKCBpIFwpDQotIFwoIFxoYXR7eX1faSBcKTogZ2nDoSB0cuG7iyBk4buxIMSRb8Ohbg0KLSBcKCBoX3tpaX0gXCk6IHBo4bqnbiB04butIMSRxrDhu51uZyBjaMOpbyBj4bunYSBtYSB0cuG6rW4gaGF0IFwoIEggPSBYKFheVFgpXnstMX1YXlQgXCkNCi0gXCggXGhhdHtcc2lnbWF9IFwpOiBzYWkgc+G7kSBjaHXhuqluIMaw4bubYyBsxrDhu6NuZyB04burIHRvw6BuIGLhu5kgZOG7ryBsaeG7h3UNCi0gXCggXGhhdHtcc2lnbWF9X3soaSl9IFwpOiBzYWkgc+G7kSBjaHXhuqluIGtoaSAqKmxv4bqhaSBi4buPKiogcXVhbiBzw6F0IHRo4bupIFwoIGkgXCkNCg0KIyMjIDMuMi4gUmVzaWR1YWwgUGxvdHMNCg0KUmVzaWR1YWwgcGxvdHMgxJHGsOG7o2Mgc+G7rSBk4bulbmcgxJHhu4Mga2nhu4NtIHRyYSBjw6FjIGdp4bqjIMSR4buLbmggdHJvbmcgbcO0IGjDrG5oIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oIHRow7RuZyBxdWEgcGjhuqduIGTGsCAkcl9pID0geV9pIC0gXGhhdHtcbXV9X2kkDQoNCiMjIyMgMy4yLjEuIFBsb3QgUmVzaWR1YWxzIEFnYWluc3QgXCggeF9qIFwpOiBMaW5lYXJpdHkNCg0KQmnhu4N1IMSR4buTIHBo4bqnbiBkxrAgdGhlbyB04burbmcgYmnhur9uIGdp4bqjaSB0aMOtY2ggXCggeF9qIFwpIMSR4buDIGtp4buDbSB0cmEgZ2nhuqMgxJHhu4tuaCB0dXnhur9uIHTDrW5oIGdp4buvYSBiaeG6v24gXCggeF9qIFwpIHbDoCBiaeG6v24gcGjhu6UgdGh14buZYy4gTuG6v3UgYmnhu4N1IMSR4buTIGtow7RuZyBjw7MgbeG6q3UgaG/hurdjIHh1IGjGsOG7m25nIHLDtSByw6BuZywgZ2nhuqMgxJHhu4tuaCB0dXnhur9uIHTDrW5oIMSRxrDhu6NjIHRo4buPYSBtw6NuLg0KDQojIyMjIDMuMi4yLiBQYXJ0aWFsIFJlc2lkdWFsIFBsb3RzDQoNCkdpw7pwIMSRw6FuaCBnacOhIOG6o25oIGjGsOG7n25nIHJpw6puZyBiaeG7h3QgY+G7p2EgYmnhur9uICBcKCB4X2ogXCkgdHJvbmcgbcO0IGjDrG5oIMSRYSBiaeG6v24gYuG6sW5nIGPDoWNoIHTDoWNoIHBo4bqnbiBkxrAgbGnDqm4gcXVhbiDEkeG6v24gYmnhur9uIG7DoHksIGjhu5cgdHLhu6MgcGjDoXQgaGnhu4duIG3hu5FpIHF1YW4gaOG7hyBwaGkgdHV54bq/biBob+G6t2Mg4bqjbmggaMaw4bufbmcgxJHhurdjIGJp4buHdC4NCg0KIyMjIyAzLjIuMy4gUGxvdCBSZXNpZHVhbHMgQWdhaW5zdCBcKCBcaGF0e1xtdX0gXCk6IENvbnN0YW50IFZhcmlhbmNlDQoNCkJp4buDdSDEkeG7kyBwaOG6p24gZMawIHRoZW8gZ2nDoSB0cuG7iyBk4buxIMSRb8OhbiBcKCBcaGF0e1xtdX0gXCkgxJHhu4Mga2nhu4NtIHRyYSBnaeG6oyDEkeG7i25oIHBoxrDGoW5nIHNhaSDEkeG7k25nIG5o4bqldCAoaG9tb3NjZWRhc3RpY2l0eSkuIE7hur91IHBo4bqnbiBkxrAgcGjDom4gYuG7kSDEkeG7gXUsIGtow7RuZyBjw7MgeHUgaMaw4bubbmcgdGhheSDEkeG7lWkgcGjGsMahbmcgc2FpIHRoZW8gXCggXGhhdHtcbXV9IFwpLCBnaeG6oyDEkeG7i25oIMSRxrDhu6NjIGdp4buvLg0KDQojIyMjIDMuMi40LiBR4oCTUSBQbG90cyBhbmQgTm9ybWFsaXR5DQoNClPhu60gZOG7pW5nIGJp4buDdSDEkeG7kyBRLVEgxJHhu4Mga2nhu4NtIHRyYSBwaMOibiBwaOG7kWkgY2h14bqpbiBj4bunYSBwaOG6p24gZMawLiBQaOG6p24gZMawIHR1w6JuIHRoZW8gcGjDom4gcGjhu5FpIGNodeG6qW4gbuG6v3UgY8OhYyDEkWnhu4NtIGfhuqduIHRo4bqzbmcgaMOgbmcgdHLDqm4gYmnhu4N1IMSR4buTLg0KDQojIyMjIDMuMi41LiBMYWcgUGxvdHMgYW5kIERlcGVuZGVuY2Ugb3ZlciBUaW1lDQoNClPhu60gZOG7pW5nIGJp4buDdSDEkeG7kyBsYWcgxJHhu4MgcGjDoXQgaGnhu4duIHPhu7EgcGjhu6UgdGh14buZYyBob+G6t2MgbeG6q3UgdHJvbmcgcGjhuqduIGTGsCB0aGVvIHRo4budaSBnaWFuLCBnacO6cCBraeG7g20gdHJhIGdp4bqjIMSR4buLbmggxJHhu5ljIGzhuq1wIGPhu6dhIGPDoWMgc2FpIHPhu5EuDQoNCiMjIyAzLjMuIE91dGxpZXJzIGFuZCBJbmZsdWVudGlhbCBPYnNlcnZhdGlvbnMNCiMjIyMgMy4zLjEuIEdp4bubaSB0aGnhu4d1DQoNCi0gT3V0bGllcnMgbMOgIGPDoWMgcXVhbiBzw6F0IGPDsyBwaOG6p24gZMawIGzhu5tuLCBjw7MgdGjhu4MgbMOgbSBzYWkgbOG7h2NoIGvhur90IHF14bqjIGjhu5NpIHF1eS4NCg0KLSBJbmZsdWVudGlhbCBvYnNlcnZhdGlvbnMgbMOgIG5o4buvbmcgxJFp4buDbSBjw7Mg4bqjbmggaMaw4bufbmcgbOG7m24gdOG7m2kgxrDhu5tjIGzGsOG7o25nIG3DtCBow6xuaCwgY8OzIHRo4buDIGtow7RuZyBwaOG6o2kgb3V0bGllciB24buBIHBo4bqnbiBkxrAgbmjGsG5nIGzhuqFpIGPDsyBsZXZlcmFnZSBjYW8uDQoNCiMjIyMgMy4zLjIgT3V0bGllcnMgYW5kIFN0dWRlbnRpemVkIFJlc2lkdWFscw0KUGjhuqduIGTGsCBzdHVkZW50aXplZCAoc3R1ZGVudGl6ZWQgcmVzaWR1YWxzKSBnacO6cCBwaMOhdCBoaeG7h24gb3V0bGllcnMgYuG6sW5nIGPDoWNoIGNodeG6qW4gaMOzYSBwaOG6p24gZMawIHRoZW8gxJHhu5kgbOG7h2NoIGNodeG6qW4gZOG7sSDEkW/DoW4uDQpDw7RuZyB0aOG7qWM6DQokJA0KdF9pID0gXGZyYWN7cl9pfXtcaGF0e1xzaWdtYX0gXHNxcnR7MSAtIGhfe2lpfX19DQokJA0KVHJvbmcgxJHDszoNCg0KLSBcKCByX2kgPSB5X2kgLSBcaGF0e1xtdX1faSBcKSBsw6AgcGjhuqduIGTGsCBxdWFuIHPDoXQgdGjhu6kgXCggaSBcKS4NCg0KLSBcKCBcaGF0e1xzaWdtYX0gXCkgbMOgIMaw4bubYyBsxrDhu6NuZyDEkeG7mSBs4buHY2ggY2h14bqpbiBzYWkgc+G7kSAocmVzaWR1YWwgc3RhbmRhcmQgZXJyb3IpLg0KDQotIFwoIGhfe2lpfSBcKSBsw6AgbGV2ZXJhZ2UgKGdpw6EgdHLhu4sgdHLDqm4gxJHGsOG7nW5nIGNow6lvIGPhu6dhIG1hIHRy4bqtbiBcKCBIID0gWCAoWF5UIFgpXnstMX0gWF5UIFwpKS4NCg0KQ2jDuiDDvTogR2nDoSB0cuG7iyBcKCB8dF9pfCBcKSBs4bubbiAodGjGsOG7nW5nID4gMiBob+G6t2MgPiAzKSBj4bqjbmggYsOhbyBxdWFuIHPDoXQgxJHDsyBjw7MgdGjhu4MgbMOgIG91dGxpZXIuDQoNCiMjIyMgMy4zLjMgSW5mbHVlbnRpYWwgT2JzZXJ2YXRpb25zDQoNCsSQw6FuaCBnacOhIG3hu6ljIMSR4buZIOG6o25oIGjGsOG7n25nIGPhu6dhIMSRaeG7g20gZOG7ryBsaeG7h3UgZOG7sWEgdHLDqm4gY8OhYyBjaOG7iSBz4buROg0KLSBMZXZlcmFnZSBcKCBoX3tpaX0gXCk6IMSRbyDEkeG7mSAieGEiIGPhu6dhIMSRaeG7g20gcXVhbiBzw6F0IHRyw6puIGtow7RuZyBnaWFuIGJp4bq/biDEkeG7mWMgbOG6rXANCg0KLSBDb29r4oCZcyBEaXN0YW5jZSBcKCBEX2kgXCk6IMSRbyBz4buxIHRoYXkgxJHhu5VpIHThu5VuZyB0aOG7gyBj4bunYSBjw6FjIMaw4bubYyBsxrDhu6NuZyBraGkgYuG7jyDEkWnhu4NtIFwoIGkgXCkuDQpDw7RuZyB0aOG7qWM6IFxbDQpEX2kgPSBcZnJhY3tyX2leMn17cCBcaGF0e1xzaWdtYX1eMn0gXGNkb3QgXGZyYWN7aF97aWl9fXsoMSAtIGhfe2lpfSleMn0NClxdDQoNClRyb25nIMSRw7M6DQoNCi0gXCggcCBcKTogbMOgIHPhu5EgYmnhur9uIHRyb25nIG3DtCBow6xuaCAoYmFvIGfhu5NtIGPhuqMgaOG6sW5nIHPhu5EgaW50ZXJjZXB0KQ0KLSBcKCByX2kgXCksIFwoIFxoYXR7XHNpZ21hfSBcKSwgXCggaF97aWl9IFwpOiBuaMawIMSRw6MgxJHhu4tuaCBuZ2jEqWEg4bufIHRyw6puDQoNCkdoaSBjaMO6OiANClF1YW4gc8OhdCBjw7MgQ29va+KAmXMgRGlzdGFuY2UgbOG7m24gKHbDrSBk4bulIFwoIERfaSA+IDEgXCkpIMSRxrDhu6NjIHhlbSBsw6AgY8OzIOG6o25oIGjGsOG7n25nIG3huqFuaCDEkeG6v24gbcO0IGjDrG5oIHbDoCBj4bqnbiDEkcaw4bujYyB4ZW0geMOpdCBr4bu5IGzGsOG7oW5nLg0KDQoNCiMjIENoxrDGoW5nIDQ6IEJleW9uZCBMaW5lYXIgUmVncmVzc2lvbiAtIFRoZSBNZXRob2Qgb2YgTWF4aW11bSBMaWtlbGlob29kDQoNCg0KIyMjIDQuMSBHaeG7m2kgdGhp4buHdQ0KDQpLaMOhaSBxdcOhdCB24buBIHBoxrDGoW5nIHBow6FwIMav4bubYyBsxrDhu6NuZyBD4buxYyDEkeG6oWkgKE1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0aW9uIC0gTUxFKSBuaMawIG3hu5l0IHBoxrDGoW5nIHBow6FwIHThu5VuZyBxdcOhdCBjaG8gY8OhYyBtw7QgaMOsbmggdGjhu5FuZyBrw6ogdsaw4bujdCByYSBuZ2/DoGkgaOG7k2kgcXV5IHR1eeG6v24gdMOtbmggdGjDtG5nIHRoxrDhu51uZy4NCg0KIyMjIDQuMiBUaGUgTmVlZCBmb3IgTm9uLW5vcm1hbCBSZWdyZXNzaW9uIE1vZGVscw0KDQoqKktoaSBuw6BvIG3DtCBow6xuaCB0dXnhur9uIHTDrW5oIGtow7RuZyBwaMO5IGjhu6NwOioqDQoNCi0gQmnhur9uIHBo4bulIHRodeG7mWMga2jDtG5nIHBo4bqjaSBsw6AgYmnhur9uIGxpw6puIHThu6VjIGPDsyBwaMOibiBwaOG7kWkgY2h14bqpbi4NCiAgKiBWw60gZOG7pTogZOG7ryBsaeG7h3Ugbmjhu4sgcGjDom4sIMSR4bq/bSwgaG/hurdjIGdpw6EgdHLhu4sgZMawxqFuZyBsacOqbiB04bulYy4NCg0KKipDw6FjIGxv4bqhaSBk4buvIGxp4buHdSB2w6AgbcO0IGjDrG5oIHBow7kgaOG7o3A6KioNCg0KLSBE4buvIGxp4buHdSBuaOG7iyBwaMOibiBob+G6t2MgxJHhur9tIG5o4buLIHBow6JuIOKGkiBtw7QgaMOsbmggQmVybm91bGxpLCBCaW5vbWlhbC4NCi0gROG7ryBsaeG7h3UgxJHhur9tIGtow7RuZyBnaeG7m2kgaOG6oW4g4oaSIFBvaXNzb24gaG/hurdjIE5lZ2F0aXZlIEJpbm9taWFsLg0KLSBE4buvIGxp4buHdSBsacOqbiB04bulYyBkxrDGoW5nIOKGkiBtw7QgaMOsbmggcGjDom4gcGjhu5FpIEdhbW1hIGhv4bq3YyBJbnZlcnNlIEdhdXNzaWFuLg0KDQojIyMgNC4zIEdlbmVyYWxpemluZyB0aGUgTm9ybWFsIExpbmVhciBNb2RlbA0KDQpN4bufIHLhu5luZyBtw7QgaMOsbmggdHV54bq/biB0w61uaCBjaHXhuqluIHNhbmcgbcO0IGjDrG5oIHThu5VuZyBxdcOhdCB24bubaSBwaMOibiBwaOG7kWkga2jDoWMgKGV4cG9uZW50aWFsIGZhbWlseSksIGNodeG6qW4gYuG7iyBjaG8gcGjGsMahbmcgcGjDoXAgTUxFLg0KDQoNCiMjIyA0LjQgVGhlIElkZWEgb2YgTGlrZWxpaG9vZCBFc3RpbWF0aW9uDQoNCioqSMOgbSBMaWtlbGlob29kKiogXCggTChcdGhldGEpIFwpOiAgDQogIFjDoWMgc3XhuqV0IMSR4buTbmcgdGjhu51pIGPhu6dhIHF1YW4gc8OhdCBkxrDhu5tpIHRoYW0gc+G7kSBcKFx0aGV0YVwpOg0KICAkJA0KICBMKFx0aGV0YSkgPSBccHJvZF97aT0xfV5uIGYoeV9pIFxtaWQgXHRoZXRhKQ0KICAkJA0KDQoqKkxvZy1saWtlbGlob29kOioqICANCiAgxJDhu4MgdMOtbmggdG/DoW4gZOG7hSBkw6BuZyBoxqFuLCBs4bqleSBsb2cgaMOgbSBsaWtlbGlob29kOg0KDQogICQkDQogIFxlbGwoXHRoZXRhKSA9IFxsb2cgTChcdGhldGEpID0gXHN1bV97aT0xfV5uIFxsb2cgZih5X2kgXG1pZCBcdGhldGEpDQogICQkDQoNCiogKirGr+G7m2MgbMaw4bujbmcgY+G7sWMgxJHhuqFpOioqICANCiAgVMOsbSBcKFxoYXR7XHRoZXRhfVwpIHNhbyBjaG8gXChcZWxsKFx0aGV0YSlcKSDEkeG6oXQgY+G7sWMgxJHhuqFpLg0KDQoNCiMjIyA0LjUgTWF4aW11bSBMaWtlbGlob29kIGZvciBFc3RpbWF0aW5nIE9uZSBQYXJhbWV0ZXINCg0KKipQaMawxqFuZyB0csOsbmggc2NvcmU6KiogIA0KICDEkOG6oW8gaMOgbSBsb2ctbGlrZWxpaG9vZCB0aGVvIHRoYW0gc+G7kToNCg0KICAkJA0KICBVKFx0aGV0YSkgPSBcZnJhY3tkXGVsbChcdGhldGEpfXtkXHRoZXRhfQ0KICAkJA0KDQogIEdp4bqjaSBcKFUoXHRoZXRhKSA9IDBcKSDEkeG7gyB0w6xtIFwoXGhhdHtcdGhldGF9XCkuDQoNCioqSMOgbSB0aMO0bmcgdGluIChJbmZvcm1hdGlvbik6KioNCg0KICAqIFRow7RuZyB0aW4gcXVhbiBzw6F0Og0KDQogICAgJCQNCiAgICBJKFx0aGV0YSkgPSAtIFxmcmFje2ReMiBcZWxsKFx0aGV0YSl9e2RcdGhldGFeMn0NCiAgICAkJA0KDQogICogVGjDtG5nIHRpbiBr4buzIHbhu41uZyAoRmlzaGVyIEluZm9ybWF0aW9uKToNCg0KICAgICQkDQogICAgXG1hdGhjYWx7SX0oXHRoZXRhKSA9IFxtYXRocm17RX1cbGVmdFsgSShcdGhldGEpIFxyaWdodF0NCiAgICAkJA0KDQoqKsSQ4buZIGzhu4djaCBjaHXhuqluIGPhu6dhIMaw4bubYyBsxrDhu6NuZzoqKg0KDQogICQkDQogIFxtYXRocm17U0V9KFxoYXR7XHRoZXRhfSkgPSBcc3FydHtcZnJhY3sxfXtcbWF0aGNhbHtJfShcaGF0e1x0aGV0YX0pfX0NCiAgJCQNCg0KIyMjIDQuNiBNYXhpbXVtIExpa2VsaWhvb2QgZm9yIE1vcmUgVGhhbiBPbmUgUGFyYW1ldGVyDQoNCioqU2NvcmUgdmVjdG9yOioqDQoNCiAgJCQNCiAgVShcYm9sZHN5bWJvbHtcdGhldGF9KSA9IFxuYWJsYSBcZWxsKFxib2xkc3ltYm9se1x0aGV0YX0pID0gXGxlZnQoXGZyYWN7XHBhcnRpYWwgXGVsbH17XHBhcnRpYWwgXHRoZXRhXzF9LCBcbGRvdHMsIFxmcmFje1xwYXJ0aWFsIFxlbGx9e1xwYXJ0aWFsIFx0aGV0YV9wfSBccmlnaHQpXlQNCiAgJCQNCioqSGVzc2lhbiBtYXRyaXggKE9ic2VydmVkIGluZm9ybWF0aW9uKToqKg0KDQogICQkDQogIEkoXGJvbGRzeW1ib2x7XHRoZXRhfSkgPSAtXG5hYmxhXjIgXGVsbChcYm9sZHN5bWJvbHtcdGhldGF9KSA9IC0gXGxlZnRbXGZyYWN7XHBhcnRpYWxeMiBcZWxsfXtccGFydGlhbCBcdGhldGFfaSBccGFydGlhbCBcdGhldGFfan1ccmlnaHRdDQogICQkDQoNCioqxq/hu5tjIGzGsOG7o25nKiogXChcaGF0e1xib2xkc3ltYm9se1x0aGV0YX19XCkgKip0w6xtIGLhurFuZyBnaeG6o2kgaOG7hyoqIFwoVShcYm9sZHN5bWJvbHtcdGhldGF9KSA9IDBcKS4NCg0KKirEkOG7mSBs4buHY2ggY2h14bqpbiB0aGFtIHPhu5E6KiogIA0KICDEkMaw4bujYyB0w61uaCB04burIG1hIHRy4bqtbiBuZ2jhu4tjaCDEkeG6o28gdGjDtG5nIHRpbiBGaXNoZXI6DQoNCiAgJCQNCiAgXG1hdGhybXtDb3Z9KFxoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX0pIFxhcHByb3ggSShcaGF0e1xib2xkc3ltYm9se1x0aGV0YX19KV57LTF9DQogICQkDQoNCiMjIyA0LjcgTWF4aW11bSBMaWtlbGlob29kIFVzaW5nIE1hdHJpeCBBbGdlYnJhICh0w7NtIHThuq90KQ0KDQoqIFPhu60gZOG7pW5nIGvDvSBoaeG7h3UgdmVjdG9yIHbDoCBtYSB0cuG6rW4gxJHhu4MgYmnhu4N1IGRp4buFbiBzY29yZSB2w6AgdGjDtG5nIHRpbi4NCg0KKiBQaMawxqFuZyB0csOsbmggc2NvcmU6DQoNCiAgJCQNCiAgVShcYm9sZHN5bWJvbHtcdGhldGF9KSA9IFxtYXRoYmZ7WH1eVCBcbWF0aGJme1d9KFxtYXRoYmZ7eX0gLSBcYm9sZHN5bWJvbHtcbXV9KQ0KICAkJA0KDQogIHbhu5tpIFwoXG1hdGhiZntXfVwpIGzDoCBtYSB0cuG6rW4gdHLhu41uZyBz4buRIHTDuXkgdGhlbyBwaMOibiBwaOG7kWkuDQoNCiogVGjDtG5nIHRpbiBGaXNoZXIgcXVhbiBzw6F0Og0KDQogICQkDQogIEkoXGJvbGRzeW1ib2x7XHRoZXRhfSkgPSBcbWF0aGJme1h9XlQgXG1hdGhiZntXfSBcbWF0aGJme1h9DQogICQkDQoNCg0KIyMjIDQuOCBGaXNoZXIgU2NvcmluZyBmb3IgQ29tcHV0aW5nIE1MRXMNCg0KKiBUaHXhuq10IHRvw6FuIGzhurdwIGThu7FhIHRyw6puIG3hu58gcuG7mW5nIE5ld3Rvbi1SYXBoc29uLCBz4butIGThu6VuZyBGaXNoZXIgSW5mb3JtYXRpb24gxJHhu4MgY+G6rXAgbmjhuq10IHRoYW0gc+G7kToNCg0KICAkJA0KICBcYm9sZHN5bWJvbHtcdGhldGF9XnsodCsxKX0gPSBcYm9sZHN5bWJvbHtcdGhldGF9XnsodCl9ICsgSShcYm9sZHN5bWJvbHtcdGhldGF9XnsodCl9KV57LTF9IFUoXGJvbGRzeW1ib2x7XHRoZXRhfV57KHQpfSkNCiAgJCQNCg0KDQojIyMgNC45IFByb3BlcnRpZXMgb2YgTUxFcw0KDQoqKlTDrW5oIGNo4bqldDoqKg0KDQogICogVMOtbmgga2jDtG5nIGNo4buHY2ggKGFzeW1wdG90aWNhbGx5IHVuYmlhc2VkKQ0KICAqIEhp4buHdSBxdeG6oyAoYXN5bXB0b3RpY2FsbHkgZWZmaWNpZW50KQ0KICAqIFBow6JuIHBo4buRaSB44bqlcCB44buJIGNodeG6qW4ga2hpIG3huqt1IGzhu5tuDQoNCg0KIyMjIDQuMTAgSHlwb3RoZXNpcyBUZXN0aW5nOiBMYXJnZSBTYW1wbGUgQXN5bXB0b3RpYyBSZXN1bHRzDQoNCiogQ8OhYyBwaMawxqFuZyBwaMOhcCBraeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dCBz4butIGThu6VuZyBNTEU6DQoNCiAgKiBLaeG7g20gxJHhu4tuaCBXYWxkDQogICogS2nhu4NtIMSR4buLbmggTGlrZWxpaG9vZCBSYXRpbw0KICAqIEtp4buDbSDEkeG7i25oIFNjb3JlIChMYWdyYW5nZSBNdWx0aXBsaWVyKQ0KDQoNCiMjIyA0LjExIENvbmZpZGVuY2UgSW50ZXJ2YWxzDQoNCiogQ8OhY2ggeMOieSBk4buxbmcga2hv4bqjbmcgdGluIGPhuq15IGNobyB0aGFtIHPhu5EgZOG7sWEgdHLDqm4gcGjDom4gcGjhu5FpIGNodeG6qW4gY+G7p2EgTUxFOg0KDQogICQkDQogIFxoYXR7XHRoZXRhfSBccG0gel97XGFscGhhLzJ9IFxjZG90IFxtYXRocm17U0V9KFxoYXR7XHRoZXRhfSkNCiAgJCQNCg0KDQojIyMgNC4xMiBDb21wYXJpbmcgTm9uLW5lc3RlZCBNb2RlbHM6IFRoZSBBSUMgYW5kIEJJQw0KDQoqKkFJQyAoQWthaWtlIEluZm9ybWF0aW9uIENyaXRlcmlvbik6KioNCg0KICAkJA0KICBcbWF0aHJte0FJQ30gPSAtMlxlbGwoXGhhdHtcdGhldGF9KSArIDJrDQogICQkDQoNCiAgduG7m2kgXChrXCkgbMOgIHPhu5EgdGhhbSBz4buRIMaw4bubYyBsxrDhu6NuZy4NCg0KKipCSUMgKEJheWVzaWFuIEluZm9ybWF0aW9uIENyaXRlcmlvbik6KioNCg0KICAkJA0KICBcbWF0aHJte0JJQ30gPSAtMlxlbGwoXGhhdHtcdGhldGF9KSArIGsgXGxvZyBuDQogICQkDQoNCkTDuW5nIMSR4buDIHNvIHPDoW5oIGPDoWMgbcO0IGjDrG5oIGtow7RuZyBs4buTbmcgbmhhdSwgY2jhu41uIG3DtCBow6xuaCBjw7MgZ2nDoSB0cuG7iyBBSUMgaG/hurdjIEJJQyBuaOG7jyBoxqFuLg0KDQoNCg0KDQojIyBDaMawxqFuZyA1OiBHZW5lcmFsaXplZCBMaW5lYXIgTW9kZWxzIChHTE1zKSAtIFN0cnVjdHVyZQ0KDQojIyMgNS4xIEdp4bubaSB0aGnhu4d1DQoNClBo4bqnbiBuw6B5IHRyw6xuaCBiw6B5IG3hu6VjIMSRw61jaCB2w6AgcGjhuqFtIHZpIGPhu6dhIEdMTSBuaMawIG3hu5l0IGtodcO0biBraOG7lSBt4bufIHLhu5luZyBjaG8gaOG7k2kgcXV5LCBnacO6cCBtw7QgaMOsbmggaMOzYSBjw6FjIGJp4bq/biBwaOG7pSB0aHXhu5ljIGtow7RuZyB0dcOibiB0aGVvIHBow6JuIHBo4buRaSBjaHXhuqluLg0KDQoNCiMjIyA1LjIgVGhlIFR3byBDb21wb25lbnRzIG9mIEdlbmVyYWxpemVkIExpbmVhciBNb2RlbHMNCg0KKipIYWkgdGjDoG5oIHBo4bqnbiBjaMOtbmggY+G7p2EgR0xNKioNCg0KLSBSYW5kb20gY29tcG9uZW50IChUaMOgbmggcGjhuqduIG5n4bqrdSBuaGnDqm4pOlBow6JuIHBo4buRaSB4w6FjIHN14bqldCBj4bunYSBiaeG6v24gcGjhuqNuIGjhu5NpLCB0aMaw4budbmcgdGh14buZYyBo4buNIEV4cG9uZW50aWFsIERpc3BlcnNpb24gTW9kZWxzIChFRE1zKS4gIA0KLSBTeXN0ZW1hdGljIGNvbXBvbmVudCAoVGjDoG5oIHBo4bqnbiBo4buHIHRo4buRbmcpOiBN4buRaSBsacOqbiBo4buHIHR1eeG6v24gdMOtbmggZ2nhu69hIGJp4bq/biDEkeG7mWMgbOG6rXAgduG7m2kgdGhhbSBz4buRIHRydW5nIGLDrG5oICRcbXUkIGPhu6dhIHBow6JuIHBo4buRaS4NCg0KDQojIyMgNS4zLiBUaGUgUmFuZG9tIENvbXBvbmVudDogRXhwb25lbnRpYWwgRGlzcGVyc2lvbiBNb2RlbHMgKEVETXMpDQoNCioqVGjDoG5oIHBo4bqnbiBuZ+G6q3Ugbmhpw6puOiBNw7QgaMOsbmggcGjDom4gcGjhu5FpIEVETSoqICANCkVETSBsw6AgaOG7jSBwaMOibiBwaOG7kWkgYmFvIGfhu5NtIG5oaeG7gXUgcGjDom4gcGjhu5FpIHBo4buVIGJp4bq/biBuaMawIGNodeG6qW4sIFBvaXNzb24sIGJpbm9taWFsLg0KDQojIyMjIDUuMy4xLiBEZWZpbml0aW9uIG9mIEVETXMgKMSQ4buLbmggbmdoxKlhIEVETXMpOg0KDQpIw6BtIG3huq10IMSR4buZIHjDoWMgc3XhuqV0IMSRxrDhu6NjIHZp4bq/dCBkxrDhu5tpIGThuqFuZzoNCg0KJCQNCmYoeTsgXHRoZXRhLCBccGhpKSA9IGEoeSwgXHBoaSkgXGV4cFxsZWZ0KFxmcmFje3kgXHRoZXRhIC0gXGthcHBhKFx0aGV0YSl9e1xwaGl9XHJpZ2h0KQ0KJCQNCg0KVHJvbmcgxJHDszogIA0KJFx0aGV0YSQgbMOgIHRoYW0gc+G7kSB04buxIG5oacOqbiwgIA0KJFxwaGkkIGzDoCB0aGFtIHPhu5EgcGjDom4gdMOhbiAoZGlzcGVyc2lvbiBwYXJhbWV0ZXIpLCAgDQokXGthcHBhKFx0aGV0YSkkIGzDoCBow6BtIGN1bXVsYW50IGxpw6puIHF1YW4gxJHhur9uIHRydW5nIGLDrG5oIHbDoCBwaMawxqFuZyBzYWkuDQoNCiMjIyMgNS4zLjIuIE1vbWVudCBhbmQgQ3VtdWxhbnQgRnVuY3Rpb25zIChIw6BtIG1vbWVudCB2w6AgY3VtdWxhbnQpOg0KDQpUcnVuZyBiw6xuaCB2w6AgcGjGsMahbmcgc2FpIGPhu6dhIGJp4bq/biAkWSQgxJHGsOG7o2MgdMOtbmggbmjGsCBzYXU6DQoNCiQkDQpcbWF0aHJte0V9W1ldID0gXGthcHBhJyhcdGhldGEpID0gXG11LCBccXVhZCBcbWF0aHJte1Zhcn1bWV0gPSBccGhpIFxrYXBwYScnKFx0aGV0YSkgPSBccGhpIFYoXG11KQ0KJCQNCg0KVuG7m2kgJFYoXG11KSQgZ+G7jWkgbMOgIGjDoG0gYmnhur9uIHRoacOqbiAodmFyaWFuY2UgZnVuY3Rpb24pLCDEkeG6t2MgdHLGsG5nIGNobyBwaMOibiBwaOG7kWkuDQoNCiMjIyMgNS4zLjMuIFRoZSBWYXJpYW5jZSBGdW5jdGlvbiAoSMOgbSBiaeG6v24gdGhpw6puKToNCg0KWMOhYyDEkeG7i25oIGPDoWNoIHBoxrDGoW5nIHNhaSB0aGF5IMSR4buVaSB0aGVvIHRydW5nIGLDrG5oICRcbXUkLCBy4bqldCBxdWFuIHRy4buNbmcgdHJvbmcgR0xNLg0KDQoNCiMjIyA1LjQgRURNcyBpbiBEaXNwZXJzaW9uIE1vZGVsIEZvcm0NCg0KKipNw7QgaMOsbmggRURNIHRoZW8gZOG6oW5nIMSR4buZIGzhu4djaCAoZGV2aWFuY2UpKioNCg0KxJDhu5kgbOG7h2NoIMSRxqFuIHbhu4sgKHVuaXQgZGV2aWFuY2UpIGTDuW5nIMSR4buDIMSRbyBz4buxIGtow6FjIGJp4buHdCBnaeG7r2EgZ2nDoSB0cuG7iyBxdWFuIHPDoXQgJHkkIHbDoCBnacOhIHRy4buLIGvhu7MgduG7jW5nICRcbXUkOg0KDQokJA0KZCh5LCBcbXUpID0gMiBcbGVmdFsgXGVsbCh5OyB5KSAtIFxlbGwoeTsgXG11KSBccmlnaHRdDQokJA0KDQokXGVsbChcY2RvdCkkIGzDoCBow6BtIGxvZy1saWtlbGlob29kLiDEkOG7mSBs4buHY2ggbsOgeSDEkcaw4bujYyBkw7luZyBsw6BtIHRpw6p1IGNow60gxJHDoW5oIGdpw6EgbcO0IGjDrG5oLg0KDQoNCiMjIyA1LjUgVGhlIFN5c3RlbWF0aWMgQ29tcG9uZW50DQoNCg0KKipMaW5rIEZ1bmN0aW9uIChIw6BtIGxpw6puIGvhur90KToqKg0KDQpIw6BtIGxpw6puIGvhur90IGvhur90IG7hu5FpIHRydW5nIGLDrG5oICRcbXUkIGPhu6dhIGJp4bq/biBwaOG6o24gaOG7k2kgduG7m2kgcHJlZGljdG9yIHR1eeG6v24gdMOtbmggJFxldGEkOg0KDQokJA0KZyhcbXVfaSkgPSBcZXRhX2kgPSB4X2leVCBcYmV0YQ0KJCQNCg0KJGcoXGNkb3QpJCBjw7MgdGjhu4MgbMOgIGxvZ2l0LCBsb2csIGlkZW50aXR5LC4uLiB0w7l5IG3DtCBow6xuaC4NCg0KKipPZmZzZXRzIChUaMOgbmggcGjhuqduIGLDuSB0cuG7qyk6KiogTMOgIHBo4bqnbiB0aMOqbSB2w6BvIHByZWRpY3RvciBtw6Aga2jDtG5nIGPDsyB0aGFtIHPhu5EgxrDhu5tjIGzGsOG7o25nLCBkw7luZyDEkeG7gyDEkWnhu4F1IGNo4buJbmggbcO0IGjDrG5oLg0KDQoNCiMjIyA1LjYgR2VuZXJhbGl6ZWQgTGluZWFyIE1vZGVscyBEZWZpbmVkDQoNCioqxJDhu4tuaCBuZ2jEqWEgdOG7lW5nIHF1w6F0IHbhu4EgR0xNKiogIA0KR0xNIGzDoCBtw7QgaMOsbmggY8OzIDMgdGjDoG5oIHBo4bqnbjoNCg0KLSBQaMOibiBwaOG7kWkgdGh14buZYyBFRE0sICANCi0gUHJlZGljdG9yIHR1eeG6v24gdMOtbmggJFxldGEgPSBYIFxiZXRhJCwgIA0KLSBIw6BtIGxpw6puIGvhur90ICRnJC4NCg0KIyMjIDUuNyBUaGUgVG90YWwgRGV2aWFuY2UNCg0KKipU4buVbmcgxJHhu5kgbOG7h2NoIChkZXZpYW5jZSkgY+G7p2EgbcO0IGjDrG5oKiogIA0KxJDhu5kgbOG7h2NoIHThu5VuZyBo4bujcCBjaG8gdG/DoG4gYuG7mSBk4buvIGxp4buHdToNCg0KJCQNCkQgPSBcc3VtX3tpPTF9Xm4gZCh5X2ksIFxoYXR7XG11fV9pKQ0KJCQNCg0KRMO5bmcgxJHhu4MgxJHDoW5oIGdpw6Egc+G7sSBwaMO5IGjhu6NwIGPhu6dhIG3DtCBow6xuaC4NCg0KIyMjIDUuOCBSZWdyZXNzaW9uIFRyYW5zZm9ybWF0aW9ucyBBcHByb3hpbWF0ZSBHTE1zDQoNCioqQ8OhYyBiaeG6v24gxJHhu5VpIGjhu5NpIHF1eSB44bqlcCB44buJIG3DtCBow6xuaCBHTE0qKiAgDQpQaOG6p24gbsOgeSBuw7NpIHbhu4EgY8OhY2ggY8OhYyBtw7QgaMOsbmggaOG7k2kgcXV5IHRydXnhu4FuIHRo4buRbmcgY8OzIHRo4buDIMSRxrDhu6NjIHhlbSBuaMawIHjhuqVwIHjhu4kgR0xNIHRow7RuZyBxdWEgYmnhur9uIMSR4buVaSBk4buvIGxp4buHdS4NCg0KIyMgQ2jGsMahbmcgNjogR2VuZXJhbGl6ZWQgTGluZWFyIE1vZGVsczpFc3RpbWF0aW9uDQoNCiMjIyA2LjEgR2nhu5tpIHRoaeG7h3UNCg0KQ2jGsMahbmcgbsOgeSB04bqtcCB0cnVuZyB2w6BvIHZp4buHYyDGsOG7m2MgbMaw4bujbmcgdGhhbSBz4buRICRcYmV0YSQgdHJvbmcgR0xNLCBjaOG7pyB54bq/dSBk4buxYSB0csOqbiBwaMawxqFuZyBwaMOhcCDGr+G7m2MgbMaw4bujbmcgQ+G7sWMgxJDhuqFpIChNYXhpbXVtIExpa2VsaWhvb2QgRXN0aW1hdGlvbiAtIE1MRSkuICANCk3hu6VjIHRpw6p1IGzDoCB0w6xtIGLhu5kgdGhhbSBz4buRICRcaGF0e1xiZXRhfSQgc2FvIGNobyBtw7QgaMOsbmggcGjDuSBo4bujcCB04buRdCBuaOG6pXQgduG7m2kgZOG7ryBsaeG7h3UgcXVhbiBzw6F0Lg0KDQoNCiMjIyA2LjIgTGlrZWxpaG9vZCBDYWxjdWxhdGlvbnMgZm9yICRcYmV0YSQNCg0KDQojIyMjIDYuMi4xLiBEaWZmZXJlbnRpYXRpbmcgdGhlIFByb2JhYmlsaXR5IEZ1bmN0aW9uICjEkOG6oW8gaMOgbSBow6BtIHjDoWMgc3XhuqV0KQ0KDQpIw6BtIGxvZy1saWtlbGlob29kIHThu5VuZyBxdcOhdCBjaG8gZOG7ryBsaeG7h3UgJHkgPSAoeV8xLCBcZG90cywgeV9uKSQgbMOgOg0KDQokJA0KXGVsbChcYmV0YSkgPSBcc3VtX3tpPTF9Xm4gXGVsbF9pKFxiZXRhKSA9IFxzdW1fe2k9MX1ebiBcbG9nIGYoeV9pOyBcdGhldGFfaSwgXHBoaSkNCiQkDQoNClRyb25nIMSRw7MgJFx0aGV0YV9pJCBwaOG7pSB0aHXhu5ljIHbDoG8gJFxiZXRhJCB0aMO0bmcgcXVhIHByZWRpY3RvciB0dXnhur9uIHTDrW5oLg0KDQojIyMjIDYuMi4yLiBTY29yZSBFcXVhdGlvbnMgYW5kIEluZm9ybWF0aW9uIGZvciAkXGJldGEkIChQaMawxqFuZyB0csOsbmggc2NvcmUgdsOgIG1hIHRy4bqtbiB0aMO0bmcgdGluKQ0KDQoqKsSQ4bqhbyBow6BtIGLhuq1jIG5o4bqldCBj4bunYSBsb2ctbGlrZWxpaG9vZCAoc2NvcmUgZnVuY3Rpb24pOioqDQoNCiQkDQpVKFxiZXRhKSA9IFxmcmFje1xwYXJ0aWFsIFxlbGwoXGJldGEpfXtccGFydGlhbCBcYmV0YX0NCiQkDQoNCioqTWEgdHLhuq1uIEZpc2hlciBpbmZvcm1hdGlvbjoqKg0KDQokJA0KSShcYmV0YSkgPSAtXG1hdGhiYntFfSBcbGVmdFsgXGZyYWN7XHBhcnRpYWxeMiBcZWxsKFxiZXRhKX17XHBhcnRpYWwgXGJldGEgXHBhcnRpYWwgXGJldGFeVH0gXHJpZ2h0XQ0KJCQNCg0KIyMjIDYuMy4gQ29tcHV0aW5nIEVzdGltYXRlcyBvZiAkXGJldGEkDQoNCioqVMOtbmggdG/DoW4gxrDhu5tjIGzGsOG7o25nICRcaGF0e1xiZXRhfSQqKiAgDQpEbyBwaMawxqFuZyB0csOsbmggc2NvcmUgdGjGsOG7nW5nIGtow7RuZyBnaeG6o2kgxJHGsOG7o2MgY2jDrW5oIHjDoWMsIHRhIGTDuW5nIHBoxrDGoW5nIHBow6FwIGzhurdwIG5oxrAgTmV3dG9uLVJhcGhzb24gaG/hurdjIEZpc2hlciBTY29yaW5nIMSR4buDIHTDrG0gbmdoaeG7h20gZ+G6p24gxJHDum5nIGPhu6dhOg0KDQokJA0KVShcYmV0YSkgPSAwDQokJA0KDQpQaMawxqFuZyBwaMOhcCBs4bq3cCBj4bqtcCBuaOG6rXQgdGhhbSBz4buROg0KDQokJA0KXGJldGFeeyh0KzEpfSA9IFxiZXRhXnsodCl9ICsgXGxlZnRbIEkoXGJldGFeeyh0KX0pIFxyaWdodF1eey0xfSBVKFxiZXRhXnsodCl9KQ0KJCQNCg0KDQojIyMgNi40LiBUaGUgUmVzaWR1YWwgRGV2aWFuY2UNCg0KKirEkOG7mSBs4buHY2ggZMawIChSZXNpZHVhbCBEZXZpYW5jZSkqKiAgDQpMw6AgdGjGsOG7m2MgxJFvIHPhu7Ega2jDoWMgYmnhu4d0IGdp4buvYSBtw7QgaMOsbmggaGnhu4duIHThuqFpIHbhu5tpIG3DtCBow6xuaCBiw6NvIGjDsmEgKG3DtCBow6xuaCBob8OgbiBo4bqjbyk6DQoNCiQkDQpEID0gMiBcc3VtX3tpPTF9Xm4gXGxlZnRbIFxlbGwoeV9pOyB5X2kpIC0gXGVsbCh5X2k7IFxoYXR7XG11fV9pKSBccmlnaHRdDQokJA0KDQrEkOG7mSBs4buHY2ggZMawIGPDoG5nIG5o4buPIHRow6wgbcO0IGjDrG5oIGPDoG5nIHBow7kgaOG7o3AgduG7m2kgZOG7ryBsaeG7h3UuDQoNCg0KIyMjIDYuNS4gU3RhbmRhcmQgRXJyb3JzIGZvciAkXGhhdHtcYmV0YX0kDQoNCioqU2FpIHPhu5EgY2h14bqpbiBj4bunYSDGsOG7m2MgbMaw4bujbmcgJFxoYXR7XGJldGF9JCoqICANCsSQxrDhu6NjIHTDrW5oIHThu6sgbWEgdHLhuq1uIHRow7RuZyB0aW4gRmlzaGVyOg0KDQokJA0KXHRleHR7VmFyfShcaGF0e1xiZXRhfSkgPSBJKFxoYXR7XGJldGF9KV57LTF9DQokJA0KDQpTYWkgc+G7kSBjaHXhuqluIGNobyB04burbmcgdGhhbSBz4buRIGzDoCBjxINuIGLhuq1jIGhhaSBjw6FjIHBo4bqnbiB04butIHRyw6puIMSRxrDhu51uZyBjaMOpbyBj4bunYSBtYSB0cuG6rW4gbsOgeS4NCg0KDQojIyMgNi42LiBFc3RpbWF0aW9uIG9mICRcYmV0YSQ6IE1hdHJpeCBGb3JtdWxhdGlvbg0KDQoqKsav4bubYyBsxrDhu6NuZyAkXGJldGEkIGTGsOG7m2kgZOG6oW5nIG1hIHRy4bqtbioqICANCkPDoWNoIHRyw6xuaCBiw6B5IHRvw6FuIGjhu41jIGTDuW5nIG1hIHRy4bqtbiDEkeG7gyB0aHXhuq1uIHRp4buHbiB0w61uaCB0b8OhbiB24bubaSBk4buvIGxp4buHdSBs4bubbjoNCg0KJCQNClUoXGJldGEpID0gWF5UIFcgKHkgLSBcbXUpDQokJA0KDQpUcm9uZyDEkcOzOiAgDQotICRYJCBsw6AgbWEgdHLhuq1uIHRoaeG6v3Qga+G6vywgIA0KLSAkVyQgbMOgIG1hIHRy4bqtbiB0cuG7jW5nIHPhu5EsICANCi0gJFxtdSA9IGdeey0xfShYXGJldGEpJC4NCg0KDQojIyMgNi43LiBFc3RpbWF0aW9uIG9mIEdMTXMgSXMgTG9jYWxseSBMaWtlIExpbmVhciBSZWdyZXNzaW9uDQoNCioqxq/hu5tjIGzGsOG7o25nIEdMTSB0xrDGoW5nIHThu7EgaOG7k2kgcXV5IHR1eeG6v24gdMOtbmggY+G7pWMgYuG7mSoqICANCkvhu7kgdGh14bqtdCDGsOG7m2MgbMaw4bujbmcgR0xNIHRo4buxYyBjaOG6pXQgbMOgIGzhurdwIGzhuqFpIGPDoWMgYsaw4bubYyBo4buTaSBxdXkgdHV54bq/biB0w61uaCB24bubaSB0cuG7jW5nIHPhu5EgY+G6rXAgbmjhuq10IHThu6tuZyB2w7JuZywgZ+G7jWkgbMOgICpJdGVyYXRpdmVseSBSZXdlaWdodGVkIExlYXN0IFNxdWFyZXMgKElSTFMpKi4NCg0KIyMjIDYuOC4gRXN0aW1hdGluZyAkXHBoaSQg4oCUIMav4bubYyBsxrDhu6NuZyB0aGFtIHPhu5EgcGjDom4gdMOhbiAkXHBoaSQNCg0KVHJvbmcgR0xNLCB0aGFtIHPhu5EgcGjDom4gdMOhbiAkXHBoaSQgKGRpc3BlcnNpb24gcGFyYW1ldGVyKSBiaeG7g3UgdGjhu4sgbeG7qWMgxJHhu5kgYmnhur9uIMSR4buZbmcgbmdvw6BpIHBo4bqnbiBnaeG6o2kgdGjDrWNoIMSRxrDhu6NjIGLhu59pIG3DtCBow6xuaCB0dXnhur9uIHTDrW5oLiBW4bubaSBt4buZdCBz4buRIHBow6JuIHBo4buRaSAobmjGsCBHYXVzc2lhbiwgR2FtbWEpICRccGhpJCBsw6AgdGhhbSBz4buRIHF1YW4gdHLhu41uZyBj4bqnbiDEkcaw4bujYyDGsOG7m2MgbMaw4bujbmcgY2jDrW5oIHjDoWMuDQoNCiMjIyMgNi44LjEuIEdp4bubaSB0aGnhu4d1DQoNCiRccGhpJCBsw6AgdGhhbSBz4buRIMSRbyDEkeG7mSBwaMOibiB0w6FuICh2YXJpYW5jZSkgdHJvbmcgZ2lhIMSRw6xuaCBwaMOibiBwaOG7kWkgY+G7p2EgR0xNLCB0aOG7gyBoaeG7h24gbeG7qWMgxJHhu5kgcGjDom4gdMOhbiBj4bunYSBk4buvIGxp4buHdSBxdWFuaCBnacOhIHRy4buLIGvhu7MgduG7jW5nLg0KDQotIFbhu5tpIHBow6JuIHBo4buRaSAqKlBvaXNzb24qKiB2w6AgKipCZXJub3VsbGkqKiwgJFxwaGkkIHRoxrDhu51uZyDEkcaw4bujYyBjb2kgbMOgIGLhurFuZyAxLCBraMO0bmcgY+G6p24gxrDhu5tjIGzGsOG7o25nLg0KLSBW4bubaSBwaMOibiBwaOG7kWkgKipHYXVzc2lhbioqLCAkXHBoaSQgbMOgIHBoxrDGoW5nIHNhaSBj4bunYSBzYWkgc+G7kS4NCg0KIyMjIyA2LjguMi4gVGhlIE1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0b3Igb2YgJFxwaGkkICANCioqxq/hu5tjIGzGsOG7o25nICRccGhpJCB0aGVvIHBoxrDGoW5nIHBow6FwIE1MRSoqDQoNCkdp4bqjIHPhu60gY8OzICRuJCBxdWFuIHPDoXQsIHRoYW0gc+G7kSAkXGJldGEkIMSRw6MgxJHGsOG7o2MgxrDhu5tjIGzGsOG7o25nLiBIw6BtIGxvZy1saWtlbGlob29kIHBo4bulIHRodeG7mWMgdsOgbyAkXHBoaSQgxJHGsOG7o2MgZMO5bmcgxJHhu4MgdOG7kWkgxJFhIGjDs2EgdMOsbSAkXGhhdHtccGhpfSQuDQoNCk3hu5l0IGPDtG5nIHRo4bupYyBwaOG7lSBiaeG6v24gY2hvICRcaGF0e1xwaGl9X3tcdGV4dHtNTEV9fSQgbMOgOg0KDQokJA0KXGhhdHtccGhpfV97XHRleHR7TUxFfX0gPSBcZnJhY3sxfXtufSBcc3VtX3tpPTF9Xm4gZF9pDQokJA0KDQp0cm9uZyDEkcOzICRkX2kkIGzDoCAqdW5pdCBkZXZpYW5jZSogKMSR4buZIGzhu4djaCDEkcahbiB24buLKSBj4bunYSBxdWFuIHPDoXQgdGjhu6kgJGkkLCB0aOG7gyBoaeG7h24ga2hv4bqjbmcgY8OhY2ggZ2nhu69hIHF1YW4gc8OhdCB2w6AgZ2nDoSB0cuG7iyBr4buzIHbhu41uZyBtw7QgaMOsbmggZOG7sSDEkW/DoW4uDQoNCiMjIyMgNi44LjMuIE1vZGlmaWVkIFByb2ZpbGUgTG9nLUxpa2VsaWhvb2QgRXN0aW1hdG9yIG9mICRccGhpJCANCg0KKirGr+G7m2MgbMaw4bujbmcgZOG7sWEgdHLDqm4gbG9nLWxpa2VsaWhvb2QgaGnhu4d1IGNo4buJbmgqKg0KDQrEkOG7gyBj4bqjaSB0aGnhu4duIHTDrW5oIOG7lW4gxJHhu4tuaCB2w6AgdMOtbmggY2jDrW5oIHjDoWMgY+G7p2EgxrDhu5tjIGzGsOG7o25nLCBuZ8aw4budaSB0YSBkw7luZyAqcHJvZmlsZSBsaWtlbGlob29kKiDEkcOjIGNo4buJbmggc+G7rWEgKCptb2RpZmllZCBwcm9maWxlIGxvZy1saWtlbGlob29kKikuICANClBoxrDGoW5nIHBow6FwIG7DoHkgZ2nhuqNtICoqYmlhcyoqIHNvIHbhu5tpIE1MRS4NCg0KQ8O0bmcgdGjhu6ljIGPhu6UgdGjhu4MgcGjhu6ljIHThuqFwLCB0aMaw4budbmcgZOG7sWEgdHLDqm4gdmnhu4djIMSRaeG7gXUgY2jhu4luaCBow6BtIGxvZy1saWtlbGlob29kIHRoZW8gdGhhbSBz4buRICRcYmV0YSQgxJHDoyDEkcaw4bujYyDGsOG7m2MgbMaw4bujbmcuDQoNCiMjIyMgNi44LjQuIE1lYW4gRGV2aWFuY2UgRXN0aW1hdG9yIG9mICRccGhpJCAgDQoqKsav4bubYyBsxrDhu6NuZyBk4buxYSB0csOqbiDEkeG7mSBs4buHY2ggdHJ1bmcgYsOsbmgqKg0KDQpQaMawxqFuZyBwaMOhcCBuw6B5IHTDrW5oICRcaGF0e1xwaGl9JCBk4buxYSB0csOqbiDEkeG7mSBs4buHY2ggZMawIChyZXNpZHVhbCBkZXZpYW5jZSkgY2hpYSBjaG8gYuG6rWMgdOG7sSBkbyAoZGVncmVlcyBvZiBmcmVlZG9tKToNCg0KJCQNClxoYXR7XHBoaX1fe1x0ZXh0e2RldmlhbmNlfX0gPSBcZnJhY3tEfXtuIC0gcH0NCiQkDQoNClRyb25nIMSRw7M6DQoNCi0gJEQgPSBcc3VtX3tpPTF9Xm4gZF9pJCBsw6AgdOG7lW5nIMSR4buZIGzhu4djaCBkxrAsDQotICRuJCBsw6Agc+G7kSBxdWFuIHPDoXQsDQotICRwJCBsw6Agc+G7kSB0aGFtIHPhu5EgxJHGsOG7o2MgxrDhu5tjIGzGsOG7o25nICjEkeG7mSB04buxIGRvIGPhu6dhIG3DtCBow6xuaCkuDQoNCiMjIyMgNi44LjUuIFBlYXJzb24gRXN0aW1hdG9yIG9mICRccGhpJCAgDQoqKsav4bubYyBsxrDhu6NuZyBk4buxYSB0csOqbiByZXNpZHVhbHMgUGVhcnNvbioqDQoNCkTDuW5nIHThu5VuZyBiw6xuaCBwaMawxqFuZyBjw6FjIHJlc2lkdWFscyBjaHXhuqluIGjDs2EgUGVhcnNvbiBjaGlhIGNobyBi4bqtYyB04buxIGRvOg0KDQokJA0KXGhhdHtccGhpfV97XHRleHR7UGVhcnNvbn19ID0gXGZyYWN7MX17biAtIHB9IFxzdW1fe2k9MX1ebiBcZnJhY3soeV9pIC0gXGhhdHtcbXV9X2kpXjJ9e1YoXGhhdHtcbXV9X2kpfQ0KJCQNCg0KVHJvbmcgxJHDszoNCg0KLSAkeV9pJCBsw6AgcXVhbiBzw6F0IHRo4bupICRpJCwNCi0gJFxoYXR7XG11fV9pJCBsw6AgZ2nDoSB0cuG7iyBr4buzIHbhu41uZyB0aGVvIG3DtCBow6xuaCwNCi0gJFYoXGhhdHtcbXV9X2kpJCBsw6AgaMOgbSBwaMawxqFuZyBzYWkg4bupbmcgduG7m2kgbcO0IGjDrG5oICh2YXJpYW5jZSBmdW5jdGlvbikuDQoNCiMjIyMgNi44LjYuIFdoaWNoIEVzdGltYXRvciBvZiAkXHBoaSQgSXMgQmVzdD8gIA0KKipTbyBzw6FuaCB2w6AgbOG7sWEgY2jhu41uIMaw4bubYyBsxrDhu6NuZyB04buRdCBuaOG6pXQqKg0KDQotICRcaGF0e1xwaGl9X3tcdGV4dHtNTEV9fSQgbMOgIMaw4bubYyBsxrDhu6NuZyAqKnRoacOqbiB24buLIChiaWFzZWQpKiogbmjGsG5nICoqbmjhuqV0IHF1w6FuKiouDQotICRcaGF0e1xwaGl9X3tcdGV4dHtkZXZpYW5jZX19JCB2w6AgJFxoYXR7XHBoaX1fe1x0ZXh0e1BlYXJzb259fSQgdGjGsOG7nW5nIMSRxrDhu6NjIGTDuW5nIHRyb25nIHRo4buxYyB04bq/IHbDrCAqKmThu4UgdMOtbmgqKiB2w6AgY8OzIHTDrW5oIGNo4bqldCAqKmLhuqV0IGJp4bq/biB04buRdCBoxqFuKiouDQoNCkzhu7FhIGNo4buNbiBwaMawxqFuZyBwaMOhcCB0w7l5IHRoZW8gbeG7pWMgxJHDrWNoIHBow6JuIHTDrWNoIHbDoCDEkeG6t2MgxJFp4buDbSBk4buvIGxp4buHdS4NCg0KDQoNCiMjIENoxrDGoW5nIDc6IEluZmVyZW5jZSBhbmQgTW9kZWwgQXNzZXNzbWVudCDigJMgU3V5IGx14bqtbiB2w6AgxJHDoW5oIGdpw6EgbcO0IGjDrG5oDQoNCiMjIyA3LjEuIEdp4bubaSB0aGnhu4d1DQoNCkPDoWMgcGjGsMahbmcgcGjDoXAgc3V5IGx14bqtbiB0aOG7kW5nIGvDqiB0cm9uZyBHTE0sIGJhbyBn4buTbSBraeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dCwgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteSBjaG8gaOG7hyBz4buRIGjhu5NpIHF1eSB2w6AgZ2nDoSB0cuG7iyBr4buzIHbhu41uZywgdsOgIGPDoWMgcGjGsMahbmcgcGjDoXAgxJHDoW5oIGdpw6EgxJHhu5kgcGjDuSBo4bujcCBtw7QgaMOsbmguDQoNCiMjIyA3LjIuIEluZmVyZW5jZSBmb3IgQ29lZmZpY2llbnRzIFdoZW4g8J2cmSBJcyBLbm93bg0KDQpLaGkkXHBoaSTEkcOjIGJp4bq/dCAodsOtIGThu6UgdHJvbmcgbcO0IGjDrG5oIG5o4buLIHBow6JuIGhv4bq3YyBQb2lzc29uKSwgY8OhYyBraeG7g20gxJHhu4tuaCBzdXkgbHXhuq1uIMSRxrDhu6NjIHRo4buxYyBoaeG7h24gbmjGsCBzYXU6DQoNCiMjIyMgNy4yLjEuIFdhbGQgVGVzdHMgZm9yIFNpbmdsZSBSZWdyZXNzaW9uIENvZWZmaWNpZW50cw0KDQpLaeG7g20gxJHhu4tuaCBXYWxkIGNobyB04burbmcgaOG7hyBz4buRIGjhu5NpIHF1eSAkXGJldGFfaiQ6DQoNCiQkDQpaID0gXGZyYWN7XGhhdHtcYmV0YX1fan17U0UoXGhhdHtcYmV0YX1fail9IFxzaW0gTigwLDEpDQokJA0KDQpO4bq/dSAkfFp8ID4gel97XGFscGhhLzJ9JCwgYsOhYyBi4buPIGdp4bqjIHRodXnhur90ICRIXzA6IFxiZXRhX2ogPSAwJC4NCg0KU0UgbMOgIHNhaSBz4buRIGNodeG6qW4gY+G7p2EgJFxoYXR7XGJldGF9X2okLCBs4bqleSB04burIG1hIHRy4bqtbiBwaMawxqFuZyBzYWnigJNoaeG7h3AgcGjGsMahbmcgc2FpLg0KDQojIyMjIDcuMi4yLiBDb25maWRlbmNlIEludGVydmFscyBmb3IgSW5kaXZpZHVhbCBDb2VmZmljaWVudHMNCg0KS2hv4bqjbmcgdGluIGPhuq15IGNobyAkXGJldGFfaiQ6DQoNCiQkDQpcaGF0e1xiZXRhfV9qIFxwbSB6X3tcYWxwaGEvMn0gXGNkb3QgU0UoXGhhdHtcYmV0YX1faikNCiQkDQoNCiMjIyMgNy4yLjMuIENvbmZpZGVuY2UgSW50ZXJ2YWxzIGZvciDwnZyHDQoNCktob+G6o25nIHRpbiBj4bqteSBjaG8gJFxtdV9pID0gRVtZX2ldJDoNCg0Kxq/hu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteSBjaG8gJFxldGFfaSA9IHhfaV5UIFxoYXR7XGJldGF9JA0KDQpTYXUgxJHDsyBjaHV54buDbiBzYW5nICRcbXVfaSQgdGjDtG5nIHF1YSBow6BtIGxpw6puIGvhur90IG5naOG7i2NoIMSR4bqjbyAkZ157LTF9KFxjZG90KSQ6DQoNCiQkDQpnXnstMX1cbGVmdChcaGF0e1xldGF9X2kgXHBtIHpfe1xhbHBoYS8yfSBcY2RvdCBTRShcaGF0e1xldGF9X2kpXHJpZ2h0KQ0KJCQNCg0KIyMjIyA3LjIuNC4gTGlrZWxpaG9vZCBSYXRpbyBUZXN0cyB0byBDb21wYXJlIE5lc3RlZCBNb2RlbHM6IPCdnJLCsiBUZXN0cw0KDQpLaeG7g20gxJHhu4tuaCB04buJIHPhu5EgaOG7o3AgbMO9Og0KDQokJA0KXExhbWJkYSA9IC0yXGxlZnRbXGVsbChcaGF0e1xiZXRhfV97XHRleHR7cmVkdWNlZH19KSAtIFxlbGwoXGhhdHtcYmV0YX1fe1x0ZXh0e2Z1bGx9fSlccmlnaHRdIFxzaW0gXGNoaV4yX3tkZn0NCiQkDQoNClbhu5tpICRkZiQgbMOgIHPhu5EgdGhhbSBz4buRIGLhu4sgcsOgbmcgYnXhu5ljLg0KDQojIyMjIDcuMi41LiBBbmFseXNpcyBvZiBEZXZpYW5jZSBUYWJsZXMgdG8gQ29tcGFyZSBOZXN0ZWQgTW9kZWxzDQoNClBow6JuIHTDrWNoIHBoxrDGoW5nIHNhaToNCg0KJCQNClxEZWx0YSBEID0gRF97XHRleHR7cmVkdWNlZH19IC0gRF97XHRleHR7ZnVsbH19IFxzaW0gXGNoaV4yX3tkZn0NCiQkDQoNCiMjIyMgNy4yLjYuIFNjb3JlIFRlc3RzDQoNCkThu7FhIHRyw6puIMSR4bqhbyBow6BtIGLhuq1jIG5o4bqldCBj4bunYSBsb2ctbGlrZWxpaG9vZDoNCg0KJCQNClUoXGJldGFfMCleVCBJKFxiZXRhXzApXnstMX0gVShcYmV0YV8wKSBcc2ltIFxjaGleMl8xDQokJA0KDQojIyMgNy4zLiBMYXJnZSBTYW1wbGUgQXN5bXB0b3RpY3Mg4oCTIFRp4buHbSBj4bqtbiBt4bqrdSBs4bubbg0KDQpW4bubaSBrw61jaCB0aMaw4bubYyBt4bqrdSBs4bubbiwgY8OhYyDGsOG7m2MgbMaw4bujbmcgJFxoYXR7XGJldGF9JCB44bqlcCB44buJIHBow6JuIHBo4buRaSBjaHXhuqluLCBjaG8gcGjDqXAgZMO5bmcga2nhu4NtIMSR4buLbmggV2FsZCwgdOG7iSBz4buRIGjhu6NwIGzDvSB2w6Agc2NvcmUgdGVzdC4NCg0KIyMjIDcuNC4gR29vZG5lc3Mtb2YtRml0IFRlc3RzIHdpdGgg8J2cmSBLbm93bg0KDQojIyMjIDcuNC4xLiBUaGUgSWRlYSBvZiBHb29kbmVzcy1vZi1GaXQNCg0KU28gc8OhbmggbcO0IGjDrG5oIGThu7EgxJFvw6FuIHbhu5tpIGThu68gbGnhu4d1IHRo4buxYywga2nhu4NtIHRyYSBwaOG6p24gY8OybiBs4bqhaSBjw7MgcGjhuqNpIGzDoCBuaGnhu4V1IG5n4bqrdSBuaGnDqm4ga2jDtG5nLg0KDQojIyMjIDcuNC4yLiBEZXZpYW5jZSBHb29kbmVzcy1vZi1GaXQgVGVzdA0KDQpE4buxYSB0csOqbiB04buVbmcgZGV2aWFuY2U6DQoNCiQkDQpEIFxzaW0gXGNoaV4yX3tuIC0gcH0NCiQkDQoNCk7hur91ICREJCBxdcOhIGzhu5tuLCBtw7QgaMOsbmgga2jDtG5nIHBow7kgaOG7o3AuDQoNCiMjIyMgNy40LjMuIFBlYXJzb24gR29vZG5lc3Mtb2YtRml0IFRlc3QNCg0KROG7sWEgdHLDqm4gdGjhu5FuZyBrw6ogUGVhcnNvbjoNCg0KJCQNClheMiA9IFxzdW1fe2k9MX1ebiBcZnJhY3soeV9pIC0gXGhhdHtcbXV9X2kpXjJ9e1YoXGhhdHtcbXV9X2kpfSBcc2ltIFxjaGleMl97biAtIHB9DQokJA0KDQojIyMgNy41LiBTbWFsbCBEaXNwZXJzaW9uIEFzeW1wdG90aWNzDQoNCktoaSAkXHBoaSBccmlnaHRhcnJvdyAwJCwgR0xNIHjhuqVwIHjhu4kgbcO0IGjDrG5oIHjDoWMgxJHhu4tuaCwgcmVzaWR1YWxzIG5o4buPLCBraeG7g20gxJHhu4tuaCBt4bqhbmggaMahbi4NCg0KIyMjIDcuNi4gSW5mZXJlbmNlIGZvciBDb2VmZmljaWVudHMgV2hlbiDwnZyZIElzIFVua25vd24NCg0KIyMjIyA3LjYuMS4gV2FsZCBUZXN0cyBmb3IgU2luZ2xlIFJlZ3Jlc3Npb24gQ29lZmZpY2llbnRzDQoNCsSQaeG7gXUgY2jhu4luaCBTRSBi4bqxbmcgJFxoYXR7XHBoaX0kOg0KDQokJA0KdCA9IFxmcmFje1xoYXR7XGJldGF9X2p9e1xoYXR7XHBoaX0gXGNkb3QgXHRleHR7VmFyfShcaGF0e1xiZXRhfV9qKX0gXHNpbSB0X3tuIC0gcH0NCiQkDQoNCiMjIyMgNy42LjIuIENvbmZpZGVuY2UgSW50ZXJ2YWxzIGZvciBJbmRpdmlkdWFsIENvZWZmaWNpZW50cw0KDQokJA0KXGhhdHtcYmV0YX1faiBccG0gdF97XGFscGhhLzIsIG4gLSBwfSBcY2RvdCBcaGF0e1xwaGl9IFxjZG90IFx0ZXh0e1Zhcn0oXGhhdHtcYmV0YX1faikNCiQkDQoNCiMjIyMgNy42LjMuIExpa2VsaWhvb2QgUmF0aW8gVGVzdHMgdG8gQ29tcGFyZSBOZXN0ZWQgTW9kZWxzOiBGLVRlc3RzDQoNCiQkDQpGID0gXGZyYWN7KERfe1x0ZXh0e3JlZHVjZWR9fSAtIERfe1x0ZXh0e2Z1bGx9fSkvcX17XGhhdHtccGhpfX0gXHNpbSBGX3txLCBuIC0gcH0NCiQkDQoNClbhu5tpICRxJCBsw6Agc+G7kSBi4bqtYyB04buxIGRvIHRow6ptIHbDoG8uDQoNCg0KIyMjIDcuNy4gQ29tcGFyaW5nIFdhbGQsIFNjb3JlIGFuZCBMaWtlbGlob29kIFJhdGlvIFRlc3RzDQoNCi0gV2FsZCBk4buFIHTDrW5oIG5oxrBuZyBraMO0bmcgY2jDrW5oIHjDoWMgbuG6v3UgJFxoYXR7XGJldGF9JCBn4bqnbiBiacOqbi4NCi0gTGlrZWxpaG9vZCBSYXRpbyBt4bqhbmggdsOgIHBo4buVIHF1w6F0IGjGoW4uDQotIFNjb3JlIHBow7kgaOG7o3AgbuG6v3UgY2jhu4kgxrDhu5tjIGzGsOG7o25nIG3DtCBow6xuaCByw7p0IGfhu41uLg0KDQojIyBDaMawxqFuZyA4OiBHZW5lcmFsaXplZCBMaW5lYXIgTW9kZWxzOkRpYWdub3N0aWNzDQoNCiMjIyA4LjEgR2nhu5tpIHRoaeG7h3UgdsOgIFThu5VuZyBxdWFuDQoNCk3DtCBow6xuaCBHTE0gbeG7nyBy4buZbmcgaOG7k2kgcXV5IHR1eeG6v24gdMOtbmggY+G7lSDEkWnhu4NuIMSR4buDIHjhu60gbMO9IGPDoWMgZOG7ryBsaeG7h3UgY8OzIHBow6JuIHBo4buRaSBraMO0bmcgY2h14bqpbiBuaMawIG5o4buLIHBow6JuIChiaW5hcnkpLCDEkeG6v20gKGNvdW50KSwgdOG7tyBs4buHLC4uLiBWaeG7h2MgY2jhuqluIMSRb8OhbiBnacO6cCB4w6FjIMSR4buLbmggeGVtIG3DtCBow6xuaCBjw7MgcGjDuSBo4bujcCB24bubaSBk4buvIGxp4buHdSBoYXkga2jDtG5nLCB04burIMSRw7MgxJFp4buBdSBjaOG7iW5oIGhv4bq3YyBj4bqjaSB0aeG6v24gbcO0IGjDrG5oLg0KDQojIyMgOC4yLiBDw6FjIGdp4bqjIMSR4buLbmggY+G7p2EgR0xNcw0KLSBE4buvIGxp4buHdSAkeV9pJCDEkeG7mWMgbOG6rXAuDQoNCi0gJHlfaSQgdGh14buZYyBo4buNIHBow6JuIHBo4buRaSBow6BtIG3FqSAoRXhwb25lbnRpYWwgRmFtaWx5KS4NCg0KLSBDw7MgaMOgbSBsacOqbiBr4bq/dDogIA0KICAkJCANCiAgZyhcbXVfaSkgPSBcZXRhX2kgPSB4X2leVCBcYmV0YSANCiAgJCQNCg0KLSBQaMawxqFuZyBzYWkgcGjhu6UgdGh14buZYyB2w6BvIHRydW5nIGLDrG5oOiAgDQogICQkDQogIFx0ZXh0e1Zhcn0oWV9pKSA9IFxwaGkgVihcbXVfaSkNCiAgJCQNCg0KVHJvbmcgxJHDszogIA0KLSAkXHBoaSQ6IGjhu4cgc+G7kSBwaMOibiB0w6FuICgqZGlzcGVyc2lvbiBwYXJhbWV0ZXIqKS4gIA0KLSAkVihcbXVfaSkkOiBow6BtIHBoxrDGoW5nIHNhaSDEkeG6t2MgdHLGsG5nIGNobyB04burbmcgcGjDom4gcGjhu5FpLg0KDQojIyMgOC4zLiBDw6FjIGxv4bqhaSBwaOG6p24gZMawIChSZXNpZHVhbHMpDQoNCiMjIyMgOC4zLjEuIFBo4bqnbiBkxrAgcGjhuqNuIGjhu5NpIChSZXNwb25zZSByZXNpZHVhbHMpDQoNCiQkDQpyX2leeyhSKX0gPSB5X2kgLSBcaGF0e1xtdX1faQ0KJCQNCg0K4oaSIEtow7RuZyBjaHXhuqluIGjDs2EsIMOtdCDEkcaw4bujYyBkw7luZyB0cm9uZyBHTE1zIHbDrCBwaMawxqFuZyBzYWkgdGhheSDEkeG7lWkgdGhlbyAkXG11X2kkLg0KDQojIyMjIDguMy4yLiBQaOG6p24gZMawIFBlYXJzb24NCg0KJCQNCnJfaV57KFApfSA9IFxmcmFje3lfaSAtIFxoYXR7XG11fV9pfXtcc3FydHtcaGF0e1Z9KFxoYXR7XG11fV9pKX19DQokJA0KVHJvbmcgxJHDszoNCi0gJHlfaSQ6IGdpw6EgdHLhu4sgcXVhbiBzw6F0IHRo4buxYyB04bq/LiAgDQotICRcaGF0e1xtdX1faSQ6IGdpw6EgdHLhu4sgZOG7sSDEkW/DoW4gdOG7qyBtw7QgaMOsbmguICANCi0gJFxoYXR7Vn0oXGhhdHtcbXV9X2kpJDogcGjGsMahbmcgc2FpIGThu7EgxJFvw6FuIHThu6sgaMOgbSBwaMawxqFuZyBzYWkgY+G7p2EgR0xNLg0KDQrihpIgVGjDrWNoIGjhu6NwIMSR4buDIGtp4buDbSB0cmEgcGjGsMahbmcgc2FpIHbDoCBwaMOhdCBoaeG7h24gcXVhbiBzw6F0IGLhuqV0IHRoxrDhu51uZy4NCg0KIyMjIyA4LjMuMy4gUGjhuqduIGTGsCBEZXZpYW5jZQ0KDQokJA0Kcl9pXnsoRCl9ID0gXHRleHR7c2lnbn0oeV9pIC0gXGhhdHtcbXV9X2kpIFxjZG90IFxzcXJ0ezIgXGxlZnRbIFxlbGwoeV9pOyB5X2kpIC0gXGVsbCh5X2k7IFxoYXR7XG11fV9pKSBccmlnaHRdfQ0KJCQNCg0KVHJvbmcgxJHDsyAkXGVsbCh5X2k7IFxtdSkkIGzDoCBsb2ctbGlrZWxpaG9vZCDEkcahbi4NCg0K4oaSIMSQxrDhu6NjIGTDuW5nIHBo4buVIGJp4bq/biDEkeG7gyDEkcOhbmggZ2nDoSB04buVbmcgdGjhu4MgxJHhu5kgcGjDuSBo4bujcCBj4bunYSBtw7QgaMOsbmguDQoNCiMjIyMgOC4zLjQuIFBo4bqnbiBkxrAgUXVhbnRpbGUNCg0KJCQNCnJfaV57KFEpfSA9IFxQaGleey0xfSBcbGVmdCggRl97WV9pfSh5X2kgXG1pZCBcaGF0e1xtdX1faSwgXGhhdHtccGhpfSkgXHJpZ2h0KQ0KJCQNCg0KLSAkRl97WV9pfSQ6IGjDoG0gcGjDom4gcGjhu5FpIHTDrWNoIGzFqXkgKENERikgY+G7p2EgYmnhur9uIHBo4bqjbiBo4buTaS4gIA0KLSAkXFBoaV57LTF9JDogcGjDom4gcGjhu5FpIGNodeG6qW4gbmfGsOG7o2MgKGludmVyc2Ugc3RhbmRhcmQgbm9ybWFsIENERikuDQoNCuKGkiBO4bq/dSBtw7QgaMOsbmggxJHDum5nLCBjw6FjIHBo4bqnbiBkxrAgbsOgeSBjw7MgcGjDom4gcGjhu5FpIGNodeG6qW4uDQoNCiMjIyA4LjQuIEjhu4cgc+G7kSDhuqNuaCBoxrDhu59uZyAoTGV2ZXJhZ2UpDQoNCiMjIyMgOC40LjEuIEjhu4cgc+G7kSBsZXZlcmFnZSBoaeG7h3UgZOG7pW5nIChXb3JraW5nIGxldmVyYWdlKQ0KDQpMZXZlcmFnZSB04bqhaSDEkWnhu4NtICRpJCBsw6AgcGjhuqduIHThu60gxJHGsOG7nW5nIGNow6lvIGPhu6dhIG1hIHRy4bqtbiBtxakgKGhhdCBtYXRyaXgpLCBrw70gaGnhu4d1IGzDoCAkaF9pJC4NCg0KIyMjIyA4LjQuMi4gTWEgdHLhuq1uIG3FqSAoSGF0IG1hdHJpeCkNCg0KR0xNIGtow7RuZyBjw7MgY8O0bmcgdGjhu6ljIMSRw7NuZyBuaMawIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oLCBuaMawbmcgbuG6v3UgdHV54bq/biB0w61uaCBow7NhIG3DtCBow6xuaCB04bqhaSBixrDhu5tjIGzhurdwIGN14buRaSB0aMOsOg0KDQokJA0KSCA9IFdeezEvMn0gWCAoWF5UIFcgWCleey0xfSBYXlQgV157MS8yfQ0KJCQNCg0KVHJvbmcgxJHDszoNCg0KJCQNClc6IFx0ZXh0e21hIHRy4bqtbiB0cuG7jW5nIHPhu5EgKGRpYWdvbmFsKSB24bubaSB9IHdfaSA9IFxsZWZ0KCBcZnJhY3tkXG11X2l9e2RcZXRhX2l9IFxyaWdodCleMiAvIFYoXG11X2kpDQokJA0KDQrihpIgJGhfaSA9IEhfe2lpfSQNCg0KDQojIyMgOC41LiBQaOG6p24gZMawIGNodeG6qW4gaMOzYSB0aGVvIGxldmVyYWdlIChTdGFuZGFyZGl6ZWQgcmVzaWR1YWxzKQ0KDQokJA0Kcl97aSxcdGV4dHtzdGR9fSA9IFxmcmFje3JfaX17XHNxcnR7MSAtIGhfaX19DQokJA0KDQrihpIgRMO5bmcgxJHhu4MgcGjDoXQgaGnhu4duIG5nb+G6oWkgbOG7hyBjw7MgbGV2ZXJhZ2UgY2FvLg0KDQojIyMgOC42LiBLaGkgbsOgbyBkw7luZyBsb+G6oWkgcGjhuqduIGTGsCBuw6BvDQoNCnwgTG/huqFpIHBo4bqnbiBkxrAgfCBLaGkgbsOgbyBkw7luZyB8DQp8LS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLXwNCnwgUGVhcnNvbiAgICAgfCBLaeG7g20gdHJhIHBoxrDGoW5nIHNhaSwgcGjDoXQgaGnhu4duIGLhuqV0IHRoxrDhu51uZyB8DQp8IERldmlhbmNlICAgIHwgxJDDoW5oIGdpw6EgdOG7lW5nIHRo4buDIG3DtCBow6xuaCB8DQp8IFF1YW50aWxlICAgIHwgU28gc8OhbmggduG7m2kgY2h14bqpbiwgZMO5bmcgxJHhu4MgY2jhuqluIMSRb8OhbiB0cuG7sWMgcXVhbiB8DQp8IFJlc3BvbnNlICAgIHwgw410IGTDuW5nIHRyb25nIEdMTXMgfA0KDQoNCiMjIyA4LjcuIEtp4buDbSB0cmEgZ2nhuqMgxJHhu4tuaCBtw7QgaMOsbmgNCg0KIyMjIyA4LjcuMS4gS2nhu4NtIHRyYSB0w61uaCDEkeG7mWMgbOG6rXANCg0KVuG6vSBwaOG6p24gZMawIHRoZW8gxJHhu5kgdHLhu4UgJHJfaSQgdnMgJHJfe2ktMX0kLiAgDQrihpIgTuG6v3UgY8OzIG3huqt1LCBjw7MgdGjhu4MgY8OzIGhp4buHbiB0xrDhu6NuZyB04buxIHTGsMahbmcgcXVhbi4NCg0KIyMjIyA4LjcuMi4gS2nhu4NtIHRyYSB0aMOgbmggcGjhuqduIGjhu4cgdGjhu5FuZw0KDQpW4bq9ICRyX2kkIHRoZW8gY8OhYyBiaeG6v24gZOG7sSBiw6FvIChwcmVkaWN0b3JzKSDEkeG7gyBwaMOhdCBoaeG7h24gZOG6oW5nIHNhaSBow6BtIGxpw6puIGvhur90IGhv4bq3YyB0aGnhur91IGJp4bq/bi4NCg0KIyMjIyA4LjcuMy4gS2nhu4NtIHRyYSB0aMOgbmggcGjhuqduIG5n4bqrdSBuaGnDqm4NCg0KVuG6vSBwaOG6p24gZMawIGNodeG6qW4gaMOzYSB2cyBnacOhIHRy4buLIGThu7EgxJFvw6FuICRcaGF0e1xtdX1faSQuICANCuKGkiBO4bq/dSBwaMOibiBi4buRIGjDrG5oIHF14bqhdCDihpIgY8OzIGhp4buHbiB0xrDhu6NuZyBwaMawxqFuZyBzYWkga2jDtG5nIMSR4buTbmcgbmjhuqV0Lg0KDQojIyMgOC44LiBOZ2/huqFpIGzhu4cgdsOgIHF1YW4gc8OhdCDhuqNuaCBoxrDhu59uZw0KDQojIyMjIDguOC4xLiBQaOG6p24gZMawIFN0dWRlbnRpemVkDQoNCiQkDQp0X2kgPSBcZnJhY3tyX2l9e1xoYXR7XHNpZ21hfSBcc3FydHsxIC0gaF9pfX0NCiQkDQoNCuKGkiBO4bq/dSAkfHRfaXwgPiAyJCwgY8OzIHRo4buDIGzDoCBuZ2/huqFpIGzhu4cuDQoNCiMjIyMgOC44LjIuIMSQaeG7g20g4bqjbmggaMaw4bufbmcgbOG7m24gKEluZmx1ZW50aWFsIG9ic2VydmF0aW9ucykNCg0KQ29va+KAmXMgRGlzdGFuY2U6DQoNCiQkDQpEX2kgPSBcZnJhY3tyX2leMn17cCBcY2RvdCBcaGF0e1xzaWdtYX1eMn0gXGNkb3QgXGZyYWN7aF9pfXsoMSAtIGhfaSleMn0NCiQkDQoNCuKGkiBO4bq/dSAkRF9pID4gMSQgaG/hurdjIGzhu5tuIGLhuqV0IHRoxrDhu51uZyBzbyB24bubaSBwaOG6p24gY8OybiBs4bqhaSDih5IgxJFp4buDbSDhuqNuaCBoxrDhu59uZyBt4bqhbmguDQoNCg0KIyMjIDguOS4gQ8OhY2ggeOG7rSBsw70gduG6pW4gxJHhu4ENCg0KLSBUaGF5IMSR4buVaSBow6BtIGxpw6puIGvhur90ICh2w60gZOG7pTogdOG7qyBsb2cgc2FuZyBsb2dpdCkuDQotIEJp4bq/biDEkeG7lWkgYmnhur9uIMSR4bqndSB2w6BvIGhv4bq3YyDEkeG6p3UgcmEgKGxvZywgc3F1YXJlIHJvb3QsLi4uKS4NCi0gVGhheSBtw7QgaMOsbmgga2jDoWMgKE5lZ2F0aXZlIEJpbm9taWFsIHRoYXkgdsOsIFBvaXNzb24pLg0KLSBMb+G6oWkgYuG7jyBob+G6t2MgZ+G7mXAgY8OhYyDEkWnhu4NtIG5nb+G6oWkgbOG7hyBu4bq/dSBo4bujcCBsw70gduG7gSBt4bq3dCBk4buvIGxp4buHdS4NCg0KDQojIyMgOC4xMC4gUXVhc2ktbGlrZWxpaG9vZCB2w6AgRXh0ZW5kZWQgUXVhc2ktbGlrZWxpaG9vZA0KDQpLaGkgcGjDom4gcGjhu5FpIGPhu6dhICRZJCBraMO0bmcgdGh14buZYyBo4buNIGV4cG9uZW50aWFsIG5oxrBuZyB24bqrbiBtdeG7kW4gZMO5bmcgR0xNOg0KDQokJA0KXHRleHR7VmFyfShZX2kpID0gXHBoaSBWKFxtdV9pKQ0KJCQNCg0K4oaSIEtow7RuZyBj4bqnbiBnaeG6oyDEkeG7i25oIGjDoG0gbeG6rXQgxJHhu5kgeMOhYyBzdeG6pXQgY+G7pSB0aOG7gywgbmjGsG5nIHbhuqtuIMaw4bubYyBsxrDhu6NuZyDEkcaw4bujYyB0aMO0bmcgcXVhIHBoxrDGoW5nIHBow6FwIHF1YXNpLWxpa2VsaWhvb2QuDQoNCg0KIyMjIDguMTEuIMSQYSBj4buZbmcgdHV54bq/biAoQ29sbGluZWFyaXR5KQ0KDQpLaeG7g20gdHJhIGLhurFuZyBWSUYg4oCTIFZhcmlhbmNlIEluZmxhdGlvbiBGYWN0b3I6DQoNCiQkDQpcdGV4dHtWSUZ9X2ogPSBcZnJhY3sxfXsxIC0gUl9qXjJ9DQokJA0KDQrihpIgTuG6v3UgJFx0ZXh0e1ZJRn0gPiA1JCBob+G6t2MgJD4gMTAkIHRow6wgY8OzIHRo4buDIGPDsyDEkWEgY+G7mW5nIHR1eeG6v24gbmdoacOqbSB0cuG7jW5nLg0KDQojIyBDaMawxqFuZyA5OiBNb2RlbHNmb3JQcm9wb3J0aW9uczpCaW5vbWlhbEdMTXMNCg0KIyMjIDkuMS4gR2nhu5tpIFRoaeG7h3UNCg0KTcO0IGjDrG5oIHThu7cgbOG7hyBsw6AgbeG7mXQgZOG6oW5nIMSR4bq3YyBiaeG7h3QgY+G7p2EgR0xNIGtoaSBiaeG6v24gcGjhu6UgdGh14buZYyBiaeG7g3UgZGnhu4VuIGThu68gbGnhu4d1IGTGsOG7m2kgZOG6oW5nIHThu7cgc+G7kSBob+G6t2MgdOG7tyBs4buHLCDEkcaw4bujYyBtw7QgaMOsbmggaMOzYSBi4bqxbmcgcGjDom4gcGjhu5FpIG5o4buLIHBow6JuIChiaW5vbWlhbCkuDQoNCiMjIyA5LjIuIE3DtCBIw6xuaCBU4bu3IEzhu4cNCg0KLSBE4buvIGxp4buHdSBn4buTbSBjw6FjIGPhurdwIChz4buRIGzhuqduIHRow6BuaCBjw7RuZywgc+G7kSBs4bqnbiB0aOG7rSBuZ2hp4buHbSkuDQotIFBow6JuIHBo4buRaTogQmlub21pYWwuDQotIEjDoG0gbGnDqm4ga+G6v3QgKHR14buzIHRoZW8gbGluayk6IGxvZ2l0LCBwcm9iaXQsIGNvbXBsZW1lbnRhcnkgbG9nLWxvZywgLi4uDQoNCiMjIyA5LjMuIEjDoG0gTGnDqm4gS+G6v3QgKExpbmsgRnVuY3Rpb25zKQ0KDQotICoqTG9naXQqKjogJGcoXG11KSA9IFxsb2dcbGVmdChcZnJhY3tcbXV9ezEgLSBcbXV9XHJpZ2h0KSQNCi0gKipQcm9iaXQqKjogJGcoXG11KSA9IFxQaGleey0xfShcbXUpJCAoaMOgbSBuZ2jhu4tjaCDEkeG6o28gY+G7p2EgQ0RGIGNodeG6qW4pLg0KLSAqKkNvbXBsZW1lbnRhcnkgTG9nLUxvZyoqOiAkZyhcbXUpID0gXGxvZygtXGxvZygxIC0gXG11KSkkDQoNCiMjIyA5LjQuIFBow6JuIFBo4buRaSBEdW5nIFNhaSAmIExpw6puIEvhur90IFByb2JpdA0KDQotIEThu7FhIHRyw6puIGdp4bqjIMSR4buLbmg6IGPDoSBuaMOibiBjw7MgbmfGsOG7oW5nIGR1bmcgc2FpLg0KLSBYw6FjIHN14bqldCB0aMOgbmggY8O0bmc6ICRQKFkgPSAxIFxtaWQgeCkgPSBcUGhpKHheVFxiZXRhKSQNCg0KIyMjIDkuNS4gT2RkcywgT2RkcyBSYXRpbyAmIExvZ2l0DQoNCi0gVOG7tyBs4buHIHRow6BuaCBjw7RuZzogJFxtdSQsIHThu7cgc+G7kSBvZGRzOiAkXGRmcmFje1xtdX17MSAtIFxtdX0kDQotIE9kZHMgcmF0aW86ICRcZGZyYWN7XG11XzEvKDEgLSBcbXVfMSl9e1xtdV8wLygxIC0gXG11XzApfSQNCi0gSMOgbSBsb2dpdCBnacO6cCB0dXnhur9uIHTDrW5oIGhvw6Egb2RkcyByYXRpbzogJFxsb2dcbGVmdChcZGZyYWN7XG11fXsxIC0gXG11fVxyaWdodCkgPSB4XlQgXGJldGEkDQoNCiMjIyA5LjYuIExp4buBdSBUcnVuZyBW4buLIEhp4buHdSBRdeG6oyAoRUQ1MCkNCg0KLSAkRURfezUwfSQ6IG3hu6ljICR4JCBzYW8gY2hvICRcbXUgPSAwLjUkDQotIFTDrW5oIHThu6sgaMOgbSBuZ2jhu4tjaDogJHggPSBnXnstMX0oMC41KSQNCg0KIyMjIDkuNy4gTGnDqm4gS+G6v3QgQ29tcGxlbWVudGFyeSBMb2ctTG9nDQoNCi0gRMO5bmcga2hpIHjDoWMgc3XhuqV0IHLhuqV0IGfhuqduIDAgaG/hurdjIDEuDQotIFThu7cgbOG7hyBwaMO5IGjhu6NwIGNobyBtw7QgaMOsbmggbOG6pXkgbeG6q3UgZOG6oW5nICoqYXNzYXkgc2luaCBo4buNYyoqLg0KDQojIyMgOS44LiBPdmVyZGlzcGVyc2lvbg0KDQotIEtoaSBiaeG6v24gcGjhu6UgdGh14buZYyBiaeG6v24gdGhpw6puIG5oaeG7gXUgaMahbiBtb25nIMSR4bujaSBj4bunYSBCaW5vbWlhbC4NCi0gR2nhuqNpIHBow6FwOiBz4butIGThu6VuZyBwaMOibiBwaOG7kWkgKipxdWFzaWJpbm9taWFsKiosIHNhaSBz4buRIHPhur0gbOG7m24gaMahbi4NCi0gRXN0aW1hdG9yOiDEkWnhu4F1IGNo4buJbmggcGjGsMahbmcgc2FpIHbhu5tpIGjhu4cgc+G7kSBwaMOibiB0w6FuICRccGhpJC4NCg0KIyMjIDkuOS4gS2hpIFdhbGQgVGVzdHMgVGjhuqV0IELhuqFpDQoNCi0gS2hpIMaw4bubYyBsxrDhu6NuZyAkXGhhdHtcYmV0YX0kIGPDsyBwaOG6p24gYuG7lW5nLCBzdGFuZGFyZCBlcnJvciBjYW8uDQotIEdp4bqjaSBwaMOhcDogZMO5bmcgKipMaWtlbGlob29kIFJhdGlvIFRlc3QqKiBob+G6t2MgKipTY29yZSBUZXN0KiogdGhheSB0aOG6vy4NCg0KIyMjIDkuMTAuIE3hu58gUuG7mW5nOiBUaGnhur91IEtp4buDbSDEkOG7i25oIEdvb2RuZXNzLW9mLUZpdA0KDQotIEtoaSBk4buvIGxp4buHdSBjaOG7iSBsw6AgMC8xLCBraMO0bmcgdGjhu4MgxJHDoW5oIGdpw6EgY2hpIHRp4bq/dCBt4bupYyDEkeG7mSBwaMO5IGjhu6NwLg0KLSBDaOG7iSBraeG7g20gxJHhu4tuaCB0aMO0bmcgcXVhIGPDoWMgdGnDqnUgY2jDrTogQUlDLCBCSUMsIGRldmlhbmNlLg0KDQojIyBDaMawxqFuZyAxMDogTW9kZWxzIGZvciBDb3VudHM6UG9pc3NvbiBhbmQgTmVnYXRpdmUgQmlub21pYWwgR0xNcw0KIyMjIDEwLjEuIEdp4bubaSB0aGnhu4d1DQpDaMawxqFuZyBuw6B5IHThuq1wIHRydW5nIHbDoG8gdmnhu4djIG3DtCBow6xuaCBow7NhIGThu68gbGnhu4d1IMSR4bq/bSAoY291bnQgZGF0YSkgYuG6sW5nIGPDoWNoIHPhu60gZOG7pW5nIE3DtCBow6xuaCBUdXnhur9uIHTDrW5oIFThu5VuZyBxdcOhdCAoR0xNcykgduG7m2kgcGjDom4gcGjhu5FpIFBvaXNzb24gdsOgIE5lZ2F0aXZlIEJpbm9taWFsLiDEkMOieSBsw6Agbmjhu69uZyBjw7RuZyBj4bulIG3huqFuaCBt4bq9IMSR4buDIHBow6JuIHTDrWNoIGPDoWMgYmnhur9uIHBo4bqjbiBo4buTaSBy4budaSBy4bqhYywgY2jhurNuZyBo4bqhbiBuaMawIHPhu5EgbOG6p24geOG6o3kgcmEgc+G7sSBraeG7h24gdHJvbmcgbeG7mXQga2hv4bqjbmcgdGjhu51pIGdpYW4gaG/hurdjIGtow7RuZyBnaWFuIG5o4bqldCDEkeG7i25oLg0KDQojIyMgMTAuMi4gVMOzbSB04bqvdCB24buBIFBvaXNzb24gR0xNcw0KDQpDw7RuZyB0aOG7qWMgbcO0IGjDrG5oIFBvaXNzb246DQoNCiQkDQpcbG9nKFxtdV9pKSA9IFxhbHBoYSArIFxiZXRhXzEgeF97MWl9ICsgXGJldGFfMiB4X3syaX0gKyBcY2RvdHMgKyBcYmV0YV9wIHhfe3BpfQ0KJCQNCg0KQ8O0bmcgdGjhu6ljIG3DtCBow6xuaCBQb2lzc29uIHbhu5tpIGJp4bq/biBvZmZzZXQgKGtoaSBtw7QgaMOsbmggaMOzYSB04bu3IGzhu4cpOg0KJCQNClxsb2coXG11X2kpID0gXGFscGhhICsgXGJldGFfMSB4X3sxaX0gKyBcY2RvdHMgKyBcYmV0YV9wIHhfe3BpfSArIFxsb2codF9pKQ0KJCQNCg0KVHJvbmcgxJHDszogJHRfaSQ6IEJp4bq/biAqb2Zmc2V0KiwgdGjGsOG7nW5nIMSR4bqhaSBkaeG7h24gY2hvIHRo4budaSBnaWFuIHF1YW4gc8OhdCBob+G6t2MgbeG7qWMgxJHhu5kgcGjGoWkgbmhp4buFbSAoZXhwb3N1cmUpIGPhu6dhIHF1YW4gc8OhdCB0aOG7qSAkaSQuDQoNCiMjIyAxMC4zLiBNw7QgaMOsbmggaMOzYSBU4bu3IGzhu4cNCktoaSBk4buvIGxp4buHdSDEkeG6v20gbGnDqm4gcXVhbiDEkeG6v24gY8OhYyBraG/huqNuZyB0aOG7nWkgZ2lhbiBob+G6t2Mga2jDtG5nIGdpYW4ga2jDoWMgbmhhdSwgdmnhu4djIHPhu60gZOG7pW5nIGJp4bq/biBvZmZzZXQgZ2nDunAgxJFp4buBdSBjaOG7iW5oIG3DtCBow6xuaCDEkeG7gyBwaOG6o24gw6FuaCB04bu3IGzhu4cgeOG6o3kgcmEgc+G7sSBraeG7h24uDQoNCkPDtG5nIHRo4bupYyBtw7QgaMOsbmggaMOzYSB04bu3IGzhu4c6DQoNCiQkDQpcbG9nXGxlZnQoXGZyYWN7XG11X2l9e3RfaX1ccmlnaHQpID0gXGFscGhhICsgXGJldGFfMSB4X3sxaX0gKyBcY2RvdHMgKyBcYmV0YV9wIHhfe3BpfQ0KJCQNClRyb25nIMSRw7M6ICRcZnJhY3tcbXVfaX17dF9pfSQ6IFThu7cgbOG7hyBr4buzIHbhu41uZyBj4bunYSBz4buxIGtp4buHbiB0csOqbiDEkcahbiB24buLIHRo4budaSBnaWFuIGhv4bq3YyBraMO0bmcgZ2lhbi4NCg0KIyMjIDEwLjQuQuG6o25nIFThuqduIHPhu5Eg4oCTIE3DtCBow6xuaCBMb2ctTGluZWFyDQoNCiMjIyMgMTAuNC4xLiBHaeG7m2kgdGhp4buHdQ0KTcO0IGjDrG5oIGxvZy1saW5lYXIgxJHGsOG7o2Mgc+G7rSBk4bulbmcgxJHhu4MgcGjDom4gdMOtY2ggY8OhYyBi4bqjbmcgdOG6p24gc+G7kSwgbsahaSB04bqldCBj4bqjIGPDoWMgYmnhur9uIMSR4buBdSBsw6AgYmnhur9uIHBow6JuIGxv4bqhaS4gVHJvbmcgbcO0IGjDrG5oIG7DoHksIGJp4bq/biBwaOG6o24gaOG7k2kgbMOgIHPhu5EgxJHhur9tIHRyb25nIG3hu5dpIMO0IGPhu6dhIGLhuqNuZywgdsOgIGPDoWMgYmnhur9uIGdp4bqjaSB0aMOtY2ggbMOgIGPDoWMgeeG6v3UgdOG7kSBwaMOibiBsb+G6oWkuDQoNCiMjIyMgMTAuNC4yLiBC4bqjbmcgSGFpIENoaeG7gXU6IFRow6BuaCBwaOG6p24gSOG7hyB0aOG7kW5nDQpYw6l0IGLhuqNuZyB04bqnbiBz4buRIGhhaSBjaGnhu4F1IHbhu5tpIGPDoWMgYmnhur9uIHBow6JuIGxv4bqhaSBcKCBBIFwpIHbDoCBcKCBCIFwpLCBz4buRIMSR4bq/bSB0cm9uZyDDtCBcKChpLCBqKVwpIMSRxrDhu6NjIGvDvSBoaeG7h3UgbMOgIFwoIG5fe2lqfSBcKS4gTcO0IGjDrG5oIGxvZy1saW5lYXIgY8OzIGThuqFuZzoNCiQkDQpcbG9nKFxtdV97aWp9KSA9IFxsYW1iZGEgKyBcbGFtYmRhX2leQSArIFxsYW1iZGFfal5CICsgXGxhbWJkYV97aWp9XntBQn0NCiQkDQpUcm9uZyDEkcOzOg0KDQokXG11X3tpan0gOiBcdGV4dHtL4buzIHbhu41uZyBj4bunYSBz4buRIMSR4bq/bSB0cm9uZyDDtCB9IChpLCBqKS4kDQoNCiRcbGFtYmRhIDogXHRleHR7SOG6sW5nIHPhu5EgY2h1bmcgKGludGVyY2VwdCkufSQNCg0KJFxsYW1iZGFfaV5BIDogXHRleHR7SGnhu4d1IOG7qW5nIGNow61uaCBj4bunYSBt4bupYyB0aOG7qSB9IGkgXHRleHR7IGPhu6dhIGJp4bq/biB9IEEuJA0KDQokXGxhbWJkYV9qXkIgOiBcdGV4dHtIaeG7h3Ug4bupbmcgY2jDrW5oIGPhu6dhIG3hu6ljIHRo4bupIH0gaiBcdGV4dHsgY+G7p2EgYmnhur9uIH0gQi4kDQoNCiRcbGFtYmRhX3tpan1ee0FCfSA6IFx0ZXh0e0hp4buHdSDhu6luZyB0xrDGoW5nIHTDoWMgZ2nhu69hIG3hu6ljIH0gaSBcdGV4dHsgY+G7p2EgfSBBIFx0ZXh0eyB2w6AgbeG7qWMgfSBqIFx0ZXh0eyBj4bunYSB9IEIuJA0KDQpO4bq/dSANCiRcbGFtYmRhX3tpan1ee0FCfSA9IDAgXHF1YWQgXHRleHR7Y2hvIG3hu41pIH0gaSwgaiwkdGjDrCBtw7QgaMOsbmggYmnhu4N1IHRo4buLIHPhu7EgxJHhu5ljIGzhuq1wIGdp4buvYSBcKCBBIFwpIHbDoCBcKCBCIFwpLg0KDQoNCiMjIyMgMTAuNC4zLiBC4bqjbmcgSGFpIENoaeG7gXU6IFRow6BuaCBwaOG6p24gTmfhuqt1IG5oacOqbg0KVHJvbmcgbcO0IGjDrG5oIGxvZy1saW5lYXIsIGdp4bqjIMSR4buLbmggcuG6sW5nIGPDoWMgc+G7kSDEkeG6v20gXCggbl97aWp9IFwpIHR1w6JuIHRoZW8gcGjDom4gcGjhu5FpIFBvaXNzb24gduG7m2kga+G7syB24buNbmcgXCggXG11X3tpan0gXCk6DQogIA0KJCRuX3tpan0gXHNpbSBcdGV4dHtQb2lzc29ufShcbXVfe2lqfSkkJA0KxJBp4buBdSBuw6B5IGNobyBwaMOpcCBz4butIGThu6VuZyBtw7QgaMOsbmggdHV54bq/biB0w61uaCB04buVbmcgcXXDoXQgKEdMTSkgduG7m2kgaMOgbSBsacOqbiBr4bq/dCBsb2cgxJHhu4MgxrDhu5tjIGzGsOG7o25nIGPDoWMgdGhhbSBz4buRLg0KDQojIyMjIDEwLjQuNC4gQuG6o25nIEJhIENoaeG7gXUNCktoaSBt4bufIHLhu5luZyBzYW5nIGLhuqNuZyBiYSBjaGnhu4F1IHbhu5tpIGPDoWMgYmnhur9uIEEsIEIsIEMsIG3DtCBow6xuaCBsb2ctbGluZWFyIGPDsyB0aOG7gyBiYW8gZ+G7k20gY8OhYyBoaeG7h3Ug4bupbmcgY2jDrW5oIHbDoCB0xrDGoW5nIHTDoWMgaGFpIGNoaeG7gXUsIGJhIGNoaeG7gXU6DQoNCiQkXGxvZyhcbXVfe2lqa30pID0gXGxhbWJkYSArIFxsYW1iZGFfaV5BICsgXGxhbWJkYV9qXkIgKyBcbGFtYmRhX2teQyArIFxsYW1iZGFfe2lqfV57QUJ9ICsgXGxhbWJkYV97aWt9XntBQ30gKyBcbGFtYmRhX3tqa31ee0JDfSArIFxsYW1iZGFfe2lqa31ee0FCQ30kJA0KVHJvbmcgxJHDszoNCg0KJFxtdV97aWprfSA6IFx0ZXh0e0vhu7MgduG7jW5nIGPhu6dhIHPhu5EgxJHhur9tIHRyb25nIMO0IH0gKGksaixrKS4kDQoNCiRcbGFtYmRhX3tpamt9XntBQkN9IDogXHRleHR7SGnhu4d1IOG7qW5nIHTGsMahbmcgdMOhYyBiYSBjaGnhu4F1IGdp4buvYSBjw6FjIG3hu6ljIH0gaSwgaiwgayBcdGV4dHsgY+G7p2EgY8OhYyBiaeG6v24gfSBBLCBCLCBDLiQNCg0KVmnhu4djIGJhbyBn4buTbSBob+G6t2MgbG/huqFpIGLhu48gY8OhYyBoaeG7h3Ug4bupbmcgdMawxqFuZyB0w6FjIGNobyBwaMOpcCBraeG7g20gdHJhIGPDoWMgZ2nhuqMgdGh1eeG6v3QgduG7gSBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGPDoWMgYmnhur9uLg0KDQojIyMjIDEwLjQuNS4gTmdo4buLY2ggbMO9IFNpbXBzb24NCk5naOG7i2NoIGzDvSBTaW1wc29uIHjhuqN5IHJhIGtoaSBt4buZdCB4dSBoxrDhu5tuZyB4deG6pXQgaGnhu4duIHRyb25nIHThu6tuZyBuaMOzbSBjb24gY+G7p2EgZOG7ryBsaeG7h3UgbmjGsG5nIGJp4bq/biBt4bqldCBob+G6t2MgxJHhuqNvIG5nxrDhu6NjIGtoaSBjw6FjIG5ow7NtIMSRxrDhu6NjIGvhur90IGjhu6NwLiBUcm9uZyBuZ+G7ryBj4bqjbmggbcO0IGjDrG5oIGxvZy1saW5lYXIsIMSRaeG7gXUgbsOgeSBuaOG6pW4gbeG6oW5oIHThuqdtIHF1YW4gdHLhu41uZyBj4bunYSB2aeG7h2MgeGVtIHjDqXQgY8OhYyB0xrDGoW5nIHTDoWMgZ2nhu69hIGPDoWMgYmnhur9uIMSR4buDIHRyw6FuaCByw7p0IHJhIGvhur90IGx14bqtbiBzYWkgbOG6p20gdOG7qyBk4buvIGxp4buHdSB04buVbmcgaOG7o3AuDQoNClbDrSBk4bulLCB0cm9uZyBt4buZdCBuZ2hpw6puIGPhu6l1IHbhu4EgdHV54buDbiBzaW5oIMSR4bqhaSBo4buNYywgY8OzIHRo4buDIHRo4bqleSBy4bqxbmcgdOG7tyBs4buHIGNo4bqlcCBuaOG6rW4gY+G7p2EgbmFtIGNhbyBoxqFuIG7hu68gdOG7lW5nIHRo4buDLCBuaMawbmcga2hpIHBow6JuIHTDrWNoIHRoZW8gdOG7q25nIGtob2EsIHThu7cgbOG7hyBjaOG6pXAgbmjhuq1uIGPhu6dhIG7hu68gbOG6oWkgY2FvIGjGoW4gdHJvbmcgaOG6p3UgaOG6v3QgY8OhYyBraG9hLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSBz4buxIGPhuqduIHRoaeG6v3QgY+G7p2Egdmnhu4djIG3DtCBow6xuaCBow7NhIGPDoWMgdMawxqFuZyB0w6FjIGdp4buvYSBnaeG7m2kgdMOtbmggdsOgIGtob2EgxJHhu4MgaGnhu4N1IMSRw7puZyBi4bqjbiBjaOG6pXQgY+G7p2EgZOG7ryBsaeG7h3UuDQoNCiMjIyMgMTAuNC42LiBUxrDGoW5nIMSRxrDGoW5nIGdp4buvYSBNw7QgaMOsbmggQmlub21pYWwgdsOgIFBvaXNzb24gR0xNcw0KVHJvbmcgbeG7mXQgc+G7kSB0csaw4budbmcgaOG7o3AsIG3DtCBow6xuaCBsb2ctbGluZWFyIFBvaXNzb24gY8OzIHRo4buDIHTGsMahbmcgxJHGsMahbmcgduG7m2kgbcO0IGjDrG5oIGjhu5NpIHF1eSBsb2dpc3RpYyAoQmlub21pYWwgR0xNKSwgxJHhurdjIGJp4buHdCBraGkgcGjDom4gdMOtY2ggYuG6o25nIHThuqduIHPhu5EgaGFpIGNoaeG7gXUuIEPhu6UgdGjhu4MsIGtoaSBtw7QgaMOsbmggaMOzYSB4w6FjIHN14bqldCB0aMOgbmggY8O0bmcgdHJvbmcgbeG7l2kgw7QgY+G7p2EgYuG6o25nLCBtw7QgaMOsbmggbG9nLWxpbmVhciB24bubaSBwaMOibiBwaOG7kWkgUG9pc3NvbiB2w6AgaMOgbSBsacOqbiBr4bq/dCBsb2cgY8OzIHRo4buDIGN1bmcgY+G6pXAga+G6v3QgcXXhuqMgdMawxqFuZyDEkcawxqFuZyB24bubaSBtw7QgaMOsbmggbG9naXN0aWMgduG7m2kgcGjDom4gcGjhu5FpIG5o4buLIHRo4bupYyB2w6AgaMOgbSBsacOqbiBr4bq/dCBsb2dpdC4NCg0KIyMjIyAxMC40LjcuIELhuqNuZyBi4bqtYyBjYW8gaMahbg0KTcO0IGjDrG5oIGxvZy1saW5lYXIgY8OzIHRo4buDIMSRxrDhu6NjIG3hu58gcuG7mW5nIMSR4buDIHBow6JuIHTDrWNoIGPDoWMgYuG6o25nIHThuqduIHPhu5EgduG7m2kgbmhp4buBdSBoxqFuIGJhIGNoaeG7gXUgKGLhuqNuZyBi4bqtYyBjYW8gaMahbikuIFZp4buHYyB4w6J5IGThu7FuZyBtw7QgaMOsbmggYmFvIGfhu5NtIGPDoWMgaGnhu4d1IOG7qW5nIGNow61uaCB2w6AgdMawxqFuZyB0w6FjIGdp4buvYSBjw6FjIGJp4bq/biwgdMO5eSB0aHXhu5ljIHbDoG8gZ2nhuqMgdGh1eeG6v3QgbmdoacOqbiBj4bupdSB2w6AgY+G6pXUgdHLDumMgY+G7p2EgZOG7ryBsaeG7h3UuDQoNCiMjIyMgMTAuNC44LiBT4buRIGtow7RuZyBj4bqldSB0csO6YyB0cm9uZyBi4bqjbmcgdOG6p24gc+G7kQ0KVHJvbmcgbeG7mXQgc+G7kSBi4bqjbmcgdOG6p24gc+G7kSwgY8OzIHRo4buDIHh14bqldCBoaeG7h24gY8OhYyDDtCB24bubaSBz4buRIMSR4bq/bSBi4bqxbmcgMCBkbyBj4bqldSB0csO6YyBj4bunYSBk4buvIGxp4buHdSBob+G6t2MgY8OhYyByw6BuZyBideG7mWMgbG9naWMgKHN0cnVjdHVyYWwgemVyb3MpLiBLaGkgeMOieSBk4buxbmcgbcO0IGjDrG5oIGxvZy1saW5lYXIsIGPhuqduIHjhu60gbMO9IGPDoWMgw7QgbsOgeSBt4buZdCBjw6FjaCBj4bqpbiB0aOG6rW4sIHRoxrDhu51uZyBi4bqxbmcgY8OhY2ggbG/huqFpIHRy4burIGNow7puZyBraOG7j2kgbcO0IGjDrG5oIGhv4bq3YyDDoXAgZOG7pW5nIGPDoWMga+G7uSB0aHXhuq10IMSR4bq3YyBiaeG7h3QgxJHhu4MgxJHhuqNtIGLhuqNvIMaw4bubYyBsxrDhu6NuZyB0aGFtIHPhu5EgY2jDrW5oIHjDoWMuDQoNCiMjIyAxMC41LiBPdmVyZGlzcGVyc2lvbg0KT3ZlcmRpc3BlcnNpb24geOG6o3kgcmEga2hpIHBoxrDGoW5nIHNhaSBj4bunYSBk4buvIGxp4buHdSBs4bubbiBoxqFuIGvhu7MgduG7jW5nIHRoZW8gbcO0IGjDrG5oIFBvaXNzb24sIHZpIHBo4bqhbSBnaeG6oyDEkeG7i25oICRcbWF0aHJte1Zhcn0oWSkgPSBcbXUkDQoNCiMjIyMgMTAuNS4xLiBPdmVyZGlzcGVyc2lvbiB0cm9uZyBQb2lzc29uIEdMTXMNCktoaSBvdmVyZGlzcGVyc2lvbiB4deG6pXQgaGnhu4duLCBtw7QgaMOsbmggUG9pc3NvbiBjw7MgdGjhu4Mga2jDtG5nIHBow7kgaOG7o3AsIGThuqtuIMSR4bq/biB2aeG7h2MgxJHDoW5oIGdpw6Egc2FpIGzhuqdtIHbhu4Egw70gbmdoxKlhIHRo4buRbmcga8OqIGPhu6dhIGPDoWMgaOG7hyBz4buRLg0KDQojIyMjIDEwLjUuMi4gTmVnYXRpdmUgQmlub21pYWwgR0xNcw0KTcO0IGjDrG5oIE5lZ2F0aXZlIEJpbm9taWFsIHRow6ptIG3hu5l0IHRoYW0gc+G7kSBwaMOibiB0w6FuICRcdGhldGEkIMSR4buDIMSRaeG7gXUgY2jhu4luaCBwaMawxqFuZyBzYWk6DQoNCiQkXHRleHR7VmFyfShZX2kpID0gXG11X2kgKyBcdGhldGEgXG11X2leMiQkDQoNClRyb25nIMSRw7M6JFx0aGV0YSQgdGhhbSBz4buRIHBow6JuIHTDoW4sIMSRaeG7gXUgY2jhu4luaCBt4bupYyDEkeG7mSBvdmVyZGlzcGVyc2lvbi4NCg0KIyMjIyAxMC41LjMuIE3DtCBow6xuaCBRdWFzaS1Qb2lzc29uDQpNw7QgaMOsbmggUXVhc2ktUG9pc3NvbiBz4butIGThu6VuZyBt4buZdCBo4buHIHPhu5EgcGjDom4gdMOhbiAkXHBoaSQgxJHhu4MgxJFp4buBdSBjaOG7iW5oIHBoxrDGoW5nIHNhaToNCiQkDQpcbWF0aHJte1Zhcn0oWV9pKSA9IFxwaGkgXG11X2kNCiQkDQpUcm9uZyDEkcOzOiAkXHBoaSQgbMOgIGjhu4cgc+G7kSBwaMOibiB0w6FuDQoNCg0KIyMgQ2jGsMahbmcgMTE6IFBvc2l0aXZlIENvbnRpbnVvdXMgRGF0YTogR2FtbWEgYW5kIEludmVyc2UgR2F1c3NpYW4gR0xNcw0KDQojIyMgMTEuMS4gR2nhu5tpIHRoaeG7h3UNCg0KQ2jGsMahbmcgbsOgeSB4ZW0geMOpdCBjw6FjIG3DtCBow6xuaCB0dXnhur9uIHTDrW5oIHThu5VuZyBxdcOhdCAoR0xNcykgY2hvIGPDoWMgYmnhur9uIHBo4bulIHRodeG7mWMgbMOgIGxpw6puIHThu6VjIHbDoCBkxrDGoW5nICh2w60gZOG7pTogdGjhu51pIGdpYW4gc+G7kW5nLCBjaGkgcGjDrSwgdOG7kWMgxJHhu5kpLiBIYWkgcGjDom4gcGjhu5FpIHBo4buVIGJp4bq/biB0cm9uZyBuaMOzbSBuw6B5IGzDoCBHYW1tYSB2w6AgSW52ZXJzZSBHYXVzc2lhbi4NCg0KIyMjIDExLjIuIE3DtCBow6xuaCBow7NhIEThu68gbGnhu4d1IExpw6puIHThu6VjIETGsMahbmcNCg0KVHJvbmcgR0xNcywgdGEgZ2nhuqMgxJHhu4tuaDoNCg0KLSAkWSBcc2ltIFx0ZXh0e0dhbW1hfShcbXUsIFxwaGkpJCBob+G6t2MgJFkgXHNpbSBcdGV4dHtJbnZlcnNlIEdhdXNzaWFufShcbXUsIFxwaGkpJCAgDQotIFbhu5tpICRnKFxtdSkgPSBcZXRhID0gXG1hdGhiZnt4fV5cdG9wIFxib2xkc3ltYm9se1xiZXRhfSQNCg0KVHJpbmcgxJHDszoNCg0KLSAkWSQ6IEJp4bq/biBwaOG6o24gaOG7k2kgKGxpw6puIHThu6VjIHbDoCBkxrDGoW5nKS4gIA0KLSAkXG11JDogS+G7syB24buNbmcgY+G7p2EgJFkkLCAkXG11ID0gXG1hdGhiYntFfShZKSQgIA0KLSAkXGV0YSQ6IFByZWRpY3RvciB0dXnhur9uIHTDrW5oICANCi0gJFxtYXRoYmZ7eH0kOiBWZWN0b3IgY8OhYyBiaeG6v24gxJHhu5ljIGzhuq1wICANCi0gJFxib2xkc3ltYm9se1xiZXRhfSQ6IFZlY3RvciBo4buHIHPhu5EgaOG7k2kgcXV5ICANCi0gJGcoXGNkb3QpJDogSMOgbSBsacOqbiBr4bq/dCAobGluayBmdW5jdGlvbikgIA0KLSAkXHBoaSQ6IFRoYW0gc+G7kSBwaMOibiB0w6FuIChkaXNwZXJzaW9uIHBhcmFtZXRlcikgIA0KDQoNCiMjIyAxMS4zLiBQaMOibiBwaOG7kWkgR2FtbWENCg0KKipQaMOibiBwaOG7kWkgR2FtbWEgY8OzIGjDoG0gbeG6rXQgxJHhu5kgeMOhYyBzdeG6pXQgKFBERik6KioNCg0KJCQNCmYoeTsgXG11LCBccGhpKSA9IFxmcmFjezF9e1xHYW1tYSgxL1xwaGkpfSBcbGVmdCggXGZyYWN7MX17XHBoaSBcbXV9IFxyaWdodCleezEvXHBoaX0geV57MS9ccGhpIC0gMX0gXGV4cFxsZWZ0KCAtXGZyYWN7eX17XHBoaSBcbXV9IFxyaWdodCkNCiQkDQoNClRyb25nIMSRw7M6DQoNCi0gJHkgPiAwJDogR2nDoSB0cuG7iyBxdWFuIHPDoXQgIA0KLSAkXG11JDogVHJ1bmcgYsOsbmggJFxtYXRoYmJ7RX0oWSkkICANCi0gJFxwaGkkOiBUaGFtIHPhu5EgcGjDom4gdMOhbiAgDQotICRcR2FtbWEoXGNkb3QpJDogSMOgbSBnYW1tYSAgDQoNCioqQ8OhYyBow6BtIGxpw6puIGvhur90IHBo4buVIGJp4bq/bjoqKg0KDQotIExvZyBsaW5rOiAkXGxvZyhcbXUpID0gXGV0YSQgIA0KLSBJbnZlcnNlIGxpbms6ICRcbXVeey0xfSA9IFxldGEkICANCi0gSWRlbnRpdHkgbGluazogJFxtdSA9IFxldGEkICANCg0KKipQaMawxqFuZyBzYWkgY+G7p2EgR2FtbWE6KioNCg0KJCQNClx0ZXh0e1Zhcn0oWSkgPSBccGhpIFxtdV4yDQokJA0KDQoNCiMjIyAxMS40LiBQaMOibiBwaOG7kWkgSW52ZXJzZSBHYXVzc2lhbg0KDQoqKlBow6JuIHBo4buRaSBJbnZlcnNlIEdhdXNzaWFuIGPDsyBow6BtIG3huq10IMSR4buZOioqDQoNCiQkDQpmKHk7IFxtdSwgXHBoaSkgPSBcbGVmdCggXGZyYWN7MX17MlxwaSBccGhpIHleM30gXHJpZ2h0KV57MS8yfSBcZXhwXGxlZnQoIC1cZnJhY3soeSAtIFxtdSleMn17MlxwaGkgXG11XjIgeX0gXHJpZ2h0KQ0KJCQNCg0KVHJvbmcgxJHDszoNCg0KLSAkeSA+IDAkOiBHacOhIHRy4buLIHF1YW4gc8OhdCAgDQotICRcbXUkOiBL4buzIHbhu41uZyAgDQotICRccGhpJDogVGhhbSBz4buRIHBow6JuIHTDoW4gIA0KDQoqKlBoxrDGoW5nIHNhaSBj4bunYSBJbnZlcnNlIEdhdXNzaWFuOioqDQoNCiQkDQpcdGV4dHtWYXJ9KFkpID0gXHBoaSBcbXVeMw0KJCQNCg0KDQojIyMgMTEuNS4gSMOgbSBMacOqbiBr4bq/dCAoTGluayBGdW5jdGlvbnMpDQoNCkdp4buRbmcgbmjGsCBjw6FjIEdMTXMga2jDoWMsIGPDoWMgaMOgbSBsacOqbiBr4bq/dCB0aMaw4budbmcgxJHGsOG7o2Mgc+G7rSBk4bulbmc6DQoNCi0gKipMb2cgbGluayoqOiAkXGxvZyhcbXUpID0gXGV0YSQgIA0KLSAqKklkZW50aXR5IGxpbmsqKjogJFxtdSA9IFxldGEkICANCi0gKipJbnZlcnNlIGxpbmsqKjogJFxtdV57LTF9ID0gXGV0YSQgIA0KDQoqKkzGsHUgw706KiogTG9nIGxpbmsgdGjGsOG7nW5nIMSRxrDhu6NjIMawYSBjaHXhu5luZyB2w6wgbHXDtG4gxJHhuqNtIGLhuqNvICRcbXUgPiAwJCB2w6AgZOG7hSBkaeG7hW4gZ2nhuqNpLg0KDQoNCiMjIyAxMS42LiDGr+G7m2MgbMaw4bujbmcgVGhhbSBz4buRIFBow6JuIHTDoW4gKERpc3BlcnNpb24gUGFyYW1ldGVyKQ0KDQpHTE1zIHbhu5tpIHBow6JuIHBo4buRaSBHYW1tYSB2w6AgSW52ZXJzZSBHYXVzc2lhbiBjw7MgdGhhbSBz4buRIHBow6JuIHTDoW4gJFxwaGkkLCBj4bqnbiDEkcaw4bujYyDGsOG7m2MgbMaw4bujbmcgdOG7qyBk4buvIGxp4buHdS4NCg0KDQojIyMjIDExLjYuMS4gxq/hu5tjIGzGsOG7o25nICRccGhpJCBjaG8gR2FtbWENCg0KJCQNClxoYXR7XHBoaX0gPSBcZnJhY3sxfXtuIC0gcH0gXHN1bV97aT0xfV57bn0gXGxlZnQoIFxmcmFje3lfaSAtIFxoYXR7XG11fV9pfXtcaGF0e1xtdX1faX0gXHJpZ2h0KV4yDQokJA0KDQpUcm9uZyDEkcOzOg0KDQotICRuJDogU+G7kSBxdWFuIHPDoXQgIA0KLSAkcCQ6IFPhu5EgdGhhbSBz4buRIChi4bqtYyB04buxIGRvKSAgDQotICR5X2kkOiBRdWFuIHPDoXQgdGjhu7FjIHThur8gIA0KLSAkXGhhdHtcbXV9X2kkOiBE4buxIMSRb8OhbiB04burIG3DtCBow6xuaCAgDQoNCg0KIyMjIyAxMS42LjIuIMav4bubYyBsxrDhu6NuZyAkXHBoaSQgY2hvIEludmVyc2UgR2F1c3NpYW4NCg0KJCQNClxoYXR7XHBoaX0gPSBcZnJhY3sxfXtuIC0gcH0gXHN1bV97aT0xfV57bn0gXGZyYWN7KHlfaSAtIFxoYXR7XG11fV9pKV4yfXtcaGF0e1xtdX1faV4zfQ0KJCQNCg0KVHJvbmcgxJHDszoNCg0KLSBDw6FjIGJp4bq/biBuaMawIHRyw6puICANCi0gJFxoYXR7XG11fV9pXjMkOiBQaOG6o24gw6FuaCBwaMawxqFuZyBzYWkgxJHhurdjIHRyxrBuZyBj4bunYSBJbnZlcnNlIEdhdXNzaWFuICANCg0KDQojIyBDaMawxqFuZyAxMjogVHdlZWRpZSBHTE1zDQoNCiMjIyAxMi4xLiBHaeG7m2kgdGhp4buHdSB2w6AgVOG7lW5nIHF1YW4NCg0KVHdlZWRpZSBHTE1zIGzDoCBtw7QgaMOsbmggbeG7nyBy4buZbmcgdGh14buZYyBo4buNIGV4cG9uZW50aWFsIGRpc3BlcnNpb24gbW9kZWxzIChFRE1zKSwgY8OzIHRo4buDIHjhu60gbMO9IG5oaeG7gXUga2nhu4N1IGThu68gbGnhu4d1IGtow6FjIG5oYXU6DQoNCi0gTGnDqm4gdOG7pWMgZMawxqFuZyAgDQotIEThu68gbGnhu4d1IGPDsyBnacOhIHRy4buLIDAgdsOgIGTGsMahbmcgbGnDqm4gdOG7pWMgIA0KLSBE4buvIGxp4buHdSDEkeG6v20gIA0KDQpQaMO5IGjhu6NwIHbhu5tpIGPDoWMgdHLGsOG7nW5nIGjhu6NwIG5oxrA6IHThu5VuIHRo4bqldCBi4bqjbyBoaeG7g20gKG5oaeG7gXUgZ2nDoSB0cuG7iyAwIHbDoCBt4buZdCBz4buRIGdpw6EgdHLhu4sgZMawxqFuZyBs4bubbiksIGThu68gbGnhu4d1IHNpbmggaOG7jWMsLi4uDQoNCg0KIyMjIDEyLjIuIFR3ZWVkaWUgRURNcw0KDQojIyMjIDEyLjIuMS4gR2nhu5tpIHRoaeG7h3UgcGjDom4gcGjhu5FpIFR3ZWVkaWUNCg0KVHdlZWRpZSBFRE1zIGzDoCBt4buZdCBs4bubcCBwaMOibiBwaOG7kWkgeMOhYyDEkeG7i25oIGLhu59pOg0KDQotIEjDoG0ga+G7syB24buNbmcgJFxtdSQgIA0KLSBUaGFtIHPhu5EgcGjDom4gdMOhbiAkXHBoaSQgIA0KLSBUaGFtIHPhu5EgY2jhu4kgc+G7kSAoaW5kZXggcGFyYW1ldGVyKSAkXHhpJCAgDQoNCkjDoG0gcGjGsMahbmcgc2FpIGPDsyBk4bqhbmc6DQoNCiQkDQpcdGV4dHtWYXJ9KFkpID0gXHBoaSBcbXVeXHhpDQokJA0KDQpUcm9uZyDEkcOzDQoNCi0gJFkkOiBCaeG6v24gcGjhuqNuIGjhu5NpICANCi0gJFxtdSA9IFxtYXRoYmJ7RX0oWSkkOiBL4buzIHbhu41uZyAgDQotICRccGhpJDogVGhhbSBz4buRIHBow6JuIHTDoW4gIA0KLSAkXHhpJDogVGhhbSBz4buRIGNo4buJIHPhu5EgeMOhYyDEkeG7i25oIGThuqFuZyBj4bunYSBwaMOibiBwaOG7kWkgVHdlZWRpZSAgDQoNCioqTeG7mXQgc+G7kSBnacOhIHRy4buLIMSR4bq3YyBiaeG7h3QgY+G7p2EgJFx4aSQ6KioNCg0KLSAkXHhpID0gMCQ6IE5vcm1hbCAgDQotICRceGkgPSAxJDogUG9pc3NvbiAgDQotICRceGkgPSAyJDogR2FtbWEgIA0KLSAkXHhpID0gMyQ6IEludmVyc2UgR2F1c3NpYW4gIA0KLSAkMSA8IFx4aSA8IDIkOiBI4buXbiBo4bujcCBnaeG7r2EgZ2nDoSB0cuG7iyAwIHbDoCBwaMOibiBwaOG7kWkgbGnDqm4gdOG7pWMgZMawxqFuZyAgDQoNCiMjIyMgMTIuMi4yLiBD4bqldSB0csO6YyBj4bunYSBUd2VlZGllIEVETXMNCg0KSMOgbSBt4bqtdCDEkeG7mSB4w6FjIHN14bqldCBraMO0bmcgY8OzIGJp4buDdSB0aOG7qWMgxJHDs25nLCBuaMawbmcgduG6q24gdGh14buZYyBo4buNIEVETSBuw6puIGPDsyBk4bqhbmc6DQoNCiQkDQpmKHk7IFx0aGV0YSwgXHBoaSkgPSBhKHksIFxwaGkpIFxleHBcbGVmdCggXGZyYWN7eSBcdGhldGEgLSBca2FwcGEoXHRoZXRhKX17XHBoaX0gXHJpZ2h0KQ0KJCQNCg0KVHJvbmcgxJHDszoNCg0KLSAkXHRoZXRhJDogVGhhbSBz4buRIHThu7Egbmhpw6puIChuYXR1cmFsIHBhcmFtZXRlcikgIA0KLSAkXGthcHBhKFx0aGV0YSkkOiBIw6BtIGxvZy1wYXJ0aXRpb24gIA0KLSAkYSh5LCBccGhpKSQ6IEjDoG0gY2h14bqpbiBow7NhICANCg0KDQojIyMjIDEyLjIuMy4gVHdlZWRpZSBFRE1zIGNobyBk4buvIGxp4buHdSBsacOqbiB04bulYyBkxrDGoW5nDQoNCkTDoG5oIGNobyBjw6FjIHRyxrDhu51uZyBo4bujcCBjaOG7iSBjw7MgZ2nDoSB0cuG7iyBkxrDGoW5nIChuaMawIGThu68gbGnhu4d1IGNoaSBwaMOtLCB0aOG7nWkgZ2lhbiwga2hv4bqjbmcgY8OhY2gsLi4uKS4gUGjDom4gcGjhu5FpIG3DtCBow6xuaCBow7NhIGJp4bq/biBkxrDGoW5nIHbhu5tpIHTDrW5oIHBow6JuIHTDoW4gY2FvLg0KDQojIyMjIDEyLjIuNC4gVHdlZWRpZSBFRE1zIGNobyBk4buvIGxp4buHdSBjw7Mgc+G7kSAwIHbDoCBnacOhIHRy4buLIGTGsMahbmcNCg0KxJDDonkgbMOgIOG7qW5nIGThu6VuZyBu4buVaSBi4bqtdDogcGjDom4gcGjhu5FpIFR3ZWVkaWUgduG7m2kgJDEgPCBceGkgPCAyJCBjw7MgeMOhYyBzdeG6pXQga2jDoWMgMCB04bqhaSDEkWnhu4NtIDAgKHBvaW50IG1hc3MgYXQgemVybyksIG7Dqm4gcGjDuSBo4bujcCBtw7QgaMOsbmggaMOzYSBk4buvIGxp4buHdSBjw7Mgbmhp4buBdSBnacOhIHRy4buLIGLhurFuZyAwIHbDoCBwaOG6p24gY8OybiBs4bqhaSBsw6Agc+G7kSBkxrDGoW5nIGxpw6puIHThu6VjLg0KDQojIyMgMTIuMy4gVHdlZWRpZSBHTE1zDQoNCiMjIyMgMTIuMy4xLiBHaeG7m2kgdGhp4buHdQ0KDQpUYSB4w6J5IGThu7FuZyBHTE0gduG7m2kgZ2nhuqMgxJHhu4tuaCAkWSBcc2ltIFx0ZXh0e1R3ZWVkaWV9KFxtdSwgXHBoaSwgXHhpKSQgdsOgOg0KDQokJA0KZyhcbXUpID0gXGV0YSA9IFxtYXRoYmZ7eH1eXHRvcCBcYm9sZHN5bWJvbHtcYmV0YX0NCiQkDQoNClRyb25nIMSRw7MNCg0KLSAkZyhcY2RvdCkkOiBIw6BtIGxpw6puIGvhur90ICh0aMaw4budbmcgbMOgIGxvZykgIA0KLSAkXGV0YSQ6IFByZWRpY3RvciB0dXnhur9uIHTDrW5oICANCi0gJFxtYXRoYmZ7eH0kOiBWZWN0b3IgYmnhur9uIMSR4buZYyBs4bqtcCAgDQotICRcYm9sZHN5bWJvbHtcYmV0YX0kOiBI4buHIHPhu5EgaOG7k2kgcXV5ICANCg0KDQojIyMjIDEyLjMuMi4gxq/hu5tjIGzGsOG7o25nIHRoYW0gc+G7kSBjaOG7iSBz4buRICRceGkkDQoNClRoYW0gc+G7kSAkXHhpJCBraMO0bmcgxJHGsOG7o2MgxrDhu5tjIGzGsOG7o25nIHRy4buxYyB0aeG6v3AgYuG6sW5nIE1MRSB0cm9uZyBow6BtIEdMTSBjxqEgYuG6o24sIG3DoCB0aMaw4budbmcgZMO5bmc6DQoNCi0gUXXDqXQgY8OhYyBnacOhIHRy4buLIHThu6sgMSDEkeG6v24gMiAgDQotIENo4buNbiBnacOhIHRy4buLIHThu5FpIMSRYSBow7NhIGxvZy1saWtlbGlob29kIGhv4bq3YyB04buRaSB0aGnhu4N1IGjDs2EgQUlDICANCg0KDQojIyMjIDEyLjMuMy4gxq/hu5tjIGzGsOG7o25nIHbDoCBGaXQgbcO0IGjDrG5oDQoNCk3DtCBow6xuaCBUd2VlZGllIHRoxrDhu51uZyBkw7luZyBsaW5rIGjDoG0gbG9nOg0KDQokJA0KXGxvZyhcbXVfaSkgPSBcbWF0aGJme3h9X2leXHRvcCBcYm9sZHN5bWJvbHtcYmV0YX0NCiQkDQoNCsav4bubYyBsxrDhu6NuZyBtw7QgaMOsbmggYuG6sW5nIGPDoWMgZ8OzaSBwaOG6p24gbeG7gW0gbmjGsDoNCg0KLSAqKlI6KiogYHN0YXRtb2RgLCBgdHdlZWRpZWAsIGBjcGxtYCAgDQotICoqUHl0aG9uOioqIGBweUdBTWAsIGBzdGF0c21vZGVsc2AgKGPDsyBnaeG7m2kgaOG6oW4pICANCg0KDQojIDIuIFRI4buQTkcgS8OKIE3DlCBU4bqiDQoNCiMjIDIuMS4gxJDhu41jIGThu68gbGnhu4d1DQpgYGB7cn0NCnN1cGVybWFya2V0IDwtIHJlYWQuY3N2MigiRDovbmFhYWFhYS9QVERMRFQvU3VwZXJtYXJrZXQgVHJhbnNhY3Rpb25zLmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwgZmlsZUVuY29kaW5nID0gIlVURi04IikNCiMgWGVtIGPhuqV1IHRyw7pjIGThu68gbGnhu4d1DQpzdHIoc3VwZXJtYXJrZXQpDQpgYGANCmBgYHtyfQ0KIyBIaeG7g24gdGjhu4sgdsOgaSBkw7JuZyDEkeG6p3UNCmhlYWQoc3VwZXJtYXJrZXQpDQpgYGANClThuq1wIGThu68gbGnhu4d1ICJTdXBlcm1hcmtldCBUcmFuc2FjdGlvbnMiIGfhu5NtIHThu5VuZyBj4buZbmcgMTQuMDU5IGTDsm5nIGThu68gbGnhu4d1LCB0xrDGoW5nIOG7qW5nIHbhu5tpIDE0LjA1OSBnaWFvIGThu4tjaCBtdWEgaMOgbmcgxJHGsOG7o2MgZ2hpIG5o4bqtbiB04bqhaSBzacOqdSB0aOG7iy4gTeG7l2kgZMOybmcgZOG7ryBsaeG7h3UgxJHhuqFpIGRp4buHbiBjaG8gbeG7mXQgZ2lhbyBk4buLY2ggcmnDqm5nIGzhursgdsOgIGJhbyBn4buTbSB0aMO0bmcgdGluIGNoaSB0aeG6v3QgduG7gSBraMOhY2ggaMOgbmcsIHPhuqNuIHBo4bqpbSwgY8WpbmcgbmjGsCBjw6FjIMSR4bq3YyDEkWnhu4NtIGxpw6puIHF1YW4gxJHhur9uIGjDoG5oIHZpIHRpw6p1IGTDuW5nLiBC4buZIGThu68gbGnhu4d1IG7DoHkgY8OzIHThu5VuZyBj4buZbmcgMTYgYmnhur9uIChj4buZdCksIGJhbyBn4buTbSBj4bqjIGJp4bq/biDEkeG7i25oIHTDrW5oIHbDoCDEkeG7i25oIGzGsOG7o25nLCBwaOG6o24gw6FuaCDEkeG6p3kgxJHhu6cgY8OhYyB54bq/dSB04buRIG5ow6JuIGto4bqpdSBo4buNYywgxJHhu4thIGzDvSB2w6Aga+G6v3QgcXXhuqMga2luaCBkb2FuaCB04burIG3hu5dpIGdpYW8gZOG7i2NoLg0KDQojIyAyLjIuIFThu5VuZyBxdWFuIGThu68gbGnhu4d1DQpgYGB7cn0NCiMgVOG6oW8gYuG6o25nIG3DtCB04bqjIGPDoWMgYmnhur9uDQp2YXJpYWJsZV9zdW1tYXJ5IDwtIGRhdGEuZnJhbWUoDQogIFZhcmlhYmxlID0gbmFtZXMoc3VwZXJtYXJrZXQpLCAgIyBj4buZdCB0w6puIGJp4bq/bg0KICBEYXRhVHlwZSA9IHNhcHBseShzdXBlcm1hcmtldCwgY2xhc3MpLCAgIyBraeG7g3UgZOG7ryBsaeG7h3UgdHJvbmcgUg0KICBVbmlxdWVWYWx1ZXMgPSBzYXBwbHkoc3VwZXJtYXJrZXQsIGZ1bmN0aW9uKHgpIGxlbmd0aCh1bmlxdWUoeCkpKSwNCiAgTWlzc2luZ1ZhbHVlcyA9IHNhcHBseShzdXBlcm1hcmtldCwgZnVuY3Rpb24oeCkgc3VtKGlzLm5hKHgpKSkNCikNCg0KIyBHw6FuIGxv4bqhaSBiaeG6v24gdGhlbyBraeG7g3UgxJHhu4tuaCB0w61uaCAvIMSR4buLbmggbMaw4bujbmcNCnZhcmlhYmxlX3N1bW1hcnkkVmFyaWFibGVUeXBlIDwtIGlmZWxzZSh2YXJpYWJsZV9zdW1tYXJ5JERhdGFUeXBlICVpbiUgYygibnVtZXJpYyIsICJpbnRlZ2VyIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIsSQ4buLbmggbMaw4bujbmciLCAixJDhu4tuaCB0w61uaCIpDQoNCiMgSW4gcmEgYuG6o25nIGfhu41uIGfDoG5nDQpwcmludCh2YXJpYWJsZV9zdW1tYXJ5KQ0KDQpgYGANCmBgYHtyfQ0KaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KbGlicmFyeShrbml0cikNCmthYmxlKHZhcmlhYmxlX3N1bW1hcnksIGNhcHRpb24gPSAiQuG6o25nIG3DtCB04bqjIGPDoWMgYmnhur9uIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgU3VwZXJtYXJrZXQgVHJhbnNhY3Rpb25zIikNCmBgYA0KDQpE4buvIGxp4buHdSDEkcaw4bujYyB0aHUgdGjhuq1wIHThu6sgbmhp4buBdSBraMOhY2ggaMOgbmcga2jDoWMgbmhhdSB2w6AgY2jhu6lhIMSRYSBk4bqhbmcgY8OhYyBiaeG6v24gdGh14buZYyBj4bqjIGhhaSBsb+G6oWk6IGJp4bq/biDEkeG7i25oIHTDrW5oIHbDoCBiaeG6v24gxJHhu4tuaCBsxrDhu6NuZy4NCg0KQ+G7pSB0aOG7gywgY8OhYyBiaeG6v24gxJHhu4tuaCB0w61uaCBiYW8gZ+G7k206DQoNCjxsaT5HaeG7m2kgdMOtbmggKEdlbmRlciksPC9saT4NCg0KPGxpPlTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiAoTWFyaXRhbFN0YXR1cyksPC9saT4NCg0KPGxpPlTDrG5oIHRy4bqhbmcgc+G7nyBo4buvdSBuaMOgIChIb21lb3duZXIpLDwvbGk+DQoNCjxsaT5UaHUgbmjhuq1wIGjDoG5nIG7Eg20gKEFubnVhbEluY29tZSkg4oCUIMSRxrDhu6NjIG3DoyBow7NhIGTGsOG7m2kgZOG6oW5nIGPDoWMga2hv4bqjbmcgdGh1IG5o4bqtcCw8L2xpPg0KDQo8bGk+dsOgIGPDoWMgYmnhur9uIGxpw6puIHF1YW4gxJHhur9uIHPhuqNuIHBo4bqpbSB2w6AgxJHhu4thIGzDvSBuaMawIFRow6BuaCBwaOG7kSAoQ2l0eSksIFThu4luaC9CYW5nIChTdGF0ZU9yUHJvdmluY2UpLCBRdeG7kWMgZ2lhIChDb3VudHJ5KSwgRGFuaCBt4bulYyBz4bqjbiBwaOG6qW0gKFByb2R1Y3RDYXRlZ29yeSksLi4uPC9saT4NCg0KQ8OhYyBiaeG6v24gxJHhu4tuaCBsxrDhu6NuZyBiYW8gZ+G7k206DQoNCjxsaT5T4buRIGNvbiAoQ2hpbGRyZW4pIOKAkyBjaG8gYmnhur90IHPhu5EgbMaw4bujbmcgY29uIGPhu6dhIGtow6FjaCBow6BuZyw8L2xpPg0KDQo8bGk+TcOjIGtow6FjaCBow6BuZyAoQ3VzdG9tZXJJRCkg4oCTIGTDuW5nIMSR4buDIG5o4bqtbiBk4bqhbmcgY8OhIG5ow6JuLDwvbGk+DQoNCjxsaT5T4buRIGzGsOG7o25nIHPhuqNuIHBo4bqpbSDEkcOjIGLDoW4gKFVuaXRzU29sZCksPC9saT4NCg0KPGxpPnbDoCBEb2FuaCB0aHUgKFJldmVudWUpIOKAkyB0aOG7gyBoaeG7h24gZ2nDoSB0cuG7iyB0aeG7gW4gdOG7hyB0aHUgxJHGsOG7o2MgdOG7qyBt4buXaSBnaWFvIGThu4tjaC48L2xpPg0KDQojIyAyLjMuVGjhu5FuZyBrw6ogbcO0IHThuqMgYmnhur9uIHPhu5ENCg0KIyMjIDIuMy4xLiBCaeG6v24gxJHhu4tuaCB0w61uaA0KDQoNCmBgYHtyfQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoa2FibGVFeHRyYSkNCg0KIyBU4bqhbyBi4bqjbmcgZOG7ryBsaeG7h3UgduG7m2kgdMOqbiBj4buZdCB0aeG6v25nIFZp4buHdCwgY8OzIGNoZWNrLm5hbWVzID0gRkFMU0UgxJHhu4MgY2hvIHBow6lwDQoNCmJpZW5fZGluaF90aW5oIDwtIGRhdGEuZnJhbWUoDQogICJUw6puIGJp4bq/biIgPSBjKA0KICAgICJHZW5kZXIiLCANCiAgICAiTWFyaXRhbFN0YXR1cyIsIA0KICAgICJIb21lb3duZXIiLCANCiAgICAiQW5udWFsSW5jb21lIiwNCiAgICAiQ2l0eSAvIFN0YXRlb3JQcm92aW5jZSAvIENvdW50cnkiLA0KICAgICJQcm9kdWN0RmFtaWx5IC8gUHJvZHVjdERlcGFydG1lbnQgLyBQcm9kdWN0Q2F0ZWdvcnkiDQogICksDQogICJLaeG7g3UgZOG7ryBsaeG7h3UiID0gcmVwKCJDaHXhu5dpIGvDvSB04buxIiwgNiksDQogICJT4buRIGdpw6EgdHLhu4sga2jDoWMgbmhhdSIgPSBjKDIsIDIsIDIsIDgsICJOaGnhu4F1IiwgIk5oaeG7gXUiKSwNCiAgIk5o4bqtbiB4w6l0IiA9IGMoDQogICAgIkJp4bq/biBwaMOibiBsb+G6oWkgxJHGoW4gZ2nhuqNuIGfhu5NtIDIgZ2nDoSB0cuG7izogTmFtIHbDoCBO4buvLiBDw7MgdGjhu4MgZMO5bmcgxJHhu4MgcGjDom4gdMOtY2ggaMOgbmggdmkgdGhlbyBnaeG7m2kuIiwNCiAgICAiR+G7k20gJ1NpbmdsZScgdsOgICdNYXJyaWVkJywgcGjhuqNuIMOhbmggdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuLiBDw7MgdGjhu4Mg4bqjbmggaMaw4bufbmcgxJHhur9uIG3hu6ljIGNoaSB0acOqdS4iLA0KICAgICJDaG8gYmnhur90IGtow6FjaCBow6BuZyBjw7Mgc+G7nyBo4buvdSBuaMOgIGhheSBraMO0bmcsIGPDsyB0aOG7gyBsacOqbiBxdWFuIMSR4bq/biB0aHUgbmjhuq1wIHbDoCBjaGkgdGnDqnUuIiwNCiAgICAiTMOgIGJp4bq/biBwaMOibiBsb+G6oWkgdGhlbyBi4bqtYyB0aHUgbmjhuq1wICh2w60gZOG7pTogJyQyNUstJDUwSycpLiBDw7MgdGjhu4MgY2h1eeG7g24gdGjDoG5oIGLhuq1jIHRoYW5nIHPhu5EgxJHhu4MgcGjDom4gdMOtY2guIiwNCiAgICAiUGjDom4gbG/huqFpIMSR4buLYSBsw70sIHBow7kgaOG7o3AgxJHhu4MgcGjDom4gdMOtY2ggdGhlbyBraHUgduG7sWMsIHbDuW5nIG1p4buBbi4iLA0KICAgICJQaMOibiBsb+G6oWkgc+G6o24gcGjhuqltIOKAlCBy4bqldCBxdWFuIHRy4buNbmcgdHJvbmcgcGjDom4gdMOtY2ggZG9hbmggdGh1IHbDoCB4dSBoxrDhu5tuZyB0acOqdSBkw7luZy4iDQogICksDQogIGNoZWNrLm5hbWVzID0gRkFMU0UNCikNCg0KIyBJbiBi4bqjbmcgxJHhurlwDQprYWJsZShiaWVuX2RpbmhfdGluaCwgImh0bWwiLCBhbGlnbiA9ICJsY2NjIiwgY2FwdGlvbiA9ICJC4bqjbmcgbcO0IHThuqMgY8OhYyBiaeG6v24gxJHhu4tuaCB0w61uaCIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpKSAlPiUNCiAgY29sdW1uX3NwZWMoNCwgd2lkdGggPSAiMzBlbSIsIGV4dHJhX2NzcyA9ICJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyIpDQoNCmBgYA0KDQojIyMgMi4zLjIgQmnhur9uIMSR4buLbmggbMaw4bujbmcNCg0KYGBge3J9DQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KDQojID09PSAyLiBC4bqiTkcgQknhur5OIMSQ4buKTkggTMav4buiTkcgPT09DQpiaWVuX2RpbmhfbHVvbmcgPC0gZGF0YS5mcmFtZSgNCiAgIlTDqm4gYmnhur9uIiA9IGMoICJDaGlsZHJlbiIsICJVbml0c1NvbGQiLCAiUmV2ZW51ZSIpLA0KICAiS2nhu4N1IGThu68gbGnhu4d1IiA9IGMoICJT4buRIG5ndXnDqm4iLCAiU+G7kSB0aOG7sWMiLCAiU+G7kSB0aOG7sWMiKSwNCiAgIlPhu5EgZ2nDoSB0cuG7iyBraMOhYyBuaGF1IiA9IGMoIDYsICJOaGnhu4F1IiwgIk5oaeG7gXUiKSwNCiAgIk5o4bqtbiB4w6l0IiA9IGMoDQogICAgIlPhu5EgbMaw4bujbmcgY29uIGPhu6dhIGtow6FjaCBow6BuZywgY8OzIHRo4buDIHBow6JuIHTDrWNoIG3hu5FpIHF1YW4gaOG7hyB24bubaSBjaGkgdGnDqnUuIiwNCiAgICAiUGjhuqNuIMOhbmggc+G7kSBsxrDhu6NuZyBz4bqjbiBwaOG6qW0gxJHGsOG7o2MgYsOhbiB0cm9uZyB04burbmcgZ2lhbyBk4buLY2guIiwNCiAgICAiQmnhur9uIG3hu6VjIHRpw6p1IGNow61uaCB0aOG7gyBoaeG7h24gZG9hbmggdGh1IOKAkyBwaMO5IGjhu6NwIMSR4buDIHBow6JuIHTDrWNoIGhp4buHdSBxdeG6oyBraW5oIGRvYW5oLiINCiAgKSwNCiAgY2hlY2submFtZXMgPSBGQUxTRSAgIyBHaeG7ryBuZ3V5w6puIHRpw6p1IMSR4buBIGPhu5l0DQopDQoNCiMgSW4gYuG6o25nDQprYWJsZShiaWVuX2RpbmhfbHVvbmcsICJodG1sIiwgYWxpZ24gPSAibGNjYyIsIGNhcHRpb24gPSAiQuG6o25nIDIuIE3DtCB04bqjIGPDoWMgYmnhur9uIMSR4buLbmggbMaw4bujbmciKSAlPiUNCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UsIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiKSkgJT4lDQogIGNvbHVtbl9zcGVjKDQsIHdpZHRoID0gIjMwZW0iLCBleHRyYV9jc3MgPSAidGV4dC1hbGlnbjoganVzdGlmeTsiKQ0KDQpgYGANCg0KDQoNCiMjIDIuNC5UaOG7kW5nIGvDqiBtw7QgdOG6oyBiaeG6v24gxJHhu4tuaCB0w61uaA0KDQojIyMgMi40LjEuIEdlbmRlcihHaeG7m2kgdMOtbmgpDQoNCmBgYHtyfQ0KDQojIFThuqFvIGLhuqNuZyB04bqnbiBzdeG6pXQNCmdlbmRlcl9jb3VudHMgPC0gdGFibGUoc3VwZXJtYXJrZXQkR2VuZGVyKQ0KcHJpbnQoZ2VuZGVyX2NvdW50cyApDQoNCg0KIyBUw61uaCBwaOG6p24gdHLEg20NCmdlbmRlcl9wZXJjZW50IDwtIHJvdW5kKHByb3AudGFibGUoZ2VuZGVyX2NvdW50cykgKiAxMDAsIDEpDQoNCiMgR8OhbiBuaMOjbiB24bubaSBwaOG6p24gdHLEg20NCmxhYmVscyA8LSBwYXN0ZShuYW1lcyhnZW5kZXJfY291bnRzKSwgIiAoIiwgZ2VuZGVyX3BlcmNlbnQsICIlKSIsIHNlcD0iIikNCg0KIyBW4bq9IGJp4buDdSDEkeG7kyB0csOybg0KcGllKGdlbmRlcl9jb3VudHMsDQogICAgbGFiZWxzID0gbGFiZWxzLA0KICAgIGNvbCA9IGMoIiNmZjk5OTkiLCIjNjZiM2ZmIiksDQogICAgbWFpbiA9ICJU4bu3IGzhu4cgZ2nhu5tpIHTDrW5oIGtow6FjaCBow6BuZyIpDQoNCmBgYA0KDQpCaeG7g3UgxJHhu5MgdHLDsm4gY2hvIHRo4bqleSBjxqEgY+G6pXUgZ2nhu5tpIHTDrW5oIGtow6FjaCBow6BuZyB04bqhaSBzacOqdSB0aOG7iyB0xrDGoW5nIMSR4buRaSDEkeG7k25nIMSR4buBdToNCg0KLSBO4buvIGPDsyA3LjE3MCBuZ8aw4budaSwgY2hp4bq/bSBraG/huqNuZyA1MS4wJSB04buVbmcgc+G7kSBraMOhY2ggaMOgbmcuDQoNCi0gTmFtIGPDsyA2Ljg4OSBuZ8aw4budaSwgY2hp4bq/bSBraG/huqNuZyA0OS4wJSB04buVbmcgc+G7kSBraMOhY2ggaMOgbmcuDQoNClThu7cgbOG7hyBnaeG7m2kgdMOtbmggZ2nhu69hIG5hbSB2w6AgbuG7ryBraMOhIGPDom4gYuG6sW5nLCBraMO0bmcgY8OzIHPhu7EgY2jDqm5oIGzhu4djaCBs4bubbi4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgc2nDqnUgdGjhu4sgdGh1IGjDunQgxJHGsOG7o2Mga2jDoWNoIGjDoG5nIOG7nyBj4bqjIGhhaSBnaeG7m2kgduG7m2kgbeG7qWMgxJHhu5kgdMawxqFuZyDEkcawxqFuZy4gVmnhu4djIHRyw6xuaCBiw6B5IGLhurFuZyBiaeG7g3UgxJHhu5MgdHLDsm4gduG7m2kgbcOgdSBz4bqvYyBwaMOibiBiaeG7h3QgdsOgIGfDoW4gbmjDo24gcGjhuqduIHRyxINtIHLDtSByw6BuZyBnacO6cCBuZ8aw4budaSB4ZW0gZOG7hSBkw6BuZyBuaOG6rW4gZGnhu4duIHbDoCBzbyBzw6FuaCB0aOG7iyBwaOG6p24gY+G7p2EgdOG7q25nIG5ow7NtIGdp4bubaSB0w61uaC4NCg0KDQojIyMgMi40LjIuIE1hcml0YWxTdGF0dXMgKFTDrG5oIHRy4bqhbmcgaMO0biBuaMOibikNCg0KYGBge3J9DQojIFThuqFvIGLhuqNuZyB04bqnbiBzdeG6pXQgdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuDQptYXJpdGFsX2NvdW50cyA8LSB0YWJsZShzdXBlcm1hcmtldCRNYXJpdGFsU3RhdHVzKQ0KcHJpbnQobWFyaXRhbF9jb3VudHMpDQoNCiMgVMOtbmggcGjhuqduIHRyxINtDQptYXJpdGFsX3BlcmNlbnQgPC0gcm91bmQocHJvcC50YWJsZShtYXJpdGFsX2NvdW50cykgKiAxMDAsIDEpDQoNCiMgR8OhbiBuaMOjbiB24bubaSBwaOG6p24gdHLEg20NCmxhYmVscyA8LSBwYXN0ZShuYW1lcyhtYXJpdGFsX2NvdW50cyksICIgKCIsIG1hcml0YWxfcGVyY2VudCwgIiUpIiwgc2VwPSIiKQ0KDQojIFbhur0gYmnhu4N1IMSR4buTIHRyw7JuDQpwaWUobWFyaXRhbF9jb3VudHMsDQogICAgbGFiZWxzID0gbGFiZWxzLA0KICAgIGNvbCA9IGMoIiNGRjAwMDAiLCAiIzAwRkYwMCIpLA0KICAgIG1haW4gPSAiVMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIGPhu6dhIGtow6FjaCBow6BuZyIpDQoNCmBgYA0KDQoNCkJp4buDdSDEkeG7kyB0csOybiB0aOG7gyBoaeG7h24gY8ahIGPhuqV1IHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiBj4bunYSBraMOhY2ggaMOgbmcgdOG6oWkgc2nDqnUgdGjhu4suIEPhu6UgdGjhu4M6DQoNCi0gS2jDoWNoIGjDoG5nIMSR4buZYyB0aMOibiAoU2luZ2xlKSBjw7MgNy4xOTMgbmfGsOG7nWksIGNoaeG6v20ga2hv4bqjbmcgNTEuMiUuDQoNCi0gS2jDoWNoIGjDoG5nIMSRw6Mga+G6v3QgaMO0biAoTWFycmllZCkgY8OzIDYuODY2IG5nxrDhu51pLCBjaGnhur9tIGtob+G6o25nIDQ4LjglLg0KDQpU4bu3IGzhu4cgZ2nhu69hIGhhaSBuaMOzbSBraMOhY2ggaMOgbmcgbMOgIGtow6EgY8OibiBi4bqxbmcsIHR1eSBuaGnDqm4gbmjDs20gxJHhu5ljIHRow6JuIGPDsyBwaOG6p24gY2hp4bq/bSDGsHUgdGjhur8gbmjhurkuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IHNpw6p1IHRo4buLIHRodSBow7p0IMSRxrDhu6NjIHPhu7EgcXVhbiB0w6JtIGPhu6dhIGPhuqMgaGFpIG5ow7NtIGtow6FjaCBow6BuZywgbmjGsG5nIGPDsyB0aOG7gyBjw6JuIG5o4bqvYyB0aMOqbSBjw6FjIGNoaeG6v24gbMaw4bujYyB0aeG6v3AgY+G6rW4gcmnDqm5nIGJp4buHdCBjaG8gdOG7q25nIG5ow7NtIMSR4buDIHThu5FpIMawdSBoaeG7h3UgcXXhuqMgbWFya2V0aW5nLg0KDQoNCiMjIyAyLjQuMy4gSG9tZW93bmVyIChUw6xuaCB0cuG6oW5nIHPhu58gaOG7r3UgbmjDoCDhu58pDQoNCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgdOG6p24gc3XhuqV0IHRoZW8gdMOsbmggdHLhuqFuZyBz4bufIGjhu691IG5ow6Ag4bufDQpob21lb3duZXJfY291bnRzIDwtIHRhYmxlKHN1cGVybWFya2V0JEhvbWVvd25lcikNCnByaW50KGhvbWVvd25lcl9jb3VudHMpDQoNCiMgVMOtbmggcGjhuqduIHRyxINtDQpob21lb3duZXJfcGVyY2VudCA8LSByb3VuZChwcm9wLnRhYmxlKGhvbWVvd25lcl9jb3VudHMpICogMTAwLCAxKQ0KDQojIEfDoW4gbmjDo24gduG7m2kgcGjhuqduIHRyxINtDQpsYWJlbHMgPC0gcGFzdGUobmFtZXMoaG9tZW93bmVyX2NvdW50cyksICIgKCIsIGhvbWVvd25lcl9wZXJjZW50LCAiJSkiLCBzZXA9IiIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MgdHLDsm4NCnBpZShob21lb3duZXJfY291bnRzLA0KICAgIGxhYmVscyA9IGxhYmVscywNCiAgICBjb2wgPSBjKCIjQzBDMEMwIiwgIiNmZmNjOTkiKSwgICMgWWVzIC0gTm8NCiAgICBtYWluID0gIlTDrG5oIHRy4bqhbmcgc+G7nyBo4buvdSBuaMOgIOG7nyBj4bunYSBraMOhY2ggaMOgbmciKQ0KDQoNCmBgYA0KDQpCaeG7g3UgxJHhu5MgdHLDsm4gdGjhu4MgaGnhu4duIHTDrG5oIHRy4bqhbmcgc+G7nyBo4buvdSBuaMOgIOG7nyBj4bunYSBraMOhY2ggaMOgbmcgdOG6oWkgc2nDqnUgdGjhu4suIEPhu6UgdGjhu4M6DQoNCi0gS2jDoWNoIGjDoG5nIGPDsyBz4bufIGjhu691IG5ow6AgKFllcyk6IDguNDQ0IG5nxrDhu51pLCBjaGnhur9tIGtob+G6o25nIDYwLjAlDQoNCi0gS2jDoWNoIGjDoG5nIGtow7RuZyBz4bufIGjhu691IG5ow6AgKE5vKTogNS42MTUgbmfGsOG7nWksIGNoaeG6v20ga2hv4bqjbmcgNDAuMCUNCg0KS+G6v3QgcXXhuqMgY2hvIHRo4bqleSBwaOG6p24gbOG7m24ga2jDoWNoIGjDoG5nIGzDoCBuZ8aw4budaSBjw7Mgc+G7nyBo4buvdSBuaMOgLCBjaGnhur9tIHThu7cgbOG7hyBjYW8gaMahbiDEkcOhbmcga+G7gyBzbyB24bubaSBuaMOzbSBraMO0bmcgc+G7nyBo4buvdS4gxJBp4buBdSBuw6B5IHBo4bqjbiDDoW5oIMSR4bq3YyDEkWnhu4NtIG5ow6JuIGto4bqpdSBo4buNYyDhu5VuIMSR4buLbmggduG7gSBraW5oIHThur8g4oCTIHjDoyBo4buZaSBj4bunYSBwaOG6p24gbOG7m24ga2jDoWNoIGjDoG5nIHThuqFpIHNpw6p1IHRo4buLLg0KDQojIyMgMi40LjQuIEFubnVhbEluY29tZSAoUGjDom4gYuG7kSB0aHUgbmjhuq1wIGjhurFuZyBuxINtKQ0KYGBge3J9DQojIFThuqFvIGLhuqNuZyB04bqnbiBzdeG6pXQNCmluY29tZV9jb3VudHMgPC0gdGFibGUoc3VwZXJtYXJrZXQkQW5udWFsSW5jb21lKQ0KcHJpbnQoaW5jb21lX2NvdW50cykNCg0KIyBUxINuZyBtYXJnaW4gZMaw4bubaSAodGhhbSBz4buRIHRo4bupIDEsIDIsIDMsIDQpIOKAkyA0IGzDoCBkxrDhu5tpDQpwYXIobWFyID0gYyg4LCA0LCA0LCAyKSArIDAuMSkgIA0KDQojIEzGsHUgduG7iyB0csOtIGPDoWMgY+G7mXQNCmJhcl9wb3MgPC0gYmFycGxvdChpbmNvbWVfY291bnRzLA0KICAgICAgICAgICAgICAgICAgIGNvbCA9IGMoIiNDMEMwQzAiLCIjODA4MDgwIiwiIzgwMDAwMCIsIiM4MDgwMDAiLCIjMDA4MDAwIiwiIzgwMDA4MCIsIiMwMDgwODAiLCIjMDAwMDgwIiksDQogICAgICAgICAgICAgICAgICAgbWFpbiA9ICJQaMOibiBi4buRIHRodSBuaOG6rXAgaMOgbmcgbsSDbSBj4bunYSBraMOhY2ggaMOgbmciLA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiTmjDs20gdGh1IG5o4bqtcCIsDQogICAgICAgICAgICAgICAgICAgeWxhYiA9ICJT4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyIsDQogICAgICAgICAgICAgICAgICAgbmFtZXMuYXJnID0gRkFMU0UsICAjIEtow7RuZyBoaeG7g24gdGjhu4sgbmjDo24gbeG6t2MgxJHhu4tuaA0KICAgICAgICAgICAgICAgICAgIGJvcmRlciA9IE5BKQ0KDQojIFbhur0gbOG6oWkgbmjDo24gdHLhu6VjIFgg4bufIHbhu4sgdHLDrSB0aOG6pXAgaMahbg0KdGV4dCh4ID0gYmFyX3BvcywNCiAgICAgeSA9IC1tYXgoaW5jb21lX2NvdW50cykqMC4wNSwgICMgROG7nWkgeHXhu5FuZyB0aOG6pXAgaMahbiBn4buRYyB0b+G6oSDEkeG7mQ0KICAgICBsYWJlbHMgPSBuYW1lcyhpbmNvbWVfY291bnRzKSwNCiAgICAgc3J0ID0gNDUsICAgICAgICAgICAgICAjIFhvYXkgbmjDo24gNDUgxJHhu5kNCiAgICAgYWRqID0gMSwgICAgICAgICAgICAgICAjIEPEg24gcGjhuqNpDQogICAgIHhwZCA9IFRSVUUsICAgICAgICAgICAgIyBDaG8gcGjDqXAgduG6vSByYSBuZ2/DoGkgcGxvdA0KICAgICBjZXggPSAwLjgpICAgICAgICAgICAgICMgQ+G7oSBjaOG7rw0KYGBgDQoNCkThu7FhIHRyw6puIGThu68gbGnhu4d1IHThu6sgY+G7mXQgQW5udWFsSW5jb21lLCB0YSBjw7MgdGjhu4MgdGjhuqV5IGtow6FjaCBow6BuZyDEkcaw4bujYyBjaGlhIHRow6BuaCA4IG5ow7NtIHRodSBuaOG6rXAsIHThu6sgZMaw4bubaSAzMEsgxJHhur9uIHRyw6puIDE1MEssIHbhu5tpIHPhu5EgbMaw4bujbmcgY+G7pSB0aOG7gyBuaMawIHNhdToNCg0KLSBOaMOzbSBjaGnhur9tIHThu7cgbOG7hyBjYW8gbmjhuqV0IGzDoCAzMEsgLSA1MEsgduG7m2kgNC42MDEga2jDoWNoIGjDoG5nLCB0xrDGoW5nIMSRxrDGoW5nIGtob+G6o25nIDI5LjklIHThu5VuZyBz4buRLg0KDQotIE5ow7NtIHRodSBuaOG6rXAgdOG7qyAxMEsgLSAzMEsgY8WpbmcgY8OzIHThu7cgbOG7hyBy4bqldCBjYW8sIDMuMDkwIG5nxrDhu51pICh+MjAuMSUpLg0KDQpQaOG6p24gbOG7m24ga2jDoWNoIGjDoG5nIChraG/huqNuZyA1MCUpIHRodeG7mWMgaGFpIG5ow7NtIHRodSBuaOG6rXAgdOG7qyAxMEsgxJHhur9uIDUwSywgdHJvbmcgxJHDsyBuaMOzbSAzMEsgLSA1MEsgY2hp4bq/bSB04bu3IGzhu4cgY2FvIG5o4bqldCwgZ+G6p24gMS8zIHThu5VuZyBz4buRIGtow6FjaCBow6BuZy4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgc2nDqnUgdGjhu4sgxJFhbmcgdGh1IGjDunQgY2jhu6cgeeG6v3UgbMOgIG5o4buvbmcgbmfGsOG7nWkgY8OzIG3hu6ljIHRodSBuaOG6rXAgdHJ1bmcgYsOsbmggLSB0aOG6pXAsIGPDsyB0aOG7gyBsw6AgbmfGsOG7nWkgbGFvIMSR4buZbmcsIGPDtG5nIG5ow6JuLCBzaW5oIHZpw6puIGhv4bq3YyBjw6FjIGjhu5kgZ2lhIMSRw6xuaCBjw7MgbmfDom4gc8OhY2ggY2hpIHRpw6p1IGjhuqFuIGNo4bq/Lg0KDQoNCi0gTmjDs20gdGh1IG5o4bqtcCB04burIDUwSyAtIDcwSyBjw7MgdOG7tyBs4buHIGtow6EgY2FvIHbhu5tpIDIsMzcwIG5nxrDhu51pIGNoaeG6v20gdOG7iSBs4buHIDE1JS4NCg0KLSBOaMOzbSB0aHUgbmjhuq1wIHThu6sgNzBLIC0gOTBLIGPDsyAxLDcwOSAofjExJSkNCg0KQ8OhYyBuaMOzbSB04burIDUwSyAtIDkwSyBjw7Mgc+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmcgdHJ1bmcgYsOsbmgsIGNoaeG6v20ga2hv4bqjbmcgMjYlIHThu5VuZyBz4buRIGtow6FjaCBow6BuZy4gxJDDonkgY8OzIHRo4buDIGzDoCBuaMOzbSBuaMOibiB2acOqbiB2xINuIHBow7JuZywgaOG7mSBnaWEgxJHDrG5oIHRy4bq7IGPDsyB0aHUgbmjhuq1wIOG7lW4gxJHhu4tuaC4NCg0KTmfGsOG7o2MgbOG6oWksIGPDoWMgbmjDs20gdGh1IG5o4bqtcCBjYW8gbmjGsDoNCg0KLSAxNTBLKyBjaOG7iSBjw7MgMjczIG5nxrDhu51pICh+MS44JSksDQoNCi0gMTMwSyAtICQxNTBLIGPDsyA3NjAgbmfGsOG7nWkgKH40LjklKSwNCg0KLSAxMTBLIC0gJDEzMEsgY8OzIDY0MyBuZ8aw4budaSAofjQuMiUpLA0KDQpOaMOzbSB0aHUgbmjhuq1wIHThu6sgOTBLIHRy4bufIGzDqm4gY2hp4bq/bSB04bu3IGzhu4cga2jDoSBuaOG7jywgY2jhu4kga2hv4bqjbmcgMTUlIHThu5VuZyBraMOhY2ggaMOgbmcsIHRyb25nIMSRw7MgbmjDs20gY2FvIG5o4bqldCBsw6AgMTUwSysgY2jhu4kgY8OzIDI3MyBuZ8aw4budaSwgdMawxqFuZyDEkcawxqFuZyBjaMawYSDEkeG6v24gMiUuIMSQaeG7gXUgbsOgeSBwaOG6o24gw6FuaCBy4bqxbmcga2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIGNhbyBraMO0bmcgcGjhuqNpIGzDoCDEkeG7kWkgdMaw4bujbmcgY2jDrW5oIGPhu6dhIHNpw6p1IHRo4buLLg0KDQoNCiMjIyAyLjQuNS4gQ291bnRyeSAoUGjDom4gYuG7kSB0aGVvIHF14buRYyBnaWEpDQoNCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgdOG6p24gc3XhuqV0DQpjb3VudHJ5X2NvdW50cyA8LSB0YWJsZShzdXBlcm1hcmtldCRDb3VudHJ5KQ0KcHJpbnQoY291bnRyeV9jb3VudHMpDQoNCiMgVOG6oW8gbmjDo24gY8OzIHBo4bqnbiB0csSDbQ0KcGVyY2VudF9sYWJlbHMgPC0gcm91bmQoMTAwICogY291bnRyeV9jb3VudHMgLyBzdW0oY291bnRyeV9jb3VudHMpLCAxKQ0KbGFiZWxzX3dpdGhfcGN0IDwtIHBhc3RlKG5hbWVzKGNvdW50cnlfY291bnRzKSwgIlxuIiwgcGVyY2VudF9sYWJlbHMsICIlIikNCg0KIyBW4bq9IGJp4buDdSDEkeG7kyB0csOybg0KcGllKGNvdW50cnlfY291bnRzLA0KICAgIGxhYmVscyA9IGxhYmVsc193aXRoX3BjdCwNCiAgICBjb2wgPSBjKCIjRkY5OTk5IiwgIiM5OUNDRkYiLCAiIzk5RkY5OSIpLCAgIyBNw6B1IGNobyB04burbmcgY291bnRyeQ0KICAgIG1haW4gPSAiVOG7iSBs4buHIGtow6FjaCBow6BuZyB0aGVvIHF14buRYyBnaWEiKQ0KDQoNCmBgYA0KDQpVU0EgY2hp4bq/bSB04bu3IHRy4buNbmcgw6FwIMSR4bqjbzogVuG7m2kgaMahbiA2MyUgdOG7lW5nIHPhu5Ega2jDoWNoIGjDoG5nLCB0aOG7iyB0csaw4budbmcgTeG7uSByw7UgcsOgbmcgbMOgIHRy4buNbmcgdMOibSBjaMOtbmggY+G7p2EgZG9hbmggbmdoaeG7h3AuDQoNCk1leGljbyBsw6AgdGjhu4sgdHLGsOG7nW5nIHRp4buBbSBuxINuZyB0aOG7qSBoYWk6IFbhu5tpIGtob+G6o25nIDMwJSBraMOhY2ggaMOgbmcsIMSRw6J5IGzDoCBt4buZdCB0aOG7iyB0csaw4budbmcgxJHDoW5nIGNow7ogw70sIGPDsyB0aOG7gyDEkWFuZyB0cm9uZyBnaWFpIMSRb+G6oW4gcGjDoXQgdHJp4buDbiB04buRdC4NCg0KQ2FuYWRhIGPDsyBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyB0aOG6pXAgbmjhuqV0OiBDaOG7iSBjaGnhur9tIGtob+G6o25nIDYuNiUsIGPDsyB0aOG7gyBsw6AgZG8gZMOibiBz4buRIHRo4bqlcCBoxqFuLCB0aMOzaSBxdWVuIHRpw6p1IGTDuW5nIGtow6FjLCBob+G6t2MgbeG7qWMgxJHhu5kgdGjDom0gbmjhuq1wIHRo4buLIHRyxrDhu51uZyBjaMawYSBjYW8uDQoNCiMjIyAyLjQuNi4gIFN0YXRlb3JQcm92aW5jZSAoUGjDom4gYuG7kSB0aGVvIHRp4buDdSBiYW5nKQ0KDQpgYGB7cn0NCiMgVOG6oW8gYuG6o25nIHThuqduIHN14bqldCB0aGVvIFN0YXRlb3JQcm92aW5jZQ0Kc3RhdGVfY291bnRzIDwtIHRhYmxlKHN1cGVybWFya2V0JFN0YXRlb3JQcm92aW5jZSkNCnByaW50KHN0YXRlX2NvdW50cykNCg0KIyBT4bqvcCB44bq/cCBnaeG6o20gZOG6p24gxJHhu4MgxJHhurlwIGjGoW4NCnN0YXRlX2NvdW50cyA8LSBzb3J0KHN0YXRlX2NvdW50cywgZGVjcmVhc2luZyA9IFRSVUUpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgbmdhbmcNCmJhcnBsb3Qoc3RhdGVfY291bnRzLA0KICAgICAgICBob3JpeiA9IFRSVUUsDQogICAgICAgIGxhcyA9IDEsICAjIFhvYXkgbmjDo24gdHLhu6VjIFkgY2hvIGThu4UgxJHhu41jDQogICAgICAgIGNvbCA9ICIjOGRhMGNiIiwNCiAgICAgICAgbWFpbiA9ICJT4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyB0aGVvIFN0YXRlL1Byb3ZpbmNlIiwNCiAgICAgICAgeGxhYiA9ICJT4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyIsDQogICAgICAgIGJvcmRlciA9IE5BKQ0KDQpgYGANCg0KDQoNCg0KQmnhu4N1IMSR4buTIHPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIGNobyB0aOG6pXk6DQoNCi0gV0EgKFdhc2hpbmd0b24pIGzDoCBiYW5nIGPDsyBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyBs4bubbiBuaOG6pXQsIGNoaeG6v20gxJHhur9uIDMyLjUlLCBjaG8gdGjhuqV5IMSRw6J5IGzDoCB0aOG7iyB0csaw4budbmcgdHLhu41uZyDEkWnhu4NtLg0KDQotIEhhaSBiYW5nIGtow6FjIGPhu6dhIE3hu7kgbMOgIENBIChDYWxpZm9ybmlhKSB2w6AgT1IgKE9yZWdvbikgY8WpbmcgY8OzIGzGsOG7o25nIGtow6FjaCBow6BuZyBy4bqldCBjYW8gKDE5LjQlIHbDoCAxNi4xJSksIGto4bqzbmcgxJHhu4tuaCBN4bu5IGzDoCBraHUgduG7sWMgY2jhu6cgbOG7sWMgduG7gSBraMOhY2ggaMOgbmcuDQoNCi0gQ8OhYyB04buJbmggdGjDoG5oIGPhu6dhIE1leGljbyBuaMawIFphY2F0ZWNhcyAoOS4yJSksIERGICg1LjglKSwgdsOgIFl1Y2F0YW4gKDQuNiUpIGPDsyBz4buxIGhp4buHbiBkaeG7h24gxJHDoW5nIGvhu4MuDQoNCi0gSmFsaXNjbyBjw7Mgc+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmcgdGjhuqVwIG5o4bqldCBjaOG7iSAwLjUlLCBjw7MgdGjhu4MgY8OibiBuaOG6r2MgbOG6oWkgdmnhu4djIHRp4bq/cCBj4bqtbiBob+G6t2MgxJHhuqd1IHTGsCDhu58ga2h1IHbhu7FjIG7DoHkuDQoNCi0gUmnDqm5nIENhbmFkYSAoQkMpIGNoaeG6v20gNS44JSwgY2hvIHRo4bqleSBz4buxIGhp4buHbiBkaeG7h24gduG7q2EgcGjhuqNpLCBraMO0bmcgcXXDoSBu4buVaSBi4bqtdC4NCg0KIyMjIDIuNC43LiAgCUNpdHkgKFBow6JuIGLhu5EgdGhlbyB0aMOgbmggcGjhu5EpDQpgYGB7cn0NCiMgVOG6oW8gYuG6o25nIHThuqduIHN14bqldCB0aGVvIHRow6BuaCBwaOG7kQ0KY2l0eV9jb3VudHMgPC0gc29ydCh0YWJsZShzdXBlcm1hcmtldCRDaXR5KSwgZGVjcmVhc2luZyA9IFRSVUUpDQpwcmludChjaXR5X2NvdW50cykNCg0KIyBUxINuZyBs4buBIHRyw6FpIMSR4buDIGNo4bupYSBuaMOjbg0KcGFyKG1hciA9IGMoNCwgMTAsIDQsIDIpICsgMC4xKQ0KDQojIFbhur0gYmnhu4N1IMSR4buTIGPhu5l0IG5nYW5nDQpiYXJwbG90KGNpdHlfY291bnRzLA0KICAgICAgICBob3JpeiA9IFRSVUUsDQogICAgICAgIGxhcyA9IDEsICAjIFhvYXkgbmjDo24gdHLhu6VjIFkgxJHhu4MgZOG7hSDEkeG7jWMNCiAgICAgICAgY29sID0gInNreWJsdWUiLA0KICAgICAgICBtYWluID0gIlPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIHRoZW8gVGjDoG5oIHBo4buRIiwNCiAgICAgICAgeGxhYiA9ICJT4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyIsDQogICAgICAgIGJvcmRlciA9IE5BKQ0KDQpgYGANCg0KDQoNCkJp4buDdSDEkeG7kyBjaG8gdGjhuqV5IHBow6JuIGLhu5Ega2jDoWNoIGjDoG5nIGtow7RuZyDEkeG7gXU6IG3hu5l0IHbDoGkgdGjDoG5oIHBo4buRIGNoaeG6v20gcGjhuqduIGzhu5tuIGtow6FjaCBow6BuZywgY8OybiBuaGnhu4F1IHRow6BuaCBwaOG7kSBraMOhYyB0aMOsIGzGsOG7o25nIGtow6FjaCB0aOG6pXAsIHRo4buDIGhp4buHbiB04bqtcCB0cnVuZyBraMOhY2ggaMOgbmcgdsOgbyBt4buZdCBz4buRIHRo4buLIHRyxrDhu51uZyBjaMOtbmguDQoNCi0gU2FsZW0gbuG7lWkgYuG6rXQgbmjhuqV0IHbhu5tpIGPhu5l0IGNhbyBoxqFuIGjhurNuLCBjaOG7qW5nIHThu48gxJHDonkgbMOgIHRow6BuaCBwaOG7kSBjw7MgbMaw4bujbmcga2jDoWNoIGjDoG5nIMSRw7RuZyBuaOG6pXQuDQoNCi0gQ8OhYyB0aMOgbmggcGjhu5EgbOG7m24gbmjGsCBMb3MgQW5nZWxlcywgUG9ydGxhbmQsIFNwb2thbmUsIFNhbiBEaWVnbyBjxaluZyBjw7MgY+G7mXQgY2FvLCB0aOG7gyBoaeG7h24gdGjhu4sgdHLGsOG7nW5nIGtow6EgbeG6oW5oLg0KDQotIOG7niBwaMOtYSBnaeG7r2EgYmnhu4N1IMSR4buTLCBjw6FjIHRow6BuaCBwaOG7kSBuaMawIE1lcmlkYSwgVmFuY291dmVyLCBTYW4gQW5kcmVzIGPDsyBz4buRIGzGsOG7o25nIGtow6FjaCB0cnVuZyBiw6xuaCwgY+G7mXQgdGjhuqVwIGjGoW4gbmjGsG5nIHbhuqtuIMSRw6FuZyBr4buDLg0KDQotIOG7niDEkeG6p3UgYmnhu4N1IMSR4buTLCBjw6FjIHRow6BuaCBwaOG7kSBuaMawIEd1YWRhbGFqYXJhLCBCZWxsaW5naGFtIGPDsyBj4buZdCB0aOG6pXAsIG5naMSpYSBsw6AgbMaw4bujbmcga2jDoWNoIGjDoG5nIMOtdCwgY2hp4bq/bSBwaOG6p24gbmjhu48gdHJvbmcgdOG7lW5nIHPhu5EuDQoNCiMjIyAyLjQuOC4gUHJvZHVjdCBmYW1pbHkgKFBow6JuIGxv4bqhaSBz4bqjbiBwaOG6qW0gZ2lhIMSRw6xuaCkNCg0KYGBge3J9DQojIFThuqFvIGLhuqNuZyB04bqnbiBzdeG6pXQgUHJvZHVjdEZhbWlseQ0KcHJvZHVjdF9mYW1pbHlfY291bnRzIDwtIHRhYmxlKHN1cGVybWFya2V0JFByb2R1Y3RGYW1pbHkpDQpwcmludChwcm9kdWN0X2ZhbWlseV9jb3VudHMpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MgdHLDsm4NCnBpZShwcm9kdWN0X2ZhbWlseV9jb3VudHMsDQogICAgbWFpbiA9ICJQaMOibiBi4buRIHRoZW8gUHJvZHVjdEZhbWlseSIsDQogICAgY29sID0gcmFpbmJvdyhsZW5ndGgocHJvZHVjdF9mYW1pbHlfY291bnRzKSksDQogICAgY2V4ID0gMC44KQ0KDQojIFRow6ptIGNow7ogdGjDrWNoIG5nb8OgaSBiaeG7g3UgxJHhu5MNCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBuYW1lcyhwcm9kdWN0X2ZhbWlseV9jb3VudHMpLCBmaWxsID0gcmFpbmJvdyhsZW5ndGgocHJvZHVjdF9mYW1pbHlfY291bnRzKSksIGNleD0wLjcpDQoNCmBgYA0KDQoNClBow6JuIGLhu5EgdGhlbyBuaMOzbSBz4bqjbiBwaOG6qW0gKFByb2R1Y3RGYW1pbHkpOg0KDQotIEZvb2QgKFRo4buxYyBwaOG6qW0pIGzDoCBuaMOzbSBs4bubbiBuaOG6pXQgduG7m2kgMTAsMTUzIHPhuqNuIHBo4bqpbSwgY2hp4bq/bSBraG/huqNuZyA3MCUgdOG7lW5nIHPhu5EuIMSQw6J5IGzDoCBuaMOzbSBjaOG7pyDEkeG6oW8gdHJvbmcgZOG7ryBsaeG7h3UsIGNobyB0aOG6pXkga2jDoWNoIGjDoG5nIG11YSBuaGnhu4F1IG5o4bqldCBjw6FjIHPhuqNuIHBo4bqpbSB0aOG7sWMgcGjhuqltLg0KDQotIERyaW5rICjEkOG7kyB14buRbmcpIGNoaeG6v20ga2hv4bqjbmcgOC42JSB24bubaSAxLDI1MCBz4bqjbiBwaOG6qW0uIMSQw6J5IGPFqW5nIGzDoCBt4buZdCBuaMOzbSBxdWFuIHRy4buNbmcgbmjGsG5nIG5o4buPIGjGoW4gbmhp4buBdSBzbyB24bubaSB0aOG7sWMgcGjhuqltLg0KDQotIE5vbi1Db25zdW1hYmxlIChT4bqjbiBwaOG6qW0ga2jDtG5nIHRpw6p1IHRo4bulIHRy4buxYyB0aeG6v3ApIGPDsyAyLDY1NiBz4bqjbiBwaOG6qW0sIGNoaeG6v20ga2hv4bqjbmcgMTguNCUuIE5ow7NtIG7DoHkgY8OzIHRo4buDIGfhu5NtIGPDoWMgduG6rXQgZOG7pW5nLCBk4bulbmcgY+G7pSBob+G6t2Mgc+G6o24gcGjhuqltIGTDuW5nIGzDonUgZMOgaSwga2jDtG5nIHBo4bqjaSB0acOqdSB0aOG7pSBuZ2F5Lg0KDQoNCg0KIyMjIDIuNC45LiBQcm9kdWN0RGVwYXJ0bWVudCAoUGjDom4gbG/huqFpIHPhuqNuIHBo4bqpbSBjdW5nIGPhuqVwKQ0KDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpwcm9kdWN0X2RlcHRfY291bnRzIDwtIHRhYmxlKHN1cGVybWFya2V0JFByb2R1Y3REZXBhcnRtZW50KQ0KDQpkZl9kZXB0IDwtIGFzLmRhdGEuZnJhbWUocHJvZHVjdF9kZXB0X2NvdW50cykNCmNvbG5hbWVzKGRmX2RlcHQpIDwtIGMoIlByb2R1Y3REZXBhcnRtZW50IiwgIkNvdW50IikNCg0KZGZfZGVwdCA8LSBkZl9kZXB0ICU+JQ0KICBtdXRhdGUoUGVyY2VudCA9IHJvdW5kKENvdW50IC8gc3VtKENvdW50KSAqIDEwMCwgMikpICU+JQ0KICBhcnJhbmdlKGRlc2MoQ291bnQpKQ0KDQpwcmludChkZl9kZXB0KQ0KDQpgYGANCkLhuqNuZyBz4buRIGxp4buHdSBjaG8gdGjhuqV5Og0KDQotIFByb2R1Y2UgKDE5OTQpLCBTbmFjayBGb29kcyAoMTYwMCksIEhvdXNlaG9sZCAoMTQyMCkgdsOgIEZyb3plbiBGb29kcyAoMTM4MikgbMOgIGPDoWMgbmjDs20gc+G6o24gcGjhuqltIGPDsyBz4buRIGzGsOG7o25nIGzhu5tuIG5o4bqldCwgY2hp4bq/bSBwaOG6p24gbOG7m24gdHJvbmcgdOG7lW5nIHPhu5Egc+G6o24gcGjhuqltLiDEkMOieSBjw7MgdGjhu4MgbMOgIG5ow7NtIGtow6FjaCBow6BuZyBtdWEgbmhp4buBdSBob+G6t2MgbmjDs20gaMOgbmcgY2jhu6cgbOG7sWMuDQoNCi0gQ8OhYyBuaMOzbSBuaMawIEJha2luZyBHb29kcyAoMTA3MiksIENhbm5lZCBGb29kcyAoOTc3KSwgRGFpcnkgKDkwMyksIHbDoCBIZWFsdGggYW5kIEh5Z2llbmUgKDg5MykgY8WpbmcgY8OzIHPhu5EgbMaw4bujbmcga2jDoSBjYW8sIGNobyB0aOG6pXkgbmh1IGPhuqd1IMSRYSBk4bqhbmcuDQoNCi0gTeG7mXQgc+G7kSBuaMOzbSBuaMawIENhcm91c2VsICg1OSksIENoZWNrb3V0ICg4MiksIE1lYXQgKDg5KSwgdsOgIFNlYWZvb2QgKDEwMikgY8OzIHPhu5EgbMaw4bujbmcgdGjhuqVwIGjGoW4sIGPDsyB0aOG7gyBsw6AgbmjDs20gc+G6o24gcGjhuqltIGNodXnDqm4gYmnhu4d0IGhv4bq3YyDDrXQgcGjhu5UgYmnhur9uIGjGoW4uDQoNCi0gQ8OhYyBuaMOzbSBjw7JuIGzhuqFpIG7hurFtIOG7nyBt4bupYyB0cnVuZyBiw6xuaCwgcGjhuqNuIMOhbmggc+G7sSBwaMOibiBi4buRIGtow6EgxJFhIGThuqFuZyB0cm9uZyBjw6FjIG3hurd0IGjDoG5nIGPhu6dhIHNpw6p1IHRo4buLLg0KDQojIyMgMi40LjEwLiBQcm9kdWN0Q2F0ZWdvcnkgKFBow6JuIGxv4bqhaSBkYW5oIG3hu6VjIHPhuqNuIHBo4bqpbSkNCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCg0KIyBU4bqhbyBi4bqjbmcgdOG6p24gc3XhuqV0IMSR4bq/bSBz4buRIGzGsOG7o25nIHRoZW8gUHJvZHVjdENhdGVnb3J5DQpwcm9kdWN0X2NhdF9jb3VudHMgPC0gc3VwZXJtYXJrZXQgJT4lDQogIGdyb3VwX2J5KFByb2R1Y3RDYXRlZ29yeSkgJT4lDQogIHN1bW1hcmlzZShDb3VudCA9IG4oKSkgJT4lDQogIGFycmFuZ2UoZGVzYyhDb3VudCkpICU+JQ0KICBtdXRhdGUoUGVyY2VudGFnZSA9IHJvdW5kKENvdW50IC8gc3VtKENvdW50KSAqIDEwMCwgMikpDQoNCiMgSW4gYuG6o25nIGvhur90IHF14bqjDQpwcmludChwcm9kdWN0X2NhdF9jb3VudHMpDQoNCmBgYA0KDQpLaMOhY2ggaMOgbmcgdOG6rXAgdHJ1bmcgbmhp4buBdSB2w6BvIGPDoWMgbmjDs20gdGjhu7FjIHBo4bqpbSB0xrDGoWkgc+G7kW5nLCDEkcO0bmcgbOG6oW5oLCDEkeG7kyDEg24gbmjhurksIHbDoCBjw6FjIHPhuqNuIHBo4bqpbSBnaWEgZOG7pW5nLiBDw6FjIG5ow7NtIG5o4buPIGjGoW4gY8OzIHRo4buDIGzDoCBjw6FjIG3hurd0IGjDoG5nIMSR4bq3YyB0aMO5IGhv4bq3YyDDrXQgcGjhu5UgYmnhur9uIGjGoW4uDQoNCipOaMOzbSBjw7Mgc+G7kSBsxrDhu6NuZyBjYW8gbmjhuqV0OioNCg0KLSBQcm9kdWNlICgxOTk0KSDigJQgdOG7qWMgY8OhYyBsb+G6oWkgcmF1IGPhu6cgcXXhuqMgdMawxqFpLCBy4bqldCDEkcaw4bujYyDGsGEgY2h14buZbmcuDQoNCi0gRnJvemVuIEZvb2RzICgxMzgyKSB2w6AgSG91c2Vob2xkICgxNDIwKSBjxaluZyBraMOhIGNhbywgY2hvIHRo4bqleSBuaHUgY+G6p3UgZMO5bmcgdGjhu7FjIHBo4bqpbSDEkcO0bmcgbOG6oW5oIHbDoCBow6BuZyBnaWEgZOG7pW5nIGzhu5tuLg0KDQotIFNuYWNrIEZvb2RzICgxNjAwKSB2w6AgQmFraW5nIEdvb2RzICgxMDcyKSBjxaluZyBu4buVaSBi4bqtdCwgcGjhuqNuIMOhbmggdGjhu4sgdHLGsOG7nW5nIMSDbiB24bq3dCB2w6AgbMOgbSBiw6FuaCBwaMOhdCB0cmnhu4NuLg0KDQoqTmjDs20gY8OzIHPhu5EgbMaw4bujbmcgdGjhuqVwIG5o4bqldDoqDQoNCi0gQ2Fyb3VzZWwgKDU5KSwgQ2hlY2tvdXQgKDgyKSwgTWVhdCAoODkpIGPDsyBz4buRIGzGsOG7o25nIMOtdCBoxqFuLCBjw7MgdGjhu4MgZG8gxJHhurdjIHRow7kgc+G6o24gcGjhuqltIGhv4bq3YyBjw6FjaCBwaMOibiBsb+G6oWkuDQoNCi0gQmFraW5nIEdvb2RzIHRo4bqlcCBoxqFuIG5oaeG7gXUgbmjDs20sIG5oxrBuZyB24bqrbiB0xrDGoW5nIMSR4buRaS4NCg0KIyMgMi41LiBUaOG7kW5nIGvDqiBtw7QgdOG6oyBiaeG6v24gxJHhu4tuaCBsxrDhu6NuZw0KDQojIyMgMi41LjEuIENoaWxkcmVuIChT4buRIGNvbiB0cm9uZyBnaWEgxJHDrG5oKQ0KDQoNCmBgYHtyfQ0KY2hpbGRyZW5fY291bnRzIDwtIHRhYmxlKHN1cGVybWFya2V0JENoaWxkcmVuKQ0KY2hpbGRyZW5fY291bnRzDQoNCmNoaWxkcmVuX3BlcmNlbnQgPC0gcHJvcC50YWJsZShjaGlsZHJlbl9jb3VudHMpICogMTAwDQpyb3VuZChjaGlsZHJlbl9wZXJjZW50LCAxKSAgIyBsw6BtIHRyw7JuIDEgY2jhu68gc+G7kSB0aOG6rXAgcGjDom4NCg0KYGBgDQoNCmBgYHtyfQ0KYmFycGxvdChjaGlsZHJlbl9jb3VudHMsDQogICAgICAgIG1haW4gPSAiU+G7kSBsxrDhu6NuZyBjb24gdHJvbmcgZ2lhIMSRw6xuaCBraMOhY2ggaMOgbmciLA0KICAgICAgICB4bGFiID0gIlPhu5EgY29uIiwNCiAgICAgICAgeWxhYiA9ICJT4buRIGzGsOG7o25nIGdpYSDEkcOsbmgiLA0KICAgICAgICBjb2wgPSAic2t5Ymx1ZSIpDQoNCmBgYA0KDQoNCg0KQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbjoNCg0KLSBHaWEgxJHDrG5oIGtow7RuZyBjw7MgY29uIGNoaeG6v20gMSwzNDQgaOG7mSBjaGnhur9tIGtob+G6o25nIDglIHThu5VuZyBz4buRICh0w7RpIHPhur0gdMOtbmggJSBj4bulIHRo4buDIGLDqm4gZMaw4bubaSkuDQoNCi0gQ8OhYyBnaWEgxJHDrG5oIGPDsyB04burIDEgxJHhur9uIDQgY29uIGNoaeG6v20gxJFhIHPhu5EgKGNoaeG6v20ga2hv4bqjbmcgODAlIHThu5VuZyksIHbDoCB04bu3IGzhu4cgcGjDom4gYuG7kSBraMOhIMSR4buTbmcgxJHhu4F1IGdp4buvYSBjw6FjIG5ow7NtIG7DoHksICBt4buXaSBuaMOzbSBjaGnhur9tIGtob+G6o25nIDE2JS0xNyUuDQoNCi0gR2lhIMSRw6xuaCBjw7MgNSBjb24gdHLhu58gbMOqbiBnaeG6o20gY8OybiAxLDQzOSBo4buZIGtob+G6o25nIDklLg0KDQojIyMgMi41LjIuIFVuaXRzU29sZCAoU+G6o24gcGjhuqltIGLDoW4gcmEpDQoNCmBgYHtyfQ0KdW5pdHNfc29sZF9jb3VudHMgPC0gdGFibGUoc3VwZXJtYXJrZXQkVW5pdHNTb2xkKQ0KcHJpbnQodW5pdHNfc29sZF9jb3VudHMpDQoNCnN1bW1hcnkoc3VwZXJtYXJrZXQkVW5pdHNTb2xkKQ0Kc2Qoc3VwZXJtYXJrZXQkVW5pdHNTb2xkKQ0KDQpgYGANCg0KDQpgYGB7cn0NCnVuaXRzX2NvdW50cyA8LSB0YWJsZShzdXBlcm1hcmtldCRVbml0c1NvbGQpDQoNCmJhcl9wb3NpdGlvbnMgPC0gYmFycGxvdCgNCiAgdW5pdHNfY291bnRzLA0KICBtYWluID0gIlBow6JuIGLhu5Egc+G7kSBsxrDhu6NuZyBz4bqjbiBwaOG6qW0gYsOhbiB0aGVvIFVuaXRzU29sZCIsDQogIHhsYWIgPSAiU+G7kSBsxrDhu6NuZyBz4bqjbiBwaOG6qW0gYsOhbiAoVW5pdHNTb2xkKSIsDQogIHlsYWIgPSAiU+G7kSBs4bqnIiwNCiAgY29sID0gInN0ZWVsYmx1ZSIsDQogIGJvcmRlciA9ICJibGFjayINCikNCg0KIyBUaMOqbSBuaMOjbiBz4buRIGzDqm4gdHLDqm4gbeG7l2kgY+G7mXQNCnRleHQoDQogIHggPSBiYXJfcG9zaXRpb25zLA0KICB5ID0gdW5pdHNfY291bnRzLA0KICBsYWJlbHMgPSB1bml0c19jb3VudHMsDQogIHBvcyA9IDMsICAgICAgICAgICAgIyBW4buLIHRyw60gdHLDqm4gxJHhuqd1IGPhu5l0DQogIGNleCA9IDAuOCwgICAgICAgICAgIyBLw61jaCBj4buhIGNo4buvDQogIGNvbCA9ICJibGFjayINCikNCg0KDQpgYGANCg0KUGjhuqduIGzhu5tuIGtow6FjaCBow6BuZyB0cm9uZyBk4buvIGxp4buHdSBjaOG7jW4gbXVhIHThu6sgMyDEkeG6v24gNSBz4bqjbiBwaOG6qW0gdHJvbmcgbeG7l2kgxJHGoW4gaMOgbmcsIHRo4buDIGhp4buHbiB4dSBoxrDhu5tuZyBtdWEgaMOgbmcgduG7q2EgcGjhuqNpLCBraMO0bmcgcXXDoSDDrXQgY8Wpbmcga2jDtG5nIHF1w6Egbmhp4buBdS4gTeG7qWMgbXVhIGPhu7FjIHRo4bqlcCAoMSBz4bqjbiBwaOG6qW0pIGhv4bq3YyBy4bqldCBjYW8gKDctOCBz4bqjbiBwaOG6qW0pIGNo4buJIGNoaeG6v20gcGjhuqduIG5o4buPIHRyb25nIHThu5VuZyBz4buRIMSRxqFuIGjDoG5nLg0KDQotIFPhu5EgbMaw4bujbmcgYsOhbiBuaGnhu4F1IG5o4bqldCByxqFpIHbDoG8gbmjDs20gNCBz4bqjbiBwaOG6qW0sIHbhu5tpIDQzNzkgxJHGoW4gduG7iywgY2hp4bq/bSB04bu3IHRy4buNbmcgbOG7m24gbmjhuqV0IHRyb25nIHThu5VuZyBwaMOibiBi4buRLg0KDQotIE5ow7NtIDMgdsOgIDUgc+G6o24gcGjhuqltIGPFqW5nIHLhuqV0IHBo4buVIGJp4bq/biwgbOG6p24gbMaw4bujdCBjw7MgMzI4OSB2w6AgMzU2MiDEkcahbiB24buLLCBjaOG7iSB0aOG6pXAgaMahbiBuaMOzbSA0IGNow7p0Lg0KDQotIE5ow7NtIDIgc+G6o24gcGjhuqltIGPFqW5nIGPDsyBz4buRIGzGsOG7o25nIGtow6EgbOG7m24sIDExMzAgxJHGoW4gduG7iy4NCg0KLSBT4buRIGzGsOG7o25nIGLDoW4g4bufIGPDoWMgbmjDs20gbmjhu48gKDEgc+G6o24gcGjhuqltKSB2w6AgbmjDs20gbOG7m24gKDcsIDggc+G6o24gcGjhuqltKSBy4bqldCDDrXQsIMSR4bq3YyBiaeG7h3QgbmjDs20gOCBjaOG7iSBjw7MgMiDEkcahbiB24buLLg0KDQojIyMgMi41LjMuIFJldmVudWUgKERvYW5oIHRodSkNCg0KYGBge3J9DQojIENodXnhu4NuIFJldmVudWUgc2FuZyBudW1lcmljDQpzdXBlcm1hcmtldCRSZXZlbnVlIDwtIGFzLm51bWVyaWMoc3VwZXJtYXJrZXQkUmV2ZW51ZSkNCg0KIyBO4bq/dSBjw7MgTkEgZG8gY2h1eeG7g24ga2jDtG5nIHRow6BuaCBjw7RuZyAodsOtIGThu6UgY8OzIGvDvSB04buxIGzhuqEpLCBsb+G6oWkgYuG7jyBOQSBraGkgdMOtbmgNCnJldmVudWVfY2xlYW4gPC0gbmEub21pdChzdXBlcm1hcmtldCRSZXZlbnVlKQ0KDQojIFTDrW5oIGPDoWMgdGjhu5FuZyBrw6oNCnN1bW1hcnkocmV2ZW51ZV9jbGVhbikNCnNkKHJldmVudWVfY2xlYW4pDQptaW4ocmV2ZW51ZV9jbGVhbikNCm1heChyZXZlbnVlX2NsZWFuKQ0KbWVkaWFuKHJldmVudWVfY2xlYW4pDQptZWFuKHJldmVudWVfY2xlYW4pDQoNCmBgYA0KDQotIE1pbiA9IDAuNTM6IEPDsyBraMOhY2ggbXVhIHLhuqV0IMOtdCB0aeG7gW4sIGNo4buJIGtob+G6o25nIDUzIGNlbnQgKHbDrSBk4bulIG11YSBtw7NuIG5o4buPLCBiw6FuaCBr4bq5bykuDQoNCi0gTWVkaWFuID0gMTEuMjU6IFBo4bqnbiBs4bubbiBnaWFvIGThu4tjaCBjw7MgZ2nDoSB0cuG7iyBraG/huqNuZyAxMS4yNSDEkcO0IGxhIChnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIG3hu5l0IGzhuqduIG11YSBow6BuZykuDQoNCi0gTWVhbiA9IDEzLjAwOiBUcnVuZyBiw6xuaCBt4buXaSBs4bqnbiBtdWEgbMOgIDEzIMSRw7QgbGEsIGPDsyBuZ2jEqWEgY8OzIG5o4buvbmcgZ2lhbyBk4buLY2ggbOG7m24gaMahbiBt4bupYyB0cnVuZyB24buLIGzDoG0gdMSDbmcgdHJ1bmcgYsOsbmguDQoNCi0gTWF4ID0gNTYuNzogQ8OzIG5o4buvbmcgZ2lhbyBk4buLY2ggbXVhIGtow6EgbOG7m24sIGPDsyB0aOG7gyBtdWEgbmhp4buBdSBtw7NuIGhv4bq3YyBow6BuZyBjYW8gY+G6pXAuDQoNCg==