Structural Equation Modeling (SEM)

Structural Equation Modeling (SEM) is a comprehensive and flexible approach that consists of studying, in a hypothetical model, the relationships between variables, whether they are measured or latent, meaning not directly observable, like any psychological construct (for example, intelligence, satisfaction, hope, trust). Comprehensive, because it is a multivariate analysis method that combines the inputs from factor analysis and that of methods based or derived from multiple regression analysis methods and canonical analysis. Flexible, because it is a technique that allows not only to identify the direct and indirect effects between variables, but also to estimate the parameters of varied and complex models including latent variable means.

The history of SEM approach traces back to three different traditions: (1) path analysis, originally developed by the geneticist Sewall Wright (Wright 1921), later picked up in sociology (Duncan 1966), (2) simultaneous-equation models, as developed in economics (Koopmans 1945), and (3) factor analysis from psychology (Anderson and Rubin 1956).

Applications

Basically, SEM is a statistical methodology that takes a confrmatory (i.e., hypothesis-testing) approach to the analysis of a structural theory bearing on some phenomenon. Typically, this theory represents “causal” processes that generate observations on multiple variables. The term “structural equation modeling” conveys two important aspects of the procedure: (1) that the causal processes under study are represented by a series of structural (i.e., regression) equations, and (2) that these structural relations can be modeled pictorially to enable a clearer conceptualization of the theory under study. The hypothesized model can then be tested statistically in a simultaneous analysis of the entire system of variables to determine the extent to which it is consistent with the data. If goodness-of-ft is adequate, the model argues for the plausibility of postulated relations among variables; if it is inadequate, the tenability of such relations is rejected.

Conducting SEM in R

Within the R environment, there are two approaches to estimate structural equation models.

The first approach is to connect R with external commercial SEM programs. This is often useful in simulation studies where fitting a model with SEM software is one part of the simulation pipeline. During one run of the simulation, syntax is written to a file in a format that can be read by the external SEM program (Mplus or EQS); the model is fitted by the external SEM program and the resulting output is written to a file that needs to be parsed manually to extract the relevant information for the study at hand. Depending on the SEM program, the connection protocols can be tedious to set up. Fortunately, two R packages have been developed to ease this process: MplusAutomation (Hallquist 2012) and REQS (Mair, Wu, and Bentler 2010), to communicate with the Mplus and EQS program respectively.

The second approach is to use a dedicated R package for structural equation modeling. Before the appearance of the lavaan, there are two alternative packages available. The sem package, developed by John Fox, has been around since 2001 (Fox, Nie, and Byrnes 2012; Fox 2006) and for a long time, it was the only package for SEM in the R environment. The second package is OpenMx (Boker, Neale, Maes, Wilde, Spiegel, Brick, Spies, Estabrook, Kenny, Bates, Mehta, and Fox 2011). As the name of the package suggests, OpenMx is a complete rewrite of the Mx program, consisting of three parts: a front end in R, a back end written in C, and a third-party commercial optimizer (NPSOL). All parts of OpenMx are open-source, except of course the NPSOL optimizer, which is closed-source.

Why lavaan?

As described above, many SEM software packages are available, both free and commercial, including a couple of packages that run in the R environment. Why then is there a need for yet another SEM package? The answers to this question are threefold:

  • lavaan aims to appeal to a large group of applied researchers that needs SEM software to answer their substantive questions. Many applied researchers have not previously used R and are accustomed to commercial SEM programs. Applied researchers often value software that is intuitive and rich with modeling features, and lavaan tries to fulfill both of these objectives.

  • lavaan aims to appeal to those who teach SEM classes or SEM workshops; ideally, teachers should have access to an easy-to-use, but complete, SEM program that is inexpensive to install in a computer classroom.

  • lavaan aims to appeal to statisticians working in the field of SEM. To implement a new methodological idea, it is advantageous to have access to an open-source SEM program that enables direct access to the SEM code.

Using lavaan

In this section I will present R codes for conducting SEM analysis with involvement.sav - the data was used in Marketing Research with SPSS. For more information you can study here.

