PROJECT OUTLINE

Arteriovenous fistula for hemodialysis access fails to clinically mature in 28-53% of the cases.

My goal is to identify inter-correlations among time-changes in fistula morphology, hemodynamics, gene expression, and smooth muscle cell and endothelial cell dysfunctions. These results can play a fundamental role in the understating of fistula maturation and failure causes, influencing clinical techniques as well as innovative strategies for fistula maturation.


BACKGROUND

Over 650,000 Americans are affected by end stage renal disease, which requires hemodialysis treatment until availability for kidney transplant. Arteriovenous fistula, a surgical connection between artery and vein of the arm, is recognized as the best hemodialysis access, as it has been reported to have lower thrombosis and infection rates compared to other fistulas. However, obtaining clinically mature fistula is challenging and the causes of fistula maturation failures are unknown. Research investigations are being performed to gain an insight into the mechanisms of maturation failure, from vascular anatomy and hemodynamics, to cell dysfunction and genomics that might play a role in vascular maturation, yet among the major limitations are small data-sets and lack of interconnection among events at micro- and macro-scales.

The Division of Vascular Surgery at the University of Florida Shands Hospital has dedicated over 8 years on multiscale analyses on arteriovenous fistula maturation placing itself among the top six internationally recognized centers specialized on the topic. This vaste research has generated large patient-specific data-sets, now available for data science exploration.


DATA-SETS

The data-sets are composed by:

  1. Gene expression of monocytes and neutrophils (53,662 total) on 50 patients at two time points (baseline, 2 weeks).
    Scientific reasoning: circulating leukocytes (such as monocytes and neutrophils) play a role in development of intimal hyperplasia. Monocytes and neutrophils both exhibit phenotype plasticity that is associated with either pro-inflammatory or non-inflammatory states. Dynamic gene expression would give insight into their role during arteriovenous fistula adaption; unique responses might occur between fistulas that successfully mature and those that don’t.
    RNA was isolated and expression levels were determined using microarrays.

  2. Anatomic and hemodynamic data along the fistula length of 50 patients at 3 time points (baseline, 6 weeks, 6 months).
    Scientific reasoning: fistula maturation consists of vessel adaptation to larger blood flow. For instance, the venous and arterial diameter increase and the vessel undergo structural change to withstand higher blood flow. If vascular adaptation mechanism fails, larger wall-shear stresses (WSS), wall-shear stress gradients (WSSG), and oscillatory shear index (OSI) can be observed. Anatomic data was extracted from ultrasound imaging; hemodynamic data was extracted from patient-specific computational fluid-dynamic analyses.

  3. Brachial artery dilation on 50 patients at two time points (pre- and post-fistula).
    Scientific reasoning: Also endothelial and smooth muscle cells play a role in vessel wall adaption to stimuli. Flow-mediated and nitroglycerin-mediated dilation (FMD and NMD, respectively) are utilized for non-invasive assessment of endothelium-dependent and endothelium-independent (smooth muscle cell) vessel functions. Dilation is measured with ultrasound imaging. The results related to this data-set are not be presented in this notebook.


EXPLORATORY ANALYSES

We will first have an overview of the full anatomic-hemodyamic and genomic data-sets to undestand their major characteristics and distributions.

1. GENOMICS

MONOCYTES: I extracted the average fold change of gene expression from baseline, for monocytes. Data sample of the fist five genes is displayed below.

Then I created a Volcano plot to display the distribution of gene-specific fold change from baseline and marked the genes with p-value > .01 and fold change > 1.3 to identify those which might play a role during fistula remodeling and adaption.

The genes with larger expression variation are listed below. The total number of significant genes from monocytes is equal to 7.

NEUTROPHILS: I replicated the same approach for neutrophil gene expression.

The genes with larger expression variation are listed below. The total number of significant genes from neutrophils is equal to 42.

Let’s move to the anatomic-hemodynamic data-set.

2. VESSELS’ MORPHOLOGY AND HEMODYNAMICS

VEIN: the full anatomic and hemodynamic data-set of the venous portion of the fistula is displayed below.

ARTERY: an overview of the full anatomic and hemodynamic data-set follows for arterial portion of the fistula.

As the vein anatomy and hemodynamics undergo to the largest changes, most visible from the area graphs, for the purposes of this brief presentation, from now on we will focus vein investigation.

Moving to the next phase of the epxloratory analysis, we will dive in our data-sets in more depth. By investigating the anatomy and hemodynamics on a patient-specific basis and compare it with the patient-specific genomic results, we can obtain a list of genes that are potentially involved with fistula remodelling and/or maturation failure mechanics. Aim: identify whether unique responses occur for fistulas that successfully mature and those that don’t.

3. PATIENT 1 - MORPHOLOGY AND HEMODYNAMICS

Fold changes from baseline are displayed below for the five parameters of interest at 6 weeks and 6 months post-intervention.

This figure shows that along some portions of the vein the cross-sectional area increased up to 2.5 fold at six months, suggesting vessel adaptation and remodeling.
However, some other portions of the vein present close to no area increase. At these locations, hemodynamic parameters such as maximum (and average) WSS as well as average WSS gradient reach the highest values, underlying risk of platelets activation and thrombus formation.

For this reason, next we analyze the genomic of this patient to identify genes that might be involved in fistula maturation failure.

4. PATIENT 1 - GENOMICS

MONOCYTES: the Volcano plot is displayed below and the genes with p-value > .01 and fold change > 1.3 are marked in blue to identify set of genes that might play a role during fistula failure.

The list of significant change in gene expression from monocytes is here reported. Total number 124.

NEUTROPHILS: the Volcano plot is displayed below and the genes with p-value > .01 and fold change > 1.3 are marked in blue to identify set of genes that might play a role during fistula failure.

The list of significant change in gene expression from neutrophils is here reported. Total number 1,193.

By investigating the genomics of all patients which fistula already failied or show hemodynamic signatures of failure, we are able to obtain a list of genes potenitally involved with fistula failure mechanicsms.


Full data-sets can be found here.
Main R scripts can be found here.

