Independent variables (constraints)

• create_networkyn?
• selectyn?
• disperseyn?
• competeyn?
• catastropheyn?
• selectforDyn?

Independent variables (others)

• numlink
• cdis1
• frqmod
• percent_species_to_wipeout
• var_fitness
• pp
• max_initial_proportion_links
• maxsp

Dependent variables

• landscape.fitness.mean
• landscape.fitness.linked
• landscape.fitness.unlinked
• cluster.fitness.mean
• landscape.fitness.linked_unlinked.difference
• cluster-fitness.linked_unlinked.difference
• cluster.linked_unlinked_species.number.mean.difference
• landscape.linked_species.deaths.mean
• landscape.unlinked_species.deaths.mean
• landscape.linked_species.mean.turnover
• landscape.unlinked_species.mean.turnover
• avg_evennessT
• avg_evennessL
• avg_evennessU
• avg_InterpEven
• count_links
• count_species

Simulation

Purpose

This model has been designed to test how specially defined ecological communities maintain stability even in the presence of stochastic turnover. Using Vellend’s (Vellend 2016) proposed set of high-level processes for conceptually framing ecological communities, i.e., selection, species drift, speciation, and dispersal, we hypothesize that these provide constraint closure in the way proposed by Moreno and Mossio (Moreno and Mossio 2015) that contribute to biological autonomy. Moreover we hypothesize specifically that these will allow stable ecological signatures to arise and be maintained through constraint closure. In this way we seek to exemplify the possibility of creating some measure of generalizability in ecosystem community structure.

Entities, state variables, and scales

The model is structured on a spatial torridal grid composed of NxN patches that form clusters of suitable and unsuitable areas. The unsuitable habitat patches form a barrier to, or retardation of, migration. Each habitat patch represents a packed set of niches that can hold M Species. Each patch contains an environmental niche score, a variable representing a habitat suitability index chosen from a uniform random distribution between 0 and 1. Each species has a similar niche score, which represents a one-dimensional niche measure of the species’ needs. This corresponds to the patch environmental niche score, which in tern is a measure of what needs that habitat will provide. A species’ fitness will be defined as the absolute distance between a species niche score and this patch’s environmental niche score.

Some species are able to form mutualisms with other species and a directed network is established between k <= M species. The fitness of a linked species, differs from unlinked species and is calculated as a given function of linked species in a given patch, e.g., the maximum or average fitness of the linked species.

The specific constraints thought to allow the creation of stable communities are (a) Selection; (b) Dispersal; (c) mutualism (with any eye to mycorrhizal symbiotic relationships); (d) Spatial Competition; and (e) Fitness Competition between linked and unlinked species. In addition there are two assumed constraints that are structural parts of the model and are not tested for effect in this stage of the model analysis but may be explored at a latter time. (a) niche packing, i.e., a finite niche space; and (b) spatial structure limiting dispersal among species.

Process Overview and Scheduling

After establishing the grid (details below in initialization section), M species are created in each patch i. A given number K, are able to form mutualistic links, the rest, M-K, are not. Each time step, τ, represents the mean time a species is likely to exist in a community. At time, τ_l, k, mutualistic links are established within the patch for the initial population of species in each patch where k=Kρ. K is the maximum number of links that can be established, and ρ is a random variable that gives the proportion of potential links that do get established for a given K. The following processes procedures are given in the order they are executed.

• Select: Fitness is calculated based on the absolute distance of a given species’ niche score to the patch’s environmental niche score. For linked species the fitness is the highest fitness among those species with which it is linked. The species with the lowest fitness on each patch is eliminated.

• Dispersal: The species with the very highest fitness spreads to one of its neighbors if it has an opening, i.e., one of its neighbor patches has fewer than M species. If it is a species that can form links in its new patch it will do so.

• Fitness competition: One of the linkable species and one of the unlinkable species is randomly selected within each patch. The one with the higher fitness reproduces, the one with the lower fitness goes extinct in the patch.

• Speciation: Whenever there are G <= M openings in the niches within a patch, G new species are created from the G species with the highest fitnesses. The new species will have a niche score with the same mean fitness as its parent’s fitness value, but with variance ν.

• Catastrophes: At given intervals, I ∈{1,t_max} a proportion, φ, of the M species in each patch can be randomly wiped out. These perturbations provide a test of stability in terms of how the patch recovers from its loss of species.

Design concepts

• Emergence: We expect stability to emerge from certain combinations of constraints which form a closed loop of interaction and create constraint closure among the ecological processes described above.

• Objectives: We will run the model under a number of different parameter combinations to understand how stability is structured and under what conditions of perturbation it is maintained.

• Interactions: Among species-agents in the model, interactions can be positive among those forming mutualistic associations, and negative among those that compete.

• Stochasticity: Stochasticity enters into the model in several places. (a) The initial patch structure of the landscape is randomly generated; (b) The proportion of species chosen to actually form links, ρ is a random variable; (c) the species that go extinct in the drift stage are randomly chosen with probability proportional to fitness; species with high fitness chosen to move, move randomly to one of their 8, Moore-neighborhood neighbors; (d) The variation of fitness around newly spectated species is a random variable ν; and initially the environmental variable and the species environmental needs variable are randomly chosen; and (e) Species eliminated in a catastrophe are randomly chosen.

• Variables of Interest: Turnover rate: The turnover rate is the number of new species created at each time step. The way the model is formulation new species arise when there is an opening in relation to the packed niche. This happens in competition between the linked and unlinked species, in selection events in which the least fit species is selected for elimination, and in perturbation events.

Initialization

Initialization consists of a random landscape being produced using two variables that control the number of patches selected and the distribution of patches. Figure xx gives an example of one of the landscapes produced. This procedure is based upon xxxx.

Testing

The model Behavior Space in NetLogo was used to test the overall behavior of the model. A complete iteration set of the binary switches turning on and off the constraint submodels and for three values of the possible number of links per species and two values of different landscape types leading to 144 possible combinations which compromise the permutation set used to explore the constraint space, with T=500 timesteps for each sample from the model hyperspace. A uniform random distribution of the variables propform, varfitness, frqmod, and perwipe, were drawn from the 150 iterations of each of the possible constraint permutation set for each of the These were taken with replacement over the multidimensional parameter space. Mixed model analyses (details are found in Supplemental Materials ) were used to explore the influence of each of the parameters thought to be of interest. The results of these analyses need a cautionary warning. As White et al. (2014) {White, 2014 #58} note, these results should not be interpreted as a test of statistical significance of each of the parameter set as the likelihood values and statistical tests are easily influenced by the number of iterations used in the model testing. Therefore they were used as a heuristic to chose the set of parameters that might be averaged or representative values chosen that do not influence how the constraints inform the results of the model.

In all of the model selection analyses, the constraint variables were retained in parameters related to fitness and as expected. For dependent variables involving fitness the full model was usually needed to explain the variation. Exceptions include for within cluster measures of fitness. The variation in turnover rates were explained by the full set of constraints and by the frequency of perturbation and the intensity of the perturbation. This provides evidence that the model’s variable and parameter set are adequate.

Variables and their roles

Global variables (independent; fixed)

• maxticks: Number of time steps to run model (time step is average species time in patch until extinction–Global used throughout)
• Maxsptot: The maximum number of species in plot–Used by set up.
• create_networkyn?: binary determines if a mutualistic network is created. CONSTRAINT
• selectyn?: binary, determines if selection is included in the runs CONSTRAINT
• disperseyn?: binary, determines if dispersal is used in the model CONSTRAINT
• competeyn?: binary, determines if competition between networked and non-networked species are used in the model. CONSTRAINT
• selectforyn?: binary, determines if most fit species are moved into patch if their is and unoccupied niche in the patch CONSTRAINT
• catastropheyn?: binary, determines if catastrophes are included in the model CONSTRAINT
• numlink: number of links each species can form with other species
• max_intial_proportion_links: proportion of maximum number of links in initial establishment of links
• cdis1: used in clustering algorithm to influence distribution of patches and clusters
• cdis2: used in clustering algorithm to influence distribution of patches and clusters
• frqmod: frequency of catastrophes
• percent_species_to_wipeout: percent of species wiped out in catastrophes
• var_fitness: variation in offspring’s inheritance of fitness value from parents (used in procedure-speciation).
• pp: parameter in establishing clusters that give some proportion of good habitat set to .25 now

Patch variables (independent; fixed)

• envir: the environment of the patch
• cluster: cluster is patch which defines cluster
• bad_cluster: used in cluster formation
• clusternum: numerical designation for cluster
• bad_clusternum: used in cluster formation
• pinclus: number of patches in your clustermaxtotsp
• propmaxrat: relative size of cluster compared to largest cluster

Patch variables (dependent)

• num_species_here: number of species here
• num_speices_linked_here: number of linked species
• max_num_species: maxnum of species here
• numdieU: number of unlinked species in patch that have died
• numdieL: number of unlinked species in patch that have died
• numdieR: number of species killed in catastrophe
• turnoverrate: turnover rate in patch
• turnoverrateL: turnover rate of linked species in patch
• turnoverrateU: turnover rate of unlinked species in patch
• lagspecies: agentset with species here last time
• lagspeciesL: agentset with species here last time
• lagspeciesU: agentset with species here last time

Species variables (independent)

• sp_num: species number
• max_links_I_can_have: individual number of links a species can form
• num_my_links: number of links I have
• inv_fitness: probability of extinction
• envir_need: environment preferred

Reporters (possible dependent variables)

• patch.habitat.percent: : The percent of good patches out of total number of patches
• patch.habitat.count: : The total number of habitat patches
• species.number.turnover: : This is a surrogate for turnover–Why? Because at new species are assigned at new species number based on +1 that last species. The sum of all species divided by the number of species gives a measure of how many new species there are.
• species.number.turnover.difference: : Gives the sum of species numbers minus the last time, or basically the change in species number for each time step
• species.number.stdiv: : gives the standard deviation of the species, i.e, how much variation there is in species numbers– Low means that all patches are turning over species at a similar rate – high means patches turnover rate is more variable.
• patches.species.withlinks.count: : The number of patches with any links
• landscape.fitness.mean: : The global fitness across all patches
• landscape.fitness.var: : variance in global fitness
• cluster.fitness.mean: : the adverage mean culster fitness averaged across region
• cluster.fitness.var: the variance among mean cluster fitness across the region
• cluster.linked.var: varance in number of linked species among clusters
• cluster.unlinked.var: varance in number of unlinked species among clusters
• cluster.linked_unlinked.var.difference: Difference in varince between unlinked and linked species
• landscape.fitness.linked_unlinked.difference: The difference in global fitness between linked and unlinked species
• cluster.fitness.linked_unlinked.difference: The difference in mean cluster fitness between linked and unlinked species : The cluster mean of species number of linked species
• cluster.linked_species.number.mean: The cluster mean of species number of linked species
• cluster.unlinked_species.number.mean: Cluster mean of species number in unlinked species
• cluster.linked_unlinked_species.number.mean.difference: Mean species number difference between linked and unlinked species
• cluster.patches.links.mean: count mean number of patches with links averaged across clusters
• cluster.patches.unlinks.mean: count mean number of patches without links averaged across clusters
• landscape.species.number.var: The variance of species number over all species in landscape
• landscape.contagion: Contagen index from equation #22 Landscape Ecology vol. 8 no. 3 pp 155-162 (1993) ‘A new contagion index to quantify spatial patterns of landscapes’ by Habin Li and James F. Reynolds
• model.stop.reason: How the model ended endlich = 1 => model reached end of max runs; endlich = 2 => all speieces went extinct; endlich = 3 => links go to zero for thirty ticks; endlich = 4 => all paches have links.
• landscape.linked.actual_possible: The proportion of linked species out of total number of possible linked species if all linkable species were linked
• cluster.count: The number of clusters
• cluster.size.mean: mean cluster size
• cluster.linked_species.deaths.mean: The cluster mean of the number of dead species in linked species.
• cluster.unlinked_species.deaths.mean: The cluster mean of the number of dead species in unlinked species.
• cluster.linked_species.random_deaths.mean: The cluster mean of the number of species killed randomly (those killed in a catastrophe)
• landscape.linked_species.deaths.mean: The number of linked species deaths in entire landscape
• landscape.unlinked_species.deaths.mean: The number of unlinked species deaths in entire landscape
• landscape.species.random_deaths: number of species killed randomly in landscape
• landscape.species.number_per_patch.mean: number of species per patch in landscape
• landscape.linked_species.number_per_patch.mean: number of linked species per patch in landscape
• cluster.linked_species.fitness.mean: The cluster mean of species fitness of linked species
• cluster.unlinked_species.fitness.mean: The cluster mean of species fitness of unlinked species
• cluster.linked_species.fitness.var: Mean variance in number of linked species per cluster
• cluster.unlinked_species.fitness.var: Mean variance in number of unlinked species per cluster
• landscape.turnover.slope.run1: calculates the slope of the line that runs through turnover rate between turnover_interval1 and turnover_interval2 near beginning of runs
• landscape.turnover.slope.run2: calculates the slope of the line that runs through the turnover rate at end of runs
• landscape.turnover.YInter.run1: Calculates y intercept of line that runs through turnover rate between turnover_interval1 and turnover_interval2 near begining of runs
• landscape.turnover.YInter.run2: Calculates y intercept of line that runs through turnover rate near end of runs
• landscape.turnover.Rsquare.run1: Calculates R-square of of line that runs through turnover rate between turnover_interval1 and turnover_interval2 near begining of runs
• landscape.turnover.Rsquare.run2: Calculates R-square line that runs through turnover rate near end of runs
• landscape.turnoverL.slope.run1: calculates the slope of the line that runs through turnover rate between turnover_interval1 and turnover_interval2 near begining of runs of linked species
• landscape.turnoverL.slope.run2: caculates the slope ofthe line that runs through the turnover rate at end of runs of linked species
• landscape.turnoverL.YInter.run1: Calculates y intercept of line that runs through turnover rate between turnover_interval1 and turnover_interval2 near begining of runs of linked species
• landscape.turnoverL.YInter.run2: Calculates y intercept of line that runs through turnover rate near end of runs of linked species
• landscape.turnoverL.Rsquare.run1: Caculates R-sqaure of of line that runs through turnover rate between turnover_interval1 and turnover_interval2 near begining of runs of linked species
• landscape.turnoverL.Rsquare.run2: Calculates R-square line that runs through turnover rate near end of runs of linked species
• landscape.turnoverU.slope.run1: calculates the slope of the line that runs through turnover rate between turnover_interval1 and turnover_interval2 near begining of runs of unlinked species
• landscape.turnoverU.slope.run2: caculates the slope ofthe line that runs through the turnover rate at end of runs of unlinked species
• landscape.turnoverU.YInter.run1: Calculates y intercept of line that runs through turnover rate between turnover_interval1 and turnover_interval2 near begining of runs of unlinked species
• landscape.turnoverU.YInter.run2: calculates y intercept of line that runs through turnover rate between turnover_interval1 and turnover_interval2 near begining of runs of unlinked species
• landscape.turnoverU.Rsquare.run1: Caculates R-sqaure of of line that runs through turnover rate between turnover_interval1 and turnover_interval2 near begining of runs of unlinked species
• landscape.turnoverU.Rsquare.run2: Calculates R-square line that runs through turnover rate near end of runs of unlinked species
• landscape.linked_species.mean.turnover: The global turnover of linked species across all patches
• landscape.unlinked_species.mean.turnover: The global turnover of unlinked species across all patches
• landscape.species.mean.turnover: The global turnover of species across all patches
• count_links: Total number of links
• count_species: Total number of species
LS0tCnRpdGxlOiAiU2ltdWxhdGlvbiB2YXJpYWJsZXMgYW5kIHBhcmFtZXRlcnMiCmF1dGhvcjogIlN0ZXZlbiBMLiBQZWNrIGFuZCBBbmRyZXcgSGVpc3MiCmRhdGU6ICJMYXN0IHJ1bjogYHIgZm9ybWF0KFN5cy50aW1lKCksICclQiAlZSwgJVknKWAiCi0tLQoKIyBWYXJpYWJsZXMgd2UgY2FyZSBhYm91dCBtb3N0CgojIyBJbmRlcGVuZGVudCB2YXJpYWJsZXMgKGNvbnN0cmFpbnRzKQoKLSAqKmBjcmVhdGVfbmV0d29ya3luP2AqKgotICoqYHNlbGVjdHluP2AqKgotICoqYGRpc3BlcnNleW4/YCoqCi0gKipgY29tcGV0ZXluP2AqKgotICoqYGNhdGFzdHJvcGhleW4/YCoqCi0gKipgc2VsZWN0Zm9yRHluP2AqKgoKIyMgSW5kZXBlbmRlbnQgdmFyaWFibGVzIChvdGhlcnMpCgotICoqYG51bWxpbmtgKioKLSAqKmBjZGlzMWAqKgotICoqYGZycW1vZGAqKgotICoqYHBlcmNlbnRfc3BlY2llc190b193aXBlb3V0YCoqCi0gKipgdmFyX2ZpdG5lc3NgKioKLSAqKmBwcGAqKgotICoqYG1heF9pbml0aWFsX3Byb3BvcnRpb25fbGlua3NgKioKLSAqKmBtYXhzcGAqKgoKIyMgRGVwZW5kZW50IHZhcmlhYmxlcwoKLSAqKmBsYW5kc2NhcGUuZml0bmVzcy5tZWFuYCoqCi0gKipgbGFuZHNjYXBlLmZpdG5lc3MubGlua2VkYCoqCi0gKipgbGFuZHNjYXBlLmZpdG5lc3MudW5saW5rZWRgKioKLSAqKmBjbHVzdGVyLmZpdG5lc3MubWVhbmAqKgotICoqYGxhbmRzY2FwZS5maXRuZXNzLmxpbmtlZF91bmxpbmtlZC5kaWZmZXJlbmNlYCoqCi0gKipgY2x1c3Rlci1maXRuZXNzLmxpbmtlZF91bmxpbmtlZC5kaWZmZXJlbmNlYCoqCi0gKipgY2x1c3Rlci5saW5rZWRfdW5saW5rZWRfc3BlY2llcy5udW1iZXIubWVhbi5kaWZmZXJlbmNlYCoqCi0gKipgbGFuZHNjYXBlLmxpbmtlZF9zcGVjaWVzLmRlYXRocy5tZWFuYCoqCi0gKipgbGFuZHNjYXBlLnVubGlua2VkX3NwZWNpZXMuZGVhdGhzLm1lYW5gKioKLSAqKmBsYW5kc2NhcGUubGlua2VkX3NwZWNpZXMubWVhbi50dXJub3ZlcmAqKgotICoqYGxhbmRzY2FwZS51bmxpbmtlZF9zcGVjaWVzLm1lYW4udHVybm92ZXJgKioKLSAqKmBhdmdfZXZlbm5lc3NUYCoqCi0gKipgYXZnX2V2ZW5uZXNzTGAqKgotICoqYGF2Z19ldmVubmVzc1VgKioKLSAqKmBhdmdfSW50ZXJwRXZlbmAqKgotICoqYGNvdW50X2xpbmtzYCoqCi0gKipgY291bnRfc3BlY2llc2AqKgoKCiMgU2ltdWxhdGlvbgoKIyMgUHVycG9zZQoKVGhpcyBtb2RlbCBoYXMgYmVlbiBkZXNpZ25lZCB0byB0ZXN0IGhvdyBzcGVjaWFsbHkgZGVmaW5lZCBlY29sb2dpY2FsIGNvbW11bml0aWVzIG1haW50YWluIHN0YWJpbGl0eSBldmVuIGluIHRoZSBwcmVzZW5jZSBvZiBzdG9jaGFzdGljIHR1cm5vdmVyLiBVc2luZyBWZWxsZW5kJ3MgKFZlbGxlbmQgMjAxNikgcHJvcG9zZWQgc2V0IG9mIGhpZ2gtbGV2ZWwgcHJvY2Vzc2VzIGZvciBjb25jZXB0dWFsbHkgZnJhbWluZyBlY29sb2dpY2FsIGNvbW11bml0aWVzLCBpLmUuLCBzZWxlY3Rpb24sIHNwZWNpZXMgZHJpZnQsIHNwZWNpYXRpb24sIGFuZCBkaXNwZXJzYWwsIHdlIGh5cG90aGVzaXplIHRoYXQgdGhlc2UgcHJvdmlkZSBjb25zdHJhaW50IGNsb3N1cmUgaW4gdGhlIHdheSBwcm9wb3NlZCBieSBNb3Jlbm8gYW5kIE1vc3NpbyAoTW9yZW5vIGFuZCBNb3NzaW8gMjAxNSkgdGhhdCBjb250cmlidXRlIHRvIGJpb2xvZ2ljYWwgYXV0b25vbXkuIE1vcmVvdmVyIHdlIGh5cG90aGVzaXplIHNwZWNpZmljYWxseSB0aGF0IHRoZXNlIHdpbGwgYWxsb3cgc3RhYmxlIGVjb2xvZ2ljYWwgc2lnbmF0dXJlcyB0byBhcmlzZSBhbmQgYmUgbWFpbnRhaW5lZCB0aHJvdWdoIGNvbnN0cmFpbnQgY2xvc3VyZS4gSW4gdGhpcyB3YXkgd2Ugc2VlayB0byBleGVtcGxpZnkgdGhlIHBvc3NpYmlsaXR5IG9mIGNyZWF0aW5nIHNvbWUgbWVhc3VyZSBvZiBnZW5lcmFsaXphYmlsaXR5IGluIGVjb3N5c3RlbSBjb21tdW5pdHkgc3RydWN0dXJlLiAKCgojIyBFbnRpdGllcywgc3RhdGUgdmFyaWFibGVzLCBhbmQgc2NhbGVzCgpUaGUgbW9kZWwgaXMgc3RydWN0dXJlZCBvbiBhIHNwYXRpYWwgdG9ycmlkYWwgZ3JpZCBjb21wb3NlZCBvZiBOeE4gcGF0Y2hlcyB0aGF0IGZvcm0gY2x1c3RlcnMgb2Ygc3VpdGFibGUgYW5kIHVuc3VpdGFibGUgYXJlYXMuIFRoZSB1bnN1aXRhYmxlIGhhYml0YXQgcGF0Y2hlcyBmb3JtIGEgYmFycmllciB0bywgb3IgcmV0YXJkYXRpb24gb2YsIG1pZ3JhdGlvbi4gRWFjaCBoYWJpdGF0IHBhdGNoIHJlcHJlc2VudHMgYSBwYWNrZWQgc2V0IG9mIG5pY2hlcyB0aGF0IGNhbiBob2xkIE0gU3BlY2llcy4gRWFjaCBwYXRjaCBjb250YWlucyBhbiBlbnZpcm9ubWVudGFsIG5pY2hlIHNjb3JlLCBhIHZhcmlhYmxlIHJlcHJlc2VudGluZyBhIGhhYml0YXQgc3VpdGFiaWxpdHkgaW5kZXggY2hvc2VuIGZyb20gYSB1bmlmb3JtIHJhbmRvbSBkaXN0cmlidXRpb24gYmV0d2VlbiAwIGFuZCAxLiBFYWNoIHNwZWNpZXMgaGFzIGEgc2ltaWxhciBuaWNoZSBzY29yZSwgd2hpY2ggcmVwcmVzZW50cyBhIG9uZS1kaW1lbnNpb25hbCBuaWNoZSBtZWFzdXJlIG9mIHRoZSBzcGVjaWVz4oCZIG5lZWRzLiBUaGlzIGNvcnJlc3BvbmRzIHRvIHRoZSBwYXRjaCBlbnZpcm9ubWVudGFsIG5pY2hlIHNjb3JlLCB3aGljaCBpbiB0ZXJuIGlzIGEgbWVhc3VyZSBvZiB3aGF0IG5lZWRzIHRoYXQgaGFiaXRhdCB3aWxsIHByb3ZpZGUuIEEgc3BlY2llc+KAmSBmaXRuZXNzIHdpbGwgYmUgZGVmaW5lZCBhcyB0aGUgYWJzb2x1dGUgZGlzdGFuY2UgYmV0d2VlbiBhIHNwZWNpZXMgbmljaGUgc2NvcmUgYW5kIHRoaXMgcGF0Y2jigJlzIGVudmlyb25tZW50YWwgbmljaGUgc2NvcmUuIAoKU29tZSBzcGVjaWVzIGFyZSBhYmxlIHRvIGZvcm0gbXV0dWFsaXNtcyB3aXRoIG90aGVyIHNwZWNpZXMgYW5kIGEgZGlyZWN0ZWQgbmV0d29yayBpcyBlc3RhYmxpc2hlZCBiZXR3ZWVuIGsgPD0gTSBzcGVjaWVzLiBUaGUgZml0bmVzcyBvZiBhIGxpbmtlZCBzcGVjaWVzLCBkaWZmZXJzIGZyb20gdW5saW5rZWQgc3BlY2llcyBhbmQgaXMgY2FsY3VsYXRlZCBhcyBhIGdpdmVuIGZ1bmN0aW9uIG9mIGxpbmtlZCBzcGVjaWVzIGluIGEgZ2l2ZW4gcGF0Y2gsIGUuZy4sIHRoZSBtYXhpbXVtIG9yIGF2ZXJhZ2UgZml0bmVzcyBvZiB0aGUgbGlua2VkIHNwZWNpZXMuIAkKClRoZSBzcGVjaWZpYyBjb25zdHJhaW50cyB0aG91Z2h0IHRvIGFsbG93IHRoZSBjcmVhdGlvbiBvZiBzdGFibGUgY29tbXVuaXRpZXMgYXJlIChhKSBTZWxlY3Rpb247IChiKSBEaXNwZXJzYWw7IChjKSBtdXR1YWxpc20gKHdpdGggYW55IGV5ZSB0byBteWNvcnJoaXphbCBzeW1iaW90aWMgcmVsYXRpb25zaGlwcyk7IChkKSBTcGF0aWFsIENvbXBldGl0aW9uOyBhbmQgKGUpIEZpdG5lc3MgQ29tcGV0aXRpb24gYmV0d2VlbiBsaW5rZWQgYW5kIHVubGlua2VkIHNwZWNpZXMuICBJbiBhZGRpdGlvbiB0aGVyZSBhcmUgdHdvIGFzc3VtZWQgY29uc3RyYWludHMgdGhhdCBhcmUgc3RydWN0dXJhbCBwYXJ0cyBvZiB0aGUgbW9kZWwgYW5kIGFyZSBub3QgdGVzdGVkIGZvciBlZmZlY3QgaW4gdGhpcyBzdGFnZSBvZiB0aGUgbW9kZWwgYW5hbHlzaXMgYnV0IG1heSBiZSBleHBsb3JlZCBhdCBhIGxhdHRlciB0aW1lLiAoYSkgbmljaGUgcGFja2luZywgaS5lLiwgYSBmaW5pdGUgbmljaGUgc3BhY2U7IGFuZCAoYikgc3BhdGlhbCBzdHJ1Y3R1cmUgbGltaXRpbmcgZGlzcGVyc2FsIGFtb25nIHNwZWNpZXMuICAKCgojIyBQcm9jZXNzIE92ZXJ2aWV3IGFuZCBTY2hlZHVsaW5nCgpBZnRlciBlc3RhYmxpc2hpbmcgdGhlIGdyaWQgKGRldGFpbHMgYmVsb3cgaW4gaW5pdGlhbGl6YXRpb24gc2VjdGlvbiksIE0gc3BlY2llcyBhcmUgY3JlYXRlZCBpbiBlYWNoIHBhdGNoIGkuIEEgZ2l2ZW4gbnVtYmVyIEssIGFyZSBhYmxlIHRvIGZvcm0gbXV0dWFsaXN0aWMgbGlua3MsIHRoZSByZXN0LCBNLUssIGFyZSBub3QuIEVhY2ggdGltZSBzdGVwLCDPhCwgcmVwcmVzZW50cyB0aGUgbWVhbiB0aW1lIGEgc3BlY2llcyBpcyBsaWtlbHkgdG8gZXhpc3QgaW4gYSBjb21tdW5pdHkuIEF0IHRpbWUsIM+EX2wsIGssIG11dHVhbGlzdGljIGxpbmtzIGFyZSBlc3RhYmxpc2hlZCB3aXRoaW4gdGhlIHBhdGNoIGZvciB0aGUgaW5pdGlhbCBwb3B1bGF0aW9uIG9mIHNwZWNpZXMgaW4gZWFjaCBwYXRjaCB3aGVyZSBrPUvPgS4gSyBpcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgbGlua3MgdGhhdCBjYW4gYmUgZXN0YWJsaXNoZWQsIGFuZCDPgSBpcyBhIHJhbmRvbSB2YXJpYWJsZSB0aGF0IGdpdmVzIHRoZSBwcm9wb3J0aW9uIG9mIHBvdGVudGlhbCBsaW5rcyB0aGF0IGRvIGdldCBlc3RhYmxpc2hlZCBmb3IgYSBnaXZlbiBLLiBUaGUgZm9sbG93aW5nIHByb2Nlc3NlcyBwcm9jZWR1cmVzIGFyZSBnaXZlbiBpbiB0aGUgb3JkZXIgdGhleSBhcmUgZXhlY3V0ZWQuIAoKLSAqKlNlbGVjdCoqOiBGaXRuZXNzIGlzIGNhbGN1bGF0ZWQgYmFzZWQgb24gdGhlIGFic29sdXRlIGRpc3RhbmNlIG9mIGEgZ2l2ZW4gc3BlY2llc+KAmSBuaWNoZSBzY29yZSB0byB0aGUgcGF0Y2jigJlzIGVudmlyb25tZW50YWwgbmljaGUgc2NvcmUuIEZvciBsaW5rZWQgc3BlY2llcyB0aGUgZml0bmVzcyBpcyB0aGUgaGlnaGVzdCBmaXRuZXNzIGFtb25nIHRob3NlIHNwZWNpZXMgd2l0aCB3aGljaCBpdCBpcyBsaW5rZWQuIFRoZSBzcGVjaWVzIHdpdGggdGhlIGxvd2VzdCBmaXRuZXNzIG9uIGVhY2ggcGF0Y2ggaXMgZWxpbWluYXRlZC4gCgotICoqRGlzcGVyc2FsKio6IFRoZSBzcGVjaWVzIHdpdGggdGhlIHZlcnkgaGlnaGVzdCBmaXRuZXNzIHNwcmVhZHMgdG8gb25lIG9mIGl0cyBuZWlnaGJvcnMgaWYgaXQgaGFzIGFuIG9wZW5pbmcsIGkuZS4sIG9uZSBvZiBpdHMgbmVpZ2hib3IgcGF0Y2hlcyBoYXMgZmV3ZXIgdGhhbiBNIHNwZWNpZXMuIElmIGl0IGlzIGEgc3BlY2llcyB0aGF0IGNhbiBmb3JtIGxpbmtzIGluIGl0cyBuZXcgcGF0Y2ggaXQgd2lsbCBkbyBzby4gCgotICoqRml0bmVzcyBjb21wZXRpdGlvbioqOiBPbmUgb2YgdGhlIGxpbmthYmxlIHNwZWNpZXMgYW5kIG9uZSBvZiB0aGUgdW5saW5rYWJsZSBzcGVjaWVzIGlzIHJhbmRvbWx5IHNlbGVjdGVkIHdpdGhpbiBlYWNoIHBhdGNoLiBUaGUgb25lIHdpdGggdGhlIGhpZ2hlciBmaXRuZXNzIHJlcHJvZHVjZXMsIHRoZSBvbmUgd2l0aCB0aGUgbG93ZXIgZml0bmVzcyBnb2VzIGV4dGluY3QgaW4gdGhlIHBhdGNoLiAKCi0gKipTcGVjaWF0aW9uKio6IFdoZW5ldmVyIHRoZXJlIGFyZSBHIDw9IE0gIG9wZW5pbmdzIGluIHRoZSBuaWNoZXMgd2l0aGluIGEgcGF0Y2gsIEcgbmV3IHNwZWNpZXMgYXJlIGNyZWF0ZWQgZnJvbSB0aGUgRyBzcGVjaWVzIHdpdGggdGhlIGhpZ2hlc3QgZml0bmVzc2VzLiBUaGUgbmV3IHNwZWNpZXMgd2lsbCBoYXZlIGEgIG5pY2hlIHNjb3JlIHdpdGggdGhlIHNhbWUgbWVhbiBmaXRuZXNzIGFzIGl0cyBwYXJlbnQncyBmaXRuZXNzIHZhbHVlLCBidXQgd2l0aCB2YXJpYW5jZSDOvS4gCgkKLSAqKkNhdGFzdHJvcGhlcyoqOiBBdCBnaXZlbiBpbnRlcnZhbHMsIEkg4oiIezEsdF9tYXh9IGEgcHJvcG9ydGlvbiwgz4YsIG9mIHRoZSBNIHNwZWNpZXMgaW4gZWFjaCBwYXRjaCBjYW4gYmUgcmFuZG9tbHkgd2lwZWQgb3V0LiBUaGVzZSBwZXJ0dXJiYXRpb25zIHByb3ZpZGUgYSB0ZXN0IG9mIHN0YWJpbGl0eSBpbiB0ZXJtcyBvZiBob3cgdGhlIHBhdGNoIHJlY292ZXJzIGZyb20gaXRzIGxvc3Mgb2Ygc3BlY2llcy4gCiAgCgojIyBEZXNpZ24gY29uY2VwdHMKCi0gKipFbWVyZ2VuY2UqKjogV2UgZXhwZWN0IHN0YWJpbGl0eSB0byBlbWVyZ2UgZnJvbSBjZXJ0YWluIGNvbWJpbmF0aW9ucyBvZiBjb25zdHJhaW50cyB3aGljaCBmb3JtIGEgY2xvc2VkIGxvb3Agb2YgaW50ZXJhY3Rpb24gYW5kIGNyZWF0ZSBjb25zdHJhaW50IGNsb3N1cmUgYW1vbmcgdGhlIGVjb2xvZ2ljYWwgcHJvY2Vzc2VzIGRlc2NyaWJlZCBhYm92ZS4gCgotICoqT2JqZWN0aXZlcyoqOiBXZSB3aWxsIHJ1biB0aGUgbW9kZWwgdW5kZXIgYSBudW1iZXIgb2YgZGlmZmVyZW50IHBhcmFtZXRlciBjb21iaW5hdGlvbnMgdG8gdW5kZXJzdGFuZCBob3cgc3RhYmlsaXR5IGlzIHN0cnVjdHVyZWQgYW5kIHVuZGVyIHdoYXQgY29uZGl0aW9ucyBvZiBwZXJ0dXJiYXRpb24gaXQgaXMgbWFpbnRhaW5lZC4gCgotICoqSW50ZXJhY3Rpb25zKio6IEFtb25nIHNwZWNpZXMtYWdlbnRzIGluIHRoZSBtb2RlbCwgaW50ZXJhY3Rpb25zIGNhbiBiZSBwb3NpdGl2ZSBhbW9uZyB0aG9zZSBmb3JtaW5nIG11dHVhbGlzdGljIGFzc29jaWF0aW9ucywgYW5kIG5lZ2F0aXZlIGFtb25nIHRob3NlIHRoYXQgY29tcGV0ZS4gCgotICoqU3RvY2hhc3RpY2l0eSoqOiBTdG9jaGFzdGljaXR5IGVudGVycyBpbnRvIHRoZSBtb2RlbCBpbiBzZXZlcmFsIHBsYWNlcy4gKGEpIFRoZSBpbml0aWFsIHBhdGNoIHN0cnVjdHVyZSBvZiB0aGUgbGFuZHNjYXBlIGlzIHJhbmRvbWx5IGdlbmVyYXRlZDsgKGIpIFRoZSBwcm9wb3J0aW9uIG9mIHNwZWNpZXMgY2hvc2VuIHRvIGFjdHVhbGx5IGZvcm0gbGlua3MsIM+BIGlzIGEgcmFuZG9tIHZhcmlhYmxlOyAoYykgdGhlIHNwZWNpZXMgdGhhdCBnbyBleHRpbmN0IGluIHRoZSBkcmlmdCBzdGFnZSBhcmUgcmFuZG9tbHkgY2hvc2VuIHdpdGggcHJvYmFiaWxpdHkgcHJvcG9ydGlvbmFsIHRvIGZpdG5lc3M7IHNwZWNpZXMgd2l0aCBoaWdoIGZpdG5lc3MgY2hvc2VuIHRvIG1vdmUsIG1vdmUgcmFuZG9tbHkgdG8gb25lIG9mIHRoZWlyIDgsIE1vb3JlLW5laWdoYm9yaG9vZCBuZWlnaGJvcnM7IChkKSBUaGUgdmFyaWF0aW9uIG9mIGZpdG5lc3MgYXJvdW5kIG5ld2x5IHNwZWN0YXRlZCBzcGVjaWVzIGlzIGEgcmFuZG9tIHZhcmlhYmxlIM69OyBhbmQgaW5pdGlhbGx5IHRoZSBlbnZpcm9ubWVudGFsIHZhcmlhYmxlIGFuZCB0aGUgc3BlY2llcyBlbnZpcm9ubWVudGFsIG5lZWRzIHZhcmlhYmxlIGFyZSByYW5kb21seSBjaG9zZW47IGFuZCAoZSkgU3BlY2llcyBlbGltaW5hdGVkIGluIGEgY2F0YXN0cm9waGUgYXJlIHJhbmRvbWx5IGNob3Nlbi4gCgotICoqVmFyaWFibGVzIG9mIEludGVyZXN0Kio6IFR1cm5vdmVyIHJhdGU6IFRoZSB0dXJub3ZlciByYXRlIGlzIHRoZSBudW1iZXIgb2YgbmV3IHNwZWNpZXMgY3JlYXRlZCBhdCBlYWNoIHRpbWUgc3RlcC4gVGhlIHdheSB0aGUgbW9kZWwgaXMgZm9ybXVsYXRpb24gbmV3IHNwZWNpZXMgYXJpc2Ugd2hlbiB0aGVyZSBpcyBhbiBvcGVuaW5nIGluIHJlbGF0aW9uIHRvIHRoZSBwYWNrZWQgbmljaGUuIFRoaXMgaGFwcGVucyBpbiBjb21wZXRpdGlvbiBiZXR3ZWVuIHRoZSBsaW5rZWQgYW5kIHVubGlua2VkIHNwZWNpZXMsIGluIHNlbGVjdGlvbiBldmVudHMgaW4gd2hpY2ggdGhlIGxlYXN0IGZpdCBzcGVjaWVzIGlzIHNlbGVjdGVkIGZvciBlbGltaW5hdGlvbiwgYW5kIGluIHBlcnR1cmJhdGlvbiBldmVudHMuIAoKIyMgSW5pdGlhbGl6YXRpb24KCkluaXRpYWxpemF0aW9uIGNvbnNpc3RzIG9mIGEgcmFuZG9tIGxhbmRzY2FwZSBiZWluZyBwcm9kdWNlZCB1c2luZyB0d28gdmFyaWFibGVzIHRoYXQgY29udHJvbCB0aGUgbnVtYmVyIG9mIHBhdGNoZXMgc2VsZWN0ZWQgYW5kIHRoZSBkaXN0cmlidXRpb24gb2YgcGF0Y2hlcy4gRmlndXJlIHh4IGdpdmVzIGFuIGV4YW1wbGUgb2Ygb25lIG9mIHRoZSBsYW5kc2NhcGVzIHByb2R1Y2VkLiBUaGlzIHByb2NlZHVyZSBpcyBiYXNlZCB1cG9uIHh4eHguCgojIyBUZXN0aW5nCgpUaGUgbW9kZWwgQmVoYXZpb3IgU3BhY2UgaW4gTmV0TG9nbyB3YXMgdXNlZCB0byB0ZXN0IHRoZSBvdmVyYWxsIGJlaGF2aW9yIG9mIHRoZSBtb2RlbC4gIEEgY29tcGxldGUgaXRlcmF0aW9uIHNldCBvZiB0aGUgYmluYXJ5IHN3aXRjaGVzIHR1cm5pbmcgb24gYW5kIG9mZiB0aGUgY29uc3RyYWludCBzdWJtb2RlbHMgYW5kIGZvciB0aHJlZSB2YWx1ZXMgb2YgdGhlIHBvc3NpYmxlIG51bWJlciBvZiBsaW5rcyBwZXIgc3BlY2llcyBhbmQgdHdvIHZhbHVlcyBvZiBkaWZmZXJlbnQgbGFuZHNjYXBlIHR5cGVzIGxlYWRpbmcgdG8gMTQ0IHBvc3NpYmxlIGNvbWJpbmF0aW9ucyB3aGljaCBjb21wcm9taXNlIHRoZSBwZXJtdXRhdGlvbiBzZXQgdXNlZCB0byBleHBsb3JlIHRoZSBjb25zdHJhaW50IHNwYWNlLCB3aXRoIFQ9NTAwIHRpbWVzdGVwcyBmb3IgZWFjaCBzYW1wbGUgZnJvbSB0aGUgbW9kZWwgaHlwZXJzcGFjZS4gQSB1bmlmb3JtIHJhbmRvbSBkaXN0cmlidXRpb24gb2YgdGhlIHZhcmlhYmxlcyBwcm9wZm9ybSwgdmFyZml0bmVzcywgZnJxbW9kLCBhbmQgcGVyd2lwZSwgd2VyZSBkcmF3biBmcm9tIHRoZSAxNTAgaXRlcmF0aW9ucyBvZiBlYWNoIG9mIHRoZSBwb3NzaWJsZSBjb25zdHJhaW50IHBlcm11dGF0aW9uIHNldCBmb3IgZWFjaCBvZiB0aGUgVGhlc2Ugd2VyZSB0YWtlbiB3aXRoIHJlcGxhY2VtZW50IG92ZXIgdGhlIG11bHRpZGltZW5zaW9uYWwgcGFyYW1ldGVyIHNwYWNlLiAgTWl4ZWQgbW9kZWwgYW5hbHlzZXMgKGRldGFpbHMgYXJlIGZvdW5kIGluICBTdXBwbGVtZW50YWwgTWF0ZXJpYWxzICkgd2VyZSB1c2VkIHRvIGV4cGxvcmUgdGhlIGluZmx1ZW5jZSBvZiBlYWNoIG9mIHRoZSBwYXJhbWV0ZXJzIHRob3VnaHQgdG8gYmUgb2YgaW50ZXJlc3QuIFRoZSByZXN1bHRzIG9mIHRoZXNlIGFuYWx5c2VzIG5lZWQgYSBjYXV0aW9uYXJ5IHdhcm5pbmcuIEFzIFdoaXRlIGV0IGFsLiAoMjAxNCkge1doaXRlLCAyMDE0ICM1OH0gbm90ZSwgdGhlc2UgcmVzdWx0cyBzaG91bGQgbm90IGJlIGludGVycHJldGVkIGFzIGEgdGVzdCBvZiBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgZWFjaCBvZiB0aGUgcGFyYW1ldGVyIHNldCBhcyB0aGUgbGlrZWxpaG9vZCB2YWx1ZXMgYW5kIHN0YXRpc3RpY2FsIHRlc3RzIGFyZSBlYXNpbHkgaW5mbHVlbmNlZCBieSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgdXNlZCBpbiB0aGUgbW9kZWwgdGVzdGluZy4gVGhlcmVmb3JlIHRoZXkgd2VyZSB1c2VkIGFzIGEgaGV1cmlzdGljIHRvIGNob3NlIHRoZSBzZXQgb2YgcGFyYW1ldGVycyB0aGF0IG1pZ2h0IGJlIGF2ZXJhZ2VkIG9yIHJlcHJlc2VudGF0aXZlIHZhbHVlcyBjaG9zZW4gdGhhdCBkbyBub3QgaW5mbHVlbmNlIGhvdyB0aGUgY29uc3RyYWludHMgaW5mb3JtIHRoZSByZXN1bHRzIG9mIHRoZSBtb2RlbC4KCkluIGFsbCBvZiB0aGUgbW9kZWwgc2VsZWN0aW9uIGFuYWx5c2VzLCB0aGUgY29uc3RyYWludCB2YXJpYWJsZXMgd2VyZSByZXRhaW5lZCBpbiBwYXJhbWV0ZXJzIHJlbGF0ZWQgdG8gZml0bmVzcyBhbmQgYXMgZXhwZWN0ZWQuIEZvciBkZXBlbmRlbnQgdmFyaWFibGVzIGludm9sdmluZyBmaXRuZXNzIHRoZSBmdWxsIG1vZGVsIHdhcyB1c3VhbGx5IG5lZWRlZCB0byBleHBsYWluIHRoZSB2YXJpYXRpb24uIEV4Y2VwdGlvbnMgaW5jbHVkZSBmb3Igd2l0aGluIGNsdXN0ZXIgbWVhc3VyZXMgb2YgZml0bmVzcy4gVGhlIHZhcmlhdGlvbiBpbiB0dXJub3ZlciByYXRlcyB3ZXJlIGV4cGxhaW5lZCBieSB0aGUgZnVsbCBzZXQgb2YgY29uc3RyYWludHMgYW5kIGJ5IHRoZSBmcmVxdWVuY3kgb2YgcGVydHVyYmF0aW9uIGFuZCB0aGUgaW50ZW5zaXR5IG9mIHRoZSBwZXJ0dXJiYXRpb24uICBUaGlzIHByb3ZpZGVzIGV2aWRlbmNlIHRoYXQgdGhlIG1vZGVs4oCZcyB2YXJpYWJsZSBhbmQgcGFyYW1ldGVyIHNldCBhcmUgYWRlcXVhdGUuIAoKIyMgRmxvdwoKIVtTaW11bGF0aW9uIGZsb3ddKGltZy9GbG93LnBuZykKCgojIFZhcmlhYmxlcyBhbmQgdGhlaXIgcm9sZXMKCiMjIEdsb2JhbCB2YXJpYWJsZXMgKGluZGVwZW5kZW50OyBmaXhlZCkKCi0gKipgbWF4dGlja3NgKio6IE51bWJlciBvZiB0aW1lIHN0ZXBzIHRvIHJ1biBtb2RlbCAodGltZSBzdGVwIGlzIGF2ZXJhZ2Ugc3BlY2llcyB0aW1lIGluIHBhdGNoIHVudGlsIGV4dGluY3Rpb24tLUdsb2JhbCB1c2VkIHRocm91Z2hvdXQpCi0gKipgTWF4c3B0b3RgKio6IFRoZSBtYXhpbXVtIG51bWJlciBvZiBzcGVjaWVzIGluIHBsb3QtLVVzZWQgYnkgc2V0IHVwLgotICoqYGNyZWF0ZV9uZXR3b3JreW4/YCoqOiBiaW5hcnkgZGV0ZXJtaW5lcyBpZiBhIG11dHVhbGlzdGljIG5ldHdvcmsgaXMgY3JlYXRlZC4gKipDT05TVFJBSU5UKioKLSAqKmBzZWxlY3R5bj9gKio6IGJpbmFyeSwgZGV0ZXJtaW5lcyBpZiBzZWxlY3Rpb24gaXMgaW5jbHVkZWQgaW4gdGhlIHJ1bnMgKipDT05TVFJBSU5UKioKLSAqKmBkaXNwZXJzZXluP2AqKjogYmluYXJ5LCBkZXRlcm1pbmVzIGlmIGRpc3BlcnNhbCBpcyB1c2VkIGluIHRoZSBtb2RlbCAqKkNPTlNUUkFJTlQqKgotICoqYGNvbXBldGV5bj9gKio6IGJpbmFyeSwgZGV0ZXJtaW5lcyBpZiBjb21wZXRpdGlvbiBiZXR3ZWVuIG5ldHdvcmtlZCBhbmQgbm9uLW5ldHdvcmtlZCBzcGVjaWVzIGFyZSB1c2VkIGluIHRoZSBtb2RlbC4gKipDT05TVFJBSU5UKioKLSAqKmBzZWxlY3Rmb3J5bj9gKio6IGJpbmFyeSwgZGV0ZXJtaW5lcyBpZiBtb3N0IGZpdCBzcGVjaWVzIGFyZSBtb3ZlZCBpbnRvIHBhdGNoIGlmIHRoZWlyIGlzIGFuZCB1bm9jY3VwaWVkIG5pY2hlIGluIHRoZSBwYXRjaCAqKkNPTlNUUkFJTlQqKgotICoqYGNhdGFzdHJvcGhleW4/YCoqOiBiaW5hcnksIGRldGVybWluZXMgaWYgY2F0YXN0cm9waGVzIGFyZSBpbmNsdWRlZCBpbiB0aGUgbW9kZWwgKipDT05TVFJBSU5UKioKLSAqKmBudW1saW5rYCoqOiBudW1iZXIgb2YgbGlua3MgZWFjaCBzcGVjaWVzIGNhbiBmb3JtIHdpdGggb3RoZXIgc3BlY2llcwotICoqYG1heF9pbnRpYWxfcHJvcG9ydGlvbl9saW5rc2AqKjogcHJvcG9ydGlvbiBvZiBtYXhpbXVtIG51bWJlciBvZiBsaW5rcyBpbiBpbml0aWFsIGVzdGFibGlzaG1lbnQgb2YgbGlua3MgCi0gKipgY2RpczFgKio6IHVzZWQgaW4gY2x1c3RlcmluZyBhbGdvcml0aG0gdG8gaW5mbHVlbmNlIGRpc3RyaWJ1dGlvbiBvZiBwYXRjaGVzIGFuZCBjbHVzdGVycwotICoqYGNkaXMyYCoqOiB1c2VkIGluIGNsdXN0ZXJpbmcgYWxnb3JpdGhtIHRvIGluZmx1ZW5jZSBkaXN0cmlidXRpb24gb2YgcGF0Y2hlcyBhbmQgY2x1c3RlcnMKLSAqKmBmcnFtb2RgKio6IGZyZXF1ZW5jeSBvZiBjYXRhc3Ryb3BoZXMgCi0gKipgcGVyY2VudF9zcGVjaWVzX3RvX3dpcGVvdXRgKio6IHBlcmNlbnQgb2Ygc3BlY2llcyB3aXBlZCBvdXQgaW4gY2F0YXN0cm9waGVzIAotICoqYHZhcl9maXRuZXNzYCoqOiB2YXJpYXRpb24gaW4gb2Zmc3ByaW5nJ3MgaW5oZXJpdGFuY2Ugb2YgZml0bmVzcyB2YWx1ZSBmcm9tIHBhcmVudHMgKHVzZWQgaW4gcHJvY2VkdXJlLXNwZWNpYXRpb24pLiAKLSAqKmBwcGAqKjogcGFyYW1ldGVyIGluIGVzdGFibGlzaGluZyBjbHVzdGVycyB0aGF0IGdpdmUgc29tZSBwcm9wb3J0aW9uIG9mIGdvb2QgaGFiaXRhdCBzZXQgdG8gLjI1IG5vdwoKIyMgUGF0Y2ggdmFyaWFibGVzIChpbmRlcGVuZGVudDsgZml4ZWQpCgotICoqYGVudmlyYCoqOiB0aGUgZW52aXJvbm1lbnQgb2YgdGhlIHBhdGNoCi0gKipgY2x1c3RlcmAqKjogY2x1c3RlciBpcyBwYXRjaCB3aGljaCBkZWZpbmVzIGNsdXN0ZXIKLSAqKmBiYWRfY2x1c3RlcmAqKjogdXNlZCBpbiBjbHVzdGVyIGZvcm1hdGlvbgotICoqYGNsdXN0ZXJudW1gKio6IG51bWVyaWNhbCBkZXNpZ25hdGlvbiBmb3IgY2x1c3RlcgotICoqYGJhZF9jbHVzdGVybnVtYCoqOiB1c2VkIGluIGNsdXN0ZXIgZm9ybWF0aW9uCi0gKipgcGluY2x1c2AqKjogbnVtYmVyIG9mIHBhdGNoZXMgaW4geW91ciBjbHVzdGVybWF4dG90c3AKLSAqKmBwcm9wbWF4cmF0YCoqOiByZWxhdGl2ZSBzaXplIG9mIGNsdXN0ZXIgY29tcGFyZWQgdG8gbGFyZ2VzdCBjbHVzdGVyCgojIyBQYXRjaCB2YXJpYWJsZXMgKGRlcGVuZGVudCkKCi0gKipgbnVtX3NwZWNpZXNfaGVyZWAqKjogbnVtYmVyIG9mIHNwZWNpZXMgaGVyZQotICoqYG51bV9zcGVpY2VzX2xpbmtlZF9oZXJlYCoqOiBudW1iZXIgb2YgbGlua2VkIHNwZWNpZXMKLSAqKmBtYXhfbnVtX3NwZWNpZXNgKio6IG1heG51bSBvZiBzcGVjaWVzIGhlcmUKLSAqKmBudW1kaWVVYCoqOiBudW1iZXIgb2YgdW5saW5rZWQgc3BlY2llcyBpbiBwYXRjaCB0aGF0IGhhdmUgZGllZAotICoqYG51bWRpZUxgKio6IG51bWJlciBvZiB1bmxpbmtlZCBzcGVjaWVzIGluIHBhdGNoIHRoYXQgaGF2ZSBkaWVkCi0gKipgbnVtZGllUmAqKjogbnVtYmVyIG9mIHNwZWNpZXMga2lsbGVkIGluIGNhdGFzdHJvcGhlCi0gKipgdHVybm92ZXJyYXRlYCoqOiB0dXJub3ZlciByYXRlIGluIHBhdGNoCi0gKipgdHVybm92ZXJyYXRlTGAqKjogdHVybm92ZXIgcmF0ZSBvZiBsaW5rZWQgc3BlY2llcyBpbiBwYXRjaAotICoqYHR1cm5vdmVycmF0ZVVgKio6IHR1cm5vdmVyIHJhdGUgb2YgdW5saW5rZWQgc3BlY2llcyBpbiBwYXRjaAotICoqYGxhZ3NwZWNpZXNgKio6IGFnZW50c2V0IHdpdGggc3BlY2llcyBoZXJlIGxhc3QgdGltZQotICoqYGxhZ3NwZWNpZXNMYCoqOiBhZ2VudHNldCB3aXRoIHNwZWNpZXMgaGVyZSBsYXN0IHRpbWUKLSAqKmBsYWdzcGVjaWVzVWAqKjogYWdlbnRzZXQgd2l0aCBzcGVjaWVzIGhlcmUgbGFzdCB0aW1lCgojIyBTcGVjaWVzIHZhcmlhYmxlcyAoaW5kZXBlbmRlbnQpCgotICoqYHNwX251bWAqKjogc3BlY2llcyBudW1iZXIKLSAqKmBtYXhfbGlua3NfSV9jYW5faGF2ZWAqKjogaW5kaXZpZHVhbCBudW1iZXIgb2YgbGlua3MgYSBzcGVjaWVzIGNhbiBmb3JtCi0gKipgbnVtX215X2xpbmtzYCoqOiBudW1iZXIgb2YgbGlua3MgSSBoYXZlCi0gKipgaW52X2ZpdG5lc3NgKio6IHByb2JhYmlsaXR5IG9mIGV4dGluY3Rpb24KLSAqKmBlbnZpcl9uZWVkYCoqOiBlbnZpcm9ubWVudCBwcmVmZXJyZWQKCiMjIFJlcG9ydGVycyAocG9zc2libGUgZGVwZW5kZW50IHZhcmlhYmxlcykKCi0gKipgcGF0Y2guaGFiaXRhdC5wZXJjZW50YCoqOiAgIDogVGhlIHBlcmNlbnQgb2YgZ29vZCBwYXRjaGVzIG91dCBvZiB0b3RhbCBudW1iZXIgb2YgcGF0Y2hlcwotICoqYHBhdGNoLmhhYml0YXQuY291bnRgKio6ICAgIDogVGhlIHRvdGFsIG51bWJlciBvZiBoYWJpdGF0IHBhdGNoZXMKLSAqKmBzcGVjaWVzLm51bWJlci50dXJub3ZlcmAqKjogIDogVGhpcyBpcyBhIHN1cnJvZ2F0ZSBmb3IgdHVybm92ZXItLVdoeT8gQmVjYXVzZSBhdCBuZXcgc3BlY2llcyBhcmUgYXNzaWduZWQgYXQgbmV3IHNwZWNpZXMgbnVtYmVyIGJhc2VkIG9uICsxIHRoYXQgbGFzdCBzcGVjaWVzLiBUaGUgc3VtIG9mIGFsbCBzcGVjaWVzIGRpdmlkZWQgYnkgdGhlIG51bWJlciBvZiBzcGVjaWVzIGdpdmVzIGEgbWVhc3VyZSBvZiBob3cgbWFueSBuZXcgc3BlY2llcyB0aGVyZSBhcmUuCi0gKipgc3BlY2llcy5udW1iZXIudHVybm92ZXIuZGlmZmVyZW5jZWAqKjogIDogR2l2ZXMgdGhlIHN1bSBvZiBzcGVjaWVzIG51bWJlcnMgbWludXMgdGhlIGxhc3QgdGltZSwgb3IgYmFzaWNhbGx5IHRoZSBjaGFuZ2UgaW4gc3BlY2llcyBudW1iZXIgZm9yIGVhY2ggdGltZSBzdGVwCi0gKipgc3BlY2llcy5udW1iZXIuc3RkaXZgKio6ICA6IGdpdmVzIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIHNwZWNpZXMsIGkuZSwgaG93IG11Y2ggdmFyaWF0aW9uIHRoZXJlIGlzIGluIHNwZWNpZXMgbnVtYmVycy0tIExvdyBtZWFucyB0aGF0IGFsbCBwYXRjaGVzIGFyZSB0dXJuaW5nIG92ZXIgc3BlY2llcyBhdCBhIHNpbWlsYXIgcmF0ZSAtLSBoaWdoIG1lYW5zIHBhdGNoZXMgdHVybm92ZXIgcmF0ZSBpcyBtb3JlIHZhcmlhYmxlLgotICoqYHBhdGNoZXMuc3BlY2llcy53aXRobGlua3MuY291bnRgKio6ICA6IFRoZSBudW1iZXIgb2YgcGF0Y2hlcyB3aXRoIGFueSBsaW5rcwotICoqYGxhbmRzY2FwZS5maXRuZXNzLm1lYW5gKio6ICA6IFRoZSBnbG9iYWwgZml0bmVzcyBhY3Jvc3MgYWxsIHBhdGNoZXMKLSAqKmBsYW5kc2NhcGUuZml0bmVzcy52YXJgKio6ICA6IHZhcmlhbmNlIGluIGdsb2JhbCBmaXRuZXNzCi0gKipgY2x1c3Rlci5maXRuZXNzLm1lYW5gKio6ICA6IHRoZSBhZHZlcmFnZSBtZWFuIGN1bHN0ZXIgZml0bmVzcyBhdmVyYWdlZCBhY3Jvc3MgcmVnaW9uCi0gKipgY2x1c3Rlci5maXRuZXNzLnZhcmAqKjogdGhlIHZhcmlhbmNlIGFtb25nIG1lYW4gY2x1c3RlciBmaXRuZXNzIGFjcm9zcyB0aGUgcmVnaW9uCi0gKipgY2x1c3Rlci5saW5rZWQudmFyYCoqOiB2YXJhbmNlIGluIG51bWJlciBvZiBsaW5rZWQgc3BlY2llcyBhbW9uZyBjbHVzdGVycwotICoqYGNsdXN0ZXIudW5saW5rZWQudmFyYCoqOiB2YXJhbmNlIGluIG51bWJlciBvZiB1bmxpbmtlZCBzcGVjaWVzIGFtb25nIGNsdXN0ZXJzCi0gKipgY2x1c3Rlci5saW5rZWRfdW5saW5rZWQudmFyLmRpZmZlcmVuY2VgKio6IERpZmZlcmVuY2UgaW4gdmFyaW5jZSBiZXR3ZWVuIHVubGlua2VkIGFuZCBsaW5rZWQgc3BlY2llcwotICoqYGxhbmRzY2FwZS5maXRuZXNzLmxpbmtlZF91bmxpbmtlZC5kaWZmZXJlbmNlYCoqOiBUaGUgZGlmZmVyZW5jZSBpbiBnbG9iYWwgZml0bmVzcyBiZXR3ZWVuIGxpbmtlZCBhbmQgdW5saW5rZWQgc3BlY2llcwotICoqYGNsdXN0ZXIuZml0bmVzcy5saW5rZWRfdW5saW5rZWQuZGlmZmVyZW5jZWAqKjogVGhlIGRpZmZlcmVuY2UgaW4gbWVhbiBjbHVzdGVyIGZpdG5lc3MgYmV0d2VlbiBsaW5rZWQgYW5kIHVubGlua2VkIHNwZWNpZXMgOiBUaGUgY2x1c3RlciBtZWFuIG9mIHNwZWNpZXMgbnVtYmVyIG9mIGxpbmtlZCBzcGVjaWVzCi0gKipgY2x1c3Rlci5saW5rZWRfc3BlY2llcy5udW1iZXIubWVhbmAqKjogVGhlIGNsdXN0ZXIgbWVhbiBvZiBzcGVjaWVzIG51bWJlciBvZiBsaW5rZWQgc3BlY2llcwotICoqYGNsdXN0ZXIudW5saW5rZWRfc3BlY2llcy5udW1iZXIubWVhbmAqKjogQ2x1c3RlciBtZWFuIG9mIHNwZWNpZXMgbnVtYmVyIGluIHVubGlua2VkIHNwZWNpZXMKLSAqKmBjbHVzdGVyLmxpbmtlZF91bmxpbmtlZF9zcGVjaWVzLm51bWJlci5tZWFuLmRpZmZlcmVuY2VgKio6IE1lYW4gc3BlY2llcyBudW1iZXIgZGlmZmVyZW5jZSBiZXR3ZWVuIGxpbmtlZCBhbmQgdW5saW5rZWQgc3BlY2llcyAKLSAqKmBjbHVzdGVyLnBhdGNoZXMubGlua3MubWVhbmAqKjogY291bnQgbWVhbiBudW1iZXIgb2YgcGF0Y2hlcyB3aXRoIGxpbmtzIGF2ZXJhZ2VkIGFjcm9zcyBjbHVzdGVycwotICoqYGNsdXN0ZXIucGF0Y2hlcy51bmxpbmtzLm1lYW5gKio6IGNvdW50IG1lYW4gbnVtYmVyIG9mIHBhdGNoZXMgd2l0aG91dCBsaW5rcyBhdmVyYWdlZCBhY3Jvc3MgY2x1c3RlcnMKLSAqKmBsYW5kc2NhcGUuc3BlY2llcy5udW1iZXIudmFyYCoqOiBUaGUgdmFyaWFuY2Ugb2Ygc3BlY2llcyBudW1iZXIgb3ZlciBhbGwgc3BlY2llcyBpbiBsYW5kc2NhcGUKLSAqKmBsYW5kc2NhcGUuY29udGFnaW9uYCoqOiBDb250YWdlbiBpbmRleCBmcm9tIGVxdWF0aW9uICMyMiBMYW5kc2NhcGUgRWNvbG9neSB2b2wuIDggbm8uIDMgcHAgMTU1LTE2MiAoMTk5MykgJ0EgbmV3IGNvbnRhZ2lvbiBpbmRleCB0byBxdWFudGlmeSBzcGF0aWFsIHBhdHRlcm5zIG9mIGxhbmRzY2FwZXMnIGJ5IEhhYmluIExpIGFuZCBKYW1lcyBGLiBSZXlub2xkcwotICoqYG1vZGVsLnN0b3AucmVhc29uYCoqOiBIb3cgdGhlIG1vZGVsIGVuZGVkIGVuZGxpY2ggPSAxID0+IG1vZGVsIHJlYWNoZWQgZW5kIG9mIG1heCBydW5zOyBlbmRsaWNoID0gMiA9PiBhbGwgc3BlaWVjZXMgd2VudCBleHRpbmN0OyBlbmRsaWNoID0gMyA9PiBsaW5rcyBnbyB0byB6ZXJvIGZvciB0aGlydHkgdGlja3M7IGVuZGxpY2ggPSA0ID0+IGFsbCBwYWNoZXMgaGF2ZSBsaW5rcy4KLSAqKmBsYW5kc2NhcGUubGlua2VkLmFjdHVhbF9wb3NzaWJsZWAqKjogVGhlIHByb3BvcnRpb24gb2YgbGlua2VkIHNwZWNpZXMgb3V0IG9mIHRvdGFsIG51bWJlciBvZiBwb3NzaWJsZSBsaW5rZWQgc3BlY2llcyBpZiBhbGwgbGlua2FibGUgc3BlY2llcyB3ZXJlIGxpbmtlZAotICoqYGNsdXN0ZXIuY291bnRgKio6IFRoZSBudW1iZXIgb2YgY2x1c3RlcnMKLSAqKmBjbHVzdGVyLnNpemUubWVhbmAqKjogbWVhbiBjbHVzdGVyIHNpemUgCi0gKipgY2x1c3Rlci5saW5rZWRfc3BlY2llcy5kZWF0aHMubWVhbmAqKjogVGhlIGNsdXN0ZXIgbWVhbiBvZiB0aGUgbnVtYmVyIG9mIGRlYWQgc3BlY2llcyBpbiBsaW5rZWQgc3BlY2llcy4KLSAqKmBjbHVzdGVyLnVubGlua2VkX3NwZWNpZXMuZGVhdGhzLm1lYW5gKio6IFRoZSBjbHVzdGVyIG1lYW4gb2YgdGhlIG51bWJlciBvZiBkZWFkIHNwZWNpZXMgaW4gdW5saW5rZWQgc3BlY2llcy4KLSAqKmBjbHVzdGVyLmxpbmtlZF9zcGVjaWVzLnJhbmRvbV9kZWF0aHMubWVhbmAqKjogVGhlIGNsdXN0ZXIgbWVhbiBvZiB0aGUgbnVtYmVyIG9mIHNwZWNpZXMga2lsbGVkIHJhbmRvbWx5ICh0aG9zZSBraWxsZWQgaW4gYSBjYXRhc3Ryb3BoZSkKLSAqKmBsYW5kc2NhcGUubGlua2VkX3NwZWNpZXMuZGVhdGhzLm1lYW5gKio6IFRoZSBudW1iZXIgb2YgbGlua2VkIHNwZWNpZXMgZGVhdGhzIGluIGVudGlyZSBsYW5kc2NhcGUgCi0gKipgbGFuZHNjYXBlLnVubGlua2VkX3NwZWNpZXMuZGVhdGhzLm1lYW5gKio6IFRoZSBudW1iZXIgb2YgdW5saW5rZWQgc3BlY2llcyBkZWF0aHMgaW4gZW50aXJlIGxhbmRzY2FwZSAKLSAqKmBsYW5kc2NhcGUuc3BlY2llcy5yYW5kb21fZGVhdGhzYCoqOiBudW1iZXIgb2Ygc3BlY2llcyBraWxsZWQgcmFuZG9tbHkgaW4gbGFuZHNjYXBlCi0gKipgbGFuZHNjYXBlLnNwZWNpZXMubnVtYmVyX3Blcl9wYXRjaC5tZWFuYCoqOiBudW1iZXIgb2Ygc3BlY2llcyBwZXIgcGF0Y2ggaW4gbGFuZHNjYXBlCi0gKipgbGFuZHNjYXBlLmxpbmtlZF9zcGVjaWVzLm51bWJlcl9wZXJfcGF0Y2gubWVhbmAqKjogbnVtYmVyIG9mIGxpbmtlZCBzcGVjaWVzIHBlciBwYXRjaCBpbiBsYW5kc2NhcGUKLSAqKmBjbHVzdGVyLmxpbmtlZF9zcGVjaWVzLmZpdG5lc3MubWVhbmAqKjogVGhlIGNsdXN0ZXIgbWVhbiBvZiBzcGVjaWVzIGZpdG5lc3Mgb2YgbGlua2VkIHNwZWNpZXMKLSAqKmBjbHVzdGVyLnVubGlua2VkX3NwZWNpZXMuZml0bmVzcy5tZWFuYCoqOiBUaGUgY2x1c3RlciBtZWFuIG9mIHNwZWNpZXMgZml0bmVzcyBvZiB1bmxpbmtlZCBzcGVjaWVzCi0gKipgY2x1c3Rlci5saW5rZWRfc3BlY2llcy5maXRuZXNzLnZhcmAqKjogTWVhbiB2YXJpYW5jZSBpbiBudW1iZXIgb2YgbGlua2VkIHNwZWNpZXMgcGVyIGNsdXN0ZXIgCi0gKipgY2x1c3Rlci51bmxpbmtlZF9zcGVjaWVzLmZpdG5lc3MudmFyYCoqOiBNZWFuIHZhcmlhbmNlIGluIG51bWJlciBvZiB1bmxpbmtlZCBzcGVjaWVzIHBlciBjbHVzdGVyCi0gKipgbGFuZHNjYXBlLnR1cm5vdmVyLnNsb3BlLnJ1bjFgKio6IGNhbGN1bGF0ZXMgdGhlIHNsb3BlIG9mIHRoZSBsaW5lIHRoYXQgcnVucyB0aHJvdWdoIHR1cm5vdmVyIHJhdGUgYmV0d2VlbiBgdHVybm92ZXJfaW50ZXJ2YWwxYCBhbmQgYHR1cm5vdmVyX2ludGVydmFsMmAgbmVhciBiZWdpbm5pbmcgb2YgcnVucwotICoqYGxhbmRzY2FwZS50dXJub3Zlci5zbG9wZS5ydW4yYCoqOiBjYWxjdWxhdGVzIHRoZSBzbG9wZSBvZiB0aGUgbGluZSB0aGF0IHJ1bnMgdGhyb3VnaCB0aGUgdHVybm92ZXIgcmF0ZSBhdCBlbmQgb2YgcnVucwotICoqYGxhbmRzY2FwZS50dXJub3Zlci5ZSW50ZXIucnVuMWAqKjogQ2FsY3VsYXRlcyB5IGludGVyY2VwdCBvZiBsaW5lIHRoYXQgcnVucyB0aHJvdWdoIHR1cm5vdmVyIHJhdGUgYmV0d2VlbiBgdHVybm92ZXJfaW50ZXJ2YWwxYCBhbmQgYHR1cm5vdmVyX2ludGVydmFsMmAgbmVhciBiZWdpbmluZyBvZiBydW5zCi0gKipgbGFuZHNjYXBlLnR1cm5vdmVyLllJbnRlci5ydW4yYCoqOiBDYWxjdWxhdGVzIHkgaW50ZXJjZXB0IG9mIGxpbmUgdGhhdCBydW5zIHRocm91Z2ggdHVybm92ZXIgcmF0ZSBuZWFyIGVuZCBvZiBydW5zCi0gKipgbGFuZHNjYXBlLnR1cm5vdmVyLlJzcXVhcmUucnVuMWAqKjogQ2FsY3VsYXRlcyBSLXNxdWFyZSBvZiBvZiBsaW5lIHRoYXQgcnVucyB0aHJvdWdoIHR1cm5vdmVyIHJhdGUgYmV0d2VlbiBgdHVybm92ZXJfaW50ZXJ2YWwxYCBhbmQgYHR1cm5vdmVyX2ludGVydmFsMmAgbmVhciBiZWdpbmluZyBvZiBydW5zCi0gKipgbGFuZHNjYXBlLnR1cm5vdmVyLlJzcXVhcmUucnVuMmAqKjogQ2FsY3VsYXRlcyBSLXNxdWFyZSBsaW5lIHRoYXQgcnVucyB0aHJvdWdoIHR1cm5vdmVyIHJhdGUgbmVhciBlbmQgb2YgcnVucyAKLSAqKmBsYW5kc2NhcGUudHVybm92ZXJMLnNsb3BlLnJ1bjFgKio6IGNhbGN1bGF0ZXMgdGhlIHNsb3BlIG9mIHRoZSBsaW5lIHRoYXQgcnVucyB0aHJvdWdoIHR1cm5vdmVyIHJhdGUgYmV0d2VlbiBgdHVybm92ZXJfaW50ZXJ2YWwxYCBhbmQgYHR1cm5vdmVyX2ludGVydmFsMmAgbmVhciBiZWdpbmluZyBvZiBydW5zIG9mIGxpbmtlZCBzcGVjaWVzIAotICoqYGxhbmRzY2FwZS50dXJub3Zlckwuc2xvcGUucnVuMmAqKjogY2FjdWxhdGVzIHRoZSBzbG9wZSBvZnRoZSBsaW5lIHRoYXQgcnVucyB0aHJvdWdoIHRoZSB0dXJub3ZlciByYXRlIGF0IGVuZCBvZiBydW5zIG9mIGxpbmtlZCBzcGVjaWVzIAotICoqYGxhbmRzY2FwZS50dXJub3ZlckwuWUludGVyLnJ1bjFgKio6IENhbGN1bGF0ZXMgeSBpbnRlcmNlcHQgb2YgbGluZSB0aGF0IHJ1bnMgdGhyb3VnaCB0dXJub3ZlciByYXRlIGJldHdlZW4gYHR1cm5vdmVyX2ludGVydmFsMWAgYW5kIGB0dXJub3Zlcl9pbnRlcnZhbDJgIG5lYXIgYmVnaW5pbmcgb2YgcnVucyBvZiBsaW5rZWQgc3BlY2llcyAKLSAqKmBsYW5kc2NhcGUudHVybm92ZXJMLllJbnRlci5ydW4yYCoqOiBDYWxjdWxhdGVzIHkgaW50ZXJjZXB0IG9mIGxpbmUgdGhhdCBydW5zIHRocm91Z2ggdHVybm92ZXIgcmF0ZSBuZWFyIGVuZCBvZiBydW5zIG9mIGxpbmtlZCBzcGVjaWVzCi0gKipgbGFuZHNjYXBlLnR1cm5vdmVyTC5Sc3F1YXJlLnJ1bjFgKio6IENhY3VsYXRlcyBSLXNxYXVyZSBvZiBvZiBsaW5lIHRoYXQgcnVucyB0aHJvdWdoIHR1cm5vdmVyIHJhdGUgYmV0d2VlbiBgdHVybm92ZXJfaW50ZXJ2YWwxYCBhbmQgYHR1cm5vdmVyX2ludGVydmFsMmAgbmVhciBiZWdpbmluZyBvZiBydW5zIG9mIGxpbmtlZCBzcGVjaWVzIAotICoqYGxhbmRzY2FwZS50dXJub3ZlckwuUnNxdWFyZS5ydW4yYCoqOiBDYWxjdWxhdGVzIFItc3F1YXJlIGxpbmUgdGhhdCBydW5zIHRocm91Z2ggdHVybm92ZXIgcmF0ZSBuZWFyIGVuZCBvZiBydW5zIG9mIGxpbmtlZCBzcGVjaWVzCi0gKipgbGFuZHNjYXBlLnR1cm5vdmVyVS5zbG9wZS5ydW4xYCoqOiBjYWxjdWxhdGVzIHRoZSBzbG9wZSBvZiB0aGUgbGluZSB0aGF0IHJ1bnMgdGhyb3VnaCB0dXJub3ZlciByYXRlIGJldHdlZW4gYHR1cm5vdmVyX2ludGVydmFsMWAgYW5kIGB0dXJub3Zlcl9pbnRlcnZhbDJgIG5lYXIgYmVnaW5pbmcgb2YgcnVucyBvZiB1bmxpbmtlZCBzcGVjaWVzIAotICoqYGxhbmRzY2FwZS50dXJub3ZlclUuc2xvcGUucnVuMmAqKjogIGNhY3VsYXRlcyB0aGUgc2xvcGUgb2Z0aGUgbGluZSB0aGF0IHJ1bnMgdGhyb3VnaCB0aGUgdHVybm92ZXIgcmF0ZSBhdCBlbmQgb2YgcnVucyBvZiB1bmxpbmtlZCBzcGVjaWVzIAotICoqYGxhbmRzY2FwZS50dXJub3ZlclUuWUludGVyLnJ1bjFgKio6IENhbGN1bGF0ZXMgeSBpbnRlcmNlcHQgb2YgbGluZSB0aGF0IHJ1bnMgdGhyb3VnaCB0dXJub3ZlciByYXRlIGJldHdlZW4gYHR1cm5vdmVyX2ludGVydmFsMWAgYW5kIGB0dXJub3Zlcl9pbnRlcnZhbDJgIG5lYXIgYmVnaW5pbmcgb2YgcnVucyBvZiB1bmxpbmtlZCBzcGVjaWVzIAotICoqYGxhbmRzY2FwZS50dXJub3ZlclUuWUludGVyLnJ1bjJgKio6IGNhbGN1bGF0ZXMgeSBpbnRlcmNlcHQgb2YgbGluZSB0aGF0IHJ1bnMgdGhyb3VnaCB0dXJub3ZlciByYXRlIGJldHdlZW4gYHR1cm5vdmVyX2ludGVydmFsMWAgYW5kIGB0dXJub3Zlcl9pbnRlcnZhbDJgIG5lYXIgYmVnaW5pbmcgb2YgcnVucyBvZiB1bmxpbmtlZCBzcGVjaWVzIAotICoqYGxhbmRzY2FwZS50dXJub3ZlclUuUnNxdWFyZS5ydW4xYCoqOiBDYWN1bGF0ZXMgUi1zcWF1cmUgb2Ygb2YgbGluZSB0aGF0IHJ1bnMgdGhyb3VnaCB0dXJub3ZlciByYXRlIGJldHdlZW4gYHR1cm5vdmVyX2ludGVydmFsMWAgYW5kIGB0dXJub3Zlcl9pbnRlcnZhbDJgIG5lYXIgYmVnaW5pbmcgb2YgcnVucyBvZiB1bmxpbmtlZCBzcGVjaWVzIAotICoqYGxhbmRzY2FwZS50dXJub3ZlclUuUnNxdWFyZS5ydW4yYCoqOiBDYWxjdWxhdGVzIFItc3F1YXJlIGxpbmUgdGhhdCBydW5zIHRocm91Z2ggdHVybm92ZXIgcmF0ZSBuZWFyIGVuZCBvZiBydW5zIG9mIHVubGlua2VkIHNwZWNpZXMKLSAqKmBsYW5kc2NhcGUubGlua2VkX3NwZWNpZXMubWVhbi50dXJub3ZlcmAqKjogVGhlIGdsb2JhbCB0dXJub3ZlciBvZiBsaW5rZWQgc3BlY2llcyBhY3Jvc3MgYWxsIHBhdGNoZXMKLSAqKmBsYW5kc2NhcGUudW5saW5rZWRfc3BlY2llcy5tZWFuLnR1cm5vdmVyYCoqOiBUaGUgZ2xvYmFsIHR1cm5vdmVyIG9mIHVubGlua2VkIHNwZWNpZXMgYWNyb3NzIGFsbCBwYXRjaGVzCi0gKipgbGFuZHNjYXBlLnNwZWNpZXMubWVhbi50dXJub3ZlcmAqKjogVGhlIGdsb2JhbCB0dXJub3ZlciBvZiBzcGVjaWVzIGFjcm9zcyBhbGwgcGF0Y2hlcwotICoqYGNvdW50X2xpbmtzYCoqOiBUb3RhbCBudW1iZXIgb2YgbGlua3MKLSAqKmBjb3VudF9zcGVjaWVzYCoqOiBUb3RhbCBudW1iZXIgb2Ygc3BlY2llcwo=