Des séries temporelles au panel
Les modèles de régression de panel sont un des outils les plus
populaires dans la recherche en économie. Ces modèles consistent à
utiliser des données disponibles pour plusieurs pays (la
cross-section), et sur plusieurs périodes (la
time-serie).
Le modèle de panel linéaire classique utilisé en économétrie peut
être décrit par : \[
Y_{i,t} = \beta X_{i,t} + \varepsilon_{i,t}
\] Où \(i = 1, \cdots,n\)
représente les individus (des pays par exemple) et \(t=1, \cdots, T\) représente l’indice
temporel (des années par exemple). Ici, \(Y_{i,t}\) représente la variable dépendante
(ou variable endogène, ou variable expliquée) - par exemple le taux de
chômage - de l’individu \(i\) à la
période \(t\) ; \(X_{i,t}\) représente la variable
indépendante (ou variable exogène, ou variable explicative) - par
exemple le taux d’inflation.
La base de données est donc constituée de \(n \times T\) observations dans ce cas,
contrairement aux modèles de séries temporelles qui ne possèdent que
\(T\) observations.
Pour bien se représenter l’apport des modèles de panel par rapport
aux modèles de séries temporelles, on peut visualiser la différence.
require(readxl)
data_panel <- read_excel("C:/users/fkraus/Desktop/data_schularick.xlsx")%>%
select(year, country, unemp, cpi)
data_ST <- data_panel %>% filter(country=="France")
head(data_panel)
head(data_ST)
D’un côté, la base de données data_ST est une base de
données en série temporelle à fréquence annuelle, c’est-à-dire qui n’est
constituée que d’un individu (la France) entre 1870 et 2020. De l’autre,
la base data_panel contient les données annuelles pour 18
pays entre 1870 et 2020.
Il peut exister deux types de base de données de panel : les panel
balancés (balanced panel) et les non-balancés (unbalanced
panel). Les panel balancés décrivent des bases de données de panel
pour lesquels tous les individus ont exactement le même nombre
d’observations, tandis que les non-balancés sont des bases où le nombre
d’observation peut différer entre chaque individus. On peut vérifier
pour notre cas :
table(data_panel$country)
Australia Belgium Canada Denmark Finland France Germany Ireland Italy Japan Netherlands
151 151 151 151 151 151 151 151 151 151 151
Norway Portugal Spain Sweden Switzerland UK USA
151 151 151 151 151 151 151
Ici, on voit qu’on a moins d’observations pour la Belgique, la
Finlande, l’Allemagne, l’Irlande, l’Italie, le Japon et le Portugal, on
a donc un panel non-balancé. Cela ne pose en revanche pas de problème
majeur dans la plupart des cas.
Si on s’intéresse à la relation entre le taux de chômage et le taux
d’inflation - la courbe de Phillips - on peut analyser la relation pour
la France avec l’équation suivante : \[
Y_{FR, t}= \alpha_0 + \beta X_{FR,t} + \varepsilon_{FR,t}
\] L’ordonnée à l’origine est donnée par \(\alpha_0\) et la pente de la courbe de
régression est donnée par \(\beta\).
Cette équation revient à visualiser le nuage de points entre le taux
d’inflation (\(X_{FR,t}\)) et de
chômage (\(Y_{FR,t}\)) de la France
:
data_ST <- data_ST %>%
mutate(inflation = c(NA, diff(log(cpi))*100))
data_ST %>% ggplot(aes(x=inflation, y=unemp))+
geom_point(size=1)+
labs(title="Nuage de point entre inflation et chômage, France (1871-2020)", y="Chômage (%)", x="Inflation (%)")+
#geom_smooth(method="lm", formula = y ~ x)+
theme_bw()

Ici, on peut voir que dans le cas de la France, on a 109
observations qui nous permettent de déterminer l’allure de la
relation décrite par la courbe de Phillips qui semble être, a priori,
confirmée par les données.
Dans le cas des données de panel, on peut appliquer le même modèle
pour tous les individus de manière séparée : \[
Y_{i, t}= \alpha_{i,0} + \beta_i X_{i,t} + \varepsilon_{i,t}
\] Encore une fois, l’ordonnée à l’origine globale (pour tous les
pays) est donnée par \(\alpha_0\) et la
pente de la courbe de régression (pour tous les pays) est donnée par
\(\beta\). Cela revient à analyser le
nuage de points entre l’inflation (\(X_{i,t}\)) et le chômage (\(Y_{i,t}\)) de tous les pays dans notre base
de données :
data_panel <- data_panel %>%
group_by(country)%>%
mutate(inflation = c(NA, diff(log(cpi))*100))%>%
filter(!inflation >= 50) # pour retirer les valeurs aberrantes
data_panel %>% ggplot(aes(x=inflation, y=unemp))+
geom_point(color="grey60")+
labs(title="Nuage de point entre inflation et chômage", y="Chômage (%)", x="Inflation (%)")+
geom_smooth(se=FALSE, method="lm", color="black")+
theme_minimal()+
theme(legend.position="bottom")+
facet_wrap(~country) # pour avoir un graphique par country

Les données de panel semblent bien confirmer les observations que
l’on avait obtenu pour la France. Cependant, on voit bien que la pente
de la relation semble être plus importante dans certains pays (USA,
Espagne ou Suisse par exemple) que dans d’autres (Portugal, Irlande,
Italie), voire même que cette pente est positive pour le Danemark.
Cette différence peut provenir - dans la majorité des cas - du fait
qu’il y a une hétérogénéité inobservée importante entre les différents
individus (les pays) dans la base de données.
Cette hétérogénéité peut être notamment captée de différentes façons,
c’est ce qui donne lieu aux modèles Between,
Pooled, Within et
Random.
Résumé des modèles
Between \[
\bar Y_i = \alpha_0 + \beta \bar X_i + \varepsilon_{i}
\] Effets aléatoires \[
Y_{i,t} = \alpha + \alpha_i + \beta X_{i,t} + \varepsilon_{i} \quad
\alpha_i \sim iid(0,\sigma^2_\alpha)
\] Suppose $ Cov(X_{i,t}, i) =0 $ Effets
fixes \[
Y_{i,t} = \alpha_i + \beta X_{i,t} + \varepsilon_{i}
\] Autorise $ Cov(X{i,t}, _i) $
Pooled \[
Y_{i,t} = \alpha + \beta X_{i,t} + \varepsilon_{i,t}
\]
Les modèles Between
Les modèles Between vont analyser les différences
structurelles entre les individus (between
individuals), en analysant les moyennes par individus.
C’est souvent le modèle le plus simple, utile pour analyser le
vocabulaire économétrique, et qui sert de base.
En analysant les différences par individus, on va réellement examiner
l’hétérogénéité, en négligeant cependant la dynamique temporelle par
individus.
\[
\bar Y_i = \alpha_0 + \beta \bar X_i + \varepsilon_{i}
\] Où \[
\bar Y_i = \frac{1}{T_i}\sum_t Y_{it}, \quad
\bar X_i = \frac{1}{T_i}\sum_t X_{it}
\] Autrement dit, on ne garde, pour chaque individu \(i\), que la moyenne des observations de
\(Y\) et \(X\), ce qui revient à faire une régression
en coupe transversale.
Visuellement, l’estimation du modèle Between ressemble à :
data_between <- data_panel %>%
group_by(country) %>%
summarise(
unemp_mean = mean(unemp, na.rm = TRUE),
inflation_mean = mean(inflation, na.rm = TRUE)
)
ggplot(data_between,
aes(x = inflation_mean, y = unemp_mean, label = country)) +
geom_point() +
geom_smooth(method = "lm", se = FALSE) +
geom_text(nudge_y = 0.3, size = 3) +
labs(title = "Relation between : moyennes par pays",
x = "Inflation moyenne (%)",
y = "Chômage moyen (%)") +
theme_minimal()

Et formellement, on estime la régression suivante :
reg_between <- feols(unemp_mean ~ inflation_mean, data = data_between)
etable(reg_between_plm)
reg_between_plm
Dependent Var.: unemp_mean
Constant 2.604. (1.273)
inflation_mean 0.9562* (0.3770)
_______________ ________________
S.E. type IID
Observations 18
R2 0.28678
Adj. R2 0.24221
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Le coefficient associé à la ligne Constant représente
l’ordonnée à l’origine \(\alpha_0\), et
le coefficient associé à inflation_mean représente la pente
de régression \(\beta\). Dans le modèle
Between, on observe que les pays qui sont structurellement plus
inflationniste tendent à avoir davantage de chômage.
Ce type de modèle est en revanche davantage descriptif que causal, et
vise en général plutôt à étudier des caractéristiques invariables dans
le temps.
Les modèles Pooled
Les modèles Pooled vont considérer toutes les observations du panel
comme si elles venaient d’un seul individu. On suppose donc
implicitement que pour tous les individus, \(Y\) et \(X\) ont la même relation et qu’il n’y a pas
d’hétérogénéité structurelle propre à chaque individu.
En effectuant des modèles de régression spécifiques à chaque
individus, de sorte à avoir une ordonnée à l’origine et une pente de
régression différente pour chaque individu \(i\) : \[
Y_{i,t} = \alpha + \beta X_{i,t} + \varepsilon_{i,t}
\]
On peut le visualiser en faisant un graphique représentant la
relation inflation-chômage pour chaque individu :
ggplot(data_panel, aes(x = inflation, y = unemp)) +
geom_point(alpha = 0.2) +
geom_smooth(method = "lm", se = FALSE) +
labs(x = "Inflation",
y = "Chômage",
title = "Pooled model") +
theme_minimal()