## lavaan 0.6-3 ended normally after 42 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                         27
## 
##   Number of observations                           256
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                     128.258
##   Degrees of freedom                                51
##   P-value (Chi-square)                           0.000
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   prcon =~                                            
##     prcon2            1.000                           
##     prcon3            1.188    0.076   15.730    0.000
##     prcon4            1.120    0.070   15.945    0.000
##     prcon5            1.166    0.071   16.323    0.000
##   involv =~                                           
##     involv1           1.000                           
##     involv2           1.065    0.046   23.235    0.000
##     involv3           1.001    0.051   19.725    0.000
##   tpress =~                                           
##     tpress1           1.000                           
##     tpress2           1.222    0.124    9.870    0.000
##     tpress3           1.185    0.122    9.753    0.000
##     tpress4           1.437    0.133   10.820    0.000
##     tpress5           1.130    0.112   10.096    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   prcon ~                                             
##     involv            0.184    0.052    3.506    0.000
##   involv ~                                            
##     tpress           -0.319    0.090   -3.559    0.000
##   tpress ~                                            
##     prcon            -0.046    0.073   -0.630    0.529
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .prcon2            1.015    0.092   11.014    0.000
##    .prcon3            0.194    0.022    8.796    0.000
##    .prcon4            0.133    0.017    7.865    0.000
##    .prcon5            0.068    0.014    4.753    0.000
##    .involv1           0.515    0.063    8.156    0.000
##    .involv2           0.185    0.052    3.562    0.000
##    .involv3           0.626    0.071    8.862    0.000
##    .tpress1           1.861    0.178   10.444    0.000
##    .tpress2           1.290    0.137    9.385    0.000
##    .tpress3           1.310    0.137    9.535    0.000
##    .tpress4           0.700    0.109    6.439    0.000
##    .tpress5           0.939    0.104    9.028    0.000
##    .prcon             1.073    0.160    6.724    0.000
##    .involv            1.751    0.198    8.829    0.000
##    .tpress            1.183    0.223    5.299    0.000
## lavaan 0.6-3 ended normally after 42 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                         27
## 
##   Number of observations                           256
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                     128.258
##   Degrees of freedom                                51
##   P-value (Chi-square)                           0.000
## 
## Model test baseline model:
## 
##   Minimum Function Test Statistic             2656.129
##   Degrees of freedom                                66
##   P-value                                        0.000
## 
## User model versus baseline model:
## 
##   Comparative Fit Index (CFI)                    0.970
##   Tucker-Lewis Index (TLI)                       0.961
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -4414.669
##   Loglikelihood unrestricted model (H1)             NA
## 
##   Number of free parameters                         27
##   Akaike (AIC)                                8883.338
##   Bayesian (BIC)                              8979.058
##   Sample-size adjusted Bayesian (BIC)         8893.461
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.077
##   90 Percent Confidence Interval          0.060  0.094
##   P-value RMSEA <= 0.05                          0.005
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.043
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   prcon =~                                            
##     prcon2            1.000                           
##     prcon3            1.188    0.076   15.730    0.000
##     prcon4            1.120    0.070   15.945    0.000
##     prcon5            1.166    0.071   16.323    0.000
##   involv =~                                           
##     involv1           1.000                           
##     involv2           1.065    0.046   23.235    0.000
##     involv3           1.001    0.051   19.725    0.000
##   tpress =~                                           
##     tpress1           1.000                           
##     tpress2           1.222    0.124    9.870    0.000
##     tpress3           1.185    0.122    9.753    0.000
##     tpress4           1.437    0.133   10.820    0.000
##     tpress5           1.130    0.112   10.096    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   prcon ~                                             
##     involv            0.184    0.052    3.506    0.000
##   involv ~                                            
##     tpress           -0.319    0.090   -3.559    0.000
##   tpress ~                                            
##     prcon            -0.046    0.073   -0.630    0.529
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .prcon2            1.015    0.092   11.014    0.000
##    .prcon3            0.194    0.022    8.796    0.000
##    .prcon4            0.133    0.017    7.865    0.000
##    .prcon5            0.068    0.014    4.753    0.000
##    .involv1           0.515    0.063    8.156    0.000
##    .involv2           0.185    0.052    3.562    0.000
##    .involv3           0.626    0.071    8.862    0.000
##    .tpress1           1.861    0.178   10.444    0.000
##    .tpress2           1.290    0.137    9.385    0.000
##    .tpress3           1.310    0.137    9.535    0.000
##    .tpress4           0.700    0.109    6.439    0.000
##    .tpress5           0.939    0.104    9.028    0.000
##    .prcon             1.073    0.160    6.724    0.000
##    .involv            1.751    0.198    8.829    0.000
##    .tpress            1.183    0.223    5.299    0.000

