python_step2.py, will include:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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)

  1. 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.
  2. 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.
  3. 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}!"
  4. 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.
  5. 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.


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)


Python Basics: Variables, Input, and Output


Functions in Python


Using the Command Line in VS Code


Advanced Concepts: Scope and Side Effects


Review Summary

  1. VS Code: Set up files, run Python code, and use the Terminal.
  2. Basic Python: Use variables, input(), and print().
  3. Functions: Define, call, pass parameters, and handle return values.
  4. Command-Line Skills: Navigate and manage files in VS Code’s Terminal.
  5. Scope & Side Effects: Understand local vs. global scope, and when functions can modify outside variables.

LS0tDQp0aXRsZTogIlB5dGhvbiBTdGVwIDIiDQphdXRob3I6ICJKZXNzaWNhIE1jUGhhdWwiDQpkYXRlOiBEZWNlbWJlciAzLCAyMDIyDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCiBgcHl0aG9uX3N0ZXAyLnB5YCwgd2lsbCBpbmNsdWRlOg0KDQoxLiAqKlNldHRpbmcgVXAgVlMgQ29kZSoqICANCiAgIC0gKipFeHBsYW5hdGlvbioqOiBJbnRyb2R1Y3Rpb24gdG8gdXNpbmcgVlMgQ29kZSBhcyBhbiBJbnRlZ3JhdGVkIERldmVsb3BtZW50IEVudmlyb25tZW50IChJREUpIGZvciBQeXRob24uDQogICAtICoqU2V0dXAgU3RlcHMqKjogSG93IHRvIGNyZWF0ZSBhbmQgb3BlbiBmaWxlcywgdXNlIHRoZSB0ZXJtaW5hbCwgYW5kIG5hdmlnYXRlIFZTIENvZGUuDQogICAtICoqQ29kZSBFeGFtcGxlKio6IEJhc2ljIGBoZWxsby5weWAgc2V0dXAuDQoNCjIuICoqQmFzaWMgUHl0aG9uIENvbnN0cnVjdHMqKiAgDQogICAtICoqRXhwbGFuYXRpb24qKjogSW50cm9kdWN0aW9uIHRvIHZhcmlhYmxlcywgZnVuY3Rpb25zLCBpbnB1dHMsIGFuZCBvdXRwdXRzLg0KICAgLSAqKlNldHVwIFN0ZXBzKio6IENyZWF0aW5nIGFuZCBydW5uaW5nIGEgc2ltcGxlIFB5dGhvbiBwcm9ncmFtLg0KICAgLSAqKkNvZGUgRXhhbXBsZSoqOiBTaW1wbGUgYGhlbGxvLnB5YCBwcm9ncmFtIHdpdGggcHJpbnQgc3RhdGVtZW50cyBhbmQgdXNlciBpbnB1dC4NCg0KMy4gKipXb3JraW5nIHdpdGggRnVuY3Rpb25zKiogIA0KICAgLSAqKkV4cGxhbmF0aW9uKio6IEV4cGxhbmF0aW9uIG9mIGZ1bmN0aW9ucywgcmV0dXJuIHZhbHVlcywgYW5kIHNpZGUgZWZmZWN0cy4NCiAgIC0gKipTZXR1cCBTdGVwcyoqOiBDcmVhdGluZyBhbmQgY2FsbGluZyBmdW5jdGlvbnMsIHVuZGVyc3RhbmRpbmcgcmV0dXJuIHZhbHVlcy4NCiAgIC0gKipDb2RlIEV4YW1wbGUqKjogR3JlZXRpbmcgY2hhdGJvdC4NCg0KNC4gKipVc2luZyB0aGUgQ29tbWFuZCBMaW5lKiogIA0KICAgLSAqKkV4cGxhbmF0aW9uKio6IEJhc2ljIGNvbW1hbmQtbGluZSBuYXZpZ2F0aW9uIGFuZCBMaW51eCBjb21tYW5kcyB1c2VkIGluIFZTIENvZGUuDQogICAtICoqU2V0dXAgU3RlcHMqKjogQmFzaWMgY29tbWFuZHMgbGlrZSBgbHNgLCBgY2RgLCBgbWtkaXJgLCBgcm1gLCBhbmQgZmlsZSBuYXZpZ2F0aW9uLg0KICAgLSAqKkNvZGUgRXhhbXBsZSoqOiBDb21tYW5kLWxpbmUgb3BlcmF0aW9ucyBpbiBWUyBDb2RlJ3MgdGVybWluYWwuDQoNCjUuICoqQWR2YW5jZWQgQ29uY2VwdHMqKiAgDQogICAtICoqRXhwbGFuYXRpb24qKjogRnVydGhlciBleHBsb3JhdGlvbiBvZiBmdW5jdGlvbnMsIHNpZGUgZWZmZWN0cywgYW5kIHZhcmlhYmxlIHNjb3BlLg0KICAgLSAqKlNldHVwIFN0ZXBzKio6IFVzaW5nIGdsb2JhbCB2YXJpYWJsZXMgYW5kIG1vZGlmeWluZyB0aGVtLg0KICAgLSAqKkNvZGUgRXhhbXBsZSoqOiBQcm9ncmFtIHNob3dpbmcgdmFyaWFibGUgc2NvcGUgYW5kIHNpZGUgZWZmZWN0cy4NCg0KLS0tDQoNCiMjIyBgcHl0aG9uX3N0ZXAyLnB5YCBNb2R1bGUNCg0KYGBgcHl0aG9uDQojIHB5dGhvbl9zdGVwMi5weQ0KDQojIC0tLSBTZWN0aW9uIDE6IFNldHRpbmcgVXAgVlMgQ29kZSAtLS0NCiIiIg0KVmlzdWFsIFN0dWRpbyBDb2RlIChWUyBDb2RlKSBpcyBhIHBvd2VyZnVsIElERSB1c2VkIGZvciB3cml0aW5nIFB5dGhvbiBjb2RlLg0KVGhpcyBzZWN0aW9uIHdpbGwgaGVscCBzZXQgdXAgYSBzaW1wbGUgcHJvZ3JhbSBhbmQgZXhlY3V0ZSBpdCBpbiBWUyBDb2RlLg0KIiIiDQoNCiMgU3RlcCAxOiBPcGVuIFZTIENvZGUNCiMgU3RlcCAyOiBDcmVhdGUgYSBuZXcgZmlsZSBuYW1lZCBgaGVsbG8ucHlgDQojIFN0ZXAgMzogSW4gYGhlbGxvLnB5YCwgd3JpdGUgYSBzaW1wbGUgcHJpbnQgc3RhdGVtZW50IGFuZCBzYXZlIHRoZSBmaWxlLg0KIyBTdGVwIDQ6IFVzZSB0aGUgdGVybWluYWwgdG8gcnVuIHRoZSBQeXRob24gc2NyaXB0Lg0KIyBDb21tYW5kIHRvIHJ1bjogcHl0aG9uIGhlbGxvLnB5DQoNCnByaW50KCJIZWxsbywgd29ybGQhIikgICMgRXhhbXBsZSBvdXRwdXQNCg0KIyAtLS0gU2VjdGlvbiAyOiBCYXNpYyBQeXRob24gQ29uc3RydWN0cyAtLS0NCiIiIg0KSW4gdGhpcyBzZWN0aW9uLCBsZWFybiBhYm91dCB2YXJpYWJsZXMgYW5kIGJhc2ljIGlucHV0LW91dHB1dC4NCiIiIg0KDQojIFZhcmlhYmxlcyBzdG9yZSBpbmZvcm1hdGlvbiB0aGF0IGNhbiBjaGFuZ2Ugb3ZlciB0aW1lLg0KbmFtZSA9IGlucHV0KCJFbnRlciB5b3VyIG5hbWU6ICIpICAjIEdldHRpbmcgdXNlciBpbnB1dA0KYWdlID0gMjUgICMgQSBzYW1wbGUgaW50ZWdlciB2YXJpYWJsZQ0KDQojIFByaW50IGNvbWJpbmVzIHRleHQgYW5kIHZhcmlhYmxlcyB0byBwcm9kdWNlIHJlYWRhYmxlIG91dHB1dC4NCnByaW50KGYiSGVsbG8sIHtuYW1lfSEgWW91IGFyZSB7YWdlfSB5ZWFycyBvbGQuIikNCg0KIyAtLS0gU2VjdGlvbiAzOiBXb3JraW5nIHdpdGggRnVuY3Rpb25zIC0tLQ0KIiIiDQpGdW5jdGlvbnMgYXJlIHJldXNhYmxlIGJsb2NrcyBvZiBjb2RlIHRoYXQgY2FuIHRha2UgaW5wdXRzIGFuZCByZXR1cm4gb3V0cHV0cy4NClRoaXMgc2VjdGlvbiBpbmNsdWRlcyBkZWZpbmluZyBmdW5jdGlvbnMgYW5kIHVuZGVyc3RhbmRpbmcgcmV0dXJuIHZhbHVlcy4NCiIiIg0KDQpkZWYgZ3JlZXRfdXNlcihuYW1lKToNCiAgICAiIiINCiAgICBGdW5jdGlvbiB0aGF0IGdyZWV0cyB0aGUgdXNlciBieSBuYW1lLg0KICAgIDpwYXJhbSBuYW1lOiBzdHIgLSBUaGUgdXNlcidzIG5hbWUNCiAgICA6cmV0dXJuOiBzdHIgLSBBIHBlcnNvbmFsaXplZCBncmVldGluZyBtZXNzYWdlDQogICAgIiIiDQogICAgcmV0dXJuIGYiSGVsbG8sIHtuYW1lfSEiDQoNCiMgRXhhbXBsZSBvZiBjYWxsaW5nIGEgZnVuY3Rpb24gYW5kIHByaW50aW5nIGl0cyByZXR1cm4gdmFsdWUuDQp1c2VyX25hbWUgPSBpbnB1dCgiRW50ZXIgeW91ciBuYW1lOiAiKQ0KcHJpbnQoZ3JlZXRfdXNlcih1c2VyX25hbWUpKQ0KDQojIC0tLSBTZWN0aW9uIDQ6IFVzaW5nIHRoZSBDb21tYW5kIExpbmUgLS0tDQoiIiINClRoZSBjb21tYW5kIGxpbmUgaXMgYSB0ZXh0LWJhc2VkIGludGVyZmFjZSBmb3IgaW50ZXJhY3Rpbmcgd2l0aCB0aGUgY29tcHV0ZXIuDQpJbiBWUyBDb2RlLCB0aGUgdGVybWluYWwgY2FuIGJlIHVzZWQgdG8gZXhlY3V0ZSB2YXJpb3VzIGNvbW1hbmRzLg0KSGVyZSBhcmUgc29tZSBjb21tb24gTGludXggY29tbWFuZHMgZm9yIGZpbGUgbWFuYWdlbWVudDoNCiAgICAtIGBsc2A6IExpc3QgZmlsZXMgYW5kIGZvbGRlcnMNCiAgICAtIGBjZCA8ZGlyZWN0b3J5PmA6IENoYW5nZSBkaXJlY3RvcnkNCiAgICAtIGBta2RpciA8Zm9sZGVyX25hbWU+YDogQ3JlYXRlIGEgbmV3IGZvbGRlcg0KICAgIC0gYHJtIDxmaWxlX25hbWU+YDogUmVtb3ZlIChkZWxldGUpIGEgZmlsZQ0KICAgIC0gYGNsZWFyYDogQ2xlYXIgdGhlIHRlcm1pbmFsIG91dHB1dA0KIiIiDQoNCiMgQ29tbWFuZC1saW5lIG9wZXJhdGlvbnMgKHVzZSB0aGVzZSBjb21tYW5kcyBpbiB0aGUgVlMgQ29kZSB0ZXJtaW5hbCkNCg0KIyBFeGFtcGxlIHRlcm1pbmFsIGNvbW1hbmRzIHRvIHRyeSBpbiBWUyBDb2RlOg0KIyBscw0KIyBjZCAuLg0KIyBta2RpciBuZXdfZm9sZGVyDQojIHJtIG9sZF9maWxlLnB5DQoNCiMgLS0tIFNlY3Rpb24gNTogQWR2YW5jZWQgQ29uY2VwdHM6IFNpZGUgRWZmZWN0cyBhbmQgU2NvcGUgLS0tDQoiIiINClRoaXMgc2VjdGlvbiBleHBsb3JlcyB2YXJpYWJsZSBzY29wZSBhbmQgc2lkZSBlZmZlY3RzIGluIFB5dGhvbi4NClNpZGUgZWZmZWN0cyBvY2N1ciB3aGVuIGEgZnVuY3Rpb24gbW9kaWZpZXMgc29tZXRoaW5nIG91dHNpZGUgaXRzIGxvY2FsIGVudmlyb25tZW50Lg0KRm9yIGV4YW1wbGUsIHVwZGF0aW5nIGEgZ2xvYmFsIHZhcmlhYmxlIGZyb20gd2l0aGluIGEgZnVuY3Rpb24uDQoiIiINCg0KIyBHbG9iYWwgdmFyaWFibGUgcmVwcmVzZW50aW5nIHRoZSBtb29kIG9mIGEgY2hhdGJvdA0KZW1vdGljb24gPSAiOigiICAjIFNhZCBmYWNlIGJ5IGRlZmF1bHQNCg0KZGVmIHVwZGF0ZV9tb29kKG5ld19tb29kKToNCiAgICAiIiINCiAgICBVcGRhdGVzIHRoZSBnbG9iYWwgYGVtb3RpY29uYCB0byBhIG5ldyBtb29kLg0KICAgIDpwYXJhbSBuZXdfbW9vZDogc3RyIC0gTmV3IGVtb3RpY29uDQogICAgOnNpZGUgZWZmZWN0OiBtb2RpZmllcyBnbG9iYWwgYGVtb3RpY29uYA0KICAgICIiIg0KICAgIGdsb2JhbCBlbW90aWNvbiAgIyBEZWNsYXJlIHRoYXQgd2UncmUgbW9kaWZ5aW5nIHRoZSBnbG9iYWwgdmFyaWFibGUNCiAgICBlbW90aWNvbiA9IG5ld19tb29kDQoNCmRlZiBzYXkocGhyYXNlKToNCiAgICAiIiINCiAgICBQcmludHMgYSBwaHJhc2UgYWxvbmcgd2l0aCB0aGUgY3VycmVudCBtb29kLg0KICAgIDpwYXJhbSBwaHJhc2U6IHN0ciAtIFRoZSBwaHJhc2UgdG8gcHJpbnQNCiAgICAiIiINCiAgICBwcmludChmIntwaHJhc2V9IHtlbW90aWNvbn0iKQ0KDQojIFVzYWdlDQpzYXkoIklzIGFueW9uZSB0aGVyZT8iKQ0KdXBkYXRlX21vb2QoIjpEIikgICMgQ2hhbmdpbmcgdGhlIG1vb2QgdG8gYSBoYXBweSBmYWNlDQpzYXkoIk9oLCBoaSEiKSAgIyBOb3cgdGhlIGNoYXRib3QgcmVzcG9uZHMgd2l0aCBhIGhhcHB5IGZhY2UNCg0KIyAtLS0gQWRkaXRpb25hbCBSZWZlcmVuY2VzIC0tLQ0KIiIiDQpGb3IgZnVydGhlciBleHBsb3JhdGlvbjoNCi0gUHl0aG9uIGRvY3VtZW50YXRpb246IGh0dHBzOi8vZG9jcy5weXRob24ub3JnLzMvDQotIENTNTAgUHl0aG9uIENvdXJzZTogaHR0cHM6Ly9jczUwLmhhcnZhcmQuZWR1L3B5dGhvbi8NCi0gVlMgQ29kZSBEb2N1bWVudGF0aW9uOiBodHRwczovL2NvZGUudmlzdWFsc3R1ZGlvLmNvbS9kb2NzDQoiIiINCmBgYA0KDQotLS0NCg0KIyMjIEV4cGxhbmF0aW9ucyAmIENvbmNlcHRzIChmb3IgU3R1ZHkpDQoNCjEuICoqVlMgQ29kZSBCYXNpY3MqKiAgDQogICAtIFZTIENvZGUgaXMgYSBwb3dlcmZ1bCBJREUgZm9yIGNvZGluZyBpbiBQeXRob24uDQogICAtIFlvdSBjYW4gaW5zdGFsbCBpdCBsb2NhbGx5IG9yIHVzZSBpdCBvbmxpbmUgdmlhIEdpdEh1YiBDb2Rlc3BhY2VzLg0KICAgLSBFc3NlbnRpYWwgc2VjdGlvbnM6IEZpbGUgRXhwbG9yZXIsIFRhYnMgZm9yIGZpbGVzLCBUZXJtaW5hbC4NCg0KMi4gKipCYXNpYyBDb25zdHJ1Y3RzOiBWYXJpYWJsZXMgYW5kIElucHV0L091dHB1dCoqICANCiAgIC0gKipWYXJpYWJsZXMqKjogQ29udGFpbmVycyBmb3IgZGF0YSAoZS5nLiwgYGFnZSA9IDI1YCkuDQogICAtICoqSW5wdXQqKjogYGlucHV0KClgIGNvbGxlY3RzIGRhdGEgZnJvbSB0aGUgdXNlci4NCiAgIC0gKipPdXRwdXQqKjogYHByaW50KClgIGRpc3BsYXlzIGRhdGEgdG8gdGhlIHNjcmVlbi4NCg0KMy4gKipGdW5jdGlvbnMqKiAgDQogICAtIEZ1bmN0aW9ucyBhcmUgZGVmaW5lZCB1c2luZyBgZGVmYCwgYW5kIHRoZXkgY2FuIHRha2UgcGFyYW1ldGVycy4NCiAgIC0gKipSZXR1cm4gVmFsdWUqKjogRnVuY3Rpb25zIGNhbiByZXR1cm4gZGF0YSB1c2luZyBgcmV0dXJuYC4NCiAgIC0gKipFeGFtcGxlKio6IGBkZWYgZ3JlZXRfdXNlcihuYW1lKTogcmV0dXJuIGYiSGVsbG8sIHtuYW1lfSEiYA0KDQo0LiAqKkNvbW1hbmQgTGluZSBDb21tYW5kcyoqICANCiAgIC0gKipMaXN0IChgbHNgKSoqOiBTaG93cyBmaWxlcyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuDQogICAtICoqQ2hhbmdlIERpcmVjdG9yeSAoYGNkYCkqKjogTmF2aWdhdGUgYmV0d2VlbiBkaXJlY3Rvcmllcy4NCiAgIC0gKipNYWtlIERpcmVjdG9yeSAoYG1rZGlyYCkqKjogQ3JlYXRlcyBhIG5ldyBmb2xkZXIuDQogICAtICoqUmVtb3ZlIChgcm1gKSoqOiBEZWxldGVzIGZpbGVzIG9yIGZvbGRlcnMuDQoNCjUuICoqQWR2YW5jZWQgQ29uY2VwdHM6IFNpZGUgRWZmZWN0cyBhbmQgU2NvcGUqKiAgDQogICAtICoqU2lkZSBFZmZlY3QqKjogV2hlbiBhIGZ1bmN0aW9uIGNoYW5nZXMgc29tZXRoaW5nIG91dHNpZGUgaXRzIHNjb3BlLg0KICAgLSAqKlNjb3BlKio6IFdoZXJlIHZhcmlhYmxlcyBhcmUgYWNjZXNzaWJsZSAobG9jYWwgdnMuIGdsb2JhbCkuDQogICAtICoqR2xvYmFsIEtleXdvcmQqKjogRGVjbGFyZXMgZ2xvYmFsIHZhcmlhYmxlcyB0byBtb2RpZnkgaW4gZnVuY3Rpb25zLg0KDQotLS0NCg0KDQotIFJldmlzZWQ/IENoZWNrIGZvcm1hdCBub3Qgc3VyZSBJIGxpa2UgaXQuICBCdXQgYWxzbyBmZWVsaW5nIGxhenkgYW5kIG5lZWRpbmcgYSBicmVhay4gIDQgZGF5cyBhZ28gSSBoYXZlIG5ldmVyIHVzZWQgcHl0aG9uLiAgTm93LCBJJ20gY3JhbW1pbmcgbXkgYnJhaW4gYW5kIGl0J3MgYXNraW5nIGZvciBhIGJyZWFrIGZyb20gcHl0aG9uIGFuZCBhbiBpbnRyb2R1Y3Rpb24gb2Ygc29tZSB3aW5lLiAgU08gaW1tYSBkbyB0aGF0IG5vdy4gDQoNCg0KDQoNCi0tLQ0KDQojIyMgYHB5dGhvbl9zdGVwMi5weWAgTW9kdWxlDQoNCmBgYHB5dGhvbg0KIiIiDQpQWVRIT04gU1RFUCAyOiBBIENPTVBSRUhFTlNJVkUgR1VJREUNCg0KV2VsY29tZSB0byBQeXRob24gU3RlcCAyISBUaGlzIGd1aWRlIGlzIGRlc2lnbmVkIHRvIHRha2UgeW91IHRocm91Z2ggUHl0aG9uIHByb2dyYW1taW5nIGVzc2VudGlhbHMuDQpFYWNoIHNlY3Rpb24gaW5jbHVkZXMgYSBkZXNjcmlwdGlvbiwgZXhhbXBsZXMsIGFuZCBjb2RlIHNuaXBwZXRzIHRvIGhlbHAgeW91IGxlYXJuIGFuZCBwcmFjdGljZS4NCg0KLS0tIFRhYmxlIG9mIENvbnRlbnRzIC0tLQ0KMS4gU2V0dGluZyBVcCBWaXN1YWwgU3R1ZGlvIENvZGUNCjIuIEJhc2ljcyBvZiBQeXRob246IFZhcmlhYmxlcywgSW5wdXQsIGFuZCBPdXRwdXQNCjMuIFdvcmtpbmcgd2l0aCBGdW5jdGlvbnMNCjQuIENvbW1hbmQtTGluZSBCYXNpY3MgaW4gVlMgQ29kZQ0KNS4gQWR2YW5jZWQgQ29uY2VwdHM6IFNjb3BlIGFuZCBTaWRlIEVmZmVjdHMNCg0KIiIiDQoNCiMgLS0tIFNFQ1RJT04gMTogU0VUVElORyBVUCBWSVNVQUwgU1RVRElPIENPREUgLS0tDQoNCiIiIg0KVmlzdWFsIFN0dWRpbyBDb2RlIChWUyBDb2RlKSBpcyBhIHBvd2VyZnVsIGFuZCBwb3B1bGFyIEludGVncmF0ZWQgRGV2ZWxvcG1lbnQgRW52aXJvbm1lbnQgKElERSkgZm9yIGNvZGluZy4NCkl0J3Mgd2lkZWx5IHVzZWQgYmVjYXVzZSBpdCdzIGZyZWUsIG9wZW4tc291cmNlLCBhbmQgaGFzIG1hbnkgdXNlZnVsIGZlYXR1cmVzLg0KDQotICoqSURFIHZzLiBUZXh0IEVkaXRvcioqOiBWUyBDb2RlIGlzIHRlY2huaWNhbGx5IGEgdGV4dCBlZGl0b3IsIGJ1dCBpdCBmdW5jdGlvbnMgbGlrZSBhbiBJREUuDQotICoqSG93IHRvIEluc3RhbGwqKjogWW91IGNhbiBkb3dubG9hZCBpdCBmb3IgZnJlZSBmcm9tIGh0dHBzOi8vY29kZS52aXN1YWxzdHVkaW8uY29tLyBvciB1c2UgaXQgb25saW5lIHZpYSBHaXRIdWIgQ29kZXNwYWNlcy4NCi0gKipLZXkgQ29tcG9uZW50cyoqOg0KICAtICpGaWxlIEV4cGxvcmVyKjogU2hvd3MgeW91ciBmaWxlcyBhbmQgZm9sZGVycy4NCiAgLSAqVGFicyo6IEVhY2ggZmlsZSB5b3Ugb3BlbiBpbiBWUyBDb2RlIG9wZW5zIGluIGEgbmV3IHRhYi4NCiAgLSAqVGVybWluYWwqOiBBIGNvbW1hbmQtbGluZSBpbnRlcmZhY2Ugd2l0aGluIFZTIENvZGUgZm9yIGV4ZWN1dGluZyBjb2RlIGFuZCBjb21tYW5kcy4NCi0gKipDcmVhdGluZyBhIFB5dGhvbiBGaWxlKio6DQogIDEuIE9wZW4gVlMgQ29kZS4NCiAgMi4gQ3JlYXRlIGEgbmV3IGZpbGUgYW5kIG5hbWUgaXQgd2l0aCB0aGUgYC5weWAgZXh0ZW5zaW9uIChlLmcuLCBgaGVsbG8ucHlgKS4NCiAgMy4gV3JpdGUgeW91ciBjb2RlLCBzYXZlIHRoZSBmaWxlLCBhbmQgcnVuIGl0IGluIHRoZSB0ZXJtaW5hbC4NCiIiIg0KDQojIEV4YW1wbGUgQ29kZTogQSBCYXNpYyBQeXRob24gUHJvZ3JhbSBpbiBgaGVsbG8ucHlgDQpwcmludCgiSGVsbG8sIHdvcmxkISIpICAjIE91dHB1dDogSGVsbG8sIHdvcmxkIQ0KDQojIFRvIHJ1biB0aGlzLCBvcGVuIHRoZSB0ZXJtaW5hbCBpbiBWUyBDb2RlIGFuZCB0eXBlOg0KIyBweXRob24gaGVsbG8ucHkNCg0KDQojIC0tLSBTRUNUSU9OIDI6IEJBU0lDUyBPRiBQWVRIT046IFZBUklBQkxFUywgSU5QVVQsIEFORCBPVVRQVVQgLS0tDQoNCiIiIg0KSW4gUHl0aG9uLCB3ZSB1c2UgdmFyaWFibGVzIHRvIHN0b3JlIGRhdGEsIGBwcmludCgpYCB0byBvdXRwdXQgaW5mb3JtYXRpb24sIGFuZCBgaW5wdXQoKWAgdG8gY29sbGVjdCBkYXRhIGZyb20gdXNlcnMuDQoNCi0gKipWYXJpYWJsZXMqKjogQ29udGFpbmVycyBmb3Igc3RvcmluZyBkYXRhIHZhbHVlcy4NCiAgLSBWYXJpYWJsZXMgY2FuIHN0b3JlIG51bWJlcnMsIHN0cmluZ3MgKHRleHQpLCBhbmQgb3RoZXIgdHlwZXMgb2YgZGF0YS4NCiAgLSBVc2UgYW4gYD1gIHRvIGFzc2lnbiB2YWx1ZXMgdG8gdmFyaWFibGVzIChlLmcuLCBgYWdlID0gMjVgKS4NCi0gKipJbnB1dCBhbmQgT3V0cHV0Kio6DQogIC0gYGlucHV0KClgIGNvbGxlY3RzIGRhdGEgZnJvbSB0aGUgdXNlci4gVGhpcyBkYXRhIGlzIGFsd2F5cyBzdG9yZWQgYXMgYSBzdHJpbmcuDQogIC0gYHByaW50KClgIGRpc3BsYXlzIGRhdGEgdG8gdGhlIHNjcmVlbi4NCiIiIg0KDQojIEV4YW1wbGUgQ29kZTogQ29sbGVjdGluZyBhbmQgRGlzcGxheWluZyBVc2VyIElucHV0DQoNCm5hbWUgPSBpbnB1dCgiRW50ZXIgeW91ciBuYW1lOiAiKSAgIyBDb2xsZWN0cyB0aGUgdXNlcidzIG5hbWUNCmFnZSA9IDI1ICAjIEFuIGV4YW1wbGUgb2YgYSB2YXJpYWJsZSBob2xkaW5nIGEgbnVtYmVyDQoNCiMgUHJpbnQgY29tYmluZXMgdGV4dCBhbmQgdmFyaWFibGVzIHRvIHByb2R1Y2UgcmVhZGFibGUgb3V0cHV0DQpwcmludChmIkhlbGxvLCB7bmFtZX0hIFlvdSBhcmUge2FnZX0geWVhcnMgb2xkLiIpICAjIE91dHB1dDogSGVsbG8sIFtuYW1lXSEgWW91IGFyZSAyNSB5ZWFycyBvbGQuDQoNCg0KIyAtLS0gU0VDVElPTiAzOiBXT1JLSU5HIFdJVEggRlVOQ1RJT05TIC0tLQ0KDQoiIiINCkZ1bmN0aW9ucyBhcmUgcmV1c2FibGUgYmxvY2tzIG9mIGNvZGUgdGhhdCBoZWxwIHVzIG9yZ2FuaXplIG91ciBwcm9ncmFtcyBhbmQgYXZvaWQgcmVwZXRpdGlvbi4NCg0KLSAqKkRlZmluaW5nIEZ1bmN0aW9ucyoqOg0KICAtIFVzZSB0aGUgYGRlZmAga2V5d29yZCwgZm9sbG93ZWQgYnkgdGhlIGZ1bmN0aW9uJ3MgbmFtZSwgcGFyZW50aGVzZXMsIGFuZCBhIGNvbG9uLg0KICAtIFdyaXRlIHRoZSBjb2RlIHRvIGJlIGV4ZWN1dGVkIGluc2lkZSB0aGUgZnVuY3Rpb24sIGluZGVudGVkIGJlbmVhdGggaXQuDQotICoqQ2FsbGluZyBGdW5jdGlvbnMqKjoNCiAgLSBZb3UgImNhbGwiIGEgZnVuY3Rpb24gYnkgd3JpdGluZyBpdHMgbmFtZSBmb2xsb3dlZCBieSBwYXJlbnRoZXNlcy4NCi0gKipQYXJhbWV0ZXJzIGFuZCBSZXR1cm4gVmFsdWVzKio6DQogIC0gKlBhcmFtZXRlcnMqOiBEYXRhIHlvdSBwYXNzIHRvIHRoZSBmdW5jdGlvbiBpbnNpZGUgdGhlIHBhcmVudGhlc2VzLg0KICAtICpSZXR1cm4gVmFsdWUqOiBUaGUgcmVzdWx0IGEgZnVuY3Rpb24gY2FuIHNlbmQgYmFjayB0byB3aGVyZSBpdCB3YXMgY2FsbGVkLCB1c2luZyB0aGUgYHJldHVybmAga2V5d29yZC4NCiIiIg0KDQojIEV4YW1wbGUgQ29kZTogQSBTaW1wbGUgR3JlZXRpbmcgRnVuY3Rpb24NCg0KZGVmIGdyZWV0X3VzZXIobmFtZSk6DQogICAgIiIiDQogICAgVGhpcyBmdW5jdGlvbiB0YWtlcyBhIHVzZXIncyBuYW1lIGFuZCByZXR1cm5zIGEgZ3JlZXRpbmcuDQogICAgOnBhcmFtIG5hbWU6IHN0ciAtIFRoZSB1c2VyJ3MgbmFtZQ0KICAgIDpyZXR1cm46IHN0ciAtIEEgcGVyc29uYWxpemVkIGdyZWV0aW5nIG1lc3NhZ2UNCiAgICAiIiINCiAgICByZXR1cm4gZiJIZWxsbywge25hbWV9ISINCg0KIyBDYWxsaW5nIHRoZSBmdW5jdGlvbiBhbmQgcHJpbnRpbmcgaXRzIHJldHVybiB2YWx1ZQ0KdXNlcl9uYW1lID0gaW5wdXQoIkVudGVyIHlvdXIgbmFtZTogIikNCnByaW50KGdyZWV0X3VzZXIodXNlcl9uYW1lKSkgICMgT3V0cHV0OiBIZWxsbywgW25hbWVdIQ0KDQoNCiMgLS0tIFNFQ1RJT04gNDogQ09NTUFORC1MSU5FIEJBU0lDUyBJTiBWUyBDT0RFIC0tLQ0KDQoiIiINClRoZSBjb21tYW5kIGxpbmUgaXMgYSB0ZXh0LWJhc2VkIGludGVyZmFjZSBmb3IgaW50ZXJhY3Rpbmcgd2l0aCB0aGUgY29tcHV0ZXIsIGFuZCBpbiBWUyBDb2RlLCBpdCdzIGFjY2Vzc2VkIHRocm91Z2ggdGhlIFRlcm1pbmFsLg0KDQotICoqQmFzaWMgQ29tbWFuZHMqKjoNCiAgLSBgbHNgOiBMaXN0cyBmaWxlcyBhbmQgZm9sZGVycyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuDQogIC0gYGNkIDxkaXJlY3Rvcnk+YDogQ2hhbmdlcyB0aGUgY3VycmVudCBkaXJlY3RvcnkuDQogIC0gYG1rZGlyIDxmb2xkZXJfbmFtZT5gOiBDcmVhdGVzIGEgbmV3IGZvbGRlci4NCiAgLSBgcm0gPGZpbGVfbmFtZT5gOiBSZW1vdmVzIChkZWxldGVzKSBhIGZpbGUuDQogIC0gYGNsZWFyYDogQ2xlYXJzIHRoZSB0ZXJtaW5hbCB3aW5kb3cuDQotICoqTmF2aWdhdGluZyB0aGUgRmlsZSBTeXN0ZW0qKjoNCiAgLSBVc2UgYGNkIC4uYCB0byBnbyB1cCBvbmUgZGlyZWN0b3J5IGxldmVsLg0KICAtIFVzZSB0aGUgVGFiIGtleSBmb3IgYXV0by1jb21wbGV0aW9uLg0KIiIiDQoNCiMgRXhhbXBsZSBUZXJtaW5hbCBDb21tYW5kcyB0byBUcnkgaW4gVlMgQ29kZSAoVGhlc2UgYXJlIG5vdCBQeXRob24gY29kZSBidXQgdHlwZWQgaW4gdGhlIFZTIENvZGUgVGVybWluYWwpDQojIGxzICAgICAgICAgICAjIExpc3RzIGFsbCBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgaW4gdGhlIGN1cnJlbnQgZm9sZGVyDQojIGNkIG5ld19mb2xkZXIgICAjIENoYW5nZXMgdG8gdGhlIGRpcmVjdG9yeSBuYW1lZCAnbmV3X2ZvbGRlcicNCiMgbWtkaXIgbXlfZm9sZGVyICMgQ3JlYXRlcyBhIG5ldyBmb2xkZXIgY2FsbGVkICdteV9mb2xkZXInDQojIHJtIHVud2FudGVkX2ZpbGUucHkgICMgRGVsZXRlcyBhIGZpbGUgY2FsbGVkICd1bndhbnRlZF9maWxlLnB5Jw0KDQoNCiMgLS0tIFNFQ1RJT04gNTogQURWQU5DRUQgQ09OQ0VQVFM6IFNDT1BFIEFORCBTSURFIEVGRkVDVFMgLS0tDQoNCiIiIg0KVW5kZXJzdGFuZGluZyBzY29wZSBhbmQgc2lkZSBlZmZlY3RzIGlzIGltcG9ydGFudCBmb3Igd3JpdGluZyBjbGVhciBhbmQgYnVnLWZyZWUgY29kZS4NCg0KLSAqKlNjb3BlKio6DQogIC0gKkxvY2FsIFNjb3BlKjogVmFyaWFibGVzIGNyZWF0ZWQgaW5zaWRlIGEgZnVuY3Rpb24gYXJlIGxvY2FsIHRvIHRoYXQgZnVuY3Rpb24gYW5kIGNhbid0IGJlIGFjY2Vzc2VkIG91dHNpZGUuDQogIC0gKkdsb2JhbCBTY29wZSo6IFZhcmlhYmxlcyBkZWZpbmVkIG91dHNpZGUgb2YgZnVuY3Rpb25zIGFyZSBnbG9iYWwgYW5kIGNhbiBiZSBhY2Nlc3NlZCBieSBhbnkgY29kZSBpbiB0aGUgZmlsZS4NCi0gKipTaWRlIEVmZmVjdHMqKjoNCiAgLSBTaWRlIGVmZmVjdHMgb2NjdXIgd2hlbiBhIGZ1bmN0aW9uIG1vZGlmaWVzIGEgdmFyaWFibGUgb3V0c2lkZSBpdHMgc2NvcGUsIG9mdGVuIHVzaW5nIGdsb2JhbCB2YXJpYWJsZXMuDQogIC0gRXhhbXBsZTogQ2hhbmdpbmcgYSBnbG9iYWwgdmFyaWFibGUgZnJvbSBpbnNpZGUgYSBmdW5jdGlvbi4NCiIiIg0KDQojIEV4YW1wbGUgQ29kZTogVXNpbmcgR2xvYmFsIFZhcmlhYmxlcyBhbmQgTW9kaWZ5aW5nIFNjb3BlDQoNCiMgQSBnbG9iYWwgdmFyaWFibGUgcmVwcmVzZW50aW5nIHRoZSAibW9vZCIgb2YgYSBjaGF0Ym90DQptb29kID0gIjooIiAgIyBEZWZhdWx0IHRvIHNhZCBmYWNlDQoNCmRlZiB1cGRhdGVfbW9vZChuZXdfbW9vZCk6DQogICAgIiIiDQogICAgVXBkYXRlcyB0aGUgZ2xvYmFsIG1vb2QgdmFyaWFibGUgdG8gYSBuZXcgbW9vZC4NCiAgICA6cGFyYW0gbmV3X21vb2Q6IHN0ciAtIFRoZSBuZXcgbW9vZCBlbW90aWNvbg0KICAgIDpzaWRlIGVmZmVjdDogbW9kaWZpZXMgZ2xvYmFsIGBtb29kYA0KICAgICIiIg0KICAgIGdsb2JhbCBtb29kICAjIERlY2xhcmVzIHRoYXQgd2Ugd2FudCB0byBtb2RpZnkgdGhlIGdsb2JhbCB2YXJpYWJsZQ0KICAgIG1vb2QgPSBuZXdfbW9vZA0KDQpkZWYgc2F5KHBocmFzZSk6DQogICAgIiIiDQogICAgUHJpbnRzIGEgcGhyYXNlIHdpdGggdGhlIGN1cnJlbnQgbW9vZCBvZiB0aGUgY2hhdGJvdC4NCiAgICA6cGFyYW0gcGhyYXNlOiBzdHIgLSBUaGUgcGhyYXNlIHRvIHByaW50DQogICAgIiIiDQogICAgcHJpbnQoZiJ7cGhyYXNlfSB7bW9vZH0iKQ0KDQojIERlbW9uc3RyYXRpbmcgZnVuY3Rpb24gc2lkZSBlZmZlY3RzIGFuZCBzY29wZQ0Kc2F5KCJJcyBhbnlvbmUgdGhlcmU/IikgICAgICAgIyBPdXRwdXQ6IElzIGFueW9uZSB0aGVyZT8gOigNCnVwZGF0ZV9tb29kKCI6RCIpICAgICAgICAgICAgICMgQ2hhbmdlIG1vb2QgdG8gYSBoYXBweSBmYWNlDQpzYXkoIk9oLCBoaSEiKSAgICAgICAgICAgICAgICAjIE91dHB1dDogT2gsIGhpISA6RA0KDQoiIiINCi0tLSBTVU1NQVJZIC0tLQ0KDQpUaGlzIGd1aWRlIGNvdmVyZWQ6DQoxLiBTZXR0aW5nIHVwIFZpc3VhbCBTdHVkaW8gQ29kZSBhbmQgY3JlYXRpbmcgUHl0aG9uIGZpbGVzLg0KMi4gVXNpbmcgdmFyaWFibGVzLCBpbnB1dCwgYW5kIG91dHB1dCBpbiBQeXRob24uDQozLiBDcmVhdGluZyBhbmQgY2FsbGluZyBmdW5jdGlvbnMsIHdpdGggYW4gZW1waGFzaXMgb24gcGFyYW1ldGVycyBhbmQgcmV0dXJuIHZhbHVlcy4NCjQuIE5hdmlnYXRpbmcgdGhlIGNvbW1hbmQgbGluZSBpbiBWUyBDb2RlLg0KNS4gQWR2YW5jZWQgY29uY2VwdHMgb2Ygc2NvcGUgYW5kIHNpZGUgZWZmZWN0cy4NCg0KLS0tIEFkZGl0aW9uYWwgUmVzb3VyY2VzIC0tLQ0KLSBbUHl0aG9uIERvY3VtZW50YXRpb25dKGh0dHBzOi8vZG9jcy5weXRob24ub3JnLzMvKQ0KLSBbVlMgQ29kZSBEb2N1bWVudGF0aW9uXShodHRwczovL2NvZGUudmlzdWFsc3R1ZGlvLmNvbS9kb2NzKQ0KLSBbQ1M1MCBQeXRob24gQ291cnNlXShodHRwczovL2NzNTAuaGFydmFyZC5lZHUvcHl0aG9uLykNCiIiIg0KYGBgDQoNCi0tLQ0KDQoNCiMjIyAqKlB5dGhvbiBpbiBWaXN1YWwgU3R1ZGlvIENvZGUgKFZTIENvZGUpKioNCg0KLSAqKlZTIENvZGUgQmFzaWNzKio6DQogIC0gVlMgQ29kZSBpcyBhIHBvcHVsYXIgSURFIChJbnRlZ3JhdGVkIERldmVsb3BtZW50IEVudmlyb25tZW50KSBmb3IgY29kaW5nLCBlc3BlY2lhbGx5IGluIFB5dGhvbi4NCiAgLSBJdCdzIGF2YWlsYWJsZSBib3RoIGFzIGEgZG93bmxvYWRhYmxlIGFwcGxpY2F0aW9uIGFuZCBhcyBhbiBvbmxpbmUgdG9vbCB2aWEgR2l0SHViIENvZGVzcGFjZXMuDQogIC0gKipLZXkgQ29tcG9uZW50cyoqOg0KICAgIC0gKkZpbGUgRXhwbG9yZXIqOiBWaWV3IGZpbGVzIGFuZCBmb2xkZXJzLg0KICAgIC0gKlRhYnMqOiBFZGl0IG11bHRpcGxlIGZpbGVzIGF0IG9uY2UuDQogICAgLSAqVGVybWluYWwqOiBDb21tYW5kLWxpbmUgaW50ZXJmYWNlIHRvIGV4ZWN1dGUgUHl0aG9uIGNvZGUgYW5kIHN5c3RlbSBjb21tYW5kcy4NCg0KLSAqKlJ1bm5pbmcgUHl0aG9uIENvZGUgaW4gVlMgQ29kZSoqOg0KICAtIENyZWF0ZSBhIG5ldyBmaWxlIHdpdGggYSBgLnB5YCBleHRlbnNpb24gKGUuZy4sIGBoZWxsby5weWApLg0KICAtIFVzZSB0aGUgVGVybWluYWwgdG8gcnVuIHRoZSBjb2RlIGJ5IHR5cGluZzogYHB5dGhvbiBoZWxsby5weWAuDQoNCi0tLQ0KDQojIyMgKipQeXRob24gQmFzaWNzOiBWYXJpYWJsZXMsIElucHV0LCBhbmQgT3V0cHV0KioNCg0KLSAqKlZhcmlhYmxlcyoqOg0KICAtIEEgdmFyaWFibGUgaXMgYSBuYW1lZCBjb250YWluZXIgZm9yIHN0b3JpbmcgZGF0YSB0aGF0IG1heSBjaGFuZ2UuDQogIC0gRXhhbXBsZTogYGFnZSA9IDI1YCBhc3NpZ25zIHRoZSBudW1iZXIgMjUgdG8gdGhlIHZhcmlhYmxlIGBhZ2VgLg0KDQotICoqSW5wdXQgYW5kIE91dHB1dCoqOg0KICAtIGBpbnB1dCgpYCBhbGxvd3MgdXNlciBpbnB1dCBmcm9tIHRoZSBrZXlib2FyZC4NCiAgLSBgcHJpbnQoKWAgZGlzcGxheXMgaW5mb3JtYXRpb24gb24gdGhlIHNjcmVlbi4NCiAgLSBFeGFtcGxlOiANCiAgICBgYGBweXRob24NCiAgICBuYW1lID0gaW5wdXQoIkVudGVyIHlvdXIgbmFtZTogIikNCiAgICBwcmludChmIkhlbGxvLCB7bmFtZX0hIikNCiAgICBgYGANCg0KLS0tDQoNCiMjIyAqKkZ1bmN0aW9ucyBpbiBQeXRob24qKg0KDQotICoqV2hhdCBpcyBhIEZ1bmN0aW9uPyoqOg0KICAtIEZ1bmN0aW9ucyBhcmUgcmV1c2FibGUgYmxvY2tzIG9mIGNvZGUgdGhhdCBwZXJmb3JtIHNwZWNpZmljIHRhc2tzLg0KICAtIERlZmluZWQgd2l0aCB0aGUgYGRlZmAga2V5d29yZCwgZm9sbG93ZWQgYnkgdGhlIGZ1bmN0aW9uIG5hbWUsIHBhcmVudGhlc2VzLCBhbmQgYSBjb2xvbi4NCiAgDQotICoqUGFyYW1ldGVycyBhbmQgUmV0dXJuIFZhbHVlcyoqOg0KICAtICpQYXJhbWV0ZXJzKiBhcmUgZGF0YSB0aGF0IHlvdSBwYXNzIGludG8gZnVuY3Rpb25zLg0KICAtICpSZXR1cm4gVmFsdWVzKiBhcmUgcmVzdWx0cyBhIGZ1bmN0aW9uIGNhbiBzZW5kIGJhY2sgdXNpbmcgYHJldHVybmAuDQogIC0gRXhhbXBsZToNCiAgICBgYGBweXRob24NCiAgICBkZWYgZ3JlZXRfdXNlcihuYW1lKToNCiAgICAgICAgcmV0dXJuIGYiSGVsbG8sIHtuYW1lfSEiDQogICAgYGBgDQoNCi0gKipDYWxsaW5nIGEgRnVuY3Rpb24qKjoNCiAgLSBUbyB1c2UgYSBmdW5jdGlvbiwgd3JpdGUgaXRzIG5hbWUgZm9sbG93ZWQgYnkgcGFyZW50aGVzZXMgd2l0aCBhbnkgbmVlZGVkIGFyZ3VtZW50cyBpbnNpZGUuDQogIC0gRXhhbXBsZTogYHByaW50KGdyZWV0X3VzZXIoIkFsaWNlIikpYCBvdXRwdXRzICJIZWxsbywgQWxpY2UhIg0KDQotLS0NCg0KIyMjICoqVXNpbmcgdGhlIENvbW1hbmQgTGluZSBpbiBWUyBDb2RlKioNCg0KLSAqKkJhc2ljIENvbW1hbmRzKio6DQogIC0gKipgbHNgKio6IExpc3RzIGZpbGVzIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeS4NCiAgLSAqKmBjZCA8ZGlyZWN0b3J5PmAqKjogQ2hhbmdlcyB0aGUgd29ya2luZyBkaXJlY3RvcnkuDQogIC0gKipgbWtkaXIgPGZvbGRlcl9uYW1lPmAqKjogQ3JlYXRlcyBhIG5ldyBmb2xkZXIuDQogIC0gKipgcm0gPGZpbGVfbmFtZT5gKio6IERlbGV0ZXMgYSBzcGVjaWZpZWQgZmlsZS4NCiAgLSAqKmBjbGVhcmAqKjogQ2xlYXJzIHRoZSBUZXJtaW5hbCB3aW5kb3cgZm9yIGEgZnJlc2ggc3RhcnQuDQoNCi0gKipOYXZpZ2F0aW9uIFRpcHMqKjoNCiAgLSBVc2UgYGNkIC4uYCB0byBnbyB1cCBvbmUgZGlyZWN0b3J5IGxldmVsLg0KICAtIFRhYiBrZXkgaGVscHMgd2l0aCBhdXRvY29tcGxldGUgZm9yIGZpbGUgYW5kIGZvbGRlciBuYW1lcy4NCg0KLS0tDQoNCiMjIyAqKkFkdmFuY2VkIENvbmNlcHRzOiBTY29wZSBhbmQgU2lkZSBFZmZlY3RzKioNCg0KLSAqKlNjb3BlKio6DQogIC0gKkxvY2FsIFNjb3BlKjogVmFyaWFibGVzIGRlZmluZWQgaW5zaWRlIGZ1bmN0aW9ucyB0aGF0IGNhbiBvbmx5IGJlIHVzZWQgd2l0aGluIHRoYXQgZnVuY3Rpb24uDQogIC0gKkdsb2JhbCBTY29wZSo6IFZhcmlhYmxlcyBkZWZpbmVkIG91dHNpZGUgZnVuY3Rpb25zLCBhY2Nlc3NpYmxlIHRocm91Z2hvdXQgdGhlIGZpbGUuDQoNCi0gKipTaWRlIEVmZmVjdHMqKjoNCiAgLSBBIHNpZGUgZWZmZWN0IG9jY3VycyB3aGVuIGEgZnVuY3Rpb24gbW9kaWZpZXMgc29tZXRoaW5nIG91dHNpZGUgaXRzIHNjb3BlLCBsaWtlIGNoYW5naW5nIGEgZ2xvYmFsIHZhcmlhYmxlLg0KICAtIFVzZSBgZ2xvYmFsYCB0byBkZWNsYXJlIHRoYXQgYSBmdW5jdGlvbiB3aWxsIG1vZGlmeSBhIGdsb2JhbCB2YXJpYWJsZS4NCiAgLSBFeGFtcGxlOg0KICAgIGBgYHB5dGhvbg0KICAgIG1vb2QgPSAiOigiICAjIEdsb2JhbCB2YXJpYWJsZQ0KICAgIA0KICAgIGRlZiB1cGRhdGVfbW9vZChuZXdfbW9vZCk6DQogICAgICAgIGdsb2JhbCBtb29kDQogICAgICAgIG1vb2QgPSBuZXdfbW9vZCAgIyBNb2RpZmllcyB0aGUgZ2xvYmFsIHZhcmlhYmxlDQoNCiAgICB1cGRhdGVfbW9vZCgiOkQiKSAgIyBOb3cgbW9vZCBpcyAiOkQiDQogICAgYGBgDQoNCi0tLQ0KDQojIyMgKipSZXZpZXcgU3VtbWFyeSoqDQoNCjEuICoqVlMgQ29kZSoqOiBTZXQgdXAgZmlsZXMsIHJ1biBQeXRob24gY29kZSwgYW5kIHVzZSB0aGUgVGVybWluYWwuDQoyLiAqKkJhc2ljIFB5dGhvbioqOiBVc2UgdmFyaWFibGVzLCBgaW5wdXQoKWAsIGFuZCBgcHJpbnQoKWAuDQozLiAqKkZ1bmN0aW9ucyoqOiBEZWZpbmUsIGNhbGwsIHBhc3MgcGFyYW1ldGVycywgYW5kIGhhbmRsZSByZXR1cm4gdmFsdWVzLg0KNC4gKipDb21tYW5kLUxpbmUgU2tpbGxzKio6IE5hdmlnYXRlIGFuZCBtYW5hZ2UgZmlsZXMgaW4gVlMgQ29kZSdzIFRlcm1pbmFsLg0KNS4gKipTY29wZSAmIFNpZGUgRWZmZWN0cyoqOiBVbmRlcnN0YW5kIGxvY2FsIHZzLiBnbG9iYWwgc2NvcGUsIGFuZCB3aGVuIGZ1bmN0aW9ucyBjYW4gbW9kaWZ5IG91dHNpZGUgdmFyaWFibGVzLiANCg0KLS0tDQoNCg==