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} \]\(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} \]\[ \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==