##   cfi rmsea 
## 0.970 0.077
## lavaan 0.6-3 ended normally after 42 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                         27
## 
##   Number of observations                           256
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                     128.258
##   Degrees of freedom                                51
##   P-value (Chi-square)                           0.000
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   prcon =~                                            
##     prcon2            1.000                           
##     prcon3            1.188    0.076   15.730    0.000
##     prcon4            1.120    0.070   15.945    0.000
##     prcon5            1.166    0.071   16.323    0.000
##   involv =~                                           
##     involv1           1.000                           
##     involv2           1.065    0.046   23.235    0.000
##     involv3           1.001    0.051   19.725    0.000
##   tpress =~                                           
##     tpress1           1.000                           
##     tpress2           1.222    0.124    9.870    0.000
##     tpress3           1.185    0.122    9.753    0.000
##     tpress4           1.437    0.133   10.820    0.000
##     tpress5           1.130    0.112   10.096    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   prcon ~                                             
##     involv            0.184    0.052    3.506    0.000
##   involv ~                                            
##     tpress           -0.319    0.090   -3.559    0.000
##   tpress ~                                            
##     prcon            -0.046    0.073   -0.630    0.529
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .prcon2            1.015    0.092   11.014    0.000
##    .prcon3            0.194    0.022    8.796    0.000
##    .prcon4            0.133    0.017    7.865    0.000
##    .prcon5            0.068    0.014    4.753    0.000
##    .involv1           0.515    0.063    8.156    0.000
##    .involv2           0.185    0.052    3.562    0.000
##    .involv3           0.626    0.071    8.862    0.000
##    .tpress1           1.861    0.178   10.444    0.000
##    .tpress2           1.290    0.137    9.385    0.000
##    .tpress3           1.310    0.137    9.535    0.000
##    .tpress4           0.700    0.109    6.439    0.000
##    .tpress5           0.939    0.104    9.028    0.000
##    .prcon             1.073    0.160    6.724    0.000
##    .involv            1.751    0.198    8.829    0.000
##    .tpress            1.183    0.223    5.299    0.000
##        lhs op     rhs est.std    se       z pvalue ci.lower ci.upper
## 1    prcon =~  prcon2   0.728 0.030  24.131  0.000    0.669    0.787
## 2    prcon =~  prcon3   0.945 0.008 120.599  0.000    0.930    0.960
## 3    prcon =~  prcon4   0.957 0.007 143.487  0.000    0.944    0.970
## 4    prcon =~  prcon5   0.979 0.005 202.362  0.000    0.969    0.988
## 5   involv =~ involv1   0.886 0.017  52.366  0.000    0.853    0.919
## 6   involv =~ involv2   0.959 0.012  78.955  0.000    0.935    0.983
## 7   involv =~ involv3   0.866 0.019  46.627  0.000    0.830    0.903
## 8   tpress =~ tpress1   0.625 0.042  14.832  0.000    0.542    0.707
## 9   tpress =~ tpress2   0.762 0.031  24.596  0.000    0.701    0.822
## 10  tpress =~ tpress3   0.749 0.032  23.386  0.000    0.686    0.812
## 11  tpress =~ tpress4   0.882 0.021  41.656  0.000    0.841    0.924
## 12  tpress =~ tpress5   0.786 0.029  27.265  0.000    0.730    0.843
## 13   prcon  ~  involv   0.236 0.064   3.702  0.000    0.111    0.361
## 14  involv  ~  tpress  -0.254 0.066  -3.861  0.000   -0.383   -0.125
## 15  tpress  ~   prcon  -0.045 0.071  -0.632  0.528   -0.184    0.095
## 16  prcon2 ~~  prcon2   0.470 0.044  10.718  0.000    0.384    0.556
## 17  prcon3 ~~  prcon3   0.107 0.015   7.243  0.000    0.078    0.136
## 18  prcon4 ~~  prcon4   0.085 0.013   6.644  0.000    0.060    0.110
## 19  prcon5 ~~  prcon5   0.042 0.009   4.410  0.000    0.023    0.060
## 20 involv1 ~~ involv1   0.215 0.030   7.164  0.000    0.156    0.274
## 21 involv2 ~~ involv2   0.080 0.023   3.423  0.001    0.034    0.125
## 22 involv3 ~~ involv3   0.249 0.032   7.750  0.000    0.186    0.313
## 23 tpress1 ~~ tpress1   0.610 0.053  11.582  0.000    0.506    0.713
## 24 tpress2 ~~ tpress2   0.420 0.047   8.907  0.000    0.328    0.512
## 25 tpress3 ~~ tpress3   0.439 0.048   9.146  0.000    0.345    0.533
## 26 tpress4 ~~ tpress4   0.222 0.037   5.926  0.000    0.148    0.295
## 27 tpress5 ~~ tpress5   0.382 0.045   8.416  0.000    0.293    0.471
## 28   prcon ~~   prcon   0.939 0.030  31.107  0.000    0.880    0.998
## 29  involv ~~  involv   0.930 0.034  27.727  0.000    0.865    0.996
## 30  tpress ~~  tpress   0.993 0.014  69.616  0.000    0.965    1.021
## lavaan 0.6-3 ended normally after 42 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                         27
## 
##   Number of observations                           256
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                     128.258
##   Degrees of freedom                                51
##   P-value (Chi-square)                           0.000
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   prcon =~                                            
##     prcon2            1.000                           
##     prcon3            1.188    0.076   15.730    0.000
##     prcon4            1.120    0.070   15.945    0.000
##     prcon5            1.166    0.071   16.323    0.000
##   involv =~                                           
##     involv1           1.000                           
##     involv2           1.065    0.046   23.235    0.000
##     involv3           1.001    0.051   19.725    0.000
##   tpress =~                                           
##     tpress1           1.000                           
##     tpress2           1.222    0.124    9.870    0.000
##     tpress3           1.185    0.122    9.753    0.000
##     tpress4           1.437    0.133   10.820    0.000
##     tpress5           1.130    0.112   10.096    0.000
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   prcon ~                                             
##     involv            0.184    0.052    3.506    0.000
##   involv ~                                            
##     tpress           -0.319    0.090   -3.559    0.000
##   tpress ~                                            
##     prcon            -0.046    0.073   -0.630    0.529
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .prcon2            1.015    0.092   11.014    0.000
##    .prcon3            0.194    0.022    8.796    0.000
##    .prcon4            0.133    0.017    7.865    0.000
##    .prcon5            0.068    0.014    4.753    0.000
##    .involv1           0.515    0.063    8.156    0.000
##    .involv2           0.185    0.052    3.562    0.000
##    .involv3           0.626    0.071    8.862    0.000
##    .tpress1           1.861    0.178   10.444    0.000
##    .tpress2           1.290    0.137    9.385    0.000
##    .tpress3           1.310    0.137    9.535    0.000
##    .tpress4           0.700    0.109    6.439    0.000
##    .tpress5           0.939    0.104    9.028    0.000
##    .prcon             1.073    0.160    6.724    0.000
##    .involv            1.751    0.198    8.829    0.000
##    .tpress            1.183    0.223    5.299    0.000

References

  1. Anderson TW, Rubin H (1956). Statistical Inference in Factor Analysis." In Proceedings of the Third Berkeley Symposium on Mathematical Statistics and Probability, pp. 111-150. University of California Press, Berkeley.

  2. Byrne, B. M. (2016). Structural equation modeling with AMOS: Basic concepts, applications, and programming. Routledge.

  3. Bollen, K. A. (1989). Structural Equations with Latent Variables. Wiley Series in Probability and Mathematical Statistics. New York: Wiley.

  4. Chapman, C., & Feit, E. M. (2015). R for marketing research and analytics. New York, NY: Springer.

  5. Boker S, Neale M, Maes HH, Wilde M, Spiegel M, Brick T, Spies J, Estabrook R, Kenny S, Bates T, Mehta P, Fox J (2011). OpenMx: An Open Source Extended Structural Equation Modeling Framework." Psychometrika, 76, 306-317.

  6. Duncan OD (1966). Path Analysis: Sociological Examples." American Journal of Sociology, 72-1.

  7. Fox J, Nie Z, Byrnes J (2012). sem: Structural Equation Models. R package version 3.0-0, URL http://CRAN.R-project.org/package=sem.

  8. Hallquist M (2012). MplusAutomation: Automating Mplus Model Estimation and Interpretation. R package version 0.5-1, URL http://CRAN.R-project.org/package=MplusAutomation.

  9. Howitt, D., & Cramer, D. (2017). Understanding statistics in psychology with SPSS. Pearson Higher Education.

  10. Koopmans T (1945). Statistical Estimation of Simultaneous Economic Relations." Journal of the American Statistical Association, 40, 448-466.

  11. Kline, R. B. (2015). Principles and practice of structural equation modeling. Guilford publications.

  12. Mair P, Wu E, Bentler PM (2010). EQS Goes R: Embedding EQS into the R Environment Using the Package REQS." Structural Equation Modeling: A Multidisciplinary Journal, 17, 333{349.

  13. Wright S (1921). “Correlation and Causation”. Journal of Agricultural Research, 20, 557

