INTRODUCTION

Generating emotional states in the laboratory can be challenging. Most available methods require researchers to choose between maximizing ecological validity or experimental rigor. Affective images seem to offer a desirable balance between these values. Researchers are therefore fond of published databases of images accompanied with statistics illustrating the core affect each image is likely to elicit.

However, careless reliance of picture sets constructed using normative affective ratings can be risky. Ideally, independent variables constructed from such databases (e.g., a neutral and a negative condition) should be independent of major non-affective sources of variance in dependent variables (e.g., subjective, bodily, or brain responses). Unfortunately, this ideal is not guaranteed when stimulus sets designed to vary in core affect. Provide evdince how sets built on valence and arousal tend to be biased on other features which can affect findings.]

The present work aims to provide a toolkit for reserachers interested in creating balanced affective stimulus sets. In particular, we have worked in four inter-related areas.

  1. Created a meta-database of all published affective image sets;
  2. Extracted perceptual features of the images in the meta-database;
  3. Extracted semantic features of the images in the meta-database;
  4. Created an algorithmic pipeline for compiling balanced image sets.

META-DATABASE

Here are the databases that are included in the meta-database. Below is a more detailed list with each database name, citation, web link, # of pictures, picture categories, normative ratings compiled by Ola Abdelhadi.

One thing to note on this figure are the different normative rating distributions between different databases. While some of this variance is caused by genuine differences between pictures, visual inspection of the images suggests that there may be systematic biases rating scale performance (even after we have converted all ratings to a common scale).

International Affective Picture System (IAPS)

  • Lang, P.J., Bradley, M.M., & Cuthbert, B.N. (2008). International affective picture system (IAPS): Affective ratings of pictures and instruction manual. Technical Report A-8. University of Florida, Gainesville, FL.
  • Pictures: 1196
  • Categories: Multiple, from furniture to complete scene, wide range of semantic categories.
  • Normative ratings: Valence, arousal, and dominance

Geneva affective picture database (GAPED)

  • Dan-Glauser, E. S., & Scherer, K. R. (2011). The Geneva affective picture database (GAPED): a new 730-picture database focusing on valence and normative significance. Behavior Research Methods, 43(2), 468-477. doi: 10.3758/s13428-011-0064-1
  • Pictures: 730
  • Categories: spiders, snakes, and scenes that induce emotions related to the violation of moral and legal norms (human rights violation or animal mistreatment). Positive and neutral pictures were also included.
  • Normative ratings: Valence, Arousal, external norm and internal norm.

Nencki Affective Picture System (NAPS)

  • Marchewka, A., Zurawski, L., Jednoróg, K., & Grabowska, A. (2014). The Nencki Affective Picture System (NAPS): Introduction to a novel, standardized, wide-range, high-quality, realistic picture database. Behavior research methods, 46(2), 596-610.
  • Pictures: 1356
  • Categories: people, faces, animals, objects, and landscapes
  • Normative ratings: Valence and arousal

Erotic subset of Nencki Affective Picture System (NAPS-ERO)

  • Wierzba, M., Riegel, M., Pucz, A., Lesniewska, Z., Dragan, W. L., Gola, M., … & Marchewka, A. (2015). Erotic subset for the Nencki Affective Picture System (NAPS ERO): cross-sexual comparison study. Frontiers in psychology, 6, 1336.
  • Pictures: 200
  • Categories: opposite-sex couple (50), male couple (50), female couple (50), male (25) and female (25)

  • Normative ratings: Valence and arousal

Set of Fear Inducing Pictures (NAPS-SFIP)

  • Michalowski, J. M., Drozdziel, D., Matuszewski, J., Koziejowski, W., Jednoróg, K., & Marchewka, A. (2016). The Set of Fear Inducing Pictures (SFIP): Development and validation in fearful and nonfearful individuals. Behavior Research Methods, 1-13.
  • Pictures: 886
  • Categories: Spiders, bugs, blood injection, fearful social exposure, angry faces
  • Normative ratings: Fear, arousal and valence

Open Affective Standardized Image Set (OASIS)

  • Kurdi, B., Lozano, S., & Banaji, M. R. (2016). Introducing the Open Affective Standardized Image Set (OASIS). Behavior research methods, 1-14.
  • Pictures: 900
  • Categories: Animal, Object, Person, Scenery
  • Normative ratings: Valence and arousal

Emotional Picture System (EmoPicS)

  • Wessa, M., Kanske, P., Neumeister, P., Bode, K., Heissler, J., & Schönfelder, S. (2010). EmoPics: Subjective and psychophysiological evaluations of new imaging material for clinical-bio-psychological research. Journal of Clinical Psychology and Psychotherapy, Supplement, 1/11, 77.
  • Pictures: 378
  • Categories: Diverse social situations animals, and plants
  • Normative ratings: Valence, excitement and complexity

Besançon Affective Picture Set-Adolescents (The BAPS-Ado)= The Attachment Picture Database (APD)

  • Szymanska, M., Monnin, J., Noiret, N., Tio, G., Galdon, L., Laurent, E., … & Vulliez-Coady, L. (2015). The Besançon Affective Picture Set-Adolescents (the BAPS-Ado): Development and validation. Psychiatry research, 228(3), 576-584.
  • Pictures: 93
  • Categories: Distress, comfort, joy-complicity and neutral
  • Normative ratings: Valence, Arousal and dominance

EmoMadrid emotional pictures database

Military Affective Picture System (MAPS)

  • Dretsch, M., Thiel, K., Born, S., Goodman, A. M., & Katz, J.S. (2013). Military Affective Picture System (MAPS) [Picture Repository]. Unpublished instrument. Auburn University.
  • Pictures: 240
  • Categories: Military
  • Normative ratings: Valence, dominance, and arousal

Image Stimuli for Emotion Elicitation (ISEE)

  • Hanjoo Kim, Xin Lu, Michael Costa, Baris Kandemir, Reginald B. Adams, Jr., Jia Li, James Z. Wang and Michelle G. Newman, ``Development and Validation of the Image Stimuli for Emotion Elicitation (ISEE),’’ Association for Psychological Science Annual Convention, poster, New York City, May 2015.
  • Pictures: 10 696
  • Categories: Pictures with emotional label and categorization from Flickr
  • Normative ratings: valence, arousal, dominance, and likeness

Open Library of Affective Food (OLAF)

  • Miccoli, L., Delgado, R., Guerra, P., Versace, F., Rodríguez, S., & Fernández-Santaella, M.C. (2016). “Affective Pictures and the Open Library of Affective Foods (OLAF): Tools to Investigate Emotions toward Food in Adults.”. PLOS ONE, DOI 10.1371/journal.pone.0158991
  • Pictures: 95
  • Categories: Food
  • Normative ratings: pleasure, arousal, dominance, and food craving

The DIsgust-RelaTed-Images (DIRTI)

  • Haberkamp, A., Glombiewski, J. A., Schmidt, F., & Barke, A. (2017). The DIsgust-RelaTed-Images (DIRTI) database: Validation of a novel standardized set of disgust pictures. Behaviour Research and Therapy, 89, 86-94.
  • Pictures: 240
  • Categories: food, animals, body products, injuries/infections, death, and hygiene
  • Normative ratings: disgust, fear, valence, and arousal.

PERCEPTUAL FEATURES

We provide a Matlab script for extracting key image statistics that can be used to assess the perceptual homogeniety of experimental stimulus sets.

We selected a small set of preceptual features based on advances in relating image statistics to core principles of primate perception. Specifically, we computed aggregate statistics of visual information on two levels:

  • non-spatial distribution of luminance and color
  • spatial organization of luminance.

Non-spatial distribution of luminance and color

We first converted each picturs to the CIE Lab color space to separate luminance from color information. The CIE color space characterizes each pixel of an image with three features: its location on a luminance, a blue-yellow, and a red-green dimension.

Separating luminance information from color corresponds to functional spcialization in the brain where many perceptual computations are mainly sensitive to luminance. The characterization of color using blue-yellow and red-green dimensions corresponds to both the principal components that explain large amounts of naturally occuring color variance, as well as to the senistivity curves of bipolar color-sensitive cells in the primate visual system.

To efficiently capture the non-spatial distribution of pixel values along these dimensions, we computed the first four statistical moments of these distributions: mean, standard deviation, skewness, and kurtosis. Note that mean luminance corresponds to brightness and standard deviation of luminance corresponds to contrast.

Spatial organization of luminance

Spatial organization of luminance information is a cruical input to perception of basic qualia such as orientation, texture, movement, and shape. A useful method for numerically representing this information is spatial frequency analysis. We therefore used the 2D Fast Fourier Transform of the CIE Lab luminance channel to extract the 2D spectogram of each image.

To efficiently aggregate the 2D spectogram, we first averaged it rotationally and then computed the intercept and slope of a linear model fitted to the average spectrum on log-transformed frequency and power axis. The steeper this negative slope, the more energy can be found in lower spatial frequency relative to higher spatial frequences. Visually, such images have fewer vivid details and more large-scale edges.

The 2D spectogram has also been shown to capture spatial organization of scenes relevant for broad distinctions such as between urban and natural environments. To extract orientation information from the 2D spectogram, we fitted regression lines to the spectograms along four orientations - 45, 90, 135 and 180 degrees. We then found the orientation with higher energy, yielding a dominant orientation, and computed the standard deviation of all four slopes, yielding a measure of heterogeniety of orientations in the given image.

SEMANTIC FEATURES

We generated a semantic labelling scheme and had reserach assistants provide lavels for the images.

Below are pairwise inter-rater agreements for a subset of 600 images on two different levels of detail.

SET COMPILATION ALGORITHM

The algrithm compiles affective image sets with desired number of parallel versions and member images. In short, it seeks to minimize within-set and maximize between-set variance along affective features as well as maximize within-set and minimize between-set variance along perceptual and semantic featurues.

The algorithm has the following basic steps: 1. Define input (use full or specific image pool, set inclusion and exclusion criteria) 2. Define output (affective seeds with desired number parallel versions and members) 3. Cluster pictures separately in three different spaces: affective, semantic, and percpetual 4. Make a joint clustering by re-allocating pictures as needed 5. Distribute images from the joint clusters to requested sets

1. Define input

The algorithm can work on either the full meta-database or a user-provided source set. The input set can be further pruned by explicit inclusion and/or exclusion criteria.

Below are illustrations of the exclusion critria we used to select a subset of the meta-database for initial semantic labelling. Specifically, we excluded images that; * had a different aspect ratio from 3:4
* had fewer than 600 pixels on the shorter edge
* likely contained a solid background
* had normative valence ratings higher than 0.55 on a 0 to 1 scale

No id variables; using all as measure variables

2. Define output

For the current implementation of the algorithm, we defined:

  • seeds for desired affective categories (4 corresponding to neutral, low, medium, and high negative intensity)

  • desired semantic categories (4 corresponding to animate nonhuman, inanimate nonhuman, individual human, social human, and bruxism-related content)

  • number of images within each set (9, driven simply by the goal to have 180 image in total)

  • number of parallel sets (3)

3. Independent clustering

As its first stage, the algorithm, generates three independent clustering solutions based on affective, semantic, and perceptual features. The goal of this stage is to obtain summary features (cluster labels) that can be used to build balanced image sets. Specifically, we assume that if two image sets comprise an equal number of images from a set of clusters, then these sets will be both balanced and variable along the given clustering dimension.

Based on the desired output, we generated:

  • 4 affective clusters

  • 5 semantic clusters

  • 9 perceptual clusters

3.1. Affective clusters

We used the K-means algorithm over normative valence data to distribute all input images into one of four clusters based on manually set seeds at 0.5 (neutral), 0.35 (low), 0.25 (medium), 0.1 (high intensity negative).

We used only valence, rather than valence and arousal to bypass apparent systematic biases in normative ratings for different source sets in our meta-database. We noticed that even after converting all ratings to a uniform 0 to 1 scale, different sets seemed to exhibit systematic biases. We therefore rely on valence ratings alone, since within negative images valence and arousal tend to be highly correlated.

3.2. Semantic clusters

The default is manual specification of labels and their desired proportions.

Options include:

  • using some selection of labels to generate data-driven semantic clusters
  • using Multiple Correspondence Analysis to define the feature vectors used for data-driven clustering

3.3. Perceptual clusters

The default feature set includes.

First four statistical momemts for the distributions of CieLab dimensions:

  • mean (brightness), standard deviation (contrast), skewness, and kurtosis for luminance
  • M, SD, s, and k for the green-red dimension
  • M, SD, s, and k for the blue-yellow dimension

Representations of 2D image spectogram computed from the luminance channel:

  • slope of the rotationally averaged spectrum
  • mean rotationally avergaed spectrum in 7 bins
  • dominant direction of the 2D spectrum out of 0, 45, 90, and 135 degrees (largest slope)
  • standard deviation of slopes of all these directions

The default is hierarchical clustering with two approaches for finding a suitabel cut:

  • top-down method - start from the largest number of clusters possible given the size of input and output. Lower the number until a solution with a sufficient number of sufficiently large and emotionally diverse clusters emerges. The idea is that the higher the cut-off, the more closely-knit the clusters will be allowing to miniize perceptual variance once pictures from the same perceptual cluster will be distribited across the eventual sets.

  • dynamic tree cut - an R funtion that directly produces the desired number of clusters

 ..cutHeight not given, setting it to 19.7  ===>  99% of the (truncated) height range in dendro.
 ..done.

4. Joint clustering

A custom-built algorithm with the following steps:

  • Create a 3D matrix from the identified affective, semantic, and perceptual clusters.
  • If a cell has one or members, keep the one that has the best silhouette statistic relative to perceptual clustering, free up others
  • Loop through cells without any members in randomized ordred
  • Rank all free images from the affected semantic and emotion cluster and any perceptual cluster based on a) their distance to the centroid of the preceptual cluster build from only the currently selected images and b) emotional cluster
  • If the above step does not yield any images, consider pictures from other emotional categories closest to the current seed until at least one is found

5. Set compilation

We now have n clusters of k pictures of p contents. Use latin square to distribute semantic contents randomly across parallel versions.

REFERENCES

