Analysis of next-generation sequencing data using
Cytoscape
Date and Venue
- June 12th 2024 - University of Sheffield
- Bartolome House, Seminar Room EG03
Schedule (Provisonal)
Thursday 12th June, 2024
- 09:30 - 11:00 Introduction to Cytoscape and it’s App
- 11:15 - 12:30 Functional Enrichment Analysis
- 12:30 - 13:15 LUNCH
- 13:15 - 15:00 Enrichment using ClueGO and CluePedia
- 15:00 - 16:30 Identifying signiifcant pathway modules and
differential expression genes
Materials
This course comprises of three sessions.
Course Overview
The workshop is designed to give you an introduction to using
Cytoscape, which is a network-based software application to perform
bioinformatics data and pathway enrichment analysis. The particular
use-case in this course is that of RNA-seq data, but many of the
concepts are used for other types of omics-analysis.
There are several reasons why we might want to use
Cytoscpae in Bioinformatics:-
- You can be a naive or non-programmer for analysing your biological
datasets generated by “high-throughput sequencing” through dedicated
Cytoscape packages.
- The packages/Apps within Cytoscape provide a user
complete support for different types of “-Omics” datasets.
- e.g. many NGS tools are developed for a Unix environment.
- Some tasks require more memory (RAM) and processor speed than we
have on our own machine
- Some analyses take too long, and whilst they are running everything
else on our machine will be slow.
- Eventually you will want to use “High-performance computing” (HPC) -
but this requires some background knowledge before you can use it.
- Hence, Cytoscape provides many advantages for those
users who wish to have their biological data analysed in a more
user-freindly manner but also visualizing results simultaneously.
Creating Network Graphs with Cytoscape
Cytoscape is a tool for viewing and analysing
networks (meaning, in this case, any group of entities that are
connected in some way). Cytoscape is not too hard to use, but it won’t
make much sense unless you have a sense of some basic network analysis
vocabulary and concepts. A glossary is made below for basic
understanding of introduction to network graphs.
Basic Terms
Biological network
A finite set (or sets) of features (a.k.a. biological entities, for
e.g. genes, mRNAs, miRNAs, proteins, peptides, metabolites, etc.) and
the relations (for e.g. co-expression) defined on them. It consists of
three elements: (1) a set of biological entities; (2) each bio-entity
has a set of individual attributes; and (3) a set of ties that defines
at least one relation among features.
Graph
A common way to visually represent biological networks, consisting of
two dimensions: bio-entity and relations (also called nodes and
edges).
Node
Nodes are the entities in graph (also called vectors). For example,
if we consider DNA-Damage Repair (DDR) pathways as a graph, then every
gene/pathway-term is a node.
Edge
These are the relationships between nodes. For example, if we
consider Extracellular-Matrix regulation as a graph then every
activation/inhibition of gene1-gene2 pair is an edge.

Types of Graphs
Undirected graph
When the relationship is always valid in both directions, then it is
called undirected graph. For e.g. If gene-1
TP53 is inhibiting gene-2 RB1 within a
cell-regulatory network, then RB1 is also activating TP53.
Directed graph
When the relationship may not be valid in both directions (connecting
nodes), then it is called a directed graph. If FGFR3 is
associated to ERBB2 within a chromosomal abberation event and ERBB2 is
not having any association to FGFR3, then relationship is directed.

Weighted network
A network in which the edges between nodes have weights
(corresponding to, e.g., the strength of a relationship) assigned to
them.
Unweighted network
A network in which the edges between nodes do not have weights
assigned to them.

Measures of Graphs or Nodes
Size
A measure of the number of genes (nodes) in a complete or sub-graphed
network.
Density
The number of ties in the network reported as a fraction of the total
possible number of ties.
Reciprocity
The proportion of mutual ties in a network.
Distance
The number of “steps” between any two genes (nodes) in a biological
network.
Clustering coefficient
A measure of a network’s genes’ tendency to “group together” into
pockets of dense connectivity.
* In the first image, the blue
node has a clustering coefficient of one, because all possible
connections among its neighboring nodes have been realized. In the
second image, only one of the possible connections has been realized —
so the blue node has a clustering coefficient of 1/3. In the third
image, none of the neighboring nodes are connected, so the blue node has
a clustering coefficient of 0.
Centrality
There are multiple ways to determine a node’s importance, or
centrality. The measure you use depends on how you define centrality.
Several of these measures are:
Degree centrality An important node is involved
in large number of interactions. The number of edges connected with
a particular node.
Eigenvector centrality or in biological terms **
“Hub-proteins”** An important node is connected to important
neighbors. This is a measure of influence of a given node in the
whole network. The notion is how well-connected a given node is with
other well connected nodes in the network.
Betweenness centrality An important node lies on
a high proportion of paths between other nodes in the network.
Closeness centrality An important node is
typically “close” to, and can communicate quickly with, the other nodes
in the network. Length of the average shortest path between a given
node and all other nodes in a graph.
Aims of the Course
These tutorials provide a basic introduction to using Cytoscape to
conduct network analysis of biological data. They’re intended to be used
with multi-omics data I collected about Urothelial Cancer of the
Bladder (UCB). However, anyone should be able to follow
along.
Here’s what’s included in the Sessions: • Creating a basic Cytoscape
network (that’s this tutorial) • Importing a node list
and working with node attributes • Selecting parts of your network •
Publishing your network diagram
Setting up your data
The most important thing to understand about Cytoscape (or, really,
most network analysis tools) is the format in which you need to
structure your data. At its most basic, Cytoscape wants a spreadsheet
containing two columns. The objects in the first column should be
connected in some way to the objects in the second column. This is
called an edge list. In the example below, my edge list
contains two kinds of things: geneA and geneB. The columns could be
reordered so that the geneB column precedes the geneA column; it doesn’t
matter. All that matters here is that each row in my spreadsheet
describes a connection between two entities.
Other kinds of relationships you could describe in an edge list:
- Gene A appears in a pathway with Gene
B.
- Gene A activates Pathway A.
- Gene B suppresses Pathway A. … and
on and on. The important thing here is that your edge list should
contain a list of relationships between, at most, two kinds of entities
(e.g., geneA and geneB, features and pathways). The nature of those
relationships can differ. For example, Gene A could have up-regulated
Pathway A, while Gene B down-regulates Pathway A. But there should be
two different kinds of things, at most, described in two columns.
If you need specific guidance on setting up your edge list, see Preparing Data
1: Making an Edge List.
You can save your spreadsheet as an Excel document (with the file
extension .xls) or its generic equivalent, a CSV (with the file
extension .csv). Cytoscape can interpret both of these formats.
If you don’t have your own data, you can use the sample
edgelist included in this tutorial. (Use the “raw” download link or
download the CSV
directly.) This data was taken from our previous published article on
bladder cancer muscle invasiveness link: https://content.iospress.com/articles/bladder-cancer/blc150024.

Get your edge list into Cytoscpae
Open up Cytoscape. You should be greeted with a welcome pane that
looks something like the one below. (If not, read on for instructions on
how to accomplish the same thing without the welcome screen.)
Start a new session From Network File. Somewhat
confusingly, Cytoscape considers your edge list a “network file.” I
guess it is a network, so maybe it’s not that confusing. Anyway, press
the From Network File button and select the edge list
you’ve prepared. You can also directly drag your .CSV file into
Cytoscape network.


Help Cytoscape understand your data
The screen that pops up after you imported your edge list might be
the most initially confusing part of Cytoscape, although it’s no problem
once you figure out what it wants. You need to tell Cytoscape which
parts of your data constitute the entities in your network diagram.
Cytoscape hasn’t understood right away that you want a network
composed of geneA and geneB nodes. You
can tell that’s the case because the icon that appears next to the words
gene symbol A and Interaction Type
looks sort of like a document, which means that Cytoscape thinks that
you’ve fed it a list of edge attributes, not edges
themselves. Edge attributes can come in handy, as I’ll explain below,
but that’s not what you’ve provided Cytoscape at the moment.
We need to tell Cytoscape that the edge list we’ve provided contains
Sources in one column and Targets in
another. It doesn’t matter, in this case, which column you designate a
source and which column you designate a
target; it’s just that one column has to be one and the
other has to be the other. (If our network was
directed, this would matter, but that’s more
information than you need right now.)
OK, let’s tell Cytoscape how to interpret our data. Click on the
arrow next to the word Gene Symbol A and from the menu
that appears, select the green circle. Cryptically, this icon means
Source. For the Gene Symbol B column,
do the same thing, but this time select the red bullseye, which means
Target.
When you’ve changed both columns, click OK.