LS0tDQp0aXRsZTogIlIgZm9yIFBzeWNob2xvZ2lzdHMgYW5kIE1hcmtldGluZyBSZXNlYXJjaDogU3RydWN0dXJhbCBFcXVhdGlvbiBNb2RlbGluZyAoU0VNKSINCmF1dGhvcjogIk5ndXllbiBDaGkgRHVuZyINCnN1YnRpdGxlOiAiUiBmb3IgUGxlYXN1cmUiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgIyBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBoaWdobGlnaHQ6IHplbmJ1cm4NCiAgICB0aGVtZTogZmxhdGx5DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQotLS0NCg0KYGBge3Igc2V0dXAsaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIGZpZy5yZXRpbmE9MikNCmBgYA0KDQoNCiFbXShDOlxVc2Vyc1xaYm9va1xEZXNrdG9wXHBpY1xzZW0ucG5nKQ0KDQojIFN0cnVjdHVyYWwgRXF1YXRpb24gTW9kZWxpbmcgKFNFTSkgDQoNClN0cnVjdHVyYWwgRXF1YXRpb24gTW9kZWxpbmcgKFNFTSkgaXMgYSBjb21wcmVoZW5zaXZlIGFuZCBmbGV4aWJsZSBhcHByb2FjaCB0aGF0IGNvbnNpc3RzIG9mIHN0dWR5aW5nLCBpbiBhIGh5cG90aGV0aWNhbCBtb2RlbCwgdGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB2YXJpYWJsZXMsIHdoZXRoZXIgdGhleSBhcmUgbWVhc3VyZWQgb3IgbGF0ZW50LCBtZWFuaW5nIG5vdCBkaXJlY3RseSBvYnNlcnZhYmxlLCBsaWtlIGFueSBwc3ljaG9sb2dpY2FsIGNvbnN0cnVjdCAoZm9yIGV4YW1wbGUsIGludGVsbGlnZW5jZSwgc2F0aXNmYWN0aW9uLCBob3BlLCB0cnVzdCkuIENvbXByZWhlbnNpdmUsIGJlY2F1c2UgaXQgaXMgYSBtdWx0aXZhcmlhdGUgYW5hbHlzaXMgbWV0aG9kIHRoYXQgY29tYmluZXMgdGhlIGlucHV0cyBmcm9tIGZhY3RvciBhbmFseXNpcyBhbmQgdGhhdCBvZiBtZXRob2RzIGJhc2VkIG9yIGRlcml2ZWQgZnJvbSBtdWx0aXBsZSByZWdyZXNzaW9uIGFuYWx5c2lzIG1ldGhvZHMgYW5kIGNhbm9uaWNhbCBhbmFseXNpcy4gRmxleGlibGUsIGJlY2F1c2UgaXQgaXMgYSB0ZWNobmlxdWUgdGhhdCBhbGxvd3Mgbm90IG9ubHkgdG8gaWRlbnRpZnkgdGhlIGRpcmVjdCBhbmQgaW5kaXJlY3QgZWZmZWN0cyBiZXR3ZWVuIHZhcmlhYmxlcywgYnV0IGFsc28gdG8gZXN0aW1hdGUgdGhlIHBhcmFtZXRlcnMgb2YgdmFyaWVkIGFuZCBjb21wbGV4IG1vZGVscyBpbmNsdWRpbmcgbGF0ZW50IHZhcmlhYmxlIG1lYW5zLg0KDQpUaGUgaGlzdG9yeSBvZiBTRU0gYXBwcm9hY2ggdHJhY2VzIGJhY2sgdG8gdGhyZWUgZGlmZmVyZW50IHRyYWRpdGlvbnM6ICgxKSBwYXRoIGFuYWx5c2lzLCBvcmlnaW5hbGx5IGRldmVsb3BlZCBieSB0aGUgZ2VuZXRpY2lzdCBTZXdhbGwgV3JpZ2h0IChXcmlnaHQgMTkyMSksIGxhdGVyIHBpY2tlZCB1cCBpbiBzb2Npb2xvZ3kgKER1bmNhbiAxOTY2KSwgKDIpIHNpbXVsdGFuZW91cy1lcXVhdGlvbiBtb2RlbHMsIGFzIGRldmVsb3BlZCBpbiBlY29ub21pY3MgKEtvb3BtYW5zIDE5NDUpLCBhbmQgKDMpIGZhY3RvciBhbmFseXNpcyBmcm9tIHBzeWNob2xvZ3kgKEFuZGVyc29uIGFuZCBSdWJpbiAxOTU2KS4NCg0KIyBBcHBsaWNhdGlvbnMNCg0KQmFzaWNhbGx5LCBTRU0gaXMgYSBzdGF0aXN0aWNhbCBtZXRob2RvbG9neSB0aGF0IHRha2VzIGEgY29uZnJtYXRvcnkgKGkuZS4sIGh5cG90aGVzaXMtdGVzdGluZykgYXBwcm9hY2ggdG8gdGhlIGFuYWx5c2lzIG9mIGEgc3RydWN0dXJhbCB0aGVvcnkgYmVhcmluZyBvbiBzb21lIHBoZW5vbWVub24uIFR5cGljYWxseSwgdGhpcyB0aGVvcnkgcmVwcmVzZW50cyDigJxjYXVzYWzigJ0gcHJvY2Vzc2VzIHRoYXQgZ2VuZXJhdGUgb2JzZXJ2YXRpb25zIG9uIG11bHRpcGxlIHZhcmlhYmxlcy4gVGhlIHRlcm0g4oCcc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbGluZ+KAnSBjb252ZXlzIHR3byBpbXBvcnRhbnQgYXNwZWN0cyBvZiB0aGUgcHJvY2VkdXJlOiAoMSkgdGhhdCB0aGUgY2F1c2FsIHByb2Nlc3NlcyB1bmRlciBzdHVkeSBhcmUgcmVwcmVzZW50ZWQgYnkgYSBzZXJpZXMgb2Ygc3RydWN0dXJhbCAoaS5lLiwgcmVncmVzc2lvbikgZXF1YXRpb25zLCBhbmQgKDIpIHRoYXQgdGhlc2Ugc3RydWN0dXJhbCByZWxhdGlvbnMgY2FuIGJlIG1vZGVsZWQgcGljdG9yaWFsbHkgdG8gZW5hYmxlIGEgY2xlYXJlciBjb25jZXB0dWFsaXphdGlvbiBvZiB0aGUgdGhlb3J5IHVuZGVyIHN0dWR5LiBUaGUgaHlwb3RoZXNpemVkIG1vZGVsIGNhbiB0aGVuIGJlIHRlc3RlZCBzdGF0aXN0aWNhbGx5IGluIGEgc2ltdWx0YW5lb3VzIGFuYWx5c2lzIG9mIHRoZSBlbnRpcmUgc3lzdGVtIG9mIHZhcmlhYmxlcyB0byBkZXRlcm1pbmUgdGhlIGV4dGVudCB0byB3aGljaCBpdCBpcyBjb25zaXN0ZW50IHdpdGggdGhlIGRhdGEuIElmIGdvb2RuZXNzLW9mLWZ0IGlzIGFkZXF1YXRlLCB0aGUgbW9kZWwgYXJndWVzIGZvciB0aGUgcGxhdXNpYmlsaXR5IG9mIHBvc3R1bGF0ZWQgcmVsYXRpb25zIGFtb25nIHZhcmlhYmxlczsgaWYgaXQgaXMgaW5hZGVxdWF0ZSwgdGhlIHRlbmFiaWxpdHkgb2Ygc3VjaCByZWxhdGlvbnMgaXMgcmVqZWN0ZWQuIA0KDQojIENvbmR1Y3RpbmcgU0VNIGluIFIgDQoNCldpdGhpbiB0aGUgUiBlbnZpcm9ubWVudCwgdGhlcmUgYXJlIHR3byBhcHByb2FjaGVzIHRvIGVzdGltYXRlIHN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxzLiANCg0KVGhlIGZpcnN0IGFwcHJvYWNoIGlzIHRvIGNvbm5lY3QgUiB3aXRoIGV4dGVybmFsIGNvbW1lcmNpYWwgU0VNIHByb2dyYW1zLiBUaGlzIGlzIG9mdGVuIHVzZWZ1bCBpbiBzaW11bGF0aW9uIHN0dWRpZXMgd2hlcmUgZml0dGluZyBhIG1vZGVsIHdpdGggU0VNIHNvZnR3YXJlIGlzIG9uZSBwYXJ0IG9mIHRoZSBzaW11bGF0aW9uIHBpcGVsaW5lLiBEdXJpbmcgb25lIHJ1biBvZiB0aGUgc2ltdWxhdGlvbiwgc3ludGF4IGlzIHdyaXR0ZW4gdG8gYSBmaWxlIGluIGEgZm9ybWF0IHRoYXQgY2FuIGJlIHJlYWQgYnkgdGhlIGV4dGVybmFsIFNFTSBwcm9ncmFtICgqKk1wbHVzKiogb3IgKipFUVMqKik7IHRoZSBtb2RlbCBpcyBmaXR0ZWQgYnkgdGhlIGV4dGVybmFsIFNFTSBwcm9ncmFtIGFuZCB0aGUgcmVzdWx0aW5nIG91dHB1dCBpcyB3cml0dGVuIHRvIGEgZmlsZSB0aGF0IG5lZWRzIHRvIGJlIHBhcnNlZCBtYW51YWxseSB0byBleHRyYWN0IHRoZSByZWxldmFudCBpbmZvcm1hdGlvbiBmb3IgdGhlIHN0dWR5IGF0IGhhbmQuIERlcGVuZGluZyBvbiB0aGUgU0VNIHByb2dyYW0sIHRoZSBjb25uZWN0aW9uIHByb3RvY29scyBjYW4gYmUgdGVkaW91cyB0byBzZXQgdXAuIEZvcnR1bmF0ZWx5LCB0d28gUiBwYWNrYWdlcyBoYXZlIGJlZW4gZGV2ZWxvcGVkIHRvIGVhc2UgdGhpcyBwcm9jZXNzOiAqKk1wbHVzQXV0b21hdGlvbioqIChIYWxscXVpc3QgMjAxMikgYW5kICoqUkVRUyoqIChNYWlyLCBXdSwgYW5kIEJlbnRsZXIgMjAxMCksIHRvIGNvbW11bmljYXRlIHdpdGggdGhlIE1wbHVzIGFuZCBFUVMgcHJvZ3JhbSByZXNwZWN0aXZlbHkuIA0KDQoNClRoZSBzZWNvbmQgYXBwcm9hY2ggaXMgdG8gdXNlIGEgZGVkaWNhdGVkIFIgcGFja2FnZSBmb3Igc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbGluZy4gQmVmb3JlIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSAqKmxhdmFhbioqLCB0aGVyZSBhcmUgdHdvIGFsdGVybmF0aXZlIHBhY2thZ2VzIGF2YWlsYWJsZS4gVGhlICoqc2VtKiogcGFja2FnZSwgZGV2ZWxvcGVkIGJ5IEpvaG4gRm94LCBoYXMgYmVlbiBhcm91bmQgc2luY2UgMjAwMSAoRm94LCBOaWUsIGFuZCBCeXJuZXMgMjAxMjsgRm94IDIwMDYpIGFuZCBmb3IgYSBsb25nIHRpbWUsIGl0IHdhcyB0aGUgb25seSBwYWNrYWdlIGZvciBTRU0gaW4gdGhlIFIgZW52aXJvbm1lbnQuIFRoZSBzZWNvbmQgcGFja2FnZSBpcyAqKk9wZW5NeCoqIChCb2tlciwgTmVhbGUsIE1hZXMsIFdpbGRlLCBTcGllZ2VsLCBCcmljaywgU3BpZXMsIEVzdGFicm9vaywgS2VubnksIEJhdGVzLCBNZWh0YSwgYW5kIEZveCAyMDExKS4gQXMgdGhlIG5hbWUgb2YgdGhlIHBhY2thZ2Ugc3VnZ2VzdHMsIE9wZW5NeCBpcyBhIGNvbXBsZXRlIHJld3JpdGUgb2YgdGhlIE14IHByb2dyYW0sIGNvbnNpc3Rpbmcgb2YgdGhyZWUgcGFydHM6IGEgZnJvbnQgZW5kIGluIFIsIGEgYmFjayBlbmQgd3JpdHRlbiBpbiBDLCBhbmQgYSB0aGlyZC1wYXJ0eSBjb21tZXJjaWFsIG9wdGltaXplciAoTlBTT0wpLiBBbGwgcGFydHMgb2YgT3Blbk14IGFyZSBvcGVuLXNvdXJjZSwgZXhjZXB0IG9mIGNvdXJzZSB0aGUgTlBTT0wgb3B0aW1pemVyLCB3aGljaCBpcyBjbG9zZWQtc291cmNlLg0KDQojIFdoeSBsYXZhYW4/DQoNCkFzIGRlc2NyaWJlZCBhYm92ZSwgbWFueSBTRU0gc29mdHdhcmUgcGFja2FnZXMgYXJlIGF2YWlsYWJsZSwgYm90aCBmcmVlIGFuZCBjb21tZXJjaWFsLCBpbmNsdWRpbmcgYSBjb3VwbGUgb2YgcGFja2FnZXMgdGhhdCBydW4gaW4gdGhlIFIgZW52aXJvbm1lbnQuIFdoeSB0aGVuIGlzIHRoZXJlIGEgbmVlZCBmb3IgeWV0IGFub3RoZXIgU0VNIHBhY2thZ2U/IFRoZSBhbnN3ZXJzIHRvIHRoaXMgcXVlc3Rpb24gYXJlIHRocmVlZm9sZDogDQoNCi0gbGF2YWFuIGFpbXMgdG8gYXBwZWFsIHRvIGEgbGFyZ2UgZ3JvdXAgb2YgYXBwbGllZCByZXNlYXJjaGVycyB0aGF0IG5lZWRzIFNFTSBzb2Z0d2FyZSB0byBhbnN3ZXIgdGhlaXIgc3Vic3RhbnRpdmUgcXVlc3Rpb25zLiBNYW55IGFwcGxpZWQgcmVzZWFyY2hlcnMgaGF2ZSBub3QgcHJldmlvdXNseSB1c2VkIFIgYW5kIGFyZSBhY2N1c3RvbWVkIHRvIGNvbW1lcmNpYWwgU0VNIHByb2dyYW1zLiBBcHBsaWVkIHJlc2VhcmNoZXJzIG9mdGVuIHZhbHVlIHNvZnR3YXJlIHRoYXQgaXMgaW50dWl0aXZlIGFuZCByaWNoIHdpdGggbW9kZWxpbmcgZmVhdHVyZXMsIGFuZCBsYXZhYW4gdHJpZXMgdG8gZnVsZmlsbCBib3RoIG9mIHRoZXNlIG9iamVjdGl2ZXMuIA0KDQotIGxhdmFhbiBhaW1zIHRvIGFwcGVhbCB0byB0aG9zZSB3aG8gdGVhY2ggU0VNIGNsYXNzZXMgb3IgU0VNIHdvcmtzaG9wczsgaWRlYWxseSwgdGVhY2hlcnMgc2hvdWxkIGhhdmUgYWNjZXNzIHRvIGFuIGVhc3ktdG8tdXNlLCBidXQgY29tcGxldGUsIFNFTSBwcm9ncmFtIHRoYXQgaXMgaW5leHBlbnNpdmUgdG8gaW5zdGFsbCBpbiBhIGNvbXB1dGVyIGNsYXNzcm9vbS4gDQoNCi0gbGF2YWFuIGFpbXMgdG8gYXBwZWFsIHRvIHN0YXRpc3RpY2lhbnMgd29ya2luZyBpbiB0aGUgZmllbGQgb2YgU0VNLiBUbyBpbXBsZW1lbnQgYSBuZXcgbWV0aG9kb2xvZ2ljYWwgaWRlYSwgaXQgaXMgYWR2YW50YWdlb3VzIHRvIGhhdmUgYWNjZXNzIHRvIGFuIG9wZW4tc291cmNlIFNFTSBwcm9ncmFtIHRoYXQgZW5hYmxlcyBkaXJlY3QgYWNjZXNzIHRvIHRoZSBTRU0gY29kZS4NCg0KIyBVc2luZyBsYXZhYW4gDQoNCkluIHRoaXMgc2VjdGlvbiBJIHdpbGwgcHJlc2VudCBSIGNvZGVzIGZvciBjb25kdWN0aW5nIFNFTSBhbmFseXNpcyB3aXRoICoqaW52b2x2ZW1lbnQuc2F2KiogLSB0aGUgZGF0YSB3YXMgdXNlZCBpbiBbTWFya2V0aW5nIFJlc2VhcmNoIHdpdGggU1BTUyBdKGh0dHBzOi8vd3d3LmFtYXpvbi5jb20vTWFya2V0aW5nLVJlc2VhcmNoLVNQU1MtUGF0cmljay1QZWxzbWFja2VyL2RwLzAyNzM3MDM4MzgpLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiB5b3UgY2FuIHN0dWR5IFtoZXJlXShodHRwczovL3BzdS1wc3ljaG9sb2d5LmdpdGh1Yi5pby9yLWJvb3RjYW1wLTIwMTgvdGFsa3MvbGF2YWFuX3R1dG9yaWFsLmh0bWwpLiANCg0KDQoNCmBgYHtyfQ0KIyBMb2FkIHNvbWUgUiBwYWNrYWdlcyBhbmQgaW1wb3J0IGRhdGE6IA0Kcm0obGlzdCA9IGxzKCkpDQpsaWJyYXJ5KGhhdmVuKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQoNCmRmX2ludm9sIDwtIHJlYWRfc2F2KCJDOlxcVXNlcnNcXFpib29rXFxEZXNrdG9wXFxhbW9zXFwwMjczNzAzODQ2X2RhdGFzZXRzXFxjaDA4XFxpbnZvbHZlbWVudC5zYXYiKQ0KDQoNCiMgSWRlbnRpZnkgb3VyIFNFTSBNb2RlbDogDQpteV9TRU0gPC0gInByY29uID1+IHByY29uMiArIHByY29uMyArIHByY29uNCArIHByY29uNQ0KICAgICAgICAgICBpbnZvbHYgPX4gaW52b2x2MSArIGludm9sdjIgKyBpbnZvbHYzDQogICAgICAgICAgIHRwcmVzcyA9fiB0cHJlc3MxICsgdHByZXNzMiArIHRwcmVzczMgKyB0cHJlc3M0ICsgdHByZXNzNQ0KICAgICAgICAgICBwcmNvbiB+IGludm9sdg0KICAgICAgICAgICBpbnZvbHYgfiB0cHJlc3MNCiAgICAgICAgICAgdHByZXNzIH4gcHJjb24iDQoNCiMgQ29uZHVjdCBTRU0gYW5hbHlzaXM6IA0KbGlicmFyeShsYXZhYW4pDQpTRU1fbW9kZWwgPC0gc2VtKG15X1NFTSwgZGF0YSA9IGRmX2ludm9sKQ0KDQojIFNob3cgcmVzdWx0czogDQpzdW1tYXJ5KFNFTV9tb2RlbCkNCg0KIyBZb3UgY2FuIHNob3cgbW9yZSBkZXRhaWxlZCByZXN1bHRzIHdpdGggZml0Lm1lYXN1cmVzID0gVFJVRTogDQpzdW1tYXJ5KFNFTV9tb2RlbCwgZml0Lm1lYXN1cmVzID0gVFJVRSkNCg0KIyBTaG93IFNFTSBQYXRoOiANCmxpYnJhcnkoc2VtUGxvdCkNCnNlbVBhdGhzKFNFTV9tb2RlbCwgd2hhdCA9ICJzdGQiLCBuQ2hhck5vZGVzID0gNiwgc2l6ZU1hbiA9IDgsDQogICAgICAgICBlZGdlLmxhYmVsLmNleCA9IDEuMSwgY3VydmVQaXZvdCA9IFRSVUUsIGZhZGUgPSBGQUxTRSkNCg0KIyBXZSBjYW4gc2hvdyBzb21lIGNyaXRlcmlhIHRoYXQgZXZhbHVhdGUgbW9kZWwgZml0dGluZzogDQpmaXRNZWFzdXJlcyhTRU1fbW9kZWwsIGZpdC5tZWFzdXJlcyA9IGMoImNmaSIsICJybXNlYSIpKQ0KDQojIFdlIGNhbiB1c2UgY2ZhKCkgZnVuY3Rpb24gZm9yIGNvbmR1Y3RpbmcgU0VNIEFuYWx5c2lzOiANCmNmYShteV9TRU0sIGRhdGEgPSBkZl9pbnZvbCkgJT4lIHN1bW1hcnkoKSANCg0KIyBTaG93IHN0YW5kYXJkaXplZCBjb2VmZmljaWVudHM6IA0Kc3RhbmRhcmRpemVkU29sdXRpb24oU0VNX21vZGVsLCB0eXBlID0gInN0ZC5hbGwiKQ0KDQojIE5vdGUgdGhhdCBzZW0oKSBmdW5jdGlvbiBhY2NlcHRzIGZhY3RvciB2YXJpYWJsZXMgYW5kIHJlc3VsdHMgYXJlIGlkZW50aWNhbDogDQpkZl9pbnZvbCAlPiUNCiAgbXV0YXRlX2FsbChhcy5udW1lcmljKSAlPiUgDQogIHNlbShteV9TRU0sIGRhdGEgPSAuKSAlPiUgDQogIHN1bW1hcnkoKQ0KDQpgYGANCg0KDQoNCiMgUmVmZXJlbmNlcw0KDQoxLiBBbmRlcnNvbiBUVywgUnViaW4gSCAoMTk1NikuIFN0YXRpc3RpY2FsIEluZmVyZW5jZSBpbiBGYWN0b3IgQW5hbHlzaXMuIiBJbiBQcm9jZWVkaW5ncyBvZiB0aGUgVGhpcmQgQmVya2VsZXkgU3ltcG9zaXVtIG9uIE1hdGhlbWF0aWNhbCBTdGF0aXN0aWNzIGFuZCBQcm9iYWJpbGl0eSwgcHAuIDExMS0xNTAuIFVuaXZlcnNpdHkgb2YgQ2FsaWZvcm5pYSBQcmVzcywgQmVya2VsZXkuIA0KDQoyLiBCeXJuZSwgQi4gTS4gKDIwMTYpLiBTdHJ1Y3R1cmFsIGVxdWF0aW9uIG1vZGVsaW5nIHdpdGggQU1PUzogQmFzaWMgY29uY2VwdHMsIGFwcGxpY2F0aW9ucywgYW5kIHByb2dyYW1taW5nLiBSb3V0bGVkZ2UuDQoNCjMuIEJvbGxlbiwgSy4gQS4gKDE5ODkpLiBTdHJ1Y3R1cmFsIEVxdWF0aW9ucyB3aXRoIExhdGVudCBWYXJpYWJsZXMuIFdpbGV5IFNlcmllcyBpbiBQcm9iYWJpbGl0eSBhbmQgTWF0aGVtYXRpY2FsIFN0YXRpc3RpY3MuIE5ldyBZb3JrOiBXaWxleS4NCg0KNC4gQ2hhcG1hbiwgQy4sICYgRmVpdCwgRS4gTS4gKDIwMTUpLiBSIGZvciBtYXJrZXRpbmcgcmVzZWFyY2ggYW5kIGFuYWx5dGljcy4gTmV3IFlvcmssIE5ZOiBTcHJpbmdlci4NCg0KNS4gQm9rZXIgUywgTmVhbGUgTSwgTWFlcyBISCwgV2lsZGUgTSwgU3BpZWdlbCBNLCBCcmljayBULCBTcGllcyBKLCBFc3RhYnJvb2sgUiwgS2VubnkgUywgQmF0ZXMgVCwgTWVodGEgUCwgRm94IEogKDIwMTEpLiBPcGVuTXg6IEFuIE9wZW4gU291cmNlIEV4dGVuZGVkIFN0cnVjdHVyYWwgRXF1YXRpb24gTW9kZWxpbmcgRnJhbWV3b3JrLiIgUHN5Y2hvbWV0cmlrYSwgNzYsIDMwNi0zMTcuDQoNCjYuIER1bmNhbiBPRCAoMTk2NikuIFBhdGggQW5hbHlzaXM6IFNvY2lvbG9naWNhbCBFeGFtcGxlcy4iIEFtZXJpY2FuIEpvdXJuYWwgb2YgU29jaW9sb2d5LCA3Mi0xLiANCg0KNy4gRm94IEosIE5pZSBaLCBCeXJuZXMgSiAoMjAxMikuIHNlbTogU3RydWN0dXJhbCBFcXVhdGlvbiBNb2RlbHMuIFIgcGFja2FnZSB2ZXJzaW9uIDMuMC0wLCBVUkwgaHR0cDovL0NSQU4uUi1wcm9qZWN0Lm9yZy9wYWNrYWdlPXNlbS4NCg0KOC4gSGFsbHF1aXN0IE0gKDIwMTIpLiBNcGx1c0F1dG9tYXRpb246IEF1dG9tYXRpbmcgTXBsdXMgTW9kZWwgRXN0aW1hdGlvbiBhbmQgSW50ZXJwcmV0YXRpb24uIFIgcGFja2FnZSB2ZXJzaW9uIDAuNS0xLCBVUkwgaHR0cDovL0NSQU4uUi1wcm9qZWN0Lm9yZy9wYWNrYWdlPU1wbHVzQXV0b21hdGlvbi4NCg0KOS4gSG93aXR0LCBELiwgJiBDcmFtZXIsIEQuICgyMDE3KS4gVW5kZXJzdGFuZGluZyBzdGF0aXN0aWNzIGluIHBzeWNob2xvZ3kgd2l0aCBTUFNTLiBQZWFyc29uIEhpZ2hlciBFZHVjYXRpb24uIA0KDQoxMC4gS29vcG1hbnMgVCAoMTk0NSkuIFN0YXRpc3RpY2FsIEVzdGltYXRpb24gb2YgU2ltdWx0YW5lb3VzIEVjb25vbWljIFJlbGF0aW9ucy4iIEpvdXJuYWwgb2YgdGhlIEFtZXJpY2FuIFN0YXRpc3RpY2FsIEFzc29jaWF0aW9uLCA0MCwgNDQ4LTQ2Ni4NCg0KMTEuIEtsaW5lLCBSLiBCLiAoMjAxNSkuIFByaW5jaXBsZXMgYW5kIHByYWN0aWNlIG9mIHN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmcuIEd1aWxmb3JkIHB1YmxpY2F0aW9ucy4NCg0KMTIuIE1haXIgUCwgV3UgRSwgQmVudGxlciBQTSAoMjAxMCkuIEVRUyBHb2VzIFI6IEVtYmVkZGluZyBFUVMgaW50byB0aGUgUiBFbnZpcm9ubWVudCBVc2luZyB0aGUgUGFja2FnZSBSRVFTLiIgU3RydWN0dXJhbCBFcXVhdGlvbiBNb2RlbGluZzogQSBNdWx0aWRpc2NpcGxpbmFyeSBKb3VybmFsLCAxNywgMzMzezM0OS4NCg0KMTMuIFdyaWdodCBTICgxOTIxKS4gIkNvcnJlbGF0aW9uIGFuZCBDYXVzYXRpb24iLiBKb3VybmFsIG9mIEFncmljdWx0dXJhbCBSZXNlYXJjaCwgMjAsIDU1Nw0KDQoNCg0K