Introduction

What is Make?

make is a powerful and widely used build automation tool in software development, especially for C and C++, but also Java and many other programming languages. It is designed to help programmers manage complex projects by automating the process of building executable files, libraries, or other artifacts from source code. Make is particularly valuable when you have multiple source files, dependencies, and compilation steps in your project.

The make program is a standard utility for Unix/Linux and is also available on MacOS as part of xcode. For other platforms, there are many open source versions of make.

Interpreted languages such as Python or R do not require a facility similar to make. This tutorial focuses on GNU make which has become the standard. We will explain the key elements of building a “makefile” which are standard across most Linux systems (and MacOS). Many integrated development environments (such as Eclipse) use some version of a make facility although they often use XML to specify dependencies rather than a traditional makefile, often using the utility ant rather than make.

Why Use Make?

There are many reasons why make is so widely used. We will take a look at a few reasons below.

Dependency Management

One of the primary reasons for using make is its ability to manage dependencies efficiently. In a typical software project, you have source files that depend on each other, configuration files, libraries, and other resources. make tracks these dependencies and ensures that only the necessary parts of your project are rebuilt when something changes. This feature saves time and prevents unnecessary recompilation.

Automation

Make automates repetitive and error-prone tasks involved in the build process. Instead of manually typing out long compilation commands, linking steps, and other tasks, you define rules and let make handle the details. This not only reduces the chances of human error but also makes your build process consistent and reproducible.

Portability

make is platform-independent, which means you can use the same Makefile (the configuration file for make) on different operating systems. This portability makes it an attractive choice for cross-platform development.

Customization

Make is highly customizable. You can tailor your build process to suit your project’s specific requirements. Define variables, rules, and targets in your Makefile to accommodate different build configurations, development environments, or deployment platforms.

When to Use Make

You should consider using make when:

  • You’re working on a project with multiple source files that need to be compiled and linked.
  • You want to automate repetitive tasks such as building, testing, and cleaning your project.
  • You need a tool that manages dependencies and ensures that only necessary parts of the project are rebuilt.
  • Your project needs to be cross-platform, and you want a build system that works consistently on different operating systems.
  • You value a high degree of customization and control over the build process.

In short, make is a fundamental tool for programmers and software developers. It streamlines the build process, manages dependencies, and automates tasks, ultimately leading to more efficient and maintainable software development projects. In the following sections of this tutorial, we will dive deeper into how to use make effectively to manage your projects.

Makefiles

Makefiles are an important element of programming, especially in C and C++ on Unix, although they can be found on other platforms and for other purposes as well. Essentially, makefiles are text files containing the rules on how an executable program is created from its source files and included libraries. A makefile serves as the input to the make program which read the rules in the makefile and produces an executable (well, a target, to be specific, which is most often an executable but doesn’t have to be). make applies the rules and only compiles what has changed since the last “build” of the executable. This is ideal when a project consists of many source files and a change in one would not require compiling all. Unfortunately, makefiles are a bit esoteric and the rules can be a bit baffling nowadays – after all, they were developed over fifty years ago when development tools were quite different.

Makefiles contain targets and dependency rules. If any source file’s dependencies change then the source file will get re-compiled and the new executable is linked.

A Simple Example

Running ‘make’

The ‘make’ command is run from the terminal (aka a shell).

% make target

When ‘make’ is run, it looks for a file named Makefile in the current folder. Note the capitalization of the file – it is important.

Let’s do the classic “Hello World” program as a makefile. Below is the contents of a really simple makefile (called Makefile).

hello:
    echo "Hello, World"

Important: Rules must be indented by a TAB and not spaces. So, hit the TAB key in your keyboard and do not type spaces with the spacebar on your keyboard. This is one of the most common mistakes that beginners run into.

Once you have the makefile, “execute it” by running the make program.

% make

Not specifying a target for make means that it builds the first target it finds.

Try it out for yourself

Go to the terminal, create a folder in which you can do this lesson, and use a text editor (e.g., vi) to create a file called Makefile and add the above.

Simple Build File Example

Makefiles are build files for projects and they contains all command to compile, link, copy, or move files and run scripts. Below is a simple example.

all: multithread

multithread: multithread.c
    gcc -o multithread multithread.c

Again, just as a reminder: the indent before gcc is a TAB and not spaces.

Generally makefiles contain a target named all that builds the entire project. It includes all of the sub targets, such as individual executables, test drivers, installation scripts, and so forth.

So, in the above example, all depends on multithread to be up-to-date, which, in turn, depends on multithread.c. So, if multithread.c changes, then it forces the rules to be applied and any commands below that rule are run. In the above example, that would be the compilation and linking with gcc.

To initiate the full build, call make all or simply make as all is the first target.

Makefile Structure and Syntax

A Makefile consists of a set of rules. A rule generally looks like this:

target: prerequisites
    command
    command
    command

The commands are the steps required to build the target. These need to start with a tab character and not spaces. The prerequisites are generally file names, separated by spaces. These files need to exist before the commands for the target are run. They define dependencies.

Target ‘clean’

Most makefiles includes a rule for a target named clean that is invoked with make clean. It’s purpose is to clean up your development environment remove the output of other targets. Note that is should not be the first target as it would then be the default target; the default target should be all.

Here is an example of a clean target for a simple project.

clean:
    rm -f multithread
    touch multithread.c

The rule removes the executable and updates the time stamp of last modification of the source file to the present time, which would force a recompile the next time you invoked make all.

Certainly, let’s expand on the second section, “Basic Makefile Structure,” to provide a more detailed explanation of the components of a Makefile and how they work together.


Basic Makefile Structure

A “Makefile” is a text file with the name Makefile (spelled just like that with a capital ‘M’) that contains instructions for the make utility on how to build a project. It consists of rules and targets, which are the building blocks of the Makefile. In this section, we will delve into the basic structure of a Makefile and explain how it works.

Rules and Targets

Targets

A target in a Makefile represents an output file or an action that make should perform. Targets are the goals of your build process, such as executables, object files, or other artifacts. Each target corresponds to a specific task that make can execute.

For example, in a C or C++ project, you might have targets like:

  • my_program: To build the final executable.
  • main.o, util.o: To compile individual source files into object files.
  • clean: To remove generated files and clean up the project.

Rules

A rule defines how to create a target from its dependencies. It consists of a target, a colon (:), and a list of dependencies. Below the rule, you specify the commands needed to build the target from its dependencies. These commands are typically indented using tabs.

Here’s a basic rule structure:

target: dependencies
    [commands]
  • Target: The name of the target you want to build.
  • Dependencies: The files or targets that the current target depends on. These represent the prerequisites for building the target.
  • Commands: The shell commands to be executed when make builds the target. These commands are indented with tabs.

Example Makefile

Let’s create a simple Makefile to compile a “Hello, World!” program written in C.

# Define the target and its dependencies
my_program: main.o

# Compile the program
main.o: main.c
    gcc -o main.o -c main.c

# Clean up generated files
clean:
    rm -f my_program main.o

In this Makefile:

  • my_program is the target, and it depends on main.o.
  • main.o is another target, which depends on main.c.
  • The gcc command is used to compile main.c into an object file (main.o).
  • The clean target is used to remove the generated files when you run make clean.

How make Works

When you run make in the command line without specifying a target, it looks for a special target called the default target. By convention, this is often named all. If you have an all target in your Makefile, make will execute the commands associated with that target.

For example:

all: my_program

When you run make without arguments, it will execute the all target, which depends on my_program. Thus, it will build my_program and its dependencies.

To summarize, a Makefile consists of rules and targets. Rules specify how to build targets from their dependencies. When you run make, it reads the Makefile, determines which targets need to be built or rebuilt based on file timestamps and dependencies, and then executes the corresponding commands. Understanding this basic structure is crucial for creating more complex and efficient Makefiles for your projects.

Certainly, let’s expand on the third section, “Makefile Rules and Targets,” to provide a more detailed explanation of rules, targets, and their practical usage in Makefiles.


3. Makefile Rules and Targets

In the context of make, rules and targets are fundamental concepts that define how your project’s build process works. Understanding how to structure and use them effectively in Makefiles is crucial for automating tasks and managing dependencies.

3.1 Targets

Targets in a Makefile represent the artifacts or actions that you want to create or perform. Targets are the focal points of your build process, and they can include:

  • Executable programs.
  • Object files (compiled source files).
  • Documentation.
  • Distribution packages.
  • Custom tasks like cleaning or testing.

Each target corresponds to a specific task or output that make should generate. Targets can be created by defining their names in your Makefile.

3.1.1 Example Targets

In a C/C++ project, you might define targets like:

  • my_program: To build the final executable.
  • main.o, util.o: To compile individual source files into object files.
  • clean: To remove generated files and clean up the project.

3.2 Rules

Rules in a Makefile define how to create a target from its dependencies. A rule consists of three main parts:

  1. Target: The name of the target that you want to build.
  2. Dependencies: The files or targets that the current target depends on. These represent the prerequisites for building the target.
  3. Commands: The shell commands to be executed when make builds the target from its dependencies. These commands are typically indented with tabs.

3.2.1 Example Rule Structure

Here’s the structure of a rule:

target: dependencies
    [commands]

3.2.2 Example Rule

Consider a simple rule to compile a C source file into an object file:

main.o: main.c
    gcc -o main.o -c main.c

In this rule:

  • main.o is the target we want to build.
  • main.c is the dependency (source file) that main.o depends on.
  • The command gcc -o main.o -c main.c is executed to build main.o from main.c.

3.3 Practical Usage

Makefiles become powerful when you have multiple rules and targets, and they help you automate complex build processes. Here are some practical tips:

3.3.1 Building All Targets

By convention, you can create an all target that depends on all the main targets in your project. When you run make, it builds the all target, which in turn builds everything else. For example:

all: my_program

my_program: main.o util.o
    gcc -o my_program main.o util.o

main.o: main.c
    gcc -o main.o -c main.c

util.o: util.c
    gcc -o util.o -c util.c

3.3.2 Cleaning Up

A clean target is handy for removing generated files and cleaning up your project. For example:

clean:
    rm -f my_program main.o util.o

3.3.3 Default Target

You can specify a default target by including it at the beginning of your Makefile. For example:

.DEFAULT_GOAL := all

This sets the all target as the default, so running make without any arguments will build all.

3.3.4 Phony Targets

Phony targets are targets that don’t represent actual files. They are used for tasks like cleaning, testing, or documentation generation. To declare a target as phony, use the .PHONY special target. For example:

.PHONY: clean test docs

clean:
    rm -f my_program main.o util.o

test:
    ./run_tests.sh

docs:
    doxygen

In this example, clean, test, and docs are phony targets.

3.4 Summary

In summary, Makefiles are composed of rules and targets. Rules specify how to build targets from their dependencies, and targets represent the artifacts or actions you want to create or perform. Understanding the structure and usage of rules and targets is essential for effectively automating tasks and managing dependencies in your software projects.

Certainly, let’s expand on the fourth section, “Variables in Makefiles,” to provide a more detailed explanation of variables and their practical usage in Makefiles.


4. Variables in Makefiles

Variables play a crucial role in Makefiles by allowing you to define reusable values that can be used throughout the file. They enhance the readability, maintainability, and flexibility of your Makefiles. In this section, we will explore how to declare and use variables effectively.

4.1 Declaring Variables

In a Makefile, you can declare variables using the following syntax:

VARIABLE_NAME = value
  • VARIABLE_NAME: This is the name of the variable, which should be written in uppercase letters by convention.
  • value: This is the value assigned to the variable. It can be a string, a command, or another variable.

4.2 Using Variables

You can use variables by enclosing their names in $(...) or ${...}. For example:

CC = gcc
CFLAGS = -Wall -O2

my_program: main.c
    $(CC) $(CFLAGS) -o my_program main.c

In this example, CC and CFLAGS are variables, and their values are substituted when the my_program target is built.

4.3 Variable Types

4.3.1 Simple Variables

Simple variables are defined using = as shown above. They can be overridden if redefined later in the Makefile.

4.3.2 Recursive Variables

Recursive variables are defined using :=. They are evaluated only when used, which means changes to their values do not affect previous usages.

VAR := initial_value
VAR := new_value  # Does not affect previous usages of VAR

4.3.3 Conditional Variables

Conditional variables are defined using ?=. They are set only if the variable is not already defined. This is useful for providing default values.

VAR ?= default_value  # VAR is set to default_value if VAR is not already defined

4.4 Practical Usage

Variables are beneficial in Makefiles for various reasons:

4.4.1 Compiler and Flags

You can use variables to store the compiler and compilation flags, making it easy to change them globally in your Makefile:

CC = gcc
CFLAGS = -Wall -O2

my_program: main.c
    $(CC) $(CFLAGS) -o my_program main.c

4.4.2 File Lists

Variables are useful for defining lists of files, especially when there are many source files:

SOURCES = main.c util.c
OBJECTS = $(SOURCES:.c=.o)

my_program: $(OBJECTS)
    $(CC) $(CFLAGS) -o my_program $(OBJECTS)

Here, OBJECTS is generated from SOURCES, converting .c to .o.

4.4.3 Conditional Compilation

Variables enable conditional compilation based on build configurations or target platforms:

# Build a debug version when DEBUG is defined
ifdef DEBUG
    CFLAGS += -g
endif

my_program: main.c
    $(CC) $(CFLAGS) -o my_program main.c

4.4.4 Versioning

You can define version numbers or project information as variables for easy updates:

VERSION = 1.0
PROJECT_NAME = my_project

my_program: main.c
    $(CC) $(CFLAGS) -o $(PROJECT_NAME)_$(VERSION) main.c

4.5 Conclusion

Variables in Makefiles provide flexibility and maintainability. They allow you to define values once and use them throughout your Makefile, making it easier to manage build configurations and adapt to different scenarios. Using variables effectively can simplify the maintenance of complex projects and make your Makefiles more readable.

Certainly, let’s expand on the fifth section, “Automatic Variables,” to provide a more detailed explanation of automatic variables and their practical usage in Makefiles.


5. Automatic Variables in Makefiles

Automatic variables are a set of predefined variables in Makefiles that simplify the construction of rules by providing information about the target and dependencies being processed. They help avoid redundancy in your Makefile and make it more concise. In this section, we’ll explore common automatic variables and how to use them effectively.

5.1 Common Automatic Variables

5.1.1 $@ - The Target

$@ represents the target of the rule being executed. It’s particularly useful when you have multiple rules with similar patterns, as it allows you to reference the target without repeating its name.

Example:

my_program: main.o util.o
    $(CC) $(CFLAGS) -o $@ $^

Here, $@ is replaced with my_program, and $^ with main.o util.o.

5.1.2 $^ - All Dependencies

$^ represents all the dependencies of the rule being executed. This is handy when you want to include all prerequisites in a command.

5.1.3 $< - The First Dependency

$< stands for the first dependency in the list of prerequisites. It’s often used when there’s only one dependency and you want to reference it directly.

Example:

main.o: main.c
    $(CC) $(CFLAGS) -o $@ $<

Here, $< is replaced with main.c.

5.1.4 $? - Out-of-Date Dependencies

$? represents all the dependencies that are out-of-date concerning the target. It’s useful when you want to process only the files that have changed since the last build.

5.2 Practical Usage

Automatic variables simplify Makefile rules, making them more concise and less error-prone. Here are some practical examples of how to use them:

5.2.1 Building Multiple Targets

Automatic variables are especially useful when building multiple targets from a single rule:

objects = main.o util.o

all: my_program

my_program: $(objects)
    $(CC) $(CFLAGS) -o $@ $^

$(objects): %.o: %.c
    $(CC) $(CFLAGS) -c -o $@ $<

In this example, $@ and $^ are used to specify the target and dependencies for the my_program rule, as well as for the pattern rule that compiles .c files into .o files.

5.2.2 Conditional Compilation

Automatic variables can be used to simplify conditional compilation based on build configurations or target platforms:

DEBUG ?= 0

ifeq ($(DEBUG), 1)
    CFLAGS += -g
endif

my_program: main.c
    $(CC) $(CFLAGS) -o $@ $<

Here, $< represents the first dependency, which is main.c. If DEBUG is defined as 1, the -g flag is added to the compilation command.

5.2.3 Out-of-Date Dependencies

Automatic variables like $? are useful when you want to process only the dependencies that have changed since the last build. For example, in a custom build script:

generate_resources: resource_generator
    ./resource_generator -o $@ $?

resource_generator: resource_generator.c
    $(CC) $(CFLAGS) -o $@ $<

In this example, generate_resources depends on the resource_generator program and all the out-of-date resource files ($?) to generate new resources.

5.3 Conclusion

Automatic variables in Makefiles simplify rule construction and reduce redundancy in your build scripts. By using variables like $@, $^, $<, and $?, you can create more concise and maintainable Makefiles that adapt to changes in your project without the need for extensive manual editing. Understanding and utilizing these automatic variables effectively can significantly enhance your Makefile-writing skills.

Certainly, let’s expand on the sixth section, “Phony Targets,” to provide a more detailed explanation of phony targets and their practical usage in Makefiles.


6. Phony Targets in Makefiles

In Makefiles, phony targets are targets that don’t represent files or artifacts but rather serve as labels for specific actions or tasks that need to be executed. Phony targets are essential for tasks such as cleaning, testing, or generating documentation. In this section, we will explore what phony targets are and how to use them effectively.

6.1 What Are Phony Targets?

Phony targets are used to define actions or tasks that make should perform when explicitly requested, but they don’t correspond to actual files in the file system. They are declared in a Makefile to provide convenient names for common development and maintenance tasks, allowing you to execute these tasks using the make command.

Typically, phony targets have no prerequisites or dependencies because their purpose is to execute a specific action, not to build a file based on dependencies.

6.2 Declaring Phony Targets

To declare a target as phony, you use the .PHONY special target in your Makefile, followed by a list of phony target names. For example:

.PHONY: clean test docs

In this example, we’ve declared three phony targets: clean, test, and docs. These targets represent common development tasks such as cleaning up generated files, running tests, and generating documentation.

6.3 Practical Usage

Phony targets are valuable for automating various development and maintenance tasks. Here are some common use cases and practical examples of phony targets:

6.3.1 Cleaning

A clean phony target is used to remove generated files and artifacts to ensure a clean project directory. It’s especially important when you want to rebuild your project from scratch or before archiving or distributing it.

.PHONY: clean

clean:
    rm -f my_program main.o util.o

Running make clean will remove the executable my_program and the object files (main.o and util.o) from the project directory.

6.3.2 Testing

A test phony target is used to run your project’s test suite. This is especially helpful for continuous integration (CI) workflows.

.PHONY: test

test:
    ./run_tests.sh

Here, run_tests.sh is a script that executes your project’s test cases. Running make test will trigger this script and execute the tests.

6.3.3 Generating Documentation

A docs phony target is used to generate project documentation. For example, if you use Doxygen for documentation generation:

.PHONY: docs

docs:
    doxygen

Running make docs will generate documentation using Doxygen or any other documentation generation tool you prefer.

6.3.4 Dependency Analysis

You can use phony targets to analyze dependencies in your project, such as generating dependency files for C/C++ code. For instance, using the GCC -M flag to generate dependency files:

.PHONY: depend

depend:
    gcc -M *.c > dependencies

Running make depend will update the dependencies file with the latest dependency information for your project.

6.4 Conclusion

Phony targets in Makefiles provide a way to define and automate common development and maintenance tasks. By declaring phony targets, you can use the make command to execute these tasks conveniently without worrying about file dependencies. This helps streamline your development workflow, making it easier to clean, test, and document your projects efficiently.

Certainly, let’s expand on the seventh section, “Dependency Management,” to provide a more detailed explanation of how dependency management works in Makefiles and its practical usage.


7. Dependency Management in Makefiles

Dependency management is a critical aspect of Makefiles, as it ensures that make rebuilds only those targets that are out-of-date based on changes in their dependencies. In this section, we will delve deeper into how dependency management works and provide practical examples.

7.1 Defining Dependencies

In a Makefile, dependencies are specified in the rules for each target. A target depends on one or more files or other targets, known as prerequisites. When make encounters a rule, it checks if the target is older than any of its prerequisites. If a prerequisite is newer than the target or if the target doesn’t exist, make rebuilds the target.

Here’s the basic structure of a rule with dependencies:

target: dependencies
    [commands]

7.2 How make Determines What to Build

When you run make, it follows these steps to determine what needs to be built:

  1. It reads the Makefile to build a dependency graph that shows how targets and dependencies are related.
  2. It checks the timestamps of targets and their dependencies.
  3. If a target is older than any of its dependencies, or if the target doesn’t exist, make executes the commands associated with that target to rebuild it.
  4. It recursively builds any prerequisites that are out-of-date before building the target.

7.3 Practical Usage

Let’s look at practical examples of how dependency management works in Makefiles.

7.3.1 C/C++ Compilation

Consider a simple C/C++ project with multiple source files and header files:

CC = gcc
CFLAGS = -Wall -O2

my_program: main.o util.o
    $(CC) $(CFLAGS) -o my_program main.o util.o

main.o: main.c util.h
    $(CC) $(CFLAGS) -c -o main.o main.c

util.o: util.c util.h
    $(CC) $(CFLAGS) -c -o util.o util.c

In this example:

  • my_program depends on main.o and util.o.
  • main.o depends on main.c and util.h.
  • util.o depends on util.c and util.h.

If you modify main.c or util.c, running make will rebuild only the affected object files and then re-link the program. The dependencies ensure that only the necessary parts of the project are rebuilt.

7.3.2 Automatic Dependency Generation

Make can also generate dependency information automatically using tools like gcc -M. For example:

CC = gcc
CFLAGS = -Wall -O2

SOURCES = main.c util.c
OBJECTS = $(SOURCES:.c=.o)

my_program: $(OBJECTS)
    $(CC) $(CFLAGS) -o my_program $(OBJECTS)

%.o: %.c
    $(CC) $(CFLAGS) -c -o $@ $<

# Automatically generate dependencies
%.d: %.c
    $(CC) -M -MP -MF $@ -MT $(@:.d=.o) $<

In this example, the %.d rule generates dependency files (*.d) that contain information about the header file dependencies of each source file. These dependency files are then included in the Makefile, ensuring that changes in header files trigger recompilation.

To include the generated dependency files in your Makefile, add this line:

-include $(SOURCES:.c=.d)

This line tells make to include the generated .d files.

7.4 Conclusion

Dependency management is a fundamental aspect of Makefiles, enabling efficient and automated builds. By specifying dependencies for each target, you can ensure that make rebuilds only what is necessary, reducing build times and ensuring consistency in your projects. Understanding how dependency management works and how to use it effectively is essential for efficient software development workflows.

Certainly, let’s expand on the eighth section, “Conditional Statements in Makefiles,” to provide a more detailed explanation of conditional statements and their practical usage in Makefiles.


8. Conditional Statements in Makefiles

Conditional statements in Makefiles allow you to create rules and targets that vary depending on specific conditions or variables. These statements enable you to customize your build process, adapt to different environments, or handle various build configurations. In this section, we’ll explore the use of conditional statements in Makefiles and provide practical examples.

8.1 Conditional Directives

Makefiles use conditional directives to define rules, targets, and variables based on conditions. Common conditional directives include ifeq, ifneq, ifdef, and ifndef. These directives allow you to check for equality, inequality, or variable existence.

The basic structure of conditional directives is as follows:

conditional_directive
    # Condition
    [commands]
else
    # Alternative commands
endif

8.2 Practical Usage

Let’s explore some practical examples of how conditional statements can be used in Makefiles.

8.2.1 Conditional Compilation

Conditional compilation is a common use case for conditional statements in Makefiles. You can use conditionals to include or exclude specific source files or compiler flags based on build configurations.

DEBUG ?= 0

ifeq ($(DEBUG), 1)
    CFLAGS += -g
endif

my_program: main.c
    $(CC) $(CFLAGS) -o my_program main.c

In this example, the -g flag is added to CFLAGS if the DEBUG variable is set to 1. This allows you to control whether debugging information is included in the compiled binary.

8.2.2 Platform-Specific Rules

You can use conditionals to define platform-specific rules or variables. For instance, you might have different compilation settings for Windows and Linux:

UNAME_S := $(shell uname -s)

ifeq ($(UNAME_S),Linux)
    CC = gcc
    CFLAGS = -Wall -O2
endif

ifeq ($(UNAME_S),Windows_NT)
    CC = cl
    CFLAGS = /W4 /O2
endif

my_program: main.c
    $(CC) $(CFLAGS) -o my_program main.c

Here, the Makefile sets the compiler (CC) and compiler flags (CFLAGS) based on the host operating system.

8.2.3 Variable Assignment

Conditional statements can also be used for variable assignment. For example, you might want to set a variable differently depending on whether a specific tool is available:

ifdef TOOL_EXISTS
    COMPILER = $(TOOL_EXISTS)
else
    COMPILER = gcc
endif

my_program: main.c
    $(COMPILER) -o my_program main.c

In this case, if the TOOL_EXISTS variable is defined, it will be used as the compiler; otherwise, gcc is used as the default.

8.3 Nested Conditionals

You can nest conditional statements to handle more complex scenarios:

DEBUG ?= 0
TARGET ?= linux

ifeq ($(DEBUG), 1)
    CFLAGS += -g
else
    ifeq ($(TARGET), windows)
        CFLAGS += -O2
    else
        CFLAGS += -O3
    endif
endif

my_program: main.c
    $(CC) $(CFLAGS) -o my_program main.c

In this example, the build configuration depends on both the DEBUG variable and the TARGET variable. Depending on these conditions, different optimization flags (-g, -O2, or -O3) are used.

8.4 Conclusion

Conditional statements in Makefiles provide flexibility and adaptability to your build process. They allow you to customize rules, targets, and variables based on conditions, making your Makefiles more versatile and suitable for various build scenarios. Understanding how to use conditional statements effectively can help you manage complex projects and accommodate different environments and configurations.

Certainly, let’s expand on the ninth section, “Pattern Rules and Automatic Prerequisites,” to provide a more detailed explanation of pattern rules, automatic prerequisites, and their practical usage in Makefiles.


9. Pattern Rules and Automatic Prerequisites in Makefiles

Pattern rules are a powerful feature in Makefiles that allow you to define generic rules for building multiple targets with similar patterns. Automatic prerequisites extend this concept by automatically generating dependency information for source files. In this section, we will explore how to use pattern rules and automatic prerequisites effectively in Makefiles.

9.1 Pattern Rules

Pattern rules in Makefiles define a general rule for building targets that match a specific pattern. They are a way to avoid writing multiple similar rules for targets with a common structure. The syntax for a pattern rule is:

%.out: %.c
    [commands]
  • %.out: The target pattern that matches any target ending with .out.
  • %.c: The prerequisite pattern that matches any source file ending with .c.
  • [commands]: The commands to build the target from the prerequisite.

For example, if you have multiple C source files and want to create executables from them, you can use a pattern rule like this:

%.out: %.c
    gcc -o $@ $<

Now, make can build any target with a .out extension from the corresponding .c source file.

9.2 Automatic Prerequisites

Automatic prerequisites are an extension of pattern rules that automatically generate dependency information for source files. This is particularly useful when you want to track changes in header files and automatically rebuild targets when header files change.

To enable automatic prerequisites, you can use the -M flag with the gcc or g++ compiler to generate dependency information. For example:

%.o: %.c
    gcc -MMD -MP -MF $*.d -c -o $@ $<
  • -MMD: Generate dependency information.
  • -MP: Generate phony targets for missing headers.
  • -MF $*.d: Specify the dependency file to be generated (e.g., main.d for main.c).
  • -c -o $@ $<: Compile the source file into an object file.

Additionally, you can include the generated dependency files in your Makefile to ensure accurate tracking of header file changes:

-include $(wildcard *.d)

This line tells make to include all .d files in the current directory.

9.3 Practical Usage

Let’s look at practical examples of how pattern rules and automatic prerequisites can be used in Makefiles.

9.3.1 Building Multiple Targets

Pattern rules are excellent for building multiple targets from similar source files. Suppose you have several C source files (file1.c, file2.c, etc.) that you want to compile into executables (file1.out, file2.out, etc.). You can use the following pattern rule:

%.out: %.c
    gcc -o $@ $<

Now, make file1.out will compile file1.c into file1.out, and the same rule applies to other source files.

9.3.2 Automatic Prerequisites for C/C++ Projects

Automatic prerequisites simplify dependency tracking in C/C++ projects. Consider this Makefile for a C project:

CC = gcc
CFLAGS = -Wall -O2

SOURCES = main.c util.c
OBJECTS = $(SOURCES:.c=.o)

-include $(wildcard *.d)

%.o: %.c
    $(CC) -MMD -MP -MF $*.d $(CFLAGS) -c -o $@ $<

my_program: $(OBJECTS)
    $(CC) $(CFLAGS) -o my_program $(OBJECTS)

With this setup, the Makefile automatically generates dependency files (.d) for each source file and includes them. If a header file changes, only the affected source files are rebuilt, saving compilation time.

9.3.3 Generic Rules for Build Systems

Pattern rules are especially useful in build systems that need to handle various source files and targets. For example, in a build system for a scripting language interpreter:

%.o: %.c
    $(CC) -MMD -MP -MF $*.d $(CFLAGS) -c -o $@ $<

interpreter: $(OBJECTS)
    $(CC) $(CFLAGS) -o interpreter $(OBJECTS)

This pattern rule and target allow you to compile any .c source file into an object file and then link them to create the interpreter.

9.4 Conclusion

Pattern rules and automatic prerequisites in Makefiles provide a powerful way to streamline the build process for projects with multiple source files and dependencies. By defining generic rules for building targets and automatically generating dependency information, you can save time and ensure accurate tracking of changes in source files and headers. Understanding how to use pattern rules and automatic prerequisites effectively is essential for efficient software development workflows.

Certainly, let’s expand on the tenth section, “Managing Libraries and Linking,” to provide a more detailed explanation of how to manage libraries and linking in Makefiles.


10. Managing Libraries and Linking in Makefiles

Libraries are an essential part of software development, and in Makefiles, managing libraries and linking them to your programs is crucial. In this section, we will explore how to include and link libraries effectively in Makefiles.

10.1 Including Libraries

Including libraries in your Makefile involves specifying the necessary libraries that your program depends on. You typically use the -l flag followed by the library name when invoking the linker (e.g., gcc or g++).

Here’s an example of how to include the math library in a Makefile:

my_program: main.c
    gcc -o my_program main.c -lm

In this example, the -lm flag tells the linker to include the math library.

10.2 Specifying Library Directories

Sometimes, the libraries you need may be located in non-standard directories. You can specify library directories using the -L flag and then include the libraries using the -l flag.

my_program: main.c
    gcc -o my_program main.c -L/path/to/libdir -lmylib

In this case, /path/to/libdir is the directory containing the libmylib.a or libmylib.so library file.

10.3 Practical Usage

Let’s explore some practical examples of managing libraries and linking them in Makefiles.

10.3.1 Linking with Multiple Libraries

If your program depends on multiple libraries, you can specify them by separating them with space after the -l flag:

my_program: main.c
    gcc -o my_program main.c -lm -lpthread -lmylib

In this example, we’re linking with the math library (-lm), the pthread library (-lpthread), and a custom library (-lmylib).

10.3.2 Using Variables for Libraries

To make your Makefile more maintainable, you can use variables to store library flags:

LIBS = -lm -lpthread -lmylib

my_program: main.c
    gcc -o my_program main.c $(LIBS)

By using variables, it’s easier to add or remove libraries from your project without changing every occurrence in your Makefile.

10.3.3 Conditional Linking

You can use conditional statements in your Makefile to handle different build configurations and link libraries accordingly. For example, you might want to link with a debugging library when debugging is enabled:

DEBUG ?= 0
LIBS = -lm -lpthread

ifeq ($(DEBUG), 1)
    LIBS += -ldebug
endif

my_program: main.c
    gcc -o my_program main.c $(LIBS)

In this example, the -ldebug library is included in the LIBS variable only if the DEBUG variable is set to 1.

10.3.4 Automatic Dependency Tracking

If your project has header file dependencies, you can use automatic prerequisites (as discussed in section 9) to automatically track changes in header files and recompile the program when needed. This ensures that your program is rebuilt when any of its dependencies change.

CC = gcc
CFLAGS = -Wall -O2
SOURCES = main.c util.c
OBJECTS = $(SOURCES:.c=.o)

-include $(wildcard *.d)

%.o: %.c
    $(CC) -MMD -MP -MF $*.d $(CFLAGS) -c -o $@ $<

my_program: $(OBJECTS)
    $(CC) $(CFLAGS) -o my_program $(OBJECTS) -lm -lpthread -lmylib

In this example, we include libraries as well as dependencies generated for source files.

10.4 Conclusion

Managing libraries and linking in Makefiles is essential for building complex software projects. By specifying libraries, library directories, and using variables and conditional statements, you can create Makefiles that handle library management efficiently. Additionally, automatic dependency tracking ensures that your program is rebuilt when necessary, keeping your build process up-to-date and reliable. Understanding these concepts is crucial for effective software development workflows using Makefiles.

Certainly, let’s expand on the eleventh section, “Cleaning and Maintenance,” to provide a more detailed explanation of cleaning targets, maintaining Makefiles, and other aspects related to cleaning and maintaining your project with Makefiles.


11. Cleaning and Maintenance in Makefiles

Cleaning and maintaining a project is a crucial part of software development. Makefiles provide several features to help you manage these tasks efficiently. In this section, we will explore how to create cleaning targets, handle project maintenance, and other related aspects in Makefiles.

11.1 Cleaning Targets

Cleaning targets are used to remove generated files and artifacts, ensuring a clean project directory for rebuilding or distribution. A common cleaning target in a Makefile is clean. To create a clean target, you can use the following rule:

.PHONY: clean

clean:
    rm -f my_program *.o

In this example, the clean target removes the my_program executable and all object files (*.o) from the project directory when you run make clean.

11.2 Maintenance Targets

Maintenance targets are used to perform tasks related to project maintenance, such as generating documentation, running tests, or checking code formatting. Here are some examples:

11.2.1 Generating Documentation

You can create a target called docs to generate project documentation. For instance, if you use Doxygen for documentation generation:

.PHONY: docs

docs:
    doxygen

Running make docs will execute the doxygen command to generate documentation.

11.2.2 Running Tests

To run your project’s test suite, you can create a target called test:

.PHONY: test

test:
    ./run_tests.sh

In this example, the test target executes a script (run_tests.sh) that runs your project’s test cases.

11.2.3 Code Formatting

You can also create a target to check or format your code using tools like clang-format:

.PHONY: format

format:
    clang-format -i *.c

Running make format would apply code formatting to all .c source files.

11.3 Automating Dependency Cleanup

If your Makefile generates dependency files (as discussed in section 9), you can create a target to clean up these files when no longer needed:

.PHONY: clean-deps

clean-deps:
    rm -f *.d

The clean-deps target removes all generated dependency files (*.d) from the project directory.

11.4 Conditional Maintenance Targets

You can use conditional statements to control when maintenance targets should be executed. For example, you might want to generate documentation only for specific build configurations:

DEBUG ?= 0

ifeq ($(DEBUG), 1)
    .PHONY: docs

    docs:
        doxygen
endif

In this example, the docs target is defined and marked as phony only if the DEBUG variable is set to 1, ensuring that documentation is generated only for debugging builds.

11.5 Conclusion

Cleaning and maintaining a project are essential aspects of software development, and Makefiles offer convenient ways to automate these tasks. By creating cleaning and maintenance targets, you can keep your project directory organized and up-to-date. Additionally, using conditional statements allows you to control when these targets are executed, ensuring they align with your project’s needs and build configurations. Understanding and effectively utilizing these features in Makefiles is crucial for managing complex software projects efficiently.

Certainly, let’s expand on the twelfth section, “Advanced Techniques and Best Practices,” to provide a more detailed explanation of advanced Makefile techniques and best practices that can help you create efficient and maintainable build systems.

Advanced Techniques and Best Practices in Makefiles

Advanced techniques and best practices in Makefiles can significantly improve the efficiency and maintainability of your build system. In this section, we’ll explore some advanced techniques and best practices that can elevate your Makefile skills.

Use Variables for Compiler and Flags

Using variables to store compiler and flag settings in your Makefile makes it more maintainable and adaptable. For example:

CC = gcc
CFLAGS = -Wall -O2

By defining these variables, you can easily change the compiler or compiler flags in one place, making it less error-prone and more flexible.

Phony Targets

Always mark targets that don’t correspond to actual files (e.g., clean, all, test, docs) as phony using the .PHONY special target. This helps prevent conflicts with files of the same name and ensures that the target is always executed, even if a file with the same name exists.

.PHONY: clean test docs

Use Wildcards for Source Files

Instead of listing all source files manually, you can use wildcards to automatically detect source files in a directory. For example, to compile all .c files in the current directory:

SOURCES = $(wildcard *.c)

This approach is more maintainable as it automatically adapts to changes in the directory.

Generating Dependency Files Automatically

Automatically generating dependency files for C/C++ projects using tools like gcc -M (as discussed in section 9) is a powerful technique. It ensures that your Makefile accurately tracks header file dependencies, reducing the risk of broken builds.

-include $(wildcard *.d)

Conditional Compilation

Conditional compilation (as discussed in section 8) allows you to adapt your build process to different configurations or platforms. This can be useful for enabling or disabling features, setting compiler flags conditionally, or specifying different build paths.

Separate Directories for Object Files

Organizing object files in a separate directory (e.g., obj/) instead of cluttering the source directory can make your project structure cleaner and avoid conflicts between object files and source files with the same names.

OBJ_DIR = obj
OBJECTS = $(addprefix $(OBJ_DIR)/, $(SOURCES:.c=.o))

$(OBJ_DIR)/%.o: %.c
    $(CC) -MMD -MP -MF $(OBJ_DIR)/$*.d $(CFLAGS) -c -o $@ $<

Target-Specific Variables

You can set variables that are specific to a particular target. This allows you to customize compilation flags or settings for specific source files or targets.

my_program: main.c
    $(CC) $(CFLAGS) -o my_program main.c

special_target: special.c
    $(CC) $(CFLAGS_SPECIAL) -o special_target special.c

Here, CFLAGS_SPECIAL is used only for the special_target.

Parallel Builds

You can use the -j flag with the make command to enable parallel builds, which can significantly reduce build times on multi-core systems. For example, make -j4 will run up to four jobs concurrently.

Comments and Documentation

Adding comments to your Makefile helps document its structure and purpose. It’s also a good practice to include a section at the beginning of your Makefile that explains its usage, dependencies, and any special instructions for building the project.

Version Control Integration

If you’re using a version control system like Git, consider adding a .gitignore file to ignore generated files, object files, and build artifacts. This keeps your repository clean and avoids tracking unnecessary files.

Continuous Integration

Integrate your Makefile with a continuous integration (CI) system like Jenkins, Travis CI, or GitHub Actions. This ensures that your project is automatically built and tested on every push to the repository, helping catch issues early.

Debugging Makefiles

When debugging Makefiles, you can use the -n or --just-print flag with make to see the commands that would be executed without actually running them. This can help identify issues in your rules and dependencies. A common mistake is not starting a line for a command with the TAB or using an editor which replaces TAB with 4 or 8 spaces.

Testing and Validation

Regularly test and validate your Makefiles with various build configurations and platforms to ensure they work correctly in different scenarios. Automated testing of the build process can be invaluable in catching regressions.

Modularization

For complex projects, consider modularizing your Makefile by splitting it into multiple smaller Makefiles or including separate Makefiles for specific components or subsystems. This can make the build system more manageable.

Performance Optimization

Profile and optimize your build process, especially for large projects. Identifying and eliminating bottlenecks can significantly improve build times and developer productivity.

Build Targets

Define clear and specific build targets (e.g., all, clean, test, docs, install) to standardize the build process across your projects and make it easier for team members to understand and use the Makefile.

Error Handling

Implement error handling in your Makefile to detect and report errors during the build process. You can use constructs like || to execute commands conditionally based on the success of previous commands.

Continuous Learning

Keep exploring advanced Makefile techniques, best practices, and new features as you continue to work on different projects. Makefiles are a versatile tool, and there’s always more to learn.

Conclusion

Advanced techniques and best practices in Makefiles can significantly enhance the efficiency, reliability, and maintainability of your build systems. By applying these practices, you can create robust and adaptable Makefiles that streamline the development and deployment of your software projects. Continuously improving your Makefile skills is a valuable asset in software development.

Summary

In this tutorial on make for programmers, we covered a wide range of topics to help you understand and effectively use Makefiles in your software development projects. Here’s a summary of the key points covered in the sections:

  1. Basic Makefile Structure: The fundamental structure of a Makefile, including rules, targets, and commands.

  2. Target Rules and Dependencies: How to define targets and their dependencies, ensuring that Make knows when to rebuild a target.

  3. Implicit Rules and Variables: Implicit rules that Make uses by default and how to override them using variables.

  4. User-Defined Variables: How to define your own variables in Makefiles to make them more flexible and maintainable.

  5. Phony Targets: The concept of phony targets for defining actions or tasks that don’t produce files, and their practical usage.

  6. Dependency Management: How Make manages dependencies and automatically rebuilds targets when dependencies change.

  7. Conditional Statements: Using conditional statements to create rules and targets that adapt to different conditions or configurations.

  8. Pattern Rules and Automatic Prerequisites: How to use pattern rules to build targets with similar patterns and automatically generate dependency information.

  9. Managing Libraries and Linking: Including libraries in your Makefile, specifying library directories, and handling advanced linking.

  10. Cleaning and Maintenance: Creating cleaning and maintenance targets, handling project maintenance, and automating dependency cleanup.

  11. Advanced Techniques and Best Practices: Advanced techniques and best practices for more efficient and maintainable Makefiles, including using variables, phony targets, wildcards, and version control integration.

By understanding and applying the concepts and techniques discussed in this tutorial, you can create robust and efficient Makefiles to automate your build processes, manage dependencies, and maintain your software projects effectively. Makefiles are a valuable tool in the arsenal of any developer, helping to streamline the development workflow and ensure consistent, reliable builds.

Tutorial

None yet.

Files & Resources

All Files for Lesson 1.901

References

Learn Makefiles

Errata

Let us know.