You have a (very confusing) network!
If the previous steps worked properly, you should have a network of
connected nodes. If you have more than 100 or so, though, your network
will look a lot like a hairball. We’ll talk about ways to make your
network graph more legible in subsequent steps.
For now, note that you can zoom in on parts of your network using the
magnifying glasses or your mouse. On a Mac, you can move your canvas
around if you hold down the command key and drag. You
can also search for individual nodes by using the search box at the
upper right of the window. (Note that Cytoscape doesn’t zoom to
the node you searched for right away; it just highlights it in yellow.
You may have to zoom out to see the selected node.). 
Switch up your style
One of the easiest ways to change the look of your network diagram is
to switch the style using one of Cytoscape’s built-in options. To do
that, click the Style tab on the control panel and then
choose one of the options with which you’re presented. I don’t know if I
love any of them, but some are more legible than others.

Change your layout
Sometimes networks are more legible if you change the arrangement of
the nodes. You can do this by switching the layout. Click on
Layout from Cytoscape’s menu bar and select one of the
layout options. Experiment with various layouts and notice how
drastically your network diagram changes.
Confoundingly, each of these wildly different network layouts
displays the same basic information. How can this be? Simple: In most
network graphs, the proximity of two nodes doesn’t indicate anything
except legibility. This can be really confusing, because cognitively, we
expect proximity to convey meaningful information. It just doesn’t,
though, in most network diagrams. The presence or absence of an edge
means something, and color and size often do, too. But proximity
generally doesn’t.

Customize your style
You can make changes to many visual attributes of your network graph
from Cytoscape’s control panel. Once you’ve selected the
Style tab, look at the bottom of the control panel.
You’ll see that three additional buttons allow you to customize the look
of the nodes, the edges, and the
network as a whole.
Looking at the Node style pane, you’ll see that we
can alter many aspects of our nodes, including their border, the color,
height, labels, etc. But what do the three columns, labeled
Def., Map., and Byp. mean?
Def. stands for default: the
default visual attribute of a node. If you click on the default fill
color for your network diagram, for example (in the image below, it’s a
blue square), you’ll see that you can swap out the colors of your
network’s nodes.
Byp. stands for bypass, and it
allows you to apply a style to a group of nodes that you select.
The Map. (mapping) column allows you to control the
visual features of your nodes according to their properties. For
example, let’s say you’d like all of the films from a particular studio
to appear in pink. You can do that by mapping that attribute to a
particular color. Or, let’s say you’d like those nodes with more
connections to appear larger. You can do that with the mapping
control.
The problem is, we don’t have any of that information currently
included in our network. So in the next tutorial, we’ll look at how to
load up attributes for our nodes.
(Or
you can skip straight to publishing your network diagram!)

Saving your network
Cytoscape provides a number of ways to save results and
visualizations: As a session: File → Save Session, File → Save
Session As…

As an image: File → Export → Network to Image…


