Load a Few Packages:

Input the Food Dataset (from reading):

Parsed with column specification:
cols(
  FOODCONSUMPTION = col_number(),
  FAMILYINCOME = col_number(),
  NUMCHULDREN = col_double(),
  HAVEGARDEN = col_character()
)
Rows: 51
Columns: 4
$ FOODCONSUMPTION <dbl> 780, 1612, 1621, 1820, 2444, 3120, 3952, 4056, 4160, 4160, 4300, 4420, 5200, …
$ FAMILYINCOME    <dbl> 24000, 20000, 37436, 36600, 10164, 2500, 29000, 40000, 30154, 34000, 46868, 1…
$ NUMCHULDREN     <dbl> 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 2, 1, 2, 4, 2, 3, 4, 2, 1,…
$ HAVEGARDEN      <chr> "NO", "NO", "NO", "YES", "YES", "NO", "YES", "NO", "NO", "YES", "NO", "NO", "…

Data Cleaning and Coding:

We use three functions to help us here. The first two are found in the dplyr package and the third comes from base R.

  1. rename is a handy function that will change the name of any variables in your dataset. The formula is newname = oldname. So, in this case, we are renaming our variables to get rid of capital letters and put spaces in between the words with underscores.

  2. mutate is another SUPER handy function that I use all the time. It allows us to generate a new variable based on a transformation (or mutation, think X-Men!) of an existing one. In this case, I am taking the original (renamed) variable have_garden, and I am creating a new variable called have_garden_fac that is equal to the old variable, but converted to a factor (that is what the as_factor function does). So now, R recognizes the difference between “Yes” and “No” for have_garden_factor as actually being two different levels of a categorical variable that I can use in frequency tables, regression models, etc.

  3. na.omit is another handy function that should come with a warning label! This one should be used very carefully. What this function does is remove any observation (row) in a dataset with missing data. This is similar to listwise deletion if you have talked about that in a previous stats class. We use it here because our original food dataset had an extra row in it that was all missing. In this case, that was just an error - this wasn’t an actual response. But, if you use na.omit on a dataset where you do have missing data, then any observation with any missingness will be removed. The nice part is we can always look back at food now that we have food.clean and see the difference- how many observations were dropped, etc.

Rows: 50
Columns: 5
$ food_consumption <dbl> 780, 1612, 1621, 1820, 2444, 3120, 3952, 4056, 4160, 4160, 4300, 4420, 5200,…
$ family_income    <dbl> 24000, 20000, 37436, 36600, 10164, 2500, 29000, 40000, 30154, 34000, 46868, …
$ num_children     <dbl> 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 2, 1, 2, 4, 2, 3, 4, 2, 1…
$ have_garden      <chr> "NO", "NO", "NO", "YES", "YES", "NO", "YES", "NO", "NO", "YES", "NO", "NO", …
$ have_garden_fac  <fct> NO, NO, NO, YES, YES, NO, YES, NO, NO, YES, NO, NO, YES, YES, YES, YES, NO, …

Use skim from the skimr package to get a nice summary:

── Data Summary ────────────────────────
                           Values    
Name                       food.clean
Number of rows             50        
Number of columns          5         
_______________________              
Column type frequency:               
  character                1         
  factor                   1         
  numeric                  3         
________________________             
Group variables            None      

── Variable type: character ──────────────────────────────────────────────────────────────────────────
  skim_variable n_missing complete_rate   min   max empty n_unique whitespace
1 have_garden           0             1     2     3     0        2          0

── Variable type: factor ─────────────────────────────────────────────────────────────────────────────
  skim_variable   n_missing complete_rate ordered n_unique top_counts     
1 have_garden_fac         0             1 FALSE          2 NO: 36, YES: 14

── Variable type: numeric ────────────────────────────────────────────────────────────────────────────
  skim_variable    n_missing complete_rate     mean       sd    p0   p25   p50     p75   p100 hist 
1 food_consumption         0             1  8795.    4599.     780  5200  8826  11895   20132 ▅▅▇▂▂
2 family_income            0             1 72322.   54170.    1200 31825 52710 105702. 192220 ▇▇▂▂▃
3 num_children             0             1     2.28     1.36     1     1     2      3       6 ▇▁▂▁▁

Start with a Simple Linear Regression: Does Income Predict Food Consumption?


