This note introduces software programs and platforms that
could be used in this course.
R & RStudio
1. What is R?
R is a language and environment for statistical computing and
graphics. It is a GNU project which is similar to the S language and
environment which was developed at Bell Laboratories (formerly AT&T,
now Lucent Technologies) by John Chambers and colleagues. R can be
considered as a different implementation of S. There are some important
differences, but much code written for S runs unaltered under R.
R is an integrated suite of software facilities for data
manipulation, calculation, and graphical display. It includes
- an effective data handling and storage facility,
- a suite of operators for calculations on arrays, in particular
matrices,
- a large, coherent, integrated collection of intermediate tools for
data analysis,
- graphical facilities for data analysis and display either on-screen
or on hardcopy, and
- a well-developed, simple, and effective programming language which
includes conditionals, loops, user-defined recursive functions, and
input and output facilities.
– https://www.r-project.org/about.html
2. RStudio
RStudio is an integrated development environment (IDE) for R. It
includes a console, and syntax-highlighting editor that supports direct
code execution, as well as tools for plotting, history, debugging, and
workspace management.
There are two versions of RStudio: RStudio Desktop and RStudio
Server. Both versions have free open-source and commercial editions. We
use the free open-source edition of RStudio Desktop that has the
following features:
- Access RStudio locally
- Syntax highlighting, code completion, and smart indentation
- Execute R code directly from the source editor
- Quickly jump to function definitions
- View content changes in real time with the Visual Markdown
Editor
- Easily manage multiple working directories using projects
- Integrated R help and documentation
- Interactive debugger to diagnose and fix errors
- Extensive package development tools
3. The Relationship between R and RStudio
R and RStudio are two distinctly different applications that serve
different purposes. R is a programming language used for statistical
computing while RStudio uses the R language to develop statistical
programs.
R and RStudio are not separate versions of the same program and
cannot be substituted for one another. R may be used without RStudio,
but RStudio may not be used without R.
RPubs
What is RPubs?
Register An Account with RPubs
First of all, you need to sign up for an account with RPubs if you
don’t have one. Otherwise, sign in to your existing RPubs account. The
following two hyperlink buttons will bring you to the appropriate
website.
Requirements
Your deed to install a recent version of You’ll need R
itself, RStudio
, and the knitr
package on your
machine.
Steps for Publishing on RPubs
In RStudio, create a new R Markdown document by choosing
File
| New
| R Markdown
.
Click the Knit HTML
button in the doc toolbar to
preview your document.
In the preview window, click
button.
Github
What is Github?
GitHub is a social networking site for programmers to share their
code. Many companies and organizations use it to facilitate project
management and collaboration. It is the most prominent source code host,
with over 60 million new repositories.
Most importantly, it is free. We can also use this resource to host
web pages. Many images and data sets that I used are stored on
GitHub.
Register A Github Account
You can use the following two buttons to sign up for an account with
Github or sign in to an existing Github account.
Getting Started with GitHub
We will use screenshots to demonstrate how to create a repository,
folders, and files.
- After you logged into your account, you click the “continue for
free” button located at the bottom of the following page
(screenshot)
- Now you see your Github front page. Click the green button “create
repository” on the left panel. Our first repository is called
“sta553”
- To organize files in the repository
sta553
, We want
folders for different files. To create a folder under
sta553
, click the hyperlink `creating a new file
- The first folder to create is called the
data
folder
which will be used to store data files. After typing “data/”, a new box
appears under the “data” folder, type the first file name - readme, and
the content of the file (see the screenshot). In the end, click the
green button “Commit new file” to complete the creation of the first
folder in the repository data
.
- To load the data file to the
data
folder, we click the
drop-down menu on the top right corner and select `upload files
- To create other folders under
sta553
, we click
Creating New File
, and we can create a new folder
image
similarly.
- To create a new repository, Click the drop-down menu on the top
right corner and select
New repository
to create a new
repository.
SAS OnDemand
1. What is SAS OnDemand (SAS Studio)
SAS OnDemand provides free data management and data
analysis tools. The advantage of SAS OnDemand is that it does not
require any installation and it runs on the cloud via the internet and
process data by connecting to the SAS server in the cloud. In other
words, your computer is only used as a monitor since it does not use any
resources (memory and CPU) of your computer.
Click Access
to enter the SAS OnDemand login page.
2. Sign-in / Sign-up
If you have already created your SAS Profile, use the email or user
ID and the password to log into the SAS OnDemand page.
3. Create An SAS Profile
If you don’t have a SAS profile, click the link
Don't have a SAS profile?
, and you will have the following
pop-up dialogue box. Click Create profile
, then you will
see a pop-up sign-up page. You then follow the direction to create your
SAS profile.
4. Log Into SAS Academic OnDemand
Provide your profile information to log into the OnDemand page, you
will see the link to the SAS Studio user interface and your account
information as well.
Once you created a SAS profile, you will have 5 GB of free
storage.
5. SAS Studio User Interfacce
In the Applications
tab, click SAS Studio
,
and you see the SAS Studio user interface on a separate page (it may
take a little bit of time to initialize your account if you use it for
the first time).
The above screenshot was taken from my SAS course webpage. For those
who learned SAS using the classical SAS, you will see SAS Studio is much
more convenient and easier to use.
A Cautionary Note on Data Security
SAS Studio (Academic OnDemand) is installed on
SAS servers hosted in the Microsoft Azure Cloud. Although SAS claims
that your assigned storage is private and secured, it is suggested to
avoid uploading sensitive data
to your private storage on
the SAS server since SAS does not release the level of security for the
storage.
R Viz Libraries
The following libraries will be used throughout this class.
1. Tidyverse
2. ggplot2
Ggplot2 is a system for creating charts based on the Grammar of
Graphics. It proved to be one of the most powerful R libraries for
visualization.
3. plotly
Plotly
is an online platform for data visualization in R
(also available in Python). This package creates interactive web-based
plots using plotly.js
library. Plotly gives users an
opportunity to interact with graphs, change their scale and point out
the necessary record. The library also supports graph hovering.
Moreover, one can easily add Plotly in knitr/R Markdown or Shiny
apps.
4. leaflet
Leaflet is a well-known package based on JavaScript libraries for
interactive maps. It is widely used for mapping and working with the
customization and design of interactive maps. Besides, Leaflet provides
an opportunity to make these maps mobile-friendly.
5. mapview
6. tmap
7. Other infrequently used packages
ggmap
, map
, dygraph
,
LS0tDQp0aXRsZTogIk9wZW4tU291cmNlIFRvb2xzIg0KYXV0aG9yOiAiQ2hlbmcgUGVuZyINCmRhdGU6ICJXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCmBgYHs9aHRtbH0NCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoNCmRpdiNUT0MgbGkgew0KICAgIGxpc3Qtc3R5bGU6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQp9DQpoMS50aXRsZSB7DQogIGZvbnQtc2l6ZTogMjRweDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYWNlOiBib2xkOw0KfQ0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhY2U6IGJvbGQ7DQp9DQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtZmFjZTogYm9sZDsNCn0NCmgxIHsgLyogSGVhZGVyIDEgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIycHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KICAgIGZvbnQtZmFjZTogYm9sZDsNCn0NCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCiAgICBmb250LWZhY2U6IGJvbGQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE1cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgZm9udC1mYWNlOiBib2xkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCiAgICBmb250LWZhY2U6IGJvbGQ7DQp9DQoNCi8qIFRhYiBmZWF0dXJlcyAqLw0KLm5hdj5saT5hIHsNCiAgICBwb3NpdGlvbjogcmVsYXRpdmU7DQogICAgZGlzcGxheTogYmxvY2s7DQogICAgcGFkZGluZzogMTBweCAxNXB4Ow0KICAgIGNvbG9yOiAjOTkwMDAwOw0KfQ0KLm5hdi1waWxscz5saS5hY3RpdmU+YSwgLm5hdi1waWxscz5saS5hY3RpdmU+YTpob3ZlciwgLm5hdi1waWxscz5saS5hY3RpdmU+YTpmb2N1cyB7DQogICAgY29sb3I6ICNmZmZmZmY7DQogICAgYmFja2dyb3VuZC1jb2xvcjogIzk5MDAwMDsNCn0NCi8qDQpuYXYtcGlsbHM+bGk6bnRoLWNoaWxkKDIpIHsNCiAgICBiYWNrZ3JvdW5kOiBncmVlbjsNCiB9DQogKi8NCjwvc3R5bGU+DQpgYGANCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCiAgIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJjb3dwbG90IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImNvd3Bsb3QiKQ0KICAgbGlicmFyeShjb3dwbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJsYXRleDJleHAiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygibGF0ZXgyZXhwIikNCiAgIGxpYnJhcnkobGF0ZXgyZXhwKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikNCiAgIGxpYnJhcnkocGxvdGx5KQ0KfQ0KaWYgKCFyZXF1aXJlKCJnYXBtaW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2FwbWluZGVyIikNCiAgIGxpYnJhcnkoZ2FwbWluZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbmciKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoInBuZyIpICAgICAjIEluc3RhbGwgcG5nIHBhY2thZ2UNCiAgICBsaWJyYXJ5KCJwbmciKQ0KfQ0KaWYgKCFyZXF1aXJlKCJSQ3VybCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiUkN1cmwiKSAgICAjIEluc3RhbGwgUkN1cmwgcGFja2FnZQ0KICAgIGxpYnJhcnkoIlJDdXJsIikNCn0NCmlmICghcmVxdWlyZSgiY29sb3VycGlja2VyIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJjb2xvdXJwaWNrZXIiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiY29sb3VycGlja2VyIikNCn0NCmlmICghcmVxdWlyZSgiZ2dhbmltYXRlIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnZ2FuaW1hdGUiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2dhbmltYXRlIikNCn0NCmlmICghcmVxdWlyZSgiZ2lmc2tpIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnaWZza2kiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2lmc2tpIikNCn0NCmlmICghcmVxdWlyZSgibWFnaWNrIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJtYWdpY2siKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgibWFnaWNrIikNCn0NCmlmICghcmVxdWlyZSgiZ3JEZXZpY2VzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnckRldmljZXMiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ3JEZXZpY2VzIikNCn0NCmlmICghcmVxdWlyZSgianBlZyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygianBlZyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJqcGVnIikNCn0NCiMga25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSAiQzovVXNlcnMvNzVDUEVORy9PbmVEcml2ZSAtIFdlc3QgQ2hlc3RlciBVbml2ZXJzaXR5IG9mIFBBL0RvY3VtZW50cyIpDQojIGtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gIkM6XFxTVEE0OTBcXHcwNSIpDQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFRSVUUsICAgDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFKQ0KYGBgDQoNCg0KDQojIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQ0KDQo8QlI+PEJSPg0KVGhpcyBub3RlIGludHJvZHVjZXMgc29mdHdhcmUgcHJvZ3JhbXMgYW5kIHBsYXRmb3JtcyB0aGF0IGNvdWxkIGJlIHVzZWQgaW4gdGhpcyBjb3Vyc2UuDQo8QlI+PEJSPg0KDQoNCg0KIyMgUiAmIFJTdHVkaW8NCg0KXA0KDQojIyMgMS4gV2hhdCBpcyBSPw0KPEJSPg0KPGNlbnRlcj48YSBocmVmPSJodHRwczovL3d3dy5yLXByb2plY3Qub3JnLyI+PGltZyBzcmMgPSAiaHR0cHM6Ly93d3cuci1wcm9qZWN0Lm9yZy9SbG9nby5wbmciIHdpZHRoID0gMTAwIGhlaWdodCA9IDEwMD48L2E+PC9jZW50ZXI+DQo8QlI+DQpSIGlzIGEgbGFuZ3VhZ2UgYW5kIGVudmlyb25tZW50IGZvciBzdGF0aXN0aWNhbCBjb21wdXRpbmcgYW5kIGdyYXBoaWNzLiBJdCBpcyBhIEdOVSBwcm9qZWN0IHdoaWNoIGlzIHNpbWlsYXIgdG8gdGhlIFMgbGFuZ3VhZ2UgYW5kIGVudmlyb25tZW50IHdoaWNoIHdhcyBkZXZlbG9wZWQgYXQgQmVsbCBMYWJvcmF0b3JpZXMgKGZvcm1lcmx5IEFUJlQsIG5vdyBMdWNlbnQgVGVjaG5vbG9naWVzKSBieSBKb2huIENoYW1iZXJzIGFuZCBjb2xsZWFndWVzLiBSIGNhbiBiZSBjb25zaWRlcmVkIGFzIGEgZGlmZmVyZW50IGltcGxlbWVudGF0aW9uIG9mIFMuIFRoZXJlIGFyZSBzb21lIGltcG9ydGFudCBkaWZmZXJlbmNlcywgYnV0IG11Y2ggY29kZSB3cml0dGVuIGZvciBTIHJ1bnMgdW5hbHRlcmVkIHVuZGVyIFIuIA0KDQpSIGlzIGFuIGludGVncmF0ZWQgc3VpdGUgb2Ygc29mdHdhcmUgZmFjaWxpdGllcyBmb3IgZGF0YSBtYW5pcHVsYXRpb24sIGNhbGN1bGF0aW9uLCBhbmQgZ3JhcGhpY2FsIGRpc3BsYXkuIEl0IGluY2x1ZGVzDQoNCiogYW4gZWZmZWN0aXZlIGRhdGEgaGFuZGxpbmcgYW5kIHN0b3JhZ2UgZmFjaWxpdHksDQoqIGEgc3VpdGUgb2Ygb3BlcmF0b3JzIGZvciBjYWxjdWxhdGlvbnMgb24gYXJyYXlzLCBpbiBwYXJ0aWN1bGFyIG1hdHJpY2VzLA0KKiBhIGxhcmdlLCBjb2hlcmVudCwgaW50ZWdyYXRlZCBjb2xsZWN0aW9uIG9mIGludGVybWVkaWF0ZSB0b29scyBmb3IgZGF0YSBhbmFseXNpcywNCiogZ3JhcGhpY2FsIGZhY2lsaXRpZXMgZm9yIGRhdGEgYW5hbHlzaXMgYW5kIGRpc3BsYXkgZWl0aGVyIG9uLXNjcmVlbiBvciBvbiBoYXJkY29weSwgYW5kDQoqIGEgd2VsbC1kZXZlbG9wZWQsIHNpbXBsZSwgYW5kIGVmZmVjdGl2ZSBwcm9ncmFtbWluZyBsYW5ndWFnZSB3aGljaCBpbmNsdWRlcyBjb25kaXRpb25hbHMsIGxvb3BzLCB1c2VyLWRlZmluZWQgcmVjdXJzaXZlIGZ1bmN0aW9ucywgYW5kIGlucHV0IGFuZCBvdXRwdXQgZmFjaWxpdGllcy4NCg0KLS0gPGh0dHBzOi8vd3d3LnItcHJvamVjdC5vcmcvYWJvdXQuaHRtbD4NCg0KIyMjIDIuIFJTdHVkaW8NCjxCUj4NCjxjZW50ZXI+PGEgaHJlZj0iaHR0cHM6Ly93d3cucnN0dWRpby5jb20vcHJvZHVjdHMvcnN0dWRpby8iPjxpbWcgc3JjID0gImh0dHBzOi8vd3d3LnJzdHVkaW8uY29tL2Fzc2V0cy9pbWcvbG9nby5zdmciIHdpZHRoID0gMTAwIGhlaWdodCA9IDEwMD48L2E+PC9jZW50ZXI+DQo8QlI+DQoNClJTdHVkaW8gaXMgYW4gaW50ZWdyYXRlZCBkZXZlbG9wbWVudCBlbnZpcm9ubWVudCAoSURFKSBmb3IgUi4gSXQgaW5jbHVkZXMgYSBjb25zb2xlLCBhbmQgc3ludGF4LWhpZ2hsaWdodGluZyBlZGl0b3IgdGhhdCBzdXBwb3J0cyBkaXJlY3QgY29kZSBleGVjdXRpb24sIGFzIHdlbGwgYXMgdG9vbHMgZm9yIHBsb3R0aW5nLCBoaXN0b3J5LCBkZWJ1Z2dpbmcsIGFuZCB3b3Jrc3BhY2UgbWFuYWdlbWVudC4NCg0KVGhlcmUgYXJlIHR3byB2ZXJzaW9ucyBvZiBSU3R1ZGlvOiBSU3R1ZGlvIERlc2t0b3AgYW5kIFJTdHVkaW8gU2VydmVyLiBCb3RoIHZlcnNpb25zIGhhdmUgZnJlZSBvcGVuLXNvdXJjZSBhbmQgY29tbWVyY2lhbCBlZGl0aW9ucy4gV2UgdXNlIHRoZSBmcmVlIG9wZW4tc291cmNlIGVkaXRpb24gb2YgUlN0dWRpbyBEZXNrdG9wIHRoYXQgaGFzIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXM6DQoNCiogQWNjZXNzIFJTdHVkaW8gbG9jYWxseQ0KKiBTeW50YXggaGlnaGxpZ2h0aW5nLCBjb2RlIGNvbXBsZXRpb24sIGFuZCBzbWFydCBpbmRlbnRhdGlvbg0KKiBFeGVjdXRlIFIgY29kZSBkaXJlY3RseSBmcm9tIHRoZSBzb3VyY2UgZWRpdG9yDQoqIFF1aWNrbHkganVtcCB0byBmdW5jdGlvbiBkZWZpbml0aW9ucw0KKiBWaWV3IGNvbnRlbnQgY2hhbmdlcyBpbiByZWFsIHRpbWUgd2l0aCB0aGUgVmlzdWFsIE1hcmtkb3duIEVkaXRvcg0KKiBFYXNpbHkgbWFuYWdlIG11bHRpcGxlIHdvcmtpbmcgZGlyZWN0b3JpZXMgdXNpbmcgcHJvamVjdHMNCiogSW50ZWdyYXRlZCBSIGhlbHAgYW5kIGRvY3VtZW50YXRpb24NCiogSW50ZXJhY3RpdmUgZGVidWdnZXIgdG8gZGlhZ25vc2UgYW5kIGZpeCBlcnJvcnMNCiogRXh0ZW5zaXZlIHBhY2thZ2UgZGV2ZWxvcG1lbnQgdG9vbHMNCg0KIyMjIDMuIFRoZSBSZWxhdGlvbnNoaXAgYmV0d2VlbiBSIGFuZCBSU3R1ZGlvDQoNClIgYW5kIFJTdHVkaW8gYXJlIHR3byBkaXN0aW5jdGx5IGRpZmZlcmVudCBhcHBsaWNhdGlvbnMgdGhhdCBzZXJ2ZSBkaWZmZXJlbnQgcHVycG9zZXMuIFIgaXMgYSBwcm9ncmFtbWluZyBsYW5ndWFnZSB1c2VkIGZvciBzdGF0aXN0aWNhbCBjb21wdXRpbmcgd2hpbGUgUlN0dWRpbyB1c2VzIHRoZSBSIGxhbmd1YWdlIHRvIGRldmVsb3Agc3RhdGlzdGljYWwgcHJvZ3JhbXMuDQoNClIgYW5kIFJTdHVkaW8gYXJlIG5vdCBzZXBhcmF0ZSB2ZXJzaW9ucyBvZiB0aGUgc2FtZSBwcm9ncmFtIGFuZCBjYW5ub3QgYmUgc3Vic3RpdHV0ZWQgZm9yIG9uZSBhbm90aGVyLiBSIG1heSBiZSB1c2VkIHdpdGhvdXQgUlN0dWRpbywgYnV0IFJTdHVkaW8gbWF5IG5vdCBiZSB1c2VkIHdpdGhvdXQgUi4NCg0KDQojIyBSUHVicw0KDQojIyMgV2hhdCBpcyBSUHVicz8NCjxicj4NCjxjZW50ZXI+PGltZyBzcmM9Imh0dHBzOi8vZ2l0aHViLmNvbS9wZW5nZHNjaS9zdGE1NTMvYmxvYi9tYWluL2ltYWdlL1JQdWJzQmFubmVyLnBuZz9yYXc9dHJ1ZSIgIGhlaWdodD0iMjUwIiB3aWR0aD0iNjAwIj48L2NlbnRlcj4NCjxicj4NCg0KIyMjIFJlZ2lzdGVyIEFuIEFjY291bnQgd2l0aCBSUHVicw0KDQpGaXJzdCBvZiBhbGwsIHlvdSBuZWVkIHRvIHNpZ24gdXAgZm9yIGFuIGFjY291bnQgd2l0aCBSUHVicyBpZiB5b3UgZG9uJ3QgaGF2ZSBvbmUuIE90aGVyd2lzZSwgc2lnbiBpbiB0byB5b3VyIGV4aXN0aW5nIFJQdWJzIGFjY291bnQuIFRoZSBmb2xsb3dpbmcgdHdvIGh5cGVybGluayBidXR0b25zIHdpbGwgYnJpbmcgeW91IHRvIHRoZSBhcHByb3ByaWF0ZSB3ZWJzaXRlLg0KPEJSPjxCUj4NCg0KPGNlbnRlcj4NCjxhIGhyZWY9Imh0dHBzOi8vcnB1YnMuY29tL2F1dGgvbG9naW4iIHRhcmdldD0icG9wdXAiICAgICAgICAgICAgICAgICAgICAgICAgICAgb25jbGljaz0id2luZG93Lm9wZW4oJ2h0dHBzOi8vcnB1YnMuY29tL2F1dGgvbG9naW4nKSI+PGltZyBzcmM9Imh0dHBzOi8vZ2l0aHViLmNvbS9wZW5nZHNjaS9zdGE1NTMvYmxvYi9tYWluL2ltYWdlL1NpZ25pbi5wbmc/cmF3PXRydWUiICBoZWlnaHQ9IjMwIiB3aWR0aD0iNjAiPjwvYT4gDQo8YSBocmVmPSJodHRwczovL3JwdWJzLmNvbS91c2Vycy9uZXciIHRhcmdldD0icG9wdXAiICAgICAgICAgICAgICAgICAgICAgICAgIG9uY2xpY2s9IndpbmRvdy5vcGVuKCdodHRwczovL3JwdWJzLmNvbS91c2Vycy9uZXcnKSI+PGltZyBzcmM9Imh0dHBzOi8vZ2l0aHViLmNvbS9wZW5nZHNjaS9zdGE1NTMvYmxvYi9tYWluL2ltYWdlL1JlZ2lzdGVyLnBuZz9yYXc9dHJ1ZSIgIGhlaWdodD0iMzAiIHdpZHRoPSI2NSI+PC9hPg0KPC9jZW50ZXI+DQoNCjxCUj4NCg0KIyMjIFJlcXVpcmVtZW50cw0KDQpZb3VyIGRlZWQgdG8gaW5zdGFsbCBhIHJlY2VudCB2ZXJzaW9uIG9mIFlvdeKAmWxsIG5lZWQgYFJgIGl0c2VsZiwgYFJTdHVkaW9gLCBhbmQgdGhlIGBrbml0cmAgcGFja2FnZSBvbiB5b3VyIG1hY2hpbmUuDQoNCiMjIyBTdGVwcyBmb3IgUHVibGlzaGluZyBvbiBSUHVicw0KDQoqIEluIFJTdHVkaW8sIGNyZWF0ZSBhIG5ldyBSIE1hcmtkb3duIGRvY3VtZW50IGJ5IGNob29zaW5nIGBGaWxlYCB8IGBOZXdgIHwgYFIgTWFya2Rvd25gLg0KDQoqIENsaWNrIHRoZSBgS25pdCBIVE1MYCBidXR0b24gaW4gdGhlIGRvYyB0b29sYmFyIHRvIHByZXZpZXcgeW91ciBkb2N1bWVudC4NCg0KKiBJbiB0aGUgcHJldmlldyB3aW5kb3csIGNsaWNrIDxpbWcgc3JjPSJodHRwczovL2dpdGh1Yi5jb20vcGVuZ2RzY2kvc3RhNTUzL2Jsb2IvbWFpbi9pbWFnZS9wdWJsaXNoLnBuZz9yYXc9dHJ1ZSIgaGVpZ2h0PSIyMiIgd2lkdGg9Ijg1Ij4gYnV0dG9uLg0KDQoNCiMjIEdpdGh1Yg0KDQojIyMgV2hhdCBpcyBHaXRodWI/DQoNCkdpdEh1YiBpcyBhIHNvY2lhbCBuZXR3b3JraW5nIHNpdGUgZm9yIHByb2dyYW1tZXJzIHRvIHNoYXJlIHRoZWlyIGNvZGUuIE1hbnkgY29tcGFuaWVzIGFuZCBvcmdhbml6YXRpb25zIHVzZSBpdCB0byBmYWNpbGl0YXRlIHByb2plY3QgbWFuYWdlbWVudCBhbmQgY29sbGFib3JhdGlvbi4gSXQgaXMgdGhlIG1vc3QgcHJvbWluZW50IHNvdXJjZSBjb2RlIGhvc3QsIHdpdGggb3ZlciA2MCBtaWxsaW9uIG5ldyByZXBvc2l0b3JpZXMuDQoNCk1vc3QgaW1wb3J0YW50bHksIGl0IGlzIGZyZWUuIFdlIGNhbiBhbHNvIHVzZSB0aGlzIHJlc291cmNlIHRvIGhvc3Qgd2ViIHBhZ2VzLiBNYW55IGltYWdlcyBhbmQgZGF0YSBzZXRzIHRoYXQgSSB1c2VkIGFyZSBzdG9yZWQgb24gR2l0SHViLg0KDQo8YnI+DQo8Y2VudGVyPjxpbWcgc3JjPSJodHRwczovL2dpdGh1Yi5jb20vcGVuZ2RzY2kvc3RhNTUzL2Jsb2IvbWFpbi9pbWFnZS9naXRodWIucG5nP3Jhdz10cnVlIiAgaGVpZ2h0PSIzNjAiIHdpZHRoPSI1NTAiPjwvY2VudGVyPg0KPGJyPg0KDQoNCiMjIyBSZWdpc3RlciBBIEdpdGh1YiBBY2NvdW50DQoNCllvdSBjYW4gdXNlIHRoZSBmb2xsb3dpbmcgdHdvIGJ1dHRvbnMgdG8gc2lnbiB1cCBmb3IgYW4gYWNjb3VudCB3aXRoIEdpdGh1YiBvciBzaWduIGluIHRvIGFuIGV4aXN0aW5nIEdpdGh1YiBhY2NvdW50Lg0KDQo8Y2VudGVyPg0KPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2xvZ2luIiB0YXJnZXQ9InBvcHVwIiAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uY2xpY2s9IndpbmRvdy5vcGVuKCdodHRwczovL2dpdGh1Yi5jb20vbG9naW4nKSI+PGltZyBzcmM9Imh0dHBzOi8vZ2l0aHViLmNvbS9wZW5nZHNjaS9zdGE1NTMvYmxvYi9tYWluL2ltYWdlL1NpZ25pbi5wbmc/cmF3PXRydWUiICBoZWlnaHQ9IjMwIiB3aWR0aD0iNjAiPjwvYT4gDQo8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2lnbnVwP3JlZl9jdGE9U2lnbit1cCZyZWZfbG9jPWhlYWRlcitsb2dnZWQrb3V0JnJlZl9wYWdlPSUyRiZzb3VyY2U9aGVhZGVyLWhvbWUiIHRhcmdldD0icG9wdXAiICAgICAgICAgICAgICAgICAgICAgICAgIG9uY2xpY2s9IndpbmRvdy5vcGVuKCdodHRwczovL2dpdGh1Yi5jb20vc2lnbnVwP3JlZl9jdGE9U2lnbit1cCZyZWZfbG9jPWhlYWRlcitsb2dnZWQrb3V0JnJlZl9wYWdlPSUyRiZzb3VyY2U9aGVhZGVyLWhvbWUnKSI+PGltZyBzcmM9Imh0dHBzOi8vZ2l0aHViLmNvbS9wZW5nZHNjaS9zdGE1NTMvYmxvYi9tYWluL2ltYWdlL1JlZ2lzdGVyLnBuZz9yYXc9dHJ1ZSIgIGhlaWdodD0iMzAiIHdpZHRoPSI2NSI+PC9hPg0KPC9jZW50ZXI+DQo8QlI+DQoNCiMjIyBHZXR0aW5nIFN0YXJ0ZWQgd2l0aCBHaXRIdWINCg0KV2Ugd2lsbCB1c2Ugc2NyZWVuc2hvdHMgdG8gZGVtb25zdHJhdGUgaG93IHRvIGNyZWF0ZSBhIHJlcG9zaXRvcnksIGZvbGRlcnMsIGFuZCBmaWxlcy4NCg0KMS4gQWZ0ZXIgeW91IGxvZ2dlZCBpbnRvIHlvdXIgYWNjb3VudCwgeW91IGNsaWNrIHRoZSAiY29udGludWUgZm9yIGZyZWUiIGJ1dHRvbiBsb2NhdGVkIGF0IHRoZSBib3R0b20gb2YgdGhlIGZvbGxvd2luZyBwYWdlIChzY3JlZW5zaG90KQ0KDQo8YnI+DQo8Y2VudGVyPjxpbWcgc3JjPSJodHRwczovL2dpdGh1Yi5jb20vcGVuZ2RzY2kvc3RhNTUzL2Jsb2IvbWFpbi9pbWFnZS9GcmVlR2l0aHViLnBuZz9yYXc9dHJ1ZSIgIGhlaWdodD0iMjUwIiB3aWR0aD0iNTUwIj48L2NlbnRlcj4NCjxicj4NCg0KMi4gTm93IHlvdSBzZWUgeW91ciBHaXRodWIgZnJvbnQgcGFnZS4gQ2xpY2sgdGhlIGdyZWVuIGJ1dHRvbiAiY3JlYXRlIHJlcG9zaXRvcnkiIG9uIHRoZSBsZWZ0IHBhbmVsLiBPdXIgZmlyc3QgcmVwb3NpdG9yeSBpcyBjYWxsZWQgInN0YTU1MyINCg0KPGJyPg0KPGNlbnRlcj48aW1nIHNyYz0iaHR0cHM6Ly9naXRodWIuY29tL3Blbmdkc2NpL3N0YTU1My9ibG9iL21haW4vaW1hZ2UvR2l0aHViRnJvbnRQYWdlLnBuZz9yYXc9dHJ1ZSIgIGhlaWdodD0iMjgwIiB3aWR0aD0iNTUwIj48L2NlbnRlcj4NCjxicj4NCg0KMy4gVG8gb3JnYW5pemUgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgYHN0YTU1M2AsIFdlIHdhbnQgZm9sZGVycyBmb3IgZGlmZmVyZW50IGZpbGVzLiBUbyBjcmVhdGUgYSBmb2xkZXIgdW5kZXIgYHN0YTU1M2AsIGNsaWNrIHRoZSBoeXBlcmxpbmsgYGNyZWF0aW5nIGEgbmV3IGZpbGUNCg0KPGJyPg0KPGNlbnRlcj48aW1nIHNyYz0iaHR0cHM6Ly9naXRodWIuY29tL3Blbmdkc2NpL3N0YTU1My9ibG9iL21haW4vaW1hZ2UvQ3JlYXRlMXN0Rm9sZGVyLnBuZz9yYXc9dHJ1ZSIgIGhlaWdodD0iMjkwIiB3aWR0aD0iNTUwIj48L2NlbnRlcj4NCjxicj4NCg0KNC4gVGhlIGZpcnN0IGZvbGRlciB0byBjcmVhdGUgaXMgY2FsbGVkIHRoZSBgZGF0YWAgZm9sZGVyIHdoaWNoIHdpbGwgYmUgdXNlZCB0byBzdG9yZSBkYXRhIGZpbGVzLiBBZnRlciB0eXBpbmcgImRhdGEvIiwgYSBuZXcgYm94IGFwcGVhcnMgdW5kZXIgdGhlICJkYXRhIiBmb2xkZXIsIHR5cGUgdGhlIGZpcnN0IGZpbGUgbmFtZSAtIHJlYWRtZSwgYW5kIHRoZSBjb250ZW50IG9mIHRoZSBmaWxlIChzZWUgdGhlIHNjcmVlbnNob3QpLiBJbiB0aGUgZW5kLCBjbGljayB0aGUgZ3JlZW4gYnV0dG9uICJDb21taXQgbmV3IGZpbGUiIHRvIGNvbXBsZXRlIHRoZSBjcmVhdGlvbiBvZiB0aGUgZmlyc3QgZm9sZGVyIGluIHRoZSByZXBvc2l0b3J5IGBkYXRhYC4NCg0KPGJyPg0KPGNlbnRlcj48aW1nIHNyYz0iaHR0cHM6Ly9naXRodWIuY29tL3Blbmdkc2NpL3N0YTU1My9ibG9iL21haW4vaW1hZ2UvQ3JlYXRlMXN0RmlsZUluMXN0Rm9sZGVyLnBuZz9yYXc9dHJ1ZSIgIGhlaWdodD0iMzYwIiB3aWR0aD0iNTUwIj48L2NlbnRlcj4NCjxicj4NCg0KNS4gVG8gbG9hZCB0aGUgZGF0YSBmaWxlIHRvIHRoZSBgZGF0YWAgZm9sZGVyLCB3ZSBjbGljayB0aGUgZHJvcC1kb3duIG1lbnUgb24gdGhlIHRvcCByaWdodCBjb3JuZXIgYW5kIHNlbGVjdCBgdXBsb2FkIGZpbGVzDQoNCjxicj4NCjxjZW50ZXI+PGltZyBzcmM9Imh0dHBzOi8vZ2l0aHViLmNvbS9wZW5nZHNjaS9zdGE1NTMvYmxvYi9tYWluL2ltYWdlL0NyZWF0ZU5leHRGb2xkZXIucG5nP3Jhdz10cnVlIiAgaGVpZ2h0PSIzMDAiIHdpZHRoPSI2NTAiPjwvY2VudGVyPg0KPGJyPg0KDQo2LiBUbyBjcmVhdGUgb3RoZXIgZm9sZGVycyB1bmRlciBgc3RhNTUzYCwgd2UgY2xpY2sgYENyZWF0aW5nIE5ldyBGaWxlYCwgYW5kIHdlIGNhbiBjcmVhdGUgYSBuZXcgZm9sZGVyIGBpbWFnZWAgc2ltaWxhcmx5Lg0KDQo8YnI+DQo8Y2VudGVyPjxpbWcgc3JjPSJodHRwczovL2dpdGh1Yi5jb20vcGVuZ2RzY2kvc3RhNTUzL2Jsb2IvbWFpbi9pbWFnZS9DcmVhdGVOZXdJbWFnZUZvbGRlci5wbmc/cmF3PXRydWUiICBoZWlnaHQ9IjI5MCIgd2lkdGg9IjYwMCI+PC9jZW50ZXI+DQo8YnI+DQoNCjcuIFRvIGNyZWF0ZSBhIG5ldyByZXBvc2l0b3J5LCBDbGljayB0aGUgZHJvcC1kb3duIG1lbnUgb24gdGhlIHRvcCByaWdodCBjb3JuZXIgYW5kIHNlbGVjdCBgTmV3IHJlcG9zaXRvcnlgIHRvIGNyZWF0ZSBhIG5ldyByZXBvc2l0b3J5Lg0KDQo8YnI+DQo8Y2VudGVyPjxpbWcgc3JjPSJodHRwczovL2dpdGh1Yi5jb20vcGVuZ2RzY2kvc3RhNTUzL2Jsb2IvbWFpbi9pbWFnZS9DcmVhdGVOZXdSZXBvcy5wbmc/cmF3PXRydWUiICBoZWlnaHQ9IjI4MCIgd2lkdGg9IjYwMCI+PC9jZW50ZXI+DQo8YnI+DQoNCg0KIyMgU0FTIE9uRGVtYW5kDQoNCiMjIyAxLiBXaGF0IGlzIFNBUyBPbkRlbWFuZCAoU0FTIFN0dWRpbykNCg0KU0FTIE9uRGVtYW5kIHByb3ZpZGVzICoqZnJlZSoqIGRhdGEgbWFuYWdlbWVudCBhbmQgZGF0YSBhbmFseXNpcyB0b29scy4gVGhlIGFkdmFudGFnZSBvZiBTQVMgT25EZW1hbmQgaXMgdGhhdCBpdCBkb2VzIG5vdCByZXF1aXJlIGFueSBpbnN0YWxsYXRpb24gYW5kIGl0IHJ1bnMgb24gdGhlIGNsb3VkIHZpYSB0aGUgaW50ZXJuZXQgYW5kIHByb2Nlc3MgZGF0YSBieSBjb25uZWN0aW5nIHRvIHRoZSBTQVMgc2VydmVyIGluIHRoZSBjbG91ZC4gSW4gb3RoZXIgd29yZHMsIHlvdXIgY29tcHV0ZXIgaXMgb25seSB1c2VkIGFzIGEgbW9uaXRvciBzaW5jZSBpdCBkb2VzIG5vdCB1c2UgYW55IHJlc291cmNlcyAobWVtb3J5IGFuZCBDUFUpIG9mIHlvdXIgY29tcHV0ZXIuDQoNCjxicj4NCjxjZW50ZXI+PGltZyBzcmM9Imh0dHBzOi8vZ2l0aHViLmNvbS9wZW5nZHNjaS9zdGE1NTMvYmxvYi9tYWluL2ltYWdlL1NBU0VudHJ5UGFnZS5wbmc/cmF3PXRydWUiICBoZWlnaHQ9IjI4MCIgd2lkdGg9IjQwMCI+PC9jZW50ZXI+DQo8YnI+DQoNCkNsaWNrIGBBY2Nlc3NgIHRvIGVudGVyIHRoZSBTQVMgT25EZW1hbmQgbG9naW4gcGFnZS4NCg0KIyMjIDIuIFNpZ24taW4gLyBTaWduLXVwDQoNCklmIHlvdSBoYXZlIGFscmVhZHkgY3JlYXRlZCB5b3VyIFNBUyBQcm9maWxlLCB1c2UgdGhlIGVtYWlsIG9yIHVzZXIgSUQgYW5kIHRoZSBwYXNzd29yZCB0byBsb2cgaW50byB0aGUgU0FTIE9uRGVtYW5kIHBhZ2UuIA0KDQo8YnI+DQo8Y2VudGVyPjxpbWcgc3JjPSJodHRwczovL2dpdGh1Yi5jb20vcGVuZ2RzY2kvc3RhNTUzL2Jsb2IvbWFpbi9pbWFnZS9TQVNMb2dpbi5wbmc/cmF3PXRydWUiICBoZWlnaHQ9IjI4MCIgd2lkdGg9IjQwMCI+PC9jZW50ZXI+DQo8YnI+DQoNCg0KIyMjIDMuIENyZWF0ZSBBbiBTQVMgUHJvZmlsZQ0KDQpJZiB5b3UgZG9uJ3QgaGF2ZSBhIFNBUyBwcm9maWxlLCBjbGljayB0aGUgbGluayBgRG9uJ3QgaGF2ZSBhIFNBUyBwcm9maWxlP2AsIGFuZCB5b3Ugd2lsbCBoYXZlIHRoZSBmb2xsb3dpbmcgcG9wLXVwIGRpYWxvZ3VlIGJveC4gQ2xpY2sgYENyZWF0ZSBwcm9maWxlYCwgdGhlbiB5b3Ugd2lsbCBzZWUgYSBwb3AtdXAgc2lnbi11cCBwYWdlLiBZb3UgdGhlbiBmb2xsb3cgdGhlIGRpcmVjdGlvbiB0byBjcmVhdGUgeW91ciBTQVMgcHJvZmlsZS4NCg0KPGJyPg0KPGNlbnRlcj48aW1nIHNyYz0iaHR0cHM6Ly9naXRodWIuY29tL3Blbmdkc2NpL3N0YTU1My9ibG9iL21haW4vaW1hZ2UvU0FTMXN0VmlzaXQucG5nP3Jhdz10cnVlIiAgaGVpZ2h0PSI4MCIgd2lkdGg9IjMwMCI+PC9jZW50ZXI+DQo8YnI+DQoNCg0KIyMjIDQuIExvZyBJbnRvIFNBUyBBY2FkZW1pYyBPbkRlbWFuZA0KDQpQcm92aWRlIHlvdXIgcHJvZmlsZSBpbmZvcm1hdGlvbiB0byBsb2cgaW50byB0aGUgT25EZW1hbmQgcGFnZSwgeW91IHdpbGwgc2VlIHRoZSBsaW5rIHRvIHRoZSBTQVMgU3R1ZGlvIHVzZXIgaW50ZXJmYWNlIGFuZCB5b3VyIGFjY291bnQgaW5mb3JtYXRpb24gYXMgd2VsbC4gDQoNCjxicj4NCjxjZW50ZXI+PGltZyBzcmM9Imh0dHBzOi8vZ2l0aHViLmNvbS9wZW5nZHNjaS9zdGE1NTMvYmxvYi9tYWluL2ltYWdlL1NBU1Byb2ZpbGVGcm9udFBhZ2UucG5nP3Jhdz10cnVlIiAgaGVpZ2h0PSIyODAiIHdpZHRoPSI0MDAiPjwvY2VudGVyPg0KPGJyPg0KDQpPbmNlIHlvdSBjcmVhdGVkIGEgU0FTIHByb2ZpbGUsIHlvdSB3aWxsIGhhdmUgNSBHQiBvZiBmcmVlIHN0b3JhZ2UuIA0KDQojIyMgNS4gU0FTIFN0dWRpbyBVc2VyIEludGVyZmFjY2UNCg0KSW4gdGhlIGBBcHBsaWNhdGlvbnNgIHRhYiwgY2xpY2sgYFNBUyBTdHVkaW9gLCBhbmQgeW91IHNlZSB0aGUgU0FTIFN0dWRpbyB1c2VyIGludGVyZmFjZSBvbiBhIHNlcGFyYXRlIHBhZ2UgKGl0IG1heSB0YWtlIGEgbGl0dGxlIGJpdCBvZiB0aW1lIHRvIGluaXRpYWxpemUgeW91ciBhY2NvdW50IGlmIHlvdSB1c2UgaXQgZm9yIHRoZSBmaXJzdCB0aW1lKS4NCg0KPGJyPg0KPGNlbnRlcj48aW1nIHNyYz0iaHR0cHM6Ly9naXRodWIuY29tL3Blbmdkc2NpL3N0YTU1My9ibG9iL21haW4vaW1hZ2UvU0FTU3R1ZGlvVUkucG5nP3Jhdz10cnVlIiAgaGVpZ2h0PSIyODAiIHdpZHRoPSI1MDAiPjwvY2VudGVyPg0KPGJyPg0KDQpUaGUgYWJvdmUgc2NyZWVuc2hvdCB3YXMgdGFrZW4gZnJvbSBteSBTQVMgY291cnNlIHdlYnBhZ2UuIEZvciB0aG9zZSB3aG8gbGVhcm5lZCBTQVMgdXNpbmcgdGhlIGNsYXNzaWNhbCBTQVMsIHlvdSB3aWxsIHNlZSBTQVMgU3R1ZGlvIGlzIG11Y2ggbW9yZSBjb252ZW5pZW50IGFuZCBlYXNpZXIgdG8gdXNlLiANCg0KIyMjICoqQSBDYXV0aW9uYXJ5IE5vdGUgb24gRGF0YSBTZWN1cml0eSoqDQoNCjxmb250IGNvbG9yID0gInJlZCI+U0FTIFN0dWRpbyAoQWNhZGVtaWMgT25EZW1hbmQpIGlzIGluc3RhbGxlZCBvbiBTQVMgc2VydmVycyBob3N0ZWQgaW4gdGhlIE1pY3Jvc29mdCBBenVyZSBDbG91ZC4gQWx0aG91Z2ggU0FTIGNsYWltcyB0aGF0IHlvdXIgYXNzaWduZWQgc3RvcmFnZSBpcyBwcml2YXRlIGFuZCBzZWN1cmVkLCBpdCBpcyBzdWdnZXN0ZWQgdG8gYXZvaWQgdXBsb2FkaW5nIGBzZW5zaXRpdmUgZGF0YWAgdG8geW91ciBwcml2YXRlIHN0b3JhZ2Ugb24gdGhlIFNBUyBzZXJ2ZXIgc2luY2UgU0FTIGRvZXMgbm90IHJlbGVhc2UgdGhlIGxldmVsIG9mIHNlY3VyaXR5IGZvciB0aGUgc3RvcmFnZS48L2ZvbnQ+DQoNCg0KIyMgUiBWaXogTGlicmFyaWVzDQoNClRoZSBmb2xsb3dpbmcgbGlicmFyaWVzIHdpbGwgYmUgdXNlZCB0aHJvdWdob3V0IHRoaXMgY2xhc3MuDQoNCiMjIyAxLiBUaWR5dmVyc2UgDQoNCiMjIyAyLiBnZ3Bsb3QyDQoNCkdncGxvdDIgaXMgYSBzeXN0ZW0gZm9yIGNyZWF0aW5nIGNoYXJ0cyBiYXNlZCBvbiB0aGUgR3JhbW1hciBvZiBHcmFwaGljcy4gSXQgcHJvdmVkIHRvIGJlIG9uZSBvZiB0aGUgbW9zdCBwb3dlcmZ1bCBSIGxpYnJhcmllcyBmb3IgdmlzdWFsaXphdGlvbi4NCg0KDQojIyMgMy4gcGxvdGx5DQoNCmBQbG90bHlgIGlzIGFuIG9ubGluZSBwbGF0Zm9ybSBmb3IgZGF0YSB2aXN1YWxpemF0aW9uIGluIFIgKGFsc28gYXZhaWxhYmxlIGluIFB5dGhvbikuIFRoaXMgcGFja2FnZSBjcmVhdGVzIGludGVyYWN0aXZlIHdlYi1iYXNlZCBwbG90cyB1c2luZyBgcGxvdGx5LmpzYCBsaWJyYXJ5LiBQbG90bHkgZ2l2ZXMgdXNlcnMgYW4gb3Bwb3J0dW5pdHkgdG8gaW50ZXJhY3Qgd2l0aCBncmFwaHMsIGNoYW5nZSB0aGVpciBzY2FsZSBhbmQgcG9pbnQgb3V0IHRoZSBuZWNlc3NhcnkgcmVjb3JkLiBUaGUgbGlicmFyeSBhbHNvIHN1cHBvcnRzIGdyYXBoIGhvdmVyaW5nLiBNb3Jlb3Zlciwgb25lIGNhbiBlYXNpbHkgYWRkIFBsb3RseSBpbiBrbml0ci9SIE1hcmtkb3duIG9yIFNoaW55IGFwcHMuDQoNCg0KIyMjIDQuIGxlYWZsZXQNCg0KTGVhZmxldCBpcyBhIHdlbGwta25vd24gcGFja2FnZSBiYXNlZCBvbiBKYXZhU2NyaXB0IGxpYnJhcmllcyBmb3IgaW50ZXJhY3RpdmUgbWFwcy4gSXQgaXMgd2lkZWx5IHVzZWQgZm9yIG1hcHBpbmcgYW5kIHdvcmtpbmcgd2l0aCB0aGUgY3VzdG9taXphdGlvbiBhbmQgZGVzaWduIG9mIGludGVyYWN0aXZlIG1hcHMuIEJlc2lkZXMsIExlYWZsZXQgcHJvdmlkZXMgYW4gb3Bwb3J0dW5pdHkgdG8gbWFrZSB0aGVzZSBtYXBzIG1vYmlsZS1mcmllbmRseS4NCg0KIyMjIDUuIG1hcHZpZXcNCg0KIyMjIDYuIHRtYXANCg0KIyMjIDcuIE90aGVyIGluZnJlcXVlbnRseSB1c2VkIHBhY2thZ2VzDQoNCmBnZ21hcGAsIGBtYXBgLCBgZHlncmFwaGAsIA0KDQoNCg0KDQoNCg0K