etable(reg_between, reg_pooled,
headers =c("Between", "Pooled"),
dict= c("unemp_mean"="unemp",
"inflation_mean"="inflation")
)
reg_between reg_pooled
Between Pooled
Dependent Var.: unemp unemp
Constant 2.604. (1.273) 5.932*** (0.1063)
inflation 0.9562* (0.3770) -0.1277*** (0.0159)
_______________ ________________ ___________________
S.E. type IID IID
Observations 18 1,942
R2 0.28678 0.03233
Adj. R2 0.24221 0.03183
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Le modèle Pooled OLS mélange l’analyse entre pays et
dans les pays. On voit qu’avec l’apport de la dimension
temporelle par rapport au modèle Between, le coefficient qui mesure
l’impact de l’inflation sur le taux de chômage est désormais négatif, et
significatif à 1%.
Cependant, si l’hétérogénéité entre les pays est trop forte (si les
institutions sont très différentes par exemple), l’estimation avec
Pooled OLS devient biaisée, et il faut plutôt utiliser des modèles à
effets fixes qui prend réellement en compte la structure de panel des
données.
Les modèles Within
Les modèles within, ou modèles à effets fixes, sont plus utiles pour
étudier des relations causales entre des variables dynamiques. Plutôt
que de s’intéresser aux différences entre pays - ce que fait le modèle
Between - le modèle Within va examiner la relation entre \(Y\) et \(X\) à l’intérieur de chaque pays
(within each country).
Pour cela, on va appliquer à chaque individu la transformation within
aux variables, en mesurant l’écart entre chaque observation avec la
moyenne, et en ajoutant une variable \(\alpha_i\) - appelée effet fixe individuel
- qui prend la forme d’une dummy spécifique à chaque individu, qui capte
les différences d’ordonnées à l’origine entre chaque individus.
\[
Y_{i,t} = \alpha_i + \beta X_{i,t} + \varepsilon_{i,t}
\]
Ici, \(\alpha_i\) représente
l’hétérogénéité inobservée propre à l’individu \(i\) (culture, institutions, structure
économique, …), tandis que \(u_{i,t}\)
représente les chocs idiosyncratiques comme en séries temporelles. \(\alpha_i\) est constant dans le
temps pour un individu, mais il est différent
entre les individus. Egalement, il peut être corrélé
avec les variables explicatives \(X_{i,t}\).
On calcule la moyenne temporelle pour chaque pays :
\[
\bar Y_i = \frac{1}{T}\sum_t Y_{it}, \quad
\bar X_i = \frac{1}{T}\sum_t X_{it}, \quad
\bar \varepsilon_i = \frac{1}{T}\sum_t \varepsilon_{it}
\]
En réécrivant le modèle avec les moyennes, on a :
\[
\bar Y_i = \alpha_i + \beta \bar X_i + \bar \varepsilon_i
\]
On soustrait cette équation à l’équation originale :
\[\begin{align}
Y_{it} - \bar Y_i &= (\alpha_i + \beta X_{it} + \varepsilon_{it}) -
(\alpha_i + \beta \bar X_i + \bar \varepsilon_i) \\
&= \beta (X_{it} - \bar X_i) + (\varepsilon_{it} - \bar
\varepsilon_i).
\end{align}\]
On obtient alors :
\[
\tilde Y_{it} = \beta \tilde X_{it} + \tilde \varepsilon_{it}
\] où les tildes (\(\tilde
y_{it}\), \(\tilde x_{it}\),
\(\tilde \varepsilon_{it}\) ) désignent
les variables ‘centrées’ par individu. On peut alors effectivement
estimer \(\beta\) par une régression
OLS classique sur les variables transformées : c’est
l’estimateur within.
En étudiant uniquement les différences à la moyenne, la
transformation within élimine l’hétérogénéité structurelle entre les
individus, et les observations deviennent donc les variations dans les
individus au cours du temps.
Visuellement, la méthode within permet de mesure l’impact global
d’une variation de \(X\) sur la
variable \(Y\) pour plusieurs
individus, dans le temps.
within_df <- data_panel %>%
group_by(country) %>%
mutate(
unemp_within = unemp - mean(unemp, na.rm = TRUE),
infl_within = inflation - mean(inflation, na.rm = TRUE)
)
ggplot(within_df, aes(x = infl_within, y = unemp_within)) +
geom_point(alpha = 0.2) +
geom_smooth(method = "lm", se = FALSE) +
labs(x = "Inflation centrée par pays (within)",
y = "Chômage centré par pays (within)",
title = "Relation within") +
theme_minimal()
On peut alors estimer le modèle suivant : \[
Y_{it} = \alpha_i + \beta X_{it} + \varepsilon_{it}
\] En prenant en compte l’hétérogénéité entre pays avec \(\alpha_i\), le coefficient \(\beta\) représente désormais l’effet de
\(X_{i,t}\) sur \(Y_{i,t}\) au sein d’un même pays.
On peut estimer l’impact du taux d’inflation sur le taux de chômage
avec un modèle within, en ajoutant des effets fixes (on compare
également avec le modèle Pooled) :
etable(reg_between, reg_pooled, reg_fe_i,
headers =c("Between", "Pooled", "Within"),
dict= c("unemp_mean"="unemp",
"inflation_mean"="inflation"), vcov="iid")
reg_between reg_pooled reg_fe_i
Between Pooled Within
Dependent Var.: unemp unemp unemp
Constant 2.604. (1.273) 5.932*** (0.1063)
inflation 0.9562* (0.3770) -0.1277*** (0.0159) -0.1712*** (0.0146)
Fixed-Effects: ---------------- ------------------- -------------------
country No No Yes
_______________ ________________ ___________________ ___________________
S.E. type IID IID IID
Observations 18 1,942 1,942
R2 0.28678 0.03233 0.22439
Within R2 -- -- 0.06688
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Dans le modèle à effets fixes individuels (Within), le
coefficient \(\beta\) mesure comment le
chômage varie quand l’inflation augmente dans un même pays au cours du
temps, après avoir retiré les différences structurelles entre pays (les
effets fixes individuels).
On voit également que dans le modèle à effets fixes, il n’y a pas de
coefficient associé à Constant, car il y a une constante
pour chaque individu qui est captée par les effets fixes individuels. On
peut cependant récupérer les effets fixes pays, et faire un graphique
pour voir l’hétérogénéité :
fe_country <- fixef(reg_fe_i)
fe_df <- data.frame(
country = names(fe_country$country),
alpha_hat = as.numeric(fe_country$country)
)
ggplot(fe_df, aes(x = reorder(country, alpha_hat), y = alpha_hat)) +
geom_point() +
geom_hline(yintercept = 0, linetype = "dashed") +
coord_flip() +
labs(x = "Pays", y = "Effet fixe estimé (α_i)",
title = "Effets fixes pays") +
theme_minimal()
On peut également vérifier la significativité globale des \(\alpha_i\) afin de regarder s’il existe de
l’hétérogénéité individuelle qui doit être prise en compte par le
modèle. Autrement dit, si tous les effets individuels sont
significatifs, alors on confirme que le modèle Pooled n’est pas
approprié, et on préfera plutôt utilise des modèles à effets fixes ou
effets aléatoires.
mod_fe <- plm(unemp ~ inflation, model="within", data_panel)
mod_pooled <- plm(unemp ~ inflation, model="pooling", data=data_panel)
pFtest(mod_fe, mod_pooled)
F test for individual effects
data: unemp ~ inflation
F = 8.0204, df1 = 149, df2 = 1791, p-value < 2.2e-16
alternative hypothesis: significant effects
L’hypothèse nulle de ce test est que tous les \(\alpha_i\) sont égaux, et qu’il n’y a donc
pas besoin d’effets fixes. L’hypothèse alternative est qu’au moins un
\(\alpha_i\) diffère, donc il y a
besoin d’utiliser des effets fixes.
En l’occurrence ici, la p-value est significative, ce qui indique
qu’on a besoin d’utiliser des effets fixes individuels plutôt qu’un
pooled model.
Effets aléatoire
Comme on a vu dans la partie sur les modèles à effets fixes, dans les
données de panel chaque individu (pays, entreprise, ménage…) possède des
caractéristiques propres et inobservables : institutions, préférences
culturelles, productivité, compétitivité, etc.
Ces caractéristiques sont représentées par un terme individuel \(\alpha_i\), qui déplace vers le haut ou
vers le bas la variable que l’on veut expliquer (ex : chômage
structurel, productivité structurelle, risque pays…). Dans les modèles à
effets fixes, on suppose que ce caractéristiques inobservables sont
corrélées aux variables explicatives. Cependant, dans le cas où ces
caractéristiques ne sont pas corrélées aux variables explicatives \[
Cov(X_{i,t}, \alpha_i)=0
\] les effets fixes sont toujours corrects, mais perdent en
efficacité. Dans ce cas précis, l’utilisation d’effets aléatoires
fournit une estimation plus précise des coefficients, en réduisant la
variance des résidus. Une autre conséquence des effets fixes est qu’il
est impossible d’ajouter des variables constantes, spécifiques à chaque
individu, en même temps que des effets fixes individuels. Dans le cas
des effets aléatoires, il est possible d’ajouter ces variables si elles
nous intéressent.
Formellement, les modèles à effets aléatoires peuvent être écrits :
\[
Y_{i,t} = \alpha + \alpha_i + \beta X_{i,t} +
\varepsilon_{i,t}\\ \alpha_i \sim iid(0,\sigma^2_\alpha) \\
Cov(\alpha_i, X_{i,t})=0
\] Note : L’estimation des modèles à effets aléatoires repose
sur les modèles GLS (Generalized Least Squares).
reg_random <- plm(unemp ~ inflation, data=data_panel, model="random")
summary(reg_random)
Oneway (individual) effect Random Effect Model
(Swamy-Arora's transformation)
Call:
plm(formula = unemp ~ inflation, data = data_panel, model = "random")
Unbalanced Panel: n = 150, T = 2-18, N = 1942
Effects:
var std.dev share
idiosyncratic 10.495 3.240 0.651
individual 5.624 2.371 0.349
theta:
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.3052 0.6570 0.6935 0.6588 0.6935 0.6935
Residuals:
Min. 1st Qu. Median Mean 3rd Qu. Max.
-5.9974 -1.9605 -0.7349 0.0669 1.5502 18.2237
Coefficients:
Estimate Std. Error z-value Pr(>|z|)
(Intercept) 5.388139 0.217691 24.7513 < 2.2e-16 ***
inflation -0.070533 0.017868 -3.9474 7.902e-05 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Total Sum of Squares: 20208
Residual Sum of Squares: 20237
R-Squared: 0.0048866
Adj. R-Squared: 0.0043737
Chisq: 15.5816 on 1 DF, p-value: 7.9021e-05
Effets fixes ou effets aléatoires ?
Le test d’Hausman est un test de spécification qui permet de
déterminer si les effets fixes sont corrélés avec les variables
explicatives. L’idée générale, comme précisé dans la partie sur les
modèles à effets aléatoires, est que si \((\alpha_i)\) est
indépendant de \((X_{it})\), alors FE et RE sont tous les
deux consistants, mais RE est plus précis. Si \((\alpha_i)\) est corrélé à
\((X_{it})\), alors seul FE est
consistant.
Le test d’Hausman a pour hypothèse nulle l’indépendence des effets
fixes avec les variables explicatives. Si la p-value est significative,
on rejette alors cette hypothèse nulle et on confirme qu’il faut
utiliser des effets fixes.
En pratique :
require(plm)
fe_model <- plm(unemp ~ inflation , data=data_panel, model="within") # modèle à effets fixes
re_model <- plm(unemp ~ inflation , data=data_panel, model="random") # modèle à effets individuels
phtest(fe_model, re_model)
Note : la fonction plm() est très utile pour faire
des modèles de panel, et peut être utilisée à la place de
feols() pour faire des régressions en panel. En revanche,
si vous avez des estimations à effets fixes, utilisez plutôt feols().
Dans la majorité des cas, les études en panel sont effectuées avec des
modèles de panel à effets fixes, et le choix de ces effets fixes
(individuel et/ou temporel) repose sur les données et la question de
recherche.
Dans le cas présent, la p-value n’est pas significative ce qui montre
que le modèle à effets aléatoires n’est pas biaisé, et il faut
privilégier ce modèle dans les estimations. En revanche, le modèle à
effets fixes est toujours correct, il est moins efficace que le modèle à
effets aléatoires dans certains cas.
Modèles à effets fixes temporels et individuels
On peut également, de la même façon qu’on peut contrôler l’influence
de variables inobservées propres à chaque individu et qui ne changent
pas dans le temps avec les effets fixes individuels, contrôler
l’influence de variables qui affectent tous les
individus et qui varient dans le temps (par exemple, des chocs
globaux). Pour cela, on a recours à des effets fixes
temporels \(\delta_t\), qui
prennent la forme de dummies spécifique à une date en particulier,
commune à tous les individus :
\[
Y_{it} = \alpha_i + \delta_t+ \beta X_{it} + \varepsilon_{it}
\]
reg_fe_it <- feols(unemp ~ inflation | country + year, data = data_panel)
etable(reg_pooled, reg_fe_i, reg_fe_it,
headers = c("Pooled OLS", "FE pays", "FE pays + année"))
Egalement, les effets fixes temporels vont prendre la forme d’une
dummy spécifique à chaque date, ce qui prend en compte les variables
inobservées communes à tous les individus, y compris les
tendances et l’influence du temps. C’est la raison pour
laquelle, en panel avec des effets fixes temporels, la stationnarité
pose moins problème qu’en séries temporelles.
Ecarts-types robustes.
Vous pouvez voir dans le résultat une ligne S.E. type.
Lorsqu’on fait des régressions - y compris en séries temporelles - les
erreurs (et la variance des erreurs) sont supposées constantes entre
tous les individus (hypothèse d’homoscédasticité des résidus). Dans la
réalité, c’est rarement le cas. L’effet direct de l’hétéroscédasticité
est qu’il va augmenter l’écart-type associé aux coefficients de
régression (donc augmenter l’incertitude dans l’inférence causale).
Il existe cependant une solution relativement simple, qui vise à
estimer les écarts-types d’une autre manière que la méthode
traditionnelle qui correspond aux modèles OLS qui respectent ces
hypothèses. La méthode la plus répandue est d’utiliser des écarts-types
robustes à l’hétéroscédasticité à la White (1980).
Dans d’autes situations, certains phénomènes n’affectent pas toutes
les observations, mais peut-être seulement certains groupes d’individus.
Cela peut obliger à utiliser les écarts-types de différentes façons :
par individu, par date, par individu-date, etc… Lorsqu’on a des données
microéconomiques suffisamment désagrégées, peut également clusteriser
par certains groupes d’individus (type de firmes par exemple),
localisation géographique (départements), etc…
reg_fe_it <- feols(unemp ~ inflation | country + year, data = data_panel)
etable(
reg_fe_it, reg_fe_it,reg_fe_it,
vcov = list(~country, ~country + year, "HC1"),
headers = c("cluster pays", "cluster pays+année", "HC1")
)
Ici on voit que la seule différence entre les deux modèles est
l’écart-type associé au coefficient de l’inflation.
Modèles de panel dynamique et GMM
Dans certains cas, on peut souhaiter estimer des modèles qui prennent
en compte la dynamique d’une série. Par exemple, si la variable \(Y_{i,t}\) est impactée par ses valeurs
passées, on peut vouloir estimer le modèle suivant :
\[
Y_{i,t} = \alpha_i + \alpha_t + \beta_1 Y_{i,t-1} + \beta_2 X_{i,t} +
\varepsilon_{i,t}
\] Ici, \(\beta_1\) va mesurer
l’impact du lag de la variable endogène sur la variable endogène
elle-même, afin de prendre en compte l’autocorrélation de la série.
Cependant, les modèles dynamique ne respectent pas la condition de
stricte exogénéité des variables explicatives, ce qui pose problème sur
l’estimation économétrique. Ces problèmes sont en général gérés par les
modèles GMM.
L’idée des GMM (Arellano-Bond) est de transformer l’équation en
différences premières, d’utiliser les lags de \(Y_t\) comme des instruments afin de
retrouver la causalité entre \(X_t\) et
\(Y_t\).
LS0tDQp0aXRsZTogIk1vZMOobGVzIGRlIHBhbmVsIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOiANCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDMNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgd29yZF9kb2N1bWVudDogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQojIERlcyBzw6lyaWVzIHRlbXBvcmVsbGVzIGF1IHBhbmVsIA0KTGVzIG1vZMOobGVzIGRlIHLDqWdyZXNzaW9uIGRlIHBhbmVsIHNvbnQgdW4gZGVzIG91dGlscyBsZXMgcGx1cyBwb3B1bGFpcmVzIGRhbnMgbGEgcmVjaGVyY2hlIGVuIMOpY29ub21pZS4gQ2VzIG1vZMOobGVzIGNvbnNpc3RlbnQgw6AgdXRpbGlzZXIgZGVzIGRvbm7DqWVzIGRpc3BvbmlibGVzIHBvdXIgcGx1c2lldXJzIHBheXMgKGxhICpjcm9zcy1zZWN0aW9uKiksIGV0IHN1ciBwbHVzaWV1cnMgcMOpcmlvZGVzIChsYSAqdGltZS1zZXJpZSopLg0KDQpMZSBtb2TDqGxlIGRlIHBhbmVsIGxpbsOpYWlyZSBjbGFzc2lxdWUgdXRpbGlzw6kgZW4gw6ljb25vbcOpdHJpZSBwZXV0IMOqdHJlIGTDqWNyaXQgcGFyIDoNCiQkDQpZX3tpLHR9ID0gIFxiZXRhIFhfe2ksdH0gKyBcdmFyZXBzaWxvbl97aSx0fQ0KJCQNCk/DuSAkaSA9IDEsIFxjZG90cyxuJCByZXByw6lzZW50ZSBsZXMgaW5kaXZpZHVzIChkZXMgcGF5cyBwYXIgZXhlbXBsZSkgZXQgJHQ9MSwgXGNkb3RzLCBUJCByZXByw6lzZW50ZSBsJ2luZGljZSB0ZW1wb3JlbCAoZGVzIGFubsOpZXMgcGFyIGV4ZW1wbGUpLiBJY2ksICRZX3tpLHR9JCByZXByw6lzZW50ZSBsYSB2YXJpYWJsZSBkw6lwZW5kYW50ZSAob3UgdmFyaWFibGUgZW5kb2fDqG5lLCBvdSB2YXJpYWJsZSBleHBsaXF1w6llKSAtIHBhciBleGVtcGxlIGxlIHRhdXggZGUgY2jDtG1hZ2UgLSBkZSBsJ2luZGl2aWR1ICRpJCDDoCBsYSBww6lyaW9kZSAkdCQgOyAkWF97aSx0fSQgcmVwcsOpc2VudGUgbGEgdmFyaWFibGUgaW5kw6lwZW5kYW50ZSAob3UgdmFyaWFibGUgZXhvZ8OobmUsIG91IHZhcmlhYmxlIGV4cGxpY2F0aXZlKSAtIHBhciBleGVtcGxlIGxlIHRhdXggZCdpbmZsYXRpb24uDQoNCg0KTGEgYmFzZSBkZSBkb25uw6llcyBlc3QgZG9uYyBjb25zdGl0dcOpZSBkZSAkbiBcdGltZXMgVCQgb2JzZXJ2YXRpb25zIGRhbnMgY2UgY2FzLCBjb250cmFpcmVtZW50IGF1eCBtb2TDqGxlcyBkZSBzw6lyaWVzIHRlbXBvcmVsbGVzIHF1aSBuZSBwb3Nzw6hkZW50IHF1ZSAkVCQgb2JzZXJ2YXRpb25zLiANCg0KUG91ciBiaWVuIHNlIHJlcHLDqXNlbnRlciBsJ2FwcG9ydCBkZXMgbW9kw6hsZXMgZGUgcGFuZWwgcGFyIHJhcHBvcnQgYXV4IG1vZMOobGVzIGRlIHPDqXJpZXMgdGVtcG9yZWxsZXMsIG9uIHBldXQgdmlzdWFsaXNlciBsYSBkaWZmw6lyZW5jZS4gDQoNCmBgYHtyfQ0KcmVxdWlyZShyZWFkeGwpDQpkYXRhX3BhbmVsIDwtIHJlYWRfZXhjZWwoIkM6L3VzZXJzL2ZrcmF1cy9EZXNrdG9wL2RhdGFfc2NodWxhcmljay54bHN4IiklPiUNCiAgc2VsZWN0KHllYXIsIGNvdW50cnksIHVuZW1wLCBjcGkpDQpkYXRhX1NUIDwtIGRhdGFfcGFuZWwgJT4lIGZpbHRlcihjb3VudHJ5PT0iRnJhbmNlIikNCg0KaGVhZChkYXRhX3BhbmVsKQ0KaGVhZChkYXRhX1NUKQ0KYGBgDQoNCkQndW4gY8O0dMOpLCBsYSBiYXNlIGRlIGRvbm7DqWVzIGBkYXRhX1NUYCBlc3QgdW5lIGJhc2UgZGUgZG9ubsOpZXMgZW4gc8OpcmllIHRlbXBvcmVsbGUgw6AgZnLDqXF1ZW5jZSBhbm51ZWxsZSwgYydlc3Qtw6AtZGlyZSBxdWkgbidlc3QgY29uc3RpdHXDqWUgcXVlIGQndW4gaW5kaXZpZHUgKGxhIEZyYW5jZSkgZW50cmUgMTg3MCBldCAyMDIwLiBEZSBsJ2F1dHJlLCBsYSBiYXNlIGBkYXRhX3BhbmVsYCBjb250aWVudCBsZXMgZG9ubsOpZXMgYW5udWVsbGVzIHBvdXIgMTggcGF5cyBlbnRyZSAxODcwIGV0IDIwMjAuIA0KDQpJbCBwZXV0IGV4aXN0ZXIgZGV1eCB0eXBlcyBkZSBiYXNlIGRlIGRvbm7DqWVzIGRlIHBhbmVsIDogbGVzIHBhbmVsIGJhbGFuY8OpcyAoKmJhbGFuY2VkIHBhbmVsKikgZXQgbGVzIG5vbi1iYWxhbmPDqXMgKCp1bmJhbGFuY2VkIHBhbmVsKikuIExlcyBwYW5lbCBiYWxhbmPDqXMgZMOpY3JpdmVudCBkZXMgYmFzZXMgZGUgZG9ubsOpZXMgZGUgcGFuZWwgcG91ciBsZXNxdWVscyB0b3VzIGxlcyBpbmRpdmlkdXMgb250IGV4YWN0ZW1lbnQgbGUgbcOqbWUgbm9tYnJlIGQnb2JzZXJ2YXRpb25zLCB0YW5kaXMgcXVlIGxlcyBub24tYmFsYW5jw6lzIHNvbnQgZGVzIGJhc2VzIG/DuSBsZSBub21icmUgZCdvYnNlcnZhdGlvbiBwZXV0IGRpZmbDqXJlciBlbnRyZSBjaGFxdWUgaW5kaXZpZHVzLiBPbiBwZXV0IHbDqXJpZmllciBwb3VyIG5vdHJlIGNhcyA6DQoNCmBgYHtyfQ0KdGFibGUoZGF0YV9wYW5lbCRjb3VudHJ5KQ0KYGBgDQpJY2ksIG9uIHZvaXQgcXUnb24gYSBtb2lucyBkJ29ic2VydmF0aW9ucyBwb3VyIGxhIEJlbGdpcXVlLCBsYSBGaW5sYW5kZSwgbCdBbGxlbWFnbmUsIGwnSXJsYW5kZSwgbCdJdGFsaWUsIGxlIEphcG9uIGV0IGxlIFBvcnR1Z2FsLCBvbiBhIGRvbmMgdW4gcGFuZWwgbm9uLWJhbGFuY8OpLiBDZWxhIG5lIHBvc2UgZW4gcmV2YW5jaGUgcGFzIGRlIHByb2Jsw6htZSBtYWpldXIgZGFucyBsYSBwbHVwYXJ0IGRlcyBjYXMuDQoNClNpIG9uIHMnaW50w6lyZXNzZSDDoCBsYSByZWxhdGlvbiBlbnRyZSBsZSB0YXV4IGRlIGNow7RtYWdlIGV0IGxlIHRhdXggZCdpbmZsYXRpb24gLSBsYSBjb3VyYmUgZGUgUGhpbGxpcHMgLSBvbiBwZXV0IGFuYWx5c2VyIGxhIHJlbGF0aW9uIHBvdXIgbGEgRnJhbmNlIGF2ZWMgbCfDqXF1YXRpb24gc3VpdmFudGUgOg0KJCQNCllfe0ZSLCB0fT0gXGFscGhhXzAgKyBcYmV0YSBYX3tGUix0fSArIFx2YXJlcHNpbG9uX3tGUix0fQ0KJCQNCkwnb3Jkb25uw6llIMOgIGwnb3JpZ2luZSBlc3QgZG9ubsOpZSBwYXIgJFxhbHBoYV8wJCBldCBsYSBwZW50ZSBkZSBsYSBjb3VyYmUgZGUgcsOpZ3Jlc3Npb24gZXN0IGRvbm7DqWUgcGFyICRcYmV0YSQuIENldHRlIMOpcXVhdGlvbiByZXZpZW50IMOgIHZpc3VhbGlzZXIgbGUgbnVhZ2UgZGUgcG9pbnRzIGVudHJlIGxlIHRhdXggZCdpbmZsYXRpb24gKCRYX3tGUix0fSQpIGV0IGRlIGNow7RtYWdlICgkWV97RlIsdH0kKSBkZSBsYSBGcmFuY2UgOg0KYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpkYXRhX1NUIDwtIGRhdGFfU1QgJT4lDQogIG11dGF0ZShpbmZsYXRpb24gPSBjKE5BLCBkaWZmKGxvZyhjcGkpKSoxMDApKQ0KDQpkYXRhX1NUICU+JSBnZ3Bsb3QoYWVzKHg9aW5mbGF0aW9uLCB5PXVuZW1wKSkrDQogIGdlb21fcG9pbnQoc2l6ZT0xKSsNCiAgbGFicyh0aXRsZT0iTnVhZ2UgZGUgcG9pbnQgZW50cmUgaW5mbGF0aW9uIGV0IGNow7RtYWdlLCBGcmFuY2UgKDE4NzEtMjAyMCkiLCB5PSJDaMO0bWFnZSAoJSkiLCB4PSJJbmZsYXRpb24gKCUpIikrDQogICNnZW9tX3Ntb290aChtZXRob2Q9ImxtIiwgZm9ybXVsYSA9IHkgfiB4KSsNCiAgdGhlbWVfYncoKQ0KYGBgDQpJY2ksIG9uIHBldXQgdm9pciBxdWUgZGFucyBsZSBjYXMgZGUgbGEgRnJhbmNlLCBvbiBhICoqMTA5IG9ic2VydmF0aW9ucyoqIHF1aSBub3VzIHBlcm1ldHRlbnQgZGUgZMOpdGVybWluZXIgbCdhbGx1cmUgZGUgbGEgcmVsYXRpb24gZMOpY3JpdGUgcGFyIGxhIGNvdXJiZSBkZSBQaGlsbGlwcyBxdWkgc2VtYmxlIMOqdHJlLCBhIHByaW9yaSwgY29uZmlybcOpZSBwYXIgbGVzIGRvbm7DqWVzLiANCg0KDQpEYW5zIGxlIGNhcyBkZXMgZG9ubsOpZXMgZGUgcGFuZWwsIG9uIHBldXQgYXBwbGlxdWVyIGxlIG3Dqm1lIG1vZMOobGUgcG91ciB0b3VzIGxlcyBpbmRpdmlkdXMgZGUgbWFuacOocmUgc8OpcGFyw6llIDoNCiQkDQpZX3tpLCB0fT0gXGFscGhhX3tpLDB9ICsgXGJldGFfaSBYX3tpLHR9ICsgXHZhcmVwc2lsb25fe2ksdH0NCiQkDQpFbmNvcmUgdW5lIGZvaXMsIGwnb3Jkb25uw6llIMOgIGwnb3JpZ2luZSBnbG9iYWxlIChwb3VyIHRvdXMgbGVzIHBheXMpIGVzdCBkb25uw6llIHBhciAkXGFscGhhXzAkIGV0IGxhIHBlbnRlIGRlIGxhIGNvdXJiZSBkZSByw6lncmVzc2lvbiAocG91ciB0b3VzIGxlcyBwYXlzKSBlc3QgZG9ubsOpZSBwYXIgJFxiZXRhJC4gQ2VsYSByZXZpZW50IMOgIGFuYWx5c2VyIGxlIG51YWdlIGRlIHBvaW50cyBlbnRyZSBsJ2luZmxhdGlvbiAoJFhfe2ksdH0kKSBldCBsZSBjaMO0bWFnZSAoJFlfe2ksdH0kKSBkZSB0b3VzIGxlcyBwYXlzIGRhbnMgbm90cmUgYmFzZSBkZSBkb25uw6llcyA6DQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KZGF0YV9wYW5lbCA8LSBkYXRhX3BhbmVsICU+JQ0KICBncm91cF9ieShjb3VudHJ5KSU+JQ0KICBtdXRhdGUoaW5mbGF0aW9uID0gYyhOQSwgZGlmZihsb2coY3BpKSkqMTAwKSklPiUNCiAgZmlsdGVyKCFpbmZsYXRpb24gPj0gNTApICMgcG91ciByZXRpcmVyIGxlcyB2YWxldXJzIGFiZXJyYW50ZXMNCg0KZGF0YV9wYW5lbCAlPiUgZ2dwbG90KGFlcyh4PWluZmxhdGlvbiwgeT11bmVtcCkpKw0KICBnZW9tX3BvaW50KGNvbG9yPSJncmV5NjAiKSsNCiAgbGFicyh0aXRsZT0iTnVhZ2UgZGUgcG9pbnQgZW50cmUgaW5mbGF0aW9uIGV0IGNow7RtYWdlIiwgeT0iQ2jDtG1hZ2UgKCUpIiwgeD0iSW5mbGF0aW9uICglKSIpKw0KICBnZW9tX3Ntb290aChzZT1GQUxTRSwgbWV0aG9kPSJsbSIsIGNvbG9yPSJibGFjayIpKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikrDQogIGZhY2V0X3dyYXAofmNvdW50cnkpICMgcG91ciBhdm9pciB1biBncmFwaGlxdWUgcGFyIGNvdW50cnkNCmBgYA0KTGVzIGRvbm7DqWVzIGRlIHBhbmVsIHNlbWJsZW50IGJpZW4gY29uZmlybWVyIGxlcyBvYnNlcnZhdGlvbnMgcXVlIGwnb24gYXZhaXQgb2J0ZW51IHBvdXIgbGEgRnJhbmNlLiANCkNlcGVuZGFudCwgb24gdm9pdCBiaWVuIHF1ZSBsYSBwZW50ZSBkZSBsYSByZWxhdGlvbiBzZW1ibGUgw6p0cmUgcGx1cyBpbXBvcnRhbnRlIGRhbnMgY2VydGFpbnMgcGF5cyAoVVNBLCBFc3BhZ25lIG91IFN1aXNzZSBwYXIgZXhlbXBsZSkgcXVlIGRhbnMgZCdhdXRyZXMgKFBvcnR1Z2FsLCBJcmxhbmRlLCBJdGFsaWUpLCB2b2lyZSBtw6ptZSBxdWUgY2V0dGUgcGVudGUgZXN0IHBvc2l0aXZlIHBvdXIgbGUgRGFuZW1hcmsuDQoNCkNldHRlIGRpZmbDqXJlbmNlIHBldXQgcHJvdmVuaXIgLSBkYW5zIGxhIG1ham9yaXTDqSBkZXMgY2FzIC0gZHUgZmFpdCBxdSdpbCB5IGEgdW5lIGjDqXTDqXJvZ8OpbsOpaXTDqSBpbm9ic2VydsOpZSBpbXBvcnRhbnRlIGVudHJlIGxlcyBkaWZmw6lyZW50cyBpbmRpdmlkdXMgKGxlcyBwYXlzKSBkYW5zIGxhIGJhc2UgZGUgZG9ubsOpZXMuIA0KDQpDZXR0ZSBow6l0w6lyb2fDqW7DqWl0w6kgcGV1dCDDqnRyZSBub3RhbW1lbnQgY2FwdMOpZSBkZSBkaWZmw6lyZW50ZXMgZmHDp29ucywgYydlc3QgY2UgcXVpIGRvbm5lIGxpZXUgYXV4IG1vZMOobGVzICoqQmV0d2VlbioqLCAqKlBvb2xlZCoqLCAqKldpdGhpbioqIGV0ICoqUmFuZG9tKiouDQoNCg0KDQoNCg0KIyBSw6lzdW3DqSBkZXMgbW9kw6hsZXMNCg0KKipCZXR3ZWVuKioNCiQkDQpcYmFyIFlfaSA9IFxhbHBoYV8wICsgXGJldGEgXGJhciBYX2kgKyBcdmFyZXBzaWxvbl97aX0NCiQkDQoqKkVmZmV0cyBhbMOpYXRvaXJlcyoqDQokJA0KIFlfe2ksdH0gPSBcYWxwaGEgKyBcYWxwaGFfaSArIFxiZXRhIFhfe2ksdH0gKyBcdmFyZXBzaWxvbl97aX0gXHF1YWQgXGFscGhhX2kgXHNpbSBpaWQoMCxcc2lnbWFeMl9cYWxwaGEpDQokJA0KU3VwcG9zZSAkIENvdihYX3tpLHR9LCBcYWxwaGFfaSkgPTAgJA0KKipFZmZldHMgZml4ZXMqKg0KJCQNCiBZX3tpLHR9ID0gXGFscGhhX2kgKyBcYmV0YSBYX3tpLHR9ICsgXHZhcmVwc2lsb25fe2l9DQokJA0KQXV0b3Jpc2UgJCBDb3YoWF97aSx0fSwgXGFscGhhX2kpIFxuZSAwICQNCg0KKipQb29sZWQqKg0KJCQNCllfe2ksdH0gPSBcYWxwaGEgKyBcYmV0YSBYX3tpLHR9ICsgXHZhcmVwc2lsb25fe2ksdH0gDQokJA0KDQojIExlcyBtb2TDqGxlcyBCZXR3ZWVuDQoNCkxlcyBtb2TDqGxlcyAqKkJldHdlZW4qKiB2b250IGFuYWx5c2VyIGxlcyBkaWZmw6lyZW5jZXMgc3RydWN0dXJlbGxlcyBlbnRyZSBsZXMgaW5kaXZpZHVzICgqKipiZXR3ZWVuIGluZGl2aWR1YWxzKioqKSwgZW4gYW5hbHlzYW50IGxlcyBtb3llbm5lcyBwYXIgaW5kaXZpZHVzLiBDJ2VzdCBzb3V2ZW50IGxlIG1vZMOobGUgbGUgcGx1cyBzaW1wbGUsIHV0aWxlIHBvdXIgYW5hbHlzZXIgbGUgdm9jYWJ1bGFpcmUgw6ljb25vbcOpdHJpcXVlLCBldCBxdWkgc2VydCBkZSBiYXNlLg0KDQpFbiBhbmFseXNhbnQgbGVzIGRpZmbDqXJlbmNlcyBwYXIgaW5kaXZpZHVzLCBvbiB2YSByw6llbGxlbWVudCBleGFtaW5lciBsJ2jDqXTDqXJvZ8OpbsOpaXTDqSwgZW4gbsOpZ2xpZ2VhbnQgY2VwZW5kYW50IGxhIGR5bmFtaXF1ZSB0ZW1wb3JlbGxlIHBhciBpbmRpdmlkdXMuDQoNCiQkDQpcYmFyIFlfaSA9IFxhbHBoYV8wICsgXGJldGEgXGJhciBYX2kgKyBcdmFyZXBzaWxvbl97aX0NCiQkDQpPw7kgDQokJA0KXGJhciBZX2kgPSBcZnJhY3sxfXtUX2l9XHN1bV90IFlfe2l0fSwgXHF1YWQNClxiYXIgWF9pID0gXGZyYWN7MX17VF9pfVxzdW1fdCBYX3tpdH0NCiQkDQpBdXRyZW1lbnQgZGl0LCBvbiBuZSBnYXJkZSwgcG91ciBjaGFxdWUgaW5kaXZpZHUgJGkkLCBxdWUgbGEgbW95ZW5uZSBkZXMgb2JzZXJ2YXRpb25zIGRlICRZJCBldCAkWCQsIGNlIHF1aSByZXZpZW50IMOgIGZhaXJlIHVuZSByw6lncmVzc2lvbiBlbiBjb3VwZSB0cmFuc3ZlcnNhbGUuIA0KDQpWaXN1ZWxsZW1lbnQsIGwnZXN0aW1hdGlvbiBkdSBtb2TDqGxlIEJldHdlZW4gcmVzc2VtYmxlIMOgIDoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KZGF0YV9iZXR3ZWVuIDwtIGRhdGFfcGFuZWwgJT4lDQogIGdyb3VwX2J5KGNvdW50cnkpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdW5lbXBfbWVhbiAgICA9IG1lYW4odW5lbXAsIG5hLnJtID0gVFJVRSksDQogICAgaW5mbGF0aW9uX21lYW4gPSBtZWFuKGluZmxhdGlvbiwgbmEucm0gPSBUUlVFKQ0KICApDQoNCmdncGxvdChkYXRhX2JldHdlZW4sDQogICAgICAgYWVzKHggPSBpbmZsYXRpb25fbWVhbiwgeSA9IHVuZW1wX21lYW4sIGxhYmVsID0gY291bnRyeSkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSkgKw0KICBnZW9tX3RleHQobnVkZ2VfeSA9IDAuMywgc2l6ZSA9IDMpICsNCiAgbGFicyh0aXRsZSA9ICJSZWxhdGlvbiBiZXR3ZWVuIDogbW95ZW5uZXMgcGFyIHBheXMiLA0KICAgICAgIHggPSAiSW5mbGF0aW9uIG1veWVubmUgKCUpIiwNCiAgICAgICB5ID0gIkNow7RtYWdlIG1veWVuICglKSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQpFdCBmb3JtZWxsZW1lbnQsIG9uIGVzdGltZSBsYSByw6lncmVzc2lvbiBzdWl2YW50ZSA6DQoNCmBgYHtyfQ0KcmVnX2JldHdlZW4gPC0gZmVvbHModW5lbXBfbWVhbiB+IGluZmxhdGlvbl9tZWFuLCBkYXRhID0gZGF0YV9iZXR3ZWVuKQ0KZXRhYmxlKHJlZ19iZXR3ZWVuKQ0KYGBgDQpMZSBjb2VmZmljaWVudCBhc3NvY2nDqSDDoCBsYSBsaWduZSBgQ29uc3RhbnRgIHJlcHLDqXNlbnRlIGwnb3Jkb25uw6llIMOgIGwnb3JpZ2luZSAkXGFscGhhXzAkLCBldCBsZSBjb2VmZmljaWVudCBhc3NvY2nDqSDDoCBgaW5mbGF0aW9uX21lYW5gIHJlcHLDqXNlbnRlIGxhIHBlbnRlIGRlIHLDqWdyZXNzaW9uICRcYmV0YSQuIERhbnMgbGUgbW9kw6hsZSBCZXR3ZWVuLCBvbiBvYnNlcnZlIHF1ZSBsZXMgcGF5cyBxdWkgc29udCBzdHJ1Y3R1cmVsbGVtZW50IHBsdXMgaW5mbGF0aW9ubmlzdGUgdGVuZGVudCDDoCBhdm9pciBkYXZhbnRhZ2UgZGUgY2jDtG1hZ2UuIA0KDQpDZSB0eXBlIGRlIG1vZMOobGUgZXN0IGVuIHJldmFuY2hlIGRhdmFudGFnZSBkZXNjcmlwdGlmIHF1ZSBjYXVzYWwsIGV0IHZpc2UgZW4gZ8OpbsOpcmFsIHBsdXTDtHQgw6Agw6l0dWRpZXIgZGVzIGNhcmFjdMOpcmlzdGlxdWVzIGludmFyaWFibGVzIGRhbnMgbGUgdGVtcHMuIA0KDQoNCiMgTGVzIG1vZMOobGVzIFBvb2xlZA0KDQpMZXMgbW9kw6hsZXMgUG9vbGVkIHZvbnQgY29uc2lkw6lyZXIgdG91dGVzIGxlcyBvYnNlcnZhdGlvbnMgZHUgcGFuZWwgY29tbWUgc2kgZWxsZXMgdmVuYWllbnQgZCd1biBzZXVsIGluZGl2aWR1LiBPbiBzdXBwb3NlIGRvbmMgaW1wbGljaXRlbWVudCBxdWUgcG91ciB0b3VzIGxlcyBpbmRpdmlkdXMsICRZJCBldCAkWCQgb250IGxhIG3Dqm1lIHJlbGF0aW9uIGV0IHF1J2lsIG4neSBhIHBhcyBkJ2jDqXTDqXJvZ8OpbsOpaXTDqSBzdHJ1Y3R1cmVsbGUgcHJvcHJlIMOgIGNoYXF1ZSBpbmRpdmlkdS4NCg0KRW4gZWZmZWN0dWFudCBkZXMgbW9kw6hsZXMgZGUgcsOpZ3Jlc3Npb24gc3DDqWNpZmlxdWVzIMOgIGNoYXF1ZSBpbmRpdmlkdXMsIGRlIHNvcnRlIMOgIGF2b2lyIHVuZSBvcmRvbm7DqWUgw6AgbCdvcmlnaW5lIGV0IHVuZSBwZW50ZSBkZSByw6lncmVzc2lvbiBkaWZmw6lyZW50ZSBwb3VyIGNoYXF1ZSBpbmRpdmlkdSAkaSQgOg0KJCQNCllfe2ksdH0gPSBcYWxwaGEgKyBcYmV0YSBYX3tpLHR9ICsgXHZhcmVwc2lsb25fe2ksdH0gDQokJA0KDQpPbiBwZXV0IGxlIHZpc3VhbGlzZXIgZW4gZmFpc2FudCB1biBncmFwaGlxdWUgcmVwcsOpc2VudGFudCBsYSByZWxhdGlvbiBpbmZsYXRpb24tY2jDtG1hZ2UgcG91ciBjaGFxdWUgaW5kaXZpZHUgOg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGxvdChkYXRhX3BhbmVsLCBhZXMoeCA9IGluZmxhdGlvbiwgeSA9IHVuZW1wKSkgKw0KICBnZW9tX3BvaW50KGFscGhhID0gMC4yKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsNCiAgbGFicyh4ID0gIkluZmxhdGlvbiIsDQogICAgICAgeSA9ICJDaMO0bWFnZSIsDQogICAgICAgdGl0bGUgPSAiUG9vbGVkIG1vZGVsIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KcmVnX3Bvb2xlZCA8LSBmZW9scyh1bmVtcCB+IGluZmxhdGlvbiwgZGF0YSA9IGRhdGFfcGFuZWwpDQpldGFibGUocmVnX2JldHdlZW4sIHJlZ19wb29sZWQsIA0KICAgICAgIGhlYWRlcnMgPWMoIkJldHdlZW4iLCAiUG9vbGVkIiksIA0KICAgICAgIGRpY3Q9IGMoInVuZW1wX21lYW4iPSJ1bmVtcCIsIA0KICAgICAgICAgICAgICAgImluZmxhdGlvbl9tZWFuIj0iaW5mbGF0aW9uIikNCiAgICAgICApDQpgYGANCkxlIG1vZMOobGUgUG9vbGVkIE9MUyBtw6lsYW5nZSBsJ2FuYWx5c2UgKiplbnRyZSoqIHBheXMgZXQgKipkYW5zKiogbGVzIHBheXMuIE9uIHZvaXQgcXUnYXZlYyBsJ2FwcG9ydCBkZSBsYSBkaW1lbnNpb24gdGVtcG9yZWxsZSBwYXIgcmFwcG9ydCBhdSBtb2TDqGxlIEJldHdlZW4sIGxlIGNvZWZmaWNpZW50IHF1aSBtZXN1cmUgbCdpbXBhY3QgZGUgbCdpbmZsYXRpb24gc3VyIGxlIHRhdXggZGUgY2jDtG1hZ2UgZXN0IGTDqXNvcm1haXMgbsOpZ2F0aWYsIGV0IHNpZ25pZmljYXRpZiDDoCAxJS4gDQoNCkNlcGVuZGFudCwgc2kgbCdow6l0w6lyb2fDqW7DqWl0w6kgZW50cmUgbGVzIHBheXMgZXN0IHRyb3AgZm9ydGUgKHNpIGxlcyBpbnN0aXR1dGlvbnMgc29udCB0csOocyBkaWZmw6lyZW50ZXMgcGFyIGV4ZW1wbGUpLCBsJ2VzdGltYXRpb24gYXZlYyBQb29sZWQgT0xTIGRldmllbnQgYmlhaXPDqWUsIGV0IGlsIGZhdXQgcGx1dMO0dCB1dGlsaXNlciBkZXMgbW9kw6hsZXMgw6AgZWZmZXRzIGZpeGVzIHF1aSBwcmVuZCByw6llbGxlbWVudCBlbiBjb21wdGUgbGEgc3RydWN0dXJlIGRlIHBhbmVsIGRlcyBkb25uw6llcy4NCg0KDQojIExlcyBtb2TDqGxlcyBXaXRoaW4NCkxlcyBtb2TDqGxlcyB3aXRoaW4sIG91IG1vZMOobGVzIMOgIGVmZmV0cyBmaXhlcywgc29udCBwbHVzIHV0aWxlcyBwb3VyIMOpdHVkaWVyIGRlcyByZWxhdGlvbnMgY2F1c2FsZXMgZW50cmUgZGVzIHZhcmlhYmxlcyBkeW5hbWlxdWVzLiBQbHV0w7R0IHF1ZSBkZSBzJ2ludMOpcmVzc2VyIGF1eCBkaWZmw6lyZW5jZXMgZW50cmUgcGF5cyAtIGNlIHF1ZSBmYWl0IGxlIG1vZMOobGUgQmV0d2VlbiAtIGxlIG1vZMOobGUgV2l0aGluIHZhIGV4YW1pbmVyIGxhIHJlbGF0aW9uIGVudHJlICRZJCBldCAkWCQgw6AgbCdpbnTDqXJpZXVyIGRlIGNoYXF1ZSBwYXlzICgqKip3aXRoaW4gZWFjaCBjb3VudHJ5KioqKS4gDQoNClBvdXIgY2VsYSwgb24gdmEgYXBwbGlxdWVyIMOgIGNoYXF1ZSBpbmRpdmlkdSBsYSB0cmFuc2Zvcm1hdGlvbiB3aXRoaW4gYXV4IHZhcmlhYmxlcywgZW4gbWVzdXJhbnQgbCfDqWNhcnQgZW50cmUgY2hhcXVlIG9ic2VydmF0aW9uIGF2ZWMgbGEgbW95ZW5uZSwgZXQgZW4gYWpvdXRhbnQgdW5lIHZhcmlhYmxlICRcYWxwaGFfaSQgLSBhcHBlbMOpZSBlZmZldCBmaXhlIGluZGl2aWR1ZWwgLSBxdWkgcHJlbmQgbGEgZm9ybWUgZCd1bmUgZHVtbXkgc3DDqWNpZmlxdWUgw6AgY2hhcXVlIGluZGl2aWR1LCBxdWkgY2FwdGUgbGVzIGRpZmbDqXJlbmNlcyBkJ29yZG9ubsOpZXMgw6AgbCdvcmlnaW5lIGVudHJlIGNoYXF1ZSBpbmRpdmlkdXMuDQoNCiQkDQogWV97aSx0fSA9IFxhbHBoYV9pICsgXGJldGEgIFhfe2ksdH0gKyBcdmFyZXBzaWxvbl97aSx0fQ0KJCQNCg0KSWNpLCAkXGFscGhhX2kkIHJlcHLDqXNlbnRlIGwnaMOpdMOpcm9nw6luw6lpdMOpIGlub2JzZXJ2w6llIHByb3ByZSDDoCBsJ2luZGl2aWR1ICRpJCAoY3VsdHVyZSwgaW5zdGl0dXRpb25zLCBzdHJ1Y3R1cmUgw6ljb25vbWlxdWUsIC4uLiksIHRhbmRpcyBxdWUgJHVfe2ksdH0kIHJlcHLDqXNlbnRlIGxlcyBjaG9jcyBpZGlvc3luY3JhdGlxdWVzIGNvbW1lIGVuIHPDqXJpZXMgdGVtcG9yZWxsZXMuICAkXGFscGhhX2kkIGVzdCAqKmNvbnN0YW50IGRhbnMgbGUgdGVtcHMqKiBwb3VyIHVuIGluZGl2aWR1LCBtYWlzIGlsIGVzdCBkaWZmw6lyZW50ICoqZW50cmUqKiBsZXMgaW5kaXZpZHVzLiBFZ2FsZW1lbnQsIGlsIHBldXQgw6p0cmUgY29ycsOpbMOpIGF2ZWMgbGVzIHZhcmlhYmxlcyBleHBsaWNhdGl2ZXMgJFhfe2ksdH0kLg0KDQpPbiBjYWxjdWxlIGxhIG1veWVubmUgdGVtcG9yZWxsZSBwb3VyIGNoYXF1ZSBwYXlzIDoNCg0KJCQNClxiYXIgWV9pID0gXGZyYWN7MX17VH1cc3VtX3QgWV97aXR9LCBccXVhZA0KXGJhciBYX2kgPSBcZnJhY3sxfXtUfVxzdW1fdCBYX3tpdH0sIFxxdWFkDQpcYmFyIFx2YXJlcHNpbG9uX2kgPSBcZnJhY3sxfXtUfVxzdW1fdCBcdmFyZXBzaWxvbl97aXR9DQokJA0KDQpFbiByw6nDqWNyaXZhbnQgbGUgbW9kw6hsZSBhdmVjIGxlcyBtb3llbm5lcywgb24gYSA6DQoNCiQkDQpcYmFyIFlfaSA9IFxhbHBoYV9pICsgXGJldGEgXGJhciBYX2kgKyBcYmFyIFx2YXJlcHNpbG9uX2kNCiQkDQoNCk9uIHNvdXN0cmFpdCBjZXR0ZSDDqXF1YXRpb24gw6AgbOKAmcOpcXVhdGlvbiBvcmlnaW5hbGUgOg0KDQoNClxiZWdpbnthbGlnbn0NCllfe2l0fSAtIFxiYXIgWV9pICY9IChcYWxwaGFfaSArIFxiZXRhIFhfe2l0fSArIFx2YXJlcHNpbG9uX3tpdH0pIC0gKFxhbHBoYV9pICsgXGJldGEgXGJhciBYX2kgKyBcYmFyIFx2YXJlcHNpbG9uX2kpIFxcDQomPSBcYmV0YSAoWF97aXR9IC0gXGJhciBYX2kpICsgKFx2YXJlcHNpbG9uX3tpdH0gLSBcYmFyIFx2YXJlcHNpbG9uX2kpLg0KXGVuZHthbGlnbn0NCg0KDQpPbiBvYnRpZW50IGFsb3JzIDoNCg0KJCQNClx0aWxkZSBZX3tpdH0gPSBcYmV0YSBcdGlsZGUgWF97aXR9ICsgXHRpbGRlIFx2YXJlcHNpbG9uX3tpdH0NCiQkDQpvw7kgbGVzIHRpbGRlcyAoJFx0aWxkZSB5X3tpdH0kLCAkXHRpbGRlIHhfe2l0fSQsICRcdGlsZGUgXHZhcmVwc2lsb25fe2l0fSQgKSBkw6lzaWduZW50IGxlcyB2YXJpYWJsZXMgJ2NlbnRyw6llcycgcGFyIGluZGl2aWR1LiBPbiBwZXV0IGFsb3JzIGVmZmVjdGl2ZW1lbnQgZXN0aW1lciAkXGJldGEkIHBhciB1bmUgcsOpZ3Jlc3Npb24gT0xTIGNsYXNzaXF1ZSBzdXIgbGVzIHZhcmlhYmxlcyB0cmFuc2Zvcm3DqWVzIDogYydlc3QgKipsJ2VzdGltYXRldXIgd2l0aGluKiouIA0KDQpFbiDDqXR1ZGlhbnQgdW5pcXVlbWVudCBsZXMgZGlmZsOpcmVuY2VzIMOgIGxhIG1veWVubmUsIGxhIHRyYW5zZm9ybWF0aW9uIHdpdGhpbiDDqWxpbWluZSBsJ2jDqXTDqXJvZ8OpbsOpaXTDqSBzdHJ1Y3R1cmVsbGUgZW50cmUgbGVzIGluZGl2aWR1cywgZXQgbGVzIG9ic2VydmF0aW9ucyBkZXZpZW5uZW50IGRvbmMgbGVzIHZhcmlhdGlvbnMgZGFucyBsZXMgaW5kaXZpZHVzIGF1IGNvdXJzIGR1IHRlbXBzLg0KDQpWaXN1ZWxsZW1lbnQsIGxhIG3DqXRob2RlIHdpdGhpbiBwZXJtZXQgZGUgbWVzdXJlIGwnaW1wYWN0IGdsb2JhbCBkJ3VuZSB2YXJpYXRpb24gZGUgJFgkIHN1ciBsYSB2YXJpYWJsZSAkWSQgcG91ciBwbHVzaWV1cnMgaW5kaXZpZHVzLCBkYW5zIGxlIHRlbXBzLg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCndpdGhpbl9kZiA8LSBkYXRhX3BhbmVsICU+JQ0KICBncm91cF9ieShjb3VudHJ5KSAlPiUNCiAgbXV0YXRlKA0KICAgIHVuZW1wX3dpdGhpbiA9IHVuZW1wIC0gbWVhbih1bmVtcCwgbmEucm0gPSBUUlVFKSwNCiAgICBpbmZsX3dpdGhpbiAgPSBpbmZsYXRpb24gLSBtZWFuKGluZmxhdGlvbiwgbmEucm0gPSBUUlVFKQ0KICApDQoNCmdncGxvdCh3aXRoaW5fZGYsIGFlcyh4ID0gaW5mbF93aXRoaW4sIHkgPSB1bmVtcF93aXRoaW4pKSArDQogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjIpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSkgKw0KICBsYWJzKHggPSAiSW5mbGF0aW9uIGNlbnRyw6llIHBhciBwYXlzICh3aXRoaW4pIiwNCiAgICAgICB5ID0gIkNow7RtYWdlIGNlbnRyw6kgcGFyIHBheXMgKHdpdGhpbikiLA0KICAgICAgIHRpdGxlID0gIlJlbGF0aW9uIHdpdGhpbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KDQpPbiBwZXV0IGFsb3JzIGVzdGltZXIgbGUgbW9kw6hsZSBzdWl2YW50IDoNCiQkDQpZX3tpdH0gPSBcYWxwaGFfaSArIFxiZXRhIFhfe2l0fSArIFx2YXJlcHNpbG9uX3tpdH0NCiQkDQpFbiBwcmVuYW50IGVuIGNvbXB0ZSBsJ2jDqXTDqXJvZ8OpbsOpaXTDqSBlbnRyZSBwYXlzIGF2ZWMgJFxhbHBoYV9pJCwgbGUgY29lZmZpY2llbnQgJFxiZXRhJCByZXByw6lzZW50ZSBkw6lzb3JtYWlzIGwnZWZmZXQgZGUgJFhfe2ksdH0kIHN1ciAkWV97aSx0fSQgYXUgc2VpbiBkJ3VuIG3Dqm1lIHBheXMuDQoNCk9uIHBldXQgZXN0aW1lciBsJ2ltcGFjdCBkdSB0YXV4IGQnaW5mbGF0aW9uIHN1ciBsZSB0YXV4IGRlIGNow7RtYWdlIGF2ZWMgdW4gbW9kw6hsZSB3aXRoaW4sIGVuIGFqb3V0YW50IGRlcyBlZmZldHMgZml4ZXMgKG9uIGNvbXBhcmUgw6lnYWxlbWVudCBhdmVjIGxlIG1vZMOobGUgUG9vbGVkKSA6DQpgYGB7cix3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KcmVnX2ZlX2kgPC0gZmVvbHModW5lbXAgfiBpbmZsYXRpb24gfCBjb3VudHJ5LCBkYXRhID0gZGF0YV9wYW5lbCkNCmV0YWJsZShyZWdfYmV0d2VlbiwgcmVnX3Bvb2xlZCwgIHJlZ19mZV9pLA0KICAgICAgIGhlYWRlcnMgPWMoIkJldHdlZW4iLCAiUG9vbGVkIiwgIldpdGhpbiIpLCANCiAgICAgICBkaWN0PSBjKCJ1bmVtcF9tZWFuIj0idW5lbXAiLCANCiAgICAgICAgICAgICAgICJpbmZsYXRpb25fbWVhbiI9ImluZmxhdGlvbiIpLCANCiAgICAgICB2Y292PSJpaWQiKQ0KYGBgDQpEYW5zIGxlIG1vZMOobGUgw6AgZWZmZXRzIGZpeGVzIGluZGl2aWR1ZWxzIChgV2l0aGluYCksIGxlIGNvZWZmaWNpZW50ICRcYmV0YSQgbWVzdXJlIGNvbW1lbnQgbGUgY2jDtG1hZ2UgdmFyaWUgcXVhbmQgbCdpbmZsYXRpb24gYXVnbWVudGUgZGFucyB1biBtw6ptZSBwYXlzIGF1IGNvdXJzIGR1IHRlbXBzLCBhcHLDqHMgYXZvaXIgcmV0aXLDqSBsZXMgZGlmZsOpcmVuY2VzIHN0cnVjdHVyZWxsZXMgZW50cmUgcGF5cyAobGVzIGVmZmV0cyBmaXhlcyBpbmRpdmlkdWVscykuDQogDQpPbiB2b2l0IMOpZ2FsZW1lbnQgcXVlIGRhbnMgbGUgbW9kw6hsZSDDoCBlZmZldHMgZml4ZXMsIGlsIG4neSBhIHBhcyBkZSBjb2VmZmljaWVudCBhc3NvY2nDqSDDoCBgQ29uc3RhbnRgLCBjYXIgaWwgeSBhIHVuZSBjb25zdGFudGUgcG91ciBjaGFxdWUgaW5kaXZpZHUgcXVpIGVzdCBjYXB0w6llIHBhciBsZXMgZWZmZXRzIGZpeGVzIGluZGl2aWR1ZWxzLiBPbiBwZXV0IGNlcGVuZGFudCByw6ljdXDDqXJlciBsZXMgZWZmZXRzIGZpeGVzIHBheXMsIGV0IGZhaXJlIHVuIGdyYXBoaXF1ZSBwb3VyIHZvaXIgbCdow6l0w6lyb2fDqW7DqWl0w6kgOg0KDQpgYGB7cn0NCmZlX2NvdW50cnkgPC0gZml4ZWYocmVnX2ZlX2kpDQoNCmZlX2RmIDwtIGRhdGEuZnJhbWUoDQogIGNvdW50cnkgICA9IG5hbWVzKGZlX2NvdW50cnkkY291bnRyeSksDQogIGFscGhhX2hhdCA9IGFzLm51bWVyaWMoZmVfY291bnRyeSRjb3VudHJ5KQ0KKQ0KDQpnZ3Bsb3QoZmVfZGYsIGFlcyh4ID0gcmVvcmRlcihjb3VudHJ5LCBhbHBoYV9oYXQpLCB5ID0gYWxwaGFfaGF0KSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnMoeCA9ICJQYXlzIiwgeSA9ICJFZmZldCBmaXhlIGVzdGltw6kgKM6xX2kpIiwNCiAgICAgICB0aXRsZSA9ICJFZmZldHMgZml4ZXMgcGF5cyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCg0KDQoNCmBgYA0KDQpPbiBwZXV0IMOpZ2FsZW1lbnQgdsOpcmlmaWVyIGxhIHNpZ25pZmljYXRpdml0w6kgZ2xvYmFsZSBkZXMgJFxhbHBoYV9pJCBhZmluIGRlIHJlZ2FyZGVyIHMnaWwgZXhpc3RlIGRlIGwnaMOpdMOpcm9nw6luw6lpdMOpIGluZGl2aWR1ZWxsZSBxdWkgZG9pdCDDqnRyZSBwcmlzZSBlbiBjb21wdGUgcGFyIGxlIG1vZMOobGUuIEF1dHJlbWVudCBkaXQsIHNpIHRvdXMgbGVzIGVmZmV0cyBpbmRpdmlkdWVscyBzb250IHNpZ25pZmljYXRpZnMsIGFsb3JzIG9uIGNvbmZpcm1lIHF1ZSBsZSBtb2TDqGxlIFBvb2xlZCBuJ2VzdCBwYXMgYXBwcm9wcmnDqSwgZXQgb24gcHLDqWZlcmEgcGx1dMO0dCB1dGlsaXNlIGRlcyBtb2TDqGxlcyDDoCBlZmZldHMgZml4ZXMgb3UgZWZmZXRzIGFsw6lhdG9pcmVzLg0KYGBge3J9DQptb2RfZmUgPC0gcGxtKHVuZW1wIH4gaW5mbGF0aW9uLCBtb2RlbD0id2l0aGluIiwgZGF0YV9wYW5lbCkNCm1vZF9wb29sZWQgPC0gIHBsbSh1bmVtcCB+IGluZmxhdGlvbiwgbW9kZWw9InBvb2xpbmciLCBkYXRhPWRhdGFfcGFuZWwpDQoNCnBGdGVzdChtb2RfZmUsIG1vZF9wb29sZWQpDQoNCmBgYA0KTCdoeXBvdGjDqHNlIG51bGxlIGRlIGNlIHRlc3QgZXN0IHF1ZSB0b3VzIGxlcyAkXGFscGhhX2kkIHNvbnQgw6lnYXV4LCBldCBxdSdpbCBuJ3kgYSBkb25jIHBhcyBiZXNvaW4gZCdlZmZldHMgZml4ZXMuIEwnaHlwb3Row6hzZSBhbHRlcm5hdGl2ZSBlc3QgcXUnYXUgbW9pbnMgdW4gJFxhbHBoYV9pJCBkaWZmw6hyZSwgZG9uYyBpbCB5IGEgYmVzb2luIGQndXRpbGlzZXIgZGVzIGVmZmV0cyBmaXhlcy4NCg0KRW4gbCdvY2N1cnJlbmNlIGljaSwgbGEgcC12YWx1ZSBlc3Qgc2lnbmlmaWNhdGl2ZSwgY2UgcXVpIGluZGlxdWUgcXUnb24gYSBiZXNvaW4gZCd1dGlsaXNlciBkZXMgZWZmZXRzIGZpeGVzIGluZGl2aWR1ZWxzIHBsdXTDtHQgcXUndW4gcG9vbGVkIG1vZGVsLg0KDQoNCg0KDQoNCiMgRWZmZXRzIGFsw6lhdG9pcmUgDQpDb21tZSBvbiBhIHZ1IGRhbnMgbGEgcGFydGllIHN1ciBsZXMgbW9kw6hsZXMgw6AgZWZmZXRzIGZpeGVzLCBkYW5zIGxlcyBkb25uw6llcyBkZSBwYW5lbCBjaGFxdWUgaW5kaXZpZHUgKHBheXMsIGVudHJlcHJpc2UsIG3DqW5hZ2XigKYpIHBvc3PDqGRlIGRlcyBjYXJhY3TDqXJpc3RpcXVlcyBwcm9wcmVzIGV0IGlub2JzZXJ2YWJsZXMgOiBpbnN0aXR1dGlvbnMsIHByw6lmw6lyZW5jZXMgY3VsdHVyZWxsZXMsIHByb2R1Y3Rpdml0w6ksIGNvbXDDqXRpdGl2aXTDqSwgZXRjLg0KDQpDZXMgY2FyYWN0w6lyaXN0aXF1ZXMgc29udCByZXByw6lzZW50w6llcyBwYXIgdW4gdGVybWUgaW5kaXZpZHVlbCAkXGFscGhhX2kkLCBxdWkgZMOpcGxhY2UgdmVycyBsZSBoYXV0IG91IHZlcnMgbGUgYmFzIGxhIHZhcmlhYmxlIHF1ZSBs4oCZb24gdmV1dCBleHBsaXF1ZXIgKGV4IDogY2jDtG1hZ2Ugc3RydWN0dXJlbCwgcHJvZHVjdGl2aXTDqSBzdHJ1Y3R1cmVsbGUsIHJpc3F1ZSBwYXlz4oCmKS4gRGFucyBsZXMgbW9kw6hsZXMgw6AgZWZmZXRzIGZpeGVzLCBvbiBzdXBwb3NlIHF1ZSBjZSBjYXJhY3TDqXJpc3RpcXVlcyBpbm9ic2VydmFibGVzIHNvbnQgY29ycsOpbMOpZXMgYXV4IHZhcmlhYmxlcyBleHBsaWNhdGl2ZXMuIENlcGVuZGFudCwgZGFucyBsZSBjYXMgb8O5IGNlcyBjYXJhY3TDqXJpc3RpcXVlcyBuZSBzb250IHBhcyBjb3Jyw6lsw6llcyBhdXggdmFyaWFibGVzIGV4cGxpY2F0aXZlcw0KJCQNCkNvdihYX3tpLHR9LCBcYWxwaGFfaSk9MA0KJCQNCmxlcyBlZmZldHMgZml4ZXMgc29udCB0b3Vqb3VycyBjb3JyZWN0cywgbWFpcyBwZXJkZW50IGVuIGVmZmljYWNpdMOpLiBEYW5zIGNlIGNhcyBwcsOpY2lzLCBsJ3V0aWxpc2F0aW9uIGQnZWZmZXRzIGFsw6lhdG9pcmVzIGZvdXJuaXQgdW5lIGVzdGltYXRpb24gcGx1cyBwcsOpY2lzZSBkZXMgY29lZmZpY2llbnRzLCBlbiByw6lkdWlzYW50IGxhIHZhcmlhbmNlIGRlcyByw6lzaWR1cy4gVW5lIGF1dHJlIGNvbnPDqXF1ZW5jZSBkZXMgZWZmZXRzIGZpeGVzIGVzdCBxdSdpbCBlc3QgaW1wb3NzaWJsZSBkJ2Fqb3V0ZXIgZGVzIHZhcmlhYmxlcyBjb25zdGFudGVzLCBzcMOpY2lmaXF1ZXMgw6AgY2hhcXVlIGluZGl2aWR1LCBlbiBtw6ptZSB0ZW1wcyBxdWUgZGVzIGVmZmV0cyBmaXhlcyBpbmRpdmlkdWVscy4gRGFucyBsZSBjYXMgZGVzIGVmZmV0cyBhbMOpYXRvaXJlcywgaWwgZXN0IHBvc3NpYmxlIGQnYWpvdXRlciBjZXMgdmFyaWFibGVzIHNpIGVsbGVzIG5vdXMgaW50w6lyZXNzZW50LiANCg0KRm9ybWVsbGVtZW50LCBsZXMgbW9kw6hsZXMgw6AgZWZmZXRzIGFsw6lhdG9pcmVzIHBldXZlbnQgw6p0cmUgw6ljcml0cyA6DQokJA0KIFlfe2ksdH0gPSBcYWxwaGEgKyBcYWxwaGFfaSArIFxiZXRhIFhfe2ksdH0gKyBcdmFyZXBzaWxvbl97aSx0fVxcICBcYWxwaGFfaSBcc2ltIGlpZCgwLFxzaWdtYV4yX1xhbHBoYSkgXFwNCiBDb3YoXGFscGhhX2ksIFhfe2ksdH0pPTANCiQkDQoqTm90ZSA6IEwnZXN0aW1hdGlvbiBkZXMgbW9kw6hsZXMgw6AgZWZmZXRzIGFsw6lhdG9pcmVzIHJlcG9zZSBzdXIgbGVzIG1vZMOobGVzIEdMUyAoR2VuZXJhbGl6ZWQgTGVhc3QgU3F1YXJlcykuKiANCg0KYGBge3J9DQpyZWdfcmFuZG9tIDwtIHBsbSh1bmVtcCB+IGluZmxhdGlvbiwgZGF0YT1kYXRhX3BhbmVsLCBtb2RlbD0icmFuZG9tIikNCnN1bW1hcnkocmVnX3JhbmRvbSkNCmBgYA0KDQoNCg0KDQoNCiMgRWZmZXRzIGZpeGVzIG91IGVmZmV0cyBhbMOpYXRvaXJlcyA/IA0KTGUgdGVzdCBkJ0hhdXNtYW4gZXN0IHVuIHRlc3QgZGUgc3DDqWNpZmljYXRpb24gcXVpIHBlcm1ldCBkZSBkw6l0ZXJtaW5lciBzaSBsZXMgZWZmZXRzIGZpeGVzIHNvbnQgY29ycsOpbMOpcyBhdmVjIGxlcyB2YXJpYWJsZXMgZXhwbGljYXRpdmVzLiBMJ2lkw6llIGfDqW7DqXJhbGUsIGNvbW1lIHByw6ljaXPDqSBkYW5zIGxhIHBhcnRpZSBzdXIgbGVzIG1vZMOobGVzIMOgIGVmZmV0cyBhbMOpYXRvaXJlcywgZXN0IHF1ZSBzaSAkKFxhbHBoYV9pKSQgZXN0ICoqaW5kw6lwZW5kYW50KiogZGUgJChYX3tpdH0pJCwgYWxvcnMgRkUgZXQgUkUgc29udCB0b3VzIGxlcyBkZXV4IGNvbnNpc3RhbnRzLCBtYWlzIFJFIGVzdCBwbHVzIHByw6ljaXMuIFNpICQoXGFscGhhX2kpJCBlc3QgKipjb3Jyw6lsw6kqKiDDoCAkKFhfe2l0fSkkLCBhbG9ycyBzZXVsIEZFIGVzdCBjb25zaXN0YW50Lg0KDQpMZSB0ZXN0IGQnSGF1c21hbiBhIHBvdXIgaHlwb3Row6hzZSBudWxsZSBsJ2luZMOpcGVuZGVuY2UgZGVzIGVmZmV0cyBmaXhlcyBhdmVjIGxlcyB2YXJpYWJsZXMgZXhwbGljYXRpdmVzLiBTaSBsYSBwLXZhbHVlIGVzdCBzaWduaWZpY2F0aXZlLCBvbiByZWpldHRlIGFsb3JzIGNldHRlIGh5cG90aMOoc2UgbnVsbGUgZXQgb24gY29uZmlybWUgcXUnaWwgZmF1dCB1dGlsaXNlciBkZXMgZWZmZXRzIGZpeGVzLg0KDQpFbiBwcmF0aXF1ZSA6DQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KcmVxdWlyZShwbG0pDQpmZV9tb2RlbCA8LSBwbG0odW5lbXAgfiBpbmZsYXRpb24gLCBkYXRhPWRhdGFfcGFuZWwsIG1vZGVsPSJ3aXRoaW4iKSAjIG1vZMOobGUgw6AgZWZmZXRzIGZpeGVzDQpyZV9tb2RlbCA8LSBwbG0odW5lbXAgfiBpbmZsYXRpb24gLCBkYXRhPWRhdGFfcGFuZWwsIG1vZGVsPSJyYW5kb20iKSAjIG1vZMOobGUgw6AgZWZmZXRzIGluZGl2aWR1ZWxzDQoNCnBodGVzdChmZV9tb2RlbCwgcmVfbW9kZWwpDQpgYGANCipOb3RlIDogbGEgZm9uY3Rpb24gYHBsbSgpYCBlc3QgdHLDqHMgdXRpbGUgcG91ciBmYWlyZSBkZXMgbW9kw6hsZXMgZGUgcGFuZWwsIGV0IHBldXQgw6p0cmUgdXRpbGlzw6llIMOgIGxhIHBsYWNlIGRlIGBmZW9scygpYCBwb3VyIGZhaXJlIGRlcyByw6lncmVzc2lvbnMgZW4gcGFuZWwuIEVuIHJldmFuY2hlLCBzaSB2b3VzIGF2ZXogZGVzIGVzdGltYXRpb25zIMOgIGVmZmV0cyBmaXhlcywgdXRpbGlzZXogcGx1dMO0dCBmZW9scygpLiBEYW5zIGxhIG1ham9yaXTDqSBkZXMgY2FzLCBsZXMgw6l0dWRlcyBlbiBwYW5lbCBzb250IGVmZmVjdHXDqWVzIGF2ZWMgZGVzIG1vZMOobGVzIGRlIHBhbmVsIMOgIGVmZmV0cyBmaXhlcywgZXQgbGUgY2hvaXggZGUgY2VzIGVmZmV0cyBmaXhlcyAoaW5kaXZpZHVlbCBldC9vdSB0ZW1wb3JlbCkgcmVwb3NlIHN1ciBsZXMgZG9ubsOpZXMgZXQgbGEgcXVlc3Rpb24gZGUgcmVjaGVyY2hlLioNCg0KRGFucyBsZSBjYXMgcHLDqXNlbnQsIGxhIHAtdmFsdWUgbidlc3QgcGFzIHNpZ25pZmljYXRpdmUgY2UgcXVpIG1vbnRyZSBxdWUgbGUgbW9kw6hsZSDDoCBlZmZldHMgYWzDqWF0b2lyZXMgbidlc3QgcGFzIGJpYWlzw6ksIGV0IGlsIGZhdXQgcHJpdmlsw6lnaWVyIGNlIG1vZMOobGUgZGFucyBsZXMgZXN0aW1hdGlvbnMuIEVuIHJldmFuY2hlLCBsZSBtb2TDqGxlIMOgIGVmZmV0cyBmaXhlcyBlc3QgdG91am91cnMgY29ycmVjdCwgaWwgZXN0IG1vaW5zIGVmZmljYWNlIHF1ZSBsZSBtb2TDqGxlIMOgIGVmZmV0cyBhbMOpYXRvaXJlcyBkYW5zIGNlcnRhaW5zIGNhcy4NCg0KDQoNCg0KDQojIE1vZMOobGVzIMOgIGVmZmV0cyBmaXhlcyB0ZW1wb3JlbHMgZXQgaW5kaXZpZHVlbHMNCk9uIHBldXQgw6lnYWxlbWVudCwgZGUgbGEgbcOqbWUgZmHDp29uIHF1J29uIHBldXQgY29udHLDtGxlciBsJ2luZmx1ZW5jZSBkZSB2YXJpYWJsZXMgaW5vYnNlcnbDqWVzIHByb3ByZXMgw6AgY2hhcXVlIGluZGl2aWR1IGV0IHF1aSBuZSBjaGFuZ2VudCBwYXMgZGFucyBsZSB0ZW1wcyBhdmVjIGxlcyBlZmZldHMgZml4ZXMgaW5kaXZpZHVlbHMsIGNvbnRyw7RsZXIgbCdpbmZsdWVuY2UgZGUgdmFyaWFibGVzIHF1aSBhZmZlY3RlbnQgKip0b3VzIGxlcyBpbmRpdmlkdXMqKiBldCBxdWkgdmFyaWVudCBkYW5zIGxlIHRlbXBzIChwYXIgZXhlbXBsZSwgZGVzIGNob2NzIGdsb2JhdXgpLiBQb3VyIGNlbGEsIG9uIGEgcmVjb3VycyDDoCBkZXMgKiplZmZldHMgZml4ZXMgdGVtcG9yZWxzKiogJFxkZWx0YV90JCwgcXVpIHByZW5uZW50IGxhIGZvcm1lIGRlIGR1bW1pZXMgc3DDqWNpZmlxdWUgw6AgdW5lIGRhdGUgZW4gcGFydGljdWxpZXIsIGNvbW11bmUgw6AgdG91cyBsZXMgaW5kaXZpZHVzIDoNCg0KJCQNCllfe2l0fSA9IFxhbHBoYV9pICsgXGRlbHRhX3QrIFxiZXRhIFhfe2l0fSArIFx2YXJlcHNpbG9uX3tpdH0NCiQkDQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KcmVnX2ZlX2l0IDwtIGZlb2xzKHVuZW1wIH4gaW5mbGF0aW9uIHwgY291bnRyeSArIHllYXIsIGRhdGEgPSBkYXRhX3BhbmVsKQ0KDQpldGFibGUocmVnX3Bvb2xlZCwgcmVnX2ZlX2ksIHJlZ19mZV9pdCwNCiAgICAgICBoZWFkZXJzID0gYygiUG9vbGVkIE9MUyIsICJGRSBwYXlzIiwgIkZFIHBheXMgKyBhbm7DqWUiKSkNCmBgYA0KDQpFZ2FsZW1lbnQsIGxlcyBlZmZldHMgZml4ZXMgdGVtcG9yZWxzIHZvbnQgcHJlbmRyZSBsYSBmb3JtZSBkJ3VuZSBkdW1teSBzcMOpY2lmaXF1ZSDDoCBjaGFxdWUgZGF0ZSwgY2UgcXVpIHByZW5kIGVuIGNvbXB0ZSBsZXMgdmFyaWFibGVzIGlub2JzZXJ2w6llcyBjb21tdW5lcyDDoCB0b3VzIGxlcyBpbmRpdmlkdXMsICoqeSBjb21wcmlzIGxlcyB0ZW5kYW5jZXMgZXQgbCdpbmZsdWVuY2UgZHUgdGVtcHMqKi4gQydlc3QgbGEgcmFpc29uIHBvdXIgbGFxdWVsbGUsIGVuIHBhbmVsIGF2ZWMgZGVzIGVmZmV0cyBmaXhlcyB0ZW1wb3JlbHMsIGxhIHN0YXRpb25uYXJpdMOpIHBvc2UgbW9pbnMgcHJvYmzDqG1lIHF1J2VuIHPDqXJpZXMgdGVtcG9yZWxsZXMuDQoNCg0KIyBFY2FydHMtdHlwZXMgcm9idXN0ZXMuDQpWb3VzIHBvdXZleiB2b2lyIGRhbnMgbGUgcsOpc3VsdGF0IHVuZSBsaWduZSBgUy5FLiB0eXBlYC4gTG9yc3F1J29uIGZhaXQgZGVzIHLDqWdyZXNzaW9ucyAtIHkgY29tcHJpcyBlbiBzw6lyaWVzIHRlbXBvcmVsbGVzIC0gbGVzIGVycmV1cnMgKGV0IGxhIHZhcmlhbmNlIGRlcyBlcnJldXJzKSBzb250IHN1cHBvc8OpZXMgY29uc3RhbnRlcyBlbnRyZSB0b3VzIGxlcyBpbmRpdmlkdXMgKGh5cG90aMOoc2UgZCdob21vc2PDqWRhc3RpY2l0w6kgZGVzIHLDqXNpZHVzKS4gRGFucyBsYSByw6lhbGl0w6ksIGMnZXN0IHJhcmVtZW50IGxlIGNhcy4gTCdlZmZldCBkaXJlY3QgZGUgbCdow6l0w6lyb3Njw6lkYXN0aWNpdMOpIGVzdCBxdSdpbCB2YSBhdWdtZW50ZXIgbCfDqWNhcnQtdHlwZSBhc3NvY2nDqSBhdXggY29lZmZpY2llbnRzIGRlIHLDqWdyZXNzaW9uIChkb25jIGF1Z21lbnRlciBsJ2luY2VydGl0dWRlIGRhbnMgbCdpbmbDqXJlbmNlIGNhdXNhbGUpLg0KDQpJbCBleGlzdGUgY2VwZW5kYW50IHVuZSBzb2x1dGlvbiByZWxhdGl2ZW1lbnQgc2ltcGxlLCBxdWkgdmlzZSDDoCBlc3RpbWVyIGxlcyDDqWNhcnRzLXR5cGVzIGQndW5lIGF1dHJlIG1hbmnDqHJlIHF1ZSBsYSBtw6l0aG9kZSB0cmFkaXRpb25uZWxsZSBxdWkgY29ycmVzcG9uZCBhdXggbW9kw6hsZXMgT0xTIHF1aSByZXNwZWN0ZW50IGNlcyBoeXBvdGjDqHNlcy4gTGEgbcOpdGhvZGUgbGEgcGx1cyByw6lwYW5kdWUgZXN0IGQndXRpbGlzZXIgZGVzIMOpY2FydHMtdHlwZXMgcm9idXN0ZXMgw6AgbCdow6l0w6lyb3Njw6lkYXN0aWNpdMOpIMOgIGxhIFdoaXRlICgxOTgwKS4gDQoNCkRhbnMgZCdhdXRlcyBzaXR1YXRpb25zLCBjZXJ0YWlucyBwaMOpbm9tw6huZXMgbidhZmZlY3RlbnQgcGFzIHRvdXRlcyBsZXMgb2JzZXJ2YXRpb25zLCBtYWlzIHBldXQtw6p0cmUgc2V1bGVtZW50IGNlcnRhaW5zIGdyb3VwZXMgZCdpbmRpdmlkdXMuIENlbGEgcGV1dCBvYmxpZ2VyIMOgIHV0aWxpc2VyIGxlcyDDqWNhcnRzLXR5cGVzIGRlIGRpZmbDqXJlbnRlcyBmYcOnb25zIDogcGFyIGluZGl2aWR1LCBwYXIgZGF0ZSwgcGFyIGluZGl2aWR1LWRhdGUsIGV0Yy4uLiBMb3JzcXUnb24gYSBkZXMgZG9ubsOpZXMgbWljcm/DqWNvbm9taXF1ZXMgc3VmZmlzYW1tZW50IGTDqXNhZ3LDqWfDqWVzLCBwZXV0IMOpZ2FsZW1lbnQgY2x1c3RlcmlzZXIgcGFyIGNlcnRhaW5zIGdyb3VwZXMgZCdpbmRpdmlkdXMgKHR5cGUgZGUgZmlybWVzIHBhciBleGVtcGxlKSwgbG9jYWxpc2F0aW9uIGfDqW9ncmFwaGlxdWUgKGTDqXBhcnRlbWVudHMpLCBldGMuLi4gICANCg0KDQoNCmBgYHtyfQ0KcmVnX2ZlX2l0IDwtIGZlb2xzKHVuZW1wIH4gaW5mbGF0aW9uIHwgY291bnRyeSArIHllYXIsIGRhdGEgPSBkYXRhX3BhbmVsKQ0KDQpldGFibGUoDQogIHJlZ19mZV9pdCwgcmVnX2ZlX2l0LHJlZ19mZV9pdCwNCiAgdmNvdiA9IGxpc3QofmNvdW50cnksIH5jb3VudHJ5ICsgeWVhciwgIkhDMSIpLA0KICBoZWFkZXJzID0gYygiY2x1c3RlciBwYXlzIiwgImNsdXN0ZXIgcGF5cythbm7DqWUiLCAiSEMxIikNCikNCg0KYGBgDQpJY2kgb24gdm9pdCBxdWUgbGEgc2V1bGUgZGlmZsOpcmVuY2UgZW50cmUgbGVzIGRldXggbW9kw6hsZXMgZXN0IGwnw6ljYXJ0LXR5cGUgYXNzb2Npw6kgYXUgY29lZmZpY2llbnQgZGUgbCdpbmZsYXRpb24uIA0KDQoNCg0KIyBNb2TDqGxlcyBkZSBwYW5lbCBkeW5hbWlxdWUgZXQgR01NIA0KRGFucyBjZXJ0YWlucyBjYXMsIG9uIHBldXQgc291aGFpdGVyIGVzdGltZXIgZGVzIG1vZMOobGVzIHF1aSBwcmVubmVudCBlbiBjb21wdGUgbGEgZHluYW1pcXVlIGQndW5lIHPDqXJpZS4gUGFyIGV4ZW1wbGUsIHNpIGxhIHZhcmlhYmxlICRZX3tpLHR9JCBlc3QgaW1wYWN0w6llIHBhciBzZXMgdmFsZXVycyBwYXNzw6llcywgb24gcGV1dCB2b3Vsb2lyIGVzdGltZXIgbGUgbW9kw6hsZSBzdWl2YW50IDoNCg0KJCQNCllfe2ksdH0gPSBcYWxwaGFfaSArIFxhbHBoYV90ICsgXGJldGFfMSBZX3tpLHQtMX0gKyBcYmV0YV8yIFhfe2ksdH0gKyBcdmFyZXBzaWxvbl97aSx0fQ0KJCQNCkljaSwgJFxiZXRhXzEkIHZhIG1lc3VyZXIgbCdpbXBhY3QgZHUgbGFnIGRlIGxhIHZhcmlhYmxlIGVuZG9nw6huZSBzdXIgbGEgdmFyaWFibGUgZW5kb2fDqG5lIGVsbGUtbcOqbWUsIGFmaW4gZGUgcHJlbmRyZSBlbiBjb21wdGUgbCdhdXRvY29ycsOpbGF0aW9uIGRlIGxhIHPDqXJpZS4gDQoNCkNlcGVuZGFudCwgbGVzIG1vZMOobGVzIGR5bmFtaXF1ZSBuZSByZXNwZWN0ZW50IHBhcyBsYSBjb25kaXRpb24gZGUgc3RyaWN0ZSBleG9nw6luw6lpdMOpIGRlcyB2YXJpYWJsZXMgZXhwbGljYXRpdmVzLCBjZSBxdWkgcG9zZSBwcm9ibMOobWUgc3VyIGwnZXN0aW1hdGlvbiDDqWNvbm9tw6l0cmlxdWUuIENlcyBwcm9ibMOobWVzIHNvbnQgZW4gZ8OpbsOpcmFsIGfDqXLDqXMgcGFyIGxlcyBtb2TDqGxlcyBHTU0uDQoNCkwnaWTDqWUgZGVzIEdNTSAoQXJlbGxhbm8tQm9uZCkgZXN0IGRlIHRyYW5zZm9ybWVyIGwnw6lxdWF0aW9uIGVuIGRpZmbDqXJlbmNlcyBwcmVtacOocmVzLCBkJ3V0aWxpc2VyIGxlcyBsYWdzIGRlICRZX3QkIGNvbW1lIGRlcyBpbnN0cnVtZW50cyBhZmluIGRlIHJldHJvdXZlciBsYSBjYXVzYWxpdMOpIGVudHJlICRYX3QkIGV0ICRZX3QkLiANCg0KDQoNCg0KDQoNCg==