Call:
lm(formula = food_consumption ~ family_income, data = food.clean)

Residuals:
    Min      1Q  Median      3Q     Max 
-4936.0 -2282.4   -48.4  1707.7  7372.6 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)   4.155e+03  7.224e+02   5.752 5.99e-07 ***
family_income 6.416e-02  8.024e-03   7.996 2.24e-10 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3043 on 48 degrees of freedom
Multiple R-squared:  0.5712,    Adjusted R-squared:  0.5622 
F-statistic: 63.93 on 1 and 48 DF,  p-value: 2.236e-10

The short answer to our question - YES! Family income does significantly predict food expenditures. The two are positively related with one another. For each additional dollar in income a family earns, they would be expected to spend an additional .06 (or 6 cents) on food. Relationship is highly significant (p<.001). The Adjusted R Squared for this model is .56, which means that family income by itself explains about 56% of the variation in food expenditures.

What About Kids? Do Things Change When We Account For Them?


Call:
lm(formula = food_consumption ~ family_income + num_children, 
    data = food.clean)

Residuals:
    Min      1Q  Median      3Q     Max 
-4793.2 -1678.5  -128.3  1376.2  7379.1 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)   2.963e+03  8.503e+02   3.485  0.00108 ** 
family_income 5.461e-02  8.631e-03   6.327  8.6e-08 ***
num_children  8.258e+02  3.448e+02   2.395  0.02068 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 2903 on 47 degrees of freedom
Multiple R-squared:  0.6178,    Adjusted R-squared:  0.6015 
F-statistic: 37.98 on 2 and 47 DF,  p-value: 1.528e-10

It looks like kids make a big difference, too! For each additional child (num_children), we would expect a family to spend about $826 more per year on food. Since family_income is in this model, too, we can say that this relationship holds when controlling for family income. Another way to think about this: if you take two families with the same income, the family with 1 more child would be predicted to spend about $827 more on food per year. Notice, too, that the estimate for family_income hasn’t really changed much- it is about .05, down from .06 in our first model. And our new Adjusted R Squared value is .60, up from .56. So, adding number of kids helped us explain about 4% more of the variation in food expenditures.

Now - What About Families Who Have a Garden? Does That Change Things?


Call:
lm(formula = food_consumption ~ family_income + num_children + 
    have_garden_fac, data = food.clean)

Residuals:
    Min      1Q  Median      3Q     Max 
-4618.9 -1616.2  -256.2  1505.4  7246.8 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         3.179e+03  9.613e+02   3.307  0.00183 ** 
family_income       5.414e-02  8.753e-03   6.185 1.53e-07 ***
num_children        8.036e+02  3.505e+02   2.293  0.02648 *  
have_garden_facYES -4.703e+02  9.456e+02  -0.497  0.62135    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 2926 on 46 degrees of freedom
Multiple R-squared:  0.6198,    Adjusted R-squared:  0.595 
F-statistic:    25 on 3 and 46 DF,  p-value: 9.576e-10

What about gardens? Might they change how much a family spends on food? Short answer here - no, not AFTER controlling for family income and number of kids. Sidenote: we could test if gardens are related to food expenditures by themselves just by running a simple linear regression with only have_garden_fac as the predictor. But here, it doesn’t look like owning a garden is significantly related to food expenditures.

Getting Advanced - Does the Number of Children Serve as a Moderator of the Income/Food Relationship?


Call:
lm(formula = food_consumption ~ family_income + num_children + 
    family_income:num_children, data = food.clean)

Residuals:
    Min      1Q  Median      3Q     Max 
-4833.2 -1654.1  -216.8  1476.2  7185.1 

Coefficients:
                             Estimate Std. Error t value Pr(>|t|)    
(Intercept)                 1.424e+03  1.349e+03   1.055   0.2968    
family_income               7.644e-02  1.723e-02   4.436 5.68e-05 ***
num_children                1.512e+03  5.812e+02   2.602   0.0124 *  
family_income:num_children -8.101e-03  5.556e-03  -1.458   0.1516    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 2869 on 46 degrees of freedom
Multiple R-squared:  0.6347,    Adjusted R-squared:  0.6109 
F-statistic: 26.64 on 3 and 46 DF,  p-value: 3.875e-10

