Skip to content

Instantly share code, notes, and snippets.

@lundeen-bryan
Last active April 17, 2024 03:19
Show Gist options
  • Save lundeen-bryan/3b8b5f5c9242287a83ac2a03e12f4fff to your computer and use it in GitHub Desktop.
Save lundeen-bryan/3b8b5f5c9242287a83ac2a03e12f4fff to your computer and use it in GitHub Desktop.
MISC

ACRExtensions_bookmarklet_README

The Bookmarklet

Note, it appears to not work anymore, but some of it is documented in the following ccimpoiACRExtensions Amazon Cloud Reader extensions

javascript:(()%3D%3E%7Bfunction%20enhanceKindleContextMenu()%7Bvar%20e%3Dnull%2Cn%3Dnull%2Co%3Dnull%3Bif(void%200!%3D%3Dwindow.KindleReaderContextMenu)e%3Dwindow%3Belse%20if(window.length)for(var%20t%3D0%3Bt%3Cwindow.length%3Bt%2B%2B)if(void%200!%3D%3Dwindow%5Bt%5D.KindleReaderContextMenu)%7Be%3Dwindow%5Bt%5D%3Bbreak%7Dif(%22object%22%3D%3Dtypeof%20e)if(o%3De.KindleReaderContextMenu%2Cn%3De.document%2Cvoid%200%3D%3D%3Do.ACRExtensions)%7Bo.ACRExtensions%3D!0%3Bvar%20i%3Do.show%3Bo.show%3Dfunction()%7Bvar%20e%3Di.apply(o%2Carguments)%2Ct%3Dnull%2Cs%3Dnull%3Bif(void%200!%3D%3Darguments%5B3%5D%26%26void%200!%3D%3Darguments%5B3%5D.start)%7Bvar%20d%3Darguments%5B3%5D.start%2Cr%3Darguments%5B3%5D.end%3B%24(%22iframe%22%2Cn).each((function(e%2Cn)%7Bvar%20o%3D%24(n).contents().get(0)%3Bif(%24(%22%23%22%2Bd%2Co).get(0))return%20t%3Do%2C!1%7D))%2Ct%26%26((s%3Dt.createRange()).setStartBefore(%24(%22%23%22%2Bd%2Ct).get(0))%2Cs.setEndAfter(%24(%22%23%22%2Br%2Ct).get(0)))%7D%24(%22%23ACRExtensions_copyB_sep%22%2Cn).remove()%2C%24(%22%23ACRExtensions_copyB%22%2Cn).remove()%3Bvar%20a%3D%24('%3Cdiv%20id%3D%22ACRExtensions_copyB_sep%22%20class%3D%22kindle_menu_separator%22%3E%3C%2Fdiv%3E')%2Cl%3D%24('%3Cdiv%20id%3D%22ACRExtensions_copyB%22%20class%3D%22kindle_menu_button%20button_enabled%20ui-corner-left%22%3ECopy%3C%2Fdiv%3E')%3Breturn%20%24(%22%23kindle_menu_border%22%2Cn).append(a).append(l)%2CsetTimeout((function()%7Ba.show()%2Cl.removeClass(%22button_hidden%22)%7D)%2C1)%2C%24(%22%23ACRExtensions_copyB%22%2Cn).click((function(e)%7Bs%26%26window.open(%22%22%2C%22ACRExtensions%22%2C%22height%3D400%2Cwidth%3D400%2Clocation%3D0%2Cmenubar%3D0%2Cscrollbars%3D1%2Ctoolbar%3D0%22).document.body.appendChild(s.cloneContents())%7D))%2Ce%7D%2Calert(%22ACRExtensions%20is%20now%20active.%22)%7Delse%20alert(%22ACRExtensions%20is%20already%20active.%22)%3Belse%20alert(%22Error%3A%20ACRExtensions%20is%20not%20active.%20The%20Amazon%20Cloud%20Reader%20window%20could%20not%20be%20found.%22)%7D%7D)()%3B

What it Does

This JavaScript code is designed to be executed as a bookmarklet on a webpage. Here's a breakdown of its functionality:

  1. Initialization:

    • The code begins by declaring and initializing a few variables (w, kDoc, and kObj).
    • It then checks if the current window has a defined KindleReaderContextMenu. If it does, it sets the variable w to the current window. If it doesn't find it in the current window, it loops through each window frame (typically from iframes) to look for it.
  2. Check for KindleReaderContextMenu:

    • If it successfully finds an instance of KindleReaderContextMenu, the code sets the kObj to that instance and kDoc to the document of that window.
    • It then checks if the ACRExtensions property exists within the KindleReaderContextMenu. If it does not, it modifies the behavior of the KindleReaderContextMenu:
  3. Modifying KindleReaderContextMenu:

    • The original show method of KindleReaderContextMenu is stored in oldMethod.
    • The show method is then overridden to add new functionality. Specifically, it:
      • Checks for the presence of specific arguments passed to this method. If these arguments exist, it appears to identify a range within an iframe (probably a text selection in the Kindle Cloud Reader).
      • Creates a range that corresponds to the start and end IDs provided in the arguments.
      • Removes any previous extensions elements (ACRExtensions_copyB_sep and ACRExtensions_copyB).
      • Adds a new separator (sepEl) and a "Copy" button (copyB) to the Kindle context menu.
      • The "Copy" button, when clicked, opens a new window and appends the contents of the previously created range to this new window.
    • After overriding the show method, it alerts the user that "ACRExtensions is now active."
  4. ACRExtensions Active:

    • If the ACRExtensions property already exists, it simply alerts the user that "ACRExtensions is already active."
  5. Error Handling:

    • If no KindleReaderContextMenu is found in the current window or any of its frames, it alerts the user with the message "Error: ACRExtensions is not active. The Amazon Cloud Reader window could not be found."

In simpler terms, this bookmarklet seems to be an enhancement for the Amazon Cloud Reader's context menu. When invoked, it adds a "Copy" button to the context menu, allowing users to copy selected content from the Amazon Cloud Reader into a new window.

The provided bookmarklet is a URL-encoded version of the JavaScript code. Let's decode it to understand the changes you've made:

Decoding the URL-encoded bookmarklet gives us:

javascript: (() => {
    function enhanceKindleContextMenu() {
        var e = null,
            n = null,
            o = null;
        if (void 0 !== window.KindleReaderContextMenu) e = window;
        else if (window.length)
            for (var t = 0; t < window.length; t++)
                if (void 0 !== window[t].KindleReaderContextMenu) {
                    e = window[t];
                    break;
                }
        if ("object" == typeof e)
            if ((o = e.KindleReaderContextMenu, n = e.document, void 0 == o.ACRExtensions)) {
                o.ACRExtensions = !0;
                var i = o.show;
                o.show = function() {
                    var e = i.apply(o, arguments),
                        t = null,
                        s = null;
                    if (void 0 !== arguments[3] && void 0 !== arguments[3].start) {
                        var d = arguments[3].start,
                            r = arguments[3].end;
                        $("iframe", n).each((function(e, n) {
                            var o = $(n).contents().get(0);
                            if ($("#" + d, o).get(0)) return t = o, !1
                        })), t && ((s = t.createRange()).setStartBefore($("#" + d, t).get(0)), s.setEndAfter($("#" + r, t).get(0)))
                    }
                    $("#ACRExtensions_copyB_sep", n).remove(), $("#ACRExtensions_copyB", n).remove();
                    var a = $('<div id="ACRExtensions_copyB_sep" class="kindle_menu_separator"></div>'),
                        l = $('<div id="ACRExtensions_copyB" class="kindle_menu_button button_enabled ui-corner-left">Copy</div>');
                    return $("#kindle_menu_border", n).append(a).append(l), setTimeout((function() {
                        a.show(), l.removeClass("button_hidden")
                    }), 1), $("#ACRExtensions_copyB", n).click((function(e) {
                        s && window.open("", "ACRExtensions", "height=400,width=400,location=0,menubar=0,scrollbars=1,toolbar=0").document.body.appendChild(s.cloneContents())
                    })), e
                }, alert("ACRExtensions is now active.")
            } else alert("ACRExtensions is already active.");
        else alert("Error: ACRExtensions is not active. The Amazon Cloud Reader window could not be found.")
    }
})();

Changes From the Original

  1. Arrow Function: The code is now wrapped in an ES6 arrow function.
  2. Variable Naming: Variable names have been shortened (w to e, kDoc to n, kObj to o, and so on). This is possibly to reduce the overall size of the bookmarklet.
  3. Checking for Undefined: You've changed the typeof checks for undefined to use void 0 !== variableName, which is another way to check if a variable is undefined.
  4. Use of ES6 Features: The function uses more ES6 features, such as arrow functions for callback functions.
  5. Code Compression: The code has been compressed for brevity, removing unnecessary spaces and using more concise expressions. This is common in bookmarklets to minimize the length.

The logic of the function remains consistent with the previous version, but these changes make the bookmarklet more compact and updated to newer JavaScript syntax.

//use this schema to do alt row shading, use format current view in modern sharepoint and apply to entire row
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json",
"additionalRowClass": "=if(@rowIndex%2==0,'ms-bgColor-themeLight','')"
}
#!/bin/bash
: ' here-doc ends with the next single quote below:
SCRIPT NAME: get_files_in_e.sh
DESCRIPTION:
This script lists files of specified extensions from a given directory, displaying them in a tree-like structure.
The results are saved to a text file in the users "Downloads" folder. At the end, the script reports the total
number of files listed and the number of folders containing these files.
USAGE:
Run the script using:
./get_files_in_e.sh
Upon execution, the script will prompt the user for:
1. A directory path (e.g., /e/)
2. File extensions, separated by commas without spaces (e.g., .epub,.pdf)
AUTHOR:
[Your Name or Handle]
DATE:
[Date of Creation or Last Modification]
'
# Ask the user for the starting directory
read -p "Please enter the directory path (e.g., /e/): " START_DIR
# Ensure the directory exists
if [ ! -d "$START_DIR" ]; then
echo "Directory $START_DIR does not exist!"
exit 1
fi
# Ask the user for file extensions (comma-separated, without spaces)
read -p "Enter file extensions separated by commas (e.g., .epub,.pdf): " INPUT_EXTENSIONS
# Convert the comma-separated extensions into a format suitable for the find command
IFS=',' read -ra EXT_ARRAY <<< "$INPUT_EXTENSIONS"
FIND_EXPRESSION=""
for ext in "${EXT_ARRAY[@]}"; do
if [ -z "$FIND_EXPRESSION" ]; then
FIND_EXPRESSION="-iname '*$ext'"
else
FIND_EXPRESSION="$FIND_EXPRESSION -o -iname '*$ext'"
fi
done
# File to save the output
OUTPUT_FILE=~/Downloads/files_found.txt
# Change to the starting directory
cd "$START_DIR" || exit 1
# Find and list files with the given extensions in a tree structure and save to the output file
eval "find . -type f \( $FIND_EXPRESSION \) | sed -e 's;[^/]*/;|----;g;s;----|; |;g'" > "$OUTPUT_FILE"
# Count the number of files listed
file_count=$(eval "find . -type f \( $FIND_EXPRESSION \)" | wc -l)
# Count the number of directories containing the files
folder_count=$(eval "find . -type f \( $FIND_EXPRESSION \) -exec dirname {} \; | sort -u" | wc -l)
echo "Listing has been saved to $OUTPUT_FILE."
echo "Total number of files listed: $file_count"
echo "Total number of folders containing the files: $folder_count"
SELECT name FROM sqlite_master WHERE type='table'
/*markdown
| name |
|-------------------|
| ice_cream_flavors |
*/
/*markdown
## EXAMPLE OF A SQLITE SQL NOTEBOOK
Just some example randomly ha
*/
SELECT * FROM ice_cream_flavors
/*markdown
| id | flavor | rating |
|----|-----------|--------|
| 1 | choco | 10 |
| 2 | straw | 9 |
| 3 | pistachio | 7.2 |
*/
| |----1 and 2 Esdras - Ancient Texts.epub
| |----1 and 2 Esdras.pdf
| |----1 & 2 Maccabees.pdf
| |----1 & 2 Maccabees - Ancient Texts.epub
| |----315 Genesis of All Prophecy.pdf
| |----315 Genesis of All Prophecy - Rabbi Eric E. Walker.epub
| |----Abaddon Ascending - Thomas R. Horn.epub
| |----Abaddon Ascending.pdf
| |----Afterlife - Donna Howell, Josh Peck,.epub
| |----Afterlife.pdf
| |----Ahriman Gate - Thomas R. Horn.epub
| |----Ahriman Gate.pdf
| |----Alliance of Evil - LTC. Robert L. Maginnis.epub
| |----Alliance of Evil.pdf
| |----Angels On Assignment Again - Jennifer LeClaire.epub
| |----Angels On Assignment Again.pdf
| |----Antichrist and the Final Solution 8.17 prepared for Kindle (1).pdf
| |----Antichrist and the Final Soluti - Tom Horn.epub
| |----Bad Moon Rising - Derek Gilbert.epub
| |----Bad Moon Rising.pdf
| |----Beast Tech.pdf
| |----Beast Tech - Thomas R. Horn.epub
| |----Blood on the Altar - Thomas R. Horn.epub
| |----Blood on the Altar.pdf
| |----Book of Enoch - Ancient Texts.epub
| |----Book of Enoch.pdf
| |----Jasher.pdf
| |----Jasher - Ancient Texts.epub
| |----Jubilees.pdf
| |----Jubilees - Ancient Texts.epub
| |----Book of Judith.pdf
| |----Book of Judith - Ancient Texts.epub
| |----Book of Sirach.pdf
| |----Book of Sirach.epub
| |----Tobias - Ancient Texts.epub
| |----Tobias.pdf
| |----Book of Wisdom.pdf
| |----Book of Wisdom - Ancient Texts.epub
| |----Brotherhood of Darkness - Dr. Stanley Monteith.epub
| |----Brotherhood of Darkness.pdf
| |----Cauldron.pdf
| |----Cauldron - Terry James.epub
| |----Christmas Classics.pdf
| |----Christmas Classics - collaborative.epub
| |----COLLISION COURSE20.pdf
| |----COLLISION COURSE - LTC. Robert L. Maginnis.epub
| |----Conmpanion to the book of Enoch - Michael Heiser.epub
| |----Conmpanion to the book of Enoch Vol 2.pdf
| |----Companion to the book of Enoch.pdf
| |----A Companion to the Book of Enoc - Dr. Michael S. Heiser.epub
| |----Dark Covenant.pdf
| |----Dark Covenant - Donna Howell.epub
| |----The Day the Earth Stands Still - Derek P. Gilbert.epub
| |----The Day the Earth Stands Still.pdf
| |----Dead Pets Don't Lie - Joe Ardis.epub
| |----Dead Pets Don't Lie.pdf
| |----Deeper State, The.pdf
| |----Deeper State, The - LT. COL. Robert Maginnis.epub
| |----Demonomics - Terry James.pdf
| |----Demonomics - Terry James.epub
| |----Departure, The - Terry James.epub
| |----Departure, The.pdf
| |----Devils and Evil Spirits of Baby - R. Campbell Thompson, M.A_.epub
| |----Devils and Evil Spirits of Babylonia, The.pdf
| |----Dispensations The Clarence Lark - Clarence Larkin.epub
| |----Project - Clarence Larkin Collection.pdf
| |----Do our pets go to Heaven - Terry James, Thomas Horn.pdf
| |----Do our pets go to Heaven - Terry James, Thomas Horn.epub
| |----Earth's Earliest Ages - George H. Pember.epub
| |----Earth's Earliest Ages.pdf
| |----Ebenezer the Final Years of Scrooge RECOVERED AND REBUILT NOV 2019.pdf
| |----Ebenezer_ The Final Years of Sc - Donna Howell.epub
| |----Encounters.pdf
| |----Encounters - Allie Anderson.epub
| |----Endtimes Investigations with Da - David Heavener.epub
| |----Endtimes Investigations with David Heavener.pdf
| |----Everyday Champions - Joe Horn.epub
| |----Everyday Champions.pdf
| |----Exo-Vaticana - Thomas R. Horn.epub
| |----Exo-Vaticana.pdf
| |----Fallen Angels and the Heroes of Mythology, The.pdf
| |----Fallen Angels and the Heroes of - Rev. John Fleming, A.B_.epub
| |----Final Fire - Thomas Horn, Larry Spargimino.epub
| |----Final Fire.pdf
| |----Final Roman Emperor, The.pdf
| |----Final Roman Emperor, The - Thomas Horn.epub
| |----Forbidden Gates.pdf
| |----Forbidden Gates - Thomas R. Horn.epub
| |----Forbidden Gates TEACHER'S GUIDE.epub
| |----Forbidden Gates TEACHER'S GUIDE.pdf
| |----Labryinth for Kindle FINAL.pdf
| |----Forbidden Secrets of the Labyri - Mark Flynn.epub
| |----Future War.pdf
| |----Future War - Lieutenant Colonel Robert L. Ma.epub
| |----GIANTS GODS DRAGONS.pdf
| |----GIANTS GODS DRAGONS.epub
| |----GIVE ME LIBERTY, NOT MARXISM - LTC Robert L. Maginnis.epub
| |----GIVE ME LIBERTY.pdf
| |----God's Ghostbusters - Collaborative.epub
| |----God's Ghostbusters.pdf
| |----Gods & Thrones - Carl Gallups.epub
| |----Gods & Thrones.pdf
| |----Gods of Ground Zero - Carl Gallups.epub
| |----Gods of Ground Zero.pdf
| |----Gods of the Final Kingdom.pdf
| |----Gods of the Final Kingdom - Carl Gallups.epub
| |----Great Inception - Derek P. Gilbert.pdf
| |----Great Inception - Derek P. Gilbert.epub
| |----Great Pyramid.pdf
| |----Great Pyramid - N. W. Hutchings.epub
| |----Handmaidens Conspiracy, The - Donna Howell.epub
| |----Handmaidens Conspiracy, The.pdf
| |----How to Overcome the Most Frightening Things You WILL Face This Century.pdf
| |----How to Overcome the Most Frightening Things You WILL Face This Century.epub
| |----I Predict.pdf
| |----I Predict - Thomas Horn.epub
| |----Immortality and the Unseen Worl - William Oscar Emil Oesterley.epub
| |----Immortality and the Unseen World.pdf
| |----Kings of the East for Kindle 5.26.22.pdf
| |----Kings of the East - Robert Maginnis.epub
| |----Unmasking the Chaldean Spirit.pdf
| |----Last Clash of the Titans - Derek P. Gilbert.epub
| |----Last Clash of the Titans.pdf
| |----Last Days Diary.pdf
| |----Last Days Diary - Terry James.epub
| |----Lawless for Kindle - Terry James.epub
| |----Lawless for Kindle.pdf
| |----Learning to Lean - Collaborative.epub
| |----Learning to Lean.pdf
| |----MASQUERADE - Carl Gallups.epub
| |----MASQUERADE.pdf
| |----Milieu, The - Collaborative.epub
| |----Milieu, The.pdf
| |----MISFITS.pdf
| |----MISFITS - Donna Howell, Allie Henson, Nit.epub
| |----Nephilim Stargates - Thomas R. Horn.epub
| |----Nephilim Stargates.pdf
| |----Never Submit.pdf
| |----Never Submit - Lt. Col. Robert Maginnis.epub
| |----No Fences.pdf
| |----No Fences - Nita Horn, Donna Howell.epub
| |----On the Path of the Immortals - Thomas R. Horn, Cris Putnam.epub
| |----On the Path of the Immortals.pdf
| |----Pandemonium's Engine.pdf
| |----Pandemonium's Engine - Collaborative.epub
| |----Petrus Romanus.pdf
| |----Petrus Romanus - Thomas R. Horn.epub
| |----Planet X - Douglas A. Elwell.pdf
| |----Planet X - Douglas A. Elwell.epub
| |----Progressive Evil - LTC. Robert L. Maginnis.epub
| |----Progressive Evil.pdf
| |----Rabbi, the Secret Message, and - Carl Gallups.epub
| |----Rabbi, the Secret Message, and the Identity of the Messiah, The.pdf
| |----Rabbis, Donald Trump...Third Temple - Thomas R. Horn.epub
| |----Rabbis, Donald Trump...Third Temple.pdf
| |----Radicals.pdf
| |----Radicals - Donna Howell.epub
| |----Redeemed Unredeemable - Thomas Horn, Donna Howell.pdf
| |----Redeemed Unredeemable - Thomas Horn, Donna Howell.epub
| |----RLOAT Vol 1.pdf
| |----RLOAT Vol 1 - Ancient Texts.epub
| |----RLOAT Vol 2.pdf
| |----RLOAT Vol 2 - Ancient Texts.epub
| |----RLOAT Vol 3.pdf
| |----RLOAT Vol 3 - Ancient Texts.epub
| |----Reversing Hermon - Dr. Michael S. Heiser.epub
| |----Reversing Hermon.pdf
| |----Saboteurs - Thomas R. Horn.epub
| |----Saboteurs.pdf
| |----Second Coming of the New Age, T - Bancarz, Peck.epub
| |----Second Coming of the New Age, The.pdf
| |----SHADOWLAND.pdf
| |----SHADOWLAND - Thamas R. Horn.epub
| |----Sheeriyth Imperative, The - Dr. Michael Lake.epub
| |----Sheeriyth Imperative, The.pdf
| |----The Shinar Directive - Dr. Michael Lake.epub
| |----The Shinar Directive.pdf
| |----Supernatural Worldview, The - Cris Putnam.epub
| |----Supernatural Worldview, The.pdf
| |----Systematic Theology Vol 1 - Augustus Hopkins Strong, D.D., .epub
| |----Systematic Theology Vol 1.pdf
| |----Systematic Theology Vol 2 - Augustus Hopkins Strong, D.D., .epub
| |----Systematic Theology Vol 2.pdf
| |----Systematic Theology Vol 3 - Augustus Hopkins Strong, D.D., .epub
| |----Systematic Theology Vol 3.pdf
| |----Temple at the Center of Time.pdf
| |----Temple at the Center of Time - David Flynn.epub
| |----Boy From El Mirage KINDLE.pdf
| |----Boy From El Mirage - Thomas Horn.epub
| |----The Defender Bible - Old Testament, New Testament, E.epub
| |----The Disappearing.pdf
| |----THE DISAPPEARING - Terry James.epub
| |----The Lost Prophecies of Qumran - Josh Peck.epub
| |----The Lost Prophecies of Qumran.pdf
| |----MESSENGER - Thomas Horn.epub
| |----MESSENGER.pdf
| |----The Omega Conspiracy - Dr. I.D.E. Thomas.epub
| |----The Omega Conspiracy RECOVERED AND REBUILT NOV 2019.pdf
| |----Second Coming Of Saturn .pdf
| |----Second Coming Of Saturn - Derek P. Gilbert.epub
| |----SUMMONING.pdf
| |----The Summoning_ Preparing for th - Carl Gallups.epub
| |----The Warrior-Priest Mindset - Drew Graffia.epub
| |----The Warrior-Priest Mindset.pdf
| |----Timebomb.pdf
| |----Timebomb - Joe Horn, Allie Anderson.epub
| |----TRAJECTORY - Terry James.epub
| |----TRAJECTORY FOR KINDLE (1).pdf
| |----Triumph of the Redeemed - Brentner, Jonathan C.epub
| |----Triumph of the Redeemed.pdf
| |----True Power - David Heavener.epub
| |----True Power.pdf
| |----Trump Prophecies, The.pdf
| |----Trump Prophecies, The - Mark Taylor.epub
| |----Unearthing the Lost World of th - Thomas R. Horn.epub
| |----Unearthing the Lost World of the Cloudeaters.pdf
| |----Unlocking Eden KINDLE.pdf
| |----Unlocking Eden KINDLE - Joe Horn.epub
| |----Unmasking the Chaldean Spirit.pdf
| |----Unmasking the Chaldean Spirit - Zev Porat.epub
| |----Unraveling the Multiverse - Josh Peck.epub
| |----Unraveling the Multiverse.pdf
| |----Unscrambling the Millennial Par - Allie Anderson.epub
| |----Unscrambling the Millennial Paradox.pdf
| |----Veneration - Sharon K. Gilbert, Derek P. Gil.epub
| |----Veneration.pdf
| |----Occult Theocrasy Vol 1 - Lady Queenborough.epub
| |----Occult Theocrasy - Volume 1.pdf
| |----Occult Theocrasy Vol 2 - Lady Queenborough.epub
| |----Occult Theocrasy - Volume 2.pdf
| |----We Walk by Faith_.Not by Sight - Dorothy Spaulding.epub
| |----We Walk by Faith...Not by Sight.pdf
| |----What Dwells Beyond - Jeffrey W. Mardis.epub
| |----What Dwells Beyond.pdf
| |----When Once We Were a Nation.pdf
| |----When Once We Were a Nation - Collaborative.epub
| |----Zeitgeist 2025 - Thomas Horn.epub
| |----Zeitgeist 2025 .pdf
| |----Zenith 2016.pdf
| |----Zenith 2016 - Thomas R. Horn.epub
fix_filename() {
if [[ $# -eq 0 ]]; then
echo "Usage: fix_filename <filename or directory> [recursive true/false]"
return 1
fi
local target="$1"
local recursive="${2:-false}" # Default to false if not provided
rename_item() {
local item="$1"
# Use sed to replace '+' and '-', spaces with '_', and make lowercase
local new_name=$(echo "$item" | sed -e 's/[+ -]/_/g' | tr '[:upper:]' '[:lower:]')
if [[ -z "$new_name" ]]; then
echo "Error: New name for '$item' is empty. Skipping."
return 1
fi
if [[ "$item" != "$new_name" ]]; then
if [[ -e $new_name ]]; then
echo "Error: '$new_name' already exists. Skipping '$item'."
else
mv -- "$item" "$new_name"
echo "Renamed '$item' to '$new_name'"
fi
fi
}
if [[ -d $target ]]; then
if [[ $recursive == true ]]; then
find "$target" -depth ! -path "$target" -print0 | while IFS= read -r -d $'\0' item; do
dir_path=$(dirname "$item")
base_name=$(basename "$item")
pushd "$dir_path" > /dev/null
rename_item "$base_name"
popd > /dev/null
done
else
dir_path=$(dirname "$target")
base_name=$(basename "$target")
pushd "$dir_path" > /dev/null
rename_item "$base_name"
popd > /dev/null
fi
elif [[ -e $target ]]; then
rename_item "$target"
else
echo "Error: '$target' does not exist."
return 1
fi
}

USER

The following is a job description and I'd like to ask you some questions about it.

# Job Description

## Percentage of total duties and description of tasks

**40%**
Using complex code (Visual Basic, SQL, Javascript), designs and implements database systems that organize and disseminate pertinent fiscal information (MIRS, SAP, Position Authority) to BMB, CDCR’s executive management, and control agencies. Utilizes MS Access databases, Excel and SQL to gather, format, and disseminate fiscal reports and position authority information in order to provide reports to management upon request.

**30%**
Maintains and improves existing complex coding for database operational efficiency in order to conduct daily, weekly and monthly data maintenance tasks. Automates routine tasks to eliminate repetitive work performed by branch analysts. Automates budget change data entry into the Fi$Cal system. Performs monthly upload of MIRS data to SQL server tables.

**15%**
Acts as the technical advisor and provides assistance and training to branch staff in the use of custom automation software. Investigates staff’s information technology issues and provides solutions and alternatives in order to achieve the best use of available multifunction automated office systems and hardware.

**5%**
Maintains procedures, documentation and standards for in‐house database systems (Costing Master, Vacancy Report, Position Recap, Allotment database).

**5%**
Performs other related special proposals and budget duties as required.

**5%**
Perform administrative duties including, but not limited to: adhere to Department policies, rules and procedures; submit administrative requests including leave, travel, and training in a timely and appropriate manner; accurately report time, and submit timesheets by the due date.

ASSISTANT

Sure, based on the provided job description, please go ahead and ask your questions!

USER

I'm also going to provide for you an SOQ that I wrote for this job to show my qualifications. After you review the SOQ, don't reply with anything yet. Just let me know you've reviewed both the job description and my SOQ.

Core Competencies: My experience and education have equipped me with essential skills such as database system design and implementation, data analysis, project management, bridging IT and business units, application development, stakeholder collaboration, data visualization, and effective communication.
Database System Design & Implementation: At DSH-Napa, I spearheaded the "EZ Logger" project, a comprehensive database system. Beyond basic CRUD operations, it incorporated advanced features such as automated data validation, conditional logic flows, and integration with other in-house tools. I employed complex SQL procedures and implemented normalization principles to ensure scalability and robustness, making the system flexible for future enhancements. This system improved operational efficiency by 73% and reduced errors by 68%.
Technical Initiatives & Application Development: In managing the "CourtReports" application, I faced a challenging task when the business rules governing report submission timelines underwent a pivotal shift. Previously, the system operated on a straightforward cadence: a patient's initial report was due 90 days post-commitment, with subsequent reports due every six months. The updated rules introduced a conditional dependency; if the 90-day report was completed early, all ensuing report timelines would hinge on that early completion date. This modification was applicable only for patients admitted after April 20, adding another layer of complexity.
I re-engineered the SQL code rather than employing the earlier method that relied heavily on multiple sub-queries. By integrating a Common Table Expression (CTE), I transitioned the logic from a disjointed multi-sub-query structure to a more streamlined, efficient, and readable format. This made the solution more performant and significantly enhanced maintainability, ensuring that future modifications could be made with minimal friction. Such experiences showcase my approach of constantly seeking ways to bridge the technical-business divide, ensuring our IT solutions are robust, agile, and aligned perfectly with ever-evolving business needs.
My experience with TestPro further complemented this hands-on approach to application development and adjustment. During this boot camp, I was deeply involved in the practical application of the Scrum framework, often taking on the role of the "Scrum Master." Our team leveraged Jira to track our progress meticulously, and our daily stand-ups fortified our project's direction and momentum.
Technical Proficiency & Solution Development: My proficiency spans a broad spectrum of tools and languages, each judiciously selected for the task. A compelling instance of this was my response to the constraints posed before we had licensing for Adobe Pro. Recognizing the pressing need to merge PDF documents for court submissions, I developed a Python script that replicated the merging capabilities of Adobe Pro. This temporary solution ensured the continuity of critical workflows, minimizing disruptions. Later, once Adobe Pro was licensed, I leveraged Visual Basic to interface with the Adobe Acrobat API, further automating converting and merging PDFs and streamlining our document management processes. My toolkit, from scripts in AutoIT, Python, and Visual Basic to methodologies imbibed from TestPro boot camp, underpins my constant drive to innovate and refine our IT solutions, ensuring they always serve as robust, agile bridges between our technological and business requirements.
Meeting Facilitation & Training: As the Scrum Master during my time with TestPro, I regularly facilitated our daily stand-up meetings, ensuring that each member was aligned, issues were promptly addressed, and collaboration was at its peak. This experience strengthened my ability to convey complex IT concepts, drive team collaboration, and ensure that projects remained on track and within the set timelines. This iterative, feedback-driven approach has been instrumental in managing projects and fostering mutual respect and understanding among my teammates.
Data Analysis & Reporting: During my tenure at DSH-Napa, I regularly harnessed data-driven insights to make informed decisions. However, a pivotal aspect of my role was the ability to convey these insights, which I achieved through carefully crafted presentations. My academic journey at the University of Phoenix instilled in me the skills to develop and deliver impactful PowerPoint presentations. These skills were further sharpened at Napa State Hospital, where I frequently took the lead in elucidating complex data findings to diverse groups. Utilizing digital tools like PowerPoint and traditional methods like hand-drawn diagrams on a whiteboard, I ensured that my audience, regardless of their technical proficiency, gained a clear and actionable understanding of the information presented. This dual skill set –deriving insights and effectively communicating them – underscored my commitment to driving informed, data-driven strategies at every juncture.
Project Management & Compliance: Ensuring compliance with standards like HIPAA and the ability to identify risks proactively proves my commitment to both the project management and compliance facets of the Associate Business Systems Analyst role.
Providing Excellent Customer Service: In my role at DSH-Napa, I was approached by a department head who was overwhelmed with the intricacies of managing multiple doctors' reports and ensuring their timely delivery to the court. Recognizing the urgency and importance of this request, I initiated a thorough consultation to understand their exact needs and pain points. I employed my technical skills and knowledge to develop "EZ Logger," a database system that streamlined the process. My commitment to service didn't end with the system's deployment; I ensured every user was trained effectively, adapting my training approach to suit each user's proficiency level. I also set up a feedback loop, regularly checking in to address any concerns or improvements, underscoring my unwavering commitment to customer satisfaction and success.

ASSISTANT

I've reviewed both the job description and your Statement of Qualifications (SOQ). Please proceed with your questions or let me know how I can assist further.

USER

Lastly, I'd like you to act as a job coach and use the given information to help me answer some general interview questions below. After reviewing the questions, start with some general advice that a job coach might offer.

general interview questions that are commonly asked:

1. **Introductory Questions**:
   - Tell me about yourself.
   - How did you hear about this position?

2. **Experience & Background**:
   - Can you explain the gaps in your work history?
   - Describe a challenge you've faced at work and how you dealt with it.
   - How does your previous experience prepare you for this role?

3. **Behavioral/Situational Questions**:
   - Describe a time when you had to work with a difficult colleague. How did you handle it?
   - Can you provide an example of a project that did not go as planned and how you managed it?
   - Describe a situation where you went above and beyond for a customer or colleague.

4. **Motivational Questions**:
   - Why do you want this job?
   - Why should we hire you?
   - Where do you see yourself in 5 years?

5. **Cultural Fit & Team Dynamics**:
   - What kind of work environment do you thrive in?
   - Describe a time when you disagreed with a team member. How did you resolve it?
   - How do you handle feedback or criticism?

6. **Work Ethics & Problem Solving**:
   - Describe a time when you had to handle a high-pressure situation.
   - How do you prioritize your tasks when faced with multiple deadlines?
   - Explain a situation where you had to solve a difficult problem. What did you do?

7. **Questions About the Company/Role**:
   - What do you know about our company?
   - What interests you about this role?
   - Do you have any concerns about the job or the company?

8. **Questions on Adaptability & Growth**:
   - How do you handle change in the workplace?
   - Can you describe a time when you had to learn a new tool or technology? How did you approach it?
   - How do you ensure continuous professional growth?

9. **Personal Qualities & Characteristics**:
   - How would your previous coworkers describe you?
   - What are your greatest strengths and weaknesses?
   - What are you most proud of in your career?

10. **Closing Questions**:
   - Do you have any questions for us?
   - What are your salary expectations?
   - When would you be available to start?

ASSISTANT

Certainly! As a job coach, here's some general advice before diving into the specific answers:

General Interview Advice:

  1. Be Authentic: Always be genuine in your answers. Interviewers can usually tell if a candidate is not being sincere. It's okay not to have a perfect answer for every question, but it's essential to be honest.

  2. Use the STAR Technique: Especially for behavioral/situational questions, structure your answers using the STAR technique:

    • Situation: Describe the situation.
    • Task: Explain the task you had at hand.
    • Action: Detail the actions you took.
    • Result: Highlight the outcomes of those actions.
  3. Prepare: Familiarize yourself with the job description and align your past experiences with the required qualifications. Practice your answers but don't memorize them to sound robotic.

  4. Body Language: Maintain eye contact, offer a firm handshake, sit up straight, and listen attentively. Your body language can say as much as your verbal responses.

  5. Ask Questions: Always have some questions ready for the interviewer. It shows your interest in the position and company.

Now, based on the provided job description and SOQ, here's how you can address some of the interview questions:

Sample Responses:

  1. Tell me about yourself.

    • I've been involved in various projects that revolve around database system design, application development, and data analysis. I pride myself on my ability to bridge the gap between IT and business units. For example, while at DSH-Napa, I developed the "EZ Logger" database system, which improved operational efficiency by 73%.
  2. Describe a challenge you've faced at work and how you dealt with it.

    • One challenge I faced was during the "CourtReports" application project. Business rules changed, introducing a conditional dependency for report submissions. I re-engineered the SQL code, using a Common Table Expression (CTE), making the system more streamlined and efficient.
  3. Why do you want this job?

    • I've always been passionate about leveraging technology to solve complex business challenges. Given my experience in database design, application development, and data analysis, I believe this role aligns perfectly with my skills and passion. The opportunity to contribute to such critical fiscal information dissemination is exciting.
  4. What kind of work environment do you thrive in?

    • I thrive in environments that promote collaboration and continuous learning. I'm at my best when I'm working with a team that values feedback and seeks innovative solutions, as I did during my time at TestPro, where we employed the Scrum framework.
  5. Describe a time when you had to handle a high-pressure situation.

    • At DSH-Napa, before obtaining an Adobe Pro license, there was an urgent need to merge PDF documents for court submissions. Recognizing the immediacy, I developed a Python script to replicate Adobe Pro's merging capabilities, ensuring the continuity of critical workflows.
  6. How do you handle change in the workplace?

    • I view change as an opportunity for growth and innovation. An example would be when the business rules for the "CourtReports" application changed. Instead of viewing it as a setback, I saw it as a chance to improve the system's efficiency and took it as a challenge.
  7. Do you have any questions for us?

    • Yes, can you describe how the team collaborates on large projects? And how does the company ensure continuous learning for its employees?

Remember, while these are sample answers tailored to your SOQ and the job description, it's crucial to adapt them to the specific dynamics of the interview and maintain authenticity. All the best with your interview!

USER

Can you please provide a few more potential answers to question 7?

ASSISTANT

Of course! Question 7 focuses on the company and the role itself, so you'll want answers that show you've done your research and genuinely care about the organization and position. Here are a few more responses tailored to the content you've provided:

  1. What do you know about our company?

    • I understand that CDCR focuses on public safety through the custody and supervision of offenders. I've also learned about the critical importance of fiscal information for the management and control agencies. Given my background in designing and implementing database systems for essential data, I believe I can contribute positively to the agency's goals.
  2. What interests you about this role?

    • I'm particularly interested in the extensive use of Visual Basic, SQL, and Javascript in the design and implementation of database systems, as highlighted in the job description. In my previous roles, I've seen firsthand how these technologies can drive efficiency and accuracy, especially in fiscal data management. The position also offers the right blend of technical challenges and opportunities for collaboration, both of which align with my strengths and passions.
  3. Do you have any concerns about the job or the company?

    • While I don't have any major concerns, I'm curious about how the department plans to adapt to emerging technologies in the future. Given the rapid pace of technological advancement, it's essential for me to understand the long-term vision for the role and the department's technology stack.

When answering these types of questions, it's always a good idea to mention specific details from the job description or the company's public information, as it shows you've taken the time to research and truly care about the position.

USER

Can you please provide a few more potential answers to the questions, "Do you have any questions for us?"

QUESTIONS FOR THEM

Certainly! Asking insightful questions at the end of an interview can demonstrate your genuine interest in the position and your eagerness to be an active participant in the company's success. Here are some potential questions based on the provided job description and your Statement of Qualifications (SOQ):

  1. About the Role:

    • How do you envision the future development and enhancement of the database systems you currently have in place?
    • Given the importance of fiscal reports and position authority information, how do you measure the success or effectiveness of these reports?
    • The job description mentions the use of MS Access databases, Excel, and SQL. Are there any other tools or platforms the department is considering integrating in the near future?
  2. About the Team & Company:

    • Can you tell me more about the team I'd be working with? What are their roles, and how do they collaborate?
    • What is the team's current biggest challenge, and how do you envision this role contributing to its resolution?
    • What does a typical career path look like for someone in this role within the department?
  3. About the Company Culture:

    • How would you describe the company's culture and values, especially when it comes to innovation and continuous improvement?
    • What type of training and professional development opportunities are available to employees in this role?
    • How does the department handle feedback and ideas from employees about improving existing processes?
  4. About the Hiring Process:

    • What are the next steps in the interview process, and what is the expected timeline for a decision?
    • How do you onboard new employees in this role to set them up for success?
    • What qualities and characteristics do the most successful individuals in this position possess?

When formulating your questions, try to ensure they reflect your genuine curiosities and concerns, showcase your research about the company or department, and underscore your commitment to making a meaningful contribution.

USER

I may have multiple questions, do I need to tell them that I have multiple questions or just start asking them questions?

ASSISTANT

It's courteous to mention that you have a few questions, so the interviewer(s) can gauge how much time they might need to allocate for this part of the discussion. It also sets a clear structure for the conversation, allowing the interviewer to mentally prepare for more than just one query.

You can introduce it in a straightforward way. For example:

  • "I do have a few questions about the role and the team. Would now be a good time to go over them?"
  • "Thank you for offering. I've prepared a couple of questions I'd like to ask to better understand the role and the company. Is that alright?"

This approach is considerate and organized. After you've asked one or two questions, be mindful of the interviewer's body language and verbal cues. If they seem pressed for time or indicate that the interview needs to wrap up, you can prioritize your most important questions and save others for a potential follow-up conversation or email.

USER

Yes I like that approach a lot. Here are some of the things I'd like to ask them about but you may need to help me word it a little better: 1) Have they considered using Python and if so would they like to know how I would use Python to help improve the processes? 2) how does the team collaborate on projects that require version control of code. They did not mention using Git or GitHub but I really feel that would be a great solution.

SUGGESTIONS

Of course! I'll help you reword your questions to sound polished and professional:

  1. Regarding Python:

    • "I noticed that the primary languages mentioned in the job description are Visual Basic, SQL, and Javascript. Out of curiosity, has the team considered or experimented with Python for any processes? Given my experience, I've found Python to be quite versatile in certain scenarios, and I'd be happy to discuss potential applications if it's of interest."
  2. Regarding Collaboration and Version Control:

    • "Can you share how the team currently manages collaboration on projects, especially when multiple versions of code are involved? I've had positive experiences using tools like Git and GitHub to streamline code version control and team collaboration. Is that something the department has considered or currently utilizes?"

These questions are structured to show both your interest in the company's processes and your willingness to bring valuable insights and experiences to the table. They also open the door for a deeper conversation on your technical expertise and its potential benefits to the team.

USER

Thank you those are great answers to the final question they are likely to ask. Now I'd like to discuss my answers to the following mock interview and see if they can be improved. Consider all the information I provided in my SOQ when reviewing the following mock interview.


Mock Interview Section

INTERVIEWER

  1. Have you had experience using complex code, specifically with languages like Visual Basic, SQL, and Javascript?

INTERVIEWEE

Yes, I have a lot of experience with all of these languages. I've written a lot of SQL and Visual Basic in particular for my current job.

INTERVIEWER

Great! Let's move to the next question.

  1. Are you familiar with fiscal information systems like MIRS, SAP, and Position Authority?

INTERVIEWEE

No, I don't think so.

INTERVIEWER

Thank you for the honest response.

  1. Have you ever designed or maintained database systems using tools like MS Access and Excel?

INTERVIEWEE

Yes, but I feel MS Access and Excel are very limited if it is going to be a long term solution. My preference would be using a SQL database. But to answer your question, I have designed and built databases for small apps using Access and Excel.

INTERVIEWER

Understood. Your preference for a SQL database is valid and could potentially be beneficial for the company.

  1. Considering the role requires improvements and maintenance of existing complex coding for database operational efficiency, have you worked on automating routine tasks or optimizing existing codes to enhance efficiency in any of your previous roles?

INTERVIEWEE

Yes, many times I've worked on VB and SQL to improve efficiency. For example, We had a very complex SQL stored procedure that merged three subqueries, but I decided to change it to a CTE which made the code easier to read and maintain.

INTERVIEWER

That's a valuable skill to have.

  1. Have you acted as a technical advisor in your previous roles, specifically providing assistance, training, or troubleshooting for staff regarding information technology issues or custom software applications?

INTERVIEWEE

Yes, where I currently work, I typically play the role of the IT liaison for the staff in the building. I typically triage problems that staff are having and if I can't fix the problem myself, I create a ticket for the technical services department (TSD) to take a look at the problem. I provide training as well to show staff basic things like connecting to a network printer or mapping a network drive.

INTERVIEWER

That's great to hear, as it aligns with the advisory role described in the job functions.

  1. Given the importance of proper documentation, have you been responsible for maintaining or creating documentation, procedures, or standards for systems or software you've worked with? If so, can you provide a brief example?

INTERVIEWEE

Yes, I've tried a number of solutions such as simple word documents, or HTML files, but what I found easiest to create and share with other users is OneNote notebooks. These contain links to resources, screenshots and I can easily update pages with new instructions when a procedure changes. I also created a number of how-to video lessons on how to use a couple of different programs we used in Forensic Services.

INTERVIEWER

Using multimedia tools like OneNote and video lessons is a forward-thinking approach and can be quite effective in communicating complex ideas.

  1. The role mentions performing "other related special proposals and budget duties." While the specifics aren't detailed here, have you had any experience with budgeting, financial proposals, or related tasks in your previous roles?

INTERVIEWEE

Yes, I'm the main person designated to do procurement for the department. So I'm very familiar with making sure my requests for products and services comply with state-wide regulations. This includes requesting a check to pay for these products or services.

INTERVIEWER

That's a valuable experience, especially in roles requiring budget and financial responsibilities.

  1. Regarding administrative duties, have you managed tasks such as submitting administrative requests, reporting time, adhering to departmental policies, and ensuring compliance with procedures and deadlines in your current or previous roles?

INTERVIEWEE

Yes, at one point I created an Excel workbook to help track and report time. I also make sure I adhere to departmental policies and compliance. I'm very good at handling deadlines. I typically use a modified agile approach with a Scrum board to track tasks.

INTERVIEWER

Excellent, leveraging agile methodologies like Scrum can be very effective in managing tasks and deadlines.

  1. In the context of collaborating with a team or department, how comfortable are you in adapting to new tools, software, or methods that might already be in place when you join a new role, even if they aren't your personal preference?

INTERVIEWEE

I'm always open to learning new tools, software and methods. Usually I learn these things very fast and train others on them as well. However, I have enough broad experience to recognize where a department might benefit from trying something different. So if this department is using MS Access, although I'm very proficient in Acess, if we have the ability to transition to a more robust model in SQL server, I would present my evidence for such a proposal at the right time in hopes of helping the department improve productivity.

INTERVIEWER

That's a great balance of adaptability and initiative.

  1. Lastly, given that the job description emphasizes the importance of disseminating fiscal reports and information to various stakeholders, how would you rate your communication skills, especially when it comes to explaining complex technical data or solutions to non-technical stakeholders?

INTERVIEWEE

I'm very used to communicating with non-technical people such as doctors and social workers at the hospital where I'm at now. I often have to describe things like metadata and unique keys to people who like to store information in Excel spreadsheets and describe the advantages of using a SQL server or even SharePoint.

INTERVIEWER

Your experience in bridging the gap between technical and non-technical stakeholders is certainly invaluable. Given your responses to the screening questions, you seem to have a strong alignment with many of the job functions listed in the description. While there might be certain areas (like the specific fiscal systems) that you'd need to familiarize yourself with, your breadth of experience in coding, database management, documentation, training, and communication make you a strong contender for the position.


ASSISTANT

Overall, your responses during the mock interview are quite strong and paint a picture of someone who has a broad range of skills and experiences that align well with the job description.

However, let's polish a few of your answers to make them even more impactful:

  1. Experience with languages:

    • "Yes, I have extensive experience with all of those languages. In my current role, I've frequently utilized SQL and Visual Basic for various tasks and projects."
  2. Database tools:

    • "Yes, I have experience designing and maintaining databases with MS Access and Excel. However, while they serve certain purposes, I believe for a more scalable and long-term solution, a SQL database would be preferable. That said, I'm adaptable and can work with whichever tools best suit the business needs."
  3. Automating and optimizing tasks:

    • "Absolutely. In my current role, I've often leveraged VB and SQL to enhance efficiency. For instance, I revamped a complex SQL stored procedure, transitioning from merging three subqueries to implementing a CTE. This not only streamlined the process but also made the code more readable and maintainable."
  4. Advisory roles:

    • "Certainly. In my current position, I frequently act as the IT liaison for our staff. I often assist with troubleshooting issues they encounter, and if it's something beyond my purview, I ensure it's escalated to our technical services department. Additionally, I provide training sessions on essential IT tasks, from connecting to network printers to mapping network drives."
  5. Documentation:

    • "Yes, documentation is essential. I've utilized various methods like word documents and HTML files, but I've found tools like OneNote to be especially effective. It allows for easy updating, contains links to essential resources, and supports multimedia like screenshots. Additionally, I've produced how-to video lessons for certain programs, which have been well-received."
  6. Budget-related tasks:

    • "Indeed, I'm responsible for procurement in my current department. I ensure that all our product and service requests align with state regulations, right from request to payment."
  7. Administrative duties:

    • "Absolutely. I once developed an Excel workbook specifically to streamline our time tracking and reporting process. As for policies and deadlines, I adhere strictly to departmental policies and have adopted an agile approach, using tools like a Scrum board, to manage tasks effectively."
  8. Adapting to new tools:

    • "I'm always keen to learn and adapt to new tools and methodologies. While I pick up new tools swiftly and often train others, I also use my experience to identify potential areas of improvement. If I feel a different tool or method could enhance our productivity, I'd certainly present a case for it, but always with the organization's best interests in mind."
  9. Communication skills:

    • "I frequently interact with non-technical professionals in my current role. This has honed my ability to translate technical concepts, like metadata or unique keys, into more accessible language. Whether it's advocating for the transition from Excel to SQL or explaining the benefits of SharePoint, I ensure my communication is clear and relatable."

Remember, interviews are as much about demonstrating your experience and skills as they are about showcasing your ability to communicate effectively and fit into the company's culture. Your revised answers give a clear and confident picture of your capabilities while also highlighting your adaptability and willingness to collaborate. Good luck with your interview!

USER

How do I tactfully ask about when they will make a decision? I really want to know how long to wait.

ASSISTANT

Absolutely, it's natural to be eager to know when a decision will be made, especially when you're excited about a potential role. Asking about the timeline for a decision is common and expected. The key is to ask in a manner that communicates your enthusiasm for the position without seeming impatient. Here are some tactful ways you can frame this question:

  1. Express Enthusiasm First:

    • "I'm really excited about the opportunity to contribute to [specific aspect of the job/company]. Could you provide some insight into the next steps and the expected timeline for a decision?"
  2. In the Context of Your Availability:

    • "To ensure I manage my calendar and other potential commitments, may I ask about the timeline you're anticipating for making a decision?"
  3. Curiosity about the Process:

    • "I'd love to understand more about the next steps in your hiring process. Do you have an estimated timeline for when you'll be making a decision?"
  4. General Inquiry:

    • "Thank you for taking the time to discuss this position with me. I was wondering, what does the timeline typically look like post-interview in terms of feedback or decisions?"
  5. Direct Approach (still tactful):

    • "I'm very interested in this role and want to ensure I stay proactive. Could you tell me when you anticipate making a decision?"

Remember, it's not just about what you ask but also how you ask. Keep your tone positive and understanding, recognizing that hiring decisions can involve several layers of discussion and consideration. And it's always a good idea to wrap up by thanking them for their time or for considering you, as it shows gratitude and maintains a positive connection.

USER

Can you give me a list of general interview questions usually asked in an interview? Perhaps not technical questions but other areas that they may ask about.

ASSISTANT

Certainly! Here are some general interview questions that are commonly asked:

  1. Introductory Questions:

    • Tell me about yourself.
    • How did you hear about this position?
  2. Experience & Background:

    • Can you explain the gaps in your work history?
    • Describe a challenge you've faced at work and how you dealt with it.
    • How does your previous experience prepare you for this role?
  3. Behavioral/Situational Questions:

    • Describe a time when you had to work with a difficult colleague. How did you handle it?
    • Can you provide an example of a project that did not go as planned and how you managed it?
    • Describe a situation where you went above and beyond for a customer or colleague.
  4. Motivational Questions:

    • Why do you want this job?
    • Why should we hire you?
    • Where do you see yourself in 5 years?
  5. Cultural Fit & Team Dynamics:

    • What kind of work environment do you thrive in?
    • Describe a time when you disagreed with a team member. How did you resolve it?
    • How do you handle feedback or criticism?
  6. Work Ethics & Problem Solving:

    • Describe a time when you had to handle a high-pressure situation.
    • How do you prioritize your tasks when faced with multiple deadlines?
    • Explain a situation where you had to solve a difficult problem. What did you do?
  7. Questions About the Company/Role:

    • What do you know about our company?
    • What interests you about this role?
    • Do you have any concerns about the job or the company?
  8. Questions on Adaptability & Growth:

    • How do you handle change in the workplace?
    • Can you describe a time when you had to learn a new tool or technology? How did you approach it?
    • How do you ensure continuous professional growth?
  9. Personal Qualities & Characteristics:

    • How would your previous coworkers describe you?
    • What are your greatest strengths and weaknesses?
    • What are you most proud of in your career?
  10. Closing Questions:

  • Do you have any questions for us?
  • What are your salary expectations?
  • When would you be available to start?

Remember, while it's beneficial to prepare for these questions, it's also essential to remain genuine in your responses. Interviewers appreciate authenticity, and rehearsed answers can sometimes come across as insincere. Use these questions as a guide to reflect on your experiences and formulate your unique responses.

USER

I'd like you to act as a job coach and help me flesh out some of the questions you provided. Help me figure out how to answer these questions. Let's start with the simple one "Tell me about yourself." How should I answer this?

ABOUT ME

Certainly! "Tell me about yourself" is one of the most common introductory questions in an interview, and it's your chance to provide a concise summary of your professional journey, highlighting key experiences, skills, and attributes that make you suitable for the job. Here's a general structure that you can follow, along with some guiding points:

1. Start with your current or most recent role:

  • Job title, responsibilities, and achievements.
  • Emphasize any skills or tasks you've handled that align with the new job's requirements.

2. Highlight past experiences:

  • Briefly touch on relevant past roles.
  • Share significant achievements or unique challenges you've overcome.
  • Mention any transitions in your career and the reasons for them (e.g., pursuing a new challenge, a growing interest in a different aspect of your field).

3. Discuss education and certifications:

  • Where you studied, what you studied, and any relevant honors or extracurriculars.
  • Additional certifications or courses that have helped you in your professional journey.

4. Share a bit about your professional interests and aspirations:

  • This can be related to the industry, a particular skill you're passionate about, or your broader career goals.

5. Wrap up with personal attributes or soft skills:

  • Discuss attributes that make you a good fit for the role and the company culture.
  • This can include teamwork, adaptability, leadership, or any other soft skill you deem relevant.

Example Response:

"I'm currently a [Your Current Role] at [Your Current Company], where I've been for the past [X years]. In this role, I've had the chance to [a significant achievement or responsibility, e.g., "optimize our database systems and lead a small team on various projects"]. Before that, I worked at [Previous Company], where I [Brief overview of significant tasks or achievements]. I earned my degree in [Your Degree] from [Your University], and I've also taken additional courses in [Specific Courses/Certifications relevant to the job]. Professionally, I'm very passionate about [Specific Interest, e.g., "finding efficient solutions to data management challenges"], and I'm eager to bring that passion to a role like this. On a personal note, I pride myself on being [Specific Attribute, e.g., "adaptable and a great team player"], which I believe aligns well with this position and the company's values."

I'm currently at Dept of State Hospitals - Napa, where I've been for the past 10 years. In this role I've had the chance to work a lot with Visual Basic, Excel and SQL to create reports that track our patients treatment. Before that I worked at the county in Procurement and helped procure both products and services. I earned my degree in Healthcare Administration from UOP. With 18 additional units in IT where I learned programming, networking and systems admin. Professionally I"m very passionate about analyzing data and helping people understand issues better with data and presenting solutions in a meaningful way. On a personal note, I pride myself on being very reliable.

Remember to tailor this structure to your experiences and the specific job you're applying for. It's essential to strike a balance between providing relevant details and keeping your answer concise and engaging.

To automate the process of moving files from a source directory to subdirectories based on the first letter of the last name, you can use a script. Here's a Bash script that should help you accomplish this task:

#!/bin/bash

# Source directory where the patient files are located
src_dir="/path/to/source_directory"

# Destination directory where subdirectories will be created
dest_dir="/path/to/destination_directory"

# Loop through each file in the source directory
for file in "$src_dir"/*; do
    # Check if it's a regular file
    if [[ -f "$file" ]]; then
        # Extract the last name from the file name
        last_name=$(basename "$file" | cut -d ',' -f 1 | tr -d '[:space:]')

        # Get the first letter of the last name
        first_letter="${last_name:0:1}"

        # Create the subdirectory if it doesn't exist
        sub_dir="$dest_dir/$first_letter"
        mkdir -p "$sub_dir"

        # Move the file to the corresponding subdirectory
        mv "$file" "$sub_dir/"
    fi
done

Here's how this script works:

  1. Replace /path/to/source_directory with the path to the directory where your patient files are located.

  2. Replace /path/to/destination_directory with the path to the directory where you want to move the files into subdirectories based on the first letter of the last name.

  3. The script loops through each file in the source directory.

  4. For each file, it extracts the last name by splitting the file name using a comma as a delimiter and removing any spaces.

  5. It then extracts the first letter of the last name.

  6. It creates a subdirectory in the destination directory with the name of the first letter if it doesn't already exist using mkdir -p.

  7. Finally, it moves the file to the corresponding subdirectory.

Make sure to save this script to a file (e.g., move_files.sh), make it executable using chmod +x move_files.sh, and then run it. It will process all files in the source directory and move them to the appropriate subdirectories in the destination directory based on the first letter of the last name.

Sub CreateDirectory()
Dim rootPath As String
Dim dirPath As String
Dim fullPath As String
Dim selectedRange As Range
' Ask for the root directory path
On Error Resume Next
Set selectedRange = Application.InputBox("Select a cell for the root directory path:", Type:=8)
On Error GoTo 0
If selectedRange Is Nothing Then Exit Sub
rootPath = selectedRange.Value
If Len(Dir(rootPath, vbDirectory)) = 0 Then
MsgBox "The specified root directory does not exist.", vbCritical
Exit Sub
End If
Do
' Ask for the directory path to create
On Error Resume Next
Set selectedRange = Application.InputBox("Select a cell for the directory path to create:", Type:=8)
On Error GoTo 0
If selectedRange Is Nothing Then Exit Do
dirPath = selectedRange.Value
fullPath = rootPath & "\" & dirPath
If Len(Dir(fullPath, vbDirectory)) = 0 Then
MkDir fullPath
MsgBox "Directory created: " & fullPath, vbInformation
Else
MsgBox "Path already exists: " & fullPath, vbExclamation
End If
Loop
End Sub
# Before we can delete, move, or copy things...we need things! It's time to get some more practice using `touch` and `mkdir`
#
# Please create a new directory somewhere on your machine called `Bootcamp`. Inside of it, create the the folders and files indicated below:
# - Sadly `Edgar` had to drop out of the course. Delete the `Edgar.txt` file in `FallCohort`
# - This means we now have space in our Fall Cohort to move someone off of the waitlist. Please move `Netta.txt` from the `Waitlist` folder into the `FallCohort` folder.
# - Please delete the `Waitlist` folder and its contents
# - It turns out that I misspelled Sara. She spells her name "Sarah" with an "h" at the end. Please rename the `Sara.txt` file to `Sarah.txt`
# - Unfortunately Italo is having a bit of a personal emergency, and he would like to move to our WinterCohort. Please move the `Italo.txt` file from `FallCohort` to the `WinterCohort` folder
# - Oh no, our entire Winter Cohort had to be cancelled because of a worldwide pandemic :( We decided to bump all of the scheduled winter students to spring. In the `Bootcamp` directory create a copy of the `WinterCohort` folder called `SpringCohort`
# - Please rename the WinterCohort folder to `WinterCohortCANCELLED`
# - Oh no! We're going out of business. Please delete the entire `Bootcamp` directory 😢
# Before we can delete, move, or copy things...we need things! It's time to get some more practice using `touch` and `mkdir`
#
# Please create a new directory somewhere on your machine called `Bootcamp`. Inside of it, create the the folders and files indicated below:
mkdir Bootcamp
cd Bootcamp
mkdir FallCohort WinterCohort
cd FallCohort
touch Italo.txt
touch Edgar.txt
touch Linus.txt
touch Sara.txt
touch Silvio.txt
mkdir Waitlist
cd Waitlist
touch Hanna.txt
touch Haris.txt
touch Netta.txt
cd ..
cd WinterCohort
touch Santiago.txt
touch Iris.txt
touch Naomi.txt
cd ..
tree
# .
# ├── FallCohort
# │ ├── Edgar.txt
# │ ├── Iris.txt
# │ ├── Italo.txt
# │ ├── Linus.txt
# │ ├── Naomi.txt
# │ ├── Santiago.txt
# │ ├── Sara.txt
# │ ├── Silvio.txt
# │ └── Waitlist
# │ ├── Hanna.txt
# │ ├── Haris.txt
# │ └── Netta.txt
# └── WinterCohort
#
# Note some files need to be moved
cd FallCohort
mv Santiago.txt Iris.txt Naomi.txt ~/repos/3998050/Bootcamp/WinterCohort/
tree
# ▶ tree
# .
# ├── FallCohort
# │ ├── Edgar.txt
# │ ├── Italo.txt
# │ ├── Linus.txt
# │ ├── Sara.txt
# │ ├── Silvio.txt
# │ └── Waitlist
# │ ├── Hanna.txt
# │ ├── Haris.txt
# │ └── Netta.txt
# └── WinterCohort
# ├── Iris.txt
# ├── Naomi.txt
# └── Santiago.txt
# Sadly Edgar had to drop out of the course. Delete the Edgar.txt file in FallCohort
rm FallCohort/Edgar.txt
tree
# This means we now have space in our Fall Cohort to move someone off of the waitlist. Please move Netta.txt from the Waitlist folder into the FallCohort folder.
clear
mv FallCohort/Waitlist/Netta.txt FallCohort/
tree
# ▶ tree
# .
# ├── FallCohort
# │ ├── Italo.txt
# │ ├── Linus.txt
# │ ├── Netta.txt
# │ ├── Sara.txt
# │ ├── Silvio.txt
# │ └── Waitlist
# │ ├── Hanna.txt
# │ └── Haris.txt
# └── WinterCohort
# ├── Iris.txt
# ├── Naomi.txt
# └── Santiago.txt
#
# log_file.py - Version 1.4.0
import os
import logging
from datetime import datetime
import xlwings as xw
# Configure basic logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
class FileProcessor:
"""
A class to process files and log their details in an Excel sheet. It tracks the duration files
remain in a specified directory and updates this information in the Excel sheet.
Parameters:
- approved_directory: Directory to scan for files.
- file_extensions: List of file extensions to consider.
- workbook_path: Full path to the Excel workbook.
- workbook_name: Name of the Excel workbook.
- sheet_name: Name of the sheet in the workbook where data is logged.
"""
def __init__(self, approved_directory, file_extensions, workbook_path, workbook_name, sheet_name):
self.approved_directory = approved_directory
self.file_extensions = file_extensions
self.workbook = xw.Book(workbook_path)
self.sheet = self.workbook.sheets[sheet_name]
def get_last_row_of_table(self, table_name):
# Get the last row number of the specified table in Excel
try:
table = self.sheet.api.ListObjects(table_name)
return table.DataBodyRange.Rows.Count + table.DataBodyRange.Row if table and table.DataBodyRange else 0
except Exception as e:
logger.error(f'Error in getting last row of table "{table_name}": {e}')
return None
def find_files(self):
# Find and yield file paths in the approved_directory with specified extensions
logger.info(f'Searching for files in {self.approved_directory} with extensions: {self.file_extensions}')
for root, _, files in os.walk(self.approved_directory):
for file in files:
if file.split('.')[-1].lower() in self.file_extensions and '~' not in file:
yield os.path.join(root, file)
def open_workbook(self):
# Open the Excel workbook and return the sheet object
logger.info(f'Opening Excel workbook at path: {self.workbook.fullname}')
return self.workbook.sheets[self.sheet_name]
def read_existing_records(self, sheet):
# Read existing records from the Excel sheet and map them by filename
records = {}
try:
table = sheet.api.ListObjects('FileLogTable')
if table.DataBodyRange:
for row in table.DataBodyRange.Rows:
filename = row.Cells(1, 3).Value # Assuming filename is in the third column
if filename:
records[filename] = [cell.Value for cell in row.Cells]
except Exception as e:
logger.error(f'Error reading existing records: {e}')
return records
def write_records(self, sheet, records):
# Write updated records to the Excel sheet
try:
next_row = self.get_last_row_of_table('FileLogTable') + 1
for record in records.values():
row_range = f'A{next_row}:{chr(64 + len(record))}{next_row}'
sheet.range(row_range).value = record
next_row += 1
table = sheet.api.ListObjects('FileLogTable')
table.Resize(table.Range.Resize[next_row - 1])
except Exception as e:
logger.error(f'Error writing records to the Excel sheet : {e}')
def process_files(self):
# Main method to process files and update records
sheet = self.open_workbook()
current_records = self.read_existing_records(sheet)
for file_path in self.find_files():
parts = file_path.rsplit('\\', 2)
subfolder, filename = (parts[-2], parts[-1]) if len(parts) >= 3 else ('', parts[-1])
record = current_records.get(filename)
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
duration = self.calculate_duration(record[0]) if record else '0'
current_records[filename] = [timestamp, subfolder, filename, 'TRUE' if not record else 'FALSE', duration]
self.write_records(sheet, current_records)
logger.info("File processing completed.")
def calculate_duration(self, timestamp):
# Calculate duration since the timestamp
start_time = datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S")
return str(datetime.now() - start_time)
if __name__ == "__main__":
# Sample configuration for standalone execution
config = {
'approved_directory': '\\\\Mhnfs1\\cdo\\Court Reports\\Review\\Approved- FS USE ONLY\\',
'file_extensions': ['docx', 'doc'],
'workbook_path': 'C:\\Users\\blundeen\\AppData\\Local\\Apps\\repos\\file_timestamp\\log_file\\log_file.xlsm',
'workbook_name': "log_file.xlsm",
'sheet_name': 'file_log'
}
processor = FileProcessor(**config)
processor.process_files()
let
Source_Named_Range = Excel.CurrentWorkbook(){[Name = "pivot_myData"]}[Content],
Removed_top_3_rows = Table.Skip(Source_Named_Range, 2),
Removed_other_columns = Table.SelectColumns(
Removed_top_3_rows,
{
"Column1",
"Column2",
"Column3",
"Column4"
}
),
First_row_headers = Table.PromoteHeaders(Removed_other_columns, [PromoteAllScalars = true]),
visit_as_date = Table.TransformColumnTypes(
First_row_headers,
{
{"patient_number", type text},
{"full_name", type text},
{"provider", type text},
{"most_recent_visit", type date}
}
),
Remove_blank_visit = Table.SelectRows(
visit_as_date, each ([most_recent_visit] <> null) and ([patient_number] <> "(blank)")
),
// Sort most recent visit descending order & place inside Table.Buffer
Buffer_table = Table.Buffer(Table.Sort(Remove_blank_visit, {{"most_recent_visit", Order.Descending}})),
Remove_duplicate_name_id = Table.Distinct(Buffer_table, {"patient_number", "full_name"}),
Sort_name_asc = Table.Sort(Remove_duplicate_name_id, {{"full_name", Order.Ascending}})
in
Sort_name_asc
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListBox.au3>
#include <GuiStatusBar.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
; #INDEX# =======================================================================================================================
; Title .........: startup_menu.au3
; AutoIt Version : 3.3.14.5
; Language ......: English
; Description ...: A GUI script for selecting and launching applications and folders at startup.
; Author(s) .....: lundeen-bryan
; Precondition(s): Must have an INI file in the ScriptDir named startup_menu.ini (see instructions file)
; ===============================================================================================================================
; #CURRENT# =====================================================================================================================
; Terminate
; HandleSelectedItems
; ExecuteItemAction
; LoadAppsFromINIFile
; StartAppAndWaitWithRunWait
; WaitForWindowAndActivate
; OpenAndResizeFolder
; ===============================================================================================================================
; #INTERNAL_USE_ONLY#============================================================================================================
; [List any internal functions or helpers here if applicable]
; ===============================================================================================================================
; #FUNCTION# ====================================================================================================================
; Author ........: lundeen-bryan
; Modified.......: [List any modifications or contributors if applicable]
; ===============================================================================================================================
#Region---------Hotkeys
HotKeySet("{ESC}", "Terminate")
#EndRegion
#Region ### START Koda GUI section ### Form=C:\Users\lunde\repos\AutoIT\startup_menu.kxf
$startup_menu = GUICreate("Bryan's Startup Menu", 583, 296, 192, 124)
GUISetFont(12, 400, 0, "Lucida Fax")
GUISetBkColor(0xFFFFFF)
$Group1 = GUICtrlCreateGroup("Choose Which Options Below You Want To Start:", 24, 16, 441, 241)
GUICtrlSetColor(-1, 0x464646)
$Apps_List = GUICtrlCreateList("", 40, 56, 409, 186, BitOR($LBS_STANDARD, $LBS_MULTIPLESEL))
GUICtrlSetData(-1, "") ; Clear any existing data
; Load data from INI file to the Listbox
LoadAppsFromINIFile()
GUICtrlCreateGroup("", -99, -99, 1, 1)
$OK_Button = GUICtrlCreateButton("OK", 496, 40, 75, 25)
GUICtrlSetColor(-1, 0x464646)
GUICtrlSetCursor(-1, 0)
$StatusBar1 = _GUICtrlStatusBar_Create($startup_menu)
Dim $StatusBar1_PartsWidth[3] = [10, 360, -1]
_GUICtrlStatusBar_SetParts($StatusBar1, $StatusBar1_PartsWidth)
_GUICtrlStatusBar_SetText($StatusBar1, "", 0)
_GUICtrlStatusBar_SetText($StatusBar1, "Status", 1)
_GUICtrlStatusBar_SetText($StatusBar1, "Time", 2)
_GUICtrlStatusBar_SetBkColor($StatusBar1, 0xF9F4EE)
_GUICtrlStatusBar_SetMinHeight($StatusBar1, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ## #
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $OK_Button
ConsoleWrite("Ok button was pressed..." & @CRLF)
HandleSelectedItems()
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Func Terminate()
Exit
EndFunc ;==>Terminate
Func HandleSelectedItems()
ConsoleWrite("Running HandleSelectedItems..." & @CRLF)
Local $selectedItems = ""
For $i = 0 To _GUICtrlListBox_GetCount($Apps_List) - 1
If _GUICtrlListBox_GetSel($Apps_List, $i) Then
$selectedItem = _GUICtrlListBox_GetText($Apps_List, $i)
$selectedItems &= $selectedItem & @CRLF
ConsoleWrite("The selected item is a " & $selectedItem & @CRLF)
ExecuteItemAction($selectedItem)
EndIf
Next
If $selectedItems <> "" Then
ConsoleWrite("You selected the following items:" & $selectedItems & @CRLF)
Else
ConsoleWrite("No items selected in the Listbox." & @CRLF)
EndIf
TrayTip("Finished!", "Finished Starup Items", 3)
Sleep(3000)
Exit
EndFunc
Func ExecuteItemAction($item)
ConsoleWrite("Running ExecuteItemAction..." & @CRLF)
Local $iniFile = @ScriptDir & "\startup_menu.ini"
Local $itemType = IniRead($iniFile, "TYPE", $item, "")
Local $itemPosition = IniRead($iniFile, "POSITION", $item, "")
If $itemType = "app" Then
StartAppAndWaitWithRunWait($item, $itemPosition = "show")
ConsoleWrite($item & " is an app." & @CRLF)
ElseIf $itemType = "folder" Then
OpenAndResizeFolder($item, $itemPosition)
ConsoleWrite($item & " is folder." & @CRLF)
Else
ConsoleWrite("The type of '" & $item & "' is not recognized.")
EndIf
EndFunc
Func LoadAppsFromINIFile()
Local $iniFile = @ScriptDir & "\startup_menu.ini"
Local $appSettings = IniReadSection($iniFile, "PATH")
If @error Then
ConsoleWrite("Failed to read settings from INI file.")
Return
EndIf
; Populate the Listbox with pseudonames
For $i = 1 To $appSettings[0][0]
GUICtrlSetData($Apps_List, $appSettings[$i][0])
Next
EndFunc
Func StartAppAndWaitWithRunWait($appKey, $showApp = False)
ConsoleWrite("Running StartAppAndWaitWithRunWait..." & @CRLF)
; Read the path to the application from the INI file
Local $iniFile = @ScriptDir & "\startup_menu.ini"
Local $appPath = IniRead($iniFile, "PATH", $appKey, "")
; Check if the path is empty or not found in the INI file
If $appPath = "" Then
ConsoleWrite("Application path not found for key: " & $appKey & @CRLF)
Return
EndIf
Local $flags = @SW_MINIMIZE
If $showApp Then
$flags = @SW_MAXIMIZE
EndIf
;~ Parameters are: `Run ( "program" [, "workingdir" [, show_flag [, opt_flag]]] )`
Local $result = Run($appPath, @WorkingDir, $flags, $STDOUT_CHILD + $STDERR_CHILD)
; Check the result of Run for errors
If $result <> 0 Then
; Application started successfully and exited with code 0
ConsoleWrite("The application " & $appKey & " has completed successfully." & @CRLF)
ElseIf @error Then
; RunWait encountered an error
ConsoleWrite("Error while starting the application (" & $appKey & "): " & @error & @CRLF)
Else
; Application exited with a non-zero exit code
ConsoleWrite("The application (" & $appKey & ") started successfully, but it encountered an error or issue during its execution." & @CRLF)
EndIf
Sleep(2000) ;~ wait a couple seconds for app to load
EndFunc
Func OpenAndResizeFolder($folderKey, $side)
ConsoleWrite("Running OpenAndResizeFolder..." & @CRLF)
; Read the path and screen number for the folder from the INI file
Local $iniFile = @ScriptDir & "\startup_menu.ini"
Local $folderPath = IniRead($iniFile, "PATH", $folderKey, "")
Local $screenNum = IniRead($iniFile, "SCREEN", $folderKey, 1) ; Default to screen 1 if not specified
; Check if the path is empty or not found in the INI file
If $folderPath = "" Then
ConsoleWrite("Folder path not found for key: " & $folderKey & @CRLF)
Return
EndIf
; Open the specified folder/app
ShellExecute($folderPath)
; Wait for a moment to allow the window to open
Sleep(1000)
; Activate the window
WinActivate("[ACTIVE]")
; Position the window based on the screen number
If $screenNum = 2 Then
; Move to the second screen
Send("#+{RIGHT}") ; Windows key + Shift + Right Arrow
EndIf
; Adjust position on the screen based on the $side parameter
If $side = "RIGHT" Then
Send("#{RIGHT}") ; Windows key + Right Arrow
Else
Send("#{LEFT}") ; Windows key + Left Arrow
EndIf
ConsoleWrite("Window for '" & $folderKey & "' positioned on screen " & $screenNum & " at " & $side & "." & @CRLF)
EndFunc
<!DOCTYPE html>
<html>
<head>
<title>Startup Menu Configuration</title>
</head>
<body>
<h2>Instructions for Configuring the <code>startup_menu.ini</code> File</h2>
<h3>Overview</h3>
<p>The <code>startup_menu.ini</code> file is used to configure the AutoIt script, determining which applications and folders are listed in the program, how they are handled, and their display preferences.</p>
<h3>Structure of the INI File</h3>
<p>The INI file is divided into three sections:</p>
<ol>
<li><strong>[PATH]</strong> - Specifies the paths to applications and folders.</li>
<li><strong>[TYPE]</strong> - Defines whether each item is an 'app' or a 'folder'.</li>
<li><strong>[POSITION]</strong> - Indicates the position for folders ('left' or 'right') and the state for apps ('show' or 'hide').</li>
</ol>
<h3>Editing Instructions</h3>
<p><strong>1. Open the INI File:</strong> Use a text editor like Notepad to open the <code>startup_menu.ini</code> file.</p>
<p><strong>2. [PATH] Section:</strong></p>
<ul>
<li>Format: <code>&lt;name&gt;=&lt;path&gt;</code></li>
<li>Add each application or folder you want to include in the list.</li>
<li>Example:
<pre><code>[PATH]
typertask=C:\Path\To\TypeTask.exe
documents=C:\Users\YourName\Documents</code></pre>
</li>
<li>Replace the example paths with the actual paths to your applications and folders.</li>
</ul>
<p><strong>3. [TYPE] Section:</strong></p>
<ul>
<li>Format: <code>&lt;name&gt;=app</code> or <code>&lt;name&gt;=folder</code></li>
<li>Specify if the item is an application (app) or a folder (folder).</li>
<li>Example:
<pre><code>[TYPE]
typertask=app
documents=folder</code></pre>
</li>
<li>Use the same <code>&lt;name&gt;</code> as in the [PATH] section.</li>
</ul>
<p><strong>4. [POSITION] Section:</strong></p>
<ul>
<li>For Apps: Format: <code>&lt;name&gt;=show</code> or <code>&lt;name&gt;=hide</code></li>
<li>For Folders: Format: <code>&lt;name&gt;=left</code> or <code>&lt;name&gt;=right</code></li>
<li>Specify the position for folders (left or right) and the visibility for apps (show or hide).</li>
<li>Example:
<pre><code>[POSITION]
documents=left
typertask=hide</code></pre>
</li>
<li>Again, use the same <code>&lt;name&gt;</code> as in the [PATH] section.</li>
</ul>
<p><strong>5. Save the INI File:</strong> After making changes, save the file.</p>
<h3>Additional Tips</h3>
<ul>
<li>Ensure the paths are correct and accessible on your system.</li>
<li>The names used across the sections must be consistent.</li>
<li>Paths to applications should be to the executable files (.exe).</li>
<li>For folders, use standard file paths.</li>
</ul>
<h3>Testing</h3>
<p>After configuring the INI file, run the AutoIt script to test your settings. Ensure that the applications and folders appear in the list and behave as expected when selected.</p>
<h3>Example INI File</h3>
<pre><code>
[PATH]
typertask=C:\Path\To\TypeTask.exe
documents=C:\Users\YourName\Documents
downloads=C:\Users\YourName\Downloads
[TYPE]
typertask=app
documents=folder
downloads=folder
[POSITION]
typertask=hide
documents=left
downloads=right
</code></pre>
<p>This example shows how the INI file should be structured. Replace the paths and names with those relevant to your setup.</p>
</body>
</html>
This file has been truncated, but you can view the full file.
{"created_by":"Tampermonkey","version":"1","scripts":[{"name":"Redirect Userscripts.org to Userscripts-MIRROR.org","options":{"check_for_updates":true,"comment":null,"compat_foreach":false,"compat_metadata":false,"compat_powerful_this":null,"compat_wrappedjsobject":false,"compatopts_for_requires":true,"noframes":null,"override":{"merge_connects":true,"merge_excludes":true,"merge_includes":true,"merge_matches":true,"orig_connects":[],"orig_excludes":["http://userscripts.org/*","https://userscripts.org/*","http://userscripts.org:8080/*","https://userscripts.org:8080/*"],"orig_includes":["http://*.*","https://*.*"],"orig_matches":[],"orig_noframes":null,"orig_run_at":"document-idle","use_blockers":[],"use_connects":[],"use_excludes":[],"use_includes":[],"use_matches":[]},"run_at":null,"sandbox":null,"tab_types":null,"unwrap":null,"user_modified":null},"storage":{"ts":1691113794635,"data":{}},"enabled":false,"position":1,"file_url":"http://userscripts-mirror.org/scripts/source/487275.user.js","uuid":"513d8eb3-d584-4ffc-82da-6a7265d238ca","source":"Ly8gPT1Vc2VyU2NyaXB0PT0KLy8gQG5hbWUgICAgICAgIFJlZGlyZWN0IFVzZXJzY3JpcHRzLm9yZyB0byBVc2Vyc2NyaXB0cy1NSVJST1Iub3JnCi8vIEBuYW1lc3BhY2UgICB1c28ydXNvbQovLyBAZGVzY3JpcHRpb24gT24gYW55IHdlYiBwYWdlIGl0IHdpbGwgY2hlY2sgaWYgdGhlIGNsaWNrZWQgbGlua3MgZ29lcyB0byB1c2Vyc2NyaXB0cy5vcmcuIElmIHNvLCB0aGUgbGluayB3aWxsIGJlIHJld3JpdHRlbiB0byBwb2ludCB0byB1c2Vyc2NyaXB0cy1taXJyb3Iub3JnCi8vIEBpbmNsdWRlICAgICBodHRwOi8vKi4qCi8vIEBpbmNsdWRlICAgICBodHRwczovLyouKgovLyBAZXhjbHVkZSAgICAgaHR0cDovL3VzZXJzY3JpcHRzLm9yZy8qCi8vIEBleGNsdWRlICAgICBodHRwczovL3VzZXJzY3JpcHRzLm9yZy8qCi8vIEBleGNsdWRlICAgICBodHRwOi8vdXNlcnNjcmlwdHMub3JnOjgwODAvKgovLyBAZXhjbHVkZSAgICAgaHR0cHM6Ly91c2Vyc2NyaXB0cy5vcmc6ODA4MC8qCi8vIEB2ZXJzaW9uICAgICAxLjIKLy8gQGdyYW50ICAgICAgIG5vbmUKLy8gPT0vVXNlclNjcmlwdD09CgovLyBUaGlzIGlzIGEgc2xpZ2h0bHkgYnJ1dGUgZm9yY2Ugc29sdXRpb24sIGJ1dCB0aGVyZSBpcyBubyBvdGhlciB3YXkgdG8gZG8gaXQgdXNpbmcgb25seSBhIHVzZXJzY3JpcHQuIEEgZnVsbC1mbGVkZ2VkIGFkZG9uIG1heSBiZSBjcmVhdGVkIHNvb24uCgpkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGZ1bmN0aW9uKGUpewogICAgdmFyIHRhcmcgPSBlLnRhcmdldCB8fCBlLnNyY0VsZW1lbnQ7CiAgICBpZiAoIHRhcmcgJiYgdGFyZy5ocmVmICYmIHRhcmcuaHJlZi5tYXRjaCgvaHR0cHM/OlwvXC91c2Vyc2NyaXB0cy5vcmcvKSApIHsKICAgICAgICB0YXJnLmhyZWYgPSB0YXJnLmhyZWYucmVwbGFjZSgvaHR0cHM/OlwvXC91c2Vyc2NyaXB0c1wub3JnLywgJ2h0dHA6Ly91c2Vyc2NyaXB0cy1taXJyb3Iub3JnJyk7CiAgICB9Cn0pOwo="},{"name":"Online Document Viewer (pdf,doc,xls,ppt,odt,ods,odp,...)","options":{"check_for_updates":true,"comment":null,"compat_foreach":false,"compat_metadata":false,"compat_powerful_this":null,"compat_wrappedjsobject":false,"compatopts_for_requires":true,"noframes":null,"override":{"merge_connects":true,"merge_excludes":true,"merge_includes":true,"merge_matches":true,"orig_connects":[],"orig_excludes":["/^https?://docs.google.com/.*/"],"orig_includes":["/^https?://.*/"],"orig_matches":[],"orig_noframes":null,"orig_run_at":"document-idle","use_blockers":[],"use_connects":[],"use_excludes":[],"use_includes":[],"use_matches":[]},"run_at":null,"sandbox":null,"tab_types":null,"unwrap":null,"user_modified":null},"storage":{"ts":1691113794635,"data":{}},"enabled":false,"position":2,"file_url":"http://userscripts-mirror.org/scripts/source/72129.user.js","uuid":"53873882-3fc5-42c7-a403-7c7abd6646f8","source":"Ly8gPT1Vc2VyU2NyaXB0PT0KLy8gQG5hbWUgICAgICAgICAgIE9ubGluZSBEb2N1bWVudCBWaWV3ZXIgKHBkZixkb2MseGxzLHBwdCxvZHQsb2RzLG9kcCwuLi4pCi8vIEBuYW1lc3BhY2UgICAgICAKLy8gQGluY2x1ZGUgICAgICAgIC9eaHR0cHM/Oi8vLiovCi8vIEBleGNsdWRlICAgICAgICAvXmh0dHBzPzovL2RvY3MuZ29vZ2xlLmNvbS8uKi8KLy8gQGdyYW50ICAgICAgICAgIG5vbmUKLy8gQHZlcnNpb24gICAgICAgIDEuNgovLyBiYXNlZCBvbiBodHRwczovL3VzZXJzY3JpcHRzLW1pcnJvci5vcmcvc2NyaXB0cy9zaG93LzU5NTU3IGJ5IEtvb25pZXMKLy8gPT0vVXNlclNjcmlwdD09CgooZnVuY3Rpb24oKXsKICAgIHZhciBsID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImEiKTsKICAgIHZhciBpID0gbC5sZW5ndGg7IAogICAgd2hpbGUgKGktLSkgewogICAgICBpZiAobFtpXS5ocmVmLm1hdGNoKC9eaHR0cHM/OihbXj9dK3xbXjpdKylcLihwZGZ8cHN8ZXBzfGRvY3xkb2N4fHhsc3x4bHN4fHBwdHxwcHR4fHBwc3xvZHR8c3h3fHRpZnx0aWZmKSQvaSkpIHsKICAgICAgICB2YXIgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKTsKICAgICAgICBhLmhyZWYgPSAnaHR0cDovL2RvY3MuZ29vZ2xlLmNvbS92aWV3ZXI/dXJsPScgKyBlc2NhcGUobFtpXS5ocmVmKTsKCiAgICAgICAgdmFyIGljbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImltZyIpOwogICAgICAgIGljby5zcmMgPSAiaHR0cDovL3d3dy5nb29nbGUuY29tL2Zhdmljb24uaWNvIjsKICAgICAgICBpY28uc2V0QXR0cmlidXRlKCJzdHlsZSIsICJib3JkZXItc3R5bGU6IG5vbmU7IHZlcnRpY2FsLWFsaWduOiB0ZXh0LWJvdHRvbTsgaGVpZ2h0OiAxZW0iKTsKCiAgICAgICAgYS5hcHBlbmRDaGlsZChpY28pOwoKCQl2YXIgc3BhY2UgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgiICIpOwoKICAgICAgICBsW2ldLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsIGxbaV0ubmV4dFNpYmxpbmcpOwogICAgICAgIGxbaV0ucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc3BhY2UsIGxbaV0ubmV4dFNpYmxpbmcpOwogICAgICB9CiAgICAgIGVsc2UgaWYgKGxbaV0uaHJlZi5tYXRjaCgvXmh0dHBzPzooW14/XSt8W146XSspXC4ob2RzfG9kcHxvZGd8c3hjfHN4aXxzeGQpJC9pKSkgewogICAgICAgIHZhciBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOwogICAgICAgIGEuaHJlZiA9ICdodHRwOi8vdmlld2RvY3NvbmxpbmUuY29tL3ZpZXcucGhwP3VybD0nICsgbFtpXS5ocmVmOwoJCQogICAgICAgIHZhciBpY28gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpbWciKTsKICAgICAgICBpY28uc3JjID0gImh0dHA6Ly92aWV3ZG9jc29ubGluZS5jb20vZmF2aWNvbi5pY28iOwogICAgICAgIGljby5zZXRBdHRyaWJ1dGUoInN0eWxlIiwgImJvcmRlci1zdHlsZTogbm9uZTsgdmVydGljYWwtYWxpZ246IHRleHQtYm90dG9tOyBoZWlnaHQ6IDFlbSIpOwoJCQogICAgICAgIGEuYXBwZW5kQ2hpbGQoaWNvKTsKCQkKCQl2YXIgc3BhY2UgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgiICIpOwoKICAgICAgICBsW2ldLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsIGxbaV0ubmV4dFNpYmxpbmcpOwogICAgICAgIGxbaV0ucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc3BhY2UsIGxbaV0ubmV4dFNpYmxpbmcpOwogICAgICB9CiAgICAgIGVsc2UgaWYgKGxbaV0uaHJlZi5tYXRjaCgvXmh0dHBzPzooW14/XSt8W146XSspXC4oYm1wfHBwbXx4cG0pJC9pKSkgewogICAgICAgIHZhciBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOwogICAgICAgIGEuaHJlZiA9ICdodHRwOi8vdnV6aXQuY29tL3ZpZXc/dXJsPScgKyBlc2NhcGUobFtpXS5ocmVmKTsKCQkKICAgICAgICB2YXIgaWNvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiaW1nIik7CiAgICAgICAgaWNvLnNyYyA9ICJodHRwOi8vdnV6aXQuY29tL2Zhdmljb24uaWNvIjsKICAgICAgICBpY28uc2V0QXR0cmlidXRlKCJzdHlsZSIsICJib3JkZXItc3R5bGU6IG5vbmU7IHZlcnRpY2FsLWFsaWduOiB0ZXh0LWJvdHRvbTsgaGVpZ2h0OiAxZW0iKTsKCQkKICAgICAgICBhLmFwcGVuZENoaWxkKGljbyk7CgkJCgkJdmFyIHNwYWNlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIiAiKTsKCiAgICAgICAgbFtpXS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShhLCBsW2ldLm5leHRTaWJsaW5nKTsKICAgICAgICBsW2ldLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHNwYWNlLCBsW2ldLm5leHRTaWJsaW5nKTsKICAgICAgfQogICAgfQp9KSgpOwo="},{"name":"Google to YouTube Search","options":{"check_for_updates":true,"comment":null,"compat_foreach":false,"compat_metadata":false,"compat_powerful_this":null,"compat_wrappedjsobject":false,"compatopts_for_requires":true,"noframes":null,"override":{"merge_connects":true,"merge_excludes":true,"merge_includes":true,"merge_matches":true,"orig_connects":[],"orig_excludes":[],"orig_includes":["https://www.google.*/search*","https://potato.net/*"],"orig_matches":[],"orig_noframes":null,"orig_run_at":"document-start","use_blockers":[],"use_connects":[],"use_excludes":[],"use_includes":[],"use_matches":[]},"run_at":null,"sandbox":null,"tab_types":null,"unwrap":null,"user_modified":null},"storage":{"ts":1703890780667,"data":{"_MonkeyConfig_Configure_cfg":"s{\"YouTube\":true,\"Reddit\":true,\"Github\":true}"}},"enabled":true,"position":3,"file_url":"https://update.greasyfork.org/scripts/19256/Google%20to%20YouTube%20Search.user.js","uuid":"b02c2a1a-1cd1-4de8-afd5-55f96c2e22a1","source":"Ly8gPT1Vc2VyU2NyaXB0PT0KLy8gQG5hbWUgICAgICAgICAgICAgICBHb29nbGUgdG8gWW91VHViZSBTZWFyY2gKLy8gQG5hbWVzcGFjZSAgICAgICAgICBodHRwczovL2dyZWFzeWZvcmsub3JnL2VuL3VzZXJzLzEwMTE4LWRyaG91c2UKLy8gQHZlcnNpb24gICAgICAgICAgICA2LjUKLy8gQGRlc2NyaXB0aW9uICAgICAgICBVc2UgeW91ciBHb29nbGUgU2VhcmNoIHRlcm1zIHRvIHNlYXJjaCBZb3VUdWJlIGJ5IGNsaWNraW5nIGEgbmV3IFlvdVR1YmUgbGluayBhZGRlZCB0byB5b3VyIEdvb2dsZSBTZWFyY2ggcGFnZS4KLy8gQHJ1bi1hdCAgICAgICAgICAgICBkb2N1bWVudC1zdGFydAovLyBAaW5jbHVkZSAgICAgICAgICAgIGh0dHBzOi8vd3d3Lmdvb2dsZS4qL3NlYXJjaCoKLy8gQGluY2x1ZGUgICAgICAgICAgICBodHRwczovL3BvdGF0by5uZXQvKgovLyBAcmVxdWlyZSAgICAgICAgICAgIGh0dHA6Ly9hamF4Lmdvb2dsZWFwaXMuY29tL2FqYXgvbGlicy9qcXVlcnkvMS45LjEvanF1ZXJ5Lm1pbi5qcwovLyBAcmVxdWlyZSAgICAgICAgICAgIGh0dHBzOi8vZ3JlYXN5Zm9yay5vcmcvc2NyaXB0cy80MzkwOTktbW9ua2V5Y29uZmlnLW1vZGVybi1yZWxvYWRlZC9jb2RlL01vbmtleUNvbmZpZyUyME1vZGVybiUyMFJlbG9hZGVkLmpzP3ZlcnNpb249MTAxMjUzOAovLyBAZ3JhbnQgICAgICAgICAgICAgIEdNX2dldFZhbHVlCi8vIEBncmFudCAgICAgICAgICAgICAgR01fc2V0VmFsdWUKLy8gQGdyYW50ICAgICAgICAgICAgICBHTV9hZGRTdHlsZQovLyBAZ3JhbnQgICAgICAgICAgICAgIEdNX2luZm8KLy8gQGdyYW50ICAgICAgICAgICAgICBHTV9yZWdpc3Rlck1lbnVDb21tYW5kCi8vIEBhdXRob3IgICAgICAgICAgICAgZHJob3VzZQovLyBAbGljZW5zZSAgICAgICAgICAgIENDLUJZLU5DLVNBLTQuMAovLyBAaWNvbiAgICAgICAgICAgICAgIGh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vczIvZmF2aWNvbnM/ZG9tYWluPWdvb2dsZS5jb20KLy8gQGRvd25sb2FkVVJMIGh0dHBzOi8vdXBkYXRlLmdyZWFzeWZvcmsub3JnL3NjcmlwdHMvMTkyNTYvR29vZ2xlJTIwdG8lMjBZb3VUdWJlJTIwU2VhcmNoLnVzZXIuanMKLy8gQHVwZGF0ZVVSTCBodHRwczovL3VwZGF0ZS5ncmVhc3lmb3JrLm9yZy9zY3JpcHRzLzE5MjU2L0dvb2dsZSUyMHRvJTIwWW91VHViZSUyMFNlYXJjaC5tZXRhLmpzCi8vID09L1VzZXJTY3JpcHQ9PQovKiBnbG9iYWwgalF1ZXJ5LCBNb25rZXlDb25maWcsICQgKi8KJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24gKCkgewoKICAgIHZhciBjZmcgPSBuZXcgTW9ua2V5Q29uZmlnKHsKICAgICAgICB0aXRsZTogJ0NvbmZpZ3VyZScsCiAgICAgICAgbWVudUNvbW1hbmQ6IHRydWUsCiAgICAgICAgcGFyYW1zOiB7CiAgICAgICAgICAgICdZb3VUdWJlJzogewogICAgICAgICAgICAgICAgdHlwZTogJ2NoZWNrYm94JywKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWUKICAgICAgICAgICAgfSwKICAgICAgICAgICAgJ1JlZGRpdCc6IHsKICAgICAgICAgICAgICAgIHR5cGU6ICdjaGVja2JveCcsCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICdHaXRodWInOiB7CiAgICAgICAgICAgICAgICB0eXBlOiAnY2hlY2tib3gnLAogICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgIH0sCiAgICB9KQoKICAgIGZ1bmN0aW9uIGNyZWF0ZUxpbmsoc2l0ZSwgdXJsLCBxdWVyeSkgewogICAgICAgICQoJzxhIGNsYXNzPSJMYXRwTWMgblBEelQgVDNGb0piIHpJdEFuZCBGT1UxemYiIGlkPSJhYm92ZSIgaHJlZj0iJyArIHVybCArIGVuY29kZVVSSUNvbXBvbmVudChxdWVyeSkgKyAnIj48ZGl2IGNsYXNzPSJHS1M3cyI+PHNwYW4gY2xhc3MgPSJGTUt0VGIgVXFjSXZiIj4nICsgc2l0ZSArICc8L3NwYW4+PC9kaXY+PC9hPicpCiAgICAgICAgICAgIC5pbnNlcnRCZWZvcmUoIiN1ZGRpYV8xIikKICAgICAgICAgICAgLmxhc3QoKTsKICAgIH0KICAgIAogICAgdmFyIGdxdWVyeSA9ICQoInRleHRhcmVhIikudGV4dCgpCiAgICAvLyBjb25zdCBlbGVtZW50TGVuZ3RoID0gJCgiI2NudCA+IGRpdjpudGgtY2hpbGQoOCkiKS5sZW5ndGg7CiAgICBjb25zdCBlbGVtZW50TGVuZ3RoID0gJCgiI2NudCA+IGRpdjpudGgtY2hpbGQoMjApIikubGVuZ3RoOwogICAgY29uc3QgbnRoQ2hpbGRWYWx1ZSA9IGVsZW1lbnRMZW5ndGggPT09IDEgPyA4IDogMTA7CgogICAgaWYgKGNmZy5nZXQoJ0dpdGh1YicpKSB7CiAgICAgICAgY3JlYXRlTGluaygnR2l0aHViJywgJ2h0dHBzOi8vJyskKGxvY2F0aW9uKS5hdHRyKCdob3N0bmFtZScpKycvc2VhcmNoP3E9c2l0ZSUzQWdpdGh1Yi5jb20rJywgZ3F1ZXJ5ICsgJyZ0eXBlPXJlcG9zaXRvcmllcycpOwogICAgfQoKICAgIGlmIChjZmcuZ2V0KCdSZWRkaXQnKSkgewogICAgICAgIGNyZWF0ZUxpbmsoJ1JlZGRpdCcsICdodHRwczovLycrJChsb2NhdGlvbikuYXR0cignaG9zdG5hbWUnKSsnL3NlYXJjaD9xPXNpdGUlM0FyZWRkaXQuY29tKycsIGdxdWVyeSk7CiAgICB9CgogICAgaWYgKGNmZy5nZXQoJ1lvdVR1YmUnKSkgewogICAgICAgIGNyZWF0ZUxpbmsoJ1lvdVR1YmUnLCAnaHR0cHM6Ly93d3cueW91dHViZS5jb20vcmVzdWx0cz9zZWFyY2hfcXVlcnk9JywgZ3F1ZXJ5KTsKICAgIH0KICAgIAp9KTs=","requires":[{"meta":{"name":"jquery.min.js","url":"http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js","ts":1706935757622,"mimetype":"text/javascript"},"source":"LyohIGpRdWVyeSB2MS45LjEgfCAoYykgMjAwNSwgMjAxMiBqUXVlcnkgRm91bmRhdGlvbiwgSW5jLiB8IGpxdWVyeS5vcmcvbGljZW5zZQovL0Agc291cmNlTWFwcGluZ1VSTD1qcXVlcnkubWluLm1hcAoqLyhmdW5jdGlvbihlLHQpe3ZhciBuLHIsaT10eXBlb2YgdCxvPWUuZG9jdW1lbnQsYT1lLmxvY2F0aW9uLHM9ZS5qUXVlcnksdT1lLiQsbD17fSxjPVtdLHA9IjEuOS4xIixmPWMuY29uY2F0LGQ9Yy5wdXNoLGg9Yy5zbGljZSxnPWMuaW5kZXhPZixtPWwudG9TdHJpbmcseT1sLmhhc093blByb3BlcnR5LHY9cC50cmltLGI9ZnVuY3Rpb24oZSx0KXtyZXR1cm4gbmV3IGIuZm4uaW5pdChlLHQscil9LHg9L1srLV0/KD86XGQqXC58KVxkKyg/OltlRV1bKy1dP1xkK3wpLy5zb3VyY2Usdz0vXFMrL2csVD0vXltcc1x1RkVGRlx4QTBdK3xbXHNcdUZFRkZceEEwXSskL2csTj0vXig/Oig8W1x3XFddKz4pW14+XSp8IyhbXHctXSopKSQvLEM9L148KFx3KylccypcLz8+KD86PFwvXDE+fCkkLyxrPS9eW1xdLDp7fVxzXSokLyxFPS8oPzpefDp8LCkoPzpccypcWykrL2csUz0vXFwoPzpbIlxcXC9iZm5ydF18dVtcZGEtZkEtRl17NH0pL2csQT0vIlteIlxcXHJcbl0qInx0cnVlfGZhbHNlfG51bGx8LT8oPzpcZCtcLnwpXGQrKD86W2VFXVsrLV0/XGQrfCkvZyxqPS9eLW1zLS8sRD0vLShbXGRhLXpdKS9naSxMPWZ1bmN0aW9uKGUsdCl7cmV0dXJuIHQudG9VcHBlckNhc2UoKX0sSD1mdW5jdGlvbihlKXsoby5hZGRFdmVudExpc3RlbmVyfHwibG9hZCI9PT1lLnR5cGV8fCJjb21wbGV0ZSI9PT1vLnJlYWR5U3RhdGUpJiYocSgpLGIucmVhZHkoKSl9LHE9ZnVuY3Rpb24oKXtvLmFkZEV2ZW50TGlzdGVuZXI/KG8ucmVtb3ZlRXZlbnRMaXN0ZW5lcigiRE9NQ29udGVudExvYWRlZCIsSCwhMSksZS5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2FkIixILCExKSk6KG8uZGV0YWNoRXZlbnQoIm9ucmVhZHlzdGF0ZWNoYW5nZSIsSCksZS5kZXRhY2hFdmVudCgib25sb2FkIixIKSl9O2IuZm49Yi5wcm90b3R5cGU9e2pxdWVyeTpwLGNvbnN0cnVjdG9yOmIsaW5pdDpmdW5jdGlvbihlLG4scil7dmFyIGksYTtpZighZSlyZXR1cm4gdGhpcztpZigic3RyaW5nIj09dHlwZW9mIGUpe2lmKGk9IjwiPT09ZS5jaGFyQXQoMCkmJiI+Ij09PWUuY2hhckF0KGUubGVuZ3RoLTEpJiZlLmxlbmd0aD49Mz9bbnVsbCxlLG51bGxdOk4uZXhlYyhlKSwhaXx8IWlbMV0mJm4pcmV0dXJuIW58fG4uanF1ZXJ5PyhufHxyKS5maW5kKGUpOnRoaXMuY29uc3RydWN0b3IobikuZmluZChlKTtpZihpWzFdKXtpZihuPW4gaW5zdGFuY2VvZiBiP25bMF06bixiLm1lcmdlKHRoaXMsYi5wYXJzZUhUTUwoaVsxXSxuJiZuLm5vZGVUeXBlP24ub3duZXJEb2N1bWVudHx8bjpvLCEwKSksQy50ZXN0KGlbMV0pJiZiLmlzUGxhaW5PYmplY3QobikpZm9yKGkgaW4gbiliLmlzRnVuY3Rpb24odGhpc1tpXSk/dGhpc1tpXShuW2ldKTp0aGlzLmF0dHIoaSxuW2ldKTtyZXR1cm4gdGhpc31pZihhPW8uZ2V0RWxlbWVudEJ5SWQoaVsyXSksYSYmYS5wYXJlbnROb2RlKXtpZihhLmlkIT09aVsyXSlyZXR1cm4gci5maW5kKGUpO3RoaXMubGVuZ3RoPTEsdGhpc1swXT1hfXJldHVybiB0aGlzLmNvbnRleHQ9byx0aGlzLnNlbGVjdG9yPWUsdGhpc31yZXR1cm4gZS5ub2RlVHlwZT8odGhpcy5jb250ZXh0PXRoaXNbMF09ZSx0aGlzLmxlbmd0aD0xLHRoaXMpOmIuaXNGdW5jdGlvbihlKT9yLnJlYWR5KGUpOihlLnNlbGVjdG9yIT09dCYmKHRoaXMuc2VsZWN0b3I9ZS5zZWxlY3Rvcix0aGlzLmNvbnRleHQ9ZS5jb250ZXh0KSxiLm1ha2VBcnJheShlLHRoaXMpKX0sc2VsZWN0b3I6IiIsbGVuZ3RoOjAsc2l6ZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmxlbmd0aH0sdG9BcnJheTpmdW5jdGlvbigpe3JldHVybiBoLmNhbGwodGhpcyl9LGdldDpmdW5jdGlvbihlKXtyZXR1cm4gbnVsbD09ZT90aGlzLnRvQXJyYXkoKTowPmU/dGhpc1t0aGlzLmxlbmd0aCtlXTp0aGlzW2VdfSxwdXNoU3RhY2s6ZnVuY3Rpb24oZSl7dmFyIHQ9Yi5tZXJnZSh0aGlzLmNvbnN0cnVjdG9yKCksZSk7cmV0dXJuIHQucHJldk9iamVjdD10aGlzLHQuY29udGV4dD10aGlzLmNvbnRleHQsdH0sZWFjaDpmdW5jdGlvbihlLHQpe3JldHVybiBiLmVhY2godGhpcyxlLHQpfSxyZWFkeTpmdW5jdGlvbihlKXtyZXR1cm4gYi5yZWFkeS5wcm9taXNlKCkuZG9uZShlKSx0aGlzfSxzbGljZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLnB1c2hTdGFjayhoLmFwcGx5KHRoaXMsYXJndW1lbnRzKSl9LGZpcnN0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZXEoMCl9LGxhc3Q6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lcSgtMSl9LGVxOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMubGVuZ3RoLG49K2UrKDA+ZT90OjApO3JldHVybiB0aGlzLnB1c2hTdGFjayhuPj0wJiZ0Pm4/W3RoaXNbbl1dOltdKX0sbWFwOmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLnB1c2hTdGFjayhiLm1hcCh0aGlzLGZ1bmN0aW9uKHQsbil7cmV0dXJuIGUuY2FsbCh0LG4sdCl9KSl9LGVuZDpmdW5jdGlvbigpe3JldHVybiB0aGlzLnByZXZPYmplY3R8fHRoaXMuY29uc3RydWN0b3IobnVsbCl9LHB1c2g6ZCxzb3J0OltdLnNvcnQsc3BsaWNlOltdLnNwbGljZX0sYi5mbi5pbml0LnByb3RvdHlwZT1iLmZuLGIuZXh0ZW5kPWIuZm4uZXh0ZW5kPWZ1bmN0aW9uKCl7dmFyIGUsbixyLGksbyxhLHM9YXJndW1lbnRzWzBdfHx7fSx1PTEsbD1hcmd1bWVudHMubGVuZ3RoLGM9ITE7Zm9yKCJib29sZWFuIj09dHlwZW9mIHMmJihjPXMscz1hcmd1bWVudHNbMV18fHt9LHU9MiksIm9iamVjdCI9PXR5cGVvZiBzfHxiLmlzRnVuY3Rpb24ocyl8fChzPXt9KSxsPT09dSYmKHM9dGhpcywtLXUpO2w+dTt1KyspaWYobnVsbCE9KG89YXJndW1lbnRzW3VdKSlmb3IoaSBpbiBvKWU9c1tpXSxyPW9baV0scyE9PXImJihjJiZyJiYoYi5pc1BsYWluT2JqZWN0KHIpfHwobj1iLmlzQXJyYXkocikpKT8obj8obj0hMSxhPWUmJmIuaXNBcnJheShlKT9lOltdKTphPWUmJmIuaXNQbGFpbk9iamVjdChlKT9lOnt9LHNbaV09Yi5leHRlbmQoYyxhLHIpKTpyIT09dCYmKHNbaV09cikpO3JldHVybiBzfSxiLmV4dGVuZCh7bm9Db25mbGljdDpmdW5jdGlvbih0KXtyZXR1cm4gZS4kPT09YiYmKGUuJD11KSx0JiZlLmpRdWVyeT09PWImJihlLmpRdWVyeT1zKSxifSxpc1JlYWR5OiExLHJlYWR5V2FpdDoxLGhvbGRSZWFkeTpmdW5jdGlvbihlKXtlP2IucmVhZHlXYWl0Kys6Yi5yZWFkeSghMCl9LHJlYWR5OmZ1bmN0aW9uKGUpe2lmKGU9PT0hMD8hLS1iLnJlYWR5V2FpdDohYi5pc1JlYWR5KXtpZighby5ib2R5KXJldHVybiBzZXRUaW1lb3V0KGIucmVhZHkpO2IuaXNSZWFkeT0hMCxlIT09ITAmJi0tYi5yZWFkeVdhaXQ+MHx8KG4ucmVzb2x2ZVdpdGgobyxbYl0pLGIuZm4udHJpZ2dlciYmYihvKS50cmlnZ2VyKCJyZWFkeSIpLm9mZigicmVhZHkiKSl9fSxpc0Z1bmN0aW9uOmZ1bmN0aW9uKGUpe3JldHVybiJmdW5jdGlvbiI9PT1iLnR5cGUoZSl9LGlzQXJyYXk6QXJyYXkuaXNBcnJheXx8ZnVuY3Rpb24oZSl7cmV0dXJuImFycmF5Ij09PWIudHlwZShlKX0saXNXaW5kb3c6ZnVuY3Rpb24oZSl7cmV0dXJuIG51bGwhPWUmJmU9PWUud2luZG93fSxpc051bWVyaWM6ZnVuY3Rpb24oZSl7cmV0dXJuIWlzTmFOKHBhcnNlRmxvYXQoZSkpJiZpc0Zpbml0ZShlKX0sdHlwZTpmdW5jdGlvbihlKXtyZXR1cm4gbnVsbD09ZT9lKyIiOiJvYmplY3QiPT10eXBlb2YgZXx8ImZ1bmN0aW9uIj09dHlwZW9mIGU/bFttLmNhbGwoZSldfHwib2JqZWN0Ijp0eXBlb2YgZX0saXNQbGFpbk9iamVjdDpmdW5jdGlvbihlKXtpZighZXx8Im9iamVjdCIhPT1iLnR5cGUoZSl8fGUubm9kZVR5cGV8fGIuaXNXaW5kb3coZSkpcmV0dXJuITE7dHJ5e2lmKGUuY29uc3RydWN0b3ImJiF5LmNhbGwoZSwiY29uc3RydWN0b3IiKSYmIXkuY2FsbChlLmNvbnN0cnVjdG9yLnByb3RvdHlwZSwiaXNQcm90b3R5cGVPZiIpKXJldHVybiExfWNhdGNoKG4pe3JldHVybiExfXZhciByO2ZvcihyIGluIGUpO3JldHVybiByPT09dHx8eS5jYWxsKGUscil9LGlzRW1wdHlPYmplY3Q6ZnVuY3Rpb24oZSl7dmFyIHQ7Zm9yKHQgaW4gZSlyZXR1cm4hMTtyZXR1cm4hMH0sZXJyb3I6ZnVuY3Rpb24oZSl7dGhyb3cgRXJyb3IoZSl9LHBhcnNlSFRNTDpmdW5jdGlvbihlLHQsbil7aWYoIWV8fCJzdHJpbmciIT10eXBlb2YgZSlyZXR1cm4gbnVsbDsiYm9vbGVhbiI9PXR5cGVvZiB0JiYobj10LHQ9ITEpLHQ9dHx8bzt2YXIgcj1DLmV4ZWMoZSksaT0hbiYmW107cmV0dXJuIHI/W3QuY3JlYXRlRWxlbWVudChyWzFdKV06KHI9Yi5idWlsZEZyYWdtZW50KFtlXSx0LGkpLGkmJmIoaSkucmVtb3ZlKCksYi5tZXJnZShbXSxyLmNoaWxkTm9kZXMpKX0scGFyc2VKU09OOmZ1bmN0aW9uKG4pe3JldHVybiBlLkpTT04mJmUuSlNPTi5wYXJzZT9lLkpTT04ucGFyc2Uobik6bnVsbD09PW4/bjoic3RyaW5nIj09dHlwZW9mIG4mJihuPWIudHJpbShuKSxuJiZrLnRlc3Qobi5yZXBsYWNlKFMsIkAiKS5yZXBsYWNlKEEsIl0iKS5yZXBsYWNlKEUsIiIpKSk/RnVuY3Rpb24oInJldHVybiAiK24pKCk6KGIuZXJyb3IoIkludmFsaWQgSlNPTjogIituKSx0KX0scGFyc2VYTUw6ZnVuY3Rpb24obil7dmFyIHIsaTtpZighbnx8InN0cmluZyIhPXR5cGVvZiBuKXJldHVybiBudWxsO3RyeXtlLkRPTVBhcnNlcj8oaT1uZXcgRE9NUGFyc2VyLHI9aS5wYXJzZUZyb21TdHJpbmcobiwidGV4dC94bWwiKSk6KHI9bmV3IEFjdGl2ZVhPYmplY3QoIk1pY3Jvc29mdC5YTUxET00iKSxyLmFzeW5jPSJmYWxzZSIsci5sb2FkWE1MKG4pKX1jYXRjaChvKXtyPXR9cmV0dXJuIHImJnIuZG9jdW1lbnRFbGVtZW50JiYhci5nZXRFbGVtZW50c0J5VGFnTmFtZSgicGFyc2VyZXJyb3IiKS5sZW5ndGh8fGIuZXJyb3IoIkludmFsaWQgWE1MOiAiK24pLHJ9LG5vb3A6ZnVuY3Rpb24oKXt9LGdsb2JhbEV2YWw6ZnVuY3Rpb24odCl7dCYmYi50cmltKHQpJiYoZS5leGVjU2NyaXB0fHxmdW5jdGlvbih0KXtlLmV2YWwuY2FsbChlLHQpfSkodCl9LGNhbWVsQ2FzZTpmdW5jdGlvbihlKXtyZXR1cm4gZS5yZXBsYWNlKGosIm1zLSIpLnJlcGxhY2UoRCxMKX0sbm9kZU5hbWU6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gZS5ub2RlTmFtZSYmZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpPT09dC50b0xvd2VyQ2FzZSgpfSxlYWNoOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpPTAsbz1lLmxlbmd0aCxhPU0oZSk7aWYobil7aWYoYSl7Zm9yKDtvPmk7aSsrKWlmKHI9dC5hcHBseShlW2ldLG4pLHI9PT0hMSlicmVha31lbHNlIGZvcihpIGluIGUpaWYocj10LmFwcGx5KGVbaV0sbikscj09PSExKWJyZWFrfWVsc2UgaWYoYSl7Zm9yKDtvPmk7aSsrKWlmKHI9dC5jYWxsKGVbaV0saSxlW2ldKSxyPT09ITEpYnJlYWt9ZWxzZSBmb3IoaSBpbiBlKWlmKHI9dC5jYWxsKGVbaV0saSxlW2ldKSxyPT09ITEpYnJlYWs7cmV0dXJuIGV9LHRyaW06diYmIXYuY2FsbCgiXHVmZWZmXHUwMGEwIik/ZnVuY3Rpb24oZSl7cmV0dXJuIG51bGw9PWU/IiI6di5jYWxsKGUpfTpmdW5jdGlvbihlKXtyZXR1cm4gbnVsbD09ZT8iIjooZSsiIikucmVwbGFjZShULCIiKX0sbWFrZUFycmF5OmZ1bmN0aW9uKGUsdCl7dmFyIG49dHx8W107cmV0dXJuIG51bGwhPWUmJihNKE9iamVjdChlKSk/Yi5tZXJnZShuLCJzdHJpbmciPT10eXBlb2YgZT9bZV06ZSk6ZC5jYWxsKG4sZSkpLG59LGluQXJyYXk6ZnVuY3Rpb24oZSx0LG4pe3ZhciByO2lmKHQpe2lmKGcpcmV0dXJuIGcuY2FsbCh0LGUsbik7Zm9yKHI9dC5sZW5ndGgsbj1uPzA+bj9NYXRoLm1heCgwLHIrbik6bjowO3I+bjtuKyspaWYobiBpbiB0JiZ0W25dPT09ZSlyZXR1cm4gbn1yZXR1cm4tMX0sbWVyZ2U6ZnVuY3Rpb24oZSxuKXt2YXIgcj1uLmxlbmd0aCxpPWUubGVuZ3RoLG89MDtpZigibnVtYmVyIj09dHlwZW9mIHIpZm9yKDtyPm87bysrKWVbaSsrXT1uW29dO2Vsc2Ugd2hpbGUobltvXSE9PXQpZVtpKytdPW5bbysrXTtyZXR1cm4gZS5sZW5ndGg9aSxlfSxncmVwOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpPVtdLG89MCxhPWUubGVuZ3RoO2ZvcihuPSEhbjthPm87bysrKXI9ISF0KGVbb10sbyksbiE9PXImJmkucHVzaChlW29dKTtyZXR1cm4gaX0sbWFwOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpPTAsbz1lLmxlbmd0aCxhPU0oZSkscz1bXTtpZihhKWZvcig7bz5pO2krKylyPXQoZVtpXSxpLG4pLG51bGwhPXImJihzW3MubGVuZ3RoXT1yKTtlbHNlIGZvcihpIGluIGUpcj10KGVbaV0saSxuKSxudWxsIT1yJiYoc1tzLmxlbmd0aF09cik7cmV0dXJuIGYuYXBwbHkoW10scyl9LGd1aWQ6MSxwcm94eTpmdW5jdGlvbihlLG4pe3ZhciByLGksbztyZXR1cm4ic3RyaW5nIj09dHlwZW9mIG4mJihvPWVbbl0sbj1lLGU9byksYi5pc0Z1bmN0aW9uKGUpPyhyPWguY2FsbChhcmd1bWVudHMsMiksaT1mdW5jdGlvbigpe3JldHVybiBlLmFwcGx5KG58fHRoaXMsci5jb25jYXQoaC5jYWxsKGFyZ3VtZW50cykpKX0saS5ndWlkPWUuZ3VpZD1lLmd1aWR8fGIuZ3VpZCsrLGkpOnR9LGFjY2VzczpmdW5jdGlvbihlLG4scixpLG8sYSxzKXt2YXIgdT0wLGw9ZS5sZW5ndGgsYz1udWxsPT1yO2lmKCJvYmplY3QiPT09Yi50eXBlKHIpKXtvPSEwO2Zvcih1IGluIHIpYi5hY2Nlc3MoZSxuLHUsclt1XSwhMCxhLHMpfWVsc2UgaWYoaSE9PXQmJihvPSEwLGIuaXNGdW5jdGlvbihpKXx8KHM9ITApLGMmJihzPyhuLmNhbGwoZSxpKSxuPW51bGwpOihjPW4sbj1mdW5jdGlvbihlLHQsbil7cmV0dXJuIGMuY2FsbChiKGUpLG4pfSkpLG4pKWZvcig7bD51O3UrKyluKGVbdV0scixzP2k6aS5jYWxsKGVbdV0sdSxuKGVbdV0scikpKTtyZXR1cm4gbz9lOmM/bi5jYWxsKGUpOmw/bihlWzBdLHIpOmF9LG5vdzpmdW5jdGlvbigpe3JldHVybihuZXcgRGF0ZSkuZ2V0VGltZSgpfX0pLGIucmVhZHkucHJvbWlzZT1mdW5jdGlvbih0KXtpZighbilpZihuPWIuRGVmZXJyZWQoKSwiY29tcGxldGUiPT09by5yZWFkeVN0YXRlKXNldFRpbWVvdXQoYi5yZWFkeSk7ZWxzZSBpZihvLmFkZEV2ZW50TGlzdGVuZXIpby5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIixILCExKSxlLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLEgsITEpO2Vsc2V7by5hdHRhY2hFdmVudCgib25yZWFkeXN0YXRlY2hhbmdlIixIKSxlLmF0dGFjaEV2ZW50KCJvbmxvYWQiLEgpO3ZhciByPSExO3RyeXtyPW51bGw9PWUuZnJhbWVFbGVtZW50JiZvLmRvY3VtZW50RWxlbWVudH1jYXRjaChpKXt9ciYmci5kb1Njcm9sbCYmZnVuY3Rpb24gYSgpe2lmKCFiLmlzUmVhZHkpe3RyeXtyLmRvU2Nyb2xsKCJsZWZ0Iil9Y2F0Y2goZSl7cmV0dXJuIHNldFRpbWVvdXQoYSw1MCl9cSgpLGIucmVhZHkoKX19KCl9cmV0dXJuIG4ucHJvbWlzZSh0KX0sYi5lYWNoKCJCb29sZWFuIE51bWJlciBTdHJpbmcgRnVuY3Rpb24gQXJyYXkgRGF0ZSBSZWdFeHAgT2JqZWN0IEVycm9yIi5zcGxpdCgiICIpLGZ1bmN0aW9uKGUsdCl7bFsiW29iamVjdCAiK3QrIl0iXT10LnRvTG93ZXJDYXNlKCl9KTtmdW5jdGlvbiBNKGUpe3ZhciB0PWUubGVuZ3RoLG49Yi50eXBlKGUpO3JldHVybiBiLmlzV2luZG93KGUpPyExOjE9PT1lLm5vZGVUeXBlJiZ0PyEwOiJhcnJheSI9PT1ufHwiZnVuY3Rpb24iIT09biYmKDA9PT10fHwibnVtYmVyIj09dHlwZW9mIHQmJnQ+MCYmdC0xIGluIGUpfXI9YihvKTt2YXIgXz17fTtmdW5jdGlvbiBGKGUpe3ZhciB0PV9bZV09e307cmV0dXJuIGIuZWFjaChlLm1hdGNoKHcpfHxbXSxmdW5jdGlvbihlLG4pe3Rbbl09ITB9KSx0fWIuQ2FsbGJhY2tzPWZ1bmN0aW9uKGUpe2U9InN0cmluZyI9PXR5cGVvZiBlP19bZV18fEYoZSk6Yi5leHRlbmQoe30sZSk7dmFyIG4scixpLG8sYSxzLHU9W10sbD0hZS5vbmNlJiZbXSxjPWZ1bmN0aW9uKHQpe2ZvcihyPWUubWVtb3J5JiZ0LGk9ITAsYT1zfHwwLHM9MCxvPXUubGVuZ3RoLG49ITA7dSYmbz5hO2ErKylpZih1W2FdLmFwcGx5KHRbMF0sdFsxXSk9PT0hMSYmZS5zdG9wT25GYWxzZSl7cj0hMTticmVha31uPSExLHUmJihsP2wubGVuZ3RoJiZjKGwuc2hpZnQoKSk6cj91PVtdOnAuZGlzYWJsZSgpKX0scD17YWRkOmZ1bmN0aW9uKCl7aWYodSl7dmFyIHQ9dS5sZW5ndGg7KGZ1bmN0aW9uIGkodCl7Yi5lYWNoKHQsZnVuY3Rpb24odCxuKXt2YXIgcj1iLnR5cGUobik7ImZ1bmN0aW9uIj09PXI/ZS51bmlxdWUmJnAuaGFzKG4pfHx1LnB1c2gobik6biYmbi5sZW5ndGgmJiJzdHJpbmciIT09ciYmaShuKX0pfSkoYXJndW1lbnRzKSxuP289dS5sZW5ndGg6ciYmKHM9dCxjKHIpKX1yZXR1cm4gdGhpc30scmVtb3ZlOmZ1bmN0aW9uKCl7cmV0dXJuIHUmJmIuZWFjaChhcmd1bWVudHMsZnVuY3Rpb24oZSx0KXt2YXIgcjt3aGlsZSgocj1iLmluQXJyYXkodCx1LHIpKT4tMSl1LnNwbGljZShyLDEpLG4mJihvPj1yJiZvLS0sYT49ciYmYS0tKX0pLHRoaXN9LGhhczpmdW5jdGlvbihlKXtyZXR1cm4gZT9iLmluQXJyYXkoZSx1KT4tMTohKCF1fHwhdS5sZW5ndGgpfSxlbXB0eTpmdW5jdGlvbigpe3JldHVybiB1PVtdLHRoaXN9LGRpc2FibGU6ZnVuY3Rpb24oKXtyZXR1cm4gdT1sPXI9dCx0aGlzfSxkaXNhYmxlZDpmdW5jdGlvbigpe3JldHVybiF1fSxsb2NrOmZ1bmN0aW9uKCl7cmV0dXJuIGw9dCxyfHxwLmRpc2FibGUoKSx0aGlzfSxsb2NrZWQ6ZnVuY3Rpb24oKXtyZXR1cm4hbH0sZmlyZVdpdGg6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdD10fHxbXSx0PVtlLHQuc2xpY2U/dC5zbGljZSgpOnRdLCF1fHxpJiYhbHx8KG4/bC5wdXNoKHQpOmModCkpLHRoaXN9LGZpcmU6ZnVuY3Rpb24oKXtyZXR1cm4gcC5maXJlV2l0aCh0aGlzLGFyZ3VtZW50cyksdGhpc30sZmlyZWQ6ZnVuY3Rpb24oKXtyZXR1cm4hIWl9fTtyZXR1cm4gcH0sYi5leHRlbmQoe0RlZmVycmVkOmZ1bmN0aW9uKGUpe3ZhciB0PVtbInJlc29sdmUiLCJkb25lIixiLkNhbGxiYWNrcygib25jZSBtZW1vcnkiKSwicmVzb2x2ZWQiXSxbInJlamVjdCIsImZhaWwiLGIuQ2FsbGJhY2tzKCJvbmNlIG1lbW9yeSIpLCJyZWplY3RlZCJdLFsibm90aWZ5IiwicHJvZ3Jlc3MiLGIuQ2FsbGJhY2tzKCJtZW1vcnkiKV1dLG49InBlbmRpbmciLHI9e3N0YXRlOmZ1bmN0aW9uKCl7cmV0dXJuIG59LGFsd2F5czpmdW5jdGlvbigpe3JldHVybiBpLmRvbmUoYXJndW1lbnRzKS5mYWlsKGFyZ3VtZW50cyksdGhpc30sdGhlbjpmdW5jdGlvbigpe3ZhciBlPWFyZ3VtZW50cztyZXR1cm4gYi5EZWZlcnJlZChmdW5jdGlvbihuKXtiLmVhY2godCxmdW5jdGlvbih0LG8pe3ZhciBhPW9bMF0scz1iLmlzRnVuY3Rpb24oZVt0XSkmJmVbdF07aVtvWzFdXShmdW5jdGlvbigpe3ZhciBlPXMmJnMuYXBwbHkodGhpcyxhcmd1bWVudHMpO2UmJmIuaXNGdW5jdGlvbihlLnByb21pc2UpP2UucHJvbWlzZSgpLmRvbmUobi5yZXNvbHZlKS5mYWlsKG4ucmVqZWN0KS5wcm9ncmVzcyhuLm5vdGlmeSk6blthKyJXaXRoIl0odGhpcz09PXI/bi5wcm9taXNlKCk6dGhpcyxzP1tlXTphcmd1bWVudHMpfSl9KSxlPW51bGx9KS5wcm9taXNlKCl9LHByb21pc2U6ZnVuY3Rpb24oZSl7cmV0dXJuIG51bGwhPWU/Yi5leHRlbmQoZSxyKTpyfX0saT17fTtyZXR1cm4gci5waXBlPXIudGhlbixiLmVhY2godCxmdW5jdGlvbihlLG8pe3ZhciBhPW9bMl0scz1vWzNdO3Jbb1sxXV09YS5hZGQscyYmYS5hZGQoZnVuY3Rpb24oKXtuPXN9LHRbMV5lXVsyXS5kaXNhYmxlLHRbMl1bMl0ubG9jayksaVtvWzBdXT1mdW5jdGlvbigpe3JldHVybiBpW29bMF0rIldpdGgiXSh0aGlzPT09aT9yOnRoaXMsYXJndW1lbnRzKSx0aGlzfSxpW29bMF0rIldpdGgiXT1hLmZpcmVXaXRofSksci5wcm9taXNlKGkpLGUmJmUuY2FsbChpLGkpLGl9LHdoZW46ZnVuY3Rpb24oZSl7dmFyIHQ9MCxuPWguY2FsbChhcmd1bWVudHMpLHI9bi5sZW5ndGgsaT0xIT09cnx8ZSYmYi5pc0Z1bmN0aW9uKGUucHJvbWlzZSk/cjowLG89MT09PWk/ZTpiLkRlZmVycmVkKCksYT1mdW5jdGlvbihlLHQsbil7cmV0dXJuIGZ1bmN0aW9uKHIpe3RbZV09dGhpcyxuW2VdPWFyZ3VtZW50cy5sZW5ndGg+MT9oLmNhbGwoYXJndW1lbnRzKTpyLG49PT1zP28ubm90aWZ5V2l0aCh0LG4pOi0taXx8by5yZXNvbHZlV2l0aCh0LG4pfX0scyx1LGw7aWYocj4xKWZvcihzPUFycmF5KHIpLHU9QXJyYXkociksbD1BcnJheShyKTtyPnQ7dCsrKW5bdF0mJmIuaXNGdW5jdGlvbihuW3RdLnByb21pc2UpP25bdF0ucHJvbWlzZSgpLmRvbmUoYSh0LGwsbikpLmZhaWwoby5yZWplY3QpLnByb2dyZXNzKGEodCx1LHMpKTotLWk7cmV0dXJuIGl8fG8ucmVzb2x2ZVdpdGgobCxuKSxvLnByb21pc2UoKX19KSxiLnN1cHBvcnQ9ZnVuY3Rpb24oKXt2YXIgdCxuLHIsYSxzLHUsbCxjLHAsZixkPW8uY3JlYXRlRWxlbWVudCgiZGl2Iik7aWYoZC5zZXRBdHRyaWJ1dGUoImNsYXNzTmFtZSIsInQiKSxkLmlubmVySFRNTD0iICA8bGluay8+PHRhYmxlPjwvdGFibGU+PGEgaHJlZj0nL2EnPmE8L2E+PGlucHV0IHR5cGU9J2NoZWNrYm94Jy8+IixuPWQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIioiKSxyPWQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImEiKVswXSwhbnx8IXJ8fCFuLmxlbmd0aClyZXR1cm57fTtzPW8uY3JlYXRlRWxlbWVudCgic2VsZWN0IiksbD1zLmFwcGVuZENoaWxkKG8uY3JlYXRlRWxlbWVudCgib3B0aW9uIikpLGE9ZC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiaW5wdXQiKVswXSxyLnN0eWxlLmNzc1RleHQ9InRvcDoxcHg7ZmxvYXQ6bGVmdDtvcGFjaXR5Oi41Iix0PXtnZXRTZXRBdHRyaWJ1dGU6InQiIT09ZC5jbGFzc05hbWUsbGVhZGluZ1doaXRlc3BhY2U6Mz09PWQuZmlyc3RDaGlsZC5ub2RlVHlwZSx0Ym9keTohZC5nZXRFbGVtZW50c0J5VGFnTmFtZSgidGJvZHkiKS5sZW5ndGgsaHRtbFNlcmlhbGl6ZTohIWQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImxpbmsiKS5sZW5ndGgsc3R5bGU6L3RvcC8udGVzdChyLmdldEF0dHJpYnV0ZSgic3R5bGUiKSksaHJlZk5vcm1hbGl6ZWQ6Ii9hIj09PXIuZ2V0QXR0cmlidXRlKCJocmVmIiksb3BhY2l0eTovXjAuNS8udGVzdChyLnN0eWxlLm9wYWNpdHkpLGNzc0Zsb2F0OiEhci5zdHlsZS5jc3NGbG9hdCxjaGVja09uOiEhYS52YWx1ZSxvcHRTZWxlY3RlZDpsLnNlbGVjdGVkLGVuY3R5cGU6ISFvLmNyZWF0ZUVsZW1lbnQoImZvcm0iKS5lbmN0eXBlLGh0bWw1Q2xvbmU6Ijw6bmF2PjwvOm5hdj4iIT09by5jcmVhdGVFbGVtZW50KCJuYXYiKS5jbG9uZU5vZGUoITApLm91dGVySFRNTCxib3hNb2RlbDoiQ1NTMUNvbXBhdCI9PT1vLmNvbXBhdE1vZGUsZGVsZXRlRXhwYW5kbzohMCxub0Nsb25lRXZlbnQ6ITAsaW5saW5lQmxvY2tOZWVkc0xheW91dDohMSxzaHJpbmtXcmFwQmxvY2tzOiExLHJlbGlhYmxlTWFyZ2luUmlnaHQ6ITAsYm94U2l6aW5nUmVsaWFibGU6ITAscGl4ZWxQb3NpdGlvbjohMX0sYS5jaGVja2VkPSEwLHQubm9DbG9uZUNoZWNrZWQ9YS5jbG9uZU5vZGUoITApLmNoZWNrZWQscy5kaXNhYmxlZD0hMCx0Lm9wdERpc2FibGVkPSFsLmRpc2FibGVkO3RyeXtkZWxldGUgZC50ZXN0fWNhdGNoKGgpe3QuZGVsZXRlRXhwYW5kbz0hMX1hPW8uY3JlYXRlRWxlbWVudCgiaW5wdXQiKSxhLnNldEF0dHJpYnV0ZSgidmFsdWUiLCIiKSx0LmlucHV0PSIiPT09YS5nZXRBdHRyaWJ1dGUoInZhbHVlIiksYS52YWx1ZT0idCIsYS5zZXRBdHRyaWJ1dGUoInR5cGUiLCJyYWRpbyIpLHQucmFkaW9WYWx1ZT0idCI9PT1hLnZhbHVlLGEuc2V0QXR0cmlidXRlKCJjaGVja2VkIiwidCIpLGEuc2V0QXR0cmlidXRlKCJuYW1lIiwidCIpLHU9by5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksdS5hcHBlbmRDaGlsZChhKSx0LmFwcGVuZENoZWNrZWQ9YS5jaGVja2VkLHQuY2hlY2tDbG9uZT11LmNsb25lTm9kZSghMCkuY2xvbmVOb2RlKCEwKS5sYXN0Q2hpbGQuY2hlY2tlZCxkLmF0dGFjaEV2ZW50JiYoZC5hdHRhY2hFdmVudCgib25jbGljayIsZnVuY3Rpb24oKXt0Lm5vQ2xvbmVFdmVudD0hMX0pLGQuY2xvbmVOb2RlKCEwKS5jbGljaygpKTtmb3IoZiBpbntzdWJtaXQ6ITAsY2hhbmdlOiEwLGZvY3VzaW46ITB9KWQuc2V0QXR0cmlidXRlKGM9Im9uIitmLCJ0IiksdFtmKyJCdWJibGVzIl09YyBpbiBlfHxkLmF0dHJpYnV0ZXNbY10uZXhwYW5kbz09PSExO3JldHVybiBkLnN0eWxlLmJhY2tncm91bmRDbGlwPSJjb250ZW50LWJveCIsZC5jbG9uZU5vZGUoITApLnN0eWxlLmJhY2tncm91bmRDbGlwPSIiLHQuY2xlYXJDbG9uZVN0eWxlPSJjb250ZW50LWJveCI9PT1kLnN0eWxlLmJhY2tncm91bmRDbGlwLGIoZnVuY3Rpb24oKXt2YXIgbixyLGEscz0icGFkZGluZzowO21hcmdpbjowO2JvcmRlcjowO2Rpc3BsYXk6YmxvY2s7Ym94LXNpemluZzpjb250ZW50LWJveDstbW96LWJveC1zaXppbmc6Y29udGVudC1ib3g7LXdlYmtpdC1ib3gtc2l6aW5nOmNvbnRlbnQtYm94OyIsdT1vLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJib2R5IilbMF07dSYmKG49by5jcmVhdGVFbGVtZW50KCJkaXYiKSxuLnN0eWxlLmNzc1RleHQ9ImJvcmRlcjowO3dpZHRoOjA7aGVpZ2h0OjA7cG9zaXRpb246YWJzb2x1dGU7dG9wOjA7bGVmdDotOTk5OXB4O21hcmdpbi10b3A6MXB4Iix1LmFwcGVuZENoaWxkKG4pLmFwcGVuZENoaWxkKGQpLGQuaW5uZXJIVE1MPSI8dGFibGU+PHRyPjx0ZD48L3RkPjx0ZD50PC90ZD48L3RyPjwvdGFibGU+IixhPWQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInRkIiksYVswXS5zdHlsZS5jc3NUZXh0PSJwYWRkaW5nOjA7bWFyZ2luOjA7Ym9yZGVyOjA7ZGlzcGxheTpub25lIixwPTA9PT1hWzBdLm9mZnNldEhlaWdodCxhWzBdLnN0eWxlLmRpc3BsYXk9IiIsYVsxXS5zdHlsZS5kaXNwbGF5PSJub25lIix0LnJlbGlhYmxlSGlkZGVuT2Zmc2V0cz1wJiYwPT09YVswXS5vZmZzZXRIZWlnaHQsZC5pbm5lckhUTUw9IiIsZC5zdHlsZS5jc3NUZXh0PSJib3gtc2l6aW5nOmJvcmRlci1ib3g7LW1vei1ib3gtc2l6aW5nOmJvcmRlci1ib3g7LXdlYmtpdC1ib3gtc2l6aW5nOmJvcmRlci1ib3g7cGFkZGluZzoxcHg7Ym9yZGVyOjFweDtkaXNwbGF5OmJsb2NrO3dpZHRoOjRweDttYXJnaW4tdG9wOjElO3Bvc2l0aW9uOmFic29sdXRlO3RvcDoxJTsiLHQuYm94U2l6aW5nPTQ9PT1kLm9mZnNldFdpZHRoLHQuZG9lc05vdEluY2x1ZGVNYXJnaW5JbkJvZHlPZmZzZXQ9MSE9PXUub2Zmc2V0VG9wLGUuZ2V0Q29tcHV0ZWRTdHlsZSYmKHQucGl4ZWxQb3NpdGlvbj0iMSUiIT09KGUuZ2V0Q29tcHV0ZWRTdHlsZShkLG51bGwpfHx7fSkudG9wLHQuYm94U2l6aW5nUmVsaWFibGU9IjRweCI9PT0oZS5nZXRDb21wdXRlZFN0eWxlKGQsbnVsbCl8fHt3aWR0aDoiNHB4In0pLndpZHRoLHI9ZC5hcHBlbmRDaGlsZChvLmNyZWF0ZUVsZW1lbnQoImRpdiIpKSxyLnN0eWxlLmNzc1RleHQ9ZC5zdHlsZS5jc3NUZXh0PXMsci5zdHlsZS5tYXJnaW5SaWdodD1yLnN0eWxlLndpZHRoPSIwIixkLnN0eWxlLndpZHRoPSIxcHgiLHQucmVsaWFibGVNYXJnaW5SaWdodD0hcGFyc2VGbG9hdCgoZS5nZXRDb21wdXRlZFN0eWxlKHIsbnVsbCl8fHt9KS5tYXJnaW5SaWdodCkpLHR5cGVvZiBkLnN0eWxlLnpvb20hPT1pJiYoZC5pbm5lckhUTUw9IiIsZC5zdHlsZS5jc3NUZXh0PXMrIndpZHRoOjFweDtwYWRkaW5nOjFweDtkaXNwbGF5OmlubGluZTt6b29tOjEiLHQuaW5saW5lQmxvY2tOZWVkc0xheW91dD0zPT09ZC5vZmZzZXRXaWR0aCxkLnN0eWxlLmRpc3BsYXk9ImJsb2NrIixkLmlubmVySFRNTD0iPGRpdj48L2Rpdj4iLGQuZmlyc3RDaGlsZC5zdHlsZS53aWR0aD0iNXB4Iix0LnNocmlua1dyYXBCbG9ja3M9MyE9PWQub2Zmc2V0V2lkdGgsdC5pbmxpbmVCbG9ja05lZWRzTGF5b3V0JiYodS5zdHlsZS56b29tPTEpKSx1LnJlbW92ZUNoaWxkKG4pLG49ZD1hPXI9bnVsbCl9KSxuPXM9dT1sPXI9YT1udWxsLHR9KCk7dmFyIE89Lyg/Olx7W1xzXFNdKlx9fFxbW1xzXFNdKlxdKSQvLEI9LyhbQS1aXSkvZztmdW5jdGlvbiBQKGUsbixyLGkpe2lmKGIuYWNjZXB0RGF0YShlKSl7dmFyIG8sYSxzPWIuZXhwYW5kbyx1PSJzdHJpbmciPT10eXBlb2YgbixsPWUubm9kZVR5cGUscD1sP2IuY2FjaGU6ZSxmPWw/ZVtzXTplW3NdJiZzO2lmKGYmJnBbZl0mJihpfHxwW2ZdLmRhdGEpfHwhdXx8ciE9PXQpcmV0dXJuIGZ8fChsP2Vbc109Zj1jLnBvcCgpfHxiLmd1aWQrKzpmPXMpLHBbZl18fChwW2ZdPXt9LGx8fChwW2ZdLnRvSlNPTj1iLm5vb3ApKSwoIm9iamVjdCI9PXR5cGVvZiBufHwiZnVuY3Rpb24iPT10eXBlb2YgbikmJihpP3BbZl09Yi5leHRlbmQocFtmXSxuKTpwW2ZdLmRhdGE9Yi5leHRlbmQocFtmXS5kYXRhLG4pKSxvPXBbZl0saXx8KG8uZGF0YXx8KG8uZGF0YT17fSksbz1vLmRhdGEpLHIhPT10JiYob1tiLmNhbWVsQ2FzZShuKV09ciksdT8oYT1vW25dLG51bGw9PWEmJihhPW9bYi5jYW1lbENhc2UobildKSk6YT1vLGF9fWZ1bmN0aW9uIFIoZSx0LG4pe2lmKGIuYWNjZXB0RGF0YShlKSl7dmFyIHIsaSxvLGE9ZS5ub2RlVHlwZSxzPWE/Yi5jYWNoZTplLHU9YT9lW2IuZXhwYW5kb106Yi5leHBhbmRvO2lmKHNbdV0pe2lmKHQmJihvPW4/c1t1XTpzW3VdLmRhdGEpKXtiLmlzQXJyYXkodCk/dD10LmNvbmNhdChiLm1hcCh0LGIuY2FtZWxDYXNlKSk6dCBpbiBvP3Q9W3RdOih0PWIuY2FtZWxDYXNlKHQpLHQ9dCBpbiBvP1t0XTp0LnNwbGl0KCIgIikpO2ZvcihyPTAsaT10Lmxlbmd0aDtpPnI7cisrKWRlbGV0ZSBvW3Rbcl1dO2lmKCEobj8kOmIuaXNFbXB0eU9iamVjdCkobykpcmV0dXJufShufHwoZGVsZXRlIHNbdV0uZGF0YSwkKHNbdV0pKSkmJihhP2IuY2xlYW5EYXRhKFtlXSwhMCk6Yi5zdXBwb3J0LmRlbGV0ZUV4cGFuZG98fHMhPXMud2luZG93P2RlbGV0ZSBzW3VdOnNbdV09bnVsbCl9fX1iLmV4dGVuZCh7Y2FjaGU6e30sZXhwYW5kbzoialF1ZXJ5IisocCtNYXRoLnJhbmRvbSgpKS5yZXBsYWNlKC9cRC9nLCIiKSxub0RhdGE6e2VtYmVkOiEwLG9iamVjdDoiY2xzaWQ6RDI3Q0RCNkUtQUU2RC0xMWNmLTk2QjgtNDQ0NTUzNTQwMDAwIixhcHBsZXQ6ITB9LGhhc0RhdGE6ZnVuY3Rpb24oZSl7cmV0dXJuIGU9ZS5ub2RlVHlwZT9iLmNhY2hlW2VbYi5leHBhbmRvXV06ZVtiLmV4cGFuZG9dLCEhZSYmISQoZSl9LGRhdGE6ZnVuY3Rpb24oZSx0LG4pe3JldHVybiBQKGUsdCxuKX0scmVtb3ZlRGF0YTpmdW5jdGlvbihlLHQpe3JldHVybiBSKGUsdCl9LF9kYXRhOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gUChlLHQsbiwhMCl9LF9yZW1vdmVEYXRhOmZ1bmN0aW9uKGUsdCl7cmV0dXJuIFIoZSx0LCEwKX0sYWNjZXB0RGF0YTpmdW5jdGlvbihlKXtpZihlLm5vZGVUeXBlJiYxIT09ZS5ub2RlVHlwZSYmOSE9PWUubm9kZVR5cGUpcmV0dXJuITE7dmFyIHQ9ZS5ub2RlTmFtZSYmYi5ub0RhdGFbZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpXTtyZXR1cm4hdHx8dCE9PSEwJiZlLmdldEF0dHJpYnV0ZSgiY2xhc3NpZCIpPT09dH19KSxiLmZuLmV4dGVuZCh7ZGF0YTpmdW5jdGlvbihlLG4pe3ZhciByLGksbz10aGlzWzBdLGE9MCxzPW51bGw7aWYoZT09PXQpe2lmKHRoaXMubGVuZ3RoJiYocz1iLmRhdGEobyksMT09PW8ubm9kZVR5cGUmJiFiLl9kYXRhKG8sInBhcnNlZEF0dHJzIikpKXtmb3Iocj1vLmF0dHJpYnV0ZXM7ci5sZW5ndGg+YTthKyspaT1yW2FdLm5hbWUsaS5pbmRleE9mKCJkYXRhLSIpfHwoaT1iLmNhbWVsQ2FzZShpLnNsaWNlKDUpKSxXKG8saSxzW2ldKSk7Yi5fZGF0YShvLCJwYXJzZWRBdHRycyIsITApfXJldHVybiBzfXJldHVybiJvYmplY3QiPT10eXBlb2YgZT90aGlzLmVhY2goZnVuY3Rpb24oKXtiLmRhdGEodGhpcyxlKX0pOmIuYWNjZXNzKHRoaXMsZnVuY3Rpb24obil7cmV0dXJuIG49PT10P28/VyhvLGUsYi5kYXRhKG8sZSkpOm51bGw6KHRoaXMuZWFjaChmdW5jdGlvbigpe2IuZGF0YSh0aGlzLGUsbil9KSx0KX0sbnVsbCxuLGFyZ3VtZW50cy5sZW5ndGg+MSxudWxsLCEwKX0scmVtb3ZlRGF0YTpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7Yi5yZW1vdmVEYXRhKHRoaXMsZSl9KX19KTtmdW5jdGlvbiBXKGUsbixyKXtpZihyPT09dCYmMT09PWUubm9kZVR5cGUpe3ZhciBpPSJkYXRhLSIrbi5yZXBsYWNlKEIsIi0kMSIpLnRvTG93ZXJDYXNlKCk7aWYocj1lLmdldEF0dHJpYnV0ZShpKSwic3RyaW5nIj09dHlwZW9mIHIpe3RyeXtyPSJ0cnVlIj09PXI/ITA6ImZhbHNlIj09PXI/ITE6Im51bGwiPT09cj9udWxsOityKyIiPT09cj8rcjpPLnRlc3Qocik/Yi5wYXJzZUpTT04ocik6cn1jYXRjaChvKXt9Yi5kYXRhKGUsbixyKX1lbHNlIHI9dH1yZXR1cm4gcn1mdW5jdGlvbiAkKGUpe3ZhciB0O2Zvcih0IGluIGUpaWYoKCJkYXRhIiE9PXR8fCFiLmlzRW1wdHlPYmplY3QoZVt0XSkpJiYidG9KU09OIiE9PXQpcmV0dXJuITE7cmV0dXJuITB9Yi5leHRlbmQoe3F1ZXVlOmZ1bmN0aW9uKGUsbixyKXt2YXIgaTtyZXR1cm4gZT8obj0obnx8ImZ4IikrInF1ZXVlIixpPWIuX2RhdGEoZSxuKSxyJiYoIWl8fGIuaXNBcnJheShyKT9pPWIuX2RhdGEoZSxuLGIubWFrZUFycmF5KHIpKTppLnB1c2gocikpLGl8fFtdKTp0fSxkZXF1ZXVlOmZ1bmN0aW9uKGUsdCl7dD10fHwiZngiO3ZhciBuPWIucXVldWUoZSx0KSxyPW4ubGVuZ3RoLGk9bi5zaGlmdCgpLG89Yi5fcXVldWVIb29rcyhlLHQpLGE9ZnVuY3Rpb24oKXtiLmRlcXVldWUoZSx0KX07ImlucHJvZ3Jlc3MiPT09aSYmKGk9bi5zaGlmdCgpLHItLSksby5jdXI9aSxpJiYoImZ4Ij09PXQmJm4udW5zaGlmdCgiaW5wcm9ncmVzcyIpLGRlbGV0ZSBvLnN0b3AsaS5jYWxsKGUsYSxvKSksIXImJm8mJm8uZW1wdHkuZmlyZSgpfSxfcXVldWVIb29rczpmdW5jdGlvbihlLHQpe3ZhciBuPXQrInF1ZXVlSG9va3MiO3JldHVybiBiLl9kYXRhKGUsbil8fGIuX2RhdGEoZSxuLHtlbXB0eTpiLkNhbGxiYWNrcygib25jZSBtZW1vcnkiKS5hZGQoZnVuY3Rpb24oKXtiLl9yZW1vdmVEYXRhKGUsdCsicXVldWUiKSxiLl9yZW1vdmVEYXRhKGUsbil9KX0pfX0pLGIuZm4uZXh0ZW5kKHtxdWV1ZTpmdW5jdGlvbihlLG4pe3ZhciByPTI7cmV0dXJuInN0cmluZyIhPXR5cGVvZiBlJiYobj1lLGU9ImZ4IixyLS0pLHI+YXJndW1lbnRzLmxlbmd0aD9iLnF1ZXVlKHRoaXNbMF0sZSk6bj09PXQ/dGhpczp0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgdD1iLnF1ZXVlKHRoaXMsZSxuKTtiLl9xdWV1ZUhvb2tzKHRoaXMsZSksImZ4Ij09PWUmJiJpbnByb2dyZXNzIiE9PXRbMF0mJmIuZGVxdWV1ZSh0aGlzLGUpfSl9LGRlcXVldWU6ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe2IuZGVxdWV1ZSh0aGlzLGUpfSl9LGRlbGF5OmZ1bmN0aW9uKGUsdCl7cmV0dXJuIGU9Yi5meD9iLmZ4LnNwZWVkc1tlXXx8ZTplLHQ9dHx8ImZ4Iix0aGlzLnF1ZXVlKHQsZnVuY3Rpb24odCxuKXt2YXIgcj1zZXRUaW1lb3V0KHQsZSk7bi5zdG9wPWZ1bmN0aW9uKCl7Y2xlYXJUaW1lb3V0KHIpfX0pfSxjbGVhclF1ZXVlOmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLnF1ZXVlKGV8fCJmeCIsW10pfSxwcm9taXNlOmZ1bmN0aW9uKGUsbil7dmFyIHIsaT0xLG89Yi5EZWZlcnJlZCgpLGE9dGhpcyxzPXRoaXMubGVuZ3RoLHU9ZnVuY3Rpb24oKXstLWl8fG8ucmVzb2x2ZVdpdGgoYSxbYV0pfTsic3RyaW5nIiE9dHlwZW9mIGUmJihuPWUsZT10KSxlPWV8fCJmeCI7d2hpbGUocy0tKXI9Yi5fZGF0YShhW3NdLGUrInF1ZXVlSG9va3MiKSxyJiZyLmVtcHR5JiYoaSsrLHIuZW1wdHkuYWRkKHUpKTtyZXR1cm4gdSgpLG8ucHJvbWlzZShuKX19KTt2YXIgSSx6LFg9L1tcdFxyXG5dL2csVT0vXHIvZyxWPS9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbnxvYmplY3QpJC9pLFk9L14oPzphfGFyZWEpJC9pLEo9L14oPzpjaGVja2VkfHNlbGVjdGVkfGF1dG9mb2N1c3xhdXRvcGxheXxhc3luY3xjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZCkkL2ksRz0vXig/OmNoZWNrZWR8c2VsZWN0ZWQpJC9pLFE9Yi5zdXBwb3J0LmdldFNldEF0dHJpYnV0ZSxLPWIuc3VwcG9ydC5pbnB1dDtiLmZuLmV4dGVuZCh7YXR0cjpmdW5jdGlvbihlLHQpe3JldHVybiBiLmFjY2Vzcyh0aGlzLGIuYXR0cixlLHQsYXJndW1lbnRzLmxlbmd0aD4xKX0scmVtb3ZlQXR0cjpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7Yi5yZW1vdmVBdHRyKHRoaXMsZSl9KX0scHJvcDpmdW5jdGlvbihlLHQpe3JldHVybiBiLmFjY2Vzcyh0aGlzLGIucHJvcCxlLHQsYXJndW1lbnRzLmxlbmd0aD4xKX0scmVtb3ZlUHJvcDpmdW5jdGlvbihlKXtyZXR1cm4gZT1iLnByb3BGaXhbZV18fGUsdGhpcy5lYWNoKGZ1bmN0aW9uKCl7dHJ5e3RoaXNbZV09dCxkZWxldGUgdGhpc1tlXX1jYXRjaChuKXt9fSl9LGFkZENsYXNzOmZ1bmN0aW9uKGUpe3ZhciB0LG4scixpLG8sYT0wLHM9dGhpcy5sZW5ndGgsdT0ic3RyaW5nIj09dHlwZW9mIGUmJmU7aWYoYi5pc0Z1bmN0aW9uKGUpKXJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24odCl7Yih0aGlzKS5hZGRDbGFzcyhlLmNhbGwodGhpcyx0LHRoaXMuY2xhc3NOYW1lKSl9KTtpZih1KWZvcih0PShlfHwiIikubWF0Y2godyl8fFtdO3M+YTthKyspaWYobj10aGlzW2FdLHI9MT09PW4ubm9kZVR5cGUmJihuLmNsYXNzTmFtZT8oIiAiK24uY2xhc3NOYW1lKyIgIikucmVwbGFjZShYLCIgIik6IiAiKSl7bz0wO3doaWxlKGk9dFtvKytdKTA+ci5pbmRleE9mKCIgIitpKyIgIikmJihyKz1pKyIgIik7bi5jbGFzc05hbWU9Yi50cmltKHIpfXJldHVybiB0aGlzfSxyZW1vdmVDbGFzczpmdW5jdGlvbihlKXt2YXIgdCxuLHIsaSxvLGE9MCxzPXRoaXMubGVuZ3RoLHU9MD09PWFyZ3VtZW50cy5sZW5ndGh8fCJzdHJpbmciPT10eXBlb2YgZSYmZTtpZihiLmlzRnVuY3Rpb24oZSkpcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbih0KXtiKHRoaXMpLnJlbW92ZUNsYXNzKGUuY2FsbCh0aGlzLHQsdGhpcy5jbGFzc05hbWUpKX0pO2lmKHUpZm9yKHQ9KGV8fCIiKS5tYXRjaCh3KXx8W107cz5hO2ErKylpZihuPXRoaXNbYV0scj0xPT09bi5ub2RlVHlwZSYmKG4uY2xhc3NOYW1lPygiICIrbi5jbGFzc05hbWUrIiAiKS5yZXBsYWNlKFgsIiAiKToiIikpe289MDt3aGlsZShpPXRbbysrXSl3aGlsZShyLmluZGV4T2YoIiAiK2krIiAiKT49MClyPXIucmVwbGFjZSgiICIraSsiICIsIiAiKTtuLmNsYXNzTmFtZT1lP2IudHJpbShyKToiIn1yZXR1cm4gdGhpc30sdG9nZ2xlQ2xhc3M6ZnVuY3Rpb24oZSx0KXt2YXIgbj10eXBlb2YgZSxyPSJib29sZWFuIj09dHlwZW9mIHQ7cmV0dXJuIGIuaXNGdW5jdGlvbihlKT90aGlzLmVhY2goZnVuY3Rpb24obil7Yih0aGlzKS50b2dnbGVDbGFzcyhlLmNhbGwodGhpcyxuLHRoaXMuY2xhc3NOYW1lLHQpLHQpfSk6dGhpcy5lYWNoKGZ1bmN0aW9uKCl7aWYoInN0cmluZyI9PT1uKXt2YXIgbyxhPTAscz1iKHRoaXMpLHU9dCxsPWUubWF0Y2godyl8fFtdO3doaWxlKG89bFthKytdKXU9cj91OiFzLmhhc0NsYXNzKG8pLHNbdT8iYWRkQ2xhc3MiOiJyZW1vdmVDbGFzcyJdKG8pfWVsc2Uobj09PWl8fCJib29sZWFuIj09PW4pJiYodGhpcy5jbGFzc05hbWUmJmIuX2RhdGEodGhpcywiX19jbGFzc05hbWVfXyIsdGhpcy5jbGFzc05hbWUpLHRoaXMuY2xhc3NOYW1lPXRoaXMuY2xhc3NOYW1lfHxlPT09ITE/IiI6Yi5fZGF0YSh0aGlzLCJfX2NsYXNzTmFtZV9fIil8fCIiKX0pfSxoYXNDbGFzczpmdW5jdGlvbihlKXt2YXIgdD0iICIrZSsiICIsbj0wLHI9dGhpcy5sZW5ndGg7Zm9yKDtyPm47bisrKWlmKDE9PT10aGlzW25dLm5vZGVUeXBlJiYoIiAiK3RoaXNbbl0uY2xhc3NOYW1lKyIgIikucmVwbGFjZShYLCIgIikuaW5kZXhPZih0KT49MClyZXR1cm4hMDtyZXR1cm4hMX0sdmFsOmZ1bmN0aW9uKGUpe3ZhciBuLHIsaSxvPXRoaXNbMF07e2lmKGFyZ3VtZW50cy5sZW5ndGgpcmV0dXJuIGk9Yi5pc0Z1bmN0aW9uKGUpLHRoaXMuZWFjaChmdW5jdGlvbihuKXt2YXIgbyxhPWIodGhpcyk7MT09PXRoaXMubm9kZVR5cGUmJihvPWk/ZS5jYWxsKHRoaXMsbixhLnZhbCgpKTplLG51bGw9PW8/bz0iIjoibnVtYmVyIj09dHlwZW9mIG8/bys9IiI6Yi5pc0FycmF5KG8pJiYobz1iLm1hcChvLGZ1bmN0aW9uKGUpe3JldHVybiBudWxsPT1lPyIiOmUrIiJ9KSkscj1iLnZhbEhvb2tzW3RoaXMudHlwZV18fGIudmFsSG9va3NbdGhpcy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpXSxyJiYic2V0ImluIHImJnIuc2V0KHRoaXMsbywidmFsdWUiKSE9PXR8fCh0aGlzLnZhbHVlPW8pKX0pO2lmKG8pcmV0dXJuIHI9Yi52YWxIb29rc1tvLnR5cGVdfHxiLnZhbEhvb2tzW28ubm9kZU5hbWUudG9Mb3dlckNhc2UoKV0sciYmImdldCJpbiByJiYobj1yLmdldChvLCJ2YWx1ZSIpKSE9PXQ/bjoobj1vLnZhbHVlLCJzdHJpbmciPT10eXBlb2Ygbj9uLnJlcGxhY2UoVSwiIik6bnVsbD09bj8iIjpuKX19fSksYi5leHRlbmQoe3ZhbEhvb2tzOntvcHRpb246e2dldDpmdW5jdGlvbihlKXt2YXIgdD1lLmF0dHJpYnV0ZXMudmFsdWU7cmV0dXJuIXR8fHQuc3BlY2lmaWVkP2UudmFsdWU6ZS50ZXh0fX0sc2VsZWN0OntnZXQ6ZnVuY3Rpb24oZSl7dmFyIHQsbixyPWUub3B0aW9ucyxpPWUuc2VsZWN0ZWRJbmRleCxvPSJzZWxlY3Qtb25lIj09PWUudHlwZXx8MD5pLGE9bz9udWxsOltdLHM9bz9pKzE6ci5sZW5ndGgsdT0wPmk/czpvP2k6MDtmb3IoO3M+dTt1KyspaWYobj1yW3VdLCEoIW4uc2VsZWN0ZWQmJnUhPT1pfHwoYi5zdXBwb3J0Lm9wdERpc2FibGVkP24uZGlzYWJsZWQ6bnVsbCE9PW4uZ2V0QXR0cmlidXRlKCJkaXNhYmxlZCIpKXx8bi5wYXJlbnROb2RlLmRpc2FibGVkJiZiLm5vZGVOYW1lKG4ucGFyZW50Tm9kZSwib3B0Z3JvdXAiKSkpe2lmKHQ9YihuKS52YWwoKSxvKXJldHVybiB0O2EucHVzaCh0KX1yZXR1cm4gYX0sc2V0OmZ1bmN0aW9uKGUsdCl7dmFyIG49Yi5tYWtlQXJyYXkodCk7cmV0dXJuIGIoZSkuZmluZCgib3B0aW9uIikuZWFjaChmdW5jdGlvbigpe3RoaXMuc2VsZWN0ZWQ9Yi5pbkFycmF5KGIodGhpcykudmFsKCksbik+PTB9KSxuLmxlbmd0aHx8KGUuc2VsZWN0ZWRJbmRleD0tMSksbn19fSxhdHRyOmZ1bmN0aW9uKGUsbixyKXt2YXIgbyxhLHMsdT1lLm5vZGVUeXBlO2lmKGUmJjMhPT11JiY4IT09dSYmMiE9PXUpcmV0dXJuIHR5cGVvZiBlLmdldEF0dHJpYnV0ZT09PWk/Yi5wcm9wKGUsbixyKTooYT0xIT09dXx8IWIuaXNYTUxEb2MoZSksYSYmKG49bi50b0xvd2VyQ2FzZSgpLG89Yi5hdHRySG9va3Nbbl18fChKLnRlc3Qobik/ejpJKSkscj09PXQ/byYmYSYmImdldCJpbiBvJiZudWxsIT09KHM9by5nZXQoZSxuKSk/czoodHlwZW9mIGUuZ2V0QXR0cmlidXRlIT09aSYmKHM9ZS5nZXRBdHRyaWJ1dGUobikpLG51bGw9PXM/dDpzKTpudWxsIT09cj9vJiZhJiYic2V0ImluIG8mJihzPW8uc2V0KGUscixuKSkhPT10P3M6KGUuc2V0QXR0cmlidXRlKG4scisiIikscik6KGIucmVtb3ZlQXR0cihlLG4pLHQpKX0scmVtb3ZlQXR0cjpmdW5jdGlvbihlLHQpe3ZhciBuLHIsaT0wLG89dCYmdC5tYXRjaCh3KTtpZihvJiYxPT09ZS5ub2RlVHlwZSl3aGlsZShuPW9baSsrXSlyPWIucHJvcEZpeFtuXXx8bixKLnRlc3Qobik/IVEmJkcudGVzdChuKT9lW2IuY2FtZWxDYXNlKCJkZWZhdWx0LSIrbildPWVbcl09ITE6ZVtyXT0hMTpiLmF0dHIoZSxuLCIiKSxlLnJlbW92ZUF0dHJpYnV0ZShRP246cil9LGF0dHJIb29rczp7dHlwZTp7c2V0OmZ1bmN0aW9uKGUsdCl7aWYoIWIuc3VwcG9ydC5yYWRpb1ZhbHVlJiYicmFkaW8iPT09dCYmYi5ub2RlTmFtZShlLCJpbnB1dCIpKXt2YXIgbj1lLnZhbHVlO3JldHVybiBlLnNldEF0dHJpYnV0ZSgidHlwZSIsdCksbiYmKGUudmFsdWU9biksdH19fX0scHJvcEZpeDp7dGFiaW5kZXg6InRhYkluZGV4IixyZWFkb25seToicmVhZE9ubHkiLCJmb3IiOiJodG1sRm9yIiwiY2xhc3MiOiJjbGFzc05hbWUiLG1heGxlbmd0aDoibWF4TGVuZ3RoIixjZWxsc3BhY2luZzoiY2VsbFNwYWNpbmciLGNlbGxwYWRkaW5nOiJjZWxsUGFkZGluZyIscm93c3Bhbjoicm93U3BhbiIsY29sc3BhbjoiY29sU3BhbiIsdXNlbWFwOiJ1c2VNYXAiLGZyYW1lYm9yZGVyOiJmcmFtZUJvcmRlciIsY29udGVudGVkaXRhYmxlOiJjb250ZW50RWRpdGFibGUifSxwcm9wOmZ1bmN0aW9uKGUsbixyKXt2YXIgaSxvLGEscz1lLm5vZGVUeXBlO2lmKGUmJjMhPT1zJiY4IT09cyYmMiE9PXMpcmV0dXJuIGE9MSE9PXN8fCFiLmlzWE1MRG9jKGUpLGEmJihuPWIucHJvcEZpeFtuXXx8bixvPWIucHJvcEhvb2tzW25dKSxyIT09dD9vJiYic2V0ImluIG8mJihpPW8uc2V0KGUscixuKSkhPT10P2k6ZVtuXT1yOm8mJiJnZXQiaW4gbyYmbnVsbCE9PShpPW8uZ2V0KGUsbikpP2k6ZVtuXX0scHJvcEhvb2tzOnt0YWJJbmRleDp7Z2V0OmZ1bmN0aW9uKGUpe3ZhciBuPWUuZ2V0QXR0cmlidXRlTm9kZSgidGFiaW5kZXgiKTtyZXR1cm4gbiYmbi5zcGVjaWZpZWQ/cGFyc2VJbnQobi52YWx1ZSwxMCk6Vi50ZXN0KGUubm9kZU5hbWUpfHxZLnRlc3QoZS5ub2RlTmFtZSkmJmUuaHJlZj8wOnR9fX19KSx6PXtnZXQ6ZnVuY3Rpb24oZSxuKXt2YXIgcj1iLnByb3AoZSxuKSxpPSJib29sZWFuIj09dHlwZW9mIHImJmUuZ2V0QXR0cmlidXRlKG4pLG89ImJvb2xlYW4iPT10eXBlb2Ygcj9LJiZRP251bGwhPWk6Ry50ZXN0KG4pP2VbYi5jYW1lbENhc2UoImRlZmF1bHQtIituKV06ISFpOmUuZ2V0QXR0cmlidXRlTm9kZShuKTtyZXR1cm4gbyYmby52YWx1ZSE9PSExP24udG9Mb3dlckNhc2UoKTp0fSxzZXQ6ZnVuY3Rpb24oZSx0LG4pe3JldHVybiB0PT09ITE/Yi5yZW1vdmVBdHRyKGUsbik6SyYmUXx8IUcudGVzdChuKT9lLnNldEF0dHJpYnV0ZSghUSYmYi5wcm9wRml4W25dfHxuLG4pOmVbYi5jYW1lbENhc2UoImRlZmF1bHQtIituKV09ZVtuXT0hMCxufX0sSyYmUXx8KGIuYXR0ckhvb2tzLnZhbHVlPXtnZXQ6ZnVuY3Rpb24oZSxuKXt2YXIgcj1lLmdldEF0dHJpYnV0ZU5vZGUobik7cmV0dXJuIGIubm9kZU5hbWUoZSwiaW5wdXQiKT9lLmRlZmF1bHRWYWx1ZTpyJiZyLnNwZWNpZmllZD9yLnZhbHVlOnR9LHNldDpmdW5jdGlvbihlLG4scil7cmV0dXJuIGIubm9kZU5hbWUoZSwiaW5wdXQiKT8oZS5kZWZhdWx0VmFsdWU9bix0KTpJJiZJLnNldChlLG4scil9fSksUXx8KEk9Yi52YWxIb29rcy5idXR0b249e2dldDpmdW5jdGlvbihlLG4pe3ZhciByPWUuZ2V0QXR0cmlidXRlTm9kZShuKTtyZXR1cm4gciYmKCJpZCI9PT1ufHwibmFtZSI9PT1ufHwiY29vcmRzIj09PW4/IiIhPT1yLnZhbHVlOnIuc3BlY2lmaWVkKT9yLnZhbHVlOnR9LHNldDpmdW5jdGlvbihlLG4scil7dmFyIGk9ZS5nZXRBdHRyaWJ1dGVOb2RlKHIpO3JldHVybiBpfHxlLnNldEF0dHJpYnV0ZU5vZGUoaT1lLm93bmVyRG9jdW1lbnQuY3JlYXRlQXR0cmlidXRlKHIpKSxpLnZhbHVlPW4rPSIiLCJ2YWx1ZSI9PT1yfHxuPT09ZS5nZXRBdHRyaWJ1dGUocik/bjp0fX0sYi5hdHRySG9va3MuY29udGVudGVkaXRhYmxlPXtnZXQ6SS5nZXQsc2V0OmZ1bmN0aW9uKGUsdCxuKXtJLnNldChlLCIiPT09dD8hMTp0LG4pfX0sYi5lYWNoKFsid2lkdGgiLCJoZWlnaHQiXSxmdW5jdGlvbihlLG4pe2IuYXR0ckhvb2tzW25dPWIuZXh0ZW5kKGIuYXR0ckhvb2tzW25dLHtzZXQ6ZnVuY3Rpb24oZSxyKXtyZXR1cm4iIj09PXI/KGUuc2V0QXR0cmlidXRlKG4sImF1dG8iKSxyKTp0fX0pfSkpLGIuc3VwcG9ydC5ocmVmTm9ybWFsaXplZHx8KGIuZWFjaChbImhyZWYiLCJzcmMiLCJ3aWR0aCIsImhlaWdodCJdLGZ1bmN0aW9uKGUsbil7Yi5hdHRySG9va3Nbbl09Yi5leHRlbmQoYi5hdHRySG9va3Nbbl0se2dldDpmdW5jdGlvbihlKXt2YXIgcj1lLmdldEF0dHJpYnV0ZShuLDIpO3JldHVybiBudWxsPT1yP3Q6cn19KX0pLGIuZWFjaChbImhyZWYiLCJzcmMiXSxmdW5jdGlvbihlLHQpe2IucHJvcEhvb2tzW3RdPXtnZXQ6ZnVuY3Rpb24oZSl7cmV0dXJuIGUuZ2V0QXR0cmlidXRlKHQsNCl9fX0pKSxiLnN1cHBvcnQuc3R5bGV8fChiLmF0dHJIb29rcy5zdHlsZT17Z2V0OmZ1bmN0aW9uKGUpe3JldHVybiBlLnN0eWxlLmNzc1RleHR8fHR9LHNldDpmdW5jdGlvbihlLHQpe3JldHVybiBlLnN0eWxlLmNzc1RleHQ9dCsiIn19KSxiLnN1cHBvcnQub3B0U2VsZWN0ZWR8fChiLnByb3BIb29rcy5zZWxlY3RlZD1iLmV4dGVuZChiLnByb3BIb29rcy5zZWxlY3RlZCx7Z2V0OmZ1bmN0aW9uKGUpe3ZhciB0PWUucGFyZW50Tm9kZTtyZXR1cm4gdCYmKHQuc2VsZWN0ZWRJbmRleCx0LnBhcmVudE5vZGUmJnQucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4KSxudWxsfX0pKSxiLnN1cHBvcnQuZW5jdHlwZXx8KGIucHJvcEZpeC5lbmN0eXBlPSJlbmNvZGluZyIpLGIuc3VwcG9ydC5jaGVja09ufHxiLmVhY2goWyJyYWRpbyIsImNoZWNrYm94Il0sZnVuY3Rpb24oKXtiLnZhbEhvb2tzW3RoaXNdPXtnZXQ6ZnVuY3Rpb24oZSl7cmV0dXJuIG51bGw9PT1lLmdldEF0dHJpYnV0ZSgidmFsdWUiKT8ib24iOmUudmFsdWV9fX0pLGIuZWFjaChbInJhZGlvIiwiY2hlY2tib3giXSxmdW5jdGlvbigpe2IudmFsSG9va3NbdGhpc109Yi5leHRlbmQoYi52YWxIb29rc1t0aGlzXSx7c2V0OmZ1bmN0aW9uKGUsbil7cmV0dXJuIGIuaXNBcnJheShuKT9lLmNoZWNrZWQ9Yi5pbkFycmF5KGIoZSkudmFsKCksbik+PTA6dH19KX0pO3ZhciBaPS9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhKSQvaSxldD0vXmtleS8sdHQ9L14oPzptb3VzZXxjb250ZXh0bWVudSl8Y2xpY2svLG50PS9eKD86Zm9jdXNpbmZvY3VzfGZvY3Vzb3V0Ymx1cikkLyxydD0vXihbXi5dKikoPzpcLiguKyl8KSQvO2Z1bmN0aW9uIGl0KCl7cmV0dXJuITB9ZnVuY3Rpb24gb3QoKXtyZXR1cm4hMX1iLmV2ZW50PXtnbG9iYWw6e30sYWRkOmZ1bmN0aW9uKGUsbixyLG8sYSl7dmFyIHMsdSxsLGMscCxmLGQsaCxnLG0seSx2PWIuX2RhdGEoZSk7aWYodil7ci5oYW5kbGVyJiYoYz1yLHI9Yy5oYW5kbGVyLGE9Yy5zZWxlY3Rvciksci5ndWlkfHwoci5ndWlkPWIuZ3VpZCsrKSwodT12LmV2ZW50cyl8fCh1PXYuZXZlbnRzPXt9KSwoZj12LmhhbmRsZSl8fChmPXYuaGFuZGxlPWZ1bmN0aW9uKGUpe3JldHVybiB0eXBlb2YgYj09PWl8fGUmJmIuZXZlbnQudHJpZ2dlcmVkPT09ZS50eXBlP3Q6Yi5ldmVudC5kaXNwYXRjaC5hcHBseShmLmVsZW0sYXJndW1lbnRzKX0sZi5lbGVtPWUpLG49KG58fCIiKS5tYXRjaCh3KXx8WyIiXSxsPW4ubGVuZ3RoO3doaWxlKGwtLSlzPXJ0LmV4ZWMobltsXSl8fFtdLGc9eT1zWzFdLG09KHNbMl18fCIiKS5zcGxpdCgiLiIpLnNvcnQoKSxwPWIuZXZlbnQuc3BlY2lhbFtnXXx8e30sZz0oYT9wLmRlbGVnYXRlVHlwZTpwLmJpbmRUeXBlKXx8ZyxwPWIuZXZlbnQuc3BlY2lhbFtnXXx8e30sZD1iLmV4dGVuZCh7dHlwZTpnLG9yaWdUeXBlOnksZGF0YTpvLGhhbmRsZXI6cixndWlkOnIuZ3VpZCxzZWxlY3RvcjphLG5lZWRzQ29udGV4dDphJiZiLmV4cHIubWF0Y2gubmVlZHNDb250ZXh0LnRlc3QoYSksbmFtZXNwYWNlOm0uam9pbigiLiIpfSxjKSwoaD11W2ddKXx8KGg9dVtnXT1bXSxoLmRlbGVnYXRlQ291bnQ9MCxwLnNldHVwJiZwLnNldHVwLmNhbGwoZSxvLG0sZikhPT0hMXx8KGUuYWRkRXZlbnRMaXN0ZW5lcj9lLmFkZEV2ZW50TGlzdGVuZXIoZyxmLCExKTplLmF0dGFjaEV2ZW50JiZlLmF0dGFjaEV2ZW50KCJvbiIrZyxmKSkpLHAuYWRkJiYocC5hZGQuY2FsbChlLGQpLGQuaGFuZGxlci5ndWlkfHwoZC5oYW5kbGVyLmd1aWQ9ci5ndWlkKSksYT9oLnNwbGljZShoLmRlbGVnYXRlQ291bnQrKywwLGQpOmgucHVzaChkKSxiLmV2ZW50Lmdsb2JhbFtnXT0hMDtlPW51bGx9fSxyZW1vdmU6ZnVuY3Rpb24oZSx0LG4scixpKXt2YXIgbyxhLHMsdSxsLGMscCxmLGQsaCxnLG09Yi5oYXNEYXRhKGUpJiZiLl9kYXRhKGUpO2lmKG0mJihjPW0uZXZlbnRzKSl7dD0odHx8IiIpLm1hdGNoKHcpfHxbIiJdLGw9dC5sZW5ndGg7d2hpbGUobC0tKWlmKHM9cnQuZXhlYyh0W2xdKXx8W10sZD1nPXNbMV0saD0oc1syXXx8IiIpLnNwbGl0KCIuIikuc29ydCgpLGQpe3A9Yi5ldmVudC5zcGVjaWFsW2RdfHx7fSxkPShyP3AuZGVsZWdhdGVUeXBlOnAuYmluZFR5cGUpfHxkLGY9Y1tkXXx8W10scz1zWzJdJiZSZWdFeHAoIihefFxcLikiK2guam9pbigiXFwuKD86LipcXC58KSIpKyIoXFwufCQpIiksdT1vPWYubGVuZ3RoO3doaWxlKG8tLSlhPWZbb10sIWkmJmchPT1hLm9yaWdUeXBlfHxuJiZuLmd1aWQhPT1hLmd1aWR8fHMmJiFzLnRlc3QoYS5uYW1lc3BhY2UpfHxyJiZyIT09YS5zZWxlY3RvciYmKCIqKiIhPT1yfHwhYS5zZWxlY3Rvcil8fChmLnNwbGljZShvLDEpLGEuc2VsZWN0b3ImJmYuZGVsZWdhdGVDb3VudC0tLHAucmVtb3ZlJiZwLnJlbW92ZS5jYWxsKGUsYSkpO3UmJiFmLmxlbmd0aCYmKHAudGVhcmRvd24mJnAudGVhcmRvd24uY2FsbChlLGgsbS5oYW5kbGUpIT09ITF8fGIucmVtb3ZlRXZlbnQoZSxkLG0uaGFuZGxlKSxkZWxldGUgY1tkXSl9ZWxzZSBmb3IoZCBpbiBjKWIuZXZlbnQucmVtb3ZlKGUsZCt0W2xdLG4sciwhMCk7Yi5pc0VtcHR5T2JqZWN0KGMpJiYoZGVsZXRlIG0uaGFuZGxlLGIuX3JlbW92ZURhdGEoZSwiZXZlbnRzIikpfX0sdHJpZ2dlcjpmdW5jdGlvbihuLHIsaSxhKXt2YXIgcyx1LGwsYyxwLGYsZCxoPVtpfHxvXSxnPXkuY2FsbChuLCJ0eXBlIik/bi50eXBlOm4sbT15LmNhbGwobiwibmFtZXNwYWNlIik/bi5uYW1lc3BhY2Uuc3BsaXQoIi4iKTpbXTtpZihsPWY9aT1pfHxvLDMhPT1pLm5vZGVUeXBlJiY4IT09aS5ub2RlVHlwZSYmIW50LnRlc3QoZytiLmV2ZW50LnRyaWdnZXJlZCkmJihnLmluZGV4T2YoIi4iKT49MCYmKG09Zy5zcGxpdCgiLiIpLGc9bS5zaGlmdCgpLG0uc29ydCgpKSx1PTA+Zy5pbmRleE9mKCI6IikmJiJvbiIrZyxuPW5bYi5leHBhbmRvXT9uOm5ldyBiLkV2ZW50KGcsIm9iamVjdCI9PXR5cGVvZiBuJiZuKSxuLmlzVHJpZ2dlcj0hMCxuLm5hbWVzcGFjZT1tLmpvaW4oIi4iKSxuLm5hbWVzcGFjZV9yZT1uLm5hbWVzcGFjZT9SZWdFeHAoIihefFxcLikiK20uam9pbigiXFwuKD86LipcXC58KSIpKyIoXFwufCQpIik6bnVsbCxuLnJlc3VsdD10LG4udGFyZ2V0fHwobi50YXJnZXQ9aSkscj1udWxsPT1yP1tuXTpiLm1ha2VBcnJheShyLFtuXSkscD1iLmV2ZW50LnNwZWNpYWxbZ118fHt9LGF8fCFwLnRyaWdnZXJ8fHAudHJpZ2dlci5hcHBseShpLHIpIT09ITEpKXtpZighYSYmIXAubm9CdWJibGUmJiFiLmlzV2luZG93KGkpKXtmb3IoYz1wLmRlbGVnYXRlVHlwZXx8ZyxudC50ZXN0KGMrZyl8fChsPWwucGFyZW50Tm9kZSk7bDtsPWwucGFyZW50Tm9kZSloLnB1c2gobCksZj1sO2Y9PT0oaS5vd25lckRvY3VtZW50fHxvKSYmaC5wdXNoKGYuZGVmYXVsdFZpZXd8fGYucGFyZW50V2luZG93fHxlKX1kPTA7d2hpbGUoKGw9aFtkKytdKSYmIW4uaXNQcm9wYWdhdGlvblN0b3BwZWQoKSluLnR5cGU9ZD4xP2M6cC5iaW5kVHlwZXx8ZyxzPShiLl9kYXRhKGwsImV2ZW50cyIpfHx7fSlbbi50eXBlXSYmYi5fZGF0YShsLCJoYW5kbGUiKSxzJiZzLmFwcGx5KGwscikscz11JiZsW3VdLHMmJmIuYWNjZXB0RGF0YShsKSYmcy5hcHBseSYmcy5hcHBseShsLHIpPT09ITEmJm4ucHJldmVudERlZmF1bHQoKTtpZihuLnR5cGU9ZywhKGF8fG4uaXNEZWZhdWx0UHJldmVudGVkKCl8fHAuX2RlZmF1bHQmJnAuX2RlZmF1bHQuYXBwbHkoaS5vd25lckRvY3VtZW50LHIpIT09ITF8fCJjbGljayI9PT1nJiZiLm5vZGVOYW1lKGksImEiKXx8IWIuYWNjZXB0RGF0YShpKXx8IXV8fCFpW2ddfHxiLmlzV2luZG93KGkpKSl7Zj1pW3VdLGYmJihpW3VdPW51bGwpLGIuZXZlbnQudHJpZ2dlcmVkPWc7dHJ5e2lbZ10oKX1jYXRjaCh2KXt9Yi5ldmVudC50cmlnZ2VyZWQ9dCxmJiYoaVt1XT1mKX1yZXR1cm4gbi5yZXN1bHR9fSxkaXNwYXRjaDpmdW5jdGlvbihlKXtlPWIuZXZlbnQuZml4KGUpO3ZhciBuLHIsaSxvLGEscz1bXSx1PWguY2FsbChhcmd1bWVudHMpLGw9KGIuX2RhdGEodGhpcywiZXZlbnRzIil8fHt9KVtlLnR5cGVdfHxbXSxjPWIuZXZlbnQuc3BlY2lhbFtlLnR5cGVdfHx7fTtpZih1WzBdPWUsZS5kZWxlZ2F0ZVRhcmdldD10aGlzLCFjLnByZURpc3BhdGNofHxjLnByZURpc3BhdGNoLmNhbGwodGhpcyxlKSE9PSExKXtzPWIuZXZlbnQuaGFuZGxlcnMuY2FsbCh0aGlzLGUsbCksbj0wO3doaWxlKChvPXNbbisrXSkmJiFlLmlzUHJvcGFnYXRpb25TdG9wcGVkKCkpe2UuY3VycmVudFRhcmdldD1vLmVsZW0sYT0wO3doaWxlKChpPW8uaGFuZGxlcnNbYSsrXSkmJiFlLmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkKCkpKCFlLm5hbWVzcGFjZV9yZXx8ZS5uYW1lc3BhY2VfcmUudGVzdChpLm5hbWVzcGFjZSkpJiYoZS5oYW5kbGVPYmo9aSxlLmRhdGE9aS5kYXRhLHI9KChiLmV2ZW50LnNwZWNpYWxbaS5vcmlnVHlwZV18fHt9KS5oYW5kbGV8fGkuaGFuZGxlcikuYXBwbHkoby5lbGVtLHUpLHIhPT10JiYoZS5yZXN1bHQ9cik9PT0hMSYmKGUucHJldmVudERlZmF1bHQoKSxlLnN0b3BQcm9wYWdhdGlvbigpKSl9cmV0dXJuIGMucG9zdERpc3BhdGNoJiZjLnBvc3REaXNwYXRjaC5jYWxsKHRoaXMsZSksZS5yZXN1bHR9fSxoYW5kbGVyczpmdW5jdGlvbihlLG4pe3ZhciByLGksbyxhLHM9W10sdT1uLmRlbGVnYXRlQ291bnQsbD1lLnRhcmdldDtpZih1JiZsLm5vZGVUeXBlJiYoIWUuYnV0dG9ufHwiY2xpY2siIT09ZS50eXBlKSlmb3IoO2whPXRoaXM7bD1sLnBhcmVudE5vZGV8fHRoaXMpaWYoMT09PWwubm9kZVR5cGUmJihsLmRpc2FibGVkIT09ITB8fCJjbGljayIhPT1lLnR5cGUpKXtmb3Iobz1bXSxhPTA7dT5hO2ErKylpPW5bYV0scj1pLnNlbGVjdG9yKyIgIixvW3JdPT09dCYmKG9bcl09aS5uZWVkc0NvbnRleHQ/YihyLHRoaXMpLmluZGV4KGwpPj0wOmIuZmluZChyLHRoaXMsbnVsbCxbbF0pLmxlbmd0aCksb1tyXSYmby5wdXNoKGkpO28ubGVuZ3RoJiZzLnB1c2goe2VsZW06bCxoYW5kbGVyczpvfSl9cmV0dXJuIG4ubGVuZ3RoPnUmJnMucHVzaCh7ZWxlbTp0aGlzLGhhbmRsZXJzOm4uc2xpY2UodSl9KSxzfSxmaXg6ZnVuY3Rpb24oZSl7aWYoZVtiLmV4cGFuZG9dKXJldHVybiBlO3ZhciB0LG4scixpPWUudHlwZSxhPWUscz10aGlzLmZpeEhvb2tzW2ldO3N8fCh0aGlzLmZpeEhvb2tzW2ldPXM9dHQudGVzdChpKT90aGlzLm1vdXNlSG9va3M6ZXQudGVzdChpKT90aGlzLmtleUhvb2tzOnt9KSxyPXMucHJvcHM/dGhpcy5wcm9wcy5jb25jYXQocy5wcm9wcyk6dGhpcy5wcm9wcyxlPW5ldyBiLkV2ZW50KGEpLHQ9ci5sZW5ndGg7d2hpbGUodC0tKW49clt0XSxlW25dPWFbbl07cmV0dXJuIGUudGFyZ2V0fHwoZS50YXJnZXQ9YS5zcmNFbGVtZW50fHxvKSwzPT09ZS50YXJnZXQubm9kZVR5cGUmJihlLnRhcmdldD1lLnRhcmdldC5wYXJlbnROb2RlKSxlLm1ldGFLZXk9ISFlLm1ldGFLZXkscy5maWx0ZXI/cy5maWx0ZXIoZSxhKTplfSxwcm9wczoiYWx0S2V5IGJ1YmJsZXMgY2FuY2VsYWJsZSBjdHJsS2V5IGN1cnJlbnRUYXJnZXQgZXZlbnRQaGFzZSBtZXRhS2V5IHJlbGF0ZWRUYXJnZXQgc2hpZnRLZXkgdGFyZ2V0IHRpbWVTdGFtcCB2aWV3IHdoaWNoIi5zcGxpdCgiICIpLGZpeEhvb2tzOnt9LGtleUhvb2tzOntwcm9wczoiY2hhciBjaGFyQ29kZSBrZXkga2V5Q29kZSIuc3BsaXQoIiAiKSxmaWx0ZXI6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gbnVsbD09ZS53aGljaCYmKGUud2hpY2g9bnVsbCE9dC5jaGFyQ29kZT90LmNoYXJDb2RlOnQua2V5Q29kZSksZX19LG1vdXNlSG9va3M6e3Byb3BzOiJidXR0b24gYnV0dG9ucyBjbGllbnRYIGNsaWVudFkgZnJvbUVsZW1lbnQgb2Zmc2V0WCBvZmZzZXRZIHBhZ2VYIHBhZ2VZIHNjcmVlblggc2NyZWVuWSB0b0VsZW1lbnQiLnNwbGl0KCIgIiksZmlsdGVyOmZ1bmN0aW9uKGUsbil7dmFyIHIsaSxhLHM9bi5idXR0b24sdT1uLmZyb21FbGVtZW50O3JldHVybiBudWxsPT1lLnBhZ2VYJiZudWxsIT1uLmNsaWVudFgmJihpPWUudGFyZ2V0Lm93bmVyRG9jdW1lbnR8fG8sYT1pLmRvY3VtZW50RWxlbWVudCxyPWkuYm9keSxlLnBhZ2VYPW4uY2xpZW50WCsoYSYmYS5zY3JvbGxMZWZ0fHxyJiZyLnNjcm9sbExlZnR8fDApLShhJiZhLmNsaWVudExlZnR8fHImJnIuY2xpZW50TGVmdHx8MCksZS5wYWdlWT1uLmNsaWVudFkrKGEmJmEuc2Nyb2xsVG9wfHxyJiZyLnNjcm9sbFRvcHx8MCktKGEmJmEuY2xpZW50VG9wfHxyJiZyLmNsaWVudFRvcHx8MCkpLCFlLnJlbGF0ZWRUYXJnZXQmJnUmJihlLnJlbGF0ZWRUYXJnZXQ9dT09PWUudGFyZ2V0P24udG9FbGVtZW50OnUpLGUud2hpY2h8fHM9PT10fHwoZS53aGljaD0xJnM/MToyJnM/Mzo0JnM/MjowKSxlfX0sc3BlY2lhbDp7bG9hZDp7bm9CdWJibGU6ITB9LGNsaWNrOnt0cmlnZ2VyOmZ1bmN0aW9uKCl7cmV0dXJuIGIubm9kZU5hbWUodGhpcywiaW5wdXQiKSYmImNoZWNrYm94Ij09PXRoaXMudHlwZSYmdGhpcy5jbGljaz8odGhpcy5jbGljaygpLCExKTp0fX0sZm9jdXM6e3RyaWdnZXI6ZnVuY3Rpb24oKXtpZih0aGlzIT09by5hY3RpdmVFbGVtZW50JiZ0aGlzLmZvY3VzKXRyeXtyZXR1cm4gdGhpcy5mb2N1cygpLCExfWNhdGNoKGUpe319LGRlbGVnYXRlVHlwZToiZm9jdXNpbiJ9LGJsdXI6e3RyaWdnZXI6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcz09PW8uYWN0aXZlRWxlbWVudCYmdGhpcy5ibHVyPyh0aGlzLmJsdXIoKSwhMSk6dH0sZGVsZWdhdGVUeXBlOiJmb2N1c291dCJ9LGJlZm9yZXVubG9hZDp7cG9zdERpc3BhdGNoOmZ1bmN0aW9uKGUpe2UucmVzdWx0IT09dCYmKGUub3JpZ2luYWxFdmVudC5yZXR1cm5WYWx1ZT1lLnJlc3VsdCl9fX0sc2ltdWxhdGU6ZnVuY3Rpb24oZSx0LG4scil7dmFyIGk9Yi5leHRlbmQobmV3IGIuRXZlbnQsbix7dHlwZTplLGlzU2ltdWxhdGVkOiEwLG9yaWdpbmFsRXZlbnQ6e319KTtyP2IuZXZlbnQudHJpZ2dlcihpLG51bGwsdCk6Yi5ldmVudC5kaXNwYXRjaC5jYWxsKHQsaSksaS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSYmbi5wcmV2ZW50RGVmYXVsdCgpfX0sYi5yZW1vdmVFdmVudD1vLnJlbW92ZUV2ZW50TGlzdGVuZXI/ZnVuY3Rpb24oZSx0LG4pe2UucmVtb3ZlRXZlbnRMaXN0ZW5lciYmZS5yZW1vdmVFdmVudExpc3RlbmVyKHQsbiwhMSl9OmZ1bmN0aW9uKGUsdCxuKXt2YXIgcj0ib24iK3Q7ZS5kZXRhY2hFdmVudCYmKHR5cGVvZiBlW3JdPT09aSYmKGVbcl09bnVsbCksZS5kZXRhY2hFdmVudChyLG4pKX0sYi5FdmVudD1mdW5jdGlvbihlLG4pe3JldHVybiB0aGlzIGluc3RhbmNlb2YgYi5FdmVudD8oZSYmZS50eXBlPyh0aGlzLm9yaWdpbmFsRXZlbnQ9ZSx0aGlzLnR5cGU9ZS50eXBlLHRoaXMuaXNEZWZhdWx0UHJldmVudGVkPWUuZGVmYXVsdFByZXZlbnRlZHx8ZS5yZXR1cm5WYWx1ZT09PSExfHxlLmdldFByZXZlbnREZWZhdWx0JiZlLmdldFByZXZlbnREZWZhdWx0KCk/aXQ6b3QpOnRoaXMudHlwZT1lLG4mJmIuZXh0ZW5kKHRoaXMsbiksdGhpcy50aW1lU3RhbXA9ZSYmZS50aW1lU3RhbXB8fGIubm93KCksdGhpc1tiLmV4cGFuZG9dPSEwLHQpOm5ldyBiLkV2ZW50KGUsbil9LGIuRXZlbnQucHJvdG90eXBlPXtpc0RlZmF1bHRQcmV2ZW50ZWQ6b3QsaXNQcm9wYWdhdGlvblN0b3BwZWQ6b3QsaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQ6b3QscHJldmVudERlZmF1bHQ6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLm9yaWdpbmFsRXZlbnQ7dGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQ9aXQsZSYmKGUucHJldmVudERlZmF1bHQ/ZS5wcmV2ZW50RGVmYXVsdCgpOmUucmV0dXJuVmFsdWU9ITEpfSxzdG9wUHJvcGFnYXRpb246ZnVuY3Rpb24oKXt2YXIgZT10aGlzLm9yaWdpbmFsRXZlbnQ7dGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZD1pdCxlJiYoZS5zdG9wUHJvcGFnYXRpb24mJmUuc3RvcFByb3BhZ2F0aW9uKCksZS5jYW5jZWxCdWJibGU9ITApfSxzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb246ZnVuY3Rpb24oKXt0aGlzLmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkPWl0LHRoaXMuc3RvcFByb3BhZ2F0aW9uKCl9fSxiLmVhY2goe21vdXNlZW50ZXI6Im1vdXNlb3ZlciIsbW91c2VsZWF2ZToibW91c2VvdXQifSxmdW5jdGlvbihlLHQpe2IuZXZlbnQuc3BlY2lhbFtlXT17ZGVsZWdhdGVUeXBlOnQsYmluZFR5cGU6dCxoYW5kbGU6ZnVuY3Rpb24oZSl7dmFyIG4scj10aGlzLGk9ZS5yZWxhdGVkVGFyZ2V0LG89ZS5oYW5kbGVPYmo7CnJldHVybighaXx8aSE9PXImJiFiLmNvbnRhaW5zKHIsaSkpJiYoZS50eXBlPW8ub3JpZ1R5cGUsbj1vLmhhbmRsZXIuYXBwbHkodGhpcyxhcmd1bWVudHMpLGUudHlwZT10KSxufX19KSxiLnN1cHBvcnQuc3VibWl0QnViYmxlc3x8KGIuZXZlbnQuc3BlY2lhbC5zdWJtaXQ9e3NldHVwOmZ1bmN0aW9uKCl7cmV0dXJuIGIubm9kZU5hbWUodGhpcywiZm9ybSIpPyExOihiLmV2ZW50LmFkZCh0aGlzLCJjbGljay5fc3VibWl0IGtleXByZXNzLl9zdWJtaXQiLGZ1bmN0aW9uKGUpe3ZhciBuPWUudGFyZ2V0LHI9Yi5ub2RlTmFtZShuLCJpbnB1dCIpfHxiLm5vZGVOYW1lKG4sImJ1dHRvbiIpP24uZm9ybTp0O3ImJiFiLl9kYXRhKHIsInN1Ym1pdEJ1YmJsZXMiKSYmKGIuZXZlbnQuYWRkKHIsInN1Ym1pdC5fc3VibWl0IixmdW5jdGlvbihlKXtlLl9zdWJtaXRfYnViYmxlPSEwfSksYi5fZGF0YShyLCJzdWJtaXRCdWJibGVzIiwhMCkpfSksdCl9LHBvc3REaXNwYXRjaDpmdW5jdGlvbihlKXtlLl9zdWJtaXRfYnViYmxlJiYoZGVsZXRlIGUuX3N1Ym1pdF9idWJibGUsdGhpcy5wYXJlbnROb2RlJiYhZS5pc1RyaWdnZXImJmIuZXZlbnQuc2ltdWxhdGUoInN1Ym1pdCIsdGhpcy5wYXJlbnROb2RlLGUsITApKX0sdGVhcmRvd246ZnVuY3Rpb24oKXtyZXR1cm4gYi5ub2RlTmFtZSh0aGlzLCJmb3JtIik/ITE6KGIuZXZlbnQucmVtb3ZlKHRoaXMsIi5fc3VibWl0IiksdCl9fSksYi5zdXBwb3J0LmNoYW5nZUJ1YmJsZXN8fChiLmV2ZW50LnNwZWNpYWwuY2hhbmdlPXtzZXR1cDpmdW5jdGlvbigpe3JldHVybiBaLnRlc3QodGhpcy5ub2RlTmFtZSk/KCgiY2hlY2tib3giPT09dGhpcy50eXBlfHwicmFkaW8iPT09dGhpcy50eXBlKSYmKGIuZXZlbnQuYWRkKHRoaXMsInByb3BlcnR5Y2hhbmdlLl9jaGFuZ2UiLGZ1bmN0aW9uKGUpeyJjaGVja2VkIj09PWUub3JpZ2luYWxFdmVudC5wcm9wZXJ0eU5hbWUmJih0aGlzLl9qdXN0X2NoYW5nZWQ9ITApfSksYi5ldmVudC5hZGQodGhpcywiY2xpY2suX2NoYW5nZSIsZnVuY3Rpb24oZSl7dGhpcy5fanVzdF9jaGFuZ2VkJiYhZS5pc1RyaWdnZXImJih0aGlzLl9qdXN0X2NoYW5nZWQ9ITEpLGIuZXZlbnQuc2ltdWxhdGUoImNoYW5nZSIsdGhpcyxlLCEwKX0pKSwhMSk6KGIuZXZlbnQuYWRkKHRoaXMsImJlZm9yZWFjdGl2YXRlLl9jaGFuZ2UiLGZ1bmN0aW9uKGUpe3ZhciB0PWUudGFyZ2V0O1oudGVzdCh0Lm5vZGVOYW1lKSYmIWIuX2RhdGEodCwiY2hhbmdlQnViYmxlcyIpJiYoYi5ldmVudC5hZGQodCwiY2hhbmdlLl9jaGFuZ2UiLGZ1bmN0aW9uKGUpeyF0aGlzLnBhcmVudE5vZGV8fGUuaXNTaW11bGF0ZWR8fGUuaXNUcmlnZ2VyfHxiLmV2ZW50LnNpbXVsYXRlKCJjaGFuZ2UiLHRoaXMucGFyZW50Tm9kZSxlLCEwKX0pLGIuX2RhdGEodCwiY2hhbmdlQnViYmxlcyIsITApKX0pLHQpfSxoYW5kbGU6ZnVuY3Rpb24oZSl7dmFyIG49ZS50YXJnZXQ7cmV0dXJuIHRoaXMhPT1ufHxlLmlzU2ltdWxhdGVkfHxlLmlzVHJpZ2dlcnx8InJhZGlvIiE9PW4udHlwZSYmImNoZWNrYm94IiE9PW4udHlwZT9lLmhhbmRsZU9iai5oYW5kbGVyLmFwcGx5KHRoaXMsYXJndW1lbnRzKTp0fSx0ZWFyZG93bjpmdW5jdGlvbigpe3JldHVybiBiLmV2ZW50LnJlbW92ZSh0aGlzLCIuX2NoYW5nZSIpLCFaLnRlc3QodGhpcy5ub2RlTmFtZSl9fSksYi5zdXBwb3J0LmZvY3VzaW5CdWJibGVzfHxiLmVhY2goe2ZvY3VzOiJmb2N1c2luIixibHVyOiJmb2N1c291dCJ9LGZ1bmN0aW9uKGUsdCl7dmFyIG49MCxyPWZ1bmN0aW9uKGUpe2IuZXZlbnQuc2ltdWxhdGUodCxlLnRhcmdldCxiLmV2ZW50LmZpeChlKSwhMCl9O2IuZXZlbnQuc3BlY2lhbFt0XT17c2V0dXA6ZnVuY3Rpb24oKXswPT09bisrJiZvLmFkZEV2ZW50TGlzdGVuZXIoZSxyLCEwKX0sdGVhcmRvd246ZnVuY3Rpb24oKXswPT09LS1uJiZvLnJlbW92ZUV2ZW50TGlzdGVuZXIoZSxyLCEwKX19fSksYi5mbi5leHRlbmQoe29uOmZ1bmN0aW9uKGUsbixyLGksbyl7dmFyIGEscztpZigib2JqZWN0Ij09dHlwZW9mIGUpeyJzdHJpbmciIT10eXBlb2YgbiYmKHI9cnx8bixuPXQpO2ZvcihhIGluIGUpdGhpcy5vbihhLG4scixlW2FdLG8pO3JldHVybiB0aGlzfWlmKG51bGw9PXImJm51bGw9PWk/KGk9bixyPW49dCk6bnVsbD09aSYmKCJzdHJpbmciPT10eXBlb2Ygbj8oaT1yLHI9dCk6KGk9cixyPW4sbj10KSksaT09PSExKWk9b3Q7ZWxzZSBpZighaSlyZXR1cm4gdGhpcztyZXR1cm4gMT09PW8mJihzPWksaT1mdW5jdGlvbihlKXtyZXR1cm4gYigpLm9mZihlKSxzLmFwcGx5KHRoaXMsYXJndW1lbnRzKX0saS5ndWlkPXMuZ3VpZHx8KHMuZ3VpZD1iLmd1aWQrKykpLHRoaXMuZWFjaChmdW5jdGlvbigpe2IuZXZlbnQuYWRkKHRoaXMsZSxpLHIsbil9KX0sb25lOmZ1bmN0aW9uKGUsdCxuLHIpe3JldHVybiB0aGlzLm9uKGUsdCxuLHIsMSl9LG9mZjpmdW5jdGlvbihlLG4scil7dmFyIGksbztpZihlJiZlLnByZXZlbnREZWZhdWx0JiZlLmhhbmRsZU9iailyZXR1cm4gaT1lLmhhbmRsZU9iaixiKGUuZGVsZWdhdGVUYXJnZXQpLm9mZihpLm5hbWVzcGFjZT9pLm9yaWdUeXBlKyIuIitpLm5hbWVzcGFjZTppLm9yaWdUeXBlLGkuc2VsZWN0b3IsaS5oYW5kbGVyKSx0aGlzO2lmKCJvYmplY3QiPT10eXBlb2YgZSl7Zm9yKG8gaW4gZSl0aGlzLm9mZihvLG4sZVtvXSk7cmV0dXJuIHRoaXN9cmV0dXJuKG49PT0hMXx8ImZ1bmN0aW9uIj09dHlwZW9mIG4pJiYocj1uLG49dCkscj09PSExJiYocj1vdCksdGhpcy5lYWNoKGZ1bmN0aW9uKCl7Yi5ldmVudC5yZW1vdmUodGhpcyxlLHIsbil9KX0sYmluZDpmdW5jdGlvbihlLHQsbil7cmV0dXJuIHRoaXMub24oZSxudWxsLHQsbil9LHVuYmluZDpmdW5jdGlvbihlLHQpe3JldHVybiB0aGlzLm9mZihlLG51bGwsdCl9LGRlbGVnYXRlOmZ1bmN0aW9uKGUsdCxuLHIpe3JldHVybiB0aGlzLm9uKHQsZSxuLHIpfSx1bmRlbGVnYXRlOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gMT09PWFyZ3VtZW50cy5sZW5ndGg/dGhpcy5vZmYoZSwiKioiKTp0aGlzLm9mZih0LGV8fCIqKiIsbil9LHRyaWdnZXI6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7Yi5ldmVudC50cmlnZ2VyKGUsdCx0aGlzKX0pfSx0cmlnZ2VySGFuZGxlcjpmdW5jdGlvbihlLG4pe3ZhciByPXRoaXNbMF07cmV0dXJuIHI/Yi5ldmVudC50cmlnZ2VyKGUsbixyLCEwKTp0fX0pLGZ1bmN0aW9uKGUsdCl7dmFyIG4scixpLG8sYSxzLHUsbCxjLHAsZixkLGgsZyxtLHksdix4PSJzaXp6bGUiKy1uZXcgRGF0ZSx3PWUuZG9jdW1lbnQsVD17fSxOPTAsQz0wLGs9aXQoKSxFPWl0KCksUz1pdCgpLEE9dHlwZW9mIHQsaj0xPDwzMSxEPVtdLEw9RC5wb3AsSD1ELnB1c2gscT1ELnNsaWNlLE09RC5pbmRleE9mfHxmdW5jdGlvbihlKXt2YXIgdD0wLG49dGhpcy5sZW5ndGg7Zm9yKDtuPnQ7dCsrKWlmKHRoaXNbdF09PT1lKXJldHVybiB0O3JldHVybi0xfSxfPSJbXFx4MjBcXHRcXHJcXG5cXGZdIixGPSIoPzpcXFxcLnxbXFx3LV18W15cXHgwMC1cXHhhMF0pKyIsTz1GLnJlcGxhY2UoInciLCJ3IyIpLEI9IihbKl4kfCF+XT89KSIsUD0iXFxbIitfKyIqKCIrRisiKSIrXysiKig/OiIrQitfKyIqKD86KFsnXCJdKSgoPzpcXFxcLnxbXlxcXFxdKSo/KVxcM3woIitPKyIpfCl8KSIrXysiKlxcXSIsUj0iOigiK0YrIikoPzpcXCgoKFsnXCJdKSgoPzpcXFxcLnxbXlxcXFxdKSo/KVxcM3woKD86XFxcXC58W15cXFxcKClbXFxdXXwiK1AucmVwbGFjZSgzLDgpKyIpKil8LiopXFwpfCkiLFc9UmVnRXhwKCJeIitfKyIrfCgoPzpefFteXFxcXF0pKD86XFxcXC4pKikiK18rIiskIiwiZyIpLCQ9UmVnRXhwKCJeIitfKyIqLCIrXysiKiIpLEk9UmVnRXhwKCJeIitfKyIqKFtcXHgyMFxcdFxcclxcblxcZj4rfl0pIitfKyIqIiksej1SZWdFeHAoUiksWD1SZWdFeHAoIl4iK08rIiQiKSxVPXtJRDpSZWdFeHAoIl4jKCIrRisiKSIpLENMQVNTOlJlZ0V4cCgiXlxcLigiK0YrIikiKSxOQU1FOlJlZ0V4cCgiXlxcW25hbWU9WydcIl0/KCIrRisiKVsnXCJdP1xcXSIpLFRBRzpSZWdFeHAoIl4oIitGLnJlcGxhY2UoInciLCJ3KiIpKyIpIiksQVRUUjpSZWdFeHAoIl4iK1ApLFBTRVVETzpSZWdFeHAoIl4iK1IpLENISUxEOlJlZ0V4cCgiXjoob25seXxmaXJzdHxsYXN0fG50aHxudGgtbGFzdCktKGNoaWxkfG9mLXR5cGUpKD86XFwoIitfKyIqKGV2ZW58b2RkfCgoWystXXwpKFxcZCopbnwpIitfKyIqKD86KFsrLV18KSIrXysiKihcXGQrKXwpKSIrXysiKlxcKXwpIiwiaSIpLG5lZWRzQ29udGV4dDpSZWdFeHAoIl4iK18rIipbPit+XXw6KGV2ZW58b2RkfGVxfGd0fGx0fG50aHxmaXJzdHxsYXN0KSg/OlxcKCIrXysiKigoPzotXFxkKT9cXGQqKSIrXysiKlxcKXwpKD89W14tXXwkKSIsImkiKX0sVj0vW1x4MjBcdFxyXG5cZl0qWyt+XS8sWT0vXltee10rXHtccypcW25hdGl2ZSBjb2RlLyxKPS9eKD86IyhbXHctXSspfChcdyspfFwuKFtcdy1dKykpJC8sRz0vXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b24pJC9pLFE9L15oXGQkL2ksSz0vJ3xcXC9nLFo9L1w9W1x4MjBcdFxyXG5cZl0qKFteJyJcXV0qKVtceDIwXHRcclxuXGZdKlxdL2csZXQ9L1xcKFtcZGEtZkEtRl17MSw2fVtceDIwXHRcclxuXGZdP3wuKS9nLHR0PWZ1bmN0aW9uKGUsdCl7dmFyIG49IjB4Iit0LTY1NTM2O3JldHVybiBuIT09bj90OjA+bj9TdHJpbmcuZnJvbUNoYXJDb2RlKG4rNjU1MzYpOlN0cmluZy5mcm9tQ2hhckNvZGUoNTUyOTZ8bj4+MTAsNTYzMjB8MTAyMyZuKX07dHJ5e3EuY2FsbCh3LmRvY3VtZW50RWxlbWVudC5jaGlsZE5vZGVzLDApWzBdLm5vZGVUeXBlfWNhdGNoKG50KXtxPWZ1bmN0aW9uKGUpe3ZhciB0LG49W107d2hpbGUodD10aGlzW2UrK10pbi5wdXNoKHQpO3JldHVybiBufX1mdW5jdGlvbiBydChlKXtyZXR1cm4gWS50ZXN0KGUrIiIpfWZ1bmN0aW9uIGl0KCl7dmFyIGUsdD1bXTtyZXR1cm4gZT1mdW5jdGlvbihuLHIpe3JldHVybiB0LnB1c2gobis9IiAiKT5pLmNhY2hlTGVuZ3RoJiZkZWxldGUgZVt0LnNoaWZ0KCldLGVbbl09cn19ZnVuY3Rpb24gb3QoZSl7cmV0dXJuIGVbeF09ITAsZX1mdW5jdGlvbiBhdChlKXt2YXIgdD1wLmNyZWF0ZUVsZW1lbnQoImRpdiIpO3RyeXtyZXR1cm4gZSh0KX1jYXRjaChuKXtyZXR1cm4hMX1maW5hbGx5e3Q9bnVsbH19ZnVuY3Rpb24gc3QoZSx0LG4scil7dmFyIGksbyxhLHMsdSxsLGYsZyxtLHY7aWYoKHQ/dC5vd25lckRvY3VtZW50fHx0OncpIT09cCYmYyh0KSx0PXR8fHAsbj1ufHxbXSwhZXx8InN0cmluZyIhPXR5cGVvZiBlKXJldHVybiBuO2lmKDEhPT0ocz10Lm5vZGVUeXBlKSYmOSE9PXMpcmV0dXJuW107aWYoIWQmJiFyKXtpZihpPUouZXhlYyhlKSlpZihhPWlbMV0pe2lmKDk9PT1zKXtpZihvPXQuZ2V0RWxlbWVudEJ5SWQoYSksIW98fCFvLnBhcmVudE5vZGUpcmV0dXJuIG47aWYoby5pZD09PWEpcmV0dXJuIG4ucHVzaChvKSxufWVsc2UgaWYodC5vd25lckRvY3VtZW50JiYobz10Lm93bmVyRG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYSkpJiZ5KHQsbykmJm8uaWQ9PT1hKXJldHVybiBuLnB1c2gobyksbn1lbHNle2lmKGlbMl0pcmV0dXJuIEguYXBwbHkobixxLmNhbGwodC5nZXRFbGVtZW50c0J5VGFnTmFtZShlKSwwKSksbjtpZigoYT1pWzNdKSYmVC5nZXRCeUNsYXNzTmFtZSYmdC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKXJldHVybiBILmFwcGx5KG4scS5jYWxsKHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShhKSwwKSksbn1pZihULnFzYSYmIWgudGVzdChlKSl7aWYoZj0hMCxnPXgsbT10LHY9OT09PXMmJmUsMT09PXMmJiJvYmplY3QiIT09dC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKXtsPWZ0KGUpLChmPXQuZ2V0QXR0cmlidXRlKCJpZCIpKT9nPWYucmVwbGFjZShLLCJcXCQmIik6dC5zZXRBdHRyaWJ1dGUoImlkIixnKSxnPSJbaWQ9JyIrZysiJ10gIix1PWwubGVuZ3RoO3doaWxlKHUtLSlsW3VdPWcrZHQobFt1XSk7bT1WLnRlc3QoZSkmJnQucGFyZW50Tm9kZXx8dCx2PWwuam9pbigiLCIpfWlmKHYpdHJ5e3JldHVybiBILmFwcGx5KG4scS5jYWxsKG0ucXVlcnlTZWxlY3RvckFsbCh2KSwwKSksbn1jYXRjaChiKXt9ZmluYWxseXtmfHx0LnJlbW92ZUF0dHJpYnV0ZSgiaWQiKX19fXJldHVybiB3dChlLnJlcGxhY2UoVywiJDEiKSx0LG4scil9YT1zdC5pc1hNTD1mdW5jdGlvbihlKXt2YXIgdD1lJiYoZS5vd25lckRvY3VtZW50fHxlKS5kb2N1bWVudEVsZW1lbnQ7cmV0dXJuIHQ/IkhUTUwiIT09dC5ub2RlTmFtZTohMX0sYz1zdC5zZXREb2N1bWVudD1mdW5jdGlvbihlKXt2YXIgbj1lP2Uub3duZXJEb2N1bWVudHx8ZTp3O3JldHVybiBuIT09cCYmOT09PW4ubm9kZVR5cGUmJm4uZG9jdW1lbnRFbGVtZW50PyhwPW4sZj1uLmRvY3VtZW50RWxlbWVudCxkPWEobiksVC50YWdOYW1lTm9Db21tZW50cz1hdChmdW5jdGlvbihlKXtyZXR1cm4gZS5hcHBlbmRDaGlsZChuLmNyZWF0ZUNvbW1lbnQoIiIpKSwhZS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpLmxlbmd0aH0pLFQuYXR0cmlidXRlcz1hdChmdW5jdGlvbihlKXtlLmlubmVySFRNTD0iPHNlbGVjdD48L3NlbGVjdD4iO3ZhciB0PXR5cGVvZiBlLmxhc3RDaGlsZC5nZXRBdHRyaWJ1dGUoIm11bHRpcGxlIik7cmV0dXJuImJvb2xlYW4iIT09dCYmInN0cmluZyIhPT10fSksVC5nZXRCeUNsYXNzTmFtZT1hdChmdW5jdGlvbihlKXtyZXR1cm4gZS5pbm5lckhUTUw9IjxkaXYgY2xhc3M9J2hpZGRlbiBlJz48L2Rpdj48ZGl2IGNsYXNzPSdoaWRkZW4nPjwvZGl2PiIsZS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lJiZlLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoImUiKS5sZW5ndGg/KGUubGFzdENoaWxkLmNsYXNzTmFtZT0iZSIsMj09PWUuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgiZSIpLmxlbmd0aCk6ITF9KSxULmdldEJ5TmFtZT1hdChmdW5jdGlvbihlKXtlLmlkPXgrMCxlLmlubmVySFRNTD0iPGEgbmFtZT0nIit4KyInPjwvYT48ZGl2IG5hbWU9JyIreCsiJz48L2Rpdj4iLGYuaW5zZXJ0QmVmb3JlKGUsZi5maXJzdENoaWxkKTt2YXIgdD1uLmdldEVsZW1lbnRzQnlOYW1lJiZuLmdldEVsZW1lbnRzQnlOYW1lKHgpLmxlbmd0aD09PTIrbi5nZXRFbGVtZW50c0J5TmFtZSh4KzApLmxlbmd0aDtyZXR1cm4gVC5nZXRJZE5vdE5hbWU9IW4uZ2V0RWxlbWVudEJ5SWQoeCksZi5yZW1vdmVDaGlsZChlKSx0fSksaS5hdHRySGFuZGxlPWF0KGZ1bmN0aW9uKGUpe3JldHVybiBlLmlubmVySFRNTD0iPGEgaHJlZj0nIyc+PC9hPiIsZS5maXJzdENoaWxkJiZ0eXBlb2YgZS5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSE9PUEmJiIjIj09PWUuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoImhyZWYiKX0pP3t9OntocmVmOmZ1bmN0aW9uKGUpe3JldHVybiBlLmdldEF0dHJpYnV0ZSgiaHJlZiIsMil9LHR5cGU6ZnVuY3Rpb24oZSl7cmV0dXJuIGUuZ2V0QXR0cmlidXRlKCJ0eXBlIil9fSxULmdldElkTm90TmFtZT8oaS5maW5kLklEPWZ1bmN0aW9uKGUsdCl7aWYodHlwZW9mIHQuZ2V0RWxlbWVudEJ5SWQhPT1BJiYhZCl7dmFyIG49dC5nZXRFbGVtZW50QnlJZChlKTtyZXR1cm4gbiYmbi5wYXJlbnROb2RlP1tuXTpbXX19LGkuZmlsdGVyLklEPWZ1bmN0aW9uKGUpe3ZhciB0PWUucmVwbGFjZShldCx0dCk7cmV0dXJuIGZ1bmN0aW9uKGUpe3JldHVybiBlLmdldEF0dHJpYnV0ZSgiaWQiKT09PXR9fSk6KGkuZmluZC5JRD1mdW5jdGlvbihlLG4pe2lmKHR5cGVvZiBuLmdldEVsZW1lbnRCeUlkIT09QSYmIWQpe3ZhciByPW4uZ2V0RWxlbWVudEJ5SWQoZSk7cmV0dXJuIHI/ci5pZD09PWV8fHR5cGVvZiByLmdldEF0dHJpYnV0ZU5vZGUhPT1BJiZyLmdldEF0dHJpYnV0ZU5vZGUoImlkIikudmFsdWU9PT1lP1tyXTp0OltdfX0saS5maWx0ZXIuSUQ9ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5yZXBsYWNlKGV0LHR0KTtyZXR1cm4gZnVuY3Rpb24oZSl7dmFyIG49dHlwZW9mIGUuZ2V0QXR0cmlidXRlTm9kZSE9PUEmJmUuZ2V0QXR0cmlidXRlTm9kZSgiaWQiKTtyZXR1cm4gbiYmbi52YWx1ZT09PXR9fSksaS5maW5kLlRBRz1ULnRhZ05hbWVOb0NvbW1lbnRzP2Z1bmN0aW9uKGUsbil7cmV0dXJuIHR5cGVvZiBuLmdldEVsZW1lbnRzQnlUYWdOYW1lIT09QT9uLmdldEVsZW1lbnRzQnlUYWdOYW1lKGUpOnR9OmZ1bmN0aW9uKGUsdCl7dmFyIG4scj1bXSxpPTAsbz10LmdldEVsZW1lbnRzQnlUYWdOYW1lKGUpO2lmKCIqIj09PWUpe3doaWxlKG49b1tpKytdKTE9PT1uLm5vZGVUeXBlJiZyLnB1c2gobik7cmV0dXJuIHJ9cmV0dXJuIG99LGkuZmluZC5OQU1FPVQuZ2V0QnlOYW1lJiZmdW5jdGlvbihlLG4pe3JldHVybiB0eXBlb2Ygbi5nZXRFbGVtZW50c0J5TmFtZSE9PUE/bi5nZXRFbGVtZW50c0J5TmFtZShuYW1lKTp0fSxpLmZpbmQuQ0xBU1M9VC5nZXRCeUNsYXNzTmFtZSYmZnVuY3Rpb24oZSxuKXtyZXR1cm4gdHlwZW9mIG4uZ2V0RWxlbWVudHNCeUNsYXNzTmFtZT09PUF8fGQ/dDpuLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoZSl9LGc9W10saD1bIjpmb2N1cyJdLChULnFzYT1ydChuLnF1ZXJ5U2VsZWN0b3JBbGwpKSYmKGF0KGZ1bmN0aW9uKGUpe2UuaW5uZXJIVE1MPSI8c2VsZWN0PjxvcHRpb24gc2VsZWN0ZWQ9Jyc+PC9vcHRpb24+PC9zZWxlY3Q+IixlLnF1ZXJ5U2VsZWN0b3JBbGwoIltzZWxlY3RlZF0iKS5sZW5ndGh8fGgucHVzaCgiXFxbIitfKyIqKD86Y2hlY2tlZHxkaXNhYmxlZHxpc21hcHxtdWx0aXBsZXxyZWFkb25seXxzZWxlY3RlZHx2YWx1ZSkiKSxlLnF1ZXJ5U2VsZWN0b3JBbGwoIjpjaGVja2VkIikubGVuZ3RofHxoLnB1c2goIjpjaGVja2VkIil9KSxhdChmdW5jdGlvbihlKXtlLmlubmVySFRNTD0iPGlucHV0IHR5cGU9J2hpZGRlbicgaT0nJy8+IixlLnF1ZXJ5U2VsZWN0b3JBbGwoIltpXj0nJ10iKS5sZW5ndGgmJmgucHVzaCgiWypeJF09IitfKyIqKD86XCJcInwnJykiKSxlLnF1ZXJ5U2VsZWN0b3JBbGwoIjplbmFibGVkIikubGVuZ3RofHxoLnB1c2goIjplbmFibGVkIiwiOmRpc2FibGVkIiksZS5xdWVyeVNlbGVjdG9yQWxsKCIqLDp4IiksaC5wdXNoKCIsLio6Iil9KSksKFQubWF0Y2hlc1NlbGVjdG9yPXJ0KG09Zi5tYXRjaGVzU2VsZWN0b3J8fGYubW96TWF0Y2hlc1NlbGVjdG9yfHxmLndlYmtpdE1hdGNoZXNTZWxlY3Rvcnx8Zi5vTWF0Y2hlc1NlbGVjdG9yfHxmLm1zTWF0Y2hlc1NlbGVjdG9yKSkmJmF0KGZ1bmN0aW9uKGUpe1QuZGlzY29ubmVjdGVkTWF0Y2g9bS5jYWxsKGUsImRpdiIpLG0uY2FsbChlLCJbcyE9JyddOngiKSxnLnB1c2goIiE9IixSKX0pLGg9UmVnRXhwKGguam9pbigifCIpKSxnPVJlZ0V4cChnLmpvaW4oInwiKSkseT1ydChmLmNvbnRhaW5zKXx8Zi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbj9mdW5jdGlvbihlLHQpe3ZhciBuPTk9PT1lLm5vZGVUeXBlP2UuZG9jdW1lbnRFbGVtZW50OmUscj10JiZ0LnBhcmVudE5vZGU7cmV0dXJuIGU9PT1yfHwhKCFyfHwxIT09ci5ub2RlVHlwZXx8IShuLmNvbnRhaW5zP24uY29udGFpbnMocik6ZS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiYmMTYmZS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihyKSkpfTpmdW5jdGlvbihlLHQpe2lmKHQpd2hpbGUodD10LnBhcmVudE5vZGUpaWYodD09PWUpcmV0dXJuITA7cmV0dXJuITF9LHY9Zi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbj9mdW5jdGlvbihlLHQpe3ZhciByO3JldHVybiBlPT09dD8odT0hMCwwKToocj10LmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uJiZlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uJiZlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKHQpKT8xJnJ8fGUucGFyZW50Tm9kZSYmMTE9PT1lLnBhcmVudE5vZGUubm9kZVR5cGU/ZT09PW58fHkodyxlKT8tMTp0PT09bnx8eSh3LHQpPzE6MDo0JnI/LTE6MTplLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uPy0xOjF9OmZ1bmN0aW9uKGUsdCl7dmFyIHIsaT0wLG89ZS5wYXJlbnROb2RlLGE9dC5wYXJlbnROb2RlLHM9W2VdLGw9W3RdO2lmKGU9PT10KXJldHVybiB1PSEwLDA7aWYoIW98fCFhKXJldHVybiBlPT09bj8tMTp0PT09bj8xOm8/LTE6YT8xOjA7aWYobz09PWEpcmV0dXJuIHV0KGUsdCk7cj1lO3doaWxlKHI9ci5wYXJlbnROb2RlKXMudW5zaGlmdChyKTtyPXQ7d2hpbGUocj1yLnBhcmVudE5vZGUpbC51bnNoaWZ0KHIpO3doaWxlKHNbaV09PT1sW2ldKWkrKztyZXR1cm4gaT91dChzW2ldLGxbaV0pOnNbaV09PT13Py0xOmxbaV09PT13PzE6MH0sdT0hMSxbMCwwXS5zb3J0KHYpLFQuZGV0ZWN0RHVwbGljYXRlcz11LHApOnB9LHN0Lm1hdGNoZXM9ZnVuY3Rpb24oZSx0KXtyZXR1cm4gc3QoZSxudWxsLG51bGwsdCl9LHN0Lm1hdGNoZXNTZWxlY3Rvcj1mdW5jdGlvbihlLHQpe2lmKChlLm93bmVyRG9jdW1lbnR8fGUpIT09cCYmYyhlKSx0PXQucmVwbGFjZShaLCI9JyQxJ10iKSwhKCFULm1hdGNoZXNTZWxlY3Rvcnx8ZHx8ZyYmZy50ZXN0KHQpfHxoLnRlc3QodCkpKXRyeXt2YXIgbj1tLmNhbGwoZSx0KTtpZihufHxULmRpc2Nvbm5lY3RlZE1hdGNofHxlLmRvY3VtZW50JiYxMSE9PWUuZG9jdW1lbnQubm9kZVR5cGUpcmV0dXJuIG59Y2F0Y2gocil7fXJldHVybiBzdCh0LHAsbnVsbCxbZV0pLmxlbmd0aD4wfSxzdC5jb250YWlucz1mdW5jdGlvbihlLHQpe3JldHVybihlLm93bmVyRG9jdW1lbnR8fGUpIT09cCYmYyhlKSx5KGUsdCl9LHN0LmF0dHI9ZnVuY3Rpb24oZSx0KXt2YXIgbjtyZXR1cm4oZS5vd25lckRvY3VtZW50fHxlKSE9PXAmJmMoZSksZHx8KHQ9dC50b0xvd2VyQ2FzZSgpKSwobj1pLmF0dHJIYW5kbGVbdF0pP24oZSk6ZHx8VC5hdHRyaWJ1dGVzP2UuZ2V0QXR0cmlidXRlKHQpOigobj1lLmdldEF0dHJpYnV0ZU5vZGUodCkpfHxlLmdldEF0dHJpYnV0ZSh0KSkmJmVbdF09PT0hMD90Om4mJm4uc3BlY2lmaWVkP24udmFsdWU6bnVsbH0sc3QuZXJyb3I9ZnVuY3Rpb24oZSl7dGhyb3cgRXJyb3IoIlN5bnRheCBlcnJvciwgdW5yZWNvZ25pemVkIGV4cHJlc3Npb246ICIrZSl9LHN0LnVuaXF1ZVNvcnQ9ZnVuY3Rpb24oZSl7dmFyIHQsbj1bXSxyPTEsaT0wO2lmKHU9IVQuZGV0ZWN0RHVwbGljYXRlcyxlLnNvcnQodiksdSl7Zm9yKDt0PWVbcl07cisrKXQ9PT1lW3ItMV0mJihpPW4ucHVzaChyKSk7d2hpbGUoaS0tKWUuc3BsaWNlKG5baV0sMSl9cmV0dXJuIGV9O2Z1bmN0aW9uIHV0KGUsdCl7dmFyIG49dCYmZSxyPW4mJih+dC5zb3VyY2VJbmRleHx8aiktKH5lLnNvdXJjZUluZGV4fHxqKTtpZihyKXJldHVybiByO2lmKG4pd2hpbGUobj1uLm5leHRTaWJsaW5nKWlmKG49PT10KXJldHVybi0xO3JldHVybiBlPzE6LTF9ZnVuY3Rpb24gbHQoZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3ZhciBuPXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtyZXR1cm4iaW5wdXQiPT09biYmdC50eXBlPT09ZX19ZnVuY3Rpb24gY3QoZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3ZhciBuPXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtyZXR1cm4oImlucHV0Ij09PW58fCJidXR0b24iPT09bikmJnQudHlwZT09PWV9fWZ1bmN0aW9uIHB0KGUpe3JldHVybiBvdChmdW5jdGlvbih0KXtyZXR1cm4gdD0rdCxvdChmdW5jdGlvbihuLHIpe3ZhciBpLG89ZShbXSxuLmxlbmd0aCx0KSxhPW8ubGVuZ3RoO3doaWxlKGEtLSluW2k9b1thXV0mJihuW2ldPSEocltpXT1uW2ldKSl9KX0pfW89c3QuZ2V0VGV4dD1mdW5jdGlvbihlKXt2YXIgdCxuPSIiLHI9MCxpPWUubm9kZVR5cGU7aWYoaSl7aWYoMT09PWl8fDk9PT1pfHwxMT09PWkpe2lmKCJzdHJpbmciPT10eXBlb2YgZS50ZXh0Q29udGVudClyZXR1cm4gZS50ZXh0Q29udGVudDtmb3IoZT1lLmZpcnN0Q2hpbGQ7ZTtlPWUubmV4dFNpYmxpbmcpbis9byhlKX1lbHNlIGlmKDM9PT1pfHw0PT09aSlyZXR1cm4gZS5ub2RlVmFsdWV9ZWxzZSBmb3IoO3Q9ZVtyXTtyKyspbis9byh0KTtyZXR1cm4gbn0saT1zdC5zZWxlY3RvcnM9e2NhY2hlTGVuZ3RoOjUwLGNyZWF0ZVBzZXVkbzpvdCxtYXRjaDpVLGZpbmQ6e30scmVsYXRpdmU6eyI+Ijp7ZGlyOiJwYXJlbnROb2RlIixmaXJzdDohMH0sIiAiOntkaXI6InBhcmVudE5vZGUifSwiKyI6e2RpcjoicHJldmlvdXNTaWJsaW5nIixmaXJzdDohMH0sIn4iOntkaXI6InByZXZpb3VzU2libGluZyJ9fSxwcmVGaWx0ZXI6e0FUVFI6ZnVuY3Rpb24oZSl7cmV0dXJuIGVbMV09ZVsxXS5yZXBsYWNlKGV0LHR0KSxlWzNdPShlWzRdfHxlWzVdfHwiIikucmVwbGFjZShldCx0dCksIn49Ij09PWVbMl0mJihlWzNdPSIgIitlWzNdKyIgIiksZS5zbGljZSgwLDQpfSxDSElMRDpmdW5jdGlvbihlKXtyZXR1cm4gZVsxXT1lWzFdLnRvTG93ZXJDYXNlKCksIm50aCI9PT1lWzFdLnNsaWNlKDAsMyk/KGVbM118fHN0LmVycm9yKGVbMF0pLGVbNF09KyhlWzRdP2VbNV0rKGVbNl18fDEpOjIqKCJldmVuIj09PWVbM118fCJvZGQiPT09ZVszXSkpLGVbNV09KyhlWzddK2VbOF18fCJvZGQiPT09ZVszXSkpOmVbM10mJnN0LmVycm9yKGVbMF0pLGV9LFBTRVVETzpmdW5jdGlvbihlKXt2YXIgdCxuPSFlWzVdJiZlWzJdO3JldHVybiBVLkNISUxELnRlc3QoZVswXSk/bnVsbDooZVs0XT9lWzJdPWVbNF06biYmei50ZXN0KG4pJiYodD1mdChuLCEwKSkmJih0PW4uaW5kZXhPZigiKSIsbi5sZW5ndGgtdCktbi5sZW5ndGgpJiYoZVswXT1lWzBdLnNsaWNlKDAsdCksZVsyXT1uLnNsaWNlKDAsdCkpLGUuc2xpY2UoMCwzKSl9fSxmaWx0ZXI6e1RBRzpmdW5jdGlvbihlKXtyZXR1cm4iKiI9PT1lP2Z1bmN0aW9uKCl7cmV0dXJuITB9OihlPWUucmVwbGFjZShldCx0dCkudG9Mb3dlckNhc2UoKSxmdW5jdGlvbih0KXtyZXR1cm4gdC5ub2RlTmFtZSYmdC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpPT09ZX0pfSxDTEFTUzpmdW5jdGlvbihlKXt2YXIgdD1rW2UrIiAiXTtyZXR1cm4gdHx8KHQ9UmVnRXhwKCIoXnwiK18rIikiK2UrIigiK18rInwkKSIpKSYmayhlLGZ1bmN0aW9uKGUpe3JldHVybiB0LnRlc3QoZS5jbGFzc05hbWV8fHR5cGVvZiBlLmdldEF0dHJpYnV0ZSE9PUEmJmUuZ2V0QXR0cmlidXRlKCJjbGFzcyIpfHwiIil9KX0sQVRUUjpmdW5jdGlvbihlLHQsbil7cmV0dXJuIGZ1bmN0aW9uKHIpe3ZhciBpPXN0LmF0dHIocixlKTtyZXR1cm4gbnVsbD09aT8iIT0iPT09dDp0PyhpKz0iIiwiPSI9PT10P2k9PT1uOiIhPSI9PT10P2khPT1uOiJePSI9PT10P24mJjA9PT1pLmluZGV4T2Yobik6Iio9Ij09PXQ/biYmaS5pbmRleE9mKG4pPi0xOiIkPSI9PT10P24mJmkuc2xpY2UoLW4ubGVuZ3RoKT09PW46In49Ij09PXQ/KCIgIitpKyIgIikuaW5kZXhPZihuKT4tMToifD0iPT09dD9pPT09bnx8aS5zbGljZSgwLG4ubGVuZ3RoKzEpPT09bisiLSI6ITEpOiEwfX0sQ0hJTEQ6ZnVuY3Rpb24oZSx0LG4scixpKXt2YXIgbz0ibnRoIiE9PWUuc2xpY2UoMCwzKSxhPSJsYXN0IiE9PWUuc2xpY2UoLTQpLHM9Im9mLXR5cGUiPT09dDtyZXR1cm4gMT09PXImJjA9PT1pP2Z1bmN0aW9uKGUpe3JldHVybiEhZS5wYXJlbnROb2RlfTpmdW5jdGlvbih0LG4sdSl7dmFyIGwsYyxwLGYsZCxoLGc9byE9PWE/Im5leHRTaWJsaW5nIjoicHJldmlvdXNTaWJsaW5nIixtPXQucGFyZW50Tm9kZSx5PXMmJnQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSx2PSF1JiYhcztpZihtKXtpZihvKXt3aGlsZShnKXtwPXQ7d2hpbGUocD1wW2ddKWlmKHM/cC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpPT09eToxPT09cC5ub2RlVHlwZSlyZXR1cm4hMTtoPWc9Im9ubHkiPT09ZSYmIWgmJiJuZXh0U2libGluZyJ9cmV0dXJuITB9aWYoaD1bYT9tLmZpcnN0Q2hpbGQ6bS5sYXN0Q2hpbGRdLGEmJnYpe2M9bVt4XXx8KG1beF09e30pLGw9Y1tlXXx8W10sZD1sWzBdPT09TiYmbFsxXSxmPWxbMF09PT1OJiZsWzJdLHA9ZCYmbS5jaGlsZE5vZGVzW2RdO3doaWxlKHA9KytkJiZwJiZwW2ddfHwoZj1kPTApfHxoLnBvcCgpKWlmKDE9PT1wLm5vZGVUeXBlJiYrK2YmJnA9PT10KXtjW2VdPVtOLGQsZl07YnJlYWt9fWVsc2UgaWYodiYmKGw9KHRbeF18fCh0W3hdPXt9KSlbZV0pJiZsWzBdPT09TilmPWxbMV07ZWxzZSB3aGlsZShwPSsrZCYmcCYmcFtnXXx8KGY9ZD0wKXx8aC5wb3AoKSlpZigocz9wLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk9PT15OjE9PT1wLm5vZGVUeXBlKSYmKytmJiYodiYmKChwW3hdfHwocFt4XT17fSkpW2VdPVtOLGZdKSxwPT09dCkpYnJlYWs7cmV0dXJuIGYtPWksZj09PXJ8fDA9PT1mJXImJmYvcj49MH19fSxQU0VVRE86ZnVuY3Rpb24oZSx0KXt2YXIgbixyPWkucHNldWRvc1tlXXx8aS5zZXRGaWx0ZXJzW2UudG9Mb3dlckNhc2UoKV18fHN0LmVycm9yKCJ1bnN1cHBvcnRlZCBwc2V1ZG86ICIrZSk7cmV0dXJuIHJbeF0/cih0KTpyLmxlbmd0aD4xPyhuPVtlLGUsIiIsdF0saS5zZXRGaWx0ZXJzLmhhc093blByb3BlcnR5KGUudG9Mb3dlckNhc2UoKSk/b3QoZnVuY3Rpb24oZSxuKXt2YXIgaSxvPXIoZSx0KSxhPW8ubGVuZ3RoO3doaWxlKGEtLSlpPU0uY2FsbChlLG9bYV0pLGVbaV09IShuW2ldPW9bYV0pfSk6ZnVuY3Rpb24oZSl7cmV0dXJuIHIoZSwwLG4pfSk6cn19LHBzZXVkb3M6e25vdDpvdChmdW5jdGlvbihlKXt2YXIgdD1bXSxuPVtdLHI9cyhlLnJlcGxhY2UoVywiJDEiKSk7cmV0dXJuIHJbeF0/b3QoZnVuY3Rpb24oZSx0LG4saSl7dmFyIG8sYT1yKGUsbnVsbCxpLFtdKSxzPWUubGVuZ3RoO3doaWxlKHMtLSkobz1hW3NdKSYmKGVbc109ISh0W3NdPW8pKX0pOmZ1bmN0aW9uKGUsaSxvKXtyZXR1cm4gdFswXT1lLHIodCxudWxsLG8sbiksIW4ucG9wKCl9fSksaGFzOm90KGZ1bmN0aW9uKGUpe3JldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gc3QoZSx0KS5sZW5ndGg+MH19KSxjb250YWluczpvdChmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24odCl7cmV0dXJuKHQudGV4dENvbnRlbnR8fHQuaW5uZXJUZXh0fHxvKHQpKS5pbmRleE9mKGUpPi0xfX0pLGxhbmc6b3QoZnVuY3Rpb24oZSl7cmV0dXJuIFgudGVzdChlfHwiIil8fHN0LmVycm9yKCJ1bnN1cHBvcnRlZCBsYW5nOiAiK2UpLGU9ZS5yZXBsYWNlKGV0LHR0KS50b0xvd2VyQ2FzZSgpLGZ1bmN0aW9uKHQpe3ZhciBuO2RvIGlmKG49ZD90LmdldEF0dHJpYnV0ZSgieG1sOmxhbmciKXx8dC5nZXRBdHRyaWJ1dGUoImxhbmciKTp0LmxhbmcpcmV0dXJuIG49bi50b0xvd2VyQ2FzZSgpLG49PT1lfHwwPT09bi5pbmRleE9mKGUrIi0iKTt3aGlsZSgodD10LnBhcmVudE5vZGUpJiYxPT09dC5ub2RlVHlwZSk7cmV0dXJuITF9fSksdGFyZ2V0OmZ1bmN0aW9uKHQpe3ZhciBuPWUubG9jYXRpb24mJmUubG9jYXRpb24uaGFzaDtyZXR1cm4gbiYmbi5zbGljZSgxKT09PXQuaWR9LHJvb3Q6ZnVuY3Rpb24oZSl7cmV0dXJuIGU9PT1mfSxmb2N1czpmdW5jdGlvbihlKXtyZXR1cm4gZT09PXAuYWN0aXZlRWxlbWVudCYmKCFwLmhhc0ZvY3VzfHxwLmhhc0ZvY3VzKCkpJiYhIShlLnR5cGV8fGUuaHJlZnx8fmUudGFiSW5kZXgpfSxlbmFibGVkOmZ1bmN0aW9uKGUpe3JldHVybiBlLmRpc2FibGVkPT09ITF9LGRpc2FibGVkOmZ1bmN0aW9uKGUpe3JldHVybiBlLmRpc2FibGVkPT09ITB9LGNoZWNrZWQ6ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO3JldHVybiJpbnB1dCI9PT10JiYhIWUuY2hlY2tlZHx8Im9wdGlvbiI9PT10JiYhIWUuc2VsZWN0ZWR9LHNlbGVjdGVkOmZ1bmN0aW9uKGUpe3JldHVybiBlLnBhcmVudE5vZGUmJmUucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4LGUuc2VsZWN0ZWQ9PT0hMH0sZW1wdHk6ZnVuY3Rpb24oZSl7Zm9yKGU9ZS5maXJzdENoaWxkO2U7ZT1lLm5leHRTaWJsaW5nKWlmKGUubm9kZU5hbWU+IkAifHwzPT09ZS5ub2RlVHlwZXx8ND09PWUubm9kZVR5cGUpcmV0dXJuITE7cmV0dXJuITB9LHBhcmVudDpmdW5jdGlvbihlKXtyZXR1cm4haS5wc2V1ZG9zLmVtcHR5KGUpfSxoZWFkZXI6ZnVuY3Rpb24oZSl7cmV0dXJuIFEudGVzdChlLm5vZGVOYW1lKX0saW5wdXQ6ZnVuY3Rpb24oZSl7cmV0dXJuIEcudGVzdChlLm5vZGVOYW1lKX0sYnV0dG9uOmZ1bmN0aW9uKGUpe3ZhciB0PWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtyZXR1cm4iaW5wdXQiPT09dCYmImJ1dHRvbiI9PT1lLnR5cGV8fCJidXR0b24iPT09dH0sdGV4dDpmdW5jdGlvbihlKXt2YXIgdDtyZXR1cm4iaW5wdXQiPT09ZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpJiYidGV4dCI9PT1lLnR5cGUmJihudWxsPT0odD1lLmdldEF0dHJpYnV0ZSgidHlwZSIpKXx8dC50b0xvd2VyQ2FzZSgpPT09ZS50eXBlKX0sZmlyc3Q6cHQoZnVuY3Rpb24oKXtyZXR1cm5bMF19KSxsYXN0OnB0KGZ1bmN0aW9uKGUsdCl7cmV0dXJuW3QtMV19KSxlcTpwdChmdW5jdGlvbihlLHQsbil7cmV0dXJuWzA+bj9uK3Q6bl19KSxldmVuOnB0KGZ1bmN0aW9uKGUsdCl7dmFyIG49MDtmb3IoO3Q+bjtuKz0yKWUucHVzaChuKTtyZXR1cm4gZX0pLG9kZDpwdChmdW5jdGlvbihlLHQpe3ZhciBuPTE7Zm9yKDt0Pm47bis9MillLnB1c2gobik7cmV0dXJuIGV9KSxsdDpwdChmdW5jdGlvbihlLHQsbil7dmFyIHI9MD5uP24rdDpuO2Zvcig7LS1yPj0wOyllLnB1c2gocik7cmV0dXJuIGV9KSxndDpwdChmdW5jdGlvbihlLHQsbil7dmFyIHI9MD5uP24rdDpuO2Zvcig7dD4rK3I7KWUucHVzaChyKTtyZXR1cm4gZX0pfX07Zm9yKG4gaW57cmFkaW86ITAsY2hlY2tib3g6ITAsZmlsZTohMCxwYXNzd29yZDohMCxpbWFnZTohMH0paS5wc2V1ZG9zW25dPWx0KG4pO2ZvcihuIGlue3N1Ym1pdDohMCxyZXNldDohMH0paS5wc2V1ZG9zW25dPWN0KG4pO2Z1bmN0aW9uIGZ0KGUsdCl7dmFyIG4scixvLGEscyx1LGwsYz1FW2UrIiAiXTtpZihjKXJldHVybiB0PzA6Yy5zbGljZSgwKTtzPWUsdT1bXSxsPWkucHJlRmlsdGVyO3doaWxlKHMpeyghbnx8KHI9JC5leGVjKHMpKSkmJihyJiYocz1zLnNsaWNlKHJbMF0ubGVuZ3RoKXx8cyksdS5wdXNoKG89W10pKSxuPSExLChyPUkuZXhlYyhzKSkmJihuPXIuc2hpZnQoKSxvLnB1c2goe3ZhbHVlOm4sdHlwZTpyWzBdLnJlcGxhY2UoVywiICIpfSkscz1zLnNsaWNlKG4ubGVuZ3RoKSk7Zm9yKGEgaW4gaS5maWx0ZXIpIShyPVVbYV0uZXhlYyhzKSl8fGxbYV0mJiEocj1sW2FdKHIpKXx8KG49ci5zaGlmdCgpLG8ucHVzaCh7dmFsdWU6bix0eXBlOmEsbWF0Y2hlczpyfSkscz1zLnNsaWNlKG4ubGVuZ3RoKSk7aWYoIW4pYnJlYWt9cmV0dXJuIHQ/cy5sZW5ndGg6cz9zdC5lcnJvcihlKTpFKGUsdSkuc2xpY2UoMCl9ZnVuY3Rpb24gZHQoZSl7dmFyIHQ9MCxuPWUubGVuZ3RoLHI9IiI7Zm9yKDtuPnQ7dCsrKXIrPWVbdF0udmFsdWU7cmV0dXJuIHJ9ZnVuY3Rpb24gaHQoZSx0LG4pe3ZhciBpPXQuZGlyLG89biYmInBhcmVudE5vZGUiPT09aSxhPUMrKztyZXR1cm4gdC5maXJzdD9mdW5jdGlvbih0LG4scil7d2hpbGUodD10W2ldKWlmKDE9PT10Lm5vZGVUeXBlfHxvKXJldHVybiBlKHQsbixyKX06ZnVuY3Rpb24odCxuLHMpe3ZhciB1LGwsYyxwPU4rIiAiK2E7aWYocyl7d2hpbGUodD10W2ldKWlmKCgxPT09dC5ub2RlVHlwZXx8bykmJmUodCxuLHMpKXJldHVybiEwfWVsc2Ugd2hpbGUodD10W2ldKWlmKDE9PT10Lm5vZGVUeXBlfHxvKWlmKGM9dFt4XXx8KHRbeF09e30pLChsPWNbaV0pJiZsWzBdPT09cCl7aWYoKHU9bFsxXSk9PT0hMHx8dT09PXIpcmV0dXJuIHU9PT0hMH1lbHNlIGlmKGw9Y1tpXT1bcF0sbFsxXT1lKHQsbixzKXx8cixsWzFdPT09ITApcmV0dXJuITB9fWZ1bmN0aW9uIGd0KGUpe3JldHVybiBlLmxlbmd0aD4xP2Z1bmN0aW9uKHQsbixyKXt2YXIgaT1lLmxlbmd0aDt3aGlsZShpLS0paWYoIWVbaV0odCxuLHIpKXJldHVybiExO3JldHVybiEwfTplWzBdfWZ1bmN0aW9uIG10KGUsdCxuLHIsaSl7dmFyIG8sYT1bXSxzPTAsdT1lLmxlbmd0aCxsPW51bGwhPXQ7Zm9yKDt1PnM7cysrKShvPWVbc10pJiYoIW58fG4obyxyLGkpKSYmKGEucHVzaChvKSxsJiZ0LnB1c2gocykpO3JldHVybiBhfWZ1bmN0aW9uIHl0KGUsdCxuLHIsaSxvKXtyZXR1cm4gciYmIXJbeF0mJihyPXl0KHIpKSxpJiYhaVt4XSYmKGk9eXQoaSxvKSksb3QoZnVuY3Rpb24obyxhLHMsdSl7dmFyIGwsYyxwLGY9W10sZD1bXSxoPWEubGVuZ3RoLGc9b3x8eHQodHx8IioiLHMubm9kZVR5cGU/W3NdOnMsW10pLG09IWV8fCFvJiZ0P2c6bXQoZyxmLGUscyx1KSx5PW4/aXx8KG8/ZTpofHxyKT9bXTphOm07aWYobiYmbihtLHkscyx1KSxyKXtsPW10KHksZCkscihsLFtdLHMsdSksYz1sLmxlbmd0aDt3aGlsZShjLS0pKHA9bFtjXSkmJih5W2RbY11dPSEobVtkW2NdXT1wKSl9aWYobyl7aWYoaXx8ZSl7aWYoaSl7bD1bXSxjPXkubGVuZ3RoO3doaWxlKGMtLSkocD15W2NdKSYmbC5wdXNoKG1bY109cCk7aShudWxsLHk9W10sbCx1KX1jPXkubGVuZ3RoO3doaWxlKGMtLSkocD15W2NdKSYmKGw9aT9NLmNhbGwobyxwKTpmW2NdKT4tMSYmKG9bbF09IShhW2xdPXApKX19ZWxzZSB5PW10KHk9PT1hP3kuc3BsaWNlKGgseS5sZW5ndGgpOnkpLGk/aShudWxsLGEseSx1KTpILmFwcGx5KGEseSl9KX1mdW5jdGlvbiB2dChlKXt2YXIgdCxuLHIsbz1lLmxlbmd0aCxhPWkucmVsYXRpdmVbZVswXS50eXBlXSxzPWF8fGkucmVsYXRpdmVbIiAiXSx1PWE/MTowLGM9aHQoZnVuY3Rpb24oZSl7cmV0dXJuIGU9PT10fSxzLCEwKSxwPWh0KGZ1bmN0aW9uKGUpe3JldHVybiBNLmNhbGwodCxlKT4tMX0scywhMCksZj1bZnVuY3Rpb24oZSxuLHIpe3JldHVybiFhJiYocnx8biE9PWwpfHwoKHQ9bikubm9kZVR5cGU/YyhlLG4scik6cChlLG4scikpfV07Zm9yKDtvPnU7dSsrKWlmKG49aS5yZWxhdGl2ZVtlW3VdLnR5cGVdKWY9W2h0KGd0KGYpLG4pXTtlbHNle2lmKG49aS5maWx0ZXJbZVt1XS50eXBlXS5hcHBseShudWxsLGVbdV0ubWF0Y2hlcyksblt4XSl7Zm9yKHI9Kyt1O28+cjtyKyspaWYoaS5yZWxhdGl2ZVtlW3JdLnR5cGVdKWJyZWFrO3JldHVybiB5dCh1PjEmJmd0KGYpLHU+MSYmZHQoZS5zbGljZSgwLHUtMSkpLnJlcGxhY2UoVywiJDEiKSxuLHI+dSYmdnQoZS5zbGljZSh1LHIpKSxvPnImJnZ0KGU9ZS5zbGljZShyKSksbz5yJiZkdChlKSl9Zi5wdXNoKG4pfXJldHVybiBndChmKX1mdW5jdGlvbiBidChlLHQpe3ZhciBuPTAsbz10Lmxlbmd0aD4wLGE9ZS5sZW5ndGg+MCxzPWZ1bmN0aW9uKHMsdSxjLGYsZCl7dmFyIGgsZyxtLHk9W10sdj0wLGI9IjAiLHg9cyYmW10sdz1udWxsIT1kLFQ9bCxDPXN8fGEmJmkuZmluZC5UQUcoIioiLGQmJnUucGFyZW50Tm9kZXx8dSksaz1OKz1udWxsPT1UPzE6TWF0aC5yYW5kb20oKXx8LjE7Zm9yKHcmJihsPXUhPT1wJiZ1LHI9bik7bnVsbCE9KGg9Q1tiXSk7YisrKXtpZihhJiZoKXtnPTA7d2hpbGUobT1lW2crK10paWYobShoLHUsYykpe2YucHVzaChoKTticmVha313JiYoTj1rLHI9KytuKX1vJiYoKGg9IW0mJmgpJiZ2LS0scyYmeC5wdXNoKGgpKX1pZih2Kz1iLG8mJmIhPT12KXtnPTA7d2hpbGUobT10W2crK10pbSh4LHksdSxjKTtpZihzKXtpZih2PjApd2hpbGUoYi0tKXhbYl18fHlbYl18fCh5W2JdPUwuY2FsbChmKSk7eT1tdCh5KX1ILmFwcGx5KGYseSksdyYmIXMmJnkubGVuZ3RoPjAmJnYrdC5sZW5ndGg+MSYmc3QudW5pcXVlU29ydChmKX1yZXR1cm4gdyYmKE49ayxsPVQpLHh9O3JldHVybiBvP290KHMpOnN9cz1zdC5jb21waWxlPWZ1bmN0aW9uKGUsdCl7dmFyIG4scj1bXSxpPVtdLG89U1tlKyIgIl07aWYoIW8pe3R8fCh0PWZ0KGUpKSxuPXQubGVuZ3RoO3doaWxlKG4tLSlvPXZ0KHRbbl0pLG9beF0/ci5wdXNoKG8pOmkucHVzaChvKTtvPVMoZSxidChpLHIpKX1yZXR1cm4gb307ZnVuY3Rpb24geHQoZSx0LG4pe3ZhciByPTAsaT10Lmxlbmd0aDtmb3IoO2k+cjtyKyspc3QoZSx0W3JdLG4pO3JldHVybiBufWZ1bmN0aW9uIHd0KGUsdCxuLHIpe3ZhciBvLGEsdSxsLGMscD1mdChlKTtpZighciYmMT09PXAubGVuZ3RoKXtpZihhPXBbMF09cFswXS5zbGljZSgwKSxhLmxlbmd0aD4yJiYiSUQiPT09KHU9YVswXSkudHlwZSYmOT09PXQubm9kZVR5cGUmJiFkJiZpLnJlbGF0aXZlW2FbMV0udHlwZV0pe2lmKHQ9aS5maW5kLklEKHUubWF0Y2hlc1swXS5yZXBsYWNlKGV0LHR0KSx0KVswXSwhdClyZXR1cm4gbjtlPWUuc2xpY2UoYS5zaGlmdCgpLnZhbHVlLmxlbmd0aCl9bz1VLm5lZWRzQ29udGV4dC50ZXN0KGUpPzA6YS5sZW5ndGg7d2hpbGUoby0tKXtpZih1PWFbb10saS5yZWxhdGl2ZVtsPXUudHlwZV0pYnJlYWs7aWYoKGM9aS5maW5kW2xdKSYmKHI9Yyh1Lm1hdGNoZXNbMF0ucmVwbGFjZShldCx0dCksVi50ZXN0KGFbMF0udHlwZSkmJnQucGFyZW50Tm9kZXx8dCkpKXtpZihhLnNwbGljZShvLDEpLGU9ci5sZW5ndGgmJmR0KGEpLCFlKXJldHVybiBILmFwcGx5KG4scS5jYWxsKHIsMCkpLG47YnJlYWt9fX1yZXR1cm4gcyhlLHApKHIsdCxkLG4sVi50ZXN0KGUpKSxufWkucHNldWRvcy5udGg9aS5wc2V1ZG9zLmVxO2Z1bmN0aW9uIFR0KCl7fWkuZmlsdGVycz1UdC5wcm90b3R5cGU9aS5wc2V1ZG9zLGkuc2V0RmlsdGVycz1uZXcgVHQsYygpLHN0LmF0dHI9Yi5hdHRyLGIuZmluZD1zdCxiLmV4cHI9c3Quc2VsZWN0b3JzLGIuZXhwclsiOiJdPWIuZXhwci5wc2V1ZG9zLGIudW5pcXVlPXN0LnVuaXF1ZVNvcnQsYi50ZXh0PXN0LmdldFRleHQsYi5pc1hNTERvYz1zdC5pc1hNTCxiLmNvbnRhaW5zPXN0LmNvbnRhaW5zfShlKTt2YXIgYXQ9L1VudGlsJC8sc3Q9L14oPzpwYXJlbnRzfHByZXYoPzpVbnRpbHxBbGwpKS8sdXQ9L14uW146I1xbXC4sXSokLyxsdD1iLmV4cHIubWF0Y2gubmVlZHNDb250ZXh0LGN0PXtjaGlsZHJlbjohMCxjb250ZW50czohMCxuZXh0OiEwLHByZXY6ITB9O2IuZm4uZXh0ZW5kKHtmaW5kOmZ1bmN0aW9uKGUpe3ZhciB0LG4scixpPXRoaXMubGVuZ3RoO2lmKCJzdHJpbmciIT10eXBlb2YgZSlyZXR1cm4gcj10aGlzLHRoaXMucHVzaFN0YWNrKGIoZSkuZmlsdGVyKGZ1bmN0aW9uKCl7Zm9yKHQ9MDtpPnQ7dCsrKWlmKGIuY29udGFpbnMoclt0XSx0aGlzKSlyZXR1cm4hMH0pKTtmb3Iobj1bXSx0PTA7aT50O3QrKyliLmZpbmQoZSx0aGlzW3RdLG4pO3JldHVybiBuPXRoaXMucHVzaFN0YWNrKGk+MT9iLnVuaXF1ZShuKTpuKSxuLnNlbGVjdG9yPSh0aGlzLnNlbGVjdG9yP3RoaXMuc2VsZWN0b3IrIiAiOiIiKStlLG59LGhhczpmdW5jdGlvbihlKXt2YXIgdCxuPWIoZSx0aGlzKSxyPW4ubGVuZ3RoO3JldHVybiB0aGlzLmZpbHRlcihmdW5jdGlvbigpe2Zvcih0PTA7cj50O3QrKylpZihiLmNvbnRhaW5zKHRoaXMsblt0XSkpcmV0dXJuITB9KX0sbm90OmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLnB1c2hTdGFjayhmdCh0aGlzLGUsITEpKX0sZmlsdGVyOmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLnB1c2hTdGFjayhmdCh0aGlzLGUsITApKX0saXM6ZnVuY3Rpb24oZSl7cmV0dXJuISFlJiYoInN0cmluZyI9PXR5cGVvZiBlP2x0LnRlc3QoZSk/YihlLHRoaXMuY29udGV4dCkuaW5kZXgodGhpc1swXSk+PTA6Yi5maWx0ZXIoZSx0aGlzKS5sZW5ndGg+MDp0aGlzLmZpbHRlcihlKS5sZW5ndGg+MCl9LGNsb3Nlc3Q6ZnVuY3Rpb24oZSx0KXt2YXIgbixyPTAsaT10aGlzLmxlbmd0aCxvPVtdLGE9bHQudGVzdChlKXx8InN0cmluZyIhPXR5cGVvZiBlP2IoZSx0fHx0aGlzLmNvbnRleHQpOjA7Zm9yKDtpPnI7cisrKXtuPXRoaXNbcl07d2hpbGUobiYmbi5vd25lckRvY3VtZW50JiZuIT09dCYmMTEhPT1uLm5vZGVUeXBlKXtpZihhP2EuaW5kZXgobik+LTE6Yi5maW5kLm1hdGNoZXNTZWxlY3RvcihuLGUpKXtvLnB1c2gobik7YnJlYWt9bj1uLnBhcmVudE5vZGV9fXJldHVybiB0aGlzLnB1c2hTdGFjayhvLmxlbmd0aD4xP2IudW5pcXVlKG8pOm8pfSxpbmRleDpmdW5jdGlvbihlKXtyZXR1cm4gZT8ic3RyaW5nIj09dHlwZW9mIGU/Yi5pbkFycmF5KHRoaXNbMF0sYihlKSk6Yi5pbkFycmF5KGUuanF1ZXJ5P2VbMF06ZSx0aGlzKTp0aGlzWzBdJiZ0aGlzWzBdLnBhcmVudE5vZGU/dGhpcy5maXJzdCgpLnByZXZBbGwoKS5sZW5ndGg6LTF9LGFkZDpmdW5jdGlvbihlLHQpe3ZhciBuPSJzdHJpbmciPT10eXBlb2YgZT9iKGUsdCk6Yi5tYWtlQXJyYXkoZSYmZS5ub2RlVHlwZT9bZV06ZSkscj1iLm1lcmdlKHRoaXMuZ2V0KCksbik7cmV0dXJuIHRoaXMucHVzaFN0YWNrKGIudW5pcXVlKHIpKX0sYWRkQmFjazpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5hZGQobnVsbD09ZT90aGlzLnByZXZPYmplY3Q6dGhpcy5wcmV2T2JqZWN0LmZpbHRlcihlKSl9fSksYi5mbi5hbmRTZWxmPWIuZm4uYWRkQmFjaztmdW5jdGlvbiBwdChlLHQpe2RvIGU9ZVt0XTt3aGlsZShlJiYxIT09ZS5ub2RlVHlwZSk7cmV0dXJuIGV9Yi5lYWNoKHtwYXJlbnQ6ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5wYXJlbnROb2RlO3JldHVybiB0JiYxMSE9PXQubm9kZVR5cGU/dDpudWxsfSxwYXJlbnRzOmZ1bmN0aW9uKGUpe3JldHVybiBiLmRpcihlLCJwYXJlbnROb2RlIil9LHBhcmVudHNVbnRpbDpmdW5jdGlvbihlLHQsbil7cmV0dXJuIGIuZGlyKGUsInBhcmVudE5vZGUiLG4pfSxuZXh0OmZ1bmN0aW9uKGUpe3JldHVybiBwdChlLCJuZXh0U2libGluZyIpfSxwcmV2OmZ1bmN0aW9uKGUpe3JldHVybiBwdChlLCJwcmV2aW91c1NpYmxpbmciKX0sbmV4dEFsbDpmdW5jdGlvbihlKXtyZXR1cm4gYi5kaXIoZSwibmV4dFNpYmxpbmciKX0scHJldkFsbDpmdW5jdGlvbihlKXtyZXR1cm4gYi5kaXIoZSwicHJldmlvdXNTaWJsaW5nIil9LG5leHRVbnRpbDpmdW5jdGlvbihlLHQsbil7cmV0dXJuIGIuZGlyKGUsIm5leHRTaWJsaW5nIixuKX0scHJldlVudGlsOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gYi5kaXIoZSwicHJldmlvdXNTaWJsaW5nIixuKX0sc2libGluZ3M6ZnVuY3Rpb24oZSl7cmV0dXJuIGIuc2libGluZygoZS5wYXJlbnROb2RlfHx7fSkuZmlyc3RDaGlsZCxlKX0sY2hpbGRyZW46ZnVuY3Rpb24oZSl7cmV0dXJuIGIuc2libGluZyhlLmZpcnN0Q2hpbGQpfSxjb250ZW50czpmdW5jdGlvbihlKXtyZXR1cm4gYi5ub2RlTmFtZShlLCJpZnJhbWUiKT9lLmNvbnRlbnREb2N1bWVudHx8ZS5jb250ZW50V2luZG93LmRvY3VtZW50OmIubWVyZ2UoW10sZS5jaGlsZE5vZGVzKX19LGZ1bmN0aW9uKGUsdCl7Yi5mbltlXT1mdW5jdGlvbihuLHIpe3ZhciBpPWIubWFwKHRoaXMsdCxuKTtyZXR1cm4gYXQudGVzdChlKXx8KHI9biksciYmInN0cmluZyI9PXR5cGVvZiByJiYoaT1iLmZpbHRlcihyLGkpKSxpPXRoaXMubGVuZ3RoPjEmJiFjdFtlXT9iLnVuaXF1ZShpKTppLHRoaXMubGVuZ3RoPjEmJnN0LnRlc3QoZSkmJihpPWkucmV2ZXJzZSgpKSx0aGlzLnB1c2hTdGFjayhpKX19KSxiLmV4dGVuZCh7ZmlsdGVyOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gbiYmKGU9Ijpub3QoIitlKyIpIiksMT09PXQubGVuZ3RoP2IuZmluZC5tYXRjaGVzU2VsZWN0b3IodFswXSxlKT9bdFswXV06W106Yi5maW5kLm1hdGNoZXMoZSx0KX0sZGlyOmZ1bmN0aW9uKGUsbixyKXt2YXIgaT1bXSxvPWVbbl07d2hpbGUobyYmOSE9PW8ubm9kZVR5cGUmJihyPT09dHx8MSE9PW8ubm9kZVR5cGV8fCFiKG8pLmlzKHIpKSkxPT09by5ub2RlVHlwZSYmaS5wdXNoKG8pLG89b1tuXTtyZXR1cm4gaX0sc2libGluZzpmdW5jdGlvbihlLHQpe3ZhciBuPVtdO2Zvcig7ZTtlPWUubmV4dFNpYmxpbmcpMT09PWUubm9kZVR5cGUmJmUhPT10JiZuLnB1c2goZSk7cmV0dXJuIG59fSk7ZnVuY3Rpb24gZnQoZSx0LG4pe2lmKHQ9dHx8MCxiLmlzRnVuY3Rpb24odCkpcmV0dXJuIGIuZ3JlcChlLGZ1bmN0aW9uKGUscil7dmFyIGk9ISF0LmNhbGwoZSxyLGUpO3JldHVybiBpPT09bn0pO2lmKHQubm9kZVR5cGUpcmV0dXJuIGIuZ3JlcChlLGZ1bmN0aW9uKGUpe3JldHVybiBlPT09dD09PW59KTtpZigic3RyaW5nIj09dHlwZW9mIHQpe3ZhciByPWIuZ3JlcChlLGZ1bmN0aW9uKGUpe3JldHVybiAxPT09ZS5ub2RlVHlwZX0pO2lmKHV0LnRlc3QodCkpcmV0dXJuIGIuZmlsdGVyKHQsciwhbik7dD1iLmZpbHRlcih0LHIpfXJldHVybiBiLmdyZXAoZSxmdW5jdGlvbihlKXtyZXR1cm4gYi5pbkFycmF5KGUsdCk+PTA9PT1ufSl9ZnVuY3Rpb24gZHQoZSl7dmFyIHQ9aHQuc3BsaXQoInwiKSxuPWUuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO2lmKG4uY3JlYXRlRWxlbWVudCl3aGlsZSh0Lmxlbmd0aCluLmNyZWF0ZUVsZW1lbnQodC5wb3AoKSk7cmV0dXJuIG59dmFyIGh0PSJhYmJyfGFydGljbGV8YXNpZGV8YXVkaW98YmRpfGNhbnZhc3xkYXRhfGRhdGFsaXN0fGRldGFpbHN8ZmlnY2FwdGlvbnxmaWd1cmV8Zm9vdGVyfGhlYWRlcnxoZ3JvdXB8bWFya3xtZXRlcnxuYXZ8b3V0cHV0fHByb2dyZXNzfHNlY3Rpb258c3VtbWFyeXx0aW1lfHZpZGVvIixndD0vIGpRdWVyeVxkKz0iKD86bnVsbHxcZCspIi9nLG10PVJlZ0V4cCgiPCg/OiIraHQrIilbXFxzLz5dIiwiaSIpLHl0PS9eXHMrLyx2dD0vPCg/IWFyZWF8YnJ8Y29sfGVtYmVkfGhyfGltZ3xpbnB1dHxsaW5rfG1ldGF8cGFyYW0pKChbXHc6XSspW14+XSopXC8+L2dpLGJ0PS88KFtcdzpdKykvLHh0PS88dGJvZHkvaSx3dD0vPHwmIz9cdys7LyxUdD0vPCg/OnNjcmlwdHxzdHlsZXxsaW5rKS9pLE50PS9eKD86Y2hlY2tib3h8cmFkaW8pJC9pLEN0PS9jaGVja2VkXHMqKD86W149XXw9XHMqLmNoZWNrZWQuKS9pLGt0PS9eJHxcLyg/OmphdmF8ZWNtYSlzY3JpcHQvaSxFdD0vXnRydWVcLyguKikvLFN0PS9eXHMqPCEoPzpcW0NEQVRBXFt8LS0pfCg/OlxdXF18LS0pPlxzKiQvZyxBdD17b3B0aW9uOlsxLCI8c2VsZWN0IG11bHRpcGxlPSdtdWx0aXBsZSc+IiwiPC9zZWxlY3Q+Il0sbGVnZW5kOlsxLCI8ZmllbGRzZXQ+IiwiPC9maWVsZHNldD4iXSxhcmVhOlsxLCI8bWFwPiIsIjwvbWFwPiJdLHBhcmFtOlsxLCI8b2JqZWN0PiIsIjwvb2JqZWN0PiJdLHRoZWFkOlsxLCI8dGFibGU+IiwiPC90YWJsZT4iXSx0cjpbMiwiPHRhYmxlPjx0Ym9keT4iLCI8L3Rib2R5PjwvdGFibGU+Il0sY29sOlsyLCI8dGFibGU+PHRib2R5PjwvdGJvZHk+PGNvbGdyb3VwPiIsIjwvY29sZ3JvdXA+PC90YWJsZT4iXSx0ZDpbMywiPHRhYmxlPjx0Ym9keT48dHI+IiwiPC90cj48L3Rib2R5PjwvdGFibGU+Il0sX2RlZmF1bHQ6Yi5zdXBwb3J0Lmh0bWxTZXJpYWxpemU/WzAsIiIsIiJdOlsxLCJYPGRpdj4iLCI8L2Rpdj4iXX0sanQ9ZHQobyksRHQ9anQuYXBwZW5kQ2hpbGQoby5jcmVhdGVFbGVtZW50KCJkaXYiKSk7QXQub3B0Z3JvdXA9QXQub3B0aW9uLEF0LnRib2R5PUF0LnRmb290PUF0LmNvbGdyb3VwPUF0LmNhcHRpb249QXQudGhlYWQsQXQudGg9QXQudGQsYi5mbi5leHRlbmQoe3RleHQ6ZnVuY3Rpb24oZSl7cmV0dXJuIGIuYWNjZXNzKHRoaXMsZnVuY3Rpb24oZSl7cmV0dXJuIGU9PT10P2IudGV4dCh0aGlzKTp0aGlzLmVtcHR5KCkuYXBwZW5kKCh0aGlzWzBdJiZ0aGlzWzBdLm93bmVyRG9jdW1lbnR8fG8pLmNyZWF0ZVRleHROb2RlKGUpKX0sbnVsbCxlLGFyZ3VtZW50cy5sZW5ndGgpfSx3cmFwQWxsOmZ1bmN0aW9uKGUpe2lmKGIuaXNGdW5jdGlvbihlKSlyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKHQpe2IodGhpcykud3JhcEFsbChlLmNhbGwodGhpcyx0KSl9KTtpZih0aGlzWzBdKXt2YXIgdD1iKGUsdGhpc1swXS5vd25lckRvY3VtZW50KS5lcSgwKS5jbG9uZSghMCk7dGhpc1swXS5wYXJlbnROb2RlJiZ0Lmluc2VydEJlZm9yZSh0aGlzWzBdKSx0Lm1hcChmdW5jdGlvbigpe3ZhciBlPXRoaXM7d2hpbGUoZS5maXJzdENoaWxkJiYxPT09ZS5maXJzdENoaWxkLm5vZGVUeXBlKWU9ZS5maXJzdENoaWxkO3JldHVybiBlfSkuYXBwZW5kKHRoaXMpfXJldHVybiB0aGlzfSx3cmFwSW5uZXI6ZnVuY3Rpb24oZSl7cmV0dXJuIGIuaXNGdW5jdGlvbihlKT90aGlzLmVhY2goZnVuY3Rpb24odCl7Yih0aGlzKS53cmFwSW5uZXIoZS5jYWxsKHRoaXMsdCkpfSk6dGhpcy5lYWNoKGZ1bmN0aW9uKCl7dmFyIHQ9Yih0aGlzKSxuPXQuY29udGVudHMoKTtuLmxlbmd0aD9uLndyYXBBbGwoZSk6dC5hcHBlbmQoZSl9KX0sd3JhcDpmdW5jdGlvbihlKXt2YXIgdD1iLmlzRnVuY3Rpb24oZSk7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihuKXtiKHRoaXMpLndyYXBBbGwodD9lLmNhbGwodGhpcyxuKTplKX0pfSx1bndyYXA6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wYXJlbnQoKS5lYWNoKGZ1bmN0aW9uKCl7Yi5ub2RlTmFtZSh0aGlzLCJib2R5Iil8fGIodGhpcykucmVwbGFjZVdpdGgodGhpcy5jaGlsZE5vZGVzKX0pLmVuZCgpfSxhcHBlbmQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kb21NYW5pcChhcmd1bWVudHMsITAsZnVuY3Rpb24oZSl7KDE9PT10aGlzLm5vZGVUeXBlfHwxMT09PXRoaXMubm9kZVR5cGV8fDk9PT10aGlzLm5vZGVUeXBlKSYmdGhpcy5hcHBlbmRDaGlsZChlKX0pfSxwcmVwZW5kOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZG9tTWFuaXAoYXJndW1lbnRzLCEwLGZ1bmN0aW9uKGUpeygxPT09dGhpcy5ub2RlVHlwZXx8MTE9PT10aGlzLm5vZGVUeXBlfHw5PT09dGhpcy5ub2RlVHlwZSkmJnRoaXMuaW5zZXJ0QmVmb3JlKGUsdGhpcy5maXJzdENoaWxkKX0pfSxiZWZvcmU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kb21NYW5pcChhcmd1bWVudHMsITEsZnVuY3Rpb24oZSl7dGhpcy5wYXJlbnROb2RlJiZ0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGUsdGhpcyl9KX0sYWZ0ZXI6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kb21NYW5pcChhcmd1bWVudHMsITEsZnVuY3Rpb24oZSl7dGhpcy5wYXJlbnROb2RlJiZ0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGUsdGhpcy5uZXh0U2libGluZyl9KX0scmVtb3ZlOmZ1bmN0aW9uKGUsdCl7dmFyIG4scj0wO2Zvcig7bnVsbCE9KG49dGhpc1tyXSk7cisrKSghZXx8Yi5maWx0ZXIoZSxbbl0pLmxlbmd0aD4wKSYmKHR8fDEhPT1uLm5vZGVUeXBlfHxiLmNsZWFuRGF0YShPdChuKSksbi5wYXJlbnROb2RlJiYodCYmYi5jb250YWlucyhuLm93bmVyRG9jdW1lbnQsbikmJk10KE90KG4sInNjcmlwdCIpKSxuLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobikpKTtyZXR1cm4gdGhpc30sZW1wdHk6ZnVuY3Rpb24oKXt2YXIgZSx0PTA7Zm9yKDtudWxsIT0oZT10aGlzW3RdKTt0KyspezE9PT1lLm5vZGVUeXBlJiZiLmNsZWFuRGF0YShPdChlLCExKSk7d2hpbGUoZS5maXJzdENoaWxkKWUucmVtb3ZlQ2hpbGQoZS5maXJzdENoaWxkKTtlLm9wdGlvbnMmJmIubm9kZU5hbWUoZSwic2VsZWN0IikmJihlLm9wdGlvbnMubGVuZ3RoPTApfXJldHVybiB0aGlzfSxjbG9uZTpmdW5jdGlvbihlLHQpe3JldHVybiBlPW51bGw9PWU/ITE6ZSx0PW51bGw9PXQ/ZTp0LHRoaXMubWFwKGZ1bmN0aW9uKCl7cmV0dXJuIGIuY2xvbmUodGhpcyxlLHQpfSl9LGh0bWw6ZnVuY3Rpb24oZSl7cmV0dXJuIGIuYWNjZXNzKHRoaXMsZnVuY3Rpb24oZSl7dmFyIG49dGhpc1swXXx8e30scj0wLGk9dGhpcy5sZW5ndGg7aWYoZT09PXQpcmV0dXJuIDE9PT1uLm5vZGVUeXBlP24uaW5uZXJIVE1MLnJlcGxhY2UoZ3QsIiIpOnQ7aWYoISgic3RyaW5nIiE9dHlwZW9mIGV8fFR0LnRlc3QoZSl8fCFiLnN1cHBvcnQuaHRtbFNlcmlhbGl6ZSYmbXQudGVzdChlKXx8IWIuc3VwcG9ydC5sZWFkaW5nV2hpdGVzcGFjZSYmeXQudGVzdChlKXx8QXRbKGJ0LmV4ZWMoZSl8fFsiIiwiIl0pWzFdLnRvTG93ZXJDYXNlKCldKSl7ZT1lLnJlcGxhY2UodnQsIjwkMT48LyQyPiIpO3RyeXtmb3IoO2k+cjtyKyspbj10aGlzW3JdfHx7fSwxPT09bi5ub2RlVHlwZSYmKGIuY2xlYW5EYXRhKE90KG4sITEpKSxuLmlubmVySFRNTD1lKTtuPTB9Y2F0Y2gobyl7fX1uJiZ0aGlzLmVtcHR5KCkuYXBwZW5kKGUpfSxudWxsLGUsYXJndW1lbnRzLmxlbmd0aCl9LHJlcGxhY2VXaXRoOmZ1bmN0aW9uKGUpe3ZhciB0PWIuaXNGdW5jdGlvbihlKTtyZXR1cm4gdHx8InN0cmluZyI9PXR5cGVvZiBlfHwoZT1iKGUpLm5vdCh0aGlzKS5kZXRhY2goKSksdGhpcy5kb21NYW5pcChbZV0sITAsZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5uZXh0U2libGluZyxuPXRoaXMucGFyZW50Tm9kZTtuJiYoYih0aGlzKS5yZW1vdmUoKSxuLmluc2VydEJlZm9yZShlLHQpKX0pfSxkZXRhY2g6ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMucmVtb3ZlKGUsITApfSxkb21NYW5pcDpmdW5jdGlvbihlLG4scil7ZT1mLmFwcGx5KFtdLGUpO3ZhciBpLG8sYSxzLHUsbCxjPTAscD10aGlzLmxlbmd0aCxkPXRoaXMsaD1wLTEsZz1lWzBdLG09Yi5pc0Z1bmN0aW9uKGcpO2lmKG18fCEoMT49cHx8InN0cmluZyIhPXR5cGVvZiBnfHxiLnN1cHBvcnQuY2hlY2tDbG9uZSkmJkN0LnRlc3QoZykpcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihpKXt2YXIgbz1kLmVxKGkpO20mJihlWzBdPWcuY2FsbCh0aGlzLGksbj9vLmh0bWwoKTp0KSksby5kb21NYW5pcChlLG4scil9KTtpZihwJiYobD1iLmJ1aWxkRnJhZ21lbnQoZSx0aGlzWzBdLm93bmVyRG9jdW1lbnQsITEsdGhpcyksaT1sLmZpcnN0Q2hpbGQsMT09PWwuY2hpbGROb2Rlcy5sZW5ndGgmJihsPWkpLGkpKXtmb3Iobj1uJiZiLm5vZGVOYW1lKGksInRyIikscz1iLm1hcChPdChsLCJzY3JpcHQiKSxIdCksYT1zLmxlbmd0aDtwPmM7YysrKW89bCxjIT09aCYmKG89Yi5jbG9uZShvLCEwLCEwKSxhJiZiLm1lcmdlKHMsT3Qobywic2NyaXB0IikpKSxyLmNhbGwobiYmYi5ub2RlTmFtZSh0aGlzW2NdLCJ0YWJsZSIpP0x0KHRoaXNbY10sInRib2R5Iik6dGhpc1tjXSxvLGMpO2lmKGEpZm9yKHU9c1tzLmxlbmd0aC0xXS5vd25lckRvY3VtZW50LGIubWFwKHMscXQpLGM9MDthPmM7YysrKW89c1tjXSxrdC50ZXN0KG8udHlwZXx8IiIpJiYhYi5fZGF0YShvLCJnbG9iYWxFdmFsIikmJmIuY29udGFpbnModSxvKSYmKG8uc3JjP2IuYWpheCh7dXJsOm8uc3JjLHR5cGU6IkdFVCIsZGF0YVR5cGU6InNjcmlwdCIsYXN5bmM6ITEsZ2xvYmFsOiExLCJ0aHJvd3MiOiEwfSk6Yi5nbG9iYWxFdmFsKChvLnRleHR8fG8udGV4dENvbnRlbnR8fG8uaW5uZXJIVE1MfHwiIikucmVwbGFjZShTdCwiIikpKTtsPWk9bnVsbH1yZXR1cm4gdGhpc319KTtmdW5jdGlvbiBMdChlLHQpe3JldHVybiBlLmdldEVsZW1lbnRzQnlUYWdOYW1lKHQpWzBdfHxlLmFwcGVuZENoaWxkKGUub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KHQpKX1mdW5jdGlvbiBIdChlKXt2YXIgdD1lLmdldEF0dHJpYnV0ZU5vZGUoInR5cGUiKTtyZXR1cm4gZS50eXBlPSh0JiZ0LnNwZWNpZmllZCkrIi8iK2UudHlwZSxlfWZ1bmN0aW9uIHF0KGUpe3ZhciB0PUV0LmV4ZWMoZS50eXBlKTtyZXR1cm4gdD9lLnR5cGU9dFsxXTplLnJlbW92ZUF0dHJpYnV0ZSgidHlwZSIpLGV9ZnVuY3Rpb24gTXQoZSx0KXt2YXIgbixyPTA7Zm9yKDtudWxsIT0obj1lW3JdKTtyKyspYi5fZGF0YShuLCJnbG9iYWxFdmFsIiwhdHx8Yi5fZGF0YSh0W3JdLCJnbG9iYWxFdmFsIikpfWZ1bmN0aW9uIF90KGUsdCl7aWYoMT09PXQubm9kZVR5cGUmJmIuaGFzRGF0YShlKSl7dmFyIG4scixpLG89Yi5fZGF0YShlKSxhPWIuX2RhdGEodCxvKSxzPW8uZXZlbnRzO2lmKHMpe2RlbGV0ZSBhLmhhbmRsZSxhLmV2ZW50cz17fTtmb3IobiBpbiBzKWZvcihyPTAsaT1zW25dLmxlbmd0aDtpPnI7cisrKWIuZXZlbnQuYWRkKHQsbixzW25dW3JdKX1hLmRhdGEmJihhLmRhdGE9Yi5leHRlbmQoe30sYS5kYXRhKSl9fWZ1bmN0aW9uIEZ0KGUsdCl7dmFyIG4scixpO2lmKDE9PT10Lm5vZGVUeXBlKXtpZihuPXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSwhYi5zdXBwb3J0Lm5vQ2xvbmVFdmVudCYmdFtiLmV4cGFuZG9dKXtpPWIuX2RhdGEodCk7Zm9yKHIgaW4gaS5ldmVudHMpYi5yZW1vdmVFdmVudCh0LHIsaS5oYW5kbGUpO3QucmVtb3ZlQXR0cmlidXRlKGIuZXhwYW5kbyl9InNjcmlwdCI9PT1uJiZ0LnRleHQhPT1lLnRleHQ/KEh0KHQpLnRleHQ9ZS50ZXh0LHF0KHQpKToib2JqZWN0Ij09PW4/KHQucGFyZW50Tm9kZSYmKHQub3V0ZXJIVE1MPWUub3V0ZXJIVE1MKSxiLnN1cHBvcnQuaHRtbDVDbG9uZSYmZS5pbm5lckhUTUwmJiFiLnRyaW0odC5pbm5lckhUTUwpJiYodC5pbm5lckhUTUw9ZS5pbm5lckhUTUwpKToiaW5wdXQiPT09biYmTnQudGVzdChlLnR5cGUpPyh0LmRlZmF1bHRDaGVja2VkPXQuY2hlY2tlZD1lLmNoZWNrZWQsdC52YWx1ZSE9PWUudmFsdWUmJih0LnZhbHVlPWUudmFsdWUpKToib3B0aW9uIj09PW4/dC5kZWZhdWx0U2VsZWN0ZWQ9dC5zZWxlY3RlZD1lLmRlZmF1bHRTZWxlY3RlZDooImlucHV0Ij09PW58fCJ0ZXh0YXJlYSI9PT1uKSYmKHQuZGVmYXVsdFZhbHVlPWUuZGVmYXVsdFZhbHVlKX19Yi5lYWNoKHthcHBlbmRUbzoiYXBwZW5kIixwcmVwZW5kVG86InByZXBlbmQiLGluc2VydEJlZm9yZToiYmVmb3JlIixpbnNlcnRBZnRlcjoiYWZ0ZXIiLHJlcGxhY2VBbGw6InJlcGxhY2VXaXRoIn0sZnVuY3Rpb24oZSx0KXtiLmZuW2VdPWZ1bmN0aW9uKGUpe3ZhciBuLHI9MCxpPVtdLG89YihlKSxhPW8ubGVuZ3RoLTE7Zm9yKDthPj1yO3IrKyluPXI9PT1hP3RoaXM6dGhpcy5jbG9uZSghMCksYihvW3JdKVt0XShuKSxkLmFwcGx5KGksbi5nZXQoKSk7cmV0dXJuIHRoaXMucHVzaFN0YWNrKGkpfX0pO2Z1bmN0aW9uIE90KGUsbil7dmFyIHIsbyxhPTAscz10eXBlb2YgZS5nZXRFbGVtZW50c0J5VGFnTmFtZSE9PWk/ZS5nZXRFbGVtZW50c0J5VGFnTmFtZShufHwiKiIpOnR5cGVvZiBlLnF1ZXJ5U2VsZWN0b3JBbGwhPT1pP2UucXVlcnlTZWxlY3RvckFsbChufHwiKiIpOnQ7aWYoIXMpZm9yKHM9W10scj1lLmNoaWxkTm9kZXN8fGU7bnVsbCE9KG89clthXSk7YSsrKSFufHxiLm5vZGVOYW1lKG8sbik/cy5wdXNoKG8pOmIubWVyZ2UocyxPdChvLG4pKTtyZXR1cm4gbj09PXR8fG4mJmIubm9kZU5hbWUoZSxuKT9iLm1lcmdlKFtlXSxzKTpzfWZ1bmN0aW9uIEJ0KGUpe050LnRlc3QoZS50eXBlKSYmKGUuZGVmYXVsdENoZWNrZWQ9ZS5jaGVja2VkKX1iLmV4dGVuZCh7Y2xvbmU6ZnVuY3Rpb24oZSx0LG4pe3ZhciByLGksbyxhLHMsdT1iLmNvbnRhaW5zKGUub3duZXJEb2N1bWVudCxlKTtpZihiLnN1cHBvcnQuaHRtbDVDbG9uZXx8Yi5pc1hNTERvYyhlKXx8IW10LnRlc3QoIjwiK2Uubm9kZU5hbWUrIj4iKT9vPWUuY2xvbmVOb2RlKCEwKTooRHQuaW5uZXJIVE1MPWUub3V0ZXJIVE1MLER0LnJlbW92ZUNoaWxkKG89RHQuZmlyc3RDaGlsZCkpLCEoYi5zdXBwb3J0Lm5vQ2xvbmVFdmVudCYmYi5zdXBwb3J0Lm5vQ2xvbmVDaGVja2VkfHwxIT09ZS5ub2RlVHlwZSYmMTEhPT1lLm5vZGVUeXBlfHxiLmlzWE1MRG9jKGUpKSlmb3Iocj1PdChvKSxzPU90KGUpLGE9MDtudWxsIT0oaT1zW2FdKTsrK2EpclthXSYmRnQoaSxyW2FdKTtpZih0KWlmKG4pZm9yKHM9c3x8T3QoZSkscj1yfHxPdChvKSxhPTA7bnVsbCE9KGk9c1thXSk7YSsrKV90KGksclthXSk7ZWxzZSBfdChlLG8pO3JldHVybiByPU90KG8sInNjcmlwdCIpLHIubGVuZ3RoPjAmJk10KHIsIXUmJk90KGUsInNjcmlwdCIpKSxyPXM9aT1udWxsLG99LGJ1aWxkRnJhZ21lbnQ6ZnVuY3Rpb24oZSx0LG4scil7dmFyIGksbyxhLHMsdSxsLGMscD1lLmxlbmd0aCxmPWR0KHQpLGQ9W10saD0wO2Zvcig7cD5oO2grKylpZihvPWVbaF0sb3x8MD09PW8paWYoIm9iamVjdCI9PT1iLnR5cGUobykpYi5tZXJnZShkLG8ubm9kZVR5cGU/W29dOm8pO2Vsc2UgaWYod3QudGVzdChvKSl7cz1zfHxmLmFwcGVuZENoaWxkKHQuY3JlYXRlRWxlbWVudCgiZGl2IikpLHU9KGJ0LmV4ZWMobyl8fFsiIiwiIl0pWzFdLnRvTG93ZXJDYXNlKCksYz1BdFt1XXx8QXQuX2RlZmF1bHQscy5pbm5lckhUTUw9Y1sxXStvLnJlcGxhY2UodnQsIjwkMT48LyQyPiIpK2NbMl0saT1jWzBdO3doaWxlKGktLSlzPXMubGFzdENoaWxkO2lmKCFiLnN1cHBvcnQubGVhZGluZ1doaXRlc3BhY2UmJnl0LnRlc3QobykmJmQucHVzaCh0LmNyZWF0ZVRleHROb2RlKHl0LmV4ZWMobylbMF0pKSwhYi5zdXBwb3J0LnRib2R5KXtvPSJ0YWJsZSIhPT11fHx4dC50ZXN0KG8pPyI8dGFibGU+IiE9PWNbMV18fHh0LnRlc3Qobyk/MDpzOnMuZmlyc3RDaGlsZCxpPW8mJm8uY2hpbGROb2Rlcy5sZW5ndGg7d2hpbGUoaS0tKWIubm9kZU5hbWUobD1vLmNoaWxkTm9kZXNbaV0sInRib2R5IikmJiFsLmNoaWxkTm9kZXMubGVuZ3RoJiZvLnJlbW92ZUNoaWxkKGwpCn1iLm1lcmdlKGQscy5jaGlsZE5vZGVzKSxzLnRleHRDb250ZW50PSIiO3doaWxlKHMuZmlyc3RDaGlsZClzLnJlbW92ZUNoaWxkKHMuZmlyc3RDaGlsZCk7cz1mLmxhc3RDaGlsZH1lbHNlIGQucHVzaCh0LmNyZWF0ZVRleHROb2RlKG8pKTtzJiZmLnJlbW92ZUNoaWxkKHMpLGIuc3VwcG9ydC5hcHBlbmRDaGVja2VkfHxiLmdyZXAoT3QoZCwiaW5wdXQiKSxCdCksaD0wO3doaWxlKG89ZFtoKytdKWlmKCghcnx8LTE9PT1iLmluQXJyYXkobyxyKSkmJihhPWIuY29udGFpbnMoby5vd25lckRvY3VtZW50LG8pLHM9T3QoZi5hcHBlbmRDaGlsZChvKSwic2NyaXB0IiksYSYmTXQocyksbikpe2k9MDt3aGlsZShvPXNbaSsrXSlrdC50ZXN0KG8udHlwZXx8IiIpJiZuLnB1c2gobyl9cmV0dXJuIHM9bnVsbCxmfSxjbGVhbkRhdGE6ZnVuY3Rpb24oZSx0KXt2YXIgbixyLG8sYSxzPTAsdT1iLmV4cGFuZG8sbD1iLmNhY2hlLHA9Yi5zdXBwb3J0LmRlbGV0ZUV4cGFuZG8sZj1iLmV2ZW50LnNwZWNpYWw7Zm9yKDtudWxsIT0obj1lW3NdKTtzKyspaWYoKHR8fGIuYWNjZXB0RGF0YShuKSkmJihvPW5bdV0sYT1vJiZsW29dKSl7aWYoYS5ldmVudHMpZm9yKHIgaW4gYS5ldmVudHMpZltyXT9iLmV2ZW50LnJlbW92ZShuLHIpOmIucmVtb3ZlRXZlbnQobixyLGEuaGFuZGxlKTtsW29dJiYoZGVsZXRlIGxbb10scD9kZWxldGUgblt1XTp0eXBlb2Ygbi5yZW1vdmVBdHRyaWJ1dGUhPT1pP24ucmVtb3ZlQXR0cmlidXRlKHUpOm5bdV09bnVsbCxjLnB1c2gobykpfX19KTt2YXIgUHQsUnQsV3QsJHQ9L2FscGhhXChbXildKlwpL2ksSXQ9L29wYWNpdHlccyo9XHMqKFteKV0qKS8senQ9L14odG9wfHJpZ2h0fGJvdHRvbXxsZWZ0KSQvLFh0PS9eKG5vbmV8dGFibGUoPyEtY1tlYV0pLispLyxVdD0vXm1hcmdpbi8sVnQ9UmVnRXhwKCJeKCIreCsiKSguKikkIiwiaSIpLFl0PVJlZ0V4cCgiXigiK3grIikoPyFweClbYS16JV0rJCIsImkiKSxKdD1SZWdFeHAoIl4oWystXSk9KCIreCsiKSIsImkiKSxHdD17Qk9EWToiYmxvY2sifSxRdD17cG9zaXRpb246ImFic29sdXRlIix2aXNpYmlsaXR5OiJoaWRkZW4iLGRpc3BsYXk6ImJsb2NrIn0sS3Q9e2xldHRlclNwYWNpbmc6MCxmb250V2VpZ2h0OjQwMH0sWnQ9WyJUb3AiLCJSaWdodCIsIkJvdHRvbSIsIkxlZnQiXSxlbj1bIldlYmtpdCIsIk8iLCJNb3oiLCJtcyJdO2Z1bmN0aW9uIHRuKGUsdCl7aWYodCBpbiBlKXJldHVybiB0O3ZhciBuPXQuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrdC5zbGljZSgxKSxyPXQsaT1lbi5sZW5ndGg7d2hpbGUoaS0tKWlmKHQ9ZW5baV0rbix0IGluIGUpcmV0dXJuIHQ7cmV0dXJuIHJ9ZnVuY3Rpb24gbm4oZSx0KXtyZXR1cm4gZT10fHxlLCJub25lIj09PWIuY3NzKGUsImRpc3BsYXkiKXx8IWIuY29udGFpbnMoZS5vd25lckRvY3VtZW50LGUpfWZ1bmN0aW9uIHJuKGUsdCl7dmFyIG4scixpLG89W10sYT0wLHM9ZS5sZW5ndGg7Zm9yKDtzPmE7YSsrKXI9ZVthXSxyLnN0eWxlJiYob1thXT1iLl9kYXRhKHIsIm9sZGRpc3BsYXkiKSxuPXIuc3R5bGUuZGlzcGxheSx0PyhvW2FdfHwibm9uZSIhPT1ufHwoci5zdHlsZS5kaXNwbGF5PSIiKSwiIj09PXIuc3R5bGUuZGlzcGxheSYmbm4ocikmJihvW2FdPWIuX2RhdGEociwib2xkZGlzcGxheSIsdW4oci5ub2RlTmFtZSkpKSk6b1thXXx8KGk9bm4ociksKG4mJiJub25lIiE9PW58fCFpKSYmYi5fZGF0YShyLCJvbGRkaXNwbGF5IixpP246Yi5jc3MociwiZGlzcGxheSIpKSkpO2ZvcihhPTA7cz5hO2ErKylyPWVbYV0sci5zdHlsZSYmKHQmJiJub25lIiE9PXIuc3R5bGUuZGlzcGxheSYmIiIhPT1yLnN0eWxlLmRpc3BsYXl8fChyLnN0eWxlLmRpc3BsYXk9dD9vW2FdfHwiIjoibm9uZSIpKTtyZXR1cm4gZX1iLmZuLmV4dGVuZCh7Y3NzOmZ1bmN0aW9uKGUsbil7cmV0dXJuIGIuYWNjZXNzKHRoaXMsZnVuY3Rpb24oZSxuLHIpe3ZhciBpLG8sYT17fSxzPTA7aWYoYi5pc0FycmF5KG4pKXtmb3Iobz1SdChlKSxpPW4ubGVuZ3RoO2k+cztzKyspYVtuW3NdXT1iLmNzcyhlLG5bc10sITEsbyk7cmV0dXJuIGF9cmV0dXJuIHIhPT10P2Iuc3R5bGUoZSxuLHIpOmIuY3NzKGUsbil9LGUsbixhcmd1bWVudHMubGVuZ3RoPjEpfSxzaG93OmZ1bmN0aW9uKCl7cmV0dXJuIHJuKHRoaXMsITApfSxoaWRlOmZ1bmN0aW9uKCl7cmV0dXJuIHJuKHRoaXMpfSx0b2dnbGU6ZnVuY3Rpb24oZSl7dmFyIHQ9ImJvb2xlYW4iPT10eXBlb2YgZTtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7KHQ/ZTpubih0aGlzKSk/Yih0aGlzKS5zaG93KCk6Yih0aGlzKS5oaWRlKCl9KX19KSxiLmV4dGVuZCh7Y3NzSG9va3M6e29wYWNpdHk6e2dldDpmdW5jdGlvbihlLHQpe2lmKHQpe3ZhciBuPVd0KGUsIm9wYWNpdHkiKTtyZXR1cm4iIj09PW4/IjEiOm59fX19LGNzc051bWJlcjp7Y29sdW1uQ291bnQ6ITAsZmlsbE9wYWNpdHk6ITAsZm9udFdlaWdodDohMCxsaW5lSGVpZ2h0OiEwLG9wYWNpdHk6ITAsb3JwaGFuczohMCx3aWRvd3M6ITAsekluZGV4OiEwLHpvb206ITB9LGNzc1Byb3BzOnsiZmxvYXQiOmIuc3VwcG9ydC5jc3NGbG9hdD8iY3NzRmxvYXQiOiJzdHlsZUZsb2F0In0sc3R5bGU6ZnVuY3Rpb24oZSxuLHIsaSl7aWYoZSYmMyE9PWUubm9kZVR5cGUmJjghPT1lLm5vZGVUeXBlJiZlLnN0eWxlKXt2YXIgbyxhLHMsdT1iLmNhbWVsQ2FzZShuKSxsPWUuc3R5bGU7aWYobj1iLmNzc1Byb3BzW3VdfHwoYi5jc3NQcm9wc1t1XT10bihsLHUpKSxzPWIuY3NzSG9va3Nbbl18fGIuY3NzSG9va3NbdV0scj09PXQpcmV0dXJuIHMmJiJnZXQiaW4gcyYmKG89cy5nZXQoZSwhMSxpKSkhPT10P286bFtuXTtpZihhPXR5cGVvZiByLCJzdHJpbmciPT09YSYmKG89SnQuZXhlYyhyKSkmJihyPShvWzFdKzEpKm9bMl0rcGFyc2VGbG9hdChiLmNzcyhlLG4pKSxhPSJudW1iZXIiKSwhKG51bGw9PXJ8fCJudW1iZXIiPT09YSYmaXNOYU4ocil8fCgibnVtYmVyIiE9PWF8fGIuY3NzTnVtYmVyW3VdfHwocis9InB4IiksYi5zdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZXx8IiIhPT1yfHwwIT09bi5pbmRleE9mKCJiYWNrZ3JvdW5kIil8fChsW25dPSJpbmhlcml0IikscyYmInNldCJpbiBzJiYocj1zLnNldChlLHIsaSkpPT09dCkpKXRyeXtsW25dPXJ9Y2F0Y2goYyl7fX19LGNzczpmdW5jdGlvbihlLG4scixpKXt2YXIgbyxhLHMsdT1iLmNhbWVsQ2FzZShuKTtyZXR1cm4gbj1iLmNzc1Byb3BzW3VdfHwoYi5jc3NQcm9wc1t1XT10bihlLnN0eWxlLHUpKSxzPWIuY3NzSG9va3Nbbl18fGIuY3NzSG9va3NbdV0scyYmImdldCJpbiBzJiYoYT1zLmdldChlLCEwLHIpKSxhPT09dCYmKGE9V3QoZSxuLGkpKSwibm9ybWFsIj09PWEmJm4gaW4gS3QmJihhPUt0W25dKSwiIj09PXJ8fHI/KG89cGFyc2VGbG9hdChhKSxyPT09ITB8fGIuaXNOdW1lcmljKG8pP298fDA6YSk6YX0sc3dhcDpmdW5jdGlvbihlLHQsbixyKXt2YXIgaSxvLGE9e307Zm9yKG8gaW4gdClhW29dPWUuc3R5bGVbb10sZS5zdHlsZVtvXT10W29dO2k9bi5hcHBseShlLHJ8fFtdKTtmb3IobyBpbiB0KWUuc3R5bGVbb109YVtvXTtyZXR1cm4gaX19KSxlLmdldENvbXB1dGVkU3R5bGU/KFJ0PWZ1bmN0aW9uKHQpe3JldHVybiBlLmdldENvbXB1dGVkU3R5bGUodCxudWxsKX0sV3Q9ZnVuY3Rpb24oZSxuLHIpe3ZhciBpLG8sYSxzPXJ8fFJ0KGUpLHU9cz9zLmdldFByb3BlcnR5VmFsdWUobil8fHNbbl06dCxsPWUuc3R5bGU7cmV0dXJuIHMmJigiIiE9PXV8fGIuY29udGFpbnMoZS5vd25lckRvY3VtZW50LGUpfHwodT1iLnN0eWxlKGUsbikpLFl0LnRlc3QodSkmJlV0LnRlc3QobikmJihpPWwud2lkdGgsbz1sLm1pbldpZHRoLGE9bC5tYXhXaWR0aCxsLm1pbldpZHRoPWwubWF4V2lkdGg9bC53aWR0aD11LHU9cy53aWR0aCxsLndpZHRoPWksbC5taW5XaWR0aD1vLGwubWF4V2lkdGg9YSkpLHV9KTpvLmRvY3VtZW50RWxlbWVudC5jdXJyZW50U3R5bGUmJihSdD1mdW5jdGlvbihlKXtyZXR1cm4gZS5jdXJyZW50U3R5bGV9LFd0PWZ1bmN0aW9uKGUsbixyKXt2YXIgaSxvLGEscz1yfHxSdChlKSx1PXM/c1tuXTp0LGw9ZS5zdHlsZTtyZXR1cm4gbnVsbD09dSYmbCYmbFtuXSYmKHU9bFtuXSksWXQudGVzdCh1KSYmIXp0LnRlc3QobikmJihpPWwubGVmdCxvPWUucnVudGltZVN0eWxlLGE9byYmby5sZWZ0LGEmJihvLmxlZnQ9ZS5jdXJyZW50U3R5bGUubGVmdCksbC5sZWZ0PSJmb250U2l6ZSI9PT1uPyIxZW0iOnUsdT1sLnBpeGVsTGVmdCsicHgiLGwubGVmdD1pLGEmJihvLmxlZnQ9YSkpLCIiPT09dT8iYXV0byI6dX0pO2Z1bmN0aW9uIG9uKGUsdCxuKXt2YXIgcj1WdC5leGVjKHQpO3JldHVybiByP01hdGgubWF4KDAsclsxXS0obnx8MCkpKyhyWzJdfHwicHgiKTp0fWZ1bmN0aW9uIGFuKGUsdCxuLHIsaSl7dmFyIG89bj09PShyPyJib3JkZXIiOiJjb250ZW50Iik/NDoid2lkdGgiPT09dD8xOjAsYT0wO2Zvcig7ND5vO28rPTIpIm1hcmdpbiI9PT1uJiYoYSs9Yi5jc3MoZSxuK1p0W29dLCEwLGkpKSxyPygiY29udGVudCI9PT1uJiYoYS09Yi5jc3MoZSwicGFkZGluZyIrWnRbb10sITAsaSkpLCJtYXJnaW4iIT09biYmKGEtPWIuY3NzKGUsImJvcmRlciIrWnRbb10rIldpZHRoIiwhMCxpKSkpOihhKz1iLmNzcyhlLCJwYWRkaW5nIitadFtvXSwhMCxpKSwicGFkZGluZyIhPT1uJiYoYSs9Yi5jc3MoZSwiYm9yZGVyIitadFtvXSsiV2lkdGgiLCEwLGkpKSk7cmV0dXJuIGF9ZnVuY3Rpb24gc24oZSx0LG4pe3ZhciByPSEwLGk9IndpZHRoIj09PXQ/ZS5vZmZzZXRXaWR0aDplLm9mZnNldEhlaWdodCxvPVJ0KGUpLGE9Yi5zdXBwb3J0LmJveFNpemluZyYmImJvcmRlci1ib3giPT09Yi5jc3MoZSwiYm94U2l6aW5nIiwhMSxvKTtpZigwPj1pfHxudWxsPT1pKXtpZihpPVd0KGUsdCxvKSwoMD5pfHxudWxsPT1pKSYmKGk9ZS5zdHlsZVt0XSksWXQudGVzdChpKSlyZXR1cm4gaTtyPWEmJihiLnN1cHBvcnQuYm94U2l6aW5nUmVsaWFibGV8fGk9PT1lLnN0eWxlW3RdKSxpPXBhcnNlRmxvYXQoaSl8fDB9cmV0dXJuIGkrYW4oZSx0LG58fChhPyJib3JkZXIiOiJjb250ZW50IikscixvKSsicHgifWZ1bmN0aW9uIHVuKGUpe3ZhciB0PW8sbj1HdFtlXTtyZXR1cm4gbnx8KG49bG4oZSx0KSwibm9uZSIhPT1uJiZufHwoUHQ9KFB0fHxiKCI8aWZyYW1lIGZyYW1lYm9yZGVyPScwJyB3aWR0aD0nMCcgaGVpZ2h0PScwJy8+IikuY3NzKCJjc3NUZXh0IiwiZGlzcGxheTpibG9jayAhaW1wb3J0YW50IikpLmFwcGVuZFRvKHQuZG9jdW1lbnRFbGVtZW50KSx0PShQdFswXS5jb250ZW50V2luZG93fHxQdFswXS5jb250ZW50RG9jdW1lbnQpLmRvY3VtZW50LHQud3JpdGUoIjwhZG9jdHlwZSBodG1sPjxodG1sPjxib2R5PiIpLHQuY2xvc2UoKSxuPWxuKGUsdCksUHQuZGV0YWNoKCkpLEd0W2VdPW4pLG59ZnVuY3Rpb24gbG4oZSx0KXt2YXIgbj1iKHQuY3JlYXRlRWxlbWVudChlKSkuYXBwZW5kVG8odC5ib2R5KSxyPWIuY3NzKG5bMF0sImRpc3BsYXkiKTtyZXR1cm4gbi5yZW1vdmUoKSxyfWIuZWFjaChbImhlaWdodCIsIndpZHRoIl0sZnVuY3Rpb24oZSxuKXtiLmNzc0hvb2tzW25dPXtnZXQ6ZnVuY3Rpb24oZSxyLGkpe3JldHVybiByPzA9PT1lLm9mZnNldFdpZHRoJiZYdC50ZXN0KGIuY3NzKGUsImRpc3BsYXkiKSk/Yi5zd2FwKGUsUXQsZnVuY3Rpb24oKXtyZXR1cm4gc24oZSxuLGkpfSk6c24oZSxuLGkpOnR9LHNldDpmdW5jdGlvbihlLHQscil7dmFyIGk9ciYmUnQoZSk7cmV0dXJuIG9uKGUsdCxyP2FuKGUsbixyLGIuc3VwcG9ydC5ib3hTaXppbmcmJiJib3JkZXItYm94Ij09PWIuY3NzKGUsImJveFNpemluZyIsITEsaSksaSk6MCl9fX0pLGIuc3VwcG9ydC5vcGFjaXR5fHwoYi5jc3NIb29rcy5vcGFjaXR5PXtnZXQ6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gSXQudGVzdCgodCYmZS5jdXJyZW50U3R5bGU/ZS5jdXJyZW50U3R5bGUuZmlsdGVyOmUuc3R5bGUuZmlsdGVyKXx8IiIpPy4wMSpwYXJzZUZsb2F0KFJlZ0V4cC4kMSkrIiI6dD8iMSI6IiJ9LHNldDpmdW5jdGlvbihlLHQpe3ZhciBuPWUuc3R5bGUscj1lLmN1cnJlbnRTdHlsZSxpPWIuaXNOdW1lcmljKHQpPyJhbHBoYShvcGFjaXR5PSIrMTAwKnQrIikiOiIiLG89ciYmci5maWx0ZXJ8fG4uZmlsdGVyfHwiIjtuLnpvb209MSwodD49MXx8IiI9PT10KSYmIiI9PT1iLnRyaW0oby5yZXBsYWNlKCR0LCIiKSkmJm4ucmVtb3ZlQXR0cmlidXRlJiYobi5yZW1vdmVBdHRyaWJ1dGUoImZpbHRlciIpLCIiPT09dHx8ciYmIXIuZmlsdGVyKXx8KG4uZmlsdGVyPSR0LnRlc3Qobyk/by5yZXBsYWNlKCR0LGkpOm8rIiAiK2kpfX0pLGIoZnVuY3Rpb24oKXtiLnN1cHBvcnQucmVsaWFibGVNYXJnaW5SaWdodHx8KGIuY3NzSG9va3MubWFyZ2luUmlnaHQ9e2dldDpmdW5jdGlvbihlLG4pe3JldHVybiBuP2Iuc3dhcChlLHtkaXNwbGF5OiJpbmxpbmUtYmxvY2sifSxXdCxbZSwibWFyZ2luUmlnaHQiXSk6dH19KSwhYi5zdXBwb3J0LnBpeGVsUG9zaXRpb24mJmIuZm4ucG9zaXRpb24mJmIuZWFjaChbInRvcCIsImxlZnQiXSxmdW5jdGlvbihlLG4pe2IuY3NzSG9va3Nbbl09e2dldDpmdW5jdGlvbihlLHIpe3JldHVybiByPyhyPVd0KGUsbiksWXQudGVzdChyKT9iKGUpLnBvc2l0aW9uKClbbl0rInB4IjpyKTp0fX19KX0pLGIuZXhwciYmYi5leHByLmZpbHRlcnMmJihiLmV4cHIuZmlsdGVycy5oaWRkZW49ZnVuY3Rpb24oZSl7cmV0dXJuIDA+PWUub2Zmc2V0V2lkdGgmJjA+PWUub2Zmc2V0SGVpZ2h0fHwhYi5zdXBwb3J0LnJlbGlhYmxlSGlkZGVuT2Zmc2V0cyYmIm5vbmUiPT09KGUuc3R5bGUmJmUuc3R5bGUuZGlzcGxheXx8Yi5jc3MoZSwiZGlzcGxheSIpKX0sYi5leHByLmZpbHRlcnMudmlzaWJsZT1mdW5jdGlvbihlKXtyZXR1cm4hYi5leHByLmZpbHRlcnMuaGlkZGVuKGUpfSksYi5lYWNoKHttYXJnaW46IiIscGFkZGluZzoiIixib3JkZXI6IldpZHRoIn0sZnVuY3Rpb24oZSx0KXtiLmNzc0hvb2tzW2UrdF09e2V4cGFuZDpmdW5jdGlvbihuKXt2YXIgcj0wLGk9e30sbz0ic3RyaW5nIj09dHlwZW9mIG4/bi5zcGxpdCgiICIpOltuXTtmb3IoOzQ+cjtyKyspaVtlK1p0W3JdK3RdPW9bcl18fG9bci0yXXx8b1swXTtyZXR1cm4gaX19LFV0LnRlc3QoZSl8fChiLmNzc0hvb2tzW2UrdF0uc2V0PW9uKX0pO3ZhciBjbj0vJTIwL2cscG49L1xbXF0kLyxmbj0vXHI/XG4vZyxkbj0vXig/OnN1Ym1pdHxidXR0b258aW1hZ2V8cmVzZXR8ZmlsZSkkL2ksaG49L14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8a2V5Z2VuKS9pO2IuZm4uZXh0ZW5kKHtzZXJpYWxpemU6ZnVuY3Rpb24oKXtyZXR1cm4gYi5wYXJhbSh0aGlzLnNlcmlhbGl6ZUFycmF5KCkpfSxzZXJpYWxpemVBcnJheTpmdW5jdGlvbigpe3JldHVybiB0aGlzLm1hcChmdW5jdGlvbigpe3ZhciBlPWIucHJvcCh0aGlzLCJlbGVtZW50cyIpO3JldHVybiBlP2IubWFrZUFycmF5KGUpOnRoaXN9KS5maWx0ZXIoZnVuY3Rpb24oKXt2YXIgZT10aGlzLnR5cGU7cmV0dXJuIHRoaXMubmFtZSYmIWIodGhpcykuaXMoIjpkaXNhYmxlZCIpJiZobi50ZXN0KHRoaXMubm9kZU5hbWUpJiYhZG4udGVzdChlKSYmKHRoaXMuY2hlY2tlZHx8IU50LnRlc3QoZSkpfSkubWFwKGZ1bmN0aW9uKGUsdCl7dmFyIG49Yih0aGlzKS52YWwoKTtyZXR1cm4gbnVsbD09bj9udWxsOmIuaXNBcnJheShuKT9iLm1hcChuLGZ1bmN0aW9uKGUpe3JldHVybntuYW1lOnQubmFtZSx2YWx1ZTplLnJlcGxhY2UoZm4sIlxyXG4iKX19KTp7bmFtZTp0Lm5hbWUsdmFsdWU6bi5yZXBsYWNlKGZuLCJcclxuIil9fSkuZ2V0KCl9fSksYi5wYXJhbT1mdW5jdGlvbihlLG4pe3ZhciByLGk9W10sbz1mdW5jdGlvbihlLHQpe3Q9Yi5pc0Z1bmN0aW9uKHQpP3QoKTpudWxsPT10PyIiOnQsaVtpLmxlbmd0aF09ZW5jb2RlVVJJQ29tcG9uZW50KGUpKyI9IitlbmNvZGVVUklDb21wb25lbnQodCl9O2lmKG49PT10JiYobj1iLmFqYXhTZXR0aW5ncyYmYi5hamF4U2V0dGluZ3MudHJhZGl0aW9uYWwpLGIuaXNBcnJheShlKXx8ZS5qcXVlcnkmJiFiLmlzUGxhaW5PYmplY3QoZSkpYi5lYWNoKGUsZnVuY3Rpb24oKXtvKHRoaXMubmFtZSx0aGlzLnZhbHVlKX0pO2Vsc2UgZm9yKHIgaW4gZSlnbihyLGVbcl0sbixvKTtyZXR1cm4gaS5qb2luKCImIikucmVwbGFjZShjbiwiKyIpfTtmdW5jdGlvbiBnbihlLHQsbixyKXt2YXIgaTtpZihiLmlzQXJyYXkodCkpYi5lYWNoKHQsZnVuY3Rpb24odCxpKXtufHxwbi50ZXN0KGUpP3IoZSxpKTpnbihlKyJbIisoIm9iamVjdCI9PXR5cGVvZiBpP3Q6IiIpKyJdIixpLG4scil9KTtlbHNlIGlmKG58fCJvYmplY3QiIT09Yi50eXBlKHQpKXIoZSx0KTtlbHNlIGZvcihpIGluIHQpZ24oZSsiWyIraSsiXSIsdFtpXSxuLHIpfWIuZWFjaCgiYmx1ciBmb2N1cyBmb2N1c2luIGZvY3Vzb3V0IGxvYWQgcmVzaXplIHNjcm9sbCB1bmxvYWQgY2xpY2sgZGJsY2xpY2sgbW91c2Vkb3duIG1vdXNldXAgbW91c2Vtb3ZlIG1vdXNlb3ZlciBtb3VzZW91dCBtb3VzZWVudGVyIG1vdXNlbGVhdmUgY2hhbmdlIHNlbGVjdCBzdWJtaXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBlcnJvciBjb250ZXh0bWVudSIuc3BsaXQoIiAiKSxmdW5jdGlvbihlLHQpe2IuZm5bdF09ZnVuY3Rpb24oZSxuKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD4wP3RoaXMub24odCxudWxsLGUsbik6dGhpcy50cmlnZ2VyKHQpfX0pLGIuZm4uaG92ZXI9ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdGhpcy5tb3VzZWVudGVyKGUpLm1vdXNlbGVhdmUodHx8ZSl9O3ZhciBtbix5bix2bj1iLm5vdygpLGJuPS9cPy8seG49LyMuKiQvLHduPS8oWz8mXSlfPVteJl0qLyxUbj0vXiguKj8pOlsgXHRdKihbXlxyXG5dKilccj8kL2dtLE5uPS9eKD86YWJvdXR8YXBwfGFwcC1zdG9yYWdlfC4rLWV4dGVuc2lvbnxmaWxlfHJlc3x3aWRnZXQpOiQvLENuPS9eKD86R0VUfEhFQUQpJC8sa249L15cL1wvLyxFbj0vXihbXHcuKy1dKzopKD86XC9cLyhbXlwvPyM6XSopKD86OihcZCspfCl8KS8sU249Yi5mbi5sb2FkLEFuPXt9LGpuPXt9LERuPSIqLyIuY29uY2F0KCIqIik7dHJ5e3luPWEuaHJlZn1jYXRjaChMbil7eW49by5jcmVhdGVFbGVtZW50KCJhIikseW4uaHJlZj0iIix5bj15bi5ocmVmfW1uPUVuLmV4ZWMoeW4udG9Mb3dlckNhc2UoKSl8fFtdO2Z1bmN0aW9uIEhuKGUpe3JldHVybiBmdW5jdGlvbih0LG4peyJzdHJpbmciIT10eXBlb2YgdCYmKG49dCx0PSIqIik7dmFyIHIsaT0wLG89dC50b0xvd2VyQ2FzZSgpLm1hdGNoKHcpfHxbXTtpZihiLmlzRnVuY3Rpb24obikpd2hpbGUocj1vW2krK10pIisiPT09clswXT8ocj1yLnNsaWNlKDEpfHwiKiIsKGVbcl09ZVtyXXx8W10pLnVuc2hpZnQobikpOihlW3JdPWVbcl18fFtdKS5wdXNoKG4pfX1mdW5jdGlvbiBxbihlLG4scixpKXt2YXIgbz17fSxhPWU9PT1qbjtmdW5jdGlvbiBzKHUpe3ZhciBsO3JldHVybiBvW3VdPSEwLGIuZWFjaChlW3VdfHxbXSxmdW5jdGlvbihlLHUpe3ZhciBjPXUobixyLGkpO3JldHVybiJzdHJpbmciIT10eXBlb2YgY3x8YXx8b1tjXT9hPyEobD1jKTp0OihuLmRhdGFUeXBlcy51bnNoaWZ0KGMpLHMoYyksITEpfSksbH1yZXR1cm4gcyhuLmRhdGFUeXBlc1swXSl8fCFvWyIqIl0mJnMoIioiKX1mdW5jdGlvbiBNbihlLG4pe3ZhciByLGksbz1iLmFqYXhTZXR0aW5ncy5mbGF0T3B0aW9uc3x8e307Zm9yKGkgaW4gbiluW2ldIT09dCYmKChvW2ldP2U6cnx8KHI9e30pKVtpXT1uW2ldKTtyZXR1cm4gciYmYi5leHRlbmQoITAsZSxyKSxlfWIuZm4ubG9hZD1mdW5jdGlvbihlLG4scil7aWYoInN0cmluZyIhPXR5cGVvZiBlJiZTbilyZXR1cm4gU24uYXBwbHkodGhpcyxhcmd1bWVudHMpO3ZhciBpLG8sYSxzPXRoaXMsdT1lLmluZGV4T2YoIiAiKTtyZXR1cm4gdT49MCYmKGk9ZS5zbGljZSh1LGUubGVuZ3RoKSxlPWUuc2xpY2UoMCx1KSksYi5pc0Z1bmN0aW9uKG4pPyhyPW4sbj10KTpuJiYib2JqZWN0Ij09dHlwZW9mIG4mJihhPSJQT1NUIikscy5sZW5ndGg+MCYmYi5hamF4KHt1cmw6ZSx0eXBlOmEsZGF0YVR5cGU6Imh0bWwiLGRhdGE6bn0pLmRvbmUoZnVuY3Rpb24oZSl7bz1hcmd1bWVudHMscy5odG1sKGk/YigiPGRpdj4iKS5hcHBlbmQoYi5wYXJzZUhUTUwoZSkpLmZpbmQoaSk6ZSl9KS5jb21wbGV0ZShyJiZmdW5jdGlvbihlLHQpe3MuZWFjaChyLG98fFtlLnJlc3BvbnNlVGV4dCx0LGVdKX0pLHRoaXN9LGIuZWFjaChbImFqYXhTdGFydCIsImFqYXhTdG9wIiwiYWpheENvbXBsZXRlIiwiYWpheEVycm9yIiwiYWpheFN1Y2Nlc3MiLCJhamF4U2VuZCJdLGZ1bmN0aW9uKGUsdCl7Yi5mblt0XT1mdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5vbih0LGUpfX0pLGIuZWFjaChbImdldCIsInBvc3QiXSxmdW5jdGlvbihlLG4pe2Jbbl09ZnVuY3Rpb24oZSxyLGksbyl7cmV0dXJuIGIuaXNGdW5jdGlvbihyKSYmKG89b3x8aSxpPXIscj10KSxiLmFqYXgoe3VybDplLHR5cGU6bixkYXRhVHlwZTpvLGRhdGE6cixzdWNjZXNzOml9KX19KSxiLmV4dGVuZCh7YWN0aXZlOjAsbGFzdE1vZGlmaWVkOnt9LGV0YWc6e30sYWpheFNldHRpbmdzOnt1cmw6eW4sdHlwZToiR0VUIixpc0xvY2FsOk5uLnRlc3QobW5bMV0pLGdsb2JhbDohMCxwcm9jZXNzRGF0YTohMCxhc3luYzohMCxjb250ZW50VHlwZToiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04IixhY2NlcHRzOnsiKiI6RG4sdGV4dDoidGV4dC9wbGFpbiIsaHRtbDoidGV4dC9odG1sIix4bWw6ImFwcGxpY2F0aW9uL3htbCwgdGV4dC94bWwiLGpzb246ImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdCJ9LGNvbnRlbnRzOnt4bWw6L3htbC8saHRtbDovaHRtbC8sanNvbjovanNvbi99LHJlc3BvbnNlRmllbGRzOnt4bWw6InJlc3BvbnNlWE1MIix0ZXh0OiJyZXNwb25zZVRleHQifSxjb252ZXJ0ZXJzOnsiKiB0ZXh0IjplLlN0cmluZywidGV4dCBodG1sIjohMCwidGV4dCBqc29uIjpiLnBhcnNlSlNPTiwidGV4dCB4bWwiOmIucGFyc2VYTUx9LGZsYXRPcHRpb25zOnt1cmw6ITAsY29udGV4dDohMH19LGFqYXhTZXR1cDpmdW5jdGlvbihlLHQpe3JldHVybiB0P01uKE1uKGUsYi5hamF4U2V0dGluZ3MpLHQpOk1uKGIuYWpheFNldHRpbmdzLGUpfSxhamF4UHJlZmlsdGVyOkhuKEFuKSxhamF4VHJhbnNwb3J0OkhuKGpuKSxhamF4OmZ1bmN0aW9uKGUsbil7Im9iamVjdCI9PXR5cGVvZiBlJiYobj1lLGU9dCksbj1ufHx7fTt2YXIgcixpLG8sYSxzLHUsbCxjLHA9Yi5hamF4U2V0dXAoe30sbiksZj1wLmNvbnRleHR8fHAsZD1wLmNvbnRleHQmJihmLm5vZGVUeXBlfHxmLmpxdWVyeSk/YihmKTpiLmV2ZW50LGg9Yi5EZWZlcnJlZCgpLGc9Yi5DYWxsYmFja3MoIm9uY2UgbWVtb3J5IiksbT1wLnN0YXR1c0NvZGV8fHt9LHk9e30sdj17fSx4PTAsVD0iY2FuY2VsZWQiLE49e3JlYWR5U3RhdGU6MCxnZXRSZXNwb25zZUhlYWRlcjpmdW5jdGlvbihlKXt2YXIgdDtpZigyPT09eCl7aWYoIWMpe2M9e307d2hpbGUodD1Ubi5leGVjKGEpKWNbdFsxXS50b0xvd2VyQ2FzZSgpXT10WzJdfXQ9Y1tlLnRvTG93ZXJDYXNlKCldfXJldHVybiBudWxsPT10P251bGw6dH0sZ2V0QWxsUmVzcG9uc2VIZWFkZXJzOmZ1bmN0aW9uKCl7cmV0dXJuIDI9PT14P2E6bnVsbH0sc2V0UmVxdWVzdEhlYWRlcjpmdW5jdGlvbihlLHQpe3ZhciBuPWUudG9Mb3dlckNhc2UoKTtyZXR1cm4geHx8KGU9dltuXT12W25dfHxlLHlbZV09dCksdGhpc30sb3ZlcnJpZGVNaW1lVHlwZTpmdW5jdGlvbihlKXtyZXR1cm4geHx8KHAubWltZVR5cGU9ZSksdGhpc30sc3RhdHVzQ29kZTpmdW5jdGlvbihlKXt2YXIgdDtpZihlKWlmKDI+eClmb3IodCBpbiBlKW1bdF09W21bdF0sZVt0XV07ZWxzZSBOLmFsd2F5cyhlW04uc3RhdHVzXSk7cmV0dXJuIHRoaXN9LGFib3J0OmZ1bmN0aW9uKGUpe3ZhciB0PWV8fFQ7cmV0dXJuIGwmJmwuYWJvcnQodCksaygwLHQpLHRoaXN9fTtpZihoLnByb21pc2UoTikuY29tcGxldGU9Zy5hZGQsTi5zdWNjZXNzPU4uZG9uZSxOLmVycm9yPU4uZmFpbCxwLnVybD0oKGV8fHAudXJsfHx5bikrIiIpLnJlcGxhY2UoeG4sIiIpLnJlcGxhY2Uoa24sbW5bMV0rIi8vIikscC50eXBlPW4ubWV0aG9kfHxuLnR5cGV8fHAubWV0aG9kfHxwLnR5cGUscC5kYXRhVHlwZXM9Yi50cmltKHAuZGF0YVR5cGV8fCIqIikudG9Mb3dlckNhc2UoKS5tYXRjaCh3KXx8WyIiXSxudWxsPT1wLmNyb3NzRG9tYWluJiYocj1Fbi5leGVjKHAudXJsLnRvTG93ZXJDYXNlKCkpLHAuY3Jvc3NEb21haW49ISghcnx8clsxXT09PW1uWzFdJiZyWzJdPT09bW5bMl0mJihyWzNdfHwoImh0dHA6Ij09PXJbMV0/ODA6NDQzKSk9PShtblszXXx8KCJodHRwOiI9PT1tblsxXT84MDo0NDMpKSkpLHAuZGF0YSYmcC5wcm9jZXNzRGF0YSYmInN0cmluZyIhPXR5cGVvZiBwLmRhdGEmJihwLmRhdGE9Yi5wYXJhbShwLmRhdGEscC50cmFkaXRpb25hbCkpLHFuKEFuLHAsbixOKSwyPT09eClyZXR1cm4gTjt1PXAuZ2xvYmFsLHUmJjA9PT1iLmFjdGl2ZSsrJiZiLmV2ZW50LnRyaWdnZXIoImFqYXhTdGFydCIpLHAudHlwZT1wLnR5cGUudG9VcHBlckNhc2UoKSxwLmhhc0NvbnRlbnQ9IUNuLnRlc3QocC50eXBlKSxvPXAudXJsLHAuaGFzQ29udGVudHx8KHAuZGF0YSYmKG89cC51cmwrPShibi50ZXN0KG8pPyImIjoiPyIpK3AuZGF0YSxkZWxldGUgcC5kYXRhKSxwLmNhY2hlPT09ITEmJihwLnVybD13bi50ZXN0KG8pP28ucmVwbGFjZSh3biwiJDFfPSIrdm4rKyk6bysoYm4udGVzdChvKT8iJiI6Ij8iKSsiXz0iK3ZuKyspKSxwLmlmTW9kaWZpZWQmJihiLmxhc3RNb2RpZmllZFtvXSYmTi5zZXRSZXF1ZXN0SGVhZGVyKCJJZi1Nb2RpZmllZC1TaW5jZSIsYi5sYXN0TW9kaWZpZWRbb10pLGIuZXRhZ1tvXSYmTi5zZXRSZXF1ZXN0SGVhZGVyKCJJZi1Ob25lLU1hdGNoIixiLmV0YWdbb10pKSwocC5kYXRhJiZwLmhhc0NvbnRlbnQmJnAuY29udGVudFR5cGUhPT0hMXx8bi5jb250ZW50VHlwZSkmJk4uc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBlIixwLmNvbnRlbnRUeXBlKSxOLnNldFJlcXVlc3RIZWFkZXIoIkFjY2VwdCIscC5kYXRhVHlwZXNbMF0mJnAuYWNjZXB0c1twLmRhdGFUeXBlc1swXV0/cC5hY2NlcHRzW3AuZGF0YVR5cGVzWzBdXSsoIioiIT09cC5kYXRhVHlwZXNbMF0/IiwgIitEbisiOyBxPTAuMDEiOiIiKTpwLmFjY2VwdHNbIioiXSk7Zm9yKGkgaW4gcC5oZWFkZXJzKU4uc2V0UmVxdWVzdEhlYWRlcihpLHAuaGVhZGVyc1tpXSk7aWYocC5iZWZvcmVTZW5kJiYocC5iZWZvcmVTZW5kLmNhbGwoZixOLHApPT09ITF8fDI9PT14KSlyZXR1cm4gTi5hYm9ydCgpO1Q9ImFib3J0Ijtmb3IoaSBpbntzdWNjZXNzOjEsZXJyb3I6MSxjb21wbGV0ZToxfSlOW2ldKHBbaV0pO2lmKGw9cW4oam4scCxuLE4pKXtOLnJlYWR5U3RhdGU9MSx1JiZkLnRyaWdnZXIoImFqYXhTZW5kIixbTixwXSkscC5hc3luYyYmcC50aW1lb3V0PjAmJihzPXNldFRpbWVvdXQoZnVuY3Rpb24oKXtOLmFib3J0KCJ0aW1lb3V0Iil9LHAudGltZW91dCkpO3RyeXt4PTEsbC5zZW5kKHksayl9Y2F0Y2goQyl7aWYoISgyPngpKXRocm93IEM7aygtMSxDKX19ZWxzZSBrKC0xLCJObyBUcmFuc3BvcnQiKTtmdW5jdGlvbiBrKGUsbixyLGkpe3ZhciBjLHksdix3LFQsQz1uOzIhPT14JiYoeD0yLHMmJmNsZWFyVGltZW91dChzKSxsPXQsYT1pfHwiIixOLnJlYWR5U3RhdGU9ZT4wPzQ6MCxyJiYodz1fbihwLE4scikpLGU+PTIwMCYmMzAwPmV8fDMwND09PWU/KHAuaWZNb2RpZmllZCYmKFQ9Ti5nZXRSZXNwb25zZUhlYWRlcigiTGFzdC1Nb2RpZmllZCIpLFQmJihiLmxhc3RNb2RpZmllZFtvXT1UKSxUPU4uZ2V0UmVzcG9uc2VIZWFkZXIoImV0YWciKSxUJiYoYi5ldGFnW29dPVQpKSwyMDQ9PT1lPyhjPSEwLEM9Im5vY29udGVudCIpOjMwND09PWU/KGM9ITAsQz0ibm90bW9kaWZpZWQiKTooYz1GbihwLHcpLEM9Yy5zdGF0ZSx5PWMuZGF0YSx2PWMuZXJyb3IsYz0hdikpOih2PUMsKGV8fCFDKSYmKEM9ImVycm9yIiwwPmUmJihlPTApKSksTi5zdGF0dXM9ZSxOLnN0YXR1c1RleHQ9KG58fEMpKyIiLGM/aC5yZXNvbHZlV2l0aChmLFt5LEMsTl0pOmgucmVqZWN0V2l0aChmLFtOLEMsdl0pLE4uc3RhdHVzQ29kZShtKSxtPXQsdSYmZC50cmlnZ2VyKGM/ImFqYXhTdWNjZXNzIjoiYWpheEVycm9yIixbTixwLGM/eTp2XSksZy5maXJlV2l0aChmLFtOLENdKSx1JiYoZC50cmlnZ2VyKCJhamF4Q29tcGxldGUiLFtOLHBdKSwtLWIuYWN0aXZlfHxiLmV2ZW50LnRyaWdnZXIoImFqYXhTdG9wIikpKX1yZXR1cm4gTn0sZ2V0U2NyaXB0OmZ1bmN0aW9uKGUsbil7cmV0dXJuIGIuZ2V0KGUsdCxuLCJzY3JpcHQiKX0sZ2V0SlNPTjpmdW5jdGlvbihlLHQsbil7cmV0dXJuIGIuZ2V0KGUsdCxuLCJqc29uIil9fSk7ZnVuY3Rpb24gX24oZSxuLHIpe3ZhciBpLG8sYSxzLHU9ZS5jb250ZW50cyxsPWUuZGF0YVR5cGVzLGM9ZS5yZXNwb25zZUZpZWxkcztmb3IocyBpbiBjKXMgaW4gciYmKG5bY1tzXV09cltzXSk7d2hpbGUoIioiPT09bFswXSlsLnNoaWZ0KCksbz09PXQmJihvPWUubWltZVR5cGV8fG4uZ2V0UmVzcG9uc2VIZWFkZXIoIkNvbnRlbnQtVHlwZSIpKTtpZihvKWZvcihzIGluIHUpaWYodVtzXSYmdVtzXS50ZXN0KG8pKXtsLnVuc2hpZnQocyk7YnJlYWt9aWYobFswXWluIHIpYT1sWzBdO2Vsc2V7Zm9yKHMgaW4gcil7aWYoIWxbMF18fGUuY29udmVydGVyc1tzKyIgIitsWzBdXSl7YT1zO2JyZWFrfWl8fChpPXMpfWE9YXx8aX1yZXR1cm4gYT8oYSE9PWxbMF0mJmwudW5zaGlmdChhKSxyW2FdKTp0fWZ1bmN0aW9uIEZuKGUsdCl7dmFyIG4scixpLG8sYT17fSxzPTAsdT1lLmRhdGFUeXBlcy5zbGljZSgpLGw9dVswXTtpZihlLmRhdGFGaWx0ZXImJih0PWUuZGF0YUZpbHRlcih0LGUuZGF0YVR5cGUpKSx1WzFdKWZvcihpIGluIGUuY29udmVydGVycylhW2kudG9Mb3dlckNhc2UoKV09ZS5jb252ZXJ0ZXJzW2ldO2Zvcig7cj11Wysrc107KWlmKCIqIiE9PXIpe2lmKCIqIiE9PWwmJmwhPT1yKXtpZihpPWFbbCsiICIrcl18fGFbIiogIityXSwhaSlmb3IobiBpbiBhKWlmKG89bi5zcGxpdCgiICIpLG9bMV09PT1yJiYoaT1hW2wrIiAiK29bMF1dfHxhWyIqICIrb1swXV0pKXtpPT09ITA/aT1hW25dOmFbbl0hPT0hMCYmKHI9b1swXSx1LnNwbGljZShzLS0sMCxyKSk7YnJlYWt9aWYoaSE9PSEwKWlmKGkmJmVbInRocm93cyJdKXQ9aSh0KTtlbHNlIHRyeXt0PWkodCl9Y2F0Y2goYyl7cmV0dXJue3N0YXRlOiJwYXJzZXJlcnJvciIsZXJyb3I6aT9jOiJObyBjb252ZXJzaW9uIGZyb20gIitsKyIgdG8gIityfX19bD1yfXJldHVybntzdGF0ZToic3VjY2VzcyIsZGF0YTp0fX1iLmFqYXhTZXR1cCh7YWNjZXB0czp7c2NyaXB0OiJ0ZXh0L2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2VjbWFzY3JpcHQsIGFwcGxpY2F0aW9uL3gtZWNtYXNjcmlwdCJ9LGNvbnRlbnRzOntzY3JpcHQ6Lyg/OmphdmF8ZWNtYSlzY3JpcHQvfSxjb252ZXJ0ZXJzOnsidGV4dCBzY3JpcHQiOmZ1bmN0aW9uKGUpe3JldHVybiBiLmdsb2JhbEV2YWwoZSksZX19fSksYi5hamF4UHJlZmlsdGVyKCJzY3JpcHQiLGZ1bmN0aW9uKGUpe2UuY2FjaGU9PT10JiYoZS5jYWNoZT0hMSksZS5jcm9zc0RvbWFpbiYmKGUudHlwZT0iR0VUIixlLmdsb2JhbD0hMSl9KSxiLmFqYXhUcmFuc3BvcnQoInNjcmlwdCIsZnVuY3Rpb24oZSl7aWYoZS5jcm9zc0RvbWFpbil7dmFyIG4scj1vLmhlYWR8fGIoImhlYWQiKVswXXx8by5kb2N1bWVudEVsZW1lbnQ7cmV0dXJue3NlbmQ6ZnVuY3Rpb24odCxpKXtuPW8uY3JlYXRlRWxlbWVudCgic2NyaXB0Iiksbi5hc3luYz0hMCxlLnNjcmlwdENoYXJzZXQmJihuLmNoYXJzZXQ9ZS5zY3JpcHRDaGFyc2V0KSxuLnNyYz1lLnVybCxuLm9ubG9hZD1uLm9ucmVhZHlzdGF0ZWNoYW5nZT1mdW5jdGlvbihlLHQpeyh0fHwhbi5yZWFkeVN0YXRlfHwvbG9hZGVkfGNvbXBsZXRlLy50ZXN0KG4ucmVhZHlTdGF0ZSkpJiYobi5vbmxvYWQ9bi5vbnJlYWR5c3RhdGVjaGFuZ2U9bnVsbCxuLnBhcmVudE5vZGUmJm4ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChuKSxuPW51bGwsdHx8aSgyMDAsInN1Y2Nlc3MiKSl9LHIuaW5zZXJ0QmVmb3JlKG4sci5maXJzdENoaWxkKX0sYWJvcnQ6ZnVuY3Rpb24oKXtuJiZuLm9ubG9hZCh0LCEwKX19fX0pO3ZhciBPbj1bXSxCbj0vKD0pXD8oPz0mfCQpfFw/XD8vO2IuYWpheFNldHVwKHtqc29ucDoiY2FsbGJhY2siLGpzb25wQ2FsbGJhY2s6ZnVuY3Rpb24oKXt2YXIgZT1Pbi5wb3AoKXx8Yi5leHBhbmRvKyJfIit2bisrO3JldHVybiB0aGlzW2VdPSEwLGV9fSksYi5hamF4UHJlZmlsdGVyKCJqc29uIGpzb25wIixmdW5jdGlvbihuLHIsaSl7dmFyIG8sYSxzLHU9bi5qc29ucCE9PSExJiYoQm4udGVzdChuLnVybCk/InVybCI6InN0cmluZyI9PXR5cGVvZiBuLmRhdGEmJiEobi5jb250ZW50VHlwZXx8IiIpLmluZGV4T2YoImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIpJiZCbi50ZXN0KG4uZGF0YSkmJiJkYXRhIik7cmV0dXJuIHV8fCJqc29ucCI9PT1uLmRhdGFUeXBlc1swXT8obz1uLmpzb25wQ2FsbGJhY2s9Yi5pc0Z1bmN0aW9uKG4uanNvbnBDYWxsYmFjayk/bi5qc29ucENhbGxiYWNrKCk6bi5qc29ucENhbGxiYWNrLHU/blt1XT1uW3VdLnJlcGxhY2UoQm4sIiQxIitvKTpuLmpzb25wIT09ITEmJihuLnVybCs9KGJuLnRlc3Qobi51cmwpPyImIjoiPyIpK24uanNvbnArIj0iK28pLG4uY29udmVydGVyc1sic2NyaXB0IGpzb24iXT1mdW5jdGlvbigpe3JldHVybiBzfHxiLmVycm9yKG8rIiB3YXMgbm90IGNhbGxlZCIpLHNbMF19LG4uZGF0YVR5cGVzWzBdPSJqc29uIixhPWVbb10sZVtvXT1mdW5jdGlvbigpe3M9YXJndW1lbnRzfSxpLmFsd2F5cyhmdW5jdGlvbigpe2Vbb109YSxuW29dJiYobi5qc29ucENhbGxiYWNrPXIuanNvbnBDYWxsYmFjayxPbi5wdXNoKG8pKSxzJiZiLmlzRnVuY3Rpb24oYSkmJmEoc1swXSkscz1hPXR9KSwic2NyaXB0Iik6dH0pO3ZhciBQbixSbixXbj0wLCRuPWUuQWN0aXZlWE9iamVjdCYmZnVuY3Rpb24oKXt2YXIgZTtmb3IoZSBpbiBQbilQbltlXSh0LCEwKX07ZnVuY3Rpb24gSW4oKXt0cnl7cmV0dXJuIG5ldyBlLlhNTEh0dHBSZXF1ZXN0fWNhdGNoKHQpe319ZnVuY3Rpb24gem4oKXt0cnl7cmV0dXJuIG5ldyBlLkFjdGl2ZVhPYmplY3QoIk1pY3Jvc29mdC5YTUxIVFRQIil9Y2F0Y2godCl7fX1iLmFqYXhTZXR0aW5ncy54aHI9ZS5BY3RpdmVYT2JqZWN0P2Z1bmN0aW9uKCl7cmV0dXJuIXRoaXMuaXNMb2NhbCYmSW4oKXx8em4oKX06SW4sUm49Yi5hamF4U2V0dGluZ3MueGhyKCksYi5zdXBwb3J0LmNvcnM9ISFSbiYmIndpdGhDcmVkZW50aWFscyJpbiBSbixSbj1iLnN1cHBvcnQuYWpheD0hIVJuLFJuJiZiLmFqYXhUcmFuc3BvcnQoZnVuY3Rpb24obil7aWYoIW4uY3Jvc3NEb21haW58fGIuc3VwcG9ydC5jb3JzKXt2YXIgcjtyZXR1cm57c2VuZDpmdW5jdGlvbihpLG8pe3ZhciBhLHMsdT1uLnhocigpO2lmKG4udXNlcm5hbWU/dS5vcGVuKG4udHlwZSxuLnVybCxuLmFzeW5jLG4udXNlcm5hbWUsbi5wYXNzd29yZCk6dS5vcGVuKG4udHlwZSxuLnVybCxuLmFzeW5jKSxuLnhockZpZWxkcylmb3IocyBpbiBuLnhockZpZWxkcyl1W3NdPW4ueGhyRmllbGRzW3NdO24ubWltZVR5cGUmJnUub3ZlcnJpZGVNaW1lVHlwZSYmdS5vdmVycmlkZU1pbWVUeXBlKG4ubWltZVR5cGUpLG4uY3Jvc3NEb21haW58fGlbIlgtUmVxdWVzdGVkLVdpdGgiXXx8KGlbIlgtUmVxdWVzdGVkLVdpdGgiXT0iWE1MSHR0cFJlcXVlc3QiKTt0cnl7Zm9yKHMgaW4gaSl1LnNldFJlcXVlc3RIZWFkZXIocyxpW3NdKX1jYXRjaChsKXt9dS5zZW5kKG4uaGFzQ29udGVudCYmbi5kYXRhfHxudWxsKSxyPWZ1bmN0aW9uKGUsaSl7dmFyIHMsbCxjLHA7dHJ5e2lmKHImJihpfHw0PT09dS5yZWFkeVN0YXRlKSlpZihyPXQsYSYmKHUub25yZWFkeXN0YXRlY2hhbmdlPWIubm9vcCwkbiYmZGVsZXRlIFBuW2FdKSxpKTQhPT11LnJlYWR5U3RhdGUmJnUuYWJvcnQoKTtlbHNle3A9e30scz11LnN0YXR1cyxsPXUuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCksInN0cmluZyI9PXR5cGVvZiB1LnJlc3BvbnNlVGV4dCYmKHAudGV4dD11LnJlc3BvbnNlVGV4dCk7dHJ5e2M9dS5zdGF0dXNUZXh0fWNhdGNoKGYpe2M9IiJ9c3x8IW4uaXNMb2NhbHx8bi5jcm9zc0RvbWFpbj8xMjIzPT09cyYmKHM9MjA0KTpzPXAudGV4dD8yMDA6NDA0fX1jYXRjaChkKXtpfHxvKC0xLGQpfXAmJm8ocyxjLHAsbCl9LG4uYXN5bmM/ND09PXUucmVhZHlTdGF0ZT9zZXRUaW1lb3V0KHIpOihhPSsrV24sJG4mJihQbnx8KFBuPXt9LGIoZSkudW5sb2FkKCRuKSksUG5bYV09ciksdS5vbnJlYWR5c3RhdGVjaGFuZ2U9cik6cigpfSxhYm9ydDpmdW5jdGlvbigpe3ImJnIodCwhMCl9fX19KTt2YXIgWG4sVW4sVm49L14oPzp0b2dnbGV8c2hvd3xoaWRlKSQvLFluPVJlZ0V4cCgiXig/OihbKy1dKT18KSgiK3grIikoW2EteiVdKikkIiwiaSIpLEpuPS9xdWV1ZUhvb2tzJC8sR249W25yXSxRbj17IioiOltmdW5jdGlvbihlLHQpe3ZhciBuLHIsaT10aGlzLmNyZWF0ZVR3ZWVuKGUsdCksbz1Zbi5leGVjKHQpLGE9aS5jdXIoKSxzPSthfHwwLHU9MSxsPTIwO2lmKG8pe2lmKG49K29bMl0scj1vWzNdfHwoYi5jc3NOdW1iZXJbZV0/IiI6InB4IiksInB4IiE9PXImJnMpe3M9Yi5jc3MoaS5lbGVtLGUsITApfHxufHwxO2RvIHU9dXx8Ii41IixzLz11LGIuc3R5bGUoaS5lbGVtLGUscytyKTt3aGlsZSh1IT09KHU9aS5jdXIoKS9hKSYmMSE9PXUmJi0tbCl9aS51bml0PXIsaS5zdGFydD1zLGkuZW5kPW9bMV0/cysob1sxXSsxKSpuOm59cmV0dXJuIGl9XX07ZnVuY3Rpb24gS24oKXtyZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbigpe1huPXR9KSxYbj1iLm5vdygpfWZ1bmN0aW9uIFpuKGUsdCl7Yi5lYWNoKHQsZnVuY3Rpb24odCxuKXt2YXIgcj0oUW5bdF18fFtdKS5jb25jYXQoUW5bIioiXSksaT0wLG89ci5sZW5ndGg7Zm9yKDtvPmk7aSsrKWlmKHJbaV0uY2FsbChlLHQsbikpcmV0dXJufSl9ZnVuY3Rpb24gZXIoZSx0LG4pe3ZhciByLGksbz0wLGE9R24ubGVuZ3RoLHM9Yi5EZWZlcnJlZCgpLmFsd2F5cyhmdW5jdGlvbigpe2RlbGV0ZSB1LmVsZW19KSx1PWZ1bmN0aW9uKCl7aWYoaSlyZXR1cm4hMTt2YXIgdD1Ybnx8S24oKSxuPU1hdGgubWF4KDAsbC5zdGFydFRpbWUrbC5kdXJhdGlvbi10KSxyPW4vbC5kdXJhdGlvbnx8MCxvPTEtcixhPTAsdT1sLnR3ZWVucy5sZW5ndGg7Zm9yKDt1PmE7YSsrKWwudHdlZW5zW2FdLnJ1bihvKTtyZXR1cm4gcy5ub3RpZnlXaXRoKGUsW2wsbyxuXSksMT5vJiZ1P246KHMucmVzb2x2ZVdpdGgoZSxbbF0pLCExKX0sbD1zLnByb21pc2Uoe2VsZW06ZSxwcm9wczpiLmV4dGVuZCh7fSx0KSxvcHRzOmIuZXh0ZW5kKCEwLHtzcGVjaWFsRWFzaW5nOnt9fSxuKSxvcmlnaW5hbFByb3BlcnRpZXM6dCxvcmlnaW5hbE9wdGlvbnM6bixzdGFydFRpbWU6WG58fEtuKCksZHVyYXRpb246bi5kdXJhdGlvbix0d2VlbnM6W10sY3JlYXRlVHdlZW46ZnVuY3Rpb24odCxuKXt2YXIgcj1iLlR3ZWVuKGUsbC5vcHRzLHQsbixsLm9wdHMuc3BlY2lhbEVhc2luZ1t0XXx8bC5vcHRzLmVhc2luZyk7cmV0dXJuIGwudHdlZW5zLnB1c2gocikscn0sc3RvcDpmdW5jdGlvbih0KXt2YXIgbj0wLHI9dD9sLnR3ZWVucy5sZW5ndGg6MDtpZihpKXJldHVybiB0aGlzO2ZvcihpPSEwO3I+bjtuKyspbC50d2VlbnNbbl0ucnVuKDEpO3JldHVybiB0P3MucmVzb2x2ZVdpdGgoZSxbbCx0XSk6cy5yZWplY3RXaXRoKGUsW2wsdF0pLHRoaXN9fSksYz1sLnByb3BzO2Zvcih0cihjLGwub3B0cy5zcGVjaWFsRWFzaW5nKTthPm87bysrKWlmKHI9R25bb10uY2FsbChsLGUsYyxsLm9wdHMpKXJldHVybiByO3JldHVybiBabihsLGMpLGIuaXNGdW5jdGlvbihsLm9wdHMuc3RhcnQpJiZsLm9wdHMuc3RhcnQuY2FsbChlLGwpLGIuZngudGltZXIoYi5leHRlbmQodSx7ZWxlbTplLGFuaW06bCxxdWV1ZTpsLm9wdHMucXVldWV9KSksbC5wcm9ncmVzcyhsLm9wdHMucHJvZ3Jlc3MpLmRvbmUobC5vcHRzLmRvbmUsbC5vcHRzLmNvbXBsZXRlKS5mYWlsKGwub3B0cy5mYWlsKS5hbHdheXMobC5vcHRzLmFsd2F5cyl9ZnVuY3Rpb24gdHIoZSx0KXt2YXIgbixyLGksbyxhO2ZvcihpIGluIGUpaWYocj1iLmNhbWVsQ2FzZShpKSxvPXRbcl0sbj1lW2ldLGIuaXNBcnJheShuKSYmKG89blsxXSxuPWVbaV09blswXSksaSE9PXImJihlW3JdPW4sZGVsZXRlIGVbaV0pLGE9Yi5jc3NIb29rc1tyXSxhJiYiZXhwYW5kImluIGEpe249YS5leHBhbmQobiksZGVsZXRlIGVbcl07Zm9yKGkgaW4gbilpIGluIGV8fChlW2ldPW5baV0sdFtpXT1vKX1lbHNlIHRbcl09b31iLkFuaW1hdGlvbj1iLmV4dGVuZChlcix7dHdlZW5lcjpmdW5jdGlvbihlLHQpe2IuaXNGdW5jdGlvbihlKT8odD1lLGU9WyIqIl0pOmU9ZS5zcGxpdCgiICIpO3ZhciBuLHI9MCxpPWUubGVuZ3RoO2Zvcig7aT5yO3IrKyluPWVbcl0sUW5bbl09UW5bbl18fFtdLFFuW25dLnVuc2hpZnQodCl9LHByZWZpbHRlcjpmdW5jdGlvbihlLHQpe3Q/R24udW5zaGlmdChlKTpHbi5wdXNoKGUpfX0pO2Z1bmN0aW9uIG5yKGUsdCxuKXt2YXIgcixpLG8sYSxzLHUsbCxjLHAsZj10aGlzLGQ9ZS5zdHlsZSxoPXt9LGc9W10sbT1lLm5vZGVUeXBlJiZubihlKTtuLnF1ZXVlfHwoYz1iLl9xdWV1ZUhvb2tzKGUsImZ4IiksbnVsbD09Yy51bnF1ZXVlZCYmKGMudW5xdWV1ZWQ9MCxwPWMuZW1wdHkuZmlyZSxjLmVtcHR5LmZpcmU9ZnVuY3Rpb24oKXtjLnVucXVldWVkfHxwKCl9KSxjLnVucXVldWVkKyssZi5hbHdheXMoZnVuY3Rpb24oKXtmLmFsd2F5cyhmdW5jdGlvbigpe2MudW5xdWV1ZWQtLSxiLnF1ZXVlKGUsImZ4IikubGVuZ3RofHxjLmVtcHR5LmZpcmUoKX0pfSkpLDE9PT1lLm5vZGVUeXBlJiYoImhlaWdodCJpbiB0fHwid2lkdGgiaW4gdCkmJihuLm92ZXJmbG93PVtkLm92ZXJmbG93LGQub3ZlcmZsb3dYLGQub3ZlcmZsb3dZXSwiaW5saW5lIj09PWIuY3NzKGUsImRpc3BsYXkiKSYmIm5vbmUiPT09Yi5jc3MoZSwiZmxvYXQiKSYmKGIuc3VwcG9ydC5pbmxpbmVCbG9ja05lZWRzTGF5b3V0JiYiaW5saW5lIiE9PXVuKGUubm9kZU5hbWUpP2Quem9vbT0xOmQuZGlzcGxheT0iaW5saW5lLWJsb2NrIikpLG4ub3ZlcmZsb3cmJihkLm92ZXJmbG93PSJoaWRkZW4iLGIuc3VwcG9ydC5zaHJpbmtXcmFwQmxvY2tzfHxmLmFsd2F5cyhmdW5jdGlvbigpe2Qub3ZlcmZsb3c9bi5vdmVyZmxvd1swXSxkLm92ZXJmbG93WD1uLm92ZXJmbG93WzFdLGQub3ZlcmZsb3dZPW4ub3ZlcmZsb3dbMl19KSk7Zm9yKGkgaW4gdClpZihhPXRbaV0sVm4uZXhlYyhhKSl7aWYoZGVsZXRlIHRbaV0sdT11fHwidG9nZ2xlIj09PWEsYT09PShtPyJoaWRlIjoic2hvdyIpKWNvbnRpbnVlO2cucHVzaChpKX1pZihvPWcubGVuZ3RoKXtzPWIuX2RhdGEoZSwiZnhzaG93Iil8fGIuX2RhdGEoZSwiZnhzaG93Iix7fSksImhpZGRlbiJpbiBzJiYobT1zLmhpZGRlbiksdSYmKHMuaGlkZGVuPSFtKSxtP2IoZSkuc2hvdygpOmYuZG9uZShmdW5jdGlvbigpe2IoZSkuaGlkZSgpfSksZi5kb25lKGZ1bmN0aW9uKCl7dmFyIHQ7Yi5fcmVtb3ZlRGF0YShlLCJmeHNob3ciKTtmb3IodCBpbiBoKWIuc3R5bGUoZSx0LGhbdF0pfSk7Zm9yKGk9MDtvPmk7aSsrKXI9Z1tpXSxsPWYuY3JlYXRlVHdlZW4ocixtP3Nbcl06MCksaFtyXT1zW3JdfHxiLnN0eWxlKGUsciksciBpbiBzfHwoc1tyXT1sLnN0YXJ0LG0mJihsLmVuZD1sLnN0YXJ0LGwuc3RhcnQ9IndpZHRoIj09PXJ8fCJoZWlnaHQiPT09cj8xOjApKX19ZnVuY3Rpb24gcnIoZSx0LG4scixpKXtyZXR1cm4gbmV3IHJyLnByb3RvdHlwZS5pbml0KGUsdCxuLHIsaSl9Yi5Ud2Vlbj1ycixyci5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOnJyLGluaXQ6ZnVuY3Rpb24oZSx0LG4scixpLG8pe3RoaXMuZWxlbT1lLHRoaXMucHJvcD1uLHRoaXMuZWFzaW5nPWl8fCJzd2luZyIsdGhpcy5vcHRpb25zPXQsdGhpcy5zdGFydD10aGlzLm5vdz10aGlzLmN1cigpLHRoaXMuZW5kPXIsdGhpcy51bml0PW98fChiLmNzc051bWJlcltuXT8iIjoicHgiKX0sY3VyOmZ1bmN0aW9uKCl7dmFyIGU9cnIucHJvcEhvb2tzW3RoaXMucHJvcF07cmV0dXJuIGUmJmUuZ2V0P2UuZ2V0KHRoaXMpOnJyLnByb3BIb29rcy5fZGVmYXVsdC5nZXQodGhpcyl9LHJ1bjpmdW5jdGlvbihlKXt2YXIgdCxuPXJyLnByb3BIb29rc1t0aGlzLnByb3BdO3JldHVybiB0aGlzLnBvcz10PXRoaXMub3B0aW9ucy5kdXJhdGlvbj9iLmVhc2luZ1t0aGlzLmVhc2luZ10oZSx0aGlzLm9wdGlvbnMuZHVyYXRpb24qZSwwLDEsdGhpcy5vcHRpb25zLmR1cmF0aW9uKTplLHRoaXMubm93PSh0aGlzLmVuZC10aGlzLnN0YXJ0KSp0K3RoaXMuc3RhcnQsdGhpcy5vcHRpb25zLnN0ZXAmJnRoaXMub3B0aW9ucy5zdGVwLmNhbGwodGhpcy5lbGVtLHRoaXMubm93LHRoaXMpLG4mJm4uc2V0P24uc2V0KHRoaXMpOnJyLnByb3BIb29rcy5fZGVmYXVsdC5zZXQodGhpcyksdGhpc319LHJyLnByb3RvdHlwZS5pbml0LnByb3RvdHlwZT1yci5wcm90b3R5cGUscnIucHJvcEhvb2tzPXtfZGVmYXVsdDp7Z2V0OmZ1bmN0aW9uKGUpe3ZhciB0O3JldHVybiBudWxsPT1lLmVsZW1bZS5wcm9wXXx8ZS5lbGVtLnN0eWxlJiZudWxsIT1lLmVsZW0uc3R5bGVbZS5wcm9wXT8odD1iLmNzcyhlLmVsZW0sZS5wcm9wLCIiKSx0JiYiYXV0byIhPT10P3Q6MCk6ZS5lbGVtW2UucHJvcF19LHNldDpmdW5jdGlvbihlKXtiLmZ4LnN0ZXBbZS5wcm9wXT9iLmZ4LnN0ZXBbZS5wcm9wXShlKTplLmVsZW0uc3R5bGUmJihudWxsIT1lLmVsZW0uc3R5bGVbYi5jc3NQcm9wc1tlLnByb3BdXXx8Yi5jc3NIb29rc1tlLnByb3BdKT9iLnN0eWxlKGUuZWxlbSxlLnByb3AsZS5ub3crZS51bml0KTplLmVsZW1bZS5wcm9wXT1lLm5vd319fSxyci5wcm9wSG9va3Muc2Nyb2xsVG9wPXJyLnByb3BIb29rcy5zY3JvbGxMZWZ0PXtzZXQ6ZnVuY3Rpb24oZSl7ZS5lbGVtLm5vZGVUeXBlJiZlLmVsZW0ucGFyZW50Tm9kZSYmKGUuZWxlbVtlLnByb3BdPWUubm93KX19LGIuZWFjaChbInRvZ2dsZSIsInNob3ciLCJoaWRlIl0sZnVuY3Rpb24oZSx0KXt2YXIgbj1iLmZuW3RdO2IuZm5bdF09ZnVuY3Rpb24oZSxyLGkpe3JldHVybiBudWxsPT1lfHwiYm9vbGVhbiI9PXR5cGVvZiBlP24uYXBwbHkodGhpcyxhcmd1bWVudHMpOnRoaXMuYW5pbWF0ZShpcih0LCEwKSxlLHIsaSl9fSksYi5mbi5leHRlbmQoe2ZhZGVUbzpmdW5jdGlvbihlLHQsbixyKXtyZXR1cm4gdGhpcy5maWx0ZXIobm4pLmNzcygib3BhY2l0eSIsMCkuc2hvdygpLmVuZCgpLmFuaW1hdGUoe29wYWNpdHk6dH0sZSxuLHIpfSxhbmltYXRlOmZ1bmN0aW9uKGUsdCxuLHIpe3ZhciBpPWIuaXNFbXB0eU9iamVjdChlKSxvPWIuc3BlZWQodCxuLHIpLGE9ZnVuY3Rpb24oKXt2YXIgdD1lcih0aGlzLGIuZXh0ZW5kKHt9LGUpLG8pO2EuZmluaXNoPWZ1bmN0aW9uKCl7dC5zdG9wKCEwKX0sKGl8fGIuX2RhdGEodGhpcywiZmluaXNoIikpJiZ0LnN0b3AoITApfTtyZXR1cm4gYS5maW5pc2g9YSxpfHxvLnF1ZXVlPT09ITE/dGhpcy5lYWNoKGEpOnRoaXMucXVldWUoby5xdWV1ZSxhKX0sc3RvcDpmdW5jdGlvbihlLG4scil7dmFyIGk9ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5zdG9wO2RlbGV0ZSBlLnN0b3AsdChyKX07cmV0dXJuInN0cmluZyIhPXR5cGVvZiBlJiYocj1uLG49ZSxlPXQpLG4mJmUhPT0hMSYmdGhpcy5xdWV1ZShlfHwiZngiLFtdKSx0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgdD0hMCxuPW51bGwhPWUmJmUrInF1ZXVlSG9va3MiLG89Yi50aW1lcnMsYT1iLl9kYXRhKHRoaXMpO2lmKG4pYVtuXSYmYVtuXS5zdG9wJiZpKGFbbl0pO2Vsc2UgZm9yKG4gaW4gYSlhW25dJiZhW25dLnN0b3AmJkpuLnRlc3QobikmJmkoYVtuXSk7Zm9yKG49by5sZW5ndGg7bi0tOylvW25dLmVsZW0hPT10aGlzfHxudWxsIT1lJiZvW25dLnF1ZXVlIT09ZXx8KG9bbl0uYW5pbS5zdG9wKHIpLHQ9ITEsby5zcGxpY2UobiwxKSk7KHR8fCFyKSYmYi5kZXF1ZXVlKHRoaXMsZSl9KX0sZmluaXNoOmZ1bmN0aW9uKGUpe3JldHVybiBlIT09ITEmJihlPWV8fCJmeCIpLHRoaXMuZWFjaChmdW5jdGlvbigpe3ZhciB0LG49Yi5fZGF0YSh0aGlzKSxyPW5bZSsicXVldWUiXSxpPW5bZSsicXVldWVIb29rcyJdLG89Yi50aW1lcnMsYT1yP3IubGVuZ3RoOjA7Zm9yKG4uZmluaXNoPSEwLGIucXVldWUodGhpcyxlLFtdKSxpJiZpLmN1ciYmaS5jdXIuZmluaXNoJiZpLmN1ci5maW5pc2guY2FsbCh0aGlzKSx0PW8ubGVuZ3RoO3QtLTspb1t0XS5lbGVtPT09dGhpcyYmb1t0XS5xdWV1ZT09PWUmJihvW3RdLmFuaW0uc3RvcCghMCksby5zcGxpY2UodCwxKSk7Zm9yKHQ9MDthPnQ7dCsrKXJbdF0mJnJbdF0uZmluaXNoJiZyW3RdLmZpbmlzaC5jYWxsKHRoaXMpO2RlbGV0ZSBuLmZpbmlzaH0pfX0pO2Z1bmN0aW9uIGlyKGUsdCl7dmFyIG4scj17aGVpZ2h0OmV9LGk9MDtmb3IodD10PzE6MDs0Pmk7aSs9Mi10KW49WnRbaV0sclsibWFyZ2luIituXT1yWyJwYWRkaW5nIituXT1lO3JldHVybiB0JiYoci5vcGFjaXR5PXIud2lkdGg9ZSkscn1iLmVhY2goe3NsaWRlRG93bjppcigic2hvdyIpLHNsaWRlVXA6aXIoImhpZGUiKSxzbGlkZVRvZ2dsZTppcigidG9nZ2xlIiksZmFkZUluOntvcGFjaXR5OiJzaG93In0sZmFkZU91dDp7b3BhY2l0eToiaGlkZSJ9LGZhZGVUb2dnbGU6e29wYWNpdHk6InRvZ2dsZSJ9fSxmdW5jdGlvbihlLHQpe2IuZm5bZV09ZnVuY3Rpb24oZSxuLHIpe3JldHVybiB0aGlzLmFuaW1hdGUodCxlLG4scil9fSksYi5zcGVlZD1mdW5jdGlvbihlLHQsbil7dmFyIHI9ZSYmIm9iamVjdCI9PXR5cGVvZiBlP2IuZXh0ZW5kKHt9LGUpOntjb21wbGV0ZTpufHwhbiYmdHx8Yi5pc0Z1bmN0aW9uKGUpJiZlLGR1cmF0aW9uOmUsZWFzaW5nOm4mJnR8fHQmJiFiLmlzRnVuY3Rpb24odCkmJnR9O3JldHVybiByLmR1cmF0aW9uPWIuZngub2ZmPzA6Im51bWJlciI9PXR5cGVvZiByLmR1cmF0aW9uP3IuZHVyYXRpb246ci5kdXJhdGlvbiBpbiBiLmZ4LnNwZWVkcz9iLmZ4LnNwZWVkc1tyLmR1cmF0aW9uXTpiLmZ4LnNwZWVkcy5fZGVmYXVsdCwobnVsbD09ci5xdWV1ZXx8ci5xdWV1ZT09PSEwKSYmKHIucXVldWU9ImZ4Iiksci5vbGQ9ci5jb21wbGV0ZSxyLmNvbXBsZXRlPWZ1bmN0aW9uKCl7Yi5pc0Z1bmN0aW9uKHIub2xkKSYmci5vbGQuY2FsbCh0aGlzKSxyLnF1ZXVlJiZiLmRlcXVldWUodGhpcyxyLnF1ZXVlKX0scn0sYi5lYXNpbmc9e2xpbmVhcjpmdW5jdGlvbihlKXtyZXR1cm4gZX0sc3dpbmc6ZnVuY3Rpb24oZSl7cmV0dXJuLjUtTWF0aC5jb3MoZSpNYXRoLlBJKS8yfX0sYi50aW1lcnM9W10sYi5meD1yci5wcm90b3R5cGUuaW5pdCxiLmZ4LnRpY2s9ZnVuY3Rpb24oKXt2YXIgZSxuPWIudGltZXJzLHI9MDtmb3IoWG49Yi5ub3coKTtuLmxlbmd0aD5yO3IrKyllPW5bcl0sZSgpfHxuW3JdIT09ZXx8bi5zcGxpY2Uoci0tLDEpO24ubGVuZ3RofHxiLmZ4LnN0b3AoKSxYbj10fSxiLmZ4LnRpbWVyPWZ1bmN0aW9uKGUpe2UoKSYmYi50aW1lcnMucHVzaChlKSYmYi5meC5zdGFydCgpfSxiLmZ4LmludGVydmFsPTEzLGIuZnguc3RhcnQ9ZnVuY3Rpb24oKXtVbnx8KFVuPXNldEludGVydmFsKGIuZngudGljayxiLmZ4LmludGVydmFsKSl9LGIuZnguc3RvcD1mdW5jdGlvbigpe2NsZWFySW50ZXJ2YWwoVW4pLFVuPW51bGx9LGIuZnguc3BlZWRzPXtzbG93OjYwMCxmYXN0OjIwMCxfZGVmYXVsdDo0MDB9LGIuZnguc3RlcD17fSxiLmV4cHImJmIuZXhwci5maWx0ZXJzJiYoYi5leHByLmZpbHRlcnMuYW5pbWF0ZWQ9ZnVuY3Rpb24oZSl7cmV0dXJuIGIuZ3JlcChiLnRpbWVycyxmdW5jdGlvbih0KXtyZXR1cm4gZT09PXQuZWxlbX0pLmxlbmd0aH0pLGIuZm4ub2Zmc2V0PWZ1bmN0aW9uKGUpe2lmKGFyZ3VtZW50cy5sZW5ndGgpcmV0dXJuIGU9PT10P3RoaXM6dGhpcy5lYWNoKGZ1bmN0aW9uKHQpe2Iub2Zmc2V0LnNldE9mZnNldCh0aGlzLGUsdCl9KTt2YXIgbixyLG89e3RvcDowLGxlZnQ6MH0sYT10aGlzWzBdLHM9YSYmYS5vd25lckRvY3VtZW50O2lmKHMpcmV0dXJuIG49cy5kb2N1bWVudEVsZW1lbnQsYi5jb250YWlucyhuLGEpPyh0eXBlb2YgYS5nZXRCb3VuZGluZ0NsaWVudFJlY3QhPT1pJiYobz1hLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKSxyPW9yKHMpLHt0b3A6by50b3ArKHIucGFnZVlPZmZzZXR8fG4uc2Nyb2xsVG9wKS0obi5jbGllbnRUb3B8fDApLGxlZnQ6by5sZWZ0KyhyLnBhZ2VYT2Zmc2V0fHxuLnNjcm9sbExlZnQpLShuLmNsaWVudExlZnR8fDApfSk6b30sYi5vZmZzZXQ9e3NldE9mZnNldDpmdW5jdGlvbihlLHQsbil7dmFyIHI9Yi5jc3MoZSwicG9zaXRpb24iKTsic3RhdGljIj09PXImJihlLnN0eWxlLnBvc2l0aW9uPSJyZWxhdGl2ZSIpO3ZhciBpPWIoZSksbz1pLm9mZnNldCgpLGE9Yi5jc3MoZSwidG9wIikscz1iLmNzcyhlLCJsZWZ0IiksdT0oImFic29sdXRlIj09PXJ8fCJmaXhlZCI9PT1yKSYmYi5pbkFycmF5KCJhdXRvIixbYSxzXSk+LTEsbD17fSxjPXt9LHAsZjt1PyhjPWkucG9zaXRpb24oKSxwPWMudG9wLGY9Yy5sZWZ0KToocD1wYXJzZUZsb2F0KGEpfHwwLGY9cGFyc2VGbG9hdChzKXx8MCksYi5pc0Z1bmN0aW9uKHQpJiYodD10LmNhbGwoZSxuLG8pKSxudWxsIT10LnRvcCYmKGwudG9wPXQudG9wLW8udG9wK3ApLG51bGwhPXQubGVmdCYmKGwubGVmdD10LmxlZnQtby5sZWZ0K2YpLCJ1c2luZyJpbiB0P3QudXNpbmcuY2FsbChlLGwpOmkuY3NzKGwpfX0sYi5mbi5leHRlbmQoe3Bvc2l0aW9uOmZ1bmN0aW9uKCl7aWYodGhpc1swXSl7dmFyIGUsdCxuPXt0b3A6MCxsZWZ0OjB9LHI9dGhpc1swXTtyZXR1cm4iZml4ZWQiPT09Yi5jc3MociwicG9zaXRpb24iKT90PXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk6KGU9dGhpcy5vZmZzZXRQYXJlbnQoKSx0PXRoaXMub2Zmc2V0KCksYi5ub2RlTmFtZShlWzBdLCJodG1sIil8fChuPWUub2Zmc2V0KCkpLG4udG9wKz1iLmNzcyhlWzBdLCJib3JkZXJUb3BXaWR0aCIsITApLG4ubGVmdCs9Yi5jc3MoZVswXSwiYm9yZGVyTGVmdFdpZHRoIiwhMCkpLHt0b3A6dC50b3Atbi50b3AtYi5jc3MociwibWFyZ2luVG9wIiwhMCksbGVmdDp0LmxlZnQtbi5sZWZ0LWIuY3NzKHIsIm1hcmdpbkxlZnQiLCEwKX19fSxvZmZzZXRQYXJlbnQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKXt2YXIgZT10aGlzLm9mZnNldFBhcmVudHx8by5kb2N1bWVudEVsZW1lbnQ7d2hpbGUoZSYmIWIubm9kZU5hbWUoZSwiaHRtbCIpJiYic3RhdGljIj09PWIuY3NzKGUsInBvc2l0aW9uIikpZT1lLm9mZnNldFBhcmVudDtyZXR1cm4gZXx8by5kb2N1bWVudEVsZW1lbnR9KX19KSxiLmVhY2goe3Njcm9sbExlZnQ6InBhZ2VYT2Zmc2V0IixzY3JvbGxUb3A6InBhZ2VZT2Zmc2V0In0sZnVuY3Rpb24oZSxuKXt2YXIgcj0vWS8udGVzdChuKTtiLmZuW2VdPWZ1bmN0aW9uKGkpe3JldHVybiBiLmFjY2Vzcyh0aGlzLGZ1bmN0aW9uKGUsaSxvKXt2YXIgYT1vcihlKTtyZXR1cm4gbz09PXQ/YT9uIGluIGE/YVtuXTphLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudFtpXTplW2ldOihhP2Euc2Nyb2xsVG8ocj9iKGEpLnNjcm9sbExlZnQoKTpvLHI/bzpiKGEpLnNjcm9sbFRvcCgpKTplW2ldPW8sdCl9LGUsaSxhcmd1bWVudHMubGVuZ3RoLG51bGwpfX0pO2Z1bmN0aW9uIG9yKGUpe3JldHVybiBiLmlzV2luZG93KGUpP2U6OT09PWUubm9kZVR5cGU/ZS5kZWZhdWx0Vmlld3x8ZS5wYXJlbnRXaW5kb3c6ITF9Yi5lYWNoKHtIZWlnaHQ6ImhlaWdodCIsV2lkdGg6IndpZHRoIn0sZnVuY3Rpb24oZSxuKXtiLmVhY2goe3BhZGRpbmc6ImlubmVyIitlLGNvbnRlbnQ6biwiIjoib3V0ZXIiK2V9LGZ1bmN0aW9uKHIsaSl7Yi5mbltpXT1mdW5jdGlvbihpLG8pe3ZhciBhPWFyZ3VtZW50cy5sZW5ndGgmJihyfHwiYm9vbGVhbiIhPXR5cGVvZiBpKSxzPXJ8fChpPT09ITB8fG89PT0hMD8ibWFyZ2luIjoiYm9yZGVyIik7cmV0dXJuIGIuYWNjZXNzKHRoaXMsZnVuY3Rpb24obixyLGkpe3ZhciBvO3JldHVybiBiLmlzV2luZG93KG4pP24uZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50WyJjbGllbnQiK2VdOjk9PT1uLm5vZGVUeXBlPyhvPW4uZG9jdW1lbnRFbGVtZW50LE1hdGgubWF4KG4uYm9keVsic2Nyb2xsIitlXSxvWyJzY3JvbGwiK2VdLG4uYm9keVsib2Zmc2V0IitlXSxvWyJvZmZzZXQiK2VdLG9bImNsaWVudCIrZV0pKTppPT09dD9iLmNzcyhuLHIscyk6Yi5zdHlsZShuLHIsaSxzKX0sbixhP2k6dCxhLG51bGwpfX0pfSksZS5qUXVlcnk9ZS4kPWIsImZ1bmN0aW9uIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZCYmZGVmaW5lLmFtZC5qUXVlcnkmJmRlZmluZSgianF1ZXJ5IixbXSxmdW5jdGlvbigpe3JldHVybiBifSl9KSh3aW5kb3cpOw=="},{"meta":{"name":"MonkeyConfig%20Modern%20Reloaded.js","url":"https://greasyfork.org/scripts/439099-monkeyconfig-modern-reloaded/code/MonkeyConfig%20Modern%20Reloaded.js?version=1012538","ts":1706935757626,"mimetype":"text/javascript"},"source":"Ly8gPT1Vc2VyU2NyaXB0PT0KLy8gQG5hbWUgICAgICAgICAgIE1vbmtleUNvbmZpZyBNb2Rlcm4gUmVsb2FkZWQKLy8gQG5hbWVzcGFjZSAgICAgIGh0dHA6Ly9vZHluaWVjLm5ldC8KLy8gQGRlc2NyaXB0aW9uICAgIEVhc3kgY29uZmlndXJhdGlvbiBkaWFsb2cgYnVpbGRlciBmb3IgdXNlciBzY3JpcHRzCi8vIEBpbmNsdWRlICAgICAgICAqCi8vID09L1VzZXJTY3JpcHQ9PQoKLyoKICogTW9ua2V5Q29uZmlnCiAqIHZlcnNpb24gMC4xLjQKICogCiAqIENvcHlyaWdodCAoYykgMjAxMS0yMDEzIE1pY2hhbCBXb2pjaWVjaG93c2tpIChvZHluaWVjLm5ldCkKICogdjAuMS40IC0gSmFudWFyeSAyMDIwIC0gRGF2aWQgSG9zaWVyIChodHRwczovL2dpdGh1Yi5jb20vZGF2aWQtaG9zaWVyL01vbmtleUNvbmZpZykKICovCgpmdW5jdGlvbiBNb25rZXlDb25maWcoKSB7CiAgICB2YXIgY2ZnID0gdGhpcywKICAgICAgICAvKiBEYXRhIG9iamVjdCBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yICovCiAgICAgICAgZGF0YSwKICAgICAgICAvKiBDb25maWd1cmF0aW9uIHBhcmFtZXRlcnMgKGRhdGEucGFyYW1ldGVycyBvciBkYXRhLnBhcmFtcykgKi8KICAgICAgICBwYXJhbXMsCiAgICAgICAgLyogQ3VycmVudCB2YWx1ZXMgb2YgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXJzICovCiAgICAgICAgdmFsdWVzID0ge30sCiAgICAgICAgLyogSWRlbnRpZmllciB1c2VkIHRvIHN0b3JlL3JldHJpZXZlIGNvbmZpZ3VyYXRpb24gKi8KICAgICAgICBzdG9yYWdlS2V5LAogICAgICAgIC8qIElzIHRoZSBjb25maWd1cmF0aW9uIGRpYWxvZyBkaXNwbGF5ZWQ/ICovCiAgICAgICAgZGlzcGxheWVkLAogICAgICAgIC8qIEN1cnJlbnRseSBkaXNwbGF5ZWQgd2luZG93L2xheWVyICovCiAgICAgICAgb3Blbldpbiwgb3BlbkxheWVyLAogICAgICAgIC8qIERPTSBlbGVtZW50IHdyYXBwaW5nIHRoZSBjb25maWd1cmF0aW9uIGZvcm0gKi8KICAgICAgICBjb250YWluZXIsCiAgICAgICAgLyogRGFya2VuZWQgb3ZlcmxheSB1c2VkIGluIHRoZSBsYXllciBkaXNwbGF5IG1vZGUgKi8KICAgICAgICBvdmVybGF5OwogICAgCiAgICAvKioKICAgICAqIEluaXRpYWxpemUgY29uZmlndXJhdGlvbiAKICAgICAqIAogICAgICogQHBhcmFtIG5ld0RhdGEgTmV3IGRhdGEgb2JqZWN0CiAgICAgKi8KICAgIGZ1bmN0aW9uIGluaXQobmV3RGF0YSkgewogICAgICAgIGRhdGEgPSBuZXdEYXRhOwoKICAgICAgICBpZiAoZGF0YSkgewogICAgICAgICAgICBwYXJhbXMgPSBkYXRhLnBhcmFtZXRlcnMgfHwgZGF0YS5wYXJhbXM7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoZGF0YS5idXR0b25zID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICAvKiBTZXQgZGVmYXVsdCBidXR0b25zICovCiAgICAgICAgICAgICAgICBkYXRhLmJ1dHRvbnMgPSBbICdzYXZlJywgJ2RlZmF1bHRzJywgJ2NhbmNlbCcgXTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChkYXRhLnRpdGxlID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogSWYgR01fZ2V0TWV0YWRhdGEgaXMgYXZhaWxhYmxlLCBnZXQgdGhlIG5hbWUgb2YgdGhlIHNjcmlwdAogICAgICAgICAgICAgICAgICogYW5kIHVzZSBpdCBpbiB0aGUgZGlhbG9nIHRpdGxlCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgR01fZ2V0TWV0YWRhdGEgPT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICAgICAgICAgIHZhciBzY3JpcHROYW1lID0gR01fZ2V0TWV0YWRhdGEoJ25hbWUnKTsKICAgICAgICAgICAgICAgICAgICBkYXRhLnRpdGxlID0gc2NyaXB0TmFtZSArICcgQ29uZmlndXJhdGlvbic7IAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGRhdGEudGl0bGUgPSAnQ29uZmlndXJhdGlvbic7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8qIE1ha2UgYSBzYWZlIHZlcnNpb24gb2YgdGl0bGUgdG8gYmUgdXNlZCBhcyBzdG9yZWQgdmFsdWUgaWRlbnRpZmllciAqLyAKICAgICAgICB2YXIgc2FmZVRpdGxlID0gZGF0YSAmJiBkYXRhLnRpdGxlID8KICAgICAgICAgICAgICAgIGRhdGEudGl0bGUucmVwbGFjZSgvW15hLXpBLVowLTldL2csICdfJykgOiAnJzsKCiAgICAgICAgc3RvcmFnZUtleSA9ICdfTW9ua2V5Q29uZmlnXycgKyBzYWZlVGl0bGUgKyAnX2NmZyc7CiAgICAgICAgCiAgICAgICAgdmFyIHN0b3JlZFZhbHVlczsKICAgICAgICAKICAgICAgICAvKiBMb2FkIHN0b3JlZCB2YWx1ZXMgKGlmIHByZXNlbnQpICovCiAgICAgICAgaWYgKEdNX2dldFZhbHVlKHN0b3JhZ2VLZXkpKQogICAgICAgICAgICBzdG9yZWRWYWx1ZXMgPSBKU09OLnBhcnNlKEdNX2dldFZhbHVlKHN0b3JhZ2VLZXkpKTsKCiAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBwYXJhbXMpIHsKICAgICAgICAgICAgLyogSWYgdGhlcmUncyBhIHZhbHVlIGRlZmluZWQgaW4gdGhlIHBhc3NlZCBkYXRhIG9iamVjdCwgdXNlIGl0ICovCiAgICAgICAgICAgIGlmIChwYXJhbXNbbmFtZV1bJ3ZhbHVlJ10gIT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgIHNldChuYW1lLCBwYXJhbXNbbmFtZV0udmFsdWUpOwogICAgICAgICAgICAvKiBDaGVjayBpZiB0aGVyZSdzIGEgc3RvcmVkIHZhbHVlIGZvciB0aGlzIHBhcmFtZXRlciAqLwogICAgICAgICAgICBlbHNlIGlmIChzdG9yZWRWYWx1ZXMgJiYgc3RvcmVkVmFsdWVzW25hbWVdICE9PSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICBzZXQobmFtZSwgc3RvcmVkVmFsdWVzW25hbWVdKTsgICAgICAgICAgICAKICAgICAgICAgICAgLyogT3RoZXJ3aXNlLCBzZXQgdGhlIGRlZmF1bHQgdmFsdWUgKGlmIGRlZmluZWQpICovCiAgICAgICAgICAgIGVsc2UgaWYgKHBhcmFtc1tuYW1lXVsnZGVmYXVsdCddICE9PSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICBzZXQobmFtZSwgcGFyYW1zW25hbWVdWydkZWZhdWx0J10pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBzZXQobmFtZSwgJycpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGRhdGEubWVudUNvbW1hbmQpIHsKICAgICAgICAgICAgLyogQWRkIGFuIGl0ZW0gdG8gdGhlIFVzZXIgU2NyaXB0IENvbW1hbmRzIG1lbnUgKi8KICAgICAgICAgICAgdmFyIGNhcHRpb24gPSBkYXRhLm1lbnVDb21tYW5kICE9PSB0cnVlID8gZGF0YS5tZW51Q29tbWFuZCA6CiAgICAgICAgICAgICAgICBkYXRhLnRpdGxlOwogICAgICAgICAgICAKICAgICAgICAgICAgR01fcmVnaXN0ZXJNZW51Q29tbWFuZChjYXB0aW9uLCBmdW5jdGlvbiAoKSB7IGNmZy5vcGVuKCk7IH0pOwogICAgICAgIH0KCiAgICAgICAgLyogRXhwb3NlIHB1YmxpYyBtZXRob2RzICovCiAgICAgICAgY2ZnLm9wZW4gPSBvcGVuOwogICAgICAgIGNmZy5jbG9zZSA9IGNsb3NlOwogICAgICAgIGNmZy5nZXQgPSBnZXQ7CiAgICAgICAgY2ZnLnNldCA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkgewogICAgICAgICAgICBzZXQobmFtZSwgdmFsdWUpOwogICAgICAgICAgICB1cGRhdGUoKTsKICAgICAgICB9OwogICAgfQogICAgCiAgICAvKioKICAgICAqIEdldCB0aGUgdmFsdWUgb2YgYSBjb25maWd1cmF0aW9uIHBhcmFtZXRlcgogICAgICogCiAgICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIHRoZSBjb25maWd1cmF0aW9uIHBhcmFtZXRlcgogICAgICogQHJldHVybnMgVmFsdWUgb2YgdGhlIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyCiAgICAgKi8KICAgIGZ1bmN0aW9uIGdldChuYW1lKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlc1tuYW1lXTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIKICAgICAqIAogICAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiB0aGUgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIKICAgICAqIEBwYXJhbSB2YWx1ZSBOZXcgdmFsdWUgb2YgdGhlIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNldChuYW1lLCB2YWx1ZSkgewogICAgICAgIHZhbHVlc1tuYW1lXSA9IHZhbHVlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJlc2V0IGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVycyB0byBkZWZhdWx0IHZhbHVlcwogICAgICovIAogICAgZnVuY3Rpb24gc2V0RGVmYXVsdHMoKSB7CiAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBwYXJhbXMpIHsKICAgICAgICAgICAgaWYgKHR5cGVvZiBwYXJhbXNbbmFtZV1bJ2RlZmF1bHQnXSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAgICAgICAgIHNldChuYW1lLCBwYXJhbXNbbmFtZV1bJ2RlZmF1bHQnXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmVuZGVyIHRoZSBjb25maWd1cmF0aW9uIGRpYWxvZwogICAgICovCiAgICBmdW5jdGlvbiByZW5kZXIoKSB7CiAgICAgICAgdmFyIGh0bWwgPSAnPGRpdiBjbGFzcz0iX19Nb25rZXlDb25maWdfY29udGFpbmVyIj4nICsKICAgICAgICAgICAgJzxoMT4nICsgZGF0YS50aXRsZSArICc8L2gxPicgKwogICAgICAgICAgICAnPHRhYmxlPic7CgogICAgICAgIGZvciAodmFyIG5hbWUgaW4gcGFyYW1zKSB7CiAgICAgICAgICAgIGh0bWwgKz0gTW9ua2V5Q29uZmlnLmZvcm1hdHRlcnNbJ3RyJ10obmFtZSwgcGFyYW1zW25hbWVdKTt9CgogICAgICAgIGh0bWwgKz0gJzx0cj48dGQgY29sc3Bhbj0iMiIgY2xhc3M9Il9fTW9ua2V5Q29uZmlnX2J1dHRvbnMiPicgKwogICAgICAgICAgICAgICAgJzx0YWJsZT48dHI+JzsKCiAgICAgICAgLyogUmVuZGVyIGJ1dHRvbnMgKi8KICAgICAgICBmb3IgKHZhciBidXR0b24gaW4gZGF0YS5idXR0b25zKSB7CiAgICAgICAgICAgIGh0bWwgKz0gJzx0ZD4nOwogICAgICAgICAgICAKICAgICAgICAgICAgc3dpdGNoIChkYXRhLmJ1dHRvbnNbYnV0dG9uXSkgewogICAgICAgICAgICBjYXNlICdjYW5jZWwnOgogICAgICAgICAgICAgICAgaHRtbCArPSAnPGJ1dHRvbiB0eXBlPSJidXR0b24iICcgKwogICAgICAgICAgICAgICAgICAgICdpZD0iX19Nb25rZXlDb25maWdfYnV0dG9uX2NhbmNlbCI+JyArCiAgICAgICAgICAgICAgICAgICAgJzxpbWcgc3JjPSJkYXRhOmltYWdlL3BuZztiYXNlNjQsJyArCiAgICAgICAgICAgICAgICAgICAgICAgIE1vbmtleUNvbmZpZy5yZXMuaWNvbnMuY2FuY2VsICsgJyIgLz4mbmJzcDsnICsKICAgICAgICAgICAgICAgICAgICAnQ2FuY2VsPC9idXR0b24+JzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdkZWZhdWx0cyc6CiAgICAgICAgICAgICAgICBodG1sICs9ICc8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgJyArCiAgICAgICAgICAgICAgICAgICAgJ2lkPSJfX01vbmtleUNvbmZpZ19idXR0b25fZGVmYXVsdHMiPicgKwogICAgICAgICAgICAgICAgICAgICc8aW1nIHNyYz0iZGF0YTppbWFnZS9wbmc7YmFzZTY0LCcgKwogICAgICAgICAgICAgICAgICAgICAgICBNb25rZXlDb25maWcucmVzLmljb25zLmFycm93X3VuZG8gKyAnIiAvPiZuYnNwOycgKwogICAgICAgICAgICAgICAgICAgICdTZXQmbmJzcDtEZWZhdWx0czwvYnV0dG9uPic7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnc2F2ZSc6CiAgICAgICAgICAgICAgICBodG1sICs9ICc8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgJyArCiAgICAgICAgICAgICAgICAgICAgJ2lkPSJfX01vbmtleUNvbmZpZ19idXR0b25fc2F2ZSI+JyArCiAgICAgICAgICAgICAgICAgICAgJzxpbWcgc3JjPSJkYXRhOmltYWdlL3BuZztiYXNlNjQsJyArCiAgICAgICAgICAgICAgICAgICAgICAgIE1vbmtleUNvbmZpZy5yZXMuaWNvbnMudGljayArICciIC8+Jm5ic3A7JyArCiAgICAgICAgICAgICAgICAgICAgJ1NhdmU8L2J1dHRvbj4nOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGh0bWwgKz0gJzwvdGQ+JzsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaHRtbCArPSAnPC90cj48L3RhYmxlPjwvdGQ+PC90cj4nOwogICAgICAgIAogICAgICAgIGh0bWwgKz0gIjwvdGFibGU+PGRpdj4iOwoKICAgICAgICByZXR1cm4gaHRtbDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBVcGRhdGUgdGhlIGZpZWxkcyBpbiB0aGUgZGlhbG9nIHRvIHJlZmxlY3QgY3VycmVudCB2YWx1ZXMgCiAgICAgKi8KICAgIGZ1bmN0aW9uIHVwZGF0ZSgpIHsKICAgICAgICAvKiBEbyBub3RoaW5nIGlmIHRoZSBkaWFsb2cgaXMgbm90IGN1cnJlbnRseSBkaXNwbGF5ZWQgKi8KICAgICAgICBpZiAoIWRpc3BsYXllZCkKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIAogICAgICAgIGZvciAodmFyIG5hbWUgaW4gcGFyYW1zKSB7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHZhbHVlc1tuYW1lXTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHN3aXRjaCAocGFyYW1zW25hbWVdLnR5cGUpIHsKICAgICAgICAgICAgY2FzZSAnY2hlY2tib3gnOgogICAgICAgICAgICAgICAgdmFyIGVsZW0gPSBjb250YWluZXIucXVlcnlTZWxlY3RvcignW25hbWU9IicgKyBuYW1lICsgJyJdJyk7CiAgICAgICAgICAgICAgICBlbGVtLmNoZWNrZWQgPSAhIXZhbHVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ2N1c3RvbSc6CiAgICAgICAgICAgICAgICBwYXJhbXNbbmFtZV0uc2V0KHZhbHVlLCBjb250YWluZXIKICAgICAgICAgICAgICAgICAgICAgICAgLnF1ZXJ5U2VsZWN0b3IoJyNfX01vbmtleUNvbmZpZ19wYXJlbnRfJyArIG5hbWUpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdudW1iZXInOgogICAgICAgICAgICBjYXNlICd0ZXh0JzoKICAgICAgICAgICAgY2FzZSAnY29sb3InOgogICAgICAgICAgICAgICAgdmFyIGVsZW0gPSBjb250YWluZXIucXVlcnlTZWxlY3RvcignW25hbWU9IicgKyBuYW1lICsgJyJdJyk7CiAgICAgICAgICAgICAgICBlbGVtLnZhbHVlID0gdmFsdWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnc2VsZWN0JzoKICAgICAgICAgICAgICAgIHZhciBlbGVtID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ1tuYW1lPSInICsgbmFtZSArICciXScpOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoZWxlbS50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT0gJ2lucHV0JykgewogICAgICAgICAgICAgICAgICAgIGlmIChlbGVtLnR5cGUgJiYgZWxlbS50eXBlID09ICdyYWRpbycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogU2luZ2xlIHNlbGVjdGlvbiB3aXRoIHJhZGlvIGJ1dHRvbnMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgZWxlbSA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1tuYW1lPSInICsgbmFtZSArICciXVt2YWx1ZT0iJyArIHZhbHVlICsgJyJdJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0uY2hlY2tlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsZW0udHlwZSAmJiBlbGVtLnR5cGUgPT0gJ2NoZWNrYm94JykgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBNdWx0aXBsZSBzZWxlY3Rpb24gd2l0aCBjaGVja2JveGVzICovCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGVja2JveGVzID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaW5wdXRbbmFtZT0iJyArIG5hbWUgKyAnIl0nKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hlY2tib3hlcy5sZW5ndGg7IGkrKykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrYm94ZXNbaV0uY2hlY2tlZCA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZS5pbmRleE9mKGNoZWNrYm94ZXNbaV0udmFsdWUpID4gLTEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsZW0udGFnTmFtZS50b0xvd2VyQ2FzZSgpID09ICdzZWxlY3QnKQogICAgICAgICAgICAgICAgICAgIGlmIChlbGVtLm11bHRpcGxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIE11bHRpcGxlIHNlbGVjdGlvbiBlbGVtZW50ICovCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcHRpb25zID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0W25hbWU9IicgKyBuYW1lICsgJyJdIG9wdGlvbicpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3B0aW9ucy5sZW5ndGg7IGkrKykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnNbaV0uc2VsZWN0ZWQgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZS5pbmRleE9mKG9wdGlvbnNbaV0udmFsdWUpID4gLTEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFNpbmdsZSBzZWxlY3Rpb24gZWxlbWVudCAqLwogICAgICAgICAgICAgICAgICAgICAgICBlbGVtLnZhbHVlID0gdmFsdWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTYXZlIGJ1dHRvbiBjbGljayBldmVudCBoYW5kbGVyCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNhdmVDbGljaygpIHsKICAgICAgICBmb3IgKHZhciBuYW1lIGluIHBhcmFtcykgewogICAgICAgICAgICBzd2l0Y2ggKHBhcmFtc1tuYW1lXS50eXBlKSB7CiAgICAgICAgICAgIGNhc2UgJ2NoZWNrYm94JzoKICAgICAgICAgICAgICAgIHZhciBlbGVtID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ1tuYW1lPSInICsgbmFtZSArICciXScpOwogICAgICAgICAgICAgICAgdmFsdWVzW25hbWVdID0gZWxlbS5jaGVja2VkOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ2N1c3RvbSc6CiAgICAgICAgICAgICAgICB2YWx1ZXNbbmFtZV0gPSBwYXJhbXNbbmFtZV0uZ2V0KGNvbnRhaW5lcgogICAgICAgICAgICAgICAgICAgICAgICAucXVlcnlTZWxlY3RvcignI19fTW9ua2V5Q29uZmlnX3BhcmVudF8nICsgbmFtZSkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ251bWJlcic6CiAgICAgICAgICAgIGNhc2UgJ3RleHQnOgogICAgICAgICAgICBjYXNlICdjb2xvcic6CiAgICAgICAgICAgICAgICB2YXIgZWxlbSA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdbbmFtZT0iJyArIG5hbWUgKyAnIl0nKTsKICAgICAgICAgICAgICAgIHZhbHVlc1tuYW1lXSA9IGVsZW0udmFsdWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnc2VsZWN0JzoKICAgICAgICAgICAgICAgIHZhciBlbGVtID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ1tuYW1lPSInICsgbmFtZSArICciXScpOwoKICAgICAgICAgICAgICAgIGlmIChlbGVtLnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PSAnaW5wdXQnKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0udHlwZSAmJiBlbGVtLnR5cGUgPT0gJ3JhZGlvJykKICAgICAgICAgICAgICAgICAgICAgICAgLyogU2luZ2xlIHNlbGVjdGlvbiB3aXRoIHJhZGlvIGJ1dHRvbnMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzW25hbWVdID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnW25hbWU9IicgKyBuYW1lICsgJyJdOmNoZWNrZWQnKS52YWx1ZTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlbGVtLnR5cGUgJiYgZWxlbS50eXBlID09ICdjaGVja2JveCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogTXVsdGlwbGUgc2VsZWN0aW9uIHdpdGggY2hlY2tib3hlcyAqLwogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbbmFtZV0gPSBbXTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlucHV0cyA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2lucHV0W25hbWU9IicgKyBuYW1lICsgJyJdJyk7CgogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dHNbaV0uY2hlY2tlZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbbmFtZV0ucHVzaChpbnB1dHNbaV0udmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsZW0udGFnTmFtZS50b0xvd2VyQ2FzZSgpID09ICdzZWxlY3QnICYmIGVsZW0ubXVsdGlwbGUpIHsKICAgICAgICAgICAgICAgICAgICAvKiBNdWx0aXBsZSBzZWxlY3Rpb24gZWxlbWVudCAqLwogICAgICAgICAgICAgICAgICAgIHZhbHVlc1tuYW1lXSA9IFtdOwogICAgICAgICAgICAgICAgICAgIHZhciBvcHRpb25zID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoCiAgICAgICAgICAgICAgICAgICAgICAgICdzZWxlY3RbbmFtZT0iJyArIG5hbWUgKyAnIl0gb3B0aW9uJyk7CgogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3B0aW9ucy5sZW5ndGg7IGkrKykKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnNbaV0uc2VsZWN0ZWQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbbmFtZV0ucHVzaChvcHRpb25zW2ldLnZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbbmFtZV0gPSBlbGVtLnZhbHVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgR01fc2V0VmFsdWUoc3RvcmFnZUtleSwgSlNPTi5zdHJpbmdpZnkodmFsdWVzKSk7CiAgICAgICAgCiAgICAgICAgY2xvc2UoKTsKICAgICAgICAKICAgICAgICBpZiAoZGF0YS5vblNhdmUpCiAgICAgICAgICAgIGRhdGEub25TYXZlKHZhbHVlcyk7CiAgICAgICAgICAgIAogICAgICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDYW5jZWwgYnV0dG9uIGNsaWNrIGV2ZW50IGhhbmRsZXIgCiAgICAgKi8KICAgIGZ1bmN0aW9uIGNhbmNlbENsaWNrKCkgewogICAgICAgIGNsb3NlKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0IERlZmF1bHRzIGJ1dHRvbiBjbGljayBldmVudCBoYW5kbGVyCiAgICAgKi8KICAgIGZ1bmN0aW9uIGRlZmF1bHRzQ2xpY2soKSB7CiAgICAgICAgc2V0RGVmYXVsdHMoKTsKICAgICAgICB1cGRhdGUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIE9wZW4gY29uZmlndXJhdGlvbiBkaWFsb2cKICAgICAqIAogICAgICogQHBhcmFtIG1vZGUKICAgICAqICAgICAgICAgICAgRGlzcGxheSBtb2RlICgiaWZyYW1lIiwgImxheWVyIiwgb3IgIndpbmRvdyIsIGRlZmF1bHRzIHRvCiAgICAgKiAgICAgICAgICAgICJpZnJhbWUiKQogICAgICogQHBhcmFtIG9wdGlvbnMKICAgICAqICAgICAgICAgICAgRGlzcGxheSBtb2RlIG9wdGlvbnMKICAgICAqLwogICAgZnVuY3Rpb24gb3Blbihtb2RlLCBvcHRpb25zKSB7CiAgICAgICAgZnVuY3Rpb24gb3BlbkRvbmUoKSB7CiAgICAgICAgICAgIC8qIEF0dGFjaCBidXR0b24gZXZlbnQgaGFuZGxlcnMgKi8KICAgICAgICAgICAgdmFyIGJ1dHRvbjsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChidXR0b24gPSBjb250YWluZXIucXVlcnlTZWxlY3RvcignI19fTW9ua2V5Q29uZmlnX2J1dHRvbl9zYXZlJykpCiAgICAgICAgICAgICAgICBidXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzYXZlQ2xpY2ssIHRydWUpOwogICAgICAgICAgICBpZiAoYnV0dG9uID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJyNfX01vbmtleUNvbmZpZ19idXR0b25fY2FuY2VsJykpCiAgICAgICAgICAgICAgICBidXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBjYW5jZWxDbGljaywgdHJ1ZSk7CiAgICAgICAgICAgIGlmIChidXR0b24gPSBjb250YWluZXIucXVlcnlTZWxlY3RvcignI19fTW9ua2V5Q29uZmlnX2J1dHRvbl9kZWZhdWx0cycpKQogICAgICAgICAgICAgICAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZGVmYXVsdHNDbGljaywgdHJ1ZSk7CiAgICAgICAgICAgIAogICAgICAgICAgICBkaXNwbGF5ZWQgPSB0cnVlOwogICAgICAgICAgICB1cGRhdGUoKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgc3dpdGNoIChtb2RlKSB7CiAgICAgICAgY2FzZSAnd2luZG93JzogICAgICAgIAogICAgICAgICAgICB2YXIgd2luZG93RmVhdHVyZXMgPSB7CiAgICAgICAgICAgICAgICBsb2NhdGlvbjogJ25vJywKICAgICAgICAgICAgICAgIHN0YXR1czogJ25vJywKICAgICAgICAgICAgICAgIGxlZnQ6IHdpbmRvdy5zY3JlZW5YLAogICAgICAgICAgICAgICAgdG9wOiB3aW5kb3cuc2NyZWVuWSwKICAgICAgICAgICAgICAgIHdpZHRoOiAxMDAsCiAgICAgICAgICAgICAgICBoZWlnaHQ6IDEwMAogICAgICAgICAgICB9OwogICAgICAgICAgICAKICAgICAgICAgICAgLyogQWRkaXRpb25hbCBmZWF0dXJlcyBtYXkgYmUgc3BlY2lmaWVkIGFzIGFuIG9wdGlvbiAqLwogICAgICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLndpbmRvd0ZlYXR1cmVzKQogICAgICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBvcHRpb25zLndpbmRvd0ZlYXR1cmVzKQogICAgICAgICAgICAgICAgICAgIHdpbmRvd0ZlYXR1cmVzW25hbWVdID0gb3B0aW9ucy53aW5kb3dGZWF0dXJlc1tuYW1lXTsKCiAgICAgICAgICAgIHZhciBmZWF0dXJlc0FycmF5ID0gW107CiAgICAgICAgICAgIAogICAgICAgICAgICBmb3IgKHZhciBuYW1lIGluIHdpbmRvd0ZlYXR1cmVzKQogICAgICAgICAgICAgICAgZmVhdHVyZXNBcnJheS5wdXNoKG5hbWUgKyAnPScgKyB3aW5kb3dGZWF0dXJlc1tuYW1lXSk7CgogICAgICAgICAgICB2YXIgd2luID0gd2luZG93Lm9wZW4oJycsIGRhdGEudGl0bGUsIGZlYXR1cmVzQXJyYXkuam9pbignLCcpKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qIEZpbmQgaGVhZCBhbmQgYm9keSAodGhlbiBjYWxsIHRoZSBibG9vZCBzcGF0dGVyIGFuYWx5c3QpICovCiAgICAgICAgICAgIHZhciBoZWFkID0gd2luLmRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF0sCiAgICAgICAgICAgICAgICBib2R5ID0gd2luLmRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdib2R5JylbMF07CgogICAgICAgICAgICBoZWFkLmlubmVySFRNTCA9ICc8dGl0bGU+JyArIGRhdGEudGl0bGUgKyAnPC90aXRsZT4nICsgCiAgICAgICAgICAgICAgICAnPHN0eWxlIHR5cGU9InRleHQvY3NzIj4nICsKICAgICAgICAgICAgICAgIE1vbmtleUNvbmZpZy5yZXMuc3R5bGVzaGVldHMubWFpbiArICc8L3N0eWxlPic7CiAgICAgICAgICAgIAogICAgICAgICAgICBib2R5LmNsYXNzTmFtZSA9ICdfX01vbmtleUNvbmZpZ193aW5kb3cnOwogICAgICAgICAgICAvKiBQbGFjZSB0aGUgcmVuZGVyZWQgY29uZmlndXJhdGlvbiBkaWFsb2cgaW5zaWRlIHRoZSB3aW5kb3cgYm9keSAqLwogICAgICAgICAgICBib2R5LmlubmVySFRNTCA9IHJlbmRlcigpOwoKICAgICAgICAgICAgLyogRmluZCB0aGUgY29udGFpbmVyIChDQkFOLTM0ODkpICovCiAgICAgICAgICAgIGNvbnRhaW5lciA9IHdpbi5kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuX19Nb25rZXlDb25maWdfY29udGFpbmVyJyk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvKiBSZXNpemUgd2luZG93IHRvIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBjb250YWluZXIgZGl2ICovCiAgICAgICAgICAgIHdpbi5pbm5lcldpZHRoID0gY29udGFpbmVyLmNsaWVudFdpZHRoOwogICAgICAgICAgICB3aW4ucmVzaXplQnkoMCwgLXdpbi5pbm5lckhlaWdodCArIGNvbnRhaW5lci5jbGllbnRIZWlnaHQpOwogICAgICAgICAgICAKICAgICAgICAgICAgLyogUGxhY2UgdGhlIHdpbmRvdyBjZW50ZXJlZCByZWxhdGl2ZSB0byB0aGUgcGFyZW50ICovCiAgICAgICAgICAgIHdpbi5tb3ZlQnkoTWF0aC5yb3VuZCgod2luZG93Lm91dGVyV2lkdGggLSB3aW4ub3V0ZXJXaWR0aCkgLyAyKSwKICAgICAgICAgICAgICAgIE1hdGgucm91bmQoKHdpbmRvdy5vdXRlckhlaWdodCAtIHdpbi5vdXRlckhlaWdodCkgLyAyKSk7CiAgICAgICAgICAgIAogICAgICAgICAgICBvcGVuV2luID0gd2luOwogICAgICAgICAgICAKICAgICAgICAgICAgb3BlbkRvbmUoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ2xheWVyJzoKICAgICAgICAgICAgaWYgKCFNb25rZXlDb25maWcuc3R5bGVBZGRlZCkgewogICAgICAgICAgICAgICAgR01fYWRkU3R5bGUoTW9ua2V5Q29uZmlnLnJlcy5zdHlsZXNoZWV0cy5tYWluKTsKICAgICAgICAgICAgICAgIE1vbmtleUNvbmZpZy5zdHlsZUFkZGVkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgdmFyIGJvZHkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5Jyk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvKiBDcmVhdGUgdGhlIGxheWVyIGVsZW1lbnQgKi8KICAgICAgICAgICAgb3BlbkxheWVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CiAgICAgICAgICAgIG9wZW5MYXllci5jbGFzc05hbWUgPSAnX19Nb25rZXlDb25maWdfbGF5ZXInOwogICAgICAgICAgICAKICAgICAgICAgICAgLyogQ3JlYXRlIHRoZSBvdmVybGF5ICovCiAgICAgICAgICAgIG92ZXJsYXkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgICAgICAgICAgb3ZlcmxheS5jbGFzc05hbWUgPSAnX19Nb25rZXlDb25maWdfb3ZlcmxheSc7CiAgICAgICAgICAgIG92ZXJsYXkuc3R5bGUubGVmdCA9IDA7CiAgICAgICAgICAgIG92ZXJsYXkuc3R5bGUudG9wID0gMDsKICAgICAgICAgICAgb3ZlcmxheS5zdHlsZS53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoICsgJ3B4JzsKICAgICAgICAgICAgb3ZlcmxheS5zdHlsZS5oZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQgKyAncHgnOwogICAgICAgICAgICBvdmVybGF5LnN0eWxlLnpJbmRleCA9IDk5OTk7CiAgICAgICAgICAgIAogICAgICAgICAgICBib2R5LmFwcGVuZENoaWxkKG92ZXJsYXkpOyAgICAgICAgIAogICAgICAgICAgICBib2R5LmFwcGVuZENoaWxkKG9wZW5MYXllcik7CiAgICAgICAgICAgIAogICAgICAgICAgICAvKiAKICAgICAgICAgICAgICogUGxhY2UgdGhlIHJlbmRlcmVkIGNvbmZpZ3VyYXRpb24gZGlhbG9nIGluc2lkZSB0aGUgbGF5ZXIgZWxlbWVudAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgb3BlbkxheWVyLmlubmVySFRNTCA9IHJlbmRlcigpOwogICAgICAgICAgICAKICAgICAgICAgICAgLyogUG9zaXRpb24gdGhlIGxheWVyIGluIHRoZSBjZW50ZXIgb2YgdGhlIHZpZXdwb3J0ICovCiAgICAgICAgICAgIG9wZW5MYXllci5zdHlsZS5sZWZ0ID0gTWF0aC5yb3VuZCgod2luZG93LmlubmVyV2lkdGggLQogICAgICAgICAgICAgICAgICAgIG9wZW5MYXllci5jbGllbnRXaWR0aCkgLyAyKSArICdweCc7CiAgICAgICAgICAgIG9wZW5MYXllci5zdHlsZS50b3AgPSBNYXRoLnJvdW5kKCh3aW5kb3cuaW5uZXJIZWlnaHQgLQogICAgICAgICAgICAgICAgICAgIG9wZW5MYXllci5jbGllbnRIZWlnaHQpIC8gMikgKyAncHgnOwogICAgICAgICAgICBvcGVuTGF5ZXIuc3R5bGUuekluZGV4ID0gOTk5OTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGNvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5fX01vbmtleUNvbmZpZ19jb250YWluZXInKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIG9wZW5Eb25lKCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdpZnJhbWUnOgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGlmICghTW9ua2V5Q29uZmlnLnN0eWxlQWRkZWQpIHsKICAgICAgICAgICAgICAgIEdNX2FkZFN0eWxlKE1vbmtleUNvbmZpZy5yZXMuc3R5bGVzaGVldHMubWFpbik7CiAgICAgICAgICAgICAgICBNb25rZXlDb25maWcuc3R5bGVBZGRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgdmFyIGJvZHkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5Jyk7CiAgICAgICAgICAgIHZhciBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qIENyZWF0ZSB0aGUgbGF5ZXIgZWxlbWVudCAqLwogICAgICAgICAgICBvcGVuTGF5ZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgICAgICAgICAgb3BlbkxheWVyLmNsYXNzTmFtZSA9ICdfX01vbmtleUNvbmZpZ19sYXllcic7CiAgICAgICAgICAgIAogICAgICAgICAgICAvKiBDcmVhdGUgdGhlIG92ZXJsYXkgKi8KICAgICAgICAgICAgb3ZlcmxheSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgICAgICBvdmVybGF5LmNsYXNzTmFtZSA9ICdfX01vbmtleUNvbmZpZ19vdmVybGF5JzsKICAgICAgICAgICAgb3ZlcmxheS5zdHlsZS5sZWZ0ID0gMDsKICAgICAgICAgICAgb3ZlcmxheS5zdHlsZS50b3AgPSAwOwogICAgICAgICAgICBvdmVybGF5LnN0eWxlLndpZHRoID0gd2luZG93LmlubmVyV2lkdGggKyAncHgnOwogICAgICAgICAgICBvdmVybGF5LnN0eWxlLmhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodCArICdweCc7CiAgICAgICAgICAgIG92ZXJsYXkuc3R5bGUuekluZGV4ID0gOTk5OTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmcmFtZS5pZCA9ICdfX01vbmtleUNvbmZpZ19mcmFtZSc7CiAgICAgICAgICAgIC8qIAogICAgICAgICAgICAgKiBNYWtlIHRoZSBpZnJhbWUgdHJhbnNwYXJlbnQgc28gdGhhdCBpdCByZW1haW5zIGludmlzaWJsZSB1bnRpbAogICAgICAgICAgICAgKiB0aGUgZG9jdW1lbnQgaW5zaWRlIGl0IGlzIHJlYWR5CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZnJhbWUuc3R5bGUub3BhY2l0eSA9IDA7CiAgICAgICAgICAgIGlmcmFtZS5zcmMgPSAnYWJvdXQ6YmxhbmsnOwogICAgICAgICAgICAKICAgICAgICAgICAgLyogTWFrZSB0aGUgaWZyYW1lIHNlYW1sZXNzIHdpdGggbm8gYm9yZGVyIGFuZCBubyBzY3JvbGxiYXJzICovIAogICAgICAgICAgICBpZiAodW5kZWZpbmVkICE9PSBpZnJhbWUuZnJhbWVib3JkZXIpCiAgICAgICAgICAgICAgICBpZnJhbWUuZnJhbWVCb3JkZXIgPSAnMCc7CiAgICAgICAgICAgIGlmICh1bmRlZmluZWQgIT09IGlmcmFtZS5zY3JvbGxpbmcpCiAgICAgICAgICAgICAgICBpZnJhbWUuc2Nyb2xsaW5nID0gJ25vJzsKICAgICAgICAgICAgaWYgKHVuZGVmaW5lZCAhPT0gaWZyYW1lLnNlYW1sZXNzKQogICAgICAgICAgICAgICAgaWZyYW1lLnNlYW1sZXNzID0gdHJ1ZTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qIERvIHRoZSByZXN0IGluIHRoZSBsb2FkIGV2ZW50IGhhbmRsZXIgKi8KICAgICAgICAgICAgaWZyYW1lLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBpZnJhbWUuY29udGVudERvY3VtZW50LmJvZHkuaW5uZXJIVE1MID0gcmVuZGVyKCk7CiAgICAgICAgICAgICAgICBpZnJhbWUuc3R5bGUub3BhY2l0eSA9IDE7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8qIEFwcGVuZCB0aGUgc3R5bGUgdG8gdGhlIGhlYWQgKi8KICAgICAgICAgICAgICAgIHZhciBoZWFkID0gaWZyYW1lLmNvbnRlbnREb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdoZWFkJyksCiAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBpZnJhbWUuY29udGVudERvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7CiAgICAgICAgICAgICAgICBzdHlsZS5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAndGV4dC9jc3MnKTsKICAgICAgICAgICAgICAgIHN0eWxlLmFwcGVuZENoaWxkKGlmcmFtZS5jb250ZW50RG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoCiAgICAgICAgICAgICAgICAgICAgICAgIE1vbmtleUNvbmZpZy5yZXMuc3R5bGVzaGVldHMubWFpbikpOwogICAgICAgICAgICAgICAgaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBib2R5ID0gaWZyYW1lLmNvbnRlbnREb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5Jyk7CiAgICAgICAgICAgICAgICBib2R5LmNsYXNzTmFtZSA9ICdfX01vbmtleUNvbmZpZ19ib2R5JzsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgY29udGFpbmVyID0gaWZyYW1lLmNvbnRlbnREb2N1bWVudAogICAgICAgICAgICAgICAgICAgIC5xdWVyeVNlbGVjdG9yKCcuX19Nb25rZXlDb25maWdfY29udGFpbmVyJyk7CgogICAgICAgICAgICAgICAgaWZyYW1lLndpZHRoID0gY29udGFpbmVyLmNsaWVudFdpZHRoOwogICAgICAgICAgICAgICAgaWZyYW1lLmhlaWdodCA9IGNvbnRhaW5lci5jbGllbnRIZWlnaHQ7CgogICAgICAgICAgICAgICAgLyogUG9zaXRpb24gdGhlIGxheWVyIGluIHRoZSBjZW50ZXIgb2YgdGhlIHZpZXdwb3J0ICovCiAgICAgICAgICAgICAgICBvcGVuTGF5ZXIuc3R5bGUubGVmdCA9IE1hdGgucm91bmQoKHdpbmRvdy5pbm5lcldpZHRoIC0KICAgICAgICAgICAgICAgICAgICAgICAgb3BlbkxheWVyLmNsaWVudFdpZHRoKSAvIDIpICsgJ3B4JzsKICAgICAgICAgICAgICAgIG9wZW5MYXllci5zdHlsZS50b3AgPSBNYXRoLnJvdW5kKCh3aW5kb3cuaW5uZXJIZWlnaHQgLQogICAgICAgICAgICAgICAgICAgICAgICBvcGVuTGF5ZXIuY2xpZW50SGVpZ2h0KSAvIDIpICsgJ3B4JzsKICAgICAgICAgICAgICAgIG9wZW5MYXllci5zdHlsZS56SW5kZXggPSA5OTk5OwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBvcGVuRG9uZSgpOwogICAgICAgICAgICB9LCBmYWxzZSk7CgogICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGlmcmFtZS53aWR0aCA9IGNvbnRhaW5lci5jbGllbnRXaWR0aDsKICAgICAgICAgICAgICAgIGlmcmFtZS5oZWlnaHQgPSBjb250YWluZXIuY2xpZW50SGVpZ2h0OwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvKiBQb3NpdGlvbiB0aGUgbGF5ZXIgaW4gdGhlIGNlbnRlciBvZiB0aGUgdmlld3BvcnQgKi8KICAgICAgICAgICAgICAgIG9wZW5MYXllci5zdHlsZS5sZWZ0ID0gTWF0aC5yb3VuZCgod2luZG93LmlubmVyV2lkdGggLQogICAgICAgICAgICAgICAgICAgICAgICBvcGVuTGF5ZXIuY2xpZW50V2lkdGgpIC8gMikgKyAncHgnOwogICAgICAgICAgICAgICAgb3BlbkxheWVyLnN0eWxlLnRvcCA9IE1hdGgucm91bmQoKHdpbmRvdy5pbm5lckhlaWdodCAtCiAgICAgICAgICAgICAgICAgICAgICAgIG9wZW5MYXllci5jbGllbnRIZWlnaHQpIC8gMikgKyAncHgnOwogICAgICAgICAgICAgICAgb3BlbkxheWVyLnN0eWxlLnpJbmRleCA9IDk5OTk7CiAgICAgICAgICAgIH0sIDApOwogICAgICAgICAgICAKICAgICAgICAgICAgYm9keS5hcHBlbmRDaGlsZChvdmVybGF5KTsgICAgICAgICAKICAgICAgICAgICAgYm9keS5hcHBlbmRDaGlsZChvcGVuTGF5ZXIpOwogICAgICAgICAgICBvcGVuTGF5ZXIuYXBwZW5kQ2hpbGQoaWZyYW1lKTsKICAgICAgICAKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIENsb3NlIGNvbmZpZ3VyYXRpb24gZGlhbG9nIAogICAgICovCiAgICBmdW5jdGlvbiBjbG9zZSgpIHsKICAgICAgICBpZiAob3BlbldpbikgewogICAgICAgICAgICBvcGVuV2luLmNsb3NlKCk7CiAgICAgICAgICAgIG9wZW5XaW4gPSB1bmRlZmluZWQ7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKG9wZW5MYXllcikgewogICAgICAgICAgICBvcGVuTGF5ZXIucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChvcGVuTGF5ZXIpOwogICAgICAgICAgICBvcGVuTGF5ZXIgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAob3ZlcmxheSkgewogICAgICAgICAgICAgICAgb3ZlcmxheS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG92ZXJsYXkpOwogICAgICAgICAgICAgICAgb3ZlcmxheSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBkaXNwbGF5ZWQgPSBmYWxzZTsKICAgIH0KCiAgICBpbml0KGFyZ3VtZW50c1swXSk7Cn0KCi8qKgogKiBSZXBsYWNlIGRvdWJsZSBxdW90ZXMgd2l0aCBlbnRpdGllcyBzbyB0aGF0IHRoZSBzdHJpbmcgY2FuIGJlIHNhZmVseSB1c2VkCiAqIGluIGEgSFRNTCBhdHRyaWJ1dGUKICogCiAqIEBwYXJhbSBzdHJpbmcgQSBzdHJpbmcKICogQHJldHVybnMgU3RyaW5nIHdpdGggZG91YmxlIHF1b3RlcyByZXBsYWNlZCB3aXRoIGVudGl0aWVzCiAqLwpNb25rZXlDb25maWcuZXNjID0gZnVuY3Rpb24gKHN0cmluZykgewogICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC8iL2csICcmcXVvdDsnKTsKfTsKCk1vbmtleUNvbmZpZy5IVE1MID0gewogICAgJ19maWVsZCc6IGZ1bmN0aW9uIChuYW1lLCBvcHRpb25zLCBkYXRhKSB7CiAgICAgICAgdmFyIGh0bWw7CiAgICAgICAgCiAgICAgICAgaWYgKG9wdGlvbnMudHlwZSAmJiBNb25rZXlDb25maWcuSFRNTFtvcHRpb25zLnR5cGVdKQogICAgICAgICAgICBodG1sID0gTW9ua2V5Q29uZmlnLkhUTUxbb3B0aW9ucy50eXBlXShuYW1lLCBvcHRpb25zLCBkYXRhKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAKICAgICAgICBpZiAoL1xbRklFTERcXS8udGVzdChvcHRpb25zLmh0bWwpKSB7CiAgICAgICAgICAgIGh0bWwgPSBvcHRpb25zLmh0bWwucmVwbGFjZSgvXFtGSUVMRFxdLywgaHRtbCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBodG1sOwogICAgfSwKICAgICdfbGFiZWwnOiBmdW5jdGlvbiAobmFtZSwgb3B0aW9ucywgZGF0YSkgewogICAgICAgIHZhciBsYWJlbCA9IG9wdGlvbnNbJ2xhYmVsJ10gfHwKICAgICAgICAgICAgbmFtZS5zdWJzdHJpbmcoMCwgMSkudG9VcHBlckNhc2UoKSArIG5hbWUuc3Vic3RyaW5nKDEpCiAgICAgICAgICAgICAgICAucmVwbGFjZSgvXy9nLCAnJm5ic3A7Jyk7CgogICAgICAgIHJldHVybiAnPGxhYmVsIGZvcj0iX19Nb25rZXlDb25maWdfZmllbGRfJyArIG5hbWUgKyAnIj4nICsgbGFiZWwgKwogICAgICAgICAgICAnPC9sYWJlbD4nOwogICAgfSwKICAgICdjaGVja2JveCc6IGZ1bmN0aW9uIChuYW1lLCBvcHRpb25zLCBkYXRhKSB7CiAgICAgICAgcmV0dXJuICc8aW5wdXQgaWQ9Il9fTW9ua2V5Q29uZmlnX2ZpZWxkXycgKyBuYW1lICsgCiAgICAgICAgICAgICciIHR5cGU9ImNoZWNrYm94IiBuYW1lPSInICsgbmFtZSArICciIC8+JzsgCiAgICB9LAogICAgJ2N1c3RvbSc6IGZ1bmN0aW9uIChuYW1lLCBvcHRpb25zLCBkYXRhKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbnMuaHRtbDsKICAgIH0sCiAgICAnbnVtYmVyJzogZnVuY3Rpb24gKG5hbWUsIG9wdGlvbnMsIGRhdGEpIHsKICAgICAgICByZXR1cm4gJzxpbnB1dCBpZD0iX19Nb25rZXlDb25maWdfZmllbGRfJyArIG5hbWUgKyAnIiAnICsKICAgICAgICAgICAgJ3R5cGU9InRleHQiIGNsYXNzPSJfX01vbmtleUNvbmZpZ19maWVsZF9udW1iZXIiICcgKwogICAgICAgICAgICAnbmFtZT0iJyArIG5hbWUgKyAnIiAvPic7CiAgICB9LAogICAgJ3NlbGVjdCc6IGZ1bmN0aW9uIChuYW1lLCBvcHRpb25zLCBkYXRhKSB7CiAgICAgICAgdmFyIGNob2ljZXMgPSB7fSwgaHRtbCA9ICcnOwogICAgICAgIAogICAgICAgIGlmIChvcHRpb25zLmNob2ljZXMuY29uc3RydWN0b3IgPT0gQXJyYXkpIHsKICAgICAgICAgICAgLyogb3B0aW9ucy5jaG9pY2VzIGlzIGFuIGFycmF5IC0tIGJ1aWxkIGtleS92YWx1ZSBwYWlycyAqLwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wdGlvbnMuY2hvaWNlcy5sZW5ndGg7IGkrKykKICAgICAgICAgICAgICAgIGNob2ljZXNbb3B0aW9ucy5jaG9pY2VzW2ldXSA9IG9wdGlvbnMuY2hvaWNlc1tpXTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICAvKiBvcHRpb25zLmNob2ljZXMgaXMgYW4gb2JqZWN0IC0tIHVzZSBpdCBhcyBpdCBpcyAqLwogICAgICAgICAgICBjaG9pY2VzID0gb3B0aW9ucy5jaG9pY2VzOwoKICAgICAgICBpZiAoIW9wdGlvbnMubXVsdGlwbGUpIHsKICAgICAgICAgICAgLyogU2luZ2xlIHNlbGVjdGlvbiAqLwogICAgICAgICAgICBpZiAoIS9ecmFkaW8vLnRlc3Qob3B0aW9ucy52YXJpYW50KSkgewogICAgICAgICAgICAgICAgLyogU2VsZWN0IGVsZW1lbnQgKi8KICAgICAgICAgICAgICAgIGh0bWwgKz0gJzxzZWxlY3QgaWQ9Il9fTW9ua2V5Q29uZmlnX2ZpZWxkXycgKyBuYW1lICsgJyIgJyArCiAgICAgICAgICAgICAgICAgICAgJ2NsYXNzPSJfX01vbmtleUNvbmZpZ19maWVsZF9zZWxlY3QiICcgKwogICAgICAgICAgICAgICAgICAgICduYW1lPSInICsgbmFtZSArICciPic7CiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgZm9yICh2YXIgdmFsdWUgaW4gY2hvaWNlcykKICAgICAgICAgICAgICAgICAgICBodG1sICs9ICc8b3B0aW9uIHZhbHVlPSInICsgTW9ua2V5Q29uZmlnLmVzYyh2YWx1ZSkgKyAnIj4nICsKICAgICAgICAgICAgICAgICAgICAgICAgY2hvaWNlc1t2YWx1ZV0gKyAnPC9vcHRpb24+JzsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaHRtbCArPSAnPC9zZWxlY3Q+JzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIFJhZGlvIGJ1dHRvbnMgKi8KICAgICAgICAgICAgICAgIGZvciAodmFyIHZhbHVlIGluIGNob2ljZXMpIHsKICAgICAgICAgICAgICAgICAgICBodG1sICs9ICc8bGFiZWw+PGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSInICsgbmFtZSArICciICcgKwogICAgICAgICAgICAgICAgICAgICAgICAndmFsdWU9IicgKyBNb25rZXlDb25maWcuZXNjKHZhbHVlKSArICciIC8+Jm5ic3A7JyArCiAgICAgICAgICAgICAgICAgICAgICAgIGNob2ljZXNbdmFsdWVdICsgJzwvbGFiZWw+JyArCiAgICAgICAgICAgICAgICAgICAgICAgICgvIGNvbHVtbi8udGVzdChvcHRpb25zLnZhcmlhbnQpID8gJzxiciAvPicgOiAnJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8qIE11bHRpcGxlIHNlbGVjdGlvbiAqLwogICAgICAgICAgICBpZiAoIS9eY2hlY2tib3gvLnRlc3Qob3B0aW9ucy52YXJpYW50KSkgewogICAgICAgICAgICAgICAgLyogQ2hlY2tib3hlcyAqLwogICAgICAgICAgICAgICAgaHRtbCArPSAnPHNlbGVjdCBpZD0iX19Nb25rZXlDb25maWdfZmllbGRfJyArIG5hbWUgKyAnIiAnICsKICAgICAgICAgICAgICAgICAgICAnY2xhc3M9Il9fTW9ua2V5Q29uZmlnX2ZpZWxkX3NlbGVjdCIgJyArCiAgICAgICAgICAgICAgICAgICAgJ211bHRpcGxlPSJtdWx0aXBsZSIgJyArCiAgICAgICAgICAgICAgICAgICAgJ25hbWU9IicgKyBuYW1lICsgJyI+JzsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgZm9yICh2YXIgdmFsdWUgaW4gY2hvaWNlcykKICAgICAgICAgICAgICAgICAgICBodG1sICs9ICc8b3B0aW9uIHZhbHVlPSInICsgTW9ua2V5Q29uZmlnLmVzYyh2YWx1ZSkgKyAnIj4nICsKICAgICAgICAgICAgICAgICAgICAgICAgY2hvaWNlc1t2YWx1ZV0gKyAnPC9vcHRpb24+JzsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaHRtbCArPSAnPC9zZWxlY3Q+JzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIFNlbGVjdCBlbGVtZW50ICovCiAgICAgICAgICAgICAgICBmb3IgKHZhciB2YWx1ZSBpbiBjaG9pY2VzKSB7CiAgICAgICAgICAgICAgICAgICAgaHRtbCArPSAnPGxhYmVsPjxpbnB1dCB0eXBlPSJjaGVja2JveCIgJyArCiAgICAgICAgICAgICAgICAgICAgICAgICduYW1lPSInICsgbmFtZSArICciICcgKwogICAgICAgICAgICAgICAgICAgICAgICAndmFsdWU9IicgKyBNb25rZXlDb25maWcuZXNjKHZhbHVlKSArICciIC8+Jm5ic3A7JyArCiAgICAgICAgICAgICAgICAgICAgICAgIGNob2ljZXNbdmFsdWVdICsgJzwvbGFiZWw+JyArCiAgICAgICAgICAgICAgICAgICAgICAgICgvIGNvbHVtbi8udGVzdChvcHRpb25zLnZhcmlhbnQpID8gJzxiciAvPicgOiAnJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIGh0bWw7CiAgICB9LAogICAgJ3RleHQnOiBmdW5jdGlvbiAobmFtZSwgb3B0aW9ucywgZGF0YSkgewogICAgICAgIGlmIChvcHRpb25zLmxvbmcpCiAgICAgICAgICAgIHJldHVybiAnPHRleHRhcmVhIGlkPSJfX01vbmtleUNvbmZpZ19maWVsZF8nICsgbmFtZSArICciICcgKwogICAgICAgICAgICAgICAgJ2NsYXNzPSJfX01vbmtleUNvbmZpZ19maWVsZF90ZXh0IiAnICsKICAgICAgICAgICAgICAgICghaXNOYU4ob3B0aW9ucy5sb25nKSA/ICdyb3dzPSInICsgb3B0aW9ucy5sb25nICsgJyIgJyA6ICcnKSArCiAgICAgICAgICAgICAgICAnbmFtZT0iJyArIG5hbWUgKyAnIj48L3RleHRhcmVhPic7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gJzxpbnB1dCBpZD0iX19Nb25rZXlDb25maWdfZmllbGRfJyArIG5hbWUgKyAnIiAnICsKICAgICAgICAgICAgICAgICd0eXBlPSJ0ZXh0IiBjbGFzcz0iX19Nb25rZXlDb25maWdfZmllbGRfdGV4dCIgJyArCiAgICAgICAgICAgICAgICAnbmFtZT0iJyArIG5hbWUgKyAnIiAvPic7CiAgICB9LAogICAgJ2NvbG9yJzogZnVuY3Rpb24obmFtZSwgb3B0aW9ucywgZGF0YSkgewogICAgICAgIHJldHVybiAnPGlucHV0IGlkPSJfX01vbmtleUNvbmZpZ19maWVsZF8nICsgbmFtZSArICciICcgKwogICAgICAgICAgICAndHlwZT0iY29sb3IiIGNsYXNzPSJfX01vbmtleUNvbmZpZ19maWVsZF90ZXh0IiAnICsKICAgICAgICAgICAgJ25hbWU9IicgKyBuYW1lICsgJyIgLz4nOwogICAgfQp9OwoKTW9ua2V5Q29uZmlnLmZvcm1hdHRlcnMgPSB7CiAgICAndHInOiBmdW5jdGlvbiAobmFtZSwgb3B0aW9ucywgZGF0YSkgewogICAgICAgIHZhciBodG1sID0gJzx0cj4nOwoKICAgICAgICBzd2l0Y2ggKG9wdGlvbnMudHlwZSkgewogICAgICAgIGNhc2UgJ2NoZWNrYm94JzoKICAgICAgICAgICAgLyogQ2hlY2tib3hlcyBnZXQgc3BlY2lhbCB0cmVhdG1lbnQgKi8KICAgICAgICAgICAgaHRtbCArPSAnPHRkIGlkPSJfX01vbmtleUNvbmZpZ19wYXJlbnRfJyArIG5hbWUgKyAnIiBjb2xzcGFuPSIyIj4nOwogICAgICAgICAgICBodG1sICs9IE1vbmtleUNvbmZpZy5IVE1MWydfZmllbGQnXShuYW1lLCBvcHRpb25zLCBkYXRhKSArICcgJzsKICAgICAgICAgICAgaHRtbCArPSBNb25rZXlDb25maWcuSFRNTFsnX2xhYmVsJ10obmFtZSwgb3B0aW9ucywgZGF0YSk7CiAgICAgICAgICAgIGh0bWwgKz0gJzwvdGQ+JzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaHRtbCArPSAnPHRkPic7CiAgICAgICAgICAgIGh0bWwgKz0gTW9ua2V5Q29uZmlnLkhUTUxbJ19sYWJlbCddKG5hbWUsIG9wdGlvbnMsIGRhdGEpOwogICAgICAgICAgICBodG1sICs9ICc8L3RkPjx0ZCBpZD0iX19Nb25rZXlDb25maWdfcGFyZW50XycgKyBuYW1lICsgJyI+JzsKICAgICAgICAgICAgaHRtbCArPSBNb25rZXlDb25maWcuSFRNTFsnX2ZpZWxkJ10obmFtZSwgb3B0aW9ucywgZGF0YSk7CiAgICAgICAgICAgIGh0bWwgKz0gJzwvdGQ+JzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGh0bWwgKz0gJzwvdHI+JzsKCiAgICAgICAgcmV0dXJuIGh0bWw7CiAgICB9Cn07CgovKiBIYXMgdGhlIHN0eWxlc2hlZXQgYmVlbiBhZGRlZD8gKi8KTW9ua2V5Q29uZmlnLnN0eWxlQWRkZWQgPSBmYWxzZTsKCi8qIFJlc291cmNlcyAqLwpNb25rZXlDb25maWcucmVzID0ge307CgovKiBJY29ucyAqLwpNb25rZXlDb25maWcucmVzLmljb25zID0gewogICAgJ2Fycm93X3VuZG8nOiAnaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFDQVlBQUFBZjgvOWhBQUFBQkdkQlRVRUFBSy9JTndXSzZRQUFBQmwwUlZoMFwKVTI5bWRIZGhjbVVBUVdSdlltVWdTVzFoWjJWU1pXRmtlWEhKWlR3QUFBSUpTVVJCVkRqTHBWTTlhSk5SRkQzNUdzUlNvVUtLelEvQlwKME5KSkYzRVFsS3JWZ2lqU0NCbUM0TkJGS2loSWNYQndFWmRTSFZvVXdVSW5GVUVrUTFEUTRDS2lGc1FzVHJiNXhOcGdhWkh3MlVvZ1wKNXQ1em4wTkpORmF3MGd1WDk3aHd6dVBjYzE3SU9ZZk5sSWROVnJoeHVmUjZ4SmtaakFiU1FHWGpOQW9ycWl4U1dGRFYzS1BoSitVR1wKTHRTUU1QcnlyRHNjUHdMbkFIT0VPUWM2Z2tiVXBJYWdHbUFwV0liL3BaUlg0ZmpqODg5bldpU1F0Z1l5QloxQlRVRWo2QWpQYTBQN1wKMW5iMEpmcXdhK2Z1dEloZUhyelJuMnlSUUNVSy9sT1FoQXBCSlZRSkNoSGZua0NxT3dXRVEraU9SSkhja1V5WDVrc3ZBRXlHTnVKQ1wKK3M2eENSWE5ITnh6S01tUTRsdXdnamZ2WnA2OXV2cjIrSVpjeUo4cmpJcG9ycnhVUmdnZXRuVjBRRVQzcnJQeHpNTk0yK243cDY3OFwKalVUckNpV2hwaEFqVkhSOURsUjBXa1N6ZjRJSHhnNU1TRjB6WFpFdVZLV0tTbENCQ29zdFM4emVHN29WNjR3UHF4SW5idzg2bGJWWFwKS0VROG1rQXFtVUo0U3hpZWVWaGNuQU5GQzAyQzdOMmg2OUhPMklYZVdDOE1EajJKbnFhRk5BTWQ4ZjNIS2p4NitMeFFSbW5PejFPWlwKYXhLSWFGMVZJU1l3QjlBUlpvUWFZWTZvMVdwWUNWWXh0K3pEbi9YelZCdi9NT1dYVzVKNDR1YlJ5VmdrZWxGcG1GLzRCSlZmT1ZEbFwKVnlxTFZCWkk1bWFuUGphakRPZGNzd2ZHOWsvM1g5djMvdmZadjdyRkJhbnJpSW8rK0ovZitCTVQrWVdTNmhYbDdRQUFBQUJKUlU1RVwKcmtKZ2dnPT0nLAogICAgJ2NhbmNlbCc6ICdpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQkFBQUFBUUNBWUFBQUFmOC85aEFBQUFCR2RCVFVFQUFLL0lOd1dLNlFBQUFCbDBSVmgwXApVMjltZEhkaGNtVUFRV1J2WW1VZ1NXMWhaMlZTWldGa2VYSEpaVHdBQUFIZFNVUkJWRGpMcFpOcmF4cEJGSWIzYTBnZ0lTbW1OSVNXXApYbU9ib0tpaHhwZ1VOR1dOU3B2YVM2UnBLTDNSeS8vTWgxd2dmNlBFbGFDeXpxNjdPMDluVmpkVmxKYlNEeThMdzc3UG1mZWNNd1pnXAovSS9HRHczRENvOEhDa1psL1JsZ0dBMGUzWWZ2NytEYkFmTHJXK1NYT3ZMVEcrU0hWL2dQYnVNWlJuc3lJREwvT0FTemlNeGtrS2tVXApRVEpKc0xhR244L2lIejZuZCs4bVF2ODdBaGcySDlUaC9CeFpxeEVrRWdTcnEvaVZDdkxzREs5YXd0dmZ4YjJ6akQyQVJJRCtsVlZsXApiYWJUZ1dZVHYxckZMNWZCVXRIYmJlVEpDYjNFUTNvdkNuUkM2eEFnekp0T0UrenRoZVlJRWtxYkZhUzN2WTJ6dUlqNzdBbXRZWUR1XApzUHk4L3p1dnVuSmtES1hNN3RZV1RpeUdXRmpBcWVRbkFENis3dWVOeC9GTHBSR0FydTdtY29qNWVicXpzemlsN0RnZ2VGL0RYMW5CXApOODJyelBxcnpiUmF5SXNMaEpxTVBUMk44M1NkeTJHQXB3RnFSTjdqRlBMMHRGKzEwY0RkM01UWjJBak5Va0dDb3lPNnk5Y1J4ZlFvXAp3RlVicHVmcjFjdDRab0hnK0RnMDY3emR1VG1FYnE0eWkvVWtZaWREZStrYVRjUDRPYkpJYWprc1BkL2V5eDNjK04ycnZQYk1EUGJVXApGUFpTTEt6Y0dqS1ByYkphRHN1K2RRTzNtc2ZaemVHWTJUQ3ZLR1lRaGRTWWVlSmpVdDIxZEljalhRN1U3S3Y1OTlmNGovb0Y1NVc0XApnLzJlM2I4QUFBQUFTVVZPUks1Q1lJST0nLAogICAgJ3RpY2snOiAnaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFDQVlBQUFBZjgvOWhBQUFBQkdkQlRVRUFBSy9JTndXSzZRQUFBQmwwUlZoMFwKVTI5bWRIZGhjbVVBUVdSdlltVWdTVzFoWjJWU1pXRmtlWEhKWlR3QUFBR3JTVVJCVkRqTHZaUFpMa05oRklWNzV6anZZbTdWR0ZOQ1wKcW9aVUorcm9LVVVwalJ1cXA2MVdxME5LRE1lbEdHcU94QlNVSUJLWFd0V0daeEF2b2JyOGxXakNoUmdTRi8vZHY5YmUrOXRyQ3dBSVwKL3ZJRS8yNmdYbXZpVzVicW5iOHlVSzAyOHFaalBmb1BXRWo0S3U1SEJzcGdBejk0MUlYWmV6ZThOMWJvdHRTbzhCVFp2aVZXckVoNVwKNDZFTzAzRVhwdUpPZEc2M290SmJqQktIa0VwL01sNnlOWVl6cHVleldMNHM1Vk10VDhhY0NNUWNiNVhMM2VKRThWZ0JsUjdCZU1HV1wKOVo0eVQ5eTFDZXl1Y3VoZFRHRHhmZnRhQk83RzRMK3pnOTFVb2N4Vm1DaXk1MU5waVAzbjJ0cmVVUHVqTDh4aE9qWU96WllzUVdBTlwKeVJZbFU0WTlCcjZvSGQ1YkRoMGJDcFNPaXhKaVd4NzFZWTA5SjVwTS9XRWJ6RmNEbUh2d3dCdTJ3bmlrZytsRWo0bXdCZTViQzVoMVwKT1VxY3dwZEM2MGR4ZWdSbVIwNlR5akNGOUc5eitxTTJ1Q0ptdU1KbWFOWmFVckNTSWk2WCtqSklCQll0VzVDZ2U3Y2Q3c2dvSERmRFwKYUF2S1FHQWxSWlljNmx0SmxNeFgwM1V6bGFSbEJkUXJ6U0N3a3NMUmJPcEhVU2I3cGNzbnhDQ3duZ3ZNMlJtL3VnVUNpODRmeWNyNFwKbDJ0OEJiNmlxVHhTQ2dOSUFBQUFBRWxGVGtTdVFtQ0MnCn07CgovKiBTdHlsZXNoZWV0cyAqLwpNb25rZXlDb25maWcucmVzLnN0eWxlc2hlZXRzID0gewogICAgJ21haW4nOiAnXApib2R5Ll9fTW9ua2V5Q29uZmlnX3dpbmRvdyB7XAogICAgYXBwZWFyYW5jZTogd2luZG93ICFpbXBvcnRhbnQ7XAogICAgLW1vei1hcHBlYXJhbmNlOiB3aW5kb3cgIWltcG9ydGFudDtcCiAgICBiYWNrZ3JvdW5kOiBhdXRvO1wKICAgIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmICFpbXBvcnRhbnQ7XAogICAgaGVpZ2h0OiAxMDAlICFpbXBvcnRhbnQ7XAogICAgbWFyZ2luOiAwICFpbXBvcnRhbnQ7XAogICAgcGFkZGluZzogMCAhaW1wb3J0YW50O1wKICAgIHdpZHRoOiAxMDAlICFpbXBvcnRhbnQ7XAp9XApcCmRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIge1wKICAgIGRpc3BsYXk6IHRhYmxlICFpbXBvcnRhbnQ7XAogICAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWYgIWltcG9ydGFudDtcCiAgICBwYWRkaW5nOiAwLjNlbSAhaW1wb3J0YW50O1wKfVwKXApib2R5Ll9fTW9ua2V5Q29uZmlnX3dpbmRvdyBkaXYuX19Nb25rZXlDb25maWdfY29udGFpbmVyIHtcCiAgICBhcHBlYXJhbmNlOiB3aW5kb3cgIWltcG9ydGFudDtcCiAgICAtbW96LWFwcGVhcmFuY2U6IHdpbmRvdyAhaW1wb3J0YW50O1wKICAgIGhlaWdodDogMTAwJTtcCiAgICB3aWR0aDogMTAwJTtcCn1cClwKZGl2Ll9fTW9ua2V5Q29uZmlnX2NvbnRhaW5lciBoMSB7XAogICAgYm9yZGVyLWJvdHRvbTogc29saWQgMXB4ICM5OTkgIWltcG9ydGFudDtcCiAgICBmb250LWZhbWlseTogc2Fucy1zZXJpZiAhaW1wb3J0YW50O1wKICAgIGZvbnQtc2l6ZTogMTIwJSAhaW1wb3J0YW50O1wKICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1wKICAgIHBhZGRpbmc6IDAgMCAwLjNlbSAwICFpbXBvcnRhbnQ7XAp9XApcCmRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIgdGFibGUge1wKICAgIGJvcmRlci1zcGFjaW5nOiAwICFpbXBvcnRhbnQ7XAogICAgbWFyZ2luOiAwICFpbXBvcnRhbnQ7XAp9XApcCmRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIgdGFibGUgdGQge1wKICAgIGJvcmRlcjogbm9uZSAhaW1wb3J0YW50O1wKICAgIGxpbmUtaGVpZ2h0OiAxMDAlICFpbXBvcnRhbnQ7XAogICAgcGFkZGluZzogMC4zZW0gIWltcG9ydGFudDtcCiAgICB0ZXh0LWFsaWduOiBsZWZ0ICFpbXBvcnRhbnQ7XAogICAgdmVydGljYWwtYWxpZ246IHRvcCAhaW1wb3J0YW50O1wKICAgIHdoaXRlLXNwYWNlOiBub3dyYXAgIWltcG9ydGFudDtcCn1cClwKZGl2Ll9fTW9ua2V5Q29uZmlnX2NvbnRhaW5lciB0YWJsZSB0ZC5fX01vbmtleUNvbmZpZ19idXR0b25zIHtcCiAgICBwYWRkaW5nOiAwLjJlbSAwICFpbXBvcnRhbnQ7XAp9XApcCi5fX01vbmtleUNvbmZpZ19maWVsZF9udW1iZXIge1wKICAgIHdpZHRoOiA1ZW0gIWltcG9ydGFudDtcCn1cClwKZGl2Ll9fTW9ua2V5Q29uZmlnX2NvbnRhaW5lciB0ZC5fX01vbmtleUNvbmZpZ19idXR0b25zIHRhYmxlIHtcCiAgICBib3JkZXItdG9wOiBzb2xpZCAxcHggIzk5OSAhaW1wb3J0YW50O1wKICAgIHdpZHRoOiAxMDAlICFpbXBvcnRhbnQ7XAp9XApcCmRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIgdGQuX19Nb25rZXlDb25maWdfYnV0dG9ucyB0ZCB7XAogICAgcGFkZGluZzogMC42ZW0gMC4zZW0gMC4xZW0gMC4zZW0gIWltcG9ydGFudDtcCiAgICB0ZXh0LWFsaWduOiBjZW50ZXIgIWltcG9ydGFudDtcCiAgICB2ZXJ0aWNhbC1hbGlnbjogdG9wO1wKfVwKXApkaXYuX19Nb25rZXlDb25maWdfY29udGFpbmVyIHRkLl9fTW9ua2V5Q29uZmlnX2J1dHRvbnMgYnV0dG9uIHtcCiAgICBhcHBlYXJhbmNlOiBidXR0b24gIWltcG9ydGFudDtcCiAgICAtbW96LWFwcGVhcmFuY2U6IGJ1dHRvbiAhaW1wb3J0YW50O1wKICAgIGJhY2tncm91bmQtcG9zaXRpb246IDhweCA1MCUgIWltcG9ydGFudDtcCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0ICFpbXBvcnRhbnQ7XAogICAgcGFkZGluZzogM3B4IDhweCAzcHggMjRweCAhaW1wb3J0YW50O1wKICAgIHBhZGRpbmc6IDNweCA4cHggIWltcG9ydGFudDtcCiAgICB3aGl0ZS1zcGFjZTogbm93cmFwICFpbXBvcnRhbnQ7XAp9XApcCmRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIgdGQuX19Nb25rZXlDb25maWdfYnV0dG9ucyBidXR0b24gaW1nIHtcCiAgICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlICFpbXBvcnRhbnQ7XAp9XApcCmRpdi5fX01vbmtleUNvbmZpZ19sYXllciB7XAogICAgZGlzcGxheTogdGFibGUgIWltcG9ydGFudDtcCiAgICBwb3NpdGlvbjogZml4ZWQgIWltcG9ydGFudDtcCn1cClwKZGl2Ll9fTW9ua2V5Q29uZmlnX2xheWVyIGRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIsXApib2R5Ll9fTW9ua2V5Q29uZmlnX2JvZHkgPiBkaXYuX19Nb25rZXlDb25maWdfY29udGFpbmVyIHtcCiAgICBiYWNrZ3JvdW5kOiAjZWVlIGxpbmVhci1ncmFkaWVudCgxODBkZWcsXAogICAgICAgICNmOGY4ZjggMCwgI2RkZCAxMDAlKSAhaW1wb3J0YW50O1wKICAgIGJvcmRlci1yYWRpdXM6IDAuNWVtICFpbXBvcnRhbnQ7XAogICAgYm94LXNoYWRvdzogMnB4IDJweCAxNnB4ICMwMDAgIWltcG9ydGFudDtcCiAgICBjb2xvcjogIzAwMCAhaW1wb3J0YW50O1wKICAgIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmICFpbXBvcnRhbnQ7XAogICAgZm9udC1zaXplOiAxMXB0ICFpbXBvcnRhbnQ7XAogICAgcGFkZGluZzogMWVtIDFlbSAwLjRlbSAxZW0gIWltcG9ydGFudDtcCn1cClwKZGl2Ll9fTW9ua2V5Q29uZmlnX2xheWVyIGRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIgdGQsXApkaXYuX19Nb25rZXlDb25maWdfbGF5ZXIgZGl2Ll9fTW9ua2V5Q29uZmlnX2NvbnRhaW5lciBsYWJlbCxcCmRpdi5fX01vbmtleUNvbmZpZ19sYXllciBkaXYuX19Nb25rZXlDb25maWdfY29udGFpbmVyIGlucHV0LFwKZGl2Ll9fTW9ua2V5Q29uZmlnX2xheWVyIGRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIgc2VsZWN0LFwKZGl2Ll9fTW9ua2V5Q29uZmlnX2xheWVyIGRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIgdGV4dGFyZWEsXApkaXYuX19Nb25rZXlDb25maWdfbGF5ZXIgZGl2Ll9fTW9ua2V5Q29uZmlnX2NvbnRhaW5lciBidXR0b24ge1wKICAgIGNvbG9yOiAjMDAwICFpbXBvcnRhbnQ7XAogICAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWYgIWltcG9ydGFudDtcCiAgICBmb250LXNpemU6IDExcHQgIWltcG9ydGFudDtcCiAgICBsaW5lLWhlaWdodDogMTAwJSAhaW1wb3J0YW50O1wKICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1wKICAgIHZlcnRpY2FsLWFsaWduOiBiYXNlbGluZSAhaW1wb3J0YW50O1wKfVwKXApkaXYuX19Nb25rZXlDb25maWdfY29udGFpbmVyIGxhYmVsIHtcCiAgICBsaW5lLWhlaWdodDogMTIwJSAhaW1wb3J0YW50O1wKICAgIHZlcnRpY2FsLWFsaWduOiBiYXNlbGluZSAhaW1wb3J0YW50O1wKfVwKXApkaXYuX19Nb25rZXlDb25maWdfY29udGFpbmVyIHRleHRhcmVhIHtcCiAgICB2ZXJ0aWNhbC1hbGlnbjogdGV4dC10b3AgIWltcG9ydGFudDtcCiAgICB3aWR0aDogMTAwJTtcCn1cClwKZGl2Ll9fTW9ua2V5Q29uZmlnX2xheWVyIGRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIgaW5wdXRbdHlwZT0idGV4dCJdIHtcCiAgICBhcHBlYXJhbmNlOiB0ZXh0ZmllbGQgIWltcG9ydGFudDtcCiAgICAtbW96LWFwcGVhcmFuY2U6IHRleHRmaWVsZCAhaW1wb3J0YW50O1wKICAgIGJhY2tncm91bmQ6ICNmZmYgIWltcG9ydGFudDtcCn1cClwKZGl2Ll9fTW9ua2V5Q29uZmlnX2xheWVyIGRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIgaDEge1wKICAgIGZvbnQtd2VpZ2h0OiBib2xkICFpbXBvcnRhbnQ7XAogICAgdGV4dC1hbGlnbjogbGVmdCAhaW1wb3J0YW50O1wKfVwKXApkaXYuX19Nb25rZXlDb25maWdfbGF5ZXIgZGl2Ll9fTW9ua2V5Q29uZmlnX2NvbnRhaW5lciB0ZC5fX01vbmtleUNvbmZpZ19idXR0b25zIGJ1dHRvbixcCmJvZHkgPiBkaXYuX19Nb25rZXlDb25maWdfY29udGFpbmVyIHRkLl9fTW9ua2V5Q29uZmlnX2J1dHRvbnMgYnV0dG9uIHtcCiAgICBhcHBlYXJhbmNlOiBidXR0b24gIWltcG9ydGFudDtcCiAgICAtbW96LWFwcGVhcmFuY2U6IGJ1dHRvbiAhaW1wb3J0YW50O1wKICAgIGJhY2tncm91bmQ6ICNjY2MgbGluZWFyLWdyYWRpZW50KDE4MGRlZyxcCiAgICAgICAgI2RkZCAwLCAjY2NjIDQ1JSwgI2JiYiA1MCUsICNhYWEgMTAwJSkgIWltcG9ydGFudDtcCiAgICBib3JkZXItc3R5bGU6IHNvbGlkICFpbXBvcnRhbnQ7XAogICAgYm9yZGVyLXdpZHRoOiAxcHggIWltcG9ydGFudDtcCiAgICBib3JkZXItcmFkaXVzOiAwLjVlbSAhaW1wb3J0YW50O1wKICAgIGJveC1zaGFkb3c6IDAgMCAxcHggIzAwMCAhaW1wb3J0YW50O1wKICAgIGNvbG9yOiAjMDAwICFpbXBvcnRhbnQ7XAogICAgZm9udC1zaXplOiAxMXB0ICFpbXBvcnRhbnQ7XAp9XApcCmRpdi5fX01vbmtleUNvbmZpZ19sYXllciBkaXYuX19Nb25rZXlDb25maWdfY29udGFpbmVyIHRkLl9fTW9ua2V5Q29uZmlnX2J1dHRvbnMgYnV0dG9uOmhvdmVyLFwKYm9keSA+IGRpdi5fX01vbmtleUNvbmZpZ19jb250YWluZXIgdGQuX19Nb25rZXlDb25maWdfYnV0dG9ucyBidXR0b246aG92ZXIge1wKICAgIGJhY2tncm91bmQ6ICNkMmQyZDIgbGluZWFyLWdyYWRpZW50KDE4MGRlZyxcCiAgICAgICAgI2UyZTJlMiAwLCAjZDJkMmQyIDQ1JSwgI2MyYzJjMiA1MCUsICNiMmIyYjIgMTAwJSkgIWltcG9ydGFudDtcCn1cClwKZGl2Ll9fTW9ua2V5Q29uZmlnX292ZXJsYXkge1wKICAgIGJhY2tncm91bmQtY29sb3I6ICMwMDAgIWltcG9ydGFudDtcCiAgICBvcGFjaXR5OiAwLjYgIWltcG9ydGFudDtcCiAgICBwb3NpdGlvbjogZml4ZWQgIWltcG9ydGFudDtcCn1cClwKaWZyYW1lI19fTW9ua2V5Q29uZmlnX2ZyYW1lIHtcCiAgICBib3JkZXI6IG5vbmUgIWltcG9ydGFudDtcCiAgICBib3gtc2hhZG93OiAycHggMnB4IDE2cHggIzAwMCAhaW1wb3J0YW50O1wKfVwKXApib2R5Ll9fTW9ua2V5Q29uZmlnX2JvZHkge1wKICAgIG1hcmdpbjogMCAhaW1wb3J0YW50O1wKICAgIHBhZGRpbmc6IDAgIWltcG9ydGFudDtcCn1cCicKfTs="}]},{"name":"Password Revealer","options":{"check_for_updates":true,"comment":null,"compat_foreach":false,"compat_metadata":false,"compat_powerful_this":null,"compat_wrappedjsobject":false,"compatopts_for_requires":true,"noframes":null,"override":{"merge_connects":true,"merge_excludes":true,"merge_includes":true,"merge_matches":true,"orig_connects":[],"orig_excludes":["file:///*/perf.html*"],"orig_includes":["http://*","https://*","file:///*"],"orig_matches":[],"orig_noframes":null,"orig_run_at":"document-idle","use_blockers":[],"use_connects":[],"use_excludes":[],"use_includes":[],"use_matches":[]},"run_at":null,"sandbox":null,"tab_types":null,"unwrap":null,"user_modified":null},"storage":{"ts":1691113794673,"data":{}},"enabled":true,"position":4,"file_url":"https://greasyfork.org/scripts/2175-password-revealer/code/Password%20Revealer.user.js","uuid":"c12488c6-3f38-409b-8c43-6737f44e1950","source":"Ly8gPT1Vc2VyU2NyaXB0PT0KLy8gQG5hbWUgICAgICAgICAgIFBhc3N3b3JkIFJldmVhbGVyCi8vIEBuYW1lc3BhY2UgICAgICBodHRwOi8vdXNlcnNjcmlwdHMub3JnL3VzZXJzLzIzNjUyCi8vIEBkZXNjcmlwdGlvbiAgICBTaG93cyBwYXNzd29yZHMgb24gbW91c2UgaG92ZXIgb3IgZm9jdXMKLy8gQGluY2x1ZGUgICAgICAgIGh0dHA6Ly8qCi8vIEBpbmNsdWRlICAgICAgICBodHRwczovLyoKLy8gQGluY2x1ZGUgICAgICAgIGZpbGU6Ly8vKgovLyBAZXhjbHVkZSAgICAgICAgZmlsZTovLy8qL3BlcmYuaHRtbCoKLy8gQGNvcHlyaWdodCAgICAgIEpvZVNpbW1vbnMKLy8gQHZlcnNpb24gICAgICAgIDEuMC41MQovLyBAbGljZW5zZSAgICAgICAgR1BMIHZlcnNpb24gMyBvciBhbnkgbGF0ZXIgdmVyc2lvbjsgaHR0cDovL3d3dy5nbnUub3JnL2NvcHlsZWZ0L2dwbC5odG1sCi8vID09L1VzZXJTY3JpcHQ9PQooZnVuY3Rpb24oKSB7CgoKCgogICAgdmFyIHNob3dfb25seV9vbl9jbGljayA9IGZhbHNlOyAvLyBvbmx5IHNob3cgcGFzc3dvcmRzIHdoZW4geW91IGNsaWNrIG9uIHRoZSBmaWVsZAoKCgoKCiAgICB2YXIgaGFuZGxlcnMgPSBbXTsKCiAgICBmdW5jdGlvbiB0b1RleHQoZSkgewogICAgICAgIGUgPSBlLnRhcmdldDsKCiAgICAgICAgaWYgKGUudGFnTmFtZSA9PT0gJ0lOUFVUJyAmJiBlLnR5cGUgPT09ICdwYXNzd29yZCcpIHsKICAgICAgICAgICAgLy8gc2F2ZSB0aGUgY3Vyc29yIHBvc2l0aW9uCiAgICAgICAgICAgIGUuY2FyZXRTdGFydCA9IGUuc2VsZWN0aW9uU3RhcnQ7CiAgICAgICAgICAgIGUuY2FyZXRFbmQgPSBlLnNlbGVjdGlvbkVuZDsKCiAgICAgICAgICAgIC8vIHN3aXRjaCBpdCB0byB0ZXh0LCBidXQgbWFrZSBpdCByZW1lbWJlciBpdCB3YXMgYSBwYXNzd29yZCB0eXBlCiAgICAgICAgICAgIGUudHlwZSA9ICd0ZXh0JzsKICAgICAgICAgICAgZS5vbGRUeXBlID0gJ3Bhc3N3b3JkJzsKCiAgICAgICAgICAgIC8vIHRoZSBzZWxlY3Rpb24gcmFuZ2UgZ2V0cyByZXNldCB3aGVuIHdlIHN3aXRjaCBpdHMgdHlwZSwgc28gbGV0J3MgZml4IGl0CiAgICAgICAgICAgIGUuc2V0U2VsZWN0aW9uUmFuZ2UoZS5jYXJldFN0YXJ0LCBlLmNhcmV0RW5kKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gdG9QYXNzd29yZChlKSB7CiAgICAgICAgZSA9IGUudGFyZ2V0OwoKICAgICAgICBpZiAoZS50YWdOYW1lID09PSAnSU5QVVQnICYmIGUub2xkVHlwZSA9PT0gJ3Bhc3N3b3JkJykgewogICAgICAgICAgICAvLyBzYXZlIHRoZSBjdXJzb3IgcG9zaXRpb24KICAgICAgICAgICAgZS5jYXJldFN0YXJ0ID0gZS5zZWxlY3Rpb25TdGFydDsKICAgICAgICAgICAgZS5jYXJldEVuZCA9IGUuc2VsZWN0aW9uRW5kOwoKICAgICAgICAgICAgLy8gc3dpdGNoIGl0IHRvIGEgcGFzc3dvcmQgZmllbGQKICAgICAgICAgICAgZS50eXBlID0gJ3Bhc3N3b3JkJzsKCiAgICAgICAgICAgIC8vIHRoZSBzZWxlY3Rpb24gcmFuZ2UgZ2V0cyByZXNldCB3aGVuIHdlIHN3aXRjaCBpdHMgdHlwZSwgc28gbGV0J3MgZml4IGl0CiAgICAgICAgICAgIGUuc2V0U2VsZWN0aW9uUmFuZ2UoZS5jYXJldFN0YXJ0LCBlLmNhcmV0RW5kKTsKICAgICAgICAgICAgZS5zZXRTZWxlY3Rpb25SYW5nZShlLmNhcmV0U3RhcnQsIGUuY2FyZXRFbmQpOwoKICAgICAgICAgICAgLy8gbGV0J3MgY2xlYW4gdXAgb3VyIG5vdy11bnVzZWQgcHJvcGVydGllcwogICAgICAgICAgICBkZWxldGUgZS5jYXJldFN0YXJ0OwogICAgICAgICAgICBkZWxldGUgZS5jYXJldEVuZDsKICAgICAgICAgICAgZGVsZXRlIGUub2xkVHlwZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gYWRkSGFuZGxlcnMoKSB7CiAgICAgICAgdmFyIGZpZWxkcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W3R5cGU9InBhc3N3b3JkIl0nKSwgaSwgZmllbGQ7CgogICAgICAgIGZvciAoaSA9IDA7IGZpZWxkID0gZmllbGRzW2ldOyBpICs9IDEpIHsKICAgICAgICAgICAgaWYgKGhhbmRsZXJzLmluZGV4T2YoZmllbGQpID09PSAtMSkgewogICAgICAgICAgICAgICAgZmllbGQuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCB0b1RleHQsIGZhbHNlKTsKICAgICAgICAgICAgICAgIGZpZWxkLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCB0b1Bhc3N3b3JkLCBmYWxzZSk7CiAgICAgICAgICAgICAgICBoYW5kbGVycy5wdXNoKGZpZWxkKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAoc2hvd19vbmx5X29uX2NsaWNrID09PSBmYWxzZSkgewogICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW92ZXInLCB0b1RleHQsIGZhbHNlKTsKICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdXQnLCB0b1Bhc3N3b3JkLCBmYWxzZSk7CiAgICB9IGVsc2UgewogICAgICAgIHdpbmRvdy5zZXRJbnRlcnZhbChhZGRIYW5kbGVycywgMTAwMCk7CiAgICB9Cgp9KCkpOw=="},{"name":"Local YouTube Downloader","options":{"check_for_updates":true,"comment":null,"compat_foreach":false,"compat_metadata":false,"compat_powerful_this":null,"compat_wrappedjsobject":false,"compatopts_for_requires":true,"noframes":null,"override":{"merge_connects":true,"merge_excludes":true,"merge_includes":true,"merge_matches":true,"orig_connects":["googlevideo.com"],"orig_excludes":[],"orig_includes":[],"orig_matches":["https://*.youtube.com/*"],"orig_noframes":null,"orig_run_at":"document-end","use_blockers":[],"use_connects":[],"use_excludes":[],"use_includes":[],"use_matches":[]},"run_at":null,"sandbox":null,"tab_types":null,"unwrap":null,"user_modified":null},"storage":{"ts":1691113794688,"data":{"tampermonkey_breaks_should_alert":"bfalse"}},"enabled":false,"position":5,"file_url":"https://greasyfork.org/scripts/369400-local-youtube-downloader/code/Local%20YouTube%20Downloader.user.js","uuid":"f727efe8-eb66-4ac1-9a20-5352aabc247f","source":"Ly8gPT1Vc2VyU2NyaXB0PT0KLy8gQG5hbWUgICAgICAgICBMb2NhbCBZb3VUdWJlIERvd25sb2FkZXIKLy8gQG5hbWU6emgtVFcgICDmnKzlnLAgWW91VHViZSDkuIvovInlmagKLy8gQG5hbWU6emgtSEsgICDmnKzlnLAgWW91VHViZSDkuIvovInlmagKLy8gQG5hbWU6emgtQ04gICDmnKzlnLAgWW91VHViZSDkuIvovb3lmagKLy8gQG5hbWU6amEgICAgICDjg63jg7zjgqvjg6sgWW91VHViZSDjg4Djgqbjg7Pjg63jg7zjg4Djg7wKLy8gQG5hbWU6a3IgICAgICDroZzsu6wgWW91VHViZSDri6TsmrTroZzrjZQKLy8gQG5hbWVzcGFjZSAgICBodHRwczovL2Jsb2cubWFwbGUzMTQyLm5ldC8KLy8gQHZlcnNpb24gICAgICAwLjkuNTQKLy8gQGRlc2NyaXB0aW9uICAgICAgICBEb3dubG9hZCBZb3VUdWJlIHZpZGVvcyB3aXRob3V0IGV4dGVybmFsIHNlcnZpY2UuCi8vIEBkZXNjcmlwdGlvbjp6aC1UVyAg5LiN6ZyA6YCP6YGO56ys5LiJ5pa55pyN5YuZ5Y2z5Y+v5LiL6LyJIFlvdVR1YmUg5b2x54mH44CCCi8vIEBkZXNjcmlwdGlvbjp6aC1ISyAg5LiN6ZyA6YCP6YGO56ys5LiJ5pa55pyN5YuZ5Y2z5Y+v5LiL6LyJIFlvdVR1YmUg5b2x54mH44CCCi8vIEBkZXNjcmlwdGlvbjp6aC1DTiAg5LiN6ZyA6KaB6YCP6L+H56ys5LiJ5pa555qE5pyN5Yqh5bCx6IO95LiL6L29IFlvdVR1YmUg6KeG6aKR44CCCi8vIEBkZXNjcmlwdGlvbjpqYSAgICAg5aSW6YOo44K144O844OT44K544Gq44GX44GnIFlvdVR1YmUg5YuV55S744KS44OA44Km44Oz44Ot44O844OJCi8vIEBkZXNjcmlwdGlvbjprciAgICAg7Jm467aAIOyEnOu5hOyKpOyXhuydtCBZb3VUdWJlIOuPmeyYgeyDgeydhCDri6TsmrTroZzrk5wKLy8gQGRlc2NyaXB0aW9uOmZyICAgICBPYnRlbmV6IHVuIGxpZW4gYnJ1dCBZb3VUdWJlIHNhbnMgc2VydmljZSBleHRlcm5lLgovLyBAZGVzY3JpcHRpb246Y3MgICAgIFN0YWh1anRlIFlvdVR1YmUgdmlkZWEgYmV6IGV4dGVybsOtY2ggc2x1xb5lYi4KLy8gQGF1dGhvciAgICAgICBtYXBsZTMxNDIKLy8gQG1hdGNoICAgICAgICBodHRwczovLyoueW91dHViZS5jb20vKgovLyBAcmVxdWlyZSAgICAgIGh0dHBzOi8vdW5wa2cuY29tL3Z1ZUAyLjYuMTAvZGlzdC92dWUuanMKLy8gQHJlcXVpcmUgICAgICBodHRwczovL3VucGtnLmNvbS94ZmV0Y2gtanNAMC4zLjQveGZldGNoLm1pbi5qcwovLyBAcmVxdWlyZSAgICAgIGh0dHBzOi8vdW5wa2cuY29tL0BmZm1wZWcvZmZtcGVnQDAuNi4xL2Rpc3QvZmZtcGVnLm1pbi5qcwovLyBAcmVxdWlyZSAgICAgIGh0dHBzOi8vYnVuZGxlLnJ1bi9wLXF1ZXVlQDYuMy4wCi8vIEBncmFudCAgICAgICAgR01feG1saHR0cFJlcXVlc3QKLy8gQGdyYW50ICAgICAgICBHTV9pbmZvCi8vIEBncmFudCAgICAgICAgR01fc2V0VmFsdWUKLy8gQGdyYW50ICAgICAgICBHTV9nZXRWYWx1ZQovLyBAZ3JhbnQgICAgICAgIHVuc2FmZVdpbmRvdwovLyBAcnVuLWF0ICAgICAgIGRvY3VtZW50LWVuZAovLyBAY29ubmVjdCAgICAgIGdvb2dsZXZpZGVvLmNvbQovLyBAY29tcGF0aWJsZSAgIGZpcmVmb3ggPj01MgovLyBAY29tcGF0aWJsZSAgIGNocm9tZSA+PTU1Ci8vIEBsaWNlbnNlICAgICAgTUlUCi8vID09L1VzZXJTY3JpcHQ9PQoKOyhmdW5jdGlvbiAoKSB7CgkndXNlIHN0cmljdCcKCWlmICgKCQl3aW5kb3cudG9wID09PSB3aW5kb3cuc2VsZiAmJgoJCUdNX2luZm8uc2NyaXB0SGFuZGxlciA9PT0gJ1RhbXBlcm1vbmtleScgJiYKCQlHTV9pbmZvLnZlcnNpb24gPT09ICc0LjE4LjAnICYmCgkJR01fZ2V0VmFsdWUoJ3RhbXBlcm1vbmtleV9icmVha3Nfc2hvdWxkX2FsZXJ0JywgdHJ1ZSkKCSkgewoJCWFsZXJ0KAoJCQlgVGFtcGVybW9ua2V5IHJlY2VudGx5IHJlbGVhc2UgYSBicmVha2luZyBjaGFuZ2UgLyBidWcgaW4gdmVyc2lvbiA0LjE4LjAgdGhhdCBicmVha3MgdGhpcyBzY3JpcHQsIHdoaWNoIGlzIGZpeGVkIGluIG5ld2VyIHZlcnNpb24gb2YgVGFtcGVybW9ua2V5IHJpZ2h0IG5vdy4gWW91IHNob3VsZCB1cGRhdGUgaXQgb3Igc3dpdGNoIHRvIFZpb2xlbnRtb25rZXkgaW5zdGVhZC5gCgkJKQoJCUdNX3NldFZhbHVlKCd0YW1wZXJtb25rZXlfYnJlYWtzX3Nob3VsZF9hbGVydCcsIGZhbHNlKQoJfQoJY29uc3QgREVCVUcgPSB0cnVlCgljb25zdCBjcmVhdGVMb2dnZXIgPSAoY29uc29sZSwgdGFnKSA9PgoJCU9iamVjdC5rZXlzKGNvbnNvbGUpCgkJCS5tYXAoayA9PiBbaywgKC4uLmFyZ3MpID0+IChERUJVRyA/IGNvbnNvbGVba10odGFnICsgJzogJyArIGFyZ3NbMF0sIC4uLmFyZ3Muc2xpY2UoMSkpIDogdm9pZCAwKV0pCgkJCS5yZWR1Y2UoKGFjYywgW2ssIGZuXSkgPT4gKChhY2Nba10gPSBmbiksIGFjYyksIHt9KQoJY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKGNvbnNvbGUsICdZVERMJykKCWNvbnN0IHNsZWVwID0gbXMgPT4gbmV3IFByb21pc2UocmVzID0+IHNldFRpbWVvdXQocmVzLCBtcykpCgoJY29uc3QgTEFOR19GQUxMQkFDSyA9ICdlbicKCWNvbnN0IExPQ0FMRSA9IHsKCQllbjogewoJCQl0b2dnbGVsaW5rczogJ1Nob3cvSGlkZSBMaW5rcycsCgkJCXN0cmVhbTogJ1N0cmVhbScsCgkJCWFkYXB0aXZlOiAnQWRhcHRpdmUgKE5vIFNvdW5kKScsCgkJCXZpZGVvaWQ6ICdWaWRlbyBJRDogJywKCQkJaW5icm93c2VyX2FkYXB0aXZlX21lcmdlcjogJ09ubGluZSBBZGFwdGl2ZSBWaWRlbyAmIEF1ZGlvIE1lcmdlciAoRkZtcGVnKScsCgkJCWRsbXA0OiAnRG93bmxvYWQgaGlnaC1yZXNvbHV0aW9uIG1wNCBpbiBvbmUgY2xpY2snLAoJCQlnZXRfdmlkZW9fZmFpbGVkOiAnRmFpbGVkIHRvIGdldCB2aWRlbyBpbmZvbWF0aW9uIGZvciB1bmtub3duIHJlYXNvbiwgcmVmcmVzaCB0aGUgcGFnZSBtYXkgd29yay4nLAoJCQlsaXZlX3N0cmVhbV9kaXNhYmxlZF9tZXNzYWdlOiAnTG9jYWwgWW91VHViZSBEb3dubG9hZGVyIGlzIG5vdCBhdmFpbGFibGUgZm9yIGxpdmUgc3RyZWFtJwoJCX0sCgkJJ3poLXR3JzogewoJCQl0b2dnbGVsaW5rczogJ+mhr+ekuiAvIOmaseiXj+mAo+e1kCcsCgkJCXN0cmVhbTogJ+S4sua1gSBTdHJlYW0nLAoJCQlhZGFwdGl2ZTogJ+iHqumBqeaHiSBBZGFwdGl2ZSAo5rKS5pyJ6IGy6Z+zKScsCgkJCXZpZGVvaWQ6ICflvbHniYcgSUQ6ICcsCgkJCWluYnJvd3Nlcl9hZGFwdGl2ZV9tZXJnZXI6ICfnt5rkuIroh6rpganmh4nlvbHniYflj4rpn7PoqIrlkIjmiJDlt6XlhbcgKEZGbXBlZyknLAoJCQlkbG1wNDogJ+S4gOmNteS4i+i8iemrmOeVq+izqiBtcDQnLAoJCQlnZXRfdmlkZW9fZmFpbGVkOiAn54Sh5rOV5Y+W5b6X5b2x54mH6LOH6KiK77yM6YeN5paw5pW055CG6aCB6Z2i5Y+v6IO95pyD5pyJ5pWI5p6c44CCJywKCQkJbGl2ZV9zdHJlYW1fZGlzYWJsZWRfbWVzc2FnZTogJ+WboOeCuuaYr+ebtOaSreeahOe3o+aVhe+8jOacrOWcsCBZb3VUdWJlIOS4i+i8ieWZqOeahOWKn+iDveaYr+WBnOeUqOeahOOAgicKCQl9LAoJCSd6aC1oayc6IHsKCQkJdG9nZ2xlbGlua3M6ICfpoa/npLrvvI/pmrHol4/pgKPntZAnLAoJCQlzdHJlYW06ICfkuLLmtYEgU3RyZWFtJywKCQkJYWRhcHRpdmU6ICfoh6rli5Xpganmh4kgQWRhcHRpdmUgKOaykuacieiBsumfsyknLAoJCQl2aWRlb2lkOiAn5b2x54mHIElEOiAnLAoJCQlpbmJyb3dzZXJfYWRhcHRpdmVfbWVyZ2VyOiAn57ay5LiK6Ieq5YuV6YGp5oeJ5b2x54mH5Y+K6Z+z6KiK5ZCI5oiQ5bel5YW3IChGRm1wZWcpJywKCQkJZGxtcDQ6ICfkuIDigIljbGlja+KAieS4i+i8iemrmOeVq+izqiBtcDQnLAoJCQlnZXRfdmlkZW9fZmFpbGVkOiAn54Sh5rOV5Y+W5b6X5b2x54mH6LOH6KiK77yM6YeN5paw5pW055CG6aCB6Z2i5Y+v6IO95pyD5pyJ5pWI5p6c44CCJywKCQkJbGl2ZV9zdHJlYW1fZGlzYWJsZWRfbWVzc2FnZTogJ+acrOWcsCBZb3VUdWJlIOS4i+i8ieWZqOeEoeazleeUqOaWvOebtOaSreOAgicKCQl9LAoJCXpoOiB7CgkJCXRvZ2dsZWxpbmtzOiAn5pi+56S677yP6ZqQ6JeP6ZO+5o6lJywKCQkJc3RyZWFtOiAn5Liy5rWBIFN0cmVhbScsCgkJCWFkYXB0aXZlOiAn6Ieq6YCC5bqUIEFkYXB0aXZlICjmsqHmnInlo7Dpn7MpJywKCQkJdmlkZW9pZDogJ+inhumikSBJRDogJywKCQkJaW5icm93c2VyX2FkYXB0aXZlX21lcmdlcjogJ+e6v+S4iuiHqumAguW6lOinhumikeWPiumfs+mikeWQiOaIkOW3peWFtyAoRkZtcGVnKScsCgkJCWRsbXA0OiAn5LiA6ZSu5LiL6L296auY55S76LSoIG1wNCcsCgkJCWdldF92aWRlb19mYWlsZWQ6ICfml6Dms5Xlj5blvpflvbHniYfotYTorq/vvIzph43mlrDmlbTnkIbpobXpnaLlj6/og73kvJrmnInmlYjmnpzjgIInLAoJCQlsaXZlX3N0cmVhbV9kaXNhYmxlZF9tZXNzYWdlOiAn5Zug5Li65piv55u05pKt77yM5pys5ZywIFlvdVR1YmUg5LiL6L295Zmo55qE5Yqf6IO95bey6KKr56aB55So44CCJwoJCX0sCgkJamE6IHsKCQkJdG9nZ2xlbGlua3M6ICfjg6rjg7Pjgq/ooajnpLrjg7vpnZ7ooajnpLonLAoJCQlzdHJlYW06ICfjgrnjg4jjg6rjg7zjg5/jg7PjgrAnLAoJCQlhZGFwdGl2ZTogJ+OCouODgOODl+ODhuOCo+ODlu+8iOmfs+eEoeOBl++8iScsCgkJCXZpZGVvaWQ6ICfjg5Pjg4fjgqogSUQ6ICcsCgkJCWluYnJvd3Nlcl9hZGFwdGl2ZV9tZXJnZXI6ICfjg5Pjg4fjgqrjgajjgqrjg7zjg4fjgqPjgqrjgpLlkIjkvbXjgZnjgovjgqrjg7Pjg6njgqTjg7Pjg4Tjg7zjg6sgKEZGbXBlZyknLAoJCQlkbG1wNDogJ+ODr+ODs+OCr+ODquODg+OCr+OBp+mrmOino+WDj+W6puOBriBtcDQg44KS44OA44Km44Oz44Ot44O844OJJywKCQkJbGl2ZV9zdHJlYW1fZGlzYWJsZWRfbWVzc2FnZTogJ+ODqeOCpOODlumFjeS/oeOBruOBn+OCgeOAgeODreODvOOCq+ODqyBZb3VUdWJlIOODgOOCpuODs+ODreODvOODgOODvOOBr+eEoeWKueOBq+OBquOBo+OBpuOBhOOBvuOBmeOAgicKCQl9LAoJCWtyOiB7CgkJCXRvZ2dsZWxpbmtzOiAn66eB7YGsIOuztOydtOq4sCDCtyDsiKjquLDquLAnLAoJCQlzdHJlYW06ICfsiqTtirjrpqzrsI0nLAoJCQlhZGFwdGl2ZTogJ+yggeydkSAo7Ja064yR7Yuw67iMKScsCgkJCXZpZGVvaWQ6ICfruYTrlJTsmKQgSUQ6ICcsCgkJCWluYnJvd3Nlcl9hZGFwdGl2ZV9tZXJnZXI6ICfruYTrlJTsmKTsmYAg7Jik65SU7Jik66W8IO2Vqeuzke2VmOuKlCDsmKjrnbzsnbgg64+E6rWsIChGRm1wZWcpJywKCQkJZGxtcDQ6ICftlZwg67KI7J2YIO2BtOumreycvOuhnCDqs6DtlbTsg4Hrj4QgbXA0IOuLpOyatOuhnOuTnCcKCQl9LAoJCWVzOiB7CgkJCXRvZ2dsZWxpbmtzOiAnTW9zdHJhci9PY3VsdGFyIExpbmtzJywKCQkJc3RyZWFtOiAnU3RyZWFtJywKCQkJYWRhcHRpdmU6ICdBZGFwdGFibGUnLAoJCQl2aWRlb2lkOiAnSWQgZGVsIFZpZGVvOiAnLAoJCQlpbmJyb3dzZXJfYWRhcHRpdmVfbWVyZ2VyOiAnQWNvcGxhciBBdWRpbyBhIFZpZGVvIChGRm1wZWcpJwoJCX0sCgkJaGU6IHsKCQkJdG9nZ2xlbGlua3M6ICfXlNem15Iv15TXodeq16gg16fXmdep15XXqNeZ150nLAoJCQlzdHJlYW06ICfXodeY16jXmdedJywKCQkJYWRhcHRpdmU6ICfXkNeT16TXmNeZ15HXmScsCgkJCXZpZGVvaWQ6ICfXnteW15TXlCDXodeo15jXldefOiAnCgkJfSwKCQlmcjogewoJCQl0b2dnbGVsaW5rczogJ0FmZmljaGVyL01hc3F1ZXIgbGVzIGxpZW5zJywKCQkJc3RyZWFtOiAnU3RyZWFtJywKCQkJYWRhcHRpdmU6ICdBZGFwdGF0aXZlJywKCQkJdmlkZW9pZDogJ0lEIHZpZMOpbzogJywKCQkJaW5icm93c2VyX2FkYXB0aXZlX21lcmdlcjogJ0Z1c2lvbm5lciB2aWTDqW9zIGV0IGF1ZGlvcyBhZGFwdGF0aWZzIGRhbnMgbGUgbmF2aWdhdGV1ciAoRkZtcGVnKScsCgkJCWRsbXA0OiAnVMOpbMOpY2hhcmdleiBsYSBwbHVzIGhhdXRlIHLDqXNvbHV0aW9uIG1wNCBlbiB1biBjbGljJwoJCX0sCgkJcGw6IHsKCQkJdG9nZ2xlbGlua3M6ICdQb2thxbwvVWtyeWogTGlua2knLAoJCQlzdHJlYW06ICdTdHJlYW0nLAoJCQlhZGFwdGl2ZTogJ0FkYXB0eXduZScsCgkJCXZpZGVvaWQ6ICdJRCBmaWxtdTogJywKCQkJaW5icm93c2VyX2FkYXB0aXZlX21lcmdlcjogJ1BvxYLEhWN6IGF1ZGlvIGkgd2lkZW8gYWRhcHR5d25lIHcgcHJ6ZWdsxIVkYXJjZSAoRkZtcGVnKScsCgkJCWRsbXA0OiAnUG9iaWVyeiAubXA0IHcgbmFqd3nFvHN6ZWogamFrb8WbY2knCgkJfSwKCQloaTogewoJCQl0b2dnbGVsaW5rczogJ+CksuCkv+CkguCklSDgpJ/gpYngpJfgpLIg4KSV4KSw4KWH4KSCJywKCQkJc3RyZWFtOiAn4KS44KWN4KSf4KWN4KSw4KWA4KSu4KS/4KSC4KSXIChTdHJlYW0pJywKCQkJYWRhcHRpdmU6ICfgpIXgpKjgpYHgpJXgpYLgpLLgpYAgKEFkYXB0aXZlKScsCgkJCXZpZGVvaWQ6ICfgpLXgpYDgpKHgpL/gpK/gpYsg4KSG4KSI4KSh4KWAOiB7e2lkfX0nCgkJfSwKCQlydTogewoJCQl0b2dnbGVsaW5rczogJ9Cf0L7QutCw0LfQsNGC0YwvQ9C60YDRi9GC0Ywg0YHRgdGL0LvQutC4JywKCQkJc3RyZWFtOiAn0J/QvtGC0L7QuicsCgkJCWFkYXB0aXZlOiAn0JDQtNCw0L/RgtC40LLQvdGL0LknLAoJCQl2aWRlb2lkOiAn0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0LLQuNC00LXQvjogJywKCQkJaW5icm93c2VyX2FkYXB0aXZlX21lcmdlcjogJ9CQ0LTQsNC/0YLQuNCy0L3QvtC1INGB0LvQuNGP0L3QuNC1INCy0LjQtNC10L4g0Lgg0LDRg9C00LjQviDQvtC90LvQsNC50L0gKEZGbXBlZyknLAoJCQlkbG1wNDogJ9Ch0LrQsNGH0LDRgtGMIG1wNCDQsiDQstGL0YHQvtC60L7QvCDRgNCw0LfRgNC10YjQtdC90LjQuCDQsiDQvtC00LjQvSDQutC70LjQuicsCgkJCWdldF92aWRlb19mYWlsZWQ6CgkJCQkn0J3QtSDRg9C00LDQu9C+0YHRjCDQv9C+0LvRg9GH0LjRgtGMINC40L3RhNC+0YDQvNCw0YbQuNGOINC+INCy0LjQtNC10L4g0L/QviDQvdC10LjQt9Cy0LXRgdGC0L3QvtC5INC/0YDQuNGH0LjQvdC1LCDQv9C+0L/RgNC+0LHRg9C50YLQtSDQvtCx0L3QvtCy0LjRgtGMINGB0YLRgNCw0L3QuNGG0YMuJywKCQkJbGl2ZV9zdHJlYW1fZGlzYWJsZWRfbWVzc2FnZTogJ9Cb0L7QutCw0LvRjNC90YvQuSDQt9Cw0LPRgNGD0LfRh9C40LogWW91VHViZSDQvdC10LTQvtGB0YLRg9C/0LXQvSDQtNC70Y8g0L/RgNGP0LzQvtC5INGC0YDQsNC90YHQu9GP0YbQuNC4JwoJCX0sCgkJdWE6IHsKCQkJdG9nZ2xlbGlua3M6ICfQn9C+0LrQsNC30LDRgtC4L9Cf0YDQuNGF0L7QstCw0YLQuCDQv9C+0YHQuNC70LDQvdC90Y8nLAoJCQlzdHJlYW06ICfQn9C+0YLRltC6JywKCQkJYWRhcHRpdmU6ICfQkNC00LDQv9GC0LjQstC90LjQuScsCgkJCXZpZGVvaWQ6ICfQhtC00LXQvdGC0LjRhNGW0LrQsNGC0L7RgCDQstGW0LTQtdC+OiAnLAoJCQlpbmJyb3dzZXJfYWRhcHRpdmVfbWVyZ2VyOiAn0JDQtNCw0L/RgtC40LLQvdC1INC30LvQuNGC0YLRjyDQstGW0LTQtdC+INGWINCw0YPQtNGW0L4g0L7QvdC70LDQudC9IChGRm1wZWcpJywKCQkJZGxtcDQ6ICfQl9Cw0LLQsNC90YLQsNC20LjRgtC4IG1wNCDRgyDQstC40YHQvtC60ZbQuSDRgNC+0LfQtNGW0LvRjNC90ZbQuSDQt9C00LDRgtC90L7RgdGC0ZYg0LIg0L7QtNC40L0g0LrQu9GW0LonLAoJCQlnZXRfdmlkZW9fZmFpbGVkOgoJCQkJJ9Cd0LUg0LLQtNCw0LvQvtGB0Y8g0L7RgtGA0LjQvNCw0YLQuCDRltC90YTQvtGA0LzQsNGG0ZbRjiDQv9GA0L4g0LLRltC00LXQviDQtyDQvdC10LLRltC00L7QvNC+0Zcg0L/RgNC40YfQuNC90LgsINGB0L/RgNC+0LHRg9C50YLQtSDQvtC90L7QstC40YLQuCDRgdGC0L7RgNGW0L3QutGDLicsCgkJCWxpdmVfc3RyZWFtX2Rpc2FibGVkX21lc3NhZ2U6ICfQm9C+0LrQsNC70YzQvdC40Lkg0LfQsNCy0LDQvdGC0LDQttGD0LLQsNGHIFlvdVR1YmUg0L3QtdC00L7RgdGC0YPQv9C90LjQuSDQtNC70Y8g0L/RgNGP0LzQvtGXINGC0YDQsNC90YHQu9GP0YbRltGXJwoJCX0sCgkJY3M6IHsKCQkJdG9nZ2xlbGlua3M6ICdab2JyYXppdC9Ta3LDvXQgb2RrYXp5JywKCQkJc3RyZWFtOiAnU3RyZWFtJywKCQkJYWRhcHRpdmU6ICdBZGFwdGl2bsOtJywKCQkJdmlkZW9pZDogJ0lEIHZpZGVhOiAnLAoJCQlpbmJyb3dzZXJfYWRhcHRpdmVfbWVyZ2VyOiAnT25saW5lIG7DoXN0cm9qIHBybyBzbG91xI1lbsOtIHZpZGVhIGEgYXVkaWEgKEZGbXBlZyknLAoJCQlkbG1wNDogJ1N0w6Fobm91dCB2aWRlbyBtcDQgamVkbsOtbSBrbGlrbnV0w61tIHZlIHZ5c29rw6ltIHJvemxpxaFlbsOtJywKCQkJZ2V0X3ZpZGVvX2ZhaWxlZDogJ05lcG9kYcWZaWxvIHNlIG5haHLDoXQgaW5mb3JtYWNlIG8gdmlkZXUuIFprdXN0ZSBvYm5vdml0IHN0csOhbmt1IChGNSkuJywKCQkJbGl2ZV9zdHJlYW1fZGlzYWJsZWRfbWVzc2FnZTogJ0xvY2FsIFlvdVR1YmUgRG93bmxvYWRlciBuZW7DrSBkb3N0dXBuw70gcHJvIMW+aXbDqSB2eXPDrWzDoW7DrScKCQl9Cgl9Cglmb3IgKGNvbnN0IFtsYW5nLCBkYXRhXSBvZiBPYmplY3QuZW50cmllcyhMT0NBTEUpKSB7CgkJaWYgKGxhbmcgPT09IExBTkdfRkFMTEJBQ0spIGNvbnRpbnVlCgkJZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoTE9DQUxFW0xBTkdfRkFMTEJBQ0tdKSkgewoJCQlpZiAoIShrZXkgaW4gZGF0YSkpIHsKCQkJCWRhdGFba2V5XSA9IExPQ0FMRVtMQU5HX0ZBTExCQUNLXVtrZXldCgkJCX0KCQl9Cgl9Cgljb25zdCBmaW5kTGFuZyA9IGwgPT4gewoJCWwgPSBsLnJlcGxhY2UoJy1IYW50JywgJycpIC8vIHNwZWNpYWwgY2FzZSBmb3IgemgtSGFudC1UVwoJCS8vIGxhbmd1YWdlIHJlc29sdXRpb24gbG9naWM6IHpoLXR3IC0tKGlmIG5vdCBleGlzdHMpLS0+IHpoIC0tKGlmIG5vdCBleGlzdHMpLS0+IExBTkdfRkFMTEJBQ0soZW4pCgkJbCA9IGwudG9Mb3dlckNhc2UoKS5yZXBsYWNlKCdfJywgJy0nKQoJCWlmIChsIGluIExPQ0FMRSkgcmV0dXJuIGwKCQllbHNlIGlmIChsLmxlbmd0aCA+IDIpIHJldHVybiBmaW5kTGFuZyhsLnNwbGl0KCctJylbMF0pCgkJZWxzZSByZXR1cm4gTEFOR19GQUxMQkFDSwoJfQoJY29uc3QgZ2V0TGFuZ0NvZGUgPSAoKSA9PiB7CgkJY29uc3QgaHRtbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2h0bWwnKQoJCWlmIChodG1sKSB7CgkJCXJldHVybiBodG1sLmxhbmcKCQl9IGVsc2UgewoJCQlyZXR1cm4gbmF2aWdhdG9yLmxhbmd1YWdlCgkJfQoJfQoJY29uc3QgJCA9IChzLCB4ID0gZG9jdW1lbnQpID0+IHgucXVlcnlTZWxlY3RvcihzKQoJY29uc3QgJGVsID0gKHRhZywgb3B0cykgPT4gewoJCWNvbnN0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpCgkJT2JqZWN0LmFzc2lnbihlbCwgb3B0cykKCQlyZXR1cm4gZWwKCX0KCWNvbnN0IGVzY2FwZVJlZ0V4cCA9IHMgPT4gcy5yZXBsYWNlKC9bLiorP14ke30oKXxbXF1cXF0vZywgJ1xcJCYnKQoJY29uc3QgcGFyc2VEZWNzaWcgPSBkYXRhID0+IHsKCQl0cnkgewoJCQlpZiAoZGF0YS5zdGFydHNXaXRoKCd2YXIgc2NyaXB0JykpIHsKCQkJCS8vIHRoZXkgaW5qZWN0IHRoZSBzY3JpcHQgdmlhIHNjcmlwdCB0YWcKCQkJCWNvbnN0IG9iaiA9IHt9CgkJCQljb25zdCBkb2N1bWVudCA9IHsKCQkJCQljcmVhdGVFbGVtZW50OiAoKSA9PiBvYmosCgkJCQkJaGVhZDogeyBhcHBlbmRDaGlsZDogKCkgPT4ge30gfQoJCQkJfQoJCQkJZXZhbChkYXRhKQoJCQkJZGF0YSA9IG9iai5pbm5lckhUTUwKCQkJfQoJCQljb25zdCBmbm5hbWVyZXN1bHQgPSAvPShbYS16QS1aMC05XCRfXSs/KVwoZGVjb2RlVVJJQ29tcG9uZW50Ly5leGVjKGRhdGEpCgkJCWNvbnN0IGZubmFtZSA9IGZubmFtZXJlc3VsdFsxXQoJCQljb25zdCBfYXJnbmFtZWZuYm9keXJlc3VsdCA9IG5ldyBSZWdFeHAoZXNjYXBlUmVnRXhwKGZubmFtZSkgKyAnPWZ1bmN0aW9uXFwoKC4rPylcXCl7KCguKyk9XFwyLis/KX0nKS5leGVjKAoJCQkJZGF0YQoJCQkpCgkJCWNvbnN0IFtfLCBhcmduYW1lLCBmbmJvZHldID0gX2FyZ25hbWVmbmJvZHlyZXN1bHQKCQkJY29uc3QgaGVscGVybmFtZXJlc3VsdCA9IC87KFthLXpBLVowLTkkX10rPylcLi4rP1woLy5leGVjKGZuYm9keSkKCQkJY29uc3QgaGVscGVybmFtZSA9IGhlbHBlcm5hbWVyZXN1bHRbMV0KCQkJY29uc3QgaGVscGVycmVzdWx0ID0gbmV3IFJlZ0V4cCgndmFyICcgKyBlc2NhcGVSZWdFeHAoaGVscGVybmFtZSkgKyAnPXtbXFxzXFxTXSs/fTsnKS5leGVjKGRhdGEpCgkJCWNvbnN0IGhlbHBlciA9IGhlbHBlcnJlc3VsdFswXQoJCQlsb2dnZXIubG9nKGBwYXJzZWRlY3NpZyByZXN1bHQ6ICVzPT57JXNcbiVzfWAsIGFyZ25hbWUsIGhlbHBlciwgZm5ib2R5KQoJCQlyZXR1cm4gbmV3IEZ1bmN0aW9uKFthcmduYW1lXSwgaGVscGVyICsgJ1xuJyArIGZuYm9keSkKCQl9IGNhdGNoIChlKSB7CgkJCWxvZ2dlci5lcnJvcigncGFyc2VkZWNzaWcgZXJyb3I6ICVvJywgZSkKCQkJbG9nZ2VyLmluZm8oJ3NjcmlwdCBjb250ZW50OiAlcycsIGRhdGEpCgkJCWxvZ2dlci5pbmZvKAoJCQkJJ0lmIHlvdSBlbmNvdW50ZXIgdGhpcyBlcnJvciwgcGxlYXNlIGNvcHkgdGhlIGZ1bGwgInNjcmlwdCBjb250ZW50IiB0byBodHRwczovL3Bhc3RlYmluLmNvbS8gZm9yIG1lLicKCQkJKQoJCX0KCX0KCWNvbnN0IHBhcnNlUXVlcnkgPSBzID0+IFsuLi5uZXcgVVJMU2VhcmNoUGFyYW1zKHMpLmVudHJpZXMoKV0ucmVkdWNlKChhY2MsIFtrLCB2XSkgPT4gKChhY2Nba10gPSB2KSwgYWNjKSwge30pCgljb25zdCBwYXJzZVJlc3BvbnNlID0gKGlkLCBwbGF5ZXJSZXNwb25zZSwgZGVjc2lnKSA9PiB7CgkJbG9nZ2VyLmxvZyhgdmlkZW8gJXMgcGxheWVyUmVzcG9uc2U6ICVvYCwgaWQsIHBsYXllclJlc3BvbnNlKQoJCWxldCBzdHJlYW0gPSBbXQoJCWlmIChwbGF5ZXJSZXNwb25zZS5zdHJlYW1pbmdEYXRhLmZvcm1hdHMpIHsKCQkJc3RyZWFtID0gcGxheWVyUmVzcG9uc2Uuc3RyZWFtaW5nRGF0YS5mb3JtYXRzLm1hcCh4ID0+CgkJCQlPYmplY3QuYXNzaWduKHt9LCB4LCBwYXJzZVF1ZXJ5KHguY2lwaGVyIHx8IHguc2lnbmF0dXJlQ2lwaGVyKSkKCQkJKQoJCQlsb2dnZXIubG9nKGB2aWRlbyAlcyBzdHJlYW06ICVvYCwgaWQsIHN0cmVhbSkKCQkJZm9yIChjb25zdCBvYmogb2Ygc3RyZWFtKSB7CgkJCQlpZiAob2JqLnMpIHsKCQkJCQlvYmoucyA9IGRlY3NpZyhvYmoucykKCQkJCQlvYmoudXJsICs9IGAmJHtvYmouc3B9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KG9iai5zKX1gCgkJCQl9CgkJCX0KCQl9CgoJCWxldCBhZGFwdGl2ZSA9IFtdCgkJaWYgKHBsYXllclJlc3BvbnNlLnN0cmVhbWluZ0RhdGEuYWRhcHRpdmVGb3JtYXRzKSB7CgkJCWFkYXB0aXZlID0gcGxheWVyUmVzcG9uc2Uuc3RyZWFtaW5nRGF0YS5hZGFwdGl2ZUZvcm1hdHMubWFwKHggPT4KCQkJCU9iamVjdC5hc3NpZ24oe30sIHgsIHBhcnNlUXVlcnkoeC5jaXBoZXIgfHwgeC5zaWduYXR1cmVDaXBoZXIpKQoJCQkpCgkJCWxvZ2dlci5sb2coYHZpZGVvICVzIGFkYXB0aXZlOiAlb2AsIGlkLCBhZGFwdGl2ZSkKCQkJZm9yIChjb25zdCBvYmogb2YgYWRhcHRpdmUpIHsKCQkJCWlmIChvYmoucykgewoJCQkJCW9iai5zID0gZGVjc2lnKG9iai5zKQoJCQkJCW9iai51cmwgKz0gYCYke29iai5zcH09JHtlbmNvZGVVUklDb21wb25lbnQob2JqLnMpfWAKCQkJCX0KCQkJfQoJCX0KCQlsb2dnZXIubG9nKGB2aWRlbyAlcyByZXN1bHQ6ICVvYCwgaWQsIHsgc3RyZWFtLCBhZGFwdGl2ZSB9KQoJCXJldHVybiB7IHN0cmVhbSwgYWRhcHRpdmUsIGRldGFpbHM6IHBsYXllclJlc3BvbnNlLnZpZGVvRGV0YWlscywgcGxheWVyUmVzcG9uc2UgfQoJfQoKCS8vIHZpZGVvIGRvd25sb2FkZXIKCWNvbnN0IHhockRvd25sb2FkVWludDhBcnJheSA9IGFzeW5jICh7IHVybCwgY29udGVudExlbmd0aCB9LCBwcm9ncmVzc0NiKSA9PiB7CgkJaWYgKHR5cGVvZiBjb250ZW50TGVuZ3RoID09PSAnc3RyaW5nJykgY29udGVudExlbmd0aCA9IHBhcnNlSW50KGNvbnRlbnRMZW5ndGgpCgkJcHJvZ3Jlc3NDYih7CgkJCWxvYWRlZDogMCwKCQkJdG90YWw6IGNvbnRlbnRMZW5ndGgsCgkJCXNwZWVkOiAwCgkJfSkKCQljb25zdCBjaHVua1NpemUgPSA2NTUzNgoJCWNvbnN0IGdldEJ1ZmZlciA9IChzdGFydCwgZW5kKSA9PgoJCQlmZXRjaCh1cmwgKyBgJnJhbmdlPSR7c3RhcnR9LSR7ZW5kID8gZW5kIC0gMSA6ICcnfWApLnRoZW4ociA9PiByLmFycmF5QnVmZmVyKCkpCgkJY29uc3QgZGF0YSA9IG5ldyBVaW50OEFycmF5KGNvbnRlbnRMZW5ndGgpCgkJbGV0IGRvd25sb2FkZWQgPSAwCgkJY29uc3QgcXVldWUgPSBuZXcgcFF1ZXVlLmRlZmF1bHQoeyBjb25jdXJyZW5jeTogNiB9KQoJCWNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCkKCQljb25zdCBwcyA9IFtdCgkJZm9yIChsZXQgc3RhcnQgPSAwOyBzdGFydCA8IGNvbnRlbnRMZW5ndGg7IHN0YXJ0ICs9IGNodW5rU2l6ZSkgewoJCQljb25zdCBleGNlZWRlZCA9IHN0YXJ0ICsgY2h1bmtTaXplID4gY29udGVudExlbmd0aAoJCQljb25zdCBjdXJDaHVua1NpemUgPSBleGNlZWRlZCA/IGNvbnRlbnRMZW5ndGggLSBzdGFydCA6IGNodW5rU2l6ZQoJCQljb25zdCBlbmQgPSBleGNlZWRlZCA/IG51bGwgOiBzdGFydCArIGNodW5rU2l6ZQoJCQljb25zdCBwID0gcXVldWUuYWRkKCgpID0+IHsKCQkJCWNvbnNvbGUubG9nKCdkbCBzdGFydCcsIHVybCwgc3RhcnQsIGVuZCkKCQkJCXJldHVybiBnZXRCdWZmZXIoc3RhcnQsIGVuZCkKCQkJCQkudGhlbihidWYgPT4gewoJCQkJCQljb25zb2xlLmxvZygnZGwgZG9uZScsIHVybCwgc3RhcnQsIGVuZCkKCQkJCQkJZG93bmxvYWRlZCArPSBjdXJDaHVua1NpemUKCQkJCQkJZGF0YS5zZXQobmV3IFVpbnQ4QXJyYXkoYnVmKSwgc3RhcnQpCgkJCQkJCWNvbnN0IGRzID0gKERhdGUubm93KCkgLSBzdGFydFRpbWUgKyAxKSAvIDEwMDAKCQkJCQkJcHJvZ3Jlc3NDYih7CgkJCQkJCQlsb2FkZWQ6IGRvd25sb2FkZWQsCgkJCQkJCQl0b3RhbDogY29udGVudExlbmd0aCwKCQkJCQkJCXNwZWVkOiBkb3dubG9hZGVkIC8gZHMKCQkJCQkJfSkKCQkJCQl9KQoJCQkJCS5jYXRjaChlcnIgPT4gewoJCQkJCQlxdWV1ZS5jbGVhcigpCgkJCQkJCWFsZXJ0KCdEb3dubG9hZCBlcnJvcicpCgkJCQkJfSkKCQkJfSkKCQkJcHMucHVzaChwKQoJCX0KCQlhd2FpdCBQcm9taXNlLmFsbChwcykKCQlyZXR1cm4gZGF0YQoJfQoKCWNvbnN0IGZmV29ya2VyID0gRkZtcGVnLmNyZWF0ZVdvcmtlcih7CgkJbG9nZ2VyOiBERUJVRyA/IG0gPT4gbG9nZ2VyLmxvZyhtLm1lc3NhZ2UpIDogKCkgPT4ge30KCX0pCglsZXQgZmZXb3JrZXJMb2FkZWQgPSBmYWxzZQoJY29uc3QgbWVyZ2VWaWRlbyA9IGFzeW5jICh2aWRlbywgYXVkaW8pID0+IHsKCQlpZiAoIWZmV29ya2VyTG9hZGVkKSBhd2FpdCBmZldvcmtlci5sb2FkKCkKCQlhd2FpdCBmZldvcmtlci53cml0ZSgndmlkZW8ubXA0JywgdmlkZW8pCgkJYXdhaXQgZmZXb3JrZXIud3JpdGUoJ2F1ZGlvLm1wNCcsIGF1ZGlvKQoJCWF3YWl0IGZmV29ya2VyLnJ1bignLWkgdmlkZW8ubXA0IC1pIGF1ZGlvLm1wNCAtYyBjb3B5IG91dHB1dC5tcDQnLCB7CgkJCWlucHV0OiBbJ3ZpZGVvLm1wNCcsICdhdWRpby5tcDQnXSwKCQkJb3V0cHV0OiAnb3V0cHV0Lm1wNCcKCQl9KQoJCWNvbnN0IHsgZGF0YSB9ID0gYXdhaXQgZmZXb3JrZXIucmVhZCgnb3V0cHV0Lm1wNCcpCgkJYXdhaXQgZmZXb3JrZXIucmVtb3ZlKCdvdXRwdXQubXA0JykKCQlyZXR1cm4gZGF0YQoJfQoJY29uc3QgdHJpZ2dlckRvd25sb2FkID0gKHVybCwgZmlsZW5hbWUpID0+IHsKCQljb25zdCBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpCgkJYS5ocmVmID0gdXJsCgkJYS5kb3dubG9hZCA9IGZpbGVuYW1lCgkJZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChhKQoJCWEuY2xpY2soKQoJCWEucmVtb3ZlKCkKCX0KCWNvbnN0IGRsTW9kYWxUZW1wbGF0ZSA9IGAKPGRpdiBzdHlsZT0id2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsiPgoJPGRpdiB2LWlmPSJtZXJnaW5nIiBzdHlsZT0iaGVpZ2h0OiAxMDAlOyB3aWR0aDogMTAwJTsgZGlzcGxheTogZmxleDsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGZvbnQtc2l6ZTogMjRweDsiPk1lcmdpbmcgdmlkZW8sIHBsZWFzZSB3YWl0Li4uPC9kaXY+Cgk8ZGl2IHYtZWxzZSBzdHlsZT0iaGVpZ2h0OiAxMDAlOyB3aWR0aDogMTAwJTsgZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsiPgogCQk8ZGl2IHN0eWxlPSJmbGV4OiAxOyBtYXJnaW46IDEwcHg7Ij4KCQkJPHAgc3R5bGU9ImZvbnQtc2l6ZTogMjRweDsiPlZpZGVvPC9wPgoJCQk8cHJvZ3Jlc3Mgc3R5bGU9IndpZHRoOiAxMDAlOyIgOnZhbHVlPSJ2aWRlby5wcm9ncmVzcyIgbWluPSIwIiBtYXg9IjEwMCI+PC9wcm9ncmVzcz4KCQkJPGRpdiBzdHlsZT0iZGlzcGxheTogZmxleDsganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOyI+CgkJCQk8c3Bhbj57e3ZpZGVvLnNwZWVkfX0ga0Ivczwvc3Bhbj4KCQkJCTxzcGFuPnt7dmlkZW8ubG9hZGVkfX0ve3t2aWRlby50b3RhbH19IE1CPC9zcGFuPgoJCQk8L2Rpdj4KCQk8L2Rpdj4KCQk8ZGl2IHN0eWxlPSJmbGV4OiAxOyBtYXJnaW46IDEwcHg7Ij4KCQkJPHAgc3R5bGU9ImZvbnQtc2l6ZTogMjRweDsiPkF1ZGlvPC9wPgoJCQk8cHJvZ3Jlc3Mgc3R5bGU9IndpZHRoOiAxMDAlOyIgOnZhbHVlPSJhdWRpby5wcm9ncmVzcyIgbWluPSIwIiBtYXg9IjEwMCI+PC9wcm9ncmVzcz4KCQkJPGRpdiBzdHlsZT0iZGlzcGxheTogZmxleDsganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOyI+CgkJCQk8c3Bhbj57e2F1ZGlvLnNwZWVkfX0ga0Ivczwvc3Bhbj4KCQkJCTxzcGFuPnt7YXVkaW8ubG9hZGVkfX0ve3thdWRpby50b3RhbH19IE1CPC9zcGFuPgoJCQk8L2Rpdj4KCQk8L2Rpdj4KCTwvZGl2Pgo8L2Rpdj4KYAoJZnVuY3Rpb24gb3BlbkRvd25sb2FkTW9kZWwoYWRhcHRpdmUsIHRpdGxlKSB7CgkJY29uc3Qgd2luID0gb3BlbigKCQkJJycsCgkJCSdWaWRlbyBEb3dubG9hZCcsCgkJCWB0b29sYmFyPW5vLGhlaWdodD0ke3NjcmVlbi5oZWlnaHQgLyAyfSx3aWR0aD0ke3NjcmVlbi53aWR0aCAvIDJ9LGxlZnQ9JHtzY3JlZW5MZWZ0fSx0b3A9JHtzY3JlZW5Ub3B9YAoJCSkKCQljb25zdCBkaXYgPSB3aW4uZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JykKCQl3aW4uZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkaXYpCgkJd2luLmRvY3VtZW50LnRpdGxlID0gYERvd25sb2FkaW5nICIke3RpdGxlfSJgCgkJY29uc3QgZGxNb2RhbEFwcCA9IG5ldyBWdWUoewoJCQl0ZW1wbGF0ZTogZGxNb2RhbFRlbXBsYXRlLAoJCQlkYXRhKCkgewoJCQkJcmV0dXJuIHsKCQkJCQl2aWRlbzogewoJCQkJCQlwcm9ncmVzczogMCwKCQkJCQkJdG90YWw6IDAsCgkJCQkJCWxvYWRlZDogMCwKCQkJCQkJc3BlZWQ6IDAKCQkJCQl9LAoJCQkJCWF1ZGlvOiB7CgkJCQkJCXByb2dyZXNzOiAwLAoJCQkJCQl0b3RhbDogMCwKCQkJCQkJbG9hZGVkOiAwLAoJCQkJCQlzcGVlZDogMAoJCQkJCX0sCgkJCQkJbWVyZ2luZzogZmFsc2UKCQkJCX0KCQkJfSwKCQkJbWV0aG9kczogewoJCQkJYXN5bmMgc3RhcnQoYWRhcHRpdmUsIHRpdGxlKSB7CgkJCQkJd2luLm9uYmVmb3JldW5sb2FkID0gKCkgPT4gdHJ1ZQoJCQkJCS8vIFlvdVR1YmUncyBkZWZhdWx0IG9yZGVyIGlzIGRlc2NlbmRpbmcgYnkgdmlkZW8gcXVhbGl0eQoJCQkJCWNvbnN0IHZpZGVvT2JqID0gYWRhcHRpdmUKCQkJCQkJLmZpbHRlcih4ID0+IHgubWltZVR5cGUuaW5jbHVkZXMoJ3ZpZGVvL21wNCcpIHx8IHgubWltZVR5cGUuaW5jbHVkZXMoJ3ZpZGVvL3dlYm0nKSkKCQkJCQkJLm1hcCh2ID0+IHsKCQkJCQkJCWNvbnN0IFtfLCBxdWFsaXR5LCBmcHNdID0gLyhcZCspcChcZCopLy5leGVjKHYucXVhbGl0eUxhYmVsKQoJCQkJCQkJdi5xdWFsaXR5TnVtID0gcGFyc2VJbnQocXVhbGl0eSkKCQkJCQkJCXYuZnBzID0gZnBzID8gcGFyc2VJbnQoZnBzKSA6IDMwCgkJCQkJCQlyZXR1cm4gdgoJCQkJCQl9KQoJCQkJCQkuc29ydCgoYSwgYikgPT4gewoJCQkJCQkJaWYgKGEucXVhbGl0eU51bSA9PT0gYi5xdWFsaXR5TnVtKSByZXR1cm4gYi5mcHMgLSBhLmZwcyAvLyBleDogMzAtNjA9LTMwLCB0aGVuIGEgd2lsbCBiZSBwdXQgYmVmb3JlIGIKCQkJCQkJCXJldHVybiBiLnF1YWxpdHlOdW0gLSBhLnF1YWxpdHlOdW0KCQkJCQkJfSlbMF0KCQkJCQljb25zdCBhdWRpb09iaiA9IGFkYXB0aXZlLmZpbmQoeCA9PiB4Lm1pbWVUeXBlLmluY2x1ZGVzKCdhdWRpby9tcDQnKSkKCQkJCQljb25zdCB2UHJvbWlzZSA9IHhockRvd25sb2FkVWludDhBcnJheSh2aWRlb09iaiwgZSA9PiB7CgkJCQkJCXRoaXMudmlkZW8ucHJvZ3Jlc3MgPSAoZS5sb2FkZWQgLyBlLnRvdGFsKSAqIDEwMAoJCQkJCQl0aGlzLnZpZGVvLmxvYWRlZCA9IChlLmxvYWRlZCAvIDEwMjQgLyAxMDI0KS50b0ZpeGVkKDIpCgkJCQkJCXRoaXMudmlkZW8udG90YWwgPSAoZS50b3RhbCAvIDEwMjQgLyAxMDI0KS50b0ZpeGVkKDIpCgkJCQkJCXRoaXMudmlkZW8uc3BlZWQgPSAoZS5zcGVlZCAvIDEwMjQpLnRvRml4ZWQoMikKCQkJCQl9KQoJCQkJCWNvbnN0IGFQcm9taXNlID0geGhyRG93bmxvYWRVaW50OEFycmF5KGF1ZGlvT2JqLCBlID0+IHsKCQkJCQkJdGhpcy5hdWRpby5wcm9ncmVzcyA9IChlLmxvYWRlZCAvIGUudG90YWwpICogMTAwCgkJCQkJCXRoaXMuYXVkaW8ubG9hZGVkID0gKGUubG9hZGVkIC8gMTAyNCAvIDEwMjQpLnRvRml4ZWQoMikKCQkJCQkJdGhpcy5hdWRpby50b3RhbCA9IChlLnRvdGFsIC8gMTAyNCAvIDEwMjQpLnRvRml4ZWQoMikKCQkJCQkJdGhpcy5hdWRpby5zcGVlZCA9IChlLnNwZWVkIC8gMTAyNCkudG9GaXhlZCgyKQoJCQkJCX0pCgkJCQkJY29uc3QgW3ZhcnIsIGFhcnJdID0gYXdhaXQgUHJvbWlzZS5hbGwoW3ZQcm9taXNlLCBhUHJvbWlzZV0pCgkJCQkJdGhpcy5tZXJnaW5nID0gdHJ1ZQoJCQkJCXdpbi5vbnVubG9hZCA9ICgpID0+IHsKCQkJCQkJLy8gdHJpZ2dlciBkb3dubG9hZCB3aGVuIHVzZXIgY2xvc2UgaXQKCQkJCQkJY29uc3QgYnZ1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKFt2YXJyXSkpCgkJCQkJCWNvbnN0IGJhdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbYWFycl0pKQoJCQkJCQl0cmlnZ2VyRG93bmxvYWQoYnZ1cmwsIHRpdGxlICsgJy12aWRlb29ubHkubXA0JykKCQkJCQkJdHJpZ2dlckRvd25sb2FkKGJhdXJsLCB0aXRsZSArICctYXVkaW9vbmx5Lm1wNCcpCgkJCQkJfQoJCQkJCWNvbnN0IHJlc3VsdCA9IGF3YWl0IFByb21pc2UucmFjZShbbWVyZ2VWaWRlbyh2YXJyLCBhYXJyKSwgc2xlZXAoMTAwMCAqIDI1KS50aGVuKCgpID0+IG51bGwpXSkKCQkJCQlpZiAoIXJlc3VsdCkgewoJCQkJCQlhbGVydCgnQW4gZXJyb3IgaGFzIG9jY3VycmVkIHdoZW4gbWVyZ2luZyB2aWRlbycpCgkJCQkJCWNvbnN0IGJ2dXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbdmFycl0pKQoJCQkJCQljb25zdCBiYXVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoW2FhcnJdKSkKCQkJCQkJdHJpZ2dlckRvd25sb2FkKGJ2dXJsLCB0aXRsZSArICctdmlkZW9vbmx5Lm1wNCcpCgkJCQkJCXRyaWdnZXJEb3dubG9hZChiYXVybCwgdGl0bGUgKyAnLWF1ZGlvb25seS5tcDQnKQoJCQkJCQlyZXR1cm4gdGhpcy5jbG9zZSgpCgkJCQkJfQoJCQkJCXRoaXMubWVyZ2luZyA9IGZhbHNlCgkJCQkJY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbcmVzdWx0XSkpCgkJCQkJdHJpZ2dlckRvd25sb2FkKHVybCwgdGl0bGUgKyAnLm1wNCcpCgkJCQkJd2luLm9uYmVmb3JldW5sb2FkID0gbnVsbAoJCQkJCXdpbi5vbnVubG9hZCA9IG51bGwKCQkJCQl3aW4uY2xvc2UoKQoJCQkJfQoJCQl9CgkJfSkuJG1vdW50KGRpdikKCQlkbE1vZGFsQXBwLnN0YXJ0KGFkYXB0aXZlLCB0aXRsZSkKCX0KCgljb25zdCB0ZW1wbGF0ZSA9IGAKPGRpdiBjbGFzcz0iYm94IiA6Y2xhc3M9InsnZGFyayc6ZGFya30iPgogIDx0ZW1wbGF0ZSB2LWlmPSIhaXNMaXZlU3RyZWFtIj4KICAgIDxkaXYgdi1pZj0iYWRhcHRpdmUubGVuZ3RoIiBjbGFzcz0ib2YtaCB0LWNlbnRlciBjLXBvaW50ZXIgbGgtMjAiPgogICAgICA8YSBjbGFzcz0iZnMtMTRweCIgQGNsaWNrPSJkbG1wNCIgdi10ZXh0PSJzdHJpbmdzLmRsbXA0Ij48L2E+CiAgICA8L2Rpdj4KICAgIDxkaXYgQGNsaWNrPSJoaWRlPSFoaWRlIiBjbGFzcz0iYm94LXRvZ2dsZSBkaXYtYSB0LWNlbnRlciBmcy0xNHB4IGMtcG9pbnRlciBsaC0yMCIgdi10ZXh0PSJzdHJpbmdzLnRvZ2dsZWxpbmtzIj48L2Rpdj4KICAgIDxkaXYgOmNsYXNzPSJ7J2hpZGUnOmhpZGV9Ij4KICAgICAgPGRpdiBjbGFzcz0idC1jZW50ZXIgZnMtMTRweCIgdi10ZXh0PSJzdHJpbmdzLnZpZGVvaWQraWQiPjwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJkLWZsZXgiPgogICAgICAgIDxkaXYgY2xhc3M9ImYtMSBvZi1oIj4KICAgICAgICAgIDxkaXYgY2xhc3M9InQtY2VudGVyIGZzLTE0cHgiIHYtdGV4dD0ic3RyaW5ncy5zdHJlYW0iPjwvZGl2PgogICAgICAgICAgPGEgY2xhc3M9Inl0ZGwtbGluay1idG4gZnMtMTRweCIgdGFyZ2V0PSJfYmxhbmsiIHYtZm9yPSJ2aWQgaW4gc3RyZWFtIiA6aHJlZj0idmlkLnVybCIgOnRpdGxlPSJ2aWQudHlwZSIgdi10ZXh0PSJmb3JtYXRTdHJlYW1UZXh0KHZpZCkiPjwvYT4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJmLTEgb2YtaCI+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJ0LWNlbnRlciBmcy0xNHB4IiB2LXRleHQ9InN0cmluZ3MuYWRhcHRpdmUiPjwvZGl2PgogICAgICAgICAgPGEgY2xhc3M9Inl0ZGwtbGluay1idG4gZnMtMTRweCIgdGFyZ2V0PSJfYmxhbmsiIHYtZm9yPSJ2aWQgaW4gYWRhcHRpdmUiIDpocmVmPSJ2aWQudXJsIiA6dGl0bGU9InZpZC50eXBlIiB2LXRleHQ9ImZvcm1hdEFkYXB0aXZlVGV4dCh2aWQpIj48L2E+CiAgICAgICAgPC9kaXY+CiAgICAgIDwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJvZi1oIHQtY2VudGVyIj4KICAgICAgICA8YSBjbGFzcz0iZnMtMTRweCIgaHJlZj0iaHR0cHM6Ly9tYXBsZTMxNDIuZ2l0aHViLmlvL21lcmdlbXA0LyIgdGFyZ2V0PSJfYmxhbmsiIHYtdGV4dD0ic3RyaW5ncy5pbmJyb3dzZXJfYWRhcHRpdmVfbWVyZ2VyIj48L2E+CiAgICAgIDwvZGl2PgogICAgPC9kaXY+CiAgPC90ZW1wbGF0ZT4KICA8dGVtcGxhdGUgdi1lbHNlPgogICAgPGRpdiBjbGFzcz0idC1jZW50ZXIgZnMtMTRweCBsaC0yMCIgdi10ZXh0PSJzdHJpbmdzLmxpdmVfc3RyZWFtX2Rpc2FibGVkX21lc3NhZ2UiPjwvZGl2PgogIDwvdGVtcGxhdGU+CjwvZGl2PgpgLnNsaWNlKDEpCgljb25zdCBhcHAgPSBuZXcgVnVlKHsKCQlkYXRhKCkgewoJCQlyZXR1cm4gewoJCQkJaGlkZTogdHJ1ZSwKCQkJCWlkOiAnJywKCQkJCWlzTGl2ZVN0cmVhbTogZmFsc2UsCgkJCQlzdHJlYW06IFtdLAoJCQkJYWRhcHRpdmU6IFtdLAoJCQkJZGV0YWlsczogbnVsbCwKCQkJCWRhcms6IGZhbHNlLAoJCQkJbGFuZzogZmluZExhbmcoZ2V0TGFuZ0NvZGUoKSkKCQkJfQoJCX0sCgkJY29tcHV0ZWQ6IHsKCQkJc3RyaW5ncygpIHsKCQkJCXJldHVybiBMT0NBTEVbdGhpcy5sYW5nLnRvTG93ZXJDYXNlKCldCgkJCX0KCQl9LAoJCW1ldGhvZHM6IHsKCQkJZGxtcDQoKSB7CgkJCQlvcGVuRG93bmxvYWRNb2RlbCh0aGlzLmFkYXB0aXZlLCB0aGlzLmRldGFpbHMudGl0bGUpCgkJCX0sCgkJCWZvcm1hdFN0cmVhbVRleHQodmlkKSB7CgkJCQlyZXR1cm4gW3ZpZC5xdWFsaXR5TGFiZWwsIHZpZC5xdWFsaXR5XS5maWx0ZXIoeCA9PiB4KS5qb2luKCc6ICcpCgkJCX0sCgkJCWZvcm1hdEFkYXB0aXZlVGV4dCh2aWQpIHsKCQkJCWxldCBzdHIgPSBbdmlkLnF1YWxpdHlMYWJlbCwgdmlkLm1pbWVUeXBlXS5maWx0ZXIoeCA9PiB4KS5qb2luKCc6ICcpCgkJCQlpZiAodmlkLm1pbWVUeXBlLmluY2x1ZGVzKCdhdWRpbycpKSB7CgkJCQkJc3RyICs9IGAgJHtNYXRoLnJvdW5kKHZpZC5iaXRyYXRlIC8gMTAwMCl9a2Jwc2AKCQkJCX0KCQkJCXJldHVybiBzdHIKCQkJfQoJCX0sCgkJdGVtcGxhdGUKCX0pCglsb2dnZXIubG9nKGBkZWZhdWx0IGxhbmd1YWdlOiAlc2AsIGFwcC5sYW5nKQoKCS8vIGF0dGFjaCBlbGVtZW50Cgljb25zdCBzaGFkb3dIb3N0ID0gJGVsKCdkaXYnKQoJY29uc3Qgc2hhZG93ID0gc2hhZG93SG9zdC5hdHRhY2hTaGFkb3cgPyBzaGFkb3dIb3N0LmF0dGFjaFNoYWRvdyh7IG1vZGU6ICdjbG9zZWQnIH0pIDogc2hhZG93SG9zdCAvLyBubyBzaGFkb3cgZG9tCglsb2dnZXIubG9nKCdzaGFkb3dIb3N0OiAlbycsIHNoYWRvd0hvc3QpCgljb25zdCBjb250YWluZXIgPSAkZWwoJ2RpdicpCglzaGFkb3cuYXBwZW5kQ2hpbGQoY29udGFpbmVyKQoJYXBwLiRtb3VudChjb250YWluZXIpCgoJaWYgKERFQlVHICYmIHR5cGVvZiB1bnNhZmVXaW5kb3cgIT09ICd1bmRlZmluZWQnKSB7CgkJLy8gZXhwb3NlIHNvbWUgZnVuY3Rpb25zIGZvciBkZWJ1Z2dpbmcKCQl1bnNhZmVXaW5kb3cuJGFwcCA9IGFwcAoJCXVuc2FmZVdpbmRvdy5wYXJzZVF1ZXJ5ID0gcGFyc2VRdWVyeQoJCXVuc2FmZVdpbmRvdy5wYXJzZURlY3NpZyA9IHBhcnNlRGVjc2lnCgkJdW5zYWZlV2luZG93LnBhcnNlUmVzcG9uc2UgPSBwYXJzZVJlc3BvbnNlCgl9Cgljb25zdCBsb2FkID0gYXN5bmMgcGxheWVyUmVzcG9uc2UgPT4gewoJCXRyeSB7CgkJCWNvbnN0IGJhc2VqcyA9CgkJCQkodHlwZW9mIHl0cGxheWVyICE9PSAndW5kZWZpbmVkJyAmJiAnY29uZmlnJyBpbiB5dHBsYXllciAmJiB5dHBsYXllci5jb25maWcuYXNzZXRzCgkJCQkJPyAnaHR0cHM6Ly8nICsgbG9jYXRpb24uaG9zdCArIHl0cGxheWVyLmNvbmZpZy5hc3NldHMuanMKCQkJCQk6ICd3ZWJfcGxheWVyX2NvbnRleHRfY29uZmlnJyBpbiB5dHBsYXllcgoJCQkJCT8gJ2h0dHBzOi8vJyArIGxvY2F0aW9uLmhvc3QgKyB5dHBsYXllci53ZWJfcGxheWVyX2NvbnRleHRfY29uZmlnLmpzVXJsCgkJCQkJOiBudWxsKSB8fCAkKCdzY3JpcHRbc3JjJD0iYmFzZS5qcyJdJykuc3JjCgkJCWNvbnN0IGRlY3NpZyA9IGF3YWl0IHhmLmdldChiYXNlanMpLnRleHQocGFyc2VEZWNzaWcpCgkJCWNvbnN0IGlkID0gcGFyc2VRdWVyeShsb2NhdGlvbi5zZWFyY2gpLnYKCQkJY29uc3QgZGF0YSA9IHBhcnNlUmVzcG9uc2UoaWQsIHBsYXllclJlc3BvbnNlLCBkZWNzaWcpCgkJCWxvZ2dlci5sb2coJ3ZpZGVvIGxvYWRlZDogJXMnLCBpZCkKCQkJYXBwLmlzTGl2ZVN0cmVhbSA9IGRhdGEucGxheWVyUmVzcG9uc2UucGxheWFiaWxpdHlTdGF0dXMubGl2ZVN0cmVhbWFiaWxpdHkgIT0gbnVsbAoJCQlhcHAuaWQgPSBpZAoJCQlhcHAuc3RyZWFtID0gZGF0YS5zdHJlYW0KCQkJYXBwLmFkYXB0aXZlID0gZGF0YS5hZGFwdGl2ZQoJCQlhcHAuZGV0YWlscyA9IGRhdGEuZGV0YWlscwoKCQkJY29uc3QgYWN0TGFuZyA9IGdldExhbmdDb2RlKCkKCQkJaWYgKGFjdExhbmcgIT0gbnVsbCkgewoJCQkJY29uc3QgbGFuZyA9IGZpbmRMYW5nKGFjdExhbmcpCgkJCQlsb2dnZXIubG9nKCd5b3V0dWJlIHVpIGxhbmc6ICVzJywgYWN0TGFuZykKCQkJCWxvZ2dlci5sb2coJ3l0ZGwgbGFuZzonLCBsYW5nKQoJCQkJYXBwLmxhbmcgPSBsYW5nCgkJCX0KCQl9IGNhdGNoIChlcnIpIHsKCQkJYWxlcnQoYXBwLnN0cmluZ3MuZ2V0X3ZpZGVvX2ZhaWxlZCkKCQkJbG9nZ2VyLmVycm9yKCdsb2FkJywgZXJyKQoJCX0KCX0KCgkvLyBob29rIGZldGNoIHJlc3BvbnNlCgljb25zdCBmZiA9IGZldGNoCgl1bnNhZmVXaW5kb3cuZmV0Y2ggPSAoLi4uYXJncykgPT4gewoJCWlmIChhcmdzWzBdIGluc3RhbmNlb2YgUmVxdWVzdCkgewoJCQlyZXR1cm4gZmYoLi4uYXJncykudGhlbihyZXNwID0+IHsKCQkJCWlmIChyZXNwLnVybC5pbmNsdWRlcygncGxheWVyJykpIHsKCQkJCQlyZXNwLmNsb25lKCkuanNvbigpLnRoZW4obG9hZCkKCQkJCX0KCQkJCXJldHVybiByZXNwCgkJCX0pCgkJfQoJCXJldHVybiBmZiguLi5hcmdzKQoJfQoKCS8vIGF0dGFjaCBlbGVtZW50CglzZXRJbnRlcnZhbCgoKSA9PiB7CgkJY29uc3QgZWwgPQoJCQkkKCcjaW5mby1jb250ZW50cycpIHx8CgkJCSQoJyN3YXRjaC1oZWFkZXInKSB8fAoJCQkkKCcucGFnZS1jb250YWluZXI6bm90KFtoaWRkZW5dKSB5dG0taXRlbS1zZWN0aW9uLXJlbmRlcmVyPmxhenktbGlzdCcpCgkJaWYgKGVsICYmICFlbC5jb250YWlucyhzaGFkb3dIb3N0KSkgewoJCQllbC5hcHBlbmRDaGlsZChzaGFkb3dIb3N0KQoJCX0KCX0sIDEwMCkKCgkvLyBpbml0Cgl1bnNhZmVXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsICgpID0+IHsKCQljb25zdCBmaXJzdFJlc3AgPSB1bnNhZmVXaW5kb3c/Lnl0cGxheWVyPy5jb25maWc/LmFyZ3M/LnJhd19wbGF5ZXJfcmVzcG9uc2UKCQlpZiAoZmlyc3RSZXNwKSB7CgkJCWxvYWQoZmlyc3RSZXNwKQoJCX0KCX0pCgoJLy8gbGlzdGVuIHRvIGRhcmsgbW9kZSB0b2dnbGUKCWNvbnN0ICRodG1sID0gJCgnaHRtbCcpCgluZXcgTXV0YXRpb25PYnNlcnZlcigoKSA9PiB7CgkJYXBwLmRhcmsgPSAkaHRtbC5nZXRBdHRyaWJ1dGUoJ2RhcmsnKSAhPT0gbnVsbAoJfSkub2JzZXJ2ZSgkaHRtbCwgeyBhdHRyaWJ1dGVzOiB0cnVlIH0pCglhcHAuZGFyayA9ICRodG1sLmdldEF0dHJpYnV0ZSgnZGFyaycpICE9PSBudWxsCgoJY29uc3QgY3NzID0gYAouaGlkZXsKCWRpc3BsYXk6IG5vbmU7Cn0KLnQtY2VudGVyewoJdGV4dC1hbGlnbjogY2VudGVyOwp9Ci5kLWZsZXh7CglkaXNwbGF5OiBmbGV4Owp9Ci5mLTF7CglmbGV4OiAxOwp9Ci5mcy0xNHB4ewoJZm9udC1zaXplOiAxNHB4Owp9Ci5vZi1oewoJb3ZlcmZsb3c6IGhpZGRlbjsKfQouYm94ewogIHBhZGRpbmctdG9wOiAuNWVtOwogIHBhZGRpbmctYm90dG9tOiAuNWVtOwoJYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLXl0LWJvcmRlci1jb2xvcik7Cglmb250LWZhbWlseTogQXJpYWw7Cn0KLmJveC10b2dnbGV7CgltYXJnaW46IDNweDsKCXVzZXItc2VsZWN0OiBub25lOwoJLW1vei11c2VyLXNlbGVjdDogLW1vei1ub25lOwp9Ci55dGRsLWxpbmstYnRuewoJZGlzcGxheTogYmxvY2s7Cglib3JkZXI6IDFweCBzb2xpZCAhaW1wb3J0YW50OwoJYm9yZGVyLXJhZGl1czogM3B4OwoJdGV4dC1kZWNvcmF0aW9uOiBub25lICFpbXBvcnRhbnQ7CglvdXRsaW5lOiAwOwoJdGV4dC1hbGlnbjogY2VudGVyOwoJcGFkZGluZzogMnB4OwoJbWFyZ2luOiA1cHg7Cgljb2xvcjogYmxhY2s7Cn0KYSwgLmRpdi1hewoJdGV4dC1kZWNvcmF0aW9uOiBub25lOwoJY29sb3I6IHZhcigtLXl0LWJ1dHRvbi1jb2xvciwgaW5oZXJpdCk7Cn0KYTpob3ZlciwgLmRpdi1hOmhvdmVyewoJY29sb3I6IHZhcigtLXl0LXNwZWMtY2FsbC10by1hY3Rpb24sIGJsdWUpOwp9Ci5ib3guZGFya3sKCWNvbG9yOiB2YXIoLS15dC1lbmRwb2ludC1jb2xvciwgdmFyKC0teXQtc3BlYy10ZXh0LXByaW1hcnkpKTsKfQouYm94LmRhcmsgLnl0ZGwtbGluay1idG57Cgljb2xvcjogdmFyKC0teXQtZW5kcG9pbnQtY29sb3IsIHZhcigtLXl0LXNwZWMtdGV4dC1wcmltYXJ5KSk7Cn0KLmJveC5kYXJrIC55dGRsLWxpbmstYnRuOmhvdmVyewoJY29sb3I6IHJnYmEoMjAwLCAyMDAsIDI1NSwgMC44KTsKfQouYm94LmRhcmsgLmJveC10b2dnbGU6aG92ZXJ7Cgljb2xvcjogcmdiYSgyMDAsIDIwMCwgMjU1LCAwLjgpOwp9Ci5jLXBvaW50ZXJ7CgljdXJzb3I6IHBvaW50ZXI7Cn0KLmxoLTIwewoJbGluZS1oZWlnaHQ6IDIwcHg7Cn0KYAoJc2hhZG93LmFwcGVuZENoaWxkKCRlbCgnc3R5bGUnLCB7IHRleHRDb250ZW50OiBjc3MgfSkpCgljb25zdCBjc3MyID0gYAovKiBodHRwczovL2dyZWFzeWZvcmsub3JnL3poLVRXL3NjcmlwdHMvMzY5NDAwLWxvY2FsLXlvdXR1YmUtZG93bmxvYWRlci9kaXNjdXNzaW9ucy85NTc0NCAqLwojbWV0YS1jb250ZW50cywKI2luZm8tY29udGVudHN7CglkaXNwbGF5OiBjb250ZW50cyAhaW1wb3J0YW50Owp9Cgp5dGQtd2F0Y2gtbWV0YWRhdGEuc3R5bGUtc2NvcGUgewoJZGlzcGxheTogbm9uZSAhaW1wb3J0YW50Owp9CmAKCWRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoJGVsKCdzdHlsZScsIHsgdGV4dENvbnRlbnQ6IGNzczIgfSkpCn0pKCkK","requires":[{"meta":{"name":"vue.js","url":"https://unpkg.com/[email protected]/dist/vue.js","ts":1691113794682,"mimetype":"text/javascript"},"source":"LyohCiAqIFZ1ZS5qcyB2Mi42LjEwCiAqIChjKSAyMDE0LTIwMTkgRXZhbiBZb3UKICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLgogKi8KKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHsKICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6CiAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDoKICAoZ2xvYmFsID0gZ2xvYmFsIHx8IHNlbGYsIGdsb2JhbC5WdWUgPSBmYWN0b3J5KCkpOwp9KHRoaXMsIGZ1bmN0aW9uICgpIHsgJ3VzZSBzdHJpY3QnOwoKICAvKiAgKi8KCiAgdmFyIGVtcHR5T2JqZWN0ID0gT2JqZWN0LmZyZWV6ZSh7fSk7CgogIC8vIFRoZXNlIGhlbHBlcnMgcHJvZHVjZSBiZXR0ZXIgVk0gY29kZSBpbiBKUyBlbmdpbmVzIGR1ZSB0byB0aGVpcgogIC8vIGV4cGxpY2l0bmVzcyBhbmQgZnVuY3Rpb24gaW5saW5pbmcuCiAgZnVuY3Rpb24gaXNVbmRlZiAodikgewogICAgcmV0dXJuIHYgPT09IHVuZGVmaW5lZCB8fCB2ID09PSBudWxsCiAgfQoKICBmdW5jdGlvbiBpc0RlZiAodikgewogICAgcmV0dXJuIHYgIT09IHVuZGVmaW5lZCAmJiB2ICE9PSBudWxsCiAgfQoKICBmdW5jdGlvbiBpc1RydWUgKHYpIHsKICAgIHJldHVybiB2ID09PSB0cnVlCiAgfQoKICBmdW5jdGlvbiBpc0ZhbHNlICh2KSB7CiAgICByZXR1cm4gdiA9PT0gZmFsc2UKICB9CgogIC8qKgogICAqIENoZWNrIGlmIHZhbHVlIGlzIHByaW1pdGl2ZS4KICAgKi8KICBmdW5jdGlvbiBpc1ByaW1pdGl2ZSAodmFsdWUpIHsKICAgIHJldHVybiAoCiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgfHwKICAgICAgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyB8fAogICAgICAvLyAkZmxvdy1kaXNhYmxlLWxpbmUKICAgICAgdHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJyB8fAogICAgICB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJwogICAgKQogIH0KCiAgLyoqCiAgICogUXVpY2sgb2JqZWN0IGNoZWNrIC0gdGhpcyBpcyBwcmltYXJpbHkgdXNlZCB0byB0ZWxsCiAgICogT2JqZWN0cyBmcm9tIHByaW1pdGl2ZSB2YWx1ZXMgd2hlbiB3ZSBrbm93IHRoZSB2YWx1ZQogICAqIGlzIGEgSlNPTi1jb21wbGlhbnQgdHlwZS4KICAgKi8KICBmdW5jdGlvbiBpc09iamVjdCAob2JqKSB7CiAgICByZXR1cm4gb2JqICE9PSBudWxsICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnCiAgfQoKICAvKioKICAgKiBHZXQgdGhlIHJhdyB0eXBlIHN0cmluZyBvZiBhIHZhbHVlLCBlLmcuLCBbb2JqZWN0IE9iamVjdF0uCiAgICovCiAgdmFyIF90b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7CgogIGZ1bmN0aW9uIHRvUmF3VHlwZSAodmFsdWUpIHsKICAgIHJldHVybiBfdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpCiAgfQoKICAvKioKICAgKiBTdHJpY3Qgb2JqZWN0IHR5cGUgY2hlY2suIE9ubHkgcmV0dXJucyB0cnVlCiAgICogZm9yIHBsYWluIEphdmFTY3JpcHQgb2JqZWN0cy4KICAgKi8KICBmdW5jdGlvbiBpc1BsYWluT2JqZWN0IChvYmopIHsKICAgIHJldHVybiBfdG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBPYmplY3RdJwogIH0KCiAgZnVuY3Rpb24gaXNSZWdFeHAgKHYpIHsKICAgIHJldHVybiBfdG9TdHJpbmcuY2FsbCh2KSA9PT0gJ1tvYmplY3QgUmVnRXhwXScKICB9CgogIC8qKgogICAqIENoZWNrIGlmIHZhbCBpcyBhIHZhbGlkIGFycmF5IGluZGV4LgogICAqLwogIGZ1bmN0aW9uIGlzVmFsaWRBcnJheUluZGV4ICh2YWwpIHsKICAgIHZhciBuID0gcGFyc2VGbG9hdChTdHJpbmcodmFsKSk7CiAgICByZXR1cm4gbiA+PSAwICYmIE1hdGguZmxvb3IobikgPT09IG4gJiYgaXNGaW5pdGUodmFsKQogIH0KCiAgZnVuY3Rpb24gaXNQcm9taXNlICh2YWwpIHsKICAgIHJldHVybiAoCiAgICAgIGlzRGVmKHZhbCkgJiYKICAgICAgdHlwZW9mIHZhbC50aGVuID09PSAnZnVuY3Rpb24nICYmCiAgICAgIHR5cGVvZiB2YWwuY2F0Y2ggPT09ICdmdW5jdGlvbicKICAgICkKICB9CgogIC8qKgogICAqIENvbnZlcnQgYSB2YWx1ZSB0byBhIHN0cmluZyB0aGF0IGlzIGFjdHVhbGx5IHJlbmRlcmVkLgogICAqLwogIGZ1bmN0aW9uIHRvU3RyaW5nICh2YWwpIHsKICAgIHJldHVybiB2YWwgPT0gbnVsbAogICAgICA/ICcnCiAgICAgIDogQXJyYXkuaXNBcnJheSh2YWwpIHx8IChpc1BsYWluT2JqZWN0KHZhbCkgJiYgdmFsLnRvU3RyaW5nID09PSBfdG9TdHJpbmcpCiAgICAgICAgPyBKU09OLnN0cmluZ2lmeSh2YWwsIG51bGwsIDIpCiAgICAgICAgOiBTdHJpbmcodmFsKQogIH0KCiAgLyoqCiAgICogQ29udmVydCBhbiBpbnB1dCB2YWx1ZSB0byBhIG51bWJlciBmb3IgcGVyc2lzdGVuY2UuCiAgICogSWYgdGhlIGNvbnZlcnNpb24gZmFpbHMsIHJldHVybiBvcmlnaW5hbCBzdHJpbmcuCiAgICovCiAgZnVuY3Rpb24gdG9OdW1iZXIgKHZhbCkgewogICAgdmFyIG4gPSBwYXJzZUZsb2F0KHZhbCk7CiAgICByZXR1cm4gaXNOYU4obikgPyB2YWwgOiBuCiAgfQoKICAvKioKICAgKiBNYWtlIGEgbWFwIGFuZCByZXR1cm4gYSBmdW5jdGlvbiBmb3IgY2hlY2tpbmcgaWYgYSBrZXkKICAgKiBpcyBpbiB0aGF0IG1hcC4KICAgKi8KICBmdW5jdGlvbiBtYWtlTWFwICgKICAgIHN0ciwKICAgIGV4cGVjdHNMb3dlckNhc2UKICApIHsKICAgIHZhciBtYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpOwogICAgdmFyIGxpc3QgPSBzdHIuc3BsaXQoJywnKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykgewogICAgICBtYXBbbGlzdFtpXV0gPSB0cnVlOwogICAgfQogICAgcmV0dXJuIGV4cGVjdHNMb3dlckNhc2UKICAgICAgPyBmdW5jdGlvbiAodmFsKSB7IHJldHVybiBtYXBbdmFsLnRvTG93ZXJDYXNlKCldOyB9CiAgICAgIDogZnVuY3Rpb24gKHZhbCkgeyByZXR1cm4gbWFwW3ZhbF07IH0KICB9CgogIC8qKgogICAqIENoZWNrIGlmIGEgdGFnIGlzIGEgYnVpbHQtaW4gdGFnLgogICAqLwogIHZhciBpc0J1aWx0SW5UYWcgPSBtYWtlTWFwKCdzbG90LGNvbXBvbmVudCcsIHRydWUpOwoKICAvKioKICAgKiBDaGVjayBpZiBhbiBhdHRyaWJ1dGUgaXMgYSByZXNlcnZlZCBhdHRyaWJ1dGUuCiAgICovCiAgdmFyIGlzUmVzZXJ2ZWRBdHRyaWJ1dGUgPSBtYWtlTWFwKCdrZXkscmVmLHNsb3Qsc2xvdC1zY29wZSxpcycpOwoKICAvKioKICAgKiBSZW1vdmUgYW4gaXRlbSBmcm9tIGFuIGFycmF5LgogICAqLwogIGZ1bmN0aW9uIHJlbW92ZSAoYXJyLCBpdGVtKSB7CiAgICBpZiAoYXJyLmxlbmd0aCkgewogICAgICB2YXIgaW5kZXggPSBhcnIuaW5kZXhPZihpdGVtKTsKICAgICAgaWYgKGluZGV4ID4gLTEpIHsKICAgICAgICByZXR1cm4gYXJyLnNwbGljZShpbmRleCwgMSkKICAgICAgfQogICAgfQogIH0KCiAgLyoqCiAgICogQ2hlY2sgd2hldGhlciBhbiBvYmplY3QgaGFzIHRoZSBwcm9wZXJ0eS4KICAgKi8KICB2YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5OwogIGZ1bmN0aW9uIGhhc093biAob2JqLCBrZXkpIHsKICAgIHJldHVybiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KQogIH0KCiAgLyoqCiAgICogQ3JlYXRlIGEgY2FjaGVkIHZlcnNpb24gb2YgYSBwdXJlIGZ1bmN0aW9uLgogICAqLwogIGZ1bmN0aW9uIGNhY2hlZCAoZm4pIHsKICAgIHZhciBjYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7CiAgICByZXR1cm4gKGZ1bmN0aW9uIGNhY2hlZEZuIChzdHIpIHsKICAgICAgdmFyIGhpdCA9IGNhY2hlW3N0cl07CiAgICAgIHJldHVybiBoaXQgfHwgKGNhY2hlW3N0cl0gPSBmbihzdHIpKQogICAgfSkKICB9CgogIC8qKgogICAqIENhbWVsaXplIGEgaHlwaGVuLWRlbGltaXRlZCBzdHJpbmcuCiAgICovCiAgdmFyIGNhbWVsaXplUkUgPSAvLShcdykvZzsKICB2YXIgY2FtZWxpemUgPSBjYWNoZWQoZnVuY3Rpb24gKHN0cikgewogICAgcmV0dXJuIHN0ci5yZXBsYWNlKGNhbWVsaXplUkUsIGZ1bmN0aW9uIChfLCBjKSB7IHJldHVybiBjID8gYy50b1VwcGVyQ2FzZSgpIDogJyc7IH0pCiAgfSk7CgogIC8qKgogICAqIENhcGl0YWxpemUgYSBzdHJpbmcuCiAgICovCiAgdmFyIGNhcGl0YWxpemUgPSBjYWNoZWQoZnVuY3Rpb24gKHN0cikgewogICAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKQogIH0pOwoKICAvKioKICAgKiBIeXBoZW5hdGUgYSBjYW1lbENhc2Ugc3RyaW5nLgogICAqLwogIHZhciBoeXBoZW5hdGVSRSA9IC9cQihbQS1aXSkvZzsKICB2YXIgaHlwaGVuYXRlID0gY2FjaGVkKGZ1bmN0aW9uIChzdHIpIHsKICAgIHJldHVybiBzdHIucmVwbGFjZShoeXBoZW5hdGVSRSwgJy0kMScpLnRvTG93ZXJDYXNlKCkKICB9KTsKCiAgLyoqCiAgICogU2ltcGxlIGJpbmQgcG9seWZpbGwgZm9yIGVudmlyb25tZW50cyB0aGF0IGRvIG5vdCBzdXBwb3J0IGl0LAogICAqIGUuZy4sIFBoYW50b21KUyAxLnguIFRlY2huaWNhbGx5LCB3ZSBkb24ndCBuZWVkIHRoaXMgYW55bW9yZQogICAqIHNpbmNlIG5hdGl2ZSBiaW5kIGlzIG5vdyBwZXJmb3JtYW50IGVub3VnaCBpbiBtb3N0IGJyb3dzZXJzLgogICAqIEJ1dCByZW1vdmluZyBpdCB3b3VsZCBtZWFuIGJyZWFraW5nIGNvZGUgdGhhdCB3YXMgYWJsZSB0byBydW4gaW4KICAgKiBQaGFudG9tSlMgMS54LCBzbyB0aGlzIG11c3QgYmUga2VwdCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS4KICAgKi8KCiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8KICBmdW5jdGlvbiBwb2x5ZmlsbEJpbmQgKGZuLCBjdHgpIHsKICAgIGZ1bmN0aW9uIGJvdW5kRm4gKGEpIHsKICAgICAgdmFyIGwgPSBhcmd1bWVudHMubGVuZ3RoOwogICAgICByZXR1cm4gbAogICAgICAgID8gbCA+IDEKICAgICAgICAgID8gZm4uYXBwbHkoY3R4LCBhcmd1bWVudHMpCiAgICAgICAgICA6IGZuLmNhbGwoY3R4LCBhKQogICAgICAgIDogZm4uY2FsbChjdHgpCiAgICB9CgogICAgYm91bmRGbi5fbGVuZ3RoID0gZm4ubGVuZ3RoOwogICAgcmV0dXJuIGJvdW5kRm4KICB9CgogIGZ1bmN0aW9uIG5hdGl2ZUJpbmQgKGZuLCBjdHgpIHsKICAgIHJldHVybiBmbi5iaW5kKGN0eCkKICB9CgogIHZhciBiaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQKICAgID8gbmF0aXZlQmluZAogICAgOiBwb2x5ZmlsbEJpbmQ7CgogIC8qKgogICAqIENvbnZlcnQgYW4gQXJyYXktbGlrZSBvYmplY3QgdG8gYSByZWFsIEFycmF5LgogICAqLwogIGZ1bmN0aW9uIHRvQXJyYXkgKGxpc3QsIHN0YXJ0KSB7CiAgICBzdGFydCA9IHN0YXJ0IHx8IDA7CiAgICB2YXIgaSA9IGxpc3QubGVuZ3RoIC0gc3RhcnQ7CiAgICB2YXIgcmV0ID0gbmV3IEFycmF5KGkpOwogICAgd2hpbGUgKGktLSkgewogICAgICByZXRbaV0gPSBsaXN0W2kgKyBzdGFydF07CiAgICB9CiAgICByZXR1cm4gcmV0CiAgfQoKICAvKioKICAgKiBNaXggcHJvcGVydGllcyBpbnRvIHRhcmdldCBvYmplY3QuCiAgICovCiAgZnVuY3Rpb24gZXh0ZW5kICh0bywgX2Zyb20pIHsKICAgIGZvciAodmFyIGtleSBpbiBfZnJvbSkgewogICAgICB0b1trZXldID0gX2Zyb21ba2V5XTsKICAgIH0KICAgIHJldHVybiB0bwogIH0KCiAgLyoqCiAgICogTWVyZ2UgYW4gQXJyYXkgb2YgT2JqZWN0cyBpbnRvIGEgc2luZ2xlIE9iamVjdC4KICAgKi8KICBmdW5jdGlvbiB0b09iamVjdCAoYXJyKSB7CiAgICB2YXIgcmVzID0ge307CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykgewogICAgICBpZiAoYXJyW2ldKSB7CiAgICAgICAgZXh0ZW5kKHJlcywgYXJyW2ldKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlcwogIH0KCiAgLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi8KCiAgLyoqCiAgICogUGVyZm9ybSBubyBvcGVyYXRpb24uCiAgICogU3R1YmJpbmcgYXJncyB0byBtYWtlIEZsb3cgaGFwcHkgd2l0aG91dCBsZWF2aW5nIHVzZWxlc3MgdHJhbnNwaWxlZCBjb2RlCiAgICogd2l0aCAuLi5yZXN0IChodHRwczovL2Zsb3cub3JnL2Jsb2cvMjAxNy8wNS8wNy9TdHJpY3QtRnVuY3Rpb24tQ2FsbC1Bcml0eS8pLgogICAqLwogIGZ1bmN0aW9uIG5vb3AgKGEsIGIsIGMpIHt9CgogIC8qKgogICAqIEFsd2F5cyByZXR1cm4gZmFsc2UuCiAgICovCiAgdmFyIG5vID0gZnVuY3Rpb24gKGEsIGIsIGMpIHsgcmV0dXJuIGZhbHNlOyB9OwoKICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVudXNlZC12YXJzICovCgogIC8qKgogICAqIFJldHVybiB0aGUgc2FtZSB2YWx1ZS4KICAgKi8KICB2YXIgaWRlbnRpdHkgPSBmdW5jdGlvbiAoXykgeyByZXR1cm4gXzsgfTsKCiAgLyoqCiAgICogR2VuZXJhdGUgYSBzdHJpbmcgY29udGFpbmluZyBzdGF0aWMga2V5cyBmcm9tIGNvbXBpbGVyIG1vZHVsZXMuCiAgICovCiAgZnVuY3Rpb24gZ2VuU3RhdGljS2V5cyAobW9kdWxlcykgewogICAgcmV0dXJuIG1vZHVsZXMucmVkdWNlKGZ1bmN0aW9uIChrZXlzLCBtKSB7CiAgICAgIHJldHVybiBrZXlzLmNvbmNhdChtLnN0YXRpY0tleXMgfHwgW10pCiAgICB9LCBbXSkuam9pbignLCcpCiAgfQoKICAvKioKICAgKiBDaGVjayBpZiB0d28gdmFsdWVzIGFyZSBsb29zZWx5IGVxdWFsIC0gdGhhdCBpcywKICAgKiBpZiB0aGV5IGFyZSBwbGFpbiBvYmplY3RzLCBkbyB0aGV5IGhhdmUgdGhlIHNhbWUgc2hhcGU/CiAgICovCiAgZnVuY3Rpb24gbG9vc2VFcXVhbCAoYSwgYikgewogICAgaWYgKGEgPT09IGIpIHsgcmV0dXJuIHRydWUgfQogICAgdmFyIGlzT2JqZWN0QSA9IGlzT2JqZWN0KGEpOwogICAgdmFyIGlzT2JqZWN0QiA9IGlzT2JqZWN0KGIpOwogICAgaWYgKGlzT2JqZWN0QSAmJiBpc09iamVjdEIpIHsKICAgICAgdHJ5IHsKICAgICAgICB2YXIgaXNBcnJheUEgPSBBcnJheS5pc0FycmF5KGEpOwogICAgICAgIHZhciBpc0FycmF5QiA9IEFycmF5LmlzQXJyYXkoYik7CiAgICAgICAgaWYgKGlzQXJyYXlBICYmIGlzQXJyYXlCKSB7CiAgICAgICAgICByZXR1cm4gYS5sZW5ndGggPT09IGIubGVuZ3RoICYmIGEuZXZlcnkoZnVuY3Rpb24gKGUsIGkpIHsKICAgICAgICAgICAgcmV0dXJuIGxvb3NlRXF1YWwoZSwgYltpXSkKICAgICAgICAgIH0pCiAgICAgICAgfSBlbHNlIGlmIChhIGluc3RhbmNlb2YgRGF0ZSAmJiBiIGluc3RhbmNlb2YgRGF0ZSkgewogICAgICAgICAgcmV0dXJuIGEuZ2V0VGltZSgpID09PSBiLmdldFRpbWUoKQogICAgICAgIH0gZWxzZSBpZiAoIWlzQXJyYXlBICYmICFpc0FycmF5QikgewogICAgICAgICAgdmFyIGtleXNBID0gT2JqZWN0LmtleXMoYSk7CiAgICAgICAgICB2YXIga2V5c0IgPSBPYmplY3Qua2V5cyhiKTsKICAgICAgICAgIHJldHVybiBrZXlzQS5sZW5ndGggPT09IGtleXNCLmxlbmd0aCAmJiBrZXlzQS5ldmVyeShmdW5jdGlvbiAoa2V5KSB7CiAgICAgICAgICAgIHJldHVybiBsb29zZUVxdWFsKGFba2V5XSwgYltrZXldKQogICAgICAgICAgfSkKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8KICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgIH0KICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovCiAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgIH0KICAgIH0gZWxzZSBpZiAoIWlzT2JqZWN0QSAmJiAhaXNPYmplY3RCKSB7CiAgICAgIHJldHVybiBTdHJpbmcoYSkgPT09IFN0cmluZyhiKQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIGZhbHNlCiAgICB9CiAgfQoKICAvKioKICAgKiBSZXR1cm4gdGhlIGZpcnN0IGluZGV4IGF0IHdoaWNoIGEgbG9vc2VseSBlcXVhbCB2YWx1ZSBjYW4gYmUKICAgKiBmb3VuZCBpbiB0aGUgYXJyYXkgKGlmIHZhbHVlIGlzIGEgcGxhaW4gb2JqZWN0LCB0aGUgYXJyYXkgbXVzdAogICAqIGNvbnRhaW4gYW4gb2JqZWN0IG9mIHRoZSBzYW1lIHNoYXBlKSwgb3IgLTEgaWYgaXQgaXMgbm90IHByZXNlbnQuCiAgICovCiAgZnVuY3Rpb24gbG9vc2VJbmRleE9mIChhcnIsIHZhbCkgewogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKGxvb3NlRXF1YWwoYXJyW2ldLCB2YWwpKSB7IHJldHVybiBpIH0KICAgIH0KICAgIHJldHVybiAtMQogIH0KCiAgLyoqCiAgICogRW5zdXJlIGEgZnVuY3Rpb24gaXMgY2FsbGVkIG9ubHkgb25jZS4KICAgKi8KICBmdW5jdGlvbiBvbmNlIChmbikgewogICAgdmFyIGNhbGxlZCA9IGZhbHNlOwogICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsKICAgICAgaWYgKCFjYWxsZWQpIHsKICAgICAgICBjYWxsZWQgPSB0cnVlOwogICAgICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgIH0KICAgIH0KICB9CgogIHZhciBTU1JfQVRUUiA9ICdkYXRhLXNlcnZlci1yZW5kZXJlZCc7CgogIHZhciBBU1NFVF9UWVBFUyA9IFsKICAgICdjb21wb25lbnQnLAogICAgJ2RpcmVjdGl2ZScsCiAgICAnZmlsdGVyJwogIF07CgogIHZhciBMSUZFQ1lDTEVfSE9PS1MgPSBbCiAgICAnYmVmb3JlQ3JlYXRlJywKICAgICdjcmVhdGVkJywKICAgICdiZWZvcmVNb3VudCcsCiAgICAnbW91bnRlZCcsCiAgICAnYmVmb3JlVXBkYXRlJywKICAgICd1cGRhdGVkJywKICAgICdiZWZvcmVEZXN0cm95JywKICAgICdkZXN0cm95ZWQnLAogICAgJ2FjdGl2YXRlZCcsCiAgICAnZGVhY3RpdmF0ZWQnLAogICAgJ2Vycm9yQ2FwdHVyZWQnLAogICAgJ3NlcnZlclByZWZldGNoJwogIF07CgogIC8qICAqLwoKCgogIHZhciBjb25maWcgPSAoewogICAgLyoqCiAgICAgKiBPcHRpb24gbWVyZ2Ugc3RyYXRlZ2llcyAodXNlZCBpbiBjb3JlL3V0aWwvb3B0aW9ucykKICAgICAqLwogICAgLy8gJGZsb3ctZGlzYWJsZS1saW5lCiAgICBvcHRpb25NZXJnZVN0cmF0ZWdpZXM6IE9iamVjdC5jcmVhdGUobnVsbCksCgogICAgLyoqCiAgICAgKiBXaGV0aGVyIHRvIHN1cHByZXNzIHdhcm5pbmdzLgogICAgICovCiAgICBzaWxlbnQ6IGZhbHNlLAoKICAgIC8qKgogICAgICogU2hvdyBwcm9kdWN0aW9uIG1vZGUgdGlwIG1lc3NhZ2Ugb24gYm9vdD8KICAgICAqLwogICAgcHJvZHVjdGlvblRpcDogImRldmVsb3BtZW50IiAhPT0gJ3Byb2R1Y3Rpb24nLAoKICAgIC8qKgogICAgICogV2hldGhlciB0byBlbmFibGUgZGV2dG9vbHMKICAgICAqLwogICAgZGV2dG9vbHM6ICJkZXZlbG9wbWVudCIgIT09ICdwcm9kdWN0aW9uJywKCiAgICAvKioKICAgICAqIFdoZXRoZXIgdG8gcmVjb3JkIHBlcmYKICAgICAqLwogICAgcGVyZm9ybWFuY2U6IGZhbHNlLAoKICAgIC8qKgogICAgICogRXJyb3IgaGFuZGxlciBmb3Igd2F0Y2hlciBlcnJvcnMKICAgICAqLwogICAgZXJyb3JIYW5kbGVyOiBudWxsLAoKICAgIC8qKgogICAgICogV2FybiBoYW5kbGVyIGZvciB3YXRjaGVyIHdhcm5zCiAgICAgKi8KICAgIHdhcm5IYW5kbGVyOiBudWxsLAoKICAgIC8qKgogICAgICogSWdub3JlIGNlcnRhaW4gY3VzdG9tIGVsZW1lbnRzCiAgICAgKi8KICAgIGlnbm9yZWRFbGVtZW50czogW10sCgogICAgLyoqCiAgICAgKiBDdXN0b20gdXNlciBrZXkgYWxpYXNlcyBmb3Igdi1vbgogICAgICovCiAgICAvLyAkZmxvdy1kaXNhYmxlLWxpbmUKICAgIGtleUNvZGVzOiBPYmplY3QuY3JlYXRlKG51bGwpLAoKICAgIC8qKgogICAgICogQ2hlY2sgaWYgYSB0YWcgaXMgcmVzZXJ2ZWQgc28gdGhhdCBpdCBjYW5ub3QgYmUgcmVnaXN0ZXJlZCBhcyBhCiAgICAgKiBjb21wb25lbnQuIFRoaXMgaXMgcGxhdGZvcm0tZGVwZW5kZW50IGFuZCBtYXkgYmUgb3ZlcndyaXR0ZW4uCiAgICAgKi8KICAgIGlzUmVzZXJ2ZWRUYWc6IG5vLAoKICAgIC8qKgogICAgICogQ2hlY2sgaWYgYW4gYXR0cmlidXRlIGlzIHJlc2VydmVkIHNvIHRoYXQgaXQgY2Fubm90IGJlIHVzZWQgYXMgYSBjb21wb25lbnQKICAgICAqIHByb3AuIFRoaXMgaXMgcGxhdGZvcm0tZGVwZW5kZW50IGFuZCBtYXkgYmUgb3ZlcndyaXR0ZW4uCiAgICAgKi8KICAgIGlzUmVzZXJ2ZWRBdHRyOiBubywKCiAgICAvKioKICAgICAqIENoZWNrIGlmIGEgdGFnIGlzIGFuIHVua25vd24gZWxlbWVudC4KICAgICAqIFBsYXRmb3JtLWRlcGVuZGVudC4KICAgICAqLwogICAgaXNVbmtub3duRWxlbWVudDogbm8sCgogICAgLyoqCiAgICAgKiBHZXQgdGhlIG5hbWVzcGFjZSBvZiBhbiBlbGVtZW50CiAgICAgKi8KICAgIGdldFRhZ05hbWVzcGFjZTogbm9vcCwKCiAgICAvKioKICAgICAqIFBhcnNlIHRoZSByZWFsIHRhZyBuYW1lIGZvciB0aGUgc3BlY2lmaWMgcGxhdGZvcm0uCiAgICAgKi8KICAgIHBhcnNlUGxhdGZvcm1UYWdOYW1lOiBpZGVudGl0eSwKCiAgICAvKioKICAgICAqIENoZWNrIGlmIGFuIGF0dHJpYnV0ZSBtdXN0IGJlIGJvdW5kIHVzaW5nIHByb3BlcnR5LCBlLmcuIHZhbHVlCiAgICAgKiBQbGF0Zm9ybS1kZXBlbmRlbnQuCiAgICAgKi8KICAgIG11c3RVc2VQcm9wOiBubywKCiAgICAvKioKICAgICAqIFBlcmZvcm0gdXBkYXRlcyBhc3luY2hyb25vdXNseS4gSW50ZW5kZWQgdG8gYmUgdXNlZCBieSBWdWUgVGVzdCBVdGlscwogICAgICogVGhpcyB3aWxsIHNpZ25pZmljYW50bHkgcmVkdWNlIHBlcmZvcm1hbmNlIGlmIHNldCB0byBmYWxzZS4KICAgICAqLwogICAgYXN5bmM6IHRydWUsCgogICAgLyoqCiAgICAgKiBFeHBvc2VkIGZvciBsZWdhY3kgcmVhc29ucwogICAgICovCiAgICBfbGlmZWN5Y2xlSG9va3M6IExJRkVDWUNMRV9IT09LUwogIH0pOwoKICAvKiAgKi8KCiAgLyoqCiAgICogdW5pY29kZSBsZXR0ZXJzIHVzZWQgZm9yIHBhcnNpbmcgaHRtbCB0YWdzLCBjb21wb25lbnQgbmFtZXMgYW5kIHByb3BlcnR5IHBhdGhzLgogICAqIHVzaW5nIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9odG1sNTMvc2VtYW50aWNzLXNjcmlwdGluZy5odG1sI3BvdGVudGlhbGN1c3RvbWVsZW1lbnRuYW1lCiAgICogc2tpcHBpbmcgXHUxMDAwMC1cdUVGRkZGIGR1ZSB0byBpdCBmcmVlemluZyB1cCBQaGFudG9tSlMKICAgKi8KICB2YXIgdW5pY29kZVJlZ0V4cCA9IC9hLXpBLVpcdTAwQjdcdTAwQzAtXHUwMEQ2XHUwMEQ4LVx1MDBGNlx1MDBGOC1cdTAzN0RcdTAzN0YtXHUxRkZGXHUyMDBDLVx1MjAwRFx1MjAzRi1cdTIwNDBcdTIwNzAtXHUyMThGXHUyQzAwLVx1MkZFRlx1MzAwMS1cdUQ3RkZcdUY5MDAtXHVGRENGXHVGREYwLVx1RkZGRC87CgogIC8qKgogICAqIENoZWNrIGlmIGEgc3RyaW5nIHN0YXJ0cyB3aXRoICQgb3IgXwogICAqLwogIGZ1bmN0aW9uIGlzUmVzZXJ2ZWQgKHN0cikgewogICAgdmFyIGMgPSAoc3RyICsgJycpLmNoYXJDb2RlQXQoMCk7CiAgICByZXR1cm4gYyA9PT0gMHgyNCB8fCBjID09PSAweDVGCiAgfQoKICAvKioKICAgKiBEZWZpbmUgYSBwcm9wZXJ0eS4KICAgKi8KICBmdW5jdGlvbiBkZWYgKG9iaiwga2V5LCB2YWwsIGVudW1lcmFibGUpIHsKICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgewogICAgICB2YWx1ZTogdmFsLAogICAgICBlbnVtZXJhYmxlOiAhIWVudW1lcmFibGUsCiAgICAgIHdyaXRhYmxlOiB0cnVlLAogICAgICBjb25maWd1cmFibGU6IHRydWUKICAgIH0pOwogIH0KCiAgLyoqCiAgICogUGFyc2Ugc2ltcGxlIHBhdGguCiAgICovCiAgdmFyIGJhaWxSRSA9IG5ldyBSZWdFeHAoKCJbXiIgKyAodW5pY29kZVJlZ0V4cC5zb3VyY2UpICsgIi4kX1xcZF0iKSk7CiAgZnVuY3Rpb24gcGFyc2VQYXRoIChwYXRoKSB7CiAgICBpZiAoYmFpbFJFLnRlc3QocGF0aCkpIHsKICAgICAgcmV0dXJuCiAgICB9CiAgICB2YXIgc2VnbWVudHMgPSBwYXRoLnNwbGl0KCcuJyk7CiAgICByZXR1cm4gZnVuY3Rpb24gKG9iaikgewogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgaWYgKCFvYmopIHsgcmV0dXJuIH0KICAgICAgICBvYmogPSBvYmpbc2VnbWVudHNbaV1dOwogICAgICB9CiAgICAgIHJldHVybiBvYmoKICAgIH0KICB9CgogIC8qICAqLwoKICAvLyBjYW4gd2UgdXNlIF9fcHJvdG9fXz8KICB2YXIgaGFzUHJvdG8gPSAnX19wcm90b19fJyBpbiB7fTsKCiAgLy8gQnJvd3NlciBlbnZpcm9ubWVudCBzbmlmZmluZwogIHZhciBpbkJyb3dzZXIgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJzsKICB2YXIgaW5XZWV4ID0gdHlwZW9mIFdYRW52aXJvbm1lbnQgIT09ICd1bmRlZmluZWQnICYmICEhV1hFbnZpcm9ubWVudC5wbGF0Zm9ybTsKICB2YXIgd2VleFBsYXRmb3JtID0gaW5XZWV4ICYmIFdYRW52aXJvbm1lbnQucGxhdGZvcm0udG9Mb3dlckNhc2UoKTsKICB2YXIgVUEgPSBpbkJyb3dzZXIgJiYgd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKTsKICB2YXIgaXNJRSA9IFVBICYmIC9tc2llfHRyaWRlbnQvLnRlc3QoVUEpOwogIHZhciBpc0lFOSA9IFVBICYmIFVBLmluZGV4T2YoJ21zaWUgOS4wJykgPiAwOwogIHZhciBpc0VkZ2UgPSBVQSAmJiBVQS5pbmRleE9mKCdlZGdlLycpID4gMDsKICB2YXIgaXNBbmRyb2lkID0gKFVBICYmIFVBLmluZGV4T2YoJ2FuZHJvaWQnKSA+IDApIHx8ICh3ZWV4UGxhdGZvcm0gPT09ICdhbmRyb2lkJyk7CiAgdmFyIGlzSU9TID0gKFVBICYmIC9pcGhvbmV8aXBhZHxpcG9kfGlvcy8udGVzdChVQSkpIHx8ICh3ZWV4UGxhdGZvcm0gPT09ICdpb3MnKTsKICB2YXIgaXNDaHJvbWUgPSBVQSAmJiAvY2hyb21lXC9cZCsvLnRlc3QoVUEpICYmICFpc0VkZ2U7CiAgdmFyIGlzUGhhbnRvbUpTID0gVUEgJiYgL3BoYW50b21qcy8udGVzdChVQSk7CiAgdmFyIGlzRkYgPSBVQSAmJiBVQS5tYXRjaCgvZmlyZWZveFwvKFxkKykvKTsKCiAgLy8gRmlyZWZveCBoYXMgYSAid2F0Y2giIGZ1bmN0aW9uIG9uIE9iamVjdC5wcm90b3R5cGUuLi4KICB2YXIgbmF0aXZlV2F0Y2ggPSAoe30pLndhdGNoOwoKICB2YXIgc3VwcG9ydHNQYXNzaXZlID0gZmFsc2U7CiAgaWYgKGluQnJvd3NlcikgewogICAgdHJ5IHsKICAgICAgdmFyIG9wdHMgPSB7fTsKICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9wdHMsICdwYXNzaXZlJywgKHsKICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCAoKSB7CiAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLwogICAgICAgICAgc3VwcG9ydHNQYXNzaXZlID0gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0pKTsgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2Zsb3cvaXNzdWVzLzI4NQogICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndGVzdC1wYXNzaXZlJywgbnVsbCwgb3B0cyk7CiAgICB9IGNhdGNoIChlKSB7fQogIH0KCiAgLy8gdGhpcyBuZWVkcyB0byBiZSBsYXp5LWV2YWxlZCBiZWNhdXNlIHZ1ZSBtYXkgYmUgcmVxdWlyZWQgYmVmb3JlCiAgLy8gdnVlLXNlcnZlci1yZW5kZXJlciBjYW4gc2V0IFZVRV9FTlYKICB2YXIgX2lzU2VydmVyOwogIHZhciBpc1NlcnZlclJlbmRlcmluZyA9IGZ1bmN0aW9uICgpIHsKICAgIGlmIChfaXNTZXJ2ZXIgPT09IHVuZGVmaW5lZCkgewogICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgICAgaWYgKCFpbkJyb3dzZXIgJiYgIWluV2VleCAmJiB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJykgewogICAgICAgIC8vIGRldGVjdCBwcmVzZW5jZSBvZiB2dWUtc2VydmVyLXJlbmRlcmVyIGFuZCBhdm9pZAogICAgICAgIC8vIFdlYnBhY2sgc2hpbW1pbmcgdGhlIHByb2Nlc3MKICAgICAgICBfaXNTZXJ2ZXIgPSBnbG9iYWxbJ3Byb2Nlc3MnXSAmJiBnbG9iYWxbJ3Byb2Nlc3MnXS5lbnYuVlVFX0VOViA9PT0gJ3NlcnZlcic7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgX2lzU2VydmVyID0gZmFsc2U7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBfaXNTZXJ2ZXIKICB9OwoKICAvLyBkZXRlY3QgZGV2dG9vbHMKICB2YXIgZGV2dG9vbHMgPSBpbkJyb3dzZXIgJiYgd2luZG93Ll9fVlVFX0RFVlRPT0xTX0dMT0JBTF9IT09LX187CgogIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovCiAgZnVuY3Rpb24gaXNOYXRpdmUgKEN0b3IpIHsKICAgIHJldHVybiB0eXBlb2YgQ3RvciA9PT0gJ2Z1bmN0aW9uJyAmJiAvbmF0aXZlIGNvZGUvLnRlc3QoQ3Rvci50b1N0cmluZygpKQogIH0KCiAgdmFyIGhhc1N5bWJvbCA9CiAgICB0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBpc05hdGl2ZShTeW1ib2wpICYmCiAgICB0eXBlb2YgUmVmbGVjdCAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNOYXRpdmUoUmVmbGVjdC5vd25LZXlzKTsKCiAgdmFyIF9TZXQ7CiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovIC8vICRmbG93LWRpc2FibGUtbGluZQogIGlmICh0eXBlb2YgU2V0ICE9PSAndW5kZWZpbmVkJyAmJiBpc05hdGl2ZShTZXQpKSB7CiAgICAvLyB1c2UgbmF0aXZlIFNldCB3aGVuIGF2YWlsYWJsZS4KICAgIF9TZXQgPSBTZXQ7CiAgfSBlbHNlIHsKICAgIC8vIGEgbm9uLXN0YW5kYXJkIFNldCBwb2x5ZmlsbCB0aGF0IG9ubHkgd29ya3Mgd2l0aCBwcmltaXRpdmUga2V5cy4KICAgIF9TZXQgPSAvKkBfX1BVUkVfXyovKGZ1bmN0aW9uICgpIHsKICAgICAgZnVuY3Rpb24gU2V0ICgpIHsKICAgICAgICB0aGlzLnNldCA9IE9iamVjdC5jcmVhdGUobnVsbCk7CiAgICAgIH0KICAgICAgU2V0LnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiBoYXMgKGtleSkgewogICAgICAgIHJldHVybiB0aGlzLnNldFtrZXldID09PSB0cnVlCiAgICAgIH07CiAgICAgIFNldC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkIChrZXkpIHsKICAgICAgICB0aGlzLnNldFtrZXldID0gdHJ1ZTsKICAgICAgfTsKICAgICAgU2V0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uIGNsZWFyICgpIHsKICAgICAgICB0aGlzLnNldCA9IE9iamVjdC5jcmVhdGUobnVsbCk7CiAgICAgIH07CgogICAgICByZXR1cm4gU2V0OwogICAgfSgpKTsKICB9CgogIC8qICAqLwoKICB2YXIgd2FybiA9IG5vb3A7CiAgdmFyIHRpcCA9IG5vb3A7CiAgdmFyIGdlbmVyYXRlQ29tcG9uZW50VHJhY2UgPSAobm9vcCk7IC8vIHdvcmsgYXJvdW5kIGZsb3cgY2hlY2sKICB2YXIgZm9ybWF0Q29tcG9uZW50TmFtZSA9IChub29wKTsKCiAgewogICAgdmFyIGhhc0NvbnNvbGUgPSB0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCc7CiAgICB2YXIgY2xhc3NpZnlSRSA9IC8oPzpefFstX10pKFx3KS9nOwogICAgdmFyIGNsYXNzaWZ5ID0gZnVuY3Rpb24gKHN0cikgeyByZXR1cm4gc3RyCiAgICAgIC5yZXBsYWNlKGNsYXNzaWZ5UkUsIGZ1bmN0aW9uIChjKSB7IHJldHVybiBjLnRvVXBwZXJDYXNlKCk7IH0pCiAgICAgIC5yZXBsYWNlKC9bLV9dL2csICcnKTsgfTsKCiAgICB3YXJuID0gZnVuY3Rpb24gKG1zZywgdm0pIHsKICAgICAgdmFyIHRyYWNlID0gdm0gPyBnZW5lcmF0ZUNvbXBvbmVudFRyYWNlKHZtKSA6ICcnOwoKICAgICAgaWYgKGNvbmZpZy53YXJuSGFuZGxlcikgewogICAgICAgIGNvbmZpZy53YXJuSGFuZGxlci5jYWxsKG51bGwsIG1zZywgdm0sIHRyYWNlKTsKICAgICAgfSBlbHNlIGlmIChoYXNDb25zb2xlICYmICghY29uZmlnLnNpbGVudCkpIHsKICAgICAgICBjb25zb2xlLmVycm9yKCgiW1Z1ZSB3YXJuXTogIiArIG1zZyArIHRyYWNlKSk7CiAgICAgIH0KICAgIH07CgogICAgdGlwID0gZnVuY3Rpb24gKG1zZywgdm0pIHsKICAgICAgaWYgKGhhc0NvbnNvbGUgJiYgKCFjb25maWcuc2lsZW50KSkgewogICAgICAgIGNvbnNvbGUud2FybigiW1Z1ZSB0aXBdOiAiICsgbXNnICsgKAogICAgICAgICAgdm0gPyBnZW5lcmF0ZUNvbXBvbmVudFRyYWNlKHZtKSA6ICcnCiAgICAgICAgKSk7CiAgICAgIH0KICAgIH07CgogICAgZm9ybWF0Q29tcG9uZW50TmFtZSA9IGZ1bmN0aW9uICh2bSwgaW5jbHVkZUZpbGUpIHsKICAgICAgaWYgKHZtLiRyb290ID09PSB2bSkgewogICAgICAgIHJldHVybiAnPFJvb3Q+JwogICAgICB9CiAgICAgIHZhciBvcHRpb25zID0gdHlwZW9mIHZtID09PSAnZnVuY3Rpb24nICYmIHZtLmNpZCAhPSBudWxsCiAgICAgICAgPyB2bS5vcHRpb25zCiAgICAgICAgOiB2bS5faXNWdWUKICAgICAgICAgID8gdm0uJG9wdGlvbnMgfHwgdm0uY29uc3RydWN0b3Iub3B0aW9ucwogICAgICAgICAgOiB2bTsKICAgICAgdmFyIG5hbWUgPSBvcHRpb25zLm5hbWUgfHwgb3B0aW9ucy5fY29tcG9uZW50VGFnOwogICAgICB2YXIgZmlsZSA9IG9wdGlvbnMuX19maWxlOwogICAgICBpZiAoIW5hbWUgJiYgZmlsZSkgewogICAgICAgIHZhciBtYXRjaCA9IGZpbGUubWF0Y2goLyhbXi9cXF0rKVwudnVlJC8pOwogICAgICAgIG5hbWUgPSBtYXRjaCAmJiBtYXRjaFsxXTsKICAgICAgfQoKICAgICAgcmV0dXJuICgKICAgICAgICAobmFtZSA/ICgiPCIgKyAoY2xhc3NpZnkobmFtZSkpICsgIj4iKSA6ICI8QW5vbnltb3VzPiIpICsKICAgICAgICAoZmlsZSAmJiBpbmNsdWRlRmlsZSAhPT0gZmFsc2UgPyAoIiBhdCAiICsgZmlsZSkgOiAnJykKICAgICAgKQogICAgfTsKCiAgICB2YXIgcmVwZWF0ID0gZnVuY3Rpb24gKHN0ciwgbikgewogICAgICB2YXIgcmVzID0gJyc7CiAgICAgIHdoaWxlIChuKSB7CiAgICAgICAgaWYgKG4gJSAyID09PSAxKSB7IHJlcyArPSBzdHI7IH0KICAgICAgICBpZiAobiA+IDEpIHsgc3RyICs9IHN0cjsgfQogICAgICAgIG4gPj49IDE7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlcwogICAgfTsKCiAgICBnZW5lcmF0ZUNvbXBvbmVudFRyYWNlID0gZnVuY3Rpb24gKHZtKSB7CiAgICAgIGlmICh2bS5faXNWdWUgJiYgdm0uJHBhcmVudCkgewogICAgICAgIHZhciB0cmVlID0gW107CiAgICAgICAgdmFyIGN1cnJlbnRSZWN1cnNpdmVTZXF1ZW5jZSA9IDA7CiAgICAgICAgd2hpbGUgKHZtKSB7CiAgICAgICAgICBpZiAodHJlZS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgIHZhciBsYXN0ID0gdHJlZVt0cmVlLmxlbmd0aCAtIDFdOwogICAgICAgICAgICBpZiAobGFzdC5jb25zdHJ1Y3RvciA9PT0gdm0uY29uc3RydWN0b3IpIHsKICAgICAgICAgICAgICBjdXJyZW50UmVjdXJzaXZlU2VxdWVuY2UrKzsKICAgICAgICAgICAgICB2bSA9IHZtLiRwYXJlbnQ7CiAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50UmVjdXJzaXZlU2VxdWVuY2UgPiAwKSB7CiAgICAgICAgICAgICAgdHJlZVt0cmVlLmxlbmd0aCAtIDFdID0gW2xhc3QsIGN1cnJlbnRSZWN1cnNpdmVTZXF1ZW5jZV07CiAgICAgICAgICAgICAgY3VycmVudFJlY3Vyc2l2ZVNlcXVlbmNlID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgdHJlZS5wdXNoKHZtKTsKICAgICAgICAgIHZtID0gdm0uJHBhcmVudDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICdcblxuZm91bmQgaW5cblxuJyArIHRyZWUKICAgICAgICAgIC5tYXAoZnVuY3Rpb24gKHZtLCBpKSB7IHJldHVybiAoIiIgKyAoaSA9PT0gMCA/ICctLS0+ICcgOiByZXBlYXQoJyAnLCA1ICsgaSAqIDIpKSArIChBcnJheS5pc0FycmF5KHZtKQogICAgICAgICAgICAgID8gKChmb3JtYXRDb21wb25lbnROYW1lKHZtWzBdKSkgKyAiLi4uICgiICsgKHZtWzFdKSArICIgcmVjdXJzaXZlIGNhbGxzKSIpCiAgICAgICAgICAgICAgOiBmb3JtYXRDb21wb25lbnROYW1lKHZtKSkpOyB9KQogICAgICAgICAgLmpvaW4oJ1xuJykKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKCJcblxuKGZvdW5kIGluICIgKyAoZm9ybWF0Q29tcG9uZW50TmFtZSh2bSkpICsgIikiKQogICAgICB9CiAgICB9OwogIH0KCiAgLyogICovCgogIHZhciB1aWQgPSAwOwoKICAvKioKICAgKiBBIGRlcCBpcyBhbiBvYnNlcnZhYmxlIHRoYXQgY2FuIGhhdmUgbXVsdGlwbGUKICAgKiBkaXJlY3RpdmVzIHN1YnNjcmliaW5nIHRvIGl0LgogICAqLwogIHZhciBEZXAgPSBmdW5jdGlvbiBEZXAgKCkgewogICAgdGhpcy5pZCA9IHVpZCsrOwogICAgdGhpcy5zdWJzID0gW107CiAgfTsKCiAgRGVwLnByb3RvdHlwZS5hZGRTdWIgPSBmdW5jdGlvbiBhZGRTdWIgKHN1YikgewogICAgdGhpcy5zdWJzLnB1c2goc3ViKTsKICB9OwoKICBEZXAucHJvdG90eXBlLnJlbW92ZVN1YiA9IGZ1bmN0aW9uIHJlbW92ZVN1YiAoc3ViKSB7CiAgICByZW1vdmUodGhpcy5zdWJzLCBzdWIpOwogIH07CgogIERlcC5wcm90b3R5cGUuZGVwZW5kID0gZnVuY3Rpb24gZGVwZW5kICgpIHsKICAgIGlmIChEZXAudGFyZ2V0KSB7CiAgICAgIERlcC50YXJnZXQuYWRkRGVwKHRoaXMpOwogICAgfQogIH07CgogIERlcC5wcm90b3R5cGUubm90aWZ5ID0gZnVuY3Rpb24gbm90aWZ5ICgpIHsKICAgIC8vIHN0YWJpbGl6ZSB0aGUgc3Vic2NyaWJlciBsaXN0IGZpcnN0CiAgICB2YXIgc3VicyA9IHRoaXMuc3Vicy5zbGljZSgpOwogICAgaWYgKCFjb25maWcuYXN5bmMpIHsKICAgICAgLy8gc3VicyBhcmVuJ3Qgc29ydGVkIGluIHNjaGVkdWxlciBpZiBub3QgcnVubmluZyBhc3luYwogICAgICAvLyB3ZSBuZWVkIHRvIHNvcnQgdGhlbSBub3cgdG8gbWFrZSBzdXJlIHRoZXkgZmlyZSBpbiBjb3JyZWN0CiAgICAgIC8vIG9yZGVyCiAgICAgIHN1YnMuc29ydChmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYS5pZCAtIGIuaWQ7IH0pOwogICAgfQogICAgZm9yICh2YXIgaSA9IDAsIGwgPSBzdWJzLmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICBzdWJzW2ldLnVwZGF0ZSgpOwogICAgfQogIH07CgogIC8vIFRoZSBjdXJyZW50IHRhcmdldCB3YXRjaGVyIGJlaW5nIGV2YWx1YXRlZC4KICAvLyBUaGlzIGlzIGdsb2JhbGx5IHVuaXF1ZSBiZWNhdXNlIG9ubHkgb25lIHdhdGNoZXIKICAvLyBjYW4gYmUgZXZhbHVhdGVkIGF0IGEgdGltZS4KICBEZXAudGFyZ2V0ID0gbnVsbDsKICB2YXIgdGFyZ2V0U3RhY2sgPSBbXTsKCiAgZnVuY3Rpb24gcHVzaFRhcmdldCAodGFyZ2V0KSB7CiAgICB0YXJnZXRTdGFjay5wdXNoKHRhcmdldCk7CiAgICBEZXAudGFyZ2V0ID0gdGFyZ2V0OwogIH0KCiAgZnVuY3Rpb24gcG9wVGFyZ2V0ICgpIHsKICAgIHRhcmdldFN0YWNrLnBvcCgpOwogICAgRGVwLnRhcmdldCA9IHRhcmdldFN0YWNrW3RhcmdldFN0YWNrLmxlbmd0aCAtIDFdOwogIH0KCiAgLyogICovCgogIHZhciBWTm9kZSA9IGZ1bmN0aW9uIFZOb2RlICgKICAgIHRhZywKICAgIGRhdGEsCiAgICBjaGlsZHJlbiwKICAgIHRleHQsCiAgICBlbG0sCiAgICBjb250ZXh0LAogICAgY29tcG9uZW50T3B0aW9ucywKICAgIGFzeW5jRmFjdG9yeQogICkgewogICAgdGhpcy50YWcgPSB0YWc7CiAgICB0aGlzLmRhdGEgPSBkYXRhOwogICAgdGhpcy5jaGlsZHJlbiA9IGNoaWxkcmVuOwogICAgdGhpcy50ZXh0ID0gdGV4dDsKICAgIHRoaXMuZWxtID0gZWxtOwogICAgdGhpcy5ucyA9IHVuZGVmaW5lZDsKICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CiAgICB0aGlzLmZuQ29udGV4dCA9IHVuZGVmaW5lZDsKICAgIHRoaXMuZm5PcHRpb25zID0gdW5kZWZpbmVkOwogICAgdGhpcy5mblNjb3BlSWQgPSB1bmRlZmluZWQ7CiAgICB0aGlzLmtleSA9IGRhdGEgJiYgZGF0YS5rZXk7CiAgICB0aGlzLmNvbXBvbmVudE9wdGlvbnMgPSBjb21wb25lbnRPcHRpb25zOwogICAgdGhpcy5jb21wb25lbnRJbnN0YW5jZSA9IHVuZGVmaW5lZDsKICAgIHRoaXMucGFyZW50ID0gdW5kZWZpbmVkOwogICAgdGhpcy5yYXcgPSBmYWxzZTsKICAgIHRoaXMuaXNTdGF0aWMgPSBmYWxzZTsKICAgIHRoaXMuaXNSb290SW5zZXJ0ID0gdHJ1ZTsKICAgIHRoaXMuaXNDb21tZW50ID0gZmFsc2U7CiAgICB0aGlzLmlzQ2xvbmVkID0gZmFsc2U7CiAgICB0aGlzLmlzT25jZSA9IGZhbHNlOwogICAgdGhpcy5hc3luY0ZhY3RvcnkgPSBhc3luY0ZhY3Rvcnk7CiAgICB0aGlzLmFzeW5jTWV0YSA9IHVuZGVmaW5lZDsKICAgIHRoaXMuaXNBc3luY1BsYWNlaG9sZGVyID0gZmFsc2U7CiAgfTsKCiAgdmFyIHByb3RvdHlwZUFjY2Vzc29ycyA9IHsgY2hpbGQ6IHsgY29uZmlndXJhYmxlOiB0cnVlIH0gfTsKCiAgLy8gREVQUkVDQVRFRDogYWxpYXMgZm9yIGNvbXBvbmVudEluc3RhbmNlIGZvciBiYWNrd2FyZHMgY29tcGF0LgogIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovCiAgcHJvdG90eXBlQWNjZXNzb3JzLmNoaWxkLmdldCA9IGZ1bmN0aW9uICgpIHsKICAgIHJldHVybiB0aGlzLmNvbXBvbmVudEluc3RhbmNlCiAgfTsKCiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIFZOb2RlLnByb3RvdHlwZSwgcHJvdG90eXBlQWNjZXNzb3JzICk7CgogIHZhciBjcmVhdGVFbXB0eVZOb2RlID0gZnVuY3Rpb24gKHRleHQpIHsKICAgIGlmICggdGV4dCA9PT0gdm9pZCAwICkgdGV4dCA9ICcnOwoKICAgIHZhciBub2RlID0gbmV3IFZOb2RlKCk7CiAgICBub2RlLnRleHQgPSB0ZXh0OwogICAgbm9kZS5pc0NvbW1lbnQgPSB0cnVlOwogICAgcmV0dXJuIG5vZGUKICB9OwoKICBmdW5jdGlvbiBjcmVhdGVUZXh0Vk5vZGUgKHZhbCkgewogICAgcmV0dXJuIG5ldyBWTm9kZSh1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBTdHJpbmcodmFsKSkKICB9CgogIC8vIG9wdGltaXplZCBzaGFsbG93IGNsb25lCiAgLy8gdXNlZCBmb3Igc3RhdGljIG5vZGVzIGFuZCBzbG90IG5vZGVzIGJlY2F1c2UgdGhleSBtYXkgYmUgcmV1c2VkIGFjcm9zcwogIC8vIG11bHRpcGxlIHJlbmRlcnMsIGNsb25pbmcgdGhlbSBhdm9pZHMgZXJyb3JzIHdoZW4gRE9NIG1hbmlwdWxhdGlvbnMgcmVseQogIC8vIG9uIHRoZWlyIGVsbSByZWZlcmVuY2UuCiAgZnVuY3Rpb24gY2xvbmVWTm9kZSAodm5vZGUpIHsKICAgIHZhciBjbG9uZWQgPSBuZXcgVk5vZGUoCiAgICAgIHZub2RlLnRhZywKICAgICAgdm5vZGUuZGF0YSwKICAgICAgLy8gIzc5NzUKICAgICAgLy8gY2xvbmUgY2hpbGRyZW4gYXJyYXkgdG8gYXZvaWQgbXV0YXRpbmcgb3JpZ2luYWwgaW4gY2FzZSBvZiBjbG9uaW5nCiAgICAgIC8vIGEgY2hpbGQuCiAgICAgIHZub2RlLmNoaWxkcmVuICYmIHZub2RlLmNoaWxkcmVuLnNsaWNlKCksCiAgICAgIHZub2RlLnRleHQsCiAgICAgIHZub2RlLmVsbSwKICAgICAgdm5vZGUuY29udGV4dCwKICAgICAgdm5vZGUuY29tcG9uZW50T3B0aW9ucywKICAgICAgdm5vZGUuYXN5bmNGYWN0b3J5CiAgICApOwogICAgY2xvbmVkLm5zID0gdm5vZGUubnM7CiAgICBjbG9uZWQuaXNTdGF0aWMgPSB2bm9kZS5pc1N0YXRpYzsKICAgIGNsb25lZC5rZXkgPSB2bm9kZS5rZXk7CiAgICBjbG9uZWQuaXNDb21tZW50ID0gdm5vZGUuaXNDb21tZW50OwogICAgY2xvbmVkLmZuQ29udGV4dCA9IHZub2RlLmZuQ29udGV4dDsKICAgIGNsb25lZC5mbk9wdGlvbnMgPSB2bm9kZS5mbk9wdGlvbnM7CiAgICBjbG9uZWQuZm5TY29wZUlkID0gdm5vZGUuZm5TY29wZUlkOwogICAgY2xvbmVkLmFzeW5jTWV0YSA9IHZub2RlLmFzeW5jTWV0YTsKICAgIGNsb25lZC5pc0Nsb25lZCA9IHRydWU7CiAgICByZXR1cm4gY2xvbmVkCiAgfQoKICAvKgogICAqIG5vdCB0eXBlIGNoZWNraW5nIHRoaXMgZmlsZSBiZWNhdXNlIGZsb3cgZG9lc24ndCBwbGF5IHdlbGwgd2l0aAogICAqIGR5bmFtaWNhbGx5IGFjY2Vzc2luZyBtZXRob2RzIG9uIEFycmF5IHByb3RvdHlwZQogICAqLwoKICB2YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTsKICB2YXIgYXJyYXlNZXRob2RzID0gT2JqZWN0LmNyZWF0ZShhcnJheVByb3RvKTsKCiAgdmFyIG1ldGhvZHNUb1BhdGNoID0gWwogICAgJ3B1c2gnLAogICAgJ3BvcCcsCiAgICAnc2hpZnQnLAogICAgJ3Vuc2hpZnQnLAogICAgJ3NwbGljZScsCiAgICAnc29ydCcsCiAgICAncmV2ZXJzZScKICBdOwoKICAvKioKICAgKiBJbnRlcmNlcHQgbXV0YXRpbmcgbWV0aG9kcyBhbmQgZW1pdCBldmVudHMKICAgKi8KICBtZXRob2RzVG9QYXRjaC5mb3JFYWNoKGZ1bmN0aW9uIChtZXRob2QpIHsKICAgIC8vIGNhY2hlIG9yaWdpbmFsIG1ldGhvZAogICAgdmFyIG9yaWdpbmFsID0gYXJyYXlQcm90b1ttZXRob2RdOwogICAgZGVmKGFycmF5TWV0aG9kcywgbWV0aG9kLCBmdW5jdGlvbiBtdXRhdG9yICgpIHsKICAgICAgdmFyIGFyZ3MgPSBbXSwgbGVuID0gYXJndW1lbnRzLmxlbmd0aDsKICAgICAgd2hpbGUgKCBsZW4tLSApIGFyZ3NbIGxlbiBdID0gYXJndW1lbnRzWyBsZW4gXTsKCiAgICAgIHZhciByZXN1bHQgPSBvcmlnaW5hbC5hcHBseSh0aGlzLCBhcmdzKTsKICAgICAgdmFyIG9iID0gdGhpcy5fX29iX187CiAgICAgIHZhciBpbnNlcnRlZDsKICAgICAgc3dpdGNoIChtZXRob2QpIHsKICAgICAgICBjYXNlICdwdXNoJzoKICAgICAgICBjYXNlICd1bnNoaWZ0JzoKICAgICAgICAgIGluc2VydGVkID0gYXJnczsKICAgICAgICAgIGJyZWFrCiAgICAgICAgY2FzZSAnc3BsaWNlJzoKICAgICAgICAgIGluc2VydGVkID0gYXJncy5zbGljZSgyKTsKICAgICAgICAgIGJyZWFrCiAgICAgIH0KICAgICAgaWYgKGluc2VydGVkKSB7IG9iLm9ic2VydmVBcnJheShpbnNlcnRlZCk7IH0KICAgICAgLy8gbm90aWZ5IGNoYW5nZQogICAgICBvYi5kZXAubm90aWZ5KCk7CiAgICAgIHJldHVybiByZXN1bHQKICAgIH0pOwogIH0pOwoKICAvKiAgKi8KCiAgdmFyIGFycmF5S2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGFycmF5TWV0aG9kcyk7CgogIC8qKgogICAqIEluIHNvbWUgY2FzZXMgd2UgbWF5IHdhbnQgdG8gZGlzYWJsZSBvYnNlcnZhdGlvbiBpbnNpZGUgYSBjb21wb25lbnQncwogICAqIHVwZGF0ZSBjb21wdXRhdGlvbi4KICAgKi8KICB2YXIgc2hvdWxkT2JzZXJ2ZSA9IHRydWU7CgogIGZ1bmN0aW9uIHRvZ2dsZU9ic2VydmluZyAodmFsdWUpIHsKICAgIHNob3VsZE9ic2VydmUgPSB2YWx1ZTsKICB9CgogIC8qKgogICAqIE9ic2VydmVyIGNsYXNzIHRoYXQgaXMgYXR0YWNoZWQgdG8gZWFjaCBvYnNlcnZlZAogICAqIG9iamVjdC4gT25jZSBhdHRhY2hlZCwgdGhlIG9ic2VydmVyIGNvbnZlcnRzIHRoZSB0YXJnZXQKICAgKiBvYmplY3QncyBwcm9wZXJ0eSBrZXlzIGludG8gZ2V0dGVyL3NldHRlcnMgdGhhdAogICAqIGNvbGxlY3QgZGVwZW5kZW5jaWVzIGFuZCBkaXNwYXRjaCB1cGRhdGVzLgogICAqLwogIHZhciBPYnNlcnZlciA9IGZ1bmN0aW9uIE9ic2VydmVyICh2YWx1ZSkgewogICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgdGhpcy5kZXAgPSBuZXcgRGVwKCk7CiAgICB0aGlzLnZtQ291bnQgPSAwOwogICAgZGVmKHZhbHVlLCAnX19vYl9fJywgdGhpcyk7CiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHsKICAgICAgaWYgKGhhc1Byb3RvKSB7CiAgICAgICAgcHJvdG9BdWdtZW50KHZhbHVlLCBhcnJheU1ldGhvZHMpOwogICAgICB9IGVsc2UgewogICAgICAgIGNvcHlBdWdtZW50KHZhbHVlLCBhcnJheU1ldGhvZHMsIGFycmF5S2V5cyk7CiAgICAgIH0KICAgICAgdGhpcy5vYnNlcnZlQXJyYXkodmFsdWUpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy53YWxrKHZhbHVlKTsKICAgIH0KICB9OwoKICAvKioKICAgKiBXYWxrIHRocm91Z2ggYWxsIHByb3BlcnRpZXMgYW5kIGNvbnZlcnQgdGhlbSBpbnRvCiAgICogZ2V0dGVyL3NldHRlcnMuIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIGNhbGxlZCB3aGVuCiAgICogdmFsdWUgdHlwZSBpcyBPYmplY3QuCiAgICovCiAgT2JzZXJ2ZXIucHJvdG90eXBlLndhbGsgPSBmdW5jdGlvbiB3YWxrIChvYmopIHsKICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewogICAgICBkZWZpbmVSZWFjdGl2ZSQkMShvYmosIGtleXNbaV0pOwogICAgfQogIH07CgogIC8qKgogICAqIE9ic2VydmUgYSBsaXN0IG9mIEFycmF5IGl0ZW1zLgogICAqLwogIE9ic2VydmVyLnByb3RvdHlwZS5vYnNlcnZlQXJyYXkgPSBmdW5jdGlvbiBvYnNlcnZlQXJyYXkgKGl0ZW1zKSB7CiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGl0ZW1zLmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICBvYnNlcnZlKGl0ZW1zW2ldKTsKICAgIH0KICB9OwoKICAvLyBoZWxwZXJzCgogIC8qKgogICAqIEF1Z21lbnQgYSB0YXJnZXQgT2JqZWN0IG9yIEFycmF5IGJ5IGludGVyY2VwdGluZwogICAqIHRoZSBwcm90b3R5cGUgY2hhaW4gdXNpbmcgX19wcm90b19fCiAgICovCiAgZnVuY3Rpb24gcHJvdG9BdWdtZW50ICh0YXJnZXQsIHNyYykgewogICAgLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi8KICAgIHRhcmdldC5fX3Byb3RvX18gPSBzcmM7CiAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXByb3RvICovCiAgfQoKICAvKioKICAgKiBBdWdtZW50IGEgdGFyZ2V0IE9iamVjdCBvciBBcnJheSBieSBkZWZpbmluZwogICAqIGhpZGRlbiBwcm9wZXJ0aWVzLgogICAqLwogIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovCiAgZnVuY3Rpb24gY29weUF1Z21lbnQgKHRhcmdldCwgc3JjLCBrZXlzKSB7CiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7CiAgICAgIHZhciBrZXkgPSBrZXlzW2ldOwogICAgICBkZWYodGFyZ2V0LCBrZXksIHNyY1trZXldKTsKICAgIH0KICB9CgogIC8qKgogICAqIEF0dGVtcHQgdG8gY3JlYXRlIGFuIG9ic2VydmVyIGluc3RhbmNlIGZvciBhIHZhbHVlLAogICAqIHJldHVybnMgdGhlIG5ldyBvYnNlcnZlciBpZiBzdWNjZXNzZnVsbHkgb2JzZXJ2ZWQsCiAgICogb3IgdGhlIGV4aXN0aW5nIG9ic2VydmVyIGlmIHRoZSB2YWx1ZSBhbHJlYWR5IGhhcyBvbmUuCiAgICovCiAgZnVuY3Rpb24gb2JzZXJ2ZSAodmFsdWUsIGFzUm9vdERhdGEpIHsKICAgIGlmICghaXNPYmplY3QodmFsdWUpIHx8IHZhbHVlIGluc3RhbmNlb2YgVk5vZGUpIHsKICAgICAgcmV0dXJuCiAgICB9CiAgICB2YXIgb2I7CiAgICBpZiAoaGFzT3duKHZhbHVlLCAnX19vYl9fJykgJiYgdmFsdWUuX19vYl9fIGluc3RhbmNlb2YgT2JzZXJ2ZXIpIHsKICAgICAgb2IgPSB2YWx1ZS5fX29iX187CiAgICB9IGVsc2UgaWYgKAogICAgICBzaG91bGRPYnNlcnZlICYmCiAgICAgICFpc1NlcnZlclJlbmRlcmluZygpICYmCiAgICAgIChBcnJheS5pc0FycmF5KHZhbHVlKSB8fCBpc1BsYWluT2JqZWN0KHZhbHVlKSkgJiYKICAgICAgT2JqZWN0LmlzRXh0ZW5zaWJsZSh2YWx1ZSkgJiYKICAgICAgIXZhbHVlLl9pc1Z1ZQogICAgKSB7CiAgICAgIG9iID0gbmV3IE9ic2VydmVyKHZhbHVlKTsKICAgIH0KICAgIGlmIChhc1Jvb3REYXRhICYmIG9iKSB7CiAgICAgIG9iLnZtQ291bnQrKzsKICAgIH0KICAgIHJldHVybiBvYgogIH0KCiAgLyoqCiAgICogRGVmaW5lIGEgcmVhY3RpdmUgcHJvcGVydHkgb24gYW4gT2JqZWN0LgogICAqLwogIGZ1bmN0aW9uIGRlZmluZVJlYWN0aXZlJCQxICgKICAgIG9iaiwKICAgIGtleSwKICAgIHZhbCwKICAgIGN1c3RvbVNldHRlciwKICAgIHNoYWxsb3cKICApIHsKICAgIHZhciBkZXAgPSBuZXcgRGVwKCk7CgogICAgdmFyIHByb3BlcnR5ID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIGtleSk7CiAgICBpZiAocHJvcGVydHkgJiYgcHJvcGVydHkuY29uZmlndXJhYmxlID09PSBmYWxzZSkgewogICAgICByZXR1cm4KICAgIH0KCiAgICAvLyBjYXRlciBmb3IgcHJlLWRlZmluZWQgZ2V0dGVyL3NldHRlcnMKICAgIHZhciBnZXR0ZXIgPSBwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5nZXQ7CiAgICB2YXIgc2V0dGVyID0gcHJvcGVydHkgJiYgcHJvcGVydHkuc2V0OwogICAgaWYgKCghZ2V0dGVyIHx8IHNldHRlcikgJiYgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgewogICAgICB2YWwgPSBvYmpba2V5XTsKICAgIH0KCiAgICB2YXIgY2hpbGRPYiA9ICFzaGFsbG93ICYmIG9ic2VydmUodmFsKTsKICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgewogICAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgICBjb25maWd1cmFibGU6IHRydWUsCiAgICAgIGdldDogZnVuY3Rpb24gcmVhY3RpdmVHZXR0ZXIgKCkgewogICAgICAgIHZhciB2YWx1ZSA9IGdldHRlciA/IGdldHRlci5jYWxsKG9iaikgOiB2YWw7CiAgICAgICAgaWYgKERlcC50YXJnZXQpIHsKICAgICAgICAgIGRlcC5kZXBlbmQoKTsKICAgICAgICAgIGlmIChjaGlsZE9iKSB7CiAgICAgICAgICAgIGNoaWxkT2IuZGVwLmRlcGVuZCgpOwogICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHsKICAgICAgICAgICAgICBkZXBlbmRBcnJheSh2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlCiAgICAgIH0sCiAgICAgIHNldDogZnVuY3Rpb24gcmVhY3RpdmVTZXR0ZXIgKG5ld1ZhbCkgewogICAgICAgIHZhciB2YWx1ZSA9IGdldHRlciA/IGdldHRlci5jYWxsKG9iaikgOiB2YWw7CiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tc2VsZi1jb21wYXJlICovCiAgICAgICAgaWYgKG5ld1ZhbCA9PT0gdmFsdWUgfHwgKG5ld1ZhbCAhPT0gbmV3VmFsICYmIHZhbHVlICE9PSB2YWx1ZSkpIHsKICAgICAgICAgIHJldHVybgogICAgICAgIH0KICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXNlbGYtY29tcGFyZSAqLwogICAgICAgIGlmIChjdXN0b21TZXR0ZXIpIHsKICAgICAgICAgIGN1c3RvbVNldHRlcigpOwogICAgICAgIH0KICAgICAgICAvLyAjNzk4MTogZm9yIGFjY2Vzc29yIHByb3BlcnRpZXMgd2l0aG91dCBzZXR0ZXIKICAgICAgICBpZiAoZ2V0dGVyICYmICFzZXR0ZXIpIHsgcmV0dXJuIH0KICAgICAgICBpZiAoc2V0dGVyKSB7CiAgICAgICAgICBzZXR0ZXIuY2FsbChvYmosIG5ld1ZhbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHZhbCA9IG5ld1ZhbDsKICAgICAgICB9CiAgICAgICAgY2hpbGRPYiA9ICFzaGFsbG93ICYmIG9ic2VydmUobmV3VmFsKTsKICAgICAgICBkZXAubm90aWZ5KCk7CiAgICAgIH0KICAgIH0pOwogIH0KCiAgLyoqCiAgICogU2V0IGEgcHJvcGVydHkgb24gYW4gb2JqZWN0LiBBZGRzIHRoZSBuZXcgcHJvcGVydHkgYW5kCiAgICogdHJpZ2dlcnMgY2hhbmdlIG5vdGlmaWNhdGlvbiBpZiB0aGUgcHJvcGVydHkgZG9lc24ndAogICAqIGFscmVhZHkgZXhpc3QuCiAgICovCiAgZnVuY3Rpb24gc2V0ICh0YXJnZXQsIGtleSwgdmFsKSB7CiAgICBpZiAoaXNVbmRlZih0YXJnZXQpIHx8IGlzUHJpbWl0aXZlKHRhcmdldCkKICAgICkgewogICAgICB3YXJuKCgiQ2Fubm90IHNldCByZWFjdGl2ZSBwcm9wZXJ0eSBvbiB1bmRlZmluZWQsIG51bGwsIG9yIHByaW1pdGl2ZSB2YWx1ZTogIiArICgodGFyZ2V0KSkpKTsKICAgIH0KICAgIGlmIChBcnJheS5pc0FycmF5KHRhcmdldCkgJiYgaXNWYWxpZEFycmF5SW5kZXgoa2V5KSkgewogICAgICB0YXJnZXQubGVuZ3RoID0gTWF0aC5tYXgodGFyZ2V0Lmxlbmd0aCwga2V5KTsKICAgICAgdGFyZ2V0LnNwbGljZShrZXksIDEsIHZhbCk7CiAgICAgIHJldHVybiB2YWwKICAgIH0KICAgIGlmIChrZXkgaW4gdGFyZ2V0ICYmICEoa2V5IGluIE9iamVjdC5wcm90b3R5cGUpKSB7CiAgICAgIHRhcmdldFtrZXldID0gdmFsOwogICAgICByZXR1cm4gdmFsCiAgICB9CiAgICB2YXIgb2IgPSAodGFyZ2V0KS5fX29iX187CiAgICBpZiAodGFyZ2V0Ll9pc1Z1ZSB8fCAob2IgJiYgb2Iudm1Db3VudCkpIHsKICAgICAgd2FybigKICAgICAgICAnQXZvaWQgYWRkaW5nIHJlYWN0aXZlIHByb3BlcnRpZXMgdG8gYSBWdWUgaW5zdGFuY2Ugb3IgaXRzIHJvb3QgJGRhdGEgJyArCiAgICAgICAgJ2F0IHJ1bnRpbWUgLSBkZWNsYXJlIGl0IHVwZnJvbnQgaW4gdGhlIGRhdGEgb3B0aW9uLicKICAgICAgKTsKICAgICAgcmV0dXJuIHZhbAogICAgfQogICAgaWYgKCFvYikgewogICAgICB0YXJnZXRba2V5XSA9IHZhbDsKICAgICAgcmV0dXJuIHZhbAogICAgfQogICAgZGVmaW5lUmVhY3RpdmUkJDEob2IudmFsdWUsIGtleSwgdmFsKTsKICAgIG9iLmRlcC5ub3RpZnkoKTsKICAgIHJldHVybiB2YWwKICB9CgogIC8qKgogICAqIERlbGV0ZSBhIHByb3BlcnR5IGFuZCB0cmlnZ2VyIGNoYW5nZSBpZiBuZWNlc3NhcnkuCiAgICovCiAgZnVuY3Rpb24gZGVsICh0YXJnZXQsIGtleSkgewogICAgaWYgKGlzVW5kZWYodGFyZ2V0KSB8fCBpc1ByaW1pdGl2ZSh0YXJnZXQpCiAgICApIHsKICAgICAgd2FybigoIkNhbm5vdCBkZWxldGUgcmVhY3RpdmUgcHJvcGVydHkgb24gdW5kZWZpbmVkLCBudWxsLCBvciBwcmltaXRpdmUgdmFsdWU6ICIgKyAoKHRhcmdldCkpKSk7CiAgICB9CiAgICBpZiAoQXJyYXkuaXNBcnJheSh0YXJnZXQpICYmIGlzVmFsaWRBcnJheUluZGV4KGtleSkpIHsKICAgICAgdGFyZ2V0LnNwbGljZShrZXksIDEpOwogICAgICByZXR1cm4KICAgIH0KICAgIHZhciBvYiA9ICh0YXJnZXQpLl9fb2JfXzsKICAgIGlmICh0YXJnZXQuX2lzVnVlIHx8IChvYiAmJiBvYi52bUNvdW50KSkgewogICAgICB3YXJuKAogICAgICAgICdBdm9pZCBkZWxldGluZyBwcm9wZXJ0aWVzIG9uIGEgVnVlIGluc3RhbmNlIG9yIGl0cyByb290ICRkYXRhICcgKwogICAgICAgICctIGp1c3Qgc2V0IGl0IHRvIG51bGwuJwogICAgICApOwogICAgICByZXR1cm4KICAgIH0KICAgIGlmICghaGFzT3duKHRhcmdldCwga2V5KSkgewogICAgICByZXR1cm4KICAgIH0KICAgIGRlbGV0ZSB0YXJnZXRba2V5XTsKICAgIGlmICghb2IpIHsKICAgICAgcmV0dXJuCiAgICB9CiAgICBvYi5kZXAubm90aWZ5KCk7CiAgfQoKICAvKioKICAgKiBDb2xsZWN0IGRlcGVuZGVuY2llcyBvbiBhcnJheSBlbGVtZW50cyB3aGVuIHRoZSBhcnJheSBpcyB0b3VjaGVkLCBzaW5jZQogICAqIHdlIGNhbm5vdCBpbnRlcmNlcHQgYXJyYXkgZWxlbWVudCBhY2Nlc3MgbGlrZSBwcm9wZXJ0eSBnZXR0ZXJzLgogICAqLwogIGZ1bmN0aW9uIGRlcGVuZEFycmF5ICh2YWx1ZSkgewogICAgZm9yICh2YXIgZSA9ICh2b2lkIDApLCBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICBlID0gdmFsdWVbaV07CiAgICAgIGUgJiYgZS5fX29iX18gJiYgZS5fX29iX18uZGVwLmRlcGVuZCgpOwogICAgICBpZiAoQXJyYXkuaXNBcnJheShlKSkgewogICAgICAgIGRlcGVuZEFycmF5KGUpOwogICAgICB9CiAgICB9CiAgfQoKICAvKiAgKi8KCiAgLyoqCiAgICogT3B0aW9uIG92ZXJ3cml0aW5nIHN0cmF0ZWdpZXMgYXJlIGZ1bmN0aW9ucyB0aGF0IGhhbmRsZQogICAqIGhvdyB0byBtZXJnZSBhIHBhcmVudCBvcHRpb24gdmFsdWUgYW5kIGEgY2hpbGQgb3B0aW9uCiAgICogdmFsdWUgaW50byB0aGUgZmluYWwgdmFsdWUuCiAgICovCiAgdmFyIHN0cmF0cyA9IGNvbmZpZy5vcHRpb25NZXJnZVN0cmF0ZWdpZXM7CgogIC8qKgogICAqIE9wdGlvbnMgd2l0aCByZXN0cmljdGlvbnMKICAgKi8KICB7CiAgICBzdHJhdHMuZWwgPSBzdHJhdHMucHJvcHNEYXRhID0gZnVuY3Rpb24gKHBhcmVudCwgY2hpbGQsIHZtLCBrZXkpIHsKICAgICAgaWYgKCF2bSkgewogICAgICAgIHdhcm4oCiAgICAgICAgICAib3B0aW9uIFwiIiArIGtleSArICJcIiBjYW4gb25seSBiZSB1c2VkIGR1cmluZyBpbnN0YW5jZSAiICsKICAgICAgICAgICdjcmVhdGlvbiB3aXRoIHRoZSBgbmV3YCBrZXl3b3JkLicKICAgICAgICApOwogICAgICB9CiAgICAgIHJldHVybiBkZWZhdWx0U3RyYXQocGFyZW50LCBjaGlsZCkKICAgIH07CiAgfQoKICAvKioKICAgKiBIZWxwZXIgdGhhdCByZWN1cnNpdmVseSBtZXJnZXMgdHdvIGRhdGEgb2JqZWN0cyB0b2dldGhlci4KICAgKi8KICBmdW5jdGlvbiBtZXJnZURhdGEgKHRvLCBmcm9tKSB7CiAgICBpZiAoIWZyb20pIHsgcmV0dXJuIHRvIH0KICAgIHZhciBrZXksIHRvVmFsLCBmcm9tVmFsOwoKICAgIHZhciBrZXlzID0gaGFzU3ltYm9sCiAgICAgID8gUmVmbGVjdC5vd25LZXlzKGZyb20pCiAgICAgIDogT2JqZWN0LmtleXMoZnJvbSk7CgogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CiAgICAgIGtleSA9IGtleXNbaV07CiAgICAgIC8vIGluIGNhc2UgdGhlIG9iamVjdCBpcyBhbHJlYWR5IG9ic2VydmVkLi4uCiAgICAgIGlmIChrZXkgPT09ICdfX29iX18nKSB7IGNvbnRpbnVlIH0KICAgICAgdG9WYWwgPSB0b1trZXldOwogICAgICBmcm9tVmFsID0gZnJvbVtrZXldOwogICAgICBpZiAoIWhhc093bih0bywga2V5KSkgewogICAgICAgIHNldCh0bywga2V5LCBmcm9tVmFsKTsKICAgICAgfSBlbHNlIGlmICgKICAgICAgICB0b1ZhbCAhPT0gZnJvbVZhbCAmJgogICAgICAgIGlzUGxhaW5PYmplY3QodG9WYWwpICYmCiAgICAgICAgaXNQbGFpbk9iamVjdChmcm9tVmFsKQogICAgICApIHsKICAgICAgICBtZXJnZURhdGEodG9WYWwsIGZyb21WYWwpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gdG8KICB9CgogIC8qKgogICAqIERhdGEKICAgKi8KICBmdW5jdGlvbiBtZXJnZURhdGFPckZuICgKICAgIHBhcmVudFZhbCwKICAgIGNoaWxkVmFsLAogICAgdm0KICApIHsKICAgIGlmICghdm0pIHsKICAgICAgLy8gaW4gYSBWdWUuZXh0ZW5kIG1lcmdlLCBib3RoIHNob3VsZCBiZSBmdW5jdGlvbnMKICAgICAgaWYgKCFjaGlsZFZhbCkgewogICAgICAgIHJldHVybiBwYXJlbnRWYWwKICAgICAgfQogICAgICBpZiAoIXBhcmVudFZhbCkgewogICAgICAgIHJldHVybiBjaGlsZFZhbAogICAgICB9CiAgICAgIC8vIHdoZW4gcGFyZW50VmFsICYgY2hpbGRWYWwgYXJlIGJvdGggcHJlc2VudCwKICAgICAgLy8gd2UgbmVlZCB0byByZXR1cm4gYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlCiAgICAgIC8vIG1lcmdlZCByZXN1bHQgb2YgYm90aCBmdW5jdGlvbnMuLi4gbm8gbmVlZCB0bwogICAgICAvLyBjaGVjayBpZiBwYXJlbnRWYWwgaXMgYSBmdW5jdGlvbiBoZXJlIGJlY2F1c2UKICAgICAgLy8gaXQgaGFzIHRvIGJlIGEgZnVuY3Rpb24gdG8gcGFzcyBwcmV2aW91cyBtZXJnZXMuCiAgICAgIHJldHVybiBmdW5jdGlvbiBtZXJnZWREYXRhRm4gKCkgewogICAgICAgIHJldHVybiBtZXJnZURhdGEoCiAgICAgICAgICB0eXBlb2YgY2hpbGRWYWwgPT09ICdmdW5jdGlvbicgPyBjaGlsZFZhbC5jYWxsKHRoaXMsIHRoaXMpIDogY2hpbGRWYWwsCiAgICAgICAgICB0eXBlb2YgcGFyZW50VmFsID09PSAnZnVuY3Rpb24nID8gcGFyZW50VmFsLmNhbGwodGhpcywgdGhpcykgOiBwYXJlbnRWYWwKICAgICAgICApCiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBmdW5jdGlvbiBtZXJnZWRJbnN0YW5jZURhdGFGbiAoKSB7CiAgICAgICAgLy8gaW5zdGFuY2UgbWVyZ2UKICAgICAgICB2YXIgaW5zdGFuY2VEYXRhID0gdHlwZW9mIGNoaWxkVmFsID09PSAnZnVuY3Rpb24nCiAgICAgICAgICA/IGNoaWxkVmFsLmNhbGwodm0sIHZtKQogICAgICAgICAgOiBjaGlsZFZhbDsKICAgICAgICB2YXIgZGVmYXVsdERhdGEgPSB0eXBlb2YgcGFyZW50VmFsID09PSAnZnVuY3Rpb24nCiAgICAgICAgICA/IHBhcmVudFZhbC5jYWxsKHZtLCB2bSkKICAgICAgICAgIDogcGFyZW50VmFsOwogICAgICAgIGlmIChpbnN0YW5jZURhdGEpIHsKICAgICAgICAgIHJldHVybiBtZXJnZURhdGEoaW5zdGFuY2VEYXRhLCBkZWZhdWx0RGF0YSkKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGRlZmF1bHREYXRhCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICBzdHJhdHMuZGF0YSA9IGZ1bmN0aW9uICgKICAgIHBhcmVudFZhbCwKICAgIGNoaWxkVmFsLAogICAgdm0KICApIHsKICAgIGlmICghdm0pIHsKICAgICAgaWYgKGNoaWxkVmFsICYmIHR5cGVvZiBjaGlsZFZhbCAhPT0gJ2Z1bmN0aW9uJykgewogICAgICAgIHdhcm4oCiAgICAgICAgICAnVGhlICJkYXRhIiBvcHRpb24gc2hvdWxkIGJlIGEgZnVuY3Rpb24gJyArCiAgICAgICAgICAndGhhdCByZXR1cm5zIGEgcGVyLWluc3RhbmNlIHZhbHVlIGluIGNvbXBvbmVudCAnICsKICAgICAgICAgICdkZWZpbml0aW9ucy4nLAogICAgICAgICAgdm0KICAgICAgICApOwoKICAgICAgICByZXR1cm4gcGFyZW50VmFsCiAgICAgIH0KICAgICAgcmV0dXJuIG1lcmdlRGF0YU9yRm4ocGFyZW50VmFsLCBjaGlsZFZhbCkKICAgIH0KCiAgICByZXR1cm4gbWVyZ2VEYXRhT3JGbihwYXJlbnRWYWwsIGNoaWxkVmFsLCB2bSkKICB9OwoKICAvKioKICAgKiBIb29rcyBhbmQgcHJvcHMgYXJlIG1lcmdlZCBhcyBhcnJheXMuCiAgICovCiAgZnVuY3Rpb24gbWVyZ2VIb29rICgKICAgIHBhcmVudFZhbCwKICAgIGNoaWxkVmFsCiAgKSB7CiAgICB2YXIgcmVzID0gY2hpbGRWYWwKICAgICAgPyBwYXJlbnRWYWwKICAgICAgICA/IHBhcmVudFZhbC5jb25jYXQoY2hpbGRWYWwpCiAgICAgICAgOiBBcnJheS5pc0FycmF5KGNoaWxkVmFsKQogICAgICAgICAgPyBjaGlsZFZhbAogICAgICAgICAgOiBbY2hpbGRWYWxdCiAgICAgIDogcGFyZW50VmFsOwogICAgcmV0dXJuIHJlcwogICAgICA/IGRlZHVwZUhvb2tzKHJlcykKICAgICAgOiByZXMKICB9CgogIGZ1bmN0aW9uIGRlZHVwZUhvb2tzIChob29rcykgewogICAgdmFyIHJlcyA9IFtdOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBob29rcy5sZW5ndGg7IGkrKykgewogICAgICBpZiAocmVzLmluZGV4T2YoaG9va3NbaV0pID09PSAtMSkgewogICAgICAgIHJlcy5wdXNoKGhvb2tzW2ldKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlcwogIH0KCiAgTElGRUNZQ0xFX0hPT0tTLmZvckVhY2goZnVuY3Rpb24gKGhvb2spIHsKICAgIHN0cmF0c1tob29rXSA9IG1lcmdlSG9vazsKICB9KTsKCiAgLyoqCiAgICogQXNzZXRzCiAgICoKICAgKiBXaGVuIGEgdm0gaXMgcHJlc2VudCAoaW5zdGFuY2UgY3JlYXRpb24pLCB3ZSBuZWVkIHRvIGRvCiAgICogYSB0aHJlZS13YXkgbWVyZ2UgYmV0d2VlbiBjb25zdHJ1Y3RvciBvcHRpb25zLCBpbnN0YW5jZQogICAqIG9wdGlvbnMgYW5kIHBhcmVudCBvcHRpb25zLgogICAqLwogIGZ1bmN0aW9uIG1lcmdlQXNzZXRzICgKICAgIHBhcmVudFZhbCwKICAgIGNoaWxkVmFsLAogICAgdm0sCiAgICBrZXkKICApIHsKICAgIHZhciByZXMgPSBPYmplY3QuY3JlYXRlKHBhcmVudFZhbCB8fCBudWxsKTsKICAgIGlmIChjaGlsZFZhbCkgewogICAgICBhc3NlcnRPYmplY3RUeXBlKGtleSwgY2hpbGRWYWwsIHZtKTsKICAgICAgcmV0dXJuIGV4dGVuZChyZXMsIGNoaWxkVmFsKQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIHJlcwogICAgfQogIH0KCiAgQVNTRVRfVFlQRVMuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkgewogICAgc3RyYXRzW3R5cGUgKyAncyddID0gbWVyZ2VBc3NldHM7CiAgfSk7CgogIC8qKgogICAqIFdhdGNoZXJzLgogICAqCiAgICogV2F0Y2hlcnMgaGFzaGVzIHNob3VsZCBub3Qgb3ZlcndyaXRlIG9uZQogICAqIGFub3RoZXIsIHNvIHdlIG1lcmdlIHRoZW0gYXMgYXJyYXlzLgogICAqLwogIHN0cmF0cy53YXRjaCA9IGZ1bmN0aW9uICgKICAgIHBhcmVudFZhbCwKICAgIGNoaWxkVmFsLAogICAgdm0sCiAgICBrZXkKICApIHsKICAgIC8vIHdvcmsgYXJvdW5kIEZpcmVmb3gncyBPYmplY3QucHJvdG90eXBlLndhdGNoLi4uCiAgICBpZiAocGFyZW50VmFsID09PSBuYXRpdmVXYXRjaCkgeyBwYXJlbnRWYWwgPSB1bmRlZmluZWQ7IH0KICAgIGlmIChjaGlsZFZhbCA9PT0gbmF0aXZlV2F0Y2gpIHsgY2hpbGRWYWwgPSB1bmRlZmluZWQ7IH0KICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgaWYgKCFjaGlsZFZhbCkgeyByZXR1cm4gT2JqZWN0LmNyZWF0ZShwYXJlbnRWYWwgfHwgbnVsbCkgfQogICAgewogICAgICBhc3NlcnRPYmplY3RUeXBlKGtleSwgY2hpbGRWYWwsIHZtKTsKICAgIH0KICAgIGlmICghcGFyZW50VmFsKSB7IHJldHVybiBjaGlsZFZhbCB9CiAgICB2YXIgcmV0ID0ge307CiAgICBleHRlbmQocmV0LCBwYXJlbnRWYWwpOwogICAgZm9yICh2YXIga2V5JDEgaW4gY2hpbGRWYWwpIHsKICAgICAgdmFyIHBhcmVudCA9IHJldFtrZXkkMV07CiAgICAgIHZhciBjaGlsZCA9IGNoaWxkVmFsW2tleSQxXTsKICAgICAgaWYgKHBhcmVudCAmJiAhQXJyYXkuaXNBcnJheShwYXJlbnQpKSB7CiAgICAgICAgcGFyZW50ID0gW3BhcmVudF07CiAgICAgIH0KICAgICAgcmV0W2tleSQxXSA9IHBhcmVudAogICAgICAgID8gcGFyZW50LmNvbmNhdChjaGlsZCkKICAgICAgICA6IEFycmF5LmlzQXJyYXkoY2hpbGQpID8gY2hpbGQgOiBbY2hpbGRdOwogICAgfQogICAgcmV0dXJuIHJldAogIH07CgogIC8qKgogICAqIE90aGVyIG9iamVjdCBoYXNoZXMuCiAgICovCiAgc3RyYXRzLnByb3BzID0KICBzdHJhdHMubWV0aG9kcyA9CiAgc3RyYXRzLmluamVjdCA9CiAgc3RyYXRzLmNvbXB1dGVkID0gZnVuY3Rpb24gKAogICAgcGFyZW50VmFsLAogICAgY2hpbGRWYWwsCiAgICB2bSwKICAgIGtleQogICkgewogICAgaWYgKGNoaWxkVmFsICYmICJkZXZlbG9wbWVudCIgIT09ICdwcm9kdWN0aW9uJykgewogICAgICBhc3NlcnRPYmplY3RUeXBlKGtleSwgY2hpbGRWYWwsIHZtKTsKICAgIH0KICAgIGlmICghcGFyZW50VmFsKSB7IHJldHVybiBjaGlsZFZhbCB9CiAgICB2YXIgcmV0ID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKICAgIGV4dGVuZChyZXQsIHBhcmVudFZhbCk7CiAgICBpZiAoY2hpbGRWYWwpIHsgZXh0ZW5kKHJldCwgY2hpbGRWYWwpOyB9CiAgICByZXR1cm4gcmV0CiAgfTsKICBzdHJhdHMucHJvdmlkZSA9IG1lcmdlRGF0YU9yRm47CgogIC8qKgogICAqIERlZmF1bHQgc3RyYXRlZ3kuCiAgICovCiAgdmFyIGRlZmF1bHRTdHJhdCA9IGZ1bmN0aW9uIChwYXJlbnRWYWwsIGNoaWxkVmFsKSB7CiAgICByZXR1cm4gY2hpbGRWYWwgPT09IHVuZGVmaW5lZAogICAgICA/IHBhcmVudFZhbAogICAgICA6IGNoaWxkVmFsCiAgfTsKCiAgLyoqCiAgICogVmFsaWRhdGUgY29tcG9uZW50IG5hbWVzCiAgICovCiAgZnVuY3Rpb24gY2hlY2tDb21wb25lbnRzIChvcHRpb25zKSB7CiAgICBmb3IgKHZhciBrZXkgaW4gb3B0aW9ucy5jb21wb25lbnRzKSB7CiAgICAgIHZhbGlkYXRlQ29tcG9uZW50TmFtZShrZXkpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gdmFsaWRhdGVDb21wb25lbnROYW1lIChuYW1lKSB7CiAgICBpZiAoIW5ldyBSZWdFeHAoKCJeW2EtekEtWl1bXFwtXFwuMC05XyIgKyAodW5pY29kZVJlZ0V4cC5zb3VyY2UpICsgIl0qJCIpKS50ZXN0KG5hbWUpKSB7CiAgICAgIHdhcm4oCiAgICAgICAgJ0ludmFsaWQgY29tcG9uZW50IG5hbWU6ICInICsgbmFtZSArICciLiBDb21wb25lbnQgbmFtZXMgJyArCiAgICAgICAgJ3Nob3VsZCBjb25mb3JtIHRvIHZhbGlkIGN1c3RvbSBlbGVtZW50IG5hbWUgaW4gaHRtbDUgc3BlY2lmaWNhdGlvbi4nCiAgICAgICk7CiAgICB9CiAgICBpZiAoaXNCdWlsdEluVGFnKG5hbWUpIHx8IGNvbmZpZy5pc1Jlc2VydmVkVGFnKG5hbWUpKSB7CiAgICAgIHdhcm4oCiAgICAgICAgJ0RvIG5vdCB1c2UgYnVpbHQtaW4gb3IgcmVzZXJ2ZWQgSFRNTCBlbGVtZW50cyBhcyBjb21wb25lbnQgJyArCiAgICAgICAgJ2lkOiAnICsgbmFtZQogICAgICApOwogICAgfQogIH0KCiAgLyoqCiAgICogRW5zdXJlIGFsbCBwcm9wcyBvcHRpb24gc3ludGF4IGFyZSBub3JtYWxpemVkIGludG8gdGhlCiAgICogT2JqZWN0LWJhc2VkIGZvcm1hdC4KICAgKi8KICBmdW5jdGlvbiBub3JtYWxpemVQcm9wcyAob3B0aW9ucywgdm0pIHsKICAgIHZhciBwcm9wcyA9IG9wdGlvbnMucHJvcHM7CiAgICBpZiAoIXByb3BzKSB7IHJldHVybiB9CiAgICB2YXIgcmVzID0ge307CiAgICB2YXIgaSwgdmFsLCBuYW1lOwogICAgaWYgKEFycmF5LmlzQXJyYXkocHJvcHMpKSB7CiAgICAgIGkgPSBwcm9wcy5sZW5ndGg7CiAgICAgIHdoaWxlIChpLS0pIHsKICAgICAgICB2YWwgPSBwcm9wc1tpXTsKICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgIG5hbWUgPSBjYW1lbGl6ZSh2YWwpOwogICAgICAgICAgcmVzW25hbWVdID0geyB0eXBlOiBudWxsIH07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHdhcm4oJ3Byb3BzIG11c3QgYmUgc3RyaW5ncyB3aGVuIHVzaW5nIGFycmF5IHN5bnRheC4nKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoaXNQbGFpbk9iamVjdChwcm9wcykpIHsKICAgICAgZm9yICh2YXIga2V5IGluIHByb3BzKSB7CiAgICAgICAgdmFsID0gcHJvcHNba2V5XTsKICAgICAgICBuYW1lID0gY2FtZWxpemUoa2V5KTsKICAgICAgICByZXNbbmFtZV0gPSBpc1BsYWluT2JqZWN0KHZhbCkKICAgICAgICAgID8gdmFsCiAgICAgICAgICA6IHsgdHlwZTogdmFsIH07CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHdhcm4oCiAgICAgICAgIkludmFsaWQgdmFsdWUgZm9yIG9wdGlvbiBcInByb3BzXCI6IGV4cGVjdGVkIGFuIEFycmF5IG9yIGFuIE9iamVjdCwgIiArCiAgICAgICAgImJ1dCBnb3QgIiArICh0b1Jhd1R5cGUocHJvcHMpKSArICIuIiwKICAgICAgICB2bQogICAgICApOwogICAgfQogICAgb3B0aW9ucy5wcm9wcyA9IHJlczsKICB9CgogIC8qKgogICAqIE5vcm1hbGl6ZSBhbGwgaW5qZWN0aW9ucyBpbnRvIE9iamVjdC1iYXNlZCBmb3JtYXQKICAgKi8KICBmdW5jdGlvbiBub3JtYWxpemVJbmplY3QgKG9wdGlvbnMsIHZtKSB7CiAgICB2YXIgaW5qZWN0ID0gb3B0aW9ucy5pbmplY3Q7CiAgICBpZiAoIWluamVjdCkgeyByZXR1cm4gfQogICAgdmFyIG5vcm1hbGl6ZWQgPSBvcHRpb25zLmluamVjdCA9IHt9OwogICAgaWYgKEFycmF5LmlzQXJyYXkoaW5qZWN0KSkgewogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluamVjdC5sZW5ndGg7IGkrKykgewogICAgICAgIG5vcm1hbGl6ZWRbaW5qZWN0W2ldXSA9IHsgZnJvbTogaW5qZWN0W2ldIH07CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoaXNQbGFpbk9iamVjdChpbmplY3QpKSB7CiAgICAgIGZvciAodmFyIGtleSBpbiBpbmplY3QpIHsKICAgICAgICB2YXIgdmFsID0gaW5qZWN0W2tleV07CiAgICAgICAgbm9ybWFsaXplZFtrZXldID0gaXNQbGFpbk9iamVjdCh2YWwpCiAgICAgICAgICA/IGV4dGVuZCh7IGZyb206IGtleSB9LCB2YWwpCiAgICAgICAgICA6IHsgZnJvbTogdmFsIH07CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHdhcm4oCiAgICAgICAgIkludmFsaWQgdmFsdWUgZm9yIG9wdGlvbiBcImluamVjdFwiOiBleHBlY3RlZCBhbiBBcnJheSBvciBhbiBPYmplY3QsICIgKwogICAgICAgICJidXQgZ290ICIgKyAodG9SYXdUeXBlKGluamVjdCkpICsgIi4iLAogICAgICAgIHZtCiAgICAgICk7CiAgICB9CiAgfQoKICAvKioKICAgKiBOb3JtYWxpemUgcmF3IGZ1bmN0aW9uIGRpcmVjdGl2ZXMgaW50byBvYmplY3QgZm9ybWF0LgogICAqLwogIGZ1bmN0aW9uIG5vcm1hbGl6ZURpcmVjdGl2ZXMgKG9wdGlvbnMpIHsKICAgIHZhciBkaXJzID0gb3B0aW9ucy5kaXJlY3RpdmVzOwogICAgaWYgKGRpcnMpIHsKICAgICAgZm9yICh2YXIga2V5IGluIGRpcnMpIHsKICAgICAgICB2YXIgZGVmJCQxID0gZGlyc1trZXldOwogICAgICAgIGlmICh0eXBlb2YgZGVmJCQxID09PSAnZnVuY3Rpb24nKSB7CiAgICAgICAgICBkaXJzW2tleV0gPSB7IGJpbmQ6IGRlZiQkMSwgdXBkYXRlOiBkZWYkJDEgfTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIGFzc2VydE9iamVjdFR5cGUgKG5hbWUsIHZhbHVlLCB2bSkgewogICAgaWYgKCFpc1BsYWluT2JqZWN0KHZhbHVlKSkgewogICAgICB3YXJuKAogICAgICAgICJJbnZhbGlkIHZhbHVlIGZvciBvcHRpb24gXCIiICsgbmFtZSArICJcIjogZXhwZWN0ZWQgYW4gT2JqZWN0LCAiICsKICAgICAgICAiYnV0IGdvdCAiICsgKHRvUmF3VHlwZSh2YWx1ZSkpICsgIi4iLAogICAgICAgIHZtCiAgICAgICk7CiAgICB9CiAgfQoKICAvKioKICAgKiBNZXJnZSB0d28gb3B0aW9uIG9iamVjdHMgaW50byBhIG5ldyBvbmUuCiAgICogQ29yZSB1dGlsaXR5IHVzZWQgaW4gYm90aCBpbnN0YW50aWF0aW9uIGFuZCBpbmhlcml0YW5jZS4KICAgKi8KICBmdW5jdGlvbiBtZXJnZU9wdGlvbnMgKAogICAgcGFyZW50LAogICAgY2hpbGQsCiAgICB2bQogICkgewogICAgewogICAgICBjaGVja0NvbXBvbmVudHMoY2hpbGQpOwogICAgfQoKICAgIGlmICh0eXBlb2YgY2hpbGQgPT09ICdmdW5jdGlvbicpIHsKICAgICAgY2hpbGQgPSBjaGlsZC5vcHRpb25zOwogICAgfQoKICAgIG5vcm1hbGl6ZVByb3BzKGNoaWxkLCB2bSk7CiAgICBub3JtYWxpemVJbmplY3QoY2hpbGQsIHZtKTsKICAgIG5vcm1hbGl6ZURpcmVjdGl2ZXMoY2hpbGQpOwoKICAgIC8vIEFwcGx5IGV4dGVuZHMgYW5kIG1peGlucyBvbiB0aGUgY2hpbGQgb3B0aW9ucywKICAgIC8vIGJ1dCBvbmx5IGlmIGl0IGlzIGEgcmF3IG9wdGlvbnMgb2JqZWN0IHRoYXQgaXNuJ3QKICAgIC8vIHRoZSByZXN1bHQgb2YgYW5vdGhlciBtZXJnZU9wdGlvbnMgY2FsbC4KICAgIC8vIE9ubHkgbWVyZ2VkIG9wdGlvbnMgaGFzIHRoZSBfYmFzZSBwcm9wZXJ0eS4KICAgIGlmICghY2hpbGQuX2Jhc2UpIHsKICAgICAgaWYgKGNoaWxkLmV4dGVuZHMpIHsKICAgICAgICBwYXJlbnQgPSBtZXJnZU9wdGlvbnMocGFyZW50LCBjaGlsZC5leHRlbmRzLCB2bSk7CiAgICAgIH0KICAgICAgaWYgKGNoaWxkLm1peGlucykgewogICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gY2hpbGQubWl4aW5zLmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICAgICAgcGFyZW50ID0gbWVyZ2VPcHRpb25zKHBhcmVudCwgY2hpbGQubWl4aW5zW2ldLCB2bSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgdmFyIG9wdGlvbnMgPSB7fTsKICAgIHZhciBrZXk7CiAgICBmb3IgKGtleSBpbiBwYXJlbnQpIHsKICAgICAgbWVyZ2VGaWVsZChrZXkpOwogICAgfQogICAgZm9yIChrZXkgaW4gY2hpbGQpIHsKICAgICAgaWYgKCFoYXNPd24ocGFyZW50LCBrZXkpKSB7CiAgICAgICAgbWVyZ2VGaWVsZChrZXkpOwogICAgICB9CiAgICB9CiAgICBmdW5jdGlvbiBtZXJnZUZpZWxkIChrZXkpIHsKICAgICAgdmFyIHN0cmF0ID0gc3RyYXRzW2tleV0gfHwgZGVmYXVsdFN0cmF0OwogICAgICBvcHRpb25zW2tleV0gPSBzdHJhdChwYXJlbnRba2V5XSwgY2hpbGRba2V5XSwgdm0sIGtleSk7CiAgICB9CiAgICByZXR1cm4gb3B0aW9ucwogIH0KCiAgLyoqCiAgICogUmVzb2x2ZSBhbiBhc3NldC4KICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgYmVjYXVzZSBjaGlsZCBpbnN0YW5jZXMgbmVlZCBhY2Nlc3MKICAgKiB0byBhc3NldHMgZGVmaW5lZCBpbiBpdHMgYW5jZXN0b3IgY2hhaW4uCiAgICovCiAgZnVuY3Rpb24gcmVzb2x2ZUFzc2V0ICgKICAgIG9wdGlvbnMsCiAgICB0eXBlLAogICAgaWQsCiAgICB3YXJuTWlzc2luZwogICkgewogICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICBpZiAodHlwZW9mIGlkICE9PSAnc3RyaW5nJykgewogICAgICByZXR1cm4KICAgIH0KICAgIHZhciBhc3NldHMgPSBvcHRpb25zW3R5cGVdOwogICAgLy8gY2hlY2sgbG9jYWwgcmVnaXN0cmF0aW9uIHZhcmlhdGlvbnMgZmlyc3QKICAgIGlmIChoYXNPd24oYXNzZXRzLCBpZCkpIHsgcmV0dXJuIGFzc2V0c1tpZF0gfQogICAgdmFyIGNhbWVsaXplZElkID0gY2FtZWxpemUoaWQpOwogICAgaWYgKGhhc093bihhc3NldHMsIGNhbWVsaXplZElkKSkgeyByZXR1cm4gYXNzZXRzW2NhbWVsaXplZElkXSB9CiAgICB2YXIgUGFzY2FsQ2FzZUlkID0gY2FwaXRhbGl6ZShjYW1lbGl6ZWRJZCk7CiAgICBpZiAoaGFzT3duKGFzc2V0cywgUGFzY2FsQ2FzZUlkKSkgeyByZXR1cm4gYXNzZXRzW1Bhc2NhbENhc2VJZF0gfQogICAgLy8gZmFsbGJhY2sgdG8gcHJvdG90eXBlIGNoYWluCiAgICB2YXIgcmVzID0gYXNzZXRzW2lkXSB8fCBhc3NldHNbY2FtZWxpemVkSWRdIHx8IGFzc2V0c1tQYXNjYWxDYXNlSWRdOwogICAgaWYgKHdhcm5NaXNzaW5nICYmICFyZXMpIHsKICAgICAgd2FybigKICAgICAgICAnRmFpbGVkIHRvIHJlc29sdmUgJyArIHR5cGUuc2xpY2UoMCwgLTEpICsgJzogJyArIGlkLAogICAgICAgIG9wdGlvbnMKICAgICAgKTsKICAgIH0KICAgIHJldHVybiByZXMKICB9CgogIC8qICAqLwoKCgogIGZ1bmN0aW9uIHZhbGlkYXRlUHJvcCAoCiAgICBrZXksCiAgICBwcm9wT3B0aW9ucywKICAgIHByb3BzRGF0YSwKICAgIHZtCiAgKSB7CiAgICB2YXIgcHJvcCA9IHByb3BPcHRpb25zW2tleV07CiAgICB2YXIgYWJzZW50ID0gIWhhc093bihwcm9wc0RhdGEsIGtleSk7CiAgICB2YXIgdmFsdWUgPSBwcm9wc0RhdGFba2V5XTsKICAgIC8vIGJvb2xlYW4gY2FzdGluZwogICAgdmFyIGJvb2xlYW5JbmRleCA9IGdldFR5cGVJbmRleChCb29sZWFuLCBwcm9wLnR5cGUpOwogICAgaWYgKGJvb2xlYW5JbmRleCA+IC0xKSB7CiAgICAgIGlmIChhYnNlbnQgJiYgIWhhc093bihwcm9wLCAnZGVmYXVsdCcpKSB7CiAgICAgICAgdmFsdWUgPSBmYWxzZTsKICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJycgfHwgdmFsdWUgPT09IGh5cGhlbmF0ZShrZXkpKSB7CiAgICAgICAgLy8gb25seSBjYXN0IGVtcHR5IHN0cmluZyAvIHNhbWUgbmFtZSB0byBib29sZWFuIGlmCiAgICAgICAgLy8gYm9vbGVhbiBoYXMgaGlnaGVyIHByaW9yaXR5CiAgICAgICAgdmFyIHN0cmluZ0luZGV4ID0gZ2V0VHlwZUluZGV4KFN0cmluZywgcHJvcC50eXBlKTsKICAgICAgICBpZiAoc3RyaW5nSW5kZXggPCAwIHx8IGJvb2xlYW5JbmRleCA8IHN0cmluZ0luZGV4KSB7CiAgICAgICAgICB2YWx1ZSA9IHRydWU7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICAvLyBjaGVjayBkZWZhdWx0IHZhbHVlCiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkgewogICAgICB2YWx1ZSA9IGdldFByb3BEZWZhdWx0VmFsdWUodm0sIHByb3AsIGtleSk7CiAgICAgIC8vIHNpbmNlIHRoZSBkZWZhdWx0IHZhbHVlIGlzIGEgZnJlc2ggY29weSwKICAgICAgLy8gbWFrZSBzdXJlIHRvIG9ic2VydmUgaXQuCiAgICAgIHZhciBwcmV2U2hvdWxkT2JzZXJ2ZSA9IHNob3VsZE9ic2VydmU7CiAgICAgIHRvZ2dsZU9ic2VydmluZyh0cnVlKTsKICAgICAgb2JzZXJ2ZSh2YWx1ZSk7CiAgICAgIHRvZ2dsZU9ic2VydmluZyhwcmV2U2hvdWxkT2JzZXJ2ZSk7CiAgICB9CiAgICB7CiAgICAgIGFzc2VydFByb3AocHJvcCwga2V5LCB2YWx1ZSwgdm0sIGFic2VudCk7CiAgICB9CiAgICByZXR1cm4gdmFsdWUKICB9CgogIC8qKgogICAqIEdldCB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBhIHByb3AuCiAgICovCiAgZnVuY3Rpb24gZ2V0UHJvcERlZmF1bHRWYWx1ZSAodm0sIHByb3AsIGtleSkgewogICAgLy8gbm8gZGVmYXVsdCwgcmV0dXJuIHVuZGVmaW5lZAogICAgaWYgKCFoYXNPd24ocHJvcCwgJ2RlZmF1bHQnKSkgewogICAgICByZXR1cm4gdW5kZWZpbmVkCiAgICB9CiAgICB2YXIgZGVmID0gcHJvcC5kZWZhdWx0OwogICAgLy8gd2FybiBhZ2FpbnN0IG5vbi1mYWN0b3J5IGRlZmF1bHRzIGZvciBPYmplY3QgJiBBcnJheQogICAgaWYgKGlzT2JqZWN0KGRlZikpIHsKICAgICAgd2FybigKICAgICAgICAnSW52YWxpZCBkZWZhdWx0IHZhbHVlIGZvciBwcm9wICInICsga2V5ICsgJyI6ICcgKwogICAgICAgICdQcm9wcyB3aXRoIHR5cGUgT2JqZWN0L0FycmF5IG11c3QgdXNlIGEgZmFjdG9yeSBmdW5jdGlvbiAnICsKICAgICAgICAndG8gcmV0dXJuIHRoZSBkZWZhdWx0IHZhbHVlLicsCiAgICAgICAgdm0KICAgICAgKTsKICAgIH0KICAgIC8vIHRoZSByYXcgcHJvcCB2YWx1ZSB3YXMgYWxzbyB1bmRlZmluZWQgZnJvbSBwcmV2aW91cyByZW5kZXIsCiAgICAvLyByZXR1cm4gcHJldmlvdXMgZGVmYXVsdCB2YWx1ZSB0byBhdm9pZCB1bm5lY2Vzc2FyeSB3YXRjaGVyIHRyaWdnZXIKICAgIGlmICh2bSAmJiB2bS4kb3B0aW9ucy5wcm9wc0RhdGEgJiYKICAgICAgdm0uJG9wdGlvbnMucHJvcHNEYXRhW2tleV0gPT09IHVuZGVmaW5lZCAmJgogICAgICB2bS5fcHJvcHNba2V5XSAhPT0gdW5kZWZpbmVkCiAgICApIHsKICAgICAgcmV0dXJuIHZtLl9wcm9wc1trZXldCiAgICB9CiAgICAvLyBjYWxsIGZhY3RvcnkgZnVuY3Rpb24gZm9yIG5vbi1GdW5jdGlvbiB0eXBlcwogICAgLy8gYSB2YWx1ZSBpcyBGdW5jdGlvbiBpZiBpdHMgcHJvdG90eXBlIGlzIGZ1bmN0aW9uIGV2ZW4gYWNyb3NzIGRpZmZlcmVudCBleGVjdXRpb24gY29udGV4dAogICAgcmV0dXJuIHR5cGVvZiBkZWYgPT09ICdmdW5jdGlvbicgJiYgZ2V0VHlwZShwcm9wLnR5cGUpICE9PSAnRnVuY3Rpb24nCiAgICAgID8gZGVmLmNhbGwodm0pCiAgICAgIDogZGVmCiAgfQoKICAvKioKICAgKiBBc3NlcnQgd2hldGhlciBhIHByb3AgaXMgdmFsaWQuCiAgICovCiAgZnVuY3Rpb24gYXNzZXJ0UHJvcCAoCiAgICBwcm9wLAogICAgbmFtZSwKICAgIHZhbHVlLAogICAgdm0sCiAgICBhYnNlbnQKICApIHsKICAgIGlmIChwcm9wLnJlcXVpcmVkICYmIGFic2VudCkgewogICAgICB3YXJuKAogICAgICAgICdNaXNzaW5nIHJlcXVpcmVkIHByb3A6ICInICsgbmFtZSArICciJywKICAgICAgICB2bQogICAgICApOwogICAgICByZXR1cm4KICAgIH0KICAgIGlmICh2YWx1ZSA9PSBudWxsICYmICFwcm9wLnJlcXVpcmVkKSB7CiAgICAgIHJldHVybgogICAgfQogICAgdmFyIHR5cGUgPSBwcm9wLnR5cGU7CiAgICB2YXIgdmFsaWQgPSAhdHlwZSB8fCB0eXBlID09PSB0cnVlOwogICAgdmFyIGV4cGVjdGVkVHlwZXMgPSBbXTsKICAgIGlmICh0eXBlKSB7CiAgICAgIGlmICghQXJyYXkuaXNBcnJheSh0eXBlKSkgewogICAgICAgIHR5cGUgPSBbdHlwZV07CiAgICAgIH0KICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0eXBlLmxlbmd0aCAmJiAhdmFsaWQ7IGkrKykgewogICAgICAgIHZhciBhc3NlcnRlZFR5cGUgPSBhc3NlcnRUeXBlKHZhbHVlLCB0eXBlW2ldKTsKICAgICAgICBleHBlY3RlZFR5cGVzLnB1c2goYXNzZXJ0ZWRUeXBlLmV4cGVjdGVkVHlwZSB8fCAnJyk7CiAgICAgICAgdmFsaWQgPSBhc3NlcnRlZFR5cGUudmFsaWQ7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoIXZhbGlkKSB7CiAgICAgIHdhcm4oCiAgICAgICAgZ2V0SW52YWxpZFR5cGVNZXNzYWdlKG5hbWUsIHZhbHVlLCBleHBlY3RlZFR5cGVzKSwKICAgICAgICB2bQogICAgICApOwogICAgICByZXR1cm4KICAgIH0KICAgIHZhciB2YWxpZGF0b3IgPSBwcm9wLnZhbGlkYXRvcjsKICAgIGlmICh2YWxpZGF0b3IpIHsKICAgICAgaWYgKCF2YWxpZGF0b3IodmFsdWUpKSB7CiAgICAgICAgd2FybigKICAgICAgICAgICdJbnZhbGlkIHByb3A6IGN1c3RvbSB2YWxpZGF0b3IgY2hlY2sgZmFpbGVkIGZvciBwcm9wICInICsgbmFtZSArICciLicsCiAgICAgICAgICB2bQogICAgICAgICk7CiAgICAgIH0KICAgIH0KICB9CgogIHZhciBzaW1wbGVDaGVja1JFID0gL14oU3RyaW5nfE51bWJlcnxCb29sZWFufEZ1bmN0aW9ufFN5bWJvbCkkLzsKCiAgZnVuY3Rpb24gYXNzZXJ0VHlwZSAodmFsdWUsIHR5cGUpIHsKICAgIHZhciB2YWxpZDsKICAgIHZhciBleHBlY3RlZFR5cGUgPSBnZXRUeXBlKHR5cGUpOwogICAgaWYgKHNpbXBsZUNoZWNrUkUudGVzdChleHBlY3RlZFR5cGUpKSB7CiAgICAgIHZhciB0ID0gdHlwZW9mIHZhbHVlOwogICAgICB2YWxpZCA9IHQgPT09IGV4cGVjdGVkVHlwZS50b0xvd2VyQ2FzZSgpOwogICAgICAvLyBmb3IgcHJpbWl0aXZlIHdyYXBwZXIgb2JqZWN0cwogICAgICBpZiAoIXZhbGlkICYmIHQgPT09ICdvYmplY3QnKSB7CiAgICAgICAgdmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIHR5cGU7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnT2JqZWN0JykgewogICAgICB2YWxpZCA9IGlzUGxhaW5PYmplY3QodmFsdWUpOwogICAgfSBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICdBcnJheScpIHsKICAgICAgdmFsaWQgPSBBcnJheS5pc0FycmF5KHZhbHVlKTsKICAgIH0gZWxzZSB7CiAgICAgIHZhbGlkID0gdmFsdWUgaW5zdGFuY2VvZiB0eXBlOwogICAgfQogICAgcmV0dXJuIHsKICAgICAgdmFsaWQ6IHZhbGlkLAogICAgICBleHBlY3RlZFR5cGU6IGV4cGVjdGVkVHlwZQogICAgfQogIH0KCiAgLyoqCiAgICogVXNlIGZ1bmN0aW9uIHN0cmluZyBuYW1lIHRvIGNoZWNrIGJ1aWx0LWluIHR5cGVzLAogICAqIGJlY2F1c2UgYSBzaW1wbGUgZXF1YWxpdHkgY2hlY2sgd2lsbCBmYWlsIHdoZW4gcnVubmluZwogICAqIGFjcm9zcyBkaWZmZXJlbnQgdm1zIC8gaWZyYW1lcy4KICAgKi8KICBmdW5jdGlvbiBnZXRUeXBlIChmbikgewogICAgdmFyIG1hdGNoID0gZm4gJiYgZm4udG9TdHJpbmcoKS5tYXRjaCgvXlxzKmZ1bmN0aW9uIChcdyspLyk7CiAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXSA6ICcnCiAgfQoKICBmdW5jdGlvbiBpc1NhbWVUeXBlIChhLCBiKSB7CiAgICByZXR1cm4gZ2V0VHlwZShhKSA9PT0gZ2V0VHlwZShiKQogIH0KCiAgZnVuY3Rpb24gZ2V0VHlwZUluZGV4ICh0eXBlLCBleHBlY3RlZFR5cGVzKSB7CiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZXhwZWN0ZWRUeXBlcykpIHsKICAgICAgcmV0dXJuIGlzU2FtZVR5cGUoZXhwZWN0ZWRUeXBlcywgdHlwZSkgPyAwIDogLTEKICAgIH0KICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBleHBlY3RlZFR5cGVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgIGlmIChpc1NhbWVUeXBlKGV4cGVjdGVkVHlwZXNbaV0sIHR5cGUpKSB7CiAgICAgICAgcmV0dXJuIGkKICAgICAgfQogICAgfQogICAgcmV0dXJuIC0xCiAgfQoKICBmdW5jdGlvbiBnZXRJbnZhbGlkVHlwZU1lc3NhZ2UgKG5hbWUsIHZhbHVlLCBleHBlY3RlZFR5cGVzKSB7CiAgICB2YXIgbWVzc2FnZSA9ICJJbnZhbGlkIHByb3A6IHR5cGUgY2hlY2sgZmFpbGVkIGZvciBwcm9wIFwiIiArIG5hbWUgKyAiXCIuIiArCiAgICAgICIgRXhwZWN0ZWQgIiArIChleHBlY3RlZFR5cGVzLm1hcChjYXBpdGFsaXplKS5qb2luKCcsICcpKTsKICAgIHZhciBleHBlY3RlZFR5cGUgPSBleHBlY3RlZFR5cGVzWzBdOwogICAgdmFyIHJlY2VpdmVkVHlwZSA9IHRvUmF3VHlwZSh2YWx1ZSk7CiAgICB2YXIgZXhwZWN0ZWRWYWx1ZSA9IHN0eWxlVmFsdWUodmFsdWUsIGV4cGVjdGVkVHlwZSk7CiAgICB2YXIgcmVjZWl2ZWRWYWx1ZSA9IHN0eWxlVmFsdWUodmFsdWUsIHJlY2VpdmVkVHlwZSk7CiAgICAvLyBjaGVjayBpZiB3ZSBuZWVkIHRvIHNwZWNpZnkgZXhwZWN0ZWQgdmFsdWUKICAgIGlmIChleHBlY3RlZFR5cGVzLmxlbmd0aCA9PT0gMSAmJgogICAgICAgIGlzRXhwbGljYWJsZShleHBlY3RlZFR5cGUpICYmCiAgICAgICAgIWlzQm9vbGVhbihleHBlY3RlZFR5cGUsIHJlY2VpdmVkVHlwZSkpIHsKICAgICAgbWVzc2FnZSArPSAiIHdpdGggdmFsdWUgIiArIGV4cGVjdGVkVmFsdWU7CiAgICB9CiAgICBtZXNzYWdlICs9ICIsIGdvdCAiICsgcmVjZWl2ZWRUeXBlICsgIiAiOwogICAgLy8gY2hlY2sgaWYgd2UgbmVlZCB0byBzcGVjaWZ5IHJlY2VpdmVkIHZhbHVlCiAgICBpZiAoaXNFeHBsaWNhYmxlKHJlY2VpdmVkVHlwZSkpIHsKICAgICAgbWVzc2FnZSArPSAid2l0aCB2YWx1ZSAiICsgcmVjZWl2ZWRWYWx1ZSArICIuIjsKICAgIH0KICAgIHJldHVybiBtZXNzYWdlCiAgfQoKICBmdW5jdGlvbiBzdHlsZVZhbHVlICh2YWx1ZSwgdHlwZSkgewogICAgaWYgKHR5cGUgPT09ICdTdHJpbmcnKSB7CiAgICAgIHJldHVybiAoIlwiIiArIHZhbHVlICsgIlwiIikKICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ051bWJlcicpIHsKICAgICAgcmV0dXJuICgiIiArIChOdW1iZXIodmFsdWUpKSkKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiAoIiIgKyB2YWx1ZSkKICAgIH0KICB9CgogIGZ1bmN0aW9uIGlzRXhwbGljYWJsZSAodmFsdWUpIHsKICAgIHZhciBleHBsaWNpdFR5cGVzID0gWydzdHJpbmcnLCAnbnVtYmVyJywgJ2Jvb2xlYW4nXTsKICAgIHJldHVybiBleHBsaWNpdFR5cGVzLnNvbWUoZnVuY3Rpb24gKGVsZW0pIHsgcmV0dXJuIHZhbHVlLnRvTG93ZXJDYXNlKCkgPT09IGVsZW07IH0pCiAgfQoKICBmdW5jdGlvbiBpc0Jvb2xlYW4gKCkgewogICAgdmFyIGFyZ3MgPSBbXSwgbGVuID0gYXJndW1lbnRzLmxlbmd0aDsKICAgIHdoaWxlICggbGVuLS0gKSBhcmdzWyBsZW4gXSA9IGFyZ3VtZW50c1sgbGVuIF07CgogICAgcmV0dXJuIGFyZ3Muc29tZShmdW5jdGlvbiAoZWxlbSkgeyByZXR1cm4gZWxlbS50b0xvd2VyQ2FzZSgpID09PSAnYm9vbGVhbic7IH0pCiAgfQoKICAvKiAgKi8KCiAgZnVuY3Rpb24gaGFuZGxlRXJyb3IgKGVyciwgdm0sIGluZm8pIHsKICAgIC8vIERlYWN0aXZhdGUgZGVwcyB0cmFja2luZyB3aGlsZSBwcm9jZXNzaW5nIGVycm9yIGhhbmRsZXIgdG8gYXZvaWQgcG9zc2libGUgaW5maW5pdGUgcmVuZGVyaW5nLgogICAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vdnVlanMvdnVleC9pc3N1ZXMvMTUwNQogICAgcHVzaFRhcmdldCgpOwogICAgdHJ5IHsKICAgICAgaWYgKHZtKSB7CiAgICAgICAgdmFyIGN1ciA9IHZtOwogICAgICAgIHdoaWxlICgoY3VyID0gY3VyLiRwYXJlbnQpKSB7CiAgICAgICAgICB2YXIgaG9va3MgPSBjdXIuJG9wdGlvbnMuZXJyb3JDYXB0dXJlZDsKICAgICAgICAgIGlmIChob29rcykgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhvb2tzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHZhciBjYXB0dXJlID0gaG9va3NbaV0uY2FsbChjdXIsIGVyciwgdm0sIGluZm8pID09PSBmYWxzZTsKICAgICAgICAgICAgICAgIGlmIChjYXB0dXJlKSB7IHJldHVybiB9CiAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgZ2xvYmFsSGFuZGxlRXJyb3IoZSwgY3VyLCAnZXJyb3JDYXB0dXJlZCBob29rJyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIGdsb2JhbEhhbmRsZUVycm9yKGVyciwgdm0sIGluZm8pOwogICAgfSBmaW5hbGx5IHsKICAgICAgcG9wVGFyZ2V0KCk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBpbnZva2VXaXRoRXJyb3JIYW5kbGluZyAoCiAgICBoYW5kbGVyLAogICAgY29udGV4dCwKICAgIGFyZ3MsCiAgICB2bSwKICAgIGluZm8KICApIHsKICAgIHZhciByZXM7CiAgICB0cnkgewogICAgICByZXMgPSBhcmdzID8gaGFuZGxlci5hcHBseShjb250ZXh0LCBhcmdzKSA6IGhhbmRsZXIuY2FsbChjb250ZXh0KTsKICAgICAgaWYgKHJlcyAmJiAhcmVzLl9pc1Z1ZSAmJiBpc1Byb21pc2UocmVzKSAmJiAhcmVzLl9oYW5kbGVkKSB7CiAgICAgICAgcmVzLmNhdGNoKGZ1bmN0aW9uIChlKSB7IHJldHVybiBoYW5kbGVFcnJvcihlLCB2bSwgaW5mbyArICIgKFByb21pc2UvYXN5bmMpIik7IH0pOwogICAgICAgIC8vIGlzc3VlICM5NTExCiAgICAgICAgLy8gYXZvaWQgY2F0Y2ggdHJpZ2dlcmluZyBtdWx0aXBsZSB0aW1lcyB3aGVuIG5lc3RlZCBjYWxscwogICAgICAgIHJlcy5faGFuZGxlZCA9IHRydWU7CiAgICAgIH0KICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgaGFuZGxlRXJyb3IoZSwgdm0sIGluZm8pOwogICAgfQogICAgcmV0dXJuIHJlcwogIH0KCiAgZnVuY3Rpb24gZ2xvYmFsSGFuZGxlRXJyb3IgKGVyciwgdm0sIGluZm8pIHsKICAgIGlmIChjb25maWcuZXJyb3JIYW5kbGVyKSB7CiAgICAgIHRyeSB7CiAgICAgICAgcmV0dXJuIGNvbmZpZy5lcnJvckhhbmRsZXIuY2FsbChudWxsLCBlcnIsIHZtLCBpbmZvKQogICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgLy8gaWYgdGhlIHVzZXIgaW50ZW50aW9uYWxseSB0aHJvd3MgdGhlIG9yaWdpbmFsIGVycm9yIGluIHRoZSBoYW5kbGVyLAogICAgICAgIC8vIGRvIG5vdCBsb2cgaXQgdHdpY2UKICAgICAgICBpZiAoZSAhPT0gZXJyKSB7CiAgICAgICAgICBsb2dFcnJvcihlLCBudWxsLCAnY29uZmlnLmVycm9ySGFuZGxlcicpOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgbG9nRXJyb3IoZXJyLCB2bSwgaW5mbyk7CiAgfQoKICBmdW5jdGlvbiBsb2dFcnJvciAoZXJyLCB2bSwgaW5mbykgewogICAgewogICAgICB3YXJuKCgiRXJyb3IgaW4gIiArIGluZm8gKyAiOiBcIiIgKyAoZXJyLnRvU3RyaW5nKCkpICsgIlwiIiksIHZtKTsKICAgIH0KICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovCiAgICBpZiAoKGluQnJvd3NlciB8fCBpbldlZXgpICYmIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJykgewogICAgICBjb25zb2xlLmVycm9yKGVycik7CiAgICB9IGVsc2UgewogICAgICB0aHJvdyBlcnIKICAgIH0KICB9CgogIC8qICAqLwoKICB2YXIgaXNVc2luZ01pY3JvVGFzayA9IGZhbHNlOwoKICB2YXIgY2FsbGJhY2tzID0gW107CiAgdmFyIHBlbmRpbmcgPSBmYWxzZTsKCiAgZnVuY3Rpb24gZmx1c2hDYWxsYmFja3MgKCkgewogICAgcGVuZGluZyA9IGZhbHNlOwogICAgdmFyIGNvcGllcyA9IGNhbGxiYWNrcy5zbGljZSgwKTsKICAgIGNhbGxiYWNrcy5sZW5ndGggPSAwOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3BpZXMubGVuZ3RoOyBpKyspIHsKICAgICAgY29waWVzW2ldKCk7CiAgICB9CiAgfQoKICAvLyBIZXJlIHdlIGhhdmUgYXN5bmMgZGVmZXJyaW5nIHdyYXBwZXJzIHVzaW5nIG1pY3JvdGFza3MuCiAgLy8gSW4gMi41IHdlIHVzZWQgKG1hY3JvKSB0YXNrcyAoaW4gY29tYmluYXRpb24gd2l0aCBtaWNyb3Rhc2tzKS4KICAvLyBIb3dldmVyLCBpdCBoYXMgc3VidGxlIHByb2JsZW1zIHdoZW4gc3RhdGUgaXMgY2hhbmdlZCByaWdodCBiZWZvcmUgcmVwYWludAogIC8vIChlLmcuICM2ODEzLCBvdXQtaW4gdHJhbnNpdGlvbnMpLgogIC8vIEFsc28sIHVzaW5nIChtYWNybykgdGFza3MgaW4gZXZlbnQgaGFuZGxlciB3b3VsZCBjYXVzZSBzb21lIHdlaXJkIGJlaGF2aW9ycwogIC8vIHRoYXQgY2Fubm90IGJlIGNpcmN1bXZlbnRlZCAoZS5nLiAjNzEwOSwgIzcxNTMsICM3NTQ2LCAjNzgzNCwgIzgxMDkpLgogIC8vIFNvIHdlIG5vdyB1c2UgbWljcm90YXNrcyBldmVyeXdoZXJlLCBhZ2Fpbi4KICAvLyBBIG1ham9yIGRyYXdiYWNrIG9mIHRoaXMgdHJhZGVvZmYgaXMgdGhhdCB0aGVyZSBhcmUgc29tZSBzY2VuYXJpb3MKICAvLyB3aGVyZSBtaWNyb3Rhc2tzIGhhdmUgdG9vIGhpZ2ggYSBwcmlvcml0eSBhbmQgZmlyZSBpbiBiZXR3ZWVuIHN1cHBvc2VkbHkKICAvLyBzZXF1ZW50aWFsIGV2ZW50cyAoZS5nLiAjNDUyMSwgIzY2OTAsIHdoaWNoIGhhdmUgd29ya2Fyb3VuZHMpCiAgLy8gb3IgZXZlbiBiZXR3ZWVuIGJ1YmJsaW5nIG9mIHRoZSBzYW1lIGV2ZW50ICgjNjU2NikuCiAgdmFyIHRpbWVyRnVuYzsKCiAgLy8gVGhlIG5leHRUaWNrIGJlaGF2aW9yIGxldmVyYWdlcyB0aGUgbWljcm90YXNrIHF1ZXVlLCB3aGljaCBjYW4gYmUgYWNjZXNzZWQKICAvLyB2aWEgZWl0aGVyIG5hdGl2ZSBQcm9taXNlLnRoZW4gb3IgTXV0YXRpb25PYnNlcnZlci4KICAvLyBNdXRhdGlvbk9ic2VydmVyIGhhcyB3aWRlciBzdXBwb3J0LCBob3dldmVyIGl0IGlzIHNlcmlvdXNseSBidWdnZWQgaW4KICAvLyBVSVdlYlZpZXcgaW4gaU9TID49IDkuMy4zIHdoZW4gdHJpZ2dlcmVkIGluIHRvdWNoIGV2ZW50IGhhbmRsZXJzLiBJdAogIC8vIGNvbXBsZXRlbHkgc3RvcHMgd29ya2luZyBhZnRlciB0cmlnZ2VyaW5nIGEgZmV3IHRpbWVzLi4uIHNvLCBpZiBuYXRpdmUKICAvLyBQcm9taXNlIGlzIGF2YWlsYWJsZSwgd2Ugd2lsbCB1c2UgaXQ6CiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQsICRmbG93LWRpc2FibGUtbGluZSAqLwogIGlmICh0eXBlb2YgUHJvbWlzZSAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNOYXRpdmUoUHJvbWlzZSkpIHsKICAgIHZhciBwID0gUHJvbWlzZS5yZXNvbHZlKCk7CiAgICB0aW1lckZ1bmMgPSBmdW5jdGlvbiAoKSB7CiAgICAgIHAudGhlbihmbHVzaENhbGxiYWNrcyk7CiAgICAgIC8vIEluIHByb2JsZW1hdGljIFVJV2ViVmlld3MsIFByb21pc2UudGhlbiBkb2Vzbid0IGNvbXBsZXRlbHkgYnJlYWssIGJ1dAogICAgICAvLyBpdCBjYW4gZ2V0IHN0dWNrIGluIGEgd2VpcmQgc3RhdGUgd2hlcmUgY2FsbGJhY2tzIGFyZSBwdXNoZWQgaW50byB0aGUKICAgICAgLy8gbWljcm90YXNrIHF1ZXVlIGJ1dCB0aGUgcXVldWUgaXNuJ3QgYmVpbmcgZmx1c2hlZCwgdW50aWwgdGhlIGJyb3dzZXIKICAgICAgLy8gbmVlZHMgdG8gZG8gc29tZSBvdGhlciB3b3JrLCBlLmcuIGhhbmRsZSBhIHRpbWVyLiBUaGVyZWZvcmUgd2UgY2FuCiAgICAgIC8vICJmb3JjZSIgdGhlIG1pY3JvdGFzayBxdWV1ZSB0byBiZSBmbHVzaGVkIGJ5IGFkZGluZyBhbiBlbXB0eSB0aW1lci4KICAgICAgaWYgKGlzSU9TKSB7IHNldFRpbWVvdXQobm9vcCk7IH0KICAgIH07CiAgICBpc1VzaW5nTWljcm9UYXNrID0gdHJ1ZTsKICB9IGVsc2UgaWYgKCFpc0lFICYmIHR5cGVvZiBNdXRhdGlvbk9ic2VydmVyICE9PSAndW5kZWZpbmVkJyAmJiAoCiAgICBpc05hdGl2ZShNdXRhdGlvbk9ic2VydmVyKSB8fAogICAgLy8gUGhhbnRvbUpTIGFuZCBpT1MgNy54CiAgICBNdXRhdGlvbk9ic2VydmVyLnRvU3RyaW5nKCkgPT09ICdbb2JqZWN0IE11dGF0aW9uT2JzZXJ2ZXJDb25zdHJ1Y3Rvcl0nCiAgKSkgewogICAgLy8gVXNlIE11dGF0aW9uT2JzZXJ2ZXIgd2hlcmUgbmF0aXZlIFByb21pc2UgaXMgbm90IGF2YWlsYWJsZSwKICAgIC8vIGUuZy4gUGhhbnRvbUpTLCBpT1M3LCBBbmRyb2lkIDQuNAogICAgLy8gKCM2NDY2IE11dGF0aW9uT2JzZXJ2ZXIgaXMgdW5yZWxpYWJsZSBpbiBJRTExKQogICAgdmFyIGNvdW50ZXIgPSAxOwogICAgdmFyIG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoZmx1c2hDYWxsYmFja3MpOwogICAgdmFyIHRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoU3RyaW5nKGNvdW50ZXIpKTsKICAgIG9ic2VydmVyLm9ic2VydmUodGV4dE5vZGUsIHsKICAgICAgY2hhcmFjdGVyRGF0YTogdHJ1ZQogICAgfSk7CiAgICB0aW1lckZ1bmMgPSBmdW5jdGlvbiAoKSB7CiAgICAgIGNvdW50ZXIgPSAoY291bnRlciArIDEpICUgMjsKICAgICAgdGV4dE5vZGUuZGF0YSA9IFN0cmluZyhjb3VudGVyKTsKICAgIH07CiAgICBpc1VzaW5nTWljcm9UYXNrID0gdHJ1ZTsKICB9IGVsc2UgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgIT09ICd1bmRlZmluZWQnICYmIGlzTmF0aXZlKHNldEltbWVkaWF0ZSkpIHsKICAgIC8vIEZhbGxiYWNrIHRvIHNldEltbWVkaWF0ZS4KICAgIC8vIFRlY2hpbmljYWxseSBpdCBsZXZlcmFnZXMgdGhlIChtYWNybykgdGFzayBxdWV1ZSwKICAgIC8vIGJ1dCBpdCBpcyBzdGlsbCBhIGJldHRlciBjaG9pY2UgdGhhbiBzZXRUaW1lb3V0LgogICAgdGltZXJGdW5jID0gZnVuY3Rpb24gKCkgewogICAgICBzZXRJbW1lZGlhdGUoZmx1c2hDYWxsYmFja3MpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gRmFsbGJhY2sgdG8gc2V0VGltZW91dC4KICAgIHRpbWVyRnVuYyA9IGZ1bmN0aW9uICgpIHsKICAgICAgc2V0VGltZW91dChmbHVzaENhbGxiYWNrcywgMCk7CiAgICB9OwogIH0KCiAgZnVuY3Rpb24gbmV4dFRpY2sgKGNiLCBjdHgpIHsKICAgIHZhciBfcmVzb2x2ZTsKICAgIGNhbGxiYWNrcy5wdXNoKGZ1bmN0aW9uICgpIHsKICAgICAgaWYgKGNiKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGNiLmNhbGwoY3R4KTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICBoYW5kbGVFcnJvcihlLCBjdHgsICduZXh0VGljaycpOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChfcmVzb2x2ZSkgewogICAgICAgIF9yZXNvbHZlKGN0eCk7CiAgICAgIH0KICAgIH0pOwogICAgaWYgKCFwZW5kaW5nKSB7CiAgICAgIHBlbmRpbmcgPSB0cnVlOwogICAgICB0aW1lckZ1bmMoKTsKICAgIH0KICAgIC8vICRmbG93LWRpc2FibGUtbGluZQogICAgaWYgKCFjYiAmJiB0eXBlb2YgUHJvbWlzZSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7CiAgICAgICAgX3Jlc29sdmUgPSByZXNvbHZlOwogICAgICB9KQogICAgfQogIH0KCiAgLyogICovCgogIHZhciBtYXJrOwogIHZhciBtZWFzdXJlOwoKICB7CiAgICB2YXIgcGVyZiA9IGluQnJvd3NlciAmJiB3aW5kb3cucGVyZm9ybWFuY2U7CiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgIGlmICgKICAgICAgcGVyZiAmJgogICAgICBwZXJmLm1hcmsgJiYKICAgICAgcGVyZi5tZWFzdXJlICYmCiAgICAgIHBlcmYuY2xlYXJNYXJrcyAmJgogICAgICBwZXJmLmNsZWFyTWVhc3VyZXMKICAgICkgewogICAgICBtYXJrID0gZnVuY3Rpb24gKHRhZykgeyByZXR1cm4gcGVyZi5tYXJrKHRhZyk7IH07CiAgICAgIG1lYXN1cmUgPSBmdW5jdGlvbiAobmFtZSwgc3RhcnRUYWcsIGVuZFRhZykgewogICAgICAgIHBlcmYubWVhc3VyZShuYW1lLCBzdGFydFRhZywgZW5kVGFnKTsKICAgICAgICBwZXJmLmNsZWFyTWFya3Moc3RhcnRUYWcpOwogICAgICAgIHBlcmYuY2xlYXJNYXJrcyhlbmRUYWcpOwogICAgICAgIC8vIHBlcmYuY2xlYXJNZWFzdXJlcyhuYW1lKQogICAgICB9OwogICAgfQogIH0KCiAgLyogbm90IHR5cGUgY2hlY2tpbmcgdGhpcyBmaWxlIGJlY2F1c2UgZmxvdyBkb2Vzbid0IHBsYXkgd2VsbCB3aXRoIFByb3h5ICovCgogIHZhciBpbml0UHJveHk7CgogIHsKICAgIHZhciBhbGxvd2VkR2xvYmFscyA9IG1ha2VNYXAoCiAgICAgICdJbmZpbml0eSx1bmRlZmluZWQsTmFOLGlzRmluaXRlLGlzTmFOLCcgKwogICAgICAncGFyc2VGbG9hdCxwYXJzZUludCxkZWNvZGVVUkksZGVjb2RlVVJJQ29tcG9uZW50LGVuY29kZVVSSSxlbmNvZGVVUklDb21wb25lbnQsJyArCiAgICAgICdNYXRoLE51bWJlcixEYXRlLEFycmF5LE9iamVjdCxCb29sZWFuLFN0cmluZyxSZWdFeHAsTWFwLFNldCxKU09OLEludGwsJyArCiAgICAgICdyZXF1aXJlJyAvLyBmb3IgV2VicGFjay9Ccm93c2VyaWZ5CiAgICApOwoKICAgIHZhciB3YXJuTm9uUHJlc2VudCA9IGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgewogICAgICB3YXJuKAogICAgICAgICJQcm9wZXJ0eSBvciBtZXRob2QgXCIiICsga2V5ICsgIlwiIGlzIG5vdCBkZWZpbmVkIG9uIHRoZSBpbnN0YW5jZSBidXQgIiArCiAgICAgICAgJ3JlZmVyZW5jZWQgZHVyaW5nIHJlbmRlci4gTWFrZSBzdXJlIHRoYXQgdGhpcyBwcm9wZXJ0eSBpcyByZWFjdGl2ZSwgJyArCiAgICAgICAgJ2VpdGhlciBpbiB0aGUgZGF0YSBvcHRpb24sIG9yIGZvciBjbGFzcy1iYXNlZCBjb21wb25lbnRzLCBieSAnICsKICAgICAgICAnaW5pdGlhbGl6aW5nIHRoZSBwcm9wZXJ0eS4gJyArCiAgICAgICAgJ1NlZTogaHR0cHM6Ly92dWVqcy5vcmcvdjIvZ3VpZGUvcmVhY3Rpdml0eS5odG1sI0RlY2xhcmluZy1SZWFjdGl2ZS1Qcm9wZXJ0aWVzLicsCiAgICAgICAgdGFyZ2V0CiAgICAgICk7CiAgICB9OwoKICAgIHZhciB3YXJuUmVzZXJ2ZWRQcmVmaXggPSBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsKICAgICAgd2FybigKICAgICAgICAiUHJvcGVydHkgXCIiICsga2V5ICsgIlwiIG11c3QgYmUgYWNjZXNzZWQgd2l0aCBcIiRkYXRhLiIgKyBrZXkgKyAiXCIgYmVjYXVzZSAiICsKICAgICAgICAncHJvcGVydGllcyBzdGFydGluZyB3aXRoICIkIiBvciAiXyIgYXJlIG5vdCBwcm94aWVkIGluIHRoZSBWdWUgaW5zdGFuY2UgdG8gJyArCiAgICAgICAgJ3ByZXZlbnQgY29uZmxpY3RzIHdpdGggVnVlIGludGVybmFscycgKwogICAgICAgICdTZWU6IGh0dHBzOi8vdnVlanMub3JnL3YyL2FwaS8jZGF0YScsCiAgICAgICAgdGFyZ2V0CiAgICAgICk7CiAgICB9OwoKICAgIHZhciBoYXNQcm94eSA9CiAgICAgIHR5cGVvZiBQcm94eSAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNOYXRpdmUoUHJveHkpOwoKICAgIGlmIChoYXNQcm94eSkgewogICAgICB2YXIgaXNCdWlsdEluTW9kaWZpZXIgPSBtYWtlTWFwKCdzdG9wLHByZXZlbnQsc2VsZixjdHJsLHNoaWZ0LGFsdCxtZXRhLGV4YWN0Jyk7CiAgICAgIGNvbmZpZy5rZXlDb2RlcyA9IG5ldyBQcm94eShjb25maWcua2V5Q29kZXMsIHsKICAgICAgICBzZXQ6IGZ1bmN0aW9uIHNldCAodGFyZ2V0LCBrZXksIHZhbHVlKSB7CiAgICAgICAgICBpZiAoaXNCdWlsdEluTW9kaWZpZXIoa2V5KSkgewogICAgICAgICAgICB3YXJuKCgiQXZvaWQgb3ZlcndyaXRpbmcgYnVpbHQtaW4gbW9kaWZpZXIgaW4gY29uZmlnLmtleUNvZGVzOiAuIiArIGtleSkpOwogICAgICAgICAgICByZXR1cm4gZmFsc2UKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRhcmdldFtrZXldID0gdmFsdWU7CiAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9KTsKICAgIH0KCiAgICB2YXIgaGFzSGFuZGxlciA9IHsKICAgICAgaGFzOiBmdW5jdGlvbiBoYXMgKHRhcmdldCwga2V5KSB7CiAgICAgICAgdmFyIGhhcyA9IGtleSBpbiB0YXJnZXQ7CiAgICAgICAgdmFyIGlzQWxsb3dlZCA9IGFsbG93ZWRHbG9iYWxzKGtleSkgfHwKICAgICAgICAgICh0eXBlb2Yga2V5ID09PSAnc3RyaW5nJyAmJiBrZXkuY2hhckF0KDApID09PSAnXycgJiYgIShrZXkgaW4gdGFyZ2V0LiRkYXRhKSk7CiAgICAgICAgaWYgKCFoYXMgJiYgIWlzQWxsb3dlZCkgewogICAgICAgICAgaWYgKGtleSBpbiB0YXJnZXQuJGRhdGEpIHsgd2FyblJlc2VydmVkUHJlZml4KHRhcmdldCwga2V5KTsgfQogICAgICAgICAgZWxzZSB7IHdhcm5Ob25QcmVzZW50KHRhcmdldCwga2V5KTsgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaGFzIHx8ICFpc0FsbG93ZWQKICAgICAgfQogICAgfTsKCiAgICB2YXIgZ2V0SGFuZGxlciA9IHsKICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQgKHRhcmdldCwga2V5KSB7CiAgICAgICAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnICYmICEoa2V5IGluIHRhcmdldCkpIHsKICAgICAgICAgIGlmIChrZXkgaW4gdGFyZ2V0LiRkYXRhKSB7IHdhcm5SZXNlcnZlZFByZWZpeCh0YXJnZXQsIGtleSk7IH0KICAgICAgICAgIGVsc2UgeyB3YXJuTm9uUHJlc2VudCh0YXJnZXQsIGtleSk7IH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRhcmdldFtrZXldCiAgICAgIH0KICAgIH07CgogICAgaW5pdFByb3h5ID0gZnVuY3Rpb24gaW5pdFByb3h5ICh2bSkgewogICAgICBpZiAoaGFzUHJveHkpIHsKICAgICAgICAvLyBkZXRlcm1pbmUgd2hpY2ggcHJveHkgaGFuZGxlciB0byB1c2UKICAgICAgICB2YXIgb3B0aW9ucyA9IHZtLiRvcHRpb25zOwogICAgICAgIHZhciBoYW5kbGVycyA9IG9wdGlvbnMucmVuZGVyICYmIG9wdGlvbnMucmVuZGVyLl93aXRoU3RyaXBwZWQKICAgICAgICAgID8gZ2V0SGFuZGxlcgogICAgICAgICAgOiBoYXNIYW5kbGVyOwogICAgICAgIHZtLl9yZW5kZXJQcm94eSA9IG5ldyBQcm94eSh2bSwgaGFuZGxlcnMpOwogICAgICB9IGVsc2UgewogICAgICAgIHZtLl9yZW5kZXJQcm94eSA9IHZtOwogICAgICB9CiAgICB9OwogIH0KCiAgLyogICovCgogIHZhciBzZWVuT2JqZWN0cyA9IG5ldyBfU2V0KCk7CgogIC8qKgogICAqIFJlY3Vyc2l2ZWx5IHRyYXZlcnNlIGFuIG9iamVjdCB0byBldm9rZSBhbGwgY29udmVydGVkCiAgICogZ2V0dGVycywgc28gdGhhdCBldmVyeSBuZXN0ZWQgcHJvcGVydHkgaW5zaWRlIHRoZSBvYmplY3QKICAgKiBpcyBjb2xsZWN0ZWQgYXMgYSAiZGVlcCIgZGVwZW5kZW5jeS4KICAgKi8KICBmdW5jdGlvbiB0cmF2ZXJzZSAodmFsKSB7CiAgICBfdHJhdmVyc2UodmFsLCBzZWVuT2JqZWN0cyk7CiAgICBzZWVuT2JqZWN0cy5jbGVhcigpOwogIH0KCiAgZnVuY3Rpb24gX3RyYXZlcnNlICh2YWwsIHNlZW4pIHsKICAgIHZhciBpLCBrZXlzOwogICAgdmFyIGlzQSA9IEFycmF5LmlzQXJyYXkodmFsKTsKICAgIGlmICgoIWlzQSAmJiAhaXNPYmplY3QodmFsKSkgfHwgT2JqZWN0LmlzRnJvemVuKHZhbCkgfHwgdmFsIGluc3RhbmNlb2YgVk5vZGUpIHsKICAgICAgcmV0dXJuCiAgICB9CiAgICBpZiAodmFsLl9fb2JfXykgewogICAgICB2YXIgZGVwSWQgPSB2YWwuX19vYl9fLmRlcC5pZDsKICAgICAgaWYgKHNlZW4uaGFzKGRlcElkKSkgewogICAgICAgIHJldHVybgogICAgICB9CiAgICAgIHNlZW4uYWRkKGRlcElkKTsKICAgIH0KICAgIGlmIChpc0EpIHsKICAgICAgaSA9IHZhbC5sZW5ndGg7CiAgICAgIHdoaWxlIChpLS0pIHsgX3RyYXZlcnNlKHZhbFtpXSwgc2Vlbik7IH0KICAgIH0gZWxzZSB7CiAgICAgIGtleXMgPSBPYmplY3Qua2V5cyh2YWwpOwogICAgICBpID0ga2V5cy5sZW5ndGg7CiAgICAgIHdoaWxlIChpLS0pIHsgX3RyYXZlcnNlKHZhbFtrZXlzW2ldXSwgc2Vlbik7IH0KICAgIH0KICB9CgogIC8qICAqLwoKICB2YXIgbm9ybWFsaXplRXZlbnQgPSBjYWNoZWQoZnVuY3Rpb24gKG5hbWUpIHsKICAgIHZhciBwYXNzaXZlID0gbmFtZS5jaGFyQXQoMCkgPT09ICcmJzsKICAgIG5hbWUgPSBwYXNzaXZlID8gbmFtZS5zbGljZSgxKSA6IG5hbWU7CiAgICB2YXIgb25jZSQkMSA9IG5hbWUuY2hhckF0KDApID09PSAnfic7IC8vIFByZWZpeGVkIGxhc3QsIGNoZWNrZWQgZmlyc3QKICAgIG5hbWUgPSBvbmNlJCQxID8gbmFtZS5zbGljZSgxKSA6IG5hbWU7CiAgICB2YXIgY2FwdHVyZSA9IG5hbWUuY2hhckF0KDApID09PSAnISc7CiAgICBuYW1lID0gY2FwdHVyZSA/IG5hbWUuc2xpY2UoMSkgOiBuYW1lOwogICAgcmV0dXJuIHsKICAgICAgbmFtZTogbmFtZSwKICAgICAgb25jZTogb25jZSQkMSwKICAgICAgY2FwdHVyZTogY2FwdHVyZSwKICAgICAgcGFzc2l2ZTogcGFzc2l2ZQogICAgfQogIH0pOwoKICBmdW5jdGlvbiBjcmVhdGVGbkludm9rZXIgKGZucywgdm0pIHsKICAgIGZ1bmN0aW9uIGludm9rZXIgKCkgewogICAgICB2YXIgYXJndW1lbnRzJDEgPSBhcmd1bWVudHM7CgogICAgICB2YXIgZm5zID0gaW52b2tlci5mbnM7CiAgICAgIGlmIChBcnJheS5pc0FycmF5KGZucykpIHsKICAgICAgICB2YXIgY2xvbmVkID0gZm5zLnNsaWNlKCk7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjbG9uZWQubGVuZ3RoOyBpKyspIHsKICAgICAgICAgIGludm9rZVdpdGhFcnJvckhhbmRsaW5nKGNsb25lZFtpXSwgbnVsbCwgYXJndW1lbnRzJDEsIHZtLCAidi1vbiBoYW5kbGVyIik7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIHJldHVybiBoYW5kbGVyIHJldHVybiB2YWx1ZSBmb3Igc2luZ2xlIGhhbmRsZXJzCiAgICAgICAgcmV0dXJuIGludm9rZVdpdGhFcnJvckhhbmRsaW5nKGZucywgbnVsbCwgYXJndW1lbnRzLCB2bSwgInYtb24gaGFuZGxlciIpCiAgICAgIH0KICAgIH0KICAgIGludm9rZXIuZm5zID0gZm5zOwogICAgcmV0dXJuIGludm9rZXIKICB9CgogIGZ1bmN0aW9uIHVwZGF0ZUxpc3RlbmVycyAoCiAgICBvbiwKICAgIG9sZE9uLAogICAgYWRkLAogICAgcmVtb3ZlJCQxLAogICAgY3JlYXRlT25jZUhhbmRsZXIsCiAgICB2bQogICkgewogICAgdmFyIG5hbWUsIGRlZiQkMSwgY3VyLCBvbGQsIGV2ZW50OwogICAgZm9yIChuYW1lIGluIG9uKSB7CiAgICAgIGRlZiQkMSA9IGN1ciA9IG9uW25hbWVdOwogICAgICBvbGQgPSBvbGRPbltuYW1lXTsKICAgICAgZXZlbnQgPSBub3JtYWxpemVFdmVudChuYW1lKTsKICAgICAgaWYgKGlzVW5kZWYoY3VyKSkgewogICAgICAgIHdhcm4oCiAgICAgICAgICAiSW52YWxpZCBoYW5kbGVyIGZvciBldmVudCBcIiIgKyAoZXZlbnQubmFtZSkgKyAiXCI6IGdvdCAiICsgU3RyaW5nKGN1ciksCiAgICAgICAgICB2bQogICAgICAgICk7CiAgICAgIH0gZWxzZSBpZiAoaXNVbmRlZihvbGQpKSB7CiAgICAgICAgaWYgKGlzVW5kZWYoY3VyLmZucykpIHsKICAgICAgICAgIGN1ciA9IG9uW25hbWVdID0gY3JlYXRlRm5JbnZva2VyKGN1ciwgdm0pOwogICAgICAgIH0KICAgICAgICBpZiAoaXNUcnVlKGV2ZW50Lm9uY2UpKSB7CiAgICAgICAgICBjdXIgPSBvbltuYW1lXSA9IGNyZWF0ZU9uY2VIYW5kbGVyKGV2ZW50Lm5hbWUsIGN1ciwgZXZlbnQuY2FwdHVyZSk7CiAgICAgICAgfQogICAgICAgIGFkZChldmVudC5uYW1lLCBjdXIsIGV2ZW50LmNhcHR1cmUsIGV2ZW50LnBhc3NpdmUsIGV2ZW50LnBhcmFtcyk7CiAgICAgIH0gZWxzZSBpZiAoY3VyICE9PSBvbGQpIHsKICAgICAgICBvbGQuZm5zID0gY3VyOwogICAgICAgIG9uW25hbWVdID0gb2xkOwogICAgICB9CiAgICB9CiAgICBmb3IgKG5hbWUgaW4gb2xkT24pIHsKICAgICAgaWYgKGlzVW5kZWYob25bbmFtZV0pKSB7CiAgICAgICAgZXZlbnQgPSBub3JtYWxpemVFdmVudChuYW1lKTsKICAgICAgICByZW1vdmUkJDEoZXZlbnQubmFtZSwgb2xkT25bbmFtZV0sIGV2ZW50LmNhcHR1cmUpOwogICAgICB9CiAgICB9CiAgfQoKICAvKiAgKi8KCiAgZnVuY3Rpb24gbWVyZ2VWTm9kZUhvb2sgKGRlZiwgaG9va0tleSwgaG9vaykgewogICAgaWYgKGRlZiBpbnN0YW5jZW9mIFZOb2RlKSB7CiAgICAgIGRlZiA9IGRlZi5kYXRhLmhvb2sgfHwgKGRlZi5kYXRhLmhvb2sgPSB7fSk7CiAgICB9CiAgICB2YXIgaW52b2tlcjsKICAgIHZhciBvbGRIb29rID0gZGVmW2hvb2tLZXldOwoKICAgIGZ1bmN0aW9uIHdyYXBwZWRIb29rICgpIHsKICAgICAgaG9vay5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAvLyBpbXBvcnRhbnQ6IHJlbW92ZSBtZXJnZWQgaG9vayB0byBlbnN1cmUgaXQncyBjYWxsZWQgb25seSBvbmNlCiAgICAgIC8vIGFuZCBwcmV2ZW50IG1lbW9yeSBsZWFrCiAgICAgIHJlbW92ZShpbnZva2VyLmZucywgd3JhcHBlZEhvb2spOwogICAgfQoKICAgIGlmIChpc1VuZGVmKG9sZEhvb2spKSB7CiAgICAgIC8vIG5vIGV4aXN0aW5nIGhvb2sKICAgICAgaW52b2tlciA9IGNyZWF0ZUZuSW52b2tlcihbd3JhcHBlZEhvb2tdKTsKICAgIH0gZWxzZSB7CiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgICBpZiAoaXNEZWYob2xkSG9vay5mbnMpICYmIGlzVHJ1ZShvbGRIb29rLm1lcmdlZCkpIHsKICAgICAgICAvLyBhbHJlYWR5IGEgbWVyZ2VkIGludm9rZXIKICAgICAgICBpbnZva2VyID0gb2xkSG9vazsKICAgICAgICBpbnZva2VyLmZucy5wdXNoKHdyYXBwZWRIb29rKTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBleGlzdGluZyBwbGFpbiBob29rCiAgICAgICAgaW52b2tlciA9IGNyZWF0ZUZuSW52b2tlcihbb2xkSG9vaywgd3JhcHBlZEhvb2tdKTsKICAgICAgfQogICAgfQoKICAgIGludm9rZXIubWVyZ2VkID0gdHJ1ZTsKICAgIGRlZltob29rS2V5XSA9IGludm9rZXI7CiAgfQoKICAvKiAgKi8KCiAgZnVuY3Rpb24gZXh0cmFjdFByb3BzRnJvbVZOb2RlRGF0YSAoCiAgICBkYXRhLAogICAgQ3RvciwKICAgIHRhZwogICkgewogICAgLy8gd2UgYXJlIG9ubHkgZXh0cmFjdGluZyByYXcgdmFsdWVzIGhlcmUuCiAgICAvLyB2YWxpZGF0aW9uIGFuZCBkZWZhdWx0IHZhbHVlcyBhcmUgaGFuZGxlZCBpbiB0aGUgY2hpbGQKICAgIC8vIGNvbXBvbmVudCBpdHNlbGYuCiAgICB2YXIgcHJvcE9wdGlvbnMgPSBDdG9yLm9wdGlvbnMucHJvcHM7CiAgICBpZiAoaXNVbmRlZihwcm9wT3B0aW9ucykpIHsKICAgICAgcmV0dXJuCiAgICB9CiAgICB2YXIgcmVzID0ge307CiAgICB2YXIgYXR0cnMgPSBkYXRhLmF0dHJzOwogICAgdmFyIHByb3BzID0gZGF0YS5wcm9wczsKICAgIGlmIChpc0RlZihhdHRycykgfHwgaXNEZWYocHJvcHMpKSB7CiAgICAgIGZvciAodmFyIGtleSBpbiBwcm9wT3B0aW9ucykgewogICAgICAgIHZhciBhbHRLZXkgPSBoeXBoZW5hdGUoa2V5KTsKICAgICAgICB7CiAgICAgICAgICB2YXIga2V5SW5Mb3dlckNhc2UgPSBrZXkudG9Mb3dlckNhc2UoKTsKICAgICAgICAgIGlmICgKICAgICAgICAgICAga2V5ICE9PSBrZXlJbkxvd2VyQ2FzZSAmJgogICAgICAgICAgICBhdHRycyAmJiBoYXNPd24oYXR0cnMsIGtleUluTG93ZXJDYXNlKQogICAgICAgICAgKSB7CiAgICAgICAgICAgIHRpcCgKICAgICAgICAgICAgICAiUHJvcCBcIiIgKyBrZXlJbkxvd2VyQ2FzZSArICJcIiBpcyBwYXNzZWQgdG8gY29tcG9uZW50ICIgKwogICAgICAgICAgICAgIChmb3JtYXRDb21wb25lbnROYW1lKHRhZyB8fCBDdG9yKSkgKyAiLCBidXQgdGhlIGRlY2xhcmVkIHByb3AgbmFtZSBpcyIgKwogICAgICAgICAgICAgICIgXCIiICsga2V5ICsgIlwiLiAiICsKICAgICAgICAgICAgICAiTm90ZSB0aGF0IEhUTUwgYXR0cmlidXRlcyBhcmUgY2FzZS1pbnNlbnNpdGl2ZSBhbmQgY2FtZWxDYXNlZCAiICsKICAgICAgICAgICAgICAicHJvcHMgbmVlZCB0byB1c2UgdGhlaXIga2ViYWItY2FzZSBlcXVpdmFsZW50cyB3aGVuIHVzaW5nIGluLURPTSAiICsKICAgICAgICAgICAgICAidGVtcGxhdGVzLiBZb3Ugc2hvdWxkIHByb2JhYmx5IHVzZSBcIiIgKyBhbHRLZXkgKyAiXCIgaW5zdGVhZCBvZiBcIiIgKyBrZXkgKyAiXCIuIgogICAgICAgICAgICApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjaGVja1Byb3AocmVzLCBwcm9wcywga2V5LCBhbHRLZXksIHRydWUpIHx8CiAgICAgICAgY2hlY2tQcm9wKHJlcywgYXR0cnMsIGtleSwgYWx0S2V5LCBmYWxzZSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXMKICB9CgogIGZ1bmN0aW9uIGNoZWNrUHJvcCAoCiAgICByZXMsCiAgICBoYXNoLAogICAga2V5LAogICAgYWx0S2V5LAogICAgcHJlc2VydmUKICApIHsKICAgIGlmIChpc0RlZihoYXNoKSkgewogICAgICBpZiAoaGFzT3duKGhhc2gsIGtleSkpIHsKICAgICAgICByZXNba2V5XSA9IGhhc2hba2V5XTsKICAgICAgICBpZiAoIXByZXNlcnZlKSB7CiAgICAgICAgICBkZWxldGUgaGFzaFtrZXldOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZQogICAgICB9IGVsc2UgaWYgKGhhc093bihoYXNoLCBhbHRLZXkpKSB7CiAgICAgICAgcmVzW2tleV0gPSBoYXNoW2FsdEtleV07CiAgICAgICAgaWYgKCFwcmVzZXJ2ZSkgewogICAgICAgICAgZGVsZXRlIGhhc2hbYWx0S2V5XTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWUKICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlCiAgfQoKICAvKiAgKi8KCiAgLy8gVGhlIHRlbXBsYXRlIGNvbXBpbGVyIGF0dGVtcHRzIHRvIG1pbmltaXplIHRoZSBuZWVkIGZvciBub3JtYWxpemF0aW9uIGJ5CiAgLy8gc3RhdGljYWxseSBhbmFseXppbmcgdGhlIHRlbXBsYXRlIGF0IGNvbXBpbGUgdGltZS4KICAvLwogIC8vIEZvciBwbGFpbiBIVE1MIG1hcmt1cCwgbm9ybWFsaXphdGlvbiBjYW4gYmUgY29tcGxldGVseSBza2lwcGVkIGJlY2F1c2UgdGhlCiAgLy8gZ2VuZXJhdGVkIHJlbmRlciBmdW5jdGlvbiBpcyBndWFyYW50ZWVkIHRvIHJldHVybiBBcnJheTxWTm9kZT4uIFRoZXJlIGFyZQogIC8vIHR3byBjYXNlcyB3aGVyZSBleHRyYSBub3JtYWxpemF0aW9uIGlzIG5lZWRlZDoKCiAgLy8gMS4gV2hlbiB0aGUgY2hpbGRyZW4gY29udGFpbnMgY29tcG9uZW50cyAtIGJlY2F1c2UgYSBmdW5jdGlvbmFsIGNvbXBvbmVudAogIC8vIG1heSByZXR1cm4gYW4gQXJyYXkgaW5zdGVhZCBvZiBhIHNpbmdsZSByb290LiBJbiB0aGlzIGNhc2UsIGp1c3QgYSBzaW1wbGUKICAvLyBub3JtYWxpemF0aW9uIGlzIG5lZWRlZCAtIGlmIGFueSBjaGlsZCBpcyBhbiBBcnJheSwgd2UgZmxhdHRlbiB0aGUgd2hvbGUKICAvLyB0aGluZyB3aXRoIEFycmF5LnByb3RvdHlwZS5jb25jYXQuIEl0IGlzIGd1YXJhbnRlZWQgdG8gYmUgb25seSAxLWxldmVsIGRlZXAKICAvLyBiZWNhdXNlIGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhbHJlYWR5IG5vcm1hbGl6ZSB0aGVpciBvd24gY2hpbGRyZW4uCiAgZnVuY3Rpb24gc2ltcGxlTm9ybWFsaXplQ2hpbGRyZW4gKGNoaWxkcmVuKSB7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgIGlmIChBcnJheS5pc0FycmF5KGNoaWxkcmVuW2ldKSkgewogICAgICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbikKICAgICAgfQogICAgfQogICAgcmV0dXJuIGNoaWxkcmVuCiAgfQoKICAvLyAyLiBXaGVuIHRoZSBjaGlsZHJlbiBjb250YWlucyBjb25zdHJ1Y3RzIHRoYXQgYWx3YXlzIGdlbmVyYXRlZCBuZXN0ZWQgQXJyYXlzLAogIC8vIGUuZy4gPHRlbXBsYXRlPiwgPHNsb3Q+LCB2LWZvciwgb3Igd2hlbiB0aGUgY2hpbGRyZW4gaXMgcHJvdmlkZWQgYnkgdXNlcgogIC8vIHdpdGggaGFuZC13cml0dGVuIHJlbmRlciBmdW5jdGlvbnMgLyBKU1guIEluIHN1Y2ggY2FzZXMgYSBmdWxsIG5vcm1hbGl6YXRpb24KICAvLyBpcyBuZWVkZWQgdG8gY2F0ZXIgdG8gYWxsIHBvc3NpYmxlIHR5cGVzIG9mIGNoaWxkcmVuIHZhbHVlcy4KICBmdW5jdGlvbiBub3JtYWxpemVDaGlsZHJlbiAoY2hpbGRyZW4pIHsKICAgIHJldHVybiBpc1ByaW1pdGl2ZShjaGlsZHJlbikKICAgICAgPyBbY3JlYXRlVGV4dFZOb2RlKGNoaWxkcmVuKV0KICAgICAgOiBBcnJheS5pc0FycmF5KGNoaWxkcmVuKQogICAgICAgID8gbm9ybWFsaXplQXJyYXlDaGlsZHJlbihjaGlsZHJlbikKICAgICAgICA6IHVuZGVmaW5lZAogIH0KCiAgZnVuY3Rpb24gaXNUZXh0Tm9kZSAobm9kZSkgewogICAgcmV0dXJuIGlzRGVmKG5vZGUpICYmIGlzRGVmKG5vZGUudGV4dCkgJiYgaXNGYWxzZShub2RlLmlzQ29tbWVudCkKICB9CgogIGZ1bmN0aW9uIG5vcm1hbGl6ZUFycmF5Q2hpbGRyZW4gKGNoaWxkcmVuLCBuZXN0ZWRJbmRleCkgewogICAgdmFyIHJlcyA9IFtdOwogICAgdmFyIGksIGMsIGxhc3RJbmRleCwgbGFzdDsKICAgIGZvciAoaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICBjID0gY2hpbGRyZW5baV07CiAgICAgIGlmIChpc1VuZGVmKGMpIHx8IHR5cGVvZiBjID09PSAnYm9vbGVhbicpIHsgY29udGludWUgfQogICAgICBsYXN0SW5kZXggPSByZXMubGVuZ3RoIC0gMTsKICAgICAgbGFzdCA9IHJlc1tsYXN0SW5kZXhdOwogICAgICAvLyAgbmVzdGVkCiAgICAgIGlmIChBcnJheS5pc0FycmF5KGMpKSB7CiAgICAgICAgaWYgKGMubGVuZ3RoID4gMCkgewogICAgICAgICAgYyA9IG5vcm1hbGl6ZUFycmF5Q2hpbGRyZW4oYywgKChuZXN0ZWRJbmRleCB8fCAnJykgKyAiXyIgKyBpKSk7CiAgICAgICAgICAvLyBtZXJnZSBhZGphY2VudCB0ZXh0IG5vZGVzCiAgICAgICAgICBpZiAoaXNUZXh0Tm9kZShjWzBdKSAmJiBpc1RleHROb2RlKGxhc3QpKSB7CiAgICAgICAgICAgIHJlc1tsYXN0SW5kZXhdID0gY3JlYXRlVGV4dFZOb2RlKGxhc3QudGV4dCArIChjWzBdKS50ZXh0KTsKICAgICAgICAgICAgYy5zaGlmdCgpOwogICAgICAgICAgfQogICAgICAgICAgcmVzLnB1c2guYXBwbHkocmVzLCBjKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoaXNQcmltaXRpdmUoYykpIHsKICAgICAgICBpZiAoaXNUZXh0Tm9kZShsYXN0KSkgewogICAgICAgICAgLy8gbWVyZ2UgYWRqYWNlbnQgdGV4dCBub2RlcwogICAgICAgICAgLy8gdGhpcyBpcyBuZWNlc3NhcnkgZm9yIFNTUiBoeWRyYXRpb24gYmVjYXVzZSB0ZXh0IG5vZGVzIGFyZQogICAgICAgICAgLy8gZXNzZW50aWFsbHkgbWVyZ2VkIHdoZW4gcmVuZGVyZWQgdG8gSFRNTCBzdHJpbmdzCiAgICAgICAgICByZXNbbGFzdEluZGV4XSA9IGNyZWF0ZVRleHRWTm9kZShsYXN0LnRleHQgKyBjKTsKICAgICAgICB9IGVsc2UgaWYgKGMgIT09ICcnKSB7CiAgICAgICAgICAvLyBjb252ZXJ0IHByaW1pdGl2ZSB0byB2bm9kZQogICAgICAgICAgcmVzLnB1c2goY3JlYXRlVGV4dFZOb2RlKGMpKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKGlzVGV4dE5vZGUoYykgJiYgaXNUZXh0Tm9kZShsYXN0KSkgewogICAgICAgICAgLy8gbWVyZ2UgYWRqYWNlbnQgdGV4dCBub2RlcwogICAgICAgICAgcmVzW2xhc3RJbmRleF0gPSBjcmVhdGVUZXh0Vk5vZGUobGFzdC50ZXh0ICsgYy50ZXh0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gZGVmYXVsdCBrZXkgZm9yIG5lc3RlZCBhcnJheSBjaGlsZHJlbiAobGlrZWx5IGdlbmVyYXRlZCBieSB2LWZvcikKICAgICAgICAgIGlmIChpc1RydWUoY2hpbGRyZW4uX2lzVkxpc3QpICYmCiAgICAgICAgICAgIGlzRGVmKGMudGFnKSAmJgogICAgICAgICAgICBpc1VuZGVmKGMua2V5KSAmJgogICAgICAgICAgICBpc0RlZihuZXN0ZWRJbmRleCkpIHsKICAgICAgICAgICAgYy5rZXkgPSAiX192bGlzdCIgKyBuZXN0ZWRJbmRleCArICJfIiArIGkgKyAiX18iOwogICAgICAgICAgfQogICAgICAgICAgcmVzLnB1c2goYyk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICByZXR1cm4gcmVzCiAgfQoKICAvKiAgKi8KCiAgZnVuY3Rpb24gaW5pdFByb3ZpZGUgKHZtKSB7CiAgICB2YXIgcHJvdmlkZSA9IHZtLiRvcHRpb25zLnByb3ZpZGU7CiAgICBpZiAocHJvdmlkZSkgewogICAgICB2bS5fcHJvdmlkZWQgPSB0eXBlb2YgcHJvdmlkZSA9PT0gJ2Z1bmN0aW9uJwogICAgICAgID8gcHJvdmlkZS5jYWxsKHZtKQogICAgICAgIDogcHJvdmlkZTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIGluaXRJbmplY3Rpb25zICh2bSkgewogICAgdmFyIHJlc3VsdCA9IHJlc29sdmVJbmplY3Qodm0uJG9wdGlvbnMuaW5qZWN0LCB2bSk7CiAgICBpZiAocmVzdWx0KSB7CiAgICAgIHRvZ2dsZU9ic2VydmluZyhmYWxzZSk7CiAgICAgIE9iamVjdC5rZXlzKHJlc3VsdCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7CiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi8KICAgICAgICB7CiAgICAgICAgICBkZWZpbmVSZWFjdGl2ZSQkMSh2bSwga2V5LCByZXN1bHRba2V5XSwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICB3YXJuKAogICAgICAgICAgICAgICJBdm9pZCBtdXRhdGluZyBhbiBpbmplY3RlZCB2YWx1ZSBkaXJlY3RseSBzaW5jZSB0aGUgY2hhbmdlcyB3aWxsIGJlICIgKwogICAgICAgICAgICAgICJvdmVyd3JpdHRlbiB3aGVuZXZlciB0aGUgcHJvdmlkZWQgY29tcG9uZW50IHJlLXJlbmRlcnMuICIgKwogICAgICAgICAgICAgICJpbmplY3Rpb24gYmVpbmcgbXV0YXRlZDogXCIiICsga2V5ICsgIlwiIiwKICAgICAgICAgICAgICB2bQogICAgICAgICAgICApOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9KTsKICAgICAgdG9nZ2xlT2JzZXJ2aW5nKHRydWUpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gcmVzb2x2ZUluamVjdCAoaW5qZWN0LCB2bSkgewogICAgaWYgKGluamVjdCkgewogICAgICAvLyBpbmplY3QgaXMgOmFueSBiZWNhdXNlIGZsb3cgaXMgbm90IHNtYXJ0IGVub3VnaCB0byBmaWd1cmUgb3V0IGNhY2hlZAogICAgICB2YXIgcmVzdWx0ID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKICAgICAgdmFyIGtleXMgPSBoYXNTeW1ib2wKICAgICAgICA/IFJlZmxlY3Qub3duS2V5cyhpbmplY3QpCiAgICAgICAgOiBPYmplY3Qua2V5cyhpbmplY3QpOwoKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIGtleSA9IGtleXNbaV07CiAgICAgICAgLy8gIzY1NzQgaW4gY2FzZSB0aGUgaW5qZWN0IG9iamVjdCBpcyBvYnNlcnZlZC4uLgogICAgICAgIGlmIChrZXkgPT09ICdfX29iX18nKSB7IGNvbnRpbnVlIH0KICAgICAgICB2YXIgcHJvdmlkZUtleSA9IGluamVjdFtrZXldLmZyb207CiAgICAgICAgdmFyIHNvdXJjZSA9IHZtOwogICAgICAgIHdoaWxlIChzb3VyY2UpIHsKICAgICAgICAgIGlmIChzb3VyY2UuX3Byb3ZpZGVkICYmIGhhc093bihzb3VyY2UuX3Byb3ZpZGVkLCBwcm92aWRlS2V5KSkgewogICAgICAgICAgICByZXN1bHRba2V5XSA9IHNvdXJjZS5fcHJvdmlkZWRbcHJvdmlkZUtleV07CiAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICB9CiAgICAgICAgICBzb3VyY2UgPSBzb3VyY2UuJHBhcmVudDsKICAgICAgICB9CiAgICAgICAgaWYgKCFzb3VyY2UpIHsKICAgICAgICAgIGlmICgnZGVmYXVsdCcgaW4gaW5qZWN0W2tleV0pIHsKICAgICAgICAgICAgdmFyIHByb3ZpZGVEZWZhdWx0ID0gaW5qZWN0W2tleV0uZGVmYXVsdDsKICAgICAgICAgICAgcmVzdWx0W2tleV0gPSB0eXBlb2YgcHJvdmlkZURlZmF1bHQgPT09ICdmdW5jdGlvbicKICAgICAgICAgICAgICA/IHByb3ZpZGVEZWZhdWx0LmNhbGwodm0pCiAgICAgICAgICAgICAgOiBwcm92aWRlRGVmYXVsdDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHdhcm4oKCJJbmplY3Rpb24gXCIiICsga2V5ICsgIlwiIG5vdCBmb3VuZCIpLCB2bSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiByZXN1bHQKICAgIH0KICB9CgogIC8qICAqLwoKCgogIC8qKgogICAqIFJ1bnRpbWUgaGVscGVyIGZvciByZXNvbHZpbmcgcmF3IGNoaWxkcmVuIFZOb2RlcyBpbnRvIGEgc2xvdCBvYmplY3QuCiAgICovCiAgZnVuY3Rpb24gcmVzb2x2ZVNsb3RzICgKICAgIGNoaWxkcmVuLAogICAgY29udGV4dAogICkgewogICAgaWYgKCFjaGlsZHJlbiB8fCAhY2hpbGRyZW4ubGVuZ3RoKSB7CiAgICAgIHJldHVybiB7fQogICAgfQogICAgdmFyIHNsb3RzID0ge307CiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICB2YXIgY2hpbGQgPSBjaGlsZHJlbltpXTsKICAgICAgdmFyIGRhdGEgPSBjaGlsZC5kYXRhOwogICAgICAvLyByZW1vdmUgc2xvdCBhdHRyaWJ1dGUgaWYgdGhlIG5vZGUgaXMgcmVzb2x2ZWQgYXMgYSBWdWUgc2xvdCBub2RlCiAgICAgIGlmIChkYXRhICYmIGRhdGEuYXR0cnMgJiYgZGF0YS5hdHRycy5zbG90KSB7CiAgICAgICAgZGVsZXRlIGRhdGEuYXR0cnMuc2xvdDsKICAgICAgfQogICAgICAvLyBuYW1lZCBzbG90cyBzaG91bGQgb25seSBiZSByZXNwZWN0ZWQgaWYgdGhlIHZub2RlIHdhcyByZW5kZXJlZCBpbiB0aGUKICAgICAgLy8gc2FtZSBjb250ZXh0LgogICAgICBpZiAoKGNoaWxkLmNvbnRleHQgPT09IGNvbnRleHQgfHwgY2hpbGQuZm5Db250ZXh0ID09PSBjb250ZXh0KSAmJgogICAgICAgIGRhdGEgJiYgZGF0YS5zbG90ICE9IG51bGwKICAgICAgKSB7CiAgICAgICAgdmFyIG5hbWUgPSBkYXRhLnNsb3Q7CiAgICAgICAgdmFyIHNsb3QgPSAoc2xvdHNbbmFtZV0gfHwgKHNsb3RzW25hbWVdID0gW10pKTsKICAgICAgICBpZiAoY2hpbGQudGFnID09PSAndGVtcGxhdGUnKSB7CiAgICAgICAgICBzbG90LnB1c2guYXBwbHkoc2xvdCwgY2hpbGQuY2hpbGRyZW4gfHwgW10pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzbG90LnB1c2goY2hpbGQpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAoc2xvdHMuZGVmYXVsdCB8fCAoc2xvdHMuZGVmYXVsdCA9IFtdKSkucHVzaChjaGlsZCk7CiAgICAgIH0KICAgIH0KICAgIC8vIGlnbm9yZSBzbG90cyB0aGF0IGNvbnRhaW5zIG9ubHkgd2hpdGVzcGFjZQogICAgZm9yICh2YXIgbmFtZSQxIGluIHNsb3RzKSB7CiAgICAgIGlmIChzbG90c1tuYW1lJDFdLmV2ZXJ5KGlzV2hpdGVzcGFjZSkpIHsKICAgICAgICBkZWxldGUgc2xvdHNbbmFtZSQxXTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHNsb3RzCiAgfQoKICBmdW5jdGlvbiBpc1doaXRlc3BhY2UgKG5vZGUpIHsKICAgIHJldHVybiAobm9kZS5pc0NvbW1lbnQgJiYgIW5vZGUuYXN5bmNGYWN0b3J5KSB8fCBub2RlLnRleHQgPT09ICcgJwogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIG5vcm1hbGl6ZVNjb3BlZFNsb3RzICgKICAgIHNsb3RzLAogICAgbm9ybWFsU2xvdHMsCiAgICBwcmV2U2xvdHMKICApIHsKICAgIHZhciByZXM7CiAgICB2YXIgaGFzTm9ybWFsU2xvdHMgPSBPYmplY3Qua2V5cyhub3JtYWxTbG90cykubGVuZ3RoID4gMDsKICAgIHZhciBpc1N0YWJsZSA9IHNsb3RzID8gISFzbG90cy4kc3RhYmxlIDogIWhhc05vcm1hbFNsb3RzOwogICAgdmFyIGtleSA9IHNsb3RzICYmIHNsb3RzLiRrZXk7CiAgICBpZiAoIXNsb3RzKSB7CiAgICAgIHJlcyA9IHt9OwogICAgfSBlbHNlIGlmIChzbG90cy5fbm9ybWFsaXplZCkgewogICAgICAvLyBmYXN0IHBhdGggMTogY2hpbGQgY29tcG9uZW50IHJlLXJlbmRlciBvbmx5LCBwYXJlbnQgZGlkIG5vdCBjaGFuZ2UKICAgICAgcmV0dXJuIHNsb3RzLl9ub3JtYWxpemVkCiAgICB9IGVsc2UgaWYgKAogICAgICBpc1N0YWJsZSAmJgogICAgICBwcmV2U2xvdHMgJiYKICAgICAgcHJldlNsb3RzICE9PSBlbXB0eU9iamVjdCAmJgogICAgICBrZXkgPT09IHByZXZTbG90cy4ka2V5ICYmCiAgICAgICFoYXNOb3JtYWxTbG90cyAmJgogICAgICAhcHJldlNsb3RzLiRoYXNOb3JtYWwKICAgICkgewogICAgICAvLyBmYXN0IHBhdGggMjogc3RhYmxlIHNjb3BlZCBzbG90cyB3LyBubyBub3JtYWwgc2xvdHMgdG8gcHJveHksCiAgICAgIC8vIG9ubHkgbmVlZCB0byBub3JtYWxpemUgb25jZQogICAgICByZXR1cm4gcHJldlNsb3RzCiAgICB9IGVsc2UgewogICAgICByZXMgPSB7fTsKICAgICAgZm9yICh2YXIga2V5JDEgaW4gc2xvdHMpIHsKICAgICAgICBpZiAoc2xvdHNba2V5JDFdICYmIGtleSQxWzBdICE9PSAnJCcpIHsKICAgICAgICAgIHJlc1trZXkkMV0gPSBub3JtYWxpemVTY29wZWRTbG90KG5vcm1hbFNsb3RzLCBrZXkkMSwgc2xvdHNba2V5JDFdKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIC8vIGV4cG9zZSBub3JtYWwgc2xvdHMgb24gc2NvcGVkU2xvdHMKICAgIGZvciAodmFyIGtleSQyIGluIG5vcm1hbFNsb3RzKSB7CiAgICAgIGlmICghKGtleSQyIGluIHJlcykpIHsKICAgICAgICByZXNba2V5JDJdID0gcHJveHlOb3JtYWxTbG90KG5vcm1hbFNsb3RzLCBrZXkkMik7CiAgICAgIH0KICAgIH0KICAgIC8vIGF2b3JpYXogc2VlbXMgdG8gbW9jayBhIG5vbi1leHRlbnNpYmxlICRzY29wZWRTbG90cyBvYmplY3QKICAgIC8vIGFuZCB3aGVuIHRoYXQgaXMgcGFzc2VkIGRvd24gdGhpcyB3b3VsZCBjYXVzZSBhbiBlcnJvcgogICAgaWYgKHNsb3RzICYmIE9iamVjdC5pc0V4dGVuc2libGUoc2xvdHMpKSB7CiAgICAgIChzbG90cykuX25vcm1hbGl6ZWQgPSByZXM7CiAgICB9CiAgICBkZWYocmVzLCAnJHN0YWJsZScsIGlzU3RhYmxlKTsKICAgIGRlZihyZXMsICcka2V5Jywga2V5KTsKICAgIGRlZihyZXMsICckaGFzTm9ybWFsJywgaGFzTm9ybWFsU2xvdHMpOwogICAgcmV0dXJuIHJlcwogIH0KCiAgZnVuY3Rpb24gbm9ybWFsaXplU2NvcGVkU2xvdChub3JtYWxTbG90cywga2V5LCBmbikgewogICAgdmFyIG5vcm1hbGl6ZWQgPSBmdW5jdGlvbiAoKSB7CiAgICAgIHZhciByZXMgPSBhcmd1bWVudHMubGVuZ3RoID8gZm4uYXBwbHkobnVsbCwgYXJndW1lbnRzKSA6IGZuKHt9KTsKICAgICAgcmVzID0gcmVzICYmIHR5cGVvZiByZXMgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KHJlcykKICAgICAgICA/IFtyZXNdIC8vIHNpbmdsZSB2bm9kZQogICAgICAgIDogbm9ybWFsaXplQ2hpbGRyZW4ocmVzKTsKICAgICAgcmV0dXJuIHJlcyAmJiAoCiAgICAgICAgcmVzLmxlbmd0aCA9PT0gMCB8fAogICAgICAgIChyZXMubGVuZ3RoID09PSAxICYmIHJlc1swXS5pc0NvbW1lbnQpIC8vICM5NjU4CiAgICAgICkgPyB1bmRlZmluZWQKICAgICAgICA6IHJlcwogICAgfTsKICAgIC8vIHRoaXMgaXMgYSBzbG90IHVzaW5nIHRoZSBuZXcgdi1zbG90IHN5bnRheCB3aXRob3V0IHNjb3BlLiBhbHRob3VnaCBpdCBpcwogICAgLy8gY29tcGlsZWQgYXMgYSBzY29wZWQgc2xvdCwgcmVuZGVyIGZuIHVzZXJzIHdvdWxkIGV4cGVjdCBpdCB0byBiZSBwcmVzZW50CiAgICAvLyBvbiB0aGlzLiRzbG90cyBiZWNhdXNlIHRoZSB1c2FnZSBpcyBzZW1hbnRpY2FsbHkgYSBub3JtYWwgc2xvdC4KICAgIGlmIChmbi5wcm94eSkgewogICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobm9ybWFsU2xvdHMsIGtleSwgewogICAgICAgIGdldDogbm9ybWFsaXplZCwKICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogICAgICB9KTsKICAgIH0KICAgIHJldHVybiBub3JtYWxpemVkCiAgfQoKICBmdW5jdGlvbiBwcm94eU5vcm1hbFNsb3Qoc2xvdHMsIGtleSkgewogICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNsb3RzW2tleV07IH0KICB9CgogIC8qICAqLwoKICAvKioKICAgKiBSdW50aW1lIGhlbHBlciBmb3IgcmVuZGVyaW5nIHYtZm9yIGxpc3RzLgogICAqLwogIGZ1bmN0aW9uIHJlbmRlckxpc3QgKAogICAgdmFsLAogICAgcmVuZGVyCiAgKSB7CiAgICB2YXIgcmV0LCBpLCBsLCBrZXlzLCBrZXk7CiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpIHx8IHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7CiAgICAgIHJldCA9IG5ldyBBcnJheSh2YWwubGVuZ3RoKTsKICAgICAgZm9yIChpID0gMCwgbCA9IHZhbC5sZW5ndGg7IGkgPCBsOyBpKyspIHsKICAgICAgICByZXRbaV0gPSByZW5kZXIodmFsW2ldLCBpKTsKICAgICAgfQogICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykgewogICAgICByZXQgPSBuZXcgQXJyYXkodmFsKTsKICAgICAgZm9yIChpID0gMDsgaSA8IHZhbDsgaSsrKSB7CiAgICAgICAgcmV0W2ldID0gcmVuZGVyKGkgKyAxLCBpKTsKICAgICAgfQogICAgfSBlbHNlIGlmIChpc09iamVjdCh2YWwpKSB7CiAgICAgIGlmIChoYXNTeW1ib2wgJiYgdmFsW1N5bWJvbC5pdGVyYXRvcl0pIHsKICAgICAgICByZXQgPSBbXTsKICAgICAgICB2YXIgaXRlcmF0b3IgPSB2YWxbU3ltYm9sLml0ZXJhdG9yXSgpOwogICAgICAgIHZhciByZXN1bHQgPSBpdGVyYXRvci5uZXh0KCk7CiAgICAgICAgd2hpbGUgKCFyZXN1bHQuZG9uZSkgewogICAgICAgICAgcmV0LnB1c2gocmVuZGVyKHJlc3VsdC52YWx1ZSwgcmV0Lmxlbmd0aCkpOwogICAgICAgICAgcmVzdWx0ID0gaXRlcmF0b3IubmV4dCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBrZXlzID0gT2JqZWN0LmtleXModmFsKTsKICAgICAgICByZXQgPSBuZXcgQXJyYXkoa2V5cy5sZW5ndGgpOwogICAgICAgIGZvciAoaSA9IDAsIGwgPSBrZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICAgICAga2V5ID0ga2V5c1tpXTsKICAgICAgICAgIHJldFtpXSA9IHJlbmRlcih2YWxba2V5XSwga2V5LCBpKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGlmICghaXNEZWYocmV0KSkgewogICAgICByZXQgPSBbXTsKICAgIH0KICAgIChyZXQpLl9pc1ZMaXN0ID0gdHJ1ZTsKICAgIHJldHVybiByZXQKICB9CgogIC8qICAqLwoKICAvKioKICAgKiBSdW50aW1lIGhlbHBlciBmb3IgcmVuZGVyaW5nIDxzbG90PgogICAqLwogIGZ1bmN0aW9uIHJlbmRlclNsb3QgKAogICAgbmFtZSwKICAgIGZhbGxiYWNrLAogICAgcHJvcHMsCiAgICBiaW5kT2JqZWN0CiAgKSB7CiAgICB2YXIgc2NvcGVkU2xvdEZuID0gdGhpcy4kc2NvcGVkU2xvdHNbbmFtZV07CiAgICB2YXIgbm9kZXM7CiAgICBpZiAoc2NvcGVkU2xvdEZuKSB7IC8vIHNjb3BlZCBzbG90CiAgICAgIHByb3BzID0gcHJvcHMgfHwge307CiAgICAgIGlmIChiaW5kT2JqZWN0KSB7CiAgICAgICAgaWYgKCFpc09iamVjdChiaW5kT2JqZWN0KSkgewogICAgICAgICAgd2FybigKICAgICAgICAgICAgJ3Nsb3Qgdi1iaW5kIHdpdGhvdXQgYXJndW1lbnQgZXhwZWN0cyBhbiBPYmplY3QnLAogICAgICAgICAgICB0aGlzCiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBwcm9wcyA9IGV4dGVuZChleHRlbmQoe30sIGJpbmRPYmplY3QpLCBwcm9wcyk7CiAgICAgIH0KICAgICAgbm9kZXMgPSBzY29wZWRTbG90Rm4ocHJvcHMpIHx8IGZhbGxiYWNrOwogICAgfSBlbHNlIHsKICAgICAgbm9kZXMgPSB0aGlzLiRzbG90c1tuYW1lXSB8fCBmYWxsYmFjazsKICAgIH0KCiAgICB2YXIgdGFyZ2V0ID0gcHJvcHMgJiYgcHJvcHMuc2xvdDsKICAgIGlmICh0YXJnZXQpIHsKICAgICAgcmV0dXJuIHRoaXMuJGNyZWF0ZUVsZW1lbnQoJ3RlbXBsYXRlJywgeyBzbG90OiB0YXJnZXQgfSwgbm9kZXMpCiAgICB9IGVsc2UgewogICAgICByZXR1cm4gbm9kZXMKICAgIH0KICB9CgogIC8qICAqLwoKICAvKioKICAgKiBSdW50aW1lIGhlbHBlciBmb3IgcmVzb2x2aW5nIGZpbHRlcnMKICAgKi8KICBmdW5jdGlvbiByZXNvbHZlRmlsdGVyIChpZCkgewogICAgcmV0dXJuIHJlc29sdmVBc3NldCh0aGlzLiRvcHRpb25zLCAnZmlsdGVycycsIGlkLCB0cnVlKSB8fCBpZGVudGl0eQogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIGlzS2V5Tm90TWF0Y2ggKGV4cGVjdCwgYWN0dWFsKSB7CiAgICBpZiAoQXJyYXkuaXNBcnJheShleHBlY3QpKSB7CiAgICAgIHJldHVybiBleHBlY3QuaW5kZXhPZihhY3R1YWwpID09PSAtMQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIGV4cGVjdCAhPT0gYWN0dWFsCiAgICB9CiAgfQoKICAvKioKICAgKiBSdW50aW1lIGhlbHBlciBmb3IgY2hlY2tpbmcga2V5Q29kZXMgZnJvbSBjb25maWcuCiAgICogZXhwb3NlZCBhcyBWdWUucHJvdG90eXBlLl9rCiAgICogcGFzc2luZyBpbiBldmVudEtleU5hbWUgYXMgbGFzdCBhcmd1bWVudCBzZXBhcmF0ZWx5IGZvciBiYWNrd2FyZHMgY29tcGF0CiAgICovCiAgZnVuY3Rpb24gY2hlY2tLZXlDb2RlcyAoCiAgICBldmVudEtleUNvZGUsCiAgICBrZXksCiAgICBidWlsdEluS2V5Q29kZSwKICAgIGV2ZW50S2V5TmFtZSwKICAgIGJ1aWx0SW5LZXlOYW1lCiAgKSB7CiAgICB2YXIgbWFwcGVkS2V5Q29kZSA9IGNvbmZpZy5rZXlDb2Rlc1trZXldIHx8IGJ1aWx0SW5LZXlDb2RlOwogICAgaWYgKGJ1aWx0SW5LZXlOYW1lICYmIGV2ZW50S2V5TmFtZSAmJiAhY29uZmlnLmtleUNvZGVzW2tleV0pIHsKICAgICAgcmV0dXJuIGlzS2V5Tm90TWF0Y2goYnVpbHRJbktleU5hbWUsIGV2ZW50S2V5TmFtZSkKICAgIH0gZWxzZSBpZiAobWFwcGVkS2V5Q29kZSkgewogICAgICByZXR1cm4gaXNLZXlOb3RNYXRjaChtYXBwZWRLZXlDb2RlLCBldmVudEtleUNvZGUpCiAgICB9IGVsc2UgaWYgKGV2ZW50S2V5TmFtZSkgewogICAgICByZXR1cm4gaHlwaGVuYXRlKGV2ZW50S2V5TmFtZSkgIT09IGtleQogICAgfQogIH0KCiAgLyogICovCgogIC8qKgogICAqIFJ1bnRpbWUgaGVscGVyIGZvciBtZXJnaW5nIHYtYmluZD0ib2JqZWN0IiBpbnRvIGEgVk5vZGUncyBkYXRhLgogICAqLwogIGZ1bmN0aW9uIGJpbmRPYmplY3RQcm9wcyAoCiAgICBkYXRhLAogICAgdGFnLAogICAgdmFsdWUsCiAgICBhc1Byb3AsCiAgICBpc1N5bmMKICApIHsKICAgIGlmICh2YWx1ZSkgewogICAgICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkgewogICAgICAgIHdhcm4oCiAgICAgICAgICAndi1iaW5kIHdpdGhvdXQgYXJndW1lbnQgZXhwZWN0cyBhbiBPYmplY3Qgb3IgQXJyYXkgdmFsdWUnLAogICAgICAgICAgdGhpcwogICAgICAgICk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7CiAgICAgICAgICB2YWx1ZSA9IHRvT2JqZWN0KHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgdmFyIGhhc2g7CiAgICAgICAgdmFyIGxvb3AgPSBmdW5jdGlvbiAoIGtleSApIHsKICAgICAgICAgIGlmICgKICAgICAgICAgICAga2V5ID09PSAnY2xhc3MnIHx8CiAgICAgICAgICAgIGtleSA9PT0gJ3N0eWxlJyB8fAogICAgICAgICAgICBpc1Jlc2VydmVkQXR0cmlidXRlKGtleSkKICAgICAgICAgICkgewogICAgICAgICAgICBoYXNoID0gZGF0YTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciB0eXBlID0gZGF0YS5hdHRycyAmJiBkYXRhLmF0dHJzLnR5cGU7CiAgICAgICAgICAgIGhhc2ggPSBhc1Byb3AgfHwgY29uZmlnLm11c3RVc2VQcm9wKHRhZywgdHlwZSwga2V5KQogICAgICAgICAgICAgID8gZGF0YS5kb21Qcm9wcyB8fCAoZGF0YS5kb21Qcm9wcyA9IHt9KQogICAgICAgICAgICAgIDogZGF0YS5hdHRycyB8fCAoZGF0YS5hdHRycyA9IHt9KTsKICAgICAgICAgIH0KICAgICAgICAgIHZhciBjYW1lbGl6ZWRLZXkgPSBjYW1lbGl6ZShrZXkpOwogICAgICAgICAgdmFyIGh5cGhlbmF0ZWRLZXkgPSBoeXBoZW5hdGUoa2V5KTsKICAgICAgICAgIGlmICghKGNhbWVsaXplZEtleSBpbiBoYXNoKSAmJiAhKGh5cGhlbmF0ZWRLZXkgaW4gaGFzaCkpIHsKICAgICAgICAgICAgaGFzaFtrZXldID0gdmFsdWVba2V5XTsKCiAgICAgICAgICAgIGlmIChpc1N5bmMpIHsKICAgICAgICAgICAgICB2YXIgb24gPSBkYXRhLm9uIHx8IChkYXRhLm9uID0ge30pOwogICAgICAgICAgICAgIG9uWygidXBkYXRlOiIgKyBrZXkpXSA9IGZ1bmN0aW9uICgkZXZlbnQpIHsKICAgICAgICAgICAgICAgIHZhbHVlW2tleV0gPSAkZXZlbnQ7CiAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkgbG9vcCgga2V5ICk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBkYXRhCiAgfQoKICAvKiAgKi8KCiAgLyoqCiAgICogUnVudGltZSBoZWxwZXIgZm9yIHJlbmRlcmluZyBzdGF0aWMgdHJlZXMuCiAgICovCiAgZnVuY3Rpb24gcmVuZGVyU3RhdGljICgKICAgIGluZGV4LAogICAgaXNJbkZvcgogICkgewogICAgdmFyIGNhY2hlZCA9IHRoaXMuX3N0YXRpY1RyZWVzIHx8ICh0aGlzLl9zdGF0aWNUcmVlcyA9IFtdKTsKICAgIHZhciB0cmVlID0gY2FjaGVkW2luZGV4XTsKICAgIC8vIGlmIGhhcyBhbHJlYWR5LXJlbmRlcmVkIHN0YXRpYyB0cmVlIGFuZCBub3QgaW5zaWRlIHYtZm9yLAogICAgLy8gd2UgY2FuIHJldXNlIHRoZSBzYW1lIHRyZWUuCiAgICBpZiAodHJlZSAmJiAhaXNJbkZvcikgewogICAgICByZXR1cm4gdHJlZQogICAgfQogICAgLy8gb3RoZXJ3aXNlLCByZW5kZXIgYSBmcmVzaCB0cmVlLgogICAgdHJlZSA9IGNhY2hlZFtpbmRleF0gPSB0aGlzLiRvcHRpb25zLnN0YXRpY1JlbmRlckZuc1tpbmRleF0uY2FsbCgKICAgICAgdGhpcy5fcmVuZGVyUHJveHksCiAgICAgIG51bGwsCiAgICAgIHRoaXMgLy8gZm9yIHJlbmRlciBmbnMgZ2VuZXJhdGVkIGZvciBmdW5jdGlvbmFsIGNvbXBvbmVudCB0ZW1wbGF0ZXMKICAgICk7CiAgICBtYXJrU3RhdGljKHRyZWUsICgiX19zdGF0aWNfXyIgKyBpbmRleCksIGZhbHNlKTsKICAgIHJldHVybiB0cmVlCiAgfQoKICAvKioKICAgKiBSdW50aW1lIGhlbHBlciBmb3Igdi1vbmNlLgogICAqIEVmZmVjdGl2ZWx5IGl0IG1lYW5zIG1hcmtpbmcgdGhlIG5vZGUgYXMgc3RhdGljIHdpdGggYSB1bmlxdWUga2V5LgogICAqLwogIGZ1bmN0aW9uIG1hcmtPbmNlICgKICAgIHRyZWUsCiAgICBpbmRleCwKICAgIGtleQogICkgewogICAgbWFya1N0YXRpYyh0cmVlLCAoIl9fb25jZV9fIiArIGluZGV4ICsgKGtleSA/ICgiXyIgKyBrZXkpIDogIiIpKSwgdHJ1ZSk7CiAgICByZXR1cm4gdHJlZQogIH0KCiAgZnVuY3Rpb24gbWFya1N0YXRpYyAoCiAgICB0cmVlLAogICAga2V5LAogICAgaXNPbmNlCiAgKSB7CiAgICBpZiAoQXJyYXkuaXNBcnJheSh0cmVlKSkgewogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRyZWUubGVuZ3RoOyBpKyspIHsKICAgICAgICBpZiAodHJlZVtpXSAmJiB0eXBlb2YgdHJlZVtpXSAhPT0gJ3N0cmluZycpIHsKICAgICAgICAgIG1hcmtTdGF0aWNOb2RlKHRyZWVbaV0sIChrZXkgKyAiXyIgKyBpKSwgaXNPbmNlKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIG1hcmtTdGF0aWNOb2RlKHRyZWUsIGtleSwgaXNPbmNlKTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIG1hcmtTdGF0aWNOb2RlIChub2RlLCBrZXksIGlzT25jZSkgewogICAgbm9kZS5pc1N0YXRpYyA9IHRydWU7CiAgICBub2RlLmtleSA9IGtleTsKICAgIG5vZGUuaXNPbmNlID0gaXNPbmNlOwogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIGJpbmRPYmplY3RMaXN0ZW5lcnMgKGRhdGEsIHZhbHVlKSB7CiAgICBpZiAodmFsdWUpIHsKICAgICAgaWYgKCFpc1BsYWluT2JqZWN0KHZhbHVlKSkgewogICAgICAgIHdhcm4oCiAgICAgICAgICAndi1vbiB3aXRob3V0IGFyZ3VtZW50IGV4cGVjdHMgYW4gT2JqZWN0IHZhbHVlJywKICAgICAgICAgIHRoaXMKICAgICAgICApOwogICAgICB9IGVsc2UgewogICAgICAgIHZhciBvbiA9IGRhdGEub24gPSBkYXRhLm9uID8gZXh0ZW5kKHt9LCBkYXRhLm9uKSA6IHt9OwogICAgICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkgewogICAgICAgICAgdmFyIGV4aXN0aW5nID0gb25ba2V5XTsKICAgICAgICAgIHZhciBvdXJzID0gdmFsdWVba2V5XTsKICAgICAgICAgIG9uW2tleV0gPSBleGlzdGluZyA/IFtdLmNvbmNhdChleGlzdGluZywgb3VycykgOiBvdXJzOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIGRhdGEKICB9CgogIC8qICAqLwoKICBmdW5jdGlvbiByZXNvbHZlU2NvcGVkU2xvdHMgKAogICAgZm5zLCAvLyBzZWUgZmxvdy92bm9kZQogICAgcmVzLAogICAgLy8gdGhlIGZvbGxvd2luZyBhcmUgYWRkZWQgaW4gMi42CiAgICBoYXNEeW5hbWljS2V5cywKICAgIGNvbnRlbnRIYXNoS2V5CiAgKSB7CiAgICByZXMgPSByZXMgfHwgeyAkc3RhYmxlOiAhaGFzRHluYW1pY0tleXMgfTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZm5zLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBzbG90ID0gZm5zW2ldOwogICAgICBpZiAoQXJyYXkuaXNBcnJheShzbG90KSkgewogICAgICAgIHJlc29sdmVTY29wZWRTbG90cyhzbG90LCByZXMsIGhhc0R5bmFtaWNLZXlzKTsKICAgICAgfSBlbHNlIGlmIChzbG90KSB7CiAgICAgICAgLy8gbWFya2VyIGZvciByZXZlcnNlIHByb3h5aW5nIHYtc2xvdCB3aXRob3V0IHNjb3BlIG9uIHRoaXMuJHNsb3RzCiAgICAgICAgaWYgKHNsb3QucHJveHkpIHsKICAgICAgICAgIHNsb3QuZm4ucHJveHkgPSB0cnVlOwogICAgICAgIH0KICAgICAgICByZXNbc2xvdC5rZXldID0gc2xvdC5mbjsKICAgICAgfQogICAgfQogICAgaWYgKGNvbnRlbnRIYXNoS2V5KSB7CiAgICAgIChyZXMpLiRrZXkgPSBjb250ZW50SGFzaEtleTsKICAgIH0KICAgIHJldHVybiByZXMKICB9CgogIC8qICAqLwoKICBmdW5jdGlvbiBiaW5kRHluYW1pY0tleXMgKGJhc2VPYmosIHZhbHVlcykgewogICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpICs9IDIpIHsKICAgICAgdmFyIGtleSA9IHZhbHVlc1tpXTsKICAgICAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnICYmIGtleSkgewogICAgICAgIGJhc2VPYmpbdmFsdWVzW2ldXSA9IHZhbHVlc1tpICsgMV07CiAgICAgIH0gZWxzZSBpZiAoa2V5ICE9PSAnJyAmJiBrZXkgIT09IG51bGwpIHsKICAgICAgICAvLyBudWxsIGlzIGEgc3BlaWNhbCB2YWx1ZSBmb3IgZXhwbGljaXRseSByZW1vdmluZyBhIGJpbmRpbmcKICAgICAgICB3YXJuKAogICAgICAgICAgKCJJbnZhbGlkIHZhbHVlIGZvciBkeW5hbWljIGRpcmVjdGl2ZSBhcmd1bWVudCAoZXhwZWN0ZWQgc3RyaW5nIG9yIG51bGwpOiAiICsga2V5KSwKICAgICAgICAgIHRoaXMKICAgICAgICApOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gYmFzZU9iagogIH0KCiAgLy8gaGVscGVyIHRvIGR5bmFtaWNhbGx5IGFwcGVuZCBtb2RpZmllciBydW50aW1lIG1hcmtlcnMgdG8gZXZlbnQgbmFtZXMuCiAgLy8gZW5zdXJlIG9ubHkgYXBwZW5kIHdoZW4gdmFsdWUgaXMgYWxyZWFkeSBzdHJpbmcsIG90aGVyd2lzZSBpdCB3aWxsIGJlIGNhc3QKICAvLyB0byBzdHJpbmcgYW5kIGNhdXNlIHRoZSB0eXBlIGNoZWNrIHRvIG1pc3MuCiAgZnVuY3Rpb24gcHJlcGVuZE1vZGlmaWVyICh2YWx1ZSwgc3ltYm9sKSB7CiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHN5bWJvbCArIHZhbHVlIDogdmFsdWUKICB9CgogIC8qICAqLwoKICBmdW5jdGlvbiBpbnN0YWxsUmVuZGVySGVscGVycyAodGFyZ2V0KSB7CiAgICB0YXJnZXQuX28gPSBtYXJrT25jZTsKICAgIHRhcmdldC5fbiA9IHRvTnVtYmVyOwogICAgdGFyZ2V0Ll9zID0gdG9TdHJpbmc7CiAgICB0YXJnZXQuX2wgPSByZW5kZXJMaXN0OwogICAgdGFyZ2V0Ll90ID0gcmVuZGVyU2xvdDsKICAgIHRhcmdldC5fcSA9IGxvb3NlRXF1YWw7CiAgICB0YXJnZXQuX2kgPSBsb29zZUluZGV4T2Y7CiAgICB0YXJnZXQuX20gPSByZW5kZXJTdGF0aWM7CiAgICB0YXJnZXQuX2YgPSByZXNvbHZlRmlsdGVyOwogICAgdGFyZ2V0Ll9rID0gY2hlY2tLZXlDb2RlczsKICAgIHRhcmdldC5fYiA9IGJpbmRPYmplY3RQcm9wczsKICAgIHRhcmdldC5fdiA9IGNyZWF0ZVRleHRWTm9kZTsKICAgIHRhcmdldC5fZSA9IGNyZWF0ZUVtcHR5Vk5vZGU7CiAgICB0YXJnZXQuX3UgPSByZXNvbHZlU2NvcGVkU2xvdHM7CiAgICB0YXJnZXQuX2cgPSBiaW5kT2JqZWN0TGlzdGVuZXJzOwogICAgdGFyZ2V0Ll9kID0gYmluZER5bmFtaWNLZXlzOwogICAgdGFyZ2V0Ll9wID0gcHJlcGVuZE1vZGlmaWVyOwogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIEZ1bmN0aW9uYWxSZW5kZXJDb250ZXh0ICgKICAgIGRhdGEsCiAgICBwcm9wcywKICAgIGNoaWxkcmVuLAogICAgcGFyZW50LAogICAgQ3RvcgogICkgewogICAgdmFyIHRoaXMkMSA9IHRoaXM7CgogICAgdmFyIG9wdGlvbnMgPSBDdG9yLm9wdGlvbnM7CiAgICAvLyBlbnN1cmUgdGhlIGNyZWF0ZUVsZW1lbnQgZnVuY3Rpb24gaW4gZnVuY3Rpb25hbCBjb21wb25lbnRzCiAgICAvLyBnZXRzIGEgdW5pcXVlIGNvbnRleHQgLSB0aGlzIGlzIG5lY2Vzc2FyeSBmb3IgY29ycmVjdCBuYW1lZCBzbG90IGNoZWNrCiAgICB2YXIgY29udGV4dFZtOwogICAgaWYgKGhhc093bihwYXJlbnQsICdfdWlkJykpIHsKICAgICAgY29udGV4dFZtID0gT2JqZWN0LmNyZWF0ZShwYXJlbnQpOwogICAgICAvLyAkZmxvdy1kaXNhYmxlLWxpbmUKICAgICAgY29udGV4dFZtLl9vcmlnaW5hbCA9IHBhcmVudDsKICAgIH0gZWxzZSB7CiAgICAgIC8vIHRoZSBjb250ZXh0IHZtIHBhc3NlZCBpbiBpcyBhIGZ1bmN0aW9uYWwgY29udGV4dCBhcyB3ZWxsLgogICAgICAvLyBpbiB0aGlzIGNhc2Ugd2Ugd2FudCB0byBtYWtlIHN1cmUgd2UgYXJlIGFibGUgdG8gZ2V0IGEgaG9sZCB0byB0aGUKICAgICAgLy8gcmVhbCBjb250ZXh0IGluc3RhbmNlLgogICAgICBjb250ZXh0Vm0gPSBwYXJlbnQ7CiAgICAgIC8vICRmbG93LWRpc2FibGUtbGluZQogICAgICBwYXJlbnQgPSBwYXJlbnQuX29yaWdpbmFsOwogICAgfQogICAgdmFyIGlzQ29tcGlsZWQgPSBpc1RydWUob3B0aW9ucy5fY29tcGlsZWQpOwogICAgdmFyIG5lZWROb3JtYWxpemF0aW9uID0gIWlzQ29tcGlsZWQ7CgogICAgdGhpcy5kYXRhID0gZGF0YTsKICAgIHRoaXMucHJvcHMgPSBwcm9wczsKICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjsKICAgIHRoaXMucGFyZW50ID0gcGFyZW50OwogICAgdGhpcy5saXN0ZW5lcnMgPSBkYXRhLm9uIHx8IGVtcHR5T2JqZWN0OwogICAgdGhpcy5pbmplY3Rpb25zID0gcmVzb2x2ZUluamVjdChvcHRpb25zLmluamVjdCwgcGFyZW50KTsKICAgIHRoaXMuc2xvdHMgPSBmdW5jdGlvbiAoKSB7CiAgICAgIGlmICghdGhpcyQxLiRzbG90cykgewogICAgICAgIG5vcm1hbGl6ZVNjb3BlZFNsb3RzKAogICAgICAgICAgZGF0YS5zY29wZWRTbG90cywKICAgICAgICAgIHRoaXMkMS4kc2xvdHMgPSByZXNvbHZlU2xvdHMoY2hpbGRyZW4sIHBhcmVudCkKICAgICAgICApOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzJDEuJHNsb3RzCiAgICB9OwoKICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnc2NvcGVkU2xvdHMnLCAoewogICAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgICBnZXQ6IGZ1bmN0aW9uIGdldCAoKSB7CiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZVNjb3BlZFNsb3RzKGRhdGEuc2NvcGVkU2xvdHMsIHRoaXMuc2xvdHMoKSkKICAgICAgfQogICAgfSkpOwoKICAgIC8vIHN1cHBvcnQgZm9yIGNvbXBpbGVkIGZ1bmN0aW9uYWwgdGVtcGxhdGUKICAgIGlmIChpc0NvbXBpbGVkKSB7CiAgICAgIC8vIGV4cG9zaW5nICRvcHRpb25zIGZvciByZW5kZXJTdGF0aWMoKQogICAgICB0aGlzLiRvcHRpb25zID0gb3B0aW9uczsKICAgICAgLy8gcHJlLXJlc29sdmUgc2xvdHMgZm9yIHJlbmRlclNsb3QoKQogICAgICB0aGlzLiRzbG90cyA9IHRoaXMuc2xvdHMoKTsKICAgICAgdGhpcy4kc2NvcGVkU2xvdHMgPSBub3JtYWxpemVTY29wZWRTbG90cyhkYXRhLnNjb3BlZFNsb3RzLCB0aGlzLiRzbG90cyk7CiAgICB9CgogICAgaWYgKG9wdGlvbnMuX3Njb3BlSWQpIHsKICAgICAgdGhpcy5fYyA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkKSB7CiAgICAgICAgdmFyIHZub2RlID0gY3JlYXRlRWxlbWVudChjb250ZXh0Vm0sIGEsIGIsIGMsIGQsIG5lZWROb3JtYWxpemF0aW9uKTsKICAgICAgICBpZiAodm5vZGUgJiYgIUFycmF5LmlzQXJyYXkodm5vZGUpKSB7CiAgICAgICAgICB2bm9kZS5mblNjb3BlSWQgPSBvcHRpb25zLl9zY29wZUlkOwogICAgICAgICAgdm5vZGUuZm5Db250ZXh0ID0gcGFyZW50OwogICAgICAgIH0KICAgICAgICByZXR1cm4gdm5vZGUKICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgIHRoaXMuX2MgPSBmdW5jdGlvbiAoYSwgYiwgYywgZCkgeyByZXR1cm4gY3JlYXRlRWxlbWVudChjb250ZXh0Vm0sIGEsIGIsIGMsIGQsIG5lZWROb3JtYWxpemF0aW9uKTsgfTsKICAgIH0KICB9CgogIGluc3RhbGxSZW5kZXJIZWxwZXJzKEZ1bmN0aW9uYWxSZW5kZXJDb250ZXh0LnByb3RvdHlwZSk7CgogIGZ1bmN0aW9uIGNyZWF0ZUZ1bmN0aW9uYWxDb21wb25lbnQgKAogICAgQ3RvciwKICAgIHByb3BzRGF0YSwKICAgIGRhdGEsCiAgICBjb250ZXh0Vm0sCiAgICBjaGlsZHJlbgogICkgewogICAgdmFyIG9wdGlvbnMgPSBDdG9yLm9wdGlvbnM7CiAgICB2YXIgcHJvcHMgPSB7fTsKICAgIHZhciBwcm9wT3B0aW9ucyA9IG9wdGlvbnMucHJvcHM7CiAgICBpZiAoaXNEZWYocHJvcE9wdGlvbnMpKSB7CiAgICAgIGZvciAodmFyIGtleSBpbiBwcm9wT3B0aW9ucykgewogICAgICAgIHByb3BzW2tleV0gPSB2YWxpZGF0ZVByb3Aoa2V5LCBwcm9wT3B0aW9ucywgcHJvcHNEYXRhIHx8IGVtcHR5T2JqZWN0KTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgaWYgKGlzRGVmKGRhdGEuYXR0cnMpKSB7IG1lcmdlUHJvcHMocHJvcHMsIGRhdGEuYXR0cnMpOyB9CiAgICAgIGlmIChpc0RlZihkYXRhLnByb3BzKSkgeyBtZXJnZVByb3BzKHByb3BzLCBkYXRhLnByb3BzKTsgfQogICAgfQoKICAgIHZhciByZW5kZXJDb250ZXh0ID0gbmV3IEZ1bmN0aW9uYWxSZW5kZXJDb250ZXh0KAogICAgICBkYXRhLAogICAgICBwcm9wcywKICAgICAgY2hpbGRyZW4sCiAgICAgIGNvbnRleHRWbSwKICAgICAgQ3RvcgogICAgKTsKCiAgICB2YXIgdm5vZGUgPSBvcHRpb25zLnJlbmRlci5jYWxsKG51bGwsIHJlbmRlckNvbnRleHQuX2MsIHJlbmRlckNvbnRleHQpOwoKICAgIGlmICh2bm9kZSBpbnN0YW5jZW9mIFZOb2RlKSB7CiAgICAgIHJldHVybiBjbG9uZUFuZE1hcmtGdW5jdGlvbmFsUmVzdWx0KHZub2RlLCBkYXRhLCByZW5kZXJDb250ZXh0LnBhcmVudCwgb3B0aW9ucywgcmVuZGVyQ29udGV4dCkKICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2bm9kZSkpIHsKICAgICAgdmFyIHZub2RlcyA9IG5vcm1hbGl6ZUNoaWxkcmVuKHZub2RlKSB8fCBbXTsKICAgICAgdmFyIHJlcyA9IG5ldyBBcnJheSh2bm9kZXMubGVuZ3RoKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2bm9kZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICByZXNbaV0gPSBjbG9uZUFuZE1hcmtGdW5jdGlvbmFsUmVzdWx0KHZub2Rlc1tpXSwgZGF0YSwgcmVuZGVyQ29udGV4dC5wYXJlbnQsIG9wdGlvbnMsIHJlbmRlckNvbnRleHQpOwogICAgICB9CiAgICAgIHJldHVybiByZXMKICAgIH0KICB9CgogIGZ1bmN0aW9uIGNsb25lQW5kTWFya0Z1bmN0aW9uYWxSZXN1bHQgKHZub2RlLCBkYXRhLCBjb250ZXh0Vm0sIG9wdGlvbnMsIHJlbmRlckNvbnRleHQpIHsKICAgIC8vICM3ODE3IGNsb25lIG5vZGUgYmVmb3JlIHNldHRpbmcgZm5Db250ZXh0LCBvdGhlcndpc2UgaWYgdGhlIG5vZGUgaXMgcmV1c2VkCiAgICAvLyAoZS5nLiBpdCB3YXMgZnJvbSBhIGNhY2hlZCBub3JtYWwgc2xvdCkgdGhlIGZuQ29udGV4dCBjYXVzZXMgbmFtZWQgc2xvdHMKICAgIC8vIHRoYXQgc2hvdWxkIG5vdCBiZSBtYXRjaGVkIHRvIG1hdGNoLgogICAgdmFyIGNsb25lID0gY2xvbmVWTm9kZSh2bm9kZSk7CiAgICBjbG9uZS5mbkNvbnRleHQgPSBjb250ZXh0Vm07CiAgICBjbG9uZS5mbk9wdGlvbnMgPSBvcHRpb25zOwogICAgewogICAgICAoY2xvbmUuZGV2dG9vbHNNZXRhID0gY2xvbmUuZGV2dG9vbHNNZXRhIHx8IHt9KS5yZW5kZXJDb250ZXh0ID0gcmVuZGVyQ29udGV4dDsKICAgIH0KICAgIGlmIChkYXRhLnNsb3QpIHsKICAgICAgKGNsb25lLmRhdGEgfHwgKGNsb25lLmRhdGEgPSB7fSkpLnNsb3QgPSBkYXRhLnNsb3Q7CiAgICB9CiAgICByZXR1cm4gY2xvbmUKICB9CgogIGZ1bmN0aW9uIG1lcmdlUHJvcHMgKHRvLCBmcm9tKSB7CiAgICBmb3IgKHZhciBrZXkgaW4gZnJvbSkgewogICAgICB0b1tjYW1lbGl6ZShrZXkpXSA9IGZyb21ba2V5XTsKICAgIH0KICB9CgogIC8qICAqLwoKICAvKiAgKi8KCiAgLyogICovCgogIC8qICAqLwoKICAvLyBpbmxpbmUgaG9va3MgdG8gYmUgaW52b2tlZCBvbiBjb21wb25lbnQgVk5vZGVzIGR1cmluZyBwYXRjaAogIHZhciBjb21wb25lbnRWTm9kZUhvb2tzID0gewogICAgaW5pdDogZnVuY3Rpb24gaW5pdCAodm5vZGUsIGh5ZHJhdGluZykgewogICAgICBpZiAoCiAgICAgICAgdm5vZGUuY29tcG9uZW50SW5zdGFuY2UgJiYKICAgICAgICAhdm5vZGUuY29tcG9uZW50SW5zdGFuY2UuX2lzRGVzdHJveWVkICYmCiAgICAgICAgdm5vZGUuZGF0YS5rZWVwQWxpdmUKICAgICAgKSB7CiAgICAgICAgLy8ga2VwdC1hbGl2ZSBjb21wb25lbnRzLCB0cmVhdCBhcyBhIHBhdGNoCiAgICAgICAgdmFyIG1vdW50ZWROb2RlID0gdm5vZGU7IC8vIHdvcmsgYXJvdW5kIGZsb3cKICAgICAgICBjb21wb25lbnRWTm9kZUhvb2tzLnByZXBhdGNoKG1vdW50ZWROb2RlLCBtb3VudGVkTm9kZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmFyIGNoaWxkID0gdm5vZGUuY29tcG9uZW50SW5zdGFuY2UgPSBjcmVhdGVDb21wb25lbnRJbnN0YW5jZUZvclZub2RlKAogICAgICAgICAgdm5vZGUsCiAgICAgICAgICBhY3RpdmVJbnN0YW5jZQogICAgICAgICk7CiAgICAgICAgY2hpbGQuJG1vdW50KGh5ZHJhdGluZyA/IHZub2RlLmVsbSA6IHVuZGVmaW5lZCwgaHlkcmF0aW5nKTsKICAgICAgfQogICAgfSwKCiAgICBwcmVwYXRjaDogZnVuY3Rpb24gcHJlcGF0Y2ggKG9sZFZub2RlLCB2bm9kZSkgewogICAgICB2YXIgb3B0aW9ucyA9IHZub2RlLmNvbXBvbmVudE9wdGlvbnM7CiAgICAgIHZhciBjaGlsZCA9IHZub2RlLmNvbXBvbmVudEluc3RhbmNlID0gb2xkVm5vZGUuY29tcG9uZW50SW5zdGFuY2U7CiAgICAgIHVwZGF0ZUNoaWxkQ29tcG9uZW50KAogICAgICAgIGNoaWxkLAogICAgICAgIG9wdGlvbnMucHJvcHNEYXRhLCAvLyB1cGRhdGVkIHByb3BzCiAgICAgICAgb3B0aW9ucy5saXN0ZW5lcnMsIC8vIHVwZGF0ZWQgbGlzdGVuZXJzCiAgICAgICAgdm5vZGUsIC8vIG5ldyBwYXJlbnQgdm5vZGUKICAgICAgICBvcHRpb25zLmNoaWxkcmVuIC8vIG5ldyBjaGlsZHJlbgogICAgICApOwogICAgfSwKCiAgICBpbnNlcnQ6IGZ1bmN0aW9uIGluc2VydCAodm5vZGUpIHsKICAgICAgdmFyIGNvbnRleHQgPSB2bm9kZS5jb250ZXh0OwogICAgICB2YXIgY29tcG9uZW50SW5zdGFuY2UgPSB2bm9kZS5jb21wb25lbnRJbnN0YW5jZTsKICAgICAgaWYgKCFjb21wb25lbnRJbnN0YW5jZS5faXNNb3VudGVkKSB7CiAgICAgICAgY29tcG9uZW50SW5zdGFuY2UuX2lzTW91bnRlZCA9IHRydWU7CiAgICAgICAgY2FsbEhvb2soY29tcG9uZW50SW5zdGFuY2UsICdtb3VudGVkJyk7CiAgICAgIH0KICAgICAgaWYgKHZub2RlLmRhdGEua2VlcEFsaXZlKSB7CiAgICAgICAgaWYgKGNvbnRleHQuX2lzTW91bnRlZCkgewogICAgICAgICAgLy8gdnVlLXJvdXRlciMxMjEyCiAgICAgICAgICAvLyBEdXJpbmcgdXBkYXRlcywgYSBrZXB0LWFsaXZlIGNvbXBvbmVudCdzIGNoaWxkIGNvbXBvbmVudHMgbWF5CiAgICAgICAgICAvLyBjaGFuZ2UsIHNvIGRpcmVjdGx5IHdhbGtpbmcgdGhlIHRyZWUgaGVyZSBtYXkgY2FsbCBhY3RpdmF0ZWQgaG9va3MKICAgICAgICAgIC8vIG9uIGluY29ycmVjdCBjaGlsZHJlbi4gSW5zdGVhZCB3ZSBwdXNoIHRoZW0gaW50byBhIHF1ZXVlIHdoaWNoIHdpbGwKICAgICAgICAgIC8vIGJlIHByb2Nlc3NlZCBhZnRlciB0aGUgd2hvbGUgcGF0Y2ggcHJvY2VzcyBlbmRlZC4KICAgICAgICAgIHF1ZXVlQWN0aXZhdGVkQ29tcG9uZW50KGNvbXBvbmVudEluc3RhbmNlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYWN0aXZhdGVDaGlsZENvbXBvbmVudChjb21wb25lbnRJbnN0YW5jZSwgdHJ1ZSAvKiBkaXJlY3QgKi8pOwogICAgICAgIH0KICAgICAgfQogICAgfSwKCiAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95ICh2bm9kZSkgewogICAgICB2YXIgY29tcG9uZW50SW5zdGFuY2UgPSB2bm9kZS5jb21wb25lbnRJbnN0YW5jZTsKICAgICAgaWYgKCFjb21wb25lbnRJbnN0YW5jZS5faXNEZXN0cm95ZWQpIHsKICAgICAgICBpZiAoIXZub2RlLmRhdGEua2VlcEFsaXZlKSB7CiAgICAgICAgICBjb21wb25lbnRJbnN0YW5jZS4kZGVzdHJveSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBkZWFjdGl2YXRlQ2hpbGRDb21wb25lbnQoY29tcG9uZW50SW5zdGFuY2UsIHRydWUgLyogZGlyZWN0ICovKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9OwoKICB2YXIgaG9va3NUb01lcmdlID0gT2JqZWN0LmtleXMoY29tcG9uZW50Vk5vZGVIb29rcyk7CgogIGZ1bmN0aW9uIGNyZWF0ZUNvbXBvbmVudCAoCiAgICBDdG9yLAogICAgZGF0YSwKICAgIGNvbnRleHQsCiAgICBjaGlsZHJlbiwKICAgIHRhZwogICkgewogICAgaWYgKGlzVW5kZWYoQ3RvcikpIHsKICAgICAgcmV0dXJuCiAgICB9CgogICAgdmFyIGJhc2VDdG9yID0gY29udGV4dC4kb3B0aW9ucy5fYmFzZTsKCiAgICAvLyBwbGFpbiBvcHRpb25zIG9iamVjdDogdHVybiBpdCBpbnRvIGEgY29uc3RydWN0b3IKICAgIGlmIChpc09iamVjdChDdG9yKSkgewogICAgICBDdG9yID0gYmFzZUN0b3IuZXh0ZW5kKEN0b3IpOwogICAgfQoKICAgIC8vIGlmIGF0IHRoaXMgc3RhZ2UgaXQncyBub3QgYSBjb25zdHJ1Y3RvciBvciBhbiBhc3luYyBjb21wb25lbnQgZmFjdG9yeSwKICAgIC8vIHJlamVjdC4KICAgIGlmICh0eXBlb2YgQ3RvciAhPT0gJ2Z1bmN0aW9uJykgewogICAgICB7CiAgICAgICAgd2FybigoIkludmFsaWQgQ29tcG9uZW50IGRlZmluaXRpb246ICIgKyAoU3RyaW5nKEN0b3IpKSksIGNvbnRleHQpOwogICAgICB9CiAgICAgIHJldHVybgogICAgfQoKICAgIC8vIGFzeW5jIGNvbXBvbmVudAogICAgdmFyIGFzeW5jRmFjdG9yeTsKICAgIGlmIChpc1VuZGVmKEN0b3IuY2lkKSkgewogICAgICBhc3luY0ZhY3RvcnkgPSBDdG9yOwogICAgICBDdG9yID0gcmVzb2x2ZUFzeW5jQ29tcG9uZW50KGFzeW5jRmFjdG9yeSwgYmFzZUN0b3IpOwogICAgICBpZiAoQ3RvciA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgLy8gcmV0dXJuIGEgcGxhY2Vob2xkZXIgbm9kZSBmb3IgYXN5bmMgY29tcG9uZW50LCB3aGljaCBpcyByZW5kZXJlZAogICAgICAgIC8vIGFzIGEgY29tbWVudCBub2RlIGJ1dCBwcmVzZXJ2ZXMgYWxsIHRoZSByYXcgaW5mb3JtYXRpb24gZm9yIHRoZSBub2RlLgogICAgICAgIC8vIHRoZSBpbmZvcm1hdGlvbiB3aWxsIGJlIHVzZWQgZm9yIGFzeW5jIHNlcnZlci1yZW5kZXJpbmcgYW5kIGh5ZHJhdGlvbi4KICAgICAgICByZXR1cm4gY3JlYXRlQXN5bmNQbGFjZWhvbGRlcigKICAgICAgICAgIGFzeW5jRmFjdG9yeSwKICAgICAgICAgIGRhdGEsCiAgICAgICAgICBjb250ZXh0LAogICAgICAgICAgY2hpbGRyZW4sCiAgICAgICAgICB0YWcKICAgICAgICApCiAgICAgIH0KICAgIH0KCiAgICBkYXRhID0gZGF0YSB8fCB7fTsKCiAgICAvLyByZXNvbHZlIGNvbnN0cnVjdG9yIG9wdGlvbnMgaW4gY2FzZSBnbG9iYWwgbWl4aW5zIGFyZSBhcHBsaWVkIGFmdGVyCiAgICAvLyBjb21wb25lbnQgY29uc3RydWN0b3IgY3JlYXRpb24KICAgIHJlc29sdmVDb25zdHJ1Y3Rvck9wdGlvbnMoQ3Rvcik7CgogICAgLy8gdHJhbnNmb3JtIGNvbXBvbmVudCB2LW1vZGVsIGRhdGEgaW50byBwcm9wcyAmIGV2ZW50cwogICAgaWYgKGlzRGVmKGRhdGEubW9kZWwpKSB7CiAgICAgIHRyYW5zZm9ybU1vZGVsKEN0b3Iub3B0aW9ucywgZGF0YSk7CiAgICB9CgogICAgLy8gZXh0cmFjdCBwcm9wcwogICAgdmFyIHByb3BzRGF0YSA9IGV4dHJhY3RQcm9wc0Zyb21WTm9kZURhdGEoZGF0YSwgQ3RvciwgdGFnKTsKCiAgICAvLyBmdW5jdGlvbmFsIGNvbXBvbmVudAogICAgaWYgKGlzVHJ1ZShDdG9yLm9wdGlvbnMuZnVuY3Rpb25hbCkpIHsKICAgICAgcmV0dXJuIGNyZWF0ZUZ1bmN0aW9uYWxDb21wb25lbnQoQ3RvciwgcHJvcHNEYXRhLCBkYXRhLCBjb250ZXh0LCBjaGlsZHJlbikKICAgIH0KCiAgICAvLyBleHRyYWN0IGxpc3RlbmVycywgc2luY2UgdGhlc2UgbmVlZHMgdG8gYmUgdHJlYXRlZCBhcwogICAgLy8gY2hpbGQgY29tcG9uZW50IGxpc3RlbmVycyBpbnN0ZWFkIG9mIERPTSBsaXN0ZW5lcnMKICAgIHZhciBsaXN0ZW5lcnMgPSBkYXRhLm9uOwogICAgLy8gcmVwbGFjZSB3aXRoIGxpc3RlbmVycyB3aXRoIC5uYXRpdmUgbW9kaWZpZXIKICAgIC8vIHNvIGl0IGdldHMgcHJvY2Vzc2VkIGR1cmluZyBwYXJlbnQgY29tcG9uZW50IHBhdGNoLgogICAgZGF0YS5vbiA9IGRhdGEubmF0aXZlT247CgogICAgaWYgKGlzVHJ1ZShDdG9yLm9wdGlvbnMuYWJzdHJhY3QpKSB7CiAgICAgIC8vIGFic3RyYWN0IGNvbXBvbmVudHMgZG8gbm90IGtlZXAgYW55dGhpbmcKICAgICAgLy8gb3RoZXIgdGhhbiBwcm9wcyAmIGxpc3RlbmVycyAmIHNsb3QKCiAgICAgIC8vIHdvcmsgYXJvdW5kIGZsb3cKICAgICAgdmFyIHNsb3QgPSBkYXRhLnNsb3Q7CiAgICAgIGRhdGEgPSB7fTsKICAgICAgaWYgKHNsb3QpIHsKICAgICAgICBkYXRhLnNsb3QgPSBzbG90OwogICAgICB9CiAgICB9CgogICAgLy8gaW5zdGFsbCBjb21wb25lbnQgbWFuYWdlbWVudCBob29rcyBvbnRvIHRoZSBwbGFjZWhvbGRlciBub2RlCiAgICBpbnN0YWxsQ29tcG9uZW50SG9va3MoZGF0YSk7CgogICAgLy8gcmV0dXJuIGEgcGxhY2Vob2xkZXIgdm5vZGUKICAgIHZhciBuYW1lID0gQ3Rvci5vcHRpb25zLm5hbWUgfHwgdGFnOwogICAgdmFyIHZub2RlID0gbmV3IFZOb2RlKAogICAgICAoInZ1ZS1jb21wb25lbnQtIiArIChDdG9yLmNpZCkgKyAobmFtZSA/ICgiLSIgKyBuYW1lKSA6ICcnKSksCiAgICAgIGRhdGEsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGNvbnRleHQsCiAgICAgIHsgQ3RvcjogQ3RvciwgcHJvcHNEYXRhOiBwcm9wc0RhdGEsIGxpc3RlbmVyczogbGlzdGVuZXJzLCB0YWc6IHRhZywgY2hpbGRyZW46IGNoaWxkcmVuIH0sCiAgICAgIGFzeW5jRmFjdG9yeQogICAgKTsKCiAgICByZXR1cm4gdm5vZGUKICB9CgogIGZ1bmN0aW9uIGNyZWF0ZUNvbXBvbmVudEluc3RhbmNlRm9yVm5vZGUgKAogICAgdm5vZGUsIC8vIHdlIGtub3cgaXQncyBNb3VudGVkQ29tcG9uZW50Vk5vZGUgYnV0IGZsb3cgZG9lc24ndAogICAgcGFyZW50IC8vIGFjdGl2ZUluc3RhbmNlIGluIGxpZmVjeWNsZSBzdGF0ZQogICkgewogICAgdmFyIG9wdGlvbnMgPSB7CiAgICAgIF9pc0NvbXBvbmVudDogdHJ1ZSwKICAgICAgX3BhcmVudFZub2RlOiB2bm9kZSwKICAgICAgcGFyZW50OiBwYXJlbnQKICAgIH07CiAgICAvLyBjaGVjayBpbmxpbmUtdGVtcGxhdGUgcmVuZGVyIGZ1bmN0aW9ucwogICAgdmFyIGlubGluZVRlbXBsYXRlID0gdm5vZGUuZGF0YS5pbmxpbmVUZW1wbGF0ZTsKICAgIGlmIChpc0RlZihpbmxpbmVUZW1wbGF0ZSkpIHsKICAgICAgb3B0aW9ucy5yZW5kZXIgPSBpbmxpbmVUZW1wbGF0ZS5yZW5kZXI7CiAgICAgIG9wdGlvbnMuc3RhdGljUmVuZGVyRm5zID0gaW5saW5lVGVtcGxhdGUuc3RhdGljUmVuZGVyRm5zOwogICAgfQogICAgcmV0dXJuIG5ldyB2bm9kZS5jb21wb25lbnRPcHRpb25zLkN0b3Iob3B0aW9ucykKICB9CgogIGZ1bmN0aW9uIGluc3RhbGxDb21wb25lbnRIb29rcyAoZGF0YSkgewogICAgdmFyIGhvb2tzID0gZGF0YS5ob29rIHx8IChkYXRhLmhvb2sgPSB7fSk7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhvb2tzVG9NZXJnZS5sZW5ndGg7IGkrKykgewogICAgICB2YXIga2V5ID0gaG9va3NUb01lcmdlW2ldOwogICAgICB2YXIgZXhpc3RpbmcgPSBob29rc1trZXldOwogICAgICB2YXIgdG9NZXJnZSA9IGNvbXBvbmVudFZOb2RlSG9va3Nba2V5XTsKICAgICAgaWYgKGV4aXN0aW5nICE9PSB0b01lcmdlICYmICEoZXhpc3RpbmcgJiYgZXhpc3RpbmcuX21lcmdlZCkpIHsKICAgICAgICBob29rc1trZXldID0gZXhpc3RpbmcgPyBtZXJnZUhvb2skMSh0b01lcmdlLCBleGlzdGluZykgOiB0b01lcmdlOwogICAgICB9CiAgICB9CiAgfQoKICBmdW5jdGlvbiBtZXJnZUhvb2skMSAoZjEsIGYyKSB7CiAgICB2YXIgbWVyZ2VkID0gZnVuY3Rpb24gKGEsIGIpIHsKICAgICAgLy8gZmxvdyBjb21wbGFpbnMgYWJvdXQgZXh0cmEgYXJncyB3aGljaCBpcyB3aHkgd2UgdXNlIGFueQogICAgICBmMShhLCBiKTsKICAgICAgZjIoYSwgYik7CiAgICB9OwogICAgbWVyZ2VkLl9tZXJnZWQgPSB0cnVlOwogICAgcmV0dXJuIG1lcmdlZAogIH0KCiAgLy8gdHJhbnNmb3JtIGNvbXBvbmVudCB2LW1vZGVsIGluZm8gKHZhbHVlIGFuZCBjYWxsYmFjaykgaW50bwogIC8vIHByb3AgYW5kIGV2ZW50IGhhbmRsZXIgcmVzcGVjdGl2ZWx5LgogIGZ1bmN0aW9uIHRyYW5zZm9ybU1vZGVsIChvcHRpb25zLCBkYXRhKSB7CiAgICB2YXIgcHJvcCA9IChvcHRpb25zLm1vZGVsICYmIG9wdGlvbnMubW9kZWwucHJvcCkgfHwgJ3ZhbHVlJzsKICAgIHZhciBldmVudCA9IChvcHRpb25zLm1vZGVsICYmIG9wdGlvbnMubW9kZWwuZXZlbnQpIHx8ICdpbnB1dCcKICAgIDsoZGF0YS5hdHRycyB8fCAoZGF0YS5hdHRycyA9IHt9KSlbcHJvcF0gPSBkYXRhLm1vZGVsLnZhbHVlOwogICAgdmFyIG9uID0gZGF0YS5vbiB8fCAoZGF0YS5vbiA9IHt9KTsKICAgIHZhciBleGlzdGluZyA9IG9uW2V2ZW50XTsKICAgIHZhciBjYWxsYmFjayA9IGRhdGEubW9kZWwuY2FsbGJhY2s7CiAgICBpZiAoaXNEZWYoZXhpc3RpbmcpKSB7CiAgICAgIGlmICgKICAgICAgICBBcnJheS5pc0FycmF5KGV4aXN0aW5nKQogICAgICAgICAgPyBleGlzdGluZy5pbmRleE9mKGNhbGxiYWNrKSA9PT0gLTEKICAgICAgICAgIDogZXhpc3RpbmcgIT09IGNhbGxiYWNrCiAgICAgICkgewogICAgICAgIG9uW2V2ZW50XSA9IFtjYWxsYmFja10uY29uY2F0KGV4aXN0aW5nKTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgb25bZXZlbnRdID0gY2FsbGJhY2s7CiAgICB9CiAgfQoKICAvKiAgKi8KCiAgdmFyIFNJTVBMRV9OT1JNQUxJWkUgPSAxOwogIHZhciBBTFdBWVNfTk9STUFMSVpFID0gMjsKCiAgLy8gd3JhcHBlciBmdW5jdGlvbiBmb3IgcHJvdmlkaW5nIGEgbW9yZSBmbGV4aWJsZSBpbnRlcmZhY2UKICAvLyB3aXRob3V0IGdldHRpbmcgeWVsbGVkIGF0IGJ5IGZsb3cKICBmdW5jdGlvbiBjcmVhdGVFbGVtZW50ICgKICAgIGNvbnRleHQsCiAgICB0YWcsCiAgICBkYXRhLAogICAgY2hpbGRyZW4sCiAgICBub3JtYWxpemF0aW9uVHlwZSwKICAgIGFsd2F5c05vcm1hbGl6ZQogICkgewogICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkgfHwgaXNQcmltaXRpdmUoZGF0YSkpIHsKICAgICAgbm9ybWFsaXphdGlvblR5cGUgPSBjaGlsZHJlbjsKICAgICAgY2hpbGRyZW4gPSBkYXRhOwogICAgICBkYXRhID0gdW5kZWZpbmVkOwogICAgfQogICAgaWYgKGlzVHJ1ZShhbHdheXNOb3JtYWxpemUpKSB7CiAgICAgIG5vcm1hbGl6YXRpb25UeXBlID0gQUxXQVlTX05PUk1BTElaRTsKICAgIH0KICAgIHJldHVybiBfY3JlYXRlRWxlbWVudChjb250ZXh0LCB0YWcsIGRhdGEsIGNoaWxkcmVuLCBub3JtYWxpemF0aW9uVHlwZSkKICB9CgogIGZ1bmN0aW9uIF9jcmVhdGVFbGVtZW50ICgKICAgIGNvbnRleHQsCiAgICB0YWcsCiAgICBkYXRhLAogICAgY2hpbGRyZW4sCiAgICBub3JtYWxpemF0aW9uVHlwZQogICkgewogICAgaWYgKGlzRGVmKGRhdGEpICYmIGlzRGVmKChkYXRhKS5fX29iX18pKSB7CiAgICAgIHdhcm4oCiAgICAgICAgIkF2b2lkIHVzaW5nIG9ic2VydmVkIGRhdGEgb2JqZWN0IGFzIHZub2RlIGRhdGE6ICIgKyAoSlNPTi5zdHJpbmdpZnkoZGF0YSkpICsgIlxuIiArCiAgICAgICAgJ0Fsd2F5cyBjcmVhdGUgZnJlc2ggdm5vZGUgZGF0YSBvYmplY3RzIGluIGVhY2ggcmVuZGVyIScsCiAgICAgICAgY29udGV4dAogICAgICApOwogICAgICByZXR1cm4gY3JlYXRlRW1wdHlWTm9kZSgpCiAgICB9CiAgICAvLyBvYmplY3Qgc3ludGF4IGluIHYtYmluZAogICAgaWYgKGlzRGVmKGRhdGEpICYmIGlzRGVmKGRhdGEuaXMpKSB7CiAgICAgIHRhZyA9IGRhdGEuaXM7CiAgICB9CiAgICBpZiAoIXRhZykgewogICAgICAvLyBpbiBjYXNlIG9mIGNvbXBvbmVudCA6aXMgc2V0IHRvIGZhbHN5IHZhbHVlCiAgICAgIHJldHVybiBjcmVhdGVFbXB0eVZOb2RlKCkKICAgIH0KICAgIC8vIHdhcm4gYWdhaW5zdCBub24tcHJpbWl0aXZlIGtleQogICAgaWYgKGlzRGVmKGRhdGEpICYmIGlzRGVmKGRhdGEua2V5KSAmJiAhaXNQcmltaXRpdmUoZGF0YS5rZXkpCiAgICApIHsKICAgICAgewogICAgICAgIHdhcm4oCiAgICAgICAgICAnQXZvaWQgdXNpbmcgbm9uLXByaW1pdGl2ZSB2YWx1ZSBhcyBrZXksICcgKwogICAgICAgICAgJ3VzZSBzdHJpbmcvbnVtYmVyIHZhbHVlIGluc3RlYWQuJywKICAgICAgICAgIGNvbnRleHQKICAgICAgICApOwogICAgICB9CiAgICB9CiAgICAvLyBzdXBwb3J0IHNpbmdsZSBmdW5jdGlvbiBjaGlsZHJlbiBhcyBkZWZhdWx0IHNjb3BlZCBzbG90CiAgICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZHJlbikgJiYKICAgICAgdHlwZW9mIGNoaWxkcmVuWzBdID09PSAnZnVuY3Rpb24nCiAgICApIHsKICAgICAgZGF0YSA9IGRhdGEgfHwge307CiAgICAgIGRhdGEuc2NvcGVkU2xvdHMgPSB7IGRlZmF1bHQ6IGNoaWxkcmVuWzBdIH07CiAgICAgIGNoaWxkcmVuLmxlbmd0aCA9IDA7CiAgICB9CiAgICBpZiAobm9ybWFsaXphdGlvblR5cGUgPT09IEFMV0FZU19OT1JNQUxJWkUpIHsKICAgICAgY2hpbGRyZW4gPSBub3JtYWxpemVDaGlsZHJlbihjaGlsZHJlbik7CiAgICB9IGVsc2UgaWYgKG5vcm1hbGl6YXRpb25UeXBlID09PSBTSU1QTEVfTk9STUFMSVpFKSB7CiAgICAgIGNoaWxkcmVuID0gc2ltcGxlTm9ybWFsaXplQ2hpbGRyZW4oY2hpbGRyZW4pOwogICAgfQogICAgdmFyIHZub2RlLCBuczsKICAgIGlmICh0eXBlb2YgdGFnID09PSAnc3RyaW5nJykgewogICAgICB2YXIgQ3RvcjsKICAgICAgbnMgPSAoY29udGV4dC4kdm5vZGUgJiYgY29udGV4dC4kdm5vZGUubnMpIHx8IGNvbmZpZy5nZXRUYWdOYW1lc3BhY2UodGFnKTsKICAgICAgaWYgKGNvbmZpZy5pc1Jlc2VydmVkVGFnKHRhZykpIHsKICAgICAgICAvLyBwbGF0Zm9ybSBidWlsdC1pbiBlbGVtZW50cwogICAgICAgIHZub2RlID0gbmV3IFZOb2RlKAogICAgICAgICAgY29uZmlnLnBhcnNlUGxhdGZvcm1UYWdOYW1lKHRhZyksIGRhdGEsIGNoaWxkcmVuLAogICAgICAgICAgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGNvbnRleHQKICAgICAgICApOwogICAgICB9IGVsc2UgaWYgKCghZGF0YSB8fCAhZGF0YS5wcmUpICYmIGlzRGVmKEN0b3IgPSByZXNvbHZlQXNzZXQoY29udGV4dC4kb3B0aW9ucywgJ2NvbXBvbmVudHMnLCB0YWcpKSkgewogICAgICAgIC8vIGNvbXBvbmVudAogICAgICAgIHZub2RlID0gY3JlYXRlQ29tcG9uZW50KEN0b3IsIGRhdGEsIGNvbnRleHQsIGNoaWxkcmVuLCB0YWcpOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIHVua25vd24gb3IgdW5saXN0ZWQgbmFtZXNwYWNlZCBlbGVtZW50cwogICAgICAgIC8vIGNoZWNrIGF0IHJ1bnRpbWUgYmVjYXVzZSBpdCBtYXkgZ2V0IGFzc2lnbmVkIGEgbmFtZXNwYWNlIHdoZW4gaXRzCiAgICAgICAgLy8gcGFyZW50IG5vcm1hbGl6ZXMgY2hpbGRyZW4KICAgICAgICB2bm9kZSA9IG5ldyBWTm9kZSgKICAgICAgICAgIHRhZywgZGF0YSwgY2hpbGRyZW4sCiAgICAgICAgICB1bmRlZmluZWQsIHVuZGVmaW5lZCwgY29udGV4dAogICAgICAgICk7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIC8vIGRpcmVjdCBjb21wb25lbnQgb3B0aW9ucyAvIGNvbnN0cnVjdG9yCiAgICAgIHZub2RlID0gY3JlYXRlQ29tcG9uZW50KHRhZywgZGF0YSwgY29udGV4dCwgY2hpbGRyZW4pOwogICAgfQogICAgaWYgKEFycmF5LmlzQXJyYXkodm5vZGUpKSB7CiAgICAgIHJldHVybiB2bm9kZQogICAgfSBlbHNlIGlmIChpc0RlZih2bm9kZSkpIHsKICAgICAgaWYgKGlzRGVmKG5zKSkgeyBhcHBseU5TKHZub2RlLCBucyk7IH0KICAgICAgaWYgKGlzRGVmKGRhdGEpKSB7IHJlZ2lzdGVyRGVlcEJpbmRpbmdzKGRhdGEpOyB9CiAgICAgIHJldHVybiB2bm9kZQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIGNyZWF0ZUVtcHR5Vk5vZGUoKQogICAgfQogIH0KCiAgZnVuY3Rpb24gYXBwbHlOUyAodm5vZGUsIG5zLCBmb3JjZSkgewogICAgdm5vZGUubnMgPSBuczsKICAgIGlmICh2bm9kZS50YWcgPT09ICdmb3JlaWduT2JqZWN0JykgewogICAgICAvLyB1c2UgZGVmYXVsdCBuYW1lc3BhY2UgaW5zaWRlIGZvcmVpZ25PYmplY3QKICAgICAgbnMgPSB1bmRlZmluZWQ7CiAgICAgIGZvcmNlID0gdHJ1ZTsKICAgIH0KICAgIGlmIChpc0RlZih2bm9kZS5jaGlsZHJlbikpIHsKICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB2bm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHsKICAgICAgICB2YXIgY2hpbGQgPSB2bm9kZS5jaGlsZHJlbltpXTsKICAgICAgICBpZiAoaXNEZWYoY2hpbGQudGFnKSAmJiAoCiAgICAgICAgICBpc1VuZGVmKGNoaWxkLm5zKSB8fCAoaXNUcnVlKGZvcmNlKSAmJiBjaGlsZC50YWcgIT09ICdzdmcnKSkpIHsKICAgICAgICAgIGFwcGx5TlMoY2hpbGQsIG5zLCBmb3JjZSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICAvLyByZWYgIzUzMTgKICAvLyBuZWNlc3NhcnkgdG8gZW5zdXJlIHBhcmVudCByZS1yZW5kZXIgd2hlbiBkZWVwIGJpbmRpbmdzIGxpa2UgOnN0eWxlIGFuZAogIC8vIDpjbGFzcyBhcmUgdXNlZCBvbiBzbG90IG5vZGVzCiAgZnVuY3Rpb24gcmVnaXN0ZXJEZWVwQmluZGluZ3MgKGRhdGEpIHsKICAgIGlmIChpc09iamVjdChkYXRhLnN0eWxlKSkgewogICAgICB0cmF2ZXJzZShkYXRhLnN0eWxlKTsKICAgIH0KICAgIGlmIChpc09iamVjdChkYXRhLmNsYXNzKSkgewogICAgICB0cmF2ZXJzZShkYXRhLmNsYXNzKTsKICAgIH0KICB9CgogIC8qICAqLwoKICBmdW5jdGlvbiBpbml0UmVuZGVyICh2bSkgewogICAgdm0uX3Zub2RlID0gbnVsbDsgLy8gdGhlIHJvb3Qgb2YgdGhlIGNoaWxkIHRyZWUKICAgIHZtLl9zdGF0aWNUcmVlcyA9IG51bGw7IC8vIHYtb25jZSBjYWNoZWQgdHJlZXMKICAgIHZhciBvcHRpb25zID0gdm0uJG9wdGlvbnM7CiAgICB2YXIgcGFyZW50Vm5vZGUgPSB2bS4kdm5vZGUgPSBvcHRpb25zLl9wYXJlbnRWbm9kZTsgLy8gdGhlIHBsYWNlaG9sZGVyIG5vZGUgaW4gcGFyZW50IHRyZWUKICAgIHZhciByZW5kZXJDb250ZXh0ID0gcGFyZW50Vm5vZGUgJiYgcGFyZW50Vm5vZGUuY29udGV4dDsKICAgIHZtLiRzbG90cyA9IHJlc29sdmVTbG90cyhvcHRpb25zLl9yZW5kZXJDaGlsZHJlbiwgcmVuZGVyQ29udGV4dCk7CiAgICB2bS4kc2NvcGVkU2xvdHMgPSBlbXB0eU9iamVjdDsKICAgIC8vIGJpbmQgdGhlIGNyZWF0ZUVsZW1lbnQgZm4gdG8gdGhpcyBpbnN0YW5jZQogICAgLy8gc28gdGhhdCB3ZSBnZXQgcHJvcGVyIHJlbmRlciBjb250ZXh0IGluc2lkZSBpdC4KICAgIC8vIGFyZ3Mgb3JkZXI6IHRhZywgZGF0YSwgY2hpbGRyZW4sIG5vcm1hbGl6YXRpb25UeXBlLCBhbHdheXNOb3JtYWxpemUKICAgIC8vIGludGVybmFsIHZlcnNpb24gaXMgdXNlZCBieSByZW5kZXIgZnVuY3Rpb25zIGNvbXBpbGVkIGZyb20gdGVtcGxhdGVzCiAgICB2bS5fYyA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkKSB7IHJldHVybiBjcmVhdGVFbGVtZW50KHZtLCBhLCBiLCBjLCBkLCBmYWxzZSk7IH07CiAgICAvLyBub3JtYWxpemF0aW9uIGlzIGFsd2F5cyBhcHBsaWVkIGZvciB0aGUgcHVibGljIHZlcnNpb24sIHVzZWQgaW4KICAgIC8vIHVzZXItd3JpdHRlbiByZW5kZXIgZnVuY3Rpb25zLgogICAgdm0uJGNyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbiAoYSwgYiwgYywgZCkgeyByZXR1cm4gY3JlYXRlRWxlbWVudCh2bSwgYSwgYiwgYywgZCwgdHJ1ZSk7IH07CgogICAgLy8gJGF0dHJzICYgJGxpc3RlbmVycyBhcmUgZXhwb3NlZCBmb3IgZWFzaWVyIEhPQyBjcmVhdGlvbi4KICAgIC8vIHRoZXkgbmVlZCB0byBiZSByZWFjdGl2ZSBzbyB0aGF0IEhPQ3MgdXNpbmcgdGhlbSBhcmUgYWx3YXlzIHVwZGF0ZWQKICAgIHZhciBwYXJlbnREYXRhID0gcGFyZW50Vm5vZGUgJiYgcGFyZW50Vm5vZGUuZGF0YTsKCiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqLwogICAgewogICAgICBkZWZpbmVSZWFjdGl2ZSQkMSh2bSwgJyRhdHRycycsIHBhcmVudERhdGEgJiYgcGFyZW50RGF0YS5hdHRycyB8fCBlbXB0eU9iamVjdCwgZnVuY3Rpb24gKCkgewogICAgICAgICFpc1VwZGF0aW5nQ2hpbGRDb21wb25lbnQgJiYgd2FybigiJGF0dHJzIGlzIHJlYWRvbmx5LiIsIHZtKTsKICAgICAgfSwgdHJ1ZSk7CiAgICAgIGRlZmluZVJlYWN0aXZlJCQxKHZtLCAnJGxpc3RlbmVycycsIG9wdGlvbnMuX3BhcmVudExpc3RlbmVycyB8fCBlbXB0eU9iamVjdCwgZnVuY3Rpb24gKCkgewogICAgICAgICFpc1VwZGF0aW5nQ2hpbGRDb21wb25lbnQgJiYgd2FybigiJGxpc3RlbmVycyBpcyByZWFkb25seS4iLCB2bSk7CiAgICAgIH0sIHRydWUpOwogICAgfQogIH0KCiAgdmFyIGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSA9IG51bGw7CgogIGZ1bmN0aW9uIHJlbmRlck1peGluIChWdWUpIHsKICAgIC8vIGluc3RhbGwgcnVudGltZSBjb252ZW5pZW5jZSBoZWxwZXJzCiAgICBpbnN0YWxsUmVuZGVySGVscGVycyhWdWUucHJvdG90eXBlKTsKCiAgICBWdWUucHJvdG90eXBlLiRuZXh0VGljayA9IGZ1bmN0aW9uIChmbikgewogICAgICByZXR1cm4gbmV4dFRpY2soZm4sIHRoaXMpCiAgICB9OwoKICAgIFZ1ZS5wcm90b3R5cGUuX3JlbmRlciA9IGZ1bmN0aW9uICgpIHsKICAgICAgdmFyIHZtID0gdGhpczsKICAgICAgdmFyIHJlZiA9IHZtLiRvcHRpb25zOwogICAgICB2YXIgcmVuZGVyID0gcmVmLnJlbmRlcjsKICAgICAgdmFyIF9wYXJlbnRWbm9kZSA9IHJlZi5fcGFyZW50Vm5vZGU7CgogICAgICBpZiAoX3BhcmVudFZub2RlKSB7CiAgICAgICAgdm0uJHNjb3BlZFNsb3RzID0gbm9ybWFsaXplU2NvcGVkU2xvdHMoCiAgICAgICAgICBfcGFyZW50Vm5vZGUuZGF0YS5zY29wZWRTbG90cywKICAgICAgICAgIHZtLiRzbG90cywKICAgICAgICAgIHZtLiRzY29wZWRTbG90cwogICAgICAgICk7CiAgICAgIH0KCiAgICAgIC8vIHNldCBwYXJlbnQgdm5vZGUuIHRoaXMgYWxsb3dzIHJlbmRlciBmdW5jdGlvbnMgdG8gaGF2ZSBhY2Nlc3MKICAgICAgLy8gdG8gdGhlIGRhdGEgb24gdGhlIHBsYWNlaG9sZGVyIG5vZGUuCiAgICAgIHZtLiR2bm9kZSA9IF9wYXJlbnRWbm9kZTsKICAgICAgLy8gcmVuZGVyIHNlbGYKICAgICAgdmFyIHZub2RlOwogICAgICB0cnkgewogICAgICAgIC8vIFRoZXJlJ3Mgbm8gbmVlZCB0byBtYWludGFpbiBhIHN0YWNrIGJlY2F1ZXMgYWxsIHJlbmRlciBmbnMgYXJlIGNhbGxlZAogICAgICAgIC8vIHNlcGFyYXRlbHkgZnJvbSBvbmUgYW5vdGhlci4gTmVzdGVkIGNvbXBvbmVudCdzIHJlbmRlciBmbnMgYXJlIGNhbGxlZAogICAgICAgIC8vIHdoZW4gcGFyZW50IGNvbXBvbmVudCBpcyBwYXRjaGVkLgogICAgICAgIGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSA9IHZtOwogICAgICAgIHZub2RlID0gcmVuZGVyLmNhbGwodm0uX3JlbmRlclByb3h5LCB2bS4kY3JlYXRlRWxlbWVudCk7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICBoYW5kbGVFcnJvcihlLCB2bSwgInJlbmRlciIpOwogICAgICAgIC8vIHJldHVybiBlcnJvciByZW5kZXIgcmVzdWx0LAogICAgICAgIC8vIG9yIHByZXZpb3VzIHZub2RlIHRvIHByZXZlbnQgcmVuZGVyIGVycm9yIGNhdXNpbmcgYmxhbmsgY29tcG9uZW50CiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi8KICAgICAgICBpZiAodm0uJG9wdGlvbnMucmVuZGVyRXJyb3IpIHsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIHZub2RlID0gdm0uJG9wdGlvbnMucmVuZGVyRXJyb3IuY2FsbCh2bS5fcmVuZGVyUHJveHksIHZtLiRjcmVhdGVFbGVtZW50LCBlKTsKICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgaGFuZGxlRXJyb3IoZSwgdm0sICJyZW5kZXJFcnJvciIpOwogICAgICAgICAgICB2bm9kZSA9IHZtLl92bm9kZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgdm5vZGUgPSB2bS5fdm5vZGU7CiAgICAgICAgfQogICAgICB9IGZpbmFsbHkgewogICAgICAgIGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSA9IG51bGw7CiAgICAgIH0KICAgICAgLy8gaWYgdGhlIHJldHVybmVkIGFycmF5IGNvbnRhaW5zIG9ubHkgYSBzaW5nbGUgbm9kZSwgYWxsb3cgaXQKICAgICAgaWYgKEFycmF5LmlzQXJyYXkodm5vZGUpICYmIHZub2RlLmxlbmd0aCA9PT0gMSkgewogICAgICAgIHZub2RlID0gdm5vZGVbMF07CiAgICAgIH0KICAgICAgLy8gcmV0dXJuIGVtcHR5IHZub2RlIGluIGNhc2UgdGhlIHJlbmRlciBmdW5jdGlvbiBlcnJvcmVkIG91dAogICAgICBpZiAoISh2bm9kZSBpbnN0YW5jZW9mIFZOb2RlKSkgewogICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZub2RlKSkgewogICAgICAgICAgd2FybigKICAgICAgICAgICAgJ011bHRpcGxlIHJvb3Qgbm9kZXMgcmV0dXJuZWQgZnJvbSByZW5kZXIgZnVuY3Rpb24uIFJlbmRlciBmdW5jdGlvbiAnICsKICAgICAgICAgICAgJ3Nob3VsZCByZXR1cm4gYSBzaW5nbGUgcm9vdCBub2RlLicsCiAgICAgICAgICAgIHZtCiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICB2bm9kZSA9IGNyZWF0ZUVtcHR5Vk5vZGUoKTsKICAgICAgfQogICAgICAvLyBzZXQgcGFyZW50CiAgICAgIHZub2RlLnBhcmVudCA9IF9wYXJlbnRWbm9kZTsKICAgICAgcmV0dXJuIHZub2RlCiAgICB9OwogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIGVuc3VyZUN0b3IgKGNvbXAsIGJhc2UpIHsKICAgIGlmICgKICAgICAgY29tcC5fX2VzTW9kdWxlIHx8CiAgICAgIChoYXNTeW1ib2wgJiYgY29tcFtTeW1ib2wudG9TdHJpbmdUYWddID09PSAnTW9kdWxlJykKICAgICkgewogICAgICBjb21wID0gY29tcC5kZWZhdWx0OwogICAgfQogICAgcmV0dXJuIGlzT2JqZWN0KGNvbXApCiAgICAgID8gYmFzZS5leHRlbmQoY29tcCkKICAgICAgOiBjb21wCiAgfQoKICBmdW5jdGlvbiBjcmVhdGVBc3luY1BsYWNlaG9sZGVyICgKICAgIGZhY3RvcnksCiAgICBkYXRhLAogICAgY29udGV4dCwKICAgIGNoaWxkcmVuLAogICAgdGFnCiAgKSB7CiAgICB2YXIgbm9kZSA9IGNyZWF0ZUVtcHR5Vk5vZGUoKTsKICAgIG5vZGUuYXN5bmNGYWN0b3J5ID0gZmFjdG9yeTsKICAgIG5vZGUuYXN5bmNNZXRhID0geyBkYXRhOiBkYXRhLCBjb250ZXh0OiBjb250ZXh0LCBjaGlsZHJlbjogY2hpbGRyZW4sIHRhZzogdGFnIH07CiAgICByZXR1cm4gbm9kZQogIH0KCiAgZnVuY3Rpb24gcmVzb2x2ZUFzeW5jQ29tcG9uZW50ICgKICAgIGZhY3RvcnksCiAgICBiYXNlQ3RvcgogICkgewogICAgaWYgKGlzVHJ1ZShmYWN0b3J5LmVycm9yKSAmJiBpc0RlZihmYWN0b3J5LmVycm9yQ29tcCkpIHsKICAgICAgcmV0dXJuIGZhY3RvcnkuZXJyb3JDb21wCiAgICB9CgogICAgaWYgKGlzRGVmKGZhY3RvcnkucmVzb2x2ZWQpKSB7CiAgICAgIHJldHVybiBmYWN0b3J5LnJlc29sdmVkCiAgICB9CgogICAgdmFyIG93bmVyID0gY3VycmVudFJlbmRlcmluZ0luc3RhbmNlOwogICAgaWYgKG93bmVyICYmIGlzRGVmKGZhY3Rvcnkub3duZXJzKSAmJiBmYWN0b3J5Lm93bmVycy5pbmRleE9mKG93bmVyKSA9PT0gLTEpIHsKICAgICAgLy8gYWxyZWFkeSBwZW5kaW5nCiAgICAgIGZhY3Rvcnkub3duZXJzLnB1c2gob3duZXIpOwogICAgfQoKICAgIGlmIChpc1RydWUoZmFjdG9yeS5sb2FkaW5nKSAmJiBpc0RlZihmYWN0b3J5LmxvYWRpbmdDb21wKSkgewogICAgICByZXR1cm4gZmFjdG9yeS5sb2FkaW5nQ29tcAogICAgfQoKICAgIGlmIChvd25lciAmJiAhaXNEZWYoZmFjdG9yeS5vd25lcnMpKSB7CiAgICAgIHZhciBvd25lcnMgPSBmYWN0b3J5Lm93bmVycyA9IFtvd25lcl07CiAgICAgIHZhciBzeW5jID0gdHJ1ZTsKICAgICAgdmFyIHRpbWVyTG9hZGluZyA9IG51bGw7CiAgICAgIHZhciB0aW1lclRpbWVvdXQgPSBudWxsCgogICAgICA7KG93bmVyKS4kb24oJ2hvb2s6ZGVzdHJveWVkJywgZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVtb3ZlKG93bmVycywgb3duZXIpOyB9KTsKCiAgICAgIHZhciBmb3JjZVJlbmRlciA9IGZ1bmN0aW9uIChyZW5kZXJDb21wbGV0ZWQpIHsKICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG93bmVycy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKICAgICAgICAgIChvd25lcnNbaV0pLiRmb3JjZVVwZGF0ZSgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHJlbmRlckNvbXBsZXRlZCkgewogICAgICAgICAgb3duZXJzLmxlbmd0aCA9IDA7CiAgICAgICAgICBpZiAodGltZXJMb2FkaW5nICE9PSBudWxsKSB7CiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lckxvYWRpbmcpOwogICAgICAgICAgICB0aW1lckxvYWRpbmcgPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHRpbWVyVGltZW91dCAhPT0gbnVsbCkgewogICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXJUaW1lb3V0KTsKICAgICAgICAgICAgdGltZXJUaW1lb3V0ID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH07CgogICAgICB2YXIgcmVzb2x2ZSA9IG9uY2UoZnVuY3Rpb24gKHJlcykgewogICAgICAgIC8vIGNhY2hlIHJlc29sdmVkCiAgICAgICAgZmFjdG9yeS5yZXNvbHZlZCA9IGVuc3VyZUN0b3IocmVzLCBiYXNlQ3Rvcik7CiAgICAgICAgLy8gaW52b2tlIGNhbGxiYWNrcyBvbmx5IGlmIHRoaXMgaXMgbm90IGEgc3luY2hyb25vdXMgcmVzb2x2ZQogICAgICAgIC8vIChhc3luYyByZXNvbHZlcyBhcmUgc2hpbW1lZCBhcyBzeW5jaHJvbm91cyBkdXJpbmcgU1NSKQogICAgICAgIGlmICghc3luYykgewogICAgICAgICAgZm9yY2VSZW5kZXIodHJ1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG93bmVycy5sZW5ndGggPSAwOwogICAgICAgIH0KICAgICAgfSk7CgogICAgICB2YXIgcmVqZWN0ID0gb25jZShmdW5jdGlvbiAocmVhc29uKSB7CiAgICAgICAgd2FybigKICAgICAgICAgICJGYWlsZWQgdG8gcmVzb2x2ZSBhc3luYyBjb21wb25lbnQ6ICIgKyAoU3RyaW5nKGZhY3RvcnkpKSArCiAgICAgICAgICAocmVhc29uID8gKCJcblJlYXNvbjogIiArIHJlYXNvbikgOiAnJykKICAgICAgICApOwogICAgICAgIGlmIChpc0RlZihmYWN0b3J5LmVycm9yQ29tcCkpIHsKICAgICAgICAgIGZhY3RvcnkuZXJyb3IgPSB0cnVlOwogICAgICAgICAgZm9yY2VSZW5kZXIodHJ1ZSk7CiAgICAgICAgfQogICAgICB9KTsKCiAgICAgIHZhciByZXMgPSBmYWN0b3J5KHJlc29sdmUsIHJlamVjdCk7CgogICAgICBpZiAoaXNPYmplY3QocmVzKSkgewogICAgICAgIGlmIChpc1Byb21pc2UocmVzKSkgewogICAgICAgICAgLy8gKCkgPT4gUHJvbWlzZQogICAgICAgICAgaWYgKGlzVW5kZWYoZmFjdG9yeS5yZXNvbHZlZCkpIHsKICAgICAgICAgICAgcmVzLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGlzUHJvbWlzZShyZXMuY29tcG9uZW50KSkgewogICAgICAgICAgcmVzLmNvbXBvbmVudC50aGVuKHJlc29sdmUsIHJlamVjdCk7CgogICAgICAgICAgaWYgKGlzRGVmKHJlcy5lcnJvcikpIHsKICAgICAgICAgICAgZmFjdG9yeS5lcnJvckNvbXAgPSBlbnN1cmVDdG9yKHJlcy5lcnJvciwgYmFzZUN0b3IpOwogICAgICAgICAgfQoKICAgICAgICAgIGlmIChpc0RlZihyZXMubG9hZGluZykpIHsKICAgICAgICAgICAgZmFjdG9yeS5sb2FkaW5nQ29tcCA9IGVuc3VyZUN0b3IocmVzLmxvYWRpbmcsIGJhc2VDdG9yKTsKICAgICAgICAgICAgaWYgKHJlcy5kZWxheSA9PT0gMCkgewogICAgICAgICAgICAgIGZhY3RvcnkubG9hZGluZyA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgdGltZXJMb2FkaW5nID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aW1lckxvYWRpbmcgPSBudWxsOwogICAgICAgICAgICAgICAgaWYgKGlzVW5kZWYoZmFjdG9yeS5yZXNvbHZlZCkgJiYgaXNVbmRlZihmYWN0b3J5LmVycm9yKSkgewogICAgICAgICAgICAgICAgICBmYWN0b3J5LmxvYWRpbmcgPSB0cnVlOwogICAgICAgICAgICAgICAgICBmb3JjZVJlbmRlcihmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfSwgcmVzLmRlbGF5IHx8IDIwMCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBpZiAoaXNEZWYocmVzLnRpbWVvdXQpKSB7CiAgICAgICAgICAgIHRpbWVyVGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHRpbWVyVGltZW91dCA9IG51bGw7CiAgICAgICAgICAgICAgaWYgKGlzVW5kZWYoZmFjdG9yeS5yZXNvbHZlZCkpIHsKICAgICAgICAgICAgICAgIHJlamVjdCgKICAgICAgICAgICAgICAgICAgInRpbWVvdXQgKCIgKyAocmVzLnRpbWVvdXQpICsgIm1zKSIKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCByZXMudGltZW91dCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CgogICAgICBzeW5jID0gZmFsc2U7CiAgICAgIC8vIHJldHVybiBpbiBjYXNlIHJlc29sdmVkIHN5bmNocm9ub3VzbHkKICAgICAgcmV0dXJuIGZhY3RvcnkubG9hZGluZwogICAgICAgID8gZmFjdG9yeS5sb2FkaW5nQ29tcAogICAgICAgIDogZmFjdG9yeS5yZXNvbHZlZAogICAgfQogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIGlzQXN5bmNQbGFjZWhvbGRlciAobm9kZSkgewogICAgcmV0dXJuIG5vZGUuaXNDb21tZW50ICYmIG5vZGUuYXN5bmNGYWN0b3J5CiAgfQoKICAvKiAgKi8KCiAgZnVuY3Rpb24gZ2V0Rmlyc3RDb21wb25lbnRDaGlsZCAoY2hpbGRyZW4pIHsKICAgIGlmIChBcnJheS5pc0FycmF5KGNoaWxkcmVuKSkgewogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIGMgPSBjaGlsZHJlbltpXTsKICAgICAgICBpZiAoaXNEZWYoYykgJiYgKGlzRGVmKGMuY29tcG9uZW50T3B0aW9ucykgfHwgaXNBc3luY1BsYWNlaG9sZGVyKGMpKSkgewogICAgICAgICAgcmV0dXJuIGMKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIC8qICAqLwoKICAvKiAgKi8KCiAgZnVuY3Rpb24gaW5pdEV2ZW50cyAodm0pIHsKICAgIHZtLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpOwogICAgdm0uX2hhc0hvb2tFdmVudCA9IGZhbHNlOwogICAgLy8gaW5pdCBwYXJlbnQgYXR0YWNoZWQgZXZlbnRzCiAgICB2YXIgbGlzdGVuZXJzID0gdm0uJG9wdGlvbnMuX3BhcmVudExpc3RlbmVyczsKICAgIGlmIChsaXN0ZW5lcnMpIHsKICAgICAgdXBkYXRlQ29tcG9uZW50TGlzdGVuZXJzKHZtLCBsaXN0ZW5lcnMpOwogICAgfQogIH0KCiAgdmFyIHRhcmdldDsKCiAgZnVuY3Rpb24gYWRkIChldmVudCwgZm4pIHsKICAgIHRhcmdldC4kb24oZXZlbnQsIGZuKTsKICB9CgogIGZ1bmN0aW9uIHJlbW92ZSQxIChldmVudCwgZm4pIHsKICAgIHRhcmdldC4kb2ZmKGV2ZW50LCBmbik7CiAgfQoKICBmdW5jdGlvbiBjcmVhdGVPbmNlSGFuZGxlciAoZXZlbnQsIGZuKSB7CiAgICB2YXIgX3RhcmdldCA9IHRhcmdldDsKICAgIHJldHVybiBmdW5jdGlvbiBvbmNlSGFuZGxlciAoKSB7CiAgICAgIHZhciByZXMgPSBmbi5hcHBseShudWxsLCBhcmd1bWVudHMpOwogICAgICBpZiAocmVzICE9PSBudWxsKSB7CiAgICAgICAgX3RhcmdldC4kb2ZmKGV2ZW50LCBvbmNlSGFuZGxlcik7CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIHVwZGF0ZUNvbXBvbmVudExpc3RlbmVycyAoCiAgICB2bSwKICAgIGxpc3RlbmVycywKICAgIG9sZExpc3RlbmVycwogICkgewogICAgdGFyZ2V0ID0gdm07CiAgICB1cGRhdGVMaXN0ZW5lcnMobGlzdGVuZXJzLCBvbGRMaXN0ZW5lcnMgfHwge30sIGFkZCwgcmVtb3ZlJDEsIGNyZWF0ZU9uY2VIYW5kbGVyLCB2bSk7CiAgICB0YXJnZXQgPSB1bmRlZmluZWQ7CiAgfQoKICBmdW5jdGlvbiBldmVudHNNaXhpbiAoVnVlKSB7CiAgICB2YXIgaG9va1JFID0gL15ob29rOi87CiAgICBWdWUucHJvdG90eXBlLiRvbiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHsKICAgICAgdmFyIHZtID0gdGhpczsKICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZXZlbnQpKSB7CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBldmVudC5sZW5ndGg7IGkgPCBsOyBpKyspIHsKICAgICAgICAgIHZtLiRvbihldmVudFtpXSwgZm4pOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAodm0uX2V2ZW50c1tldmVudF0gfHwgKHZtLl9ldmVudHNbZXZlbnRdID0gW10pKS5wdXNoKGZuKTsKICAgICAgICAvLyBvcHRpbWl6ZSBob29rOmV2ZW50IGNvc3QgYnkgdXNpbmcgYSBib29sZWFuIGZsYWcgbWFya2VkIGF0IHJlZ2lzdHJhdGlvbgogICAgICAgIC8vIGluc3RlYWQgb2YgYSBoYXNoIGxvb2t1cAogICAgICAgIGlmIChob29rUkUudGVzdChldmVudCkpIHsKICAgICAgICAgIHZtLl9oYXNIb29rRXZlbnQgPSB0cnVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gdm0KICAgIH07CgogICAgVnVlLnByb3RvdHlwZS4kb25jZSA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHsKICAgICAgdmFyIHZtID0gdGhpczsKICAgICAgZnVuY3Rpb24gb24gKCkgewogICAgICAgIHZtLiRvZmYoZXZlbnQsIG9uKTsKICAgICAgICBmbi5hcHBseSh2bSwgYXJndW1lbnRzKTsKICAgICAgfQogICAgICBvbi5mbiA9IGZuOwogICAgICB2bS4kb24oZXZlbnQsIG9uKTsKICAgICAgcmV0dXJuIHZtCiAgICB9OwoKICAgIFZ1ZS5wcm90b3R5cGUuJG9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHsKICAgICAgdmFyIHZtID0gdGhpczsKICAgICAgLy8gYWxsCiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgewogICAgICAgIHZtLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpOwogICAgICAgIHJldHVybiB2bQogICAgICB9CiAgICAgIC8vIGFycmF5IG9mIGV2ZW50cwogICAgICBpZiAoQXJyYXkuaXNBcnJheShldmVudCkpIHsKICAgICAgICBmb3IgKHZhciBpJDEgPSAwLCBsID0gZXZlbnQubGVuZ3RoOyBpJDEgPCBsOyBpJDErKykgewogICAgICAgICAgdm0uJG9mZihldmVudFtpJDFdLCBmbik7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2bQogICAgICB9CiAgICAgIC8vIHNwZWNpZmljIGV2ZW50CiAgICAgIHZhciBjYnMgPSB2bS5fZXZlbnRzW2V2ZW50XTsKICAgICAgaWYgKCFjYnMpIHsKICAgICAgICByZXR1cm4gdm0KICAgICAgfQogICAgICBpZiAoIWZuKSB7CiAgICAgICAgdm0uX2V2ZW50c1tldmVudF0gPSBudWxsOwogICAgICAgIHJldHVybiB2bQogICAgICB9CiAgICAgIC8vIHNwZWNpZmljIGhhbmRsZXIKICAgICAgdmFyIGNiOwogICAgICB2YXIgaSA9IGNicy5sZW5ndGg7CiAgICAgIHdoaWxlIChpLS0pIHsKICAgICAgICBjYiA9IGNic1tpXTsKICAgICAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikgewogICAgICAgICAgY2JzLnNwbGljZShpLCAxKTsKICAgICAgICAgIGJyZWFrCiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB2bQogICAgfTsKCiAgICBWdWUucHJvdG90eXBlLiRlbWl0ID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgIHZhciB2bSA9IHRoaXM7CiAgICAgIHsKICAgICAgICB2YXIgbG93ZXJDYXNlRXZlbnQgPSBldmVudC50b0xvd2VyQ2FzZSgpOwogICAgICAgIGlmIChsb3dlckNhc2VFdmVudCAhPT0gZXZlbnQgJiYgdm0uX2V2ZW50c1tsb3dlckNhc2VFdmVudF0pIHsKICAgICAgICAgIHRpcCgKICAgICAgICAgICAgIkV2ZW50IFwiIiArIGxvd2VyQ2FzZUV2ZW50ICsgIlwiIGlzIGVtaXR0ZWQgaW4gY29tcG9uZW50ICIgKwogICAgICAgICAgICAoZm9ybWF0Q29tcG9uZW50TmFtZSh2bSkpICsgIiBidXQgdGhlIGhhbmRsZXIgaXMgcmVnaXN0ZXJlZCBmb3IgXCIiICsgZXZlbnQgKyAiXCIuICIgKwogICAgICAgICAgICAiTm90ZSB0aGF0IEhUTUwgYXR0cmlidXRlcyBhcmUgY2FzZS1pbnNlbnNpdGl2ZSBhbmQgeW91IGNhbm5vdCB1c2UgIiArCiAgICAgICAgICAgICJ2LW9uIHRvIGxpc3RlbiB0byBjYW1lbENhc2UgZXZlbnRzIHdoZW4gdXNpbmcgaW4tRE9NIHRlbXBsYXRlcy4gIiArCiAgICAgICAgICAgICJZb3Ugc2hvdWxkIHByb2JhYmx5IHVzZSBcIiIgKyAoaHlwaGVuYXRlKGV2ZW50KSkgKyAiXCIgaW5zdGVhZCBvZiBcIiIgKyBldmVudCArICJcIi4iCiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgfQogICAgICB2YXIgY2JzID0gdm0uX2V2ZW50c1tldmVudF07CiAgICAgIGlmIChjYnMpIHsKICAgICAgICBjYnMgPSBjYnMubGVuZ3RoID4gMSA/IHRvQXJyYXkoY2JzKSA6IGNiczsKICAgICAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzLCAxKTsKICAgICAgICB2YXIgaW5mbyA9ICJldmVudCBoYW5kbGVyIGZvciBcIiIgKyBldmVudCArICJcIiI7CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjYnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7CiAgICAgICAgICBpbnZva2VXaXRoRXJyb3JIYW5kbGluZyhjYnNbaV0sIHZtLCBhcmdzLCB2bSwgaW5mbyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB2bQogICAgfTsKICB9CgogIC8qICAqLwoKICB2YXIgYWN0aXZlSW5zdGFuY2UgPSBudWxsOwogIHZhciBpc1VwZGF0aW5nQ2hpbGRDb21wb25lbnQgPSBmYWxzZTsKCiAgZnVuY3Rpb24gc2V0QWN0aXZlSW5zdGFuY2Uodm0pIHsKICAgIHZhciBwcmV2QWN0aXZlSW5zdGFuY2UgPSBhY3RpdmVJbnN0YW5jZTsKICAgIGFjdGl2ZUluc3RhbmNlID0gdm07CiAgICByZXR1cm4gZnVuY3Rpb24gKCkgewogICAgICBhY3RpdmVJbnN0YW5jZSA9IHByZXZBY3RpdmVJbnN0YW5jZTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIGluaXRMaWZlY3ljbGUgKHZtKSB7CiAgICB2YXIgb3B0aW9ucyA9IHZtLiRvcHRpb25zOwoKICAgIC8vIGxvY2F0ZSBmaXJzdCBub24tYWJzdHJhY3QgcGFyZW50CiAgICB2YXIgcGFyZW50ID0gb3B0aW9ucy5wYXJlbnQ7CiAgICBpZiAocGFyZW50ICYmICFvcHRpb25zLmFic3RyYWN0KSB7CiAgICAgIHdoaWxlIChwYXJlbnQuJG9wdGlvbnMuYWJzdHJhY3QgJiYgcGFyZW50LiRwYXJlbnQpIHsKICAgICAgICBwYXJlbnQgPSBwYXJlbnQuJHBhcmVudDsKICAgICAgfQogICAgICBwYXJlbnQuJGNoaWxkcmVuLnB1c2godm0pOwogICAgfQoKICAgIHZtLiRwYXJlbnQgPSBwYXJlbnQ7CiAgICB2bS4kcm9vdCA9IHBhcmVudCA/IHBhcmVudC4kcm9vdCA6IHZtOwoKICAgIHZtLiRjaGlsZHJlbiA9IFtdOwogICAgdm0uJHJlZnMgPSB7fTsKCiAgICB2bS5fd2F0Y2hlciA9IG51bGw7CiAgICB2bS5faW5hY3RpdmUgPSBudWxsOwogICAgdm0uX2RpcmVjdEluYWN0aXZlID0gZmFsc2U7CiAgICB2bS5faXNNb3VudGVkID0gZmFsc2U7CiAgICB2bS5faXNEZXN0cm95ZWQgPSBmYWxzZTsKICAgIHZtLl9pc0JlaW5nRGVzdHJveWVkID0gZmFsc2U7CiAgfQoKICBmdW5jdGlvbiBsaWZlY3ljbGVNaXhpbiAoVnVlKSB7CiAgICBWdWUucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAodm5vZGUsIGh5ZHJhdGluZykgewogICAgICB2YXIgdm0gPSB0aGlzOwogICAgICB2YXIgcHJldkVsID0gdm0uJGVsOwogICAgICB2YXIgcHJldlZub2RlID0gdm0uX3Zub2RlOwogICAgICB2YXIgcmVzdG9yZUFjdGl2ZUluc3RhbmNlID0gc2V0QWN0aXZlSW5zdGFuY2Uodm0pOwogICAgICB2bS5fdm5vZGUgPSB2bm9kZTsKICAgICAgLy8gVnVlLnByb3RvdHlwZS5fX3BhdGNoX18gaXMgaW5qZWN0ZWQgaW4gZW50cnkgcG9pbnRzCiAgICAgIC8vIGJhc2VkIG9uIHRoZSByZW5kZXJpbmcgYmFja2VuZCB1c2VkLgogICAgICBpZiAoIXByZXZWbm9kZSkgewogICAgICAgIC8vIGluaXRpYWwgcmVuZGVyCiAgICAgICAgdm0uJGVsID0gdm0uX19wYXRjaF9fKHZtLiRlbCwgdm5vZGUsIGh5ZHJhdGluZywgZmFsc2UgLyogcmVtb3ZlT25seSAqLyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gdXBkYXRlcwogICAgICAgIHZtLiRlbCA9IHZtLl9fcGF0Y2hfXyhwcmV2Vm5vZGUsIHZub2RlKTsKICAgICAgfQogICAgICByZXN0b3JlQWN0aXZlSW5zdGFuY2UoKTsKICAgICAgLy8gdXBkYXRlIF9fdnVlX18gcmVmZXJlbmNlCiAgICAgIGlmIChwcmV2RWwpIHsKICAgICAgICBwcmV2RWwuX192dWVfXyA9IG51bGw7CiAgICAgIH0KICAgICAgaWYgKHZtLiRlbCkgewogICAgICAgIHZtLiRlbC5fX3Z1ZV9fID0gdm07CiAgICAgIH0KICAgICAgLy8gaWYgcGFyZW50IGlzIGFuIEhPQywgdXBkYXRlIGl0cyAkZWwgYXMgd2VsbAogICAgICBpZiAodm0uJHZub2RlICYmIHZtLiRwYXJlbnQgJiYgdm0uJHZub2RlID09PSB2bS4kcGFyZW50Ll92bm9kZSkgewogICAgICAgIHZtLiRwYXJlbnQuJGVsID0gdm0uJGVsOwogICAgICB9CiAgICAgIC8vIHVwZGF0ZWQgaG9vayBpcyBjYWxsZWQgYnkgdGhlIHNjaGVkdWxlciB0byBlbnN1cmUgdGhhdCBjaGlsZHJlbiBhcmUKICAgICAgLy8gdXBkYXRlZCBpbiBhIHBhcmVudCdzIHVwZGF0ZWQgaG9vay4KICAgIH07CgogICAgVnVlLnByb3RvdHlwZS4kZm9yY2VVcGRhdGUgPSBmdW5jdGlvbiAoKSB7CiAgICAgIHZhciB2bSA9IHRoaXM7CiAgICAgIGlmICh2bS5fd2F0Y2hlcikgewogICAgICAgIHZtLl93YXRjaGVyLnVwZGF0ZSgpOwogICAgICB9CiAgICB9OwoKICAgIFZ1ZS5wcm90b3R5cGUuJGRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7CiAgICAgIHZhciB2bSA9IHRoaXM7CiAgICAgIGlmICh2bS5faXNCZWluZ0Rlc3Ryb3llZCkgewogICAgICAgIHJldHVybgogICAgICB9CiAgICAgIGNhbGxIb29rKHZtLCAnYmVmb3JlRGVzdHJveScpOwogICAgICB2bS5faXNCZWluZ0Rlc3Ryb3llZCA9IHRydWU7CiAgICAgIC8vIHJlbW92ZSBzZWxmIGZyb20gcGFyZW50CiAgICAgIHZhciBwYXJlbnQgPSB2bS4kcGFyZW50OwogICAgICBpZiAocGFyZW50ICYmICFwYXJlbnQuX2lzQmVpbmdEZXN0cm95ZWQgJiYgIXZtLiRvcHRpb25zLmFic3RyYWN0KSB7CiAgICAgICAgcmVtb3ZlKHBhcmVudC4kY2hpbGRyZW4sIHZtKTsKICAgICAgfQogICAgICAvLyB0ZWFyZG93biB3YXRjaGVycwogICAgICBpZiAodm0uX3dhdGNoZXIpIHsKICAgICAgICB2bS5fd2F0Y2hlci50ZWFyZG93bigpOwogICAgICB9CiAgICAgIHZhciBpID0gdm0uX3dhdGNoZXJzLmxlbmd0aDsKICAgICAgd2hpbGUgKGktLSkgewogICAgICAgIHZtLl93YXRjaGVyc1tpXS50ZWFyZG93bigpOwogICAgICB9CiAgICAgIC8vIHJlbW92ZSByZWZlcmVuY2UgZnJvbSBkYXRhIG9iCiAgICAgIC8vIGZyb3plbiBvYmplY3QgbWF5IG5vdCBoYXZlIG9ic2VydmVyLgogICAgICBpZiAodm0uX2RhdGEuX19vYl9fKSB7CiAgICAgICAgdm0uX2RhdGEuX19vYl9fLnZtQ291bnQtLTsKICAgICAgfQogICAgICAvLyBjYWxsIHRoZSBsYXN0IGhvb2suLi4KICAgICAgdm0uX2lzRGVzdHJveWVkID0gdHJ1ZTsKICAgICAgLy8gaW52b2tlIGRlc3Ryb3kgaG9va3Mgb24gY3VycmVudCByZW5kZXJlZCB0cmVlCiAgICAgIHZtLl9fcGF0Y2hfXyh2bS5fdm5vZGUsIG51bGwpOwogICAgICAvLyBmaXJlIGRlc3Ryb3llZCBob29rCiAgICAgIGNhbGxIb29rKHZtLCAnZGVzdHJveWVkJyk7CiAgICAgIC8vIHR1cm4gb2ZmIGFsbCBpbnN0YW5jZSBsaXN0ZW5lcnMuCiAgICAgIHZtLiRvZmYoKTsKICAgICAgLy8gcmVtb3ZlIF9fdnVlX18gcmVmZXJlbmNlCiAgICAgIGlmICh2bS4kZWwpIHsKICAgICAgICB2bS4kZWwuX192dWVfXyA9IG51bGw7CiAgICAgIH0KICAgICAgLy8gcmVsZWFzZSBjaXJjdWxhciByZWZlcmVuY2UgKCM2NzU5KQogICAgICBpZiAodm0uJHZub2RlKSB7CiAgICAgICAgdm0uJHZub2RlLnBhcmVudCA9IG51bGw7CiAgICAgIH0KICAgIH07CiAgfQoKICBmdW5jdGlvbiBtb3VudENvbXBvbmVudCAoCiAgICB2bSwKICAgIGVsLAogICAgaHlkcmF0aW5nCiAgKSB7CiAgICB2bS4kZWwgPSBlbDsKICAgIGlmICghdm0uJG9wdGlvbnMucmVuZGVyKSB7CiAgICAgIHZtLiRvcHRpb25zLnJlbmRlciA9IGNyZWF0ZUVtcHR5Vk5vZGU7CiAgICAgIHsKICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgICAgICBpZiAoKHZtLiRvcHRpb25zLnRlbXBsYXRlICYmIHZtLiRvcHRpb25zLnRlbXBsYXRlLmNoYXJBdCgwKSAhPT0gJyMnKSB8fAogICAgICAgICAgdm0uJG9wdGlvbnMuZWwgfHwgZWwpIHsKICAgICAgICAgIHdhcm4oCiAgICAgICAgICAgICdZb3UgYXJlIHVzaW5nIHRoZSBydW50aW1lLW9ubHkgYnVpbGQgb2YgVnVlIHdoZXJlIHRoZSB0ZW1wbGF0ZSAnICsKICAgICAgICAgICAgJ2NvbXBpbGVyIGlzIG5vdCBhdmFpbGFibGUuIEVpdGhlciBwcmUtY29tcGlsZSB0aGUgdGVtcGxhdGVzIGludG8gJyArCiAgICAgICAgICAgICdyZW5kZXIgZnVuY3Rpb25zLCBvciB1c2UgdGhlIGNvbXBpbGVyLWluY2x1ZGVkIGJ1aWxkLicsCiAgICAgICAgICAgIHZtCiAgICAgICAgICApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB3YXJuKAogICAgICAgICAgICAnRmFpbGVkIHRvIG1vdW50IGNvbXBvbmVudDogdGVtcGxhdGUgb3IgcmVuZGVyIGZ1bmN0aW9uIG5vdCBkZWZpbmVkLicsCiAgICAgICAgICAgIHZtCiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgY2FsbEhvb2sodm0sICdiZWZvcmVNb3VudCcpOwoKICAgIHZhciB1cGRhdGVDb21wb25lbnQ7CiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgIGlmIChjb25maWcucGVyZm9ybWFuY2UgJiYgbWFyaykgewogICAgICB1cGRhdGVDb21wb25lbnQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIG5hbWUgPSB2bS5fbmFtZTsKICAgICAgICB2YXIgaWQgPSB2bS5fdWlkOwogICAgICAgIHZhciBzdGFydFRhZyA9ICJ2dWUtcGVyZi1zdGFydDoiICsgaWQ7CiAgICAgICAgdmFyIGVuZFRhZyA9ICJ2dWUtcGVyZi1lbmQ6IiArIGlkOwoKICAgICAgICBtYXJrKHN0YXJ0VGFnKTsKICAgICAgICB2YXIgdm5vZGUgPSB2bS5fcmVuZGVyKCk7CiAgICAgICAgbWFyayhlbmRUYWcpOwogICAgICAgIG1lYXN1cmUoKCJ2dWUgIiArIG5hbWUgKyAiIHJlbmRlciIpLCBzdGFydFRhZywgZW5kVGFnKTsKCiAgICAgICAgbWFyayhzdGFydFRhZyk7CiAgICAgICAgdm0uX3VwZGF0ZSh2bm9kZSwgaHlkcmF0aW5nKTsKICAgICAgICBtYXJrKGVuZFRhZyk7CiAgICAgICAgbWVhc3VyZSgoInZ1ZSAiICsgbmFtZSArICIgcGF0Y2giKSwgc3RhcnRUYWcsIGVuZFRhZyk7CiAgICAgIH07CiAgICB9IGVsc2UgewogICAgICB1cGRhdGVDb21wb25lbnQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdm0uX3VwZGF0ZSh2bS5fcmVuZGVyKCksIGh5ZHJhdGluZyk7CiAgICAgIH07CiAgICB9CgogICAgLy8gd2Ugc2V0IHRoaXMgdG8gdm0uX3dhdGNoZXIgaW5zaWRlIHRoZSB3YXRjaGVyJ3MgY29uc3RydWN0b3IKICAgIC8vIHNpbmNlIHRoZSB3YXRjaGVyJ3MgaW5pdGlhbCBwYXRjaCBtYXkgY2FsbCAkZm9yY2VVcGRhdGUgKGUuZy4gaW5zaWRlIGNoaWxkCiAgICAvLyBjb21wb25lbnQncyBtb3VudGVkIGhvb2spLCB3aGljaCByZWxpZXMgb24gdm0uX3dhdGNoZXIgYmVpbmcgYWxyZWFkeSBkZWZpbmVkCiAgICBuZXcgV2F0Y2hlcih2bSwgdXBkYXRlQ29tcG9uZW50LCBub29wLCB7CiAgICAgIGJlZm9yZTogZnVuY3Rpb24gYmVmb3JlICgpIHsKICAgICAgICBpZiAodm0uX2lzTW91bnRlZCAmJiAhdm0uX2lzRGVzdHJveWVkKSB7CiAgICAgICAgICBjYWxsSG9vayh2bSwgJ2JlZm9yZVVwZGF0ZScpOwogICAgICAgIH0KICAgICAgfQogICAgfSwgdHJ1ZSAvKiBpc1JlbmRlcldhdGNoZXIgKi8pOwogICAgaHlkcmF0aW5nID0gZmFsc2U7CgogICAgLy8gbWFudWFsbHkgbW91bnRlZCBpbnN0YW5jZSwgY2FsbCBtb3VudGVkIG9uIHNlbGYKICAgIC8vIG1vdW50ZWQgaXMgY2FsbGVkIGZvciByZW5kZXItY3JlYXRlZCBjaGlsZCBjb21wb25lbnRzIGluIGl0cyBpbnNlcnRlZCBob29rCiAgICBpZiAodm0uJHZub2RlID09IG51bGwpIHsKICAgICAgdm0uX2lzTW91bnRlZCA9IHRydWU7CiAgICAgIGNhbGxIb29rKHZtLCAnbW91bnRlZCcpOwogICAgfQogICAgcmV0dXJuIHZtCiAgfQoKICBmdW5jdGlvbiB1cGRhdGVDaGlsZENvbXBvbmVudCAoCiAgICB2bSwKICAgIHByb3BzRGF0YSwKICAgIGxpc3RlbmVycywKICAgIHBhcmVudFZub2RlLAogICAgcmVuZGVyQ2hpbGRyZW4KICApIHsKICAgIHsKICAgICAgaXNVcGRhdGluZ0NoaWxkQ29tcG9uZW50ID0gdHJ1ZTsKICAgIH0KCiAgICAvLyBkZXRlcm1pbmUgd2hldGhlciBjb21wb25lbnQgaGFzIHNsb3QgY2hpbGRyZW4KICAgIC8vIHdlIG5lZWQgdG8gZG8gdGhpcyBiZWZvcmUgb3ZlcndyaXRpbmcgJG9wdGlvbnMuX3JlbmRlckNoaWxkcmVuLgoKICAgIC8vIGNoZWNrIGlmIHRoZXJlIGFyZSBkeW5hbWljIHNjb3BlZFNsb3RzIChoYW5kLXdyaXR0ZW4gb3IgY29tcGlsZWQgYnV0IHdpdGgKICAgIC8vIGR5bmFtaWMgc2xvdCBuYW1lcykuIFN0YXRpYyBzY29wZWQgc2xvdHMgY29tcGlsZWQgZnJvbSB0ZW1wbGF0ZSBoYXMgdGhlCiAgICAvLyAiJHN0YWJsZSIgbWFya2VyLgogICAgdmFyIG5ld1Njb3BlZFNsb3RzID0gcGFyZW50Vm5vZGUuZGF0YS5zY29wZWRTbG90czsKICAgIHZhciBvbGRTY29wZWRTbG90cyA9IHZtLiRzY29wZWRTbG90czsKICAgIHZhciBoYXNEeW5hbWljU2NvcGVkU2xvdCA9ICEhKAogICAgICAobmV3U2NvcGVkU2xvdHMgJiYgIW5ld1Njb3BlZFNsb3RzLiRzdGFibGUpIHx8CiAgICAgIChvbGRTY29wZWRTbG90cyAhPT0gZW1wdHlPYmplY3QgJiYgIW9sZFNjb3BlZFNsb3RzLiRzdGFibGUpIHx8CiAgICAgIChuZXdTY29wZWRTbG90cyAmJiB2bS4kc2NvcGVkU2xvdHMuJGtleSAhPT0gbmV3U2NvcGVkU2xvdHMuJGtleSkKICAgICk7CgogICAgLy8gQW55IHN0YXRpYyBzbG90IGNoaWxkcmVuIGZyb20gdGhlIHBhcmVudCBtYXkgaGF2ZSBjaGFuZ2VkIGR1cmluZyBwYXJlbnQncwogICAgLy8gdXBkYXRlLiBEeW5hbWljIHNjb3BlZCBzbG90cyBtYXkgYWxzbyBoYXZlIGNoYW5nZWQuIEluIHN1Y2ggY2FzZXMsIGEgZm9yY2VkCiAgICAvLyB1cGRhdGUgaXMgbmVjZXNzYXJ5IHRvIGVuc3VyZSBjb3JyZWN0bmVzcy4KICAgIHZhciBuZWVkc0ZvcmNlVXBkYXRlID0gISEoCiAgICAgIHJlbmRlckNoaWxkcmVuIHx8ICAgICAgICAgICAgICAgLy8gaGFzIG5ldyBzdGF0aWMgc2xvdHMKICAgICAgdm0uJG9wdGlvbnMuX3JlbmRlckNoaWxkcmVuIHx8ICAvLyBoYXMgb2xkIHN0YXRpYyBzbG90cwogICAgICBoYXNEeW5hbWljU2NvcGVkU2xvdAogICAgKTsKCiAgICB2bS4kb3B0aW9ucy5fcGFyZW50Vm5vZGUgPSBwYXJlbnRWbm9kZTsKICAgIHZtLiR2bm9kZSA9IHBhcmVudFZub2RlOyAvLyB1cGRhdGUgdm0ncyBwbGFjZWhvbGRlciBub2RlIHdpdGhvdXQgcmUtcmVuZGVyCgogICAgaWYgKHZtLl92bm9kZSkgeyAvLyB1cGRhdGUgY2hpbGQgdHJlZSdzIHBhcmVudAogICAgICB2bS5fdm5vZGUucGFyZW50ID0gcGFyZW50Vm5vZGU7CiAgICB9CiAgICB2bS4kb3B0aW9ucy5fcmVuZGVyQ2hpbGRyZW4gPSByZW5kZXJDaGlsZHJlbjsKCiAgICAvLyB1cGRhdGUgJGF0dHJzIGFuZCAkbGlzdGVuZXJzIGhhc2gKICAgIC8vIHRoZXNlIGFyZSBhbHNvIHJlYWN0aXZlIHNvIHRoZXkgbWF5IHRyaWdnZXIgY2hpbGQgdXBkYXRlIGlmIHRoZSBjaGlsZAogICAgLy8gdXNlZCB0aGVtIGR1cmluZyByZW5kZXIKICAgIHZtLiRhdHRycyA9IHBhcmVudFZub2RlLmRhdGEuYXR0cnMgfHwgZW1wdHlPYmplY3Q7CiAgICB2bS4kbGlzdGVuZXJzID0gbGlzdGVuZXJzIHx8IGVtcHR5T2JqZWN0OwoKICAgIC8vIHVwZGF0ZSBwcm9wcwogICAgaWYgKHByb3BzRGF0YSAmJiB2bS4kb3B0aW9ucy5wcm9wcykgewogICAgICB0b2dnbGVPYnNlcnZpbmcoZmFsc2UpOwogICAgICB2YXIgcHJvcHMgPSB2bS5fcHJvcHM7CiAgICAgIHZhciBwcm9wS2V5cyA9IHZtLiRvcHRpb25zLl9wcm9wS2V5cyB8fCBbXTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wS2V5cy5sZW5ndGg7IGkrKykgewogICAgICAgIHZhciBrZXkgPSBwcm9wS2V5c1tpXTsKICAgICAgICB2YXIgcHJvcE9wdGlvbnMgPSB2bS4kb3B0aW9ucy5wcm9wczsgLy8gd3RmIGZsb3c/CiAgICAgICAgcHJvcHNba2V5XSA9IHZhbGlkYXRlUHJvcChrZXksIHByb3BPcHRpb25zLCBwcm9wc0RhdGEsIHZtKTsKICAgICAgfQogICAgICB0b2dnbGVPYnNlcnZpbmcodHJ1ZSk7CiAgICAgIC8vIGtlZXAgYSBjb3B5IG9mIHJhdyBwcm9wc0RhdGEKICAgICAgdm0uJG9wdGlvbnMucHJvcHNEYXRhID0gcHJvcHNEYXRhOwogICAgfQoKICAgIC8vIHVwZGF0ZSBsaXN0ZW5lcnMKICAgIGxpc3RlbmVycyA9IGxpc3RlbmVycyB8fCBlbXB0eU9iamVjdDsKICAgIHZhciBvbGRMaXN0ZW5lcnMgPSB2bS4kb3B0aW9ucy5fcGFyZW50TGlzdGVuZXJzOwogICAgdm0uJG9wdGlvbnMuX3BhcmVudExpc3RlbmVycyA9IGxpc3RlbmVyczsKICAgIHVwZGF0ZUNvbXBvbmVudExpc3RlbmVycyh2bSwgbGlzdGVuZXJzLCBvbGRMaXN0ZW5lcnMpOwoKICAgIC8vIHJlc29sdmUgc2xvdHMgKyBmb3JjZSB1cGRhdGUgaWYgaGFzIGNoaWxkcmVuCiAgICBpZiAobmVlZHNGb3JjZVVwZGF0ZSkgewogICAgICB2bS4kc2xvdHMgPSByZXNvbHZlU2xvdHMocmVuZGVyQ2hpbGRyZW4sIHBhcmVudFZub2RlLmNvbnRleHQpOwogICAgICB2bS4kZm9yY2VVcGRhdGUoKTsKICAgIH0KCiAgICB7CiAgICAgIGlzVXBkYXRpbmdDaGlsZENvbXBvbmVudCA9IGZhbHNlOwogICAgfQogIH0KCiAgZnVuY3Rpb24gaXNJbkluYWN0aXZlVHJlZSAodm0pIHsKICAgIHdoaWxlICh2bSAmJiAodm0gPSB2bS4kcGFyZW50KSkgewogICAgICBpZiAodm0uX2luYWN0aXZlKSB7IHJldHVybiB0cnVlIH0KICAgIH0KICAgIHJldHVybiBmYWxzZQogIH0KCiAgZnVuY3Rpb24gYWN0aXZhdGVDaGlsZENvbXBvbmVudCAodm0sIGRpcmVjdCkgewogICAgaWYgKGRpcmVjdCkgewogICAgICB2bS5fZGlyZWN0SW5hY3RpdmUgPSBmYWxzZTsKICAgICAgaWYgKGlzSW5JbmFjdGl2ZVRyZWUodm0pKSB7CiAgICAgICAgcmV0dXJuCiAgICAgIH0KICAgIH0gZWxzZSBpZiAodm0uX2RpcmVjdEluYWN0aXZlKSB7CiAgICAgIHJldHVybgogICAgfQogICAgaWYgKHZtLl9pbmFjdGl2ZSB8fCB2bS5faW5hY3RpdmUgPT09IG51bGwpIHsKICAgICAgdm0uX2luYWN0aXZlID0gZmFsc2U7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdm0uJGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgYWN0aXZhdGVDaGlsZENvbXBvbmVudCh2bS4kY2hpbGRyZW5baV0pOwogICAgICB9CiAgICAgIGNhbGxIb29rKHZtLCAnYWN0aXZhdGVkJyk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBkZWFjdGl2YXRlQ2hpbGRDb21wb25lbnQgKHZtLCBkaXJlY3QpIHsKICAgIGlmIChkaXJlY3QpIHsKICAgICAgdm0uX2RpcmVjdEluYWN0aXZlID0gdHJ1ZTsKICAgICAgaWYgKGlzSW5JbmFjdGl2ZVRyZWUodm0pKSB7CiAgICAgICAgcmV0dXJuCiAgICAgIH0KICAgIH0KICAgIGlmICghdm0uX2luYWN0aXZlKSB7CiAgICAgIHZtLl9pbmFjdGl2ZSA9IHRydWU7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdm0uJGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgZGVhY3RpdmF0ZUNoaWxkQ29tcG9uZW50KHZtLiRjaGlsZHJlbltpXSk7CiAgICAgIH0KICAgICAgY2FsbEhvb2sodm0sICdkZWFjdGl2YXRlZCcpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gY2FsbEhvb2sgKHZtLCBob29rKSB7CiAgICAvLyAjNzU3MyBkaXNhYmxlIGRlcCBjb2xsZWN0aW9uIHdoZW4gaW52b2tpbmcgbGlmZWN5Y2xlIGhvb2tzCiAgICBwdXNoVGFyZ2V0KCk7CiAgICB2YXIgaGFuZGxlcnMgPSB2bS4kb3B0aW9uc1tob29rXTsKICAgIHZhciBpbmZvID0gaG9vayArICIgaG9vayI7CiAgICBpZiAoaGFuZGxlcnMpIHsKICAgICAgZm9yICh2YXIgaSA9IDAsIGogPSBoYW5kbGVycy5sZW5ndGg7IGkgPCBqOyBpKyspIHsKICAgICAgICBpbnZva2VXaXRoRXJyb3JIYW5kbGluZyhoYW5kbGVyc1tpXSwgdm0sIG51bGwsIHZtLCBpbmZvKTsKICAgICAgfQogICAgfQogICAgaWYgKHZtLl9oYXNIb29rRXZlbnQpIHsKICAgICAgdm0uJGVtaXQoJ2hvb2s6JyArIGhvb2spOwogICAgfQogICAgcG9wVGFyZ2V0KCk7CiAgfQoKICAvKiAgKi8KCiAgdmFyIE1BWF9VUERBVEVfQ09VTlQgPSAxMDA7CgogIHZhciBxdWV1ZSA9IFtdOwogIHZhciBhY3RpdmF0ZWRDaGlsZHJlbiA9IFtdOwogIHZhciBoYXMgPSB7fTsKICB2YXIgY2lyY3VsYXIgPSB7fTsKICB2YXIgd2FpdGluZyA9IGZhbHNlOwogIHZhciBmbHVzaGluZyA9IGZhbHNlOwogIHZhciBpbmRleCA9IDA7CgogIC8qKgogICAqIFJlc2V0IHRoZSBzY2hlZHVsZXIncyBzdGF0ZS4KICAgKi8KICBmdW5jdGlvbiByZXNldFNjaGVkdWxlclN0YXRlICgpIHsKICAgIGluZGV4ID0gcXVldWUubGVuZ3RoID0gYWN0aXZhdGVkQ2hpbGRyZW4ubGVuZ3RoID0gMDsKICAgIGhhcyA9IHt9OwogICAgewogICAgICBjaXJjdWxhciA9IHt9OwogICAgfQogICAgd2FpdGluZyA9IGZsdXNoaW5nID0gZmFsc2U7CiAgfQoKICAvLyBBc3luYyBlZGdlIGNhc2UgIzY1NjYgcmVxdWlyZXMgc2F2aW5nIHRoZSB0aW1lc3RhbXAgd2hlbiBldmVudCBsaXN0ZW5lcnMgYXJlCiAgLy8gYXR0YWNoZWQuIEhvd2V2ZXIsIGNhbGxpbmcgcGVyZm9ybWFuY2Uubm93KCkgaGFzIGEgcGVyZiBvdmVyaGVhZCBlc3BlY2lhbGx5CiAgLy8gaWYgdGhlIHBhZ2UgaGFzIHRob3VzYW5kcyBvZiBldmVudCBsaXN0ZW5lcnMuIEluc3RlYWQsIHdlIHRha2UgYSB0aW1lc3RhbXAKICAvLyBldmVyeSB0aW1lIHRoZSBzY2hlZHVsZXIgZmx1c2hlcyBhbmQgdXNlIHRoYXQgZm9yIGFsbCBldmVudCBsaXN0ZW5lcnMKICAvLyBhdHRhY2hlZCBkdXJpbmcgdGhhdCBmbHVzaC4KICB2YXIgY3VycmVudEZsdXNoVGltZXN0YW1wID0gMDsKCiAgLy8gQXN5bmMgZWRnZSBjYXNlIGZpeCByZXF1aXJlcyBzdG9yaW5nIGFuIGV2ZW50IGxpc3RlbmVyJ3MgYXR0YWNoIHRpbWVzdGFtcC4KICB2YXIgZ2V0Tm93ID0gRGF0ZS5ub3c7CgogIC8vIERldGVybWluZSB3aGF0IGV2ZW50IHRpbWVzdGFtcCB0aGUgYnJvd3NlciBpcyB1c2luZy4gQW5ub3lpbmdseSwgdGhlCiAgLy8gdGltZXN0YW1wIGNhbiBlaXRoZXIgYmUgaGktcmVzIChyZWxhdGl2ZSB0byBwYWdlIGxvYWQpIG9yIGxvdy1yZXMKICAvLyAocmVsYXRpdmUgdG8gVU5JWCBlcG9jaCksIHNvIGluIG9yZGVyIHRvIGNvbXBhcmUgdGltZSB3ZSBoYXZlIHRvIHVzZSB0aGUKICAvLyBzYW1lIHRpbWVzdGFtcCB0eXBlIHdoZW4gc2F2aW5nIHRoZSBmbHVzaCB0aW1lc3RhbXAuCiAgLy8gQWxsIElFIHZlcnNpb25zIHVzZSBsb3ctcmVzIGV2ZW50IHRpbWVzdGFtcHMsIGFuZCBoYXZlIHByb2JsZW1hdGljIGNsb2NrCiAgLy8gaW1wbGVtZW50YXRpb25zICgjOTYzMikKICBpZiAoaW5Ccm93c2VyICYmICFpc0lFKSB7CiAgICB2YXIgcGVyZm9ybWFuY2UgPSB3aW5kb3cucGVyZm9ybWFuY2U7CiAgICBpZiAoCiAgICAgIHBlcmZvcm1hbmNlICYmCiAgICAgIHR5cGVvZiBwZXJmb3JtYW5jZS5ub3cgPT09ICdmdW5jdGlvbicgJiYKICAgICAgZ2V0Tm93KCkgPiBkb2N1bWVudC5jcmVhdGVFdmVudCgnRXZlbnQnKS50aW1lU3RhbXAKICAgICkgewogICAgICAvLyBpZiB0aGUgZXZlbnQgdGltZXN0YW1wLCBhbHRob3VnaCBldmFsdWF0ZWQgQUZURVIgdGhlIERhdGUubm93KCksIGlzCiAgICAgIC8vIHNtYWxsZXIgdGhhbiBpdCwgaXQgbWVhbnMgdGhlIGV2ZW50IGlzIHVzaW5nIGEgaGktcmVzIHRpbWVzdGFtcCwKICAgICAgLy8gYW5kIHdlIG5lZWQgdG8gdXNlIHRoZSBoaS1yZXMgdmVyc2lvbiBmb3IgZXZlbnQgbGlzdGVuZXIgdGltZXN0YW1wcyBhcwogICAgICAvLyB3ZWxsLgogICAgICBnZXROb3cgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBwZXJmb3JtYW5jZS5ub3coKTsgfTsKICAgIH0KICB9CgogIC8qKgogICAqIEZsdXNoIGJvdGggcXVldWVzIGFuZCBydW4gdGhlIHdhdGNoZXJzLgogICAqLwogIGZ1bmN0aW9uIGZsdXNoU2NoZWR1bGVyUXVldWUgKCkgewogICAgY3VycmVudEZsdXNoVGltZXN0YW1wID0gZ2V0Tm93KCk7CiAgICBmbHVzaGluZyA9IHRydWU7CiAgICB2YXIgd2F0Y2hlciwgaWQ7CgogICAgLy8gU29ydCBxdWV1ZSBiZWZvcmUgZmx1c2guCiAgICAvLyBUaGlzIGVuc3VyZXMgdGhhdDoKICAgIC8vIDEuIENvbXBvbmVudHMgYXJlIHVwZGF0ZWQgZnJvbSBwYXJlbnQgdG8gY2hpbGQuIChiZWNhdXNlIHBhcmVudCBpcyBhbHdheXMKICAgIC8vICAgIGNyZWF0ZWQgYmVmb3JlIHRoZSBjaGlsZCkKICAgIC8vIDIuIEEgY29tcG9uZW50J3MgdXNlciB3YXRjaGVycyBhcmUgcnVuIGJlZm9yZSBpdHMgcmVuZGVyIHdhdGNoZXIgKGJlY2F1c2UKICAgIC8vICAgIHVzZXIgd2F0Y2hlcnMgYXJlIGNyZWF0ZWQgYmVmb3JlIHRoZSByZW5kZXIgd2F0Y2hlcikKICAgIC8vIDMuIElmIGEgY29tcG9uZW50IGlzIGRlc3Ryb3llZCBkdXJpbmcgYSBwYXJlbnQgY29tcG9uZW50J3Mgd2F0Y2hlciBydW4sCiAgICAvLyAgICBpdHMgd2F0Y2hlcnMgY2FuIGJlIHNraXBwZWQuCiAgICBxdWV1ZS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhLmlkIC0gYi5pZDsgfSk7CgogICAgLy8gZG8gbm90IGNhY2hlIGxlbmd0aCBiZWNhdXNlIG1vcmUgd2F0Y2hlcnMgbWlnaHQgYmUgcHVzaGVkCiAgICAvLyBhcyB3ZSBydW4gZXhpc3Rpbmcgd2F0Y2hlcnMKICAgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IHF1ZXVlLmxlbmd0aDsgaW5kZXgrKykgewogICAgICB3YXRjaGVyID0gcXVldWVbaW5kZXhdOwogICAgICBpZiAod2F0Y2hlci5iZWZvcmUpIHsKICAgICAgICB3YXRjaGVyLmJlZm9yZSgpOwogICAgICB9CiAgICAgIGlkID0gd2F0Y2hlci5pZDsKICAgICAgaGFzW2lkXSA9IG51bGw7CiAgICAgIHdhdGNoZXIucnVuKCk7CiAgICAgIC8vIGluIGRldiBidWlsZCwgY2hlY2sgYW5kIHN0b3AgY2lyY3VsYXIgdXBkYXRlcy4KICAgICAgaWYgKGhhc1tpZF0gIT0gbnVsbCkgewogICAgICAgIGNpcmN1bGFyW2lkXSA9IChjaXJjdWxhcltpZF0gfHwgMCkgKyAxOwogICAgICAgIGlmIChjaXJjdWxhcltpZF0gPiBNQVhfVVBEQVRFX0NPVU5UKSB7CiAgICAgICAgICB3YXJuKAogICAgICAgICAgICAnWW91IG1heSBoYXZlIGFuIGluZmluaXRlIHVwZGF0ZSBsb29wICcgKyAoCiAgICAgICAgICAgICAgd2F0Y2hlci51c2VyCiAgICAgICAgICAgICAgICA/ICgiaW4gd2F0Y2hlciB3aXRoIGV4cHJlc3Npb24gXCIiICsgKHdhdGNoZXIuZXhwcmVzc2lvbikgKyAiXCIiKQogICAgICAgICAgICAgICAgOiAiaW4gYSBjb21wb25lbnQgcmVuZGVyIGZ1bmN0aW9uLiIKICAgICAgICAgICAgKSwKICAgICAgICAgICAgd2F0Y2hlci52bQogICAgICAgICAgKTsKICAgICAgICAgIGJyZWFrCiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgLy8ga2VlcCBjb3BpZXMgb2YgcG9zdCBxdWV1ZXMgYmVmb3JlIHJlc2V0dGluZyBzdGF0ZQogICAgdmFyIGFjdGl2YXRlZFF1ZXVlID0gYWN0aXZhdGVkQ2hpbGRyZW4uc2xpY2UoKTsKICAgIHZhciB1cGRhdGVkUXVldWUgPSBxdWV1ZS5zbGljZSgpOwoKICAgIHJlc2V0U2NoZWR1bGVyU3RhdGUoKTsKCiAgICAvLyBjYWxsIGNvbXBvbmVudCB1cGRhdGVkIGFuZCBhY3RpdmF0ZWQgaG9va3MKICAgIGNhbGxBY3RpdmF0ZWRIb29rcyhhY3RpdmF0ZWRRdWV1ZSk7CiAgICBjYWxsVXBkYXRlZEhvb2tzKHVwZGF0ZWRRdWV1ZSk7CgogICAgLy8gZGV2dG9vbCBob29rCiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgIGlmIChkZXZ0b29scyAmJiBjb25maWcuZGV2dG9vbHMpIHsKICAgICAgZGV2dG9vbHMuZW1pdCgnZmx1c2gnKTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIGNhbGxVcGRhdGVkSG9va3MgKHF1ZXVlKSB7CiAgICB2YXIgaSA9IHF1ZXVlLmxlbmd0aDsKICAgIHdoaWxlIChpLS0pIHsKICAgICAgdmFyIHdhdGNoZXIgPSBxdWV1ZVtpXTsKICAgICAgdmFyIHZtID0gd2F0Y2hlci52bTsKICAgICAgaWYgKHZtLl93YXRjaGVyID09PSB3YXRjaGVyICYmIHZtLl9pc01vdW50ZWQgJiYgIXZtLl9pc0Rlc3Ryb3llZCkgewogICAgICAgIGNhbGxIb29rKHZtLCAndXBkYXRlZCcpOwogICAgICB9CiAgICB9CiAgfQoKICAvKioKICAgKiBRdWV1ZSBhIGtlcHQtYWxpdmUgY29tcG9uZW50IHRoYXQgd2FzIGFjdGl2YXRlZCBkdXJpbmcgcGF0Y2guCiAgICogVGhlIHF1ZXVlIHdpbGwgYmUgcHJvY2Vzc2VkIGFmdGVyIHRoZSBlbnRpcmUgdHJlZSBoYXMgYmVlbiBwYXRjaGVkLgogICAqLwogIGZ1bmN0aW9uIHF1ZXVlQWN0aXZhdGVkQ29tcG9uZW50ICh2bSkgewogICAgLy8gc2V0dGluZyBfaW5hY3RpdmUgdG8gZmFsc2UgaGVyZSBzbyB0aGF0IGEgcmVuZGVyIGZ1bmN0aW9uIGNhbgogICAgLy8gcmVseSBvbiBjaGVja2luZyB3aGV0aGVyIGl0J3MgaW4gYW4gaW5hY3RpdmUgdHJlZSAoZS5nLiByb3V0ZXItdmlldykKICAgIHZtLl9pbmFjdGl2ZSA9IGZhbHNlOwogICAgYWN0aXZhdGVkQ2hpbGRyZW4ucHVzaCh2bSk7CiAgfQoKICBmdW5jdGlvbiBjYWxsQWN0aXZhdGVkSG9va3MgKHF1ZXVlKSB7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHF1ZXVlLmxlbmd0aDsgaSsrKSB7CiAgICAgIHF1ZXVlW2ldLl9pbmFjdGl2ZSA9IHRydWU7CiAgICAgIGFjdGl2YXRlQ2hpbGRDb21wb25lbnQocXVldWVbaV0sIHRydWUgLyogdHJ1ZSAqLyk7CiAgICB9CiAgfQoKICAvKioKICAgKiBQdXNoIGEgd2F0Y2hlciBpbnRvIHRoZSB3YXRjaGVyIHF1ZXVlLgogICAqIEpvYnMgd2l0aCBkdXBsaWNhdGUgSURzIHdpbGwgYmUgc2tpcHBlZCB1bmxlc3MgaXQncwogICAqIHB1c2hlZCB3aGVuIHRoZSBxdWV1ZSBpcyBiZWluZyBmbHVzaGVkLgogICAqLwogIGZ1bmN0aW9uIHF1ZXVlV2F0Y2hlciAod2F0Y2hlcikgewogICAgdmFyIGlkID0gd2F0Y2hlci5pZDsKICAgIGlmIChoYXNbaWRdID09IG51bGwpIHsKICAgICAgaGFzW2lkXSA9IHRydWU7CiAgICAgIGlmICghZmx1c2hpbmcpIHsKICAgICAgICBxdWV1ZS5wdXNoKHdhdGNoZXIpOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIGlmIGFscmVhZHkgZmx1c2hpbmcsIHNwbGljZSB0aGUgd2F0Y2hlciBiYXNlZCBvbiBpdHMgaWQKICAgICAgICAvLyBpZiBhbHJlYWR5IHBhc3QgaXRzIGlkLCBpdCB3aWxsIGJlIHJ1biBuZXh0IGltbWVkaWF0ZWx5LgogICAgICAgIHZhciBpID0gcXVldWUubGVuZ3RoIC0gMTsKICAgICAgICB3aGlsZSAoaSA+IGluZGV4ICYmIHF1ZXVlW2ldLmlkID4gd2F0Y2hlci5pZCkgewogICAgICAgICAgaS0tOwogICAgICAgIH0KICAgICAgICBxdWV1ZS5zcGxpY2UoaSArIDEsIDAsIHdhdGNoZXIpOwogICAgICB9CiAgICAgIC8vIHF1ZXVlIHRoZSBmbHVzaAogICAgICBpZiAoIXdhaXRpbmcpIHsKICAgICAgICB3YWl0aW5nID0gdHJ1ZTsKCiAgICAgICAgaWYgKCFjb25maWcuYXN5bmMpIHsKICAgICAgICAgIGZsdXNoU2NoZWR1bGVyUXVldWUoKTsKICAgICAgICAgIHJldHVybgogICAgICAgIH0KICAgICAgICBuZXh0VGljayhmbHVzaFNjaGVkdWxlclF1ZXVlKTsKICAgICAgfQogICAgfQogIH0KCiAgLyogICovCgoKCiAgdmFyIHVpZCQyID0gMDsKCiAgLyoqCiAgICogQSB3YXRjaGVyIHBhcnNlcyBhbiBleHByZXNzaW9uLCBjb2xsZWN0cyBkZXBlbmRlbmNpZXMsCiAgICogYW5kIGZpcmVzIGNhbGxiYWNrIHdoZW4gdGhlIGV4cHJlc3Npb24gdmFsdWUgY2hhbmdlcy4KICAgKiBUaGlzIGlzIHVzZWQgZm9yIGJvdGggdGhlICR3YXRjaCgpIGFwaSBhbmQgZGlyZWN0aXZlcy4KICAgKi8KICB2YXIgV2F0Y2hlciA9IGZ1bmN0aW9uIFdhdGNoZXIgKAogICAgdm0sCiAgICBleHBPckZuLAogICAgY2IsCiAgICBvcHRpb25zLAogICAgaXNSZW5kZXJXYXRjaGVyCiAgKSB7CiAgICB0aGlzLnZtID0gdm07CiAgICBpZiAoaXNSZW5kZXJXYXRjaGVyKSB7CiAgICAgIHZtLl93YXRjaGVyID0gdGhpczsKICAgIH0KICAgIHZtLl93YXRjaGVycy5wdXNoKHRoaXMpOwogICAgLy8gb3B0aW9ucwogICAgaWYgKG9wdGlvbnMpIHsKICAgICAgdGhpcy5kZWVwID0gISFvcHRpb25zLmRlZXA7CiAgICAgIHRoaXMudXNlciA9ICEhb3B0aW9ucy51c2VyOwogICAgICB0aGlzLmxhenkgPSAhIW9wdGlvbnMubGF6eTsKICAgICAgdGhpcy5zeW5jID0gISFvcHRpb25zLnN5bmM7CiAgICAgIHRoaXMuYmVmb3JlID0gb3B0aW9ucy5iZWZvcmU7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmRlZXAgPSB0aGlzLnVzZXIgPSB0aGlzLmxhenkgPSB0aGlzLnN5bmMgPSBmYWxzZTsKICAgIH0KICAgIHRoaXMuY2IgPSBjYjsKICAgIHRoaXMuaWQgPSArK3VpZCQyOyAvLyB1aWQgZm9yIGJhdGNoaW5nCiAgICB0aGlzLmFjdGl2ZSA9IHRydWU7CiAgICB0aGlzLmRpcnR5ID0gdGhpcy5sYXp5OyAvLyBmb3IgbGF6eSB3YXRjaGVycwogICAgdGhpcy5kZXBzID0gW107CiAgICB0aGlzLm5ld0RlcHMgPSBbXTsKICAgIHRoaXMuZGVwSWRzID0gbmV3IF9TZXQoKTsKICAgIHRoaXMubmV3RGVwSWRzID0gbmV3IF9TZXQoKTsKICAgIHRoaXMuZXhwcmVzc2lvbiA9IGV4cE9yRm4udG9TdHJpbmcoKTsKICAgIC8vIHBhcnNlIGV4cHJlc3Npb24gZm9yIGdldHRlcgogICAgaWYgKHR5cGVvZiBleHBPckZuID09PSAnZnVuY3Rpb24nKSB7CiAgICAgIHRoaXMuZ2V0dGVyID0gZXhwT3JGbjsKICAgIH0gZWxzZSB7CiAgICAgIHRoaXMuZ2V0dGVyID0gcGFyc2VQYXRoKGV4cE9yRm4pOwogICAgICBpZiAoIXRoaXMuZ2V0dGVyKSB7CiAgICAgICAgdGhpcy5nZXR0ZXIgPSBub29wOwogICAgICAgIHdhcm4oCiAgICAgICAgICAiRmFpbGVkIHdhdGNoaW5nIHBhdGg6IFwiIiArIGV4cE9yRm4gKyAiXCIgIiArCiAgICAgICAgICAnV2F0Y2hlciBvbmx5IGFjY2VwdHMgc2ltcGxlIGRvdC1kZWxpbWl0ZWQgcGF0aHMuICcgKwogICAgICAgICAgJ0ZvciBmdWxsIGNvbnRyb2wsIHVzZSBhIGZ1bmN0aW9uIGluc3RlYWQuJywKICAgICAgICAgIHZtCiAgICAgICAgKTsKICAgICAgfQogICAgfQogICAgdGhpcy52YWx1ZSA9IHRoaXMubGF6eQogICAgICA/IHVuZGVmaW5lZAogICAgICA6IHRoaXMuZ2V0KCk7CiAgfTsKCiAgLyoqCiAgICogRXZhbHVhdGUgdGhlIGdldHRlciwgYW5kIHJlLWNvbGxlY3QgZGVwZW5kZW5jaWVzLgogICAqLwogIFdhdGNoZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIGdldCAoKSB7CiAgICBwdXNoVGFyZ2V0KHRoaXMpOwogICAgdmFyIHZhbHVlOwogICAgdmFyIHZtID0gdGhpcy52bTsKICAgIHRyeSB7CiAgICAgIHZhbHVlID0gdGhpcy5nZXR0ZXIuY2FsbCh2bSwgdm0pOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAodGhpcy51c2VyKSB7CiAgICAgICAgaGFuZGxlRXJyb3IoZSwgdm0sICgiZ2V0dGVyIGZvciB3YXRjaGVyIFwiIiArICh0aGlzLmV4cHJlc3Npb24pICsgIlwiIikpOwogICAgICB9IGVsc2UgewogICAgICAgIHRocm93IGUKICAgICAgfQogICAgfSBmaW5hbGx5IHsKICAgICAgLy8gInRvdWNoIiBldmVyeSBwcm9wZXJ0eSBzbyB0aGV5IGFyZSBhbGwgdHJhY2tlZCBhcwogICAgICAvLyBkZXBlbmRlbmNpZXMgZm9yIGRlZXAgd2F0Y2hpbmcKICAgICAgaWYgKHRoaXMuZGVlcCkgewogICAgICAgIHRyYXZlcnNlKHZhbHVlKTsKICAgICAgfQogICAgICBwb3BUYXJnZXQoKTsKICAgICAgdGhpcy5jbGVhbnVwRGVwcygpOwogICAgfQogICAgcmV0dXJuIHZhbHVlCiAgfTsKCiAgLyoqCiAgICogQWRkIGEgZGVwZW5kZW5jeSB0byB0aGlzIGRpcmVjdGl2ZS4KICAgKi8KICBXYXRjaGVyLnByb3RvdHlwZS5hZGREZXAgPSBmdW5jdGlvbiBhZGREZXAgKGRlcCkgewogICAgdmFyIGlkID0gZGVwLmlkOwogICAgaWYgKCF0aGlzLm5ld0RlcElkcy5oYXMoaWQpKSB7CiAgICAgIHRoaXMubmV3RGVwSWRzLmFkZChpZCk7CiAgICAgIHRoaXMubmV3RGVwcy5wdXNoKGRlcCk7CiAgICAgIGlmICghdGhpcy5kZXBJZHMuaGFzKGlkKSkgewogICAgICAgIGRlcC5hZGRTdWIodGhpcyk7CiAgICAgIH0KICAgIH0KICB9OwoKICAvKioKICAgKiBDbGVhbiB1cCBmb3IgZGVwZW5kZW5jeSBjb2xsZWN0aW9uLgogICAqLwogIFdhdGNoZXIucHJvdG90eXBlLmNsZWFudXBEZXBzID0gZnVuY3Rpb24gY2xlYW51cERlcHMgKCkgewogICAgdmFyIGkgPSB0aGlzLmRlcHMubGVuZ3RoOwogICAgd2hpbGUgKGktLSkgewogICAgICB2YXIgZGVwID0gdGhpcy5kZXBzW2ldOwogICAgICBpZiAoIXRoaXMubmV3RGVwSWRzLmhhcyhkZXAuaWQpKSB7CiAgICAgICAgZGVwLnJlbW92ZVN1Yih0aGlzKTsKICAgICAgfQogICAgfQogICAgdmFyIHRtcCA9IHRoaXMuZGVwSWRzOwogICAgdGhpcy5kZXBJZHMgPSB0aGlzLm5ld0RlcElkczsKICAgIHRoaXMubmV3RGVwSWRzID0gdG1wOwogICAgdGhpcy5uZXdEZXBJZHMuY2xlYXIoKTsKICAgIHRtcCA9IHRoaXMuZGVwczsKICAgIHRoaXMuZGVwcyA9IHRoaXMubmV3RGVwczsKICAgIHRoaXMubmV3RGVwcyA9IHRtcDsKICAgIHRoaXMubmV3RGVwcy5sZW5ndGggPSAwOwogIH07CgogIC8qKgogICAqIFN1YnNjcmliZXIgaW50ZXJmYWNlLgogICAqIFdpbGwgYmUgY2FsbGVkIHdoZW4gYSBkZXBlbmRlbmN5IGNoYW5nZXMuCiAgICovCiAgV2F0Y2hlci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlICgpIHsKICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovCiAgICBpZiAodGhpcy5sYXp5KSB7CiAgICAgIHRoaXMuZGlydHkgPSB0cnVlOwogICAgfSBlbHNlIGlmICh0aGlzLnN5bmMpIHsKICAgICAgdGhpcy5ydW4oKTsKICAgIH0gZWxzZSB7CiAgICAgIHF1ZXVlV2F0Y2hlcih0aGlzKTsKICAgIH0KICB9OwoKICAvKioKICAgKiBTY2hlZHVsZXIgam9iIGludGVyZmFjZS4KICAgKiBXaWxsIGJlIGNhbGxlZCBieSB0aGUgc2NoZWR1bGVyLgogICAqLwogIFdhdGNoZXIucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uIHJ1biAoKSB7CiAgICBpZiAodGhpcy5hY3RpdmUpIHsKICAgICAgdmFyIHZhbHVlID0gdGhpcy5nZXQoKTsKICAgICAgaWYgKAogICAgICAgIHZhbHVlICE9PSB0aGlzLnZhbHVlIHx8CiAgICAgICAgLy8gRGVlcCB3YXRjaGVycyBhbmQgd2F0Y2hlcnMgb24gT2JqZWN0L0FycmF5cyBzaG91bGQgZmlyZSBldmVuCiAgICAgICAgLy8gd2hlbiB0aGUgdmFsdWUgaXMgdGhlIHNhbWUsIGJlY2F1c2UgdGhlIHZhbHVlIG1heQogICAgICAgIC8vIGhhdmUgbXV0YXRlZC4KICAgICAgICBpc09iamVjdCh2YWx1ZSkgfHwKICAgICAgICB0aGlzLmRlZXAKICAgICAgKSB7CiAgICAgICAgLy8gc2V0IG5ldyB2YWx1ZQogICAgICAgIHZhciBvbGRWYWx1ZSA9IHRoaXMudmFsdWU7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICAgIGlmICh0aGlzLnVzZXIpIHsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIHRoaXMuY2IuY2FsbCh0aGlzLnZtLCB2YWx1ZSwgb2xkVmFsdWUpOwogICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICBoYW5kbGVFcnJvcihlLCB0aGlzLnZtLCAoImNhbGxiYWNrIGZvciB3YXRjaGVyIFwiIiArICh0aGlzLmV4cHJlc3Npb24pICsgIlwiIikpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aGlzLmNiLmNhbGwodGhpcy52bSwgdmFsdWUsIG9sZFZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9OwoKICAvKioKICAgKiBFdmFsdWF0ZSB0aGUgdmFsdWUgb2YgdGhlIHdhdGNoZXIuCiAgICogVGhpcyBvbmx5IGdldHMgY2FsbGVkIGZvciBsYXp5IHdhdGNoZXJzLgogICAqLwogIFdhdGNoZXIucHJvdG90eXBlLmV2YWx1YXRlID0gZnVuY3Rpb24gZXZhbHVhdGUgKCkgewogICAgdGhpcy52YWx1ZSA9IHRoaXMuZ2V0KCk7CiAgICB0aGlzLmRpcnR5ID0gZmFsc2U7CiAgfTsKCiAgLyoqCiAgICogRGVwZW5kIG9uIGFsbCBkZXBzIGNvbGxlY3RlZCBieSB0aGlzIHdhdGNoZXIuCiAgICovCiAgV2F0Y2hlci5wcm90b3R5cGUuZGVwZW5kID0gZnVuY3Rpb24gZGVwZW5kICgpIHsKICAgIHZhciBpID0gdGhpcy5kZXBzLmxlbmd0aDsKICAgIHdoaWxlIChpLS0pIHsKICAgICAgdGhpcy5kZXBzW2ldLmRlcGVuZCgpOwogICAgfQogIH07CgogIC8qKgogICAqIFJlbW92ZSBzZWxmIGZyb20gYWxsIGRlcGVuZGVuY2llcycgc3Vic2NyaWJlciBsaXN0LgogICAqLwogIFdhdGNoZXIucHJvdG90eXBlLnRlYXJkb3duID0gZnVuY3Rpb24gdGVhcmRvd24gKCkgewogICAgaWYgKHRoaXMuYWN0aXZlKSB7CiAgICAgIC8vIHJlbW92ZSBzZWxmIGZyb20gdm0ncyB3YXRjaGVyIGxpc3QKICAgICAgLy8gdGhpcyBpcyBhIHNvbWV3aGF0IGV4cGVuc2l2ZSBvcGVyYXRpb24gc28gd2Ugc2tpcCBpdAogICAgICAvLyBpZiB0aGUgdm0gaXMgYmVpbmcgZGVzdHJveWVkLgogICAgICBpZiAoIXRoaXMudm0uX2lzQmVpbmdEZXN0cm95ZWQpIHsKICAgICAgICByZW1vdmUodGhpcy52bS5fd2F0Y2hlcnMsIHRoaXMpOwogICAgICB9CiAgICAgIHZhciBpID0gdGhpcy5kZXBzLmxlbmd0aDsKICAgICAgd2hpbGUgKGktLSkgewogICAgICAgIHRoaXMuZGVwc1tpXS5yZW1vdmVTdWIodGhpcyk7CiAgICAgIH0KICAgICAgdGhpcy5hY3RpdmUgPSBmYWxzZTsKICAgIH0KICB9OwoKICAvKiAgKi8KCiAgdmFyIHNoYXJlZFByb3BlcnR5RGVmaW5pdGlvbiA9IHsKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUsCiAgICBnZXQ6IG5vb3AsCiAgICBzZXQ6IG5vb3AKICB9OwoKICBmdW5jdGlvbiBwcm94eSAodGFyZ2V0LCBzb3VyY2VLZXksIGtleSkgewogICAgc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uLmdldCA9IGZ1bmN0aW9uIHByb3h5R2V0dGVyICgpIHsKICAgICAgcmV0dXJuIHRoaXNbc291cmNlS2V5XVtrZXldCiAgICB9OwogICAgc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uLnNldCA9IGZ1bmN0aW9uIHByb3h5U2V0dGVyICh2YWwpIHsKICAgICAgdGhpc1tzb3VyY2VLZXldW2tleV0gPSB2YWw7CiAgICB9OwogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBzaGFyZWRQcm9wZXJ0eURlZmluaXRpb24pOwogIH0KCiAgZnVuY3Rpb24gaW5pdFN0YXRlICh2bSkgewogICAgdm0uX3dhdGNoZXJzID0gW107CiAgICB2YXIgb3B0cyA9IHZtLiRvcHRpb25zOwogICAgaWYgKG9wdHMucHJvcHMpIHsgaW5pdFByb3BzKHZtLCBvcHRzLnByb3BzKTsgfQogICAgaWYgKG9wdHMubWV0aG9kcykgeyBpbml0TWV0aG9kcyh2bSwgb3B0cy5tZXRob2RzKTsgfQogICAgaWYgKG9wdHMuZGF0YSkgewogICAgICBpbml0RGF0YSh2bSk7CiAgICB9IGVsc2UgewogICAgICBvYnNlcnZlKHZtLl9kYXRhID0ge30sIHRydWUgLyogYXNSb290RGF0YSAqLyk7CiAgICB9CiAgICBpZiAob3B0cy5jb21wdXRlZCkgeyBpbml0Q29tcHV0ZWQodm0sIG9wdHMuY29tcHV0ZWQpOyB9CiAgICBpZiAob3B0cy53YXRjaCAmJiBvcHRzLndhdGNoICE9PSBuYXRpdmVXYXRjaCkgewogICAgICBpbml0V2F0Y2godm0sIG9wdHMud2F0Y2gpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5pdFByb3BzICh2bSwgcHJvcHNPcHRpb25zKSB7CiAgICB2YXIgcHJvcHNEYXRhID0gdm0uJG9wdGlvbnMucHJvcHNEYXRhIHx8IHt9OwogICAgdmFyIHByb3BzID0gdm0uX3Byb3BzID0ge307CiAgICAvLyBjYWNoZSBwcm9wIGtleXMgc28gdGhhdCBmdXR1cmUgcHJvcHMgdXBkYXRlcyBjYW4gaXRlcmF0ZSB1c2luZyBBcnJheQogICAgLy8gaW5zdGVhZCBvZiBkeW5hbWljIG9iamVjdCBrZXkgZW51bWVyYXRpb24uCiAgICB2YXIga2V5cyA9IHZtLiRvcHRpb25zLl9wcm9wS2V5cyA9IFtdOwogICAgdmFyIGlzUm9vdCA9ICF2bS4kcGFyZW50OwogICAgLy8gcm9vdCBpbnN0YW5jZSBwcm9wcyBzaG91bGQgYmUgY29udmVydGVkCiAgICBpZiAoIWlzUm9vdCkgewogICAgICB0b2dnbGVPYnNlcnZpbmcoZmFsc2UpOwogICAgfQogICAgdmFyIGxvb3AgPSBmdW5jdGlvbiAoIGtleSApIHsKICAgICAga2V5cy5wdXNoKGtleSk7CiAgICAgIHZhciB2YWx1ZSA9IHZhbGlkYXRlUHJvcChrZXksIHByb3BzT3B0aW9ucywgcHJvcHNEYXRhLCB2bSk7CiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovCiAgICAgIHsKICAgICAgICB2YXIgaHlwaGVuYXRlZEtleSA9IGh5cGhlbmF0ZShrZXkpOwogICAgICAgIGlmIChpc1Jlc2VydmVkQXR0cmlidXRlKGh5cGhlbmF0ZWRLZXkpIHx8CiAgICAgICAgICAgIGNvbmZpZy5pc1Jlc2VydmVkQXR0cihoeXBoZW5hdGVkS2V5KSkgewogICAgICAgICAgd2FybigKICAgICAgICAgICAgKCJcIiIgKyBoeXBoZW5hdGVkS2V5ICsgIlwiIGlzIGEgcmVzZXJ2ZWQgYXR0cmlidXRlIGFuZCBjYW5ub3QgYmUgdXNlZCBhcyBjb21wb25lbnQgcHJvcC4iKSwKICAgICAgICAgICAgdm0KICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGRlZmluZVJlYWN0aXZlJCQxKHByb3BzLCBrZXksIHZhbHVlLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICBpZiAoIWlzUm9vdCAmJiAhaXNVcGRhdGluZ0NoaWxkQ29tcG9uZW50KSB7CiAgICAgICAgICAgIHdhcm4oCiAgICAgICAgICAgICAgIkF2b2lkIG11dGF0aW5nIGEgcHJvcCBkaXJlY3RseSBzaW5jZSB0aGUgdmFsdWUgd2lsbCBiZSAiICsKICAgICAgICAgICAgICAib3ZlcndyaXR0ZW4gd2hlbmV2ZXIgdGhlIHBhcmVudCBjb21wb25lbnQgcmUtcmVuZGVycy4gIiArCiAgICAgICAgICAgICAgIkluc3RlYWQsIHVzZSBhIGRhdGEgb3IgY29tcHV0ZWQgcHJvcGVydHkgYmFzZWQgb24gdGhlIHByb3AncyAiICsKICAgICAgICAgICAgICAidmFsdWUuIFByb3AgYmVpbmcgbXV0YXRlZDogXCIiICsga2V5ICsgIlwiIiwKICAgICAgICAgICAgICB2bQogICAgICAgICAgICApOwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9CiAgICAgIC8vIHN0YXRpYyBwcm9wcyBhcmUgYWxyZWFkeSBwcm94aWVkIG9uIHRoZSBjb21wb25lbnQncyBwcm90b3R5cGUKICAgICAgLy8gZHVyaW5nIFZ1ZS5leHRlbmQoKS4gV2Ugb25seSBuZWVkIHRvIHByb3h5IHByb3BzIGRlZmluZWQgYXQKICAgICAgLy8gaW5zdGFudGlhdGlvbiBoZXJlLgogICAgICBpZiAoIShrZXkgaW4gdm0pKSB7CiAgICAgICAgcHJveHkodm0sICJfcHJvcHMiLCBrZXkpOwogICAgICB9CiAgICB9OwoKICAgIGZvciAodmFyIGtleSBpbiBwcm9wc09wdGlvbnMpIGxvb3AoIGtleSApOwogICAgdG9nZ2xlT2JzZXJ2aW5nKHRydWUpOwogIH0KCiAgZnVuY3Rpb24gaW5pdERhdGEgKHZtKSB7CiAgICB2YXIgZGF0YSA9IHZtLiRvcHRpb25zLmRhdGE7CiAgICBkYXRhID0gdm0uX2RhdGEgPSB0eXBlb2YgZGF0YSA9PT0gJ2Z1bmN0aW9uJwogICAgICA/IGdldERhdGEoZGF0YSwgdm0pCiAgICAgIDogZGF0YSB8fCB7fTsKICAgIGlmICghaXNQbGFpbk9iamVjdChkYXRhKSkgewogICAgICBkYXRhID0ge307CiAgICAgIHdhcm4oCiAgICAgICAgJ2RhdGEgZnVuY3Rpb25zIHNob3VsZCByZXR1cm4gYW4gb2JqZWN0OlxuJyArCiAgICAgICAgJ2h0dHBzOi8vdnVlanMub3JnL3YyL2d1aWRlL2NvbXBvbmVudHMuaHRtbCNkYXRhLU11c3QtQmUtYS1GdW5jdGlvbicsCiAgICAgICAgdm0KICAgICAgKTsKICAgIH0KICAgIC8vIHByb3h5IGRhdGEgb24gaW5zdGFuY2UKICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoZGF0YSk7CiAgICB2YXIgcHJvcHMgPSB2bS4kb3B0aW9ucy5wcm9wczsKICAgIHZhciBtZXRob2RzID0gdm0uJG9wdGlvbnMubWV0aG9kczsKICAgIHZhciBpID0ga2V5cy5sZW5ndGg7CiAgICB3aGlsZSAoaS0tKSB7CiAgICAgIHZhciBrZXkgPSBrZXlzW2ldOwogICAgICB7CiAgICAgICAgaWYgKG1ldGhvZHMgJiYgaGFzT3duKG1ldGhvZHMsIGtleSkpIHsKICAgICAgICAgIHdhcm4oCiAgICAgICAgICAgICgiTWV0aG9kIFwiIiArIGtleSArICJcIiBoYXMgYWxyZWFkeSBiZWVuIGRlZmluZWQgYXMgYSBkYXRhIHByb3BlcnR5LiIpLAogICAgICAgICAgICB2bQogICAgICAgICAgKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKHByb3BzICYmIGhhc093bihwcm9wcywga2V5KSkgewogICAgICAgIHdhcm4oCiAgICAgICAgICAiVGhlIGRhdGEgcHJvcGVydHkgXCIiICsga2V5ICsgIlwiIGlzIGFscmVhZHkgZGVjbGFyZWQgYXMgYSBwcm9wLiAiICsKICAgICAgICAgICJVc2UgcHJvcCBkZWZhdWx0IHZhbHVlIGluc3RlYWQuIiwKICAgICAgICAgIHZtCiAgICAgICAgKTsKICAgICAgfSBlbHNlIGlmICghaXNSZXNlcnZlZChrZXkpKSB7CiAgICAgICAgcHJveHkodm0sICJfZGF0YSIsIGtleSk7CiAgICAgIH0KICAgIH0KICAgIC8vIG9ic2VydmUgZGF0YQogICAgb2JzZXJ2ZShkYXRhLCB0cnVlIC8qIGFzUm9vdERhdGEgKi8pOwogIH0KCiAgZnVuY3Rpb24gZ2V0RGF0YSAoZGF0YSwgdm0pIHsKICAgIC8vICM3NTczIGRpc2FibGUgZGVwIGNvbGxlY3Rpb24gd2hlbiBpbnZva2luZyBkYXRhIGdldHRlcnMKICAgIHB1c2hUYXJnZXQoKTsKICAgIHRyeSB7CiAgICAgIHJldHVybiBkYXRhLmNhbGwodm0sIHZtKQogICAgfSBjYXRjaCAoZSkgewogICAgICBoYW5kbGVFcnJvcihlLCB2bSwgImRhdGEoKSIpOwogICAgICByZXR1cm4ge30KICAgIH0gZmluYWxseSB7CiAgICAgIHBvcFRhcmdldCgpOwogICAgfQogIH0KCiAgdmFyIGNvbXB1dGVkV2F0Y2hlck9wdGlvbnMgPSB7IGxhenk6IHRydWUgfTsKCiAgZnVuY3Rpb24gaW5pdENvbXB1dGVkICh2bSwgY29tcHV0ZWQpIHsKICAgIC8vICRmbG93LWRpc2FibGUtbGluZQogICAgdmFyIHdhdGNoZXJzID0gdm0uX2NvbXB1dGVkV2F0Y2hlcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpOwogICAgLy8gY29tcHV0ZWQgcHJvcGVydGllcyBhcmUganVzdCBnZXR0ZXJzIGR1cmluZyBTU1IKICAgIHZhciBpc1NTUiA9IGlzU2VydmVyUmVuZGVyaW5nKCk7CgogICAgZm9yICh2YXIga2V5IGluIGNvbXB1dGVkKSB7CiAgICAgIHZhciB1c2VyRGVmID0gY29tcHV0ZWRba2V5XTsKICAgICAgdmFyIGdldHRlciA9IHR5cGVvZiB1c2VyRGVmID09PSAnZnVuY3Rpb24nID8gdXNlckRlZiA6IHVzZXJEZWYuZ2V0OwogICAgICBpZiAoZ2V0dGVyID09IG51bGwpIHsKICAgICAgICB3YXJuKAogICAgICAgICAgKCJHZXR0ZXIgaXMgbWlzc2luZyBmb3IgY29tcHV0ZWQgcHJvcGVydHkgXCIiICsga2V5ICsgIlwiLiIpLAogICAgICAgICAgdm0KICAgICAgICApOwogICAgICB9CgogICAgICBpZiAoIWlzU1NSKSB7CiAgICAgICAgLy8gY3JlYXRlIGludGVybmFsIHdhdGNoZXIgZm9yIHRoZSBjb21wdXRlZCBwcm9wZXJ0eS4KICAgICAgICB3YXRjaGVyc1trZXldID0gbmV3IFdhdGNoZXIoCiAgICAgICAgICB2bSwKICAgICAgICAgIGdldHRlciB8fCBub29wLAogICAgICAgICAgbm9vcCwKICAgICAgICAgIGNvbXB1dGVkV2F0Y2hlck9wdGlvbnMKICAgICAgICApOwogICAgICB9CgogICAgICAvLyBjb21wb25lbnQtZGVmaW5lZCBjb21wdXRlZCBwcm9wZXJ0aWVzIGFyZSBhbHJlYWR5IGRlZmluZWQgb24gdGhlCiAgICAgIC8vIGNvbXBvbmVudCBwcm90b3R5cGUuIFdlIG9ubHkgbmVlZCB0byBkZWZpbmUgY29tcHV0ZWQgcHJvcGVydGllcyBkZWZpbmVkCiAgICAgIC8vIGF0IGluc3RhbnRpYXRpb24gaGVyZS4KICAgICAgaWYgKCEoa2V5IGluIHZtKSkgewogICAgICAgIGRlZmluZUNvbXB1dGVkKHZtLCBrZXksIHVzZXJEZWYpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChrZXkgaW4gdm0uJGRhdGEpIHsKICAgICAgICAgIHdhcm4oKCJUaGUgY29tcHV0ZWQgcHJvcGVydHkgXCIiICsga2V5ICsgIlwiIGlzIGFscmVhZHkgZGVmaW5lZCBpbiBkYXRhLiIpLCB2bSk7CiAgICAgICAgfSBlbHNlIGlmICh2bS4kb3B0aW9ucy5wcm9wcyAmJiBrZXkgaW4gdm0uJG9wdGlvbnMucHJvcHMpIHsKICAgICAgICAgIHdhcm4oKCJUaGUgY29tcHV0ZWQgcHJvcGVydHkgXCIiICsga2V5ICsgIlwiIGlzIGFscmVhZHkgZGVmaW5lZCBhcyBhIHByb3AuIiksIHZtKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIGRlZmluZUNvbXB1dGVkICgKICAgIHRhcmdldCwKICAgIGtleSwKICAgIHVzZXJEZWYKICApIHsKICAgIHZhciBzaG91bGRDYWNoZSA9ICFpc1NlcnZlclJlbmRlcmluZygpOwogICAgaWYgKHR5cGVvZiB1c2VyRGVmID09PSAnZnVuY3Rpb24nKSB7CiAgICAgIHNoYXJlZFByb3BlcnR5RGVmaW5pdGlvbi5nZXQgPSBzaG91bGRDYWNoZQogICAgICAgID8gY3JlYXRlQ29tcHV0ZWRHZXR0ZXIoa2V5KQogICAgICAgIDogY3JlYXRlR2V0dGVySW52b2tlcih1c2VyRGVmKTsKICAgICAgc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uLnNldCA9IG5vb3A7CiAgICB9IGVsc2UgewogICAgICBzaGFyZWRQcm9wZXJ0eURlZmluaXRpb24uZ2V0ID0gdXNlckRlZi5nZXQKICAgICAgICA/IHNob3VsZENhY2hlICYmIHVzZXJEZWYuY2FjaGUgIT09IGZhbHNlCiAgICAgICAgICA/IGNyZWF0ZUNvbXB1dGVkR2V0dGVyKGtleSkKICAgICAgICAgIDogY3JlYXRlR2V0dGVySW52b2tlcih1c2VyRGVmLmdldCkKICAgICAgICA6IG5vb3A7CiAgICAgIHNoYXJlZFByb3BlcnR5RGVmaW5pdGlvbi5zZXQgPSB1c2VyRGVmLnNldCB8fCBub29wOwogICAgfQogICAgaWYgKHNoYXJlZFByb3BlcnR5RGVmaW5pdGlvbi5zZXQgPT09IG5vb3ApIHsKICAgICAgc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uLnNldCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB3YXJuKAogICAgICAgICAgKCJDb21wdXRlZCBwcm9wZXJ0eSBcIiIgKyBrZXkgKyAiXCIgd2FzIGFzc2lnbmVkIHRvIGJ1dCBpdCBoYXMgbm8gc2V0dGVyLiIpLAogICAgICAgICAgdGhpcwogICAgICAgICk7CiAgICAgIH07CiAgICB9CiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHNoYXJlZFByb3BlcnR5RGVmaW5pdGlvbik7CiAgfQoKICBmdW5jdGlvbiBjcmVhdGVDb21wdXRlZEdldHRlciAoa2V5KSB7CiAgICByZXR1cm4gZnVuY3Rpb24gY29tcHV0ZWRHZXR0ZXIgKCkgewogICAgICB2YXIgd2F0Y2hlciA9IHRoaXMuX2NvbXB1dGVkV2F0Y2hlcnMgJiYgdGhpcy5fY29tcHV0ZWRXYXRjaGVyc1trZXldOwogICAgICBpZiAod2F0Y2hlcikgewogICAgICAgIGlmICh3YXRjaGVyLmRpcnR5KSB7CiAgICAgICAgICB3YXRjaGVyLmV2YWx1YXRlKCk7CiAgICAgICAgfQogICAgICAgIGlmIChEZXAudGFyZ2V0KSB7CiAgICAgICAgICB3YXRjaGVyLmRlcGVuZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gd2F0Y2hlci52YWx1ZQogICAgICB9CiAgICB9CiAgfQoKICBmdW5jdGlvbiBjcmVhdGVHZXR0ZXJJbnZva2VyKGZuKSB7CiAgICByZXR1cm4gZnVuY3Rpb24gY29tcHV0ZWRHZXR0ZXIgKCkgewogICAgICByZXR1cm4gZm4uY2FsbCh0aGlzLCB0aGlzKQogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5pdE1ldGhvZHMgKHZtLCBtZXRob2RzKSB7CiAgICB2YXIgcHJvcHMgPSB2bS4kb3B0aW9ucy5wcm9wczsKICAgIGZvciAodmFyIGtleSBpbiBtZXRob2RzKSB7CiAgICAgIHsKICAgICAgICBpZiAodHlwZW9mIG1ldGhvZHNba2V5XSAhPT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgd2FybigKICAgICAgICAgICAgIk1ldGhvZCBcIiIgKyBrZXkgKyAiXCIgaGFzIHR5cGUgXCIiICsgKHR5cGVvZiBtZXRob2RzW2tleV0pICsgIlwiIGluIHRoZSBjb21wb25lbnQgZGVmaW5pdGlvbi4gIiArCiAgICAgICAgICAgICJEaWQgeW91IHJlZmVyZW5jZSB0aGUgZnVuY3Rpb24gY29ycmVjdGx5PyIsCiAgICAgICAgICAgIHZtCiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBpZiAocHJvcHMgJiYgaGFzT3duKHByb3BzLCBrZXkpKSB7CiAgICAgICAgICB3YXJuKAogICAgICAgICAgICAoIk1ldGhvZCBcIiIgKyBrZXkgKyAiXCIgaGFzIGFscmVhZHkgYmVlbiBkZWZpbmVkIGFzIGEgcHJvcC4iKSwKICAgICAgICAgICAgdm0KICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGlmICgoa2V5IGluIHZtKSAmJiBpc1Jlc2VydmVkKGtleSkpIHsKICAgICAgICAgIHdhcm4oCiAgICAgICAgICAgICJNZXRob2QgXCIiICsga2V5ICsgIlwiIGNvbmZsaWN0cyB3aXRoIGFuIGV4aXN0aW5nIFZ1ZSBpbnN0YW5jZSBtZXRob2QuICIgKwogICAgICAgICAgICAiQXZvaWQgZGVmaW5pbmcgY29tcG9uZW50IG1ldGhvZHMgdGhhdCBzdGFydCB3aXRoIF8gb3IgJC4iCiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgfQogICAgICB2bVtrZXldID0gdHlwZW9mIG1ldGhvZHNba2V5XSAhPT0gJ2Z1bmN0aW9uJyA/IG5vb3AgOiBiaW5kKG1ldGhvZHNba2V5XSwgdm0pOwogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5pdFdhdGNoICh2bSwgd2F0Y2gpIHsKICAgIGZvciAodmFyIGtleSBpbiB3YXRjaCkgewogICAgICB2YXIgaGFuZGxlciA9IHdhdGNoW2tleV07CiAgICAgIGlmIChBcnJheS5pc0FycmF5KGhhbmRsZXIpKSB7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYW5kbGVyLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICBjcmVhdGVXYXRjaGVyKHZtLCBrZXksIGhhbmRsZXJbaV0pOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBjcmVhdGVXYXRjaGVyKHZtLCBrZXksIGhhbmRsZXIpOwogICAgICB9CiAgICB9CiAgfQoKICBmdW5jdGlvbiBjcmVhdGVXYXRjaGVyICgKICAgIHZtLAogICAgZXhwT3JGbiwKICAgIGhhbmRsZXIsCiAgICBvcHRpb25zCiAgKSB7CiAgICBpZiAoaXNQbGFpbk9iamVjdChoYW5kbGVyKSkgewogICAgICBvcHRpb25zID0gaGFuZGxlcjsKICAgICAgaGFuZGxlciA9IGhhbmRsZXIuaGFuZGxlcjsKICAgIH0KICAgIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ3N0cmluZycpIHsKICAgICAgaGFuZGxlciA9IHZtW2hhbmRsZXJdOwogICAgfQogICAgcmV0dXJuIHZtLiR3YXRjaChleHBPckZuLCBoYW5kbGVyLCBvcHRpb25zKQogIH0KCiAgZnVuY3Rpb24gc3RhdGVNaXhpbiAoVnVlKSB7CiAgICAvLyBmbG93IHNvbWVob3cgaGFzIHByb2JsZW1zIHdpdGggZGlyZWN0bHkgZGVjbGFyZWQgZGVmaW5pdGlvbiBvYmplY3QKICAgIC8vIHdoZW4gdXNpbmcgT2JqZWN0LmRlZmluZVByb3BlcnR5LCBzbyB3ZSBoYXZlIHRvIHByb2NlZHVyYWxseSBidWlsZCB1cAogICAgLy8gdGhlIG9iamVjdCBoZXJlLgogICAgdmFyIGRhdGFEZWYgPSB7fTsKICAgIGRhdGFEZWYuZ2V0ID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5fZGF0YSB9OwogICAgdmFyIHByb3BzRGVmID0ge307CiAgICBwcm9wc0RlZi5nZXQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLl9wcm9wcyB9OwogICAgewogICAgICBkYXRhRGVmLnNldCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB3YXJuKAogICAgICAgICAgJ0F2b2lkIHJlcGxhY2luZyBpbnN0YW5jZSByb290ICRkYXRhLiAnICsKICAgICAgICAgICdVc2UgbmVzdGVkIGRhdGEgcHJvcGVydGllcyBpbnN0ZWFkLicsCiAgICAgICAgICB0aGlzCiAgICAgICAgKTsKICAgICAgfTsKICAgICAgcHJvcHNEZWYuc2V0ID0gZnVuY3Rpb24gKCkgewogICAgICAgIHdhcm4oIiRwcm9wcyBpcyByZWFkb25seS4iLCB0aGlzKTsKICAgICAgfTsKICAgIH0KICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShWdWUucHJvdG90eXBlLCAnJGRhdGEnLCBkYXRhRGVmKTsKICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShWdWUucHJvdG90eXBlLCAnJHByb3BzJywgcHJvcHNEZWYpOwoKICAgIFZ1ZS5wcm90b3R5cGUuJHNldCA9IHNldDsKICAgIFZ1ZS5wcm90b3R5cGUuJGRlbGV0ZSA9IGRlbDsKCiAgICBWdWUucHJvdG90eXBlLiR3YXRjaCA9IGZ1bmN0aW9uICgKICAgICAgZXhwT3JGbiwKICAgICAgY2IsCiAgICAgIG9wdGlvbnMKICAgICkgewogICAgICB2YXIgdm0gPSB0aGlzOwogICAgICBpZiAoaXNQbGFpbk9iamVjdChjYikpIHsKICAgICAgICByZXR1cm4gY3JlYXRlV2F0Y2hlcih2bSwgZXhwT3JGbiwgY2IsIG9wdGlvbnMpCiAgICAgIH0KICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgICAgIG9wdGlvbnMudXNlciA9IHRydWU7CiAgICAgIHZhciB3YXRjaGVyID0gbmV3IFdhdGNoZXIodm0sIGV4cE9yRm4sIGNiLCBvcHRpb25zKTsKICAgICAgaWYgKG9wdGlvbnMuaW1tZWRpYXRlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGNiLmNhbGwodm0sIHdhdGNoZXIudmFsdWUpOwogICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgICBoYW5kbGVFcnJvcihlcnJvciwgdm0sICgiY2FsbGJhY2sgZm9yIGltbWVkaWF0ZSB3YXRjaGVyIFwiIiArICh3YXRjaGVyLmV4cHJlc3Npb24pICsgIlwiIikpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gZnVuY3Rpb24gdW53YXRjaEZuICgpIHsKICAgICAgICB3YXRjaGVyLnRlYXJkb3duKCk7CiAgICAgIH0KICAgIH07CiAgfQoKICAvKiAgKi8KCiAgdmFyIHVpZCQzID0gMDsKCiAgZnVuY3Rpb24gaW5pdE1peGluIChWdWUpIHsKICAgIFZ1ZS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiAob3B0aW9ucykgewogICAgICB2YXIgdm0gPSB0aGlzOwogICAgICAvLyBhIHVpZAogICAgICB2bS5fdWlkID0gdWlkJDMrKzsKCiAgICAgIHZhciBzdGFydFRhZywgZW5kVGFnOwogICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgICAgaWYgKGNvbmZpZy5wZXJmb3JtYW5jZSAmJiBtYXJrKSB7CiAgICAgICAgc3RhcnRUYWcgPSAidnVlLXBlcmYtc3RhcnQ6IiArICh2bS5fdWlkKTsKICAgICAgICBlbmRUYWcgPSAidnVlLXBlcmYtZW5kOiIgKyAodm0uX3VpZCk7CiAgICAgICAgbWFyayhzdGFydFRhZyk7CiAgICAgIH0KCiAgICAgIC8vIGEgZmxhZyB0byBhdm9pZCB0aGlzIGJlaW5nIG9ic2VydmVkCiAgICAgIHZtLl9pc1Z1ZSA9IHRydWU7CiAgICAgIC8vIG1lcmdlIG9wdGlvbnMKICAgICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5faXNDb21wb25lbnQpIHsKICAgICAgICAvLyBvcHRpbWl6ZSBpbnRlcm5hbCBjb21wb25lbnQgaW5zdGFudGlhdGlvbgogICAgICAgIC8vIHNpbmNlIGR5bmFtaWMgb3B0aW9ucyBtZXJnaW5nIGlzIHByZXR0eSBzbG93LCBhbmQgbm9uZSBvZiB0aGUKICAgICAgICAvLyBpbnRlcm5hbCBjb21wb25lbnQgb3B0aW9ucyBuZWVkcyBzcGVjaWFsIHRyZWF0bWVudC4KICAgICAgICBpbml0SW50ZXJuYWxDb21wb25lbnQodm0sIG9wdGlvbnMpOwogICAgICB9IGVsc2UgewogICAgICAgIHZtLiRvcHRpb25zID0gbWVyZ2VPcHRpb25zKAogICAgICAgICAgcmVzb2x2ZUNvbnN0cnVjdG9yT3B0aW9ucyh2bS5jb25zdHJ1Y3RvciksCiAgICAgICAgICBvcHRpb25zIHx8IHt9LAogICAgICAgICAgdm0KICAgICAgICApOwogICAgICB9CiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovCiAgICAgIHsKICAgICAgICBpbml0UHJveHkodm0pOwogICAgICB9CiAgICAgIC8vIGV4cG9zZSByZWFsIHNlbGYKICAgICAgdm0uX3NlbGYgPSB2bTsKICAgICAgaW5pdExpZmVjeWNsZSh2bSk7CiAgICAgIGluaXRFdmVudHModm0pOwogICAgICBpbml0UmVuZGVyKHZtKTsKICAgICAgY2FsbEhvb2sodm0sICdiZWZvcmVDcmVhdGUnKTsKICAgICAgaW5pdEluamVjdGlvbnModm0pOyAvLyByZXNvbHZlIGluamVjdGlvbnMgYmVmb3JlIGRhdGEvcHJvcHMKICAgICAgaW5pdFN0YXRlKHZtKTsKICAgICAgaW5pdFByb3ZpZGUodm0pOyAvLyByZXNvbHZlIHByb3ZpZGUgYWZ0ZXIgZGF0YS9wcm9wcwogICAgICBjYWxsSG9vayh2bSwgJ2NyZWF0ZWQnKTsKCiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgICBpZiAoY29uZmlnLnBlcmZvcm1hbmNlICYmIG1hcmspIHsKICAgICAgICB2bS5fbmFtZSA9IGZvcm1hdENvbXBvbmVudE5hbWUodm0sIGZhbHNlKTsKICAgICAgICBtYXJrKGVuZFRhZyk7CiAgICAgICAgbWVhc3VyZSgoInZ1ZSAiICsgKHZtLl9uYW1lKSArICIgaW5pdCIpLCBzdGFydFRhZywgZW5kVGFnKTsKICAgICAgfQoKICAgICAgaWYgKHZtLiRvcHRpb25zLmVsKSB7CiAgICAgICAgdm0uJG1vdW50KHZtLiRvcHRpb25zLmVsKTsKICAgICAgfQogICAgfTsKICB9CgogIGZ1bmN0aW9uIGluaXRJbnRlcm5hbENvbXBvbmVudCAodm0sIG9wdGlvbnMpIHsKICAgIHZhciBvcHRzID0gdm0uJG9wdGlvbnMgPSBPYmplY3QuY3JlYXRlKHZtLmNvbnN0cnVjdG9yLm9wdGlvbnMpOwogICAgLy8gZG9pbmcgdGhpcyBiZWNhdXNlIGl0J3MgZmFzdGVyIHRoYW4gZHluYW1pYyBlbnVtZXJhdGlvbi4KICAgIHZhciBwYXJlbnRWbm9kZSA9IG9wdGlvbnMuX3BhcmVudFZub2RlOwogICAgb3B0cy5wYXJlbnQgPSBvcHRpb25zLnBhcmVudDsKICAgIG9wdHMuX3BhcmVudFZub2RlID0gcGFyZW50Vm5vZGU7CgogICAgdmFyIHZub2RlQ29tcG9uZW50T3B0aW9ucyA9IHBhcmVudFZub2RlLmNvbXBvbmVudE9wdGlvbnM7CiAgICBvcHRzLnByb3BzRGF0YSA9IHZub2RlQ29tcG9uZW50T3B0aW9ucy5wcm9wc0RhdGE7CiAgICBvcHRzLl9wYXJlbnRMaXN0ZW5lcnMgPSB2bm9kZUNvbXBvbmVudE9wdGlvbnMubGlzdGVuZXJzOwogICAgb3B0cy5fcmVuZGVyQ2hpbGRyZW4gPSB2bm9kZUNvbXBvbmVudE9wdGlvbnMuY2hpbGRyZW47CiAgICBvcHRzLl9jb21wb25lbnRUYWcgPSB2bm9kZUNvbXBvbmVudE9wdGlvbnMudGFnOwoKICAgIGlmIChvcHRpb25zLnJlbmRlcikgewogICAgICBvcHRzLnJlbmRlciA9IG9wdGlvbnMucmVuZGVyOwogICAgICBvcHRzLnN0YXRpY1JlbmRlckZucyA9IG9wdGlvbnMuc3RhdGljUmVuZGVyRm5zOwogICAgfQogIH0KCiAgZnVuY3Rpb24gcmVzb2x2ZUNvbnN0cnVjdG9yT3B0aW9ucyAoQ3RvcikgewogICAgdmFyIG9wdGlvbnMgPSBDdG9yLm9wdGlvbnM7CiAgICBpZiAoQ3Rvci5zdXBlcikgewogICAgICB2YXIgc3VwZXJPcHRpb25zID0gcmVzb2x2ZUNvbnN0cnVjdG9yT3B0aW9ucyhDdG9yLnN1cGVyKTsKICAgICAgdmFyIGNhY2hlZFN1cGVyT3B0aW9ucyA9IEN0b3Iuc3VwZXJPcHRpb25zOwogICAgICBpZiAoc3VwZXJPcHRpb25zICE9PSBjYWNoZWRTdXBlck9wdGlvbnMpIHsKICAgICAgICAvLyBzdXBlciBvcHRpb24gY2hhbmdlZCwKICAgICAgICAvLyBuZWVkIHRvIHJlc29sdmUgbmV3IG9wdGlvbnMuCiAgICAgICAgQ3Rvci5zdXBlck9wdGlvbnMgPSBzdXBlck9wdGlvbnM7CiAgICAgICAgLy8gY2hlY2sgaWYgdGhlcmUgYXJlIGFueSBsYXRlLW1vZGlmaWVkL2F0dGFjaGVkIG9wdGlvbnMgKCM0OTc2KQogICAgICAgIHZhciBtb2RpZmllZE9wdGlvbnMgPSByZXNvbHZlTW9kaWZpZWRPcHRpb25zKEN0b3IpOwogICAgICAgIC8vIHVwZGF0ZSBiYXNlIGV4dGVuZCBvcHRpb25zCiAgICAgICAgaWYgKG1vZGlmaWVkT3B0aW9ucykgewogICAgICAgICAgZXh0ZW5kKEN0b3IuZXh0ZW5kT3B0aW9ucywgbW9kaWZpZWRPcHRpb25zKTsKICAgICAgICB9CiAgICAgICAgb3B0aW9ucyA9IEN0b3Iub3B0aW9ucyA9IG1lcmdlT3B0aW9ucyhzdXBlck9wdGlvbnMsIEN0b3IuZXh0ZW5kT3B0aW9ucyk7CiAgICAgICAgaWYgKG9wdGlvbnMubmFtZSkgewogICAgICAgICAgb3B0aW9ucy5jb21wb25lbnRzW29wdGlvbnMubmFtZV0gPSBDdG9yOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIG9wdGlvbnMKICB9CgogIGZ1bmN0aW9uIHJlc29sdmVNb2RpZmllZE9wdGlvbnMgKEN0b3IpIHsKICAgIHZhciBtb2RpZmllZDsKICAgIHZhciBsYXRlc3QgPSBDdG9yLm9wdGlvbnM7CiAgICB2YXIgc2VhbGVkID0gQ3Rvci5zZWFsZWRPcHRpb25zOwogICAgZm9yICh2YXIga2V5IGluIGxhdGVzdCkgewogICAgICBpZiAobGF0ZXN0W2tleV0gIT09IHNlYWxlZFtrZXldKSB7CiAgICAgICAgaWYgKCFtb2RpZmllZCkgeyBtb2RpZmllZCA9IHt9OyB9CiAgICAgICAgbW9kaWZpZWRba2V5XSA9IGxhdGVzdFtrZXldOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gbW9kaWZpZWQKICB9CgogIGZ1bmN0aW9uIFZ1ZSAob3B0aW9ucykgewogICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFZ1ZSkKICAgICkgewogICAgICB3YXJuKCdWdWUgaXMgYSBjb25zdHJ1Y3RvciBhbmQgc2hvdWxkIGJlIGNhbGxlZCB3aXRoIHRoZSBgbmV3YCBrZXl3b3JkJyk7CiAgICB9CiAgICB0aGlzLl9pbml0KG9wdGlvbnMpOwogIH0KCiAgaW5pdE1peGluKFZ1ZSk7CiAgc3RhdGVNaXhpbihWdWUpOwogIGV2ZW50c01peGluKFZ1ZSk7CiAgbGlmZWN5Y2xlTWl4aW4oVnVlKTsKICByZW5kZXJNaXhpbihWdWUpOwoKICAvKiAgKi8KCiAgZnVuY3Rpb24gaW5pdFVzZSAoVnVlKSB7CiAgICBWdWUudXNlID0gZnVuY3Rpb24gKHBsdWdpbikgewogICAgICB2YXIgaW5zdGFsbGVkUGx1Z2lucyA9ICh0aGlzLl9pbnN0YWxsZWRQbHVnaW5zIHx8ICh0aGlzLl9pbnN0YWxsZWRQbHVnaW5zID0gW10pKTsKICAgICAgaWYgKGluc3RhbGxlZFBsdWdpbnMuaW5kZXhPZihwbHVnaW4pID4gLTEpIHsKICAgICAgICByZXR1cm4gdGhpcwogICAgICB9CgogICAgICAvLyBhZGRpdGlvbmFsIHBhcmFtZXRlcnMKICAgICAgdmFyIGFyZ3MgPSB0b0FycmF5KGFyZ3VtZW50cywgMSk7CiAgICAgIGFyZ3MudW5zaGlmdCh0aGlzKTsKICAgICAgaWYgKHR5cGVvZiBwbHVnaW4uaW5zdGFsbCA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgIHBsdWdpbi5pbnN0YWxsLmFwcGx5KHBsdWdpbiwgYXJncyk7CiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHBsdWdpbiA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgIHBsdWdpbi5hcHBseShudWxsLCBhcmdzKTsKICAgICAgfQogICAgICBpbnN0YWxsZWRQbHVnaW5zLnB1c2gocGx1Z2luKTsKICAgICAgcmV0dXJuIHRoaXMKICAgIH07CiAgfQoKICAvKiAgKi8KCiAgZnVuY3Rpb24gaW5pdE1peGluJDEgKFZ1ZSkgewogICAgVnVlLm1peGluID0gZnVuY3Rpb24gKG1peGluKSB7CiAgICAgIHRoaXMub3B0aW9ucyA9IG1lcmdlT3B0aW9ucyh0aGlzLm9wdGlvbnMsIG1peGluKTsKICAgICAgcmV0dXJuIHRoaXMKICAgIH07CiAgfQoKICAvKiAgKi8KCiAgZnVuY3Rpb24gaW5pdEV4dGVuZCAoVnVlKSB7CiAgICAvKioKICAgICAqIEVhY2ggaW5zdGFuY2UgY29uc3RydWN0b3IsIGluY2x1ZGluZyBWdWUsIGhhcyBhIHVuaXF1ZQogICAgICogY2lkLiBUaGlzIGVuYWJsZXMgdXMgdG8gY3JlYXRlIHdyYXBwZWQgImNoaWxkCiAgICAgKiBjb25zdHJ1Y3RvcnMiIGZvciBwcm90b3R5cGFsIGluaGVyaXRhbmNlIGFuZCBjYWNoZSB0aGVtLgogICAgICovCiAgICBWdWUuY2lkID0gMDsKICAgIHZhciBjaWQgPSAxOwoKICAgIC8qKgogICAgICogQ2xhc3MgaW5oZXJpdGFuY2UKICAgICAqLwogICAgVnVlLmV4dGVuZCA9IGZ1bmN0aW9uIChleHRlbmRPcHRpb25zKSB7CiAgICAgIGV4dGVuZE9wdGlvbnMgPSBleHRlbmRPcHRpb25zIHx8IHt9OwogICAgICB2YXIgU3VwZXIgPSB0aGlzOwogICAgICB2YXIgU3VwZXJJZCA9IFN1cGVyLmNpZDsKICAgICAgdmFyIGNhY2hlZEN0b3JzID0gZXh0ZW5kT3B0aW9ucy5fQ3RvciB8fCAoZXh0ZW5kT3B0aW9ucy5fQ3RvciA9IHt9KTsKICAgICAgaWYgKGNhY2hlZEN0b3JzW1N1cGVySWRdKSB7CiAgICAgICAgcmV0dXJuIGNhY2hlZEN0b3JzW1N1cGVySWRdCiAgICAgIH0KCiAgICAgIHZhciBuYW1lID0gZXh0ZW5kT3B0aW9ucy5uYW1lIHx8IFN1cGVyLm9wdGlvbnMubmFtZTsKICAgICAgaWYgKG5hbWUpIHsKICAgICAgICB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZSk7CiAgICAgIH0KCiAgICAgIHZhciBTdWIgPSBmdW5jdGlvbiBWdWVDb21wb25lbnQgKG9wdGlvbnMpIHsKICAgICAgICB0aGlzLl9pbml0KG9wdGlvbnMpOwogICAgICB9OwogICAgICBTdWIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShTdXBlci5wcm90b3R5cGUpOwogICAgICBTdWIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gU3ViOwogICAgICBTdWIuY2lkID0gY2lkKys7CiAgICAgIFN1Yi5vcHRpb25zID0gbWVyZ2VPcHRpb25zKAogICAgICAgIFN1cGVyLm9wdGlvbnMsCiAgICAgICAgZXh0ZW5kT3B0aW9ucwogICAgICApOwogICAgICBTdWJbJ3N1cGVyJ10gPSBTdXBlcjsKCiAgICAgIC8vIEZvciBwcm9wcyBhbmQgY29tcHV0ZWQgcHJvcGVydGllcywgd2UgZGVmaW5lIHRoZSBwcm94eSBnZXR0ZXJzIG9uCiAgICAgIC8vIHRoZSBWdWUgaW5zdGFuY2VzIGF0IGV4dGVuc2lvbiB0aW1lLCBvbiB0aGUgZXh0ZW5kZWQgcHJvdG90eXBlLiBUaGlzCiAgICAgIC8vIGF2b2lkcyBPYmplY3QuZGVmaW5lUHJvcGVydHkgY2FsbHMgZm9yIGVhY2ggaW5zdGFuY2UgY3JlYXRlZC4KICAgICAgaWYgKFN1Yi5vcHRpb25zLnByb3BzKSB7CiAgICAgICAgaW5pdFByb3BzJDEoU3ViKTsKICAgICAgfQogICAgICBpZiAoU3ViLm9wdGlvbnMuY29tcHV0ZWQpIHsKICAgICAgICBpbml0Q29tcHV0ZWQkMShTdWIpOwogICAgICB9CgogICAgICAvLyBhbGxvdyBmdXJ0aGVyIGV4dGVuc2lvbi9taXhpbi9wbHVnaW4gdXNhZ2UKICAgICAgU3ViLmV4dGVuZCA9IFN1cGVyLmV4dGVuZDsKICAgICAgU3ViLm1peGluID0gU3VwZXIubWl4aW47CiAgICAgIFN1Yi51c2UgPSBTdXBlci51c2U7CgogICAgICAvLyBjcmVhdGUgYXNzZXQgcmVnaXN0ZXJzLCBzbyBleHRlbmRlZCBjbGFzc2VzCiAgICAgIC8vIGNhbiBoYXZlIHRoZWlyIHByaXZhdGUgYXNzZXRzIHRvby4KICAgICAgQVNTRVRfVFlQRVMuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkgewogICAgICAgIFN1Ylt0eXBlXSA9IFN1cGVyW3R5cGVdOwogICAgICB9KTsKICAgICAgLy8gZW5hYmxlIHJlY3Vyc2l2ZSBzZWxmLWxvb2t1cAogICAgICBpZiAobmFtZSkgewogICAgICAgIFN1Yi5vcHRpb25zLmNvbXBvbmVudHNbbmFtZV0gPSBTdWI7CiAgICAgIH0KCiAgICAgIC8vIGtlZXAgYSByZWZlcmVuY2UgdG8gdGhlIHN1cGVyIG9wdGlvbnMgYXQgZXh0ZW5zaW9uIHRpbWUuCiAgICAgIC8vIGxhdGVyIGF0IGluc3RhbnRpYXRpb24gd2UgY2FuIGNoZWNrIGlmIFN1cGVyJ3Mgb3B0aW9ucyBoYXZlCiAgICAgIC8vIGJlZW4gdXBkYXRlZC4KICAgICAgU3ViLnN1cGVyT3B0aW9ucyA9IFN1cGVyLm9wdGlvbnM7CiAgICAgIFN1Yi5leHRlbmRPcHRpb25zID0gZXh0ZW5kT3B0aW9uczsKICAgICAgU3ViLnNlYWxlZE9wdGlvbnMgPSBleHRlbmQoe30sIFN1Yi5vcHRpb25zKTsKCiAgICAgIC8vIGNhY2hlIGNvbnN0cnVjdG9yCiAgICAgIGNhY2hlZEN0b3JzW1N1cGVySWRdID0gU3ViOwogICAgICByZXR1cm4gU3ViCiAgICB9OwogIH0KCiAgZnVuY3Rpb24gaW5pdFByb3BzJDEgKENvbXApIHsKICAgIHZhciBwcm9wcyA9IENvbXAub3B0aW9ucy5wcm9wczsKICAgIGZvciAodmFyIGtleSBpbiBwcm9wcykgewogICAgICBwcm94eShDb21wLnByb3RvdHlwZSwgIl9wcm9wcyIsIGtleSk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBpbml0Q29tcHV0ZWQkMSAoQ29tcCkgewogICAgdmFyIGNvbXB1dGVkID0gQ29tcC5vcHRpb25zLmNvbXB1dGVkOwogICAgZm9yICh2YXIga2V5IGluIGNvbXB1dGVkKSB7CiAgICAgIGRlZmluZUNvbXB1dGVkKENvbXAucHJvdG90eXBlLCBrZXksIGNvbXB1dGVkW2tleV0pOwogICAgfQogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIGluaXRBc3NldFJlZ2lzdGVycyAoVnVlKSB7CiAgICAvKioKICAgICAqIENyZWF0ZSBhc3NldCByZWdpc3RyYXRpb24gbWV0aG9kcy4KICAgICAqLwogICAgQVNTRVRfVFlQRVMuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkgewogICAgICBWdWVbdHlwZV0gPSBmdW5jdGlvbiAoCiAgICAgICAgaWQsCiAgICAgICAgZGVmaW5pdGlvbgogICAgICApIHsKICAgICAgICBpZiAoIWRlZmluaXRpb24pIHsKICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnNbdHlwZSArICdzJ11baWRdCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgICAgICAgaWYgKHR5cGUgPT09ICdjb21wb25lbnQnKSB7CiAgICAgICAgICAgIHZhbGlkYXRlQ29tcG9uZW50TmFtZShpZCk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAodHlwZSA9PT0gJ2NvbXBvbmVudCcgJiYgaXNQbGFpbk9iamVjdChkZWZpbml0aW9uKSkgewogICAgICAgICAgICBkZWZpbml0aW9uLm5hbWUgPSBkZWZpbml0aW9uLm5hbWUgfHwgaWQ7CiAgICAgICAgICAgIGRlZmluaXRpb24gPSB0aGlzLm9wdGlvbnMuX2Jhc2UuZXh0ZW5kKGRlZmluaXRpb24pOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHR5cGUgPT09ICdkaXJlY3RpdmUnICYmIHR5cGVvZiBkZWZpbml0aW9uID09PSAnZnVuY3Rpb24nKSB7CiAgICAgICAgICAgIGRlZmluaXRpb24gPSB7IGJpbmQ6IGRlZmluaXRpb24sIHVwZGF0ZTogZGVmaW5pdGlvbiB9OwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5vcHRpb25zW3R5cGUgKyAncyddW2lkXSA9IGRlZmluaXRpb247CiAgICAgICAgICByZXR1cm4gZGVmaW5pdGlvbgogICAgICAgIH0KICAgICAgfTsKICAgIH0pOwogIH0KCiAgLyogICovCgoKCiAgZnVuY3Rpb24gZ2V0Q29tcG9uZW50TmFtZSAob3B0cykgewogICAgcmV0dXJuIG9wdHMgJiYgKG9wdHMuQ3Rvci5vcHRpb25zLm5hbWUgfHwgb3B0cy50YWcpCiAgfQoKICBmdW5jdGlvbiBtYXRjaGVzIChwYXR0ZXJuLCBuYW1lKSB7CiAgICBpZiAoQXJyYXkuaXNBcnJheShwYXR0ZXJuKSkgewogICAgICByZXR1cm4gcGF0dGVybi5pbmRleE9mKG5hbWUpID4gLTEKICAgIH0gZWxzZSBpZiAodHlwZW9mIHBhdHRlcm4gPT09ICdzdHJpbmcnKSB7CiAgICAgIHJldHVybiBwYXR0ZXJuLnNwbGl0KCcsJykuaW5kZXhPZihuYW1lKSA+IC0xCiAgICB9IGVsc2UgaWYgKGlzUmVnRXhwKHBhdHRlcm4pKSB7CiAgICAgIHJldHVybiBwYXR0ZXJuLnRlc3QobmFtZSkKICAgIH0KICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovCiAgICByZXR1cm4gZmFsc2UKICB9CgogIGZ1bmN0aW9uIHBydW5lQ2FjaGUgKGtlZXBBbGl2ZUluc3RhbmNlLCBmaWx0ZXIpIHsKICAgIHZhciBjYWNoZSA9IGtlZXBBbGl2ZUluc3RhbmNlLmNhY2hlOwogICAgdmFyIGtleXMgPSBrZWVwQWxpdmVJbnN0YW5jZS5rZXlzOwogICAgdmFyIF92bm9kZSA9IGtlZXBBbGl2ZUluc3RhbmNlLl92bm9kZTsKICAgIGZvciAodmFyIGtleSBpbiBjYWNoZSkgewogICAgICB2YXIgY2FjaGVkTm9kZSA9IGNhY2hlW2tleV07CiAgICAgIGlmIChjYWNoZWROb2RlKSB7CiAgICAgICAgdmFyIG5hbWUgPSBnZXRDb21wb25lbnROYW1lKGNhY2hlZE5vZGUuY29tcG9uZW50T3B0aW9ucyk7CiAgICAgICAgaWYgKG5hbWUgJiYgIWZpbHRlcihuYW1lKSkgewogICAgICAgICAgcHJ1bmVDYWNoZUVudHJ5KGNhY2hlLCBrZXksIGtleXMsIF92bm9kZSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICBmdW5jdGlvbiBwcnVuZUNhY2hlRW50cnkgKAogICAgY2FjaGUsCiAgICBrZXksCiAgICBrZXlzLAogICAgY3VycmVudAogICkgewogICAgdmFyIGNhY2hlZCQkMSA9IGNhY2hlW2tleV07CiAgICBpZiAoY2FjaGVkJCQxICYmICghY3VycmVudCB8fCBjYWNoZWQkJDEudGFnICE9PSBjdXJyZW50LnRhZykpIHsKICAgICAgY2FjaGVkJCQxLmNvbXBvbmVudEluc3RhbmNlLiRkZXN0cm95KCk7CiAgICB9CiAgICBjYWNoZVtrZXldID0gbnVsbDsKICAgIHJlbW92ZShrZXlzLCBrZXkpOwogIH0KCiAgdmFyIHBhdHRlcm5UeXBlcyA9IFtTdHJpbmcsIFJlZ0V4cCwgQXJyYXldOwoKICB2YXIgS2VlcEFsaXZlID0gewogICAgbmFtZTogJ2tlZXAtYWxpdmUnLAogICAgYWJzdHJhY3Q6IHRydWUsCgogICAgcHJvcHM6IHsKICAgICAgaW5jbHVkZTogcGF0dGVyblR5cGVzLAogICAgICBleGNsdWRlOiBwYXR0ZXJuVHlwZXMsCiAgICAgIG1heDogW1N0cmluZywgTnVtYmVyXQogICAgfSwKCiAgICBjcmVhdGVkOiBmdW5jdGlvbiBjcmVhdGVkICgpIHsKICAgICAgdGhpcy5jYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7CiAgICAgIHRoaXMua2V5cyA9IFtdOwogICAgfSwKCiAgICBkZXN0cm95ZWQ6IGZ1bmN0aW9uIGRlc3Ryb3llZCAoKSB7CiAgICAgIGZvciAodmFyIGtleSBpbiB0aGlzLmNhY2hlKSB7CiAgICAgICAgcHJ1bmVDYWNoZUVudHJ5KHRoaXMuY2FjaGUsIGtleSwgdGhpcy5rZXlzKTsKICAgICAgfQogICAgfSwKCiAgICBtb3VudGVkOiBmdW5jdGlvbiBtb3VudGVkICgpIHsKICAgICAgdmFyIHRoaXMkMSA9IHRoaXM7CgogICAgICB0aGlzLiR3YXRjaCgnaW5jbHVkZScsIGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICBwcnVuZUNhY2hlKHRoaXMkMSwgZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuIG1hdGNoZXModmFsLCBuYW1lKTsgfSk7CiAgICAgIH0pOwogICAgICB0aGlzLiR3YXRjaCgnZXhjbHVkZScsIGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICBwcnVuZUNhY2hlKHRoaXMkMSwgZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuICFtYXRjaGVzKHZhbCwgbmFtZSk7IH0pOwogICAgICB9KTsKICAgIH0sCgogICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIgKCkgewogICAgICB2YXIgc2xvdCA9IHRoaXMuJHNsb3RzLmRlZmF1bHQ7CiAgICAgIHZhciB2bm9kZSA9IGdldEZpcnN0Q29tcG9uZW50Q2hpbGQoc2xvdCk7CiAgICAgIHZhciBjb21wb25lbnRPcHRpb25zID0gdm5vZGUgJiYgdm5vZGUuY29tcG9uZW50T3B0aW9uczsKICAgICAgaWYgKGNvbXBvbmVudE9wdGlvbnMpIHsKICAgICAgICAvLyBjaGVjayBwYXR0ZXJuCiAgICAgICAgdmFyIG5hbWUgPSBnZXRDb21wb25lbnROYW1lKGNvbXBvbmVudE9wdGlvbnMpOwogICAgICAgIHZhciByZWYgPSB0aGlzOwogICAgICAgIHZhciBpbmNsdWRlID0gcmVmLmluY2x1ZGU7CiAgICAgICAgdmFyIGV4Y2x1ZGUgPSByZWYuZXhjbHVkZTsKICAgICAgICBpZiAoCiAgICAgICAgICAvLyBub3QgaW5jbHVkZWQKICAgICAgICAgIChpbmNsdWRlICYmICghbmFtZSB8fCAhbWF0Y2hlcyhpbmNsdWRlLCBuYW1lKSkpIHx8CiAgICAgICAgICAvLyBleGNsdWRlZAogICAgICAgICAgKGV4Y2x1ZGUgJiYgbmFtZSAmJiBtYXRjaGVzKGV4Y2x1ZGUsIG5hbWUpKQogICAgICAgICkgewogICAgICAgICAgcmV0dXJuIHZub2RlCiAgICAgICAgfQoKICAgICAgICB2YXIgcmVmJDEgPSB0aGlzOwogICAgICAgIHZhciBjYWNoZSA9IHJlZiQxLmNhY2hlOwogICAgICAgIHZhciBrZXlzID0gcmVmJDEua2V5czsKICAgICAgICB2YXIga2V5ID0gdm5vZGUua2V5ID09IG51bGwKICAgICAgICAgIC8vIHNhbWUgY29uc3RydWN0b3IgbWF5IGdldCByZWdpc3RlcmVkIGFzIGRpZmZlcmVudCBsb2NhbCBjb21wb25lbnRzCiAgICAgICAgICAvLyBzbyBjaWQgYWxvbmUgaXMgbm90IGVub3VnaCAoIzMyNjkpCiAgICAgICAgICA/IGNvbXBvbmVudE9wdGlvbnMuQ3Rvci5jaWQgKyAoY29tcG9uZW50T3B0aW9ucy50YWcgPyAoIjo6IiArIChjb21wb25lbnRPcHRpb25zLnRhZykpIDogJycpCiAgICAgICAgICA6IHZub2RlLmtleTsKICAgICAgICBpZiAoY2FjaGVba2V5XSkgewogICAgICAgICAgdm5vZGUuY29tcG9uZW50SW5zdGFuY2UgPSBjYWNoZVtrZXldLmNvbXBvbmVudEluc3RhbmNlOwogICAgICAgICAgLy8gbWFrZSBjdXJyZW50IGtleSBmcmVzaGVzdAogICAgICAgICAgcmVtb3ZlKGtleXMsIGtleSk7CiAgICAgICAgICBrZXlzLnB1c2goa2V5KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2FjaGVba2V5XSA9IHZub2RlOwogICAgICAgICAga2V5cy5wdXNoKGtleSk7CiAgICAgICAgICAvLyBwcnVuZSBvbGRlc3QgZW50cnkKICAgICAgICAgIGlmICh0aGlzLm1heCAmJiBrZXlzLmxlbmd0aCA+IHBhcnNlSW50KHRoaXMubWF4KSkgewogICAgICAgICAgICBwcnVuZUNhY2hlRW50cnkoY2FjaGUsIGtleXNbMF0sIGtleXMsIHRoaXMuX3Zub2RlKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHZub2RlLmRhdGEua2VlcEFsaXZlID0gdHJ1ZTsKICAgICAgfQogICAgICByZXR1cm4gdm5vZGUgfHwgKHNsb3QgJiYgc2xvdFswXSkKICAgIH0KICB9OwoKICB2YXIgYnVpbHRJbkNvbXBvbmVudHMgPSB7CiAgICBLZWVwQWxpdmU6IEtlZXBBbGl2ZQogIH07CgogIC8qICAqLwoKICBmdW5jdGlvbiBpbml0R2xvYmFsQVBJIChWdWUpIHsKICAgIC8vIGNvbmZpZwogICAgdmFyIGNvbmZpZ0RlZiA9IHt9OwogICAgY29uZmlnRGVmLmdldCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbmZpZzsgfTsKICAgIHsKICAgICAgY29uZmlnRGVmLnNldCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB3YXJuKAogICAgICAgICAgJ0RvIG5vdCByZXBsYWNlIHRoZSBWdWUuY29uZmlnIG9iamVjdCwgc2V0IGluZGl2aWR1YWwgZmllbGRzIGluc3RlYWQuJwogICAgICAgICk7CiAgICAgIH07CiAgICB9CiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVnVlLCAnY29uZmlnJywgY29uZmlnRGVmKTsKCiAgICAvLyBleHBvc2VkIHV0aWwgbWV0aG9kcy4KICAgIC8vIE5PVEU6IHRoZXNlIGFyZSBub3QgY29uc2lkZXJlZCBwYXJ0IG9mIHRoZSBwdWJsaWMgQVBJIC0gYXZvaWQgcmVseWluZyBvbgogICAgLy8gdGhlbSB1bmxlc3MgeW91IGFyZSBhd2FyZSBvZiB0aGUgcmlzay4KICAgIFZ1ZS51dGlsID0gewogICAgICB3YXJuOiB3YXJuLAogICAgICBleHRlbmQ6IGV4dGVuZCwKICAgICAgbWVyZ2VPcHRpb25zOiBtZXJnZU9wdGlvbnMsCiAgICAgIGRlZmluZVJlYWN0aXZlOiBkZWZpbmVSZWFjdGl2ZSQkMQogICAgfTsKCiAgICBWdWUuc2V0ID0gc2V0OwogICAgVnVlLmRlbGV0ZSA9IGRlbDsKICAgIFZ1ZS5uZXh0VGljayA9IG5leHRUaWNrOwoKICAgIC8vIDIuNiBleHBsaWNpdCBvYnNlcnZhYmxlIEFQSQogICAgVnVlLm9ic2VydmFibGUgPSBmdW5jdGlvbiAob2JqKSB7CiAgICAgIG9ic2VydmUob2JqKTsKICAgICAgcmV0dXJuIG9iagogICAgfTsKCiAgICBWdWUub3B0aW9ucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7CiAgICBBU1NFVF9UWVBFUy5mb3JFYWNoKGZ1bmN0aW9uICh0eXBlKSB7CiAgICAgIFZ1ZS5vcHRpb25zW3R5cGUgKyAncyddID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKICAgIH0pOwoKICAgIC8vIHRoaXMgaXMgdXNlZCB0byBpZGVudGlmeSB0aGUgImJhc2UiIGNvbnN0cnVjdG9yIHRvIGV4dGVuZCBhbGwgcGxhaW4tb2JqZWN0CiAgICAvLyBjb21wb25lbnRzIHdpdGggaW4gV2VleCdzIG11bHRpLWluc3RhbmNlIHNjZW5hcmlvcy4KICAgIFZ1ZS5vcHRpb25zLl9iYXNlID0gVnVlOwoKICAgIGV4dGVuZChWdWUub3B0aW9ucy5jb21wb25lbnRzLCBidWlsdEluQ29tcG9uZW50cyk7CgogICAgaW5pdFVzZShWdWUpOwogICAgaW5pdE1peGluJDEoVnVlKTsKICAgIGluaXRFeHRlbmQoVnVlKTsKICAgIGluaXRBc3NldFJlZ2lzdGVycyhWdWUpOwogIH0KCiAgaW5pdEdsb2JhbEFQSShWdWUpOwoKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVnVlLnByb3RvdHlwZSwgJyRpc1NlcnZlcicsIHsKICAgIGdldDogaXNTZXJ2ZXJSZW5kZXJpbmcKICB9KTsKCiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZS5wcm90b3R5cGUsICckc3NyQ29udGV4dCcsIHsKICAgIGdldDogZnVuY3Rpb24gZ2V0ICgpIHsKICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8KICAgICAgcmV0dXJuIHRoaXMuJHZub2RlICYmIHRoaXMuJHZub2RlLnNzckNvbnRleHQKICAgIH0KICB9KTsKCiAgLy8gZXhwb3NlIEZ1bmN0aW9uYWxSZW5kZXJDb250ZXh0IGZvciBzc3IgcnVudGltZSBoZWxwZXIgaW5zdGFsbGF0aW9uCiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZSwgJ0Z1bmN0aW9uYWxSZW5kZXJDb250ZXh0JywgewogICAgdmFsdWU6IEZ1bmN0aW9uYWxSZW5kZXJDb250ZXh0CiAgfSk7CgogIFZ1ZS52ZXJzaW9uID0gJzIuNi4xMCc7CgogIC8qICAqLwoKICAvLyB0aGVzZSBhcmUgcmVzZXJ2ZWQgZm9yIHdlYiBiZWNhdXNlIHRoZXkgYXJlIGRpcmVjdGx5IGNvbXBpbGVkIGF3YXkKICAvLyBkdXJpbmcgdGVtcGxhdGUgY29tcGlsYXRpb24KICB2YXIgaXNSZXNlcnZlZEF0dHIgPSBtYWtlTWFwKCdzdHlsZSxjbGFzcycpOwoKICAvLyBhdHRyaWJ1dGVzIHRoYXQgc2hvdWxkIGJlIHVzaW5nIHByb3BzIGZvciBiaW5kaW5nCiAgdmFyIGFjY2VwdFZhbHVlID0gbWFrZU1hcCgnaW5wdXQsdGV4dGFyZWEsb3B0aW9uLHNlbGVjdCxwcm9ncmVzcycpOwogIHZhciBtdXN0VXNlUHJvcCA9IGZ1bmN0aW9uICh0YWcsIHR5cGUsIGF0dHIpIHsKICAgIHJldHVybiAoCiAgICAgIChhdHRyID09PSAndmFsdWUnICYmIGFjY2VwdFZhbHVlKHRhZykpICYmIHR5cGUgIT09ICdidXR0b24nIHx8CiAgICAgIChhdHRyID09PSAnc2VsZWN0ZWQnICYmIHRhZyA9PT0gJ29wdGlvbicpIHx8CiAgICAgIChhdHRyID09PSAnY2hlY2tlZCcgJiYgdGFnID09PSAnaW5wdXQnKSB8fAogICAgICAoYXR0ciA9PT0gJ211dGVkJyAmJiB0YWcgPT09ICd2aWRlbycpCiAgICApCiAgfTsKCiAgdmFyIGlzRW51bWVyYXRlZEF0dHIgPSBtYWtlTWFwKCdjb250ZW50ZWRpdGFibGUsZHJhZ2dhYmxlLHNwZWxsY2hlY2snKTsKCiAgdmFyIGlzVmFsaWRDb250ZW50RWRpdGFibGVWYWx1ZSA9IG1ha2VNYXAoJ2V2ZW50cyxjYXJldCx0eXBpbmcscGxhaW50ZXh0LW9ubHknKTsKCiAgdmFyIGNvbnZlcnRFbnVtZXJhdGVkVmFsdWUgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkgewogICAgcmV0dXJuIGlzRmFsc3lBdHRyVmFsdWUodmFsdWUpIHx8IHZhbHVlID09PSAnZmFsc2UnCiAgICAgID8gJ2ZhbHNlJwogICAgICAvLyBhbGxvdyBhcmJpdHJhcnkgc3RyaW5nIHZhbHVlIGZvciBjb250ZW50ZWRpdGFibGUKICAgICAgOiBrZXkgPT09ICdjb250ZW50ZWRpdGFibGUnICYmIGlzVmFsaWRDb250ZW50RWRpdGFibGVWYWx1ZSh2YWx1ZSkKICAgICAgICA/IHZhbHVlCiAgICAgICAgOiAndHJ1ZScKICB9OwoKICB2YXIgaXNCb29sZWFuQXR0ciA9IG1ha2VNYXAoCiAgICAnYWxsb3dmdWxsc2NyZWVuLGFzeW5jLGF1dG9mb2N1cyxhdXRvcGxheSxjaGVja2VkLGNvbXBhY3QsY29udHJvbHMsZGVjbGFyZSwnICsKICAgICdkZWZhdWx0LGRlZmF1bHRjaGVja2VkLGRlZmF1bHRtdXRlZCxkZWZhdWx0c2VsZWN0ZWQsZGVmZXIsZGlzYWJsZWQsJyArCiAgICAnZW5hYmxlZCxmb3Jtbm92YWxpZGF0ZSxoaWRkZW4saW5kZXRlcm1pbmF0ZSxpbmVydCxpc21hcCxpdGVtc2NvcGUsbG9vcCxtdWx0aXBsZSwnICsKICAgICdtdXRlZCxub2hyZWYsbm9yZXNpemUsbm9zaGFkZSxub3ZhbGlkYXRlLG5vd3JhcCxvcGVuLHBhdXNlb25leGl0LHJlYWRvbmx5LCcgKwogICAgJ3JlcXVpcmVkLHJldmVyc2VkLHNjb3BlZCxzZWFtbGVzcyxzZWxlY3RlZCxzb3J0YWJsZSx0cmFuc2xhdGUsJyArCiAgICAndHJ1ZXNwZWVkLHR5cGVtdXN0bWF0Y2gsdmlzaWJsZScKICApOwoKICB2YXIgeGxpbmtOUyA9ICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rJzsKCiAgdmFyIGlzWGxpbmsgPSBmdW5jdGlvbiAobmFtZSkgewogICAgcmV0dXJuIG5hbWUuY2hhckF0KDUpID09PSAnOicgJiYgbmFtZS5zbGljZSgwLCA1KSA9PT0gJ3hsaW5rJwogIH07CgogIHZhciBnZXRYbGlua1Byb3AgPSBmdW5jdGlvbiAobmFtZSkgewogICAgcmV0dXJuIGlzWGxpbmsobmFtZSkgPyBuYW1lLnNsaWNlKDYsIG5hbWUubGVuZ3RoKSA6ICcnCiAgfTsKCiAgdmFyIGlzRmFsc3lBdHRyVmFsdWUgPSBmdW5jdGlvbiAodmFsKSB7CiAgICByZXR1cm4gdmFsID09IG51bGwgfHwgdmFsID09PSBmYWxzZQogIH07CgogIC8qICAqLwoKICBmdW5jdGlvbiBnZW5DbGFzc0ZvclZub2RlICh2bm9kZSkgewogICAgdmFyIGRhdGEgPSB2bm9kZS5kYXRhOwogICAgdmFyIHBhcmVudE5vZGUgPSB2bm9kZTsKICAgIHZhciBjaGlsZE5vZGUgPSB2bm9kZTsKICAgIHdoaWxlIChpc0RlZihjaGlsZE5vZGUuY29tcG9uZW50SW5zdGFuY2UpKSB7CiAgICAgIGNoaWxkTm9kZSA9IGNoaWxkTm9kZS5jb21wb25lbnRJbnN0YW5jZS5fdm5vZGU7CiAgICAgIGlmIChjaGlsZE5vZGUgJiYgY2hpbGROb2RlLmRhdGEpIHsKICAgICAgICBkYXRhID0gbWVyZ2VDbGFzc0RhdGEoY2hpbGROb2RlLmRhdGEsIGRhdGEpOwogICAgICB9CiAgICB9CiAgICB3aGlsZSAoaXNEZWYocGFyZW50Tm9kZSA9IHBhcmVudE5vZGUucGFyZW50KSkgewogICAgICBpZiAocGFyZW50Tm9kZSAmJiBwYXJlbnROb2RlLmRhdGEpIHsKICAgICAgICBkYXRhID0gbWVyZ2VDbGFzc0RhdGEoZGF0YSwgcGFyZW50Tm9kZS5kYXRhKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlbmRlckNsYXNzKGRhdGEuc3RhdGljQ2xhc3MsIGRhdGEuY2xhc3MpCiAgfQoKICBmdW5jdGlvbiBtZXJnZUNsYXNzRGF0YSAoY2hpbGQsIHBhcmVudCkgewogICAgcmV0dXJuIHsKICAgICAgc3RhdGljQ2xhc3M6IGNvbmNhdChjaGlsZC5zdGF0aWNDbGFzcywgcGFyZW50LnN0YXRpY0NsYXNzKSwKICAgICAgY2xhc3M6IGlzRGVmKGNoaWxkLmNsYXNzKQogICAgICAgID8gW2NoaWxkLmNsYXNzLCBwYXJlbnQuY2xhc3NdCiAgICAgICAgOiBwYXJlbnQuY2xhc3MKICAgIH0KICB9CgogIGZ1bmN0aW9uIHJlbmRlckNsYXNzICgKICAgIHN0YXRpY0NsYXNzLAogICAgZHluYW1pY0NsYXNzCiAgKSB7CiAgICBpZiAoaXNEZWYoc3RhdGljQ2xhc3MpIHx8IGlzRGVmKGR5bmFtaWNDbGFzcykpIHsKICAgICAgcmV0dXJuIGNvbmNhdChzdGF0aWNDbGFzcywgc3RyaW5naWZ5Q2xhc3MoZHluYW1pY0NsYXNzKSkKICAgIH0KICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovCiAgICByZXR1cm4gJycKICB9CgogIGZ1bmN0aW9uIGNvbmNhdCAoYSwgYikgewogICAgcmV0dXJuIGEgPyBiID8gKGEgKyAnICcgKyBiKSA6IGEgOiAoYiB8fCAnJykKICB9CgogIGZ1bmN0aW9uIHN0cmluZ2lmeUNsYXNzICh2YWx1ZSkgewogICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7CiAgICAgIHJldHVybiBzdHJpbmdpZnlBcnJheSh2YWx1ZSkKICAgIH0KICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHsKICAgICAgcmV0dXJuIHN0cmluZ2lmeU9iamVjdCh2YWx1ZSkKICAgIH0KICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7CiAgICAgIHJldHVybiB2YWx1ZQogICAgfQogICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8KICAgIHJldHVybiAnJwogIH0KCiAgZnVuY3Rpb24gc3RyaW5naWZ5QXJyYXkgKHZhbHVlKSB7CiAgICB2YXIgcmVzID0gJyc7CiAgICB2YXIgc3RyaW5naWZpZWQ7CiAgICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICBpZiAoaXNEZWYoc3RyaW5naWZpZWQgPSBzdHJpbmdpZnlDbGFzcyh2YWx1ZVtpXSkpICYmIHN0cmluZ2lmaWVkICE9PSAnJykgewogICAgICAgIGlmIChyZXMpIHsgcmVzICs9ICcgJzsgfQogICAgICAgIHJlcyArPSBzdHJpbmdpZmllZDsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlcwogIH0KCiAgZnVuY3Rpb24gc3RyaW5naWZ5T2JqZWN0ICh2YWx1ZSkgewogICAgdmFyIHJlcyA9ICcnOwogICAgZm9yICh2YXIga2V5IGluIHZhbHVlKSB7CiAgICAgIGlmICh2YWx1ZVtrZXldKSB7CiAgICAgICAgaWYgKHJlcykgeyByZXMgKz0gJyAnOyB9CiAgICAgICAgcmVzICs9IGtleTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlcwogIH0KCiAgLyogICovCgogIHZhciBuYW1lc3BhY2VNYXAgPSB7CiAgICBzdmc6ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsCiAgICBtYXRoOiAnaHR0cDovL3d3dy53My5vcmcvMTk5OC9NYXRoL01hdGhNTCcKICB9OwoKICB2YXIgaXNIVE1MVGFnID0gbWFrZU1hcCgKICAgICdodG1sLGJvZHksYmFzZSxoZWFkLGxpbmssbWV0YSxzdHlsZSx0aXRsZSwnICsKICAgICdhZGRyZXNzLGFydGljbGUsYXNpZGUsZm9vdGVyLGhlYWRlcixoMSxoMixoMyxoNCxoNSxoNixoZ3JvdXAsbmF2LHNlY3Rpb24sJyArCiAgICAnZGl2LGRkLGRsLGR0LGZpZ2NhcHRpb24sZmlndXJlLHBpY3R1cmUsaHIsaW1nLGxpLG1haW4sb2wscCxwcmUsdWwsJyArCiAgICAnYSxiLGFiYnIsYmRpLGJkbyxicixjaXRlLGNvZGUsZGF0YSxkZm4sZW0saSxrYmQsbWFyayxxLHJwLHJ0LHJ0YyxydWJ5LCcgKwogICAgJ3Msc2FtcCxzbWFsbCxzcGFuLHN0cm9uZyxzdWIsc3VwLHRpbWUsdSx2YXIsd2JyLGFyZWEsYXVkaW8sbWFwLHRyYWNrLHZpZGVvLCcgKwogICAgJ2VtYmVkLG9iamVjdCxwYXJhbSxzb3VyY2UsY2FudmFzLHNjcmlwdCxub3NjcmlwdCxkZWwsaW5zLCcgKwogICAgJ2NhcHRpb24sY29sLGNvbGdyb3VwLHRhYmxlLHRoZWFkLHRib2R5LHRkLHRoLHRyLCcgKwogICAgJ2J1dHRvbixkYXRhbGlzdCxmaWVsZHNldCxmb3JtLGlucHV0LGxhYmVsLGxlZ2VuZCxtZXRlcixvcHRncm91cCxvcHRpb24sJyArCiAgICAnb3V0cHV0LHByb2dyZXNzLHNlbGVjdCx0ZXh0YXJlYSwnICsKICAgICdkZXRhaWxzLGRpYWxvZyxtZW51LG1lbnVpdGVtLHN1bW1hcnksJyArCiAgICAnY29udGVudCxlbGVtZW50LHNoYWRvdyx0ZW1wbGF0ZSxibG9ja3F1b3RlLGlmcmFtZSx0Zm9vdCcKICApOwoKICAvLyB0aGlzIG1hcCBpcyBpbnRlbnRpb25hbGx5IHNlbGVjdGl2ZSwgb25seSBjb3ZlcmluZyBTVkcgZWxlbWVudHMgdGhhdCBtYXkKICAvLyBjb250YWluIGNoaWxkIGVsZW1lbnRzLgogIHZhciBpc1NWRyA9IG1ha2VNYXAoCiAgICAnc3ZnLGFuaW1hdGUsY2lyY2xlLGNsaXBwYXRoLGN1cnNvcixkZWZzLGRlc2MsZWxsaXBzZSxmaWx0ZXIsZm9udC1mYWNlLCcgKwogICAgJ2ZvcmVpZ25PYmplY3QsZyxnbHlwaCxpbWFnZSxsaW5lLG1hcmtlcixtYXNrLG1pc3NpbmctZ2x5cGgscGF0aCxwYXR0ZXJuLCcgKwogICAgJ3BvbHlnb24scG9seWxpbmUscmVjdCxzd2l0Y2gsc3ltYm9sLHRleHQsdGV4dHBhdGgsdHNwYW4sdXNlLHZpZXcnLAogICAgdHJ1ZQogICk7CgogIHZhciBpc1ByZVRhZyA9IGZ1bmN0aW9uICh0YWcpIHsgcmV0dXJuIHRhZyA9PT0gJ3ByZSc7IH07CgogIHZhciBpc1Jlc2VydmVkVGFnID0gZnVuY3Rpb24gKHRhZykgewogICAgcmV0dXJuIGlzSFRNTFRhZyh0YWcpIHx8IGlzU1ZHKHRhZykKICB9OwoKICBmdW5jdGlvbiBnZXRUYWdOYW1lc3BhY2UgKHRhZykgewogICAgaWYgKGlzU1ZHKHRhZykpIHsKICAgICAgcmV0dXJuICdzdmcnCiAgICB9CiAgICAvLyBiYXNpYyBzdXBwb3J0IGZvciBNYXRoTUwKICAgIC8vIG5vdGUgaXQgZG9lc24ndCBzdXBwb3J0IG90aGVyIE1hdGhNTCBlbGVtZW50cyBiZWluZyBjb21wb25lbnQgcm9vdHMKICAgIGlmICh0YWcgPT09ICdtYXRoJykgewogICAgICByZXR1cm4gJ21hdGgnCiAgICB9CiAgfQoKICB2YXIgdW5rbm93bkVsZW1lbnRDYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7CiAgZnVuY3Rpb24gaXNVbmtub3duRWxlbWVudCAodGFnKSB7CiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgIGlmICghaW5Ccm93c2VyKSB7CiAgICAgIHJldHVybiB0cnVlCiAgICB9CiAgICBpZiAoaXNSZXNlcnZlZFRhZyh0YWcpKSB7CiAgICAgIHJldHVybiBmYWxzZQogICAgfQogICAgdGFnID0gdGFnLnRvTG93ZXJDYXNlKCk7CiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgIGlmICh1bmtub3duRWxlbWVudENhY2hlW3RhZ10gIT0gbnVsbCkgewogICAgICByZXR1cm4gdW5rbm93bkVsZW1lbnRDYWNoZVt0YWddCiAgICB9CiAgICB2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZyk7CiAgICBpZiAodGFnLmluZGV4T2YoJy0nKSA+IC0xKSB7CiAgICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzI4MjEwMzY0LzEwNzAyNDQKICAgICAgcmV0dXJuICh1bmtub3duRWxlbWVudENhY2hlW3RhZ10gPSAoCiAgICAgICAgZWwuY29uc3RydWN0b3IgPT09IHdpbmRvdy5IVE1MVW5rbm93bkVsZW1lbnQgfHwKICAgICAgICBlbC5jb25zdHJ1Y3RvciA9PT0gd2luZG93LkhUTUxFbGVtZW50CiAgICAgICkpCiAgICB9IGVsc2UgewogICAgICByZXR1cm4gKHVua25vd25FbGVtZW50Q2FjaGVbdGFnXSA9IC9IVE1MVW5rbm93bkVsZW1lbnQvLnRlc3QoZWwudG9TdHJpbmcoKSkpCiAgICB9CiAgfQoKICB2YXIgaXNUZXh0SW5wdXRUeXBlID0gbWFrZU1hcCgndGV4dCxudW1iZXIscGFzc3dvcmQsc2VhcmNoLGVtYWlsLHRlbCx1cmwnKTsKCiAgLyogICovCgogIC8qKgogICAqIFF1ZXJ5IGFuIGVsZW1lbnQgc2VsZWN0b3IgaWYgaXQncyBub3QgYW4gZWxlbWVudCBhbHJlYWR5LgogICAqLwogIGZ1bmN0aW9uIHF1ZXJ5IChlbCkgewogICAgaWYgKHR5cGVvZiBlbCA9PT0gJ3N0cmluZycpIHsKICAgICAgdmFyIHNlbGVjdGVkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbCk7CiAgICAgIGlmICghc2VsZWN0ZWQpIHsKICAgICAgICB3YXJuKAogICAgICAgICAgJ0Nhbm5vdCBmaW5kIGVsZW1lbnQ6ICcgKyBlbAogICAgICAgICk7CiAgICAgICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpCiAgICAgIH0KICAgICAgcmV0dXJuIHNlbGVjdGVkCiAgICB9IGVsc2UgewogICAgICByZXR1cm4gZWwKICAgIH0KICB9CgogIC8qICAqLwoKICBmdW5jdGlvbiBjcmVhdGVFbGVtZW50JDEgKHRhZ05hbWUsIHZub2RlKSB7CiAgICB2YXIgZWxtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKTsKICAgIGlmICh0YWdOYW1lICE9PSAnc2VsZWN0JykgewogICAgICByZXR1cm4gZWxtCiAgICB9CiAgICAvLyBmYWxzZSBvciBudWxsIHdpbGwgcmVtb3ZlIHRoZSBhdHRyaWJ1dGUgYnV0IHVuZGVmaW5lZCB3aWxsIG5vdAogICAgaWYgKHZub2RlLmRhdGEgJiYgdm5vZGUuZGF0YS5hdHRycyAmJiB2bm9kZS5kYXRhLmF0dHJzLm11bHRpcGxlICE9PSB1bmRlZmluZWQpIHsKICAgICAgZWxtLnNldEF0dHJpYnV0ZSgnbXVsdGlwbGUnLCAnbXVsdGlwbGUnKTsKICAgIH0KICAgIHJldHVybiBlbG0KICB9CgogIGZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnROUyAobmFtZXNwYWNlLCB0YWdOYW1lKSB7CiAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZU1hcFtuYW1lc3BhY2VdLCB0YWdOYW1lKQogIH0KCiAgZnVuY3Rpb24gY3JlYXRlVGV4dE5vZGUgKHRleHQpIHsKICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0ZXh0KQogIH0KCiAgZnVuY3Rpb24gY3JlYXRlQ29tbWVudCAodGV4dCkgewogICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQodGV4dCkKICB9CgogIGZ1bmN0aW9uIGluc2VydEJlZm9yZSAocGFyZW50Tm9kZSwgbmV3Tm9kZSwgcmVmZXJlbmNlTm9kZSkgewogICAgcGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3Tm9kZSwgcmVmZXJlbmNlTm9kZSk7CiAgfQoKICBmdW5jdGlvbiByZW1vdmVDaGlsZCAobm9kZSwgY2hpbGQpIHsKICAgIG5vZGUucmVtb3ZlQ2hpbGQoY2hpbGQpOwogIH0KCiAgZnVuY3Rpb24gYXBwZW5kQ2hpbGQgKG5vZGUsIGNoaWxkKSB7CiAgICBub2RlLmFwcGVuZENoaWxkKGNoaWxkKTsKICB9CgogIGZ1bmN0aW9uIHBhcmVudE5vZGUgKG5vZGUpIHsKICAgIHJldHVybiBub2RlLnBhcmVudE5vZGUKICB9CgogIGZ1bmN0aW9uIG5leHRTaWJsaW5nIChub2RlKSB7CiAgICByZXR1cm4gbm9kZS5uZXh0U2libGluZwogIH0KCiAgZnVuY3Rpb24gdGFnTmFtZSAobm9kZSkgewogICAgcmV0dXJuIG5vZGUudGFnTmFtZQogIH0KCiAgZnVuY3Rpb24gc2V0VGV4dENvbnRlbnQgKG5vZGUsIHRleHQpIHsKICAgIG5vZGUudGV4dENvbnRlbnQgPSB0ZXh0OwogIH0KCiAgZnVuY3Rpb24gc2V0U3R5bGVTY29wZSAobm9kZSwgc2NvcGVJZCkgewogICAgbm9kZS5zZXRBdHRyaWJ1dGUoc2NvcGVJZCwgJycpOwogIH0KCiAgdmFyIG5vZGVPcHMgPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7CiAgICBjcmVhdGVFbGVtZW50OiBjcmVhdGVFbGVtZW50JDEsCiAgICBjcmVhdGVFbGVtZW50TlM6IGNyZWF0ZUVsZW1lbnROUywKICAgIGNyZWF0ZVRleHROb2RlOiBjcmVhdGVUZXh0Tm9kZSwKICAgIGNyZWF0ZUNvbW1lbnQ6IGNyZWF0ZUNvbW1lbnQsCiAgICBpbnNlcnRCZWZvcmU6IGluc2VydEJlZm9yZSwKICAgIHJlbW92ZUNoaWxkOiByZW1vdmVDaGlsZCwKICAgIGFwcGVuZENoaWxkOiBhcHBlbmRDaGlsZCwKICAgIHBhcmVudE5vZGU6IHBhcmVudE5vZGUsCiAgICBuZXh0U2libGluZzogbmV4dFNpYmxpbmcsCiAgICB0YWdOYW1lOiB0YWdOYW1lLAogICAgc2V0VGV4dENvbnRlbnQ6IHNldFRleHRDb250ZW50LAogICAgc2V0U3R5bGVTY29wZTogc2V0U3R5bGVTY29wZQogIH0pOwoKICAvKiAgKi8KCiAgdmFyIHJlZiA9IHsKICAgIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlIChfLCB2bm9kZSkgewogICAgICByZWdpc3RlclJlZih2bm9kZSk7CiAgICB9LAogICAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUgKG9sZFZub2RlLCB2bm9kZSkgewogICAgICBpZiAob2xkVm5vZGUuZGF0YS5yZWYgIT09IHZub2RlLmRhdGEucmVmKSB7CiAgICAgICAgcmVnaXN0ZXJSZWYob2xkVm5vZGUsIHRydWUpOwogICAgICAgIHJlZ2lzdGVyUmVmKHZub2RlKTsKICAgICAgfQogICAgfSwKICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3kgKHZub2RlKSB7CiAgICAgIHJlZ2lzdGVyUmVmKHZub2RlLCB0cnVlKTsKICAgIH0KICB9OwoKICBmdW5jdGlvbiByZWdpc3RlclJlZiAodm5vZGUsIGlzUmVtb3ZhbCkgewogICAgdmFyIGtleSA9IHZub2RlLmRhdGEucmVmOwogICAgaWYgKCFpc0RlZihrZXkpKSB7IHJldHVybiB9CgogICAgdmFyIHZtID0gdm5vZGUuY29udGV4dDsKICAgIHZhciByZWYgPSB2bm9kZS5jb21wb25lbnRJbnN0YW5jZSB8fCB2bm9kZS5lbG07CiAgICB2YXIgcmVmcyA9IHZtLiRyZWZzOwogICAgaWYgKGlzUmVtb3ZhbCkgewogICAgICBpZiAoQXJyYXkuaXNBcnJheShyZWZzW2tleV0pKSB7CiAgICAgICAgcmVtb3ZlKHJlZnNba2V5XSwgcmVmKTsKICAgICAgfSBlbHNlIGlmIChyZWZzW2tleV0gPT09IHJlZikgewogICAgICAgIHJlZnNba2V5XSA9IHVuZGVmaW5lZDsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgaWYgKHZub2RlLmRhdGEucmVmSW5Gb3IpIHsKICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkocmVmc1trZXldKSkgewogICAgICAgICAgcmVmc1trZXldID0gW3JlZl07CiAgICAgICAgfSBlbHNlIGlmIChyZWZzW2tleV0uaW5kZXhPZihyZWYpIDwgMCkgewogICAgICAgICAgLy8gJGZsb3ctZGlzYWJsZS1saW5lCiAgICAgICAgICByZWZzW2tleV0ucHVzaChyZWYpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICByZWZzW2tleV0gPSByZWY7CiAgICAgIH0KICAgIH0KICB9CgogIC8qKgogICAqIFZpcnR1YWwgRE9NIHBhdGNoaW5nIGFsZ29yaXRobSBiYXNlZCBvbiBTbmFiYmRvbSBieQogICAqIFNpbW9uIEZyaWlzIFZpbmR1bSAoQHBhbGRlcGluZCkKICAgKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UKICAgKiBodHRwczovL2dpdGh1Yi5jb20vcGFsZGVwaW5kL3NuYWJiZG9tL2Jsb2IvbWFzdGVyL0xJQ0VOU0UKICAgKgogICAqIG1vZGlmaWVkIGJ5IEV2YW4gWW91IChAeXl4OTkwODAzKQogICAqCiAgICogTm90IHR5cGUtY2hlY2tpbmcgdGhpcyBiZWNhdXNlIHRoaXMgZmlsZSBpcyBwZXJmLWNyaXRpY2FsIGFuZCB0aGUgY29zdAogICAqIG9mIG1ha2luZyBmbG93IHVuZGVyc3RhbmQgaXQgaXMgbm90IHdvcnRoIGl0LgogICAqLwoKICB2YXIgZW1wdHlOb2RlID0gbmV3IFZOb2RlKCcnLCB7fSwgW10pOwoKICB2YXIgaG9va3MgPSBbJ2NyZWF0ZScsICdhY3RpdmF0ZScsICd1cGRhdGUnLCAncmVtb3ZlJywgJ2Rlc3Ryb3knXTsKCiAgZnVuY3Rpb24gc2FtZVZub2RlIChhLCBiKSB7CiAgICByZXR1cm4gKAogICAgICBhLmtleSA9PT0gYi5rZXkgJiYgKAogICAgICAgICgKICAgICAgICAgIGEudGFnID09PSBiLnRhZyAmJgogICAgICAgICAgYS5pc0NvbW1lbnQgPT09IGIuaXNDb21tZW50ICYmCiAgICAgICAgICBpc0RlZihhLmRhdGEpID09PSBpc0RlZihiLmRhdGEpICYmCiAgICAgICAgICBzYW1lSW5wdXRUeXBlKGEsIGIpCiAgICAgICAgKSB8fCAoCiAgICAgICAgICBpc1RydWUoYS5pc0FzeW5jUGxhY2Vob2xkZXIpICYmCiAgICAgICAgICBhLmFzeW5jRmFjdG9yeSA9PT0gYi5hc3luY0ZhY3RvcnkgJiYKICAgICAgICAgIGlzVW5kZWYoYi5hc3luY0ZhY3RvcnkuZXJyb3IpCiAgICAgICAgKQogICAgICApCiAgICApCiAgfQoKICBmdW5jdGlvbiBzYW1lSW5wdXRUeXBlIChhLCBiKSB7CiAgICBpZiAoYS50YWcgIT09ICdpbnB1dCcpIHsgcmV0dXJuIHRydWUgfQogICAgdmFyIGk7CiAgICB2YXIgdHlwZUEgPSBpc0RlZihpID0gYS5kYXRhKSAmJiBpc0RlZihpID0gaS5hdHRycykgJiYgaS50eXBlOwogICAgdmFyIHR5cGVCID0gaXNEZWYoaSA9IGIuZGF0YSkgJiYgaXNEZWYoaSA9IGkuYXR0cnMpICYmIGkudHlwZTsKICAgIHJldHVybiB0eXBlQSA9PT0gdHlwZUIgfHwgaXNUZXh0SW5wdXRUeXBlKHR5cGVBKSAmJiBpc1RleHRJbnB1dFR5cGUodHlwZUIpCiAgfQoKICBmdW5jdGlvbiBjcmVhdGVLZXlUb09sZElkeCAoY2hpbGRyZW4sIGJlZ2luSWR4LCBlbmRJZHgpIHsKICAgIHZhciBpLCBrZXk7CiAgICB2YXIgbWFwID0ge307CiAgICBmb3IgKGkgPSBiZWdpbklkeDsgaSA8PSBlbmRJZHg7ICsraSkgewogICAgICBrZXkgPSBjaGlsZHJlbltpXS5rZXk7CiAgICAgIGlmIChpc0RlZihrZXkpKSB7IG1hcFtrZXldID0gaTsgfQogICAgfQogICAgcmV0dXJuIG1hcAogIH0KCiAgZnVuY3Rpb24gY3JlYXRlUGF0Y2hGdW5jdGlvbiAoYmFja2VuZCkgewogICAgdmFyIGksIGo7CiAgICB2YXIgY2JzID0ge307CgogICAgdmFyIG1vZHVsZXMgPSBiYWNrZW5kLm1vZHVsZXM7CiAgICB2YXIgbm9kZU9wcyA9IGJhY2tlbmQubm9kZU9wczsKCiAgICBmb3IgKGkgPSAwOyBpIDwgaG9va3MubGVuZ3RoOyArK2kpIHsKICAgICAgY2JzW2hvb2tzW2ldXSA9IFtdOwogICAgICBmb3IgKGogPSAwOyBqIDwgbW9kdWxlcy5sZW5ndGg7ICsraikgewogICAgICAgIGlmIChpc0RlZihtb2R1bGVzW2pdW2hvb2tzW2ldXSkpIHsKICAgICAgICAgIGNic1tob29rc1tpXV0ucHVzaChtb2R1bGVzW2pdW2hvb2tzW2ldXSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZW1wdHlOb2RlQXQgKGVsbSkgewogICAgICByZXR1cm4gbmV3IFZOb2RlKG5vZGVPcHMudGFnTmFtZShlbG0pLnRvTG93ZXJDYXNlKCksIHt9LCBbXSwgdW5kZWZpbmVkLCBlbG0pCiAgICB9CgogICAgZnVuY3Rpb24gY3JlYXRlUm1DYiAoY2hpbGRFbG0sIGxpc3RlbmVycykgewogICAgICBmdW5jdGlvbiByZW1vdmUkJDEgKCkgewogICAgICAgIGlmICgtLXJlbW92ZSQkMS5saXN0ZW5lcnMgPT09IDApIHsKICAgICAgICAgIHJlbW92ZU5vZGUoY2hpbGRFbG0pOwogICAgICAgIH0KICAgICAgfQogICAgICByZW1vdmUkJDEubGlzdGVuZXJzID0gbGlzdGVuZXJzOwogICAgICByZXR1cm4gcmVtb3ZlJCQxCiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlTm9kZSAoZWwpIHsKICAgICAgdmFyIHBhcmVudCA9IG5vZGVPcHMucGFyZW50Tm9kZShlbCk7CiAgICAgIC8vIGVsZW1lbnQgbWF5IGhhdmUgYWxyZWFkeSBiZWVuIHJlbW92ZWQgZHVlIHRvIHYtaHRtbCAvIHYtdGV4dAogICAgICBpZiAoaXNEZWYocGFyZW50KSkgewogICAgICAgIG5vZGVPcHMucmVtb3ZlQ2hpbGQocGFyZW50LCBlbCk7CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBpc1Vua25vd25FbGVtZW50JCQxICh2bm9kZSwgaW5WUHJlKSB7CiAgICAgIHJldHVybiAoCiAgICAgICAgIWluVlByZSAmJgogICAgICAgICF2bm9kZS5ucyAmJgogICAgICAgICEoCiAgICAgICAgICBjb25maWcuaWdub3JlZEVsZW1lbnRzLmxlbmd0aCAmJgogICAgICAgICAgY29uZmlnLmlnbm9yZWRFbGVtZW50cy5zb21lKGZ1bmN0aW9uIChpZ25vcmUpIHsKICAgICAgICAgICAgcmV0dXJuIGlzUmVnRXhwKGlnbm9yZSkKICAgICAgICAgICAgICA/IGlnbm9yZS50ZXN0KHZub2RlLnRhZykKICAgICAgICAgICAgICA6IGlnbm9yZSA9PT0gdm5vZGUudGFnCiAgICAgICAgICB9KQogICAgICAgICkgJiYKICAgICAgICBjb25maWcuaXNVbmtub3duRWxlbWVudCh2bm9kZS50YWcpCiAgICAgICkKICAgIH0KCiAgICB2YXIgY3JlYXRpbmdFbG1JblZQcmUgPSAwOwoKICAgIGZ1bmN0aW9uIGNyZWF0ZUVsbSAoCiAgICAgIHZub2RlLAogICAgICBpbnNlcnRlZFZub2RlUXVldWUsCiAgICAgIHBhcmVudEVsbSwKICAgICAgcmVmRWxtLAogICAgICBuZXN0ZWQsCiAgICAgIG93bmVyQXJyYXksCiAgICAgIGluZGV4CiAgICApIHsKICAgICAgaWYgKGlzRGVmKHZub2RlLmVsbSkgJiYgaXNEZWYob3duZXJBcnJheSkpIHsKICAgICAgICAvLyBUaGlzIHZub2RlIHdhcyB1c2VkIGluIGEgcHJldmlvdXMgcmVuZGVyIQogICAgICAgIC8vIG5vdyBpdCdzIHVzZWQgYXMgYSBuZXcgbm9kZSwgb3ZlcndyaXRpbmcgaXRzIGVsbSB3b3VsZCBjYXVzZQogICAgICAgIC8vIHBvdGVudGlhbCBwYXRjaCBlcnJvcnMgZG93biB0aGUgcm9hZCB3aGVuIGl0J3MgdXNlZCBhcyBhbiBpbnNlcnRpb24KICAgICAgICAvLyByZWZlcmVuY2Ugbm9kZS4gSW5zdGVhZCwgd2UgY2xvbmUgdGhlIG5vZGUgb24tZGVtYW5kIGJlZm9yZSBjcmVhdGluZwogICAgICAgIC8vIGFzc29jaWF0ZWQgRE9NIGVsZW1lbnQgZm9yIGl0LgogICAgICAgIHZub2RlID0gb3duZXJBcnJheVtpbmRleF0gPSBjbG9uZVZOb2RlKHZub2RlKTsKICAgICAgfQoKICAgICAgdm5vZGUuaXNSb290SW5zZXJ0ID0gIW5lc3RlZDsgLy8gZm9yIHRyYW5zaXRpb24gZW50ZXIgY2hlY2sKICAgICAgaWYgKGNyZWF0ZUNvbXBvbmVudCh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBwYXJlbnRFbG0sIHJlZkVsbSkpIHsKICAgICAgICByZXR1cm4KICAgICAgfQoKICAgICAgdmFyIGRhdGEgPSB2bm9kZS5kYXRhOwogICAgICB2YXIgY2hpbGRyZW4gPSB2bm9kZS5jaGlsZHJlbjsKICAgICAgdmFyIHRhZyA9IHZub2RlLnRhZzsKICAgICAgaWYgKGlzRGVmKHRhZykpIHsKICAgICAgICB7CiAgICAgICAgICBpZiAoZGF0YSAmJiBkYXRhLnByZSkgewogICAgICAgICAgICBjcmVhdGluZ0VsbUluVlByZSsrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGlzVW5rbm93bkVsZW1lbnQkJDEodm5vZGUsIGNyZWF0aW5nRWxtSW5WUHJlKSkgewogICAgICAgICAgICB3YXJuKAogICAgICAgICAgICAgICdVbmtub3duIGN1c3RvbSBlbGVtZW50OiA8JyArIHRhZyArICc+IC0gZGlkIHlvdSAnICsKICAgICAgICAgICAgICAncmVnaXN0ZXIgdGhlIGNvbXBvbmVudCBjb3JyZWN0bHk/IEZvciByZWN1cnNpdmUgY29tcG9uZW50cywgJyArCiAgICAgICAgICAgICAgJ21ha2Ugc3VyZSB0byBwcm92aWRlIHRoZSAibmFtZSIgb3B0aW9uLicsCiAgICAgICAgICAgICAgdm5vZGUuY29udGV4dAogICAgICAgICAgICApOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdm5vZGUuZWxtID0gdm5vZGUubnMKICAgICAgICAgID8gbm9kZU9wcy5jcmVhdGVFbGVtZW50TlModm5vZGUubnMsIHRhZykKICAgICAgICAgIDogbm9kZU9wcy5jcmVhdGVFbGVtZW50KHRhZywgdm5vZGUpOwogICAgICAgIHNldFNjb3BlKHZub2RlKTsKCiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICAgICAgewogICAgICAgICAgY3JlYXRlQ2hpbGRyZW4odm5vZGUsIGNoaWxkcmVuLCBpbnNlcnRlZFZub2RlUXVldWUpOwogICAgICAgICAgaWYgKGlzRGVmKGRhdGEpKSB7CiAgICAgICAgICAgIGludm9rZUNyZWF0ZUhvb2tzKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpOwogICAgICAgICAgfQogICAgICAgICAgaW5zZXJ0KHBhcmVudEVsbSwgdm5vZGUuZWxtLCByZWZFbG0pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGRhdGEgJiYgZGF0YS5wcmUpIHsKICAgICAgICAgIGNyZWF0aW5nRWxtSW5WUHJlLS07CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYgKGlzVHJ1ZSh2bm9kZS5pc0NvbW1lbnQpKSB7CiAgICAgICAgdm5vZGUuZWxtID0gbm9kZU9wcy5jcmVhdGVDb21tZW50KHZub2RlLnRleHQpOwogICAgICAgIGluc2VydChwYXJlbnRFbG0sIHZub2RlLmVsbSwgcmVmRWxtKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB2bm9kZS5lbG0gPSBub2RlT3BzLmNyZWF0ZVRleHROb2RlKHZub2RlLnRleHQpOwogICAgICAgIGluc2VydChwYXJlbnRFbG0sIHZub2RlLmVsbSwgcmVmRWxtKTsKICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGNyZWF0ZUNvbXBvbmVudCAodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSwgcGFyZW50RWxtLCByZWZFbG0pIHsKICAgICAgdmFyIGkgPSB2bm9kZS5kYXRhOwogICAgICBpZiAoaXNEZWYoaSkpIHsKICAgICAgICB2YXIgaXNSZWFjdGl2YXRlZCA9IGlzRGVmKHZub2RlLmNvbXBvbmVudEluc3RhbmNlKSAmJiBpLmtlZXBBbGl2ZTsKICAgICAgICBpZiAoaXNEZWYoaSA9IGkuaG9vaykgJiYgaXNEZWYoaSA9IGkuaW5pdCkpIHsKICAgICAgICAgIGkodm5vZGUsIGZhbHNlIC8qIGh5ZHJhdGluZyAqLyk7CiAgICAgICAgfQogICAgICAgIC8vIGFmdGVyIGNhbGxpbmcgdGhlIGluaXQgaG9vaywgaWYgdGhlIHZub2RlIGlzIGEgY2hpbGQgY29tcG9uZW50CiAgICAgICAgLy8gaXQgc2hvdWxkJ3ZlIGNyZWF0ZWQgYSBjaGlsZCBpbnN0YW5jZSBhbmQgbW91bnRlZCBpdC4gdGhlIGNoaWxkCiAgICAgICAgLy8gY29tcG9uZW50IGFsc28gaGFzIHNldCB0aGUgcGxhY2Vob2xkZXIgdm5vZGUncyBlbG0uCiAgICAgICAgLy8gaW4gdGhhdCBjYXNlIHdlIGNhbiBqdXN0IHJldHVybiB0aGUgZWxlbWVudCBhbmQgYmUgZG9uZS4KICAgICAgICBpZiAoaXNEZWYodm5vZGUuY29tcG9uZW50SW5zdGFuY2UpKSB7CiAgICAgICAgICBpbml0Q29tcG9uZW50KHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpOwogICAgICAgICAgaW5zZXJ0KHBhcmVudEVsbSwgdm5vZGUuZWxtLCByZWZFbG0pOwogICAgICAgICAgaWYgKGlzVHJ1ZShpc1JlYWN0aXZhdGVkKSkgewogICAgICAgICAgICByZWFjdGl2YXRlQ29tcG9uZW50KHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIHBhcmVudEVsbSwgcmVmRWxtKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gaW5pdENvbXBvbmVudCAodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSkgewogICAgICBpZiAoaXNEZWYodm5vZGUuZGF0YS5wZW5kaW5nSW5zZXJ0KSkgewogICAgICAgIGluc2VydGVkVm5vZGVRdWV1ZS5wdXNoLmFwcGx5KGluc2VydGVkVm5vZGVRdWV1ZSwgdm5vZGUuZGF0YS5wZW5kaW5nSW5zZXJ0KTsKICAgICAgICB2bm9kZS5kYXRhLnBlbmRpbmdJbnNlcnQgPSBudWxsOwogICAgICB9CiAgICAgIHZub2RlLmVsbSA9IHZub2RlLmNvbXBvbmVudEluc3RhbmNlLiRlbDsKICAgICAgaWYgKGlzUGF0Y2hhYmxlKHZub2RlKSkgewogICAgICAgIGludm9rZUNyZWF0ZUhvb2tzKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpOwogICAgICAgIHNldFNjb3BlKHZub2RlKTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBlbXB0eSBjb21wb25lbnQgcm9vdC4KICAgICAgICAvLyBza2lwIGFsbCBlbGVtZW50LXJlbGF0ZWQgbW9kdWxlcyBleGNlcHQgZm9yIHJlZiAoIzM0NTUpCiAgICAgICAgcmVnaXN0ZXJSZWYodm5vZGUpOwogICAgICAgIC8vIG1ha2Ugc3VyZSB0byBpbnZva2UgdGhlIGluc2VydCBob29rCiAgICAgICAgaW5zZXJ0ZWRWbm9kZVF1ZXVlLnB1c2godm5vZGUpOwogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gcmVhY3RpdmF0ZUNvbXBvbmVudCAodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSwgcGFyZW50RWxtLCByZWZFbG0pIHsKICAgICAgdmFyIGk7CiAgICAgIC8vIGhhY2sgZm9yICM0MzM5OiBhIHJlYWN0aXZhdGVkIGNvbXBvbmVudCB3aXRoIGlubmVyIHRyYW5zaXRpb24KICAgICAgLy8gZG9lcyBub3QgdHJpZ2dlciBiZWNhdXNlIHRoZSBpbm5lciBub2RlJ3MgY3JlYXRlZCBob29rcyBhcmUgbm90IGNhbGxlZAogICAgICAvLyBhZ2Fpbi4gSXQncyBub3QgaWRlYWwgdG8gaW52b2x2ZSBtb2R1bGUtc3BlY2lmaWMgbG9naWMgaW4gaGVyZSBidXQKICAgICAgLy8gdGhlcmUgZG9lc24ndCBzZWVtIHRvIGJlIGEgYmV0dGVyIHdheSB0byBkbyBpdC4KICAgICAgdmFyIGlubmVyTm9kZSA9IHZub2RlOwogICAgICB3aGlsZSAoaW5uZXJOb2RlLmNvbXBvbmVudEluc3RhbmNlKSB7CiAgICAgICAgaW5uZXJOb2RlID0gaW5uZXJOb2RlLmNvbXBvbmVudEluc3RhbmNlLl92bm9kZTsKICAgICAgICBpZiAoaXNEZWYoaSA9IGlubmVyTm9kZS5kYXRhKSAmJiBpc0RlZihpID0gaS50cmFuc2l0aW9uKSkgewogICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNicy5hY3RpdmF0ZS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBjYnMuYWN0aXZhdGVbaV0oZW1wdHlOb2RlLCBpbm5lck5vZGUpOwogICAgICAgICAgfQogICAgICAgICAgaW5zZXJ0ZWRWbm9kZVF1ZXVlLnB1c2goaW5uZXJOb2RlKTsKICAgICAgICAgIGJyZWFrCiAgICAgICAgfQogICAgICB9CiAgICAgIC8vIHVubGlrZSBhIG5ld2x5IGNyZWF0ZWQgY29tcG9uZW50LAogICAgICAvLyBhIHJlYWN0aXZhdGVkIGtlZXAtYWxpdmUgY29tcG9uZW50IGRvZXNuJ3QgaW5zZXJ0IGl0c2VsZgogICAgICBpbnNlcnQocGFyZW50RWxtLCB2bm9kZS5lbG0sIHJlZkVsbSk7CiAgICB9CgogICAgZnVuY3Rpb24gaW5zZXJ0IChwYXJlbnQsIGVsbSwgcmVmJCQxKSB7CiAgICAgIGlmIChpc0RlZihwYXJlbnQpKSB7CiAgICAgICAgaWYgKGlzRGVmKHJlZiQkMSkpIHsKICAgICAgICAgIGlmIChub2RlT3BzLnBhcmVudE5vZGUocmVmJCQxKSA9PT0gcGFyZW50KSB7CiAgICAgICAgICAgIG5vZGVPcHMuaW5zZXJ0QmVmb3JlKHBhcmVudCwgZWxtLCByZWYkJDEpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBub2RlT3BzLmFwcGVuZENoaWxkKHBhcmVudCwgZWxtKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBjcmVhdGVDaGlsZHJlbiAodm5vZGUsIGNoaWxkcmVuLCBpbnNlcnRlZFZub2RlUXVldWUpIHsKICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGRyZW4pKSB7CiAgICAgICAgewogICAgICAgICAgY2hlY2tEdXBsaWNhdGVLZXlzKGNoaWxkcmVuKTsKICAgICAgICB9CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7ICsraSkgewogICAgICAgICAgY3JlYXRlRWxtKGNoaWxkcmVuW2ldLCBpbnNlcnRlZFZub2RlUXVldWUsIHZub2RlLmVsbSwgbnVsbCwgdHJ1ZSwgY2hpbGRyZW4sIGkpOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChpc1ByaW1pdGl2ZSh2bm9kZS50ZXh0KSkgewogICAgICAgIG5vZGVPcHMuYXBwZW5kQ2hpbGQodm5vZGUuZWxtLCBub2RlT3BzLmNyZWF0ZVRleHROb2RlKFN0cmluZyh2bm9kZS50ZXh0KSkpOwogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gaXNQYXRjaGFibGUgKHZub2RlKSB7CiAgICAgIHdoaWxlICh2bm9kZS5jb21wb25lbnRJbnN0YW5jZSkgewogICAgICAgIHZub2RlID0gdm5vZGUuY29tcG9uZW50SW5zdGFuY2UuX3Zub2RlOwogICAgICB9CiAgICAgIHJldHVybiBpc0RlZih2bm9kZS50YWcpCiAgICB9CgogICAgZnVuY3Rpb24gaW52b2tlQ3JlYXRlSG9va3MgKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpIHsKICAgICAgZm9yICh2YXIgaSQxID0gMDsgaSQxIDwgY2JzLmNyZWF0ZS5sZW5ndGg7ICsraSQxKSB7CiAgICAgICAgY2JzLmNyZWF0ZVtpJDFdKGVtcHR5Tm9kZSwgdm5vZGUpOwogICAgICB9CiAgICAgIGkgPSB2bm9kZS5kYXRhLmhvb2s7IC8vIFJldXNlIHZhcmlhYmxlCiAgICAgIGlmIChpc0RlZihpKSkgewogICAgICAgIGlmIChpc0RlZihpLmNyZWF0ZSkpIHsgaS5jcmVhdGUoZW1wdHlOb2RlLCB2bm9kZSk7IH0KICAgICAgICBpZiAoaXNEZWYoaS5pbnNlcnQpKSB7IGluc2VydGVkVm5vZGVRdWV1ZS5wdXNoKHZub2RlKTsgfQogICAgICB9CiAgICB9CgogICAgLy8gc2V0IHNjb3BlIGlkIGF0dHJpYnV0ZSBmb3Igc2NvcGVkIENTUy4KICAgIC8vIHRoaXMgaXMgaW1wbGVtZW50ZWQgYXMgYSBzcGVjaWFsIGNhc2UgdG8gYXZvaWQgdGhlIG92ZXJoZWFkCiAgICAvLyBvZiBnb2luZyB0aHJvdWdoIHRoZSBub3JtYWwgYXR0cmlidXRlIHBhdGNoaW5nIHByb2Nlc3MuCiAgICBmdW5jdGlvbiBzZXRTY29wZSAodm5vZGUpIHsKICAgICAgdmFyIGk7CiAgICAgIGlmIChpc0RlZihpID0gdm5vZGUuZm5TY29wZUlkKSkgewogICAgICAgIG5vZGVPcHMuc2V0U3R5bGVTY29wZSh2bm9kZS5lbG0sIGkpOwogICAgICB9IGVsc2UgewogICAgICAgIHZhciBhbmNlc3RvciA9IHZub2RlOwogICAgICAgIHdoaWxlIChhbmNlc3RvcikgewogICAgICAgICAgaWYgKGlzRGVmKGkgPSBhbmNlc3Rvci5jb250ZXh0KSAmJiBpc0RlZihpID0gaS4kb3B0aW9ucy5fc2NvcGVJZCkpIHsKICAgICAgICAgICAgbm9kZU9wcy5zZXRTdHlsZVNjb3BlKHZub2RlLmVsbSwgaSk7CiAgICAgICAgICB9CiAgICAgICAgICBhbmNlc3RvciA9IGFuY2VzdG9yLnBhcmVudDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLy8gZm9yIHNsb3QgY29udGVudCB0aGV5IHNob3VsZCBhbHNvIGdldCB0aGUgc2NvcGVJZCBmcm9tIHRoZSBob3N0IGluc3RhbmNlLgogICAgICBpZiAoaXNEZWYoaSA9IGFjdGl2ZUluc3RhbmNlKSAmJgogICAgICAgIGkgIT09IHZub2RlLmNvbnRleHQgJiYKICAgICAgICBpICE9PSB2bm9kZS5mbkNvbnRleHQgJiYKICAgICAgICBpc0RlZihpID0gaS4kb3B0aW9ucy5fc2NvcGVJZCkKICAgICAgKSB7CiAgICAgICAgbm9kZU9wcy5zZXRTdHlsZVNjb3BlKHZub2RlLmVsbSwgaSk7CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBhZGRWbm9kZXMgKHBhcmVudEVsbSwgcmVmRWxtLCB2bm9kZXMsIHN0YXJ0SWR4LCBlbmRJZHgsIGluc2VydGVkVm5vZGVRdWV1ZSkgewogICAgICBmb3IgKDsgc3RhcnRJZHggPD0gZW5kSWR4OyArK3N0YXJ0SWR4KSB7CiAgICAgICAgY3JlYXRlRWxtKHZub2Rlc1tzdGFydElkeF0sIGluc2VydGVkVm5vZGVRdWV1ZSwgcGFyZW50RWxtLCByZWZFbG0sIGZhbHNlLCB2bm9kZXMsIHN0YXJ0SWR4KTsKICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGludm9rZURlc3Ryb3lIb29rICh2bm9kZSkgewogICAgICB2YXIgaSwgajsKICAgICAgdmFyIGRhdGEgPSB2bm9kZS5kYXRhOwogICAgICBpZiAoaXNEZWYoZGF0YSkpIHsKICAgICAgICBpZiAoaXNEZWYoaSA9IGRhdGEuaG9vaykgJiYgaXNEZWYoaSA9IGkuZGVzdHJveSkpIHsgaSh2bm9kZSk7IH0KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY2JzLmRlc3Ryb3kubGVuZ3RoOyArK2kpIHsgY2JzLmRlc3Ryb3lbaV0odm5vZGUpOyB9CiAgICAgIH0KICAgICAgaWYgKGlzRGVmKGkgPSB2bm9kZS5jaGlsZHJlbikpIHsKICAgICAgICBmb3IgKGogPSAwOyBqIDwgdm5vZGUuY2hpbGRyZW4ubGVuZ3RoOyArK2opIHsKICAgICAgICAgIGludm9rZURlc3Ryb3lIb29rKHZub2RlLmNoaWxkcmVuW2pdKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiByZW1vdmVWbm9kZXMgKHBhcmVudEVsbSwgdm5vZGVzLCBzdGFydElkeCwgZW5kSWR4KSB7CiAgICAgIGZvciAoOyBzdGFydElkeCA8PSBlbmRJZHg7ICsrc3RhcnRJZHgpIHsKICAgICAgICB2YXIgY2ggPSB2bm9kZXNbc3RhcnRJZHhdOwogICAgICAgIGlmIChpc0RlZihjaCkpIHsKICAgICAgICAgIGlmIChpc0RlZihjaC50YWcpKSB7CiAgICAgICAgICAgIHJlbW92ZUFuZEludm9rZVJlbW92ZUhvb2soY2gpOwogICAgICAgICAgICBpbnZva2VEZXN0cm95SG9vayhjaCk7CiAgICAgICAgICB9IGVsc2UgeyAvLyBUZXh0IG5vZGUKICAgICAgICAgICAgcmVtb3ZlTm9kZShjaC5lbG0pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHJlbW92ZUFuZEludm9rZVJlbW92ZUhvb2sgKHZub2RlLCBybSkgewogICAgICBpZiAoaXNEZWYocm0pIHx8IGlzRGVmKHZub2RlLmRhdGEpKSB7CiAgICAgICAgdmFyIGk7CiAgICAgICAgdmFyIGxpc3RlbmVycyA9IGNicy5yZW1vdmUubGVuZ3RoICsgMTsKICAgICAgICBpZiAoaXNEZWYocm0pKSB7CiAgICAgICAgICAvLyB3ZSBoYXZlIGEgcmVjdXJzaXZlbHkgcGFzc2VkIGRvd24gcm0gY2FsbGJhY2sKICAgICAgICAgIC8vIGluY3JlYXNlIHRoZSBsaXN0ZW5lcnMgY291bnQKICAgICAgICAgIHJtLmxpc3RlbmVycyArPSBsaXN0ZW5lcnM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vIGRpcmVjdGx5IHJlbW92aW5nCiAgICAgICAgICBybSA9IGNyZWF0ZVJtQ2Iodm5vZGUuZWxtLCBsaXN0ZW5lcnMpOwogICAgICAgIH0KICAgICAgICAvLyByZWN1cnNpdmVseSBpbnZva2UgaG9va3Mgb24gY2hpbGQgY29tcG9uZW50IHJvb3Qgbm9kZQogICAgICAgIGlmIChpc0RlZihpID0gdm5vZGUuY29tcG9uZW50SW5zdGFuY2UpICYmIGlzRGVmKGkgPSBpLl92bm9kZSkgJiYgaXNEZWYoaS5kYXRhKSkgewogICAgICAgICAgcmVtb3ZlQW5kSW52b2tlUmVtb3ZlSG9vayhpLCBybSk7CiAgICAgICAgfQogICAgICAgIGZvciAoaSA9IDA7IGkgPCBjYnMucmVtb3ZlLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICBjYnMucmVtb3ZlW2ldKHZub2RlLCBybSk7CiAgICAgICAgfQogICAgICAgIGlmIChpc0RlZihpID0gdm5vZGUuZGF0YS5ob29rKSAmJiBpc0RlZihpID0gaS5yZW1vdmUpKSB7CiAgICAgICAgICBpKHZub2RlLCBybSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJtKCk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIHJlbW92ZU5vZGUodm5vZGUuZWxtKTsKICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHVwZGF0ZUNoaWxkcmVuIChwYXJlbnRFbG0sIG9sZENoLCBuZXdDaCwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCByZW1vdmVPbmx5KSB7CiAgICAgIHZhciBvbGRTdGFydElkeCA9IDA7CiAgICAgIHZhciBuZXdTdGFydElkeCA9IDA7CiAgICAgIHZhciBvbGRFbmRJZHggPSBvbGRDaC5sZW5ndGggLSAxOwogICAgICB2YXIgb2xkU3RhcnRWbm9kZSA9IG9sZENoWzBdOwogICAgICB2YXIgb2xkRW5kVm5vZGUgPSBvbGRDaFtvbGRFbmRJZHhdOwogICAgICB2YXIgbmV3RW5kSWR4ID0gbmV3Q2gubGVuZ3RoIC0gMTsKICAgICAgdmFyIG5ld1N0YXJ0Vm5vZGUgPSBuZXdDaFswXTsKICAgICAgdmFyIG5ld0VuZFZub2RlID0gbmV3Q2hbbmV3RW5kSWR4XTsKICAgICAgdmFyIG9sZEtleVRvSWR4LCBpZHhJbk9sZCwgdm5vZGVUb01vdmUsIHJlZkVsbTsKCiAgICAgIC8vIHJlbW92ZU9ubHkgaXMgYSBzcGVjaWFsIGZsYWcgdXNlZCBvbmx5IGJ5IDx0cmFuc2l0aW9uLWdyb3VwPgogICAgICAvLyB0byBlbnN1cmUgcmVtb3ZlZCBlbGVtZW50cyBzdGF5IGluIGNvcnJlY3QgcmVsYXRpdmUgcG9zaXRpb25zCiAgICAgIC8vIGR1cmluZyBsZWF2aW5nIHRyYW5zaXRpb25zCiAgICAgIHZhciBjYW5Nb3ZlID0gIXJlbW92ZU9ubHk7CgogICAgICB7CiAgICAgICAgY2hlY2tEdXBsaWNhdGVLZXlzKG5ld0NoKTsKICAgICAgfQoKICAgICAgd2hpbGUgKG9sZFN0YXJ0SWR4IDw9IG9sZEVuZElkeCAmJiBuZXdTdGFydElkeCA8PSBuZXdFbmRJZHgpIHsKICAgICAgICBpZiAoaXNVbmRlZihvbGRTdGFydFZub2RlKSkgewogICAgICAgICAgb2xkU3RhcnRWbm9kZSA9IG9sZENoWysrb2xkU3RhcnRJZHhdOyAvLyBWbm9kZSBoYXMgYmVlbiBtb3ZlZCBsZWZ0CiAgICAgICAgfSBlbHNlIGlmIChpc1VuZGVmKG9sZEVuZFZub2RlKSkgewogICAgICAgICAgb2xkRW5kVm5vZGUgPSBvbGRDaFstLW9sZEVuZElkeF07CiAgICAgICAgfSBlbHNlIGlmIChzYW1lVm5vZGUob2xkU3RhcnRWbm9kZSwgbmV3U3RhcnRWbm9kZSkpIHsKICAgICAgICAgIHBhdGNoVm5vZGUob2xkU3RhcnRWbm9kZSwgbmV3U3RhcnRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBuZXdDaCwgbmV3U3RhcnRJZHgpOwogICAgICAgICAgb2xkU3RhcnRWbm9kZSA9IG9sZENoWysrb2xkU3RhcnRJZHhdOwogICAgICAgICAgbmV3U3RhcnRWbm9kZSA9IG5ld0NoWysrbmV3U3RhcnRJZHhdOwogICAgICAgIH0gZWxzZSBpZiAoc2FtZVZub2RlKG9sZEVuZFZub2RlLCBuZXdFbmRWbm9kZSkpIHsKICAgICAgICAgIHBhdGNoVm5vZGUob2xkRW5kVm5vZGUsIG5ld0VuZFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIG5ld0NoLCBuZXdFbmRJZHgpOwogICAgICAgICAgb2xkRW5kVm5vZGUgPSBvbGRDaFstLW9sZEVuZElkeF07CiAgICAgICAgICBuZXdFbmRWbm9kZSA9IG5ld0NoWy0tbmV3RW5kSWR4XTsKICAgICAgICB9IGVsc2UgaWYgKHNhbWVWbm9kZShvbGRTdGFydFZub2RlLCBuZXdFbmRWbm9kZSkpIHsgLy8gVm5vZGUgbW92ZWQgcmlnaHQKICAgICAgICAgIHBhdGNoVm5vZGUob2xkU3RhcnRWbm9kZSwgbmV3RW5kVm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSwgbmV3Q2gsIG5ld0VuZElkeCk7CiAgICAgICAgICBjYW5Nb3ZlICYmIG5vZGVPcHMuaW5zZXJ0QmVmb3JlKHBhcmVudEVsbSwgb2xkU3RhcnRWbm9kZS5lbG0sIG5vZGVPcHMubmV4dFNpYmxpbmcob2xkRW5kVm5vZGUuZWxtKSk7CiAgICAgICAgICBvbGRTdGFydFZub2RlID0gb2xkQ2hbKytvbGRTdGFydElkeF07CiAgICAgICAgICBuZXdFbmRWbm9kZSA9IG5ld0NoWy0tbmV3RW5kSWR4XTsKICAgICAgICB9IGVsc2UgaWYgKHNhbWVWbm9kZShvbGRFbmRWbm9kZSwgbmV3U3RhcnRWbm9kZSkpIHsgLy8gVm5vZGUgbW92ZWQgbGVmdAogICAgICAgICAgcGF0Y2hWbm9kZShvbGRFbmRWbm9kZSwgbmV3U3RhcnRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBuZXdDaCwgbmV3U3RhcnRJZHgpOwogICAgICAgICAgY2FuTW92ZSAmJiBub2RlT3BzLmluc2VydEJlZm9yZShwYXJlbnRFbG0sIG9sZEVuZFZub2RlLmVsbSwgb2xkU3RhcnRWbm9kZS5lbG0pOwogICAgICAgICAgb2xkRW5kVm5vZGUgPSBvbGRDaFstLW9sZEVuZElkeF07CiAgICAgICAgICBuZXdTdGFydFZub2RlID0gbmV3Q2hbKytuZXdTdGFydElkeF07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChpc1VuZGVmKG9sZEtleVRvSWR4KSkgeyBvbGRLZXlUb0lkeCA9IGNyZWF0ZUtleVRvT2xkSWR4KG9sZENoLCBvbGRTdGFydElkeCwgb2xkRW5kSWR4KTsgfQogICAgICAgICAgaWR4SW5PbGQgPSBpc0RlZihuZXdTdGFydFZub2RlLmtleSkKICAgICAgICAgICAgPyBvbGRLZXlUb0lkeFtuZXdTdGFydFZub2RlLmtleV0KICAgICAgICAgICAgOiBmaW5kSWR4SW5PbGQobmV3U3RhcnRWbm9kZSwgb2xkQ2gsIG9sZFN0YXJ0SWR4LCBvbGRFbmRJZHgpOwogICAgICAgICAgaWYgKGlzVW5kZWYoaWR4SW5PbGQpKSB7IC8vIE5ldyBlbGVtZW50CiAgICAgICAgICAgIGNyZWF0ZUVsbShuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIHBhcmVudEVsbSwgb2xkU3RhcnRWbm9kZS5lbG0sIGZhbHNlLCBuZXdDaCwgbmV3U3RhcnRJZHgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdm5vZGVUb01vdmUgPSBvbGRDaFtpZHhJbk9sZF07CiAgICAgICAgICAgIGlmIChzYW1lVm5vZGUodm5vZGVUb01vdmUsIG5ld1N0YXJ0Vm5vZGUpKSB7CiAgICAgICAgICAgICAgcGF0Y2hWbm9kZSh2bm9kZVRvTW92ZSwgbmV3U3RhcnRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBuZXdDaCwgbmV3U3RhcnRJZHgpOwogICAgICAgICAgICAgIG9sZENoW2lkeEluT2xkXSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICBjYW5Nb3ZlICYmIG5vZGVPcHMuaW5zZXJ0QmVmb3JlKHBhcmVudEVsbSwgdm5vZGVUb01vdmUuZWxtLCBvbGRTdGFydFZub2RlLmVsbSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgLy8gc2FtZSBrZXkgYnV0IGRpZmZlcmVudCBlbGVtZW50LiB0cmVhdCBhcyBuZXcgZWxlbWVudAogICAgICAgICAgICAgIGNyZWF0ZUVsbShuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIHBhcmVudEVsbSwgb2xkU3RhcnRWbm9kZS5lbG0sIGZhbHNlLCBuZXdDaCwgbmV3U3RhcnRJZHgpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBuZXdTdGFydFZub2RlID0gbmV3Q2hbKytuZXdTdGFydElkeF07CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChvbGRTdGFydElkeCA+IG9sZEVuZElkeCkgewogICAgICAgIHJlZkVsbSA9IGlzVW5kZWYobmV3Q2hbbmV3RW5kSWR4ICsgMV0pID8gbnVsbCA6IG5ld0NoW25ld0VuZElkeCArIDFdLmVsbTsKICAgICAgICBhZGRWbm9kZXMocGFyZW50RWxtLCByZWZFbG0sIG5ld0NoLCBuZXdTdGFydElkeCwgbmV3RW5kSWR4LCBpbnNlcnRlZFZub2RlUXVldWUpOwogICAgICB9IGVsc2UgaWYgKG5ld1N0YXJ0SWR4ID4gbmV3RW5kSWR4KSB7CiAgICAgICAgcmVtb3ZlVm5vZGVzKHBhcmVudEVsbSwgb2xkQ2gsIG9sZFN0YXJ0SWR4LCBvbGRFbmRJZHgpOwogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY2hlY2tEdXBsaWNhdGVLZXlzIChjaGlsZHJlbikgewogICAgICB2YXIgc2VlbktleXMgPSB7fTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICAgIHZhciB2bm9kZSA9IGNoaWxkcmVuW2ldOwogICAgICAgIHZhciBrZXkgPSB2bm9kZS5rZXk7CiAgICAgICAgaWYgKGlzRGVmKGtleSkpIHsKICAgICAgICAgIGlmIChzZWVuS2V5c1trZXldKSB7CiAgICAgICAgICAgIHdhcm4oCiAgICAgICAgICAgICAgKCJEdXBsaWNhdGUga2V5cyBkZXRlY3RlZDogJyIgKyBrZXkgKyAiJy4gVGhpcyBtYXkgY2F1c2UgYW4gdXBkYXRlIGVycm9yLiIpLAogICAgICAgICAgICAgIHZub2RlLmNvbnRleHQKICAgICAgICAgICAgKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNlZW5LZXlzW2tleV0gPSB0cnVlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGZpbmRJZHhJbk9sZCAobm9kZSwgb2xkQ2gsIHN0YXJ0LCBlbmQpIHsKICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHsKICAgICAgICB2YXIgYyA9IG9sZENoW2ldOwogICAgICAgIGlmIChpc0RlZihjKSAmJiBzYW1lVm5vZGUobm9kZSwgYykpIHsgcmV0dXJuIGkgfQogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gcGF0Y2hWbm9kZSAoCiAgICAgIG9sZFZub2RlLAogICAgICB2bm9kZSwKICAgICAgaW5zZXJ0ZWRWbm9kZVF1ZXVlLAogICAgICBvd25lckFycmF5LAogICAgICBpbmRleCwKICAgICAgcmVtb3ZlT25seQogICAgKSB7CiAgICAgIGlmIChvbGRWbm9kZSA9PT0gdm5vZGUpIHsKICAgICAgICByZXR1cm4KICAgICAgfQoKICAgICAgaWYgKGlzRGVmKHZub2RlLmVsbSkgJiYgaXNEZWYob3duZXJBcnJheSkpIHsKICAgICAgICAvLyBjbG9uZSByZXVzZWQgdm5vZGUKICAgICAgICB2bm9kZSA9IG93bmVyQXJyYXlbaW5kZXhdID0gY2xvbmVWTm9kZSh2bm9kZSk7CiAgICAgIH0KCiAgICAgIHZhciBlbG0gPSB2bm9kZS5lbG0gPSBvbGRWbm9kZS5lbG07CgogICAgICBpZiAoaXNUcnVlKG9sZFZub2RlLmlzQXN5bmNQbGFjZWhvbGRlcikpIHsKICAgICAgICBpZiAoaXNEZWYodm5vZGUuYXN5bmNGYWN0b3J5LnJlc29sdmVkKSkgewogICAgICAgICAgaHlkcmF0ZShvbGRWbm9kZS5lbG0sIHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB2bm9kZS5pc0FzeW5jUGxhY2Vob2xkZXIgPSB0cnVlOwogICAgICAgIH0KICAgICAgICByZXR1cm4KICAgICAgfQoKICAgICAgLy8gcmV1c2UgZWxlbWVudCBmb3Igc3RhdGljIHRyZWVzLgogICAgICAvLyBub3RlIHdlIG9ubHkgZG8gdGhpcyBpZiB0aGUgdm5vZGUgaXMgY2xvbmVkIC0KICAgICAgLy8gaWYgdGhlIG5ldyBub2RlIGlzIG5vdCBjbG9uZWQgaXQgbWVhbnMgdGhlIHJlbmRlciBmdW5jdGlvbnMgaGF2ZSBiZWVuCiAgICAgIC8vIHJlc2V0IGJ5IHRoZSBob3QtcmVsb2FkLWFwaSBhbmQgd2UgbmVlZCB0byBkbyBhIHByb3BlciByZS1yZW5kZXIuCiAgICAgIGlmIChpc1RydWUodm5vZGUuaXNTdGF0aWMpICYmCiAgICAgICAgaXNUcnVlKG9sZFZub2RlLmlzU3RhdGljKSAmJgogICAgICAgIHZub2RlLmtleSA9PT0gb2xkVm5vZGUua2V5ICYmCiAgICAgICAgKGlzVHJ1ZSh2bm9kZS5pc0Nsb25lZCkgfHwgaXNUcnVlKHZub2RlLmlzT25jZSkpCiAgICAgICkgewogICAgICAgIHZub2RlLmNvbXBvbmVudEluc3RhbmNlID0gb2xkVm5vZGUuY29tcG9uZW50SW5zdGFuY2U7CiAgICAgICAgcmV0dXJuCiAgICAgIH0KCiAgICAgIHZhciBpOwogICAgICB2YXIgZGF0YSA9IHZub2RlLmRhdGE7CiAgICAgIGlmIChpc0RlZihkYXRhKSAmJiBpc0RlZihpID0gZGF0YS5ob29rKSAmJiBpc0RlZihpID0gaS5wcmVwYXRjaCkpIHsKICAgICAgICBpKG9sZFZub2RlLCB2bm9kZSk7CiAgICAgIH0KCiAgICAgIHZhciBvbGRDaCA9IG9sZFZub2RlLmNoaWxkcmVuOwogICAgICB2YXIgY2ggPSB2bm9kZS5jaGlsZHJlbjsKICAgICAgaWYgKGlzRGVmKGRhdGEpICYmIGlzUGF0Y2hhYmxlKHZub2RlKSkgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCBjYnMudXBkYXRlLmxlbmd0aDsgKytpKSB7IGNicy51cGRhdGVbaV0ob2xkVm5vZGUsIHZub2RlKTsgfQogICAgICAgIGlmIChpc0RlZihpID0gZGF0YS5ob29rKSAmJiBpc0RlZihpID0gaS51cGRhdGUpKSB7IGkob2xkVm5vZGUsIHZub2RlKTsgfQogICAgICB9CiAgICAgIGlmIChpc1VuZGVmKHZub2RlLnRleHQpKSB7CiAgICAgICAgaWYgKGlzRGVmKG9sZENoKSAmJiBpc0RlZihjaCkpIHsKICAgICAgICAgIGlmIChvbGRDaCAhPT0gY2gpIHsgdXBkYXRlQ2hpbGRyZW4oZWxtLCBvbGRDaCwgY2gsIGluc2VydGVkVm5vZGVRdWV1ZSwgcmVtb3ZlT25seSk7IH0KICAgICAgICB9IGVsc2UgaWYgKGlzRGVmKGNoKSkgewogICAgICAgICAgewogICAgICAgICAgICBjaGVja0R1cGxpY2F0ZUtleXMoY2gpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGlzRGVmKG9sZFZub2RlLnRleHQpKSB7IG5vZGVPcHMuc2V0VGV4dENvbnRlbnQoZWxtLCAnJyk7IH0KICAgICAgICAgIGFkZFZub2RlcyhlbG0sIG51bGwsIGNoLCAwLCBjaC5sZW5ndGggLSAxLCBpbnNlcnRlZFZub2RlUXVldWUpOwogICAgICAgIH0gZWxzZSBpZiAoaXNEZWYob2xkQ2gpKSB7CiAgICAgICAgICByZW1vdmVWbm9kZXMoZWxtLCBvbGRDaCwgMCwgb2xkQ2gubGVuZ3RoIC0gMSk7CiAgICAgICAgfSBlbHNlIGlmIChpc0RlZihvbGRWbm9kZS50ZXh0KSkgewogICAgICAgICAgbm9kZU9wcy5zZXRUZXh0Q29udGVudChlbG0sICcnKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAob2xkVm5vZGUudGV4dCAhPT0gdm5vZGUudGV4dCkgewogICAgICAgIG5vZGVPcHMuc2V0VGV4dENvbnRlbnQoZWxtLCB2bm9kZS50ZXh0KTsKICAgICAgfQogICAgICBpZiAoaXNEZWYoZGF0YSkpIHsKICAgICAgICBpZiAoaXNEZWYoaSA9IGRhdGEuaG9vaykgJiYgaXNEZWYoaSA9IGkucG9zdHBhdGNoKSkgeyBpKG9sZFZub2RlLCB2bm9kZSk7IH0KICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGludm9rZUluc2VydEhvb2sgKHZub2RlLCBxdWV1ZSwgaW5pdGlhbCkgewogICAgICAvLyBkZWxheSBpbnNlcnQgaG9va3MgZm9yIGNvbXBvbmVudCByb290IG5vZGVzLCBpbnZva2UgdGhlbSBhZnRlciB0aGUKICAgICAgLy8gZWxlbWVudCBpcyByZWFsbHkgaW5zZXJ0ZWQKICAgICAgaWYgKGlzVHJ1ZShpbml0aWFsKSAmJiBpc0RlZih2bm9kZS5wYXJlbnQpKSB7CiAgICAgICAgdm5vZGUucGFyZW50LmRhdGEucGVuZGluZ0luc2VydCA9IHF1ZXVlOwogICAgICB9IGVsc2UgewogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcXVldWUubGVuZ3RoOyArK2kpIHsKICAgICAgICAgIHF1ZXVlW2ldLmRhdGEuaG9vay5pbnNlcnQocXVldWVbaV0pOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIHZhciBoeWRyYXRpb25CYWlsZWQgPSBmYWxzZTsKICAgIC8vIGxpc3Qgb2YgbW9kdWxlcyB0aGF0IGNhbiBza2lwIGNyZWF0ZSBob29rIGR1cmluZyBoeWRyYXRpb24gYmVjYXVzZSB0aGV5CiAgICAvLyBhcmUgYWxyZWFkeSByZW5kZXJlZCBvbiB0aGUgY2xpZW50IG9yIGhhcyBubyBuZWVkIGZvciBpbml0aWFsaXphdGlvbgogICAgLy8gTm90ZTogc3R5bGUgaXMgZXhjbHVkZWQgYmVjYXVzZSBpdCByZWxpZXMgb24gaW5pdGlhbCBjbG9uZSBmb3IgZnV0dXJlCiAgICAvLyBkZWVwIHVwZGF0ZXMgKCM3MDYzKS4KICAgIHZhciBpc1JlbmRlcmVkTW9kdWxlID0gbWFrZU1hcCgnYXR0cnMsY2xhc3Msc3RhdGljQ2xhc3Msc3RhdGljU3R5bGUsa2V5Jyk7CgogICAgLy8gTm90ZTogdGhpcyBpcyBhIGJyb3dzZXItb25seSBmdW5jdGlvbiBzbyB3ZSBjYW4gYXNzdW1lIGVsbXMgYXJlIERPTSBub2Rlcy4KICAgIGZ1bmN0aW9uIGh5ZHJhdGUgKGVsbSwgdm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSwgaW5WUHJlKSB7CiAgICAgIHZhciBpOwogICAgICB2YXIgdGFnID0gdm5vZGUudGFnOwogICAgICB2YXIgZGF0YSA9IHZub2RlLmRhdGE7CiAgICAgIHZhciBjaGlsZHJlbiA9IHZub2RlLmNoaWxkcmVuOwogICAgICBpblZQcmUgPSBpblZQcmUgfHwgKGRhdGEgJiYgZGF0YS5wcmUpOwogICAgICB2bm9kZS5lbG0gPSBlbG07CgogICAgICBpZiAoaXNUcnVlKHZub2RlLmlzQ29tbWVudCkgJiYgaXNEZWYodm5vZGUuYXN5bmNGYWN0b3J5KSkgewogICAgICAgIHZub2RlLmlzQXN5bmNQbGFjZWhvbGRlciA9IHRydWU7CiAgICAgICAgcmV0dXJuIHRydWUKICAgICAgfQogICAgICAvLyBhc3NlcnQgbm9kZSBtYXRjaAogICAgICB7CiAgICAgICAgaWYgKCFhc3NlcnROb2RlTWF0Y2goZWxtLCB2bm9kZSwgaW5WUHJlKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChpc0RlZihkYXRhKSkgewogICAgICAgIGlmIChpc0RlZihpID0gZGF0YS5ob29rKSAmJiBpc0RlZihpID0gaS5pbml0KSkgeyBpKHZub2RlLCB0cnVlIC8qIGh5ZHJhdGluZyAqLyk7IH0KICAgICAgICBpZiAoaXNEZWYoaSA9IHZub2RlLmNvbXBvbmVudEluc3RhbmNlKSkgewogICAgICAgICAgLy8gY2hpbGQgY29tcG9uZW50LiBpdCBzaG91bGQgaGF2ZSBoeWRyYXRlZCBpdHMgb3duIHRyZWUuCiAgICAgICAgICBpbml0Q29tcG9uZW50KHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpOwogICAgICAgICAgcmV0dXJuIHRydWUKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGlzRGVmKHRhZykpIHsKICAgICAgICBpZiAoaXNEZWYoY2hpbGRyZW4pKSB7CiAgICAgICAgICAvLyBlbXB0eSBlbGVtZW50LCBhbGxvdyBjbGllbnQgdG8gcGljayB1cCBhbmQgcG9wdWxhdGUgY2hpbGRyZW4KICAgICAgICAgIGlmICghZWxtLmhhc0NoaWxkTm9kZXMoKSkgewogICAgICAgICAgICBjcmVhdGVDaGlsZHJlbih2bm9kZSwgY2hpbGRyZW4sIGluc2VydGVkVm5vZGVRdWV1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyB2LWh0bWwgYW5kIGRvbVByb3BzOiBpbm5lckhUTUwKICAgICAgICAgICAgaWYgKGlzRGVmKGkgPSBkYXRhKSAmJiBpc0RlZihpID0gaS5kb21Qcm9wcykgJiYgaXNEZWYoaSA9IGkuaW5uZXJIVE1MKSkgewogICAgICAgICAgICAgIGlmIChpICE9PSBlbG0uaW5uZXJIVE1MKSB7CiAgICAgICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcgJiYKICAgICAgICAgICAgICAgICAgIWh5ZHJhdGlvbkJhaWxlZAogICAgICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICAgIGh5ZHJhdGlvbkJhaWxlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUGFyZW50OiAnLCBlbG0pOwogICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ3NlcnZlciBpbm5lckhUTUw6ICcsIGkpOwogICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ2NsaWVudCBpbm5lckhUTUw6ICcsIGVsbS5pbm5lckhUTUwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIC8vIGl0ZXJhdGUgYW5kIGNvbXBhcmUgY2hpbGRyZW4gbGlzdHMKICAgICAgICAgICAgICB2YXIgY2hpbGRyZW5NYXRjaCA9IHRydWU7CiAgICAgICAgICAgICAgdmFyIGNoaWxkTm9kZSA9IGVsbS5maXJzdENoaWxkOwogICAgICAgICAgICAgIGZvciAodmFyIGkkMSA9IDA7IGkkMSA8IGNoaWxkcmVuLmxlbmd0aDsgaSQxKyspIHsKICAgICAgICAgICAgICAgIGlmICghY2hpbGROb2RlIHx8ICFoeWRyYXRlKGNoaWxkTm9kZSwgY2hpbGRyZW5baSQxXSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBpblZQcmUpKSB7CiAgICAgICAgICAgICAgICAgIGNoaWxkcmVuTWF0Y2ggPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNoaWxkTm9kZSA9IGNoaWxkTm9kZS5uZXh0U2libGluZzsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgLy8gaWYgY2hpbGROb2RlIGlzIG5vdCBudWxsLCBpdCBtZWFucyB0aGUgYWN0dWFsIGNoaWxkTm9kZXMgbGlzdCBpcwogICAgICAgICAgICAgIC8vIGxvbmdlciB0aGFuIHRoZSB2aXJ0dWFsIGNoaWxkcmVuIGxpc3QuCiAgICAgICAgICAgICAgaWYgKCFjaGlsZHJlbk1hdGNoIHx8IGNoaWxkTm9kZSkgewogICAgICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmCiAgICAgICAgICAgICAgICAgICFoeWRyYXRpb25CYWlsZWQKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICBoeWRyYXRpb25CYWlsZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1BhcmVudDogJywgZWxtKTsKICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdNaXNtYXRjaGluZyBjaGlsZE5vZGVzIHZzLiBWTm9kZXM6ICcsIGVsbS5jaGlsZE5vZGVzLCBjaGlsZHJlbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2UKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGlzRGVmKGRhdGEpKSB7CiAgICAgICAgICB2YXIgZnVsbEludm9rZSA9IGZhbHNlOwogICAgICAgICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHsKICAgICAgICAgICAgaWYgKCFpc1JlbmRlcmVkTW9kdWxlKGtleSkpIHsKICAgICAgICAgICAgICBmdWxsSW52b2tlID0gdHJ1ZTsKICAgICAgICAgICAgICBpbnZva2VDcmVhdGVIb29rcyh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTsKICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIWZ1bGxJbnZva2UgJiYgZGF0YVsnY2xhc3MnXSkgewogICAgICAgICAgICAvLyBlbnN1cmUgY29sbGVjdGluZyBkZXBzIGZvciBkZWVwIGNsYXNzIGJpbmRpbmdzIGZvciBmdXR1cmUgdXBkYXRlcwogICAgICAgICAgICB0cmF2ZXJzZShkYXRhWydjbGFzcyddKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoZWxtLmRhdGEgIT09IHZub2RlLnRleHQpIHsKICAgICAgICBlbG0uZGF0YSA9IHZub2RlLnRleHQ7CiAgICAgIH0KICAgICAgcmV0dXJuIHRydWUKICAgIH0KCiAgICBmdW5jdGlvbiBhc3NlcnROb2RlTWF0Y2ggKG5vZGUsIHZub2RlLCBpblZQcmUpIHsKICAgICAgaWYgKGlzRGVmKHZub2RlLnRhZykpIHsKICAgICAgICByZXR1cm4gdm5vZGUudGFnLmluZGV4T2YoJ3Z1ZS1jb21wb25lbnQnKSA9PT0gMCB8fCAoCiAgICAgICAgICAhaXNVbmtub3duRWxlbWVudCQkMSh2bm9kZSwgaW5WUHJlKSAmJgogICAgICAgICAgdm5vZGUudGFnLnRvTG93ZXJDYXNlKCkgPT09IChub2RlLnRhZ05hbWUgJiYgbm9kZS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpCiAgICAgICAgKQogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBub2RlLm5vZGVUeXBlID09PSAodm5vZGUuaXNDb21tZW50ID8gOCA6IDMpCiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gZnVuY3Rpb24gcGF0Y2ggKG9sZFZub2RlLCB2bm9kZSwgaHlkcmF0aW5nLCByZW1vdmVPbmx5KSB7CiAgICAgIGlmIChpc1VuZGVmKHZub2RlKSkgewogICAgICAgIGlmIChpc0RlZihvbGRWbm9kZSkpIHsgaW52b2tlRGVzdHJveUhvb2sob2xkVm5vZGUpOyB9CiAgICAgICAgcmV0dXJuCiAgICAgIH0KCiAgICAgIHZhciBpc0luaXRpYWxQYXRjaCA9IGZhbHNlOwogICAgICB2YXIgaW5zZXJ0ZWRWbm9kZVF1ZXVlID0gW107CgogICAgICBpZiAoaXNVbmRlZihvbGRWbm9kZSkpIHsKICAgICAgICAvLyBlbXB0eSBtb3VudCAobGlrZWx5IGFzIGNvbXBvbmVudCksIGNyZWF0ZSBuZXcgcm9vdCBlbGVtZW50CiAgICAgICAgaXNJbml0aWFsUGF0Y2ggPSB0cnVlOwogICAgICAgIGNyZWF0ZUVsbSh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB2YXIgaXNSZWFsRWxlbWVudCA9IGlzRGVmKG9sZFZub2RlLm5vZGVUeXBlKTsKICAgICAgICBpZiAoIWlzUmVhbEVsZW1lbnQgJiYgc2FtZVZub2RlKG9sZFZub2RlLCB2bm9kZSkpIHsKICAgICAgICAgIC8vIHBhdGNoIGV4aXN0aW5nIHJvb3Qgbm9kZQogICAgICAgICAgcGF0Y2hWbm9kZShvbGRWbm9kZSwgdm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSwgbnVsbCwgbnVsbCwgcmVtb3ZlT25seSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChpc1JlYWxFbGVtZW50KSB7CiAgICAgICAgICAgIC8vIG1vdW50aW5nIHRvIGEgcmVhbCBlbGVtZW50CiAgICAgICAgICAgIC8vIGNoZWNrIGlmIHRoaXMgaXMgc2VydmVyLXJlbmRlcmVkIGNvbnRlbnQgYW5kIGlmIHdlIGNhbiBwZXJmb3JtCiAgICAgICAgICAgIC8vIGEgc3VjY2Vzc2Z1bCBoeWRyYXRpb24uCiAgICAgICAgICAgIGlmIChvbGRWbm9kZS5ub2RlVHlwZSA9PT0gMSAmJiBvbGRWbm9kZS5oYXNBdHRyaWJ1dGUoU1NSX0FUVFIpKSB7CiAgICAgICAgICAgICAgb2xkVm5vZGUucmVtb3ZlQXR0cmlidXRlKFNTUl9BVFRSKTsKICAgICAgICAgICAgICBoeWRyYXRpbmcgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc1RydWUoaHlkcmF0aW5nKSkgewogICAgICAgICAgICAgIGlmIChoeWRyYXRlKG9sZFZub2RlLCB2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKSkgewogICAgICAgICAgICAgICAgaW52b2tlSW5zZXJ0SG9vayh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCB0cnVlKTsKICAgICAgICAgICAgICAgIHJldHVybiBvbGRWbm9kZQogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB3YXJuKAogICAgICAgICAgICAgICAgICAnVGhlIGNsaWVudC1zaWRlIHJlbmRlcmVkIHZpcnR1YWwgRE9NIHRyZWUgaXMgbm90IG1hdGNoaW5nICcgKwogICAgICAgICAgICAgICAgICAnc2VydmVyLXJlbmRlcmVkIGNvbnRlbnQuIFRoaXMgaXMgbGlrZWx5IGNhdXNlZCBieSBpbmNvcnJlY3QgJyArCiAgICAgICAgICAgICAgICAgICdIVE1MIG1hcmt1cCwgZm9yIGV4YW1wbGUgbmVzdGluZyBibG9jay1sZXZlbCBlbGVtZW50cyBpbnNpZGUgJyArCiAgICAgICAgICAgICAgICAgICc8cD4sIG9yIG1pc3NpbmcgPHRib2R5Pi4gQmFpbGluZyBoeWRyYXRpb24gYW5kIHBlcmZvcm1pbmcgJyArCiAgICAgICAgICAgICAgICAgICdmdWxsIGNsaWVudC1zaWRlIHJlbmRlci4nCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBlaXRoZXIgbm90IHNlcnZlci1yZW5kZXJlZCwgb3IgaHlkcmF0aW9uIGZhaWxlZC4KICAgICAgICAgICAgLy8gY3JlYXRlIGFuIGVtcHR5IG5vZGUgYW5kIHJlcGxhY2UgaXQKICAgICAgICAgICAgb2xkVm5vZGUgPSBlbXB0eU5vZGVBdChvbGRWbm9kZSk7CiAgICAgICAgICB9CgogICAgICAgICAgLy8gcmVwbGFjaW5nIGV4aXN0aW5nIGVsZW1lbnQKICAgICAgICAgIHZhciBvbGRFbG0gPSBvbGRWbm9kZS5lbG07CiAgICAgICAgICB2YXIgcGFyZW50RWxtID0gbm9kZU9wcy5wYXJlbnROb2RlKG9sZEVsbSk7CgogICAgICAgICAgLy8gY3JlYXRlIG5ldyBub2RlCiAgICAgICAgICBjcmVhdGVFbG0oCiAgICAgICAgICAgIHZub2RlLAogICAgICAgICAgICBpbnNlcnRlZFZub2RlUXVldWUsCiAgICAgICAgICAgIC8vIGV4dHJlbWVseSByYXJlIGVkZ2UgY2FzZTogZG8gbm90IGluc2VydCBpZiBvbGQgZWxlbWVudCBpcyBpbiBhCiAgICAgICAgICAgIC8vIGxlYXZpbmcgdHJhbnNpdGlvbi4gT25seSBoYXBwZW5zIHdoZW4gY29tYmluaW5nIHRyYW5zaXRpb24gKwogICAgICAgICAgICAvLyBrZWVwLWFsaXZlICsgSE9Dcy4gKCM0NTkwKQogICAgICAgICAgICBvbGRFbG0uX2xlYXZlQ2IgPyBudWxsIDogcGFyZW50RWxtLAogICAgICAgICAgICBub2RlT3BzLm5leHRTaWJsaW5nKG9sZEVsbSkKICAgICAgICAgICk7CgogICAgICAgICAgLy8gdXBkYXRlIHBhcmVudCBwbGFjZWhvbGRlciBub2RlIGVsZW1lbnQsIHJlY3Vyc2l2ZWx5CiAgICAgICAgICBpZiAoaXNEZWYodm5vZGUucGFyZW50KSkgewogICAgICAgICAgICB2YXIgYW5jZXN0b3IgPSB2bm9kZS5wYXJlbnQ7CiAgICAgICAgICAgIHZhciBwYXRjaGFibGUgPSBpc1BhdGNoYWJsZSh2bm9kZSk7CiAgICAgICAgICAgIHdoaWxlIChhbmNlc3RvcikgewogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2JzLmRlc3Ryb3kubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIGNicy5kZXN0cm95W2ldKGFuY2VzdG9yKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYW5jZXN0b3IuZWxtID0gdm5vZGUuZWxtOwogICAgICAgICAgICAgIGlmIChwYXRjaGFibGUpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkkMSA9IDA7IGkkMSA8IGNicy5jcmVhdGUubGVuZ3RoOyArK2kkMSkgewogICAgICAgICAgICAgICAgICBjYnMuY3JlYXRlW2kkMV0oZW1wdHlOb2RlLCBhbmNlc3Rvcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyAjNjUxMwogICAgICAgICAgICAgICAgLy8gaW52b2tlIGluc2VydCBob29rcyB0aGF0IG1heSBoYXZlIGJlZW4gbWVyZ2VkIGJ5IGNyZWF0ZSBob29rcy4KICAgICAgICAgICAgICAgIC8vIGUuZy4gZm9yIGRpcmVjdGl2ZXMgdGhhdCB1c2VzIHRoZSAiaW5zZXJ0ZWQiIGhvb2suCiAgICAgICAgICAgICAgICB2YXIgaW5zZXJ0ID0gYW5jZXN0b3IuZGF0YS5ob29rLmluc2VydDsKICAgICAgICAgICAgICAgIGlmIChpbnNlcnQubWVyZ2VkKSB7CiAgICAgICAgICAgICAgICAgIC8vIHN0YXJ0IGF0IGluZGV4IDEgdG8gYXZvaWQgcmUtaW52b2tpbmcgY29tcG9uZW50IG1vdW50ZWQgaG9vawogICAgICAgICAgICAgICAgICBmb3IgKHZhciBpJDIgPSAxOyBpJDIgPCBpbnNlcnQuZm5zLmxlbmd0aDsgaSQyKyspIHsKICAgICAgICAgICAgICAgICAgICBpbnNlcnQuZm5zW2kkMl0oKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZWdpc3RlclJlZihhbmNlc3Rvcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGFuY2VzdG9yID0gYW5jZXN0b3IucGFyZW50OwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgLy8gZGVzdHJveSBvbGQgbm9kZQogICAgICAgICAgaWYgKGlzRGVmKHBhcmVudEVsbSkpIHsKICAgICAgICAgICAgcmVtb3ZlVm5vZGVzKHBhcmVudEVsbSwgW29sZFZub2RlXSwgMCwgMCk7CiAgICAgICAgICB9IGVsc2UgaWYgKGlzRGVmKG9sZFZub2RlLnRhZykpIHsKICAgICAgICAgICAgaW52b2tlRGVzdHJveUhvb2sob2xkVm5vZGUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgaW52b2tlSW5zZXJ0SG9vayh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBpc0luaXRpYWxQYXRjaCk7CiAgICAgIHJldHVybiB2bm9kZS5lbG0KICAgIH0KICB9CgogIC8qICAqLwoKICB2YXIgZGlyZWN0aXZlcyA9IHsKICAgIGNyZWF0ZTogdXBkYXRlRGlyZWN0aXZlcywKICAgIHVwZGF0ZTogdXBkYXRlRGlyZWN0aXZlcywKICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIHVuYmluZERpcmVjdGl2ZXMgKHZub2RlKSB7CiAgICAgIHVwZGF0ZURpcmVjdGl2ZXModm5vZGUsIGVtcHR5Tm9kZSk7CiAgICB9CiAgfTsKCiAgZnVuY3Rpb24gdXBkYXRlRGlyZWN0aXZlcyAob2xkVm5vZGUsIHZub2RlKSB7CiAgICBpZiAob2xkVm5vZGUuZGF0YS5kaXJlY3RpdmVzIHx8IHZub2RlLmRhdGEuZGlyZWN0aXZlcykgewogICAgICBfdXBkYXRlKG9sZFZub2RlLCB2bm9kZSk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBfdXBkYXRlIChvbGRWbm9kZSwgdm5vZGUpIHsKICAgIHZhciBpc0NyZWF0ZSA9IG9sZFZub2RlID09PSBlbXB0eU5vZGU7CiAgICB2YXIgaXNEZXN0cm95ID0gdm5vZGUgPT09IGVtcHR5Tm9kZTsKICAgIHZhciBvbGREaXJzID0gbm9ybWFsaXplRGlyZWN0aXZlcyQxKG9sZFZub2RlLmRhdGEuZGlyZWN0aXZlcywgb2xkVm5vZGUuY29udGV4dCk7CiAgICB2YXIgbmV3RGlycyA9IG5vcm1hbGl6ZURpcmVjdGl2ZXMkMSh2bm9kZS5kYXRhLmRpcmVjdGl2ZXMsIHZub2RlLmNvbnRleHQpOwoKICAgIHZhciBkaXJzV2l0aEluc2VydCA9IFtdOwogICAgdmFyIGRpcnNXaXRoUG9zdHBhdGNoID0gW107CgogICAgdmFyIGtleSwgb2xkRGlyLCBkaXI7CiAgICBmb3IgKGtleSBpbiBuZXdEaXJzKSB7CiAgICAgIG9sZERpciA9IG9sZERpcnNba2V5XTsKICAgICAgZGlyID0gbmV3RGlyc1trZXldOwogICAgICBpZiAoIW9sZERpcikgewogICAgICAgIC8vIG5ldyBkaXJlY3RpdmUsIGJpbmQKICAgICAgICBjYWxsSG9vayQxKGRpciwgJ2JpbmQnLCB2bm9kZSwgb2xkVm5vZGUpOwogICAgICAgIGlmIChkaXIuZGVmICYmIGRpci5kZWYuaW5zZXJ0ZWQpIHsKICAgICAgICAgIGRpcnNXaXRoSW5zZXJ0LnB1c2goZGlyKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gZXhpc3RpbmcgZGlyZWN0aXZlLCB1cGRhdGUKICAgICAgICBkaXIub2xkVmFsdWUgPSBvbGREaXIudmFsdWU7CiAgICAgICAgZGlyLm9sZEFyZyA9IG9sZERpci5hcmc7CiAgICAgICAgY2FsbEhvb2skMShkaXIsICd1cGRhdGUnLCB2bm9kZSwgb2xkVm5vZGUpOwogICAgICAgIGlmIChkaXIuZGVmICYmIGRpci5kZWYuY29tcG9uZW50VXBkYXRlZCkgewogICAgICAgICAgZGlyc1dpdGhQb3N0cGF0Y2gucHVzaChkaXIpOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGlmIChkaXJzV2l0aEluc2VydC5sZW5ndGgpIHsKICAgICAgdmFyIGNhbGxJbnNlcnQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkaXJzV2l0aEluc2VydC5sZW5ndGg7IGkrKykgewogICAgICAgICAgY2FsbEhvb2skMShkaXJzV2l0aEluc2VydFtpXSwgJ2luc2VydGVkJywgdm5vZGUsIG9sZFZub2RlKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIGlmIChpc0NyZWF0ZSkgewogICAgICAgIG1lcmdlVk5vZGVIb29rKHZub2RlLCAnaW5zZXJ0JywgY2FsbEluc2VydCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY2FsbEluc2VydCgpOwogICAgICB9CiAgICB9CgogICAgaWYgKGRpcnNXaXRoUG9zdHBhdGNoLmxlbmd0aCkgewogICAgICBtZXJnZVZOb2RlSG9vayh2bm9kZSwgJ3Bvc3RwYXRjaCcsIGZ1bmN0aW9uICgpIHsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRpcnNXaXRoUG9zdHBhdGNoLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICBjYWxsSG9vayQxKGRpcnNXaXRoUG9zdHBhdGNoW2ldLCAnY29tcG9uZW50VXBkYXRlZCcsIHZub2RlLCBvbGRWbm9kZSk7CiAgICAgICAgfQogICAgICB9KTsKICAgIH0KCiAgICBpZiAoIWlzQ3JlYXRlKSB7CiAgICAgIGZvciAoa2V5IGluIG9sZERpcnMpIHsKICAgICAgICBpZiAoIW5ld0RpcnNba2V5XSkgewogICAgICAgICAgLy8gbm8gbG9uZ2VyIHByZXNlbnQsIHVuYmluZAogICAgICAgICAgY2FsbEhvb2skMShvbGREaXJzW2tleV0sICd1bmJpbmQnLCBvbGRWbm9kZSwgb2xkVm5vZGUsIGlzRGVzdHJveSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICB2YXIgZW1wdHlNb2RpZmllcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpOwoKICBmdW5jdGlvbiBub3JtYWxpemVEaXJlY3RpdmVzJDEgKAogICAgZGlycywKICAgIHZtCiAgKSB7CiAgICB2YXIgcmVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKICAgIGlmICghZGlycykgewogICAgICAvLyAkZmxvdy1kaXNhYmxlLWxpbmUKICAgICAgcmV0dXJuIHJlcwogICAgfQogICAgdmFyIGksIGRpcjsKICAgIGZvciAoaSA9IDA7IGkgPCBkaXJzLmxlbmd0aDsgaSsrKSB7CiAgICAgIGRpciA9IGRpcnNbaV07CiAgICAgIGlmICghZGlyLm1vZGlmaWVycykgewogICAgICAgIC8vICRmbG93LWRpc2FibGUtbGluZQogICAgICAgIGRpci5tb2RpZmllcnMgPSBlbXB0eU1vZGlmaWVyczsKICAgICAgfQogICAgICByZXNbZ2V0UmF3RGlyTmFtZShkaXIpXSA9IGRpcjsKICAgICAgZGlyLmRlZiA9IHJlc29sdmVBc3NldCh2bS4kb3B0aW9ucywgJ2RpcmVjdGl2ZXMnLCBkaXIubmFtZSwgdHJ1ZSk7CiAgICB9CiAgICAvLyAkZmxvdy1kaXNhYmxlLWxpbmUKICAgIHJldHVybiByZXMKICB9CgogIGZ1bmN0aW9uIGdldFJhd0Rpck5hbWUgKGRpcikgewogICAgcmV0dXJuIGRpci5yYXdOYW1lIHx8ICgoZGlyLm5hbWUpICsgIi4iICsgKE9iamVjdC5rZXlzKGRpci5tb2RpZmllcnMgfHwge30pLmpvaW4oJy4nKSkpCiAgfQoKICBmdW5jdGlvbiBjYWxsSG9vayQxIChkaXIsIGhvb2ssIHZub2RlLCBvbGRWbm9kZSwgaXNEZXN0cm95KSB7CiAgICB2YXIgZm4gPSBkaXIuZGVmICYmIGRpci5kZWZbaG9va107CiAgICBpZiAoZm4pIHsKICAgICAgdHJ5IHsKICAgICAgICBmbih2bm9kZS5lbG0sIGRpciwgdm5vZGUsIG9sZFZub2RlLCBpc0Rlc3Ryb3kpOwogICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgaGFuZGxlRXJyb3IoZSwgdm5vZGUuY29udGV4dCwgKCJkaXJlY3RpdmUgIiArIChkaXIubmFtZSkgKyAiICIgKyBob29rICsgIiBob29rIikpOwogICAgICB9CiAgICB9CiAgfQoKICB2YXIgYmFzZU1vZHVsZXMgPSBbCiAgICByZWYsCiAgICBkaXJlY3RpdmVzCiAgXTsKCiAgLyogICovCgogIGZ1bmN0aW9uIHVwZGF0ZUF0dHJzIChvbGRWbm9kZSwgdm5vZGUpIHsKICAgIHZhciBvcHRzID0gdm5vZGUuY29tcG9uZW50T3B0aW9uczsKICAgIGlmIChpc0RlZihvcHRzKSAmJiBvcHRzLkN0b3Iub3B0aW9ucy5pbmhlcml0QXR0cnMgPT09IGZhbHNlKSB7CiAgICAgIHJldHVybgogICAgfQogICAgaWYgKGlzVW5kZWYob2xkVm5vZGUuZGF0YS5hdHRycykgJiYgaXNVbmRlZih2bm9kZS5kYXRhLmF0dHJzKSkgewogICAgICByZXR1cm4KICAgIH0KICAgIHZhciBrZXksIGN1ciwgb2xkOwogICAgdmFyIGVsbSA9IHZub2RlLmVsbTsKICAgIHZhciBvbGRBdHRycyA9IG9sZFZub2RlLmRhdGEuYXR0cnMgfHwge307CiAgICB2YXIgYXR0cnMgPSB2bm9kZS5kYXRhLmF0dHJzIHx8IHt9OwogICAgLy8gY2xvbmUgb2JzZXJ2ZWQgb2JqZWN0cywgYXMgdGhlIHVzZXIgcHJvYmFibHkgd2FudHMgdG8gbXV0YXRlIGl0CiAgICBpZiAoaXNEZWYoYXR0cnMuX19vYl9fKSkgewogICAgICBhdHRycyA9IHZub2RlLmRhdGEuYXR0cnMgPSBleHRlbmQoe30sIGF0dHJzKTsKICAgIH0KCiAgICBmb3IgKGtleSBpbiBhdHRycykgewogICAgICBjdXIgPSBhdHRyc1trZXldOwogICAgICBvbGQgPSBvbGRBdHRyc1trZXldOwogICAgICBpZiAob2xkICE9PSBjdXIpIHsKICAgICAgICBzZXRBdHRyKGVsbSwga2V5LCBjdXIpOwogICAgICB9CiAgICB9CiAgICAvLyAjNDM5MTogaW4gSUU5LCBzZXR0aW5nIHR5cGUgY2FuIHJlc2V0IHZhbHVlIGZvciBpbnB1dFt0eXBlPXJhZGlvXQogICAgLy8gIzY2NjY6IElFL0VkZ2UgZm9yY2VzIHByb2dyZXNzIHZhbHVlIGRvd24gdG8gMSBiZWZvcmUgc2V0dGluZyBhIG1heAogICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICBpZiAoKGlzSUUgfHwgaXNFZGdlKSAmJiBhdHRycy52YWx1ZSAhPT0gb2xkQXR0cnMudmFsdWUpIHsKICAgICAgc2V0QXR0cihlbG0sICd2YWx1ZScsIGF0dHJzLnZhbHVlKTsKICAgIH0KICAgIGZvciAoa2V5IGluIG9sZEF0dHJzKSB7CiAgICAgIGlmIChpc1VuZGVmKGF0dHJzW2tleV0pKSB7CiAgICAgICAgaWYgKGlzWGxpbmsoa2V5KSkgewogICAgICAgICAgZWxtLnJlbW92ZUF0dHJpYnV0ZU5TKHhsaW5rTlMsIGdldFhsaW5rUHJvcChrZXkpKTsKICAgICAgICB9IGVsc2UgaWYgKCFpc0VudW1lcmF0ZWRBdHRyKGtleSkpIHsKICAgICAgICAgIGVsbS5yZW1vdmVBdHRyaWJ1dGUoa2V5KTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIHNldEF0dHIgKGVsLCBrZXksIHZhbHVlKSB7CiAgICBpZiAoZWwudGFnTmFtZS5pbmRleE9mKCctJykgPiAtMSkgewogICAgICBiYXNlU2V0QXR0cihlbCwga2V5LCB2YWx1ZSk7CiAgICB9IGVsc2UgaWYgKGlzQm9vbGVhbkF0dHIoa2V5KSkgewogICAgICAvLyBzZXQgYXR0cmlidXRlIGZvciBibGFuayB2YWx1ZQogICAgICAvLyBlLmcuIDxvcHRpb24gZGlzYWJsZWQ+U2VsZWN0IG9uZTwvb3B0aW9uPgogICAgICBpZiAoaXNGYWxzeUF0dHJWYWx1ZSh2YWx1ZSkpIHsKICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoa2V5KTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyB0ZWNobmljYWxseSBhbGxvd2Z1bGxzY3JlZW4gaXMgYSBib29sZWFuIGF0dHJpYnV0ZSBmb3IgPGlmcmFtZT4sCiAgICAgICAgLy8gYnV0IEZsYXNoIGV4cGVjdHMgYSB2YWx1ZSBvZiAidHJ1ZSIgd2hlbiB1c2VkIG9uIDxlbWJlZD4gdGFnCiAgICAgICAgdmFsdWUgPSBrZXkgPT09ICdhbGxvd2Z1bGxzY3JlZW4nICYmIGVsLnRhZ05hbWUgPT09ICdFTUJFRCcKICAgICAgICAgID8gJ3RydWUnCiAgICAgICAgICA6IGtleTsKICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoa2V5LCB2YWx1ZSk7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoaXNFbnVtZXJhdGVkQXR0cihrZXkpKSB7CiAgICAgIGVsLnNldEF0dHJpYnV0ZShrZXksIGNvbnZlcnRFbnVtZXJhdGVkVmFsdWUoa2V5LCB2YWx1ZSkpOwogICAgfSBlbHNlIGlmIChpc1hsaW5rKGtleSkpIHsKICAgICAgaWYgKGlzRmFsc3lBdHRyVmFsdWUodmFsdWUpKSB7CiAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlTlMoeGxpbmtOUywgZ2V0WGxpbmtQcm9wKGtleSkpOwogICAgICB9IGVsc2UgewogICAgICAgIGVsLnNldEF0dHJpYnV0ZU5TKHhsaW5rTlMsIGtleSwgdmFsdWUpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBiYXNlU2V0QXR0cihlbCwga2V5LCB2YWx1ZSk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBiYXNlU2V0QXR0ciAoZWwsIGtleSwgdmFsdWUpIHsKICAgIGlmIChpc0ZhbHN5QXR0clZhbHVlKHZhbHVlKSkgewogICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoa2V5KTsKICAgIH0gZWxzZSB7CiAgICAgIC8vICM3MTM4OiBJRTEwICYgMTEgZmlyZXMgaW5wdXQgZXZlbnQgd2hlbiBzZXR0aW5nIHBsYWNlaG9sZGVyIG9uCiAgICAgIC8vIDx0ZXh0YXJlYT4uLi4gYmxvY2sgdGhlIGZpcnN0IGlucHV0IGV2ZW50IGFuZCByZW1vdmUgdGhlIGJsb2NrZXIKICAgICAgLy8gaW1tZWRpYXRlbHkuCiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgICBpZiAoCiAgICAgICAgaXNJRSAmJiAhaXNJRTkgJiYKICAgICAgICBlbC50YWdOYW1lID09PSAnVEVYVEFSRUEnICYmCiAgICAgICAga2V5ID09PSAncGxhY2Vob2xkZXInICYmIHZhbHVlICE9PSAnJyAmJiAhZWwuX19pZXBoCiAgICAgICkgewogICAgICAgIHZhciBibG9ja2VyID0gZnVuY3Rpb24gKGUpIHsKICAgICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7CiAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKCdpbnB1dCcsIGJsb2NrZXIpOwogICAgICAgIH07CiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBibG9ja2VyKTsKICAgICAgICAvLyAkZmxvdy1kaXNhYmxlLWxpbmUKICAgICAgICBlbC5fX2llcGggPSB0cnVlOyAvKiBJRSBwbGFjZWhvbGRlciBwYXRjaGVkICovCiAgICAgIH0KICAgICAgZWwuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpOwogICAgfQogIH0KCiAgdmFyIGF0dHJzID0gewogICAgY3JlYXRlOiB1cGRhdGVBdHRycywKICAgIHVwZGF0ZTogdXBkYXRlQXR0cnMKICB9OwoKICAvKiAgKi8KCiAgZnVuY3Rpb24gdXBkYXRlQ2xhc3MgKG9sZFZub2RlLCB2bm9kZSkgewogICAgdmFyIGVsID0gdm5vZGUuZWxtOwogICAgdmFyIGRhdGEgPSB2bm9kZS5kYXRhOwogICAgdmFyIG9sZERhdGEgPSBvbGRWbm9kZS5kYXRhOwogICAgaWYgKAogICAgICBpc1VuZGVmKGRhdGEuc3RhdGljQ2xhc3MpICYmCiAgICAgIGlzVW5kZWYoZGF0YS5jbGFzcykgJiYgKAogICAgICAgIGlzVW5kZWYob2xkRGF0YSkgfHwgKAogICAgICAgICAgaXNVbmRlZihvbGREYXRhLnN0YXRpY0NsYXNzKSAmJgogICAgICAgICAgaXNVbmRlZihvbGREYXRhLmNsYXNzKQogICAgICAgICkKICAgICAgKQogICAgKSB7CiAgICAgIHJldHVybgogICAgfQoKICAgIHZhciBjbHMgPSBnZW5DbGFzc0ZvclZub2RlKHZub2RlKTsKCiAgICAvLyBoYW5kbGUgdHJhbnNpdGlvbiBjbGFzc2VzCiAgICB2YXIgdHJhbnNpdGlvbkNsYXNzID0gZWwuX3RyYW5zaXRpb25DbGFzc2VzOwogICAgaWYgKGlzRGVmKHRyYW5zaXRpb25DbGFzcykpIHsKICAgICAgY2xzID0gY29uY2F0KGNscywgc3RyaW5naWZ5Q2xhc3ModHJhbnNpdGlvbkNsYXNzKSk7CiAgICB9CgogICAgLy8gc2V0IHRoZSBjbGFzcwogICAgaWYgKGNscyAhPT0gZWwuX3ByZXZDbGFzcykgewogICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgY2xzKTsKICAgICAgZWwuX3ByZXZDbGFzcyA9IGNsczsKICAgIH0KICB9CgogIHZhciBrbGFzcyA9IHsKICAgIGNyZWF0ZTogdXBkYXRlQ2xhc3MsCiAgICB1cGRhdGU6IHVwZGF0ZUNsYXNzCiAgfTsKCiAgLyogICovCgogIHZhciB2YWxpZERpdmlzaW9uQ2hhclJFID0gL1tcdykuK1wtXyRcXV0vOwoKICBmdW5jdGlvbiBwYXJzZUZpbHRlcnMgKGV4cCkgewogICAgdmFyIGluU2luZ2xlID0gZmFsc2U7CiAgICB2YXIgaW5Eb3VibGUgPSBmYWxzZTsKICAgIHZhciBpblRlbXBsYXRlU3RyaW5nID0gZmFsc2U7CiAgICB2YXIgaW5SZWdleCA9IGZhbHNlOwogICAgdmFyIGN1cmx5ID0gMDsKICAgIHZhciBzcXVhcmUgPSAwOwogICAgdmFyIHBhcmVuID0gMDsKICAgIHZhciBsYXN0RmlsdGVySW5kZXggPSAwOwogICAgdmFyIGMsIHByZXYsIGksIGV4cHJlc3Npb24sIGZpbHRlcnM7CgogICAgZm9yIChpID0gMDsgaSA8IGV4cC5sZW5ndGg7IGkrKykgewogICAgICBwcmV2ID0gYzsKICAgICAgYyA9IGV4cC5jaGFyQ29kZUF0KGkpOwogICAgICBpZiAoaW5TaW5nbGUpIHsKICAgICAgICBpZiAoYyA9PT0gMHgyNyAmJiBwcmV2ICE9PSAweDVDKSB7IGluU2luZ2xlID0gZmFsc2U7IH0KICAgICAgfSBlbHNlIGlmIChpbkRvdWJsZSkgewogICAgICAgIGlmIChjID09PSAweDIyICYmIHByZXYgIT09IDB4NUMpIHsgaW5Eb3VibGUgPSBmYWxzZTsgfQogICAgICB9IGVsc2UgaWYgKGluVGVtcGxhdGVTdHJpbmcpIHsKICAgICAgICBpZiAoYyA9PT0gMHg2MCAmJiBwcmV2ICE9PSAweDVDKSB7IGluVGVtcGxhdGVTdHJpbmcgPSBmYWxzZTsgfQogICAgICB9IGVsc2UgaWYgKGluUmVnZXgpIHsKICAgICAgICBpZiAoYyA9PT0gMHgyZiAmJiBwcmV2ICE9PSAweDVDKSB7IGluUmVnZXggPSBmYWxzZTsgfQogICAgICB9IGVsc2UgaWYgKAogICAgICAgIGMgPT09IDB4N0MgJiYgLy8gcGlwZQogICAgICAgIGV4cC5jaGFyQ29kZUF0KGkgKyAxKSAhPT0gMHg3QyAmJgogICAgICAgIGV4cC5jaGFyQ29kZUF0KGkgLSAxKSAhPT0gMHg3QyAmJgogICAgICAgICFjdXJseSAmJiAhc3F1YXJlICYmICFwYXJlbgogICAgICApIHsKICAgICAgICBpZiAoZXhwcmVzc2lvbiA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAvLyBmaXJzdCBmaWx0ZXIsIGVuZCBvZiBleHByZXNzaW9uCiAgICAgICAgICBsYXN0RmlsdGVySW5kZXggPSBpICsgMTsKICAgICAgICAgIGV4cHJlc3Npb24gPSBleHAuc2xpY2UoMCwgaSkudHJpbSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwdXNoRmlsdGVyKCk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIHN3aXRjaCAoYykgewogICAgICAgICAgY2FzZSAweDIyOiBpbkRvdWJsZSA9IHRydWU7IGJyZWFrICAgICAgICAgLy8gIgogICAgICAgICAgY2FzZSAweDI3OiBpblNpbmdsZSA9IHRydWU7IGJyZWFrICAgICAgICAgLy8gJwogICAgICAgICAgY2FzZSAweDYwOiBpblRlbXBsYXRlU3RyaW5nID0gdHJ1ZTsgYnJlYWsgLy8gYAogICAgICAgICAgY2FzZSAweDI4OiBwYXJlbisrOyBicmVhayAgICAgICAgICAgICAgICAgLy8gKAogICAgICAgICAgY2FzZSAweDI5OiBwYXJlbi0tOyBicmVhayAgICAgICAgICAgICAgICAgLy8gKQogICAgICAgICAgY2FzZSAweDVCOiBzcXVhcmUrKzsgYnJlYWsgICAgICAgICAgICAgICAgLy8gWwogICAgICAgICAgY2FzZSAweDVEOiBzcXVhcmUtLTsgYnJlYWsgICAgICAgICAgICAgICAgLy8gXQogICAgICAgICAgY2FzZSAweDdCOiBjdXJseSsrOyBicmVhayAgICAgICAgICAgICAgICAgLy8gewogICAgICAgICAgY2FzZSAweDdEOiBjdXJseS0tOyBicmVhayAgICAgICAgICAgICAgICAgLy8gfQogICAgICAgIH0KICAgICAgICBpZiAoYyA9PT0gMHgyZikgeyAvLyAvCiAgICAgICAgICB2YXIgaiA9IGkgLSAxOwogICAgICAgICAgdmFyIHAgPSAodm9pZCAwKTsKICAgICAgICAgIC8vIGZpbmQgZmlyc3Qgbm9uLXdoaXRlc3BhY2UgcHJldiBjaGFyCiAgICAgICAgICBmb3IgKDsgaiA+PSAwOyBqLS0pIHsKICAgICAgICAgICAgcCA9IGV4cC5jaGFyQXQoaik7CiAgICAgICAgICAgIGlmIChwICE9PSAnICcpIHsgYnJlYWsgfQogICAgICAgICAgfQogICAgICAgICAgaWYgKCFwIHx8ICF2YWxpZERpdmlzaW9uQ2hhclJFLnRlc3QocCkpIHsKICAgICAgICAgICAgaW5SZWdleCA9IHRydWU7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgaWYgKGV4cHJlc3Npb24gPT09IHVuZGVmaW5lZCkgewogICAgICBleHByZXNzaW9uID0gZXhwLnNsaWNlKDAsIGkpLnRyaW0oKTsKICAgIH0gZWxzZSBpZiAobGFzdEZpbHRlckluZGV4ICE9PSAwKSB7CiAgICAgIHB1c2hGaWx0ZXIoKTsKICAgIH0KCiAgICBmdW5jdGlvbiBwdXNoRmlsdGVyICgpIHsKICAgICAgKGZpbHRlcnMgfHwgKGZpbHRlcnMgPSBbXSkpLnB1c2goZXhwLnNsaWNlKGxhc3RGaWx0ZXJJbmRleCwgaSkudHJpbSgpKTsKICAgICAgbGFzdEZpbHRlckluZGV4ID0gaSArIDE7CiAgICB9CgogICAgaWYgKGZpbHRlcnMpIHsKICAgICAgZm9yIChpID0gMDsgaSA8IGZpbHRlcnMubGVuZ3RoOyBpKyspIHsKICAgICAgICBleHByZXNzaW9uID0gd3JhcEZpbHRlcihleHByZXNzaW9uLCBmaWx0ZXJzW2ldKTsKICAgICAgfQogICAgfQoKICAgIHJldHVybiBleHByZXNzaW9uCiAgfQoKICBmdW5jdGlvbiB3cmFwRmlsdGVyIChleHAsIGZpbHRlcikgewogICAgdmFyIGkgPSBmaWx0ZXIuaW5kZXhPZignKCcpOwogICAgaWYgKGkgPCAwKSB7CiAgICAgIC8vIF9mOiByZXNvbHZlRmlsdGVyCiAgICAgIHJldHVybiAoIl9mKFwiIiArIGZpbHRlciArICJcIikoIiArIGV4cCArICIpIikKICAgIH0gZWxzZSB7CiAgICAgIHZhciBuYW1lID0gZmlsdGVyLnNsaWNlKDAsIGkpOwogICAgICB2YXIgYXJncyA9IGZpbHRlci5zbGljZShpICsgMSk7CiAgICAgIHJldHVybiAoIl9mKFwiIiArIG5hbWUgKyAiXCIpKCIgKyBleHAgKyAoYXJncyAhPT0gJyknID8gJywnICsgYXJncyA6IGFyZ3MpKQogICAgfQogIH0KCiAgLyogICovCgoKCiAgLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi8KICBmdW5jdGlvbiBiYXNlV2FybiAobXNnLCByYW5nZSkgewogICAgY29uc29sZS5lcnJvcigoIltWdWUgY29tcGlsZXJdOiAiICsgbXNnKSk7CiAgfQogIC8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi8KCiAgZnVuY3Rpb24gcGx1Y2tNb2R1bGVGdW5jdGlvbiAoCiAgICBtb2R1bGVzLAogICAga2V5CiAgKSB7CiAgICByZXR1cm4gbW9kdWxlcwogICAgICA/IG1vZHVsZXMubWFwKGZ1bmN0aW9uIChtKSB7IHJldHVybiBtW2tleV07IH0pLmZpbHRlcihmdW5jdGlvbiAoXykgeyByZXR1cm4gXzsgfSkKICAgICAgOiBbXQogIH0KCiAgZnVuY3Rpb24gYWRkUHJvcCAoZWwsIG5hbWUsIHZhbHVlLCByYW5nZSwgZHluYW1pYykgewogICAgKGVsLnByb3BzIHx8IChlbC5wcm9wcyA9IFtdKSkucHVzaChyYW5nZVNldEl0ZW0oeyBuYW1lOiBuYW1lLCB2YWx1ZTogdmFsdWUsIGR5bmFtaWM6IGR5bmFtaWMgfSwgcmFuZ2UpKTsKICAgIGVsLnBsYWluID0gZmFsc2U7CiAgfQoKICBmdW5jdGlvbiBhZGRBdHRyIChlbCwgbmFtZSwgdmFsdWUsIHJhbmdlLCBkeW5hbWljKSB7CiAgICB2YXIgYXR0cnMgPSBkeW5hbWljCiAgICAgID8gKGVsLmR5bmFtaWNBdHRycyB8fCAoZWwuZHluYW1pY0F0dHJzID0gW10pKQogICAgICA6IChlbC5hdHRycyB8fCAoZWwuYXR0cnMgPSBbXSkpOwogICAgYXR0cnMucHVzaChyYW5nZVNldEl0ZW0oeyBuYW1lOiBuYW1lLCB2YWx1ZTogdmFsdWUsIGR5bmFtaWM6IGR5bmFtaWMgfSwgcmFuZ2UpKTsKICAgIGVsLnBsYWluID0gZmFsc2U7CiAgfQoKICAvLyBhZGQgYSByYXcgYXR0ciAodXNlIHRoaXMgaW4gcHJlVHJhbnNmb3JtcykKICBmdW5jdGlvbiBhZGRSYXdBdHRyIChlbCwgbmFtZSwgdmFsdWUsIHJhbmdlKSB7CiAgICBlbC5hdHRyc01hcFtuYW1lXSA9IHZhbHVlOwogICAgZWwuYXR0cnNMaXN0LnB1c2gocmFuZ2VTZXRJdGVtKHsgbmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlIH0sIHJhbmdlKSk7CiAgfQoKICBmdW5jdGlvbiBhZGREaXJlY3RpdmUgKAogICAgZWwsCiAgICBuYW1lLAogICAgcmF3TmFtZSwKICAgIHZhbHVlLAogICAgYXJnLAogICAgaXNEeW5hbWljQXJnLAogICAgbW9kaWZpZXJzLAogICAgcmFuZ2UKICApIHsKICAgIChlbC5kaXJlY3RpdmVzIHx8IChlbC5kaXJlY3RpdmVzID0gW10pKS5wdXNoKHJhbmdlU2V0SXRlbSh7CiAgICAgIG5hbWU6IG5hbWUsCiAgICAgIHJhd05hbWU6IHJhd05hbWUsCiAgICAgIHZhbHVlOiB2YWx1ZSwKICAgICAgYXJnOiBhcmcsCiAgICAgIGlzRHluYW1pY0FyZzogaXNEeW5hbWljQXJnLAogICAgICBtb2RpZmllcnM6IG1vZGlmaWVycwogICAgfSwgcmFuZ2UpKTsKICAgIGVsLnBsYWluID0gZmFsc2U7CiAgfQoKICBmdW5jdGlvbiBwcmVwZW5kTW9kaWZpZXJNYXJrZXIgKHN5bWJvbCwgbmFtZSwgZHluYW1pYykgewogICAgcmV0dXJuIGR5bmFtaWMKICAgICAgPyAoIl9wKCIgKyBuYW1lICsgIixcIiIgKyBzeW1ib2wgKyAiXCIpIikKICAgICAgOiBzeW1ib2wgKyBuYW1lIC8vIG1hcmsgdGhlIGV2ZW50IGFzIGNhcHR1cmVkCiAgfQoKICBmdW5jdGlvbiBhZGRIYW5kbGVyICgKICAgIGVsLAogICAgbmFtZSwKICAgIHZhbHVlLAogICAgbW9kaWZpZXJzLAogICAgaW1wb3J0YW50LAogICAgd2FybiwKICAgIHJhbmdlLAogICAgZHluYW1pYwogICkgewogICAgbW9kaWZpZXJzID0gbW9kaWZpZXJzIHx8IGVtcHR5T2JqZWN0OwogICAgLy8gd2FybiBwcmV2ZW50IGFuZCBwYXNzaXZlIG1vZGlmaWVyCiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgIGlmICgKICAgICAgd2FybiAmJgogICAgICBtb2RpZmllcnMucHJldmVudCAmJiBtb2RpZmllcnMucGFzc2l2ZQogICAgKSB7CiAgICAgIHdhcm4oCiAgICAgICAgJ3Bhc3NpdmUgYW5kIHByZXZlbnQgY2FuXCd0IGJlIHVzZWQgdG9nZXRoZXIuICcgKwogICAgICAgICdQYXNzaXZlIGhhbmRsZXIgY2FuXCd0IHByZXZlbnQgZGVmYXVsdCBldmVudC4nLAogICAgICAgIHJhbmdlCiAgICAgICk7CiAgICB9CgogICAgLy8gbm9ybWFsaXplIGNsaWNrLnJpZ2h0IGFuZCBjbGljay5taWRkbGUgc2luY2UgdGhleSBkb24ndCBhY3R1YWxseSBmaXJlCiAgICAvLyB0aGlzIGlzIHRlY2huaWNhbGx5IGJyb3dzZXItc3BlY2lmaWMsIGJ1dCBhdCBsZWFzdCBmb3Igbm93IGJyb3dzZXJzIGFyZQogICAgLy8gdGhlIG9ubHkgdGFyZ2V0IGVudnMgdGhhdCBoYXZlIHJpZ2h0L21pZGRsZSBjbGlja3MuCiAgICBpZiAobW9kaWZpZXJzLnJpZ2h0KSB7CiAgICAgIGlmIChkeW5hbWljKSB7CiAgICAgICAgbmFtZSA9ICIoIiArIG5hbWUgKyAiKT09PSdjbGljayc/J2NvbnRleHRtZW51JzooIiArIG5hbWUgKyAiKSI7CiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ2NsaWNrJykgewogICAgICAgIG5hbWUgPSAnY29udGV4dG1lbnUnOwogICAgICAgIGRlbGV0ZSBtb2RpZmllcnMucmlnaHQ7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAobW9kaWZpZXJzLm1pZGRsZSkgewogICAgICBpZiAoZHluYW1pYykgewogICAgICAgIG5hbWUgPSAiKCIgKyBuYW1lICsgIik9PT0nY2xpY2snPydtb3VzZXVwJzooIiArIG5hbWUgKyAiKSI7CiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ2NsaWNrJykgewogICAgICAgIG5hbWUgPSAnbW91c2V1cCc7CiAgICAgIH0KICAgIH0KCiAgICAvLyBjaGVjayBjYXB0dXJlIG1vZGlmaWVyCiAgICBpZiAobW9kaWZpZXJzLmNhcHR1cmUpIHsKICAgICAgZGVsZXRlIG1vZGlmaWVycy5jYXB0dXJlOwogICAgICBuYW1lID0gcHJlcGVuZE1vZGlmaWVyTWFya2VyKCchJywgbmFtZSwgZHluYW1pYyk7CiAgICB9CiAgICBpZiAobW9kaWZpZXJzLm9uY2UpIHsKICAgICAgZGVsZXRlIG1vZGlmaWVycy5vbmNlOwogICAgICBuYW1lID0gcHJlcGVuZE1vZGlmaWVyTWFya2VyKCd+JywgbmFtZSwgZHluYW1pYyk7CiAgICB9CiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgIGlmIChtb2RpZmllcnMucGFzc2l2ZSkgewogICAgICBkZWxldGUgbW9kaWZpZXJzLnBhc3NpdmU7CiAgICAgIG5hbWUgPSBwcmVwZW5kTW9kaWZpZXJNYXJrZXIoJyYnLCBuYW1lLCBkeW5hbWljKTsKICAgIH0KCiAgICB2YXIgZXZlbnRzOwogICAgaWYgKG1vZGlmaWVycy5uYXRpdmUpIHsKICAgICAgZGVsZXRlIG1vZGlmaWVycy5uYXRpdmU7CiAgICAgIGV2ZW50cyA9IGVsLm5hdGl2ZUV2ZW50cyB8fCAoZWwubmF0aXZlRXZlbnRzID0ge30pOwogICAgfSBlbHNlIHsKICAgICAgZXZlbnRzID0gZWwuZXZlbnRzIHx8IChlbC5ldmVudHMgPSB7fSk7CiAgICB9CgogICAgdmFyIG5ld0hhbmRsZXIgPSByYW5nZVNldEl0ZW0oeyB2YWx1ZTogdmFsdWUudHJpbSgpLCBkeW5hbWljOiBkeW5hbWljIH0sIHJhbmdlKTsKICAgIGlmIChtb2RpZmllcnMgIT09IGVtcHR5T2JqZWN0KSB7CiAgICAgIG5ld0hhbmRsZXIubW9kaWZpZXJzID0gbW9kaWZpZXJzOwogICAgfQoKICAgIHZhciBoYW5kbGVycyA9IGV2ZW50c1tuYW1lXTsKICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgaWYgKEFycmF5LmlzQXJyYXkoaGFuZGxlcnMpKSB7CiAgICAgIGltcG9ydGFudCA/IGhhbmRsZXJzLnVuc2hpZnQobmV3SGFuZGxlcikgOiBoYW5kbGVycy5wdXNoKG5ld0hhbmRsZXIpOwogICAgfSBlbHNlIGlmIChoYW5kbGVycykgewogICAgICBldmVudHNbbmFtZV0gPSBpbXBvcnRhbnQgPyBbbmV3SGFuZGxlciwgaGFuZGxlcnNdIDogW2hhbmRsZXJzLCBuZXdIYW5kbGVyXTsKICAgIH0gZWxzZSB7CiAgICAgIGV2ZW50c1tuYW1lXSA9IG5ld0hhbmRsZXI7CiAgICB9CgogICAgZWwucGxhaW4gPSBmYWxzZTsKICB9CgogIGZ1bmN0aW9uIGdldFJhd0JpbmRpbmdBdHRyICgKICAgIGVsLAogICAgbmFtZQogICkgewogICAgcmV0dXJuIGVsLnJhd0F0dHJzTWFwWyc6JyArIG5hbWVdIHx8CiAgICAgIGVsLnJhd0F0dHJzTWFwWyd2LWJpbmQ6JyArIG5hbWVdIHx8CiAgICAgIGVsLnJhd0F0dHJzTWFwW25hbWVdCiAgfQoKICBmdW5jdGlvbiBnZXRCaW5kaW5nQXR0ciAoCiAgICBlbCwKICAgIG5hbWUsCiAgICBnZXRTdGF0aWMKICApIHsKICAgIHZhciBkeW5hbWljVmFsdWUgPQogICAgICBnZXRBbmRSZW1vdmVBdHRyKGVsLCAnOicgKyBuYW1lKSB8fAogICAgICBnZXRBbmRSZW1vdmVBdHRyKGVsLCAndi1iaW5kOicgKyBuYW1lKTsKICAgIGlmIChkeW5hbWljVmFsdWUgIT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyc2VGaWx0ZXJzKGR5bmFtaWNWYWx1ZSkKICAgIH0gZWxzZSBpZiAoZ2V0U3RhdGljICE9PSBmYWxzZSkgewogICAgICB2YXIgc3RhdGljVmFsdWUgPSBnZXRBbmRSZW1vdmVBdHRyKGVsLCBuYW1lKTsKICAgICAgaWYgKHN0YXRpY1ZhbHVlICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc3RhdGljVmFsdWUpCiAgICAgIH0KICAgIH0KICB9CgogIC8vIG5vdGU6IHRoaXMgb25seSByZW1vdmVzIHRoZSBhdHRyIGZyb20gdGhlIEFycmF5IChhdHRyc0xpc3QpIHNvIHRoYXQgaXQKICAvLyBkb2Vzbid0IGdldCBwcm9jZXNzZWQgYnkgcHJvY2Vzc0F0dHJzLgogIC8vIEJ5IGRlZmF1bHQgaXQgZG9lcyBOT1QgcmVtb3ZlIGl0IGZyb20gdGhlIG1hcCAoYXR0cnNNYXApIGJlY2F1c2UgdGhlIG1hcCBpcwogIC8vIG5lZWRlZCBkdXJpbmcgY29kZWdlbi4KICBmdW5jdGlvbiBnZXRBbmRSZW1vdmVBdHRyICgKICAgIGVsLAogICAgbmFtZSwKICAgIHJlbW92ZUZyb21NYXAKICApIHsKICAgIHZhciB2YWw7CiAgICBpZiAoKHZhbCA9IGVsLmF0dHJzTWFwW25hbWVdKSAhPSBudWxsKSB7CiAgICAgIHZhciBsaXN0ID0gZWwuYXR0cnNMaXN0OwogICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGxpc3QubGVuZ3RoOyBpIDwgbDsgaSsrKSB7CiAgICAgICAgaWYgKGxpc3RbaV0ubmFtZSA9PT0gbmFtZSkgewogICAgICAgICAgbGlzdC5zcGxpY2UoaSwgMSk7CiAgICAgICAgICBicmVhawogICAgICAgIH0KICAgICAgfQogICAgfQogICAgaWYgKHJlbW92ZUZyb21NYXApIHsKICAgICAgZGVsZXRlIGVsLmF0dHJzTWFwW25hbWVdOwogICAgfQogICAgcmV0dXJuIHZhbAogIH0KCiAgZnVuY3Rpb24gZ2V0QW5kUmVtb3ZlQXR0ckJ5UmVnZXggKAogICAgZWwsCiAgICBuYW1lCiAgKSB7CiAgICB2YXIgbGlzdCA9IGVsLmF0dHJzTGlzdDsKICAgIGZvciAodmFyIGkgPSAwLCBsID0gbGlzdC5sZW5ndGg7IGkgPCBsOyBpKyspIHsKICAgICAgdmFyIGF0dHIgPSBsaXN0W2ldOwogICAgICBpZiAobmFtZS50ZXN0KGF0dHIubmFtZSkpIHsKICAgICAgICBsaXN0LnNwbGljZShpLCAxKTsKICAgICAgICByZXR1cm4gYXR0cgogICAgICB9CiAgICB9CiAgfQoKICBmdW5jdGlvbiByYW5nZVNldEl0ZW0gKAogICAgaXRlbSwKICAgIHJhbmdlCiAgKSB7CiAgICBpZiAocmFuZ2UpIHsKICAgICAgaWYgKHJhbmdlLnN0YXJ0ICE9IG51bGwpIHsKICAgICAgICBpdGVtLnN0YXJ0ID0gcmFuZ2Uuc3RhcnQ7CiAgICAgIH0KICAgICAgaWYgKHJhbmdlLmVuZCAhPSBudWxsKSB7CiAgICAgICAgaXRlbS5lbmQgPSByYW5nZS5lbmQ7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBpdGVtCiAgfQoKICAvKiAgKi8KCiAgLyoqCiAgICogQ3Jvc3MtcGxhdGZvcm0gY29kZSBnZW5lcmF0aW9uIGZvciBjb21wb25lbnQgdi1tb2RlbAogICAqLwogIGZ1bmN0aW9uIGdlbkNvbXBvbmVudE1vZGVsICgKICAgIGVsLAogICAgdmFsdWUsCiAgICBtb2RpZmllcnMKICApIHsKICAgIHZhciByZWYgPSBtb2RpZmllcnMgfHwge307CiAgICB2YXIgbnVtYmVyID0gcmVmLm51bWJlcjsKICAgIHZhciB0cmltID0gcmVmLnRyaW07CgogICAgdmFyIGJhc2VWYWx1ZUV4cHJlc3Npb24gPSAnJCR2JzsKICAgIHZhciB2YWx1ZUV4cHJlc3Npb24gPSBiYXNlVmFsdWVFeHByZXNzaW9uOwogICAgaWYgKHRyaW0pIHsKICAgICAgdmFsdWVFeHByZXNzaW9uID0KICAgICAgICAiKHR5cGVvZiAiICsgYmFzZVZhbHVlRXhwcmVzc2lvbiArICIgPT09ICdzdHJpbmcnIiArCiAgICAgICAgIj8gIiArIGJhc2VWYWx1ZUV4cHJlc3Npb24gKyAiLnRyaW0oKSIgKwogICAgICAgICI6ICIgKyBiYXNlVmFsdWVFeHByZXNzaW9uICsgIikiOwogICAgfQogICAgaWYgKG51bWJlcikgewogICAgICB2YWx1ZUV4cHJlc3Npb24gPSAiX24oIiArIHZhbHVlRXhwcmVzc2lvbiArICIpIjsKICAgIH0KICAgIHZhciBhc3NpZ25tZW50ID0gZ2VuQXNzaWdubWVudENvZGUodmFsdWUsIHZhbHVlRXhwcmVzc2lvbik7CgogICAgZWwubW9kZWwgPSB7CiAgICAgIHZhbHVlOiAoIigiICsgdmFsdWUgKyAiKSIpLAogICAgICBleHByZXNzaW9uOiBKU09OLnN0cmluZ2lmeSh2YWx1ZSksCiAgICAgIGNhbGxiYWNrOiAoImZ1bmN0aW9uICgiICsgYmFzZVZhbHVlRXhwcmVzc2lvbiArICIpIHsiICsgYXNzaWdubWVudCArICJ9IikKICAgIH07CiAgfQoKICAvKioKICAgKiBDcm9zcy1wbGF0Zm9ybSBjb2RlZ2VuIGhlbHBlciBmb3IgZ2VuZXJhdGluZyB2LW1vZGVsIHZhbHVlIGFzc2lnbm1lbnQgY29kZS4KICAgKi8KICBmdW5jdGlvbiBnZW5Bc3NpZ25tZW50Q29kZSAoCiAgICB2YWx1ZSwKICAgIGFzc2lnbm1lbnQKICApIHsKICAgIHZhciByZXMgPSBwYXJzZU1vZGVsKHZhbHVlKTsKICAgIGlmIChyZXMua2V5ID09PSBudWxsKSB7CiAgICAgIHJldHVybiAodmFsdWUgKyAiPSIgKyBhc3NpZ25tZW50KQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuICgiJHNldCgiICsgKHJlcy5leHApICsgIiwgIiArIChyZXMua2V5KSArICIsICIgKyBhc3NpZ25tZW50ICsgIikiKQogICAgfQogIH0KCiAgLyoqCiAgICogUGFyc2UgYSB2LW1vZGVsIGV4cHJlc3Npb24gaW50byBhIGJhc2UgcGF0aCBhbmQgYSBmaW5hbCBrZXkgc2VnbWVudC4KICAgKiBIYW5kbGVzIGJvdGggZG90LXBhdGggYW5kIHBvc3NpYmxlIHNxdWFyZSBicmFja2V0cy4KICAgKgogICAqIFBvc3NpYmxlIGNhc2VzOgogICAqCiAgICogLSB0ZXN0CiAgICogLSB0ZXN0W2tleV0KICAgKiAtIHRlc3RbdGVzdDFba2V5XV0KICAgKiAtIHRlc3RbImEiXVtrZXldCiAgICogLSB4eHgudGVzdFthW2FdLnRlc3QxW2tleV1dCiAgICogLSB0ZXN0Lnh4eC5hWyJhc2EiXVt0ZXN0MVtrZXldXQogICAqCiAgICovCgogIHZhciBsZW4sIHN0ciwgY2hyLCBpbmRleCQxLCBleHByZXNzaW9uUG9zLCBleHByZXNzaW9uRW5kUG9zOwoKCgogIGZ1bmN0aW9uIHBhcnNlTW9kZWwgKHZhbCkgewogICAgLy8gRml4IGh0dHBzOi8vZ2l0aHViLmNvbS92dWVqcy92dWUvcHVsbC83NzMwCiAgICAvLyBhbGxvdyB2LW1vZGVsPSJvYmoudmFsICIgKHRyYWlsaW5nIHdoaXRlc3BhY2UpCiAgICB2YWwgPSB2YWwudHJpbSgpOwogICAgbGVuID0gdmFsLmxlbmd0aDsKCiAgICBpZiAodmFsLmluZGV4T2YoJ1snKSA8IDAgfHwgdmFsLmxhc3RJbmRleE9mKCddJykgPCBsZW4gLSAxKSB7CiAgICAgIGluZGV4JDEgPSB2YWwubGFzdEluZGV4T2YoJy4nKTsKICAgICAgaWYgKGluZGV4JDEgPiAtMSkgewogICAgICAgIHJldHVybiB7CiAgICAgICAgICBleHA6IHZhbC5zbGljZSgwLCBpbmRleCQxKSwKICAgICAgICAgIGtleTogJyInICsgdmFsLnNsaWNlKGluZGV4JDEgKyAxKSArICciJwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gewogICAgICAgICAgZXhwOiB2YWwsCiAgICAgICAgICBrZXk6IG51bGwKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBzdHIgPSB2YWw7CiAgICBpbmRleCQxID0gZXhwcmVzc2lvblBvcyA9IGV4cHJlc3Npb25FbmRQb3MgPSAwOwoKICAgIHdoaWxlICghZW9mKCkpIHsKICAgICAgY2hyID0gbmV4dCgpOwogICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgICAgaWYgKGlzU3RyaW5nU3RhcnQoY2hyKSkgewogICAgICAgIHBhcnNlU3RyaW5nKGNocik7CiAgICAgIH0gZWxzZSBpZiAoY2hyID09PSAweDVCKSB7CiAgICAgICAgcGFyc2VCcmFja2V0KGNocik7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gewogICAgICBleHA6IHZhbC5zbGljZSgwLCBleHByZXNzaW9uUG9zKSwKICAgICAga2V5OiB2YWwuc2xpY2UoZXhwcmVzc2lvblBvcyArIDEsIGV4cHJlc3Npb25FbmRQb3MpCiAgICB9CiAgfQoKICBmdW5jdGlvbiBuZXh0ICgpIHsKICAgIHJldHVybiBzdHIuY2hhckNvZGVBdCgrK2luZGV4JDEpCiAgfQoKICBmdW5jdGlvbiBlb2YgKCkgewogICAgcmV0dXJuIGluZGV4JDEgPj0gbGVuCiAgfQoKICBmdW5jdGlvbiBpc1N0cmluZ1N0YXJ0IChjaHIpIHsKICAgIHJldHVybiBjaHIgPT09IDB4MjIgfHwgY2hyID09PSAweDI3CiAgfQoKICBmdW5jdGlvbiBwYXJzZUJyYWNrZXQgKGNocikgewogICAgdmFyIGluQnJhY2tldCA9IDE7CiAgICBleHByZXNzaW9uUG9zID0gaW5kZXgkMTsKICAgIHdoaWxlICghZW9mKCkpIHsKICAgICAgY2hyID0gbmV4dCgpOwogICAgICBpZiAoaXNTdHJpbmdTdGFydChjaHIpKSB7CiAgICAgICAgcGFyc2VTdHJpbmcoY2hyKTsKICAgICAgICBjb250aW51ZQogICAgICB9CiAgICAgIGlmIChjaHIgPT09IDB4NUIpIHsgaW5CcmFja2V0Kys7IH0KICAgICAgaWYgKGNociA9PT0gMHg1RCkgeyBpbkJyYWNrZXQtLTsgfQogICAgICBpZiAoaW5CcmFja2V0ID09PSAwKSB7CiAgICAgICAgZXhwcmVzc2lvbkVuZFBvcyA9IGluZGV4JDE7CiAgICAgICAgYnJlYWsKICAgICAgfQogICAgfQogIH0KCiAgZnVuY3Rpb24gcGFyc2VTdHJpbmcgKGNocikgewogICAgdmFyIHN0cmluZ1F1b3RlID0gY2hyOwogICAgd2hpbGUgKCFlb2YoKSkgewogICAgICBjaHIgPSBuZXh0KCk7CiAgICAgIGlmIChjaHIgPT09IHN0cmluZ1F1b3RlKSB7CiAgICAgICAgYnJlYWsKICAgICAgfQogICAgfQogIH0KCiAgLyogICovCgogIHZhciB3YXJuJDE7CgogIC8vIGluIHNvbWUgY2FzZXMsIHRoZSBldmVudCB1c2VkIGhhcyB0byBiZSBkZXRlcm1pbmVkIGF0IHJ1bnRpbWUKICAvLyBzbyB3ZSB1c2VkIHNvbWUgcmVzZXJ2ZWQgdG9rZW5zIGR1cmluZyBjb21waWxlLgogIHZhciBSQU5HRV9UT0tFTiA9ICdfX3InOwogIHZhciBDSEVDS0JPWF9SQURJT19UT0tFTiA9ICdfX2MnOwoKICBmdW5jdGlvbiBtb2RlbCAoCiAgICBlbCwKICAgIGRpciwKICAgIF93YXJuCiAgKSB7CiAgICB3YXJuJDEgPSBfd2FybjsKICAgIHZhciB2YWx1ZSA9IGRpci52YWx1ZTsKICAgIHZhciBtb2RpZmllcnMgPSBkaXIubW9kaWZpZXJzOwogICAgdmFyIHRhZyA9IGVsLnRhZzsKICAgIHZhciB0eXBlID0gZWwuYXR0cnNNYXAudHlwZTsKCiAgICB7CiAgICAgIC8vIGlucHV0cyB3aXRoIHR5cGU9ImZpbGUiIGFyZSByZWFkIG9ubHkgYW5kIHNldHRpbmcgdGhlIGlucHV0J3MKICAgICAgLy8gdmFsdWUgd2lsbCB0aHJvdyBhbiBlcnJvci4KICAgICAgaWYgKHRhZyA9PT0gJ2lucHV0JyAmJiB0eXBlID09PSAnZmlsZScpIHsKICAgICAgICB3YXJuJDEoCiAgICAgICAgICAiPCIgKyAoZWwudGFnKSArICIgdi1tb2RlbD1cIiIgKyB2YWx1ZSArICJcIiB0eXBlPVwiZmlsZVwiPjpcbiIgKwogICAgICAgICAgIkZpbGUgaW5wdXRzIGFyZSByZWFkIG9ubHkuIFVzZSBhIHYtb246Y2hhbmdlIGxpc3RlbmVyIGluc3RlYWQuIiwKICAgICAgICAgIGVsLnJhd0F0dHJzTWFwWyd2LW1vZGVsJ10KICAgICAgICApOwogICAgICB9CiAgICB9CgogICAgaWYgKGVsLmNvbXBvbmVudCkgewogICAgICBnZW5Db21wb25lbnRNb2RlbChlbCwgdmFsdWUsIG1vZGlmaWVycyk7CiAgICAgIC8vIGNvbXBvbmVudCB2LW1vZGVsIGRvZXNuJ3QgbmVlZCBleHRyYSBydW50aW1lCiAgICAgIHJldHVybiBmYWxzZQogICAgfSBlbHNlIGlmICh0YWcgPT09ICdzZWxlY3QnKSB7CiAgICAgIGdlblNlbGVjdChlbCwgdmFsdWUsIG1vZGlmaWVycyk7CiAgICB9IGVsc2UgaWYgKHRhZyA9PT0gJ2lucHV0JyAmJiB0eXBlID09PSAnY2hlY2tib3gnKSB7CiAgICAgIGdlbkNoZWNrYm94TW9kZWwoZWwsIHZhbHVlLCBtb2RpZmllcnMpOwogICAgfSBlbHNlIGlmICh0YWcgPT09ICdpbnB1dCcgJiYgdHlwZSA9PT0gJ3JhZGlvJykgewogICAgICBnZW5SYWRpb01vZGVsKGVsLCB2YWx1ZSwgbW9kaWZpZXJzKTsKICAgIH0gZWxzZSBpZiAodGFnID09PSAnaW5wdXQnIHx8IHRhZyA9PT0gJ3RleHRhcmVhJykgewogICAgICBnZW5EZWZhdWx0TW9kZWwoZWwsIHZhbHVlLCBtb2RpZmllcnMpOwogICAgfSBlbHNlIGlmICghY29uZmlnLmlzUmVzZXJ2ZWRUYWcodGFnKSkgewogICAgICBnZW5Db21wb25lbnRNb2RlbChlbCwgdmFsdWUsIG1vZGlmaWVycyk7CiAgICAgIC8vIGNvbXBvbmVudCB2LW1vZGVsIGRvZXNuJ3QgbmVlZCBleHRyYSBydW50aW1lCiAgICAgIHJldHVybiBmYWxzZQogICAgfSBlbHNlIHsKICAgICAgd2FybiQxKAogICAgICAgICI8IiArIChlbC50YWcpICsgIiB2LW1vZGVsPVwiIiArIHZhbHVlICsgIlwiPjogIiArCiAgICAgICAgInYtbW9kZWwgaXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGVsZW1lbnQgdHlwZS4gIiArCiAgICAgICAgJ0lmIHlvdSBhcmUgd29ya2luZyB3aXRoIGNvbnRlbnRlZGl0YWJsZSwgaXRcJ3MgcmVjb21tZW5kZWQgdG8gJyArCiAgICAgICAgJ3dyYXAgYSBsaWJyYXJ5IGRlZGljYXRlZCBmb3IgdGhhdCBwdXJwb3NlIGluc2lkZSBhIGN1c3RvbSBjb21wb25lbnQuJywKICAgICAgICBlbC5yYXdBdHRyc01hcFsndi1tb2RlbCddCiAgICAgICk7CiAgICB9CgogICAgLy8gZW5zdXJlIHJ1bnRpbWUgZGlyZWN0aXZlIG1ldGFkYXRhCiAgICByZXR1cm4gdHJ1ZQogIH0KCiAgZnVuY3Rpb24gZ2VuQ2hlY2tib3hNb2RlbCAoCiAgICBlbCwKICAgIHZhbHVlLAogICAgbW9kaWZpZXJzCiAgKSB7CiAgICB2YXIgbnVtYmVyID0gbW9kaWZpZXJzICYmIG1vZGlmaWVycy5udW1iZXI7CiAgICB2YXIgdmFsdWVCaW5kaW5nID0gZ2V0QmluZGluZ0F0dHIoZWwsICd2YWx1ZScpIHx8ICdudWxsJzsKICAgIHZhciB0cnVlVmFsdWVCaW5kaW5nID0gZ2V0QmluZGluZ0F0dHIoZWwsICd0cnVlLXZhbHVlJykgfHwgJ3RydWUnOwogICAgdmFyIGZhbHNlVmFsdWVCaW5kaW5nID0gZ2V0QmluZGluZ0F0dHIoZWwsICdmYWxzZS12YWx1ZScpIHx8ICdmYWxzZSc7CiAgICBhZGRQcm9wKGVsLCAnY2hlY2tlZCcsCiAgICAgICJBcnJheS5pc0FycmF5KCIgKyB2YWx1ZSArICIpIiArCiAgICAgICI/X2koIiArIHZhbHVlICsgIiwiICsgdmFsdWVCaW5kaW5nICsgIik+LTEiICsgKAogICAgICAgIHRydWVWYWx1ZUJpbmRpbmcgPT09ICd0cnVlJwogICAgICAgICAgPyAoIjooIiArIHZhbHVlICsgIikiKQogICAgICAgICAgOiAoIjpfcSgiICsgdmFsdWUgKyAiLCIgKyB0cnVlVmFsdWVCaW5kaW5nICsgIikiKQogICAgICApCiAgICApOwogICAgYWRkSGFuZGxlcihlbCwgJ2NoYW5nZScsCiAgICAgICJ2YXIgJCRhPSIgKyB2YWx1ZSArICIsIiArCiAgICAgICAgICAnJCRlbD0kZXZlbnQudGFyZ2V0LCcgKwogICAgICAgICAgIiQkYz0kJGVsLmNoZWNrZWQ/KCIgKyB0cnVlVmFsdWVCaW5kaW5nICsgIik6KCIgKyBmYWxzZVZhbHVlQmluZGluZyArICIpOyIgKwogICAgICAnaWYoQXJyYXkuaXNBcnJheSgkJGEpKXsnICsKICAgICAgICAidmFyICQkdj0iICsgKG51bWJlciA/ICdfbignICsgdmFsdWVCaW5kaW5nICsgJyknIDogdmFsdWVCaW5kaW5nKSArICIsIiArCiAgICAgICAgICAgICckJGk9X2koJCRhLCQkdik7JyArCiAgICAgICAgImlmKCQkZWwuY2hlY2tlZCl7JCRpPDAmJigiICsgKGdlbkFzc2lnbm1lbnRDb2RlKHZhbHVlLCAnJCRhLmNvbmNhdChbJCR2XSknKSkgKyAiKX0iICsKICAgICAgICAiZWxzZXskJGk+LTEmJigiICsgKGdlbkFzc2lnbm1lbnRDb2RlKHZhbHVlLCAnJCRhLnNsaWNlKDAsJCRpKS5jb25jYXQoJCRhLnNsaWNlKCQkaSsxKSknKSkgKyAiKX0iICsKICAgICAgIn1lbHNleyIgKyAoZ2VuQXNzaWdubWVudENvZGUodmFsdWUsICckJGMnKSkgKyAifSIsCiAgICAgIG51bGwsIHRydWUKICAgICk7CiAgfQoKICBmdW5jdGlvbiBnZW5SYWRpb01vZGVsICgKICAgIGVsLAogICAgdmFsdWUsCiAgICBtb2RpZmllcnMKICApIHsKICAgIHZhciBudW1iZXIgPSBtb2RpZmllcnMgJiYgbW9kaWZpZXJzLm51bWJlcjsKICAgIHZhciB2YWx1ZUJpbmRpbmcgPSBnZXRCaW5kaW5nQXR0cihlbCwgJ3ZhbHVlJykgfHwgJ251bGwnOwogICAgdmFsdWVCaW5kaW5nID0gbnVtYmVyID8gKCJfbigiICsgdmFsdWVCaW5kaW5nICsgIikiKSA6IHZhbHVlQmluZGluZzsKICAgIGFkZFByb3AoZWwsICdjaGVja2VkJywgKCJfcSgiICsgdmFsdWUgKyAiLCIgKyB2YWx1ZUJpbmRpbmcgKyAiKSIpKTsKICAgIGFkZEhhbmRsZXIoZWwsICdjaGFuZ2UnLCBnZW5Bc3NpZ25tZW50Q29kZSh2YWx1ZSwgdmFsdWVCaW5kaW5nKSwgbnVsbCwgdHJ1ZSk7CiAgfQoKICBmdW5jdGlvbiBnZW5TZWxlY3QgKAogICAgZWwsCiAgICB2YWx1ZSwKICAgIG1vZGlmaWVycwogICkgewogICAgdmFyIG51bWJlciA9IG1vZGlmaWVycyAmJiBtb2RpZmllcnMubnVtYmVyOwogICAgdmFyIHNlbGVjdGVkVmFsID0gIkFycmF5LnByb3RvdHlwZS5maWx0ZXIiICsKICAgICAgIi5jYWxsKCRldmVudC50YXJnZXQub3B0aW9ucyxmdW5jdGlvbihvKXtyZXR1cm4gby5zZWxlY3RlZH0pIiArCiAgICAgICIubWFwKGZ1bmN0aW9uKG8pe3ZhciB2YWwgPSBcIl92YWx1ZVwiIGluIG8gPyBvLl92YWx1ZSA6IG8udmFsdWU7IiArCiAgICAgICJyZXR1cm4gIiArIChudW1iZXIgPyAnX24odmFsKScgOiAndmFsJykgKyAifSkiOwoKICAgIHZhciBhc3NpZ25tZW50ID0gJyRldmVudC50YXJnZXQubXVsdGlwbGUgPyAkJHNlbGVjdGVkVmFsIDogJCRzZWxlY3RlZFZhbFswXSc7CiAgICB2YXIgY29kZSA9ICJ2YXIgJCRzZWxlY3RlZFZhbCA9ICIgKyBzZWxlY3RlZFZhbCArICI7IjsKICAgIGNvZGUgPSBjb2RlICsgIiAiICsgKGdlbkFzc2lnbm1lbnRDb2RlKHZhbHVlLCBhc3NpZ25tZW50KSk7CiAgICBhZGRIYW5kbGVyKGVsLCAnY2hhbmdlJywgY29kZSwgbnVsbCwgdHJ1ZSk7CiAgfQoKICBmdW5jdGlvbiBnZW5EZWZhdWx0TW9kZWwgKAogICAgZWwsCiAgICB2YWx1ZSwKICAgIG1vZGlmaWVycwogICkgewogICAgdmFyIHR5cGUgPSBlbC5hdHRyc01hcC50eXBlOwoKICAgIC8vIHdhcm4gaWYgdi1iaW5kOnZhbHVlIGNvbmZsaWN0cyB3aXRoIHYtbW9kZWwKICAgIC8vIGV4Y2VwdCBmb3IgaW5wdXRzIHdpdGggdi1iaW5kOnR5cGUKICAgIHsKICAgICAgdmFyIHZhbHVlJDEgPSBlbC5hdHRyc01hcFsndi1iaW5kOnZhbHVlJ10gfHwgZWwuYXR0cnNNYXBbJzp2YWx1ZSddOwogICAgICB2YXIgdHlwZUJpbmRpbmcgPSBlbC5hdHRyc01hcFsndi1iaW5kOnR5cGUnXSB8fCBlbC5hdHRyc01hcFsnOnR5cGUnXTsKICAgICAgaWYgKHZhbHVlJDEgJiYgIXR5cGVCaW5kaW5nKSB7CiAgICAgICAgdmFyIGJpbmRpbmcgPSBlbC5hdHRyc01hcFsndi1iaW5kOnZhbHVlJ10gPyAndi1iaW5kOnZhbHVlJyA6ICc6dmFsdWUnOwogICAgICAgIHdhcm4kMSgKICAgICAgICAgIGJpbmRpbmcgKyAiPVwiIiArIHZhbHVlJDEgKyAiXCIgY29uZmxpY3RzIHdpdGggdi1tb2RlbCBvbiB0aGUgc2FtZSBlbGVtZW50ICIgKwogICAgICAgICAgJ2JlY2F1c2UgdGhlIGxhdHRlciBhbHJlYWR5IGV4cGFuZHMgdG8gYSB2YWx1ZSBiaW5kaW5nIGludGVybmFsbHknLAogICAgICAgICAgZWwucmF3QXR0cnNNYXBbYmluZGluZ10KICAgICAgICApOwogICAgICB9CiAgICB9CgogICAgdmFyIHJlZiA9IG1vZGlmaWVycyB8fCB7fTsKICAgIHZhciBsYXp5ID0gcmVmLmxhenk7CiAgICB2YXIgbnVtYmVyID0gcmVmLm51bWJlcjsKICAgIHZhciB0cmltID0gcmVmLnRyaW07CiAgICB2YXIgbmVlZENvbXBvc2l0aW9uR3VhcmQgPSAhbGF6eSAmJiB0eXBlICE9PSAncmFuZ2UnOwogICAgdmFyIGV2ZW50ID0gbGF6eQogICAgICA/ICdjaGFuZ2UnCiAgICAgIDogdHlwZSA9PT0gJ3JhbmdlJwogICAgICAgID8gUkFOR0VfVE9LRU4KICAgICAgICA6ICdpbnB1dCc7CgogICAgdmFyIHZhbHVlRXhwcmVzc2lvbiA9ICckZXZlbnQudGFyZ2V0LnZhbHVlJzsKICAgIGlmICh0cmltKSB7CiAgICAgIHZhbHVlRXhwcmVzc2lvbiA9ICIkZXZlbnQudGFyZ2V0LnZhbHVlLnRyaW0oKSI7CiAgICB9CiAgICBpZiAobnVtYmVyKSB7CiAgICAgIHZhbHVlRXhwcmVzc2lvbiA9ICJfbigiICsgdmFsdWVFeHByZXNzaW9uICsgIikiOwogICAgfQoKICAgIHZhciBjb2RlID0gZ2VuQXNzaWdubWVudENvZGUodmFsdWUsIHZhbHVlRXhwcmVzc2lvbik7CiAgICBpZiAobmVlZENvbXBvc2l0aW9uR3VhcmQpIHsKICAgICAgY29kZSA9ICJpZigkZXZlbnQudGFyZ2V0LmNvbXBvc2luZylyZXR1cm47IiArIGNvZGU7CiAgICB9CgogICAgYWRkUHJvcChlbCwgJ3ZhbHVlJywgKCIoIiArIHZhbHVlICsgIikiKSk7CiAgICBhZGRIYW5kbGVyKGVsLCBldmVudCwgY29kZSwgbnVsbCwgdHJ1ZSk7CiAgICBpZiAodHJpbSB8fCBudW1iZXIpIHsKICAgICAgYWRkSGFuZGxlcihlbCwgJ2JsdXInLCAnJGZvcmNlVXBkYXRlKCknKTsKICAgIH0KICB9CgogIC8qICAqLwoKICAvLyBub3JtYWxpemUgdi1tb2RlbCBldmVudCB0b2tlbnMgdGhhdCBjYW4gb25seSBiZSBkZXRlcm1pbmVkIGF0IHJ1bnRpbWUuCiAgLy8gaXQncyBpbXBvcnRhbnQgdG8gcGxhY2UgdGhlIGV2ZW50IGFzIHRoZSBmaXJzdCBpbiB0aGUgYXJyYXkgYmVjYXVzZQogIC8vIHRoZSB3aG9sZSBwb2ludCBpcyBlbnN1cmluZyB0aGUgdi1tb2RlbCBjYWxsYmFjayBnZXRzIGNhbGxlZCBiZWZvcmUKICAvLyB1c2VyLWF0dGFjaGVkIGhhbmRsZXJzLgogIGZ1bmN0aW9uIG5vcm1hbGl6ZUV2ZW50cyAob24pIHsKICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgaWYgKGlzRGVmKG9uW1JBTkdFX1RPS0VOXSkpIHsKICAgICAgLy8gSUUgaW5wdXRbdHlwZT1yYW5nZV0gb25seSBzdXBwb3J0cyBgY2hhbmdlYCBldmVudAogICAgICB2YXIgZXZlbnQgPSBpc0lFID8gJ2NoYW5nZScgOiAnaW5wdXQnOwogICAgICBvbltldmVudF0gPSBbXS5jb25jYXQob25bUkFOR0VfVE9LRU5dLCBvbltldmVudF0gfHwgW10pOwogICAgICBkZWxldGUgb25bUkFOR0VfVE9LRU5dOwogICAgfQogICAgLy8gVGhpcyB3YXMgb3JpZ2luYWxseSBpbnRlbmRlZCB0byBmaXggIzQ1MjEgYnV0IG5vIGxvbmdlciBuZWNlc3NhcnkKICAgIC8vIGFmdGVyIDIuNS4gS2VlcGluZyBpdCBmb3IgYmFja3dhcmRzIGNvbXBhdCB3aXRoIGdlbmVyYXRlZCBjb2RlIGZyb20gPCAyLjQKICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgaWYgKGlzRGVmKG9uW0NIRUNLQk9YX1JBRElPX1RPS0VOXSkpIHsKICAgICAgb24uY2hhbmdlID0gW10uY29uY2F0KG9uW0NIRUNLQk9YX1JBRElPX1RPS0VOXSwgb24uY2hhbmdlIHx8IFtdKTsKICAgICAgZGVsZXRlIG9uW0NIRUNLQk9YX1JBRElPX1RPS0VOXTsKICAgIH0KICB9CgogIHZhciB0YXJnZXQkMTsKCiAgZnVuY3Rpb24gY3JlYXRlT25jZUhhbmRsZXIkMSAoZXZlbnQsIGhhbmRsZXIsIGNhcHR1cmUpIHsKICAgIHZhciBfdGFyZ2V0ID0gdGFyZ2V0JDE7IC8vIHNhdmUgY3VycmVudCB0YXJnZXQgZWxlbWVudCBpbiBjbG9zdXJlCiAgICByZXR1cm4gZnVuY3Rpb24gb25jZUhhbmRsZXIgKCkgewogICAgICB2YXIgcmVzID0gaGFuZGxlci5hcHBseShudWxsLCBhcmd1bWVudHMpOwogICAgICBpZiAocmVzICE9PSBudWxsKSB7CiAgICAgICAgcmVtb3ZlJDIoZXZlbnQsIG9uY2VIYW5kbGVyLCBjYXB0dXJlLCBfdGFyZ2V0KTsKICAgICAgfQogICAgfQogIH0KCiAgLy8gIzk0NDY6IEZpcmVmb3ggPD0gNTMgKGluIHBhcnRpY3VsYXIsIEVTUiA1MikgaGFzIGluY29ycmVjdCBFdmVudC50aW1lU3RhbXAKICAvLyBpbXBsZW1lbnRhdGlvbiBhbmQgZG9lcyBub3QgZmlyZSBtaWNyb3Rhc2tzIGluIGJldHdlZW4gZXZlbnQgcHJvcGFnYXRpb24sIHNvCiAgLy8gc2FmZSB0byBleGNsdWRlLgogIHZhciB1c2VNaWNyb3Rhc2tGaXggPSBpc1VzaW5nTWljcm9UYXNrICYmICEoaXNGRiAmJiBOdW1iZXIoaXNGRlsxXSkgPD0gNTMpOwoKICBmdW5jdGlvbiBhZGQkMSAoCiAgICBuYW1lLAogICAgaGFuZGxlciwKICAgIGNhcHR1cmUsCiAgICBwYXNzaXZlCiAgKSB7CiAgICAvLyBhc3luYyBlZGdlIGNhc2UgIzY1NjY6IGlubmVyIGNsaWNrIGV2ZW50IHRyaWdnZXJzIHBhdGNoLCBldmVudCBoYW5kbGVyCiAgICAvLyBhdHRhY2hlZCB0byBvdXRlciBlbGVtZW50IGR1cmluZyBwYXRjaCwgYW5kIHRyaWdnZXJlZCBhZ2Fpbi4gVGhpcwogICAgLy8gaGFwcGVucyBiZWNhdXNlIGJyb3dzZXJzIGZpcmUgbWljcm90YXNrIHRpY2tzIGJldHdlZW4gZXZlbnQgcHJvcGFnYXRpb24uCiAgICAvLyB0aGUgc29sdXRpb24gaXMgc2ltcGxlOiB3ZSBzYXZlIHRoZSB0aW1lc3RhbXAgd2hlbiBhIGhhbmRsZXIgaXMgYXR0YWNoZWQsCiAgICAvLyBhbmQgdGhlIGhhbmRsZXIgd291bGQgb25seSBmaXJlIGlmIHRoZSBldmVudCBwYXNzZWQgdG8gaXQgd2FzIGZpcmVkCiAgICAvLyBBRlRFUiBpdCB3YXMgYXR0YWNoZWQuCiAgICBpZiAodXNlTWljcm90YXNrRml4KSB7CiAgICAgIHZhciBhdHRhY2hlZFRpbWVzdGFtcCA9IGN1cnJlbnRGbHVzaFRpbWVzdGFtcDsKICAgICAgdmFyIG9yaWdpbmFsID0gaGFuZGxlcjsKICAgICAgaGFuZGxlciA9IG9yaWdpbmFsLl93cmFwcGVyID0gZnVuY3Rpb24gKGUpIHsKICAgICAgICBpZiAoCiAgICAgICAgICAvLyBubyBidWJibGluZywgc2hvdWxkIGFsd2F5cyBmaXJlLgogICAgICAgICAgLy8gdGhpcyBpcyBqdXN0IGEgc2FmZXR5IG5ldCBpbiBjYXNlIGV2ZW50LnRpbWVTdGFtcCBpcyB1bnJlbGlhYmxlIGluCiAgICAgICAgICAvLyBjZXJ0YWluIHdlaXJkIGVudmlyb25tZW50cy4uLgogICAgICAgICAgZS50YXJnZXQgPT09IGUuY3VycmVudFRhcmdldCB8fAogICAgICAgICAgLy8gZXZlbnQgaXMgZmlyZWQgYWZ0ZXIgaGFuZGxlciBhdHRhY2htZW50CiAgICAgICAgICBlLnRpbWVTdGFtcCA+PSBhdHRhY2hlZFRpbWVzdGFtcCB8fAogICAgICAgICAgLy8gYmFpbCBmb3IgZW52aXJvbm1lbnRzIHRoYXQgaGF2ZSBidWdneSBldmVudC50aW1lU3RhbXAgaW1wbGVtZW50YXRpb25zCiAgICAgICAgICAvLyAjOTQ2MiBpT1MgOSBidWc6IGV2ZW50LnRpbWVTdGFtcCBpcyAwIGFmdGVyIGhpc3RvcnkucHVzaFN0YXRlCiAgICAgICAgICAvLyAjOTY4MSBRdFdlYkVuZ2luZSBldmVudC50aW1lU3RhbXAgaXMgbmVnYXRpdmUgdmFsdWUKICAgICAgICAgIGUudGltZVN0YW1wIDw9IDAgfHwKICAgICAgICAgIC8vICM5NDQ4IGJhaWwgaWYgZXZlbnQgaXMgZmlyZWQgaW4gYW5vdGhlciBkb2N1bWVudCBpbiBhIG11bHRpLXBhZ2UKICAgICAgICAgIC8vIGVsZWN0cm9uL253LmpzIGFwcCwgc2luY2UgZXZlbnQudGltZVN0YW1wIHdpbGwgYmUgdXNpbmcgYSBkaWZmZXJlbnQKICAgICAgICAgIC8vIHN0YXJ0aW5nIHJlZmVyZW5jZQogICAgICAgICAgZS50YXJnZXQub3duZXJEb2N1bWVudCAhPT0gZG9jdW1lbnQKICAgICAgICApIHsKICAgICAgICAgIHJldHVybiBvcmlnaW5hbC5hcHBseSh0aGlzLCBhcmd1bWVudHMpCiAgICAgICAgfQogICAgICB9OwogICAgfQogICAgdGFyZ2V0JDEuYWRkRXZlbnRMaXN0ZW5lcigKICAgICAgbmFtZSwKICAgICAgaGFuZGxlciwKICAgICAgc3VwcG9ydHNQYXNzaXZlCiAgICAgICAgPyB7IGNhcHR1cmU6IGNhcHR1cmUsIHBhc3NpdmU6IHBhc3NpdmUgfQogICAgICAgIDogY2FwdHVyZQogICAgKTsKICB9CgogIGZ1bmN0aW9uIHJlbW92ZSQyICgKICAgIG5hbWUsCiAgICBoYW5kbGVyLAogICAgY2FwdHVyZSwKICAgIF90YXJnZXQKICApIHsKICAgIChfdGFyZ2V0IHx8IHRhcmdldCQxKS5yZW1vdmVFdmVudExpc3RlbmVyKAogICAgICBuYW1lLAogICAgICBoYW5kbGVyLl93cmFwcGVyIHx8IGhhbmRsZXIsCiAgICAgIGNhcHR1cmUKICAgICk7CiAgfQoKICBmdW5jdGlvbiB1cGRhdGVET01MaXN0ZW5lcnMgKG9sZFZub2RlLCB2bm9kZSkgewogICAgaWYgKGlzVW5kZWYob2xkVm5vZGUuZGF0YS5vbikgJiYgaXNVbmRlZih2bm9kZS5kYXRhLm9uKSkgewogICAgICByZXR1cm4KICAgIH0KICAgIHZhciBvbiA9IHZub2RlLmRhdGEub24gfHwge307CiAgICB2YXIgb2xkT24gPSBvbGRWbm9kZS5kYXRhLm9uIHx8IHt9OwogICAgdGFyZ2V0JDEgPSB2bm9kZS5lbG07CiAgICBub3JtYWxpemVFdmVudHMob24pOwogICAgdXBkYXRlTGlzdGVuZXJzKG9uLCBvbGRPbiwgYWRkJDEsIHJlbW92ZSQyLCBjcmVhdGVPbmNlSGFuZGxlciQxLCB2bm9kZS5jb250ZXh0KTsKICAgIHRhcmdldCQxID0gdW5kZWZpbmVkOwogIH0KCiAgdmFyIGV2ZW50cyA9IHsKICAgIGNyZWF0ZTogdXBkYXRlRE9NTGlzdGVuZXJzLAogICAgdXBkYXRlOiB1cGRhdGVET01MaXN0ZW5lcnMKICB9OwoKICAvKiAgKi8KCiAgdmFyIHN2Z0NvbnRhaW5lcjsKCiAgZnVuY3Rpb24gdXBkYXRlRE9NUHJvcHMgKG9sZFZub2RlLCB2bm9kZSkgewogICAgaWYgKGlzVW5kZWYob2xkVm5vZGUuZGF0YS5kb21Qcm9wcykgJiYgaXNVbmRlZih2bm9kZS5kYXRhLmRvbVByb3BzKSkgewogICAgICByZXR1cm4KICAgIH0KICAgIHZhciBrZXksIGN1cjsKICAgIHZhciBlbG0gPSB2bm9kZS5lbG07CiAgICB2YXIgb2xkUHJvcHMgPSBvbGRWbm9kZS5kYXRhLmRvbVByb3BzIHx8IHt9OwogICAgdmFyIHByb3BzID0gdm5vZGUuZGF0YS5kb21Qcm9wcyB8fCB7fTsKICAgIC8vIGNsb25lIG9ic2VydmVkIG9iamVjdHMsIGFzIHRoZSB1c2VyIHByb2JhYmx5IHdhbnRzIHRvIG11dGF0ZSBpdAogICAgaWYgKGlzRGVmKHByb3BzLl9fb2JfXykpIHsKICAgICAgcHJvcHMgPSB2bm9kZS5kYXRhLmRvbVByb3BzID0gZXh0ZW5kKHt9LCBwcm9wcyk7CiAgICB9CgogICAgZm9yIChrZXkgaW4gb2xkUHJvcHMpIHsKICAgICAgaWYgKCEoa2V5IGluIHByb3BzKSkgewogICAgICAgIGVsbVtrZXldID0gJyc7CiAgICAgIH0KICAgIH0KCiAgICBmb3IgKGtleSBpbiBwcm9wcykgewogICAgICBjdXIgPSBwcm9wc1trZXldOwogICAgICAvLyBpZ25vcmUgY2hpbGRyZW4gaWYgdGhlIG5vZGUgaGFzIHRleHRDb250ZW50IG9yIGlubmVySFRNTCwKICAgICAgLy8gYXMgdGhlc2Ugd2lsbCB0aHJvdyBhd2F5IGV4aXN0aW5nIERPTSBub2RlcyBhbmQgY2F1c2UgcmVtb3ZhbCBlcnJvcnMKICAgICAgLy8gb24gc3Vic2VxdWVudCBwYXRjaGVzICgjMzM2MCkKICAgICAgaWYgKGtleSA9PT0gJ3RleHRDb250ZW50JyB8fCBrZXkgPT09ICdpbm5lckhUTUwnKSB7CiAgICAgICAgaWYgKHZub2RlLmNoaWxkcmVuKSB7IHZub2RlLmNoaWxkcmVuLmxlbmd0aCA9IDA7IH0KICAgICAgICBpZiAoY3VyID09PSBvbGRQcm9wc1trZXldKSB7IGNvbnRpbnVlIH0KICAgICAgICAvLyAjNjYwMSB3b3JrIGFyb3VuZCBDaHJvbWUgdmVyc2lvbiA8PSA1NSBidWcgd2hlcmUgc2luZ2xlIHRleHROb2RlCiAgICAgICAgLy8gcmVwbGFjZWQgYnkgaW5uZXJIVE1ML3RleHRDb250ZW50IHJldGFpbnMgaXRzIHBhcmVudE5vZGUgcHJvcGVydHkKICAgICAgICBpZiAoZWxtLmNoaWxkTm9kZXMubGVuZ3RoID09PSAxKSB7CiAgICAgICAgICBlbG0ucmVtb3ZlQ2hpbGQoZWxtLmNoaWxkTm9kZXNbMF0pOwogICAgICAgIH0KICAgICAgfQoKICAgICAgaWYgKGtleSA9PT0gJ3ZhbHVlJyAmJiBlbG0udGFnTmFtZSAhPT0gJ1BST0dSRVNTJykgewogICAgICAgIC8vIHN0b3JlIHZhbHVlIGFzIF92YWx1ZSBhcyB3ZWxsIHNpbmNlCiAgICAgICAgLy8gbm9uLXN0cmluZyB2YWx1ZXMgd2lsbCBiZSBzdHJpbmdpZmllZAogICAgICAgIGVsbS5fdmFsdWUgPSBjdXI7CiAgICAgICAgLy8gYXZvaWQgcmVzZXR0aW5nIGN1cnNvciBwb3NpdGlvbiB3aGVuIHZhbHVlIGlzIHRoZSBzYW1lCiAgICAgICAgdmFyIHN0ckN1ciA9IGlzVW5kZWYoY3VyKSA/ICcnIDogU3RyaW5nKGN1cik7CiAgICAgICAgaWYgKHNob3VsZFVwZGF0ZVZhbHVlKGVsbSwgc3RyQ3VyKSkgewogICAgICAgICAgZWxtLnZhbHVlID0gc3RyQ3VyOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChrZXkgPT09ICdpbm5lckhUTUwnICYmIGlzU1ZHKGVsbS50YWdOYW1lKSAmJiBpc1VuZGVmKGVsbS5pbm5lckhUTUwpKSB7CiAgICAgICAgLy8gSUUgZG9lc24ndCBzdXBwb3J0IGlubmVySFRNTCBmb3IgU1ZHIGVsZW1lbnRzCiAgICAgICAgc3ZnQ29udGFpbmVyID0gc3ZnQ29udGFpbmVyIHx8IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgIHN2Z0NvbnRhaW5lci5pbm5lckhUTUwgPSAiPHN2Zz4iICsgY3VyICsgIjwvc3ZnPiI7CiAgICAgICAgdmFyIHN2ZyA9IHN2Z0NvbnRhaW5lci5maXJzdENoaWxkOwogICAgICAgIHdoaWxlIChlbG0uZmlyc3RDaGlsZCkgewogICAgICAgICAgZWxtLnJlbW92ZUNoaWxkKGVsbS5maXJzdENoaWxkKTsKICAgICAgICB9CiAgICAgICAgd2hpbGUgKHN2Zy5maXJzdENoaWxkKSB7CiAgICAgICAgICBlbG0uYXBwZW5kQ2hpbGQoc3ZnLmZpcnN0Q2hpbGQpOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmICgKICAgICAgICAvLyBza2lwIHRoZSB1cGRhdGUgaWYgb2xkIGFuZCBuZXcgVkRPTSBzdGF0ZSBpcyB0aGUgc2FtZS4KICAgICAgICAvLyBgdmFsdWVgIGlzIGhhbmRsZWQgc2VwYXJhdGVseSBiZWNhdXNlIHRoZSBET00gdmFsdWUgbWF5IGJlIHRlbXBvcmFyaWx5CiAgICAgICAgLy8gb3V0IG9mIHN5bmMgd2l0aCBWRE9NIHN0YXRlIGR1ZSB0byBmb2N1cywgY29tcG9zaXRpb24gYW5kIG1vZGlmaWVycy4KICAgICAgICAvLyBUaGlzICAjNDUyMSBieSBza2lwcGluZyB0aGUgdW5uZWNlc2FycnkgYGNoZWNrZWRgIHVwZGF0ZS4KICAgICAgICBjdXIgIT09IG9sZFByb3BzW2tleV0KICAgICAgKSB7CiAgICAgICAgLy8gc29tZSBwcm9wZXJ0eSB1cGRhdGVzIGNhbiB0aHJvdwogICAgICAgIC8vIGUuZy4gYHZhbHVlYCBvbiA8cHJvZ3Jlc3M+IHcvIG5vbi1maW5pdGUgdmFsdWUKICAgICAgICB0cnkgewogICAgICAgICAgZWxtW2tleV0gPSBjdXI7CiAgICAgICAgfSBjYXRjaCAoZSkge30KICAgICAgfQogICAgfQogIH0KCiAgLy8gY2hlY2sgcGxhdGZvcm1zL3dlYi91dGlsL2F0dHJzLmpzIGFjY2VwdFZhbHVlCgoKICBmdW5jdGlvbiBzaG91bGRVcGRhdGVWYWx1ZSAoZWxtLCBjaGVja1ZhbCkgewogICAgcmV0dXJuICghZWxtLmNvbXBvc2luZyAmJiAoCiAgICAgIGVsbS50YWdOYW1lID09PSAnT1BUSU9OJyB8fAogICAgICBpc05vdEluRm9jdXNBbmREaXJ0eShlbG0sIGNoZWNrVmFsKSB8fAogICAgICBpc0RpcnR5V2l0aE1vZGlmaWVycyhlbG0sIGNoZWNrVmFsKQogICAgKSkKICB9CgogIGZ1bmN0aW9uIGlzTm90SW5Gb2N1c0FuZERpcnR5IChlbG0sIGNoZWNrVmFsKSB7CiAgICAvLyByZXR1cm4gdHJ1ZSB3aGVuIHRleHRib3ggKC5udW1iZXIgYW5kIC50cmltKSBsb3NlcyBmb2N1cyBhbmQgaXRzIHZhbHVlIGlzCiAgICAvLyBub3QgZXF1YWwgdG8gdGhlIHVwZGF0ZWQgdmFsdWUKICAgIHZhciBub3RJbkZvY3VzID0gdHJ1ZTsKICAgIC8vICM2MTU3CiAgICAvLyB3b3JrIGFyb3VuZCBJRSBidWcgd2hlbiBhY2Nlc3NpbmcgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCBpbiBhbiBpZnJhbWUKICAgIHRyeSB7IG5vdEluRm9jdXMgPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICE9PSBlbG07IH0gY2F0Y2ggKGUpIHt9CiAgICByZXR1cm4gbm90SW5Gb2N1cyAmJiBlbG0udmFsdWUgIT09IGNoZWNrVmFsCiAgfQoKICBmdW5jdGlvbiBpc0RpcnR5V2l0aE1vZGlmaWVycyAoZWxtLCBuZXdWYWwpIHsKICAgIHZhciB2YWx1ZSA9IGVsbS52YWx1ZTsKICAgIHZhciBtb2RpZmllcnMgPSBlbG0uX3ZNb2RpZmllcnM7IC8vIGluamVjdGVkIGJ5IHYtbW9kZWwgcnVudGltZQogICAgaWYgKGlzRGVmKG1vZGlmaWVycykpIHsKICAgICAgaWYgKG1vZGlmaWVycy5udW1iZXIpIHsKICAgICAgICByZXR1cm4gdG9OdW1iZXIodmFsdWUpICE9PSB0b051bWJlcihuZXdWYWwpCiAgICAgIH0KICAgICAgaWYgKG1vZGlmaWVycy50cmltKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlLnRyaW0oKSAhPT0gbmV3VmFsLnRyaW0oKQogICAgICB9CiAgICB9CiAgICByZXR1cm4gdmFsdWUgIT09IG5ld1ZhbAogIH0KCiAgdmFyIGRvbVByb3BzID0gewogICAgY3JlYXRlOiB1cGRhdGVET01Qcm9wcywKICAgIHVwZGF0ZTogdXBkYXRlRE9NUHJvcHMKICB9OwoKICAvKiAgKi8KCiAgdmFyIHBhcnNlU3R5bGVUZXh0ID0gY2FjaGVkKGZ1bmN0aW9uIChjc3NUZXh0KSB7CiAgICB2YXIgcmVzID0ge307CiAgICB2YXIgbGlzdERlbGltaXRlciA9IC87KD8hW14oXSpcKSkvZzsKICAgIHZhciBwcm9wZXJ0eURlbGltaXRlciA9IC86KC4rKS87CiAgICBjc3NUZXh0LnNwbGl0KGxpc3REZWxpbWl0ZXIpLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgaWYgKGl0ZW0pIHsKICAgICAgICB2YXIgdG1wID0gaXRlbS5zcGxpdChwcm9wZXJ0eURlbGltaXRlcik7CiAgICAgICAgdG1wLmxlbmd0aCA+IDEgJiYgKHJlc1t0bXBbMF0udHJpbSgpXSA9IHRtcFsxXS50cmltKCkpOwogICAgICB9CiAgICB9KTsKICAgIHJldHVybiByZXMKICB9KTsKCiAgLy8gbWVyZ2Ugc3RhdGljIGFuZCBkeW5hbWljIHN0eWxlIGRhdGEgb24gdGhlIHNhbWUgdm5vZGUKICBmdW5jdGlvbiBub3JtYWxpemVTdHlsZURhdGEgKGRhdGEpIHsKICAgIHZhciBzdHlsZSA9IG5vcm1hbGl6ZVN0eWxlQmluZGluZyhkYXRhLnN0eWxlKTsKICAgIC8vIHN0YXRpYyBzdHlsZSBpcyBwcmUtcHJvY2Vzc2VkIGludG8gYW4gb2JqZWN0IGR1cmluZyBjb21waWxhdGlvbgogICAgLy8gYW5kIGlzIGFsd2F5cyBhIGZyZXNoIG9iamVjdCwgc28gaXQncyBzYWZlIHRvIG1lcmdlIGludG8gaXQKICAgIHJldHVybiBkYXRhLnN0YXRpY1N0eWxlCiAgICAgID8gZXh0ZW5kKGRhdGEuc3RhdGljU3R5bGUsIHN0eWxlKQogICAgICA6IHN0eWxlCiAgfQoKICAvLyBub3JtYWxpemUgcG9zc2libGUgYXJyYXkgLyBzdHJpbmcgdmFsdWVzIGludG8gT2JqZWN0CiAgZnVuY3Rpb24gbm9ybWFsaXplU3R5bGVCaW5kaW5nIChiaW5kaW5nU3R5bGUpIHsKICAgIGlmIChBcnJheS5pc0FycmF5KGJpbmRpbmdTdHlsZSkpIHsKICAgICAgcmV0dXJuIHRvT2JqZWN0KGJpbmRpbmdTdHlsZSkKICAgIH0KICAgIGlmICh0eXBlb2YgYmluZGluZ1N0eWxlID09PSAnc3RyaW5nJykgewogICAgICByZXR1cm4gcGFyc2VTdHlsZVRleHQoYmluZGluZ1N0eWxlKQogICAgfQogICAgcmV0dXJuIGJpbmRpbmdTdHlsZQogIH0KCiAgLyoqCiAgICogcGFyZW50IGNvbXBvbmVudCBzdHlsZSBzaG91bGQgYmUgYWZ0ZXIgY2hpbGQncwogICAqIHNvIHRoYXQgcGFyZW50IGNvbXBvbmVudCdzIHN0eWxlIGNvdWxkIG92ZXJyaWRlIGl0CiAgICovCiAgZnVuY3Rpb24gZ2V0U3R5bGUgKHZub2RlLCBjaGVja0NoaWxkKSB7CiAgICB2YXIgcmVzID0ge307CiAgICB2YXIgc3R5bGVEYXRhOwoKICAgIGlmIChjaGVja0NoaWxkKSB7CiAgICAgIHZhciBjaGlsZE5vZGUgPSB2bm9kZTsKICAgICAgd2hpbGUgKGNoaWxkTm9kZS5jb21wb25lbnRJbnN0YW5jZSkgewogICAgICAgIGNoaWxkTm9kZSA9IGNoaWxkTm9kZS5jb21wb25lbnRJbnN0YW5jZS5fdm5vZGU7CiAgICAgICAgaWYgKAogICAgICAgICAgY2hpbGROb2RlICYmIGNoaWxkTm9kZS5kYXRhICYmCiAgICAgICAgICAoc3R5bGVEYXRhID0gbm9ybWFsaXplU3R5bGVEYXRhKGNoaWxkTm9kZS5kYXRhKSkKICAgICAgICApIHsKICAgICAgICAgIGV4dGVuZChyZXMsIHN0eWxlRGF0YSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgaWYgKChzdHlsZURhdGEgPSBub3JtYWxpemVTdHlsZURhdGEodm5vZGUuZGF0YSkpKSB7CiAgICAgIGV4dGVuZChyZXMsIHN0eWxlRGF0YSk7CiAgICB9CgogICAgdmFyIHBhcmVudE5vZGUgPSB2bm9kZTsKICAgIHdoaWxlICgocGFyZW50Tm9kZSA9IHBhcmVudE5vZGUucGFyZW50KSkgewogICAgICBpZiAocGFyZW50Tm9kZS5kYXRhICYmIChzdHlsZURhdGEgPSBub3JtYWxpemVTdHlsZURhdGEocGFyZW50Tm9kZS5kYXRhKSkpIHsKICAgICAgICBleHRlbmQocmVzLCBzdHlsZURhdGEpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gcmVzCiAgfQoKICAvKiAgKi8KCiAgdmFyIGNzc1ZhclJFID0gL14tLS87CiAgdmFyIGltcG9ydGFudFJFID0gL1xzKiFpbXBvcnRhbnQkLzsKICB2YXIgc2V0UHJvcCA9IGZ1bmN0aW9uIChlbCwgbmFtZSwgdmFsKSB7CiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgIGlmIChjc3NWYXJSRS50ZXN0KG5hbWUpKSB7CiAgICAgIGVsLnN0eWxlLnNldFByb3BlcnR5KG5hbWUsIHZhbCk7CiAgICB9IGVsc2UgaWYgKGltcG9ydGFudFJFLnRlc3QodmFsKSkgewogICAgICBlbC5zdHlsZS5zZXRQcm9wZXJ0eShoeXBoZW5hdGUobmFtZSksIHZhbC5yZXBsYWNlKGltcG9ydGFudFJFLCAnJyksICdpbXBvcnRhbnQnKTsKICAgIH0gZWxzZSB7CiAgICAgIHZhciBub3JtYWxpemVkTmFtZSA9IG5vcm1hbGl6ZShuYW1lKTsKICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsKSkgewogICAgICAgIC8vIFN1cHBvcnQgdmFsdWVzIGFycmF5IGNyZWF0ZWQgYnkgYXV0b3ByZWZpeGVyLCBlLmcuCiAgICAgICAgLy8ge2Rpc3BsYXk6IFsiLXdlYmtpdC1ib3giLCAiLW1zLWZsZXhib3giLCAiZmxleCJdfQogICAgICAgIC8vIFNldCB0aGVtIG9uZSBieSBvbmUsIGFuZCB0aGUgYnJvd3NlciB3aWxsIG9ubHkgc2V0IHRob3NlIGl0IGNhbiByZWNvZ25pemUKICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdmFsLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgICBlbC5zdHlsZVtub3JtYWxpemVkTmFtZV0gPSB2YWxbaV07CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGVsLnN0eWxlW25vcm1hbGl6ZWROYW1lXSA9IHZhbDsKICAgICAgfQogICAgfQogIH07CgogIHZhciB2ZW5kb3JOYW1lcyA9IFsnV2Via2l0JywgJ01veicsICdtcyddOwoKICB2YXIgZW1wdHlTdHlsZTsKICB2YXIgbm9ybWFsaXplID0gY2FjaGVkKGZ1bmN0aW9uIChwcm9wKSB7CiAgICBlbXB0eVN0eWxlID0gZW1wdHlTdHlsZSB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKS5zdHlsZTsKICAgIHByb3AgPSBjYW1lbGl6ZShwcm9wKTsKICAgIGlmIChwcm9wICE9PSAnZmlsdGVyJyAmJiAocHJvcCBpbiBlbXB0eVN0eWxlKSkgewogICAgICByZXR1cm4gcHJvcAogICAgfQogICAgdmFyIGNhcE5hbWUgPSBwcm9wLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcHJvcC5zbGljZSgxKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmVuZG9yTmFtZXMubGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIG5hbWUgPSB2ZW5kb3JOYW1lc1tpXSArIGNhcE5hbWU7CiAgICAgIGlmIChuYW1lIGluIGVtcHR5U3R5bGUpIHsKICAgICAgICByZXR1cm4gbmFtZQogICAgICB9CiAgICB9CiAgfSk7CgogIGZ1bmN0aW9uIHVwZGF0ZVN0eWxlIChvbGRWbm9kZSwgdm5vZGUpIHsKICAgIHZhciBkYXRhID0gdm5vZGUuZGF0YTsKICAgIHZhciBvbGREYXRhID0gb2xkVm5vZGUuZGF0YTsKCiAgICBpZiAoaXNVbmRlZihkYXRhLnN0YXRpY1N0eWxlKSAmJiBpc1VuZGVmKGRhdGEuc3R5bGUpICYmCiAgICAgIGlzVW5kZWYob2xkRGF0YS5zdGF0aWNTdHlsZSkgJiYgaXNVbmRlZihvbGREYXRhLnN0eWxlKQogICAgKSB7CiAgICAgIHJldHVybgogICAgfQoKICAgIHZhciBjdXIsIG5hbWU7CiAgICB2YXIgZWwgPSB2bm9kZS5lbG07CiAgICB2YXIgb2xkU3RhdGljU3R5bGUgPSBvbGREYXRhLnN0YXRpY1N0eWxlOwogICAgdmFyIG9sZFN0eWxlQmluZGluZyA9IG9sZERhdGEubm9ybWFsaXplZFN0eWxlIHx8IG9sZERhdGEuc3R5bGUgfHwge307CgogICAgLy8gaWYgc3RhdGljIHN0eWxlIGV4aXN0cywgc3R5bGViaW5kaW5nIGFscmVhZHkgbWVyZ2VkIGludG8gaXQgd2hlbiBkb2luZyBub3JtYWxpemVTdHlsZURhdGEKICAgIHZhciBvbGRTdHlsZSA9IG9sZFN0YXRpY1N0eWxlIHx8IG9sZFN0eWxlQmluZGluZzsKCiAgICB2YXIgc3R5bGUgPSBub3JtYWxpemVTdHlsZUJpbmRpbmcodm5vZGUuZGF0YS5zdHlsZSkgfHwge307CgogICAgLy8gc3RvcmUgbm9ybWFsaXplZCBzdHlsZSB1bmRlciBhIGRpZmZlcmVudCBrZXkgZm9yIG5leHQgZGlmZgogICAgLy8gbWFrZSBzdXJlIHRvIGNsb25lIGl0IGlmIGl0J3MgcmVhY3RpdmUsIHNpbmNlIHRoZSB1c2VyIGxpa2VseSB3YW50cwogICAgLy8gdG8gbXV0YXRlIGl0LgogICAgdm5vZGUuZGF0YS5ub3JtYWxpemVkU3R5bGUgPSBpc0RlZihzdHlsZS5fX29iX18pCiAgICAgID8gZXh0ZW5kKHt9LCBzdHlsZSkKICAgICAgOiBzdHlsZTsKCiAgICB2YXIgbmV3U3R5bGUgPSBnZXRTdHlsZSh2bm9kZSwgdHJ1ZSk7CgogICAgZm9yIChuYW1lIGluIG9sZFN0eWxlKSB7CiAgICAgIGlmIChpc1VuZGVmKG5ld1N0eWxlW25hbWVdKSkgewogICAgICAgIHNldFByb3AoZWwsIG5hbWUsICcnKTsKICAgICAgfQogICAgfQogICAgZm9yIChuYW1lIGluIG5ld1N0eWxlKSB7CiAgICAgIGN1ciA9IG5ld1N0eWxlW25hbWVdOwogICAgICBpZiAoY3VyICE9PSBvbGRTdHlsZVtuYW1lXSkgewogICAgICAgIC8vIGllOSBzZXR0aW5nIHRvIG51bGwgaGFzIG5vIGVmZmVjdCwgbXVzdCB1c2UgZW1wdHkgc3RyaW5nCiAgICAgICAgc2V0UHJvcChlbCwgbmFtZSwgY3VyID09IG51bGwgPyAnJyA6IGN1cik7CiAgICAgIH0KICAgIH0KICB9CgogIHZhciBzdHlsZSA9IHsKICAgIGNyZWF0ZTogdXBkYXRlU3R5bGUsCiAgICB1cGRhdGU6IHVwZGF0ZVN0eWxlCiAgfTsKCiAgLyogICovCgogIHZhciB3aGl0ZXNwYWNlUkUgPSAvXHMrLzsKCiAgLyoqCiAgICogQWRkIGNsYXNzIHdpdGggY29tcGF0aWJpbGl0eSBmb3IgU1ZHIHNpbmNlIGNsYXNzTGlzdCBpcyBub3Qgc3VwcG9ydGVkIG9uCiAgICogU1ZHIGVsZW1lbnRzIGluIElFCiAgICovCiAgZnVuY3Rpb24gYWRkQ2xhc3MgKGVsLCBjbHMpIHsKICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgaWYgKCFjbHMgfHwgIShjbHMgPSBjbHMudHJpbSgpKSkgewogICAgICByZXR1cm4KICAgIH0KCiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqLwogICAgaWYgKGVsLmNsYXNzTGlzdCkgewogICAgICBpZiAoY2xzLmluZGV4T2YoJyAnKSA+IC0xKSB7CiAgICAgICAgY2xzLnNwbGl0KHdoaXRlc3BhY2VSRSkuZm9yRWFjaChmdW5jdGlvbiAoYykgeyByZXR1cm4gZWwuY2xhc3NMaXN0LmFkZChjKTsgfSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZWwuY2xhc3NMaXN0LmFkZChjbHMpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICB2YXIgY3VyID0gIiAiICsgKGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSB8fCAnJykgKyAiICI7CiAgICAgIGlmIChjdXIuaW5kZXhPZignICcgKyBjbHMgKyAnICcpIDwgMCkgewogICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAoY3VyICsgY2xzKS50cmltKCkpOwogICAgICB9CiAgICB9CiAgfQoKICAvKioKICAgKiBSZW1vdmUgY2xhc3Mgd2l0aCBjb21wYXRpYmlsaXR5IGZvciBTVkcgc2luY2UgY2xhc3NMaXN0IGlzIG5vdCBzdXBwb3J0ZWQgb24KICAgKiBTVkcgZWxlbWVudHMgaW4gSUUKICAgKi8KICBmdW5jdGlvbiByZW1vdmVDbGFzcyAoZWwsIGNscykgewogICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICBpZiAoIWNscyB8fCAhKGNscyA9IGNscy50cmltKCkpKSB7CiAgICAgIHJldHVybgogICAgfQoKICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovCiAgICBpZiAoZWwuY2xhc3NMaXN0KSB7CiAgICAgIGlmIChjbHMuaW5kZXhPZignICcpID4gLTEpIHsKICAgICAgICBjbHMuc3BsaXQod2hpdGVzcGFjZVJFKS5mb3JFYWNoKGZ1bmN0aW9uIChjKSB7IHJldHVybiBlbC5jbGFzc0xpc3QucmVtb3ZlKGMpOyB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKGNscyk7CiAgICAgIH0KICAgICAgaWYgKCFlbC5jbGFzc0xpc3QubGVuZ3RoKSB7CiAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCdjbGFzcycpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICB2YXIgY3VyID0gIiAiICsgKGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSB8fCAnJykgKyAiICI7CiAgICAgIHZhciB0YXIgPSAnICcgKyBjbHMgKyAnICc7CiAgICAgIHdoaWxlIChjdXIuaW5kZXhPZih0YXIpID49IDApIHsKICAgICAgICBjdXIgPSBjdXIucmVwbGFjZSh0YXIsICcgJyk7CiAgICAgIH0KICAgICAgY3VyID0gY3VyLnRyaW0oKTsKICAgICAgaWYgKGN1cikgewogICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCBjdXIpOwogICAgICB9IGVsc2UgewogICAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZSgnY2xhc3MnKTsKICAgICAgfQogICAgfQogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIHJlc29sdmVUcmFuc2l0aW9uIChkZWYkJDEpIHsKICAgIGlmICghZGVmJCQxKSB7CiAgICAgIHJldHVybgogICAgfQogICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi8KICAgIGlmICh0eXBlb2YgZGVmJCQxID09PSAnb2JqZWN0JykgewogICAgICB2YXIgcmVzID0ge307CiAgICAgIGlmIChkZWYkJDEuY3NzICE9PSBmYWxzZSkgewogICAgICAgIGV4dGVuZChyZXMsIGF1dG9Dc3NUcmFuc2l0aW9uKGRlZiQkMS5uYW1lIHx8ICd2JykpOwogICAgICB9CiAgICAgIGV4dGVuZChyZXMsIGRlZiQkMSk7CiAgICAgIHJldHVybiByZXMKICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZiQkMSA9PT0gJ3N0cmluZycpIHsKICAgICAgcmV0dXJuIGF1dG9Dc3NUcmFuc2l0aW9uKGRlZiQkMSkKICAgIH0KICB9CgogIHZhciBhdXRvQ3NzVHJhbnNpdGlvbiA9IGNhY2hlZChmdW5jdGlvbiAobmFtZSkgewogICAgcmV0dXJuIHsKICAgICAgZW50ZXJDbGFzczogKG5hbWUgKyAiLWVudGVyIiksCiAgICAgIGVudGVyVG9DbGFzczogKG5hbWUgKyAiLWVudGVyLXRvIiksCiAgICAgIGVudGVyQWN0aXZlQ2xhc3M6IChuYW1lICsgIi1lbnRlci1hY3RpdmUiKSwKICAgICAgbGVhdmVDbGFzczogKG5hbWUgKyAiLWxlYXZlIiksCiAgICAgIGxlYXZlVG9DbGFzczogKG5hbWUgKyAiLWxlYXZlLXRvIiksCiAgICAgIGxlYXZlQWN0aXZlQ2xhc3M6IChuYW1lICsgIi1sZWF2ZS1hY3RpdmUiKQogICAgfQogIH0pOwoKICB2YXIgaGFzVHJhbnNpdGlvbiA9IGluQnJvd3NlciAmJiAhaXNJRTk7CiAgdmFyIFRSQU5TSVRJT04gPSAndHJhbnNpdGlvbic7CiAgdmFyIEFOSU1BVElPTiA9ICdhbmltYXRpb24nOwoKICAvLyBUcmFuc2l0aW9uIHByb3BlcnR5L2V2ZW50IHNuaWZmaW5nCiAgdmFyIHRyYW5zaXRpb25Qcm9wID0gJ3RyYW5zaXRpb24nOwogIHZhciB0cmFuc2l0aW9uRW5kRXZlbnQgPSAndHJhbnNpdGlvbmVuZCc7CiAgdmFyIGFuaW1hdGlvblByb3AgPSAnYW5pbWF0aW9uJzsKICB2YXIgYW5pbWF0aW9uRW5kRXZlbnQgPSAnYW5pbWF0aW9uZW5kJzsKICBpZiAoaGFzVHJhbnNpdGlvbikgewogICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICBpZiAod2luZG93Lm9udHJhbnNpdGlvbmVuZCA9PT0gdW5kZWZpbmVkICYmCiAgICAgIHdpbmRvdy5vbndlYmtpdHRyYW5zaXRpb25lbmQgIT09IHVuZGVmaW5lZAogICAgKSB7CiAgICAgIHRyYW5zaXRpb25Qcm9wID0gJ1dlYmtpdFRyYW5zaXRpb24nOwogICAgICB0cmFuc2l0aW9uRW5kRXZlbnQgPSAnd2Via2l0VHJhbnNpdGlvbkVuZCc7CiAgICB9CiAgICBpZiAod2luZG93Lm9uYW5pbWF0aW9uZW5kID09PSB1bmRlZmluZWQgJiYKICAgICAgd2luZG93Lm9ud2Via2l0YW5pbWF0aW9uZW5kICE9PSB1bmRlZmluZWQKICAgICkgewogICAgICBhbmltYXRpb25Qcm9wID0gJ1dlYmtpdEFuaW1hdGlvbic7CiAgICAgIGFuaW1hdGlvbkVuZEV2ZW50ID0gJ3dlYmtpdEFuaW1hdGlvbkVuZCc7CiAgICB9CiAgfQoKICAvLyBiaW5kaW5nIHRvIHdpbmRvdyBpcyBuZWNlc3NhcnkgdG8gbWFrZSBob3QgcmVsb2FkIHdvcmsgaW4gSUUgaW4gc3RyaWN0IG1vZGUKICB2YXIgcmFmID0gaW5Ccm93c2VyCiAgICA/IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUKICAgICAgPyB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lLmJpbmQod2luZG93KQogICAgICA6IHNldFRpbWVvdXQKICAgIDogLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gZnVuY3Rpb24gKGZuKSB7IHJldHVybiBmbigpOyB9OwoKICBmdW5jdGlvbiBuZXh0RnJhbWUgKGZuKSB7CiAgICByYWYoZnVuY3Rpb24gKCkgewogICAgICByYWYoZm4pOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBhZGRUcmFuc2l0aW9uQ2xhc3MgKGVsLCBjbHMpIHsKICAgIHZhciB0cmFuc2l0aW9uQ2xhc3NlcyA9IGVsLl90cmFuc2l0aW9uQ2xhc3NlcyB8fCAoZWwuX3RyYW5zaXRpb25DbGFzc2VzID0gW10pOwogICAgaWYgKHRyYW5zaXRpb25DbGFzc2VzLmluZGV4T2YoY2xzKSA8IDApIHsKICAgICAgdHJhbnNpdGlvbkNsYXNzZXMucHVzaChjbHMpOwogICAgICBhZGRDbGFzcyhlbCwgY2xzKTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIHJlbW92ZVRyYW5zaXRpb25DbGFzcyAoZWwsIGNscykgewogICAgaWYgKGVsLl90cmFuc2l0aW9uQ2xhc3NlcykgewogICAgICByZW1vdmUoZWwuX3RyYW5zaXRpb25DbGFzc2VzLCBjbHMpOwogICAgfQogICAgcmVtb3ZlQ2xhc3MoZWwsIGNscyk7CiAgfQoKICBmdW5jdGlvbiB3aGVuVHJhbnNpdGlvbkVuZHMgKAogICAgZWwsCiAgICBleHBlY3RlZFR5cGUsCiAgICBjYgogICkgewogICAgdmFyIHJlZiA9IGdldFRyYW5zaXRpb25JbmZvKGVsLCBleHBlY3RlZFR5cGUpOwogICAgdmFyIHR5cGUgPSByZWYudHlwZTsKICAgIHZhciB0aW1lb3V0ID0gcmVmLnRpbWVvdXQ7CiAgICB2YXIgcHJvcENvdW50ID0gcmVmLnByb3BDb3VudDsKICAgIGlmICghdHlwZSkgeyByZXR1cm4gY2IoKSB9CiAgICB2YXIgZXZlbnQgPSB0eXBlID09PSBUUkFOU0lUSU9OID8gdHJhbnNpdGlvbkVuZEV2ZW50IDogYW5pbWF0aW9uRW5kRXZlbnQ7CiAgICB2YXIgZW5kZWQgPSAwOwogICAgdmFyIGVuZCA9IGZ1bmN0aW9uICgpIHsKICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgb25FbmQpOwogICAgICBjYigpOwogICAgfTsKICAgIHZhciBvbkVuZCA9IGZ1bmN0aW9uIChlKSB7CiAgICAgIGlmIChlLnRhcmdldCA9PT0gZWwpIHsKICAgICAgICBpZiAoKytlbmRlZCA+PSBwcm9wQ291bnQpIHsKICAgICAgICAgIGVuZCgpOwogICAgICAgIH0KICAgICAgfQogICAgfTsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICBpZiAoZW5kZWQgPCBwcm9wQ291bnQpIHsKICAgICAgICBlbmQoKTsKICAgICAgfQogICAgfSwgdGltZW91dCArIDEpOwogICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgb25FbmQpOwogIH0KCiAgdmFyIHRyYW5zZm9ybVJFID0gL1xiKHRyYW5zZm9ybXxhbGwpKCx8JCkvOwoKICBmdW5jdGlvbiBnZXRUcmFuc2l0aW9uSW5mbyAoZWwsIGV4cGVjdGVkVHlwZSkgewogICAgdmFyIHN0eWxlcyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKTsKICAgIC8vIEpTRE9NIG1heSByZXR1cm4gdW5kZWZpbmVkIGZvciB0cmFuc2l0aW9uIHByb3BlcnRpZXMKICAgIHZhciB0cmFuc2l0aW9uRGVsYXlzID0gKHN0eWxlc1t0cmFuc2l0aW9uUHJvcCArICdEZWxheSddIHx8ICcnKS5zcGxpdCgnLCAnKTsKICAgIHZhciB0cmFuc2l0aW9uRHVyYXRpb25zID0gKHN0eWxlc1t0cmFuc2l0aW9uUHJvcCArICdEdXJhdGlvbiddIHx8ICcnKS5zcGxpdCgnLCAnKTsKICAgIHZhciB0cmFuc2l0aW9uVGltZW91dCA9IGdldFRpbWVvdXQodHJhbnNpdGlvbkRlbGF5cywgdHJhbnNpdGlvbkR1cmF0aW9ucyk7CiAgICB2YXIgYW5pbWF0aW9uRGVsYXlzID0gKHN0eWxlc1thbmltYXRpb25Qcm9wICsgJ0RlbGF5J10gfHwgJycpLnNwbGl0KCcsICcpOwogICAgdmFyIGFuaW1hdGlvbkR1cmF0aW9ucyA9IChzdHlsZXNbYW5pbWF0aW9uUHJvcCArICdEdXJhdGlvbiddIHx8ICcnKS5zcGxpdCgnLCAnKTsKICAgIHZhciBhbmltYXRpb25UaW1lb3V0ID0gZ2V0VGltZW91dChhbmltYXRpb25EZWxheXMsIGFuaW1hdGlvbkR1cmF0aW9ucyk7CgogICAgdmFyIHR5cGU7CiAgICB2YXIgdGltZW91dCA9IDA7CiAgICB2YXIgcHJvcENvdW50ID0gMDsKICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgaWYgKGV4cGVjdGVkVHlwZSA9PT0gVFJBTlNJVElPTikgewogICAgICBpZiAodHJhbnNpdGlvblRpbWVvdXQgPiAwKSB7CiAgICAgICAgdHlwZSA9IFRSQU5TSVRJT047CiAgICAgICAgdGltZW91dCA9IHRyYW5zaXRpb25UaW1lb3V0OwogICAgICAgIHByb3BDb3VudCA9IHRyYW5zaXRpb25EdXJhdGlvbnMubGVuZ3RoOwogICAgICB9CiAgICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gQU5JTUFUSU9OKSB7CiAgICAgIGlmIChhbmltYXRpb25UaW1lb3V0ID4gMCkgewogICAgICAgIHR5cGUgPSBBTklNQVRJT047CiAgICAgICAgdGltZW91dCA9IGFuaW1hdGlvblRpbWVvdXQ7CiAgICAgICAgcHJvcENvdW50ID0gYW5pbWF0aW9uRHVyYXRpb25zLmxlbmd0aDsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgdGltZW91dCA9IE1hdGgubWF4KHRyYW5zaXRpb25UaW1lb3V0LCBhbmltYXRpb25UaW1lb3V0KTsKICAgICAgdHlwZSA9IHRpbWVvdXQgPiAwCiAgICAgICAgPyB0cmFuc2l0aW9uVGltZW91dCA+IGFuaW1hdGlvblRpbWVvdXQKICAgICAgICAgID8gVFJBTlNJVElPTgogICAgICAgICAgOiBBTklNQVRJT04KICAgICAgICA6IG51bGw7CiAgICAgIHByb3BDb3VudCA9IHR5cGUKICAgICAgICA/IHR5cGUgPT09IFRSQU5TSVRJT04KICAgICAgICAgID8gdHJhbnNpdGlvbkR1cmF0aW9ucy5sZW5ndGgKICAgICAgICAgIDogYW5pbWF0aW9uRHVyYXRpb25zLmxlbmd0aAogICAgICAgIDogMDsKICAgIH0KICAgIHZhciBoYXNUcmFuc2Zvcm0gPQogICAgICB0eXBlID09PSBUUkFOU0lUSU9OICYmCiAgICAgIHRyYW5zZm9ybVJFLnRlc3Qoc3R5bGVzW3RyYW5zaXRpb25Qcm9wICsgJ1Byb3BlcnR5J10pOwogICAgcmV0dXJuIHsKICAgICAgdHlwZTogdHlwZSwKICAgICAgdGltZW91dDogdGltZW91dCwKICAgICAgcHJvcENvdW50OiBwcm9wQ291bnQsCiAgICAgIGhhc1RyYW5zZm9ybTogaGFzVHJhbnNmb3JtCiAgICB9CiAgfQoKICBmdW5jdGlvbiBnZXRUaW1lb3V0IChkZWxheXMsIGR1cmF0aW9ucykgewogICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8KICAgIHdoaWxlIChkZWxheXMubGVuZ3RoIDwgZHVyYXRpb25zLmxlbmd0aCkgewogICAgICBkZWxheXMgPSBkZWxheXMuY29uY2F0KGRlbGF5cyk7CiAgICB9CgogICAgcmV0dXJuIE1hdGgubWF4LmFwcGx5KG51bGwsIGR1cmF0aW9ucy5tYXAoZnVuY3Rpb24gKGQsIGkpIHsKICAgICAgcmV0dXJuIHRvTXMoZCkgKyB0b01zKGRlbGF5c1tpXSkKICAgIH0pKQogIH0KCiAgLy8gT2xkIHZlcnNpb25zIG9mIENocm9taXVtIChiZWxvdyA2MS4wLjMxNjMuMTAwKSBmb3JtYXRzIGZsb2F0aW5nIHBvaW50ZXIgbnVtYmVycwogIC8vIGluIGEgbG9jYWxlLWRlcGVuZGVudCB3YXksIHVzaW5nIGEgY29tbWEgaW5zdGVhZCBvZiBhIGRvdC4KICAvLyBJZiBjb21tYSBpcyBub3QgcmVwbGFjZWQgd2l0aCBhIGRvdCwgdGhlIGlucHV0IHdpbGwgYmUgcm91bmRlZCBkb3duIChpLmUuIGFjdGluZwogIC8vIGFzIGEgZmxvb3IgZnVuY3Rpb24pIGNhdXNpbmcgdW5leHBlY3RlZCBiZWhhdmlvcnMKICBmdW5jdGlvbiB0b01zIChzKSB7CiAgICByZXR1cm4gTnVtYmVyKHMuc2xpY2UoMCwgLTEpLnJlcGxhY2UoJywnLCAnLicpKSAqIDEwMDAKICB9CgogIC8qICAqLwoKICBmdW5jdGlvbiBlbnRlciAodm5vZGUsIHRvZ2dsZURpc3BsYXkpIHsKICAgIHZhciBlbCA9IHZub2RlLmVsbTsKCiAgICAvLyBjYWxsIGxlYXZlIGNhbGxiYWNrIG5vdwogICAgaWYgKGlzRGVmKGVsLl9sZWF2ZUNiKSkgewogICAgICBlbC5fbGVhdmVDYi5jYW5jZWxsZWQgPSB0cnVlOwogICAgICBlbC5fbGVhdmVDYigpOwogICAgfQoKICAgIHZhciBkYXRhID0gcmVzb2x2ZVRyYW5zaXRpb24odm5vZGUuZGF0YS50cmFuc2l0aW9uKTsKICAgIGlmIChpc1VuZGVmKGRhdGEpKSB7CiAgICAgIHJldHVybgogICAgfQoKICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgaWYgKGlzRGVmKGVsLl9lbnRlckNiKSB8fCBlbC5ub2RlVHlwZSAhPT0gMSkgewogICAgICByZXR1cm4KICAgIH0KCiAgICB2YXIgY3NzID0gZGF0YS5jc3M7CiAgICB2YXIgdHlwZSA9IGRhdGEudHlwZTsKICAgIHZhciBlbnRlckNsYXNzID0gZGF0YS5lbnRlckNsYXNzOwogICAgdmFyIGVudGVyVG9DbGFzcyA9IGRhdGEuZW50ZXJUb0NsYXNzOwogICAgdmFyIGVudGVyQWN0aXZlQ2xhc3MgPSBkYXRhLmVudGVyQWN0aXZlQ2xhc3M7CiAgICB2YXIgYXBwZWFyQ2xhc3MgPSBkYXRhLmFwcGVhckNsYXNzOwogICAgdmFyIGFwcGVhclRvQ2xhc3MgPSBkYXRhLmFwcGVhclRvQ2xhc3M7CiAgICB2YXIgYXBwZWFyQWN0aXZlQ2xhc3MgPSBkYXRhLmFwcGVhckFjdGl2ZUNsYXNzOwogICAgdmFyIGJlZm9yZUVudGVyID0gZGF0YS5iZWZvcmVFbnRlcjsKICAgIHZhciBlbnRlciA9IGRhdGEuZW50ZXI7CiAgICB2YXIgYWZ0ZXJFbnRlciA9IGRhdGEuYWZ0ZXJFbnRlcjsKICAgIHZhciBlbnRlckNhbmNlbGxlZCA9IGRhdGEuZW50ZXJDYW5jZWxsZWQ7CiAgICB2YXIgYmVmb3JlQXBwZWFyID0gZGF0YS5iZWZvcmVBcHBlYXI7CiAgICB2YXIgYXBwZWFyID0gZGF0YS5hcHBlYXI7CiAgICB2YXIgYWZ0ZXJBcHBlYXIgPSBkYXRhLmFmdGVyQXBwZWFyOwogICAgdmFyIGFwcGVhckNhbmNlbGxlZCA9IGRhdGEuYXBwZWFyQ2FuY2VsbGVkOwogICAgdmFyIGR1cmF0aW9uID0gZGF0YS5kdXJhdGlvbjsKCiAgICAvLyBhY3RpdmVJbnN0YW5jZSB3aWxsIGFsd2F5cyBiZSB0aGUgPHRyYW5zaXRpb24+IGNvbXBvbmVudCBtYW5hZ2luZyB0aGlzCiAgICAvLyB0cmFuc2l0aW9uLiBPbmUgZWRnZSBjYXNlIHRvIGNoZWNrIGlzIHdoZW4gdGhlIDx0cmFuc2l0aW9uPiBpcyBwbGFjZWQKICAgIC8vIGFzIHRoZSByb290IG5vZGUgb2YgYSBjaGlsZCBjb21wb25lbnQuIEluIHRoYXQgY2FzZSB3ZSBuZWVkIHRvIGNoZWNrCiAgICAvLyA8dHJhbnNpdGlvbj4ncyBwYXJlbnQgZm9yIGFwcGVhciBjaGVjay4KICAgIHZhciBjb250ZXh0ID0gYWN0aXZlSW5zdGFuY2U7CiAgICB2YXIgdHJhbnNpdGlvbk5vZGUgPSBhY3RpdmVJbnN0YW5jZS4kdm5vZGU7CiAgICB3aGlsZSAodHJhbnNpdGlvbk5vZGUgJiYgdHJhbnNpdGlvbk5vZGUucGFyZW50KSB7CiAgICAgIGNvbnRleHQgPSB0cmFuc2l0aW9uTm9kZS5jb250ZXh0OwogICAgICB0cmFuc2l0aW9uTm9kZSA9IHRyYW5zaXRpb25Ob2RlLnBhcmVudDsKICAgIH0KCiAgICB2YXIgaXNBcHBlYXIgPSAhY29udGV4dC5faXNNb3VudGVkIHx8ICF2bm9kZS5pc1Jvb3RJbnNlcnQ7CgogICAgaWYgKGlzQXBwZWFyICYmICFhcHBlYXIgJiYgYXBwZWFyICE9PSAnJykgewogICAgICByZXR1cm4KICAgIH0KCiAgICB2YXIgc3RhcnRDbGFzcyA9IGlzQXBwZWFyICYmIGFwcGVhckNsYXNzCiAgICAgID8gYXBwZWFyQ2xhc3MKICAgICAgOiBlbnRlckNsYXNzOwogICAgdmFyIGFjdGl2ZUNsYXNzID0gaXNBcHBlYXIgJiYgYXBwZWFyQWN0aXZlQ2xhc3MKICAgICAgPyBhcHBlYXJBY3RpdmVDbGFzcwogICAgICA6IGVudGVyQWN0aXZlQ2xhc3M7CiAgICB2YXIgdG9DbGFzcyA9IGlzQXBwZWFyICYmIGFwcGVhclRvQ2xhc3MKICAgICAgPyBhcHBlYXJUb0NsYXNzCiAgICAgIDogZW50ZXJUb0NsYXNzOwoKICAgIHZhciBiZWZvcmVFbnRlckhvb2sgPSBpc0FwcGVhcgogICAgICA/IChiZWZvcmVBcHBlYXIgfHwgYmVmb3JlRW50ZXIpCiAgICAgIDogYmVmb3JlRW50ZXI7CiAgICB2YXIgZW50ZXJIb29rID0gaXNBcHBlYXIKICAgICAgPyAodHlwZW9mIGFwcGVhciA9PT0gJ2Z1bmN0aW9uJyA/IGFwcGVhciA6IGVudGVyKQogICAgICA6IGVudGVyOwogICAgdmFyIGFmdGVyRW50ZXJIb29rID0gaXNBcHBlYXIKICAgICAgPyAoYWZ0ZXJBcHBlYXIgfHwgYWZ0ZXJFbnRlcikKICAgICAgOiBhZnRlckVudGVyOwogICAgdmFyIGVudGVyQ2FuY2VsbGVkSG9vayA9IGlzQXBwZWFyCiAgICAgID8gKGFwcGVhckNhbmNlbGxlZCB8fCBlbnRlckNhbmNlbGxlZCkKICAgICAgOiBlbnRlckNhbmNlbGxlZDsKCiAgICB2YXIgZXhwbGljaXRFbnRlckR1cmF0aW9uID0gdG9OdW1iZXIoCiAgICAgIGlzT2JqZWN0KGR1cmF0aW9uKQogICAgICAgID8gZHVyYXRpb24uZW50ZXIKICAgICAgICA6IGR1cmF0aW9uCiAgICApOwoKICAgIGlmIChleHBsaWNpdEVudGVyRHVyYXRpb24gIT0gbnVsbCkgewogICAgICBjaGVja0R1cmF0aW9uKGV4cGxpY2l0RW50ZXJEdXJhdGlvbiwgJ2VudGVyJywgdm5vZGUpOwogICAgfQoKICAgIHZhciBleHBlY3RzQ1NTID0gY3NzICE9PSBmYWxzZSAmJiAhaXNJRTk7CiAgICB2YXIgdXNlcldhbnRzQ29udHJvbCA9IGdldEhvb2tBcmd1bWVudHNMZW5ndGgoZW50ZXJIb29rKTsKCiAgICB2YXIgY2IgPSBlbC5fZW50ZXJDYiA9IG9uY2UoZnVuY3Rpb24gKCkgewogICAgICBpZiAoZXhwZWN0c0NTUykgewogICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgdG9DbGFzcyk7CiAgICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBhY3RpdmVDbGFzcyk7CiAgICAgIH0KICAgICAgaWYgKGNiLmNhbmNlbGxlZCkgewogICAgICAgIGlmIChleHBlY3RzQ1NTKSB7CiAgICAgICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIHN0YXJ0Q2xhc3MpOwogICAgICAgIH0KICAgICAgICBlbnRlckNhbmNlbGxlZEhvb2sgJiYgZW50ZXJDYW5jZWxsZWRIb29rKGVsKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhZnRlckVudGVySG9vayAmJiBhZnRlckVudGVySG9vayhlbCk7CiAgICAgIH0KICAgICAgZWwuX2VudGVyQ2IgPSBudWxsOwogICAgfSk7CgogICAgaWYgKCF2bm9kZS5kYXRhLnNob3cpIHsKICAgICAgLy8gcmVtb3ZlIHBlbmRpbmcgbGVhdmUgZWxlbWVudCBvbiBlbnRlciBieSBpbmplY3RpbmcgYW4gaW5zZXJ0IGhvb2sKICAgICAgbWVyZ2VWTm9kZUhvb2sodm5vZGUsICdpbnNlcnQnLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHBhcmVudCA9IGVsLnBhcmVudE5vZGU7CiAgICAgICAgdmFyIHBlbmRpbmdOb2RlID0gcGFyZW50ICYmIHBhcmVudC5fcGVuZGluZyAmJiBwYXJlbnQuX3BlbmRpbmdbdm5vZGUua2V5XTsKICAgICAgICBpZiAocGVuZGluZ05vZGUgJiYKICAgICAgICAgIHBlbmRpbmdOb2RlLnRhZyA9PT0gdm5vZGUudGFnICYmCiAgICAgICAgICBwZW5kaW5nTm9kZS5lbG0uX2xlYXZlQ2IKICAgICAgICApIHsKICAgICAgICAgIHBlbmRpbmdOb2RlLmVsbS5fbGVhdmVDYigpOwogICAgICAgIH0KICAgICAgICBlbnRlckhvb2sgJiYgZW50ZXJIb29rKGVsLCBjYik7CiAgICAgIH0pOwogICAgfQoKICAgIC8vIHN0YXJ0IGVudGVyIHRyYW5zaXRpb24KICAgIGJlZm9yZUVudGVySG9vayAmJiBiZWZvcmVFbnRlckhvb2soZWwpOwogICAgaWYgKGV4cGVjdHNDU1MpIHsKICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBzdGFydENsYXNzKTsKICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBhY3RpdmVDbGFzcyk7CiAgICAgIG5leHRGcmFtZShmdW5jdGlvbiAoKSB7CiAgICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBzdGFydENsYXNzKTsKICAgICAgICBpZiAoIWNiLmNhbmNlbGxlZCkgewogICAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCB0b0NsYXNzKTsKICAgICAgICAgIGlmICghdXNlcldhbnRzQ29udHJvbCkgewogICAgICAgICAgICBpZiAoaXNWYWxpZER1cmF0aW9uKGV4cGxpY2l0RW50ZXJEdXJhdGlvbikpIHsKICAgICAgICAgICAgICBzZXRUaW1lb3V0KGNiLCBleHBsaWNpdEVudGVyRHVyYXRpb24pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHdoZW5UcmFuc2l0aW9uRW5kcyhlbCwgdHlwZSwgY2IpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9KTsKICAgIH0KCiAgICBpZiAodm5vZGUuZGF0YS5zaG93KSB7CiAgICAgIHRvZ2dsZURpc3BsYXkgJiYgdG9nZ2xlRGlzcGxheSgpOwogICAgICBlbnRlckhvb2sgJiYgZW50ZXJIb29rKGVsLCBjYik7CiAgICB9CgogICAgaWYgKCFleHBlY3RzQ1NTICYmICF1c2VyV2FudHNDb250cm9sKSB7CiAgICAgIGNiKCk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBsZWF2ZSAodm5vZGUsIHJtKSB7CiAgICB2YXIgZWwgPSB2bm9kZS5lbG07CgogICAgLy8gY2FsbCBlbnRlciBjYWxsYmFjayBub3cKICAgIGlmIChpc0RlZihlbC5fZW50ZXJDYikpIHsKICAgICAgZWwuX2VudGVyQ2IuY2FuY2VsbGVkID0gdHJ1ZTsKICAgICAgZWwuX2VudGVyQ2IoKTsKICAgIH0KCiAgICB2YXIgZGF0YSA9IHJlc29sdmVUcmFuc2l0aW9uKHZub2RlLmRhdGEudHJhbnNpdGlvbik7CiAgICBpZiAoaXNVbmRlZihkYXRhKSB8fCBlbC5ub2RlVHlwZSAhPT0gMSkgewogICAgICByZXR1cm4gcm0oKQogICAgfQoKICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgaWYgKGlzRGVmKGVsLl9sZWF2ZUNiKSkgewogICAgICByZXR1cm4KICAgIH0KCiAgICB2YXIgY3NzID0gZGF0YS5jc3M7CiAgICB2YXIgdHlwZSA9IGRhdGEudHlwZTsKICAgIHZhciBsZWF2ZUNsYXNzID0gZGF0YS5sZWF2ZUNsYXNzOwogICAgdmFyIGxlYXZlVG9DbGFzcyA9IGRhdGEubGVhdmVUb0NsYXNzOwogICAgdmFyIGxlYXZlQWN0aXZlQ2xhc3MgPSBkYXRhLmxlYXZlQWN0aXZlQ2xhc3M7CiAgICB2YXIgYmVmb3JlTGVhdmUgPSBkYXRhLmJlZm9yZUxlYXZlOwogICAgdmFyIGxlYXZlID0gZGF0YS5sZWF2ZTsKICAgIHZhciBhZnRlckxlYXZlID0gZGF0YS5hZnRlckxlYXZlOwogICAgdmFyIGxlYXZlQ2FuY2VsbGVkID0gZGF0YS5sZWF2ZUNhbmNlbGxlZDsKICAgIHZhciBkZWxheUxlYXZlID0gZGF0YS5kZWxheUxlYXZlOwogICAgdmFyIGR1cmF0aW9uID0gZGF0YS5kdXJhdGlvbjsKCiAgICB2YXIgZXhwZWN0c0NTUyA9IGNzcyAhPT0gZmFsc2UgJiYgIWlzSUU5OwogICAgdmFyIHVzZXJXYW50c0NvbnRyb2wgPSBnZXRIb29rQXJndW1lbnRzTGVuZ3RoKGxlYXZlKTsKCiAgICB2YXIgZXhwbGljaXRMZWF2ZUR1cmF0aW9uID0gdG9OdW1iZXIoCiAgICAgIGlzT2JqZWN0KGR1cmF0aW9uKQogICAgICAgID8gZHVyYXRpb24ubGVhdmUKICAgICAgICA6IGR1cmF0aW9uCiAgICApOwoKICAgIGlmIChpc0RlZihleHBsaWNpdExlYXZlRHVyYXRpb24pKSB7CiAgICAgIGNoZWNrRHVyYXRpb24oZXhwbGljaXRMZWF2ZUR1cmF0aW9uLCAnbGVhdmUnLCB2bm9kZSk7CiAgICB9CgogICAgdmFyIGNiID0gZWwuX2xlYXZlQ2IgPSBvbmNlKGZ1bmN0aW9uICgpIHsKICAgICAgaWYgKGVsLnBhcmVudE5vZGUgJiYgZWwucGFyZW50Tm9kZS5fcGVuZGluZykgewogICAgICAgIGVsLnBhcmVudE5vZGUuX3BlbmRpbmdbdm5vZGUua2V5XSA9IG51bGw7CiAgICAgIH0KICAgICAgaWYgKGV4cGVjdHNDU1MpIHsKICAgICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIGxlYXZlVG9DbGFzcyk7CiAgICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZUFjdGl2ZUNsYXNzKTsKICAgICAgfQogICAgICBpZiAoY2IuY2FuY2VsbGVkKSB7CiAgICAgICAgaWYgKGV4cGVjdHNDU1MpIHsKICAgICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVDbGFzcyk7CiAgICAgICAgfQogICAgICAgIGxlYXZlQ2FuY2VsbGVkICYmIGxlYXZlQ2FuY2VsbGVkKGVsKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBybSgpOwogICAgICAgIGFmdGVyTGVhdmUgJiYgYWZ0ZXJMZWF2ZShlbCk7CiAgICAgIH0KICAgICAgZWwuX2xlYXZlQ2IgPSBudWxsOwogICAgfSk7CgogICAgaWYgKGRlbGF5TGVhdmUpIHsKICAgICAgZGVsYXlMZWF2ZShwZXJmb3JtTGVhdmUpOwogICAgfSBlbHNlIHsKICAgICAgcGVyZm9ybUxlYXZlKCk7CiAgICB9CgogICAgZnVuY3Rpb24gcGVyZm9ybUxlYXZlICgpIHsKICAgICAgLy8gdGhlIGRlbGF5ZWQgbGVhdmUgbWF5IGhhdmUgYWxyZWFkeSBiZWVuIGNhbmNlbGxlZAogICAgICBpZiAoY2IuY2FuY2VsbGVkKSB7CiAgICAgICAgcmV0dXJuCiAgICAgIH0KICAgICAgLy8gcmVjb3JkIGxlYXZpbmcgZWxlbWVudAogICAgICBpZiAoIXZub2RlLmRhdGEuc2hvdyAmJiBlbC5wYXJlbnROb2RlKSB7CiAgICAgICAgKGVsLnBhcmVudE5vZGUuX3BlbmRpbmcgfHwgKGVsLnBhcmVudE5vZGUuX3BlbmRpbmcgPSB7fSkpWyh2bm9kZS5rZXkpXSA9IHZub2RlOwogICAgICB9CiAgICAgIGJlZm9yZUxlYXZlICYmIGJlZm9yZUxlYXZlKGVsKTsKICAgICAgaWYgKGV4cGVjdHNDU1MpIHsKICAgICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGxlYXZlQ2xhc3MpOwogICAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVBY3RpdmVDbGFzcyk7CiAgICAgICAgbmV4dEZyYW1lKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVDbGFzcyk7CiAgICAgICAgICBpZiAoIWNiLmNhbmNlbGxlZCkgewogICAgICAgICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGxlYXZlVG9DbGFzcyk7CiAgICAgICAgICAgIGlmICghdXNlcldhbnRzQ29udHJvbCkgewogICAgICAgICAgICAgIGlmIChpc1ZhbGlkRHVyYXRpb24oZXhwbGljaXRMZWF2ZUR1cmF0aW9uKSkgewogICAgICAgICAgICAgICAgc2V0VGltZW91dChjYiwgZXhwbGljaXRMZWF2ZUR1cmF0aW9uKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgd2hlblRyYW5zaXRpb25FbmRzKGVsLCB0eXBlLCBjYik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgIH0KICAgICAgbGVhdmUgJiYgbGVhdmUoZWwsIGNiKTsKICAgICAgaWYgKCFleHBlY3RzQ1NTICYmICF1c2VyV2FudHNDb250cm9sKSB7CiAgICAgICAgY2IoKTsKICAgICAgfQogICAgfQogIH0KCiAgLy8gb25seSB1c2VkIGluIGRldiBtb2RlCiAgZnVuY3Rpb24gY2hlY2tEdXJhdGlvbiAodmFsLCBuYW1lLCB2bm9kZSkgewogICAgaWYgKHR5cGVvZiB2YWwgIT09ICdudW1iZXInKSB7CiAgICAgIHdhcm4oCiAgICAgICAgIjx0cmFuc2l0aW9uPiBleHBsaWNpdCAiICsgbmFtZSArICIgZHVyYXRpb24gaXMgbm90IGEgdmFsaWQgbnVtYmVyIC0gIiArCiAgICAgICAgImdvdCAiICsgKEpTT04uc3RyaW5naWZ5KHZhbCkpICsgIi4iLAogICAgICAgIHZub2RlLmNvbnRleHQKICAgICAgKTsKICAgIH0gZWxzZSBpZiAoaXNOYU4odmFsKSkgewogICAgICB3YXJuKAogICAgICAgICI8dHJhbnNpdGlvbj4gZXhwbGljaXQgIiArIG5hbWUgKyAiIGR1cmF0aW9uIGlzIE5hTiAtICIgKwogICAgICAgICd0aGUgZHVyYXRpb24gZXhwcmVzc2lvbiBtaWdodCBiZSBpbmNvcnJlY3QuJywKICAgICAgICB2bm9kZS5jb250ZXh0CiAgICAgICk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBpc1ZhbGlkRHVyYXRpb24gKHZhbCkgewogICAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdudW1iZXInICYmICFpc05hTih2YWwpCiAgfQoKICAvKioKICAgKiBOb3JtYWxpemUgYSB0cmFuc2l0aW9uIGhvb2sncyBhcmd1bWVudCBsZW5ndGguIFRoZSBob29rIG1heSBiZToKICAgKiAtIGEgbWVyZ2VkIGhvb2sgKGludm9rZXIpIHdpdGggdGhlIG9yaWdpbmFsIGluIC5mbnMKICAgKiAtIGEgd3JhcHBlZCBjb21wb25lbnQgbWV0aG9kIChjaGVjayAuX2xlbmd0aCkKICAgKiAtIGEgcGxhaW4gZnVuY3Rpb24gKC5sZW5ndGgpCiAgICovCiAgZnVuY3Rpb24gZ2V0SG9va0FyZ3VtZW50c0xlbmd0aCAoZm4pIHsKICAgIGlmIChpc1VuZGVmKGZuKSkgewogICAgICByZXR1cm4gZmFsc2UKICAgIH0KICAgIHZhciBpbnZva2VyRm5zID0gZm4uZm5zOwogICAgaWYgKGlzRGVmKGludm9rZXJGbnMpKSB7CiAgICAgIC8vIGludm9rZXIKICAgICAgcmV0dXJuIGdldEhvb2tBcmd1bWVudHNMZW5ndGgoCiAgICAgICAgQXJyYXkuaXNBcnJheShpbnZva2VyRm5zKQogICAgICAgICAgPyBpbnZva2VyRm5zWzBdCiAgICAgICAgICA6IGludm9rZXJGbnMKICAgICAgKQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIChmbi5fbGVuZ3RoIHx8IGZuLmxlbmd0aCkgPiAxCiAgICB9CiAgfQoKICBmdW5jdGlvbiBfZW50ZXIgKF8sIHZub2RlKSB7CiAgICBpZiAodm5vZGUuZGF0YS5zaG93ICE9PSB0cnVlKSB7CiAgICAgIGVudGVyKHZub2RlKTsKICAgIH0KICB9CgogIHZhciB0cmFuc2l0aW9uID0gaW5Ccm93c2VyID8gewogICAgY3JlYXRlOiBfZW50ZXIsCiAgICBhY3RpdmF0ZTogX2VudGVyLAogICAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUkJDEgKHZub2RlLCBybSkgewogICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqLwogICAgICBpZiAodm5vZGUuZGF0YS5zaG93ICE9PSB0cnVlKSB7CiAgICAgICAgbGVhdmUodm5vZGUsIHJtKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBybSgpOwogICAgICB9CiAgICB9CiAgfSA6IHt9OwoKICB2YXIgcGxhdGZvcm1Nb2R1bGVzID0gWwogICAgYXR0cnMsCiAgICBrbGFzcywKICAgIGV2ZW50cywKICAgIGRvbVByb3BzLAogICAgc3R5bGUsCiAgICB0cmFuc2l0aW9uCiAgXTsKCiAgLyogICovCgogIC8vIHRoZSBkaXJlY3RpdmUgbW9kdWxlIHNob3VsZCBiZSBhcHBsaWVkIGxhc3QsIGFmdGVyIGFsbAogIC8vIGJ1aWx0LWluIG1vZHVsZXMgaGF2ZSBiZWVuIGFwcGxpZWQuCiAgdmFyIG1vZHVsZXMgPSBwbGF0Zm9ybU1vZHVsZXMuY29uY2F0KGJhc2VNb2R1bGVzKTsKCiAgdmFyIHBhdGNoID0gY3JlYXRlUGF0Y2hGdW5jdGlvbih7IG5vZGVPcHM6IG5vZGVPcHMsIG1vZHVsZXM6IG1vZHVsZXMgfSk7CgogIC8qKgogICAqIE5vdCB0eXBlIGNoZWNraW5nIHRoaXMgZmlsZSBiZWNhdXNlIGZsb3cgZG9lc24ndCBsaWtlIGF0dGFjaGluZwogICAqIHByb3BlcnRpZXMgdG8gRWxlbWVudHMuCiAgICovCgogIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogIGlmIChpc0lFOSkgewogICAgLy8gaHR0cDovL3d3dy5tYXR0czQxMS5jb20vcG9zdC9pbnRlcm5ldC1leHBsb3Jlci05LW9uaW5wdXQvCiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdzZWxlY3Rpb25jaGFuZ2UnLCBmdW5jdGlvbiAoKSB7CiAgICAgIHZhciBlbCA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7CiAgICAgIGlmIChlbCAmJiBlbC52bW9kZWwpIHsKICAgICAgICB0cmlnZ2VyKGVsLCAnaW5wdXQnKTsKICAgICAgfQogICAgfSk7CiAgfQoKICB2YXIgZGlyZWN0aXZlID0gewogICAgaW5zZXJ0ZWQ6IGZ1bmN0aW9uIGluc2VydGVkIChlbCwgYmluZGluZywgdm5vZGUsIG9sZFZub2RlKSB7CiAgICAgIGlmICh2bm9kZS50YWcgPT09ICdzZWxlY3QnKSB7CiAgICAgICAgLy8gIzY5MDMKICAgICAgICBpZiAob2xkVm5vZGUuZWxtICYmICFvbGRWbm9kZS5lbG0uX3ZPcHRpb25zKSB7CiAgICAgICAgICBtZXJnZVZOb2RlSG9vayh2bm9kZSwgJ3Bvc3RwYXRjaCcsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZGlyZWN0aXZlLmNvbXBvbmVudFVwZGF0ZWQoZWwsIGJpbmRpbmcsIHZub2RlKTsKICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzZXRTZWxlY3RlZChlbCwgYmluZGluZywgdm5vZGUuY29udGV4dCk7CiAgICAgICAgfQogICAgICAgIGVsLl92T3B0aW9ucyA9IFtdLm1hcC5jYWxsKGVsLm9wdGlvbnMsIGdldFZhbHVlKTsKICAgICAgfSBlbHNlIGlmICh2bm9kZS50YWcgPT09ICd0ZXh0YXJlYScgfHwgaXNUZXh0SW5wdXRUeXBlKGVsLnR5cGUpKSB7CiAgICAgICAgZWwuX3ZNb2RpZmllcnMgPSBiaW5kaW5nLm1vZGlmaWVyczsKICAgICAgICBpZiAoIWJpbmRpbmcubW9kaWZpZXJzLmxhenkpIHsKICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NvbXBvc2l0aW9uc3RhcnQnLCBvbkNvbXBvc2l0aW9uU3RhcnQpOwogICAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcignY29tcG9zaXRpb25lbmQnLCBvbkNvbXBvc2l0aW9uRW5kKTsKICAgICAgICAgIC8vIFNhZmFyaSA8IDEwLjIgJiBVSVdlYlZpZXcgZG9lc24ndCBmaXJlIGNvbXBvc2l0aW9uZW5kIHdoZW4KICAgICAgICAgIC8vIHN3aXRjaGluZyBmb2N1cyBiZWZvcmUgY29uZmlybWluZyBjb21wb3NpdGlvbiBjaG9pY2UKICAgICAgICAgIC8vIHRoaXMgYWxzbyBmaXhlcyB0aGUgaXNzdWUgd2hlcmUgc29tZSBicm93c2VycyBlLmcuIGlPUyBDaHJvbWUKICAgICAgICAgIC8vIGZpcmVzICJjaGFuZ2UiIGluc3RlYWQgb2YgImlucHV0IiBvbiBhdXRvY29tcGxldGUuCiAgICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBvbkNvbXBvc2l0aW9uRW5kKTsKICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgICAgICAgaWYgKGlzSUU5KSB7CiAgICAgICAgICAgIGVsLnZtb2RlbCA9IHRydWU7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9LAoKICAgIGNvbXBvbmVudFVwZGF0ZWQ6IGZ1bmN0aW9uIGNvbXBvbmVudFVwZGF0ZWQgKGVsLCBiaW5kaW5nLCB2bm9kZSkgewogICAgICBpZiAodm5vZGUudGFnID09PSAnc2VsZWN0JykgewogICAgICAgIHNldFNlbGVjdGVkKGVsLCBiaW5kaW5nLCB2bm9kZS5jb250ZXh0KTsKICAgICAgICAvLyBpbiBjYXNlIHRoZSBvcHRpb25zIHJlbmRlcmVkIGJ5IHYtZm9yIGhhdmUgY2hhbmdlZCwKICAgICAgICAvLyBpdCdzIHBvc3NpYmxlIHRoYXQgdGhlIHZhbHVlIGlzIG91dC1vZi1zeW5jIHdpdGggdGhlIHJlbmRlcmVkIG9wdGlvbnMuCiAgICAgICAgLy8gZGV0ZWN0IHN1Y2ggY2FzZXMgYW5kIGZpbHRlciBvdXQgdmFsdWVzIHRoYXQgbm8gbG9uZ2VyIGhhcyBhIG1hdGNoaW5nCiAgICAgICAgLy8gb3B0aW9uIGluIHRoZSBET00uCiAgICAgICAgdmFyIHByZXZPcHRpb25zID0gZWwuX3ZPcHRpb25zOwogICAgICAgIHZhciBjdXJPcHRpb25zID0gZWwuX3ZPcHRpb25zID0gW10ubWFwLmNhbGwoZWwub3B0aW9ucywgZ2V0VmFsdWUpOwogICAgICAgIGlmIChjdXJPcHRpb25zLnNvbWUoZnVuY3Rpb24gKG8sIGkpIHsgcmV0dXJuICFsb29zZUVxdWFsKG8sIHByZXZPcHRpb25zW2ldKTsgfSkpIHsKICAgICAgICAgIC8vIHRyaWdnZXIgY2hhbmdlIGV2ZW50IGlmCiAgICAgICAgICAvLyBubyBtYXRjaGluZyBvcHRpb24gZm91bmQgZm9yIGF0IGxlYXN0IG9uZSB2YWx1ZQogICAgICAgICAgdmFyIG5lZWRSZXNldCA9IGVsLm11bHRpcGxlCiAgICAgICAgICAgID8gYmluZGluZy52YWx1ZS5zb21lKGZ1bmN0aW9uICh2KSB7IHJldHVybiBoYXNOb01hdGNoaW5nT3B0aW9uKHYsIGN1ck9wdGlvbnMpOyB9KQogICAgICAgICAgICA6IGJpbmRpbmcudmFsdWUgIT09IGJpbmRpbmcub2xkVmFsdWUgJiYgaGFzTm9NYXRjaGluZ09wdGlvbihiaW5kaW5nLnZhbHVlLCBjdXJPcHRpb25zKTsKICAgICAgICAgIGlmIChuZWVkUmVzZXQpIHsKICAgICAgICAgICAgdHJpZ2dlcihlbCwgJ2NoYW5nZScpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH07CgogIGZ1bmN0aW9uIHNldFNlbGVjdGVkIChlbCwgYmluZGluZywgdm0pIHsKICAgIGFjdHVhbGx5U2V0U2VsZWN0ZWQoZWwsIGJpbmRpbmcsIHZtKTsKICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgaWYgKGlzSUUgfHwgaXNFZGdlKSB7CiAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgIGFjdHVhbGx5U2V0U2VsZWN0ZWQoZWwsIGJpbmRpbmcsIHZtKTsKICAgICAgfSwgMCk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBhY3R1YWxseVNldFNlbGVjdGVkIChlbCwgYmluZGluZywgdm0pIHsKICAgIHZhciB2YWx1ZSA9IGJpbmRpbmcudmFsdWU7CiAgICB2YXIgaXNNdWx0aXBsZSA9IGVsLm11bHRpcGxlOwogICAgaWYgKGlzTXVsdGlwbGUgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7CiAgICAgIHdhcm4oCiAgICAgICAgIjxzZWxlY3QgbXVsdGlwbGUgdi1tb2RlbD1cIiIgKyAoYmluZGluZy5leHByZXNzaW9uKSArICJcIj4gIiArCiAgICAgICAgImV4cGVjdHMgYW4gQXJyYXkgdmFsdWUgZm9yIGl0cyBiaW5kaW5nLCBidXQgZ290ICIgKyAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKS5zbGljZSg4LCAtMSkpLAogICAgICAgIHZtCiAgICAgICk7CiAgICAgIHJldHVybgogICAgfQogICAgdmFyIHNlbGVjdGVkLCBvcHRpb247CiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGVsLm9wdGlvbnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7CiAgICAgIG9wdGlvbiA9IGVsLm9wdGlvbnNbaV07CiAgICAgIGlmIChpc011bHRpcGxlKSB7CiAgICAgICAgc2VsZWN0ZWQgPSBsb29zZUluZGV4T2YodmFsdWUsIGdldFZhbHVlKG9wdGlvbikpID4gLTE7CiAgICAgICAgaWYgKG9wdGlvbi5zZWxlY3RlZCAhPT0gc2VsZWN0ZWQpIHsKICAgICAgICAgIG9wdGlvbi5zZWxlY3RlZCA9IHNlbGVjdGVkOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAobG9vc2VFcXVhbChnZXRWYWx1ZShvcHRpb24pLCB2YWx1ZSkpIHsKICAgICAgICAgIGlmIChlbC5zZWxlY3RlZEluZGV4ICE9PSBpKSB7CiAgICAgICAgICAgIGVsLnNlbGVjdGVkSW5kZXggPSBpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBpZiAoIWlzTXVsdGlwbGUpIHsKICAgICAgZWwuc2VsZWN0ZWRJbmRleCA9IC0xOwogICAgfQogIH0KCiAgZnVuY3Rpb24gaGFzTm9NYXRjaGluZ09wdGlvbiAodmFsdWUsIG9wdGlvbnMpIHsKICAgIHJldHVybiBvcHRpb25zLmV2ZXJ5KGZ1bmN0aW9uIChvKSB7IHJldHVybiAhbG9vc2VFcXVhbChvLCB2YWx1ZSk7IH0pCiAgfQoKICBmdW5jdGlvbiBnZXRWYWx1ZSAob3B0aW9uKSB7CiAgICByZXR1cm4gJ192YWx1ZScgaW4gb3B0aW9uCiAgICAgID8gb3B0aW9uLl92YWx1ZQogICAgICA6IG9wdGlvbi52YWx1ZQogIH0KCiAgZnVuY3Rpb24gb25Db21wb3NpdGlvblN0YXJ0IChlKSB7CiAgICBlLnRhcmdldC5jb21wb3NpbmcgPSB0cnVlOwogIH0KCiAgZnVuY3Rpb24gb25Db21wb3NpdGlvbkVuZCAoZSkgewogICAgLy8gcHJldmVudCB0cmlnZ2VyaW5nIGFuIGlucHV0IGV2ZW50IGZvciBubyByZWFzb24KICAgIGlmICghZS50YXJnZXQuY29tcG9zaW5nKSB7IHJldHVybiB9CiAgICBlLnRhcmdldC5jb21wb3NpbmcgPSBmYWxzZTsKICAgIHRyaWdnZXIoZS50YXJnZXQsICdpbnB1dCcpOwogIH0KCiAgZnVuY3Rpb24gdHJpZ2dlciAoZWwsIHR5cGUpIHsKICAgIHZhciBlID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0hUTUxFdmVudHMnKTsKICAgIGUuaW5pdEV2ZW50KHR5cGUsIHRydWUsIHRydWUpOwogICAgZWwuZGlzcGF0Y2hFdmVudChlKTsKICB9CgogIC8qICAqLwoKICAvLyByZWN1cnNpdmVseSBzZWFyY2ggZm9yIHBvc3NpYmxlIHRyYW5zaXRpb24gZGVmaW5lZCBpbnNpZGUgdGhlIGNvbXBvbmVudCByb290CiAgZnVuY3Rpb24gbG9jYXRlTm9kZSAodm5vZGUpIHsKICAgIHJldHVybiB2bm9kZS5jb21wb25lbnRJbnN0YW5jZSAmJiAoIXZub2RlLmRhdGEgfHwgIXZub2RlLmRhdGEudHJhbnNpdGlvbikKICAgICAgPyBsb2NhdGVOb2RlKHZub2RlLmNvbXBvbmVudEluc3RhbmNlLl92bm9kZSkKICAgICAgOiB2bm9kZQogIH0KCiAgdmFyIHNob3cgPSB7CiAgICBiaW5kOiBmdW5jdGlvbiBiaW5kIChlbCwgcmVmLCB2bm9kZSkgewogICAgICB2YXIgdmFsdWUgPSByZWYudmFsdWU7CgogICAgICB2bm9kZSA9IGxvY2F0ZU5vZGUodm5vZGUpOwogICAgICB2YXIgdHJhbnNpdGlvbiQkMSA9IHZub2RlLmRhdGEgJiYgdm5vZGUuZGF0YS50cmFuc2l0aW9uOwogICAgICB2YXIgb3JpZ2luYWxEaXNwbGF5ID0gZWwuX192T3JpZ2luYWxEaXNwbGF5ID0KICAgICAgICBlbC5zdHlsZS5kaXNwbGF5ID09PSAnbm9uZScgPyAnJyA6IGVsLnN0eWxlLmRpc3BsYXk7CiAgICAgIGlmICh2YWx1ZSAmJiB0cmFuc2l0aW9uJCQxKSB7CiAgICAgICAgdm5vZGUuZGF0YS5zaG93ID0gdHJ1ZTsKICAgICAgICBlbnRlcih2bm9kZSwgZnVuY3Rpb24gKCkgewogICAgICAgICAgZWwuc3R5bGUuZGlzcGxheSA9IG9yaWdpbmFsRGlzcGxheTsKICAgICAgICB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gdmFsdWUgPyBvcmlnaW5hbERpc3BsYXkgOiAnbm9uZSc7CiAgICAgIH0KICAgIH0sCgogICAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUgKGVsLCByZWYsIHZub2RlKSB7CiAgICAgIHZhciB2YWx1ZSA9IHJlZi52YWx1ZTsKICAgICAgdmFyIG9sZFZhbHVlID0gcmVmLm9sZFZhbHVlOwoKICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICAgIGlmICghdmFsdWUgPT09ICFvbGRWYWx1ZSkgeyByZXR1cm4gfQogICAgICB2bm9kZSA9IGxvY2F0ZU5vZGUodm5vZGUpOwogICAgICB2YXIgdHJhbnNpdGlvbiQkMSA9IHZub2RlLmRhdGEgJiYgdm5vZGUuZGF0YS50cmFuc2l0aW9uOwogICAgICBpZiAodHJhbnNpdGlvbiQkMSkgewogICAgICAgIHZub2RlLmRhdGEuc2hvdyA9IHRydWU7CiAgICAgICAgaWYgKHZhbHVlKSB7CiAgICAgICAgICBlbnRlcih2bm9kZSwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gZWwuX192T3JpZ2luYWxEaXNwbGF5OwogICAgICAgICAgfSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGxlYXZlKHZub2RlLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZWwuc3R5bGUuZGlzcGxheSA9IHZhbHVlID8gZWwuX192T3JpZ2luYWxEaXNwbGF5IDogJ25vbmUnOwogICAgICB9CiAgICB9LAoKICAgIHVuYmluZDogZnVuY3Rpb24gdW5iaW5kICgKICAgICAgZWwsCiAgICAgIGJpbmRpbmcsCiAgICAgIHZub2RlLAogICAgICBvbGRWbm9kZSwKICAgICAgaXNEZXN0cm95CiAgICApIHsKICAgICAgaWYgKCFpc0Rlc3Ryb3kpIHsKICAgICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gZWwuX192T3JpZ2luYWxEaXNwbGF5OwogICAgICB9CiAgICB9CiAgfTsKCiAgdmFyIHBsYXRmb3JtRGlyZWN0aXZlcyA9IHsKICAgIG1vZGVsOiBkaXJlY3RpdmUsCiAgICBzaG93OiBzaG93CiAgfTsKCiAgLyogICovCgogIHZhciB0cmFuc2l0aW9uUHJvcHMgPSB7CiAgICBuYW1lOiBTdHJpbmcsCiAgICBhcHBlYXI6IEJvb2xlYW4sCiAgICBjc3M6IEJvb2xlYW4sCiAgICBtb2RlOiBTdHJpbmcsCiAgICB0eXBlOiBTdHJpbmcsCiAgICBlbnRlckNsYXNzOiBTdHJpbmcsCiAgICBsZWF2ZUNsYXNzOiBTdHJpbmcsCiAgICBlbnRlclRvQ2xhc3M6IFN0cmluZywKICAgIGxlYXZlVG9DbGFzczogU3RyaW5nLAogICAgZW50ZXJBY3RpdmVDbGFzczogU3RyaW5nLAogICAgbGVhdmVBY3RpdmVDbGFzczogU3RyaW5nLAogICAgYXBwZWFyQ2xhc3M6IFN0cmluZywKICAgIGFwcGVhckFjdGl2ZUNsYXNzOiBTdHJpbmcsCiAgICBhcHBlYXJUb0NsYXNzOiBTdHJpbmcsCiAgICBkdXJhdGlvbjogW051bWJlciwgU3RyaW5nLCBPYmplY3RdCiAgfTsKCiAgLy8gaW4gY2FzZSB0aGUgY2hpbGQgaXMgYWxzbyBhbiBhYnN0cmFjdCBjb21wb25lbnQsIGUuZy4gPGtlZXAtYWxpdmU+CiAgLy8gd2Ugd2FudCB0byByZWN1cnNpdmVseSByZXRyaWV2ZSB0aGUgcmVhbCBjb21wb25lbnQgdG8gYmUgcmVuZGVyZWQKICBmdW5jdGlvbiBnZXRSZWFsQ2hpbGQgKHZub2RlKSB7CiAgICB2YXIgY29tcE9wdGlvbnMgPSB2bm9kZSAmJiB2bm9kZS5jb21wb25lbnRPcHRpb25zOwogICAgaWYgKGNvbXBPcHRpb25zICYmIGNvbXBPcHRpb25zLkN0b3Iub3B0aW9ucy5hYnN0cmFjdCkgewogICAgICByZXR1cm4gZ2V0UmVhbENoaWxkKGdldEZpcnN0Q29tcG9uZW50Q2hpbGQoY29tcE9wdGlvbnMuY2hpbGRyZW4pKQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIHZub2RlCiAgICB9CiAgfQoKICBmdW5jdGlvbiBleHRyYWN0VHJhbnNpdGlvbkRhdGEgKGNvbXApIHsKICAgIHZhciBkYXRhID0ge307CiAgICB2YXIgb3B0aW9ucyA9IGNvbXAuJG9wdGlvbnM7CiAgICAvLyBwcm9wcwogICAgZm9yICh2YXIga2V5IGluIG9wdGlvbnMucHJvcHNEYXRhKSB7CiAgICAgIGRhdGFba2V5XSA9IGNvbXBba2V5XTsKICAgIH0KICAgIC8vIGV2ZW50cy4KICAgIC8vIGV4dHJhY3QgbGlzdGVuZXJzIGFuZCBwYXNzIHRoZW0gZGlyZWN0bHkgdG8gdGhlIHRyYW5zaXRpb24gbWV0aG9kcwogICAgdmFyIGxpc3RlbmVycyA9IG9wdGlvbnMuX3BhcmVudExpc3RlbmVyczsKICAgIGZvciAodmFyIGtleSQxIGluIGxpc3RlbmVycykgewogICAgICBkYXRhW2NhbWVsaXplKGtleSQxKV0gPSBsaXN0ZW5lcnNba2V5JDFdOwogICAgfQogICAgcmV0dXJuIGRhdGEKICB9CgogIGZ1bmN0aW9uIHBsYWNlaG9sZGVyIChoLCByYXdDaGlsZCkgewogICAgaWYgKC9cZC1rZWVwLWFsaXZlJC8udGVzdChyYXdDaGlsZC50YWcpKSB7CiAgICAgIHJldHVybiBoKCdrZWVwLWFsaXZlJywgewogICAgICAgIHByb3BzOiByYXdDaGlsZC5jb21wb25lbnRPcHRpb25zLnByb3BzRGF0YQogICAgICB9KQogICAgfQogIH0KCiAgZnVuY3Rpb24gaGFzUGFyZW50VHJhbnNpdGlvbiAodm5vZGUpIHsKICAgIHdoaWxlICgodm5vZGUgPSB2bm9kZS5wYXJlbnQpKSB7CiAgICAgIGlmICh2bm9kZS5kYXRhLnRyYW5zaXRpb24pIHsKICAgICAgICByZXR1cm4gdHJ1ZQogICAgICB9CiAgICB9CiAgfQoKICBmdW5jdGlvbiBpc1NhbWVDaGlsZCAoY2hpbGQsIG9sZENoaWxkKSB7CiAgICByZXR1cm4gb2xkQ2hpbGQua2V5ID09PSBjaGlsZC5rZXkgJiYgb2xkQ2hpbGQudGFnID09PSBjaGlsZC50YWcKICB9CgogIHZhciBpc05vdFRleHROb2RlID0gZnVuY3Rpb24gKGMpIHsgcmV0dXJuIGMudGFnIHx8IGlzQXN5bmNQbGFjZWhvbGRlcihjKTsgfTsKCiAgdmFyIGlzVlNob3dEaXJlY3RpdmUgPSBmdW5jdGlvbiAoZCkgeyByZXR1cm4gZC5uYW1lID09PSAnc2hvdyc7IH07CgogIHZhciBUcmFuc2l0aW9uID0gewogICAgbmFtZTogJ3RyYW5zaXRpb24nLAogICAgcHJvcHM6IHRyYW5zaXRpb25Qcm9wcywKICAgIGFic3RyYWN0OiB0cnVlLAoKICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyIChoKSB7CiAgICAgIHZhciB0aGlzJDEgPSB0aGlzOwoKICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy4kc2xvdHMuZGVmYXVsdDsKICAgICAgaWYgKCFjaGlsZHJlbikgewogICAgICAgIHJldHVybgogICAgICB9CgogICAgICAvLyBmaWx0ZXIgb3V0IHRleHQgbm9kZXMgKHBvc3NpYmxlIHdoaXRlc3BhY2VzKQogICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuLmZpbHRlcihpc05vdFRleHROb2RlKTsKICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICAgIGlmICghY2hpbGRyZW4ubGVuZ3RoKSB7CiAgICAgICAgcmV0dXJuCiAgICAgIH0KCiAgICAgIC8vIHdhcm4gbXVsdGlwbGUgZWxlbWVudHMKICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCA+IDEpIHsKICAgICAgICB3YXJuKAogICAgICAgICAgJzx0cmFuc2l0aW9uPiBjYW4gb25seSBiZSB1c2VkIG9uIGEgc2luZ2xlIGVsZW1lbnQuIFVzZSAnICsKICAgICAgICAgICc8dHJhbnNpdGlvbi1ncm91cD4gZm9yIGxpc3RzLicsCiAgICAgICAgICB0aGlzLiRwYXJlbnQKICAgICAgICApOwogICAgICB9CgogICAgICB2YXIgbW9kZSA9IHRoaXMubW9kZTsKCiAgICAgIC8vIHdhcm4gaW52YWxpZCBtb2RlCiAgICAgIGlmIChtb2RlICYmIG1vZGUgIT09ICdpbi1vdXQnICYmIG1vZGUgIT09ICdvdXQtaW4nCiAgICAgICkgewogICAgICAgIHdhcm4oCiAgICAgICAgICAnaW52YWxpZCA8dHJhbnNpdGlvbj4gbW9kZTogJyArIG1vZGUsCiAgICAgICAgICB0aGlzLiRwYXJlbnQKICAgICAgICApOwogICAgICB9CgogICAgICB2YXIgcmF3Q2hpbGQgPSBjaGlsZHJlblswXTsKCiAgICAgIC8vIGlmIHRoaXMgaXMgYSBjb21wb25lbnQgcm9vdCBub2RlIGFuZCB0aGUgY29tcG9uZW50J3MKICAgICAgLy8gcGFyZW50IGNvbnRhaW5lciBub2RlIGFsc28gaGFzIHRyYW5zaXRpb24sIHNraXAuCiAgICAgIGlmIChoYXNQYXJlbnRUcmFuc2l0aW9uKHRoaXMuJHZub2RlKSkgewogICAgICAgIHJldHVybiByYXdDaGlsZAogICAgICB9CgogICAgICAvLyBhcHBseSB0cmFuc2l0aW9uIGRhdGEgdG8gY2hpbGQKICAgICAgLy8gdXNlIGdldFJlYWxDaGlsZCgpIHRvIGlnbm9yZSBhYnN0cmFjdCBjb21wb25lbnRzIGUuZy4ga2VlcC1hbGl2ZQogICAgICB2YXIgY2hpbGQgPSBnZXRSZWFsQ2hpbGQocmF3Q2hpbGQpOwogICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgICAgaWYgKCFjaGlsZCkgewogICAgICAgIHJldHVybiByYXdDaGlsZAogICAgICB9CgogICAgICBpZiAodGhpcy5fbGVhdmluZykgewogICAgICAgIHJldHVybiBwbGFjZWhvbGRlcihoLCByYXdDaGlsZCkKICAgICAgfQoKICAgICAgLy8gZW5zdXJlIGEga2V5IHRoYXQgaXMgdW5pcXVlIHRvIHRoZSB2bm9kZSB0eXBlIGFuZCB0byB0aGlzIHRyYW5zaXRpb24KICAgICAgLy8gY29tcG9uZW50IGluc3RhbmNlLiBUaGlzIGtleSB3aWxsIGJlIHVzZWQgdG8gcmVtb3ZlIHBlbmRpbmcgbGVhdmluZyBub2RlcwogICAgICAvLyBkdXJpbmcgZW50ZXJpbmcuCiAgICAgIHZhciBpZCA9ICJfX3RyYW5zaXRpb24tIiArICh0aGlzLl91aWQpICsgIi0iOwogICAgICBjaGlsZC5rZXkgPSBjaGlsZC5rZXkgPT0gbnVsbAogICAgICAgID8gY2hpbGQuaXNDb21tZW50CiAgICAgICAgICA/IGlkICsgJ2NvbW1lbnQnCiAgICAgICAgICA6IGlkICsgY2hpbGQudGFnCiAgICAgICAgOiBpc1ByaW1pdGl2ZShjaGlsZC5rZXkpCiAgICAgICAgICA/IChTdHJpbmcoY2hpbGQua2V5KS5pbmRleE9mKGlkKSA9PT0gMCA/IGNoaWxkLmtleSA6IGlkICsgY2hpbGQua2V5KQogICAgICAgICAgOiBjaGlsZC5rZXk7CgogICAgICB2YXIgZGF0YSA9IChjaGlsZC5kYXRhIHx8IChjaGlsZC5kYXRhID0ge30pKS50cmFuc2l0aW9uID0gZXh0cmFjdFRyYW5zaXRpb25EYXRhKHRoaXMpOwogICAgICB2YXIgb2xkUmF3Q2hpbGQgPSB0aGlzLl92bm9kZTsKICAgICAgdmFyIG9sZENoaWxkID0gZ2V0UmVhbENoaWxkKG9sZFJhd0NoaWxkKTsKCiAgICAgIC8vIG1hcmsgdi1zaG93CiAgICAgIC8vIHNvIHRoYXQgdGhlIHRyYW5zaXRpb24gbW9kdWxlIGNhbiBoYW5kIG92ZXIgdGhlIGNvbnRyb2wgdG8gdGhlIGRpcmVjdGl2ZQogICAgICBpZiAoY2hpbGQuZGF0YS5kaXJlY3RpdmVzICYmIGNoaWxkLmRhdGEuZGlyZWN0aXZlcy5zb21lKGlzVlNob3dEaXJlY3RpdmUpKSB7CiAgICAgICAgY2hpbGQuZGF0YS5zaG93ID0gdHJ1ZTsKICAgICAgfQoKICAgICAgaWYgKAogICAgICAgIG9sZENoaWxkICYmCiAgICAgICAgb2xkQ2hpbGQuZGF0YSAmJgogICAgICAgICFpc1NhbWVDaGlsZChjaGlsZCwgb2xkQ2hpbGQpICYmCiAgICAgICAgIWlzQXN5bmNQbGFjZWhvbGRlcihvbGRDaGlsZCkgJiYKICAgICAgICAvLyAjNjY4NyBjb21wb25lbnQgcm9vdCBpcyBhIGNvbW1lbnQgbm9kZQogICAgICAgICEob2xkQ2hpbGQuY29tcG9uZW50SW5zdGFuY2UgJiYgb2xkQ2hpbGQuY29tcG9uZW50SW5zdGFuY2UuX3Zub2RlLmlzQ29tbWVudCkKICAgICAgKSB7CiAgICAgICAgLy8gcmVwbGFjZSBvbGQgY2hpbGQgdHJhbnNpdGlvbiBkYXRhIHdpdGggZnJlc2ggb25lCiAgICAgICAgLy8gaW1wb3J0YW50IGZvciBkeW5hbWljIHRyYW5zaXRpb25zIQogICAgICAgIHZhciBvbGREYXRhID0gb2xkQ2hpbGQuZGF0YS50cmFuc2l0aW9uID0gZXh0ZW5kKHt9LCBkYXRhKTsKICAgICAgICAvLyBoYW5kbGUgdHJhbnNpdGlvbiBtb2RlCiAgICAgICAgaWYgKG1vZGUgPT09ICdvdXQtaW4nKSB7CiAgICAgICAgICAvLyByZXR1cm4gcGxhY2Vob2xkZXIgbm9kZSBhbmQgcXVldWUgdXBkYXRlIHdoZW4gbGVhdmUgZmluaXNoZXMKICAgICAgICAgIHRoaXMuX2xlYXZpbmcgPSB0cnVlOwogICAgICAgICAgbWVyZ2VWTm9kZUhvb2sob2xkRGF0YSwgJ2FmdGVyTGVhdmUnLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMkMS5fbGVhdmluZyA9IGZhbHNlOwogICAgICAgICAgICB0aGlzJDEuJGZvcmNlVXBkYXRlKCk7CiAgICAgICAgICB9KTsKICAgICAgICAgIHJldHVybiBwbGFjZWhvbGRlcihoLCByYXdDaGlsZCkKICAgICAgICB9IGVsc2UgaWYgKG1vZGUgPT09ICdpbi1vdXQnKSB7CiAgICAgICAgICBpZiAoaXNBc3luY1BsYWNlaG9sZGVyKGNoaWxkKSkgewogICAgICAgICAgICByZXR1cm4gb2xkUmF3Q2hpbGQKICAgICAgICAgIH0KICAgICAgICAgIHZhciBkZWxheWVkTGVhdmU7CiAgICAgICAgICB2YXIgcGVyZm9ybUxlYXZlID0gZnVuY3Rpb24gKCkgeyBkZWxheWVkTGVhdmUoKTsgfTsKICAgICAgICAgIG1lcmdlVk5vZGVIb29rKGRhdGEsICdhZnRlckVudGVyJywgcGVyZm9ybUxlYXZlKTsKICAgICAgICAgIG1lcmdlVk5vZGVIb29rKGRhdGEsICdlbnRlckNhbmNlbGxlZCcsIHBlcmZvcm1MZWF2ZSk7CiAgICAgICAgICBtZXJnZVZOb2RlSG9vayhvbGREYXRhLCAnZGVsYXlMZWF2ZScsIGZ1bmN0aW9uIChsZWF2ZSkgeyBkZWxheWVkTGVhdmUgPSBsZWF2ZTsgfSk7CiAgICAgICAgfQogICAgICB9CgogICAgICByZXR1cm4gcmF3Q2hpbGQKICAgIH0KICB9OwoKICAvKiAgKi8KCiAgdmFyIHByb3BzID0gZXh0ZW5kKHsKICAgIHRhZzogU3RyaW5nLAogICAgbW92ZUNsYXNzOiBTdHJpbmcKICB9LCB0cmFuc2l0aW9uUHJvcHMpOwoKICBkZWxldGUgcHJvcHMubW9kZTsKCiAgdmFyIFRyYW5zaXRpb25Hcm91cCA9IHsKICAgIHByb3BzOiBwcm9wcywKCiAgICBiZWZvcmVNb3VudDogZnVuY3Rpb24gYmVmb3JlTW91bnQgKCkgewogICAgICB2YXIgdGhpcyQxID0gdGhpczsKCiAgICAgIHZhciB1cGRhdGUgPSB0aGlzLl91cGRhdGU7CiAgICAgIHRoaXMuX3VwZGF0ZSA9IGZ1bmN0aW9uICh2bm9kZSwgaHlkcmF0aW5nKSB7CiAgICAgICAgdmFyIHJlc3RvcmVBY3RpdmVJbnN0YW5jZSA9IHNldEFjdGl2ZUluc3RhbmNlKHRoaXMkMSk7CiAgICAgICAgLy8gZm9yY2UgcmVtb3ZpbmcgcGFzcwogICAgICAgIHRoaXMkMS5fX3BhdGNoX18oCiAgICAgICAgICB0aGlzJDEuX3Zub2RlLAogICAgICAgICAgdGhpcyQxLmtlcHQsCiAgICAgICAgICBmYWxzZSwgLy8gaHlkcmF0aW5nCiAgICAgICAgICB0cnVlIC8vIHJlbW92ZU9ubHkgKCFpbXBvcnRhbnQsIGF2b2lkcyB1bm5lY2Vzc2FyeSBtb3ZlcykKICAgICAgICApOwogICAgICAgIHRoaXMkMS5fdm5vZGUgPSB0aGlzJDEua2VwdDsKICAgICAgICByZXN0b3JlQWN0aXZlSW5zdGFuY2UoKTsKICAgICAgICB1cGRhdGUuY2FsbCh0aGlzJDEsIHZub2RlLCBoeWRyYXRpbmcpOwogICAgICB9OwogICAgfSwKCiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlciAoaCkgewogICAgICB2YXIgdGFnID0gdGhpcy50YWcgfHwgdGhpcy4kdm5vZGUuZGF0YS50YWcgfHwgJ3NwYW4nOwogICAgICB2YXIgbWFwID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKICAgICAgdmFyIHByZXZDaGlsZHJlbiA9IHRoaXMucHJldkNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbjsKICAgICAgdmFyIHJhd0NoaWxkcmVuID0gdGhpcy4kc2xvdHMuZGVmYXVsdCB8fCBbXTsKICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbiA9IFtdOwogICAgICB2YXIgdHJhbnNpdGlvbkRhdGEgPSBleHRyYWN0VHJhbnNpdGlvbkRhdGEodGhpcyk7CgogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhd0NoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIGMgPSByYXdDaGlsZHJlbltpXTsKICAgICAgICBpZiAoYy50YWcpIHsKICAgICAgICAgIGlmIChjLmtleSAhPSBudWxsICYmIFN0cmluZyhjLmtleSkuaW5kZXhPZignX192bGlzdCcpICE9PSAwKSB7CiAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goYyk7CiAgICAgICAgICAgIG1hcFtjLmtleV0gPSBjCiAgICAgICAgICAgIDsoYy5kYXRhIHx8IChjLmRhdGEgPSB7fSkpLnRyYW5zaXRpb24gPSB0cmFuc2l0aW9uRGF0YTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciBvcHRzID0gYy5jb21wb25lbnRPcHRpb25zOwogICAgICAgICAgICB2YXIgbmFtZSA9IG9wdHMgPyAob3B0cy5DdG9yLm9wdGlvbnMubmFtZSB8fCBvcHRzLnRhZyB8fCAnJykgOiBjLnRhZzsKICAgICAgICAgICAgd2FybigoIjx0cmFuc2l0aW9uLWdyb3VwPiBjaGlsZHJlbiBtdXN0IGJlIGtleWVkOiA8IiArIG5hbWUgKyAiPiIpKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmIChwcmV2Q2hpbGRyZW4pIHsKICAgICAgICB2YXIga2VwdCA9IFtdOwogICAgICAgIHZhciByZW1vdmVkID0gW107CiAgICAgICAgZm9yICh2YXIgaSQxID0gMDsgaSQxIDwgcHJldkNoaWxkcmVuLmxlbmd0aDsgaSQxKyspIHsKICAgICAgICAgIHZhciBjJDEgPSBwcmV2Q2hpbGRyZW5baSQxXTsKICAgICAgICAgIGMkMS5kYXRhLnRyYW5zaXRpb24gPSB0cmFuc2l0aW9uRGF0YTsKICAgICAgICAgIGMkMS5kYXRhLnBvcyA9IGMkMS5lbG0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CiAgICAgICAgICBpZiAobWFwW2MkMS5rZXldKSB7CiAgICAgICAgICAgIGtlcHQucHVzaChjJDEpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVtb3ZlZC5wdXNoKGMkMSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMua2VwdCA9IGgodGFnLCBudWxsLCBrZXB0KTsKICAgICAgICB0aGlzLnJlbW92ZWQgPSByZW1vdmVkOwogICAgICB9CgogICAgICByZXR1cm4gaCh0YWcsIG51bGwsIGNoaWxkcmVuKQogICAgfSwKCiAgICB1cGRhdGVkOiBmdW5jdGlvbiB1cGRhdGVkICgpIHsKICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5wcmV2Q2hpbGRyZW47CiAgICAgIHZhciBtb3ZlQ2xhc3MgPSB0aGlzLm1vdmVDbGFzcyB8fCAoKHRoaXMubmFtZSB8fCAndicpICsgJy1tb3ZlJyk7CiAgICAgIGlmICghY2hpbGRyZW4ubGVuZ3RoIHx8ICF0aGlzLmhhc01vdmUoY2hpbGRyZW5bMF0uZWxtLCBtb3ZlQ2xhc3MpKSB7CiAgICAgICAgcmV0dXJuCiAgICAgIH0KCiAgICAgIC8vIHdlIGRpdmlkZSB0aGUgd29yayBpbnRvIHRocmVlIGxvb3BzIHRvIGF2b2lkIG1peGluZyBET00gcmVhZHMgYW5kIHdyaXRlcwogICAgICAvLyBpbiBlYWNoIGl0ZXJhdGlvbiAtIHdoaWNoIGhlbHBzIHByZXZlbnQgbGF5b3V0IHRocmFzaGluZy4KICAgICAgY2hpbGRyZW4uZm9yRWFjaChjYWxsUGVuZGluZ0Nicyk7CiAgICAgIGNoaWxkcmVuLmZvckVhY2gocmVjb3JkUG9zaXRpb24pOwogICAgICBjaGlsZHJlbi5mb3JFYWNoKGFwcGx5VHJhbnNsYXRpb24pOwoKICAgICAgLy8gZm9yY2UgcmVmbG93IHRvIHB1dCBldmVyeXRoaW5nIGluIHBvc2l0aW9uCiAgICAgIC8vIGFzc2lnbiB0byB0aGlzIHRvIGF2b2lkIGJlaW5nIHJlbW92ZWQgaW4gdHJlZS1zaGFraW5nCiAgICAgIC8vICRmbG93LWRpc2FibGUtbGluZQogICAgICB0aGlzLl9yZWZsb3cgPSBkb2N1bWVudC5ib2R5Lm9mZnNldEhlaWdodDsKCiAgICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGMpIHsKICAgICAgICBpZiAoYy5kYXRhLm1vdmVkKSB7CiAgICAgICAgICB2YXIgZWwgPSBjLmVsbTsKICAgICAgICAgIHZhciBzID0gZWwuc3R5bGU7CiAgICAgICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIG1vdmVDbGFzcyk7CiAgICAgICAgICBzLnRyYW5zZm9ybSA9IHMuV2Via2l0VHJhbnNmb3JtID0gcy50cmFuc2l0aW9uRHVyYXRpb24gPSAnJzsKICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIodHJhbnNpdGlvbkVuZEV2ZW50LCBlbC5fbW92ZUNiID0gZnVuY3Rpb24gY2IgKGUpIHsKICAgICAgICAgICAgaWYgKGUgJiYgZS50YXJnZXQgIT09IGVsKSB7CiAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFlIHx8IC90cmFuc2Zvcm0kLy50ZXN0KGUucHJvcGVydHlOYW1lKSkgewogICAgICAgICAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIodHJhbnNpdGlvbkVuZEV2ZW50LCBjYik7CiAgICAgICAgICAgICAgZWwuX21vdmVDYiA9IG51bGw7CiAgICAgICAgICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBtb3ZlQ2xhc3MpOwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfSwKCiAgICBtZXRob2RzOiB7CiAgICAgIGhhc01vdmU6IGZ1bmN0aW9uIGhhc01vdmUgKGVsLCBtb3ZlQ2xhc3MpIHsKICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgICAgICBpZiAoIWhhc1RyYW5zaXRpb24pIHsKICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgIH0KICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgICAgICBpZiAodGhpcy5faGFzTW92ZSkgewogICAgICAgICAgcmV0dXJuIHRoaXMuX2hhc01vdmUKICAgICAgICB9CiAgICAgICAgLy8gRGV0ZWN0IHdoZXRoZXIgYW4gZWxlbWVudCB3aXRoIHRoZSBtb3ZlIGNsYXNzIGFwcGxpZWQgaGFzCiAgICAgICAgLy8gQ1NTIHRyYW5zaXRpb25zLiBTaW5jZSB0aGUgZWxlbWVudCBtYXkgYmUgaW5zaWRlIGFuIGVudGVyaW5nCiAgICAgICAgLy8gdHJhbnNpdGlvbiBhdCB0aGlzIHZlcnkgbW9tZW50LCB3ZSBtYWtlIGEgY2xvbmUgb2YgaXQgYW5kIHJlbW92ZQogICAgICAgIC8vIGFsbCBvdGhlciB0cmFuc2l0aW9uIGNsYXNzZXMgYXBwbGllZCB0byBlbnN1cmUgb25seSB0aGUgbW92ZSBjbGFzcwogICAgICAgIC8vIGlzIGFwcGxpZWQuCiAgICAgICAgdmFyIGNsb25lID0gZWwuY2xvbmVOb2RlKCk7CiAgICAgICAgaWYgKGVsLl90cmFuc2l0aW9uQ2xhc3NlcykgewogICAgICAgICAgZWwuX3RyYW5zaXRpb25DbGFzc2VzLmZvckVhY2goZnVuY3Rpb24gKGNscykgeyByZW1vdmVDbGFzcyhjbG9uZSwgY2xzKTsgfSk7CiAgICAgICAgfQogICAgICAgIGFkZENsYXNzKGNsb25lLCBtb3ZlQ2xhc3MpOwogICAgICAgIGNsb25lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAgICAgdGhpcy4kZWwuYXBwZW5kQ2hpbGQoY2xvbmUpOwogICAgICAgIHZhciBpbmZvID0gZ2V0VHJhbnNpdGlvbkluZm8oY2xvbmUpOwogICAgICAgIHRoaXMuJGVsLnJlbW92ZUNoaWxkKGNsb25lKTsKICAgICAgICByZXR1cm4gKHRoaXMuX2hhc01vdmUgPSBpbmZvLmhhc1RyYW5zZm9ybSkKICAgICAgfQogICAgfQogIH07CgogIGZ1bmN0aW9uIGNhbGxQZW5kaW5nQ2JzIChjKSB7CiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgIGlmIChjLmVsbS5fbW92ZUNiKSB7CiAgICAgIGMuZWxtLl9tb3ZlQ2IoKTsKICAgIH0KICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgaWYgKGMuZWxtLl9lbnRlckNiKSB7CiAgICAgIGMuZWxtLl9lbnRlckNiKCk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiByZWNvcmRQb3NpdGlvbiAoYykgewogICAgYy5kYXRhLm5ld1BvcyA9IGMuZWxtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogIH0KCiAgZnVuY3Rpb24gYXBwbHlUcmFuc2xhdGlvbiAoYykgewogICAgdmFyIG9sZFBvcyA9IGMuZGF0YS5wb3M7CiAgICB2YXIgbmV3UG9zID0gYy5kYXRhLm5ld1BvczsKICAgIHZhciBkeCA9IG9sZFBvcy5sZWZ0IC0gbmV3UG9zLmxlZnQ7CiAgICB2YXIgZHkgPSBvbGRQb3MudG9wIC0gbmV3UG9zLnRvcDsKICAgIGlmIChkeCB8fCBkeSkgewogICAgICBjLmRhdGEubW92ZWQgPSB0cnVlOwogICAgICB2YXIgcyA9IGMuZWxtLnN0eWxlOwogICAgICBzLnRyYW5zZm9ybSA9IHMuV2Via2l0VHJhbnNmb3JtID0gInRyYW5zbGF0ZSgiICsgZHggKyAicHgsIiArIGR5ICsgInB4KSI7CiAgICAgIHMudHJhbnNpdGlvbkR1cmF0aW9uID0gJzBzJzsKICAgIH0KICB9CgogIHZhciBwbGF0Zm9ybUNvbXBvbmVudHMgPSB7CiAgICBUcmFuc2l0aW9uOiBUcmFuc2l0aW9uLAogICAgVHJhbnNpdGlvbkdyb3VwOiBUcmFuc2l0aW9uR3JvdXAKICB9OwoKICAvKiAgKi8KCiAgLy8gaW5zdGFsbCBwbGF0Zm9ybSBzcGVjaWZpYyB1dGlscwogIFZ1ZS5jb25maWcubXVzdFVzZVByb3AgPSBtdXN0VXNlUHJvcDsKICBWdWUuY29uZmlnLmlzUmVzZXJ2ZWRUYWcgPSBpc1Jlc2VydmVkVGFnOwogIFZ1ZS5jb25maWcuaXNSZXNlcnZlZEF0dHIgPSBpc1Jlc2VydmVkQXR0cjsKICBWdWUuY29uZmlnLmdldFRhZ05hbWVzcGFjZSA9IGdldFRhZ05hbWVzcGFjZTsKICBWdWUuY29uZmlnLmlzVW5rbm93bkVsZW1lbnQgPSBpc1Vua25vd25FbGVtZW50OwoKICAvLyBpbnN0YWxsIHBsYXRmb3JtIHJ1bnRpbWUgZGlyZWN0aXZlcyAmIGNvbXBvbmVudHMKICBleHRlbmQoVnVlLm9wdGlvbnMuZGlyZWN0aXZlcywgcGxhdGZvcm1EaXJlY3RpdmVzKTsKICBleHRlbmQoVnVlLm9wdGlvbnMuY29tcG9uZW50cywgcGxhdGZvcm1Db21wb25lbnRzKTsKCiAgLy8gaW5zdGFsbCBwbGF0Zm9ybSBwYXRjaCBmdW5jdGlvbgogIFZ1ZS5wcm90b3R5cGUuX19wYXRjaF9fID0gaW5Ccm93c2VyID8gcGF0Y2ggOiBub29wOwoKICAvLyBwdWJsaWMgbW91bnQgbWV0aG9kCiAgVnVlLnByb3RvdHlwZS4kbW91bnQgPSBmdW5jdGlvbiAoCiAgICBlbCwKICAgIGh5ZHJhdGluZwogICkgewogICAgZWwgPSBlbCAmJiBpbkJyb3dzZXIgPyBxdWVyeShlbCkgOiB1bmRlZmluZWQ7CiAgICByZXR1cm4gbW91bnRDb21wb25lbnQodGhpcywgZWwsIGh5ZHJhdGluZykKICB9OwoKICAvLyBkZXZ0b29scyBnbG9iYWwgaG9vawogIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovCiAgaWYgKGluQnJvd3NlcikgewogICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgIGlmIChjb25maWcuZGV2dG9vbHMpIHsKICAgICAgICBpZiAoZGV2dG9vbHMpIHsKICAgICAgICAgIGRldnRvb2xzLmVtaXQoJ2luaXQnLCBWdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjb25zb2xlW2NvbnNvbGUuaW5mbyA/ICdpbmZvJyA6ICdsb2cnXSgKICAgICAgICAgICAgJ0Rvd25sb2FkIHRoZSBWdWUgRGV2dG9vbHMgZXh0ZW5zaW9uIGZvciBhIGJldHRlciBkZXZlbG9wbWVudCBleHBlcmllbmNlOlxuJyArCiAgICAgICAgICAgICdodHRwczovL2dpdGh1Yi5jb20vdnVlanMvdnVlLWRldnRvb2xzJwogICAgICAgICAgKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGNvbmZpZy5wcm9kdWN0aW9uVGlwICE9PSBmYWxzZSAmJgogICAgICAgIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJwogICAgICApIHsKICAgICAgICBjb25zb2xlW2NvbnNvbGUuaW5mbyA/ICdpbmZvJyA6ICdsb2cnXSgKICAgICAgICAgICJZb3UgYXJlIHJ1bm5pbmcgVnVlIGluIGRldmVsb3BtZW50IG1vZGUuXG4iICsKICAgICAgICAgICJNYWtlIHN1cmUgdG8gdHVybiBvbiBwcm9kdWN0aW9uIG1vZGUgd2hlbiBkZXBsb3lpbmcgZm9yIHByb2R1Y3Rpb24uXG4iICsKICAgICAgICAgICJTZWUgbW9yZSB0aXBzIGF0IGh0dHBzOi8vdnVlanMub3JnL2d1aWRlL2RlcGxveW1lbnQuaHRtbCIKICAgICAgICApOwogICAgICB9CiAgICB9LCAwKTsKICB9CgogIC8qICAqLwoKICB2YXIgZGVmYXVsdFRhZ1JFID0gL1x7XHsoKD86Lnxccj9cbikrPylcfVx9L2c7CiAgdmFyIHJlZ2V4RXNjYXBlUkUgPSAvWy0uKis/XiR7fSgpfFtcXVwvXFxdL2c7CgogIHZhciBidWlsZFJlZ2V4ID0gY2FjaGVkKGZ1bmN0aW9uIChkZWxpbWl0ZXJzKSB7CiAgICB2YXIgb3BlbiA9IGRlbGltaXRlcnNbMF0ucmVwbGFjZShyZWdleEVzY2FwZVJFLCAnXFwkJicpOwogICAgdmFyIGNsb3NlID0gZGVsaW1pdGVyc1sxXS5yZXBsYWNlKHJlZ2V4RXNjYXBlUkUsICdcXCQmJyk7CiAgICByZXR1cm4gbmV3IFJlZ0V4cChvcGVuICsgJygoPzoufFxcbikrPyknICsgY2xvc2UsICdnJykKICB9KTsKCgoKICBmdW5jdGlvbiBwYXJzZVRleHQgKAogICAgdGV4dCwKICAgIGRlbGltaXRlcnMKICApIHsKICAgIHZhciB0YWdSRSA9IGRlbGltaXRlcnMgPyBidWlsZFJlZ2V4KGRlbGltaXRlcnMpIDogZGVmYXVsdFRhZ1JFOwogICAgaWYgKCF0YWdSRS50ZXN0KHRleHQpKSB7CiAgICAgIHJldHVybgogICAgfQogICAgdmFyIHRva2VucyA9IFtdOwogICAgdmFyIHJhd1Rva2VucyA9IFtdOwogICAgdmFyIGxhc3RJbmRleCA9IHRhZ1JFLmxhc3RJbmRleCA9IDA7CiAgICB2YXIgbWF0Y2gsIGluZGV4LCB0b2tlblZhbHVlOwogICAgd2hpbGUgKChtYXRjaCA9IHRhZ1JFLmV4ZWModGV4dCkpKSB7CiAgICAgIGluZGV4ID0gbWF0Y2guaW5kZXg7CiAgICAgIC8vIHB1c2ggdGV4dCB0b2tlbgogICAgICBpZiAoaW5kZXggPiBsYXN0SW5kZXgpIHsKICAgICAgICByYXdUb2tlbnMucHVzaCh0b2tlblZhbHVlID0gdGV4dC5zbGljZShsYXN0SW5kZXgsIGluZGV4KSk7CiAgICAgICAgdG9rZW5zLnB1c2goSlNPTi5zdHJpbmdpZnkodG9rZW5WYWx1ZSkpOwogICAgICB9CiAgICAgIC8vIHRhZyB0b2tlbgogICAgICB2YXIgZXhwID0gcGFyc2VGaWx0ZXJzKG1hdGNoWzFdLnRyaW0oKSk7CiAgICAgIHRva2Vucy5wdXNoKCgiX3MoIiArIGV4cCArICIpIikpOwogICAgICByYXdUb2tlbnMucHVzaCh7ICdAYmluZGluZyc6IGV4cCB9KTsKICAgICAgbGFzdEluZGV4ID0gaW5kZXggKyBtYXRjaFswXS5sZW5ndGg7CiAgICB9CiAgICBpZiAobGFzdEluZGV4IDwgdGV4dC5sZW5ndGgpIHsKICAgICAgcmF3VG9rZW5zLnB1c2godG9rZW5WYWx1ZSA9IHRleHQuc2xpY2UobGFzdEluZGV4KSk7CiAgICAgIHRva2Vucy5wdXNoKEpTT04uc3RyaW5naWZ5KHRva2VuVmFsdWUpKTsKICAgIH0KICAgIHJldHVybiB7CiAgICAgIGV4cHJlc3Npb246IHRva2Vucy5qb2luKCcrJyksCiAgICAgIHRva2VuczogcmF3VG9rZW5zCiAgICB9CiAgfQoKICAvKiAgKi8KCiAgZnVuY3Rpb24gdHJhbnNmb3JtTm9kZSAoZWwsIG9wdGlvbnMpIHsKICAgIHZhciB3YXJuID0gb3B0aW9ucy53YXJuIHx8IGJhc2VXYXJuOwogICAgdmFyIHN0YXRpY0NsYXNzID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ2NsYXNzJyk7CiAgICBpZiAoc3RhdGljQ2xhc3MpIHsKICAgICAgdmFyIHJlcyA9IHBhcnNlVGV4dChzdGF0aWNDbGFzcywgb3B0aW9ucy5kZWxpbWl0ZXJzKTsKICAgICAgaWYgKHJlcykgewogICAgICAgIHdhcm4oCiAgICAgICAgICAiY2xhc3M9XCIiICsgc3RhdGljQ2xhc3MgKyAiXCI6ICIgKwogICAgICAgICAgJ0ludGVycG9sYXRpb24gaW5zaWRlIGF0dHJpYnV0ZXMgaGFzIGJlZW4gcmVtb3ZlZC4gJyArCiAgICAgICAgICAnVXNlIHYtYmluZCBvciB0aGUgY29sb24gc2hvcnRoYW5kIGluc3RlYWQuIEZvciBleGFtcGxlLCAnICsKICAgICAgICAgICdpbnN0ZWFkIG9mIDxkaXYgY2xhc3M9Int7IHZhbCB9fSI+LCB1c2UgPGRpdiA6Y2xhc3M9InZhbCI+LicsCiAgICAgICAgICBlbC5yYXdBdHRyc01hcFsnY2xhc3MnXQogICAgICAgICk7CiAgICAgIH0KICAgIH0KICAgIGlmIChzdGF0aWNDbGFzcykgewogICAgICBlbC5zdGF0aWNDbGFzcyA9IEpTT04uc3RyaW5naWZ5KHN0YXRpY0NsYXNzKTsKICAgIH0KICAgIHZhciBjbGFzc0JpbmRpbmcgPSBnZXRCaW5kaW5nQXR0cihlbCwgJ2NsYXNzJywgZmFsc2UgLyogZ2V0U3RhdGljICovKTsKICAgIGlmIChjbGFzc0JpbmRpbmcpIHsKICAgICAgZWwuY2xhc3NCaW5kaW5nID0gY2xhc3NCaW5kaW5nOwogICAgfQogIH0KCiAgZnVuY3Rpb24gZ2VuRGF0YSAoZWwpIHsKICAgIHZhciBkYXRhID0gJyc7CiAgICBpZiAoZWwuc3RhdGljQ2xhc3MpIHsKICAgICAgZGF0YSArPSAic3RhdGljQ2xhc3M6IiArIChlbC5zdGF0aWNDbGFzcykgKyAiLCI7CiAgICB9CiAgICBpZiAoZWwuY2xhc3NCaW5kaW5nKSB7CiAgICAgIGRhdGEgKz0gImNsYXNzOiIgKyAoZWwuY2xhc3NCaW5kaW5nKSArICIsIjsKICAgIH0KICAgIHJldHVybiBkYXRhCiAgfQoKICB2YXIga2xhc3MkMSA9IHsKICAgIHN0YXRpY0tleXM6IFsnc3RhdGljQ2xhc3MnXSwKICAgIHRyYW5zZm9ybU5vZGU6IHRyYW5zZm9ybU5vZGUsCiAgICBnZW5EYXRhOiBnZW5EYXRhCiAgfTsKCiAgLyogICovCgogIGZ1bmN0aW9uIHRyYW5zZm9ybU5vZGUkMSAoZWwsIG9wdGlvbnMpIHsKICAgIHZhciB3YXJuID0gb3B0aW9ucy53YXJuIHx8IGJhc2VXYXJuOwogICAgdmFyIHN0YXRpY1N0eWxlID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3N0eWxlJyk7CiAgICBpZiAoc3RhdGljU3R5bGUpIHsKICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICAgIHsKICAgICAgICB2YXIgcmVzID0gcGFyc2VUZXh0KHN0YXRpY1N0eWxlLCBvcHRpb25zLmRlbGltaXRlcnMpOwogICAgICAgIGlmIChyZXMpIHsKICAgICAgICAgIHdhcm4oCiAgICAgICAgICAgICJzdHlsZT1cIiIgKyBzdGF0aWNTdHlsZSArICJcIjogIiArCiAgICAgICAgICAgICdJbnRlcnBvbGF0aW9uIGluc2lkZSBhdHRyaWJ1dGVzIGhhcyBiZWVuIHJlbW92ZWQuICcgKwogICAgICAgICAgICAnVXNlIHYtYmluZCBvciB0aGUgY29sb24gc2hvcnRoYW5kIGluc3RlYWQuIEZvciBleGFtcGxlLCAnICsKICAgICAgICAgICAgJ2luc3RlYWQgb2YgPGRpdiBzdHlsZT0ie3sgdmFsIH19Ij4sIHVzZSA8ZGl2IDpzdHlsZT0idmFsIj4uJywKICAgICAgICAgICAgZWwucmF3QXR0cnNNYXBbJ3N0eWxlJ10KICAgICAgICAgICk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGVsLnN0YXRpY1N0eWxlID0gSlNPTi5zdHJpbmdpZnkocGFyc2VTdHlsZVRleHQoc3RhdGljU3R5bGUpKTsKICAgIH0KCiAgICB2YXIgc3R5bGVCaW5kaW5nID0gZ2V0QmluZGluZ0F0dHIoZWwsICdzdHlsZScsIGZhbHNlIC8qIGdldFN0YXRpYyAqLyk7CiAgICBpZiAoc3R5bGVCaW5kaW5nKSB7CiAgICAgIGVsLnN0eWxlQmluZGluZyA9IHN0eWxlQmluZGluZzsKICAgIH0KICB9CgogIGZ1bmN0aW9uIGdlbkRhdGEkMSAoZWwpIHsKICAgIHZhciBkYXRhID0gJyc7CiAgICBpZiAoZWwuc3RhdGljU3R5bGUpIHsKICAgICAgZGF0YSArPSAic3RhdGljU3R5bGU6IiArIChlbC5zdGF0aWNTdHlsZSkgKyAiLCI7CiAgICB9CiAgICBpZiAoZWwuc3R5bGVCaW5kaW5nKSB7CiAgICAgIGRhdGEgKz0gInN0eWxlOigiICsgKGVsLnN0eWxlQmluZGluZykgKyAiKSwiOwogICAgfQogICAgcmV0dXJuIGRhdGEKICB9CgogIHZhciBzdHlsZSQxID0gewogICAgc3RhdGljS2V5czogWydzdGF0aWNTdHlsZSddLAogICAgdHJhbnNmb3JtTm9kZTogdHJhbnNmb3JtTm9kZSQxLAogICAgZ2VuRGF0YTogZ2VuRGF0YSQxCiAgfTsKCiAgLyogICovCgogIHZhciBkZWNvZGVyOwoKICB2YXIgaGUgPSB7CiAgICBkZWNvZGU6IGZ1bmN0aW9uIGRlY29kZSAoaHRtbCkgewogICAgICBkZWNvZGVyID0gZGVjb2RlciB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgICAgZGVjb2Rlci5pbm5lckhUTUwgPSBodG1sOwogICAgICByZXR1cm4gZGVjb2Rlci50ZXh0Q29udGVudAogICAgfQogIH07CgogIC8qICAqLwoKICB2YXIgaXNVbmFyeVRhZyA9IG1ha2VNYXAoCiAgICAnYXJlYSxiYXNlLGJyLGNvbCxlbWJlZCxmcmFtZSxocixpbWcsaW5wdXQsaXNpbmRleCxrZXlnZW4sJyArCiAgICAnbGluayxtZXRhLHBhcmFtLHNvdXJjZSx0cmFjayx3YnInCiAgKTsKCiAgLy8gRWxlbWVudHMgdGhhdCB5b3UgY2FuLCBpbnRlbnRpb25hbGx5LCBsZWF2ZSBvcGVuCiAgLy8gKGFuZCB3aGljaCBjbG9zZSB0aGVtc2VsdmVzKQogIHZhciBjYW5CZUxlZnRPcGVuVGFnID0gbWFrZU1hcCgKICAgICdjb2xncm91cCxkZCxkdCxsaSxvcHRpb25zLHAsdGQsdGZvb3QsdGgsdGhlYWQsdHIsc291cmNlJwogICk7CgogIC8vIEhUTUw1IHRhZ3MgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvaW5kaWNlcy5odG1sI2VsZW1lbnRzLTMKICAvLyBQaHJhc2luZyBDb250ZW50IGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2RvbS5odG1sI3BocmFzaW5nLWNvbnRlbnQKICB2YXIgaXNOb25QaHJhc2luZ1RhZyA9IG1ha2VNYXAoCiAgICAnYWRkcmVzcyxhcnRpY2xlLGFzaWRlLGJhc2UsYmxvY2txdW90ZSxib2R5LGNhcHRpb24sY29sLGNvbGdyb3VwLGRkLCcgKwogICAgJ2RldGFpbHMsZGlhbG9nLGRpdixkbCxkdCxmaWVsZHNldCxmaWdjYXB0aW9uLGZpZ3VyZSxmb290ZXIsZm9ybSwnICsKICAgICdoMSxoMixoMyxoNCxoNSxoNixoZWFkLGhlYWRlcixoZ3JvdXAsaHIsaHRtbCxsZWdlbmQsbGksbWVudWl0ZW0sbWV0YSwnICsKICAgICdvcHRncm91cCxvcHRpb24scGFyYW0scnAscnQsc291cmNlLHN0eWxlLHN1bW1hcnksdGJvZHksdGQsdGZvb3QsdGgsdGhlYWQsJyArCiAgICAndGl0bGUsdHIsdHJhY2snCiAgKTsKCiAgLyoqCiAgICogTm90IHR5cGUtY2hlY2tpbmcgdGhpcyBmaWxlIGJlY2F1c2UgaXQncyBtb3N0bHkgdmVuZG9yIGNvZGUuCiAgICovCgogIC8vIFJlZ3VsYXIgRXhwcmVzc2lvbnMgZm9yIHBhcnNpbmcgdGFncyBhbmQgYXR0cmlidXRlcwogIHZhciBhdHRyaWJ1dGUgPSAvXlxzKihbXlxzIic8PlwvPV0rKSg/OlxzKig9KVxzKig/OiIoW14iXSopIit8JyhbXiddKiknK3woW15ccyInPTw+YF0rKSkpPy87CiAgdmFyIGR5bmFtaWNBcmdBdHRyaWJ1dGUgPSAvXlxzKigoPzp2LVtcdy1dKzp8QHw6fCMpXFtbXj1dK1xdW15ccyInPD5cLz1dKikoPzpccyooPSlccyooPzoiKFteIl0qKSIrfCcoW14nXSopJyt8KFteXHMiJz08PmBdKykpKT8vOwogIHZhciBuY25hbWUgPSAiW2EtekEtWl9dW1xcLVxcLjAtOV9hLXpBLVoiICsgKHVuaWNvZGVSZWdFeHAuc291cmNlKSArICJdKiI7CiAgdmFyIHFuYW1lQ2FwdHVyZSA9ICIoKD86IiArIG5jbmFtZSArICJcXDopPyIgKyBuY25hbWUgKyAiKSI7CiAgdmFyIHN0YXJ0VGFnT3BlbiA9IG5ldyBSZWdFeHAoKCJePCIgKyBxbmFtZUNhcHR1cmUpKTsKICB2YXIgc3RhcnRUYWdDbG9zZSA9IC9eXHMqKFwvPyk+LzsKICB2YXIgZW5kVGFnID0gbmV3IFJlZ0V4cCgoIl48XFwvIiArIHFuYW1lQ2FwdHVyZSArICJbXj5dKj4iKSk7CiAgdmFyIGRvY3R5cGUgPSAvXjwhRE9DVFlQRSBbXj5dKz4vaTsKICAvLyAjNzI5ODogZXNjYXBlIC0gdG8gYXZvaWQgYmVpbmcgcGFzZWQgYXMgSFRNTCBjb21tZW50IHdoZW4gaW5saW5lZCBpbiBwYWdlCiAgdmFyIGNvbW1lbnQgPSAvXjwhXC0tLzsKICB2YXIgY29uZGl0aW9uYWxDb21tZW50ID0gL148IVxbLzsKCiAgLy8gU3BlY2lhbCBFbGVtZW50cyAoY2FuIGNvbnRhaW4gYW55dGhpbmcpCiAgdmFyIGlzUGxhaW5UZXh0RWxlbWVudCA9IG1ha2VNYXAoJ3NjcmlwdCxzdHlsZSx0ZXh0YXJlYScsIHRydWUpOwogIHZhciByZUNhY2hlID0ge307CgogIHZhciBkZWNvZGluZ01hcCA9IHsKICAgICcmbHQ7JzogJzwnLAogICAgJyZndDsnOiAnPicsCiAgICAnJnF1b3Q7JzogJyInLAogICAgJyZhbXA7JzogJyYnLAogICAgJyYjMTA7JzogJ1xuJywKICAgICcmIzk7JzogJ1x0JywKICAgICcmIzM5Oyc6ICInIgogIH07CiAgdmFyIGVuY29kZWRBdHRyID0gLyYoPzpsdHxndHxxdW90fGFtcHwjMzkpOy9nOwogIHZhciBlbmNvZGVkQXR0cldpdGhOZXdMaW5lcyA9IC8mKD86bHR8Z3R8cXVvdHxhbXB8IzM5fCMxMHwjOSk7L2c7CgogIC8vICM1OTkyCiAgdmFyIGlzSWdub3JlTmV3bGluZVRhZyA9IG1ha2VNYXAoJ3ByZSx0ZXh0YXJlYScsIHRydWUpOwogIHZhciBzaG91bGRJZ25vcmVGaXJzdE5ld2xpbmUgPSBmdW5jdGlvbiAodGFnLCBodG1sKSB7IHJldHVybiB0YWcgJiYgaXNJZ25vcmVOZXdsaW5lVGFnKHRhZykgJiYgaHRtbFswXSA9PT0gJ1xuJzsgfTsKCiAgZnVuY3Rpb24gZGVjb2RlQXR0ciAodmFsdWUsIHNob3VsZERlY29kZU5ld2xpbmVzKSB7CiAgICB2YXIgcmUgPSBzaG91bGREZWNvZGVOZXdsaW5lcyA/IGVuY29kZWRBdHRyV2l0aE5ld0xpbmVzIDogZW5jb2RlZEF0dHI7CiAgICByZXR1cm4gdmFsdWUucmVwbGFjZShyZSwgZnVuY3Rpb24gKG1hdGNoKSB7IHJldHVybiBkZWNvZGluZ01hcFttYXRjaF07IH0pCiAgfQoKICBmdW5jdGlvbiBwYXJzZUhUTUwgKGh0bWwsIG9wdGlvbnMpIHsKICAgIHZhciBzdGFjayA9IFtdOwogICAgdmFyIGV4cGVjdEhUTUwgPSBvcHRpb25zLmV4cGVjdEhUTUw7CiAgICB2YXIgaXNVbmFyeVRhZyQkMSA9IG9wdGlvbnMuaXNVbmFyeVRhZyB8fCBubzsKICAgIHZhciBjYW5CZUxlZnRPcGVuVGFnJCQxID0gb3B0aW9ucy5jYW5CZUxlZnRPcGVuVGFnIHx8IG5vOwogICAgdmFyIGluZGV4ID0gMDsKICAgIHZhciBsYXN0LCBsYXN0VGFnOwogICAgd2hpbGUgKGh0bWwpIHsKICAgICAgbGFzdCA9IGh0bWw7CiAgICAgIC8vIE1ha2Ugc3VyZSB3ZSdyZSBub3QgaW4gYSBwbGFpbnRleHQgY29udGVudCBlbGVtZW50IGxpa2Ugc2NyaXB0L3N0eWxlCiAgICAgIGlmICghbGFzdFRhZyB8fCAhaXNQbGFpblRleHRFbGVtZW50KGxhc3RUYWcpKSB7CiAgICAgICAgdmFyIHRleHRFbmQgPSBodG1sLmluZGV4T2YoJzwnKTsKICAgICAgICBpZiAodGV4dEVuZCA9PT0gMCkgewogICAgICAgICAgLy8gQ29tbWVudDoKICAgICAgICAgIGlmIChjb21tZW50LnRlc3QoaHRtbCkpIHsKICAgICAgICAgICAgdmFyIGNvbW1lbnRFbmQgPSBodG1sLmluZGV4T2YoJy0tPicpOwoKICAgICAgICAgICAgaWYgKGNvbW1lbnRFbmQgPj0gMCkgewogICAgICAgICAgICAgIGlmIChvcHRpb25zLnNob3VsZEtlZXBDb21tZW50KSB7CiAgICAgICAgICAgICAgICBvcHRpb25zLmNvbW1lbnQoaHRtbC5zdWJzdHJpbmcoNCwgY29tbWVudEVuZCksIGluZGV4LCBpbmRleCArIGNvbW1lbnRFbmQgKyAzKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYWR2YW5jZShjb21tZW50RW5kICsgMyk7CiAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIC8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29uZGl0aW9uYWxfY29tbWVudCNEb3dubGV2ZWwtcmV2ZWFsZWRfY29uZGl0aW9uYWxfY29tbWVudAogICAgICAgICAgaWYgKGNvbmRpdGlvbmFsQ29tbWVudC50ZXN0KGh0bWwpKSB7CiAgICAgICAgICAgIHZhciBjb25kaXRpb25hbEVuZCA9IGh0bWwuaW5kZXhPZignXT4nKTsKCiAgICAgICAgICAgIGlmIChjb25kaXRpb25hbEVuZCA+PSAwKSB7CiAgICAgICAgICAgICAgYWR2YW5jZShjb25kaXRpb25hbEVuZCArIDIpOwogICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICAvLyBEb2N0eXBlOgogICAgICAgICAgdmFyIGRvY3R5cGVNYXRjaCA9IGh0bWwubWF0Y2goZG9jdHlwZSk7CiAgICAgICAgICBpZiAoZG9jdHlwZU1hdGNoKSB7CiAgICAgICAgICAgIGFkdmFuY2UoZG9jdHlwZU1hdGNoWzBdLmxlbmd0aCk7CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICB9CgogICAgICAgICAgLy8gRW5kIHRhZzoKICAgICAgICAgIHZhciBlbmRUYWdNYXRjaCA9IGh0bWwubWF0Y2goZW5kVGFnKTsKICAgICAgICAgIGlmIChlbmRUYWdNYXRjaCkgewogICAgICAgICAgICB2YXIgY3VySW5kZXggPSBpbmRleDsKICAgICAgICAgICAgYWR2YW5jZShlbmRUYWdNYXRjaFswXS5sZW5ndGgpOwogICAgICAgICAgICBwYXJzZUVuZFRhZyhlbmRUYWdNYXRjaFsxXSwgY3VySW5kZXgsIGluZGV4KTsKICAgICAgICAgICAgY29udGludWUKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBTdGFydCB0YWc6CiAgICAgICAgICB2YXIgc3RhcnRUYWdNYXRjaCA9IHBhcnNlU3RhcnRUYWcoKTsKICAgICAgICAgIGlmIChzdGFydFRhZ01hdGNoKSB7CiAgICAgICAgICAgIGhhbmRsZVN0YXJ0VGFnKHN0YXJ0VGFnTWF0Y2gpOwogICAgICAgICAgICBpZiAoc2hvdWxkSWdub3JlRmlyc3ROZXdsaW5lKHN0YXJ0VGFnTWF0Y2gudGFnTmFtZSwgaHRtbCkpIHsKICAgICAgICAgICAgICBhZHZhbmNlKDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB2YXIgdGV4dCA9ICh2b2lkIDApLCByZXN0ID0gKHZvaWQgMCksIG5leHQgPSAodm9pZCAwKTsKICAgICAgICBpZiAodGV4dEVuZCA+PSAwKSB7CiAgICAgICAgICByZXN0ID0gaHRtbC5zbGljZSh0ZXh0RW5kKTsKICAgICAgICAgIHdoaWxlICgKICAgICAgICAgICAgIWVuZFRhZy50ZXN0KHJlc3QpICYmCiAgICAgICAgICAgICFzdGFydFRhZ09wZW4udGVzdChyZXN0KSAmJgogICAgICAgICAgICAhY29tbWVudC50ZXN0KHJlc3QpICYmCiAgICAgICAgICAgICFjb25kaXRpb25hbENvbW1lbnQudGVzdChyZXN0KQogICAgICAgICAgKSB7CiAgICAgICAgICAgIC8vIDwgaW4gcGxhaW4gdGV4dCwgYmUgZm9yZ2l2aW5nIGFuZCB0cmVhdCBpdCBhcyB0ZXh0CiAgICAgICAgICAgIG5leHQgPSByZXN0LmluZGV4T2YoJzwnLCAxKTsKICAgICAgICAgICAgaWYgKG5leHQgPCAwKSB7IGJyZWFrIH0KICAgICAgICAgICAgdGV4dEVuZCArPSBuZXh0OwogICAgICAgICAgICByZXN0ID0gaHRtbC5zbGljZSh0ZXh0RW5kKTsKICAgICAgICAgIH0KICAgICAgICAgIHRleHQgPSBodG1sLnN1YnN0cmluZygwLCB0ZXh0RW5kKTsKICAgICAgICB9CgogICAgICAgIGlmICh0ZXh0RW5kIDwgMCkgewogICAgICAgICAgdGV4dCA9IGh0bWw7CiAgICAgICAgfQoKICAgICAgICBpZiAodGV4dCkgewogICAgICAgICAgYWR2YW5jZSh0ZXh0Lmxlbmd0aCk7CiAgICAgICAgfQoKICAgICAgICBpZiAob3B0aW9ucy5jaGFycyAmJiB0ZXh0KSB7CiAgICAgICAgICBvcHRpb25zLmNoYXJzKHRleHQsIGluZGV4IC0gdGV4dC5sZW5ndGgsIGluZGV4KTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmFyIGVuZFRhZ0xlbmd0aCA9IDA7CiAgICAgICAgdmFyIHN0YWNrZWRUYWcgPSBsYXN0VGFnLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgdmFyIHJlU3RhY2tlZFRhZyA9IHJlQ2FjaGVbc3RhY2tlZFRhZ10gfHwgKHJlQ2FjaGVbc3RhY2tlZFRhZ10gPSBuZXcgUmVnRXhwKCcoW1xcc1xcU10qPykoPC8nICsgc3RhY2tlZFRhZyArICdbXj5dKj4pJywgJ2knKSk7CiAgICAgICAgdmFyIHJlc3QkMSA9IGh0bWwucmVwbGFjZShyZVN0YWNrZWRUYWcsIGZ1bmN0aW9uIChhbGwsIHRleHQsIGVuZFRhZykgewogICAgICAgICAgZW5kVGFnTGVuZ3RoID0gZW5kVGFnLmxlbmd0aDsKICAgICAgICAgIGlmICghaXNQbGFpblRleHRFbGVtZW50KHN0YWNrZWRUYWcpICYmIHN0YWNrZWRUYWcgIT09ICdub3NjcmlwdCcpIHsKICAgICAgICAgICAgdGV4dCA9IHRleHQKICAgICAgICAgICAgICAucmVwbGFjZSgvPCFcLS0oW1xzXFNdKj8pLS0+L2csICckMScpIC8vICM3Mjk4CiAgICAgICAgICAgICAgLnJlcGxhY2UoLzwhXFtDREFUQVxbKFtcc1xTXSo/KV1dPi9nLCAnJDEnKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChzaG91bGRJZ25vcmVGaXJzdE5ld2xpbmUoc3RhY2tlZFRhZywgdGV4dCkpIHsKICAgICAgICAgICAgdGV4dCA9IHRleHQuc2xpY2UoMSk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAob3B0aW9ucy5jaGFycykgewogICAgICAgICAgICBvcHRpb25zLmNoYXJzKHRleHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuICcnCiAgICAgICAgfSk7CiAgICAgICAgaW5kZXggKz0gaHRtbC5sZW5ndGggLSByZXN0JDEubGVuZ3RoOwogICAgICAgIGh0bWwgPSByZXN0JDE7CiAgICAgICAgcGFyc2VFbmRUYWcoc3RhY2tlZFRhZywgaW5kZXggLSBlbmRUYWdMZW5ndGgsIGluZGV4KTsKICAgICAgfQoKICAgICAgaWYgKGh0bWwgPT09IGxhc3QpIHsKICAgICAgICBvcHRpb25zLmNoYXJzICYmIG9wdGlvbnMuY2hhcnMoaHRtbCk7CiAgICAgICAgaWYgKCFzdGFjay5sZW5ndGggJiYgb3B0aW9ucy53YXJuKSB7CiAgICAgICAgICBvcHRpb25zLndhcm4oKCJNYWwtZm9ybWF0dGVkIHRhZyBhdCBlbmQgb2YgdGVtcGxhdGU6IFwiIiArIGh0bWwgKyAiXCIiKSwgeyBzdGFydDogaW5kZXggKyBodG1sLmxlbmd0aCB9KTsKICAgICAgICB9CiAgICAgICAgYnJlYWsKICAgICAgfQogICAgfQoKICAgIC8vIENsZWFuIHVwIGFueSByZW1haW5pbmcgdGFncwogICAgcGFyc2VFbmRUYWcoKTsKCiAgICBmdW5jdGlvbiBhZHZhbmNlIChuKSB7CiAgICAgIGluZGV4ICs9IG47CiAgICAgIGh0bWwgPSBodG1sLnN1YnN0cmluZyhuKTsKICAgIH0KCiAgICBmdW5jdGlvbiBwYXJzZVN0YXJ0VGFnICgpIHsKICAgICAgdmFyIHN0YXJ0ID0gaHRtbC5tYXRjaChzdGFydFRhZ09wZW4pOwogICAgICBpZiAoc3RhcnQpIHsKICAgICAgICB2YXIgbWF0Y2ggPSB7CiAgICAgICAgICB0YWdOYW1lOiBzdGFydFsxXSwKICAgICAgICAgIGF0dHJzOiBbXSwKICAgICAgICAgIHN0YXJ0OiBpbmRleAogICAgICAgIH07CiAgICAgICAgYWR2YW5jZShzdGFydFswXS5sZW5ndGgpOwogICAgICAgIHZhciBlbmQsIGF0dHI7CiAgICAgICAgd2hpbGUgKCEoZW5kID0gaHRtbC5tYXRjaChzdGFydFRhZ0Nsb3NlKSkgJiYgKGF0dHIgPSBodG1sLm1hdGNoKGR5bmFtaWNBcmdBdHRyaWJ1dGUpIHx8IGh0bWwubWF0Y2goYXR0cmlidXRlKSkpIHsKICAgICAgICAgIGF0dHIuc3RhcnQgPSBpbmRleDsKICAgICAgICAgIGFkdmFuY2UoYXR0clswXS5sZW5ndGgpOwogICAgICAgICAgYXR0ci5lbmQgPSBpbmRleDsKICAgICAgICAgIG1hdGNoLmF0dHJzLnB1c2goYXR0cik7CiAgICAgICAgfQogICAgICAgIGlmIChlbmQpIHsKICAgICAgICAgIG1hdGNoLnVuYXJ5U2xhc2ggPSBlbmRbMV07CiAgICAgICAgICBhZHZhbmNlKGVuZFswXS5sZW5ndGgpOwogICAgICAgICAgbWF0Y2guZW5kID0gaW5kZXg7CiAgICAgICAgICByZXR1cm4gbWF0Y2gKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBoYW5kbGVTdGFydFRhZyAobWF0Y2gpIHsKICAgICAgdmFyIHRhZ05hbWUgPSBtYXRjaC50YWdOYW1lOwogICAgICB2YXIgdW5hcnlTbGFzaCA9IG1hdGNoLnVuYXJ5U2xhc2g7CgogICAgICBpZiAoZXhwZWN0SFRNTCkgewogICAgICAgIGlmIChsYXN0VGFnID09PSAncCcgJiYgaXNOb25QaHJhc2luZ1RhZyh0YWdOYW1lKSkgewogICAgICAgICAgcGFyc2VFbmRUYWcobGFzdFRhZyk7CiAgICAgICAgfQogICAgICAgIGlmIChjYW5CZUxlZnRPcGVuVGFnJCQxKHRhZ05hbWUpICYmIGxhc3RUYWcgPT09IHRhZ05hbWUpIHsKICAgICAgICAgIHBhcnNlRW5kVGFnKHRhZ05hbWUpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgdmFyIHVuYXJ5ID0gaXNVbmFyeVRhZyQkMSh0YWdOYW1lKSB8fCAhIXVuYXJ5U2xhc2g7CgogICAgICB2YXIgbCA9IG1hdGNoLmF0dHJzLmxlbmd0aDsKICAgICAgdmFyIGF0dHJzID0gbmV3IEFycmF5KGwpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGw7IGkrKykgewogICAgICAgIHZhciBhcmdzID0gbWF0Y2guYXR0cnNbaV07CiAgICAgICAgdmFyIHZhbHVlID0gYXJnc1szXSB8fCBhcmdzWzRdIHx8IGFyZ3NbNV0gfHwgJyc7CiAgICAgICAgdmFyIHNob3VsZERlY29kZU5ld2xpbmVzID0gdGFnTmFtZSA9PT0gJ2EnICYmIGFyZ3NbMV0gPT09ICdocmVmJwogICAgICAgICAgPyBvcHRpb25zLnNob3VsZERlY29kZU5ld2xpbmVzRm9ySHJlZgogICAgICAgICAgOiBvcHRpb25zLnNob3VsZERlY29kZU5ld2xpbmVzOwogICAgICAgIGF0dHJzW2ldID0gewogICAgICAgICAgbmFtZTogYXJnc1sxXSwKICAgICAgICAgIHZhbHVlOiBkZWNvZGVBdHRyKHZhbHVlLCBzaG91bGREZWNvZGVOZXdsaW5lcykKICAgICAgICB9OwogICAgICAgIGlmIChvcHRpb25zLm91dHB1dFNvdXJjZVJhbmdlKSB7CiAgICAgICAgICBhdHRyc1tpXS5zdGFydCA9IGFyZ3Muc3RhcnQgKyBhcmdzWzBdLm1hdGNoKC9eXHMqLykubGVuZ3RoOwogICAgICAgICAgYXR0cnNbaV0uZW5kID0gYXJncy5lbmQ7CiAgICAgICAgfQogICAgICB9CgogICAgICBpZiAoIXVuYXJ5KSB7CiAgICAgICAgc3RhY2sucHVzaCh7IHRhZzogdGFnTmFtZSwgbG93ZXJDYXNlZFRhZzogdGFnTmFtZS50b0xvd2VyQ2FzZSgpLCBhdHRyczogYXR0cnMsIHN0YXJ0OiBtYXRjaC5zdGFydCwgZW5kOiBtYXRjaC5lbmQgfSk7CiAgICAgICAgbGFzdFRhZyA9IHRhZ05hbWU7CiAgICAgIH0KCiAgICAgIGlmIChvcHRpb25zLnN0YXJ0KSB7CiAgICAgICAgb3B0aW9ucy5zdGFydCh0YWdOYW1lLCBhdHRycywgdW5hcnksIG1hdGNoLnN0YXJ0LCBtYXRjaC5lbmQpOwogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gcGFyc2VFbmRUYWcgKHRhZ05hbWUsIHN0YXJ0LCBlbmQpIHsKICAgICAgdmFyIHBvcywgbG93ZXJDYXNlZFRhZ05hbWU7CiAgICAgIGlmIChzdGFydCA9PSBudWxsKSB7IHN0YXJ0ID0gaW5kZXg7IH0KICAgICAgaWYgKGVuZCA9PSBudWxsKSB7IGVuZCA9IGluZGV4OyB9CgogICAgICAvLyBGaW5kIHRoZSBjbG9zZXN0IG9wZW5lZCB0YWcgb2YgdGhlIHNhbWUgdHlwZQogICAgICBpZiAodGFnTmFtZSkgewogICAgICAgIGxvd2VyQ2FzZWRUYWdOYW1lID0gdGFnTmFtZS50b0xvd2VyQ2FzZSgpOwogICAgICAgIGZvciAocG9zID0gc3RhY2subGVuZ3RoIC0gMTsgcG9zID49IDA7IHBvcy0tKSB7CiAgICAgICAgICBpZiAoc3RhY2tbcG9zXS5sb3dlckNhc2VkVGFnID09PSBsb3dlckNhc2VkVGFnTmFtZSkgewogICAgICAgICAgICBicmVhawogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBJZiBubyB0YWcgbmFtZSBpcyBwcm92aWRlZCwgY2xlYW4gc2hvcAogICAgICAgIHBvcyA9IDA7CiAgICAgIH0KCiAgICAgIGlmIChwb3MgPj0gMCkgewogICAgICAgIC8vIENsb3NlIGFsbCB0aGUgb3BlbiBlbGVtZW50cywgdXAgdGhlIHN0YWNrCiAgICAgICAgZm9yICh2YXIgaSA9IHN0YWNrLmxlbmd0aCAtIDE7IGkgPj0gcG9zOyBpLS0pIHsKICAgICAgICAgIGlmIChpID4gcG9zIHx8ICF0YWdOYW1lICYmCiAgICAgICAgICAgIG9wdGlvbnMud2FybgogICAgICAgICAgKSB7CiAgICAgICAgICAgIG9wdGlvbnMud2FybigKICAgICAgICAgICAgICAoInRhZyA8IiArIChzdGFja1tpXS50YWcpICsgIj4gaGFzIG5vIG1hdGNoaW5nIGVuZCB0YWcuIiksCiAgICAgICAgICAgICAgeyBzdGFydDogc3RhY2tbaV0uc3RhcnQsIGVuZDogc3RhY2tbaV0uZW5kIH0KICAgICAgICAgICAgKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChvcHRpb25zLmVuZCkgewogICAgICAgICAgICBvcHRpb25zLmVuZChzdGFja1tpXS50YWcsIHN0YXJ0LCBlbmQpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gUmVtb3ZlIHRoZSBvcGVuIGVsZW1lbnRzIGZyb20gdGhlIHN0YWNrCiAgICAgICAgc3RhY2subGVuZ3RoID0gcG9zOwogICAgICAgIGxhc3RUYWcgPSBwb3MgJiYgc3RhY2tbcG9zIC0gMV0udGFnOwogICAgICB9IGVsc2UgaWYgKGxvd2VyQ2FzZWRUYWdOYW1lID09PSAnYnInKSB7CiAgICAgICAgaWYgKG9wdGlvbnMuc3RhcnQpIHsKICAgICAgICAgIG9wdGlvbnMuc3RhcnQodGFnTmFtZSwgW10sIHRydWUsIHN0YXJ0LCBlbmQpOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChsb3dlckNhc2VkVGFnTmFtZSA9PT0gJ3AnKSB7CiAgICAgICAgaWYgKG9wdGlvbnMuc3RhcnQpIHsKICAgICAgICAgIG9wdGlvbnMuc3RhcnQodGFnTmFtZSwgW10sIGZhbHNlLCBzdGFydCwgZW5kKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbnMuZW5kKSB7CiAgICAgICAgICBvcHRpb25zLmVuZCh0YWdOYW1lLCBzdGFydCwgZW5kKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIC8qICAqLwoKICB2YXIgb25SRSA9IC9eQHxedi1vbjovOwogIHZhciBkaXJSRSA9IC9edi18XkB8XjovOwogIHZhciBmb3JBbGlhc1JFID0gLyhbXHNcU10qPylccysoPzppbnxvZilccysoW1xzXFNdKikvOwogIHZhciBmb3JJdGVyYXRvclJFID0gLywoW14sXH1cXV0qKSg/OiwoW14sXH1cXV0qKSk/JC87CiAgdmFyIHN0cmlwUGFyZW5zUkUgPSAvXlwofFwpJC9nOwogIHZhciBkeW5hbWljQXJnUkUgPSAvXlxbLipcXSQvOwoKICB2YXIgYXJnUkUgPSAvOiguKikkLzsKICB2YXIgYmluZFJFID0gL146fF5cLnxedi1iaW5kOi87CiAgdmFyIG1vZGlmaWVyUkUgPSAvXC5bXi5cXV0rKD89W15cXV0qJCkvZzsKCiAgdmFyIHNsb3RSRSA9IC9edi1zbG90KDp8JCl8XiMvOwoKICB2YXIgbGluZUJyZWFrUkUgPSAvW1xyXG5dLzsKICB2YXIgd2hpdGVzcGFjZVJFJDEgPSAvXHMrL2c7CgogIHZhciBpbnZhbGlkQXR0cmlidXRlUkUgPSAvW1xzIic8PlwvPV0vOwoKICB2YXIgZGVjb2RlSFRNTENhY2hlZCA9IGNhY2hlZChoZS5kZWNvZGUpOwoKICB2YXIgZW1wdHlTbG90U2NvcGVUb2tlbiA9ICJfZW1wdHlfIjsKCiAgLy8gY29uZmlndXJhYmxlIHN0YXRlCiAgdmFyIHdhcm4kMjsKICB2YXIgZGVsaW1pdGVyczsKICB2YXIgdHJhbnNmb3JtczsKICB2YXIgcHJlVHJhbnNmb3JtczsKICB2YXIgcG9zdFRyYW5zZm9ybXM7CiAgdmFyIHBsYXRmb3JtSXNQcmVUYWc7CiAgdmFyIHBsYXRmb3JtTXVzdFVzZVByb3A7CiAgdmFyIHBsYXRmb3JtR2V0VGFnTmFtZXNwYWNlOwogIHZhciBtYXliZUNvbXBvbmVudDsKCiAgZnVuY3Rpb24gY3JlYXRlQVNURWxlbWVudCAoCiAgICB0YWcsCiAgICBhdHRycywKICAgIHBhcmVudAogICkgewogICAgcmV0dXJuIHsKICAgICAgdHlwZTogMSwKICAgICAgdGFnOiB0YWcsCiAgICAgIGF0dHJzTGlzdDogYXR0cnMsCiAgICAgIGF0dHJzTWFwOiBtYWtlQXR0cnNNYXAoYXR0cnMpLAogICAgICByYXdBdHRyc01hcDoge30sCiAgICAgIHBhcmVudDogcGFyZW50LAogICAgICBjaGlsZHJlbjogW10KICAgIH0KICB9CgogIC8qKgogICAqIENvbnZlcnQgSFRNTCBzdHJpbmcgdG8gQVNULgogICAqLwogIGZ1bmN0aW9uIHBhcnNlICgKICAgIHRlbXBsYXRlLAogICAgb3B0aW9ucwogICkgewogICAgd2FybiQyID0gb3B0aW9ucy53YXJuIHx8IGJhc2VXYXJuOwoKICAgIHBsYXRmb3JtSXNQcmVUYWcgPSBvcHRpb25zLmlzUHJlVGFnIHx8IG5vOwogICAgcGxhdGZvcm1NdXN0VXNlUHJvcCA9IG9wdGlvbnMubXVzdFVzZVByb3AgfHwgbm87CiAgICBwbGF0Zm9ybUdldFRhZ05hbWVzcGFjZSA9IG9wdGlvbnMuZ2V0VGFnTmFtZXNwYWNlIHx8IG5vOwogICAgdmFyIGlzUmVzZXJ2ZWRUYWcgPSBvcHRpb25zLmlzUmVzZXJ2ZWRUYWcgfHwgbm87CiAgICBtYXliZUNvbXBvbmVudCA9IGZ1bmN0aW9uIChlbCkgeyByZXR1cm4gISFlbC5jb21wb25lbnQgfHwgIWlzUmVzZXJ2ZWRUYWcoZWwudGFnKTsgfTsKCiAgICB0cmFuc2Zvcm1zID0gcGx1Y2tNb2R1bGVGdW5jdGlvbihvcHRpb25zLm1vZHVsZXMsICd0cmFuc2Zvcm1Ob2RlJyk7CiAgICBwcmVUcmFuc2Zvcm1zID0gcGx1Y2tNb2R1bGVGdW5jdGlvbihvcHRpb25zLm1vZHVsZXMsICdwcmVUcmFuc2Zvcm1Ob2RlJyk7CiAgICBwb3N0VHJhbnNmb3JtcyA9IHBsdWNrTW9kdWxlRnVuY3Rpb24ob3B0aW9ucy5tb2R1bGVzLCAncG9zdFRyYW5zZm9ybU5vZGUnKTsKCiAgICBkZWxpbWl0ZXJzID0gb3B0aW9ucy5kZWxpbWl0ZXJzOwoKICAgIHZhciBzdGFjayA9IFtdOwogICAgdmFyIHByZXNlcnZlV2hpdGVzcGFjZSA9IG9wdGlvbnMucHJlc2VydmVXaGl0ZXNwYWNlICE9PSBmYWxzZTsKICAgIHZhciB3aGl0ZXNwYWNlT3B0aW9uID0gb3B0aW9ucy53aGl0ZXNwYWNlOwogICAgdmFyIHJvb3Q7CiAgICB2YXIgY3VycmVudFBhcmVudDsKICAgIHZhciBpblZQcmUgPSBmYWxzZTsKICAgIHZhciBpblByZSA9IGZhbHNlOwogICAgdmFyIHdhcm5lZCA9IGZhbHNlOwoKICAgIGZ1bmN0aW9uIHdhcm5PbmNlIChtc2csIHJhbmdlKSB7CiAgICAgIGlmICghd2FybmVkKSB7CiAgICAgICAgd2FybmVkID0gdHJ1ZTsKICAgICAgICB3YXJuJDIobXNnLCByYW5nZSk7CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBjbG9zZUVsZW1lbnQgKGVsZW1lbnQpIHsKICAgICAgdHJpbUVuZGluZ1doaXRlc3BhY2UoZWxlbWVudCk7CiAgICAgIGlmICghaW5WUHJlICYmICFlbGVtZW50LnByb2Nlc3NlZCkgewogICAgICAgIGVsZW1lbnQgPSBwcm9jZXNzRWxlbWVudChlbGVtZW50LCBvcHRpb25zKTsKICAgICAgfQogICAgICAvLyB0cmVlIG1hbmFnZW1lbnQKICAgICAgaWYgKCFzdGFjay5sZW5ndGggJiYgZWxlbWVudCAhPT0gcm9vdCkgewogICAgICAgIC8vIGFsbG93IHJvb3QgZWxlbWVudHMgd2l0aCB2LWlmLCB2LWVsc2UtaWYgYW5kIHYtZWxzZQogICAgICAgIGlmIChyb290LmlmICYmIChlbGVtZW50LmVsc2VpZiB8fCBlbGVtZW50LmVsc2UpKSB7CiAgICAgICAgICB7CiAgICAgICAgICAgIGNoZWNrUm9vdENvbnN0cmFpbnRzKGVsZW1lbnQpOwogICAgICAgICAgfQogICAgICAgICAgYWRkSWZDb25kaXRpb24ocm9vdCwgewogICAgICAgICAgICBleHA6IGVsZW1lbnQuZWxzZWlmLAogICAgICAgICAgICBibG9jazogZWxlbWVudAogICAgICAgICAgfSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHdhcm5PbmNlKAogICAgICAgICAgICAiQ29tcG9uZW50IHRlbXBsYXRlIHNob3VsZCBjb250YWluIGV4YWN0bHkgb25lIHJvb3QgZWxlbWVudC4gIiArCiAgICAgICAgICAgICJJZiB5b3UgYXJlIHVzaW5nIHYtaWYgb24gbXVsdGlwbGUgZWxlbWVudHMsICIgKwogICAgICAgICAgICAidXNlIHYtZWxzZS1pZiB0byBjaGFpbiB0aGVtIGluc3RlYWQuIiwKICAgICAgICAgICAgeyBzdGFydDogZWxlbWVudC5zdGFydCB9CiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoY3VycmVudFBhcmVudCAmJiAhZWxlbWVudC5mb3JiaWRkZW4pIHsKICAgICAgICBpZiAoZWxlbWVudC5lbHNlaWYgfHwgZWxlbWVudC5lbHNlKSB7CiAgICAgICAgICBwcm9jZXNzSWZDb25kaXRpb25zKGVsZW1lbnQsIGN1cnJlbnRQYXJlbnQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoZWxlbWVudC5zbG90U2NvcGUpIHsKICAgICAgICAgICAgLy8gc2NvcGVkIHNsb3QKICAgICAgICAgICAgLy8ga2VlcCBpdCBpbiB0aGUgY2hpbGRyZW4gbGlzdCBzbyB0aGF0IHYtZWxzZSgtaWYpIGNvbmRpdGlvbnMgY2FuCiAgICAgICAgICAgIC8vIGZpbmQgaXQgYXMgdGhlIHByZXYgbm9kZS4KICAgICAgICAgICAgdmFyIG5hbWUgPSBlbGVtZW50LnNsb3RUYXJnZXQgfHwgJyJkZWZhdWx0IicKICAgICAgICAgICAgOyhjdXJyZW50UGFyZW50LnNjb3BlZFNsb3RzIHx8IChjdXJyZW50UGFyZW50LnNjb3BlZFNsb3RzID0ge30pKVtuYW1lXSA9IGVsZW1lbnQ7CiAgICAgICAgICB9CiAgICAgICAgICBjdXJyZW50UGFyZW50LmNoaWxkcmVuLnB1c2goZWxlbWVudCk7CiAgICAgICAgICBlbGVtZW50LnBhcmVudCA9IGN1cnJlbnRQYXJlbnQ7CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyBmaW5hbCBjaGlsZHJlbiBjbGVhbnVwCiAgICAgIC8vIGZpbHRlciBvdXQgc2NvcGVkIHNsb3RzCiAgICAgIGVsZW1lbnQuY2hpbGRyZW4gPSBlbGVtZW50LmNoaWxkcmVuLmZpbHRlcihmdW5jdGlvbiAoYykgeyByZXR1cm4gIShjKS5zbG90U2NvcGU7IH0pOwogICAgICAvLyByZW1vdmUgdHJhaWxpbmcgd2hpdGVzcGFjZSBub2RlIGFnYWluCiAgICAgIHRyaW1FbmRpbmdXaGl0ZXNwYWNlKGVsZW1lbnQpOwoKICAgICAgLy8gY2hlY2sgcHJlIHN0YXRlCiAgICAgIGlmIChlbGVtZW50LnByZSkgewogICAgICAgIGluVlByZSA9IGZhbHNlOwogICAgICB9CiAgICAgIGlmIChwbGF0Zm9ybUlzUHJlVGFnKGVsZW1lbnQudGFnKSkgewogICAgICAgIGluUHJlID0gZmFsc2U7CiAgICAgIH0KICAgICAgLy8gYXBwbHkgcG9zdC10cmFuc2Zvcm1zCiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9zdFRyYW5zZm9ybXMubGVuZ3RoOyBpKyspIHsKICAgICAgICBwb3N0VHJhbnNmb3Jtc1tpXShlbGVtZW50LCBvcHRpb25zKTsKICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRyaW1FbmRpbmdXaGl0ZXNwYWNlIChlbCkgewogICAgICAvLyByZW1vdmUgdHJhaWxpbmcgd2hpdGVzcGFjZSBub2RlCiAgICAgIGlmICghaW5QcmUpIHsKICAgICAgICB2YXIgbGFzdE5vZGU7CiAgICAgICAgd2hpbGUgKAogICAgICAgICAgKGxhc3ROb2RlID0gZWwuY2hpbGRyZW5bZWwuY2hpbGRyZW4ubGVuZ3RoIC0gMV0pICYmCiAgICAgICAgICBsYXN0Tm9kZS50eXBlID09PSAzICYmCiAgICAgICAgICBsYXN0Tm9kZS50ZXh0ID09PSAnICcKICAgICAgICApIHsKICAgICAgICAgIGVsLmNoaWxkcmVuLnBvcCgpOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGNoZWNrUm9vdENvbnN0cmFpbnRzIChlbCkgewogICAgICBpZiAoZWwudGFnID09PSAnc2xvdCcgfHwgZWwudGFnID09PSAndGVtcGxhdGUnKSB7CiAgICAgICAgd2Fybk9uY2UoCiAgICAgICAgICAiQ2Fubm90IHVzZSA8IiArIChlbC50YWcpICsgIj4gYXMgY29tcG9uZW50IHJvb3QgZWxlbWVudCBiZWNhdXNlIGl0IG1heSAiICsKICAgICAgICAgICdjb250YWluIG11bHRpcGxlIG5vZGVzLicsCiAgICAgICAgICB7IHN0YXJ0OiBlbC5zdGFydCB9CiAgICAgICAgKTsKICAgICAgfQogICAgICBpZiAoZWwuYXR0cnNNYXAuaGFzT3duUHJvcGVydHkoJ3YtZm9yJykpIHsKICAgICAgICB3YXJuT25jZSgKICAgICAgICAgICdDYW5ub3QgdXNlIHYtZm9yIG9uIHN0YXRlZnVsIGNvbXBvbmVudCByb290IGVsZW1lbnQgYmVjYXVzZSAnICsKICAgICAgICAgICdpdCByZW5kZXJzIG11bHRpcGxlIGVsZW1lbnRzLicsCiAgICAgICAgICBlbC5yYXdBdHRyc01hcFsndi1mb3InXQogICAgICAgICk7CiAgICAgIH0KICAgIH0KCiAgICBwYXJzZUhUTUwodGVtcGxhdGUsIHsKICAgICAgd2Fybjogd2FybiQyLAogICAgICBleHBlY3RIVE1MOiBvcHRpb25zLmV4cGVjdEhUTUwsCiAgICAgIGlzVW5hcnlUYWc6IG9wdGlvbnMuaXNVbmFyeVRhZywKICAgICAgY2FuQmVMZWZ0T3BlblRhZzogb3B0aW9ucy5jYW5CZUxlZnRPcGVuVGFnLAogICAgICBzaG91bGREZWNvZGVOZXdsaW5lczogb3B0aW9ucy5zaG91bGREZWNvZGVOZXdsaW5lcywKICAgICAgc2hvdWxkRGVjb2RlTmV3bGluZXNGb3JIcmVmOiBvcHRpb25zLnNob3VsZERlY29kZU5ld2xpbmVzRm9ySHJlZiwKICAgICAgc2hvdWxkS2VlcENvbW1lbnQ6IG9wdGlvbnMuY29tbWVudHMsCiAgICAgIG91dHB1dFNvdXJjZVJhbmdlOiBvcHRpb25zLm91dHB1dFNvdXJjZVJhbmdlLAogICAgICBzdGFydDogZnVuY3Rpb24gc3RhcnQgKHRhZywgYXR0cnMsIHVuYXJ5LCBzdGFydCQxLCBlbmQpIHsKICAgICAgICAvLyBjaGVjayBuYW1lc3BhY2UuCiAgICAgICAgLy8gaW5oZXJpdCBwYXJlbnQgbnMgaWYgdGhlcmUgaXMgb25lCiAgICAgICAgdmFyIG5zID0gKGN1cnJlbnRQYXJlbnQgJiYgY3VycmVudFBhcmVudC5ucykgfHwgcGxhdGZvcm1HZXRUYWdOYW1lc3BhY2UodGFnKTsKCiAgICAgICAgLy8gaGFuZGxlIElFIHN2ZyBidWcKICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgICAgICBpZiAoaXNJRSAmJiBucyA9PT0gJ3N2ZycpIHsKICAgICAgICAgIGF0dHJzID0gZ3VhcmRJRVNWR0J1ZyhhdHRycyk7CiAgICAgICAgfQoKICAgICAgICB2YXIgZWxlbWVudCA9IGNyZWF0ZUFTVEVsZW1lbnQodGFnLCBhdHRycywgY3VycmVudFBhcmVudCk7CiAgICAgICAgaWYgKG5zKSB7CiAgICAgICAgICBlbGVtZW50Lm5zID0gbnM7CiAgICAgICAgfQoKICAgICAgICB7CiAgICAgICAgICBpZiAob3B0aW9ucy5vdXRwdXRTb3VyY2VSYW5nZSkgewogICAgICAgICAgICBlbGVtZW50LnN0YXJ0ID0gc3RhcnQkMTsKICAgICAgICAgICAgZWxlbWVudC5lbmQgPSBlbmQ7CiAgICAgICAgICAgIGVsZW1lbnQucmF3QXR0cnNNYXAgPSBlbGVtZW50LmF0dHJzTGlzdC5yZWR1Y2UoZnVuY3Rpb24gKGN1bXVsYXRlZCwgYXR0cikgewogICAgICAgICAgICAgIGN1bXVsYXRlZFthdHRyLm5hbWVdID0gYXR0cjsKICAgICAgICAgICAgICByZXR1cm4gY3VtdWxhdGVkCiAgICAgICAgICAgIH0sIHt9KTsKICAgICAgICAgIH0KICAgICAgICAgIGF0dHJzLmZvckVhY2goZnVuY3Rpb24gKGF0dHIpIHsKICAgICAgICAgICAgaWYgKGludmFsaWRBdHRyaWJ1dGVSRS50ZXN0KGF0dHIubmFtZSkpIHsKICAgICAgICAgICAgICB3YXJuJDIoCiAgICAgICAgICAgICAgICAiSW52YWxpZCBkeW5hbWljIGFyZ3VtZW50IGV4cHJlc3Npb246IGF0dHJpYnV0ZSBuYW1lcyBjYW5ub3QgY29udGFpbiAiICsKICAgICAgICAgICAgICAgICJzcGFjZXMsIHF1b3RlcywgPCwgPiwgLyBvciA9LiIsCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIHN0YXJ0OiBhdHRyLnN0YXJ0ICsgYXR0ci5uYW1lLmluZGV4T2YoIlsiKSwKICAgICAgICAgICAgICAgICAgZW5kOiBhdHRyLnN0YXJ0ICsgYXR0ci5uYW1lLmxlbmd0aAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzRm9yYmlkZGVuVGFnKGVsZW1lbnQpICYmICFpc1NlcnZlclJlbmRlcmluZygpKSB7CiAgICAgICAgICBlbGVtZW50LmZvcmJpZGRlbiA9IHRydWU7CiAgICAgICAgICB3YXJuJDIoCiAgICAgICAgICAgICdUZW1wbGF0ZXMgc2hvdWxkIG9ubHkgYmUgcmVzcG9uc2libGUgZm9yIG1hcHBpbmcgdGhlIHN0YXRlIHRvIHRoZSAnICsKICAgICAgICAgICAgJ1VJLiBBdm9pZCBwbGFjaW5nIHRhZ3Mgd2l0aCBzaWRlLWVmZmVjdHMgaW4geW91ciB0ZW1wbGF0ZXMsIHN1Y2ggYXMgJyArCiAgICAgICAgICAgICI8IiArIHRhZyArICI+IiArICcsIGFzIHRoZXkgd2lsbCBub3QgYmUgcGFyc2VkLicsCiAgICAgICAgICAgIHsgc3RhcnQ6IGVsZW1lbnQuc3RhcnQgfQogICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIC8vIGFwcGx5IHByZS10cmFuc2Zvcm1zCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcmVUcmFuc2Zvcm1zLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICBlbGVtZW50ID0gcHJlVHJhbnNmb3Jtc1tpXShlbGVtZW50LCBvcHRpb25zKSB8fCBlbGVtZW50OwogICAgICAgIH0KCiAgICAgICAgaWYgKCFpblZQcmUpIHsKICAgICAgICAgIHByb2Nlc3NQcmUoZWxlbWVudCk7CiAgICAgICAgICBpZiAoZWxlbWVudC5wcmUpIHsKICAgICAgICAgICAgaW5WUHJlID0gdHJ1ZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHBsYXRmb3JtSXNQcmVUYWcoZWxlbWVudC50YWcpKSB7CiAgICAgICAgICBpblByZSA9IHRydWU7CiAgICAgICAgfQogICAgICAgIGlmIChpblZQcmUpIHsKICAgICAgICAgIHByb2Nlc3NSYXdBdHRycyhlbGVtZW50KTsKICAgICAgICB9IGVsc2UgaWYgKCFlbGVtZW50LnByb2Nlc3NlZCkgewogICAgICAgICAgLy8gc3RydWN0dXJhbCBkaXJlY3RpdmVzCiAgICAgICAgICBwcm9jZXNzRm9yKGVsZW1lbnQpOwogICAgICAgICAgcHJvY2Vzc0lmKGVsZW1lbnQpOwogICAgICAgICAgcHJvY2Vzc09uY2UoZWxlbWVudCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIXJvb3QpIHsKICAgICAgICAgIHJvb3QgPSBlbGVtZW50OwogICAgICAgICAgewogICAgICAgICAgICBjaGVja1Jvb3RDb25zdHJhaW50cyhyb290KTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghdW5hcnkpIHsKICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSBlbGVtZW50OwogICAgICAgICAgc3RhY2sucHVzaChlbGVtZW50KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2xvc2VFbGVtZW50KGVsZW1lbnQpOwogICAgICAgIH0KICAgICAgfSwKCiAgICAgIGVuZDogZnVuY3Rpb24gZW5kICh0YWcsIHN0YXJ0LCBlbmQkMSkgewogICAgICAgIHZhciBlbGVtZW50ID0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV07CiAgICAgICAgLy8gcG9wIHN0YWNrCiAgICAgICAgc3RhY2subGVuZ3RoIC09IDE7CiAgICAgICAgY3VycmVudFBhcmVudCA9IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdOwogICAgICAgIGlmIChvcHRpb25zLm91dHB1dFNvdXJjZVJhbmdlKSB7CiAgICAgICAgICBlbGVtZW50LmVuZCA9IGVuZCQxOwogICAgICAgIH0KICAgICAgICBjbG9zZUVsZW1lbnQoZWxlbWVudCk7CiAgICAgIH0sCgogICAgICBjaGFyczogZnVuY3Rpb24gY2hhcnMgKHRleHQsIHN0YXJ0LCBlbmQpIHsKICAgICAgICBpZiAoIWN1cnJlbnRQYXJlbnQpIHsKICAgICAgICAgIHsKICAgICAgICAgICAgaWYgKHRleHQgPT09IHRlbXBsYXRlKSB7CiAgICAgICAgICAgICAgd2Fybk9uY2UoCiAgICAgICAgICAgICAgICAnQ29tcG9uZW50IHRlbXBsYXRlIHJlcXVpcmVzIGEgcm9vdCBlbGVtZW50LCByYXRoZXIgdGhhbiBqdXN0IHRleHQuJywKICAgICAgICAgICAgICAgIHsgc3RhcnQ6IHN0YXJ0IH0KICAgICAgICAgICAgICApOwogICAgICAgICAgICB9IGVsc2UgaWYgKCh0ZXh0ID0gdGV4dC50cmltKCkpKSB7CiAgICAgICAgICAgICAgd2Fybk9uY2UoCiAgICAgICAgICAgICAgICAoInRleHQgXCIiICsgdGV4dCArICJcIiBvdXRzaWRlIHJvb3QgZWxlbWVudCB3aWxsIGJlIGlnbm9yZWQuIiksCiAgICAgICAgICAgICAgICB7IHN0YXJ0OiBzdGFydCB9CiAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuCiAgICAgICAgfQogICAgICAgIC8vIElFIHRleHRhcmVhIHBsYWNlaG9sZGVyIGJ1ZwogICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgICAgIGlmIChpc0lFICYmCiAgICAgICAgICBjdXJyZW50UGFyZW50LnRhZyA9PT0gJ3RleHRhcmVhJyAmJgogICAgICAgICAgY3VycmVudFBhcmVudC5hdHRyc01hcC5wbGFjZWhvbGRlciA9PT0gdGV4dAogICAgICAgICkgewogICAgICAgICAgcmV0dXJuCiAgICAgICAgfQogICAgICAgIHZhciBjaGlsZHJlbiA9IGN1cnJlbnRQYXJlbnQuY2hpbGRyZW47CiAgICAgICAgaWYgKGluUHJlIHx8IHRleHQudHJpbSgpKSB7CiAgICAgICAgICB0ZXh0ID0gaXNUZXh0VGFnKGN1cnJlbnRQYXJlbnQpID8gdGV4dCA6IGRlY29kZUhUTUxDYWNoZWQodGV4dCk7CiAgICAgICAgfSBlbHNlIGlmICghY2hpbGRyZW4ubGVuZ3RoKSB7CiAgICAgICAgICAvLyByZW1vdmUgdGhlIHdoaXRlc3BhY2Utb25seSBub2RlIHJpZ2h0IGFmdGVyIGFuIG9wZW5pbmcgdGFnCiAgICAgICAgICB0ZXh0ID0gJyc7CiAgICAgICAgfSBlbHNlIGlmICh3aGl0ZXNwYWNlT3B0aW9uKSB7CiAgICAgICAgICBpZiAod2hpdGVzcGFjZU9wdGlvbiA9PT0gJ2NvbmRlbnNlJykgewogICAgICAgICAgICAvLyBpbiBjb25kZW5zZSBtb2RlLCByZW1vdmUgdGhlIHdoaXRlc3BhY2Ugbm9kZSBpZiBpdCBjb250YWlucwogICAgICAgICAgICAvLyBsaW5lIGJyZWFrLCBvdGhlcndpc2UgY29uZGVuc2UgdG8gYSBzaW5nbGUgc3BhY2UKICAgICAgICAgICAgdGV4dCA9IGxpbmVCcmVha1JFLnRlc3QodGV4dCkgPyAnJyA6ICcgJzsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRleHQgPSAnICc7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRleHQgPSBwcmVzZXJ2ZVdoaXRlc3BhY2UgPyAnICcgOiAnJzsKICAgICAgICB9CiAgICAgICAgaWYgKHRleHQpIHsKICAgICAgICAgIGlmICghaW5QcmUgJiYgd2hpdGVzcGFjZU9wdGlvbiA9PT0gJ2NvbmRlbnNlJykgewogICAgICAgICAgICAvLyBjb25kZW5zZSBjb25zZWN1dGl2ZSB3aGl0ZXNwYWNlcyBpbnRvIHNpbmdsZSBzcGFjZQogICAgICAgICAgICB0ZXh0ID0gdGV4dC5yZXBsYWNlKHdoaXRlc3BhY2VSRSQxLCAnICcpOwogICAgICAgICAgfQogICAgICAgICAgdmFyIHJlczsKICAgICAgICAgIHZhciBjaGlsZDsKICAgICAgICAgIGlmICghaW5WUHJlICYmIHRleHQgIT09ICcgJyAmJiAocmVzID0gcGFyc2VUZXh0KHRleHQsIGRlbGltaXRlcnMpKSkgewogICAgICAgICAgICBjaGlsZCA9IHsKICAgICAgICAgICAgICB0eXBlOiAyLAogICAgICAgICAgICAgIGV4cHJlc3Npb246IHJlcy5leHByZXNzaW9uLAogICAgICAgICAgICAgIHRva2VuczogcmVzLnRva2VucywKICAgICAgICAgICAgICB0ZXh0OiB0ZXh0CiAgICAgICAgICAgIH07CiAgICAgICAgICB9IGVsc2UgaWYgKHRleHQgIT09ICcgJyB8fCAhY2hpbGRyZW4ubGVuZ3RoIHx8IGNoaWxkcmVuW2NoaWxkcmVuLmxlbmd0aCAtIDFdLnRleHQgIT09ICcgJykgewogICAgICAgICAgICBjaGlsZCA9IHsKICAgICAgICAgICAgICB0eXBlOiAzLAogICAgICAgICAgICAgIHRleHQ6IHRleHQKICAgICAgICAgICAgfTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChjaGlsZCkgewogICAgICAgICAgICBpZiAob3B0aW9ucy5vdXRwdXRTb3VyY2VSYW5nZSkgewogICAgICAgICAgICAgIGNoaWxkLnN0YXJ0ID0gc3RhcnQ7CiAgICAgICAgICAgICAgY2hpbGQuZW5kID0gZW5kOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goY2hpbGQpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSwKICAgICAgY29tbWVudDogZnVuY3Rpb24gY29tbWVudCAodGV4dCwgc3RhcnQsIGVuZCkgewogICAgICAgIC8vIGFkZGluZyBhbnl0aW5nIGFzIGEgc2libGluZyB0byB0aGUgcm9vdCBub2RlIGlzIGZvcmJpZGRlbgogICAgICAgIC8vIGNvbW1lbnRzIHNob3VsZCBzdGlsbCBiZSBhbGxvd2VkLCBidXQgaWdub3JlZAogICAgICAgIGlmIChjdXJyZW50UGFyZW50KSB7CiAgICAgICAgICB2YXIgY2hpbGQgPSB7CiAgICAgICAgICAgIHR5cGU6IDMsCiAgICAgICAgICAgIHRleHQ6IHRleHQsCiAgICAgICAgICAgIGlzQ29tbWVudDogdHJ1ZQogICAgICAgICAgfTsKICAgICAgICAgIGlmIChvcHRpb25zLm91dHB1dFNvdXJjZVJhbmdlKSB7CiAgICAgICAgICAgIGNoaWxkLnN0YXJ0ID0gc3RhcnQ7CiAgICAgICAgICAgIGNoaWxkLmVuZCA9IGVuZDsKICAgICAgICAgIH0KICAgICAgICAgIGN1cnJlbnRQYXJlbnQuY2hpbGRyZW4ucHVzaChjaGlsZCk7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICAgIHJldHVybiByb290CiAgfQoKICBmdW5jdGlvbiBwcm9jZXNzUHJlIChlbCkgewogICAgaWYgKGdldEFuZFJlbW92ZUF0dHIoZWwsICd2LXByZScpICE9IG51bGwpIHsKICAgICAgZWwucHJlID0gdHJ1ZTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIHByb2Nlc3NSYXdBdHRycyAoZWwpIHsKICAgIHZhciBsaXN0ID0gZWwuYXR0cnNMaXN0OwogICAgdmFyIGxlbiA9IGxpc3QubGVuZ3RoOwogICAgaWYgKGxlbikgewogICAgICB2YXIgYXR0cnMgPSBlbC5hdHRycyA9IG5ldyBBcnJheShsZW4pOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgYXR0cnNbaV0gPSB7CiAgICAgICAgICBuYW1lOiBsaXN0W2ldLm5hbWUsCiAgICAgICAgICB2YWx1ZTogSlNPTi5zdHJpbmdpZnkobGlzdFtpXS52YWx1ZSkKICAgICAgICB9OwogICAgICAgIGlmIChsaXN0W2ldLnN0YXJ0ICE9IG51bGwpIHsKICAgICAgICAgIGF0dHJzW2ldLnN0YXJ0ID0gbGlzdFtpXS5zdGFydDsKICAgICAgICAgIGF0dHJzW2ldLmVuZCA9IGxpc3RbaV0uZW5kOwogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIGlmICghZWwucHJlKSB7CiAgICAgIC8vIG5vbiByb290IG5vZGUgaW4gcHJlIGJsb2NrcyB3aXRoIG5vIGF0dHJpYnV0ZXMKICAgICAgZWwucGxhaW4gPSB0cnVlOwogICAgfQogIH0KCiAgZnVuY3Rpb24gcHJvY2Vzc0VsZW1lbnQgKAogICAgZWxlbWVudCwKICAgIG9wdGlvbnMKICApIHsKICAgIHByb2Nlc3NLZXkoZWxlbWVudCk7CgogICAgLy8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBpcyBhIHBsYWluIGVsZW1lbnQgYWZ0ZXIKICAgIC8vIHJlbW92aW5nIHN0cnVjdHVyYWwgYXR0cmlidXRlcwogICAgZWxlbWVudC5wbGFpbiA9ICgKICAgICAgIWVsZW1lbnQua2V5ICYmCiAgICAgICFlbGVtZW50LnNjb3BlZFNsb3RzICYmCiAgICAgICFlbGVtZW50LmF0dHJzTGlzdC5sZW5ndGgKICAgICk7CgogICAgcHJvY2Vzc1JlZihlbGVtZW50KTsKICAgIHByb2Nlc3NTbG90Q29udGVudChlbGVtZW50KTsKICAgIHByb2Nlc3NTbG90T3V0bGV0KGVsZW1lbnQpOwogICAgcHJvY2Vzc0NvbXBvbmVudChlbGVtZW50KTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdHJhbnNmb3Jtcy5sZW5ndGg7IGkrKykgewogICAgICBlbGVtZW50ID0gdHJhbnNmb3Jtc1tpXShlbGVtZW50LCBvcHRpb25zKSB8fCBlbGVtZW50OwogICAgfQogICAgcHJvY2Vzc0F0dHJzKGVsZW1lbnQpOwogICAgcmV0dXJuIGVsZW1lbnQKICB9CgogIGZ1bmN0aW9uIHByb2Nlc3NLZXkgKGVsKSB7CiAgICB2YXIgZXhwID0gZ2V0QmluZGluZ0F0dHIoZWwsICdrZXknKTsKICAgIGlmIChleHApIHsKICAgICAgewogICAgICAgIGlmIChlbC50YWcgPT09ICd0ZW1wbGF0ZScpIHsKICAgICAgICAgIHdhcm4kMigKICAgICAgICAgICAgIjx0ZW1wbGF0ZT4gY2Fubm90IGJlIGtleWVkLiBQbGFjZSB0aGUga2V5IG9uIHJlYWwgZWxlbWVudHMgaW5zdGVhZC4iLAogICAgICAgICAgICBnZXRSYXdCaW5kaW5nQXR0cihlbCwgJ2tleScpCiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBpZiAoZWwuZm9yKSB7CiAgICAgICAgICB2YXIgaXRlcmF0b3IgPSBlbC5pdGVyYXRvcjIgfHwgZWwuaXRlcmF0b3IxOwogICAgICAgICAgdmFyIHBhcmVudCA9IGVsLnBhcmVudDsKICAgICAgICAgIGlmIChpdGVyYXRvciAmJiBpdGVyYXRvciA9PT0gZXhwICYmIHBhcmVudCAmJiBwYXJlbnQudGFnID09PSAndHJhbnNpdGlvbi1ncm91cCcpIHsKICAgICAgICAgICAgd2FybiQyKAogICAgICAgICAgICAgICJEbyBub3QgdXNlIHYtZm9yIGluZGV4IGFzIGtleSBvbiA8dHJhbnNpdGlvbi1ncm91cD4gY2hpbGRyZW4sICIgKwogICAgICAgICAgICAgICJ0aGlzIGlzIHRoZSBzYW1lIGFzIG5vdCB1c2luZyBrZXlzLiIsCiAgICAgICAgICAgICAgZ2V0UmF3QmluZGluZ0F0dHIoZWwsICdrZXknKSwKICAgICAgICAgICAgICB0cnVlIC8qIHRpcCAqLwogICAgICAgICAgICApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBlbC5rZXkgPSBleHA7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBwcm9jZXNzUmVmIChlbCkgewogICAgdmFyIHJlZiA9IGdldEJpbmRpbmdBdHRyKGVsLCAncmVmJyk7CiAgICBpZiAocmVmKSB7CiAgICAgIGVsLnJlZiA9IHJlZjsKICAgICAgZWwucmVmSW5Gb3IgPSBjaGVja0luRm9yKGVsKTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIHByb2Nlc3NGb3IgKGVsKSB7CiAgICB2YXIgZXhwOwogICAgaWYgKChleHAgPSBnZXRBbmRSZW1vdmVBdHRyKGVsLCAndi1mb3InKSkpIHsKICAgICAgdmFyIHJlcyA9IHBhcnNlRm9yKGV4cCk7CiAgICAgIGlmIChyZXMpIHsKICAgICAgICBleHRlbmQoZWwsIHJlcyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgd2FybiQyKAogICAgICAgICAgKCJJbnZhbGlkIHYtZm9yIGV4cHJlc3Npb246ICIgKyBleHApLAogICAgICAgICAgZWwucmF3QXR0cnNNYXBbJ3YtZm9yJ10KICAgICAgICApOwogICAgICB9CiAgICB9CiAgfQoKCgogIGZ1bmN0aW9uIHBhcnNlRm9yIChleHApIHsKICAgIHZhciBpbk1hdGNoID0gZXhwLm1hdGNoKGZvckFsaWFzUkUpOwogICAgaWYgKCFpbk1hdGNoKSB7IHJldHVybiB9CiAgICB2YXIgcmVzID0ge307CiAgICByZXMuZm9yID0gaW5NYXRjaFsyXS50cmltKCk7CiAgICB2YXIgYWxpYXMgPSBpbk1hdGNoWzFdLnRyaW0oKS5yZXBsYWNlKHN0cmlwUGFyZW5zUkUsICcnKTsKICAgIHZhciBpdGVyYXRvck1hdGNoID0gYWxpYXMubWF0Y2goZm9ySXRlcmF0b3JSRSk7CiAgICBpZiAoaXRlcmF0b3JNYXRjaCkgewogICAgICByZXMuYWxpYXMgPSBhbGlhcy5yZXBsYWNlKGZvckl0ZXJhdG9yUkUsICcnKS50cmltKCk7CiAgICAgIHJlcy5pdGVyYXRvcjEgPSBpdGVyYXRvck1hdGNoWzFdLnRyaW0oKTsKICAgICAgaWYgKGl0ZXJhdG9yTWF0Y2hbMl0pIHsKICAgICAgICByZXMuaXRlcmF0b3IyID0gaXRlcmF0b3JNYXRjaFsyXS50cmltKCk7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHJlcy5hbGlhcyA9IGFsaWFzOwogICAgfQogICAgcmV0dXJuIHJlcwogIH0KCiAgZnVuY3Rpb24gcHJvY2Vzc0lmIChlbCkgewogICAgdmFyIGV4cCA9IGdldEFuZFJlbW92ZUF0dHIoZWwsICd2LWlmJyk7CiAgICBpZiAoZXhwKSB7CiAgICAgIGVsLmlmID0gZXhwOwogICAgICBhZGRJZkNvbmRpdGlvbihlbCwgewogICAgICAgIGV4cDogZXhwLAogICAgICAgIGJsb2NrOiBlbAogICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgIGlmIChnZXRBbmRSZW1vdmVBdHRyKGVsLCAndi1lbHNlJykgIT0gbnVsbCkgewogICAgICAgIGVsLmVsc2UgPSB0cnVlOwogICAgICB9CiAgICAgIHZhciBlbHNlaWYgPSBnZXRBbmRSZW1vdmVBdHRyKGVsLCAndi1lbHNlLWlmJyk7CiAgICAgIGlmIChlbHNlaWYpIHsKICAgICAgICBlbC5lbHNlaWYgPSBlbHNlaWY7CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIHByb2Nlc3NJZkNvbmRpdGlvbnMgKGVsLCBwYXJlbnQpIHsKICAgIHZhciBwcmV2ID0gZmluZFByZXZFbGVtZW50KHBhcmVudC5jaGlsZHJlbik7CiAgICBpZiAocHJldiAmJiBwcmV2LmlmKSB7CiAgICAgIGFkZElmQ29uZGl0aW9uKHByZXYsIHsKICAgICAgICBleHA6IGVsLmVsc2VpZiwKICAgICAgICBibG9jazogZWwKICAgICAgfSk7CiAgICB9IGVsc2UgewogICAgICB3YXJuJDIoCiAgICAgICAgInYtIiArIChlbC5lbHNlaWYgPyAoJ2Vsc2UtaWY9IicgKyBlbC5lbHNlaWYgKyAnIicpIDogJ2Vsc2UnKSArICIgIiArCiAgICAgICAgInVzZWQgb24gZWxlbWVudCA8IiArIChlbC50YWcpICsgIj4gd2l0aG91dCBjb3JyZXNwb25kaW5nIHYtaWYuIiwKICAgICAgICBlbC5yYXdBdHRyc01hcFtlbC5lbHNlaWYgPyAndi1lbHNlLWlmJyA6ICd2LWVsc2UnXQogICAgICApOwogICAgfQogIH0KCiAgZnVuY3Rpb24gZmluZFByZXZFbGVtZW50IChjaGlsZHJlbikgewogICAgdmFyIGkgPSBjaGlsZHJlbi5sZW5ndGg7CiAgICB3aGlsZSAoaS0tKSB7CiAgICAgIGlmIChjaGlsZHJlbltpXS50eXBlID09PSAxKSB7CiAgICAgICAgcmV0dXJuIGNoaWxkcmVuW2ldCiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKGNoaWxkcmVuW2ldLnRleHQgIT09ICcgJykgewogICAgICAgICAgd2FybiQyKAogICAgICAgICAgICAidGV4dCBcIiIgKyAoY2hpbGRyZW5baV0udGV4dC50cmltKCkpICsgIlwiIGJldHdlZW4gdi1pZiBhbmQgdi1lbHNlKC1pZikgIiArCiAgICAgICAgICAgICJ3aWxsIGJlIGlnbm9yZWQuIiwKICAgICAgICAgICAgY2hpbGRyZW5baV0KICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGNoaWxkcmVuLnBvcCgpOwogICAgICB9CiAgICB9CiAgfQoKICBmdW5jdGlvbiBhZGRJZkNvbmRpdGlvbiAoZWwsIGNvbmRpdGlvbikgewogICAgaWYgKCFlbC5pZkNvbmRpdGlvbnMpIHsKICAgICAgZWwuaWZDb25kaXRpb25zID0gW107CiAgICB9CiAgICBlbC5pZkNvbmRpdGlvbnMucHVzaChjb25kaXRpb24pOwogIH0KCiAgZnVuY3Rpb24gcHJvY2Vzc09uY2UgKGVsKSB7CiAgICB2YXIgb25jZSQkMSA9IGdldEFuZFJlbW92ZUF0dHIoZWwsICd2LW9uY2UnKTsKICAgIGlmIChvbmNlJCQxICE9IG51bGwpIHsKICAgICAgZWwub25jZSA9IHRydWU7CiAgICB9CiAgfQoKICAvLyBoYW5kbGUgY29udGVudCBiZWluZyBwYXNzZWQgdG8gYSBjb21wb25lbnQgYXMgc2xvdCwKICAvLyBlLmcuIDx0ZW1wbGF0ZSBzbG90PSJ4eHgiPiwgPGRpdiBzbG90LXNjb3BlPSJ4eHgiPgogIGZ1bmN0aW9uIHByb2Nlc3NTbG90Q29udGVudCAoZWwpIHsKICAgIHZhciBzbG90U2NvcGU7CiAgICBpZiAoZWwudGFnID09PSAndGVtcGxhdGUnKSB7CiAgICAgIHNsb3RTY29wZSA9IGdldEFuZFJlbW92ZUF0dHIoZWwsICdzY29wZScpOwogICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgICAgaWYgKHNsb3RTY29wZSkgewogICAgICAgIHdhcm4kMigKICAgICAgICAgICJ0aGUgXCJzY29wZVwiIGF0dHJpYnV0ZSBmb3Igc2NvcGVkIHNsb3RzIGhhdmUgYmVlbiBkZXByZWNhdGVkIGFuZCAiICsKICAgICAgICAgICJyZXBsYWNlZCBieSBcInNsb3Qtc2NvcGVcIiBzaW5jZSAyLjUuIFRoZSBuZXcgXCJzbG90LXNjb3BlXCIgYXR0cmlidXRlICIgKwogICAgICAgICAgImNhbiBhbHNvIGJlIHVzZWQgb24gcGxhaW4gZWxlbWVudHMgaW4gYWRkaXRpb24gdG8gPHRlbXBsYXRlPiB0byAiICsKICAgICAgICAgICJkZW5vdGUgc2NvcGVkIHNsb3RzLiIsCiAgICAgICAgICBlbC5yYXdBdHRyc01hcFsnc2NvcGUnXSwKICAgICAgICAgIHRydWUKICAgICAgICApOwogICAgICB9CiAgICAgIGVsLnNsb3RTY29wZSA9IHNsb3RTY29wZSB8fCBnZXRBbmRSZW1vdmVBdHRyKGVsLCAnc2xvdC1zY29wZScpOwogICAgfSBlbHNlIGlmICgoc2xvdFNjb3BlID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3Nsb3Qtc2NvcGUnKSkpIHsKICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICAgIGlmIChlbC5hdHRyc01hcFsndi1mb3InXSkgewogICAgICAgIHdhcm4kMigKICAgICAgICAgICJBbWJpZ3VvdXMgY29tYmluZWQgdXNhZ2Ugb2Ygc2xvdC1zY29wZSBhbmQgdi1mb3Igb24gPCIgKyAoZWwudGFnKSArICI+ICIgKwogICAgICAgICAgIih2LWZvciB0YWtlcyBoaWdoZXIgcHJpb3JpdHkpLiBVc2UgYSB3cmFwcGVyIDx0ZW1wbGF0ZT4gZm9yIHRoZSAiICsKICAgICAgICAgICJzY29wZWQgc2xvdCB0byBtYWtlIGl0IGNsZWFyZXIuIiwKICAgICAgICAgIGVsLnJhd0F0dHJzTWFwWydzbG90LXNjb3BlJ10sCiAgICAgICAgICB0cnVlCiAgICAgICAgKTsKICAgICAgfQogICAgICBlbC5zbG90U2NvcGUgPSBzbG90U2NvcGU7CiAgICB9CgogICAgLy8gc2xvdD0ieHh4IgogICAgdmFyIHNsb3RUYXJnZXQgPSBnZXRCaW5kaW5nQXR0cihlbCwgJ3Nsb3QnKTsKICAgIGlmIChzbG90VGFyZ2V0KSB7CiAgICAgIGVsLnNsb3RUYXJnZXQgPSBzbG90VGFyZ2V0ID09PSAnIiInID8gJyJkZWZhdWx0IicgOiBzbG90VGFyZ2V0OwogICAgICBlbC5zbG90VGFyZ2V0RHluYW1pYyA9ICEhKGVsLmF0dHJzTWFwWyc6c2xvdCddIHx8IGVsLmF0dHJzTWFwWyd2LWJpbmQ6c2xvdCddKTsKICAgICAgLy8gcHJlc2VydmUgc2xvdCBhcyBhbiBhdHRyaWJ1dGUgZm9yIG5hdGl2ZSBzaGFkb3cgRE9NIGNvbXBhdAogICAgICAvLyBvbmx5IGZvciBub24tc2NvcGVkIHNsb3RzLgogICAgICBpZiAoZWwudGFnICE9PSAndGVtcGxhdGUnICYmICFlbC5zbG90U2NvcGUpIHsKICAgICAgICBhZGRBdHRyKGVsLCAnc2xvdCcsIHNsb3RUYXJnZXQsIGdldFJhd0JpbmRpbmdBdHRyKGVsLCAnc2xvdCcpKTsKICAgICAgfQogICAgfQoKICAgIC8vIDIuNiB2LXNsb3Qgc3ludGF4CiAgICB7CiAgICAgIGlmIChlbC50YWcgPT09ICd0ZW1wbGF0ZScpIHsKICAgICAgICAvLyB2LXNsb3Qgb24gPHRlbXBsYXRlPgogICAgICAgIHZhciBzbG90QmluZGluZyA9IGdldEFuZFJlbW92ZUF0dHJCeVJlZ2V4KGVsLCBzbG90UkUpOwogICAgICAgIGlmIChzbG90QmluZGluZykgewogICAgICAgICAgewogICAgICAgICAgICBpZiAoZWwuc2xvdFRhcmdldCB8fCBlbC5zbG90U2NvcGUpIHsKICAgICAgICAgICAgICB3YXJuJDIoCiAgICAgICAgICAgICAgICAiVW5leHBlY3RlZCBtaXhlZCB1c2FnZSBvZiBkaWZmZXJlbnQgc2xvdCBzeW50YXhlcy4iLAogICAgICAgICAgICAgICAgZWwKICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChlbC5wYXJlbnQgJiYgIW1heWJlQ29tcG9uZW50KGVsLnBhcmVudCkpIHsKICAgICAgICAgICAgICB3YXJuJDIoCiAgICAgICAgICAgICAgICAiPHRlbXBsYXRlIHYtc2xvdD4gY2FuIG9ubHkgYXBwZWFyIGF0IHRoZSByb290IGxldmVsIGluc2lkZSAiICsKICAgICAgICAgICAgICAgICJ0aGUgcmVjZWl2aW5nIHRoZSBjb21wb25lbnQiLAogICAgICAgICAgICAgICAgZWwKICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICB2YXIgcmVmID0gZ2V0U2xvdE5hbWUoc2xvdEJpbmRpbmcpOwogICAgICAgICAgdmFyIG5hbWUgPSByZWYubmFtZTsKICAgICAgICAgIHZhciBkeW5hbWljID0gcmVmLmR5bmFtaWM7CiAgICAgICAgICBlbC5zbG90VGFyZ2V0ID0gbmFtZTsKICAgICAgICAgIGVsLnNsb3RUYXJnZXREeW5hbWljID0gZHluYW1pYzsKICAgICAgICAgIGVsLnNsb3RTY29wZSA9IHNsb3RCaW5kaW5nLnZhbHVlIHx8IGVtcHR5U2xvdFNjb3BlVG9rZW47IC8vIGZvcmNlIGl0IGludG8gYSBzY29wZWQgc2xvdCBmb3IgcGVyZgogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyB2LXNsb3Qgb24gY29tcG9uZW50LCBkZW5vdGVzIGRlZmF1bHQgc2xvdAogICAgICAgIHZhciBzbG90QmluZGluZyQxID0gZ2V0QW5kUmVtb3ZlQXR0ckJ5UmVnZXgoZWwsIHNsb3RSRSk7CiAgICAgICAgaWYgKHNsb3RCaW5kaW5nJDEpIHsKICAgICAgICAgIHsKICAgICAgICAgICAgaWYgKCFtYXliZUNvbXBvbmVudChlbCkpIHsKICAgICAgICAgICAgICB3YXJuJDIoCiAgICAgICAgICAgICAgICAidi1zbG90IGNhbiBvbmx5IGJlIHVzZWQgb24gY29tcG9uZW50cyBvciA8dGVtcGxhdGU+LiIsCiAgICAgICAgICAgICAgICBzbG90QmluZGluZyQxCiAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZWwuc2xvdFNjb3BlIHx8IGVsLnNsb3RUYXJnZXQpIHsKICAgICAgICAgICAgICB3YXJuJDIoCiAgICAgICAgICAgICAgICAiVW5leHBlY3RlZCBtaXhlZCB1c2FnZSBvZiBkaWZmZXJlbnQgc2xvdCBzeW50YXhlcy4iLAogICAgICAgICAgICAgICAgZWwKICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChlbC5zY29wZWRTbG90cykgewogICAgICAgICAgICAgIHdhcm4kMigKICAgICAgICAgICAgICAgICJUbyBhdm9pZCBzY29wZSBhbWJpZ3VpdHksIHRoZSBkZWZhdWx0IHNsb3Qgc2hvdWxkIGFsc28gdXNlICIgKwogICAgICAgICAgICAgICAgIjx0ZW1wbGF0ZT4gc3ludGF4IHdoZW4gdGhlcmUgYXJlIG90aGVyIG5hbWVkIHNsb3RzLiIsCiAgICAgICAgICAgICAgICBzbG90QmluZGluZyQxCiAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgLy8gYWRkIHRoZSBjb21wb25lbnQncyBjaGlsZHJlbiB0byBpdHMgZGVmYXVsdCBzbG90CiAgICAgICAgICB2YXIgc2xvdHMgPSBlbC5zY29wZWRTbG90cyB8fCAoZWwuc2NvcGVkU2xvdHMgPSB7fSk7CiAgICAgICAgICB2YXIgcmVmJDEgPSBnZXRTbG90TmFtZShzbG90QmluZGluZyQxKTsKICAgICAgICAgIHZhciBuYW1lJDEgPSByZWYkMS5uYW1lOwogICAgICAgICAgdmFyIGR5bmFtaWMkMSA9IHJlZiQxLmR5bmFtaWM7CiAgICAgICAgICB2YXIgc2xvdENvbnRhaW5lciA9IHNsb3RzW25hbWUkMV0gPSBjcmVhdGVBU1RFbGVtZW50KCd0ZW1wbGF0ZScsIFtdLCBlbCk7CiAgICAgICAgICBzbG90Q29udGFpbmVyLnNsb3RUYXJnZXQgPSBuYW1lJDE7CiAgICAgICAgICBzbG90Q29udGFpbmVyLnNsb3RUYXJnZXREeW5hbWljID0gZHluYW1pYyQxOwogICAgICAgICAgc2xvdENvbnRhaW5lci5jaGlsZHJlbiA9IGVsLmNoaWxkcmVuLmZpbHRlcihmdW5jdGlvbiAoYykgewogICAgICAgICAgICBpZiAoIWMuc2xvdFNjb3BlKSB7CiAgICAgICAgICAgICAgYy5wYXJlbnQgPSBzbG90Q29udGFpbmVyOwogICAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgICAgc2xvdENvbnRhaW5lci5zbG90U2NvcGUgPSBzbG90QmluZGluZyQxLnZhbHVlIHx8IGVtcHR5U2xvdFNjb3BlVG9rZW47CiAgICAgICAgICAvLyByZW1vdmUgY2hpbGRyZW4gYXMgdGhleSBhcmUgcmV0dXJuZWQgZnJvbSBzY29wZWRTbG90cyBub3cKICAgICAgICAgIGVsLmNoaWxkcmVuID0gW107CiAgICAgICAgICAvLyBtYXJrIGVsIG5vbi1wbGFpbiBzbyBkYXRhIGdldHMgZ2VuZXJhdGVkCiAgICAgICAgICBlbC5wbGFpbiA9IGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgZnVuY3Rpb24gZ2V0U2xvdE5hbWUgKGJpbmRpbmcpIHsKICAgIHZhciBuYW1lID0gYmluZGluZy5uYW1lLnJlcGxhY2Uoc2xvdFJFLCAnJyk7CiAgICBpZiAoIW5hbWUpIHsKICAgICAgaWYgKGJpbmRpbmcubmFtZVswXSAhPT0gJyMnKSB7CiAgICAgICAgbmFtZSA9ICdkZWZhdWx0JzsKICAgICAgfSBlbHNlIHsKICAgICAgICB3YXJuJDIoCiAgICAgICAgICAidi1zbG90IHNob3J0aGFuZCBzeW50YXggcmVxdWlyZXMgYSBzbG90IG5hbWUuIiwKICAgICAgICAgIGJpbmRpbmcKICAgICAgICApOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gZHluYW1pY0FyZ1JFLnRlc3QobmFtZSkKICAgICAgLy8gZHluYW1pYyBbbmFtZV0KICAgICAgPyB7IG5hbWU6IG5hbWUuc2xpY2UoMSwgLTEpLCBkeW5hbWljOiB0cnVlIH0KICAgICAgLy8gc3RhdGljIG5hbWUKICAgICAgOiB7IG5hbWU6ICgiXCIiICsgbmFtZSArICJcIiIpLCBkeW5hbWljOiBmYWxzZSB9CiAgfQoKICAvLyBoYW5kbGUgPHNsb3QvPiBvdXRsZXRzCiAgZnVuY3Rpb24gcHJvY2Vzc1Nsb3RPdXRsZXQgKGVsKSB7CiAgICBpZiAoZWwudGFnID09PSAnc2xvdCcpIHsKICAgICAgZWwuc2xvdE5hbWUgPSBnZXRCaW5kaW5nQXR0cihlbCwgJ25hbWUnKTsKICAgICAgaWYgKGVsLmtleSkgewogICAgICAgIHdhcm4kMigKICAgICAgICAgICJga2V5YCBkb2VzIG5vdCB3b3JrIG9uIDxzbG90PiBiZWNhdXNlIHNsb3RzIGFyZSBhYnN0cmFjdCBvdXRsZXRzICIgKwogICAgICAgICAgImFuZCBjYW4gcG9zc2libHkgZXhwYW5kIGludG8gbXVsdGlwbGUgZWxlbWVudHMuICIgKwogICAgICAgICAgIlVzZSB0aGUga2V5IG9uIGEgd3JhcHBpbmcgZWxlbWVudCBpbnN0ZWFkLiIsCiAgICAgICAgICBnZXRSYXdCaW5kaW5nQXR0cihlbCwgJ2tleScpCiAgICAgICAgKTsKICAgICAgfQogICAgfQogIH0KCiAgZnVuY3Rpb24gcHJvY2Vzc0NvbXBvbmVudCAoZWwpIHsKICAgIHZhciBiaW5kaW5nOwogICAgaWYgKChiaW5kaW5nID0gZ2V0QmluZGluZ0F0dHIoZWwsICdpcycpKSkgewogICAgICBlbC5jb21wb25lbnQgPSBiaW5kaW5nOwogICAgfQogICAgaWYgKGdldEFuZFJlbW92ZUF0dHIoZWwsICdpbmxpbmUtdGVtcGxhdGUnKSAhPSBudWxsKSB7CiAgICAgIGVsLmlubGluZVRlbXBsYXRlID0gdHJ1ZTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIHByb2Nlc3NBdHRycyAoZWwpIHsKICAgIHZhciBsaXN0ID0gZWwuYXR0cnNMaXN0OwogICAgdmFyIGksIGwsIG5hbWUsIHJhd05hbWUsIHZhbHVlLCBtb2RpZmllcnMsIHN5bmNHZW4sIGlzRHluYW1pYzsKICAgIGZvciAoaSA9IDAsIGwgPSBsaXN0Lmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICBuYW1lID0gcmF3TmFtZSA9IGxpc3RbaV0ubmFtZTsKICAgICAgdmFsdWUgPSBsaXN0W2ldLnZhbHVlOwogICAgICBpZiAoZGlyUkUudGVzdChuYW1lKSkgewogICAgICAgIC8vIG1hcmsgZWxlbWVudCBhcyBkeW5hbWljCiAgICAgICAgZWwuaGFzQmluZGluZ3MgPSB0cnVlOwogICAgICAgIC8vIG1vZGlmaWVycwogICAgICAgIG1vZGlmaWVycyA9IHBhcnNlTW9kaWZpZXJzKG5hbWUucmVwbGFjZShkaXJSRSwgJycpKTsKICAgICAgICAvLyBzdXBwb3J0IC5mb28gc2hvcnRoYW5kIHN5bnRheCBmb3IgdGhlIC5wcm9wIG1vZGlmaWVyCiAgICAgICAgaWYgKG1vZGlmaWVycykgewogICAgICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZShtb2RpZmllclJFLCAnJyk7CiAgICAgICAgfQogICAgICAgIGlmIChiaW5kUkUudGVzdChuYW1lKSkgeyAvLyB2LWJpbmQKICAgICAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoYmluZFJFLCAnJyk7CiAgICAgICAgICB2YWx1ZSA9IHBhcnNlRmlsdGVycyh2YWx1ZSk7CiAgICAgICAgICBpc0R5bmFtaWMgPSBkeW5hbWljQXJnUkUudGVzdChuYW1lKTsKICAgICAgICAgIGlmIChpc0R5bmFtaWMpIHsKICAgICAgICAgICAgbmFtZSA9IG5hbWUuc2xpY2UoMSwgLTEpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKAogICAgICAgICAgICB2YWx1ZS50cmltKCkubGVuZ3RoID09PSAwCiAgICAgICAgICApIHsKICAgICAgICAgICAgd2FybiQyKAogICAgICAgICAgICAgICgiVGhlIHZhbHVlIGZvciBhIHYtYmluZCBleHByZXNzaW9uIGNhbm5vdCBiZSBlbXB0eS4gRm91bmQgaW4gXCJ2LWJpbmQ6IiArIG5hbWUgKyAiXCIiKQogICAgICAgICAgICApOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG1vZGlmaWVycykgewogICAgICAgICAgICBpZiAobW9kaWZpZXJzLnByb3AgJiYgIWlzRHluYW1pYykgewogICAgICAgICAgICAgIG5hbWUgPSBjYW1lbGl6ZShuYW1lKTsKICAgICAgICAgICAgICBpZiAobmFtZSA9PT0gJ2lubmVySHRtbCcpIHsgbmFtZSA9ICdpbm5lckhUTUwnOyB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG1vZGlmaWVycy5jYW1lbCAmJiAhaXNEeW5hbWljKSB7CiAgICAgICAgICAgICAgbmFtZSA9IGNhbWVsaXplKG5hbWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChtb2RpZmllcnMuc3luYykgewogICAgICAgICAgICAgIHN5bmNHZW4gPSBnZW5Bc3NpZ25tZW50Q29kZSh2YWx1ZSwgIiRldmVudCIpOwogICAgICAgICAgICAgIGlmICghaXNEeW5hbWljKSB7CiAgICAgICAgICAgICAgICBhZGRIYW5kbGVyKAogICAgICAgICAgICAgICAgICBlbCwKICAgICAgICAgICAgICAgICAgKCJ1cGRhdGU6IiArIChjYW1lbGl6ZShuYW1lKSkpLAogICAgICAgICAgICAgICAgICBzeW5jR2VuLAogICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgd2FybiQyLAogICAgICAgICAgICAgICAgICBsaXN0W2ldCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgaWYgKGh5cGhlbmF0ZShuYW1lKSAhPT0gY2FtZWxpemUobmFtZSkpIHsKICAgICAgICAgICAgICAgICAgYWRkSGFuZGxlcigKICAgICAgICAgICAgICAgICAgICBlbCwKICAgICAgICAgICAgICAgICAgICAoInVwZGF0ZToiICsgKGh5cGhlbmF0ZShuYW1lKSkpLAogICAgICAgICAgICAgICAgICAgIHN5bmNHZW4sCiAgICAgICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgICB3YXJuJDIsCiAgICAgICAgICAgICAgICAgICAgbGlzdFtpXQogICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBoYW5kbGVyIHcvIGR5bmFtaWMgZXZlbnQgbmFtZQogICAgICAgICAgICAgICAgYWRkSGFuZGxlcigKICAgICAgICAgICAgICAgICAgZWwsCiAgICAgICAgICAgICAgICAgICgiXCJ1cGRhdGU6XCIrKCIgKyBuYW1lICsgIikiKSwKICAgICAgICAgICAgICAgICAgc3luY0dlbiwKICAgICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIHdhcm4kMiwKICAgICAgICAgICAgICAgICAgbGlzdFtpXSwKICAgICAgICAgICAgICAgICAgdHJ1ZSAvLyBkeW5hbWljCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgaWYgKChtb2RpZmllcnMgJiYgbW9kaWZpZXJzLnByb3ApIHx8ICgKICAgICAgICAgICAgIWVsLmNvbXBvbmVudCAmJiBwbGF0Zm9ybU11c3RVc2VQcm9wKGVsLnRhZywgZWwuYXR0cnNNYXAudHlwZSwgbmFtZSkKICAgICAgICAgICkpIHsKICAgICAgICAgICAgYWRkUHJvcChlbCwgbmFtZSwgdmFsdWUsIGxpc3RbaV0sIGlzRHluYW1pYyk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBhZGRBdHRyKGVsLCBuYW1lLCB2YWx1ZSwgbGlzdFtpXSwgaXNEeW5hbWljKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKG9uUkUudGVzdChuYW1lKSkgeyAvLyB2LW9uCiAgICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKG9uUkUsICcnKTsKICAgICAgICAgIGlzRHluYW1pYyA9IGR5bmFtaWNBcmdSRS50ZXN0KG5hbWUpOwogICAgICAgICAgaWYgKGlzRHluYW1pYykgewogICAgICAgICAgICBuYW1lID0gbmFtZS5zbGljZSgxLCAtMSk7CiAgICAgICAgICB9CiAgICAgICAgICBhZGRIYW5kbGVyKGVsLCBuYW1lLCB2YWx1ZSwgbW9kaWZpZXJzLCBmYWxzZSwgd2FybiQyLCBsaXN0W2ldLCBpc0R5bmFtaWMpOwogICAgICAgIH0gZWxzZSB7IC8vIG5vcm1hbCBkaXJlY3RpdmVzCiAgICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKGRpclJFLCAnJyk7CiAgICAgICAgICAvLyBwYXJzZSBhcmcKICAgICAgICAgIHZhciBhcmdNYXRjaCA9IG5hbWUubWF0Y2goYXJnUkUpOwogICAgICAgICAgdmFyIGFyZyA9IGFyZ01hdGNoICYmIGFyZ01hdGNoWzFdOwogICAgICAgICAgaXNEeW5hbWljID0gZmFsc2U7CiAgICAgICAgICBpZiAoYXJnKSB7CiAgICAgICAgICAgIG5hbWUgPSBuYW1lLnNsaWNlKDAsIC0oYXJnLmxlbmd0aCArIDEpKTsKICAgICAgICAgICAgaWYgKGR5bmFtaWNBcmdSRS50ZXN0KGFyZykpIHsKICAgICAgICAgICAgICBhcmcgPSBhcmcuc2xpY2UoMSwgLTEpOwogICAgICAgICAgICAgIGlzRHluYW1pYyA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGFkZERpcmVjdGl2ZShlbCwgbmFtZSwgcmF3TmFtZSwgdmFsdWUsIGFyZywgaXNEeW5hbWljLCBtb2RpZmllcnMsIGxpc3RbaV0pOwogICAgICAgICAgaWYgKG5hbWUgPT09ICdtb2RlbCcpIHsKICAgICAgICAgICAgY2hlY2tGb3JBbGlhc01vZGVsKGVsLCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIGxpdGVyYWwgYXR0cmlidXRlCiAgICAgICAgewogICAgICAgICAgdmFyIHJlcyA9IHBhcnNlVGV4dCh2YWx1ZSwgZGVsaW1pdGVycyk7CiAgICAgICAgICBpZiAocmVzKSB7CiAgICAgICAgICAgIHdhcm4kMigKICAgICAgICAgICAgICBuYW1lICsgIj1cIiIgKyB2YWx1ZSArICJcIjogIiArCiAgICAgICAgICAgICAgJ0ludGVycG9sYXRpb24gaW5zaWRlIGF0dHJpYnV0ZXMgaGFzIGJlZW4gcmVtb3ZlZC4gJyArCiAgICAgICAgICAgICAgJ1VzZSB2LWJpbmQgb3IgdGhlIGNvbG9uIHNob3J0aGFuZCBpbnN0ZWFkLiBGb3IgZXhhbXBsZSwgJyArCiAgICAgICAgICAgICAgJ2luc3RlYWQgb2YgPGRpdiBpZD0ie3sgdmFsIH19Ij4sIHVzZSA8ZGl2IDppZD0idmFsIj4uJywKICAgICAgICAgICAgICBsaXN0W2ldCiAgICAgICAgICAgICk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFkZEF0dHIoZWwsIG5hbWUsIEpTT04uc3RyaW5naWZ5KHZhbHVlKSwgbGlzdFtpXSk7CiAgICAgICAgLy8gIzY4ODcgZmlyZWZveCBkb2Vzbid0IHVwZGF0ZSBtdXRlZCBzdGF0ZSBpZiBzZXQgdmlhIGF0dHJpYnV0ZQogICAgICAgIC8vIGV2ZW4gaW1tZWRpYXRlbHkgYWZ0ZXIgZWxlbWVudCBjcmVhdGlvbgogICAgICAgIGlmICghZWwuY29tcG9uZW50ICYmCiAgICAgICAgICAgIG5hbWUgPT09ICdtdXRlZCcgJiYKICAgICAgICAgICAgcGxhdGZvcm1NdXN0VXNlUHJvcChlbC50YWcsIGVsLmF0dHJzTWFwLnR5cGUsIG5hbWUpKSB7CiAgICAgICAgICBhZGRQcm9wKGVsLCBuYW1lLCAndHJ1ZScsIGxpc3RbaV0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgZnVuY3Rpb24gY2hlY2tJbkZvciAoZWwpIHsKICAgIHZhciBwYXJlbnQgPSBlbDsKICAgIHdoaWxlIChwYXJlbnQpIHsKICAgICAgaWYgKHBhcmVudC5mb3IgIT09IHVuZGVmaW5lZCkgewogICAgICAgIHJldHVybiB0cnVlCiAgICAgIH0KICAgICAgcGFyZW50ID0gcGFyZW50LnBhcmVudDsKICAgIH0KICAgIHJldHVybiBmYWxzZQogIH0KCiAgZnVuY3Rpb24gcGFyc2VNb2RpZmllcnMgKG5hbWUpIHsKICAgIHZhciBtYXRjaCA9IG5hbWUubWF0Y2gobW9kaWZpZXJSRSk7CiAgICBpZiAobWF0Y2gpIHsKICAgICAgdmFyIHJldCA9IHt9OwogICAgICBtYXRjaC5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7IHJldFttLnNsaWNlKDEpXSA9IHRydWU7IH0pOwogICAgICByZXR1cm4gcmV0CiAgICB9CiAgfQoKICBmdW5jdGlvbiBtYWtlQXR0cnNNYXAgKGF0dHJzKSB7CiAgICB2YXIgbWFwID0ge307CiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGF0dHJzLmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICBpZiAoCiAgICAgICAgbWFwW2F0dHJzW2ldLm5hbWVdICYmICFpc0lFICYmICFpc0VkZ2UKICAgICAgKSB7CiAgICAgICAgd2FybiQyKCdkdXBsaWNhdGUgYXR0cmlidXRlOiAnICsgYXR0cnNbaV0ubmFtZSwgYXR0cnNbaV0pOwogICAgICB9CiAgICAgIG1hcFthdHRyc1tpXS5uYW1lXSA9IGF0dHJzW2ldLnZhbHVlOwogICAgfQogICAgcmV0dXJuIG1hcAogIH0KCiAgLy8gZm9yIHNjcmlwdCAoZS5nLiB0eXBlPSJ4L3RlbXBsYXRlIikgb3Igc3R5bGUsIGRvIG5vdCBkZWNvZGUgY29udGVudAogIGZ1bmN0aW9uIGlzVGV4dFRhZyAoZWwpIHsKICAgIHJldHVybiBlbC50YWcgPT09ICdzY3JpcHQnIHx8IGVsLnRhZyA9PT0gJ3N0eWxlJwogIH0KCiAgZnVuY3Rpb24gaXNGb3JiaWRkZW5UYWcgKGVsKSB7CiAgICByZXR1cm4gKAogICAgICBlbC50YWcgPT09ICdzdHlsZScgfHwKICAgICAgKGVsLnRhZyA9PT0gJ3NjcmlwdCcgJiYgKAogICAgICAgICFlbC5hdHRyc01hcC50eXBlIHx8CiAgICAgICAgZWwuYXR0cnNNYXAudHlwZSA9PT0gJ3RleHQvamF2YXNjcmlwdCcKICAgICAgKSkKICAgICkKICB9CgogIHZhciBpZU5TQnVnID0gL154bWxuczpOU1xkKy87CiAgdmFyIGllTlNQcmVmaXggPSAvXk5TXGQrOi87CgogIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovCiAgZnVuY3Rpb24gZ3VhcmRJRVNWR0J1ZyAoYXR0cnMpIHsKICAgIHZhciByZXMgPSBbXTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXR0cnMubGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIGF0dHIgPSBhdHRyc1tpXTsKICAgICAgaWYgKCFpZU5TQnVnLnRlc3QoYXR0ci5uYW1lKSkgewogICAgICAgIGF0dHIubmFtZSA9IGF0dHIubmFtZS5yZXBsYWNlKGllTlNQcmVmaXgsICcnKTsKICAgICAgICByZXMucHVzaChhdHRyKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlcwogIH0KCiAgZnVuY3Rpb24gY2hlY2tGb3JBbGlhc01vZGVsIChlbCwgdmFsdWUpIHsKICAgIHZhciBfZWwgPSBlbDsKICAgIHdoaWxlIChfZWwpIHsKICAgICAgaWYgKF9lbC5mb3IgJiYgX2VsLmFsaWFzID09PSB2YWx1ZSkgewogICAgICAgIHdhcm4kMigKICAgICAgICAgICI8IiArIChlbC50YWcpICsgIiB2LW1vZGVsPVwiIiArIHZhbHVlICsgIlwiPjogIiArCiAgICAgICAgICAiWW91IGFyZSBiaW5kaW5nIHYtbW9kZWwgZGlyZWN0bHkgdG8gYSB2LWZvciBpdGVyYXRpb24gYWxpYXMuICIgKwogICAgICAgICAgIlRoaXMgd2lsbCBub3QgYmUgYWJsZSB0byBtb2RpZnkgdGhlIHYtZm9yIHNvdXJjZSBhcnJheSBiZWNhdXNlICIgKwogICAgICAgICAgIndyaXRpbmcgdG8gdGhlIGFsaWFzIGlzIGxpa2UgbW9kaWZ5aW5nIGEgZnVuY3Rpb24gbG9jYWwgdmFyaWFibGUuICIgKwogICAgICAgICAgIkNvbnNpZGVyIHVzaW5nIGFuIGFycmF5IG9mIG9iamVjdHMgYW5kIHVzZSB2LW1vZGVsIG9uIGFuIG9iamVjdCBwcm9wZXJ0eSBpbnN0ZWFkLiIsCiAgICAgICAgICBlbC5yYXdBdHRyc01hcFsndi1tb2RlbCddCiAgICAgICAgKTsKICAgICAgfQogICAgICBfZWwgPSBfZWwucGFyZW50OwogICAgfQogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIHByZVRyYW5zZm9ybU5vZGUgKGVsLCBvcHRpb25zKSB7CiAgICBpZiAoZWwudGFnID09PSAnaW5wdXQnKSB7CiAgICAgIHZhciBtYXAgPSBlbC5hdHRyc01hcDsKICAgICAgaWYgKCFtYXBbJ3YtbW9kZWwnXSkgewogICAgICAgIHJldHVybgogICAgICB9CgogICAgICB2YXIgdHlwZUJpbmRpbmc7CiAgICAgIGlmIChtYXBbJzp0eXBlJ10gfHwgbWFwWyd2LWJpbmQ6dHlwZSddKSB7CiAgICAgICAgdHlwZUJpbmRpbmcgPSBnZXRCaW5kaW5nQXR0cihlbCwgJ3R5cGUnKTsKICAgICAgfQogICAgICBpZiAoIW1hcC50eXBlICYmICF0eXBlQmluZGluZyAmJiBtYXBbJ3YtYmluZCddKSB7CiAgICAgICAgdHlwZUJpbmRpbmcgPSAiKCIgKyAobWFwWyd2LWJpbmQnXSkgKyAiKS50eXBlIjsKICAgICAgfQoKICAgICAgaWYgKHR5cGVCaW5kaW5nKSB7CiAgICAgICAgdmFyIGlmQ29uZGl0aW9uID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3YtaWYnLCB0cnVlKTsKICAgICAgICB2YXIgaWZDb25kaXRpb25FeHRyYSA9IGlmQ29uZGl0aW9uID8gKCImJigiICsgaWZDb25kaXRpb24gKyAiKSIpIDogIiI7CiAgICAgICAgdmFyIGhhc0Vsc2UgPSBnZXRBbmRSZW1vdmVBdHRyKGVsLCAndi1lbHNlJywgdHJ1ZSkgIT0gbnVsbDsKICAgICAgICB2YXIgZWxzZUlmQ29uZGl0aW9uID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3YtZWxzZS1pZicsIHRydWUpOwogICAgICAgIC8vIDEuIGNoZWNrYm94CiAgICAgICAgdmFyIGJyYW5jaDAgPSBjbG9uZUFTVEVsZW1lbnQoZWwpOwogICAgICAgIC8vIHByb2Nlc3MgZm9yIG9uIHRoZSBtYWluIG5vZGUKICAgICAgICBwcm9jZXNzRm9yKGJyYW5jaDApOwogICAgICAgIGFkZFJhd0F0dHIoYnJhbmNoMCwgJ3R5cGUnLCAnY2hlY2tib3gnKTsKICAgICAgICBwcm9jZXNzRWxlbWVudChicmFuY2gwLCBvcHRpb25zKTsKICAgICAgICBicmFuY2gwLnByb2Nlc3NlZCA9IHRydWU7IC8vIHByZXZlbnQgaXQgZnJvbSBkb3VibGUtcHJvY2Vzc2VkCiAgICAgICAgYnJhbmNoMC5pZiA9ICIoIiArIHR5cGVCaW5kaW5nICsgIik9PT0nY2hlY2tib3gnIiArIGlmQ29uZGl0aW9uRXh0cmE7CiAgICAgICAgYWRkSWZDb25kaXRpb24oYnJhbmNoMCwgewogICAgICAgICAgZXhwOiBicmFuY2gwLmlmLAogICAgICAgICAgYmxvY2s6IGJyYW5jaDAKICAgICAgICB9KTsKICAgICAgICAvLyAyLiBhZGQgcmFkaW8gZWxzZS1pZiBjb25kaXRpb24KICAgICAgICB2YXIgYnJhbmNoMSA9IGNsb25lQVNURWxlbWVudChlbCk7CiAgICAgICAgZ2V0QW5kUmVtb3ZlQXR0cihicmFuY2gxLCAndi1mb3InLCB0cnVlKTsKICAgICAgICBhZGRSYXdBdHRyKGJyYW5jaDEsICd0eXBlJywgJ3JhZGlvJyk7CiAgICAgICAgcHJvY2Vzc0VsZW1lbnQoYnJhbmNoMSwgb3B0aW9ucyk7CiAgICAgICAgYWRkSWZDb25kaXRpb24oYnJhbmNoMCwgewogICAgICAgICAgZXhwOiAiKCIgKyB0eXBlQmluZGluZyArICIpPT09J3JhZGlvJyIgKyBpZkNvbmRpdGlvbkV4dHJhLAogICAgICAgICAgYmxvY2s6IGJyYW5jaDEKICAgICAgICB9KTsKICAgICAgICAvLyAzLiBvdGhlcgogICAgICAgIHZhciBicmFuY2gyID0gY2xvbmVBU1RFbGVtZW50KGVsKTsKICAgICAgICBnZXRBbmRSZW1vdmVBdHRyKGJyYW5jaDIsICd2LWZvcicsIHRydWUpOwogICAgICAgIGFkZFJhd0F0dHIoYnJhbmNoMiwgJzp0eXBlJywgdHlwZUJpbmRpbmcpOwogICAgICAgIHByb2Nlc3NFbGVtZW50KGJyYW5jaDIsIG9wdGlvbnMpOwogICAgICAgIGFkZElmQ29uZGl0aW9uKGJyYW5jaDAsIHsKICAgICAgICAgIGV4cDogaWZDb25kaXRpb24sCiAgICAgICAgICBibG9jazogYnJhbmNoMgogICAgICAgIH0pOwoKICAgICAgICBpZiAoaGFzRWxzZSkgewogICAgICAgICAgYnJhbmNoMC5lbHNlID0gdHJ1ZTsKICAgICAgICB9IGVsc2UgaWYgKGVsc2VJZkNvbmRpdGlvbikgewogICAgICAgICAgYnJhbmNoMC5lbHNlaWYgPSBlbHNlSWZDb25kaXRpb247CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYnJhbmNoMAogICAgICB9CiAgICB9CiAgfQoKICBmdW5jdGlvbiBjbG9uZUFTVEVsZW1lbnQgKGVsKSB7CiAgICByZXR1cm4gY3JlYXRlQVNURWxlbWVudChlbC50YWcsIGVsLmF0dHJzTGlzdC5zbGljZSgpLCBlbC5wYXJlbnQpCiAgfQoKICB2YXIgbW9kZWwkMSA9IHsKICAgIHByZVRyYW5zZm9ybU5vZGU6IHByZVRyYW5zZm9ybU5vZGUKICB9OwoKICB2YXIgbW9kdWxlcyQxID0gWwogICAga2xhc3MkMSwKICAgIHN0eWxlJDEsCiAgICBtb2RlbCQxCiAgXTsKCiAgLyogICovCgogIGZ1bmN0aW9uIHRleHQgKGVsLCBkaXIpIHsKICAgIGlmIChkaXIudmFsdWUpIHsKICAgICAgYWRkUHJvcChlbCwgJ3RleHRDb250ZW50JywgKCJfcygiICsgKGRpci52YWx1ZSkgKyAiKSIpLCBkaXIpOwogICAgfQogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIGh0bWwgKGVsLCBkaXIpIHsKICAgIGlmIChkaXIudmFsdWUpIHsKICAgICAgYWRkUHJvcChlbCwgJ2lubmVySFRNTCcsICgiX3MoIiArIChkaXIudmFsdWUpICsgIikiKSwgZGlyKTsKICAgIH0KICB9CgogIHZhciBkaXJlY3RpdmVzJDEgPSB7CiAgICBtb2RlbDogbW9kZWwsCiAgICB0ZXh0OiB0ZXh0LAogICAgaHRtbDogaHRtbAogIH07CgogIC8qICAqLwoKICB2YXIgYmFzZU9wdGlvbnMgPSB7CiAgICBleHBlY3RIVE1MOiB0cnVlLAogICAgbW9kdWxlczogbW9kdWxlcyQxLAogICAgZGlyZWN0aXZlczogZGlyZWN0aXZlcyQxLAogICAgaXNQcmVUYWc6IGlzUHJlVGFnLAogICAgaXNVbmFyeVRhZzogaXNVbmFyeVRhZywKICAgIG11c3RVc2VQcm9wOiBtdXN0VXNlUHJvcCwKICAgIGNhbkJlTGVmdE9wZW5UYWc6IGNhbkJlTGVmdE9wZW5UYWcsCiAgICBpc1Jlc2VydmVkVGFnOiBpc1Jlc2VydmVkVGFnLAogICAgZ2V0VGFnTmFtZXNwYWNlOiBnZXRUYWdOYW1lc3BhY2UsCiAgICBzdGF0aWNLZXlzOiBnZW5TdGF0aWNLZXlzKG1vZHVsZXMkMSkKICB9OwoKICAvKiAgKi8KCiAgdmFyIGlzU3RhdGljS2V5OwogIHZhciBpc1BsYXRmb3JtUmVzZXJ2ZWRUYWc7CgogIHZhciBnZW5TdGF0aWNLZXlzQ2FjaGVkID0gY2FjaGVkKGdlblN0YXRpY0tleXMkMSk7CgogIC8qKgogICAqIEdvYWwgb2YgdGhlIG9wdGltaXplcjogd2FsayB0aGUgZ2VuZXJhdGVkIHRlbXBsYXRlIEFTVCB0cmVlCiAgICogYW5kIGRldGVjdCBzdWItdHJlZXMgdGhhdCBhcmUgcHVyZWx5IHN0YXRpYywgaS5lLiBwYXJ0cyBvZgogICAqIHRoZSBET00gdGhhdCBuZXZlciBuZWVkcyB0byBjaGFuZ2UuCiAgICoKICAgKiBPbmNlIHdlIGRldGVjdCB0aGVzZSBzdWItdHJlZXMsIHdlIGNhbjoKICAgKgogICAqIDEuIEhvaXN0IHRoZW0gaW50byBjb25zdGFudHMsIHNvIHRoYXQgd2Ugbm8gbG9uZ2VyIG5lZWQgdG8KICAgKiAgICBjcmVhdGUgZnJlc2ggbm9kZXMgZm9yIHRoZW0gb24gZWFjaCByZS1yZW5kZXI7CiAgICogMi4gQ29tcGxldGVseSBza2lwIHRoZW0gaW4gdGhlIHBhdGNoaW5nIHByb2Nlc3MuCiAgICovCiAgZnVuY3Rpb24gb3B0aW1pemUgKHJvb3QsIG9wdGlvbnMpIHsKICAgIGlmICghcm9vdCkgeyByZXR1cm4gfQogICAgaXNTdGF0aWNLZXkgPSBnZW5TdGF0aWNLZXlzQ2FjaGVkKG9wdGlvbnMuc3RhdGljS2V5cyB8fCAnJyk7CiAgICBpc1BsYXRmb3JtUmVzZXJ2ZWRUYWcgPSBvcHRpb25zLmlzUmVzZXJ2ZWRUYWcgfHwgbm87CiAgICAvLyBmaXJzdCBwYXNzOiBtYXJrIGFsbCBub24tc3RhdGljIG5vZGVzLgogICAgbWFya1N0YXRpYyQxKHJvb3QpOwogICAgLy8gc2Vjb25kIHBhc3M6IG1hcmsgc3RhdGljIHJvb3RzLgogICAgbWFya1N0YXRpY1Jvb3RzKHJvb3QsIGZhbHNlKTsKICB9CgogIGZ1bmN0aW9uIGdlblN0YXRpY0tleXMkMSAoa2V5cykgewogICAgcmV0dXJuIG1ha2VNYXAoCiAgICAgICd0eXBlLHRhZyxhdHRyc0xpc3QsYXR0cnNNYXAscGxhaW4scGFyZW50LGNoaWxkcmVuLGF0dHJzLHN0YXJ0LGVuZCxyYXdBdHRyc01hcCcgKwogICAgICAoa2V5cyA/ICcsJyArIGtleXMgOiAnJykKICAgICkKICB9CgogIGZ1bmN0aW9uIG1hcmtTdGF0aWMkMSAobm9kZSkgewogICAgbm9kZS5zdGF0aWMgPSBpc1N0YXRpYyhub2RlKTsKICAgIGlmIChub2RlLnR5cGUgPT09IDEpIHsKICAgICAgLy8gZG8gbm90IG1ha2UgY29tcG9uZW50IHNsb3QgY29udGVudCBzdGF0aWMuIHRoaXMgYXZvaWRzCiAgICAgIC8vIDEuIGNvbXBvbmVudHMgbm90IGFibGUgdG8gbXV0YXRlIHNsb3Qgbm9kZXMKICAgICAgLy8gMi4gc3RhdGljIHNsb3QgY29udGVudCBmYWlscyBmb3IgaG90LXJlbG9hZGluZwogICAgICBpZiAoCiAgICAgICAgIWlzUGxhdGZvcm1SZXNlcnZlZFRhZyhub2RlLnRhZykgJiYKICAgICAgICBub2RlLnRhZyAhPT0gJ3Nsb3QnICYmCiAgICAgICAgbm9kZS5hdHRyc01hcFsnaW5saW5lLXRlbXBsYXRlJ10gPT0gbnVsbAogICAgICApIHsKICAgICAgICByZXR1cm4KICAgICAgfQogICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7CiAgICAgICAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZHJlbltpXTsKICAgICAgICBtYXJrU3RhdGljJDEoY2hpbGQpOwogICAgICAgIGlmICghY2hpbGQuc3RhdGljKSB7CiAgICAgICAgICBub2RlLnN0YXRpYyA9IGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAobm9kZS5pZkNvbmRpdGlvbnMpIHsKICAgICAgICBmb3IgKHZhciBpJDEgPSAxLCBsJDEgPSBub2RlLmlmQ29uZGl0aW9ucy5sZW5ndGg7IGkkMSA8IGwkMTsgaSQxKyspIHsKICAgICAgICAgIHZhciBibG9jayA9IG5vZGUuaWZDb25kaXRpb25zW2kkMV0uYmxvY2s7CiAgICAgICAgICBtYXJrU3RhdGljJDEoYmxvY2spOwogICAgICAgICAgaWYgKCFibG9jay5zdGF0aWMpIHsKICAgICAgICAgICAgbm9kZS5zdGF0aWMgPSBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIG1hcmtTdGF0aWNSb290cyAobm9kZSwgaXNJbkZvcikgewogICAgaWYgKG5vZGUudHlwZSA9PT0gMSkgewogICAgICBpZiAobm9kZS5zdGF0aWMgfHwgbm9kZS5vbmNlKSB7CiAgICAgICAgbm9kZS5zdGF0aWNJbkZvciA9IGlzSW5Gb3I7CiAgICAgIH0KICAgICAgLy8gRm9yIGEgbm9kZSB0byBxdWFsaWZ5IGFzIGEgc3RhdGljIHJvb3QsIGl0IHNob3VsZCBoYXZlIGNoaWxkcmVuIHRoYXQKICAgICAgLy8gYXJlIG5vdCBqdXN0IHN0YXRpYyB0ZXh0LiBPdGhlcndpc2UgdGhlIGNvc3Qgb2YgaG9pc3Rpbmcgb3V0IHdpbGwKICAgICAgLy8gb3V0d2VpZ2ggdGhlIGJlbmVmaXRzIGFuZCBpdCdzIGJldHRlciBvZmYgdG8ganVzdCBhbHdheXMgcmVuZGVyIGl0IGZyZXNoLgogICAgICBpZiAobm9kZS5zdGF0aWMgJiYgbm9kZS5jaGlsZHJlbi5sZW5ndGggJiYgISgKICAgICAgICBub2RlLmNoaWxkcmVuLmxlbmd0aCA9PT0gMSAmJgogICAgICAgIG5vZGUuY2hpbGRyZW5bMF0udHlwZSA9PT0gMwogICAgICApKSB7CiAgICAgICAgbm9kZS5zdGF0aWNSb290ID0gdHJ1ZTsKICAgICAgICByZXR1cm4KICAgICAgfSBlbHNlIHsKICAgICAgICBub2RlLnN0YXRpY1Jvb3QgPSBmYWxzZTsKICAgICAgfQogICAgICBpZiAobm9kZS5jaGlsZHJlbikgewogICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHsKICAgICAgICAgIG1hcmtTdGF0aWNSb290cyhub2RlLmNoaWxkcmVuW2ldLCBpc0luRm9yIHx8ICEhbm9kZS5mb3IpOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAobm9kZS5pZkNvbmRpdGlvbnMpIHsKICAgICAgICBmb3IgKHZhciBpJDEgPSAxLCBsJDEgPSBub2RlLmlmQ29uZGl0aW9ucy5sZW5ndGg7IGkkMSA8IGwkMTsgaSQxKyspIHsKICAgICAgICAgIG1hcmtTdGF0aWNSb290cyhub2RlLmlmQ29uZGl0aW9uc1tpJDFdLmJsb2NrLCBpc0luRm9yKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIGlzU3RhdGljIChub2RlKSB7CiAgICBpZiAobm9kZS50eXBlID09PSAyKSB7IC8vIGV4cHJlc3Npb24KICAgICAgcmV0dXJuIGZhbHNlCiAgICB9CiAgICBpZiAobm9kZS50eXBlID09PSAzKSB7IC8vIHRleHQKICAgICAgcmV0dXJuIHRydWUKICAgIH0KICAgIHJldHVybiAhIShub2RlLnByZSB8fCAoCiAgICAgICFub2RlLmhhc0JpbmRpbmdzICYmIC8vIG5vIGR5bmFtaWMgYmluZGluZ3MKICAgICAgIW5vZGUuaWYgJiYgIW5vZGUuZm9yICYmIC8vIG5vdCB2LWlmIG9yIHYtZm9yIG9yIHYtZWxzZQogICAgICAhaXNCdWlsdEluVGFnKG5vZGUudGFnKSAmJiAvLyBub3QgYSBidWlsdC1pbgogICAgICBpc1BsYXRmb3JtUmVzZXJ2ZWRUYWcobm9kZS50YWcpICYmIC8vIG5vdCBhIGNvbXBvbmVudAogICAgICAhaXNEaXJlY3RDaGlsZE9mVGVtcGxhdGVGb3Iobm9kZSkgJiYKICAgICAgT2JqZWN0LmtleXMobm9kZSkuZXZlcnkoaXNTdGF0aWNLZXkpCiAgICApKQogIH0KCiAgZnVuY3Rpb24gaXNEaXJlY3RDaGlsZE9mVGVtcGxhdGVGb3IgKG5vZGUpIHsKICAgIHdoaWxlIChub2RlLnBhcmVudCkgewogICAgICBub2RlID0gbm9kZS5wYXJlbnQ7CiAgICAgIGlmIChub2RlLnRhZyAhPT0gJ3RlbXBsYXRlJykgewogICAgICAgIHJldHVybiBmYWxzZQogICAgICB9CiAgICAgIGlmIChub2RlLmZvcikgewogICAgICAgIHJldHVybiB0cnVlCiAgICAgIH0KICAgIH0KICAgIHJldHVybiBmYWxzZQogIH0KCiAgLyogICovCgogIHZhciBmbkV4cFJFID0gL14oW1x3JF9dK3xcKFteKV0qP1wpKVxzKj0+fF5mdW5jdGlvblxzKig/OltcdyRdKyk/XHMqXCgvOwogIHZhciBmbkludm9rZVJFID0gL1woW14pXSo/XCk7KiQvOwogIHZhciBzaW1wbGVQYXRoUkUgPSAvXltBLVphLXpfJF1bXHckXSooPzpcLltBLVphLXpfJF1bXHckXSp8XFsnW14nXSo/J118XFsiW14iXSo/Il18XFtcZCtdfFxbW0EtWmEtel8kXVtcdyRdKl0pKiQvOwoKICAvLyBLZXlib2FyZEV2ZW50LmtleUNvZGUgYWxpYXNlcwogIHZhciBrZXlDb2RlcyA9IHsKICAgIGVzYzogMjcsCiAgICB0YWI6IDksCiAgICBlbnRlcjogMTMsCiAgICBzcGFjZTogMzIsCiAgICB1cDogMzgsCiAgICBsZWZ0OiAzNywKICAgIHJpZ2h0OiAzOSwKICAgIGRvd246IDQwLAogICAgJ2RlbGV0ZSc6IFs4LCA0Nl0KICB9OwoKICAvLyBLZXlib2FyZEV2ZW50LmtleSBhbGlhc2VzCiAgdmFyIGtleU5hbWVzID0gewogICAgLy8gIzc4ODA6IElFMTEgYW5kIEVkZ2UgdXNlIGBFc2NgIGZvciBFc2NhcGUga2V5IG5hbWUuCiAgICBlc2M6IFsnRXNjJywgJ0VzY2FwZSddLAogICAgdGFiOiAnVGFiJywKICAgIGVudGVyOiAnRW50ZXInLAogICAgLy8gIzkxMTI6IElFMTEgdXNlcyBgU3BhY2ViYXJgIGZvciBTcGFjZSBrZXkgbmFtZS4KICAgIHNwYWNlOiBbJyAnLCAnU3BhY2ViYXInXSwKICAgIC8vICM3ODA2OiBJRTExIHVzZXMga2V5IG5hbWVzIHdpdGhvdXQgYEFycm93YCBwcmVmaXggZm9yIGFycm93IGtleXMuCiAgICB1cDogWydVcCcsICdBcnJvd1VwJ10sCiAgICBsZWZ0OiBbJ0xlZnQnLCAnQXJyb3dMZWZ0J10sCiAgICByaWdodDogWydSaWdodCcsICdBcnJvd1JpZ2h0J10sCiAgICBkb3duOiBbJ0Rvd24nLCAnQXJyb3dEb3duJ10sCiAgICAvLyAjOTExMjogSUUxMSB1c2VzIGBEZWxgIGZvciBEZWxldGUga2V5IG5hbWUuCiAgICAnZGVsZXRlJzogWydCYWNrc3BhY2UnLCAnRGVsZXRlJywgJ0RlbCddCiAgfTsKCiAgLy8gIzQ4Njg6IG1vZGlmaWVycyB0aGF0IHByZXZlbnQgdGhlIGV4ZWN1dGlvbiBvZiB0aGUgbGlzdGVuZXIKICAvLyBuZWVkIHRvIGV4cGxpY2l0bHkgcmV0dXJuIG51bGwgc28gdGhhdCB3ZSBjYW4gZGV0ZXJtaW5lIHdoZXRoZXIgdG8gcmVtb3ZlCiAgLy8gdGhlIGxpc3RlbmVyIGZvciAub25jZQogIHZhciBnZW5HdWFyZCA9IGZ1bmN0aW9uIChjb25kaXRpb24pIHsgcmV0dXJuICgiaWYoIiArIGNvbmRpdGlvbiArICIpcmV0dXJuIG51bGw7Iik7IH07CgogIHZhciBtb2RpZmllckNvZGUgPSB7CiAgICBzdG9wOiAnJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOycsCiAgICBwcmV2ZW50OiAnJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7JywKICAgIHNlbGY6IGdlbkd1YXJkKCIkZXZlbnQudGFyZ2V0ICE9PSAkZXZlbnQuY3VycmVudFRhcmdldCIpLAogICAgY3RybDogZ2VuR3VhcmQoIiEkZXZlbnQuY3RybEtleSIpLAogICAgc2hpZnQ6IGdlbkd1YXJkKCIhJGV2ZW50LnNoaWZ0S2V5IiksCiAgICBhbHQ6IGdlbkd1YXJkKCIhJGV2ZW50LmFsdEtleSIpLAogICAgbWV0YTogZ2VuR3VhcmQoIiEkZXZlbnQubWV0YUtleSIpLAogICAgbGVmdDogZ2VuR3VhcmQoIididXR0b24nIGluICRldmVudCAmJiAkZXZlbnQuYnV0dG9uICE9PSAwIiksCiAgICBtaWRkbGU6IGdlbkd1YXJkKCInYnV0dG9uJyBpbiAkZXZlbnQgJiYgJGV2ZW50LmJ1dHRvbiAhPT0gMSIpLAogICAgcmlnaHQ6IGdlbkd1YXJkKCInYnV0dG9uJyBpbiAkZXZlbnQgJiYgJGV2ZW50LmJ1dHRvbiAhPT0gMiIpCiAgfTsKCiAgZnVuY3Rpb24gZ2VuSGFuZGxlcnMgKAogICAgZXZlbnRzLAogICAgaXNOYXRpdmUKICApIHsKICAgIHZhciBwcmVmaXggPSBpc05hdGl2ZSA/ICduYXRpdmVPbjonIDogJ29uOic7CiAgICB2YXIgc3RhdGljSGFuZGxlcnMgPSAiIjsKICAgIHZhciBkeW5hbWljSGFuZGxlcnMgPSAiIjsKICAgIGZvciAodmFyIG5hbWUgaW4gZXZlbnRzKSB7CiAgICAgIHZhciBoYW5kbGVyQ29kZSA9IGdlbkhhbmRsZXIoZXZlbnRzW25hbWVdKTsKICAgICAgaWYgKGV2ZW50c1tuYW1lXSAmJiBldmVudHNbbmFtZV0uZHluYW1pYykgewogICAgICAgIGR5bmFtaWNIYW5kbGVycyArPSBuYW1lICsgIiwiICsgaGFuZGxlckNvZGUgKyAiLCI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RhdGljSGFuZGxlcnMgKz0gIlwiIiArIG5hbWUgKyAiXCI6IiArIGhhbmRsZXJDb2RlICsgIiwiOwogICAgICB9CiAgICB9CiAgICBzdGF0aWNIYW5kbGVycyA9ICJ7IiArIChzdGF0aWNIYW5kbGVycy5zbGljZSgwLCAtMSkpICsgIn0iOwogICAgaWYgKGR5bmFtaWNIYW5kbGVycykgewogICAgICByZXR1cm4gcHJlZml4ICsgIl9kKCIgKyBzdGF0aWNIYW5kbGVycyArICIsWyIgKyAoZHluYW1pY0hhbmRsZXJzLnNsaWNlKDAsIC0xKSkgKyAiXSkiCiAgICB9IGVsc2UgewogICAgICByZXR1cm4gcHJlZml4ICsgc3RhdGljSGFuZGxlcnMKICAgIH0KICB9CgogIGZ1bmN0aW9uIGdlbkhhbmRsZXIgKGhhbmRsZXIpIHsKICAgIGlmICghaGFuZGxlcikgewogICAgICByZXR1cm4gJ2Z1bmN0aW9uKCl7fScKICAgIH0KCiAgICBpZiAoQXJyYXkuaXNBcnJheShoYW5kbGVyKSkgewogICAgICByZXR1cm4gKCJbIiArIChoYW5kbGVyLm1hcChmdW5jdGlvbiAoaGFuZGxlcikgeyByZXR1cm4gZ2VuSGFuZGxlcihoYW5kbGVyKTsgfSkuam9pbignLCcpKSArICJdIikKICAgIH0KCiAgICB2YXIgaXNNZXRob2RQYXRoID0gc2ltcGxlUGF0aFJFLnRlc3QoaGFuZGxlci52YWx1ZSk7CiAgICB2YXIgaXNGdW5jdGlvbkV4cHJlc3Npb24gPSBmbkV4cFJFLnRlc3QoaGFuZGxlci52YWx1ZSk7CiAgICB2YXIgaXNGdW5jdGlvbkludm9jYXRpb24gPSBzaW1wbGVQYXRoUkUudGVzdChoYW5kbGVyLnZhbHVlLnJlcGxhY2UoZm5JbnZva2VSRSwgJycpKTsKCiAgICBpZiAoIWhhbmRsZXIubW9kaWZpZXJzKSB7CiAgICAgIGlmIChpc01ldGhvZFBhdGggfHwgaXNGdW5jdGlvbkV4cHJlc3Npb24pIHsKICAgICAgICByZXR1cm4gaGFuZGxlci52YWx1ZQogICAgICB9CiAgICAgIHJldHVybiAoImZ1bmN0aW9uKCRldmVudCl7IiArIChpc0Z1bmN0aW9uSW52b2NhdGlvbiA/ICgicmV0dXJuICIgKyAoaGFuZGxlci52YWx1ZSkpIDogaGFuZGxlci52YWx1ZSkgKyAifSIpIC8vIGlubGluZSBzdGF0ZW1lbnQKICAgIH0gZWxzZSB7CiAgICAgIHZhciBjb2RlID0gJyc7CiAgICAgIHZhciBnZW5Nb2RpZmllckNvZGUgPSAnJzsKICAgICAgdmFyIGtleXMgPSBbXTsKICAgICAgZm9yICh2YXIga2V5IGluIGhhbmRsZXIubW9kaWZpZXJzKSB7CiAgICAgICAgaWYgKG1vZGlmaWVyQ29kZVtrZXldKSB7CiAgICAgICAgICBnZW5Nb2RpZmllckNvZGUgKz0gbW9kaWZpZXJDb2RlW2tleV07CiAgICAgICAgICAvLyBsZWZ0L3JpZ2h0CiAgICAgICAgICBpZiAoa2V5Q29kZXNba2V5XSkgewogICAgICAgICAgICBrZXlzLnB1c2goa2V5KTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gJ2V4YWN0JykgewogICAgICAgICAgdmFyIG1vZGlmaWVycyA9IChoYW5kbGVyLm1vZGlmaWVycyk7CiAgICAgICAgICBnZW5Nb2RpZmllckNvZGUgKz0gZ2VuR3VhcmQoCiAgICAgICAgICAgIFsnY3RybCcsICdzaGlmdCcsICdhbHQnLCAnbWV0YSddCiAgICAgICAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAoa2V5TW9kaWZpZXIpIHsgcmV0dXJuICFtb2RpZmllcnNba2V5TW9kaWZpZXJdOyB9KQogICAgICAgICAgICAgIC5tYXAoZnVuY3Rpb24gKGtleU1vZGlmaWVyKSB7IHJldHVybiAoIiRldmVudC4iICsga2V5TW9kaWZpZXIgKyAiS2V5Iik7IH0pCiAgICAgICAgICAgICAgLmpvaW4oJ3x8JykKICAgICAgICAgICk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGtleXMucHVzaChrZXkpOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoa2V5cy5sZW5ndGgpIHsKICAgICAgICBjb2RlICs9IGdlbktleUZpbHRlcihrZXlzKTsKICAgICAgfQogICAgICAvLyBNYWtlIHN1cmUgbW9kaWZpZXJzIGxpa2UgcHJldmVudCBhbmQgc3RvcCBnZXQgZXhlY3V0ZWQgYWZ0ZXIga2V5IGZpbHRlcmluZwogICAgICBpZiAoZ2VuTW9kaWZpZXJDb2RlKSB7CiAgICAgICAgY29kZSArPSBnZW5Nb2RpZmllckNvZGU7CiAgICAgIH0KICAgICAgdmFyIGhhbmRsZXJDb2RlID0gaXNNZXRob2RQYXRoCiAgICAgICAgPyAoInJldHVybiAiICsgKGhhbmRsZXIudmFsdWUpICsgIigkZXZlbnQpIikKICAgICAgICA6IGlzRnVuY3Rpb25FeHByZXNzaW9uCiAgICAgICAgICA/ICgicmV0dXJuICgiICsgKGhhbmRsZXIudmFsdWUpICsgIikoJGV2ZW50KSIpCiAgICAgICAgICA6IGlzRnVuY3Rpb25JbnZvY2F0aW9uCiAgICAgICAgICAgID8gKCJyZXR1cm4gIiArIChoYW5kbGVyLnZhbHVlKSkKICAgICAgICAgICAgOiBoYW5kbGVyLnZhbHVlOwogICAgICByZXR1cm4gKCJmdW5jdGlvbigkZXZlbnQpeyIgKyBjb2RlICsgaGFuZGxlckNvZGUgKyAifSIpCiAgICB9CiAgfQoKICBmdW5jdGlvbiBnZW5LZXlGaWx0ZXIgKGtleXMpIHsKICAgIHJldHVybiAoCiAgICAgIC8vIG1ha2Ugc3VyZSB0aGUga2V5IGZpbHRlcnMgb25seSBhcHBseSB0byBLZXlib2FyZEV2ZW50cwogICAgICAvLyAjOTQ0MTogY2FuJ3QgdXNlICdrZXlDb2RlJyBpbiAkZXZlbnQgYmVjYXVzZSBDaHJvbWUgYXV0b2ZpbGwgZmlyZXMgZmFrZQogICAgICAvLyBrZXkgZXZlbnRzIHRoYXQgZG8gbm90IGhhdmUga2V5Q29kZSBwcm9wZXJ0eS4uLgogICAgICAiaWYoISRldmVudC50eXBlLmluZGV4T2YoJ2tleScpJiYiICsKICAgICAgKGtleXMubWFwKGdlbkZpbHRlckNvZGUpLmpvaW4oJyYmJykpICsgIilyZXR1cm4gbnVsbDsiCiAgICApCiAgfQoKICBmdW5jdGlvbiBnZW5GaWx0ZXJDb2RlIChrZXkpIHsKICAgIHZhciBrZXlWYWwgPSBwYXJzZUludChrZXksIDEwKTsKICAgIGlmIChrZXlWYWwpIHsKICAgICAgcmV0dXJuICgiJGV2ZW50LmtleUNvZGUhPT0iICsga2V5VmFsKQogICAgfQogICAgdmFyIGtleUNvZGUgPSBrZXlDb2Rlc1trZXldOwogICAgdmFyIGtleU5hbWUgPSBrZXlOYW1lc1trZXldOwogICAgcmV0dXJuICgKICAgICAgIl9rKCRldmVudC5rZXlDb2RlLCIgKwogICAgICAoSlNPTi5zdHJpbmdpZnkoa2V5KSkgKyAiLCIgKwogICAgICAoSlNPTi5zdHJpbmdpZnkoa2V5Q29kZSkpICsgIiwiICsKICAgICAgIiRldmVudC5rZXksIiArCiAgICAgICIiICsgKEpTT04uc3RyaW5naWZ5KGtleU5hbWUpKSArCiAgICAgICIpIgogICAgKQogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIG9uIChlbCwgZGlyKSB7CiAgICBpZiAoZGlyLm1vZGlmaWVycykgewogICAgICB3YXJuKCJ2LW9uIHdpdGhvdXQgYXJndW1lbnQgZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmllcnMuIik7CiAgICB9CiAgICBlbC53cmFwTGlzdGVuZXJzID0gZnVuY3Rpb24gKGNvZGUpIHsgcmV0dXJuICgiX2coIiArIGNvZGUgKyAiLCIgKyAoZGlyLnZhbHVlKSArICIpIik7IH07CiAgfQoKICAvKiAgKi8KCiAgZnVuY3Rpb24gYmluZCQxIChlbCwgZGlyKSB7CiAgICBlbC53cmFwRGF0YSA9IGZ1bmN0aW9uIChjb2RlKSB7CiAgICAgIHJldHVybiAoIl9iKCIgKyBjb2RlICsgIiwnIiArIChlbC50YWcpICsgIicsIiArIChkaXIudmFsdWUpICsgIiwiICsgKGRpci5tb2RpZmllcnMgJiYgZGlyLm1vZGlmaWVycy5wcm9wID8gJ3RydWUnIDogJ2ZhbHNlJykgKyAoZGlyLm1vZGlmaWVycyAmJiBkaXIubW9kaWZpZXJzLnN5bmMgPyAnLHRydWUnIDogJycpICsgIikiKQogICAgfTsKICB9CgogIC8qICAqLwoKICB2YXIgYmFzZURpcmVjdGl2ZXMgPSB7CiAgICBvbjogb24sCiAgICBiaW5kOiBiaW5kJDEsCiAgICBjbG9hazogbm9vcAogIH07CgogIC8qICAqLwoKCgoKCiAgdmFyIENvZGVnZW5TdGF0ZSA9IGZ1bmN0aW9uIENvZGVnZW5TdGF0ZSAob3B0aW9ucykgewogICAgdGhpcy5vcHRpb25zID0gb3B0aW9uczsKICAgIHRoaXMud2FybiA9IG9wdGlvbnMud2FybiB8fCBiYXNlV2FybjsKICAgIHRoaXMudHJhbnNmb3JtcyA9IHBsdWNrTW9kdWxlRnVuY3Rpb24ob3B0aW9ucy5tb2R1bGVzLCAndHJhbnNmb3JtQ29kZScpOwogICAgdGhpcy5kYXRhR2VuRm5zID0gcGx1Y2tNb2R1bGVGdW5jdGlvbihvcHRpb25zLm1vZHVsZXMsICdnZW5EYXRhJyk7CiAgICB0aGlzLmRpcmVjdGl2ZXMgPSBleHRlbmQoZXh0ZW5kKHt9LCBiYXNlRGlyZWN0aXZlcyksIG9wdGlvbnMuZGlyZWN0aXZlcyk7CiAgICB2YXIgaXNSZXNlcnZlZFRhZyA9IG9wdGlvbnMuaXNSZXNlcnZlZFRhZyB8fCBubzsKICAgIHRoaXMubWF5YmVDb21wb25lbnQgPSBmdW5jdGlvbiAoZWwpIHsgcmV0dXJuICEhZWwuY29tcG9uZW50IHx8ICFpc1Jlc2VydmVkVGFnKGVsLnRhZyk7IH07CiAgICB0aGlzLm9uY2VJZCA9IDA7CiAgICB0aGlzLnN0YXRpY1JlbmRlckZucyA9IFtdOwogICAgdGhpcy5wcmUgPSBmYWxzZTsKICB9OwoKCgogIGZ1bmN0aW9uIGdlbmVyYXRlICgKICAgIGFzdCwKICAgIG9wdGlvbnMKICApIHsKICAgIHZhciBzdGF0ZSA9IG5ldyBDb2RlZ2VuU3RhdGUob3B0aW9ucyk7CiAgICB2YXIgY29kZSA9IGFzdCA/IGdlbkVsZW1lbnQoYXN0LCBzdGF0ZSkgOiAnX2MoImRpdiIpJzsKICAgIHJldHVybiB7CiAgICAgIHJlbmRlcjogKCJ3aXRoKHRoaXMpe3JldHVybiAiICsgY29kZSArICJ9IiksCiAgICAgIHN0YXRpY1JlbmRlckZuczogc3RhdGUuc3RhdGljUmVuZGVyRm5zCiAgICB9CiAgfQoKICBmdW5jdGlvbiBnZW5FbGVtZW50IChlbCwgc3RhdGUpIHsKICAgIGlmIChlbC5wYXJlbnQpIHsKICAgICAgZWwucHJlID0gZWwucHJlIHx8IGVsLnBhcmVudC5wcmU7CiAgICB9CgogICAgaWYgKGVsLnN0YXRpY1Jvb3QgJiYgIWVsLnN0YXRpY1Byb2Nlc3NlZCkgewogICAgICByZXR1cm4gZ2VuU3RhdGljKGVsLCBzdGF0ZSkKICAgIH0gZWxzZSBpZiAoZWwub25jZSAmJiAhZWwub25jZVByb2Nlc3NlZCkgewogICAgICByZXR1cm4gZ2VuT25jZShlbCwgc3RhdGUpCiAgICB9IGVsc2UgaWYgKGVsLmZvciAmJiAhZWwuZm9yUHJvY2Vzc2VkKSB7CiAgICAgIHJldHVybiBnZW5Gb3IoZWwsIHN0YXRlKQogICAgfSBlbHNlIGlmIChlbC5pZiAmJiAhZWwuaWZQcm9jZXNzZWQpIHsKICAgICAgcmV0dXJuIGdlbklmKGVsLCBzdGF0ZSkKICAgIH0gZWxzZSBpZiAoZWwudGFnID09PSAndGVtcGxhdGUnICYmICFlbC5zbG90VGFyZ2V0ICYmICFzdGF0ZS5wcmUpIHsKICAgICAgcmV0dXJuIGdlbkNoaWxkcmVuKGVsLCBzdGF0ZSkgfHwgJ3ZvaWQgMCcKICAgIH0gZWxzZSBpZiAoZWwudGFnID09PSAnc2xvdCcpIHsKICAgICAgcmV0dXJuIGdlblNsb3QoZWwsIHN0YXRlKQogICAgfSBlbHNlIHsKICAgICAgLy8gY29tcG9uZW50IG9yIGVsZW1lbnQKICAgICAgdmFyIGNvZGU7CiAgICAgIGlmIChlbC5jb21wb25lbnQpIHsKICAgICAgICBjb2RlID0gZ2VuQ29tcG9uZW50KGVsLmNvbXBvbmVudCwgZWwsIHN0YXRlKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB2YXIgZGF0YTsKICAgICAgICBpZiAoIWVsLnBsYWluIHx8IChlbC5wcmUgJiYgc3RhdGUubWF5YmVDb21wb25lbnQoZWwpKSkgewogICAgICAgICAgZGF0YSA9IGdlbkRhdGEkMihlbCwgc3RhdGUpOwogICAgICAgIH0KCiAgICAgICAgdmFyIGNoaWxkcmVuID0gZWwuaW5saW5lVGVtcGxhdGUgPyBudWxsIDogZ2VuQ2hpbGRyZW4oZWwsIHN0YXRlLCB0cnVlKTsKICAgICAgICBjb2RlID0gIl9jKCciICsgKGVsLnRhZykgKyAiJyIgKyAoZGF0YSA/ICgiLCIgKyBkYXRhKSA6ICcnKSArIChjaGlsZHJlbiA/ICgiLCIgKyBjaGlsZHJlbikgOiAnJykgKyAiKSI7CiAgICAgIH0KICAgICAgLy8gbW9kdWxlIHRyYW5zZm9ybXMKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGF0ZS50cmFuc2Zvcm1zLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgY29kZSA9IHN0YXRlLnRyYW5zZm9ybXNbaV0oZWwsIGNvZGUpOwogICAgICB9CiAgICAgIHJldHVybiBjb2RlCiAgICB9CiAgfQoKICAvLyBob2lzdCBzdGF0aWMgc3ViLXRyZWVzIG91dAogIGZ1bmN0aW9uIGdlblN0YXRpYyAoZWwsIHN0YXRlKSB7CiAgICBlbC5zdGF0aWNQcm9jZXNzZWQgPSB0cnVlOwogICAgLy8gU29tZSBlbGVtZW50cyAodGVtcGxhdGVzKSBuZWVkIHRvIGJlaGF2ZSBkaWZmZXJlbnRseSBpbnNpZGUgb2YgYSB2LXByZQogICAgLy8gbm9kZS4gIEFsbCBwcmUgbm9kZXMgYXJlIHN0YXRpYyByb290cywgc28gd2UgY2FuIHVzZSB0aGlzIGFzIGEgbG9jYXRpb24gdG8KICAgIC8vIHdyYXAgYSBzdGF0ZSBjaGFuZ2UgYW5kIHJlc2V0IGl0IHVwb24gZXhpdGluZyB0aGUgcHJlIG5vZGUuCiAgICB2YXIgb3JpZ2luYWxQcmVTdGF0ZSA9IHN0YXRlLnByZTsKICAgIGlmIChlbC5wcmUpIHsKICAgICAgc3RhdGUucHJlID0gZWwucHJlOwogICAgfQogICAgc3RhdGUuc3RhdGljUmVuZGVyRm5zLnB1c2goKCJ3aXRoKHRoaXMpe3JldHVybiAiICsgKGdlbkVsZW1lbnQoZWwsIHN0YXRlKSkgKyAifSIpKTsKICAgIHN0YXRlLnByZSA9IG9yaWdpbmFsUHJlU3RhdGU7CiAgICByZXR1cm4gKCJfbSgiICsgKHN0YXRlLnN0YXRpY1JlbmRlckZucy5sZW5ndGggLSAxKSArIChlbC5zdGF0aWNJbkZvciA/ICcsdHJ1ZScgOiAnJykgKyAiKSIpCiAgfQoKICAvLyB2LW9uY2UKICBmdW5jdGlvbiBnZW5PbmNlIChlbCwgc3RhdGUpIHsKICAgIGVsLm9uY2VQcm9jZXNzZWQgPSB0cnVlOwogICAgaWYgKGVsLmlmICYmICFlbC5pZlByb2Nlc3NlZCkgewogICAgICByZXR1cm4gZ2VuSWYoZWwsIHN0YXRlKQogICAgfSBlbHNlIGlmIChlbC5zdGF0aWNJbkZvcikgewogICAgICB2YXIga2V5ID0gJyc7CiAgICAgIHZhciBwYXJlbnQgPSBlbC5wYXJlbnQ7CiAgICAgIHdoaWxlIChwYXJlbnQpIHsKICAgICAgICBpZiAocGFyZW50LmZvcikgewogICAgICAgICAga2V5ID0gcGFyZW50LmtleTsKICAgICAgICAgIGJyZWFrCiAgICAgICAgfQogICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnQ7CiAgICAgIH0KICAgICAgaWYgKCFrZXkpIHsKICAgICAgICBzdGF0ZS53YXJuKAogICAgICAgICAgInYtb25jZSBjYW4gb25seSBiZSB1c2VkIGluc2lkZSB2LWZvciB0aGF0IGlzIGtleWVkLiAiLAogICAgICAgICAgZWwucmF3QXR0cnNNYXBbJ3Ytb25jZSddCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gZ2VuRWxlbWVudChlbCwgc3RhdGUpCiAgICAgIH0KICAgICAgcmV0dXJuICgiX28oIiArIChnZW5FbGVtZW50KGVsLCBzdGF0ZSkpICsgIiwiICsgKHN0YXRlLm9uY2VJZCsrKSArICIsIiArIGtleSArICIpIikKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBnZW5TdGF0aWMoZWwsIHN0YXRlKQogICAgfQogIH0KCiAgZnVuY3Rpb24gZ2VuSWYgKAogICAgZWwsCiAgICBzdGF0ZSwKICAgIGFsdEdlbiwKICAgIGFsdEVtcHR5CiAgKSB7CiAgICBlbC5pZlByb2Nlc3NlZCA9IHRydWU7IC8vIGF2b2lkIHJlY3Vyc2lvbgogICAgcmV0dXJuIGdlbklmQ29uZGl0aW9ucyhlbC5pZkNvbmRpdGlvbnMuc2xpY2UoKSwgc3RhdGUsIGFsdEdlbiwgYWx0RW1wdHkpCiAgfQoKICBmdW5jdGlvbiBnZW5JZkNvbmRpdGlvbnMgKAogICAgY29uZGl0aW9ucywKICAgIHN0YXRlLAogICAgYWx0R2VuLAogICAgYWx0RW1wdHkKICApIHsKICAgIGlmICghY29uZGl0aW9ucy5sZW5ndGgpIHsKICAgICAgcmV0dXJuIGFsdEVtcHR5IHx8ICdfZSgpJwogICAgfQoKICAgIHZhciBjb25kaXRpb24gPSBjb25kaXRpb25zLnNoaWZ0KCk7CiAgICBpZiAoY29uZGl0aW9uLmV4cCkgewogICAgICByZXR1cm4gKCIoIiArIChjb25kaXRpb24uZXhwKSArICIpPyIgKyAoZ2VuVGVybmFyeUV4cChjb25kaXRpb24uYmxvY2spKSArICI6IiArIChnZW5JZkNvbmRpdGlvbnMoY29uZGl0aW9ucywgc3RhdGUsIGFsdEdlbiwgYWx0RW1wdHkpKSkKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiAoIiIgKyAoZ2VuVGVybmFyeUV4cChjb25kaXRpb24uYmxvY2spKSkKICAgIH0KCiAgICAvLyB2LWlmIHdpdGggdi1vbmNlIHNob3VsZCBnZW5lcmF0ZSBjb2RlIGxpa2UgKGEpP19tKDApOl9tKDEpCiAgICBmdW5jdGlvbiBnZW5UZXJuYXJ5RXhwIChlbCkgewogICAgICByZXR1cm4gYWx0R2VuCiAgICAgICAgPyBhbHRHZW4oZWwsIHN0YXRlKQogICAgICAgIDogZWwub25jZQogICAgICAgICAgPyBnZW5PbmNlKGVsLCBzdGF0ZSkKICAgICAgICAgIDogZ2VuRWxlbWVudChlbCwgc3RhdGUpCiAgICB9CiAgfQoKICBmdW5jdGlvbiBnZW5Gb3IgKAogICAgZWwsCiAgICBzdGF0ZSwKICAgIGFsdEdlbiwKICAgIGFsdEhlbHBlcgogICkgewogICAgdmFyIGV4cCA9IGVsLmZvcjsKICAgIHZhciBhbGlhcyA9IGVsLmFsaWFzOwogICAgdmFyIGl0ZXJhdG9yMSA9IGVsLml0ZXJhdG9yMSA/ICgiLCIgKyAoZWwuaXRlcmF0b3IxKSkgOiAnJzsKICAgIHZhciBpdGVyYXRvcjIgPSBlbC5pdGVyYXRvcjIgPyAoIiwiICsgKGVsLml0ZXJhdG9yMikpIDogJyc7CgogICAgaWYgKHN0YXRlLm1heWJlQ29tcG9uZW50KGVsKSAmJgogICAgICBlbC50YWcgIT09ICdzbG90JyAmJgogICAgICBlbC50YWcgIT09ICd0ZW1wbGF0ZScgJiYKICAgICAgIWVsLmtleQogICAgKSB7CiAgICAgIHN0YXRlLndhcm4oCiAgICAgICAgIjwiICsgKGVsLnRhZykgKyAiIHYtZm9yPVwiIiArIGFsaWFzICsgIiBpbiAiICsgZXhwICsgIlwiPjogY29tcG9uZW50IGxpc3RzIHJlbmRlcmVkIHdpdGggIiArCiAgICAgICAgInYtZm9yIHNob3VsZCBoYXZlIGV4cGxpY2l0IGtleXMuICIgKwogICAgICAgICJTZWUgaHR0cHM6Ly92dWVqcy5vcmcvZ3VpZGUvbGlzdC5odG1sI2tleSBmb3IgbW9yZSBpbmZvLiIsCiAgICAgICAgZWwucmF3QXR0cnNNYXBbJ3YtZm9yJ10sCiAgICAgICAgdHJ1ZSAvKiB0aXAgKi8KICAgICAgKTsKICAgIH0KCiAgICBlbC5mb3JQcm9jZXNzZWQgPSB0cnVlOyAvLyBhdm9pZCByZWN1cnNpb24KICAgIHJldHVybiAoYWx0SGVscGVyIHx8ICdfbCcpICsgIigoIiArIGV4cCArICIpLCIgKwogICAgICAiZnVuY3Rpb24oIiArIGFsaWFzICsgaXRlcmF0b3IxICsgaXRlcmF0b3IyICsgIil7IiArCiAgICAgICAgInJldHVybiAiICsgKChhbHRHZW4gfHwgZ2VuRWxlbWVudCkoZWwsIHN0YXRlKSkgKwogICAgICAnfSknCiAgfQoKICBmdW5jdGlvbiBnZW5EYXRhJDIgKGVsLCBzdGF0ZSkgewogICAgdmFyIGRhdGEgPSAneyc7CgogICAgLy8gZGlyZWN0aXZlcyBmaXJzdC4KICAgIC8vIGRpcmVjdGl2ZXMgbWF5IG11dGF0ZSB0aGUgZWwncyBvdGhlciBwcm9wZXJ0aWVzIGJlZm9yZSB0aGV5IGFyZSBnZW5lcmF0ZWQuCiAgICB2YXIgZGlycyA9IGdlbkRpcmVjdGl2ZXMoZWwsIHN0YXRlKTsKICAgIGlmIChkaXJzKSB7IGRhdGEgKz0gZGlycyArICcsJzsgfQoKICAgIC8vIGtleQogICAgaWYgKGVsLmtleSkgewogICAgICBkYXRhICs9ICJrZXk6IiArIChlbC5rZXkpICsgIiwiOwogICAgfQogICAgLy8gcmVmCiAgICBpZiAoZWwucmVmKSB7CiAgICAgIGRhdGEgKz0gInJlZjoiICsgKGVsLnJlZikgKyAiLCI7CiAgICB9CiAgICBpZiAoZWwucmVmSW5Gb3IpIHsKICAgICAgZGF0YSArPSAicmVmSW5Gb3I6dHJ1ZSwiOwogICAgfQogICAgLy8gcHJlCiAgICBpZiAoZWwucHJlKSB7CiAgICAgIGRhdGEgKz0gInByZTp0cnVlLCI7CiAgICB9CiAgICAvLyByZWNvcmQgb3JpZ2luYWwgdGFnIG5hbWUgZm9yIGNvbXBvbmVudHMgdXNpbmcgImlzIiBhdHRyaWJ1dGUKICAgIGlmIChlbC5jb21wb25lbnQpIHsKICAgICAgZGF0YSArPSAidGFnOlwiIiArIChlbC50YWcpICsgIlwiLCI7CiAgICB9CiAgICAvLyBtb2R1bGUgZGF0YSBnZW5lcmF0aW9uIGZ1bmN0aW9ucwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGF0ZS5kYXRhR2VuRm5zLmxlbmd0aDsgaSsrKSB7CiAgICAgIGRhdGEgKz0gc3RhdGUuZGF0YUdlbkZuc1tpXShlbCk7CiAgICB9CiAgICAvLyBhdHRyaWJ1dGVzCiAgICBpZiAoZWwuYXR0cnMpIHsKICAgICAgZGF0YSArPSAiYXR0cnM6IiArIChnZW5Qcm9wcyhlbC5hdHRycykpICsgIiwiOwogICAgfQogICAgLy8gRE9NIHByb3BzCiAgICBpZiAoZWwucHJvcHMpIHsKICAgICAgZGF0YSArPSAiZG9tUHJvcHM6IiArIChnZW5Qcm9wcyhlbC5wcm9wcykpICsgIiwiOwogICAgfQogICAgLy8gZXZlbnQgaGFuZGxlcnMKICAgIGlmIChlbC5ldmVudHMpIHsKICAgICAgZGF0YSArPSAoZ2VuSGFuZGxlcnMoZWwuZXZlbnRzLCBmYWxzZSkpICsgIiwiOwogICAgfQogICAgaWYgKGVsLm5hdGl2ZUV2ZW50cykgewogICAgICBkYXRhICs9IChnZW5IYW5kbGVycyhlbC5uYXRpdmVFdmVudHMsIHRydWUpKSArICIsIjsKICAgIH0KICAgIC8vIHNsb3QgdGFyZ2V0CiAgICAvLyBvbmx5IGZvciBub24tc2NvcGVkIHNsb3RzCiAgICBpZiAoZWwuc2xvdFRhcmdldCAmJiAhZWwuc2xvdFNjb3BlKSB7CiAgICAgIGRhdGEgKz0gInNsb3Q6IiArIChlbC5zbG90VGFyZ2V0KSArICIsIjsKICAgIH0KICAgIC8vIHNjb3BlZCBzbG90cwogICAgaWYgKGVsLnNjb3BlZFNsb3RzKSB7CiAgICAgIGRhdGEgKz0gKGdlblNjb3BlZFNsb3RzKGVsLCBlbC5zY29wZWRTbG90cywgc3RhdGUpKSArICIsIjsKICAgIH0KICAgIC8vIGNvbXBvbmVudCB2LW1vZGVsCiAgICBpZiAoZWwubW9kZWwpIHsKICAgICAgZGF0YSArPSAibW9kZWw6e3ZhbHVlOiIgKyAoZWwubW9kZWwudmFsdWUpICsgIixjYWxsYmFjazoiICsgKGVsLm1vZGVsLmNhbGxiYWNrKSArICIsZXhwcmVzc2lvbjoiICsgKGVsLm1vZGVsLmV4cHJlc3Npb24pICsgIn0sIjsKICAgIH0KICAgIC8vIGlubGluZS10ZW1wbGF0ZQogICAgaWYgKGVsLmlubGluZVRlbXBsYXRlKSB7CiAgICAgIHZhciBpbmxpbmVUZW1wbGF0ZSA9IGdlbklubGluZVRlbXBsYXRlKGVsLCBzdGF0ZSk7CiAgICAgIGlmIChpbmxpbmVUZW1wbGF0ZSkgewogICAgICAgIGRhdGEgKz0gaW5saW5lVGVtcGxhdGUgKyAiLCI7CiAgICAgIH0KICAgIH0KICAgIGRhdGEgPSBkYXRhLnJlcGxhY2UoLywkLywgJycpICsgJ30nOwogICAgLy8gdi1iaW5kIGR5bmFtaWMgYXJndW1lbnQgd3JhcAogICAgLy8gdi1iaW5kIHdpdGggZHluYW1pYyBhcmd1bWVudHMgbXVzdCBiZSBhcHBsaWVkIHVzaW5nIHRoZSBzYW1lIHYtYmluZCBvYmplY3QKICAgIC8vIG1lcmdlIGhlbHBlciBzbyB0aGF0IGNsYXNzL3N0eWxlL211c3RVc2VQcm9wIGF0dHJzIGFyZSBoYW5kbGVkIGNvcnJlY3RseS4KICAgIGlmIChlbC5keW5hbWljQXR0cnMpIHsKICAgICAgZGF0YSA9ICJfYigiICsgZGF0YSArICIsXCIiICsgKGVsLnRhZykgKyAiXCIsIiArIChnZW5Qcm9wcyhlbC5keW5hbWljQXR0cnMpKSArICIpIjsKICAgIH0KICAgIC8vIHYtYmluZCBkYXRhIHdyYXAKICAgIGlmIChlbC53cmFwRGF0YSkgewogICAgICBkYXRhID0gZWwud3JhcERhdGEoZGF0YSk7CiAgICB9CiAgICAvLyB2LW9uIGRhdGEgd3JhcAogICAgaWYgKGVsLndyYXBMaXN0ZW5lcnMpIHsKICAgICAgZGF0YSA9IGVsLndyYXBMaXN0ZW5lcnMoZGF0YSk7CiAgICB9CiAgICByZXR1cm4gZGF0YQogIH0KCiAgZnVuY3Rpb24gZ2VuRGlyZWN0aXZlcyAoZWwsIHN0YXRlKSB7CiAgICB2YXIgZGlycyA9IGVsLmRpcmVjdGl2ZXM7CiAgICBpZiAoIWRpcnMpIHsgcmV0dXJuIH0KICAgIHZhciByZXMgPSAnZGlyZWN0aXZlczpbJzsKICAgIHZhciBoYXNSdW50aW1lID0gZmFsc2U7CiAgICB2YXIgaSwgbCwgZGlyLCBuZWVkUnVudGltZTsKICAgIGZvciAoaSA9IDAsIGwgPSBkaXJzLmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICBkaXIgPSBkaXJzW2ldOwogICAgICBuZWVkUnVudGltZSA9IHRydWU7CiAgICAgIHZhciBnZW4gPSBzdGF0ZS5kaXJlY3RpdmVzW2Rpci5uYW1lXTsKICAgICAgaWYgKGdlbikgewogICAgICAgIC8vIGNvbXBpbGUtdGltZSBkaXJlY3RpdmUgdGhhdCBtYW5pcHVsYXRlcyBBU1QuCiAgICAgICAgLy8gcmV0dXJucyB0cnVlIGlmIGl0IGFsc28gbmVlZHMgYSBydW50aW1lIGNvdW50ZXJwYXJ0LgogICAgICAgIG5lZWRSdW50aW1lID0gISFnZW4oZWwsIGRpciwgc3RhdGUud2Fybik7CiAgICAgIH0KICAgICAgaWYgKG5lZWRSdW50aW1lKSB7CiAgICAgICAgaGFzUnVudGltZSA9IHRydWU7CiAgICAgICAgcmVzICs9ICJ7bmFtZTpcIiIgKyAoZGlyLm5hbWUpICsgIlwiLHJhd05hbWU6XCIiICsgKGRpci5yYXdOYW1lKSArICJcIiIgKyAoZGlyLnZhbHVlID8gKCIsdmFsdWU6KCIgKyAoZGlyLnZhbHVlKSArICIpLGV4cHJlc3Npb246IiArIChKU09OLnN0cmluZ2lmeShkaXIudmFsdWUpKSkgOiAnJykgKyAoZGlyLmFyZyA/ICgiLGFyZzoiICsgKGRpci5pc0R5bmFtaWNBcmcgPyBkaXIuYXJnIDogKCJcIiIgKyAoZGlyLmFyZykgKyAiXCIiKSkpIDogJycpICsgKGRpci5tb2RpZmllcnMgPyAoIixtb2RpZmllcnM6IiArIChKU09OLnN0cmluZ2lmeShkaXIubW9kaWZpZXJzKSkpIDogJycpICsgIn0sIjsKICAgICAgfQogICAgfQogICAgaWYgKGhhc1J1bnRpbWUpIHsKICAgICAgcmV0dXJuIHJlcy5zbGljZSgwLCAtMSkgKyAnXScKICAgIH0KICB9CgogIGZ1bmN0aW9uIGdlbklubGluZVRlbXBsYXRlIChlbCwgc3RhdGUpIHsKICAgIHZhciBhc3QgPSBlbC5jaGlsZHJlblswXTsKICAgIGlmIChlbC5jaGlsZHJlbi5sZW5ndGggIT09IDEgfHwgYXN0LnR5cGUgIT09IDEpIHsKICAgICAgc3RhdGUud2FybigKICAgICAgICAnSW5saW5lLXRlbXBsYXRlIGNvbXBvbmVudHMgbXVzdCBoYXZlIGV4YWN0bHkgb25lIGNoaWxkIGVsZW1lbnQuJywKICAgICAgICB7IHN0YXJ0OiBlbC5zdGFydCB9CiAgICAgICk7CiAgICB9CiAgICBpZiAoYXN0ICYmIGFzdC50eXBlID09PSAxKSB7CiAgICAgIHZhciBpbmxpbmVSZW5kZXJGbnMgPSBnZW5lcmF0ZShhc3QsIHN0YXRlLm9wdGlvbnMpOwogICAgICByZXR1cm4gKCJpbmxpbmVUZW1wbGF0ZTp7cmVuZGVyOmZ1bmN0aW9uKCl7IiArIChpbmxpbmVSZW5kZXJGbnMucmVuZGVyKSArICJ9LHN0YXRpY1JlbmRlckZuczpbIiArIChpbmxpbmVSZW5kZXJGbnMuc3RhdGljUmVuZGVyRm5zLm1hcChmdW5jdGlvbiAoY29kZSkgeyByZXR1cm4gKCJmdW5jdGlvbigpeyIgKyBjb2RlICsgIn0iKTsgfSkuam9pbignLCcpKSArICJdfSIpCiAgICB9CiAgfQoKICBmdW5jdGlvbiBnZW5TY29wZWRTbG90cyAoCiAgICBlbCwKICAgIHNsb3RzLAogICAgc3RhdGUKICApIHsKICAgIC8vIGJ5IGRlZmF1bHQgc2NvcGVkIHNsb3RzIGFyZSBjb25zaWRlcmVkICJzdGFibGUiLCB0aGlzIGFsbG93cyBjaGlsZAogICAgLy8gY29tcG9uZW50cyB3aXRoIG9ubHkgc2NvcGVkIHNsb3RzIHRvIHNraXAgZm9yY2VkIHVwZGF0ZXMgZnJvbSBwYXJlbnQuCiAgICAvLyBidXQgaW4gc29tZSBjYXNlcyB3ZSBoYXZlIHRvIGJhaWwtb3V0IG9mIHRoaXMgb3B0aW1pemF0aW9uCiAgICAvLyBmb3IgZXhhbXBsZSBpZiB0aGUgc2xvdCBjb250YWlucyBkeW5hbWljIG5hbWVzLCBoYXMgdi1pZiBvciB2LWZvciBvbiB0aGVtLi4uCiAgICB2YXIgbmVlZHNGb3JjZVVwZGF0ZSA9IGVsLmZvciB8fCBPYmplY3Qua2V5cyhzbG90cykuc29tZShmdW5jdGlvbiAoa2V5KSB7CiAgICAgIHZhciBzbG90ID0gc2xvdHNba2V5XTsKICAgICAgcmV0dXJuICgKICAgICAgICBzbG90LnNsb3RUYXJnZXREeW5hbWljIHx8CiAgICAgICAgc2xvdC5pZiB8fAogICAgICAgIHNsb3QuZm9yIHx8CiAgICAgICAgY29udGFpbnNTbG90Q2hpbGQoc2xvdCkgLy8gaXMgcGFzc2luZyBkb3duIHNsb3QgZnJvbSBwYXJlbnQgd2hpY2ggbWF5IGJlIGR5bmFtaWMKICAgICAgKQogICAgfSk7CgogICAgLy8gIzk1MzQ6IGlmIGEgY29tcG9uZW50IHdpdGggc2NvcGVkIHNsb3RzIGlzIGluc2lkZSBhIGNvbmRpdGlvbmFsIGJyYW5jaCwKICAgIC8vIGl0J3MgcG9zc2libGUgZm9yIHRoZSBzYW1lIGNvbXBvbmVudCB0byBiZSByZXVzZWQgYnV0IHdpdGggZGlmZmVyZW50CiAgICAvLyBjb21waWxlZCBzbG90IGNvbnRlbnQuIFRvIGF2b2lkIHRoYXQsIHdlIGdlbmVyYXRlIGEgdW5pcXVlIGtleSBiYXNlZCBvbgogICAgLy8gdGhlIGdlbmVyYXRlZCBjb2RlIG9mIGFsbCB0aGUgc2xvdCBjb250ZW50cy4KICAgIHZhciBuZWVkc0tleSA9ICEhZWwuaWY7CgogICAgLy8gT1Igd2hlbiBpdCBpcyBpbnNpZGUgYW5vdGhlciBzY29wZWQgc2xvdCBvciB2LWZvciAodGhlIHJlYWN0aXZpdHkgbWF5IGJlCiAgICAvLyBkaXNjb25uZWN0ZWQgZHVlIHRvIHRoZSBpbnRlcm1lZGlhdGUgc2NvcGUgdmFyaWFibGUpCiAgICAvLyAjOTQzOCwgIzk1MDYKICAgIC8vIFRPRE86IHRoaXMgY2FuIGJlIGZ1cnRoZXIgb3B0aW1pemVkIGJ5IHByb3Blcmx5IGFuYWx5emluZyBpbi1zY29wZSBiaW5kaW5ncwogICAgLy8gYW5kIHNraXAgZm9yY2UgdXBkYXRpbmcgb25lcyB0aGF0IGRvIG5vdCBhY3R1YWxseSB1c2Ugc2NvcGUgdmFyaWFibGVzLgogICAgaWYgKCFuZWVkc0ZvcmNlVXBkYXRlKSB7CiAgICAgIHZhciBwYXJlbnQgPSBlbC5wYXJlbnQ7CiAgICAgIHdoaWxlIChwYXJlbnQpIHsKICAgICAgICBpZiAoCiAgICAgICAgICAocGFyZW50LnNsb3RTY29wZSAmJiBwYXJlbnQuc2xvdFNjb3BlICE9PSBlbXB0eVNsb3RTY29wZVRva2VuKSB8fAogICAgICAgICAgcGFyZW50LmZvcgogICAgICAgICkgewogICAgICAgICAgbmVlZHNGb3JjZVVwZGF0ZSA9IHRydWU7CiAgICAgICAgICBicmVhawogICAgICAgIH0KICAgICAgICBpZiAocGFyZW50LmlmKSB7CiAgICAgICAgICBuZWVkc0tleSA9IHRydWU7CiAgICAgICAgfQogICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnQ7CiAgICAgIH0KICAgIH0KCiAgICB2YXIgZ2VuZXJhdGVkU2xvdHMgPSBPYmplY3Qua2V5cyhzbG90cykKICAgICAgLm1hcChmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBnZW5TY29wZWRTbG90KHNsb3RzW2tleV0sIHN0YXRlKTsgfSkKICAgICAgLmpvaW4oJywnKTsKCiAgICByZXR1cm4gKCJzY29wZWRTbG90czpfdShbIiArIGdlbmVyYXRlZFNsb3RzICsgIl0iICsgKG5lZWRzRm9yY2VVcGRhdGUgPyAiLG51bGwsdHJ1ZSIgOiAiIikgKyAoIW5lZWRzRm9yY2VVcGRhdGUgJiYgbmVlZHNLZXkgPyAoIixudWxsLGZhbHNlLCIgKyAoaGFzaChnZW5lcmF0ZWRTbG90cykpKSA6ICIiKSArICIpIikKICB9CgogIGZ1bmN0aW9uIGhhc2goc3RyKSB7CiAgICB2YXIgaGFzaCA9IDUzODE7CiAgICB2YXIgaSA9IHN0ci5sZW5ndGg7CiAgICB3aGlsZShpKSB7CiAgICAgIGhhc2ggPSAoaGFzaCAqIDMzKSBeIHN0ci5jaGFyQ29kZUF0KC0taSk7CiAgICB9CiAgICByZXR1cm4gaGFzaCA+Pj4gMAogIH0KCiAgZnVuY3Rpb24gY29udGFpbnNTbG90Q2hpbGQgKGVsKSB7CiAgICBpZiAoZWwudHlwZSA9PT0gMSkgewogICAgICBpZiAoZWwudGFnID09PSAnc2xvdCcpIHsKICAgICAgICByZXR1cm4gdHJ1ZQogICAgICB9CiAgICAgIHJldHVybiBlbC5jaGlsZHJlbi5zb21lKGNvbnRhaW5zU2xvdENoaWxkKQogICAgfQogICAgcmV0dXJuIGZhbHNlCiAgfQoKICBmdW5jdGlvbiBnZW5TY29wZWRTbG90ICgKICAgIGVsLAogICAgc3RhdGUKICApIHsKICAgIHZhciBpc0xlZ2FjeVN5bnRheCA9IGVsLmF0dHJzTWFwWydzbG90LXNjb3BlJ107CiAgICBpZiAoZWwuaWYgJiYgIWVsLmlmUHJvY2Vzc2VkICYmICFpc0xlZ2FjeVN5bnRheCkgewogICAgICByZXR1cm4gZ2VuSWYoZWwsIHN0YXRlLCBnZW5TY29wZWRTbG90LCAibnVsbCIpCiAgICB9CiAgICBpZiAoZWwuZm9yICYmICFlbC5mb3JQcm9jZXNzZWQpIHsKICAgICAgcmV0dXJuIGdlbkZvcihlbCwgc3RhdGUsIGdlblNjb3BlZFNsb3QpCiAgICB9CiAgICB2YXIgc2xvdFNjb3BlID0gZWwuc2xvdFNjb3BlID09PSBlbXB0eVNsb3RTY29wZVRva2VuCiAgICAgID8gIiIKICAgICAgOiBTdHJpbmcoZWwuc2xvdFNjb3BlKTsKICAgIHZhciBmbiA9ICJmdW5jdGlvbigiICsgc2xvdFNjb3BlICsgIil7IiArCiAgICAgICJyZXR1cm4gIiArIChlbC50YWcgPT09ICd0ZW1wbGF0ZScKICAgICAgICA/IGVsLmlmICYmIGlzTGVnYWN5U3ludGF4CiAgICAgICAgICA/ICgiKCIgKyAoZWwuaWYpICsgIik/IiArIChnZW5DaGlsZHJlbihlbCwgc3RhdGUpIHx8ICd1bmRlZmluZWQnKSArICI6dW5kZWZpbmVkIikKICAgICAgICAgIDogZ2VuQ2hpbGRyZW4oZWwsIHN0YXRlKSB8fCAndW5kZWZpbmVkJwogICAgICAgIDogZ2VuRWxlbWVudChlbCwgc3RhdGUpKSArICJ9IjsKICAgIC8vIHJldmVyc2UgcHJveHkgdi1zbG90IHdpdGhvdXQgc2NvcGUgb24gdGhpcy4kc2xvdHMKICAgIHZhciByZXZlcnNlUHJveHkgPSBzbG90U2NvcGUgPyAiIiA6ICIscHJveHk6dHJ1ZSI7CiAgICByZXR1cm4gKCJ7a2V5OiIgKyAoZWwuc2xvdFRhcmdldCB8fCAiXCJkZWZhdWx0XCIiKSArICIsZm46IiArIGZuICsgcmV2ZXJzZVByb3h5ICsgIn0iKQogIH0KCiAgZnVuY3Rpb24gZ2VuQ2hpbGRyZW4gKAogICAgZWwsCiAgICBzdGF0ZSwKICAgIGNoZWNrU2tpcCwKICAgIGFsdEdlbkVsZW1lbnQsCiAgICBhbHRHZW5Ob2RlCiAgKSB7CiAgICB2YXIgY2hpbGRyZW4gPSBlbC5jaGlsZHJlbjsKICAgIGlmIChjaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgdmFyIGVsJDEgPSBjaGlsZHJlblswXTsKICAgICAgLy8gb3B0aW1pemUgc2luZ2xlIHYtZm9yCiAgICAgIGlmIChjaGlsZHJlbi5sZW5ndGggPT09IDEgJiYKICAgICAgICBlbCQxLmZvciAmJgogICAgICAgIGVsJDEudGFnICE9PSAndGVtcGxhdGUnICYmCiAgICAgICAgZWwkMS50YWcgIT09ICdzbG90JwogICAgICApIHsKICAgICAgICB2YXIgbm9ybWFsaXphdGlvblR5cGUgPSBjaGVja1NraXAKICAgICAgICAgID8gc3RhdGUubWF5YmVDb21wb25lbnQoZWwkMSkgPyAiLDEiIDogIiwwIgogICAgICAgICAgOiAiIjsKICAgICAgICByZXR1cm4gKCIiICsgKChhbHRHZW5FbGVtZW50IHx8IGdlbkVsZW1lbnQpKGVsJDEsIHN0YXRlKSkgKyBub3JtYWxpemF0aW9uVHlwZSkKICAgICAgfQogICAgICB2YXIgbm9ybWFsaXphdGlvblR5cGUkMSA9IGNoZWNrU2tpcAogICAgICAgID8gZ2V0Tm9ybWFsaXphdGlvblR5cGUoY2hpbGRyZW4sIHN0YXRlLm1heWJlQ29tcG9uZW50KQogICAgICAgIDogMDsKICAgICAgdmFyIGdlbiA9IGFsdEdlbk5vZGUgfHwgZ2VuTm9kZTsKICAgICAgcmV0dXJuICgiWyIgKyAoY2hpbGRyZW4ubWFwKGZ1bmN0aW9uIChjKSB7IHJldHVybiBnZW4oYywgc3RhdGUpOyB9KS5qb2luKCcsJykpICsgIl0iICsgKG5vcm1hbGl6YXRpb25UeXBlJDEgPyAoIiwiICsgbm9ybWFsaXphdGlvblR5cGUkMSkgOiAnJykpCiAgICB9CiAgfQoKICAvLyBkZXRlcm1pbmUgdGhlIG5vcm1hbGl6YXRpb24gbmVlZGVkIGZvciB0aGUgY2hpbGRyZW4gYXJyYXkuCiAgLy8gMDogbm8gbm9ybWFsaXphdGlvbiBuZWVkZWQKICAvLyAxOiBzaW1wbGUgbm9ybWFsaXphdGlvbiBuZWVkZWQgKHBvc3NpYmxlIDEtbGV2ZWwgZGVlcCBuZXN0ZWQgYXJyYXkpCiAgLy8gMjogZnVsbCBub3JtYWxpemF0aW9uIG5lZWRlZAogIGZ1bmN0aW9uIGdldE5vcm1hbGl6YXRpb25UeXBlICgKICAgIGNoaWxkcmVuLAogICAgbWF5YmVDb21wb25lbnQKICApIHsKICAgIHZhciByZXMgPSAwOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICB2YXIgZWwgPSBjaGlsZHJlbltpXTsKICAgICAgaWYgKGVsLnR5cGUgIT09IDEpIHsKICAgICAgICBjb250aW51ZQogICAgICB9CiAgICAgIGlmIChuZWVkc05vcm1hbGl6YXRpb24oZWwpIHx8CiAgICAgICAgICAoZWwuaWZDb25kaXRpb25zICYmIGVsLmlmQ29uZGl0aW9ucy5zb21lKGZ1bmN0aW9uIChjKSB7IHJldHVybiBuZWVkc05vcm1hbGl6YXRpb24oYy5ibG9jayk7IH0pKSkgewogICAgICAgIHJlcyA9IDI7CiAgICAgICAgYnJlYWsKICAgICAgfQogICAgICBpZiAobWF5YmVDb21wb25lbnQoZWwpIHx8CiAgICAgICAgICAoZWwuaWZDb25kaXRpb25zICYmIGVsLmlmQ29uZGl0aW9ucy5zb21lKGZ1bmN0aW9uIChjKSB7IHJldHVybiBtYXliZUNvbXBvbmVudChjLmJsb2NrKTsgfSkpKSB7CiAgICAgICAgcmVzID0gMTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlcwogIH0KCiAgZnVuY3Rpb24gbmVlZHNOb3JtYWxpemF0aW9uIChlbCkgewogICAgcmV0dXJuIGVsLmZvciAhPT0gdW5kZWZpbmVkIHx8IGVsLnRhZyA9PT0gJ3RlbXBsYXRlJyB8fCBlbC50YWcgPT09ICdzbG90JwogIH0KCiAgZnVuY3Rpb24gZ2VuTm9kZSAobm9kZSwgc3RhdGUpIHsKICAgIGlmIChub2RlLnR5cGUgPT09IDEpIHsKICAgICAgcmV0dXJuIGdlbkVsZW1lbnQobm9kZSwgc3RhdGUpCiAgICB9IGVsc2UgaWYgKG5vZGUudHlwZSA9PT0gMyAmJiBub2RlLmlzQ29tbWVudCkgewogICAgICByZXR1cm4gZ2VuQ29tbWVudChub2RlKQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIGdlblRleHQobm9kZSkKICAgIH0KICB9CgogIGZ1bmN0aW9uIGdlblRleHQgKHRleHQpIHsKICAgIHJldHVybiAoIl92KCIgKyAodGV4dC50eXBlID09PSAyCiAgICAgID8gdGV4dC5leHByZXNzaW9uIC8vIG5vIG5lZWQgZm9yICgpIGJlY2F1c2UgYWxyZWFkeSB3cmFwcGVkIGluIF9zKCkKICAgICAgOiB0cmFuc2Zvcm1TcGVjaWFsTmV3bGluZXMoSlNPTi5zdHJpbmdpZnkodGV4dC50ZXh0KSkpICsgIikiKQogIH0KCiAgZnVuY3Rpb24gZ2VuQ29tbWVudCAoY29tbWVudCkgewogICAgcmV0dXJuICgiX2UoIiArIChKU09OLnN0cmluZ2lmeShjb21tZW50LnRleHQpKSArICIpIikKICB9CgogIGZ1bmN0aW9uIGdlblNsb3QgKGVsLCBzdGF0ZSkgewogICAgdmFyIHNsb3ROYW1lID0gZWwuc2xvdE5hbWUgfHwgJyJkZWZhdWx0Iic7CiAgICB2YXIgY2hpbGRyZW4gPSBnZW5DaGlsZHJlbihlbCwgc3RhdGUpOwogICAgdmFyIHJlcyA9ICJfdCgiICsgc2xvdE5hbWUgKyAoY2hpbGRyZW4gPyAoIiwiICsgY2hpbGRyZW4pIDogJycpOwogICAgdmFyIGF0dHJzID0gZWwuYXR0cnMgfHwgZWwuZHluYW1pY0F0dHJzCiAgICAgID8gZ2VuUHJvcHMoKGVsLmF0dHJzIHx8IFtdKS5jb25jYXQoZWwuZHluYW1pY0F0dHJzIHx8IFtdKS5tYXAoZnVuY3Rpb24gKGF0dHIpIHsgcmV0dXJuICh7CiAgICAgICAgICAvLyBzbG90IHByb3BzIGFyZSBjYW1lbGl6ZWQKICAgICAgICAgIG5hbWU6IGNhbWVsaXplKGF0dHIubmFtZSksCiAgICAgICAgICB2YWx1ZTogYXR0ci52YWx1ZSwKICAgICAgICAgIGR5bmFtaWM6IGF0dHIuZHluYW1pYwogICAgICAgIH0pOyB9KSkKICAgICAgOiBudWxsOwogICAgdmFyIGJpbmQkJDEgPSBlbC5hdHRyc01hcFsndi1iaW5kJ107CiAgICBpZiAoKGF0dHJzIHx8IGJpbmQkJDEpICYmICFjaGlsZHJlbikgewogICAgICByZXMgKz0gIixudWxsIjsKICAgIH0KICAgIGlmIChhdHRycykgewogICAgICByZXMgKz0gIiwiICsgYXR0cnM7CiAgICB9CiAgICBpZiAoYmluZCQkMSkgewogICAgICByZXMgKz0gKGF0dHJzID8gJycgOiAnLG51bGwnKSArICIsIiArIGJpbmQkJDE7CiAgICB9CiAgICByZXR1cm4gcmVzICsgJyknCiAgfQoKICAvLyBjb21wb25lbnROYW1lIGlzIGVsLmNvbXBvbmVudCwgdGFrZSBpdCBhcyBhcmd1bWVudCB0byBzaHVuIGZsb3cncyBwZXNzaW1pc3RpYyByZWZpbmVtZW50CiAgZnVuY3Rpb24gZ2VuQ29tcG9uZW50ICgKICAgIGNvbXBvbmVudE5hbWUsCiAgICBlbCwKICAgIHN0YXRlCiAgKSB7CiAgICB2YXIgY2hpbGRyZW4gPSBlbC5pbmxpbmVUZW1wbGF0ZSA/IG51bGwgOiBnZW5DaGlsZHJlbihlbCwgc3RhdGUsIHRydWUpOwogICAgcmV0dXJuICgiX2MoIiArIGNvbXBvbmVudE5hbWUgKyAiLCIgKyAoZ2VuRGF0YSQyKGVsLCBzdGF0ZSkpICsgKGNoaWxkcmVuID8gKCIsIiArIGNoaWxkcmVuKSA6ICcnKSArICIpIikKICB9CgogIGZ1bmN0aW9uIGdlblByb3BzIChwcm9wcykgewogICAgdmFyIHN0YXRpY1Byb3BzID0gIiI7CiAgICB2YXIgZHluYW1pY1Byb3BzID0gIiI7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBwcm9wID0gcHJvcHNbaV07CiAgICAgIHZhciB2YWx1ZSA9IHRyYW5zZm9ybVNwZWNpYWxOZXdsaW5lcyhwcm9wLnZhbHVlKTsKICAgICAgaWYgKHByb3AuZHluYW1pYykgewogICAgICAgIGR5bmFtaWNQcm9wcyArPSAocHJvcC5uYW1lKSArICIsIiArIHZhbHVlICsgIiwiOwogICAgICB9IGVsc2UgewogICAgICAgIHN0YXRpY1Byb3BzICs9ICJcIiIgKyAocHJvcC5uYW1lKSArICJcIjoiICsgdmFsdWUgKyAiLCI7CiAgICAgIH0KICAgIH0KICAgIHN0YXRpY1Byb3BzID0gInsiICsgKHN0YXRpY1Byb3BzLnNsaWNlKDAsIC0xKSkgKyAifSI7CiAgICBpZiAoZHluYW1pY1Byb3BzKSB7CiAgICAgIHJldHVybiAoIl9kKCIgKyBzdGF0aWNQcm9wcyArICIsWyIgKyAoZHluYW1pY1Byb3BzLnNsaWNlKDAsIC0xKSkgKyAiXSkiKQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIHN0YXRpY1Byb3BzCiAgICB9CiAgfQoKICAvLyAjMzg5NSwgIzQyNjgKICBmdW5jdGlvbiB0cmFuc2Zvcm1TcGVjaWFsTmV3bGluZXMgKHRleHQpIHsKICAgIHJldHVybiB0ZXh0CiAgICAgIC5yZXBsYWNlKC9cdTIwMjgvZywgJ1xcdTIwMjgnKQogICAgICAucmVwbGFjZSgvXHUyMDI5L2csICdcXHUyMDI5JykKICB9CgogIC8qICAqLwoKCgogIC8vIHRoZXNlIGtleXdvcmRzIHNob3VsZCBub3QgYXBwZWFyIGluc2lkZSBleHByZXNzaW9ucywgYnV0IG9wZXJhdG9ycyBsaWtlCiAgLy8gdHlwZW9mLCBpbnN0YW5jZW9mIGFuZCBpbiBhcmUgYWxsb3dlZAogIHZhciBwcm9oaWJpdGVkS2V5d29yZFJFID0gbmV3IFJlZ0V4cCgnXFxiJyArICgKICAgICdkbyxpZixmb3IsbGV0LG5ldyx0cnksdmFyLGNhc2UsZWxzZSx3aXRoLGF3YWl0LGJyZWFrLGNhdGNoLGNsYXNzLGNvbnN0LCcgKwogICAgJ3N1cGVyLHRocm93LHdoaWxlLHlpZWxkLGRlbGV0ZSxleHBvcnQsaW1wb3J0LHJldHVybixzd2l0Y2gsZGVmYXVsdCwnICsKICAgICdleHRlbmRzLGZpbmFsbHksY29udGludWUsZGVidWdnZXIsZnVuY3Rpb24sYXJndW1lbnRzJwogICkuc3BsaXQoJywnKS5qb2luKCdcXGJ8XFxiJykgKyAnXFxiJyk7CgogIC8vIHRoZXNlIHVuYXJ5IG9wZXJhdG9ycyBzaG91bGQgbm90IGJlIHVzZWQgYXMgcHJvcGVydHkvbWV0aG9kIG5hbWVzCiAgdmFyIHVuYXJ5T3BlcmF0b3JzUkUgPSBuZXcgUmVnRXhwKCdcXGInICsgKAogICAgJ2RlbGV0ZSx0eXBlb2Ysdm9pZCcKICApLnNwbGl0KCcsJykuam9pbignXFxzKlxcKFteXFwpXSpcXCl8XFxiJykgKyAnXFxzKlxcKFteXFwpXSpcXCknKTsKCiAgLy8gc3RyaXAgc3RyaW5ncyBpbiBleHByZXNzaW9ucwogIHZhciBzdHJpcFN0cmluZ1JFID0gLycoPzpbXidcXF18XFwuKSonfCIoPzpbXiJcXF18XFwuKSoifGAoPzpbXmBcXF18XFwuKSpcJFx7fFx9KD86W15gXFxdfFxcLikqYHxgKD86W15gXFxdfFxcLikqYC9nOwoKICAvLyBkZXRlY3QgcHJvYmxlbWF0aWMgZXhwcmVzc2lvbnMgaW4gYSB0ZW1wbGF0ZQogIGZ1bmN0aW9uIGRldGVjdEVycm9ycyAoYXN0LCB3YXJuKSB7CiAgICBpZiAoYXN0KSB7CiAgICAgIGNoZWNrTm9kZShhc3QsIHdhcm4pOwogICAgfQogIH0KCiAgZnVuY3Rpb24gY2hlY2tOb2RlIChub2RlLCB3YXJuKSB7CiAgICBpZiAobm9kZS50eXBlID09PSAxKSB7CiAgICAgIGZvciAodmFyIG5hbWUgaW4gbm9kZS5hdHRyc01hcCkgewogICAgICAgIGlmIChkaXJSRS50ZXN0KG5hbWUpKSB7CiAgICAgICAgICB2YXIgdmFsdWUgPSBub2RlLmF0dHJzTWFwW25hbWVdOwogICAgICAgICAgaWYgKHZhbHVlKSB7CiAgICAgICAgICAgIHZhciByYW5nZSA9IG5vZGUucmF3QXR0cnNNYXBbbmFtZV07CiAgICAgICAgICAgIGlmIChuYW1lID09PSAndi1mb3InKSB7CiAgICAgICAgICAgICAgY2hlY2tGb3Iobm9kZSwgKCJ2LWZvcj1cIiIgKyB2YWx1ZSArICJcIiIpLCB3YXJuLCByYW5nZSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAob25SRS50ZXN0KG5hbWUpKSB7CiAgICAgICAgICAgICAgY2hlY2tFdmVudCh2YWx1ZSwgKG5hbWUgKyAiPVwiIiArIHZhbHVlICsgIlwiIiksIHdhcm4sIHJhbmdlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBjaGVja0V4cHJlc3Npb24odmFsdWUsIChuYW1lICsgIj1cIiIgKyB2YWx1ZSArICJcIiIpLCB3YXJuLCByYW5nZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKG5vZGUuY2hpbGRyZW4pIHsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsKICAgICAgICAgIGNoZWNrTm9kZShub2RlLmNoaWxkcmVuW2ldLCB3YXJuKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSBpZiAobm9kZS50eXBlID09PSAyKSB7CiAgICAgIGNoZWNrRXhwcmVzc2lvbihub2RlLmV4cHJlc3Npb24sIG5vZGUudGV4dCwgd2Fybiwgbm9kZSk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBjaGVja0V2ZW50IChleHAsIHRleHQsIHdhcm4sIHJhbmdlKSB7CiAgICB2YXIgc3RpcHBlZCA9IGV4cC5yZXBsYWNlKHN0cmlwU3RyaW5nUkUsICcnKTsKICAgIHZhciBrZXl3b3JkTWF0Y2ggPSBzdGlwcGVkLm1hdGNoKHVuYXJ5T3BlcmF0b3JzUkUpOwogICAgaWYgKGtleXdvcmRNYXRjaCAmJiBzdGlwcGVkLmNoYXJBdChrZXl3b3JkTWF0Y2guaW5kZXggLSAxKSAhPT0gJyQnKSB7CiAgICAgIHdhcm4oCiAgICAgICAgImF2b2lkIHVzaW5nIEphdmFTY3JpcHQgdW5hcnkgb3BlcmF0b3IgYXMgcHJvcGVydHkgbmFtZTogIiArCiAgICAgICAgIlwiIiArIChrZXl3b3JkTWF0Y2hbMF0pICsgIlwiIGluIGV4cHJlc3Npb24gIiArICh0ZXh0LnRyaW0oKSksCiAgICAgICAgcmFuZ2UKICAgICAgKTsKICAgIH0KICAgIGNoZWNrRXhwcmVzc2lvbihleHAsIHRleHQsIHdhcm4sIHJhbmdlKTsKICB9CgogIGZ1bmN0aW9uIGNoZWNrRm9yIChub2RlLCB0ZXh0LCB3YXJuLCByYW5nZSkgewogICAgY2hlY2tFeHByZXNzaW9uKG5vZGUuZm9yIHx8ICcnLCB0ZXh0LCB3YXJuLCByYW5nZSk7CiAgICBjaGVja0lkZW50aWZpZXIobm9kZS5hbGlhcywgJ3YtZm9yIGFsaWFzJywgdGV4dCwgd2FybiwgcmFuZ2UpOwogICAgY2hlY2tJZGVudGlmaWVyKG5vZGUuaXRlcmF0b3IxLCAndi1mb3IgaXRlcmF0b3InLCB0ZXh0LCB3YXJuLCByYW5nZSk7CiAgICBjaGVja0lkZW50aWZpZXIobm9kZS5pdGVyYXRvcjIsICd2LWZvciBpdGVyYXRvcicsIHRleHQsIHdhcm4sIHJhbmdlKTsKICB9CgogIGZ1bmN0aW9uIGNoZWNrSWRlbnRpZmllciAoCiAgICBpZGVudCwKICAgIHR5cGUsCiAgICB0ZXh0LAogICAgd2FybiwKICAgIHJhbmdlCiAgKSB7CiAgICBpZiAodHlwZW9mIGlkZW50ID09PSAnc3RyaW5nJykgewogICAgICB0cnkgewogICAgICAgIG5ldyBGdW5jdGlvbigoInZhciAiICsgaWRlbnQgKyAiPV8iKSk7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICB3YXJuKCgiaW52YWxpZCAiICsgdHlwZSArICIgXCIiICsgaWRlbnQgKyAiXCIgaW4gZXhwcmVzc2lvbjogIiArICh0ZXh0LnRyaW0oKSkpLCByYW5nZSk7CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIGNoZWNrRXhwcmVzc2lvbiAoZXhwLCB0ZXh0LCB3YXJuLCByYW5nZSkgewogICAgdHJ5IHsKICAgICAgbmV3IEZ1bmN0aW9uKCgicmV0dXJuICIgKyBleHApKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgdmFyIGtleXdvcmRNYXRjaCA9IGV4cC5yZXBsYWNlKHN0cmlwU3RyaW5nUkUsICcnKS5tYXRjaChwcm9oaWJpdGVkS2V5d29yZFJFKTsKICAgICAgaWYgKGtleXdvcmRNYXRjaCkgewogICAgICAgIHdhcm4oCiAgICAgICAgICAiYXZvaWQgdXNpbmcgSmF2YVNjcmlwdCBrZXl3b3JkIGFzIHByb3BlcnR5IG5hbWU6ICIgKwogICAgICAgICAgIlwiIiArIChrZXl3b3JkTWF0Y2hbMF0pICsgIlwiXG4gIFJhdyBleHByZXNzaW9uOiAiICsgKHRleHQudHJpbSgpKSwKICAgICAgICAgIHJhbmdlCiAgICAgICAgKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB3YXJuKAogICAgICAgICAgImludmFsaWQgZXhwcmVzc2lvbjogIiArIChlLm1lc3NhZ2UpICsgIiBpblxuXG4iICsKICAgICAgICAgICIgICAgIiArIGV4cCArICJcblxuIiArCiAgICAgICAgICAiICBSYXcgZXhwcmVzc2lvbjogIiArICh0ZXh0LnRyaW0oKSkgKyAiXG4iLAogICAgICAgICAgcmFuZ2UKICAgICAgICApOwogICAgICB9CiAgICB9CiAgfQoKICAvKiAgKi8KCiAgdmFyIHJhbmdlID0gMjsKCiAgZnVuY3Rpb24gZ2VuZXJhdGVDb2RlRnJhbWUgKAogICAgc291cmNlLAogICAgc3RhcnQsCiAgICBlbmQKICApIHsKICAgIGlmICggc3RhcnQgPT09IHZvaWQgMCApIHN0YXJ0ID0gMDsKICAgIGlmICggZW5kID09PSB2b2lkIDAgKSBlbmQgPSBzb3VyY2UubGVuZ3RoOwoKICAgIHZhciBsaW5lcyA9IHNvdXJjZS5zcGxpdCgvXHI/XG4vKTsKICAgIHZhciBjb3VudCA9IDA7CiAgICB2YXIgcmVzID0gW107CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7CiAgICAgIGNvdW50ICs9IGxpbmVzW2ldLmxlbmd0aCArIDE7CiAgICAgIGlmIChjb3VudCA+PSBzdGFydCkgewogICAgICAgIGZvciAodmFyIGogPSBpIC0gcmFuZ2U7IGogPD0gaSArIHJhbmdlIHx8IGVuZCA+IGNvdW50OyBqKyspIHsKICAgICAgICAgIGlmIChqIDwgMCB8fCBqID49IGxpbmVzLmxlbmd0aCkgeyBjb250aW51ZSB9CiAgICAgICAgICByZXMucHVzaCgoIiIgKyAoaiArIDEpICsgKHJlcGVhdCQxKCIgIiwgMyAtIFN0cmluZyhqICsgMSkubGVuZ3RoKSkgKyAifCAgIiArIChsaW5lc1tqXSkpKTsKICAgICAgICAgIHZhciBsaW5lTGVuZ3RoID0gbGluZXNbal0ubGVuZ3RoOwogICAgICAgICAgaWYgKGogPT09IGkpIHsKICAgICAgICAgICAgLy8gcHVzaCB1bmRlcmxpbmUKICAgICAgICAgICAgdmFyIHBhZCA9IHN0YXJ0IC0gKGNvdW50IC0gbGluZUxlbmd0aCkgKyAxOwogICAgICAgICAgICB2YXIgbGVuZ3RoID0gZW5kID4gY291bnQgPyBsaW5lTGVuZ3RoIC0gcGFkIDogZW5kIC0gc3RhcnQ7CiAgICAgICAgICAgIHJlcy5wdXNoKCIgICB8ICAiICsgcmVwZWF0JDEoIiAiLCBwYWQpICsgcmVwZWF0JDEoIl4iLCBsZW5ndGgpKTsKICAgICAgICAgIH0gZWxzZSBpZiAoaiA+IGkpIHsKICAgICAgICAgICAgaWYgKGVuZCA+IGNvdW50KSB7CiAgICAgICAgICAgICAgdmFyIGxlbmd0aCQxID0gTWF0aC5taW4oZW5kIC0gY291bnQsIGxpbmVMZW5ndGgpOwogICAgICAgICAgICAgIHJlcy5wdXNoKCIgICB8ICAiICsgcmVwZWF0JDEoIl4iLCBsZW5ndGgkMSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvdW50ICs9IGxpbmVMZW5ndGggKyAxOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhawogICAgICB9CiAgICB9CiAgICByZXR1cm4gcmVzLmpvaW4oJ1xuJykKICB9CgogIGZ1bmN0aW9uIHJlcGVhdCQxIChzdHIsIG4pIHsKICAgIHZhciByZXN1bHQgPSAnJzsKICAgIGlmIChuID4gMCkgewogICAgICB3aGlsZSAodHJ1ZSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lCiAgICAgICAgaWYgKG4gJiAxKSB7IHJlc3VsdCArPSBzdHI7IH0KICAgICAgICBuID4+Pj0gMTsKICAgICAgICBpZiAobiA8PSAwKSB7IGJyZWFrIH0KICAgICAgICBzdHIgKz0gc3RyOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gcmVzdWx0CiAgfQoKICAvKiAgKi8KCgoKICBmdW5jdGlvbiBjcmVhdGVGdW5jdGlvbiAoY29kZSwgZXJyb3JzKSB7CiAgICB0cnkgewogICAgICByZXR1cm4gbmV3IEZ1bmN0aW9uKGNvZGUpCiAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgZXJyb3JzLnB1c2goeyBlcnI6IGVyciwgY29kZTogY29kZSB9KTsKICAgICAgcmV0dXJuIG5vb3AKICAgIH0KICB9CgogIGZ1bmN0aW9uIGNyZWF0ZUNvbXBpbGVUb0Z1bmN0aW9uRm4gKGNvbXBpbGUpIHsKICAgIHZhciBjYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7CgogICAgcmV0dXJuIGZ1bmN0aW9uIGNvbXBpbGVUb0Z1bmN0aW9ucyAoCiAgICAgIHRlbXBsYXRlLAogICAgICBvcHRpb25zLAogICAgICB2bQogICAgKSB7CiAgICAgIG9wdGlvbnMgPSBleHRlbmQoe30sIG9wdGlvbnMpOwogICAgICB2YXIgd2FybiQkMSA9IG9wdGlvbnMud2FybiB8fCB3YXJuOwogICAgICBkZWxldGUgb3B0aW9ucy53YXJuOwoKICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICAgIHsKICAgICAgICAvLyBkZXRlY3QgcG9zc2libGUgQ1NQIHJlc3RyaWN0aW9uCiAgICAgICAgdHJ5IHsKICAgICAgICAgIG5ldyBGdW5jdGlvbigncmV0dXJuIDEnKTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICBpZiAoZS50b1N0cmluZygpLm1hdGNoKC91bnNhZmUtZXZhbHxDU1AvKSkgewogICAgICAgICAgICB3YXJuJCQxKAogICAgICAgICAgICAgICdJdCBzZWVtcyB5b3UgYXJlIHVzaW5nIHRoZSBzdGFuZGFsb25lIGJ1aWxkIG9mIFZ1ZS5qcyBpbiBhbiAnICsKICAgICAgICAgICAgICAnZW52aXJvbm1lbnQgd2l0aCBDb250ZW50IFNlY3VyaXR5IFBvbGljeSB0aGF0IHByb2hpYml0cyB1bnNhZmUtZXZhbC4gJyArCiAgICAgICAgICAgICAgJ1RoZSB0ZW1wbGF0ZSBjb21waWxlciBjYW5ub3Qgd29yayBpbiB0aGlzIGVudmlyb25tZW50LiBDb25zaWRlciAnICsKICAgICAgICAgICAgICAncmVsYXhpbmcgdGhlIHBvbGljeSB0byBhbGxvdyB1bnNhZmUtZXZhbCBvciBwcmUtY29tcGlsaW5nIHlvdXIgJyArCiAgICAgICAgICAgICAgJ3RlbXBsYXRlcyBpbnRvIHJlbmRlciBmdW5jdGlvbnMuJwogICAgICAgICAgICApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gY2hlY2sgY2FjaGUKICAgICAgdmFyIGtleSA9IG9wdGlvbnMuZGVsaW1pdGVycwogICAgICAgID8gU3RyaW5nKG9wdGlvbnMuZGVsaW1pdGVycykgKyB0ZW1wbGF0ZQogICAgICAgIDogdGVtcGxhdGU7CiAgICAgIGlmIChjYWNoZVtrZXldKSB7CiAgICAgICAgcmV0dXJuIGNhY2hlW2tleV0KICAgICAgfQoKICAgICAgLy8gY29tcGlsZQogICAgICB2YXIgY29tcGlsZWQgPSBjb21waWxlKHRlbXBsYXRlLCBvcHRpb25zKTsKCiAgICAgIC8vIGNoZWNrIGNvbXBpbGF0aW9uIGVycm9ycy90aXBzCiAgICAgIHsKICAgICAgICBpZiAoY29tcGlsZWQuZXJyb3JzICYmIGNvbXBpbGVkLmVycm9ycy5sZW5ndGgpIHsKICAgICAgICAgIGlmIChvcHRpb25zLm91dHB1dFNvdXJjZVJhbmdlKSB7CiAgICAgICAgICAgIGNvbXBpbGVkLmVycm9ycy5mb3JFYWNoKGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgd2FybiQkMSgKICAgICAgICAgICAgICAgICJFcnJvciBjb21waWxpbmcgdGVtcGxhdGU6XG5cbiIgKyAoZS5tc2cpICsgIlxuXG4iICsKICAgICAgICAgICAgICAgIGdlbmVyYXRlQ29kZUZyYW1lKHRlbXBsYXRlLCBlLnN0YXJ0LCBlLmVuZCksCiAgICAgICAgICAgICAgICB2bQogICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgd2FybiQkMSgKICAgICAgICAgICAgICAiRXJyb3IgY29tcGlsaW5nIHRlbXBsYXRlOlxuXG4iICsgdGVtcGxhdGUgKyAiXG5cbiIgKwogICAgICAgICAgICAgIGNvbXBpbGVkLmVycm9ycy5tYXAoZnVuY3Rpb24gKGUpIHsgcmV0dXJuICgiLSAiICsgZSk7IH0pLmpvaW4oJ1xuJykgKyAnXG4nLAogICAgICAgICAgICAgIHZtCiAgICAgICAgICAgICk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChjb21waWxlZC50aXBzICYmIGNvbXBpbGVkLnRpcHMubGVuZ3RoKSB7CiAgICAgICAgICBpZiAob3B0aW9ucy5vdXRwdXRTb3VyY2VSYW5nZSkgewogICAgICAgICAgICBjb21waWxlZC50aXBzLmZvckVhY2goZnVuY3Rpb24gKGUpIHsgcmV0dXJuIHRpcChlLm1zZywgdm0pOyB9KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNvbXBpbGVkLnRpcHMuZm9yRWFjaChmdW5jdGlvbiAobXNnKSB7IHJldHVybiB0aXAobXNnLCB2bSk7IH0pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gdHVybiBjb2RlIGludG8gZnVuY3Rpb25zCiAgICAgIHZhciByZXMgPSB7fTsKICAgICAgdmFyIGZuR2VuRXJyb3JzID0gW107CiAgICAgIHJlcy5yZW5kZXIgPSBjcmVhdGVGdW5jdGlvbihjb21waWxlZC5yZW5kZXIsIGZuR2VuRXJyb3JzKTsKICAgICAgcmVzLnN0YXRpY1JlbmRlckZucyA9IGNvbXBpbGVkLnN0YXRpY1JlbmRlckZucy5tYXAoZnVuY3Rpb24gKGNvZGUpIHsKICAgICAgICByZXR1cm4gY3JlYXRlRnVuY3Rpb24oY29kZSwgZm5HZW5FcnJvcnMpCiAgICAgIH0pOwoKICAgICAgLy8gY2hlY2sgZnVuY3Rpb24gZ2VuZXJhdGlvbiBlcnJvcnMuCiAgICAgIC8vIHRoaXMgc2hvdWxkIG9ubHkgaGFwcGVuIGlmIHRoZXJlIGlzIGEgYnVnIGluIHRoZSBjb21waWxlciBpdHNlbGYuCiAgICAgIC8vIG1vc3RseSBmb3IgY29kZWdlbiBkZXZlbG9wbWVudCB1c2UKICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICAgIHsKICAgICAgICBpZiAoKCFjb21waWxlZC5lcnJvcnMgfHwgIWNvbXBpbGVkLmVycm9ycy5sZW5ndGgpICYmIGZuR2VuRXJyb3JzLmxlbmd0aCkgewogICAgICAgICAgd2FybiQkMSgKICAgICAgICAgICAgIkZhaWxlZCB0byBnZW5lcmF0ZSByZW5kZXIgZnVuY3Rpb246XG5cbiIgKwogICAgICAgICAgICBmbkdlbkVycm9ycy5tYXAoZnVuY3Rpb24gKHJlZikgewogICAgICAgICAgICAgIHZhciBlcnIgPSByZWYuZXJyOwogICAgICAgICAgICAgIHZhciBjb2RlID0gcmVmLmNvZGU7CgogICAgICAgICAgICAgIHJldHVybiAoKGVyci50b1N0cmluZygpKSArICIgaW5cblxuIiArIGNvZGUgKyAiXG4iKTsKICAgICAgICAgIH0pLmpvaW4oJ1xuJyksCiAgICAgICAgICAgIHZtCiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcmV0dXJuIChjYWNoZVtrZXldID0gcmVzKQogICAgfQogIH0KCiAgLyogICovCgogIGZ1bmN0aW9uIGNyZWF0ZUNvbXBpbGVyQ3JlYXRvciAoYmFzZUNvbXBpbGUpIHsKICAgIHJldHVybiBmdW5jdGlvbiBjcmVhdGVDb21waWxlciAoYmFzZU9wdGlvbnMpIHsKICAgICAgZnVuY3Rpb24gY29tcGlsZSAoCiAgICAgICAgdGVtcGxhdGUsCiAgICAgICAgb3B0aW9ucwogICAgICApIHsKICAgICAgICB2YXIgZmluYWxPcHRpb25zID0gT2JqZWN0LmNyZWF0ZShiYXNlT3B0aW9ucyk7CiAgICAgICAgdmFyIGVycm9ycyA9IFtdOwogICAgICAgIHZhciB0aXBzID0gW107CgogICAgICAgIHZhciB3YXJuID0gZnVuY3Rpb24gKG1zZywgcmFuZ2UsIHRpcCkgewogICAgICAgICAgKHRpcCA/IHRpcHMgOiBlcnJvcnMpLnB1c2gobXNnKTsKICAgICAgICB9OwoKICAgICAgICBpZiAob3B0aW9ucykgewogICAgICAgICAgaWYgKG9wdGlvbnMub3V0cHV0U291cmNlUmFuZ2UpIHsKICAgICAgICAgICAgLy8gJGZsb3ctZGlzYWJsZS1saW5lCiAgICAgICAgICAgIHZhciBsZWFkaW5nU3BhY2VMZW5ndGggPSB0ZW1wbGF0ZS5tYXRjaCgvXlxzKi8pWzBdLmxlbmd0aDsKCiAgICAgICAgICAgIHdhcm4gPSBmdW5jdGlvbiAobXNnLCByYW5nZSwgdGlwKSB7CiAgICAgICAgICAgICAgdmFyIGRhdGEgPSB7IG1zZzogbXNnIH07CiAgICAgICAgICAgICAgaWYgKHJhbmdlKSB7CiAgICAgICAgICAgICAgICBpZiAocmFuZ2Uuc3RhcnQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBkYXRhLnN0YXJ0ID0gcmFuZ2Uuc3RhcnQgKyBsZWFkaW5nU3BhY2VMZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAocmFuZ2UuZW5kICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZGF0YS5lbmQgPSByYW5nZS5lbmQgKyBsZWFkaW5nU3BhY2VMZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICh0aXAgPyB0aXBzIDogZXJyb3JzKS5wdXNoKGRhdGEpOwogICAgICAgICAgICB9OwogICAgICAgICAgfQogICAgICAgICAgLy8gbWVyZ2UgY3VzdG9tIG1vZHVsZXMKICAgICAgICAgIGlmIChvcHRpb25zLm1vZHVsZXMpIHsKICAgICAgICAgICAgZmluYWxPcHRpb25zLm1vZHVsZXMgPQogICAgICAgICAgICAgIChiYXNlT3B0aW9ucy5tb2R1bGVzIHx8IFtdKS5jb25jYXQob3B0aW9ucy5tb2R1bGVzKTsKICAgICAgICAgIH0KICAgICAgICAgIC8vIG1lcmdlIGN1c3RvbSBkaXJlY3RpdmVzCiAgICAgICAgICBpZiAob3B0aW9ucy5kaXJlY3RpdmVzKSB7CiAgICAgICAgICAgIGZpbmFsT3B0aW9ucy5kaXJlY3RpdmVzID0gZXh0ZW5kKAogICAgICAgICAgICAgIE9iamVjdC5jcmVhdGUoYmFzZU9wdGlvbnMuZGlyZWN0aXZlcyB8fCBudWxsKSwKICAgICAgICAgICAgICBvcHRpb25zLmRpcmVjdGl2ZXMKICAgICAgICAgICAgKTsKICAgICAgICAgIH0KICAgICAgICAgIC8vIGNvcHkgb3RoZXIgb3B0aW9ucwogICAgICAgICAgZm9yICh2YXIga2V5IGluIG9wdGlvbnMpIHsKICAgICAgICAgICAgaWYgKGtleSAhPT0gJ21vZHVsZXMnICYmIGtleSAhPT0gJ2RpcmVjdGl2ZXMnKSB7CiAgICAgICAgICAgICAgZmluYWxPcHRpb25zW2tleV0gPSBvcHRpb25zW2tleV07CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZpbmFsT3B0aW9ucy53YXJuID0gd2FybjsKCiAgICAgICAgdmFyIGNvbXBpbGVkID0gYmFzZUNvbXBpbGUodGVtcGxhdGUudHJpbSgpLCBmaW5hbE9wdGlvbnMpOwogICAgICAgIHsKICAgICAgICAgIGRldGVjdEVycm9ycyhjb21waWxlZC5hc3QsIHdhcm4pOwogICAgICAgIH0KICAgICAgICBjb21waWxlZC5lcnJvcnMgPSBlcnJvcnM7CiAgICAgICAgY29tcGlsZWQudGlwcyA9IHRpcHM7CiAgICAgICAgcmV0dXJuIGNvbXBpbGVkCiAgICAgIH0KCiAgICAgIHJldHVybiB7CiAgICAgICAgY29tcGlsZTogY29tcGlsZSwKICAgICAgICBjb21waWxlVG9GdW5jdGlvbnM6IGNyZWF0ZUNvbXBpbGVUb0Z1bmN0aW9uRm4oY29tcGlsZSkKICAgICAgfQogICAgfQogIH0KCiAgLyogICovCgogIC8vIGBjcmVhdGVDb21waWxlckNyZWF0b3JgIGFsbG93cyBjcmVhdGluZyBjb21waWxlcnMgdGhhdCB1c2UgYWx0ZXJuYXRpdmUKICAvLyBwYXJzZXIvb3B0aW1pemVyL2NvZGVnZW4sIGUuZyB0aGUgU1NSIG9wdGltaXppbmcgY29tcGlsZXIuCiAgLy8gSGVyZSB3ZSBqdXN0IGV4cG9ydCBhIGRlZmF1bHQgY29tcGlsZXIgdXNpbmcgdGhlIGRlZmF1bHQgcGFydHMuCiAgdmFyIGNyZWF0ZUNvbXBpbGVyID0gY3JlYXRlQ29tcGlsZXJDcmVhdG9yKGZ1bmN0aW9uIGJhc2VDb21waWxlICgKICAgIHRlbXBsYXRlLAogICAgb3B0aW9ucwogICkgewogICAgdmFyIGFzdCA9IHBhcnNlKHRlbXBsYXRlLnRyaW0oKSwgb3B0aW9ucyk7CiAgICBpZiAob3B0aW9ucy5vcHRpbWl6ZSAhPT0gZmFsc2UpIHsKICAgICAgb3B0aW1pemUoYXN0LCBvcHRpb25zKTsKICAgIH0KICAgIHZhciBjb2RlID0gZ2VuZXJhdGUoYXN0LCBvcHRpb25zKTsKICAgIHJldHVybiB7CiAgICAgIGFzdDogYXN0LAogICAgICByZW5kZXI6IGNvZGUucmVuZGVyLAogICAgICBzdGF0aWNSZW5kZXJGbnM6IGNvZGUuc3RhdGljUmVuZGVyRm5zCiAgICB9CiAgfSk7CgogIC8qICAqLwoKICB2YXIgcmVmJDEgPSBjcmVhdGVDb21waWxlcihiYXNlT3B0aW9ucyk7CiAgdmFyIGNvbXBpbGUgPSByZWYkMS5jb21waWxlOwogIHZhciBjb21waWxlVG9GdW5jdGlvbnMgPSByZWYkMS5jb21waWxlVG9GdW5jdGlvbnM7CgogIC8qICAqLwoKICAvLyBjaGVjayB3aGV0aGVyIGN1cnJlbnQgYnJvd3NlciBlbmNvZGVzIGEgY2hhciBpbnNpZGUgYXR0cmlidXRlIHZhbHVlcwogIHZhciBkaXY7CiAgZnVuY3Rpb24gZ2V0U2hvdWxkRGVjb2RlIChocmVmKSB7CiAgICBkaXYgPSBkaXYgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CiAgICBkaXYuaW5uZXJIVE1MID0gaHJlZiA/ICI8YSBocmVmPVwiXG5cIi8+IiA6ICI8ZGl2IGE9XCJcblwiLz4iOwogICAgcmV0dXJuIGRpdi5pbm5lckhUTUwuaW5kZXhPZignJiMxMDsnKSA+IDAKICB9CgogIC8vICMzNjYzOiBJRSBlbmNvZGVzIG5ld2xpbmVzIGluc2lkZSBhdHRyaWJ1dGUgdmFsdWVzIHdoaWxlIG90aGVyIGJyb3dzZXJzIGRvbid0CiAgdmFyIHNob3VsZERlY29kZU5ld2xpbmVzID0gaW5Ccm93c2VyID8gZ2V0U2hvdWxkRGVjb2RlKGZhbHNlKSA6IGZhbHNlOwogIC8vICM2ODI4OiBjaHJvbWUgZW5jb2RlcyBjb250ZW50IGluIGFbaHJlZl0KICB2YXIgc2hvdWxkRGVjb2RlTmV3bGluZXNGb3JIcmVmID0gaW5Ccm93c2VyID8gZ2V0U2hvdWxkRGVjb2RlKHRydWUpIDogZmFsc2U7CgogIC8qICAqLwoKICB2YXIgaWRUb1RlbXBsYXRlID0gY2FjaGVkKGZ1bmN0aW9uIChpZCkgewogICAgdmFyIGVsID0gcXVlcnkoaWQpOwogICAgcmV0dXJuIGVsICYmIGVsLmlubmVySFRNTAogIH0pOwoKICB2YXIgbW91bnQgPSBWdWUucHJvdG90eXBlLiRtb3VudDsKICBWdWUucHJvdG90eXBlLiRtb3VudCA9IGZ1bmN0aW9uICgKICAgIGVsLAogICAgaHlkcmF0aW5nCiAgKSB7CiAgICBlbCA9IGVsICYmIHF1ZXJ5KGVsKTsKCiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgIGlmIChlbCA9PT0gZG9jdW1lbnQuYm9keSB8fCBlbCA9PT0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7CiAgICAgIHdhcm4oCiAgICAgICAgIkRvIG5vdCBtb3VudCBWdWUgdG8gPGh0bWw+IG9yIDxib2R5PiAtIG1vdW50IHRvIG5vcm1hbCBlbGVtZW50cyBpbnN0ZWFkLiIKICAgICAgKTsKICAgICAgcmV0dXJuIHRoaXMKICAgIH0KCiAgICB2YXIgb3B0aW9ucyA9IHRoaXMuJG9wdGlvbnM7CiAgICAvLyByZXNvbHZlIHRlbXBsYXRlL2VsIGFuZCBjb252ZXJ0IHRvIHJlbmRlciBmdW5jdGlvbgogICAgaWYgKCFvcHRpb25zLnJlbmRlcikgewogICAgICB2YXIgdGVtcGxhdGUgPSBvcHRpb25zLnRlbXBsYXRlOwogICAgICBpZiAodGVtcGxhdGUpIHsKICAgICAgICBpZiAodHlwZW9mIHRlbXBsYXRlID09PSAnc3RyaW5nJykgewogICAgICAgICAgaWYgKHRlbXBsYXRlLmNoYXJBdCgwKSA9PT0gJyMnKSB7CiAgICAgICAgICAgIHRlbXBsYXRlID0gaWRUb1RlbXBsYXRlKHRlbXBsYXRlKTsKICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovCiAgICAgICAgICAgIGlmICghdGVtcGxhdGUpIHsKICAgICAgICAgICAgICB3YXJuKAogICAgICAgICAgICAgICAgKCJUZW1wbGF0ZSBlbGVtZW50IG5vdCBmb3VuZCBvciBpcyBlbXB0eTogIiArIChvcHRpb25zLnRlbXBsYXRlKSksCiAgICAgICAgICAgICAgICB0aGlzCiAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAodGVtcGxhdGUubm9kZVR5cGUpIHsKICAgICAgICAgIHRlbXBsYXRlID0gdGVtcGxhdGUuaW5uZXJIVE1MOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB7CiAgICAgICAgICAgIHdhcm4oJ2ludmFsaWQgdGVtcGxhdGUgb3B0aW9uOicgKyB0ZW1wbGF0ZSwgdGhpcyk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpcwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChlbCkgewogICAgICAgIHRlbXBsYXRlID0gZ2V0T3V0ZXJIVE1MKGVsKTsKICAgICAgfQogICAgICBpZiAodGVtcGxhdGUpIHsKICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi8KICAgICAgICBpZiAoY29uZmlnLnBlcmZvcm1hbmNlICYmIG1hcmspIHsKICAgICAgICAgIG1hcmsoJ2NvbXBpbGUnKTsKICAgICAgICB9CgogICAgICAgIHZhciByZWYgPSBjb21waWxlVG9GdW5jdGlvbnModGVtcGxhdGUsIHsKICAgICAgICAgIG91dHB1dFNvdXJjZVJhbmdlOiAiZGV2ZWxvcG1lbnQiICE9PSAncHJvZHVjdGlvbicsCiAgICAgICAgICBzaG91bGREZWNvZGVOZXdsaW5lczogc2hvdWxkRGVjb2RlTmV3bGluZXMsCiAgICAgICAgICBzaG91bGREZWNvZGVOZXdsaW5lc0ZvckhyZWY6IHNob3VsZERlY29kZU5ld2xpbmVzRm9ySHJlZiwKICAgICAgICAgIGRlbGltaXRlcnM6IG9wdGlvbnMuZGVsaW1pdGVycywKICAgICAgICAgIGNvbW1lbnRzOiBvcHRpb25zLmNvbW1lbnRzCiAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgdmFyIHJlbmRlciA9IHJlZi5yZW5kZXI7CiAgICAgICAgdmFyIHN0YXRpY1JlbmRlckZucyA9IHJlZi5zdGF0aWNSZW5kZXJGbnM7CiAgICAgICAgb3B0aW9ucy5yZW5kZXIgPSByZW5kZXI7CiAgICAgICAgb3B0aW9ucy5zdGF0aWNSZW5kZXJGbnMgPSBzdGF0aWNSZW5kZXJGbnM7CgogICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqLwogICAgICAgIGlmIChjb25maWcucGVyZm9ybWFuY2UgJiYgbWFyaykgewogICAgICAgICAgbWFyaygnY29tcGlsZSBlbmQnKTsKICAgICAgICAgIG1lYXN1cmUoKCJ2dWUgIiArICh0aGlzLl9uYW1lKSArICIgY29tcGlsZSIpLCAnY29tcGlsZScsICdjb21waWxlIGVuZCcpOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIG1vdW50LmNhbGwodGhpcywgZWwsIGh5ZHJhdGluZykKICB9OwoKICAvKioKICAgKiBHZXQgb3V0ZXJIVE1MIG9mIGVsZW1lbnRzLCB0YWtpbmcgY2FyZQogICAqIG9mIFNWRyBlbGVtZW50cyBpbiBJRSBhcyB3ZWxsLgogICAqLwogIGZ1bmN0aW9uIGdldE91dGVySFRNTCAoZWwpIHsKICAgIGlmIChlbC5vdXRlckhUTUwpIHsKICAgICAgcmV0dXJuIGVsLm91dGVySFRNTAogICAgfSBlbHNlIHsKICAgICAgdmFyIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoZWwuY2xvbmVOb2RlKHRydWUpKTsKICAgICAgcmV0dXJuIGNvbnRhaW5lci5pbm5lckhUTUwKICAgIH0KICB9CgogIFZ1ZS5jb21waWxlID0gY29tcGlsZVRvRnVuY3Rpb25zOwoKICByZXR1cm4gVnVlOwoKfSkpOwo="},{"meta":{"name":"xfetch.min.js","url":"https://unpkg.com/[email protected]/xfetch.min.js","ts":1691113794682,"mimetype":"text/javascript"},"source":"KChhLGIpPT57ImZ1bmN0aW9uIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoW10sYik6Im9iamVjdCI9PXR5cGVvZiBleHBvcnRzP21vZHVsZS5leHBvcnRzPWIoKTphLnhmPWIoKX0pKHRoaXMsKCk9Pntjb25zdCBhPVsiZ2V0IiwicG9zdCIsInB1dCIsInBhdGNoIiwiZGVsZXRlIiwiaGVhZCJdO2NsYXNzIGIgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcihhKXtzdXBlcihhLnN0YXR1c1RleHQpLHRoaXMubmFtZT0iSFRUUEVycm9yIix0aGlzLnJlc3BvbnNlPWF9fWNsYXNzIGMgZXh0ZW5kcyBQcm9taXNle31mb3IoY29uc3QgYSBvZlsiYXJyYXlCdWZmZXIiLCJibG9iIiwiZm9ybURhdGEiLCJqc29uIiwidGV4dCJdKWMucHJvdG90eXBlW2FdPWZ1bmN0aW9uKGIpe3JldHVybiB0aGlzLnRoZW4oYj0+YlthXSgpKS50aGVuKGJ8fChhPT5hKSl9O2NvbnN0e2Fzc2lnbjpkfT1PYmplY3QsZT1hPT5hLnJlZHVjZSgoYSxbYixjXSk9PihhW2JdPWMsYSkse30pLGY9KC4uLmEpPT5iPT5hLnNvbWUoYT0+InN0cmluZyI9PXR5cGVvZiBhP3R5cGVvZiBiPT1hOmIgaW5zdGFuY2VvZiBhKSxnPWYoInN0cmluZyIpLGg9Zigib2JqZWN0IiksaT1hPT5nKGEpfHxoKGEpLGo9YT0+e2lmKCFhLm9rKXRocm93IG5ldyBiKGEpO3JldHVybiBhfSxrPShoPXt9KT0+e2NvbnN0IGw9KGEsYj17fSk9PntkKGIsaCk7Y29uc3Qgaz1hPT5uZXcgYi5VUkxTZWFyY2hQYXJhbXMoYSkudG9TdHJpbmcoKSxsPW5ldyBiLlVSTChhLGIuYmFzZVVSSXx8dm9pZCAwKTtpZihiLmhlYWRlcnM/ZihiLkhlYWRlcnMpKGIuaGVhZGVycykmJihiLmhlYWRlcnM9ZShbLi4uYi5oZWFkZXJzLmVudHJpZXMoKV0pKTpiLmhlYWRlcnM9e30sYi5qc29uKWIuYm9keT1KU09OLnN0cmluZ2lmeShiLmpzb24pLGIuaGVhZGVyc1siQ29udGVudC1UeXBlIl09ImFwcGxpY2F0aW9uL2pzb24iO2Vsc2UgaWYoaShiLnVybGVuY29kZWQpKWIuYm9keT1nKGIudXJsZW5jb2RlZCk/Yi51cmxlbmNvZGVkOmsoYi51cmxlbmNvZGVkKSxiLmhlYWRlcnNbIkNvbnRlbnQtVHlwZSJdPSJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiO2Vsc2UgaWYoZihiLkZvcm1EYXRhLCJvYmplY3QiKShiLmZvcm1EYXRhKSl7aWYoIWYoYi5Gb3JtRGF0YSkoYi5mb3JtRGF0YSkpe2NvbnN0IGE9bmV3IGIuRm9ybURhdGE7Zm9yKGNvbnN0W2MsZF1vZiBPYmplY3QuZW50cmllcyhiLmZvcm1EYXRhKSlhLmFwcGVuZChjLGQpO2IuZm9ybURhdGE9YX1iLmJvZHk9Yi5mb3JtRGF0YX1yZXR1cm4gYi5xcyYmKGcoYi5xcykmJihiLnFzPShhPT5lKFsuLi5uZXcgYi5VUkxTZWFyY2hQYXJhbXMoYSkuZW50cmllcygpXSkpKGIucXMpKSxsLnNlYXJjaD1rKGQoZShbLi4ubC5zZWFyY2hQYXJhbXMuZW50cmllcygpXSksYi5xcykpKSxiLmNyZWRlbnRpYWxzfHwoYi5jcmVkZW50aWFscz0ic2FtZS1vcmlnaW4iKSxjLnJlc29sdmUoYi5mZXRjaChsLGIpLnRoZW4oaikpfTtmb3IoY29uc3QgYiBvZiBhKWxbYl09KGEsYz17fSk9PihjLm1ldGhvZD1iLnRvVXBwZXJDYXNlKCksbChhLGMpKTtyZXR1cm4gbC5leHRlbmQ9YT0+ayhkKHt9LGgsYSkpLGwuSFRUUEVycm9yPWIsbH0sbD0idW5kZWZpbmVkIiE9dHlwZW9mIGRvY3VtZW50LG09InVuZGVmaW5lZCIhPXR5cGVvZiBzZWxmO3JldHVybiBtP2soe2ZldGNoOmZldGNoLmJpbmQoc2VsZiksVVJMLFJlc3BvbnNlLFVSTFNlYXJjaFBhcmFtcyxIZWFkZXJzLEZvcm1EYXRhLGJhc2VVUkk6bD9kb2N1bWVudC5iYXNlVVJJOiIifSk6aygpfSk7"},{"meta":{"name":"ffmpeg.min.js","url":"https://unpkg.com/@ffmpeg/[email protected]/dist/ffmpeg.min.js","ts":1691113794682,"mimetype":"text/javascript"},"source":"IWZ1bmN0aW9uKHQsZSl7Im9iamVjdCI9PXR5cGVvZiBleHBvcnRzJiYib2JqZWN0Ij09dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1lKCk6ImZ1bmN0aW9uIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoW10sZSk6Im9iamVjdCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHMuRkZtcGVnPWUoKTp0LkZGbXBlZz1lKCl9KHdpbmRvdywoZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24odCl7dmFyIGU9e307ZnVuY3Rpb24gcihuKXtpZihlW25dKXJldHVybiBlW25dLmV4cG9ydHM7dmFyIG89ZVtuXT17aTpuLGw6ITEsZXhwb3J0czp7fX07cmV0dXJuIHRbbl0uY2FsbChvLmV4cG9ydHMsbyxvLmV4cG9ydHMsciksby5sPSEwLG8uZXhwb3J0c31yZXR1cm4gci5tPXQsci5jPWUsci5kPWZ1bmN0aW9uKHQsZSxuKXtyLm8odCxlKXx8T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsZSx7ZW51bWVyYWJsZTohMCxnZXQ6bn0pfSxyLnI9ZnVuY3Rpb24odCl7InVuZGVmaW5lZCIhPXR5cGVvZiBTeW1ib2wmJlN5bWJvbC50b1N0cmluZ1RhZyYmT2JqZWN0LmRlZmluZVByb3BlcnR5KHQsU3ltYm9sLnRvU3RyaW5nVGFnLHt2YWx1ZToiTW9kdWxlIn0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LCJfX2VzTW9kdWxlIix7dmFsdWU6ITB9KX0sci50PWZ1bmN0aW9uKHQsZSl7aWYoMSZlJiYodD1yKHQpKSw4JmUpcmV0dXJuIHQ7aWYoNCZlJiYib2JqZWN0Ij09dHlwZW9mIHQmJnQmJnQuX19lc01vZHVsZSlyZXR1cm4gdDt2YXIgbj1PYmplY3QuY3JlYXRlKG51bGwpO2lmKHIucihuKSxPYmplY3QuZGVmaW5lUHJvcGVydHkobiwiZGVmYXVsdCIse2VudW1lcmFibGU6ITAsdmFsdWU6dH0pLDImZSYmInN0cmluZyIhPXR5cGVvZiB0KWZvcih2YXIgbyBpbiB0KXIuZChuLG8sZnVuY3Rpb24oZSl7cmV0dXJuIHRbZV19LmJpbmQobnVsbCxvKSk7cmV0dXJuIG59LHIubj1mdW5jdGlvbih0KXt2YXIgZT10JiZ0Ll9fZXNNb2R1bGU/ZnVuY3Rpb24oKXtyZXR1cm4gdC5kZWZhdWx0fTpmdW5jdGlvbigpe3JldHVybiB0fTtyZXR1cm4gci5kKGUsImEiLGUpLGV9LHIubz1mdW5jdGlvbih0LGUpe3JldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxlKX0sci5wPSIiLHIoci5zPTQpfShbZnVuY3Rpb24odCxlKXt2YXIgcixuLG89dC5leHBvcnRzPXt9O2Z1bmN0aW9uIGkoKXt0aHJvdyBuZXcgRXJyb3IoInNldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQiKX1mdW5jdGlvbiBhKCl7dGhyb3cgbmV3IEVycm9yKCJjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQiKX1mdW5jdGlvbiBjKHQpe2lmKHI9PT1zZXRUaW1lb3V0KXJldHVybiBzZXRUaW1lb3V0KHQsMCk7aWYoKHI9PT1pfHwhcikmJnNldFRpbWVvdXQpcmV0dXJuIHI9c2V0VGltZW91dCxzZXRUaW1lb3V0KHQsMCk7dHJ5e3JldHVybiByKHQsMCl9Y2F0Y2goZSl7dHJ5e3JldHVybiByLmNhbGwobnVsbCx0LDApfWNhdGNoKGUpe3JldHVybiByLmNhbGwodGhpcyx0LDApfX19IWZ1bmN0aW9uKCl7dHJ5e3I9ImZ1bmN0aW9uIj09dHlwZW9mIHNldFRpbWVvdXQ/c2V0VGltZW91dDppfWNhdGNoKHQpe3I9aX10cnl7bj0iZnVuY3Rpb24iPT10eXBlb2YgY2xlYXJUaW1lb3V0P2NsZWFyVGltZW91dDphfWNhdGNoKHQpe249YX19KCk7dmFyIHUscz1bXSxmPSExLGw9LTE7ZnVuY3Rpb24gcCgpe2YmJnUmJihmPSExLHUubGVuZ3RoP3M9dS5jb25jYXQocyk6bD0tMSxzLmxlbmd0aCYmZCgpKX1mdW5jdGlvbiBkKCl7aWYoIWYpe3ZhciB0PWMocCk7Zj0hMDtmb3IodmFyIGU9cy5sZW5ndGg7ZTspe2Zvcih1PXMscz1bXTsrK2w8ZTspdSYmdVtsXS5ydW4oKTtsPS0xLGU9cy5sZW5ndGh9dT1udWxsLGY9ITEsZnVuY3Rpb24odCl7aWYobj09PWNsZWFyVGltZW91dClyZXR1cm4gY2xlYXJUaW1lb3V0KHQpO2lmKChuPT09YXx8IW4pJiZjbGVhclRpbWVvdXQpcmV0dXJuIG49Y2xlYXJUaW1lb3V0LGNsZWFyVGltZW91dCh0KTt0cnl7bih0KX1jYXRjaChlKXt0cnl7cmV0dXJuIG4uY2FsbChudWxsLHQpfWNhdGNoKGUpe3JldHVybiBuLmNhbGwodGhpcyx0KX19fSh0KX19ZnVuY3Rpb24gaCh0LGUpe3RoaXMuZnVuPXQsdGhpcy5hcnJheT1lfWZ1bmN0aW9uIHkoKXt9by5uZXh0VGljaz1mdW5jdGlvbih0KXt2YXIgZT1uZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aC0xKTtpZihhcmd1bWVudHMubGVuZ3RoPjEpZm9yKHZhciByPTE7cjxhcmd1bWVudHMubGVuZ3RoO3IrKyllW3ItMV09YXJndW1lbnRzW3JdO3MucHVzaChuZXcgaCh0LGUpKSwxIT09cy5sZW5ndGh8fGZ8fGMoZCl9LGgucHJvdG90eXBlLnJ1bj1mdW5jdGlvbigpe3RoaXMuZnVuLmFwcGx5KG51bGwsdGhpcy5hcnJheSl9LG8udGl0bGU9ImJyb3dzZXIiLG8uYnJvd3Nlcj0hMCxvLmVudj17fSxvLmFyZ3Y9W10sby52ZXJzaW9uPSIiLG8udmVyc2lvbnM9e30sby5vbj15LG8uYWRkTGlzdGVuZXI9eSxvLm9uY2U9eSxvLm9mZj15LG8ucmVtb3ZlTGlzdGVuZXI9eSxvLnJlbW92ZUFsbExpc3RlbmVycz15LG8uZW1pdD15LG8ucHJlcGVuZExpc3RlbmVyPXksby5wcmVwZW5kT25jZUxpc3RlbmVyPXksby5saXN0ZW5lcnM9ZnVuY3Rpb24odCl7cmV0dXJuW119LG8uYmluZGluZz1mdW5jdGlvbih0KXt0aHJvdyBuZXcgRXJyb3IoInByb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkIil9LG8uY3dkPWZ1bmN0aW9uKCl7cmV0dXJuIi8ifSxvLmNoZGlyPWZ1bmN0aW9uKHQpe3Rocm93IG5ldyBFcnJvcigicHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkIil9LG8udW1hc2s9ZnVuY3Rpb24oKXtyZXR1cm4gMH19LGZ1bmN0aW9uKHQsZSxyKXt2YXIgbixvO3ZvaWQgMD09PShvPSJmdW5jdGlvbiI9PXR5cGVvZihuPWZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIHQ9YXJndW1lbnRzLmxlbmd0aDtpZigwPT09dCl0aHJvdyBuZXcgRXJyb3IoInJlc29sdmVVcmwgcmVxdWlyZXMgYXQgbGVhc3Qgb25lIGFyZ3VtZW50OyBnb3Qgbm9uZS4iKTt2YXIgZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJiYXNlIik7aWYoZS5ocmVmPWFyZ3VtZW50c1swXSwxPT09dClyZXR1cm4gZS5ocmVmO3ZhciByPWRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJoZWFkIilbMF07ci5pbnNlcnRCZWZvcmUoZSxyLmZpcnN0Q2hpbGQpO2Zvcih2YXIgbixvPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKSxpPTE7aTx0O2krKylvLmhyZWY9YXJndW1lbnRzW2ldLG49by5ocmVmLGUuaHJlZj1uO3JldHVybiByLnJlbW92ZUNoaWxkKGUpLG59fSk/bi5jYWxsKGUscixlLHQpOm4pfHwodC5leHBvcnRzPW8pfSxmdW5jdGlvbih0LGUpe3ZhciByPXRoaXMsbj0hMTtlLmxvZ2dpbmc9bixlLnNldExvZ2dpbmc9ZnVuY3Rpb24odCl7bj10fSxlLmxvZz1mdW5jdGlvbigpe2Zvcih2YXIgdD1hcmd1bWVudHMubGVuZ3RoLGU9bmV3IEFycmF5KHQpLG89MDtvPHQ7bysrKWVbb109YXJndW1lbnRzW29dO3JldHVybiBuP2NvbnNvbGUubG9nLmFwcGx5KHIsZSk6bnVsbH19LGZ1bmN0aW9uKHQsZSl7dC5leHBvcnRzPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIiIuY29uY2F0KHQsIi0iKS5jb25jYXQoZSwiLSIpLmNvbmNhdChNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDE2KS5zbGljZSgzLDgpKX19LGZ1bmN0aW9uKHQsZSxyKXtyKDUpO3ZhciBuPXIoMiksbz1uLmxvZ2dpbmcsaT1uLnNldExvZ2dpbmcsYT1yKDYpO3QuZXhwb3J0cz17bG9nZ2luZzpvLHNldExvZ2dpbmc6aSxjcmVhdGVXb3JrZXI6YX19LGZ1bmN0aW9uKHQsZSxyKXt2YXIgbj1mdW5jdGlvbih0KXsidXNlIHN0cmljdCI7dmFyIGU9T2JqZWN0LnByb3RvdHlwZSxyPWUuaGFzT3duUHJvcGVydHksbj0iZnVuY3Rpb24iPT10eXBlb2YgU3ltYm9sP1N5bWJvbDp7fSxvPW4uaXRlcmF0b3J8fCJAQGl0ZXJhdG9yIixpPW4uYXN5bmNJdGVyYXRvcnx8IkBAYXN5bmNJdGVyYXRvciIsYT1uLnRvU3RyaW5nVGFnfHwiQEB0b1N0cmluZ1RhZyI7ZnVuY3Rpb24gYyh0LGUscixuKXt2YXIgbz1lJiZlLnByb3RvdHlwZSBpbnN0YW5jZW9mIGY/ZTpmLGk9T2JqZWN0LmNyZWF0ZShvLnByb3RvdHlwZSksYT1uZXcgaihufHxbXSk7cmV0dXJuIGkuX2ludm9rZT1mdW5jdGlvbih0LGUscil7dmFyIG49InN1c3BlbmRlZFN0YXJ0IjtyZXR1cm4gZnVuY3Rpb24obyxpKXtpZigiZXhlY3V0aW5nIj09PW4pdGhyb3cgbmV3IEVycm9yKCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBydW5uaW5nIik7aWYoImNvbXBsZXRlZCI9PT1uKXtpZigidGhyb3ciPT09byl0aHJvdyBpO3JldHVybiBrKCl9Zm9yKHIubWV0aG9kPW8sci5hcmc9aTs7KXt2YXIgYT1yLmRlbGVnYXRlO2lmKGEpe3ZhciBjPWIoYSxyKTtpZihjKXtpZihjPT09cyljb250aW51ZTtyZXR1cm4gY319aWYoIm5leHQiPT09ci5tZXRob2Qpci5zZW50PXIuX3NlbnQ9ci5hcmc7ZWxzZSBpZigidGhyb3ciPT09ci5tZXRob2Qpe2lmKCJzdXNwZW5kZWRTdGFydCI9PT1uKXRocm93IG49ImNvbXBsZXRlZCIsci5hcmc7ci5kaXNwYXRjaEV4Y2VwdGlvbihyLmFyZyl9ZWxzZSJyZXR1cm4iPT09ci5tZXRob2QmJnIuYWJydXB0KCJyZXR1cm4iLHIuYXJnKTtuPSJleGVjdXRpbmciO3ZhciBmPXUodCxlLHIpO2lmKCJub3JtYWwiPT09Zi50eXBlKXtpZihuPXIuZG9uZT8iY29tcGxldGVkIjoic3VzcGVuZGVkWWllbGQiLGYuYXJnPT09cyljb250aW51ZTtyZXR1cm57dmFsdWU6Zi5hcmcsZG9uZTpyLmRvbmV9fSJ0aHJvdyI9PT1mLnR5cGUmJihuPSJjb21wbGV0ZWQiLHIubWV0aG9kPSJ0aHJvdyIsci5hcmc9Zi5hcmcpfX19KHQscixhKSxpfWZ1bmN0aW9uIHUodCxlLHIpe3RyeXtyZXR1cm57dHlwZToibm9ybWFsIixhcmc6dC5jYWxsKGUscil9fWNhdGNoKHQpe3JldHVybnt0eXBlOiJ0aHJvdyIsYXJnOnR9fX10LndyYXA9Yzt2YXIgcz17fTtmdW5jdGlvbiBmKCl7fWZ1bmN0aW9uIGwoKXt9ZnVuY3Rpb24gcCgpe312YXIgZD17fTtkW29dPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXN9O3ZhciBoPU9iamVjdC5nZXRQcm90b3R5cGVPZix5PWgmJmgoaChPKFtdKSkpO3kmJnkhPT1lJiZyLmNhbGwoeSxvKSYmKGQ9eSk7dmFyIGc9cC5wcm90b3R5cGU9Zi5wcm90b3R5cGU9T2JqZWN0LmNyZWF0ZShkKTtmdW5jdGlvbiB2KHQpe1sibmV4dCIsInRocm93IiwicmV0dXJuIl0uZm9yRWFjaCgoZnVuY3Rpb24oZSl7dFtlXT1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5faW52b2tlKGUsdCl9fSkpfWZ1bmN0aW9uIG0odCl7dmFyIGU7dGhpcy5faW52b2tlPWZ1bmN0aW9uKG4sbyl7ZnVuY3Rpb24gaSgpe3JldHVybiBuZXcgUHJvbWlzZSgoZnVuY3Rpb24oZSxpKXshZnVuY3Rpb24gZShuLG8saSxhKXt2YXIgYz11KHRbbl0sdCxvKTtpZigidGhyb3ciIT09Yy50eXBlKXt2YXIgcz1jLmFyZyxmPXMudmFsdWU7cmV0dXJuIGYmJiJvYmplY3QiPT10eXBlb2YgZiYmci5jYWxsKGYsIl9fYXdhaXQiKT9Qcm9taXNlLnJlc29sdmUoZi5fX2F3YWl0KS50aGVuKChmdW5jdGlvbih0KXtlKCJuZXh0Iix0LGksYSl9KSwoZnVuY3Rpb24odCl7ZSgidGhyb3ciLHQsaSxhKX0pKTpQcm9taXNlLnJlc29sdmUoZikudGhlbigoZnVuY3Rpb24odCl7cy52YWx1ZT10LGkocyl9KSwoZnVuY3Rpb24odCl7cmV0dXJuIGUoInRocm93Iix0LGksYSl9KSl9YShjLmFyZyl9KG4sbyxlLGkpfSkpfXJldHVybiBlPWU/ZS50aGVuKGksaSk6aSgpfX1mdW5jdGlvbiBiKHQsZSl7dmFyIHI9dC5pdGVyYXRvcltlLm1ldGhvZF07aWYodm9pZCAwPT09cil7aWYoZS5kZWxlZ2F0ZT1udWxsLCJ0aHJvdyI9PT1lLm1ldGhvZCl7aWYodC5pdGVyYXRvci5yZXR1cm4mJihlLm1ldGhvZD0icmV0dXJuIixlLmFyZz12b2lkIDAsYih0LGUpLCJ0aHJvdyI9PT1lLm1ldGhvZCkpcmV0dXJuIHM7ZS5tZXRob2Q9InRocm93IixlLmFyZz1uZXcgVHlwZUVycm9yKCJUaGUgaXRlcmF0b3IgZG9lcyBub3QgcHJvdmlkZSBhICd0aHJvdycgbWV0aG9kIil9cmV0dXJuIHN9dmFyIG49dShyLHQuaXRlcmF0b3IsZS5hcmcpO2lmKCJ0aHJvdyI9PT1uLnR5cGUpcmV0dXJuIGUubWV0aG9kPSJ0aHJvdyIsZS5hcmc9bi5hcmcsZS5kZWxlZ2F0ZT1udWxsLHM7dmFyIG89bi5hcmc7cmV0dXJuIG8/by5kb25lPyhlW3QucmVzdWx0TmFtZV09by52YWx1ZSxlLm5leHQ9dC5uZXh0TG9jLCJyZXR1cm4iIT09ZS5tZXRob2QmJihlLm1ldGhvZD0ibmV4dCIsZS5hcmc9dm9pZCAwKSxlLmRlbGVnYXRlPW51bGwscyk6bzooZS5tZXRob2Q9InRocm93IixlLmFyZz1uZXcgVHlwZUVycm9yKCJpdGVyYXRvciByZXN1bHQgaXMgbm90IGFuIG9iamVjdCIpLGUuZGVsZWdhdGU9bnVsbCxzKX1mdW5jdGlvbiB3KHQpe3ZhciBlPXt0cnlMb2M6dFswXX07MSBpbiB0JiYoZS5jYXRjaExvYz10WzFdKSwyIGluIHQmJihlLmZpbmFsbHlMb2M9dFsyXSxlLmFmdGVyTG9jPXRbM10pLHRoaXMudHJ5RW50cmllcy5wdXNoKGUpfWZ1bmN0aW9uIHgodCl7dmFyIGU9dC5jb21wbGV0aW9ufHx7fTtlLnR5cGU9Im5vcm1hbCIsZGVsZXRlIGUuYXJnLHQuY29tcGxldGlvbj1lfWZ1bmN0aW9uIGoodCl7dGhpcy50cnlFbnRyaWVzPVt7dHJ5TG9jOiJyb290In1dLHQuZm9yRWFjaCh3LHRoaXMpLHRoaXMucmVzZXQoITApfWZ1bmN0aW9uIE8odCl7aWYodCl7dmFyIGU9dFtvXTtpZihlKXJldHVybiBlLmNhbGwodCk7aWYoImZ1bmN0aW9uIj09dHlwZW9mIHQubmV4dClyZXR1cm4gdDtpZighaXNOYU4odC5sZW5ndGgpKXt2YXIgbj0tMSxpPWZ1bmN0aW9uIGUoKXtmb3IoOysrbjx0Lmxlbmd0aDspaWYoci5jYWxsKHQsbikpcmV0dXJuIGUudmFsdWU9dFtuXSxlLmRvbmU9ITEsZTtyZXR1cm4gZS52YWx1ZT12b2lkIDAsZS5kb25lPSEwLGV9O3JldHVybiBpLm5leHQ9aX19cmV0dXJue25leHQ6a319ZnVuY3Rpb24gaygpe3JldHVybnt2YWx1ZTp2b2lkIDAsZG9uZTohMH19cmV0dXJuIGwucHJvdG90eXBlPWcuY29uc3RydWN0b3I9cCxwLmNvbnN0cnVjdG9yPWwscFthXT1sLmRpc3BsYXlOYW1lPSJHZW5lcmF0b3JGdW5jdGlvbiIsdC5pc0dlbmVyYXRvckZ1bmN0aW9uPWZ1bmN0aW9uKHQpe3ZhciBlPSJmdW5jdGlvbiI9PXR5cGVvZiB0JiZ0LmNvbnN0cnVjdG9yO3JldHVybiEhZSYmKGU9PT1sfHwiR2VuZXJhdG9yRnVuY3Rpb24iPT09KGUuZGlzcGxheU5hbWV8fGUubmFtZSkpfSx0Lm1hcms9ZnVuY3Rpb24odCl7cmV0dXJuIE9iamVjdC5zZXRQcm90b3R5cGVPZj9PYmplY3Quc2V0UHJvdG90eXBlT2YodCxwKToodC5fX3Byb3RvX189cCxhIGluIHR8fCh0W2FdPSJHZW5lcmF0b3JGdW5jdGlvbiIpKSx0LnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKGcpLHR9LHQuYXdyYXA9ZnVuY3Rpb24odCl7cmV0dXJue19fYXdhaXQ6dH19LHYobS5wcm90b3R5cGUpLG0ucHJvdG90eXBlW2ldPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXN9LHQuQXN5bmNJdGVyYXRvcj1tLHQuYXN5bmM9ZnVuY3Rpb24oZSxyLG4sbyl7dmFyIGk9bmV3IG0oYyhlLHIsbixvKSk7cmV0dXJuIHQuaXNHZW5lcmF0b3JGdW5jdGlvbihyKT9pOmkubmV4dCgpLnRoZW4oKGZ1bmN0aW9uKHQpe3JldHVybiB0LmRvbmU/dC52YWx1ZTppLm5leHQoKX0pKX0sdihnKSxnW2FdPSJHZW5lcmF0b3IiLGdbb109ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc30sZy50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiJbb2JqZWN0IEdlbmVyYXRvcl0ifSx0LmtleXM9ZnVuY3Rpb24odCl7dmFyIGU9W107Zm9yKHZhciByIGluIHQpZS5wdXNoKHIpO3JldHVybiBlLnJldmVyc2UoKSxmdW5jdGlvbiByKCl7Zm9yKDtlLmxlbmd0aDspe3ZhciBuPWUucG9wKCk7aWYobiBpbiB0KXJldHVybiByLnZhbHVlPW4sci5kb25lPSExLHJ9cmV0dXJuIHIuZG9uZT0hMCxyfX0sdC52YWx1ZXM9TyxqLnByb3RvdHlwZT17Y29uc3RydWN0b3I6aixyZXNldDpmdW5jdGlvbih0KXtpZih0aGlzLnByZXY9MCx0aGlzLm5leHQ9MCx0aGlzLnNlbnQ9dGhpcy5fc2VudD12b2lkIDAsdGhpcy5kb25lPSExLHRoaXMuZGVsZWdhdGU9bnVsbCx0aGlzLm1ldGhvZD0ibmV4dCIsdGhpcy5hcmc9dm9pZCAwLHRoaXMudHJ5RW50cmllcy5mb3JFYWNoKHgpLCF0KWZvcih2YXIgZSBpbiB0aGlzKSJ0Ij09PWUuY2hhckF0KDApJiZyLmNhbGwodGhpcyxlKSYmIWlzTmFOKCtlLnNsaWNlKDEpKSYmKHRoaXNbZV09dm9pZCAwKX0sc3RvcDpmdW5jdGlvbigpe3RoaXMuZG9uZT0hMDt2YXIgdD10aGlzLnRyeUVudHJpZXNbMF0uY29tcGxldGlvbjtpZigidGhyb3ciPT09dC50eXBlKXRocm93IHQuYXJnO3JldHVybiB0aGlzLnJ2YWx9LGRpc3BhdGNoRXhjZXB0aW9uOmZ1bmN0aW9uKHQpe2lmKHRoaXMuZG9uZSl0aHJvdyB0O3ZhciBlPXRoaXM7ZnVuY3Rpb24gbihyLG4pe3JldHVybiBhLnR5cGU9InRocm93IixhLmFyZz10LGUubmV4dD1yLG4mJihlLm1ldGhvZD0ibmV4dCIsZS5hcmc9dm9pZCAwKSwhIW59Zm9yKHZhciBvPXRoaXMudHJ5RW50cmllcy5sZW5ndGgtMTtvPj0wOy0tbyl7dmFyIGk9dGhpcy50cnlFbnRyaWVzW29dLGE9aS5jb21wbGV0aW9uO2lmKCJyb290Ij09PWkudHJ5TG9jKXJldHVybiBuKCJlbmQiKTtpZihpLnRyeUxvYzw9dGhpcy5wcmV2KXt2YXIgYz1yLmNhbGwoaSwiY2F0Y2hMb2MiKSx1PXIuY2FsbChpLCJmaW5hbGx5TG9jIik7aWYoYyYmdSl7aWYodGhpcy5wcmV2PGkuY2F0Y2hMb2MpcmV0dXJuIG4oaS5jYXRjaExvYywhMCk7aWYodGhpcy5wcmV2PGkuZmluYWxseUxvYylyZXR1cm4gbihpLmZpbmFsbHlMb2MpfWVsc2UgaWYoYyl7aWYodGhpcy5wcmV2PGkuY2F0Y2hMb2MpcmV0dXJuIG4oaS5jYXRjaExvYywhMCl9ZWxzZXtpZighdSl0aHJvdyBuZXcgRXJyb3IoInRyeSBzdGF0ZW1lbnQgd2l0aG91dCBjYXRjaCBvciBmaW5hbGx5Iik7aWYodGhpcy5wcmV2PGkuZmluYWxseUxvYylyZXR1cm4gbihpLmZpbmFsbHlMb2MpfX19fSxhYnJ1cHQ6ZnVuY3Rpb24odCxlKXtmb3IodmFyIG49dGhpcy50cnlFbnRyaWVzLmxlbmd0aC0xO24+PTA7LS1uKXt2YXIgbz10aGlzLnRyeUVudHJpZXNbbl07aWYoby50cnlMb2M8PXRoaXMucHJldiYmci5jYWxsKG8sImZpbmFsbHlMb2MiKSYmdGhpcy5wcmV2PG8uZmluYWxseUxvYyl7dmFyIGk9bzticmVha319aSYmKCJicmVhayI9PT10fHwiY29udGludWUiPT09dCkmJmkudHJ5TG9jPD1lJiZlPD1pLmZpbmFsbHlMb2MmJihpPW51bGwpO3ZhciBhPWk/aS5jb21wbGV0aW9uOnt9O3JldHVybiBhLnR5cGU9dCxhLmFyZz1lLGk/KHRoaXMubWV0aG9kPSJuZXh0Iix0aGlzLm5leHQ9aS5maW5hbGx5TG9jLHMpOnRoaXMuY29tcGxldGUoYSl9LGNvbXBsZXRlOmZ1bmN0aW9uKHQsZSl7aWYoInRocm93Ij09PXQudHlwZSl0aHJvdyB0LmFyZztyZXR1cm4iYnJlYWsiPT09dC50eXBlfHwiY29udGludWUiPT09dC50eXBlP3RoaXMubmV4dD10LmFyZzoicmV0dXJuIj09PXQudHlwZT8odGhpcy5ydmFsPXRoaXMuYXJnPXQuYXJnLHRoaXMubWV0aG9kPSJyZXR1cm4iLHRoaXMubmV4dD0iZW5kIik6Im5vcm1hbCI9PT10LnR5cGUmJmUmJih0aGlzLm5leHQ9ZSksc30sZmluaXNoOmZ1bmN0aW9uKHQpe2Zvcih2YXIgZT10aGlzLnRyeUVudHJpZXMubGVuZ3RoLTE7ZT49MDstLWUpe3ZhciByPXRoaXMudHJ5RW50cmllc1tlXTtpZihyLmZpbmFsbHlMb2M9PT10KXJldHVybiB0aGlzLmNvbXBsZXRlKHIuY29tcGxldGlvbixyLmFmdGVyTG9jKSx4KHIpLHN9fSxjYXRjaDpmdW5jdGlvbih0KXtmb3IodmFyIGU9dGhpcy50cnlFbnRyaWVzLmxlbmd0aC0xO2U+PTA7LS1lKXt2YXIgcj10aGlzLnRyeUVudHJpZXNbZV07aWYoci50cnlMb2M9PT10KXt2YXIgbj1yLmNvbXBsZXRpb247aWYoInRocm93Ij09PW4udHlwZSl7dmFyIG89bi5hcmc7eChyKX1yZXR1cm4gb319dGhyb3cgbmV3IEVycm9yKCJpbGxlZ2FsIGNhdGNoIGF0dGVtcHQiKX0sZGVsZWdhdGVZaWVsZDpmdW5jdGlvbih0LGUscil7cmV0dXJuIHRoaXMuZGVsZWdhdGU9e2l0ZXJhdG9yOk8odCkscmVzdWx0TmFtZTplLG5leHRMb2M6cn0sIm5leHQiPT09dGhpcy5tZXRob2QmJih0aGlzLmFyZz12b2lkIDApLHN9fSx0fSh0LmV4cG9ydHMpO3RyeXtyZWdlbmVyYXRvclJ1bnRpbWU9bn1jYXRjaCh0KXtGdW5jdGlvbigiciIsInJlZ2VuZXJhdG9yUnVudGltZSA9IHIiKShuKX19LGZ1bmN0aW9uKHQsZSxyKXtmdW5jdGlvbiBuKHQsZSxyLG4sbyxpLGEpe3RyeXt2YXIgYz10W2ldKGEpLHU9Yy52YWx1ZX1jYXRjaCh0KXtyZXR1cm4gdm9pZCByKHQpfWMuZG9uZT9lKHUpOlByb21pc2UucmVzb2x2ZSh1KS50aGVuKG4sbyl9ZnVuY3Rpb24gbyh0KXtyZXR1cm4gZnVuY3Rpb24oKXt2YXIgZT10aGlzLHI9YXJndW1lbnRzO3JldHVybiBuZXcgUHJvbWlzZSgoZnVuY3Rpb24obyxpKXt2YXIgYT10LmFwcGx5KGUscik7ZnVuY3Rpb24gYyh0KXtuKGEsbyxpLGMsdSwibmV4dCIsdCl9ZnVuY3Rpb24gdSh0KXtuKGEsbyxpLGMsdSwidGhyb3ciLHQpfWModm9pZCAwKX0pKX19ZnVuY3Rpb24gaSh0LGUpe3ZhciByPU9iamVjdC5rZXlzKHQpO2lmKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpe3ZhciBuPU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModCk7ZSYmKG49bi5maWx0ZXIoKGZ1bmN0aW9uKGUpe3JldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHQsZSkuZW51bWVyYWJsZX0pKSksci5wdXNoLmFwcGx5KHIsbil9cmV0dXJuIHJ9ZnVuY3Rpb24gYSh0KXtmb3IodmFyIGU9MTtlPGFyZ3VtZW50cy5sZW5ndGg7ZSsrKXt2YXIgcj1udWxsIT1hcmd1bWVudHNbZV0/YXJndW1lbnRzW2VdOnt9O2UlMj9pKHIsITApLmZvckVhY2goKGZ1bmN0aW9uKGUpe2ModCxlLHJbZV0pfSkpOk9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzP09iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHQsT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMocikpOmkocikuZm9yRWFjaCgoZnVuY3Rpb24oZSl7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsZSxPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHIsZSkpfSkpfXJldHVybiB0fWZ1bmN0aW9uIGModCxlLHIpe3JldHVybiBlIGluIHQ/T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsZSx7dmFsdWU6cixlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMH0pOnRbZV09cix0fWZ1bmN0aW9uIHUodCxlKXtpZihudWxsPT10KXJldHVybnt9O3ZhciByLG4sbz1mdW5jdGlvbih0LGUpe2lmKG51bGw9PXQpcmV0dXJue307dmFyIHIsbixvPXt9LGk9T2JqZWN0LmtleXModCk7Zm9yKG49MDtuPGkubGVuZ3RoO24rKylyPWlbbl0sZS5pbmRleE9mKHIpPj0wfHwob1tyXT10W3JdKTtyZXR1cm4gb30odCxlKTtpZihPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKXt2YXIgaT1PYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHQpO2ZvcihuPTA7bjxpLmxlbmd0aDtuKyspcj1pW25dLGUuaW5kZXhPZihyKT49MHx8T2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHQscikmJihvW3JdPXRbcl0pfXJldHVybiBvfXZhciBzPXIoNyksZj1yKDIpLmxvZyxsPXIoMykscD1yKDgpLGQ9cig5KSxoPXIoMTIpLHk9cigxMyksZz15LmRlZmF1bHRPcHRpb25zLHY9eS5zcGF3bldvcmtlcixtPXkub25NZXNzYWdlLGI9eS5mZXRjaEZpbGUsdz0wO3QuZXhwb3J0cz1mdW5jdGlvbigpe3ZhciB0PWFyZ3VtZW50cy5sZW5ndGg+MCYmdm9pZCAwIT09YXJndW1lbnRzWzBdP2FyZ3VtZW50c1swXTp7fSxlPWwoIldvcmtlciIsdykscj1kKGEoe30sZyx7fSx0KSksbj1yLmxvZ2dlcixpPXIucHJvZ3Jlc3MsYz11KHIsWyJsb2dnZXIiLCJwcm9ncmVzcyJdKSx5PXt9LHg9e30saj12KGMpO3crPTE7dmFyIE89ZnVuY3Rpb24odCxlKXt5W3RdPWV9LGs9ZnVuY3Rpb24odCxlKXt4W3RdPWV9LFA9ZnVuY3Rpb24odCl7dmFyIHI9dC5pZCxuPXQuYWN0aW9uLG89dC5wYXlsb2FkO3JldHVybiBuZXcgUHJvbWlzZSgoZnVuY3Rpb24odCxpKXt2YXIgYT17d29ya2VySWQ6ZSxqb2JJZDpyLGFjdGlvbjpuLHBheWxvYWQ6b307ZigiWyIuY29uY2F0KGUsIl06IFN0YXJ0ICIpLmNvbmNhdChyLCIsIGFjdGlvbj0iKS5jb25jYXQobikpLE8obix0KSxrKG4saSksai5wb3N0TWVzc2FnZShhLGgoYSkpfSkpfSxFPWZ1bmN0aW9uKHQpe3JldHVybiBQKHMoe2lkOnQsYWN0aW9uOiJsb2FkIixwYXlsb2FkOntvcHRpb25zOmN9fSkpfSxMPWZ1bmN0aW9uKCl7dmFyIHQ9byhyZWdlbmVyYXRvclJ1bnRpbWUubWFyaygoZnVuY3Rpb24gdChlLHIsbil7cmV0dXJuIHJlZ2VuZXJhdG9yUnVudGltZS53cmFwKChmdW5jdGlvbih0KXtmb3IoOzspc3dpdGNoKHQucHJldj10Lm5leHQpe2Nhc2UgMDpyZXR1cm4gdC50MD1QLHQudDE9cyx0LnQyPW4sdC50Mz1lLHQubmV4dD02LGIocik7Y2FzZSA2OnJldHVybiB0LnQ0PXQuc2VudCx0LnQ1PVt0LnQzLHQudDRdLHQudDY9e21ldGhvZDoid3JpdGVGaWxlIixhcmdzOnQudDV9LHQudDc9e2lkOnQudDIsYWN0aW9uOiJGUyIscGF5bG9hZDp0LnQ2fSx0LnQ4PSgwLHQudDEpKHQudDcpLHQuYWJydXB0KCJyZXR1cm4iLCgwLHQudDApKHQudDgpKTtjYXNlIDEyOmNhc2UiZW5kIjpyZXR1cm4gdC5zdG9wKCl9fSksdCl9KSkpO3JldHVybiBmdW5jdGlvbihlLHIsbil7cmV0dXJuIHQuYXBwbHkodGhpcyxhcmd1bWVudHMpfX0oKSxTPWZ1bmN0aW9uKHQsZSxyKXtyZXR1cm4gUChzKHtpZDpyLGFjdGlvbjoiRlMiLHBheWxvYWQ6e21ldGhvZDoid3JpdGVGaWxlIixhcmdzOlt0LGVdfX0pKX0sRj1mdW5jdGlvbih0LGUpe3JldHVybiBQKHMoe2lkOmUsYWN0aW9uOiJGUyIscGF5bG9hZDp7bWV0aG9kOiJyZWFkRmlsZSIsYXJnczpbdF19fSkpfSxUPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIFAocyh7aWQ6ZSxhY3Rpb246IkZTIixwYXlsb2FkOnttZXRob2Q6InVubGluayIsYXJnczpbdF19fSkpfSxfPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIFAocyh7aWQ6ZSxhY3Rpb246InJ1biIscGF5bG9hZDp7YXJnczp0fX0pKX0sQT1mdW5jdGlvbih0LGUpe3JldHVybiBQKHMoe2lkOmUsYWN0aW9uOiJGUyIscGF5bG9hZDp7bWV0aG9kOiJyZWFkZGlyIixhcmdzOlt0XX19KSl9LFI9ZnVuY3Rpb24odCxlKXt2YXIgcj1hcmd1bWVudHMubGVuZ3RoPjImJnZvaWQgMCE9PWFyZ3VtZW50c1syXT9hcmd1bWVudHNbMl06IiIsbj1hcmd1bWVudHMubGVuZ3RoPjM/YXJndW1lbnRzWzNdOnZvaWQgMDtyZXR1cm4gXygiLWkgIi5jb25jYXQodCwiICIpLmNvbmNhdChyLCIgIikuY29uY2F0KGUpLG4pfSxEPWZ1bmN0aW9uKHQsZSxyLG4pe3ZhciBvPWFyZ3VtZW50cy5sZW5ndGg+NCYmdm9pZCAwIT09YXJndW1lbnRzWzRdP2FyZ3VtZW50c1s0XToiIixpPWFyZ3VtZW50cy5sZW5ndGg+NT9hcmd1bWVudHNbNV06dm9pZCAwO3JldHVybiBfKCItaSAiLmNvbmNhdCh0LCIgLXNzICIpLmNvbmNhdChyLCIgLXRvICIpLmNvbmNhdChuLCIgIikuY29uY2F0KG8sIiAiKS5jb25jYXQoZSksaSl9LEk9ZnVuY3Rpb24oKXt2YXIgdD1vKHJlZ2VuZXJhdG9yUnVudGltZS5tYXJrKChmdW5jdGlvbiB0KGUscil7dmFyIG4sbyxpLGE9YXJndW1lbnRzO3JldHVybiByZWdlbmVyYXRvclJ1bnRpbWUud3JhcCgoZnVuY3Rpb24odCl7Zm9yKDs7KXN3aXRjaCh0LnByZXY9dC5uZXh0KXtjYXNlIDA6cmV0dXJuIG49YS5sZW5ndGg+MiYmdm9pZCAwIT09YVsyXT9hWzJdOiIiLG89YS5sZW5ndGg+Mz9hWzNdOnZvaWQgMCxpPWUucmVkdWNlKChmdW5jdGlvbih0LGUpe3JldHVybiIiLmNvbmNhdCh0LCJcbmZpbGUgIikuY29uY2F0KGUpfSksIiIpLHQubmV4dD01LFMoImNvbmNhdF9saXN0LnR4dCIsaSk7Y2FzZSA1OnJldHVybiB0LmFicnVwdCgicmV0dXJuIixfKCItZiBjb25jYXQgLXNhZmUgMCAtaSBjb25jYXRfbGlzdC50eHQgIi5jb25jYXQobiwiICIpLmNvbmNhdChyKSxvKSk7Y2FzZSA2OmNhc2UiZW5kIjpyZXR1cm4gdC5zdG9wKCl9fSksdCl9KSkpO3JldHVybiBmdW5jdGlvbihlLHIpe3JldHVybiB0LmFwcGx5KHRoaXMsYXJndW1lbnRzKX19KCksVz1mdW5jdGlvbigpe3ZhciB0PW8ocmVnZW5lcmF0b3JSdW50aW1lLm1hcmsoKGZ1bmN0aW9uIHQoZSl7cmV0dXJuIHJlZ2VuZXJhdG9yUnVudGltZS53cmFwKChmdW5jdGlvbih0KXtmb3IoOzspc3dpdGNoKHQucHJldj10Lm5leHQpe2Nhc2UgMDppZihudWxsPT09ail7dC5uZXh0PTU7YnJlYWt9cmV0dXJuIHQubmV4dD0zLFAocyh7aWQ6ZSxhY3Rpb246InRlcm1pbmF0ZSJ9KSk7Y2FzZSAzOmoudGVybWluYXRlKCksaj1udWxsO2Nhc2UgNTpyZXR1cm4gdC5hYnJ1cHQoInJldHVybiIsUHJvbWlzZS5yZXNvbHZlKCkpO2Nhc2UgNjpjYXNlImVuZCI6cmV0dXJuIHQuc3RvcCgpfX0pLHQpfSkpKTtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIHQuYXBwbHkodGhpcyxhcmd1bWVudHMpfX0oKTtyZXR1cm4gbShqLChmdW5jdGlvbih0KXt2YXIgZT10LndvcmtlcklkLHI9dC5qb2JJZCxvPXQuYWN0aW9uLGE9dC5zdGF0dXMsYz10LnBheWxvYWQ7aWYoInJlc29sdmUiPT09YSl7dmFyIHU9Yy5tZXNzYWdlLHM9Yy5kYXRhO2YoIlsiLmNvbmNhdChlLCJdOiBDb21wbGV0ZSAiKS5jb25jYXQocikpLHlbb10oe3dvcmtlcklkOmUsam9iSWQ6cixtZXNzYWdlOnUsZGF0YTpzfSl9ZWxzZXtpZigicmVqZWN0Ij09PWEpdGhyb3cgeFtvXShjKSxFcnJvcihjKTsicHJvZ3Jlc3MiPT09YSYmKHAoYyxpKSxuKGMpKX19KSkse2lkOmUsd29ya2VyOmosc2V0UmVzb2x2ZTpPLHNldFJlamVjdDprLGxvYWQ6RSx3cml0ZTpMLHdyaXRlVGV4dDpTLHJlYWQ6RixyZW1vdmU6VCxsczpBLHJ1bjpfLHRyYW5zY29kZTpSLHRyaW06RCxjb25jYXREZW11eGVyOkksdGVybWluYXRlOld9fX0sZnVuY3Rpb24odCxlLHIpe3ZhciBuPXIoMyksbz0wO3QuZXhwb3J0cz1mdW5jdGlvbih0KXt2YXIgZT10LmlkLHI9dC5hY3Rpb24saT10LnBheWxvYWQsYT12b2lkIDA9PT1pP3t9OmksYz1lO3JldHVybiB2b2lkIDA9PT1jJiYoYz1uKCJKb2IiLG8pLG8rPTEpLHtpZDpjLGFjdGlvbjpyLHBheWxvYWQ6YX19fSxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIHIodCxlKXtyZXR1cm4gZnVuY3Rpb24odCl7aWYoQXJyYXkuaXNBcnJheSh0KSlyZXR1cm4gdH0odCl8fGZ1bmN0aW9uKHQsZSl7aWYoIShTeW1ib2wuaXRlcmF0b3IgaW4gT2JqZWN0KHQpfHwiW29iamVjdCBBcmd1bWVudHNdIj09PU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KSkpcmV0dXJuO3ZhciByPVtdLG49ITAsbz0hMSxpPXZvaWQgMDt0cnl7Zm9yKHZhciBhLGM9dFtTeW1ib2wuaXRlcmF0b3JdKCk7IShuPShhPWMubmV4dCgpKS5kb25lKSYmKHIucHVzaChhLnZhbHVlKSwhZXx8ci5sZW5ndGghPT1lKTtuPSEwKTt9Y2F0Y2godCl7bz0hMCxpPXR9ZmluYWxseXt0cnl7bnx8bnVsbD09Yy5yZXR1cm58fGMucmV0dXJuKCl9ZmluYWxseXtpZihvKXRocm93IGl9fXJldHVybiByfSh0LGUpfHxmdW5jdGlvbigpe3Rocm93IG5ldyBUeXBlRXJyb3IoIkludmFsaWQgYXR0ZW1wdCB0byBkZXN0cnVjdHVyZSBub24taXRlcmFibGUgaW5zdGFuY2UiKX0oKX12YXIgbj0wLG89ZnVuY3Rpb24odCl7dmFyIGU9cih0LnNwbGl0KCI6IiksMyksbj1lWzBdLG89ZVsxXSxpPWVbMl07cmV0dXJuIDYwKnBhcnNlRmxvYXQobikqNjArNjAqcGFyc2VGbG9hdChvKStwYXJzZUZsb2F0KGkpfTt0LmV4cG9ydHM9ZnVuY3Rpb24odCxlKXt2YXIgcj10Lm1lc3NhZ2U7aWYoInN0cmluZyI9PXR5cGVvZiByKWlmKHIuc3RhcnRzV2l0aCgiICBEdXJhdGlvbiIpKXt2YXIgaT1yLnNwbGl0KCIsICIpWzBdLnNwbGl0KCI6ICIpWzFdLGE9byhpKTsoMD09PW58fG4+YSkmJihuPWEpfWVsc2UgaWYoci5zdGFydHNXaXRoKCJmcmFtZSIpKXt2YXIgYz1yLnNwbGl0KCJ0aW1lPSIpWzFdLnNwbGl0KCIgIilbMF07ZSh7cmF0aW86byhjKS9ufSl9ZWxzZSByLnN0YXJ0c1dpdGgoInZpZGVvOiIpJiZlKHtyYXRpbzoxfSl9fSxmdW5jdGlvbih0LGUscil7ZnVuY3Rpb24gbih0LGUpe3ZhciByPU9iamVjdC5rZXlzKHQpO2lmKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpe3ZhciBuPU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModCk7ZSYmKG49bi5maWx0ZXIoKGZ1bmN0aW9uKGUpe3JldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHQsZSkuZW51bWVyYWJsZX0pKSksci5wdXNoLmFwcGx5KHIsbil9cmV0dXJuIHJ9ZnVuY3Rpb24gbyh0LGUscil7cmV0dXJuIGUgaW4gdD9PYmplY3QuZGVmaW5lUHJvcGVydHkodCxlLHt2YWx1ZTpyLGVudW1lcmFibGU6ITAsY29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwfSk6dFtlXT1yLHR9dmFyIGk9ImJyb3dzZXIiPT09cigxMCkoInR5cGUiKT9yKDEpOmZ1bmN0aW9uKHQpe3JldHVybiB0fTt0LmV4cG9ydHM9ZnVuY3Rpb24odCl7dmFyIGU9ZnVuY3Rpb24odCl7Zm9yKHZhciBlPTE7ZTxhcmd1bWVudHMubGVuZ3RoO2UrKyl7dmFyIHI9bnVsbCE9YXJndW1lbnRzW2VdP2FyZ3VtZW50c1tlXTp7fTtlJTI/bihyLCEwKS5mb3JFYWNoKChmdW5jdGlvbihlKXtvKHQsZSxyW2VdKX0pKTpPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycz9PYmplY3QuZGVmaW5lUHJvcGVydGllcyh0LE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKHIpKTpuKHIpLmZvckVhY2goKGZ1bmN0aW9uKGUpe09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LGUsT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihyLGUpKX0pKX1yZXR1cm4gdH0oe30sdCk7cmV0dXJuWyJjb3JlUGF0aCIsIndvcmtlclBhdGgiXS5mb3JFYWNoKChmdW5jdGlvbihyKXt2b2lkIDAhPT10W3JdJiYoZVtyXT1pKGVbcl0pKX0pKSxlfX0sZnVuY3Rpb24odCxlLHIpeyhmdW5jdGlvbihlKXtmdW5jdGlvbiBuKHQpe3JldHVybihuPSJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJiJzeW1ib2wiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJiJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJnQuY29uc3RydWN0b3I9PT1TeW1ib2wmJnQhPT1TeW1ib2wucHJvdG90eXBlPyJzeW1ib2wiOnR5cGVvZiB0fSkodCl9dmFyIG89cigxMSk7dC5leHBvcnRzPWZ1bmN0aW9uKHQpe3ZhciByPXt9O3JldHVybiBvKCk/ci50eXBlPSJlbGVjdHJvbiI6Im9iamVjdCI9PT0oInVuZGVmaW5lZCI9PXR5cGVvZiB3aW5kb3c/InVuZGVmaW5lZCI6bih3aW5kb3cpKT9yLnR5cGU9ImJyb3dzZXIiOiJmdW5jdGlvbiI9PXR5cGVvZiBpbXBvcnRTY3JpcHRzP3IudHlwZT0id2Vid29ya2VyIjoib2JqZWN0Ij09PSh2b2lkIDA9PT1lPyJ1bmRlZmluZWQiOm4oZSkpJiYoci50eXBlPSJub2RlIiksdm9pZCAwPT09dD9yOnJbdF19fSkuY2FsbCh0aGlzLHIoMCkpfSxmdW5jdGlvbih0LGUscil7KGZ1bmN0aW9uKGUpe3QuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybiJ1bmRlZmluZWQiIT10eXBlb2Ygd2luZG93JiYib2JqZWN0Ij09dHlwZW9mIHdpbmRvdy5wcm9jZXNzJiYicmVuZGVyZXIiPT09d2luZG93LnByb2Nlc3MudHlwZXx8KCEodm9pZCAwPT09ZXx8Im9iamVjdCIhPXR5cGVvZiBlLnZlcnNpb25zfHwhZS52ZXJzaW9ucy5lbGVjdHJvbil8fCJvYmplY3QiPT10eXBlb2YgbmF2aWdhdG9yJiYic3RyaW5nIj09dHlwZW9mIG5hdmlnYXRvci51c2VyQWdlbnQmJm5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiRWxlY3Ryb24iKT49MCl9fSkuY2FsbCh0aGlzLHIoMCkpfSxmdW5jdGlvbih0LGUpe3QuZXhwb3J0cz1mdW5jdGlvbih0KXt2YXIgZT1bXSxyPWZ1bmN0aW9uKHQpe3QgaW5zdGFuY2VvZiBVaW50OEFycmF5P2UucHVzaCh0LmJ1ZmZlcik6dCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyJiZlLnB1c2godCl9LG49dC5wYXlsb2FkLG89bi5hcmdzLGk9bi5kYXRhO3JldHVybiByKGkpLEFycmF5LmlzQXJyYXkobykmJm8uZm9yRWFjaCgoZnVuY3Rpb24odCl7cmV0dXJuIHIodCl9KSksZX19LGZ1bmN0aW9uKHQsZSxyKXt2YXIgbj1yKDE0KSxvPXIoMTcpLGk9cigxOCksYT1yKDE5KTt0LmV4cG9ydHM9e2RlZmF1bHRPcHRpb25zOm4sc3Bhd25Xb3JrZXI6byxvbk1lc3NhZ2U6aSxmZXRjaEZpbGU6YX19LGZ1bmN0aW9uKHQsZSxyKXsoZnVuY3Rpb24oZSl7ZnVuY3Rpb24gbih0LGUpe3ZhciByPU9iamVjdC5rZXlzKHQpO2lmKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpe3ZhciBuPU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModCk7ZSYmKG49bi5maWx0ZXIoKGZ1bmN0aW9uKGUpe3JldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHQsZSkuZW51bWVyYWJsZX0pKSksci5wdXNoLmFwcGx5KHIsbil9cmV0dXJuIHJ9ZnVuY3Rpb24gbyh0LGUscil7cmV0dXJuIGUgaW4gdD9PYmplY3QuZGVmaW5lUHJvcGVydHkodCxlLHt2YWx1ZTpyLGVudW1lcmFibGU6ITAsY29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwfSk6dFtlXT1yLHR9dmFyIGk9cigxKSxhPXIoMTUpLGM9YS52ZXJzaW9uLHU9YS5kZXBlbmRlbmNpZXMscz1yKDE2KTt0LmV4cG9ydHM9ZnVuY3Rpb24odCl7Zm9yKHZhciBlPTE7ZTxhcmd1bWVudHMubGVuZ3RoO2UrKyl7dmFyIHI9bnVsbCE9YXJndW1lbnRzW2VdP2FyZ3VtZW50c1tlXTp7fTtlJTI/bihyLCEwKS5mb3JFYWNoKChmdW5jdGlvbihlKXtvKHQsZSxyW2VdKX0pKTpPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycz9PYmplY3QuZGVmaW5lUHJvcGVydGllcyh0LE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKHIpKTpuKHIpLmZvckVhY2goKGZ1bmN0aW9uKGUpe09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LGUsT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihyLGUpKX0pKX1yZXR1cm4gdH0oe30scyx7d29ya2VyUGF0aDp2b2lkIDAhPT1lJiYiZGV2ZWxvcG1lbnQiPT09ZS5lbnYuRkZNUEVHX0VOVj9pKCIvZGlzdC93b3JrZXIuZGV2LmpzP25vY2FjaGU9Ii5jb25jYXQoTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMykpKToiaHR0cHM6Ly91bnBrZy5jb20vQGZmbXBlZy9mZm1wZWdAdiIuY29uY2F0KGMsIi9kaXN0L3dvcmtlci5taW4uanMiKSxjb3JlUGF0aDoiaHR0cHM6Ly91bnBrZy5jb20vQGZmbXBlZy9jb3JlQHYiLmNvbmNhdCh1WyJAZmZtcGVnL2NvcmUiXS5zdWJzdHJpbmcoMSksIi9mZm1wZWctY29yZS5qcyIpLHdvcmtlckJsb2JVUkw6ITB9KX0pLmNhbGwodGhpcyxyKDApKX0sZnVuY3Rpb24odCl7dC5leHBvcnRzPUpTT04ucGFyc2UoJ3sibmFtZSI6IkBmZm1wZWcvZmZtcGVnIiwidmVyc2lvbiI6IjAuNi4xIiwiZGVzY3JpcHRpb24iOiJGRm1wZWcgV2ViQXNzZW1ibHkgdmVyc2lvbiIsIm1haW4iOiJzcmMvaW5kZXguanMiLCJkaXJlY3RvcmllcyI6eyJleGFtcGxlIjoiZXhhbXBsZXMifSwic2NyaXB0cyI6eyJzdGFydCI6Im5vZGUgc2NyaXB0cy9zZXJ2ZXIuanMiLCJidWlsZCI6InJpbXJhZiBkaXN0ICYmIHdlYnBhY2sgLS1jb25maWcgc2NyaXB0cy93ZWJwYWNrLmNvbmZpZy5wcm9kLmpzIiwicHJlcHVibGlzaE9ubHkiOiJucG0gcnVuIGJ1aWxkIiwibGludCI6ImVzbGludCBzcmMiLCJ3YWl0IjoicmltcmFmIGRpc3QgJiYgd2FpdC1vbiBodHRwOi8vbG9jYWxob3N0OjMwMDAvZGlzdC9mZm1wZWcuZGV2LmpzIiwidGVzdCI6Im5wbS1ydW4tYWxsIC1wIC1yIHN0YXJ0IHRlc3Q6YWxsIiwidGVzdDphbGwiOiJucG0tcnVuLWFsbCB3YWl0IHRlc3Q6YnJvd3NlcjpmZm1wZWcgdGVzdDpub2RlOmFsbCIsInRlc3Q6bm9kZSI6Im55YyBtb2NoYSAtLWV4aXQgLS1iYWlsIC0tcmVxdWlyZSAuL3NjcmlwdHMvdGVzdC1oZWxwZXIuanMiLCJ0ZXN0Om5vZGU6YWxsIjoibnBtIHJ1biB0ZXN0Om5vZGUgLS0gLi90ZXN0cy8qLnRlc3QuanMiLCJ0ZXN0OmJyb3dzZXIiOiJtb2NoYS1oZWFkbGVzcy1jaHJvbWUgLWEgaW5jb2duaXRvIC1hIG5vLXNhbmRib3ggLWEgZGlzYWJsZS1zZXR1aWQtc2FuZGJveCAtYSBkaXNhYmxlLWxvZ2dpbmcgLXQgMzAwMDAwIiwidGVzdDpicm93c2VyOmZmbXBlZyI6Im5wbSBydW4gdGVzdDpicm93c2VyIC0tIC1mIC4vdGVzdHMvZmZtcGVnLnRlc3QuaHRtbCJ9LCJicm93c2VyIjp7Ii4vc3JjL3dvcmtlci9ub2RlL2luZGV4LmpzIjoiLi9zcmMvd29ya2VyL2Jyb3dzZXIvaW5kZXguanMifSwicmVwb3NpdG9yeSI6eyJ0eXBlIjoiZ2l0IiwidXJsIjoiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS9mZm1wZWdqcy9mZm1wZWcuanMuZ2l0In0sImtleXdvcmRzIjpbImZmbXBlZyIsIldlYkFzc2VtYmx5IiwidmlkZW8iXSwiYXV0aG9yIjoiSmVyb21lIFd1IDxqZXJvbWV3dXNAZ21haWwuY29tPiIsImxpY2Vuc2UiOiJNSVQiLCJidWdzIjp7InVybCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9mZm1wZWdqcy9mZm1wZWcuanMvaXNzdWVzIn0sImVuZ2luZXMiOnsibm9kZSI6Ij49MTAuNS4wIn0sImhvbWVwYWdlIjoiaHR0cHM6Ly9naXRodWIuY29tL2ZmbXBlZ2pzL2ZmbXBlZy5qcyNyZWFkbWUiLCJkZXBlbmRlbmNpZXMiOnsiQGZmbXBlZy9jb3JlIjoiXjAuNi4wIiwiaWRiIjoiXjQuMC41IiwiaXMtZWxlY3Ryb24iOiJeMi4yLjAiLCJpcy11cmwiOiJeMS4yLjQiLCJub2RlLWZldGNoIjoiXjIuNi4wIiwicmVnZW5lcmF0b3ItcnVudGltZSI6Il4wLjEzLjMiLCJyZXNvbHZlLXVybCI6Il4wLjIuMSJ9LCJkZXZEZXBlbmRlbmNpZXMiOnsiQGJhYmVsL2NvcmUiOiJeNy42LjQiLCJAYmFiZWwvcHJlc2V0LWVudiI6Il43LjYuMyIsImJhYmVsLWxvYWRlciI6Il44LjAuNiIsImNvcnMiOiJeMi44LjUiLCJlc2xpbnQiOiJeNi4xLjAiLCJlc2xpbnQtY29uZmlnLWFpcmJuYi1iYXNlIjoiXjE0LjAuMCIsImVzbGludC1wbHVnaW4taW1wb3J0IjoiXjIuMTguMiIsImV4cGVjdC5qcyI6Il4wLjMuMSIsImV4cHJlc3MiOiJeNC4xNy4xIiwibW9jaGEiOiJeNi4yLjIiLCJtb2NoYS1oZWFkbGVzcy1jaHJvbWUiOiJeMi4wLjMiLCJucG0tcnVuLWFsbCI6Il40LjEuNSIsIm55YyI6Il4xNC4xLjEiLCJ3YWl0LW9uIjoiXjMuMy4wIiwid2VicGFjayI6Il40LjQxLjIiLCJ3ZWJwYWNrLWNsaSI6Il4zLjMuOSIsIndlYnBhY2stZGV2LW1pZGRsZXdhcmUiOiJeMy43LjIifX0nKX0sZnVuY3Rpb24odCxlKXt0LmV4cG9ydHM9e2xvZ2dlcjpmdW5jdGlvbigpe30scHJvZ3Jlc3M6ZnVuY3Rpb24oKXt9fX0sZnVuY3Rpb24odCxlKXt0LmV4cG9ydHM9ZnVuY3Rpb24odCl7dmFyIGUscj10LndvcmtlclBhdGgsbj10LndvcmtlckJsb2JVUkw7aWYoQmxvYiYmVVJMJiZuKXt2YXIgbz1uZXcgQmxvYihbJ2ltcG9ydFNjcmlwdHMoIicuY29uY2F0KHIsJyIpOycpXSx7dHlwZToiYXBwbGljYXRpb24vamF2YXNjcmlwdCJ9KTtlPW5ldyBXb3JrZXIoVVJMLmNyZWF0ZU9iamVjdFVSTChvKSl9ZWxzZSBlPW5ldyBXb3JrZXIocik7cmV0dXJuIGV9fSxmdW5jdGlvbih0LGUpe3QuZXhwb3J0cz1mdW5jdGlvbih0LGUpe3Qub25tZXNzYWdlPWZ1bmN0aW9uKHQpe3ZhciByPXQuZGF0YTtlKHIpfX19LGZ1bmN0aW9uKHQsZSxyKXtmdW5jdGlvbiBuKHQsZSxyLG4sbyxpLGEpe3RyeXt2YXIgYz10W2ldKGEpLHU9Yy52YWx1ZX1jYXRjaCh0KXtyZXR1cm4gdm9pZCByKHQpfWMuZG9uZT9lKHUpOlByb21pc2UucmVzb2x2ZSh1KS50aGVuKG4sbyl9dmFyIG89cigxKSxpPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgUHJvbWlzZSgoZnVuY3Rpb24oZSxyKXt2YXIgbj1uZXcgRmlsZVJlYWRlcjtuLm9ubG9hZD1mdW5jdGlvbigpe2Uobi5yZXN1bHQpfSxuLm9uZXJyb3I9ZnVuY3Rpb24odCl7dmFyIGU9dC50YXJnZXQuZXJyb3IuY29kZTtyKEVycm9yKCJGaWxlIGNvdWxkIG5vdCBiZSByZWFkISBDb2RlPSIuY29uY2F0KGUpKSl9LG4ucmVhZEFzQXJyYXlCdWZmZXIodCl9KSl9O3QuZXhwb3J0cz1mdW5jdGlvbigpe3ZhciB0LGU9KHQ9cmVnZW5lcmF0b3JSdW50aW1lLm1hcmsoKGZ1bmN0aW9uIHQoZSl7dmFyIHIsbjtyZXR1cm4gcmVnZW5lcmF0b3JSdW50aW1lLndyYXAoKGZ1bmN0aW9uKHQpe2Zvcig7Oylzd2l0Y2godC5wcmV2PXQubmV4dCl7Y2FzZSAwOmlmKHI9ZSx2b2lkIDAhPT1lKXt0Lm5leHQ9MzticmVha31yZXR1cm4gdC5hYnJ1cHQoInJldHVybiIsInVuZGVmaW5lZCIpO2Nhc2UgMzppZigic3RyaW5nIiE9dHlwZW9mIGUpe3QubmV4dD0xNjticmVha31pZighL2RhdGE6X2RhdGFcLyhbYS16QS1aXSopO2Jhc2U2NCwoW14iXSopLy50ZXN0KGUpKXt0Lm5leHQ9ODticmVha31yPWF0b2IoZS5zcGxpdCgiLCIpWzFdKS5zcGxpdCgiIikubWFwKChmdW5jdGlvbih0KXtyZXR1cm4gdC5jaGFyQ29kZUF0KDApfSkpLHQubmV4dD0xNDticmVhaztjYXNlIDg6cmV0dXJuIHQubmV4dD0xMCxmZXRjaChvKGUpKTtjYXNlIDEwOnJldHVybiBuPXQuc2VudCx0Lm5leHQ9MTMsbi5hcnJheUJ1ZmZlcigpO2Nhc2UgMTM6cj10LnNlbnQ7Y2FzZSAxNDp0Lm5leHQ9MjA7YnJlYWs7Y2FzZSAxNjppZighKGUgaW5zdGFuY2VvZiBGaWxlfHxlIGluc3RhbmNlb2YgQmxvYikpe3QubmV4dD0yMDticmVha31yZXR1cm4gdC5uZXh0PTE5LGkoZSk7Y2FzZSAxOTpyPXQuc2VudDtjYXNlIDIwOnJldHVybiB0LmFicnVwdCgicmV0dXJuIixuZXcgVWludDhBcnJheShyKSk7Y2FzZSAyMTpjYXNlImVuZCI6cmV0dXJuIHQuc3RvcCgpfX0pLHQpfSkpLGZ1bmN0aW9uKCl7dmFyIGU9dGhpcyxyPWFyZ3VtZW50cztyZXR1cm4gbmV3IFByb21pc2UoKGZ1bmN0aW9uKG8saSl7dmFyIGE9dC5hcHBseShlLHIpO2Z1bmN0aW9uIGModCl7bihhLG8saSxjLHUsIm5leHQiLHQpfWZ1bmN0aW9uIHUodCl7bihhLG8saSxjLHUsInRocm93Iix0KX1jKHZvaWQgMCl9KSl9KTtyZXR1cm4gZnVuY3Rpb24odCl7cmV0dXJuIGUuYXBwbHkodGhpcyxhcmd1bWVudHMpfX0oKX1dKX0pKTsKLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmZtcGVnLm1pbi5qcy5tYXA="},{"meta":{"name":"[email protected]","url":"https://bundle.run/[email protected]","ts":1691113794682,"mimetype":"text/plain"},"source":"IWZ1bmN0aW9uKGUpe2lmKCJvYmplY3QiPT10eXBlb2YgZXhwb3J0cyYmInVuZGVmaW5lZCIhPXR5cGVvZiBtb2R1bGUpbW9kdWxlLmV4cG9ydHM9ZSgpO2Vsc2UgaWYoImZ1bmN0aW9uIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZClkZWZpbmUoW10sZSk7ZWxzZXsoInVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3c/d2luZG93OiJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsP2dsb2JhbDoidW5kZWZpbmVkIiE9dHlwZW9mIHNlbGY/c2VsZjp0aGlzKS5wUXVldWU9ZSgpfX0oZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24gZSh0LHIsbil7ZnVuY3Rpb24gaShzLHUpe2lmKCFyW3NdKXtpZighdFtzXSl7dmFyIGE9ImZ1bmN0aW9uIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEocywhMCk7aWYobylyZXR1cm4gbyhzLCEwKTt2YXIgbD1uZXcgRXJyb3IoIkNhbm5vdCBmaW5kIG1vZHVsZSAnIitzKyInIik7dGhyb3cgbC5jb2RlPSJNT0RVTEVfTk9UX0ZPVU5EIixsfXZhciBjPXJbc109e2V4cG9ydHM6e319O3Rbc11bMF0uY2FsbChjLmV4cG9ydHMsZnVuY3Rpb24oZSl7cmV0dXJuIGkodFtzXVsxXVtlXXx8ZSl9LGMsYy5leHBvcnRzLGUsdCxyLG4pfXJldHVybiByW3NdLmV4cG9ydHN9Zm9yKHZhciBvPSJmdW5jdGlvbiI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLHM9MDtzPG4ubGVuZ3RoO3MrKylpKG5bc10pO3JldHVybiBpfX0oKSh7MTpbZnVuY3Rpb24oZSx0LHIpeyJ1c2Ugc3RyaWN0IjtPYmplY3QuZGVmaW5lUHJvcGVydHkociwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7Y29uc3Qgbj1lKCJldmVudGVtaXR0ZXIzIiksaT1lKCJwLXRpbWVvdXQiKSxvPWUoIi4vcHJpb3JpdHktcXVldWUiKSxzPSgpPT57fSx1PW5ldyBpLlRpbWVvdXRFcnJvcjtyLmRlZmF1bHQ9Y2xhc3MgZXh0ZW5kcyBue2NvbnN0cnVjdG9yKGUpe2lmKHN1cGVyKCksT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIl9jYXJyeW92ZXJDb25jdXJyZW5jeUNvdW50Iix7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6dm9pZCAwfSksT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIl9pc0ludGVydmFsSWdub3JlZCIse2VudW1lcmFibGU6ITAsY29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwLHZhbHVlOnZvaWQgMH0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJfaW50ZXJ2YWxDb3VudCIse2VudW1lcmFibGU6ITAsY29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwLHZhbHVlOjB9KSxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiX2ludGVydmFsQ2FwIix7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6dm9pZCAwfSksT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIl9pbnRlcnZhbCIse2VudW1lcmFibGU6ITAsY29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwLHZhbHVlOnZvaWQgMH0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJfaW50ZXJ2YWxFbmQiLHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMCx2YWx1ZTowfSksT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIl9pbnRlcnZhbElkIix7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6dm9pZCAwfSksT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIl90aW1lb3V0SWQiLHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMCx2YWx1ZTp2b2lkIDB9KSxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiX3F1ZXVlIix7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6dm9pZCAwfSksT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIl9xdWV1ZUNsYXNzIix7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6dm9pZCAwfSksT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIl9wZW5kaW5nQ291bnQiLHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMCx2YWx1ZTowfSksT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIl9jb25jdXJyZW5jeSIse2VudW1lcmFibGU6ITAsY29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwLHZhbHVlOnZvaWQgMH0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJfaXNQYXVzZWQiLHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMCx2YWx1ZTp2b2lkIDB9KSxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiX3Jlc29sdmVFbXB0eSIse2VudW1lcmFibGU6ITAsY29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwLHZhbHVlOnN9KSxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiX3Jlc29sdmVJZGxlIix7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6c30pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJfdGltZW91dCIse2VudW1lcmFibGU6ITAsY29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwLHZhbHVlOnZvaWQgMH0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJfdGhyb3dPblRpbWVvdXQiLHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMCx2YWx1ZTp2b2lkIDB9KSwhKCJudW1iZXIiPT10eXBlb2YoZT1PYmplY3QuYXNzaWduKHtjYXJyeW92ZXJDb25jdXJyZW5jeUNvdW50OiExLGludGVydmFsQ2FwOjEvMCxpbnRlcnZhbDowLGNvbmN1cnJlbmN5OjEvMCxhdXRvU3RhcnQ6ITAscXVldWVDbGFzczpvLmRlZmF1bHR9LGUpKS5pbnRlcnZhbENhcCYmZS5pbnRlcnZhbENhcD49MSkpdGhyb3cgbmV3IFR5cGVFcnJvcihgRXhwZWN0ZWQgXGBpbnRlcnZhbENhcFxgIHRvIGJlIGEgbnVtYmVyIGZyb20gMSBhbmQgdXAsIGdvdCBcYCR7ZS5pbnRlcnZhbENhcH1cYCAoJHt0eXBlb2YgZS5pbnRlcnZhbENhcH0pYCk7aWYodm9pZCAwPT09ZS5pbnRlcnZhbHx8IShOdW1iZXIuaXNGaW5pdGUoZS5pbnRlcnZhbCkmJmUuaW50ZXJ2YWw+PTApKXRocm93IG5ldyBUeXBlRXJyb3IoYEV4cGVjdGVkIFxgaW50ZXJ2YWxcYCB0byBiZSBhIGZpbml0ZSBudW1iZXIgPj0gMCwgZ290IFxgJHtlLmludGVydmFsfVxgICgke3R5cGVvZiBlLmludGVydmFsfSlgKTt0aGlzLl9jYXJyeW92ZXJDb25jdXJyZW5jeUNvdW50PWUuY2FycnlvdmVyQ29uY3VycmVuY3lDb3VudCx0aGlzLl9pc0ludGVydmFsSWdub3JlZD1lLmludGVydmFsQ2FwPT09MS8wfHwwPT09ZS5pbnRlcnZhbCx0aGlzLl9pbnRlcnZhbENhcD1lLmludGVydmFsQ2FwLHRoaXMuX2ludGVydmFsPWUuaW50ZXJ2YWwsdGhpcy5fcXVldWU9bmV3IGUucXVldWVDbGFzcyx0aGlzLl9xdWV1ZUNsYXNzPWUucXVldWVDbGFzcyx0aGlzLmNvbmN1cnJlbmN5PWUuY29uY3VycmVuY3ksdGhpcy5fdGltZW91dD1lLnRpbWVvdXQsdGhpcy5fdGhyb3dPblRpbWVvdXQ9ITA9PT1lLnRocm93T25UaW1lb3V0LHRoaXMuX2lzUGF1c2VkPSExPT09ZS5hdXRvU3RhcnR9Z2V0IF9kb2VzSW50ZXJ2YWxBbGxvd0Fub3RoZXIoKXtyZXR1cm4gdGhpcy5faXNJbnRlcnZhbElnbm9yZWR8fHRoaXMuX2ludGVydmFsQ291bnQ8dGhpcy5faW50ZXJ2YWxDYXB9Z2V0IF9kb2VzQ29uY3VycmVudEFsbG93QW5vdGhlcigpe3JldHVybiB0aGlzLl9wZW5kaW5nQ291bnQ8dGhpcy5fY29uY3VycmVuY3l9X25leHQoKXt0aGlzLl9wZW5kaW5nQ291bnQtLSx0aGlzLl90cnlUb1N0YXJ0QW5vdGhlcigpfV9yZXNvbHZlUHJvbWlzZXMoKXt0aGlzLl9yZXNvbHZlRW1wdHkoKSx0aGlzLl9yZXNvbHZlRW1wdHk9cywwPT09dGhpcy5fcGVuZGluZ0NvdW50JiYodGhpcy5fcmVzb2x2ZUlkbGUoKSx0aGlzLl9yZXNvbHZlSWRsZT1zKX1fb25SZXN1bWVJbnRlcnZhbCgpe3RoaXMuX29uSW50ZXJ2YWwoKSx0aGlzLl9pbml0aWFsaXplSW50ZXJ2YWxJZk5lZWRlZCgpLHRoaXMuX3RpbWVvdXRJZD12b2lkIDB9X2lzSW50ZXJ2YWxQYXVzZWQoKXtjb25zdCBlPURhdGUubm93KCk7aWYodm9pZCAwPT09dGhpcy5faW50ZXJ2YWxJZCl7Y29uc3QgdD10aGlzLl9pbnRlcnZhbEVuZC1lO2lmKCEodDwwKSlyZXR1cm4gdm9pZCAwPT09dGhpcy5fdGltZW91dElkJiYodGhpcy5fdGltZW91dElkPXNldFRpbWVvdXQoKCk9Pnt0aGlzLl9vblJlc3VtZUludGVydmFsKCl9LHQpKSwhMDt0aGlzLl9pbnRlcnZhbENvdW50PXRoaXMuX2NhcnJ5b3ZlckNvbmN1cnJlbmN5Q291bnQ/dGhpcy5fcGVuZGluZ0NvdW50OjB9cmV0dXJuITF9X3RyeVRvU3RhcnRBbm90aGVyKCl7aWYoMD09PXRoaXMuX3F1ZXVlLnNpemUpcmV0dXJuIHRoaXMuX2ludGVydmFsSWQmJmNsZWFySW50ZXJ2YWwodGhpcy5faW50ZXJ2YWxJZCksdGhpcy5faW50ZXJ2YWxJZD12b2lkIDAsdGhpcy5fcmVzb2x2ZVByb21pc2VzKCksITE7aWYoIXRoaXMuX2lzUGF1c2VkKXtjb25zdCBlPSF0aGlzLl9pc0ludGVydmFsUGF1c2VkKCk7aWYodGhpcy5fZG9lc0ludGVydmFsQWxsb3dBbm90aGVyJiZ0aGlzLl9kb2VzQ29uY3VycmVudEFsbG93QW5vdGhlcilyZXR1cm4gdGhpcy5lbWl0KCJhY3RpdmUiKSx0aGlzLl9xdWV1ZS5kZXF1ZXVlKCkoKSxlJiZ0aGlzLl9pbml0aWFsaXplSW50ZXJ2YWxJZk5lZWRlZCgpLCEwfXJldHVybiExfV9pbml0aWFsaXplSW50ZXJ2YWxJZk5lZWRlZCgpe3RoaXMuX2lzSW50ZXJ2YWxJZ25vcmVkfHx2b2lkIDAhPT10aGlzLl9pbnRlcnZhbElkfHwodGhpcy5faW50ZXJ2YWxJZD1zZXRJbnRlcnZhbCgoKT0+e3RoaXMuX29uSW50ZXJ2YWwoKX0sdGhpcy5faW50ZXJ2YWwpLHRoaXMuX2ludGVydmFsRW5kPURhdGUubm93KCkrdGhpcy5faW50ZXJ2YWwpfV9vbkludGVydmFsKCl7MD09PXRoaXMuX2ludGVydmFsQ291bnQmJjA9PT10aGlzLl9wZW5kaW5nQ291bnQmJnRoaXMuX2ludGVydmFsSWQmJihjbGVhckludGVydmFsKHRoaXMuX2ludGVydmFsSWQpLHRoaXMuX2ludGVydmFsSWQ9dm9pZCAwKSx0aGlzLl9pbnRlcnZhbENvdW50PXRoaXMuX2NhcnJ5b3ZlckNvbmN1cnJlbmN5Q291bnQ/dGhpcy5fcGVuZGluZ0NvdW50OjAsdGhpcy5fcHJvY2Vzc1F1ZXVlKCl9X3Byb2Nlc3NRdWV1ZSgpe2Zvcig7dGhpcy5fdHJ5VG9TdGFydEFub3RoZXIoKTspO31nZXQgY29uY3VycmVuY3koKXtyZXR1cm4gdGhpcy5fY29uY3VycmVuY3l9c2V0IGNvbmN1cnJlbmN5KGUpe2lmKCEoIm51bWJlciI9PXR5cGVvZiBlJiZlPj0xKSl0aHJvdyBuZXcgVHlwZUVycm9yKGBFeHBlY3RlZCBcYGNvbmN1cnJlbmN5XGAgdG8gYmUgYSBudW1iZXIgZnJvbSAxIGFuZCB1cCwgZ290IFxgJHtlfVxgICgke3R5cGVvZiBlfSlgKTt0aGlzLl9jb25jdXJyZW5jeT1lLHRoaXMuX3Byb2Nlc3NRdWV1ZSgpfWFzeW5jIGFkZChlLHQ9e30pe3JldHVybiBuZXcgUHJvbWlzZSgocixuKT0+e3RoaXMuX3F1ZXVlLmVucXVldWUoYXN5bmMoKT0+e3RoaXMuX3BlbmRpbmdDb3VudCsrLHRoaXMuX2ludGVydmFsQ291bnQrKzt0cnl7Y29uc3Qgbz12b2lkIDA9PT10aGlzLl90aW1lb3V0JiZ2b2lkIDA9PT10LnRpbWVvdXQ/ZSgpOmkuZGVmYXVsdChQcm9taXNlLnJlc29sdmUoZSgpKSx2b2lkIDA9PT10LnRpbWVvdXQ/dGhpcy5fdGltZW91dDp0LnRpbWVvdXQsKCk9Pnsodm9pZCAwPT09dC50aHJvd09uVGltZW91dD90aGlzLl90aHJvd09uVGltZW91dDp0LnRocm93T25UaW1lb3V0KSYmbih1KX0pO3IoYXdhaXQgbyl9Y2F0Y2goZSl7bihlKX10aGlzLl9uZXh0KCl9LHQpLHRoaXMuX3RyeVRvU3RhcnRBbm90aGVyKCl9KX1hc3luYyBhZGRBbGwoZSx0KXtyZXR1cm4gUHJvbWlzZS5hbGwoZS5tYXAoYXN5bmMgZT0+dGhpcy5hZGQoZSx0KSkpfXN0YXJ0KCl7cmV0dXJuIHRoaXMuX2lzUGF1c2VkPyh0aGlzLl9pc1BhdXNlZD0hMSx0aGlzLl9wcm9jZXNzUXVldWUoKSx0aGlzKTp0aGlzfXBhdXNlKCl7dGhpcy5faXNQYXVzZWQ9ITB9Y2xlYXIoKXt0aGlzLl9xdWV1ZT1uZXcgdGhpcy5fcXVldWVDbGFzc31hc3luYyBvbkVtcHR5KCl7aWYoMCE9PXRoaXMuX3F1ZXVlLnNpemUpcmV0dXJuIG5ldyBQcm9taXNlKGU9Pntjb25zdCB0PXRoaXMuX3Jlc29sdmVFbXB0eTt0aGlzLl9yZXNvbHZlRW1wdHk9KCgpPT57dCgpLGUoKX0pfSl9YXN5bmMgb25JZGxlKCl7aWYoMCE9PXRoaXMuX3BlbmRpbmdDb3VudHx8MCE9PXRoaXMuX3F1ZXVlLnNpemUpcmV0dXJuIG5ldyBQcm9taXNlKGU9Pntjb25zdCB0PXRoaXMuX3Jlc29sdmVJZGxlO3RoaXMuX3Jlc29sdmVJZGxlPSgoKT0+e3QoKSxlKCl9KX0pfWdldCBzaXplKCl7cmV0dXJuIHRoaXMuX3F1ZXVlLnNpemV9c2l6ZUJ5KGUpe3JldHVybiB0aGlzLl9xdWV1ZS5maWx0ZXIoZSkubGVuZ3RofWdldCBwZW5kaW5nKCl7cmV0dXJuIHRoaXMuX3BlbmRpbmdDb3VudH1nZXQgaXNQYXVzZWQoKXtyZXR1cm4gdGhpcy5faXNQYXVzZWR9c2V0IHRpbWVvdXQoZSl7dGhpcy5fdGltZW91dD1lfWdldCB0aW1lb3V0KCl7cmV0dXJuIHRoaXMuX3RpbWVvdXR9fX0seyIuL3ByaW9yaXR5LXF1ZXVlIjozLGV2ZW50ZW1pdHRlcjM6NCwicC10aW1lb3V0Ijo2fV0sMjpbZnVuY3Rpb24oZSx0LHIpeyJ1c2Ugc3RyaWN0IjtPYmplY3QuZGVmaW5lUHJvcGVydHkociwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSksci5kZWZhdWx0PWZ1bmN0aW9uKGUsdCxyKXtsZXQgbj0wLGk9ZS5sZW5ndGg7Zm9yKDtpPjA7KXtjb25zdCBvPWkvMnwwO2xldCBzPW4rbztyKGVbc10sdCk8PTA/KG49KytzLGktPW8rMSk6aT1vfXJldHVybiBufX0se31dLDM6W2Z1bmN0aW9uKGUsdCxyKXsidXNlIHN0cmljdCI7T2JqZWN0LmRlZmluZVByb3BlcnR5KHIsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pO2NvbnN0IG49ZSgiLi9sb3dlci1ib3VuZCIpO3IuZGVmYXVsdD1jbGFzc3tjb25zdHJ1Y3Rvcigpe09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJfcXVldWUiLHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMCx2YWx1ZTpbXX0pfWVucXVldWUoZSx0KXtjb25zdCByPXtwcmlvcml0eToodD1PYmplY3QuYXNzaWduKHtwcmlvcml0eTowfSx0KSkucHJpb3JpdHkscnVuOmV9O2lmKHRoaXMuc2l6ZSYmdGhpcy5fcXVldWVbdGhpcy5zaXplLTFdLnByaW9yaXR5Pj10LnByaW9yaXR5KXJldHVybiB2b2lkIHRoaXMuX3F1ZXVlLnB1c2gocik7Y29uc3QgaT1uLmRlZmF1bHQodGhpcy5fcXVldWUsciwoZSx0KT0+dC5wcmlvcml0eS1lLnByaW9yaXR5KTt0aGlzLl9xdWV1ZS5zcGxpY2UoaSwwLHIpfWRlcXVldWUoKXtjb25zdCBlPXRoaXMuX3F1ZXVlLnNoaWZ0KCk7cmV0dXJuIGUmJmUucnVufWZpbHRlcihlKXtyZXR1cm4gdGhpcy5fcXVldWUuZmlsdGVyKHQ9PnQucHJpb3JpdHk9PT1lLnByaW9yaXR5KS5tYXAoZT0+ZS5ydW4pfWdldCBzaXplKCl7cmV0dXJuIHRoaXMuX3F1ZXVlLmxlbmd0aH19fSx7Ii4vbG93ZXItYm91bmQiOjJ9XSw0OltmdW5jdGlvbihlLHQscil7InVzZSBzdHJpY3QiO3ZhciBuPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksaT0ifiI7ZnVuY3Rpb24gbygpe31mdW5jdGlvbiBzKGUsdCxyKXt0aGlzLmZuPWUsdGhpcy5jb250ZXh0PXQsdGhpcy5vbmNlPXJ8fCExfWZ1bmN0aW9uIHUoZSx0LHIsbixvKXtpZigiZnVuY3Rpb24iIT10eXBlb2Ygcil0aHJvdyBuZXcgVHlwZUVycm9yKCJUaGUgbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uIik7dmFyIHU9bmV3IHMocixufHxlLG8pLGE9aT9pK3Q6dDtyZXR1cm4gZS5fZXZlbnRzW2FdP2UuX2V2ZW50c1thXS5mbj9lLl9ldmVudHNbYV09W2UuX2V2ZW50c1thXSx1XTplLl9ldmVudHNbYV0ucHVzaCh1KTooZS5fZXZlbnRzW2FdPXUsZS5fZXZlbnRzQ291bnQrKyksZX1mdW5jdGlvbiBhKGUsdCl7MD09LS1lLl9ldmVudHNDb3VudD9lLl9ldmVudHM9bmV3IG86ZGVsZXRlIGUuX2V2ZW50c1t0XX1mdW5jdGlvbiBsKCl7dGhpcy5fZXZlbnRzPW5ldyBvLHRoaXMuX2V2ZW50c0NvdW50PTB9T2JqZWN0LmNyZWF0ZSYmKG8ucHJvdG90eXBlPU9iamVjdC5jcmVhdGUobnVsbCksKG5ldyBvKS5fX3Byb3RvX198fChpPSExKSksbC5wcm90b3R5cGUuZXZlbnROYW1lcz1mdW5jdGlvbigpe3ZhciBlLHQscj1bXTtpZigwPT09dGhpcy5fZXZlbnRzQ291bnQpcmV0dXJuIHI7Zm9yKHQgaW4gZT10aGlzLl9ldmVudHMpbi5jYWxsKGUsdCkmJnIucHVzaChpP3Quc2xpY2UoMSk6dCk7cmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM/ci5jb25jYXQoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhlKSk6cn0sbC5wcm90b3R5cGUubGlzdGVuZXJzPWZ1bmN0aW9uKGUpe3ZhciB0PWk/aStlOmUscj10aGlzLl9ldmVudHNbdF07aWYoIXIpcmV0dXJuW107aWYoci5mbilyZXR1cm5bci5mbl07Zm9yKHZhciBuPTAsbz1yLmxlbmd0aCxzPW5ldyBBcnJheShvKTtuPG87bisrKXNbbl09cltuXS5mbjtyZXR1cm4gc30sbC5wcm90b3R5cGUubGlzdGVuZXJDb3VudD1mdW5jdGlvbihlKXt2YXIgdD1pP2krZTplLHI9dGhpcy5fZXZlbnRzW3RdO3JldHVybiByP3IuZm4/MTpyLmxlbmd0aDowfSxsLnByb3RvdHlwZS5lbWl0PWZ1bmN0aW9uKGUsdCxyLG4sbyxzKXt2YXIgdT1pP2krZTplO2lmKCF0aGlzLl9ldmVudHNbdV0pcmV0dXJuITE7dmFyIGEsbCxjPXRoaXMuX2V2ZW50c1t1XSxoPWFyZ3VtZW50cy5sZW5ndGg7aWYoYy5mbil7c3dpdGNoKGMub25jZSYmdGhpcy5yZW1vdmVMaXN0ZW5lcihlLGMuZm4sdm9pZCAwLCEwKSxoKXtjYXNlIDE6cmV0dXJuIGMuZm4uY2FsbChjLmNvbnRleHQpLCEwO2Nhc2UgMjpyZXR1cm4gYy5mbi5jYWxsKGMuY29udGV4dCx0KSwhMDtjYXNlIDM6cmV0dXJuIGMuZm4uY2FsbChjLmNvbnRleHQsdCxyKSwhMDtjYXNlIDQ6cmV0dXJuIGMuZm4uY2FsbChjLmNvbnRleHQsdCxyLG4pLCEwO2Nhc2UgNTpyZXR1cm4gYy5mbi5jYWxsKGMuY29udGV4dCx0LHIsbixvKSwhMDtjYXNlIDY6cmV0dXJuIGMuZm4uY2FsbChjLmNvbnRleHQsdCxyLG4sbyxzKSwhMH1mb3IobD0xLGE9bmV3IEFycmF5KGgtMSk7bDxoO2wrKylhW2wtMV09YXJndW1lbnRzW2xdO2MuZm4uYXBwbHkoYy5jb250ZXh0LGEpfWVsc2V7dmFyIGYsdj1jLmxlbmd0aDtmb3IobD0wO2w8djtsKyspc3dpdGNoKGNbbF0ub25jZSYmdGhpcy5yZW1vdmVMaXN0ZW5lcihlLGNbbF0uZm4sdm9pZCAwLCEwKSxoKXtjYXNlIDE6Y1tsXS5mbi5jYWxsKGNbbF0uY29udGV4dCk7YnJlYWs7Y2FzZSAyOmNbbF0uZm4uY2FsbChjW2xdLmNvbnRleHQsdCk7YnJlYWs7Y2FzZSAzOmNbbF0uZm4uY2FsbChjW2xdLmNvbnRleHQsdCxyKTticmVhaztjYXNlIDQ6Y1tsXS5mbi5jYWxsKGNbbF0uY29udGV4dCx0LHIsbik7YnJlYWs7ZGVmYXVsdDppZighYSlmb3IoZj0xLGE9bmV3IEFycmF5KGgtMSk7ZjxoO2YrKylhW2YtMV09YXJndW1lbnRzW2ZdO2NbbF0uZm4uYXBwbHkoY1tsXS5jb250ZXh0LGEpfX1yZXR1cm4hMH0sbC5wcm90b3R5cGUub249ZnVuY3Rpb24oZSx0LHIpe3JldHVybiB1KHRoaXMsZSx0LHIsITEpfSxsLnByb3RvdHlwZS5vbmNlPWZ1bmN0aW9uKGUsdCxyKXtyZXR1cm4gdSh0aGlzLGUsdCxyLCEwKX0sbC5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXI9ZnVuY3Rpb24oZSx0LHIsbil7dmFyIG89aT9pK2U6ZTtpZighdGhpcy5fZXZlbnRzW29dKXJldHVybiB0aGlzO2lmKCF0KXJldHVybiBhKHRoaXMsbyksdGhpczt2YXIgcz10aGlzLl9ldmVudHNbb107aWYocy5mbilzLmZuIT09dHx8biYmIXMub25jZXx8ciYmcy5jb250ZXh0IT09cnx8YSh0aGlzLG8pO2Vsc2V7Zm9yKHZhciB1PTAsbD1bXSxjPXMubGVuZ3RoO3U8Yzt1KyspKHNbdV0uZm4hPT10fHxuJiYhc1t1XS5vbmNlfHxyJiZzW3VdLmNvbnRleHQhPT1yKSYmbC5wdXNoKHNbdV0pO2wubGVuZ3RoP3RoaXMuX2V2ZW50c1tvXT0xPT09bC5sZW5ndGg/bFswXTpsOmEodGhpcyxvKX1yZXR1cm4gdGhpc30sbC5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzPWZ1bmN0aW9uKGUpe3ZhciB0O3JldHVybiBlPyh0PWk/aStlOmUsdGhpcy5fZXZlbnRzW3RdJiZhKHRoaXMsdCkpOih0aGlzLl9ldmVudHM9bmV3IG8sdGhpcy5fZXZlbnRzQ291bnQ9MCksdGhpc30sbC5wcm90b3R5cGUub2ZmPWwucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyLGwucHJvdG90eXBlLmFkZExpc3RlbmVyPWwucHJvdG90eXBlLm9uLGwucHJlZml4ZWQ9aSxsLkV2ZW50RW1pdHRlcj1sLHZvaWQgMCE9PXQmJih0LmV4cG9ydHM9bCl9LHt9XSw1OltmdW5jdGlvbihlLHQscil7InVzZSBzdHJpY3QiO3QuZXhwb3J0cz0oKGUsdCk9Pih0PXR8fCgoKT0+e30pLGUudGhlbihlPT5uZXcgUHJvbWlzZShlPT57ZSh0KCkpfSkudGhlbigoKT0+ZSksZT0+bmV3IFByb21pc2UoZT0+e2UodCgpKX0pLnRoZW4oKCk9Pnt0aHJvdyBlfSkpKSl9LHt9XSw2OltmdW5jdGlvbihlLHQscil7InVzZSBzdHJpY3QiO2NvbnN0IG49ZSgicC1maW5hbGx5Iik7Y2xhc3MgaSBleHRlbmRzIEVycm9ye2NvbnN0cnVjdG9yKGUpe3N1cGVyKGUpLHRoaXMubmFtZT0iVGltZW91dEVycm9yIn19Y29uc3Qgbz0oZSx0LHIpPT5uZXcgUHJvbWlzZSgobyxzKT0+e2lmKCJudW1iZXIiIT10eXBlb2YgdHx8dDwwKXRocm93IG5ldyBUeXBlRXJyb3IoIkV4cGVjdGVkIGBtaWxsaXNlY29uZHNgIHRvIGJlIGEgcG9zaXRpdmUgbnVtYmVyIik7aWYodD09PTEvMClyZXR1cm4gdm9pZCBvKGUpO2NvbnN0IHU9c2V0VGltZW91dCgoKT0+e2lmKCJmdW5jdGlvbiI9PXR5cGVvZiByKXt0cnl7byhyKCkpfWNhdGNoKGUpe3MoZSl9cmV0dXJufWNvbnN0IG49ciBpbnN0YW5jZW9mIEVycm9yP3I6bmV3IGkoInN0cmluZyI9PXR5cGVvZiByP3I6YFByb21pc2UgdGltZWQgb3V0IGFmdGVyICR7dH0gbWlsbGlzZWNvbmRzYCk7ImZ1bmN0aW9uIj09dHlwZW9mIGUuY2FuY2VsJiZlLmNhbmNlbCgpLHMobil9LHQpO24oZS50aGVuKG8scyksKCk9PntjbGVhclRpbWVvdXQodSl9KX0pO3QuZXhwb3J0cz1vLHQuZXhwb3J0cy5kZWZhdWx0PW8sdC5leHBvcnRzLlRpbWVvdXRFcnJvcj1pfSx7InAtZmluYWxseSI6NX1dfSx7fSxbMV0pKDEpfSk7"}]},{"name":"Image Max URL","options":{"check_for_updates":true,"comment":null,"compat_foreach":false,"compat_metadata":false,"compat_powerful_this":null,"compat_wrappedjsobject":false,"compatopts_for_requires":true,"noframes":null,"override":{"merge_connects":true,"merge_excludes":true,"merge_includes":true,"merge_matches":true,"orig_connects":["*","api.github.com"],"orig_excludes":[],"orig_includes":["*"],"orig_matches":[],"orig_noframes":null,"orig_run_at":"document-start","use_blockers":[],"use_connects":["youtube.com","dreamstime.com","aetnd.com","api.imgur.com","www.123rf.com","xhamster.com","*"],"use_excludes":[],"use_includes":[],"use_matches":[]},"run_at":null,"sandbox":null,"tab_types":null,"unwrap":null,"user_modified":null},"storage":{"ts":1707026101866,"data":{"last_update_check":"s1707026101866","last_update_version":"s\"2024.1.1\"","settings_version":"s11"}},"enabled":true,"position":6,"file_url":"https://greasyfork.org/scripts/36662-image-max-url/code/Image%20Max%20URL.user.js","uuid":"9c38162f-b72c-42ba-b72b-4dd22da778ea","source":"Ly8gQGxpY2Vuc2UgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wIEFwYWNoZS0yLjAKLy8gXiBmb3IgTGlicmVKUyAodGhpcyBoYXMgdG8gYmUgdGhlIGZpcnN0IGNvbW1lbnQgaW4gdGhlIGZpbGUpCgovLyA9PVVzZXJTY3JpcHQ9PQovLyBAbmFtZSAgICAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTphciAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpjcyAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpkYSAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpkZSAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTplbCAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTplbyAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTplcyAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpmaSAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpmciAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpmci1DQSAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpoZSAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpoaSAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpodSAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTppZCAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTppdCAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpqYSAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTprbyAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpuYiAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpubCAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpwbCAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpwdC1CUiAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpydSAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTpiZyAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTp1ayAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTp0aCAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTp0ciAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTp2aSAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTp6aCAgICAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTp6aC1DTiAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTp6aC1UVyAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAbmFtZTp6aC1ISyAgICAgICAgSW1hZ2UgTWF4IFVSTAovLyBAZGVzY3JpcHRpb24gICAgICAgRmluZHMgbGFyZ2VyIG9yIG9yaWdpbmFsIHZlcnNpb25zIG9mIGltYWdlcyBhbmQgdmlkZW9zIGZvciA4MDAwKyB3ZWJzaXRlcywgaW5jbHVkaW5nIGEgcG93ZXJmdWwgbWVkaWEgcG9wdXAgYW5kIGRvd25sb2FkIGZlYXR1cmUKLy8gQGRlc2NyaXB0aW9uOmFyICAgINin2YTYqNit2Ksg2LnZhiDZhtiz2K4g2KPZg9io2LEg2KPZiCDYo9i12YTZitipINmF2YYg2KfZhNi12YjYsSDZhNij2YPYq9ixINmF2YYgODAwMCDZhdmI2YLYuSDZiNmK2KgKLy8gQGRlc2NyaXB0aW9uOmNzICAgIFZ5aGxlZMOhIHbEm3TFocOtIG5lYm8gcMWvdm9kbsOtIHZlcnplIG9icsOhemvFryBhIHZpZGXDrSBwcm8gdsOtY2UgbmXFviA4MDAwIHdlYsWvCi8vIEBkZXNjcmlwdGlvbjpkYSAgICBGaW5kZXIgc3TDuHJyZSBlbGxlciBvcmlnaW5hbGUgdmVyc2lvbmVyIGFmIGJpbGxlZGVyIG9nIHZpZGVvZXIgdGlsIG1lcmUgZW5kIDgwMDAgd2Vic3RlZGVyCi8vIEBkZXNjcmlwdGlvbjpkZSAgICBTdWNodCBuYWNoIGdyw7bDn2VyZW4gb2RlciBvcmlnaW5hbGVuIFZlcnNpb25lbiB2b24gQmlsZGVybiB1bmQgVmlkZW9zIGbDvHIgbWVociBhbHMgODAwMCBXZWJzaXRlcwovLyBAZGVzY3JpcHRpb246ZWwgICAgzpLPgc6vz4POus61zrkgzrzOtc6zzrHOu8+Nz4TOtc+BzrXPgiDOriDPgM+Bz4nPhM+Mz4TPhc+AzrXPgiDOtc66zrTPjM+DzrXOuc+CIM61zrnOus+Mzr3Pic69IM66zrHOuSDOss6vzr3PhM61zr8gzrPOuc6xIM+AzrXPgc65z4PPg8+Mz4TOtc+Bzr/Phc+CIM6xz4DPjCA4MDAwIM65z4PPhM+Mz4TOv8+Azr/Phc+CCi8vIEBkZXNjcmlwdGlvbjplbyAgICBUcm92YXMgcGxpIGdyYW5kYWpuIGHFrSBvcmlnaW5hbGFqbiB2ZXJzaW9qbiBkZSBiaWxkb2oga2FqIGZpbG1ldG9qIHBvciBwbGkgb2wgODAwMCByZXRlam9qCi8vIEBkZXNjcmlwdGlvbjplcyAgICBFbmN1ZW50cmEgaW3DoWdlbmVzIG3DoXMgZ3JhbmRlcyB5IG9yaWdpbmFsZXMgcGFyYSBtw6FzIGRlIDgwMDAgc2l0aW9zCi8vIEBkZXNjcmlwdGlvbjpmaSAgICBFdHNpaSBzdXVyZW1waWEgdGFpIGFsa3VwZXLDpGlzacOkIHZlcnNpb2l0YSBrdXZpc3RhIGphIHZpZGVvaXN0YSB5bGkgODAwMCB2ZXJra29zaXZ1c3RvbGxlCi8vIEBkZXNjcmlwdGlvbjpmciAgICBUcm91dmUgZGVzIHZlcnNpb25zIHBsdXMgZ3JhbmRlcyBvdSBvcmlnaW5hbGVzIGQnaW1hZ2VzIGV0IGRlIHZpZMOpb3MgcG91ciBwbHVzIGRlIDggMDAwIHNpdGVzIHdlYiwgeSBjb21wcmlzIHVuZSBwdWlzc2FudGUgZm9uY3Rpb24gZGUgcG9wdXAgbcOpZGlhCi8vIEBkZXNjcmlwdGlvbjpmci1DQSBUcm91dmUgZGVzIHZlcnNpb25zIHBsdXMgZ3JhbmRlcyBvdSBvcmlnaW5hbGVzIGQnaW1hZ2VzIGV0IGRlIHZpZMOpb3MgcG91ciBwbHVzIGRlIDggMDAwIHNpdGVzIHdlYiwgeSBjb21wcmlzIHVuZSBwdWlzc2FudGUgZm9uY3Rpb24gZGUgcG9wdXAgbcOpZGlhCi8vIEBkZXNjcmlwdGlvbjpoZSAgICDXnteV16bXkCDXkteo16HXkNeV16og15LXk9eV15zXldeqINeZ15XXqteoINeQ15Ug157Xp9eV16jXmdeV16og16nXnCDXqtee15XXoNeV16og15XXodeo15jXldeg15nXnSDXoteR15XXqCDXmdeV16rXqCDXni04MDAwINeQ16rXqNeZ150KLy8gQGRlc2NyaXB0aW9uOmhpICAgIDgwMDAg4KS44KWHIOCkheCkp+Ckv+CklSDgpLXgpYfgpKzgpLjgpL7gpIfgpJ/gpYvgpIIg4KSV4KWHIOCksuCkv+CkjyDgpKvgpLzgpYvgpJ/gpYsg4KSU4KSwIOCkteClgOCkoeCkv+Ckr+CliyDgpJXgpYcg4KSs4KSh4KS84KWHIOCkr+CkviDgpK7gpYLgpLIg4KS44KSC4KS44KWN4KSV4KSw4KSjIOCkouClguCkgeCkouCkpOCkviDgpLngpYgKLy8gQGRlc2NyaXB0aW9uOmh1ICAgIFTDtmJiIG1pbnQgODAwMCB3ZWJoZWx5IGvDqXDDqW5layDDqXMgdmlkZcOzaW5hayBuYWd5b2JiIHZhZ3kgZXJlZGV0aSB2w6FsdG96YXTDoXQgdGFsw6FsamEKLy8gQGRlc2NyaXB0aW9uOmlkICAgIE1lbmVtdWthbiB2ZXJzaSBnYW1iYXIgZGFuIHZpZGVvIHlhbmcgbGViaWggYmVzYXIgYXRhdSBvcmlzaW5hbCB1bnR1ayBsZWJpaCBkYXJpIDgwMDAgc2l0dXMgd2ViCi8vIEBkZXNjcmlwdGlvbjppdCAgICBUcm92YSB2ZXJzaW9uaSBwacO5IGdyYW5kaSBvIG9yaWdpbmFsaSBkaSBpbW1hZ2luaSBlIHZpZGVvIHBlciBvbHRyZSA4MDAwIHNpdGkgd2ViCi8vIEBkZXNjcmlwdGlvbjpqYSAgICA4MDAw5Lul5LiK44Gu44Km44Kn44OW44K144Kk44OI44Gn6auY55S76LOq44KE5Y6f5pys55S75YOP44KS6KaL44Gk44GR5Ye644GX44G+44GZCi8vIEBkZXNjcmlwdGlvbjprbyAgICA4MDAw6rCcIOydtOyDgeydmCDsgqzsnbTtirjsl5Ag64yA7ZW0IOqzoO2ZlOyniOydtOuCmCDsm5Drs7gg7J2066+47KeA66W8IOywvuyVhOuTnOumveuLiOuLpAovLyBAZGVzY3JpcHRpb246bmIgICAgRmlubmVyIHN0w7hycmUgZWxsZXIgb3JpZ2luYWxlIHZlcnNqb25lciBhdiBiaWxkZXIgb2cgdmlkZW9lciBmb3IgbWVyIGVubiA4MDAwIG5ldHRzdGVkZXIKLy8gQGRlc2NyaXB0aW9uOm5sICAgIFZpbmR0IGdyb3RlcmUgb2Ygb3JpZ2luZWxlIHZlcnNpZXMgdmFuIGZvdG8ncyBlbiB2aWRlbydzIHZvb3IgbWVlciBkYW4gODAwMCB3ZWJzaXRlcwovLyBAZGVzY3JpcHRpb246cGwgICAgV3lzenVrdWplIHdpxJlrc3plIGx1YiBvcnlnaW5hbG5lIHdlcnNqZSBvYnJhesOzdyBpIGZpbG3Ds3cgZGxhIHBvbmFkIDgwMDAgc3Ryb24gaW50ZXJuZXRvd3ljaAovLyBAZGVzY3JpcHRpb246cHQtQlIgRW5jb250cmEgdmVyc8O1ZXMgbWFpb3JlcyBvdSBvcmlnaW5haXMgZGUgaW1hZ2VucyBlIHbDrWRlb3MgcGFyYSBtYWlzIGRlIDgwMDAgc2l0ZXMKLy8gQGRlc2NyaXB0aW9uOnJ1ICAgINCd0LDRhdC+0LTQuNGCINGD0LLQtdC70LjRh9C10L3QvdGL0LUg0LjQu9C4INC+0YDQuNCz0LjQvdCw0LvRjNC90YvQtSDQstC10YDRgdC40Lgg0LjQt9C+0LHRgNCw0LbQtdC90LjQuSDQtNC70Y8g0LHQvtC70LXQtSDRh9C10LwgODAwMCDQstC10LEt0YHQsNC50YLQvtCyCi8vIEBkZXNjcmlwdGlvbjpiZyAgICDQndCw0LzQuNGA0LAg0YPQstC10LvQuNGH0LXQvdC4INC40LvQuCDQvtGA0LjQs9C40L3QsNC70L3QuCDQstC10YDRgdC40Lgg0L3QsCDQuNC30L7QsdGA0LDQttC10L3QuNGPINC30LAg0L/QvtCy0LXRh9C1INC+0YIgODAwMCDRg9C10LEg0YHQsNC50YLQvtCy0LUKLy8gQGRlc2NyaXB0aW9uOnVrICAgINCX0L3QsNGF0L7QtNC40YLRjCDQt9Cx0ZbQu9GM0YjQtdC90ZYg0LDQsdC+INC+0YDQuNCz0ZbQvdCw0LvRjNC90ZYg0LLQtdGA0YHRltGXINC30L7QsdGA0LDQttC10L3RjCDQtNC70Y8g0LHRltC70YzRiCDQvdGW0LYgODAwMCDQstC10LEt0YHQsNC50YLRltCyCi8vIEBkZXNjcmlwdGlvbjp0aCAgICDguKvguLLguJfguLXguYjguYPguKvguI3guYjguIHguKfguYjguLLguKvguKPguLfguK3guYDguKfguK3guKPguYzguIrguLHguYjguJnguJTguLHguYnguIfguYDguJTguLTguKHguILguK3guIfguKDguLLguJ7guJfguLHguYnguIfguKvguKHguJTguYHguKXguLDguKfguLXguJTguLXguYLguK3guKrguLPguKvguKPguLHguJrguKHguLLguIHguIHguKfguYjguLIgODAwMCDguIfguYDguKfguYfguJrguYTguIvguJXguYwKLy8gQGRlc2NyaXB0aW9uOnRyICAgIDgwMDAnZGVuIGZhemxhIHdlYiBzaXRlc2kgacOnaW4gcmVzaW0gdmUgdmlkZW9sYXLEsW4gZGFoYSBiw7x5w7xrIHZleWEgb3JpamluYWwgc8O8csO8bWxlcmluaSBidWx1cgovLyBAZGVzY3JpcHRpb246dmkgICAgVMOsbSBwaGnDqm4gYuG6o24gbOG7m24gaMahbiBob+G6t2MgcGhpw6puIGLhuqNuIGfhu5FjIGPhu6dhIGjDrG5oIOG6o25oIHbDoCB2aWRlbyBjaG8gaMahbiA4MDAwIHRyYW5nIHdlYgovLyBAZGVzY3JpcHRpb246emggICAg5Li6ODAwMOWkmuS4que9keermeafpeaJvuabtOWkp+aIluWOn+Wni+WbvuWDjwovLyBAZGVzY3JpcHRpb246emgtQ04g5Li6ODAwMOWkmuS4que9keermeafpeaJvuabtOWkp+aIluWOn+Wni+WbvuWDjwovLyBAZGVzY3JpcHRpb246emgtVFcg54K6ODAwMOWkmuWAi+e2suermeafpeaJvuabtOWkp+aIluWOn+Wni+WcluWDjwovLyBAZGVzY3JpcHRpb246emgtSEsg54K6ODAwMOWkmuWAi+e2suermeafpeaJvuabtOWkp+aIluWOn+Wni+WcluWDjwovLyBAbmFtZXNwYWNlICAgICAgICAgaHR0cDovL3RhbXBlcm1vbmtleS5uZXQvCi8vIEB2ZXJzaW9uICAgICAgICAgICAwLjE5LjUKLy8gQGF1dGhvciAgICAgICAgICAgIHFzbml5ZwovLyBAaG9tZXBhZ2VVUkwgICAgICAgaHR0cHM6Ly9xc25peWcuZ2l0aHViLmlvL21heHVybC9vcHRpb25zLmh0bWwKLy8gQHN1cHBvcnRVUkwgICAgICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9xc25peWcvbWF4dXJsL2lzc3VlcwovLyBAaWNvbiAgICAgICAgICAgICAgaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Fzbml5Zy9tYXh1cmwvYjVjNTQ4OGVjMDVlNmUyMzk4ZDRlMGQ2ZTMyZjFiYmFkMTE1ZjZkMi9yZXNvdXJjZXMvbG9nb18yNTYucG5nCi8vIEBpbmNsdWRlICAgICAgICAgICAqCi8vIEBncmFudCAgICAgICAgICAgICBHTS54bWxIdHRwUmVxdWVzdAovLyBAZ3JhbnQgICAgICAgICAgICAgR01feG1saHR0cFJlcXVlc3QKLy8gQGdyYW50ICAgICAgICAgICAgIEdNLnNldFZhbHVlCi8vIEBncmFudCAgICAgICAgICAgICBHTV9zZXRWYWx1ZQovLyBAZ3JhbnQgICAgICAgICAgICAgR00uZ2V0VmFsdWUKLy8gQGdyYW50ICAgICAgICAgICAgIEdNX2dldFZhbHVlCi8vIEBncmFudCAgICAgICAgICAgICBHTV9yZWdpc3Rlck1lbnVDb21tYW5kCi8vIEBncmFudCAgICAgICAgICAgICBHTV91bnJlZ2lzdGVyTWVudUNvbW1hbmQKLy8gQGdyYW50ICAgICAgICAgICAgIEdNX2FkZFZhbHVlQ2hhbmdlTGlzdGVuZXIKLy8gQGdyYW50ICAgICAgICAgICAgIEdNX2Rvd25sb2FkCi8vIEBncmFudCAgICAgICAgICAgICBHTV9vcGVuSW5UYWIKLy8gQGdyYW50ICAgICAgICAgICAgIEdNLm9wZW5JblRhYgovLyBAZ3JhbnQgICAgICAgICAgICAgR01fbm90aWZpY2F0aW9uCi8vIEBncmFudCAgICAgICAgICAgICBHTS5ub3RpZmljYXRpb24KLy8gQGdyYW50ICAgICAgICAgICAgIEdNX3NldENsaXBib2FyZAovLyBAZ3JhbnQgICAgICAgICAgICAgR00uc2V0Q2xpcGJvYXJkCi8vIEBjb25uZWN0ICAgICAgICAgICAqCi8vIGFwaS5naXRodWIuY29tIGlzIHVzZWQgZm9yIGNoZWNraW5nIGZvciB1cGRhdGVzIChjYW4gYmUgZGlzYWJsZWQgdGhyb3VnaCB0aGUgIkNoZWNrIFVwZGF0ZXMiIHNldHRpbmcpCi8vIEBjb25uZWN0ICAgICAgICAgICBhcGkuZ2l0aHViLmNvbQovLyBAcnVuLWF0ICAgICAgICAgICAgZG9jdW1lbnQtc3RhcnQKLy8gQGxpY2Vuc2UgICAgICAgICAgIEFwYWNoZS0yLjAKLy8gbm9uLWdyZWFzeWZvcmsvb3VqcyB2ZXJzaW9ucyBuZWVkIHVwZGF0ZVVSTCBhbmQgZG93bmxvYWRVUkwgdG8gYXV0by11cGRhdGUgZm9yIGNlcnRhaW4gdXNlcnNjcmlwdCBtYW5hZ2VycwovLwovLyAgR3JlYXN5Zm9yayBhbmQgT3BlblVzZXJKUyBoYXZlIDJNQiBhbmQgMU1CIGxpbWl0cyBmb3IgdXNlcnNjcmlwdHMgKHJlc3BlY3RpdmVseSkuCi8vICBCZWNhdXNlIG9mIHRoaXMsIHRoZSBydWxlcyAofjEuNE1CKSBoYXZlIGJlZW4gc3BsaXQgaW50byBhIHNlcGFyYXRlIGZpbGUsIGxpbmtlZCBiZWxvdy4KLy8gIE5vdGUgdGhhdCBqc2RlbGl2ci5uZXQgbWlnaHQgbm90IGFsd2F5cyBiZSByZWxpYWJsZSwgYnV0IChBRkFJSykgdGhpcyBpcyB0aGUgb25seSByZWFzb25hYmxlIG9wdGlvbiBmcm9tIHdoYXQgZ3JlYXN5Zm9yayBhbGxvd3MuCi8vICBJJ2QgcmVjb21tZW5kIHVzaW5nIHRoZSBHaXRodWIgdmVyc2lvbiBvZiB0aGUgc2NyaXB0IGlmIHlvdSBlbmNvdW50ZXIgYW55IGlzc3VlcyAobGlua2VkIGluIHRoZSAnUHJvamVjdCBsaW5rcycgc2VjdGlvbiBiZWxvdykuCi8vCi8vIEByZXF1aXJlIGh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9naC9xc25peWcvbWF4dXJsQDk3OGM0MWUxZDNmOWZhMzk2MDgwNGI3ZGRjMzNlZDRjNmZmZmI0Y2EvYnVpbGQvcnVsZXMuanMKLy8gPT0vVXNlclNjcmlwdD09CgovLyBJZiB5b3Ugc2VlICJBIHVzZXJzY3JpcHQgd2FudHMgdG8gYWNjZXNzIGEgY3Jvc3Mtb3JpZ2luIHJlc291cmNlLiIsIGl0J3MgdXNlZCBmb3I6Ci8vICAgKiBEZXRlY3Rpbmcgd2hldGhlciBvciBub3QgdGhlIGRlc3RpbmF0aW9uIFVSTCBleGlzdHMgYmVmb3JlIHJlZGlyZWN0aW5nCi8vICAgKiBBUEkgY2FsbHMgZm9yIHZhcmlvdXMgd2Vic2l0ZXMgdG8gZmluZCB0aGUgbGFyZ2VyIGltYWdlIChlLmcuIGZvciBGbGlja3IpCi8vICAgICAqIFlvdSBjYW4gY29udHJvbCB0aGlzIHdpdGggdGhlICJSdWxlcyB1c2luZyBBUEkgY2FsbHMiIHNldHRpbmcKLy8gICAqIERvd25sb2FkaW5nIHRoZSBpbWFnZSBmb3IgdGhlIHBvcHVwCi8vICAgKiBRdWVyeWluZyBhIHRoaXJkLXBhcnR5IGxpYnJhcnkKLy8gICAgICogWW91IGNhbiBjb250cm9sIHRoaXMgd2l0aCB0aGUgIkFsbG93IDNyZC1wYXJ0eSBsaWJyYXJpZXMiIHNldHRpbmcuCi8vICAgICAgIDNyZC1wYXJ0eSBsaWJyYXJpZXMgYXJlIGRpc2FibGVkIGJ5IGRlZmF1bHQgZm9yIHNlY3VyaXR5IHJlYXNvbnMuCi8vIFNlYXJjaCBmb3IgZG9fcmVxdWVzdCwgYXBpX3F1ZXJ5LCBhbmQgd2Vic2l0ZV9xdWVyeSBpZiB5b3Ugd2FudCB0byBzZWUgd2hhdCB0aGUgY29kZSBkb2VzIGV4YWN0bHkuCi8vCi8vIFBsZWFzZSBjb250YWN0IG1lIGlmIHlvdSBoYXZlIGFueSBxdWVzdGlvbnMgb3IgY29uY2VybnMgcmVnYXJkaW5nIHRoZSBzY3JpcHQuCi8vCi8vIFByb2plY3QgbGlua3M6Ci8vCi8vICAgKiBHaXRodWI6ICAgICAgICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9xc25peWcvbWF4dXJsCi8vICAgKiBEaXNjb3JkOiAgICAgICAgIGh0dHBzOi8vZGlzY29yZC5nZy9mSDlQZjU0Ci8vICAgKiBSZWRkaXQ6ICAgICAgICAgIGh0dHBzOi8vd3d3LnJlZGRpdC5jb20vci9NYXhJbWFnZS8KLy8gICAqIFdlYnNpdGU6ICAgICAgICAgaHR0cHM6Ly9xc25peWcuZ2l0aHViLmlvL21heHVybC8KLy8gICAqIEd1aWRlOiAgICAgICAgICAgaHR0cHM6Ly9xc25peWcuZ2l0aHViLmlvL21heHVybC9ndWlkZS5odG1sCi8vICAgKiBVc2Vyc2NyaXB0OgovLyAgICAgKiBHcmVhc3lmb3JrOiAgICBodHRwczovL2dyZWFzeWZvcmsub3JnL3NjcmlwdHMvMzY2NjItaW1hZ2UtbWF4LXVybAovLyAgICAgKiBPcGVuVXNlckpTOiAgICBodHRwczovL29wZW51c2VyanMub3JnL3NjcmlwdHMvcXNuaXlnL0ltYWdlX01heF9VUkwKLy8gICAgICogR2l0aHViOiAgICAgICAgaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Fzbml5Zy9tYXh1cmwvbWFzdGVyL3VzZXJzY3JpcHRfc21hbGxlci51c2VyLmpzCi8vICAgICAqIEdpdGh1YiAoYmV0YSk6IGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9xc25peWcvbWF4dXJsL21hc3Rlci91c2Vyc2NyaXB0LnVzZXIuanMKLy8gICAqIEZpcmVmb3ggYWRkb246ICAgaHR0cHM6Ly9hZGRvbnMubW96aWxsYS5vcmcvZmlyZWZveC9hZGRvbi9pbWFnZS1tYXgtdXJsLwovLyAgICogT3BlcmEgZXh0ZW5zaW9uOiBodHRwczovL2FkZG9ucy5vcGVyYS5jb20vZW4vZXh0ZW5zaW9ucy9kZXRhaWxzL2ltYWdlLW1heC11cmwvCgoKCgp2YXIgJCRJTVVfRVhQT1JUJCQ7CgovLyBEaXNhYmxlIGxpbnRpbmcgYmVjYXVzZSBvdGhlcndpc2UgZWRpdGluZyBpcyBpbmNyZWRpYmx5IHNsb3cKLy8ganNoaW50IGlnbm9yZTogc3RhcnQKKGZ1bmN0aW9uKCkgewoJLy8gRG9uJ3QgJ3VzZSBzdHJpY3QnLCBhcyBpdCBwcmV2ZW50cyBuZXN0ZWQgZnVuY3Rpb25zCgkvLyd1c2Ugc3RyaWN0JzsKCgl2YXIgX25pcl9kZWJ1Z18gPSBmYWxzZTsKCglpZiAoX25pcl9kZWJ1Z18pIHsKCQlfbmlyX2RlYnVnXyA9IHsKCQkJbm9fcmVxdWVzdDogZmFsc2UsCgkJCW5vX3JlY3Vyc2U6IGZhbHNlLAoJCQlub19yZWRpcmVjdDogdHJ1ZSwKCgkJCS8vIGNoYW5uZWxzCgkJCW1hcDogdHJ1ZSwKCQkJY2FjaGU6IHRydWUsCgkJCWJpZ2ltYWdlX3JlY3Vyc2l2ZTogdHJ1ZSwKCQkJaW5wdXQ6IHRydWUsCgkJCWNoZWNrX2ltYWdlX2dldDogdHJ1ZSwKCQkJZmluZF9zb3VyY2U6IHRydWUKCQl9OwoKCQljb25zb2xlLmxvZygiTG9hZGVkIik7Cgl9CgoJdmFyIG51bGxmdW5jID0gZnVuY3Rpb24oKXt9OwoKCXZhciBpc19leHRlbnNpb24gPSBmYWxzZTsKCXZhciBpc193ZWJleHRlbnNpb24gPSBmYWxzZTsKCXZhciBpc19leHRlbnNpb25fYmcgPSBmYWxzZTsKCXZhciBpc19maXJlZm94X3dlYmV4dGVuc2lvbiA9IGZhbHNlOwoJdmFyIGV4dGVuc2lvbl9zZW5kX21lc3NhZ2UgPSBudWxsOwoJdmFyIGV4dGVuc2lvbl9lcnJvcl9oYW5kbGVyID0gZnVuY3Rpb24oKXt9OwoJdmFyIGV4dGVuc2lvbl9vcHRpb25zX3BhZ2UgPSBudWxsOwoJdmFyIGlzX3Rlcm1pbmF0ZWQgPSBmYWxzZTsKCXZhciBpc19leHRlbnNpb25fb3B0aW9uc19wYWdlID0gZmFsc2U7Cgl2YXIgaXNfb3B0aW9uc19wYWdlID0gZmFsc2U7Cgl2YXIgaXNfbWF4dXJsX3dlYnNpdGUgPSBmYWxzZTsKCXZhciB3aW5kb3dfbG9jYXRpb24gPSBudWxsOwoJdmFyIG9wdGlvbnNfcGFnZSA9ICJodHRwczovL3Fzbml5Zy5naXRodWIuaW8vbWF4dXJsL29wdGlvbnMuaHRtbCI7CgkvLyB0b2RvOiB1cGRhdGUKCXZhciBhcmNoaXZlX29wdGlvbnNfcGFnZSA9ICJodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAyMTAzMjgwNjM5NDAvaHR0cHM6Ly9xc25peWcuZ2l0aHViLmlvL21heHVybC9vcHRpb25zLmh0bWwiOwoJdmFyIHByZWZlcnJlZF9vcHRpb25zX3BhZ2UgPSBvcHRpb25zX3BhZ2U7Cgl2YXIgZmlyZWZveF9hZGRvbl9wYWdlID0gImh0dHBzOi8vYWRkb25zLm1vemlsbGEub3JnL2VuLVVTL2ZpcmVmb3gvYWRkb24vaW1hZ2UtbWF4LXVybC8iOwoJdmFyIHVzZXJzY3JpcHRfdXBkYXRlX3VybCA9ICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcXNuaXlnL21heHVybC9tYXN0ZXIvdXNlcnNjcmlwdF9zbWFsbGVyLnVzZXIuanMiOwoJdmFyIGdyZWFzeWZvcmtfdXBkYXRlX3VybCA9IHVzZXJzY3JpcHRfdXBkYXRlX3VybDsKCS8vdmFyIGdyZWFzeWZvcmtfdXBkYXRlX3VybCA9ICJodHRwczovL2dyZWFzeWZvcmsub3JnL3NjcmlwdHMvMzY2NjItaW1hZ2UtbWF4LXVybC9jb2RlL0ltYWdlJTIwTWF4JTIwVVJMLnVzZXIuanMiOwoJdmFyIGdpdGh1Yl9pc3N1ZXNfcGFnZSA9ICJodHRwczovL2dpdGh1Yi5jb20vcXNuaXlnL21heHVybC9pc3N1ZXMiOwoJdmFyIGltdV9pY29uID0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9xc25peWcvbWF4dXJsL2I1YzU0ODhlYzA1ZTZlMjM5OGQ0ZTBkNmUzMmYxYmJhZDExNWY2ZDIvcmVzb3VyY2VzL2xvZ29fMjU2LnBuZyI7Cgl2YXIgY3VycmVudF92ZXJzaW9uID0gbnVsbDsKCXZhciBpbWFnZXRhYl9va19vdmVycmlkZSA9IGZhbHNlOwoJdmFyIGhhc19mZm1wZWdfbGliID0gdHJ1ZTsKCgkvLyAtLSBDdXJyZW50bHkgdGhpcyBpcyB1bnVzZWQsIGl0J2xsIGJlIHVzZWQgaW4gYSBmdXR1cmUgcmVsZWFzZSAodG8gd29ya2Fyb3VuZCB0aGUgMU1CIGFuZCAyTUIgbGltaXRzIGZvciBPVUpTIGFuZCBHcmVhc3lmb3JrIHJlc3BlY3RpdmVseSkgLS0KCS8vIFRoaXMgaXMgb25seSBzZXQgZm9yIHRoZSBHcmVhc3lmb3JrL09VSlMgdmVyc2lvbnMgaWYgaXQgZmFpbHMgdG8gQHJlcXVpcmUgdGhlIHJ1bGVzIChjb250ZW50cyBvZiBiaWdpbWFnZSkuCgkvLyBUaGUgbGlrZWx5IGNhdXNlcyB3b3VsZCBiZSBlaXRoZXIgYSBDRE4gZmFpbHVyZSwgb3IgdGhhdCB0aGUgdXNlcnNjcmlwdCBtYW5hZ2VyIGRvZXNuJ3Qgc3VwcG9ydCBAcmVxdWlyZS4KCXZhciByZXF1aXJlX3J1bGVzX2ZhaWxlZCA9IGZhbHNlOwoKCXZhciBnZXRfcmF3X3dpbmRvdyA9IGZ1bmN0aW9uKCkgewoJCWlmICh0eXBlb2YodW5zYWZlV2luZG93KSAhPT0gInVuZGVmaW5lZCIpCgkJCXJldHVybiB1bnNhZmVXaW5kb3cgfHwgdGhpcy53aW5kb3cgfHwgd2luZG93OwoKCQlyZXR1cm4gdGhpcy53aW5kb3cgfHwgd2luZG93OwoJfTsKCgl2YXIgZ2V0X3dpbmRvdyA9IGZ1bmN0aW9uKCkgewoJCXZhciByYXdfd2luZG93ID0gZ2V0X3Jhd193aW5kb3coKTsKCQkvLyBodHRwczovL2dpdGh1Yi5jb20vcXNuaXlnL21heHVybC9pc3N1ZXMvNjc4I2lzc3VlY29tbWVudC03OTE4NTUxNzYKCQkvLyB1c2Vyc2NyaXB0IHVuZGVyIGZpcmVmb3ggdmlvbGVudG1vbmtleSB1bmRlciB0d2l0dGVyJ3MgdW5zYWZlV2luZG93IHJldHVybnMgU2FuZGJveCwgd2hpY2ggaXNuJ3QgYW4gRXZlbnRUYXJnZXQgKGJyZWFrcyAibWVzc2FnZSIgaGFuZGxlcikKCQkvLyAuc2VsZiByZXR1cm5zIHRoZSBhY3R1YWwgd2luZG93LCB3aGljaCBpcyBhbiBFdmVudFRhcmdldAoJCWlmIChyYXdfd2luZG93LnNlbGYpCgkJCXJldHVybiByYXdfd2luZG93LnNlbGY7CgkJZWxzZQoJCQlyZXR1cm4gcmF3X3dpbmRvdzsKCX07CgoJdmFyIHRlcm1pbmF0aW9uX2hvb2tzID0gW107Cgl2YXIgaXNfc3VzcGVuZGVkID0gZnVuY3Rpb24oZnVsbCkgewoJCWlmIChpc190ZXJtaW5hdGVkIHx8ICFzZXR0aW5ncy5pbXVfZW5hYmxlZCkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCWlmIChmdWxsICYmIGlzX2V4dGVuc2lvbikgewoJCQl0cnkgewoJCQkJY2hyb21lLnJ1bnRpbWUuZ2V0VVJMKCJtYW5pZmVzdC5qc29uIik7CgkJCX0gY2F0Y2ggKGUpIHsKCQkJCXNldF90ZXJtaW5hdGVkKHRydWUpOwoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgoJCXJldHVybiBmYWxzZTsKCX07CgoJdmFyIHNldF90ZXJtaW5hdGVkID0gZnVuY3Rpb24odGVybWluYXRlZCkgewoJCXZhciB3YXNfdGVybWluYXRlZCA9IGlzX3Rlcm1pbmF0ZWQ7CgkJaXNfdGVybWluYXRlZCA9IHRlcm1pbmF0ZWQ7CgoJCWlmICh0ZXJtaW5hdGVkICYmICF3YXNfdGVybWluYXRlZCkgewoJCQlhcnJheV9mb3JlYWNoKHRlcm1pbmF0aW9uX2hvb2tzLCBmdW5jdGlvbihob29rKSB7CgkJCQlob29rKCk7CgkJCX0pOwoJCX0KCX07CgoJdHJ5IHsKCQl3aW5kb3dfbG9jYXRpb24gPSB3aW5kb3cubG9jYXRpb24uaHJlZjsKCgkJKGZ1bmN0aW9uKCkgewoJCQl2YXIgb3VyX3VybCA9IHdpbmRvd19sb2NhdGlvbi5yZXBsYWNlKC9eW2Etel0rOlwvXC93ZWJcLmFyY2hpdmVcLm9yZ1wvK3dlYlwvK1swLTldK1wvKyhodHRwcz86XC9cLykvLCAiJDEiKTsKCgkJCWlmICgvXmh0dHBzPzpcL1wvcXNuaXlnXC5naXRodWJcLmlvXC8rbWF4dXJsXC8rb3B0aW9uc1wuaHRtbC8udGVzdChvdXJfdXJsKSB8fAoJCQkJL15maWxlOlwvXC8uKlwvbWF4dXJsXC9zaXRlXC9vcHRpb25zXC5odG1sLy50ZXN0KHdpbmRvd19sb2NhdGlvbikpIHsKCQkJCWlzX29wdGlvbnNfcGFnZSA9IHRydWU7CgkJCQlpc19tYXh1cmxfd2Vic2l0ZSA9IHRydWU7CgkJCX0gZWxzZSBpZiAoL15odHRwcz86XC9cL3Fzbml5Z1wuZ2l0aHViXC5pb1wvK21heHVybFwvKy8udGVzdChvdXJfdXJsKSB8fAoJCQkJL15maWxlOlwvXC8uKlwvbWF4dXJsXC9zaXRlXC8oPzppbmRleHxhYm91dHxvcHRpb25zKVwuaHRtbC8udGVzdCh3aW5kb3dfbG9jYXRpb24pKSB7CgkJCQlpc19tYXh1cmxfd2Vic2l0ZSA9IHRydWU7CgkJCX0KCQl9KSgpOwoJfSBjYXRjaChlKSB7Cgl9CgoJdmFyIGNoZWNrX2lmX2V4dGVuc2lvbiA9IGZ1bmN0aW9uKCkgewoJCS8vIGluIHNlbmR2aWQuY29tLCBjaHJvbWUgaXMgbnVsbCwgd2hpY2ggdHlwZW9mID09PSAib2JqZWN0IgoJCWlmICh0eXBlb2YgY2hyb21lICE9PSAib2JqZWN0IiB8fCAhY2hyb21lIHx8IHR5cGVvZiBjaHJvbWUucnVudGltZSAhPT0gIm9iamVjdCIpCgkJCXJldHVybjsKCgkJdHJ5IHsKCQkJdmFyIGV4dGVuc2lvbl9tYW5pZmVzdCA9IGNocm9tZS5ydW50aW1lLmdldE1hbmlmZXN0KCk7CgkJCWlzX2V4dGVuc2lvbiA9IGV4dGVuc2lvbl9tYW5pZmVzdC5uYW1lID09PSAiSW1hZ2UgTWF4IFVSTCI7CgoJCQlpZiAoIWlzX2V4dGVuc2lvbikKCQkJCXJldHVybjsKCgkJCWV4dGVuc2lvbl9lcnJvcl9oYW5kbGVyID0gZnVuY3Rpb24oY29udGV4dCkgewoJCQkJdHJ5IHsKCQkJCQl2YXIgbGFzdF9lcnJvciA9IGNocm9tZS5ydW50aW1lLmxhc3RFcnJvcjsKCQkJCQlpZiAobGFzdF9lcnJvcikgewoJCQkJCQljb25zb2xlLmVycm9yKGxhc3RfZXJyb3IubWVzc2FnZSwgY29udGV4dCk7CgkJCQkJfQoJCQkJfSBjYXRjaCAoZSkgewoJCQkJCWNvbnNvbGUuZXJyb3IoZSk7CgkJCQl9CgkJCX07CgoJCQlpc19leHRlbnNpb25fYmcgPSAvXihbLWEtel0rKWV4dGVuc2lvbjpcL1wvW14vXStcLytfZ2VuZXJhdGVkX2JhY2tncm91bmRfcGFnZVwuaHRtbC8udGVzdCh3aW5kb3dfbG9jYXRpb24pOwoKCQkJZXh0ZW5zaW9uX29wdGlvbnNfcGFnZSA9IGNocm9tZS5ydW50aW1lLmdldFVSTCgiZXh0ZW5zaW9uL29wdGlvbnMuaHRtbCIpOwoJCQlpc19leHRlbnNpb25fb3B0aW9uc19wYWdlID0gd2luZG93X2xvY2F0aW9uLnJlcGxhY2UoL1s/I10uKiQvLCAiIikgPT09IGV4dGVuc2lvbl9vcHRpb25zX3BhZ2U7CgkJCWlzX29wdGlvbnNfcGFnZSA9IGlzX29wdGlvbnNfcGFnZSB8fCBpc19leHRlbnNpb25fb3B0aW9uc19wYWdlOwoJCQkvL29wdGlvbnNfcGFnZSA9IGV4dGVuc2lvbl9vcHRpb25zX3BhZ2U7IC8vIGNhbid0IGxvYWQgZnJvbSB3ZWJzaXRlCgkJCXByZWZlcnJlZF9vcHRpb25zX3BhZ2UgPSBleHRlbnNpb25fb3B0aW9uc19wYWdlOwoKCQkJaXNfd2ViZXh0ZW5zaW9uID0gdHJ1ZTsKCQkJaWYgKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiRmlyZWZveCIpID49IDApCgkJCQlpc19maXJlZm94X3dlYmV4dGVuc2lvbiA9IHRydWU7CgoJCQljdXJyZW50X3ZlcnNpb24gPSBleHRlbnNpb25fbWFuaWZlc3QudmVyc2lvbjsKCgkJCWV4dGVuc2lvbl9zZW5kX21lc3NhZ2UgPSBmdW5jdGlvbihtZXNzYWdlLCByZXNwb25kKSB7CgkJCQltZXNzYWdlID0gZGVlcGNvcHkobWVzc2FnZSwge2pzb246dHJ1ZX0pOwoJCQkJaWYgKCFyZXNwb25kKQoJCQkJCXJlc3BvbmQgPSBudWxsZnVuYzsKCgkJCQlpZiAoaXNfZXh0ZW5zaW9uX2JnKSB7CgkJCQkJcmV0dXJuIHVzZXJzY3JpcHRfZXh0ZW5zaW9uX21lc3NhZ2VfaGFuZGxlcihtZXNzYWdlLCByZXNwb25kKTsKCQkJCX0gZWxzZSB7CgkJCQkJaWYgKCFyZXNwb25kIHx8IHJlc3BvbmQgPT09IG51bGxmdW5jKSB7CgkJCQkJCXJldHVybiBjaHJvbWUucnVudGltZS5zZW5kTWVzc2FnZShudWxsLCBtZXNzYWdlKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlyZXR1cm4gY2hyb21lLnJ1bnRpbWUuc2VuZE1lc3NhZ2UobnVsbCwgbWVzc2FnZSwgbnVsbCwgZnVuY3Rpb24oKSB7CgkJCQkJCQlleHRlbnNpb25fZXJyb3JfaGFuZGxlcihtZXNzYWdlKTsKCQkJCQkJCXJldHVybiByZXNwb25kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CgkJCQkJCX0pOwoJCQkJCX0KCQkJCX0KCQkJfTsKCgkJCWlmICghaXNfZXh0ZW5zaW9uX2JnKSB7CgkJCQkvLyBmaXJlZm94IGRvZXNuJ3QgbG9hZCB0aGUgcnVudGltZSBsaXN0ZW5lciBpbW1lZGlhdGVseQoJCQkJc2V0VGltZW91dChmdW5jdGlvbigpIHsKCQkJCQl2YXIgcnVudGltZV9wb3J0ID0gY2hyb21lLnJ1bnRpbWUuY29ubmVjdCgpOwoJCQkJCXJ1bnRpbWVfcG9ydC5vbkRpc2Nvbm5lY3QuYWRkTGlzdGVuZXIoZnVuY3Rpb24oZSkgewoJCQkJCQljb25zb2xlLmVycm9yKGUpOwoJCQkJCQlleHRlbnNpb25fZXJyb3JfaGFuZGxlcigpOwoJCQkJCQlzZXRfdGVybWluYXRlZCh0cnVlKTsKCQkJCQl9KTsKCQkJCX0sIDEwKTsKCQkJfQoKCQkJZXh0ZW5zaW9uX2Vycm9yX2hhbmRsZXIoKTsKCQl9IGNhdGNoIChlKSB7CgkJCWlmIChpc19leHRlbnNpb24pIHsKCQkJCWNvbnNvbGUuZXJyb3IoZSk7CgkJCQlleHRlbnNpb25fZXJyb3JfaGFuZGxlcigpOwoJCQl9CgkJfTsKCX07CgoJY2hlY2tfaWZfZXh0ZW5zaW9uKCk7CgoJdmFyIGlzX25vZGUgPSBmYWxzZTsKCWlmICgodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpICYmCgkJdHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykgewoJCWlzX25vZGUgPSB0cnVlOwoJfQoKCXZhciBpc19zY3JpcHR0YWcgPSBmYWxzZTsKCWlmICh0eXBlb2YgaW11X3ZhcmlhYmxlICE9PSAndW5kZWZpbmVkJyAmJiAodHlwZW9mKEdNX3htbGh0dHBSZXF1ZXN0KSA9PT0gJ3VuZGVmaW5lZCcgJiYKCQkJCQkJCQkJCQkJdHlwZW9mKEdNKSA9PT0gJ3VuZGVmaW5lZCcpKQoJCWlzX3NjcmlwdHRhZyA9IHRydWU7CgoJdmFyIGlzX3VzZXJzY3JpcHQgPSBmYWxzZTsKCWlmICghaXNfbm9kZSAmJiAhaXNfc2NyaXB0dGFnICYmICFpc19leHRlbnNpb24pCgkJaXNfdXNlcnNjcmlwdCA9IHRydWU7CgoJLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzMyNjA3NgoJdmFyIGNoZWNrX2luX2lmcmFtZSA9IGZ1bmN0aW9uKCkgewoJCXRyeSB7CgkJCXJldHVybiB3aW5kb3cuc2VsZiAhPT0gd2luZG93LnRvcDsKCQl9IGNhdGNoIChlKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCX07Cgl2YXIgaXNfaW5faWZyYW1lID0gY2hlY2tfaW5faWZyYW1lKCk7Cgl2YXIgaXNfcmVtb3RlX3Bvc3NpYmxlID0gZmFsc2U7CgoJdmFyIGlzX2ludGVyYWN0aXZlID0gKGlzX2V4dGVuc2lvbiB8fCBpc191c2Vyc2NyaXB0KSAmJiAhaXNfZXh0ZW5zaW9uX2JnOwoKCXZhciB1c2Vyc2NyaXB0X21hbmFnZXIgPSAidW5rbm93biI7Cgl2YXIgdXNlcnNjcmlwdF9tYW5hZ2VyX3ZlcnNpb24gPSAiIjsKCWlmIChpc191c2Vyc2NyaXB0KSB7CgkJdmFyIGdtX2luZm8gPSB2b2lkIDA7CgoJCWlmICh0eXBlb2YgR01faW5mbyA9PT0gImZ1bmN0aW9uIikgewoJCQlnbV9pbmZvID0gR01faW5mbygpOwoJCX0gZWxzZSBpZiAodHlwZW9mIEdNX2luZm8gPT09ICJvYmplY3QiKSB7CgkJCWdtX2luZm8gPSBHTV9pbmZvOwoJCX0KCgkJaWYgKHR5cGVvZiBnbV9pbmZvID09PSAib2JqZWN0IikgewoJCQlpZiAoZ21faW5mby5zY3JpcHRIYW5kbGVyKSB7CgkJCQl1c2Vyc2NyaXB0X21hbmFnZXIgPSBnbV9pbmZvLnNjcmlwdEhhbmRsZXI7CgkJCX0KCgkJCWlmIChnbV9pbmZvLnZlcnNpb24pIHsKCQkJCXVzZXJzY3JpcHRfbWFuYWdlcl92ZXJzaW9uID0gZ21faW5mby52ZXJzaW9uOwoJCQl9CgkJfSBlbHNlIGlmICh0eXBlb2YgR01fZmV0Y2ggPT09ICdmdW5jdGlvbicgJiYgZ21faW5mbyA9PT0gbnVsbCkgewoJCQkvLyBVbmZvcnR1bmF0ZWx5IEZpcmVNb25rZXkgY3VycmVudGx5IGRvZXNuJ3QgaW1wbGVtZW50IEdNX2luZm8ncyBzY3JpcHRIYW5kbGVyOgoJCQkvLyAgIGh0dHBzOi8vZ2l0aHViLmNvbS9lcm9zbWFuL3N1cHBvcnQvaXNzdWVzLzk4I2lzc3VlY29tbWVudC01MzQ2NzEyMjkKCQkJLy8gV2UgY3VycmVudGx5IGhhdmUgdG8gcmVseSBvbiB0aGlzIGhhY2sKCQkJdXNlcnNjcmlwdF9tYW5hZ2VyID0gIkZpcmVNb25rZXkiOwoJCQlnbV9pbmZvID0ge3NjcmlwdEhhbmRsZXI6IHVzZXJzY3JpcHRfbWFuYWdlcn07CgkJfQoKCQlpZiAoX25pcl9kZWJ1Z18gJiYgZmFsc2UpIHsKCQkJY29uc29sZS5sb2coIkdNX2luZm8iLCBnbV9pbmZvKTsKCQl9CgoJCXRyeSB7CgkJCWN1cnJlbnRfdmVyc2lvbiA9IGdtX2luZm8uc2NyaXB0LnZlcnNpb247CgkJfSBjYXRjaCAoZSkgewoJCQljdXJyZW50X3ZlcnNpb24gPSBudWxsOwoJCX07Cgl9CgoJLy8gcmVzdG9yZSBjb25zb2xlLmxvZyBmb3Igd2Vic2l0ZXMgdGhhdCByZW1vdmUgaXQgKHR3aXR0ZXIpCgkvLyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9JdmFuY2EvNDU4NjA3MQoJLy92YXIgY29uc29sZV9sb2cgPSBmdW5jdGlvbigpeyByZXR1cm4gd2luZG93LmNvbnNvbGUuX19wcm90b19fLmxvZy5hcHBseShjb25zb2xlLCBhcmd1bWVudHMpIH0gOwoJLy92YXIgY29uc29sZV9lcnJvciA9IGZ1bmN0aW9uKCl7IHJldHVybiB3aW5kb3cuY29uc29sZS5fX3Byb3RvX18uZXJyb3IuYXBwbHkoY29uc29sZSwgYXJndW1lbnRzKSB9IDsKCgkvLyBzaW5jZSB0aGUgdXNlcnNjcmlwdCBpcyBydW4gZmlyc3QsIHRoaXMgZ2VuZXJhbGx5IHNob3VsZG4ndCBiZSBhIHByb2JsZW0KCXZhciBjb25zb2xlX2xvZyA9IGNvbnNvbGUubG9nOwoJdmFyIGNvbnNvbGVfZXJyb3IgPSBjb25zb2xlLmVycm9yOwoJdmFyIGNvbnNvbGVfd2FybiA9IGNvbnNvbGUud2FybjsKCXZhciBjb25zb2xlX3RyYWNlID0gY29uc29sZS50cmFjZTsKCgl2YXIgbmlyX2RlYnVnID0gZnVuY3Rpb24oKSB7fTsKCWlmIChfbmlyX2RlYnVnXykgewoJCW5pcl9kZWJ1ZyA9IGZ1bmN0aW9uKCkgewoJCQl2YXIgY2hhbm5lbCA9IGFyZ3VtZW50c1swXTsKCQkJaWYgKCFfbmlyX2RlYnVnX1tjaGFubmVsXSkKCQkJCXJldHVybjsKCgkJCXZhciBhcmdzID0gW107CgkJCWZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CgkJCQlhcmdzLnB1c2goYXJndW1lbnRzW2ldKTsKCQkJfQoKCQkJY29uc29sZV9sb2cuYXBwbHkodGhpcywgYXJncyk7CgkJfTsKCX0KCgl2YXIgSlNPTl9zdHJpbmdpZnk7Cgl2YXIgSlNPTl9wYXJzZSA9IEpTT04ucGFyc2U7CgoJLy8gcGFyc2VJbnQgb2NjYXNpb25hbGx5IGNyYXNoZXMgZm9yIHRhZ2Vzc3BpZWdlbC5kZSB3aXRoIGJyYXZlIHNoaWVsZHMgYW5kIHZpb2xlbnRtb25rZXkgMi4xMy4wCgkvLyBzZWVtcyB0byBiZSBhIHJhY2UsIGFzIGl0IHNvbWV0aW1lcyB3b3JrcywgYW5kIGl0IGFsd2F5cyB3b3JrcyBpbiB0aGUgY29uc29sZQoJdmFyIHBhcnNlX2ludCA9IGZ1bmN0aW9uKHgpIHsKCQlyZXR1cm4geHwwOwoJfTsKCgl2YXIgYmFzZTY0X2RlY29kZSwgYmFzZTY0X2VuY29kZSwKCQlpc19hcnJheSwgYXJyYXlfaW5kZXhvZiwgc3RyaW5nX2luZGV4b2YsCgkJLy8gaHR0cHM6Ly93d3cuYmluZy5jb20vIG92ZXJyaWRlcyBCbG9iCgkJLy8gaHR0cHM6Ly93d3cuZHByZXZpZXcuY29tLyBvdmVycmlkZXMgVVJMCgkJbmF0aXZlX2Jsb2IsIG5hdGl2ZV9VUkwsCgkJbmV3X2Jsb2IsCgkJb3VyX0V2ZW50VGFyZ2V0LCBvdXJfYWRkRXZlbnRMaXN0ZW5lciwgb3VyX3JlbW92ZUV2ZW50TGlzdGVuZXIsCgkJc3RyaW5nX2Zyb21jaGFyY29kZSwgc3RyaW5nX2NoYXJhdCwKCQlhcnJheV9yZWR1Y2UsIGFycmF5X3JlZHVjZV9wcm90b3R5cGUsCgkJZG9jdW1lbnRfY3JlYXRlRWxlbWVudDsKCglpZiAoaXNfbm9kZSkgewoJCWJhc2U2NF9kZWNvZGUgPSBmdW5jdGlvbihhKSB7CgkJCXJldHVybiBCdWZmZXIuZnJvbShhLCAnYmFzZTY0JykudG9TdHJpbmcoJ2JpbmFyeScpOwoJCX07CgoJCWJhc2U2NF9lbmNvZGUgPSBmdW5jdGlvbihhKSB7CgkJCXJldHVybiBCdWZmZXIuZnJvbShhKS50b1N0cmluZygnYmFzZTY0Jyk7CgkJfTsKCX0KCgl2YXIgZ2V0X2NvbXBhdF9mdW5jdGlvbnMgPSBmdW5jdGlvbigpIHsKCQl2YXIgbmF0aXZlX2Z1bmN0aW9uc190b19nZXQgPSBbXTsKCgkJLy8gdWJsb2NrIHByZXZlbnRzIEpTT04uc3RyaW5naWZ5IGZyb20gYmVpbmcgdXNlZCBvbiBmb3huZXdzLmNvbQoJCXZhciBnZXRfanNvbl9zdHJpbmdpZnkgPSBmdW5jdGlvbigpIHsKCQkJdHJ5IHsKCQkJCUpTT05fc3RyaW5naWZ5ID0gSlNPTi5zdHJpbmdpZnk7CgkJCX0gY2F0Y2ggKGUpIHsKCQkJCWNvbnNvbGVfd2FybigiQ2Fubm90IHVzZSBuYXRpdmUgSlNPTi5zdHJpbmdpZnksIHVzaW5nIHNsb3cgaW1wbGVtZW50YXRpb24gaW5zdGVhZCIsIGUpOwoKCQkJCXZhciBpc19qc29uX3VuZGVmaW5lZCA9IGZ1bmN0aW9uKHgpIHsKCQkJCQlyZXR1cm4geCA9PT0gdm9pZCAwIHx8IHR5cGVvZiB4ID09PSAiZnVuY3Rpb24iOwoJCQkJfTsKCgkJCQkvLyBwcm9iYWJseSBpbmNvcnJlY3QgKGVzcGVjaWFsbHkgcmVnYXJkaW5nIHN0cmluZyBoYW5kbGluZykgYW5kIGRvZXNuJ3Qgc3VwcG9ydCBmb3JtYXR0aW5nCgkJCQkvLyBkb2VzIGl0IG1hdHRlcj8KCQkJCUpTT05fc3RyaW5naWZ5ID0gZnVuY3Rpb24oeCkgewoJCQkJCWlmIChpc19qc29uX3VuZGVmaW5lZCh4KSkKCQkJCQkJcmV0dXJuIHZvaWQgMDsKCgkJCQkJaWYgKHR5cGVvZiB4ID09PSAic3RyaW5nIikgewoJCQkJCQlyZXR1cm4gJyInICsgeAoJCQkJCQkJLnJlcGxhY2UoL1xcL2csICJcXFxcIikKCQkJCQkJCS5yZXBsYWNlKC8iL2csICdcXCInKSArICciJzsKCQkJCQl9CgoJCQkJCWlmICh4ID09PSBudWxsKQoJCQkJCQlyZXR1cm4gIm51bGwiOwoKCQkJCQlpZiAodHlwZW9mIHggPT09ICJudW1iZXIiKQoJCQkJCQlyZXR1cm4geCArICIiOwoKCQkJCQlpZiAoaXNfYXJyYXkoeCkpIHsKCQkJCQkJdmFyIGVscyA9IFtdOwoJCQkJCQlmb3IgKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyBpKyspIHsKCQkJCQkJCXZhciBzdHJpbmdpZmllZCA9IEpTT05fc3RyaW5naWZ5KHhbaV0pOwoJCQkJCQkJaWYgKHN0cmluZ2lmaWVkID09PSB2b2lkIDApCgkJCQkJCQkJc3RyaW5naWZpZWQgPSAibnVsbCI7CgoJCQkJCQkJZWxzLnB1c2goc3RyaW5naWZpZWQpOwoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gIlsiICsgZWxzLmpvaW4oIiwiKSArICJdIjsKCQkJCQl9CgoJCQkJCWlmICh0eXBlb2YgeCA9PT0gIm9iamVjdCIpIHsKCQkJCQkJdmFyIGVscyA9IFtdOwoJCQkJCQlmb3IgKHZhciBrZXkgaW4geCkgewoJCQkJCQkJdmFyIHN0cmluZ2lmaWVkID0gSlNPTl9zdHJpbmdpZnkoeFtrZXldKTsKCQkJCQkJCWlmIChzdHJpbmdpZmllZCA9PT0gdm9pZCAwKQoJCQkJCQkJCWNvbnRpbnVlOwoKCQkJCQkJCWVscy5wdXNoKCciJyArIGtleSArICciOicgKyBKU09OX3N0cmluZ2lmeSh4W2tleV0pKTsKCQkJCQkJfQoKCQkJCQkJcmV0dXJuICJ7IiArIGVscy5qb2luKCIsIikgKyAifSI7CgkJCQkJfQoKCQkJCQkvLyBkb2VzIHRoaXMgaGFwcGVuPwoJCQkJCXJldHVybiB2b2lkIDA7CgkJCQl9OwoJCQl9CgkJfTsKCQlnZXRfanNvbl9zdHJpbmdpZnkoKTsKCgkJLy8gTmFubyBEZWZlbmRlcig/KSBvdmVycmlkZXMgdGhpcyBvbiBzb21lIHNpdGVzLgoJCXZhciBnZXRfb3JpZ19ldmVudHRhcmdldCA9IGZ1bmN0aW9uKCkgewoJCQkvLyBuYXRpdmVfZnVuY3Rpb25zIHJldHVybnMgaWZyYW1lCgkJCXZhciBFdmVudFRhcmdldF9hZGRFdmVudExpc3RlbmVyLCBFdmVudFRhcmdldF9yZW1vdmVFdmVudExpc3RlbmVyOwoKCQkJaWYgKGlzX2ludGVyYWN0aXZlKSB7CgkJCQlvdXJfRXZlbnRUYXJnZXQgPSBFdmVudFRhcmdldDsKCQkJCUV2ZW50VGFyZ2V0X2FkZEV2ZW50TGlzdGVuZXIgPSBvdXJfRXZlbnRUYXJnZXQucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXI7CgkJCQlFdmVudFRhcmdldF9yZW1vdmVFdmVudExpc3RlbmVyID0gb3VyX0V2ZW50VGFyZ2V0LnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyOwoJCQl9CgoJCQl2YXIgZXZlbnRoYW5kbGVyX21hcCA9IG51bGw7CgoJCQl2YXIgaW5pdF9ldmVudGhhbmRsZXJfbWFwID0gZnVuY3Rpb24oKSB7CgkJCQlpZiAoIWV2ZW50aGFuZGxlcl9tYXApCgkJCQkJZXZlbnRoYW5kbGVyX21hcCA9IG5ld19tYXAoKTsKCQkJfTsKCgkJCW91cl9hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZWxlbWVudCwgZXZlbnQsIGhhbmRsZXIsIG9wdGlvbnMpIHsKCQkJCS8vIFZNIGNvbXBhdGliaWxpdHkKCQkJCWlmIChlbGVtZW50ID09PSB3aW5kb3cgJiYgZWxlbWVudC51bnNhZmVXaW5kb3cpCgkJCQkJZWxlbWVudCA9IGVsZW1lbnQudW5zYWZlV2luZG93OwoKCQkJCS8vIHBlcmZvcm1hbmNlCgkJCQl2YXIgc3VzcGVuZGVkX2NoZWNrID0gZnVuY3Rpb24oKSB7cmV0dXJuIGlzX3N1c3BlbmRlZCh0cnVlKTt9OwoJCQkJaWYgKGV2ZW50ID09PSAibW91c2Vtb3ZlIikgewoJCQkJCXN1c3BlbmRlZF9jaGVjayA9IGZ1bmN0aW9uKCkge3JldHVybiBpc19zdXNwZW5kZWQoZmFsc2UpO307CgkJCQl9CgoJCQkJdmFyIHJlYWxfaGFuZGxlciA9IGhhbmRsZXI7CgkJCQl2YXIgaGFuZGxlciA9IGZ1bmN0aW9uKGUpIHsKCQkJCQlpZiAoc3VzcGVuZGVkX2NoZWNrKCkpIHsKCQkJCQkJaWYgKGlzX3Rlcm1pbmF0ZWQpIG91cl9yZW1vdmVFdmVudExpc3RlbmVyKGVsZW1lbnQsIGV2ZW50LCByZWFsX2hhbmRsZXIpOwoJCQkJCQlyZXR1cm47CgkJCQkJfQoKCQkJCQlyZXR1cm4gcmVhbF9oYW5kbGVyKGUpOwoJCQkJfTsKCgkJCQkvLyBpPz8uZmFzdHBpYy5ydTogbmVlZGxlcyBhcmUgJ2NsaWNrJyBhbmQgJ3BvcE1hZ2ljJwoJCQkJdmFyIG5ld19oYW5kbGVyID0gZnVuY3Rpb24oZSkgewoJCQkJCXJldHVybiBoYW5kbGVyKGUpOwoJCQkJfTsKCgkJCQlpbml0X2V2ZW50aGFuZGxlcl9tYXAoKTsKCQkJCW1hcF9zZXQoZXZlbnRoYW5kbGVyX21hcCwgcmVhbF9oYW5kbGVyLCBuZXdfaGFuZGxlcik7CgoJCQkJRXZlbnRUYXJnZXRfYWRkRXZlbnRMaXN0ZW5lci5jYWxsKGVsZW1lbnQsIGV2ZW50LCBuZXdfaGFuZGxlciwgb3B0aW9ucyk7CgkJCX07CgoJCQlvdXJfcmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGVsZW1lbnQsIGV2ZW50LCBoYW5kbGVyLCBvcHRpb25zKSB7CgkJCQlpbml0X2V2ZW50aGFuZGxlcl9tYXAoKTsKCQkJCXZhciBuZXdfaGFuZGxlciA9IG1hcF9nZXQoZXZlbnRoYW5kbGVyX21hcCwgaGFuZGxlcik7CgkJCQlpZiAoIW5ld19oYW5kbGVyKSB7CgkJCQkJY29uc29sZV93YXJuKCJNb2RpZmllZCBoYW5kbGVyIG5vdCBmb3VuZCwgZGVmYXVsdGluZyB0byBzcGVjaWZpZWQgaGFuZGxlciIpOwoJCQkJCW5ld19oYW5kbGVyID0gaGFuZGxlcjsKCQkJCX0gZWxzZSB7CgkJCQkJbWFwX3JlbW92ZShldmVudGhhbmRsZXJfbWFwLCBuZXdfaGFuZGxlcik7CgkJCQl9CgoJCQkJRXZlbnRUYXJnZXRfcmVtb3ZlRXZlbnRMaXN0ZW5lci5jYWxsKGVsZW1lbnQsIGV2ZW50LCBuZXdfaGFuZGxlciwgb3B0aW9ucyk7CgkJCX07CgkJfTsKCQlnZXRfb3JpZ19ldmVudHRhcmdldCgpOwoKCQkvLyBpPz8uZmFzdHBpYy5ydSB3aXRoIHZpb2xlbnRtb25rZXkKCQl2YXIgZ2V0X29yaWdfY3JlYXRlZWxlbWVudCA9IGZ1bmN0aW9uKCkgewoJCQl2YXIgSFRNTERvY3VtZW50X2NyZWF0ZUVsZW1lbnQ7CgoJCQlpZiAoaXNfaW50ZXJhY3RpdmUgfHwgaXNfc2NyaXB0dGFnIHx8IHR5cGVvZiBIVE1MRG9jdW1lbnQgPT09ICJmdW5jdGlvbiIpIHsKCQkJCUhUTUxEb2N1bWVudF9jcmVhdGVFbGVtZW50ID0gSFRNTERvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVFbGVtZW50OwoJCQl9CgoJCQlkb2N1bWVudF9jcmVhdGVFbGVtZW50ID0gZnVuY3Rpb24oZWxlbWVudCkgewoJCQkJaWYgKCFIVE1MRG9jdW1lbnRfY3JlYXRlRWxlbWVudCkgewoJCQkJCWNvbnNvbGVfZXJyb3IoIlVuYWJsZSB0byBjcmVhdGUgZWxlbWVudCIsIGVsZW1lbnQsICIsIEhUTUxEb2N1bWVudC5wcm90b3R5cGUuY3JlYXRlRWxlbWVudCBkb2VzIG5vdCBleGlzdCIpOwoJCQkJCXJldHVybjsKCQkJCX0KCgkJCQlyZXR1cm4gSFRNTERvY3VtZW50X2NyZWF0ZUVsZW1lbnQuY2FsbChkb2N1bWVudCwgZWxlbWVudCk7CgkJCX07CgkJfTsKCQlnZXRfb3JpZ19jcmVhdGVlbGVtZW50KCk7CgoJCXZhciBzYW5pdHlfdGVzdCA9IGZ1bmN0aW9uKG9yaWcsIGNvcnJlY3QsIGNoZWNrLCBuYXRpdmVfZnVuYykgewoJCQlpZiAoIW9yaWcpCgkJCQlyZXR1cm4gY29ycmVjdDsKCgkJCWlmIChjaGVjaykgewoJCQkJdHJ5IHsKCQkJCQlpZiAoY2hlY2sob3JpZykpCgkJCQkJCXJldHVybiBvcmlnOwoJCQkJfSBjYXRjaCAoZSkge307CgkJCX0KCgkJCWlmIChuYXRpdmVfZnVuYykgewoJCQkJbmF0aXZlX2Z1bmN0aW9uc190b19nZXQucHVzaChuYXRpdmVfZnVuYyk7CgkJCX0KCgkJCXJldHVybiBjb3JyZWN0OwoJCX07CgoJCXZhciBnZXRfaXNfYXJyYXkgPSBmdW5jdGlvbigpIHsKCQkJdmFyIGlzX2FycmF5X29yaWcgPSBBcnJheS5pc0FycmF5OwoJCQl2YXIgaXNfYXJyYXlfY29ycmVjdCA9IGZ1bmN0aW9uKHgpIHsKCQkJCXJldHVybiB4IGluc3RhbmNlb2YgQXJyYXk7CgkJCX07CgoJCQlpZiAoaXNfYXJyYXlfb3JpZykgewoJCQkJaXNfYXJyYXkgPSBpc19hcnJheV9vcmlnOwoJCQl9IGVsc2UgewoJCQkJaXNfYXJyYXkgPSBpc19hcnJheV9jb3JyZWN0OwoJCQl9CgoJCQkvLyBGSVhNRTogd2h5IGlzIHRoZXJlIG5vIGNoZWNrPyBpcyB0aGlzIGEgYnVnLCBvciB3YXMgdGhpcyBpbnRlbnRpb25hbD8KCQkJLy9pc19hcnJheSA9IHNhbml0eV90ZXN0KGlzX2FycmF5X29yaWcsIGlzX2FycmF5X2NvcnJlY3QpOwoJCX07CgkJZ2V0X2lzX2FycmF5KCk7CgoJCS8vIGtpY2thc3MuY29tCgkJdmFyIGdldF9jb21wYXRfc3RyaW5nX2Zyb21jaGFyY29kZSA9IGZ1bmN0aW9uKCkgewoJCQl2YXIgc3RyaW5nX2Zyb21jaGFyY29kZV9vcmlnID0gbnVsbDsKCQkJLy8gdWJsb2NrIG9uIGNsaXB3YXRjaGluZyBibG9ja3MgdGhpcyBlbnRpcmVseQoJCQl0cnkgewoJCQkJc3RyaW5nX2Zyb21jaGFyY29kZV9vcmlnID0gU3RyaW5nLmZyb21DaGFyQ29kZTsKCQkJfSBjYXRjaCAoZSkge30KCgkJCXZhciBmcm9tY2hhcmNvZGVfY2hlY2sgPSBmdW5jdGlvbihmdW5jKSB7CgkJCQlyZXR1cm4gZnVuYyg1MCkgPT09ICIyIiAmJiBmdW5jKDEwMCkgPT09ICJkIiAmJiBmdW5jKCI1MCIsICIxMDAiKSA9PT0gIjJkIjsKCQkJfTsKCgkJCXZhciBmcm9tY2hhcmNvZGVfY29ycmVjdCA9IGZ1bmN0aW9uKCkgewoJCQkJdmFyIHVuaWNvZGUgPSAiIjsKCgkJCQlmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgewoJCQkJCXVuaWNvZGUgKz0gIlxcdSIgKyAoIjAwMDAiICsgcGFyc2VJbnQoYXJndW1lbnRzW2ldKS50b1N0cmluZygxNikpLnNsaWNlKC00KTsKCQkJCX0KCgkJCQlyZXR1cm4gSlNPTl9wYXJzZSgnIicgKyB1bmljb2RlICsgJyInKTsKCQkJfTsKCgkJCXN0cmluZ19mcm9tY2hhcmNvZGUgPSBzYW5pdHlfdGVzdChzdHJpbmdfZnJvbWNoYXJjb2RlX29yaWcsIGZyb21jaGFyY29kZV9jb3JyZWN0LCBmcm9tY2hhcmNvZGVfY2hlY2spOwoJCX07CgkJZ2V0X2NvbXBhdF9zdHJpbmdfZnJvbWNoYXJjb2RlKCk7CgoJCS8vIHBvcm4uY29tICh1YmxvY2spCgkJdmFyIGdldF9jb21wYXRfc3RyaW5nX2NoYXJhdCA9IGZ1bmN0aW9uKCkgewoJCQl2YXIgc3RyaW5nX3Byb3RvdHlwZV9jaGFyYXQgPSBTdHJpbmcucHJvdG90eXBlLmNoYXJBdDsKCQkJdmFyIHN0cmluZ19jaGFyYXRfb3JpZyA9IGZ1bmN0aW9uKHN0cmluZywgeCkgewoJCQkJcmV0dXJuIHN0cmluZ19wcm90b3R5cGVfY2hhcmF0LmNhbGwoc3RyaW5nLCB4KTsKCQkJfTsKCgkJCXZhciBzdHJpbmdfY2hhcmF0X2NvcnJlY3QgPSBmdW5jdGlvbihzdHJpbmcsIHgpIHsKCQkJCXZhciByZXN1bHQgPSBzdHJpbmdbeF07CgkJCQlpZiAocmVzdWx0ID09PSB2b2lkIDApCgkJCQkJcmVzdWx0ID0gIiI7CgoJCQkJcmV0dXJuIHJlc3VsdDsKCQkJfTsKCgkJCXZhciBzdHJpbmdfY2hhcmF0X2NoZWNrID0gZnVuY3Rpb24oZnVuYykgewoJCQkJdmFyIHRlc3Rfc3RyaW5nID0gImFiYyI7CgkJCQlpZiAoZnVuYyh0ZXN0X3N0cmluZywgMCkgPT09ICJhIiAmJgoJCQkJCWZ1bmModGVzdF9zdHJpbmcsIDEpID09PSAiYiIgJiYKCQkJCQlmdW5jKHRlc3Rfc3RyaW5nLCAtMSkgPT09ICIiICYmCgkJCQkJZnVuYyh0ZXN0X3N0cmluZywgMykgPT09ICIiKSB7CgkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9OwoKCQkJc3RyaW5nX2NoYXJhdCA9IHNhbml0eV90ZXN0KHN0cmluZ19jaGFyYXRfb3JpZywgc3RyaW5nX2NoYXJhdF9jb3JyZWN0LCBzdHJpbmdfY2hhcmF0X2NoZWNrKTsKCQl9OwoJCWdldF9jb21wYXRfc3RyaW5nX2NoYXJhdCgpOwoKCQl2YXIgZ2V0X2NvbXBhdF9iYXNlNjQgPSBmdW5jdGlvbigpIHsKCQkJaWYgKGlzX25vZGUpCgkJCQlyZXR1cm47CgoJCQkvLyBTb21lIHdlYnNpdGVzIHJlcGxhY2UgYXRvYiwgc28gd2UgaGF2ZSB0byBwcm92aWRlIG91ciBvd24gaW1wbGVtZW50YXRpb24gaW4gdGhvc2UgY2FzZXMKCQkJLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzE1MDE2NjA1CgkJCS8vIHVubWluaWZpZWQgdmVyc2lvbjogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzMwNTg5NzQKCQkJdmFyIGJhc2U2NF9kZWNvZGVfY29ycmVjdCA9IGZ1bmN0aW9uKHMpIHsKCQkJCXZhciBlPXt9LGksYj0wLGMseCxsPTAsYSxyPScnLHc9c3RyaW5nX2Zyb21jaGFyY29kZSxMPXMubGVuZ3RoOwoJCQkJdmFyIEE9IkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8iOwoJCQkJZm9yKGk9MDtpPDY0O2krKyl7ZVtzdHJpbmdfY2hhcmF0KEEsIGkpXT1pO30KCQkJCWZvcih4PTA7eDxMO3grKyl7CgkJCQkJYz1lW3N0cmluZ19jaGFyYXQocywgeCldO2I9KGI8PDYpK2M7bCs9NjsKCQkJCQl3aGlsZShsPj04KXsoKGE9KGI+Pj4obC09OCkpJjB4ZmYpfHwoeDwoTC0yKSkpJiYocis9dyhhKSk7fQoJCQkJfQoJCQkJcmV0dXJuIHI7CgkJCX07CgoJCQl2YXIgYmFzZTY0X2RlY29kZV90ZXN0ID0gZnVuY3Rpb24oZnVuYykgewoJCQkJaWYgKGZ1bmMoImRHVnpkQT09IikgPT09ICJ0ZXN0IikgewoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoKCQkJCXJldHVybiBmYWxzZTsKCQkJfTsKCgkJCWJhc2U2NF9kZWNvZGUgPSBzYW5pdHlfdGVzdChhdG9iLCBiYXNlNjRfZGVjb2RlX2NvcnJlY3QsIGJhc2U2NF9kZWNvZGVfdGVzdCwgImF0b2IiKTsKCgkJCXZhciBiYXNlNjRfZW5jb2RlX3Rlc3QgPSBmdW5jdGlvbihmdW5jKSB7CgkJCQlpZiAoZnVuYygidGVzdCIpID09PSAiZEdWemRBPT0iKSB7CgkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9OwoKCQkJdmFyIGZha2VfYmFzZTY0X2VuY29kZSA9IGZ1bmN0aW9uKHMpIHsKCQkJCWNvbnNvbGVfd2FybigiVXNpbmcgZmFrZSBiYXNlNjQgZW5jb2RlciIpOwoJCQkJcmV0dXJuIHM7CgkJCX07CgoJCQliYXNlNjRfZW5jb2RlID0gc2FuaXR5X3Rlc3QoYnRvYSwgZmFrZV9iYXNlNjRfZW5jb2RlLCBiYXNlNjRfZW5jb2RlX3Rlc3QsICJidG9hIik7CgkJfTsKCQlnZXRfY29tcGF0X2Jhc2U2NCgpOwoKCQl2YXIgZ2V0X2NvbXBhdF9hcnJheV9pbmRleG9mID0gZnVuY3Rpb24oKSB7CgkJCS8vIGh0dHBzOi8vd3d3Lm15Y29taWNzaG9wLmNvbS9zZWFyY2g/bWlueXI9MTkzOCZtYXh5cj0xOTU1JlRJRD0yOTE3MDIzNQoJCQkvLyB0aGlzIHNpdGUgcmVwbGFjZXMgQXJyYXkuaW5kZXhPZgoJCQkvLyBjYWNoZSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZiBpbiBjYXNlIGl0IGNoYW5nZXMgd2hpbGUgdGhlIHNjcmlwdCBpcyBleGVjdXRpbmcKCQkJdmFyIGFycmF5X3Byb3RvdHlwZV9pbmRleG9mID0gQXJyYXkucHJvdG90eXBlLmluZGV4T2Y7CgkJCXZhciBhcnJheV9pbmRleG9mX29yaWcgPSBmdW5jdGlvbihhcnJheSwgeCkgewoJCQkJcmV0dXJuIGFycmF5X3Byb3RvdHlwZV9pbmRleG9mLmNhbGwoYXJyYXksIHgpOwoJCQl9OwoKCQkJdmFyIGFycmF5X2luZGV4b2ZfY29ycmVjdCA9IGZ1bmN0aW9uKGFycmF5LCB4KSB7CgkJCQlpZiAodHlwZW9mIGFycmF5ID09PSAic3RyaW5nIikgewoJCQkJCS8vIFRPRE86IG1ha2Ugc3VyZSBBcnJheS5mcm9tIGlzIHNhbmUKCQkJCQlhcnJheSA9IEFycmF5LmZyb20oYXJyYXkpOwoJCQkJfQoKCQkJCWZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKCQkJCQlpZiAoYXJyYXlbaV0gPT09IHgpIHsKCQkJCQkJcmV0dXJuIGk7CgkJCQkJfQoJCQkJfQoKCQkJCXJldHVybiAtMTsKCQkJfTsKCgkJCXZhciBhcnJheV9pbmRleG9mX2NoZWNrID0gZnVuY3Rpb24oZnVuYykgewoJCQkJdmFyIHRlc3RfYXJyYXkgPSBbImEiLCAiYiJdOwoJCQkJdmFyIHRlc3Rfc3RyaW5nID0gImFiYyI7CgkJCQlpZiAoZnVuYyh0ZXN0X2FycmF5LCAibm90IGhlcmUiKSA9PT0gLTEgJiYKCQkJCQlmdW5jKHRlc3RfYXJyYXksICJiIikgPT09IDEgJiYKCQkJCQlmdW5jKHRlc3Rfc3RyaW5nLCAibiIpID09PSAtMSAmJgoJCQkJCWZ1bmModGVzdF9zdHJpbmcsICJiIikgPT09IDEgJiYKCQkJCQlmdW5jKHRlc3Rfc3RyaW5nLCAiYmMiKSA9PT0gLTEpIHsKCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCX0KCgkJCQlyZXR1cm4gZmFsc2U7CgkJCX07CgoJCQlhcnJheV9pbmRleG9mID0gc2FuaXR5X3Rlc3QoYXJyYXlfaW5kZXhvZl9vcmlnLCBhcnJheV9pbmRleG9mX2NvcnJlY3QsIGFycmF5X2luZGV4b2ZfY2hlY2spOwoJCX07CgkJZ2V0X2NvbXBhdF9hcnJheV9pbmRleG9mKCk7CgoJCS8vIGlkb2wuc2Fua2FrdWNvbXBsZXguY29tIG92ZXJyaWRlcyB0aGlzIHdpdGggYSBicm9rZW4gb25lCgkJdmFyIGdldF9jb21wYXRfYXJyYXlfcmVkdWNlID0gZnVuY3Rpb24oKSB7CgkJCXZhciBhcnJheV9wcm90b3R5cGVfcmVkdWNlID0gQXJyYXkucHJvdG90eXBlLnJlZHVjZTsKCQkJdmFyIGFycmF5X3JlZHVjZV9vcmlnID0gZnVuY3Rpb24oYXJyYXksIGNiLCBpbml0aWFsKSB7CgkJCQlpZiAodHlwZW9mIGluaXRpYWwgIT09ICJ1bmRlZmluZWQiKQoJCQkJCXJldHVybiBhcnJheV9wcm90b3R5cGVfcmVkdWNlLmNhbGwoYXJyYXksIGNiLCBpbml0aWFsKTsKCQkJCWVsc2UKCQkJCQlyZXR1cm4gYXJyYXlfcHJvdG90eXBlX3JlZHVjZS5jYWxsKGFycmF5LCBjYik7CgkJCX07CgoJCQl2YXIgYXJyYXlfcmVkdWNlX2NvcnJlY3QgPSBmdW5jdGlvbihhcnJheSwgY2IsIGluaXRpYWwpIHsKCQkJCXZhciBmaXJzdGluZGV4ID0gMDsKCgkJCQlpZiAodHlwZW9mIGluaXRpYWwgPT09ICJ1bmRlZmluZWQiKSB7CgkJCQkJaWYgKCFhcnJheS5sZW5ndGgpIHsKCQkJCQkJdGhyb3cgbmV3IFR5cGVFcnJvcigiUmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZSIpOwoJCQkJCX0KCgkJCQkJaW5pdGlhbCA9IGFycmF5WzBdOwoJCQkJCWZpcnN0aW5kZXggPSAxOwoJCQkJfQoKCQkJCXZhciBhY2MgPSBpbml0aWFsOwoJCQkJZm9yICh2YXIgaSA9IGZpcnN0aW5kZXg7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgewoJCQkJCWFjYyA9IGNiKGFjYywgYXJyYXlbaV0sIGksIGFycmF5KTsKCQkJCX0KCgkJCQlyZXR1cm4gYWNjOwoJCQl9OwoKCQkJdmFyIGFycmF5X3JlZHVjZV9jaGVjayA9IGZ1bmN0aW9uKGZ1bmMpIHsKCQkJCS8vIHNob3VsZCB0aHJvdyAndW5kZWZpbmVkIGlzIG5vdCBhIGZ1bmN0aW9uJwoJCQkJdHJ5IHsKCQkJCQlmdW5jKFtdKTsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9IGNhdGNoIChlKSB7fQoKCQkJCS8vIHNob3VsZCB0aHJvdyAnUmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZScKCQkJCXRyeSB7CgkJCQkJZnVuYyhbXSwgZnVuY3Rpb24oKXt9KTsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9IGNhdGNoIChlKSB7fQoKCQkJCXZhciByZWR1Y2VyID0gZnVuY3Rpb24oYWNjLCBjdXIsIGkpIHtyZXR1cm4gYWNjLnggKyBjdXIueCArIGl9OwoKCQkJCWlmIChpc05hTihmdW5jKFt7eDoyfSx7eDoyfSx7eDoyfV0sIHJlZHVjZXIpKSAmJgoJCQkJCWZ1bmMoW3t4OjJ9LHt4OjZ9XSwgcmVkdWNlcikgPT09IDkgJiYKCQkJCQlmdW5jKFt7eDoyfV0sIHJlZHVjZXIpLnggPT09IDIgJiYKCQkJCQlmdW5jKFt7eDoyfV0sIHJlZHVjZXIsIHt4OjZ9KSA9PT0gOCkgewoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoKCQkJCXJldHVybiBmYWxzZTsKCQkJfTsKCgkJCWFycmF5X3JlZHVjZSA9IHNhbml0eV90ZXN0KGFycmF5X3JlZHVjZV9vcmlnLCBhcnJheV9yZWR1Y2VfY29ycmVjdCwgYXJyYXlfcmVkdWNlX2NoZWNrKTsKCgkJCWFycmF5X3JlZHVjZV9wcm90b3R5cGUgPSBmdW5jdGlvbihjYiwgaW5pdGlhbCkgewoJCQkJcmV0dXJuIGFycmF5X3JlZHVjZSh0aGlzLCBjYiwgaW5pdGlhbCk7CgkJCX07CgkJfTsKCQlnZXRfY29tcGF0X2FycmF5X3JlZHVjZSgpOwoKCQl2YXIgZ2V0X2NvbXBhdF9zdHJpbmdfaW5kZXhvZiA9IGZ1bmN0aW9uKCkgewoJCQl2YXIgc3RyaW5nX3Byb3RvdHlwZV9pbmRleG9mID0gU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mOwoJCQl2YXIgc3RyaW5nX2luZGV4b2Zfb3JpZyA9IGZ1bmN0aW9uKHN0cmluZywgeCkgewoJCQkJcmV0dXJuIHN0cmluZ19wcm90b3R5cGVfaW5kZXhvZi5jYWxsKHN0cmluZywgeCk7CgkJCX07CgoJCQl2YXIgc3RyaW5nX2luZGV4b2ZfY29ycmVjdCA9IGZ1bmN0aW9uKHN0cmluZywgeCkgewoJCQkJaWYgKHgubGVuZ3RoID09PSAwKQoJCQkJCXJldHVybiAwOwoKCQkJCXZhciB4X2kgPSAwOwoJCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyBpKyspIHsKCQkJCQlpZiAoc3RyaW5nX2NoYXJhdChzdHJpbmcsIGkpID09PSBzdHJpbmdfY2hhcmF0KHgsIHhfaSkpIHsKCQkJCQkJaWYgKHhfaSArIDEgPT09IHgubGVuZ3RoKSB7CgkJCQkJCQlyZXR1cm4gaSAtIHhfaTsKCQkJCQkJfSBlbHNlIHsKCQkJCQkJCXhfaSsrOwoJCQkJCQl9CgkJCQkJfSBlbHNlIHsKCQkJCQkJeF9pID0gMDsKCQkJCQl9CgkJCQl9CgoJCQkJcmV0dXJuIC0xOwoJCQl9OwoKCQkJdmFyIHN0cmluZ19pbmRleG9mX2NoZWNrID0gZnVuY3Rpb24oZnVuYykgewoJCQkJdmFyIHRlc3Rfc3RyaW5nID0gImFiYyI7CgkJCQlpZiAoZnVuYyh0ZXN0X3N0cmluZywgIm4iKSA9PT0gLTEgJiYKCQkJCQlmdW5jKHRlc3Rfc3RyaW5nLCAiYiIpID09PSAxICYmCgkJCQkJZnVuYyh0ZXN0X3N0cmluZywgImJjIikgPT09IDEgJiYKCQkJCQlmdW5jKHRlc3Rfc3RyaW5nLCAiYmN6IikgPT09IC0xICYmCgkJCQkJZnVuYyh0ZXN0X3N0cmluZywgIiIpID09PSAwKSB7CgkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9OwoKCQkJc3RyaW5nX2luZGV4b2YgPSBzYW5pdHlfdGVzdChzdHJpbmdfaW5kZXhvZl9vcmlnLCBzdHJpbmdfaW5kZXhvZl9jb3JyZWN0LCBzdHJpbmdfaW5kZXhvZl9jaGVjayk7CgkJfTsKCQlnZXRfY29tcGF0X3N0cmluZ19pbmRleG9mKCk7CgoJCXZhciBnZXRfY29tcGF0X3VybCA9IGZ1bmN0aW9uKCkgewoJCQlpZiAoaXNfbm9kZSkKCQkJCXJldHVybjsKCgkJCXZhciBuYXRpdmVfdXJsX2NoZWNrID0gZnVuY3Rpb24oVVJMKSB7CgkJCQlpZiAodHlwZW9mIFVSTCAhPT0gImZ1bmN0aW9uIiB8fCB0eXBlb2YgVVJMLnByb3RvdHlwZSAhPT0gIm9iamVjdCIpCgkJCQkJcmV0dXJuIGZhbHNlOwoKCQkJCWlmICghKCJzZWFyY2hQYXJhbXMiIGluIFVSTC5wcm90b3R5cGUpKQoJCQkJCXJldHVybiBmYWxzZTsKCgkJCQlpZiAoaXNfaW50ZXJhY3RpdmUpIHsKCQkJCQlpZiAoISgiY3JlYXRlT2JqZWN0VVJMIiBpbiBVUkwpIHx8ICEoInJldm9rZU9iamVjdFVSTCIgaW4gVVJMKSkKCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoKCQkJCXJldHVybiB0cnVlOwoJCQl9OwoKCQkJdmFyIG9yaWdfVVJMID0gVVJMIHx8IHdlYmtpdFVSTDsKCQkJbmF0aXZlX1VSTCA9IHNhbml0eV90ZXN0KG9yaWdfVVJMLCBudWxsZnVuYywgbmF0aXZlX3VybF9jaGVjaywgIlVSTCIpOwoJCX07CgkJZ2V0X2NvbXBhdF91cmwoKTsKCgkJdmFyIGdldF9jb21wYXRfYmxvYiA9IGZ1bmN0aW9uKCkgewoJCQlpZiAoaXNfbm9kZSkKCQkJCXJldHVybjsKCgkJCXZhciBuYXRpdmVfYmxvYl9jaGVjayA9IGZ1bmN0aW9uKEJsb2IpIHsKCQkJCWlmICh0eXBlb2YgQmxvYiAhPT0gImZ1bmN0aW9uIiB8fCB0eXBlb2YgQmxvYi5wcm90b3R5cGUgIT09ICJvYmplY3QiKQoJCQkJCXJldHVybiBmYWxzZTsKCgkJCQkvLyBkb2Vzbid0IHNlZW0gdG8gd29yayB1bmRlciBGaXJlZm94CgkJCQkvLyBpdCBkb2VzIGV4aXN0IGFmdGVyIGEgd2hpbGUsIGJ1dCBub3Qgd2hpbGUgY2hlY2tpbmcKCQkJCWlmIChmYWxzZSAmJiBCbG9iLm5hbWUgIT09ICJCbG9iIikKCQkJCQlyZXR1cm4gZmFsc2U7CgoJCQkJaWYgKC8qISgiYXJyYXlCdWZmZXIiIGluIEJsb2IucHJvdG90eXBlKSB8fCovIC8vIE5vdCBpbXBsZW1lbnRlZCBpbiBwYWxlIG1vb24KCQkJCQkhKCJzbGljZSIgaW4gQmxvYi5wcm90b3R5cGUpIHx8CgkJCQkJISgic2l6ZSIgaW4gQmxvYi5wcm90b3R5cGUpKQoJCQkJCXJldHVybiBmYWxzZTsKCgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfTsKCgkJCXZhciBmYWtlX2Jsb2IgPSBmdW5jdGlvbigpIHsKCQkJCWNvbnNvbGVfd2FybigiVGhpcyBpcyBhIGZha2UgQmxvYiBvYmplY3QsIHlvdSB3aWxsIGFsbW9zdCBjZXJ0YWlubHkgZW5jb3VudGVyIHByb2JsZW1zLiIpOwoJCQl9OwoKCQkJbmV3X2Jsb2IgPSBmdW5jdGlvbihkYXRhLCBjYiwgb3B0aW9ucykgewoJCQkJY2IobmV3IG5hdGl2ZV9ibG9iKFtkYXRhXSwgb3B0aW9ucykpOwoJCQl9OwoKCQkJbmF0aXZlX2Jsb2IgPSBzYW5pdHlfdGVzdChCbG9iLCBmYWtlX2Jsb2IsIG5hdGl2ZV9ibG9iX2NoZWNrLCAiQmxvYiIpOwoKCQkJaWYgKG5hdGl2ZV9ibG9iICE9PSBCbG9iKSB7CgkJCQkvLyB0b2RvOiBzYW5pdHkgY2hlY2sgUmVzcG9uc2UgYW5kIEZpbGUKCQkJCWlmICh0eXBlb2YgUmVzcG9uc2UgPT09ICJmdW5jdGlvbiIpIHsKCQkJCQluZXdfYmxvYiA9IGZ1bmN0aW9uKGRhdGEsIGNiLCBvcHRpb25zKSB7CgkJCQkJCXZhciByZXNwb25zZV9vcHQgPSB7fTsKCQkJCQkJaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy50eXBlKSB7CgkJCQkJCQlyZXNwb25zZV9vcHQuaGVhZGVycyA9IHsKCQkJCQkJCQkiQ29udGVudC1UeXBlIjogb3B0aW9ucy50eXBlCgkJCQkJCQl9OwoJCQkJCQl9CgoJCQkJCQluZXcgUmVzcG9uc2UoZGF0YSwgcmVzcG9uc2Vfb3B0KS5ibG9iKCkudGhlbihmdW5jdGlvbihyZXNwKSB7CgkJCQkJCQljYihyZXNwKTsKCQkJCQkJfSk7CgkJCQkJfTsKCQkJCX0gZWxzZSBpZiAodHlwZW9mIEZpbGUgPT09ICJmdW5jdGlvbiIpIHsKCQkJCQluZXdfYmxvYiA9IGZ1bmN0aW9uKGRhdGEsIGNiLCBvcHRpb25zKSB7CgkJCQkJCWNiKG5ldyBGaWxlKFtkYXRhXSwgIiIsIG9wdGlvbnMpKTsKCQkJCQl9OwoJCQkJfQoJCQl9CgkJfTsKCQlnZXRfY29tcGF0X2Jsb2IoKTsKCgkJLy8gdGhpcyBpcyByYXRoZXIgc2xvdyAofjI1bXMgYWNjb3JkaW5nIHRvIGZpcmVhdHRhY2sncyBwcm9maWxlKQoJCXZhciBuYXRpdmVfZnVuY3Rpb25zID0ge307CgkJdmFyIGdldF9uYXRpdmVfZnVuY3Rpb25zID0gZnVuY3Rpb24oZnVuY3Rpb25zKSB7CgkJCS8vIHRoYW5rcyB0byB0b3BoZiBoZXJlOiBodHRwczovL2dpdGh1Yi5jb20vdmlvbGVudG1vbmtleS92aW9sZW50bW9ua2V5L2lzc3Vlcy85NDQKCQkJdmFyIGlmcmFtZSA9IGRvY3VtZW50X2NyZWF0ZUVsZW1lbnQoImlmcmFtZSIpOwoJCQlpZnJhbWUuc3JjZG9jID0gIiI7IC8vImphdmFzY3JpcHQ6MCIKCQkJZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKGlmcmFtZSk7CgkJCXZhciBmcmFtZV93aW5kb3cgPSBpZnJhbWUuY29udGVudFdpbmRvdzsKCgkJCWZvciAodmFyIGkgPSAwOyBpIDwgZnVuY3Rpb25zLmxlbmd0aDsgaSsrKSB7CgkJCQl2YXIgZnVuYyA9IGZ1bmN0aW9uc1tpXTsKCQkJCW5hdGl2ZV9mdW5jdGlvbnNbZnVuY10gPSBmcmFtZV93aW5kb3dbZnVuY107CgkJCX0KCgkJCWlmcmFtZS5wYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGlmcmFtZSk7CgkJfTsKCgkJLy8gRklYTUU6IHRoaXMgZG9lc24ndCB3b3JrIHVuZGVyIHBhbGUgbW9vbjogaHR0cHM6Ly9naXRodWIuY29tL3Fzbml5Zy9tYXh1cmwvaXNzdWVzLzM0OQoJCWlmIChuYXRpdmVfZnVuY3Rpb25zX3RvX2dldC5sZW5ndGggPiAwKSB7CgkJCXRyeSB7CgkJCQlnZXRfbmF0aXZlX2Z1bmN0aW9ucyhuYXRpdmVfZnVuY3Rpb25zX3RvX2dldCk7CgkJCX0gY2F0Y2ggKGUpIHsKCQkJCWNvbnNvbGVfZXJyb3IoZSk7CgkJCX0KCgkJCWlmICgiQmxvYiIgaW4gbmF0aXZlX2Z1bmN0aW9ucykgewoJCQkJbmF0aXZlX2Jsb2IgPSBuYXRpdmVfZnVuY3Rpb25zLkJsb2I7CgkJCX0KCgkJCWlmICgiVVJMIiBpbiBuYXRpdmVfZnVuY3Rpb25zKSB7CgkJCQluYXRpdmVfVVJMID0gbmF0aXZlX2Z1bmN0aW9ucy5VUkw7CgkJCX0KCgkJCWlmICgiYXRvYiIgaW4gbmF0aXZlX2Z1bmN0aW9ucykgewoJCQkJYmFzZTY0X2RlY29kZSA9IG5hdGl2ZV9mdW5jdGlvbnMuYXRvYjsKCQkJfQoKCQkJaWYgKCJidG9hIiBpbiBuYXRpdmVfZnVuY3Rpb25zKSB7CgkJCQliYXNlNjRfZW5jb2RlID0gbmF0aXZlX2Z1bmN0aW9ucy5idG9hOwoJCQl9CgkJfQoJfTsKCWdldF9jb21wYXRfZnVuY3Rpb25zKCk7CgoJdmFyIGFycmF5X2V4dGVuZCA9IGZ1bmN0aW9uKGFycmF5LCBvdGhlcikgewoJCWlmICghaXNfYXJyYXkob3RoZXIpKSBvdGhlciA9IFtvdGhlcl07CgkJW10ucHVzaC5hcHBseShhcnJheSwgb3RoZXIpOwoJfTsKCgl2YXIgYXJyYXlfZm9yZWFjaCA9IGZ1bmN0aW9uKGFycmF5LCBjYiwgZG9fc2hhbGxvd19jb3B5KSB7CgkJaWYgKGRvX3NoYWxsb3dfY29weSkgewoJCQl2YXIgbmV3YXJyYXkgPSBbXTsKCgkJCWZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKCQkJCW5ld2FycmF5LnB1c2goYXJyYXlbaV0pOwoJCQl9CgoJCQlhcnJheSA9IG5ld2FycmF5OwoJCX0KCgkJZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgewoJCQlpZiAoY2IoYXJyYXlbaV0sIGkpID09PSBmYWxzZSkKCQkJCXJldHVybjsKCQl9Cgl9OwoKCXZhciBhcnJheV9vcl9udWxsID0gZnVuY3Rpb24oYXJyYXkpIHsKCQlpZiAoIWFycmF5IHx8ICFhcnJheS5sZW5ndGgpCgkJCXJldHVybiBudWxsOwoKCQlyZXR1cm4gYXJyYXk7Cgl9OwoKCXZhciBhcnJheV91cHVzaCA9IGZ1bmN0aW9uKGFycmF5LCBpdGVtKSB7CgkJaWYgKGFycmF5X2luZGV4b2YoYXJyYXksIGl0ZW0pIDwgMCkKCQkJYXJyYXkucHVzaChpdGVtKTsKCX07CgoJdmFyIHN0cmluZ19yZXBsYWNlYWxsID0gZnVuY3Rpb24oc3RyLCBmaW5kLCByZXBsYWNlKSB7CgkJLy8gVE9ETzogbWFrZSBmYXN0ZXIKCQlyZXR1cm4gc3RyLnNwbGl0KGZpbmQpLmpvaW4ocmVwbGFjZSk7Cgl9OwoKCXZhciBtYXRjaF9hbGwgPSBmdW5jdGlvbihzdHIsIHJlZ2V4KSB7CgkJdmFyIGdsb2JhbF9yZWdleCA9IG5ldyBSZWdFeHAocmVnZXgsICJnIik7CgoJCXZhciBtYXRjaGVzID0gc3RyLm1hdGNoKGdsb2JhbF9yZWdleCk7CgkJaWYgKCFtYXRjaGVzKQoJCQlyZXR1cm4gbnVsbDsKCgkJdmFyIHJlc3VsdCA9IFtdOwoJCWFycmF5X2ZvcmVhY2gobWF0Y2hlcywgZnVuY3Rpb24obWF0Y2gpIHsKCQkJcmVzdWx0LnB1c2gobWF0Y2gubWF0Y2gocmVnZXgpKTsKCQl9KTsKCgkJcmV0dXJuIHJlc3VsdDsKCX07CgoJdmFyIG9ial9mb3JlYWNoID0gZnVuY3Rpb24ob2JqLCBjYikgewoJCWZvciAodmFyIGtleSBpbiBvYmopIHsKCQkJaWYgKGNiKGtleSwgb2JqW2tleV0pID09PSBmYWxzZSkKCQkJCXJldHVybjsKCQl9Cgl9OwoKCXZhciBvYmpfZXh0ZW5kID0gZnVuY3Rpb24ob2JqLCBvdGhlcm9iaikgewoJCWZvciAodmFyIGtleSBpbiBvdGhlcm9iaikgewoJCQlvYmpba2V5XSA9IG90aGVyb2JqW2tleV07CgkJfQoKCQlyZXR1cm4gb2JqOwoJfTsKCgl2YXIgY29tbW9uX2Z1bmN0aW9ucyA9IHt9OwoKCWNvbW1vbl9mdW5jdGlvbnMubnVsbGZ1bmMgPSBmdW5jdGlvbigpIHt9OwoKCWNvbW1vbl9mdW5jdGlvbnMubnVsbG9iamZ1bmMgPSBmdW5jdGlvbigpIHsKCQl2YXIgeCA9IHsKCQkJZnVuYzogZnVuY3Rpb24oKSB7fQoJCX07CgoJCXJldHVybiB4OwoJfTsKCgljb21tb25fZnVuY3Rpb25zLnJ1bl9hcnJheWRfc3RyaW5nID0gZnVuY3Rpb24oc3RyLCBvcHRpb25zKSB7CgkJc3RyID0gc3RyLnNwbGl0KCIiKTsKCQlvcHRpb25zLmNiKHN0cik7CgkJcmV0dXJuIHN0ci5qb2luKCIiKTsKCX07CgoJY29tbW9uX2Z1bmN0aW9ucy5uZXdfdm0gPSBmdW5jdGlvbigpIHsKCQkvLyBzaVtuXSA9IG50aCBzdGFjayBpdGVtIChsYXN0ID0gMCkKCQl2YXIgdm1fYXJjaCA9IFsKCQkJLy8gMDogUHVzaCBkYXRhIHRvIHRoZSBzdGFjawoJCQlmdW5jdGlvbih2bSkgewoJCQkJdm0uc3RhY2sudW5zaGlmdCh2bS5kYXRhKTsKCQkJfSwKCQkJLy8gMTogUHVzaCBhcmcgdG8gdGhlIHN0YWNrCgkJCWZ1bmN0aW9uKHZtKSB7CgkJCQl2bS5zdGFjay51bnNoaWZ0KHZtLmFyZyk7CgkJCX0sCgkJCS8vIDI6IFBvcCBzaVswXSAuLiBzaVthcmddCgkJCWZ1bmN0aW9uKHZtKSB7CgkJCQlmb3IgKHZhciBpID0gMDsgaSA8IHZtLmFyZzsgaSsrKSB7CgkJCQkJdm0uc3RhY2suc2hpZnQoKTsKCQkJCX0KCQkJfSwKCQkJLy8gMzogUHVzaCBzaVthcmddIHRvIHNpWzBdCgkJCWZ1bmN0aW9uKHZtKSB7CgkJCQl2bS5zdGFjay51bnNoaWZ0KHZtLnN0YWNrW3ZtLmFyZ10pOwoJCQl9LAoJCQkvLyA0OiBBcHBlbmQgc2lbMV0gdG8gc2lbMF0KCQkJZnVuY3Rpb24odm0pIHsKCQkJCXZtLnN0YWNrWzBdLnB1c2godm0uc3RhY2tbMV0pOwoJCQl9LAoJCQkvLyA1OiBQcmVwZW5kIHNpWzFdIHRvIHNpWzBdCgkJCWZ1bmN0aW9uKHZtKSB7CgkJCQl2bS5zdGFja1swXS51bnNoaWZ0KHZtLnN0YWNrWzFdKTsKCQkJfSwKCQkJLy8gNjogUmV2ZXJzZSBzaVswXQoJCQlmdW5jdGlvbih2bSkgewoJCQkJdm0uc3RhY2tbMF0ucmV2ZXJzZSgpOwoJCQl9LAoJCQkvLyA3OiBTd2FwcyB0aGUgdmFsdWVzIGF0IHNpWzFdIGFuZCBzaVsyXSBpbiBzaVswXQoJCQlmdW5jdGlvbih2bSkgewoJCQkJdmFyIHJlZ2lzdGVyID0gdm0uc3RhY2tbMF1bdm0uc3RhY2tbMl1dOwoJCQkJdm0uc3RhY2tbMF1bdm0uc3RhY2tbMl1dID0gdm0uc3RhY2tbMF1bdm0uc3RhY2tbMV0gJSB2bS5zdGFja1swXS5sZW5ndGhdOwoJCQkJdm0uc3RhY2tbMF1bdm0uc3RhY2tbMV0gJSB2bS5zdGFja1swXS5sZW5ndGhdID0gcmVnaXN0ZXI7CgkJCX0sCgkJCS8vIDg6IFJlbW92ZXMgc2lbMV0gKGlkKSBmcm9tIHNpWzBdCgkJCWZ1bmN0aW9uKHZtKSB7CgkJCQl2bS5zdGFja1swXS5zcGxpY2Uodm0uc3RhY2tbMV0sIDEpOwoJCQl9LAoJCQkvLyA5OiBSZW1vdmVzIGV2ZXJ5dGhpbmcgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHNpWzBdIHRvIHNpWzFdCgkJCWZ1bmN0aW9uKHZtKSB7CgkJCQl2bS5zdGFja1swXS5zcGxpY2UoMCwgdm0uc3RhY2tbMV0pOwoJCQl9LAoJCQkvLyAxMDogUmVtb3ZlcyBldmVyeXRoaW5nIGZyb20gc2lbMV0gdG8gdGhlIGVuZCBvZiBzaVswXQoJCQlmdW5jdGlvbih2bSkgewoJCQkJdm0uc3RhY2tbMF0uc3BsaWNlKHZtLnN0YWNrWzFdLCB2bS5zdGFja1swXS5sZW5ndGgpOwoJCQl9LAoJCQkvLyAxMTogQWRkcyBzaVsyXSB0byB0aGUgdmFsdWUgYXQgc2lbMV0gaW4gc2lbMF0KCQkJZnVuY3Rpb24odm0pIHsKCQkJCXZtLnN0YWNrWzBdW3ZtLnN0YWNrWzFdXSArPSB2bS5zdGFja1syXTsKCQkJfSwKCQkJLy8gMTI6IE11bHRpcGxpZXMgc2lbMl0gd2l0aCB0aGUgdmFsdWUgYXQgc2lbMV0gaW4gc2lbMF0KCQkJZnVuY3Rpb24odm0pIHsKCQkJCXZtLnN0YWNrWzBdW3ZtLnN0YWNrWzFdXSAqPSB2bS5zdGFja1syXTsKCQkJfSwKCQkJLy8gMTM6IE5lZ2F0ZXMgdGhlIHZhbHVlIGF0IHNpWzFdIGluIHNpWzBdCgkJCWZ1bmN0aW9uKHZtKSB7CgkJCQl2bS5zdGFja1swXVt2bS5zdGFja1sxXV0gKj0gLTE7CgkJCX0sCgkJXTsKCgkJdmFyIF9ydW5fdm0gPSBmdW5jdGlvbihvcHMsIGRhdGEpIHsKCQkJdmFyIHZtID0gewoJCQkJc3RhY2s6IFtdLAoJCQkJZGF0YTogZGF0YQoJCQl9OwoKCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBvcHMubGVuZ3RoOyBpICs9IDIpIHsKCQkJCXZhciBpbnN0ID0gb3BzW2ldOwoJCQkJdmFyIGFyZyA9IG9wc1tpICsgMV07CgoJCQkJdm0uYXJnID0gYXJnOwoJCQkJdm1fYXJjaFtpbnN0XSh2bSk7CgkJCX0KCgkJCXJldHVybiBkYXRhOwoJCX07CgoJCXZhciBydW5fdm0gPSBmdW5jdGlvbihvcHMsIGRhdGEpIHsKCQkJaWYgKHR5cGVvZiBkYXRhID09PSAic3RyaW5nIikgewoJCQkJcmV0dXJuIGNvbW1vbl9mdW5jdGlvbnMucnVuX2FycmF5ZF9zdHJpbmcoZGF0YSwgewoJCQkJCWNiOiBmdW5jdGlvbihkYXRhKSB7CgkJCQkJCXJldHVybiBfcnVuX3ZtKG9wcywgZGF0YSk7CgkJCQkJfQoJCQkJfSk7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm4gX3J1bl92bShvcHMsIGRhdGEpOwoJCQl9CgkJfTsKCgkJcmV0dXJuIHsKCQkJYXJjaDogdm1fYXJjaCwKCQkJb3Bfc3RhcnQ6IDQsIC8vIGZpcnN0IDQgYXJlIHB1c2gvcG9wCgkJCXRvdGFsX2luc3RyczogT2JqZWN0LmtleXModm1fYXJjaCkubGVuZ3RoLAoJCQlydW46IHJ1bl92bQoJCX07Cgl9OwoKCWNvbW1vbl9mdW5jdGlvbnMuY3JlYXRlX3ZtX29wcyA9IGZ1bmN0aW9uKGluc3RydWN0aW9ucykgewoJCXZhciBvcHMgPSBbXTsKCgkJLy8gaW5pdGlhbGl6ZSBzdGFjawoJCWZvciAodmFyIGkgPSAwOyBpIDwgMzsgaSsrKSB7CgkJCW9wcy5wdXNoKDEsIDApOwoJCX0KCgkJYXJyYXlfZm9yZWFjaChpbnN0cnVjdGlvbnMsIGZ1bmN0aW9uKGluc3QpIHsKCQkJdmFyIG9wY29kZSA9IGluc3RbMF07CgoJCQkvLyBwdXNoIGFyZ3VtZW50cwoJCQlmb3IgKHZhciBpID0gMTsgaSA8IGluc3QubGVuZ3RoOyBpKyspIHsKCQkJCW9wcy5wdXNoKDEsIGluc3RbaV0pOwoJCQl9CgkJCXZhciBhcmdzX2NvdW50ID0gaW5zdC5sZW5ndGggLSAxOwoKCQkJb3BzLnB1c2goCgkJCQkvLyBwdXNoIGRhdGEKCQkJCTAsIG51bGwsCgoJCQkJLy8gcnVuIG9wZXJhdGlvbgoJCQkJb3Bjb2RlLCBudWxsLAoKCQkJCS8vIHBvcCBkYXRhK2FyZ3MKCQkJCTIsIDEgKyBhcmdzX2NvdW50CgkJCSk7CgkJfSk7CgoJCS8vIGNsZWFudXAKCQlvcHMucHVzaCgyLCAzKTsKCgkJcmV0dXJuIG9wczsKCX07CgoJLy8gdWJsb2NrIGJsb2NrcyBhY2Nlc3NpbmcgTWF0aCBvbiBzaXRlcyBsaWtlIGdmeWNhdAoJdmFyIE1hdGhfZmxvb3IsIE1hdGhfcm91bmQsIE1hdGhfcmFuZG9tLCBNYXRoX21heCwgTWF0aF9taW4sIE1hdGhfYWJzLCBNYXRoX3BvdzsKCXZhciBnZXRfY29tcGF0X21hdGggPSBmdW5jdGlvbigpIHsKCQlpZiAoaXNfbm9kZSkKCQkJcmV0dXJuOwoKCQl0cnkgewoJCQlNYXRoX2Zsb29yID0gTWF0aC5mbG9vcjsKCQkJTWF0aF9yb3VuZCA9IE1hdGgucm91bmQ7CgkJCU1hdGhfcmFuZG9tID0gTWF0aC5yYW5kb207CgkJCU1hdGhfbWF4ID0gTWF0aC5tYXg7CgkJCU1hdGhfbWluID0gTWF0aC5taW47CgkJCU1hdGhfYWJzID0gTWF0aC5hYnM7CgkJCU1hdGhfcG93ID0gTWF0aC5wb3c7CgkJfSBjYXRjaCAoZSkgewoJCQlNYXRoX2Zsb29yID0gZnVuY3Rpb24oeCkgewoJCQkJcmV0dXJuIHggfCAwOwoJCQl9OwoKCQkJTWF0aF9yb3VuZCA9IGZ1bmN0aW9uKHgpIHsKCQkJCXJldHVybiBNYXRoX2Zsb29yKHggKyAwLjUpOwoJCQl9OwoKCQkJdmFyIG1hdGhfc2VlZCA9IERhdGUubm93KCk7CgkJCXZhciBtYXRoX3ZtID0gbnVsbDsKCQkJTWF0aF9yYW5kb20gPSBmdW5jdGlvbigpIHsKCQkJCWlmICghbWF0aF92bSkgewoJCQkJCW1hdGhfdm0gPSBjb21tb25fZnVuY3Rpb25zLm5ld192bSgpOwoJCQkJfQoKCQkJCWlmIChtYXRoX3ZtKSB7CgkJCQkJdmFyIHRvdGFsX2luc3RycyA9IG1hdGhfdm0udG90YWxfaW5zdHJzIC0gbWF0aF92bS5vcF9zdGFydDsKCQkJCQl2YXIgYmFkX2luc3RycyA9IFs4LCA5LCAxMCwgMTNdOwoKCQkJCQl2YXIgaW5zdHJ1Y3Rpb25zID0gW107CgoJCQkJCXZhciB0aW1lcyA9IG1hdGhfc2VlZCAmIDB4ZjsKCQkJCQlpZiAoIXRpbWVzKQoJCQkJCQl0aW1lcyA9IDQ7CgkJCQkJZm9yICh2YXIgaSA9IDA7IGkgPCB0aW1lczsgaSsrKSB7CgkJCQkJCXZhciBpbnN0ciA9ICgoKG1hdGhfc2VlZCA+PiA0KSAmIDB4ZikgKyAoKG1hdGhfc2VlZCA+PiAoaSU4KSkgJiAweGYpKSAlIHRvdGFsX2luc3RycyArIG1hdGhfdm0ub3Bfc3RhcnQ7CgoJCQkJCQlpZiAoYXJyYXlfaW5kZXhvZihiYWRfaW5zdHJzLCBpbnN0cikgPj0gMCkgewoJCQkJCQkJdGltZXMrKzsKCQkJCQkJCWNvbnRpbnVlOwoJCQkJCQl9CgoJCQkJCQlpbnN0cnVjdGlvbnMucHVzaChbCgkJCQkJCQlpbnN0ciwKCgkJCQkJCQkobWF0aF9zZWVkICYgMHhmZikgKyBpLAoJCQkJCQkJKChtYXRoX3NlZWQgJiAweGYpICsgaSkgJSA1CgkJCQkJCV0pOwoJCQkJCX0KCgkJCQkJdmFyIG9wcyA9IGNvbW1vbl9mdW5jdGlvbnMuY3JlYXRlX3ZtX29wcyhpbnN0cnVjdGlvbnMpOwoKCQkJCQl0cnkgewoJCQkJCQl2YXIgbmV3X21hdGhfc2VlZCA9IHBhcnNlRmxvYXQobWF0aF92bS5ydW4ob3BzLCBtYXRoX3NlZWQgKyAiIikpOwoKCQkJCQkJaWYgKCFpc05hTihuZXdfbWF0aF9zZWVkKSkKCQkJCQkJCW1hdGhfc2VlZCArPSBuZXdfbWF0aF9zZWVkOwoJCQkJCX0gY2F0Y2ggKGUpIHsKCQkJCQkJLy9jb25zb2xlX3dhcm4oZSk7CgkJCQkJfQoJCQkJfQoKCQkJCW1hdGhfc2VlZCArPSBEYXRlLm5vdygpOwoJCQkJbWF0aF9zZWVkICU9IDFlODsKCQkJCXJldHVybiBtYXRoX3NlZWQgLyAxZTg7CgkJCX07CgoJCQlNYXRoX21heCA9IGZ1bmN0aW9uKCkgewoJCQkJdmFyIG1heCA9IC1JbmZpbml0eTsKCgkJCQlmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgewoJCQkJCWlmIChhcmd1bWVudHNbaV0gPiBtYXgpCgkJCQkJCW1heCA9IGFyZ3VtZW50c1tpXTsKCQkJCX0KCgkJCQlyZXR1cm4gbWF4OwoJCQl9OwoKCQkJTWF0aF9taW4gPSBmdW5jdGlvbigpIHsKCQkJCXZhciBtaW4gPSBJbmZpbml0eTsKCgkJCQlmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgewoJCQkJCWlmIChhcmd1bWVudHNbaV0gPCBtaW4pCgkJCQkJCW1pbiA9IGFyZ3VtZW50c1tpXTsKCQkJCX0KCgkJCQlyZXR1cm4gbWluOwoJCQl9OwoKCQkJTWF0aF9hYnMgPSBmdW5jdGlvbih4KSB7CgkJCQlpZiAoeCA8IDApCgkJCQkJcmV0dXJuIC14OwoKCQkJCXJldHVybiB4OwoJCQl9OwoKCQkJLy8gaW5jb3JyZWN0IGJ1dCBnb29kIGVub3VnaCBmb3Igbm93CgkJCU1hdGhfcG93ID0gZnVuY3Rpb24oeCwgeSkgewoJCQkJZm9yICh2YXIgaSA9IDE7IGkgPCB5OyBpKyspIHsKCQkJCQl4ICo9IHg7CgkJCQl9CgoJCQkJcmV0dXJuIHg7CgkJCX07CgkJfQoJfTsKCWdldF9jb21wYXRfbWF0aCgpOwoKCXZhciBnZXRfcmFuZG9tX3RleHQgPSBmdW5jdGlvbihsZW5ndGgsIG51bSkgewoJCXZhciB0ZXh0ID0gIiI7CgoJCXdoaWxlICh0ZXh0Lmxlbmd0aCA8IGxlbmd0aCkgewoJCQl2YXIgbmV3bnVtID0gTWF0aF9mbG9vcihNYXRoX3JhbmRvbSgpICogMTBlOCk7CgoJCQl2YXIgbmV3dGV4dDsKCQkJaWYgKCFudW0pIHsKCQkJCW5ld3RleHQgPSBuZXdudW0udG9TdHJpbmcoMjYpOwoJCQl9IGVsc2UgewoJCQkJbmV3dGV4dCA9IG5ld251bS50b1N0cmluZygxMCk7CgkJCX0KCgkJCXRleHQgKz0gbmV3dGV4dDsKCQl9CgoJCXRleHQgPSB0ZXh0LnN1YnN0cigwLCBsZW5ndGgpOwoJCXJldHVybiB0ZXh0OwoJfTsKCgl2YXIgZ2V0X3JhbmRvbV9pZCA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiBnZXRfcmFuZG9tX3RleHQoMTApICsgRGF0ZS5ub3coKTsKCX07CgoJdmFyIGdldF9vcHRpb25zX3BhZ2UgPSBmdW5jdGlvbigpIHsKCQlpZiAoaXNfZXh0ZW5zaW9uKQoJCQlyZXR1cm4gcHJlZmVycmVkX29wdGlvbnNfcGFnZTsKCgkJaWYgKHNldHRpbmdzICYmIHNldHRpbmdzLnVzZV93ZWJhcmNoaXZlX2Zvcl9saWIpIHsKCQkJcmV0dXJuIGFyY2hpdmVfb3B0aW9uc19wYWdlOwoJCX0gZWxzZSB7CgkJCXJldHVybiBwcmVmZXJyZWRfb3B0aW9uc19wYWdlCgkJfQoJfTsKCgl2YXIgaWRfdG9faWZyYW1lID0ge307CgoJLy8gdG9kbzogbW92ZSB0byBkb19tb3VzZW92ZXIKCXZhciBnZXRfZnJhbWVfaW5mbyA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiB7CgkJCWlkOiBjdXJyZW50X2ZyYW1lX2lkLAoJCQkvL3VybDogd2luZG93LmxvY2F0aW9uLmhyZWYsIC8vIGRvZXNuJ3QgZ2V0IHVwZGF0ZWQgZm9yIHRoZSBpZnJhbWUgc3JjJ3MgYXR0cmlidXRlPwoJCQl1cmw6IGN1cnJlbnRfZnJhbWVfdXJsLAoJCQlzaXplOiBbCgkJCQkvL2RvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxXaWR0aCwKCQkJCS8vZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbEhlaWdodAoJCQkJLy8gaW5kYXZpZGVvLmh1IGhhcyBpZnJhbWVzIHdpdGggbW9yZSBoZWlnaHQgdGhhbiB3aGF0IGlzIGRpc3BsYXllZAoJCQkJd2luZG93LmlubmVyV2lkdGgsCgkJCQl3aW5kb3cuaW5uZXJIZWlnaHQKCQkJXQoJCX07Cgl9OwoKCS8vIHRvZG86IG1vdmUgdG8gZG9fbW91c2VvdmVyCgl2YXIgZmluZF9pZnJhbWVfZm9yX2luZm8gPSBmdW5jdGlvbihpbmZvKSB7CgkJaWYgKGluZm8uaWQgaW4gaWRfdG9faWZyYW1lKQoJCQlyZXR1cm4gaWRfdG9faWZyYW1lW2luZm8uaWRdOwoKCQl2YXIgZmluaXNoID0gZnVuY3Rpb24oaWZyYW1lKSB7CgkJCWlmICghaWZyYW1lKQoJCQkJcmV0dXJuIGlmcmFtZTsKCgkJCWlkX3RvX2lmcmFtZVtpbmZvLmlkXSA9IGlmcmFtZTsKCQkJcmV0dXJuIGlmcmFtZTsKCQl9CgoJCXZhciBpZnJhbWVzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImlmcmFtZSIpOwoJCXZhciBuZXdpZnJhbWVzID0gW107CgkJZm9yICh2YXIgaSA9IDA7IGkgPCBpZnJhbWVzLmxlbmd0aDsgaSsrKSB7CgkJCWlmIChpZnJhbWVzW2ldLnNyYyAhPT0gaW5mby51cmwpCgkJCQljb250aW51ZTsKCgkJCW5ld2lmcmFtZXMucHVzaChpZnJhbWVzW2ldKTsKCQl9CgoJCS8vIHVzZWZ1bCBmb3IgbGF0ZXIgaWYgd2UgZG9uJ3QgaGF2ZSB0aGUgbGVuZ3RoIDw9IDEgY2hlY2sKCQl2YXIgaWdub3JlZF9zcmMgPSBmYWxzZTsKCgkJaWYgKG5ld2lmcmFtZXMubGVuZ3RoID09PSAwKSB7CgkJCS8vIGUuZy4gaW5kYXZpZGVvLCBmcmFtZSdzIHNyYyAhPSBpZnJhbWUgc3JjIGJlY2F1c2UgaXQgZ2V0cyByZWRpcmVjdGVkICgvIGF0IHRoZSBlbmQgaXMgcmVtb3ZlZCkKCQkJbmV3aWZyYW1lcyA9IGlmcmFtZXM7CgkJCWlnbm9yZWRfc3JjID0gdHJ1ZTsKCQl9IGVsc2UgaWYgKG5ld2lmcmFtZXMubGVuZ3RoIDw9IDEpIHsKCQkJcmV0dXJuIGZpbmlzaChuZXdpZnJhbWVzWzBdKTsKCQl9CgoJCWlmcmFtZXMgPSBuZXdpZnJhbWVzOwoJCW5ld2lmcmFtZXMgPSBbXTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IGlmcmFtZXMubGVuZ3RoOyBpKyspIHsKCQkJaWYgKGlmcmFtZXNbaV0uc2Nyb2xsV2lkdGggIT09IGluZm8uc2l6ZVswXSB8fAoJCQkJaWZyYW1lc1tpXS5zY3JvbGxIZWlnaHQgIT09IGluZm8uc2l6ZVsxXSkgewoJCQkJY29udGludWU7CgkJCX0KCgkJCW5ld2lmcmFtZXMucHVzaChpZnJhbWVzW2ldKTsKCQl9CgoJCWlmIChuZXdpZnJhbWVzLmxlbmd0aCA8PSAxKQoJCQlyZXR1cm4gZmluaXNoKG5ld2lmcmFtZXNbMF0pOwoKCQkvLyBUT0RPOiBjaGVjayBjdXJzb3IgdG9vCgkJcmV0dXJuIG51bGw7Cgl9OwoKCXZhciBpZnJhbWVfdG9faWQgPSBmdW5jdGlvbihpZnJhbWUpIHsKCQlmb3IgKHZhciBpZCBpbiBpZF90b19pZnJhbWUpIHsKCQkJaWYgKGlkX3RvX2lmcmFtZVtpZF0gPT09IGlmcmFtZSkKCQkJCXJldHVybiBpZDsKCQl9CgoJCXJldHVybiBudWxsOwoJfTsKCgl2YXIgaWRfdG9faWZyYW1lX3dpbmRvdyA9IGZ1bmN0aW9uKGlkKSB7CgkJaWYgKCEoaWQgaW4gaWRfdG9faWZyYW1lKSkKCQkJcmV0dXJuIG51bGw7CgoJCS8vIG5vIG5lZWQgZm9yIGNvbnRlbnRXaW5kb3cgaW4gdG9wCgkJaWYgKGlkICE9PSAidG9wIikgewoJCQl0cnkgewoJCQkJaWYgKGlkX3RvX2lmcmFtZVtpZF0uY29udGVudFdpbmRvdykKCQkJCQlyZXR1cm4gaWRfdG9faWZyYW1lW2lkXS5jb250ZW50V2luZG93OwoJCQl9IGNhdGNoIChlKSB7CgkJCQkvLyBub3QgYWxsb3dlZAoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJfQoKCQlyZXR1cm4gaWRfdG9faWZyYW1lW2lkXTsKCX07CgoJdmFyIHJlbW90ZV9zZW5kX21lc3NhZ2UgPSBudWxsOwoJdmFyIHJlbW90ZV9zZW5kX3JlcGx5ID0gbnVsbDsKCXZhciByZW1vdGVfcmVwbHlfaWRzID0ge307Cgl2YXIgY3VycmVudF9mcmFtZV9pZCA9IG51bGw7Cgl2YXIgY3VycmVudF9mcmFtZV91cmwgPSBudWxsOwoKCXZhciByYXdfcmVtb3RlX3NlbmRfbWVzc2FnZSA9IG51bGw7Cgl2YXIgcmVtb3RlX3NlbmRfbWVzc2FnZSA9IGNvbW1vbl9mdW5jdGlvbnMubnVsbGZ1bmM7Cgl2YXIgcmVtb3RlX3NlbmRfcmVwbHkgPSBjb21tb25fZnVuY3Rpb25zLm51bGxmdW5jOwoJdmFyIGltdV9tZXNzYWdlX2tleSA9ICJfX0lNVV9NRVNTQUdFX18iOwoKCWlmIChpc19leHRlbnNpb24pIHsKCQlyYXdfcmVtb3RlX3NlbmRfbWVzc2FnZSA9IGZ1bmN0aW9uKHRvLCBtZXNzYWdlKSB7CgkJCWV4dGVuc2lvbl9zZW5kX21lc3NhZ2UobWVzc2FnZSkKCQl9OwoKCQlpc19yZW1vdGVfcG9zc2libGUgPSB0cnVlOwoJfSBlbHNlIGlmIChpc19pbnRlcmFjdGl2ZSkgewoJCWlmIChpc19pbl9pZnJhbWUgJiYgd2luZG93LnBhcmVudCkgewoJCQlpZF90b19pZnJhbWVbInRvcCJdID0gd2luZG93LnBhcmVudDsKCQl9CgoJCXJhd19yZW1vdGVfc2VuZF9tZXNzYWdlID0gZnVuY3Rpb24odG8sIG1lc3NhZ2UpIHsKCQkJaWYgKCF0byAmJiBpc19pbl9pZnJhbWUpCgkJCQl0byA9ICJ0b3AiOyAvLyBmaXhtZT8KCgkJCXZhciBzcGVjaWZpZWRfd2luZG93OwoJCQlpZiAodG8gJiYgdG8gaW4gaWRfdG9faWZyYW1lKSB7CgkJCQlzcGVjaWZpZWRfd2luZG93ID0gaWRfdG9faWZyYW1lX3dpbmRvdyh0byk7CgkJCQlpZiAoIXNwZWNpZmllZF93aW5kb3cpIHsKCQkJCQlpZiAoX25pcl9kZWJ1Z18pIHsKCQkJCQkJY29uc29sZV93YXJuKCJVbmFibGUgdG8gZmluZCB3aW5kb3cgZm9yIiwgdG8sIHtpc19pbl9pZnJhbWU6IGlzX2luX2lmcmFtZSwgaWRfdG9faWZyYW1lOiBpZF90b19pZnJhbWV9KTsKCQkJCQl9CgkJCQkJLy8gbm90IGFsbG93ZWQKCQkJCQlyZXR1cm47CgkJCQl9CgkJCX0KCgkJCW1lc3NhZ2UuaW11ID0gdHJ1ZTsKCgkJCXZhciB3cmFwcGVkX21lc3NhZ2UgPSB7fTsKCQkJd3JhcHBlZF9tZXNzYWdlW2ltdV9tZXNzYWdlX2tleV0gPSBtZXNzYWdlOwoKCQkJaWYgKCFzcGVjaWZpZWRfd2luZG93KSB7CgkJCQlmb3IgKHZhciBpID0gMDsgaSA8IHdpbmRvdy5mcmFtZXMubGVuZ3RoOyBpKyspIHsKCQkJCQl0cnkgewoJCQkJCQl3aW5kb3cuZnJhbWVzW2ldLnBvc3RNZXNzYWdlKHdyYXBwZWRfbWVzc2FnZSwgIioiKTsKCQkJCQl9IGNhdGNoIChlKSB7CgkJCQkJCWlmIChfbmlyX2RlYnVnXykgewoJCQkJCQkJY29uc29sZV93YXJuKCJVbmFibGUgdG8gc2VuZCBtZXNzYWdlIHRvIiwgd2luZG93LmZyYW1lc1tpXSwgZSk7CgkJCQkJCX0KCQkJCQkJLy8gbm90IGFsbG93ZWQKCQkJCQkJY29udGludWU7CgkJCQkJfQoJCQkJfQoJCQl9IGVsc2UgewoJCQkJc3BlY2lmaWVkX3dpbmRvdy5wb3N0TWVzc2FnZSh3cmFwcGVkX21lc3NhZ2UsICIqIik7CgkJCX0KCQl9OwoKCQlpc19yZW1vdGVfcG9zc2libGUgPSB0cnVlOwoKCQlpZiAod2luZG93LmxvY2F0aW9uLmhvc3RuYW1lID09PSAiY2FmZS5kYXVtLm5ldCIpIHsKCQkJLy8gdW5mb3J0dW5hdGVseSB0aGV5IGludGVycHJldCBhbGwgbWVzc2FnZSBldmVudHMsIGxlYWRpbmcgdG8gYnVncyBpbiB0aGVpciB3ZWJzaXRlLiB0aGFua3MgdG8gYW1ibGVyIG9uIGRpc2NvcmQgZm9yIG5vdGljaW5nCgkJCWlzX3JlbW90ZV9wb3NzaWJsZSA9IGZhbHNlOwoJCX0KCX0KCglpZiAoaXNfcmVtb3RlX3Bvc3NpYmxlKSB7CgkJY3VycmVudF9mcmFtZV91cmwgPSB3aW5kb3dfbG9jYXRpb247CgkJY3VycmVudF9mcmFtZV9pZCA9IGdldF9yYW5kb21faWQoKSArICIgIiArIGN1cnJlbnRfZnJhbWVfdXJsOwoKCQlpZiAoIWlzX2luX2lmcmFtZSkKCQkJY3VycmVudF9mcmFtZV9pZCA9ICJ0b3AiOwoKCQlyZW1vdGVfc2VuZF9tZXNzYWdlID0gZnVuY3Rpb24odG8sIGRhdGEsIGNiKSB7CgkJCXZhciBpZCA9IHZvaWQgMDsKCgkJCWlmIChjYikgewoJCQkJaWQgPSBnZXRfcmFuZG9tX2lkKCk7CgkJCQlyZW1vdGVfcmVwbHlfaWRzW2lkXSA9IGNiOwoJCQl9CgoJCQl2YXIgbWVzc2FnZSA9IHsKCQkJCXR5cGU6ICJyZW1vdGUiLAoJCQkJZGF0YTogZGF0YSwKCQkJCXRvOiB0bywKCQkJCWZyb206IGN1cnJlbnRfZnJhbWVfaWQsCgkJCQlyZXNwb25zZV9pZDogaWQKCQkJfTsKCgkJCWlmIChfbmlyX2RlYnVnXykgewoJCQkJY29uc29sZV9sb2coInJlbW90ZV9zZW5kX21lc3NhZ2UiLCB0bywgbWVzc2FnZSk7CgkJCX0KCgkJCS8vY29uc29sZV9sb2coInJlbW90ZSIsIGRhdGEpOwoJCQlyYXdfcmVtb3RlX3NlbmRfbWVzc2FnZSh0bywgbWVzc2FnZSk7CgkJfTsKCgkJcmVtb3RlX3NlbmRfcmVwbHkgPSBmdW5jdGlvbih0bywgcmVzcG9uc2VfaWQsIGRhdGEpIHsKCQkJcmF3X3JlbW90ZV9zZW5kX21lc3NhZ2UodG8sIHsKCQkJCXR5cGU6ICJyZW1vdGVfcmVwbHkiLAoJCQkJZGF0YTogZGF0YSwKCQkJCXJlc3BvbnNlX2lkOiByZXNwb25zZV9pZAoJCQl9KTsKCQl9OwoJfQoKCXZhciBjYW5fdXNlX3JlbW90ZSA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiBpc19yZW1vdGVfcG9zc2libGUgJiYgc2V0dGluZ3MuYWxsb3dfcmVtb3RlOwoJfTsKCgl2YXIgY2FuX2lmcmFtZV9wb3BvdXQgPSBmdW5jdGlvbigpIHsKCQlyZXR1cm4gY2FuX3VzZV9yZW1vdGUoKSAmJiBzZXR0aW5ncy5tb3VzZW92ZXJfdXNlX3JlbW90ZTsKCX07CgoJdmFyIGRvX3JlcXVlc3RfYnJvd3NlciA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7CgkJaWYgKF9uaXJfZGVidWdfKSB7CgkJCWNvbnNvbGVfbG9nKCJkb19yZXF1ZXN0X2Jyb3dzZXIiLCByZXF1ZXN0KTsKCQl9CgoJCXZhciBtZXRob2QgPSByZXF1ZXN0Lm1ldGhvZCB8fCAiR0VUIjsKCgkJdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOwoJCXhoci5vcGVuKG1ldGhvZCwgcmVxdWVzdC51cmwsIHRydWUpOwoKCQlpZiAocmVxdWVzdC5yZXNwb25zZVR5cGUpCgkJCXhoci5yZXNwb25zZVR5cGUgPSByZXF1ZXN0LnJlc3BvbnNlVHlwZTsKCgkJaWYgKHJlcXVlc3QuaGVhZGVycykgewoJCQlvYmpfZm9yZWFjaChyZXF1ZXN0LmhlYWRlcnMsIGZ1bmN0aW9uKGhlYWRlcl9uYW1lLCBoZWFkZXJfdmFsdWUpIHsKCQkJCXRyeSB7CgkJCQkJeGhyLnNldFJlcXVlc3RIZWFkZXIoaGVhZGVyX25hbWUsIGhlYWRlcl92YWx1ZSk7CgkJCQl9IGNhdGNoIChlKSB7fQoJCQl9KTsKCQl9CgoJCXZhciBkb19maW5hbCA9IGZ1bmN0aW9uKG92ZXJyaWRlLCBjYikgewoJCQlpZiAoX25pcl9kZWJ1Z18pIHsKCQkJCWNvbnNvbGVfbG9nKCJkb19yZXF1ZXN0X2Jyb3dzZXIncyBkb19maW5hbCIsIHhociwgY2IpOwoJCQl9CgoJCQl2YXIgcmVzcCA9IHsKCQkJCXJlYWR5U3RhdGU6IHhoci5yZWFkeVN0YXRlLAoJCQkJZmluYWxVcmw6IHhoci5yZXNwb25zZVVSTCwKCQkJCXJlc3BvbnNlSGVhZGVyczogeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpLAoJCQkJcmVzcG9uc2VUeXBlOiB4aHIucmVzcG9uc2VUeXBlLAoJCQkJc3RhdHVzOiB4aHIuc3RhdHVzLCAvLyBmaWxlOi8vIHJldHVybnMgMCwgdHJhY2tpbmcgcHJvdGVjdGlvbiBhbHNvIHJldHVybnMgMAoJCQkJc3RhdHVzVGV4dDogeGhyLnN0YXR1c1RleHQsCgkJCQl0aW1lb3V0OiB4aHIudGltZW91dAoJCQl9OwoKCQkJcmVzcC5yZXNwb25zZSA9IHhoci5yZXNwb25zZTsKCgkJCXRyeSB7CgkJCQlyZXNwLnJlc3BvbnNlVGV4dCA9IHhoci5yZXNwb25zZVRleHQ7CgkJCX0gY2F0Y2ggKGUpIHt9CgoJCQljYihyZXNwKTsKCQl9OwoKCQl2YXIgYWRkX2hhbmRsZXIgPSBmdW5jdGlvbihldmVudCwgZW1wdHkpIHsKCQkJeGhyW2V2ZW50XSA9IGZ1bmN0aW9uKCkgewoJCQkJaWYgKGVtcHR5KSB7CgkJCQkJcmV0dXJuIHJlcXVlc3RbZXZlbnRdKG51bGwpOwoJCQkJfQoKCQkJCWRvX2ZpbmFsKHt9LCBmdW5jdGlvbihyZXNwKSB7CgkJCQkJcmVxdWVzdFtldmVudF0ocmVzcCk7CgkJCQl9KTsKCQkJfTsKCQl9OwoKCQlhZGRfaGFuZGxlcigib25sb2FkIik7CgkJYWRkX2hhbmRsZXIoIm9uZXJyb3IiKTsKCQlhZGRfaGFuZGxlcigib25wcm9ncmVzcyIpOwoJCWFkZF9oYW5kbGVyKCJvbmFib3J0IiwgdHJ1ZSk7CgkJYWRkX2hhbmRsZXIoIm9udGltZW91dCIsIHRydWUpOwoKCQl0cnkgewoJCQl4aHIuc2VuZChyZXF1ZXN0LmRhdGEpOwoJCX0gY2F0Y2ggKGUpIHsKCQkJLy8gbmV0OjpFUlJfTkVUV09SS19DSEFOR0VEIGNhbiB0aHJvdyBhbiBlcnJvcgoJCQkvLyB0aGFua3MgdG8gQWRDbGVhcjI0NyBmb3IgcmVwb3J0aW5nOiBodHRwczovL2dpdGh1Yi5jb20vcXNuaXlnL21heHVybC9pc3N1ZXMvNzQ3CgoJCQljb25zb2xlX2Vycm9yKGUpOwoJCQl4aHIuYWJvcnQoKTsKCQl9CgoJCXJldHVybiB7CgkJCWFib3J0OiBmdW5jdGlvbigpIHsKCQkJCXhoci5hYm9ydCgpOwoJCQl9CgkJfTsKCX07CgoJdHJ5IHsKCQlpZiAodHlwZW9mIFhNTEh0dHBSZXF1ZXN0ICE9PSAiZnVuY3Rpb24iKSB7CgkJCWRvX3JlcXVlc3RfYnJvd3NlciA9IG51bGw7CgkJfQoJfSBjYXRjaCAoZSkgewoJCS8vIGFkYmxvY2sgb24gaml6emJ1bmtlci5jb20sIHNlbmRzIGFuIGV4Y2VwdGlvbiB3aXRoIGEgcmFuZG9tIG1hZ2ljIHN0cmluZyBpZiBYTUxIdHRwUmVxdWVzdCBpcyBhY2Nlc3NlZAoJCWRvX3JlcXVlc3RfYnJvd3NlciA9IG51bGw7Cgl9CgoJdmFyIGV4dGVuc2lvbl9yZXF1ZXN0cyA9IHt9OwoKCXZhciBkb19yZXF1ZXN0X3JhdyA9IG51bGw7CglpZiAoaXNfZXh0ZW5zaW9uKSB7CgkJZG9fcmVxdWVzdF9yYXcgPSBmdW5jdGlvbihkYXRhKSB7CgkJCXZhciByZXFpZDsKCQkJdmFyIGRvX2Fib3J0ID0gZmFsc2U7CgoJCQlleHRlbnNpb25fc2VuZF9tZXNzYWdlKHsKCQkJCXR5cGU6ICJyZXF1ZXN0IiwKCQkJCWRhdGE6IGRhdGEKCQkJfSwgZnVuY3Rpb24gKHJlc3BvbnNlKSB7CgkJCQlpZiAocmVzcG9uc2UudHlwZSAhPT0gImlkIikgewoJCQkJCWNvbnNvbGVfZXJyb3IoIkludGVybmFsIGVycm9yOiBXcm9uZyByZXNwb25zZSIsIHJlc3BvbnNlKTsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJcmVxaWQgPSByZXNwb25zZS5kYXRhOwoKCQkJCWV4dGVuc2lvbl9yZXF1ZXN0c1tyZXFpZF0gPSB7CgkJCQkJaWQ6IHJlcWlkLAoJCQkJCWRhdGE6IGRhdGEKCQkJCX07CgoJCQkJaWYgKGRvX2Fib3J0KSB7CgkJCQkJZXh0ZW5zaW9uX3NlbmRfbWVzc2FnZSh7CgkJCQkJCXR5cGU6ICJhYm9ydF9yZXF1ZXN0IiwKCQkJCQkJZGF0YTogcmVxaWQKCQkJCQl9KTsKCgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9KTsKCgkJCXJldHVybiB7CgkJCQlhYm9ydDogZnVuY3Rpb24oKSB7CgkJCQkJaWYgKHJlcWlkID09PSB2b2lkIDApIHsKCQkJCQkJY29uc29sZV93YXJuKCJhYm9ydCgpIHdhcyBjYWxsZWQgYmVmb3JlIHRoZSByZXF1ZXN0IHdhcyBpbml0aWFsaXplZCIpOwoJCQkJCQlkb19hYm9ydCA9IHRydWU7CgkJCQkJCXJldHVybjsKCQkJCQl9CgoJCQkJCWV4dGVuc2lvbl9zZW5kX21lc3NhZ2UoewoJCQkJCQl0eXBlOiAiYWJvcnRfcmVxdWVzdCIsCgkJCQkJCWRhdGE6IHJlcWlkCgkJCQkJfSk7CgkJCQl9CgkJCX07CgkJfTsKCgl9IGVsc2UgaWYgKHR5cGVvZihHTV94bWxodHRwUmVxdWVzdCkgIT09ICJ1bmRlZmluZWQiKSB7CgkJLy8gaWRvbC5zYW5rYWt1Y29tcGxleC5jb20gb3ZlcnJpZGVzIGFycmF5LnByb3RvdHlwZS5yZWR1Y2UKCQkvLyBub3QgYW4gaXNzdWUgZm9yIG5ld2VyIFZpb2xlbnRtb25rZXkgdmVyc2lvbnMKCQlpZiAodXNlcnNjcmlwdF9tYW5hZ2VyID09PSAiVmlvbGVudG1vbmtleSIgJiYgdmVyc2lvbl9jb21wYXJlKHVzZXJzY3JpcHRfbWFuYWdlcl92ZXJzaW9uLCAiMi4xMi43IikgPD0gMCkgewoJCQlkb19yZXF1ZXN0X3JhdyA9IGZ1bmN0aW9uKGRhdGEpIHsKCQkJCXZhciBvcmlnX2NicyA9IHt9OwoKCQkJCXZhciBpc19uYXRpdmUgPSBmdW5jdGlvbih4KSB7CgkJCQkJdmFyIHhfc3RyID0geC50b1N0cmluZygpOwoKCQkJCQlpZiAoeF9zdHIubGVuZ3RoIDwgODAgJiYgc3RyaW5nX2luZGV4b2YoeF9zdHIsICJuYXRpdmUgY29kZSIpID4gMCkgewoJCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCQl9IGVsc2UgewoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfQoJCQkJfQoKCQkJCXZhciByZXZlcnQgPSBbXTsKCgkJCQlpZiAoQXJyYXkucHJvdG90eXBlLnJlZHVjZSAhPT0gYXJyYXlfcmVkdWNlX3Byb3RvdHlwZSAmJiAhaXNfbmF0aXZlKEFycmF5LnByb3RvdHlwZS5yZWR1Y2UpKSB7CgkJCQkJdmFyIG9sZF9yZWR1Y2UgPSBBcnJheS5wcm90b3R5cGUucmVkdWNlOwoKCQkJCQlBcnJheS5wcm90b3R5cGUucmVkdWNlID0gYXJyYXlfcmVkdWNlX3Byb3RvdHlwZTsKCgkJCQkJcmV2ZXJ0LnB1c2goZnVuY3Rpb24oKSB7CgkJCQkJCUFycmF5LnByb3RvdHlwZS5yZWR1Y2UgPSBvbGRfcmVkdWNlOwoJCQkJCX0pOwoJCQkJfQoKCQkJCXZhciByZXZlcnRlZCA9IGZhbHNlOwoJCQkJdmFyIG9uZmluYWwgPSBmdW5jdGlvbih4LCBhcmdzKSB7CgkJCQkJaWYgKCFyZXZlcnRlZCkgewoJCQkJCQlhcnJheV9mb3JlYWNoKHJldmVydCwgZnVuY3Rpb24ocmV2ZXJ0X2Z1bmMpIHsKCQkJCQkJCXJldmVydF9mdW5jKCk7CgkJCQkJCX0pOwoJCQkJCQlyZXZlcnRlZCA9IHRydWU7CgkJCQkJfQoKCQkJCQlyZXR1cm4gb3JpZ19jYnNbeF0uYXBwbHkodGhpcywgYXJncyk7CgkJCQl9OwoKCQkJCWlmIChyZXZlcnQubGVuZ3RoKSB7CgkJCQkJdmFyIHJlcGxhY2UgPSBbIm9ubG9hZCIsICJvbmFib3J0IiwgIm9uZXJyb3IiLCAib250aW1lb3V0Il07CgkJCQkJYXJyYXlfZm9yZWFjaChyZXBsYWNlLCBmdW5jdGlvbih4KSB7CgkJCQkJCWlmICh4IGluIGRhdGEpIHsKCQkJCQkJCW9yaWdfY2JzW3hdID0gZGF0YVt4XTsKCQkJCQkJCWRhdGFbeF0gPSBmdW5jdGlvbigpIHsKCQkJCQkJCQlyZXR1cm4gb25maW5hbCh4LCBhcmd1bWVudHMpOwoJCQkJCQkJfTsKCQkJCQkJfQoJCQkJCX0pOwoJCQkJfQoKCQkJCXJldHVybiBHTV94bWxodHRwUmVxdWVzdChkYXRhKTsKCQkJfTsKCQl9IGVsc2UgewoJCQlkb19yZXF1ZXN0X3JhdyA9IEdNX3htbGh0dHBSZXF1ZXN0OwoJCX0KCX0gZWxzZSBpZiAodHlwZW9mKEdNKSAhPT0gInVuZGVmaW5lZCIgJiYgdHlwZW9mKEdNLnhtbEh0dHBSZXF1ZXN0KSAhPT0gInVuZGVmaW5lZCIpIHsKCQlkb19yZXF1ZXN0X3JhdyA9IEdNLnhtbEh0dHBSZXF1ZXN0OwoJfQoKCXZhciByZWdpc3Rlcl9tZW51Y29tbWFuZCA9IGNvbW1vbl9mdW5jdGlvbnMubnVsbGZ1bmM7Cgl2YXIgdW5yZWdpc3Rlcl9tZW51Y29tbWFuZCA9IGNvbW1vbl9mdW5jdGlvbnMubnVsbGZ1bmM7Cgl2YXIgbnVtX21lbnVjb21tYW5kcyA9IDA7CgoJaWYgKGlzX3VzZXJzY3JpcHQpIHsKCQlpZiAodHlwZW9mKEdNX3JlZ2lzdGVyTWVudUNvbW1hbmQpICE9PSAidW5kZWZpbmVkIikgewoJCQlyZWdpc3Rlcl9tZW51Y29tbWFuZCA9IGZ1bmN0aW9uKG5hbWUsIGZ1bmMpIHsKCQkJCW51bV9tZW51Y29tbWFuZHMrKzsKCgkJCQlpZiAodHlwZW9mIGZ1bmMgPT09ICJzdHJpbmciKSB7CgkJCQkJdmFyIGRlc3QgPSBmdW5jOwoJCQkJCWZ1bmMgPSBmdW5jdGlvbigpIHsKCQkJCQkJLy8gdGhpcyBnZXRzIHJ1biBmb3IgZXZlcnkgZnJhbWUgdGhlIHNjcmlwdCBpcyBpbmplY3RlZCBpbgoJCQkJCQlpZiAoaXNfaW5faWZyYW1lKQoJCQkJCQkJcmV0dXJuOwoKCQkJCQkJb3Blbl9pbl90YWIoZGVzdCk7CgkJCQkJfTsKCQkJCX0KCgkJCQl2YXIgY2FwdGlvbiA9ICJbIiArIG51bV9tZW51Y29tbWFuZHMgKyAiXSAiICsgbmFtZTsKCQkJCXZhciBpZCA9IEdNX3JlZ2lzdGVyTWVudUNvbW1hbmQoY2FwdGlvbiwgZnVuYyk7CgoJCQkJaWYgKGlkID09PSB2b2lkIDAgfHwgaWQgPT09IG51bGwpCgkJCQkJaWQgPSBjYXB0aW9uOwoJCQkJcmV0dXJuIGlkOwoJCQl9OwoJCX0KCgkJaWYgKHR5cGVvZihHTV91bnJlZ2lzdGVyTWVudUNvbW1hbmQpICE9PSAidW5kZWZpbmVkIikgewoJCQl1bnJlZ2lzdGVyX21lbnVjb21tYW5kID0gZnVuY3Rpb24oaWQpIHsKCQkJCW51bV9tZW51Y29tbWFuZHMtLTsKCgkJCQlyZXR1cm4gR01fdW5yZWdpc3Rlck1lbnVDb21tYW5kKGlkKTsKCQkJfTsKCQl9Cgl9CgoJdmFyIG9wZW5faW5fdGFiID0gY29tbW9uX2Z1bmN0aW9ucy5udWxsZnVuYzsKCgkvLyB0b2RvOiBtb3ZlIGJlbG93IHNldHRpbmdzIGZvciBvcHRpb25zIHBhZ2UKCWlmIChpc191c2Vyc2NyaXB0KSB7CgkJaWYgKHR5cGVvZihHTV9vcGVuSW5UYWIpICE9PSAidW5kZWZpbmVkIikgewoJCQlvcGVuX2luX3RhYiA9IEdNX29wZW5JblRhYjsKCQl9IGVsc2UgaWYgKHR5cGVvZihHTSkgIT09ICJ1bmRlZmluZWQiICYmIHR5cGVvZihHTS5vcGVuSW5UYWIpICE9PSAidW5kZWZpbmVkIikgewoJCQlvcGVuX2luX3RhYiA9IEdNLm9wZW5JblRhYjsKCQl9CgoJCWlmIChvcGVuX2luX3RhYiAhPT0gY29tbW9uX2Z1bmN0aW9ucy5udWxsZnVuYykgewoJCQlyZWdpc3Rlcl9tZW51Y29tbWFuZCgiT3B0aW9ucyIsIGdldF9vcHRpb25zX3BhZ2UoKSk7CgkJfQoJfQoKCXZhciBvcGVuX2luX3RhYl9pbXUgPSBmdW5jdGlvbihpbXUsIGJnLCBjYikgewoJCWlmIChpc19leHRlbnNpb24pIHsKCQkJZXh0ZW5zaW9uX3NlbmRfbWVzc2FnZSh7CgkJCQl0eXBlOiAibmV3dGFiIiwKCQkJCWRhdGE6IHsKCQkJCQlpbXU6IGltdSwKCQkJCQliYWNrZ3JvdW5kOiBiZwoJCQkJfQoJCQl9LCBjYik7CgkJfSBlbHNlIGlmIChpc191c2Vyc2NyaXB0ICYmIG9wZW5faW5fdGFiKSB7CgkJCW9wZW5faW5fdGFiKGltdS51cmwsIGJnKTsKCQkJaWYgKGNiKSB7CgkJCQljYigpOwoJCQl9CgkJfQoJfTsKCgl2YXIgY2hlY2tfdHJhY2tpbmdfYmxvY2tlZCA9IGZ1bmN0aW9uKHJlc3VsdCkgewoJCS8vIEZpcmVNb25rZXkgcmV0dXJucyBudWxsIGZvciByZXN1bHQgaWYgYmxvY2tlZAoJCS8vIEdyZWFzZU1vbmtleSByZXR1cm5zIG51bGwgZm9yIHN0YXR1cyBpZiBibG9ja2VkCgkJaWYgKCFyZXN1bHQgfHwgcmVzdWx0LnN0YXR1cyA9PT0gMCB8fCByZXN1bHQuc3RhdHVzID09PSBudWxsKSB7CgkJCWlmIChyZXN1bHQgJiYgcmVzdWx0LmZpbmFsVXJsICYmIC9eZmlsZTpcL1wvLy50ZXN0KHJlc3VsdC5maW5hbFVybCkpCgkJCQlyZXR1cm4gZmFsc2U7CgoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfTsKCgl2YXIgZG9fcmVxdWVzdCA9IG51bGw7CglpZiAoZG9fcmVxdWVzdF9yYXcpIHsKCQlkb19yZXF1ZXN0ID0gZnVuY3Rpb24oZGF0YSkgewoJCQlpZiAoX25pcl9kZWJ1Z18pIHsKCQkJCWNvbnNvbGVfbG9nKCJkb19yZXF1ZXN0IiwgZGVlcGNvcHkoZGF0YSkpOwoJCQl9CgoJCQkvLyBGb3IgY3Jvc3Mtb3JpZ2luIGNvb2tpZXMKCQkJaWYgKCEoIndpdGhDcmVkZW50aWFscyIgaW4gZGF0YSkpIHsKCQkJCWRhdGEud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTsKCQkJfQoKCQkJaWYgKCEoImhlYWRlcnMiIGluIGRhdGEpKSB7CgkJCQlkYXRhLmhlYWRlcnMgPSB7fTsKCQkJfQoKCQkJaWYgKGRhdGEuaW11X21vZGUpIHsKCQkJCXZhciBoZWFkZXJzX3RvX3NldCA9IHt9OwoKCQkJCWlmIChkYXRhLmltdV9tb2RlID09PSAiZG9jdW1lbnQiIHx8IGRhdGEuaW11X21vZGUgPT09ICJpZnJhbWUiKSB7CgkJCQkJaGVhZGVyc190b19zZXQuYWNjZXB0ID0gInRleHQvaHRtbCxhcHBsaWNhdGlvbi94aHRtbCt4bWwsYXBwbGljYXRpb24veG1sO3E9MC45LGltYWdlL3dlYnAsaW1hZ2UvYXBuZywqLyo7cT0wLjgsYXBwbGljYXRpb24vc2lnbmVkLWV4Y2hhbmdlO3Y9YjM7cT0wLjkiOwoJCQkJCWhlYWRlcnNfdG9fc2V0WyJTZWMtRmV0Y2gtRGVzdCJdID0gZGF0YS5pbXVfbW9kZSA9PT0gImRvY3VtZW50IiA/ICJkb2N1bWVudCIgOiAiaWZyYW1lIjsKCQkJCQloZWFkZXJzX3RvX3NldFsiU2VjLUZldGNoLU1vZGUiXSA9ICJuYXZpZ2F0ZSI7CgkJCQkJaGVhZGVyc190b19zZXRbIlNlYy1GZXRjaC1TaXRlIl0gPSBkYXRhLmltdV9tb2RlID09PSAiZG9jdW1lbnQiID8gIm5vbmUiIDogImNyb3NzLXNpdGUiOwoJCQkJCWhlYWRlcnNfdG9fc2V0WyJTZWMtRmV0Y2gtVXNlciJdID0gIj8xIjsKCQkJCX0gZWxzZSBpZiAoZGF0YS5pbXVfbW9kZSA9PT0gInhociIpIHsKCQkJCQloZWFkZXJzX3RvX3NldC5hY2NlcHQgPSAiKi8qIjsKCQkJCQloZWFkZXJzX3RvX3NldFsiU2VjLUZldGNoLURlc3QiXSA9ICJlbXB0eSI7CgkJCQkJaGVhZGVyc190b19zZXRbIlNlYy1GZXRjaC1Nb2RlIl0gPSAiY29ycyI7CgkJCQkJaGVhZGVyc190b19zZXRbIlNlYy1GZXRjaC1TaXRlIl0gPSAic2FtZS1vcmlnaW4iOwoKCQkJCQloZWFkZXJzX3RvX3NldC5vcmlnaW4gPSBkYXRhLnVybC5yZXBsYWNlKC9eKFthLXpdKzpcL1wvW14vXSspKD86XC8rLiopPyQvLCAiJDEiKTsKCQkJCX0gZWxzZSBpZiAoZGF0YS5pbXVfbW9kZSA9PT0gImltYWdlIikgewoJCQkJCWhlYWRlcnNfdG9fc2V0LmFjY2VwdCA9ICJpbWFnZS93ZWJwLGltYWdlL2FwbmcsaW1hZ2UvKiwqLyo7cT0wLjgiOwoJCQkJCWhlYWRlcnNfdG9fc2V0WyJTZWMtRmV0Y2gtRGVzdCJdID0gImltYWdlIjsKCQkJCQloZWFkZXJzX3RvX3NldFsiU2VjLUZldGNoLU1vZGUiXSA9ICJuby1jb3JzIjsKCQkJCQloZWFkZXJzX3RvX3NldFsiU2VjLUZldGNoLVNpdGUiXSA9ICJzYW1lLXNpdGUiOwoJCQkJfSBlbHNlIGlmIChkYXRhLmltdV9tb2RlID09PSAidmlkZW8iKSB7CgkJCQkJaGVhZGVyc190b19zZXQuYWNjZXB0ID0gIiovKiI7CgkJCQkJaGVhZGVyc190b19zZXRbIlNlYy1GZXRjaC1EZXN0Il0gPSAidmlkZW8iOwoJCQkJCWhlYWRlcnNfdG9fc2V0WyJTZWMtRmV0Y2gtTW9kZSJdID0gIm5vLWNvcnMiOwoJCQkJCWhlYWRlcnNfdG9fc2V0WyJTZWMtRmV0Y2gtU2l0ZSJdID0gInNhbWUtc2l0ZSI7CgkJCQl9CgoJCQkJZGVsZXRlIGRhdGEuaW11X21vZGU7CgoJCQkJZm9yICh2YXIgaGVhZGVyIGluIGhlYWRlcnNfdG9fc2V0KSB7CgkJCQkJaWYgKGhlYWRlcm9ial9nZXQoZGF0YS5oZWFkZXJzLCBoZWFkZXIpID09PSB2b2lkIDApIHsKCQkJCQkJaGVhZGVyb2JqX3NldChkYXRhLmhlYWRlcnMsIGhlYWRlciwgaGVhZGVyc190b19zZXRbaGVhZGVyXSk7CgkJCQkJfQoJCQkJfQoJCQl9CgoJCQlpZiAoZGF0YS5pbXVfbXVsdGlwYXJ0KSB7CgkJCQkvL3ZhciBib3VuZGFyeSA9ICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIgKyBnZXRfcmFuZG9tX3RleHQoMjApOwoJCQkJdmFyIGJvdW5kYXJ5ID0gIi0tLS1XZWJLaXRGb3JtQm91bmRhcnkiICsgZ2V0X3JhbmRvbV90ZXh0KDE2KTsKCgkJCQkvLyBUT0RPOiBmaXg/IG9ubHkgdGVzdGVkIGZvciBvbmUga2V5CgkJCQl2YXIgcG9zdGRhdGEgPSAiIjsKCQkJCWZvciAodmFyIGtleSBpbiBkYXRhLmltdV9tdWx0aXBhcnQpIHsKCQkJCQl2YXIgdmFsdWUgPSBkYXRhLmltdV9tdWx0aXBhcnRba2V5XTsKCgkJCQkJcG9zdGRhdGEgKz0gIi0tIiArIGJvdW5kYXJ5ICsgIlxyXG5Db250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9XCIiICsga2V5ICsgIlwiXHJcblxyXG4iOwoJCQkJCXBvc3RkYXRhICs9IHZhbHVlICsgIlxyXG4iOwoJCQkJfQoKCQkJCXBvc3RkYXRhICs9ICItLSIgKyBib3VuZGFyeSArICItLVxyXG4iOwoKCQkJCWhlYWRlcm9ial9zZXQoZGF0YS5oZWFkZXJzLCAiQ29udGVudC1UeXBlIiwgIm11bHRpcGFydC9mb3JtLWRhdGE7IGJvdW5kYXJ5PSIgKyBib3VuZGFyeSk7CgkJCQlkYXRhLmRhdGEgPSBwb3N0ZGF0YTsKCgkJCQlkZWxldGUgZGF0YS5pbXVfbXVsdGlwYXJ0OwoJCQl9CgoJCQl2YXIgb3JpZ19kYXRhID0gZGVlcGNvcHkoZGF0YSk7CgoJCQlpZiAodHlwZW9mIGRhdGEudXJsID09PSAic3RyaW5nIikKCQkJCWRhdGEudXJsID0gZGF0YS51cmwucmVwbGFjZSgvIy4qLywgIiIpOwoKCQkJaWYgKCFkYXRhLm9uZXJyb3IpCgkJCQlkYXRhLm9uZXJyb3IgPSBkYXRhLm9ubG9hZDsKCgkJCWlmICghZGF0YS5vbnRpbWVvdXQpCgkJCQlkYXRhLm9udGltZW91dCA9IGRhdGEub25lcnJvcjsKCgkJCXZhciByYXdfcmVxdWVzdF9kbyA9IGRvX3JlcXVlc3RfcmF3OwoJCQlpZiAoaXNfdXNlcnNjcmlwdCAmJiBzZXR0aW5ncy5hbGxvd19icm93c2VyX3JlcXVlc3QpIHsKCQkJCWlmICh1c2Vyc2NyaXB0X21hbmFnZXIgPT09ICJGYWxrb24gR3JlYXNlTW9ua2V5IiB8fAoJCQkJCS8vIFVTSSBkb2Vzbid0IHByb3Blcmx5IHN1cHBvcnQgYmxvYiByZXNwb25zZXM6IGh0dHBzOi8vYml0YnVja2V0Lm9yZy91c2ktZGV2L3VzaS9pc3N1ZXMvMTMvdmFyaW91cy1wcm9ibGVtcy13aXRoLWdtX3htbGh0dHByZXF1ZXN0CgkJCQkJKHVzZXJzY3JpcHRfbWFuYWdlciA9PT0gIlVTSSIgJiYgZGF0YS5uZWVkX2Jsb2JfcmVzcG9uc2UpKSB7CgkJCQkJcmF3X3JlcXVlc3RfZG8gPSBkb19yZXF1ZXN0X2Jyb3dzZXI7CgkJCQkJZGVsZXRlIGRhdGEudHJhY2tpbmdwcm90ZWN0aW9uX2ZhaWxzYWZlOwoJCQkJfQoJCQl9CgoJCQlpZiAoZGF0YS5yZXRyeV81MDMpIHsKCQkJCWlmIChkYXRhLnJldHJ5XzUwMyA9PT0gdHJ1ZSB8fCB0eXBlb2YgZGF0YS5yZXRyeV81MDMgIT09ICJudW1iZXIiKQoJCQkJCWRhdGEucmV0cnlfNTAzID0gcGFyc2VfaW50KHNldHRpbmdzLnJldHJ5XzUwM190aW1lcyk7CgoJCQkJaWYgKGRhdGEucmV0cnlfNTAzID4gMCkgewoJCQkJCXZhciByZWFsX29ubG9hZF81MDMgPSBkYXRhLm9ubG9hZDsKCQkJCQl2YXIgcmVhbF9vbmVycm9yXzUwMyA9IGRhdGEub25lcnJvcjsKCgkJCQkJdmFyIGZpbmFsY2JfNTAzID0gZnVuY3Rpb24ocmVzcCwgaXNlcnJvcikgewoJCQkJCQlpZiAoX25pcl9kZWJ1Z18pIHsKCQkJCQkJCWNvbnNvbGVfbG9nKCJkb19yZXF1ZXN0J3MgZmluYWxjYl81MDM6IiwgcmVzcCwgaXNlcnJvciwgZGVlcGNvcHkoZGF0YSkpOwoJCQkJCQl9CgoJCQkJCQlpZiAocmVzcC5zdGF0dXMgPT09IDUwMykgewoJCQkJCQkJY29uc29sZV93YXJuKCJSZWNlaXZlZCBzdGF0dXMgNTAzLCByZXRyeWluZyByZXF1ZXN0IiwgcmVzcCwgb3JpZ19kYXRhKTsKCQkJCQkJCW9yaWdfZGF0YS5yZXRyeV81MDMgPSBkYXRhLnJldHJ5XzUwMyAtIDE7CgoJCQkJCQkJc2V0VGltZW91dChmdW5jdGlvbigpIHsKCQkJCQkJCQlkb19yZXF1ZXN0KG9yaWdfZGF0YSk7CgkJCQkJCQl9LCBwYXJzZV9pbnQoc2V0dGluZ3MucmV0cnlfNTAzX21zKSB8fCAxKTsKCQkJCQkJfSBlbHNlIHsKCQkJCQkJCWlmIChpc2Vycm9yKSB7CgkJCQkJCQkJcmVhbF9vbmVycm9yXzUwMyhyZXNwKTsKCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJcmVhbF9vbmxvYWRfNTAzKHJlc3ApOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfTsKCgkJCQkJZGF0YS5vbmxvYWQgPSBmdW5jdGlvbihyZXNwKSB7CgkJCQkJCWZpbmFsY2JfNTAzKHJlc3AsIGZhbHNlKTsKCQkJCQl9OwoKCQkJCQlkYXRhLm9uZXJyb3IgPSBmdW5jdGlvbihyZXNwKSB7CgkJCQkJCWZpbmFsY2JfNTAzKHJlc3AsIHRydWUpOwoJCQkJCX07CgkJCQl9CgkJCX0KCgkJCWlmIChkYXRhLnRyYWNraW5ncHJvdGVjdGlvbl9mYWlsc2FmZSAmJiBzZXR0aW5ncy5hbGxvd19icm93c2VyX3JlcXVlc3QgJiYgZG9fcmVxdWVzdF9icm93c2VyKSB7CgkJCQl2YXIgcmVhbF9vbmxvYWQgPSBkYXRhLm9ubG9hZDsKCQkJCXZhciByZWFsX29uZXJyb3IgPSBkYXRhLm9uZXJyb3I7CgoJCQkJdmFyIGZpbmFsY2IgPSBmdW5jdGlvbihyZXNwLCBpc2Vycm9yKSB7CgkJCQkJaWYgKF9uaXJfZGVidWdfKSB7CgkJCQkJCWNvbnNvbGVfbG9nKCJkb19yZXF1ZXN0J3MgZmluYWxjYjoiLCByZXNwLCBpc2Vycm9yKTsKCQkJCQl9CgoJCQkJCWlmIChjaGVja190cmFja2luZ19ibG9ja2VkKHJlc3ApKSB7CgkJCQkJCS8vIFdvcmthcm91bmQgZm9yIGEgYnVnIGluIEZpcmVNb25rZXkgd2hlcmUgaXQgY2FsbHMgYm90aCBvbmxvYWQgYW5kIG9uZXJyb3I6IGh0dHBzOi8vZ2l0aHViLmNvbS9lcm9zbWFuL3N1cHBvcnQvaXNzdWVzLzEzNAoJCQkJCQlkYXRhLm9ubG9hZCA9IG51bGw7CgkJCQkJCWRhdGEub25lcnJvciA9IG51bGw7CgoJCQkJCQl2YXIgbmV3ZGF0YSA9IHNoYWxsb3djb3B5KGRhdGEpOwoJCQkJCQluZXdkYXRhLm9ubG9hZCA9IHJlYWxfb25sb2FkOwoJCQkJCQluZXdkYXRhLm9uZXJyb3IgPSByZWFsX29uZXJyb3I7CgoJCQkJCQlpZiAobmV3ZGF0YS5pbXVfcmVzcG9uc2VUeXBlID09PSAiYmxvYiIpIHsKCQkJCQkJCW5ld2RhdGEucmVzcG9uc2VUeXBlID0gImJsb2IiOwoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gZG9fcmVxdWVzdF9icm93c2VyKG5ld2RhdGEpOwoJCQkJCX0gZWxzZSB7CgkJCQkJCWlmIChpc2Vycm9yKSB7CgkJCQkJCQlyZWFsX29uZXJyb3IocmVzcCk7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQlyZWFsX29ubG9hZChyZXNwKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX07CgoJCQkJZGF0YS5vbmxvYWQgPSBmdW5jdGlvbihyZXNwKSB7CgkJCQkJZmluYWxjYihyZXNwLCBmYWxzZSk7CgkJCQl9OwoKCQkJCWRhdGEub25lcnJvciA9IGZ1bmN0aW9uKHJlc3ApIHsKCQkJCQlmaW5hbGNiKHJlc3AsIHRydWUpOwoJCQkJfTsKCQkJfQoKCQkJaWYgKGRhdGEucmVzcG9uc2VUeXBlID09PSAiYmxvYiIgJiYgIXNldHRpbmdzLnVzZV9ibG9iX292ZXJfYXJyYXlidWZmZXIpIHsKCQkJCShmdW5jdGlvbihyZWFsX29ubG9hZCkgewoJCQkJCWRhdGEub25sb2FkID0gZnVuY3Rpb24ocmVzcCkgewoJCQkJCQl2YXIgbmV3cmVzcCA9IHJlc3A7CgoJCQkJCQl2YXIgZmluYWwgPSBmdW5jdGlvbigpIHsKCQkJCQkJCWlmIChfbmlyX2RlYnVnXykgewoJCQkJCQkJCWNvbnNvbGVfbG9nKCJkb19yZXF1ZXN0J3MgYXJyYXlidWZmZXItPmJsb2I6IiwgZGVlcGNvcHkocmVzcCksIG5ld3Jlc3ApOwoJCQkJCQkJfQoKCQkJCQkJCXJlYWxfb25sb2FkKG5ld3Jlc3ApOwoJCQkJCQl9OwoKCQkJCQkJaWYgKHJlc3AucmVzcG9uc2UpIHsKCQkJCQkJCXZhciBtaW1lID0gbnVsbDsKCQkJCQkJCS8vIGhhY2sgZm9yIGV4dGVuc2lvbiBmb3IgcGVyZm9ybWFuY2UKCQkJCQkJCWlmIChpc19leHRlbnNpb24gJiYgIl9yZXNwb25zZUVuY29kZWQiIGluIHJlc3AgJiYgcmVzcC5fcmVzcG9uc2VFbmNvZGVkLnR5cGUpIHsKCQkJCQkJCQltaW1lID0gcmVzcC5fcmVzcG9uc2VFbmNvZGVkLnR5cGUKCQkJCQkJCX0gZWxzZSBpZiAocmVzcC5yZXNwb25zZUhlYWRlcnMpIHsKCQkJCQkJCQl2YXIgcGFyc2VkX2hlYWRlcnMgPSBoZWFkZXJzX2xpc3RfdG9fZGljdChwYXJzZV9oZWFkZXJzKHJlc3AucmVzcG9uc2VIZWFkZXJzKSk7CgkJCQkJCQkJaWYgKHBhcnNlZF9oZWFkZXJzWyJjb250ZW50LXR5cGUiXSkgewoJCQkJCQkJCQltaW1lID0gcGFyc2VkX2hlYWRlcnNbImNvbnRlbnQtdHlwZSJdOwoJCQkJCQkJCX0KCQkJCQkJCX0KCgkJCQkJCQluZXdyZXNwID0gc2hhbGxvd2NvcHkocmVzcCk7CgkJCQkJCQl2YXIgYmxvYl9vcHRpb25zID0gdm9pZCAwOwoJCQkJCQkJaWYgKG1pbWUpIHsKCQkJCQkJCQlibG9iX29wdGlvbnMgPSB7dHlwZTogbWltZX07CgkJCQkJCQl9CgoJCQkJCQkJbmV3X2Jsb2IocmVzcC5yZXNwb25zZSwgZnVuY3Rpb24oYmxvYikgewoJCQkJCQkJCW5ld3Jlc3AucmVzcG9uc2UgPSBibG9iOwoJCQkJCQkJCWZpbmFsKCk7CgkJCQkJCQl9LCBibG9iX29wdGlvbnMpOwoJCQkJCQl9IGVsc2UgewoJCQkJCQkJZmluYWwoKTsKCQkJCQkJfQoJCQkJCX07CgkJCQl9KShkYXRhLm9ubG9hZCk7CgoJCQkJZGF0YS5yZXNwb25zZVR5cGUgPSAiYXJyYXlidWZmZXIiOwoJCQkJZGF0YS5pbXVfcmVzcG9uc2VUeXBlID0gImJsb2IiOwoJCQl9CgoJCQlpZiAoX25pcl9kZWJ1Z18pIHsKCQkJCWNvbnNvbGVfbG9nKCJkb19yZXF1ZXN0IChtb2RpZmllZCBkYXRhKToiLCBkZWVwY29weShkYXRhKSk7CgkJCX0KCgkJCXJldHVybiByYXdfcmVxdWVzdF9kbyhkYXRhKTsKCQl9OwoJfSBlbHNlIGlmIChpc19pbnRlcmFjdGl2ZSkgewoJCWNvbnNvbGUud2FybigiVW5hYmxlIHRvIGluaXRpYWxpemUgZG9fcmVxdWVzdCwgbW9zdCBmdW5jdGlvbnMgd2lsbCBsaWtlbHkgZmFpbCIpOwoJfQoKCXZhciBmaXh1cF9maWxlbmFtZSA9IGZ1bmN0aW9uKGZpbGVuYW1lKSB7CgkJdmFyIHNwZWNpYWxfcmVnZXggPSAvWyI8Pi86P1xcKnxcXl0vZzsKCgkJaWYgKHNldHRpbmdzLmZpbGVuYW1lX3JlcGxhY2Vfc3BlY2lhbF91bmRlcnNjb3JlcykKCQkJcmV0dXJuIGZpbGVuYW1lLnJlcGxhY2Uoc3BlY2lhbF9yZWdleCwgIl8iKTsKCgkJcmV0dXJuIGZpbGVuYW1lOwoJfTsKCgl2YXIgZG9fYnJvd3Nlcl9kb3dubG9hZCA9IGZ1bmN0aW9uKGltdSwgZmlsZW5hbWUsIGNiKSB7CgkJaWYgKF9uaXJfZGVidWdfKSB7CgkJCWNvbnNvbGVfbG9nKCJkb19icm93c2VyX2Rvd25sb2FkIiwgaW11LCBmaWxlbmFtZSwgY2IpOwoJCX0KCgkJdmFyIGEgPSBkb2N1bWVudF9jcmVhdGVFbGVtZW50KCJhIik7CgoJCWEuaHJlZiA9IGltdS51cmw7CgoJCWlmIChmaWxlbmFtZSAmJiBmaWxlbmFtZS5sZW5ndGggPiAwKSB7CgkJCWEuc2V0QXR0cmlidXRlKCJkb3dubG9hZCIsIGZpeHVwX2ZpbGVuYW1lKGZpbGVuYW1lKSk7CgkJfSBlbHNlIHsKCQkJdmFyIGF0dHIgPSBkb2N1bWVudC5jcmVhdGVBdHRyaWJ1dGUoImRvd25sb2FkIik7CgkJCWEuc2V0QXR0cmlidXRlTm9kZShhdHRyKTsKCQl9CgoJCWEuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKCQlhLm9uY2xpY2sgPSBmdW5jdGlvbihlKSB7CgkJCWUuc3RvcFByb3BhZ2F0aW9uKCk7CgkJCWUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7CgkJCXJldHVybiB0cnVlOwoJCX07CgoJCWRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7CgkJYS5jbGljaygpOwoKCQlzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewoJCQlkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpOwoJCX0sIDUwMCk7CgoJCWlmIChjYikKCQkJY2IoKTsKCX07CgoJdmFyIGRvX2Rvd25sb2FkID0gZnVuY3Rpb24oaW11LCBmaWxlbmFtZSwgc2l6ZSwgY2IpIHsKCQlpZiAodHJ1ZXx8X25pcl9kZWJ1Z18pIHsKCQkJY29uc29sZV9sb2coImRvX2Rvd25sb2FkIiwgaW11LCBmaWxlbmFtZSwgc2l6ZSwgY2IpOwoJCX0KCgkJaWYgKGZhbHNlKSB7CgkJCXJlcXVlc3RfY2h1bmtlZChpbXUsIHsKCQkJCW9ubG9hZDogZnVuY3Rpb24oZGF0YSkgewoJCQkJCWNvbnNvbGVfbG9nKCJmaW5pc2hlZCIsIGRhdGEpOwoKCQkJCQl2YXIgYmxvYiA9IG5ldyBuYXRpdmVfYmxvYihbZGF0YS5kYXRhXSwgewoJCQkJCQl0eXBlOiBkYXRhLm1pbWUgfHwgdm9pZCAwCgkJCQkJfSk7CgkJCQkJdmFyIG9ianVybCA9IGNyZWF0ZV9vYmplY3R1cmwoYmxvYik7CgoJCQkJCWRvX2Jyb3dzZXJfZG93bmxvYWQoewoJCQkJCQl1cmw6IG9ianVybCwKCQkJCQl9LCBmaWxlbmFtZSwgY2IpOwoKCQkJCQlzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewoJCQkJCQlyZXZva2Vfb2JqZWN0dXJsKG9ianVybCk7CgkJCQkJfSwgNTAwKTsKCQkJCX0sCgkJCQlvbnByb2dyZXNzOiBmdW5jdGlvbihwcm9nb2JqKSB7CgkJCQkJY29uc29sZV9sb2cocHJvZ29iai5wZXJjZW50LCBwcm9nb2JqKTsKCQkJCX0KCQkJfSk7CgkJCXJldHVybjsKCQl9CgoJCXZhciB1c2VfZ21fZG93bmxvYWQgPSBpc191c2Vyc2NyaXB0ICYmIHR5cGVvZiBHTV9kb3dubG9hZCAhPT0gInVuZGVmaW5lZCIgJiYgc2V0dGluZ3MuZW5hYmxlX2dtX2Rvd25sb2FkOwoJCXZhciBnbV9kb3dubG9hZF9tYXggPSBwYXJzZUZsb2F0KHNldHRpbmdzLmdtX2Rvd25sb2FkX21heCkgfHwgMDsKCQlpZiAodXNlX2dtX2Rvd25sb2FkICYmIHNpemUgJiYgZ21fZG93bmxvYWRfbWF4KSB7CgkJCWlmICgoZ21fZG93bmxvYWRfbWF4ICogMTAyNCAqIDEwMjQpIDwgc2l6ZSkgewoJCQkJdXNlX2dtX2Rvd25sb2FkID0gZmFsc2U7CgkJCX0KCQl9CgoJCXZhciBpc19kYXRhID0gZmFsc2U7CgkJaWYgKGltdSAmJiBpbXUudXJsKSB7CgkJCWlzX2RhdGEgPSAvXmRhdGE6Ly50ZXN0KGltdS51cmwpOwoJCX0KCgkJLy8gaGFja3kgYnV0IHdvcmtzIGZvciBub3cKCQlpZiAoaXNfZGF0YSkgewoJCQlyZXR1cm4gZG9fYnJvd3Nlcl9kb3dubG9hZChpbXUsIGZpbGVuYW1lLCBjYik7CgkJfQoKCQlpZiAoaXNfZXh0ZW5zaW9uKSB7CgkJCWV4dGVuc2lvbl9zZW5kX21lc3NhZ2UoewoJCQkJdHlwZTogImRvd25sb2FkIiwKCQkJCWRhdGE6IHsKCQkJCQlpbXU6IGltdSwKCQkJCQlmaWxlbmFtZTogZml4dXBfZmlsZW5hbWUoZmlsZW5hbWUpLAoJCQkJCWZvcmNlX3NhdmVhczogISFzZXR0aW5ncy5lbmFibGVfd2ViZXh0ZW5zaW9uX2Rvd25sb2FkCgkJCQl9CgkJCX0sIGZ1bmN0aW9uKCkgewoJCQkJaWYgKGNiKQoJCQkJCWNiKCk7CgkJCX0pOwoJCX0gZWxzZSBpZiAodXNlX2dtX2Rvd25sb2FkKSB7CgkJCXZhciBoZWFkZXJzOwoKCQkJaWYgKGltdS5oZWFkZXJzKQoJCQkJaGVhZGVycyA9IGhlYWRlcnNfZGljdF90b19saXN0KGltdS5oZWFkZXJzKTsKCgkJCXZhciBkb3dubG9hZF9vYmogPSB7CgkJCQl1cmw6IGltdS51cmwsCgkJCQloZWFkZXJzOiBoZWFkZXJzLAoJCQkJc2F2ZUFzOiB0cnVlLAoJCQkJb25lcnJvcjogZnVuY3Rpb24oZXJyb3IpIHsKCQkJCQlpZiAoZXJyb3IgJiYgZXJyb3IuZXJyb3IgJiYgZXJyb3IuZXJyb3IgIT09ICJub3Rfc3VjY2VlZGVkIikgewoJCQkJCQlkb19icm93c2VyX2Rvd25sb2FkKGltdSwgZmlsZW5hbWUsIGNiKTsKCQkJCQl9CgkJCQl9CgkJCX07CgoJCQlpZiAoZmlsZW5hbWUpIHsKCQkJCWRvd25sb2FkX29iai5uYW1lID0gZml4dXBfZmlsZW5hbWUoZmlsZW5hbWUpOwoJCQl9IGVsc2UgewoJCQkJZG93bmxvYWRfb2JqLm5hbWUgPSAiZG93bmxvYWQiOyAvLyBpdCBjYW4ndCBiZSBibGFuawoJCQl9CgoJCQlpZiAoX25pcl9kZWJ1Z18pIHsKCQkJCWNvbnNvbGVfbG9nKCJHTV9kb3dubG9hZCIsIGRlZXBjb3B5KGRvd25sb2FkX29iaikpOwoJCQl9CgoJCQlHTV9kb3dubG9hZChkb3dubG9hZF9vYmopOwoJCX0gZWxzZSB7CgkJCWRvX2Jyb3dzZXJfZG93bmxvYWQoaW11LCBmaWxlbmFtZSwgY2IpOwoJCX0KCX07CgoJdmFyIGRvX2Jsb2JfZG93bmxvYWQgPSBmdW5jdGlvbihibG9iLCBmaWxlbmFtZSwgY2IpIHsKCQl2YXIgb2JqdXJsID0gY3JlYXRlX29iamVjdHVybChibG9iKTsKCgkJZG9fYnJvd3Nlcl9kb3dubG9hZCh7CgkJCXVybDogb2JqdXJsLAoJCX0sIGZpbGVuYW1lKTsKCgkJc2V0VGltZW91dChmdW5jdGlvbigpIHsKCQkJcmV2b2tlX29iamVjdHVybChvYmp1cmwpOwoJCQlpZiAoY2IpIGNiKCk7CgkJfSwgNTAwKTsKCX07CgoJdmFyIG11bHRpcXVldWUgPSBmdW5jdGlvbihvcHRpb25zLCBjYikgewoJCXZhciBydW5uaW5nID0gZmFsc2U7CgoJCXZhciBjdXJyZW50bHlfcnVubmluZyA9IDA7CgoJCS8vIHRvZG86IHN1cHBvcnQgYWRkaW5nIG5ldyBpdGVtcyBtaWQtcnVuCgkJdmFyIHJ1bl9zaW5nbGUgPSBmdW5jdGlvbigpIHsKCQkJaWYgKCFvcHRpb25zLnF1ZXVlLmxlbmd0aCkgewoJCQkJaWYgKGN1cnJlbnRseV9ydW5uaW5nIDw9IDApIHsKCQkJCQlyZXR1cm4gY2IoKTsKCQkJCX0KCgkJCQlyZXR1cm47CgkJCX0KCgkJCXZhciBpdGVtID0gb3B0aW9ucy5xdWV1ZS5zaGlmdCgpOwoKCQkJY3VycmVudGx5X3J1bm5pbmcrKzsKCQkJb3B0aW9ucy5ydW5uZXIoaXRlbSwgZnVuY3Rpb24oKSB7CgkJCQljdXJyZW50bHlfcnVubmluZy0tOwoJCQkJcnVuX3NpbmdsZSgpOwoJCQl9KTsKCQl9OwoKCQl2YXIgcnVuID0gZnVuY3Rpb24oKSB7CgkJCWlmIChydW5uaW5nKSByZXR1cm47CgkJCXJ1bm5pbmcgPSB0cnVlOwoKCQkJZm9yICh2YXIgaSA9IG9wdGlvbnMuY29uY3VycmVuY3k7IGkgPiAwOyBpLS0pIHsKCQkJCXJ1bl9zaW5nbGUoKTsKCQkJfQoJCX07CgoJCXJldHVybiB7CgkJCWFkZDogZnVuY3Rpb24oeCkgewoJCQkJb3B0aW9ucy5xdWV1ZS5wdXNoKHgpOwoJCQl9LAoJCQlzdGFydDogcnVuCgkJfTsKCX07CgoJdmFyIEltcHJlY2lzZVByb2dyZXNzID0gZnVuY3Rpb24ob3B0aW9ucykgewoJCXRoaXMuZWxlbWVudHNfbnVtID0gb3B0aW9ucy5lbGVtZW50c19udW0gfHwgMDsKCQl0aGlzLnRvdGFsX3NpemUgPSBvcHRpb25zLnRvdGFsX3NpemUgfHwgMDsKCQkvL3RoaXMudG90YWxfc2l6ZV9rbm93biA9IGZhbHNlOwoJCXRoaXMua25vd25fZWxlbWVudHMgPSB7fTsKCQl0aGlzLmZpbmlzaGVkID0gZmFsc2U7CgoJCXZhciBsYXN0X3BlcmNlbnQgPSAwOwoKCQl0aGlzLmNhbGNfY29tcGxldGlvbiA9IGZ1bmN0aW9uKCkgewoJCQl2YXIga25vd25fdG90YWwgPSAwOwoJCQl2YXIga25vd25fbnVtID0gMDsKCQkJdmFyIGtub3duX3Byb2dyZXNzID0gMDsKCQkJdmFyIGFwcHJveCA9IFtdOwoJCQlvYmpfZm9yZWFjaCh0aGlzLmtub3duX2VsZW1lbnRzLCBmdW5jdGlvbihpZCwgb2JqKSB7CgkJCQlpZiAoIW9iai5zaXplICYmIG9iai5wcm9ncmVzc19yYXRpbykgewoJCQkJCWFwcHJveC5wdXNoKG9iaik7CgkJCQkJcmV0dXJuOwoJCQkJfQoKCQkJCWtub3duX3RvdGFsICs9IG9iai5zaXplOwoJCQkJa25vd25fcHJvZ3Jlc3MgKz0gb2JqLnByb2dyZXNzOwoJCQkJa25vd25fbnVtKys7CgkJCX0pOwoKCQkJdmFyIHRvdGFsID0gdGhpcy50b3RhbF9zaXplOwoJCQl2YXIgdG90YWxfYWNjdXJhdGUgPSB0cnVlOwoKCQkJaWYgKGFwcHJveC5sZW5ndGgpIHsKCQkJCXRvdGFsX2FjY3VyYXRlID0gZmFsc2U7CgoJCQkJdmFyIGF2ZXJhZ2VfbGVuZ3RoID0gMTsKCQkJCWlmIChrbm93bl9udW0pIHsKCQkJCQlhdmVyYWdlX2xlbmd0aCA9IGtub3duX3RvdGFsIC8ga25vd25fbnVtOwoJCQkJfQoKCQkJCWFycmF5X2ZvcmVhY2goYXBwcm94LCBmdW5jdGlvbihvYmopIHsKCQkJCQlrbm93bl90b3RhbCArPSBhdmVyYWdlX2xlbmd0aDsKCQkJCQlrbm93bl9wcm9ncmVzcyArPSBvYmoucHJvZ3Jlc3NfcmF0aW8gKiBhdmVyYWdlX2xlbmd0aDsKCQkJCQlrbm93bl9udW0rKzsKCQkJCX0pOwoJCQl9CgoJCQlpZiAoIXRvdGFsKSB7CgkJCQl0b3RhbCA9IGtub3duX3RvdGFsOwoKCQkJCXZhciB1bmtub3duX2NvdW50ID0gdGhpcy5lbGVtZW50c19udW0gLSBrbm93bl9udW07CgkJCQlpZiAodW5rbm93bl9jb3VudCA+IDAgJiYga25vd25fbnVtID4gMCkgewoJCQkJCXRvdGFsICs9IChrbm93bl90b3RhbCAvIGtub3duX251bSkgKiB1bmtub3duX2NvdW50OwoJCQkJCXRvdGFsX2FjY3VyYXRlID0gZmFsc2U7CgkJCQl9CgkJCX0KCgkJCXZhciByZXRvYmogPSB7CgkJCQlwZXJjZW50OiBrbm93bl9wcm9ncmVzcyAvIHRvdGFsLAoJCQkJdG90YWw6IHRvdGFsLAoJCQkJdG90YWxfYWNjdXJhdGU6IHRvdGFsX2FjY3VyYXRlLAoJCQkJbG9hZGVkOiBrbm93bl9wcm9ncmVzcwoJCQl9OwoKCQkJaWYgKHRoaXMuZmluaXNoZWQpIHsKCQkJCXJldG9iai5wZXJjZW50ID0gMTsKCQkJCXJldG9iai5sb2FkZWQgPSByZXRvYmoudG90YWw7CgkJCX0KCgkJCXJldHVybiByZXRvYmo7CgkJfTsKCgkJdGhpcy5fZG9fY2IgPSBmdW5jdGlvbigpIHsKCQkJdmFyIGNvbXBsZXRpb24gPSB0aGlzLmNhbGNfY29tcGxldGlvbigpOwoKCQkJaWYgKGNvbXBsZXRpb24ucGVyY2VudCA9PT0gbGFzdF9wZXJjZW50KSByZXR1cm47CgkJCWxhc3RfcGVyY2VudCA9IGNvbXBsZXRpb24ucGVyY2VudDsKCgkJCW9wdGlvbnMuY2IoY29tcGxldGlvbik7CgkJfTsKCgkJdGhpcy51cGRhdGUgPSBmdW5jdGlvbihpZCwgcHJvZ3Jlc3MsIHNpemUpIHsKCQkJaWYgKCEoaWQgaW4gdGhpcy5rbm93bl9lbGVtZW50cykpIHsKCQkJCXRoaXMua25vd25fZWxlbWVudHNbaWRdID0gewoJCQkJCXByb2dyZXNzOiAwLAoJCQkJCXNpemU6IDAKCQkJCX07CgkJCX0KCgkJCWlmIChzaXplIHx8ICFwcm9ncmVzcykgewoJCQkJdGhpcy5rbm93bl9lbGVtZW50c1tpZF0ucHJvZ3Jlc3MgPSBwcm9ncmVzczsKCQkJCXRoaXMua25vd25fZWxlbWVudHNbaWRdLnNpemUgPSBzaXplOwoJCQl9IGVsc2UgaWYgKHRoaXMua25vd25fZWxlbWVudHNbaWRdLnNpemUpIHsKCQkJCXRoaXMua25vd25fZWxlbWVudHNbaWRdLnByb2dyZXNzID0gcHJvZ3Jlc3MgKiB0aGlzLmtub3duX2VsZW1lbnRzW2lkXS5zaXplOwoJCQl9IGVsc2UgewoJCQkJdGhpcy5rbm93bl9lbGVtZW50c1tpZF0ucHJvZ3Jlc3NfcmF0aW8gPSBwcm9ncmVzczsKCQkJfQoKCQkJdGhpcy5fZG9fY2IoKTsKCQl9OwoKCQl0aGlzLnVwZGF0ZV9wcm9nb2JqID0gZnVuY3Rpb24oaWQsIHByb2dvYmopIHsKCQkJdGhpcy51cGRhdGUoaWQsIHByb2dvYmoubG9hZGVkLCBwcm9nb2JqLnRvdGFsKTsKCQl9OwoKCQl0aGlzLmZpbmlzaF9pZCA9IGZ1bmN0aW9uKGlkKSB7CgkJCXRoaXMudXBkYXRlKGlkLCAxKTsKCQl9OwoKCQl0aGlzLmZpbmlzaCA9IGZ1bmN0aW9uKCkgewoJCQl0aGlzLmZpbmlzaGVkID0gdHJ1ZTsKCgkJCXRoaXMuX2RvX2NiKCk7CgkJfTsKCX07CgoJdmFyIHJlcXVlc3RfY2h1bmtlZCA9IGZ1bmN0aW9uKHhocm9iaiwgb3B0aW9ucykgewoJCWlmICgheGhyb2JqLmhlYWRlcnMpIHsKCQkJeGhyb2JqLmhlYWRlcnMgPSB7fTsKCQl9CgoJCXhocm9iai5yZXNwb25zZVR5cGUgPSAiYXJyYXlidWZmZXIiOwoKCQl2YXIgZG9fcHJvZ3Jlc3MgPSAhIW9wdGlvbnMub25wcm9ncmVzczsKCgkJdmFyIGdldF9jb250ZW50cmFuZ2VfbGVuZ3RoID0gZnVuY3Rpb24oaGVhZGVycykgewoJCQlpZiAoISgiY29udGVudC1yYW5nZSIgaW4gaGVhZGVycykpIHsKCQkJCXJldHVybiBudWxsOwoJCQl9IGVsc2UgewoJCQkJLy8gdG9kbzogaW1wcm92ZQoJCQkJdmFyIHJhbmdlID0gaGVhZGVyc1siY29udGVudC1yYW5nZSJdLnNwbGl0KCIvIik7CgkJCQlyZXR1cm4gcGFyc2VfaW50KHJhbmdlWzFdKTsKCQkJfQoJCX07CgoJCXZhciBkb3dubG9hZF9jaHVuayA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQsIGNiLCBwcm9ncmVzc2NiKSB7CgkJCS8vY29uc29sZV9sb2coImRvd25sb2FkaW5nIiwgc3RhcnQsIGVuZCwgeGhyb2JqLnVybCk7CgoJCQl2YXIgb3Vyb2JqID0gZGVlcGNvcHkoeGhyb2JqKTsKCQkJb3Vyb2JqLm1ldGhvZCA9ICJHRVQiOwoKCQkJdmFyIHJhbmdlX3ZhbHVlID0gImJ5dGVzPSIgKyBzdGFydCArICItIjsKCQkJaWYgKGVuZCkgcmFuZ2VfdmFsdWUgKz0gKGVuZCAtIDEpOwoKCQkJdmFyIGlkID0gc3RhcnQ7CgoJCQloZWFkZXJvYmpfc2V0KG91cm9iai5oZWFkZXJzLCAiUmFuZ2UiLCByYW5nZV92YWx1ZSk7CgoJCQlpZiAocHJvZ3Jlc3NjYikgewoJCQkJb3Vyb2JqLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbihyZXNwKSB7CgkJCQkJaWYgKHJlc3AubG9hZGVkICYmIHJlc3AudG90YWwpIHsKCQkJCQkJdmFyIGhlYWRlcnMgPSBoZWFkZXJzX2xpc3RfdG9fZGljdChwYXJzZV9oZWFkZXJzKHJlc3AucmVzcG9uc2VIZWFkZXJzKSk7CgkJCQkJCXZhciBjb250ZW50bGVuZ3RoID0gZ2V0X2NvbnRlbnRyYW5nZV9sZW5ndGgoaGVhZGVycyk7CgoJCQkJCQlyZXR1cm4gcHJvZ3Jlc3NjYihpZCwgcmVzcC5sb2FkZWQsIHJlc3AudG90YWwsIGNvbnRlbnRsZW5ndGgpOwoJCQkJCX0KCQkJCX07CgoJCQkJb3Vyb2JqLm9ubG9hZCA9IGZ1bmN0aW9uKHJlc3ApIHsKCQkJCQl2YXIgbGVuZ3RoOwoKCQkJCQlpZiAoZW5kKSBsZW5ndGggPSBlbmQgLSBzdGFydDsKCQkJCQlpZiAocmVzcC5yZXNwb25zZSkgbGVuZ3RoID0gcmVzcC5yZXNwb25zZS5ieXRlTGVuZ3RoOyAvLyBwcm9iYWJseSB0aGUgb25seSBvbmUgdGhhdCdzIGFjdHVhbGx5IG5lZWRlZD8KCgkJCQkJaWYgKCFsZW5ndGgpIHsKCQkJCQkJdmFyIGhlYWRlcnMgPSBoZWFkZXJzX2xpc3RfdG9fZGljdChwYXJzZV9oZWFkZXJzKHJlc3AucmVzcG9uc2VIZWFkZXJzKSk7CgkJCQkJCWlmICgiY29udGVudC1sZW5ndGgiIGluIGhlYWRlcnMpIHsKCQkJCQkJCWxlbmd0aCA9IHBhcnNlX2ludChoZWFkZXJzWyJjb250ZW50LWxlbmd0aCJdKTsKCQkJCQkJfQoJCQkJCX0KCgkJCQkJcHJvZ3Jlc3NjYihpZCwgbGVuZ3RoLCBsZW5ndGgpOwoJCQkJCWNiKHJlc3ApOwoJCQkJfTsKCQkJfSBlbHNlIHsKCQkJCW91cm9iai5vbmxvYWQgPSBjYjsKCQkJfQoKCQkJZG9fcmVxdWVzdChvdXJvYmopOwoJCX07CgoJCXZhciBpcCA9IG51bGwsIGNodW5rX3Byb2dyZXNzID0gbnVsbDsKCQlpZiAoZG9fcHJvZ3Jlc3MpIHsKCQkJaXAgPSBuZXcgSW1wcmVjaXNlUHJvZ3Jlc3MoewoJCQkJY2I6IG9wdGlvbnMub25wcm9ncmVzcywKCQkJCWVsZW1lbnRzX251bTogMQoJCQl9KTsKCgkJCWNodW5rX3Byb2dyZXNzID0gZnVuY3Rpb24oaWQsIHByb2dyZXNzLCB0b3RhbCwgZnVsbF90b3RhbCkgewoJCQkJaWYgKCFpcC50b3RhbF9zaXplICYmIGZ1bGxfdG90YWwpIGlwLnRvdGFsX3NpemUgPSBmdWxsX3RvdGFsOwoKCQkJCWlwLnVwZGF0ZShpZCwgcHJvZ3Jlc3MsIHRvdGFsKTsKCQkJfTsKCQl9CgoJCXZhciBkYXRhID0gbnVsbDsKCQl2YXIgbWltZSA9IG51bGw7CgoJCXZhciBmaW5hbF9jYiA9IGZ1bmN0aW9uKHJlc3ApIHsKCQkJaWYgKGRvX3Byb2dyZXNzKSBpcC5maW5pc2goKTsKCQkJb3B0aW9ucy5vbmxvYWQoewoJCQkJZGF0YTogZGF0YSwKCQkJCW1pbWU6IG1pbWUKCQkJfSwgcmVzcCk7CgkJfTsKCgkJdmFyIGNodW5rX3NpemUgPSBvcHRpb25zLmNodW5rX3NpemU7CgkJaWYgKCFjaHVua19zaXplICYmIGNodW5rX3NpemUgIT09IDApCgkJCWNodW5rX3NpemUgPSA1MTIqMTAyNDsKCgkJLy8gdG9kbzogR0VULCBpZiBBY2NlcHQtUmFuZ2VzIGlzIHByZXNlbnQsIGFib3J0LCBzYXZlIHRoZSBjdXJyZW50IHJlc3BvbnNlLCB0aGVuIGdvIHdpdGggY2h1bmtlZAoJCS8vIG1vcmUgaW5mbzogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRUUC9SYW5nZV9yZXF1ZXN0cwoJCS8vIG9yIG1heWJlIGp1c3QgY2hlY2sgMjAwLzIwNiBpbnN0ZWFkCgkJZG93bmxvYWRfY2h1bmsoMCwgY2h1bmtfc2l6ZSwgZnVuY3Rpb24ocmVzcCkgewoJCQl2YXIgaGVhZGVycyA9IGhlYWRlcnNfbGlzdF90b19kaWN0KHBhcnNlX2hlYWRlcnMocmVzcC5yZXNwb25zZUhlYWRlcnMpKTsKCgkJCXZhciBjb250ZW50X2xlbmd0aCA9IDA7CgkJCWlmIChyZXNwLnN0YXR1cyA9PT0gMjAwKSB7CgkJCQljb250ZW50X2xlbmd0aCA9IHJlc3AucmVzcG9uc2UuYnl0ZUxlbmd0aDsKCQkJfSBlbHNlIGlmIChyZXNwLnN0YXR1cyA9PT0gMjA2KSB7CgkJCQljb250ZW50X2xlbmd0aCA9IGdldF9jb250ZW50cmFuZ2VfbGVuZ3RoKGhlYWRlcnMpOwoJCQkJaWYgKGNvbnRlbnRfbGVuZ3RoID09PSBudWxsKSB7CgkJCQkJY29uc29sZV9lcnJvcigiVW5hYmxlIHRvIGZpbmQgbGVuZ3RoIHRocm91Z2ggY29udGVudC1yYW5nZSIpOwoJCQkJCXJldHVybiBvcHRpb25zLm9ubG9hZChudWxsLCByZXNwKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWNvbnNvbGVfZXJyb3IoIkJhZCBzdGF0dXMiLCByZXNwLnN0YXR1cywgcmVzcCk7CgkJCQlyZXR1cm4gb3B0aW9ucy5vbmxvYWQobnVsbCwgcmVzcCk7CgkJCX0KCgkJCWRhdGEgPSBuZXcgVWludDhBcnJheShjb250ZW50X2xlbmd0aCk7CgkJCWRhdGEuc2V0KG5ldyBVaW50OEFycmF5KHJlc3AucmVzcG9uc2UpLCAwKTsKCgkJCWlmIChyZXNwLnJlc3BvbnNlLmJ5dGVMZW5ndGggPj0gY29udGVudF9sZW5ndGgpIHsKCQkJCXJldHVybiBmaW5hbF9jYihyZXNwKTsKCQkJfQoKCQkJaWYgKCJjb250ZW50LXR5cGUiIGluIGhlYWRlcnMpIHsKCQkJCW1pbWUgPSBoZWFkZXJzWyJjb250ZW50LXR5cGUiXTsKCQkJfQoKCQkJaWYgKGRvX3Byb2dyZXNzKSBpcC50b3RhbF9zaXplID0gY29udGVudF9sZW5ndGg7CgkJCS8vY29uc29sZV9sb2coY29udGVudF9sZW5ndGgpOwoKCQkJLy8gdG9kbzogaW5zdGVhZCBvZiB0aGlzLCBtYXliZSBqdXN0IGtlZXAgcnVubmluZyB1bnRpbCAyMDAvbm8gbW9yZSBkYXRhPwoJCQl2YXIgcXVldWUgPSBbXTsKCQkJZm9yICh2YXIgc3RhcnQgPSByZXNwLnJlc3BvbnNlLmJ5dGVMZW5ndGg7OyBzdGFydCArPSBjaHVua19zaXplKSB7CgkJCQl2YXIgdmFsID0gW3N0YXJ0XTsKCgkJCQl2YXIgZG9fYnJlYWsgPSB0cnVlOwoJCQkJaWYgKGNvbnRlbnRfbGVuZ3RoIC0gc3RhcnQgPiBjaHVua19zaXplKSB7CgkJCQkJdmFsLnB1c2goc3RhcnQgKyBjaHVua19zaXplKTsKCQkJCQlkb19icmVhayA9IGZhbHNlOwoJCQkJfQoKCQkJCXF1ZXVlLnB1c2godmFsKTsKCgkJCQlpZiAoZG9fYnJlYWspIGJyZWFrOwoJCQl9CgkJCWlmIChkb19wcm9ncmVzcykgaXAuZWxlbWVudHNfbnVtICs9IHF1ZXVlLmxlbmd0aDsKCgkJCS8vZGF0YS5zZXQobmV3IFVpbnQ4QXJyYXkocmVzcC5yZXNwb25zZSksIDApOwoKCQkJdmFyIG1xdWV1ZSA9IG11bHRpcXVldWUoewoJCQkJY29uY3VycmVuY3k6IG9wdGlvbnMuY2h1bmtzIHx8IDUsCgkJCQlxdWV1ZTogcXVldWUsCgkJCQlydW5uZXI6IGZ1bmN0aW9uKGl0ZW0sIGNiKSB7CgkJCQkJZG93bmxvYWRfY2h1bmsoaXRlbVswXSwgaXRlbVsxXSwgZnVuY3Rpb24ocmVzcCkgewoJCQkJCQkvLyB0b2RvOiBjaGVjayBlcnJvcnMKCQkJCQkJLy9jb25zb2xlX2xvZyhpdGVtWzBdLCBpdGVtWzFdLCByZXNwLnJlc3BvbnNlLmJ5dGVMZW5ndGgsIGNvbnRlbnRfbGVuZ3RoKTsKCQkJCQkJZGF0YS5zZXQobmV3IFVpbnQ4QXJyYXkocmVzcC5yZXNwb25zZSksIGl0ZW1bMF0pOwoJCQkJCQljYigpOwoJCQkJCX0sIGNodW5rX3Byb2dyZXNzKTsKCQkJCX0KCQkJfSwgZnVuY3Rpb24oKSB7CgkJCQlmaW5hbF9jYihyZXNwKTsKCQkJfSk7CgoJCQltcXVldWUuc3RhcnQoKTsKCQl9LCBjaHVua19wcm9ncmVzcyk7Cgl9OwoKCXZhciBuYXRpdmVfY2xpcGJvYXJkX3dyaXRlID0gbnVsbDsKCXZhciBicm93c2VyX2NsaXBib2FyZF93cml0ZSA9IG51bGw7Cgl2YXIgYnJvd3Nlcl9jbGlwYm9hcmRfYXBpX3dyaXRlID0gbnVsbDsKCglpZiAoaXNfaW50ZXJhY3RpdmUpIHsKCQlicm93c2VyX2NsaXBib2FyZF93cml0ZSA9IGZ1bmN0aW9uKGRhdGEsIGNiKSB7CgkJCWlmIChfbmlyX2RlYnVnXykKCQkJCWNvbnNvbGVfbG9nKCJjbGlwYm9hcmRfd3JpdGUgZXhlY2NvbW1hbmQiLCBkYXRhKTsKCgkJCXZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRleHRhcmVhIik7CgoJCQkvLyBkaXNwbGF5OiBub25lIGFuZCB2aXNpYmlsaXR5OiBoaWRkZW4gcHJldmVudCBpdCBmcm9tIGJlaW5nIGNvcGllZCBpbiBjaHJvbWUKCQkJaW5wdXQuc3R5bGUuaGVpZ2h0ID0gIjFweCI7CgkJCWlucHV0LnN0eWxlLndpZHRoID0gIjFweCI7CgkJCWlucHV0LnN0eWxlLnJlc2l6ZSA9ICJub25lIjsKCQkJaW5wdXQuc3R5bGUuYXBwZWFyYW5jZSA9ICJub25lIjsKCQkJaW5wdXQuc3R5bGUuYm9yZGVyID0gMDsKCQkJaW5wdXQuc3R5bGUubWFyZ2luID0gMDsKCQkJaW5wdXQuc3R5bGUucGFkZGluZyA9IDA7CgkJCWlucHV0LnN0eWxlLmRpc3BsYXkgPSAiaW5saW5lIjsKCQkJaW5wdXQuc3R5bGUuY3Vyc29yID0gImRlZmF1bHQiOwoKCQkJZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChpbnB1dCk7CgoJCQlpbnB1dC5pbm5lclRleHQgPSBkYXRhLnRleHQ7CgkJCWlucHV0LmZvY3VzKCk7CgkJCWlucHV0LnNlbGVjdCgpOwoKCQkJc2V0VGltZW91dChmdW5jdGlvbigpIHsKCQkJCWRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoaW5wdXQpOwoJCQl9LCAxMDApOwoKCQkJY2IoISFkb2N1bWVudC5leGVjQ29tbWFuZCgiY29weSIpKTsKCQl9OwoKCQkvLyBmaXJlZm94ICg4MykgZG9lc24ndCB5ZXQgc3VwcG9ydCBjbGlwYm9hcmQud3JpdGUKCQlpZiAobmF2aWdhdG9yLmNsaXBib2FyZCAmJiAobmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZSB8fCBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dCkpIHsKCQkJYnJvd3Nlcl9jbGlwYm9hcmRfYXBpX3dyaXRlID0gZnVuY3Rpb24oZGF0YSwgY2IpIHsKCQkJCWlmIChfbmlyX2RlYnVnXykKCQkJCQljb25zb2xlX2xvZygiY2xpcGJvYXJkX3dyaXRlIGNsaXBib2FyZF9hcGkiLCBkYXRhKTsKCgkJCQl2YXIgcHJvbWlzZTsKCgkJCQl2YXIgY2FuX3VzZV93cml0ZXRleHQgPSBkYXRhLm1pbWUgPT09ICJ0ZXh0L3BsYWluIiAmJiBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dDsKCgkJCQkvLyB0aG91Z2ggd3JpdGVUZXh0IGlzIGEgd3JhcHBlciBvdmVyIHdyaXRlLCBpdCBhbGxvd3MgdXMgdG8gYXZvaWQgY3JlYXRpbmcgYSBibG9iLCB3aGljaCBjYW4gYmUgYW4gaXNzdWUgb24gc29tZSB3ZWJzaXRlcwoJCQkJLy8gZm9yIHNvbWUgcmVhc29uLCBjaHJvbWUgZG9lc24ndCBhbGxvdyBjcmVhdGluZyBhIENsaXBib2FyZEl0ZW0gd2l0aG91dCBhIGJsb2IKCQkJCWlmICghY2FuX3VzZV93cml0ZXRleHQgJiYgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZSAmJiB0eXBlb2YgQ2xpcGJvYXJkSXRlbSA9PT0gImZ1bmN0aW9uIikgewoJCQkJCXZhciBtaW1lcyA9IHt9OwoJCQkJCW1pbWVzW2RhdGEubWltZV0gPSBuZXcgbmF0aXZlX2Jsb2IoW2RhdGEudGV4dF0sIHt0eXBlOiBkYXRhLm1pbWV9KTsKCgkJCQkJdmFyIGl0ZW0gPSBuZXcgQ2xpcGJvYXJkSXRlbShtaW1lcyk7CgkJCQkJcHJvbWlzZSA9IG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGUoW2l0ZW1dKTsKCQkJCX0gZWxzZSBpZiAoY2FuX3VzZV93cml0ZXRleHQpIHsKCQkJCQlwcm9taXNlID0gbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQoZGF0YS50ZXh0KTsKCQkJCX0gZWxzZSB7CgkJCQkJcmV0dXJuIGNiKGZhbHNlKTsKCQkJCX0KCgkJCQlwcm9taXNlLnRoZW4oCgkJCQkJZnVuY3Rpb24oKSB7Y2IodHJ1ZSk7fSwKCQkJCQlmdW5jdGlvbihlKSB7CgkJCQkJCWNvbnNvbGUuZXJyb3IoZSk7CgkJCQkJCWNiKGZhbHNlKTsKCQkJCQl9CgkJCQkpCgkJCX07CgkJfQoJfQoKCWlmIChpc191c2Vyc2NyaXB0KSB7CgkJaWYgKHR5cGVvZiBHTV9zZXRDbGlwYm9hcmQgPT09ICJmdW5jdGlvbiIpIHsKCQkJbmF0aXZlX2NsaXBib2FyZF93cml0ZSA9IGZ1bmN0aW9uKGRhdGEsIGNiKSB7CgkJCQkvLyBWaW9sZW50bW9ua2V5IGRvZXNuJ3Qgc3VwcG9ydCB0aGUgaW5mbyBvYmplY3QgdGhhdCBUYW1wZXJtb25rZXkgc3VwcG9ydHMsIHNvIGp1c3QgdXNlIG1pbWUgYnkgaXRzZWxmCgkJCQlHTV9zZXRDbGlwYm9hcmQoZGF0YS50ZXh0LCBkYXRhLm1pbWUpOwoJCQkJY2IodHJ1ZSk7CgkJCX07CgkJfSBlbHNlIGlmICh0eXBlb2YgR00gPT09ICJvYmplY3QiICYmIHR5cGVvZiBHTS5zZXRDbGlwYm9hcmQgPT09ICJmdW5jdGlvbiIpIHsKCQkJbmF0aXZlX2NsaXBib2FyZF93cml0ZSA9IGZ1bmN0aW9uKGRhdGEsIGNiKSB7CgkJCQlHTS5zZXRDbGlwYm9hcmQoZGF0YS50ZXh0KTsKCQkJCWNiKHRydWUpOwoJCQl9OwoJCX0KCX0KCgl2YXIgY2xpcGJvYXJkX3dyaXRlID0gZnVuY3Rpb24oZGF0YSwgY2IpIHsKCQlpZiAoIWNiKSBjYiA9IG51bGxmdW5jOwoKCQlpZiAodHlwZW9mIGRhdGEgPT09ICJzdHJpbmciKSB7CgkJCWRhdGEgPSB7dGV4dDogZGF0YX07CgkJfQoKCQlpZiAoIWRhdGEubWltZSkgZGF0YS5taW1lID0gInRleHQvcGxhaW4iOwoKCQl2YXIgd3JpdGVycyA9IFsKCQkJbmF0aXZlX2NsaXBib2FyZF93cml0ZSwKCQkJYnJvd3Nlcl9jbGlwYm9hcmRfYXBpX3dyaXRlLAoJCQlicm93c2VyX2NsaXBib2FyZF93cml0ZQoJCV07CgoJCXZhciBkb193cml0ZSA9IGZ1bmN0aW9uKCkgewoJCQl2YXIgd3JpdGVyOwoJCQlmb3IgKHZhciBpID0gMDsgaSA8IHdyaXRlcnMubGVuZ3RoOyBpKyspIHsKCQkJCWlmICghd3JpdGVyc1tpXSkgewoJCQkJCXdyaXRlcnMuc2hpZnQoKTsKCQkJCQlpLS07CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJd3JpdGVyID0gd3JpdGVyc1tpXTsKCQkJCWJyZWFrOwoJCQl9CgoJCQl3cml0ZXIoZGF0YSwgZnVuY3Rpb24oc3VjY2VzcykgewoJCQkJaWYgKHdyaXRlcnMubGVuZ3RoID4gMCAmJiAhc3VjY2VzcykgewoJCQkJCXdyaXRlcnMuc2hpZnQoKTsKCQkJCQlyZXR1cm4gZG9fd3JpdGUoKTsKCQkJCX0KCgkJCQljYihzdWNjZXNzKTsKCQkJfSk7CgkJfTsKCgkJZG9fd3JpdGUoKTsKCX07CgoJLy8gdGhpcyBtaWdodCBiZSBkaWZmZXJlbnQgbGF0ZXIKCXZhciBjbGlwYm9hcmRfd3JpdGVfbGluayA9IGNsaXBib2FyZF93cml0ZTsKCgl2YXIgZ2V0X2Nvb2tpZXMgPSBudWxsOwoJaWYgKGlzX2V4dGVuc2lvbikgewoJCWdldF9jb29raWVzID0gZnVuY3Rpb24odXJsLCBjYikgewoJCQlpZiAoc2V0dGluZ3MuYnJvd3Nlcl9jb29raWVzID09PSBmYWxzZSkgewoJCQkJcmV0dXJuIGNiKG51bGwpOwoJCQl9CgoJCQlleHRlbnNpb25fc2VuZF9tZXNzYWdlKHsKCQkJCXR5cGU6ICJnZXRjb29raWVzIiwKCQkJCWRhdGE6IHt1cmw6IHVybH0KCQkJfSwgZnVuY3Rpb24obWVzc2FnZSkgewoJCQkJY2IobWVzc2FnZS5kYXRhKTsKCQkJfSk7CgkJfTsKCX0gZWxzZSBpZiAoaXNfdXNlcnNjcmlwdCkgewoJCS8vIFRPRE86IHN1cHBvcnQgR01fY29va2llCgkJZ2V0X2Nvb2tpZXMgPSBmdW5jdGlvbih1cmwsIGNiLCBvcHRpb25zKSB7CgkJCWlmIChzZXR0aW5ncy5icm93c2VyX2Nvb2tpZXMgPT09IGZhbHNlKSB7CgkJCQlyZXR1cm4gY2IobnVsbCk7CgkJCX0KCgkJCWlmICghb3B0aW9ucykgewoJCQkJb3B0aW9ucyA9IHt9OwoJCQl9CgoJCQlpZiAob3B0aW9ucy5uZWVkX2Z1bGwpIHsKCQkJCXJldHVybiBjYihudWxsKTsKCQkJfQoKCQkJdmFyIGhvc3RfZG9tYWluID0gZ2V0X2RvbWFpbl9mcm9tX3VybCh3aW5kb3dfbG9jYXRpb24pOwoJCQl2YXIgaG9zdF9kb21haW5fbm9zdWIgPSBnZXRfZG9tYWluX25vc3ViKGhvc3RfZG9tYWluKTsKCgkJCXZhciB1cmxfZG9tYWluID0gZ2V0X2RvbWFpbl9mcm9tX3VybCh1cmwpOwoJCQl2YXIgdXJsX2RvbWFpbl9ub3N1YiA9IGdldF9kb21haW5fbm9zdWIodXJsX2RvbWFpbik7CgoJCQkvLyB0aGlzIGlzIHVnbHkKCQkJaWYgKGhvc3RfZG9tYWluX25vc3ViID09PSB1cmxfZG9tYWluX25vc3ViKSB7CgkJCQljYihjb29raWVzX3N0cl90b19saXN0KGRvY3VtZW50LmNvb2tpZSkpOwoJCQl9IGVsc2UgewoJCQkJY2IobnVsbCk7CgkJCX0KCQl9OwoJfQoKCXZhciBjb29raWVzX3N0cl90b19saXN0ID0gZnVuY3Rpb24oY29va2llc3N0cikgewoJCXZhciBjb29raWVzID0gW107CgoJCXZhciBzcGxpdHRlZCA9IGNvb2tpZXNzdHIuc3BsaXQoLztccyovKTsKCQlhcnJheV9mb3JlYWNoKHNwbGl0dGVkLCBmdW5jdGlvbihrdikgewoJCQl2YXIgbWF0Y2ggPSBrdi5tYXRjaCgvXlxzKihbXj1cc10rKVxzKj1ccyooPzoiKFteIl0rKSJ8KFteIl1cUyopKVxzKiQvKTsKCQkJaWYgKCFtYXRjaCkgewoJCQkJY29uc29sZV93YXJuKCJVbmFibGUgdG8gcGFyc2UgY29va2llIiwga3YpOwoJCQkJcmV0dXJuOwoJCQl9CgoJCQljb29raWVzLnB1c2goe25hbWU6IG1hdGNoWzFdLCB2YWx1ZTogbWF0Y2hbMl0gfHwgbWF0Y2hbM119KTsKCQl9KTsKCgkJcmV0dXJuIGNvb2tpZXM7Cgl9OwoKCXZhciBjb29raWVzX3RvX2h0dHBoZWFkZXIgPSBmdW5jdGlvbihjb29raWVzKSB7CgkJLy8gZGVkdXBsaWNhdGlvbiBhcHBhcmVudGx5IGlzbid0IG5lY2Vzc2FyeSAoYnJvd3NlciBkdXBsaWNhdGVzIHRoZW0gdG9vKQoKCQl2YXIgc3RycyA9IFtdOwoJCWZvciAodmFyIGkgPSAwOyBpIDwgY29va2llcy5sZW5ndGg7IGkrKykgewoJCQl2YXIgc3RyID0gY29va2llc1tpXS5uYW1lICsgIj0iICsgY29va2llc1tpXS52YWx1ZTsKCQkJc3Rycy5wdXNoKHN0cik7CgkJfQoKCQlyZXR1cm4gc3Rycy5qb2luKCI7ICIpOwoJfTsKCgl2YXIgYmlnaW1hZ2VfZmlsdGVyID0gZnVuY3Rpb24oKSB7CgkJcmV0dXJuIHRydWU7Cgl9OwoKCWlmIChpc19pbnRlcmFjdGl2ZSB8fCBpc19leHRlbnNpb25fYmcpIHsKCQliaWdpbWFnZV9maWx0ZXIgPSBmdW5jdGlvbih1cmwpIHsKCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBibGFja2xpc3RfcmVnZXhlcy5sZW5ndGg7IGkrKykgewoJCQkJaWYgKGJsYWNrbGlzdF9yZWdleGVzW2ldLnRlc3QodXJsKSkKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCgkJCXJldHVybiB0cnVlOwoJCX0KCX0KCgl2YXIgZGVmYXVsdF9vcHRpb25zID0gewoJCWZpbGxfb2JqZWN0OiB0cnVlLAoJCW51bGxfaWZfbm9fY2hhbmdlOiBmYWxzZSwKCQljYXRjaF9lcnJvcnM6IHRydWUsCgkJdXNlX2NhY2hlOiB0cnVlLAoJCXVzZV9hcGlfY2FjaGU6IHRydWUsCgkJdXJsY2FjaGVfdGltZTogNjAqNjAsCgkJaXRlcmF0aW9uczogMjAwLAoJCWV4Y2x1ZGVfcHJvYmxlbXM6IFsKCQkJIndhdGVybWFyayIsCgkJCSJzbWFsbGVyIiwKCQkJInBvc3NpYmx5X2RpZmZlcmVudCIsCgkJCSJwb3NzaWJseV9icm9rZW4iCgkJXSwKCQlleGNsdWRlX3ZpZGVvczogZmFsc2UsCgkJaW5jbHVkZV9wYXN0b2JqczogdHJ1ZSwKCQlmb3JjZV9wYWdlOiBmYWxzZSwKCQlhbGxvd190aGlyZHBhcnR5OiBmYWxzZSwKCQlhbGxvd190aGlyZHBhcnR5X2xpYnM6IHRydWUsCgkJYWxsb3dfdGhpcmRwYXJ0eV9jb2RlOiBmYWxzZSwKCQlwcm9jZXNzX2Zvcm1hdDoge30sCgkJZmlsdGVyOiBiaWdpbWFnZV9maWx0ZXIsCgoJCXJ1bGVfc3BlY2lmaWM6IHsKCQkJZGV2aWFudGFydF9wcmVmZXJfc2l6ZTogZmFsc2UsCgkJCWRldmlhbnRhcnRfc3VwcG9ydF9kb3dubG9hZDogdHJ1ZSwKCQkJZWhlbnRhaV9mdWxsX2ltYWdlOiB0cnVlLAoJCQlpbWd1cl9zb3VyY2U6IHRydWUsCgkJCWltZ3VyX25zZndfaGVhZGVyczogbnVsbCwKCQkJaW5zdGFncmFtX3VzZV9hcHBfYXBpOiBmYWxzZSwKCQkJaW5zdGFncmFtX2RvbnRfdXNlX3dlYjogZmFsc2UsCgkJCWluc3RhZ3JhbV9wcmVmZXJfdmlkZW9fcXVhbGl0eTogdHJ1ZSwKCQkJaW5zdGFncmFtX2dhbGxlcnlfcG9zdGxpbms6IGZhbHNlLAoJCQlzbmFwY2hhdF9vcmlnX21lZGlhOiB0cnVlLAoJCQl0aWt0b2tfbm9fd2F0ZXJtYXJrczogZmFsc2UsCgkJCXRpa3Rva190aGlyZHBhcnR5OiBudWxsLAoJCQl0dW1ibHJfYXBpX2tleTogbnVsbCwKCQkJbGlua2VkX2ltYWdlOiBmYWxzZSwKCQl9LAoKCQlkb19yZXF1ZXN0OiBkb19yZXF1ZXN0LAoJCWdldF9jb29raWVzOiBnZXRfY29va2llcywKCQlob3N0X3VybDogbnVsbCwKCQlkb2N1bWVudDogbnVsbCwKCQl3aW5kb3c6IG51bGwsCgkJZWxlbWVudDogbnVsbCwKCgkJY2I6IG51bGwKCX07CgoJdmFyIGRlZmF1bHRfb2JqZWN0ID0gewoJCXVybDogbnVsbCwKCQlhbHdheXNfb2s6IGZhbHNlLAoJCWxpa2VseV9icm9rZW46IGZhbHNlLAoJCWNhbl9oZWFkOiB0cnVlLAoJCWNhbl9tdWx0aXBsZV9yZXF1ZXN0OiB0cnVlLAoJCWhlYWRfb2tfZXJyb3JzOiBbXSwKCQloZWFkX3dyb25nX2NvbnRlbnR0eXBlOiBmYWxzZSwKCQloZWFkX3dyb25nX2NvbnRlbnRsZW5ndGg6IGZhbHNlLAoJCW5lZWRfYmxvYjogZmFsc2UsCgkJbmVlZF9kYXRhX3VybDogZmFsc2UsCgkJd2FpdGluZzogZmFsc2UsCgkJcmVkaXJlY3RzOiBmYWxzZSwKCQlmb3JjZXNfZG93bmxvYWQ6IGZhbHNlLAoJCWlzX3ByaXZhdGU6IGZhbHNlLAoJCWlzX3BhZ2VsaW5rOiBmYWxzZSwKCQlpc19vcmlnaW5hbDogZmFsc2UsCgkJbm9yZWN1cnNlOiBmYWxzZSwKCQlmb3JjZXJlY3Vyc2U6IGZhbHNlLAoJCWNhbl9jYWNoZTogdHJ1ZSwKCQliYWQ6IGZhbHNlLAoJCWJhZF9pZjogW10sCgkJZmFrZTogZmFsc2UsCgkJbWVkaWFfaW5mbzogewoJCQl0eXBlOiAiaW1hZ2UiLCAvLyAiaW1hZ2UiIG9yICJ2aWRlbyIKCQkJZGVsaXZlcnk6IG51bGwgLy8gImhscyIgb3IgImRhc2giCgkJfSwKCQl2aWRlbzogZmFsc2UsIC8vIGRlcHJlY2F0ZWQKCQlhbGJ1bV9pbmZvOiBudWxsLAoJCWhlYWRlcnM6IHt9LAoJCS8vIGhvc3QgdXJsIHRvIGNvcHkgY29va2llcyBmcm9tCgkJY29va2llX3VybDogbnVsbCwKCQkvLyB3aGV0aGVyIGNyZWRlbnRpYWxzIG5lZWQgdG8gYmUgc2VudC4gdGhpcyBpcyBtYWlubHkgYWRkZWQgZm9yIHJ1bGVzIHRvIHNwZWNpZnkgdGhhdCBjcmVkZW50aWFscyBhcmUgbm90IG5lZWRlZCAoZS5nLiB3aGVuIHVzaW5nIGNkbnMpCgkJbmVlZF9jcmVkZW50aWFsczogdHJ1ZSwKCQkvLyBvdmVycmlkZXMgdGhlIGNvbnRlbnQgdHlwZSBmb3Igd2Vic2l0ZXMgdGhhdCBzZW5kIHRoZSB3cm9uZyBvbmUKCQljb250ZW50X3R5cGU6IG51bGwsCgkJLy8gbWF4aW11bSBhbW91bnQgb2YgY2h1bmtzIGZvciBkb3dubG9hZGluZywgMCBtZWFucyB1bmxpbWl0ZWQKCQltYXhfY2h1bmtzOiAwLAoJCXJlZmVyZXJfb2s6IHsKCQkJc2FtZV9kb21haW46IGZhbHNlLAoJCQlzYW1lX2RvbWFpbl9ub3N1YjogZmFsc2UKCQl9LAoJCWV4dHJhOiB7CgkJCXBhZ2U6IG51bGwsCgkJCWNhcHRpb246IG51bGwsCgkJCWNyZWF0ZWRfZGF0ZTogbnVsbCwKCQkJdXBkYXRlZF9kYXRlOiBudWxsLAoJCQlhdXRob3JfdXNlcm5hbWU6IG51bGwsCgkJCWlkOiBudWxsCgkJfSwKCQlmaWxlbmFtZTogIiIsCgkJcHJvYmxlbXM6IHsKCQkJd2F0ZXJtYXJrOiBmYWxzZSwKCQkJc21hbGxlcjogZmFsc2UsCgkJCXBvc3NpYmx5X2RpZmZlcmVudDogZmFsc2UsCgkJCXBvc3NpYmx5X2Jyb2tlbjogZmFsc2UsCgkJCXBvc3NpYmx5X3Vwc2NhbGVkOiBmYWxzZSwKCQkJYnJ1dGVmb3JjZTogZmFsc2UKCQl9Cgl9OwoKCWZ1bmN0aW9uIGlzX2VsZW1lbnQoeCkgewoJCWlmICgheCB8fCB0eXBlb2YgeCAhPT0gIm9iamVjdCIpCgkJCXJldHVybiBmYWxzZTsKCgkJaWYgKCgibmFtZXNwYWNlVVJJIiBpbiB4KSAmJiAoIm5vZGVUeXBlIiBpbiB4KSAmJiAoIm5vZGVOYW1lIiBpbiB4KSAmJiAoImNoaWxkTm9kZXMiIGluIHgpKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLy8gd2luZG93CgkJaWYgKHR5cGVvZiB4LkhUTUxFbGVtZW50ID09PSAiZnVuY3Rpb24iICYmIHR5cGVvZiB4Lm5hdmlnYXRvciA9PT0gIm9iamVjdCIpIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkvLyB2ZXJ5IHNsb3cKCQlpZiAoaXNfaW50ZXJhY3RpdmUpIHsKCQkJaWYgKCh4IGluc3RhbmNlb2YgTm9kZSkgfHwKCQkJCSh4IGluc3RhbmNlb2YgRWxlbWVudCkgfHwKCQkJCSh4IGluc3RhbmNlb2YgSFRNTERvY3VtZW50KSB8fAoJCQkJKHggaW5zdGFuY2VvZiBXaW5kb3cpKSB7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoKCWZ1bmN0aW9uIGlzX2l0ZXJhYmxlX29iamVjdCh4KSB7CgkJcmV0dXJuIHR5cGVvZiB4ID09PSAib2JqZWN0IiAmJiB4ICE9PSBudWxsICYmICFpc19hcnJheSh4KSAmJiAhaXNfZWxlbWVudCh4KTsKCX0KCgl2YXIgc2hhbGxvd2NvcHlfb2JqID0gZnVuY3Rpb24oeCkgewoJCXJlc3VsdCA9IHt9OwoKCQlmb3IgKHZhciBrZXkgaW4geCkgewoJCQlyZXN1bHRba2V5XSA9IHhba2V5XTsKCQl9CgkJcmV0dXJuIHJlc3VsdDsKCX07CgoJaWYgKCJhc3NpZ24iIGluIE9iamVjdCkgewoJCS8vIEZJWE1FOiBzaG91bGQgdGhpcyBiZSBrZXB0PyBpdCdzIGZhc3RlciwgYnV0IGl0IGNhdXNlcyBpc3N1ZXMgd2l0aCBvYmplY3QgaW5zdGFuY2VzLCBsaWtlIGRvbSByZWN0cy4gaXQgd29ya3MgZmluZSB3aXRoIHBsYWluIG9iamVjdHMgdGhvdWdoCgkJLy8gaXQncyBhYm91dCBhcyBnb29kIGFzIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoeCkpLCBidXQgc2hhbGxvdwoJCXNoYWxsb3djb3B5X29iaiA9IGZ1bmN0aW9uKHgpIHsKCQkJcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHgpOwoJCX07Cgl9CgoJZnVuY3Rpb24gc2hhbGxvd2NvcHkoeCkgewoJCXZhciByZXN1bHQgPSB4OwoKCQlpZiAoIWlzX2l0ZXJhYmxlX29iamVjdCh4KSkgewoJCQlyZXR1cm4gcmVzdWx0OwoJCX0gZWxzZSBpZiAoaXNfYXJyYXkoeCkpIHsKCQkJcmVzdWx0ID0gW107CgkJCWZvciAodmFyIGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykgewoJCQkJdmFyIGl0ZW0gPSB4W2ldOwoJCQkJcmVzdWx0LnB1c2goaXRlbSk7CgkJCX0KCQkJcmV0dXJuIHJlc3VsdDsKCQl9IGVsc2UgaWYgKHR5cGVvZiB4ID09PSAib2JqZWN0IikgewoJCQlyZXR1cm4gc2hhbGxvd2NvcHlfb2JqKHgpOwoJCX0KCgkJcmV0dXJuIHJlc3VsdDsKCX0KCglmdW5jdGlvbiBkZWVwY29weSh4LCBvcHRpb25zKSB7CgkJaWYgKCFvcHRpb25zKQoJCQlvcHRpb25zID0ge307CgkJaWYgKCFvcHRpb25zLmhpc3RvcnkpCgkJCW9wdGlvbnMuaGlzdG9yeSA9IFtdOwoKCQl2YXIgcmVzdWx0OwoKCQlpZiAodHlwZW9mIHggPT09ICJzdHJpbmciIHx8IHggPT09IG51bGwgfHwgdHlwZW9mIHggPT09ICJ1bmRlZmluZWQiKSB7CgkJCXJldHVybiB4OwoJCX0gZWxzZSBpZiAoaXNfZWxlbWVudCh4KSB8fCB4IGluc3RhbmNlb2YgUmVnRXhwKSB7CgkJCWlmIChvcHRpb25zLmpzb24pIHsKCQkJCXJldHVybiB2b2lkIDA7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm4geDsKCQkJfQoJCX0gZWxzZSBpZiAodHlwZW9mIHggPT09ICJmdW5jdGlvbiIpIHsKCQkJaWYgKG9wdGlvbnMuanNvbikgewoJCQkJcmV0dXJuIHZvaWQgMDsKCQkJfSBlbHNlIHsKCQkJCXJldHVybiB4OwoJCQl9CgkJfSBlbHNlIGlmICh0eXBlb2YgeCA9PT0gIm9iamVjdCIpIHsKCQkJaWYgKGFycmF5X2luZGV4b2Yob3B0aW9ucy5oaXN0b3J5LCB4KSA+PSAwKQoJCQkJcmV0dXJuOwoJCQllbHNlCgkJCQlvcHRpb25zLmhpc3RvcnkucHVzaCh4KTsKCgkJCWlmIChpc19hcnJheSh4KSkgewoJCQkJcmVzdWx0ID0gW107CgkJCQlmb3IgKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyBpKyspIHsKCQkJCQl2YXIgaXRlbSA9IHhbaV07CgkJCQkJcmVzdWx0LnB1c2goZGVlcGNvcHkoaXRlbSwgb3B0aW9ucykpOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJcmVzdWx0ID0ge307CgkJCQlmb3IgKHZhciBrZXkgaW4geCkgewoJCQkJCXRyeSB7CgkJCQkJCXJlc3VsdFtrZXldID0gZGVlcGNvcHkoeFtrZXldLCBvcHRpb25zKTsKCQkJCQl9IGNhdGNoIChlKSB7CgkJCQkJCXJlc3VsdFtrZXldID0geFtrZXldOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJcmV0dXJuIHJlc3VsdDsKCQl9IGVsc2UgewoJCQlyZXR1cm4geDsKCQl9Cgl9CgoJdmFyIHNlcmlhbGl6ZV9ldmVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7CgkJcmV0dXJuIGRlZXBjb3B5KGV2ZW50LCB7anNvbjogdHJ1ZX0pOwoJfTsKCgl2YXIgZ2V0X25vbnNlbnNpdGl2ZV9zZXR0aW5ncyA9IGZ1bmN0aW9uKCkgewoJCXZhciBuZXdfc2V0dGluZ3MgPSBKU09OX3BhcnNlKEpTT05fc3RyaW5naWZ5KHNldHRpbmdzKSk7CgoJCWZvciAodmFyIGkgPSAwOyBpIDwgc2Vuc2l0aXZlX3NldHRpbmdzLmxlbmd0aDsgaSsrKSB7CgkJCWRlbGV0ZSBuZXdfc2V0dGluZ3Nbc2Vuc2l0aXZlX3NldHRpbmdzW2ldXTsKCQl9CgoJCXJldHVybiBuZXdfc2V0dGluZ3M7Cgl9OwoKCS8vIE5vdGU6IE5vbmUgb2YgdGhpcyBpbmZvcm1hdGlvbiBpcyBhdXRvbWF0aWNhbGx5IHNlbnQgYW55d2hlcmUsIGl0J3Mgb25seSBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIgd2hlbiBzb21ldGhpbmcgY3Jhc2hlcy4KCXZhciBnZXRfY3Jhc2hsb2dfaW5mbyA9IGZ1bmN0aW9uKCkgewoJCXZhciB1YSA9ICIiOwoJCXRyeSB7dWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDt9IGNhdGNoIChlKSB7fQoKCQl2YXIgaW11X3ZlcnNpb24gPSAiKCEhIVVOS05PV04sIFBMRUFTRSBGSUxMIElOISEhKVxuIjsKCQl0cnkge2ltdV92ZXJzaW9uID0gZ21faW5mby5zY3JpcHQudmVyc2lvbjt9IGNhdGNoIChlKSB7fQoKCQl2YXIgb3VyX3NldHRpbmdzX3RleHQgPSAiKHVuYWJsZSB0byBmaW5kKSI7CgkJdHJ5IHtvdXJfc2V0dGluZ3NfdGV4dCA9IEpTT05fc3RyaW5naWZ5KGdldF9ub25zZW5zaXRpdmVfc2V0dGluZ3MoKSk7fSBjYXRjaCAoZSkge30KCgkJdmFyIGtleXMgPSBbCgkJCSJVc2VyIGFnZW50OiAiICsgdWEsCgkJCSJJcyB1c2Vyc2NyaXB0OiAiICsgaXNfdXNlcnNjcmlwdCwKCQkJIklzIGFkZG9uOiAiICsgaXNfZXh0ZW5zaW9uLAoJCQkiSW1hZ2UgTWF4IFVSTCB2ZXJzaW9uOiAiICsgaW11X3ZlcnNpb24sCgkJCSJTZXR0aW5nczogIiArIG91cl9zZXR0aW5nc190ZXh0CgkJXTsKCgkJaWYgKGlzX3VzZXJzY3JpcHQpIHsKCQkJdHJ5IHsKCQkJCWtleXMucHVzaCgiVXNlcnNjcmlwdCBtYW5hZ2VyOiAiICsgdXNlcnNjcmlwdF9tYW5hZ2VyKTsKCQkJCWtleXMucHVzaCgiVXNlcnNjcmlwdCBtYW5hZ2VyIHZlcnNpb246ICIgKyB1c2Vyc2NyaXB0X21hbmFnZXJfdmVyc2lvbik7CgkJCX0gY2F0Y2ggKGUpIHt9CgkJfQoKCQlyZXR1cm4ga2V5cy5qb2luKCJcbiIpOwoJfTsKCglmdW5jdGlvbiBvdmVybGF5X29iamVjdChiYXNlLCBvYmopIHsKCQlpZiAodHlwZW9mIGJhc2UgPT09ICJmdW5jdGlvbiIgfHwgaXNfYXJyYXkoYmFzZSkpCgkJCXJldHVybiBvYmo7IC8vIEZJWE1FPwoKCQlpZiAodHlwZW9mIGJhc2UgPT09ICJvYmplY3QiKSB7CgkJCWlmICh0eXBlb2Ygb2JqICE9PSAib2JqZWN0IikKCQkJCXJldHVybiBvYmo7CgoJCQlmb3IgKHZhciBrZXkgaW4gb2JqKSB7CgkJCQlpZiAoa2V5IGluIGJhc2UpIHsKCQkJCQliYXNlW2tleV0gPSBvdmVybGF5X29iamVjdChiYXNlW2tleV0sIG9ialtrZXldKTsKCQkJCX0gZWxzZSB7CgkJCQkJYmFzZVtrZXldID0gb2JqW2tleV07CgkJCQl9CgkJCX0KCgkJCXJldHVybiBiYXNlOwoJCX0KCgkJcmV0dXJuIG9iajsKCX0KCgl2YXIgcGFyc2VfYm9vbGVhbiA9IGZ1bmN0aW9uKGJvb2wpIHsKCQlpZiAoYm9vbCA9PT0gInRydWUiIHx8IGJvb2wgPT09IHRydWUgfHwgYm9vbCA9PT0gMSkKCQkJcmV0dXJuIHRydWU7CgoJCWlmIChib29sID09PSAiZmFsc2UiIHx8IGJvb2wgPT09IGZhbHNlIHx8IGJvb2wgPT09IDApCgkJCXJldHVybiBmYWxzZTsKCgkJcmV0dXJuOwoJfTsKCgkvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjU2MDM2MzAKCWZ1bmN0aW9uIGdldF9sYW5ndWFnZSgpIHsKCQlpZiAodHlwZW9mIG5hdmlnYXRvciA9PT0gInVuZGVmaW5lZCIpCgkJCXJldHVybiAiZW4iOwoKCQlpZiAobmF2aWdhdG9yLmxhbmd1YWdlcykKCQkJcmV0dXJuIG5hdmlnYXRvci5sYW5ndWFnZXNbMF07CgoJCXJldHVybiBuYXZpZ2F0b3IubGFuZ3VhZ2UgfHwgbmF2aWdhdG9yLnVzZXJMYW5ndWFnZTsKCX0KCgl2YXIgc3VwcG9ydGVkX2xhbmd1YWdlcyA9IFsKCQkiZW4iLAoJCSJlcyIsCgkJImZyIiwKCQkiaXQiLAoJCSJrbyIsCgkJInJ1IgoJXTsKCgl2YXIgYnJvd3Nlcl9sYW5ndWFnZSA9ICJlbiI7Cgl0cnkgewoJCWJyb3dzZXJfbGFuZ3VhZ2UgPSBnZXRfbGFuZ3VhZ2UoKS50b0xvd2VyQ2FzZSgpOwoJCWlmIChhcnJheV9pbmRleG9mKHN1cHBvcnRlZF9sYW5ndWFnZXMsIGJyb3dzZXJfbGFuZ3VhZ2UpIDwgMCkgewoJCQlicm93c2VyX2xhbmd1YWdlID0gYnJvd3Nlcl9sYW5ndWFnZS5yZXBsYWNlKC8tLiovLCAiIik7CgkJCWlmIChhcnJheV9pbmRleG9mKHN1cHBvcnRlZF9sYW5ndWFnZXMsIGJyb3dzZXJfbGFuZ3VhZ2UpIDwgMCkKCQkJCWJyb3dzZXJfbGFuZ3VhZ2UgPSAiZW4iOwoJCX0KCX0gY2F0Y2ggKGUpIHsKCQljb25zb2xlX2Vycm9yKGUpOwoKCQkvLyBqdXN0IGluIGNhc2UKCQlpZiAoYXJyYXlfaW5kZXhvZihzdXBwb3J0ZWRfbGFuZ3VhZ2VzLCBicm93c2VyX2xhbmd1YWdlKSA8IDApCgkJCWJyb3dzZXJfbGFuZ3VhZ2UgPSAiZW4iOwoJfQoKCS8vIFRoaXMgc2VjdGlvbiBpcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCB1c2luZyB0b29scy91cGRhdGVfZnJvbV9wby5qcy4KCS8vIFRvIG1vZGlmeSB0cmFuc2xhdGlvbnMsIGVkaXQgdGhlIHJlc3BlY3RpdmUgLnBvIGZpbGUgdW5kZXIgdGhlIHBvIHN1YmRpcmVjdG9yeS4KCS8vIFJlZmVyIHRvIHRoZSBUcmFuc2xhdGlvbnMgc2VjdGlvbiBpbiBDT05UUklCVVRJTkcubWQgZm9yIG1vcmUgaW5mb3JtYXRpb24uCgl2YXIgc3RyaW5ncyA9IHsKCQkib3B0aW9uc19oZWFkZXIiOiB7CgkJCSJlbiI6ICJPcHRpb25zIiwKCQkJImVzIjogIk9wY2lvbmVzIiwKCQkJIml0IjogIk9wemlvbmkiLAoJCQkia28iOiAiXHVDNjM1XHVDMTU4IiwKCQkJInJ1IjogIlx1MDQxRlx1MDQzMFx1MDQ0MFx1MDQzMFx1MDQzQ1x1MDQzNVx1MDQ0Mlx1MDQ0MFx1MDQ0QiIKCQl9LAoJCSJ5ZXMiOiB7CgkJCSJlbiI6ICJZZXMiLAoJCQkiZXMiOiAiU1x1MDBFRCIsCgkJCSJmciI6ICJPdWkiLAoJCQkiaXQiOiAiU1x1MDBFQyIsCgkJCSJrbyI6ICJcdUM2MDgiLAoJCQkicnUiOiAiXHUwNDE0XHUwNDMwIgoJCX0sCgkJIm5vIjogewoJCQkiZW4iOiAiTm8iLAoJCQkiZXMiOiAiTm8iLAoJCQkiZnIiOiAiTm9uIiwKCQkJIml0IjogIk5vIiwKCQkJImtvIjogIlx1QzU0NFx1QjJDOFx1QzYyNCIsCgkJCSJydSI6ICJcdTA0MURcdTA0MzVcdTA0NDIiCgkJfSwKCQkiSW1wb3J0IjogewoJCQkiaXQiOiAiSW1wb3J0YSIsCgkJCSJrbyI6ICJcdUFDMDBcdUM4MzhcdUM2MjRcdUFFMzAiLAoJCQkicnUiOiAiXHUwNDE4XHUwNDNDXHUwNDNGXHUwNDNFXHUwNDQwXHUwNDQyIgoJCX0sCgkJIkV4cG9ydCI6IHsKCQkJIml0IjogIkVzcG9ydGEiLAoJCQkia28iOiAiXHVCMEI0XHVCQ0Y0XHVCMEI0XHVBRTMwIiwKCQkJInJ1IjogIlx1MDQyRFx1MDQzQVx1MDQ0MVx1MDQzRlx1MDQzRVx1MDQ0MFx1MDQ0MiIKCQl9LAoJCSJSZXF1aXJlczoiOiB7CgkJCSJpdCI6ICJSaWNoaWVkZSIsCgkJCSJrbyI6ICJcdUM2OTRcdUFENkNcdUMwQUNcdUQ1NkQ6IiwKCQkJInJ1IjogIlx1M
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment