python_step2.py
, will include:
- Setting Up VS Code
- Explanation: Introduction to using VS Code as an
Integrated Development Environment (IDE) for Python.
- Setup Steps: How to create and open files, use the
terminal, and navigate VS Code.
- Code Example: Basic
hello.py
setup.
- Basic Python Constructs
- Explanation: Introduction to variables, functions,
inputs, and outputs.
- Setup Steps: Creating and running a simple Python
program.
- Code Example: Simple
hello.py
program
with print statements and user input.
- Working with Functions
- Explanation: Explanation of functions, return
values, and side effects.
- Setup Steps: Creating and calling functions,
understanding return values.
- Code Example: Greeting chatbot.
- Using the Command Line
- Explanation: Basic command-line navigation and
Linux commands used in VS Code.
- Setup Steps: Basic commands like
ls
,
cd
, mkdir
, rm
, and file
navigation.
- Code Example: Command-line operations in VS Code’s
terminal.
- Advanced Concepts
- Explanation: Further exploration of functions, side
effects, and variable scope.
- Setup Steps: Using global variables and modifying
them.
- Code Example: Program showing variable scope and
side effects.
python_step2.py
Module
# python_step2.py
# --- Section 1: Setting Up VS Code ---
"""
Visual Studio Code (VS Code) is a powerful IDE used for writing Python code.
This section will help set up a simple program and execute it in VS Code.
"""
# Step 1: Open VS Code
# Step 2: Create a new file named `hello.py`
# Step 3: In `hello.py`, write a simple print statement and save the file.
# Step 4: Use the terminal to run the Python script.
# Command to run: python hello.py
print("Hello, world!") # Example output
# --- Section 2: Basic Python Constructs ---
"""
In this section, learn about variables and basic input-output.
"""
# Variables store information that can change over time.
name = input("Enter your name: ") # Getting user input
age = 25 # A sample integer variable
# Print combines text and variables to produce readable output.
print(f"Hello, {name}! You are {age} years old.")
# --- Section 3: Working with Functions ---
"""
Functions are reusable blocks of code that can take inputs and return outputs.
This section includes defining functions and understanding return values.
"""
def greet_user(name):
"""
Function that greets the user by name.
:param name: str - The user's name
:return: str - A personalized greeting message
"""
return f"Hello, {name}!"
# Example of calling a function and printing its return value.
user_name = input("Enter your name: ")
print(greet_user(user_name))
# --- Section 4: Using the Command Line ---
"""
The command line is a text-based interface for interacting with the computer.
In VS Code, the terminal can be used to execute various commands.
Here are some common Linux commands for file management:
- `ls`: List files and folders
- `cd <directory>`: Change directory
- `mkdir <folder_name>`: Create a new folder
- `rm <file_name>`: Remove (delete) a file
- `clear`: Clear the terminal output
"""
# Command-line operations (use these commands in the VS Code terminal)
# Example terminal commands to try in VS Code:
# ls
# cd ..
# mkdir new_folder
# rm old_file.py
# --- Section 5: Advanced Concepts: Side Effects and Scope ---
"""
This section explores variable scope and side effects in Python.
Side effects occur when a function modifies something outside its local environment.
For example, updating a global variable from within a function.
"""
# Global variable representing the mood of a chatbot
emoticon = ":(" # Sad face by default
def update_mood(new_mood):
"""
Updates the global `emoticon` to a new mood.
:param new_mood: str - New emoticon
:side effect: modifies global `emoticon`
"""
global emoticon # Declare that we're modifying the global variable
emoticon = new_mood
def say(phrase):
"""
Prints a phrase along with the current mood.
:param phrase: str - The phrase to print
"""
print(f"{phrase} {emoticon}")
# Usage
say("Is anyone there?")
update_mood(":D") # Changing the mood to a happy face
say("Oh, hi!") # Now the chatbot responds with a happy face
# --- Additional References ---
"""
For further exploration:
- Python documentation: https://docs.python.org/3/
- CS50 Python Course: https://cs50.harvard.edu/python/
- VS Code Documentation: https://code.visualstudio.com/docs
"""
Explanations & Concepts (for Study)
- VS Code Basics
- VS Code is a powerful IDE for coding in Python.
- You can install it locally or use it online via GitHub
Codespaces.
- Essential sections: File Explorer, Tabs for files, Terminal.
- Basic Constructs: Variables and Input/Output
- Variables: Containers for data (e.g.,
age = 25
).
- Input:
input()
collects data from the
user.
- Output:
print()
displays data to the
screen.
- Functions
- Functions are defined using
def
, and they can take
parameters.
- Return Value: Functions can return data using
return
.
- Example:
def greet_user(name): return f"Hello, {name}!"
- Command Line Commands
- List (
ls
): Shows files in the current
directory.
- Change Directory (
cd
): Navigate
between directories.
- Make Directory (
mkdir
): Creates a new
folder.
- Remove (
rm
): Deletes files or
folders.
- Advanced Concepts: Side Effects and Scope
- Side Effect: When a function changes something
outside its scope.
- Scope: Where variables are accessible (local
vs. global).
- Global Keyword: Declares global variables to modify
in functions.
- Revised? Check format not sure I like it. But also feeling lazy and
needing a break. 4 days ago I have never used python. Now, I’m cramming
my brain and it’s asking for a break from python and an introduction of
some wine. SO imma do that now.
python_step2.py
Module
"""
PYTHON STEP 2: A COMPREHENSIVE GUIDE
Welcome to Python Step 2! This guide is designed to take you through Python programming essentials.
Each section includes a description, examples, and code snippets to help you learn and practice.
--- Table of Contents ---
1. Setting Up Visual Studio Code
2. Basics of Python: Variables, Input, and Output
3. Working with Functions
4. Command-Line Basics in VS Code
5. Advanced Concepts: Scope and Side Effects
"""
# --- SECTION 1: SETTING UP VISUAL STUDIO CODE ---
"""
Visual Studio Code (VS Code) is a powerful and popular Integrated Development Environment (IDE) for coding.
It's widely used because it's free, open-source, and has many useful features.
- **IDE vs. Text Editor**: VS Code is technically a text editor, but it functions like an IDE.
- **How to Install**: You can download it for free from https://code.visualstudio.com/ or use it online via GitHub Codespaces.
- **Key Components**:
- *File Explorer*: Shows your files and folders.
- *Tabs*: Each file you open in VS Code opens in a new tab.
- *Terminal*: A command-line interface within VS Code for executing code and commands.
- **Creating a Python File**:
1. Open VS Code.
2. Create a new file and name it with the `.py` extension (e.g., `hello.py`).
3. Write your code, save the file, and run it in the terminal.
"""
# Example Code: A Basic Python Program in `hello.py`
print("Hello, world!") # Output: Hello, world!
# To run this, open the terminal in VS Code and type:
# python hello.py
# --- SECTION 2: BASICS OF PYTHON: VARIABLES, INPUT, AND OUTPUT ---
"""
In Python, we use variables to store data, `print()` to output information, and `input()` to collect data from users.
- **Variables**: Containers for storing data values.
- Variables can store numbers, strings (text), and other types of data.
- Use an `=` to assign values to variables (e.g., `age = 25`).
- **Input and Output**:
- `input()` collects data from the user. This data is always stored as a string.
- `print()` displays data to the screen.
"""
# Example Code: Collecting and Displaying User Input
name = input("Enter your name: ") # Collects the user's name
age = 25 # An example of a variable holding a number
# Print combines text and variables to produce readable output
print(f"Hello, {name}! You are {age} years old.") # Output: Hello, [name]! You are 25 years old.
# --- SECTION 3: WORKING WITH FUNCTIONS ---
"""
Functions are reusable blocks of code that help us organize our programs and avoid repetition.
- **Defining Functions**:
- Use the `def` keyword, followed by the function's name, parentheses, and a colon.
- Write the code to be executed inside the function, indented beneath it.
- **Calling Functions**:
- You "call" a function by writing its name followed by parentheses.
- **Parameters and Return Values**:
- *Parameters*: Data you pass to the function inside the parentheses.
- *Return Value*: The result a function can send back to where it was called, using the `return` keyword.
"""
# Example Code: A Simple Greeting Function
def greet_user(name):
"""
This function takes a user's name and returns a greeting.
:param name: str - The user's name
:return: str - A personalized greeting message
"""
return f"Hello, {name}!"
# Calling the function and printing its return value
user_name = input("Enter your name: ")
print(greet_user(user_name)) # Output: Hello, [name]!
# --- SECTION 4: COMMAND-LINE BASICS IN VS CODE ---
"""
The command line is a text-based interface for interacting with the computer, and in VS Code, it's accessed through the Terminal.
- **Basic Commands**:
- `ls`: Lists files and folders in the current directory.
- `cd <directory>`: Changes the current directory.
- `mkdir <folder_name>`: Creates a new folder.
- `rm <file_name>`: Removes (deletes) a file.
- `clear`: Clears the terminal window.
- **Navigating the File System**:
- Use `cd ..` to go up one directory level.
- Use the Tab key for auto-completion.
"""
# Example Terminal Commands to Try in VS Code (These are not Python code but typed in the VS Code Terminal)
# ls # Lists all files and directories in the current folder
# cd new_folder # Changes to the directory named 'new_folder'
# mkdir my_folder # Creates a new folder called 'my_folder'
# rm unwanted_file.py # Deletes a file called 'unwanted_file.py'
# --- SECTION 5: ADVANCED CONCEPTS: SCOPE AND SIDE EFFECTS ---
"""
Understanding scope and side effects is important for writing clear and bug-free code.
- **Scope**:
- *Local Scope*: Variables created inside a function are local to that function and can't be accessed outside.
- *Global Scope*: Variables defined outside of functions are global and can be accessed by any code in the file.
- **Side Effects**:
- Side effects occur when a function modifies a variable outside its scope, often using global variables.
- Example: Changing a global variable from inside a function.
"""
# Example Code: Using Global Variables and Modifying Scope
# A global variable representing the "mood" of a chatbot
mood = ":(" # Default to sad face
def update_mood(new_mood):
"""
Updates the global mood variable to a new mood.
:param new_mood: str - The new mood emoticon
:side effect: modifies global `mood`
"""
global mood # Declares that we want to modify the global variable
mood = new_mood
def say(phrase):
"""
Prints a phrase with the current mood of the chatbot.
:param phrase: str - The phrase to print
"""
print(f"{phrase} {mood}")
# Demonstrating function side effects and scope
say("Is anyone there?") # Output: Is anyone there? :(
update_mood(":D") # Change mood to a happy face
say("Oh, hi!") # Output: Oh, hi! :D
"""
--- SUMMARY ---
This guide covered:
1. Setting up Visual Studio Code and creating Python files.
2. Using variables, input, and output in Python.
3. Creating and calling functions, with an emphasis on parameters and return values.
4. Navigating the command line in VS Code.
5. Advanced concepts of scope and side effects.
--- Additional Resources ---
- [Python Documentation](https://docs.python.org/3/)
- [VS Code Documentation](https://code.visualstudio.com/docs)
- [CS50 Python Course](https://cs50.harvard.edu/python/)
"""
Python in Visual Studio Code (VS Code)
- VS Code Basics:
- VS Code is a popular IDE (Integrated Development Environment) for
coding, especially in Python.
- It’s available both as a downloadable application and as an online
tool via GitHub Codespaces.
- Key Components:
- File Explorer: View files and folders.
- Tabs: Edit multiple files at once.
- Terminal: Command-line interface to execute Python code and
system commands.
- Running Python Code in VS Code:
- Create a new file with a
.py
extension (e.g.,
hello.py
).
- Use the Terminal to run the code by typing:
python hello.py
.
Functions in Python
- What is a Function?:
- Functions are reusable blocks of code that perform specific
tasks.
- Defined with the
def
keyword, followed by the function
name, parentheses, and a colon.
- Parameters and Return Values:
Parameters are data that you pass into
functions.
Return Values are results a function can send back using
return
.
Example:
def greet_user(name):
return f"Hello, {name}!"
- Calling a Function:
- To use a function, write its name followed by parentheses with any
needed arguments inside.
- Example:
print(greet_user("Alice"))
outputs “Hello,
Alice!”
Using the Command Line in VS Code
- Basic Commands:
ls
: Lists files in the current
directory.
cd <directory>
: Changes the
working directory.
mkdir <folder_name>
: Creates a
new folder.
rm <file_name>
: Deletes a
specified file.
clear
: Clears the Terminal window for
a fresh start.
- Navigation Tips:
- Use
cd ..
to go up one directory level.
- Tab key helps with autocomplete for file and folder names.
Advanced Concepts: Scope and Side Effects
- Scope:
- Local Scope: Variables defined inside functions that can
only be used within that function.
- Global Scope: Variables defined outside functions,
accessible throughout the file.
- Side Effects:
A side effect occurs when a function modifies something outside
its scope, like changing a global variable.
Use global
to declare that a function will modify a
global variable.
Example:
mood = ":(" # Global variable
def update_mood(new_mood):
global mood
mood = new_mood # Modifies the global variable
update_mood(":D") # Now mood is ":D"
Review Summary
- VS Code: Set up files, run Python code, and use the
Terminal.
- Basic Python: Use variables,
input()
,
and print()
.
- Functions: Define, call, pass parameters, and
handle return values.
- Command-Line Skills: Navigate and manage files in
VS Code’s Terminal.
- Scope & Side Effects: Understand local
vs. global scope, and when functions can modify outside variables.
LS0tDQp0aXRsZTogIlB5dGhvbiBTdGVwIDIiDQphdXRob3I6ICJKZXNzaWNhIE1jUGhhdWwiDQpkYXRlOiBEZWNlbWJlciAzLCAyMDIyDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCiBgcHl0aG9uX3N0ZXAyLnB5YCwgd2lsbCBpbmNsdWRlOg0KDQoxLiAqKlNldHRpbmcgVXAgVlMgQ29kZSoqICANCiAgIC0gKipFeHBsYW5hdGlvbioqOiBJbnRyb2R1Y3Rpb24gdG8gdXNpbmcgVlMgQ29kZSBhcyBhbiBJbnRlZ3JhdGVkIERldmVsb3BtZW50IEVudmlyb25tZW50IChJREUpIGZvciBQeXRob24uDQogICAtICoqU2V0dXAgU3RlcHMqKjogSG93IHRvIGNyZWF0ZSBhbmQgb3BlbiBmaWxlcywgdXNlIHRoZSB0ZXJtaW5hbCwgYW5kIG5hdmlnYXRlIFZTIENvZGUuDQogICAtICoqQ29kZSBFeGFtcGxlKio6IEJhc2ljIGBoZWxsby5weWAgc2V0dXAuDQoNCjIuICoqQmFzaWMgUHl0aG9uIENvbnN0cnVjdHMqKiAgDQogICAtICoqRXhwbGFuYXRpb24qKjogSW50cm9kdWN0aW9uIHRvIHZhcmlhYmxlcywgZnVuY3Rpb25zLCBpbnB1dHMsIGFuZCBvdXRwdXRzLg0KICAgLSAqKlNldHVwIFN0ZXBzKio6IENyZWF0aW5nIGFuZCBydW5uaW5nIGEgc2ltcGxlIFB5dGhvbiBwcm9ncmFtLg0KICAgLSAqKkNvZGUgRXhhbXBsZSoqOiBTaW1wbGUgYGhlbGxvLnB5YCBwcm9ncmFtIHdpdGggcHJpbnQgc3RhdGVtZW50cyBhbmQgdXNlciBpbnB1dC4NCg0KMy4gKipXb3JraW5nIHdpdGggRnVuY3Rpb25zKiogIA0KICAgLSAqKkV4cGxhbmF0aW9uKio6IEV4cGxhbmF0aW9uIG9mIGZ1bmN0aW9ucywgcmV0dXJuIHZhbHVlcywgYW5kIHNpZGUgZWZmZWN0cy4NCiAgIC0gKipTZXR1cCBTdGVwcyoqOiBDcmVhdGluZyBhbmQgY2FsbGluZyBmdW5jdGlvbnMsIHVuZGVyc3RhbmRpbmcgcmV0dXJuIHZhbHVlcy4NCiAgIC0gKipDb2RlIEV4YW1wbGUqKjogR3JlZXRpbmcgY2hhdGJvdC4NCg0KNC4gKipVc2luZyB0aGUgQ29tbWFuZCBMaW5lKiogIA0KICAgLSAqKkV4cGxhbmF0aW9uKio6IEJhc2ljIGNvbW1hbmQtbGluZSBuYXZpZ2F0aW9uIGFuZCBMaW51eCBjb21tYW5kcyB1c2VkIGluIFZTIENvZGUuDQogICAtICoqU2V0dXAgU3RlcHMqKjogQmFzaWMgY29tbWFuZHMgbGlrZSBgbHNgLCBgY2RgLCBgbWtkaXJgLCBgcm1gLCBhbmQgZmlsZSBuYXZpZ2F0aW9uLg0KICAgLSAqKkNvZGUgRXhhbXBsZSoqOiBDb21tYW5kLWxpbmUgb3BlcmF0aW9ucyBpbiBWUyBDb2RlJ3MgdGVybWluYWwuDQoNCjUuICoqQWR2YW5jZWQgQ29uY2VwdHMqKiAgDQogICAtICoqRXhwbGFuYXRpb24qKjogRnVydGhlciBleHBsb3JhdGlvbiBvZiBmdW5jdGlvbnMsIHNpZGUgZWZmZWN0cywgYW5kIHZhcmlhYmxlIHNjb3BlLg0KICAgLSAqKlNldHVwIFN0ZXBzKio6IFVzaW5nIGdsb2JhbCB2YXJpYWJsZXMgYW5kIG1vZGlmeWluZyB0aGVtLg0KICAgLSAqKkNvZGUgRXhhbXBsZSoqOiBQcm9ncmFtIHNob3dpbmcgdmFyaWFibGUgc2NvcGUgYW5kIHNpZGUgZWZmZWN0cy4NCg0KLS0tDQoNCiMjIyBgcHl0aG9uX3N0ZXAyLnB5YCBNb2R1bGUNCg0KYGBgcHl0aG9uDQojIHB5dGhvbl9zdGVwMi5weQ0KDQojIC0tLSBTZWN0aW9uIDE6IFNldHRpbmcgVXAgVlMgQ29kZSAtLS0NCiIiIg0KVmlzdWFsIFN0dWRpbyBDb2RlIChWUyBDb2RlKSBpcyBhIHBvd2VyZnVsIElERSB1c2VkIGZvciB3cml0aW5nIFB5dGhvbiBjb2RlLg0KVGhpcyBzZWN0aW9uIHdpbGwgaGVscCBzZXQgdXAgYSBzaW1wbGUgcHJvZ3JhbSBhbmQgZXhlY3V0ZSBpdCBpbiBWUyBDb2RlLg0KIiIiDQoNCiMgU3RlcCAxOiBPcGVuIFZTIENvZGUNCiMgU3RlcCAyOiBDcmVhdGUgYSBuZXcgZmlsZSBuYW1lZCBgaGVsbG8ucHlgDQojIFN0ZXAgMzogSW4gYGhlbGxvLnB5YCwgd3JpdGUgYSBzaW1wbGUgcHJpbnQgc3RhdGVtZW50IGFuZCBzYXZlIHRoZSBmaWxlLg0KIyBTdGVwIDQ6IFVzZSB0aGUgdGVybWluYWwgdG8gcnVuIHRoZSBQeXRob24gc2NyaXB0Lg0KIyBDb21tYW5kIHRvIHJ1bjogcHl0aG9uIGhlbGxvLnB5DQoNCnByaW50KCJIZWxsbywgd29ybGQhIikgICMgRXhhbXBsZSBvdXRwdXQNCg0KIyAtLS0gU2VjdGlvbiAyOiBCYXNpYyBQeXRob24gQ29uc3RydWN0cyAtLS0NCiIiIg0KSW4gdGhpcyBzZWN0aW9uLCBsZWFybiBhYm91dCB2YXJpYWJsZXMgYW5kIGJhc2ljIGlucHV0LW91dHB1dC4NCiIiIg0KDQojIFZhcmlhYmxlcyBzdG9yZSBpbmZvcm1hdGlvbiB0aGF0IGNhbiBjaGFuZ2Ugb3ZlciB0aW1lLg0KbmFtZSA9IGlucHV0KCJFbnRlciB5b3VyIG5hbWU6ICIpICAjIEdldHRpbmcgdXNlciBpbnB1dA0KYWdlID0gMjUgICMgQSBzYW1wbGUgaW50ZWdlciB2YXJpYWJsZQ0KDQojIFByaW50IGNvbWJpbmVzIHRleHQgYW5kIHZhcmlhYmxlcyB0byBwcm9kdWNlIHJlYWRhYmxlIG91dHB1dC4NCnByaW50KGYiSGVsbG8sIHtuYW1lfSEgWW91IGFyZSB7YWdlfSB5ZWFycyBvbGQuIikNCg0KIyAtLS0gU2VjdGlvbiAzOiBXb3JraW5nIHdpdGggRnVuY3Rpb25zIC0tLQ0KIiIiDQpGdW5jdGlvbnMgYXJlIHJldXNhYmxlIGJsb2NrcyBvZiBjb2RlIHRoYXQgY2FuIHRha2UgaW5wdXRzIGFuZCByZXR1cm4gb3V0cHV0cy4NClRoaXMgc2VjdGlvbiBpbmNsdWRlcyBkZWZpbmluZyBmdW5jdGlvbnMgYW5kIHVuZGVyc3RhbmRpbmcgcmV0dXJuIHZhbHVlcy4NCiIiIg0KDQpkZWYgZ3JlZXRfdXNlcihuYW1lKToNCiAgICAiIiINCiAgICBGdW5jdGlvbiB0aGF0IGdyZWV0cyB0aGUgdXNlciBieSBuYW1lLg0KICAgIDpwYXJhbSBuYW1lOiBzdHIgLSBUaGUgdXNlcidzIG5hbWUNCiAgICA6cmV0dXJuOiBzdHIgLSBBIHBlcnNvbmFsaXplZCBncmVldGluZyBtZXNzYWdlDQogICAgIiIiDQogICAgcmV0dXJuIGYiSGVsbG8sIHtuYW1lfSEiDQoNCiMgRXhhbXBsZSBvZiBjYWxsaW5nIGEgZnVuY3Rpb24gYW5kIHByaW50aW5nIGl0cyByZXR1cm4gdmFsdWUuDQp1c2VyX25hbWUgPSBpbnB1dCgiRW50ZXIgeW91ciBuYW1lOiAiKQ0KcHJpbnQoZ3JlZXRfdXNlcih1c2VyX25hbWUpKQ0KDQojIC0tLSBTZWN0aW9uIDQ6IFVzaW5nIHRoZSBDb21tYW5kIExpbmUgLS0tDQoiIiINClRoZSBjb21tYW5kIGxpbmUgaXMgYSB0ZXh0LWJhc2VkIGludGVyZmFjZSBmb3IgaW50ZXJhY3Rpbmcgd2l0aCB0aGUgY29tcHV0ZXIuDQpJbiBWUyBDb2RlLCB0aGUgdGVybWluYWwgY2FuIGJlIHVzZWQgdG8gZXhlY3V0ZSB2YXJpb3VzIGNvbW1hbmRzLg0KSGVyZSBhcmUgc29tZSBjb21tb24gTGludXggY29tbWFuZHMgZm9yIGZpbGUgbWFuYWdlbWVudDoNCiAgICAtIGBsc2A6IExpc3QgZmlsZXMgYW5kIGZvbGRlcnMNCiAgICAtIGBjZCA8ZGlyZWN0b3J5PmA6IENoYW5nZSBkaXJlY3RvcnkNCiAgICAtIGBta2RpciA8Zm9sZGVyX25hbWU+YDogQ3JlYXRlIGEgbmV3IGZvbGRlcg0KICAgIC0gYHJtIDxmaWxlX25hbWU+YDogUmVtb3ZlIChkZWxldGUpIGEgZmlsZQ0KICAgIC0gYGNsZWFyYDogQ2xlYXIgdGhlIHRlcm1pbmFsIG91dHB1dA0KIiIiDQoNCiMgQ29tbWFuZC1saW5lIG9wZXJhdGlvbnMgKHVzZSB0aGVzZSBjb21tYW5kcyBpbiB0aGUgVlMgQ29kZSB0ZXJtaW5hbCkNCg0KIyBFeGFtcGxlIHRlcm1pbmFsIGNvbW1hbmRzIHRvIHRyeSBpbiBWUyBDb2RlOg0KIyBscw0KIyBjZCAuLg0KIyBta2RpciBuZXdfZm9sZGVyDQojIHJtIG9sZF9maWxlLnB5DQoNCiMgLS0tIFNlY3Rpb24gNTogQWR2YW5jZWQgQ29uY2VwdHM6IFNpZGUgRWZmZWN0cyBhbmQgU2NvcGUgLS0tDQoiIiINClRoaXMgc2VjdGlvbiBleHBsb3JlcyB2YXJpYWJsZSBzY29wZSBhbmQgc2lkZSBlZmZlY3RzIGluIFB5dGhvbi4NClNpZGUgZWZmZWN0cyBvY2N1ciB3aGVuIGEgZnVuY3Rpb24gbW9kaWZpZXMgc29tZXRoaW5nIG91dHNpZGUgaXRzIGxvY2FsIGVudmlyb25tZW50Lg0KRm9yIGV4YW1wbGUsIHVwZGF0aW5nIGEgZ2xvYmFsIHZhcmlhYmxlIGZyb20gd2l0aGluIGEgZnVuY3Rpb24uDQoiIiINCg0KIyBHbG9iYWwgdmFyaWFibGUgcmVwcmVzZW50aW5nIHRoZSBtb29kIG9mIGEgY2hhdGJvdA0KZW1vdGljb24gPSAiOigiICAjIFNhZCBmYWNlIGJ5IGRlZmF1bHQNCg0KZGVmIHVwZGF0ZV9tb29kKG5ld19tb29kKToNCiAgICAiIiINCiAgICBVcGRhdGVzIHRoZSBnbG9iYWwgYGVtb3RpY29uYCB0byBhIG5ldyBtb29kLg0KICAgIDpwYXJhbSBuZXdfbW9vZDogc3RyIC0gTmV3IGVtb3RpY29uDQogICAgOnNpZGUgZWZmZWN0OiBtb2RpZmllcyBnbG9iYWwgYGVtb3RpY29uYA0KICAgICIiIg0KICAgIGdsb2JhbCBlbW90aWNvbiAgIyBEZWNsYXJlIHRoYXQgd2UncmUgbW9kaWZ5aW5nIHRoZSBnbG9iYWwgdmFyaWFibGUNCiAgICBlbW90aWNvbiA9IG5ld19tb29kDQoNCmRlZiBzYXkocGhyYXNlKToNCiAgICAiIiINCiAgICBQcmludHMgYSBwaHJhc2UgYWxvbmcgd2l0aCB0aGUgY3VycmVudCBtb29kLg0KICAgIDpwYXJhbSBwaHJhc2U6IHN0ciAtIFRoZSBwaHJhc2UgdG8gcHJpbnQNCiAgICAiIiINCiAgICBwcmludChmIntwaHJhc2V9IHtlbW90aWNvbn0iKQ0KDQojIFVzYWdlDQpzYXkoIklzIGFueW9uZSB0aGVyZT8iKQ0KdXBkYXRlX21vb2QoIjpEIikgICMgQ2hhbmdpbmcgdGhlIG1vb2QgdG8gYSBoYXBweSBmYWNlDQpzYXkoIk9oLCBoaSEiKSAgIyBOb3cgdGhlIGNoYXRib3QgcmVzcG9uZHMgd2l0aCBhIGhhcHB5IGZhY2UNCg0KIyAtLS0gQWRkaXRpb25hbCBSZWZlcmVuY2VzIC0tLQ0KIiIiDQpGb3IgZnVydGhlciBleHBsb3JhdGlvbjoNCi0gUHl0aG9uIGRvY3VtZW50YXRpb246IGh0dHBzOi8vZG9jcy5weXRob24ub3JnLzMvDQotIENTNTAgUHl0aG9uIENvdXJzZTogaHR0cHM6Ly9jczUwLmhhcnZhcmQuZWR1L3B5dGhvbi8NCi0gVlMgQ29kZSBEb2N1bWVudGF0aW9uOiBodHRwczovL2NvZGUudmlzdWFsc3R1ZGlvLmNvbS9kb2NzDQoiIiINCmBgYA0KDQotLS0NCg0KIyMjIEV4cGxhbmF0aW9ucyAmIENvbmNlcHRzIChmb3IgU3R1ZHkpDQoNCjEuICoqVlMgQ29kZSBCYXNpY3MqKiAgDQogICAtIFZTIENvZGUgaXMgYSBwb3dlcmZ1bCBJREUgZm9yIGNvZGluZyBpbiBQeXRob24uDQogICAtIFlvdSBjYW4gaW5zdGFsbCBpdCBsb2NhbGx5IG9yIHVzZSBpdCBvbmxpbmUgdmlhIEdpdEh1YiBDb2Rlc3BhY2VzLg0KICAgLSBFc3NlbnRpYWwgc2VjdGlvbnM6IEZpbGUgRXhwbG9yZXIsIFRhYnMgZm9yIGZpbGVzLCBUZXJtaW5hbC4NCg0KMi4gKipCYXNpYyBDb25zdHJ1Y3RzOiBWYXJpYWJsZXMgYW5kIElucHV0L091dHB1dCoqICANCiAgIC0gKipWYXJpYWJsZXMqKjogQ29udGFpbmVycyBmb3IgZGF0YSAoZS5nLiwgYGFnZSA9IDI1YCkuDQogICAtICoqSW5wdXQqKjogYGlucHV0KClgIGNvbGxlY3RzIGRhdGEgZnJvbSB0aGUgdXNlci4NCiAgIC0gKipPdXRwdXQqKjogYHByaW50KClgIGRpc3BsYXlzIGRhdGEgdG8gdGhlIHNjcmVlbi4NCg0KMy4gKipGdW5jdGlvbnMqKiAgDQogICAtIEZ1bmN0aW9ucyBhcmUgZGVmaW5lZCB1c2luZyBgZGVmYCwgYW5kIHRoZXkgY2FuIHRha2UgcGFyYW1ldGVycy4NCiAgIC0gKipSZXR1cm4gVmFsdWUqKjogRnVuY3Rpb25zIGNhbiByZXR1cm4gZGF0YSB1c2luZyBgcmV0dXJuYC4NCiAgIC0gKipFeGFtcGxlKio6IGBkZWYgZ3JlZXRfdXNlcihuYW1lKTogcmV0dXJuIGYiSGVsbG8sIHtuYW1lfSEiYA0KDQo0LiAqKkNvbW1hbmQgTGluZSBDb21tYW5kcyoqICANCiAgIC0gKipMaXN0IChgbHNgKSoqOiBTaG93cyBmaWxlcyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuDQogICAtICoqQ2hhbmdlIERpcmVjdG9yeSAoYGNkYCkqKjogTmF2aWdhdGUgYmV0d2VlbiBkaXJlY3Rvcmllcy4NCiAgIC0gKipNYWtlIERpcmVjdG9yeSAoYG1rZGlyYCkqKjogQ3JlYXRlcyBhIG5ldyBmb2xkZXIuDQogICAtICoqUmVtb3ZlIChgcm1gKSoqOiBEZWxldGVzIGZpbGVzIG9yIGZvbGRlcnMuDQoNCjUuICoqQWR2YW5jZWQgQ29uY2VwdHM6IFNpZGUgRWZmZWN0cyBhbmQgU2NvcGUqKiAgDQogICAtICoqU2lkZSBFZmZlY3QqKjogV2hlbiBhIGZ1bmN0aW9uIGNoYW5nZXMgc29tZXRoaW5nIG91dHNpZGUgaXRzIHNjb3BlLg0KICAgLSAqKlNjb3BlKio6IFdoZXJlIHZhcmlhYmxlcyBhcmUgYWNjZXNzaWJsZSAobG9jYWwgdnMuIGdsb2JhbCkuDQogICAtICoqR2xvYmFsIEtleXdvcmQqKjogRGVjbGFyZXMgZ2xvYmFsIHZhcmlhYmxlcyB0byBtb2RpZnkgaW4gZnVuY3Rpb25zLg0KDQotLS0NCg0KDQotIFJldmlzZWQ/IENoZWNrIGZvcm1hdCBub3Qgc3VyZSBJIGxpa2UgaXQuICBCdXQgYWxzbyBmZWVsaW5nIGxhenkgYW5kIG5lZWRpbmcgYSBicmVhay4gIDQgZGF5cyBhZ28gSSBoYXZlIG5ldmVyIHVzZWQgcHl0aG9uLiAgTm93LCBJJ20gY3JhbW1pbmcgbXkgYnJhaW4gYW5kIGl0J3MgYXNraW5nIGZvciBhIGJyZWFrIGZyb20gcHl0aG9uIGFuZCBhbiBpbnRyb2R1Y3Rpb24gb2Ygc29tZSB3aW5lLiAgU08gaW1tYSBkbyB0aGF0IG5vdy4gDQoNCg0KDQoNCi0tLQ0KDQojIyMgYHB5dGhvbl9zdGVwMi5weWAgTW9kdWxlDQoNCmBgYHB5dGhvbg0KIiIiDQpQWVRIT04gU1RFUCAyOiBBIENPTVBSRUhFTlNJVkUgR1VJREUNCg0KV2VsY29tZSB0byBQeXRob24gU3RlcCAyISBUaGlzIGd1aWRlIGlzIGRlc2lnbmVkIHRvIHRha2UgeW91IHRocm91Z2ggUHl0aG9uIHByb2dyYW1taW5nIGVzc2VudGlhbHMuDQpFYWNoIHNlY3Rpb24gaW5jbHVkZXMgYSBkZXNjcmlwdGlvbiwgZXhhbXBsZXMsIGFuZCBjb2RlIHNuaXBwZXRzIHRvIGhlbHAgeW91IGxlYXJuIGFuZCBwcmFjdGljZS4NCg0KLS0tIFRhYmxlIG9mIENvbnRlbnRzIC0tLQ0KMS4gU2V0dGluZyBVcCBWaXN1YWwgU3R1ZGlvIENvZGUNCjIuIEJhc2ljcyBvZiBQeXRob246IFZhcmlhYmxlcywgSW5wdXQsIGFuZCBPdXRwdXQNCjMuIFdvcmtpbmcgd2l0aCBGdW5jdGlvbnMNCjQuIENvbW1hbmQtTGluZSBCYXNpY3MgaW4gVlMgQ29kZQ0KNS4gQWR2YW5jZWQgQ29uY2VwdHM6IFNjb3BlIGFuZCBTaWRlIEVmZmVjdHMNCg0KIiIiDQoNCiMgLS0tIFNFQ1RJT04gMTogU0VUVElORyBVUCBWSVNVQUwgU1RVRElPIENPREUgLS0tDQoNCiIiIg0KVmlzdWFsIFN0dWRpbyBDb2RlIChWUyBDb2RlKSBpcyBhIHBvd2VyZnVsIGFuZCBwb3B1bGFyIEludGVncmF0ZWQgRGV2ZWxvcG1lbnQgRW52aXJvbm1lbnQgKElERSkgZm9yIGNvZGluZy4NCkl0J3Mgd2lkZWx5IHVzZWQgYmVjYXVzZSBpdCdzIGZyZWUsIG9wZW4tc291cmNlLCBhbmQgaGFzIG1hbnkgdXNlZnVsIGZlYXR1cmVzLg0KDQotICoqSURFIHZzLiBUZXh0IEVkaXRvcioqOiBWUyBDb2RlIGlzIHRlY2huaWNhbGx5IGEgdGV4dCBlZGl0b3IsIGJ1dCBpdCBmdW5jdGlvbnMgbGlrZSBhbiBJREUuDQotICoqSG93IHRvIEluc3RhbGwqKjogWW91IGNhbiBkb3dubG9hZCBpdCBmb3IgZnJlZSBmcm9tIGh0dHBzOi8vY29kZS52aXN1YWxzdHVkaW8uY29tLyBvciB1c2UgaXQgb25saW5lIHZpYSBHaXRIdWIgQ29kZXNwYWNlcy4NCi0gKipLZXkgQ29tcG9uZW50cyoqOg0KICAtICpGaWxlIEV4cGxvcmVyKjogU2hvd3MgeW91ciBmaWxlcyBhbmQgZm9sZGVycy4NCiAgLSAqVGFicyo6IEVhY2ggZmlsZSB5b3Ugb3BlbiBpbiBWUyBDb2RlIG9wZW5zIGluIGEgbmV3IHRhYi4NCiAgLSAqVGVybWluYWwqOiBBIGNvbW1hbmQtbGluZSBpbnRlcmZhY2Ugd2l0aGluIFZTIENvZGUgZm9yIGV4ZWN1dGluZyBjb2RlIGFuZCBjb21tYW5kcy4NCi0gKipDcmVhdGluZyBhIFB5dGhvbiBGaWxlKio6DQogIDEuIE9wZW4gVlMgQ29kZS4NCiAgMi4gQ3JlYXRlIGEgbmV3IGZpbGUgYW5kIG5hbWUgaXQgd2l0aCB0aGUgYC5weWAgZXh0ZW5zaW9uIChlLmcuLCBgaGVsbG8ucHlgKS4NCiAgMy4gV3JpdGUgeW91ciBjb2RlLCBzYXZlIHRoZSBmaWxlLCBhbmQgcnVuIGl0IGluIHRoZSB0ZXJtaW5hbC4NCiIiIg0KDQojIEV4YW1wbGUgQ29kZTogQSBCYXNpYyBQeXRob24gUHJvZ3JhbSBpbiBgaGVsbG8ucHlgDQpwcmludCgiSGVsbG8sIHdvcmxkISIpICAjIE91dHB1dDogSGVsbG8sIHdvcmxkIQ0KDQojIFRvIHJ1biB0aGlzLCBvcGVuIHRoZSB0ZXJtaW5hbCBpbiBWUyBDb2RlIGFuZCB0eXBlOg0KIyBweXRob24gaGVsbG8ucHkNCg0KDQojIC0tLSBTRUNUSU9OIDI6IEJBU0lDUyBPRiBQWVRIT046IFZBUklBQkxFUywgSU5QVVQsIEFORCBPVVRQVVQgLS0tDQoNCiIiIg0KSW4gUHl0aG9uLCB3ZSB1c2UgdmFyaWFibGVzIHRvIHN0b3JlIGRhdGEsIGBwcmludCgpYCB0byBvdXRwdXQgaW5mb3JtYXRpb24sIGFuZCBgaW5wdXQoKWAgdG8gY29sbGVjdCBkYXRhIGZyb20gdXNlcnMuDQoNCi0gKipWYXJpYWJsZXMqKjogQ29udGFpbmVycyBmb3Igc3RvcmluZyBkYXRhIHZhbHVlcy4NCiAgLSBWYXJpYWJsZXMgY2FuIHN0b3JlIG51bWJlcnMsIHN0cmluZ3MgKHRleHQpLCBhbmQgb3RoZXIgdHlwZXMgb2YgZGF0YS4NCiAgLSBVc2UgYW4gYD1gIHRvIGFzc2lnbiB2YWx1ZXMgdG8gdmFyaWFibGVzIChlLmcuLCBgYWdlID0gMjVgKS4NCi0gKipJbnB1dCBhbmQgT3V0cHV0Kio6DQogIC0gYGlucHV0KClgIGNvbGxlY3RzIGRhdGEgZnJvbSB0aGUgdXNlci4gVGhpcyBkYXRhIGlzIGFsd2F5cyBzdG9yZWQgYXMgYSBzdHJpbmcuDQogIC0gYHByaW50KClgIGRpc3BsYXlzIGRhdGEgdG8gdGhlIHNjcmVlbi4NCiIiIg0KDQojIEV4YW1wbGUgQ29kZTogQ29sbGVjdGluZyBhbmQgRGlzcGxheWluZyBVc2VyIElucHV0DQoNCm5hbWUgPSBpbnB1dCgiRW50ZXIgeW91ciBuYW1lOiAiKSAgIyBDb2xsZWN0cyB0aGUgdXNlcidzIG5hbWUNCmFnZSA9IDI1ICAjIEFuIGV4YW1wbGUgb2YgYSB2YXJpYWJsZSBob2xkaW5nIGEgbnVtYmVyDQoNCiMgUHJpbnQgY29tYmluZXMgdGV4dCBhbmQgdmFyaWFibGVzIHRvIHByb2R1Y2UgcmVhZGFibGUgb3V0cHV0DQpwcmludChmIkhlbGxvLCB7bmFtZX0hIFlvdSBhcmUge2FnZX0geWVhcnMgb2xkLiIpICAjIE91dHB1dDogSGVsbG8sIFtuYW1lXSEgWW91IGFyZSAyNSB5ZWFycyBvbGQuDQoNCg0KIyAtLS0gU0VDVElPTiAzOiBXT1JLSU5HIFdJVEggRlVOQ1RJT05TIC0tLQ0KDQoiIiINCkZ1bmN0aW9ucyBhcmUgcmV1c2FibGUgYmxvY2tzIG9mIGNvZGUgdGhhdCBoZWxwIHVzIG9yZ2FuaXplIG91ciBwcm9ncmFtcyBhbmQgYXZvaWQgcmVwZXRpdGlvbi4NCg0KLSAqKkRlZmluaW5nIEZ1bmN0aW9ucyoqOg0KICAtIFVzZSB0aGUgYGRlZmAga2V5d29yZCwgZm9sbG93ZWQgYnkgdGhlIGZ1bmN0aW9uJ3MgbmFtZSwgcGFyZW50aGVzZXMsIGFuZCBhIGNvbG9uLg0KICAtIFdyaXRlIHRoZSBjb2RlIHRvIGJlIGV4ZWN1dGVkIGluc2lkZSB0aGUgZnVuY3Rpb24sIGluZGVudGVkIGJlbmVhdGggaXQuDQotICoqQ2FsbGluZyBGdW5jdGlvbnMqKjoNCiAgLSBZb3UgImNhbGwiIGEgZnVuY3Rpb24gYnkgd3JpdGluZyBpdHMgbmFtZSBmb2xsb3dlZCBieSBwYXJlbnRoZXNlcy4NCi0gKipQYXJhbWV0ZXJzIGFuZCBSZXR1cm4gVmFsdWVzKio6DQogIC0gKlBhcmFtZXRlcnMqOiBEYXRhIHlvdSBwYXNzIHRvIHRoZSBmdW5jdGlvbiBpbnNpZGUgdGhlIHBhcmVudGhlc2VzLg0KICAtICpSZXR1cm4gVmFsdWUqOiBUaGUgcmVzdWx0IGEgZnVuY3Rpb24gY2FuIHNlbmQgYmFjayB0byB3aGVyZSBpdCB3YXMgY2FsbGVkLCB1c2luZyB0aGUgYHJldHVybmAga2V5d29yZC4NCiIiIg0KDQojIEV4YW1wbGUgQ29kZTogQSBTaW1wbGUgR3JlZXRpbmcgRnVuY3Rpb24NCg0KZGVmIGdyZWV0X3VzZXIobmFtZSk6DQogICAgIiIiDQogICAgVGhpcyBmdW5jdGlvbiB0YWtlcyBhIHVzZXIncyBuYW1lIGFuZCByZXR1cm5zIGEgZ3JlZXRpbmcuDQogICAgOnBhcmFtIG5hbWU6IHN0ciAtIFRoZSB1c2VyJ3MgbmFtZQ0KICAgIDpyZXR1cm46IHN0ciAtIEEgcGVyc29uYWxpemVkIGdyZWV0aW5nIG1lc3NhZ2UNCiAgICAiIiINCiAgICByZXR1cm4gZiJIZWxsbywge25hbWV9ISINCg0KIyBDYWxsaW5nIHRoZSBmdW5jdGlvbiBhbmQgcHJpbnRpbmcgaXRzIHJldHVybiB2YWx1ZQ0KdXNlcl9uYW1lID0gaW5wdXQoIkVudGVyIHlvdXIgbmFtZTogIikNCnByaW50KGdyZWV0X3VzZXIodXNlcl9uYW1lKSkgICMgT3V0cHV0OiBIZWxsbywgW25hbWVdIQ0KDQoNCiMgLS0tIFNFQ1RJT04gNDogQ09NTUFORC1MSU5FIEJBU0lDUyBJTiBWUyBDT0RFIC0tLQ0KDQoiIiINClRoZSBjb21tYW5kIGxpbmUgaXMgYSB0ZXh0LWJhc2VkIGludGVyZmFjZSBmb3IgaW50ZXJhY3Rpbmcgd2l0aCB0aGUgY29tcHV0ZXIsIGFuZCBpbiBWUyBDb2RlLCBpdCdzIGFjY2Vzc2VkIHRocm91Z2ggdGhlIFRlcm1pbmFsLg0KDQotICoqQmFzaWMgQ29tbWFuZHMqKjoNCiAgLSBgbHNgOiBMaXN0cyBmaWxlcyBhbmQgZm9sZGVycyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuDQogIC0gYGNkIDxkaXJlY3Rvcnk+YDogQ2hhbmdlcyB0aGUgY3VycmVudCBkaXJlY3RvcnkuDQogIC0gYG1rZGlyIDxmb2xkZXJfbmFtZT5gOiBDcmVhdGVzIGEgbmV3IGZvbGRlci4NCiAgLSBgcm0gPGZpbGVfbmFtZT5gOiBSZW1vdmVzIChkZWxldGVzKSBhIGZpbGUuDQogIC0gYGNsZWFyYDogQ2xlYXJzIHRoZSB0ZXJtaW5hbCB3aW5kb3cuDQotICoqTmF2aWdhdGluZyB0aGUgRmlsZSBTeXN0ZW0qKjoNCiAgLSBVc2UgYGNkIC4uYCB0byBnbyB1cCBvbmUgZGlyZWN0b3J5IGxldmVsLg0KICAtIFVzZSB0aGUgVGFiIGtleSBmb3IgYXV0by1jb21wbGV0aW9uLg0KIiIiDQoNCiMgRXhhbXBsZSBUZXJtaW5hbCBDb21tYW5kcyB0byBUcnkgaW4gVlMgQ29kZSAoVGhlc2UgYXJlIG5vdCBQeXRob24gY29kZSBidXQgdHlwZWQgaW4gdGhlIFZTIENvZGUgVGVybWluYWwpDQojIGxzICAgICAgICAgICAjIExpc3RzIGFsbCBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgaW4gdGhlIGN1cnJlbnQgZm9sZGVyDQojIGNkIG5ld19mb2xkZXIgICAjIENoYW5nZXMgdG8gdGhlIGRpcmVjdG9yeSBuYW1lZCAnbmV3X2ZvbGRlcicNCiMgbWtkaXIgbXlfZm9sZGVyICMgQ3JlYXRlcyBhIG5ldyBmb2xkZXIgY2FsbGVkICdteV9mb2xkZXInDQojIHJtIHVud2FudGVkX2ZpbGUucHkgICMgRGVsZXRlcyBhIGZpbGUgY2FsbGVkICd1bndhbnRlZF9maWxlLnB5Jw0KDQoNCiMgLS0tIFNFQ1RJT04gNTogQURWQU5DRUQgQ09OQ0VQVFM6IFNDT1BFIEFORCBTSURFIEVGRkVDVFMgLS0tDQoNCiIiIg0KVW5kZXJzdGFuZGluZyBzY29wZSBhbmQgc2lkZSBlZmZlY3RzIGlzIGltcG9ydGFudCBmb3Igd3JpdGluZyBjbGVhciBhbmQgYnVnLWZyZWUgY29kZS4NCg0KLSAqKlNjb3BlKio6DQogIC0gKkxvY2FsIFNjb3BlKjogVmFyaWFibGVzIGNyZWF0ZWQgaW5zaWRlIGEgZnVuY3Rpb24gYXJlIGxvY2FsIHRvIHRoYXQgZnVuY3Rpb24gYW5kIGNhbid0IGJlIGFjY2Vzc2VkIG91dHNpZGUuDQogIC0gKkdsb2JhbCBTY29wZSo6IFZhcmlhYmxlcyBkZWZpbmVkIG91dHNpZGUgb2YgZnVuY3Rpb25zIGFyZSBnbG9iYWwgYW5kIGNhbiBiZSBhY2Nlc3NlZCBieSBhbnkgY29kZSBpbiB0aGUgZmlsZS4NCi0gKipTaWRlIEVmZmVjdHMqKjoNCiAgLSBTaWRlIGVmZmVjdHMgb2NjdXIgd2hlbiBhIGZ1bmN0aW9uIG1vZGlmaWVzIGEgdmFyaWFibGUgb3V0c2lkZSBpdHMgc2NvcGUsIG9mdGVuIHVzaW5nIGdsb2JhbCB2YXJpYWJsZXMuDQogIC0gRXhhbXBsZTogQ2hhbmdpbmcgYSBnbG9iYWwgdmFyaWFibGUgZnJvbSBpbnNpZGUgYSBmdW5jdGlvbi4NCiIiIg0KDQojIEV4YW1wbGUgQ29kZTogVXNpbmcgR2xvYmFsIFZhcmlhYmxlcyBhbmQgTW9kaWZ5aW5nIFNjb3BlDQoNCiMgQSBnbG9iYWwgdmFyaWFibGUgcmVwcmVzZW50aW5nIHRoZSAibW9vZCIgb2YgYSBjaGF0Ym90DQptb29kID0gIjooIiAgIyBEZWZhdWx0IHRvIHNhZCBmYWNlDQoNCmRlZiB1cGRhdGVfbW9vZChuZXdfbW9vZCk6DQogICAgIiIiDQogICAgVXBkYXRlcyB0aGUgZ2xvYmFsIG1vb2QgdmFyaWFibGUgdG8gYSBuZXcgbW9vZC4NCiAgICA6cGFyYW0gbmV3X21vb2Q6IHN0ciAtIFRoZSBuZXcgbW9vZCBlbW90aWNvbg0KICAgIDpzaWRlIGVmZmVjdDogbW9kaWZpZXMgZ2xvYmFsIGBtb29kYA0KICAgICIiIg0KICAgIGdsb2JhbCBtb29kICAjIERlY2xhcmVzIHRoYXQgd2Ugd2FudCB0byBtb2RpZnkgdGhlIGdsb2JhbCB2YXJpYWJsZQ0KICAgIG1vb2QgPSBuZXdfbW9vZA0KDQpkZWYgc2F5KHBocmFzZSk6DQogICAgIiIiDQogICAgUHJpbnRzIGEgcGhyYXNlIHdpdGggdGhlIGN1cnJlbnQgbW9vZCBvZiB0aGUgY2hhdGJvdC4NCiAgICA6cGFyYW0gcGhyYXNlOiBzdHIgLSBUaGUgcGhyYXNlIHRvIHByaW50DQogICAgIiIiDQogICAgcHJpbnQoZiJ7cGhyYXNlfSB7bW9vZH0iKQ0KDQojIERlbW9uc3RyYXRpbmcgZnVuY3Rpb24gc2lkZSBlZmZlY3RzIGFuZCBzY29wZQ0Kc2F5KCJJcyBhbnlvbmUgdGhlcmU/IikgICAgICAgIyBPdXRwdXQ6IElzIGFueW9uZSB0aGVyZT8gOigNCnVwZGF0ZV9tb29kKCI6RCIpICAgICAgICAgICAgICMgQ2hhbmdlIG1vb2QgdG8gYSBoYXBweSBmYWNlDQpzYXkoIk9oLCBoaSEiKSAgICAgICAgICAgICAgICAjIE91dHB1dDogT2gsIGhpISA6RA0KDQoiIiINCi0tLSBTVU1NQVJZIC0tLQ0KDQpUaGlzIGd1aWRlIGNvdmVyZWQ6DQoxLiBTZXR0aW5nIHVwIFZpc3VhbCBTdHVkaW8gQ29kZSBhbmQgY3JlYXRpbmcgUHl0aG9uIGZpbGVzLg0KMi4gVXNpbmcgdmFyaWFibGVzLCBpbnB1dCwgYW5kIG91dHB1dCBpbiBQeXRob24uDQozLiBDcmVhdGluZyBhbmQgY2FsbGluZyBmdW5jdGlvbnMsIHdpdGggYW4gZW1waGFzaXMgb24gcGFyYW1ldGVycyBhbmQgcmV0dXJuIHZhbHVlcy4NCjQuIE5hdmlnYXRpbmcgdGhlIGNvbW1hbmQgbGluZSBpbiBWUyBDb2RlLg0KNS4gQWR2YW5jZWQgY29uY2VwdHMgb2Ygc2NvcGUgYW5kIHNpZGUgZWZmZWN0cy4NCg0KLS0tIEFkZGl0aW9uYWwgUmVzb3VyY2VzIC0tLQ0KLSBbUHl0aG9uIERvY3VtZW50YXRpb25dKGh0dHBzOi8vZG9jcy5weXRob24ub3JnLzMvKQ0KLSBbVlMgQ29kZSBEb2N1bWVudGF0aW9uXShodHRwczovL2NvZGUudmlzdWFsc3R1ZGlvLmNvbS9kb2NzKQ0KLSBbQ1M1MCBQeXRob24gQ291cnNlXShodHRwczovL2NzNTAuaGFydmFyZC5lZHUvcHl0aG9uLykNCiIiIg0KYGBgDQoNCi0tLQ0KDQoNCiMjIyAqKlB5dGhvbiBpbiBWaXN1YWwgU3R1ZGlvIENvZGUgKFZTIENvZGUpKioNCg0KLSAqKlZTIENvZGUgQmFzaWNzKio6DQogIC0gVlMgQ29kZSBpcyBhIHBvcHVsYXIgSURFIChJbnRlZ3JhdGVkIERldmVsb3BtZW50IEVudmlyb25tZW50KSBmb3IgY29kaW5nLCBlc3BlY2lhbGx5IGluIFB5dGhvbi4NCiAgLSBJdCdzIGF2YWlsYWJsZSBib3RoIGFzIGEgZG93bmxvYWRhYmxlIGFwcGxpY2F0aW9uIGFuZCBhcyBhbiBvbmxpbmUgdG9vbCB2aWEgR2l0SHViIENvZGVzcGFjZXMuDQogIC0gKipLZXkgQ29tcG9uZW50cyoqOg0KICAgIC0gKkZpbGUgRXhwbG9yZXIqOiBWaWV3IGZpbGVzIGFuZCBmb2xkZXJzLg0KICAgIC0gKlRhYnMqOiBFZGl0IG11bHRpcGxlIGZpbGVzIGF0IG9uY2UuDQogICAgLSAqVGVybWluYWwqOiBDb21tYW5kLWxpbmUgaW50ZXJmYWNlIHRvIGV4ZWN1dGUgUHl0aG9uIGNvZGUgYW5kIHN5c3RlbSBjb21tYW5kcy4NCg0KLSAqKlJ1bm5pbmcgUHl0aG9uIENvZGUgaW4gVlMgQ29kZSoqOg0KICAtIENyZWF0ZSBhIG5ldyBmaWxlIHdpdGggYSBgLnB5YCBleHRlbnNpb24gKGUuZy4sIGBoZWxsby5weWApLg0KICAtIFVzZSB0aGUgVGVybWluYWwgdG8gcnVuIHRoZSBjb2RlIGJ5IHR5cGluZzogYHB5dGhvbiBoZWxsby5weWAuDQoNCi0tLQ0KDQojIyMgKipQeXRob24gQmFzaWNzOiBWYXJpYWJsZXMsIElucHV0LCBhbmQgT3V0cHV0KioNCg0KLSAqKlZhcmlhYmxlcyoqOg0KICAtIEEgdmFyaWFibGUgaXMgYSBuYW1lZCBjb250YWluZXIgZm9yIHN0b3JpbmcgZGF0YSB0aGF0IG1heSBjaGFuZ2UuDQogIC0gRXhhbXBsZTogYGFnZSA9IDI1YCBhc3NpZ25zIHRoZSBudW1iZXIgMjUgdG8gdGhlIHZhcmlhYmxlIGBhZ2VgLg0KDQotICoqSW5wdXQgYW5kIE91dHB1dCoqOg0KICAtIGBpbnB1dCgpYCBhbGxvd3MgdXNlciBpbnB1dCBmcm9tIHRoZSBrZXlib2FyZC4NCiAgLSBgcHJpbnQoKWAgZGlzcGxheXMgaW5mb3JtYXRpb24gb24gdGhlIHNjcmVlbi4NCiAgLSBFeGFtcGxlOiANCiAgICBgYGBweXRob24NCiAgICBuYW1lID0gaW5wdXQoIkVudGVyIHlvdXIgbmFtZTogIikNCiAgICBwcmludChmIkhlbGxvLCB7bmFtZX0hIikNCiAgICBgYGANCg0KLS0tDQoNCiMjIyAqKkZ1bmN0aW9ucyBpbiBQeXRob24qKg0KDQotICoqV2hhdCBpcyBhIEZ1bmN0aW9uPyoqOg0KICAtIEZ1bmN0aW9ucyBhcmUgcmV1c2FibGUgYmxvY2tzIG9mIGNvZGUgdGhhdCBwZXJmb3JtIHNwZWNpZmljIHRhc2tzLg0KICAtIERlZmluZWQgd2l0aCB0aGUgYGRlZmAga2V5d29yZCwgZm9sbG93ZWQgYnkgdGhlIGZ1bmN0aW9uIG5hbWUsIHBhcmVudGhlc2VzLCBhbmQgYSBjb2xvbi4NCiAgDQotICoqUGFyYW1ldGVycyBhbmQgUmV0dXJuIFZhbHVlcyoqOg0KICAtICpQYXJhbWV0ZXJzKiBhcmUgZGF0YSB0aGF0IHlvdSBwYXNzIGludG8gZnVuY3Rpb25zLg0KICAtICpSZXR1cm4gVmFsdWVzKiBhcmUgcmVzdWx0cyBhIGZ1bmN0aW9uIGNhbiBzZW5kIGJhY2sgdXNpbmcgYHJldHVybmAuDQogIC0gRXhhbXBsZToNCiAgICBgYGBweXRob24NCiAgICBkZWYgZ3JlZXRfdXNlcihuYW1lKToNCiAgICAgICAgcmV0dXJuIGYiSGVsbG8sIHtuYW1lfSEiDQogICAgYGBgDQoNCi0gKipDYWxsaW5nIGEgRnVuY3Rpb24qKjoNCiAgLSBUbyB1c2UgYSBmdW5jdGlvbiwgd3JpdGUgaXRzIG5hbWUgZm9sbG93ZWQgYnkgcGFyZW50aGVzZXMgd2l0aCBhbnkgbmVlZGVkIGFyZ3VtZW50cyBpbnNpZGUuDQogIC0gRXhhbXBsZTogYHByaW50KGdyZWV0X3VzZXIoIkFsaWNlIikpYCBvdXRwdXRzICJIZWxsbywgQWxpY2UhIg0KDQotLS0NCg0KIyMjICoqVXNpbmcgdGhlIENvbW1hbmQgTGluZSBpbiBWUyBDb2RlKioNCg0KLSAqKkJhc2ljIENvbW1hbmRzKio6DQogIC0gKipgbHNgKio6IExpc3RzIGZpbGVzIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeS4NCiAgLSAqKmBjZCA8ZGlyZWN0b3J5PmAqKjogQ2hhbmdlcyB0aGUgd29ya2luZyBkaXJlY3RvcnkuDQogIC0gKipgbWtkaXIgPGZvbGRlcl9uYW1lPmAqKjogQ3JlYXRlcyBhIG5ldyBmb2xkZXIuDQogIC0gKipgcm0gPGZpbGVfbmFtZT5gKio6IERlbGV0ZXMgYSBzcGVjaWZpZWQgZmlsZS4NCiAgLSAqKmBjbGVhcmAqKjogQ2xlYXJzIHRoZSBUZXJtaW5hbCB3aW5kb3cgZm9yIGEgZnJlc2ggc3RhcnQuDQoNCi0gKipOYXZpZ2F0aW9uIFRpcHMqKjoNCiAgLSBVc2UgYGNkIC4uYCB0byBnbyB1cCBvbmUgZGlyZWN0b3J5IGxldmVsLg0KICAtIFRhYiBrZXkgaGVscHMgd2l0aCBhdXRvY29tcGxldGUgZm9yIGZpbGUgYW5kIGZvbGRlciBuYW1lcy4NCg0KLS0tDQoNCiMjIyAqKkFkdmFuY2VkIENvbmNlcHRzOiBTY29wZSBhbmQgU2lkZSBFZmZlY3RzKioNCg0KLSAqKlNjb3BlKio6DQogIC0gKkxvY2FsIFNjb3BlKjogVmFyaWFibGVzIGRlZmluZWQgaW5zaWRlIGZ1bmN0aW9ucyB0aGF0IGNhbiBvbmx5IGJlIHVzZWQgd2l0aGluIHRoYXQgZnVuY3Rpb24uDQogIC0gKkdsb2JhbCBTY29wZSo6IFZhcmlhYmxlcyBkZWZpbmVkIG91dHNpZGUgZnVuY3Rpb25zLCBhY2Nlc3NpYmxlIHRocm91Z2hvdXQgdGhlIGZpbGUuDQoNCi0gKipTaWRlIEVmZmVjdHMqKjoNCiAgLSBBIHNpZGUgZWZmZWN0IG9jY3VycyB3aGVuIGEgZnVuY3Rpb24gbW9kaWZpZXMgc29tZXRoaW5nIG91dHNpZGUgaXRzIHNjb3BlLCBsaWtlIGNoYW5naW5nIGEgZ2xvYmFsIHZhcmlhYmxlLg0KICAtIFVzZSBgZ2xvYmFsYCB0byBkZWNsYXJlIHRoYXQgYSBmdW5jdGlvbiB3aWxsIG1vZGlmeSBhIGdsb2JhbCB2YXJpYWJsZS4NCiAgLSBFeGFtcGxlOg0KICAgIGBgYHB5dGhvbg0KICAgIG1vb2QgPSAiOigiICAjIEdsb2JhbCB2YXJpYWJsZQ0KICAgIA0KICAgIGRlZiB1cGRhdGVfbW9vZChuZXdfbW9vZCk6DQogICAgICAgIGdsb2JhbCBtb29kDQogICAgICAgIG1vb2QgPSBuZXdfbW9vZCAgIyBNb2RpZmllcyB0aGUgZ2xvYmFsIHZhcmlhYmxlDQoNCiAgICB1cGRhdGVfbW9vZCgiOkQiKSAgIyBOb3cgbW9vZCBpcyAiOkQiDQogICAgYGBgDQoNCi0tLQ0KDQojIyMgKipSZXZpZXcgU3VtbWFyeSoqDQoNCjEuICoqVlMgQ29kZSoqOiBTZXQgdXAgZmlsZXMsIHJ1biBQeXRob24gY29kZSwgYW5kIHVzZSB0aGUgVGVybWluYWwuDQoyLiAqKkJhc2ljIFB5dGhvbioqOiBVc2UgdmFyaWFibGVzLCBgaW5wdXQoKWAsIGFuZCBgcHJpbnQoKWAuDQozLiAqKkZ1bmN0aW9ucyoqOiBEZWZpbmUsIGNhbGwsIHBhc3MgcGFyYW1ldGVycywgYW5kIGhhbmRsZSByZXR1cm4gdmFsdWVzLg0KNC4gKipDb21tYW5kLUxpbmUgU2tpbGxzKio6IE5hdmlnYXRlIGFuZCBtYW5hZ2UgZmlsZXMgaW4gVlMgQ29kZSdzIFRlcm1pbmFsLg0KNS4gKipTY29wZSAmIFNpZGUgRWZmZWN0cyoqOiBVbmRlcnN0YW5kIGxvY2FsIHZzLiBnbG9iYWwgc2NvcGUsIGFuZCB3aGVuIGZ1bmN0aW9ucyBjYW4gbW9kaWZ5IG91dHNpZGUgdmFyaWFibGVzLiANCg0KLS0tDQoNCg==