OK, now for the fancy stuff- buckle up! The first three models we ran assumed that our predictors were additive, and not interactive. What does this mean? The relationship between num_children and food expenditures is the same, regardless of how much income your family has. And likewise, the relationship between family_income and food is the same, regardless of how many kids you have.

This is fine for a first step, but another hypothesis might be that these two variables INTERACT (or moderate) each other. So, the slope estimate of one is dependent on the value of the other. This is a more complex relationship between predictors. We specify an interaction with the : symbol as shown above. We want to include both main effects (so both variables are still in the equation), as WELL as their interaction family_income:num_children. If the estimate for this interaction term is signficant, then some moderation or interaction is likely happening.

In this case, we sadly don’t have enough evidence to say that interaction exists (p = .15). Power may be an issue as well - we only have 50 observations in our food dataset, and interaction effects are notoriously underpowered (meaning you usually need a much larger sample to find a true significant effect with any regularity).

Using the stargazer Package to Organize Your Results:

Last thing - let’s take our results and make them pretty! The stargazer package is a super simple and cool way to synthesize the results of a series of regression analyses. We named our models along the way (foodreg1, foodreg2, etc.), so using stargazer to collect the results is super easy. One more fun trick - see below where I include the out = "test.html" option. This creates an html table called “test” wherever you specified your working directory. Why is this cool? Microsoft Word can read html tables! So you can take this fancy table, open it up right in Word, and then paste it into your paper. #Boom

length of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changedlength of NULL cannot be changednumber of rows of result is not a multiple of vector length (arg 2)number of rows of result is not a multiple of vector length (arg 2)number of rows of result is not a multiple of vector length (arg 2)

=======================================================================
                                       Dependent variable:             
                           --------------------------------------------
                                         food_consumption              
                               (1)        (2)        (3)        (4)    
-----------------------------------------------------------------------
family_income                0.06***    0.05***    0.05***    0.08***  
                             (0.01)      (0.01)     (0.01)     (0.02)  
                                                                       
num_children                            825.78*    803.61*   1,512.28* 
                                        (344.84)   (350.48)   (581.23) 
                                                                       
have_garden_facYES                                 -470.26             
                                                   (945.63)            
                                                                       
family_income:num_children                                     -0.01   
                                                               (0.01)  
                                                                       
Constant                   4,155.21*** 2,962.95** 3,179.40**  1,423.79 
                            (722.43)    (850.26)   (961.33)  (1,349.23)
                                                                       