LS0tDQp0aXRsZTogIlRoZSAnbWFrZScgVXRpbGl0eSBhbmQgV3JpdGluZyBNYWtlZmlsZXMiDQpwYXJhbXM6DQogIGNhdGVnb3J5OiAxDQogIG51bWJlcjogOTAxDQogIHRpbWU6ICI2MCBtaW4iDQogIGxldmVsOiBiZWdpbm5lcg0KICB0YWdzOiBtYWtlLG1ha2VmaWxlLEMsQysrLFVuaXgscHJvZ3JhbW1pbmcNCiAgZGVzY3JpcHRpb246ICJJbnRyb2R1Y2VzIG1ha2VmaWxlcyBhbmQgdGhlaXIgdXNlIGluIGJ1aWxkaW5nDQogICAgICAgICAgICAgICAgcHJvZ3JhbXMsIHByaW1hcmlseSBmb3IgQyBhbmQgQysrLiINCmRhdGU6ICI8c21hbGw+YHIgU3lzLkRhdGUoKWA8L3NtYWxsPiINCmF1dGhvcjogIjxzbWFsbD5NYXJ0aW4gU2NoZWRsYmF1ZXI8L3NtYWxsPiINCmVtYWlsOiAibS5zY2hlZGxiYXVlckBuZXUuZWR1Ig0KYWZmaWxpdGF0aW9uOiAiTm9ydGhlYXN0ZXJuIFVuaXZlcnNpdHkiDQpvdXRwdXQ6IA0KICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29sbGFwc2VkOiBmYWxzZQ0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHNwYWNlbGFiDQogICAgaGlnaGxpZ2h0OiB0YW5nbw0KLS0tDQoNCi0tLQ0KdGl0bGU6ICI8c21hbGw+YHIgcGFyYW1zJGNhdGVnb3J5YC5gciBwYXJhbXMkbnVtYmVyYDwvc21hbGw+PGJyLz48c3BhbiBzdHlsZT0nY29sb3I6ICMyRTQwNTM7IGZvbnQtc2l6ZTogMC45ZW0nPmByIHJtYXJrZG93bjo6bWV0YWRhdGEkdGl0bGVgPC9zcGFuPiINCi0tLQ0KDQpgYGB7ciBjb2RlPXhmdW46OnJlYWRfdXRmOChwYXN0ZTAoaGVyZTo6aGVyZSgpLCcvUi9faW5zZXJ0MkRCLlInKSksIGluY2x1ZGUgPSBGQUxTRX0NCmBgYA0KDQojIyBJbnRyb2R1Y3Rpb24NCg0KIyMjIFdoYXQgaXMgTWFrZT8NCg0KYG1ha2VgIGlzIGEgcG93ZXJmdWwgYW5kIHdpZGVseSB1c2VkIGJ1aWxkIGF1dG9tYXRpb24gdG9vbCBpbiBzb2Z0d2FyZSBkZXZlbG9wbWVudCwgZXNwZWNpYWxseSBmb3IgQyBhbmQgQysrLCBidXQgYWxzbyBKYXZhIGFuZCBtYW55IG90aGVyIHByb2dyYW1taW5nIGxhbmd1YWdlcy4gSXQgaXMgZGVzaWduZWQgdG8gaGVscCBwcm9ncmFtbWVycyBtYW5hZ2UgY29tcGxleCBwcm9qZWN0cyBieSBhdXRvbWF0aW5nIHRoZSBwcm9jZXNzIG9mIGJ1aWxkaW5nIGV4ZWN1dGFibGUgZmlsZXMsIGxpYnJhcmllcywgb3Igb3RoZXIgYXJ0aWZhY3RzIGZyb20gc291cmNlIGNvZGUuIE1ha2UgaXMgcGFydGljdWxhcmx5IHZhbHVhYmxlIHdoZW4geW91IGhhdmUgbXVsdGlwbGUgc291cmNlIGZpbGVzLCBkZXBlbmRlbmNpZXMsIGFuZCBjb21waWxhdGlvbiBzdGVwcyBpbiB5b3VyIHByb2plY3QuDQoNClRoZSAqbWFrZSogcHJvZ3JhbSBpcyBhIHN0YW5kYXJkIHV0aWxpdHkgZm9yIFVuaXgvTGludXggYW5kIGlzIGFsc28gYXZhaWxhYmxlIG9uIE1hY09TIGFzIHBhcnQgb2YgeGNvZGUuIEZvciBvdGhlciBwbGF0Zm9ybXMsIHRoZXJlIGFyZSBtYW55IG9wZW4gc291cmNlIHZlcnNpb25zIG9mICptYWtlKi4NCg0KSW50ZXJwcmV0ZWQgbGFuZ3VhZ2VzIHN1Y2ggYXMgUHl0aG9uIG9yIFIgZG8gbm90IHJlcXVpcmUgYSBmYWNpbGl0eSBzaW1pbGFyIHRvICptYWtlKi4gVGhpcyB0dXRvcmlhbCBmb2N1c2VzIG9uIEdOVSAqbWFrZSogd2hpY2ggaGFzIGJlY29tZSB0aGUgc3RhbmRhcmQuIFdlIHdpbGwgZXhwbGFpbiB0aGUga2V5IGVsZW1lbnRzIG9mIGJ1aWxkaW5nIGEgIm1ha2VmaWxlIiB3aGljaCBhcmUgc3RhbmRhcmQgYWNyb3NzIG1vc3QgTGludXggc3lzdGVtcyAoYW5kIE1hY09TKS4gTWFueSBpbnRlZ3JhdGVkIGRldmVsb3BtZW50IGVudmlyb25tZW50cyAoc3VjaCBhcyBFY2xpcHNlKSB1c2Ugc29tZSB2ZXJzaW9uIG9mIGEgKm1ha2UqIGZhY2lsaXR5IGFsdGhvdWdoIHRoZXkgb2Z0ZW4gdXNlIFhNTCB0byBzcGVjaWZ5IGRlcGVuZGVuY2llcyByYXRoZXIgdGhhbiBhIHRyYWRpdGlvbmFsIG1ha2VmaWxlLCBvZnRlbiB1c2luZyB0aGUgdXRpbGl0eSAqYW50KiByYXRoZXIgdGhhbiAqbWFrZSouDQoNCiMjIyBXaHkgVXNlIE1ha2U/DQoNClRoZXJlIGFyZSBtYW55IHJlYXNvbnMgd2h5ICptYWtlKiBpcyBzbyB3aWRlbHkgdXNlZC4gV2Ugd2lsbCB0YWtlIGEgbG9vayBhdCBhIGZldyByZWFzb25zIGJlbG93Lg0KDQojIyMjIERlcGVuZGVuY3kgTWFuYWdlbWVudA0KDQpPbmUgb2YgdGhlIHByaW1hcnkgcmVhc29ucyBmb3IgdXNpbmcgYG1ha2VgIGlzIGl0cyBhYmlsaXR5IHRvIG1hbmFnZSBkZXBlbmRlbmNpZXMgZWZmaWNpZW50bHkuIEluIGEgdHlwaWNhbCBzb2Z0d2FyZSBwcm9qZWN0LCB5b3UgaGF2ZSBzb3VyY2UgZmlsZXMgdGhhdCBkZXBlbmQgb24gZWFjaCBvdGhlciwgY29uZmlndXJhdGlvbiBmaWxlcywgbGlicmFyaWVzLCBhbmQgb3RoZXIgcmVzb3VyY2VzLiBgbWFrZWAgdHJhY2tzIHRoZXNlIGRlcGVuZGVuY2llcyBhbmQgZW5zdXJlcyB0aGF0IG9ubHkgdGhlIG5lY2Vzc2FyeSBwYXJ0cyBvZiB5b3VyIHByb2plY3QgYXJlIHJlYnVpbHQgd2hlbiBzb21ldGhpbmcgY2hhbmdlcy4gVGhpcyBmZWF0dXJlIHNhdmVzIHRpbWUgYW5kIHByZXZlbnRzIHVubmVjZXNzYXJ5IHJlY29tcGlsYXRpb24uDQoNCiMjIyMgQXV0b21hdGlvbg0KDQpNYWtlIGF1dG9tYXRlcyByZXBldGl0aXZlIGFuZCBlcnJvci1wcm9uZSB0YXNrcyBpbnZvbHZlZCBpbiB0aGUgYnVpbGQgcHJvY2Vzcy4gSW5zdGVhZCBvZiBtYW51YWxseSB0eXBpbmcgb3V0IGxvbmcgY29tcGlsYXRpb24gY29tbWFuZHMsIGxpbmtpbmcgc3RlcHMsIGFuZCBvdGhlciB0YXNrcywgeW91IGRlZmluZSBydWxlcyBhbmQgbGV0IGBtYWtlYCBoYW5kbGUgdGhlIGRldGFpbHMuIFRoaXMgbm90IG9ubHkgcmVkdWNlcyB0aGUgY2hhbmNlcyBvZiBodW1hbiBlcnJvciBidXQgYWxzbyBtYWtlcyB5b3VyIGJ1aWxkIHByb2Nlc3MgY29uc2lzdGVudCBhbmQgcmVwcm9kdWNpYmxlLg0KDQojIyMjIFBvcnRhYmlsaXR5DQoNCmBtYWtlYCBpcyBwbGF0Zm9ybS1pbmRlcGVuZGVudCwgd2hpY2ggbWVhbnMgeW91IGNhbiB1c2UgdGhlIHNhbWUgTWFrZWZpbGUgKHRoZSBjb25maWd1cmF0aW9uIGZpbGUgZm9yIGBtYWtlYCkgb24gZGlmZmVyZW50IG9wZXJhdGluZyBzeXN0ZW1zLiBUaGlzIHBvcnRhYmlsaXR5IG1ha2VzIGl0IGFuIGF0dHJhY3RpdmUgY2hvaWNlIGZvciBjcm9zcy1wbGF0Zm9ybSBkZXZlbG9wbWVudC4NCg0KIyMjIyBDdXN0b21pemF0aW9uDQoNCk1ha2UgaXMgaGlnaGx5IGN1c3RvbWl6YWJsZS4gWW91IGNhbiB0YWlsb3IgeW91ciBidWlsZCBwcm9jZXNzIHRvIHN1aXQgeW91ciBwcm9qZWN0J3Mgc3BlY2lmaWMgcmVxdWlyZW1lbnRzLiBEZWZpbmUgdmFyaWFibGVzLCBydWxlcywgYW5kIHRhcmdldHMgaW4geW91ciBNYWtlZmlsZSB0byBhY2NvbW1vZGF0ZSBkaWZmZXJlbnQgYnVpbGQgY29uZmlndXJhdGlvbnMsIGRldmVsb3BtZW50IGVudmlyb25tZW50cywgb3IgZGVwbG95bWVudCBwbGF0Zm9ybXMuDQoNCiMjIyBXaGVuIHRvIFVzZSBNYWtlDQoNCllvdSBzaG91bGQgY29uc2lkZXIgdXNpbmcgYG1ha2VgIHdoZW46DQoNCi0gICBZb3UncmUgd29ya2luZyBvbiBhIHByb2plY3Qgd2l0aCBtdWx0aXBsZSBzb3VyY2UgZmlsZXMgdGhhdCBuZWVkIHRvIGJlIGNvbXBpbGVkIGFuZCBsaW5rZWQuDQotICAgWW91IHdhbnQgdG8gYXV0b21hdGUgcmVwZXRpdGl2ZSB0YXNrcyBzdWNoIGFzIGJ1aWxkaW5nLCB0ZXN0aW5nLCBhbmQgY2xlYW5pbmcgeW91ciBwcm9qZWN0Lg0KLSAgIFlvdSBuZWVkIGEgdG9vbCB0aGF0IG1hbmFnZXMgZGVwZW5kZW5jaWVzIGFuZCBlbnN1cmVzIHRoYXQgb25seSBuZWNlc3NhcnkgcGFydHMgb2YgdGhlIHByb2plY3QgYXJlIHJlYnVpbHQuDQotICAgWW91ciBwcm9qZWN0IG5lZWRzIHRvIGJlIGNyb3NzLXBsYXRmb3JtLCBhbmQgeW91IHdhbnQgYSBidWlsZCBzeXN0ZW0gdGhhdCB3b3JrcyBjb25zaXN0ZW50bHkgb24gZGlmZmVyZW50IG9wZXJhdGluZyBzeXN0ZW1zLg0KLSAgIFlvdSB2YWx1ZSBhIGhpZ2ggZGVncmVlIG9mIGN1c3RvbWl6YXRpb24gYW5kIGNvbnRyb2wgb3ZlciB0aGUgYnVpbGQgcHJvY2Vzcy4NCg0KSW4gc2hvcnQsIGBtYWtlYCBpcyBhIGZ1bmRhbWVudGFsIHRvb2wgZm9yIHByb2dyYW1tZXJzIGFuZCBzb2Z0d2FyZSBkZXZlbG9wZXJzLiBJdCBzdHJlYW1saW5lcyB0aGUgYnVpbGQgcHJvY2VzcywgbWFuYWdlcyBkZXBlbmRlbmNpZXMsIGFuZCBhdXRvbWF0ZXMgdGFza3MsIHVsdGltYXRlbHkgbGVhZGluZyB0byBtb3JlIGVmZmljaWVudCBhbmQgbWFpbnRhaW5hYmxlIHNvZnR3YXJlIGRldmVsb3BtZW50IHByb2plY3RzLiBJbiB0aGUgZm9sbG93aW5nIHNlY3Rpb25zIG9mIHRoaXMgdHV0b3JpYWwsIHdlIHdpbGwgZGl2ZSBkZWVwZXIgaW50byBob3cgdG8gdXNlIGBtYWtlYCBlZmZlY3RpdmVseSB0byBtYW5hZ2UgeW91ciBwcm9qZWN0cy4NCg0KIyMjIE1ha2VmaWxlcw0KDQpNYWtlZmlsZXMgYXJlIGFuIGltcG9ydGFudCBlbGVtZW50IG9mIHByb2dyYW1taW5nLCBlc3BlY2lhbGx5IGluIEMgYW5kIEMrKyBvbiBVbml4LCBhbHRob3VnaCB0aGV5IGNhbiBiZSBmb3VuZCBvbiBvdGhlciBwbGF0Zm9ybXMgYW5kIGZvciBvdGhlciBwdXJwb3NlcyBhcyB3ZWxsLiBFc3NlbnRpYWxseSwgbWFrZWZpbGVzIGFyZSB0ZXh0IGZpbGVzIGNvbnRhaW5pbmcgdGhlIHJ1bGVzIG9uIGhvdyBhbiBleGVjdXRhYmxlIHByb2dyYW0gaXMgY3JlYXRlZCBmcm9tIGl0cyBzb3VyY2UgZmlsZXMgYW5kIGluY2x1ZGVkIGxpYnJhcmllcy4gQSBtYWtlZmlsZSBzZXJ2ZXMgYXMgdGhlIGlucHV0IHRvIHRoZSAqbWFrZSogcHJvZ3JhbSB3aGljaCByZWFkIHRoZSBydWxlcyBpbiB0aGUgbWFrZWZpbGUgYW5kIHByb2R1Y2VzIGFuIGV4ZWN1dGFibGUgKHdlbGwsIGEgdGFyZ2V0LCB0byBiZSBzcGVjaWZpYywgd2hpY2ggaXMgbW9zdCBvZnRlbiBhbiBleGVjdXRhYmxlIGJ1dCBkb2Vzbid0IGhhdmUgdG8gYmUpLiAqbWFrZSogYXBwbGllcyB0aGUgcnVsZXMgYW5kIG9ubHkgY29tcGlsZXMgd2hhdCBoYXMgY2hhbmdlZCBzaW5jZSB0aGUgbGFzdCAiYnVpbGQiIG9mIHRoZSBleGVjdXRhYmxlLiBUaGlzIGlzIGlkZWFsIHdoZW4gYSBwcm9qZWN0IGNvbnNpc3RzIG9mIG1hbnkgc291cmNlIGZpbGVzIGFuZCBhIGNoYW5nZSBpbiBvbmUgd291bGQgbm90IHJlcXVpcmUgY29tcGlsaW5nIGFsbC4gVW5mb3J0dW5hdGVseSwgbWFrZWZpbGVzIGFyZSBhIGJpdCBlc290ZXJpYyBhbmQgdGhlIHJ1bGVzIGNhbiBiZSBhIGJpdCBiYWZmbGluZyBub3dhZGF5cyAtLSBhZnRlciBhbGwsIHRoZXkgd2VyZSBkZXZlbG9wZWQgb3ZlciBmaWZ0eSB5ZWFycyBhZ28gd2hlbiBkZXZlbG9wbWVudCB0b29scyB3ZXJlIHF1aXRlIGRpZmZlcmVudC4NCg0KTWFrZWZpbGVzIGNvbnRhaW4gdGFyZ2V0cyBhbmQgZGVwZW5kZW5jeSBydWxlcy4gSWYgYW55IHNvdXJjZSBmaWxlJ3MgZGVwZW5kZW5jaWVzIGNoYW5nZSB0aGVuIHRoZSBzb3VyY2UgZmlsZSB3aWxsIGdldCByZS1jb21waWxlZCBhbmQgdGhlIG5ldyBleGVjdXRhYmxlIGlzIGxpbmtlZC4NCg0KIyMgQSBTaW1wbGUgRXhhbXBsZQ0KDQojIyMgUnVubmluZyAnbWFrZScNCg0KVGhlICdtYWtlJyBjb21tYW5kIGlzIHJ1biBmcm9tIHRoZSB0ZXJtaW5hbCAoKmFrYSogYSBzaGVsbCkuDQoNCmBgYCAgICAgICAgIA0KJSBtYWtlIHRhcmdldA0KYGBgDQoNCldoZW4gJ21ha2UnIGlzIHJ1biwgaXQgbG9va3MgZm9yIGEgZmlsZSBuYW1lZCAqTWFrZWZpbGUqIGluIHRoZSBjdXJyZW50IGZvbGRlci4gTm90ZSB0aGUgY2FwaXRhbGl6YXRpb24gb2YgdGhlIGZpbGUgLS0gaXQgaXMgaW1wb3J0YW50Lg0KDQpMZXQncyBkbyB0aGUgY2xhc3NpYyAiSGVsbG8gV29ybGQiIHByb2dyYW0gYXMgYSBtYWtlZmlsZS4gQmVsb3cgaXMgdGhlIGNvbnRlbnRzIG9mIGEgcmVhbGx5IHNpbXBsZSBtYWtlZmlsZSAoY2FsbGVkICpNYWtlZmlsZSopLg0KDQpgYGAgICAgICAgICANCmhlbGxvOg0KICAgIGVjaG8gIkhlbGxvLCBXb3JsZCINCmBgYA0KDQoqKkltcG9ydGFudCoqOiBSdWxlcyBtdXN0IGJlIGluZGVudGVkIGJ5IGEgVEFCIGFuZCBub3Qgc3BhY2VzLiBTbywgaGl0IHRoZSBgVEFCYCBrZXkgaW4geW91ciBrZXlib2FyZCBhbmQgZG8gbm90IHR5cGUgc3BhY2VzIHdpdGggdGhlIHNwYWNlYmFyIG9uIHlvdXIga2V5Ym9hcmQuIFRoaXMgaXMgb25lIG9mIHRoZSBtb3N0IGNvbW1vbiBtaXN0YWtlcyB0aGF0IGJlZ2lubmVycyBydW4gaW50by4NCg0KT25jZSB5b3UgaGF2ZSB0aGUgbWFrZWZpbGUsICJleGVjdXRlIGl0IiBieSBydW5uaW5nIHRoZSBgbWFrZWAgcHJvZ3JhbS4NCg0KYGBgICAgICAgICAgDQolIG1ha2UNCmBgYA0KDQpOb3Qgc3BlY2lmeWluZyBhIHRhcmdldCBmb3IgYG1ha2VgIG1lYW5zIHRoYXQgaXQgYnVpbGRzIHRoZSBmaXJzdCB0YXJnZXQgaXQgZmluZHMuDQoNCiMjIyMgVHJ5IGl0IG91dCBmb3IgeW91cnNlbGYNCg0KR28gdG8gdGhlIHRlcm1pbmFsLCBjcmVhdGUgYSBmb2xkZXIgaW4gd2hpY2ggeW91IGNhbiBkbyB0aGlzIGxlc3NvbiwgYW5kIHVzZSBhIHRleHQgZWRpdG9yICgqZS5nLiosICp2aSopIHRvIGNyZWF0ZSBhIGZpbGUgY2FsbGVkICpNYWtlZmlsZSogYW5kIGFkZCB0aGUgYWJvdmUuDQoNCiMjIyBTaW1wbGUgQnVpbGQgRmlsZSBFeGFtcGxlDQoNCk1ha2VmaWxlcyBhcmUgYnVpbGQgZmlsZXMgZm9yIHByb2plY3RzIGFuZCB0aGV5IGNvbnRhaW5zIGFsbCBjb21tYW5kIHRvIGNvbXBpbGUsIGxpbmssIGNvcHksIG9yIG1vdmUgZmlsZXMgYW5kIHJ1biBzY3JpcHRzLiBCZWxvdyBpcyBhIHNpbXBsZSBleGFtcGxlLg0KDQpgYGAge2F0dHIuc291cmNlPSIubnVtYmVyTGluZXMifQ0KYWxsOiBtdWx0aXRocmVhZA0KDQptdWx0aXRocmVhZDogbXVsdGl0aHJlYWQuYw0KICAgIGdjYyAtbyBtdWx0aXRocmVhZCBtdWx0aXRocmVhZC5jDQpgYGANCg0KQWdhaW4sIGp1c3QgYXMgYSByZW1pbmRlcjogdGhlIGluZGVudCBiZWZvcmUgKmdjYyogaXMgYSBUQUIgYW5kIG5vdCBzcGFjZXMuDQoNCkdlbmVyYWxseSBtYWtlZmlsZXMgY29udGFpbiBhIHRhcmdldCBuYW1lZCAqYWxsKiB0aGF0IGJ1aWxkcyB0aGUgZW50aXJlIHByb2plY3QuIEl0IGluY2x1ZGVzIGFsbCBvZiB0aGUgc3ViIHRhcmdldHMsIHN1Y2ggYXMgaW5kaXZpZHVhbCBleGVjdXRhYmxlcywgdGVzdCBkcml2ZXJzLCBpbnN0YWxsYXRpb24gc2NyaXB0cywgYW5kIHNvIGZvcnRoLg0KDQpTbywgaW4gdGhlIGFib3ZlIGV4YW1wbGUsICphbGwqIGRlcGVuZHMgb24gKm11bHRpdGhyZWFkKiB0byBiZSB1cC10by1kYXRlLCB3aGljaCwgaW4gdHVybiwgZGVwZW5kcyBvbiAqbXVsdGl0aHJlYWQuYyouIFNvLCBpZiAqbXVsdGl0aHJlYWQuYyogY2hhbmdlcywgdGhlbiBpdCBmb3JjZXMgdGhlIHJ1bGVzIHRvIGJlIGFwcGxpZWQgYW5kIGFueSBjb21tYW5kcyBiZWxvdyB0aGF0IHJ1bGUgYXJlIHJ1bi4gSW4gdGhlIGFib3ZlIGV4YW1wbGUsIHRoYXQgd291bGQgYmUgdGhlIGNvbXBpbGF0aW9uIGFuZCBsaW5raW5nIHdpdGggKmdjYyouDQoNClRvIGluaXRpYXRlIHRoZSBmdWxsIGJ1aWxkLCBjYWxsIGBtYWtlIGFsbGAgb3Igc2ltcGx5IGBtYWtlYCBhcyAqYWxsKiBpcyB0aGUgZmlyc3QgdGFyZ2V0Lg0KDQojIyMgTWFrZWZpbGUgU3RydWN0dXJlIGFuZCBTeW50YXgNCg0KQSBNYWtlZmlsZSBjb25zaXN0cyBvZiBhIHNldCBvZiBydWxlcy4gQSBydWxlIGdlbmVyYWxseSBsb29rcyBsaWtlIHRoaXM6DQoNCmBgYCAgICAgICAgIA0KdGFyZ2V0OiBwcmVyZXF1aXNpdGVzDQogICAgY29tbWFuZA0KICAgIGNvbW1hbmQNCiAgICBjb21tYW5kDQpgYGANCg0KVGhlIGNvbW1hbmRzIGFyZSB0aGUgc3RlcHMgcmVxdWlyZWQgdG8gYnVpbGQgdGhlIHRhcmdldC4gVGhlc2UgbmVlZCB0byBzdGFydCB3aXRoIGEgYHRhYmAgY2hhcmFjdGVyIGFuZCBub3Qgc3BhY2VzLiBUaGUgcHJlcmVxdWlzaXRlcyBhcmUgZ2VuZXJhbGx5IGZpbGUgbmFtZXMsIHNlcGFyYXRlZCBieSBzcGFjZXMuIFRoZXNlIGZpbGVzIG5lZWQgdG8gZXhpc3QgYmVmb3JlIHRoZSBjb21tYW5kcyBmb3IgdGhlIHRhcmdldCBhcmUgcnVuLiBUaGV5IGRlZmluZSBkZXBlbmRlbmNpZXMuDQoNCiMjIyBUYXJnZXQgJ2NsZWFuJw0KDQpNb3N0IG1ha2VmaWxlcyBpbmNsdWRlcyBhIHJ1bGUgZm9yIGEgdGFyZ2V0IG5hbWVkICpjbGVhbiogdGhhdCBpcyBpbnZva2VkIHdpdGggYG1ha2UgY2xlYW5gLiBJdCdzIHB1cnBvc2UgaXMgdG8gY2xlYW4gdXAgeW91ciBkZXZlbG9wbWVudCBlbnZpcm9ubWVudCByZW1vdmUgdGhlIG91dHB1dCBvZiBvdGhlciB0YXJnZXRzLiBOb3RlIHRoYXQgaXMgc2hvdWxkIG5vdCBiZSB0aGUgZmlyc3QgdGFyZ2V0IGFzIGl0IHdvdWxkIHRoZW4gYmUgdGhlIGRlZmF1bHQgdGFyZ2V0OyB0aGUgZGVmYXVsdCB0YXJnZXQgc2hvdWxkIGJlICphbGwqLg0KDQpIZXJlIGlzIGFuIGV4YW1wbGUgb2YgYSAqY2xlYW4qIHRhcmdldCBmb3IgYSBzaW1wbGUgcHJvamVjdC4NCg0KYGBgICAgICAgICAgDQpjbGVhbjoNCiAgICBybSAtZiBtdWx0aXRocmVhZA0KICAgIHRvdWNoIG11bHRpdGhyZWFkLmMNCmBgYA0KDQpUaGUgcnVsZSByZW1vdmVzIHRoZSBleGVjdXRhYmxlIGFuZCB1cGRhdGVzIHRoZSB0aW1lIHN0YW1wIG9mIGxhc3QgbW9kaWZpY2F0aW9uIG9mIHRoZSBzb3VyY2UgZmlsZSB0byB0aGUgcHJlc2VudCB0aW1lLCB3aGljaCB3b3VsZCBmb3JjZSBhIHJlY29tcGlsZSB0aGUgbmV4dCB0aW1lIHlvdSBpbnZva2VkIGBtYWtlIGFsbGAuDQoNCiMjIENlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSBzZWNvbmQgc2VjdGlvbiwgIkJhc2ljIE1ha2VmaWxlIFN0cnVjdHVyZSwiIHRvIHByb3ZpZGUgYSBtb3JlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9mIHRoZSBjb21wb25lbnRzIG9mIGEgTWFrZWZpbGUgYW5kIGhvdyB0aGV5IHdvcmsgdG9nZXRoZXIuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyBCYXNpYyBNYWtlZmlsZSBTdHJ1Y3R1cmUNCg0KQSAiTWFrZWZpbGUiIGlzIGEgdGV4dCBmaWxlIHdpdGggdGhlIG5hbWUgKk1ha2VmaWxlKiAoc3BlbGxlZCBqdXN0IGxpa2UgdGhhdCB3aXRoIGEgY2FwaXRhbCAnTScpIHRoYXQgY29udGFpbnMgaW5zdHJ1Y3Rpb25zIGZvciB0aGUgYG1ha2VgIHV0aWxpdHkgb24gaG93IHRvIGJ1aWxkIGEgcHJvamVjdC4gSXQgY29uc2lzdHMgb2YgcnVsZXMgYW5kIHRhcmdldHMsIHdoaWNoIGFyZSB0aGUgYnVpbGRpbmcgYmxvY2tzIG9mIHRoZSBNYWtlZmlsZS4gSW4gdGhpcyBzZWN0aW9uLCB3ZSB3aWxsIGRlbHZlIGludG8gdGhlIGJhc2ljIHN0cnVjdHVyZSBvZiBhIE1ha2VmaWxlIGFuZCBleHBsYWluIGhvdyBpdCB3b3Jrcy4NCg0KIyMjIFJ1bGVzIGFuZCBUYXJnZXRzDQoNCiMjIyMgVGFyZ2V0cw0KDQpBICoqdGFyZ2V0KiogaW4gYSBNYWtlZmlsZSByZXByZXNlbnRzIGFuIG91dHB1dCBmaWxlIG9yIGFuIGFjdGlvbiB0aGF0IGBtYWtlYCBzaG91bGQgcGVyZm9ybS4gVGFyZ2V0cyBhcmUgdGhlIGdvYWxzIG9mIHlvdXIgYnVpbGQgcHJvY2Vzcywgc3VjaCBhcyBleGVjdXRhYmxlcywgb2JqZWN0IGZpbGVzLCBvciBvdGhlciBhcnRpZmFjdHMuIEVhY2ggdGFyZ2V0IGNvcnJlc3BvbmRzIHRvIGEgc3BlY2lmaWMgdGFzayB0aGF0IGBtYWtlYCBjYW4gZXhlY3V0ZS4NCg0KRm9yIGV4YW1wbGUsIGluIGEgQyBvciBDKysgcHJvamVjdCwgeW91IG1pZ2h0IGhhdmUgdGFyZ2V0cyBsaWtlOg0KDQotICAgYG15X3Byb2dyYW1gOiBUbyBidWlsZCB0aGUgZmluYWwgZXhlY3V0YWJsZS4NCi0gICBgbWFpbi5vYCwgYHV0aWwub2A6IFRvIGNvbXBpbGUgaW5kaXZpZHVhbCBzb3VyY2UgZmlsZXMgaW50byBvYmplY3QgZmlsZXMuDQotICAgYGNsZWFuYDogVG8gcmVtb3ZlIGdlbmVyYXRlZCBmaWxlcyBhbmQgY2xlYW4gdXAgdGhlIHByb2plY3QuDQoNCiMjIyMgUnVsZXMNCg0KQSAqKnJ1bGUqKiBkZWZpbmVzIGhvdyB0byBjcmVhdGUgYSB0YXJnZXQgZnJvbSBpdHMgZGVwZW5kZW5jaWVzLiBJdCBjb25zaXN0cyBvZiBhIHRhcmdldCwgYSBjb2xvbiAoYDpgKSwgYW5kIGEgbGlzdCBvZiBkZXBlbmRlbmNpZXMuIEJlbG93IHRoZSBydWxlLCB5b3Ugc3BlY2lmeSB0aGUgY29tbWFuZHMgbmVlZGVkIHRvIGJ1aWxkIHRoZSB0YXJnZXQgZnJvbSBpdHMgZGVwZW5kZW5jaWVzLiBUaGVzZSBjb21tYW5kcyBhcmUgdHlwaWNhbGx5IGluZGVudGVkIHVzaW5nIHRhYnMuDQoNCkhlcmUncyBhIGJhc2ljIHJ1bGUgc3RydWN0dXJlOg0KDQpgYGAgbWFrZQ0KdGFyZ2V0OiBkZXBlbmRlbmNpZXMNCiAgICBbY29tbWFuZHNdDQpgYGANCg0KLSAgICoqVGFyZ2V0Kio6IFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgeW91IHdhbnQgdG8gYnVpbGQuDQotICAgKipEZXBlbmRlbmNpZXMqKjogVGhlIGZpbGVzIG9yIHRhcmdldHMgdGhhdCB0aGUgY3VycmVudCB0YXJnZXQgZGVwZW5kcyBvbi4gVGhlc2UgcmVwcmVzZW50IHRoZSBwcmVyZXF1aXNpdGVzIGZvciBidWlsZGluZyB0aGUgdGFyZ2V0Lg0KLSAgICoqQ29tbWFuZHMqKjogVGhlIHNoZWxsIGNvbW1hbmRzIHRvIGJlIGV4ZWN1dGVkIHdoZW4gYG1ha2VgIGJ1aWxkcyB0aGUgdGFyZ2V0LiBUaGVzZSBjb21tYW5kcyBhcmUgaW5kZW50ZWQgd2l0aCB0YWJzLg0KDQojIyMgRXhhbXBsZSBNYWtlZmlsZQ0KDQpMZXQncyBjcmVhdGUgYSBzaW1wbGUgTWFrZWZpbGUgdG8gY29tcGlsZSBhICJIZWxsbywgV29ybGQhIiBwcm9ncmFtIHdyaXR0ZW4gaW4gQy4NCg0KYGBgIG1ha2UNCiMgRGVmaW5lIHRoZSB0YXJnZXQgYW5kIGl0cyBkZXBlbmRlbmNpZXMNCm15X3Byb2dyYW06IG1haW4ubw0KDQojIENvbXBpbGUgdGhlIHByb2dyYW0NCm1haW4ubzogbWFpbi5jDQogICAgZ2NjIC1vIG1haW4ubyAtYyBtYWluLmMNCg0KIyBDbGVhbiB1cCBnZW5lcmF0ZWQgZmlsZXMNCmNsZWFuOg0KICAgIHJtIC1mIG15X3Byb2dyYW0gbWFpbi5vDQpgYGANCg0KSW4gdGhpcyBNYWtlZmlsZToNCg0KLSAgIGBteV9wcm9ncmFtYCBpcyB0aGUgdGFyZ2V0LCBhbmQgaXQgZGVwZW5kcyBvbiBgbWFpbi5vYC4NCi0gICBgbWFpbi5vYCBpcyBhbm90aGVyIHRhcmdldCwgd2hpY2ggZGVwZW5kcyBvbiBgbWFpbi5jYC4NCi0gICBUaGUgYGdjY2AgY29tbWFuZCBpcyB1c2VkIHRvIGNvbXBpbGUgYG1haW4uY2AgaW50byBhbiBvYmplY3QgZmlsZSAoYG1haW4ub2ApLg0KLSAgIFRoZSBgY2xlYW5gIHRhcmdldCBpcyB1c2VkIHRvIHJlbW92ZSB0aGUgZ2VuZXJhdGVkIGZpbGVzIHdoZW4geW91IHJ1biBgbWFrZSBjbGVhbmAuDQoNCiMjIyBIb3cgYG1ha2VgIFdvcmtzDQoNCldoZW4geW91IHJ1biBgbWFrZWAgaW4gdGhlIGNvbW1hbmQgbGluZSB3aXRob3V0IHNwZWNpZnlpbmcgYSB0YXJnZXQsIGl0IGxvb2tzIGZvciBhIHNwZWNpYWwgdGFyZ2V0IGNhbGxlZCB0aGUgKipkZWZhdWx0IHRhcmdldCoqLiBCeSBjb252ZW50aW9uLCB0aGlzIGlzIG9mdGVuIG5hbWVkIGBhbGxgLiBJZiB5b3UgaGF2ZSBhbiBgYWxsYCB0YXJnZXQgaW4geW91ciBNYWtlZmlsZSwgYG1ha2VgIHdpbGwgZXhlY3V0ZSB0aGUgY29tbWFuZHMgYXNzb2NpYXRlZCB3aXRoIHRoYXQgdGFyZ2V0Lg0KDQpGb3IgZXhhbXBsZToNCg0KYGBgIG1ha2UNCmFsbDogbXlfcHJvZ3JhbQ0KYGBgDQoNCldoZW4geW91IHJ1biBgbWFrZWAgd2l0aG91dCBhcmd1bWVudHMsIGl0IHdpbGwgZXhlY3V0ZSB0aGUgYGFsbGAgdGFyZ2V0LCB3aGljaCBkZXBlbmRzIG9uIGBteV9wcm9ncmFtYC4gVGh1cywgaXQgd2lsbCBidWlsZCBgbXlfcHJvZ3JhbWAgYW5kIGl0cyBkZXBlbmRlbmNpZXMuDQoNClRvIHN1bW1hcml6ZSwgYSBNYWtlZmlsZSBjb25zaXN0cyBvZiBydWxlcyBhbmQgdGFyZ2V0cy4gUnVsZXMgc3BlY2lmeSBob3cgdG8gYnVpbGQgdGFyZ2V0cyBmcm9tIHRoZWlyIGRlcGVuZGVuY2llcy4gV2hlbiB5b3UgcnVuIGBtYWtlYCwgaXQgcmVhZHMgdGhlIE1ha2VmaWxlLCBkZXRlcm1pbmVzIHdoaWNoIHRhcmdldHMgbmVlZCB0byBiZSBidWlsdCBvciByZWJ1aWx0IGJhc2VkIG9uIGZpbGUgdGltZXN0YW1wcyBhbmQgZGVwZW5kZW5jaWVzLCBhbmQgdGhlbiBleGVjdXRlcyB0aGUgY29ycmVzcG9uZGluZyBjb21tYW5kcy4gVW5kZXJzdGFuZGluZyB0aGlzIGJhc2ljIHN0cnVjdHVyZSBpcyBjcnVjaWFsIGZvciBjcmVhdGluZyBtb3JlIGNvbXBsZXggYW5kIGVmZmljaWVudCBNYWtlZmlsZXMgZm9yIHlvdXIgcHJvamVjdHMuDQoNCkNlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSB0aGlyZCBzZWN0aW9uLCAiTWFrZWZpbGUgUnVsZXMgYW5kIFRhcmdldHMsIiB0byBwcm92aWRlIGEgbW9yZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvZiBydWxlcywgdGFyZ2V0cywgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZSBpbiBNYWtlZmlsZXMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyAzLiBNYWtlZmlsZSBSdWxlcyBhbmQgVGFyZ2V0cw0KDQpJbiB0aGUgY29udGV4dCBvZiBgbWFrZWAsIHJ1bGVzIGFuZCB0YXJnZXRzIGFyZSBmdW5kYW1lbnRhbCBjb25jZXB0cyB0aGF0IGRlZmluZSBob3cgeW91ciBwcm9qZWN0J3MgYnVpbGQgcHJvY2VzcyB3b3Jrcy4gVW5kZXJzdGFuZGluZyBob3cgdG8gc3RydWN0dXJlIGFuZCB1c2UgdGhlbSBlZmZlY3RpdmVseSBpbiBNYWtlZmlsZXMgaXMgY3J1Y2lhbCBmb3IgYXV0b21hdGluZyB0YXNrcyBhbmQgbWFuYWdpbmcgZGVwZW5kZW5jaWVzLg0KDQojIyMgMy4xIFRhcmdldHMNCg0KKipUYXJnZXRzKiogaW4gYSBNYWtlZmlsZSByZXByZXNlbnQgdGhlIGFydGlmYWN0cyBvciBhY3Rpb25zIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlIG9yIHBlcmZvcm0uIFRhcmdldHMgYXJlIHRoZSBmb2NhbCBwb2ludHMgb2YgeW91ciBidWlsZCBwcm9jZXNzLCBhbmQgdGhleSBjYW4gaW5jbHVkZToNCg0KLSAgIEV4ZWN1dGFibGUgcHJvZ3JhbXMuDQotICAgT2JqZWN0IGZpbGVzIChjb21waWxlZCBzb3VyY2UgZmlsZXMpLg0KLSAgIERvY3VtZW50YXRpb24uDQotICAgRGlzdHJpYnV0aW9uIHBhY2thZ2VzLg0KLSAgIEN1c3RvbSB0YXNrcyBsaWtlIGNsZWFuaW5nIG9yIHRlc3RpbmcuDQoNCkVhY2ggdGFyZ2V0IGNvcnJlc3BvbmRzIHRvIGEgc3BlY2lmaWMgdGFzayBvciBvdXRwdXQgdGhhdCBgbWFrZWAgc2hvdWxkIGdlbmVyYXRlLiBUYXJnZXRzIGNhbiBiZSBjcmVhdGVkIGJ5IGRlZmluaW5nIHRoZWlyIG5hbWVzIGluIHlvdXIgTWFrZWZpbGUuDQoNCiMjIyMgMy4xLjEgRXhhbXBsZSBUYXJnZXRzDQoNCkluIGEgQy9DKysgcHJvamVjdCwgeW91IG1pZ2h0IGRlZmluZSB0YXJnZXRzIGxpa2U6DQoNCi0gICBgbXlfcHJvZ3JhbWA6IFRvIGJ1aWxkIHRoZSBmaW5hbCBleGVjdXRhYmxlLg0KLSAgIGBtYWluLm9gLCBgdXRpbC5vYDogVG8gY29tcGlsZSBpbmRpdmlkdWFsIHNvdXJjZSBmaWxlcyBpbnRvIG9iamVjdCBmaWxlcy4NCi0gICBgY2xlYW5gOiBUbyByZW1vdmUgZ2VuZXJhdGVkIGZpbGVzIGFuZCBjbGVhbiB1cCB0aGUgcHJvamVjdC4NCg0KIyMjIDMuMiBSdWxlcw0KDQoqKlJ1bGVzKiogaW4gYSBNYWtlZmlsZSBkZWZpbmUgaG93IHRvIGNyZWF0ZSBhIHRhcmdldCBmcm9tIGl0cyBkZXBlbmRlbmNpZXMuIEEgcnVsZSBjb25zaXN0cyBvZiB0aHJlZSBtYWluIHBhcnRzOg0KDQoxLiAgKipUYXJnZXQqKjogVGhlIG5hbWUgb2YgdGhlIHRhcmdldCB0aGF0IHlvdSB3YW50IHRvIGJ1aWxkLg0KMi4gICoqRGVwZW5kZW5jaWVzKio6IFRoZSBmaWxlcyBvciB0YXJnZXRzIHRoYXQgdGhlIGN1cnJlbnQgdGFyZ2V0IGRlcGVuZHMgb24uIFRoZXNlIHJlcHJlc2VudCB0aGUgcHJlcmVxdWlzaXRlcyBmb3IgYnVpbGRpbmcgdGhlIHRhcmdldC4NCjMuICAqKkNvbW1hbmRzKio6IFRoZSBzaGVsbCBjb21tYW5kcyB0byBiZSBleGVjdXRlZCB3aGVuIGBtYWtlYCBidWlsZHMgdGhlIHRhcmdldCBmcm9tIGl0cyBkZXBlbmRlbmNpZXMuIFRoZXNlIGNvbW1hbmRzIGFyZSB0eXBpY2FsbHkgaW5kZW50ZWQgd2l0aCB0YWJzLg0KDQojIyMjIDMuMi4xIEV4YW1wbGUgUnVsZSBTdHJ1Y3R1cmUNCg0KSGVyZSdzIHRoZSBzdHJ1Y3R1cmUgb2YgYSBydWxlOg0KDQpgYGAgbWFrZQ0KdGFyZ2V0OiBkZXBlbmRlbmNpZXMNCiAgICBbY29tbWFuZHNdDQpgYGANCg0KIyMjIyAzLjIuMiBFeGFtcGxlIFJ1bGUNCg0KQ29uc2lkZXIgYSBzaW1wbGUgcnVsZSB0byBjb21waWxlIGEgQyBzb3VyY2UgZmlsZSBpbnRvIGFuIG9iamVjdCBmaWxlOg0KDQpgYGAgbWFrZQ0KbWFpbi5vOiBtYWluLmMNCiAgICBnY2MgLW8gbWFpbi5vIC1jIG1haW4uYw0KYGBgDQoNCkluIHRoaXMgcnVsZToNCg0KLSAgICoqYG1haW4ub2AqKiBpcyB0aGUgdGFyZ2V0IHdlIHdhbnQgdG8gYnVpbGQuDQotICAgKipgbWFpbi5jYCoqIGlzIHRoZSBkZXBlbmRlbmN5IChzb3VyY2UgZmlsZSkgdGhhdCBgbWFpbi5vYCBkZXBlbmRzIG9uLg0KLSAgIFRoZSBjb21tYW5kIGBnY2MgLW8gbWFpbi5vIC1jIG1haW4uY2AgaXMgZXhlY3V0ZWQgdG8gYnVpbGQgYG1haW4ub2AgZnJvbSBgbWFpbi5jYC4NCg0KIyMjIDMuMyBQcmFjdGljYWwgVXNhZ2UNCg0KTWFrZWZpbGVzIGJlY29tZSBwb3dlcmZ1bCB3aGVuIHlvdSBoYXZlIG11bHRpcGxlIHJ1bGVzIGFuZCB0YXJnZXRzLCBhbmQgdGhleSBoZWxwIHlvdSBhdXRvbWF0ZSBjb21wbGV4IGJ1aWxkIHByb2Nlc3Nlcy4gSGVyZSBhcmUgc29tZSBwcmFjdGljYWwgdGlwczoNCg0KIyMjIyAzLjMuMSBCdWlsZGluZyBBbGwgVGFyZ2V0cw0KDQpCeSBjb252ZW50aW9uLCB5b3UgY2FuIGNyZWF0ZSBhbiBgYWxsYCB0YXJnZXQgdGhhdCBkZXBlbmRzIG9uIGFsbCB0aGUgbWFpbiB0YXJnZXRzIGluIHlvdXIgcHJvamVjdC4gV2hlbiB5b3UgcnVuIGBtYWtlYCwgaXQgYnVpbGRzIHRoZSBgYWxsYCB0YXJnZXQsIHdoaWNoIGluIHR1cm4gYnVpbGRzIGV2ZXJ5dGhpbmcgZWxzZS4gRm9yIGV4YW1wbGU6DQoNCmBgYCBtYWtlDQphbGw6IG15X3Byb2dyYW0NCg0KbXlfcHJvZ3JhbTogbWFpbi5vIHV0aWwubw0KICAgIGdjYyAtbyBteV9wcm9ncmFtIG1haW4ubyB1dGlsLm8NCg0KbWFpbi5vOiBtYWluLmMNCiAgICBnY2MgLW8gbWFpbi5vIC1jIG1haW4uYw0KDQp1dGlsLm86IHV0aWwuYw0KICAgIGdjYyAtbyB1dGlsLm8gLWMgdXRpbC5jDQpgYGANCg0KIyMjIyAzLjMuMiBDbGVhbmluZyBVcA0KDQpBIGBjbGVhbmAgdGFyZ2V0IGlzIGhhbmR5IGZvciByZW1vdmluZyBnZW5lcmF0ZWQgZmlsZXMgYW5kIGNsZWFuaW5nIHVwIHlvdXIgcHJvamVjdC4gRm9yIGV4YW1wbGU6DQoNCmBgYCBtYWtlDQpjbGVhbjoNCiAgICBybSAtZiBteV9wcm9ncmFtIG1haW4ubyB1dGlsLm8NCmBgYA0KDQojIyMjIDMuMy4zIERlZmF1bHQgVGFyZ2V0DQoNCllvdSBjYW4gc3BlY2lmeSBhIGRlZmF1bHQgdGFyZ2V0IGJ5IGluY2x1ZGluZyBpdCBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgTWFrZWZpbGUuIEZvciBleGFtcGxlOg0KDQpgYGAgbWFrZQ0KLkRFRkFVTFRfR09BTCA6PSBhbGwNCmBgYA0KDQpUaGlzIHNldHMgdGhlIGBhbGxgIHRhcmdldCBhcyB0aGUgZGVmYXVsdCwgc28gcnVubmluZyBgbWFrZWAgd2l0aG91dCBhbnkgYXJndW1lbnRzIHdpbGwgYnVpbGQgYGFsbGAuDQoNCiMjIyMgMy4zLjQgUGhvbnkgVGFyZ2V0cw0KDQpQaG9ueSB0YXJnZXRzIGFyZSB0YXJnZXRzIHRoYXQgZG9uJ3QgcmVwcmVzZW50IGFjdHVhbCBmaWxlcy4gVGhleSBhcmUgdXNlZCBmb3IgdGFza3MgbGlrZSBjbGVhbmluZywgdGVzdGluZywgb3IgZG9jdW1lbnRhdGlvbiBnZW5lcmF0aW9uLiBUbyBkZWNsYXJlIGEgdGFyZ2V0IGFzIHBob255LCB1c2UgdGhlIGAuUEhPTllgIHNwZWNpYWwgdGFyZ2V0LiBGb3IgZXhhbXBsZToNCg0KYGBgIG1ha2UNCi5QSE9OWTogY2xlYW4gdGVzdCBkb2NzDQoNCmNsZWFuOg0KICAgIHJtIC1mIG15X3Byb2dyYW0gbWFpbi5vIHV0aWwubw0KDQp0ZXN0Og0KICAgIC4vcnVuX3Rlc3RzLnNoDQoNCmRvY3M6DQogICAgZG94eWdlbg0KYGBgDQoNCkluIHRoaXMgZXhhbXBsZSwgYGNsZWFuYCwgYHRlc3RgLCBhbmQgYGRvY3NgIGFyZSBwaG9ueSB0YXJnZXRzLg0KDQojIyMgMy40IFN1bW1hcnkNCg0KSW4gc3VtbWFyeSwgTWFrZWZpbGVzIGFyZSBjb21wb3NlZCBvZiBydWxlcyBhbmQgdGFyZ2V0cy4gUnVsZXMgc3BlY2lmeSBob3cgdG8gYnVpbGQgdGFyZ2V0cyBmcm9tIHRoZWlyIGRlcGVuZGVuY2llcywgYW5kIHRhcmdldHMgcmVwcmVzZW50IHRoZSBhcnRpZmFjdHMgb3IgYWN0aW9ucyB5b3Ugd2FudCB0byBjcmVhdGUgb3IgcGVyZm9ybS4gVW5kZXJzdGFuZGluZyB0aGUgc3RydWN0dXJlIGFuZCB1c2FnZSBvZiBydWxlcyBhbmQgdGFyZ2V0cyBpcyBlc3NlbnRpYWwgZm9yIGVmZmVjdGl2ZWx5IGF1dG9tYXRpbmcgdGFza3MgYW5kIG1hbmFnaW5nIGRlcGVuZGVuY2llcyBpbiB5b3VyIHNvZnR3YXJlIHByb2plY3RzLg0KDQpDZXJ0YWlubHksIGxldCdzIGV4cGFuZCBvbiB0aGUgZm91cnRoIHNlY3Rpb24sICJWYXJpYWJsZXMgaW4gTWFrZWZpbGVzLCIgdG8gcHJvdmlkZSBhIG1vcmUgZGV0YWlsZWQgZXhwbGFuYXRpb24gb2YgdmFyaWFibGVzIGFuZCB0aGVpciBwcmFjdGljYWwgdXNhZ2UgaW4gTWFrZWZpbGVzLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgNC4gVmFyaWFibGVzIGluIE1ha2VmaWxlcw0KDQpWYXJpYWJsZXMgcGxheSBhIGNydWNpYWwgcm9sZSBpbiBNYWtlZmlsZXMgYnkgYWxsb3dpbmcgeW91IHRvIGRlZmluZSByZXVzYWJsZSB2YWx1ZXMgdGhhdCBjYW4gYmUgdXNlZCB0aHJvdWdob3V0IHRoZSBmaWxlLiBUaGV5IGVuaGFuY2UgdGhlIHJlYWRhYmlsaXR5LCBtYWludGFpbmFiaWxpdHksIGFuZCBmbGV4aWJpbGl0eSBvZiB5b3VyIE1ha2VmaWxlcy4gSW4gdGhpcyBzZWN0aW9uLCB3ZSB3aWxsIGV4cGxvcmUgaG93IHRvIGRlY2xhcmUgYW5kIHVzZSB2YXJpYWJsZXMgZWZmZWN0aXZlbHkuDQoNCiMjIyA0LjEgRGVjbGFyaW5nIFZhcmlhYmxlcw0KDQpJbiBhIE1ha2VmaWxlLCB5b3UgY2FuIGRlY2xhcmUgdmFyaWFibGVzIHVzaW5nIHRoZSBmb2xsb3dpbmcgc3ludGF4Og0KDQpgYGAgbWFrZQ0KVkFSSUFCTEVfTkFNRSA9IHZhbHVlDQpgYGANCg0KLSAgIGBWQVJJQUJMRV9OQU1FYDogVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgdmFyaWFibGUsIHdoaWNoIHNob3VsZCBiZSB3cml0dGVuIGluIHVwcGVyY2FzZSBsZXR0ZXJzIGJ5IGNvbnZlbnRpb24uDQotICAgYHZhbHVlYDogVGhpcyBpcyB0aGUgdmFsdWUgYXNzaWduZWQgdG8gdGhlIHZhcmlhYmxlLiBJdCBjYW4gYmUgYSBzdHJpbmcsIGEgY29tbWFuZCwgb3IgYW5vdGhlciB2YXJpYWJsZS4NCg0KIyMjIDQuMiBVc2luZyBWYXJpYWJsZXMNCg0KWW91IGNhbiB1c2UgdmFyaWFibGVzIGJ5IGVuY2xvc2luZyB0aGVpciBuYW1lcyBpbiBgJCguLi4pYCBvciBgJHsuLi59YC4gRm9yIGV4YW1wbGU6DQoNCmBgYCBtYWtlDQpDQyA9IGdjYw0KQ0ZMQUdTID0gLVdhbGwgLU8yDQoNCm15X3Byb2dyYW06IG1haW4uYw0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyBteV9wcm9ncmFtIG1haW4uYw0KYGBgDQoNCkluIHRoaXMgZXhhbXBsZSwgYENDYCBhbmQgYENGTEFHU2AgYXJlIHZhcmlhYmxlcywgYW5kIHRoZWlyIHZhbHVlcyBhcmUgc3Vic3RpdHV0ZWQgd2hlbiB0aGUgYG15X3Byb2dyYW1gIHRhcmdldCBpcyBidWlsdC4NCg0KIyMjIDQuMyBWYXJpYWJsZSBUeXBlcw0KDQojIyMjIDQuMy4xIFNpbXBsZSBWYXJpYWJsZXMNCg0KU2ltcGxlIHZhcmlhYmxlcyBhcmUgZGVmaW5lZCB1c2luZyBgPWAgYXMgc2hvd24gYWJvdmUuIFRoZXkgY2FuIGJlIG92ZXJyaWRkZW4gaWYgcmVkZWZpbmVkIGxhdGVyIGluIHRoZSBNYWtlZmlsZS4NCg0KIyMjIyA0LjMuMiBSZWN1cnNpdmUgVmFyaWFibGVzDQoNClJlY3Vyc2l2ZSB2YXJpYWJsZXMgYXJlIGRlZmluZWQgdXNpbmcgYDo9YC4gVGhleSBhcmUgZXZhbHVhdGVkIG9ubHkgd2hlbiB1c2VkLCB3aGljaCBtZWFucyBjaGFuZ2VzIHRvIHRoZWlyIHZhbHVlcyBkbyBub3QgYWZmZWN0IHByZXZpb3VzIHVzYWdlcy4NCg0KYGBgIG1ha2UNClZBUiA6PSBpbml0aWFsX3ZhbHVlDQpWQVIgOj0gbmV3X3ZhbHVlICAjIERvZXMgbm90IGFmZmVjdCBwcmV2aW91cyB1c2FnZXMgb2YgVkFSDQpgYGANCg0KIyMjIyA0LjMuMyBDb25kaXRpb25hbCBWYXJpYWJsZXMNCg0KQ29uZGl0aW9uYWwgdmFyaWFibGVzIGFyZSBkZWZpbmVkIHVzaW5nIGA/PWAuIFRoZXkgYXJlIHNldCBvbmx5IGlmIHRoZSB2YXJpYWJsZSBpcyBub3QgYWxyZWFkeSBkZWZpbmVkLiBUaGlzIGlzIHVzZWZ1bCBmb3IgcHJvdmlkaW5nIGRlZmF1bHQgdmFsdWVzLg0KDQpgYGAgbWFrZQ0KVkFSID89IGRlZmF1bHRfdmFsdWUgICMgVkFSIGlzIHNldCB0byBkZWZhdWx0X3ZhbHVlIGlmIFZBUiBpcyBub3QgYWxyZWFkeSBkZWZpbmVkDQpgYGANCg0KIyMjIDQuNCBQcmFjdGljYWwgVXNhZ2UNCg0KVmFyaWFibGVzIGFyZSBiZW5lZmljaWFsIGluIE1ha2VmaWxlcyBmb3IgdmFyaW91cyByZWFzb25zOg0KDQojIyMjIDQuNC4xIENvbXBpbGVyIGFuZCBGbGFncw0KDQpZb3UgY2FuIHVzZSB2YXJpYWJsZXMgdG8gc3RvcmUgdGhlIGNvbXBpbGVyIGFuZCBjb21waWxhdGlvbiBmbGFncywgbWFraW5nIGl0IGVhc3kgdG8gY2hhbmdlIHRoZW0gZ2xvYmFsbHkgaW4geW91ciBNYWtlZmlsZToNCg0KYGBgIG1ha2UNCkNDID0gZ2NjDQpDRkxBR1MgPSAtV2FsbCAtTzINCg0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gbWFpbi5jDQpgYGANCg0KIyMjIyA0LjQuMiBGaWxlIExpc3RzDQoNClZhcmlhYmxlcyBhcmUgdXNlZnVsIGZvciBkZWZpbmluZyBsaXN0cyBvZiBmaWxlcywgZXNwZWNpYWxseSB3aGVuIHRoZXJlIGFyZSBtYW55IHNvdXJjZSBmaWxlczoNCg0KYGBgIG1ha2UNClNPVVJDRVMgPSBtYWluLmMgdXRpbC5jDQpPQkpFQ1RTID0gJChTT1VSQ0VTOi5jPS5vKQ0KDQpteV9wcm9ncmFtOiAkKE9CSkVDVFMpDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gJChPQkpFQ1RTKQ0KYGBgDQoNCkhlcmUsIGBPQkpFQ1RTYCBpcyBnZW5lcmF0ZWQgZnJvbSBgU09VUkNFU2AsIGNvbnZlcnRpbmcgYC5jYCB0byBgLm9gLg0KDQojIyMjIDQuNC4zIENvbmRpdGlvbmFsIENvbXBpbGF0aW9uDQoNClZhcmlhYmxlcyBlbmFibGUgY29uZGl0aW9uYWwgY29tcGlsYXRpb24gYmFzZWQgb24gYnVpbGQgY29uZmlndXJhdGlvbnMgb3IgdGFyZ2V0IHBsYXRmb3JtczoNCg0KYGBgIG1ha2UNCiMgQnVpbGQgYSBkZWJ1ZyB2ZXJzaW9uIHdoZW4gREVCVUcgaXMgZGVmaW5lZA0KaWZkZWYgREVCVUcNCiAgICBDRkxBR1MgKz0gLWcNCmVuZGlmDQoNCm15X3Byb2dyYW06IG1haW4uYw0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyBteV9wcm9ncmFtIG1haW4uYw0KYGBgDQoNCiMjIyMgNC40LjQgVmVyc2lvbmluZw0KDQpZb3UgY2FuIGRlZmluZSB2ZXJzaW9uIG51bWJlcnMgb3IgcHJvamVjdCBpbmZvcm1hdGlvbiBhcyB2YXJpYWJsZXMgZm9yIGVhc3kgdXBkYXRlczoNCg0KYGBgIG1ha2UNClZFUlNJT04gPSAxLjANClBST0pFQ1RfTkFNRSA9IG15X3Byb2plY3QNCg0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgJChDQykgJChDRkxBR1MpIC1vICQoUFJPSkVDVF9OQU1FKV8kKFZFUlNJT04pIG1haW4uYw0KYGBgDQoNCiMjIyA0LjUgQ29uY2x1c2lvbg0KDQpWYXJpYWJsZXMgaW4gTWFrZWZpbGVzIHByb3ZpZGUgZmxleGliaWxpdHkgYW5kIG1haW50YWluYWJpbGl0eS4gVGhleSBhbGxvdyB5b3UgdG8gZGVmaW5lIHZhbHVlcyBvbmNlIGFuZCB1c2UgdGhlbSB0aHJvdWdob3V0IHlvdXIgTWFrZWZpbGUsIG1ha2luZyBpdCBlYXNpZXIgdG8gbWFuYWdlIGJ1aWxkIGNvbmZpZ3VyYXRpb25zIGFuZCBhZGFwdCB0byBkaWZmZXJlbnQgc2NlbmFyaW9zLiBVc2luZyB2YXJpYWJsZXMgZWZmZWN0aXZlbHkgY2FuIHNpbXBsaWZ5IHRoZSBtYWludGVuYW5jZSBvZiBjb21wbGV4IHByb2plY3RzIGFuZCBtYWtlIHlvdXIgTWFrZWZpbGVzIG1vcmUgcmVhZGFibGUuDQoNCkNlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSBmaWZ0aCBzZWN0aW9uLCAiQXV0b21hdGljIFZhcmlhYmxlcywiIHRvIHByb3ZpZGUgYSBtb3JlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9mIGF1dG9tYXRpYyB2YXJpYWJsZXMgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZSBpbiBNYWtlZmlsZXMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyA1LiBBdXRvbWF0aWMgVmFyaWFibGVzIGluIE1ha2VmaWxlcw0KDQpBdXRvbWF0aWMgdmFyaWFibGVzIGFyZSBhIHNldCBvZiBwcmVkZWZpbmVkIHZhcmlhYmxlcyBpbiBNYWtlZmlsZXMgdGhhdCBzaW1wbGlmeSB0aGUgY29uc3RydWN0aW9uIG9mIHJ1bGVzIGJ5IHByb3ZpZGluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdGFyZ2V0IGFuZCBkZXBlbmRlbmNpZXMgYmVpbmcgcHJvY2Vzc2VkLiBUaGV5IGhlbHAgYXZvaWQgcmVkdW5kYW5jeSBpbiB5b3VyIE1ha2VmaWxlIGFuZCBtYWtlIGl0IG1vcmUgY29uY2lzZS4gSW4gdGhpcyBzZWN0aW9uLCB3ZSdsbCBleHBsb3JlIGNvbW1vbiBhdXRvbWF0aWMgdmFyaWFibGVzIGFuZCBob3cgdG8gdXNlIHRoZW0gZWZmZWN0aXZlbHkuDQoNCiMjIyA1LjEgQ29tbW9uIEF1dG9tYXRpYyBWYXJpYWJsZXMNCg0KIyMjIyA1LjEuMSBgJEBgIC0gVGhlIFRhcmdldA0KDQpgJEBgIHJlcHJlc2VudHMgdGhlIHRhcmdldCBvZiB0aGUgcnVsZSBiZWluZyBleGVjdXRlZC4gSXQncyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IGhhdmUgbXVsdGlwbGUgcnVsZXMgd2l0aCBzaW1pbGFyIHBhdHRlcm5zLCBhcyBpdCBhbGxvd3MgeW91IHRvIHJlZmVyZW5jZSB0aGUgdGFyZ2V0IHdpdGhvdXQgcmVwZWF0aW5nIGl0cyBuYW1lLg0KDQpFeGFtcGxlOg0KDQpgYGAgbWFrZQ0KbXlfcHJvZ3JhbTogbWFpbi5vIHV0aWwubw0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyAkQCAkXg0KYGBgDQoNCkhlcmUsIGAkQGAgaXMgcmVwbGFjZWQgd2l0aCBgbXlfcHJvZ3JhbWAsIGFuZCBgJF5gIHdpdGggYG1haW4ubyB1dGlsLm9gLg0KDQojIyMjIDUuMS4yIGAkXmAgLSBBbGwgRGVwZW5kZW5jaWVzDQoNCmAkXmAgcmVwcmVzZW50cyBhbGwgdGhlIGRlcGVuZGVuY2llcyBvZiB0aGUgcnVsZSBiZWluZyBleGVjdXRlZC4gVGhpcyBpcyBoYW5keSB3aGVuIHlvdSB3YW50IHRvIGluY2x1ZGUgYWxsIHByZXJlcXVpc2l0ZXMgaW4gYSBjb21tYW5kLg0KDQojIyMjIDUuMS4zIGAkPGAgLSBUaGUgRmlyc3QgRGVwZW5kZW5jeQ0KDQpgJDxgIHN0YW5kcyBmb3IgdGhlIGZpcnN0IGRlcGVuZGVuY3kgaW4gdGhlIGxpc3Qgb2YgcHJlcmVxdWlzaXRlcy4gSXQncyBvZnRlbiB1c2VkIHdoZW4gdGhlcmUncyBvbmx5IG9uZSBkZXBlbmRlbmN5IGFuZCB5b3Ugd2FudCB0byByZWZlcmVuY2UgaXQgZGlyZWN0bHkuDQoNCkV4YW1wbGU6DQoNCmBgYCBtYWtlDQptYWluLm86IG1haW4uYw0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyAkQCAkPA0KYGBgDQoNCkhlcmUsIGAkPGAgaXMgcmVwbGFjZWQgd2l0aCBgbWFpbi5jYC4NCg0KIyMjIyA1LjEuNCBgJD9gIC0gT3V0LW9mLURhdGUgRGVwZW5kZW5jaWVzDQoNCmAkP2AgcmVwcmVzZW50cyBhbGwgdGhlIGRlcGVuZGVuY2llcyB0aGF0IGFyZSBvdXQtb2YtZGF0ZSBjb25jZXJuaW5nIHRoZSB0YXJnZXQuIEl0J3MgdXNlZnVsIHdoZW4geW91IHdhbnQgdG8gcHJvY2VzcyBvbmx5IHRoZSBmaWxlcyB0aGF0IGhhdmUgY2hhbmdlZCBzaW5jZSB0aGUgbGFzdCBidWlsZC4NCg0KIyMjIDUuMiBQcmFjdGljYWwgVXNhZ2UNCg0KQXV0b21hdGljIHZhcmlhYmxlcyBzaW1wbGlmeSBNYWtlZmlsZSBydWxlcywgbWFraW5nIHRoZW0gbW9yZSBjb25jaXNlIGFuZCBsZXNzIGVycm9yLXByb25lLiBIZXJlIGFyZSBzb21lIHByYWN0aWNhbCBleGFtcGxlcyBvZiBob3cgdG8gdXNlIHRoZW06DQoNCiMjIyMgNS4yLjEgQnVpbGRpbmcgTXVsdGlwbGUgVGFyZ2V0cw0KDQpBdXRvbWF0aWMgdmFyaWFibGVzIGFyZSBlc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIGJ1aWxkaW5nIG11bHRpcGxlIHRhcmdldHMgZnJvbSBhIHNpbmdsZSBydWxlOg0KDQpgYGAgbWFrZQ0Kb2JqZWN0cyA9IG1haW4ubyB1dGlsLm8NCg0KYWxsOiBteV9wcm9ncmFtDQoNCm15X3Byb2dyYW06ICQob2JqZWN0cykNCiAgICAkKENDKSAkKENGTEFHUykgLW8gJEAgJF4NCg0KJChvYmplY3RzKTogJS5vOiAlLmMNCiAgICAkKENDKSAkKENGTEFHUykgLWMgLW8gJEAgJDwNCmBgYA0KDQpJbiB0aGlzIGV4YW1wbGUsIGAkQGAgYW5kIGAkXmAgYXJlIHVzZWQgdG8gc3BlY2lmeSB0aGUgdGFyZ2V0IGFuZCBkZXBlbmRlbmNpZXMgZm9yIHRoZSBgbXlfcHJvZ3JhbWAgcnVsZSwgYXMgd2VsbCBhcyBmb3IgdGhlIHBhdHRlcm4gcnVsZSB0aGF0IGNvbXBpbGVzIGAuY2AgZmlsZXMgaW50byBgLm9gIGZpbGVzLg0KDQojIyMjIDUuMi4yIENvbmRpdGlvbmFsIENvbXBpbGF0aW9uDQoNCkF1dG9tYXRpYyB2YXJpYWJsZXMgY2FuIGJlIHVzZWQgdG8gc2ltcGxpZnkgY29uZGl0aW9uYWwgY29tcGlsYXRpb24gYmFzZWQgb24gYnVpbGQgY29uZmlndXJhdGlvbnMgb3IgdGFyZ2V0IHBsYXRmb3JtczoNCg0KYGBgIG1ha2UNCkRFQlVHID89IDANCg0KaWZlcSAoJChERUJVRyksIDEpDQogICAgQ0ZMQUdTICs9IC1nDQplbmRpZg0KDQpteV9wcm9ncmFtOiBtYWluLmMNCiAgICAkKENDKSAkKENGTEFHUykgLW8gJEAgJDwNCmBgYA0KDQpIZXJlLCBgJDxgIHJlcHJlc2VudHMgdGhlIGZpcnN0IGRlcGVuZGVuY3ksIHdoaWNoIGlzIGBtYWluLmNgLiBJZiBgREVCVUdgIGlzIGRlZmluZWQgYXMgYDFgLCB0aGUgYC1nYCBmbGFnIGlzIGFkZGVkIHRvIHRoZSBjb21waWxhdGlvbiBjb21tYW5kLg0KDQojIyMjIDUuMi4zIE91dC1vZi1EYXRlIERlcGVuZGVuY2llcw0KDQpBdXRvbWF0aWMgdmFyaWFibGVzIGxpa2UgYCQ/YCBhcmUgdXNlZnVsIHdoZW4geW91IHdhbnQgdG8gcHJvY2VzcyBvbmx5IHRoZSBkZXBlbmRlbmNpZXMgdGhhdCBoYXZlIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgYnVpbGQuIEZvciBleGFtcGxlLCBpbiBhIGN1c3RvbSBidWlsZCBzY3JpcHQ6DQoNCmBgYCBtYWtlDQpnZW5lcmF0ZV9yZXNvdXJjZXM6IHJlc291cmNlX2dlbmVyYXRvcg0KICAgIC4vcmVzb3VyY2VfZ2VuZXJhdG9yIC1vICRAICQ/DQoNCnJlc291cmNlX2dlbmVyYXRvcjogcmVzb3VyY2VfZ2VuZXJhdG9yLmMNCiAgICAkKENDKSAkKENGTEFHUykgLW8gJEAgJDwNCmBgYA0KDQpJbiB0aGlzIGV4YW1wbGUsIGBnZW5lcmF0ZV9yZXNvdXJjZXNgIGRlcGVuZHMgb24gdGhlIGByZXNvdXJjZV9nZW5lcmF0b3JgIHByb2dyYW0gYW5kIGFsbCB0aGUgb3V0LW9mLWRhdGUgcmVzb3VyY2UgZmlsZXMgKGAkP2ApIHRvIGdlbmVyYXRlIG5ldyByZXNvdXJjZXMuDQoNCiMjIyA1LjMgQ29uY2x1c2lvbg0KDQpBdXRvbWF0aWMgdmFyaWFibGVzIGluIE1ha2VmaWxlcyBzaW1wbGlmeSBydWxlIGNvbnN0cnVjdGlvbiBhbmQgcmVkdWNlIHJlZHVuZGFuY3kgaW4geW91ciBidWlsZCBzY3JpcHRzLiBCeSB1c2luZyB2YXJpYWJsZXMgbGlrZSBgJEBgLCBgJF5gLCBgJDxgLCBhbmQgYCQ/YCwgeW91IGNhbiBjcmVhdGUgbW9yZSBjb25jaXNlIGFuZCBtYWludGFpbmFibGUgTWFrZWZpbGVzIHRoYXQgYWRhcHQgdG8gY2hhbmdlcyBpbiB5b3VyIHByb2plY3Qgd2l0aG91dCB0aGUgbmVlZCBmb3IgZXh0ZW5zaXZlIG1hbnVhbCBlZGl0aW5nLiBVbmRlcnN0YW5kaW5nIGFuZCB1dGlsaXppbmcgdGhlc2UgYXV0b21hdGljIHZhcmlhYmxlcyBlZmZlY3RpdmVseSBjYW4gc2lnbmlmaWNhbnRseSBlbmhhbmNlIHlvdXIgTWFrZWZpbGUtd3JpdGluZyBza2lsbHMuDQoNCkNlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSBzaXh0aCBzZWN0aW9uLCAiUGhvbnkgVGFyZ2V0cywiIHRvIHByb3ZpZGUgYSBtb3JlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9mIHBob255IHRhcmdldHMgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZSBpbiBNYWtlZmlsZXMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyA2LiBQaG9ueSBUYXJnZXRzIGluIE1ha2VmaWxlcw0KDQpJbiBNYWtlZmlsZXMsICoqcGhvbnkgdGFyZ2V0cyoqIGFyZSB0YXJnZXRzIHRoYXQgZG9uJ3QgcmVwcmVzZW50IGZpbGVzIG9yIGFydGlmYWN0cyBidXQgcmF0aGVyIHNlcnZlIGFzIGxhYmVscyBmb3Igc3BlY2lmaWMgYWN0aW9ucyBvciB0YXNrcyB0aGF0IG5lZWQgdG8gYmUgZXhlY3V0ZWQuIFBob255IHRhcmdldHMgYXJlIGVzc2VudGlhbCBmb3IgdGFza3Mgc3VjaCBhcyBjbGVhbmluZywgdGVzdGluZywgb3IgZ2VuZXJhdGluZyBkb2N1bWVudGF0aW9uLiBJbiB0aGlzIHNlY3Rpb24sIHdlIHdpbGwgZXhwbG9yZSB3aGF0IHBob255IHRhcmdldHMgYXJlIGFuZCBob3cgdG8gdXNlIHRoZW0gZWZmZWN0aXZlbHkuDQoNCiMjIyA2LjEgV2hhdCBBcmUgUGhvbnkgVGFyZ2V0cz8NCg0KUGhvbnkgdGFyZ2V0cyBhcmUgdXNlZCB0byBkZWZpbmUgYWN0aW9ucyBvciB0YXNrcyB0aGF0IGBtYWtlYCBzaG91bGQgcGVyZm9ybSB3aGVuIGV4cGxpY2l0bHkgcmVxdWVzdGVkLCBidXQgdGhleSBkb24ndCBjb3JyZXNwb25kIHRvIGFjdHVhbCBmaWxlcyBpbiB0aGUgZmlsZSBzeXN0ZW0uIFRoZXkgYXJlIGRlY2xhcmVkIGluIGEgTWFrZWZpbGUgdG8gcHJvdmlkZSBjb252ZW5pZW50IG5hbWVzIGZvciBjb21tb24gZGV2ZWxvcG1lbnQgYW5kIG1haW50ZW5hbmNlIHRhc2tzLCBhbGxvd2luZyB5b3UgdG8gZXhlY3V0ZSB0aGVzZSB0YXNrcyB1c2luZyB0aGUgYG1ha2VgIGNvbW1hbmQuDQoNClR5cGljYWxseSwgcGhvbnkgdGFyZ2V0cyBoYXZlIG5vIHByZXJlcXVpc2l0ZXMgb3IgZGVwZW5kZW5jaWVzIGJlY2F1c2UgdGhlaXIgcHVycG9zZSBpcyB0byBleGVjdXRlIGEgc3BlY2lmaWMgYWN0aW9uLCBub3QgdG8gYnVpbGQgYSBmaWxlIGJhc2VkIG9uIGRlcGVuZGVuY2llcy4NCg0KIyMjIDYuMiBEZWNsYXJpbmcgUGhvbnkgVGFyZ2V0cw0KDQpUbyBkZWNsYXJlIGEgdGFyZ2V0IGFzIHBob255LCB5b3UgdXNlIHRoZSBgLlBIT05ZYCBzcGVjaWFsIHRhcmdldCBpbiB5b3VyIE1ha2VmaWxlLCBmb2xsb3dlZCBieSBhIGxpc3Qgb2YgcGhvbnkgdGFyZ2V0IG5hbWVzLiBGb3IgZXhhbXBsZToNCg0KYGBgIG1ha2UNCi5QSE9OWTogY2xlYW4gdGVzdCBkb2NzDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB3ZSd2ZSBkZWNsYXJlZCB0aHJlZSBwaG9ueSB0YXJnZXRzOiBgY2xlYW5gLCBgdGVzdGAsIGFuZCBgZG9jc2AuIFRoZXNlIHRhcmdldHMgcmVwcmVzZW50IGNvbW1vbiBkZXZlbG9wbWVudCB0YXNrcyBzdWNoIGFzIGNsZWFuaW5nIHVwIGdlbmVyYXRlZCBmaWxlcywgcnVubmluZyB0ZXN0cywgYW5kIGdlbmVyYXRpbmcgZG9jdW1lbnRhdGlvbi4NCg0KIyMjIDYuMyBQcmFjdGljYWwgVXNhZ2UNCg0KUGhvbnkgdGFyZ2V0cyBhcmUgdmFsdWFibGUgZm9yIGF1dG9tYXRpbmcgdmFyaW91cyBkZXZlbG9wbWVudCBhbmQgbWFpbnRlbmFuY2UgdGFza3MuIEhlcmUgYXJlIHNvbWUgY29tbW9uIHVzZSBjYXNlcyBhbmQgcHJhY3RpY2FsIGV4YW1wbGVzIG9mIHBob255IHRhcmdldHM6DQoNCiMjIyMgNi4zLjEgQ2xlYW5pbmcNCg0KQSBgY2xlYW5gIHBob255IHRhcmdldCBpcyB1c2VkIHRvIHJlbW92ZSBnZW5lcmF0ZWQgZmlsZXMgYW5kIGFydGlmYWN0cyB0byBlbnN1cmUgYSBjbGVhbiBwcm9qZWN0IGRpcmVjdG9yeS4gSXQncyBlc3BlY2lhbGx5IGltcG9ydGFudCB3aGVuIHlvdSB3YW50IHRvIHJlYnVpbGQgeW91ciBwcm9qZWN0IGZyb20gc2NyYXRjaCBvciBiZWZvcmUgYXJjaGl2aW5nIG9yIGRpc3RyaWJ1dGluZyBpdC4NCg0KYGBgIG1ha2UNCi5QSE9OWTogY2xlYW4NCg0KY2xlYW46DQogICAgcm0gLWYgbXlfcHJvZ3JhbSBtYWluLm8gdXRpbC5vDQpgYGANCg0KUnVubmluZyBgbWFrZSBjbGVhbmAgd2lsbCByZW1vdmUgdGhlIGV4ZWN1dGFibGUgYG15X3Byb2dyYW1gIGFuZCB0aGUgb2JqZWN0IGZpbGVzIChgbWFpbi5vYCBhbmQgYHV0aWwub2ApIGZyb20gdGhlIHByb2plY3QgZGlyZWN0b3J5Lg0KDQojIyMjIDYuMy4yIFRlc3RpbmcNCg0KQSBgdGVzdGAgcGhvbnkgdGFyZ2V0IGlzIHVzZWQgdG8gcnVuIHlvdXIgcHJvamVjdCdzIHRlc3Qgc3VpdGUuIFRoaXMgaXMgZXNwZWNpYWxseSBoZWxwZnVsIGZvciBjb250aW51b3VzIGludGVncmF0aW9uIChDSSkgd29ya2Zsb3dzLg0KDQpgYGAgbWFrZQ0KLlBIT05ZOiB0ZXN0DQoNCnRlc3Q6DQogICAgLi9ydW5fdGVzdHMuc2gNCmBgYA0KDQpIZXJlLCBgcnVuX3Rlc3RzLnNoYCBpcyBhIHNjcmlwdCB0aGF0IGV4ZWN1dGVzIHlvdXIgcHJvamVjdCdzIHRlc3QgY2FzZXMuIFJ1bm5pbmcgYG1ha2UgdGVzdGAgd2lsbCB0cmlnZ2VyIHRoaXMgc2NyaXB0IGFuZCBleGVjdXRlIHRoZSB0ZXN0cy4NCg0KIyMjIyA2LjMuMyBHZW5lcmF0aW5nIERvY3VtZW50YXRpb24NCg0KQSBgZG9jc2AgcGhvbnkgdGFyZ2V0IGlzIHVzZWQgdG8gZ2VuZXJhdGUgcHJvamVjdCBkb2N1bWVudGF0aW9uLiBGb3IgZXhhbXBsZSwgaWYgeW91IHVzZSBEb3h5Z2VuIGZvciBkb2N1bWVudGF0aW9uIGdlbmVyYXRpb246DQoNCmBgYCBtYWtlDQouUEhPTlk6IGRvY3MNCg0KZG9jczoNCiAgICBkb3h5Z2VuDQpgYGANCg0KUnVubmluZyBgbWFrZSBkb2NzYCB3aWxsIGdlbmVyYXRlIGRvY3VtZW50YXRpb24gdXNpbmcgRG94eWdlbiBvciBhbnkgb3RoZXIgZG9jdW1lbnRhdGlvbiBnZW5lcmF0aW9uIHRvb2wgeW91IHByZWZlci4NCg0KIyMjIyA2LjMuNCBEZXBlbmRlbmN5IEFuYWx5c2lzDQoNCllvdSBjYW4gdXNlIHBob255IHRhcmdldHMgdG8gYW5hbHl6ZSBkZXBlbmRlbmNpZXMgaW4geW91ciBwcm9qZWN0LCBzdWNoIGFzIGdlbmVyYXRpbmcgZGVwZW5kZW5jeSBmaWxlcyBmb3IgQy9DKysgY29kZS4gRm9yIGluc3RhbmNlLCB1c2luZyB0aGUgR0NDIGAtTWAgZmxhZyB0byBnZW5lcmF0ZSBkZXBlbmRlbmN5IGZpbGVzOg0KDQpgYGAgbWFrZQ0KLlBIT05ZOiBkZXBlbmQNCg0KZGVwZW5kOg0KICAgIGdjYyAtTSAqLmMgPiBkZXBlbmRlbmNpZXMNCmBgYA0KDQpSdW5uaW5nIGBtYWtlIGRlcGVuZGAgd2lsbCB1cGRhdGUgdGhlIGBkZXBlbmRlbmNpZXNgIGZpbGUgd2l0aCB0aGUgbGF0ZXN0IGRlcGVuZGVuY3kgaW5mb3JtYXRpb24gZm9yIHlvdXIgcHJvamVjdC4NCg0KIyMjIDYuNCBDb25jbHVzaW9uDQoNClBob255IHRhcmdldHMgaW4gTWFrZWZpbGVzIHByb3ZpZGUgYSB3YXkgdG8gZGVmaW5lIGFuZCBhdXRvbWF0ZSBjb21tb24gZGV2ZWxvcG1lbnQgYW5kIG1haW50ZW5hbmNlIHRhc2tzLiBCeSBkZWNsYXJpbmcgcGhvbnkgdGFyZ2V0cywgeW91IGNhbiB1c2UgdGhlIGBtYWtlYCBjb21tYW5kIHRvIGV4ZWN1dGUgdGhlc2UgdGFza3MgY29udmVuaWVudGx5IHdpdGhvdXQgd29ycnlpbmcgYWJvdXQgZmlsZSBkZXBlbmRlbmNpZXMuIFRoaXMgaGVscHMgc3RyZWFtbGluZSB5b3VyIGRldmVsb3BtZW50IHdvcmtmbG93LCBtYWtpbmcgaXQgZWFzaWVyIHRvIGNsZWFuLCB0ZXN0LCBhbmQgZG9jdW1lbnQgeW91ciBwcm9qZWN0cyBlZmZpY2llbnRseS4NCg0KQ2VydGFpbmx5LCBsZXQncyBleHBhbmQgb24gdGhlIHNldmVudGggc2VjdGlvbiwgIkRlcGVuZGVuY3kgTWFuYWdlbWVudCwiIHRvIHByb3ZpZGUgYSBtb3JlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9mIGhvdyBkZXBlbmRlbmN5IG1hbmFnZW1lbnQgd29ya3MgaW4gTWFrZWZpbGVzIGFuZCBpdHMgcHJhY3RpY2FsIHVzYWdlLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgNy4gRGVwZW5kZW5jeSBNYW5hZ2VtZW50IGluIE1ha2VmaWxlcw0KDQpEZXBlbmRlbmN5IG1hbmFnZW1lbnQgaXMgYSBjcml0aWNhbCBhc3BlY3Qgb2YgTWFrZWZpbGVzLCBhcyBpdCBlbnN1cmVzIHRoYXQgYG1ha2VgIHJlYnVpbGRzIG9ubHkgdGhvc2UgdGFyZ2V0cyB0aGF0IGFyZSBvdXQtb2YtZGF0ZSBiYXNlZCBvbiBjaGFuZ2VzIGluIHRoZWlyIGRlcGVuZGVuY2llcy4gSW4gdGhpcyBzZWN0aW9uLCB3ZSB3aWxsIGRlbHZlIGRlZXBlciBpbnRvIGhvdyBkZXBlbmRlbmN5IG1hbmFnZW1lbnQgd29ya3MgYW5kIHByb3ZpZGUgcHJhY3RpY2FsIGV4YW1wbGVzLg0KDQojIyMgNy4xIERlZmluaW5nIERlcGVuZGVuY2llcw0KDQpJbiBhIE1ha2VmaWxlLCBkZXBlbmRlbmNpZXMgYXJlIHNwZWNpZmllZCBpbiB0aGUgcnVsZXMgZm9yIGVhY2ggdGFyZ2V0LiBBIHRhcmdldCBkZXBlbmRzIG9uIG9uZSBvciBtb3JlIGZpbGVzIG9yIG90aGVyIHRhcmdldHMsIGtub3duIGFzIHByZXJlcXVpc2l0ZXMuIFdoZW4gYG1ha2VgIGVuY291bnRlcnMgYSBydWxlLCBpdCBjaGVja3MgaWYgdGhlIHRhcmdldCBpcyBvbGRlciB0aGFuIGFueSBvZiBpdHMgcHJlcmVxdWlzaXRlcy4gSWYgYSBwcmVyZXF1aXNpdGUgaXMgbmV3ZXIgdGhhbiB0aGUgdGFyZ2V0IG9yIGlmIHRoZSB0YXJnZXQgZG9lc24ndCBleGlzdCwgYG1ha2VgIHJlYnVpbGRzIHRoZSB0YXJnZXQuDQoNCkhlcmUncyB0aGUgYmFzaWMgc3RydWN0dXJlIG9mIGEgcnVsZSB3aXRoIGRlcGVuZGVuY2llczoNCg0KYGBgIG1ha2UNCnRhcmdldDogZGVwZW5kZW5jaWVzDQogICAgW2NvbW1hbmRzXQ0KYGBgDQoNCiMjIyA3LjIgSG93IGBtYWtlYCBEZXRlcm1pbmVzIFdoYXQgdG8gQnVpbGQNCg0KV2hlbiB5b3UgcnVuIGBtYWtlYCwgaXQgZm9sbG93cyB0aGVzZSBzdGVwcyB0byBkZXRlcm1pbmUgd2hhdCBuZWVkcyB0byBiZSBidWlsdDoNCg0KMS4gIEl0IHJlYWRzIHRoZSBNYWtlZmlsZSB0byBidWlsZCBhIGRlcGVuZGVuY3kgZ3JhcGggdGhhdCBzaG93cyBob3cgdGFyZ2V0cyBhbmQgZGVwZW5kZW5jaWVzIGFyZSByZWxhdGVkLg0KMi4gIEl0IGNoZWNrcyB0aGUgdGltZXN0YW1wcyBvZiB0YXJnZXRzIGFuZCB0aGVpciBkZXBlbmRlbmNpZXMuDQozLiAgSWYgYSB0YXJnZXQgaXMgb2xkZXIgdGhhbiBhbnkgb2YgaXRzIGRlcGVuZGVuY2llcywgb3IgaWYgdGhlIHRhcmdldCBkb2Vzbid0IGV4aXN0LCBgbWFrZWAgZXhlY3V0ZXMgdGhlIGNvbW1hbmRzIGFzc29jaWF0ZWQgd2l0aCB0aGF0IHRhcmdldCB0byByZWJ1aWxkIGl0Lg0KNC4gIEl0IHJlY3Vyc2l2ZWx5IGJ1aWxkcyBhbnkgcHJlcmVxdWlzaXRlcyB0aGF0IGFyZSBvdXQtb2YtZGF0ZSBiZWZvcmUgYnVpbGRpbmcgdGhlIHRhcmdldC4NCg0KIyMjIDcuMyBQcmFjdGljYWwgVXNhZ2UNCg0KTGV0J3MgbG9vayBhdCBwcmFjdGljYWwgZXhhbXBsZXMgb2YgaG93IGRlcGVuZGVuY3kgbWFuYWdlbWVudCB3b3JrcyBpbiBNYWtlZmlsZXMuDQoNCiMjIyMgNy4zLjEgQy9DKysgQ29tcGlsYXRpb24NCg0KQ29uc2lkZXIgYSBzaW1wbGUgQy9DKysgcHJvamVjdCB3aXRoIG11bHRpcGxlIHNvdXJjZSBmaWxlcyBhbmQgaGVhZGVyIGZpbGVzOg0KDQpgYGAgbWFrZQ0KQ0MgPSBnY2MNCkNGTEFHUyA9IC1XYWxsIC1PMg0KDQpteV9wcm9ncmFtOiBtYWluLm8gdXRpbC5vDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gbWFpbi5vIHV0aWwubw0KDQptYWluLm86IG1haW4uYyB1dGlsLmgNCiAgICAkKENDKSAkKENGTEFHUykgLWMgLW8gbWFpbi5vIG1haW4uYw0KDQp1dGlsLm86IHV0aWwuYyB1dGlsLmgNCiAgICAkKENDKSAkKENGTEFHUykgLWMgLW8gdXRpbC5vIHV0aWwuYw0KYGBgDQoNCkluIHRoaXMgZXhhbXBsZToNCg0KLSAgIGBteV9wcm9ncmFtYCBkZXBlbmRzIG9uIGBtYWluLm9gIGFuZCBgdXRpbC5vYC4NCi0gICBgbWFpbi5vYCBkZXBlbmRzIG9uIGBtYWluLmNgIGFuZCBgdXRpbC5oYC4NCi0gICBgdXRpbC5vYCBkZXBlbmRzIG9uIGB1dGlsLmNgIGFuZCBgdXRpbC5oYC4NCg0KSWYgeW91IG1vZGlmeSBgbWFpbi5jYCBvciBgdXRpbC5jYCwgcnVubmluZyBgbWFrZWAgd2lsbCByZWJ1aWxkIG9ubHkgdGhlIGFmZmVjdGVkIG9iamVjdCBmaWxlcyBhbmQgdGhlbiByZS1saW5rIHRoZSBwcm9ncmFtLiBUaGUgZGVwZW5kZW5jaWVzIGVuc3VyZSB0aGF0IG9ubHkgdGhlIG5lY2Vzc2FyeSBwYXJ0cyBvZiB0aGUgcHJvamVjdCBhcmUgcmVidWlsdC4NCg0KIyMjIyA3LjMuMiBBdXRvbWF0aWMgRGVwZW5kZW5jeSBHZW5lcmF0aW9uDQoNCk1ha2UgY2FuIGFsc28gZ2VuZXJhdGUgZGVwZW5kZW5jeSBpbmZvcm1hdGlvbiBhdXRvbWF0aWNhbGx5IHVzaW5nIHRvb2xzIGxpa2UgYGdjYyAtTWAuIEZvciBleGFtcGxlOg0KDQpgYGAgbWFrZQ0KQ0MgPSBnY2MNCkNGTEFHUyA9IC1XYWxsIC1PMg0KDQpTT1VSQ0VTID0gbWFpbi5jIHV0aWwuYw0KT0JKRUNUUyA9ICQoU09VUkNFUzouYz0ubykNCg0KbXlfcHJvZ3JhbTogJChPQkpFQ1RTKQ0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyBteV9wcm9ncmFtICQoT0JKRUNUUykNCg0KJS5vOiAlLmMNCiAgICAkKENDKSAkKENGTEFHUykgLWMgLW8gJEAgJDwNCg0KIyBBdXRvbWF0aWNhbGx5IGdlbmVyYXRlIGRlcGVuZGVuY2llcw0KJS5kOiAlLmMNCiAgICAkKENDKSAtTSAtTVAgLU1GICRAIC1NVCAkKEA6LmQ9Lm8pICQ8DQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYCUuZGAgcnVsZSBnZW5lcmF0ZXMgZGVwZW5kZW5jeSBmaWxlcyAoYCouZGApIHRoYXQgY29udGFpbiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgaGVhZGVyIGZpbGUgZGVwZW5kZW5jaWVzIG9mIGVhY2ggc291cmNlIGZpbGUuIFRoZXNlIGRlcGVuZGVuY3kgZmlsZXMgYXJlIHRoZW4gaW5jbHVkZWQgaW4gdGhlIE1ha2VmaWxlLCBlbnN1cmluZyB0aGF0IGNoYW5nZXMgaW4gaGVhZGVyIGZpbGVzIHRyaWdnZXIgcmVjb21waWxhdGlvbi4NCg0KVG8gaW5jbHVkZSB0aGUgZ2VuZXJhdGVkIGRlcGVuZGVuY3kgZmlsZXMgaW4geW91ciBNYWtlZmlsZSwgYWRkIHRoaXMgbGluZToNCg0KYGBgIG1ha2UNCi1pbmNsdWRlICQoU09VUkNFUzouYz0uZCkNCmBgYA0KDQpUaGlzIGxpbmUgdGVsbHMgYG1ha2VgIHRvIGluY2x1ZGUgdGhlIGdlbmVyYXRlZCBgLmRgIGZpbGVzLg0KDQojIyMgNy40IENvbmNsdXNpb24NCg0KRGVwZW5kZW5jeSBtYW5hZ2VtZW50IGlzIGEgZnVuZGFtZW50YWwgYXNwZWN0IG9mIE1ha2VmaWxlcywgZW5hYmxpbmcgZWZmaWNpZW50IGFuZCBhdXRvbWF0ZWQgYnVpbGRzLiBCeSBzcGVjaWZ5aW5nIGRlcGVuZGVuY2llcyBmb3IgZWFjaCB0YXJnZXQsIHlvdSBjYW4gZW5zdXJlIHRoYXQgYG1ha2VgIHJlYnVpbGRzIG9ubHkgd2hhdCBpcyBuZWNlc3NhcnksIHJlZHVjaW5nIGJ1aWxkIHRpbWVzIGFuZCBlbnN1cmluZyBjb25zaXN0ZW5jeSBpbiB5b3VyIHByb2plY3RzLiBVbmRlcnN0YW5kaW5nIGhvdyBkZXBlbmRlbmN5IG1hbmFnZW1lbnQgd29ya3MgYW5kIGhvdyB0byB1c2UgaXQgZWZmZWN0aXZlbHkgaXMgZXNzZW50aWFsIGZvciBlZmZpY2llbnQgc29mdHdhcmUgZGV2ZWxvcG1lbnQgd29ya2Zsb3dzLg0KDQpDZXJ0YWlubHksIGxldCdzIGV4cGFuZCBvbiB0aGUgZWlnaHRoIHNlY3Rpb24sICJDb25kaXRpb25hbCBTdGF0ZW1lbnRzIGluIE1ha2VmaWxlcywiIHRvIHByb3ZpZGUgYSBtb3JlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9mIGNvbmRpdGlvbmFsIHN0YXRlbWVudHMgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZSBpbiBNYWtlZmlsZXMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyA4LiBDb25kaXRpb25hbCBTdGF0ZW1lbnRzIGluIE1ha2VmaWxlcw0KDQpDb25kaXRpb25hbCBzdGF0ZW1lbnRzIGluIE1ha2VmaWxlcyBhbGxvdyB5b3UgdG8gY3JlYXRlIHJ1bGVzIGFuZCB0YXJnZXRzIHRoYXQgdmFyeSBkZXBlbmRpbmcgb24gc3BlY2lmaWMgY29uZGl0aW9ucyBvciB2YXJpYWJsZXMuIFRoZXNlIHN0YXRlbWVudHMgZW5hYmxlIHlvdSB0byBjdXN0b21pemUgeW91ciBidWlsZCBwcm9jZXNzLCBhZGFwdCB0byBkaWZmZXJlbnQgZW52aXJvbm1lbnRzLCBvciBoYW5kbGUgdmFyaW91cyBidWlsZCBjb25maWd1cmF0aW9ucy4gSW4gdGhpcyBzZWN0aW9uLCB3ZSdsbCBleHBsb3JlIHRoZSB1c2Ugb2YgY29uZGl0aW9uYWwgc3RhdGVtZW50cyBpbiBNYWtlZmlsZXMgYW5kIHByb3ZpZGUgcHJhY3RpY2FsIGV4YW1wbGVzLg0KDQojIyMgOC4xIENvbmRpdGlvbmFsIERpcmVjdGl2ZXMNCg0KTWFrZWZpbGVzIHVzZSBjb25kaXRpb25hbCBkaXJlY3RpdmVzIHRvIGRlZmluZSBydWxlcywgdGFyZ2V0cywgYW5kIHZhcmlhYmxlcyBiYXNlZCBvbiBjb25kaXRpb25zLiBDb21tb24gY29uZGl0aW9uYWwgZGlyZWN0aXZlcyBpbmNsdWRlIGBpZmVxYCwgYGlmbmVxYCwgYGlmZGVmYCwgYW5kIGBpZm5kZWZgLiBUaGVzZSBkaXJlY3RpdmVzIGFsbG93IHlvdSB0byBjaGVjayBmb3IgZXF1YWxpdHksIGluZXF1YWxpdHksIG9yIHZhcmlhYmxlIGV4aXN0ZW5jZS4NCg0KVGhlIGJhc2ljIHN0cnVjdHVyZSBvZiBjb25kaXRpb25hbCBkaXJlY3RpdmVzIGlzIGFzIGZvbGxvd3M6DQoNCmBgYCBtYWtlDQpjb25kaXRpb25hbF9kaXJlY3RpdmUNCiAgICAjIENvbmRpdGlvbg0KICAgIFtjb21tYW5kc10NCmVsc2UNCiAgICAjIEFsdGVybmF0aXZlIGNvbW1hbmRzDQplbmRpZg0KYGBgDQoNCiMjIyA4LjIgUHJhY3RpY2FsIFVzYWdlDQoNCkxldCdzIGV4cGxvcmUgc29tZSBwcmFjdGljYWwgZXhhbXBsZXMgb2YgaG93IGNvbmRpdGlvbmFsIHN0YXRlbWVudHMgY2FuIGJlIHVzZWQgaW4gTWFrZWZpbGVzLg0KDQojIyMjIDguMi4xIENvbmRpdGlvbmFsIENvbXBpbGF0aW9uDQoNCkNvbmRpdGlvbmFsIGNvbXBpbGF0aW9uIGlzIGEgY29tbW9uIHVzZSBjYXNlIGZvciBjb25kaXRpb25hbCBzdGF0ZW1lbnRzIGluIE1ha2VmaWxlcy4gWW91IGNhbiB1c2UgY29uZGl0aW9uYWxzIHRvIGluY2x1ZGUgb3IgZXhjbHVkZSBzcGVjaWZpYyBzb3VyY2UgZmlsZXMgb3IgY29tcGlsZXIgZmxhZ3MgYmFzZWQgb24gYnVpbGQgY29uZmlndXJhdGlvbnMuDQoNCmBgYCBtYWtlDQpERUJVRyA/PSAwDQoNCmlmZXEgKCQoREVCVUcpLCAxKQ0KICAgIENGTEFHUyArPSAtZw0KZW5kaWYNCg0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gbWFpbi5jDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYC1nYCBmbGFnIGlzIGFkZGVkIHRvIGBDRkxBR1NgIGlmIHRoZSBgREVCVUdgIHZhcmlhYmxlIGlzIHNldCB0byBgMWAuIFRoaXMgYWxsb3dzIHlvdSB0byBjb250cm9sIHdoZXRoZXIgZGVidWdnaW5nIGluZm9ybWF0aW9uIGlzIGluY2x1ZGVkIGluIHRoZSBjb21waWxlZCBiaW5hcnkuDQoNCiMjIyMgOC4yLjIgUGxhdGZvcm0tU3BlY2lmaWMgUnVsZXMNCg0KWW91IGNhbiB1c2UgY29uZGl0aW9uYWxzIHRvIGRlZmluZSBwbGF0Zm9ybS1zcGVjaWZpYyBydWxlcyBvciB2YXJpYWJsZXMuIEZvciBpbnN0YW5jZSwgeW91IG1pZ2h0IGhhdmUgZGlmZmVyZW50IGNvbXBpbGF0aW9uIHNldHRpbmdzIGZvciBXaW5kb3dzIGFuZCBMaW51eDoNCg0KYGBgIG1ha2UNClVOQU1FX1MgOj0gJChzaGVsbCB1bmFtZSAtcykNCg0KaWZlcSAoJChVTkFNRV9TKSxMaW51eCkNCiAgICBDQyA9IGdjYw0KICAgIENGTEFHUyA9IC1XYWxsIC1PMg0KZW5kaWYNCg0KaWZlcSAoJChVTkFNRV9TKSxXaW5kb3dzX05UKQ0KICAgIENDID0gY2wNCiAgICBDRkxBR1MgPSAvVzQgL08yDQplbmRpZg0KDQpteV9wcm9ncmFtOiBtYWluLmMNCiAgICAkKENDKSAkKENGTEFHUykgLW8gbXlfcHJvZ3JhbSBtYWluLmMNCmBgYA0KDQpIZXJlLCB0aGUgTWFrZWZpbGUgc2V0cyB0aGUgY29tcGlsZXIgKGBDQ2ApIGFuZCBjb21waWxlciBmbGFncyAoYENGTEFHU2ApIGJhc2VkIG9uIHRoZSBob3N0IG9wZXJhdGluZyBzeXN0ZW0uDQoNCiMjIyMgOC4yLjMgVmFyaWFibGUgQXNzaWdubWVudA0KDQpDb25kaXRpb25hbCBzdGF0ZW1lbnRzIGNhbiBhbHNvIGJlIHVzZWQgZm9yIHZhcmlhYmxlIGFzc2lnbm1lbnQuIEZvciBleGFtcGxlLCB5b3UgbWlnaHQgd2FudCB0byBzZXQgYSB2YXJpYWJsZSBkaWZmZXJlbnRseSBkZXBlbmRpbmcgb24gd2hldGhlciBhIHNwZWNpZmljIHRvb2wgaXMgYXZhaWxhYmxlOg0KDQpgYGAgbWFrZQ0KaWZkZWYgVE9PTF9FWElTVFMNCiAgICBDT01QSUxFUiA9ICQoVE9PTF9FWElTVFMpDQplbHNlDQogICAgQ09NUElMRVIgPSBnY2MNCmVuZGlmDQoNCm15X3Byb2dyYW06IG1haW4uYw0KICAgICQoQ09NUElMRVIpIC1vIG15X3Byb2dyYW0gbWFpbi5jDQpgYGANCg0KSW4gdGhpcyBjYXNlLCBpZiB0aGUgYFRPT0xfRVhJU1RTYCB2YXJpYWJsZSBpcyBkZWZpbmVkLCBpdCB3aWxsIGJlIHVzZWQgYXMgdGhlIGNvbXBpbGVyOyBvdGhlcndpc2UsIGBnY2NgIGlzIHVzZWQgYXMgdGhlIGRlZmF1bHQuDQoNCiMjIyA4LjMgTmVzdGVkIENvbmRpdGlvbmFscw0KDQpZb3UgY2FuIG5lc3QgY29uZGl0aW9uYWwgc3RhdGVtZW50cyB0byBoYW5kbGUgbW9yZSBjb21wbGV4IHNjZW5hcmlvczoNCg0KYGBgIG1ha2UNCkRFQlVHID89IDANClRBUkdFVCA/PSBsaW51eA0KDQppZmVxICgkKERFQlVHKSwgMSkNCiAgICBDRkxBR1MgKz0gLWcNCmVsc2UNCiAgICBpZmVxICgkKFRBUkdFVCksIHdpbmRvd3MpDQogICAgICAgIENGTEFHUyArPSAtTzINCiAgICBlbHNlDQogICAgICAgIENGTEFHUyArPSAtTzMNCiAgICBlbmRpZg0KZW5kaWYNCg0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gbWFpbi5jDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYnVpbGQgY29uZmlndXJhdGlvbiBkZXBlbmRzIG9uIGJvdGggdGhlIGBERUJVR2AgdmFyaWFibGUgYW5kIHRoZSBgVEFSR0VUYCB2YXJpYWJsZS4gRGVwZW5kaW5nIG9uIHRoZXNlIGNvbmRpdGlvbnMsIGRpZmZlcmVudCBvcHRpbWl6YXRpb24gZmxhZ3MgKGAtZ2AsIGAtTzJgLCBvciBgLU8zYCkgYXJlIHVzZWQuDQoNCiMjIyA4LjQgQ29uY2x1c2lvbg0KDQpDb25kaXRpb25hbCBzdGF0ZW1lbnRzIGluIE1ha2VmaWxlcyBwcm92aWRlIGZsZXhpYmlsaXR5IGFuZCBhZGFwdGFiaWxpdHkgdG8geW91ciBidWlsZCBwcm9jZXNzLiBUaGV5IGFsbG93IHlvdSB0byBjdXN0b21pemUgcnVsZXMsIHRhcmdldHMsIGFuZCB2YXJpYWJsZXMgYmFzZWQgb24gY29uZGl0aW9ucywgbWFraW5nIHlvdXIgTWFrZWZpbGVzIG1vcmUgdmVyc2F0aWxlIGFuZCBzdWl0YWJsZSBmb3IgdmFyaW91cyBidWlsZCBzY2VuYXJpb3MuIFVuZGVyc3RhbmRpbmcgaG93IHRvIHVzZSBjb25kaXRpb25hbCBzdGF0ZW1lbnRzIGVmZmVjdGl2ZWx5IGNhbiBoZWxwIHlvdSBtYW5hZ2UgY29tcGxleCBwcm9qZWN0cyBhbmQgYWNjb21tb2RhdGUgZGlmZmVyZW50IGVudmlyb25tZW50cyBhbmQgY29uZmlndXJhdGlvbnMuDQoNCkNlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSBuaW50aCBzZWN0aW9uLCAiUGF0dGVybiBSdWxlcyBhbmQgQXV0b21hdGljIFByZXJlcXVpc2l0ZXMsIiB0byBwcm92aWRlIGEgbW9yZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvZiBwYXR0ZXJuIHJ1bGVzLCBhdXRvbWF0aWMgcHJlcmVxdWlzaXRlcywgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZSBpbiBNYWtlZmlsZXMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyA5LiBQYXR0ZXJuIFJ1bGVzIGFuZCBBdXRvbWF0aWMgUHJlcmVxdWlzaXRlcyBpbiBNYWtlZmlsZXMNCg0KUGF0dGVybiBydWxlcyBhcmUgYSBwb3dlcmZ1bCBmZWF0dXJlIGluIE1ha2VmaWxlcyB0aGF0IGFsbG93IHlvdSB0byBkZWZpbmUgZ2VuZXJpYyBydWxlcyBmb3IgYnVpbGRpbmcgbXVsdGlwbGUgdGFyZ2V0cyB3aXRoIHNpbWlsYXIgcGF0dGVybnMuIEF1dG9tYXRpYyBwcmVyZXF1aXNpdGVzIGV4dGVuZCB0aGlzIGNvbmNlcHQgYnkgYXV0b21hdGljYWxseSBnZW5lcmF0aW5nIGRlcGVuZGVuY3kgaW5mb3JtYXRpb24gZm9yIHNvdXJjZSBmaWxlcy4gSW4gdGhpcyBzZWN0aW9uLCB3ZSB3aWxsIGV4cGxvcmUgaG93IHRvIHVzZSBwYXR0ZXJuIHJ1bGVzIGFuZCBhdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyBlZmZlY3RpdmVseSBpbiBNYWtlZmlsZXMuDQoNCiMjIyA5LjEgUGF0dGVybiBSdWxlcw0KDQpQYXR0ZXJuIHJ1bGVzIGluIE1ha2VmaWxlcyBkZWZpbmUgYSBnZW5lcmFsIHJ1bGUgZm9yIGJ1aWxkaW5nIHRhcmdldHMgdGhhdCBtYXRjaCBhIHNwZWNpZmljIHBhdHRlcm4uIFRoZXkgYXJlIGEgd2F5IHRvIGF2b2lkIHdyaXRpbmcgbXVsdGlwbGUgc2ltaWxhciBydWxlcyBmb3IgdGFyZ2V0cyB3aXRoIGEgY29tbW9uIHN0cnVjdHVyZS4gVGhlIHN5bnRheCBmb3IgYSBwYXR0ZXJuIHJ1bGUgaXM6DQoNCmBgYCBtYWtlDQolLm91dDogJS5jDQogICAgW2NvbW1hbmRzXQ0KYGBgDQoNCi0gICBgJS5vdXRgOiBUaGUgdGFyZ2V0IHBhdHRlcm4gdGhhdCBtYXRjaGVzIGFueSB0YXJnZXQgZW5kaW5nIHdpdGggYC5vdXRgLg0KLSAgIGAlLmNgOiBUaGUgcHJlcmVxdWlzaXRlIHBhdHRlcm4gdGhhdCBtYXRjaGVzIGFueSBzb3VyY2UgZmlsZSBlbmRpbmcgd2l0aCBgLmNgLg0KLSAgIGBbY29tbWFuZHNdYDogVGhlIGNvbW1hbmRzIHRvIGJ1aWxkIHRoZSB0YXJnZXQgZnJvbSB0aGUgcHJlcmVxdWlzaXRlLg0KDQpGb3IgZXhhbXBsZSwgaWYgeW91IGhhdmUgbXVsdGlwbGUgQyBzb3VyY2UgZmlsZXMgYW5kIHdhbnQgdG8gY3JlYXRlIGV4ZWN1dGFibGVzIGZyb20gdGhlbSwgeW91IGNhbiB1c2UgYSBwYXR0ZXJuIHJ1bGUgbGlrZSB0aGlzOg0KDQpgYGAgbWFrZQ0KJS5vdXQ6ICUuYw0KICAgIGdjYyAtbyAkQCAkPA0KYGBgDQoNCk5vdywgYG1ha2VgIGNhbiBidWlsZCBhbnkgdGFyZ2V0IHdpdGggYSBgLm91dGAgZXh0ZW5zaW9uIGZyb20gdGhlIGNvcnJlc3BvbmRpbmcgYC5jYCBzb3VyY2UgZmlsZS4NCg0KIyMjIDkuMiBBdXRvbWF0aWMgUHJlcmVxdWlzaXRlcw0KDQpBdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyBhcmUgYW4gZXh0ZW5zaW9uIG9mIHBhdHRlcm4gcnVsZXMgdGhhdCBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlIGRlcGVuZGVuY3kgaW5mb3JtYXRpb24gZm9yIHNvdXJjZSBmaWxlcy4gVGhpcyBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IHdhbnQgdG8gdHJhY2sgY2hhbmdlcyBpbiBoZWFkZXIgZmlsZXMgYW5kIGF1dG9tYXRpY2FsbHkgcmVidWlsZCB0YXJnZXRzIHdoZW4gaGVhZGVyIGZpbGVzIGNoYW5nZS4NCg0KVG8gZW5hYmxlIGF1dG9tYXRpYyBwcmVyZXF1aXNpdGVzLCB5b3UgY2FuIHVzZSB0aGUgYC1NYCBmbGFnIHdpdGggdGhlIGBnY2NgIG9yIGBnKytgIGNvbXBpbGVyIHRvIGdlbmVyYXRlIGRlcGVuZGVuY3kgaW5mb3JtYXRpb24uIEZvciBleGFtcGxlOg0KDQpgYGAgbWFrZQ0KJS5vOiAlLmMNCiAgICBnY2MgLU1NRCAtTVAgLU1GICQqLmQgLWMgLW8gJEAgJDwNCmBgYA0KDQotICAgYC1NTURgOiBHZW5lcmF0ZSBkZXBlbmRlbmN5IGluZm9ybWF0aW9uLg0KLSAgIGAtTVBgOiBHZW5lcmF0ZSBwaG9ueSB0YXJnZXRzIGZvciBtaXNzaW5nIGhlYWRlcnMuDQotICAgYC1NRiAkKi5kYDogU3BlY2lmeSB0aGUgZGVwZW5kZW5jeSBmaWxlIHRvIGJlIGdlbmVyYXRlZCAoZS5nLiwgYG1haW4uZGAgZm9yIGBtYWluLmNgKS4NCi0gICBgLWMgLW8gJEAgJDxgOiBDb21waWxlIHRoZSBzb3VyY2UgZmlsZSBpbnRvIGFuIG9iamVjdCBmaWxlLg0KDQpBZGRpdGlvbmFsbHksIHlvdSBjYW4gaW5jbHVkZSB0aGUgZ2VuZXJhdGVkIGRlcGVuZGVuY3kgZmlsZXMgaW4geW91ciBNYWtlZmlsZSB0byBlbnN1cmUgYWNjdXJhdGUgdHJhY2tpbmcgb2YgaGVhZGVyIGZpbGUgY2hhbmdlczoNCg0KYGBgIG1ha2UNCi1pbmNsdWRlICQod2lsZGNhcmQgKi5kKQ0KYGBgDQoNClRoaXMgbGluZSB0ZWxscyBgbWFrZWAgdG8gaW5jbHVkZSBhbGwgYC5kYCBmaWxlcyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuDQoNCiMjIyA5LjMgUHJhY3RpY2FsIFVzYWdlDQoNCkxldCdzIGxvb2sgYXQgcHJhY3RpY2FsIGV4YW1wbGVzIG9mIGhvdyBwYXR0ZXJuIHJ1bGVzIGFuZCBhdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyBjYW4gYmUgdXNlZCBpbiBNYWtlZmlsZXMuDQoNCiMjIyMgOS4zLjEgQnVpbGRpbmcgTXVsdGlwbGUgVGFyZ2V0cw0KDQpQYXR0ZXJuIHJ1bGVzIGFyZSBleGNlbGxlbnQgZm9yIGJ1aWxkaW5nIG11bHRpcGxlIHRhcmdldHMgZnJvbSBzaW1pbGFyIHNvdXJjZSBmaWxlcy4gU3VwcG9zZSB5b3UgaGF2ZSBzZXZlcmFsIEMgc291cmNlIGZpbGVzIChgZmlsZTEuY2AsIGBmaWxlMi5jYCwgZXRjLikgdGhhdCB5b3Ugd2FudCB0byBjb21waWxlIGludG8gZXhlY3V0YWJsZXMgKGBmaWxlMS5vdXRgLCBgZmlsZTIub3V0YCwgZXRjLikuIFlvdSBjYW4gdXNlIHRoZSBmb2xsb3dpbmcgcGF0dGVybiBydWxlOg0KDQpgYGAgbWFrZQ0KJS5vdXQ6ICUuYw0KICAgIGdjYyAtbyAkQCAkPA0KYGBgDQoNCk5vdywgYG1ha2UgZmlsZTEub3V0YCB3aWxsIGNvbXBpbGUgYGZpbGUxLmNgIGludG8gYGZpbGUxLm91dGAsIGFuZCB0aGUgc2FtZSBydWxlIGFwcGxpZXMgdG8gb3RoZXIgc291cmNlIGZpbGVzLg0KDQojIyMjIDkuMy4yIEF1dG9tYXRpYyBQcmVyZXF1aXNpdGVzIGZvciBDL0MrKyBQcm9qZWN0cw0KDQpBdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyBzaW1wbGlmeSBkZXBlbmRlbmN5IHRyYWNraW5nIGluIEMvQysrIHByb2plY3RzLiBDb25zaWRlciB0aGlzIE1ha2VmaWxlIGZvciBhIEMgcHJvamVjdDoNCg0KYGBgIG1ha2UNCkNDID0gZ2NjDQpDRkxBR1MgPSAtV2FsbCAtTzINCg0KU09VUkNFUyA9IG1haW4uYyB1dGlsLmMNCk9CSkVDVFMgPSAkKFNPVVJDRVM6LmM9Lm8pDQoNCi1pbmNsdWRlICQod2lsZGNhcmQgKi5kKQ0KDQolLm86ICUuYw0KICAgICQoQ0MpIC1NTUQgLU1QIC1NRiAkKi5kICQoQ0ZMQUdTKSAtYyAtbyAkQCAkPA0KDQpteV9wcm9ncmFtOiAkKE9CSkVDVFMpDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gJChPQkpFQ1RTKQ0KYGBgDQoNCldpdGggdGhpcyBzZXR1cCwgdGhlIE1ha2VmaWxlIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVzIGRlcGVuZGVuY3kgZmlsZXMgKGAuZGApIGZvciBlYWNoIHNvdXJjZSBmaWxlIGFuZCBpbmNsdWRlcyB0aGVtLiBJZiBhIGhlYWRlciBmaWxlIGNoYW5nZXMsIG9ubHkgdGhlIGFmZmVjdGVkIHNvdXJjZSBmaWxlcyBhcmUgcmVidWlsdCwgc2F2aW5nIGNvbXBpbGF0aW9uIHRpbWUuDQoNCiMjIyMgOS4zLjMgR2VuZXJpYyBSdWxlcyBmb3IgQnVpbGQgU3lzdGVtcw0KDQpQYXR0ZXJuIHJ1bGVzIGFyZSBlc3BlY2lhbGx5IHVzZWZ1bCBpbiBidWlsZCBzeXN0ZW1zIHRoYXQgbmVlZCB0byBoYW5kbGUgdmFyaW91cyBzb3VyY2UgZmlsZXMgYW5kIHRhcmdldHMuIEZvciBleGFtcGxlLCBpbiBhIGJ1aWxkIHN5c3RlbSBmb3IgYSBzY3JpcHRpbmcgbGFuZ3VhZ2UgaW50ZXJwcmV0ZXI6DQoNCmBgYCBtYWtlDQolLm86ICUuYw0KICAgICQoQ0MpIC1NTUQgLU1QIC1NRiAkKi5kICQoQ0ZMQUdTKSAtYyAtbyAkQCAkPA0KDQppbnRlcnByZXRlcjogJChPQkpFQ1RTKQ0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyBpbnRlcnByZXRlciAkKE9CSkVDVFMpDQpgYGANCg0KVGhpcyBwYXR0ZXJuIHJ1bGUgYW5kIHRhcmdldCBhbGxvdyB5b3UgdG8gY29tcGlsZSBhbnkgYC5jYCBzb3VyY2UgZmlsZSBpbnRvIGFuIG9iamVjdCBmaWxlIGFuZCB0aGVuIGxpbmsgdGhlbSB0byBjcmVhdGUgdGhlIGludGVycHJldGVyLg0KDQojIyMgOS40IENvbmNsdXNpb24NCg0KUGF0dGVybiBydWxlcyBhbmQgYXV0b21hdGljIHByZXJlcXVpc2l0ZXMgaW4gTWFrZWZpbGVzIHByb3ZpZGUgYSBwb3dlcmZ1bCB3YXkgdG8gc3RyZWFtbGluZSB0aGUgYnVpbGQgcHJvY2VzcyBmb3IgcHJvamVjdHMgd2l0aCBtdWx0aXBsZSBzb3VyY2UgZmlsZXMgYW5kIGRlcGVuZGVuY2llcy4gQnkgZGVmaW5pbmcgZ2VuZXJpYyBydWxlcyBmb3IgYnVpbGRpbmcgdGFyZ2V0cyBhbmQgYXV0b21hdGljYWxseSBnZW5lcmF0aW5nIGRlcGVuZGVuY3kgaW5mb3JtYXRpb24sIHlvdSBjYW4gc2F2ZSB0aW1lIGFuZCBlbnN1cmUgYWNjdXJhdGUgdHJhY2tpbmcgb2YgY2hhbmdlcyBpbiBzb3VyY2UgZmlsZXMgYW5kIGhlYWRlcnMuIFVuZGVyc3RhbmRpbmcgaG93IHRvIHVzZSBwYXR0ZXJuIHJ1bGVzIGFuZCBhdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyBlZmZlY3RpdmVseSBpcyBlc3NlbnRpYWwgZm9yIGVmZmljaWVudCBzb2Z0d2FyZSBkZXZlbG9wbWVudCB3b3JrZmxvd3MuDQoNCkNlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSB0ZW50aCBzZWN0aW9uLCAiTWFuYWdpbmcgTGlicmFyaWVzIGFuZCBMaW5raW5nLCIgdG8gcHJvdmlkZSBhIG1vcmUgZGV0YWlsZWQgZXhwbGFuYXRpb24gb2YgaG93IHRvIG1hbmFnZSBsaWJyYXJpZXMgYW5kIGxpbmtpbmcgaW4gTWFrZWZpbGVzLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgMTAuIE1hbmFnaW5nIExpYnJhcmllcyBhbmQgTGlua2luZyBpbiBNYWtlZmlsZXMNCg0KTGlicmFyaWVzIGFyZSBhbiBlc3NlbnRpYWwgcGFydCBvZiBzb2Z0d2FyZSBkZXZlbG9wbWVudCwgYW5kIGluIE1ha2VmaWxlcywgbWFuYWdpbmcgbGlicmFyaWVzIGFuZCBsaW5raW5nIHRoZW0gdG8geW91ciBwcm9ncmFtcyBpcyBjcnVjaWFsLiBJbiB0aGlzIHNlY3Rpb24sIHdlIHdpbGwgZXhwbG9yZSBob3cgdG8gaW5jbHVkZSBhbmQgbGluayBsaWJyYXJpZXMgZWZmZWN0aXZlbHkgaW4gTWFrZWZpbGVzLg0KDQojIyMgMTAuMSBJbmNsdWRpbmcgTGlicmFyaWVzDQoNCkluY2x1ZGluZyBsaWJyYXJpZXMgaW4geW91ciBNYWtlZmlsZSBpbnZvbHZlcyBzcGVjaWZ5aW5nIHRoZSBuZWNlc3NhcnkgbGlicmFyaWVzIHRoYXQgeW91ciBwcm9ncmFtIGRlcGVuZHMgb24uIFlvdSB0eXBpY2FsbHkgdXNlIHRoZSBgLWxgIGZsYWcgZm9sbG93ZWQgYnkgdGhlIGxpYnJhcnkgbmFtZSB3aGVuIGludm9raW5nIHRoZSBsaW5rZXIgKGUuZy4sIGBnY2NgIG9yIGBnKytgKS4NCg0KSGVyZSdzIGFuIGV4YW1wbGUgb2YgaG93IHRvIGluY2x1ZGUgdGhlIG1hdGggbGlicmFyeSBpbiBhIE1ha2VmaWxlOg0KDQpgYGAgbWFrZQ0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgZ2NjIC1vIG15X3Byb2dyYW0gbWFpbi5jIC1sbQ0KYGBgDQoNCkluIHRoaXMgZXhhbXBsZSwgdGhlIGAtbG1gIGZsYWcgdGVsbHMgdGhlIGxpbmtlciB0byBpbmNsdWRlIHRoZSBtYXRoIGxpYnJhcnkuDQoNCiMjIyAxMC4yIFNwZWNpZnlpbmcgTGlicmFyeSBEaXJlY3Rvcmllcw0KDQpTb21ldGltZXMsIHRoZSBsaWJyYXJpZXMgeW91IG5lZWQgbWF5IGJlIGxvY2F0ZWQgaW4gbm9uLXN0YW5kYXJkIGRpcmVjdG9yaWVzLiBZb3UgY2FuIHNwZWNpZnkgbGlicmFyeSBkaXJlY3RvcmllcyB1c2luZyB0aGUgYC1MYCBmbGFnIGFuZCB0aGVuIGluY2x1ZGUgdGhlIGxpYnJhcmllcyB1c2luZyB0aGUgYC1sYCBmbGFnLg0KDQpgYGAgbWFrZQ0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgZ2NjIC1vIG15X3Byb2dyYW0gbWFpbi5jIC1ML3BhdGgvdG8vbGliZGlyIC1sbXlsaWINCmBgYA0KDQpJbiB0aGlzIGNhc2UsIGAvcGF0aC90by9saWJkaXJgIGlzIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgYGxpYm15bGliLmFgIG9yIGBsaWJteWxpYi5zb2AgbGlicmFyeSBmaWxlLg0KDQojIyMgMTAuMyBQcmFjdGljYWwgVXNhZ2UNCg0KTGV0J3MgZXhwbG9yZSBzb21lIHByYWN0aWNhbCBleGFtcGxlcyBvZiBtYW5hZ2luZyBsaWJyYXJpZXMgYW5kIGxpbmtpbmcgdGhlbSBpbiBNYWtlZmlsZXMuDQoNCiMjIyMgMTAuMy4xIExpbmtpbmcgd2l0aCBNdWx0aXBsZSBMaWJyYXJpZXMNCg0KSWYgeW91ciBwcm9ncmFtIGRlcGVuZHMgb24gbXVsdGlwbGUgbGlicmFyaWVzLCB5b3UgY2FuIHNwZWNpZnkgdGhlbSBieSBzZXBhcmF0aW5nIHRoZW0gd2l0aCBzcGFjZSBhZnRlciB0aGUgYC1sYCBmbGFnOg0KDQpgYGAgbWFrZQ0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgZ2NjIC1vIG15X3Byb2dyYW0gbWFpbi5jIC1sbSAtbHB0aHJlYWQgLWxteWxpYg0KYGBgDQoNCkluIHRoaXMgZXhhbXBsZSwgd2UncmUgbGlua2luZyB3aXRoIHRoZSBtYXRoIGxpYnJhcnkgKGAtbG1gKSwgdGhlIHB0aHJlYWQgbGlicmFyeSAoYC1scHRocmVhZGApLCBhbmQgYSBjdXN0b20gbGlicmFyeSAoYC1sbXlsaWJgKS4NCg0KIyMjIyAxMC4zLjIgVXNpbmcgVmFyaWFibGVzIGZvciBMaWJyYXJpZXMNCg0KVG8gbWFrZSB5b3VyIE1ha2VmaWxlIG1vcmUgbWFpbnRhaW5hYmxlLCB5b3UgY2FuIHVzZSB2YXJpYWJsZXMgdG8gc3RvcmUgbGlicmFyeSBmbGFnczoNCg0KYGBgIG1ha2UNCkxJQlMgPSAtbG0gLWxwdGhyZWFkIC1sbXlsaWINCg0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgZ2NjIC1vIG15X3Byb2dyYW0gbWFpbi5jICQoTElCUykNCmBgYA0KDQpCeSB1c2luZyB2YXJpYWJsZXMsIGl0J3MgZWFzaWVyIHRvIGFkZCBvciByZW1vdmUgbGlicmFyaWVzIGZyb20geW91ciBwcm9qZWN0IHdpdGhvdXQgY2hhbmdpbmcgZXZlcnkgb2NjdXJyZW5jZSBpbiB5b3VyIE1ha2VmaWxlLg0KDQojIyMjIDEwLjMuMyBDb25kaXRpb25hbCBMaW5raW5nDQoNCllvdSBjYW4gdXNlIGNvbmRpdGlvbmFsIHN0YXRlbWVudHMgaW4geW91ciBNYWtlZmlsZSB0byBoYW5kbGUgZGlmZmVyZW50IGJ1aWxkIGNvbmZpZ3VyYXRpb25zIGFuZCBsaW5rIGxpYnJhcmllcyBhY2NvcmRpbmdseS4gRm9yIGV4YW1wbGUsIHlvdSBtaWdodCB3YW50IHRvIGxpbmsgd2l0aCBhIGRlYnVnZ2luZyBsaWJyYXJ5IHdoZW4gZGVidWdnaW5nIGlzIGVuYWJsZWQ6DQoNCmBgYCBtYWtlDQpERUJVRyA/PSAwDQpMSUJTID0gLWxtIC1scHRocmVhZA0KDQppZmVxICgkKERFQlVHKSwgMSkNCiAgICBMSUJTICs9IC1sZGVidWcNCmVuZGlmDQoNCm15X3Byb2dyYW06IG1haW4uYw0KICAgIGdjYyAtbyBteV9wcm9ncmFtIG1haW4uYyAkKExJQlMpDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYC1sZGVidWdgIGxpYnJhcnkgaXMgaW5jbHVkZWQgaW4gdGhlIGBMSUJTYCB2YXJpYWJsZSBvbmx5IGlmIHRoZSBgREVCVUdgIHZhcmlhYmxlIGlzIHNldCB0byBgMWAuDQoNCiMjIyMgMTAuMy40IEF1dG9tYXRpYyBEZXBlbmRlbmN5IFRyYWNraW5nDQoNCklmIHlvdXIgcHJvamVjdCBoYXMgaGVhZGVyIGZpbGUgZGVwZW5kZW5jaWVzLCB5b3UgY2FuIHVzZSBhdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyAoYXMgZGlzY3Vzc2VkIGluIHNlY3Rpb24gOSkgdG8gYXV0b21hdGljYWxseSB0cmFjayBjaGFuZ2VzIGluIGhlYWRlciBmaWxlcyBhbmQgcmVjb21waWxlIHRoZSBwcm9ncmFtIHdoZW4gbmVlZGVkLiBUaGlzIGVuc3VyZXMgdGhhdCB5b3VyIHByb2dyYW0gaXMgcmVidWlsdCB3aGVuIGFueSBvZiBpdHMgZGVwZW5kZW5jaWVzIGNoYW5nZS4NCg0KYGBgIG1ha2UNCkNDID0gZ2NjDQpDRkxBR1MgPSAtV2FsbCAtTzINClNPVVJDRVMgPSBtYWluLmMgdXRpbC5jDQpPQkpFQ1RTID0gJChTT1VSQ0VTOi5jPS5vKQ0KDQotaW5jbHVkZSAkKHdpbGRjYXJkICouZCkNCg0KJS5vOiAlLmMNCiAgICAkKENDKSAtTU1EIC1NUCAtTUYgJCouZCAkKENGTEFHUykgLWMgLW8gJEAgJDwNCg0KbXlfcHJvZ3JhbTogJChPQkpFQ1RTKQ0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyBteV9wcm9ncmFtICQoT0JKRUNUUykgLWxtIC1scHRocmVhZCAtbG15bGliDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB3ZSBpbmNsdWRlIGxpYnJhcmllcyBhcyB3ZWxsIGFzIGRlcGVuZGVuY2llcyBnZW5lcmF0ZWQgZm9yIHNvdXJjZSBmaWxlcy4NCg0KIyMjIDEwLjQgQ29uY2x1c2lvbg0KDQpNYW5hZ2luZyBsaWJyYXJpZXMgYW5kIGxpbmtpbmcgaW4gTWFrZWZpbGVzIGlzIGVzc2VudGlhbCBmb3IgYnVpbGRpbmcgY29tcGxleCBzb2Z0d2FyZSBwcm9qZWN0cy4gQnkgc3BlY2lmeWluZyBsaWJyYXJpZXMsIGxpYnJhcnkgZGlyZWN0b3JpZXMsIGFuZCB1c2luZyB2YXJpYWJsZXMgYW5kIGNvbmRpdGlvbmFsIHN0YXRlbWVudHMsIHlvdSBjYW4gY3JlYXRlIE1ha2VmaWxlcyB0aGF0IGhhbmRsZSBsaWJyYXJ5IG1hbmFnZW1lbnQgZWZmaWNpZW50bHkuIEFkZGl0aW9uYWxseSwgYXV0b21hdGljIGRlcGVuZGVuY3kgdHJhY2tpbmcgZW5zdXJlcyB0aGF0IHlvdXIgcHJvZ3JhbSBpcyByZWJ1aWx0IHdoZW4gbmVjZXNzYXJ5LCBrZWVwaW5nIHlvdXIgYnVpbGQgcHJvY2VzcyB1cC10by1kYXRlIGFuZCByZWxpYWJsZS4gVW5kZXJzdGFuZGluZyB0aGVzZSBjb25jZXB0cyBpcyBjcnVjaWFsIGZvciBlZmZlY3RpdmUgc29mdHdhcmUgZGV2ZWxvcG1lbnQgd29ya2Zsb3dzIHVzaW5nIE1ha2VmaWxlcy4NCg0KQ2VydGFpbmx5LCBsZXQncyBleHBhbmQgb24gdGhlIGVsZXZlbnRoIHNlY3Rpb24sICJDbGVhbmluZyBhbmQgTWFpbnRlbmFuY2UsIiB0byBwcm92aWRlIGEgbW9yZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvZiBjbGVhbmluZyB0YXJnZXRzLCBtYWludGFpbmluZyBNYWtlZmlsZXMsIGFuZCBvdGhlciBhc3BlY3RzIHJlbGF0ZWQgdG8gY2xlYW5pbmcgYW5kIG1haW50YWluaW5nIHlvdXIgcHJvamVjdCB3aXRoIE1ha2VmaWxlcy4NCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIDExLiBDbGVhbmluZyBhbmQgTWFpbnRlbmFuY2UgaW4gTWFrZWZpbGVzDQoNCkNsZWFuaW5nIGFuZCBtYWludGFpbmluZyBhIHByb2plY3QgaXMgYSBjcnVjaWFsIHBhcnQgb2Ygc29mdHdhcmUgZGV2ZWxvcG1lbnQuIE1ha2VmaWxlcyBwcm92aWRlIHNldmVyYWwgZmVhdHVyZXMgdG8gaGVscCB5b3UgbWFuYWdlIHRoZXNlIHRhc2tzIGVmZmljaWVudGx5LiBJbiB0aGlzIHNlY3Rpb24sIHdlIHdpbGwgZXhwbG9yZSBob3cgdG8gY3JlYXRlIGNsZWFuaW5nIHRhcmdldHMsIGhhbmRsZSBwcm9qZWN0IG1haW50ZW5hbmNlLCBhbmQgb3RoZXIgcmVsYXRlZCBhc3BlY3RzIGluIE1ha2VmaWxlcy4NCg0KIyMjIDExLjEgQ2xlYW5pbmcgVGFyZ2V0cw0KDQpDbGVhbmluZyB0YXJnZXRzIGFyZSB1c2VkIHRvIHJlbW92ZSBnZW5lcmF0ZWQgZmlsZXMgYW5kIGFydGlmYWN0cywgZW5zdXJpbmcgYSBjbGVhbiBwcm9qZWN0IGRpcmVjdG9yeSBmb3IgcmVidWlsZGluZyBvciBkaXN0cmlidXRpb24uIEEgY29tbW9uIGNsZWFuaW5nIHRhcmdldCBpbiBhIE1ha2VmaWxlIGlzIGBjbGVhbmAuIFRvIGNyZWF0ZSBhIGBjbGVhbmAgdGFyZ2V0LCB5b3UgY2FuIHVzZSB0aGUgZm9sbG93aW5nIHJ1bGU6DQoNCmBgYCBtYWtlDQouUEhPTlk6IGNsZWFuDQoNCmNsZWFuOg0KICAgIHJtIC1mIG15X3Byb2dyYW0gKi5vDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYGNsZWFuYCB0YXJnZXQgcmVtb3ZlcyB0aGUgYG15X3Byb2dyYW1gIGV4ZWN1dGFibGUgYW5kIGFsbCBvYmplY3QgZmlsZXMgKGAqLm9gKSBmcm9tIHRoZSBwcm9qZWN0IGRpcmVjdG9yeSB3aGVuIHlvdSBydW4gYG1ha2UgY2xlYW5gLg0KDQojIyMgMTEuMiBNYWludGVuYW5jZSBUYXJnZXRzDQoNCk1haW50ZW5hbmNlIHRhcmdldHMgYXJlIHVzZWQgdG8gcGVyZm9ybSB0YXNrcyByZWxhdGVkIHRvIHByb2plY3QgbWFpbnRlbmFuY2UsIHN1Y2ggYXMgZ2VuZXJhdGluZyBkb2N1bWVudGF0aW9uLCBydW5uaW5nIHRlc3RzLCBvciBjaGVja2luZyBjb2RlIGZvcm1hdHRpbmcuIEhlcmUgYXJlIHNvbWUgZXhhbXBsZXM6DQoNCiMjIyMgMTEuMi4xIEdlbmVyYXRpbmcgRG9jdW1lbnRhdGlvbg0KDQpZb3UgY2FuIGNyZWF0ZSBhIHRhcmdldCBjYWxsZWQgYGRvY3NgIHRvIGdlbmVyYXRlIHByb2plY3QgZG9jdW1lbnRhdGlvbi4gRm9yIGluc3RhbmNlLCBpZiB5b3UgdXNlIERveHlnZW4gZm9yIGRvY3VtZW50YXRpb24gZ2VuZXJhdGlvbjoNCg0KYGBgIG1ha2UNCi5QSE9OWTogZG9jcw0KDQpkb2NzOg0KICAgIGRveHlnZW4NCmBgYA0KDQpSdW5uaW5nIGBtYWtlIGRvY3NgIHdpbGwgZXhlY3V0ZSB0aGUgYGRveHlnZW5gIGNvbW1hbmQgdG8gZ2VuZXJhdGUgZG9jdW1lbnRhdGlvbi4NCg0KIyMjIyAxMS4yLjIgUnVubmluZyBUZXN0cw0KDQpUbyBydW4geW91ciBwcm9qZWN0J3MgdGVzdCBzdWl0ZSwgeW91IGNhbiBjcmVhdGUgYSB0YXJnZXQgY2FsbGVkIGB0ZXN0YDoNCg0KYGBgIG1ha2UNCi5QSE9OWTogdGVzdA0KDQp0ZXN0Og0KICAgIC4vcnVuX3Rlc3RzLnNoDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYHRlc3RgIHRhcmdldCBleGVjdXRlcyBhIHNjcmlwdCAoYHJ1bl90ZXN0cy5zaGApIHRoYXQgcnVucyB5b3VyIHByb2plY3QncyB0ZXN0IGNhc2VzLg0KDQojIyMjIDExLjIuMyBDb2RlIEZvcm1hdHRpbmcNCg0KWW91IGNhbiBhbHNvIGNyZWF0ZSBhIHRhcmdldCB0byBjaGVjayBvciBmb3JtYXQgeW91ciBjb2RlIHVzaW5nIHRvb2xzIGxpa2UgYGNsYW5nLWZvcm1hdGA6DQoNCmBgYCBtYWtlDQouUEhPTlk6IGZvcm1hdA0KDQpmb3JtYXQ6DQogICAgY2xhbmctZm9ybWF0IC1pICouYw0KYGBgDQoNClJ1bm5pbmcgYG1ha2UgZm9ybWF0YCB3b3VsZCBhcHBseSBjb2RlIGZvcm1hdHRpbmcgdG8gYWxsIGAuY2Agc291cmNlIGZpbGVzLg0KDQojIyMgMTEuMyBBdXRvbWF0aW5nIERlcGVuZGVuY3kgQ2xlYW51cA0KDQpJZiB5b3VyIE1ha2VmaWxlIGdlbmVyYXRlcyBkZXBlbmRlbmN5IGZpbGVzIChhcyBkaXNjdXNzZWQgaW4gc2VjdGlvbiA5KSwgeW91IGNhbiBjcmVhdGUgYSB0YXJnZXQgdG8gY2xlYW4gdXAgdGhlc2UgZmlsZXMgd2hlbiBubyBsb25nZXIgbmVlZGVkOg0KDQpgYGAgbWFrZQ0KLlBIT05ZOiBjbGVhbi1kZXBzDQoNCmNsZWFuLWRlcHM6DQogICAgcm0gLWYgKi5kDQpgYGANCg0KVGhlIGBjbGVhbi1kZXBzYCB0YXJnZXQgcmVtb3ZlcyBhbGwgZ2VuZXJhdGVkIGRlcGVuZGVuY3kgZmlsZXMgKGAqLmRgKSBmcm9tIHRoZSBwcm9qZWN0IGRpcmVjdG9yeS4NCg0KIyMjIDExLjQgQ29uZGl0aW9uYWwgTWFpbnRlbmFuY2UgVGFyZ2V0cw0KDQpZb3UgY2FuIHVzZSBjb25kaXRpb25hbCBzdGF0ZW1lbnRzIHRvIGNvbnRyb2wgd2hlbiBtYWludGVuYW5jZSB0YXJnZXRzIHNob3VsZCBiZSBleGVjdXRlZC4gRm9yIGV4YW1wbGUsIHlvdSBtaWdodCB3YW50IHRvIGdlbmVyYXRlIGRvY3VtZW50YXRpb24gb25seSBmb3Igc3BlY2lmaWMgYnVpbGQgY29uZmlndXJhdGlvbnM6DQoNCmBgYCBtYWtlDQpERUJVRyA/PSAwDQoNCmlmZXEgKCQoREVCVUcpLCAxKQ0KICAgIC5QSE9OWTogZG9jcw0KDQogICAgZG9jczoNCiAgICAgICAgZG94eWdlbg0KZW5kaWYNCmBgYA0KDQpJbiB0aGlzIGV4YW1wbGUsIHRoZSBgZG9jc2AgdGFyZ2V0IGlzIGRlZmluZWQgYW5kIG1hcmtlZCBhcyBwaG9ueSBvbmx5IGlmIHRoZSBgREVCVUdgIHZhcmlhYmxlIGlzIHNldCB0byBgMWAsIGVuc3VyaW5nIHRoYXQgZG9jdW1lbnRhdGlvbiBpcyBnZW5lcmF0ZWQgb25seSBmb3IgZGVidWdnaW5nIGJ1aWxkcy4NCg0KIyMjIDExLjUgQ29uY2x1c2lvbg0KDQpDbGVhbmluZyBhbmQgbWFpbnRhaW5pbmcgYSBwcm9qZWN0IGFyZSBlc3NlbnRpYWwgYXNwZWN0cyBvZiBzb2Z0d2FyZSBkZXZlbG9wbWVudCwgYW5kIE1ha2VmaWxlcyBvZmZlciBjb252ZW5pZW50IHdheXMgdG8gYXV0b21hdGUgdGhlc2UgdGFza3MuIEJ5IGNyZWF0aW5nIGNsZWFuaW5nIGFuZCBtYWludGVuYW5jZSB0YXJnZXRzLCB5b3UgY2FuIGtlZXAgeW91ciBwcm9qZWN0IGRpcmVjdG9yeSBvcmdhbml6ZWQgYW5kIHVwLXRvLWRhdGUuIEFkZGl0aW9uYWxseSwgdXNpbmcgY29uZGl0aW9uYWwgc3RhdGVtZW50cyBhbGxvd3MgeW91IHRvIGNvbnRyb2wgd2hlbiB0aGVzZSB0YXJnZXRzIGFyZSBleGVjdXRlZCwgZW5zdXJpbmcgdGhleSBhbGlnbiB3aXRoIHlvdXIgcHJvamVjdCdzIG5lZWRzIGFuZCBidWlsZCBjb25maWd1cmF0aW9ucy4gVW5kZXJzdGFuZGluZyBhbmQgZWZmZWN0aXZlbHkgdXRpbGl6aW5nIHRoZXNlIGZlYXR1cmVzIGluIE1ha2VmaWxlcyBpcyBjcnVjaWFsIGZvciBtYW5hZ2luZyBjb21wbGV4IHNvZnR3YXJlIHByb2plY3RzIGVmZmljaWVudGx5Lg0KDQpDZXJ0YWlubHksIGxldCdzIGV4cGFuZCBvbiB0aGUgdHdlbGZ0aCBzZWN0aW9uLCAiQWR2YW5jZWQgVGVjaG5pcXVlcyBhbmQgQmVzdCBQcmFjdGljZXMsIiB0byBwcm92aWRlIGEgbW9yZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvZiBhZHZhbmNlZCBNYWtlZmlsZSB0ZWNobmlxdWVzIGFuZCBiZXN0IHByYWN0aWNlcyB0aGF0IGNhbiBoZWxwIHlvdSBjcmVhdGUgZWZmaWNpZW50IGFuZCBtYWludGFpbmFibGUgYnVpbGQgc3lzdGVtcy4NCg0KIyMgQWR2YW5jZWQgVGVjaG5pcXVlcyBhbmQgQmVzdCBQcmFjdGljZXMgaW4gTWFrZWZpbGVzDQoNCkFkdmFuY2VkIHRlY2huaXF1ZXMgYW5kIGJlc3QgcHJhY3RpY2VzIGluIE1ha2VmaWxlcyBjYW4gc2lnbmlmaWNhbnRseSBpbXByb3ZlIHRoZSBlZmZpY2llbmN5IGFuZCBtYWludGFpbmFiaWxpdHkgb2YgeW91ciBidWlsZCBzeXN0ZW0uIEluIHRoaXMgc2VjdGlvbiwgd2UnbGwgZXhwbG9yZSBzb21lIGFkdmFuY2VkIHRlY2huaXF1ZXMgYW5kIGJlc3QgcHJhY3RpY2VzIHRoYXQgY2FuIGVsZXZhdGUgeW91ciBNYWtlZmlsZSBza2lsbHMuDQoNCiMjIyBVc2UgVmFyaWFibGVzIGZvciBDb21waWxlciBhbmQgRmxhZ3MNCg0KVXNpbmcgdmFyaWFibGVzIHRvIHN0b3JlIGNvbXBpbGVyIGFuZCBmbGFnIHNldHRpbmdzIGluIHlvdXIgTWFrZWZpbGUgbWFrZXMgaXQgbW9yZSBtYWludGFpbmFibGUgYW5kIGFkYXB0YWJsZS4gRm9yIGV4YW1wbGU6DQoNCmBgYCBtYWtlDQpDQyA9IGdjYw0KQ0ZMQUdTID0gLVdhbGwgLU8yDQpgYGANCg0KQnkgZGVmaW5pbmcgdGhlc2UgdmFyaWFibGVzLCB5b3UgY2FuIGVhc2lseSBjaGFuZ2UgdGhlIGNvbXBpbGVyIG9yIGNvbXBpbGVyIGZsYWdzIGluIG9uZSBwbGFjZSwgbWFraW5nIGl0IGxlc3MgZXJyb3ItcHJvbmUgYW5kIG1vcmUgZmxleGlibGUuDQoNCiMjIyBQaG9ueSBUYXJnZXRzDQoNCkFsd2F5cyBtYXJrIHRhcmdldHMgdGhhdCBkb24ndCBjb3JyZXNwb25kIHRvIGFjdHVhbCBmaWxlcyAoZS5nLiwgYGNsZWFuYCwgYGFsbGAsIGB0ZXN0YCwgYGRvY3NgKSBhcyBwaG9ueSB1c2luZyB0aGUgYC5QSE9OWWAgc3BlY2lhbCB0YXJnZXQuIFRoaXMgaGVscHMgcHJldmVudCBjb25mbGljdHMgd2l0aCBmaWxlcyBvZiB0aGUgc2FtZSBuYW1lIGFuZCBlbnN1cmVzIHRoYXQgdGhlIHRhcmdldCBpcyBhbHdheXMgZXhlY3V0ZWQsIGV2ZW4gaWYgYSBmaWxlIHdpdGggdGhlIHNhbWUgbmFtZSBleGlzdHMuDQoNCmBgYCBtYWtlDQouUEhPTlk6IGNsZWFuIHRlc3QgZG9jcw0KYGBgDQoNCiMjIyBVc2UgV2lsZGNhcmRzIGZvciBTb3VyY2UgRmlsZXMNCg0KSW5zdGVhZCBvZiBsaXN0aW5nIGFsbCBzb3VyY2UgZmlsZXMgbWFudWFsbHksIHlvdSBjYW4gdXNlIHdpbGRjYXJkcyB0byBhdXRvbWF0aWNhbGx5IGRldGVjdCBzb3VyY2UgZmlsZXMgaW4gYSBkaXJlY3RvcnkuIEZvciBleGFtcGxlLCB0byBjb21waWxlIGFsbCBgLmNgIGZpbGVzIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeToNCg0KYGBgIG1ha2UNClNPVVJDRVMgPSAkKHdpbGRjYXJkICouYykNCmBgYA0KDQpUaGlzIGFwcHJvYWNoIGlzIG1vcmUgbWFpbnRhaW5hYmxlIGFzIGl0IGF1dG9tYXRpY2FsbHkgYWRhcHRzIHRvIGNoYW5nZXMgaW4gdGhlIGRpcmVjdG9yeS4NCg0KIyMjIEdlbmVyYXRpbmcgRGVwZW5kZW5jeSBGaWxlcyBBdXRvbWF0aWNhbGx5DQoNCkF1dG9tYXRpY2FsbHkgZ2VuZXJhdGluZyBkZXBlbmRlbmN5IGZpbGVzIGZvciBDL0MrKyBwcm9qZWN0cyB1c2luZyB0b29scyBsaWtlIGBnY2MgLU1gIChhcyBkaXNjdXNzZWQgaW4gc2VjdGlvbiA5KSBpcyBhIHBvd2VyZnVsIHRlY2huaXF1ZS4gSXQgZW5zdXJlcyB0aGF0IHlvdXIgTWFrZWZpbGUgYWNjdXJhdGVseSB0cmFja3MgaGVhZGVyIGZpbGUgZGVwZW5kZW5jaWVzLCByZWR1Y2luZyB0aGUgcmlzayBvZiBicm9rZW4gYnVpbGRzLg0KDQpgYGAgbWFrZQ0KLWluY2x1ZGUgJCh3aWxkY2FyZCAqLmQpDQpgYGANCg0KIyMjIENvbmRpdGlvbmFsIENvbXBpbGF0aW9uDQoNCkNvbmRpdGlvbmFsIGNvbXBpbGF0aW9uIChhcyBkaXNjdXNzZWQgaW4gc2VjdGlvbiA4KSBhbGxvd3MgeW91IHRvIGFkYXB0IHlvdXIgYnVpbGQgcHJvY2VzcyB0byBkaWZmZXJlbnQgY29uZmlndXJhdGlvbnMgb3IgcGxhdGZvcm1zLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIGVuYWJsaW5nIG9yIGRpc2FibGluZyBmZWF0dXJlcywgc2V0dGluZyBjb21waWxlciBmbGFncyBjb25kaXRpb25hbGx5LCBvciBzcGVjaWZ5aW5nIGRpZmZlcmVudCBidWlsZCBwYXRocy4NCg0KIyMjIFNlcGFyYXRlIERpcmVjdG9yaWVzIGZvciBPYmplY3QgRmlsZXMNCg0KT3JnYW5pemluZyBvYmplY3QgZmlsZXMgaW4gYSBzZXBhcmF0ZSBkaXJlY3RvcnkgKGUuZy4sIGBvYmovYCkgaW5zdGVhZCBvZiBjbHV0dGVyaW5nIHRoZSBzb3VyY2UgZGlyZWN0b3J5IGNhbiBtYWtlIHlvdXIgcHJvamVjdCBzdHJ1Y3R1cmUgY2xlYW5lciBhbmQgYXZvaWQgY29uZmxpY3RzIGJldHdlZW4gb2JqZWN0IGZpbGVzIGFuZCBzb3VyY2UgZmlsZXMgd2l0aCB0aGUgc2FtZSBuYW1lcy4NCg0KYGBgIG1ha2UNCk9CSl9ESVIgPSBvYmoNCk9CSkVDVFMgPSAkKGFkZHByZWZpeCAkKE9CSl9ESVIpLywgJChTT1VSQ0VTOi5jPS5vKSkNCg0KJChPQkpfRElSKS8lLm86ICUuYw0KICAgICQoQ0MpIC1NTUQgLU1QIC1NRiAkKE9CSl9ESVIpLyQqLmQgJChDRkxBR1MpIC1jIC1vICRAICQ8DQpgYGANCg0KIyMjIFRhcmdldC1TcGVjaWZpYyBWYXJpYWJsZXMNCg0KWW91IGNhbiBzZXQgdmFyaWFibGVzIHRoYXQgYXJlIHNwZWNpZmljIHRvIGEgcGFydGljdWxhciB0YXJnZXQuIFRoaXMgYWxsb3dzIHlvdSB0byBjdXN0b21pemUgY29tcGlsYXRpb24gZmxhZ3Mgb3Igc2V0dGluZ3MgZm9yIHNwZWNpZmljIHNvdXJjZSBmaWxlcyBvciB0YXJnZXRzLg0KDQpgYGAgbWFrZQ0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gbWFpbi5jDQoNCnNwZWNpYWxfdGFyZ2V0OiBzcGVjaWFsLmMNCiAgICAkKENDKSAkKENGTEFHU19TUEVDSUFMKSAtbyBzcGVjaWFsX3RhcmdldCBzcGVjaWFsLmMNCmBgYA0KDQpIZXJlLCBgQ0ZMQUdTX1NQRUNJQUxgIGlzIHVzZWQgb25seSBmb3IgdGhlIGBzcGVjaWFsX3RhcmdldGAuDQoNCiMjIyBQYXJhbGxlbCBCdWlsZHMNCg0KWW91IGNhbiB1c2UgdGhlIGAtamAgZmxhZyB3aXRoIHRoZSBgbWFrZWAgY29tbWFuZCB0byBlbmFibGUgcGFyYWxsZWwgYnVpbGRzLCB3aGljaCBjYW4gc2lnbmlmaWNhbnRseSByZWR1Y2UgYnVpbGQgdGltZXMgb24gbXVsdGktY29yZSBzeXN0ZW1zLiBGb3IgZXhhbXBsZSwgYG1ha2UgLWo0YCB3aWxsIHJ1biB1cCB0byBmb3VyIGpvYnMgY29uY3VycmVudGx5Lg0KDQojIyMgQ29tbWVudHMgYW5kIERvY3VtZW50YXRpb24NCg0KQWRkaW5nIGNvbW1lbnRzIHRvIHlvdXIgTWFrZWZpbGUgaGVscHMgZG9jdW1lbnQgaXRzIHN0cnVjdHVyZSBhbmQgcHVycG9zZS4gSXQncyBhbHNvIGEgZ29vZCBwcmFjdGljZSB0byBpbmNsdWRlIGEgc2VjdGlvbiBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgTWFrZWZpbGUgdGhhdCBleHBsYWlucyBpdHMgdXNhZ2UsIGRlcGVuZGVuY2llcywgYW5kIGFueSBzcGVjaWFsIGluc3RydWN0aW9ucyBmb3IgYnVpbGRpbmcgdGhlIHByb2plY3QuDQoNCiMjIyBWZXJzaW9uIENvbnRyb2wgSW50ZWdyYXRpb24NCg0KSWYgeW91J3JlIHVzaW5nIGEgdmVyc2lvbiBjb250cm9sIHN5c3RlbSBsaWtlIEdpdCwgY29uc2lkZXIgYWRkaW5nIGEgYC5naXRpZ25vcmVgIGZpbGUgdG8gaWdub3JlIGdlbmVyYXRlZCBmaWxlcywgb2JqZWN0IGZpbGVzLCBhbmQgYnVpbGQgYXJ0aWZhY3RzLiBUaGlzIGtlZXBzIHlvdXIgcmVwb3NpdG9yeSBjbGVhbiBhbmQgYXZvaWRzIHRyYWNraW5nIHVubmVjZXNzYXJ5IGZpbGVzLg0KDQojIyMgQ29udGludW91cyBJbnRlZ3JhdGlvbg0KDQpJbnRlZ3JhdGUgeW91ciBNYWtlZmlsZSB3aXRoIGEgY29udGludW91cyBpbnRlZ3JhdGlvbiAoQ0kpIHN5c3RlbSBsaWtlIEplbmtpbnMsIFRyYXZpcyBDSSwgb3IgR2l0SHViIEFjdGlvbnMuIFRoaXMgZW5zdXJlcyB0aGF0IHlvdXIgcHJvamVjdCBpcyBhdXRvbWF0aWNhbGx5IGJ1aWx0IGFuZCB0ZXN0ZWQgb24gZXZlcnkgcHVzaCB0byB0aGUgcmVwb3NpdG9yeSwgaGVscGluZyBjYXRjaCBpc3N1ZXMgZWFybHkuDQoNCiMjIyBEZWJ1Z2dpbmcgTWFrZWZpbGVzDQoNCldoZW4gZGVidWdnaW5nIE1ha2VmaWxlcywgeW91IGNhbiB1c2UgdGhlIGAtbmAgb3IgYC0tanVzdC1wcmludGAgZmxhZyB3aXRoIGBtYWtlYCB0byBzZWUgdGhlIGNvbW1hbmRzIHRoYXQgd291bGQgYmUgZXhlY3V0ZWQgd2l0aG91dCBhY3R1YWxseSBydW5uaW5nIHRoZW0uIFRoaXMgY2FuIGhlbHAgaWRlbnRpZnkgaXNzdWVzIGluIHlvdXIgcnVsZXMgYW5kIGRlcGVuZGVuY2llcy4gQSBjb21tb24gbWlzdGFrZSBpcyBub3Qgc3RhcnRpbmcgYSBsaW5lIGZvciBhIGNvbW1hbmQgd2l0aCB0aGUgVEFCIG9yIHVzaW5nIGFuIGVkaXRvciB3aGljaCByZXBsYWNlcyBUQUIgd2l0aCA0IG9yIDggc3BhY2VzLg0KDQojIyMgVGVzdGluZyBhbmQgVmFsaWRhdGlvbg0KDQpSZWd1bGFybHkgdGVzdCBhbmQgdmFsaWRhdGUgeW91ciBNYWtlZmlsZXMgd2l0aCB2YXJpb3VzIGJ1aWxkIGNvbmZpZ3VyYXRpb25zIGFuZCBwbGF0Zm9ybXMgdG8gZW5zdXJlIHRoZXkgd29yayBjb3JyZWN0bHkgaW4gZGlmZmVyZW50IHNjZW5hcmlvcy4gQXV0b21hdGVkIHRlc3Rpbmcgb2YgdGhlIGJ1aWxkIHByb2Nlc3MgY2FuIGJlIGludmFsdWFibGUgaW4gY2F0Y2hpbmcgcmVncmVzc2lvbnMuDQoNCiMjIyBNb2R1bGFyaXphdGlvbg0KDQpGb3IgY29tcGxleCBwcm9qZWN0cywgY29uc2lkZXIgbW9kdWxhcml6aW5nIHlvdXIgTWFrZWZpbGUgYnkgc3BsaXR0aW5nIGl0IGludG8gbXVsdGlwbGUgc21hbGxlciBNYWtlZmlsZXMgb3IgaW5jbHVkaW5nIHNlcGFyYXRlIE1ha2VmaWxlcyBmb3Igc3BlY2lmaWMgY29tcG9uZW50cyBvciBzdWJzeXN0ZW1zLiBUaGlzIGNhbiBtYWtlIHRoZSBidWlsZCBzeXN0ZW0gbW9yZSBtYW5hZ2VhYmxlLg0KDQojIyMgUGVyZm9ybWFuY2UgT3B0aW1pemF0aW9uDQoNClByb2ZpbGUgYW5kIG9wdGltaXplIHlvdXIgYnVpbGQgcHJvY2VzcywgZXNwZWNpYWxseSBmb3IgbGFyZ2UgcHJvamVjdHMuIElkZW50aWZ5aW5nIGFuZCBlbGltaW5hdGluZyBib3R0bGVuZWNrcyBjYW4gc2lnbmlmaWNhbnRseSBpbXByb3ZlIGJ1aWxkIHRpbWVzIGFuZCBkZXZlbG9wZXIgcHJvZHVjdGl2aXR5Lg0KDQojIyMgQnVpbGQgVGFyZ2V0cw0KDQpEZWZpbmUgY2xlYXIgYW5kIHNwZWNpZmljIGJ1aWxkIHRhcmdldHMgKGUuZy4sIGBhbGxgLCBgY2xlYW5gLCBgdGVzdGAsIGBkb2NzYCwgYGluc3RhbGxgKSB0byBzdGFuZGFyZGl6ZSB0aGUgYnVpbGQgcHJvY2VzcyBhY3Jvc3MgeW91ciBwcm9qZWN0cyBhbmQgbWFrZSBpdCBlYXNpZXIgZm9yIHRlYW0gbWVtYmVycyB0byB1bmRlcnN0YW5kIGFuZCB1c2UgdGhlIE1ha2VmaWxlLg0KDQojIyMgRXJyb3IgSGFuZGxpbmcNCg0KSW1wbGVtZW50IGVycm9yIGhhbmRsaW5nIGluIHlvdXIgTWFrZWZpbGUgdG8gZGV0ZWN0IGFuZCByZXBvcnQgZXJyb3JzIGR1cmluZyB0aGUgYnVpbGQgcHJvY2Vzcy4gWW91IGNhbiB1c2UgY29uc3RydWN0cyBsaWtlIGB8fGAgdG8gZXhlY3V0ZSBjb21tYW5kcyBjb25kaXRpb25hbGx5IGJhc2VkIG9uIHRoZSBzdWNjZXNzIG9mIHByZXZpb3VzIGNvbW1hbmRzLg0KDQojIyMgQ29udGludW91cyBMZWFybmluZw0KDQpLZWVwIGV4cGxvcmluZyBhZHZhbmNlZCBNYWtlZmlsZSB0ZWNobmlxdWVzLCBiZXN0IHByYWN0aWNlcywgYW5kIG5ldyBmZWF0dXJlcyBhcyB5b3UgY29udGludWUgdG8gd29yayBvbiBkaWZmZXJlbnQgcHJvamVjdHMuIE1ha2VmaWxlcyBhcmUgYSB2ZXJzYXRpbGUgdG9vbCwgYW5kIHRoZXJlJ3MgYWx3YXlzIG1vcmUgdG8gbGVhcm4uDQoNCiMjIyBDb25jbHVzaW9uDQoNCkFkdmFuY2VkIHRlY2huaXF1ZXMgYW5kIGJlc3QgcHJhY3RpY2VzIGluIE1ha2VmaWxlcyBjYW4gc2lnbmlmaWNhbnRseSBlbmhhbmNlIHRoZSBlZmZpY2llbmN5LCByZWxpYWJpbGl0eSwgYW5kIG1haW50YWluYWJpbGl0eSBvZiB5b3VyIGJ1aWxkIHN5c3RlbXMuIEJ5IGFwcGx5aW5nIHRoZXNlIHByYWN0aWNlcywgeW91IGNhbiBjcmVhdGUgcm9idXN0IGFuZCBhZGFwdGFibGUgTWFrZWZpbGVzIHRoYXQgc3RyZWFtbGluZSB0aGUgZGV2ZWxvcG1lbnQgYW5kIGRlcGxveW1lbnQgb2YgeW91ciBzb2Z0d2FyZSBwcm9qZWN0cy4gQ29udGludW91c2x5IGltcHJvdmluZyB5b3VyIE1ha2VmaWxlIHNraWxscyBpcyBhIHZhbHVhYmxlIGFzc2V0IGluIHNvZnR3YXJlIGRldmVsb3BtZW50Lg0KDQojIyBTdW1tYXJ5DQoNCkluIHRoaXMgdHV0b3JpYWwgb24gKm1ha2UqIGZvciBwcm9ncmFtbWVycywgd2UgY292ZXJlZCBhIHdpZGUgcmFuZ2Ugb2YgdG9waWNzIHRvIGhlbHAgeW91IHVuZGVyc3RhbmQgYW5kIGVmZmVjdGl2ZWx5IHVzZSBNYWtlZmlsZXMgaW4geW91ciBzb2Z0d2FyZSBkZXZlbG9wbWVudCBwcm9qZWN0cy4gSGVyZSdzIGEgc3VtbWFyeSBvZiB0aGUga2V5IHBvaW50cyBjb3ZlcmVkIGluIHRoZSBzZWN0aW9uczoNCg0KMi4gICoqQmFzaWMgTWFrZWZpbGUgU3RydWN0dXJlKio6IFRoZSBmdW5kYW1lbnRhbCBzdHJ1Y3R1cmUgb2YgYSBNYWtlZmlsZSwgaW5jbHVkaW5nIHJ1bGVzLCB0YXJnZXRzLCBhbmQgY29tbWFuZHMuDQoNCjMuICAqKlRhcmdldCBSdWxlcyBhbmQgRGVwZW5kZW5jaWVzKio6IEhvdyB0byBkZWZpbmUgdGFyZ2V0cyBhbmQgdGhlaXIgZGVwZW5kZW5jaWVzLCBlbnN1cmluZyB0aGF0IE1ha2Uga25vd3Mgd2hlbiB0byByZWJ1aWxkIGEgdGFyZ2V0Lg0KDQo0LiAgKipJbXBsaWNpdCBSdWxlcyBhbmQgVmFyaWFibGVzKio6IEltcGxpY2l0IHJ1bGVzIHRoYXQgTWFrZSB1c2VzIGJ5IGRlZmF1bHQgYW5kIGhvdyB0byBvdmVycmlkZSB0aGVtIHVzaW5nIHZhcmlhYmxlcy4NCg0KNS4gICoqVXNlci1EZWZpbmVkIFZhcmlhYmxlcyoqOiBIb3cgdG8gZGVmaW5lIHlvdXIgb3duIHZhcmlhYmxlcyBpbiBNYWtlZmlsZXMgdG8gbWFrZSB0aGVtIG1vcmUgZmxleGlibGUgYW5kIG1haW50YWluYWJsZS4NCg0KNi4gICoqUGhvbnkgVGFyZ2V0cyoqOiBUaGUgY29uY2VwdCBvZiBwaG9ueSB0YXJnZXRzIGZvciBkZWZpbmluZyBhY3Rpb25zIG9yIHRhc2tzIHRoYXQgZG9uJ3QgcHJvZHVjZSBmaWxlcywgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZS4NCg0KNy4gICoqRGVwZW5kZW5jeSBNYW5hZ2VtZW50Kio6IEhvdyBNYWtlIG1hbmFnZXMgZGVwZW5kZW5jaWVzIGFuZCBhdXRvbWF0aWNhbGx5IHJlYnVpbGRzIHRhcmdldHMgd2hlbiBkZXBlbmRlbmNpZXMgY2hhbmdlLg0KDQo4LiAgKipDb25kaXRpb25hbCBTdGF0ZW1lbnRzKio6IFVzaW5nIGNvbmRpdGlvbmFsIHN0YXRlbWVudHMgdG8gY3JlYXRlIHJ1bGVzIGFuZCB0YXJnZXRzIHRoYXQgYWRhcHQgdG8gZGlmZmVyZW50IGNvbmRpdGlvbnMgb3IgY29uZmlndXJhdGlvbnMuDQoNCjkuICAqKlBhdHRlcm4gUnVsZXMgYW5kIEF1dG9tYXRpYyBQcmVyZXF1aXNpdGVzKio6IEhvdyB0byB1c2UgcGF0dGVybiBydWxlcyB0byBidWlsZCB0YXJnZXRzIHdpdGggc2ltaWxhciBwYXR0ZXJucyBhbmQgYXV0b21hdGljYWxseSBnZW5lcmF0ZSBkZXBlbmRlbmN5IGluZm9ybWF0aW9uLg0KDQoxMC4gKipNYW5hZ2luZyBMaWJyYXJpZXMgYW5kIExpbmtpbmcqKjogSW5jbHVkaW5nIGxpYnJhcmllcyBpbiB5b3VyIE1ha2VmaWxlLCBzcGVjaWZ5aW5nIGxpYnJhcnkgZGlyZWN0b3JpZXMsIGFuZCBoYW5kbGluZyBhZHZhbmNlZCBsaW5raW5nLg0KDQoxMS4gKipDbGVhbmluZyBhbmQgTWFpbnRlbmFuY2UqKjogQ3JlYXRpbmcgY2xlYW5pbmcgYW5kIG1haW50ZW5hbmNlIHRhcmdldHMsIGhhbmRsaW5nIHByb2plY3QgbWFpbnRlbmFuY2UsIGFuZCBhdXRvbWF0aW5nIGRlcGVuZGVuY3kgY2xlYW51cC4NCg0KMTIuICoqQWR2YW5jZWQgVGVjaG5pcXVlcyBhbmQgQmVzdCBQcmFjdGljZXMqKjogQWR2YW5jZWQgdGVjaG5pcXVlcyBhbmQgYmVzdCBwcmFjdGljZXMgZm9yIG1vcmUgZWZmaWNpZW50IGFuZCBtYWludGFpbmFibGUgTWFrZWZpbGVzLCBpbmNsdWRpbmcgdXNpbmcgdmFyaWFibGVzLCBwaG9ueSB0YXJnZXRzLCB3aWxkY2FyZHMsIGFuZCB2ZXJzaW9uIGNvbnRyb2wgaW50ZWdyYXRpb24uDQoNCkJ5IHVuZGVyc3RhbmRpbmcgYW5kIGFwcGx5aW5nIHRoZSBjb25jZXB0cyBhbmQgdGVjaG5pcXVlcyBkaXNjdXNzZWQgaW4gdGhpcyB0dXRvcmlhbCwgeW91IGNhbiBjcmVhdGUgcm9idXN0IGFuZCBlZmZpY2llbnQgTWFrZWZpbGVzIHRvIGF1dG9tYXRlIHlvdXIgYnVpbGQgcHJvY2Vzc2VzLCBtYW5hZ2UgZGVwZW5kZW5jaWVzLCBhbmQgbWFpbnRhaW4geW91ciBzb2Z0d2FyZSBwcm9qZWN0cyBlZmZlY3RpdmVseS4gTWFrZWZpbGVzIGFyZSBhIHZhbHVhYmxlIHRvb2wgaW4gdGhlIGFyc2VuYWwgb2YgYW55IGRldmVsb3BlciwgaGVscGluZyB0byBzdHJlYW1saW5lIHRoZSBkZXZlbG9wbWVudCB3b3JrZmxvdyBhbmQgZW5zdXJlIGNvbnNpc3RlbnQsIHJlbGlhYmxlIGJ1aWxkcy4NCg0KIyMjIFR1dG9yaWFsDQoNCk5vbmUgeWV0Lg0KDQojIyBGaWxlcyAmIFJlc291cmNlcw0KDQpgYGB7ciB6aXBGaWxlcywgZWNobz1GQUxTRX0NCnppcE5hbWUgPSBzcHJpbnRmKCJMZXNzb25GaWxlcy0lcy0lcy56aXAiLCANCiAgICAgICAgICAgICAgICAgcGFyYW1zJGNhdGVnb3J5LA0KICAgICAgICAgICAgICAgICBwYXJhbXMkbnVtYmVyKQ0KDQp0ZXh0QUxpbmsgPSBwYXN0ZTAoIkFsbCBGaWxlcyBmb3IgTGVzc29uICIsIA0KICAgICAgICAgICAgICAgcGFyYW1zJGNhdGVnb3J5LCIuIixwYXJhbXMkbnVtYmVyKQ0KDQojIGRvd25sb2FkRmlsZXNMaW5rKCkgaXMgaW5jbHVkZWQgZnJvbSBfaW5zZXJ0MkRCLlINCmtuaXRyOjpyYXdfaHRtbChkb3dubG9hZEZpbGVzTGluaygiLiIsIHppcE5hbWUsIHRleHRBTGluaykpDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIFJlZmVyZW5jZXMNCg0KW0xlYXJuIE1ha2VmaWxlc10oaHR0cHM6Ly9tYWtlZmlsZXR1dG9yaWFsLmNvbS8pDQoNCiMjIEVycmF0YQ0KDQpbTGV0IHVzIGtub3ddKGh0dHBzOi8vZm9ybS5qb3Rmb3JtLmNvbS8yMTIxODcwNzI3ODQxNTcpe3RhcmdldD0iX2JsYW5rIn0uDQoNCg==