From bd6db9979a0820243ba4d522a3182b09f6454fc6 Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Wed, 10 Jun 2020 16:35:37 +0100 Subject: [PATCH] minor edit to source-aggregation --- aj-content/practicals/source-aggregation.Rmd | 2 +- .../practicals/source-aggregation.nb.html | 350 +++++++++++++++--- 2 files changed, 309 insertions(+), 43 deletions(-) diff --git a/aj-content/practicals/source-aggregation.Rmd b/aj-content/practicals/source-aggregation.Rmd index 0586a37..bb166e6 100644 --- a/aj-content/practicals/source-aggregation.Rmd +++ b/aj-content/practicals/source-aggregation.Rmd @@ -163,7 +163,7 @@ Far more honest is to fit the model as before, with the sources as we believe th ```{r a-posteriori} # combine sources C and D which are in positions 3 and 4 -simmr_out_a_posteriori <- simmr::combine_sources( +simmr_out_a_posteriori <- combine_sources( simmr_out, to_combine = simmr_out$input$source_names[c(3,4)], new_source_name = "CD") diff --git a/aj-content/practicals/source-aggregation.nb.html b/aj-content/practicals/source-aggregation.nb.html index b8c6313..870201a 100644 --- a/aj-content/practicals/source-aggregation.nb.html +++ b/aj-content/practicals/source-aggregation.nb.html @@ -1805,6 +1805,9 @@

Create some simulated data for us to work with

plot(simmr_in) + +

+ @@ -1813,27 +1816,186 @@

Fit the SIMM

We can fit a simmr model using the defaults, and here supress the output using the results='hide' option in the chunk.

+ +
simmr_out = simmr_mcmc(simmr_in)
+

And we should always check for convergence.

- +
# a summary table of convergence diagnostics
-summary(simmr_out,type='diagnostics')
-
-# plot the posterior predictive power 
+summary(simmr_out,type='diagnostics')
+ + +

+Summary for 1 
+Gelman diagnostics - these values should all be close to 1.
+If not, try a longer run of simmr_mcmc.
+deviance        A        B        C        D   sd[dC]   sd[dN] 
+       1        1        1        1        1        1        1 
+ + +
# plot the posterior predictive power 
 posterior_predictive(simmr_out)
+ +
Compiling model graph
+   Resolving undeclared variables
+   Allocating nodes
+Graph information:
+   Observed stochastic nodes: 20
+   Unobserved stochastic nodes: 26
+   Total graph size: 141
+
+Initializing model
+
+
+  |                                                        
+  |                                                  |   0%
+  |                                                        
+  |++++++++++                                        |  20%
+  |                                                        
+  |++++++++++++++++++++                              |  40%
+  |                                                        
+  |++++++++++++++++++++++++++++++                    |  60%
+  |                                                        
+  |++++++++++++++++++++++++++++++++++++++++          |  80%
+  |                                                        
+  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100%
+
+  |                                                        
+  |                                                  |   0%
+  |                                                        
+  |*                                                 |   2%
+  |                                                        
+  |**                                                |   4%
+  |                                                        
+  |***                                               |   7%
+  |                                                        
+  |****                                              |   9%
+  |                                                        
+  |******                                            |  11%
+  |                                                        
+  |*******                                           |  13%
+  |                                                        
+  |********                                          |  16%
+  |                                                        
+  |*********                                         |  18%
+  |                                                        
+  |**********                                        |  20%
+  |                                                        
+  |***********                                       |  22%
+  |                                                        
+  |************                                      |  24%
+  |                                                        
+  |*************                                     |  27%
+  |                                                        
+  |**************                                    |  29%
+  |                                                        
+  |****************                                  |  31%
+  |                                                        
+  |*****************                                 |  33%
+  |                                                        
+  |******************                                |  36%
+  |                                                        
+  |*******************                               |  38%
+  |                                                        
+  |********************                              |  40%
+  |                                                        
+  |*********************                             |  42%
+  |                                                        
+  |**********************                            |  44%
+  |                                                        
+  |***********************                           |  47%
+  |                                                        
+  |************************                          |  49%
+  |                                                        
+  |**************************                        |  51%
+  |                                                        
+  |***************************                       |  53%
+  |                                                        
+  |****************************                      |  56%
+  |                                                        
+  |*****************************                     |  58%
+  |                                                        
+  |******************************                    |  60%
+  |                                                        
+  |*******************************                   |  62%
+  |                                                        
+  |********************************                  |  64%
+  |                                                        
+  |*********************************                 |  67%
+  |                                                        
+  |**********************************                |  69%
+  |                                                        
+  |************************************              |  71%
+  |                                                        
+  |*************************************             |  73%
+  |                                                        
+  |**************************************            |  76%
+  |                                                        
+  |***************************************           |  78%
+  |                                                        
+  |****************************************          |  80%
+  |                                                        
+  |*****************************************         |  82%
+  |                                                        
+  |******************************************        |  84%
+  |                                                        
+  |*******************************************       |  87%
+  |                                                        
+  |********************************************      |  89%
+  |                                                        
+  |**********************************************    |  91%
+  |                                                        
+  |***********************************************   |  93%
+  |                                                        
+  |************************************************  |  96%
+  |                                                        
+  |************************************************* |  98%
+  |                                                        
+  |**************************************************| 100%
+ + +

+

The results of this toy example are not expected to be overly helpful or meaningful.

- -
summary(simmr_out,type='statistics')
-summary(simmr_out,type='quantiles')
+ +
summary(simmr_out,type='statistics')
+ + +

+Summary for 1 
+           mean    sd
+deviance 15.542 3.644
+A         0.245 0.069
+B         0.254 0.069
+C         0.249 0.069
+D         0.252 0.069
+sd[dC]    0.163 0.137
+sd[dN]    0.162 0.135
+ + +
summary(simmr_out,type='quantiles')
+ +

+Summary for 1 
+           2.5%    25%    50%    75%  97.5%
+deviance 10.683 12.878 14.848 17.393 24.827
+A         0.103  0.201  0.245  0.291  0.379
+B         0.121  0.206  0.254  0.299  0.394
+C         0.108  0.205  0.248  0.296  0.384
+D         0.119  0.206  0.252  0.297  0.395
+sd[dC]    0.006  0.061  0.130  0.230  0.507
+sd[dN]    0.006  0.058  0.130  0.230  0.484
+

Plot the estimates of the dietary proportions

@@ -1843,6 +2005,9 @@

Fit the SIMM

# Plot the a priori aggregated diet estimatess
 plot(simmr_out, type = "density")
+ +

+

Plot the covariance between the estimated dietary proportons in the posterior.

@@ -1853,6 +2018,9 @@

Fit the SIMM

plot(simmr_out, type = "matrix") + +

+ @@ -1861,26 +2029,6 @@

A priori aggregation

We combine the sources C and D before we run the model as is sometimes suggested. We do this by taking the mean of the means, and we square the SDs to make them variances, then add them, and then square-root them to turn them back into SDs again. We dont need to change the consumer data in any way.

- -

-# specify the source names
-S_names_a_priori = c("A","B","CD")
-
-# take the mean of the last two sources C and D
-S_means_a_priori = rbind(S_means[1:2,], colMeans(S_means[3:4,]) )
-
-# square the sds for sources C and D to convert to variance,
-# sum them and convert back to sd
-S_sds_a_priori = rbind( S_sds[1:2,], colSums(S_sds[3:4,]^2) ^ 0.5 )
-
-# and create the new simmr object
-# here we have no TDFs or concentration values
-simmr_in_a_priori <- simmr_load(mixtures = consumers,
-                       source_names = S_names_a_priori,
-                       source_means = S_means_a_priori,
-                       source_sds = S_sds_a_priori)
-
-

Plot this newly combined data.

@@ -1890,16 +2038,136 @@

A priori aggregation

# plot the raw data for the a priori aggregated example
 plot(simmr_in_a_priori)
+ +

+

Run the model on the a priori combined data.

- +
# fit the a priori aggregated models
-simmr_out_a_priori = simmr_mcmc(simmr_in_a_priori)
-
+simmr_out_a_priori = simmr_mcmc(simmr_in_a_priori) + +
Compiling model graph
+   Resolving undeclared variables
+   Allocating nodes
+Graph information:
+   Observed stochastic nodes: 20
+   Unobserved stochastic nodes: 5
+   Total graph size: 107
+
+Initializing model
+
+
+  |                                                        
+  |                                                  |   0%
+  |                                                        
+  |++++++++++                                        |  20%
+  |                                                        
+  |++++++++++++++++++++                              |  40%
+  |                                                        
+  |++++++++++++++++++++++++++++++                    |  60%
+  |                                                        
+  |++++++++++++++++++++++++++++++++++++++++          |  80%
+  |                                                        
+  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100%
+
+  |                                                        
+  |                                                  |   0%
+  |                                                        
+  |*                                                 |   2%
+  |                                                        
+  |**                                                |   4%
+  |                                                        
+  |***                                               |   7%
+  |                                                        
+  |****                                              |   9%
+  |                                                        
+  |******                                            |  11%
+  |                                                        
+  |*******                                           |  13%
+  |                                                        
+  |********                                          |  16%
+  |                                                        
+  |*********                                         |  18%
+  |                                                        
+  |**********                                        |  20%
+  |                                                        
+  |***********                                       |  22%
+  |                                                        
+  |************                                      |  24%
+  |                                                        
+  |*************                                     |  27%
+  |                                                        
+  |**************                                    |  29%
+  |                                                        
+  |****************                                  |  31%
+  |                                                        
+  |*****************                                 |  33%
+  |                                                        
+  |******************                                |  36%
+  |                                                        
+  |*******************                               |  38%
+  |                                                        
+  |********************                              |  40%
+  |                                                        
+  |*********************                             |  42%
+  |                                                        
+  |**********************                            |  44%
+  |                                                        
+  |***********************                           |  47%
+  |                                                        
+  |************************                          |  49%
+  |                                                        
+  |**************************                        |  51%
+  |                                                        
+  |***************************                       |  53%
+  |                                                        
+  |****************************                      |  56%
+  |                                                        
+  |*****************************                     |  58%
+  |                                                        
+  |******************************                    |  60%
+  |                                                        
+  |*******************************                   |  62%
+  |                                                        
+  |********************************                  |  64%
+  |                                                        
+  |*********************************                 |  67%
+  |                                                        
+  |**********************************                |  69%
+  |                                                        
+  |************************************              |  71%
+  |                                                        
+  |*************************************             |  73%
+  |                                                        
+  |**************************************            |  76%
+  |                                                        
+  |***************************************           |  78%
+  |                                                        
+  |****************************************          |  80%
+  |                                                        
+  |*****************************************         |  82%
+  |                                                        
+  |******************************************        |  84%
+  |                                                        
+  |*******************************************       |  87%
+  |                                                        
+  |********************************************      |  89%
+  |                                                        
+  |**********************************************    |  91%
+  |                                                        
+  |***********************************************   |  93%
+  |                                                        
+  |************************************************  |  96%
+  |                                                        
+  |************************************************* |  98%
+  |                                                        
+  |**************************************************| 100%
+

And plot

@@ -1909,6 +2177,9 @@

A priori aggregation

# Plot the a priori aggregated diet estimatess
 plot(simmr_out_a_priori, type = "density")
+ +

+

… and now apparently we are very sure about the contributions of all sources to the diet. There is some correlation between A and B since they need to balance each other out in combination to yield a dB value of 0. You would now incorrectly assume that CD represents pretty much a guaranteed 43% of the diet.

@@ -1919,6 +2190,9 @@

A priori aggregation

plot(simmr_out_a_priori, type = "matrix") + +

+ @@ -1927,17 +2201,9 @@

A posteriori aggregation

Far more honest is to fit the model as before, with the sources as we believe them to be a priori and then simply add our prortions together from the posterior distribution. This is made very easy in SIMMR and also MixSIAR with dedicated functions. In fact, MixSIAR also allows easier a priori aggregation by hiding the routine outlined in the preceding section.

- -
# combine sources C and D which are in positions 3 and 4
-simmr_out_a_posteriori <- simmr::combine_sources(
-  simmr_out, 
-  to_combine = simmr_out$input$source_names[c(3,4)], 
-  new_source_name = "CD")
-
-# Plot the a posteriori aggregated diet estimatess
-plot(simmr_out_a_posteriori, type = "density")
-
- + +

+

This result fits much better with what we would predict: that if the model is still not sure about the contribution of the four sources to the mixture, but that it is pretty sure that on average, 50% of the diet is comprised of both C and D. This concept continues until the model is entirely certain, with no error, that the diet is wholly 100% of A+B+C+D.

@@ -1945,7 +2211,7 @@

A posteriori aggregation

-
LS0tCnRpdGxlOiAiU291cmNlIEFnZ3JlZ2F0aW9uIgphdXRob3I6ICJBbmRyZXcgTCBKYWNrc29uIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyMgQ3JlYXRlIHNvbWUgc2ltdWxhdGVkIGRhdGEgZm9yIHVzIHRvIHdvcmsgd2l0aApUaGlzIGlzIGVzc2VudGlhbGx5IHRoZSBleGFtcGxlIHVzZWQgaW4gRnJ5LCBCLiAyMDEzLiBBbHRlcm5hdGl2ZSBhcHByb2FjaGVzIGZvciBzb2x2aW5nIHVuZGVyZGV0ZXJtaW5lZCBpc290b3BlIG1peGluZyBwcm9ibGVtcy4gKk1FUFMqLgoKSGVyZSB3ZSB1c2UgdGhlIHBhY2thZ2Ugc2ltbXIgdG8gZXhwbG9yZSB0aGUgdHdvIGFsdGVybmF0aXZlcyB0byBhZ2dyZWdhdGluZyBzb3VyY2VzIGluIG1peGluZyBtb2RlbHMuIAoKYGBge3Igc2ltdWxhdGUtZGF0YX0KbGlicmFyeShzaW1tciwgcXVpZXRseSA9IFRSVUUpCgojIFNldCB0aGUgcmFuZG9tIHNlZWQgc28gd2UgZ2V0IHRoZSBzYW1lIHNldCBvZiAKIyByYW5kb20gbnVtYmVycyBlYWNoIHRpbWUgd2UgcnVuIHRoaXMgZXhhbXBsZS4Kc2V0LnNlZWQoMSkKCiMgc3BlY2lmeSB0aGUgc291cmNlcwojIHNvdXJjZXMgPC0gZGF0YS5mcmFtZShzb3VyY2VzPWMoIkEiLCJCIiwiQyIsIkQiKSwKIyAgICAgICAgICAgICAgICAgICAgICAgICBtdUM9YygtNSwtNSw1LDUpLHNkQz1jKDEsMSwxLDEpLAojICAgICAgICAgICAgICAgICAgICAgICAgIG11Tj1jKC01LDUsNSwtNSksc2ROPWMoMSwxLDEsMSkpCgojIHNwZWNpZnkgdGhlIHNvdXJjZSBuYW1lcwpTX25hbWVzID0gYygiQSIsIkIiLCJDIiwiRCIpCgojIHNwZWNpZnkgdGhlIHNvdXJjZSBtZWFucyBieSBiaW5kaW5nIHR3byB2ZWN0b3JzIAojIHRvZ2V0aGVyIGludG8gYSBtYXRyaXggYnkgY29sdW1ucy4KU19tZWFucyA9IGNiaW5kKGMoLTUsLTUsNSw1KSwgYygtNSw1LDUsLTUpKQoKIyBzcGVjaWZ5IHRoZSBzb3VyY2Ugc3RhbmRhcmQgZGV2aWF0aW9ucwpTX3NkcyA9IGNiaW5kKGMoMSwxLDEsMSksIGMoMSwxLDEsMSkpCgojIHNwZWZpY3kgdGhlIGNvbnN1bWVyIGRhdGEgYXQgdGhlIG9yaWdpbgojIFRlbiBjb25zdW1lcnMgZm9yIHRoaXMgZXhhbXBsZSBhcm91bmQgMCB3aXRoIHNtYWxsIHNkIG9mIGVycm9yLgpjb25zdW1lcnMgPC0gY2JpbmQoZEMgPSBybm9ybSgxMCwgMCwgMC4xKSwKICAgICAgICAgICAgICAgICAgIGROID0gcm5vcm0oMTAsIDAsIDAuMSkgKQoKIyBhbmQgY3JlYXRlIHRoZSBzaW1tciBvYmplY3QKIyBoZXJlIHdlIGhhdmUgbm8gVERGcyBvciBjb25jZW50cmF0aW9uIHZhbHVlcwpzaW1tcl9pbiA8LSBzaW1tcl9sb2FkKG1peHR1cmVzID0gY29uc3VtZXJzLAogICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZV9uYW1lcyA9IFNfbmFtZXMsCiAgICAgICAgICAgICAgICAgICAgICAgc291cmNlX21lYW5zID0gU19tZWFucywKICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2Vfc2RzID0gU19zZHMpCgpgYGAKCk5vdyB3ZSBjYW4gcGxvdCB0aGUgZGF0YSB0byB2aXN1YWxpc2Ugb3VyIHN5c3RlbSBhbmQgdGhlIG91dHB1dCwKCmBgYHtyIHBsb3QtaXNvdG9wZS1kYXRhfQoKcGxvdChzaW1tcl9pbikKCmBgYAoKIyMgRml0IHRoZSBTSU1NCgpXZSBjYW4gZml0IGEgc2ltbXIgbW9kZWwgdXNpbmcgdGhlIGRlZmF1bHRzLCBhbmQgaGVyZSBzdXByZXNzIHRoZSBvdXRwdXQgdXNpbmcgdGhlIGByZXN1bHRzPSdoaWRlJ2Agb3B0aW9uIGluIHRoZSBjaHVuay4KCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30Kc2ltbXJfb3V0ID0gc2ltbXJfbWNtYyhzaW1tcl9pbikKYGBgCgpBbmQgd2Ugc2hvdWxkIGFsd2F5cyBjaGVjayBmb3IgY29udmVyZ2VuY2UuCgpgYGB7cn0KIyBhIHN1bW1hcnkgdGFibGUgb2YgY29udmVyZ2VuY2UgZGlhZ25vc3RpY3MKc3VtbWFyeShzaW1tcl9vdXQsdHlwZT0nZGlhZ25vc3RpY3MnKQoKIyBwbG90IHRoZSBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBwb3dlciAKcG9zdGVyaW9yX3ByZWRpY3RpdmUoc2ltbXJfb3V0KQpgYGAKClRoZSByZXN1bHRzIG9mIHRoaXMgdG95IGV4YW1wbGUgYXJlIG5vdCBleHBlY3RlZCB0byBiZSBvdmVybHkgaGVscGZ1bCBvciBtZWFuaW5nZnVsLgoKYGBge3J9CnN1bW1hcnkoc2ltbXJfb3V0LHR5cGU9J3N0YXRpc3RpY3MnKQpzdW1tYXJ5KHNpbW1yX291dCx0eXBlPSdxdWFudGlsZXMnKQpgYGAKClBsb3QgdGhlIGVzdGltYXRlcyBvZiB0aGUgZGlldGFyeSBwcm9wb3J0aW9ucwoKYGBge3J9CiMgUGxvdCB0aGUgYSBwcmlvcmkgYWdncmVnYXRlZCBkaWV0IGVzdGltYXRlc3MKcGxvdChzaW1tcl9vdXQsIHR5cGUgPSAiZGVuc2l0eSIpCmBgYAoKClBsb3QgdGhlIGNvdmFyaWFuY2UgYmV0d2VlbiB0aGUgZXN0aW1hdGVkIGRpZXRhcnkgcHJvcG9ydG9ucyBpbiB0aGUgcG9zdGVyaW9yLgoKYGBge3IgcGxvdC1wb3N0ZXJpb3ItY292fQoKcGxvdChzaW1tcl9vdXQsIHR5cGUgPSAibWF0cml4IikKCmBgYAoKCgojIyBfXypBIHByaW9yaSpfXyBhZ2dyZWdhdGlvbgoKV2UgY29tYmluZSB0aGUgc291cmNlcyBDIGFuZCBEIGJlZm9yZSB3ZSBydW4gdGhlIG1vZGVsIGFzIGlzIHNvbWV0aW1lcyBzdWdnZXN0ZWQuIFdlIGRvIHRoaXMgYnkgdGFraW5nIHRoZSBtZWFuIG9mIHRoZSBtZWFucywgYW5kIHdlIHNxdWFyZSB0aGUgU0RzIHRvIG1ha2UgdGhlbSB2YXJpYW5jZXMsIHRoZW4gYWRkIHRoZW0sIGFuZCB0aGVuIHNxdWFyZS1yb290IHRoZW0gdG8gdHVybiB0aGVtIGJhY2sgaW50byBTRHMgYWdhaW4uIFdlIGRvbnQgbmVlZCB0byBjaGFuZ2UgdGhlIGNvbnN1bWVyIGRhdGEgaW4gYW55IHdheS4KCmBgYHtyIGEtcHJpb3JpfQoKIyBzcGVjaWZ5IHRoZSBzb3VyY2UgbmFtZXMKU19uYW1lc19hX3ByaW9yaSA9IGMoIkEiLCJCIiwiQ0QiKQoKIyB0YWtlIHRoZSBtZWFuIG9mIHRoZSBsYXN0IHR3byBzb3VyY2VzIEMgYW5kIEQKU19tZWFuc19hX3ByaW9yaSA9IHJiaW5kKFNfbWVhbnNbMToyLF0sIGNvbE1lYW5zKFNfbWVhbnNbMzo0LF0pICkKCiMgc3F1YXJlIHRoZSBzZHMgZm9yIHNvdXJjZXMgQyBhbmQgRCB0byBjb252ZXJ0IHRvIHZhcmlhbmNlLAojIHN1bSB0aGVtIGFuZCBjb252ZXJ0IGJhY2sgdG8gc2QKU19zZHNfYV9wcmlvcmkgPSByYmluZCggU19zZHNbMToyLF0sIGNvbFN1bXMoU19zZHNbMzo0LF1eMikgXiAwLjUgKQoKIyBhbmQgY3JlYXRlIHRoZSBuZXcgc2ltbXIgb2JqZWN0CiMgaGVyZSB3ZSBoYXZlIG5vIFRERnMgb3IgY29uY2VudHJhdGlvbiB2YWx1ZXMKc2ltbXJfaW5fYV9wcmlvcmkgPC0gc2ltbXJfbG9hZChtaXh0dXJlcyA9IGNvbnN1bWVycywKICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VfbmFtZXMgPSBTX25hbWVzX2FfcHJpb3JpLAogICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZV9tZWFucyA9IFNfbWVhbnNfYV9wcmlvcmksCiAgICAgICAgICAgICAgICAgICAgICAgc291cmNlX3NkcyA9IFNfc2RzX2FfcHJpb3JpKQoKCgoKYGBgCgpQbG90IHRoaXMgbmV3bHkgY29tYmluZWQgZGF0YS4gCgpgYGB7cn0KIyBwbG90IHRoZSByYXcgZGF0YSBmb3IgdGhlIGEgcHJpb3JpIGFnZ3JlZ2F0ZWQgZXhhbXBsZQpwbG90KHNpbW1yX2luX2FfcHJpb3JpKQpgYGAKClJ1biB0aGUgbW9kZWwgb24gdGhlIGEgcHJpb3JpIGNvbWJpbmVkIGRhdGEuCgpgYGB7cn0KIyBmaXQgdGhlIGEgcHJpb3JpIGFnZ3JlZ2F0ZWQgbW9kZWxzCnNpbW1yX291dF9hX3ByaW9yaSA9IHNpbW1yX21jbWMoc2ltbXJfaW5fYV9wcmlvcmkpCgpgYGAKQW5kIHBsb3QKCmBgYHtyfQojIFBsb3QgdGhlIGEgcHJpb3JpIGFnZ3JlZ2F0ZWQgZGlldCBlc3RpbWF0ZXNzCnBsb3Qoc2ltbXJfb3V0X2FfcHJpb3JpLCB0eXBlID0gImRlbnNpdHkiKQpgYGAKCi4uLiBhbmQgbm93IGFwcGFyZW50bHkgd2UgYXJlIHZlcnkgc3VyZSBhYm91dCB0aGUgY29udHJpYnV0aW9ucyBvZiBhbGwgc291cmNlcyB0byB0aGUgZGlldC4gVGhlcmUgaXMgc29tZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIEEgYW5kIEIgc2luY2UgdGhleSBuZWVkIHRvIGJhbGFuY2UgZWFjaCBvdGhlciBvdXQgaW4gY29tYmluYXRpb24gdG8geWllbGQgYSBkQiB2YWx1ZSBvZiAwLiBZb3Ugd291bGQgbm93IGluY29ycmVjdGx5IGFzc3VtZSB0aGF0ICBDRCByZXByZXNlbnRzIHByZXR0eSBtdWNoIGEgZ3VhcmFudGVlZCA0MyUgb2YgdGhlIGRpZXQuCgpgYGB7ciBwbG90LXBvc3Rlcmlvci1jb3YtcHJpb3ItYWdnfQoKcGxvdChzaW1tcl9vdXRfYV9wcmlvcmksIHR5cGUgPSAibWF0cml4IikKCmBgYAoKIyMgX18qQSBwb3N0ZXJpb3JpKl9fIGFnZ3JlZ2F0aW9uCkZhciBtb3JlIGhvbmVzdCBpcyB0byBmaXQgdGhlIG1vZGVsIGFzIGJlZm9yZSwgd2l0aCB0aGUgc291cmNlcyBhcyB3ZSBiZWxpZXZlIHRoZW0gdG8gYmUgKmEgcHJpb3JpKiBhbmQgdGhlbiBzaW1wbHkgYWRkIG91ciBwcm9ydGlvbnMgdG9nZXRoZXIgZnJvbSB0aGUgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbi4gVGhpcyBpcyBtYWRlIHZlcnkgZWFzeSBpbiBTSU1NUiBhbmQgYWxzbyBNaXhTSUFSIHdpdGggZGVkaWNhdGVkIGZ1bmN0aW9ucy4gSW4gZmFjdCwgTWl4U0lBUiBhbHNvIGFsbG93cyBlYXNpZXIgYSBwcmlvcmkgYWdncmVnYXRpb24gYnkgaGlkaW5nIHRoZSByb3V0aW5lIG91dGxpbmVkIGluIHRoZSBwcmVjZWRpbmcgc2VjdGlvbi4KCmBgYHtyIGEtcG9zdGVyaW9yaX0KIyBjb21iaW5lIHNvdXJjZXMgQyBhbmQgRCB3aGljaCBhcmUgaW4gcG9zaXRpb25zIDMgYW5kIDQKc2ltbXJfb3V0X2FfcG9zdGVyaW9yaSA8LSBzaW1tcjo6Y29tYmluZV9zb3VyY2VzKAogIHNpbW1yX291dCwgCiAgdG9fY29tYmluZSA9IHNpbW1yX291dCRpbnB1dCRzb3VyY2VfbmFtZXNbYygzLDQpXSwgCiAgbmV3X3NvdXJjZV9uYW1lID0gIkNEIikKCiMgUGxvdCB0aGUgYSBwb3N0ZXJpb3JpIGFnZ3JlZ2F0ZWQgZGlldCBlc3RpbWF0ZXNzCnBsb3Qoc2ltbXJfb3V0X2FfcG9zdGVyaW9yaSwgdHlwZSA9ICJkZW5zaXR5IikKCgpgYGAKVGhpcyByZXN1bHQgZml0cyBtdWNoIGJldHRlciB3aXRoIHdoYXQgd2Ugd291bGQgcHJlZGljdDogdGhhdCBpZiB0aGUgbW9kZWwgaXMgc3RpbGwgbm90IHN1cmUgYWJvdXQgdGhlIGNvbnRyaWJ1dGlvbiBvZiB0aGUgZm91ciBzb3VyY2VzIHRvIHRoZSBtaXh0dXJlLCBidXQgdGhhdCBpdCBpcyBwcmV0dHkgc3VyZSB0aGF0IG9uIGF2ZXJhZ2UsIDUwJSBvZiB0aGUgZGlldCBpcyBjb21wcmlzZWQgb2YgYm90aCBDIGFuZCBELiBUaGlzIGNvbmNlcHQgY29udGludWVzIHVudGlsIHRoZSBtb2RlbCBpcyBlbnRpcmVseSBjZXJ0YWluLCB3aXRoIG5vIGVycm9yLCB0aGF0IHRoZSBkaWV0IGlzIHdob2xseSAxMDAlIG9mIEErQitDK0QuCgpPbmUgdGhpbmcgdG8gZXhwZXJpbWVudCB3aXRoIGhlcmUgaXMgdGhlIHVzZSBvZiB0aGUgSmVmZnJleSdzIHByaW9yIG9mIGBjKDAuMjUsIDAuMjUsIDAuMjUsIDAuMjUpYCBpbiBwbGFjZSBvZiB0aGUgZGVmYXVsdCB2YWd1ZSBwcmlvciBgYygxLCAxLCAxLCAxKWAuIFRoaXMgaXMgdGhlIG51YiBvZiB0aGUgY3JpdGljaXNtIGxldmVsbGVkIGF0IHRoZSBTSU1NcyBieSBCcmV0dCwgTS4gMjAxNi4gUmVzb3VyY2UgcG9seWdvbiBnZW9tZXRyeSBwcmVkaWN0cyBCYXllc2lhbiBzdGFibGUgaXNvdG9wZSBtaXhpbmcgbW9kZWwgYmlhcy4gTUVQUy4KCgo=
+
LS0tCnRpdGxlOiAiU291cmNlIEFnZ3JlZ2F0aW9uIgphdXRob3I6ICJBbmRyZXcgTCBKYWNrc29uIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyMgQ3JlYXRlIHNvbWUgc2ltdWxhdGVkIGRhdGEgZm9yIHVzIHRvIHdvcmsgd2l0aApUaGlzIGlzIGVzc2VudGlhbGx5IHRoZSBleGFtcGxlIHVzZWQgaW4gRnJ5LCBCLiAyMDEzLiBBbHRlcm5hdGl2ZSBhcHByb2FjaGVzIGZvciBzb2x2aW5nIHVuZGVyZGV0ZXJtaW5lZCBpc290b3BlIG1peGluZyBwcm9ibGVtcy4gKk1FUFMqLgoKSGVyZSB3ZSB1c2UgdGhlIHBhY2thZ2Ugc2ltbXIgdG8gZXhwbG9yZSB0aGUgdHdvIGFsdGVybmF0aXZlcyB0byBhZ2dyZWdhdGluZyBzb3VyY2VzIGluIG1peGluZyBtb2RlbHMuIAoKYGBge3Igc2ltdWxhdGUtZGF0YX0KbGlicmFyeShzaW1tciwgcXVpZXRseSA9IFRSVUUpCgojIFNldCB0aGUgcmFuZG9tIHNlZWQgc28gd2UgZ2V0IHRoZSBzYW1lIHNldCBvZiAKIyByYW5kb20gbnVtYmVycyBlYWNoIHRpbWUgd2UgcnVuIHRoaXMgZXhhbXBsZS4Kc2V0LnNlZWQoMSkKCiMgc3BlY2lmeSB0aGUgc291cmNlcwojIHNvdXJjZXMgPC0gZGF0YS5mcmFtZShzb3VyY2VzPWMoIkEiLCJCIiwiQyIsIkQiKSwKIyAgICAgICAgICAgICAgICAgICAgICAgICBtdUM9YygtNSwtNSw1LDUpLHNkQz1jKDEsMSwxLDEpLAojICAgICAgICAgICAgICAgICAgICAgICAgIG11Tj1jKC01LDUsNSwtNSksc2ROPWMoMSwxLDEsMSkpCgojIHNwZWNpZnkgdGhlIHNvdXJjZSBuYW1lcwpTX25hbWVzID0gYygiQSIsIkIiLCJDIiwiRCIpCgojIHNwZWNpZnkgdGhlIHNvdXJjZSBtZWFucyBieSBiaW5kaW5nIHR3byB2ZWN0b3JzIAojIHRvZ2V0aGVyIGludG8gYSBtYXRyaXggYnkgY29sdW1ucy4KU19tZWFucyA9IGNiaW5kKGMoLTUsLTUsNSw1KSwgYygtNSw1LDUsLTUpKQoKIyBzcGVjaWZ5IHRoZSBzb3VyY2Ugc3RhbmRhcmQgZGV2aWF0aW9ucwpTX3NkcyA9IGNiaW5kKGMoMSwxLDEsMSksIGMoMSwxLDEsMSkpCgojIHNwZWZpY3kgdGhlIGNvbnN1bWVyIGRhdGEgYXQgdGhlIG9yaWdpbgojIFRlbiBjb25zdW1lcnMgZm9yIHRoaXMgZXhhbXBsZSBhcm91bmQgMCB3aXRoIHNtYWxsIHNkIG9mIGVycm9yLgpjb25zdW1lcnMgPC0gY2JpbmQoZEMgPSBybm9ybSgxMCwgMCwgMC4xKSwKICAgICAgICAgICAgICAgICAgIGROID0gcm5vcm0oMTAsIDAsIDAuMSkgKQoKIyBhbmQgY3JlYXRlIHRoZSBzaW1tciBvYmplY3QKIyBoZXJlIHdlIGhhdmUgbm8gVERGcyBvciBjb25jZW50cmF0aW9uIHZhbHVlcwpzaW1tcl9pbiA8LSBzaW1tcl9sb2FkKG1peHR1cmVzID0gY29uc3VtZXJzLAogICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZV9uYW1lcyA9IFNfbmFtZXMsCiAgICAgICAgICAgICAgICAgICAgICAgc291cmNlX21lYW5zID0gU19tZWFucywKICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2Vfc2RzID0gU19zZHMpCgpgYGAKCk5vdyB3ZSBjYW4gcGxvdCB0aGUgZGF0YSB0byB2aXN1YWxpc2Ugb3VyIHN5c3RlbSBhbmQgdGhlIG91dHB1dCwKCmBgYHtyIHBsb3QtaXNvdG9wZS1kYXRhfQoKcGxvdChzaW1tcl9pbikKCmBgYAoKIyMgRml0IHRoZSBTSU1NCgpXZSBjYW4gZml0IGEgc2ltbXIgbW9kZWwgdXNpbmcgdGhlIGRlZmF1bHRzLCBhbmQgaGVyZSBzdXByZXNzIHRoZSBvdXRwdXQgdXNpbmcgdGhlIGByZXN1bHRzPSdoaWRlJ2Agb3B0aW9uIGluIHRoZSBjaHVuay4KCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30Kc2ltbXJfb3V0ID0gc2ltbXJfbWNtYyhzaW1tcl9pbikKYGBgCgpBbmQgd2Ugc2hvdWxkIGFsd2F5cyBjaGVjayBmb3IgY29udmVyZ2VuY2UuCgpgYGB7cn0KIyBhIHN1bW1hcnkgdGFibGUgb2YgY29udmVyZ2VuY2UgZGlhZ25vc3RpY3MKc3VtbWFyeShzaW1tcl9vdXQsdHlwZT0nZGlhZ25vc3RpY3MnKQoKIyBwbG90IHRoZSBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBwb3dlciAKcG9zdGVyaW9yX3ByZWRpY3RpdmUoc2ltbXJfb3V0KQpgYGAKClRoZSByZXN1bHRzIG9mIHRoaXMgdG95IGV4YW1wbGUgYXJlIG5vdCBleHBlY3RlZCB0byBiZSBvdmVybHkgaGVscGZ1bCBvciBtZWFuaW5nZnVsLgoKYGBge3J9CnN1bW1hcnkoc2ltbXJfb3V0LHR5cGU9J3N0YXRpc3RpY3MnKQpzdW1tYXJ5KHNpbW1yX291dCx0eXBlPSdxdWFudGlsZXMnKQpgYGAKClBsb3QgdGhlIGVzdGltYXRlcyBvZiB0aGUgZGlldGFyeSBwcm9wb3J0aW9ucwoKYGBge3J9CiMgUGxvdCB0aGUgYSBwcmlvcmkgYWdncmVnYXRlZCBkaWV0IGVzdGltYXRlc3MKcGxvdChzaW1tcl9vdXQsIHR5cGUgPSAiZGVuc2l0eSIpCmBgYAoKClBsb3QgdGhlIGNvdmFyaWFuY2UgYmV0d2VlbiB0aGUgZXN0aW1hdGVkIGRpZXRhcnkgcHJvcG9ydG9ucyBpbiB0aGUgcG9zdGVyaW9yLgoKYGBge3IgcGxvdC1wb3N0ZXJpb3ItY292fQoKcGxvdChzaW1tcl9vdXQsIHR5cGUgPSAibWF0cml4IikKCmBgYAoKCgojIyBfXypBIHByaW9yaSpfXyBhZ2dyZWdhdGlvbgoKV2UgY29tYmluZSB0aGUgc291cmNlcyBDIGFuZCBEIGJlZm9yZSB3ZSBydW4gdGhlIG1vZGVsIGFzIGlzIHNvbWV0aW1lcyBzdWdnZXN0ZWQuIFdlIGRvIHRoaXMgYnkgdGFraW5nIHRoZSBtZWFuIG9mIHRoZSBtZWFucywgYW5kIHdlIHNxdWFyZSB0aGUgU0RzIHRvIG1ha2UgdGhlbSB2YXJpYW5jZXMsIHRoZW4gYWRkIHRoZW0sIGFuZCB0aGVuIHNxdWFyZS1yb290IHRoZW0gdG8gdHVybiB0aGVtIGJhY2sgaW50byBTRHMgYWdhaW4uIFdlIGRvbnQgbmVlZCB0byBjaGFuZ2UgdGhlIGNvbnN1bWVyIGRhdGEgaW4gYW55IHdheS4KCmBgYHtyIGEtcHJpb3JpfQoKIyBzcGVjaWZ5IHRoZSBzb3VyY2UgbmFtZXMKU19uYW1lc19hX3ByaW9yaSA9IGMoIkEiLCJCIiwiQ0QiKQoKIyB0YWtlIHRoZSBtZWFuIG9mIHRoZSBsYXN0IHR3byBzb3VyY2VzIEMgYW5kIEQKU19tZWFuc19hX3ByaW9yaSA9IHJiaW5kKFNfbWVhbnNbMToyLF0sIGNvbE1lYW5zKFNfbWVhbnNbMzo0LF0pICkKCiMgc3F1YXJlIHRoZSBzZHMgZm9yIHNvdXJjZXMgQyBhbmQgRCB0byBjb252ZXJ0IHRvIHZhcmlhbmNlLAojIHN1bSB0aGVtIGFuZCBjb252ZXJ0IGJhY2sgdG8gc2QKU19zZHNfYV9wcmlvcmkgPSByYmluZCggU19zZHNbMToyLF0sIGNvbFN1bXMoU19zZHNbMzo0LF1eMikgXiAwLjUgKQoKIyBhbmQgY3JlYXRlIHRoZSBuZXcgc2ltbXIgb2JqZWN0CiMgaGVyZSB3ZSBoYXZlIG5vIFRERnMgb3IgY29uY2VudHJhdGlvbiB2YWx1ZXMKc2ltbXJfaW5fYV9wcmlvcmkgPC0gc2ltbXJfbG9hZChtaXh0dXJlcyA9IGNvbnN1bWVycywKICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VfbmFtZXMgPSBTX25hbWVzX2FfcHJpb3JpLAogICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZV9tZWFucyA9IFNfbWVhbnNfYV9wcmlvcmksCiAgICAgICAgICAgICAgICAgICAgICAgc291cmNlX3NkcyA9IFNfc2RzX2FfcHJpb3JpKQoKCgoKYGBgCgpQbG90IHRoaXMgbmV3bHkgY29tYmluZWQgZGF0YS4gCgpgYGB7cn0KIyBwbG90IHRoZSByYXcgZGF0YSBmb3IgdGhlIGEgcHJpb3JpIGFnZ3JlZ2F0ZWQgZXhhbXBsZQpwbG90KHNpbW1yX2luX2FfcHJpb3JpKQpgYGAKClJ1biB0aGUgbW9kZWwgb24gdGhlIGEgcHJpb3JpIGNvbWJpbmVkIGRhdGEuCgpgYGB7cn0KIyBmaXQgdGhlIGEgcHJpb3JpIGFnZ3JlZ2F0ZWQgbW9kZWxzCnNpbW1yX291dF9hX3ByaW9yaSA9IHNpbW1yX21jbWMoc2ltbXJfaW5fYV9wcmlvcmkpCgpgYGAKQW5kIHBsb3QKCmBgYHtyfQojIFBsb3QgdGhlIGEgcHJpb3JpIGFnZ3JlZ2F0ZWQgZGlldCBlc3RpbWF0ZXNzCnBsb3Qoc2ltbXJfb3V0X2FfcHJpb3JpLCB0eXBlID0gImRlbnNpdHkiKQpgYGAKCi4uLiBhbmQgbm93IGFwcGFyZW50bHkgd2UgYXJlIHZlcnkgc3VyZSBhYm91dCB0aGUgY29udHJpYnV0aW9ucyBvZiBhbGwgc291cmNlcyB0byB0aGUgZGlldC4gVGhlcmUgaXMgc29tZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIEEgYW5kIEIgc2luY2UgdGhleSBuZWVkIHRvIGJhbGFuY2UgZWFjaCBvdGhlciBvdXQgaW4gY29tYmluYXRpb24gdG8geWllbGQgYSBkQiB2YWx1ZSBvZiAwLiBZb3Ugd291bGQgbm93IGluY29ycmVjdGx5IGFzc3VtZSB0aGF0ICBDRCByZXByZXNlbnRzIHByZXR0eSBtdWNoIGEgZ3VhcmFudGVlZCA0MyUgb2YgdGhlIGRpZXQuCgpgYGB7ciBwbG90LXBvc3Rlcmlvci1jb3YtcHJpb3ItYWdnfQoKcGxvdChzaW1tcl9vdXRfYV9wcmlvcmksIHR5cGUgPSAibWF0cml4IikKCmBgYAoKIyMgX18qQSBwb3N0ZXJpb3JpKl9fIGFnZ3JlZ2F0aW9uCkZhciBtb3JlIGhvbmVzdCBpcyB0byBmaXQgdGhlIG1vZGVsIGFzIGJlZm9yZSwgd2l0aCB0aGUgc291cmNlcyBhcyB3ZSBiZWxpZXZlIHRoZW0gdG8gYmUgKmEgcHJpb3JpKiBhbmQgdGhlbiBzaW1wbHkgYWRkIG91ciBwcm9ydGlvbnMgdG9nZXRoZXIgZnJvbSB0aGUgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbi4gVGhpcyBpcyBtYWRlIHZlcnkgZWFzeSBpbiBTSU1NUiBhbmQgYWxzbyBNaXhTSUFSIHdpdGggZGVkaWNhdGVkIGZ1bmN0aW9ucy4gSW4gZmFjdCwgTWl4U0lBUiBhbHNvIGFsbG93cyBlYXNpZXIgYSBwcmlvcmkgYWdncmVnYXRpb24gYnkgaGlkaW5nIHRoZSByb3V0aW5lIG91dGxpbmVkIGluIHRoZSBwcmVjZWRpbmcgc2VjdGlvbi4KCmBgYHtyIGEtcG9zdGVyaW9yaX0KIyBjb21iaW5lIHNvdXJjZXMgQyBhbmQgRCB3aGljaCBhcmUgaW4gcG9zaXRpb25zIDMgYW5kIDQKc2ltbXJfb3V0X2FfcG9zdGVyaW9yaSA8LSBjb21iaW5lX3NvdXJjZXMoCiAgc2ltbXJfb3V0LCAKICB0b19jb21iaW5lID0gc2ltbXJfb3V0JGlucHV0JHNvdXJjZV9uYW1lc1tjKDMsNCldLCAKICBuZXdfc291cmNlX25hbWUgPSAiQ0QiKQoKIyBQbG90IHRoZSBhIHBvc3RlcmlvcmkgYWdncmVnYXRlZCBkaWV0IGVzdGltYXRlc3MKcGxvdChzaW1tcl9vdXRfYV9wb3N0ZXJpb3JpLCB0eXBlID0gImRlbnNpdHkiKQoKCmBgYApUaGlzIHJlc3VsdCBmaXRzIG11Y2ggYmV0dGVyIHdpdGggd2hhdCB3ZSB3b3VsZCBwcmVkaWN0OiB0aGF0IGlmIHRoZSBtb2RlbCBpcyBzdGlsbCBub3Qgc3VyZSBhYm91dCB0aGUgY29udHJpYnV0aW9uIG9mIHRoZSBmb3VyIHNvdXJjZXMgdG8gdGhlIG1peHR1cmUsIGJ1dCB0aGF0IGl0IGlzIHByZXR0eSBzdXJlIHRoYXQgb24gYXZlcmFnZSwgNTAlIG9mIHRoZSBkaWV0IGlzIGNvbXByaXNlZCBvZiBib3RoIEMgYW5kIEQuIFRoaXMgY29uY2VwdCBjb250aW51ZXMgdW50aWwgdGhlIG1vZGVsIGlzIGVudGlyZWx5IGNlcnRhaW4sIHdpdGggbm8gZXJyb3IsIHRoYXQgdGhlIGRpZXQgaXMgd2hvbGx5IDEwMCUgb2YgQStCK0MrRC4KCk9uZSB0aGluZyB0byBleHBlcmltZW50IHdpdGggaGVyZSBpcyB0aGUgdXNlIG9mIHRoZSBKZWZmcmV5J3MgcHJpb3Igb2YgYGMoMC4yNSwgMC4yNSwgMC4yNSwgMC4yNSlgIGluIHBsYWNlIG9mIHRoZSBkZWZhdWx0IHZhZ3VlIHByaW9yIGBjKDEsIDEsIDEsIDEpYC4gVGhpcyBpcyB0aGUgbnViIG9mIHRoZSBjcml0aWNpc20gbGV2ZWxsZWQgYXQgdGhlIFNJTU1zIGJ5IEJyZXR0LCBNLiAyMDE2LiBSZXNvdXJjZSBwb2x5Z29uIGdlb21ldHJ5IHByZWRpY3RzIEJheWVzaWFuIHN0YWJsZSBpc290b3BlIG1peGluZyBtb2RlbCBiaWFzLiBNRVBTLgoKCg==