To the web: File → Export → Network to Web Page… To
a public repository: File → Export → Network to NDEx As
a graph format file: File → Export → Network to
File.
Formats:
- CX JSON / CX2 JSON
- Cytoscape.js JSON
- GraphML
- PSI-MI
- XGMML
- SIF
Now let us begin the course with the first session -
Introduction to Cytoscape and it’s App. Click here:
LS0tCnRpdGxlOiAiQ3l0b3NjYXBlIENyYXNoIENvdXJzZSIKYXV0aG9yOiAiQWtzaGF5IEJoYXQiCmRhdGU6ICdgciBmb3JtYXQoU3lzLnRpbWUoKSwgIkxhc3QgbW9kaWZpZWQ6ICVkICViICVZIilgJwpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGNzczogc3R5bGVzaGVldHMvc3R5bGVzLmNzcwogIHBkZl9kb2N1bWVudDoKICAgIHRvYzogeWVzCi0tLQojIyBBbmFseXNpcyBvZiBuZXh0LWdlbmVyYXRpb24gc2VxdWVuY2luZyBkYXRhIHVzaW5nICoqQ3l0b3NjYXBlKioKCgo8IS0tIAo8aW1nIHNyYz0iaW1hZ2VzL0N5dG9zY2FwZS1Mb2dvLnBuZyIgc3R5bGU9InBvc2l0aW9uOmFic29sdXRlO3RvcDo0MHB4O3JpZ2h0OjEwcHg7IiB3aWR0aD0iMjAwIiAvPgoKPGltZyBzcmM9ImltYWdlcy9sb2dvLXNtLnBuZyIgc3R5bGU9InBvc2l0aW9uOmFic29sdXRlO3RvcDo0MHB4O2NlbnRlcjoxMHB4OyIgd2lkdGg9IjIwMCIgLz4KCi0tPgoKIyMgRGF0ZSBhbmQgVmVudWUKLSBKdW5lIDEydGggMjAyNCAtIFVuaXZlcnNpdHkgb2YgU2hlZmZpZWxkCi0gQmFydG9sb21lIEhvdXNlLCBTZW1pbmFyIFJvb20gRUcwMwoKIyMgU2NoZWR1bGUgKFByb3Zpc29uYWwpCgojIyMgVGh1cnNkYXkgMTJ0aCBKdW5lLCAyMDI0CgoKLSAwOTozMCAtIDExOjAwIEludHJvZHVjdGlvbiB0byBDeXRvc2NhcGUgYW5kIGl0J3MgQXBwCi0gMTE6MTUgLSAxMjozMCBGdW5jdGlvbmFsIEVucmljaG1lbnQgQW5hbHlzaXMKLSAxMjozMCAtIDEzOjE1IExVTkNICi0gMTM6MTUgLSAxNTowMCBFbnJpY2htZW50IHVzaW5nIENsdWVHTyBhbmQgQ2x1ZVBlZGlhCi0gMTU6MDAgLSAxNjozMCBJZGVudGlmeWluZyBzaWduaWlmY2FudCBwYXRod2F5IG1vZHVsZXMgYW5kIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGdlbmVzCgojIyBNYXRlcmlhbHMKClRoaXMgY291cnNlIGNvbXByaXNlcyBvZiB0aHJlZSBzZXNzaW9ucy4gCgoqIFtTZXNzaW9uIDE6QSAtIEludHJvZHVjdGlvbiB0byBDeXRvc2NhcGUgYW5kIGl0J3MgQXBwIC0gUGFydCAxXShzZXNzaW9uMWEuUm1kKQoqIFtQYXJ0IDE6QSAtIEhUTUxdKHNlc3Npb24xYS5uYi5odG1sKQoqIFtTZXNzaW9uIDE6QiAtIEludHJvZHVjdGlvbiB0byBDeXRvc2NhcGUgYW5kIGl0J3MgQXBwIC0gUGFydCAyXShzZXNzaW9uMWIuUm1kKQoqIFtQYXJ0IDE6QiAtIEhUTUxdKHNlc3Npb24xYi5uYi5odG1sKQoqIFtTZXNzaW9uIDI6QSAtIEJhc2ljIG5ldHdvcmsgYW5hbHlzaXMgdXNpbmcgUk5BLVNlcSBkYXRhXShzZXNzaW9uMmEuUm1kKQoqIFtQYXJ0IDI6QSAtIEhUTUxdKHNlc3Npb24yYS5uYi5odG1sKQoqIFtTZXNzaW9uIDI6QiAtIEZ1bmN0aW9uYWwgRW5yaWNobWVudCBBbmFseXNpc10oc2Vzc2lvbjJiLlJtZCkKKiBbUGFydCAyOkIgLSBIVE1MXShzZXNzaW9uMmIubmIuaHRtbCkKKiBbU2Vzc2lvbiAzIC0gRW5yaWNobWVudCB1c2luZyBDbHVlR08gYW5kIENsdWVQZWRpYS5dKHNlc3Npb24zLlJtZCkKKiBbUGFydCAzIC0gSFRNTF0oc2Vzc2lvbjMubmIuaHRtbCkKCiMgQ291cnNlIE92ZXJ2aWV3ClRoZSB3b3Jrc2hvcCBpcyBkZXNpZ25lZCB0byBnaXZlIHlvdSBhbiBpbnRyb2R1Y3Rpb24gdG8gdXNpbmcgQ3l0b3NjYXBlLCB3aGljaCBpcyBhIG5ldHdvcmstYmFzZWQgc29mdHdhcmUgYXBwbGljYXRpb24gdG8gcGVyZm9ybSBiaW9pbmZvcm1hdGljcyBkYXRhIGFuZCBwYXRod2F5IGVucmljaG1lbnQgYW5hbHlzaXMuIFRoZSBwYXJ0aWN1bGFyIHVzZS1jYXNlIGluIHRoaXMgY291cnNlIGlzIHRoYXQgb2YgUk5BLXNlcSBkYXRhLCBidXQgbWFueSBvZiB0aGUgY29uY2VwdHMgYXJlIHVzZWQgZm9yIG90aGVyIHR5cGVzIG9mICoqb21pY3MqKi1hbmFseXNpcy4gVGhlcmUgYXJlIHNldmVyYWwgcmVhc29ucyB3aHkgd2UgbWlnaHQgd2FudCB0byB1c2UgKipDeXRvc2NwYWUqKiBpbiAqKkJpb2luZm9ybWF0aWNzKio6LQoKKiBZb3UgY2FuIGJlIGEgbmFpdmUgb3Igbm9uLXByb2dyYW1tZXIgZm9yIGFuYWx5c2luZyB5b3VyIGJpb2xvZ2ljYWwgZGF0YXNldHMgZ2VuZXJhdGVkIGJ5IOKAnGhpZ2gtdGhyb3VnaHB1dCBzZXF1ZW5jaW5n4oCdIHRocm91Z2ggZGVkaWNhdGVkIEN5dG9zY2FwZSBwYWNrYWdlcy4KKiBUaGUgKipwYWNrYWdlcy9BcHBzKiogd2l0aGluIEN5dG9zY2FwZSBwcm92aWRlIGEgdXNlciBjb21wbGV0ZSBzdXBwb3J0IGZvciBkaWZmZXJlbnQgdHlwZXMgb2Yg4oCcLU9taWNz4oCdIGRhdGFzZXRzLgogICoJZS5nLiBtYW55IE5HUyB0b29scyBhcmUgZGV2ZWxvcGVkIGZvciBhIFVuaXggZW52aXJvbm1lbnQuCiAgKiBTb21lIHRhc2tzIHJlcXVpcmUgbW9yZSBtZW1vcnkgKFJBTSkgYW5kIHByb2Nlc3NvciBzcGVlZCB0aGFuIHdlIGhhdmUgb24gb3VyIG93biBtYWNoaW5lCiAgKiBTb21lIGFuYWx5c2VzIHRha2UgdG9vIGxvbmcsIGFuZCB3aGlsc3QgdGhleSBhcmUgcnVubmluZyBldmVyeXRoaW5nIGVsc2Ugb24gb3VyIG1hY2hpbmUgd2lsbCBiZSBzbG93LgogICogRXZlbnR1YWxseSB5b3Ugd2lsbCB3YW50IHRvIHVzZSDigJxIaWdoLXBlcmZvcm1hbmNlIGNvbXB1dGluZ+KAnSAoSFBDKSAtIGJ1dCB0aGlzIHJlcXVpcmVzIHNvbWUgYmFja2dyb3VuZCBrbm93bGVkZ2UgYmVmb3JlIHlvdSBjYW4gdXNlIGl0LgogICogSGVuY2UsICoqQ3l0b3NjYXBlKiogcHJvdmlkZXMgbWFueSBhZHZhbnRhZ2VzIGZvciB0aG9zZSB1c2VycyB3aG8gd2lzaCB0byBoYXZlIHRoZWlyIGJpb2xvZ2ljYWwgZGF0YSBhbmFseXNlZCBpbiBhIG1vcmUgdXNlci1mcmVpbmRseSBtYW5uZXIgYnV0IGFsc28gdmlzdWFsaXppbmcgcmVzdWx0cyBzaW11bHRhbmVvdXNseS4gCgojIyBDcmVhdGluZyBOZXR3b3JrIEdyYXBocyB3aXRoIEN5dG9zY2FwZQoKKipDeXRvc2NhcGUqKiBpcyBhIHRvb2wgZm9yIHZpZXdpbmcgYW5kIGFuYWx5c2luZyBuZXR3b3JrcyAobWVhbmluZywgaW4gdGhpcyBjYXNlLCBhbnkgZ3JvdXAgb2YgZW50aXRpZXMgdGhhdCBhcmUgY29ubmVjdGVkIGluIHNvbWUgd2F5KS4gQ3l0b3NjYXBlIGlzIG5vdCB0b28gaGFyZCB0byB1c2UsIGJ1dCBpdCB3b24ndCBtYWtlIG11Y2ggc2Vuc2UgdW5sZXNzIHlvdSBoYXZlIGEgc2Vuc2Ugb2Ygc29tZSBiYXNpYyBuZXR3b3JrIGFuYWx5c2lzIHZvY2FidWxhcnkgYW5kIGNvbmNlcHRzLiBBIGdsb3NzYXJ5IGlzIG1hZGUgYmVsb3cgZm9yIGJhc2ljIHVuZGVyc3RhbmRpbmcgb2YgaW50cm9kdWN0aW9uIHRvIG5ldHdvcmsgZ3JhcGhzLiAKCiMjICoqQmFzaWMgVGVybXMqKgoKKipCaW9sb2dpY2FsIG5ldHdvcmsqKgoKQSBmaW5pdGUgc2V0IChvciBzZXRzKSBvZiBmZWF0dXJlcyAoYS5rLmEuIGJpb2xvZ2ljYWwgZW50aXRpZXMsIGZvciBlLmcuIGdlbmVzLCBtUk5BcywgbWlSTkFzLCBwcm90ZWlucywgcGVwdGlkZXMsIG1ldGFib2xpdGVzLCBldGMuKSBhbmQgdGhlIHJlbGF0aW9ucyAoZm9yIGUuZy4gY28tZXhwcmVzc2lvbikgZGVmaW5lZCBvbiB0aGVtLiBJdApjb25zaXN0cyBvZiB0aHJlZSBlbGVtZW50czogKDEpIGEgc2V0IG9mIGJpb2xvZ2ljYWwgZW50aXRpZXM7ICgyKSBlYWNoIGJpby1lbnRpdHkgaGFzIGEKc2V0IG9mIGluZGl2aWR1YWwgYXR0cmlidXRlczsgYW5kICgzKSBhIHNldCBvZiB0aWVzIHRoYXQgZGVmaW5lcyBhdCBsZWFzdCBvbmUgcmVsYXRpb24gYW1vbmcgZmVhdHVyZXMuCgoqKkdyYXBoKioKCkEgY29tbW9uIHdheSB0byB2aXN1YWxseSByZXByZXNlbnQgYmlvbG9naWNhbCBuZXR3b3JrcywgY29uc2lzdGluZyBvZiB0d28KZGltZW5zaW9uczogYmlvLWVudGl0eSBhbmQgcmVsYXRpb25zIChhbHNvIGNhbGxlZCBub2RlcyBhbmQgZWRnZXMpLgoKKipOb2RlKioKCk5vZGVzIGFyZSB0aGUgZW50aXRpZXMgaW4gZ3JhcGggKGFsc28gY2FsbGVkIHZlY3RvcnMpLiBGb3IgZXhhbXBsZSwgaWYKd2UgY29uc2lkZXIgRE5BLURhbWFnZSBSZXBhaXIgKEREUikgcGF0aHdheXMgYXMgYSBncmFwaCwgdGhlbiBldmVyeSBnZW5lL3BhdGh3YXktdGVybSBpcyBhIG5vZGUuCgoqKkVkZ2UqKgoKVGhlc2UgYXJlIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gbm9kZXMuIEZvciBleGFtcGxlLCBpZiB3ZSBjb25zaWRlcgpFeHRyYWNlbGx1bGFyLU1hdHJpeCByZWd1bGF0aW9uIGFzIGEgZ3JhcGggdGhlbiBldmVyeSBhY3RpdmF0aW9uL2luaGliaXRpb24gb2YgZ2VuZTEtZ2VuZTIgcGFpciBpcyBhbiBlZGdlLgoKIVtdKGltYWdlcy9pbWFnZTEucG5nKSAKCiMjICoqVHlwZXMgb2YgR3JhcGhzKioKCioqVW5kaXJlY3RlZCBncmFwaCoqCgpXaGVuIHRoZSByZWxhdGlvbnNoaXAgaXMgYWx3YXlzIHZhbGlkIGluIGJvdGggZGlyZWN0aW9ucywgdGhlbiBpdCBpcwpjYWxsZWQgKip1bmRpcmVjdGVkIGdyYXBoKiouIEZvciBlLmcuIElmIGdlbmUtMSAqKlRQNTMqKiBpcyBpbmhpYml0aW5nIGdlbmUtMiAqKlJCMSoqIHdpdGhpbiBhIGNlbGwtcmVndWxhdG9yeSBuZXR3b3JrLCB0aGVuClJCMSBpcyBhbHNvIGFjdGl2YXRpbmcgVFA1My4KCioqRGlyZWN0ZWQgZ3JhcGgqKgoKV2hlbiB0aGUgcmVsYXRpb25zaGlwIG1heSBub3QgYmUgdmFsaWQgaW4gYm90aCBkaXJlY3Rpb25zIChjb25uZWN0aW5nCm5vZGVzKSwgdGhlbiBpdCBpcyBjYWxsZWQgYSAqKmRpcmVjdGVkIGdyYXBoKiouIElmIEZHRlIzIGlzIGFzc29jaWF0ZWQgdG8gRVJCQjIKd2l0aGluIGEgY2hyb21vc29tYWwgYWJiZXJhdGlvbiBldmVudCBhbmQgRVJCQjIgaXMgbm90IGhhdmluZyBhbnkgYXNzb2NpYXRpb24gdG8gRkdGUjMsIHRoZW4gcmVsYXRpb25zaGlwIGlzCmRpcmVjdGVkLgoKIVtdKGltYWdlcy9pbWFnZTIuZ2lmKQoKCioqV2VpZ2h0ZWQgbmV0d29yayoqCgpBIG5ldHdvcmsgaW4gd2hpY2ggdGhlIGVkZ2VzIGJldHdlZW4gbm9kZXMgaGF2ZSB3ZWlnaHRzIChjb3JyZXNwb25kaW5nCnRvLCBlLmcuLCB0aGUgc3RyZW5ndGggb2YgYSByZWxhdGlvbnNoaXApIGFzc2lnbmVkIHRvIHRoZW0uCgoqKlVud2VpZ2h0ZWQgbmV0d29yayoqCgpBIG5ldHdvcmsgaW4gd2hpY2ggdGhlIGVkZ2VzIGJldHdlZW4gbm9kZXMgZG8gbm90IGhhdmUgd2VpZ2h0cyBhc3NpZ25lZAp0byB0aGVtLgoKIVtdKGltYWdlcy9pbWFnZTMuanBlZykKCgojIyAqKk1lYXN1cmVzIG9mIEdyYXBocyBvciBOb2RlcyoqCgoqKlNpemUqKgoKQSBtZWFzdXJlIG9mIHRoZSBudW1iZXIgb2YgZ2VuZXMgKG5vZGVzKSBpbiBhIGNvbXBsZXRlIG9yIHN1Yi1ncmFwaGVkIG5ldHdvcmsuCgoqKkRlbnNpdHkqKgoKVGhlIG51bWJlciBvZiB0aWVzIGluIHRoZSBuZXR3b3JrIHJlcG9ydGVkIGFzIGEgZnJhY3Rpb24gb2YgdGhlIHRvdGFsCnBvc3NpYmxlIG51bWJlciBvZiB0aWVzLgoKKipSZWNpcHJvY2l0eSoqCgpUaGUgcHJvcG9ydGlvbiBvZiBtdXR1YWwgdGllcyBpbiBhIG5ldHdvcmsuCgoqKkRpc3RhbmNlKioKClRoZSBudW1iZXIgb2Yg4oCcc3RlcHPigJ0gYmV0d2VlbiBhbnkgdHdvIGdlbmVzIChub2RlcykgaW4gYSBiaW9sb2dpY2FsIG5ldHdvcmsuCgoqKkNsdXN0ZXJpbmcgY29lZmZpY2llbnQqKgoKQSBtZWFzdXJlIG9mIGEgbmV0d29ya+KAmXMgZ2VuZXPigJkgdGVuZGVuY3kgdG8g4oCcZ3JvdXAgdG9nZXRoZXLigJ0gaW50bwpwb2NrZXRzIG9mIGRlbnNlIGNvbm5lY3Rpdml0eS4KCiFbXShpbWFnZXMvaW1hZ2U1LnBuZykKKiAqSW4gdGhlIGZpcnN0IGltYWdlLCB0aGUgYmx1ZSBub2RlIGhhcyBhCmNsdXN0ZXJpbmcgY29lZmZpY2llbnQgb2Ygb25lLCBiZWNhdXNlIGFsbCBwb3NzaWJsZSBjb25uZWN0aW9ucyBhbW9uZwppdHMgbmVpZ2hib3Jpbmcgbm9kZXMgaGF2ZSBiZWVuIHJlYWxpemVkLiBJbiB0aGUgc2Vjb25kIGltYWdlLCBvbmx5IG9uZQpvZiB0aGUgcG9zc2libGUgY29ubmVjdGlvbnMgaGFzIGJlZW4gcmVhbGl6ZWQg4oCUIHNvIHRoZSBibHVlIG5vZGUgaGFzIGEKY2x1c3RlcmluZyBjb2VmZmljaWVudCBvZiAxLzMuIEluIHRoZSB0aGlyZCBpbWFnZSwgbm9uZSBvZiB0aGUKbmVpZ2hib3Jpbmcgbm9kZXMgYXJlIGNvbm5lY3RlZCwgc28gdGhlIGJsdWUgbm9kZSBoYXMgYSBjbHVzdGVyaW5nCmNvZWZmaWNpZW50IG9mIDAuKgoKKipDZW50cmFsaXR5KioKClRoZXJlIGFyZSBtdWx0aXBsZSB3YXlzIHRvIGRldGVybWluZSBhIG5vZGXigJlzIGltcG9ydGFuY2UsIG9yIGNlbnRyYWxpdHkuClRoZSBtZWFzdXJlIHlvdSB1c2UgZGVwZW5kcyBvbiBob3cgeW91IGRlZmluZSBjZW50cmFsaXR5LiBTZXZlcmFsIG9mCnRoZXNlIG1lYXN1cmVzIGFyZToKCioqRGVncmVlIGNlbnRyYWxpdHkqKgoqQW4gaW1wb3J0YW50IG5vZGUgaXMgaW52b2x2ZWQgaW4gbGFyZ2UgbnVtYmVyIG9mIGludGVyYWN0aW9ucy4qIFRoZSBudW1iZXIgb2YgZWRnZXMgY29ubmVjdGVkIHdpdGggYSBwYXJ0aWN1bGFyIG5vZGUuCgoKKipFaWdlbnZlY3RvciBjZW50cmFsaXR5Kiogb3IgaW4gYmlvbG9naWNhbCB0ZXJtcyAqKiAiSHViLXByb3RlaW5zIioqCipBbiBpbXBvcnRhbnQgbm9kZSBpcyBjb25uZWN0ZWQgdG8gaW1wb3J0YW50IG5laWdoYm9ycy4qIFRoaXMgaXMgYQptZWFzdXJlIG9mIGluZmx1ZW5jZSBvZiBhIGdpdmVuIG5vZGUgaW4gdGhlIHdob2xlIG5ldHdvcmsuIFRoZSBub3Rpb24KaXMgaG93IHdlbGwtY29ubmVjdGVkIGEgZ2l2ZW4gbm9kZSBpcyB3aXRoIG90aGVyIHdlbGwgY29ubmVjdGVkIG5vZGVzCmluIHRoZSBuZXR3b3JrLgoKKipCZXR3ZWVubmVzcyBjZW50cmFsaXR5KioKKkFuIGltcG9ydGFudCBub2RlIGxpZXMgb24gYSBoaWdoIHByb3BvcnRpb24gb2YgcGF0aHMgYmV0d2VlbiBvdGhlciBub2RlcyBpbiB0aGUgbmV0d29yay4qCgoqKkNsb3NlbmVzcyBjZW50cmFsaXR5KioKKkFuIGltcG9ydGFudCBub2RlIGlzIHR5cGljYWxseSDigJxjbG9zZeKAnSB0bywgYW5kIGNhbiBjb21tdW5pY2F0ZSBxdWlja2x5IHdpdGgsIHRoZSBvdGhlciBub2RlcyBpbiB0aGUgbmV0d29yay4qIExlbmd0aCBvZiB0aGUgYXZlcmFnZSBzaG9ydGVzdCBwYXRoIGJldHdlZW4gYSBnaXZlbiBub2RlIGFuZCBhbGwgb3RoZXIgbm9kZXMgaW4gYSBncmFwaC4KCgojIyBNb3JlIHJlc291cmNlcyAKKiBodHRwczovL2pvdXJuYWxvZmRpZ2l0YWxodW1hbml0aWVzLm9yZy8xLTEvZGVteXN0aWZ5aW5nLW5ldHdvcmtzLWJ5LXNjb3R0LXdlaW5nYXJ0LwoKCgojIyBBaW1zIG9mIHRoZSBDb3Vyc2UKClRoZXNlIHR1dG9yaWFscyBwcm92aWRlIGEgYmFzaWMgaW50cm9kdWN0aW9uIHRvIHVzaW5nIEN5dG9zY2FwZSB0byBjb25kdWN0IG5ldHdvcmsgYW5hbHlzaXMgb2YgYmlvbG9naWNhbCBkYXRhLiBUaGV5J3JlIGludGVuZGVkIHRvIGJlIHVzZWQgd2l0aCBtdWx0aS1vbWljcyBkYXRhIEkgY29sbGVjdGVkIGFib3V0ICoqVXJvdGhlbGlhbCBDYW5jZXIgb2YgdGhlIEJsYWRkZXIgKFVDQikqKi4gSG93ZXZlciwgYW55b25lIHNob3VsZCBiZSBhYmxlIHRvIGZvbGxvdyBhbG9uZy4KCkhlcmUncyB3aGF0J3MgaW5jbHVkZWQgaW4gdGhlIFNlc3Npb25zOgrigKIJQ3JlYXRpbmcgYSBiYXNpYyBDeXRvc2NhcGUgbmV0d29yayAqKih0aGF0J3MgdGhpcyB0dXRvcmlhbCkqKgrigKIJSW1wb3J0aW5nIGEgbm9kZSBsaXN0IGFuZCB3b3JraW5nIHdpdGggbm9kZSBhdHRyaWJ1dGVzCuKAoglTZWxlY3RpbmcgcGFydHMgb2YgeW91ciBuZXR3b3JrIArigKIJUHVibGlzaGluZyB5b3VyIG5ldHdvcmsgZGlhZ3JhbQoKIyMgU2V0dGluZyB1cCB5b3VyIGRhdGEKClRoZSBtb3N0IGltcG9ydGFudCB0aGluZyB0byB1bmRlcnN0YW5kIGFib3V0IEN5dG9zY2FwZSAob3IsIHJlYWxseSwgbW9zdCBuZXR3b3JrIGFuYWx5c2lzIHRvb2xzKSBpcyB0aGUgZm9ybWF0IGluIHdoaWNoIHlvdSBuZWVkIHRvIHN0cnVjdHVyZSB5b3VyIGRhdGEuIEF0IGl0cyBtb3N0IGJhc2ljLCBDeXRvc2NhcGUgd2FudHMgYSBzcHJlYWRzaGVldCBjb250YWluaW5nIHR3byBjb2x1bW5zLiBUaGUgb2JqZWN0cyBpbiB0aGUgZmlyc3QgY29sdW1uIHNob3VsZCBiZSBjb25uZWN0ZWQgaW4gc29tZSB3YXkgdG8gdGhlIG9iamVjdHMgaW4gdGhlIHNlY29uZCBjb2x1bW4uIFRoaXMgaXMgY2FsbGVkIGFuICoqZWRnZSBsaXN0KiouIEluIHRoZSBleGFtcGxlIGJlbG93LCBteSBlZGdlIGxpc3QgY29udGFpbnMgdHdvIGtpbmRzIG9mIHRoaW5nczogZ2VuZUEgYW5kIGdlbmVCLiBUaGUgY29sdW1ucyBjb3VsZCBiZSByZW9yZGVyZWQgc28gdGhhdCB0aGUgZ2VuZUIgY29sdW1uIHByZWNlZGVzIHRoZSBnZW5lQSBjb2x1bW47IGl0IGRvZXNuJ3QgbWF0dGVyLiBBbGwgdGhhdCBtYXR0ZXJzIGhlcmUgaXMgdGhhdCBlYWNoIHJvdyBpbiBteSBzcHJlYWRzaGVldCBkZXNjcmliZXMgYSBjb25uZWN0aW9uIGJldHdlZW4gdHdvIGVudGl0aWVzLgoKT3RoZXIga2luZHMgb2YgcmVsYXRpb25zaGlwcyB5b3UgY291bGQgZGVzY3JpYmUgaW4gYW4gZWRnZSBsaXN0OgoKKiAqKkdlbmUgQSoqIGFwcGVhcnMgaW4gYSBwYXRod2F5IHdpdGggKipHZW5lIEIqKi4KKiAqKkdlbmUgQSoqIGFjdGl2YXRlcyAqKlBhdGh3YXkgQS4qKgoqICoqR2VuZSBCKiogc3VwcHJlc3NlcyAqKlBhdGh3YXkgQS4qKgouLi4gYW5kIG9uIGFuZCBvbi4gVGhlIGltcG9ydGFudCB0aGluZyBoZXJlIGlzIHRoYXQgeW91ciBlZGdlIGxpc3Qgc2hvdWxkIGNvbnRhaW4gYSBsaXN0IG9mIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiwgYXQgbW9zdCwgdHdvIGtpbmRzIG9mIGVudGl0aWVzIChlLmcuLCBnZW5lQSBhbmQgZ2VuZUIsIGZlYXR1cmVzIGFuZCBwYXRod2F5cykuIFRoZSBuYXR1cmUgb2YgdGhvc2UgcmVsYXRpb25zaGlwcyBjYW4gZGlmZmVyLiBGb3IgZXhhbXBsZSwgR2VuZSBBIGNvdWxkIGhhdmUgdXAtcmVndWxhdGVkIFBhdGh3YXkgQSwgd2hpbGUgR2VuZSBCIGRvd24tcmVndWxhdGVzIFBhdGh3YXkgQS4gQnV0IHRoZXJlIHNob3VsZCBiZSB0d28gZGlmZmVyZW50IGtpbmRzIG9mIHRoaW5ncywgYXQgbW9zdCwgZGVzY3JpYmVkIGluIHR3byBjb2x1bW5zLgoKSWYgeW91IG5lZWQgc3BlY2lmaWMgZ3VpZGFuY2Ugb24gc2V0dGluZyB1cCB5b3VyIGVkZ2UgbGlzdCwgc2VlIFtQcmVwYXJpbmcgRGF0YSAxOiBNYWtpbmcgYW4gRWRnZSBMaXN0XShSZXNvdXJjZXMvcHJlcGFyaW5nLWRhdGEtMS1tYWtpbmctYW4tZWRnZS1saXN0Lm1kKS4KCllvdSBjYW4gc2F2ZSB5b3VyIHNwcmVhZHNoZWV0IGFzIGFuIEV4Y2VsIGRvY3VtZW50ICh3aXRoIHRoZSBmaWxlIGV4dGVuc2lvbiAueGxzKSBvciBpdHMgZ2VuZXJpYyBlcXVpdmFsZW50LCBhIENTViAod2l0aCB0aGUgZmlsZSBleHRlbnNpb24gLmNzdikuIEN5dG9zY2FwZSBjYW4gaW50ZXJwcmV0IGJvdGggb2YgdGhlc2UgZm9ybWF0cy4KCklmIHlvdSBkb24ndCBoYXZlIHlvdXIgb3duIGRhdGEsIHlvdSBjYW4gdXNlIHRoZSBbc2FtcGxlIGVkZ2VsaXN0XShEYXRhX0ZpbGVzL2ludGVyYWN0aW9uc19kYXRhX0JsYWRkZXJDYW5jZXJfQUJoYXRldGFsLmNzdikgaW5jbHVkZWQgaW4gdGhpcyB0dXRvcmlhbC4gKFVzZSB0aGUgInJhdyIgZG93bmxvYWQgbGluayBvciBkb3dubG9hZCB0aGUgW0NTVl0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2ExYWtzL0N5dG9zY2FwZV9Db3Vyc2UvbWFpbi9EYXRhX0ZpbGVzL2ludGVyYWN0aW9uc19kYXRhX0JsYWRkZXJDYW5jZXJfQUJoYXRldGFsLmNzdikgZGlyZWN0bHkuKSBUaGlzIGRhdGEgd2FzIHRha2VuIGZyb20gb3VyIHByZXZpb3VzIHB1Ymxpc2hlZCBhcnRpY2xlIG9uIGJsYWRkZXIgY2FuY2VyIG11c2NsZSBpbnZhc2l2ZW5lc3MgbGluazogaHR0cHM6Ly9jb250ZW50Lmlvc3ByZXNzLmNvbS9hcnRpY2xlcy9ibGFkZGVyLWNhbmNlci9ibGMxNTAwMjQuCiAKIVtdKGltYWdlcy9JbnRlcmFjdGlvblBpYy5wbmcpCgoKIyBHZXQgeW91ciBlZGdlIGxpc3QgaW50byBDeXRvc2NwYWUKT3BlbiB1cCBDeXRvc2NhcGUuIFlvdSBzaG91bGQgYmUgZ3JlZXRlZCB3aXRoIGEgd2VsY29tZSBwYW5lIHRoYXQgbG9va3Mgc29tZXRoaW5nIGxpa2UgdGhlIG9uZSBiZWxvdy4gKElmIG5vdCwgcmVhZCBvbiBmb3IgaW5zdHJ1Y3Rpb25zIG9uIGhvdyB0byBhY2NvbXBsaXNoIHRoZSBzYW1lIHRoaW5nIHdpdGhvdXQgdGhlIHdlbGNvbWUgc2NyZWVuLikKCgoKClN0YXJ0IGEgbmV3IHNlc3Npb24gKipGcm9tIE5ldHdvcmsgRmlsZS4qKiBTb21ld2hhdCBjb25mdXNpbmdseSwgQ3l0b3NjYXBlIGNvbnNpZGVycyB5b3VyIGVkZ2UgbGlzdCBhICJuZXR3b3JrIGZpbGUuIiBJIGd1ZXNzIGl0IGlzIGEgbmV0d29yaywgc28gbWF5YmUgaXQncyBub3QgdGhhdCBjb25mdXNpbmcuIEFueXdheSwgcHJlc3MgdGhlICoqRnJvbSBOZXR3b3JrIEZpbGUqKiBidXR0b24gYW5kIHNlbGVjdCB0aGUgZWRnZSBsaXN0IHlvdSd2ZSBwcmVwYXJlZC4gWW91IGNhbiBhbHNvIGRpcmVjdGx5IGRyYWcgeW91ciAuQ1NWIGZpbGUgaW50byBDeXRvc2NhcGUgbmV0d29yay4KCgohW10oaW1hZ2VzL1Nlc3Npb25fQ3l0b19JbnRlcmFjdGlvbi5wbmcpCgoKPGRpdiBjbGFzcz0iaW5mb3JtYXRpb24iPgojIElmIHlvdSBkb24ndCBzZWUgdGhhdCB3ZWxjb21lIHNjcmVlbi4uLgpubyBiaWcgZGVhbC4gU29tZW9uZSBtaWdodCBoYXZlIGRpc2FibGVkIGl0LCBidXQgeW91IGNhbiBhY2NvbXBsaXNoIHRoZSBzYW1lIHRoaW5nIGJ5IGNsaWNraW5nIG9uIHRoZSAqKkltcG9ydCBOZXR3b3JrIGZyb20gRmlsZSoqIGJ1dHRvbiAoY2lyY2xlZCBiZWxvdykgYW5kIHNlbGVjdGluZyB5b3VyIGVkZ2UgbGlzdC4KPC9kaXY+CgohW10oaW1hZ2VzL0ltcG9ydHBpYy5wbmcpCgoKCgojIEhlbHAgQ3l0b3NjYXBlIHVuZGVyc3RhbmQgeW91ciBkYXRhClRoZSBzY3JlZW4gdGhhdCBwb3BzIHVwIGFmdGVyIHlvdSBpbXBvcnRlZCB5b3VyIGVkZ2UgbGlzdCBtaWdodCBiZSB0aGUgbW9zdCBpbml0aWFsbHkgY29uZnVzaW5nIHBhcnQgb2YgQ3l0b3NjYXBlLCBhbHRob3VnaCBpdCdzIG5vIHByb2JsZW0gb25jZSB5b3UgZmlndXJlIG91dCB3aGF0IGl0IHdhbnRzLiBZb3UgbmVlZCB0byB0ZWxsIEN5dG9zY2FwZSB3aGljaCBwYXJ0cyBvZiB5b3VyIGRhdGEgY29uc3RpdHV0ZSB0aGUgZW50aXRpZXMgaW4geW91ciBuZXR3b3JrIGRpYWdyYW0uCgoKQ3l0b3NjYXBlIGhhc24ndCB1bmRlcnN0b29kIHJpZ2h0IGF3YXkgdGhhdCB5b3Ugd2FudCBhIG5ldHdvcmsgY29tcG9zZWQgb2YgKipnZW5lQSoqIGFuZCAqKmdlbmVCKiogbm9kZXMuIFlvdSBjYW4gdGVsbCB0aGF0J3MgdGhlIGNhc2UgYmVjYXVzZSB0aGUgaWNvbiB0aGF0IGFwcGVhcnMgbmV4dCB0byB0aGUgd29yZHMgKipnZW5lIHN5bWJvbCBBKiogYW5kICoqSW50ZXJhY3Rpb24gVHlwZSoqIGxvb2tzIHNvcnQgb2YgbGlrZSBhIGRvY3VtZW50LCB3aGljaCBtZWFucyB0aGF0IEN5dG9zY2FwZSB0aGlua3MgdGhhdCB5b3UndmUgZmVkIGl0IGEgbGlzdCBvZiAqKmVkZ2UgYXR0cmlidXRlcyoqLCBub3QgZWRnZXMgdGhlbXNlbHZlcy4gRWRnZSBhdHRyaWJ1dGVzIGNhbiBjb21lIGluIGhhbmR5LCBhcyBJJ2xsIGV4cGxhaW4gYmVsb3csIGJ1dCB0aGF0J3Mgbm90IHdoYXQgeW91J3ZlIHByb3ZpZGVkIEN5dG9zY2FwZSBhdCB0aGUgbW9tZW50LgoKCldlIG5lZWQgdG8gdGVsbCBDeXRvc2NhcGUgdGhhdCB0aGUgZWRnZSBsaXN0IHdlJ3ZlIHByb3ZpZGVkIGNvbnRhaW5zICoqU291cmNlcyoqIGluIG9uZSBjb2x1bW4gYW5kICoqVGFyZ2V0cyoqIGluIGFub3RoZXIuIEl0IGRvZXNuJ3QgbWF0dGVyLCBpbiB0aGlzIGNhc2UsIHdoaWNoIGNvbHVtbiB5b3UgZGVzaWduYXRlIGEgKipzb3VyY2UqKiBhbmQgd2hpY2ggY29sdW1uIHlvdSBkZXNpZ25hdGUgYSAqKnRhcmdldCoqOyBpdCdzIGp1c3QgdGhhdCBvbmUgY29sdW1uIGhhcyB0byBiZSBvbmUgYW5kIHRoZSBvdGhlciBoYXMgdG8gYmUgdGhlIG90aGVyLiAoSWYgb3VyIG5ldHdvcmsgd2FzICoqZGlyZWN0ZWQqKiwgdGhpcyB3b3VsZCBtYXR0ZXIsIGJ1dCB0aGF0J3MgbW9yZSBpbmZvcm1hdGlvbiB0aGFuIHlvdSBuZWVkIHJpZ2h0IG5vdy4pCgoKT0ssIGxldCdzIHRlbGwgQ3l0b3NjYXBlIGhvdyB0byBpbnRlcnByZXQgb3VyIGRhdGEuIENsaWNrIG9uIHRoZSBhcnJvdyBuZXh0IHRvIHRoZSB3b3JkICoqR2VuZSBTeW1ib2wgQSoqIGFuZCBmcm9tIHRoZSBtZW51IHRoYXQgYXBwZWFycywgc2VsZWN0IHRoZSBncmVlbiBjaXJjbGUuIENyeXB0aWNhbGx5LCB0aGlzIGljb24gbWVhbnMgKipTb3VyY2UuKiogRm9yIHRoZSAqKkdlbmUgU3ltYm9sIEIqKiBjb2x1bW4sIGRvIHRoZSBzYW1lIHRoaW5nLCBidXQgdGhpcyB0aW1lIHNlbGVjdCB0aGUgcmVkIGJ1bGxzZXllLCB3aGljaCBtZWFucyAqKlRhcmdldC4qKgoKCldoZW4geW91J3ZlIGNoYW5nZWQgYm90aCBjb2x1bW5zLCBjbGljayAqKk9LLioqCgohW10oaW1hZ2VzL05ldHdvcmtJbXBvcnQucG5nKQoKCgoKIyBZb3UgaGF2ZSBhICh2ZXJ5IGNvbmZ1c2luZykgbmV0d29yayEKSWYgdGhlIHByZXZpb3VzIHN0ZXBzIHdvcmtlZCBwcm9wZXJseSwgeW91IHNob3VsZCBoYXZlIGEgbmV0d29yayBvZiBjb25uZWN0ZWQgbm9kZXMuIElmIHlvdSBoYXZlIG1vcmUgdGhhbiAxMDAgb3Igc28sIHRob3VnaCwgeW91ciBuZXR3b3JrIHdpbGwgbG9vayBhIGxvdCBsaWtlIGEgaGFpcmJhbGwuIFdlJ2xsIHRhbGsgYWJvdXQgd2F5cyB0byBtYWtlIHlvdXIgbmV0d29yayBncmFwaCBtb3JlIGxlZ2libGUgaW4gc3Vic2VxdWVudCBzdGVwcy4KCkZvciBub3csIG5vdGUgdGhhdCB5b3UgY2FuIHpvb20gaW4gb24gcGFydHMgb2YgeW91ciBuZXR3b3JrIHVzaW5nIHRoZSBtYWduaWZ5aW5nIGdsYXNzZXMgb3IgeW91ciBtb3VzZS4gT24gYSBNYWMsIHlvdSBjYW4gbW92ZSB5b3VyIGNhbnZhcyBhcm91bmQgaWYgeW91IGhvbGQgZG93biB0aGUgKipjb21tYW5kKioga2V5IGFuZCBkcmFnLiBZb3UgY2FuIGFsc28gc2VhcmNoIGZvciBpbmRpdmlkdWFsIG5vZGVzIGJ5IHVzaW5nIHRoZSBzZWFyY2ggYm94IGF0IHRoZSB1cHBlciByaWdodCBvZiB0aGUgd2luZG93LiAqKihOb3RlIHRoYXQgQ3l0b3NjYXBlIGRvZXNuJ3Qgem9vbSB0byB0aGUgbm9kZSB5b3Ugc2VhcmNoZWQgZm9yIHJpZ2h0IGF3YXk7IGl0IGp1c3QgaGlnaGxpZ2h0cyBpdCBpbiB5ZWxsb3cuIFlvdSBtYXkgaGF2ZSB0byB6b29tIG91dCB0byBzZWUgdGhlIHNlbGVjdGVkIG5vZGUuKS4qKgohW10oaW1hZ2VzL0NvbmZ1c2VkX05ldHdvcmsucG5nKQoKCiMgU3dpdGNoIHVwIHlvdXIgc3R5bGUKT25lIG9mIHRoZSBlYXNpZXN0IHdheXMgdG8gY2hhbmdlIHRoZSBsb29rIG9mIHlvdXIgbmV0d29yayBkaWFncmFtIGlzIHRvIHN3aXRjaCB0aGUgc3R5bGUgdXNpbmcgb25lIG9mIEN5dG9zY2FwZSdzIGJ1aWx0LWluIG9wdGlvbnMuIFRvIGRvIHRoYXQsIGNsaWNrIHRoZSAqKlN0eWxlKiogdGFiIG9uIHRoZSBjb250cm9sIHBhbmVsIGFuZCB0aGVuIGNob29zZSBvbmUgb2YgdGhlIG9wdGlvbnMgd2l0aCB3aGljaCB5b3UncmUgcHJlc2VudGVkLiBJIGRvbid0IGtub3cgaWYgSSBsb3ZlIGFueSBvZiB0aGVtLCBidXQgc29tZSBhcmUgbW9yZSBsZWdpYmxlIHRoYW4gb3RoZXJzLgoKIVtdKGltYWdlcy9TdHlsZS10YWIucG5nKQoKCgojIENoYW5nZSB5b3VyIGxheW91dApTb21ldGltZXMgbmV0d29ya3MgYXJlIG1vcmUgbGVnaWJsZSBpZiB5b3UgY2hhbmdlIHRoZSBhcnJhbmdlbWVudCBvZiB0aGUgbm9kZXMuIFlvdSBjYW4gZG8gdGhpcyBieSBzd2l0Y2hpbmcgdGhlIGxheW91dC4gQ2xpY2sgb24gKipMYXlvdXQqKiBmcm9tIEN5dG9zY2FwZSdzIG1lbnUgYmFyIGFuZCBzZWxlY3Qgb25lIG9mIHRoZSBsYXlvdXQgb3B0aW9ucy4gRXhwZXJpbWVudCB3aXRoIHZhcmlvdXMgbGF5b3V0cyBhbmQgbm90aWNlIGhvdyBkcmFzdGljYWxseSB5b3VyIG5ldHdvcmsgZGlhZ3JhbSBjaGFuZ2VzLgoKCkNvbmZvdW5kaW5nbHksIGVhY2ggb2YgdGhlc2Ugd2lsZGx5IGRpZmZlcmVudCBuZXR3b3JrIGxheW91dHMgZGlzcGxheXMgdGhlIHNhbWUgYmFzaWMgaW5mb3JtYXRpb24uIEhvdyBjYW4gdGhpcyBiZT8gU2ltcGxlOiBJbiBtb3N0IG5ldHdvcmsgZ3JhcGhzLCB0aGUgcHJveGltaXR5IG9mIHR3byBub2RlcyBkb2Vzbid0IGluZGljYXRlIGFueXRoaW5nIGV4Y2VwdCBsZWdpYmlsaXR5LiBUaGlzIGNhbiBiZSByZWFsbHkgY29uZnVzaW5nLCBiZWNhdXNlIGNvZ25pdGl2ZWx5LCB3ZSBleHBlY3QgcHJveGltaXR5IHRvIGNvbnZleSBtZWFuaW5nZnVsIGluZm9ybWF0aW9uLiBJdCBqdXN0IGRvZXNuJ3QsIHRob3VnaCwgaW4gbW9zdCBuZXR3b3JrIGRpYWdyYW1zLiBUaGUgcHJlc2VuY2Ugb3IgYWJzZW5jZSBvZiBhbiBlZGdlIG1lYW5zIHNvbWV0aGluZywgYW5kIGNvbG9yIGFuZCBzaXplIG9mdGVuIGRvLCB0b28uIEJ1dCBwcm94aW1pdHkgZ2VuZXJhbGx5IGRvZXNuJ3QuCgohW10oaW1hZ2VzL2xheW91dC1jaGFuZ2UucG5nKQoKCgojIEN1c3RvbWl6ZSB5b3VyIHN0eWxlCgpZb3UgY2FuIG1ha2UgY2hhbmdlcyB0byBtYW55IHZpc3VhbCBhdHRyaWJ1dGVzIG9mIHlvdXIgbmV0d29yayBncmFwaCBmcm9tIEN5dG9zY2FwZSdzIGNvbnRyb2wgcGFuZWwuIE9uY2UgeW91J3ZlIHNlbGVjdGVkIHRoZSAqKlN0eWxlKiogdGFiLCBsb29rIGF0IHRoZSBib3R0b20gb2YgdGhlIGNvbnRyb2wgcGFuZWwuIFlvdSdsbCBzZWUgdGhhdCB0aHJlZSBhZGRpdGlvbmFsIGJ1dHRvbnMgYWxsb3cgeW91IHRvIGN1c3RvbWl6ZSB0aGUgbG9vayBvZiB0aGUgKipub2RlcyoqLCB0aGUgKiplZGdlcyoqLCBhbmQgdGhlICoqbmV0d29yayoqIGFzIGEgd2hvbGUuCgoKTG9va2luZyBhdCB0aGUgKipOb2RlKiogc3R5bGUgcGFuZSwgeW91J2xsIHNlZSB0aGF0IHdlIGNhbiBhbHRlciBtYW55IGFzcGVjdHMgb2Ygb3VyIG5vZGVzLCBpbmNsdWRpbmcgdGhlaXIgYm9yZGVyLCB0aGUgY29sb3IsIGhlaWdodCwgbGFiZWxzLCBldGMuIEJ1dCB3aGF0IGRvIHRoZSB0aHJlZSBjb2x1bW5zLCBsYWJlbGVkICoqRGVmLiwgTWFwLiwqKiBhbmQgKipCeXAuKiogbWVhbj8KCgoqKkRlZi4qKiBzdGFuZHMgZm9yICoqZGVmYXVsdCoqOiB0aGUgZGVmYXVsdCB2aXN1YWwgYXR0cmlidXRlIG9mIGEgbm9kZS4gSWYgeW91IGNsaWNrIG9uIHRoZSBkZWZhdWx0IGZpbGwgY29sb3IgZm9yIHlvdXIgbmV0d29yayBkaWFncmFtLCBmb3IgZXhhbXBsZSAoaW4gdGhlIGltYWdlIGJlbG93LCBpdCdzIGEgYmx1ZSBzcXVhcmUpLCB5b3UnbGwgc2VlIHRoYXQgeW91IGNhbiBzd2FwIG91dCB0aGUgY29sb3JzIG9mIHlvdXIgbmV0d29yaydzIG5vZGVzLgoKCioqQnlwLioqIHN0YW5kcyBmb3IgKipieXBhc3MqKiwgYW5kIGl0IGFsbG93cyB5b3UgdG8gYXBwbHkgYSBzdHlsZSB0byBhIGdyb3VwIG9mIG5vZGVzIHRoYXQgeW91IHNlbGVjdC4KCgpUaGUgKipNYXAuKiogKG1hcHBpbmcpIGNvbHVtbiBhbGxvd3MgeW91IHRvIGNvbnRyb2wgdGhlIHZpc3VhbCBmZWF0dXJlcyBvZiB5b3VyIG5vZGVzIGFjY29yZGluZyB0byB0aGVpciBwcm9wZXJ0aWVzLiBGb3IgZXhhbXBsZSwgbGV0J3Mgc2F5IHlvdSdkIGxpa2UgYWxsIG9mIHRoZSBmaWxtcyBmcm9tIGEgcGFydGljdWxhciBzdHVkaW8gdG8gYXBwZWFyIGluIHBpbmsuIFlvdSBjYW4gZG8gdGhhdCBieSBtYXBwaW5nIHRoYXQgYXR0cmlidXRlIHRvIGEgcGFydGljdWxhciBjb2xvci4gT3IsIGxldCdzIHNheSB5b3UnZCBsaWtlIHRob3NlIG5vZGVzIHdpdGggbW9yZSBjb25uZWN0aW9ucyB0byBhcHBlYXIgbGFyZ2VyLiBZb3UgY2FuIGRvIHRoYXQgd2l0aCB0aGUgbWFwcGluZyBjb250cm9sLgoKClRoZSBwcm9ibGVtIGlzLCB3ZSBkb24ndCBoYXZlIGFueSBvZiB0aGF0IGluZm9ybWF0aW9uIGN1cnJlbnRseSBpbmNsdWRlZCBpbiBvdXIgbmV0d29yay4gU28gaW4gdGhlIG5leHQgdHV0b3JpYWwsIHdlJ2xsIGxvb2sgYXQgaG93IHRvIGxvYWQgdXAgKiphdHRyaWJ1dGVzKiogZm9yIG91ciBub2Rlcy4KCgooW09yIHlvdSBjYW4gc2tpcCBzdHJhaWdodCB0byBwdWJsaXNoaW5nIHlvdXIgbmV0d29yayBkaWFncmFtIV0oaHR0cHM6Ly9naXRodWIuY29tL21pcmlhbXBvc25lci9jeXRvc2NhcGVfdHV0b3JpYWxzL2Jsb2IvbWFzdGVyL3B1Ymxpc2hpbmcteW91ci1uZXR3b3JrLWRpYWdyYW0ubWQpKSAKCgohW10oaW1hZ2VzL0N1c3RvbWl6ZV9TdHlsZXMucG5nKQoKCgoKIyBTYXZpbmcgeW91ciBuZXR3b3JrCkN5dG9zY2FwZSBwcm92aWRlcyBhIG51bWJlciBvZiB3YXlzIHRvIHNhdmUgcmVzdWx0cyBhbmQgdmlzdWFsaXphdGlvbnM6CkFzIGEgc2Vzc2lvbjogKipGaWxlIOKGkiBTYXZlIFNlc3Npb24sIEZpbGUg4oaSIFNhdmUgU2Vzc2lvbiBBcy4uLioqCgohW10oaW1hZ2VzL1NhdmVfU2Vzc2lvbi5wbmcpCgoKQXMgYW4gaW1hZ2U6ICoqRmlsZSDihpIgRXhwb3J0IOKGkiBOZXR3b3JrIHRvIEltYWdlLi4uKioKCgohW10oaW1hZ2VzL0V4cG9ydF9JbWFnZS5wbmcpCgohW10oaW1hZ2VzL1NpZl9Gb3JtYXQucG5nKQoKCgpUbyB0aGUgd2ViOiAqKkZpbGUg4oaSIEV4cG9ydCDihpIgTmV0d29yayB0byBXZWIgUGFnZS4uLioqClRvIGEgcHVibGljIHJlcG9zaXRvcnk6ICoqRmlsZSDihpIgRXhwb3J0IOKGkiBOZXR3b3JrIHRvIE5ERXgqKgpBcyBhIGdyYXBoIGZvcm1hdCBmaWxlOiAqKkZpbGUg4oaSIEV4cG9ydCDihpIgTmV0d29yayB0byBGaWxlLioqCgoKKipGb3JtYXRzOioqCgoqIENYIEpTT04gLyBDWDIgSlNPTgoqIEN5dG9zY2FwZS5qcyBKU09OCiogR3JhcGhNTAoqIFBTSS1NSQoqIFhHTU1MCiogU0lGCgoKKipOb3cgbGV0IHVzIGJlZ2luIHRoZSBjb3Vyc2Ugd2l0aCB0aGUgZmlyc3Qgc2Vzc2lvbiAtIEludHJvZHVjdGlvbiB0byBDeXRvc2NhcGUgYW5kIGl0J3MgQXBwLiBbQ2xpY2sgaGVyZTpdKHNlc3Npb24xYS5uYi5odG1sKSAqKgo=