source("../config/Rmarkdown_config.R") # 依赖包的导入和一系列 Rmarkdown 设置

Data Processing

Read Data

# 一些标量常数
scalar <- jsonlite::fromJSON("../data/scalar.json")

# 国家代码表
country_table <- fread("../data/country_code.csv")

# 国别原始数据
nominal_variables <- fread("../data/nominal_variable.csv")

# TABLE III 中所有虚拟变量的系数估计值
load("../data/estimation-output.rda")

Data Transformation

## 1. scalars
beta <- scalar$beta
N <- scalar$N
theta <- scalar$theta[2]


## 2. exchange rate
exchange_rate <- nominal_variables$exchange_rate


## 3. trade data

# nominal bilateral trade
Xni_nominal <- nominal_variables[, -1:-6] %>%
  as.matrix() %>%
  set_colnames(NULL) %>% # 去掉列名
  `*`(10^6)

# real bilateral trade
Xni <- Xni_nominal / exchange_rate # 自动扩展除数为矩阵
Xnn <- diag(Xni)

# expenditure on manufacturing goods
Xn <- Xni %>% apply(1, sum)

imports <- Xn - Xnn
exports <- Xni %>% apply(2, sum) - Xnn


## 4. manufacturing labor and wage
industrial_labor <- nominal_variables$industrial_labor
nominal_wage <- nominal_variables$nominal_wage # 已经以美元计价

edu_year <- nominal_variables$edu_year

effective_labor <- industrial_labor * exp(0.06 * edu_year)
effective_wage <- nominal_wage * exp(-0.06 * edu_year)


## 5. income/expenditure

# GDP in dollars
Y <- nominal_variables$gdp * 10^6 / exchange_rate

# manufacturing labor income
Y_l <- effective_wage * effective_labor

# non-manufacturing income
Y_o <- Y - Y_l


## 6. beta and alpha

# beta = manufacturing labor income / manufacturing output
beta_vector <- Y_l / (Xnn + exports)
beta_vector # 不知作者如何加权得出了 beta = 0.21221 这个数值
#>  [1] 0.2048066 0.2199798 0.2066407 0.2212934 0.2857265 0.2421040 0.2378501
#>  [8] 0.2689012 0.1719368 0.2028115 0.1814813 0.2173568 0.2040843 0.1771063
#> [15] 0.1639859 0.2148792 0.2558769 0.2562417 0.2472988
# alpha = manufacturing expenditure / total expenditure
alpha_vector <- (Y_l + imports - exports) / Y
alpha_vector
#>  [1] 0.1385866 0.1858399 0.1044874 0.1008060 0.1098789 0.1212415 0.1455694
#>  [8] 0.1635214 0.1744161 0.1191180 0.1159666 0.1039748 0.1366774 0.0751703
#> [15] 0.1730889 0.1528177 0.1274808 0.1810510 0.1340285
# 各国按GDP加权计算 alpha
alpha <- (alpha_vector * Y / sum(Y)) %>% sum()
alpha
#> [1] 0.1348136
## 7. technology
# 表示技术的 T 来源于 (27) 式
# 计算所需的 source dummies 的估计系数见 TABLE VI
source_estimate <- table3_estimate[11:29]

# 这个 tech 使用的都是绝对数据
absolute_tech <- log(effective_wage) %>%
  `*`(theta) %>%
  `+`(source_estimate) %>%
  `*`(beta) %>%
  exp()
# 用绝对数据,保持准确量纲,便于 wL 直接与 Y/Y_o 相比


## 8. geography barrier
# dni^{-theta} 矩阵
Dni <- exp(barrier_measure)
# barrier_measure 来源于 (28) 式,为 -theta ln(dni)
# 用 (30) 式计算 barrier_measure 时,所需的 barrier dummies 的估计系数见 TABLE VII


## 9. gamma constant
gamma <- beta^(beta) * (1 - beta)^(1 - beta) # 不知为何 gamma 可以由 beta 推出
g <- gamma^(-theta)

Section 4

求解一般均衡模型的多元非线性方程组,作为反事实模拟的 baseline

求解多元非线性方程组

Counterfactual Simulation 的前提,是求解多元非线性方程组 \(\boldsymbol{F}(\boldsymbol{x})=0\). 这样,对于任何情形,确定了方程组的参数后,便可解出我们希望查看的变量。

最常用的数值解法,是 Newton-Raphson 迭代法:

\(\boldsymbol{F}(\boldsymbol{x})\) 关于 \(\boldsymbol{x}\) 的 Jacobi 矩阵 \[ \begin{aligned} \boldsymbol{J}(\boldsymbol{x}) \equiv \frac{\partial \boldsymbol{F}}{\partial \boldsymbol{x}} \end{aligned}=\left[\begin{array}{cccc} \frac{\partial f_{1}}{\partial x_{1}} & \frac{\partial f_{1}}{\partial x_{2}} & \cdots & \frac{\partial f_{1}}{\partial x_{n}} \\ \frac{\partial f_{2}}{\partial x_{1}} & \frac{\partial f_{2}}{\partial x_{2}} & \cdots & \frac{\partial f_{2}}{\partial x_{n}} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial f_{n}}{\partial x_{1}} & \frac{\partial f_{n}}{\partial x_{2}} & \cdots & \frac{\partial f_{n}}{\partial x_{n}} \end{array}\right] \] 可逆,令 \[ \boldsymbol{x}^{k+1}=\boldsymbol{x}^k-\boldsymbol{J}^{-1}(\boldsymbol{x}^k)\boldsymbol{F}(\boldsymbol{x}^k) \] \(\boldsymbol{x}^k\) 就组成了一个序列。若这个序列收敛,即 \(\boldsymbol{F}(\boldsymbol{x}^k) \to 0\),便能在适当的精度下找到方程组的近似数值解。

具体做法为:

  1. 确定初始向量 \(\boldsymbol{x}^0\),最大迭代次数 \(N\) 和精度要求 \(\varepsilon\),然后开启循环
  2. \(\boldsymbol{d}^k=\boldsymbol{J}^{-1}(\boldsymbol{x}^k)\boldsymbol{F}(\boldsymbol{x}^k)\)\(\boldsymbol{d}^k\) 即线性方程组 \(\boldsymbol{J}(\boldsymbol{x}^k)\boldsymbol{d}=\boldsymbol{F}(\boldsymbol{x}^k)\) 的解)
  3. \(|\boldsymbol{d}^k|<\varepsilon\)\(k=N\),则停止计算;否则,令 \(\boldsymbol{x}^{k+1}=\boldsymbol{x}^k-\boldsymbol{d}^k\),然后回到第二步计算 \(\boldsymbol{d}^{k+1}\),直到精度满足要求或迭代次数耗尽。
  4. 当精度满足要求时,迭代所得的 \(\boldsymbol{x}\) 就可以作为 \(\boldsymbol{F}(\boldsymbol{x})=0\) 的根。

一般均衡模型的矩阵形式

当使用支持向量化操作的语言编程时,最好先将模型都写成矩阵形式。因为数据多以向量和矩阵的形式保存,矩阵运算本身就是相当完善的伪代码,使真正的代码编写变得非常省脑。

\(P_n=p_n^{-\theta}\)\(g=\gamma^{-\theta}\)\(D_{ni}=d_{ni}^{-\theta} \in (0,1]\)\(k_i=gT_iw_i^{-\beta\theta}\)

源代码中用 \(\beta^\beta(1-\beta)^{1-\beta}\) 作为 \(\gamma\) 值,理由何在?(9) 式中,\(\gamma\) 明明是由 \(\theta\)\(\sigma\) 决定的。

情境一:劳动力可跨部门流动

制造业部门雇佣劳动力可变,工资不变(由非贸易部门决定),国民收入不变。

已知工资、技术、地理障碍、国民收入数据

  1. 由 (16) 式解出均衡价格
  2. 通过 (17) 式计算贸易份额
  3. 通过 (20) 式计算制造业劳动力
  4. 通过 (19) 式计算对制造业产品的支出,再结合 (17) 式即可知双边贸易量
  5. 最后由 \(W_{n}=Y_{n} / p_{n}^{\alpha}\) 计算福利水平

将 (16) 式写为矩阵形式:

\[ \begin{bmatrix} P_1 \\ \vdots \\ P_N \end{bmatrix} = \boldsymbol{D}\left( \boldsymbol{k} \circ \begin{bmatrix} P_1^{1-\beta} \\ \vdots \\ P_N^{1-\beta} \end{bmatrix} \right) \]

其中

\(\boldsymbol{D} = \begin{bmatrix} D_{11} & D_{12} & \cdots & D_{1N} \\ \vdots & \vdots & \vdots & \vdots \\ D_{N1} & D_{N2} & \cdots & D_{NN} \end{bmatrix}\)\(\boldsymbol{k}=\begin{bmatrix} k_1 \\ \vdots \\ k_N \end{bmatrix}=g \cdot \begin{bmatrix} T_1 \\ \vdots \\ T_N \end{bmatrix} \circ \begin{bmatrix} w_1^{-\beta\theta} \\ \vdots \\ w_N^{-\beta\theta} \end{bmatrix}\)

\(\circ\) 表示哈达马积(矩阵的对应元素相乘),则 (16) 式所代表的 \(N\) 元非线性方程组可以写为 \[ \boldsymbol{D}^{-1}\begin{bmatrix} P_1 \\ \vdots \\ P_N \end{bmatrix} - g \cdot \begin{bmatrix} T_1 \\ \vdots \\ T_N \end{bmatrix} \circ \begin{bmatrix} w_1^{-\beta\theta} \\ \vdots \\ w_N^{-\beta\theta} \end{bmatrix} \circ \begin{bmatrix} P_1^{1-\beta} \\ \vdots \\ P_N^{1-\beta} \end{bmatrix} = \boldsymbol{0} \] 由于工资不变,仅有 \(P_n\)\(N\) 个未知数,可以用 Newton-Raphson 迭代法求 \(P_n\) 的数值解。

使用 Newton-Raphson Method 时,需要定义迭代的初值。

由理论不难推断,\(P_n\) 是存在上下限的:

  1. Autarky 时,价格水平 \(p_n\) 最高,\(P_n\) 取得最小值。此时 \(d_{ni} \to \infty, D_{ni} = 0, \forall n \neq i\),从而 \(\boldsymbol{D}\) 为单位矩阵 \(\boldsymbol{I}_N\),从方程组中解得 \(P_n^{low} = k_n^{1/\beta}\)
  2. 零贸易障碍时,能买到国外便宜的商品,且加价为 \(0\),故价格水平 \(p_n\) 最低,\(P_n\) 取得最大值。此时 \(D_{ni} = d_{ni} = 1, \forall n \neq i\),从而 \(\boldsymbol{D}\) 为全 \(1\) 矩阵,从方程组中解得 \(P_n^{high} = \left({\textstyle \sum_{n=1}^{N} k_n} \right)^{1/\beta}\)

最好使用 \(P_n^{low}\)\(P_n^{high}\) 之间的数值作为迭代初值,迭代序列一般都能顺利收敛

此外,由于 \(P_n^{low}\)\(P_n^{high}\) 要在 Newton-Raphson 迭代之外算出来,所以 \(k_i=gT_iw_i^{-\beta\theta}\) 也必须提前算好。

将 (17) 式的标量形式 \(\pi_{ni}=k_iD_{ni}P_i^{1-\beta}/P_n\) 改写为矩阵形式,即可计算 \(\boldsymbol{\Pi}\)