LS0tCnRpdGxlOiAiKk1VTFRJU0NBTEUgQU5BTFlTRVMgT04gQVJURVJJT1ZFTk9VUyBGSVNUVUxBIE1BVFVSQVRJT04qIgphdXRob3I6ICJSb3NhbWFyaWEgVHJpY2FyaWNvIgpkYXRlOiAiRmVicnVhcnkgMSwgMjAxOCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKKioqCgoqKlBST0pFQ1QgT1VUTElORSoqCgpBcnRlcmlvdmVub3VzIGZpc3R1bGEgZm9yIGhlbW9kaWFseXNpcyBhY2Nlc3MgZmFpbHMgdG8gY2xpbmljYWxseSBtYXR1cmUgaW4gWzI4LTUzJV0oaHR0cHM6Ly9jamFzbi5hc25qb3VybmFscy5vcmcvY29udGVudC9jbGluamFzbi8xLzIvMzMyLmZ1bGwucGRmKSBvZiB0aGUgY2FzZXMuCgpNeSBnb2FsIGlzIHRvIGlkZW50aWZ5IGludGVyLWNvcnJlbGF0aW9ucyBhbW9uZyB0aW1lLWNoYW5nZXMgaW4gZmlzdHVsYSBtb3JwaG9sb2d5LCBoZW1vZHluYW1pY3MsIGdlbmUgZXhwcmVzc2lvbiwgYW5kIHNtb290aCBtdXNjbGUgY2VsbCBhbmQgZW5kb3RoZWxpYWwgY2VsbCBkeXNmdW5jdGlvbnMuClRoZXNlIHJlc3VsdHMgY2FuIHBsYXkgYSBmdW5kYW1lbnRhbCByb2xlIGluIHRoZSB1bmRlcnN0YXRpbmcgb2YgZmlzdHVsYSBtYXR1cmF0aW9uIGFuZCBmYWlsdXJlIGNhdXNlcywgaW5mbHVlbmNpbmcgY2xpbmljYWwgdGVjaG5pcXVlcyBhcyB3ZWxsIGFzIGlubm92YXRpdmUgc3RyYXRlZ2llcyBmb3IgZmlzdHVsYSBtYXR1cmF0aW9uLiAKCioqKgoKKipCQUNLR1JPVU5EKioKCk92ZXIgNjUwLDAwMCBBbWVyaWNhbnMgYXJlIGFmZmVjdGVkIGJ5IFtlbmQgc3RhZ2UgcmVuYWwgZGlzZWFzZV0oaHR0cHM6Ly93d3cubmlkZGsubmloLmdvdi9oZWFsdGgtaW5mb3JtYXRpb24vaGVhbHRoLXN0YXRpc3RpY3Mva2lkbmV5LWRpc2Vhc2UpLCB3aGljaCByZXF1aXJlcyBbaGVtb2RpYWx5c2lzIHRyZWF0bWVudF0oaHR0cHM6Ly93d3cubmlkZGsubmloLmdvdi9oZWFsdGgtaW5mb3JtYXRpb24va2lkbmV5LWRpc2Vhc2Uva2lkbmV5LWZhaWx1cmUvaGVtb2RpYWx5c2lzKSB1bnRpbCBhdmFpbGFiaWxpdHkgZm9yIGtpZG5leSB0cmFuc3BsYW50LiAKW0FydGVyaW92ZW5vdXMgZmlzdHVsYV0oaHR0cHM6Ly9zdXJnZXJ5LnVjc2YuZWR1L2NvbmRpdGlvbnMtLXByb2NlZHVyZXMvdmFzY3VsYXItYWNjZXNzLWZvci1oZW1vZGlhbHlzaXMuYXNweCksIGEgc3VyZ2ljYWwgY29ubmVjdGlvbiBiZXR3ZWVuIGFydGVyeSBhbmQgdmVpbiBvZiB0aGUgYXJtLCBpcyByZWNvZ25pemVkIGFzIHRoZSBiZXN0IGhlbW9kaWFseXNpcyBhY2Nlc3MsIGFzIGl0IGhhcyBiZWVuIHJlcG9ydGVkIHRvIGhhdmUgbG93ZXIgdGhyb21ib3NpcyBhbmQgaW5mZWN0aW9uIHJhdGVzIGNvbXBhcmVkIHRvIG90aGVyIGZpc3R1bGFzLiAKSG93ZXZlciwgb2J0YWluaW5nIGNsaW5pY2FsbHkgbWF0dXJlIGZpc3R1bGEgaXMgY2hhbGxlbmdpbmcgYW5kIHRoZSBjYXVzZXMgb2YgZmlzdHVsYSBtYXR1cmF0aW9uIGZhaWx1cmVzIGFyZSB1bmtub3duLiBbUmVzZWFyY2ggaW52ZXN0aWdhdGlvbnNdKGh0dHBzOi8vcHVicy5yc25hLm9yZy9kb2kvcGRmLzEwLjExNDgvcmFkaW9sLjIwMTUxNTAzODUpIGFyZSBiZWluZyBwZXJmb3JtZWQgdG8gZ2FpbiBhbiBpbnNpZ2h0IGludG8gdGhlIG1lY2hhbmlzbXMgb2YgbWF0dXJhdGlvbiBmYWlsdXJlLCBmcm9tIHZhc2N1bGFyIGFuYXRvbXkgYW5kIGhlbW9keW5hbWljcywgdG8gY2VsbCBkeXNmdW5jdGlvbiBhbmQgZ2Vub21pY3MgdGhhdCBtaWdodCBwbGF5IGEgcm9sZSBpbiB2YXNjdWxhciBtYXR1cmF0aW9uLCB5ZXQgYW1vbmcgdGhlIG1ham9yIGxpbWl0YXRpb25zIGFyZSBzbWFsbCBkYXRhLXNldHMgYW5kIGxhY2sgb2YgaW50ZXJjb25uZWN0aW9uIGFtb25nIGV2ZW50cyBhdCBtaWNyby0gYW5kIG1hY3JvLXNjYWxlcy4KClRoZSBbRGl2aXNpb24gb2YgVmFzY3VsYXIgU3VyZ2VyeSBhdCB0aGUgVW5pdmVyc2l0eSBvZiBGbG9yaWRhIFNoYW5kcyBIb3NwaXRhbF0oaHR0cHM6Ly92YXNjdWxhci5zdXJnZXJ5Lm1lZC51ZmwuZWR1L3Jlc2VhcmNoL25hdGlvbmFsLWluc3RpdHV0ZXMtb2YtaGVhbHRoLXN0dWR5LW9mLWF2LWZpc3R1bGFzLykgaGFzIGRlZGljYXRlZCBvdmVyIDggeWVhcnMgb24gbXVsdGlzY2FsZSBhbmFseXNlcyBvbiBhcnRlcmlvdmVub3VzIGZpc3R1bGEgbWF0dXJhdGlvbiBwbGFjaW5nIGl0c2VsZiBhbW9uZyB0aGUgdG9wIHNpeCBpbnRlcm5hdGlvbmFsbHkgcmVjb2duaXplZCBjZW50ZXJzIHNwZWNpYWxpemVkIG9uIHRoZSB0b3BpYy4gVGhpcyB2YXN0ZSByZXNlYXJjaCBoYXMgZ2VuZXJhdGVkIGxhcmdlIHBhdGllbnQtc3BlY2lmaWMgZGF0YS1zZXRzLCBub3cgYXZhaWxhYmxlIGZvciBkYXRhIHNjaWVuY2UgZXhwbG9yYXRpb24uCgoqKioKCioqREFUQS1TRVRTKioKClRoZSBkYXRhLXNldHMgYXJlIGNvbXBvc2VkIGJ5OgoKMS4gKipHZW5lIGV4cHJlc3Npb24gb2YgbW9ub2N5dGVzIGFuZCBuZXV0cm9waGlscyAoNTMsNjYyIHRvdGFsKSBvbiA1MCBwYXRpZW50cyBhdCB0d28gdGltZSBwb2ludHMgKGJhc2VsaW5lLCAyIHdlZWtzKS4qKiAgClNjaWVudGlmaWMgcmVhc29uaW5nOiBjaXJjdWxhdGluZyBsZXVrb2N5dGVzIChzdWNoIGFzIG1vbm9jeXRlcyBhbmQgbmV1dHJvcGhpbHMpIHBsYXkgYSByb2xlIGluIGRldmVsb3BtZW50IG9mIGludGltYWwgaHlwZXJwbGFzaWEuIE1vbm9jeXRlcyBhbmQgbmV1dHJvcGhpbHMgYm90aCBleGhpYml0IHBoZW5vdHlwZSBwbGFzdGljaXR5IHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIGVpdGhlciBwcm8taW5mbGFtbWF0b3J5IG9yIG5vbi1pbmZsYW1tYXRvcnkgc3RhdGVzLiBEeW5hbWljIGdlbmUgZXhwcmVzc2lvbiB3b3VsZCBnaXZlIGluc2lnaHQgaW50byB0aGVpciByb2xlIGR1cmluZyBhcnRlcmlvdmVub3VzIGZpc3R1bGEgYWRhcHRpb247IHVuaXF1ZSByZXNwb25zZXMgbWlnaHQgb2NjdXIgYmV0d2VlbiBmaXN0dWxhcyB0aGF0IHN1Y2Nlc3NmdWxseSBtYXR1cmUgYW5kIHRob3NlIHRoYXQgZG9u4oCZdC4gIApSTkEgd2FzIGlzb2xhdGVkIGFuZCBleHByZXNzaW9uIGxldmVscyB3ZXJlIGRldGVybWluZWQgdXNpbmcgbWljcm9hcnJheXMuIAoKCjIuICoqQW5hdG9taWMgYW5kIGhlbW9keW5hbWljIGRhdGEgYWxvbmcgdGhlIGZpc3R1bGEgbGVuZ3RoIG9mIDUwIHBhdGllbnRzIGF0IDMgdGltZSBwb2ludHMgKGJhc2VsaW5lLCA2IHdlZWtzLCA2IG1vbnRocykuKiogIApTY2llbnRpZmljIHJlYXNvbmluZzogZmlzdHVsYSBtYXR1cmF0aW9uIGNvbnNpc3RzIG9mIHZlc3NlbCBhZGFwdGF0aW9uIHRvIGxhcmdlciBibG9vZCBmbG93LiBGb3IgaW5zdGFuY2UsIHRoZSB2ZW5vdXMgYW5kIGFydGVyaWFsIGRpYW1ldGVyIGluY3JlYXNlIGFuZCB0aGUgdmVzc2VsIHVuZGVyZ28gc3RydWN0dXJhbCBjaGFuZ2UgdG8gd2l0aHN0YW5kIGhpZ2hlciBibG9vZCBmbG93LiBJZiB2YXNjdWxhciBhZGFwdGF0aW9uIG1lY2hhbmlzbSBmYWlscywgbGFyZ2VyIHdhbGwtc2hlYXIgc3RyZXNzZXMgKFdTUyksIHdhbGwtc2hlYXIgc3RyZXNzIGdyYWRpZW50cyAoV1NTRyksIGFuZCBvc2NpbGxhdG9yeSBzaGVhciBpbmRleCAoT1NJKSBjYW4gYmUgb2JzZXJ2ZWQuIApBbmF0b21pYyBkYXRhIHdhcyBleHRyYWN0ZWQgZnJvbSB1bHRyYXNvdW5kIGltYWdpbmc7IGhlbW9keW5hbWljIGRhdGEgd2FzIGV4dHJhY3RlZCBmcm9tIHBhdGllbnQtc3BlY2lmaWMgY29tcHV0YXRpb25hbCBmbHVpZC1keW5hbWljIGFuYWx5c2VzLgoKMy4gKipCcmFjaGlhbCBhcnRlcnkgZGlsYXRpb24gb24gNTAgcGF0aWVudHMgYXQgdHdvIHRpbWUgcG9pbnRzIChwcmUtIGFuZCBwb3N0LWZpc3R1bGEpLioqICAKU2NpZW50aWZpYyByZWFzb25pbmc6IEFsc28gZW5kb3RoZWxpYWwgYW5kIHNtb290aCBtdXNjbGUgY2VsbHMgcGxheSBhIHJvbGUgaW4gdmVzc2VsIHdhbGwgYWRhcHRpb24gdG8gc3RpbXVsaS4gRmxvdy1tZWRpYXRlZCBhbmQgbml0cm9nbHljZXJpbi1tZWRpYXRlZCBkaWxhdGlvbiAoRk1EIGFuZCBOTUQsIHJlc3BlY3RpdmVseSkgYXJlIHV0aWxpemVkIGZvciBub24taW52YXNpdmUgYXNzZXNzbWVudCBvZiBlbmRvdGhlbGl1bS1kZXBlbmRlbnQgYW5kIGVuZG90aGVsaXVtLWluZGVwZW5kZW50IChzbW9vdGggbXVzY2xlIGNlbGwpIHZlc3NlbCBmdW5jdGlvbnMuIApEaWxhdGlvbiBpcyBtZWFzdXJlZCB3aXRoIHVsdHJhc291bmQgaW1hZ2luZy4KKlRoZSByZXN1bHRzIHJlbGF0ZWQgdG8gdGhpcyBkYXRhLXNldCBhcmUgbm90IGJlIHByZXNlbnRlZCBpbiB0aGlzIG5vdGVib29rLioKCioqKgoKKipFWFBMT1JBVE9SWSBBTkFMWVNFUyoqCgpXZSB3aWxsIGZpcnN0IGhhdmUgYW4gb3ZlcnZpZXcgb2YgdGhlIGZ1bGwgYW5hdG9taWMtaGVtb2R5YW1pYyBhbmQgZ2Vub21pYyBkYXRhLXNldHMgdG8gdW5kZXN0YW5kIHRoZWlyIG1ham9yIGNoYXJhY3RlcmlzdGljcyBhbmQgZGlzdHJpYnV0aW9ucy4KCioqKjEuIEdFTk9NSUNTKioqCgoqTU9OT0NZVEVTKjoKSSBleHRyYWN0ZWQgdGhlIGF2ZXJhZ2UgZm9sZCBjaGFuZ2Ugb2YgZ2VuZSBleHByZXNzaW9uIGZyb20gYmFzZWxpbmUsIGZvciBtb25vY3l0ZXMuIERhdGEgc2FtcGxlIG9mIHRoZSBmaXN0IGZpdmUgZ2VuZXMgaXMgZGlzcGxheWVkIGJlbG93LiAKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgUmVhZCB0aGUgZ2VuZSBleHByZXNzaW9uIGRhdGEgc2V0Ck1vbm9jeXRlIDwtIHJlYWQuY3N2KGZpbGU9Ik1vbm9jeXRlLmNzdiIsaGVhZD1UUlVFLHNlcD0iLCIpCnAgPC0gZGltKE1vbm9jeXRlKTsKR2VuZSA8LSBNb25vY3l0ZVsxOjFdOwpEYXRhIDwtIE1vbm9jeXRlWzI6KHBbMl0pXTsKbiA8LSBkaW0oRGF0YSk7Cm0gPC0gKChuWzJdKS8yKTsKIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2UgZm9sZCBjaGFuZ2UgZm9yIGVhY2ggZ2VuZSBmcm9tIGJhc2VsaW5lIHRvIDItd2Vla3MgYWZ0ZXIgZmlzdHVsYQpCX21lYW5zIDwtIHJvd01lYW5zKERhdGFbMTptXSk7ClcyX21lYW5zIDwtIHJvd01lYW5zKERhdGFbKG0rMSk6KG5bMl0pXSk7CmxvZzJGb2xkQ2hhbmdlIDwtIChXMl9tZWFucyAtIEJfbWVhbnMpOyAjZm9yIHNlbXBsaWNpdHkgZ2VuZSBleHByZXNzaW9uIGlzIHJlcG9ydGVkIGFzIGxvZzIoZ2VuZSBleHByZXNzaW9uKQojIENhbGN1bGF0ZSB0aGUgcC12YWx1ZSBvZiB0aGUgdC10ZXN0IGJldHdlZW4gYmFzZWxpbmUgYW5kIDItd2Vla3MgYWZ0ZXIgZmlzdHVsYQpQdmFsdWUgPC0gYXBwbHkoRGF0YSwgMSwgZnVuY3Rpb24oRGF0YSkgewogIHQudGVzdCh4ID0gRGF0YVsxOm1dLCB5ID0gRGF0YVsobSsxKTooblsyXSldKSRwLnZhbHVlfSk7CiMgU2F2ZSBkYXRhClJlc3VsdHMgPSBjYmluZChHZW5lLCBsb2cyRm9sZENoYW5nZSk7ClJlc3VsdHMgPSBjYmluZChSZXN1bHRzLCBwdmFsdWUgPSBQdmFsdWUpOwp3cml0ZS5jc3YoUmVzdWx0cywgZmlsZSA9ICJNb25vY3l0ZV9GQy1QVi5jc3YiKQp3cml0ZS50YWJsZShSZXN1bHRzLCBmaWxlID0gIk1vbm9jeXRlX0ZDLVBWLnR4dCIpCmhlYWQoUmVzdWx0cykKYGBgCgpUaGVuIEkgY3JlYXRlZCBhIFZvbGNhbm8gcGxvdCB0byBkaXNwbGF5IHRoZSBkaXN0cmlidXRpb24gb2YgZ2VuZS1zcGVjaWZpYyBmb2xkIGNoYW5nZSBmcm9tIGJhc2VsaW5lIGFuZCBtYXJrZWQgdGhlIGdlbmVzIHdpdGggcC12YWx1ZSA+IC4wMSBhbmQgZm9sZCBjaGFuZ2UgPiAxLjMgdG8gaWRlbnRpZnkgdGhvc2Ugd2hpY2ggbWlnaHQgcGxheSBhIHJvbGUgZHVyaW5nIGZpc3R1bGEgcmVtb2RlbGluZyBhbmQgYWRhcHRpb24uCgpgYGB7cn0KIyBNYWtlIGEgYmFzaWMgdm9sY2FubyBwbG90ClRhYmxlIDwtIHJlYWQudGFibGUoIk1vbm9jeXRlX0ZDLVBWLnR4dCIsIGhlYWRlcj1UUlVFKQp3aXRoKFRhYmxlLCBwbG90KGxvZzJGb2xkQ2hhbmdlLCAtbG9nMTAocHZhbHVlKSwgcGNoPTEsIG1haW49Ik1vbm9jeXRlIiwgeGxpbT1jKC0xLDEpKSkKIyBBZGQgY29sb3JlZCBwb2ludHMgZ3JlZW4gaWYgcHZhbHVlPC4wMSAoYWxpYXMgLWxvZzEwKHB2YWx1ZSk8MikgYW5kIEZvbGRDaGFuZ2U+MS4zCmEgPC0gbG9nMigxLjMpOwp3aXRoKHN1YnNldChUYWJsZSwgcHZhbHVlPi4wMSB8IGFicyhsb2cyRm9sZENoYW5nZSk8YSksIHBvaW50cyhsb2cyRm9sZENoYW5nZSwgLWxvZzEwKHB2YWx1ZSksIHBjaD0xLCBjb2w9ImdyYXkiKSkKd2l0aChzdWJzZXQoVGFibGUsIHB2YWx1ZTwuMDEgJiBhYnMobG9nMkZvbGRDaGFuZ2UpPmEpLCBwb2ludHMobG9nMkZvbGRDaGFuZ2UsIC1sb2cxMChwdmFsdWUpLCBwY2g9MjAsIGNvbD0iYmxhY2siKSkKYWJsaW5lKHY9YygrYSwtYSksIGNvbD1jKCJibGFjayIsICJibGFjayIpLCBsdHk9YygyLDIpLCBsd2Q9YygxLCAxKSkKYWJsaW5lKGg9MiwgY29sPWMoImJsYWNrIiwgImJsYWNrIiksIGx0eT1jKDIsMiksIGx3ZD1jKDEsIDEpKQpgYGAKClRoZSBnZW5lcyB3aXRoIGxhcmdlciBleHByZXNzaW9uIHZhcmlhdGlvbiBhcmUgbGlzdGVkIGJlbG93LiBUaGUgdG90YWwgbnVtYmVyIG9mIHNpZ25pZmljYW50IGdlbmVzIGZyb20gbW9ub2N5dGVzIGlzIGVxdWFsIHRvIDcuCmBgYHtyIGVjaG89RkFMU0V9ClNpZ25pZmljYW50IDwtIHN1YnNldChUYWJsZSwgcHZhbHVlPC4wMSAmIGFicyhsb2cyRm9sZENoYW5nZSk+YSkKU2lnbmlmaWNhbnQKd3JpdGUuY3N2KFNpZ25pZmljYW50LCBmaWxlID0gIlNpZ25pZmljYW50X01vbm9jeXRlcy5jc3YiKQpgYGAKCipORVVUUk9QSElMUyo6CkkgcmVwbGljYXRlZCB0aGUgc2FtZSBhcHByb2FjaCBmb3IgbmV1dHJvcGhpbCBnZW5lIGV4cHJlc3Npb24uIApgYGB7ciBlY2hvPUZBTFNFfQpOZXV0cm9waGlsIDwtIHJlYWQuY3N2KGZpbGU9Ik5ldXRyb3BoaWwuY3N2IixoZWFkPVRSVUUsc2VwPSIsIikKcCA8LSBkaW0oTmV1dHJvcGhpbCk7CkdlbmUgPC0gTmV1dHJvcGhpbFsxOjFdOwpEYXRhIDwtIE5ldXRyb3BoaWxbMjoocFsyXSldOwpuIDwtIGRpbShEYXRhKTsKbSA8LSAoKG5bMl0pLzIpOwojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBmb2xkIGNoYW5nZSBmb3IgZWFjaCBnZW5lIGZyb20gYmFzZWxpbmUgdG8gMi13ZWVrcyBhZnRlciBmaXN0dWxhCkJfbWVhbnMgPC0gcm93TWVhbnMoRGF0YVsxOm1dKTsKVzJfbWVhbnMgPC0gcm93TWVhbnMoRGF0YVsobSsxKTooblsyXSldKTsKbG9nMkZvbGRDaGFuZ2UgPC0gKFcyX21lYW5zIC0gQl9tZWFucyk7CiMgQ2FsY3VsYXRlIHRoZSBwLXZhbHVlIG9mIHRoZSB0LXRlc3QgYmV0d2VlbiBiYXNlbGluZSBhbmQgMi13ZWVrcyBhZnRlciBmaXN0dWxhClB2YWx1ZSA8LSBhcHBseShEYXRhLCAxLCBmdW5jdGlvbihEYXRhKSB7CiAgdC50ZXN0KHggPSBEYXRhWzE6bV0sIHkgPSBEYXRhWyhtKzEpOihuWzJdKV0pJHAudmFsdWV9KQojIFNhdmUgZGF0YQpSZXN1bHRzID0gY2JpbmQoR2VuZSwgbG9nMkZvbGRDaGFuZ2UpOwpSZXN1bHRzID0gY2JpbmQoUmVzdWx0cywgcHZhbHVlID0gUHZhbHVlKTsKd3JpdGUuY3N2KFJlc3VsdHMsIGZpbGUgPSAiTmV1dHJvcGhpbF9GQy1QVi5jc3YiKQp3cml0ZS50YWJsZShSZXN1bHRzLCBmaWxlID0gIk5ldXRyb3BoaWxfRkMtUFYudHh0IikKIyBNYWtlIGEgYmFzaWMgdm9sY2FubyBwbG90ClRhYmxlIDwtIHJlYWQudGFibGUoIk5ldXRyb3BoaWxfRkMtUFYudHh0IiwgaGVhZGVyPVRSVUUpCndpdGgoVGFibGUsIHBsb3QobG9nMkZvbGRDaGFuZ2UsIC1sb2cxMChwdmFsdWUpLCBwY2g9MSwgbWFpbj0iTmV1dHJvcGhpbCIsIHhsaW09YygtMSwxKSkpCiMgQWRkIGNvbG9yZWQgcG9pbnRzIGdyZWVuIGlmIHB2YWx1ZTwuMDEgKGFsaWFzIC1sb2cxMChwdmFsdWUpPDIpIGFuZCBGb2xkQ2hhbmdlPjEuMwphIDwtIGxvZzIoMS4zKTsKd2l0aChzdWJzZXQoVGFibGUsIHB2YWx1ZT4uMDEgfCBhYnMobG9nMkZvbGRDaGFuZ2UpPGEpLCBwb2ludHMobG9nMkZvbGRDaGFuZ2UsIC1sb2cxMChwdmFsdWUpLCBwY2g9MSwgY29sPSJncmF5IikpOwp3aXRoKHN1YnNldChUYWJsZSwgcHZhbHVlPC4wMSAmIGFicyhsb2cyRm9sZENoYW5nZSk+YSksIHBvaW50cyhsb2cyRm9sZENoYW5nZSwgLWxvZzEwKHB2YWx1ZSksIHBjaD0yMCwgY29sPSJibGFjayIpKTsKYWJsaW5lKHY9YygrYSwtYSksIGNvbD1jKCJibGFjayIsICJibGFjayIpLCBsdHk9YygyLDIpLCBsd2Q9YygxLCAxKSk7CmFibGluZShoPTIsIGNvbD1jKCJibGFjayIsICJibGFjayIpLCBsdHk9YygyLDIpLCBsd2Q9YygxLCAxKSkKYGBgCgpUaGUgZ2VuZXMgd2l0aCBsYXJnZXIgZXhwcmVzc2lvbiB2YXJpYXRpb24gYXJlIGxpc3RlZCBiZWxvdy4gVGhlIHRvdGFsIG51bWJlciBvZiBzaWduaWZpY2FudCBnZW5lcyBmcm9tIG5ldXRyb3BoaWxzIGlzIGVxdWFsIHRvIDQyLgpgYGB7ciBlY2hvPUZBTFNFfQpTaWduaWZpY2FudCA8LSBzdWJzZXQoVGFibGUsIHB2YWx1ZTwuMDEgJiBhYnMobG9nMkZvbGRDaGFuZ2UpPmEpOwpTaWduaWZpY2FudAp3cml0ZS5jc3YoU2lnbmlmaWNhbnQsIGZpbGUgPSAiU2lnbmlmaWNhbnRfTmV1dHJvcGhpbHMuY3N2IikKYGBgCgpMZXQncyBtb3ZlIHRvIHRoZSBhbmF0b21pYy1oZW1vZHluYW1pYyBkYXRhLXNldC4KCioqKjIuIFZFU1NFTFMnIE1PUlBIT0xPR1kgQU5EIEhFTU9EWU5BTUlDUyoqKgoKKlZFSU4qOgp0aGUgZnVsbCBhbmF0b21pYyBhbmQgaGVtb2R5bmFtaWMgZGF0YS1zZXQgb2YgdGhlICp2ZW5vdXMqIHBvcnRpb24gb2YgdGhlIGZpc3R1bGEgaXMgZGlzcGxheWVkIGJlbG93LgpgYGB7ciBlY2hvPUZBTFNFfQojIFJlYWQgdGhlIGhlbW9keW5hbWljIGRhdGEgc2V0CkhlbW9keW5hbWljcyA8LSByZWFkLmNzdihmaWxlPSJIZW1vZHluYW1pY3NfRmlzdHVsYS1WZWluLmNzdiIsIGhlYWQ9VFJVRSwgc2VwPSIsIikKIyMgTG9hZApsaWJyYXJ5KGxhdHRpY2UpCnBhcihjZXggPSAuNikKb3B0aW9ucyhzY2lwZW49OTk5KSAgIyB0dXJuLW9mZiBzY2llbnRpZmljIG5vdGF0aW9uIGxpa2UgMWUrNDgKIy0tRGVmaW5lIHBsb3QgdGl0bGVzOgpsYWIuU2Nhbi4xIDwtICJCYXNlbGluZSIKbGFiLlNjYW4uMiA8LSAiNiB3ZWVrcyIKbGFiLlNjYW4uMyA8LSAiNiBtb250aHMiCiMtLUN1c3RvbSBzdHJpcCBmdW5jdGlvbjoKbXkuc3RyaXAgPC0gZnVuY3Rpb24od2hpY2guZ2l2ZW4sIHdoaWNoLnBhbmVsLCAuLi4pIHsKICBzdHJpcC5sYWJlbHMgPC0gYyhsYWIuU2Nhbi4xLCBsYWIuU2Nhbi4yLCBsYWIuU2Nhbi4zKQogIHBhbmVsLnJlY3QoMCwgMCwgMSwgMSwgY29sPSIjZmZlNWNjIiwgYm9yZGVyPTEpCiAgcGFuZWwudGV4dCh4PTAuNSwgeT0wLjUsIGFkaj1jKDAuNSwgMC41NSksIGNleD0wLjk1LAogICAgICAgICAgICAgbGFiPXN0cmlwLmxhYmVsc1t3aGljaC5wYW5lbFt3aGljaC5naXZlbl1dKX0KI0NyZWF0ZSBwbG90cwp4eXBsb3QoYXJlYSB+IGQubW0gfCBTY2FuLCBkYXRhID0gSGVtb2R5bmFtaWNzLCBncm91cHMgPSBQYXRpZW50LCB0eXBlID0gImwiLCBsd2Q9MC41LCBncmlkID0gVFJVRSwgCiAgICAgICBzdHJpcD1teS5zdHJpcCwgbGF5b3V0PWMoMSwgMywgMSksIHhsYWI9IlZlaW4gTGVuZ3RoIFttbV0iLCB5bGFiPSJBcmVhIFttbV4yXSIpCnh5cGxvdChXU1NhdmUgfiBkLm1tIHwgU2NhbiwgZGF0YSA9IEhlbW9keW5hbWljcywgZ3JvdXBzID0gUGF0aWVudCwgdHlwZSA9ICJsIiwgbHdkPTAuNSwgZ3JpZCA9IFRSVUUsCiAgICAgICBzdHJpcD1teS5zdHJpcCwgbGF5b3V0PWMoMSwgMywgMSksIHhsYWI9IlZlaW4gTGVuZ3RoIFttbV0iLCB5bGFiPSJBdmVyYWdlIG9mIFdTUyBbUGFdIikKeHlwbG90KFdTU21heCB+IGQubW0gfCBTY2FuLCBkYXRhID0gSGVtb2R5bmFtaWNzLCBncm91cHMgPSBQYXRpZW50LCB0eXBlID0gImwiLCBsd2Q9MC41LCBncmlkID0gVFJVRSwKICAgICAgIHN0cmlwPW15LnN0cmlwLCBsYXlvdXQ9YygxLCAzLCAxKSwgeGxhYj0iVmVpbiBMZW5ndGggW21tXSIsIHlsYWI9Ik1heGltdW0gV1NTIFtQYV0iKQp4eXBsb3QoV1NTR2F2ZSB+IGQubW0gfCBTY2FuLCBkYXRhID0gSGVtb2R5bmFtaWNzLCBncm91cHMgPSBQYXRpZW50LCB0eXBlID0gImwiLCBsd2Q9MC41LCBncmlkID0gVFJVRSwKICAgICAgIHN0cmlwPW15LnN0cmlwLCBsYXlvdXQ9YygxLCAzLCAxKSwgeGxhYj0iVmVpbiBMZW5ndGggW21tXSIsIHlsYWI9IkF2ZXJhZ2Ugb2YgV1NTIGdyYWRpZW50IFsxL1BhXSIpCnh5cGxvdChPU0kgfiBkLm1tIHwgU2NhbiwgZGF0YSA9IEhlbW9keW5hbWljcywgZ3JvdXBzID0gUGF0aWVudCwgdHlwZSA9ICJsIiwgbHdkPTAuNSwgZ3JpZCA9IFRSVUUsIAogICAgICAgc3RyaXA9bXkuc3RyaXAsIGxheW91dD1jKDEsIDMsIDEpLCB4bGFiPSJWZWluIExlbmd0aCBbbW1dIiwgeWxhYj0iT3NjaWxsYXRvcnkgU2hlYXIgSW5kZXgiKQpgYGAKCipBUlRFUlkqOiAKYW4gb3ZlcnZpZXcgb2YgdGhlIGZ1bGwgYW5hdG9taWMgYW5kIGhlbW9keW5hbWljIGRhdGEtc2V0IGZvbGxvd3MgZm9yICphcnRlcmlhbCogcG9ydGlvbiBvZiB0aGUgZmlzdHVsYS4KYGBge3IgZWNobz1GQUxTRX0KIyBSZWFkIHRoZSBoZW1vZHluYW1pYyBkYXRhIHNldApIZW1vZHluYW1pY3MgPC0gcmVhZC5jc3YoZmlsZT0iSGVtb2R5bmFtaWNzX0Zpc3R1bGEtQXJ0ZXJ5LmNzdiIsIGhlYWQ9VFJVRSwgc2VwPSIsIikKIyMgTG9hZApsaWJyYXJ5KGxhdHRpY2UpCnBhcihjZXggPSAuNikKb3B0aW9ucyhzY2lwZW49OTk5KSAgIyB0dXJuLW9mZiBzY2llbnRpZmljIG5vdGF0aW9uIGxpa2UgMWUrNDgKIy0tRGVmaW5lIHBsb3QgdGl0bGVzOgpsYWIuU2Nhbi4xIDwtICJCYXNlbGluZSIKbGFiLlNjYW4uMiA8LSAiNiB3ZWVrcyIKbGFiLlNjYW4uMyA8LSAiNiBtb250aHMiCiMtLUN1c3RvbSBzdHJpcCBmdW5jdGlvbjoKbXkuc3RyaXAgPC0gZnVuY3Rpb24od2hpY2guZ2l2ZW4sIHdoaWNoLnBhbmVsLCAuLi4pIHsKICBzdHJpcC5sYWJlbHMgPC0gYyhsYWIuU2Nhbi4xLCBsYWIuU2Nhbi4yLCBsYWIuU2Nhbi4zKQogIHBhbmVsLnJlY3QoMCwgMCwgMSwgMSwgY29sPSIjZmZlNWNjIiwgYm9yZGVyPTEpCiAgcGFuZWwudGV4dCh4PTAuNSwgeT0wLjUsIGFkaj1jKDAuNSwgMC41NSksIGNleD0wLjk1LAogICAgICAgICAgICAgbGFiPXN0cmlwLmxhYmVsc1t3aGljaC5wYW5lbFt3aGljaC5naXZlbl1dKX0KI0NyZWF0ZSBwbG90cwp4eXBsb3QoYXJlYSB+IGQubW0gfCBTY2FuLCBkYXRhID0gSGVtb2R5bmFtaWNzLCBncm91cHMgPSBQYXRpZW50LCB0eXBlID0gImwiLCBsd2Q9MC41LCBncmlkID0gVFJVRSwKICAgICAgIHN0cmlwPW15LnN0cmlwLCBsYXlvdXQ9YygxLCAzLCAxKSwgeGxhYj0iQXJ0ZXJ5IExlbmd0aCBbbW1dIiwgeWxhYj0iQXJlYSBbbW1eMl0iKQp4eXBsb3QoV1NTYXZlIH4gZC5tbSB8IFNjYW4sIGRhdGEgPSBIZW1vZHluYW1pY3MsIGdyb3VwcyA9IFBhdGllbnQsIHR5cGUgPSAibCIsIGx3ZD0wLjUsIGdyaWQgPSBUUlVFLCAKICAgICAgIHN0cmlwPW15LnN0cmlwLCBsYXlvdXQ9YygxLCAzLCAxKSwgeGxhYj0iQXJ0ZXJ5IExlbmd0aCBbbW1dIiwgeWxhYj0iQXZlcmFnZSBvZiBXU1MgW1BhXSIpCnh5cGxvdChXU1NtYXggfiBkLm1tIHwgU2NhbiwgZGF0YSA9IEhlbW9keW5hbWljcywgZ3JvdXBzID0gUGF0aWVudCwgdHlwZSA9ICJsIiwgbHdkPTAuNSwgZ3JpZCA9IFRSVUUsIAogICAgICAgc3RyaXA9bXkuc3RyaXAsIGxheW91dD1jKDEsIDMsIDEpLCB4bGFiPSJBcnRlcnkgTGVuZ3RoIFttbV0iLCB5bGFiPSJNYXhpbXVtIFdTUyBbUGFdIikKeHlwbG90KFdTU0dhdmUgfiBkLm1tIHwgU2NhbiwgZGF0YSA9IEhlbW9keW5hbWljcywgZ3JvdXBzID0gUGF0aWVudCwgdHlwZSA9ICJsIiwgbHdkPTAuNSwgZ3JpZCA9IFRSVUUsCiAgICAgICBzdHJpcD1teS5zdHJpcCwgbGF5b3V0PWMoMSwgMywgMSksIHhsYWI9IkFydGVyeSBMZW5ndGggW21tXSIsIHlsYWI9IkF2ZXJhZ2Ugb2YgV1NTIGdyYWRpZW50IFsxL1BhXSIpCnh5cGxvdChPU0kgfiBkLm1tIHwgU2NhbiwgZGF0YSA9IEhlbW9keW5hbWljcywgZ3JvdXBzID0gUGF0aWVudCwgdHlwZSA9ICJsIiwgbHdkPTAuNSwgZ3JpZCA9IFRSVUUsIAogICAgICAgc3RyaXA9bXkuc3RyaXAsIGxheW91dD1jKDEsIDMsIDEpLCB4bGFiPSJBcnRlcnkgTGVuZ3RoIFttbV0iLCB5bGFiPSJPc2NpbGxhdG9yeSBTaGVhciBJbmRleCIpCmBgYAoKQXMgdGhlICp2ZWluIGFuYXRvbXkgYW5kIGhlbW9keW5hbWljcyogdW5kZXJnbyB0byB0aGUgbGFyZ2VzdCBjaGFuZ2VzLCBtb3N0IHZpc2libGUgZnJvbSB0aGUgYXJlYSBncmFwaHMsIGZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBicmllZiBwcmVzZW50YXRpb24sIGZyb20gbm93IG9uIHdlIHdpbGwgZm9jdXMgKnZlaW4qIGludmVzdGlnYXRpb24uCgoqTW92aW5nIHRvIHRoZSBuZXh0IHBoYXNlIG9mIHRoZSBlcHhsb3JhdG9yeSBhbmFseXNpcywgd2Ugd2lsbCBkaXZlIGluIG91ciBkYXRhLXNldHMgaW4gbW9yZSBkZXB0aC4gICoKKkJ5IGludmVzdGlnYXRpbmcgdGhlIGFuYXRvbXkgYW5kIGhlbW9keW5hbWljcyBvbiBhIHBhdGllbnQtc3BlY2lmaWMgYmFzaXMgYW5kIGNvbXBhcmUgaXQgd2l0aCB0aGUgcGF0aWVudC1zcGVjaWZpYyBnZW5vbWljIHJlc3VsdHMsIHdlIGNhbiBvYnRhaW4gYSBsaXN0IG9mIGdlbmVzIHRoYXQgYXJlIHBvdGVudGlhbGx5IGludm9sdmVkIHdpdGggZmlzdHVsYSByZW1vZGVsbGluZyBhbmQvb3IgbWF0dXJhdGlvbiBmYWlsdXJlIG1lY2hhbmljcy4gICoKKkFpbTogaWRlbnRpZnkgd2hldGhlciB1bmlxdWUgcmVzcG9uc2VzIG9jY3VyIGZvciBmaXN0dWxhcyB0aGF0IHN1Y2Nlc3NmdWxseSBtYXR1cmUgYW5kIHRob3NlIHRoYXQgZG9u4oCZdC4qCgoqKiozLiBQQVRJRU5UIDEgLSBNT1JQSE9MT0dZIEFORCBIRU1PRFlOQU1JQ1MqKioKCkZvbGQgY2hhbmdlcyBmcm9tIGJhc2VsaW5lIGFyZSBkaXNwbGF5ZWQgYmVsb3cgZm9yIHRoZSBmaXZlIHBhcmFtZXRlcnMgb2YgaW50ZXJlc3QgYXQgNiB3ZWVrcyBhbmQgNiBtb250aHMgcG9zdC1pbnRlcnZlbnRpb24uCmBgYHtyIGVjaG89RkFMU0V9ClBhdGllbnQxIDwtIGZpbHRlcihIZW1vZHluYW1pY3MsIFBhdGllbnQgPT0gIjAzMTE0MyBISiIpCkJhc2VsaW5lIDwtIGZpbHRlcihQYXRpZW50MSwgU2NhbiA9PSAxKQpXZWVrNiA8LSBmaWx0ZXIoUGF0aWVudDEsIFNjYW4gPT0gMikKTW9udGg2IDwtIGZpbHRlcihQYXRpZW50MSwgU2NhbiA9PSAzKQpuIDwtIGRpbShCYXNlbGluZSk7Cm0gPC0gKG5bMV0pOwpGb2xkQ2hhbmdlX1dlZWs2IDwtIFdlZWs2WzU6OV0vQmFzZWxpbmVbNTo5XQpGb2xkQ2hhbmdlX01vbnRoNiA8LSBNb250aDZbNTo5XS9CYXNlbGluZVs1OjldCnhkaW0gPC0gaGVhZChQYXRpZW50MVs0OjRdLG0pClBhdGllbnQxX0ZvbGRDaGFuZ2VfV2VlazYgPSBjYmluZCh4ZGltLCBGb2xkQ2hhbmdlX1dlZWs2KTsKUGF0aWVudDFfRm9sZENoYW5nZV9Nb250aDYgPSBjYmluZCh4ZGltLCBGb2xkQ2hhbmdlX01vbnRoNik7CiMtLURlZmluZSBwbG90IHRpdGxlczoKbGFiLmFyZWEgPC0gIkFyZWEiCmxhYi5XU1NhdmUgPC0gIkF2ZXJhZ2Ugb2YgV1NTIgpsYWIuV1NTbWF4IDwtICJNYXhpbXVtIFdTUyIKbGFiLldTU0dhdmUgPC0gIkF2ZXJhZ2Ugb2YgV1NTIGdyYWRpZW50IgpsYWIuT1NJIDwtICJPc2NpbGxhdG9yeSBTaGVhciBJbmRleCIKIy0tQ3VzdG9tIHN0cmlwIGZ1bmN0aW9uOgpteS5zdHJpcCA8LSBmdW5jdGlvbih3aGljaC5naXZlbiwgd2hpY2gucGFuZWwsIC4uLikgewogIHN0cmlwLmxhYmVscyA8LSBjKGxhYi5hcmVhLCBsYWIuV1NTYXZlLCBsYWIuV1NTbWF4LCBsYWIuV1NTR2F2ZSwgbGFiLk9TSSkKICBwYW5lbC5yZWN0KDAsIDAsIDEsIDEsIGNvbD0iI2ZmZTVjYyIsIGJvcmRlcj0xKQogIHBhbmVsLnRleHQoeD0wLjUsIHk9MC41LCBhZGo9YygwLjUsIDAuNTUpLCBjZXg9MC45NSwKICAgICAgICAgICAgIGxhYj1zdHJpcC5sYWJlbHNbd2hpY2gucGFuZWxbd2hpY2guZ2l2ZW5dXSl9CiNzZXR0aW5ncyBmb3IgZ3JhcGggdGl0bGUgc3R5bGUKbXkuc2V0dGluZ3MgPC0gbGlzdCgKICBwYXIubWFpbi50ZXh0ID0gbGlzdChmb250ID0gMiwgIyBtYWtlIGl0IGJvbGQKICAgICAgICAgICAgICAgICAgICAgICBqdXN0ID0gImxlZnQiLCAKICAgICAgICAgICAgICAgICAgICAgICB4ID0gZ3JpZDo6dW5pdCg1LCAibW0iKSksCiAgcGFyLnN1Yi50ZXh0ID0gbGlzdChmb250ID0gMC41LCAKICAgICAgICAgICAgICAgICAgICAgIGp1c3QgPSAibGVmdCIsIAogICAgICAgICAgICAgICAgICAgICAgeCA9IGdyaWQ6OnVuaXQoNSwgIm1tIikpKQojQ3JlYXRpbmcgdGhlIGNvbWJpbmVkIGdyYXBoClBhdGllbnQxX0ZvbGRDaGFuZ2UgPSAwOwpQYXRpZW50MV9Gb2xkQ2hhbmdlID0gcmJpbmQoUGF0aWVudDFfRm9sZENoYW5nZV9XZWVrNiwgUGF0aWVudDFfRm9sZENoYW5nZV9Nb250aDYpOwojVmlldyhQYXRpZW50MV9Gb2xkQ2hhbmdlKQpTY2FuIDwtIHRhaWwoUGF0aWVudDFbMzozXSwoblsxXSoyKSk7ClBhdGllbnQxX0ZvbGRDaGFuZ2UgPSBjYmluZChTY2FuLFBhdGllbnQxX0ZvbGRDaGFuZ2UpOwp4eXBsb3QoYXJlYSArIFdTU2F2ZSArIFdTU21heCArIFdTU0dhdmUgKyBPU0kgfiBkLm1tLCBkYXRhID0gUGF0aWVudDFfRm9sZENoYW5nZSwgZ3JvdXBzID0gU2Nhbiwgc2NhbGVzPWxpc3QoeT0iZnJlZSIsIHJvdD0wKSx0eXBlID0gImwiLCAKICAgICAgIGdyaWQgPSBUUlVFLCBzdHJpcD1teS5zdHJpcCwgb3V0ZXI9VFJVRSwgbGF5b3V0PWMoMSwgNSwgMSksIHhsYWI9IlZlaW4gTGVuZ3RoIFttbV0iLCB5bGFiPSIiLAogICAgICAga2V5PWxpc3QodGV4dD1saXN0KGMoIjYgd2Vla3MiLCAiNiBtb250aHMiKSksCiAgICAgICAgICAgICAgICB0aXRsZT0iUGF0aWVudCAzMTE0MyAtIEZvbGQgY2hhbmdlIGZyb20gYmFzZWxpbmUiLAogICAgICAgICAgICAgICAgY29sPWMoImRlZXBza3libHVlMyIsICJkZWVwcGluayIpLCBsdHk9YygxLCAxKSwKICAgICAgICAgICAgICAgIGNvbHVtbnM9MiwgY2V4PTAuNywKICAgICAgICAgICAgICAgIGxpbmVzPVRSVUUpKQpgYGAKVGhpcyBmaWd1cmUgc2hvd3MgdGhhdCBhbG9uZyBzb21lIHBvcnRpb25zIG9mIHRoZSB2ZWluIHRoZSBjcm9zcy1zZWN0aW9uYWwgYXJlYSBpbmNyZWFzZWQgdXAgdG8gMi41IGZvbGQgYXQgc2l4IG1vbnRocywgc3VnZ2VzdGluZyB2ZXNzZWwgYWRhcHRhdGlvbiBhbmQgcmVtb2RlbGluZy4gICAKSG93ZXZlciwgc29tZSBvdGhlciBwb3J0aW9ucyBvZiB0aGUgdmVpbiBwcmVzZW50IGNsb3NlIHRvIG5vIGFyZWEgaW5jcmVhc2UuIEF0IHRoZXNlIGxvY2F0aW9ucywgaGVtb2R5bmFtaWMgcGFyYW1ldGVycyBzdWNoIGFzIG1heGltdW0gKGFuZCBhdmVyYWdlKSBXU1MgYXMgd2VsbCBhcyBhdmVyYWdlIFdTUyBncmFkaWVudCByZWFjaCB0aGUgaGlnaGVzdCB2YWx1ZXMsIHVuZGVybHlpbmcgcmlzayBvZiBwbGF0ZWxldHMgYWN0aXZhdGlvbiBhbmQgdGhyb21idXMgZm9ybWF0aW9uLiAKCkZvciB0aGlzIHJlYXNvbiwgbmV4dCB3ZSBhbmFseXplIHRoZSBnZW5vbWljIG9mIHRoaXMgcGF0aWVudCB0byBpZGVudGlmeSBnZW5lcyB0aGF0IG1pZ2h0IGJlIGludm9sdmVkIGluIGZpc3R1bGEgbWF0dXJhdGlvbiBmYWlsdXJlLgoKKioqNC4gUEFUSUVOVCAxIC0gR0VOT01JQ1MqKioKCipNT05PQ1lURVMqOiAKdGhlIFZvbGNhbm8gcGxvdCBpcyBkaXNwbGF5ZWQgYmVsb3cgYW5kIHRoZSBnZW5lcyB3aXRoIHAtdmFsdWUgPiAuMDEgYW5kIGZvbGQgY2hhbmdlID4gMS4zIGFyZSBtYXJrZWQgaW4gYmx1ZSB0byBpZGVudGlmeSBzZXQgb2YgZ2VuZXMgdGhhdCBtaWdodCBwbGF5IGEgcm9sZSBkdXJpbmcgZmlzdHVsYSBmYWlsdXJlLgoKYGBge3IgZWNobz1GQUxTRX0KR2VuZSA8LSBNb25vY3l0ZVsxOjFdOwpEYXRhIDwtIE1vbm9jeXRlWzI6KHBbMl0pXTsKbiA8LSBkaW0oRGF0YSk7Cm0gPC0gKChuWzJdKS8yKTsKQmFzZWxpbmUgPC0gRGF0YSRYMzExNDMuQjsKV2VlazIgPC0gRGF0YSRYMzExNDMuMlc7ClBhdGllbnQxIDwtIGRhdGEuZnJhbWUoR2VuZSxCYXNlbGluZSxXZWVrMikKIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2UgZm9sZCBjaGFuZ2UgZm9yIGVhY2ggZ2VuZSBmcm9tIGJhc2VsaW5lIHRvIDItd2Vla3MgYWZ0ZXIgZmlzdHVsYQpsb2cyRm9sZENoYW5nZSA8LSAoV2VlazIgLSBCYXNlbGluZSk7CiMgQ2FsY3VsYXRlIHRoZSBwLXZhbHVlIG9mIHRoZSB0LXRlc3QgYmV0d2VlbiBiYXNlbGluZSBhbmQgMi13ZWVrcyBhZnRlciBmaXN0dWxhClB2YWx1ZSA8LSBhcHBseShEYXRhLCAxLCBmdW5jdGlvbihEYXRhKSB7CiAgdC50ZXN0KHggPSBEYXRhWzE6bV0sIHkgPSBEYXRhWyhtKzEpOihuWzJdKV0pJHAudmFsdWV9KQojIFNhdmUgZGF0YQpSZXN1bHRzID0gY2JpbmQoR2VuZSwgbG9nMkZvbGRDaGFuZ2UpOwpSZXN1bHRzID0gY2JpbmQoUmVzdWx0cywgcHZhbHVlID0gUHZhbHVlKTsKd3JpdGUuY3N2KFJlc3VsdHMsIGZpbGUgPSAiUGF0aWVudDMxMTQzX01vbm9jeXRlX0ZDLVBWLmNzdiIpCndyaXRlLnRhYmxlKFJlc3VsdHMsIGZpbGUgPSAiUGF0aWVudDMxMTQzX01vbm9jeXRlX0ZDLVBWLnR4dCIpCiMgTWFrZSBhIGJhc2ljIHZvbGNhbm8gcGxvdApUYWJsZSA8LSByZWFkLnRhYmxlKCJQYXRpZW50MzExNDNfTW9ub2N5dGVfRkMtUFYudHh0IiwgaGVhZGVyPVRSVUUpCndpdGgoVGFibGUsIHBsb3QobG9nMkZvbGRDaGFuZ2UsIC1sb2cxMChwdmFsdWUpLCBwY2g9MSwgbWFpbj0iUGF0aWVudCAzMTE0MyBNb25vY3l0ZSIsIHhsaW09YygtNSw1KSkpCiMgQWRkIGNvbG9yZWQgcG9pbnRzIGdyZWVuIGlmIHB2YWx1ZTwuMDEgKGFsaWFzIC1sb2cxMChwdmFsdWUpPDIpIGFuZCBGb2xkQ2hhbmdlPjEuMwphIDwtIGxvZzIoMS4zKTsKd2l0aChzdWJzZXQoVGFibGUsIHB2YWx1ZT4uMDEgfCBhYnMobG9nMkZvbGRDaGFuZ2UpPGEpLCBwb2ludHMobG9nMkZvbGRDaGFuZ2UsIC1sb2cxMChwdmFsdWUpLCBwY2g9MSwgY29sPSJncmF5IikpOwp3aXRoKHN1YnNldChUYWJsZSwgcHZhbHVlPC4wMSAmIGFicyhsb2cyRm9sZENoYW5nZSk+YSksIHBvaW50cyhsb2cyRm9sZENoYW5nZSwgLWxvZzEwKHB2YWx1ZSksIHBjaD0yMCwgY29sPSJibGFjayIpKTsKYWJsaW5lKHY9YygrYSwtYSksIGNvbD1jKCJibGFjayIsICJibGFjayIpLCBsdHk9YygyLDIpLCBsd2Q9YygxLCAxKSk7CmFibGluZShoPTIsIGNvbD1jKCJibGFjayIsICJibGFjayIpLCBsdHk9YygyLDIpLCBsd2Q9YygxLCAxKSkKYGBgCgpUaGUgbGlzdCBvZiBzaWduaWZpY2FudCBjaGFuZ2UgaW4gZ2VuZSBleHByZXNzaW9uIGZyb20gKm1vbm9jeXRlcyogaXMgaGVyZSByZXBvcnRlZC4gVG90YWwgbnVtYmVyIDEyNC4KYGBge3IgZWNobz1GQUxTRX0KU2lnbmlmaWNhbnQgPC0gc3Vic2V0KFRhYmxlLCBwdmFsdWU8LjAxICYgYWJzKGxvZzJGb2xkQ2hhbmdlKT5hKQpTaWduaWZpY2FudAp3cml0ZS5jc3YoU2lnbmlmaWNhbnQsIGZpbGUgPSAiUGF0aWVudDMxMTQzX1NpZ25pZmljYW50X01vbm9jeXRlcy5jc3YiKQpgYGAKCipORVVUUk9QSElMUyo6IAp0aGUgVm9sY2FubyBwbG90IGlzIGRpc3BsYXllZCBiZWxvdyBhbmQgdGhlIGdlbmVzIHdpdGggcC12YWx1ZSA+IC4wMSBhbmQgZm9sZCBjaGFuZ2UgPiAxLjMgYXJlIG1hcmtlZCBpbiBibHVlIHRvIGlkZW50aWZ5IHNldCBvZiBnZW5lcyB0aGF0IG1pZ2h0IHBsYXkgYSByb2xlIGR1cmluZyBmaXN0dWxhIGZhaWx1cmUuCmBgYHtyIGVjaG89RkFMU0V9CiMgUmVhZCB0aGUgZ2VuZSBleHByZXNzaW9uIGRhdGEgc2V0CkJhc2VsaW5lIDwtIERhdGEkWDMxMTQzLkI7ICN3aWxsIGJlIGNoYW5nZWQgd2l0aCBlYWNoIHBhdGllbnQgY29kZQpXZWVrMiA8LSBEYXRhJFgzMTE0My4yVzsgI3dpbGwgYmUgY2hhbmdlZCB3aXRoIGVhY2ggcGF0aWVudCBjb2RlClBhdGllbnQxIDwtIGRhdGEuZnJhbWUoR2VuZSxCYXNlbGluZSxXZWVrMikKIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2UgZm9sZCBjaGFuZ2UgZm9yIGVhY2ggZ2VuZSBmcm9tIGJhc2VsaW5lIHRvIDItd2Vla3MgYWZ0ZXIgZmlzdHVsYQpsb2cyRm9sZENoYW5nZSA8LSAoV2VlazIgLSBCYXNlbGluZSk7CiMgQ2FsY3VsYXRlIHRoZSBwLXZhbHVlIG9mIHRoZSB0LXRlc3QgYmV0d2VlbiBiYXNlbGluZSBhbmQgMi13ZWVrcyBhZnRlciBmaXN0dWxhClB2YWx1ZSA8LSBhcHBseShEYXRhLCAxLCBmdW5jdGlvbihEYXRhKSB7CiAgdC50ZXN0KHggPSBEYXRhWzE6bV0sIHkgPSBEYXRhWyhtKzEpOihuWzJdKV0pJHAudmFsdWV9KQojIFNhdmUgZGF0YQpSZXN1bHRzID0gY2JpbmQoR2VuZSwgbG9nMkZvbGRDaGFuZ2UpOwpSZXN1bHRzID0gY2JpbmQoUmVzdWx0cywgcHZhbHVlID0gUHZhbHVlKTsKd3JpdGUuY3N2KFJlc3VsdHMsIGZpbGUgPSAiUGF0aWVudDMxMTQzX05ldXRyb3BoaWxfRkMtUFYuY3N2IikKd3JpdGUudGFibGUoUmVzdWx0cywgZmlsZSA9ICJQYXRpZW50MzExNDNfTmV1dHJvcGhpbF9GQy1QVi50eHQiKQojIE1ha2UgYSBiYXNpYyB2b2xjYW5vIHBsb3QKVGFibGUgPC0gcmVhZC50YWJsZSgiUGF0aWVudDMxMTQzX05ldXRyb3BoaWxfRkMtUFYudHh0IiwgaGVhZGVyPVRSVUUpCndpdGgoVGFibGUsIHBsb3QobG9nMkZvbGRDaGFuZ2UsIC1sb2cxMChwdmFsdWUpLCBwY2g9MSwgbWFpbj0iUGF0aWVudCAzMTE0MyBOZXV0cm9waGlsIikpCiMgQWRkIGNvbG9yZWQgcG9pbnRzIGdyZWVuIGlmIHB2YWx1ZTwuMDEgKGFsaWFzIC1sb2cxMChwdmFsdWUpPDIpIGFuZCBGb2xkQ2hhbmdlPjEuMwphIDwtIGxvZzIoMS4zKTsKd2l0aChzdWJzZXQoVGFibGUsIHB2YWx1ZT4uMDEgfCBhYnMobG9nMkZvbGRDaGFuZ2UpPGEpLCBwb2ludHMobG9nMkZvbGRDaGFuZ2UsIC1sb2cxMChwdmFsdWUpLCBwY2g9MSwgY29sPSJncmF5IikpOwp3aXRoKHN1YnNldChUYWJsZSwgcHZhbHVlPC4wMSAmIGFicyhsb2cyRm9sZENoYW5nZSk+YSksIHBvaW50cyhsb2cyRm9sZENoYW5nZSwgLWxvZzEwKHB2YWx1ZSksIHBjaD0yMCwgY29sPSJibGFjayIpKTsKYWJsaW5lKHY9YygrYSwtYSksIGNvbD1jKCJibGFjayIsICJibGFjayIpLCBsdHk9YygyLDIpLCBsd2Q9YygxLCAxKSk7CmFibGluZShoPTIsIGNvbD1jKCJibGFjayIsICJibGFjayIpLCBsdHk9YygyLDIpLCBsd2Q9YygxLCAxKSk7CmBgYAoKVGhlIGxpc3Qgb2Ygc2lnbmlmaWNhbnQgY2hhbmdlIGluIGdlbmUgZXhwcmVzc2lvbiBmcm9tICpuZXV0cm9waGlscyogaXMgaGVyZSByZXBvcnRlZC4gVG90YWwgbnVtYmVyIDEsMTkzLgpgYGB7ciBlY2hvPUZBTFNFfQpTaWduaWZpY2FudCA8LSBzdWJzZXQoVGFibGUsIHB2YWx1ZTwuMDEgJiBhYnMobG9nMkZvbGRDaGFuZ2UpPmEpClNpZ25pZmljYW50CndyaXRlLmNzdihTaWduaWZpY2FudCwgZmlsZSA9ICJQYXRpZW50MzExNDNfU2lnbmlmaWNhbnRfTmV1dHJvcGhpbHMuY3N2IikKYGBgCgoqQnkgaW52ZXN0aWdhdGluZyB0aGUgZ2Vub21pY3Mgb2YgYWxsIHBhdGllbnRzIHdoaWNoIGZpc3R1bGEgYWxyZWFkeSBmYWlsaWVkIG9yIHNob3cgaGVtb2R5bmFtaWMgc2lnbmF0dXJlcyBvZiBmYWlsdXJlLCB3ZSBhcmUgYWJsZSB0byBvYnRhaW4gYSBsaXN0IG9mIGdlbmVzIHBvdGVuaXRhbGx5IGludm9sdmVkIHdpdGggZmlzdHVsYSBmYWlsdXJlIG1lY2hhbmljc21zLioKCioqKgoKKipGdWxsIGRhdGEtc2V0cyBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9Sb3NhbWFyaWFUcmljYXJpY28vMjAxOVRESS90cmVlL21hc3Rlci9EQVRBLlNFVFMpLioqICAKKipNYWluIFIgc2NyaXB0cyBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9Sb3NhbWFyaWFUcmljYXJpY28vMjAxOVRESS90cmVlL21hc3Rlci9SLlNDUklQVFMpLioqCg==