LS0tDQp0aXRsZTogIkFmZmVjdGl2ZSBJbWFnZSBTZXQgQnVpbGRlciINCmF1dGhvcjogQW5kZXJvIFV1c2JlcmcNCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazoNCiAgICBmaWdfaGVpZ2h0OiAxMA0KICAgIGZpZ193aWR0aDogMTgNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIHRoZW1lOiBwYXBlcg0KYmlibGlvZ3JhcGh5OiByZWYuYmliDQotLS0NCg0KYGBge3IgU0VUVVAsIGluY2x1ZGU9Rn0NCg0KDQojIFRPIERPOg0KIyANCiMgMTggY2VsbHMgb2YgMTAgaW1hZ2VzIGluIGVhY2gsIA0KIyAjIGFkZCAzIHByYWN0aWNlIGltYWdlcw0KIyANCiMgYWRkIG9wdGlvbnMgdG8gd2VpZ2ggdGhlIGZlYXR1cmVzDQojIHNlZTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzA0NDUxOTgvZGlzcGxheWluZy1pbWFnZS1vbi1wb2ludC1ob3Zlci1pbi1wbG90bHkNCiMgbWFrZSBwYXJhbWV0cml6YXRpb24gc2ltcGxlcg0KDQoNCgkjIHNldCB3b3JraW5nIGRpcmVjdG9yeQ0KCXJvb3QgPC0gIkM6L1VzZXJzL3JvL0dvb2dsZSBEcml2ZS9zZXQgYnVpbGRlci8iDQoNCgkjIGxvYWQgcGFja2FnZXMNCglpZiAoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KCXBhY21hbjo6cF9sb2FkKCJ0aWR5dmVyc2UiLCJwc3ljaCIsICJyZXNoYXBlMiIsICJSQ29sb3JCcmV3ZXIiLCAiaW1hZ2VyIiwgIlJtaXNjIiwNCgkJCQkJCQkJICJmYWN0b2V4dHJhIiwgImNsdXN0ZXIiLCAiZHluYW1pY1RyZWVDdXQiLCAiYWRlNCIsICJGYWN0b01pbmVSIiwgImFwZSIsICJjb3JycGxvdCIsICJpcnIiICwgImNpdHIiKQ0KDQoJIyBsb2FkIGZ1bmN0aW9ucw0KCXNvdXJjZShwYXN0ZTAocm9vdCwic2V0QnVpbGRlcmZ1bmN0aW9ucy5SIikpDQoJDQoJDQoJIyBTRVQgUEFSQU1FVEVSUw0KCXBybSA8LSByYmluZChkYXRhLmZyYW1lKGVtbyA9ICJudHIiLCAgdmFsZW5jZSA9IDAuNSwgYXJvdXNhbCA9IDAuMCwgc2V0TnVtID0gNSwgc2V0U2l6ZSA9IDksIHNlZWQgPSAiZml4ZWQiKSwNCiAJCQkJCQkJIGRhdGEuZnJhbWUoZW1vID0gImxvdyIsICB2YWxlbmNlID0gMC4zNSwgYXJvdXNhbCA9IDAuMywgc2V0TnVtID0gNSwgc2V0U2l6ZSA9IDksIHNlZWQgPSAiZml4ZWQiKSwNCgkJCQkJCQkgZGF0YS5mcmFtZShlbW8gPSAibWlkIiwgIHZhbGVuY2UgPSAwLjI1LCBhcm91c2FsID0gMC42LCBzZXROdW0gPSA1LCBzZXRTaXplID0gOSwgc2VlZCA9ICJmaXhlZCIpLA0KCQkJCQkgCQkgZGF0YS5mcmFtZShlbW8gPSAiaGlnaCIsIHZhbGVuY2UgPSAwLjEsIGFyb3VzYWwgPSAwLjksIHNldE51bSA9IDUsIHNldFNpemUgPSA5LCBzZWVkID0gImZpeGVkIikpDQoJDQoNCgl3LmVtbyA9IDENCgl3LmxvdyA9IDINCgl3LnNlbSA9IDAuNQ0KCQ0KCQ0KCXBybTIgPSBsaXN0KG4gPSBsaXN0KGVtbyA9IDQsICMgbnVtYmVyIG9mIGVtb3Rpb25hbCBjbHVzdGVycw0KCQkJCQkJCQkJCQkgc2VtID0gNSwgIyBudW1iZXIgb2Ygc2VtYW50aWMgY2x1c3RlcnMgDQoJCQkJCQkJCQkJCSBsb3cgPSAxMCwgIyBudW1iZXIgb2YgcGVyY2VwdHVhbCBjbHVzdGVycyANCgkJCQkJCQkJCQkJIHBhciA9IDMpLCAjIG51bWJlciBvZiBwYXJhbGxlbCBzZXRzIA0KCQkJCQkJCXcgPSBsaXN0KGVtbyA9IDEsc2VtID0gMC41LCBsb3cgPSAyKSwgIyB3ZWlnaHRzIG9mIGRpZmZlcmVudCBmZWF0dXJlcyBpbiB0aGUgYmFsYW5jaW5nIHByb2Nlc3MgKG5vdCBkaXJlY3RseSByZXByZXNlbnRhdGl2ZSkNCgkJCQkJCQlzZWVkID0gZGF0YS5mcmFtZShyb3cubmFtZXMgPSBjKCJudHIiLCAibG93IiwgIm1pZCIsICJoaWdoIiksICMgYWZmZWN0aXZlIHNlZWRzDQoJCQkJCQkJCQkJCQkJCQkJdmFsZW5jZSA9IGMoMC41LDAuMzUsMC4yNSwwLjEpLCANCgkJCQkJCQkJCQkJCQkJCQlhcm91c2FsID0gYygwLjEsMC4zLDAuNiwwLjkpKSwNCgkJCQkJCQlleHBvcnQgPSBUKQ0KCQ0KDQoJDQoJc291cmNlID0gInNtYWxsIiANCgkjIHNvdXJjZSA9ICJsYXJnZSINCgkNCglnZW5lcmF0ZSA9IFQNCiANCmBgYA0KDQojIElOVFJPRFVDVElPTg0KDQpHZW5lcmF0aW5nIGVtb3Rpb25hbCBzdGF0ZXMgaW4gdGhlIGxhYm9yYXRvcnkgY2FuIGJlIGNoYWxsZW5naW5nLiBNb3N0IGF2YWlsYWJsZSBtZXRob2RzIHJlcXVpcmUgcmVzZWFyY2hlcnMgdG8gY2hvb3NlIGJldHdlZW4gbWF4aW1pemluZyBlY29sb2dpY2FsIHZhbGlkaXR5IG9yIGV4cGVyaW1lbnRhbCByaWdvci4gQWZmZWN0aXZlIGltYWdlcyBzZWVtIHRvIG9mZmVyIGEgZGVzaXJhYmxlIGJhbGFuY2UgYmV0d2VlbiB0aGVzZSB2YWx1ZXMuIFJlc2VhcmNoZXJzIGFyZSB0aGVyZWZvcmUgZm9uZCBvZiBwdWJsaXNoZWQgZGF0YWJhc2VzIG9mIGltYWdlcyBhY2NvbXBhbmllZCB3aXRoIHN0YXRpc3RpY3MgaWxsdXN0cmF0aW5nIHRoZSBjb3JlIGFmZmVjdCBlYWNoIGltYWdlIGlzIGxpa2VseSB0byBlbGljaXQuIA0KDQpIb3dldmVyLCBjYXJlbGVzcyByZWxpYW5jZSBvZiBwaWN0dXJlIHNldHMgY29uc3RydWN0ZWQgdXNpbmcgbm9ybWF0aXZlIGFmZmVjdGl2ZSByYXRpbmdzIGNhbiBiZSByaXNreS4gSWRlYWxseSwgaW5kZXBlbmRlbnQgdmFyaWFibGVzIGNvbnN0cnVjdGVkIGZyb20gc3VjaCBkYXRhYmFzZXMgKGUuZy4sIGEgbmV1dHJhbCBhbmQgYSBuZWdhdGl2ZSBjb25kaXRpb24pIHNob3VsZCBiZSBpbmRlcGVuZGVudCBvZiBtYWpvciBub24tYWZmZWN0aXZlIHNvdXJjZXMgb2YgdmFyaWFuY2UgaW4gZGVwZW5kZW50IHZhcmlhYmxlcyAoZS5nLiwgc3ViamVjdGl2ZSwgYm9kaWx5LCBvciBicmFpbiByZXNwb25zZXMpLiBVbmZvcnR1bmF0ZWx5LCB0aGlzIGlkZWFsIGlzIG5vdCBndWFyYW50ZWVkIHdoZW4gc3RpbXVsdXMgc2V0cyBkZXNpZ25lZCB0byB2YXJ5IGluIGNvcmUgYWZmZWN0LiAqUHJvdmlkZSBldmRpbmNlIGhvdyBzZXRzIGJ1aWx0IG9uIHZhbGVuY2UgYW5kIGFyb3VzYWwgdGVuZCB0byBiZSBiaWFzZWQgb24gb3RoZXIgZmVhdHVyZXMgd2hpY2ggY2FuIGFmZmVjdCBmaW5kaW5ncy4qXQ0KDQpUaGUgcHJlc2VudCB3b3JrIGFpbXMgdG8gcHJvdmlkZSBhIHRvb2xraXQgZm9yIHJlc2VyYWNoZXJzIGludGVyZXN0ZWQgaW4gY3JlYXRpbmcgYmFsYW5jZWQgYWZmZWN0aXZlIHN0aW11bHVzIHNldHMuIEluIHBhcnRpY3VsYXIsIHdlIGhhdmUgd29ya2VkIGluIGZvdXIgaW50ZXItcmVsYXRlZCBhcmVhcy4NCg0KMS4gQ3JlYXRlZCBhIG1ldGEtZGF0YWJhc2Ugb2YgYWxsIHB1Ymxpc2hlZCBhZmZlY3RpdmUgaW1hZ2Ugc2V0czsgIA0KMi4gRXh0cmFjdGVkIHBlcmNlcHR1YWwgZmVhdHVyZXMgb2YgdGhlIGltYWdlcyBpbiB0aGUgbWV0YS1kYXRhYmFzZTsgIA0KMy4gRXh0cmFjdGVkIHNlbWFudGljIGZlYXR1cmVzIG9mIHRoZSBpbWFnZXMgaW4gdGhlIG1ldGEtZGF0YWJhc2U7ICANCjQuIENyZWF0ZWQgYW4gYWxnb3JpdGhtaWMgcGlwZWxpbmUgZm9yIGNvbXBpbGluZyBiYWxhbmNlZCBpbWFnZSBzZXRzLg0KDQojIE1FVEEtREFUQUJBU0UgDQoNCkhlcmUgYXJlIHRoZSBkYXRhYmFzZXMgdGhhdCBhcmUgaW5jbHVkZWQgaW4gdGhlIG1ldGEtZGF0YWJhc2UuIEJlbG93IGlzIGEgbW9yZSBkZXRhaWxlZCBsaXN0IHdpdGggZWFjaCBkYXRhYmFzZSBuYW1lLCBjaXRhdGlvbiwgd2ViIGxpbmssICMgb2YgcGljdHVyZXMsIHBpY3R1cmUgY2F0ZWdvcmllcywgbm9ybWF0aXZlIHJhdGluZ3MgY29tcGlsZWQgYnkgT2xhIEFiZGVsaGFkaS4NCg0KT25lIHRoaW5nIHRvIG5vdGUgb24gdGhpcyBmaWd1cmUgYXJlIHRoZSBkaWZmZXJlbnQgbm9ybWF0aXZlIHJhdGluZyBkaXN0cmlidXRpb25zIGJldHdlZW4gZGlmZmVyZW50IGRhdGFiYXNlcy4gV2hpbGUgc29tZSBvZiB0aGlzIHZhcmlhbmNlIGlzIGNhdXNlZCBieSBnZW51aW5lIGRpZmZlcmVuY2VzIGJldHdlZW4gcGljdHVyZXMsIHZpc3VhbCBpbnNwZWN0aW9uIG9mIHRoZSBpbWFnZXMgc3VnZ2VzdHMgdGhhdCB0aGVyZSBtYXkgYmUgc3lzdGVtYXRpYyBiaWFzZXMgcmF0aW5nIHNjYWxlIHBlcmZvcm1hbmNlIChldmVuIGFmdGVyIHdlIGhhdmUgY29udmVydGVkIGFsbCByYXRpbmdzIHRvIGEgY29tbW9uIHNjYWxlKS4gDQoNCmBgYHtyIHByZXBhcmUgZGF0YWJhc2UsIG1lc3NhZ2U9RiwgZWNobyA9IEYsIGZpZy5oZWlnaHQ9OCxmaWcud2lkdGg9MTR9DQoNCmlmKHNvdXJjZT09ImxhcmdlIil7DQoNCiMjIFdPUksgT04gQUZGRUNUSVZFIEZFQVRVUkUgVEFCTEUgIyMjIw0KDQojIGltcG9ydA0KCWEgPC0gcmVhZC5jc3YyKCJkYXRhYmFzZS9kYXRhYmFzZS5jc3YiKQ0KDQojIGZpeCBsYWJlbHMNCgljb2xuYW1lcyhhKVsxXSA9ICJpbWFnZUlEIg0KCWEkaW1hZ2VJRCA8LSBhcy5jaGFyYWN0ZXIodHJpbXdzKGEkaW1hZ2VJRCkpDQoJIyBhZGQgbGVhZGluZyAwLXMgdG8gc29tZSBuYW1lcw0KCWEkaW1hZ2VJRFthJFNldCA9PSAiRW1vUGljUyJdIDwtIHNhcHBseShhJGltYWdlSURbYSRTZXQgPT0gIkVtb1BpY1MiXSwgZnVuY3Rpb24oeCkgc3ByaW50ZigiJTAzZCIsIGFzLm51bWVyaWMoeCkpKQ0KCSMgTUFQUyBmaXhlcw0KCWEkaW1hZ2VJRFthJFNldCA9PSAiTUFQUyJdID0gcGFzdGUwKCJNQVBTIiwgYSRpbWFnZUlEW2EkU2V0PT0iTUFQUyJdKQ0KCWEkVmFsLk1bYSRTZXQgPT0gIk1BUFMiXSA9IGFwcGx5KGFbYSRTZXQgPT0gIk1BUFMiLCBjKCJWYWwuTS4uRmVtYWxlIiwiVmFsLk0uTWFsZSIpXSwxLG1lYW4pDQoJYSRBcm8uTVthJFNldCA9PSAiTUFQUyJdID0gYXBwbHkoYVthJFNldCA9PSAiTUFQUyIsIGMoIkFyby5NLkZlbWFsZSIsIkFyby5NLk1hbGUiKV0sMSxtZWFuKQ0KDQoJIyByZW1vdmUgZmlsZSBleHRlbnNpb25zIGZyb20gc29tZSBJRCBjb2Rlcw0KCWEkaW1hZ2VJRCA9IHVubGlzdChzYXBwbHkoYSRpbWFnZUlELCBmdW5jdGlvbih4KSBzdHJzcGxpdCh4LCJcXC4iKVtbMV1dWzFdKSkNCgkjIG1ha2UgYSB1bmlxdWUgSUQgY29kZSBieSBhZGRpbmcgc2V0IG5hbWUgdG8gcGljdHVyZSBuYW1lDQoJYSRJRCA8LSBpZmVsc2UoYSRTZXQ9PSJPQVNJUyIsDQoJCQkJCQkJIAlwYXN0ZTAoYSRTZXQsIl8iLCBhJERlc2NyaXB0aW9uKSwNCgkJCQkJCQkgCXBhc3RlMChhJFNldCwiXyIsIGEkaW1hZ2VJRCkpDQoNCiMgcHJ1bmUNCgkjIHN0YXJ0IGEgbWV0YWRhdGEgdGFibGUNCgltZXRhID0gZGF0YS5mcmFtZShyb3cubmFtZXMgPSAiYWZmZWN0aXZlIiwgc3RhcnRfd2l0aCA9IGRpbShhKVsxXSkNCgkjIHJlbW92ZSBkdXBsaWNhdGVzDQoJbWV0YSRkdXBsaWNhdGVzID0gc3VtKGR1cGxpY2F0ZWQoYSRJRCkpDQoJYSA8LSBhWyFkdXBsaWNhdGVkKGEkSUQpLF0NCgkjIHJlbW92ZSBwaWN0dXJlcyB3aXRob3V0IHJhdGluZ3MNCgltZXRhJG5vX3JhdGluZyA9IHN1bShpcy5uYShhJFZhbC5NKSB8IGlzLm5hKGEkQXJvLk0pKQ0KCWEgPC0gYVshKGlzLm5hKGEkVmFsLk0pIHwgaXMubmEoYSRBcm8uTSkpLF0NCg0KIyBzdGFuZGFyZGl6ZSByYXRpbmdzIHdpdGhpbiBwaWN0dXJlIHNldA0KCXNjIDwtIHJiaW5kKGRhdGEuZnJhbWUoc2V0ID0gIklBUFMiLCBtaW4gPSAxLCBtYXggPSA5KSwNCgkJCQlkYXRhLmZyYW1lKHNldCA9ICJHQVBFRCIsIG1pbiA9IDAsIG1heCA9IDEwMCksDQoJCQkJZGF0YS5mcmFtZShzZXQgPSAiTkFQUyIsIG1pbiA9IDEsIG1heCA9IDkpLA0KCQkJCWRhdGEuZnJhbWUoc2V0ID0gIk5BUFMtU0ZJUCIsIG1pbiA9IDEsIG1heCA9IDkpLA0KCQkJCWRhdGEuZnJhbWUoc2V0ID0gIk5BUFMtRVJPIiwgbWluID0gMSwgbWF4ID0gOSksDQoJCQkJZGF0YS5mcmFtZShzZXQgPSAiT0FTSVMiLCBtaW4gPSAxLCBtYXggPSA3KSwNCgkJCQlkYXRhLmZyYW1lKHNldCA9ICJFbW9QaWNTIiwgbWluID0gMSwgbWF4ID0gOSksDQoJCQkJZGF0YS5mcmFtZShzZXQgPSAiRW1vTWFkcmlkIiwgbWluID0gLTIsIG1heCA9IDIpLA0KCQkJCWRhdGEuZnJhbWUoc2V0ID0gIk1BUFMiLCBtaW4gPSAxLCBtYXggPSA5KSwNCgkJCQlkYXRhLmZyYW1lKHNldCA9ICJJU0VFIiwgbWluID0gMSwgbWF4ID0gNyksDQoJCQkJZGF0YS5mcmFtZShzZXQgPSAiT0xBRiIsIG1pbiA9IDEsIG1heCA9IDkpLA0KCQkJCWRhdGEuZnJhbWUoc2V0ID0gIkRJUlRJIiwgbWluID0gMSwgbWF4ID0gOSksDQoJCQkJZGF0YS5mcmFtZShzZXQgPSAiU0JFUiIsIG1pbiA9IDEsIG1heCA9IDkpKQ0KDQoJIyByZS1zY2FsZXMgdGhlIGFmZmVjdGl2ZSBzY2FsZXMNCglhJHZhbGVuY2UgPC0gKGEkVmFsLk0tc2MkbWluW21hdGNoKGEkU2V0LHNjJHNldCldKS8oc2MkbWF4W21hdGNoKGEkU2V0LHNjJHNldCldLXNjJG1pblttYXRjaChhJFNldCxzYyRzZXQpXSkNCglhJGFyb3VzYWwgPC0gKGEkQXJvLk0tc2MkbWluW21hdGNoKGEkU2V0LHNjJHNldCldKS8oc2MkbWF4W21hdGNoKGEkU2V0LHNjJHNldCldLXNjJG1pblttYXRjaChhJFNldCxzYyRzZXQpXSkNCgkjIGNvbXB1dGUgYSB1bmlkaW1lbnNpb25hbCBhY3RpdmF0aW9uIG1lYXN1cmUgZnJvbSB2YWxlbmNlIGFuZCBhcm91c2FsDQoJYSRhY3RpdmF0aW9uID0gaWZlbHNlKGEkdmFsZW5jZTwwLjUsYSR2YWxlbmNlLWEkYXJvdXNhbCxhJHZhbGVuY2UrYSRhcm91c2FsKQ0KDQojIyBXT1JLIFdJVEggTE9XLUxFVkVMIEZFQVRVUkVTIFRBQkxFICMjIyMNCg0KIyBpbXBvcnQNCgliIDwtIHJlYWQuY3N2MigibG93IGxldmVsL2xvd2xldmVsLmNzdiIpDQoJbmFtZXMoYilbMV0gPC0gIlNldCINCg0KIyBsYWJlbHMNCgkjIG1ha2UgYW4gZXF1aXZhbGVudCBJRC1jb2RlDQoJYiRpbWFnZUZpbGUgPC0gYiRpbWFnZUlEDQoJIyByZW1vdmUgcmVtYWluaW5nIGZpbGUgZXh0ZW5zaW9ucw0KCWIkaW1hZ2VJRCA9IHVubGlzdChzYXBwbHkoYXMuY2hhcmFjdGVyKGIkaW1hZ2VJRCksIGZ1bmN0aW9uKHgpIHN0cnNwbGl0KHgsIlxcLiIpW1sxXV1bMV0pKQ0KCWIkSUQgPC0gcGFzdGUwKGIkU2V0LCJfIiwgYiRpbWFnZUlEKQ0KDQojIHBydW5lDQoJbWV0YVsyLCJzdGFydF93aXRoIl0gPSBkaW0oYilbMV0NCglyb3duYW1lcyhtZXRhKVsyXSA9ICJsb3ctbGV2ZWwiDQoJbWV0YSRkdXBsaWNhdGVzWzJdID0gc3VtKGR1cGxpY2F0ZWQoYiRJRCkpDQoJIyByZW1vdmUgZHVwbGljYXRlcyBiYXNlZCBvbiBJRCBjb2RlDQoJYiA8LSBiWyFkdXBsaWNhdGVkKGIkSUQpLF0NCgkjIHJlbW92ZSBkdXBsaWNhdGVzIGJhc2VkIG9uIGltYWdlIHN0YXRpc3RpY3MNCgliIDwtIGJbIWR1cGxpY2F0ZWQoYlssYyhncmVwKCJsdW1pbmFuY2UiLG5hbWVzKGIpKSwgZ3JlcCgiYmx1ZVllbGxvdyIsbmFtZXMoYikpLCBncmVwKCJncmVlblJlZCIsbmFtZXMoYikpLCBncmVwKCJzcGVjdHJ1bV9yYXZnIixuYW1lcyhiKSkpXSksXQ0KDQoNCiMgYW5hbHl6ZSBtaXNzaW5nIGRhdGENCgkjIGNoZWNrIHdoaWNoIGRhdGFiYXNlcyBoYXZlIHByb2JsZW1zIG1lcmdpbmcNCglub0ZpbGUgPC0gc2V0ZGlmZih1bmlxdWUoYSRJRCksdW5pcXVlKGIkSUQpKQ0KCW5vRGF0YSA8LSBzZXRkaWZmKHVuaXF1ZShiJElEKSx1bmlxdWUoYSRJRCkpDQoNCgltZXRhJG5vX21hdGNoX2luX290aGVyID0gYyhsZW5ndGgobm9GaWxlKSxsZW5ndGgobm9EYXRhKSkNCg0KIyMgTUVSR0UgREFUQVNFVFMgIyMjIw0KCWQgPSBpbm5lcl9qb2luKGEsYlssc2V0ZGlmZihuYW1lcyhiKSxjKCJTZXQiLCAiaW1hZ2VJRCIpKV0sIklEIikNCgltZXRhWzMsInN0YXJ0X3dpdGgiXSA9IGRpbShkKVsxXQ0KCXJvd25hbWVzKG1ldGEpWzNdID0gIm1lcmdlZCINCg0KIyBsYWJlbHMNCgkjIGNsZWFuIGRlc2NyaXB0b2lvbiBsYWJsZXMNCglkJERlc2NyaXB0aW9uIDwtIGFzLmNoYXJhY3RlcihkJERlc2NyaXB0aW9uKQ0KCWQkRGVzY3JpcHRpb24gPC0gZ3N1YigiWzAtOV0rIiwiIixkJERlc2NyaXB0aW9uKQ0KDQoJIyBjbGVhbiBjYXRlZ29yeSBsYWJlbHMNCglkJENhdGVnb3J5IDwtIGFzLmNoYXJhY3RlcihkJENhdGVnb3J5KQ0KCWQkQ2F0ZWdvcnlbZCRTZXQ9PSJPTEFGIl0gPC0gIkZvb2QiDQoNCg0KIyBjb21wdXRlIGFkZGl0aW9uYWwgdmFyaWFibGVzDQoJIyBzdW1tYXJpemUgb3JpZW5hdGlvbiBmZWF0dXJlcw0KCWQkZG9taW5hbnRBbmdsZSA9IGFwcGx5KGRbLGMoInNsb3BlX05TIiwgInNsb3BlX05XIiwgInNsb3BlX1dFIiwgInNsb3BlX05FIildLDEsZnVuY3Rpb24oeCkgb3JkZXIoeCxkZWNyZWFzaW5nPVQpWzFdKQ0KCWQkYW5nbGVWYXJpYW5jZSA9IGFwcGx5KGRbLGMoInNsb3BlX05TIiwgInNsb3BlX05XIiwgInNsb3BlX1dFIiwgInNsb3BlX05FIildLDEsZnVuY3Rpb24oeCkgc2QoeCkpDQoNCg0KIyBwbG90IGFmZmVjdGl2ZSByYXRpbmdzDQoJZCRTZXR3TiA9IHVuc3BsaXQoc2FwcGx5KHNwbGl0KGQsZCRTZXQpLGZ1bmN0aW9uKHgpIHBhc3RlMCh4JFNldCwgIlxubj0iLG5yb3coeCksIiIpKSxkJFNldCkNCglnZ3Bsb3QoZCxhZXMoeD12YWxlbmNlLCB5ID0gYXJvdXNhbCwgY29sb3IgPSBTZXR3TikpICsgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKyBwbHQgKyBmYWNldF93cmFwKH5TZXR3TikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCgkJbGFicyh0aXRsZSA9ICJJbnB1dCBwaWN0dXJlIHNldHMiLCBzdWJ0aXRsZSA9IHBhc3RlMCgibj0gIixucm93KGQpKSkNCg0KfQ0KYGBgDQoNCg0KWypJbnRlcm5hdGlvbmFsIEFmZmVjdGl2ZSBQaWN0dXJlIFN5c3RlbSAoSUFQUykqXShodHRwOi8vY3NlYS5waGhwLnVmbC5lZHUvTWVkaWEuaHRtbCN0b3BtZWRpYSkgDQoNCiogTGFuZywgUC5KLiwgQnJhZGxleSwgTS5NLiwgJiBDdXRoYmVydCwgQi5OLiAoMjAwOCkuIEludGVybmF0aW9uYWwgYWZmZWN0aXZlIHBpY3R1cmUgc3lzdGVtIChJQVBTKTogQWZmZWN0aXZlIHJhdGluZ3Mgb2YgcGljdHVyZXMgYW5kIGluc3RydWN0aW9uIG1hbnVhbC4gVGVjaG5pY2FsIFJlcG9ydCBBLTguIFVuaXZlcnNpdHkgb2YgRmxvcmlkYSwgR2FpbmVzdmlsbGUsIEZMLg0KKiBQaWN0dXJlczogMTE5Ng0KKiBDYXRlZ29yaWVzOiBNdWx0aXBsZSwgZnJvbSBmdXJuaXR1cmUgdG8gY29tcGxldGUgc2NlbmUsIHdpZGUgcmFuZ2Ugb2Ygc2VtYW50aWMgY2F0ZWdvcmllcy4NCiogTm9ybWF0aXZlIHJhdGluZ3M6IFZhbGVuY2UsIGFyb3VzYWwsIGFuZCBkb21pbmFuY2UNCg0KWypHZW5ldmEgYWZmZWN0aXZlIHBpY3R1cmUgZGF0YWJhc2UgKEdBUEVEKSpdKGh0dHA6Ly93d3cuYWZmZWN0aXZlLXNjaWVuY2VzLm9yZy9lbi9ob21lL3Jlc2VhcmNoL21hdGVyaWFscy1hbmQtb25saW5lLXJlc2VhcmNoL3Jlc2VhcmNoLW1hdGVyaWFsLykNCg0KKiBEYW4tR2xhdXNlciwgRS4gUy4sICYgU2NoZXJlciwgSy4gUi4gKDIwMTEpLiBUaGUgR2VuZXZhIGFmZmVjdGl2ZSBwaWN0dXJlIGRhdGFiYXNlIChHQVBFRCk6IGEgbmV3IDczMC1waWN0dXJlIGRhdGFiYXNlIGZvY3VzaW5nIG9uIHZhbGVuY2UgYW5kIG5vcm1hdGl2ZSBzaWduaWZpY2FuY2UuIEJlaGF2aW9yIFJlc2VhcmNoIE1ldGhvZHMsIDQzKDIpLCA0NjgtNDc3LiBkb2k6IDEwLjM3NTgvczEzNDI4LTAxMS0wMDY0LTENCiogUGljdHVyZXM6IDczMA0KKiBDYXRlZ29yaWVzOiBzcGlkZXJzLCBzbmFrZXMsIGFuZCBzY2VuZXMgdGhhdCBpbmR1Y2UgZW1vdGlvbnMgcmVsYXRlZCB0byB0aGUgdmlvbGF0aW9uIG9mIG1vcmFsIGFuZCBsZWdhbCBub3JtcyAoaHVtYW4gcmlnaHRzIHZpb2xhdGlvbiBvciBhbmltYWwgbWlzdHJlYXRtZW50KS4gUG9zaXRpdmUgYW5kIG5ldXRyYWwgcGljdHVyZXMgd2VyZSBhbHNvIGluY2x1ZGVkLg0KKiBOb3JtYXRpdmUgcmF0aW5nczogVmFsZW5jZSwgQXJvdXNhbCwgZXh0ZXJuYWwgbm9ybSBhbmQgaW50ZXJuYWwgbm9ybS4NCg0KWypOZW5ja2kgQWZmZWN0aXZlIFBpY3R1cmUgU3lzdGVtIChOQVBTKSpdKGh0dHA6Ly9sb2JpLm5lbmNraS5nb3YucGwvcmVzZWFyY2gvOC8pDQoNCiogTWFyY2hld2thLCBBLiwgWnVyYXdza2ksIEwuLCBKZWRub3LzZywgSy4sICYgR3JhYm93c2thLCBBLiAoMjAxNCkuIFRoZSBOZW5ja2kgQWZmZWN0aXZlIFBpY3R1cmUgU3lzdGVtIChOQVBTKTogSW50cm9kdWN0aW9uIHRvIGEgbm92ZWwsIHN0YW5kYXJkaXplZCwgd2lkZS1yYW5nZSwgaGlnaC1xdWFsaXR5LCByZWFsaXN0aWMgcGljdHVyZSBkYXRhYmFzZS4gQmVoYXZpb3IgcmVzZWFyY2ggbWV0aG9kcywgNDYoMiksIDU5Ni02MTAuDQoqIFBpY3R1cmVzOiAxMzU2DQoqIENhdGVnb3JpZXM6IHBlb3BsZSwgZmFjZXMsIGFuaW1hbHMsIG9iamVjdHMsIGFuZCBsYW5kc2NhcGVzDQoqIE5vcm1hdGl2ZSByYXRpbmdzOiBWYWxlbmNlIGFuZCBhcm91c2FsDQoNClsqRXJvdGljIHN1YnNldCBvZiBOZW5ja2kgQWZmZWN0aXZlIFBpY3R1cmUgU3lzdGVtIChOQVBTLUVSTykqXShodHRwOi8vbG9iaS5uZW5ja2kuZ292LnBsL3Jlc2VhcmNoLzgvKQ0KDQoqIFdpZXJ6YmEsIE0uLCBSaWVnZWwsIE0uLCBQdWN6LCBBLiwgTGVzbmlld3NrYSwgWi4sIERyYWdhbiwgVy4gTC4sIEdvbGEsIE0uLCAuLi4gJiBNYXJjaGV3a2EsIEEuICgyMDE1KS4gRXJvdGljIHN1YnNldCBmb3IgdGhlIE5lbmNraSBBZmZlY3RpdmUgUGljdHVyZSBTeXN0ZW0gKE5BUFMgRVJPKTogY3Jvc3Mtc2V4dWFsIGNvbXBhcmlzb24gc3R1ZHkuIEZyb250aWVycyBpbiBwc3ljaG9sb2d5LCA2LCAxMzM2Lg0KKiBQaWN0dXJlczogMjAwDQoqIENhdGVnb3JpZXM6IG9wcG9zaXRlLXNleCBjb3VwbGUgKDUwKSwgbWFsZSBjb3VwbGUgKDUwKSwgZmVtYWxlIGNvdXBsZSAoNTApLCBtYWxlICgyNSkgYW5kIGZlbWFsZSAoMjUpDQoNCiogTm9ybWF0aXZlIHJhdGluZ3M6IFZhbGVuY2UgYW5kIGFyb3VzYWwNCg0KWypTZXQgb2YgRmVhciBJbmR1Y2luZyBQaWN0dXJlcyAoTkFQUy1TRklQKSpdKGh0dHA6Ly9sb2JpLm5lbmNraS5nb3YucGwvcmVzZWFyY2gvOC8pDQoNCiogTWljaGFsb3dza2ksIEouIE0uLCBEcm96ZHppZWwsIEQuLCBNYXR1c3pld3NraSwgSi4sIEtvemllam93c2tpLCBXLiwgSmVkbm9y82csIEsuLCAmIE1hcmNoZXdrYSwgQS4gKDIwMTYpLiBUaGUgU2V0IG9mIEZlYXIgSW5kdWNpbmcgUGljdHVyZXMgKFNGSVApOiBEZXZlbG9wbWVudCBhbmQgdmFsaWRhdGlvbiBpbiBmZWFyZnVsIGFuZCBub25mZWFyZnVsIGluZGl2aWR1YWxzLiBCZWhhdmlvciBSZXNlYXJjaCBNZXRob2RzLCAxLTEzLg0KKiBQaWN0dXJlczogODg2DQoqIENhdGVnb3JpZXM6IFNwaWRlcnMsIGJ1Z3MsIGJsb29kIGluamVjdGlvbiwgZmVhcmZ1bCBzb2NpYWwgZXhwb3N1cmUsIGFuZ3J5IGZhY2VzDQoqIE5vcm1hdGl2ZSByYXRpbmdzOiBGZWFyLCBhcm91c2FsIGFuZCB2YWxlbmNlDQoNClsqT3BlbiBBZmZlY3RpdmUgU3RhbmRhcmRpemVkIEltYWdlIFNldCAoT0FTSVMpKl0oaHR0cDovL3d3dy5iZW5lZGVra3VyZGkuY29tLyUyM29hc2lzIyFwb3J0Zm9saW8vcHJvamVjdC01Lmh0bWwpDQoNCiogS3VyZGksIEIuLCBMb3phbm8sIFMuLCAmIEJhbmFqaSwgTS4gUi4gKDIwMTYpLiBJbnRyb2R1Y2luZyB0aGUgT3BlbiBBZmZlY3RpdmUgU3RhbmRhcmRpemVkIEltYWdlIFNldCAoT0FTSVMpLiBCZWhhdmlvciByZXNlYXJjaCBtZXRob2RzLCAxLTE0Lg0KKiBQaWN0dXJlczogOTAwIA0KKiBDYXRlZ29yaWVzOiBBbmltYWwsIE9iamVjdCwgUGVyc29uLCBTY2VuZXJ5DQoqIE5vcm1hdGl2ZSByYXRpbmdzOiBWYWxlbmNlIGFuZCBhcm91c2FsDQoNClsqRW1vdGlvbmFsIFBpY3R1cmUgU3lzdGVtIChFbW9QaWNTKSpdKGh0dHBzOi8vd3d3LmtsaW5pc2NoZS1wc3ljaG9sb2dpZS11bmQtbmV1cm9wc3ljaG9sb2dpZS51bmktbWFpbnouZGUvZm9yc2NodW5nL2Vtb3BpY3MvKQ0KDQoqIFdlc3NhLCBNLiwgS2Fuc2tlLCBQLiwgTmV1bWVpc3RlciwgUC4sIEJvZGUsIEsuLCBIZWlzc2xlciwgSi4sICYgU2No9m5mZWxkZXIsIFMuICgyMDEwKS4gRW1vUGljczogU3ViamVjdGl2ZSBhbmQgcHN5Y2hvcGh5c2lvbG9naWNhbCBldmFsdWF0aW9ucyBvZiBuZXcgaW1hZ2luZyBtYXRlcmlhbCBmb3IgY2xpbmljYWwtYmlvLXBzeWNob2xvZ2ljYWwgcmVzZWFyY2guIEpvdXJuYWwgb2YgQ2xpbmljYWwgUHN5Y2hvbG9neSBhbmQgUHN5Y2hvdGhlcmFweSwgU3VwcGxlbWVudCwgMS8xMSwgNzcuDQoqIFBpY3R1cmVzOiAzNzgNCiogQ2F0ZWdvcmllczogRGl2ZXJzZSBzb2NpYWwgc2l0dWF0aW9ucyBhbmltYWxzLCBhbmQgcGxhbnRzDQoqIE5vcm1hdGl2ZSByYXRpbmdzOiBWYWxlbmNlLCBleGNpdGVtZW50IGFuZCBjb21wbGV4aXR5DQoNClsqQmVzYW7nb24gQWZmZWN0aXZlIFBpY3R1cmUgU2V0LUFkb2xlc2NlbnRzIChUaGUgQkFQUy1BZG8pPSBUaGUgQXR0YWNobWVudCBQaWN0dXJlIERhdGFiYXNlIChBUEQpKl0oaHR0cDovL25ldXJvc2NpZW5jZXMudW5pdi1mY29tdGUuZnIvcGFnZXMvZnIvbWVudTQ3NjEvb3V0aWxzL2FwZC5vbGQtMTc0OTkuaHRtbCkNCg0KKiBTenltYW5za2EsIE0uLCBNb25uaW4sIEouLCBOb2lyZXQsIE4uLCBUaW8sIEcuLCBHYWxkb24sIEwuLCBMYXVyZW50LCBFLiwgLi4uICYgVnVsbGllei1Db2FkeSwgTC4gKDIwMTUpLiBUaGUgQmVzYW7nb24gQWZmZWN0aXZlIFBpY3R1cmUgU2V0LUFkb2xlc2NlbnRzICh0aGUgQkFQUy1BZG8pOiBEZXZlbG9wbWVudCBhbmQgdmFsaWRhdGlvbi4gUHN5Y2hpYXRyeSByZXNlYXJjaCwgMjI4KDMpLCA1NzYtNTg0Lg0KKiBQaWN0dXJlczogOTMNCiogQ2F0ZWdvcmllczogRGlzdHJlc3MsIGNvbWZvcnQsIGpveS1jb21wbGljaXR5IGFuZCBuZXV0cmFsDQoqIE5vcm1hdGl2ZSByYXRpbmdzOiBWYWxlbmNlLCBBcm91c2FsIGFuZCBkb21pbmFuY2UNCg0KWypFbW9NYWRyaWQgZW1vdGlvbmFsIHBpY3R1cmVzIGRhdGFiYXNlKl0oaHR0cDovL3d3dy51YW0uZXMvZ3J1cG9zaW52L2NlYWNvL0Vtb01hZHJpZC5odG0pDQoNCiogRW1vTWFkcmlkIGFmZmVjdGl2ZSBwaWN0dXJlIGRhdGFiYXNlIChodHRwOi8vd3d3LnVhbS5lcy9DRUFDTy9FbW9NYWRyaWQuaHRtKQ0KKiBQaWN0dXJlczogNzAwDQoqIENhdGVnb3JpZXM6IA0KKiBOb3JtYXRpdmUgcmF0aW5nczogVmFsZW5jZSBhbmQgYXJvdXNhbA0KDQpbKk1pbGl0YXJ5IEFmZmVjdGl2ZSBQaWN0dXJlIFN5c3RlbSAoTUFQUykqXShodHRwczovL2NsYS5hdWJ1cm4uZWR1L3BzeWNob2xvZ3kvbWlsaXRhcnktYWZmZWN0aXZlLXBpY3R1cmUtc3lzdGVtLykNCg0KKiBEcmV0c2NoLCBNLiwgVGhpZWwsIEsuLCBCb3JuLCBTLiwgR29vZG1hbiwgQS4gTS4sICYgS2F0eiwgSi5TLiAoMjAxMykuIE1pbGl0YXJ5IEFmZmVjdGl2ZSBQaWN0dXJlIFN5c3RlbSAoTUFQUykgW1BpY3R1cmUgUmVwb3NpdG9yeV0uIFVucHVibGlzaGVkIGluc3RydW1lbnQuIEF1YnVybiBVbml2ZXJzaXR5Lg0KKiBQaWN0dXJlczogMjQwICANCiogQ2F0ZWdvcmllczogTWlsaXRhcnkNCiogTm9ybWF0aXZlIHJhdGluZ3M6IFZhbGVuY2UsIGRvbWluYW5jZSwgYW5kIGFyb3VzYWwNCg0KWypJbWFnZSBTdGltdWxpIGZvciBFbW90aW9uIEVsaWNpdGF0aW9uIChJU0VFKSpdKGh0dHA6Ly9pbmZvbGFiLnN0YW5mb3JkLmVkdS9+d2FuZ3ovcHJvamVjdC9pbXNlYXJjaC9BZXN0aGV0aWNzL0FQUzE1LykNCg0KKiBIYW5qb28gS2ltLCBYaW4gTHUsIE1pY2hhZWwgQ29zdGEsIEJhcmlzIEthbmRlbWlyLCBSZWdpbmFsZCBCLiBBZGFtcywgSnIuLCBKaWEgTGksIEphbWVzIFouIFdhbmcgYW5kIE1pY2hlbGxlIEcuIE5ld21hbiwgYGBEZXZlbG9wbWVudCBhbmQgVmFsaWRhdGlvbiBvZiB0aGUgSW1hZ2UgU3RpbXVsaSBmb3IgRW1vdGlvbiBFbGljaXRhdGlvbiAoSVNFRSksJycgQXNzb2NpYXRpb24gZm9yIFBzeWNob2xvZ2ljYWwgU2NpZW5jZSBBbm51YWwgQ29udmVudGlvbiwgcG9zdGVyLCBOZXcgWW9yayBDaXR5LCBNYXkgMjAxNS4gDQoqIFBpY3R1cmVzOiAxMCA2OTYNCiogQ2F0ZWdvcmllczogUGljdHVyZXMgd2l0aCBlbW90aW9uYWwgbGFiZWwgYW5kIGNhdGVnb3JpemF0aW9uIGZyb20gRmxpY2tyDQoqIE5vcm1hdGl2ZSByYXRpbmdzOiB2YWxlbmNlLCBhcm91c2FsLCBkb21pbmFuY2UsIGFuZCBsaWtlbmVzcw0KDQpbKk9wZW4gTGlicmFyeSBvZiBBZmZlY3RpdmUgRm9vZCAoT0xBRikqXShodHRwOi8vaGRsLmhhbmRsZS5uZXQvMTA0ODEvNDE0OTkpDQoNCiogTWljY29saSwgTC4sIERlbGdhZG8sIFIuLCBHdWVycmEsIFAuLCBWZXJzYWNlLCBGLiwgUm9kcu1ndWV6LCBTLiwgJiBGZXJu4W5kZXotU2FudGFlbGxhLCBNLkMuICgyMDE2KS4gIkFmZmVjdGl2ZSBQaWN0dXJlcyBhbmQgdGhlIE9wZW4gTGlicmFyeSBvZiBBZmZlY3RpdmUgRm9vZHMgKE9MQUYpOiBUb29scyB0byBJbnZlc3RpZ2F0ZSBFbW90aW9ucyB0b3dhcmQgRm9vZCBpbiBBZHVsdHMuIi4gUExPUyBPTkUsIERPSSAxMC4xMzcxL2pvdXJuYWwucG9uZS4wMTU4OTkxDQoqIFBpY3R1cmVzOiA5NQ0KKiBDYXRlZ29yaWVzOiBGb29kDQoqIE5vcm1hdGl2ZSByYXRpbmdzOiBwbGVhc3VyZSwgYXJvdXNhbCwgZG9taW5hbmNlLCBhbmQgZm9vZCBjcmF2aW5nDQoNClsqVGhlIERJc2d1c3QtUmVsYVRlZC1JbWFnZXMgKERJUlRJKSpdKGh0dHBzOi8vemVub2RvLm9yZy9yZWNvcmQvMTY3MDM3Iy5XTFN2V1JMeXRvNCkNCg0KKiBIYWJlcmthbXAsIEEuLCBHbG9tYmlld3NraSwgSi4gQS4sIFNjaG1pZHQsIEYuLCAmIEJhcmtlLCBBLiAoMjAxNykuIFRoZSBESXNndXN0LVJlbGFUZWQtSW1hZ2VzIChESVJUSSkgZGF0YWJhc2U6IFZhbGlkYXRpb24gb2YgYSBub3ZlbCBzdGFuZGFyZGl6ZWQgc2V0IG9mIGRpc2d1c3QgcGljdHVyZXMuIEJlaGF2aW91ciBSZXNlYXJjaCBhbmQgVGhlcmFweSwgODksIDg2LTk0Lg0KKiBQaWN0dXJlczogMjQwDQoqIENhdGVnb3JpZXM6IGZvb2QsIGFuaW1hbHMsIGJvZHkgcHJvZHVjdHMsIGluanVyaWVzL2luZmVjdGlvbnMsIGRlYXRoLCBhbmQgaHlnaWVuZSANCiogTm9ybWF0aXZlIHJhdGluZ3M6IGRpc2d1c3QsIGZlYXIsIHZhbGVuY2UsIGFuZCBhcm91c2FsLiANCg0KDQojIFBFUkNFUFRVQUwgRkVBVFVSRVMgDQoNCldlIHByb3ZpZGUgW2EgTWF0bGFiIHNjcmlwdF0oaHR0cHM6Ly9kcml2ZS5nb29nbGUuY29tL29wZW4/aWQ9MEI4RHp5clh1aE00LWQxUmpSV1o0U21KblUxVSkgZm9yIGV4dHJhY3Rpbmcga2V5IGltYWdlIHN0YXRpc3RpY3MgdGhhdCBjYW4gYmUgdXNlZCB0byBhc3Nlc3MgdGhlIHBlcmNlcHR1YWwgaG9tb2dlbmlldHkgb2YgZXhwZXJpbWVudGFsIHN0aW11bHVzIHNldHMuDQoNCldlIHNlbGVjdGVkIGEgc21hbGwgc2V0IG9mIHByZWNlcHR1YWwgZmVhdHVyZXMgYmFzZWQgb24gYWR2YW5jZXMgaW4gcmVsYXRpbmcgaW1hZ2Ugc3RhdGlzdGljcyB0byBjb3JlIHByaW5jaXBsZXMgb2YgcHJpbWF0ZSBwZXJjZXB0aW9uLiBTcGVjaWZpY2FsbHksIHdlIGNvbXB1dGVkIGFnZ3JlZ2F0ZSBzdGF0aXN0aWNzIG9mIHZpc3VhbCBpbmZvcm1hdGlvbiBvbiB0d28gbGV2ZWxzOiANCg0KKiBub24tc3BhdGlhbCBkaXN0cmlidXRpb24gb2YgbHVtaW5hbmNlIGFuZCBjb2xvcg0KKiBzcGF0aWFsIG9yZ2FuaXphdGlvbiBvZiBsdW1pbmFuY2UuICANCg0KIyMgTm9uLXNwYXRpYWwgZGlzdHJpYnV0aW9uIG9mIGx1bWluYW5jZSBhbmQgY29sb3IgDQpXZSBmaXJzdCBjb252ZXJ0ZWQgZWFjaCBwaWN0dXJzIHRvIHRoZSBDSUUgTGFiIGNvbG9yIHNwYWNlIHRvIHNlcGFyYXRlIGx1bWluYW5jZSBmcm9tIGNvbG9yIGluZm9ybWF0aW9uLiBUaGUgQ0lFIGNvbG9yIHNwYWNlIGNoYXJhY3Rlcml6ZXMgZWFjaCBwaXhlbCBvZiBhbiBpbWFnZSB3aXRoIHRocmVlIGZlYXR1cmVzOiBpdHMgbG9jYXRpb24gb24gYSBsdW1pbmFuY2UsIGEgYmx1ZS15ZWxsb3csIGFuZCBhIHJlZC1ncmVlbiBkaW1lbnNpb24uIA0KDQpTZXBhcmF0aW5nIGx1bWluYW5jZSBpbmZvcm1hdGlvbiBmcm9tIGNvbG9yIGNvcnJlc3BvbmRzIHRvIGZ1bmN0aW9uYWwgc3BjaWFsaXphdGlvbiBpbiB0aGUgYnJhaW4gd2hlcmUgbWFueSBwZXJjZXB0dWFsIGNvbXB1dGF0aW9ucyBhcmUgbWFpbmx5IHNlbnNpdGl2ZSB0byBsdW1pbmFuY2UuIFRoZSBjaGFyYWN0ZXJpemF0aW9uIG9mIGNvbG9yIHVzaW5nIGJsdWUteWVsbG93IGFuZCByZWQtZ3JlZW4gZGltZW5zaW9ucyBjb3JyZXNwb25kcyB0byBib3RoIHRoZSBwcmluY2lwYWwgY29tcG9uZW50cyB0aGF0ICBleHBsYWluIGxhcmdlIGFtb3VudHMgb2YgbmF0dXJhbGx5IG9jY3VyaW5nIGNvbG9yIHZhcmlhbmNlLCBhcyB3ZWxsIGFzIHRvIHRoZSBzZW5pc3Rpdml0eSBjdXJ2ZXMgb2YgYmlwb2xhciBjb2xvci1zZW5zaXRpdmUgY2VsbHMgaW4gdGhlIHByaW1hdGUgdmlzdWFsIHN5c3RlbS4NCg0KVG8gZWZmaWNpZW50bHkgY2FwdHVyZSB0aGUgbm9uLXNwYXRpYWwgZGlzdHJpYnV0aW9uIG9mIHBpeGVsIHZhbHVlcyBhbG9uZyB0aGVzZSBkaW1lbnNpb25zLCB3ZSBjb21wdXRlZCB0aGUgZmlyc3QgZm91ciBzdGF0aXN0aWNhbCBtb21lbnRzIG9mIHRoZXNlIGRpc3RyaWJ1dGlvbnM6IG1lYW4sIHN0YW5kYXJkIGRldmlhdGlvbiwgc2tld25lc3MsIGFuZCBrdXJ0b3Npcy4gTm90ZSB0aGF0IG1lYW4gbHVtaW5hbmNlIGNvcnJlc3BvbmRzIHRvIGJyaWdodG5lc3MgYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBsdW1pbmFuY2UgY29ycmVzcG9uZHMgdG8gY29udHJhc3QuDQoNCiMjIFNwYXRpYWwgb3JnYW5pemF0aW9uIG9mIGx1bWluYW5jZQ0KU3BhdGlhbCBvcmdhbml6YXRpb24gb2YgbHVtaW5hbmNlIGluZm9ybWF0aW9uIGlzIGEgY3J1aWNhbCBpbnB1dCB0byBwZXJjZXB0aW9uIG9mIGJhc2ljIHF1YWxpYSBzdWNoIGFzIG9yaWVudGF0aW9uLCB0ZXh0dXJlLCBtb3ZlbWVudCwgYW5kIHNoYXBlLiBBIHVzZWZ1bCBtZXRob2QgZm9yIG51bWVyaWNhbGx5IHJlcHJlc2VudGluZyB0aGlzIGluZm9ybWF0aW9uIGlzIHNwYXRpYWwgZnJlcXVlbmN5IGFuYWx5c2lzLiBXZSB0aGVyZWZvcmUgdXNlZCB0aGUgMkQgRmFzdCBGb3VyaWVyIFRyYW5zZm9ybSBvZiB0aGUgQ0lFIExhYiBsdW1pbmFuY2UgY2hhbm5lbCB0byBleHRyYWN0IHRoZSAyRCBzcGVjdG9ncmFtIG9mIGVhY2ggaW1hZ2UuIA0KDQpUbyBlZmZpY2llbnRseSBhZ2dyZWdhdGUgdGhlIDJEIHNwZWN0b2dyYW0sIHdlIGZpcnN0IGF2ZXJhZ2VkIGl0IHJvdGF0aW9uYWxseSBhbmQgdGhlbiBjb21wdXRlZCB0aGUgaW50ZXJjZXB0IGFuZCBzbG9wZSBvZiBhIGxpbmVhciBtb2RlbCBmaXR0ZWQgdG8gdGhlIGF2ZXJhZ2Ugc3BlY3RydW0gb24gbG9nLXRyYW5zZm9ybWVkIGZyZXF1ZW5jeSBhbmQgcG93ZXIgYXhpcy4gVGhlIHN0ZWVwZXIgdGhpcyBuZWdhdGl2ZSBzbG9wZSwgdGhlIG1vcmUgZW5lcmd5IGNhbiBiZSBmb3VuZCBpbiBsb3dlciBzcGF0aWFsIGZyZXF1ZW5jeSByZWxhdGl2ZSB0byBoaWdoZXIgc3BhdGlhbCBmcmVxdWVuY2VzLiBWaXN1YWxseSwgc3VjaCBpbWFnZXMgaGF2ZSBmZXdlciB2aXZpZCBkZXRhaWxzIGFuZCBtb3JlIGxhcmdlLXNjYWxlIGVkZ2VzLg0KDQpUaGUgMkQgc3BlY3RvZ3JhbSBoYXMgYWxzbyBiZWVuIHNob3duIHRvIGNhcHR1cmUgc3BhdGlhbCBvcmdhbml6YXRpb24gb2Ygc2NlbmVzIHJlbGV2YW50IGZvciBicm9hZCBkaXN0aW5jdGlvbnMgc3VjaCBhcyBiZXR3ZWVuIHVyYmFuIGFuZCBuYXR1cmFsIGVudmlyb25tZW50cy4gVG8gZXh0cmFjdCBvcmllbnRhdGlvbiBpbmZvcm1hdGlvbiBmcm9tIHRoZSAyRCBzcGVjdG9ncmFtLCB3ZSBmaXR0ZWQgcmVncmVzc2lvbiBsaW5lcyB0byB0aGUgc3BlY3RvZ3JhbXMgYWxvbmcgZm91ciBvcmllbnRhdGlvbnMgLSA0NSwgOTAsIDEzNSBhbmQgMTgwIGRlZ3JlZXMuIFdlIHRoZW4gZm91bmQgdGhlIG9yaWVudGF0aW9uIHdpdGggaGlnaGVyIGVuZXJneSwgeWllbGRpbmcgYSBkb21pbmFudCBvcmllbnRhdGlvbiwgYW5kIGNvbXB1dGVkIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgYWxsIGZvdXIgc2xvcGVzLCB5aWVsZGluZyBhIG1lYXN1cmUgb2YgaGV0ZXJvZ2VuaWV0eSBvZiBvcmllbnRhdGlvbnMgaW4gdGhlIGdpdmVuIGltYWdlLg0KDQoNCiMgU0VNQU5USUMgRkVBVFVSRVMgICANCg0KV2UgZ2VuZXJhdGVkIGEgW3NlbWFudGljIGxhYmVsbGluZyBzY2hlbWVdKGh0dHBzOi8vZG9jcy5nb29nbGUuY29tL2RvY3VtZW50L2QvMUk0UVpZOVBaNktoNVc3YjI3dUpUcGVyUXptSmFhQmgySmhLbjZhT1Q1LXcvZWRpdD91c3A9c2hhcmluZykgYW5kIGhhZCByZXNlcmFjaCBhc3Npc3RhbnRzIHByb3ZpZGUgbGF2ZWxzIGZvciB0aGUgaW1hZ2VzLg0KDQpCZWxvdyBhcmUgcGFpcndpc2UgaW50ZXItcmF0ZXIgYWdyZWVtZW50cyBmb3IgYSBzdWJzZXQgb2YgNjAwIGltYWdlcyBvbiB0d28gZGlmZmVyZW50IGxldmVscyBvZiBkZXRhaWwuDQoNCg0KYGBge3IgaW1wb3J0IHN1YnNldCwgZWNobz1GLCBtZXNzYWdlPUYsIHdhcm5pbmc9RiwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTE0fQ0KDQppZihzb3VyY2UgPT0gInNtYWxsIil7DQoNCgkNCgkjIyBBREQgU0VNQU5USUMgTEFCRUxTIFRPIERBVEENCglkID0gcmVhZC5jc3YyKHBhc3RlMChyb290LCJTQkVSIGlucHV0L3Bvb2wuY3N2IikpDQoJZCRJRCA9IGFzLmNoYXJhY3RlcihkJElEKQ0KDQoJIyBpbXBvcnQgdGhlIGxhYmVsbGluZyBkYXRhDQoJcyA9IHJlYWQuY3N2MihwYXN0ZTAocm9vdCwiU0JFUiBpbnB1dC9zZW1hbnRpY3MuY3N2IiksIHNraXAgPSAxNCkNCgkjIGltcG9ydCB0aGUgbGFiZWxsaW5nIHN5c3RlbQ0KCXN5c3QgPSByZWFkLmNzdjIocGFzdGUwKHJvb3QsIlNCRVIgaW5wdXQvc2VtYW50aWNzLmNzdiIpLCBza2lwID0gMSwgc3RyaW5nc0FzRmFjdG9ycyA9IEYpWzE6MTMsMjoxNl0NCgkjIHdyaXRlIGVhY2ggY2F0ZWdvcnktbGFiZWwgY29tYmluYXRpb24gaW50byBhIHNlcGFyYXRlIGNvbHVtbg0KCXNlbWFudGljID0gTlVMTA0KCWZvcihpIGluIHNlcV9hbG9uZyhzeXN0KSl7DQoJCXNlbWFudGljID0gYyhzZW1hbnRpYyxwYXN0ZShzeXN0WzEzLGldLCBzZXRkaWZmKHQodW5pcXVlKHN5c3RbMToxMixpXSkpLCIiKSwgc2VwID0gICJfIikpDQoJfQ0KCQ0KCSMgYmluYXJ5IHJhdGluZ3Mgb24gbG93IGxldmVsDQoJbGFiID0gZGF0YS5mcmFtZShpbWcgPSB1bmlxdWUocyRJTUFHRSkpICMgd2lkZSBtYXRyaXggd2l0aCBhbGwgbWVudGlvbnMNCglsYWIyID0gZGF0YS5mcmFtZSgpICMgbG9uZyBhZ3JlZW1lbnQgYW5hbHlzaXMgDQoJZm9yIChpIGluIGxhYiRpbWcpew0KCQlmb3IgKGogaW4gc2VtYW50aWMpew0KCQkJDQoJCQlyZXNwb25zZSA9IGdyZXBsKHN0cnNwbGl0KGosIl8iKVtbMV1dWzJdLHNbcyRJTUFHRT09aSxzdHJzcGxpdChqLCJfIilbWzFdXVsxXV0pDQoJCQlsYWJbbGFiJGltZz09aSxqXSA9IGFueShyZXNwb25zZSkNCgkJCQkNCgkJCWxhYjJbZGltKGxhYjIpWzFdKzEsImltZyJdID0gaQ0KCQkJbGFiMltkaW0obGFiMilbMV0sImZ1bGxkaW0iXSA9IGoNCgkJCWxhYjJbZGltKGxhYjIpWzFdLCJkaW0iXSA9IHVubGlzdChzdHJzcGxpdChqLCJfIikpWzFdDQoJCQlsYWIyW2RpbShsYWIyKVsxXSwic3ViZGltIl0gPSB1bmxpc3Qoc3Ryc3BsaXQoaiwiXyIpKVsyXQ0KCQkJbGFiMltkaW0obGFiMilbMV0sInJhdGluZ3MiXSA9IHBhc3RlMChyZXNwb25zZVsxOjJdLCBjb2xsYXBzZSA9ICJ8IikNCgkJfQ0KCX0NCgkNCgkjIGFkZCB0aGUgd2lkZSBmaWxlIHRvIGRhdGENCgljb2xuYW1lcyhsYWIpWzFdID0gImltYWdlSUQiDQoJbGFiJGltYWdlSUQgPSBhcy5jaGFyYWN0ZXIobGFiJGltYWdlSUQpDQoJZCA9IG1lcmdlKGQsbGFiLCBieSA9ICJpbWFnZUlEIikNCgkNCgkNCgkjIyBJTlRFUi1SQVRFUiBBR1JFRU1FTlQgQU5BTFlTSVMNCgkNCgkjIE1VTFRJTk9NSUFMDQoJYSA9IGdhdGhlcihzLGRpbWVuc2lvbixyYXRpbmcsc2V0ZGlmZihuYW1lcyhzKSxjKCJJTUFHRSIsInJhdGVyIikpKSAlPiUNCgkJCWdyb3VwX2J5KElNQUdFLGRpbWVuc2lvbikgJT4lIA0KCQkJc3VtbWFyaXNlKHJhdGluZ3MgPSBwYXN0ZTAocmF0aW5nLGNvbGxhcHNlID0gInwiKSwNCgkJCQkJCQkJcmF0ZXJzID0gcGFzdGUwKHJhdGVyLGNvbGxhcHNlID0gInwiKSwNCgkJCQkJCQkJZGlzYWdyZWVtZW50ID0gbGVuZ3RoKHVuaXF1ZShyYXRpbmcpKS0xKQ0KDQoJIyBleHBvcnQgZGF0YQkJCQ0KCSMgIHdyaXRlLmNzdjIoYSxwYXN0ZTAocm9vdCwgImFncmVlbWVudCBhbmFseXNpcy5jc3YiKSkNCg0KCSMgYW5hbHl6ZSByZWxpYWJpbGl0eQ0KCWlyclNlbSA9IGRhdGEuZnJhbWUoZGltID0gdW5pcXVlKGEkZGltKSkNCglmb3IgKGRpbSBpbiBpcnJTZW0kZGltKXsNCgkJYiA9IHQoc2VwYXJhdGUoYVthJGRpbT09ZGltLCJyYXRpbmdzIl0scmF0aW5ncywgYygicjEiLCAicjIiKSwgc2VwID0gIlxcfCIpKQ0KCQlpcnJTZW1baXJyU2VtJGRpbT09ZGltLCJLcmlwcCJdID0ga3JpcHAuYWxwaGEobmEuZXhjbHVkZShiKSkkdmFsdWUNCgl9DQoNCgkjIGlyclNlbSRkaW0gPSBmYWN0b3IoYXMuY2hhcmFjdGVyKGlyclNlbSRkaW0pLCBsZXZlbHMgPSB1bmlxdWUoaXJyU2VtJGRpbSlbb3JkZXIoaXJyU2VtJEtyaXBwLCBkZWNyZWFzaW5nID0gRildKQ0KCSMgZ2dwbG90KGlyclNlbSxhZXMoeD1kaW0seT1LcmlwcCwgZmlsbCA9IEtyaXBwKSkgKyBnZW9tX2JhcihzdGF0PSAiaWRlbnRpdHkiKSArIGNvb3JkX2ZsaXAoeWxpbSA9IGMoMCwxKSkgKyBwbHQgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCgkjIAlnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBjKDAuNjcsMC44KSkgKyANCgkjIAlsYWJzKHRpdGxlID0gIktyaXBwZW5kb3JmJ3MgYWxwaGEgb2YgbXVsdGlub21pYWwgcmF0aW5ncyIpDQoNCg0KCQ0KCSMgQklOQVJZDQoJaXJyU2VtID0gZGF0YS5mcmFtZShkaW0gPSB1bmlxdWUobGFiMiRzdWJkaW0pKQ0KCWZvciAoZGltIGluIGlyclNlbSRkaW0pew0KCQliID0gc2VwYXJhdGUobGFiMltsYWIyJHN1YmRpbT09ZGltLF0sIHJhdGluZ3MsIGMoInIxIiwgInIyIiksIHNlcCA9ICJcXHwiKQ0KCQliID0gdChuYS5leGNsdWRlKGJbLGMoInIxIiwicjIiKV0pKQ0KCQlpcnJTZW1baXJyU2VtJGRpbT09ZGltLCJLcmlwcCJdID0ga3JpcHAuYWxwaGEoYikkdmFsdWUNCgl9DQoNCg0KCWlyclNlbSRkaW0gPSBmYWN0b3IoYXMuY2hhcmFjdGVyKGlyclNlbSRkaW0pLCBsZXZlbHMgPSB1bmlxdWUoaXJyU2VtJGRpbSlbb3JkZXIoaXJyU2VtJEtyaXBwLCBkZWNyZWFzaW5nID0gRildKQ0KCWdncGxvdChpcnJTZW0sYWVzKHg9ZGltLHk9S3JpcHAsIGZpbGwgPSBLcmlwcCkpICsgZ2VvbV9iYXIoc3RhdD0gImlkZW50aXR5IikgKyBjb29yZF9mbGlwKCkgKyBwbHQgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCgkJZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gYygwLjY3LDAuOCkpICsgDQoJCWxhYnModGl0bGUgPSAiSW50ZXItcmF0ZXIgYWdyZWVtZW50IGZvciBkaWZmZXJlbnQgbGFiZWxzIiwgc3VidGl0bGUgPSAiS3JpcHBlbmRvcmYncyBhbHBoYSBvZiBiaW5hcnkgcmF0aW5ncyIpDQoJCQ0KDQoJDQoJDQoJIyBzZW1hbnRpYyBleGxjdXNpb25zDQoJZCRpbmNsdWRlID0gMQ0KCSMgbm9uLWF1dGhlbnRpYw0KCWQkaW5jbHVkZVtkJEFVVEhFTlRJQ0lUWV9maWN0aW9uYWw9PTFdPTANCgkjIG5vIGxhYmVsDQoJZCRpbmNsdWRlW2FwcGx5KGRbLHNlbWFudGljXSwxLGZ1bmN0aW9uKHgpIHN1bSh4KT09MCldID0gMA0KCQ0KCSMgcmVtb3ZlIHBpY3R1cmVzIHVzZWQgbGF0ZXIgYXMgcHJhY3RpY2UgDQoJbWFudWFsX2V4Y2wgPSBjKCI5NTYxIiwibmV1dHJhbF8xOTIiLCAiT2JqZWN0c18xMjdfaCIsICJQZW9wbGVfMjA4X2giKQ0KDQoJIyAjIGF1dG9tYXRpYyANCgkjIGEgPSBhcy5kYXRhLmZyYW1lKHQoYXBwbHkoZFssYygiYXZnTCIsICJzdGRCWSIsICJrcnRHUiIsICJza3dMIiwgImF2Z0JZIiwgInN0ZEdSIiwgImtydEwiLCAic2t3QlkiLA0KCSMgCQkJCQkJCQkJCQkJCQkJICJhdmdHUiIsInN0ZEwiLCJrcnRCWSIsInNrd0dSIiwgInNsb3BlX3JhdmciLCAiZG9taW5hbnRBbmdsZSIsICJhbmdsZVZhcmlhbmNlIiwgDQoJIyAJCQkJCQkJCQkJCQkJCQkgInNwZWN0cnVtX3JhdmcxIiwgInNwZWN0cnVtX3Jhdmc0IiAsICJzcGVjdHJ1bV9yYXZnNyIsICJzcGVjdHJ1bV9yYXZnMTAiLCANCgkjIAkJCQkJCQkJCQkJCQkJCSAic3BlY3RydW1fcmF2ZzEzIiwgInNwZWN0cnVtX3JhdmcxNiIsICJzcGVjdHJ1bV9yYXZnMTkiKV0sMixzY2FsZSkpKQ0KCSMgY29sbmFtZXMoYSkgPSBkJElEDQoJIyBmb3IocCBpbiBzZXFfYWxvbmcoMTooZGltKGEpWzJdLTEpKSl7DQoJIyAJaWYgKGFueShjb3IoYVsscF0sYVssKHArMSk6ZGltKGEpWzJdXSk+MC45NSkpIHsNCgkjIAkJbWFudWFsX2V4Y2wgPSBjKG1hbnVhbF9leGNsLGQkSURbcF0pDQoJIyAJfQkJDQoJIyB9DQoJDQoJZCRpbmNsdWRlW2QkaW1hZ2VJRCAlaW4lIG1hbnVhbF9leGNsXSA9IDANCg0KCSMgdGhlIG1haW4gY3VscHJpdCBpcyBqdXN0IG9uZSBzZXQsIHNvIHdlJ2xsIHJlbW92ZSB0aGlzDQoJZCRpbmNsdWRlW2QkU2V0PT0iTkFQUy1TRklQIl0gPSAwDQoJDQoJZDIgPSBkW2QkaW5jbHVkZT09MSxdDQoNCgkjIHBsb3Qgc2VtYW50aWMgbWVhbiB2YWxlbmNlDQoJYyA9IG1lbHQoZDJbLGMoIklEIiwgInZhbGVuY2UiLCBzZW1hbnRpYyldLCBpZC52YXJzID0gYygiSUQiLCAidmFsZW5jZSIpKQ0KCWMgPSBjW2MkdmFsdWU9PVRSVUUsXQ0KCWMkdmFyaWFibGUgPSBhcy5jaGFyYWN0ZXIoYyR2YXJpYWJsZSkNCgljJHZhcmlhYmxlID0gZmFjdG9yKGMkdmFyaWFibGUsIA0KCQkJCQkJCQkJCQlsZXZlbHMgPSBuYW1lcyhzb3J0KHRhcHBseShjJHZhbGVuY2UsYyR2YXJpYWJsZSxmdW5jdGlvbih4KSBtZWFuKG5hLmV4Y2x1ZGUoeCkpKSkpKQ0KDQoJZ2dwbG90KGMsYWVzKHg9dmFyaWFibGUsIHkgPSB2YWxlbmNlLCBjb2xvciA9IHZhbGVuY2UpKSArIGdlb21faml0dGVyKHNpemUgPSAxLCBhbHBoYSA9IDAuNSkgKyANCgkJc3RhdF9zdW1tYXJ5KGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjcsIHNpemUgPSBwbC5zYy8zKSArIHBsdCArIA0KCQl0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgY29vcmRfZmxpcCgpICsgDQoJCWxhYnModGl0bGUgPSAiQWdncmVnYXRlIGFuZCByYXcgbm9ybWF0aXZlIHJhdGluZ3Mgb2YgaW1hZ2VzIHdpdGggZGlmZmVyZW50IGxhYmVscy4iLCANCgkJCQkgY2FwdGlvbiA9ICJzcHJlYWRzIGRlbm90ZSBTRSIsIHggPSAiIiwgeSA9ICJOb3JtYXRpdmUgdmFsZW5jZSByYXRpbmciKQkNCgkNCn0NCgkNCmBgYA0KDQojIFNFVCBDT01QSUxBVElPTiBBTEdPUklUSE0NCg0KVGhlIGFsZ3JpdGhtIGNvbXBpbGVzIGFmZmVjdGl2ZSBpbWFnZSBzZXRzIHdpdGggZGVzaXJlZCBudW1iZXIgb2YgcGFyYWxsZWwgdmVyc2lvbnMgYW5kIG1lbWJlciBpbWFnZXMuIEluIHNob3J0LCBpdCBzZWVrcyB0byBtaW5pbWl6ZSB3aXRoaW4tc2V0IGFuZCBtYXhpbWl6ZSBiZXR3ZWVuLXNldCB2YXJpYW5jZSBhbG9uZyBhZmZlY3RpdmUgZmVhdHVyZXMgYXMgd2VsbCBhcyBtYXhpbWl6ZSB3aXRoaW4tc2V0IGFuZCBtaW5pbWl6ZSBiZXR3ZWVuLXNldCB2YXJpYW5jZSBhbG9uZyBwZXJjZXB0dWFsIGFuZCBzZW1hbnRpYyBmZWF0dXJ1ZXMuDQoNClRoZSBhbGdvcml0aG0gaGFzIHRoZSBmb2xsb3dpbmcgYmFzaWMgc3RlcHM6DQoxLiBEZWZpbmUgaW5wdXQgKHVzZSBmdWxsIG9yIHNwZWNpZmljIGltYWdlIHBvb2wsIHNldCBpbmNsdXNpb24gYW5kIGV4Y2x1c2lvbiBjcml0ZXJpYSkNCjIuIERlZmluZSBvdXRwdXQgKGFmZmVjdGl2ZSBzZWVkcyB3aXRoIGRlc2lyZWQgbnVtYmVyIHBhcmFsbGVsIHZlcnNpb25zIGFuZCBtZW1iZXJzKQ0KMy4gQ2x1c3RlciBwaWN0dXJlcyBzZXBhcmF0ZWx5IGluIHRocmVlIGRpZmZlcmVudCBzcGFjZXM6IGFmZmVjdGl2ZSwgc2VtYW50aWMsIGFuZCBwZXJjcGV0dWFsDQo0LiBNYWtlIGEgam9pbnQgY2x1c3RlcmluZyBieSByZS1hbGxvY2F0aW5nIHBpY3R1cmVzIGFzIG5lZWRlZA0KNS4gRGlzdHJpYnV0ZSBpbWFnZXMgZnJvbSB0aGUgam9pbnQgY2x1c3RlcnMgdG8gcmVxdWVzdGVkIHNldHMNCg0KIyMgMS4gRGVmaW5lIGlucHV0DQoNClRoZSBhbGdvcml0aG0gY2FuIHdvcmsgb24gZWl0aGVyIHRoZSBmdWxsIG1ldGEtZGF0YWJhc2Ugb3IgYSB1c2VyLXByb3ZpZGVkIHNvdXJjZSBzZXQuIFRoZSBpbnB1dCBzZXQgY2FuIGJlIGZ1cnRoZXIgcHJ1bmVkIGJ5IGV4cGxpY2l0IGluY2x1c2lvbiBhbmQvb3IgZXhjbHVzaW9uIGNyaXRlcmlhLg0KDQpCZWxvdyBhcmUgaWxsdXN0cmF0aW9ucyBvZiB0aGUgZXhjbHVzaW9uIGNyaXRyaWEgd2UgdXNlZCB0byBzZWxlY3QgYSBzdWJzZXQgb2YgdGhlIG1ldGEtZGF0YWJhc2UgZm9yIGluaXRpYWwgc2VtYW50aWMgbGFiZWxsaW5nLiBTcGVjaWZpY2FsbHksIHdlIGV4Y2x1ZGVkIGltYWdlcyB0aGF0Ow0KKiBoYWQgYSBkaWZmZXJlbnQgYXNwZWN0IHJhdGlvIGZyb20gMzo0ICANCiogaGFkIGZld2VyIHRoYW4gNjAwIHBpeGVscyBvbiB0aGUgc2hvcnRlciBlZGdlICANCiogbGlrZWx5IGNvbnRhaW5lZCBhIHNvbGlkIGJhY2tncm91bmQgIA0KKiBoYWQgbm9ybWF0aXZlIHZhbGVuY2UgcmF0aW5ncyBoaWdoZXIgdGhhbiAwLjU1IG9uIGEgMCB0byAxIHNjYWxlDQoNCmBgYHtyIGV4Y2x1c2lvbnMtaW5jbHVzaW9ucywgbWVzc2FnZSA9IEYsIGVjaG89Riwgd2FybmluZz1GLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xNH0NCg0KaWYgKHNvdXJjZSA9PSAibGFyZ2UiKXsNCg0KIyBtYWtlIGFuIGluY2x1c2lvbiBmbGFnICh0byBiZSB6ZXJvZWQgZm9yIGV4bHVzaW9uKQ0KCWQkaW5jbHVkZSA9IDENCg0KIyBzZW1hbnRpYyBjYXRlZ29yaWVzDQoJYSA9IHVuaXF1ZShjKHdoaWNoKGQkQVVUSEVOVElDSVRZX2ZpY3Rpb25hbCA+IDApKSkNCglkJGluY2x1ZGVbYV0gPSAwDQoJbWV0YSRleGNsX3NlbWFudGljW2RpbShtZXRhKVsxXV0gPSBsZW5ndGgoYSkNCg0KIyBiYWQgYXNwZWN0IHJhdGlvcw0KCWEgPSBkJGFzcGVjdCE9MC43NQ0KCWQkaW5jbHVkZVthXSA9IDANCgltZXRhJGV4Y2xfYXNwZWN0W2RpbShtZXRhKVsxXV0gPSBzdW0oYSkNCg0KIyBsb3cgcmVzb2x1dGlvbg0KCWEgPSBkJHNob3J0ZXN0PDYwMA0KCWQkaW5jbHVkZVthXSA9IDANCgltZXRhJGV4Y2xfcmVzb2x1dGlvbltkaW0obWV0YSlbMV1dID0gc3VtKGEpDQoNCiMgYmxhY2sgYm9yZGVycyANCglhID0gZCRsdW1pbmFuY2UxICVpbiUJYm94cGxvdC5zdGF0cyhkJGx1bWluYW5jZTEpJG91dCAjIHRha2Ugb3V0bGllcnMgYmFzZWQgb24gdGhlIHBlcmNlbnRhZ2Ugb2YgcGljdHVyZSB0aGF0IGlzIGJsYWNrIChsb3dlcyBsdW1pbmFuY2UgdmFsdWUpDQojIAkjIGEgPSBkJGx1bWluYW5jZTEgPiAwLjUgIyB0YWtlIG91dGxpZXJzIGJhc2VkIG9uIHRoZSBwZXJjZW50YWdlIG9mIHBpY3R1cmUgdGhhdCBpcyBibGFjayAobG93ZXMgbHVtaW5hbmNlIHZhbHVlKQ0KIyANCglkJGluY2x1ZGVbYV0gPSAwDQoJbWV0YSRleGNsX291dGx5aW5nX2x1bWluYW5jZVtkaW0obWV0YSlbMV1dID0gc3VtKGEpDQoNCiMgdmFsZW5jZQ0KCWEgPSBkJHZhbGVuY2UgPiAwLjU1IHwgaXMubmEoZCR2YWxlbmNlKSAjIHZhbGVuY2UgaXMgc2NhbGVkIHRvIDAgdG8gMQ0KCWQkaW5jbHVkZVthXSA9IDANCgltZXRhJGV4Y2xfcG9zX3ZhbGVuY2VbZGltKG1ldGEpWzFdXSA9IHN1bShhKQ0KCQ0KCW1ldGEkbGVmdF93aXRoW2RpbShtZXRhKVsxXV0gPSBzdW0oZCRpbmNsdWRlKQ0KCW1ldGEkZHVwbGljYXRlc1tkaW0obWV0YSlbMV1dID0gc3VtKG1ldGEkZHVwbGljYXRlc1sxOjJdKQ0KCQ0KIyBtYWtlIGEgc3Vic2V0CQ0KCWQyID0gZFtkJGluY2x1ZGU9PTEsXQ0KCQ0KIyBpbGx1c3RyYXRlIGV4bHVzaW9uIGRlY2lzaW9ucw0KCWdncGxvdChtZWx0KG1ldGFbZGltKG1ldGEpWzFdLCFpcy5uYShtZXRhW2RpbShtZXRhKVsxXSxdKV0pLGFlcyh4ID0gZ3N1YigiXyIsIiAiLHZhcmlhYmxlKSx5ID0gdmFsdWUsIGZpbGwgPSB2YWx1ZSkpICsgDQoJCWdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKyBjb29yZF9mbGlwKCkgKyBwbHQgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgDQoJCWxhYnMoeSA9ICJudW1iZXIgb2YgaW1hZ2VzIiwgeCA9ICIiLCAidGl0bGUiID0gIkV4Y2x1c2lvbiBoaXN0b3J5IikNCgkNCiMgc291cmNlIGFmdGVyIGV4Y2x1c2lvbnMNCglkMiRTZXR3TiA9IHVuc3BsaXQoc2FwcGx5KHNwbGl0KGQyLGQyJFNldCksZnVuY3Rpb24oeCkgcGFzdGUwKHgkU2V0LCAiXG5uPSIsbnJvdyh4KSwiIikpLGQyJFNldCkNCglnZ3Bsb3QoZDIsYWVzKHg9dmFsZW5jZSwgeSA9IGFyb3VzYWwsIGNvbG9yID0gU2V0d04pKSArIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsgcGx0ICsgZmFjZXRfd3JhcCh+U2V0d04pICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIA0KCQlsYWJzKHRpdGxlID0gIkluY2x1ZGVkIHBpY3R1cmVzIiwgc3VidGl0bGUgPSBwYXN0ZTAoIm49ICIsbnJvdyhkMikpKQ0KDQojIHdoYXQgc2V0cyBnZXQgZXhjbHVkZWQNCglwbGQgPSBkW2QkaW5jbHVkZT09MCxdDQoJcGxkJFNldHdOID0gdW5zcGxpdChzYXBwbHkoc3BsaXQocGxkLHBsZCRTZXQpLGZ1bmN0aW9uKHgpIHBhc3RlMCh4JFNldCwgIlxubj0iLG5yb3coeCksIiIpKSxwbGQkU2V0KQ0KCWdncGxvdChwbGQsYWVzKHg9dmFsZW5jZSwgeSA9IGFyb3VzYWwsIGNvbG9yID0gU2V0d04pKSArIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsgcGx0ICsgZmFjZXRfd3JhcCh+U2V0d04pICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIA0KCQlsYWJzKHRpdGxlID0gIkV4bGNsdWRlZCBwaWN0dXJlcyIsIHN1YnRpdGxlID0gcGFzdGUwKCJuPSAiLG5yb3cocGxkKSkpDQoNCgl9DQoJCQ0KYGBgDQoNCiMjIDIuIERlZmluZSBvdXRwdXQNCg0KRm9yIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIG9mIHRoZSBhbGdvcml0aG0sIHdlIGRlZmluZWQ6DQoNCiogc2VlZHMgZm9yIGRlc2lyZWQgYWZmZWN0aXZlIGNhdGVnb3JpZXMgKDQgY29ycmVzcG9uZGluZyB0byBuZXV0cmFsLCBsb3csIG1lZGl1bSwgYW5kIGhpZ2ggbmVnYXRpdmUgaW50ZW5zaXR5KSANCg0KKiBkZXNpcmVkIHNlbWFudGljIGNhdGVnb3JpZXMgKDQgY29ycmVzcG9uZGluZyB0byBhbmltYXRlIG5vbmh1bWFuLCBpbmFuaW1hdGUgbm9uaHVtYW4sIGluZGl2aWR1YWwgaHVtYW4sIHNvY2lhbCBodW1hbiwgYW5kIGJydXhpc20tcmVsYXRlZCBjb250ZW50KQ0KDQoqIG51bWJlciBvZiBpbWFnZXMgd2l0aGluIGVhY2ggc2V0ICg5LCBkcml2ZW4gc2ltcGx5IGJ5IHRoZSBnb2FsIHRvIGhhdmUgMTgwIGltYWdlIGluIHRvdGFsKQ0KDQoqIG51bWJlciBvZiBwYXJhbGxlbCBzZXRzICgzKQ0KDQojIyAzLiBJbmRlcGVuZGVudCBjbHVzdGVyaW5nDQoNCkFzIGl0cyBmaXJzdCBzdGFnZSwgdGhlIGFsZ29yaXRobSwgZ2VuZXJhdGVzIHRocmVlIGluZGVwZW5kZW50IGNsdXN0ZXJpbmcgc29sdXRpb25zIGJhc2VkIG9uIGFmZmVjdGl2ZSwgc2VtYW50aWMsIGFuZCBwZXJjZXB0dWFsIGZlYXR1cmVzLiBUaGUgZ29hbCBvZiB0aGlzIHN0YWdlIGlzIHRvIG9idGFpbiBzdW1tYXJ5IGZlYXR1cmVzIChjbHVzdGVyIGxhYmVscykgdGhhdCBjYW4gYmUgdXNlZCB0byBidWlsZCBiYWxhbmNlZCBpbWFnZSBzZXRzLiBTcGVjaWZpY2FsbHksIHdlIGFzc3VtZSB0aGF0IGlmIHR3byBpbWFnZSBzZXRzIGNvbXByaXNlIGFuIGVxdWFsIG51bWJlciBvZiBpbWFnZXMgZnJvbSBhIHNldCBvZiBjbHVzdGVycywgdGhlbiB0aGVzZSBzZXRzIHdpbGwgYmUgYm90aCBiYWxhbmNlZCBhbmQgdmFyaWFibGUgYWxvbmcgdGhlIGdpdmVuIGNsdXN0ZXJpbmcgZGltZW5zaW9uLiANCg0KQmFzZWQgb24gdGhlIGRlc2lyZWQgb3V0cHV0LCB3ZSBnZW5lcmF0ZWQ6DQoNCiogNCBhZmZlY3RpdmUgY2x1c3RlcnMgIA0KDQoqIDUgc2VtYW50aWMgY2x1c3RlcnMgIA0KDQoqIDkgcGVyY2VwdHVhbCBjbHVzdGVycyANCg0KIyMjIDMuMS4gQWZmZWN0aXZlIGNsdXN0ZXJzDQoNCldlIHVzZWQgdGhlIEstbWVhbnMgYWxnb3JpdGhtIG92ZXIgbm9ybWF0aXZlIHZhbGVuY2UgZGF0YSB0byBkaXN0cmlidXRlIGFsbCBpbnB1dCBpbWFnZXMgaW50byBvbmUgb2YgZm91ciBjbHVzdGVycyBiYXNlZCBvbiBtYW51YWxseSBzZXQgc2VlZHMgYXQgMC41IChuZXV0cmFsKSwgMC4zNSAobG93KSwgMC4yNSAobWVkaXVtKSwgMC4xIChoaWdoIGludGVuc2l0eSBuZWdhdGl2ZSkuDQoNCldlIHVzZWQgb25seSB2YWxlbmNlLCByYXRoZXIgdGhhbiB2YWxlbmNlIGFuZCBhcm91c2FsIHRvIGJ5cGFzcyBhcHBhcmVudCBzeXN0ZW1hdGljIGJpYXNlcyBpbiBub3JtYXRpdmUgcmF0aW5ncyBmb3IgZGlmZmVyZW50IHNvdXJjZSBzZXRzIGluIG91ciBtZXRhLWRhdGFiYXNlLiBXZSBub3RpY2VkIHRoYXQgZXZlbiBhZnRlciBjb252ZXJ0aW5nIGFsbCByYXRpbmdzIHRvIGEgdW5pZm9ybSAwIHRvIDEgc2NhbGUsIGRpZmZlcmVudCBzZXRzIHNlZW1lZCB0byBleGhpYml0IHN5c3RlbWF0aWMgYmlhc2VzLiBXZSB0aGVyZWZvcmUgcmVseSBvbiB2YWxlbmNlIHJhdGluZ3MgYWxvbmUsIHNpbmNlIHdpdGhpbiBuZWdhdGl2ZSBpbWFnZXMgdmFsZW5jZSBhbmQgYXJvdXNhbCB0ZW5kIHRvIGJlIGhpZ2hseSBjb3JyZWxhdGVkLg0KDQoNCmBgYHtyIGFmZmVjdGl2ZSBjbHVzdGVycywgbWVzc2FnZSA9IEYsIGVjaG89Rix3YXJuaW5nPUYsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTE0fQ0KDQojIFBSRVBBUkUgREFUQSBGT1IgQ0xVU1RFUklORyANCgkNCiMgIyMgQUZGRUNUSVZFIDItZGltZXNpb25hbCAjIyMjDQojCQllbW8uZmVhdCA9IGRbZCRpbmNsdWRlPT0xLGMod2hpY2goIklEIiA9PSBuYW1lcyhkKSksIGdyZXAoInZhbGVuY2UiLG5hbWVzKGQpKSwgZ3JlcCgiYXJvdXNhbCIsbmFtZXMoZCkpKV0NCiMgCXRvY2x1c3QgPC0gZW1vLmZlYXQNCiMgDQojIAkNCiMgIyBJRiBkYXRhLWRyaXZlbiBjbHVzdGVyaW5nDQojIAlpZihwcm0kc2VlZFsxXSA9PSAiZGF0YSIpew0KIw0KIyAjIG5vcm1hbGl6ZQ0KIyAJdG9jbHVzdFssLTFdID0gYXBwbHkodG9jbHVzdFssLTFdLDIsc2NhbGUpDQoNCiMgCQkjIG1ha2UgdHdvIGNsdXN0ZXINCiMgCQlhID0ga21lYW5zKHRvY2x1c3RbLC0xXSwgNCkNCiMgCQkNCiMgCQkjIHRvIGdldCB0aGUgZGlzdGFuY2VzDQojIAkJYSA9IGZpeEttZWFucyh0b2NsdXN0WywtMV0sIGEkY2VudGVycykNCiMgCQ0KIyANCiMgCSMgaWYgZml4ZWQgc2VlZHMJDQojIAl9IGVsc2Ugew0KIyAJDQojIAkJY2VudGVycyA9IHBybVssYygidmFsZW5jZSIsICJhcm91c2FsIildDQojIAkJDQojIAkJYSA9IGZpeEttZWFucyh0b2NsdXN0WywtMV0sIGNlbnRlcnMpDQojIA0KIyAJfQ0KIyANCiMgDQojIAlzaWwgPSBzaWxob3VldHRlKGEkY2x1c3RlciwgZGlzdChlbW8uZmVhdFssLTFdKSkNCiMgDQojICMgYWRkIHRvIGRhdGENCiMgCWQyJGVtb0NsdXN0ID0gc2lsWywxXQ0KIyAJZDIkZW1vQ2x1c3RTaWxoID0gc2lsWywzXQ0KIyANCiMgCWQyJGVtb0NsdXN0ID0gYSRjbHVzdGVyDQojIAlkMiRlbW9DbHVzdFNpbGggPSBhJGRpc3RhbmNlW2EkY2x1c3Rlcl0NCiMgDQojICMgdmlzdWFsaXplDQojIAlmdml6X2NsdXN0ZXIoYSwgdG9jbHVzdFssLTFdKSArIHBsdA0KIyAJIyBmdml6X3NpbGhvdWV0dGUoc2lsLCBwcmludC5zdW1tYXJ5ID0gRikNCiMgCQkNCiMgDQojIAkNCiMjIEFGRkVDVElWRSAxLWRpbWVzaW9uYWwgIyMjIw0KCWVtby5mZWF0ID0gZFtkJGluY2x1ZGU9PTEsYyh3aGljaCgiSUQiID09IG5hbWVzKGQpKSwgZ3JlcCgidmFsZW5jZSIsbmFtZXMoZCkpKV0NCgl0b2NsdXN0IDwtIGVtby5mZWF0DQoNCg0KIyBJRiBkYXRhLWRyaXZlbiBjbHVzdGVyaW5nDQoJaWYocHJtJHNlZWRbMV0gPT0gImRhdGEiKXsNCg0KCQkjIG5vcm1hbGl6ZQ0KCQkjIHRvY2x1c3RbLC0xXSA9IHNjYWxlKHRvY2x1c3RbLC0xXSkNCgkJIyBmb3Igc2luZ2xlIGRpbWVuc2lvbnMJDQoJCXRvY2x1c3RbLC0xXSA9IGFzLmRhdGEuZnJhbWUoc2NhbGUodG9jbHVzdFssLTFdKSkNCgkJIyBtYWtlIHR3byBjbHVzdGVyDQoJCWEgPSBrbWVhbnModG9jbHVzdFssLTFdLCA0KQ0KCQkjIHRvIGdldCB0aGUgZGlzdGFuY2VzDQoJCWEgPSBmaXhLbWVhbnModG9jbHVzdFssLTFdLCBhJGNlbnRlcnMpDQoJDQoJIyBpZiBmaXhlZCBzZWVkcwkNCgl9IGVsc2Ugew0KCQ0KCQljZW50ZXJzID0gcHJtW2MoInZhbGVuY2UiKV0NCgkJYSA9IGZpeEttZWFucyh0b2NsdXN0Wy0xXSwgY2VudGVycykNCg0KCX0NCg0KCXNpbCA9IHNpbGhvdWV0dGUoYSRjbHVzdGVyLCBkaXN0KHRvY2x1c3RbLC0xXSkpDQoNCiMgYWRkIHRvIGRhdGENCglkMiRlbW9DbHVzdCA9IHNpbFssMV0NCglkMiRlbW9DbHVzdFNpbGggPSBzaWxbLDNdDQoJIyByYW5rIGltYWdlcyBiYXNlZCBvbiB0aGVpciBkaXN0YW5jZSB0byB0aGVpciBjbHVzdGVyDQoJZDIkZW1vQ2x1c3RSYW5rID0gdW5zcGxpdChzYXBwbHkoc3BsaXQoZDIkZW1vQ2x1c3RTaWxoLGQyJGVtb0NsdXN0KSxmdW5jdGlvbih4KSByYW5rKC14KSksZDIkZW1vQ2x1c3QpDQoJDQoJIyBkMiRlbW9DbHVzdCA9IGEkY2x1c3Rlcg0KCSMgZDIkZW1vQ2x1c3RTaWxoID0gTlVMTA0KCSMgZm9yKGkgaW4gMTpkaW0oYSRkaXN0YW5jZSkpew0KCSMgCWQyJGVtb0NsdXN0U2lsaFtpXSA9IGEkZGlzdGFuY2VbaSxhJGNsdXN0ZXJbaV1dDQoJIyB9DQoNCiMgdmlzdWFsaXplDQoJZnZpel9zaWxob3VldHRlKHNpbCwgcHJpbnQuc3VtbWFyeSA9IEYpICsgcGx0ICsgbGFicyh0aXRsZSA9ICJBZmZlY3RpdmUgY2x1c3RlcnMiKQ0KCQ0KCWdncGxvdChkMixhZXMoeCA9IHZhbGVuY2UsIHkgPSBhcm91c2FsLCBjb2xvciA9IGFzLmZhY3RvcihlbW9DbHVzdCkpKSArIGdlb21fcG9pbnQoKSArIA0KCQljb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoMCwxKSwgeGxpbSA9IGMoMCwxKSkgKyANCgkJZ2VvbV9wb2ludChkYXRhID0gcHJtLCBhZXMoeCA9IHZhbGVuY2UsIHkgPSBhcm91c2FsLCBzaGFwZSA9IGVtbyksIHNpemUgPSBwbC5zYyoyLCBpbmhlcml0LmFlcyA9IEYpICsgDQoJCXBsdCArIGxhYnModGl0bGUgPSAiQWZmZWN0aXZlIHNlZWRzIGFuZCBjbHVzdGVycyIsIGNvbG9yID0gIkNsdXN0ZXIiLCANCgkJCQkJCQkgc3VidGl0bGUgPSBwYXN0ZTAocGFzdGUwKGFzLmNoYXJhY3RlcigxOjQpLCAiIG49IiwgYXMuY2hhcmFjdGVyKHRhYmxlKGQyJGVtb0NsdXN0KSkpLGNvbGxhcHNlID0gIjsgIikpIA0KDQpgYGANCg0KDQojIyMgMy4yLiBTZW1hbnRpYyBjbHVzdGVycw0KDQpUaGUgZGVmYXVsdCBpcyBtYW51YWwgc3BlY2lmaWNhdGlvbiBvZiBsYWJlbHMgYW5kIHRoZWlyIGRlc2lyZWQgcHJvcG9ydGlvbnMuDQoNCk9wdGlvbnMgaW5jbHVkZToNCg0KKiB1c2luZyBzb21lIHNlbGVjdGlvbiBvZiBsYWJlbHMgdG8gZ2VuZXJhdGUgZGF0YS1kcml2ZW4gc2VtYW50aWMgY2x1c3RlcnMNCiogdXNpbmcgTXVsdGlwbGUgQ29ycmVzcG9uZGVuY2UgQW5hbHlzaXMgdG8gZGVmaW5lIHRoZSBmZWF0dXJlIHZlY3RvcnMgdXNlZCBmb3IgZGF0YS1kcml2ZW4gY2x1c3RlcmluZw0KDQpgYGB7ciBzZW1hbnRpYyBjbHVzdGVycywgbWVzc2FnZSA9IEYsIGVjaG89Rix3YXJuaW5nPUYsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTE0fQ0KDQoJIyAjIHdoaWNoIG9uZXMgYXJlIGluZGVwZW5kZW50IG9mIGFmZmVjdD8NCgkjIG5vbkFmZmVjdGl2ZSA9IGRhdGEuZnJhbWUoZGltID0gbmFtZXMobGFiWy0xXSkpDQoJIyBmb3IoaSBpbiBuYW1lcyhsYWJbLTFdKSl7DQoJIyAJIyBwbG90IGRpc3RyaWJ1dGlvbnMNCgkjIAkjIHBsb3QodGFibGUoZCRhc3NpZ24sZFssaV0pLCBtYWluID0gaSwgc3ViID0gcm91bmQoY2hpc3EudGVzdCh0YWJsZShkJGFzc2lnbixkWyxpXSkpJHAudmFsdWUsMykpDQoJIyAJbm9uQWZmZWN0aXZlW25vbkFmZmVjdGl2ZSRkaW09PWksInAiXSA9IGNoaXNxLnRlc3QodGFibGUoZCRhc3NpZ24sZFssaV0pKSRwLnZhbHVlDQoJIyB9DQoJIyANCgkjICMgdXNlIGZvciBjbHVzdGVyaW5nDQoJIyAjIGRhdGEtZHJpdmVuIHZlcnNpb24NCgkjIHNlbWFudGljQ2x1c3QgPSBub25BZmZlY3RpdmUkZGltW25vbkFmZmVjdGl2ZSRwPjAuMDVdDQoJDQoNCiMgbWFrZSB0aGUgbWFudWFsIGJhbGFuY2luZyBjYXRlZ29yeQ0KCWQyJHNlbWFudGljID0gIiINCglkMiRzZW1hbnRpY1tkMiRCQVNJQ19hbmltYWw9PVQgfCBkMiRgU0NFTkVfd2l0aCBhbmltYWxzYCA9PSBUXSA9ICJhbmltYXRlIG5vbmh1bWFuIg0KCWQyJHNlbWFudGljW2QyJEJBU0lDX29iamVjdCA9PSBUIHwgZDIkQkFTSUNfcGxhbnQgPT0gVCB8IChkMiRCQVNJQ19zY2VuZSA9PSBUICYgZDIkYFNDRU5FX3dpdGggcGVvcGxlYCA9PSBGICYgZDIkYFNDRU5FX3dpdGggYW5pbWFsc2AgPT0gRildID0gImluYW5pbWF0ZSBub25odW1hbiIgDQoJZDIkc2VtYW50aWNbKGQyJEJBU0lDX2h1bWFuID09IFQgJiBkMiROVU1CRVJfMSA9PSBGKSB8IGQyJGBTQ0VORV93aXRoIHBlb3BsZWAgPT0gVF0gPSAic29jaWFsIGh1bWFuIg0KCWQyJHNlbWFudGljW2QyJEJBU0lDX2h1bWFuID09IFQgJiBkMiROVU1CRVJfMSA9PSBUXSA9ICJpbmRpdmlkdWFsIGh1bWFuIg0KCWQyJHNlbWFudGljW2QyJFNCRVJfZGVudGFsPT0gVCB8IGQyJGBTQkVSX2ZhY2UgcGFpbmA9PVQgfCBkMiRTQkVSX3NsZWVwID09IFQgfCBncmVwbCgiU0JFUiIsZDIkaW1hZ2VJRCldID0gImJydXhpc20iDQoNCglkMiRtYW51YWxfMSA9IGlmZWxzZShkMiRzZW1hbnRpYyA9PSAiYW5pbWF0ZSBub25odW1hbiIsVCxGKQ0KCWQyJG1hbnVhbF8yID0gaWZlbHNlKGQyJHNlbWFudGljID09ICJpbmFuaW1hdGUgbm9uaHVtYW4iLCBULEYpDQoJZDIkbWFudWFsXzMgPSBpZmVsc2UoZDIkc2VtYW50aWMgPT0gInNvY2lhbCBodW1hbiIsVCxGKQ0KCWQyJG1hbnVhbF80ID0gaWZlbHNlKGQyJHNlbWFudGljID09ICJpbmRpdmlkdWFsIGh1bWFuIixULEYpDQoJZDIkbWFudWFsXzUgPSBpZmVsc2UoZDIkc2VtYW50aWMgPT0gImJydXhpc20iLFQsRikNCglkMiRtYW51YWxfMCA9IGlmZWxzZShkMiRzZW1hbnRpYyA9PSAiIiwgVCwgRikNCg0KCQkNCgkjICMgbWFudWFsIGlucHV0IHRvIE1DQQ0KCSMgc2VtYW50aWNDbHVzdCA9IGMoIkJBU0lDIiwgIkVOVklST05NRU5UIiwiTlVNQkVSIiwgIlNCRVIiLCAiU0NFTkUiKQ0KCSMgc2VtYW50aWNDbHVzdCA9IG5hbWVzKGxhYilbc2FwcGx5KHN0cnNwbGl0KG5hbWVzKGxhYikgLCJfIiksZnVuY3Rpb24oeCkgYW55KGdyZXAoeFtbMV1dWzFdLHNlbWFudGljQ2x1c3QpKSldDQoNCgkjIGFsbCBpbmNsdWRlZA0KCSMgc2VtYW50aWNDbHVzdCA9IHNlbWFudGljDQoJDQoJc2VtYW50aWNDbHVzdCA9IG5hbWVzKGQyKVtncmVwKCJtYW51YWwiLG5hbWVzKChkMikpKV0NCg0KCSMgcHJlcGFyZSBkYXRhDQoJc2VtLmZlYXQgPSBkMlssYygiSUQiLCBhcy5jaGFyYWN0ZXIoc2VtYW50aWNDbHVzdCkpXQ0KDQoJIyByZW1vdmUgY29sdW1ucyB3aXRoIG5vIHZhcmlhbmNlDQoJc2VtLmZlYXQgPSBzZW0uZmVhdFssYygxLCB3aGljaChhcHBseShzZW0uZmVhdFstMV0sMixmdW5jdGlvbih4KSBzdW0oeCk+MCkpKzEpXQ0KDQoJIyAjIFNFTUFOVElDIE1DQQ0KCSMgIyBjb21wdXRlIE11bHRpcGxlIENvcnJlc3BvbmRlbmNlIEFuYWx5c2lzIHNvbHV0aW9uDQoJIyBmaXQgPSBNQ0Eoc2VtLmZlYXRbLTFdLDQpDQoJIyAjIGdldCBwaWN0dXJlIGNvLW9yZGluYXRlcyBvbiBzb21lIHN1YnNldCBvZiBkaW1lbnNvb25zDQoJIyBhID0gZml0JHZhciRjb29yZA0KCSMgZCA9IG1lcmdlKGQsYSwiSUQiKQ0KCSMgY29sbmFtZXMoZCkgPSBnc3ViKCJEaW0gIiwgIkRpbSIsIGNvbG5hbWVzKGQpKQ0KCQ0KCQ0KCSMgTUFLRSBBQ1RVQUwgU0VNQU5USUMgQ0xVU1RFUlMNCgkNCgkjIGNvbXB1dGUgZGlzdGFuY2UgbWF0cml4IGZyb20gYmluYXJ5IGRhdGE6IGh0dHA6Ly93d3cuaWlpc2NpLm9yZy9qb3VybmFsL0NWJC9zY2kvcGRmcy9HUzMxNUpHLnBkZg0KCXNlbS5kaXN0IDwtIGRpc3QuYmluYXJ5KDEqc2VtLmZlYXRbLTFdLDkpDQoNCgkjIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nIHNvbHV0aW9uDQoJdHJlZSA9IGhjbHVzdChzZW0uZGlzdCkNCg0KCSMgY3V0IGludG8gdGhlIG51bWJlciBvZiBwYXJhbGxlbCBzZXRzDQoJY2x1c3QgPSBjdXRyZWUodHJlZSwgaz11bmlxdWUocHJtJHNldE51bSkpDQoNCgkjIGlmIHdlIHdhbnQgdG8gdXNlIHRoZSBzZW1hbnRpYyBjYXRlZ29yeSBtYW51YWxseSBzZXQNCgljbHVzdCA9IGFzLm51bWVyaWMoZmFjdG9yKGQyJHNlbWFudGljLGxldmVscyA9IGMoIiIsc2V0ZGlmZihkMiRzZW1hbnRpYywiIikpKSktMQ0KCQ0KCQ0KCXNpbCA9IHNpbGhvdWV0dGUoY2x1c3QsIGRpc3Qoc2VtLmZlYXRbLC0xXSkpDQoJDQoJIyBwbG90KGFzLnBoeWxvKHRyZWUpLCB0eXBlID0gImZhbiIpDQoJZnZpel9zaWxob3VldHRlKHNpbCwgcHJpbnQuc3VtbWFyeSA9IEYpICsgcGx0ICsgbGFicyh0aXRsZSA9ICJTZW1hbnRpYyBjbHVzdGVycyIpDQoNCgkjIGEgPSBwYW0oc2VtLmRpc3QsMTApICMgLSBjbHVzdGVyIGFyb3VuZCBhIG1lZGlhbiByb3cgDQoJDQoJIyBjZW50ZXJzID0gdChzYXBwbHkoc3BsaXQoc2VtLmZlYXRbLC0xXSxjKSwgZnVuY3Rpb24oeCkgYXBwbHkoeCwyLG1lYW4pKSkNCgkjIGEgPSBmaXhLbWVhbnMoc2VtLmZlYXRbLC0xXSwgY2VudGVycykNCg0KCSMgZ2V0IHRoZSBjbHVzdGVyIGlkZW50aXRpZXMNCglkMiRzZW1DbHVzdCA9IHNpbFssMV0NCgkNCgkjIHVzZSB0aGUgc2lsaG91ZXR0ZSBzdGF0aXN0aWMgYXMgZGlzdGFuY2UgbWV0cmljIChhIGJlbmVmaXQgaXMgdGhhdCBpdHMgYWxyZWFkeSBub3JtYWxpemVkKQ0KCWQyJHNlbUNsdXN0U2lsaCA9IHNpbFssM10NCglkMiRzZW1DbHVzdFJhbmsgPSB1bnNwbGl0KHNhcHBseShzcGxpdChkMiRzZW1DbHVzdFNpbGgsZDIkc2VtQ2x1c3QpLGZ1bmN0aW9uKHgpIHJhbmsoLXgpKSxkMiRzZW1DbHVzdCkNCgkNCgkjIGQyJHNlbUNsdXN0ID0gYSRjbHVzdGVyDQoJIyBkMiRzZW1DbHVzdFNpbGggPSBOVUxMDQoJIyBmb3IoaSBpbiAxOmRpbShhJGRpc3RhbmNlKSl7DQoJIyAJZDIkc2VtQ2x1c3RTaWxoW2ldID0gYSRkaXN0YW5jZVtpLGEkY2x1c3RlcltpXV0NCgkjIH0NCg0KDQoJIyBjb3JycGxvdChzZW0uZGlzdFstMV0sIG1ldGhvZCA9ICJzcXVhcmUiKQ0KDQoJDQpgYGANCg0KDQojIyMgMy4zLiBQZXJjZXB0dWFsIGNsdXN0ZXJzDQoNClRoZSBkZWZhdWx0IGZlYXR1cmUgc2V0IGluY2x1ZGVzLg0KDQpGaXJzdCBmb3VyIHN0YXRpc3RpY2FsIG1vbWVtdHMgZm9yIHRoZSBkaXN0cmlidXRpb25zIG9mIENpZUxhYiBkaW1lbnNpb25zOg0KDQoqIG1lYW4gKGJyaWdodG5lc3MpLCBzdGFuZGFyZCBkZXZpYXRpb24gKGNvbnRyYXN0KSwgc2tld25lc3MsIGFuZCBrdXJ0b3NpcyBmb3IgbHVtaW5hbmNlDQoqIE0sIFNELCBzLCBhbmQgayBmb3IgdGhlIGdyZWVuLXJlZCBkaW1lbnNpb24NCiogTSwgU0QsIHMsIGFuZCBrIGZvciB0aGUgYmx1ZS15ZWxsb3cgZGltZW5zaW9uDQoNClJlcHJlc2VudGF0aW9ucyBvZiAyRCBpbWFnZSBzcGVjdG9ncmFtIGNvbXB1dGVkIGZyb20gdGhlIGx1bWluYW5jZSBjaGFubmVsOg0KDQoqIHNsb3BlIG9mIHRoZSByb3RhdGlvbmFsbHkgYXZlcmFnZWQgc3BlY3RydW0NCiogbWVhbiByb3RhdGlvbmFsbHkgYXZlcmdhZWQgc3BlY3RydW0gaW4gNyBiaW5zIA0KKiBkb21pbmFudCBkaXJlY3Rpb24gb2YgdGhlIDJEIHNwZWN0cnVtIG91dCBvZiAwLCA0NSwgOTAsIGFuZCAxMzUgZGVncmVlcyAobGFyZ2VzdCBzbG9wZSkNCiogc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHNsb3BlcyBvZiBhbGwgdGhlc2UgZGlyZWN0aW9ucw0KIA0KDQpUaGUgZGVmYXVsdCBpcyBoaWVyYXJjaGljYWwgY2x1c3RlcmluZyB3aXRoIHR3byBhcHByb2FjaGVzIGZvciBmaW5kaW5nIGEgc3VpdGFiZWwgY3V0OiANCg0KKiB0b3AtZG93biBtZXRob2QgLSBzdGFydCBmcm9tIHRoZSBsYXJnZXN0IG51bWJlciBvZiBjbHVzdGVycyBwb3NzaWJsZSBnaXZlbiB0aGUgc2l6ZSBvZiBpbnB1dCBhbmQgb3V0cHV0LiBMb3dlciB0aGUgbnVtYmVyIHVudGlsIGEgc29sdXRpb24gd2l0aCAgYSBzdWZmaWNpZW50IG51bWJlciBvZiBzdWZmaWNpZW50bHkgbGFyZ2UgYW5kIGVtb3Rpb25hbGx5IGRpdmVyc2UgY2x1c3RlcnMgZW1lcmdlcy4gVGhlIGlkZWEgaXMgdGhhdCB0aGUgaGlnaGVyIHRoZSBjdXQtb2ZmLCB0aGUgbW9yZSBjbG9zZWx5LWtuaXQgdGhlIGNsdXN0ZXJzIHdpbGwgYmUgYWxsb3dpbmcgdG8gbWluaWl6ZSBwZXJjZXB0dWFsIHZhcmlhbmNlIG9uY2UgcGljdHVyZXMgZnJvbSB0aGUgc2FtZSBwZXJjZXB0dWFsIGNsdXN0ZXIgd2lsbCBiZSBkaXN0cmliaXRlZCBhY3Jvc3MgdGhlIGV2ZW50dWFsIHNldHMuDQoNCiogZHluYW1pYyB0cmVlIGN1dCAtIGFuIFIgZnVudGlvbiB0aGF0IGRpcmVjdGx5IHByb2R1Y2VzIHRoZSBkZXNpcmVkIG51bWJlciBvZiBjbHVzdGVycw0KDQoNCmBgYHtyIFBFUkNFUFRVQUwgQ0xVU1RFUlMsIGVjaG89Rix3YXJuaW5nPUYsIG1lc3NhZ2UgPSBGLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xNH0NCg0KIyBQUkVQQVJFIEZFQVRVUkVTDQoNCgkjIHJhdyBsb3ctbGV2ZWwgZmVhdHVyZXMgdG8gYmUgdXNlZCBmb3IgcXVhbGl0eSBjb250cm9sIHBsb3R0aW5nDQoJbG93LmZlYXQgPSBkW2QkaW5jbHVkZT09MSxjKHdoaWNoKCJJRCIgPT0gbmFtZXMoZCkpLCBncmVwKCJsdW1pbmFuY2UiLG5hbWVzKGQpKSwgZ3JlcCgic3BlY3RydW0iLG5hbWVzKGQpKSwNCgkJCQkJCQkJCQkJCQkJCWdyZXAoImJsdWVZZWxsb3ciLG5hbWVzKGQpKSwgZ3JlcCgiZ3JlZW5SZWQiLG5hbWVzKGQpKSldDQoNCgkjIGZlYXR1cmVzIGZvciBjbHVzdGVyaW5nDQoJc3VtLmZlYXQgPSBjKCJJRCIsIHBhc3RlMChyZXAoYygiYXZnIiwgInN0ZCIsICJrcnQiLCAic2t3IiksMyksYygiTCIsICJCWSIsICJHUiIpKSwgICMgNCBzdGF0aXN0aWNhbCBtb21lbnRzIG9mIGx1bWluYW5jZSBhbmQgdGhlIHR3byBjb2xvciBjaGFubmVscyAoMTIpDQoJCQkJCQkJICJzbG9wZV9yYXZnIiwgImRvbWluYW50QW5nbGUiLCAiYW5nbGVWYXJpYW5jZSIsIHBhc3RlMCgic3BlY3RydW1fcmF2ZyIsIGFzLmNoYXJhY3RlcihzZXEoMSwyMCwzKSkpKSAjIHNwZWN0cm9ncmFtIGZlYXR1cmVzICgxMCkNCglzdW0uZmVhdCA9IGRbZCRpbmNsdWRlPT0xLGludGVyc2VjdChzdW0uZmVhdCxuYW1lcyhkKSldDQoNCgkjIHZpc3VsYWl6ZSBmZWF0dXJlIGNvLXZhcmlhbmNlDQoJY29ycnBsb3QubWl4ZWQoY29yKGNiaW5kKGQyJHZhbGVuY2Usc3VtLmZlYXRbLTFdKSksIHVwcGVyID0gInNxdWFyZSIsIGxvd2VyID0gIm51bWJlciIsIHRsLnBvcyA9ICJsdCIsIA0KCQkJCQkJCQkgdGl0bGUgPSAiQ292YXJpYW5jZSBvciBmZWF0dXJlcyBzZWxlY3RkIGZvciBwZXJjZXB0dWFsIGNsdXN0ZXJpbmciKQ0KCQkjIG9yZGVyID0gImhjbHVzdCIsIA0KDQoJIyBzZWxlY3QgZmVhdHVyZXMgZm9yIGNsdXN0ZXJpbmcNCgl0b2NsdXN0ID0gc3VtLmZlYXQNCgkNCgkjIHN0YW5kYXJkaXplIGZlYXR1cmUgZGlzdHJpYnV0aW9ucyAodG8gd2VpZ2ggdGhlbSBlcXVhbGx5KQ0KCXRvY2x1c3RbLC0xXSA9IGFwcGx5KHRvY2x1c3RbLC0xXSwyLHNjYWxlKQ0KCQ0KCSMgZ2V0IG1heGltYWwgbnVtYmVyIG9mIGNsdXN0ZXJzIChpZiBhbGwgdGhlIGF2YWlsYWJsZSBwaWN0dXJlcyB3ZXJlIGRpc3RyaWJ1dGVkIGVxdWFsbHkgYmV0d2VlbiBjbHVzdGVycykNCgltYXhOQyA9IHJvdW5kKGRpbSh0b2NsdXN0KVsxXS9zdW0ocHJtJHNldE51bSkpDQoJDQoJIyBnZXQgbWluaW1hbCBudW1iZXIgb2YgY2x1c3RlcnMNCgltaW5OQyA9IG1heChwcm0kc2V0U2l6ZSkNCg0KCSMgY29tcHV0ZSBoaWVyYXJjaGljYWwgY2x1c3RlcmluZyB3aXRoIGV1Y2xlZGlhbiBkaXN0YW5jZSAJDQoJYiA9IGhjbHVzdChkaXN0KHRvY2x1c3RbLC0xXSksIG1ldGhvZCA9ICJjb21wbGV0ZSIpDQoJDQoJIyBzZXQgYSBmbGFnIGZvciBzZWFjaGluZyBmb3IgYW4gb3B0aW1hbCBjbHV0c2VyaW5nIHNvbHV0aW9uDQoJc2VlayA9IDENCgkNCgkjIGxvb3AgdGhyb3VnaCBudW1iZXIgb2YgY2x1c3RlcnMgZnJvbSBsYXJnZXN0IHRvIHNtYWxsZXN0IHBvc3NpYmxlDQoJZm9yKGNsdXN0TnVtIGluIHNlcShtYXhOQyxtaW5OQywtMSkpeyAgDQoJDQoJCSMgY3V0IGF0IHRoZSBzZWxlY3RlZCBsZXZlbA0KCQljID0gY3V0cmVlKGIsayA9IGNsdXN0TnVtKQ0KCQkjIGNvbXB1dGUgc2lsaG91ZXR0ZQ0KCQlzaWwgPSBzaWxob3VldHRlKGMsIGRpc3QodG9jbHVzdFssLTFdKSkNCg0KCQkjIGlmIHRoZSBzb2x1dGlvbiBoYXMgZW5vdWdoIGNsdXN0ZXJzIHdpdGggZW5vdWdoIHBpY3R1cmVzIGluIGVhY2ggZW1vIGNsdXN0ZXINCgkJaWYoc3VtKGFwcGx5KHRhYmxlKGQyJGVtb0NsdXN0LHNpbFssMV0pLDIsIGZ1bmN0aW9uKHgpIGFsbCh4ID49cHJtJHNldE51bSkpKT49bWluTkMpew0KCQkJc2VlayA9IDANCgkJCW1ldGhvZCA9ICJ0b3AtZHdvbiINCgkJCWJyZWFrDQoJCX0NCgl9DQoJDQoJIyBpZiB0aGUgYWJvdmUgYXBwcm9hY2ggZmFpbGVkIHRvIHByb2R1Y2UgYW5kIG9wdGltYWwgc29sdXRpb24NCglpZihzZWVrPT0xKXsgDQoJCSNEeW5hbWljIEN1dCAgLSB1c2UgdGhpcyB3aGVuIHRoZSBmaXJzdCB0aGluZyBmYWlscyBodHRwczovL2xhYnMuZ2VuZXRpY3MudWNsYS5lZHUvaG9ydmF0aC9Db2V4cHJlc3Npb25OZXR3b3JrL0JyYW5jaEN1dHRpbmcvU3VwcGxlbWVudC5wZGYNCgkJYyA9IGN1dHJlZUR5bmFtaWMoYiwgbWluQ2x1c3RlclNpemU9c3VtKHBybSRzZXROdW0pLCBtZXRob2Q9Imh5YnJpZCIsIGRpc3RNPWFzLm1hdHJpeChkaXN0KHRvY2x1c3RbLTFdKSksIGRlZXBTcGxpdD00LCANCgkJCQkJCQkJCW1heENvcmVTY2F0dGVyPU5VTEwsIG1pbkdhcD1OVUxMLCBtYXhBYnNDb3JlU2NhdHRlcj1OVUxMLCBtaW5BYnNHYXA9TlVMTCkNCgkJc2lsID0gc2lsaG91ZXR0ZShjLCBkaXN0KHRvY2x1c3RbLC0xXSkpDQoJCWlmKHN1bShhcHBseSh0YWJsZShkMiRlbW9DbHVzdCxzaWxbLDFdKSwyLCBmdW5jdGlvbih4KSBhbGwoeCA+PXBybSRzZXROdW0pKSk+PW1pbk5DKXsNCgkJCXNlZWsgPSAwDQoJCX0NCgkJbWV0aG9kID0gImR5bmFtaWMgY3V0Ig0KCX0NCg0KCSMgcGxvdCBhIHNpbGhvdWV0dGUgYW5hbHlzZXMgb2YgdGhlIG9idGFpbmVkIHNvbHV0aW9uDQoJZnZpel9zaWxob3VldHRlKHNpbCwgcHJpbnQuc3VtbWFyeSA9IEYpICsgbGFicyh0aXRsZSA9ICJPYnJ0YWluZWQgcGVyY2VwdHVhbCBjbHVzdGVyaW5nIiwgc3VidGl0bGUgPSBwYXN0ZSgiTWV0aG9kOiIsIG1ldGhvZCkpICsgcGx0DQoNCgkjIGFkZCB0byBkYXRhDQoJIyBjbHVzdGVyIGxhYmVsDQoJZDIkbG93Q2x1c3QgPSBzaWxbLDFdDQoJIyBhZGQgZGlzdGFuY2UgdmFyaWFibGVzIHRvIGRhdGEgLSBzaWxob3VldHRlIHN0YXRpc3RpYyAoLTEgdG8gMSwgbGFyZ2VyID0gYmV0dGVyKQ0KCWQyJGxvd0NsdXN0U2lsaCA9IHNpbFssM10NCgkjIHdpdGhpbi1jbHVzdGVyIHJhbmtpbmcgb2YgaW1hZ2VzIChsYXJnZXIgaXMgYmV0dGVyKQ0KCWQyJGxvd0NsdXN0UmFuayA9IHVuc3BsaXQoc2FwcGx5KHNwbGl0KGQyJGxvd0NsdXN0U2lsaCxkMiRsb3dDbHVzdCksZnVuY3Rpb24oeCkgcmFuaygteCkpLGQyJGxvd0NsdXN0KQ0KDQoJIyBzZWxlY3QgbG93ZXIgY2x1c3RlcnMgdG8gd29yayB3aXRoIChiYXNlZCBvbiBhdmVyYWdlIHNpbGhvdWV0dGUsIHNpemUgYW5kIHRoZSBudW1iZXIgb2Ygbm9uLXplcm8gZW1vdGlvbiBjYXRlZ29yaWVzOyBsYXJnZXIgPSBiZXR0ZXIpDQoJIyBmaW5kIHVzYWJsZSBjbHVzdGVycw0KCXVzZUNsdXN0ID0gc29ydCgNCgkJcmFuayhhcHBseSh0YWJsZShkMiRsb3dDbHVzdCxkMiRlbW9DbHVzdCksMSxmdW5jdGlvbih4KSBtZWFuKHgvcHJtJHNldE51bSkgKyBzdW0oeD4wKSkpKncuZW1vDQoJCSMrIHJhbmsoYXBwbHkodGFibGUoZDIkbG93Q2x1c3QsZDIkc2VtQ2x1c3QpLDEsZnVuY3Rpb24oeCkgbWVhbih4L2MoMSw0LDQsNCw0LDQpKSArIHN1bSh4PjApKSkqdy5zZW0NCgkJKyByYW5rKHRhcHBseShkMiRsb3dDbHVzdFNpbGgsZDIkbG93Q2x1c3QsbWVhbikpKncubG93KjIsZGVjcmVhc2luZyA9IFQpDQoJdXNlQ2x1c3QgPSBzZXRkaWZmKGFzLm51bWVyaWMobmFtZXModXNlQ2x1c3QpKSwwKVsxOnVuaXF1ZShwcm0kc2V0U2l6ZSldCQ0KCSMgbWFyayB0aGUgcmVzdCB0byB6ZXJvDQoJZDIkbG93Q2x1c3RbIShkMiRsb3dDbHVzdCAlaW4lIHVzZUNsdXN0KV0gPSAwDQoNCgkjIHJlY29tcHV0ZSB0aGUgc2lsaG91ZXR0ZSBzb2x1dGlvbg0KCXNpbCA9IHNpbGhvdWV0dGUoZDIkbG93Q2x1c3QsIGRpc3QodG9jbHVzdFssLTFdKSkNCgkjIHBsb3QgaXQNCglmdml6X3NpbGhvdWV0dGUoc2lsLCBwcmludC5zdW1tYXJ5ID0gRikgKyBsYWJzKHRpdGxlID0gIlBydW5lZCBwZXJjZXB0dWFsIGNsdXN0ZXJpbmciKSArIHBsdA0KDQoNCgkjIHVwZGF0ZSBxdWFsaXR5IHZhaXJhYmxlcw0KCSMgc2lsaG91ZXR0ZSBzdGF0aXN0aWMgKC0xIHRvIDEsIGxhcmdlciA9IGJldHRlcikNCglkMiRsb3dDbHVzdFNpbGggPSBzaWxbLDNdDQoJIyB3aXRoaW4tY2x1c3RlciByYW5raW5nIG9mIGltYWdlcyAobGFyZ2VyIHNpbGhvdWV0dGUgc3RhdGlzdGljcyAtPiBzbWFsbGVyIHJhbmspDQoJZDIkbG93Q2x1c3RSYW5rID0gdW5zcGxpdChzYXBwbHkoc3BsaXQoZDIkbG93Q2x1c3RTaWxoLGQyJGxvd0NsdXN0KSxmdW5jdGlvbih4KSByYW5rKC14KSksZDIkbG93Q2x1c3QpDQoNCgkjIG1ha2UgYSBzcGFyZSBjb3B5DQoJdmFydSA9IGQyDQoNCmBgYA0KDQoNCiMjIDQuIEpvaW50IGNsdXN0ZXJpbmcNCg0KQSBjdXN0b20tYnVpbHQgYWxnb3JpdGhtIHdpdGggdGhlIGZvbGxvd2luZyBzdGVwczoNCg0KKiBDcmVhdGUgYSAzRCBtYXRyaXggZnJvbSB0aGUgaWRlbnRpZmllZCBhZmZlY3RpdmUsIHNlbWFudGljLCBhbmQgcGVyY2VwdHVhbCBjbHVzdGVycy4NCiogSWYgYSBjZWxsIGhhcyBvbmUgb3IgbWVtYmVycywga2VlcCB0aGUgb25lIHRoYXQgaGFzIHRoZSBiZXN0IHNpbGhvdWV0dGUgc3RhdGlzdGljIHJlbGF0aXZlIHRvIHBlcmNlcHR1YWwgY2x1c3RlcmluZywgZnJlZSB1cCBvdGhlcnMNCiogTG9vcCB0aHJvdWdoIGNlbGxzIHdpdGhvdXQgYW55IG1lbWJlcnMgaW4gcmFuZG9taXplZCBvcmRyZWQNCiogUmFuayBhbGwgZnJlZSBpbWFnZXMgZnJvbSB0aGUgYWZmZWN0ZWQgc2VtYW50aWMgYW5kIGVtb3Rpb24gY2x1c3RlciBhbmQgYW55IHBlcmNlcHR1YWwgY2x1c3RlciBiYXNlZCBvbiBhKSB0aGVpciBkaXN0YW5jZSB0byB0aGUgY2VudHJvaWQgb2YgdGhlIHByZWNlcHR1YWwgY2x1c3RlciBidWlsZCBmcm9tIG9ubHkgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBpbWFnZXMgYW5kIGIpIGVtb3Rpb25hbCBjbHVzdGVyDQoqIElmIHRoZSBhYm92ZSBzdGVwIGRvZXMgbm90IHlpZWxkIGFueSBpbWFnZXMsIGNvbnNpZGVyIHBpY3R1cmVzIGZyb20gb3RoZXIgZW1vdGlvbmFsIGNhdGVnb3JpZXMgY2xvc2VzdCB0byB0aGUgY3VycmVudCBzZWVkIHVudGlsIGF0IGxlYXN0IG9uZSBpcyBmb3VuZCANCg0KDQpgYGB7ciBCVUlMRCBKT0lOVCBDTFVTVEVSLCBlY2hvPUYsIHdhcm5pbmc9RiwgbWVzc2FnZSA9IEYsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTE0fQ0KDQoJZDIgPSB2YXJ1DQoJDQoJIyBzZXQgYWxsIGltYWdlcyB0byBiZSBpbmNsdWRlZA0KCWQyJGluY2x1ZGUgPSAxDQoJIyByZW1vdmUgYW55IHplcm9lZCBvdXQgY2x1c3RlcnMNCglkMiRpbmNsdWRlW2QyJGxvd0NsdXN0PT0wIHwgZDIkc2VtQ2x1c3Q9PTAgfCBkMiRlbW9DbHVzdD09MF0gPSAwDQoJIyBwbG90IHRoZSBpbml0aWFsLCBuYXR1cmFsIGRpc3RyaWJ1dGlvbiBvZiBpbWFnZXMgYmV0d2VlbiB0aGUgY2F0ZWdvcmllcw0KCXdpdGgoZDJbZDIkaW5jbHVkZT09MSxdLHBsb3QodGFibGUobG93Q2x1c3QsIGVtb0NsdXN0LCBzZW1DbHVzdCksIG1haW4gPSAiYmVmb3JlIikpDQoNCgkjIGZyZWUgdXAgaW1hZ2VzIHRvIGJlIHJlLWFzc2lnbmVkIA0KCWZvcihzIGluIHNldGRpZmYodW5pcXVlKGQyJHNlbUNsdXN0KSwwKSl7DQoJCWZvcihlIGluIHNldGRpZmYodW5pcXVlKGQyJGVtb0NsdXN0KSwwKSl7DQoJCQlmb3IobCBpbiBzZXRkaWZmKHVuaXF1ZShkMiRsb3dDbHVzdCksMCkpew0KCQkJCWluZHMgPSB3aGljaChkMiRzZW1DbHVzdCA9PSBzICYgZDIkbG93Q2x1c3QgPT0gbCAmIGQyJGVtb0NsdXN0ID09IGUgJiBkMiRpbmNsdWRlPT0xKQ0KCQkJCSMgc2tpcCBpZiB0aGVyZSBhcmUgbm9uZSBvciB0aGVyZSBpcyBqdXN0IG9uZSwgb3RoZXJ3aXNlIHBpY2sgdGhlIGJlc3QNCgkJCQlpZihsZW5ndGgoaW5kcyk+MSl7DQoJCQkJCSMga2VlcCBqdXN0IHRoZSBvbmUgd2hpY2ggaXMgdGhlIGJlc3QgbWF0Y2ggdG8gdGhlIGpvaW50IGNsdXN0ZXIgKHNtYWxsZXIgPSBiZXR0ZXIpDQoJCQkJCSMgcm5rID0gcmFuayhkMiRsb3dDbHVzdFJhbmtbaW5kc10qdy5sb3cgKyBkMiRlbW9DbHVzdFJhbmtbaW5kc10qdy5lbW8gKyBkMiRzZW1DbHVzdFJhbmtbaW5kc10qdy5zZW0sdGllcy5tZXRob2QgPSAicmFuZG9tIikNCgkJCQkJDQoJCQkJCSMga2VlcCBqdXN0IHRoZSBvbmUgd2hpY2ggaXMgdGhlIGJlc3QgbWF0Y2ggdG8gdGhlIHBlcmNlcHR1YWwgY2x1c3Rlcg0KCQkJCQlybmsgPSByYW5rKGQyJGxvd0NsdXN0UmFua1tpbmRzXSx0aWVzLm1ldGhvZCA9ICJyYW5kb20iKQ0KDQoJCQkJCSMgemVybyBvdXQgYW55dGhpbmcgYmV5b25kIHRoZSBiZXN0DQoJCQkJCWQyJGluY2x1ZGVbaW5kc1tybms+MV1dID0gMA0KCQkJCX0NCgkJCX0NCgkJfQ0KCX0NCgkNCgljb21iID0gZXhwYW5kLmdyaWQoInNlbSIgPSBzZXRkaWZmKHVuaXF1ZShkMiRzZW1DbHVzdCksMCksImVtbyIgPSBzZXRkaWZmKHVuaXF1ZShkMiRlbW9DbHVzdCksMCksImxvdyIgPSBzZXRkaWZmKHVuaXF1ZShkMiRsb3dDbHVzdCksMCkpDQoJY29tYiRleGlzdCA9IGFwcGx5KGNvbWIsMSxmdW5jdGlvbih4KSBhbnkoZDIkZW1vQ2x1c3Q9PXhbImVtbyJdICYgZDIkc2VtQ2x1c3QgPT0geFsic2VtIl0gJiBkMiRsb3dDbHVzdCA9PSB4WyJsb3ciXSkpDQoNCgkjICMgcHJlcGFyZSBmb3IgcGVyY2VwdHVhbCBjbHVzdGVyaW5nIChtb3ZlIHRvIGFib3ZlKQ0KCWxvd01hdCA9IGFzLmRhdGEuZnJhbWUoYXBwbHkoc3VtLmZlYXRbLTFdLDIsc2NhbGUpKQ0KCWVtb01hdCA9IGFzLmRhdGEuZnJhbWUoYXBwbHkoZW1vLmZlYXRbLTFdLDIsc2NhbGUpKQ0KCXNlbU1hdCA9IGFzLmRhdGEuZnJhbWUoYXBwbHkoc2VtLmZlYXRbLTFdLDIsc2NhbGUpKQ0KDQoJIyBtYWtlIGEgdmVjdG9yIHRvIHJldmVydCB0byBpbiBjYXNlIHRoZSBzZWFyY2ggZmFpbHMNCgliYWNrdXAuZDIgPSBkMjsgYmFja3VwLmNvbWIgPSBjb21iDQoNCglzZWVrZXIgPSBsaXN0KCkNCgkNCglmZWF0ID0gYXMuZGF0YS5mcmFtZShhcHBseShkMlssYyhuYW1lcyhzdW0uZmVhdFstMV0pLG5hbWVzKGVtby5mZWF0KVstMV0sbmFtZXMoc2VtLmZlYXQpWy0xXSldLDIsZnVuY3Rpb24oeCkgc2NhbGUoeCxjZW50ZXI9RikpKQ0KDQoJZm9yKGogaW4gMToxMDAwKSB7DQoNCgkJZDIgPSBiYWNrdXAuZDINCgkJY29tYiA9IGJhY2t1cC5jb21iDQoJCQ0KCQkjIGxvb3AgdGhyb3VnaCBjZWxscyB3aXRoIG1pc3NpbmcgaW1hZ2VzIGluIHJhbmRvbSBvcmRlciANCgkJZm9yIChpIGluIHNhbXBsZSh3aGljaChjb21iJGV4aXN0PT1GKSkpIHsNCgkJCQ0KCQkJIyBwaWN0dXJlcyBub3QgY3VycmVudGx5IHNlbGVjdGVkIGZyb20gdGhlIHNlbWFudGljIGFuZCBhZmZlY3RpdmUgY2F0ZWdvcnkgY29tYmluYXRpb24NCgkJCWZyZWUgPC0gd2hpY2goZDIkaW5jbHVkZSA9PSAwICYgZDIkc2VtQ2x1c3QgPT0gY29tYltpLCJzZW0iXSAmIGQyJGVtb0NsdXN0ID09IGNvbWJbaSwiZW1vIl0pDQoJCQkNCgkJCSMgaWYgbm9uZSBpcyBmb3VuZCwgZmluZCB0aGUgaW1hZ2UgdGhhdCBoYXMgc21hbGxlc3Qgd2VpZ2h0ZWQgZGlzdGFuY2UgdG8gdGhlIGVtb3Rpb25hbCBhbmQgcGVyY2VwdHVhbCBzZWVkIHdpdGhpbmcgdGhlIHNhbWUgc2VtYW50aWMgY2F0ZWdvcnkNCgkJCW4gPSAwDQoJCQl3aGlsZShsZW5ndGgoZnJlZSk9PTApew0KCQkJCW4gPSBuICsgMQ0KCQkJCWVtb0Rpc3QgPSBzY2FsZShteUV1Y2xpZChlbW9NYXQsdChhcHBseShhcy5tYXRyaXgoZW1vTWF0W2QyJGVtb0NsdXN0PT1jb21iW2ksImVtbyJdLF0pLDIsbWVhbikpKSkqdy5lbW8NCgkJCQlsb3dEaXN0ID0gc2NhbGUobXlFdWNsaWQobG93TWF0LHQoYXBwbHkobG93TWF0W2QyJGxvd0NsdXN0PT1jb21iW2ksImxvdyJdICYgZDIkaW5jbHVkZSA9PSAxLF0sMixtZWFuKSkpKSp3Lmxvdw0KDQoJCQkJZnJlZSA8LSBpbnRlcnNlY3Qod2hpY2goZDIkaW5jbHVkZSA9PSAwICYgZDIkc2VtQ2x1c3QgPT0gY29tYltpLCJzZW0iXSksIG9yZGVyKGVtb0Rpc3QrbG93RGlzdClbMTpuXSkNCgkJCX0NCgkNCgkJCSMgZ2V0IGRpc3RhbmNlcywgd2VpZ2ggZGlmZmVyZW50IGFzcGVjdHMgDQoJCQkjIHRvIHVzZSB0aGUgY3VycmVudCBjZW50cm9pZCwgcmF0aGVyIHRoYW4gdGhlIG9yaWdpbmFsIG9uZSBmb3IgbG93IGxldmVsIGFkZCB0aGlzIHRvIGZpcnN0IGxpbmUgJiBkMiRpbmNsdWRlID09IDENCgkJCWRpc3RhbmNlcyA9IHNjYWxlKG15RXVjbGlkKGxvd01hdFtmcmVlLF0sdChhcHBseShsb3dNYXRbZDIkbG93Q2x1c3Q9PWNvbWJbaSwibG93Il0gJiBkMiRpbmNsdWRlID09IDEsXSwyLG1lYW4pKSksY2VudGVyPUYpKncubG93ICsNCgkJCQlzY2FsZShteUV1Y2xpZChlbW9NYXRbZnJlZSxdLHQoYXBwbHkoYXMubWF0cml4KGVtb01hdFtkMiRlbW9DbHVzdD09Y29tYltpLCJlbW8iXSxdKSwyLG1lYW4pKSksY2VudGVyPUYpKncuZW1vIA0KCQkJI2xlbmd0aChpbmRzKSsgbXlFdWNsaWQoc2VtTWF0W2ZyZWUsXSx0KGFwcGx5KHNlbU1hdFtkMiRzZW1DbHVzdD09Y29tYltpLCJzZW0iXSxdLDIsbWVhbikpKSp3LnNlbQ0KCQkJDQoJCQkjIGFkZGluZyB0aGUgY2xvc2VzdCBwaWN0dXJlIHRvIGEgY2x1c3RlciAoaGVyZSBzbWFsbGVyIGlzIGJldHRlcikNCgkJCWQyW2ZyZWVbb3JkZXIoZGlzdGFuY2VzKVsxXV0sYygiaW5jbHVkZSIsICJsb3dDbHVzdCIsICJlbW9DbHVzdCIsICJzZW1DbHVzdCIpXSA9IGMoMSxjb21iW2ksImxvdyJdLCBjb21iW2ksImVtbyJdLCBjb21iW2ksInNlbSJdKQ0KCQkJY29tYltpLCJleGlzdCJdID0gVA0KCQl9DQoJDQoJDQoJCSMgd2Ugd2FudCB0aGUgcGVyY2VwdHVhbCBtZWFucyBhbmQgc3RhbmRhcmQgZGV2aWF0b24gdG8gYmUgYXMgc2ltaWxhciBhcyBwb3NzaWJsZSBhY3Jvc3MgZW1vdGlvbmFsIGFuZCBzZW1hbnRpYyBjbHVzdGVycyAuDQoJCSMgbWVhbiB3aXRoaW4gZWFjaCBjbHVzdGVyIG9uIGVhY2ggbWVhc3VyZSwgU0Qgb2YgdGhvc2UgbWVhbnMgb24gZWFjaCBtZWFzdXJlLCBtZWFuIG9mIHRob3NlIFNEcyAgDQoJCWVtby5kaWZmID0gbWVhbihhcHBseShzYXBwbHkoc3BsaXQoZmVhdFtkMiRpbmNsdWRlPT0xLG5hbWVzKHN1bS5mZWF0Wy0xXSldLGQyJGVtb0NsdXN0W2QyJGluY2x1ZGU9PTFdKSwgDQoJCQkJCQkJCQkJCQkJCQkJCQkJIGZ1bmN0aW9uKHgpIGFwcGx5KHgsMixtZWFuKSksMSxzZCkpICsNCgkJCSMgc2FtZSBmb3IgU0Qgd2l0aGluIGVhY2ggY2x1c3Rlcg0KCQkJCQkJCW1lYW4oYXBwbHkoc2FwcGx5KHNwbGl0KGZlYXRbZDIkaW5jbHVkZT09MSxuYW1lcyhzdW0uZmVhdFstMV0pXSxkMiRlbW9DbHVzdFtkMiRpbmNsdWRlPT0xXSksIA0KCQkJCQkJCQkJCQkJCQkJCQkJCSBmdW5jdGlvbih4KSBhcHBseSh4LDIsc2QpKSwxLHNkKSkNCg0KCQlzZW0uZGlmZiA9IG1lYW4oYXBwbHkoc2FwcGx5KHNwbGl0KGZlYXRbZDIkaW5jbHVkZT09MSxuYW1lcyhzdW0uZmVhdFstMV0pXSxkMiRzZW1DbHVzdFtkMiRpbmNsdWRlPT0xXSksIA0KCQkJCQkJCQkJCQkJCQkJCQkJCSBmdW5jdGlvbih4KSBhcHBseSh4LDIsbWVhbikpLCAxLHNkKSkgKyANCgkJCQkJCQltZWFuKGFwcGx5KHNhcHBseShzcGxpdChmZWF0W2QyJGluY2x1ZGU9PTEsbmFtZXMoc3VtLmZlYXRbLTFdKV0sZDIkc2VtQ2x1c3RbZDIkaW5jbHVkZT09MV0pLCANCgkJCQkJCQkJCQkJCQkJCQkJCQkgZnVuY3Rpb24oeCkgYXBwbHkoeCwyLHNkKSksIDEsc2QpKQ0KDQoJCQkNCgkJCQ0KCQlzZWVrZXIkY3JpdFtqXSA9IGVtby5kaWZmICsgc2VtLmRpZmYNCgkJDQoJCXNlZWtlciRpbmNsdWRlW1tqXV0gPSBkMiRpbmNsdWRlDQoJCXNlZWtlciRsb3dDbHVzdFtbal1dID0gZDIkbG93Q2x1c3QNCgkJDQoJfQ0KDQoJcGxvdChzb3J0KHNlZWtlciRjcml0KSwgbWFpbiA9ICJCZXR3ZWVuLWNsdXN0ZXIgdmFyaWFuY2UgZnJvbSAxMDAwIHJ1bnMiKQ0KCWQyJGluY2x1ZGUgPSBzZWVrZXIkaW5jbHVkZVtbd2hpY2gubWluKHNlZWtlciRjcml0KV1dDQoJZDIkbG93Q2x1c3QgPSBzZWVrZXIkbG93Q2x1c3RbW3doaWNoLm1pbihzZWVrZXIkY3JpdCldXQ0KDQoJZDMgPSBkMltkMiRpbmNsdWRlPT0xLF0NCg0KDQpgYGANCg0KYGBge3IgVklTVUFMSVpFIENMVVNURVJTLCBlY2hvPUYsIHdhcm5pbmc9RiwgbWVzc2FnZSA9IEYsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTE0fQ0KDQoJZDMgPSBkMltkMiRpbmNsdWRlPT0xLF0NCg0KCXdpdGgoZDJbZDIkaW5jbHVkZT09MSxdLHBsb3QodGFibGUobG93Q2x1c3QsIGVtb0NsdXN0LCBzZW1DbHVzdCksIG1haW4gPSAiYWZ0ZXIiKSkNCgkNCgkjIHBsb3QgdGhlIGNsdXN0ZXIgbWV0cmljcyANCglmdml6X3NpbGhvdWV0dGUoc2lsaG91ZXR0ZShkMiRsb3dDbHVzdFtkMiRpbmNsdWRlPT0xXSwgZGlzdChzdW0uZmVhdFtkMiRpbmNsdWRlPT0xLC0xXSkpLHByaW50LnN1bW1hcnkgPSBGKSArIGxhYnModGl0bGUgPSAiUHJ1bmVkIHBlcmNlcHR1YWwgY2x1c3RlcmluZyIpICsgcGx0DQoJDQoJZnZpel9zaWxob3VldHRlKHNpbGhvdWV0dGUoZDIkc2VtQ2x1c3RbZDIkaW5jbHVkZT09MV0sIGRpc3Qoc2VtLmZlYXRbZDIkaW5jbHVkZT09MSwtMV0pKSxwcmludC5zdW1tYXJ5ID0gRikgKyBsYWJzKHRpdGxlID0gIlBydW5lZCBzZW1hbnRpYyBjbHVzdGVyaW5nIikgKyBwbHQNCgkNCglmdml6X3NpbGhvdWV0dGUoc2lsaG91ZXR0ZShkMiRlbW9DbHVzdFtkMiRpbmNsdWRlPT0xXSwgZGlzdChlbW8uZmVhdFtkMiRpbmNsdWRlPT0xLC0xXSkpLHByaW50LnN1bW1hcnkgPSBGKSArIGxhYnModGl0bGUgPSAiUHJ1bmVkIGVtb3Rpb25hbCBjbHVzdGVyaW5nIikgKyBwbHQNCg0KDQoNCgkjIGlkZW50aWZ5IHByb3RvdHlwaWNhbCBwaWN0dXJlcw0KCSMgZDIkcHJvdG8gPSB1bnNwbGl0KHNhcHBseShzcGxpdChkMiRtZW1iZXJRdWFsaXR5LGQyJGxvd0NsdXN0KSwgZnVuY3Rpb24oeCkgaWZlbHNlKHJhbmsoeCx0aWVzLm1ldGhvZCA9ICJyYW5kb20iKTw9MywxLDApKSxkMiRsb3dDbHVzdCkNCg0KIyB2aWV3IHBlcmNlcHR1YWwgZmVhdHVyZXMNCglwbGQgPSBtZWx0KGQzWyxjKCJsb3dDbHVzdCIsIG5hbWVzKGxvdy5mZWF0KSldLGlkLnZhcnMgPSBjKCJJRCIsImxvd0NsdXN0IikpDQoJcGxkJHNhbXBsZSA9IGFzLm51bWVyaWModW5saXN0KHJlZ21hdGNoZXMocGxkJHZhcmlhYmxlLGdyZWdleHByKCJbMC05XSsiLHBsZCR2YXJpYWJsZSkpKSkNCglwbGQkdmFyaWFibGUgPSBnc3ViKCJbMC05XSsiLCIiLHBsZCR2YXJpYWJsZSkNCglwbGQgPSBwbGRbcGxkJHZhcmlhYmxlICVpbiUgYygiYmx1ZVllbGxvdyIsICJncmVlblJlZCIsICJsdW1pbmFuY2UiLCAic3BlY3RydW1fcmF2ZyIpLF0NCgkNCglnZ3Bsb3QocGxkLGFlcyh4PXNhbXBsZSx5PXZhbHVlLCBjb2xvciA9IGxvd0NsdXN0LCBmaWxsID0gbG93Q2x1c3QsIGdyb3VwID0gbG93Q2x1c3QpKSArIHN0YXRfc3VtbWFyeShmdW4ueSA9ICJtZWFuIiwgZ2VvbSA9ICJsaW5lIikgKyANCgkJZmFjZXRfd3JhcCh+dmFyaWFibGUsIHNjYWxlcyA9ICJmcmVlIikgKyANCgkJIyBzdGF0X3N1bW1hcnkoZ2VvbSA9ICJyaWJib24iLCBhbHBoYSA9IDAuMDUpICsgDQoJCXBsdCArIGxhYnModGl0bGUgPSAiTWVhbiBsb3ctbGV2ZWwgcHJvZmlsZXMgb2YgaWRlbnRpZmllZCBjbHVzdGVycyIpDQoNCgkNCgkjIHZpZXcgc2VtYW50aWMgZmVhdHVyZXMNCgkNCg0KCSMgcGxvdCB0aGUgYWZmZWN0aXZlIGRpc3RyaWJ1dGlvbg0KCWdncGxvdChkMyxhZXMoeD12YWxlbmNlLCB5ID0gYXJvdXNhbCwgY29sb3IgPSBlbW9DbHVzdCkpICsgZ2VvbV9wb2ludCgpICsgcGx0ICsgZmFjZXRfd3JhcCh+bG93Q2x1c3QpICsgDQoJCWxhYnModGl0bGUgPSAiQWZmZWN0aXZlIGZlYXR1cmVzIGluIHBlcmNwZXR1YWwgY2x1c3RlcnMiKQ0KCQ0KCSMgcGxvdCB0aGUgYWZmZWN0aXZlIGRpc3RyaWJ1dGlvbg0KCWdncGxvdChkMyxhZXMoeD12YWxlbmNlLCB5ID0gYXJvdXNhbCwgY29sb3IgPSBlbW9DbHVzdCkpICsgZ2VvbV9wb2ludCgpICsgcGx0ICsgZmFjZXRfd3JhcCh+c2VtQ2x1c3QpICsgDQoJCWxhYnModGl0bGUgPSAiQWZmZWN0aXZlIGZlYXR1cmVzIGluIHNlbWFudGljIGNsdXN0ZXJzIikNCg0KDQoJIyBWaWV3IHR5cGljYWwgcGljdHVyZXMNCgkjIHByb3RvID0gZDJbZDIkcHJvdG8+MCwgYygibG93Q2x1c3QiLCJwcm90byIsICJhZGRyZXNzIiwgImltYWdlRmlsZSIpXQ0KCSMgZm9yKGkgaW4gMTpkaW0ocHJvdG8pWzFdKXsNCgkjIAlwcm90b1tpLCJsb2FkIl0gPSBwYXN0ZTAoZ3N1YigiUzovU3lsdmlhIiwiLy9oc2ZpbGVzL3BzeWNob3BoeXNpb2xvZ3kvU0JFUiIsZ3N1YigiXFwiLCIvIiwgYXMuY2hhcmFjdGVyKHByb3RvJGFkZHJlc3NbaV0pLGZpeGVkID0gVCkpLA0KCSMgCQkJCQkJCQkJIGFzLmNoYXJhY3Rlcihwcm90byRpbWFnZUZpbGVbaV0pKQ0KCSMgfQ0KCQ0KCSMgZm9yKGkgaW4gdW5pcXVlKHByb3RvJGxvd0NsdXN0KSl7DQoJIyAJbGF5b3V0KG1hdHJpeCgxOjMsMSwzKSkNCgkjIAlmb3IgKGogaW4gcHJvdG9bcHJvdG8kbG93Q2x1c3Q9PWksImxvYWQiXSl7DQoJIyAJCXByaW50KHBsb3QobG9hZC5pbWFnZShqKSxtYWluID0gaSxheGVzPUYpKQ0KCSMgCX0NCgkjIH0NCgkNCg0KCQ0KYGBgDQoNCiMjIDUuIFNldCBjb21waWxhdGlvbg0KDQpXZSBub3cgaGF2ZSBuIGNsdXN0ZXJzIG9mIGsgcGljdHVyZXMgb2YgcCBjb250ZW50cy4gVXNlIGxhdGluIHNxdWFyZSB0byBkaXN0cmlidXRlIHNlbWFudGljIGNvbnRlbnRzIHJhbmRvbWx5IGFjcm9zcyBwYXJhbGxlbCB2ZXJzaW9ucy4NCg0KYGBge3IgQlVJTEQgU0VUUywgbWVzc2FnZSA9IEYsIGVjaG89Riwgd2FybmluZz1GLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xNH0NCg0KDQoJZDMgPSByZWFkLmNzdjIocGFzdGUwKHJvb3QsIi9ub3JtaW5nIHN0dWR5L3NldHVwL2ltYWdlcy9pbWFnZV9kYXRhLmNzdiIpKQ0KDQoJZDMkYXNzaWduID0gZmFjdG9yKGQzJGVtb0NsdXN0LCBsYWJlbHMgPSBwcm0kZW1vKQ0KDQoJc2Vla2VyID0gbGlzdCgpDQoJDQoJZmVhdCA9IGFzLmRhdGEuZnJhbWUoYXBwbHkoZDNbLGMobmFtZXMoc3VtLmZlYXRbLTFdKSxuYW1lcyhlbW8uZmVhdClbLTFdLG5hbWVzKHNlbS5mZWF0KVstMV0pXSwyLGZ1bmN0aW9uKHgpIHNjYWxlKHgsY2VudGVyPUYpKSkNCg0KDQoJZm9yKGkgaW4gMToxMDAwKSB7DQoJDQoJCWQzJHBpY3NldCA9IE5VTEwNCgkJZm9yIChsIGluIHVuaXF1ZShkMyRsb3dDbHVzdCkpew0KCQkJIyBtYWtlIGEgbmV3IGxhdGluIHNxdWFyZSBmb3IgZWFjaCByb3VuZA0KCQkJIyBsYXRpbiA9IGxhdGluc3F1YXJlKHBybSRzZXROdW1bMV0sMikNCgkJCSMgbWFrZSBhIGxhcmdlciBsYXRpbiBzcXVhcmUgYW5kIGp1c3QgcGljayBmcm9tIGl0DQoJCQlsYXRpbiA9IGNiaW5kKGxhdGluc3F1YXJlKDMsMyksbGF0aW5zcXVhcmUoMywzKSkNCgkJCWZvciAocyBpbiBzZXFfYWxvbmcodW5pcXVlKGQzJHNlbUNsdXN0KSkpew0KCQkJCWZvciAoZSBpbiBzZXFfYWxvbmcodW5pcXVlKGQzJGVtb0NsdXN0KSkpew0KCQkJCQlkMyRwaWNzZXRbZDMkbG93Q2x1c3QgPT0gbCAmIGQzJHNlbUNsdXN0ID09IHVuaXF1ZShkMyRzZW1DbHVzdClbc10gJiBkMyRlbW9DbHVzdCA9PSB1bmlxdWUoZDMkZW1vQ2x1c3QpW2VdXSA9IExFVFRFUlNbbGF0aW5bZSxzXV0NCgkJCQl9DQoJCQl9DQoJCX0NCgkJDQoJCXNlZWtlciRjcml0W2ldID0gbWVhbihhcHBseShzYXBwbHkoc3BsaXQoZmVhdCxkMyRwaWNzZXQpLCBmdW5jdGlvbih4KSBhcHBseSh4LDIsbWVhbikpLCAxLHNkKSkgKw0KCQkJCQkJCQkJCSBtZWFuKGFwcGx5KHNhcHBseShzcGxpdChmZWF0LGQzJHBpY3NldCksIGZ1bmN0aW9uKHgpIGFwcGx5KHgsMixzZCkpLCAxLHNkKSkNCgkNCgkJaWYgKGxlbmd0aCh1bmlxdWUodGFibGUoZDMkcGljc2V0KSkpPjEpew0KCQkJc2Vla2VyJGNyaXRbaV0gPSBtYXgoc2Vla2VyJGNyaXQpDQoJCX0NCgkJDQoJCXNlZWtlciRwaWNzZXRbW2ldXSA9IGQzJHBpY3NldA0KCX0NCgkNCiAgcGxvdChzb3J0KHNlZWtlciRjcml0KSwgbWFpbiA9ICJCZXR3ZWVuLXBpY3NldCB2YXJpYW5jZSBmcm9tIDEwMDAgcnVucyIpDQoNCglkMyRwaWNzZXQgPSBzZWVrZXIkcGljc2V0W1t3aGljaC5taW4oc2Vla2VyJGNyaXQpXV0NCg0KCQ0KCSMgZm9yIE1UdXJrDQoJZDMkYWRkX3F1ZXN0aW9uX3JhbmsgPSB1bnNwbGl0KGxhcHBseShzcGxpdChkMyRlbW9DbHVzdFJhbmssbGlzdChkMyRhc3NpZ24sZDMkcGljc2V0KSksZnVuY3Rpb24oeCkgcmFuayh4LCB0aWVzLm1ldGhvZCA9ICJyYW5kb20iKSksbGlzdChkMyRhc3NpZ24sZDMkcGljc2V0KSkNCg0KCSMgYWRkIGF0dGVudGlvbiBjaGVjayB0byBlYWNoIDR0aCBhbmQgNXRoIGltYWdlIGluIGRpc3RhbmNlIGZyb20gZW1vIHNlZWQNCglkMyRhZGRfcXVlc3Rpb24gPSBpZmVsc2UoZDMkYWRkX3F1ZXN0aW9uX3Jhbms8NiwiYXR0ZW50aW9uX2NoZWNrIiwiIikNCgkNCgkjIGFkZCBmcmVlIHJlc3BvbnNlIHRvIGVhY2ggMSwyLDNyZCBpbWFnZQ0KCWQzJGFkZF9xdWVzdGlvbltkMyRhZGRfcXVlc3Rpb25fcmFuayA8IDRdID0gImZyZWVfcmVzcG9uc2UiDQoNCgkNCgkjICMgcmVtb3ZlIGV4dHJhIHBpY3R1cmVzIGJhc2VkIG9uIGVtb0NsdXN0RGlzdA0KCSMgZDMkaW5jbHVkZSA9IGFzLm51bWVyaWModW5zcGxpdChzYXBwbHkoc3BsaXQoZDMkZW1vQ2x1c3RSYW5rLGQzJHBpY3NldCksZnVuY3Rpb24oeCkgeCAlaW4lIHhbb3JkZXIoeClbMTo2NF1dKSxkMyRwaWNzZXQpKQ0KCSMgZDMgPSBkM1tkMyRpbmNsdWRlPT0xLF0NCgkjIA0KCSMgbWFrZSB0aGVzZSBpbnRvIHByYWN0aWNlIHBpY3R1cmVzDQoNCgkNCgkjIFNVTU1BUlkgVklTVUFMDQoJZ2dwbG90KGQzLGFlcyh5PXZhbGVuY2UsIHggPSBhc3NpZ24sIGNvbG9yID0gcGljc2V0KSkgKyBzdGF0X3N1bW1hcnkocG9zaXRpb24gPSBwbC5wZCkgKyAgZ2VvbV9qaXR0ZXIoc2l6ZSA9IHBsLnNjLzIsIGFscGhhID0gMC4zKSArIHBsdCArIA0KCQlzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDAuNSkpICsgbGFicyh0aXRsZSA9ICJTZWxlY3RlZCBwaWN0dXJlcyBhbmQgbWVhbnMgYW5kIHN0YW5kYXJkIGVycm9ycyBvZiB0aGUgc2V0cyIpDQoNCgkNCgkjIFZJU1VBTElaRSBBRkZFQ1RJVkUgU0VUUw0KCXdpdGgoZDMscGxvdCh0YWJsZShhc3NpZ24sc2VtQ2x1c3QpLCBtYWluID0gIkRpc3RyaWJ1dGlvbiBvZiBzZW1hbnRpYyBjbHVzdGVycyBhY3Jvc3MgYWZmZWN0IikpDQoJZ2dwbG90KGQzLGFlcyh5PXZhbGVuY2UsIHggPSBzZW1hbnRpYywgY29sb3IgPSBhc3NpZ24pKSArIHN0YXRfc3VtbWFyeShwb3NpdGlvbiA9IHBsLnBkKSArICBnZW9tX2ppdHRlcihzaXplID0gcGwuc2MvMiwgYWxwaGEgPSAwLjMpICsgcGx0ICsgDQoJCXNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsMC41KSkgKyBsYWJzKHRpdGxlID0gIlNlbWFudGljIGNsdXN0ZXJzIHdpdGhpbiBhZmZlY3RpdmUgc3BhY2UiKQ0KCQ0KDQoJd2l0aChkMyxwbG90KHRhYmxlKGFzc2lnbixsb3dDbHVzdCksIG1haW4gPSAiRGlzdHJpYnV0aW9uIG9mIHBlcmNlcHRpYWwgY2x1c3RlcnMgYWNyb3NzIGFmZmVjdCIpKQ0KCWdncGxvdChkMyxhZXMoeT12YWxlbmNlLCB4ID0gbG93Q2x1c3QsIGNvbG9yID0gYXNzaWduKSkgKyBzdGF0X3N1bW1hcnkocG9zaXRpb24gPSBwbC5wZCkgKyAgZ2VvbV9qaXR0ZXIoc2l6ZSA9IHBsLnNjLzIsIGFscGhhID0gMC4zKSArIHBsdCArIA0KCQlzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDAuNSkpICsgbGFicyh0aXRsZSA9ICJQZXJjZXB0dWFsIGNsdXN0ZXJzIHdpdGhpbiBhZmZlY3RpdmUgc3BhY2UiKQ0KDQoNCgkjIFZJU1VBTElaRSBQQVJBTExFTCBTRVRTDQoJd2l0aChkMyxwbG90KHRhYmxlKHBpY3NldCxzZW1DbHVzdCksIG1haW4gPSAiRGlzdHJpYnV0aW9uIG9mIHNlbWFudGljIGNsdXN0ZXJzIGFjcm9zcyBwYXJhbGxlbCBzZXRzIikpDQoJZ2dwbG90KGQzLGFlcyh5PXZhbGVuY2UsIHggPSBzZW1hbnRpYywgY29sb3IgPSBwaWNzZXQpKSArIHN0YXRfc3VtbWFyeShwb3NpdGlvbiA9IHBsLnBkKSArICBnZW9tX2ppdHRlcihzaXplID0gcGwuc2MvMiwgYWxwaGEgPSAwLjMpICsgcGx0ICsgDQoJCXNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsMC41KSkgKyBsYWJzKHRpdGxlID0gIlNlbWFudGljIGNsdXN0ZXJzIGFjcm9zcyBwYXJhbGxlbCBzZXRzIikNCg0KCXdpdGgoZDMscGxvdCh0YWJsZShwaWNzZXQsbG93Q2x1c3QpLCBtYWluID0gIkRpc3RyaWJ1dGlvbiBvZiBwZXJjZXB0dWFsIGNsdXN0ZXJzIGFjcm9zcyBwYXJhbGxlbCBzZXRzIikpDQoJZ2dwbG90KGQzLGFlcyh5PXZhbGVuY2UsIHggPSBsb3dDbHVzdCwgY29sb3IgPSBwaWNzZXQpKSArIHN0YXRfc3VtbWFyeShwb3NpdGlvbiA9IHBsLnBkKSArICBnZW9tX2ppdHRlcihzaXplID0gcGwuc2MvMiwgYWxwaGEgPSAwLjMpICsgcGx0ICsgDQoJCXNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsMC41KSkgKyBsYWJzKHRpdGxlID0gIlBlcmNlcHR1YWwgY2x1c3RlcnMgYWNjcm9zcyBwYXJhbGxlbCBzZXRzIikNCg0KDQojIGFkZCBjb21wYXJpc29uIG9mIGxvdy1sZXZlbCBmZWF0dXJlcw0KCXBsZCA9IG1lbHQoZDNbLGMobmFtZXMobG93LmZlYXQpLCJhc3NpZ24iLCAicGljc2V0IildLGlkLnZhcnMgPSBjKCJJRCIsImFzc2lnbiIsICJwaWNzZXQiKSkNCglwbGQkc2FtcGxlID0gYXMubnVtZXJpYyh1bmxpc3QocmVnbWF0Y2hlcyhwbGQkdmFyaWFibGUsZ3JlZ2V4cHIoIlswLTldKyIscGxkJHZhcmlhYmxlKSkpKQ0KCXBsZCR2YXJpYWJsZSA9IGdzdWIoIlswLTldKyIsIiIscGxkJHZhcmlhYmxlKQ0KCXBsZCA9IHBsZFtwbGQkdmFyaWFibGUgJWluJSBjKCJibHVlWWVsbG93IiwgImdyZWVuUmVkIiwgImx1bWluYW5jZSIsICJzcGVjdHJ1bV9yYXZnIiwgIkRpbSIpLF0NCgkJDQoJIyBjb21wYXJlIExGIGJ5IGVtb3Rpb24NCglnZ3Bsb3QocGxkLGFlcyh4PXNhbXBsZSx5PXZhbHVlLCBjb2xvciA9IGFzc2lnbiwgZmlsbCA9IGFzc2lnbiwgZ3JvdXAgPSBhc3NpZ24pKSArIHN0YXRfc3VtbWFyeShmdW4ueSA9ICJtZWFuIiwgZ2VvbSA9ICJsaW5lIikgKw0KCQlmYWNldF93cmFwKH52YXJpYWJsZSwgc2NhbGVzID0gImZyZWUiKSArIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9ICJtZWFuX3NlIiwgZ2VvbSA9ICJyaWJib24iLCBhbHBoYSA9IDAuMTUpICsgcGx0ICArIA0KCQlsYWJzKHRpdGxlID0gIlBlcmNlcHR1YWwgZXF1aXZhbGVuY2Ugb2YgdGhlIGFmZmVjdGl2ZSBjYXRlZ29yaWVzIikNCg0KCSMgY29tcGFyZSBMRiAgYnkgcGljc2V0DQoJZ2dwbG90KHBsZCxhZXMoeD1zYW1wbGUseT12YWx1ZSwgY29sb3IgPSBwaWNzZXQsIGZpbGwgPSBwaWNzZXQsIGdyb3VwID0gcGljc2V0KSkgKyBzdGF0X3N1bW1hcnkoZnVuLnkgPSAibWVhbiIsIGdlb20gPSAibGluZSIpICsNCgkJZmFjZXRfd3JhcCh+dmFyaWFibGUsIHNjYWxlcyA9ICJmcmVlIikgKyBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSAibWVhbl9zZSIsIGdlb20gPSAicmliYm9uIiwgYWxwaGEgPSAwLjE1KSArIHBsdCArDQoJCQkJbGFicyh0aXRsZSA9ICJQZXJjZXB0dWFsIGVxdWl2YWxlbmNlIG9mIHBhcmFsbGVsIHZlcnNpb25zIikNCg0KCQkJDQoJIyBzb3VyY2UgZGlzdHJpYnV0aW9pbnMNCglkMyRTZXR3TiA9IHVuc3BsaXQoc2FwcGx5KHNwbGl0KGQzLGQzJFNldCksZnVuY3Rpb24oeCkgcGFzdGUwKHgkU2V0LCAiXG5uPSIsbnJvdyh4KSwiIikpLGQzJFNldCkNCglnZ3Bsb3QoZDMsYWVzKHg9dmFsZW5jZSwgeSA9IGFyb3VzYWwsIGNvbG9yID0gU2V0d04pKSArIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsgcGx0ICsgZmFjZXRfd3JhcCh+U2V0d04pICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIA0KCQlsYWJzKHRpdGxlID0gIlNvdXJjZSBwaWN0dXJlIHNldHMiLCBzdWJ0aXRsZSA9IHBhc3RlMCgibj0gIixucm93KGQzKSkpDQoNCgkNCgkjIHN0YXRpc3RpY3MNCgkjIGNvbXAgPSBkYXRhLmZyYW1lKHZhcmlhYmxlID0gc2V0ZGlmZih1bmlxdWUoYyhuYW1lcyhzdW0uZmVhdFstMV0pLCBuYW1lcyhsb3cuZmVhdFstMV0pKSksInNwZWN0cnVtX3JhdmcyMCIpKQ0KCWNvbXAgPSBkYXRhLmZyYW1lKHZhcmlhYmxlID0gbmFtZXMoc3VtLmZlYXRbLTFdKSkNCg0KCWNvbXAkdmFyaWFibGUgPSBhcy5jaGFyYWN0ZXIoY29tcCR2YXJpYWJsZSkNCglmb3IodmFyIGluIGNvbXAkdmFyaWFibGUpew0KCQljb21wJGFzc2lnbltjb21wJHZhcmlhYmxlPT12YXJdID0gc3VtbWFyeShhb3YobG0ocGFzdGUodmFyLCAifiBhc3NpZ24iKSwgZGF0YSA9IGQzWyxjKCJhc3NpZ24iLCBjb21wJHZhcmlhYmxlKV0pKSlbWzFdXSRgUHIoPkYpYFsxXQ0KCQljb21wJHNldFtjb21wJHZhcmlhYmxlPT12YXJdID0gc3VtbWFyeShhb3YobG0ocGFzdGUodmFyLCAifiBwaWNzZXQiKSwgZGF0YSA9IGQzWyxjKCJwaWNzZXQiLCBjb21wJHZhcmlhYmxlKV0pKSlbWzFdXSRgUHIoPkYpYFsxXQ0KCX0NCgkNCgkjIHdoaWNoIGZlYXR1cmVzIGRpZmZlciBzaWduaWZpY2FudGx5IGJldHdlZW4gdGhlIHNldHMNCgljb21wW2NvbXAkc2V0PC4wNSxdDQoNCgkjIA0KCWNvbXBbY29tcCRhc3NpZ248LjA1LF0NCgkNCmBgYA0KDQpgYGB7ciBFWFBPUlQgU0VUUywgaW5jbHVkZSA9IEYsIGVjaG8gPSBGLCBtZXNzYWdlID0gRiwgd2FybmluZz1GfQ0KDQppZihnZW5lcmF0ZSA9PSBUKXsNCg0KCW91dCA9IGQzDQoJDQoJIyBnZW5lcmF0ZSBkaXJlY3Rvcmllcw0KCWRpci5jcmVhdGUocGFzdGUwKHJvb3QsIm91dHB1dCIpKQ0KCWRpci5jcmVhdGUocGFzdGUwKHJvb3QsIm91dHB1dC9wb29sIikpDQoJDQoJIyBzZXQNCglkaXIuY3JlYXRlKHBhc3RlMChyb290LCJvdXRwdXQvc2V0cyIpKQ0KCQ0KCSMgZm9yKGYgaW4gdW5pcXVlKG91dCRhc3NpZ24pKXsNCgkjIAlkaXIuY3JlYXRlKHBhc3RlMChyb290LCJvdXRwdXQvc2V0cy8iLGFzLmNoYXJhY3RlcihmKSkpDQoJIyAJZm9yKHAgaW4gdW5pcXVlKG91dCRwaWNzZXQpKSB7DQoJIyAJCWRpci5jcmVhdGUocGFzdGUwKHJvb3QsIm91dHB1dC9zZXRzLyIsYXMuY2hhcmFjdGVyKGYpLCIvIixhcy5jaGFyYWN0ZXIocCkpKQ0KCSMgCX0NCgkjIH0NCg0KCWZvcihmIGluIHVuaXF1ZShvdXQkcGljc2V0KSl7DQoJCWRpci5jcmVhdGUocGFzdGUwKHJvb3QsIm91dHB1dC9zZXRzLyIsYXMuY2hhcmFjdGVyKGYpKSkNCgkJIyBmb3IocCBpbiB1bmlxdWUob3V0JGFzc2lnbikpIHsNCgkJIyAJZGlyLmNyZWF0ZShwYXN0ZTAocm9vdCwib3V0cHV0L3NldHMvIixhcy5jaGFyYWN0ZXIoZiksIi8iLGFzLmNoYXJhY3RlcihwKSkpDQoJCSMgfQ0KCX0NCg0KCQ0KCSMgZmlsZS5jb3B5IGNhbiBiZSB1c2VkIHRvIGFjdHVhbGx5IGJ1aWxkIHRoZSBzZXRzIGZvciB2aWV3aW5nDQoJZm9yKGYgaW4gMTpkaW0ob3V0KVsxXSl7DQoNCgkJCWZyb20gPC0gcGFzdGUwKGdzdWIoIlM6LyIsIi8vaHNmaWxlcy9wc3ljaG9waHlzaW9sb2d5LyIsZ3N1YigiXFwiLCIvIiwgYXMuY2hhcmFjdGVyKG91dCRhZGRyZXNzW2ZdKSxmaXhlZCA9IFQpKSwNCgkJCQkJCQkJCQkgYXMuY2hhcmFjdGVyKG91dCRpbWFnZUZpbGVbZl0pKQ0KCQkJDQoJCQkjIHdyaXRlIHRvIHNldC1sZXZlbCBmb2xkZXINCgkJCSN0byA8LSBwYXN0ZTAocm9vdCwib3V0cHV0L3NldHMvIixhcy5jaGFyYWN0ZXIob3V0JGFzc2lnbltmXSksIi8iLGFzLmNoYXJhY3RlcihvdXQkcGljc2V0W2ZdKSwiLyIsYXMuY2hhcmFjdGVyKG91dCRpbWFnZUZpbGVbZl0pKQ0KCQkJIyB0byA8LSBwYXN0ZTAocm9vdCwib3V0cHV0L3NldHMvIixhcy5jaGFyYWN0ZXIob3V0JHBpY3NldFtmXSksIi8iLGFzLmNoYXJhY3RlcihvdXQkYXNzaWduW2ZdKSwiLyIsYXMuY2hhcmFjdGVyKG91dCRpbWFnZUZpbGVbZl0pKQ0KCQkJdG8gPC0gcGFzdGUwKHJvb3QsIm91dHB1dC9zZXRzLyIsYXMuY2hhcmFjdGVyKG91dCRwaWNzZXRbZl0pLCIvIixhcy5jaGFyYWN0ZXIob3V0JGltYWdlRmlsZVtmXSkpDQoJCQlmaWxlLmNvcHkoZnJvbSx0bykNCgkJCQ0KCQkJIyB3cml0ZSB0byBvbmUgYmlnIHBvb2wNCgkJCXRvIDwtIHBhc3RlMChyb290LCJvdXRwdXQvcG9vbC8iLGFzLmNoYXJhY3RlcihvdXQkaW1hZ2VGaWxlW2ZdKSkNCgkJCWZpbGUuY29weShmcm9tLHRvKQ0KCX0NCgl3cml0ZS5jc3YyKG91dCwgcGFzdGUwKHJvb3QsIi9vdXRwdXQvcG9vbC5jc3YiKSkNCg0KCQ0KCSMgIyAjIGdlbmVyYXRlIHRoZSBzYW1wbGUgcGljdHVyZSBwb29sIChvbmUgZnJvbSBlYWNoIGNlbGwpDQoJIyBkaXIuY3JlYXRlKHBhc3RlMChyb290LCJvdXRwdXQvc2FtcGxlIikpDQoNCgkjIHNhbXBsZSA9IE5VTEwNCgkjIGZvcihzIGluIHVuaXF1ZShvdXQkcGljc2V0KSl7DQoJIyAJZm9yKGUgaW4gdW5pcXVlKG91dCRhc3NpZ24pKXsNCgkjIAkJc2FtcGxlID0gYyhzYW1wbGUsIHdoaWNoKG91dCRwaWNzZXQ9PXMgJiBvdXQkYXNzaWduPT1lKVsxXSkNCgkjIAl9DQoJIyB9DQoNCgkjIG91dCA9IG91dFtzYW1wbGUsXQ0KCSMgIyBmaWxlLmNvcHkgY2FuIGJlIHVzZWQgdG8gYWN0dWFsbHkgYnVpbGQgdGhlIHNldHMgZm9yIHZpZXdpbmcNCgkjIGZvcihmIGluIDE6ZGltKG91dClbMV0pew0KCSMgDQoJIyAJCWZyb20gPC0gcGFzdGUwKGdzdWIoIlM6L1N5bHZpYSIsIi8vaHNmaWxlcy9wc3ljaG9waHlzaW9sb2d5L1NCRVIiLGdzdWIoIlxcIiwiLyIsIGFzLmNoYXJhY3RlcihvdXQkYWRkcmVzc1tmXSksZml4ZWQgPSBUKSksDQoJIyAJCQkJCQkJCQkgYXMuY2hhcmFjdGVyKG91dCRpbWFnZUZpbGVbZl0pKQ0KCSMgCQl0byA8LSBwYXN0ZTAocm9vdCwib3V0cHV0L3NhbXBsZS8iLGFzLmNoYXJhY3RlcihvdXQkaW1hZ2VGaWxlW2ZdKSkNCgkjIAkJZmlsZS5jb3B5KGZyb20sdG8pDQoJIyB9DQoJIyB3cml0ZS5jc3YyKG91dCwgcGFzdGUwKHJvb3QsIi9vdXRwdXQvc2FtcGxlLmNzdiIpKQ0KCQ0KfQkNCmBgYA0KDQojIFJFRkVSRU5DRVM=