\[ \boldsymbol{\Pi}=\begin{bmatrix} \pi_{11} & \pi_{12} & \cdots & \pi_{1N} \\ \vdots & \vdots & \vdots & \vdots \\ \pi_{N1} & \pi_{N2} & \cdots & \pi_{NN} \end{bmatrix}=\boldsymbol{D} \circ \left( \begin{bmatrix} 1/P_1 \\ \cdots \\ 1/P_N \end{bmatrix}\otimes \left( g \cdot \begin{bmatrix} T_1 \\ \vdots \\ T_N \end{bmatrix} \circ \begin{bmatrix} w_1^{-\beta\theta} \\ \vdots \\ w_N^{-\beta\theta} \end{bmatrix} \circ \begin{bmatrix} P_1^{1-\beta} \\ \vdots \\ P_N^{1-\beta} \end{bmatrix}\right)'\right) \]

\(\otimes\) 表示克罗内克积

将 (20) 式写为矩阵形式:

\[ \begin{bmatrix} w_1L_1 \\ \vdots \\ w_NL_N \end{bmatrix} = (1-\beta)\boldsymbol{\Pi}'\begin{bmatrix} w_1L_1 \\ \vdots \\ w_NL_N \end{bmatrix}+\alpha\beta\boldsymbol{\Pi}'\begin{bmatrix} Y_1 \\ \vdots \\ Y_N \end{bmatrix} \]

为求解各国制造业劳动力向量 \(\boldsymbol{L}\),将其变形为

\[ \begin{bmatrix} L_1 \\ \vdots \\ L_N \end{bmatrix} = \alpha\beta\begin{bmatrix} 1/w_1 \\ \vdots \\ 1/w_N \end{bmatrix}\circ\left(\left(I_N-(1-\beta)\boldsymbol{\Pi}'\right)^{-1}\boldsymbol{\Pi}'\begin{bmatrix} Y_1 \\ \vdots \\ Y_N \end{bmatrix}\right) \]

将 (19) 式写为矩阵形式:

\[ \boldsymbol{X_n} \equiv \begin{bmatrix} X_1 \\ \vdots \\ X_N \end{bmatrix} =\begin{bmatrix} w_1 \\ \vdots \\ w_N \end{bmatrix} \circ \begin{bmatrix} L_1 \\ \vdots \\ L_N \end{bmatrix} *(1-\beta)/\beta+\alpha\begin{bmatrix} Y_1 \\ \vdots \\ Y_N \end{bmatrix} \] 从而由 (17) 式知双边贸易量矩阵 \[ \boldsymbol{X}_{ni} \equiv \begin{bmatrix} X_{11} & X_{12} & \cdots & X_{1N} \\ \vdots & \vdots & \vdots & \vdots \\ X_{N1} & X_{N2} & \cdots & X_{NN} \end{bmatrix}=\boldsymbol{\Pi} \circ \left(\begin{bmatrix} X_1 \\ \vdots \\ X_N \end{bmatrix} \otimes [1 \cdots 1] \right) \] 该矩阵所有元素的和减去迹即为 19 国之间的双边贸易总量 \[ \text{trade volumn}= \sum_{n=1}^N\sum_{i=1}^N X_{ni}-tr(\boldsymbol{X}_{ni}) \]

最后,福利水平为 \[ \begin{bmatrix} W_1 \\ \vdots \\ W_N \end{bmatrix} =\begin{bmatrix} Y_1 \\ \vdots \\ Y_N \end{bmatrix} \circ \begin{bmatrix} 1/p_1^{\alpha} \\ \vdots \\ 1/p_N^{\alpha} \end{bmatrix}=\begin{bmatrix} Y_1 \\ \vdots \\ Y_N \end{bmatrix} \circ \begin{bmatrix} P_1^{\alpha/\theta} \\ \vdots \\ P_N^{\alpha/\theta} \end{bmatrix} \]

模型输出三个向量 \(\boldsymbol{p}=\boldsymbol{P}^{-1/\theta}\), \(\boldsymbol{L}\), \(\boldsymbol{W}\), 一个矩阵 \(\boldsymbol{X}_{ni}\), 一个标量 \(\text{trade volumn}\)

注:为了便于后续使用,输出 \(p_n\) 而非 \(P_n\)

情境二:劳动力不可跨部门流动

制造业部门工资可变,雇佣劳动力不变,国民收入可变,非制造业劳动力收入不变。

已知制造业劳动力、技术、地理障碍、非制造业劳动力收入数据

  1. 由 (16)、(21) 式联立计算出均衡工资、均衡价格
  2. 通过 (17) 式计算贸易份额
  3. 通过 (19) 式计算对制造业产品的支出,再结合 (17) 式即可知双边贸易量
  4. 最后由 \(W_{n}=(w_nL_n+Y_{n}^o) / p_{n}^{\alpha}\) 计算福利水平

将 (21) 式写为矩阵形式:

\[ \left[I_N-(1-\beta+\alpha\beta)\boldsymbol{\Pi}'\right]\begin{bmatrix} w_1 \\ \vdots \\ w_N \end{bmatrix} \circ \begin{bmatrix} L_1 \\ \vdots \\ L_N \end{bmatrix}-\alpha\beta \boldsymbol{\Pi}'\begin{bmatrix} Y_1^o \\ \vdots \\ Y_N^o \end{bmatrix}=\boldsymbol{0} \]

其中非制造业收入 \(Y_n^o\)、制造业劳动力 \(L_n\) 为常量。但这 \(N\) 个方程无法解出工资向量 \(w_n\),因为 \(\boldsymbol{\Pi}\) 中还含有 \(P_n\)

\(N\) 个方程需要与 (16) 式代表的 \(N\) 个方程 \[ \boldsymbol{D}^{-1}\begin{bmatrix} P_1 \\ \vdots \\ P_N \end{bmatrix} - g \cdot \begin{bmatrix} T_1 \\ \vdots \\ T_N \end{bmatrix} \circ \begin{bmatrix} w_1^{-\beta\theta} \\ \vdots \\ w_N^{-\beta\theta} \end{bmatrix} \circ \begin{bmatrix} P_1^{1-\beta} \\ \vdots \\ P_N^{1-\beta} \end{bmatrix} = \boldsymbol{0} \] 联立,才能解出 \(w_n\)\(P_n\). 因此,这是一个 \(2N\) 元非线性方程组的求解问题。

解出 \(w_n\)\(P_n\) 后,同样从 (17) 式可计算 \[ \boldsymbol{\Pi}=\begin{bmatrix} \pi_{11} & \pi_{12} & \cdots & \pi_{1N} \\ \vdots & \vdots & \vdots & \vdots \\ \pi_{N1} & \pi_{N2} & \cdots & \pi_{NN} \end{bmatrix}=\boldsymbol{D} \circ \left( \begin{bmatrix} 1/P_1 \\ \cdots \\ 1/P_N \end{bmatrix}\otimes \left( g \cdot \begin{bmatrix} T_1 \\ \vdots \\ T_N \end{bmatrix} \circ \begin{bmatrix} w_1^{-\beta\theta} \\ \vdots \\ w_N^{-\beta\theta} \end{bmatrix} \circ \begin{bmatrix} P_1^{1-\beta} \\ \vdots \\ P_N^{1-\beta} \end{bmatrix}\right)'\right) \] 由 (19) 式可计算 \[ \boldsymbol{X}_n \equiv \begin{bmatrix} X_1 \\ \vdots \\ X_N \end{bmatrix} =\begin{bmatrix} w_1 \\ \vdots \\ w_N \end{bmatrix} \circ \begin{bmatrix} L_1 \\ \vdots \\ L_N \end{bmatrix} *\left(\alpha+\frac{1-\beta}{\beta}\right)+\alpha\begin{bmatrix} Y_1^o \\ \vdots \\ Y_N^o \end{bmatrix} \]

再代入 (17) 式即得双边贸易量矩阵 \[ \boldsymbol{X}_{ni} \equiv \begin{bmatrix} X_{11} & X_{12} & \cdots & X_{1N} \\ \vdots & \vdots & \vdots & \vdots \\ X_{N1} & X_{N2} & \cdots & X_{NN} \end{bmatrix}=\boldsymbol{\Pi} \circ \left(\begin{bmatrix} X_1 \\ \vdots \\ X_N \end{bmatrix} \otimes [1 \cdots 1] \right) \]

该矩阵所有元素的和减去迹即为 19 国之间的双边贸易总量 \[ \text{trade volumn} = \sum_{n=1}^N\sum_{i=1}^N X_{ni}-tr(\boldsymbol{X}_{ni}) \]

最后,福利水平为 \[ \begin{bmatrix} W_1 \\ \vdots \\ W_N \end{bmatrix} = \left( \begin{bmatrix} w_1 \\ \vdots \\ w_N \end{bmatrix} \circ \begin{bmatrix} L_1 \\ \vdots \\ L_N \end{bmatrix} + \begin{bmatrix} Y_1^o \\ \vdots \\ Y_N^o \end{bmatrix} \right) \circ \begin{bmatrix} P_1^{\alpha/\theta} \\ \vdots \\ P_N^{\alpha/\theta} \end{bmatrix} \]

模型输出三个向量 \(\boldsymbol{p}\), \(\boldsymbol{w}\), \(\boldsymbol{W}\), 一个矩阵 \(\boldsymbol{X}_{ni}\), 一个标量 \(\text{trade volumn}\)

总结:参数与输出

情境一:mobile labor 情境二:immobile labor
不变参数 制造业工资 \(\boldsymbol{w}\)、国民收入 \(\boldsymbol{Y}\) 制造业劳动力 \(\boldsymbol{L}\)、非制造业劳动力收入 \(\boldsymbol{Y^o}\)
可变参数 地理障碍 \(\boldsymbol{D}\)、技术 \(\boldsymbol{T}\)、关税率 \(\boldsymbol{t}\) 地理障碍 \(\boldsymbol{D}\)、技术 \(\boldsymbol{T}\)、关税率 \(\boldsymbol{t}\)
模型输出 价格指数 \(\boldsymbol{p}\)、制造业劳动力 \(\boldsymbol{L}\)、福利水平 \(\boldsymbol{W}\)、双边贸易量矩阵 \(\boldsymbol{X}_{ni}\)、19 国贸易总量 \(\text{trade volumn}\) 价格指数 \(\boldsymbol{p}\)、制造业工资 \(\boldsymbol{w}\)、福利水平 \(\boldsymbol{W}\)、双边贸易量矩阵 \(\boldsymbol{X}_{ni}\)、19 国贸易总量 \(\text{trade volumn}\)

编程实现

情境一:劳动力可以跨部门流动

model_mobile <- function(tech, Dni) {
  # 不变参数
  w <- effective_wage
  Y <- Y

  # 可变参数
  T <- tech
  D <- Dni
  k <- g * T * w^(-beta * theta)

  # 设定 P 的迭代初值
  P_low <- k^(1 / beta)
  P_high <- rep(sum(k)^(1 / beta), N)
  P_start <- (P_low + P_high) / 2

  # (16) 式
  equations <- function(P) {
    solve(D) %*% P - k * P^(1 - beta)
  }
  
  # 解 P
  if (identical(D, matrix(rep(1, N^2), nrow = N))) {
    P <- P_high
  } else {
    P <- rootSolve::multiroot(
      f = equations, start = P_start,
      rtol = 1e-10, positive = TRUE
    )$root
  }
  
  # 根据 P 推导其他变量
  Pi <- D * kronecker(1 / P, t(k * P^(1 - beta)))

  L <- alpha * beta * (1 / w) * (solve(diag(N) - (1 - beta) * t(Pi)) %*% t(Pi) %*% Y) %>%
    as.vector()

  Xn <- w * L * (1 - beta) / beta + alpha * Y

  Xni <- Pi * kronecker(Xn, rep(1, N) %>% t())

  trade_volumn <- sum(Xni) - diag(Xni) %>% sum()

  W <- Y * P^(alpha / theta)

  # 输出模型结果
  list(
    p = P^(-1 / theta), L = L, W = W,
    Xni = Xni, trade_volumn = trade_volumn
  )
}

baseline_mobile <- model_mobile(absolute_tech, Dni)

情境二:劳动力不能跨部门流动

model_immobile <- function(tech, Dni) {
  # 不变参数
  L <- effective_labor
  Y_o <- Y_o

  # 可变参数
  T <- tech
  D <- Dni

  # w 初始值
  w <- effective_wage

  # 假设w已知,由(16)解出P后,可推出Y_l/w,即对劳动力的引致需求
  # 它与劳动力L的差,为超额需求,会根据一定弹性拉动w的变化
  # 然后不断迭代 w,直到超额需求为0
  for (i in 1:500) {
    # 迭代初值
    k <- g * T * w^(-beta * theta)
    P_low <- k^(1 / beta)
    P_high <- rep(sum(k)^(1 / beta), N)
    P_start <- (P_low + P_high) / 2
    
    # (16) 式
    equations <- function(P) {
      solve(D) %*% P - k * P^(1 - beta)
    }
    
    # 解 P
    if (identical(D, matrix(rep(1, N^2), nrow = N))) {
      P <- P_high
    } else {
      P <- rootSolve::multiroot(
        f = equations, start = P_start,
        rtol = 1e-10, positive = TRUE
      )$root
    }

    Pi <- D * kronecker(1 / P, t(k * P^(1 - beta)))

    # 用 (21) 式计算制造业收入(世界市场对各国制造业产品的需求)
    Y_l <- (1 - beta + alpha * beta) * t(Pi) %*% (w * L) +
      alpha * beta * t(Pi) %*% Y_o

    # 引致的超额劳动需求
    excess_labor_ratio <- (as.vector(Y_l) / w - L) / L

    tolerance <- sum(excess_labor_ratio^2) %>% sqrt()

    if (tolerance < 1e-9) {
      # 精度符合要求,可输出模型结果
      Xn <- w * L * (alpha + (1 - beta) / beta) + alpha * Y_o
      Xni <- Pi * kronecker(Xn, rep(1, N) %>% t())
      trade_volumn <- sum(Xni) - diag(Xni) %>% sum()
      W <- (w * L + Y_o) * P^(alpha / theta)

      return(list(
        p = P^(-1 / theta), w = w, W = W,
        Xni = Xni, trade_volumn = trade_volumn
      ))
    } else {
      # 对劳动的超额需求会导致工资发生变化
      w <- w * (1 + excess_labor_ratio * 0.3) # 0.3 为弹性
      # print(str_c("iterator: ", i))
    }
  }
  
  # 500 次迭代还没结果,一般来说,是因为序列不收敛
  print("not convergent")
}

baseline_immobile <- model_immobile(absolute_tech, Dni)

Section 6 Counterfactual Simulation

从一般均衡模型解出的任何一个变量 \(x\),都可用 \(\begin{aligned} 100\ln \frac{x'}{x_0}\end{aligned}\) 计算反事实模拟值 \(x'\) 相对于 baseline 值 \(x_0\) 的百分比变化

TABLE IX

提高贸易障碍至 Autarky

D_autarky <- diag(19)

autarky_mobile <- model_mobile(absolute_tech, D_autarky)
autarky_immobile <- model_immobile(absolute_tech, D_autarky)

table9 <- cbind(
  country_table$name,
  (100 * log(autarky_mobile$W / baseline_mobile$W)) %>% sprintf("%.1f", .),
  (100 * log(autarky_mobile$p / baseline_mobile$p)) %>% sprintf("%.1f", .),
  (100 * log(autarky_mobile$L / baseline_mobile$L)) %>% sprintf("%.1f", .),
  (100 * log(autarky_immobile$W / baseline_immobile$W)) %>% sprintf("%.1f", .),
  (100 * log(autarky_immobile$p / baseline_immobile$p)) %>% sprintf("%.1f", .),
  (100 * log(autarky_immobile$w / baseline_immobile$w)) %>% sprintf("%.1f", .)
) %>%
  as.data.table()


table9 %>%
  set_colnames(c(
    "Country", "Welfare", "Mfg.Prices", "Mfg.Labor", "Welfare", "Mfg.Prices", "Mfg.Wages"
  )) %>%
  prettify(
    caption = "TABLE IX \\\n The Gains from Trade: Raising Geographic Barriers"
  ) %>%
  add_header_above(c(
    " " = 1, "Mobile Labor" = 3,
    "Immobile Labor" = 3
  )) %>%
  add_header_above(c(
    " " = 1, "Percentage Change from Baseline to Autarky" = 6
  ))
TABLE IX
The Gains from Trade: Raising Geographic Barriers
Percentage Change from Baseline to Autarky
Mobile Labor
Immobile Labor
Country Welfare Mfg.Prices Mfg.Labor Welfare Mfg.Prices Mfg.Wages
Australia -1.8 13.3 62.5 -3.0 65.3 54.2
Austria -3.4 25.2 16.7 -3.3 28.1 4.1
Belgium -10.2 75.4 6.0 -10.3 79.2 3.1
Canada -4.5 33.7 -53.3 -6.6 58.3 9.9
Denmark -5.3 39.5 18.8 -5.6 59.1 18.6
Finland -2.4 18.1 11.6 -2.5 27.7 9.6
France -2.5 18.4 13.1 -2.5 27.9 9.7
Germany -1.9 14.4 -23.2 -3.2 -34.5 -47.2
Greece -3.6 26.9 99.1 -7.3 117.2 93.2
Italy -1.5 11.4 0.5 -1.8 21.3 8.6
Japan -0.2 1.3 -13.6 -0.3 -8.1 -9.7
Netherlands -8.3 61.2 16.5 -8.9 85.5 21.3
New Zealand -3.1 23.2 47.7 -3.8 62.4 41.2
Norway -3.9 28.7 28.1 -5.5 78.6 46.5
Portugal -3.5 25.9 31.4 -3.8 53.6 28.3
Spain -1.6 12.1 35.1 -1.7 32.4 22.1
Sweden -3.2 24.0 1.4 -3.2 19.1 -4.5
United Kingdom -2.8 20.6 5.7 -2.6 11.8 -7.4
United States -1.1 7.9 9.6 -0.9 15.5 9.2

TABLE X

降低贸易障碍。贸易障碍可以理解为 \(d_{ni}-1\),即价格加成的幅度

D_zero_barrier <- matrix(rep(1, N^2), nrow = N)
zero_barrier_mobile <- model_mobile(absolute_tech, D_zero_barrier)
zero_barrier_mobile$trade_volumn / baseline_mobile$trade_volumn
#> [1] 4.929291

可见,若完全消除贸易障碍,贸易规模将是现在的将近 5 倍之多。

D_double_trade <- (Dni^(-1 / theta)) %>% # dni
  `-`(1) %>% # dni-1,可以认为这是贸易障碍(加价程度)
  `*`(0.667) %>% # 贸易障碍变为实际水平的 66.7%
  `+`(1) %>% # 新的 dni
  `^`(-theta)
double_trade_mobile <- model_mobile(absolute_tech, D_double_trade)
double_trade_mobile$trade_volumn / baseline_mobile$trade_volumn
#> [1] 2.00069

贸易障碍变为当前的 66.7%,贸易规模将翻倍

table10 <- cbind(
  country_table$name,
  (100 * log(zero_barrier_mobile$W / baseline_mobile$W)) %>% sprintf("%.1f", .),
  (100 * log(zero_barrier_mobile$p / baseline_mobile$p)) %>% sprintf("%.1f", .),
  (100 * log(zero_barrier_mobile$L / baseline_mobile$L)) %>% sprintf("%.1f", .),
  (100 * log(double_trade_mobile$W / baseline_mobile$W)) %>% sprintf("%.1f", .),
  (100 * log(double_trade_mobile$p / baseline_mobile$p)) %>% sprintf("%.1f", .),
  (100 * log(double_trade_mobile$L / baseline_mobile$L)) %>% sprintf("%.1f", .)
) %>%
  as.data.frame()


table10 %>%
  set_colnames(c(
    "Country", "Welfare", "Mfg.Prices", "Mfg.Labor", "Welfare", "Mfg.Prices", "Mfg.Labor"
  )) %>%
  prettify(
    caption = "TABLE X \\\n The Gains from Trade: Lowering Grographic Barriers"
  ) %>%
  add_header_above(c(
    " " = 1, "Baseline to Zero Gravity" = 3,
    "Baseline to Doubled Trade" = 3
  )) %>%
  add_header_above(c(
    " " = 1, "Percentage Changes in the Case of Mobile Labor" = 6
  ))
TABLE X
The Gains from Trade: Lowering Grographic Barriers
Percentage Changes in the Case of Mobile Labor
Baseline to Zero Gravity
Baseline to Doubled Trade
Country Welfare Mfg.Prices Mfg.Labor Welfare Mfg.Prices Mfg.Labor
Australia 21.3 -157.7 161.3 2.6 -19.6 -15.1
Austria 21.9 -162.1 149.2 3.2 -23.6 43.1
Belgium 18.6 -138.1 72.2 2.8 -20.7 70.7
Canada 18.1 -134.6 -15.1 1.9 -14.4 -1.0
Denmark 20.9 -154.9 159.2 3.2 -23.9 74.9
Finland 21.8 -161.5 173.8 3.1 -23.2 45.8
France 18.8 -139.5 -4.7 2.5 -18.8 13.6
Germany 17.6 -130.5 -41.0 2.2 -16.5 13.6
Greece 24.3 -180.3 262.6 3.8 -27.9 32.7
Italy 18.9 -140.3 2.1 2.4 -17.5 1.5
Japan 16.3 -121.3 -60.4 0.9 -6.9 -23.7
Netherlands 18.7 -138.5 68.9 2.8 -20.6 66.7
New Zealand 22.2 -164.5 308.6 3.1 -22.7 58.3
Norway 21.7 -160.9 188.4 3.3 -24.8 69.0
Portugal 22.4 -166.4 240.9 3.4 -25.4 70.8
Spain 21.2 -157.5 85.4 2.8 -21.0 -5.7
Sweden 20.1 -149.2 121.6 3.0 -21.9 57.7
United Kingdom 18.3 -136.1 10.2 2.5 -18.5 29.8
United States 15.8 -117.3 -103.3 1.3 -9.6 -22.9

若实现零贸易障碍,小国的福利增长幅度更大;而美国、日本、德国等大国的福利增长幅度更小。因此小国对降低贸易障碍往往持更热切的态度。

FIGURE III

贸易障碍为无穷大(autarky)时,制造业就业占比均等于常数 \(\alpha\);贸易障碍为零时,制造业就业占比正比于 \(T_i/w_i^{1+\theta\beta}\),完全由技术和工资决定;贸易障碍在二者之间,制造业就业占比同时受到地理因素和技术/工资的影响。

注:地理因素就是 TABLE VII 中的 29 个影响贸易障碍的虚拟变量,包括区位、语言、贸易协定、目的地国效应等。

地理障碍的下降的两种效应

  1. 会导致可贸易品范围的不断拓宽。只要贸易障碍不再是无穷大,给定 Fréchet 效率分布,各国都有部分产品效率足够高、价格足够低,可以跨越地理障碍开展贸易。而且,随着贸易障碍逐渐下降,能够跨越门槛进行贸易的商品种类越来越多,推动贸易不断增长。
  2. 会影响中间投入品的价格。但各国中间投入品价格下降的速率是不同的,从而导致各国最终品价格变化幅度的不对称和贸易增量的不对称。

制造业就业变化的两种模式

Simulation 的结果显示,各国制造业就业的变化似乎遵循两种模式:小国的制造业先萎缩后扩张;大国的制造业先扩张后萎缩。美国、日本、德国是比较典型的大国,英国、法国、意大利、加拿大处于临界状态,其他国家则是典型的小国。

一种可能的解释如下:

  1. 起初,大国的中间投入品更便宜,使大国拥有对小国的要素成本优势,大国能够打入小国市场的产品相对多,小国能打入大国市场的产品相对少。因此,大国对小国的净出口为正,大国制造业扩张,小国制造业萎缩。
  2. 随着地理障碍的不断下降,越来越多的商品跨越了贸易障碍的门槛。大国对小国的净出口越来越多(虽然贸易增量中大国出口对小国出口的比例在下降),小国制造业日益萎缩。
  3. 当地理障碍下降到一定程度时,上述趋势将被逆转:此时较小的国家也可以低价购买中间产品(小国中间投入品下降的速度比大国快),使小国制造业产品逐渐获得要素成本优势。当越来越多的小国制造业产品反攻进入大国市场,与大国对小国的出口增量持平时,就出现了拐点。越过这个拐点,大国对小国的净出口将开始减少,乃至由正专负,大国制造业转向萎缩(相比 autarky),小国制造业走向扩张。
# 按一定倍率放缩地理障碍 dni-1
n_points <- 51
exponent <- seq(from = -5, to = 5, length.out = n_points)
scale <- 2^exponent # 放缩倍数,从 1/32 到 32
visible_countries <- c("Belgium", "Denmark", "Germany", "Japan")

Figure 3a 显示,随着贸易障碍的下降,日本和德国的中间品价格长期保持稳定,而比利时的中间品价格已经有巨大的下降,相当程度上缓解了成本劣势。

Figure 3b 显示,在当前(对贸易障碍的放缩倍数为 \(1\))基础上进一步降低贸易障碍时,丹麦、比利时等小国的制造业占比会快速回升(虽然尚未回复到 autarky 水平),德国也会继续上升一段时间,日本则处于最高点,即将开始下降。

事情远比想象的复杂

事实上,由本程序 Section 4 中 (20) 式变形求 \(\boldsymbol{L}\) 的表达式知,有三种力量影响制造业就业规模:(1) 贸易障碍 \(\boldsymbol{D}\);(2) 各国经济规模 \(\boldsymbol{Y}\);(3) 各国竞争力(\(\boldsymbol{T}/\boldsymbol{w}^{1+\theta\beta}\))。

其中,(1) 是地理因素,(3) 是技术因素,(2) 是规模因素。这三种因素如何作用,是非常复杂的。虽然不难想象,国家规模更多地影响制造业就业占比波动的幅度,较少影响其波动的形状,但毕竟有影响,该变量波动的形状绝非仅有地理因素或仅有国家规模因素正交地决定,并没有论文所述的那样一种清晰的模式。

由上图可见,英国、法国、意大利、加拿大四个中等国家的制造业就业经历了多轮峰-谷变化,很难给出简单的解释。

TABLE XI

技术进步改善福利的外溢效果

# 美国技术进步
tech_US <- inset(rep(1, N), N, 1.2) * absolute_tech

tech_US_mobile <- model_mobile(tech_US, Dni)
benefits_mobile <- 100 * log(tech_US_mobile$W / baseline_mobile$W)
normalized_US_mobile <- 100 * benefits_mobile / benefits_mobile[N] # 除以美国

tech_US_immobile <- model_immobile(tech_US, Dni)
benefits_immobile <- 100 * log(tech_US_immobile$W / baseline_immobile$W)
normalized_US_immobile <- 100 * benefits_immobile / benefits_immobile[N] # 除以美国


# 德国技术进步
tech_GE <- inset(rep(1, N), 8, 1.2) * absolute_tech

tech_GE_mobile <- model_mobile(tech_GE, Dni)
benefits_mobile <- 100 * log(tech_GE_mobile$W / baseline_mobile$W)
normalized_GE_mobile <- 100 * benefits_mobile / benefits_mobile[8] # 除以德国

tech_GE_immobile <- model_immobile(tech_GE, Dni)
benefits_immobile <- 100 * log(tech_GE_immobile$W / baseline_immobile$W)
normalized_GE_immobile <- 100 * benefits_immobile / benefits_immobile[8] # 除以德国


# TABLE XI
table11 <- cbind(
  country_table$name,
  normalized_US_mobile %>% sprintf("%.1f", .),
  normalized_US_immobile %>% sprintf("%.1f", .),
  normalized_GE_mobile %>% sprintf("%.1f", .),
  normalized_GE_immobile %>% sprintf("%.1f", .)
) %>%
  as.data.frame()


table11 %>%
  set_colnames(c(
    "Country", "Mobile Labor", "Immobile Labor", "Mobile Labor", "Immobile Labor"
  )) %>%
  prettify(
    caption = "TABLE XI \\\n The Benefits of Foreign Technology"
  ) %>%
  add_header_above(c(
    " " = 1, "Higher U.S. State of Technology" = 2,
    "Higher German State of Technology" = 2
  )) %>%
  add_header_above(c(
    " " = 1, "Welfare Consequences of Improved Technology" = 4
  )) %>%
  footnote(
    general = "All numbers are expressed relative to the percentage welfare gain in the country whose technology expands. Based on a counterfactual 20 percent increase in the state of technology for either the United States or Germany.",
    general_title = "\n Note: ",
    footnote_as_chunk = T
  )
TABLE XI
The Benefits of Foreign Technology
Welfare Consequences of Improved Technology
Higher U.S. State of Technology
Higher German State of Technology
Country Mobile Labor Immobile Labor Mobile Labor Immobile Labor
Australia 31.4 14.9 10.8 4.4
Austria 11.8 2.8 60.7 5.3
Belgium 16.1 3.0 47.8 4.8
Canada 82.4 20.5 6.5 1.5
Denmark 15.0 6.3 59.5 7.1
Finland 13.7 4.3 34.8 3.0
France 12.5 4.2 37.1 3.0
Germany 12.3 -11.9 100.0 100.0
Greece 17.4 18.3 37.1 8.1
Italy 11.4 3.9 34.7 3.0
Japan 6.5 -0.8 4.3 -0.2
Netherlands 15.8 6.9 60.5 8.3
New Zealand 37.5 13.5 13.0 3.9
Norway 15.6 11.8 39.6 6.2
Portugal 17.6 8.6 37.3 4.7
Spain 12.6 6.9 27.3 3.3
Sweden 15.6 1.0 39.7 2.3
United Kingdom 18.0 0.4 36.1 1.6
United States 100.0 100.0 7.2 1.5

Note:
All numbers are expressed relative to the percentage welfare gain in the country whose technology expands. Based on a counterfactual 20 percent increase in the state of technology for either the United States or Germany.

TABLE XII

building…

LS0tDQp0aXRsZTogIkVLMjAwMjogU2ltdWxhdGlvbiBcbiINCnN1YnRpdGxlOiAnJw0KYXV0aG9yOiAiSHVtb29uIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0OiBodG1sX2RvY3VtZW50DQpkb2N1bWVudGNsYXNzOiBjdGV4YXJ0DQpjbGFzc29wdGlvbjogaHlwZXJyZWYsDQplZGl0b3Jfb3B0aW9uczogDQogIG1hcmtkb3duOiANCiAgICB3cmFwOiA4MA0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpzb3VyY2UoIi4uL2NvbmZpZy9SbWFya2Rvd25fY29uZmlnLlIiKQ0KDQojIyBnbG9iYWwgb3B0aW9ucyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICB3aWR0aCA9IGNvbmZpZyR3aWR0aCwNCiAgZmlnLndpZHRoID0gY29uZmlnJGZpZy53aWR0aCwNCiAgZmlnLmFzcCA9IGNvbmZpZyRmaWcuYXNwLA0KICBvdXQud2lkdGggPSBjb25maWckb3V0LndpZHRoLA0KICBmaWcuYWxpZ24gPSBjb25maWckZmlnLmFsaWduLA0KICBmaWcucGF0aCA9IGNvbmZpZyRmaWcucGF0aCwNCiAgZmlnLnNob3cgPSBjb25maWckZmlnLnNob3csDQogIHdhcm4gPSBjb25maWckd2FybiwNCiAgd2FybmluZyA9IGNvbmZpZyR3YXJuaW5nLA0KICBtZXNzYWdlID0gY29uZmlnJG1lc3NhZ2UsDQogIGVjaG8gPSBjb25maWckZWNobywNCiAgZXZhbCA9IGNvbmZpZyRldmFsLA0KICB0aWR5ID0gY29uZmlnJHRpZHksDQogIGNvbW1lbnQgPSBjb25maWckY29tbWVudCwNCiAgY29sbGFwc2UgPSBjb25maWckY29sbGFwc2UsDQogIGNhY2hlID0gY29uZmlnJGNhY2hlLA0KICBjYWNoZS5jb21tZW50cyA9IGNvbmZpZyRjYWNoZS5jb21tZW50cywNCiAgYXV0b2RlcCA9IGNvbmZpZyRhdXRvZGVwDQopDQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0V9DQpkb3dubG9hZHRoaXM6OmRvd25sb2FkX2RpcigNCiAgcGF0aCA9ICIuLi9kYXRhIiwNCiAgb3V0cHV0X25hbWUgPSAiZGF0YSIsDQogIGJ1dHRvbl9sYWJlbCA9ICJEb3dubG9hZCBkYXRhIGRpciIsDQogIGJ1dHRvbl90eXBlID0gInN1Y2Nlc3MiLA0KICBzZWxmX2NvbnRhaW5lZCA9IEZBTFNFDQopDQojIGRvd25sb2FkdGhpczo6ZG93bmxvYWRfZmlsZSgNCiMgICBwYXRoID0gIi4uL2NvbmZpZy9SbWFya2Rvd25fY29uZmlnLlIiLA0KIyAgIG91dHB1dF9uYW1lID0gIlJtYXJrZG93bl9jb25maWciLA0KIyAgIGJ1dHRvbl9sYWJlbCA9ICJEb3dubG9hZCBSbWFya2Rvd25fY29uZmlnLlIiLA0KIyAgIGJ1dHRvbl90eXBlID0gInN1Y2Nlc3MiLA0KIyAgIHNlbGZfY29udGFpbmVkID0gRkFMU0UNCiMgKQ0KYGBgDQoNCmBgYHtyfQ0Kc291cmNlKCIuLi9jb25maWcvUm1hcmtkb3duX2NvbmZpZy5SIikgIyDkvp3otZbljIXnmoTlr7zlhaXlkozkuIDns7vliJcgUm1hcmtkb3duIOiuvue9rg0KYGBgDQoNCiMjIERhdGEgUHJvY2Vzc2luZw0KDQojIyMgUmVhZCBEYXRhDQoNCmBgYHtyfQ0KIyDkuIDkupvmoIfph4/luLjmlbANCnNjYWxhciA8LSBqc29ubGl0ZTo6ZnJvbUpTT04oIi4uL2RhdGEvc2NhbGFyLmpzb24iKQ0KDQojIOWbveWutuS7o+eggeihqA0KY291bnRyeV90YWJsZSA8LSBmcmVhZCgiLi4vZGF0YS9jb3VudHJ5X2NvZGUuY3N2IikNCg0KIyDlm73liKvljp/lp4vmlbDmja4NCm5vbWluYWxfdmFyaWFibGVzIDwtIGZyZWFkKCIuLi9kYXRhL25vbWluYWxfdmFyaWFibGUuY3N2IikNCg0KIyBUQUJMRSBJSUkg5Lit5omA5pyJ6Jma5ouf5Y+Y6YeP55qE57O75pWw5Lyw6K6h5YC8DQpsb2FkKCIuLi9kYXRhL2VzdGltYXRpb24tb3V0cHV0LnJkYSIpDQpgYGANCg0KIyMjIERhdGEgVHJhbnNmb3JtYXRpb24NCg0KYGBge3J9DQojIyAxLiBzY2FsYXJzDQpiZXRhIDwtIHNjYWxhciRiZXRhDQpOIDwtIHNjYWxhciRODQp0aGV0YSA8LSBzY2FsYXIkdGhldGFbMl0NCg0KDQojIyAyLiBleGNoYW5nZSByYXRlDQpleGNoYW5nZV9yYXRlIDwtIG5vbWluYWxfdmFyaWFibGVzJGV4Y2hhbmdlX3JhdGUNCg0KDQojIyAzLiB0cmFkZSBkYXRhDQoNCiMgbm9taW5hbCBiaWxhdGVyYWwgdHJhZGUNClhuaV9ub21pbmFsIDwtIG5vbWluYWxfdmFyaWFibGVzWywgLTE6LTZdICU+JQ0KICBhcy5tYXRyaXgoKSAlPiUNCiAgc2V0X2NvbG5hbWVzKE5VTEwpICU+JSAjIOWOu+aOieWIl+WQjQ0KICBgKmAoMTBeNikNCg0KIyByZWFsIGJpbGF0ZXJhbCB0cmFkZQ0KWG5pIDwtIFhuaV9ub21pbmFsIC8gZXhjaGFuZ2VfcmF0ZSAjIOiHquWKqOaJqeWxlemZpOaVsOS4uuefqemYtQ0KWG5uIDwtIGRpYWcoWG5pKQ0KDQojIGV4cGVuZGl0dXJlIG9uIG1hbnVmYWN0dXJpbmcgZ29vZHMNClhuIDwtIFhuaSAlPiUgYXBwbHkoMSwgc3VtKQ0KDQppbXBvcnRzIDwtIFhuIC0gWG5uDQpleHBvcnRzIDwtIFhuaSAlPiUgYXBwbHkoMiwgc3VtKSAtIFhubg0KDQoNCiMjIDQuIG1hbnVmYWN0dXJpbmcgbGFib3IgYW5kIHdhZ2UNCmluZHVzdHJpYWxfbGFib3IgPC0gbm9taW5hbF92YXJpYWJsZXMkaW5kdXN0cmlhbF9sYWJvcg0Kbm9taW5hbF93YWdlIDwtIG5vbWluYWxfdmFyaWFibGVzJG5vbWluYWxfd2FnZSAjIOW3sue7j+S7pee+juWFg+iuoeS7tw0KDQplZHVfeWVhciA8LSBub21pbmFsX3ZhcmlhYmxlcyRlZHVfeWVhcg0KDQplZmZlY3RpdmVfbGFib3IgPC0gaW5kdXN0cmlhbF9sYWJvciAqIGV4cCgwLjA2ICogZWR1X3llYXIpDQplZmZlY3RpdmVfd2FnZSA8LSBub21pbmFsX3dhZ2UgKiBleHAoLTAuMDYgKiBlZHVfeWVhcikNCg0KDQojIyA1LiBpbmNvbWUvZXhwZW5kaXR1cmUNCg0KIyBHRFAgaW4gZG9sbGFycw0KWSA8LSBub21pbmFsX3ZhcmlhYmxlcyRnZHAgKiAxMF42IC8gZXhjaGFuZ2VfcmF0ZQ0KDQojIG1hbnVmYWN0dXJpbmcgbGFib3IgaW5jb21lDQpZX2wgPC0gZWZmZWN0aXZlX3dhZ2UgKiBlZmZlY3RpdmVfbGFib3INCg0KIyBub24tbWFudWZhY3R1cmluZyBpbmNvbWUNCllfbyA8LSBZIC0gWV9sDQoNCg0KIyMgNi4gYmV0YSBhbmQgYWxwaGENCg0KIyBiZXRhID0gbWFudWZhY3R1cmluZyBsYWJvciBpbmNvbWUgLyBtYW51ZmFjdHVyaW5nIG91dHB1dA0KYmV0YV92ZWN0b3IgPC0gWV9sIC8gKFhubiArIGV4cG9ydHMpDQpiZXRhX3ZlY3RvciAjIOS4jeefpeS9nOiAheWmguS9leWKoOadg+W+l+WHuuS6hiBiZXRhID0gMC4yMTIyMSDov5nkuKrmlbDlgLwNCg0KIyBhbHBoYSA9IG1hbnVmYWN0dXJpbmcgZXhwZW5kaXR1cmUgLyB0b3RhbCBleHBlbmRpdHVyZQ0KYWxwaGFfdmVjdG9yIDwtIChZX2wgKyBpbXBvcnRzIC0gZXhwb3J0cykgLyBZDQphbHBoYV92ZWN0b3INCg0KIyDlkITlm73mjIlHRFDliqDmnYPorqHnrpcgYWxwaGENCmFscGhhIDwtIChhbHBoYV92ZWN0b3IgKiBZIC8gc3VtKFkpKSAlPiUgc3VtKCkNCmFscGhhDQoNCg0KIyMgNy4gdGVjaG5vbG9neQ0KIyDooajnpLrmioDmnK/nmoQgVCDmnaXmupDkuo4gKDI3KSDlvI8NCiMg6K6h566X5omA6ZyA55qEIHNvdXJjZSBkdW1taWVzIOeahOS8sOiuoeezu+aVsOingSBUQUJMRSBWSQ0Kc291cmNlX2VzdGltYXRlIDwtIHRhYmxlM19lc3RpbWF0ZVsxMToyOV0NCg0KIyDov5nkuKogdGVjaCDkvb/nlKjnmoTpg73mmK/nu53lr7nmlbDmja4NCmFic29sdXRlX3RlY2ggPC0gbG9nKGVmZmVjdGl2ZV93YWdlKSAlPiUNCiAgYCpgKHRoZXRhKSAlPiUNCiAgYCtgKHNvdXJjZV9lc3RpbWF0ZSkgJT4lDQogIGAqYChiZXRhKSAlPiUNCiAgZXhwKCkNCiMg55So57ud5a+55pWw5o2u77yM5L+d5oyB5YeG56Gu6YeP57qy77yM5L6/5LqOIHdMIOebtOaOpeS4jiBZL1lfbyDnm7jmr5QNCg0KDQojIyA4LiBnZW9ncmFwaHkgYmFycmllcg0KIyBkbmleey10aGV0YX0g55+p6Zi1DQpEbmkgPC0gZXhwKGJhcnJpZXJfbWVhc3VyZSkNCiMgYmFycmllcl9tZWFzdXJlIOadpea6kOS6jiAoMjgpIOW8j++8jOS4uiAtdGhldGEgbG4oZG5pKQ0KIyDnlKggKDMwKSDlvI/orqHnrpcgYmFycmllcl9tZWFzdXJlIOaXtu+8jOaJgOmcgOeahCBiYXJyaWVyIGR1bW1pZXMg55qE5Lyw6K6h57O75pWw6KeBIFRBQkxFIFZJSQ0KDQoNCiMjIDkuIGdhbW1hIGNvbnN0YW50DQpnYW1tYSA8LSBiZXRhXihiZXRhKSAqICgxIC0gYmV0YSleKDEgLSBiZXRhKSAjIOS4jeefpeS4uuS9lSBnYW1tYSDlj6/ku6XnlLEgYmV0YSDmjqjlh7oNCmcgPC0gZ2FtbWFeKC10aGV0YSkNCmBgYA0KDQojIyBTZWN0aW9uIDQNCg0K5rGC6Kej5LiA6Iis5Z2H6KGh5qih5Z6L55qE5aSa5YWD6Z2e57q/5oCn5pa556iL57uE77yM5L2c5Li65Y+N5LqL5a6e5qih5ouf55qEIGJhc2VsaW5lDQoNCiMjIyDmsYLop6PlpJrlhYPpnZ7nur/mgKfmlrnnqIvnu4QNCg0KQ291bnRlcmZhY3R1YWwgU2ltdWxhdGlvbiDnmoTliY3mj5DvvIzmmK/msYLop6PlpJrlhYPpnZ7nur/mgKfmlrnnqIvnu4QNCiRcYm9sZHN5bWJvbHtGfShcYm9sZHN5bWJvbHt4fSk9MCQuDQrov5nmoLfvvIzlr7nkuo7ku7vkvZXmg4XlvaLvvIznoa7lrprkuobmlrnnqIvnu4TnmoTlj4LmlbDlkI7vvIzkvr/lj6/op6Plh7rmiJHku6zluIzmnJvmn6XnnIvnmoTlj5jph4/jgIINCg0K5pyA5bi455So55qE5pWw5YC86Kej5rOV77yM5pivIE5ld3Rvbi1SYXBoc29uIOi/reS7o+azle+8mg0KDQroi6UgJFxib2xkc3ltYm9se0Z9KFxib2xkc3ltYm9se3h9KSQg5YWz5LqOICRcYm9sZHN5bWJvbHt4fSQg55qEIEphY29iaSDnn6npmLUgJCQNClxiZWdpbnthbGlnbmVkfSBcYm9sZHN5bWJvbHtKfShcYm9sZHN5bWJvbHt4fSkgXGVxdWl2IFxmcmFje1xwYXJ0aWFsIFxib2xkc3ltYm9se0Z9fXtccGFydGlhbCBcYm9sZHN5bWJvbHt4fX0gXGVuZHthbGlnbmVkfT1cbGVmdFtcYmVnaW57YXJyYXl9e2NjY2N9DQpcZnJhY3tccGFydGlhbCBmX3sxfX17XHBhcnRpYWwgeF97MX19ICYgXGZyYWN7XHBhcnRpYWwgZl97MX19e1xwYXJ0aWFsIHhfezJ9fSAmIFxjZG90cyAmIFxmcmFje1xwYXJ0aWFsIGZfezF9fXtccGFydGlhbCB4X3tufX0gXFwNClxmcmFje1xwYXJ0aWFsIGZfezJ9fXtccGFydGlhbCB4X3sxfX0gJiBcZnJhY3tccGFydGlhbCBmX3syfX17XHBhcnRpYWwgeF97Mn19ICYgXGNkb3RzICYgXGZyYWN7XHBhcnRpYWwgZl97Mn19e1xwYXJ0aWFsIHhfe259fSBcXA0KXHZkb3RzICYgXHZkb3RzICYgXGRkb3RzICYgXHZkb3RzIFxcDQpcZnJhY3tccGFydGlhbCBmX3tufX17XHBhcnRpYWwgeF97MX19ICYgXGZyYWN7XHBhcnRpYWwgZl97bn19e1xwYXJ0aWFsIHhfezJ9fSAmIFxjZG90cyAmIFxmcmFje1xwYXJ0aWFsIGZfe259fXtccGFydGlhbCB4X3tufX0NClxlbmR7YXJyYXl9XHJpZ2h0XQ0KJCQg5Y+v6YCG77yM5LukICQkDQpcYm9sZHN5bWJvbHt4fV57aysxfT1cYm9sZHN5bWJvbHt4fV5rLVxib2xkc3ltYm9se0p9XnstMX0oXGJvbGRzeW1ib2x7eH1eaylcYm9sZHN5bWJvbHtGfShcYm9sZHN5bWJvbHt4fV5rKQ0KJCQgJFxib2xkc3ltYm9se3h9XmskIOWwsee7hOaIkOS6huS4gOS4quW6j+WIl+OAguiLpei/meS4quW6j+WIl+aUtuaVm++8jOWNsw0KJFxib2xkc3ltYm9se0Z9KFxib2xkc3ltYm9se3h9XmspIFx0byAwJO+8jOS+v+iDveWcqOmAguW9k+eahOeyvuW6puS4i+aJvuWIsOaWueeoi+e7hOeahOi/keS8vOaVsOWAvOino+OAgg0KDQrlhbfkvZPlgZrms5XkuLrvvJoNCg0KMS4gIOehruWumuWIneWni+WQkemHjyAkXGJvbGRzeW1ib2x7eH1eMCTvvIzmnIDlpKfov63ku6PmrKHmlbAgJE4kIOWSjOeyvuW6puimgeaxgg0KICAgICRcdmFyZXBzaWxvbiTvvIznhLblkI7lvIDlkK/lvqrnjq8NCjIuICDku6QNCiAgICAkXGJvbGRzeW1ib2x7ZH1eaz1cYm9sZHN5bWJvbHtKfV57LTF9KFxib2xkc3ltYm9se3h9XmspXGJvbGRzeW1ib2x7Rn0oXGJvbGRzeW1ib2x7eH1eaykk77yIJFxib2xkc3ltYm9se2R9XmskDQogICAg5Y2z57q/5oCn5pa556iL57uEDQogICAgJFxib2xkc3ltYm9se0p9KFxib2xkc3ltYm9se3h9XmspXGJvbGRzeW1ib2x7ZH09XGJvbGRzeW1ib2x7Rn0oXGJvbGRzeW1ib2x7eH1eaykkDQogICAg55qE6Kej77yJDQozLiAg6IulICR8XGJvbGRzeW1ib2x7ZH1ea3w8XHZhcmVwc2lsb24kIOaIliAkaz1OJO+8jOWImeWBnOatouiuoeeul++8m+WQpuWIme+8jOS7pA0KICAgICRcYm9sZHN5bWJvbHt4fV57aysxfT1cYm9sZHN5bWJvbHt4fV5rLVxib2xkc3ltYm9se2R9Xmsk77yM54S25ZCO5Zue5Yiw56ys5LqM5q2l6K6h566XDQogICAgJFxib2xkc3ltYm9se2R9XntrKzF9JO+8jOebtOWIsOeyvuW6pua7oei2s+imgeaxguaIlui/reS7o+asoeaVsOiAl+WwveOAgg0KNC4gIOW9k+eyvuW6pua7oei2s+imgeaxguaXtu+8jOi/reS7o+aJgOW+l+eahCAkXGJvbGRzeW1ib2x7eH0kIOWwseWPr+S7peS9nOS4ug0KICAgICRcYm9sZHN5bWJvbHtGfShcYm9sZHN5bWJvbHt4fSk9MCQg55qE5qC544CCDQoNCiMjIyDkuIDoiKzlnYfooaHmqKHlnovnmoTnn6npmLXlvaLlvI8NCg0K5b2T5L2/55So5pSv5oyB5ZCR6YeP5YyW5pON5L2c55qE6K+t6KiA57yW56iL5pe277yM5pyA5aW95YWI5bCG5qih5Z6L6YO95YaZ5oiQ55+p6Zi15b2i5byP44CC5Zug5Li65pWw5o2u5aSa5Lul5ZCR6YeP5ZKM55+p6Zi155qE5b2i5byP5L+d5a2Y77yM55+p6Zi16L+Q566X5pys6Lqr5bCx5piv55u45b2T5a6M5ZaE55qE5Lyq5Luj56CB77yM5L2/55yf5q2j55qE5Luj56CB57yW5YaZ5Y+Y5b6X6Z2e5bi455yB6ISR44CCDQoNCuS7pCAkUF9uPXBfbl57LVx0aGV0YX0k77yMJGc9XGdhbW1hXnstXHRoZXRhfSTvvIwkRF97bml9PWRfe25pfV57LVx0aGV0YX0gXGluICgwLDFdJO+8jCRrX2k9Z1RfaXdfaV57LVxiZXRhXHRoZXRhfSQNCg0KPiDmupDku6PnoIHkuK3nlKggJFxiZXRhXlxiZXRhKDEtXGJldGEpXnsxLVxiZXRhfSQg5L2c5Li6ICRcZ2FtbWEkIOWAvO+8jOeQhueUseS9leWcqO+8nyg5KSDlvI/kuK3vvIwkXGdhbW1hJCDmmI7mmI7mmK/nlLEgJFx0aGV0YSQg5ZKMICRcc2lnbWEkIOWGs+WumueahOOAgg0KDQojIyMjIOaDheWig+S4gO+8muWKs+WKqOWKm+WPr+i3qOmDqOmXqOa1geWKqA0KDQrliLbpgKDkuJrpg6jpl6jpm4fkvaPlirPliqjlipvlj6/lj5jvvIzlt6XotYTkuI3lj5jvvIjnlLHpnZ7otLjmmJPpg6jpl6jlhrPlrprvvInvvIzlm73msJHmlLblhaXkuI3lj5jjgIINCg0K5bey55+l5bel6LWE44CB5oqA5pyv44CB5Zyw55CG6Zqc56KN44CB5Zu95rCR5pS25YWl5pWw5o2uDQoNCjEuICDnlLEgKDE2KSDlvI/op6Plh7rlnYfooaEqKuS7t+agvCoqDQoyLiAg6YCa6L+HICgxNykg5byP6K6h566XKirotLjmmJPku73pop0qKg0KMy4gIOmAmui/hyAoMjApIOW8j+iuoeeulyoq5Yi26YCg5Lia5Yqz5Yqo5YqbKioNCjQuICDpgJrov4cgKDE5KSDlvI/orqHnrpflr7nliLbpgKDkuJrkuqflk4HnmoTmlK/lh7rvvIzlho3nu5PlkIggKDE3KSDlvI/ljbPlj6/nn6UqKuWPjOi+uei0uOaYk+mHjyoqDQo1LiAg5pyA5ZCO55SxICRXX3tufT1ZX3tufSAvIHBfe259XntcYWxwaGF9JCDorqHnrpcqKuemj+WIqSoq5rC05bmzDQoNCuWwhiAoMTYpIOW8j+WGmeS4uuefqemYteW9ouW8j++8mg0KDQokJA0KXGJlZ2lue2JtYXRyaXh9DQogUF8xIFxcIFx2ZG90cyBcXCBQX04NClxlbmR7Ym1hdHJpeH0gPSBcYm9sZHN5bWJvbHtEfVxsZWZ0KCBcYm9sZHN5bWJvbHtrfSBcY2lyYw0KXGJlZ2lue2JtYXRyaXh9DQogUF8xXnsxLVxiZXRhfSBcXCBcdmRvdHMgXFwgUF9OXnsxLVxiZXRhfQ0KXGVuZHtibWF0cml4fSBccmlnaHQpDQokJCANCg0K5YW25LitDQoNCiRcYm9sZHN5bWJvbHtEfSA9IFxiZWdpbntibWF0cml4fSBEX3sxMX0gJiBEX3sxMn0gJiBcY2RvdHMgJiBEX3sxTn0gXFwgXHZkb3RzICYgXHZkb3RzICYgXHZkb3RzICYgXHZkb3RzIFxcIERfe04xfSAmIERfe04yfSAmIFxjZG90cyAmIERfe05OfSBcZW5ke2JtYXRyaXh9JO+8jCRcYm9sZHN5bWJvbHtrfT1cYmVnaW57Ym1hdHJpeH0ga18xIFxcIFx2ZG90cyBcXCBrX04gXGVuZHtibWF0cml4fT1nIFxjZG90IFxiZWdpbntibWF0cml4fSBUXzEgXFwgXHZkb3RzIFxcIFRfTiBcZW5ke2JtYXRyaXh9IFxjaXJjIFxiZWdpbntibWF0cml4fSB3XzFeey1cYmV0YVx0aGV0YX0gXFwgXHZkb3RzIFxcIHdfTl57LVxiZXRhXHRoZXRhfSBcZW5ke2JtYXRyaXh9JA0KDQokXGNpcmMkIOihqOekuuWTiOi+vumprOenr++8iOefqemYteeahOWvueW6lOWFg+e0oOebuOS5mO+8ie+8jOWImSAoMTYpIOW8j+aJgOS7o+ihqOeahCAkTiQNCuWFg+mdnue6v+aAp+aWueeoi+e7hOWPr+S7peWGmeS4uiAkJA0KXGJvbGRzeW1ib2x7RH1eey0xfVxiZWdpbntibWF0cml4fQ0KIFBfMSBcXCBcdmRvdHMgXFwgUF9ODQpcZW5ke2JtYXRyaXh9IC0gZyBcY2RvdCBcYmVnaW57Ym1hdHJpeH0NCiBUXzEgXFwgXHZkb3RzIFxcIFRfTg0KXGVuZHtibWF0cml4fSAgXGNpcmMgXGJlZ2lue2JtYXRyaXh9DQogd18xXnstXGJldGFcdGhldGF9IFxcIFx2ZG90cyBcXCB3X05eey1cYmV0YVx0aGV0YX0NClxlbmR7Ym1hdHJpeH0gXGNpcmMgXGJlZ2lue2JtYXRyaXh9DQogUF8xXnsxLVxiZXRhfSBcXCBcdmRvdHMgXFwgUF9OXnsxLVxiZXRhfQ0KXGVuZHtibWF0cml4fSA9IFxib2xkc3ltYm9sezB9DQokJCDnlLHkuo7lt6XotYTkuI3lj5jvvIzku4XmnIkgJFBfbiQg6L+ZICROJCDkuKrmnKrnn6XmlbDvvIzlj6/ku6XnlKggTmV3dG9uLVJhcGhzb24g6L+t5Luj5rOV5rGCDQokUF9uJCDnmoTmlbDlgLzop6PjgIINCg0KPiDkvb/nlKggTmV3dG9uLVJhcGhzb24gTWV0aG9kIOaXtu+8jOmcgOimgeWumuS5iei/reS7o+eahOWIneWAvOOAgg0KPg0KPiDnlLHnkIborrrkuI3pmr7mjqjmlq3vvIwkUF9uJCDmmK/lrZjlnKjkuIrkuIvpmZDnmoTvvJoNCj4NCj4gMS4gIEF1dGFya3kg5pe277yM5Lu35qC85rC05bmzICRwX24kIOacgOmrmO+8jCRQX24kIOWPluW+l+acgOWwj+WAvOOAguatpOaXtg0KPiAgICAgJGRfe25pfSBcdG8gXGluZnR5LCBEX3tuaX0gPSAwLCBcZm9yYWxsIG4gXG5lcSBpJO+8jOS7juiAjCAkXGJvbGRzeW1ib2x7RH0kDQo+ICAgICDkuLrljZXkvY3nn6npmLUgJFxib2xkc3ltYm9se0l9X04k77yM5LuO5pa556iL57uE5Lit6Kej5b6XICRQX25ee2xvd30gPSBrX25eezEvXGJldGF9JA0KPiAyLiAg6Zu26LS45piT6Zqc56KN5pe277yM6IO95Lmw5Yiw5Zu95aSW5L6/5a6c55qE5ZWG5ZOB77yM5LiU5Yqg5Lu35Li6ICQwJO+8jOaVheS7t+agvOawtOW5syAkcF9uJA0KPiAgICAg5pyA5L2O77yMJFBfbiQg5Y+W5b6X5pyA5aSn5YC844CC5q2k5pe2ICREX3tuaX0gPSBkX3tuaX0gPSAxLCBcZm9yYWxsIG4gXG5lcSBpJO+8jOS7juiAjA0KPiAgICAgJFxib2xkc3ltYm9se0R9JCDkuLrlhaggJDEkIOefqemYte+8jOS7juaWueeoi+e7hOS4reino+W+lw0KPiAgICAgJFBfbl57aGlnaH0gPSBcbGVmdCh7XHRleHRzdHlsZSBcc3VtX3tuPTF9XntOfSBrX259IFxyaWdodCleezEvXGJldGF9JA0KPg0KPiDmnIDlpb3kvb/nlKggJFBfbl57bG93fSQg5ZKMICRQX25ee2hpZ2h9JA0KPiDkuYvpl7TnmoTmlbDlgLzkvZzkuLrov63ku6PliJ3lgLzvvIzov63ku6Pluo/liJfkuIDoiKzpg73og73pobrliKnmlLbmlZsNCj4NCj4g5q2k5aSW77yM55Sx5LqOICRQX25ee2xvd30kIOWSjCAkUF9uXntoaWdofSQg6KaB5ZyoIE5ld3Rvbi1SYXBoc29uDQo+IOi/reS7o+S5i+Wklueul+WHuuadpe+8jOaJgOS7pSAka19pPWdUX2l3X2leey1cYmV0YVx0aGV0YX0kIOS5n+W/hemhu+aPkOWJjeeul+WlveOAgg0KDQrlsIYgKDE3KSDlvI/nmoTmoIfph4/lvaLlvI8gJFxwaV97bml9PWtfaURfe25pfVBfaV57MS1cYmV0YX0vUF9uJA0K5pS55YaZ5Li655+p6Zi15b2i5byP77yM5Y2z5Y+v6K6h566XICRcYm9sZHN5bWJvbHtcUGl9JO+8mg0KDQokJA0KXGJvbGRzeW1ib2x7XFBpfT1cYmVnaW57Ym1hdHJpeH0NClxwaV97MTF9ICYgXHBpX3sxMn0gJiBcY2RvdHMgJiBccGlfezFOfSBcXCANClx2ZG90cyAmIFx2ZG90cyAmIFx2ZG90cyAmIFx2ZG90cyBcXCANClxwaV97TjF9ICYgXHBpX3tOMn0gJiBcY2RvdHMgJiBccGlfe05OfQ0KXGVuZHtibWF0cml4fT1cYm9sZHN5bWJvbHtEfSBcY2lyYyBcbGVmdCggIFxiZWdpbntibWF0cml4fQ0KIDEvUF8xIFxcIFxjZG90cyBcXCAxL1BfTg0KXGVuZHtibWF0cml4fVxvdGltZXMgXGxlZnQoIGcgXGNkb3QgXGJlZ2lue2JtYXRyaXh9DQogVF8xIFxcIFx2ZG90cyBcXCBUX04NClxlbmR7Ym1hdHJpeH0gIFxjaXJjIFxiZWdpbntibWF0cml4fQ0KIHdfMV57LVxiZXRhXHRoZXRhfSBcXCBcdmRvdHMgXFwgd19OXnstXGJldGFcdGhldGF9DQpcZW5ke2JtYXRyaXh9IFxjaXJjIFxiZWdpbntibWF0cml4fQ0KIFBfMV57MS1cYmV0YX0gXFwgXHZkb3RzIFxcIFBfTl57MS1cYmV0YX0NClxlbmR7Ym1hdHJpeH1ccmlnaHQpJ1xyaWdodCkNCiQkDQoNCiRcb3RpbWVzJCDooajnpLrlhYvnvZflhoXlhYvnp68NCg0K5bCGICgyMCkg5byP5YaZ5Li655+p6Zi15b2i5byP77yaDQoNCiQkDQpcYmVnaW57Ym1hdHJpeH0NCiB3XzFMXzEgXFwgXHZkb3RzIFxcIHdfTkxfTg0KXGVuZHtibWF0cml4fSA9ICgxLVxiZXRhKVxib2xkc3ltYm9se1xQaX0nXGJlZ2lue2JtYXRyaXh9DQogd18xTF8xIFxcIFx2ZG90cyBcXCB3X05MX04NClxlbmR7Ym1hdHJpeH0rXGFscGhhXGJldGFcYm9sZHN5bWJvbHtcUGl9J1xiZWdpbntibWF0cml4fQ0KWV8xIFxcIFx2ZG90cyBcXCBZX04NClxlbmR7Ym1hdHJpeH0NCiQkIA0KDQrkuLrmsYLop6PlkITlm73liLbpgKDkuJrlirPliqjlipvlkJHph48gJFxib2xkc3ltYm9se0x9JO+8jOWwhuWFtuWPmOW9ouS4uiANCg0KJCQNClxiZWdpbntibWF0cml4fQ0KTF8xIFxcIFx2ZG90cyBcXCBMX04NClxlbmR7Ym1hdHJpeH0gPSBcYWxwaGFcYmV0YVxiZWdpbntibWF0cml4fQ0KMS93XzEgXFwgXHZkb3RzIFxcIDEvd19ODQpcZW5ke2JtYXRyaXh9XGNpcmNcbGVmdChcbGVmdChJX04tKDEtXGJldGEpXGJvbGRzeW1ib2x7XFBpfSdccmlnaHQpXnstMX1cYm9sZHN5bWJvbHtcUGl9J1xiZWdpbntibWF0cml4fQ0KWV8xIFxcIFx2ZG90cyBcXCBZX04NClxlbmR7Ym1hdHJpeH1ccmlnaHQpDQokJA0KDQrlsIYgKDE5KSDlvI/lhpnkuLrnn6npmLXlvaLlvI/vvJoNCg0KJCQNClxib2xkc3ltYm9se1hfbn0gXGVxdWl2IFxiZWdpbntibWF0cml4fQ0KWF8xIFxcIFx2ZG90cyBcXCBYX04NClxlbmR7Ym1hdHJpeH0gPVxiZWdpbntibWF0cml4fQ0KIHdfMSBcXCBcdmRvdHMgXFwgd19ODQpcZW5ke2JtYXRyaXh9IFxjaXJjIFxiZWdpbntibWF0cml4fQ0KIExfMSBcXCBcdmRvdHMgXFwgTF9ODQpcZW5ke2JtYXRyaXh9ICooMS1cYmV0YSkvXGJldGErXGFscGhhXGJlZ2lue2JtYXRyaXh9DQpZXzEgXFwgXHZkb3RzIFxcIFlfTg0KXGVuZHtibWF0cml4fQ0KJCQg5LuO6ICM55SxICgxNykg5byP55+l5Y+M6L656LS45piT6YeP55+p6Zi1ICQkDQpcYm9sZHN5bWJvbHtYfV97bml9IFxlcXVpdiBcYmVnaW57Ym1hdHJpeH0NClhfezExfSAmIFhfezEyfSAmIFxjZG90cyAmIFhfezFOfSBcXCANClx2ZG90cyAmIFx2ZG90cyAmIFx2ZG90cyAmIFx2ZG90cyBcXCANClhfe04xfSAmIFhfe04yfSAmIFxjZG90cyAmIFhfe05OfQ0KXGVuZHtibWF0cml4fT1cYm9sZHN5bWJvbHtcUGl9IFxjaXJjIFxsZWZ0KFxiZWdpbntibWF0cml4fQ0KWF8xIFxcIFx2ZG90cyBcXCBYX04NClxlbmR7Ym1hdHJpeH0gXG90aW1lcyBbMSBcY2RvdHMgMV0gXHJpZ2h0KQ0KJCQg6K+l55+p6Zi15omA5pyJ5YWD57Sg55qE5ZKM5YeP5Y676L+55Y2z5Li6IDE5IOWbveS5i+mXtOeahCoq5Y+M6L656LS45piT5oC76YePKiogJCQNClx0ZXh0e3RyYWRlIHZvbHVtbn09IFxzdW1fe249MX1eTlxzdW1fe2k9MX1eTiBYX3tuaX0tdHIoXGJvbGRzeW1ib2x7WH1fe25pfSkNCiQkDQoNCuacgOWQju+8jOemj+WIqeawtOW5s+S4uiAkJA0KXGJlZ2lue2JtYXRyaXh9DQpXXzEgXFwgXHZkb3RzIFxcIFdfTg0KXGVuZHtibWF0cml4fSA9XGJlZ2lue2JtYXRyaXh9DQpZXzEgXFwgXHZkb3RzIFxcIFlfTg0KXGVuZHtibWF0cml4fSBcY2lyYyBcYmVnaW57Ym1hdHJpeH0NCjEvcF8xXntcYWxwaGF9IFxcIFx2ZG90cyBcXCAxL3BfTl57XGFscGhhfQ0KXGVuZHtibWF0cml4fT1cYmVnaW57Ym1hdHJpeH0NCllfMSBcXCBcdmRvdHMgXFwgWV9ODQpcZW5ke2JtYXRyaXh9IFxjaXJjIFxiZWdpbntibWF0cml4fQ0KUF8xXntcYWxwaGEvXHRoZXRhfSBcXCBcdmRvdHMgXFwgUF9OXntcYWxwaGEvXHRoZXRhfQ0KXGVuZHtibWF0cml4fQ0KJCQNCg0K5qih5Z6L6L6T5Ye65LiJ5Liq5ZCR6YePICRcYm9sZHN5bWJvbHtwfT1cYm9sZHN5bWJvbHtQfV57LTEvXHRoZXRhfSQsICRcYm9sZHN5bWJvbHtMfSQsICRcYm9sZHN5bWJvbHtXfSQsIOS4gOS4quefqemYtQ0KJFxib2xkc3ltYm9se1h9X3tuaX0kLCDkuIDkuKrmoIfph48gJFx0ZXh0e3RyYWRlIHZvbHVtbn0kDQoNCj4g5rOo77ya5Li65LqG5L6/5LqO5ZCO57ut5L2/55So77yM6L6T5Ye6ICRwX24kIOiAjOmdniAkUF9uJA0KDQojIyMjIOaDheWig+S6jO+8muWKs+WKqOWKm+S4jeWPr+i3qOmDqOmXqOa1geWKqA0KDQrliLbpgKDkuJrpg6jpl6jlt6XotYTlj6/lj5jvvIzpm4fkvaPlirPliqjlipvkuI3lj5jvvIzlm73msJHmlLblhaXlj6/lj5jvvIzpnZ7liLbpgKDkuJrlirPliqjlipvmlLblhaXkuI3lj5jjgIINCg0K5bey55+l5Yi26YCg5Lia5Yqz5Yqo5Yqb44CB5oqA5pyv44CB5Zyw55CG6Zqc56KN44CB6Z2e5Yi26YCg5Lia5Yqz5Yqo5Yqb5pS25YWl5pWw5o2uDQoNCjEuICDnlLEgKDE2KeOAgSgyMSkg5byP6IGU56uL6K6h566X5Ye65Z2H6KGhKirlt6XotYQqKuOAgeWdh+ihoSoq5Lu35qC8KioNCjIuICDpgJrov4cgKDE3KSDlvI/orqHnrpcqKui0uOaYk+S7veminSoqDQozLiAg6YCa6L+HICgxOSkg5byP6K6h566X5a+55Yi26YCg5Lia5Lqn5ZOB55qE5pSv5Ye677yM5YaN57uT5ZCIICgxNykg5byP5Y2z5Y+v55+lKirlj4zovrnotLjmmJPph48qKg0KNC4gIOacgOWQjueUsSAkV197bn09KHdfbkxfbitZX3tufV5vKSAvIHBfe259XntcYWxwaGF9JCDorqHnrpcqKuemj+WIqSoq5rC05bmzDQoNCuWwhiAoMjEpIOW8j+WGmeS4uuefqemYteW9ouW8j++8mg0KDQokJA0KXGxlZnRbSV9OLSgxLVxiZXRhK1xhbHBoYVxiZXRhKVxib2xkc3ltYm9se1xQaX0nXHJpZ2h0XVxiZWdpbntibWF0cml4fQ0KIHdfMSBcXCBcdmRvdHMgXFwgd19ODQpcZW5ke2JtYXRyaXh9IFxjaXJjIFxiZWdpbntibWF0cml4fQ0KTF8xIFxcIFx2ZG90cyBcXCBMX04NClxlbmR7Ym1hdHJpeH0tXGFscGhhXGJldGEgXGJvbGRzeW1ib2x7XFBpfSdcYmVnaW57Ym1hdHJpeH0NCllfMV5vIFxcIFx2ZG90cyBcXCBZX05ebw0KXGVuZHtibWF0cml4fT1cYm9sZHN5bWJvbHswfQ0KJCQNCg0K5YW25Lit6Z2e5Yi26YCg5Lia5pS25YWlICRZX25ebyTjgIHliLbpgKDkuJrlirPliqjlipsgJExfbiQg5Li65bi46YeP44CC5L2G6L+ZICROJA0K5Liq5pa556iL5peg5rOV6Kej5Ye65bel6LWE5ZCR6YePICR3X24k77yM5Zug5Li6ICRcYm9sZHN5bWJvbHtcUGl9JCDkuK3ov5jlkKvmnIkgJFBfbiQNCg0K6L+ZICROJCDkuKrmlrnnqIvpnIDopoHkuI4gKDE2KSDlvI/ku6PooajnmoQgJE4kIOS4quaWueeoiyAkJA0KXGJvbGRzeW1ib2x7RH1eey0xfVxiZWdpbntibWF0cml4fQ0KIFBfMSBcXCBcdmRvdHMgXFwgUF9ODQpcZW5ke2JtYXRyaXh9IC0gZyBcY2RvdCBcYmVnaW57Ym1hdHJpeH0NCiBUXzEgXFwgXHZkb3RzIFxcIFRfTg0KXGVuZHtibWF0cml4fSAgXGNpcmMgXGJlZ2lue2JtYXRyaXh9DQogd18xXnstXGJldGFcdGhldGF9IFxcIFx2ZG90cyBcXCB3X05eey1cYmV0YVx0aGV0YX0NClxlbmR7Ym1hdHJpeH0gXGNpcmMgXGJlZ2lue2JtYXRyaXh9DQogUF8xXnsxLVxiZXRhfSBcXCBcdmRvdHMgXFwgUF9OXnsxLVxiZXRhfQ0KXGVuZHtibWF0cml4fSA9IFxib2xkc3ltYm9sezB9DQokJCDogZTnq4vvvIzmiY3og73op6Plh7ogJHdfbiQg5ZKMICRQX24kLiDlm6DmraTvvIzov5nmmK/kuIDkuKogJDJOJCDlhYPpnZ7nur/mgKfmlrnnqIvnu4TnmoTmsYLop6Ppl67popjjgIINCg0K6Kej5Ye6ICR3X24k5ZKMICRQX24kIOWQju+8jOWQjOagt+S7jiAoMTcpIOW8j+WPr+iuoeeulyAkJA0KXGJvbGRzeW1ib2x7XFBpfT1cYmVnaW57Ym1hdHJpeH0NClxwaV97MTF9ICYgXHBpX3sxMn0gJiBcY2RvdHMgJiBccGlfezFOfSBcXCANClx2ZG90cyAmIFx2ZG90cyAmIFx2ZG90cyAmIFx2ZG90cyBcXCANClxwaV97TjF9ICYgXHBpX3tOMn0gJiBcY2RvdHMgJiBccGlfe05OfQ0KXGVuZHtibWF0cml4fT1cYm9sZHN5bWJvbHtEfSBcY2lyYyBcbGVmdCggIFxiZWdpbntibWF0cml4fQ0KIDEvUF8xIFxcIFxjZG90cyBcXCAxL1BfTg0KXGVuZHtibWF0cml4fVxvdGltZXMgXGxlZnQoIGcgXGNkb3QgXGJlZ2lue2JtYXRyaXh9DQogVF8xIFxcIFx2ZG90cyBcXCBUX04NClxlbmR7Ym1hdHJpeH0gIFxjaXJjIFxiZWdpbntibWF0cml4fQ0KIHdfMV57LVxiZXRhXHRoZXRhfSBcXCBcdmRvdHMgXFwgd19OXnstXGJldGFcdGhldGF9DQpcZW5ke2JtYXRyaXh9IFxjaXJjIFxiZWdpbntibWF0cml4fQ0KIFBfMV57MS1cYmV0YX0gXFwgXHZkb3RzIFxcIFBfTl57MS1cYmV0YX0NClxlbmR7Ym1hdHJpeH1ccmlnaHQpJ1xyaWdodCkNCiQkIOeUsSAoMTkpIOW8j+WPr+iuoeeulyAkJA0KXGJvbGRzeW1ib2x7WH1fbiBcZXF1aXYgXGJlZ2lue2JtYXRyaXh9DQpYXzEgXFwgXHZkb3RzIFxcIFhfTg0KXGVuZHtibWF0cml4fSA9XGJlZ2lue2JtYXRyaXh9DQogd18xIFxcIFx2ZG90cyBcXCB3X04NClxlbmR7Ym1hdHJpeH0gXGNpcmMgXGJlZ2lue2JtYXRyaXh9DQogTF8xIFxcIFx2ZG90cyBcXCBMX04NClxlbmR7Ym1hdHJpeH0gKlxsZWZ0KFxhbHBoYStcZnJhY3sxLVxiZXRhfXtcYmV0YX1ccmlnaHQpK1xhbHBoYVxiZWdpbntibWF0cml4fQ0KWV8xXm8gXFwgXHZkb3RzIFxcIFlfTl5vDQpcZW5ke2JtYXRyaXh9DQokJA0KDQrlho3ku6PlhaUgKDE3KSDlvI/ljbPlvpflj4zovrnotLjmmJPph4/nn6npmLUgJCQNClxib2xkc3ltYm9se1h9X3tuaX0gXGVxdWl2IFxiZWdpbntibWF0cml4fQ0KWF97MTF9ICYgWF97MTJ9ICYgXGNkb3RzICYgWF97MU59IFxcIA0KXHZkb3RzICYgXHZkb3RzICYgXHZkb3RzICYgXHZkb3RzIFxcIA0KWF97TjF9ICYgWF97TjJ9ICYgXGNkb3RzICYgWF97Tk59DQpcZW5ke2JtYXRyaXh9PVxib2xkc3ltYm9se1xQaX0gXGNpcmMgXGxlZnQoXGJlZ2lue2JtYXRyaXh9DQpYXzEgXFwgXHZkb3RzIFxcIFhfTg0KXGVuZHtibWF0cml4fSBcb3RpbWVzIFsxIFxjZG90cyAxXSBccmlnaHQpDQokJA0KDQror6Xnn6npmLXmiYDmnInlhYPntKDnmoTlkozlh4/ljrvov7nljbPkuLogMTkg5Zu95LmL6Ze055qEKirlj4zovrnotLjmmJPmgLvph48qKiAkJA0KXHRleHR7dHJhZGUgdm9sdW1ufSA9IFxzdW1fe249MX1eTlxzdW1fe2k9MX1eTiBYX3tuaX0tdHIoXGJvbGRzeW1ib2x7WH1fe25pfSkNCiQkDQoNCuacgOWQju+8jOemj+WIqeawtOW5s+S4uiAkJA0KXGJlZ2lue2JtYXRyaXh9DQpXXzEgXFwgXHZkb3RzIFxcIFdfTg0KXGVuZHtibWF0cml4fSA9IFxsZWZ0KCBcYmVnaW57Ym1hdHJpeH0NCiB3XzEgXFwgXHZkb3RzIFxcIHdfTg0KXGVuZHtibWF0cml4fSBcY2lyYyBcYmVnaW57Ym1hdHJpeH0NCiBMXzEgXFwgXHZkb3RzIFxcIExfTg0KXGVuZHtibWF0cml4fSArIFxiZWdpbntibWF0cml4fQ0KWV8xXm8gXFwgXHZkb3RzIFxcIFlfTl5vDQpcZW5ke2JtYXRyaXh9IFxyaWdodCkgXGNpcmMgXGJlZ2lue2JtYXRyaXh9DQpQXzFee1xhbHBoYS9cdGhldGF9IFxcIFx2ZG90cyBcXCBQX05ee1xhbHBoYS9cdGhldGF9DQpcZW5ke2JtYXRyaXh9DQokJA0KDQrmqKHlnovovpPlh7rkuInkuKrlkJHph48gJFxib2xkc3ltYm9se3B9JCwgJFxib2xkc3ltYm9se3d9JCwgJFxib2xkc3ltYm9se1d9JCwg5LiA5Liq55+p6Zi1DQokXGJvbGRzeW1ib2x7WH1fe25pfSQsIOS4gOS4quagh+mHjyAkXHRleHR7dHJhZGUgdm9sdW1ufSQNCg0KIyMjIyDmgLvnu5PvvJrlj4LmlbDkuI7ovpPlh7oNCg0KfCAgICAgICAgICB8IOaDheWig+S4gO+8mm1vYmlsZSBsYWJvciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCDmg4XlooPkuozvvJppbW1vYmlsZSBsYWJvciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8LS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18DQp8IOS4jeWPmOWPguaVsCB8IOWItumAoOS4muW3pei1hCAkXGJvbGRzeW1ib2x7d30k44CB5Zu95rCR5pS25YWlICRcYm9sZHN5bWJvbHtZfSQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IOWItumAoOS4muWKs+WKqOWKmyAkXGJvbGRzeW1ib2x7TH0k44CB6Z2e5Yi26YCg5Lia5Yqz5Yqo5Yqb5pS25YWlICRcYm9sZHN5bWJvbHtZXm99JCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCDlj6/lj5jlj4LmlbAgfCDlnLDnkIbpmpznoo0gJFxib2xkc3ltYm9se0R9JOOAgeaKgOacryAkXGJvbGRzeW1ib2x7VH0k44CB5YWz56iO546HICRcYm9sZHN5bWJvbHt0fSQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IOWcsOeQhumanOeijSAkXGJvbGRzeW1ib2x7RH0k44CB5oqA5pyvICRcYm9sZHN5bWJvbHtUfSTjgIHlhbPnqI7njocgJFxib2xkc3ltYm9se3R9JCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwg5qih5Z6L6L6T5Ye6IHwg5Lu35qC85oyH5pWwICRcYm9sZHN5bWJvbHtwfSTjgIHliLbpgKDkuJrlirPliqjlipsgJFxib2xkc3ltYm9se0x9JOOAgeemj+WIqeawtOW5syAkXGJvbGRzeW1ib2x7V30k44CB5Y+M6L656LS45piT6YeP55+p6Zi1ICRcYm9sZHN5bWJvbHtYfV97bml9JOOAgTE5IOWbvei0uOaYk+aAu+mHjyAkXHRleHR7dHJhZGUgdm9sdW1ufSQgfCDku7fmoLzmjIfmlbAgJFxib2xkc3ltYm9se3B9JOOAgeWItumAoOS4muW3pei1hCAkXGJvbGRzeW1ib2x7d30k44CB56aP5Yip5rC05bmzICRcYm9sZHN5bWJvbHtXfSTjgIHlj4zovrnotLjmmJPph4/nn6npmLUgJFxib2xkc3ltYm9se1h9X3tuaX0k44CBMTkg5Zu96LS45piT5oC76YePICRcdGV4dHt0cmFkZSB2b2x1bW59JCB8DQoNCiMjIyDnvJbnqIvlrp7njrANCg0KIyMjIyDmg4XlooPkuIDvvJrlirPliqjlipvlj6/ku6Xot6jpg6jpl6jmtYHliqgNCg0KYGBge3J9DQoNCm1vZGVsX21vYmlsZSA8LSBmdW5jdGlvbih0ZWNoLCBEbmkpIHsNCiAgIyDkuI3lj5jlj4LmlbANCiAgdyA8LSBlZmZlY3RpdmVfd2FnZQ0KICBZIDwtIFkNCg0KICAjIOWPr+WPmOWPguaVsA0KICBUIDwtIHRlY2gNCiAgRCA8LSBEbmkNCiAgayA8LSBnICogVCAqIHdeKC1iZXRhICogdGhldGEpDQoNCiAgIyDorr7lrpogUCDnmoTov63ku6PliJ3lgLwNCiAgUF9sb3cgPC0ga14oMSAvIGJldGEpDQogIFBfaGlnaCA8LSByZXAoc3VtKGspXigxIC8gYmV0YSksIE4pDQogIFBfc3RhcnQgPC0gKFBfbG93ICsgUF9oaWdoKSAvIDINCg0KICAjICgxNikg5byPDQogIGVxdWF0aW9ucyA8LSBmdW5jdGlvbihQKSB7DQogICAgc29sdmUoRCkgJSolIFAgLSBrICogUF4oMSAtIGJldGEpDQogIH0NCiAgDQogICMg6KejIFANCiAgaWYgKGlkZW50aWNhbChELCBtYXRyaXgocmVwKDEsIE5eMiksIG5yb3cgPSBOKSkpIHsNCiAgICBQIDwtIFBfaGlnaA0KICB9IGVsc2Ugew0KICAgIFAgPC0gcm9vdFNvbHZlOjptdWx0aXJvb3QoDQogICAgICBmID0gZXF1YXRpb25zLCBzdGFydCA9IFBfc3RhcnQsDQogICAgICBydG9sID0gMWUtMTAsIHBvc2l0aXZlID0gVFJVRQ0KICAgICkkcm9vdA0KICB9DQogIA0KICAjIOagueaNriBQIOaOqOWvvOWFtuS7luWPmOmHjw0KICBQaSA8LSBEICoga3JvbmVja2VyKDEgLyBQLCB0KGsgKiBQXigxIC0gYmV0YSkpKQ0KDQogIEwgPC0gYWxwaGEgKiBiZXRhICogKDEgLyB3KSAqIChzb2x2ZShkaWFnKE4pIC0gKDEgLSBiZXRhKSAqIHQoUGkpKSAlKiUgdChQaSkgJSolIFkpICU+JQ0KICAgIGFzLnZlY3RvcigpDQoNCiAgWG4gPC0gdyAqIEwgKiAoMSAtIGJldGEpIC8gYmV0YSArIGFscGhhICogWQ0KDQogIFhuaSA8LSBQaSAqIGtyb25lY2tlcihYbiwgcmVwKDEsIE4pICU+JSB0KCkpDQoNCiAgdHJhZGVfdm9sdW1uIDwtIHN1bShYbmkpIC0gZGlhZyhYbmkpICU+JSBzdW0oKQ0KDQogIFcgPC0gWSAqIFBeKGFscGhhIC8gdGhldGEpDQoNCiAgIyDovpPlh7rmqKHlnovnu5PmnpwNCiAgbGlzdCgNCiAgICBwID0gUF4oLTEgLyB0aGV0YSksIEwgPSBMLCBXID0gVywNCiAgICBYbmkgPSBYbmksIHRyYWRlX3ZvbHVtbiA9IHRyYWRlX3ZvbHVtbg0KICApDQp9DQoNCmJhc2VsaW5lX21vYmlsZSA8LSBtb2RlbF9tb2JpbGUoYWJzb2x1dGVfdGVjaCwgRG5pKQ0KYGBgDQoNCiMjIyMg5oOF5aKD5LqM77ya5Yqz5Yqo5Yqb5LiN6IO96Leo6YOo6Zeo5rWB5YqoDQoNCmBgYHtyfQ0KbW9kZWxfaW1tb2JpbGUgPC0gZnVuY3Rpb24odGVjaCwgRG5pKSB7DQogICMg5LiN5Y+Y5Y+C5pWwDQogIEwgPC0gZWZmZWN0aXZlX2xhYm9yDQogIFlfbyA8LSBZX28NCg0KICAjIOWPr+WPmOWPguaVsA0KICBUIDwtIHRlY2gNCiAgRCA8LSBEbmkNCg0KICAjIHcg5Yid5aeL5YC8DQogIHcgPC0gZWZmZWN0aXZlX3dhZ2UNCg0KICAjIOWBh+iuvnflt7Lnn6XvvIznlLEoMTYp6Kej5Ye6UOWQju+8jOWPr+aOqOWHullfbC9377yM5Y2z5a+55Yqz5Yqo5Yqb55qE5byV6Ie06ZyA5rGCDQogICMg5a6D5LiO5Yqz5Yqo5YqbTOeahOW3ru+8jOS4uui2heminemcgOaxgu+8jOS8muagueaNruS4gOWumuW8ueaAp+aLieWKqHfnmoTlj5jljJYNCiAgIyDnhLblkI7kuI3mlq3ov63ku6Mgd++8jOebtOWIsOi2heminemcgOaxguS4ujANCiAgZm9yIChpIGluIDE6NTAwKSB7DQogICAgIyDov63ku6PliJ3lgLwNCiAgICBrIDwtIGcgKiBUICogd14oLWJldGEgKiB0aGV0YSkNCiAgICBQX2xvdyA8LSBrXigxIC8gYmV0YSkNCiAgICBQX2hpZ2ggPC0gcmVwKHN1bShrKV4oMSAvIGJldGEpLCBOKQ0KICAgIFBfc3RhcnQgPC0gKFBfbG93ICsgUF9oaWdoKSAvIDINCiAgICANCiAgICAjICgxNikg5byPDQogICAgZXF1YXRpb25zIDwtIGZ1bmN0aW9uKFApIHsNCiAgICAgIHNvbHZlKEQpICUqJSBQIC0gayAqIFBeKDEgLSBiZXRhKQ0KICAgIH0NCiAgICANCiAgICAjIOinoyBQDQogICAgaWYgKGlkZW50aWNhbChELCBtYXRyaXgocmVwKDEsIE5eMiksIG5yb3cgPSBOKSkpIHsNCiAgICAgIFAgPC0gUF9oaWdoDQogICAgfSBlbHNlIHsNCiAgICAgIFAgPC0gcm9vdFNvbHZlOjptdWx0aXJvb3QoDQogICAgICAgIGYgPSBlcXVhdGlvbnMsIHN0YXJ0ID0gUF9zdGFydCwNCiAgICAgICAgcnRvbCA9IDFlLTEwLCBwb3NpdGl2ZSA9IFRSVUUNCiAgICAgICkkcm9vdA0KICAgIH0NCg0KICAgIFBpIDwtIEQgKiBrcm9uZWNrZXIoMSAvIFAsIHQoayAqIFBeKDEgLSBiZXRhKSkpDQoNCiAgICAjIOeUqCAoMjEpIOW8j+iuoeeul+WItumAoOS4muaUtuWFpSjkuJbnlYzluILlnLrlr7nlkITlm73liLbpgKDkuJrkuqflk4HnmoTpnIDmsYIpDQogICAgWV9sIDwtICgxIC0gYmV0YSArIGFscGhhICogYmV0YSkgKiB0KFBpKSAlKiUgKHcgKiBMKSArDQogICAgICBhbHBoYSAqIGJldGEgKiB0KFBpKSAlKiUgWV9vDQoNCiAgICAjIOW8leiHtOeahOi2hemineWKs+WKqOmcgOaxgg0KICAgIGV4Y2Vzc19sYWJvcl9yYXRpbyA8LSAoYXMudmVjdG9yKFlfbCkgLyB3IC0gTCkgLyBMDQoNCiAgICB0b2xlcmFuY2UgPC0gc3VtKGV4Y2Vzc19sYWJvcl9yYXRpb14yKSAlPiUgc3FydCgpDQoNCiAgICBpZiAodG9sZXJhbmNlIDwgMWUtOSkgew0KICAgICAgIyDnsr7luqbnrKblkIjopoHmsYLvvIzlj6/ovpPlh7rmqKHlnovnu5PmnpwNCiAgICAgIFhuIDwtIHcgKiBMICogKGFscGhhICsgKDEgLSBiZXRhKSAvIGJldGEpICsgYWxwaGEgKiBZX28NCiAgICAgIFhuaSA8LSBQaSAqIGtyb25lY2tlcihYbiwgcmVwKDEsIE4pICU+JSB0KCkpDQogICAgICB0cmFkZV92b2x1bW4gPC0gc3VtKFhuaSkgLSBkaWFnKFhuaSkgJT4lIHN1bSgpDQogICAgICBXIDwtICh3ICogTCArIFlfbykgKiBQXihhbHBoYSAvIHRoZXRhKQ0KDQogICAgICByZXR1cm4obGlzdCgNCiAgICAgICAgcCA9IFBeKC0xIC8gdGhldGEpLCB3ID0gdywgVyA9IFcsDQogICAgICAgIFhuaSA9IFhuaSwgdHJhZGVfdm9sdW1uID0gdHJhZGVfdm9sdW1uDQogICAgICApKQ0KICAgIH0gZWxzZSB7DQogICAgICAjIOWvueWKs+WKqOeahOi2heminemcgOaxguS8muWvvOiHtOW3pei1hOWPkeeUn+WPmOWMlg0KICAgICAgdyA8LSB3ICogKDEgKyBleGNlc3NfbGFib3JfcmF0aW8gKiAwLjMpICMgMC4zIOS4uuW8ueaApw0KICAgICAgIyBwcmludChzdHJfYygiaXRlcmF0b3I6ICIsIGkpKQ0KICAgIH0NCiAgfQ0KICANCiAgIyA1MDAg5qyh6L+t5Luj6L+Y5rKh57uT5p6c77yM5LiA6Iis5p2l6K+077yM5piv5Zug5Li65bqP5YiX5LiN5pS25pWbDQogIHByaW50KCJub3QgY29udmVyZ2VudCIpDQp9DQoNCmJhc2VsaW5lX2ltbW9iaWxlIDwtIG1vZGVsX2ltbW9iaWxlKGFic29sdXRlX3RlY2gsIERuaSkNCmBgYA0KDQojIyBTZWN0aW9uIDYgQ291bnRlcmZhY3R1YWwgU2ltdWxhdGlvbg0KDQrku47kuIDoiKzlnYfooaHmqKHlnovop6Plh7rnmoTku7vkvZXkuIDkuKrlj5jph48gJHgk77yM6YO95Y+v55SoDQokXGJlZ2lue2FsaWduZWR9IDEwMFxsbiBcZnJhY3t4J317eF8wfVxlbmR7YWxpZ25lZH0kIOiuoeeul+WPjeS6i+WunuaooeaLn+WAvCAkeCckDQrnm7jlr7nkuo4gYmFzZWxpbmUg5YC8ICR4XzAkIOeahOeZvuWIhuavlOWPmOWMlg0KDQojIyMgVEFCTEUgSVgNCg0K5o+Q6auY6LS45piT6Zqc56KN6IezIEF1dGFya3kNCg0KYGBge3J9DQpEX2F1dGFya3kgPC0gZGlhZygxOSkNCg0KYXV0YXJreV9tb2JpbGUgPC0gbW9kZWxfbW9iaWxlKGFic29sdXRlX3RlY2gsIERfYXV0YXJreSkNCmF1dGFya3lfaW1tb2JpbGUgPC0gbW9kZWxfaW1tb2JpbGUoYWJzb2x1dGVfdGVjaCwgRF9hdXRhcmt5KQ0KDQp0YWJsZTkgPC0gY2JpbmQoDQogIGNvdW50cnlfdGFibGUkbmFtZSwNCiAgKDEwMCAqIGxvZyhhdXRhcmt5X21vYmlsZSRXIC8gYmFzZWxpbmVfbW9iaWxlJFcpKSAlPiUgc3ByaW50ZigiJS4xZiIsIC4pLA0KICAoMTAwICogbG9nKGF1dGFya3lfbW9iaWxlJHAgLyBiYXNlbGluZV9tb2JpbGUkcCkpICU+JSBzcHJpbnRmKCIlLjFmIiwgLiksDQogICgxMDAgKiBsb2coYXV0YXJreV9tb2JpbGUkTCAvIGJhc2VsaW5lX21vYmlsZSRMKSkgJT4lIHNwcmludGYoIiUuMWYiLCAuKSwNCiAgKDEwMCAqIGxvZyhhdXRhcmt5X2ltbW9iaWxlJFcgLyBiYXNlbGluZV9pbW1vYmlsZSRXKSkgJT4lIHNwcmludGYoIiUuMWYiLCAuKSwNCiAgKDEwMCAqIGxvZyhhdXRhcmt5X2ltbW9iaWxlJHAgLyBiYXNlbGluZV9pbW1vYmlsZSRwKSkgJT4lIHNwcmludGYoIiUuMWYiLCAuKSwNCiAgKDEwMCAqIGxvZyhhdXRhcmt5X2ltbW9iaWxlJHcgLyBiYXNlbGluZV9pbW1vYmlsZSR3KSkgJT4lIHNwcmludGYoIiUuMWYiLCAuKQ0KKSAlPiUNCiAgYXMuZGF0YS50YWJsZSgpDQoNCg0KdGFibGU5ICU+JQ0KICBzZXRfY29sbmFtZXMoYygNCiAgICAiQ291bnRyeSIsICJXZWxmYXJlIiwgIk1mZy5QcmljZXMiLCAiTWZnLkxhYm9yIiwgIldlbGZhcmUiLCAiTWZnLlByaWNlcyIsICJNZmcuV2FnZXMiDQogICkpICU+JQ0KICBwcmV0dGlmeSgNCiAgICBjYXB0aW9uID0gIlRBQkxFIElYIFxcXG4gVGhlIEdhaW5zIGZyb20gVHJhZGU6IFJhaXNpbmcgR2VvZ3JhcGhpYyBCYXJyaWVycyINCiAgKSAlPiUNCiAgYWRkX2hlYWRlcl9hYm92ZShjKA0KICAgICIgIiA9IDEsICJNb2JpbGUgTGFib3IiID0gMywNCiAgICAiSW1tb2JpbGUgTGFib3IiID0gMw0KICApKSAlPiUNCiAgYWRkX2hlYWRlcl9hYm92ZShjKA0KICAgICIgIiA9IDEsICJQZXJjZW50YWdlIENoYW5nZSBmcm9tIEJhc2VsaW5lIHRvIEF1dGFya3kiID0gNg0KICApKQ0KYGBgDQoNCiMjIyBUQUJMRSBYDQoNCumZjeS9jui0uOaYk+manOeijeOAgui0uOaYk+manOeijeWPr+S7peeQhuino+S4uiAkZF97bml9LTEk77yM5Y2z5Lu35qC85Yqg5oiQ55qE5bmF5bqmDQoNCmBgYHtyfQ0KRF96ZXJvX2JhcnJpZXIgPC0gbWF0cml4KHJlcCgxLCBOXjIpLCBucm93ID0gTikNCnplcm9fYmFycmllcl9tb2JpbGUgPC0gbW9kZWxfbW9iaWxlKGFic29sdXRlX3RlY2gsIERfemVyb19iYXJyaWVyKQ0KemVyb19iYXJyaWVyX21vYmlsZSR0cmFkZV92b2x1bW4gLyBiYXNlbGluZV9tb2JpbGUkdHJhZGVfdm9sdW1uDQpgYGANCg0K5Y+v6KeB77yM6Iul5a6M5YWo5raI6Zmk6LS45piT6Zqc56KN77yM6LS45piT6KeE5qih5bCG5piv546w5Zyo55qE5bCG6L+RIDUg5YCN5LmL5aSa44CCDQoNCmBgYHtyfQ0KRF9kb3VibGVfdHJhZGUgPC0gKERuaV4oLTEgLyB0aGV0YSkpICU+JSAjIGRuaQ0KICBgLWAoMSkgJT4lICMgZG5pLTHvvIzlj6/ku6XorqTkuLrov5nmmK/otLjmmJPpmpznoo3vvIjliqDku7fnqIvluqbvvIkNCiAgYCpgKDAuNjY3KSAlPiUgIyDotLjmmJPpmpznoo3lj5jkuLrlrp7pmYXmsLTlubPnmoQgNjYuNyUNCiAgYCtgKDEpICU+JSAjIOaWsOeahCBkbmkNCiAgYF5gKC10aGV0YSkNCmRvdWJsZV90cmFkZV9tb2JpbGUgPC0gbW9kZWxfbW9iaWxlKGFic29sdXRlX3RlY2gsIERfZG91YmxlX3RyYWRlKQ0KZG91YmxlX3RyYWRlX21vYmlsZSR0cmFkZV92b2x1bW4gLyBiYXNlbGluZV9tb2JpbGUkdHJhZGVfdm9sdW1uDQpgYGANCg0K6LS45piT6Zqc56KN5Y+Y5Li65b2T5YmN55qEIDY2Ljcl77yM6LS45piT6KeE5qih5bCG57+75YCNDQoNCmBgYHtyfQ0KdGFibGUxMCA8LSBjYmluZCgNCiAgY291bnRyeV90YWJsZSRuYW1lLA0KICAoMTAwICogbG9nKHplcm9fYmFycmllcl9tb2JpbGUkVyAvIGJhc2VsaW5lX21vYmlsZSRXKSkgJT4lIHNwcmludGYoIiUuMWYiLCAuKSwNCiAgKDEwMCAqIGxvZyh6ZXJvX2JhcnJpZXJfbW9iaWxlJHAgLyBiYXNlbGluZV9tb2JpbGUkcCkpICU+JSBzcHJpbnRmKCIlLjFmIiwgLiksDQogICgxMDAgKiBsb2coemVyb19iYXJyaWVyX21vYmlsZSRMIC8gYmFzZWxpbmVfbW9iaWxlJEwpKSAlPiUgc3ByaW50ZigiJS4xZiIsIC4pLA0KICAoMTAwICogbG9nKGRvdWJsZV90cmFkZV9tb2JpbGUkVyAvIGJhc2VsaW5lX21vYmlsZSRXKSkgJT4lIHNwcmludGYoIiUuMWYiLCAuKSwNCiAgKDEwMCAqIGxvZyhkb3VibGVfdHJhZGVfbW9iaWxlJHAgLyBiYXNlbGluZV9tb2JpbGUkcCkpICU+JSBzcHJpbnRmKCIlLjFmIiwgLiksDQogICgxMDAgKiBsb2coZG91YmxlX3RyYWRlX21vYmlsZSRMIC8gYmFzZWxpbmVfbW9iaWxlJEwpKSAlPiUgc3ByaW50ZigiJS4xZiIsIC4pDQopICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkNCg0KDQp0YWJsZTEwICU+JQ0KICBzZXRfY29sbmFtZXMoYygNCiAgICAiQ291bnRyeSIsICJXZWxmYXJlIiwgIk1mZy5QcmljZXMiLCAiTWZnLkxhYm9yIiwgIldlbGZhcmUiLCAiTWZnLlByaWNlcyIsICJNZmcuTGFib3IiDQogICkpICU+JQ0KICBwcmV0dGlmeSgNCiAgICBjYXB0aW9uID0gIlRBQkxFIFggXFxcbiBUaGUgR2FpbnMgZnJvbSBUcmFkZTogTG93ZXJpbmcgR3JvZ3JhcGhpYyBCYXJyaWVycyINCiAgKSAlPiUNCiAgYWRkX2hlYWRlcl9hYm92ZShjKA0KICAgICIgIiA9IDEsICJCYXNlbGluZSB0byBaZXJvIEdyYXZpdHkiID0gMywNCiAgICAiQmFzZWxpbmUgdG8gRG91YmxlZCBUcmFkZSIgPSAzDQogICkpICU+JQ0KICBhZGRfaGVhZGVyX2Fib3ZlKGMoDQogICAgIiAiID0gMSwgIlBlcmNlbnRhZ2UgQ2hhbmdlcyBpbiB0aGUgQ2FzZSBvZiBNb2JpbGUgTGFib3IiID0gNg0KICApKQ0KYGBgDQoNCuiLpeWunueOsOmbtui0uOaYk+manOeije+8jOWwj+WbveeahOemj+WIqeWinumVv+W5heW6puabtOWkp++8m+iAjOe+juWbveOAgeaXpeacrOOAgeW+t+WbveetieWkp+WbveeahOemj+WIqeWinumVv+W5heW6puabtOWwj+OAguWboOatpOWwj+WbveWvuemZjeS9jui0uOaYk+manOeijeW+gOW+gOaMgeabtOeDreWIh+eahOaAgeW6puOAgg0KDQojIyMgRklHVVJFIElJSQ0KDQrotLjmmJPpmpznoo3kuLrml6DnqbflpKfvvIhhdXRhcmt577yJ5pe277yM5Yi26YCg5Lia5bCx5Lia5Y2g5q+U5Z2H562J5LqO5bi45pWwICRcYWxwaGEk77yb6LS45piT6Zqc56KN5Li66Zu25pe277yM5Yi26YCg5Lia5bCx5Lia5Y2g5q+U5q2j5q+U5LqOICRUX2kvd19pXnsxK1x0aGV0YVxiZXRhfSTvvIzlrozlhajnlLHmioDmnK/lkozlt6XotYTlhrPlrprvvJvotLjmmJPpmpznoo3lnKjkuozogIXkuYvpl7TvvIzliLbpgKDkuJrlsLHkuJrljaDmr5TlkIzml7blj5fliLDlnLDnkIblm6DntKDlkozmioDmnK8v5bel6LWE55qE5b2x5ZON44CCDQoNCj4g5rOo77ya5Zyw55CG5Zug57Sg5bCx5pivIFRBQkxFIFZJSSDkuK3nmoQgMjkg5Liq5b2x5ZON6LS45piT6Zqc56KN55qE6Jma5ouf5Y+Y6YeP77yM5YyF5ous5Yy65L2N44CB6K+t6KiA44CB6LS45piT5Y2P5a6a44CB55uu55qE5Zyw5Zu95pWI5bqU562J44CCDQoNCiMjIyMg5Zyw55CG6Zqc56KN55qE5LiL6ZmN55qE5Lik56eN5pWI5bqUDQoNCjEuIOS8muWvvOiHtOWPr+i0uOaYk+WTgeiMg+WbtOeahOS4jeaWreaLk+WuveOAguWPquimgei0uOaYk+manOeijeS4jeWGjeaYr+aXoOept+Wkp++8jOe7meWumiBGcsOpY2hldCDmlYjnjofliIbluIPvvIzlkITlm73pg73mnInpg6jliIbkuqflk4HmlYjnjofotrPlpJ/pq5jjgIHku7fmoLzotrPlpJ/kvY7vvIzlj6/ku6Xot6jotorlnLDnkIbpmpznoo3lvIDlsZXotLjmmJPjgILogIzkuJTvvIzpmo/nnYDotLjmmJPpmpznoo3pgJDmuJDkuIvpmY3vvIzog73lpJ/ot6jotorpl6jmp5vov5vooYzotLjmmJPnmoTllYblk4Hnp43nsbvotormnaXotorlpJrvvIzmjqjliqjotLjmmJPkuI3mlq3lop7plb/jgIINCjIuIOS8muW9seWTjeS4remXtOaKleWFpeWTgeeahOS7t+agvOOAguS9huWQhOWbveS4remXtOaKleWFpeWTgeS7t+agvOS4i+mZjeeahOmAn+eOh+aYr+S4jeWQjOeahO+8jOS7juiAjOWvvOiHtOWQhOWbveacgOe7iOWTgeS7t+agvOWPmOWMluW5heW6pueahOS4jeWvueensOWSjOi0uOaYk+WinumHj+eahOS4jeWvueensOOAgg0KDQojIyMjIOWItumAoOS4muWwseS4muWPmOWMlueahOS4pOenjeaooeW8jw0KDQpTaW11bGF0aW9uIOeahOe7k+aenOaYvuekuu+8jOWQhOWbveWItumAoOS4muWwseS4mueahOWPmOWMluS8vOS5jumBteW+quS4pOenjeaooeW8j++8muWwj+WbveeahOWItumAoOS4muWFiOiQjue8qeWQjuaJqeW8oO+8m+Wkp+WbveeahOWItumAoOS4muWFiOaJqeW8oOWQjuiQjue8qeOAgue+juWbveOAgeaXpeacrOOAgeW+t+WbveaYr+avlOi+g+WFuOWei+eahOWkp+Wbve+8jOiLseWbveOAgeazleWbveOAgeaEj+Wkp+WIqeOAgeWKoOaLv+Wkp+WkhOS6juS4tOeVjOeKtuaAge+8jOWFtuS7luWbveWutuWImeaYr+WFuOWei+eahOWwj+WbveOAgg0KDQrkuIDnp43lj6/og73nmoTop6Pph4rlpoLkuIvvvJoNCg0KMS4g6LW35Yid77yM5aSn5Zu955qE5Lit6Ze05oqV5YWl5ZOB5pu05L6/5a6c77yM5L2/5aSn5Zu95oul5pyJ5a+55bCP5Zu955qE6KaB57Sg5oiQ5pys5LyY5Yq/77yM5aSn5Zu96IO95aSf5omT5YWl5bCP5Zu95biC5Zy655qE5Lqn5ZOB55u45a+55aSa77yM5bCP5Zu96IO95omT5YWl5aSn5Zu95biC5Zy655qE5Lqn5ZOB55u45a+55bCR44CC5Zug5q2k77yM5aSn5Zu95a+55bCP5Zu955qE5YeA5Ye65Y+j5Li65q2j77yM5aSn5Zu95Yi26YCg5Lia5omp5byg77yM5bCP5Zu95Yi26YCg5Lia6JCO57yp44CCDQoyLiDpmo/nnYDlnLDnkIbpmpznoo3nmoTkuI3mlq3kuIvpmY3vvIzotormnaXotorlpJrnmoTllYblk4Hot6jotorkuobotLjmmJPpmpznoo3nmoTpl6jmp5vjgILlpKflm73lr7nlsI/lm73nmoTlh4Dlh7rlj6PotormnaXotorlpJrvvIjomb3nhLbotLjmmJPlop7ph4/kuK3lpKflm73lh7rlj6Plr7nlsI/lm73lh7rlj6PnmoTmr5TkvovlnKjkuIvpmY3vvInvvIzlsI/lm73liLbpgKDkuJrml6Xnm4rokI7nvKnjgIINCjMuIOW9k+WcsOeQhumanOeijeS4i+mZjeWIsOS4gOWumueoi+W6puaXtu+8jOS4iui/sOi2i+WKv+Wwhuiiq+mAhui9rO+8muatpOaXtui+g+Wwj+eahOWbveWutuS5n+WPr+S7peS9juS7t+i0reS5sOS4remXtOS6p+WTge+8iCoq5bCP5Zu95Lit6Ze05oqV5YWl5ZOB5LiL6ZmN55qE6YCf5bqm5q+U5aSn5Zu95b+rKirvvInvvIzkvb/lsI/lm73liLbpgKDkuJrkuqflk4HpgJDmuJDojrflvpfopoHntKDmiJDmnKzkvJjlir/jgILlvZPotormnaXotorlpJrnmoTlsI/lm73liLbpgKDkuJrkuqflk4Hlj43mlLvov5vlhaXlpKflm73luILlnLrvvIzkuI7lpKflm73lr7nlsI/lm73nmoTlh7rlj6Plop7ph4/mjIHlubPml7bvvIzlsLHlh7rnjrDkuobmi5DngrnjgILotorov4fov5nkuKrmi5DngrnvvIzlpKflm73lr7nlsI/lm73nmoTlh4Dlh7rlj6PlsIblvIDlp4vlh4/lsJHvvIzkuYPoh7PnlLHmraPkuJPotJ/vvIzlpKflm73liLbpgKDkuJrovazlkJHokI7nvKnvvIjnm7jmr5QgYXV0YXJree+8ie+8jOWwj+WbveWItumAoOS4mui1sOWQkeaJqeW8oOOAgg0KDQpgYGB7cn0NCiMg5oyJ5LiA5a6a5YCN546H5pS+57yp5Zyw55CG6Zqc56KNIGRuaS0xDQpuX3BvaW50cyA8LSA1MQ0KZXhwb25lbnQgPC0gc2VxKGZyb20gPSAtNSwgdG8gPSA1LCBsZW5ndGgub3V0ID0gbl9wb2ludHMpDQpzY2FsZSA8LSAyXmV4cG9uZW50ICMg5pS+57yp5YCN5pWw77yM5LuOIDEvMzIg5YiwIDMyDQp2aXNpYmxlX2NvdW50cmllcyA8LSBjKCJCZWxnaXVtIiwgIkRlbm1hcmsiLCAiR2VybWFueSIsICJKYXBhbiIpDQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0V9DQojIOavlOi+g+WQhOWbveS7t+agvOawtOW5s+eahOWPmOWMlg0KY29tcGFyaXNvbl9tb2JpbGVfcHJpY2UgPC0gc2NhbGUgJT4lDQogIG1hcCggIyDov5Tlm57nmoTliJfooajnmoTmr4/kuKrlhYPntKDpg73mmK/kuIDkuKrnu4/ov4fmlL7nvKnnmoQgRG5pIOefqemYtQ0KICAgIH4gKERuaV4oLTEgLyB0aGV0YSkpICU+JQ0KICAgICAgYC1gKDEpICU+JSAjIGRuaS0xIOaYr+i0uOaYk+manOeijQ0KICAgICAgYCpgKC54KSAlPiUgIyDmlL7nvKnlgI3mlbANCiAgICAgIGArYCgxKSAlPiUNCiAgICAgIGBeYCgtdGhldGEpDQogICkgJT4lDQogIG1hcF9kZmMoDQogICAgfiBtb2RlbF9tb2JpbGUoYWJzb2x1dGVfdGVjaCwgLngpJHAgLyB6ZXJvX2JhcnJpZXJfbW9iaWxlJHANCiAgKSAlPiUNCiAgYXNfdGliYmxlKCkgJT4lDQogIHNldF9jb2xuYW1lcyhleHBvbmVudCAlPiUgYXMuY2hhcmFjdGVyKCkpICU+JQ0KICBtdXRhdGUoY291bnRyeSA9IGNvdW50cnlfdGFibGUkbmFtZSkgJT4lDQogIHBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gMTpuX3BvaW50cywgbmFtZXNfdG8gPSAiZXhwb25lbnQiLA0KICAgIHZhbHVlc190byA9ICJyZWxhdGl2ZV9wcmljZSINCiAgKSAlPiUNCiAgbXV0YXRlKGJhcnJpZXJfc2NhbGUgPSAyXmFzLm51bWVyaWMoZXhwb25lbnQpKSAlPiUNCiAgYXMuZGF0YS50YWJsZSgpDQoNCg0KY291bnRyeV90YWJsZSRuYW1lICU+JQ0KICByZWR1Y2UoDQogICAgLmYgPSBmdW5jdGlvbihwbG90LCBjb3VudHJ5X25hbWUpIHsNCiAgICAgIHBsb3QgJT4lDQogICAgICAgIGFkZF9tYXJrZXJzKA0KICAgICAgICAgIGRhdGEgPSBjb21wYXJpc29uX21vYmlsZV9wcmljZVtjb3VudHJ5ID09IGNvdW50cnlfbmFtZSwgXSwNCiAgICAgICAgICB4ID0gfmJhcnJpZXJfc2NhbGUsIHkgPSB+cmVsYXRpdmVfcHJpY2UsDQogICAgICAgICAgbmFtZSA9IH5jb3VudHJ5X25hbWUsIHNob3dsZWdlbmQgPSBUUlVFLA0KICAgICAgICAgIHZpc2libGUgPSBpZmVsc2UoY291bnRyeV9uYW1lICVpbiUgdmlzaWJsZV9jb3VudHJpZXMsIFQsICJsZWdlbmRvbmx5IiksDQogICAgICAgICAgb3BhY2l0eSA9IDAuOA0KICAgICAgICApDQogICAgfSwNCiAgICAuaW5pdCA9IGNhbnZhcw0KICApICU+JQ0KICBhY2FkZW1pY19sYXlvdXQoKSAlPiUNCiAgbGF5b3V0KA0KICAgIGNvbG9yd2F5ID0gdG9wby5jb2xvcnMoMTkpLA0KICAgIHRpdGxlID0gbGlzdCh0ZXh0ID0gIjxiPkZJR1VSRSAzYSBSZWxhdGl2ZSBQcmljZSB0byBaZXJvIEJhcnJpZXI6IE1vYmlsZSBTaXR1YXRpb248L2I+IiksDQogICAgeGF4aXMgPSBsaXN0KA0KICAgICAgdGl0bGUgPSBsaXN0KHRleHQgPSAic2NhbGluZyBmYWN0b3IgaW4gZ2VvZ3JhcGhpYyBiYXJyaWVyczogZnJvbSBhdXRhcmt5IHRvIHplcm8iKSwNCiAgICAgIHJhbmdlID0gYyhsb2coMzIpIC8gbG9nKDEwKSwgLWxvZygzMikgLyBsb2coMTApKSwNCiAgICAgIHR5cGUgPSAibG9nIiAjIHBsb3RseSDnmoTlr7nmlbDlnZDmoIfovbTku6UxMOS4uuW6lQ0KICAgICksDQogICAgeWF4aXMgPSBsaXN0KA0KICAgICAgdGl0bGUgPSBsaXN0KHRleHQgPSAicmVsYXRpdmUgcHJpY2UiKQ0KICAgICksDQogICAgbGVnZW5kID0gbGlzdCgNCiAgICAgIHhhbmNob3IgPSAibGVmdCIsDQogICAgICBmb250ID0gbGlzdChmYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIiwgc2l6ZSA9IDE0KQ0KICAgICkNCiAgKQ0KYGBgDQoNCkZpZ3VyZSAzYSDmmL7npLrvvIzpmo/nnYDotLjmmJPpmpznoo3nmoTkuIvpmY3vvIzml6XmnKzlkozlvrflm73nmoTkuK3pl7Tlk4Hku7fmoLzplb/mnJ/kv53mjIHnqLPlrprvvIzogIzmr5TliKnml7bnmoTkuK3pl7Tlk4Hku7fmoLzlt7Lnu4/mnInlt6jlpKfnmoTkuIvpmY3vvIznm7jlvZPnqIvluqbkuIrnvJPop6PkuobmiJDmnKzliqPlir/jgIINCg0KYGBge3IsIGVjaG89RkFMU0V9DQojIOavlOi+g+WQhOWbveWItumAoOS4muWKs+WKqOWNoOavlOeahOWPmOWMlg0KY29tcGFyaXNvbl9tb2JpbGVfbGFib3IgPC0gc2NhbGUgJT4lDQogIG1hcCggIyDov5Tlm57nmoTliJfooajnmoTmr4/kuKrlhYPntKDpg73mmK/kuIDkuKrnu4/ov4fmlL7nvKnnmoQgRG5pIOefqemYtQ0KICAgIH4gKERuaV4oLTEgLyB0aGV0YSkpICU+JQ0KICAgICAgYC1gKDEpICU+JSAjIGRuaS0xIOaYr+i0uOaYk+manOeijQ0KICAgICAgYCpgKC54KSAlPiUgIyDmlL7nvKnlgI3mlbANCiAgICAgIGArYCgxKSAlPiUNCiAgICAgIGBeYCgtdGhldGEpDQogICkgJT4lDQogIG1hcF9kZmMoDQogICAgfiBhbHBoYSAqIG1vZGVsX21vYmlsZShhYnNvbHV0ZV90ZWNoLCAueCkkTCAvIGF1dGFya3lfbW9iaWxlJEwNCiAgKSAlPiUNCiAgYXNfdGliYmxlKCkgJT4lDQogIHNldF9jb2xuYW1lcyhleHBvbmVudCAlPiUgYXMuY2hhcmFjdGVyKCkpICU+JQ0KICBtdXRhdGUoY291bnRyeSA9IGNvdW50cnlfdGFibGUkbmFtZSkgJT4lDQogIHBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gMTpuX3BvaW50cywgbmFtZXNfdG8gPSAiZXhwb25lbnQiLA0KICAgIHZhbHVlc190byA9ICJsYWJvcl9mcmFjdGlvbiINCiAgKSAlPiUNCiAgbXV0YXRlKGJhcnJpZXJfc2NhbGUgPSAyXmFzLm51bWVyaWMoZXhwb25lbnQpKSAlPiUNCiAgYXMuZGF0YS50YWJsZSgpDQoNCmNvdW50cnlfdGFibGUkbmFtZSAlPiUNCiAgcmVkdWNlKA0KICAgIC5mID0gZnVuY3Rpb24ocGxvdCwgY291bnRyeV9uYW1lKSB7DQogICAgICBwbG90ICU+JQ0KICAgICAgICBhZGRfbWFya2VycygNCiAgICAgICAgICBkYXRhID0gY29tcGFyaXNvbl9tb2JpbGVfbGFib3JbY291bnRyeSA9PSBjb3VudHJ5X25hbWUsIF0sDQogICAgICAgICAgeCA9IH5iYXJyaWVyX3NjYWxlLCB5ID0gfmxhYm9yX2ZyYWN0aW9uLA0KICAgICAgICAgIG5hbWUgPSB+Y291bnRyeV9uYW1lLCBzaG93bGVnZW5kID0gVFJVRSwNCiAgICAgICAgICB2aXNpYmxlID0gaWZlbHNlKGNvdW50cnlfbmFtZSAlaW4lIHZpc2libGVfY291bnRyaWVzLCBULCAibGVnZW5kb25seSIpLA0KICAgICAgICAgIG9wYWNpdHkgPSAwLjgNCiAgICAgICAgKQ0KICAgIH0sDQogICAgLmluaXQgPSBjYW52YXMNCiAgKSAlPiUNCiAgYWNhZGVtaWNfbGF5b3V0KCkgJT4lDQogIGxheW91dCgNCiAgICBjb2xvcndheSA9IHRvcG8uY29sb3JzKDE5KSwNCiAgICB0aXRsZSA9IGxpc3QodGV4dCA9ICI8Yj5GSUdVUkUgM2IgU3BlY2lhbGl6YXRpb24gQ2hhbmdlIGZyb20gQXV0YXJreTogTW9iaWxlIFNpdHVhdGlvbjwvYj4iKSwNCiAgICB4YXhpcyA9IGxpc3QoDQogICAgICB0aXRsZSA9IGxpc3QodGV4dCA9ICJzY2FsaW5nIGZhY3RvciBpbiBnZW9ncmFwaGljIGJhcnJpZXJzOiBmcm9tIGF1dGFya3kgdG8gemVybyIpLA0KICAgICAgcmFuZ2UgPSBjKGxvZygzMikgLyBsb2coMTApLCAtbG9nKDMyKSAvIGxvZygxMCkpLA0KICAgICAgdHlwZSA9ICJsb2ciICMgcGxvdGx5IOeahOWvueaVsOWdkOagh+i9tOS7pTEw5Li65bqVDQogICAgKSwNCiAgICB5YXhpcyA9IGxpc3QoDQogICAgICB0aXRsZSA9IGxpc3QodGV4dCA9ICJmcmFjdGlvbiBvZiBsYWJvciBlbXBsb3llZCBpbiBtYW51ZmFjdHVyaW5nIikNCiAgICApLA0KICAgIGxlZ2VuZCA9IGxpc3QoDQogICAgICB4YW5jaG9yID0gImxlZnQiLA0KICAgICAgZm9udCA9IGxpc3QoZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIsIHNpemUgPSAxNCkNCiAgICApDQogICkNCmBgYA0KDQpGaWd1cmUgM2Ig5pi+56S677yM5Zyo5b2T5YmN77yI5a+56LS45piT6Zqc56KN55qE5pS+57yp5YCN5pWw5Li6ICQxJO+8ieWfuuehgOS4iui/m+S4gOatpemZjeS9jui0uOaYk+manOeijeaXtu+8jOS4uem6puOAgeavlOWIqeaXtuetieWwj+WbveeahOWItumAoOS4muWNoOavlOS8muW/q+mAn+WbnuWNh++8iOiZveeEtuWwmuacquWbnuWkjeWIsCBhdXRhcmt5IOawtOW5s++8ie+8jOW+t+WbveS5n+S8mue7p+e7reS4iuWNh+S4gOauteaXtumXtO+8jOaXpeacrOWImeWkhOS6juacgOmrmOeCue+8jOWNs+WwhuW8gOWni+S4i+mZjeOAgg0KDQojIyMjIOS6i+aDhei/nOavlOaDs+ixoeeahOWkjeadgg0KDQrkuovlrp7kuIrvvIznlLHmnKznqIvluo8gU2VjdGlvbiA0IOS4rSAoMjApIOW8j+WPmOW9ouaxgiAkXGJvbGRzeW1ib2x7TH0kIOeahOihqOi+vuW8j+efpe+8jOacieS4ieenjeWKm+mHj+W9seWTjeWItumAoOS4muWwseS4muinhOaooe+8migxKSDotLjmmJPpmpznoo0gJFxib2xkc3ltYm9se0R9JO+8mygyKSDlkITlm73nu4/mtY7op4TmqKEgJFxib2xkc3ltYm9se1l9JO+8mygzKSDlkITlm73nq57kuonlipvvvIgkXGJvbGRzeW1ib2x7VH0vXGJvbGRzeW1ib2x7d31eezErXHRoZXRhXGJldGF9JO+8ieOAgg0KDQrlhbbkuK3vvIwoMSkg5piv5Zyw55CG5Zug57Sg77yMKDMpIOaYr+aKgOacr+WboOe0oO+8jCgyKSDmmK/op4TmqKHlm6DntKDjgILov5nkuInnp43lm6DntKDlpoLkvZXkvZznlKjvvIzmmK/pnZ7luLjlpI3mnYLnmoTjgILomb3nhLbkuI3pmr7mg7PosaHvvIzlm73lrrbop4TmqKHmm7TlpJrlnLDlvbHlk43liLbpgKDkuJrlsLHkuJrljaDmr5Tms6LliqjnmoTluYXluqbvvIzovoPlsJHlvbHlk43lhbbms6LliqjnmoTlvaLnirbvvIzkvYbmr5Xnq5/mnInlvbHlk43vvIzor6Xlj5jph4/ms6LliqjnmoTlvaLnirbnu53pnZ7ku4XmnInlnLDnkIblm6DntKDmiJbku4XmnInlm73lrrbop4TmqKHlm6DntKDmraPkuqTlnLDlhrPlrprvvIzlubbmsqHmnInorrrmlofmiYDov7DnmoTpgqPmoLfkuIDnp43muIXmmbDnmoTmqKHlvI/jgIINCg0KYGBge3IsIGVjaG89RkFMU0V9DQp2aXNpYmxlX2NvdW50cmllcyA8LSBjKCJDYW5hZGEiLCAiRnJhbmNlIiwgIkl0YWx5IiwgIlVuaXRlZCBLaW5nZG9tIikNCg0KY291bnRyeV90YWJsZSRuYW1lICU+JQ0KICByZWR1Y2UoDQogICAgLmYgPSBmdW5jdGlvbihwbG90LCBjb3VudHJ5X25hbWUpIHsNCiAgICAgIHBsb3QgJT4lDQogICAgICAgIGFkZF9tYXJrZXJzKA0KICAgICAgICAgIGRhdGEgPSBjb21wYXJpc29uX21vYmlsZV9sYWJvcltjb3VudHJ5ID09IGNvdW50cnlfbmFtZSwgXSwNCiAgICAgICAgICB4ID0gfmJhcnJpZXJfc2NhbGUsIHkgPSB+bGFib3JfZnJhY3Rpb24sDQogICAgICAgICAgbmFtZSA9IH5jb3VudHJ5X25hbWUsIHNob3dsZWdlbmQgPSBUUlVFLA0KICAgICAgICAgIHZpc2libGUgPSBpZmVsc2UoY291bnRyeV9uYW1lICVpbiUgdmlzaWJsZV9jb3VudHJpZXMsIFQsICJsZWdlbmRvbmx5IiksDQogICAgICAgICAgb3BhY2l0eSA9IDAuOA0KICAgICAgICApDQogICAgfSwNCiAgICAuaW5pdCA9IGNhbnZhcw0KICApICU+JQ0KICBhY2FkZW1pY19sYXlvdXQoKSAlPiUNCiAgbGF5b3V0KA0KICAgIGNvbG9yd2F5ID0gdG9wby5jb2xvcnMoMTkpLA0KICAgIHRpdGxlID0gbGlzdCh0ZXh0ID0gIjxiPkZJR1VSRSAzYyBNaWRkbGUgQ291bnRyaWVzPC9iPiIpLA0KICAgIHhheGlzID0gbGlzdCgNCiAgICAgIHRpdGxlID0gbGlzdCh0ZXh0ID0gInNjYWxpbmcgZmFjdG9yIGluIGdlb2dyYXBoaWMgYmFycmllcnM6IGZyb20gYXV0YXJreSB0byB6ZXJvIiksDQogICAgICByYW5nZSA9IGMobG9nKDMyKSAvIGxvZygxMCksIC1sb2coMzIpIC8gbG9nKDEwKSksDQogICAgICB0eXBlID0gImxvZyIgIyBwbG90bHkg55qE5a+55pWw5Z2Q5qCH6L205LulMTDkuLrlupUNCiAgICApLA0KICAgIHlheGlzID0gbGlzdCgNCiAgICAgIHRpdGxlID0gbGlzdCh0ZXh0ID0gImZyYWN0aW9uIG9mIGxhYm9yIGVtcGxveWVkIGluIG1hbnVmYWN0dXJpbmciKQ0KICAgICksDQogICAgbGVnZW5kID0gbGlzdCgNCiAgICAgIHhhbmNob3IgPSAibGVmdCIsDQogICAgICBmb250ID0gbGlzdChmYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIiwgc2l6ZSA9IDE0KQ0KICAgICkNCiAgKQ0KYGBgDQoNCueUseS4iuWbvuWPr+inge+8jOiLseWbveOAgeazleWbveOAgeaEj+Wkp+WIqeOAgeWKoOaLv+Wkp+Wbm+S4quS4reetieWbveWutueahOWItumAoOS4muWwseS4mue7j+WOhuS6huWkmui9ruWzsC3osLflj5jljJbvvIzlvojpmr7nu5nlh7rnroDljZXnmoTop6Pph4rjgIINCg0KIyMjIFRBQkxFIFhJDQoNCuaKgOacr+i/m+atpeaUueWWhOemj+WIqeeahOWklua6ouaViOaenA0KDQpgYGB7cn0NCiMg576O5Zu95oqA5pyv6L+b5q2lDQp0ZWNoX1VTIDwtIGluc2V0KHJlcCgxLCBOKSwgTiwgMS4yKSAqIGFic29sdXRlX3RlY2gNCg0KdGVjaF9VU19tb2JpbGUgPC0gbW9kZWxfbW9iaWxlKHRlY2hfVVMsIERuaSkNCmJlbmVmaXRzX21vYmlsZSA8LSAxMDAgKiBsb2codGVjaF9VU19tb2JpbGUkVyAvIGJhc2VsaW5lX21vYmlsZSRXKQ0Kbm9ybWFsaXplZF9VU19tb2JpbGUgPC0gMTAwICogYmVuZWZpdHNfbW9iaWxlIC8gYmVuZWZpdHNfbW9iaWxlW05dICMg6Zmk5Lul576O5Zu9DQoNCnRlY2hfVVNfaW1tb2JpbGUgPC0gbW9kZWxfaW1tb2JpbGUodGVjaF9VUywgRG5pKQ0KYmVuZWZpdHNfaW1tb2JpbGUgPC0gMTAwICogbG9nKHRlY2hfVVNfaW1tb2JpbGUkVyAvIGJhc2VsaW5lX2ltbW9iaWxlJFcpDQpub3JtYWxpemVkX1VTX2ltbW9iaWxlIDwtIDEwMCAqIGJlbmVmaXRzX2ltbW9iaWxlIC8gYmVuZWZpdHNfaW1tb2JpbGVbTl0gIyDpmaTku6Xnvo7lm70NCg0KDQojIOW+t+WbveaKgOacr+i/m+atpQ0KdGVjaF9HRSA8LSBpbnNldChyZXAoMSwgTiksIDgsIDEuMikgKiBhYnNvbHV0ZV90ZWNoDQoNCnRlY2hfR0VfbW9iaWxlIDwtIG1vZGVsX21vYmlsZSh0ZWNoX0dFLCBEbmkpDQpiZW5lZml0c19tb2JpbGUgPC0gMTAwICogbG9nKHRlY2hfR0VfbW9iaWxlJFcgLyBiYXNlbGluZV9tb2JpbGUkVykNCm5vcm1hbGl6ZWRfR0VfbW9iaWxlIDwtIDEwMCAqIGJlbmVmaXRzX21vYmlsZSAvIGJlbmVmaXRzX21vYmlsZVs4XSAjIOmZpOS7peW+t+WbvQ0KDQp0ZWNoX0dFX2ltbW9iaWxlIDwtIG1vZGVsX2ltbW9iaWxlKHRlY2hfR0UsIERuaSkNCmJlbmVmaXRzX2ltbW9iaWxlIDwtIDEwMCAqIGxvZyh0ZWNoX0dFX2ltbW9iaWxlJFcgLyBiYXNlbGluZV9pbW1vYmlsZSRXKQ0Kbm9ybWFsaXplZF9HRV9pbW1vYmlsZSA8LSAxMDAgKiBiZW5lZml0c19pbW1vYmlsZSAvIGJlbmVmaXRzX2ltbW9iaWxlWzhdICMg6Zmk5Lul5b635Zu9DQoNCg0KIyBUQUJMRSBYSQ0KdGFibGUxMSA8LSBjYmluZCgNCiAgY291bnRyeV90YWJsZSRuYW1lLA0KICBub3JtYWxpemVkX1VTX21vYmlsZSAlPiUgc3ByaW50ZigiJS4xZiIsIC4pLA0KICBub3JtYWxpemVkX1VTX2ltbW9iaWxlICU+JSBzcHJpbnRmKCIlLjFmIiwgLiksDQogIG5vcm1hbGl6ZWRfR0VfbW9iaWxlICU+JSBzcHJpbnRmKCIlLjFmIiwgLiksDQogIG5vcm1hbGl6ZWRfR0VfaW1tb2JpbGUgJT4lIHNwcmludGYoIiUuMWYiLCAuKQ0KKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpDQoNCg0KdGFibGUxMSAlPiUNCiAgc2V0X2NvbG5hbWVzKGMoDQogICAgIkNvdW50cnkiLCAiTW9iaWxlIExhYm9yIiwgIkltbW9iaWxlIExhYm9yIiwgIk1vYmlsZSBMYWJvciIsICJJbW1vYmlsZSBMYWJvciINCiAgKSkgJT4lDQogIHByZXR0aWZ5KA0KICAgIGNhcHRpb24gPSAiVEFCTEUgWEkgXFxcbiBUaGUgQmVuZWZpdHMgb2YgRm9yZWlnbiBUZWNobm9sb2d5Ig0KICApICU+JQ0KICBhZGRfaGVhZGVyX2Fib3ZlKGMoDQogICAgIiAiID0gMSwgIkhpZ2hlciBVLlMuIFN0YXRlIG9mIFRlY2hub2xvZ3kiID0gMiwNCiAgICAiSGlnaGVyIEdlcm1hbiBTdGF0ZSBvZiBUZWNobm9sb2d5IiA9IDINCiAgKSkgJT4lDQogIGFkZF9oZWFkZXJfYWJvdmUoYygNCiAgICAiICIgPSAxLCAiV2VsZmFyZSBDb25zZXF1ZW5jZXMgb2YgSW1wcm92ZWQgVGVjaG5vbG9neSIgPSA0DQogICkpICU+JQ0KICBmb290bm90ZSgNCiAgICBnZW5lcmFsID0gIkFsbCBudW1iZXJzIGFyZSBleHByZXNzZWQgcmVsYXRpdmUgdG8gdGhlIHBlcmNlbnRhZ2Ugd2VsZmFyZSBnYWluIGluIHRoZSBjb3VudHJ5IHdob3NlIHRlY2hub2xvZ3kgZXhwYW5kcy4gQmFzZWQgb24gYSBjb3VudGVyZmFjdHVhbCAyMCBwZXJjZW50IGluY3JlYXNlIGluIHRoZSBzdGF0ZSBvZiB0ZWNobm9sb2d5IGZvciBlaXRoZXIgdGhlIFVuaXRlZCBTdGF0ZXMgb3IgR2VybWFueS4iLA0KICAgIGdlbmVyYWxfdGl0bGUgPSAiXG4gTm90ZTogIiwNCiAgICBmb290bm90ZV9hc19jaHVuayA9IFQNCiAgKQ0KYGBgDQoNCiMjIyBUQUJMRSBYSUkNCg0KYnVpbGRpbmcuLi4NCg==