Introduction
Data science is a dynamic field that focuses on gathering, analyzing,
and interpreting large datasets to uncover valuable insights through the
use of statistical techniques and machine learning methods. However, the
ultimate value of data science work lies not only in the quality of the
analysis but also in how effectively the results are communicated.
Effective technical communication is essential in ensuring that complex
findings are understood, acted upon, and used to make informed
decisions. This note outlines the key elements of effective technical
communication in data science, focusing on reporting, presentations, and
discussions.
Clarity and Simplicity in Reporting
One of the most critical elements of effective communication in data
science is clarity. Data science reports often deal with intricate
algorithms, statistical models, and large datasets, which can overwhelm
readers if presented poorly. Technical reports must avoid jargon and
complex terminology that might alienate non-expert audiences. While
technical accuracy is vital, the language should be accessible to a wide
audience, including stakeholders who may not have a deep understanding
of the methods used.
Clear communication can be achieved by structuring reports logically.
Each report should begin with an executive summary, outlining key
findings and their implications. This is followed by detailed sections
that explain the methodology, results, and conclusions. Finally,
recommendations should be presented clearly, based on the data’s
insights. To avoid information overload, the report should be concise,
with a focus on the most important points, using bullet points or tables
to summarize key findings.
Visualization: Making Complex Data Accessible
Effective data science communication relies heavily on the use of
visualizations. Data, in its raw form, can be challenging to interpret.
Charts, graphs, and other visual tools help to present data in a way
that is intuitive and comprehensible. Whether it’s a time series graph,
a heatmap, or a scatter plot, visualizations can highlight trends,
correlations, and outliers more effectively than raw numbers.
However, visualizations must be designed carefully to convey the
correct message. Poorly designed visuals can mislead or confuse the
audience. It’s essential to choose the right type of graph for the data,
use clear labels, and avoid unnecessary clutter. For example, when
presenting a correlation matrix, a heatmap with clear color gradients
can quickly communicate which variables are most closely related, making
it easier for the audience to understand the relationships within the
data.
Tailoring Communication to the Audience
Another important factor in effective technical communication is
knowing your audience. Data scientists often communicate their findings
to diverse groups, including executives, technical teams, and
non-technical stakeholders. Tailoring the depth and style of
communication according to the audience is crucial for ensuring that the
message is understood.
For business executives, the emphasis should be on actionable
insights rather than the technical details of the analysis. A summary of
the key findings, along with clear recommendations, is more valuable
than a deep dive into the algorithms used. On the other hand, for a
technical audience, the focus should be on the methods, assumptions, and
results of the analysis, allowing them to assess the validity of the
work themselves.
Understanding the audience’s needs also helps in choosing the
appropriate level of detail. Executives may only need a high-level
overview of the outcomes, while technical teams require a deeper
understanding of the data’s structure, modeling techniques, and
validation processes.
Storytelling: Framing Data Within a Narrative
In addition to clarity and audience awareness, storytelling is a
powerful technique in data science communication. Numbers and models may
seem abstract, but when framed within a narrative, they become more
relatable and memorable. Storytelling helps to connect the findings with
real-world problems and illustrates their implications in a way that
resonates with the audience.
A compelling data story begins by presenting the problem or challenge
that the data analysis seeks to address. The narrative should then
outline how the data was gathered, processed, and analyzed, before
leading into the key findings. Finally, the story should close with a
conclusion or recommendation that ties everything back to the initial
problem, showing how the insights can be used to make informed
decisions.
Precision and Accuracy
The importance of precision and accuracy in technical communication
cannot be overstated. Data science relies on the correct application of
mathematical models and statistical techniques, and any miscommunication
of these methods can lead to incorrect conclusions and, potentially,
harmful decisions. Whether in written reports, presentations, or
discussions, data scientists must ensure that the results are accurate,
and the assumptions behind their analysis are clearly stated.
It’s also important to emphasize the limitations of the analysis. No
model is perfect, and acknowledging potential errors or areas of
uncertainty can help build trust with the audience. For example,
discussing the confidence intervals around predictions or the
assumptions underlying a regression model provides context and allows
the audience to assess the reliability of the results.
Engaging Discussions
Finally, effective communication in data science extends beyond
written reports and presentations to interactive discussions. In these
settings, data scientists must be prepared to explain their work in a
conversational manner, answering questions, clarifying doubts, and
engaging with the audience. Active listening is critical here, as it
allows the communicator to address the audience’s concerns and adjust
the explanation accordingly.
Moreover, discussions provide an opportunity for feedback, which is
essential for improving the analysis. During discussions, data
scientists can clarify misunderstandings, explain complex concepts in
simpler terms, and fine-tune their message to ensure that it is
understood by all parties involved. This two-way communication helps to
ensure that the findings are interpreted correctly and can guide future
decisions.
Data Analysis
Workflow
The data science analysis workflow refers to the series of steps or
stages that data scientists follow to gather, process, analyze, and
interpret data in order to extract actionable insights. This workflow
can vary slightly depending on the specific project, but it typically
includes the following key stages.
Define Objectives and
Questions
In data science and machine learning projects, defining objectives
and questions accurately is crucial as they set the foundation for the
entire analysis and model development process. Clear objectives and
well-formulated questions guide data collection, feature engineering,
model selection, and result interpretation. Here’s how to define them
accurately.
Projects Objectives
Objectives describe the overall goal or purpose of the project. They
are the desired outcomes that the analysis or machine learning model
aims to achieve. In data science and machine learning projects,
objectives should be:
Clear and Specific: The objective should be
well-defined, leaving no ambiguity about what is to be achieved. For
example, predicting the likelihood of customer churn in the next
quarter.
Measurable: The objective should be quantifiable so that
progress can be tracked and success can be evaluated. For example,
Increasing prediction accuracy of churn rate by 15% over baseline
models.
Feasible: Ensure that the objective can be
realistically achieved within the constraints of data, time, and
resources available. For example, Building a model with at least 80%
accuracy based on available data sources.
Aligned Business Needs: The objective should address the
business problem or requirement of the stakeholders, whether they are
business leaders, researchers, or clients. For example, Providing
actionable insights to reduce customer churn in a subscription-based
business.
Formulating Analytic Questions
Analytic Questions are the specific inquiries that guide the
analysis or modeling process. These are more detailed than objectives
and often help in formulating hypotheses and defining the scope of the
project. Well-crafted questions should:
Be Relevant to the Problem: Analytic
Questions should directly relate to the problem you are solving
or the objective you aim to achieve. For example, What factors are most
strongly correlated with customer churn in the current dataset?
Be Actionable: Analytic Questions
should lead to findings or decisions that can be acted upon. For
example, can we identify potential high-risk customers who are likely to
churn within the next 3 months?
Be Clear and Focused: Analytic
Questions should be concise and precise. Avoid vague or broad
questions that may be difficult to address. For example, what are the
top predictors of house price variation in the market? (instead of What
determines house prices?)
Be Hypothesis-Driven: In many cases, analytic
questions will be based on a hypothesis you want to test
through the data. For example: Does the number of bedrooms in a house
significantly impact its price?
Be Testable with Data: Analytic
Questions should be formulated in a way that they can be
addressed using the available data and analysis techniques. For example:
Can we use customer demographic data to predict purchasing
behavior?
Account for Constraints: Consider whether the questions
can be answered within the available time, data, and resources. For
example, hHow can we predict the likelihood of loan approval based on
income, credit score, and employment history, given the available
data?
Some Well-crafted Example Analytic Questions
What are the key drivers of customer satisfaction in our online
retail platform?
Is there a significant relationship between income and spending
patterns in different demographic groups?
How can we improve the accuracy of fraud detection in credit card
transactions using machine learning models?
Data Collection and
Preparation
Data collection and preparation are crucial steps in the machine
learning (ML) pipeline, serving as the foundation for building effective
and reliable models. Without high-quality, relevant data, even the most
advanced machine learning algorithms are unlikely to deliver meaningful
or accurate results. This subsection explores the importance of data
collection and preparation in the context of machine learning, outlining
the processes involved, challenges faced, and best practices for
ensuring that data is suitable for analysis.
Data
Collection
Data collection is the first and most critical step in the machine
learning pipeline. It involves acquiring the data needed to solve a
specific problem. This step must focus on gathering data that is
relevant, diverse, and representative of the problem domain. The
following are key considerations during data collection:
Source Identification: The first step is
identifying the data sources. These can include internal databases,
public datasets, APIs, or third-party providers. The quality of the data
depends on the credibility and relevance of the sources. For example, in
the customer churn prediction modeling, data could be collected from
customer databases, transaction records, customer support interactions,
and web analytics.
Data Volume and Variety: A common challenge in
machine learning is collecting enough data to accurately represent the
problem. Machine learning models often perform better with large,
diverse datasets that capture the full range of possible inputs and
scenarios.
Data Relevance: The data collected must be
directly relevant to the task at hand. Irrelevant data not only adds
unnecessary complexity but can also introduce noise that hinders model
performance.
Data Privacy and Ethics: Collecting data must be
done ethically, ensuring that personal and sensitive information is
handled responsibly. This includes adhering to data protection
regulations like GDPR and obtaining informed consent from individuals
where necessary.
Data Integration: In many cases, data may come
from multiple sources, each with its own structure and format.
Integrating disparate datasets while ensuring consistency and integrity
is a vital part of the collection phase.
Data
Preparation
Once data has been collected, the next critical step is preparing it
for analysis. Data preparation encompasses several processes, including
cleaning, transformation, and feature engineering. The goal is to ensure
that the data is clean, complete, and in a format that is compatible
with machine learning algorithms. Key steps in data preparation
include:
Data Cleaning
Raw data is often messy and incomplete, containing errors,
inconsistencies, or missing values. Cleaning the data involves:
Handling Missing Values: Data may have missing
or null values due to errors in data collection or user behavior. These
missing values can be handled by removing rows, imputing missing values
based on other data points, or using algorithms that handle missing data
naturally.
Removing Duplicates: Duplicate records can skew
analysis and negatively affect model training. Identifying and removing
duplicates is a crucial step.
Fixing Errors: Errors in data, such as incorrect
labels, misformatted dates, or outliers, must be addressed to ensure
data quality.
Data Transformation: Data transformation
involves converting data into a usable format. This includes scaling,
normalizing, or encoding features to ensure that the machine learning
algorithm can process the data effectively.
Scaling and Normalization
Machine learning algorithms, especially those that rely on distance
metrics like k-nearest neighbors (KNN) or gradient descent, require
features to be on similar scales. Normalizing or standardizing the data
ensures that all features contribute equally to the model.
Encoding Categorical Variables: Many machine
learning algorithms cannot work directly with categorical variables
(e.g., gender, country, or product category). Techniques like one-hot
encoding or label encoding are used to convert these variables into
numerical form.
Feature Engineering: This process involves
creating new features or modifying existing ones to improve model
performance. For example, combining date and time fields into a “day of
the week” feature or calculating the difference between two timestamp
columns can provide more meaningful inputs for the model.
Data Splitting
To assess model performance and prevent overfitting, the dataset is
usually split into training, validation, and testing sets. The training
set is used to build the model, the validation set helps tune
hyperparameters, and the testing set evaluates the model’s
generalization ability.
Outlier Detection
Outliers are data points that differ significantly from others and
can distort the results of a model. Detecting and handling outliers is
crucial for preventing these values from negatively influencing the
model’s predictions.
Data Augmentation
In some cases, especially when working with images or text, data
augmentation techniques like rotation, cropping, or text paraphrasing
can be used to artificially expand the dataset and improve model
robustness.
Best Practices
To overcome these challenges and ensure successful machine learning
projects, the following best practices should be followed:
Understand the Problem Domain: Collaborate with
domain experts to ensure the data collected is relevant and useful for
the problem being solved.
Automate Data Collection: Whenever possible,
automate the data collection process to improve efficiency and
consistency.
Iterate and Refine: Data preparation is not a
one-time task. It’s important to iterate and refine the dataset as the
model is developed and as new data becomes available.
Document the Process: Keep detailed records of
the data collection and preparation steps. This ensures transparency and
reproducibility, which is especially important for collaborative and
regulatory compliance.
Test for Bias: Regularly test the data for bias
and ensure that the model is trained on representative and diverse
datasets.
In summary, data collection and preparation are
foundational steps in machine learning, directly influencing the quality
and effectiveness of the resulting models. Ensuring the data is
relevant, clean, and properly formatted is critical for developing
models that can make accurate predictions and provide valuable insights.
By carefully managing these stages, data scientists can build reliable,
scalable models that perform well in real-world applications. As machine
learning continues to evolve, mastering data collection and preparation
will remain an essential skill for data scientists and machine learning
practitioners.
Exploratory Data
Analysis (EDA)
Exploratory Data Analysis (EDA) is a crucial step in the machine
learning workflow, serving as an initial investigation into the dataset
to uncover underlying patterns, relationships, and potential issues. EDA
involves analyzing the data’s structure and distribution, generating
hypotheses, and identifying trends or anomalies that might influence
subsequent modeling decisions. It helps data scientists and machine
learning practitioners understand the data before diving into complex
algorithms, ensuring a better understanding of the dataset, improved
data preprocessing, and more effective model selection.
The Role of EDA in
Machine Learning
EDA provides a foundational understanding of the dataset, ensuring
that data scientists can make informed decisions during the modeling
phase. By exploring the data visually and statistically, EDA helps
identify key insights, detect errors, and reveal aspects of the data
that might otherwise remain hidden. This step is vital because the
quality of the data used in machine learning directly affects the
model’s performance, and the insights gained during EDA can guide
further data cleaning, feature engineering, and model refinement.
We next list some of the key steps in EDA.
1. Understanding the Dataset Structure
The first step in EDA is understanding the structure of the dataset.
This involves checking the number of rows (data points) and columns
(features), and understanding the data types of each feature (e.g.,
categorical, numerical, text). This step is fundamental for determining
how the data can be processed or transformed for analysis.
Example: A dataset with customer information may
include features like “age,” “income,” and “gender.” Understanding
whether these features are numerical or categorical helps in choosing
the right statistical techniques or machine learning algorithms.
2. Descriptive Statistics
Descriptive statistics summarize the central tendencies, variability,
and distribution of the data. Key metrics include the mean, median,
standard deviation, minimum, and maximum values for numerical features,
and frequency counts for categorical features. These statistics offer an
initial overview of the data’s characteristics, helping identify any
obvious data issues or skewed distributions.
Example: For a numerical feature like “age,”
checking the mean and standard deviation can highlight if there are
extreme outliers or if the data is heavily skewed.
3. Data Visualization
Visualizations are an essential part of EDA, allowing data scientists
to identify patterns, trends, and relationships between features more
intuitively. Common visualizations used in EDA include:
Histograms: Show the distribution of numerical data,
helping to understand the spread and skewness of variables.
Box Plots: Help identify outliers and the spread of
data, showing the median, quartiles, and any extreme values.
Scatter Plots: Show relationships between two numerical
variables and can highlight correlations or the absence of
them.
Correlation Heatmaps: Show the relationships between
different numerical features, highlighting correlations that could be
important for predictive modeling.
Example: A scatter plot of “age” vs. “income” might
reveal a trend where younger customers have lower income, while older
customers earn higher salaries. This insight could influence model
feature selection or transformation.
4. Handling Missing Data
One of the most common issues encountered in real-world data sets is
missing data. EDA helps identify which features have missing values, and
the extent of missingness. We will use a week to discuss various
imputation methods. No details will be provided in this note.
5. Identifying Outliers
Outliers are data points that differ significantly from the rest of
the dataset. EDA helps in identifying outliers that could skew model
performance or lead to incorrect predictions. Techniques such as box
plots or Z-scores are often used to detect these extreme values. In some
cases, outliers are genuine observations, while in others, they may be
errors that need to be addressed.
Example: In a dataset of house prices, an outlier
could be a mansion priced far below the market rate. This could either
be a rare but valid instance or an error in the data entry process that
requires correction.
6. Exploring Relationships Between Variables
EDA also involves investigating the relationships between variables.
This helps identify whether any features are correlated or if certain
variables influence others. For example, examining correlations between
independent variables and the target variable (in supervised learning)
can guide feature selection and help improve model performance.
Example: In a dataset predicting house prices,
variables such as “square footage” and “number of bedrooms” are likely
to have a strong positive correlation with the target variable,
“price.”
7. Feature Engineering and Transformation
During EDA, data scientists often begin to think about how to
transform features or create new ones. This might involve encoding
categorical variables, normalizing numerical features, or combining
features to extract new insights. EDA provides the context needed to
determine which transformations are necessary and how they should be
applied to the data.
Example: If “date” is a feature, it could be
transformed into multiple features such as “day of the week,” “month,”
or “season,” depending on the problem.
Importance of
EDA
Guiding Data Cleaning: EDA helps identify
inconsistencies, missing values, and outliers in the data that need to
be addressed before model training. By cleaning the data based on
insights from EDA, model performance can be significantly improved.
Improving Model Accuracy: Understanding the data’s
structure, relationships, and distributions helps select the right
machine learning model. For instance, knowing the target variable’s
distribution might help choose between regression and classification
models or influence the decision to use specific algorithms like
decision trees, random forests, or neural networks.
Preventing Overfitting: By visualizing the
relationships between features, EDA helps data scientists understand the
complexity of the model they are building. It allows them to decide
whether certain features should be included or whether some variables
might lead to overfitting.
Improving Interpretability: Visualizations and
statistical summaries created during EDA provide insights that can
improve the interpretability of the machine learning model. Clear
visualizations help stakeholders better understand the model and the
results it generates.
In summary, EDA is an essential process in the machine learning
pipeline, providing data scientists with a deep understanding of the
dataset before building models. By summarizing the data through
descriptive statistics, visualizing key relationships, and addressing
potential issues such as missing data and outliers, EDA ensures that
machine learning models are based on a solid foundation. Through
effective EDA, practitioners can improve model accuracy, prevent biases,
and make more informed decisions about data preprocessing, feature
engineering, and model selection. Ultimately, EDA enhances the
reliability and success of machine learning projects.
Optimal Model
Identification
Identifying the right model and algorithm is essential for achieving
high-performance results. The process of identifying the optimal models
and algorithms is a fundamental task that can significantly influence
the accuracy, efficiency, and interpretability of machine learning
solutions. This subsection explores the importance of model and
algorithm selection, the factors that influence these decisions, and the
process of identifying the best model for a given task.
Machine learning encompasses a wide variety of tasks, such as
classification, regression, clustering, and reinforcement learning, each
requiring different approaches and algorithms. Given the broad range of
available models and algorithms, it is essential to choose the most
suitable one for the problem at hand. The right model or algorithm can
help to uncover patterns in the data, make accurate predictions, and
deliver actionable insights.
However, choosing the optimal model is not always straightforward. It
requires an understanding of the problem domain, the nature of the data,
and the performance metrics that matter most to stakeholders.
Incorrectly selecting a model or algorithm can lead to overfitting,
underfitting, or inefficient computation, which in turn can affect the
overall quality of the model’s predictions or performance.
Factors Influencing
Model Selection
Several factors play a role in determining which machine learning
model or algorithm is most suitable for a given problem.
1. Problem Type
The nature of the problem is perhaps the most critical factor. Is it
a classification task (predicting categories), regression task
(predicting continuous values), clustering task (grouping data), or
something else? Different problems require different algorithms.
Example. For a classification task, algorithms like
logistic regression, support vector machines (SVM), decision trees, or
neural networks might be considered. For a regression task, algorithms
like linear regression or random forests might be more suitable.
2. Data Characteristics
The type of data, its size, and its quality all influence model
selection. For instance, if the dataset is large and high-dimensional,
models like deep neural networks might be more effective. Conversely, if
the data is small or contains many missing values, simpler models like
decision trees or k-nearest neighbors (KNN) may perform better.
Example: In cases where data is sparse or contains
missing values, simpler models such as logistic regression or decision
trees might be preferred over complex models like neural networks.
3. Accuracy vs. Interpretability
Some models offer high predictive accuracy but are difficult to
interpret (e.g., deep neural networks), while others may provide less
accuracy but offer greater interpretability (e.g., decision trees or
linear regression). Depending on the application, stakeholders might
prioritize one over the other.
Example: In medical applications where
explainability is crucial, decision trees or logistic regression might
be chosen for their transparency, even if they offer slightly lower
accuracy compared to a neural network.
4. Computational Resources and Time Constraints
The computational resources required for training and deploying
models should also be considered. More complex models, such as deep
learning models, may require significant computing power and time to
train, while simpler models can be trained more quickly and with fewer
resources.
Example: In a real-time system where speed is
essential, a simpler model like logistic regression may be preferred due
to its lower computational cost compared to a more complex model like a
deep neural network.
5. Performance Metrics
The performance metric being optimized also plays a key role in
algorithm selection. Different models excel at different evaluation
criteria, such as accuracy, precision, recall, F1 score, or area under
the ROC curve (AUC). The choice of metric depends on the task and the
specific goals of the project.
Example: In a fraud detection system, precision and
recall might be prioritized over accuracy to ensure that fraudulent
activities are detected with minimal false negatives.
Process of Model
Identification
Selecting the optimal model and algorithm typically involves several
key steps in the machine learning pipeline. These steps help guide the
practitioner through the process of experimentation, evaluation, and
refinement.
1. Data Preprocessing
Before selecting a model, it is essential to preprocess the data.
This includes handling missing values, encoding categorical variables,
scaling numerical features, and performing any necessary
transformations. Proper data preparation ensures that the chosen model
receives clean, structured input, improving its ability to make accurate
predictions.
2. Model Selection Based on Problem Type
The first step in identifying the optimal algorithm is to select a
model based on the problem type. For supervised learning tasks like
classification and regression, a wide array of models may be tested.
These include:
For Classification: Logistic regression,
decision trees, support vector machines, k-nearest neighbors, and
ensemble methods like random forests and gradient boosting.
For Regression: Linear regression, decision
trees, random forests, support vector regression, and neural
networks.
For Clustering: K-means, hierarchical
clustering, DBSCAN, and Gaussian mixture models.
3. Model Training and Evaluation
Once the models are selected, they are trained on the available
dataset. It is essential to split the dataset into training, validation,
and test sets to avoid overfitting and ensure that the model generalizes
well to unseen data. Model evaluation is done using appropriate
performance metrics (e.g., accuracy, precision, recall, etc.).
Cross-validation techniques, such as k-fold cross-validation, are
often used to further assess model performance and stability. This
process helps determine how well the model will perform on unseen data
and prevents overfitting by ensuring the model generalizes well.
4. Hyperparameter Tuning
Many machine learning algorithms have hyperparameters that need to be
tuned for optimal performance. These hyperparameters control various
aspects of the model, such as the learning rate, regularization
strength, and the depth of decision trees. Hyperparameter tuning is
typically done using grid search or randomized search techniques, which
involve training the model multiple times with different hyperparameter
values and selecting the set that results in the best performance.
5. Model Comparison
After training and tuning several models, the performance of each
model is compared using the selected metrics. This comparison allows
practitioners to evaluate the trade-offs between models in terms of
accuracy, interpretability, and computational efficiency.
Example: If a decision tree model offers high
interpretability but lower accuracy compared to a random forest model, a
decision might be made to prioritize accuracy over interpretability,
depending on the project’s needs.
6. Model Deployment and Monitoring
Once the optimal model has been identified, it is deployed into
production. Continuous monitoring is essential to ensure that the model
continues to perform well as new data is collected. If performance drops
over time, the model may need to be retrained or updated.
Challenges in Model
Selection
The process of identifying the optimal model is not without
challenges. Some of the key difficulties include:
Model Complexity vs. Performance: More complex
models may achieve higher accuracy but require more computational
resources and are more prone to overfitting. Balancing complexity with
performance is a common challenge.
Data Quality: Poor data quality, including missing
values, imbalanced classes, or noisy data, can make it difficult to
identify the optimal model, as the model’s performance may be affected
by the underlying issues in the data.
Overfitting: Selecting a model that performs well on
training data but poorly on test data due to overfitting can be a
significant challenge. Techniques such as cross-validation and
regularization are used to mitigate this issue.
In summary, identifying the optimal models and algorithms in machine
learning is a crucial task that requires careful consideration of
various factors, including the problem type, data characteristics,
available resources, and performance metrics. The process involves
experimenting with different models, training and evaluating them,
tuning their hyperparameters, and selecting the best-performing model.
While the selection process can be challenging due to issues like data
quality, overfitting, and model complexity, following a structured
approach can lead to the identification of the most suitable model for
the task at hand. As machine learning continues to evolve, selecting the
right model will remain a critical factor in delivering accurate,
efficient, and impactful solutions
Validation and
Testing
Validation and testing are critical phases in the machine learning
(ML) workflow. These steps ensure that the model built on the training
data is not only accurate but also generalizes well to new, unseen data.
Without effective validation and testing, a model might appear to
perform well during training but fail to deliver reliable results in
real-world applications. This subsection explores the importance of
validation and testing, the methods commonly used, and their role in
building robust machine learning models.
The Importance of
Validation and Testing
Machine learning models are trained on a specific dataset, known as
the training dataset, which contains examples used to teach the model.
However, the ultimate goal is to develop a model that can make accurate
predictions on new data—data it has not encountered before. This is
where validation and testing come into play.
Validation is used to tune model hyperparameters
and assess the model’s performance during training. It helps in
selecting the best model configuration before final testing, ensuring
that the model does not simply memorize the training data (a phenomenon
known as overfitting).
Testing evaluates the model’s final performance
on an independent set of data, known as the test dataset, that was not
used in any part of the model’s training or validation. This final
evaluation ensures that the model generalizes well to new data.
Without proper validation and testing, there is a risk of developing
a model that works well on the training data but fails to generalize,
leading to poor real-world performance. Thus, these steps are crucial to
model reliability and accuracy.
Validation
Techniques
Validation methods are used to assess the model’s performance during
the training process, before it is tested on unseen data. Several
techniques are commonly employed for this purpose:
Holdout Method
The simplest form of validation, the holdout method involves
splitting the data into two or three sets: a training set, a validation
set, and sometimes a test set. The model is trained on the training set
and validated on the validation set to evaluate its performance. The
test set remains completely untouched during training and
validation.
Example: A typical split might involve using 70% of
the data for training, 15% for validation, and 15% for testing. The
model is trained on the 70%, tuned using the 15% validation set, and
finally tested on the remaining 15%.
K-Fold Cross-Validation
One of the most popular techniques, k-fold cross-validation divides
the data into k equal parts, or “folds.” The model is trained k times,
each time using k-1 folds for training and the remaining fold for
validation. This process is repeated until each fold has been used as
the validation set once. K-fold cross-validation is particularly useful
when the dataset is small, as it allows the model to be validated on
different portions of the data.
Example: In 5-fold cross-validation, the data is
divided into five parts. The model is trained on four parts and
validated on the remaining one, and this process is repeated five times,
ensuring that every data point is used for validation.
Stratified K-Fold Cross-Validation
A variation of k-fold cross-validation, stratified k-fold
cross-validation ensures that each fold has the same proportion of each
class as the entire dataset. This is particularly useful when the
dataset is imbalanced, as it ensures that the training and validation
sets represent the data distribution accurately.
Example: In a binary classification task where the
data is imbalanced (e.g., 90% class A, 10% class B), stratified k-fold
ensures that each fold contains a similar ratio of class A to class
B.
Leave-One-Out Cross-Validation (LOOCV)
In leave-one-out cross-validation, each data point is used as a
separate validation set while the rest of the data points are used for
training. This process is repeated for each data point in the dataset,
which is particularly useful when the dataset is small.
Example: For a dataset of 100 data points, LOOCV
trains the model 100 times, each time leaving out a different single
data point for validation.
These validation techniques help prevent overfitting, ensure that the
model is well-tuned, and make the most out of available data.
Testing the
Model
Once the model has been trained and validated, it is crucial to
evaluate its performance on a separate test dataset. The test set is
used to assess how well the model generalizes to new, unseen data. This
evaluation provides an estimate of how the model will perform in
production or on new incoming data.
Test Dataset
The test dataset should never be used in any part of the
model-building process, including during training or validation. Its
sole purpose is to serve as an independent assessment of the model’s
generalization capability.
Performance Metrics
The performance of the model is measured using various metrics, which
depend on the type of problem (e.g., classification, regression). Common
metrics include:
For Classification: Accuracy, precision, recall,
F1 score, area under the ROC curve (AUC), confusion matrix.
For Regression: Mean squared error (MSE), root
mean squared error (RMSE), mean absolute error (MAE),
R-squared.
These metrics allow practitioners to evaluate how well the model
makes predictions, detect biases, and understand areas where the model
may require improvement.
Example For a classification problem, accuracy alone
might not be sufficient, especially if the classes are imbalanced. In
this case, metrics like precision, recall, and F1 score can provide more
insight into model performance.
Model Comparison
Once the model is tested, it can be compared to baseline models or
other competing models to determine whether it provides a significant
improvement. If multiple models are considered, statistical tests like
paired t-tests or cross-validation results can be used to determine
which model performs best.
Example: A decision tree model might be compared to
a random forest model or a support vector machine. The model with the
highest performance metrics and generalization ability would be chosen
for deployment.
Overfitting and Underfitting
After testing the model, it’s important to ensure that it is not
overfitting (i.e., performing exceptionally well on the training data
but poorly on unseen data) or underfitting (i.e., not capturing the
underlying patterns in the data well enough). These issues can be
diagnosed using the difference between performance on the training set,
validation set, and test set.
Example: A model that shows high performance on the
training set but performs poorly on the test set may be overfitting,
indicating the need for regularization or more data.
In summary, both validation and testing play a key role in model
optimization. Validation helps fine-tune the model during the training
process, ensuring that it is not overfitting or underfitting the data.
Once a model is finalized, testing provides the final evaluation of its
ability to generalize to new data. By using proper validation
techniques, machine learning practitioners can build models that are
robust, accurate, and capable of delivering reliable results on
real-world data.
Reporting Actionable
Results
Translating statistical or model outputs into actionable insights is
crucial. Interpreting results in terms of their real-world implications
adds value to the report.
Actionable Insights: Discuss how stakeholders
can use the findings to make informed decisions or address
challenges.
Policy or Strategy Recommendations: Suggest
specific policies, strategies, or interventions based on the
results.
Scalability and Generalizability: Explain
whether the findings can be applied beyond the analyzed sample or
context.
For example, in an environmental impact study, interpreting results
might involve recommending changes in agricultural practices to reduce
carbon emissions.
Drafting Effective
Reports
Technical report writing is a vital skill for data scientists,
enabling them to communicate complex findings and analyses to various
stakeholders effectively. A well-structured technical report ensures
clarity, precision, and relevance, making it easier for readers to
understand and act upon the information provided. Below are guidelines
and best practices for crafting effective technical reports in data
science.
What to Report
In statistics and data science, effective reporting is crucial for
transparency, reproducibility, and actionable insights. The way findings
are communicated can significantly influence decision-making and the
ability of others to understand, replicate, and build upon the work.
Proper reporting ensures that the analysis is credible, meaningful, and
useful to stakeholders. This subsection discusses the key components
that should be reported in statistics and data science projects,
emphasizing clarity, accuracy, and ethical considerations.
Problem Definition
and Objectives
Every data science or statistical report should begin with a clear
articulation of the problem being addressed. This includes:
Research Questions: What specific questions or
hypotheses is the analysis trying to answer or test?
Objectives: What are the goals of the analysis,
such as making predictions, understanding relationships, or identifying
trends?
Context: Background information about the
domain, industry, or problem being addressed to provide stakeholders
with a comprehensive understanding.
Data Description and
Sources
Understanding the data is fundamental to the credibility of the
analysis. Include:
Data Sources: The origin of the data, whether
collected internally, scraped from the web, or sourced from publicly
available repositories.
Data Characteristics: Description of the
dataset, including size, number of variables, data types, and whether
the data is structured or unstructured.
Data Collection Methods: How the data was
collected (e.g., surveys, sensors, experiments) and any sampling methods
used.
Ethics and Privacy: A discussion of ethical
considerations, including how data privacy was ensured and whether
appropriate permissions or consents were obtained.
Data Cleaning and
Preprocessing
Before analysis, data often requires cleaning and preprocessing.
Report:
Handling of Missing Data: Methods used to
address missing values (e.g., imputation, removal).
Outlier Treatment: Identification and handling
of outliers.
Data Transformation: Any transformations applied
to make the data suitable for analysis, such as scaling, encoding, or
normalizing.
Data Quality Issues: Challenges encountered,
such as inconsistencies, duplicates, or biases in the data.
Exploratory Data
Analysis (EDA)
EDA provides insights into the data’s structure and relationships.
Report:
Descriptive Statistics: Summary statistics such
as mean, median, standard deviation, and frequency
distributions.
Visualization: Key visualizations that reveal
trends, patterns, or anomalies (e.g., histograms, scatter plots,
correlation heatmaps).
Initial Insights: Observations from the data,
such as relationships between variables or potential challenges for the
modeling phase.
Feature Engineering: Additional feature creation
and extraction based on models and algorithms.
Methodology
Transparency in the methods used ensures reproducibility and aids
interpretation.
Statistical Methods or Models: A detailed
explanation of the statistical methods or machine learning models
used.
Assumptions: Assumptions underlying the chosen
methods and whether they were tested (e.g., normality, linearity,
independence).
Hyperparameters and Tuning: Specific parameters
of the models and the process for optimizing them.
Validation and
Testing
To ensure reliability, describe the validation and testing
process:
Train-Test Split: How the data was divided into
training, validation, and test sets, including proportions and methods
(e.g., random sampling, stratified sampling).
Validation Techniques: Approaches used, such as
k-fold cross-validation or holdout validation.
Performance Metrics: Metrics used to evaluate
model performance (e.g., accuracy, precision, recall, F1 score, AUC,
mean squared error).
Results,
Interpretatons, and Discussions
The results should be presented clearly and objectively,
including:
Key Findings: Highlight the most important insights
derived from the analysis and avoid reporting everything the outputs of
the final models. The intermediate candidate models
that are not cited to support your arguments should not be discussed in
the report.
Model Performance: Detailed performance metrics,
including comparisons between candidate models or methods. Make sure the
performance metrics are at the same scale and comparable.
Statistical Significance: Report p-values,
confidence intervals, and effect sizes, if applicable, of the final
model(s) to be recommended to clients and/or to be deployed in
production environment.
Visualizations: Charts, graphs, or tables that
effectively communicate the results. Try interactive visual
representations whenever possible and follow best practices in visual
design.
Discussion and Interpretation Discuss the results
and their practical implications.
Insights: Explain the meaning of the findings
and how they address the research questions or objectives.
Limitations: Acknowledge any limitations in the
data, methodology, or generalizability of the results.
Contextual Relevance: Discuss how the findings
relate to the problem domain and contribute to decision-making.
Ethical
Considerations and Reproducibility
Ethical transparency is a growing priority in data
science.
- Bias and Fairness: Assess and address biases in the
data or models.
- Privacy and Security: Measures taken to protect
sensitive data.
- Impact of Results: Consider potential consequences
of the analysis, especially if it influences policy or business
decisions.
Reproducibility ensures that others can replicate
the analysis by reporting
- Code and Tools: The programming languages,
libraries, and software tools used.
- Parameters and Settings: Specific settings,
configurations, or seeds used in the analysis.
- Access to Data and Code: Whether the data and code
are available and how they can be accessed (while adhering to privacy
and copyright restrictions).
Conclusion and
Recommendations
Summarize and provide actionable insights:
Summary: Recap the problem, approach, and key
findings.
Recommendations: Offer suggestions for stakeholders,
such as policy changes, further analysis, or business strategies.
Future Work: Highlight areas for additional
exploration or improvement.
In summary, effective reporting in statistics and data science
requires clarity, accuracy, and thoroughness. By addressing the problem,
data, methods, results, and implications, analysts can ensure that their
findings are understandable, actionable, and reproducible. Additionally,
ethical considerations and reproducibility are integral to building
trust and fostering responsible data science practices. A comprehensive
report not only showcases the technical rigor of the analysis but also
bridges the gap between complex data science processes and actionable
insights for stakeholders.
Structure of a
Technical Report
In the fields of statistics and data science, effective communication
of findings is paramount. A well-structured report allows stakeholders
to understand the analysis, evaluate its reliability, and derive
actionable insights. The structure of such a report must balance
technical rigor with clarity to cater to both technical and
non-technical audiences.
Title and
Abstract
The title and abstract are the first components of the report that
readers encounter.
Title: A concise and descriptive title should
accurately reflect the content of the report. It should include key
terms relevant to the analysis to immediately inform readers about the
scope of the work.
Abstract: The abstract provides a brief summary of
the report, typically in 150–250 words. It outlines the problem,
methodology, key results, and main conclusions. The abstract helps
readers quickly determine the report’s relevance to their needs.
Abstract is an optional component of all
reports in this class. However, you are encouraged to include the
abstaract in yout report
Introduction
The introduction sets the stage for the report by providing context
and defining its objectives.
Background: Explain the problem domain and why the
analysis is important. This includes a discussion of any prior work or
challenges that necessitated the analysis.
Objectives: Clearly state the goals of the report,
such as answering specific research questions, testing hypotheses, or
developing predictive models.
Scope: Define the boundaries of the analysis,
including any assumptions or limitations known at the outset.
Clear Problem Statements: The research/practical
questions must clearly defined and are translate to analytic questions
accurately.
Data
Description
This section provides detailed information about the data used in the
analysis.
Data Sources: Describe where the data originated,
whether from internal systems, external repositories, or experimental
collection methods.
Data Characteristics: Provide an overview of the
dataset, including the number of observations, variables, and types of
data (e.g., categorical, numerical, text).
Ethical Considerations: Highlight any measures taken
to ensure ethical use of the data, such as anonymization or obtaining
consent.
Methodology
The methodology section outlines the steps taken to process and
analyze the data.
Data Preprocessing: Describe how missing values,
outliers, or inconsistencies were handled, along with any
transformations or feature engineering performed.
Exploratory Data Analysis (EDA): Summarize the key
exploratory steps, such as identifying distributions, relationships, and
patterns. Include relevant visualizations and descriptive
statistics.
Feature Engineering: Summarize all feature
engineering procedures that are justified and performed in the
analysis.
Modeling and Analysis: Specify the statistical
methods, machine learning algorithms, or analytical frameworks used.
Include details about parameter tuning, feature selection, and any
assumptions tested.
Reporting
Results
The results section presents the findings of the analysis in an
organized and interpretable manner.
Descriptive Results: Highlight key statistics,
trends, and relationships discovered during EDA.
Model Performance: Provide metrics evaluating the
performance of models, such as accuracy, precision, recall, or
R-squared, depending on the task.
Visualizations: Include charts, graphs, or tables
that effectively communicate findings. Use annotations and captions for
clarity.
Discussion and
Recommendations
The discussion interprets the results and connects them to the
original objectives.
Interpretation of Results: Explain what the findings
mean in the context of the problem. Discuss whether the results answered
the research questions or hypotheses.
Comparison with Prior Work: If applicable, compare
the findings to previous studies or analyses to highlight similarities,
differences, or improvements.
Limitations: Acknowledge any limitations in the
data, methods, or generalizability of the results. For example, discuss
potential biases or assumptions that may have influenced the
analysis.
Recommendations: Offer suggestions for
decision-makers based on the results, such as changes to policies,
strategies, or further research.
Conclusions: Recap the key points of the report,
emphasizing the problem, major findings, and their implications.
###. References and Appendices
Cite all sources of data, tools, methods, and prior research used in
the report. Use a standard citation format (e.g., APA, IEEE) to ensure
proper attribution. Appendices provide additional details that support
the main report but are not essential to the primary narrative.
In summary, a statistics and data science report is more than just a
collection of numbers and charts; it is a structured narrative that
guides readers through the analysis process and its findings. By
adhering to a clear structure—including an abstract, introduction, data
description, methodology, results, discussion, recommendations, and
appendices—analysts can effectively communicate complex ideas. This
structured approach ensures that the report is comprehensive,
transparent, and accessible to a diverse audience, ultimately enabling
data-driven decision-making.
Writing Best
Practices
Effective communication is integral to the success of statistics and
data science projects. A well-crafted report bridges the gap between
complex analyses and actionable insights, enabling stakeholders to make
informed decisions. Best practices in report writing focus on clarity,
transparency, accuracy, and accessibility.
1. Begin with a Clear Structure
The foundation of a great report lies in its structure. Organizing
the content in a logical and predictable format helps readers navigate
the document effortlessly.
Title and Abstract: Start with a descriptive
title and a concise abstract summarizing the problem, methodology, key
findings, and conclusions.
Section Headings: Use well-defined sections such
as Introduction, Data Description, Methodology, Results, Discussion, and
Recommendations. These sections create a roadmap for the
report.
Appendices: Include supplementary materials such
as detailed tables, charts, or code in appendices to avoid cluttering
the main text.
2. Know Your Audience
Understanding the target audience is crucial for effective
communication.
Tailor Content: Adjust the level of detail and
technical complexity to suit the audience. For technical readers,
include in-depth explanations, algorithms, and code. For non-technical
stakeholders, focus on key insights and business implications.
Define Terms: Avoid assuming familiarity with
jargon or technical terms. Provide clear definitions or include a
glossary for unfamiliar concepts.
3. Prioritize Clarity and Simplicity
A report should communicate complex ideas in a way that is easy to
understand.
Concise Writing: Avoid verbosity by presenting
ideas succinctly. Use bullet points and numbered lists to summarize key
points.
Active Voice: Use active voice for direct and
engaging sentences (e.g., “We analyzed the data,” instead of “The data
was analyzed”).
Logical Flow: Present the content in a logical
sequence, leading readers step-by-step through the analysis.
4. Ensure Transparency and Reproducibility
Transparency builds trust in the findings, while reproducibility
allows others to validate the work.
Data Description: Provide detailed information
about the dataset, including sources, collection methods, and
characteristics.
Methodology: Clearly explain the steps taken in
preprocessing, exploratory analysis, modeling, and validation. Mention
any assumptions or limitations of the methods used.
Code and Tools: Share the programming tools,
libraries, and code snippets used in the analysis, adhering to any
applicable data-sharing and privacy constraints.
5. Emphasize Visual Communication
Visual elements enhance understanding and make the report more
engaging.
Data Visualizations: Use charts, graphs, and
plots to represent data and findings. Ensure each visualization is
labeled, captioned, and easy to interpret.
Clarity in Design: Avoid overcrowding visuals
with excessive information. Use clean, minimalist designs with color
schemes accessible to colorblind readers.
Comparative Analysis: When presenting multiple
models or scenarios, use side-by-side visual comparisons to highlight
differences.
6. Present Results Objectively
Objectivity in presenting results is critical for credibility.
Report All Results: Include both positive and
negative findings. Acknowledge any inconsistencies or unexpected
outcomes.
Performance Metrics: Clearly explain the metrics
used to evaluate models (e.g., accuracy, precision, recall, F1 score,
ROC and AUC, etc.) and why they were chosen.
Statistical Significance: Highlight statistical
significance, confidence intervals, and effect sizes to provide context
for the results.
7. Address Ethical Considerations
Ethics are an integral part of statistics and data science
reporting.
Bias and Fairness: Discuss potential biases in
the data or methods and their implications for the results.
Privacy and Consent: Explain how privacy
concerns were addressed, including measures for anonymization or secure
data handling.
Impact Analysis: Consider the broader
implications of the findings, especially if they influence policy or
decision-making.
8. Focus on Actionable Insights
A key goal of data science reports is to provide insights that
stakeholders can act upon.
Business Relevance: Relate findings back to the
original problem or objectives.
Recommendations: Offer clear, evidence-based
recommendations for next steps or decisions.
Future Work: Suggest areas for further research
or potential improvements in methodology.
Web-based Effective
Presentation
In an increasingly digital world, web-based presentations have become
a critical tool for communication, education, and business. Unlike
traditional formats, web-based presentations must cater to the dynamics
of online platforms, ensuring they engage audiences and convey messages
effectively in a virtual environment. This essay outlines key principles
and strategies for designing effective web-based presentations, focusing
on content structure, visual appeal, interactivity, and
accessibility.
Clear and Logical
Structure
An effective web-based presentation begins with a well-organized
structure to guide the audience through the content seamlessly.
Define Objectives: Start by identifying the purpose
of the presentation and the key takeaways for the audience. This helps
in aligning the content with the goals.
Outline the Flow: Arrange slides in a logical
sequence—beginning with an introduction, followed by the main content,
and ending with a strong conclusion or call to action.
Chunk Information: Break complex information into
smaller, digestible sections to maintain the audience’s focus and avoid
cognitive overload.
For instance, a presentation on data analytics might start with an
overview of the field, proceed to methods and tools, and conclude with
real-world applications.
Visual Design and
Aesthetics
The visual design and aesthetics of presentation slides play a
critical role in capturing attention, conveying information effectively,
and maintaining audience engagement. Good design ensures that the
message is not only clear but also memorable. This subsection explores
key principles and strategies for achieving effective visual design and
aesthetics in presentation slides, emphasizing clarity, consistency, and
audience-centered design.
1. The Role of Visual Design in Presentations
Visual design is not just about making slides look appealing—it
serves to enhance communication and understanding.
Attracting Attention: Well-designed slides can
immediately capture the audience’s interest and set a positive tone for
the presentation.
Improving Comprehension: Visual elements like
charts, diagrams, and color-coded highlights make complex information
easier to understand.
Maintaining Engagement: Aesthetic and dynamic
design keeps the audience focused and prevents monotony. Reinforcing
Messaging: Consistent and thoughtful design choices strengthen the
impact of the presented message.
For example, a presentation on renewable energy benefits from
visually appealing graphs and images of wind turbines and solar panels
to highlight key points effectively.
2. Key Principles of Slide Design
Achieving strong visual design involves adhering to fundamental
design principles that prioritize clarity and coherence.
Simplicity: Keep slides clean and uncluttered.
Focus on one main idea per slide to avoid overwhelming the
audience.
Hierarchy: Use visual hierarchy to guide the
audience’s attention. Larger fonts, bold text, and contrasting colors
can emphasize key points.
Balance: Arrange elements symmetrically or
asymmetrically to create harmony and avoid a cluttered
appearance.
Alignment: Align text, images, and other
elements for a polished and professional look. Misaligned objects can
appear unprofessional and distract from the message.
Contrast: Ensure sufficient contrast between
text and background colors to enhance readability, especially in
low-light settings.
For instance, using a bold, large font for headings and smaller,
lighter text for supporting details creates a clear visual
hierarchy.
3. Effective Use of Colors
Colors are a powerful tool for setting the tone and enhancing the
readability of slides.
Consistent Color Scheme: Stick to a limited
palette of 2–4 colors that align with the presentation’s theme or brand
identity.
Purposeful Colors: Use colors to emphasize
specific points, such as red for warnings or green for positive
outcomes.
Readable Combinations: Avoid low-contrast
combinations like light text on a light background. Dark text on a light
background or vice versa is generally more legible.
Psychological Impact: Consider the emotional and
psychological associations of colors. For example, blue conveys trust
and professionalism, while orange suggests energy and
creativity.
For example, a healthcare presentation might use calming blues and
whites to instill trust and professionalism.
4. Less Text, More Storytelling
Slides overloaded with text can disengage audiences and obscure the
core message. Instead, embracing storytelling with visuals can create a
more impactful and memorable experience. This approach transforms slides
from static reading material into a dynamic tool that supports the
presenter’s narrative, engaging the audience on a deeper emotional and
intellectual level. Minimizing text on slides forces the presenter to
engage the audience directly and focus on key points.
One Idea Per Slide: Limit each slide to a single
concept to avoid overwhelming the audience.
Bullet Point Reduction: Replace long lists of
bullet points with succinct phrases, visuals, or icons.
Presenter-Centered Delivery: Use the slides as
prompts for speaking rather than as a script.
5. Incorporating Visual Elements
Visual elements like images, icons, and charts can enhance slides by
making abstract concepts tangible and data more relatable.
High-Quality Images: Use sharp, relevant images
that align with the presentation’s topic. Avoid pixelated or generic
stock photos.
Infographics and Charts: Use well-designed
charts and infographics to present data clearly. Select the right type
of chart (e.g., bar, line, pie) for the data.
Icons: Add icons to illustrate points and break
up text. Use a consistent icon style for visual harmony.
White Space: Allow for white space around
visuals to prevent overcrowding and maintain a clean, organized
appearance.
For example, a financial report presentation could include a line
graph showing trends over time, accompanied by icons representing key
milestones.
6. Animations and Transitions
Animations and transitions can enhance the flow of a presentation but
must be used judiciously.
Subtle Animations: Use animations sparingly to
draw attention to important elements without distracting the
audience.
Consistent Transitions: Apply a uniform
transition style across slides to maintain visual continuity.
Avoid Overuse: Excessive or flashy animations
can detract from the message and appear unprofessional.
For instance, using a fade-in animation to introduce bullet points
one by one helps maintain audience focus without being distracting.
7. Designing for Accessibility
Aesthetic design should also account for the diverse needs of the
audience, ensuring accessibility for all.
Readable Fonts: Choose fonts that are legible
for viewers with visual impairments, avoiding overly ornate or narrow
typefaces.
Colorblind-Friendly Palette: Use color
combinations that are distinguishable for individuals with color vision
deficiencies.
Alt Text: Add alt text descriptions to images
for audiences relying on screen readers.
Responsive Design: Optimize slides for various
devices, especially in virtual presentations where viewers may use
smartphones or tablets.
For example, a presentation on public policy should use distinct
patterns or labels in charts instead of relying solely on color
differentiation.
Interactive and
Dynamic Elements
Interactive content in presentation slides can significantly enhance
audience engagement and comprehension by transforming a passive
experience into an active one. It allows presenters to tailor the
delivery to audience interests, foster participation, and provide a more
dynamic presentation. To maximize the effectiveness of interactive
content, adhere to the following principles:
Purposeful Interactivity: Ensure every
interactive element has a clear purpose that supports the presentation’s
goals. Avoid adding features just for novelty.
Simplicity: Keep interactive elements intuitive
and easy to use. Overly complex designs can confuse and disengage the
audience.
Test Functionality: Verify that all interactive
features work as intended, especially when presenting on unfamiliar
equipment or platforms.
Balance with Content: Interactivity should
complement, not overshadow, the core message of the
presentation.
Accessibility and
Inclusivity
Designing presentation slides with accessibility and inclusivity in
mind ensures that all audience members, regardless of their abilities or
backgrounds, can fully engage with and understand the content. This
approach not only reflects respect and consideration but also broadens
the reach and impact of the presentation.
1. Text Accessibility
Text content should be clear, legible, and structured for all
viewers.
Readable Fonts: Use simple, sans-serif fonts
like Arial or Calibri, avoiding decorative styles.
Sufficient Font Size: Ensure text is large
enough to be read from a distance, typically 24–36 points for body text
and 36–44 points for headings.
Contrast: Use high contrast between text and
background, such as dark text on a light background or vice
versa.
Text Hierarchy: Use headings, subheadings, and
bullet points to organize content logically and make it
scannable.
2. Visual and Graphic Accessibility
Images, charts, and other visuals should be accessible and
inclusive.
Alt Text for Images: Provide alternative text
descriptions for images to support audience members using screen
readers.
Colorblind-Friendly Design: Avoid relying solely
on color to convey information. Use patterns, labels, or text
annotations in graphs and charts.
Simple Visuals: Avoid overly complex graphics
that may overwhelm or confuse the audience. White Space: Use sufficient
white space to avoid visual clutter and make content easier to focus
on.
3. Inclusive Language and Content
Inclusivity goes beyond technical design to encompass the
presentation’s tone and language.
Avoid Jargon: Use clear, straightforward
language to ensure the content is accessible to people with varying
levels of expertise.
Cultural Sensitivity: Avoid idioms, metaphors,
or references that may not translate well across cultures.
Representation: Include diverse examples,
images, and perspectives to reflect the audience’s varied
backgrounds.
In summary, designing effective web-based presentations requires a
thoughtful approach that integrates clear structure, engaging visuals,
interactivity, accessibility, and practical delivery strategies. By
focusing on these elements, presenters can create impactful online
experiences that resonate with diverse audiences. As virtual
communication continues to grow, mastering the art of web-based
presentation design will be an essential skill for professionals across
industries.
LS0tDQp0aXRsZTogJ0RhdGEgQW5hbHlzaXMsIFJlcG9ydGluZywgYW5kIFByZXNlbnRhdGlvbiBXb3JrZmxvdycNCmF1dGhvcjogIkNoZW5nIFBlbmciDQpkYXRlOiAiV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7PWh0bWx9DQoNCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoNCi8qIENhc2NhZGluZyBTdHlsZSBTaGVldHMgKENTUykgaXMgYSBzdHlsZXNoZWV0IGxhbmd1YWdlIHVzZWQgdG8gZGVzY3JpYmUgdGhlIHByZXNlbnRhdGlvbiBvZiBhIGRvY3VtZW50IHdyaXR0ZW4gaW4gSFRNTCBvciBYTUwuIGl0IGlzIGEgc2ltcGxlIG1lY2hhbmlzbSBmb3IgYWRkaW5nIHN0eWxlIChlLmcuLCBmb250cywgY29sb3JzLCBzcGFjaW5nKSB0byBXZWIgZG9jdW1lbnRzLiAqLw0KDQpoMS50aXRsZSB7ICAvKiBUaXRsZSAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgdGhlIHJlcG9ydCB0aXRsZSAqLw0KICBmb250LXNpemU6IDI0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGF1dGhvcnMgICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IG5hdnk7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciB0aGUgZGF0ZSAgKi8NCiAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQp9DQpoMSB7IC8qIEhlYWRlciAxIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgbGV2ZWwgMSBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDIgeyAvKiBIZWFkZXIgMiAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGxldmVsIDIgc2VjdGlvbiB0aXRsZSAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgbGV2ZWwgMyBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgbGV2ZWwgNCBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KPC9zdHlsZT4NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJHR2FsbHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiR0dhbGx5IikNCmxpYnJhcnkoR0dhbGx5KQ0KfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQ0KICAgICAgICAgICAgICAgICAgICAgICkgIA0KYGBgDQoNClwNCg0KIyBJbnRyb2R1Y3Rpb24NCg0KRGF0YSBzY2llbmNlIGlzIGEgZHluYW1pYyBmaWVsZCB0aGF0IGZvY3VzZXMgb24gZ2F0aGVyaW5nLCBhbmFseXppbmcsIGFuZCBpbnRlcnByZXRpbmcgbGFyZ2UgZGF0YXNldHMgdG8gdW5jb3ZlciB2YWx1YWJsZSBpbnNpZ2h0cyB0aHJvdWdoIHRoZSB1c2Ugb2Ygc3RhdGlzdGljYWwgdGVjaG5pcXVlcyBhbmQgbWFjaGluZSBsZWFybmluZyBtZXRob2RzLiBIb3dldmVyLCB0aGUgdWx0aW1hdGUgdmFsdWUgb2YgZGF0YSBzY2llbmNlIHdvcmsgbGllcyBub3Qgb25seSBpbiB0aGUgcXVhbGl0eSBvZiB0aGUgYW5hbHlzaXMgYnV0IGFsc28gaW4gaG93IGVmZmVjdGl2ZWx5IHRoZSByZXN1bHRzIGFyZSBjb21tdW5pY2F0ZWQuIEVmZmVjdGl2ZSB0ZWNobmljYWwgY29tbXVuaWNhdGlvbiBpcyBlc3NlbnRpYWwgaW4gZW5zdXJpbmcgdGhhdCBjb21wbGV4IGZpbmRpbmdzIGFyZSB1bmRlcnN0b29kLCBhY3RlZCB1cG9uLCBhbmQgdXNlZCB0byBtYWtlIGluZm9ybWVkIGRlY2lzaW9ucy4gVGhpcyBub3RlIG91dGxpbmVzIHRoZSBrZXkgZWxlbWVudHMgb2YgZWZmZWN0aXZlIHRlY2huaWNhbCBjb21tdW5pY2F0aW9uIGluIGRhdGEgc2NpZW5jZSwgZm9jdXNpbmcgb24gcmVwb3J0aW5nLCBwcmVzZW50YXRpb25zLCBhbmQgZGlzY3Vzc2lvbnMuDQoNCioqQ2xhcml0eSBhbmQgU2ltcGxpY2l0eSBpbiBSZXBvcnRpbmcqKg0KDQpPbmUgb2YgdGhlIG1vc3QgY3JpdGljYWwgZWxlbWVudHMgb2YgZWZmZWN0aXZlIGNvbW11bmljYXRpb24gaW4gZGF0YSBzY2llbmNlIGlzIGNsYXJpdHkuIERhdGEgc2NpZW5jZSByZXBvcnRzIG9mdGVuIGRlYWwgd2l0aCBpbnRyaWNhdGUgYWxnb3JpdGhtcywgc3RhdGlzdGljYWwgbW9kZWxzLCBhbmQgbGFyZ2UgZGF0YXNldHMsIHdoaWNoIGNhbiBvdmVyd2hlbG0gcmVhZGVycyBpZiBwcmVzZW50ZWQgcG9vcmx5LiBUZWNobmljYWwgcmVwb3J0cyBtdXN0IGF2b2lkIGphcmdvbiBhbmQgY29tcGxleCB0ZXJtaW5vbG9neSB0aGF0IG1pZ2h0IGFsaWVuYXRlIG5vbi1leHBlcnQgYXVkaWVuY2VzLiBXaGlsZSB0ZWNobmljYWwgYWNjdXJhY3kgaXMgdml0YWwsIHRoZSBsYW5ndWFnZSBzaG91bGQgYmUgYWNjZXNzaWJsZSB0byBhIHdpZGUgYXVkaWVuY2UsIGluY2x1ZGluZyBzdGFrZWhvbGRlcnMgd2hvIG1heSBub3QgaGF2ZSBhIGRlZXAgdW5kZXJzdGFuZGluZyBvZiB0aGUgbWV0aG9kcyB1c2VkLg0KDQpDbGVhciBjb21tdW5pY2F0aW9uIGNhbiBiZSBhY2hpZXZlZCBieSBzdHJ1Y3R1cmluZyByZXBvcnRzIGxvZ2ljYWxseS4gRWFjaCByZXBvcnQgc2hvdWxkIGJlZ2luIHdpdGggYW4gZXhlY3V0aXZlIHN1bW1hcnksIG91dGxpbmluZyBrZXkgZmluZGluZ3MgYW5kIHRoZWlyIGltcGxpY2F0aW9ucy4gVGhpcyBpcyBmb2xsb3dlZCBieSBkZXRhaWxlZCBzZWN0aW9ucyB0aGF0IGV4cGxhaW4gdGhlIG1ldGhvZG9sb2d5LCByZXN1bHRzLCBhbmQgY29uY2x1c2lvbnMuIEZpbmFsbHksIHJlY29tbWVuZGF0aW9ucyBzaG91bGQgYmUgcHJlc2VudGVkIGNsZWFybHksIGJhc2VkIG9uIHRoZSBkYXRhJ3MgaW5zaWdodHMuIFRvIGF2b2lkIGluZm9ybWF0aW9uIG92ZXJsb2FkLCB0aGUgcmVwb3J0IHNob3VsZCBiZSBjb25jaXNlLCB3aXRoIGEgZm9jdXMgb24gdGhlIG1vc3QgaW1wb3J0YW50IHBvaW50cywgdXNpbmcgYnVsbGV0IHBvaW50cyBvciB0YWJsZXMgdG8gc3VtbWFyaXplIGtleSBmaW5kaW5ncy4NCg0KKipWaXN1YWxpemF0aW9uOiBNYWtpbmcgQ29tcGxleCBEYXRhIEFjY2Vzc2libGUqKg0KDQpFZmZlY3RpdmUgZGF0YSBzY2llbmNlIGNvbW11bmljYXRpb24gcmVsaWVzIGhlYXZpbHkgb24gdGhlIHVzZSBvZiB2aXN1YWxpemF0aW9ucy4gRGF0YSwgaW4gaXRzIHJhdyBmb3JtLCBjYW4gYmUgY2hhbGxlbmdpbmcgdG8gaW50ZXJwcmV0LiBDaGFydHMsIGdyYXBocywgYW5kIG90aGVyIHZpc3VhbCB0b29scyBoZWxwIHRvIHByZXNlbnQgZGF0YSBpbiBhIHdheSB0aGF0IGlzIGludHVpdGl2ZSBhbmQgY29tcHJlaGVuc2libGUuIFdoZXRoZXIgaXTigJlzIGEgdGltZSBzZXJpZXMgZ3JhcGgsIGEgaGVhdG1hcCwgb3IgYSBzY2F0dGVyIHBsb3QsIHZpc3VhbGl6YXRpb25zIGNhbiBoaWdobGlnaHQgdHJlbmRzLCBjb3JyZWxhdGlvbnMsIGFuZCBvdXRsaWVycyBtb3JlIGVmZmVjdGl2ZWx5IHRoYW4gcmF3IG51bWJlcnMuDQoNCkhvd2V2ZXIsIHZpc3VhbGl6YXRpb25zIG11c3QgYmUgZGVzaWduZWQgY2FyZWZ1bGx5IHRvIGNvbnZleSB0aGUgY29ycmVjdCBtZXNzYWdlLiBQb29ybHkgZGVzaWduZWQgdmlzdWFscyBjYW4gbWlzbGVhZCBvciBjb25mdXNlIHRoZSBhdWRpZW5jZS4gSXTigJlzIGVzc2VudGlhbCB0byBjaG9vc2UgdGhlIHJpZ2h0IHR5cGUgb2YgZ3JhcGggZm9yIHRoZSBkYXRhLCB1c2UgY2xlYXIgbGFiZWxzLCBhbmQgYXZvaWQgdW5uZWNlc3NhcnkgY2x1dHRlci4gRm9yIGV4YW1wbGUsIHdoZW4gcHJlc2VudGluZyBhIGNvcnJlbGF0aW9uIG1hdHJpeCwgYSBoZWF0bWFwIHdpdGggY2xlYXIgY29sb3IgZ3JhZGllbnRzIGNhbiBxdWlja2x5IGNvbW11bmljYXRlIHdoaWNoIHZhcmlhYmxlcyBhcmUgbW9zdCBjbG9zZWx5IHJlbGF0ZWQsIG1ha2luZyBpdCBlYXNpZXIgZm9yIHRoZSBhdWRpZW5jZSB0byB1bmRlcnN0YW5kIHRoZSByZWxhdGlvbnNoaXBzIHdpdGhpbiB0aGUgZGF0YS4NCg0KKipUYWlsb3JpbmcgQ29tbXVuaWNhdGlvbiB0byB0aGUgQXVkaWVuY2UqKg0KDQpBbm90aGVyIGltcG9ydGFudCBmYWN0b3IgaW4gZWZmZWN0aXZlIHRlY2huaWNhbCBjb21tdW5pY2F0aW9uIGlzIGtub3dpbmcgeW91ciBhdWRpZW5jZS4gRGF0YSBzY2llbnRpc3RzIG9mdGVuIGNvbW11bmljYXRlIHRoZWlyIGZpbmRpbmdzIHRvIGRpdmVyc2UgZ3JvdXBzLCBpbmNsdWRpbmcgZXhlY3V0aXZlcywgdGVjaG5pY2FsIHRlYW1zLCBhbmQgbm9uLXRlY2huaWNhbCBzdGFrZWhvbGRlcnMuIFRhaWxvcmluZyB0aGUgZGVwdGggYW5kIHN0eWxlIG9mIGNvbW11bmljYXRpb24gYWNjb3JkaW5nIHRvIHRoZSBhdWRpZW5jZSBpcyBjcnVjaWFsIGZvciBlbnN1cmluZyB0aGF0IHRoZSBtZXNzYWdlIGlzIHVuZGVyc3Rvb2QuDQoNCkZvciBidXNpbmVzcyBleGVjdXRpdmVzLCB0aGUgZW1waGFzaXMgc2hvdWxkIGJlIG9uIGFjdGlvbmFibGUgaW5zaWdodHMgcmF0aGVyIHRoYW4gdGhlIHRlY2huaWNhbCBkZXRhaWxzIG9mIHRoZSBhbmFseXNpcy4gQSBzdW1tYXJ5IG9mIHRoZSBrZXkgZmluZGluZ3MsIGFsb25nIHdpdGggY2xlYXIgcmVjb21tZW5kYXRpb25zLCBpcyBtb3JlIHZhbHVhYmxlIHRoYW4gYSBkZWVwIGRpdmUgaW50byB0aGUgYWxnb3JpdGhtcyB1c2VkLiBPbiB0aGUgb3RoZXIgaGFuZCwgZm9yIGEgdGVjaG5pY2FsIGF1ZGllbmNlLCB0aGUgZm9jdXMgc2hvdWxkIGJlIG9uIHRoZSBtZXRob2RzLCBhc3N1bXB0aW9ucywgYW5kIHJlc3VsdHMgb2YgdGhlIGFuYWx5c2lzLCBhbGxvd2luZyB0aGVtIHRvIGFzc2VzcyB0aGUgdmFsaWRpdHkgb2YgdGhlIHdvcmsgdGhlbXNlbHZlcy4NCg0KVW5kZXJzdGFuZGluZyB0aGUgYXVkaWVuY2XigJlzIG5lZWRzIGFsc28gaGVscHMgaW4gY2hvb3NpbmcgdGhlIGFwcHJvcHJpYXRlIGxldmVsIG9mIGRldGFpbC4gRXhlY3V0aXZlcyBtYXkgb25seSBuZWVkIGEgaGlnaC1sZXZlbCBvdmVydmlldyBvZiB0aGUgb3V0Y29tZXMsIHdoaWxlIHRlY2huaWNhbCB0ZWFtcyByZXF1aXJlIGEgZGVlcGVyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIGRhdGHigJlzIHN0cnVjdHVyZSwgbW9kZWxpbmcgdGVjaG5pcXVlcywgYW5kIHZhbGlkYXRpb24gcHJvY2Vzc2VzLg0KDQoqKlN0b3J5dGVsbGluZzogRnJhbWluZyBEYXRhIFdpdGhpbiBhIE5hcnJhdGl2ZSoqDQoNCkluIGFkZGl0aW9uIHRvIGNsYXJpdHkgYW5kIGF1ZGllbmNlIGF3YXJlbmVzcywgc3Rvcnl0ZWxsaW5nIGlzIGEgcG93ZXJmdWwgdGVjaG5pcXVlIGluIGRhdGEgc2NpZW5jZSBjb21tdW5pY2F0aW9uLiBOdW1iZXJzIGFuZCBtb2RlbHMgbWF5IHNlZW0gYWJzdHJhY3QsIGJ1dCB3aGVuIGZyYW1lZCB3aXRoaW4gYSBuYXJyYXRpdmUsIHRoZXkgYmVjb21lIG1vcmUgcmVsYXRhYmxlIGFuZCBtZW1vcmFibGUuIFN0b3J5dGVsbGluZyBoZWxwcyB0byBjb25uZWN0IHRoZSBmaW5kaW5ncyB3aXRoIHJlYWwtd29ybGQgcHJvYmxlbXMgYW5kIGlsbHVzdHJhdGVzIHRoZWlyIGltcGxpY2F0aW9ucyBpbiBhIHdheSB0aGF0IHJlc29uYXRlcyB3aXRoIHRoZSBhdWRpZW5jZS4NCg0KQSBjb21wZWxsaW5nIGRhdGEgc3RvcnkgYmVnaW5zIGJ5IHByZXNlbnRpbmcgdGhlIHByb2JsZW0gb3IgY2hhbGxlbmdlIHRoYXQgdGhlIGRhdGEgYW5hbHlzaXMgc2Vla3MgdG8gYWRkcmVzcy4gVGhlIG5hcnJhdGl2ZSBzaG91bGQgdGhlbiBvdXRsaW5lIGhvdyB0aGUgZGF0YSB3YXMgZ2F0aGVyZWQsIHByb2Nlc3NlZCwgYW5kIGFuYWx5emVkLCBiZWZvcmUgbGVhZGluZyBpbnRvIHRoZSBrZXkgZmluZGluZ3MuIEZpbmFsbHksIHRoZSBzdG9yeSBzaG91bGQgY2xvc2Ugd2l0aCBhIGNvbmNsdXNpb24gb3IgcmVjb21tZW5kYXRpb24gdGhhdCB0aWVzIGV2ZXJ5dGhpbmcgYmFjayB0byB0aGUgaW5pdGlhbCBwcm9ibGVtLCBzaG93aW5nIGhvdyB0aGUgaW5zaWdodHMgY2FuIGJlIHVzZWQgdG8gbWFrZSBpbmZvcm1lZCBkZWNpc2lvbnMuDQoNCioqUHJlY2lzaW9uIGFuZCBBY2N1cmFjeSoqDQoNClRoZSBpbXBvcnRhbmNlIG9mIHByZWNpc2lvbiBhbmQgYWNjdXJhY3kgaW4gdGVjaG5pY2FsIGNvbW11bmljYXRpb24gY2Fubm90IGJlIG92ZXJzdGF0ZWQuIERhdGEgc2NpZW5jZSByZWxpZXMgb24gdGhlIGNvcnJlY3QgYXBwbGljYXRpb24gb2YgbWF0aGVtYXRpY2FsIG1vZGVscyBhbmQgc3RhdGlzdGljYWwgdGVjaG5pcXVlcywgYW5kIGFueSBtaXNjb21tdW5pY2F0aW9uIG9mIHRoZXNlIG1ldGhvZHMgY2FuIGxlYWQgdG8gaW5jb3JyZWN0IGNvbmNsdXNpb25zIGFuZCwgcG90ZW50aWFsbHksIGhhcm1mdWwgZGVjaXNpb25zLiBXaGV0aGVyIGluIHdyaXR0ZW4gcmVwb3J0cywgcHJlc2VudGF0aW9ucywgb3IgZGlzY3Vzc2lvbnMsIGRhdGEgc2NpZW50aXN0cyBtdXN0IGVuc3VyZSB0aGF0IHRoZSByZXN1bHRzIGFyZSBhY2N1cmF0ZSwgYW5kIHRoZSBhc3N1bXB0aW9ucyBiZWhpbmQgdGhlaXIgYW5hbHlzaXMgYXJlIGNsZWFybHkgc3RhdGVkLg0KDQpJdOKAmXMgYWxzbyBpbXBvcnRhbnQgdG8gZW1waGFzaXplIHRoZSBsaW1pdGF0aW9ucyBvZiB0aGUgYW5hbHlzaXMuIE5vIG1vZGVsIGlzIHBlcmZlY3QsIGFuZCBhY2tub3dsZWRnaW5nIHBvdGVudGlhbCBlcnJvcnMgb3IgYXJlYXMgb2YgdW5jZXJ0YWludHkgY2FuIGhlbHAgYnVpbGQgdHJ1c3Qgd2l0aCB0aGUgYXVkaWVuY2UuIEZvciBleGFtcGxlLCBkaXNjdXNzaW5nIHRoZSBjb25maWRlbmNlIGludGVydmFscyBhcm91bmQgcHJlZGljdGlvbnMgb3IgdGhlIGFzc3VtcHRpb25zIHVuZGVybHlpbmcgYSByZWdyZXNzaW9uIG1vZGVsIHByb3ZpZGVzIGNvbnRleHQgYW5kIGFsbG93cyB0aGUgYXVkaWVuY2UgdG8gYXNzZXNzIHRoZSByZWxpYWJpbGl0eSBvZiB0aGUgcmVzdWx0cy4NCg0KKipFbmdhZ2luZyBEaXNjdXNzaW9ucyoqDQoNCkZpbmFsbHksIGVmZmVjdGl2ZSBjb21tdW5pY2F0aW9uIGluIGRhdGEgc2NpZW5jZSBleHRlbmRzIGJleW9uZCB3cml0dGVuIHJlcG9ydHMgYW5kIHByZXNlbnRhdGlvbnMgdG8gaW50ZXJhY3RpdmUgZGlzY3Vzc2lvbnMuIEluIHRoZXNlIHNldHRpbmdzLCBkYXRhIHNjaWVudGlzdHMgbXVzdCBiZSBwcmVwYXJlZCB0byBleHBsYWluIHRoZWlyIHdvcmsgaW4gYSBjb252ZXJzYXRpb25hbCBtYW5uZXIsIGFuc3dlcmluZyBxdWVzdGlvbnMsIGNsYXJpZnlpbmcgZG91YnRzLCBhbmQgZW5nYWdpbmcgd2l0aCB0aGUgYXVkaWVuY2UuIEFjdGl2ZSBsaXN0ZW5pbmcgaXMgY3JpdGljYWwgaGVyZSwgYXMgaXQgYWxsb3dzIHRoZSBjb21tdW5pY2F0b3IgdG8gYWRkcmVzcyB0aGUgYXVkaWVuY2UncyBjb25jZXJucyBhbmQgYWRqdXN0IHRoZSBleHBsYW5hdGlvbiBhY2NvcmRpbmdseS4NCg0KTW9yZW92ZXIsIGRpc2N1c3Npb25zIHByb3ZpZGUgYW4gb3Bwb3J0dW5pdHkgZm9yIGZlZWRiYWNrLCB3aGljaCBpcyBlc3NlbnRpYWwgZm9yIGltcHJvdmluZyB0aGUgYW5hbHlzaXMuIER1cmluZyBkaXNjdXNzaW9ucywgZGF0YSBzY2llbnRpc3RzIGNhbiBjbGFyaWZ5IG1pc3VuZGVyc3RhbmRpbmdzLCBleHBsYWluIGNvbXBsZXggY29uY2VwdHMgaW4gc2ltcGxlciB0ZXJtcywgYW5kIGZpbmUtdHVuZSB0aGVpciBtZXNzYWdlIHRvIGVuc3VyZSB0aGF0IGl0IGlzIHVuZGVyc3Rvb2QgYnkgYWxsIHBhcnRpZXMgaW52b2x2ZWQuIFRoaXMgdHdvLXdheSBjb21tdW5pY2F0aW9uIGhlbHBzIHRvIGVuc3VyZSB0aGF0IHRoZSBmaW5kaW5ncyBhcmUgaW50ZXJwcmV0ZWQgY29ycmVjdGx5IGFuZCBjYW4gZ3VpZGUgZnV0dXJlIGRlY2lzaW9ucy4NCg0KDQoNCiMgRGF0YSBBbmFseXNpcyBXb3JrZmxvdw0KDQpUaGUgZGF0YSBzY2llbmNlIGFuYWx5c2lzIHdvcmtmbG93IHJlZmVycyB0byB0aGUgc2VyaWVzIG9mIHN0ZXBzIG9yIHN0YWdlcyB0aGF0IGRhdGEgc2NpZW50aXN0cyBmb2xsb3cgdG8gZ2F0aGVyLCBwcm9jZXNzLCBhbmFseXplLCBhbmQgaW50ZXJwcmV0IGRhdGEgaW4gb3JkZXIgdG8gZXh0cmFjdCBhY3Rpb25hYmxlIGluc2lnaHRzLiBUaGlzIHdvcmtmbG93IGNhbiB2YXJ5IHNsaWdodGx5IGRlcGVuZGluZyBvbiB0aGUgc3BlY2lmaWMgcHJvamVjdCwgYnV0IGl0IHR5cGljYWxseSBpbmNsdWRlcyB0aGUgZm9sbG93aW5nIGtleSBzdGFnZXMuDQoNCiMjIERlZmluZSBPYmplY3RpdmVzIGFuZCBRdWVzdGlvbnMNCg0KSW4gZGF0YSBzY2llbmNlIGFuZCBtYWNoaW5lIGxlYXJuaW5nIHByb2plY3RzLCBkZWZpbmluZyBvYmplY3RpdmVzIGFuZCBxdWVzdGlvbnMgYWNjdXJhdGVseSBpcyBjcnVjaWFsIGFzIHRoZXkgc2V0IHRoZSBmb3VuZGF0aW9uIGZvciB0aGUgZW50aXJlIGFuYWx5c2lzIGFuZCBtb2RlbCBkZXZlbG9wbWVudCBwcm9jZXNzLiBDbGVhciBvYmplY3RpdmVzIGFuZCB3ZWxsLWZvcm11bGF0ZWQgcXVlc3Rpb25zIGd1aWRlIGRhdGEgY29sbGVjdGlvbiwgZmVhdHVyZSBlbmdpbmVlcmluZywgbW9kZWwgc2VsZWN0aW9uLCBhbmQgcmVzdWx0IGludGVycHJldGF0aW9uLiBIZXJl4oCZcyBob3cgdG8gZGVmaW5lIHRoZW0gYWNjdXJhdGVseS4NCg0KKipQcm9qZWN0cyBPYmplY3RpdmVzKioNCg0KT2JqZWN0aXZlcyBkZXNjcmliZSB0aGUgb3ZlcmFsbCBnb2FsIG9yIHB1cnBvc2Ugb2YgdGhlIHByb2plY3QuIFRoZXkgYXJlIHRoZSBkZXNpcmVkIG91dGNvbWVzIHRoYXQgdGhlIGFuYWx5c2lzIG9yIG1hY2hpbmUgbGVhcm5pbmcgbW9kZWwgYWltcyB0byBhY2hpZXZlLiBJbiBkYXRhIHNjaWVuY2UgYW5kIG1hY2hpbmUgbGVhcm5pbmcgcHJvamVjdHMsIG9iamVjdGl2ZXMgc2hvdWxkIGJlOg0KDQoqICpDbGVhciBhbmQgU3BlY2lmaWMqOiBUaGUgb2JqZWN0aXZlIHNob3VsZCBiZSB3ZWxsLWRlZmluZWQsIGxlYXZpbmcgbm8gYW1iaWd1aXR5IGFib3V0IHdoYXQgaXMgdG8gYmUgYWNoaWV2ZWQuIEZvciBleGFtcGxlLCBwcmVkaWN0aW5nIHRoZSBsaWtlbGlob29kIG9mIGN1c3RvbWVyIGNodXJuIGluIHRoZSBuZXh0IHF1YXJ0ZXIuDQoNCiogKk1lYXN1cmFibGUqOiBUaGUgb2JqZWN0aXZlIHNob3VsZCBiZSBxdWFudGlmaWFibGUgc28gdGhhdCBwcm9ncmVzcyBjYW4gYmUgdHJhY2tlZCBhbmQgc3VjY2VzcyBjYW4gYmUgZXZhbHVhdGVkLiBGb3IgZXhhbXBsZSwgSW5jcmVhc2luZyBwcmVkaWN0aW9uIGFjY3VyYWN5IG9mIGNodXJuIHJhdGUgYnkgMTUlIG92ZXIgYmFzZWxpbmUgbW9kZWxzLg0KDQoqICoqRmVhc2libGUqKjogRW5zdXJlIHRoYXQgdGhlIG9iamVjdGl2ZSBjYW4gYmUgcmVhbGlzdGljYWxseSBhY2hpZXZlZCB3aXRoaW4gdGhlIGNvbnN0cmFpbnRzIG9mIGRhdGEsIHRpbWUsIGFuZCByZXNvdXJjZXMgYXZhaWxhYmxlLiBGb3IgZXhhbXBsZSwgQnVpbGRpbmcgYSBtb2RlbCB3aXRoIGF0IGxlYXN0IDgwJSBhY2N1cmFjeSBiYXNlZCBvbiBhdmFpbGFibGUgZGF0YSBzb3VyY2VzLg0KDQoqICpBbGlnbmVkIEJ1c2luZXNzIE5lZWRzKjogVGhlIG9iamVjdGl2ZSBzaG91bGQgYWRkcmVzcyB0aGUgYnVzaW5lc3MgcHJvYmxlbSBvciByZXF1aXJlbWVudCBvZiB0aGUgc3Rha2Vob2xkZXJzLCB3aGV0aGVyIHRoZXkgYXJlIGJ1c2luZXNzIGxlYWRlcnMsIHJlc2VhcmNoZXJzLCBvciBjbGllbnRzLiBGb3IgZXhhbXBsZSwgUHJvdmlkaW5nIGFjdGlvbmFibGUgaW5zaWdodHMgdG8gcmVkdWNlIGN1c3RvbWVyIGNodXJuIGluIGEgc3Vic2NyaXB0aW9uLWJhc2VkIGJ1c2luZXNzLg0KDQoNCioqRm9ybXVsYXRpbmcgQW5hbHl0aWMgUXVlc3Rpb25zKioNCg0KKkFuYWx5dGljIFF1ZXN0aW9ucyogYXJlIHRoZSBzcGVjaWZpYyBpbnF1aXJpZXMgdGhhdCBndWlkZSB0aGUgYW5hbHlzaXMgb3IgbW9kZWxpbmcgcHJvY2Vzcy4gVGhlc2UgYXJlIG1vcmUgZGV0YWlsZWQgdGhhbiBvYmplY3RpdmVzIGFuZCBvZnRlbiBoZWxwIGluIGZvcm11bGF0aW5nIGh5cG90aGVzZXMgYW5kIGRlZmluaW5nIHRoZSBzY29wZSBvZiB0aGUgcHJvamVjdC4gV2VsbC1jcmFmdGVkIHF1ZXN0aW9ucyBzaG91bGQ6DQoNCiogKkJlIFJlbGV2YW50IHRvIHRoZSBQcm9ibGVtKjogKipBbmFseXRpYyBRdWVzdGlvbnMqKiBzaG91bGQgZGlyZWN0bHkgcmVsYXRlIHRvIHRoZSBwcm9ibGVtIHlvdSBhcmUgc29sdmluZyBvciB0aGUgb2JqZWN0aXZlIHlvdSBhaW0gdG8gYWNoaWV2ZS4gRm9yIGV4YW1wbGUsIFdoYXQgZmFjdG9ycyBhcmUgbW9zdCBzdHJvbmdseSBjb3JyZWxhdGVkIHdpdGggY3VzdG9tZXIgY2h1cm4gaW4gdGhlIGN1cnJlbnQgZGF0YXNldD8NCg0KKiAqQmUgQWN0aW9uYWJsZSo6ICoqQW5hbHl0aWMgUXVlc3Rpb25zKiogc2hvdWxkIGxlYWQgdG8gZmluZGluZ3Mgb3IgZGVjaXNpb25zIHRoYXQgY2FuIGJlIGFjdGVkIHVwb24uIEZvciBleGFtcGxlLCBjYW4gd2UgaWRlbnRpZnkgcG90ZW50aWFsIGhpZ2gtcmlzayBjdXN0b21lcnMgd2hvIGFyZSBsaWtlbHkgdG8gY2h1cm4gd2l0aGluIHRoZSBuZXh0IDMgbW9udGhzPw0KDQoqICpCZSBDbGVhciBhbmQgRm9jdXNlZCo6ICoqQW5hbHl0aWMgUXVlc3Rpb25zKiogc2hvdWxkIGJlIGNvbmNpc2UgYW5kIHByZWNpc2UuIEF2b2lkIHZhZ3VlIG9yIGJyb2FkIHF1ZXN0aW9ucyB0aGF0IG1heSBiZSBkaWZmaWN1bHQgdG8gYWRkcmVzcy4gRm9yIGV4YW1wbGUsIHdoYXQgYXJlIHRoZSB0b3AgcHJlZGljdG9ycyBvZiBob3VzZSBwcmljZSB2YXJpYXRpb24gaW4gdGhlIG1hcmtldD8gKGluc3RlYWQgb2YgV2hhdCBkZXRlcm1pbmVzIGhvdXNlIHByaWNlcz8pDQoNCiogKkJlIEh5cG90aGVzaXMtRHJpdmVuKjogSW4gbWFueSBjYXNlcywgKiphbmFseXRpYyBxdWVzdGlvbnMqKiB3aWxsIGJlIGJhc2VkIG9uIGEgaHlwb3RoZXNpcyB5b3Ugd2FudCB0byB0ZXN0IHRocm91Z2ggdGhlIGRhdGEuIEZvciBleGFtcGxlOiBEb2VzIHRoZSBudW1iZXIgb2YgYmVkcm9vbXMgaW4gYSBob3VzZSBzaWduaWZpY2FudGx5IGltcGFjdCBpdHMgcHJpY2U/DQoNCiogKkJlIFRlc3RhYmxlIHdpdGggRGF0YSo6ICoqQW5hbHl0aWMgUXVlc3Rpb25zKiogc2hvdWxkIGJlIGZvcm11bGF0ZWQgaW4gYSB3YXkgdGhhdCB0aGV5IGNhbiBiZSBhZGRyZXNzZWQgdXNpbmcgdGhlIGF2YWlsYWJsZSBkYXRhIGFuZCBhbmFseXNpcyB0ZWNobmlxdWVzLiBGb3IgZXhhbXBsZTogQ2FuIHdlIHVzZSBjdXN0b21lciBkZW1vZ3JhcGhpYyBkYXRhIHRvIHByZWRpY3QgcHVyY2hhc2luZyBiZWhhdmlvcj8NCg0KKiAqQWNjb3VudCBmb3IgQ29uc3RyYWludHMqOiBDb25zaWRlciB3aGV0aGVyIHRoZSBxdWVzdGlvbnMgY2FuIGJlIGFuc3dlcmVkIHdpdGhpbiB0aGUgYXZhaWxhYmxlIHRpbWUsIGRhdGEsIGFuZCByZXNvdXJjZXMuIEZvciBleGFtcGxlLCBoSG93IGNhbiB3ZSBwcmVkaWN0IHRoZSBsaWtlbGlob29kIG9mIGxvYW4gYXBwcm92YWwgYmFzZWQgb24gaW5jb21lLCBjcmVkaXQgc2NvcmUsIGFuZCBlbXBsb3ltZW50IGhpc3RvcnksIGdpdmVuIHRoZSBhdmFpbGFibGUgZGF0YT8NCg0KKipTb21lIFdlbGwtY3JhZnRlZCBFeGFtcGxlIEFuYWx5dGljIFF1ZXN0aW9ucyoqDQoNCiogV2hhdCBhcmUgdGhlIGtleSBkcml2ZXJzIG9mIGN1c3RvbWVyIHNhdGlzZmFjdGlvbiBpbiBvdXIgb25saW5lIHJldGFpbCBwbGF0Zm9ybT8NCg0KKiBJcyB0aGVyZSBhIHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGluY29tZSBhbmQgc3BlbmRpbmcgcGF0dGVybnMgaW4gZGlmZmVyZW50IGRlbW9ncmFwaGljIGdyb3Vwcz8NCg0KKiBIb3cgY2FuIHdlIGltcHJvdmUgdGhlIGFjY3VyYWN5IG9mIGZyYXVkIGRldGVjdGlvbiBpbiBjcmVkaXQgY2FyZCB0cmFuc2FjdGlvbnMgdXNpbmcgbWFjaGluZSBsZWFybmluZyBtb2RlbHM/DQoNCg0KIyMgRGF0YSBDb2xsZWN0aW9uIGFuZCBQcmVwYXJhdGlvbg0KDQpEYXRhIGNvbGxlY3Rpb24gYW5kIHByZXBhcmF0aW9uIGFyZSBjcnVjaWFsIHN0ZXBzIGluIHRoZSBtYWNoaW5lIGxlYXJuaW5nIChNTCkgcGlwZWxpbmUsIHNlcnZpbmcgYXMgdGhlIGZvdW5kYXRpb24gZm9yIGJ1aWxkaW5nIGVmZmVjdGl2ZSBhbmQgcmVsaWFibGUgbW9kZWxzLiBXaXRob3V0IGhpZ2gtcXVhbGl0eSwgcmVsZXZhbnQgZGF0YSwgZXZlbiB0aGUgbW9zdCBhZHZhbmNlZCBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobXMgYXJlIHVubGlrZWx5IHRvIGRlbGl2ZXIgbWVhbmluZ2Z1bCBvciBhY2N1cmF0ZSByZXN1bHRzLiBUaGlzIHN1YnNlY3Rpb24gZXhwbG9yZXMgdGhlIGltcG9ydGFuY2Ugb2YgZGF0YSBjb2xsZWN0aW9uIGFuZCBwcmVwYXJhdGlvbiBpbiB0aGUgY29udGV4dCBvZiBtYWNoaW5lIGxlYXJuaW5nLCBvdXRsaW5pbmcgdGhlIHByb2Nlc3NlcyBpbnZvbHZlZCwgY2hhbGxlbmdlcyBmYWNlZCwgYW5kIGJlc3QgcHJhY3RpY2VzIGZvciBlbnN1cmluZyB0aGF0IGRhdGEgaXMgc3VpdGFibGUgZm9yIGFuYWx5c2lzLg0KDQojIyMgRGF0YSBDb2xsZWN0aW9uDQoNCkRhdGEgY29sbGVjdGlvbiBpcyB0aGUgZmlyc3QgYW5kIG1vc3QgY3JpdGljYWwgc3RlcCBpbiB0aGUgbWFjaGluZSBsZWFybmluZyBwaXBlbGluZS4gSXQgaW52b2x2ZXMgYWNxdWlyaW5nIHRoZSBkYXRhIG5lZWRlZCB0byBzb2x2ZSBhIHNwZWNpZmljIHByb2JsZW0uIFRoaXMgc3RlcCBtdXN0IGZvY3VzIG9uIGdhdGhlcmluZyBkYXRhIHRoYXQgaXMgcmVsZXZhbnQsIGRpdmVyc2UsIGFuZCByZXByZXNlbnRhdGl2ZSBvZiB0aGUgcHJvYmxlbSBkb21haW4uIFRoZSBmb2xsb3dpbmcgYXJlIGtleSBjb25zaWRlcmF0aW9ucyBkdXJpbmcgZGF0YSBjb2xsZWN0aW9uOg0KDQoqICoqU291cmNlIElkZW50aWZpY2F0aW9uKio6IFRoZSBmaXJzdCBzdGVwIGlzIGlkZW50aWZ5aW5nIHRoZSBkYXRhIHNvdXJjZXMuIFRoZXNlIGNhbiBpbmNsdWRlIGludGVybmFsIGRhdGFiYXNlcywgcHVibGljIGRhdGFzZXRzLCBBUElzLCBvciB0aGlyZC1wYXJ0eSBwcm92aWRlcnMuIFRoZSBxdWFsaXR5IG9mIHRoZSBkYXRhIGRlcGVuZHMgb24gdGhlIGNyZWRpYmlsaXR5IGFuZCByZWxldmFuY2Ugb2YgdGhlIHNvdXJjZXMuICBGb3IgZXhhbXBsZSwgaW4gdGhlIGN1c3RvbWVyIGNodXJuIHByZWRpY3Rpb24gbW9kZWxpbmcsIGRhdGEgY291bGQgYmUgY29sbGVjdGVkIGZyb20gY3VzdG9tZXIgZGF0YWJhc2VzLCB0cmFuc2FjdGlvbiByZWNvcmRzLCBjdXN0b21lciBzdXBwb3J0IGludGVyYWN0aW9ucywgYW5kIHdlYiBhbmFseXRpY3MuDQoNCiogKipEYXRhIFZvbHVtZSBhbmQgVmFyaWV0eSoqOiBBIGNvbW1vbiBjaGFsbGVuZ2UgaW4gbWFjaGluZSBsZWFybmluZyBpcyBjb2xsZWN0aW5nIGVub3VnaCBkYXRhIHRvIGFjY3VyYXRlbHkgcmVwcmVzZW50IHRoZSBwcm9ibGVtLiBNYWNoaW5lIGxlYXJuaW5nIG1vZGVscyBvZnRlbiBwZXJmb3JtIGJldHRlciB3aXRoIGxhcmdlLCBkaXZlcnNlIGRhdGFzZXRzIHRoYXQgY2FwdHVyZSB0aGUgZnVsbCByYW5nZSBvZiBwb3NzaWJsZSBpbnB1dHMgYW5kIHNjZW5hcmlvcy4NCg0KKiAqKkRhdGEgUmVsZXZhbmNlKio6IFRoZSBkYXRhIGNvbGxlY3RlZCBtdXN0IGJlIGRpcmVjdGx5IHJlbGV2YW50IHRvIHRoZSB0YXNrIGF0IGhhbmQuIElycmVsZXZhbnQgZGF0YSBub3Qgb25seSBhZGRzIHVubmVjZXNzYXJ5IGNvbXBsZXhpdHkgYnV0IGNhbiBhbHNvIGludHJvZHVjZSBub2lzZSB0aGF0IGhpbmRlcnMgbW9kZWwgcGVyZm9ybWFuY2UuDQoNCiogKipEYXRhIFByaXZhY3kgYW5kIEV0aGljcyoqOiBDb2xsZWN0aW5nIGRhdGEgbXVzdCBiZSBkb25lIGV0aGljYWxseSwgZW5zdXJpbmcgdGhhdCBwZXJzb25hbCBhbmQgc2Vuc2l0aXZlIGluZm9ybWF0aW9uIGlzIGhhbmRsZWQgcmVzcG9uc2libHkuIFRoaXMgaW5jbHVkZXMgYWRoZXJpbmcgdG8gZGF0YSBwcm90ZWN0aW9uIHJlZ3VsYXRpb25zIGxpa2UgR0RQUiBhbmQgb2J0YWluaW5nIGluZm9ybWVkIGNvbnNlbnQgZnJvbSBpbmRpdmlkdWFscyB3aGVyZSBuZWNlc3NhcnkuDQoNCiogKipEYXRhIEludGVncmF0aW9uKio6IEluIG1hbnkgY2FzZXMsIGRhdGEgbWF5IGNvbWUgZnJvbSBtdWx0aXBsZSBzb3VyY2VzLCBlYWNoIHdpdGggaXRzIG93biBzdHJ1Y3R1cmUgYW5kIGZvcm1hdC4gSW50ZWdyYXRpbmcgZGlzcGFyYXRlIGRhdGFzZXRzIHdoaWxlIGVuc3VyaW5nIGNvbnNpc3RlbmN5IGFuZCBpbnRlZ3JpdHkgaXMgYSB2aXRhbCBwYXJ0IG9mIHRoZSBjb2xsZWN0aW9uIHBoYXNlLg0KDQoNCiMjIyBEYXRhIFByZXBhcmF0aW9uDQoNCk9uY2UgZGF0YSBoYXMgYmVlbiBjb2xsZWN0ZWQsIHRoZSBuZXh0IGNyaXRpY2FsIHN0ZXAgaXMgcHJlcGFyaW5nIGl0IGZvciBhbmFseXNpcy4gRGF0YSBwcmVwYXJhdGlvbiBlbmNvbXBhc3NlcyBzZXZlcmFsIHByb2Nlc3NlcywgaW5jbHVkaW5nIGNsZWFuaW5nLCB0cmFuc2Zvcm1hdGlvbiwgYW5kIGZlYXR1cmUgZW5naW5lZXJpbmcuIFRoZSBnb2FsIGlzIHRvIGVuc3VyZSB0aGF0IHRoZSBkYXRhIGlzIGNsZWFuLCBjb21wbGV0ZSwgYW5kIGluIGEgZm9ybWF0IHRoYXQgaXMgY29tcGF0aWJsZSB3aXRoIG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtcy4gS2V5IHN0ZXBzIGluIGRhdGEgcHJlcGFyYXRpb24gaW5jbHVkZToNCg0KKipEYXRhIENsZWFuaW5nKiogDQoNClJhdyBkYXRhIGlzIG9mdGVuIG1lc3N5IGFuZCBpbmNvbXBsZXRlLCBjb250YWluaW5nIGVycm9ycywgaW5jb25zaXN0ZW5jaWVzLCBvciBtaXNzaW5nIHZhbHVlcy4gQ2xlYW5pbmcgdGhlIGRhdGEgaW52b2x2ZXM6DQoNCiogKipIYW5kbGluZyBNaXNzaW5nIFZhbHVlcyoqOiBEYXRhIG1heSBoYXZlIG1pc3Npbmcgb3IgbnVsbCB2YWx1ZXMgZHVlIHRvIGVycm9ycyBpbiBkYXRhIGNvbGxlY3Rpb24gb3IgdXNlciBiZWhhdmlvci4gVGhlc2UgbWlzc2luZyB2YWx1ZXMgY2FuIGJlIGhhbmRsZWQgYnkgcmVtb3Zpbmcgcm93cywgaW1wdXRpbmcgbWlzc2luZyB2YWx1ZXMgYmFzZWQgb24gb3RoZXIgZGF0YSBwb2ludHMsIG9yIHVzaW5nIGFsZ29yaXRobXMgdGhhdCBoYW5kbGUgbWlzc2luZyBkYXRhIG5hdHVyYWxseS4NCg0KKiAqKlJlbW92aW5nIER1cGxpY2F0ZXMqKjogRHVwbGljYXRlIHJlY29yZHMgY2FuIHNrZXcgYW5hbHlzaXMgYW5kIG5lZ2F0aXZlbHkgYWZmZWN0IG1vZGVsIHRyYWluaW5nLiBJZGVudGlmeWluZyBhbmQgcmVtb3ZpbmcgZHVwbGljYXRlcyBpcyBhIGNydWNpYWwgc3RlcC4NCg0KKiAqKkZpeGluZyBFcnJvcnMqKjogRXJyb3JzIGluIGRhdGEsIHN1Y2ggYXMgaW5jb3JyZWN0IGxhYmVscywgbWlzZm9ybWF0dGVkIGRhdGVzLCBvciBvdXRsaWVycywgbXVzdCBiZSBhZGRyZXNzZWQgdG8gZW5zdXJlIGRhdGEgcXVhbGl0eS4NCg0KKiAqKkRhdGEgVHJhbnNmb3JtYXRpb24qKjogRGF0YSB0cmFuc2Zvcm1hdGlvbiBpbnZvbHZlcyBjb252ZXJ0aW5nIGRhdGEgaW50byBhIHVzYWJsZSBmb3JtYXQuIFRoaXMgaW5jbHVkZXMgc2NhbGluZywgbm9ybWFsaXppbmcsIG9yIGVuY29kaW5nIGZlYXR1cmVzIHRvIGVuc3VyZSB0aGF0IHRoZSBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobSBjYW4gcHJvY2VzcyB0aGUgZGF0YSBlZmZlY3RpdmVseS4NCg0KXA0KDQoqKlNjYWxpbmcgYW5kIE5vcm1hbGl6YXRpb24qKiANCg0KTWFjaGluZSBsZWFybmluZyBhbGdvcml0aG1zLCBlc3BlY2lhbGx5IHRob3NlIHRoYXQgcmVseSBvbiBkaXN0YW5jZSBtZXRyaWNzIGxpa2Ugay1uZWFyZXN0IG5laWdoYm9ycyAoS05OKSBvciBncmFkaWVudCBkZXNjZW50LCByZXF1aXJlIGZlYXR1cmVzIHRvIGJlIG9uIHNpbWlsYXIgc2NhbGVzLiBOb3JtYWxpemluZyBvciBzdGFuZGFyZGl6aW5nIHRoZSBkYXRhIGVuc3VyZXMgdGhhdCBhbGwgZmVhdHVyZXMgY29udHJpYnV0ZSBlcXVhbGx5IHRvIHRoZSBtb2RlbC4NCg0KKiAqKkVuY29kaW5nIENhdGVnb3JpY2FsIFZhcmlhYmxlcyoqOiBNYW55IG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtcyBjYW5ub3Qgd29yayBkaXJlY3RseSB3aXRoIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyAoZS5nLiwgZ2VuZGVyLCBjb3VudHJ5LCBvciBwcm9kdWN0IGNhdGVnb3J5KS4gVGVjaG5pcXVlcyBsaWtlIG9uZS1ob3QgZW5jb2Rpbmcgb3IgbGFiZWwgZW5jb2RpbmcgYXJlIHVzZWQgdG8gY29udmVydCB0aGVzZSB2YXJpYWJsZXMgaW50byBudW1lcmljYWwgZm9ybS4NCg0KKiAqKkZlYXR1cmUgRW5naW5lZXJpbmcqKjogVGhpcyBwcm9jZXNzIGludm9sdmVzIGNyZWF0aW5nIG5ldyBmZWF0dXJlcyBvciBtb2RpZnlpbmcgZXhpc3Rpbmcgb25lcyB0byBpbXByb3ZlIG1vZGVsIHBlcmZvcm1hbmNlLiBGb3IgZXhhbXBsZSwgY29tYmluaW5nIGRhdGUgYW5kIHRpbWUgZmllbGRzIGludG8gYSAiZGF5IG9mIHRoZSB3ZWVrIiBmZWF0dXJlIG9yIGNhbGN1bGF0aW5nIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIHRpbWVzdGFtcCBjb2x1bW5zIGNhbiBwcm92aWRlIG1vcmUgbWVhbmluZ2Z1bCBpbnB1dHMgZm9yIHRoZSBtb2RlbC4NCg0KKipEYXRhIFNwbGl0dGluZyoqDQoNClRvIGFzc2VzcyBtb2RlbCBwZXJmb3JtYW5jZSBhbmQgcHJldmVudCBvdmVyZml0dGluZywgdGhlIGRhdGFzZXQgaXMgdXN1YWxseSBzcGxpdCBpbnRvIHRyYWluaW5nLCB2YWxpZGF0aW9uLCBhbmQgdGVzdGluZyBzZXRzLiBUaGUgdHJhaW5pbmcgc2V0IGlzIHVzZWQgdG8gYnVpbGQgdGhlIG1vZGVsLCB0aGUgdmFsaWRhdGlvbiBzZXQgaGVscHMgdHVuZSBoeXBlcnBhcmFtZXRlcnMsIGFuZCB0aGUgdGVzdGluZyBzZXQgZXZhbHVhdGVzIHRoZSBtb2RlbOKAmXMgZ2VuZXJhbGl6YXRpb24gYWJpbGl0eS4NCg0KKipPdXRsaWVyIERldGVjdGlvbioqDQoNCk91dGxpZXJzIGFyZSBkYXRhIHBvaW50cyB0aGF0IGRpZmZlciBzaWduaWZpY2FudGx5IGZyb20gb3RoZXJzIGFuZCBjYW4gZGlzdG9ydCB0aGUgcmVzdWx0cyBvZiBhIG1vZGVsLiBEZXRlY3RpbmcgYW5kIGhhbmRsaW5nIG91dGxpZXJzIGlzIGNydWNpYWwgZm9yIHByZXZlbnRpbmcgdGhlc2UgdmFsdWVzIGZyb20gbmVnYXRpdmVseSBpbmZsdWVuY2luZyB0aGUgbW9kZWwncyBwcmVkaWN0aW9ucy4NCg0KKipEYXRhIEF1Z21lbnRhdGlvbioqDQoNCkluIHNvbWUgY2FzZXMsIGVzcGVjaWFsbHkgd2hlbiB3b3JraW5nIHdpdGggaW1hZ2VzIG9yIHRleHQsIGRhdGEgYXVnbWVudGF0aW9uIHRlY2huaXF1ZXMgbGlrZSByb3RhdGlvbiwgY3JvcHBpbmcsIG9yIHRleHQgcGFyYXBocmFzaW5nIGNhbiBiZSB1c2VkIHRvIGFydGlmaWNpYWxseSBleHBhbmQgdGhlIGRhdGFzZXQgYW5kIGltcHJvdmUgbW9kZWwgcm9idXN0bmVzcy4NCg0KDQojIyMgQmVzdCBQcmFjdGljZXMNCg0KVG8gb3ZlcmNvbWUgdGhlc2UgY2hhbGxlbmdlcyBhbmQgZW5zdXJlIHN1Y2Nlc3NmdWwgbWFjaGluZSBsZWFybmluZyBwcm9qZWN0cywgdGhlIGZvbGxvd2luZyBiZXN0IHByYWN0aWNlcyBzaG91bGQgYmUgZm9sbG93ZWQ6DQoNCiogKipVbmRlcnN0YW5kIHRoZSBQcm9ibGVtIERvbWFpbioqOiBDb2xsYWJvcmF0ZSB3aXRoIGRvbWFpbiBleHBlcnRzIHRvIGVuc3VyZSB0aGUgZGF0YSBjb2xsZWN0ZWQgaXMgcmVsZXZhbnQgYW5kIHVzZWZ1bCBmb3IgdGhlIHByb2JsZW0gYmVpbmcgc29sdmVkLg0KDQoqICoqQXV0b21hdGUgRGF0YSBDb2xsZWN0aW9uKio6IFdoZW5ldmVyIHBvc3NpYmxlLCBhdXRvbWF0ZSB0aGUgZGF0YSBjb2xsZWN0aW9uIHByb2Nlc3MgdG8gaW1wcm92ZSBlZmZpY2llbmN5IGFuZCBjb25zaXN0ZW5jeS4NCg0KKiAqKkl0ZXJhdGUgYW5kIFJlZmluZSoqOiBEYXRhIHByZXBhcmF0aW9uIGlzIG5vdCBhIG9uZS10aW1lIHRhc2suIEl04oCZcyBpbXBvcnRhbnQgdG8gaXRlcmF0ZSBhbmQgcmVmaW5lIHRoZSBkYXRhc2V0IGFzIHRoZSBtb2RlbCBpcyBkZXZlbG9wZWQgYW5kIGFzIG5ldyBkYXRhIGJlY29tZXMgYXZhaWxhYmxlLg0KDQoqICoqRG9jdW1lbnQgdGhlIFByb2Nlc3MqKjogS2VlcCBkZXRhaWxlZCByZWNvcmRzIG9mIHRoZSBkYXRhIGNvbGxlY3Rpb24gYW5kIHByZXBhcmF0aW9uIHN0ZXBzLiBUaGlzIGVuc3VyZXMgdHJhbnNwYXJlbmN5IGFuZCByZXByb2R1Y2liaWxpdHksIHdoaWNoIGlzIGVzcGVjaWFsbHkgaW1wb3J0YW50IGZvciBjb2xsYWJvcmF0aXZlIGFuZCByZWd1bGF0b3J5IGNvbXBsaWFuY2UuDQoNCiogKipUZXN0IGZvciBCaWFzKio6IFJlZ3VsYXJseSB0ZXN0IHRoZSBkYXRhIGZvciBiaWFzIGFuZCBlbnN1cmUgdGhhdCB0aGUgbW9kZWwgaXMgdHJhaW5lZCBvbiByZXByZXNlbnRhdGl2ZSBhbmQgZGl2ZXJzZSBkYXRhc2V0cy4NCg0KXA0KDQoqKkluIHN1bW1hcnkqKiwgZGF0YSBjb2xsZWN0aW9uIGFuZCBwcmVwYXJhdGlvbiBhcmUgZm91bmRhdGlvbmFsIHN0ZXBzIGluIG1hY2hpbmUgbGVhcm5pbmcsIGRpcmVjdGx5IGluZmx1ZW5jaW5nIHRoZSBxdWFsaXR5IGFuZCBlZmZlY3RpdmVuZXNzIG9mIHRoZSByZXN1bHRpbmcgbW9kZWxzLiBFbnN1cmluZyB0aGUgZGF0YSBpcyByZWxldmFudCwgY2xlYW4sIGFuZCBwcm9wZXJseSBmb3JtYXR0ZWQgaXMgY3JpdGljYWwgZm9yIGRldmVsb3BpbmcgbW9kZWxzIHRoYXQgY2FuIG1ha2UgYWNjdXJhdGUgcHJlZGljdGlvbnMgYW5kIHByb3ZpZGUgdmFsdWFibGUgaW5zaWdodHMuIEJ5IGNhcmVmdWxseSBtYW5hZ2luZyB0aGVzZSBzdGFnZXMsIGRhdGEgc2NpZW50aXN0cyBjYW4gYnVpbGQgcmVsaWFibGUsIHNjYWxhYmxlIG1vZGVscyB0aGF0IHBlcmZvcm0gd2VsbCBpbiByZWFsLXdvcmxkIGFwcGxpY2F0aW9ucy4gQXMgbWFjaGluZSBsZWFybmluZyBjb250aW51ZXMgdG8gZXZvbHZlLCBtYXN0ZXJpbmcgZGF0YSBjb2xsZWN0aW9uIGFuZCBwcmVwYXJhdGlvbiB3aWxsIHJlbWFpbiBhbiBlc3NlbnRpYWwgc2tpbGwgZm9yIGRhdGEgc2NpZW50aXN0cyBhbmQgbWFjaGluZSBsZWFybmluZyBwcmFjdGl0aW9uZXJzLg0KDQpcDQoNCiMjIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMgKEVEQSkNCg0KRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcyAoRURBKSBpcyBhIGNydWNpYWwgc3RlcCBpbiB0aGUgbWFjaGluZSBsZWFybmluZyB3b3JrZmxvdywgc2VydmluZyBhcyBhbiBpbml0aWFsIGludmVzdGlnYXRpb24gaW50byB0aGUgZGF0YXNldCB0byB1bmNvdmVyIHVuZGVybHlpbmcgcGF0dGVybnMsIHJlbGF0aW9uc2hpcHMsIGFuZCBwb3RlbnRpYWwgaXNzdWVzLiBFREEgaW52b2x2ZXMgYW5hbHl6aW5nIHRoZSBkYXRhJ3Mgc3RydWN0dXJlIGFuZCBkaXN0cmlidXRpb24sIGdlbmVyYXRpbmcgaHlwb3RoZXNlcywgYW5kIGlkZW50aWZ5aW5nIHRyZW5kcyBvciBhbm9tYWxpZXMgdGhhdCBtaWdodCBpbmZsdWVuY2Ugc3Vic2VxdWVudCBtb2RlbGluZyBkZWNpc2lvbnMuIEl0IGhlbHBzIGRhdGEgc2NpZW50aXN0cyBhbmQgbWFjaGluZSBsZWFybmluZyBwcmFjdGl0aW9uZXJzIHVuZGVyc3RhbmQgdGhlIGRhdGEgYmVmb3JlIGRpdmluZyBpbnRvIGNvbXBsZXggYWxnb3JpdGhtcywgZW5zdXJpbmcgYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZiB0aGUgZGF0YXNldCwgaW1wcm92ZWQgZGF0YSBwcmVwcm9jZXNzaW5nLCBhbmQgbW9yZSBlZmZlY3RpdmUgbW9kZWwgc2VsZWN0aW9uLg0KDQojIyMgVGhlIFJvbGUgb2YgRURBIGluIE1hY2hpbmUgTGVhcm5pbmcNCg0KRURBIHByb3ZpZGVzIGEgZm91bmRhdGlvbmFsIHVuZGVyc3RhbmRpbmcgb2YgdGhlIGRhdGFzZXQsIGVuc3VyaW5nIHRoYXQgZGF0YSBzY2llbnRpc3RzIGNhbiBtYWtlIGluZm9ybWVkIGRlY2lzaW9ucyBkdXJpbmcgdGhlIG1vZGVsaW5nIHBoYXNlLiBCeSBleHBsb3JpbmcgdGhlIGRhdGEgdmlzdWFsbHkgYW5kIHN0YXRpc3RpY2FsbHksIEVEQSBoZWxwcyBpZGVudGlmeSBrZXkgaW5zaWdodHMsIGRldGVjdCBlcnJvcnMsIGFuZCByZXZlYWwgYXNwZWN0cyBvZiB0aGUgZGF0YSB0aGF0IG1pZ2h0IG90aGVyd2lzZSByZW1haW4gaGlkZGVuLiBUaGlzIHN0ZXAgaXMgdml0YWwgYmVjYXVzZSB0aGUgcXVhbGl0eSBvZiB0aGUgZGF0YSB1c2VkIGluIG1hY2hpbmUgbGVhcm5pbmcgZGlyZWN0bHkgYWZmZWN0cyB0aGUgbW9kZWwncyBwZXJmb3JtYW5jZSwgYW5kIHRoZSBpbnNpZ2h0cyBnYWluZWQgZHVyaW5nIEVEQSBjYW4gZ3VpZGUgZnVydGhlciBkYXRhIGNsZWFuaW5nLCBmZWF0dXJlIGVuZ2luZWVyaW5nLCBhbmQgbW9kZWwgcmVmaW5lbWVudC4NCg0KV2UgbmV4dCBsaXN0IHNvbWUgb2YgdGhlIGtleSBzdGVwcyBpbiBFREEuDQoNCg0KKioxLiBVbmRlcnN0YW5kaW5nIHRoZSBEYXRhc2V0IFN0cnVjdHVyZSoqDQoNClRoZSBmaXJzdCBzdGVwIGluIEVEQSBpcyB1bmRlcnN0YW5kaW5nIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGFzZXQuIFRoaXMgaW52b2x2ZXMgY2hlY2tpbmcgdGhlIG51bWJlciBvZiByb3dzIChkYXRhIHBvaW50cykgYW5kIGNvbHVtbnMgKGZlYXR1cmVzKSwgYW5kIHVuZGVyc3RhbmRpbmcgdGhlIGRhdGEgdHlwZXMgb2YgZWFjaCBmZWF0dXJlIChlLmcuLCBjYXRlZ29yaWNhbCwgbnVtZXJpY2FsLCB0ZXh0KS4gVGhpcyBzdGVwIGlzIGZ1bmRhbWVudGFsIGZvciBkZXRlcm1pbmluZyBob3cgdGhlIGRhdGEgY2FuIGJlIHByb2Nlc3NlZCBvciB0cmFuc2Zvcm1lZCBmb3IgYW5hbHlzaXMuDQoNCioqRXhhbXBsZSoqOiBBIGRhdGFzZXQgd2l0aCBjdXN0b21lciBpbmZvcm1hdGlvbiBtYXkgaW5jbHVkZSBmZWF0dXJlcyBsaWtlICJhZ2UsIiAiaW5jb21lLCIgYW5kICJnZW5kZXIuIiBVbmRlcnN0YW5kaW5nIHdoZXRoZXIgdGhlc2UgZmVhdHVyZXMgYXJlIG51bWVyaWNhbCBvciBjYXRlZ29yaWNhbCBoZWxwcyBpbiBjaG9vc2luZyB0aGUgcmlnaHQgc3RhdGlzdGljYWwgdGVjaG5pcXVlcyBvciBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobXMuDQoNCioqMi4gRGVzY3JpcHRpdmUgU3RhdGlzdGljcyoqIA0KDQpEZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIHN1bW1hcml6ZSB0aGUgY2VudHJhbCB0ZW5kZW5jaWVzLCB2YXJpYWJpbGl0eSwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGF0YS4gS2V5IG1ldHJpY3MgaW5jbHVkZSB0aGUgbWVhbiwgbWVkaWFuLCBzdGFuZGFyZCBkZXZpYXRpb24sIG1pbmltdW0sIGFuZCBtYXhpbXVtIHZhbHVlcyBmb3IgbnVtZXJpY2FsIGZlYXR1cmVzLCBhbmQgZnJlcXVlbmN5IGNvdW50cyBmb3IgY2F0ZWdvcmljYWwgZmVhdHVyZXMuIFRoZXNlIHN0YXRpc3RpY3Mgb2ZmZXIgYW4gaW5pdGlhbCBvdmVydmlldyBvZiB0aGUgZGF0YSdzIGNoYXJhY3RlcmlzdGljcywgaGVscGluZyBpZGVudGlmeSBhbnkgb2J2aW91cyBkYXRhIGlzc3VlcyBvciBza2V3ZWQgZGlzdHJpYnV0aW9ucy4NCg0KKipFeGFtcGxlKio6IEZvciBhIG51bWVyaWNhbCBmZWF0dXJlIGxpa2UgImFnZSwiIGNoZWNraW5nIHRoZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gY2FuIGhpZ2hsaWdodCBpZiB0aGVyZSBhcmUgZXh0cmVtZSBvdXRsaWVycyBvciBpZiB0aGUgZGF0YSBpcyBoZWF2aWx5IHNrZXdlZC4NCg0KKiozLiBEYXRhIFZpc3VhbGl6YXRpb24qKiANCg0KVmlzdWFsaXphdGlvbnMgYXJlIGFuIGVzc2VudGlhbCBwYXJ0IG9mIEVEQSwgYWxsb3dpbmcgZGF0YSBzY2llbnRpc3RzIHRvIGlkZW50aWZ5IHBhdHRlcm5zLCB0cmVuZHMsIGFuZCByZWxhdGlvbnNoaXBzIGJldHdlZW4gZmVhdHVyZXMgbW9yZSBpbnR1aXRpdmVseS4gQ29tbW9uIHZpc3VhbGl6YXRpb25zIHVzZWQgaW4gRURBIGluY2x1ZGU6DQoNCiogKkhpc3RvZ3JhbXMqOiBTaG93IHRoZSBkaXN0cmlidXRpb24gb2YgbnVtZXJpY2FsIGRhdGEsIGhlbHBpbmcgdG8gdW5kZXJzdGFuZCB0aGUgc3ByZWFkIGFuZCBza2V3bmVzcyBvZiB2YXJpYWJsZXMuDQoNCiogKkJveCBQbG90cyo6IEhlbHAgaWRlbnRpZnkgb3V0bGllcnMgYW5kIHRoZSBzcHJlYWQgb2YgZGF0YSwgc2hvd2luZyB0aGUgbWVkaWFuLCBxdWFydGlsZXMsIGFuZCBhbnkgZXh0cmVtZSB2YWx1ZXMuDQoNCiogKlNjYXR0ZXIgUGxvdHMqOiBTaG93IHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB0d28gbnVtZXJpY2FsIHZhcmlhYmxlcyBhbmQgY2FuIGhpZ2hsaWdodCBjb3JyZWxhdGlvbnMgb3IgdGhlIGFic2VuY2Ugb2YgdGhlbS4NCg0KKiAqQ29ycmVsYXRpb24gSGVhdG1hcHMqOiBTaG93IHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gZGlmZmVyZW50IG51bWVyaWNhbCBmZWF0dXJlcywgaGlnaGxpZ2h0aW5nIGNvcnJlbGF0aW9ucyB0aGF0IGNvdWxkIGJlIGltcG9ydGFudCBmb3IgcHJlZGljdGl2ZSBtb2RlbGluZy4NCg0KKipFeGFtcGxlKio6IEEgc2NhdHRlciBwbG90IG9mICJhZ2UiIHZzLiAiaW5jb21lIiBtaWdodCByZXZlYWwgYSB0cmVuZCB3aGVyZSB5b3VuZ2VyIGN1c3RvbWVycyBoYXZlIGxvd2VyIGluY29tZSwgd2hpbGUgb2xkZXIgY3VzdG9tZXJzIGVhcm4gaGlnaGVyIHNhbGFyaWVzLiBUaGlzIGluc2lnaHQgY291bGQgaW5mbHVlbmNlIG1vZGVsIGZlYXR1cmUgc2VsZWN0aW9uIG9yIHRyYW5zZm9ybWF0aW9uLg0KDQoNCioqNC4gSGFuZGxpbmcgTWlzc2luZyBEYXRhKiogDQoNCk9uZSBvZiB0aGUgbW9zdCBjb21tb24gaXNzdWVzIGVuY291bnRlcmVkIGluIHJlYWwtd29ybGQgZGF0YSBzZXRzIGlzIG1pc3NpbmcgZGF0YS4gRURBIGhlbHBzIGlkZW50aWZ5IHdoaWNoIGZlYXR1cmVzIGhhdmUgbWlzc2luZyB2YWx1ZXMsIGFuZCB0aGUgZXh0ZW50IG9mIG1pc3NpbmduZXNzLiBXZSB3aWxsIHVzZSBhIHdlZWsgdG8gZGlzY3VzcyB2YXJpb3VzIGltcHV0YXRpb24gbWV0aG9kcy4gTm8gZGV0YWlscyB3aWxsIGJlIHByb3ZpZGVkIGluIHRoaXMgbm90ZS4NCg0KDQoqKjUuIElkZW50aWZ5aW5nIE91dGxpZXJzKioNCg0KT3V0bGllcnMgYXJlIGRhdGEgcG9pbnRzIHRoYXQgZGlmZmVyIHNpZ25pZmljYW50bHkgZnJvbSB0aGUgcmVzdCBvZiB0aGUgZGF0YXNldC4gRURBIGhlbHBzIGluIGlkZW50aWZ5aW5nIG91dGxpZXJzIHRoYXQgY291bGQgc2tldyBtb2RlbCBwZXJmb3JtYW5jZSBvciBsZWFkIHRvIGluY29ycmVjdCBwcmVkaWN0aW9ucy4gVGVjaG5pcXVlcyBzdWNoIGFzIGJveCBwbG90cyBvciBaLXNjb3JlcyBhcmUgb2Z0ZW4gdXNlZCB0byBkZXRlY3QgdGhlc2UgZXh0cmVtZSB2YWx1ZXMuIEluIHNvbWUgY2FzZXMsIG91dGxpZXJzIGFyZSBnZW51aW5lIG9ic2VydmF0aW9ucywgd2hpbGUgaW4gb3RoZXJzLCB0aGV5IG1heSBiZSBlcnJvcnMgdGhhdCBuZWVkIHRvIGJlIGFkZHJlc3NlZC4NCg0KKipFeGFtcGxlKio6IEluIGEgZGF0YXNldCBvZiBob3VzZSBwcmljZXMsIGFuIG91dGxpZXIgY291bGQgYmUgYSBtYW5zaW9uIHByaWNlZCBmYXIgYmVsb3cgdGhlIG1hcmtldCByYXRlLiBUaGlzIGNvdWxkIGVpdGhlciBiZSBhIHJhcmUgYnV0IHZhbGlkIGluc3RhbmNlIG9yIGFuIGVycm9yIGluIHRoZSBkYXRhIGVudHJ5IHByb2Nlc3MgdGhhdCByZXF1aXJlcyBjb3JyZWN0aW9uLg0KDQoqKjYuIEV4cGxvcmluZyBSZWxhdGlvbnNoaXBzIEJldHdlZW4gVmFyaWFibGVzKiogDQoNCkVEQSBhbHNvIGludm9sdmVzIGludmVzdGlnYXRpbmcgdGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB2YXJpYWJsZXMuIFRoaXMgaGVscHMgaWRlbnRpZnkgd2hldGhlciBhbnkgZmVhdHVyZXMgYXJlIGNvcnJlbGF0ZWQgb3IgaWYgY2VydGFpbiB2YXJpYWJsZXMgaW5mbHVlbmNlIG90aGVycy4gRm9yIGV4YW1wbGUsIGV4YW1pbmluZyBjb3JyZWxhdGlvbnMgYmV0d2VlbiBpbmRlcGVuZGVudCB2YXJpYWJsZXMgYW5kIHRoZSB0YXJnZXQgdmFyaWFibGUgKGluIHN1cGVydmlzZWQgbGVhcm5pbmcpIGNhbiBndWlkZSBmZWF0dXJlIHNlbGVjdGlvbiBhbmQgaGVscCBpbXByb3ZlIG1vZGVsIHBlcmZvcm1hbmNlLg0KDQoNCioqRXhhbXBsZSoqOiBJbiBhIGRhdGFzZXQgcHJlZGljdGluZyBob3VzZSBwcmljZXMsIHZhcmlhYmxlcyBzdWNoIGFzICJzcXVhcmUgZm9vdGFnZSIgYW5kICJudW1iZXIgb2YgYmVkcm9vbXMiIGFyZSBsaWtlbHkgdG8gaGF2ZSBhIHN0cm9uZyBwb3NpdGl2ZSBjb3JyZWxhdGlvbiB3aXRoIHRoZSB0YXJnZXQgdmFyaWFibGUsICJwcmljZS4iDQoNCg0KKio3LiBGZWF0dXJlIEVuZ2luZWVyaW5nIGFuZCBUcmFuc2Zvcm1hdGlvbioqIA0KDQpEdXJpbmcgRURBLCBkYXRhIHNjaWVudGlzdHMgb2Z0ZW4gYmVnaW4gdG8gdGhpbmsgYWJvdXQgaG93IHRvIHRyYW5zZm9ybSBmZWF0dXJlcyBvciBjcmVhdGUgbmV3IG9uZXMuIFRoaXMgbWlnaHQgaW52b2x2ZSBlbmNvZGluZyBjYXRlZ29yaWNhbCB2YXJpYWJsZXMsIG5vcm1hbGl6aW5nIG51bWVyaWNhbCBmZWF0dXJlcywgb3IgY29tYmluaW5nIGZlYXR1cmVzIHRvIGV4dHJhY3QgbmV3IGluc2lnaHRzLiBFREEgcHJvdmlkZXMgdGhlIGNvbnRleHQgbmVlZGVkIHRvIGRldGVybWluZSB3aGljaCB0cmFuc2Zvcm1hdGlvbnMgYXJlIG5lY2Vzc2FyeSBhbmQgaG93IHRoZXkgc2hvdWxkIGJlIGFwcGxpZWQgdG8gdGhlIGRhdGEuDQoNCioqRXhhbXBsZSoqOiBJZiAiZGF0ZSIgaXMgYSBmZWF0dXJlLCBpdCBjb3VsZCBiZSB0cmFuc2Zvcm1lZCBpbnRvIG11bHRpcGxlIGZlYXR1cmVzIHN1Y2ggYXMgImRheSBvZiB0aGUgd2VlaywiICJtb250aCwiIG9yICJzZWFzb24sIiBkZXBlbmRpbmcgb24gdGhlIHByb2JsZW0uDQoNCg0KIyMjIEltcG9ydGFuY2Ugb2YgRURBDQoNCioqR3VpZGluZyBEYXRhIENsZWFuaW5nKio6IEVEQSBoZWxwcyBpZGVudGlmeSBpbmNvbnNpc3RlbmNpZXMsIG1pc3NpbmcgdmFsdWVzLCBhbmQgb3V0bGllcnMgaW4gdGhlIGRhdGEgdGhhdCBuZWVkIHRvIGJlIGFkZHJlc3NlZCBiZWZvcmUgbW9kZWwgdHJhaW5pbmcuIEJ5IGNsZWFuaW5nIHRoZSBkYXRhIGJhc2VkIG9uIGluc2lnaHRzIGZyb20gRURBLCBtb2RlbCBwZXJmb3JtYW5jZSBjYW4gYmUgc2lnbmlmaWNhbnRseSBpbXByb3ZlZC4NCg0KKipJbXByb3ZpbmcgTW9kZWwgQWNjdXJhY3kqKjogVW5kZXJzdGFuZGluZyB0aGUgZGF0YeKAmXMgc3RydWN0dXJlLCByZWxhdGlvbnNoaXBzLCBhbmQgZGlzdHJpYnV0aW9ucyBoZWxwcyBzZWxlY3QgdGhlIHJpZ2h0IG1hY2hpbmUgbGVhcm5pbmcgbW9kZWwuIEZvciBpbnN0YW5jZSwga25vd2luZyB0aGUgdGFyZ2V0IHZhcmlhYmxl4oCZcyBkaXN0cmlidXRpb24gbWlnaHQgaGVscCBjaG9vc2UgYmV0d2VlbiByZWdyZXNzaW9uIGFuZCBjbGFzc2lmaWNhdGlvbiBtb2RlbHMgb3IgaW5mbHVlbmNlIHRoZSBkZWNpc2lvbiB0byB1c2Ugc3BlY2lmaWMgYWxnb3JpdGhtcyBsaWtlIGRlY2lzaW9uIHRyZWVzLCByYW5kb20gZm9yZXN0cywgb3IgbmV1cmFsIG5ldHdvcmtzLg0KDQoqKlByZXZlbnRpbmcgT3ZlcmZpdHRpbmcqKjogQnkgdmlzdWFsaXppbmcgdGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBmZWF0dXJlcywgRURBIGhlbHBzIGRhdGEgc2NpZW50aXN0cyB1bmRlcnN0YW5kIHRoZSBjb21wbGV4aXR5IG9mIHRoZSBtb2RlbCB0aGV5IGFyZSBidWlsZGluZy4gSXQgYWxsb3dzIHRoZW0gdG8gZGVjaWRlIHdoZXRoZXIgY2VydGFpbiBmZWF0dXJlcyBzaG91bGQgYmUgaW5jbHVkZWQgb3Igd2hldGhlciBzb21lIHZhcmlhYmxlcyBtaWdodCBsZWFkIHRvIG92ZXJmaXR0aW5nLg0KDQoqKkltcHJvdmluZyBJbnRlcnByZXRhYmlsaXR5Kio6IFZpc3VhbGl6YXRpb25zIGFuZCBzdGF0aXN0aWNhbCBzdW1tYXJpZXMgY3JlYXRlZCBkdXJpbmcgRURBIHByb3ZpZGUgaW5zaWdodHMgdGhhdCBjYW4gaW1wcm92ZSB0aGUgaW50ZXJwcmV0YWJpbGl0eSBvZiB0aGUgbWFjaGluZSBsZWFybmluZyBtb2RlbC4gQ2xlYXIgdmlzdWFsaXphdGlvbnMgaGVscCBzdGFrZWhvbGRlcnMgYmV0dGVyIHVuZGVyc3RhbmQgdGhlIG1vZGVsIGFuZCB0aGUgcmVzdWx0cyBpdCBnZW5lcmF0ZXMuDQoNCg0KSW4gc3VtbWFyeSwgRURBIGlzIGFuIGVzc2VudGlhbCBwcm9jZXNzIGluIHRoZSBtYWNoaW5lIGxlYXJuaW5nIHBpcGVsaW5lLCBwcm92aWRpbmcgZGF0YSBzY2llbnRpc3RzIHdpdGggYSBkZWVwIHVuZGVyc3RhbmRpbmcgb2YgdGhlIGRhdGFzZXQgYmVmb3JlIGJ1aWxkaW5nIG1vZGVscy4gQnkgc3VtbWFyaXppbmcgdGhlIGRhdGEgdGhyb3VnaCBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzLCB2aXN1YWxpemluZyBrZXkgcmVsYXRpb25zaGlwcywgYW5kIGFkZHJlc3NpbmcgcG90ZW50aWFsIGlzc3VlcyBzdWNoIGFzIG1pc3NpbmcgZGF0YSBhbmQgb3V0bGllcnMsIEVEQSBlbnN1cmVzIHRoYXQgbWFjaGluZSBsZWFybmluZyBtb2RlbHMgYXJlIGJhc2VkIG9uIGEgc29saWQgZm91bmRhdGlvbi4gVGhyb3VnaCBlZmZlY3RpdmUgRURBLCBwcmFjdGl0aW9uZXJzIGNhbiBpbXByb3ZlIG1vZGVsIGFjY3VyYWN5LCBwcmV2ZW50IGJpYXNlcywgYW5kIG1ha2UgbW9yZSBpbmZvcm1lZCBkZWNpc2lvbnMgYWJvdXQgZGF0YSBwcmVwcm9jZXNzaW5nLCBmZWF0dXJlIGVuZ2luZWVyaW5nLCBhbmQgbW9kZWwgc2VsZWN0aW9uLiBVbHRpbWF0ZWx5LCBFREEgZW5oYW5jZXMgdGhlIHJlbGlhYmlsaXR5IGFuZCBzdWNjZXNzIG9mIG1hY2hpbmUgbGVhcm5pbmcgcHJvamVjdHMuDQoNCg0KDQoNCiMjIE9wdGltYWwgTW9kZWwgSWRlbnRpZmljYXRpb24NCg0KSWRlbnRpZnlpbmcgdGhlIHJpZ2h0IG1vZGVsIGFuZCBhbGdvcml0aG0gaXMgZXNzZW50aWFsIGZvciBhY2hpZXZpbmcgaGlnaC1wZXJmb3JtYW5jZSByZXN1bHRzLiBUaGUgcHJvY2VzcyBvZiBpZGVudGlmeWluZyB0aGUgb3B0aW1hbCBtb2RlbHMgYW5kIGFsZ29yaXRobXMgaXMgYSBmdW5kYW1lbnRhbCB0YXNrIHRoYXQgY2FuIHNpZ25pZmljYW50bHkgaW5mbHVlbmNlIHRoZSBhY2N1cmFjeSwgZWZmaWNpZW5jeSwgYW5kIGludGVycHJldGFiaWxpdHkgb2YgbWFjaGluZSBsZWFybmluZyBzb2x1dGlvbnMuIFRoaXMgc3Vic2VjdGlvbiBleHBsb3JlcyB0aGUgaW1wb3J0YW5jZSBvZiBtb2RlbCBhbmQgYWxnb3JpdGhtIHNlbGVjdGlvbiwgdGhlIGZhY3RvcnMgdGhhdCBpbmZsdWVuY2UgdGhlc2UgZGVjaXNpb25zLCBhbmQgdGhlIHByb2Nlc3Mgb2YgaWRlbnRpZnlpbmcgdGhlIGJlc3QgbW9kZWwgZm9yIGEgZ2l2ZW4gdGFzay4NCg0KTWFjaGluZSBsZWFybmluZyBlbmNvbXBhc3NlcyBhIHdpZGUgdmFyaWV0eSBvZiB0YXNrcywgc3VjaCBhcyBjbGFzc2lmaWNhdGlvbiwgcmVncmVzc2lvbiwgY2x1c3RlcmluZywgYW5kIHJlaW5mb3JjZW1lbnQgbGVhcm5pbmcsIGVhY2ggcmVxdWlyaW5nIGRpZmZlcmVudCBhcHByb2FjaGVzIGFuZCBhbGdvcml0aG1zLiBHaXZlbiB0aGUgYnJvYWQgcmFuZ2Ugb2YgYXZhaWxhYmxlIG1vZGVscyBhbmQgYWxnb3JpdGhtcywgaXQgaXMgZXNzZW50aWFsIHRvIGNob29zZSB0aGUgbW9zdCBzdWl0YWJsZSBvbmUgZm9yIHRoZSBwcm9ibGVtIGF0IGhhbmQuIFRoZSByaWdodCBtb2RlbCBvciBhbGdvcml0aG0gY2FuIGhlbHAgdG8gdW5jb3ZlciBwYXR0ZXJucyBpbiB0aGUgZGF0YSwgbWFrZSBhY2N1cmF0ZSBwcmVkaWN0aW9ucywgYW5kIGRlbGl2ZXIgYWN0aW9uYWJsZSBpbnNpZ2h0cy4NCg0KSG93ZXZlciwgY2hvb3NpbmcgdGhlIG9wdGltYWwgbW9kZWwgaXMgbm90IGFsd2F5cyBzdHJhaWdodGZvcndhcmQuIEl0IHJlcXVpcmVzIGFuIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHByb2JsZW0gZG9tYWluLCB0aGUgbmF0dXJlIG9mIHRoZSBkYXRhLCBhbmQgdGhlIHBlcmZvcm1hbmNlIG1ldHJpY3MgdGhhdCBtYXR0ZXIgbW9zdCB0byBzdGFrZWhvbGRlcnMuIEluY29ycmVjdGx5IHNlbGVjdGluZyBhIG1vZGVsIG9yIGFsZ29yaXRobSBjYW4gbGVhZCB0byBvdmVyZml0dGluZywgdW5kZXJmaXR0aW5nLCBvciBpbmVmZmljaWVudCBjb21wdXRhdGlvbiwgd2hpY2ggaW4gdHVybiBjYW4gYWZmZWN0IHRoZSBvdmVyYWxsIHF1YWxpdHkgb2YgdGhlIG1vZGVsJ3MgcHJlZGljdGlvbnMgb3IgcGVyZm9ybWFuY2UuDQoNCiMjIyBGYWN0b3JzIEluZmx1ZW5jaW5nIE1vZGVsIFNlbGVjdGlvbg0KDQpTZXZlcmFsIGZhY3RvcnMgcGxheSBhIHJvbGUgaW4gZGV0ZXJtaW5pbmcgd2hpY2ggbWFjaGluZSBsZWFybmluZyBtb2RlbCBvciBhbGdvcml0aG0gaXMgbW9zdCBzdWl0YWJsZSBmb3IgYSBnaXZlbiBwcm9ibGVtLg0KDQoNCioqMS4gUHJvYmxlbSBUeXBlKiogDQoNClRoZSBuYXR1cmUgb2YgdGhlIHByb2JsZW0gaXMgcGVyaGFwcyB0aGUgbW9zdCBjcml0aWNhbCBmYWN0b3IuIElzIGl0IGEgY2xhc3NpZmljYXRpb24gdGFzayAocHJlZGljdGluZyBjYXRlZ29yaWVzKSwgcmVncmVzc2lvbiB0YXNrIChwcmVkaWN0aW5nIGNvbnRpbnVvdXMgdmFsdWVzKSwgY2x1c3RlcmluZyB0YXNrIChncm91cGluZyBkYXRhKSwgb3Igc29tZXRoaW5nIGVsc2U/IERpZmZlcmVudCBwcm9ibGVtcyByZXF1aXJlIGRpZmZlcmVudCBhbGdvcml0aG1zLg0KDQoqKkV4YW1wbGUqKi4gRm9yIGEgY2xhc3NpZmljYXRpb24gdGFzaywgYWxnb3JpdGhtcyBsaWtlIGxvZ2lzdGljIHJlZ3Jlc3Npb24sIHN1cHBvcnQgdmVjdG9yIG1hY2hpbmVzIChTVk0pLCBkZWNpc2lvbiB0cmVlcywgb3IgbmV1cmFsIG5ldHdvcmtzIG1pZ2h0IGJlIGNvbnNpZGVyZWQuIEZvciBhIHJlZ3Jlc3Npb24gdGFzaywgYWxnb3JpdGhtcyBsaWtlIGxpbmVhciByZWdyZXNzaW9uIG9yIHJhbmRvbSBmb3Jlc3RzIG1pZ2h0IGJlIG1vcmUgc3VpdGFibGUuDQoNCioqMi4gRGF0YSBDaGFyYWN0ZXJpc3RpY3MqKiANCg0KVGhlIHR5cGUgb2YgZGF0YSwgaXRzIHNpemUsIGFuZCBpdHMgcXVhbGl0eSBhbGwgaW5mbHVlbmNlIG1vZGVsIHNlbGVjdGlvbi4gRm9yIGluc3RhbmNlLCBpZiB0aGUgZGF0YXNldCBpcyBsYXJnZSBhbmQgaGlnaC1kaW1lbnNpb25hbCwgbW9kZWxzIGxpa2UgZGVlcCBuZXVyYWwgbmV0d29ya3MgbWlnaHQgYmUgbW9yZSBlZmZlY3RpdmUuIENvbnZlcnNlbHksIGlmIHRoZSBkYXRhIGlzIHNtYWxsIG9yIGNvbnRhaW5zIG1hbnkgbWlzc2luZyB2YWx1ZXMsIHNpbXBsZXIgbW9kZWxzIGxpa2UgZGVjaXNpb24gdHJlZXMgb3Igay1uZWFyZXN0IG5laWdoYm9ycyAoS05OKSBtYXkgcGVyZm9ybSBiZXR0ZXIuDQoNCioqRXhhbXBsZSoqOiBJbiBjYXNlcyB3aGVyZSBkYXRhIGlzIHNwYXJzZSBvciBjb250YWlucyBtaXNzaW5nIHZhbHVlcywgc2ltcGxlciBtb2RlbHMgc3VjaCBhcyBsb2dpc3RpYyByZWdyZXNzaW9uIG9yIGRlY2lzaW9uIHRyZWVzIG1pZ2h0IGJlIHByZWZlcnJlZCBvdmVyIGNvbXBsZXggbW9kZWxzIGxpa2UgbmV1cmFsIG5ldHdvcmtzLg0KDQoNCioqMy4gQWNjdXJhY3kgdnMuIEludGVycHJldGFiaWxpdHkqKiANCg0KU29tZSBtb2RlbHMgb2ZmZXIgaGlnaCBwcmVkaWN0aXZlIGFjY3VyYWN5IGJ1dCBhcmUgZGlmZmljdWx0IHRvIGludGVycHJldCAoZS5nLiwgZGVlcCBuZXVyYWwgbmV0d29ya3MpLCB3aGlsZSBvdGhlcnMgbWF5IHByb3ZpZGUgbGVzcyBhY2N1cmFjeSBidXQgb2ZmZXIgZ3JlYXRlciBpbnRlcnByZXRhYmlsaXR5IChlLmcuLCBkZWNpc2lvbiB0cmVlcyBvciBsaW5lYXIgcmVncmVzc2lvbikuIERlcGVuZGluZyBvbiB0aGUgYXBwbGljYXRpb24sIHN0YWtlaG9sZGVycyBtaWdodCBwcmlvcml0aXplIG9uZSBvdmVyIHRoZSBvdGhlci4NCg0KKipFeGFtcGxlKio6IEluIG1lZGljYWwgYXBwbGljYXRpb25zIHdoZXJlIGV4cGxhaW5hYmlsaXR5IGlzIGNydWNpYWwsIGRlY2lzaW9uIHRyZWVzIG9yIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbWlnaHQgYmUgY2hvc2VuIGZvciB0aGVpciB0cmFuc3BhcmVuY3ksIGV2ZW4gaWYgdGhleSBvZmZlciBzbGlnaHRseSBsb3dlciBhY2N1cmFjeSBjb21wYXJlZCB0byBhIG5ldXJhbCBuZXR3b3JrLg0KDQoqKjQuIENvbXB1dGF0aW9uYWwgUmVzb3VyY2VzIGFuZCBUaW1lIENvbnN0cmFpbnRzKiogDQoNClRoZSBjb21wdXRhdGlvbmFsIHJlc291cmNlcyByZXF1aXJlZCBmb3IgdHJhaW5pbmcgYW5kIGRlcGxveWluZyBtb2RlbHMgc2hvdWxkIGFsc28gYmUgY29uc2lkZXJlZC4gTW9yZSBjb21wbGV4IG1vZGVscywgc3VjaCBhcyBkZWVwIGxlYXJuaW5nIG1vZGVscywgbWF5IHJlcXVpcmUgc2lnbmlmaWNhbnQgY29tcHV0aW5nIHBvd2VyIGFuZCB0aW1lIHRvIHRyYWluLCB3aGlsZSBzaW1wbGVyIG1vZGVscyBjYW4gYmUgdHJhaW5lZCBtb3JlIHF1aWNrbHkgYW5kIHdpdGggZmV3ZXIgcmVzb3VyY2VzLg0KDQoqKkV4YW1wbGUqKjogSW4gYSByZWFsLXRpbWUgc3lzdGVtIHdoZXJlIHNwZWVkIGlzIGVzc2VudGlhbCwgYSBzaW1wbGVyIG1vZGVsIGxpa2UgbG9naXN0aWMgcmVncmVzc2lvbiBtYXkgYmUgcHJlZmVycmVkIGR1ZSB0byBpdHMgbG93ZXIgY29tcHV0YXRpb25hbCBjb3N0IGNvbXBhcmVkIHRvIGEgbW9yZSBjb21wbGV4IG1vZGVsIGxpa2UgYSBkZWVwIG5ldXJhbCBuZXR3b3JrLg0KDQoNCioqNS4gUGVyZm9ybWFuY2UgTWV0cmljcyoqIA0KDQpUaGUgcGVyZm9ybWFuY2UgbWV0cmljIGJlaW5nIG9wdGltaXplZCBhbHNvIHBsYXlzIGEga2V5IHJvbGUgaW4gYWxnb3JpdGhtIHNlbGVjdGlvbi4gRGlmZmVyZW50IG1vZGVscyBleGNlbCBhdCBkaWZmZXJlbnQgZXZhbHVhdGlvbiBjcml0ZXJpYSwgc3VjaCBhcyBhY2N1cmFjeSwgcHJlY2lzaW9uLCByZWNhbGwsIEYxIHNjb3JlLCBvciBhcmVhIHVuZGVyIHRoZSBST0MgY3VydmUgKEFVQykuIFRoZSBjaG9pY2Ugb2YgbWV0cmljIGRlcGVuZHMgb24gdGhlIHRhc2sgYW5kIHRoZSBzcGVjaWZpYyBnb2FscyBvZiB0aGUgcHJvamVjdC4NCg0KKipFeGFtcGxlKio6IEluIGEgZnJhdWQgZGV0ZWN0aW9uIHN5c3RlbSwgcHJlY2lzaW9uIGFuZCByZWNhbGwgbWlnaHQgYmUgcHJpb3JpdGl6ZWQgb3ZlciBhY2N1cmFjeSB0byBlbnN1cmUgdGhhdCBmcmF1ZHVsZW50IGFjdGl2aXRpZXMgYXJlIGRldGVjdGVkIHdpdGggbWluaW1hbCBmYWxzZSBuZWdhdGl2ZXMuDQoNCg0KIyMjIFByb2Nlc3Mgb2YgTW9kZWwgSWRlbnRpZmljYXRpb24gDQoNClNlbGVjdGluZyB0aGUgb3B0aW1hbCBtb2RlbCBhbmQgYWxnb3JpdGhtIHR5cGljYWxseSBpbnZvbHZlcyBzZXZlcmFsIGtleSBzdGVwcyBpbiB0aGUgbWFjaGluZSBsZWFybmluZyBwaXBlbGluZS4gVGhlc2Ugc3RlcHMgaGVscCBndWlkZSB0aGUgcHJhY3RpdGlvbmVyIHRocm91Z2ggdGhlIHByb2Nlc3Mgb2YgZXhwZXJpbWVudGF0aW9uLCBldmFsdWF0aW9uLCBhbmQgcmVmaW5lbWVudC4NCg0KKioxLiBEYXRhIFByZXByb2Nlc3NpbmcqKiANCg0KQmVmb3JlIHNlbGVjdGluZyBhIG1vZGVsLCBpdCBpcyBlc3NlbnRpYWwgdG8gcHJlcHJvY2VzcyB0aGUgZGF0YS4gVGhpcyBpbmNsdWRlcyBoYW5kbGluZyBtaXNzaW5nIHZhbHVlcywgZW5jb2RpbmcgY2F0ZWdvcmljYWwgdmFyaWFibGVzLCBzY2FsaW5nIG51bWVyaWNhbCBmZWF0dXJlcywgYW5kIHBlcmZvcm1pbmcgYW55IG5lY2Vzc2FyeSB0cmFuc2Zvcm1hdGlvbnMuIFByb3BlciBkYXRhIHByZXBhcmF0aW9uIGVuc3VyZXMgdGhhdCB0aGUgY2hvc2VuIG1vZGVsIHJlY2VpdmVzIGNsZWFuLCBzdHJ1Y3R1cmVkIGlucHV0LCBpbXByb3ZpbmcgaXRzIGFiaWxpdHkgdG8gbWFrZSBhY2N1cmF0ZSBwcmVkaWN0aW9ucy4NCg0KKioyLiBNb2RlbCBTZWxlY3Rpb24gQmFzZWQgb24gUHJvYmxlbSBUeXBlKioNCg0KVGhlIGZpcnN0IHN0ZXAgaW4gaWRlbnRpZnlpbmcgdGhlIG9wdGltYWwgYWxnb3JpdGhtIGlzIHRvIHNlbGVjdCBhIG1vZGVsIGJhc2VkIG9uIHRoZSBwcm9ibGVtIHR5cGUuIEZvciBzdXBlcnZpc2VkIGxlYXJuaW5nIHRhc2tzIGxpa2UgY2xhc3NpZmljYXRpb24gYW5kIHJlZ3Jlc3Npb24sIGEgd2lkZSBhcnJheSBvZiBtb2RlbHMgbWF5IGJlIHRlc3RlZC4gVGhlc2UgaW5jbHVkZToNCg0KKiAqKkZvciBDbGFzc2lmaWNhdGlvbioqOiBMb2dpc3RpYyByZWdyZXNzaW9uLCBkZWNpc2lvbiB0cmVlcywgc3VwcG9ydCB2ZWN0b3IgbWFjaGluZXMsIGstbmVhcmVzdCBuZWlnaGJvcnMsIGFuZCBlbnNlbWJsZSBtZXRob2RzIGxpa2UgcmFuZG9tIGZvcmVzdHMgYW5kIGdyYWRpZW50IGJvb3N0aW5nLg0KDQoqICoqRm9yIFJlZ3Jlc3Npb24qKjogTGluZWFyIHJlZ3Jlc3Npb24sIGRlY2lzaW9uIHRyZWVzLCByYW5kb20gZm9yZXN0cywgc3VwcG9ydCB2ZWN0b3IgcmVncmVzc2lvbiwgYW5kIG5ldXJhbCBuZXR3b3Jrcy4NCg0KKiAqKkZvciBDbHVzdGVyaW5nKio6IEstbWVhbnMsIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nLCBEQlNDQU4sIGFuZCBHYXVzc2lhbiBtaXh0dXJlIG1vZGVscy4NCg0KDQoqKjMuIE1vZGVsIFRyYWluaW5nIGFuZCBFdmFsdWF0aW9uKioNCg0KT25jZSB0aGUgbW9kZWxzIGFyZSBzZWxlY3RlZCwgdGhleSBhcmUgdHJhaW5lZCBvbiB0aGUgYXZhaWxhYmxlIGRhdGFzZXQuIEl0IGlzIGVzc2VudGlhbCB0byBzcGxpdCB0aGUgZGF0YXNldCBpbnRvIHRyYWluaW5nLCB2YWxpZGF0aW9uLCBhbmQgdGVzdCBzZXRzIHRvIGF2b2lkIG92ZXJmaXR0aW5nIGFuZCBlbnN1cmUgdGhhdCB0aGUgbW9kZWwgZ2VuZXJhbGl6ZXMgd2VsbCB0byB1bnNlZW4gZGF0YS4gTW9kZWwgZXZhbHVhdGlvbiBpcyBkb25lIHVzaW5nIGFwcHJvcHJpYXRlIHBlcmZvcm1hbmNlIG1ldHJpY3MgKGUuZy4sIGFjY3VyYWN5LCBwcmVjaXNpb24sIHJlY2FsbCwgZXRjLikuDQoNCkNyb3NzLXZhbGlkYXRpb24gdGVjaG5pcXVlcywgc3VjaCBhcyBrLWZvbGQgY3Jvc3MtdmFsaWRhdGlvbiwgYXJlIG9mdGVuIHVzZWQgdG8gZnVydGhlciBhc3Nlc3MgbW9kZWwgcGVyZm9ybWFuY2UgYW5kIHN0YWJpbGl0eS4gVGhpcyBwcm9jZXNzIGhlbHBzIGRldGVybWluZSBob3cgd2VsbCB0aGUgbW9kZWwgd2lsbCBwZXJmb3JtIG9uIHVuc2VlbiBkYXRhIGFuZCBwcmV2ZW50cyBvdmVyZml0dGluZyBieSBlbnN1cmluZyB0aGUgbW9kZWwgZ2VuZXJhbGl6ZXMgd2VsbC4NCg0KKio0LiBIeXBlcnBhcmFtZXRlciBUdW5pbmcqKg0KDQpNYW55IG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtcyBoYXZlIGh5cGVycGFyYW1ldGVycyB0aGF0IG5lZWQgdG8gYmUgdHVuZWQgZm9yIG9wdGltYWwgcGVyZm9ybWFuY2UuIFRoZXNlIGh5cGVycGFyYW1ldGVycyBjb250cm9sIHZhcmlvdXMgYXNwZWN0cyBvZiB0aGUgbW9kZWwsIHN1Y2ggYXMgdGhlIGxlYXJuaW5nIHJhdGUsIHJlZ3VsYXJpemF0aW9uIHN0cmVuZ3RoLCBhbmQgdGhlIGRlcHRoIG9mIGRlY2lzaW9uIHRyZWVzLiBIeXBlcnBhcmFtZXRlciB0dW5pbmcgaXMgdHlwaWNhbGx5IGRvbmUgdXNpbmcgZ3JpZCBzZWFyY2ggb3IgcmFuZG9taXplZCBzZWFyY2ggdGVjaG5pcXVlcywgd2hpY2ggaW52b2x2ZSB0cmFpbmluZyB0aGUgbW9kZWwgbXVsdGlwbGUgdGltZXMgd2l0aCBkaWZmZXJlbnQgaHlwZXJwYXJhbWV0ZXIgdmFsdWVzIGFuZCBzZWxlY3RpbmcgdGhlIHNldCB0aGF0IHJlc3VsdHMgaW4gdGhlIGJlc3QgcGVyZm9ybWFuY2UuDQoNCioqNS4gTW9kZWwgQ29tcGFyaXNvbioqDQoNCkFmdGVyIHRyYWluaW5nIGFuZCB0dW5pbmcgc2V2ZXJhbCBtb2RlbHMsIHRoZSBwZXJmb3JtYW5jZSBvZiBlYWNoIG1vZGVsIGlzIGNvbXBhcmVkIHVzaW5nIHRoZSBzZWxlY3RlZCBtZXRyaWNzLiBUaGlzIGNvbXBhcmlzb24gYWxsb3dzIHByYWN0aXRpb25lcnMgdG8gZXZhbHVhdGUgdGhlIHRyYWRlLW9mZnMgYmV0d2VlbiBtb2RlbHMgaW4gdGVybXMgb2YgYWNjdXJhY3ksIGludGVycHJldGFiaWxpdHksIGFuZCBjb21wdXRhdGlvbmFsIGVmZmljaWVuY3kuDQoNCioqRXhhbXBsZSoqOiBJZiBhIGRlY2lzaW9uIHRyZWUgbW9kZWwgb2ZmZXJzIGhpZ2ggaW50ZXJwcmV0YWJpbGl0eSBidXQgbG93ZXIgYWNjdXJhY3kgY29tcGFyZWQgdG8gYSByYW5kb20gZm9yZXN0IG1vZGVsLCBhIGRlY2lzaW9uIG1pZ2h0IGJlIG1hZGUgdG8gcHJpb3JpdGl6ZSBhY2N1cmFjeSBvdmVyIGludGVycHJldGFiaWxpdHksIGRlcGVuZGluZyBvbiB0aGUgcHJvamVjdCdzIG5lZWRzLg0KDQoqKjYuIE1vZGVsIERlcGxveW1lbnQgYW5kIE1vbml0b3JpbmcqKg0KDQpPbmNlIHRoZSBvcHRpbWFsIG1vZGVsIGhhcyBiZWVuIGlkZW50aWZpZWQsIGl0IGlzIGRlcGxveWVkIGludG8gcHJvZHVjdGlvbi4gQ29udGludW91cyBtb25pdG9yaW5nIGlzIGVzc2VudGlhbCB0byBlbnN1cmUgdGhhdCB0aGUgbW9kZWwgY29udGludWVzIHRvIHBlcmZvcm0gd2VsbCBhcyBuZXcgZGF0YSBpcyBjb2xsZWN0ZWQuIElmIHBlcmZvcm1hbmNlIGRyb3BzIG92ZXIgdGltZSwgdGhlIG1vZGVsIG1heSBuZWVkIHRvIGJlIHJldHJhaW5lZCBvciB1cGRhdGVkLg0KDQojIyMgQ2hhbGxlbmdlcyBpbiBNb2RlbCBTZWxlY3Rpb24NCg0KVGhlIHByb2Nlc3Mgb2YgaWRlbnRpZnlpbmcgdGhlIG9wdGltYWwgbW9kZWwgaXMgbm90IHdpdGhvdXQgY2hhbGxlbmdlcy4gU29tZSBvZiB0aGUga2V5IGRpZmZpY3VsdGllcyBpbmNsdWRlOg0KDQoqKk1vZGVsIENvbXBsZXhpdHkgdnMuIFBlcmZvcm1hbmNlKio6IE1vcmUgY29tcGxleCBtb2RlbHMgbWF5IGFjaGlldmUgaGlnaGVyIGFjY3VyYWN5IGJ1dCByZXF1aXJlIG1vcmUgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIGFyZSBtb3JlIHByb25lIHRvIG92ZXJmaXR0aW5nLiBCYWxhbmNpbmcgY29tcGxleGl0eSB3aXRoIHBlcmZvcm1hbmNlIGlzIGEgY29tbW9uIGNoYWxsZW5nZS4NCg0KKipEYXRhIFF1YWxpdHkqKjogUG9vciBkYXRhIHF1YWxpdHksIGluY2x1ZGluZyBtaXNzaW5nIHZhbHVlcywgaW1iYWxhbmNlZCBjbGFzc2VzLCBvciBub2lzeSBkYXRhLCBjYW4gbWFrZSBpdCBkaWZmaWN1bHQgdG8gaWRlbnRpZnkgdGhlIG9wdGltYWwgbW9kZWwsIGFzIHRoZSBtb2RlbCdzIHBlcmZvcm1hbmNlIG1heSBiZSBhZmZlY3RlZCBieSB0aGUgdW5kZXJseWluZyBpc3N1ZXMgaW4gdGhlIGRhdGEuDQoNCioqT3ZlcmZpdHRpbmcqKjogU2VsZWN0aW5nIGEgbW9kZWwgdGhhdCBwZXJmb3JtcyB3ZWxsIG9uIHRyYWluaW5nIGRhdGEgYnV0IHBvb3JseSBvbiB0ZXN0IGRhdGEgZHVlIHRvIG92ZXJmaXR0aW5nIGNhbiBiZSBhIHNpZ25pZmljYW50IGNoYWxsZW5nZS4gVGVjaG5pcXVlcyBzdWNoIGFzIGNyb3NzLXZhbGlkYXRpb24gYW5kIHJlZ3VsYXJpemF0aW9uIGFyZSB1c2VkIHRvIG1pdGlnYXRlIHRoaXMgaXNzdWUuDQoNClwNCg0KSW4gc3VtbWFyeSwgaWRlbnRpZnlpbmcgdGhlIG9wdGltYWwgbW9kZWxzIGFuZCBhbGdvcml0aG1zIGluIG1hY2hpbmUgbGVhcm5pbmcgaXMgYSBjcnVjaWFsIHRhc2sgdGhhdCByZXF1aXJlcyBjYXJlZnVsIGNvbnNpZGVyYXRpb24gb2YgdmFyaW91cyBmYWN0b3JzLCBpbmNsdWRpbmcgdGhlIHByb2JsZW0gdHlwZSwgZGF0YSBjaGFyYWN0ZXJpc3RpY3MsIGF2YWlsYWJsZSByZXNvdXJjZXMsIGFuZCBwZXJmb3JtYW5jZSBtZXRyaWNzLiBUaGUgcHJvY2VzcyBpbnZvbHZlcyBleHBlcmltZW50aW5nIHdpdGggZGlmZmVyZW50IG1vZGVscywgdHJhaW5pbmcgYW5kIGV2YWx1YXRpbmcgdGhlbSwgdHVuaW5nIHRoZWlyIGh5cGVycGFyYW1ldGVycywgYW5kIHNlbGVjdGluZyB0aGUgYmVzdC1wZXJmb3JtaW5nIG1vZGVsLiBXaGlsZSB0aGUgc2VsZWN0aW9uIHByb2Nlc3MgY2FuIGJlIGNoYWxsZW5naW5nIGR1ZSB0byBpc3N1ZXMgbGlrZSBkYXRhIHF1YWxpdHksIG92ZXJmaXR0aW5nLCBhbmQgbW9kZWwgY29tcGxleGl0eSwgZm9sbG93aW5nIGEgc3RydWN0dXJlZCBhcHByb2FjaCBjYW4gbGVhZCB0byB0aGUgaWRlbnRpZmljYXRpb24gb2YgdGhlIG1vc3Qgc3VpdGFibGUgbW9kZWwgZm9yIHRoZSB0YXNrIGF0IGhhbmQuIEFzIG1hY2hpbmUgbGVhcm5pbmcgY29udGludWVzIHRvIGV2b2x2ZSwgc2VsZWN0aW5nIHRoZSByaWdodCBtb2RlbCB3aWxsIHJlbWFpbiBhIGNyaXRpY2FsIGZhY3RvciBpbiBkZWxpdmVyaW5nIGFjY3VyYXRlLCBlZmZpY2llbnQsIGFuZCBpbXBhY3RmdWwgc29sdXRpb25zDQoNCg0KDQojIyBWYWxpZGF0aW9uIGFuZCBUZXN0aW5nDQoNClZhbGlkYXRpb24gYW5kIHRlc3RpbmcgYXJlIGNyaXRpY2FsIHBoYXNlcyBpbiB0aGUgbWFjaGluZSBsZWFybmluZyAoTUwpIHdvcmtmbG93LiBUaGVzZSBzdGVwcyBlbnN1cmUgdGhhdCB0aGUgbW9kZWwgYnVpbHQgb24gdGhlIHRyYWluaW5nIGRhdGEgaXMgbm90IG9ubHkgYWNjdXJhdGUgYnV0IGFsc28gZ2VuZXJhbGl6ZXMgd2VsbCB0byBuZXcsIHVuc2VlbiBkYXRhLiBXaXRob3V0IGVmZmVjdGl2ZSB2YWxpZGF0aW9uIGFuZCB0ZXN0aW5nLCBhIG1vZGVsIG1pZ2h0IGFwcGVhciB0byBwZXJmb3JtIHdlbGwgZHVyaW5nIHRyYWluaW5nIGJ1dCBmYWlsIHRvIGRlbGl2ZXIgcmVsaWFibGUgcmVzdWx0cyBpbiByZWFsLXdvcmxkIGFwcGxpY2F0aW9ucy4gVGhpcyBzdWJzZWN0aW9uIGV4cGxvcmVzIHRoZSBpbXBvcnRhbmNlIG9mIHZhbGlkYXRpb24gYW5kIHRlc3RpbmcsIHRoZSBtZXRob2RzIGNvbW1vbmx5IHVzZWQsIGFuZCB0aGVpciByb2xlIGluIGJ1aWxkaW5nIHJvYnVzdCBtYWNoaW5lIGxlYXJuaW5nIG1vZGVscy4NCg0KDQojIyMgVGhlIEltcG9ydGFuY2Ugb2YgVmFsaWRhdGlvbiBhbmQgVGVzdGluZw0KDQpNYWNoaW5lIGxlYXJuaW5nIG1vZGVscyBhcmUgdHJhaW5lZCBvbiBhIHNwZWNpZmljIGRhdGFzZXQsIGtub3duIGFzIHRoZSB0cmFpbmluZyBkYXRhc2V0LCB3aGljaCBjb250YWlucyBleGFtcGxlcyB1c2VkIHRvIHRlYWNoIHRoZSBtb2RlbC4gSG93ZXZlciwgdGhlIHVsdGltYXRlIGdvYWwgaXMgdG8gZGV2ZWxvcCBhIG1vZGVsIHRoYXQgY2FuIG1ha2UgYWNjdXJhdGUgcHJlZGljdGlvbnMgb24gbmV3IGRhdGHigJRkYXRhIGl0IGhhcyBub3QgZW5jb3VudGVyZWQgYmVmb3JlLiBUaGlzIGlzIHdoZXJlIHZhbGlkYXRpb24gYW5kIHRlc3RpbmcgY29tZSBpbnRvIHBsYXkuDQoNCiogKipWYWxpZGF0aW9uKiogaXMgdXNlZCB0byB0dW5lIG1vZGVsIGh5cGVycGFyYW1ldGVycyBhbmQgYXNzZXNzIHRoZSBtb2RlbOKAmXMgcGVyZm9ybWFuY2UgZHVyaW5nIHRyYWluaW5nLiBJdCBoZWxwcyBpbiBzZWxlY3RpbmcgdGhlIGJlc3QgbW9kZWwgY29uZmlndXJhdGlvbiBiZWZvcmUgZmluYWwgdGVzdGluZywgZW5zdXJpbmcgdGhhdCB0aGUgbW9kZWwgZG9lcyBub3Qgc2ltcGx5IG1lbW9yaXplIHRoZSB0cmFpbmluZyBkYXRhIChhIHBoZW5vbWVub24ga25vd24gYXMgb3ZlcmZpdHRpbmcpLg0KDQoqICoqVGVzdGluZyBldmFsdWF0ZXMqKiB0aGUgbW9kZWwncyBmaW5hbCBwZXJmb3JtYW5jZSBvbiBhbiBpbmRlcGVuZGVudCBzZXQgb2YgZGF0YSwga25vd24gYXMgdGhlIHRlc3QgZGF0YXNldCwgdGhhdCB3YXMgbm90IHVzZWQgaW4gYW55IHBhcnQgb2YgdGhlIG1vZGVs4oCZcyB0cmFpbmluZyBvciB2YWxpZGF0aW9uLiBUaGlzIGZpbmFsIGV2YWx1YXRpb24gZW5zdXJlcyB0aGF0IHRoZSBtb2RlbCBnZW5lcmFsaXplcyB3ZWxsIHRvIG5ldyBkYXRhLg0KDQpXaXRob3V0IHByb3BlciB2YWxpZGF0aW9uIGFuZCB0ZXN0aW5nLCB0aGVyZSBpcyBhIHJpc2sgb2YgZGV2ZWxvcGluZyBhIG1vZGVsIHRoYXQgd29ya3Mgd2VsbCBvbiB0aGUgdHJhaW5pbmcgZGF0YSBidXQgZmFpbHMgdG8gZ2VuZXJhbGl6ZSwgbGVhZGluZyB0byBwb29yIHJlYWwtd29ybGQgcGVyZm9ybWFuY2UuIFRodXMsIHRoZXNlIHN0ZXBzIGFyZSBjcnVjaWFsIHRvIG1vZGVsIHJlbGlhYmlsaXR5IGFuZCBhY2N1cmFjeS4NCg0KDQojIyMgVmFsaWRhdGlvbiBUZWNobmlxdWVzDQoNClZhbGlkYXRpb24gbWV0aG9kcyBhcmUgdXNlZCB0byBhc3Nlc3MgdGhlIG1vZGVs4oCZcyBwZXJmb3JtYW5jZSBkdXJpbmcgdGhlIHRyYWluaW5nIHByb2Nlc3MsIGJlZm9yZSBpdCBpcyB0ZXN0ZWQgb24gdW5zZWVuIGRhdGEuIFNldmVyYWwgdGVjaG5pcXVlcyBhcmUgY29tbW9ubHkgZW1wbG95ZWQgZm9yIHRoaXMgcHVycG9zZToNCg0KKipIb2xkb3V0IE1ldGhvZCoqIA0KDQpUaGUgc2ltcGxlc3QgZm9ybSBvZiB2YWxpZGF0aW9uLCB0aGUgaG9sZG91dCBtZXRob2QgaW52b2x2ZXMgc3BsaXR0aW5nIHRoZSBkYXRhIGludG8gdHdvIG9yIHRocmVlIHNldHM6IGEgdHJhaW5pbmcgc2V0LCBhIHZhbGlkYXRpb24gc2V0LCBhbmQgc29tZXRpbWVzIGEgdGVzdCBzZXQuIFRoZSBtb2RlbCBpcyB0cmFpbmVkIG9uIHRoZSB0cmFpbmluZyBzZXQgYW5kIHZhbGlkYXRlZCBvbiB0aGUgdmFsaWRhdGlvbiBzZXQgdG8gZXZhbHVhdGUgaXRzIHBlcmZvcm1hbmNlLiBUaGUgdGVzdCBzZXQgcmVtYWlucyBjb21wbGV0ZWx5IHVudG91Y2hlZCBkdXJpbmcgdHJhaW5pbmcgYW5kIHZhbGlkYXRpb24uDQoNCioqRXhhbXBsZSoqOiBBIHR5cGljYWwgc3BsaXQgbWlnaHQgaW52b2x2ZSB1c2luZyA3MCUgb2YgdGhlIGRhdGEgZm9yIHRyYWluaW5nLCAxNSUgZm9yIHZhbGlkYXRpb24sIGFuZCAxNSUgZm9yIHRlc3RpbmcuIFRoZSBtb2RlbCBpcyB0cmFpbmVkIG9uIHRoZSA3MCUsIHR1bmVkIHVzaW5nIHRoZSAxNSUgdmFsaWRhdGlvbiBzZXQsIGFuZCBmaW5hbGx5IHRlc3RlZCBvbiB0aGUgcmVtYWluaW5nIDE1JS4NCg0KDQoqKkstRm9sZCBDcm9zcy1WYWxpZGF0aW9uKiogDQoNCk9uZSBvZiB0aGUgbW9zdCBwb3B1bGFyIHRlY2huaXF1ZXMsIGstZm9sZCBjcm9zcy12YWxpZGF0aW9uIGRpdmlkZXMgdGhlIGRhdGEgaW50byBrIGVxdWFsIHBhcnRzLCBvciAiZm9sZHMuIiBUaGUgbW9kZWwgaXMgdHJhaW5lZCBrIHRpbWVzLCBlYWNoIHRpbWUgdXNpbmcgay0xIGZvbGRzIGZvciB0cmFpbmluZyBhbmQgdGhlIHJlbWFpbmluZyBmb2xkIGZvciB2YWxpZGF0aW9uLiBUaGlzIHByb2Nlc3MgaXMgcmVwZWF0ZWQgdW50aWwgZWFjaCBmb2xkIGhhcyBiZWVuIHVzZWQgYXMgdGhlIHZhbGlkYXRpb24gc2V0IG9uY2UuIEstZm9sZCBjcm9zcy12YWxpZGF0aW9uIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiB0aGUgZGF0YXNldCBpcyBzbWFsbCwgYXMgaXQgYWxsb3dzIHRoZSBtb2RlbCB0byBiZSB2YWxpZGF0ZWQgb24gZGlmZmVyZW50IHBvcnRpb25zIG9mIHRoZSBkYXRhLg0KDQoqKkV4YW1wbGUqKjogSW4gNS1mb2xkIGNyb3NzLXZhbGlkYXRpb24sIHRoZSBkYXRhIGlzIGRpdmlkZWQgaW50byBmaXZlIHBhcnRzLiBUaGUgbW9kZWwgaXMgdHJhaW5lZCBvbiBmb3VyIHBhcnRzIGFuZCB2YWxpZGF0ZWQgb24gdGhlIHJlbWFpbmluZyBvbmUsIGFuZCB0aGlzIHByb2Nlc3MgaXMgcmVwZWF0ZWQgZml2ZSB0aW1lcywgZW5zdXJpbmcgdGhhdCBldmVyeSBkYXRhIHBvaW50IGlzIHVzZWQgZm9yIHZhbGlkYXRpb24uDQoNCioqU3RyYXRpZmllZCBLLUZvbGQgQ3Jvc3MtVmFsaWRhdGlvbioqDQoNCkEgdmFyaWF0aW9uIG9mIGstZm9sZCBjcm9zcy12YWxpZGF0aW9uLCBzdHJhdGlmaWVkIGstZm9sZCBjcm9zcy12YWxpZGF0aW9uIGVuc3VyZXMgdGhhdCBlYWNoIGZvbGQgaGFzIHRoZSBzYW1lIHByb3BvcnRpb24gb2YgZWFjaCBjbGFzcyBhcyB0aGUgZW50aXJlIGRhdGFzZXQuIFRoaXMgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCB3aGVuIHRoZSBkYXRhc2V0IGlzIGltYmFsYW5jZWQsIGFzIGl0IGVuc3VyZXMgdGhhdCB0aGUgdHJhaW5pbmcgYW5kIHZhbGlkYXRpb24gc2V0cyByZXByZXNlbnQgdGhlIGRhdGEgZGlzdHJpYnV0aW9uIGFjY3VyYXRlbHkuDQoNCioqRXhhbXBsZSoqOiBJbiBhIGJpbmFyeSBjbGFzc2lmaWNhdGlvbiB0YXNrIHdoZXJlIHRoZSBkYXRhIGlzIGltYmFsYW5jZWQgKGUuZy4sIDkwJSBjbGFzcyBBLCAxMCUgY2xhc3MgQiksIHN0cmF0aWZpZWQgay1mb2xkIGVuc3VyZXMgdGhhdCBlYWNoIGZvbGQgY29udGFpbnMgYSBzaW1pbGFyIHJhdGlvIG9mIGNsYXNzIEEgdG8gY2xhc3MgQi4NCg0KKipMZWF2ZS1PbmUtT3V0IENyb3NzLVZhbGlkYXRpb24gKExPT0NWKSoqDQoNCkluIGxlYXZlLW9uZS1vdXQgY3Jvc3MtdmFsaWRhdGlvbiwgZWFjaCBkYXRhIHBvaW50IGlzIHVzZWQgYXMgYSBzZXBhcmF0ZSB2YWxpZGF0aW9uIHNldCB3aGlsZSB0aGUgcmVzdCBvZiB0aGUgZGF0YSBwb2ludHMgYXJlIHVzZWQgZm9yIHRyYWluaW5nLiBUaGlzIHByb2Nlc3MgaXMgcmVwZWF0ZWQgZm9yIGVhY2ggZGF0YSBwb2ludCBpbiB0aGUgZGF0YXNldCwgd2hpY2ggaXMgcGFydGljdWxhcmx5IHVzZWZ1bCB3aGVuIHRoZSBkYXRhc2V0IGlzIHNtYWxsLg0KDQoqKkV4YW1wbGUqKjogRm9yIGEgZGF0YXNldCBvZiAxMDAgZGF0YSBwb2ludHMsIExPT0NWIHRyYWlucyB0aGUgbW9kZWwgMTAwIHRpbWVzLCBlYWNoIHRpbWUgbGVhdmluZyBvdXQgYSBkaWZmZXJlbnQgc2luZ2xlIGRhdGEgcG9pbnQgZm9yIHZhbGlkYXRpb24uDQoNClRoZXNlIHZhbGlkYXRpb24gdGVjaG5pcXVlcyBoZWxwIHByZXZlbnQgb3ZlcmZpdHRpbmcsIGVuc3VyZSB0aGF0IHRoZSBtb2RlbCBpcyB3ZWxsLXR1bmVkLCBhbmQgbWFrZSB0aGUgbW9zdCBvdXQgb2YgYXZhaWxhYmxlIGRhdGEuDQoNCg0KIyMjIFRlc3RpbmcgdGhlIE1vZGVsDQoNCk9uY2UgdGhlIG1vZGVsIGhhcyBiZWVuIHRyYWluZWQgYW5kIHZhbGlkYXRlZCwgaXQgaXMgY3J1Y2lhbCB0byBldmFsdWF0ZSBpdHMgcGVyZm9ybWFuY2Ugb24gYSBzZXBhcmF0ZSB0ZXN0IGRhdGFzZXQuIFRoZSB0ZXN0IHNldCBpcyB1c2VkIHRvIGFzc2VzcyBob3cgd2VsbCB0aGUgbW9kZWwgZ2VuZXJhbGl6ZXMgdG8gbmV3LCB1bnNlZW4gZGF0YS4gVGhpcyBldmFsdWF0aW9uIHByb3ZpZGVzIGFuIGVzdGltYXRlIG9mIGhvdyB0aGUgbW9kZWwgd2lsbCBwZXJmb3JtIGluIHByb2R1Y3Rpb24gb3Igb24gbmV3IGluY29taW5nIGRhdGEuDQoNCioqVGVzdCBEYXRhc2V0KioNCg0KVGhlIHRlc3QgZGF0YXNldCBzaG91bGQgbmV2ZXIgYmUgdXNlZCBpbiBhbnkgcGFydCBvZiB0aGUgbW9kZWwtYnVpbGRpbmcgcHJvY2VzcywgaW5jbHVkaW5nIGR1cmluZyB0cmFpbmluZyBvciB2YWxpZGF0aW9uLiBJdHMgc29sZSBwdXJwb3NlIGlzIHRvIHNlcnZlIGFzIGFuIGluZGVwZW5kZW50IGFzc2Vzc21lbnQgb2YgdGhlIG1vZGVs4oCZcyBnZW5lcmFsaXphdGlvbiBjYXBhYmlsaXR5Lg0KDQoqKlBlcmZvcm1hbmNlIE1ldHJpY3MqKg0KDQpUaGUgcGVyZm9ybWFuY2Ugb2YgdGhlIG1vZGVsIGlzIG1lYXN1cmVkIHVzaW5nIHZhcmlvdXMgbWV0cmljcywgd2hpY2ggZGVwZW5kIG9uIHRoZSB0eXBlIG9mIHByb2JsZW0gKGUuZy4sIGNsYXNzaWZpY2F0aW9uLCByZWdyZXNzaW9uKS4gQ29tbW9uIG1ldHJpY3MgaW5jbHVkZToNCg0KKiAqKkZvciBDbGFzc2lmaWNhdGlvbioqOiBBY2N1cmFjeSwgcHJlY2lzaW9uLCByZWNhbGwsIEYxIHNjb3JlLCBhcmVhIHVuZGVyIHRoZSBST0MgY3VydmUgKEFVQyksIGNvbmZ1c2lvbiBtYXRyaXguDQoNCiogKipGb3IgUmVncmVzc2lvbioqOiBNZWFuIHNxdWFyZWQgZXJyb3IgKE1TRSksIHJvb3QgbWVhbiBzcXVhcmVkIGVycm9yIChSTVNFKSwgbWVhbiBhYnNvbHV0ZSBlcnJvciAoTUFFKSwgUi1zcXVhcmVkLg0KDQpUaGVzZSBtZXRyaWNzIGFsbG93IHByYWN0aXRpb25lcnMgdG8gZXZhbHVhdGUgaG93IHdlbGwgdGhlIG1vZGVsIG1ha2VzIHByZWRpY3Rpb25zLCBkZXRlY3QgYmlhc2VzLCBhbmQgdW5kZXJzdGFuZCBhcmVhcyB3aGVyZSB0aGUgbW9kZWwgbWF5IHJlcXVpcmUgaW1wcm92ZW1lbnQuDQoNCioqRXhhbXBsZSoqIEZvciBhIGNsYXNzaWZpY2F0aW9uIHByb2JsZW0sIGFjY3VyYWN5IGFsb25lIG1pZ2h0IG5vdCBiZSBzdWZmaWNpZW50LCBlc3BlY2lhbGx5IGlmIHRoZSBjbGFzc2VzIGFyZSBpbWJhbGFuY2VkLiBJbiB0aGlzIGNhc2UsIG1ldHJpY3MgbGlrZSBwcmVjaXNpb24sIHJlY2FsbCwgYW5kIEYxIHNjb3JlIGNhbiBwcm92aWRlIG1vcmUgaW5zaWdodCBpbnRvIG1vZGVsIHBlcmZvcm1hbmNlLg0KDQoqKk1vZGVsIENvbXBhcmlzb24qKg0KDQpPbmNlIHRoZSBtb2RlbCBpcyB0ZXN0ZWQsIGl0IGNhbiBiZSBjb21wYXJlZCB0byBiYXNlbGluZSBtb2RlbHMgb3Igb3RoZXIgY29tcGV0aW5nIG1vZGVscyB0byBkZXRlcm1pbmUgd2hldGhlciBpdCBwcm92aWRlcyBhIHNpZ25pZmljYW50IGltcHJvdmVtZW50LiBJZiBtdWx0aXBsZSBtb2RlbHMgYXJlIGNvbnNpZGVyZWQsIHN0YXRpc3RpY2FsIHRlc3RzIGxpa2UgcGFpcmVkIHQtdGVzdHMgb3IgY3Jvc3MtdmFsaWRhdGlvbiByZXN1bHRzIGNhbiBiZSB1c2VkIHRvIGRldGVybWluZSB3aGljaCBtb2RlbCBwZXJmb3JtcyBiZXN0Lg0KDQoqKkV4YW1wbGUqKjogQSBkZWNpc2lvbiB0cmVlIG1vZGVsIG1pZ2h0IGJlIGNvbXBhcmVkIHRvIGEgcmFuZG9tIGZvcmVzdCBtb2RlbCBvciBhIHN1cHBvcnQgdmVjdG9yIG1hY2hpbmUuIFRoZSBtb2RlbCB3aXRoIHRoZSBoaWdoZXN0IHBlcmZvcm1hbmNlIG1ldHJpY3MgYW5kIGdlbmVyYWxpemF0aW9uIGFiaWxpdHkgd291bGQgYmUgY2hvc2VuIGZvciBkZXBsb3ltZW50Lg0KDQoqKk92ZXJmaXR0aW5nIGFuZCBVbmRlcmZpdHRpbmcqKiANCg0KQWZ0ZXIgdGVzdGluZyB0aGUgbW9kZWwsIGl04oCZcyBpbXBvcnRhbnQgdG8gZW5zdXJlIHRoYXQgaXQgaXMgbm90IG92ZXJmaXR0aW5nIChpLmUuLCBwZXJmb3JtaW5nIGV4Y2VwdGlvbmFsbHkgd2VsbCBvbiB0aGUgdHJhaW5pbmcgZGF0YSBidXQgcG9vcmx5IG9uIHVuc2VlbiBkYXRhKSBvciB1bmRlcmZpdHRpbmcgKGkuZS4sIG5vdCBjYXB0dXJpbmcgdGhlIHVuZGVybHlpbmcgcGF0dGVybnMgaW4gdGhlIGRhdGEgd2VsbCBlbm91Z2gpLiBUaGVzZSBpc3N1ZXMgY2FuIGJlIGRpYWdub3NlZCB1c2luZyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHBlcmZvcm1hbmNlIG9uIHRoZSB0cmFpbmluZyBzZXQsIHZhbGlkYXRpb24gc2V0LCBhbmQgdGVzdCBzZXQuDQoNCioqRXhhbXBsZSoqOiBBIG1vZGVsIHRoYXQgc2hvd3MgaGlnaCBwZXJmb3JtYW5jZSBvbiB0aGUgdHJhaW5pbmcgc2V0IGJ1dCBwZXJmb3JtcyBwb29ybHkgb24gdGhlIHRlc3Qgc2V0IG1heSBiZSBvdmVyZml0dGluZywgaW5kaWNhdGluZyB0aGUgbmVlZCBmb3IgcmVndWxhcml6YXRpb24gb3IgbW9yZSBkYXRhLg0KDQpcDQoNCkluIHN1bW1hcnksIGJvdGggdmFsaWRhdGlvbiBhbmQgdGVzdGluZyBwbGF5IGEga2V5IHJvbGUgaW4gbW9kZWwgb3B0aW1pemF0aW9uLiBWYWxpZGF0aW9uIGhlbHBzIGZpbmUtdHVuZSB0aGUgbW9kZWwgZHVyaW5nIHRoZSB0cmFpbmluZyBwcm9jZXNzLCBlbnN1cmluZyB0aGF0IGl0IGlzIG5vdCBvdmVyZml0dGluZyBvciB1bmRlcmZpdHRpbmcgdGhlIGRhdGEuIE9uY2UgYSBtb2RlbCBpcyBmaW5hbGl6ZWQsIHRlc3RpbmcgcHJvdmlkZXMgdGhlIGZpbmFsIGV2YWx1YXRpb24gb2YgaXRzIGFiaWxpdHkgdG8gZ2VuZXJhbGl6ZSB0byBuZXcgZGF0YS4gQnkgdXNpbmcgcHJvcGVyIHZhbGlkYXRpb24gdGVjaG5pcXVlcywgbWFjaGluZSBsZWFybmluZyBwcmFjdGl0aW9uZXJzIGNhbiBidWlsZCBtb2RlbHMgdGhhdCBhcmUgcm9idXN0LCBhY2N1cmF0ZSwgYW5kIGNhcGFibGUgb2YgZGVsaXZlcmluZyByZWxpYWJsZSByZXN1bHRzIG9uIHJlYWwtd29ybGQgZGF0YS4NCg0KDQojIyBSZXBvcnRpbmcgQWN0aW9uYWJsZSBSZXN1bHRzDQoNClRyYW5zbGF0aW5nIHN0YXRpc3RpY2FsIG9yIG1vZGVsIG91dHB1dHMgaW50byBhY3Rpb25hYmxlIGluc2lnaHRzIGlzIGNydWNpYWwuIEludGVycHJldGluZyByZXN1bHRzIGluIHRlcm1zIG9mIHRoZWlyIHJlYWwtd29ybGQgaW1wbGljYXRpb25zIGFkZHMgdmFsdWUgdG8gdGhlIHJlcG9ydC4NCg0KKiAqKkFjdGlvbmFibGUgSW5zaWdodHMqKjogRGlzY3VzcyBob3cgc3Rha2Vob2xkZXJzIGNhbiB1c2UgdGhlIGZpbmRpbmdzIHRvIG1ha2UgaW5mb3JtZWQgZGVjaXNpb25zIG9yIGFkZHJlc3MgY2hhbGxlbmdlcy4NCg0KKiAqKlBvbGljeSBvciBTdHJhdGVneSBSZWNvbW1lbmRhdGlvbnMqKjogU3VnZ2VzdCBzcGVjaWZpYyBwb2xpY2llcywgc3RyYXRlZ2llcywgb3IgaW50ZXJ2ZW50aW9ucyBiYXNlZCBvbiB0aGUgcmVzdWx0cy4NCg0KKiAqKlNjYWxhYmlsaXR5IGFuZCBHZW5lcmFsaXphYmlsaXR5Kio6IEV4cGxhaW4gd2hldGhlciB0aGUgZmluZGluZ3MgY2FuIGJlIGFwcGxpZWQgYmV5b25kIHRoZSBhbmFseXplZCBzYW1wbGUgb3IgY29udGV4dC4NCg0KDQpGb3IgZXhhbXBsZSwgaW4gYW4gZW52aXJvbm1lbnRhbCBpbXBhY3Qgc3R1ZHksIGludGVycHJldGluZyByZXN1bHRzIG1pZ2h0IGludm9sdmUgcmVjb21tZW5kaW5nIGNoYW5nZXMgaW4gYWdyaWN1bHR1cmFsIHByYWN0aWNlcyB0byByZWR1Y2UgY2FyYm9uIGVtaXNzaW9ucy4NCg0KDQoNCiMgRHJhZnRpbmcgRWZmZWN0aXZlIFJlcG9ydHMNCg0KVGVjaG5pY2FsIHJlcG9ydCB3cml0aW5nIGlzIGEgdml0YWwgc2tpbGwgZm9yIGRhdGEgc2NpZW50aXN0cywgZW5hYmxpbmcgdGhlbSB0byBjb21tdW5pY2F0ZSBjb21wbGV4IGZpbmRpbmdzIGFuZCBhbmFseXNlcyB0byB2YXJpb3VzIHN0YWtlaG9sZGVycyBlZmZlY3RpdmVseS4gQSB3ZWxsLXN0cnVjdHVyZWQgdGVjaG5pY2FsIHJlcG9ydCBlbnN1cmVzIGNsYXJpdHksIHByZWNpc2lvbiwgYW5kIHJlbGV2YW5jZSwgbWFraW5nIGl0IGVhc2llciBmb3IgcmVhZGVycyB0byB1bmRlcnN0YW5kIGFuZCBhY3QgdXBvbiB0aGUgaW5mb3JtYXRpb24gcHJvdmlkZWQuIEJlbG93IGFyZSBndWlkZWxpbmVzIGFuZCBiZXN0IHByYWN0aWNlcyBmb3IgY3JhZnRpbmcgZWZmZWN0aXZlIHRlY2huaWNhbCByZXBvcnRzIGluIGRhdGEgc2NpZW5jZS4NCg0KIyMgV2hhdCB0byBSZXBvcnQNCg0KSW4gc3RhdGlzdGljcyBhbmQgZGF0YSBzY2llbmNlLCBlZmZlY3RpdmUgcmVwb3J0aW5nIGlzIGNydWNpYWwgZm9yIHRyYW5zcGFyZW5jeSwgcmVwcm9kdWNpYmlsaXR5LCBhbmQgYWN0aW9uYWJsZSBpbnNpZ2h0cy4gVGhlIHdheSBmaW5kaW5ncyBhcmUgY29tbXVuaWNhdGVkIGNhbiBzaWduaWZpY2FudGx5IGluZmx1ZW5jZSBkZWNpc2lvbi1tYWtpbmcgYW5kIHRoZSBhYmlsaXR5IG9mIG90aGVycyB0byB1bmRlcnN0YW5kLCByZXBsaWNhdGUsIGFuZCBidWlsZCB1cG9uIHRoZSB3b3JrLiBQcm9wZXIgcmVwb3J0aW5nIGVuc3VyZXMgdGhhdCB0aGUgYW5hbHlzaXMgaXMgY3JlZGlibGUsIG1lYW5pbmdmdWwsIGFuZCB1c2VmdWwgdG8gc3Rha2Vob2xkZXJzLiBUaGlzIHN1YnNlY3Rpb24gZGlzY3Vzc2VzIHRoZSBrZXkgY29tcG9uZW50cyB0aGF0IHNob3VsZCBiZSByZXBvcnRlZCBpbiBzdGF0aXN0aWNzIGFuZCBkYXRhIHNjaWVuY2UgcHJvamVjdHMsIGVtcGhhc2l6aW5nIGNsYXJpdHksIGFjY3VyYWN5LCBhbmQgZXRoaWNhbCBjb25zaWRlcmF0aW9ucy4NCg0KDQojIyMgUHJvYmxlbSBEZWZpbml0aW9uIGFuZCBPYmplY3RpdmVzDQoNCkV2ZXJ5IGRhdGEgc2NpZW5jZSBvciBzdGF0aXN0aWNhbCByZXBvcnQgc2hvdWxkIGJlZ2luIHdpdGggYSBjbGVhciBhcnRpY3VsYXRpb24gb2YgdGhlIHByb2JsZW0gYmVpbmcgYWRkcmVzc2VkLiBUaGlzIGluY2x1ZGVzOg0KDQoqICoqUmVzZWFyY2ggUXVlc3Rpb25zKio6IFdoYXQgc3BlY2lmaWMgcXVlc3Rpb25zIG9yIGh5cG90aGVzZXMgaXMgdGhlIGFuYWx5c2lzIHRyeWluZyB0byBhbnN3ZXIgb3IgdGVzdD8NCg0KKiAqKk9iamVjdGl2ZXMqKjogV2hhdCBhcmUgdGhlIGdvYWxzIG9mIHRoZSBhbmFseXNpcywgc3VjaCBhcyBtYWtpbmcgcHJlZGljdGlvbnMsIHVuZGVyc3RhbmRpbmcgcmVsYXRpb25zaGlwcywgb3IgaWRlbnRpZnlpbmcgdHJlbmRzPw0KDQoqICoqQ29udGV4dCoqOiBCYWNrZ3JvdW5kIGluZm9ybWF0aW9uIGFib3V0IHRoZSBkb21haW4sIGluZHVzdHJ5LCBvciBwcm9ibGVtIGJlaW5nIGFkZHJlc3NlZCB0byBwcm92aWRlIHN0YWtlaG9sZGVycyB3aXRoIGEgY29tcHJlaGVuc2l2ZSB1bmRlcnN0YW5kaW5nLg0KDQojIyBEYXRhIERlc2NyaXB0aW9uIGFuZCBTb3VyY2VzDQoNClVuZGVyc3RhbmRpbmcgdGhlIGRhdGEgaXMgZnVuZGFtZW50YWwgdG8gdGhlIGNyZWRpYmlsaXR5IG9mIHRoZSBhbmFseXNpcy4gSW5jbHVkZToNCg0KKiAqKkRhdGEgU291cmNlcyoqOiBUaGUgb3JpZ2luIG9mIHRoZSBkYXRhLCB3aGV0aGVyIGNvbGxlY3RlZCBpbnRlcm5hbGx5LCBzY3JhcGVkIGZyb20gdGhlIHdlYiwgb3Igc291cmNlZCBmcm9tIHB1YmxpY2x5IGF2YWlsYWJsZSByZXBvc2l0b3JpZXMuDQoNCiogKipEYXRhIENoYXJhY3RlcmlzdGljcyoqOiBEZXNjcmlwdGlvbiBvZiB0aGUgZGF0YXNldCwgaW5jbHVkaW5nIHNpemUsIG51bWJlciBvZiB2YXJpYWJsZXMsIGRhdGEgdHlwZXMsIGFuZCB3aGV0aGVyIHRoZSBkYXRhIGlzIHN0cnVjdHVyZWQgb3IgdW5zdHJ1Y3R1cmVkLg0KDQoqICoqRGF0YSBDb2xsZWN0aW9uIE1ldGhvZHMqKjogSG93IHRoZSBkYXRhIHdhcyBjb2xsZWN0ZWQgKGUuZy4sIHN1cnZleXMsIHNlbnNvcnMsIGV4cGVyaW1lbnRzKSBhbmQgYW55IHNhbXBsaW5nIG1ldGhvZHMgdXNlZC4NCg0KKiAqKkV0aGljcyBhbmQgUHJpdmFjeSoqOiBBIGRpc2N1c3Npb24gb2YgZXRoaWNhbCBjb25zaWRlcmF0aW9ucywgaW5jbHVkaW5nIGhvdyBkYXRhIHByaXZhY3kgd2FzIGVuc3VyZWQgYW5kIHdoZXRoZXIgYXBwcm9wcmlhdGUgcGVybWlzc2lvbnMgb3IgY29uc2VudHMgd2VyZSBvYnRhaW5lZC4NCg0KIyMjIERhdGEgQ2xlYW5pbmcgYW5kIFByZXByb2Nlc3NpbmcNCg0KQmVmb3JlIGFuYWx5c2lzLCBkYXRhIG9mdGVuIHJlcXVpcmVzIGNsZWFuaW5nIGFuZCBwcmVwcm9jZXNzaW5nLiBSZXBvcnQ6DQoNCiogKipIYW5kbGluZyBvZiBNaXNzaW5nIERhdGEqKjogTWV0aG9kcyB1c2VkIHRvIGFkZHJlc3MgbWlzc2luZyB2YWx1ZXMgKGUuZy4sIGltcHV0YXRpb24sIHJlbW92YWwpLg0KDQoqICoqT3V0bGllciBUcmVhdG1lbnQqKjogSWRlbnRpZmljYXRpb24gYW5kIGhhbmRsaW5nIG9mIG91dGxpZXJzLg0KDQoqICoqRGF0YSBUcmFuc2Zvcm1hdGlvbioqOiBBbnkgdHJhbnNmb3JtYXRpb25zIGFwcGxpZWQgdG8gbWFrZSB0aGUgZGF0YSBzdWl0YWJsZSBmb3IgYW5hbHlzaXMsIHN1Y2ggYXMgc2NhbGluZywgZW5jb2RpbmcsIG9yIG5vcm1hbGl6aW5nLg0KDQoqICoqRGF0YSBRdWFsaXR5IElzc3VlcyoqOiBDaGFsbGVuZ2VzIGVuY291bnRlcmVkLCBzdWNoIGFzIGluY29uc2lzdGVuY2llcywgZHVwbGljYXRlcywgb3IgYmlhc2VzIGluIHRoZSBkYXRhLg0KDQojIyMgRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcyAoRURBKQ0KDQpFREEgcHJvdmlkZXMgaW5zaWdodHMgaW50byB0aGUgZGF0YSdzIHN0cnVjdHVyZSBhbmQgcmVsYXRpb25zaGlwcy4gUmVwb3J0Og0KDQoqICoqRGVzY3JpcHRpdmUgU3RhdGlzdGljcyoqOiBTdW1tYXJ5IHN0YXRpc3RpY3Mgc3VjaCBhcyBtZWFuLCBtZWRpYW4sIHN0YW5kYXJkIGRldmlhdGlvbiwgYW5kIGZyZXF1ZW5jeSBkaXN0cmlidXRpb25zLg0KDQoqICoqVmlzdWFsaXphdGlvbioqOiBLZXkgdmlzdWFsaXphdGlvbnMgdGhhdCByZXZlYWwgdHJlbmRzLCBwYXR0ZXJucywgb3IgYW5vbWFsaWVzIChlLmcuLCBoaXN0b2dyYW1zLCBzY2F0dGVyIHBsb3RzLCBjb3JyZWxhdGlvbiBoZWF0bWFwcykuDQoNCiogKipJbml0aWFsIEluc2lnaHRzKio6IE9ic2VydmF0aW9ucyBmcm9tIHRoZSBkYXRhLCBzdWNoIGFzIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB2YXJpYWJsZXMgb3IgcG90ZW50aWFsIGNoYWxsZW5nZXMgZm9yIHRoZSBtb2RlbGluZyBwaGFzZS4NCg0KKiAqKkZlYXR1cmUgRW5naW5lZXJpbmcqKjogQWRkaXRpb25hbCBmZWF0dXJlIGNyZWF0aW9uIGFuZCBleHRyYWN0aW9uIGJhc2VkIG9uIG1vZGVscyBhbmQgYWxnb3JpdGhtcy4NCg0KDQojIyMgTWV0aG9kb2xvZ3kNCg0KVHJhbnNwYXJlbmN5IGluIHRoZSBtZXRob2RzIHVzZWQgZW5zdXJlcyByZXByb2R1Y2liaWxpdHkgYW5kIGFpZHMgaW50ZXJwcmV0YXRpb24uIA0KDQoqICoqU3RhdGlzdGljYWwgTWV0aG9kcyBvciBNb2RlbHMqKjogQSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvZiB0aGUgc3RhdGlzdGljYWwgbWV0aG9kcyBvciBtYWNoaW5lIGxlYXJuaW5nIG1vZGVscyB1c2VkLg0KDQoNCiogKipBc3N1bXB0aW9ucyoqOiBBc3N1bXB0aW9ucyB1bmRlcmx5aW5nIHRoZSBjaG9zZW4gbWV0aG9kcyBhbmQgd2hldGhlciB0aGV5IHdlcmUgdGVzdGVkIChlLmcuLCBub3JtYWxpdHksIGxpbmVhcml0eSwgaW5kZXBlbmRlbmNlKS4NCg0KKiAqKkh5cGVycGFyYW1ldGVycyBhbmQgVHVuaW5nKio6IFNwZWNpZmljIHBhcmFtZXRlcnMgb2YgdGhlIG1vZGVscyBhbmQgdGhlIHByb2Nlc3MgZm9yIG9wdGltaXppbmcgdGhlbS4NCg0KDQojIyMgVmFsaWRhdGlvbiBhbmQgVGVzdGluZw0KDQpUbyBlbnN1cmUgcmVsaWFiaWxpdHksIGRlc2NyaWJlIHRoZSB2YWxpZGF0aW9uIGFuZCB0ZXN0aW5nIHByb2Nlc3M6DQoNCiogKipUcmFpbi1UZXN0IFNwbGl0Kio6IEhvdyB0aGUgZGF0YSB3YXMgZGl2aWRlZCBpbnRvIHRyYWluaW5nLCB2YWxpZGF0aW9uLCBhbmQgdGVzdCBzZXRzLCBpbmNsdWRpbmcgcHJvcG9ydGlvbnMgYW5kIG1ldGhvZHMgKGUuZy4sIHJhbmRvbSBzYW1wbGluZywgc3RyYXRpZmllZCBzYW1wbGluZykuDQoNCiogKipWYWxpZGF0aW9uIFRlY2huaXF1ZXMqKjogQXBwcm9hY2hlcyB1c2VkLCBzdWNoIGFzIGstZm9sZCBjcm9zcy12YWxpZGF0aW9uIG9yIGhvbGRvdXQgdmFsaWRhdGlvbi4NCg0KKiAqKlBlcmZvcm1hbmNlIE1ldHJpY3MqKjogTWV0cmljcyB1c2VkIHRvIGV2YWx1YXRlIG1vZGVsIHBlcmZvcm1hbmNlIChlLmcuLCBhY2N1cmFjeSwgcHJlY2lzaW9uLCByZWNhbGwsIEYxIHNjb3JlLCBBVUMsIG1lYW4gc3F1YXJlZCBlcnJvcikuDQoNCg0KIyMjIFJlc3VsdHMsIEludGVycHJldGF0b25zLCBhbmQgRGlzY3Vzc2lvbnMNCg0KVGhlIHJlc3VsdHMgc2hvdWxkIGJlIHByZXNlbnRlZCBjbGVhcmx5IGFuZCBvYmplY3RpdmVseSwgaW5jbHVkaW5nOg0KDQoqKktleSBGaW5kaW5ncyoqOiBIaWdobGlnaHQgdGhlIG1vc3QgaW1wb3J0YW50IGluc2lnaHRzIGRlcml2ZWQgZnJvbSB0aGUgYW5hbHlzaXMgYW5kIGF2b2lkIHJlcG9ydGluZyBldmVyeXRoaW5nIHRoZSBvdXRwdXRzIG9mIHRoZSAqKmZpbmFsIG1vZGVscyoqLiBUaGUgaW50ZXJtZWRpYXRlIGNhbmRpZGF0ZSBtb2RlbHMgdGhhdCBhcmUgbm90IGNpdGVkIHRvIHN1cHBvcnQgeW91ciBhcmd1bWVudHMgc2hvdWxkIG5vdCBiZSBkaXNjdXNzZWQgaW4gdGhlIHJlcG9ydC4NCg0KDQoqKk1vZGVsIFBlcmZvcm1hbmNlKio6IERldGFpbGVkIHBlcmZvcm1hbmNlIG1ldHJpY3MsIGluY2x1ZGluZyBjb21wYXJpc29ucyBiZXR3ZWVuIGNhbmRpZGF0ZSBtb2RlbHMgb3IgbWV0aG9kcy4gIE1ha2Ugc3VyZSB0aGUgcGVyZm9ybWFuY2UgbWV0cmljcyBhcmUgYXQgdGhlIHNhbWUgc2NhbGUgYW5kIGNvbXBhcmFibGUuIA0KDQoNCioqU3RhdGlzdGljYWwgU2lnbmlmaWNhbmNlKio6IFJlcG9ydCBwLXZhbHVlcywgY29uZmlkZW5jZSBpbnRlcnZhbHMsIGFuZCBlZmZlY3Qgc2l6ZXMsIGlmIGFwcGxpY2FibGUsIG9mIHRoZSBmaW5hbCBtb2RlbChzKSB0byBiZSByZWNvbW1lbmRlZCB0byBjbGllbnRzIGFuZC9vciB0byBiZSBkZXBsb3llZCBpbiBwcm9kdWN0aW9uIGVudmlyb25tZW50Lg0KDQoqKlZpc3VhbGl6YXRpb25zKio6IENoYXJ0cywgZ3JhcGhzLCBvciB0YWJsZXMgdGhhdCBlZmZlY3RpdmVseSBjb21tdW5pY2F0ZSB0aGUgcmVzdWx0cy4gVHJ5IGludGVyYWN0aXZlIHZpc3VhbCByZXByZXNlbnRhdGlvbnMgd2hlbmV2ZXIgcG9zc2libGUgYW5kIGZvbGxvdyBiZXN0IHByYWN0aWNlcyBpbiB2aXN1YWwgZGVzaWduLg0KDQoNCioqRGlzY3Vzc2lvbiBhbmQgSW50ZXJwcmV0YXRpb24qKiBEaXNjdXNzIHRoZSByZXN1bHRzIGFuZCB0aGVpciBwcmFjdGljYWwgaW1wbGljYXRpb25zLiANCg0KKiAqKkluc2lnaHRzKio6IEV4cGxhaW4gdGhlIG1lYW5pbmcgb2YgdGhlIGZpbmRpbmdzIGFuZCBob3cgdGhleSBhZGRyZXNzIHRoZSByZXNlYXJjaCBxdWVzdGlvbnMgb3Igb2JqZWN0aXZlcy4NCg0KKiAqKkxpbWl0YXRpb25zKio6IEFja25vd2xlZGdlIGFueSBsaW1pdGF0aW9ucyBpbiB0aGUgZGF0YSwgbWV0aG9kb2xvZ3ksIG9yIGdlbmVyYWxpemFiaWxpdHkgb2YgdGhlIHJlc3VsdHMuDQoNCiogKipDb250ZXh0dWFsIFJlbGV2YW5jZSoqOiBEaXNjdXNzIGhvdyB0aGUgZmluZGluZ3MgcmVsYXRlIHRvIHRoZSBwcm9ibGVtIGRvbWFpbiBhbmQgY29udHJpYnV0ZSB0byBkZWNpc2lvbi1tYWtpbmcuDQoNCg0KDQojIyMgRXRoaWNhbCBDb25zaWRlcmF0aW9ucyBhbmQgUmVwcm9kdWNpYmlsaXR5DQoNCioqRXRoaWNhbCB0cmFuc3BhcmVuY3kqKiBpcyBhIGdyb3dpbmcgcHJpb3JpdHkgaW4gZGF0YSBzY2llbmNlLiANCg0KKiAqKkJpYXMgYW5kIEZhaXJuZXNzKio6IEFzc2VzcyBhbmQgYWRkcmVzcyBiaWFzZXMgaW4gdGhlIGRhdGEgb3IgbW9kZWxzLg0KKiAqKlByaXZhY3kgYW5kIFNlY3VyaXR5Kio6IE1lYXN1cmVzIHRha2VuIHRvIHByb3RlY3Qgc2Vuc2l0aXZlIGRhdGEuDQoqICoqSW1wYWN0IG9mIFJlc3VsdHMqKjogQ29uc2lkZXIgcG90ZW50aWFsIGNvbnNlcXVlbmNlcyBvZiB0aGUgYW5hbHlzaXMsIGVzcGVjaWFsbHkgaWYgaXQgaW5mbHVlbmNlcyBwb2xpY3kgb3IgYnVzaW5lc3MgZGVjaXNpb25zLg0KDQoNCg0KKipSZXByb2R1Y2liaWxpdHkqKiBlbnN1cmVzIHRoYXQgb3RoZXJzIGNhbiByZXBsaWNhdGUgdGhlIGFuYWx5c2lzIGJ5IHJlcG9ydGluZyANCg0KKiAqKkNvZGUgYW5kIFRvb2xzKio6IFRoZSBwcm9ncmFtbWluZyBsYW5ndWFnZXMsIGxpYnJhcmllcywgYW5kIHNvZnR3YXJlIHRvb2xzIHVzZWQuDQoqICoqUGFyYW1ldGVycyBhbmQgU2V0dGluZ3MqKjogU3BlY2lmaWMgc2V0dGluZ3MsIGNvbmZpZ3VyYXRpb25zLCBvciBzZWVkcyB1c2VkIGluIHRoZSBhbmFseXNpcy4NCiogKipBY2Nlc3MgdG8gRGF0YSBhbmQgQ29kZSoqOiBXaGV0aGVyIHRoZSBkYXRhIGFuZCBjb2RlIGFyZSBhdmFpbGFibGUgYW5kIGhvdyB0aGV5IGNhbiBiZSBhY2Nlc3NlZCAod2hpbGUgYWRoZXJpbmcgdG8gcHJpdmFjeSBhbmQgY29weXJpZ2h0IHJlc3RyaWN0aW9ucykuDQoNCg0KDQojIyMgQ29uY2x1c2lvbiBhbmQgUmVjb21tZW5kYXRpb25zDQoNClN1bW1hcml6ZSBhbmQgcHJvdmlkZSBhY3Rpb25hYmxlIGluc2lnaHRzOg0KDQoqKlN1bW1hcnkqKjogUmVjYXAgdGhlIHByb2JsZW0sIGFwcHJvYWNoLCBhbmQga2V5IGZpbmRpbmdzLg0KDQoqKlJlY29tbWVuZGF0aW9ucyoqOiBPZmZlciBzdWdnZXN0aW9ucyBmb3Igc3Rha2Vob2xkZXJzLCBzdWNoIGFzIHBvbGljeSBjaGFuZ2VzLCBmdXJ0aGVyIGFuYWx5c2lzLCBvciBidXNpbmVzcyBzdHJhdGVnaWVzLg0KDQoqKkZ1dHVyZSBXb3JrKio6IEhpZ2hsaWdodCBhcmVhcyBmb3IgYWRkaXRpb25hbCBleHBsb3JhdGlvbiBvciBpbXByb3ZlbWVudC4NCg0KXA0KDQpJbiBzdW1tYXJ5LCBlZmZlY3RpdmUgcmVwb3J0aW5nIGluIHN0YXRpc3RpY3MgYW5kIGRhdGEgc2NpZW5jZSByZXF1aXJlcyBjbGFyaXR5LCBhY2N1cmFjeSwgYW5kIHRob3JvdWdobmVzcy4gQnkgYWRkcmVzc2luZyB0aGUgcHJvYmxlbSwgZGF0YSwgbWV0aG9kcywgcmVzdWx0cywgYW5kIGltcGxpY2F0aW9ucywgYW5hbHlzdHMgY2FuIGVuc3VyZSB0aGF0IHRoZWlyIGZpbmRpbmdzIGFyZSB1bmRlcnN0YW5kYWJsZSwgYWN0aW9uYWJsZSwgYW5kIHJlcHJvZHVjaWJsZS4gQWRkaXRpb25hbGx5LCBldGhpY2FsIGNvbnNpZGVyYXRpb25zIGFuZCByZXByb2R1Y2liaWxpdHkgYXJlIGludGVncmFsIHRvIGJ1aWxkaW5nIHRydXN0IGFuZCBmb3N0ZXJpbmcgcmVzcG9uc2libGUgZGF0YSBzY2llbmNlIHByYWN0aWNlcy4gQSBjb21wcmVoZW5zaXZlIHJlcG9ydCBub3Qgb25seSBzaG93Y2FzZXMgdGhlIHRlY2huaWNhbCByaWdvciBvZiB0aGUgYW5hbHlzaXMgYnV0IGFsc28gYnJpZGdlcyB0aGUgZ2FwIGJldHdlZW4gY29tcGxleCBkYXRhIHNjaWVuY2UgcHJvY2Vzc2VzIGFuZCBhY3Rpb25hYmxlIGluc2lnaHRzIGZvciBzdGFrZWhvbGRlcnMuDQoNCg0KDQojIyBTdHJ1Y3R1cmUgb2YgYSBUZWNobmljYWwgUmVwb3J0DQoNCkluIHRoZSBmaWVsZHMgb2Ygc3RhdGlzdGljcyBhbmQgZGF0YSBzY2llbmNlLCBlZmZlY3RpdmUgY29tbXVuaWNhdGlvbiBvZiBmaW5kaW5ncyBpcyBwYXJhbW91bnQuIEEgd2VsbC1zdHJ1Y3R1cmVkIHJlcG9ydCBhbGxvd3Mgc3Rha2Vob2xkZXJzIHRvIHVuZGVyc3RhbmQgdGhlIGFuYWx5c2lzLCBldmFsdWF0ZSBpdHMgcmVsaWFiaWxpdHksIGFuZCBkZXJpdmUgYWN0aW9uYWJsZSBpbnNpZ2h0cy4gVGhlIHN0cnVjdHVyZSBvZiBzdWNoIGEgcmVwb3J0IG11c3QgYmFsYW5jZSB0ZWNobmljYWwgcmlnb3Igd2l0aCBjbGFyaXR5IHRvIGNhdGVyIHRvIGJvdGggdGVjaG5pY2FsIGFuZCBub24tdGVjaG5pY2FsIGF1ZGllbmNlcy4gDQoNCiMjIyBUaXRsZSBhbmQgQWJzdHJhY3QNCg0KVGhlIHRpdGxlIGFuZCBhYnN0cmFjdCBhcmUgdGhlIGZpcnN0IGNvbXBvbmVudHMgb2YgdGhlIHJlcG9ydCB0aGF0IHJlYWRlcnMgZW5jb3VudGVyLiANCg0KKipUaXRsZSoqOiBBIGNvbmNpc2UgYW5kIGRlc2NyaXB0aXZlIHRpdGxlIHNob3VsZCBhY2N1cmF0ZWx5IHJlZmxlY3QgdGhlIGNvbnRlbnQgb2YgdGhlIHJlcG9ydC4gSXQgc2hvdWxkIGluY2x1ZGUga2V5IHRlcm1zIHJlbGV2YW50IHRvIHRoZSBhbmFseXNpcyB0byBpbW1lZGlhdGVseSBpbmZvcm0gcmVhZGVycyBhYm91dCB0aGUgc2NvcGUgb2YgdGhlIHdvcmsuDQoNCioqQWJzdHJhY3QqKjogVGhlIGFic3RyYWN0IHByb3ZpZGVzIGEgYnJpZWYgc3VtbWFyeSBvZiB0aGUgcmVwb3J0LCB0eXBpY2FsbHkgaW4gMTUw4oCTMjUwIHdvcmRzLiBJdCBvdXRsaW5lcyB0aGUgcHJvYmxlbSwgbWV0aG9kb2xvZ3ksIGtleSByZXN1bHRzLCBhbmQgbWFpbiBjb25jbHVzaW9ucy4gVGhlIGFic3RyYWN0IGhlbHBzIHJlYWRlcnMgcXVpY2tseSBkZXRlcm1pbmUgdGhlIHJlcG9ydOKAmXMgcmVsZXZhbmNlIHRvIHRoZWlyIG5lZWRzLiA8Zm9udCBjb2xvciA9ICJyZWQiPioqXGNvbG9ye3JlZH0gQWJzdHJhY3QgaXMgYW4gb3B0aW9uYWwgY29tcG9uZW50IG9mIGFsbCByZXBvcnRzIGluIHRoaXMgY2xhc3MuIEhvd2V2ZXIsIHlvdSBhcmUgZW5jb3VyYWdlZCB0byBpbmNsdWRlIHRoZSBhYnN0YXJhY3QgaW4geW91dCByZXBvcnQqKjwvZm9udD4NCg0KIyMjIEludHJvZHVjdGlvbg0KDQpUaGUgaW50cm9kdWN0aW9uIHNldHMgdGhlIHN0YWdlIGZvciB0aGUgcmVwb3J0IGJ5IHByb3ZpZGluZyBjb250ZXh0IGFuZCBkZWZpbmluZyBpdHMgb2JqZWN0aXZlcy4NCg0KKipCYWNrZ3JvdW5kKio6IEV4cGxhaW4gdGhlIHByb2JsZW0gZG9tYWluIGFuZCB3aHkgdGhlIGFuYWx5c2lzIGlzIGltcG9ydGFudC4gVGhpcyBpbmNsdWRlcyBhIGRpc2N1c3Npb24gb2YgYW55IHByaW9yIHdvcmsgb3IgY2hhbGxlbmdlcyB0aGF0IG5lY2Vzc2l0YXRlZCB0aGUgYW5hbHlzaXMuDQoNCioqT2JqZWN0aXZlcyoqOiBDbGVhcmx5IHN0YXRlIHRoZSBnb2FscyBvZiB0aGUgcmVwb3J0LCBzdWNoIGFzIGFuc3dlcmluZyBzcGVjaWZpYyByZXNlYXJjaCBxdWVzdGlvbnMsIHRlc3RpbmcgaHlwb3RoZXNlcywgb3IgZGV2ZWxvcGluZyBwcmVkaWN0aXZlIG1vZGVscy4NCg0KKipTY29wZSoqOiBEZWZpbmUgdGhlIGJvdW5kYXJpZXMgb2YgdGhlIGFuYWx5c2lzLCBpbmNsdWRpbmcgYW55IGFzc3VtcHRpb25zIG9yIGxpbWl0YXRpb25zIGtub3duIGF0IHRoZSBvdXRzZXQuDQoNCioqQ2xlYXIgUHJvYmxlbSBTdGF0ZW1lbnRzKio6IFRoZSByZXNlYXJjaC9wcmFjdGljYWwgcXVlc3Rpb25zIG11c3QgY2xlYXJseSBkZWZpbmVkIGFuZCBhcmUgdHJhbnNsYXRlIHRvIGFuYWx5dGljIHF1ZXN0aW9ucyBhY2N1cmF0ZWx5LiANCg0KDQojIyMgRGF0YSBEZXNjcmlwdGlvbg0KDQpUaGlzIHNlY3Rpb24gcHJvdmlkZXMgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGRhdGEgdXNlZCBpbiB0aGUgYW5hbHlzaXMuDQoNCioqRGF0YSBTb3VyY2VzKio6IERlc2NyaWJlIHdoZXJlIHRoZSBkYXRhIG9yaWdpbmF0ZWQsIHdoZXRoZXIgZnJvbSBpbnRlcm5hbCBzeXN0ZW1zLCBleHRlcm5hbCByZXBvc2l0b3JpZXMsIG9yIGV4cGVyaW1lbnRhbCBjb2xsZWN0aW9uIG1ldGhvZHMuDQoNCioqRGF0YSBDaGFyYWN0ZXJpc3RpY3MqKjogUHJvdmlkZSBhbiBvdmVydmlldyBvZiB0aGUgZGF0YXNldCwgaW5jbHVkaW5nIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zLCB2YXJpYWJsZXMsIGFuZCB0eXBlcyBvZiBkYXRhIChlLmcuLCBjYXRlZ29yaWNhbCwgbnVtZXJpY2FsLCB0ZXh0KS4NCg0KKipFdGhpY2FsIENvbnNpZGVyYXRpb25zKio6IEhpZ2hsaWdodCBhbnkgbWVhc3VyZXMgdGFrZW4gdG8gZW5zdXJlIGV0aGljYWwgdXNlIG9mIHRoZSBkYXRhLCBzdWNoIGFzIGFub255bWl6YXRpb24gb3Igb2J0YWluaW5nIGNvbnNlbnQuDQoNCg0KIyMjIE1ldGhvZG9sb2d5DQoNClRoZSBtZXRob2RvbG9neSBzZWN0aW9uIG91dGxpbmVzIHRoZSBzdGVwcyB0YWtlbiB0byBwcm9jZXNzIGFuZCBhbmFseXplIHRoZSBkYXRhLg0KDQoqKkRhdGEgUHJlcHJvY2Vzc2luZyoqOiBEZXNjcmliZSBob3cgbWlzc2luZyB2YWx1ZXMsIG91dGxpZXJzLCBvciBpbmNvbnNpc3RlbmNpZXMgd2VyZSBoYW5kbGVkLCBhbG9uZyB3aXRoIGFueSB0cmFuc2Zvcm1hdGlvbnMgb3IgZmVhdHVyZSBlbmdpbmVlcmluZyBwZXJmb3JtZWQuDQoNCioqRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcyAoRURBKSoqOiBTdW1tYXJpemUgdGhlIGtleSBleHBsb3JhdG9yeSBzdGVwcywgc3VjaCBhcyBpZGVudGlmeWluZyBkaXN0cmlidXRpb25zLCByZWxhdGlvbnNoaXBzLCBhbmQgcGF0dGVybnMuIEluY2x1ZGUgcmVsZXZhbnQgdmlzdWFsaXphdGlvbnMgYW5kIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MuDQoNCioqRmVhdHVyZSBFbmdpbmVlcmluZyoqOiBTdW1tYXJpemUgYWxsIGZlYXR1cmUgZW5naW5lZXJpbmcgcHJvY2VkdXJlcyB0aGF0IGFyZSBqdXN0aWZpZWQgYW5kIHBlcmZvcm1lZCBpbiB0aGUgYW5hbHlzaXMuDQoNCioqTW9kZWxpbmcgYW5kIEFuYWx5c2lzKio6IFNwZWNpZnkgdGhlIHN0YXRpc3RpY2FsIG1ldGhvZHMsIG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtcywgb3IgYW5hbHl0aWNhbCBmcmFtZXdvcmtzIHVzZWQuIEluY2x1ZGUgZGV0YWlscyBhYm91dCBwYXJhbWV0ZXIgdHVuaW5nLCBmZWF0dXJlIHNlbGVjdGlvbiwgYW5kIGFueSBhc3N1bXB0aW9ucyB0ZXN0ZWQuDQoNCg0KIyMjIFJlcG9ydGluZyBSZXN1bHRzDQoNClRoZSByZXN1bHRzIHNlY3Rpb24gcHJlc2VudHMgdGhlIGZpbmRpbmdzIG9mIHRoZSBhbmFseXNpcyBpbiBhbiBvcmdhbml6ZWQgYW5kIGludGVycHJldGFibGUgbWFubmVyLg0KDQoqKkRlc2NyaXB0aXZlIFJlc3VsdHMqKjogSGlnaGxpZ2h0IGtleSBzdGF0aXN0aWNzLCB0cmVuZHMsIGFuZCByZWxhdGlvbnNoaXBzIGRpc2NvdmVyZWQgZHVyaW5nIEVEQS4NCg0KKipNb2RlbCBQZXJmb3JtYW5jZSoqOiBQcm92aWRlIG1ldHJpY3MgZXZhbHVhdGluZyB0aGUgcGVyZm9ybWFuY2Ugb2YgbW9kZWxzLCBzdWNoIGFzIGFjY3VyYWN5LCBwcmVjaXNpb24sIHJlY2FsbCwgb3IgUi1zcXVhcmVkLCBkZXBlbmRpbmcgb24gdGhlIHRhc2suDQoNCioqVmlzdWFsaXphdGlvbnMqKjogSW5jbHVkZSBjaGFydHMsIGdyYXBocywgb3IgdGFibGVzIHRoYXQgZWZmZWN0aXZlbHkgY29tbXVuaWNhdGUgZmluZGluZ3MuIFVzZSBhbm5vdGF0aW9ucyBhbmQgY2FwdGlvbnMgZm9yIGNsYXJpdHkuDQoNCg0KDQojIyMgRGlzY3Vzc2lvbiBhbmQgUmVjb21tZW5kYXRpb25zDQoNClRoZSBkaXNjdXNzaW9uIGludGVycHJldHMgdGhlIHJlc3VsdHMgYW5kIGNvbm5lY3RzIHRoZW0gdG8gdGhlIG9yaWdpbmFsIG9iamVjdGl2ZXMuDQoNCioqSW50ZXJwcmV0YXRpb24gb2YgUmVzdWx0cyoqOiBFeHBsYWluIHdoYXQgdGhlIGZpbmRpbmdzIG1lYW4gaW4gdGhlIGNvbnRleHQgb2YgdGhlIHByb2JsZW0uIERpc2N1c3Mgd2hldGhlciB0aGUgcmVzdWx0cyBhbnN3ZXJlZCB0aGUgcmVzZWFyY2ggcXVlc3Rpb25zIG9yIGh5cG90aGVzZXMuDQoNCioqQ29tcGFyaXNvbiB3aXRoIFByaW9yIFdvcmsqKjogSWYgYXBwbGljYWJsZSwgY29tcGFyZSB0aGUgZmluZGluZ3MgdG8gcHJldmlvdXMgc3R1ZGllcyBvciBhbmFseXNlcyB0byBoaWdobGlnaHQgc2ltaWxhcml0aWVzLCBkaWZmZXJlbmNlcywgb3IgaW1wcm92ZW1lbnRzLg0KDQoqKkxpbWl0YXRpb25zKio6IEFja25vd2xlZGdlIGFueSBsaW1pdGF0aW9ucyBpbiB0aGUgZGF0YSwgbWV0aG9kcywgb3IgZ2VuZXJhbGl6YWJpbGl0eSBvZiB0aGUgcmVzdWx0cy4gRm9yIGV4YW1wbGUsIGRpc2N1c3MgcG90ZW50aWFsIGJpYXNlcyBvciBhc3N1bXB0aW9ucyB0aGF0IG1heSBoYXZlIGluZmx1ZW5jZWQgdGhlIGFuYWx5c2lzLg0KDQoNCioqUmVjb21tZW5kYXRpb25zKio6IE9mZmVyIHN1Z2dlc3Rpb25zIGZvciBkZWNpc2lvbi1tYWtlcnMgYmFzZWQgb24gdGhlIHJlc3VsdHMsIHN1Y2ggYXMgY2hhbmdlcyB0byBwb2xpY2llcywgc3RyYXRlZ2llcywgb3IgZnVydGhlciByZXNlYXJjaC4NCg0KKipDb25jbHVzaW9ucyoqOiBSZWNhcCB0aGUga2V5IHBvaW50cyBvZiB0aGUgcmVwb3J0LCBlbXBoYXNpemluZyB0aGUgcHJvYmxlbSwgbWFqb3IgZmluZGluZ3MsIGFuZCB0aGVpciBpbXBsaWNhdGlvbnMuDQoNCiMjIy4gUmVmZXJlbmNlcyBhbmQgQXBwZW5kaWNlcw0KDQpDaXRlIGFsbCBzb3VyY2VzIG9mIGRhdGEsIHRvb2xzLCBtZXRob2RzLCBhbmQgcHJpb3IgcmVzZWFyY2ggdXNlZCBpbiB0aGUgcmVwb3J0LiBVc2UgYSBzdGFuZGFyZCBjaXRhdGlvbiBmb3JtYXQgKGUuZy4sIEFQQSwgSUVFRSkgdG8gZW5zdXJlIHByb3BlciBhdHRyaWJ1dGlvbi4gQXBwZW5kaWNlcyBwcm92aWRlIGFkZGl0aW9uYWwgZGV0YWlscyB0aGF0IHN1cHBvcnQgdGhlIG1haW4gcmVwb3J0IGJ1dCBhcmUgbm90IGVzc2VudGlhbCB0byB0aGUgcHJpbWFyeSBuYXJyYXRpdmUuDQoNClwNCg0KSW4gc3VtbWFyeSwgYSBzdGF0aXN0aWNzIGFuZCBkYXRhIHNjaWVuY2UgcmVwb3J0IGlzIG1vcmUgdGhhbiBqdXN0IGEgY29sbGVjdGlvbiBvZiBudW1iZXJzIGFuZCBjaGFydHM7IGl0IGlzIGEgc3RydWN0dXJlZCBuYXJyYXRpdmUgdGhhdCBndWlkZXMgcmVhZGVycyB0aHJvdWdoIHRoZSBhbmFseXNpcyBwcm9jZXNzIGFuZCBpdHMgZmluZGluZ3MuIEJ5IGFkaGVyaW5nIHRvIGEgY2xlYXIgc3RydWN0dXJl4oCUaW5jbHVkaW5nIGFuIGFic3RyYWN0LCBpbnRyb2R1Y3Rpb24sIGRhdGEgZGVzY3JpcHRpb24sIG1ldGhvZG9sb2d5LCByZXN1bHRzLCBkaXNjdXNzaW9uLCByZWNvbW1lbmRhdGlvbnMsIGFuZCBhcHBlbmRpY2Vz4oCUYW5hbHlzdHMgY2FuIGVmZmVjdGl2ZWx5IGNvbW11bmljYXRlIGNvbXBsZXggaWRlYXMuIFRoaXMgc3RydWN0dXJlZCBhcHByb2FjaCBlbnN1cmVzIHRoYXQgdGhlIHJlcG9ydCBpcyBjb21wcmVoZW5zaXZlLCB0cmFuc3BhcmVudCwgYW5kIGFjY2Vzc2libGUgdG8gYSBkaXZlcnNlIGF1ZGllbmNlLCB1bHRpbWF0ZWx5IGVuYWJsaW5nIGRhdGEtZHJpdmVuIGRlY2lzaW9uLW1ha2luZy4NCg0KDQoNCiMjICBSZXBvcnRpbmcgRm9ybWF0dGluZyBHdWlkZWxpbmVzDQoNCkluIHRoZSBmaWVsZCBvZiBzdGF0aXN0aWNzIGFuZCBkYXRhIHNjaWVuY2UsIGhvdyBpbmZvcm1hdGlvbiBpcyBwcmVzZW50ZWQgY2FuIGJlIGFzIGltcG9ydGFudCBhcyB0aGUgYW5hbHlzaXMgaXRzZWxmLiBQcm9wZXIgZm9ybWF0dGluZyBlbnN1cmVzIHRoYXQgcmVwb3J0cyBhcmUgY2xlYXIsIG9yZ2FuaXplZCwgYW5kIHByb2Zlc3Npb25hbCwgbWFraW5nIHRoZW0gYWNjZXNzaWJsZSB0byBkaXZlcnNlIGF1ZGllbmNlcy4gRWZmZWN0aXZlIGZvcm1hdHRpbmcgZW5oYW5jZXMgcmVhZGFiaWxpdHksIGZhY2lsaXRhdGVzIHVuZGVyc3RhbmRpbmcsIGFuZCBlbnN1cmVzIHRoYXQga2V5IGZpbmRpbmdzIGFyZSBub3QgbG9zdCBpbiBhIHNlYSBvZiBkYXRhIG9yIHRlY2huaWNhbCBqYXJnb24uIFRoaXMgc3Vic2VjdGlvbiBvdXRsaW5lcyB0aGUgZXNzZW50aWFsIGZvcm1hdHRpbmcgZ3VpZGVsaW5lcyBmb3Igc3RhdGlzdGljcyBhbmQgZGF0YSBzY2llbmNlIHJlcG9ydGluZywgY292ZXJpbmcgc3RydWN0dXJhbCBvcmdhbml6YXRpb24sIHZpc3VhbCBhaWRzLCBhbmQgc3R5bGlzdGljIGVsZW1lbnRzLg0KDQoqKjEuIFN0cnVjdHVyYWwgT3JnYW5pemF0aW9uKioNCg0KQSB3ZWxsLXN0cnVjdHVyZWQgcmVwb3J0IGZvbGxvd3MgYSBsb2dpY2FsIGZsb3csIGd1aWRpbmcgcmVhZGVycyBmcm9tIHByb2JsZW0gZGVmaW5pdGlvbiB0byBhY3Rpb25hYmxlIGluc2lnaHRzLg0KDQoqICoqU2VjdGlvbnMgYW5kIFN1YnNlY3Rpb25zKio6IFVzZSBoZWFkaW5ncyBhbmQgc3ViaGVhZGluZ3MgdG8gb3JnYW5pemUgY29udGVudCBpbnRvIGRpc3RpbmN0IHNlY3Rpb25zLCBzdWNoIGFzIEludHJvZHVjdGlvbiwgRGF0YSBEZXNjcmlwdGlvbiwgTWV0aG9kb2xvZ3ksIFJlc3VsdHMsIGFuZCBDb25jbHVzaW9ucy4gTnVtYmVyIHNlY3Rpb25zIGZvciBlYXN5IHJlZmVyZW5jZSAoZS5nLiwgMS4wLCAxLjEsIDIuMCkuDQoNCiogKipUYWJsZSBvZiBDb250ZW50cyoqOiBGb3IgbG9uZ2VyIHJlcG9ydHMsIGluY2x1ZGUgYSB0YWJsZSBvZiBjb250ZW50cyB0byBwcm92aWRlIGFuIG92ZXJ2aWV3IGFuZCBlbmFibGUgcXVpY2sgbmF2aWdhdGlvbi4NCg0KKiAqKkNvbnNpc3RlbmN5Kio6IEVuc3VyZSBjb25zaXN0ZW50IHBsYWNlbWVudCBhbmQgZm9ybWF0dGluZyBvZiB0aXRsZXMsIHN1YnRpdGxlcywgYW5kIHNlY3Rpb24gYnJlYWtzIHRocm91Z2hvdXQgdGhlIGRvY3VtZW50Lg0KDQoNCioqMi4gVmlzdWFsIEFpZHMgYW5kIERhdGEgUmVwcmVzZW50YXRpb24qKg0KDQpWaXN1YWwgcmVwcmVzZW50YXRpb24gaXMgYSBjb3JuZXJzdG9uZSBvZiBlZmZlY3RpdmUgY29tbXVuaWNhdGlvbiBpbiBzdGF0aXN0aWNzIGFuZCBkYXRhIHNjaWVuY2UuDQoNCiogKipUYWJsZXMqKjogVXNlIHRhYmxlcyB0byBzdW1tYXJpemUgbnVtZXJpY2FsIGRhdGEsIG1ha2luZyBpdCBlYXN5IGZvciByZWFkZXJzIHRvIGNvbXBhcmUgdmFsdWVzLiBFbnN1cmUgdGFibGVzIGhhdmUgY2xlYXIgaGVhZGluZ3MgYW5kIGFwcHJvcHJpYXRlIGFsaWdubWVudCAoZS5nLiwgcmlnaHQtYWxpZ24gZm9yIG51bWJlcnMsIGxlZnQtYWxpZ24gZm9yIHRleHQpLg0KDQoqICoqQ2hhcnRzIGFuZCBHcmFwaHMqKjogSW5jbHVkZSBjaGFydHMgc3VjaCBhcyBoaXN0b2dyYW1zLCBzY2F0dGVyIHBsb3RzLCBhbmQgYmFyIGdyYXBocyB0byB2aXN1YWxpemUgdHJlbmRzLCBkaXN0cmlidXRpb25zLCBhbmQgcmVsYXRpb25zaGlwcy4gQ2hvb3NlIGNoYXJ0IHR5cGVzIHRoYXQgYmVzdCBjb252ZXkgdGhlIGludGVuZGVkIG1lc3NhZ2UgYW5kIGF2b2lkIGNsdXR0ZXJlZCBvciBvdmVybHkgY29tcGxleCB2aXN1YWxzLg0KDQoqICoqTGFiZWxzIGFuZCBDYXB0aW9ucyoqOiBMYWJlbCBhbGwgZmlndXJlcyBhbmQgdGFibGVzIGNsZWFybHksIGFuZCBwcm92aWRlIGRlc2NyaXB0aXZlIGNhcHRpb25zIHRoYXQgZXhwbGFpbiB0aGVpciByZWxldmFuY2UgdG8gdGhlIGFuYWx5c2lzLg0KDQoqICoqQ29sb3IgYW5kIEFjY2Vzc2liaWxpdHkqKjogVXNlIGNvbG9ycyBzcGFyaW5nbHkgYW5kIGVuc3VyZSBhY2Nlc3NpYmlsaXR5IGJ5IHNlbGVjdGluZyBjb2xvcmJsaW5kLWZyaWVuZGx5IHBhbGV0dGVzIGFuZCBwYXR0ZXJucy4NCg0KDQoqKjMuIFR5cG9ncmFwaHkqKg0KDQpMZWdpYmxlIGFuZCBwcm9mZXNzaW9uYWwgdHlwb2dyYXBoeSBlbmhhbmNlcyByZWFkYWJpbGl0eSBhbmQgbWFpbnRhaW5zIGF1ZGllbmNlIGVuZ2FnZW1lbnQuDQoNCiogKipGb250IFN0eWxlIGFuZCBTaXplKio6IFVzZSBzaW1wbGUsIHByb2Zlc3Npb25hbCBmb250cyBzdWNoIGFzIFRpbWVzIE5ldyBSb21hbiwgQXJpYWwsIG9yIENhbGlicmksIHdpdGggYSBzdGFuZGFyZCBzaXplIChlLmcuLCAxMeKAkzEyIHB0IGZvciBib2R5IHRleHQsIDE04oCTMTYgcHQgZm9yIGhlYWRpbmdzKS4NCg0KKiAqKlNwYWNpbmcqKjogQXBwbHkgYXBwcm9wcmlhdGUgbGluZSBzcGFjaW5nICgxLjE1IG9yIDEuNSkgYW5kIG1hcmdpbnMgKGUuZy4sIDEgaW5jaCkgdG8gbWFrZSB0aGUgdGV4dCBlYXN5IHRvIHJlYWQgYW5kIGF2b2lkIG92ZXJjcm93ZGluZy4NCg0KKiAqKkJvbGQgYW5kIEl0YWxpY3MqKjogVXNlIGJvbGQgZm9yIHNlY3Rpb24gaGVhZGluZ3MgYW5kIGl0YWxpY3MgZm9yIGVtcGhhc2lzIG9yIHJlZmVyZW5jaW5nIHRlY2huaWNhbCB0ZXJtcywgYnV0IGF2b2lkIGV4Y2Vzc2l2ZSB1c2UuDQoNCg0KKio0LiBXcml0aW5nIFN0eWxlKioNCg0KQ2xhcml0eSBhbmQgY29uY2lzZW5lc3MgYXJlIHZpdGFsIGZvciBzdGF0aXN0aWNhbCBhbmQgZGF0YSBzY2llbmNlIHJlcG9ydHMuDQoNCiogKipUZWNobmljYWwgTGFuZ3VhZ2UqKjogVXNlIHByZWNpc2UgbGFuZ3VhZ2UgYXBwcm9wcmlhdGUgZm9yIHRoZSB0YXJnZXQgYXVkaWVuY2UuIEZvciBub24tdGVjaG5pY2FsIHJlYWRlcnMsIGV4cGxhaW4gamFyZ29uIGFuZCB0ZWNobmljYWwgdGVybXMgaW4gYSBnbG9zc2FyeSBvciBmb290bm90ZXMuDQoNCiogKipBY3RpdmUgVm9pY2UqKjogV3JpdGUgaW4gYW4gYWN0aXZlIHZvaWNlIHRvIG1ha2Ugc3RhdGVtZW50cyBtb3JlIGRpcmVjdCBhbmQgZW5nYWdpbmcgKGUuZy4sIOKAnFdlIGFuYWx5emVkIHRoZSBkYXRhLOKAnSBpbnN0ZWFkIG9mIOKAnFRoZSBkYXRhIHdhcyBhbmFseXplZOKAnSkuDQoNCiogKipQYXJhZ3JhcGggTGVuZ3RoKio6IEtlZXAgcGFyYWdyYXBocyBjb25jaXNlLCBmb2N1c2luZyBvbiBvbmUgbWFpbiBpZGVhIGF0IGEgdGltZS4gVXNlIGJ1bGxldCBwb2ludHMgb3IgbnVtYmVyZWQgbGlzdHMgdG8gc3VtbWFyaXplIGtleSBwb2ludHMuDQoNCiogKipPcGVuaW5nIFBhcmFncmFwaHMqKjogDQoNCiMjIFdyaXRpbmcgQmVzdCBQcmFjdGljZXMNCg0KRWZmZWN0aXZlIGNvbW11bmljYXRpb24gaXMgaW50ZWdyYWwgdG8gdGhlIHN1Y2Nlc3Mgb2Ygc3RhdGlzdGljcyBhbmQgZGF0YSBzY2llbmNlIHByb2plY3RzLiBBIHdlbGwtY3JhZnRlZCByZXBvcnQgYnJpZGdlcyB0aGUgZ2FwIGJldHdlZW4gY29tcGxleCBhbmFseXNlcyBhbmQgYWN0aW9uYWJsZSBpbnNpZ2h0cywgZW5hYmxpbmcgc3Rha2Vob2xkZXJzIHRvIG1ha2UgaW5mb3JtZWQgZGVjaXNpb25zLiBCZXN0IHByYWN0aWNlcyBpbiByZXBvcnQgd3JpdGluZyBmb2N1cyBvbiBjbGFyaXR5LCB0cmFuc3BhcmVuY3ksIGFjY3VyYWN5LCBhbmQgYWNjZXNzaWJpbGl0eS4gDQoNCioqMS4gQmVnaW4gd2l0aCBhIENsZWFyIFN0cnVjdHVyZSoqDQoNClRoZSBmb3VuZGF0aW9uIG9mIGEgZ3JlYXQgcmVwb3J0IGxpZXMgaW4gaXRzIHN0cnVjdHVyZS4gT3JnYW5pemluZyB0aGUgY29udGVudCBpbiBhIGxvZ2ljYWwgYW5kIHByZWRpY3RhYmxlIGZvcm1hdCBoZWxwcyByZWFkZXJzIG5hdmlnYXRlIHRoZSBkb2N1bWVudCBlZmZvcnRsZXNzbHkuDQoNCiogKipUaXRsZSBhbmQgQWJzdHJhY3QqKjogU3RhcnQgd2l0aCBhIGRlc2NyaXB0aXZlIHRpdGxlIGFuZCBhIGNvbmNpc2UgYWJzdHJhY3Qgc3VtbWFyaXppbmcgdGhlIHByb2JsZW0sIG1ldGhvZG9sb2d5LCBrZXkgZmluZGluZ3MsIGFuZCBjb25jbHVzaW9ucy4NCg0KKiAqKlNlY3Rpb24gSGVhZGluZ3MqKjogVXNlIHdlbGwtZGVmaW5lZCBzZWN0aW9ucyBzdWNoIGFzIEludHJvZHVjdGlvbiwgRGF0YSBEZXNjcmlwdGlvbiwgTWV0aG9kb2xvZ3ksIFJlc3VsdHMsIERpc2N1c3Npb24sIGFuZCBSZWNvbW1lbmRhdGlvbnMuIFRoZXNlIHNlY3Rpb25zIGNyZWF0ZSBhIHJvYWRtYXAgZm9yIHRoZSByZXBvcnQuDQoNCiogKipBcHBlbmRpY2VzKio6IEluY2x1ZGUgc3VwcGxlbWVudGFyeSBtYXRlcmlhbHMgc3VjaCBhcyBkZXRhaWxlZCB0YWJsZXMsIGNoYXJ0cywgb3IgY29kZSBpbiBhcHBlbmRpY2VzIHRvIGF2b2lkIGNsdXR0ZXJpbmcgdGhlIG1haW4gdGV4dC4NCg0KDQoqKjIuIEtub3cgWW91ciBBdWRpZW5jZSoqDQoNClVuZGVyc3RhbmRpbmcgdGhlIHRhcmdldCBhdWRpZW5jZSBpcyBjcnVjaWFsIGZvciBlZmZlY3RpdmUgY29tbXVuaWNhdGlvbi4NCg0KKiAqKlRhaWxvciBDb250ZW50Kio6IEFkanVzdCB0aGUgbGV2ZWwgb2YgZGV0YWlsIGFuZCB0ZWNobmljYWwgY29tcGxleGl0eSB0byBzdWl0IHRoZSBhdWRpZW5jZS4gRm9yIHRlY2huaWNhbCByZWFkZXJzLCBpbmNsdWRlIGluLWRlcHRoIGV4cGxhbmF0aW9ucywgYWxnb3JpdGhtcywgYW5kIGNvZGUuIEZvciBub24tdGVjaG5pY2FsIHN0YWtlaG9sZGVycywgZm9jdXMgb24ga2V5IGluc2lnaHRzIGFuZCBidXNpbmVzcyBpbXBsaWNhdGlvbnMuDQoNCiogKipEZWZpbmUgVGVybXMqKjogQXZvaWQgYXNzdW1pbmcgZmFtaWxpYXJpdHkgd2l0aCBqYXJnb24gb3IgdGVjaG5pY2FsIHRlcm1zLiBQcm92aWRlIGNsZWFyIGRlZmluaXRpb25zIG9yIGluY2x1ZGUgYSBnbG9zc2FyeSBmb3IgdW5mYW1pbGlhciBjb25jZXB0cy4NCg0KKiozLiBQcmlvcml0aXplIENsYXJpdHkgYW5kIFNpbXBsaWNpdHkqKg0KDQpBIHJlcG9ydCBzaG91bGQgY29tbXVuaWNhdGUgY29tcGxleCBpZGVhcyBpbiBhIHdheSB0aGF0IGlzIGVhc3kgdG8gdW5kZXJzdGFuZC4NCg0KKiAqKkNvbmNpc2UgV3JpdGluZyoqOiBBdm9pZCB2ZXJib3NpdHkgYnkgcHJlc2VudGluZyBpZGVhcyBzdWNjaW5jdGx5LiBVc2UgYnVsbGV0IHBvaW50cyBhbmQgbnVtYmVyZWQgbGlzdHMgdG8gc3VtbWFyaXplIGtleSBwb2ludHMuDQoNCiogKipBY3RpdmUgVm9pY2UqKjogVXNlIGFjdGl2ZSB2b2ljZSBmb3IgZGlyZWN0IGFuZCBlbmdhZ2luZyBzZW50ZW5jZXMgKGUuZy4sICJXZSBhbmFseXplZCB0aGUgZGF0YSwiIGluc3RlYWQgb2YgIlRoZSBkYXRhIHdhcyBhbmFseXplZCIpLg0KDQoqICoqTG9naWNhbCBGbG93Kio6IFByZXNlbnQgdGhlIGNvbnRlbnQgaW4gYSBsb2dpY2FsIHNlcXVlbmNlLCBsZWFkaW5nIHJlYWRlcnMgc3RlcC1ieS1zdGVwIHRocm91Z2ggdGhlIGFuYWx5c2lzLg0KDQoNCioqNC4gRW5zdXJlIFRyYW5zcGFyZW5jeSBhbmQgUmVwcm9kdWNpYmlsaXR5KioNCg0KVHJhbnNwYXJlbmN5IGJ1aWxkcyB0cnVzdCBpbiB0aGUgZmluZGluZ3MsIHdoaWxlIHJlcHJvZHVjaWJpbGl0eSBhbGxvd3Mgb3RoZXJzIHRvIHZhbGlkYXRlIHRoZSB3b3JrLg0KDQoqICoqRGF0YSBEZXNjcmlwdGlvbioqOiBQcm92aWRlIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHRoZSBkYXRhc2V0LCBpbmNsdWRpbmcgc291cmNlcywgY29sbGVjdGlvbiBtZXRob2RzLCBhbmQgY2hhcmFjdGVyaXN0aWNzLg0KDQoqICoqTWV0aG9kb2xvZ3kqKjogQ2xlYXJseSBleHBsYWluIHRoZSBzdGVwcyB0YWtlbiBpbiBwcmVwcm9jZXNzaW5nLCBleHBsb3JhdG9yeSBhbmFseXNpcywgbW9kZWxpbmcsIGFuZCB2YWxpZGF0aW9uLiBNZW50aW9uIGFueSBhc3N1bXB0aW9ucyBvciBsaW1pdGF0aW9ucyBvZiB0aGUgbWV0aG9kcyB1c2VkLg0KDQoqICoqQ29kZSBhbmQgVG9vbHMqKjogU2hhcmUgdGhlIHByb2dyYW1taW5nIHRvb2xzLCBsaWJyYXJpZXMsIGFuZCBjb2RlIHNuaXBwZXRzIHVzZWQgaW4gdGhlIGFuYWx5c2lzLCBhZGhlcmluZyB0byBhbnkgYXBwbGljYWJsZSBkYXRhLXNoYXJpbmcgYW5kIHByaXZhY3kgY29uc3RyYWludHMuDQoNCg0KKio1LiBFbXBoYXNpemUgVmlzdWFsIENvbW11bmljYXRpb24qKg0KDQpWaXN1YWwgZWxlbWVudHMgZW5oYW5jZSB1bmRlcnN0YW5kaW5nIGFuZCBtYWtlIHRoZSByZXBvcnQgbW9yZSBlbmdhZ2luZy4NCg0KKiAqKkRhdGEgVmlzdWFsaXphdGlvbnMqKjogVXNlIGNoYXJ0cywgZ3JhcGhzLCBhbmQgcGxvdHMgdG8gcmVwcmVzZW50IGRhdGEgYW5kIGZpbmRpbmdzLiBFbnN1cmUgZWFjaCB2aXN1YWxpemF0aW9uIGlzIGxhYmVsZWQsIGNhcHRpb25lZCwgYW5kIGVhc3kgdG8gaW50ZXJwcmV0Lg0KDQoqICoqQ2xhcml0eSBpbiBEZXNpZ24qKjogQXZvaWQgb3ZlcmNyb3dkaW5nIHZpc3VhbHMgd2l0aCBleGNlc3NpdmUgaW5mb3JtYXRpb24uIFVzZSBjbGVhbiwgbWluaW1hbGlzdCBkZXNpZ25zIHdpdGggY29sb3Igc2NoZW1lcyBhY2Nlc3NpYmxlIHRvIGNvbG9yYmxpbmQgcmVhZGVycy4NCg0KKiAqKkNvbXBhcmF0aXZlIEFuYWx5c2lzKio6IFdoZW4gcHJlc2VudGluZyBtdWx0aXBsZSBtb2RlbHMgb3Igc2NlbmFyaW9zLCB1c2Ugc2lkZS1ieS1zaWRlIHZpc3VhbCBjb21wYXJpc29ucyB0byBoaWdobGlnaHQgZGlmZmVyZW5jZXMuDQoNCg0KKio2LiBQcmVzZW50IFJlc3VsdHMgT2JqZWN0aXZlbHkqKg0KDQpPYmplY3Rpdml0eSBpbiBwcmVzZW50aW5nIHJlc3VsdHMgaXMgY3JpdGljYWwgZm9yIGNyZWRpYmlsaXR5Lg0KDQoqICoqUmVwb3J0IEFsbCBSZXN1bHRzKio6IEluY2x1ZGUgYm90aCBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgZmluZGluZ3MuIEFja25vd2xlZGdlIGFueSBpbmNvbnNpc3RlbmNpZXMgb3IgdW5leHBlY3RlZCBvdXRjb21lcy4NCg0KKiAqKlBlcmZvcm1hbmNlIE1ldHJpY3MqKjogQ2xlYXJseSBleHBsYWluIHRoZSBtZXRyaWNzIHVzZWQgdG8gZXZhbHVhdGUgbW9kZWxzIChlLmcuLCBhY2N1cmFjeSwgcHJlY2lzaW9uLCByZWNhbGwsIEYxIHNjb3JlLCBST0MgYW5kIEFVQywgZXRjLikgYW5kIHdoeSB0aGV5IHdlcmUgY2hvc2VuLg0KDQoqICoqU3RhdGlzdGljYWwgU2lnbmlmaWNhbmNlKio6IEhpZ2hsaWdodCBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2UsIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLCBhbmQgZWZmZWN0IHNpemVzIHRvIHByb3ZpZGUgY29udGV4dCBmb3IgdGhlIHJlc3VsdHMuDQoNCg0KKio3LiBBZGRyZXNzIEV0aGljYWwgQ29uc2lkZXJhdGlvbnMqKg0KDQpFdGhpY3MgYXJlIGFuIGludGVncmFsIHBhcnQgb2Ygc3RhdGlzdGljcyBhbmQgZGF0YSBzY2llbmNlIHJlcG9ydGluZy4NCg0KKiAqKkJpYXMgYW5kIEZhaXJuZXNzKio6IERpc2N1c3MgcG90ZW50aWFsIGJpYXNlcyBpbiB0aGUgZGF0YSBvciBtZXRob2RzIGFuZCB0aGVpciBpbXBsaWNhdGlvbnMgZm9yIHRoZSByZXN1bHRzLg0KDQoqICoqUHJpdmFjeSBhbmQgQ29uc2VudCoqOiBFeHBsYWluIGhvdyBwcml2YWN5IGNvbmNlcm5zIHdlcmUgYWRkcmVzc2VkLCBpbmNsdWRpbmcgbWVhc3VyZXMgZm9yIGFub255bWl6YXRpb24gb3Igc2VjdXJlIGRhdGEgaGFuZGxpbmcuDQoNCiogKipJbXBhY3QgQW5hbHlzaXMqKjogQ29uc2lkZXIgdGhlIGJyb2FkZXIgaW1wbGljYXRpb25zIG9mIHRoZSBmaW5kaW5ncywgZXNwZWNpYWxseSBpZiB0aGV5IGluZmx1ZW5jZSBwb2xpY3kgb3IgZGVjaXNpb24tbWFraW5nLg0KDQoNCioqOC4gRm9jdXMgb24gQWN0aW9uYWJsZSBJbnNpZ2h0cyoqDQoNCkEga2V5IGdvYWwgb2YgZGF0YSBzY2llbmNlIHJlcG9ydHMgaXMgdG8gcHJvdmlkZSBpbnNpZ2h0cyB0aGF0IHN0YWtlaG9sZGVycyBjYW4gYWN0IHVwb24uDQoNCiogKipCdXNpbmVzcyBSZWxldmFuY2UqKjogUmVsYXRlIGZpbmRpbmdzIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHByb2JsZW0gb3Igb2JqZWN0aXZlcy4NCg0KKiAqKlJlY29tbWVuZGF0aW9ucyoqOiBPZmZlciBjbGVhciwgZXZpZGVuY2UtYmFzZWQgcmVjb21tZW5kYXRpb25zIGZvciBuZXh0IHN0ZXBzIG9yIGRlY2lzaW9ucy4NCg0KKiAqKkZ1dHVyZSBXb3JrKio6IFN1Z2dlc3QgYXJlYXMgZm9yIGZ1cnRoZXIgcmVzZWFyY2ggb3IgcG90ZW50aWFsIGltcHJvdmVtZW50cyBpbiBtZXRob2RvbG9neS4NCg0KDQpcDQoNCiMgV2ViLWJhc2VkIEVmZmVjdGl2ZSBQcmVzZW50YXRpb24NCg0KSW4gYW4gaW5jcmVhc2luZ2x5IGRpZ2l0YWwgd29ybGQsIHdlYi1iYXNlZCBwcmVzZW50YXRpb25zIGhhdmUgYmVjb21lIGEgY3JpdGljYWwgdG9vbCBmb3IgY29tbXVuaWNhdGlvbiwgZWR1Y2F0aW9uLCBhbmQgYnVzaW5lc3MuIFVubGlrZSB0cmFkaXRpb25hbCBmb3JtYXRzLCB3ZWItYmFzZWQgcHJlc2VudGF0aW9ucyBtdXN0IGNhdGVyIHRvIHRoZSBkeW5hbWljcyBvZiBvbmxpbmUgcGxhdGZvcm1zLCBlbnN1cmluZyB0aGV5IGVuZ2FnZSBhdWRpZW5jZXMgYW5kIGNvbnZleSBtZXNzYWdlcyBlZmZlY3RpdmVseSBpbiBhIHZpcnR1YWwgZW52aXJvbm1lbnQuIFRoaXMgZXNzYXkgb3V0bGluZXMga2V5IHByaW5jaXBsZXMgYW5kIHN0cmF0ZWdpZXMgZm9yIGRlc2lnbmluZyBlZmZlY3RpdmUgd2ViLWJhc2VkIHByZXNlbnRhdGlvbnMsIGZvY3VzaW5nIG9uIGNvbnRlbnQgc3RydWN0dXJlLCB2aXN1YWwgYXBwZWFsLCBpbnRlcmFjdGl2aXR5LCBhbmQgYWNjZXNzaWJpbGl0eS4NCg0KIyMgQ2xlYXIgYW5kIExvZ2ljYWwgU3RydWN0dXJlDQoNCkFuIGVmZmVjdGl2ZSB3ZWItYmFzZWQgcHJlc2VudGF0aW9uIGJlZ2lucyB3aXRoIGEgd2VsbC1vcmdhbml6ZWQgc3RydWN0dXJlIHRvIGd1aWRlIHRoZSBhdWRpZW5jZSB0aHJvdWdoIHRoZSBjb250ZW50IHNlYW1sZXNzbHkuDQoNCioqRGVmaW5lIE9iamVjdGl2ZXMqKjogU3RhcnQgYnkgaWRlbnRpZnlpbmcgdGhlIHB1cnBvc2Ugb2YgdGhlIHByZXNlbnRhdGlvbiBhbmQgdGhlIGtleSB0YWtlYXdheXMgZm9yIHRoZSBhdWRpZW5jZS4gVGhpcyBoZWxwcyBpbiBhbGlnbmluZyB0aGUgY29udGVudCB3aXRoIHRoZSBnb2Fscy4NCg0KKipPdXRsaW5lIHRoZSBGbG93Kio6IEFycmFuZ2Ugc2xpZGVzIGluIGEgbG9naWNhbCBzZXF1ZW5jZeKAlGJlZ2lubmluZyB3aXRoIGFuIGludHJvZHVjdGlvbiwgZm9sbG93ZWQgYnkgdGhlIG1haW4gY29udGVudCwgYW5kIGVuZGluZyB3aXRoIGEgc3Ryb25nIGNvbmNsdXNpb24gb3IgY2FsbCB0byBhY3Rpb24uDQoNCioqQ2h1bmsgSW5mb3JtYXRpb24qKjogQnJlYWsgY29tcGxleCBpbmZvcm1hdGlvbiBpbnRvIHNtYWxsZXIsIGRpZ2VzdGlibGUgc2VjdGlvbnMgdG8gbWFpbnRhaW4gdGhlIGF1ZGllbmNl4oCZcyBmb2N1cyBhbmQgYXZvaWQgY29nbml0aXZlIG92ZXJsb2FkLg0KDQpGb3IgaW5zdGFuY2UsIGEgcHJlc2VudGF0aW9uIG9uIGRhdGEgYW5hbHl0aWNzIG1pZ2h0IHN0YXJ0IHdpdGggYW4gb3ZlcnZpZXcgb2YgdGhlIGZpZWxkLCBwcm9jZWVkIHRvIG1ldGhvZHMgYW5kIHRvb2xzLCBhbmQgY29uY2x1ZGUgd2l0aCByZWFsLXdvcmxkIGFwcGxpY2F0aW9ucy4NCg0KDQojIyBWaXN1YWwgRGVzaWduIGFuZCBBZXN0aGV0aWNzDQoNClRoZSB2aXN1YWwgZGVzaWduIGFuZCBhZXN0aGV0aWNzIG9mIHByZXNlbnRhdGlvbiBzbGlkZXMgcGxheSBhIGNyaXRpY2FsIHJvbGUgaW4gY2FwdHVyaW5nIGF0dGVudGlvbiwgY29udmV5aW5nIGluZm9ybWF0aW9uIGVmZmVjdGl2ZWx5LCBhbmQgbWFpbnRhaW5pbmcgYXVkaWVuY2UgZW5nYWdlbWVudC4gR29vZCBkZXNpZ24gZW5zdXJlcyB0aGF0IHRoZSBtZXNzYWdlIGlzIG5vdCBvbmx5IGNsZWFyIGJ1dCBhbHNvIG1lbW9yYWJsZS4gVGhpcyBzdWJzZWN0aW9uIGV4cGxvcmVzIGtleSBwcmluY2lwbGVzIGFuZCBzdHJhdGVnaWVzIGZvciBhY2hpZXZpbmcgZWZmZWN0aXZlIHZpc3VhbCBkZXNpZ24gYW5kIGFlc3RoZXRpY3MgaW4gcHJlc2VudGF0aW9uIHNsaWRlcywgZW1waGFzaXppbmcgY2xhcml0eSwgY29uc2lzdGVuY3ksIGFuZCBhdWRpZW5jZS1jZW50ZXJlZCBkZXNpZ24uDQoNCioqMS4gVGhlIFJvbGUgb2YgVmlzdWFsIERlc2lnbiBpbiBQcmVzZW50YXRpb25zKioNCg0KVmlzdWFsIGRlc2lnbiBpcyBub3QganVzdCBhYm91dCBtYWtpbmcgc2xpZGVzIGxvb2sgYXBwZWFsaW5n4oCUaXQgc2VydmVzIHRvIGVuaGFuY2UgY29tbXVuaWNhdGlvbiBhbmQgdW5kZXJzdGFuZGluZy4NCg0KKiAqKkF0dHJhY3RpbmcgQXR0ZW50aW9uKio6IFdlbGwtZGVzaWduZWQgc2xpZGVzIGNhbiBpbW1lZGlhdGVseSBjYXB0dXJlIHRoZSBhdWRpZW5jZeKAmXMgaW50ZXJlc3QgYW5kIHNldCBhIHBvc2l0aXZlIHRvbmUgZm9yIHRoZSBwcmVzZW50YXRpb24uDQoNCiogKipJbXByb3ZpbmcgQ29tcHJlaGVuc2lvbioqOiBWaXN1YWwgZWxlbWVudHMgbGlrZSBjaGFydHMsIGRpYWdyYW1zLCBhbmQgY29sb3ItY29kZWQgaGlnaGxpZ2h0cyBtYWtlIGNvbXBsZXggaW5mb3JtYXRpb24gZWFzaWVyIHRvIHVuZGVyc3RhbmQuDQoNCiogKipNYWludGFpbmluZyBFbmdhZ2VtZW50Kio6IEFlc3RoZXRpYyBhbmQgZHluYW1pYyBkZXNpZ24ga2VlcHMgdGhlIGF1ZGllbmNlIGZvY3VzZWQgYW5kIHByZXZlbnRzIG1vbm90b255Lg0KUmVpbmZvcmNpbmcgTWVzc2FnaW5nOiBDb25zaXN0ZW50IGFuZCB0aG91Z2h0ZnVsIGRlc2lnbiBjaG9pY2VzIHN0cmVuZ3RoZW4gdGhlIGltcGFjdCBvZiB0aGUgcHJlc2VudGVkIG1lc3NhZ2UuDQoNCkZvciBleGFtcGxlLCBhIHByZXNlbnRhdGlvbiBvbiByZW5ld2FibGUgZW5lcmd5IGJlbmVmaXRzIGZyb20gdmlzdWFsbHkgYXBwZWFsaW5nIGdyYXBocyBhbmQgaW1hZ2VzIG9mIHdpbmQgdHVyYmluZXMgYW5kIHNvbGFyIHBhbmVscyB0byBoaWdobGlnaHQga2V5IHBvaW50cyBlZmZlY3RpdmVseS4NCg0KKioyLiBLZXkgUHJpbmNpcGxlcyBvZiBTbGlkZSBEZXNpZ24qKg0KDQpBY2hpZXZpbmcgc3Ryb25nIHZpc3VhbCBkZXNpZ24gaW52b2x2ZXMgYWRoZXJpbmcgdG8gZnVuZGFtZW50YWwgZGVzaWduIHByaW5jaXBsZXMgdGhhdCBwcmlvcml0aXplIGNsYXJpdHkgYW5kIGNvaGVyZW5jZS4NCg0KKiAqKlNpbXBsaWNpdHkqKjogS2VlcCBzbGlkZXMgY2xlYW4gYW5kIHVuY2x1dHRlcmVkLiBGb2N1cyBvbiBvbmUgbWFpbiBpZGVhIHBlciBzbGlkZSB0byBhdm9pZCBvdmVyd2hlbG1pbmcgdGhlIGF1ZGllbmNlLg0KDQoqICoqSGllcmFyY2h5Kio6IFVzZSB2aXN1YWwgaGllcmFyY2h5IHRvIGd1aWRlIHRoZSBhdWRpZW5jZeKAmXMgYXR0ZW50aW9uLiBMYXJnZXIgZm9udHMsIGJvbGQgdGV4dCwgYW5kIGNvbnRyYXN0aW5nIGNvbG9ycyBjYW4gZW1waGFzaXplIGtleSBwb2ludHMuDQoNCiogKipCYWxhbmNlKio6IEFycmFuZ2UgZWxlbWVudHMgc3ltbWV0cmljYWxseSBvciBhc3ltbWV0cmljYWxseSB0byBjcmVhdGUgaGFybW9ueSBhbmQgYXZvaWQgYSBjbHV0dGVyZWQgYXBwZWFyYW5jZS4NCg0KKiAqKkFsaWdubWVudCoqOiBBbGlnbiB0ZXh0LCBpbWFnZXMsIGFuZCBvdGhlciBlbGVtZW50cyBmb3IgYSBwb2xpc2hlZCBhbmQgcHJvZmVzc2lvbmFsIGxvb2suIE1pc2FsaWduZWQgb2JqZWN0cyBjYW4gYXBwZWFyIHVucHJvZmVzc2lvbmFsIGFuZCBkaXN0cmFjdCBmcm9tIHRoZSBtZXNzYWdlLg0KDQoqICoqQ29udHJhc3QqKjogRW5zdXJlIHN1ZmZpY2llbnQgY29udHJhc3QgYmV0d2VlbiB0ZXh0IGFuZCBiYWNrZ3JvdW5kIGNvbG9ycyB0byBlbmhhbmNlIHJlYWRhYmlsaXR5LCBlc3BlY2lhbGx5IGluIGxvdy1saWdodCBzZXR0aW5ncy4NCg0KRm9yIGluc3RhbmNlLCB1c2luZyBhIGJvbGQsIGxhcmdlIGZvbnQgZm9yIGhlYWRpbmdzIGFuZCBzbWFsbGVyLCBsaWdodGVyIHRleHQgZm9yIHN1cHBvcnRpbmcgZGV0YWlscyBjcmVhdGVzIGEgY2xlYXIgdmlzdWFsIGhpZXJhcmNoeS4NCg0KKiozLiBFZmZlY3RpdmUgVXNlIG9mIENvbG9ycyoqDQoNCkNvbG9ycyBhcmUgYSBwb3dlcmZ1bCB0b29sIGZvciBzZXR0aW5nIHRoZSB0b25lIGFuZCBlbmhhbmNpbmcgdGhlIHJlYWRhYmlsaXR5IG9mIHNsaWRlcy4NCg0KKiAqKkNvbnNpc3RlbnQgQ29sb3IgU2NoZW1lKio6IFN0aWNrIHRvIGEgbGltaXRlZCBwYWxldHRlIG9mIDLigJM0IGNvbG9ycyB0aGF0IGFsaWduIHdpdGggdGhlIHByZXNlbnRhdGlvbuKAmXMgdGhlbWUgb3IgYnJhbmQgaWRlbnRpdHkuDQoNCiogKipQdXJwb3NlZnVsIENvbG9ycyoqOiBVc2UgY29sb3JzIHRvIGVtcGhhc2l6ZSBzcGVjaWZpYyBwb2ludHMsIHN1Y2ggYXMgcmVkIGZvciB3YXJuaW5ncyBvciBncmVlbiBmb3IgcG9zaXRpdmUgb3V0Y29tZXMuDQoNCiogKipSZWFkYWJsZSBDb21iaW5hdGlvbnMqKjogQXZvaWQgbG93LWNvbnRyYXN0IGNvbWJpbmF0aW9ucyBsaWtlIGxpZ2h0IHRleHQgb24gYSBsaWdodCBiYWNrZ3JvdW5kLiBEYXJrIHRleHQgb24gYSBsaWdodCBiYWNrZ3JvdW5kIG9yIHZpY2UgdmVyc2EgaXMgZ2VuZXJhbGx5IG1vcmUgbGVnaWJsZS4NCg0KKiAqKlBzeWNob2xvZ2ljYWwgSW1wYWN0Kio6IENvbnNpZGVyIHRoZSBlbW90aW9uYWwgYW5kIHBzeWNob2xvZ2ljYWwgYXNzb2NpYXRpb25zIG9mIGNvbG9ycy4gRm9yIGV4YW1wbGUsIGJsdWUgY29udmV5cyB0cnVzdCBhbmQgcHJvZmVzc2lvbmFsaXNtLCB3aGlsZSBvcmFuZ2Ugc3VnZ2VzdHMgZW5lcmd5IGFuZCBjcmVhdGl2aXR5Lg0KDQpGb3IgZXhhbXBsZSwgYSBoZWFsdGhjYXJlIHByZXNlbnRhdGlvbiBtaWdodCB1c2UgY2FsbWluZyBibHVlcyBhbmQgd2hpdGVzIHRvIGluc3RpbGwgdHJ1c3QgYW5kIHByb2Zlc3Npb25hbGlzbS4NCg0KDQoqKjQuIExlc3MgVGV4dCwgTW9yZSBTdG9yeXRlbGxpbmcqKg0KDQpTbGlkZXMgb3ZlcmxvYWRlZCB3aXRoIHRleHQgY2FuIGRpc2VuZ2FnZSBhdWRpZW5jZXMgYW5kIG9ic2N1cmUgdGhlIGNvcmUgbWVzc2FnZS4gSW5zdGVhZCwgZW1icmFjaW5nIHN0b3J5dGVsbGluZyB3aXRoIHZpc3VhbHMgY2FuIGNyZWF0ZSBhIG1vcmUgaW1wYWN0ZnVsIGFuZCBtZW1vcmFibGUgZXhwZXJpZW5jZS4gVGhpcyBhcHByb2FjaCB0cmFuc2Zvcm1zIHNsaWRlcyBmcm9tIHN0YXRpYyByZWFkaW5nIG1hdGVyaWFsIGludG8gYSBkeW5hbWljIHRvb2wgdGhhdCBzdXBwb3J0cyB0aGUgcHJlc2VudGVy4oCZcyBuYXJyYXRpdmUsIGVuZ2FnaW5nIHRoZSBhdWRpZW5jZSBvbiBhIGRlZXBlciBlbW90aW9uYWwgYW5kIGludGVsbGVjdHVhbCBsZXZlbC4gTWluaW1pemluZyB0ZXh0IG9uIHNsaWRlcyBmb3JjZXMgdGhlIHByZXNlbnRlciB0byBlbmdhZ2UgdGhlIGF1ZGllbmNlIGRpcmVjdGx5IGFuZCBmb2N1cyBvbiBrZXkgcG9pbnRzLg0KDQoqICoqT25lIElkZWEgUGVyIFNsaWRlKio6IExpbWl0IGVhY2ggc2xpZGUgdG8gYSBzaW5nbGUgY29uY2VwdCB0byBhdm9pZCBvdmVyd2hlbG1pbmcgdGhlIGF1ZGllbmNlLg0KDQoqICoqQnVsbGV0IFBvaW50IFJlZHVjdGlvbioqOiBSZXBsYWNlIGxvbmcgbGlzdHMgb2YgYnVsbGV0IHBvaW50cyB3aXRoIHN1Y2NpbmN0IHBocmFzZXMsIHZpc3VhbHMsIG9yIGljb25zLg0KDQoqICoqUHJlc2VudGVyLUNlbnRlcmVkIERlbGl2ZXJ5Kio6IFVzZSB0aGUgc2xpZGVzIGFzIHByb21wdHMgZm9yIHNwZWFraW5nIHJhdGhlciB0aGFuIGFzIGEgc2NyaXB0Lg0KDQoNCg0KKio1LiBJbmNvcnBvcmF0aW5nIFZpc3VhbCBFbGVtZW50cyoqDQoNClZpc3VhbCBlbGVtZW50cyBsaWtlIGltYWdlcywgaWNvbnMsIGFuZCBjaGFydHMgY2FuIGVuaGFuY2Ugc2xpZGVzIGJ5IG1ha2luZyBhYnN0cmFjdCBjb25jZXB0cyB0YW5naWJsZSBhbmQgZGF0YSBtb3JlIHJlbGF0YWJsZS4NCg0KKiAqKkhpZ2gtUXVhbGl0eSBJbWFnZXMqKjogVXNlIHNoYXJwLCByZWxldmFudCBpbWFnZXMgdGhhdCBhbGlnbiB3aXRoIHRoZSBwcmVzZW50YXRpb27igJlzIHRvcGljLiBBdm9pZCBwaXhlbGF0ZWQgb3IgZ2VuZXJpYyBzdG9jayBwaG90b3MuDQoNCiogKipJbmZvZ3JhcGhpY3MgYW5kIENoYXJ0cyoqOiBVc2Ugd2VsbC1kZXNpZ25lZCBjaGFydHMgYW5kIGluZm9ncmFwaGljcyB0byBwcmVzZW50IGRhdGEgY2xlYXJseS4gU2VsZWN0IHRoZSByaWdodCB0eXBlIG9mIGNoYXJ0IChlLmcuLCBiYXIsIGxpbmUsIHBpZSkgZm9yIHRoZSBkYXRhLg0KDQoqICoqSWNvbnMqKjogQWRkIGljb25zIHRvIGlsbHVzdHJhdGUgcG9pbnRzIGFuZCBicmVhayB1cCB0ZXh0LiBVc2UgYSBjb25zaXN0ZW50IGljb24gc3R5bGUgZm9yIHZpc3VhbCBoYXJtb255Lg0KDQoqICoqV2hpdGUgU3BhY2UqKjogQWxsb3cgZm9yIHdoaXRlIHNwYWNlIGFyb3VuZCB2aXN1YWxzIHRvIHByZXZlbnQgb3ZlcmNyb3dkaW5nIGFuZCBtYWludGFpbiBhIGNsZWFuLCBvcmdhbml6ZWQgYXBwZWFyYW5jZS4NCg0KDQpGb3IgZXhhbXBsZSwgYSBmaW5hbmNpYWwgcmVwb3J0IHByZXNlbnRhdGlvbiBjb3VsZCBpbmNsdWRlIGEgbGluZSBncmFwaCBzaG93aW5nIHRyZW5kcyBvdmVyIHRpbWUsIGFjY29tcGFuaWVkIGJ5IGljb25zIHJlcHJlc2VudGluZyBrZXkgbWlsZXN0b25lcy4NCg0KKio2LiBBbmltYXRpb25zIGFuZCBUcmFuc2l0aW9ucyoqDQoNCkFuaW1hdGlvbnMgYW5kIHRyYW5zaXRpb25zIGNhbiBlbmhhbmNlIHRoZSBmbG93IG9mIGEgcHJlc2VudGF0aW9uIGJ1dCBtdXN0IGJlIHVzZWQganVkaWNpb3VzbHkuDQoNCiogKipTdWJ0bGUgQW5pbWF0aW9ucyoqOiBVc2UgYW5pbWF0aW9ucyBzcGFyaW5nbHkgdG8gZHJhdyBhdHRlbnRpb24gdG8gaW1wb3J0YW50IGVsZW1lbnRzIHdpdGhvdXQgZGlzdHJhY3RpbmcgdGhlIGF1ZGllbmNlLg0KDQoqICoqQ29uc2lzdGVudCBUcmFuc2l0aW9ucyoqOiBBcHBseSBhIHVuaWZvcm0gdHJhbnNpdGlvbiBzdHlsZSBhY3Jvc3Mgc2xpZGVzIHRvIG1haW50YWluIHZpc3VhbCBjb250aW51aXR5Lg0KDQoqICoqQXZvaWQgT3ZlcnVzZSoqOiBFeGNlc3NpdmUgb3IgZmxhc2h5IGFuaW1hdGlvbnMgY2FuIGRldHJhY3QgZnJvbSB0aGUgbWVzc2FnZSBhbmQgYXBwZWFyIHVucHJvZmVzc2lvbmFsLg0KDQoNCkZvciBpbnN0YW5jZSwgdXNpbmcgYSBmYWRlLWluIGFuaW1hdGlvbiB0byBpbnRyb2R1Y2UgYnVsbGV0IHBvaW50cyBvbmUgYnkgb25lIGhlbHBzIG1haW50YWluIGF1ZGllbmNlIGZvY3VzIHdpdGhvdXQgYmVpbmcgZGlzdHJhY3RpbmcuDQoNCioqNy4gRGVzaWduaW5nIGZvciBBY2Nlc3NpYmlsaXR5KioNCg0KQWVzdGhldGljIGRlc2lnbiBzaG91bGQgYWxzbyBhY2NvdW50IGZvciB0aGUgZGl2ZXJzZSBuZWVkcyBvZiB0aGUgYXVkaWVuY2UsIGVuc3VyaW5nIGFjY2Vzc2liaWxpdHkgZm9yIGFsbC4NCg0KKiAqKlJlYWRhYmxlIEZvbnRzKio6IENob29zZSBmb250cyB0aGF0IGFyZSBsZWdpYmxlIGZvciB2aWV3ZXJzIHdpdGggdmlzdWFsIGltcGFpcm1lbnRzLCBhdm9pZGluZyBvdmVybHkgb3JuYXRlIG9yIG5hcnJvdyB0eXBlZmFjZXMuDQoNCiogKipDb2xvcmJsaW5kLUZyaWVuZGx5IFBhbGV0dGUqKjogVXNlIGNvbG9yIGNvbWJpbmF0aW9ucyB0aGF0IGFyZSBkaXN0aW5ndWlzaGFibGUgZm9yIGluZGl2aWR1YWxzIHdpdGggY29sb3IgdmlzaW9uIGRlZmljaWVuY2llcy4NCg0KKiAqKkFsdCBUZXh0Kio6IEFkZCBhbHQgdGV4dCBkZXNjcmlwdGlvbnMgdG8gaW1hZ2VzIGZvciBhdWRpZW5jZXMgcmVseWluZyBvbiBzY3JlZW4gcmVhZGVycy4NCg0KKiAqKlJlc3BvbnNpdmUgRGVzaWduKio6IE9wdGltaXplIHNsaWRlcyBmb3IgdmFyaW91cyBkZXZpY2VzLCBlc3BlY2lhbGx5IGluIHZpcnR1YWwgcHJlc2VudGF0aW9ucyB3aGVyZSB2aWV3ZXJzIG1heSB1c2Ugc21hcnRwaG9uZXMgb3IgdGFibGV0cy4NCg0KDQpGb3IgZXhhbXBsZSwgYSBwcmVzZW50YXRpb24gb24gcHVibGljIHBvbGljeSBzaG91bGQgdXNlIGRpc3RpbmN0IHBhdHRlcm5zIG9yIGxhYmVscyBpbiBjaGFydHMgaW5zdGVhZCBvZiByZWx5aW5nIHNvbGVseSBvbiBjb2xvciBkaWZmZXJlbnRpYXRpb24uDQoNCg0KIyMgSW50ZXJhY3RpdmUgYW5kIER5bmFtaWMgRWxlbWVudHMNCg0KSW50ZXJhY3RpdmUgY29udGVudCBpbiBwcmVzZW50YXRpb24gc2xpZGVzIGNhbiBzaWduaWZpY2FudGx5IGVuaGFuY2UgYXVkaWVuY2UgZW5nYWdlbWVudCBhbmQgY29tcHJlaGVuc2lvbiBieSB0cmFuc2Zvcm1pbmcgYSBwYXNzaXZlIGV4cGVyaWVuY2UgaW50byBhbiBhY3RpdmUgb25lLiBJdCBhbGxvd3MgcHJlc2VudGVycyB0byB0YWlsb3IgdGhlIGRlbGl2ZXJ5IHRvIGF1ZGllbmNlIGludGVyZXN0cywgZm9zdGVyIHBhcnRpY2lwYXRpb24sIGFuZCBwcm92aWRlIGEgbW9yZSBkeW5hbWljIHByZXNlbnRhdGlvbi4gVG8gbWF4aW1pemUgdGhlIGVmZmVjdGl2ZW5lc3Mgb2YgaW50ZXJhY3RpdmUgY29udGVudCwgYWRoZXJlIHRvIHRoZSBmb2xsb3dpbmcgcHJpbmNpcGxlczoNCg0KKiAqKlB1cnBvc2VmdWwgSW50ZXJhY3Rpdml0eSoqOiBFbnN1cmUgZXZlcnkgaW50ZXJhY3RpdmUgZWxlbWVudCBoYXMgYSBjbGVhciBwdXJwb3NlIHRoYXQgc3VwcG9ydHMgdGhlIHByZXNlbnRhdGlvbuKAmXMgZ29hbHMuIEF2b2lkIGFkZGluZyBmZWF0dXJlcyBqdXN0IGZvciBub3ZlbHR5Lg0KDQoqICoqU2ltcGxpY2l0eSoqOiBLZWVwIGludGVyYWN0aXZlIGVsZW1lbnRzIGludHVpdGl2ZSBhbmQgZWFzeSB0byB1c2UuIE92ZXJseSBjb21wbGV4IGRlc2lnbnMgY2FuIGNvbmZ1c2UgYW5kIGRpc2VuZ2FnZSB0aGUgYXVkaWVuY2UuDQoNCiogKipUZXN0IEZ1bmN0aW9uYWxpdHkqKjogVmVyaWZ5IHRoYXQgYWxsIGludGVyYWN0aXZlIGZlYXR1cmVzIHdvcmsgYXMgaW50ZW5kZWQsIGVzcGVjaWFsbHkgd2hlbiBwcmVzZW50aW5nIG9uIHVuZmFtaWxpYXIgZXF1aXBtZW50IG9yIHBsYXRmb3Jtcy4NCg0KKiAqKkJhbGFuY2Ugd2l0aCBDb250ZW50Kio6IEludGVyYWN0aXZpdHkgc2hvdWxkIGNvbXBsZW1lbnQsIG5vdCBvdmVyc2hhZG93LCB0aGUgY29yZSBtZXNzYWdlIG9mIHRoZSBwcmVzZW50YXRpb24uDQoNCg0KIyMgQWNjZXNzaWJpbGl0eSBhbmQgSW5jbHVzaXZpdHkNCg0KRGVzaWduaW5nIHByZXNlbnRhdGlvbiBzbGlkZXMgd2l0aCBhY2Nlc3NpYmlsaXR5IGFuZCBpbmNsdXNpdml0eSBpbiBtaW5kIGVuc3VyZXMgdGhhdCBhbGwgYXVkaWVuY2UgbWVtYmVycywgcmVnYXJkbGVzcyBvZiB0aGVpciBhYmlsaXRpZXMgb3IgYmFja2dyb3VuZHMsIGNhbiBmdWxseSBlbmdhZ2Ugd2l0aCBhbmQgdW5kZXJzdGFuZCB0aGUgY29udGVudC4gVGhpcyBhcHByb2FjaCBub3Qgb25seSByZWZsZWN0cyByZXNwZWN0IGFuZCBjb25zaWRlcmF0aW9uIGJ1dCBhbHNvIGJyb2FkZW5zIHRoZSByZWFjaCBhbmQgaW1wYWN0IG9mIHRoZSBwcmVzZW50YXRpb24uDQoNCioqMS4gVGV4dCBBY2Nlc3NpYmlsaXR5KioNCg0KVGV4dCBjb250ZW50IHNob3VsZCBiZSBjbGVhciwgbGVnaWJsZSwgYW5kIHN0cnVjdHVyZWQgZm9yIGFsbCB2aWV3ZXJzLg0KDQoqICoqUmVhZGFibGUgRm9udHMqKjogVXNlIHNpbXBsZSwgc2Fucy1zZXJpZiBmb250cyBsaWtlIEFyaWFsIG9yIENhbGlicmksIGF2b2lkaW5nIGRlY29yYXRpdmUgc3R5bGVzLg0KDQoqICoqU3VmZmljaWVudCBGb250IFNpemUqKjogRW5zdXJlIHRleHQgaXMgbGFyZ2UgZW5vdWdoIHRvIGJlIHJlYWQgZnJvbSBhIGRpc3RhbmNlLCB0eXBpY2FsbHkgMjTigJMzNiBwb2ludHMgZm9yIGJvZHkgdGV4dCBhbmQgMzbigJM0NCBwb2ludHMgZm9yIGhlYWRpbmdzLg0KDQoqICoqQ29udHJhc3QqKjogVXNlIGhpZ2ggY29udHJhc3QgYmV0d2VlbiB0ZXh0IGFuZCBiYWNrZ3JvdW5kLCBzdWNoIGFzIGRhcmsgdGV4dCBvbiBhIGxpZ2h0IGJhY2tncm91bmQgb3IgdmljZSB2ZXJzYS4NCg0KKiAqKlRleHQgSGllcmFyY2h5Kio6IFVzZSBoZWFkaW5ncywgc3ViaGVhZGluZ3MsIGFuZCBidWxsZXQgcG9pbnRzIHRvIG9yZ2FuaXplIGNvbnRlbnQgbG9naWNhbGx5IGFuZCBtYWtlIGl0IHNjYW5uYWJsZS4NCg0KDQoNCioqMi4gVmlzdWFsIGFuZCBHcmFwaGljIEFjY2Vzc2liaWxpdHkqKg0KDQpJbWFnZXMsIGNoYXJ0cywgYW5kIG90aGVyIHZpc3VhbHMgc2hvdWxkIGJlIGFjY2Vzc2libGUgYW5kIGluY2x1c2l2ZS4NCg0KKiAqKkFsdCBUZXh0IGZvciBJbWFnZXMqKjogUHJvdmlkZSBhbHRlcm5hdGl2ZSB0ZXh0IGRlc2NyaXB0aW9ucyBmb3IgaW1hZ2VzIHRvIHN1cHBvcnQgYXVkaWVuY2UgbWVtYmVycyB1c2luZyBzY3JlZW4gcmVhZGVycy4NCg0KKiAqKkNvbG9yYmxpbmQtRnJpZW5kbHkgRGVzaWduKio6IEF2b2lkIHJlbHlpbmcgc29sZWx5IG9uIGNvbG9yIHRvIGNvbnZleSBpbmZvcm1hdGlvbi4gVXNlIHBhdHRlcm5zLCBsYWJlbHMsIG9yIHRleHQgYW5ub3RhdGlvbnMgaW4gZ3JhcGhzIGFuZCBjaGFydHMuDQoNCiogKipTaW1wbGUgVmlzdWFscyoqOiBBdm9pZCBvdmVybHkgY29tcGxleCBncmFwaGljcyB0aGF0IG1heSBvdmVyd2hlbG0gb3IgY29uZnVzZSB0aGUgYXVkaWVuY2UuDQpXaGl0ZSBTcGFjZTogVXNlIHN1ZmZpY2llbnQgd2hpdGUgc3BhY2UgdG8gYXZvaWQgdmlzdWFsIGNsdXR0ZXIgYW5kIG1ha2UgY29udGVudCBlYXNpZXIgdG8gZm9jdXMgb24uDQoNCg0KKiozLiBJbmNsdXNpdmUgTGFuZ3VhZ2UgYW5kIENvbnRlbnQqKg0KDQpJbmNsdXNpdml0eSBnb2VzIGJleW9uZCB0ZWNobmljYWwgZGVzaWduIHRvIGVuY29tcGFzcyB0aGUgcHJlc2VudGF0aW9u4oCZcyB0b25lIGFuZCBsYW5ndWFnZS4NCg0KKiAqKkF2b2lkIEphcmdvbioqOiBVc2UgY2xlYXIsIHN0cmFpZ2h0Zm9yd2FyZCBsYW5ndWFnZSB0byBlbnN1cmUgdGhlIGNvbnRlbnQgaXMgYWNjZXNzaWJsZSB0byBwZW9wbGUgd2l0aCB2YXJ5aW5nIGxldmVscyBvZiBleHBlcnRpc2UuDQoNCiogKipDdWx0dXJhbCBTZW5zaXRpdml0eSoqOiBBdm9pZCBpZGlvbXMsIG1ldGFwaG9ycywgb3IgcmVmZXJlbmNlcyB0aGF0IG1heSBub3QgdHJhbnNsYXRlIHdlbGwgYWNyb3NzIGN1bHR1cmVzLg0KDQoqICoqUmVwcmVzZW50YXRpb24qKjogSW5jbHVkZSBkaXZlcnNlIGV4YW1wbGVzLCBpbWFnZXMsIGFuZCBwZXJzcGVjdGl2ZXMgdG8gcmVmbGVjdCB0aGUgYXVkaWVuY2XigJlzIHZhcmllZCBiYWNrZ3JvdW5kcy4NCg0KDQpcDQoNCkluIHN1bW1hcnksIGRlc2lnbmluZyBlZmZlY3RpdmUgd2ViLWJhc2VkIHByZXNlbnRhdGlvbnMgcmVxdWlyZXMgYSB0aG91Z2h0ZnVsIGFwcHJvYWNoIHRoYXQgaW50ZWdyYXRlcyBjbGVhciBzdHJ1Y3R1cmUsIGVuZ2FnaW5nIHZpc3VhbHMsIGludGVyYWN0aXZpdHksIGFjY2Vzc2liaWxpdHksIGFuZCBwcmFjdGljYWwgZGVsaXZlcnkgc3RyYXRlZ2llcy4gQnkgZm9jdXNpbmcgb24gdGhlc2UgZWxlbWVudHMsIHByZXNlbnRlcnMgY2FuIGNyZWF0ZSBpbXBhY3RmdWwgb25saW5lIGV4cGVyaWVuY2VzIHRoYXQgcmVzb25hdGUgd2l0aCBkaXZlcnNlIGF1ZGllbmNlcy4gQXMgdmlydHVhbCBjb21tdW5pY2F0aW9uIGNvbnRpbnVlcyB0byBncm93LCBtYXN0ZXJpbmcgdGhlIGFydCBvZiB3ZWItYmFzZWQgcHJlc2VudGF0aW9uIGRlc2lnbiB3aWxsIGJlIGFuIGVzc2VudGlhbCBza2lsbCBmb3IgcHJvZmVzc2lvbmFscyBhY3Jvc3MgaW5kdXN0cmllcy4NCg0KDQoNCg0KDQoNCg==