-----------------------------------------------------------------------
Observations                   50          50         50         50    
R2                            0.57        0.62       0.62       0.63   
Adjusted R2                   0.56        0.60       0.60       0.61   
=======================================================================
Note:                                     *p<0.05; **p<0.01; ***p<0.001
LS0tCnRpdGxlOiAiTW9kdWxlIDIgSGFuZG91dCAtIFJldmlldyBvZiBMaW5lYXIgUmVncmVzc2lvbiIKYXV0aG9yOiAiRHIuIEIiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIGhpZ2hsaWdodDogdGFuZ28KLS0tCgojIExvYWQgYSBGZXcgUGFja2FnZXM6CmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGJyb29tKQpsaWJyYXJ5KHNraW1yKQpgYGAKCiMgSW5wdXQgdGhlIEZvb2QgRGF0YXNldCAoZnJvbSByZWFkaW5nKToKYGBge3J9CmZvb2QgPC0gcmVhZF9jc3YoImZvb2QuY3N2IikKCnZpZXcoZm9vZCkKZ2xpbXBzZShmb29kKQpgYGAKCiMgRGF0YSBDbGVhbmluZyBhbmQgQ29kaW5nOgpXZSB1c2UgdGhyZWUgZnVuY3Rpb25zIHRvIGhlbHAgdXMgaGVyZS4gVGhlIGZpcnN0IHR3byBhcmUgZm91bmQgaW4gdGhlIGBkcGx5cmAgcGFja2FnZSBhbmQgdGhlIHRoaXJkIGNvbWVzIGZyb20gYGJhc2UgUmAuICAKXG5ld2xpbmUKCjEuIGByZW5hbWVgIGlzIGEgaGFuZHkgZnVuY3Rpb24gdGhhdCB3aWxsIGNoYW5nZSB0aGUgbmFtZSBvZiBhbnkgdmFyaWFibGVzIGluIHlvdXIgZGF0YXNldC4gVGhlIGZvcm11bGEgaXMgYG5ld25hbWUgPSBvbGRuYW1lYC4gU28sIGluIHRoaXMgY2FzZSwgd2UgYXJlIHJlbmFtaW5nIG91ciB2YXJpYWJsZXMgdG8gZ2V0IHJpZCBvZiBjYXBpdGFsIGxldHRlcnMgYW5kIHB1dCBzcGFjZXMgaW4gYmV0d2VlbiB0aGUgd29yZHMgd2l0aCB1bmRlcnNjb3Jlcy4gClxuZXdsaW5lCgoyLiBgbXV0YXRlYCBpcyBhbm90aGVyIFNVUEVSIGhhbmR5IGZ1bmN0aW9uIHRoYXQgSSB1c2UgYWxsIHRoZSB0aW1lLiBJdCBhbGxvd3MgdXMgdG8gZ2VuZXJhdGUgYSBuZXcgdmFyaWFibGUgYmFzZWQgb24gYSB0cmFuc2Zvcm1hdGlvbiAob3IgbXV0YXRpb24sIHRoaW5rIFgtTWVuISkgb2YgYW4gZXhpc3Rpbmcgb25lLiBJbiB0aGlzIGNhc2UsIEkgYW0gdGFraW5nIHRoZSBvcmlnaW5hbCAocmVuYW1lZCkgdmFyaWFibGUgYGhhdmVfZ2FyZGVuYCwgYW5kIEkgYW0gY3JlYXRpbmcgYSBuZXcgdmFyaWFibGUgY2FsbGVkIGBoYXZlX2dhcmRlbl9mYWNgIHRoYXQgaXMgZXF1YWwgdG8gdGhlIG9sZCB2YXJpYWJsZSwgYnV0IGNvbnZlcnRlZCB0byBhIGZhY3RvciAodGhhdCBpcyB3aGF0IHRoZSBgYXNfZmFjdG9yYCBmdW5jdGlvbiBkb2VzKS4gU28gbm93LCBgUmAgcmVjb2duaXplcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuICJZZXMiIGFuZCAiTm8iIGZvciBgaGF2ZV9nYXJkZW5fZmFjdG9yYCBhcyBhY3R1YWxseSBiZWluZyB0d28gZGlmZmVyZW50IGxldmVscyBvZiBhIGNhdGVnb3JpY2FsIHZhcmlhYmxlIHRoYXQgSSBjYW4gdXNlIGluIGZyZXF1ZW5jeSB0YWJsZXMsIHJlZ3Jlc3Npb24gbW9kZWxzLCBldGMuICAKXG5ld2xpbmUKCjMuIGBuYS5vbWl0YCBpcyBhbm90aGVyIGhhbmR5IGZ1bmN0aW9uIHRoYXQgc2hvdWxkIGNvbWUgd2l0aCBhIHdhcm5pbmcgbGFiZWwhICBUaGlzIG9uZSBzaG91bGQgYmUgdXNlZCB2ZXJ5IGNhcmVmdWxseS4gV2hhdCB0aGlzIGZ1bmN0aW9uIGRvZXMgaXMgcmVtb3ZlIGFueSBvYnNlcnZhdGlvbiAocm93KSBpbiBhIGRhdGFzZXQgd2l0aCBtaXNzaW5nIGRhdGEuIFRoaXMgaXMgc2ltaWxhciB0byBsaXN0d2lzZSBkZWxldGlvbiBpZiB5b3UgaGF2ZSB0YWxrZWQgYWJvdXQgdGhhdCBpbiBhIHByZXZpb3VzIHN0YXRzIGNsYXNzLiBXZSB1c2UgaXQgaGVyZSBiZWNhdXNlIG91ciBvcmlnaW5hbCBgZm9vZGAgZGF0YXNldCBoYWQgYW4gZXh0cmEgcm93IGluIGl0IHRoYXQgd2FzIGFsbCBtaXNzaW5nLiBJbiB0aGlzIGNhc2UsIHRoYXQgd2FzIGp1c3QgYW4gZXJyb3IgLSB0aGlzIHdhc24ndCBhbiBhY3R1YWwgcmVzcG9uc2UuIEJ1dCwgaWYgeW91IHVzZSBgbmEub21pdGAgb24gYSBkYXRhc2V0IHdoZXJlIHlvdSBkbyBoYXZlIG1pc3NpbmcgZGF0YSwgdGhlbiBhbnkgb2JzZXJ2YXRpb24gd2l0aCBhbnkgbWlzc2luZ25lc3Mgd2lsbCBiZSByZW1vdmVkLiBUaGUgbmljZSBwYXJ0IGlzIHdlIGNhbiBhbHdheXMgbG9vayBiYWNrIGF0IGBmb29kYCBub3cgdGhhdCB3ZSBoYXZlIGBmb29kLmNsZWFuYCBhbmQgc2VlIHRoZSBkaWZmZXJlbmNlLSBob3cgbWFueSBvYnNlcnZhdGlvbnMgd2VyZSBkcm9wcGVkLCBldGMuIAoKYGBge3J9Cgpmb29kLmNsZWFuIDwtIGZvb2QgJT4lCiAgcmVuYW1lKC4sCiAgICAgICAgIGZvb2RfY29uc3VtcHRpb24gPSBGT09EQ09OU1VNUFRJT04sCiAgICAgICAgIGZhbWlseV9pbmNvbWUgPSBGQU1JTFlJTkNPTUUsCiAgICAgICAgIG51bV9jaGlsZHJlbiA9IE5VTUNIVUxEUkVOLAogICAgICAgICBoYXZlX2dhcmRlbj0gSEFWRUdBUkRFTikgJT4lCiAgbXV0YXRlKC4sCiAgICAgICAgIGhhdmVfZ2FyZGVuX2ZhYyA9IGFzX2ZhY3RvcihoYXZlX2dhcmRlbikpICU+JQogIG5hLm9taXQoKQoKZ2xpbXBzZShmb29kLmNsZWFuKQpgYGAKCiMgVXNlIGBza2ltYCBmcm9tIHRoZSBgc2tpbXJgIHBhY2thZ2UgdG8gZ2V0IGEgbmljZSBzdW1tYXJ5OgpgYGB7cn0Kc2tpbShmb29kLmNsZWFuKQpgYGAKCiMgU3RhcnQgd2l0aCBhIFNpbXBsZSBMaW5lYXIgUmVncmVzc2lvbjogRG9lcyBJbmNvbWUgUHJlZGljdCBGb29kIENvbnN1bXB0aW9uPwpgYGB7cn0KZm9vZHJlZzEgPC0gbG0oZm9vZF9jb25zdW1wdGlvbiB+IGZhbWlseV9pbmNvbWUsIGRhdGEgPSBmb29kLmNsZWFuKQpzdW1tYXJ5KGZvb2RyZWcxKQpgYGAKClxuZXdsaW5lClRoZSBzaG9ydCBhbnN3ZXIgdG8gb3VyIHF1ZXN0aW9uIC0gWUVTISBGYW1pbHkgaW5jb21lIGRvZXMgc2lnbmlmaWNhbnRseSBwcmVkaWN0IGZvb2QgZXhwZW5kaXR1cmVzLiBUaGUgdHdvIGFyZSBwb3NpdGl2ZWx5IHJlbGF0ZWQgd2l0aCBvbmUgYW5vdGhlci4gRm9yIGVhY2ggYWRkaXRpb25hbCBkb2xsYXIgaW4gaW5jb21lIGEgZmFtaWx5IGVhcm5zLCB0aGV5IHdvdWxkIGJlIGV4cGVjdGVkIHRvIHNwZW5kIGFuIGFkZGl0aW9uYWwgLjA2IChvciA2IGNlbnRzKSBvbiBmb29kLiBSZWxhdGlvbnNoaXAgaXMgaGlnaGx5IHNpZ25pZmljYW50IChwPC4wMDEpLiBUaGUgQWRqdXN0ZWQgUiBTcXVhcmVkIGZvciB0aGlzIG1vZGVsIGlzIC41Niwgd2hpY2ggbWVhbnMgdGhhdCBmYW1pbHkgaW5jb21lIGJ5IGl0c2VsZiBleHBsYWlucyBhYm91dCA1NiUgb2YgdGhlIHZhcmlhdGlvbiBpbiBmb29kIGV4cGVuZGl0dXJlcy4KXG5ld2xpbmUKCiMgV2hhdCBBYm91dCBLaWRzPyBEbyBUaGluZ3MgQ2hhbmdlIFdoZW4gV2UgQWNjb3VudCBGb3IgVGhlbT8KYGBge3J9CmZvb2RyZWcyIDwtIGxtKGZvb2RfY29uc3VtcHRpb24gfiBmYW1pbHlfaW5jb21lICsgbnVtX2NoaWxkcmVuLCBkYXRhID0gZm9vZC5jbGVhbikKc3VtbWFyeShmb29kcmVnMikKYGBgCgpcbmV3bGluZQpJdCBsb29rcyBsaWtlIGtpZHMgbWFrZSBhIGJpZyBkaWZmZXJlbmNlLCB0b28hIEZvciBlYWNoIGFkZGl0aW9uYWwgY2hpbGQgKGBudW1fY2hpbGRyZW5gKSwgd2Ugd291bGQgZXhwZWN0IGEgZmFtaWx5IHRvIHNwZW5kIGFib3V0IFwkODI2IG1vcmUgcGVyIHllYXIgb24gZm9vZC4gU2luY2UgYGZhbWlseV9pbmNvbWVgIGlzIGluIHRoaXMgbW9kZWwsIHRvbywgd2UgY2FuIHNheSB0aGF0IHRoaXMgcmVsYXRpb25zaGlwIGhvbGRzIHdoZW4gY29udHJvbGxpbmcgZm9yIGZhbWlseSBpbmNvbWUuIEFub3RoZXIgd2F5IHRvIHRoaW5rIGFib3V0IHRoaXM6IGlmIHlvdSB0YWtlIHR3byBmYW1pbGllcyB3aXRoIHRoZSBzYW1lIGluY29tZSwgdGhlIGZhbWlseSB3aXRoIDEgbW9yZSBjaGlsZCB3b3VsZCBiZSBwcmVkaWN0ZWQgdG8gc3BlbmQgYWJvdXQgXCQ4MjcgbW9yZSBvbiBmb29kIHBlciB5ZWFyLiAKXG5ld2xpbmUKTm90aWNlLCB0b28sIHRoYXQgdGhlIGVzdGltYXRlIGZvciBgZmFtaWx5X2luY29tZWAgaGFzbid0IHJlYWxseSBjaGFuZ2VkIG11Y2gtIGl0IGlzIGFib3V0IC4wNSwgZG93biBmcm9tIC4wNiBpbiBvdXIgZmlyc3QgbW9kZWwuIEFuZCBvdXIgbmV3IEFkanVzdGVkIFIgU3F1YXJlZCB2YWx1ZSBpcyAuNjAsIHVwIGZyb20gLjU2LiBTbywgYWRkaW5nIG51bWJlciBvZiBraWRzIGhlbHBlZCB1cyBleHBsYWluIGFib3V0IDQlIG1vcmUgb2YgdGhlIHZhcmlhdGlvbiBpbiBmb29kIGV4cGVuZGl0dXJlcy4gClxuZXdsaW5lCgojIE5vdyAtIFdoYXQgQWJvdXQgRmFtaWxpZXMgV2hvIEhhdmUgYSBHYXJkZW4/IERvZXMgVGhhdCBDaGFuZ2UgVGhpbmdzPwpgYGB7cn0KZm9vZHJlZzMgPC0gbG0oZm9vZF9jb25zdW1wdGlvbiB+IGZhbWlseV9pbmNvbWUgKyBudW1fY2hpbGRyZW4gKyBoYXZlX2dhcmRlbl9mYWMsIGRhdGEgPSBmb29kLmNsZWFuKQpzdW1tYXJ5KGZvb2RyZWczKQpgYGAKClxuZXdsaW5lCldoYXQgYWJvdXQgZ2FyZGVucz8gTWlnaHQgdGhleSBjaGFuZ2UgaG93IG11Y2ggYSBmYW1pbHkgc3BlbmRzIG9uIGZvb2Q/IFNob3J0IGFuc3dlciBoZXJlIC0gbm8sIG5vdCBBRlRFUiBjb250cm9sbGluZyBmb3IgZmFtaWx5IGluY29tZSBhbmQgbnVtYmVyIG9mIGtpZHMuIFNpZGVub3RlOiB3ZSBjb3VsZCB0ZXN0IGlmIGdhcmRlbnMgYXJlIHJlbGF0ZWQgdG8gZm9vZCBleHBlbmRpdHVyZXMgYnkgdGhlbXNlbHZlcyBqdXN0IGJ5IHJ1bm5pbmcgYSBzaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb24gd2l0aCBvbmx5IGBoYXZlX2dhcmRlbl9mYWNgIGFzIHRoZSBwcmVkaWN0b3IuIEJ1dCBoZXJlLCBpdCBkb2Vzbid0IGxvb2sgbGlrZSBvd25pbmcgYSBnYXJkZW4gaXMgc2lnbmlmaWNhbnRseSByZWxhdGVkIHRvIGZvb2QgZXhwZW5kaXR1cmVzLiAKXG5ld2xpbmUKCiMgR2V0dGluZyBBZHZhbmNlZCAtIERvZXMgdGhlIE51bWJlciBvZiBDaGlsZHJlbiBTZXJ2ZSBhcyBhIE1vZGVyYXRvciBvZiB0aGUgSW5jb21lL0Zvb2QgUmVsYXRpb25zaGlwPwpgYGB7cn0KZm9vZHJlZzQgPC0gbG0oZm9vZF9jb25zdW1wdGlvbiB+IGZhbWlseV9pbmNvbWUgKyBudW1fY2hpbGRyZW4gKyBmYW1pbHlfaW5jb21lOm51bV9jaGlsZHJlbiwgZGF0YSA9IGZvb2QuY2xlYW4pCnN1bW1hcnkoZm9vZHJlZzQpCmBgYAoKXG5ld2xpbmUKT0ssIG5vdyBmb3IgdGhlIGZhbmN5IHN0dWZmLSBidWNrbGUgdXAhIFRoZSBmaXJzdCB0aHJlZSBtb2RlbHMgd2UgcmFuIGFzc3VtZWQgdGhhdCBvdXIgcHJlZGljdG9ycyB3ZXJlIGFkZGl0aXZlLCBhbmQgbm90IGludGVyYWN0aXZlLiBXaGF0IGRvZXMgdGhpcyBtZWFuPyBUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYG51bV9jaGlsZHJlbmAgYW5kIGZvb2QgZXhwZW5kaXR1cmVzIGlzIHRoZSBzYW1lLCByZWdhcmRsZXNzIG9mIGhvdyBtdWNoIGluY29tZSB5b3VyIGZhbWlseSBoYXMuIEFuZCBsaWtld2lzZSwgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGBmYW1pbHlfaW5jb21lYCBhbmQgZm9vZCBpcyB0aGUgc2FtZSwgcmVnYXJkbGVzcyBvZiBob3cgbWFueSBraWRzIHlvdSBoYXZlLiAKClxuZXdsaW5lClRoaXMgaXMgZmluZSBmb3IgYSBmaXJzdCBzdGVwLCBidXQgYW5vdGhlciBoeXBvdGhlc2lzIG1pZ2h0IGJlIHRoYXQgdGhlc2UgdHdvIHZhcmlhYmxlcyBJTlRFUkFDVCAob3IgbW9kZXJhdGUpIGVhY2ggb3RoZXIuIFNvLCB0aGUgc2xvcGUgZXN0aW1hdGUgb2Ygb25lIGlzIGRlcGVuZGVudCBvbiB0aGUgdmFsdWUgb2YgdGhlIG90aGVyLiBUaGlzIGlzIGEgbW9yZSBjb21wbGV4IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHByZWRpY3RvcnMuIFdlIHNwZWNpZnkgYW4gaW50ZXJhY3Rpb24gd2l0aCB0aGUgYDpgIHN5bWJvbCBhcyBzaG93biBhYm92ZS4gV2Ugd2FudCB0byBpbmNsdWRlIGJvdGggbWFpbiBlZmZlY3RzIChzbyBib3RoIHZhcmlhYmxlcyBhcmUgc3RpbGwgaW4gdGhlIGVxdWF0aW9uKSwgYXMgV0VMTCBhcyB0aGVpciBpbnRlcmFjdGlvbiBgZmFtaWx5X2luY29tZTpudW1fY2hpbGRyZW5gLiBJZiB0aGUgZXN0aW1hdGUgZm9yIHRoaXMgaW50ZXJhY3Rpb24gdGVybSBpcyBzaWduZmljYW50LCB0aGVuIHNvbWUgbW9kZXJhdGlvbiBvciBpbnRlcmFjdGlvbiBpcyBsaWtlbHkgaGFwcGVuaW5nLiAKClxuZXdsaW5lCkluIHRoaXMgY2FzZSwgd2Ugc2FkbHkgZG9uJ3QgaGF2ZSBlbm91Z2ggZXZpZGVuY2UgdG8gc2F5IHRoYXQgaW50ZXJhY3Rpb24gZXhpc3RzIChwID0gLjE1KS4gUG93ZXIgbWF5IGJlIGFuIGlzc3VlIGFzIHdlbGwgLSB3ZSBvbmx5IGhhdmUgNTAgb2JzZXJ2YXRpb25zIGluIG91ciBmb29kIGRhdGFzZXQsIGFuZCBpbnRlcmFjdGlvbiBlZmZlY3RzIGFyZSBub3RvcmlvdXNseSB1bmRlcnBvd2VyZWQgKG1lYW5pbmcgeW91IHVzdWFsbHkgbmVlZCBhIG11Y2ggbGFyZ2VyIHNhbXBsZSB0byBmaW5kIGEgdHJ1ZSBzaWduaWZpY2FudCBlZmZlY3Qgd2l0aCBhbnkgcmVndWxhcml0eSkuIAoKXG5ld2xpbmUKCiMgVXNpbmcgdGhlIGBzdGFyZ2F6ZXJgIFBhY2thZ2UgdG8gT3JnYW5pemUgWW91ciBSZXN1bHRzOgpcbmV3bGluZQpMYXN0IHRoaW5nIC0gbGV0J3MgdGFrZSBvdXIgcmVzdWx0cyBhbmQgbWFrZSB0aGVtIHByZXR0eSEgVGhlIGBzdGFyZ2F6ZXJgIHBhY2thZ2UgaXMgYSBzdXBlciBzaW1wbGUgYW5kIGNvb2wgd2F5IHRvIHN5bnRoZXNpemUgdGhlIHJlc3VsdHMgb2YgYSBzZXJpZXMgb2YgcmVncmVzc2lvbiBhbmFseXNlcy4gV2UgbmFtZWQgb3VyIG1vZGVscyBhbG9uZyB0aGUgd2F5IChgZm9vZHJlZzEsIGZvb2RyZWcyYCwgZXRjLiksIHNvIHVzaW5nIGBzdGFyZ2F6ZXJgIHRvIGNvbGxlY3QgdGhlIHJlc3VsdHMgaXMgc3VwZXIgZWFzeS4gClxuZXdsaW5lCk9uZSBtb3JlIGZ1biB0cmljayAtIHNlZSBiZWxvdyB3aGVyZSBJIGluY2x1ZGUgdGhlIGBvdXQgPSAidGVzdC5odG1sImAgb3B0aW9uLiBUaGlzIGNyZWF0ZXMgYW4gaHRtbCB0YWJsZSBjYWxsZWQgInRlc3QiIHdoZXJldmVyIHlvdSBzcGVjaWZpZWQgeW91ciB3b3JraW5nIGRpcmVjdG9yeS4gV2h5IGlzIHRoaXMgY29vbD8gTWljcm9zb2Z0IFdvcmQgY2FuIHJlYWQgaHRtbCB0YWJsZXMhIFNvIHlvdSBjYW4gdGFrZSB0aGlzIGZhbmN5IHRhYmxlLCBvcGVuIGl0IHVwIHJpZ2h0IGluIFdvcmQsIGFuZCB0aGVuIHBhc3RlIGl0IGludG8geW91ciBwYXBlci4gI0Jvb20KXG5ld2xpbmUKCmBgYHtyfQpsaWJyYXJ5KHN0YXJnYXplcikKc3VtbWFyeS50YWJsZSA8LSBzdGFyZ2F6ZXIoZm9vZHJlZzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvb2RyZWcyLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmb29kcmVnMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9vZHJlZzQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSAidGV4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbnQuc2l6ZSA9ICJub3JtYWxzaXplIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlnaXRzID0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcC5zdGF0ID0gYygibiIsICJyc3EiLCAiYWRqLnJzcSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBvdXQgPSAidGVzdC5odG1sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Rhci5jdXRvZmZzID0gYyguMDUsIC4wMSwgLjAwMSkpCmBgYA==