Skip to content

Instantly share code, notes, and snippets.

@larskuhtz
Last active December 4, 2018 23:05
Show Gist options
  • Select an option

  • Save larskuhtz/5ee9510ad5346f988614f202420ddcc4 to your computer and use it in GitHub Desktop.

Select an option

Save larskuhtz/5ee9510ad5346f988614f202420ddcc4 to your computer and use it in GitHub Desktop.
Haskell Benchmarks for Concurrent Transactions with Many Shared Variables

Setup

This gist contains benchmarks for read-only concurrent transaction that involve many shared variables. The test data is a mutable single-linked list where individual list "cells" are linked via mutable shared variables. The goal is to measure the overhead of different transaction types and variables in read-only transactions when there are no concurrent writes.

The input to a benchmark run is a list of a of successive Int values. The benchmark code runs a number of concurrent threads that each fold over the list and each compute the sum of all entries. The list isn't mutated during the benchmarks.

Benchmark parameters are

  • the length of the list,
  • the number of concurrent threads, and
  • the type of the variables and transactions.

Variable and transaction types are

  • MVar,
  • Compose IORef Maybe (which is fine, since the data structure isn't mutated during the benchmark),
  • TMVar (in STM) evaluated in a single STM transaction,
  • TMVar (hoisted) with each STM action hoisted into a separate singleton STM transaction,
  • TMVar (in IO) with each STM action called in a separate singleton STM transaction,
  • Compose TVar Maybe (in STM) evaluated in a single STM transaction,
  • Compose TVar Maybe (hoisted) with each STM action hoisted into a separate singleton STM transaction, and
  • Compose TVar Maybe (in IO) access in IO without using STM.

"TMVar hoisted" and "TMVar in IO" result in equivalent code. However, the overhead of the hoist implementation for the Stream type that is used in the fold and different inlining by GHC may result in different performance.

Build:

ghc -O2 -threaded -rtsopts -main-is VarList -o main VarList.hs

Run:

./main +RTS -N

Results

Results

As expected Compose IORef Maybe performs best in all settings. Compose TVar Maybe with readTVarIO performs on par with plain IORef. MVar has only little overhead.

TMVar in IO and TMVar hoisted both have acceptable performance with some overhead due to the STM transactions. The hoisted version is somewhat slower, most likely due to overhead in hoist and different inlining by GHC.

In the context of STM transactions TMVar and Compose TVar Maybe perform similar, which can be explained by the fact that TMVar a is implemented as TVar (Maybe a) in base.

Benchmarks didn't complete in acceptable time for benchmarks that run the complete fold in a single STM transaction when there was more than a single thread and a moderately large lists lengths (in the order of thousands).

Results for large STM transactions with many variables

Rendered Notebook

Focusing on the scenarios where the complete fold is done in a single STM transaction, it seems that the run time scales linear in the number of threads and, up to some point, quadratic in the length of the list.

However, if there is more than a single thread and the length of the list growth beyond a certain point (~15,000 - 20,000 in my tests) the running time distribution exhibits a growing tail of very long runs and eventually most runs become long running. The behavior seems to indicate a race between concurrent transactions, which is surprising, since there are no updates to the variables during the test run.

Conclusion

It seems that read-only STM transactions without concurrent writes scale quadratic in the number involved variables and linear in the number of concurrent transactions.

Small (singleton) read transactions come with little overhead, but are still slower than MVar with tryReadMVar.

TVars with readTVarIO have the same performance as plain IORefs. Thus TVars have the benefit that they can be used either like plain IORef without any transaction overhead or in transactions.

Using STM transactions that involve a large number of variables should be avoided, even if when there are no concurrent writes. In addition to the quadratic complexity it seems that there can be races between read-only transactions even in the absence of concurrent updates.

Thus,

  • IORefs are best when there is no concurrent updates beyond what can be done with atomicModifyIORef.
  • MVars are best when concurrent writes can't be ruled out.
  • TVars are best when variables are used in contexts that don't have concurrent writes (where readTVarIO can be used) as well as in contexts with concurrent writes.

It would be nice if base could include a function tryReadTMVarIO that avoids the overhead of an STM transaction.

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeSynonymInstances #-}
-- |
-- Module: VarList
-- Copyright: Copyright © 2018 Lars Kuhtz <lakuhtz@gmail.com>
-- License: MIT
-- Maintainer: Lars Kuhtz <lakuhtz@gmail.com>
-- Stability: experimental
--
module VarList
(
-- * Mutable Variables
Var(..)
, MaybeIORef
, MaybeTVar
-- * Cell
, Cell(..)
, foldCell
, cellToStream
, cellFromStream
-- * Test and Benchmark Data
, testCell
-- * Main functions
, main
, main1
, main2
, main3
) where
import Control.Concurrent
import Control.Concurrent.Async
import Control.Concurrent.STM
import Control.DeepSeq
import Control.Monad
import Control.Monad.Morph
import Control.StopWatch
import Criterion
import Criterion.Main
import Data.Foldable
import Data.Functor.Compose
import Data.Functor.Of
import Data.IORef
import qualified Data.List.NonEmpty as L
import qualified Data.Sequence as Seq
import qualified Streaming.Prelude as S
import System.Clock
import System.Environment
import System.IO
import System.Mem
-- -------------------------------------------------------------------------- --
-- Variables
--
-- Note that 'Compose' is used here for type constructors that aren't functors.
class Monad m => Var m v where
readVar :: v x -> m (Maybe x)
newEmptyVar :: m (v x)
newVar :: x -> m (v x)
-- | Depending on the type of the variable this function may block or spin.
awaitVar :: v x -> m x
type MaybeIORef = Compose IORef Maybe
type MaybeTVar = Compose TVar Maybe
instance Var STM TMVar where
readVar = tryReadTMVar
newEmptyVar = newEmptyTMVar
newVar = newTMVar
awaitVar = takeTMVar
{-# INLINE readVar #-}
{-# INLINE newEmptyVar #-}
{-# INLINE newVar #-}
{-# INLINE awaitVar #-}
instance Var IO TMVar where
readVar = atomically . tryReadTMVar
newEmptyVar = newEmptyTMVarIO
newVar = newTMVarIO
awaitVar = atomically . awaitVar
{-# INLINE readVar #-}
{-# INLINE newEmptyVar #-}
{-# INLINE newVar #-}
{-# INLINE awaitVar #-}
instance Var IO MVar where
readVar = tryReadMVar
newEmptyVar = newEmptyMVar
newVar = newMVar
awaitVar = takeMVar
{-# INLINE readVar #-}
{-# INLINE newEmptyVar #-}
{-# INLINE newVar #-}
{-# INLINE awaitVar #-}
instance Var STM (Compose TVar Maybe) where
readVar = readTVar . getCompose
newEmptyVar = Compose <$> newTVar Nothing
newVar = fmap Compose . newTVar . Just
awaitVar = readVar >=> maybe retry return
{-# INLINE readVar #-}
{-# INLINE newEmptyVar #-}
{-# INLINE newVar #-}
{-# INLINE awaitVar #-}
instance Var IO (Compose TVar Maybe) where
readVar = readTVarIO . getCompose
newEmptyVar = Compose <$> newTVarIO Nothing
newVar = fmap Compose . newTVarIO . Just
awaitVar = atomically . awaitVar
{-# INLINE readVar #-}
{-# INLINE newEmptyVar #-}
{-# INLINE newVar #-}
{-# INLINE awaitVar #-}
instance Var IO (Compose IORef Maybe) where
readVar = readIORef . getCompose
newEmptyVar = Compose <$> newIORef Nothing
newVar = fmap Compose . newIORef . Just
-- | This spins
awaitVar v = let go = readVar v >>= maybe (yield >> go) return in go
{-# INLINE readVar #-}
{-# INLINE newEmptyVar #-}
{-# INLINE newVar #-}
{-# INLINE awaitVar #-}
-- -------------------------------------------------------------------------- --
-- Cell
data Cell v a = Cell a !(v (Cell v a))
instance NFData a => NFData (Cell v a) where
rnf (Cell a _) = rnf a
-- | Fold over the values in a cell
--
foldCell
:: Monad m
=> Var m v
=> (b -> a -> b)
-> b
-> Cell v a
-> m b
foldCell f b = go b
where
go !i (Cell !h !t) = readVar t >>= \case
Nothing -> return i
Just c -> go (f i h) c
cellToStream :: Var m v => Cell v a -> S.Stream (Of a) m ()
cellToStream = go
where
go (Cell h t) = do
S.yield h
lift (readVar t) >>= \case
Nothing -> return ()
Just c -> go c
-- | Transforms a stream into a cell and returns the first cell if the stream
-- isn't empty.
--
-- This could be made lazy using 'unsafeInterleavedIO', which would be fine,
-- since the 'Var's won't change once the are evaluated. However, for
-- benchmarking we want it strict.
--
cellFromStream :: Var m v => S.Stream (Of a) m () -> m (v (Cell v a))
cellFromStream s = S.foldrM f (s >> lift newEmptyVar)
where
f !a !x = newVar =<< (Cell a <$> x)
cellFromList :: forall v a m . Var m v => L.NonEmpty a -> m (Cell v a)
cellFromList (a L.:| l) = Cell a <$> go l
where
go [] = newEmptyVar
go (!h:t) = newVar =<< (Cell h <$> go t)
maybeIORefCellFromList :: forall a . L.NonEmpty a -> IO (Cell MaybeIORef a)
maybeIORefCellFromList (a L.:| l) = do
v <- newEmptyVar
go v l
return $ Cell a v
where
go :: MaybeIORef (Cell MaybeIORef a) -> [a] -> IO ()
go _ [] = return ()
go !v (!h:t) = do
!v' <- newEmptyVar
writeIORef (getCompose v) (Just (Cell h v'))
go v' t
-- -------------------------------------------------------------------------- --
-- Main
testCell :: forall v m . Var m v => Int -> m (Cell v Int)
testCell i = awaitVar =<< cellFromStream (S.each [1..i])
main :: IO ()
main = main3
-- -------------------------------------------------------------------------- --
-- Test
main1 :: IO ()
main1 = do
[minThreadCount, maxThreadCount, threadCountStep, minListLength, maxListLength, listLengthStep] <- fmap read . take 2 <$> getArgs
hSetBuffering stdout LineBuffering
putStrLn $ "threadCount, listLength, time"
forM_ [minThreadCount, (minThreadCount + threadCountStep) .. maxThreadCount] $ \threadCount -> do
forM_ [minListLength, (minListLength + listLengthStep) .. maxListLength] $ \listLength -> do
-- Compute test cell
cell <- testCell @MaybeTVar listLength
-- prime test cell evaluation
void $ atomically $ S.sum $ cellToStream $ cell
-- measure concurrent test cell evaluation
performMajorGC
(_, t) <- stopWatch $ replicateConcurrently_ threadCount
$ atomically $ S.sum_ $ cellToStream $ cell
-- print result
putStrLn
$ show threadCount
<> ", " <> show listLength
<> ", " <> show (toNanoSecs t)
-- -------------------------------------------------------------------------- --
-- Comparison with Pure Sequence
main3 :: IO ()
main3 = defaultMain
[ bs 1
, bs 100
, create
]
where
create = bgroup "create" $
[ bench "seq"
$ nf (\s -> Seq.fromList [0..s]) (1000000 :: Int)
, bench "cell"
$ nfAppIO (testCell @MaybeIORef) 1000000
, bench "cell from list"
$ nfAppIO (\s -> cellFromList @MaybeIORef @Int (0 L.:| [1..s])) 1000000
, bench "cell from list 2"
$ nfAppIO (\s -> maybeIORefCellFromList @Int (0 L.:| [1..s])) 1000000
]
bs i = bgroup (show i <> " threads")
[ bgroup "stream" $
[ env (return $ Seq.fromList [0..1000000]) $ \(e :: Seq.Seq Int) -> bench "seq"
$ nfAppIO (S.sum_ . S.each) e
, env (testCell @MaybeIORef 1000000) $ \e -> bench "cell"
$ nfAppIO (S.sum_ . cellToStream) e
]
, bgroup "fold" $
[ env (return $ Seq.fromList [0..1000000]) $ \(e :: Seq.Seq Int) -> bench "seq"
$ nf (foldl' (+) 0) e
, env (testCell @MaybeIORef 1000000) $ \e -> bench "cell"
$ nfAppIO (foldCell (+) 0) e
]
]
-- -------------------------------------------------------------------------- --
-- Criterion Benchmarks
main2 :: IO ()
main2 = defaultMain
[ benchmarks 1
, benchmarks 10
, benchmarks 1000
]
benchmarks :: Int -> Benchmark
benchmarks i = bgroup (show i <> " threads")
[ env (testCell @MVar 10000) $ \e -> bench "MVar"
$ nfAppIO (threaded $ S.sum_ . cellToStream) e
, env (testCell @MaybeIORef 10000) $ \e -> bench "MaybeIORef"
$ nfAppIO (threaded $ S.sum_ . cellToStream) e
, bgroup "TMVar" $
[ env (testCell @TMVar 10000) $ \e -> bench "TMVar hoisted"
$ nfAppIO (threaded $ S.sum_ . hoist atomically . cellToStream) e
, env (testCell @TMVar 10000) $ \e -> bench "TMVar in IO"
$ nfAppIO (threaded $ S.sum_ . cellToStream) e
]
<> if i > 1 then [] else
[ env (testCell @TMVar 10000) $ \e -> bench "TMVar in STM"
$ nfAppIO (threaded $ atomically . S.sum_ . cellToStream) e
-- , env (testCell @TMVar 10000) $ \e -> bench "foldCell Cell TMVar"
-- $ nfAppIO (threaded $ atomically . foldCell ((+) @Int) 0) e
]
, bgroup "MaybeTVar" $
[ env (testCell @MaybeTVar 10000) $ \e -> bench "MaybeTVar hoisted"
$ nfAppIO (threaded $ S.sum_ . hoist atomically . cellToStream) e
, env (testCell @MaybeTVar 10000) $ \e -> bench "MaybeTVar in IO"
$ nfAppIO (threaded $ S.sum_ . cellToStream) e
]
<> if i > 1 then [] else
[ env (testCell @MaybeTVar 10000) $ \e -> bench "MaybeTVar in STM"
$ nfAppIO (threaded $ atomically . S.sum_ . cellToStream) e
]
]
where
threaded f a = replicateConcurrently_ i (f a)
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 296,
"metadata": {},
"outputs": [],
"source": [
"library(ggplot2)"
]
},
{
"cell_type": "code",
"execution_count": 297,
"metadata": {},
"outputs": [],
"source": [
"library(plotly)"
]
},
{
"cell_type": "code",
"execution_count": 298,
"metadata": {},
"outputs": [],
"source": [
"dat = read.csv(\"varlist.csv\", header = TRUE)"
]
},
{
"cell_type": "code",
"execution_count": 440,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/html": [
"<!doctype html>\n",
"<html>\n",
"\t<head>\n",
"\t\t<meta charset=\"utf-8\">\n",
"\t\t<script src=\"data:application/javascript;base64,KGZ1bmN0aW9uKCkgewogIC8vIElmIHdpbmRvdy5IVE1MV2lkZ2V0cyBpcyBhbHJlYWR5IGRlZmluZWQsIHRoZW4gdXNlIGl0OyBvdGhlcndpc2UgY3JlYXRlIGEKICAvLyBuZXcgb2JqZWN0LiBUaGlzIGFsbG93cyBwcmVjZWRpbmcgY29kZSB0byBzZXQgb3B0aW9ucyB0aGF0IGFmZmVjdCB0aGUKICAvLyBpbml0aWFsaXphdGlvbiBwcm9jZXNzICh0aG91Z2ggbm9uZSBjdXJyZW50bHkgZXhpc3QpLgogIHdpbmRvdy5IVE1MV2lkZ2V0cyA9IHdpbmRvdy5IVE1MV2lkZ2V0cyB8fCB7fTsKCiAgLy8gU2VlIGlmIHdlJ3JlIHJ1bm5pbmcgaW4gYSB2aWV3ZXIgcGFuZS4gSWYgbm90LCB3ZSdyZSBpbiBhIHdlYiBicm93c2VyLgogIHZhciB2aWV3ZXJNb2RlID0gd2luZG93LkhUTUxXaWRnZXRzLnZpZXdlck1vZGUgPQogICAgICAvXGJ2aWV3ZXJfcGFuZT0xXGIvLnRlc3Qod2luZG93LmxvY2F0aW9uKTsKCiAgLy8gU2VlIGlmIHdlJ3JlIHJ1bm5pbmcgaW4gU2hpbnkgbW9kZS4gSWYgbm90LCBpdCdzIGEgc3RhdGljIGRvY3VtZW50LgogIC8vIE5vdGUgdGhhdCBzdGF0aWMgd2lkZ2V0cyBjYW4gYXBwZWFyIGluIGJvdGggU2hpbnkgYW5kIHN0YXRpYyBtb2RlcywgYnV0CiAgLy8gb2J2aW91c2x5LCBTaGlueSB3aWRnZXRzIGNhbiBvbmx5IGFwcGVhciBpbiBTaGlueSBhcHBzL2RvY3VtZW50cy4KICB2YXIgc2hpbnlNb2RlID0gd2luZG93LkhUTUxXaWRnZXRzLnNoaW55TW9kZSA9CiAgICAgIHR5cGVvZih3aW5kb3cuU2hpbnkpICE9PSAidW5kZWZpbmVkIiAmJiAhIXdpbmRvdy5TaGlueS5vdXRwdXRCaW5kaW5nczsKCiAgLy8gV2UgY2FuJ3QgY291bnQgb24galF1ZXJ5IGJlaW5nIGF2YWlsYWJsZSwgc28gd2UgaW1wbGVtZW50IG91ciBvd24KICAvLyB2ZXJzaW9uIGlmIG5lY2Vzc2FyeS4KICBmdW5jdGlvbiBxdWVyeVNlbGVjdG9yQWxsKHNjb3BlLCBzZWxlY3RvcikgewogICAgaWYgKHR5cGVvZihqUXVlcnkpICE9PSAidW5kZWZpbmVkIiAmJiBzY29wZSBpbnN0YW5jZW9mIGpRdWVyeSkgewogICAgICByZXR1cm4gc2NvcGUuZmluZChzZWxlY3Rvcik7CiAgICB9CiAgICBpZiAoc2NvcGUucXVlcnlTZWxlY3RvckFsbCkgewogICAgICByZXR1cm4gc2NvcGUucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBhc0FycmF5KHZhbHVlKSB7CiAgICBpZiAodmFsdWUgPT09IG51bGwpCiAgICAgIHJldHVybiBbXTsKICAgIGlmICgkLmlzQXJyYXkodmFsdWUpKQogICAgICByZXR1cm4gdmFsdWU7CiAgICByZXR1cm4gW3ZhbHVlXTsKICB9CgogIC8vIEltcGxlbWVudCBqUXVlcnkncyBleHRlbmQKICBmdW5jdGlvbiBleHRlbmQodGFyZ2V0IC8qLCAuLi4gKi8pIHsKICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgcmV0dXJuIHRhcmdldDsKICAgIH0KICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07CiAgICAgIGZvciAodmFyIHByb3AgaW4gc291cmNlKSB7CiAgICAgICAgaWYgKHNvdXJjZS5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgewogICAgICAgICAgdGFyZ2V0W3Byb3BdID0gc291cmNlW3Byb3BdOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHRhcmdldDsKICB9CgogIC8vIElFOCBkb2Vzbid0IHN1cHBvcnQgQXJyYXkuZm9yRWFjaC4KICBmdW5jdGlvbiBmb3JFYWNoKHZhbHVlcywgY2FsbGJhY2ssIHRoaXNBcmcpIHsKICAgIGlmICh2YWx1ZXMuZm9yRWFjaCkgewogICAgICB2YWx1ZXMuZm9yRWFjaChjYWxsYmFjaywgdGhpc0FyZyk7CiAgICB9IGVsc2UgewogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykgewogICAgICAgIGNhbGxiYWNrLmNhbGwodGhpc0FyZywgdmFsdWVzW2ldLCBpLCB2YWx1ZXMpOwogICAgICB9CiAgICB9CiAgfQoKICAvLyBSZXBsYWNlcyB0aGUgc3BlY2lmaWVkIG1ldGhvZCB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgZnVuY1NvdXJjZS4KICAvLwogIC8vIE5vdGUgdGhhdCBmdW5jU291cmNlIHNob3VsZCBub3QgQkUgdGhlIG5ldyBtZXRob2QsIGl0IHNob3VsZCBiZSBhIGZ1bmN0aW9uCiAgLy8gdGhhdCBSRVRVUk5TIHRoZSBuZXcgbWV0aG9kLiBmdW5jU291cmNlIHJlY2VpdmVzIGEgc2luZ2xlIGFyZ3VtZW50IHRoYXQgaXMKICAvLyB0aGUgb3ZlcnJpZGRlbiBtZXRob2QsIGl0IGNhbiBiZSBjYWxsZWQgZnJvbSB0aGUgbmV3IG1ldGhvZC4gVGhlIG92ZXJyaWRkZW4KICAvLyBtZXRob2QgY2FuIGJlIGNhbGxlZCBsaWtlIGEgcmVndWxhciBmdW5jdGlvbiwgaXQgaGFzIHRoZSB0YXJnZXQgcGVybWFuZW50bHkKICAvLyBib3VuZCB0byBpdCBzbyAidGhpcyIgd2lsbCB3b3JrIGNvcnJlY3RseS4KICBmdW5jdGlvbiBvdmVycmlkZU1ldGhvZCh0YXJnZXQsIG1ldGhvZE5hbWUsIGZ1bmNTb3VyY2UpIHsKICAgIHZhciBzdXBlckZ1bmMgPSB0YXJnZXRbbWV0aG9kTmFtZV0gfHwgZnVuY3Rpb24oKSB7fTsKICAgIHZhciBzdXBlckZ1bmNCb3VuZCA9IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gc3VwZXJGdW5jLmFwcGx5KHRhcmdldCwgYXJndW1lbnRzKTsKICAgIH07CiAgICB0YXJnZXRbbWV0aG9kTmFtZV0gPSBmdW5jU291cmNlKHN1cGVyRnVuY0JvdW5kKTsKICB9CgogIC8vIEFkZCBhIG1ldGhvZCB0byBkZWxlZ2F0b3IgdGhhdCwgd2hlbiBpbnZva2VkLCBjYWxscwogIC8vIGRlbGVnYXRlZS5tZXRob2ROYW1lLiBJZiB0aGVyZSBpcyBubyBzdWNoIG1ldGhvZCBvbgogIC8vIHRoZSBkZWxlZ2F0ZWUsIGJ1dCB0aGVyZSB3YXMgb25lIG9uIGRlbGVnYXRvciBiZWZvcmUKICAvLyBkZWxlZ2F0ZU1ldGhvZCB3YXMgY2FsbGVkLCB0aGVuIHRoZSBvcmlnaW5hbCB2ZXJzaW9uCiAgLy8gaXMgaW52b2tlZCBpbnN0ZWFkLgogIC8vIEZvciBleGFtcGxlOgogIC8vCiAgLy8gdmFyIGEgPSB7CiAgLy8gICBtZXRob2QxOiBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ2ExJyk7IH0KICAvLyAgIG1ldGhvZDI6IGZ1bmN0aW9uKCkgeyBjb25zb2xlLmxvZygnYTInKTsgfQogIC8vIH07CiAgLy8gdmFyIGIgPSB7CiAgLy8gICBtZXRob2QxOiBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ2IxJyk7IH0KICAvLyB9OwogIC8vIGRlbGVnYXRlTWV0aG9kKGEsIGIsICJtZXRob2QxIik7CiAgLy8gZGVsZWdhdGVNZXRob2QoYSwgYiwgIm1ldGhvZDIiKTsKICAvLyBhLm1ldGhvZDEoKTsKICAvLyBhLm1ldGhvZDIoKTsKICAvLwogIC8vIFRoZSBvdXRwdXQgd291bGQgYmUgImIxIiwgImEyIi4KICBmdW5jdGlvbiBkZWxlZ2F0ZU1ldGhvZChkZWxlZ2F0b3IsIGRlbGVnYXRlZSwgbWV0aG9kTmFtZSkgewogICAgdmFyIGluaGVyaXRlZCA9IGRlbGVnYXRvclttZXRob2ROYW1lXTsKICAgIGRlbGVnYXRvclttZXRob2ROYW1lXSA9IGZ1bmN0aW9uKCkgewogICAgICB2YXIgdGFyZ2V0ID0gZGVsZWdhdGVlOwogICAgICB2YXIgbWV0aG9kID0gZGVsZWdhdGVlW21ldGhvZE5hbWVdOwoKICAgICAgLy8gVGhlIG1ldGhvZCBkb2Vzbid0IGV4aXN0IG9uIHRoZSBkZWxlZ2F0ZWUuIEluc3RlYWQsCiAgICAgIC8vIGNhbGwgdGhlIG1ldGhvZCBvbiB0aGUgZGVsZWdhdG9yLCBpZiBpdCBleGlzdHMuCiAgICAgIGlmICghbWV0aG9kKSB7CiAgICAgICAgdGFyZ2V0ID0gZGVsZWdhdG9yOwogICAgICAgIG1ldGhvZCA9IGluaGVyaXRlZDsKICAgICAgfQoKICAgICAgaWYgKG1ldGhvZCkgewogICAgICAgIHJldHVybiBtZXRob2QuYXBwbHkodGFyZ2V0LCBhcmd1bWVudHMpOwogICAgICB9CiAgICB9OwogIH0KCiAgLy8gSW1wbGVtZW50IGEgdmFndWUgZmFjc2ltaWxpZSBvZiBqUXVlcnkncyBkYXRhIG1ldGhvZAogIGZ1bmN0aW9uIGVsZW1lbnREYXRhKGVsLCBuYW1lLCB2YWx1ZSkgewogICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMikgewogICAgICByZXR1cm4gZWxbImh0bWx3aWRnZXRfZGF0YV8iICsgbmFtZV07CiAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMykgewogICAgICBlbFsiaHRtbHdpZGdldF9kYXRhXyIgKyBuYW1lXSA9IHZhbHVlOwogICAgICByZXR1cm4gZWw7CiAgICB9IGVsc2UgewogICAgICB0aHJvdyBuZXcgRXJyb3IoIldyb25nIG51bWJlciBvZiBhcmd1bWVudHMgZm9yIGVsZW1lbnREYXRhOiAiICsKICAgICAgICBhcmd1bWVudHMubGVuZ3RoKTsKICAgIH0KICB9CgogIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzQ0NjE3MC9lc2NhcGUtc3RyaW5nLWZvci11c2UtaW4tamF2YXNjcmlwdC1yZWdleAogIGZ1bmN0aW9uIGVzY2FwZVJlZ0V4cChzdHIpIHsKICAgIHJldHVybiBzdHIucmVwbGFjZSgvW1wtXFtcXVwvXHtcfVwoXClcKlwrXD9cLlxcXF5cJFx8XS9nLCAiXFwkJiIpOwogIH0KCiAgZnVuY3Rpb24gaGFzQ2xhc3MoZWwsIGNsYXNzTmFtZSkgewogICAgdmFyIHJlID0gbmV3IFJlZ0V4cCgiXFxiIiArIGVzY2FwZVJlZ0V4cChjbGFzc05hbWUpICsgIlxcYiIpOwogICAgcmV0dXJuIHJlLnRlc3QoZWwuY2xhc3NOYW1lKTsKICB9CgogIC8vIGVsZW1lbnRzIC0gYXJyYXkgKG9yIGFycmF5LWxpa2Ugb2JqZWN0KSBvZiBIVE1MIGVsZW1lbnRzCiAgLy8gY2xhc3NOYW1lIC0gY2xhc3MgbmFtZSB0byB0ZXN0IGZvcgogIC8vIGluY2x1ZGUgLSBpZiB0cnVlLCBvbmx5IHJldHVybiBlbGVtZW50cyB3aXRoIGdpdmVuIGNsYXNzTmFtZTsKICAvLyAgIGlmIGZhbHNlLCBvbmx5IHJldHVybiBlbGVtZW50cyAqd2l0aG91dCogZ2l2ZW4gY2xhc3NOYW1lCiAgZnVuY3Rpb24gZmlsdGVyQnlDbGFzcyhlbGVtZW50cywgY2xhc3NOYW1lLCBpbmNsdWRlKSB7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykgewogICAgICBpZiAoaGFzQ2xhc3MoZWxlbWVudHNbaV0sIGNsYXNzTmFtZSkgPT0gaW5jbHVkZSkKICAgICAgICByZXN1bHRzLnB1c2goZWxlbWVudHNbaV0pOwogICAgfQogICAgcmV0dXJuIHJlc3VsdHM7CiAgfQoKICBmdW5jdGlvbiBvbihvYmosIGV2ZW50TmFtZSwgZnVuYykgewogICAgaWYgKG9iai5hZGRFdmVudExpc3RlbmVyKSB7CiAgICAgIG9iai5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgZnVuYywgZmFsc2UpOwogICAgfSBlbHNlIGlmIChvYmouYXR0YWNoRXZlbnQpIHsKICAgICAgb2JqLmF0dGFjaEV2ZW50KGV2ZW50TmFtZSwgZnVuYyk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBvZmYob2JqLCBldmVudE5hbWUsIGZ1bmMpIHsKICAgIGlmIChvYmoucmVtb3ZlRXZlbnRMaXN0ZW5lcikKICAgICAgb2JqLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBmdW5jLCBmYWxzZSk7CiAgICBlbHNlIGlmIChvYmouZGV0YWNoRXZlbnQpIHsKICAgICAgb2JqLmRldGFjaEV2ZW50KGV2ZW50TmFtZSwgZnVuYyk7CiAgICB9CiAgfQoKICAvLyBUcmFuc2xhdGUgYXJyYXkgb2YgdmFsdWVzIHRvIHRvcC9yaWdodC9ib3R0b20vbGVmdCwgYXMgdXN1YWwgd2l0aAogIC8vIHRoZSAicGFkZGluZyIgQ1NTIHByb3BlcnR5CiAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL3BhZGRpbmcKICBmdW5jdGlvbiB1bnBhY2tQYWRkaW5nKHZhbHVlKSB7CiAgICBpZiAodHlwZW9mKHZhbHVlKSA9PT0gIm51bWJlciIpCiAgICAgIHZhbHVlID0gW3ZhbHVlXTsKICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDEpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMF0sIGJvdHRvbTogdmFsdWVbMF0sIGxlZnQ6IHZhbHVlWzBdfTsKICAgIH0KICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDIpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMV0sIGJvdHRvbTogdmFsdWVbMF0sIGxlZnQ6IHZhbHVlWzFdfTsKICAgIH0KICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDMpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMV0sIGJvdHRvbTogdmFsdWVbMl0sIGxlZnQ6IHZhbHVlWzFdfTsKICAgIH0KICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDQpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMV0sIGJvdHRvbTogdmFsdWVbMl0sIGxlZnQ6IHZhbHVlWzNdfTsKICAgIH0KICB9CgogIC8vIENvbnZlcnQgYW4gdW5wYWNrZWQgcGFkZGluZyBvYmplY3QgdG8gYSBDU1MgdmFsdWUKICBmdW5jdGlvbiBwYWRkaW5nVG9Dc3MocGFkZGluZ09iaikgewogICAgcmV0dXJuIHBhZGRpbmdPYmoudG9wICsgInB4ICIgKyBwYWRkaW5nT2JqLnJpZ2h0ICsgInB4ICIgKyBwYWRkaW5nT2JqLmJvdHRvbSArICJweCAiICsgcGFkZGluZ09iai5sZWZ0ICsgInB4IjsKICB9CgogIC8vIE1ha2VzIGEgbnVtYmVyIHN1aXRhYmxlIGZvciBDU1MKICBmdW5jdGlvbiBweCh4KSB7CiAgICBpZiAodHlwZW9mKHgpID09PSAibnVtYmVyIikKICAgICAgcmV0dXJuIHggKyAicHgiOwogICAgZWxzZQogICAgICByZXR1cm4geDsKICB9CgogIC8vIFJldHJpZXZlcyBydW50aW1lIHdpZGdldCBzaXppbmcgaW5mb3JtYXRpb24gZm9yIGFuIGVsZW1lbnQuCiAgLy8gVGhlIHJldHVybiB2YWx1ZSBpcyBlaXRoZXIgbnVsbCwgb3IgYW4gb2JqZWN0IHdpdGggZmlsbCwgcGFkZGluZywKICAvLyBkZWZhdWx0V2lkdGgsIGRlZmF1bHRIZWlnaHQgZmllbGRzLgogIGZ1bmN0aW9uIHNpemluZ1BvbGljeShlbCkgewogICAgdmFyIHNpemluZ0VsID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcigic2NyaXB0W2RhdGEtZm9yPSciICsgZWwuaWQgKyAiJ11bdHlwZT0nYXBwbGljYXRpb24vaHRtbHdpZGdldC1zaXppbmcnXSIpOwogICAgaWYgKCFzaXppbmdFbCkKICAgICAgcmV0dXJuIG51bGw7CiAgICB2YXIgc3AgPSBKU09OLnBhcnNlKHNpemluZ0VsLnRleHRDb250ZW50IHx8IHNpemluZ0VsLnRleHQgfHwgInt9Iik7CiAgICBpZiAodmlld2VyTW9kZSkgewogICAgICByZXR1cm4gc3Audmlld2VyOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIHNwLmJyb3dzZXI7CiAgICB9CiAgfQoKICAvLyBAcGFyYW0gdGFza3MgQXJyYXkgb2Ygc3RyaW5ncyAob3IgZmFsc3kgdmFsdWUsIGluIHdoaWNoIGNhc2Ugbm8tb3ApLgogIC8vICAgRWFjaCBlbGVtZW50IG11c3QgYmUgYSB2YWxpZCBKYXZhU2NyaXB0IGV4cHJlc3Npb24gdGhhdCB5aWVsZHMgYQogIC8vICAgZnVuY3Rpb24uIE9yLCBjYW4gYmUgYW4gYXJyYXkgb2Ygb2JqZWN0cyB3aXRoICJjb2RlIiBhbmQgImRhdGEiCiAgLy8gICBwcm9wZXJ0aWVzOyBpbiB0aGlzIGNhc2UsIHRoZSAiY29kZSIgcHJvcGVydHkgc2hvdWxkIGJlIGEgc3RyaW5nCiAgLy8gICBvZiBKUyB0aGF0J3MgYW4gZXhwciB0aGF0IHlpZWxkcyBhIGZ1bmN0aW9uLCBhbmQgImRhdGEiIHNob3VsZCBiZQogIC8vICAgYW4gb2JqZWN0IHRoYXQgd2lsbCBiZSBhZGRlZCBhcyBhbiBhZGRpdGlvbmFsIGFyZ3VtZW50IHdoZW4gdGhhdAogIC8vICAgZnVuY3Rpb24gaXMgY2FsbGVkLgogIC8vIEBwYXJhbSB0YXJnZXQgVGhlIG9iamVjdCB0aGF0IHdpbGwgYmUgInRoaXMiIGZvciBlYWNoIGZ1bmN0aW9uCiAgLy8gICBleGVjdXRpb24uCiAgLy8gQHBhcmFtIGFyZ3MgQXJyYXkgb2YgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb25zLiAoVGhlCiAgLy8gICBzYW1lIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBhbGwgZnVuY3Rpb25zLikKICBmdW5jdGlvbiBldmFsQW5kUnVuKHRhc2tzLCB0YXJnZXQsIGFyZ3MpIHsKICAgIGlmICh0YXNrcykgewogICAgICBmb3JFYWNoKHRhc2tzLCBmdW5jdGlvbih0YXNrKSB7CiAgICAgICAgdmFyIHRoZXNlQXJncyA9IGFyZ3M7CiAgICAgICAgaWYgKHR5cGVvZih0YXNrKSA9PT0gIm9iamVjdCIpIHsKICAgICAgICAgIHRoZXNlQXJncyA9IHRoZXNlQXJncy5jb25jYXQoW3Rhc2suZGF0YV0pOwogICAgICAgICAgdGFzayA9IHRhc2suY29kZTsKICAgICAgICB9CiAgICAgICAgdmFyIHRhc2tGdW5jID0gZXZhbCgiKCIgKyB0YXNrICsgIikiKTsKICAgICAgICBpZiAodHlwZW9mKHRhc2tGdW5jKSAhPT0gImZ1bmN0aW9uIikgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJUYXNrIG11c3QgYmUgYSBmdW5jdGlvbiEgU291cmNlOlxuIiArIHRhc2spOwogICAgICAgIH0KICAgICAgICB0YXNrRnVuYy5hcHBseSh0YXJnZXQsIHRoZXNlQXJncyk7CiAgICAgIH0pOwogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5pdFNpemluZyhlbCkgewogICAgdmFyIHNpemluZyA9IHNpemluZ1BvbGljeShlbCk7CiAgICBpZiAoIXNpemluZykKICAgICAgcmV0dXJuOwoKICAgIHZhciBjZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiaHRtbHdpZGdldF9jb250YWluZXIiKTsKICAgIGlmICghY2VsKQogICAgICByZXR1cm47CgogICAgaWYgKHR5cGVvZihzaXppbmcucGFkZGluZykgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUubWFyZ2luID0gIjAiOwogICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnBhZGRpbmcgPSBwYWRkaW5nVG9Dc3ModW5wYWNrUGFkZGluZyhzaXppbmcucGFkZGluZykpOwogICAgfQoKICAgIGlmIChzaXppbmcuZmlsbCkgewogICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gImhpZGRlbiI7CiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUud2lkdGggPSAiMTAwJSI7CiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUuaGVpZ2h0ID0gIjEwMCUiOwogICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUud2lkdGggPSAiMTAwJSI7CiAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5oZWlnaHQgPSAiMTAwJSI7CiAgICAgIGlmIChjZWwpIHsKICAgICAgICBjZWwuc3R5bGUucG9zaXRpb24gPSAiYWJzb2x1dGUiOwogICAgICAgIHZhciBwYWQgPSB1bnBhY2tQYWRkaW5nKHNpemluZy5wYWRkaW5nKTsKICAgICAgICBjZWwuc3R5bGUudG9wID0gcGFkLnRvcCArICJweCI7CiAgICAgICAgY2VsLnN0eWxlLnJpZ2h0ID0gcGFkLnJpZ2h0ICsgInB4IjsKICAgICAgICBjZWwuc3R5bGUuYm90dG9tID0gcGFkLmJvdHRvbSArICJweCI7CiAgICAgICAgY2VsLnN0eWxlLmxlZnQgPSBwYWQubGVmdCArICJweCI7CiAgICAgICAgZWwuc3R5bGUud2lkdGggPSAiMTAwJSI7CiAgICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gIjEwMCUiOwogICAgICB9CgogICAgICByZXR1cm4gewogICAgICAgIGdldFdpZHRoOiBmdW5jdGlvbigpIHsgcmV0dXJuIGNlbC5vZmZzZXRXaWR0aDsgfSwKICAgICAgICBnZXRIZWlnaHQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gY2VsLm9mZnNldEhlaWdodDsgfQogICAgICB9OwoKICAgIH0gZWxzZSB7CiAgICAgIGVsLnN0eWxlLndpZHRoID0gcHgoc2l6aW5nLndpZHRoKTsKICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gcHgoc2l6aW5nLmhlaWdodCk7CgogICAgICByZXR1cm4gewogICAgICAgIGdldFdpZHRoOiBmdW5jdGlvbigpIHsgcmV0dXJuIGVsLm9mZnNldFdpZHRoOyB9LAogICAgICAgIGdldEhlaWdodDogZnVuY3Rpb24oKSB7IHJldHVybiBlbC5vZmZzZXRIZWlnaHQ7IH0KICAgICAgfTsKICAgIH0KICB9CgogIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb25zIGZvciBtZXRob2RzCiAgdmFyIGRlZmF1bHRzID0gewogICAgZmluZDogZnVuY3Rpb24oc2NvcGUpIHsKICAgICAgcmV0dXJuIHF1ZXJ5U2VsZWN0b3JBbGwoc2NvcGUsICIuIiArIHRoaXMubmFtZSk7CiAgICB9LAogICAgcmVuZGVyRXJyb3I6IGZ1bmN0aW9uKGVsLCBlcnIpIHsKICAgICAgdmFyICRlbCA9ICQoZWwpOwoKICAgICAgdGhpcy5jbGVhckVycm9yKGVsKTsKCiAgICAgIC8vIEFkZCBhbGwgdGhlc2UgZXJyb3IgY2xhc3NlcywgYXMgU2hpbnkgZG9lcwogICAgICB2YXIgZXJyQ2xhc3MgPSAic2hpbnktb3V0cHV0LWVycm9yIjsKICAgICAgaWYgKGVyci50eXBlICE9PSBudWxsKSB7CiAgICAgICAgLy8gdXNlIHRoZSBjbGFzc2VzIG9mIHRoZSBlcnJvciBjb25kaXRpb24gYXMgQ1NTIGNsYXNzIG5hbWVzCiAgICAgICAgZXJyQ2xhc3MgPSBlcnJDbGFzcyArICIgIiArICQubWFwKGFzQXJyYXkoZXJyLnR5cGUpLCBmdW5jdGlvbih0eXBlKSB7CiAgICAgICAgICByZXR1cm4gZXJyQ2xhc3MgKyAiLSIgKyB0eXBlOwogICAgICAgIH0pLmpvaW4oIiAiKTsKICAgICAgfQogICAgICBlcnJDbGFzcyA9IGVyckNsYXNzICsgIiBodG1sd2lkZ2V0cy1lcnJvciI7CgogICAgICAvLyBJcyBlbCBpbmxpbmUgb3IgYmxvY2s/IElmIGlubGluZSBvciBpbmxpbmUtYmxvY2ssIGp1c3QgZGlzcGxheTpub25lIGl0CiAgICAgIC8vIGFuZCBhZGQgYW4gaW5saW5lIGVycm9yLgogICAgICB2YXIgZGlzcGxheSA9ICRlbC5jc3MoImRpc3BsYXkiKTsKICAgICAgJGVsLmRhdGEoInJlc3RvcmUtZGlzcGxheS1tb2RlIiwgZGlzcGxheSk7CgogICAgICBpZiAoZGlzcGxheSA9PT0gImlubGluZSIgfHwgZGlzcGxheSA9PT0gImlubGluZS1ibG9jayIpIHsKICAgICAgICAkZWwuaGlkZSgpOwogICAgICAgIGlmIChlcnIubWVzc2FnZSAhPT0gIiIpIHsKICAgICAgICAgIHZhciBlcnJvclNwYW4gPSAkKCI8c3Bhbj4iKS5hZGRDbGFzcyhlcnJDbGFzcyk7CiAgICAgICAgICBlcnJvclNwYW4udGV4dChlcnIubWVzc2FnZSk7CiAgICAgICAgICAkZWwuYWZ0ZXIoZXJyb3JTcGFuKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoZGlzcGxheSA9PT0gImJsb2NrIikgewogICAgICAgIC8vIElmIGJsb2NrLCBhZGQgYW4gZXJyb3IganVzdCBhZnRlciB0aGUgZWwsIHNldCB2aXNpYmlsaXR5Om5vbmUgb24gdGhlCiAgICAgICAgLy8gZWwsIGFuZCBwb3NpdGlvbiB0aGUgZXJyb3IgdG8gYmUgb24gdG9wIG9mIHRoZSBlbC4KICAgICAgICAvLyBNYXJrIGl0IHdpdGggYSB1bmlxdWUgSUQgYW5kIENTUyBjbGFzcyBzbyB3ZSBjYW4gcmVtb3ZlIGl0IGxhdGVyLgogICAgICAgICRlbC5jc3MoInZpc2liaWxpdHkiLCAiaGlkZGVuIik7CiAgICAgICAgaWYgKGVyci5tZXNzYWdlICE9PSAiIikgewogICAgICAgICAgdmFyIGVycm9yRGl2ID0gJCgiPGRpdj4iKS5hZGRDbGFzcyhlcnJDbGFzcykuY3NzKCJwb3NpdGlvbiIsICJhYnNvbHV0ZSIpCiAgICAgICAgICAgIC5jc3MoInRvcCIsIGVsLm9mZnNldFRvcCkKICAgICAgICAgICAgLmNzcygibGVmdCIsIGVsLm9mZnNldExlZnQpCiAgICAgICAgICAgIC8vIHNldHRpbmcgd2lkdGggY2FuIHB1c2ggb3V0IHRoZSBwYWdlIHNpemUsIGZvcmNpbmcgb3RoZXJ3aXNlCiAgICAgICAgICAgIC8vIHVubmVjZXNzYXJ5IHNjcm9sbGJhcnMgdG8gYXBwZWFyIGFuZCBtYWtpbmcgaXQgaW1wb3NzaWJsZSBmb3IKICAgICAgICAgICAgLy8gdGhlIGVsZW1lbnQgdG8gc2hyaW5rOyBzbyB1c2UgbWF4LXdpZHRoIGluc3RlYWQKICAgICAgICAgICAgLmNzcygibWF4V2lkdGgiLCBlbC5vZmZzZXRXaWR0aCkKICAgICAgICAgICAgLmNzcygiaGVpZ2h0IiwgZWwub2Zmc2V0SGVpZ2h0KTsKICAgICAgICAgIGVycm9yRGl2LnRleHQoZXJyLm1lc3NhZ2UpOwogICAgICAgICAgJGVsLmFmdGVyKGVycm9yRGl2KTsKCiAgICAgICAgICAvLyBSZWFsbHkgZHVtYiB3YXkgdG8ga2VlcCB0aGUgc2l6ZS9wb3NpdGlvbiBvZiB0aGUgZXJyb3IgaW4gc3luYyB3aXRoCiAgICAgICAgICAvLyB0aGUgcGFyZW50IGVsZW1lbnQgYXMgdGhlIHdpbmRvdyBpcyByZXNpemVkIG9yIHdoYXRldmVyLgogICAgICAgICAgdmFyIGludElkID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICghZXJyb3JEaXZbMF0ucGFyZW50RWxlbWVudCkgewogICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50SWQpOwogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlcnJvckRpdgogICAgICAgICAgICAgIC5jc3MoInRvcCIsIGVsLm9mZnNldFRvcCkKICAgICAgICAgICAgICAuY3NzKCJsZWZ0IiwgZWwub2Zmc2V0TGVmdCkKICAgICAgICAgICAgICAuY3NzKCJtYXhXaWR0aCIsIGVsLm9mZnNldFdpZHRoKQogICAgICAgICAgICAgIC5jc3MoImhlaWdodCIsIGVsLm9mZnNldEhlaWdodCk7CiAgICAgICAgICB9LCA1MDApOwogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgIGNsZWFyRXJyb3I6IGZ1bmN0aW9uKGVsKSB7CiAgICAgIHZhciAkZWwgPSAkKGVsKTsKICAgICAgdmFyIGRpc3BsYXkgPSAkZWwuZGF0YSgicmVzdG9yZS1kaXNwbGF5LW1vZGUiKTsKICAgICAgJGVsLmRhdGEoInJlc3RvcmUtZGlzcGxheS1tb2RlIiwgbnVsbCk7CgogICAgICBpZiAoZGlzcGxheSA9PT0gImlubGluZSIgfHwgZGlzcGxheSA9PT0gImlubGluZS1ibG9jayIpIHsKICAgICAgICBpZiAoZGlzcGxheSkKICAgICAgICAgICRlbC5jc3MoImRpc3BsYXkiLCBkaXNwbGF5KTsKICAgICAgICAkKGVsLm5leHRTaWJsaW5nKS5maWx0ZXIoIi5odG1sd2lkZ2V0cy1lcnJvciIpLnJlbW92ZSgpOwogICAgICB9IGVsc2UgaWYgKGRpc3BsYXkgPT09ICJibG9jayIpewogICAgICAgICRlbC5jc3MoInZpc2liaWxpdHkiLCAiaW5oZXJpdCIpOwogICAgICAgICQoZWwubmV4dFNpYmxpbmcpLmZpbHRlcigiLmh0bWx3aWRnZXRzLWVycm9yIikucmVtb3ZlKCk7CiAgICAgIH0KICAgIH0sCiAgICBzaXppbmc6IHt9CiAgfTsKCiAgLy8gQ2FsbGVkIGJ5IHdpZGdldCBiaW5kaW5ncyB0byByZWdpc3RlciBhIG5ldyB0eXBlIG9mIHdpZGdldC4gVGhlIGRlZmluaXRpb24KICAvLyBvYmplY3QgY2FuIGNvbnRhaW4gdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgogIC8vIC0gbmFtZSAocmVxdWlyZWQpIC0gQSBzdHJpbmcgaW5kaWNhdGluZyB0aGUgYmluZGluZyBuYW1lLCB3aGljaCB3aWxsIGJlCiAgLy8gICB1c2VkIGJ5IGRlZmF1bHQgYXMgdGhlIENTUyBjbGFzc25hbWUgdG8gbG9vayBmb3IuCiAgLy8gLSBpbml0aWFsaXplIChvcHRpb25hbCkgLSBBIGZ1bmN0aW9uKGVsKSB0aGF0IHdpbGwgYmUgY2FsbGVkIG9uY2UgcGVyCiAgLy8gICB3aWRnZXQgZWxlbWVudDsgaWYgYSB2YWx1ZSBpcyByZXR1cm5lZCwgaXQgd2lsbCBiZSBwYXNzZWQgYXMgdGhlIHRoaXJkCiAgLy8gICB2YWx1ZSB0byByZW5kZXJWYWx1ZS4KICAvLyAtIHJlbmRlclZhbHVlIChyZXF1aXJlZCkgLSBBIGZ1bmN0aW9uKGVsLCBkYXRhLCBpbml0VmFsdWUpIHRoYXQgd2lsbCBiZQogIC8vICAgY2FsbGVkIHdpdGggZGF0YS4gU3RhdGljIGNvbnRleHRzIHdpbGwgY2F1c2UgdGhpcyB0byBiZSBjYWxsZWQgb25jZSBwZXIKICAvLyAgIGVsZW1lbnQ7IFNoaW55IGFwcHMgd2lsbCBjYXVzZSB0aGlzIHRvIGJlIGNhbGxlZCBtdWx0aXBsZSB0aW1lcyBwZXIKICAvLyAgIGVsZW1lbnQsIGFzIHRoZSBkYXRhIGNoYW5nZXMuCiAgd2luZG93LkhUTUxXaWRnZXRzLndpZGdldCA9IGZ1bmN0aW9uKGRlZmluaXRpb24pIHsKICAgIGlmICghZGVmaW5pdGlvbi5uYW1lKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiV2lkZ2V0IG11c3QgaGF2ZSBhIG5hbWUiKTsKICAgIH0KICAgIGlmICghZGVmaW5pdGlvbi50eXBlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiV2lkZ2V0IG11c3QgaGF2ZSBhIHR5cGUiKTsKICAgIH0KICAgIC8vIEN1cnJlbnRseSB3ZSBvbmx5IHN1cHBvcnQgb3V0cHV0IHdpZGdldHMKICAgIGlmIChkZWZpbml0aW9uLnR5cGUgIT09ICJvdXRwdXQiKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiVW5yZWNvZ25pemVkIHdpZGdldCB0eXBlICciICsgZGVmaW5pdGlvbi50eXBlICsgIiciKTsKICAgIH0KICAgIC8vIFRPRE86IFZlcmlmeSB0aGF0IC5uYW1lIGlzIGEgdmFsaWQgQ1NTIGNsYXNzbmFtZQoKICAgIC8vIFN1cHBvcnQgbmV3LXN0eWxlIGluc3RhbmNlLWJvdW5kIGRlZmluaXRpb25zLiBPbGQtc3R5bGUgY2xhc3MtYm91bmQKICAgIC8vIGRlZmluaXRpb25zIGhhdmUgb25lIHdpZGdldCAib2JqZWN0IiBwZXIgd2lkZ2V0IHBlciB0eXBlL2NsYXNzIG9mCiAgICAvLyB3aWRnZXQ7IHRoZSByZW5kZXJWYWx1ZSBhbmQgcmVzaXplIG1ldGhvZHMgb24gc3VjaCB3aWRnZXQgb2JqZWN0cwogICAgLy8gdGFrZSBlbCBhbmQgaW5zdGFuY2UgYXJndW1lbnRzLCBiZWNhdXNlIHRoZSB3aWRnZXQgb2JqZWN0IGNhbid0CiAgICAvLyBzdG9yZSB0aGVtLiBOZXctc3R5bGUgaW5zdGFuY2UtYm91bmQgZGVmaW5pdGlvbnMgaGF2ZSBvbmUgd2lkZ2V0CiAgICAvLyBvYmplY3QgcGVyIHdpZGdldCBpbnN0YW5jZTsgdGhlIGRlZmluaXRpb24gdGhhdCdzIHBhc3NlZCBpbiBkb2Vzbid0CiAgICAvLyBwcm92aWRlIHJlbmRlclZhbHVlIG9yIHJlc2l6ZSBtZXRob2RzIGF0IGFsbCwganVzdCB0aGUgc2luZ2xlIG1ldGhvZAogICAgLy8gICBmYWN0b3J5KGVsLCB3aWR0aCwgaGVpZ2h0KQogICAgLy8gd2hpY2ggcmV0dXJucyBhbiBvYmplY3QgdGhhdCBoYXMgcmVuZGVyVmFsdWUoeCkgYW5kIHJlc2l6ZSh3LCBoKS4KICAgIC8vIFRoaXMgZW5hYmxlcyBhIGZhciBtb3JlIG5hdHVyYWwgcHJvZ3JhbW1pbmcgc3R5bGUgZm9yIHRoZSB3aWRnZXQKICAgIC8vIGF1dGhvciwgd2hvIGNhbiBzdG9yZSBwZXItaW5zdGFuY2Ugc3RhdGUgdXNpbmcgZWl0aGVyIE9PLXN0eWxlCiAgICAvLyBpbnN0YW5jZSBmaWVsZHMgb3IgZnVuY3Rpb25hbC1zdHlsZSBjbG9zdXJlIHZhcmlhYmxlcyAoSSBndWVzcyB0aGlzCiAgICAvLyBpcyBpbiBjb250cmFzdCB0byB3aGF0IGNhbiBvbmx5IGJlIGNhbGxlZCBDLXN0eWxlIHBzZXVkby1PTyB3aGljaCBpcwogICAgLy8gd2hhdCB3ZSByZXF1aXJlZCBiZWZvcmUpLgogICAgaWYgKGRlZmluaXRpb24uZmFjdG9yeSkgewogICAgICBkZWZpbml0aW9uID0gY3JlYXRlTGVnYWN5RGVmaW5pdGlvbkFkYXB0ZXIoZGVmaW5pdGlvbik7CiAgICB9CgogICAgaWYgKCFkZWZpbml0aW9uLnJlbmRlclZhbHVlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiV2lkZ2V0IG11c3QgaGF2ZSBhIHJlbmRlclZhbHVlIGZ1bmN0aW9uIik7CiAgICB9CgogICAgLy8gRm9yIHN0YXRpYyByZW5kZXJpbmcgKG5vbi1TaGlueSksIHVzZSBhIHNpbXBsZSB3aWRnZXQgcmVnaXN0cmF0aW9uCiAgICAvLyBzY2hlbWUuIFdlIGFsc28gdXNlIHRoaXMgc2NoZW1lIGZvciBTaGlueSBhcHBzL2RvY3VtZW50cyB0aGF0IGFsc28KICAgIC8vIGNvbnRhaW4gc3RhdGljIHdpZGdldHMuCiAgICB3aW5kb3cuSFRNTFdpZGdldHMud2lkZ2V0cyA9IHdpbmRvdy5IVE1MV2lkZ2V0cy53aWRnZXRzIHx8IFtdOwogICAgLy8gTWVyZ2UgZGVmYXVsdHMgaW50byB0aGUgZGVmaW5pdGlvbjsgZG9uJ3QgbXV0YXRlIHRoZSBvcmlnaW5hbCBkZWZpbml0aW9uLgogICAgdmFyIHN0YXRpY0JpbmRpbmcgPSBleHRlbmQoe30sIGRlZmF1bHRzLCBkZWZpbml0aW9uKTsKICAgIG92ZXJyaWRlTWV0aG9kKHN0YXRpY0JpbmRpbmcsICJmaW5kIiwgZnVuY3Rpb24oc3VwZXJmdW5jKSB7CiAgICAgIHJldHVybiBmdW5jdGlvbihzY29wZSkgewogICAgICAgIHZhciByZXN1bHRzID0gc3VwZXJmdW5jKHNjb3BlKTsKICAgICAgICAvLyBGaWx0ZXIgb3V0IFNoaW55IG91dHB1dHMsIHdlIG9ubHkgd2FudCB0aGUgc3RhdGljIGtpbmQKICAgICAgICByZXR1cm4gZmlsdGVyQnlDbGFzcyhyZXN1bHRzLCAiaHRtbC13aWRnZXQtb3V0cHV0IiwgZmFsc2UpOwogICAgICB9OwogICAgfSk7CiAgICB3aW5kb3cuSFRNTFdpZGdldHMud2lkZ2V0cy5wdXNoKHN0YXRpY0JpbmRpbmcpOwoKICAgIGlmIChzaGlueU1vZGUpIHsKICAgICAgLy8gU2hpbnkgaXMgcnVubmluZy4gUmVnaXN0ZXIgdGhlIGRlZmluaXRpb24gd2l0aCBhbiBvdXRwdXQgYmluZGluZy4KICAgICAgLy8gVGhlIGRlZmluaXRpb24gaXRzZWxmIHdpbGwgbm90IGJlIHRoZSBvdXRwdXQgYmluZGluZywgaW5zdGVhZAogICAgICAvLyB3ZSB3aWxsIG1ha2UgYW4gb3V0cHV0IGJpbmRpbmcgb2JqZWN0IHRoYXQgZGVsZWdhdGVzIHRvIHRoZQogICAgICAvLyBkZWZpbml0aW9uLiBUaGlzIGlzIGJlY2F1c2Ugd2UgZm9vbGlzaGx5IHVzZWQgdGhlIHNhbWUgbWV0aG9kCiAgICAgIC8vIG5hbWUgKHJlbmRlclZhbHVlKSBmb3IgaHRtbHdpZGdldHMgZGVmaW5pdGlvbiBhbmQgU2hpbnkgYmluZGluZ3MKICAgICAgLy8gYnV0IHRoZXkgYWN0dWFsbHkgaGF2ZSBxdWl0ZSBkaWZmZXJlbnQgc2VtYW50aWNzICh0aGUgU2hpbnkKICAgICAgLy8gYmluZGluZ3MgcmVjZWl2ZSBkYXRhIHRoYXQgaW5jbHVkZXMgbG90cyBvZiBtZXRhZGF0YSB0aGF0IGl0CiAgICAgIC8vIHN0cmlwcyBvZmYgYmVmb3JlIGNhbGxpbmcgaHRtbHdpZGdldHMgcmVuZGVyVmFsdWUpLiBXZSBjYW4ndAogICAgICAvLyBqdXN0IGlnbm9yZSB0aGUgZGlmZmVyZW5jZSBiZWNhdXNlIGluIHNvbWUgd2lkZ2V0cyBpdCdzIGhlbHBmdWwKICAgICAgLy8gdG8gY2FsbCB0aGlzLnJlbmRlclZhbHVlKCkgZnJvbSBpbnNpZGUgb2YgcmVzaXplKCksIGFuZCBpZgogICAgICAvLyB3ZSdyZSBub3QgZGVsZWdhdGluZywgdGhlbiB0aGF0IGNhbGwgd2lsbCBnbyB0byB0aGUgU2hpbnkKICAgICAgLy8gdmVyc2lvbiBpbnN0ZWFkIG9mIHRoZSBodG1sd2lkZ2V0cyB2ZXJzaW9uLgoKICAgICAgLy8gTWVyZ2UgZGVmYXVsdHMgd2l0aCBkZWZpbml0aW9uLCB3aXRob3V0IG11dGF0aW5nIGVpdGhlci4KICAgICAgdmFyIGJpbmRpbmdEZWYgPSBleHRlbmQoe30sIGRlZmF1bHRzLCBkZWZpbml0aW9uKTsKCiAgICAgIC8vIFRoaXMgb2JqZWN0IHdpbGwgYmUgb3VyIGFjdHVhbCBTaGlueSBiaW5kaW5nLgogICAgICB2YXIgc2hpbnlCaW5kaW5nID0gbmV3IFNoaW55Lk91dHB1dEJpbmRpbmcoKTsKCiAgICAgIC8vIFdpdGggYSBmZXcgZXhjZXB0aW9ucywgd2UnbGwgd2FudCB0byBzaW1wbHkgdXNlIHRoZSBiaW5kaW5nRGVmJ3MKICAgICAgLy8gdmVyc2lvbiBvZiBtZXRob2RzIGlmIHRoZXkgYXJlIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIGZhbGwgYmFjayB0bwogICAgICAvLyBTaGlueSdzIGRlZmF1bHRzLiBOT1RFOiBJZiBTaGlueSdzIG91dHB1dCBiaW5kaW5ncyBnYWluIGFkZGl0aW9uYWwKICAgICAgLy8gbWV0aG9kcyBpbiB0aGUgZnV0dXJlLCBhbmQgd2Ugd2FudCB0aGVtIHRvIGJlIG92ZXJyaWRlYWJsZSBieQogICAgICAvLyBIVE1MV2lkZ2V0IGJpbmRpbmcgZGVmaW5pdGlvbnMsIHRoZW4gd2UnbGwgbmVlZCB0byBhZGQgdGhlbSB0byB0aGlzCiAgICAgIC8vIGxpc3QuCiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgImdldElkIik7CiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgIm9uVmFsdWVDaGFuZ2UiKTsKICAgICAgZGVsZWdhdGVNZXRob2Qoc2hpbnlCaW5kaW5nLCBiaW5kaW5nRGVmLCAib25WYWx1ZUVycm9yIik7CiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgInJlbmRlckVycm9yIik7CiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgImNsZWFyRXJyb3IiKTsKICAgICAgZGVsZWdhdGVNZXRob2Qoc2hpbnlCaW5kaW5nLCBiaW5kaW5nRGVmLCAic2hvd1Byb2dyZXNzIik7CgogICAgICAvLyBUaGUgZmluZCwgcmVuZGVyVmFsdWUsIGFuZCByZXNpemUgYXJlIGhhbmRsZWQgZGlmZmVyZW50bHksIGJlY2F1c2Ugd2UKICAgICAgLy8gd2FudCB0byBhY3R1YWxseSBkZWNvcmF0ZSB0aGUgYmVoYXZpb3Igb2YgdGhlIGJpbmRpbmdEZWYgbWV0aG9kcy4KCiAgICAgIHNoaW55QmluZGluZy5maW5kID0gZnVuY3Rpb24oc2NvcGUpIHsKICAgICAgICB2YXIgcmVzdWx0cyA9IGJpbmRpbmdEZWYuZmluZChzY29wZSk7CgogICAgICAgIC8vIE9ubHkgcmV0dXJuIGVsZW1lbnRzIHRoYXQgYXJlIFNoaW55IG91dHB1dHMsIG5vdCBzdGF0aWMgb25lcwogICAgICAgIHZhciBkeW5hbWljUmVzdWx0cyA9IHJlc3VsdHMuZmlsdGVyKCIuaHRtbC13aWRnZXQtb3V0cHV0Iik7CgogICAgICAgIC8vIEl0J3MgcG9zc2libGUgdGhhdCB3aGF0ZXZlciBjYXVzZWQgU2hpbnkgdG8gdGhpbmsgdGhlcmUgbWlnaHQgYmUKICAgICAgICAvLyBuZXcgZHluYW1pYyBvdXRwdXRzLCBhbHNvIGNhdXNlZCB0aGVyZSB0byBiZSBuZXcgc3RhdGljIG91dHB1dHMuCiAgICAgICAgLy8gU2luY2UgdGhlcmUgbWlnaHQgYmUgbG90cyBvZiBkaWZmZXJlbnQgaHRtbHdpZGdldHMgYmluZGluZ3MsIHdlCiAgICAgICAgLy8gc2NoZWR1bGUgZXhlY3V0aW9uIGZvciBsYXRlci0tbm8gbmVlZCB0byBzdGF0aWNSZW5kZXIgbXVsdGlwbGUKICAgICAgICAvLyB0aW1lcy4KICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT09IGR5bmFtaWNSZXN1bHRzLmxlbmd0aCkKICAgICAgICAgIHNjaGVkdWxlU3RhdGljUmVuZGVyKCk7CgogICAgICAgIHJldHVybiBkeW5hbWljUmVzdWx0czsKICAgICAgfTsKCiAgICAgIC8vIFdyYXAgcmVuZGVyVmFsdWUgdG8gaGFuZGxlIGluaXRpYWxpemF0aW9uLCB3aGljaCB1bmZvcnR1bmF0ZWx5IGlzbid0CiAgICAgIC8vIHN1cHBvcnRlZCBuYXRpdmVseSBieSBTaGlueSBhdCB0aGUgdGltZSBvZiB0aGlzIHdyaXRpbmcuCgogICAgICBzaGlueUJpbmRpbmcucmVuZGVyVmFsdWUgPSBmdW5jdGlvbihlbCwgZGF0YSkgewogICAgICAgIFNoaW55LnJlbmRlckRlcGVuZGVuY2llcyhkYXRhLmRlcHMpOwogICAgICAgIC8vIFJlc29sdmUgc3RyaW5ncyBtYXJrZWQgYXMgamF2YXNjcmlwdCBsaXRlcmFscyB0byBvYmplY3RzCiAgICAgICAgaWYgKCEoZGF0YS5ldmFscyBpbnN0YW5jZW9mIEFycmF5KSkgZGF0YS5ldmFscyA9IFtkYXRhLmV2YWxzXTsKICAgICAgICBmb3IgKHZhciBpID0gMDsgZGF0YS5ldmFscyAmJiBpIDwgZGF0YS5ldmFscy5sZW5ndGg7IGkrKykgewogICAgICAgICAgd2luZG93LkhUTUxXaWRnZXRzLmV2YWx1YXRlU3RyaW5nTWVtYmVyKGRhdGEueCwgZGF0YS5ldmFsc1tpXSk7CiAgICAgICAgfQogICAgICAgIGlmICghYmluZGluZ0RlZi5yZW5kZXJPbk51bGxWYWx1ZSkgewogICAgICAgICAgaWYgKGRhdGEueCA9PT0gbnVsbCkgewogICAgICAgICAgICBlbC5zdHlsZS52aXNpYmlsaXR5ID0gImhpZGRlbiI7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVsLnN0eWxlLnZpc2liaWxpdHkgPSAiaW5oZXJpdCI7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghZWxlbWVudERhdGEoZWwsICJpbml0aWFsaXplZCIpKSB7CiAgICAgICAgICBpbml0U2l6aW5nKGVsKTsKCiAgICAgICAgICBlbGVtZW50RGF0YShlbCwgImluaXRpYWxpemVkIiwgdHJ1ZSk7CiAgICAgICAgICBpZiAoYmluZGluZ0RlZi5pbml0aWFsaXplKSB7CiAgICAgICAgICAgIHZhciByZXN1bHQgPSBiaW5kaW5nRGVmLmluaXRpYWxpemUoZWwsIGVsLm9mZnNldFdpZHRoLAogICAgICAgICAgICAgIGVsLm9mZnNldEhlaWdodCk7CiAgICAgICAgICAgIGVsZW1lbnREYXRhKGVsLCAiaW5pdF9yZXN1bHQiLCByZXN1bHQpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBiaW5kaW5nRGVmLnJlbmRlclZhbHVlKGVsLCBkYXRhLngsIGVsZW1lbnREYXRhKGVsLCAiaW5pdF9yZXN1bHQiKSk7CiAgICAgICAgZXZhbEFuZFJ1bihkYXRhLmpzSG9va3MucmVuZGVyLCBlbGVtZW50RGF0YShlbCwgImluaXRfcmVzdWx0IiksIFtlbCwgZGF0YS54XSk7CiAgICAgIH07CgogICAgICAvLyBPbmx5IG92ZXJyaWRlIHJlc2l6ZSBpZiBiaW5kaW5nRGVmIGltcGxlbWVudHMgaXQKICAgICAgaWYgKGJpbmRpbmdEZWYucmVzaXplKSB7CiAgICAgICAgc2hpbnlCaW5kaW5nLnJlc2l6ZSA9IGZ1bmN0aW9uKGVsLCB3aWR0aCwgaGVpZ2h0KSB7CiAgICAgICAgICAvLyBTaGlueSBjYW4gY2FsbCByZXNpemUgYmVmb3JlIGluaXRpYWxpemUvcmVuZGVyVmFsdWUgaGF2ZSBiZWVuCiAgICAgICAgICAvLyBjYWxsZWQsIHdoaWNoIGRvZXNuJ3QgbWFrZSBzZW5zZSBmb3Igd2lkZ2V0cy4KICAgICAgICAgIGlmIChlbGVtZW50RGF0YShlbCwgImluaXRpYWxpemVkIikpIHsKICAgICAgICAgICAgYmluZGluZ0RlZi5yZXNpemUoZWwsIHdpZHRoLCBoZWlnaHQsIGVsZW1lbnREYXRhKGVsLCAiaW5pdF9yZXN1bHQiKSk7CiAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgfQoKICAgICAgU2hpbnkub3V0cHV0QmluZGluZ3MucmVnaXN0ZXIoc2hpbnlCaW5kaW5nLCBiaW5kaW5nRGVmLm5hbWUpOwogICAgfQogIH07CgogIHZhciBzY2hlZHVsZVN0YXRpY1JlbmRlclRpbWVySWQgPSBudWxsOwogIGZ1bmN0aW9uIHNjaGVkdWxlU3RhdGljUmVuZGVyKCkgewogICAgaWYgKCFzY2hlZHVsZVN0YXRpY1JlbmRlclRpbWVySWQpIHsKICAgICAgc2NoZWR1bGVTdGF0aWNSZW5kZXJUaW1lcklkID0gc2V0VGltZW91dChmdW5jdGlvbigpIHsKICAgICAgICBzY2hlZHVsZVN0YXRpY1JlbmRlclRpbWVySWQgPSBudWxsOwogICAgICAgIHdpbmRvdy5IVE1MV2lkZ2V0cy5zdGF0aWNSZW5kZXIoKTsKICAgICAgfSwgMSk7CiAgICB9CiAgfQoKICAvLyBSZW5kZXIgc3RhdGljIHdpZGdldHMgYWZ0ZXIgdGhlIGRvY3VtZW50IGZpbmlzaGVzIGxvYWRpbmcKICAvLyBTdGF0aWNhbGx5IHJlbmRlciBhbGwgZWxlbWVudHMgdGhhdCBhcmUgb2YgdGhpcyB3aWRnZXQncyBjbGFzcwogIHdpbmRvdy5IVE1MV2lkZ2V0cy5zdGF0aWNSZW5kZXIgPSBmdW5jdGlvbigpIHsKICAgIHZhciBiaW5kaW5ncyA9IHdpbmRvdy5IVE1MV2lkZ2V0cy53aWRnZXRzIHx8IFtdOwogICAgZm9yRWFjaChiaW5kaW5ncywgZnVuY3Rpb24oYmluZGluZykgewogICAgICB2YXIgbWF0Y2hlcyA9IGJpbmRpbmcuZmluZChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpOwogICAgICBmb3JFYWNoKG1hdGNoZXMsIGZ1bmN0aW9uKGVsKSB7CiAgICAgICAgdmFyIHNpemVPYmogPSBpbml0U2l6aW5nKGVsLCBiaW5kaW5nKTsKCiAgICAgICAgaWYgKGhhc0NsYXNzKGVsLCAiaHRtbC13aWRnZXQtc3RhdGljLWJvdW5kIikpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgZWwuY2xhc3NOYW1lID0gZWwuY2xhc3NOYW1lICsgIiBodG1sLXdpZGdldC1zdGF0aWMtYm91bmQiOwoKICAgICAgICB2YXIgaW5pdFJlc3VsdDsKICAgICAgICBpZiAoYmluZGluZy5pbml0aWFsaXplKSB7CiAgICAgICAgICBpbml0UmVzdWx0ID0gYmluZGluZy5pbml0aWFsaXplKGVsLAogICAgICAgICAgICBzaXplT2JqID8gc2l6ZU9iai5nZXRXaWR0aCgpIDogZWwub2Zmc2V0V2lkdGgsCiAgICAgICAgICAgIHNpemVPYmogPyBzaXplT2JqLmdldEhlaWdodCgpIDogZWwub2Zmc2V0SGVpZ2h0CiAgICAgICAgICApOwogICAgICAgICAgZWxlbWVudERhdGEoZWwsICJpbml0X3Jlc3VsdCIsIGluaXRSZXN1bHQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGJpbmRpbmcucmVzaXplKSB7CiAgICAgICAgICB2YXIgbGFzdFNpemUgPSB7CiAgICAgICAgICAgIHc6IHNpemVPYmogPyBzaXplT2JqLmdldFdpZHRoKCkgOiBlbC5vZmZzZXRXaWR0aCwKICAgICAgICAgICAgaDogc2l6ZU9iaiA/IHNpemVPYmouZ2V0SGVpZ2h0KCkgOiBlbC5vZmZzZXRIZWlnaHQKICAgICAgICAgIH07CiAgICAgICAgICB2YXIgcmVzaXplSGFuZGxlciA9IGZ1bmN0aW9uKGUpIHsKICAgICAgICAgICAgdmFyIHNpemUgPSB7CiAgICAgICAgICAgICAgdzogc2l6ZU9iaiA/IHNpemVPYmouZ2V0V2lkdGgoKSA6IGVsLm9mZnNldFdpZHRoLAogICAgICAgICAgICAgIGg6IHNpemVPYmogPyBzaXplT2JqLmdldEhlaWdodCgpIDogZWwub2Zmc2V0SGVpZ2h0CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIGlmIChzaXplLncgPT09IDAgJiYgc2l6ZS5oID09PSAwKQogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgaWYgKHNpemUudyA9PT0gbGFzdFNpemUudyAmJiBzaXplLmggPT09IGxhc3RTaXplLmgpCiAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICBsYXN0U2l6ZSA9IHNpemU7CiAgICAgICAgICAgIGJpbmRpbmcucmVzaXplKGVsLCBzaXplLncsIHNpemUuaCwgaW5pdFJlc3VsdCk7CiAgICAgICAgICB9OwoKICAgICAgICAgIG9uKHdpbmRvdywgInJlc2l6ZSIsIHJlc2l6ZUhhbmRsZXIpOwoKICAgICAgICAgIC8vIFRoaXMgaXMgbmVlZGVkIGZvciBjYXNlcyB3aGVyZSB3ZSdyZSBydW5uaW5nIGluIGEgU2hpbnkKICAgICAgICAgIC8vIGFwcCwgYnV0IHRoZSB3aWRnZXQgaXRzZWxmIGlzIG5vdCBhIFNoaW55IG91dHB1dCwgYnV0CiAgICAgICAgICAvLyByYXRoZXIgYSBzaW1wbGUgc3RhdGljIHdpZGdldC4gT25lIGV4YW1wbGUgb2YgdGhpcyBpcwogICAgICAgICAgLy8gYW4gcm1hcmtkb3duIGRvY3VtZW50IHRoYXQgaGFzIHJ1bnRpbWU6c2hpbnkgYW5kIHdpZGdldAogICAgICAgICAgLy8gdGhhdCBpc24ndCBpbiBhIHJlbmRlciBmdW5jdGlvbi4gU2hpbnkgb25seSBrbm93cyB0bwogICAgICAgICAgLy8gY2FsbCByZXNpemUgaGFuZGxlcnMgZm9yIFNoaW55IG91dHB1dHMsIG5vdCBmb3Igc3RhdGljCiAgICAgICAgICAvLyB3aWRnZXRzLCBzbyB3ZSBkbyBpdCBvdXJzZWx2ZXMuCiAgICAgICAgICBpZiAod2luZG93LmpRdWVyeSkgewogICAgICAgICAgICB3aW5kb3cualF1ZXJ5KGRvY3VtZW50KS5vbigKICAgICAgICAgICAgICAic2hvd24uaHRtbHdpZGdldHMgc2hvd24uYnMudGFiLmh0bWx3aWRnZXRzIHNob3duLmJzLmNvbGxhcHNlLmh0bWx3aWRnZXRzIiwKICAgICAgICAgICAgICByZXNpemVIYW5kbGVyCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHdpbmRvdy5qUXVlcnkoZG9jdW1lbnQpLm9uKAogICAgICAgICAgICAgICJoaWRkZW4uaHRtbHdpZGdldHMgaGlkZGVuLmJzLnRhYi5odG1sd2lkZ2V0cyBoaWRkZW4uYnMuY29sbGFwc2UuaHRtbHdpZGdldHMiLAogICAgICAgICAgICAgIHJlc2l6ZUhhbmRsZXIKICAgICAgICAgICAgKTsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBUaGlzIGlzIG5lZWRlZCBmb3IgdGhlIHNwZWNpZmljIGNhc2Ugb2YgaW9zbGlkZXMsIHdoaWNoCiAgICAgICAgICAvLyBmbGlwcyBzbGlkZXMgYmV0d2VlbiBkaXNwbGF5Om5vbmUgYW5kIGRpc3BsYXk6YmxvY2suCiAgICAgICAgICAvLyBJZGVhbGx5IHdlIHdvdWxkIG5vdCBoYXZlIHRvIGhhdmUgaW9zbGlkZS1zcGVjaWZpYyBjb2RlCiAgICAgICAgICAvLyBoZXJlLCBidXQgcmF0aGVyIGhhdmUgaW9zbGlkZXMgcmFpc2UgYSBnZW5lcmljIGV2ZW50LAogICAgICAgICAgLy8gYnV0IHRoZSBybWFya2Rvd24gcGFja2FnZSBqdXN0IHdlbnQgdG8gQ1JBTiBzbyB0aGUKICAgICAgICAgIC8vIHdpbmRvdyB0byBnZXR0aW5nIHRoYXQgZml4ZWQgbWF5IGJlIGxvbmcuCiAgICAgICAgICBpZiAod2luZG93LmFkZEV2ZW50TGlzdGVuZXIpIHsKICAgICAgICAgICAgLy8gSXQncyBPSyB0byBsaW1pdCB0aGlzIHRvIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyCiAgICAgICAgICAgIC8vIGJyb3dzZXJzIGJlY2F1c2UgaW9zbGlkZXMgaXRzZWxmIG9ubHkgc3VwcG9ydHMKICAgICAgICAgICAgLy8gc3VjaCBicm93c2Vycy4KICAgICAgICAgICAgb24oZG9jdW1lbnQsICJzbGlkZWVudGVyIiwgcmVzaXplSGFuZGxlcik7CiAgICAgICAgICAgIG9uKGRvY3VtZW50LCAic2xpZGVsZWF2ZSIsIHJlc2l6ZUhhbmRsZXIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdmFyIHNjcmlwdERhdGEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJzY3JpcHRbZGF0YS1mb3I9JyIgKyBlbC5pZCArICInXVt0eXBlPSdhcHBsaWNhdGlvbi9qc29uJ10iKTsKICAgICAgICBpZiAoc2NyaXB0RGF0YSkgewogICAgICAgICAgdmFyIGRhdGEgPSBKU09OLnBhcnNlKHNjcmlwdERhdGEudGV4dENvbnRlbnQgfHwgc2NyaXB0RGF0YS50ZXh0KTsKICAgICAgICAgIC8vIFJlc29sdmUgc3RyaW5ncyBtYXJrZWQgYXMgamF2YXNjcmlwdCBsaXRlcmFscyB0byBvYmplY3RzCiAgICAgICAgICBpZiAoIShkYXRhLmV2YWxzIGluc3RhbmNlb2YgQXJyYXkpKSBkYXRhLmV2YWxzID0gW2RhdGEuZXZhbHNdOwogICAgICAgICAgZm9yICh2YXIgayA9IDA7IGRhdGEuZXZhbHMgJiYgayA8IGRhdGEuZXZhbHMubGVuZ3RoOyBrKyspIHsKICAgICAgICAgICAgd2luZG93LkhUTUxXaWRnZXRzLmV2YWx1YXRlU3RyaW5nTWVtYmVyKGRhdGEueCwgZGF0YS5ldmFsc1trXSk7CiAgICAgICAgICB9CiAgICAgICAgICBiaW5kaW5nLnJlbmRlclZhbHVlKGVsLCBkYXRhLngsIGluaXRSZXN1bHQpOwogICAgICAgICAgZXZhbEFuZFJ1bihkYXRhLmpzSG9va3MucmVuZGVyLCBpbml0UmVzdWx0LCBbZWwsIGRhdGEueF0pOwogICAgICAgIH0KICAgICAgfSk7CiAgICB9KTsKCiAgICBpbnZva2VQb3N0UmVuZGVySGFuZGxlcnMoKTsKICB9CgogIC8vIFdhaXQgdW50aWwgYWZ0ZXIgdGhlIGRvY3VtZW50IGhhcyBsb2FkZWQgdG8gcmVuZGVyIHRoZSB3aWRnZXRzLgogIGlmIChkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKSB7CiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwgZnVuY3Rpb24oKSB7CiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLCBhcmd1bWVudHMuY2FsbGVlLCBmYWxzZSk7CiAgICAgIHdpbmRvdy5IVE1MV2lkZ2V0cy5zdGF0aWNSZW5kZXIoKTsKICAgIH0sIGZhbHNlKTsKICB9IGVsc2UgaWYgKGRvY3VtZW50LmF0dGFjaEV2ZW50KSB7CiAgICBkb2N1bWVudC5hdHRhY2hFdmVudCgib25yZWFkeXN0YXRlY2hhbmdlIiwgZnVuY3Rpb24oKSB7CiAgICAgIGlmIChkb2N1bWVudC5yZWFkeVN0YXRlID09PSAiY29tcGxldGUiKSB7CiAgICAgICAgZG9jdW1lbnQuZGV0YWNoRXZlbnQoIm9ucmVhZHlzdGF0ZWNoYW5nZSIsIGFyZ3VtZW50cy5jYWxsZWUpOwogICAgICAgIHdpbmRvdy5IVE1MV2lkZ2V0cy5zdGF0aWNSZW5kZXIoKTsKICAgICAgfQogICAgfSk7CiAgfQoKCiAgd2luZG93LkhUTUxXaWRnZXRzLmdldEF0dGFjaG1lbnRVcmwgPSBmdW5jdGlvbihkZXBuYW1lLCBrZXkpIHsKICAgIC8vIElmIG5vIGtleSwgZGVmYXVsdCB0byB0aGUgZmlyc3QgaXRlbQogICAgaWYgKHR5cGVvZihrZXkpID09PSAidW5kZWZpbmVkIikKICAgICAga2V5ID0gMTsKCiAgICB2YXIgbGluayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGRlcG5hbWUgKyAiLSIgKyBrZXkgKyAiLWF0dGFjaG1lbnQiKTsKICAgIGlmICghbGluaykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoIkF0dGFjaG1lbnQgIiArIGRlcG5hbWUgKyAiLyIgKyBrZXkgKyAiIG5vdCBmb3VuZCBpbiBkb2N1bWVudCIpOwogICAgfQogICAgcmV0dXJuIGxpbmsuZ2V0QXR0cmlidXRlKCJocmVmIik7CiAgfTsKCiAgd2luZG93LkhUTUxXaWRnZXRzLmRhdGFmcmFtZVRvRDMgPSBmdW5jdGlvbihkZikgewogICAgdmFyIG5hbWVzID0gW107CiAgICB2YXIgbGVuZ3RoOwogICAgZm9yICh2YXIgbmFtZSBpbiBkZikgewogICAgICAgIGlmIChkZi5oYXNPd25Qcm9wZXJ0eShuYW1lKSkKICAgICAgICAgICAgbmFtZXMucHVzaChuYW1lKTsKICAgICAgICBpZiAodHlwZW9mKGRmW25hbWVdKSAhPT0gIm9iamVjdCIgfHwgdHlwZW9mKGRmW25hbWVdLmxlbmd0aCkgPT09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiQWxsIGZpZWxkcyBtdXN0IGJlIGFycmF5cyIpOwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mKGxlbmd0aCkgIT09ICJ1bmRlZmluZWQiICYmIGxlbmd0aCAhPT0gZGZbbmFtZV0ubGVuZ3RoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiQWxsIGZpZWxkcyBtdXN0IGJlIGFycmF5cyBvZiB0aGUgc2FtZSBsZW5ndGgiKTsKICAgICAgICB9CiAgICAgICAgbGVuZ3RoID0gZGZbbmFtZV0ubGVuZ3RoOwogICAgfQogICAgdmFyIHJlc3VsdHMgPSBbXTsKICAgIHZhciBpdGVtOwogICAgZm9yICh2YXIgcm93ID0gMDsgcm93IDwgbGVuZ3RoOyByb3crKykgewogICAgICAgIGl0ZW0gPSB7fTsKICAgICAgICBmb3IgKHZhciBjb2wgPSAwOyBjb2wgPCBuYW1lcy5sZW5ndGg7IGNvbCsrKSB7CiAgICAgICAgICAgIGl0ZW1bbmFtZXNbY29sXV0gPSBkZltuYW1lc1tjb2xdXVtyb3ddOwogICAgICAgIH0KICAgICAgICByZXN1bHRzLnB1c2goaXRlbSk7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0czsKICB9OwoKICB3aW5kb3cuSFRNTFdpZGdldHMudHJhbnNwb3NlQXJyYXkyRCA9IGZ1bmN0aW9uKGFycmF5KSB7CiAgICAgIGlmIChhcnJheS5sZW5ndGggPT09IDApIHJldHVybiBhcnJheTsKICAgICAgdmFyIG5ld0FycmF5ID0gYXJyYXlbMF0ubWFwKGZ1bmN0aW9uKGNvbCwgaSkgewogICAgICAgICAgcmV0dXJuIGFycmF5Lm1hcChmdW5jdGlvbihyb3cpIHsKICAgICAgICAgICAgICByZXR1cm4gcm93W2ldCiAgICAgICAgICB9KQogICAgICB9KTsKICAgICAgcmV0dXJuIG5ld0FycmF5OwogIH07CiAgLy8gU3BsaXQgdmFsdWUgYXQgc3BsaXRDaGFyLCBidXQgYWxsb3cgc3BsaXRDaGFyIHRvIGJlIGVzY2FwZWQKICAvLyB1c2luZyBlc2NhcGVDaGFyLiBBbnkgb3RoZXIgY2hhcmFjdGVycyBlc2NhcGVkIGJ5IGVzY2FwZUNoYXIKICAvLyB3aWxsIGJlIGluY2x1ZGVkIGFzIHVzdWFsIChpbmNsdWRpbmcgZXNjYXBlQ2hhciBpdHNlbGYpLgogIGZ1bmN0aW9uIHNwbGl0V2l0aEVzY2FwZSh2YWx1ZSwgc3BsaXRDaGFyLCBlc2NhcGVDaGFyKSB7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgdmFyIGVzY2FwZU1vZGUgPSBmYWxzZTsKICAgIHZhciBjdXJyZW50UmVzdWx0ID0gIiI7CiAgICBmb3IgKHZhciBwb3MgPSAwOyBwb3MgPCB2YWx1ZS5sZW5ndGg7IHBvcysrKSB7CiAgICAgIGlmICghZXNjYXBlTW9kZSkgewogICAgICAgIGlmICh2YWx1ZVtwb3NdID09PSBzcGxpdENoYXIpIHsKICAgICAgICAgIHJlc3VsdHMucHVzaChjdXJyZW50UmVzdWx0KTsKICAgICAgICAgIGN1cnJlbnRSZXN1bHQgPSAiIjsKICAgICAgICB9IGVsc2UgaWYgKHZhbHVlW3Bvc10gPT09IGVzY2FwZUNoYXIpIHsKICAgICAgICAgIGVzY2FwZU1vZGUgPSB0cnVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjdXJyZW50UmVzdWx0ICs9IHZhbHVlW3Bvc107CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGN1cnJlbnRSZXN1bHQgKz0gdmFsdWVbcG9zXTsKICAgICAgICBlc2NhcGVNb2RlID0gZmFsc2U7CiAgICAgIH0KICAgIH0KICAgIGlmIChjdXJyZW50UmVzdWx0ICE9PSAiIikgewogICAgICByZXN1bHRzLnB1c2goY3VycmVudFJlc3VsdCk7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0czsKICB9CiAgLy8gRnVuY3Rpb24gYXV0aG9yZWQgYnkgWWlodWkvSkogQWxsYWlyZQogIHdpbmRvdy5IVE1MV2lkZ2V0cy5ldmFsdWF0ZVN0cmluZ01lbWJlciA9IGZ1bmN0aW9uKG8sIG1lbWJlcikgewogICAgdmFyIHBhcnRzID0gc3BsaXRXaXRoRXNjYXBlKG1lbWJlciwgJy4nLCAnXFwnKTsKICAgIGZvciAodmFyIGkgPSAwLCBsID0gcGFydHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7CiAgICAgIHZhciBwYXJ0ID0gcGFydHNbaV07CiAgICAgIC8vIHBhcnQgbWF5IGJlIGEgY2hhcmFjdGVyIG9yICdudW1lcmljJyBtZW1iZXIgbmFtZQogICAgICBpZiAobyAhPT0gbnVsbCAmJiB0eXBlb2YgbyA9PT0gIm9iamVjdCIgJiYgcGFydCBpbiBvKSB7CiAgICAgICAgaWYgKGkgPT0gKGwgLSAxKSkgeyAvLyBpZiB3ZSBhcmUgYXQgdGhlIGVuZCBvZiB0aGUgbGluZSB0aGVuIGV2YWx1bGF0ZQogICAgICAgICAgaWYgKHR5cGVvZiBvW3BhcnRdID09PSAic3RyaW5nIikKICAgICAgICAgICAgb1twYXJ0XSA9IGV2YWwoIigiICsgb1twYXJ0XSArICIpIik7CiAgICAgICAgfSBlbHNlIHsgLy8gb3RoZXJ3aXNlIGNvbnRpbnVlIHRvIG5leHQgZW1iZWRkZWQgb2JqZWN0CiAgICAgICAgICBvID0gb1twYXJ0XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9OwoKICAvLyBSZXRyaWV2ZSB0aGUgSFRNTFdpZGdldCBpbnN0YW5jZSAoaS5lLiB0aGUgcmV0dXJuIHZhbHVlIG9mIGFuCiAgLy8gSFRNTFdpZGdldCBiaW5kaW5nJ3MgaW5pdGlhbGl6ZSgpIG9yIGZhY3RvcnkoKSBmdW5jdGlvbikKICAvLyBhc3NvY2lhdGVkIHdpdGggYW4gZWxlbWVudCwgb3IgbnVsbCBpZiBub25lLgogIHdpbmRvdy5IVE1MV2lkZ2V0cy5nZXRJbnN0YW5jZSA9IGZ1bmN0aW9uKGVsKSB7CiAgICByZXR1cm4gZWxlbWVudERhdGEoZWwsICJpbml0X3Jlc3VsdCIpOwogIH07CgogIC8vIEZpbmRzIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSBzY29wZSB0aGF0IG1hdGNoZXMgdGhlIHNlbGVjdG9yLAogIC8vIGFuZCByZXR1cm5zIHRoZSBIVE1MV2lkZ2V0IGluc3RhbmNlIChpLmUuIHRoZSByZXR1cm4gdmFsdWUgb2YKICAvLyBhbiBIVE1MV2lkZ2V0IGJpbmRpbmcncyBpbml0aWFsaXplKCkgb3IgZmFjdG9yeSgpIGZ1bmN0aW9uKQogIC8vIGFzc29jaWF0ZWQgd2l0aCB0aGF0IGVsZW1lbnQsIGlmIGFueS4gSWYgbm8gZWxlbWVudCBtYXRjaGVzIHRoZQogIC8vIHNlbGVjdG9yLCBvciB0aGUgZmlyc3QgbWF0Y2hpbmcgZWxlbWVudCBoYXMgbm8gSFRNTFdpZGdldAogIC8vIGluc3RhbmNlIGFzc29jaWF0ZWQgd2l0aCBpdCwgdGhlbiBudWxsIGlzIHJldHVybmVkLgogIC8vCiAgLy8gVGhlIHNjb3BlIGFyZ3VtZW50IGlzIG9wdGlvbmFsLCBhbmQgZGVmYXVsdHMgdG8gd2luZG93LmRvY3VtZW50LgogIHdpbmRvdy5IVE1MV2lkZ2V0cy5maW5kID0gZnVuY3Rpb24oc2NvcGUsIHNlbGVjdG9yKSB7CiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKSB7CiAgICAgIHNlbGVjdG9yID0gc2NvcGU7CiAgICAgIHNjb3BlID0gZG9jdW1lbnQ7CiAgICB9CgogICAgdmFyIGVsID0gc2NvcGUucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7CiAgICBpZiAoZWwgPT09IG51bGwpIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gd2luZG93LkhUTUxXaWRnZXRzLmdldEluc3RhbmNlKGVsKTsKICAgIH0KICB9OwoKICAvLyBGaW5kcyBhbGwgZWxlbWVudHMgaW4gdGhlIHNjb3BlIHRoYXQgbWF0Y2ggdGhlIHNlbGVjdG9yLCBhbmQKICAvLyByZXR1cm5zIHRoZSBIVE1MV2lkZ2V0IGluc3RhbmNlcyAoaS5lLiB0aGUgcmV0dXJuIHZhbHVlcyBvZgogIC8vIGFuIEhUTUxXaWRnZXQgYmluZGluZydzIGluaXRpYWxpemUoKSBvciBmYWN0b3J5KCkgZnVuY3Rpb24pCiAgLy8gYXNzb2NpYXRlZCB3aXRoIHRoZSBlbGVtZW50cywgaW4gYW4gYXJyYXkuIElmIGVsZW1lbnRzIHRoYXQKICAvLyBtYXRjaCB0aGUgc2VsZWN0b3IgZG9uJ3QgaGF2ZSBhbiBhc3NvY2lhdGVkIEhUTUxXaWRnZXQKICAvLyBpbnN0YW5jZSwgdGhlIHJldHVybmVkIGFycmF5IHdpbGwgY29udGFpbiBudWxscy4KICAvLwogIC8vIFRoZSBzY29wZSBhcmd1bWVudCBpcyBvcHRpb25hbCwgYW5kIGRlZmF1bHRzIHRvIHdpbmRvdy5kb2N1bWVudC4KICB3aW5kb3cuSFRNTFdpZGdldHMuZmluZEFsbCA9IGZ1bmN0aW9uKHNjb3BlLCBzZWxlY3RvcikgewogICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMSkgewogICAgICBzZWxlY3RvciA9IHNjb3BlOwogICAgICBzY29wZSA9IGRvY3VtZW50OwogICAgfQoKICAgIHZhciBub2RlcyA9IHNjb3BlLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpOwogICAgdmFyIHJlc3VsdHMgPSBbXTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHsKICAgICAgcmVzdWx0cy5wdXNoKHdpbmRvdy5IVE1MV2lkZ2V0cy5nZXRJbnN0YW5jZShub2Rlc1tpXSkpOwogICAgfQogICAgcmV0dXJuIHJlc3VsdHM7CiAgfTsKCiAgdmFyIHBvc3RSZW5kZXJIYW5kbGVycyA9IFtdOwogIGZ1bmN0aW9uIGludm9rZVBvc3RSZW5kZXJIYW5kbGVycygpIHsKICAgIHdoaWxlIChwb3N0UmVuZGVySGFuZGxlcnMubGVuZ3RoKSB7CiAgICAgIHZhciBoYW5kbGVyID0gcG9zdFJlbmRlckhhbmRsZXJzLnNoaWZ0KCk7CiAgICAgIGlmIChoYW5kbGVyKSB7CiAgICAgICAgaGFuZGxlcigpOwogICAgICB9CiAgICB9CiAgfQoKICAvLyBSZWdpc3RlciB0aGUgZ2l2ZW4gY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgaW52b2tlZCBhZnRlciB0aGUKICAvLyBuZXh0IHRpbWUgc3RhdGljIHdpZGdldHMgYXJlIHJlbmRlcmVkLgogIHdpbmRvdy5IVE1MV2lkZ2V0cy5hZGRQb3N0UmVuZGVySGFuZGxlciA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICBwb3N0UmVuZGVySGFuZGxlcnMucHVzaChjYWxsYmFjayk7CiAgfTsKCiAgLy8gVGFrZXMgYSBuZXctc3R5bGUgaW5zdGFuY2UtYm91bmQgZGVmaW5pdGlvbiwgYW5kIHJldHVybnMgYW4KICAvLyBvbGQtc3R5bGUgY2xhc3MtYm91bmQgZGVmaW5pdGlvbi4gVGhpcyBzYXZlcyB1cyBmcm9tIGhhdmluZwogIC8vIHRvIHJld3JpdGUgYWxsIHRoZSBsb2dpYyBpbiB0aGlzIGZpbGUgdG8gYWNjb21vZGF0ZSBib3RoCiAgLy8gdHlwZXMgb2YgZGVmaW5pdGlvbnMuCiAgZnVuY3Rpb24gY3JlYXRlTGVnYWN5RGVmaW5pdGlvbkFkYXB0ZXIoZGVmbikgewogICAgdmFyIHJlc3VsdCA9IHsKICAgICAgbmFtZTogZGVmbi5uYW1lLAogICAgICB0eXBlOiBkZWZuLnR5cGUsCiAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKGVsLCB3aWR0aCwgaGVpZ2h0KSB7CiAgICAgICAgcmV0dXJuIGRlZm4uZmFjdG9yeShlbCwgd2lkdGgsIGhlaWdodCk7CiAgICAgIH0sCiAgICAgIHJlbmRlclZhbHVlOiBmdW5jdGlvbihlbCwgeCwgaW5zdGFuY2UpIHsKICAgICAgICByZXR1cm4gaW5zdGFuY2UucmVuZGVyVmFsdWUoeCk7CiAgICAgIH0sCiAgICAgIHJlc2l6ZTogZnVuY3Rpb24oZWwsIHdpZHRoLCBoZWlnaHQsIGluc3RhbmNlKSB7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlLnJlc2l6ZSh3aWR0aCwgaGVpZ2h0KTsKICAgICAgfQogICAgfTsKCiAgICBpZiAoZGVmbi5maW5kKQogICAgICByZXN1bHQuZmluZCA9IGRlZm4uZmluZDsKICAgIGlmIChkZWZuLnJlbmRlckVycm9yKQogICAgICByZXN1bHQucmVuZGVyRXJyb3IgPSBkZWZuLnJlbmRlckVycm9yOwogICAgaWYgKGRlZm4uY2xlYXJFcnJvcikKICAgICAgcmVzdWx0LmNsZWFyRXJyb3IgPSBkZWZuLmNsZWFyRXJyb3I7CgogICAgcmV0dXJuIHJlc3VsdDsKICB9Cn0pKCk7Cgo=\"></script>\n",
"<script src=\"data:application/javascript;base64,CkhUTUxXaWRnZXRzLndpZGdldCh7CiAgbmFtZTogInBsb3RseSIsCiAgdHlwZTogIm91dHB1dCIsCgogIGluaXRpYWxpemU6IGZ1bmN0aW9uKGVsLCB3aWR0aCwgaGVpZ2h0KSB7CiAgICByZXR1cm4ge307CiAgfSwKCiAgcmVzaXplOiBmdW5jdGlvbihlbCwgd2lkdGgsIGhlaWdodCwgaW5zdGFuY2UpIHsKICAgIGlmIChpbnN0YW5jZS5hdXRvc2l6ZSkgewogICAgICB2YXIgd2lkdGggPSBpbnN0YW5jZS53aWR0aCB8fCB3aWR0aDsKICAgICAgdmFyIGhlaWdodCA9IGluc3RhbmNlLmhlaWdodCB8fCBoZWlnaHQ7CiAgICAgIFBsb3RseS5yZWxheW91dChlbC5pZCwge3dpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoZWlnaHR9KTsKICAgIH0KICB9LCAgCiAgCiAgcmVuZGVyVmFsdWU6IGZ1bmN0aW9uKGVsLCB4LCBpbnN0YW5jZSkgewogICAgCiAgICAvKiAKICAgIC8gJ2luZm9ybSB0aGUgd29ybGQnIGFib3V0IGhpZ2hsaWdodGluZyBvcHRpb25zIHRoaXMgaXMgc28gb3RoZXIKICAgIC8gY3Jvc3N0YWxrIGxpYnJhcmllcyBoYXZlIGEgY2hhbmNlIHRvIHJlc3BvbmQgdG8gc3BlY2lhbCBzZXR0aW5ncyAKICAgIC8gc3VjaCBhcyBwZXJzaXN0ZW50IHNlbGVjdGlvbi4gCiAgICAvIEFGQUlLLCBsZWFmbGV0IGlzIHRoZSBvbmx5IGxpYnJhcnkgd2l0aCBzdWNoIGludGVyZ3JhdGlvbgogICAgLyBodHRwczovL2dpdGh1Yi5jb20vcnN0dWRpby9sZWFmbGV0L3B1bGwvMzQ2L2ZpbGVzI2RpZmYtYWQwYzJkNTFjZTVmZGY4YzkwYzczOTViMTAyZjQyNjVSMTU0CiAgICAqLwogICAgdmFyIGN0Q29uZmlnID0gY3Jvc3N0YWxrLnZhcigncGxvdGx5Q3Jvc3N0YWxrT3B0cycpLnNldCh4LmhpZ2hsaWdodCk7CiAgICAgIAogICAgaWYgKHR5cGVvZih3aW5kb3cpICE9PSAidW5kZWZpbmVkIikgewogICAgICAvLyBtYWtlIHN1cmUgcGxvdHMgZG9uJ3QgZ2V0IGNyZWF0ZWQgb3V0c2lkZSB0aGUgbmV0d29yayAoZm9yIG9uLXByZW0pCiAgICAgIHdpbmRvdy5QTE9UTFlFTlYgPSB3aW5kb3cuUExPVExZRU5WIHx8IHt9OwogICAgICB3aW5kb3cuUExPVExZRU5WLkJBU0VfVVJMID0geC5iYXNlX3VybDsKICAgICAgCiAgICAgIC8vIEVuYWJsZSBwZXJzaXN0ZW50IHNlbGVjdGlvbiB3aGVuIHNoaWZ0IGtleSBpcyBkb3duCiAgICAgIC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE4Mjg2MTMvY2hlY2staWYtYS1rZXktaXMtZG93bgogICAgICB2YXIgcGVyc2lzdE9uU2hpZnQgPSBmdW5jdGlvbihlKSB7CiAgICAgICAgaWYgKCFlKSB3aW5kb3cuZXZlbnQ7CiAgICAgICAgaWYgKGUuc2hpZnRLZXkpIHsgCiAgICAgICAgICB4LmhpZ2hsaWdodC5wZXJzaXN0ZW50ID0gdHJ1ZTsgCiAgICAgICAgICB4LmhpZ2hsaWdodC5wZXJzaXN0ZW50U2hpZnQgPSB0cnVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB4LmhpZ2hsaWdodC5wZXJzaXN0ZW50ID0gZmFsc2U7IAogICAgICAgICAgeC5oaWdobGlnaHQucGVyc2lzdGVudFNoaWZ0ID0gZmFsc2U7CiAgICAgICAgfQogICAgICB9OwogICAgICAKICAgICAgLy8gT25seSByZWxldmFudCBpZiB3ZSBoYXZlbid0IGZvcmNlZCBwZXJzaXN0ZW50IG1vZGUgYXQgY29tbWFuZCBsaW5lCiAgICAgIGlmICgheC5oaWdobGlnaHQucGVyc2lzdGVudCkgewogICAgICAgIHdpbmRvdy5vbm1vdXNlbW92ZSA9IHBlcnNpc3RPblNoaWZ0OwogICAgICB9CiAgICB9CgogICAgdmFyIGdyYXBoRGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWwuaWQpOwogICAgCiAgICAvLyBUT0RPOiBtb3ZlIHRoZSBjb250cm9sIHBhbmVsIGluamVjdGlvbiBzdHJhdGVneSBpbnNpZGUgaGVyZS4uLgogICAgSFRNTFdpZGdldHMuYWRkUG9zdFJlbmRlckhhbmRsZXIoZnVuY3Rpb24oKSB7CiAgICAgIAogICAgICAvLyBsb3dlciB0aGUgei1pbmRleCBvZiB0aGUgbW9kZWJhciB0byBwcmV2ZW50IGl0IGZyb20gaGlnaGphY2tpbmcgaG92ZXIKICAgICAgLy8gKFRPRE86IGRvIHRoaXMgdmlhIENTUz8pCiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9yb3BlbnNjaS9wbG90bHkvaXNzdWVzLzk1NgogICAgICAvLyBodHRwczovL3d3dy53M3NjaG9vbHMuY29tL2pzcmVmL3Byb3Bfc3R5bGVfemluZGV4LmFzcAogICAgICB2YXIgbW9kZWJhcnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCIuanMtcGxvdGx5LXBsb3QgLnBsb3RseSAubW9kZWJhciIpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1vZGViYXJzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgbW9kZWJhcnNbaV0uc3R5bGUuekluZGV4ID0gMTsKICAgICAgfQogICAgfSk7CiAgICAgIAogICAgICAvLyBpbmplY3QgYSAiY29udHJvbCBwYW5lbCIgaG9sZGluZyBzZWxlY3RpemUvZHluYW1pYyBjb2xvciB3aWRnZXQocykKICAgIGlmICh4LnNlbGVjdGl6ZSB8fCB4LmhpZ2hsaWdodC5keW5hbWljICYmICFpbnN0YW5jZS5wbG90bHkpIHsKICAgICAgdmFyIGZsZXggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKICAgICAgZmxleC5jbGFzcyA9ICJwbG90bHktY3Jvc3N0YWxrLWNvbnRyb2wtcGFuZWwiOwogICAgICBmbGV4LnN0eWxlID0gImRpc3BsYXk6IGZsZXg7IGZsZXgtd3JhcDogd3JhcCI7CiAgICAgIAogICAgICAvLyBpbmplY3QgdGhlIGNvbG91cnBpY2tlciBIVE1MIGNvbnRhaW5lciBpbnRvIHRoZSBmbGV4Ym94CiAgICAgIGlmICh4LmhpZ2hsaWdodC5keW5hbWljKSB7CiAgICAgICAgdmFyIHBpY2tlckRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpOwogICAgICAgIAogICAgICAgIHZhciBwaWNrZXJJbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImlucHV0Iik7CiAgICAgICAgcGlja2VySW5wdXQuaWQgPSBlbC5pZCArICItY29sb3VycGlja2VyIjsKICAgICAgICBwaWNrZXJJbnB1dC5wbGFjZWhvbGRlciA9ICJhc2Rhc2QiOwogICAgICAgIAogICAgICAgIHZhciBwaWNrZXJMYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImxhYmVsIik7CiAgICAgICAgcGlja2VyTGFiZWwuZm9yID0gcGlja2VySW5wdXQuaWQ7CiAgICAgICAgcGlja2VyTGFiZWwuaW5uZXJIVE1MID0gIkJydXNoIGNvbG9yJm5ic3A7Jm5ic3A7IjsKICAgICAgICAKICAgICAgICBwaWNrZXJEaXYuYXBwZW5kQ2hpbGQocGlja2VyTGFiZWwpOwogICAgICAgIHBpY2tlckRpdi5hcHBlbmRDaGlsZChwaWNrZXJJbnB1dCk7CiAgICAgICAgZmxleC5hcHBlbmRDaGlsZChwaWNrZXJEaXYpOwogICAgICB9CiAgICAgIAogICAgICAvLyBpbmplY3Qgc2VsZWN0aXplIEhUTUwgY29udGFpbmVycyAob25lIGZvciBldmVyeSBjcm9zc3RhbGsgZ3JvdXApCiAgICAgIGlmICh4LnNlbGVjdGl6ZSkgewogICAgICAgIHZhciBpZHMgPSBPYmplY3Qua2V5cyh4LnNlbGVjdGl6ZSk7CiAgICAgICAgCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpZHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgIHZhciBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKICAgICAgICAgIGNvbnRhaW5lci5pZCA9IGlkc1tpXTsKICAgICAgICAgIGNvbnRhaW5lci5zdHlsZSA9ICJ3aWR0aDogODAlOyBoZWlnaHQ6IDEwJSI7CiAgICAgICAgICBjb250YWluZXIuY2xhc3MgPSAiZm9ybS1ncm91cCBjcm9zc3RhbGstaW5wdXQtcGxvdGx5LWhpZ2hsaWdodCI7CiAgICAgICAgICAKICAgICAgICAgIHZhciBsYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImxhYmVsIik7CiAgICAgICAgICBsYWJlbC5mb3IgPSBpZHNbaV07CiAgICAgICAgICBsYWJlbC5pbm5lckhUTUwgPSB4LnNlbGVjdGl6ZVtpZHNbaV1dLmdyb3VwOwogICAgICAgICAgbGFiZWwuY2xhc3MgPSAiY29udHJvbC1sYWJlbCI7CiAgICAgICAgICAKICAgICAgICAgIHZhciBzZWxlY3REaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKICAgICAgICAgIHZhciBzZWxlY3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzZWxlY3QiKTsKICAgICAgICAgIHNlbGVjdC5tdWx0aXBsZSA9IHRydWU7CiAgICAgICAgICAKICAgICAgICAgIHNlbGVjdERpdi5hcHBlbmRDaGlsZChzZWxlY3QpOwogICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGxhYmVsKTsKICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChzZWxlY3REaXYpOwogICAgICAgICAgZmxleC5hcHBlbmRDaGlsZChjb250YWluZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICAKICAgICAgLy8gZmluYWxseSwgaW5zZXJ0IHRoZSBmbGV4Ym94IGluc2lkZSB0aGUgaHRtbHdpZGdldCBjb250YWluZXIsCiAgICAgIC8vIGJ1dCBiZWZvcmUgdGhlIHBsb3RseSBncmFwaCBkaXYKICAgICAgZ3JhcGhEaXYucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUoZmxleCwgZ3JhcGhEaXYpOwogICAgICAKICAgICAgaWYgKHguaGlnaGxpZ2h0LmR5bmFtaWMpIHsKICAgICAgICB2YXIgcGlja2VyID0gJCgiIyIgKyBwaWNrZXJJbnB1dC5pZCk7CiAgICAgICAgdmFyIGNvbG9ycyA9IHguaGlnaGxpZ2h0LmNvbG9yIHx8IFtdOwogICAgICAgIC8vIFRPRE86IGxldCB1c2VycyBzcGVjaWZ5IG9wdGlvbnM/CiAgICAgICAgdmFyIG9wdHMgPSB7CiAgICAgICAgICB2YWx1ZTogY29sb3JzWzBdLAogICAgICAgICAgc2hvd0NvbG91cjogImJvdGgiLAogICAgICAgICAgcGFsZXR0ZTogImxpbWl0ZWQiLAogICAgICAgICAgYWxsb3dlZENvbHM6IGNvbG9ycy5qb2luKCIgIiksCiAgICAgICAgICB3aWR0aDogIjIwJSIsCiAgICAgICAgICBoZWlnaHQ6ICIxMCUiCiAgICAgICAgfTsKICAgICAgICBwaWNrZXIuY29sb3VycGlja2VyKHtjaGFuZ2VEZWxheTogMH0pOwogICAgICAgIHBpY2tlci5jb2xvdXJwaWNrZXIoInNldHRpbmdzIiwgb3B0cyk7CiAgICAgICAgcGlja2VyLmNvbG91cnBpY2tlcigidmFsdWUiLCBvcHRzLnZhbHVlKTsKICAgICAgICAvLyBpbmZvcm0gY3Jvc3N0YWxrIGFib3V0IGEgY2hhbmdlIGluIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBjb2xvdXIKICAgICAgICB2YXIgZ3JwcyA9IHguaGlnaGxpZ2h0LmN0R3JvdXBzIHx8IFtdOwogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ3Jwcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgY3Jvc3N0YWxrLmdyb3VwKGdycHNbaV0pLnZhcigncGxvdGx5U2VsZWN0aW9uQ29sb3VyJykKICAgICAgICAgICAgLnNldChwaWNrZXIuY29sb3VycGlja2VyKCd2YWx1ZScpKTsKICAgICAgICB9CiAgICAgICAgcGlja2VyLm9uKCJjaGFuZ2UiLCBmdW5jdGlvbigpIHsKICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ3Jwcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICBjcm9zc3RhbGsuZ3JvdXAoZ3Jwc1tpXSkudmFyKCdwbG90bHlTZWxlY3Rpb25Db2xvdXInKQogICAgICAgICAgICAgIC5zZXQocGlja2VyLmNvbG91cnBpY2tlcigndmFsdWUnKSk7CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICAgIAogICAgLy8gcmVtb3ZlICJzZW5kRGF0YVRvQ2xvdWQiLCB1bmxlc3MgdXNlciBoYXMgc3BlY2lmaWVkIHRoZXkgd2FudCBpdAogICAgeC5jb25maWcgPSB4LmNvbmZpZyB8fCB7fTsKICAgIGlmICgheC5jb25maWcuY2xvdWQpIHsKICAgICAgeC5jb25maWcubW9kZUJhckJ1dHRvbnNUb1JlbW92ZSA9IHguY29uZmlnLm1vZGVCYXJCdXR0b25zVG9SZW1vdmUgfHwgW107CiAgICAgIHguY29uZmlnLm1vZGVCYXJCdXR0b25zVG9SZW1vdmUucHVzaCgic2VuZERhdGFUb0Nsb3VkIik7CiAgICB9CiAgICAKICAgIC8vIGlmIG5vIHBsb3QgZXhpc3RzIHlldCwgY3JlYXRlIG9uZSB3aXRoIGEgcGFydGljdWxhciBjb25maWd1cmF0aW9uCiAgICBpZiAoIWluc3RhbmNlLnBsb3RseSkgewogICAgICAKICAgICAgdmFyIHBsb3QgPSBQbG90bHkucGxvdChncmFwaERpdiwgeCk7CiAgICAgIGluc3RhbmNlLnBsb3RseSA9IHRydWU7CiAgICAgIGluc3RhbmNlLmF1dG9zaXplID0geC5sYXlvdXQuYXV0b3NpemUgfHwgdHJ1ZTsKICAgICAgaW5zdGFuY2Uud2lkdGggPSB4LmxheW91dC53aWR0aDsKICAgICAgaW5zdGFuY2UuaGVpZ2h0ID0geC5sYXlvdXQuaGVpZ2h0OwogICAgICAKICAgIH0gZWxzZSB7CiAgICAgIAogICAgICAvLyBuZXcgeCBkYXRhIGNvdWxkIGNvbnRhaW4gYSBuZXcgaGVpZ2h0L3dpZHRoLi4uCiAgICAgIC8vIGF0dGFjaCB0byBpbnN0YW5jZSBzbyB0aGF0IHJlc2l6ZSBsb2dpYyBrbm93cyBhYm91dCB0aGUgbmV3IHNpemUKICAgICAgaW5zdGFuY2Uud2lkdGggPSB4LmxheW91dC53aWR0aCB8fCBpbnN0YW5jZS53aWR0aDsKICAgICAgaW5zdGFuY2UuaGVpZ2h0ID0geC5sYXlvdXQuaGVpZ2h0IHx8IGluc3RhbmNlLmhlaWdodDsKICAgICAgCiAgICAgIC8vIHRoaXMgaXMgZXNzZW50aWFsbHkgZXF1aXZhbGVudCB0byBQbG90bHkubmV3UGxvdCgpLCBidXQgYXZvaWRzIGNyZWF0aW5nIAogICAgICAvLyBhIG5ldyB3ZWJnbCBjb250ZXh0CiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wbG90bHkvcGxvdGx5LmpzL2Jsb2IvMmIyNGY5ZGVmOTAxODMxZTYxMjgyMDc2Y2YzZjgzNTU5OGQ1NmYwZS9zcmMvcGxvdF9hcGkvcGxvdF9hcGkuanMjTDUzMS1MNTMyCgogICAgICAvLyBUT0RPOiByZXN0b3JlIGNyb3NzdGFsayBzZWxlY3Rpb25zPwogICAgICBQbG90bHkucHVyZ2UoZ3JhcGhEaXYpOwogICAgICAvLyBUT0RPOiB3aHkgaXMgdGhpcyBuZWNlc3NhcnkgdG8gZ2V0IGNyb3NzdGFsayB3b3JraW5nPwogICAgICBncmFwaERpdi5kYXRhID0gdW5kZWZpbmVkOwogICAgICBncmFwaERpdi5sYXlvdXQgPSB1bmRlZmluZWQ7CiAgICAgIHZhciBwbG90ID0gUGxvdGx5LnBsb3QoZ3JhcGhEaXYsIHgpOwogICAgICAKICAgIH0KICAgIAogICAgLy8gVHJpZ2dlciBwbG90bHkuanMgY2FsbHMgZGVmaW5lZCB2aWEgYHBsb3RseVByb3h5KClgCiAgICBwbG90LnRoZW4oZnVuY3Rpb24oKSB7CiAgICAgIGlmIChIVE1MV2lkZ2V0cy5zaGlueU1vZGUpIHsKICAgICAgICBTaGlueS5hZGRDdXN0b21NZXNzYWdlSGFuZGxlcigicGxvdGx5LWNhbGxzIiwgZnVuY3Rpb24obXNnKSB7CiAgICAgICAgICB2YXIgZ2QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChtc2cuaWQpOwogICAgICAgICAgaWYgKCFnZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkNvdWxkbid0IGZpbmQgcGxvdGx5IGdyYXBoIHdpdGggaWQ6ICIgKyBtc2cuaWQpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCFQbG90bHlbbXNnLm1ldGhvZF0pIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJVbmtub3duIG1ldGhvZCAiICsgbXNnLm1ldGhvZCk7CiAgICAgICAgICB9CiAgICAgICAgICB2YXIgYXJncyA9IFtnZF0uY29uY2F0KG1zZy5hcmdzKTsKICAgICAgICAgIFBsb3RseVttc2cubWV0aG9kXS5hcHBseShudWxsLCBhcmdzKTsKICAgICAgICB9KTsKICAgICAgfQogICAgICAKICAgICAgLy8gcGxvdGx5J3MgbWFwYm94IEFQSSBkb2Vzbid0IGN1cnJlbnRseSBzdXBwb3J0IHNldHRpbmcgYm91bmRpbmcgYm94ZXMKICAgICAgLy8gaHR0cHM6Ly93d3cubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvZXhhbXBsZS9maXRib3VuZHMvCiAgICAgIC8vIHNvIHdlIGRvIHRoaXMgbWFudWFsbHkuLi4KICAgICAgLy8gVE9ETzogbWFrZSBzdXJlIHRoaXMgdHJpZ2dlcnMgb24gYSByZWRyYXcgYW5kIHJlbGF5b3V0IGFzIHdlbGwgYXMgb24gaW5pdGlhbCBkcmF3CiAgICAgIHZhciBtYXBib3hJRHMgPSBncmFwaERpdi5fZnVsbExheW91dC5fc3VicGxvdHMubWFwYm94IHx8IFtdOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1hcGJveElEcy5sZW5ndGg7IGkrKykgewogICAgICAgIHZhciBpZCA9IG1hcGJveElEc1tpXTsKICAgICAgICB2YXIgbWFwT3B0cyA9IHgubGF5b3V0W2lkXSB8fCB7fTsKICAgICAgICB2YXIgYXJncyA9IG1hcE9wdHMuX2ZpdEJvdW5kcyB8fCB7fTsKICAgICAgICBpZiAoIWFyZ3MpIHsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICB2YXIgbWFwT2JqID0gZ3JhcGhEaXYuX2Z1bGxMYXlvdXRbaWRdLl9zdWJwbG90Lm1hcDsKICAgICAgICBtYXBPYmouZml0Qm91bmRzKGFyZ3MuYm91bmRzLCBhcmdzLm9wdGlvbnMpOwogICAgICB9CiAgICAgIAogICAgfSk7CiAgICAKICAgIC8vIEF0dGFjaCBhdHRyaWJ1dGVzIChlLmcuLCAia2V5IiwgInoiKSB0byBwbG90bHkgZXZlbnQgZGF0YQogICAgZnVuY3Rpb24gZXZlbnREYXRhV2l0aEtleShldmVudERhdGEpIHsKICAgICAgaWYgKGV2ZW50RGF0YSA9PT0gdW5kZWZpbmVkIHx8ICFldmVudERhdGEuaGFzT3duUHJvcGVydHkoInBvaW50cyIpKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIGV2ZW50RGF0YS5wb2ludHMubWFwKGZ1bmN0aW9uKHB0KSB7CiAgICAgICAgdmFyIG9iaiA9IHsKICAgICAgICAgIGN1cnZlTnVtYmVyOiBwdC5jdXJ2ZU51bWJlciwgCiAgICAgICAgICBwb2ludE51bWJlcjogcHQucG9pbnROdW1iZXIsIAogICAgICAgICAgeDogcHQueCwKICAgICAgICAgIHk6IHB0LnkKICAgICAgICB9OwogICAgICAgIC8qIAogICAgICAgICAgVEw7RFI6IChJIHRoaW5rKSB3ZSBoYXZlIHRvIHNlbGVjdCB0aGUgZ3JhcGggZGl2IChhZ2FpbikgdG8gYXR0YWNoIGtleXMuLi4KICAgICAgICAgIAogICAgICAgICAgV2h5PyBSZW1lbWJlciB0aGF0IGNyb3NzdGFsayB3aWxsIGR5bmFtaWNhbGx5IGFkZC9kZWxldGUgdHJhY2VzIAogICAgICAgICAgKHNlZSB0cmFjZU1hbmFnZXIucHJvdG90eXBlLnVwZGF0ZVNlbGVjdGlvbigpIGJlbG93KQogICAgICAgICAgRm9yIHRoaXMgcmVhc29uLCB3ZSBjYW4ndCBzaW1wbHkgZ3JhYiBrZXlzIGZyb20geC5kYXRhIChsaWtlIHdlIGRpZCBwcmV2aW91c2x5KQogICAgICAgICAgTW9yZW92ZXIsIHdlIGNhbid0IHVzZSBfZnVsbERhdGEsIHNpbmNlIHRoYXQgZG9lc24ndCBpbmNsdWRlIAogICAgICAgICAgdW5vZmZpY2lhbCBhdHRyaWJ1dGVzLiBJdCdzIHRydWUgdGhhdCBjbGljay9ob3ZlciBldmVudHMgZmlyZSB3aXRoIAogICAgICAgICAgcHQuZGF0YSwgYnV0IGRyYWcgZXZlbnRzIGRvbid0Li4uCiAgICAgICAgKi8KICAgICAgICB2YXIgZ2QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbC5pZCk7CiAgICAgICAgdmFyIHRyYWNlID0gZ2QuZGF0YVtwdC5jdXJ2ZU51bWJlcl07CiAgICAgICAgCiAgICAgICAgLy8gQWRkIG90aGVyIGF0dHJpYnV0ZXMgaGVyZSwgaWYgZGVzaXJlZAogICAgICAgIGlmICghdHJhY2UuX2lzU2ltcGxlS2V5KSB7CiAgICAgICAgICB2YXIgYXR0cnNUb0F0dGFjaCA9IFsia2V5IiwgInoiXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gc2ltcGxlIGtleXMgZmlyZSB0aGUgd2hvbGUga2V5CiAgICAgICAgICBvYmoua2V5ID0gdHJhY2Uua2V5OwogICAgICAgICAgdmFyIGF0dHJzVG9BdHRhY2ggPSBbInoiXTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhdHRyc1RvQXR0YWNoLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICB2YXIgYXR0ciA9IHRyYWNlW2F0dHJzVG9BdHRhY2hbaV1dOwogICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXR0cikpIHsKICAgICAgICAgICAgICAvLyBwb2ludE51bWJlciBjYW4gYmUgYW4gYXJyYXkgKGUuZy4sIGhlYXRtYXBzKQogICAgICAgICAgICAgIC8vIFRPRE86IGNhbiBwb2ludE51bWJlciBiZSAzRD8KICAgICAgICAgICAgICBvYmpbYXR0cnNUb0F0dGFjaFtpXV0gPSB0eXBlb2YgcHQucG9pbnROdW1iZXIgPT09ICJudW1iZXIiID8gCiAgICAgICAgICAgICAgICBhdHRyW3B0LnBvaW50TnVtYmVyXSA6IGF0dHJbcHQucG9pbnROdW1iZXJbMF1dW3B0LnBvaW50TnVtYmVyWzFdXTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9iajsKICAgICAgfSk7CiAgICB9CiAgICAKICAgIC8vIHNlbmQgdXNlciBpbnB1dCBldmVudCBkYXRhIHRvIHNoaW55CiAgICBpZiAoSFRNTFdpZGdldHMuc2hpbnlNb2RlKSB7CiAgICAgIC8vIGh0dHBzOi8vcGxvdC5seS9qYXZhc2NyaXB0L3pvb20tZXZlbnRzLwogICAgICBncmFwaERpdi5vbigncGxvdGx5X3JlbGF5b3V0JywgZnVuY3Rpb24oZCkgewogICAgICAgIFNoaW55Lm9uSW5wdXRDaGFuZ2UoCiAgICAgICAgICAiLmNsaWVudFZhbHVlLXBsb3RseV9yZWxheW91dC0iICsgeC5zb3VyY2UsIAogICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZCkKICAgICAgICApOwogICAgICB9KTsKICAgICAgZ3JhcGhEaXYub24oJ3Bsb3RseV9ob3ZlcicsIGZ1bmN0aW9uKGQpIHsKICAgICAgICBTaGlueS5vbklucHV0Q2hhbmdlKAogICAgICAgICAgIi5jbGllbnRWYWx1ZS1wbG90bHlfaG92ZXItIiArIHguc291cmNlLCAKICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGV2ZW50RGF0YVdpdGhLZXkoZCkpCiAgICAgICAgKTsKICAgICAgfSk7CiAgICAgIGdyYXBoRGl2Lm9uKCdwbG90bHlfY2xpY2snLCBmdW5jdGlvbihkKSB7CiAgICAgICAgU2hpbnkub25JbnB1dENoYW5nZSgKICAgICAgICAgICIuY2xpZW50VmFsdWUtcGxvdGx5X2NsaWNrLSIgKyB4LnNvdXJjZSwgCiAgICAgICAgICBKU09OLnN0cmluZ2lmeShldmVudERhdGFXaXRoS2V5KGQpKQogICAgICAgICk7CiAgICAgIH0pOwogICAgICBncmFwaERpdi5vbigncGxvdGx5X3NlbGVjdGVkJywgZnVuY3Rpb24oZCkgewogICAgICAgIFNoaW55Lm9uSW5wdXRDaGFuZ2UoCiAgICAgICAgICAiLmNsaWVudFZhbHVlLXBsb3RseV9zZWxlY3RlZC0iICsgeC5zb3VyY2UsIAogICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZXZlbnREYXRhV2l0aEtleShkKSkKICAgICAgICApOwogICAgICB9KTsKICAgICAgZ3JhcGhEaXYub24oJ3Bsb3RseV91bmhvdmVyJywgZnVuY3Rpb24oZXZlbnREYXRhKSB7CiAgICAgICAgU2hpbnkub25JbnB1dENoYW5nZSgiLmNsaWVudFZhbHVlLXBsb3RseV9ob3Zlci0iICsgeC5zb3VyY2UsIG51bGwpOwogICAgICB9KTsKICAgICAgZ3JhcGhEaXYub24oJ3Bsb3RseV9kb3VibGVjbGljaycsIGZ1bmN0aW9uKGV2ZW50RGF0YSkgewogICAgICAgIFNoaW55Lm9uSW5wdXRDaGFuZ2UoIi5jbGllbnRWYWx1ZS1wbG90bHlfY2xpY2stIiArIHguc291cmNlLCBudWxsKTsKICAgICAgfSk7CiAgICAgIC8vICdwbG90bHlfZGVzZWxlY3QnIGlzIGNvZGUgZm9yIGRvdWJsZWNsaWNrIHdoZW4gaW4gc2VsZWN0IG1vZGUKICAgICAgZ3JhcGhEaXYub24oJ3Bsb3RseV9kZXNlbGVjdCcsIGZ1bmN0aW9uKGV2ZW50RGF0YSkgewogICAgICAgIFNoaW55Lm9uSW5wdXRDaGFuZ2UoIi5jbGllbnRWYWx1ZS1wbG90bHlfc2VsZWN0ZWQtIiArIHguc291cmNlLCBudWxsKTsKICAgICAgICBTaGlueS5vbklucHV0Q2hhbmdlKCIuY2xpZW50VmFsdWUtcGxvdGx5X2NsaWNrLSIgKyB4LnNvdXJjZSwgbnVsbCk7CiAgICAgIH0pOwogICAgfSAKICAgIAogICAgCiAgICAvLyBzZW5kIHVzZXIgaW5wdXQgZXZlbnQgZGF0YSB0byBkYXNoUgogICAgLy8gVE9ETzogbWFrZSB0aGlzIG1vcmUgY29uc2lzdGVudCB3aXRoIEdyYXBoKCkgcHJvcHM/CiAgICB2YXIgZGFzaFJ3aWRnZXRzID0gd2luZG93LmRhc2hSd2lkZ2V0cyB8fCB7fTsKICAgIHZhciBkYXNoUm1vZGUgPSB0eXBlb2YgZWwuc2V0UHJvcHMgPT09ICJmdW5jdGlvbiIgJiYKICAgICAgICAgICAgICAgICAgICB0eXBlb2YgZGFzaFJ3aWRnZXRzLmh0bWx3aWRnZXQgPT09ICJmdW5jdGlvbiI7CiAgICBpZiAoZGFzaFJtb2RlKSB7CiAgICAgIGdyYXBoRGl2Lm9uKCdwbG90bHlfcmVsYXlvdXQnLCBmdW5jdGlvbihkKSB7CiAgICAgICAgZWwuc2V0UHJvcHMoeyJpbnB1dF9wbG90bHlfcmVsYXlvdXQiOiBkfSk7CiAgICAgIH0pOwogICAgICBncmFwaERpdi5vbigncGxvdGx5X2hvdmVyJywgZnVuY3Rpb24oZCkgewogICAgICAgIGVsLnNldFByb3BzKHsiaW5wdXRfcGxvdGx5X2hvdmVyIjogZXZlbnREYXRhV2l0aEtleShkKX0pOwogICAgICB9KTsKICAgICAgZ3JhcGhEaXYub24oJ3Bsb3RseV9jbGljaycsIGZ1bmN0aW9uKGQpIHsKICAgICAgICBlbC5zZXRQcm9wcyh7ImlucHV0X3Bsb3RseV9jbGljayI6IGV2ZW50RGF0YVdpdGhLZXkoZCl9KTsKICAgICAgfSk7CiAgICAgIGdyYXBoRGl2Lm9uKCdwbG90bHlfc2VsZWN0ZWQnLCBmdW5jdGlvbihkKSB7CiAgICAgICAgZWwuc2V0UHJvcHMoeyJpbnB1dF9wbG90bHlfc2VsZWN0ZWQiOiBldmVudERhdGFXaXRoS2V5KGQpfSk7CiAgICAgIH0pOwogICAgICBncmFwaERpdi5vbigncGxvdGx5X3VuaG92ZXInLCBmdW5jdGlvbihldmVudERhdGEpIHsKICAgICAgICBlbC5zZXRQcm9wcyh7ImlucHV0X3Bsb3RseV9ob3ZlciI6IG51bGx9KTsKICAgICAgfSk7CiAgICAgIGdyYXBoRGl2Lm9uKCdwbG90bHlfZG91YmxlY2xpY2snLCBmdW5jdGlvbihldmVudERhdGEpIHsKICAgICAgICBlbC5zZXRQcm9wcyh7ImlucHV0X3Bsb3RseV9jbGljayI6IG51bGx9KTsKICAgICAgfSk7CiAgICAgIC8vICdwbG90bHlfZGVzZWxlY3QnIGlzIGNvZGUgZm9yIGRvdWJsZWNsaWNrIHdoZW4gaW4gc2VsZWN0IG1vZGUKICAgICAgZ3JhcGhEaXYub24oJ3Bsb3RseV9kZXNlbGVjdCcsIGZ1bmN0aW9uKGV2ZW50RGF0YSkgewogICAgICAgIGVsLnNldFByb3BzKHsiaW5wdXRfcGxvdGx5X3NlbGVjdGVkIjogbnVsbH0pOwogICAgICAgIGVsLnNldFByb3BzKHsiaW5wdXRfcGxvdGx5X2NsaWNrIjogbnVsbH0pOwogICAgICB9KTsKICAgIH0gCiAgICAKICAgIAogICAgLy8gR2l2ZW4gYW4gYXJyYXkgb2Yge2N1cnZlTnVtYmVyOiB4LCBwb2ludE51bWJlcjogeX0gb2JqZWN0cywKICAgIC8vIHJldHVybiBhIGhhc2ggb2YgewogICAgLy8gICBzZXQxOiB7dmFsdWU6IFtrZXkxLCBrZXkyLCAuLi5dLCBfaXNTaW1wbGVLZXk6IGZhbHNlfSwgCiAgICAvLyAgIHNldDI6IHt2YWx1ZTogW2tleTMsIGtleTQsIC4uLl0sIF9pc1NpbXBsZUtleTogZmFsc2V9CiAgICAvLyB9CiAgICBmdW5jdGlvbiBwb2ludHNUb0tleXMocG9pbnRzKSB7CiAgICAgIHZhciBrZXlzQnlTZXQgPSB7fTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAKICAgICAgICB2YXIgdHJhY2UgPSBncmFwaERpdi5kYXRhW3BvaW50c1tpXS5jdXJ2ZU51bWJlcl07CiAgICAgICAgaWYgKCF0cmFjZS5rZXkgfHwgIXRyYWNlLnNldCkgewogICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIHNldCBkZWZhdWx0cyBmb3IgdGhpcyBrZXlTZXQKICAgICAgICAvLyBub3RlIHRoYXQgd2UgZG9uJ3QgdHJhY2sgdGhlIG5lc3RlZCBwcm9wZXJ0eSAoeWV0KSBzaW5jZSB3ZSBhbHdheXMgCiAgICAgICAgLy8gZW1pdCB0aGUgdW5pb24gLS0gaHR0cDovL2Nwc2lldmVydC5naXRodWIuaW8vdGFsa3MvMjAxNjEyMTJiLyMyMQogICAgICAgIGtleXNCeVNldFt0cmFjZS5zZXRdID0ga2V5c0J5U2V0W3RyYWNlLnNldF0gfHwgewogICAgICAgICAgdmFsdWU6IFtdLAogICAgICAgICAgX2lzU2ltcGxlS2V5OiB0cmFjZS5faXNTaW1wbGVLZXkKICAgICAgICB9OwogICAgICAgIAogICAgICAgIC8vIFVzZSBwb2ludE51bWJlciBieSBkZWZhdWx0LCBidXQgYWdncmVnYXRlZCB0cmFjZXMgc2hvdWxkIGVtaXQgcG9pbnROdW1iZXJzCiAgICAgICAgdmFyIHB0TnVtID0gcG9pbnRzW2ldLnBvaW50TnVtYmVyOwogICAgICAgIHZhciBoYXNQdE51bSA9IHR5cGVvZiBwdE51bSA9PT0gIm51bWJlciI7CiAgICAgICAgdmFyIHB0TnVtID0gaGFzUHROdW0gPyBwdE51bSA6IHBvaW50c1tpXS5wb2ludE51bWJlcnM7CiAgICAgICAgCiAgICAgICAgLy8gc2VsZWN0aW5nIGEgcG9pbnQgb2YgYSAic2ltcGxlIiB0cmFjZSBtZWFuczogc2VsZWN0IHRoZSAKICAgICAgICAvLyBlbnRpcmUga2V5IGF0dGFjaGVkIHRvIHRoaXMgdHJhY2UsIHdoaWNoIGlzIHVzZWZ1bCBmb3IsCiAgICAgICAgLy8gc2F5IGNsaWNraW5nIG9uIGEgZml0dGVkIGxpbmUgdG8gc2VsZWN0IGNvcnJlc3BvbmRpbmcgb2JzZXJ2YXRpb25zIAogICAgICAgIHZhciBrZXkgPSB0cmFjZS5faXNTaW1wbGVLZXkgPyB0cmFjZS5rZXkgOiBBcnJheS5pc0FycmF5KHB0TnVtKSA/IHB0TnVtLm1hcChmdW5jdGlvbihpZHgpIHsgcmV0dXJuIHRyYWNlLmtleVtpZHhdOyB9KSA6IHRyYWNlLmtleVtwdE51bV07CiAgICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMDg2NTAyNS9tZXJnZS1mbGF0dGVuLWFuLWFycmF5LW9mLWFycmF5cy1pbi1qYXZhc2NyaXB0CiAgICAgICAgdmFyIGtleUZsYXQgPSB0cmFjZS5faXNOZXN0ZWRLZXkgPyBbXS5jb25jYXQuYXBwbHkoW10sIGtleSkgOiBrZXk7CiAgICAgICAgCiAgICAgICAgLy8gVE9ETzogYmV0dGVyIHRvIG9ubHkgYWRkIG5ldyB2YWx1ZXM/CiAgICAgICAga2V5c0J5U2V0W3RyYWNlLnNldF0udmFsdWUgPSBrZXlzQnlTZXRbdHJhY2Uuc2V0XS52YWx1ZS5jb25jYXQoa2V5RmxhdCk7CiAgICAgIH0KICAgICAgCiAgICAgIHJldHVybiBrZXlzQnlTZXQ7CiAgICB9CiAgICAKICAgIAogICAgeC5oaWdobGlnaHQuY29sb3IgPSB4LmhpZ2hsaWdodC5jb2xvciB8fCBbXTsKICAgIC8vIG1ha2Ugc3VyZSBoaWdobGlnaHQgY29sb3IgaXMgYW4gYXJyYXkKICAgIGlmICghQXJyYXkuaXNBcnJheSh4LmhpZ2hsaWdodC5jb2xvcikpIHsKICAgICAgeC5oaWdobGlnaHQuY29sb3IgPSBbeC5oaWdobGlnaHQuY29sb3JdOwogICAgfQoKICAgIHZhciB0cmFjZU1hbmFnZXIgPSBuZXcgVHJhY2VNYW5hZ2VyKGdyYXBoRGl2LCB4LmhpZ2hsaWdodCk7CgogICAgLy8gR2F0aGVyIGFsbCAqdW5pcXVlKiBzZXRzLgogICAgdmFyIGFsbFNldHMgPSBbXTsKICAgIGZvciAodmFyIGN1cnZlSWR4ID0gMDsgY3VydmVJZHggPCB4LmRhdGEubGVuZ3RoOyBjdXJ2ZUlkeCsrKSB7CiAgICAgIHZhciBuZXdTZXQgPSB4LmRhdGFbY3VydmVJZHhdLnNldDsKICAgICAgaWYgKG5ld1NldCkgewogICAgICAgIGlmIChhbGxTZXRzLmluZGV4T2YobmV3U2V0KSA9PT0gLTEpIHsKICAgICAgICAgIGFsbFNldHMucHVzaChuZXdTZXQpOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8vIHJlZ2lzdGVyIGV2ZW50IGxpc3RlbmVycyBmb3IgYWxsIHNldHMKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYWxsU2V0cy5sZW5ndGg7IGkrKykgewogICAgICAKICAgICAgdmFyIHNldCA9IGFsbFNldHNbaV07CiAgICAgIHZhciBzZWxlY3Rpb24gPSBuZXcgY3Jvc3N0YWxrLlNlbGVjdGlvbkhhbmRsZShzZXQpOwogICAgICB2YXIgZmlsdGVyID0gbmV3IGNyb3NzdGFsay5GaWx0ZXJIYW5kbGUoc2V0KTsKICAgICAgCiAgICAgIHZhciBmaWx0ZXJDaGFuZ2UgPSBmdW5jdGlvbihlKSB7CiAgICAgICAgcmVtb3ZlQnJ1c2goZWwpOwogICAgICAgIHRyYWNlTWFuYWdlci51cGRhdGVGaWx0ZXIoc2V0LCBlLnZhbHVlKTsKICAgICAgfTsKICAgICAgZmlsdGVyLm9uKCJjaGFuZ2UiLCBmaWx0ZXJDaGFuZ2UpOwogICAgICAKICAgICAgCiAgICAgIHZhciBzZWxlY3Rpb25DaGFuZ2UgPSBmdW5jdGlvbihlKSB7CiAgICAgICAgCiAgICAgICAgLy8gV29ya2Fyb3VuZCBmb3IgJ3Bsb3RseV9zZWxlY3RlZCcgbm93IGZpcmluZyBwcmV2aW91c2x5IHNlbGVjdGVkCiAgICAgICAgLy8gcG9pbnRzIChpbiBhZGRpdGlvbiB0byBuZXcgb25lcykgd2hlbiBob2xkaW5nIHNoaWZ0IGtleS4gSW4gb3VyIGNhc2UsCiAgICAgICAgLy8gd2UganVzdCB3YW50IHRoZSBuZXcga2V5cyAKICAgICAgICBpZiAoeC5oaWdobGlnaHQub24gPT09ICJwbG90bHlfc2VsZWN0ZWQiICYmIHguaGlnaGxpZ2h0LnBlcnNpc3RlbnRTaGlmdCkgewogICAgICAgICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTE4NzUxOC9ob3ctdG8tZ2V0LXRoZS1kaWZmZXJlbmNlLWJldHdlZW4tdHdvLWFycmF5cy1pbi1qYXZhc2NyaXB0CiAgICAgICAgICBBcnJheS5wcm90b3R5cGUuZGlmZiA9IGZ1bmN0aW9uKGEpIHsKICAgICAgICAgICAgICByZXR1cm4gdGhpcy5maWx0ZXIoZnVuY3Rpb24oaSkge3JldHVybiBhLmluZGV4T2YoaSkgPCAwO30pOwogICAgICAgICAgfTsKICAgICAgICAgIGUudmFsdWUgPSBlLnZhbHVlLmRpZmYoZS5vbGRWYWx1ZSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIGFycmF5IG9mICJldmVudCBvYmplY3RzIiB0cmFja2luZyB0aGUgc2VsZWN0aW9uIGhpc3RvcnkKICAgICAgICAvLyB0aGlzIGlzIHVzZWQgdG8gYXZvaWQgYWRkaW5nIHJlZHVuZGFudCBzZWxlY3Rpb25zCiAgICAgICAgdmFyIHNlbGVjdGlvbkhpc3RvcnkgPSBjcm9zc3RhbGsudmFyKCJwbG90bHlTZWxlY3Rpb25IaXN0b3J5IikuZ2V0KCkgfHwgW107CiAgICAgICAgCiAgICAgICAgLy8gQ29uc3RydWN0IGFuIGV2ZW50IG9iamVjdCAiZGVmaW5pbmciIHRoZSBjdXJyZW50IGV2ZW50LiAKICAgICAgICB2YXIgZXZlbnQgPSB7CiAgICAgICAgICByZWNlaXZlcklEOiB0cmFjZU1hbmFnZXIuZ2QuaWQsCiAgICAgICAgICBwbG90bHlTZWxlY3Rpb25Db2xvdXI6IGNyb3NzdGFsay5ncm91cChzZXQpLnZhcigicGxvdGx5U2VsZWN0aW9uQ29sb3VyIikuZ2V0KCkKICAgICAgICB9OwogICAgICAgIGV2ZW50W3NldF0gPSBlLnZhbHVlOwogICAgICAgIC8vIFRPRE86IGlzIHRoZXJlIGEgc21hcnRlciB3YXkgdG8gY2hlY2sgb2JqZWN0IGVxdWFsaXR5PwogICAgICAgIGlmIChzZWxlY3Rpb25IaXN0b3J5Lmxlbmd0aCA+IDApIHsKICAgICAgICAgIHZhciBldiA9IEpTT04uc3RyaW5naWZ5KGV2ZW50KTsKICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsZWN0aW9uSGlzdG9yeS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICB2YXIgc2VsID0gSlNPTi5zdHJpbmdpZnkoc2VsZWN0aW9uSGlzdG9yeVtpXSk7CiAgICAgICAgICAgIGlmIChzZWwgPT0gZXYpIHsKICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gYWNjdW11bGF0ZSBoaXN0b3J5IGZvciBwZXJzaXN0ZW50IHNlbGVjdGlvbgogICAgICAgIGlmICgheC5oaWdobGlnaHQucGVyc2lzdGVudCkgewogICAgICAgICAgc2VsZWN0aW9uSGlzdG9yeSA9IFtldmVudF07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHNlbGVjdGlvbkhpc3RvcnkucHVzaChldmVudCk7CiAgICAgICAgfQogICAgICAgIGNyb3NzdGFsay52YXIoInBsb3RseVNlbGVjdGlvbkhpc3RvcnkiKS5zZXQoc2VsZWN0aW9uSGlzdG9yeSk7CiAgICAgICAgCiAgICAgICAgLy8gZG8gdGhlIGFjdHVhbCB1cGRhdGluZyBvZiB0cmFjZXMsIGZyYW1lcywgYW5kIHRoZSBzZWxlY3RpemUgd2lkZ2V0CiAgICAgICAgdHJhY2VNYW5hZ2VyLnVwZGF0ZVNlbGVjdGlvbihzZXQsIGUudmFsdWUpOwogICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9zZWxlY3RpemUvc2VsZWN0aXplLmpzL2Jsb2IvbWFzdGVyL2RvY3MvYXBpLm1kI21ldGhvZHNfaXRlbXMKICAgICAgICBpZiAoeC5zZWxlY3RpemUpIHsKICAgICAgICAgIGlmICgheC5oaWdobGlnaHQucGVyc2lzdGVudCB8fCBlLnZhbHVlID09PSBudWxsKSB7CiAgICAgICAgICAgIHNlbGVjdGl6ZS5jbGVhcih0cnVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHNlbGVjdGl6ZS5hZGRJdGVtcyhlLnZhbHVlLCB0cnVlKTsKICAgICAgICAgIHNlbGVjdGl6ZS5jbG9zZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICBzZWxlY3Rpb24ub24oImNoYW5nZSIsIHNlbGVjdGlvbkNoYW5nZSk7CiAgICAgIAogICAgICAvLyBTZXQgYSBjcm9zc3RhbGsgdmFyaWFibGUgc2VsZWN0aW9uIHZhbHVlLCB0cmlnZ2VyaW5nIGFuIHVwZGF0ZQogICAgICB2YXIgdHVybk9uID0gZnVuY3Rpb24oZSkgewogICAgICAgIGlmIChlKSB7CiAgICAgICAgICB2YXIgc2VsZWN0ZWRLZXlzID0gcG9pbnRzVG9LZXlzKGUucG9pbnRzKTsKICAgICAgICAgIC8vIEtleXMgYXJlIGdyb3VwIG5hbWVzLCB2YWx1ZXMgYXJlIGFycmF5IG9mIHNlbGVjdGVkIGtleXMgZnJvbSBncm91cC4KICAgICAgICAgIGZvciAodmFyIHNldCBpbiBzZWxlY3RlZEtleXMpIHsKICAgICAgICAgICAgaWYgKHNlbGVjdGVkS2V5cy5oYXNPd25Qcm9wZXJ0eShzZXQpKSB7CiAgICAgICAgICAgICAgc2VsZWN0aW9uLnNldChzZWxlY3RlZEtleXNbc2V0XS52YWx1ZSwge3NlbmRlcjogZWx9KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfTsKICAgICAgaWYgKHguaGlnaGxpZ2h0LmRlYm91bmNlID4gMCkgewogICAgICAgIHR1cm5PbiA9IGRlYm91bmNlKHR1cm5PbiwgeC5oaWdobGlnaHQuZGVib3VuY2UpOwogICAgICB9CiAgICAgIGdyYXBoRGl2Lm9uKHguaGlnaGxpZ2h0Lm9uLCB0dXJuT24pOwogICAgICAKICAgICAgZ3JhcGhEaXYub24oeC5oaWdobGlnaHQub2ZmLCBmdW5jdGlvbiB0dXJuT2ZmKGUpIHsKICAgICAgICAvLyByZW1vdmUgYW55IHZpc3VhbCBjbHVlcwogICAgICAgIHJlbW92ZUJydXNoKGVsKTsKICAgICAgICAvLyByZW1vdmUgYW55IHNlbGVjdGlvbiBoaXN0b3J5CiAgICAgICAgY3Jvc3N0YWxrLnZhcigicGxvdGx5U2VsZWN0aW9uSGlzdG9yeSIpLnNldChudWxsKTsKICAgICAgICAvLyB0cmlnZ2VyIHRoZSBhY3R1YWwgcmVtb3ZhbCBvZiBzZWxlY3Rpb24gdHJhY2VzCiAgICAgICAgc2VsZWN0aW9uLnNldChudWxsLCB7c2VuZGVyOiBlbH0pOwogICAgICB9KTsKICAgICAgICAgIAogICAgICAvLyByZWdpc3RlciBhIGNhbGxiYWNrIGZvciBzZWxlY3RpemUgc28gdGhhdCB0aGVyZSBpcyBiaS1kaXJlY3Rpb25hbAogICAgICAvLyBjb21tdW5pY2F0aW9uIGJldHdlZW4gdGhlIHdpZGdldCBhbmQgZGlyZWN0IG1hbmlwdWxhdGlvbiBldmVudHMKICAgICAgaWYgKHguc2VsZWN0aXplKSB7CiAgICAgICAgdmFyIHNlbGVjdGl6ZUlEID0gT2JqZWN0LmtleXMoeC5zZWxlY3RpemUpW2ldOwogICAgICAgIHZhciBpdGVtcyA9IHguc2VsZWN0aXplW3NlbGVjdGl6ZUlEXS5pdGVtczsKICAgICAgICB2YXIgZmlyc3QgPSBbe3ZhbHVlOiAiIiwgbGFiZWw6ICIoQWxsKSJ9XTsKICAgICAgICB2YXIgb3B0cyA9IHsKICAgICAgICAgIG9wdGlvbnM6IGZpcnN0LmNvbmNhdChpdGVtcyksCiAgICAgICAgICBzZWFyY2hGaWVsZDogImxhYmVsIiwKICAgICAgICAgIHZhbHVlRmllbGQ6ICJ2YWx1ZSIsCiAgICAgICAgICBsYWJlbEZpZWxkOiAibGFiZWwiLAogICAgICAgICAgbWF4SXRlbXM6IDUwCiAgICAgICAgfTsKICAgICAgICB2YXIgc2VsZWN0ID0gJCgiIyIgKyBzZWxlY3RpemVJRCkuZmluZCgic2VsZWN0IilbMF07CiAgICAgICAgdmFyIHNlbGVjdGl6ZSA9ICQoc2VsZWN0KS5zZWxlY3RpemUob3B0cylbMF0uc2VsZWN0aXplOwogICAgICAgIC8vIE5PVEU6IHRoaXMgY2FsbGJhY2sgaXMgdHJpZ2dlcmVkIHdoZW4gKmRpcmVjdGx5KiBhbHRlcmluZyAKICAgICAgICAvLyBkcm9wZG93biBpdGVtcwogICAgICAgIHNlbGVjdGl6ZS5vbigiY2hhbmdlIiwgZnVuY3Rpb24oKSB7CiAgICAgICAgICB2YXIgY3VycmVudEl0ZW1zID0gdHJhY2VNYW5hZ2VyLmdyb3VwU2VsZWN0aW9uc1tzZXRdIHx8IFtdOwogICAgICAgICAgaWYgKCF4LmhpZ2hsaWdodC5wZXJzaXN0ZW50KSB7CiAgICAgICAgICAgIHJlbW92ZUJydXNoKGVsKTsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjdXJyZW50SXRlbXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICBzZWxlY3RpemUucmVtb3ZlSXRlbShjdXJyZW50SXRlbXNbaV0sIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICB2YXIgbmV3SXRlbXMgPSBzZWxlY3RpemUuaXRlbXMuZmlsdGVyKGZ1bmN0aW9uKGlkeCkgeyAKICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRJdGVtcy5pbmRleE9mKGlkeCkgPCAwOwogICAgICAgICAgfSk7CiAgICAgICAgICBpZiAobmV3SXRlbXMubGVuZ3RoID4gMCkgewogICAgICAgICAgICB0cmFjZU1hbmFnZXIudXBkYXRlU2VsZWN0aW9uKHNldCwgbmV3SXRlbXMpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gSXRlbSBoYXMgYmVlbiByZW1vdmVkLi4uCiAgICAgICAgICAgIC8vIFRPRE86IHRoaXMgbG9naWMgd29uJ3Qgd29yayBmb3IgZHluYW1pY2FsbHkgY2hhbmdpbmcgcGFsZXR0ZSAKICAgICAgICAgICAgdHJhY2VNYW5hZ2VyLnVwZGF0ZVNlbGVjdGlvbihzZXQsIG51bGwpOwogICAgICAgICAgICB0cmFjZU1hbmFnZXIudXBkYXRlU2VsZWN0aW9uKHNldCwgc2VsZWN0aXplLml0ZW1zKTsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfQogICAgfSAvLyBlbmQgb2Ygc2VsZWN0aW9uQ2hhbmdlCiAgICAKICB9IC8vIGVuZCBvZiByZW5kZXJWYWx1ZQp9KTsgLy8gZW5kIG9mIHdpZGdldCBkZWZpbml0aW9uCgovKioKICogQHBhcmFtIGdyYXBoRGl2IFRoZSBQbG90bHkgZ3JhcGggZGl2CiAqIEBwYXJhbSBoaWdobGlnaHQgQW4gb2JqZWN0IHdpdGggb3B0aW9ucyBmb3IgdXBkYXRpbmcgc2VsZWN0aW9uKHMpCiAqLwpmdW5jdGlvbiBUcmFjZU1hbmFnZXIoZ3JhcGhEaXYsIGhpZ2hsaWdodCkgewogIC8vIFRoZSBQbG90bHkgZ3JhcGggZGl2CiAgdGhpcy5nZCA9IGdyYXBoRGl2OwoKICAvLyBQcmVzZXJ2ZSB0aGUgb3JpZ2luYWwgZGF0YS4KICAvLyBUT0RPOiB0cnkgdXNpbmcgTGliLmV4dGVuZEZsYXQoKSBhcyBkb25lIGluICAKICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGxvdGx5L3Bsb3RseS5qcy9wdWxsLzExMzYgCiAgdGhpcy5vcmlnRGF0YSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZ3JhcGhEaXYuZGF0YSkpOwogIAogIC8vIGF2b2lkIGRvaW5nIHRoaXMgb3ZlciBhbmQgb3ZlcgogIHRoaXMub3JpZ09wYWNpdHkgPSBbXTsKICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMub3JpZ0RhdGEubGVuZ3RoOyBpKyspIHsKICAgIHRoaXMub3JpZ09wYWNpdHlbaV0gPSB0aGlzLm9yaWdEYXRhW2ldLm9wYWNpdHkgfHwgMTsKICB9CgogIC8vIGtleTogZ3JvdXAgbmFtZSwgdmFsdWU6IG51bGwgb3IgYXJyYXkgb2Yga2V5cyByZXByZXNlbnRpbmcgdGhlCiAgLy8gbW9zdCByZWNlbnRseSByZWNlaXZlZCBzZWxlY3Rpb24gZm9yIHRoYXQgZ3JvdXAuCiAgdGhpcy5ncm91cFNlbGVjdGlvbnMgPSB7fTsKICAKICAvLyBzZWxlY3Rpb24gcGFyYW1ldGVycyAoZS5nLiwgdHJhbnNpZW50IHZlcnN1cyBwZXJzaXN0ZW50IHNlbGVjdGlvbikKICB0aGlzLmhpZ2hsaWdodCA9IGhpZ2hsaWdodDsKfQoKVHJhY2VNYW5hZ2VyLnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uKCkgewogIC8vIFRPRE86IFVuaG9vayBhbGwgZXZlbnQgaGFuZGxlcnMKfTsKClRyYWNlTWFuYWdlci5wcm90b3R5cGUudXBkYXRlRmlsdGVyID0gZnVuY3Rpb24oZ3JvdXAsIGtleXMpIHsKCiAgaWYgKHR5cGVvZihrZXlzKSA9PT0gInVuZGVmaW5lZCIgfHwga2V5cyA9PT0gbnVsbCkgewogICAgCiAgICB0aGlzLmdkLmRhdGEgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMub3JpZ0RhdGEpKTsKICAgIAogIH0gZWxzZSB7CiAgCiAgICB2YXIgdHJhY2VzID0gW107CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMub3JpZ0RhdGEubGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIHRyYWNlID0gdGhpcy5vcmlnRGF0YVtpXTsKICAgICAgaWYgKCF0cmFjZS5rZXkgfHwgdHJhY2Uuc2V0ICE9PSBncm91cCkgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIHZhciBtYXRjaEZ1bmMgPSBnZXRNYXRjaEZ1bmModHJhY2UpOwogICAgICB2YXIgbWF0Y2hlcyA9IG1hdGNoRnVuYyh0cmFjZS5rZXksIGtleXMpOwogICAgICAKICAgICAgaWYgKG1hdGNoZXMubGVuZ3RoID4gMCkgewogICAgICAgIGlmICghdHJhY2UuX2lzU2ltcGxlS2V5KSB7CiAgICAgICAgICAvLyBzdWJzZXRBcnJheUF0dHJzIGRvZXNuJ3QgbXV0YXRlIHRyYWNlIChpdCBtYWtlcyBhIG1vZGlmaWVkIGNsb25lKQogICAgICAgICAgdHJhY2UgPSBzdWJzZXRBcnJheUF0dHJzKHRyYWNlLCBtYXRjaGVzKTsKICAgICAgICB9CiAgICAgICAgdHJhY2VzLnB1c2godHJhY2UpOwogICAgICB9CiAgICB9CiAgfQogIAogIHRoaXMuZ2QuZGF0YSA9IHRyYWNlczsKICBQbG90bHkucmVkcmF3KHRoaXMuZ2QpOwogIAogIC8vIE5PVEU6IHdlIHB1cnBvc2VseSBkbyBfbm90XyByZXN0b3JlIHNlbGVjdGlvbihzKSwgc2luY2Ugb24gZmlsdGVyLAogIC8vIGF4aXMgbGlrZWx5IHdpbGwgdXBkYXRlLCBjaGFuZ2luZyB0aGUgcGl4ZWwgLT4gZGF0YSBtYXBwaW5nLCBsZWFkaW5nIAogIC8vIHRvIGEgbGlrZWx5IG1pc21hdGNoIGluIHRoZSBicnVzaCBvdXRsaW5lIGFuZCBoaWdobGlnaHRlZCBtYXJrcwogIAp9OwoKVHJhY2VNYW5hZ2VyLnByb3RvdHlwZS51cGRhdGVTZWxlY3Rpb24gPSBmdW5jdGlvbihncm91cCwga2V5cykgewogIAogIGlmIChrZXlzICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KGtleXMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoIkludmFsaWQga2V5cyBhcmd1bWVudDsgbnVsbCBvciBhcnJheSBleHBlY3RlZCIpOwogIH0KICAKICAvLyBpZiBzZWxlY3Rpb24gaGFzIGJlZW4gY2xlYXJlZCwgb3IgaWYgdGhpcyBpcyB0cmFuc2llbnQKICAvLyBzZWxlY3Rpb24sIGRlbGV0ZSB0aGUgInNlbGVjdGlvbiB0cmFjZXMiCiAgdmFyIG5OZXdUcmFjZXMgPSB0aGlzLmdkLmRhdGEubGVuZ3RoIC0gdGhpcy5vcmlnRGF0YS5sZW5ndGg7CiAgaWYgKGtleXMgPT09IG51bGwgfHwgIXRoaXMuaGlnaGxpZ2h0LnBlcnNpc3RlbnQgJiYgbk5ld1RyYWNlcyA+IDApIHsKICAgIHZhciB0cmFjZXNUb1JlbW92ZSA9IFtdOwogICAgZm9yICh2YXIgaSA9IHRoaXMub3JpZ0RhdGEubGVuZ3RoOyBpIDwgdGhpcy5nZC5kYXRhLmxlbmd0aDsgaSsrKSB7CiAgICAgIHRyYWNlc1RvUmVtb3ZlLnB1c2goaSk7CiAgICB9CiAgICBQbG90bHkuZGVsZXRlVHJhY2VzKHRoaXMuZ2QsIHRyYWNlc1RvUmVtb3ZlKTsKICAgIHRoaXMuZ3JvdXBTZWxlY3Rpb25zW2dyb3VwXSA9IGtleXM7CiAgfSBlbHNlIHsKICAgIC8vIGFkZCB0byB0aGUgZ3JvdXBTZWxlY3Rpb24sIHJhdGhlciB0aGFuIG92ZXJ3cml0aW5nIGl0CiAgICAvLyBUT0RPOiBjYW4gdGhpcyBiZSByZW1vdmVkPwogICAgdGhpcy5ncm91cFNlbGVjdGlvbnNbZ3JvdXBdID0gdGhpcy5ncm91cFNlbGVjdGlvbnNbZ3JvdXBdIHx8IFtdOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBrID0ga2V5c1tpXTsKICAgICAgaWYgKHRoaXMuZ3JvdXBTZWxlY3Rpb25zW2dyb3VwXS5pbmRleE9mKGspIDwgMCkgewogICAgICAgIHRoaXMuZ3JvdXBTZWxlY3Rpb25zW2dyb3VwXS5wdXNoKGspOwogICAgICB9CiAgICB9CiAgfQogIAogIGlmIChrZXlzID09PSBudWxsKSB7CiAgICAKICAgIFBsb3RseS5yZXN0eWxlKHRoaXMuZ2QsIHsib3BhY2l0eSI6IHRoaXMub3JpZ09wYWNpdHl9KTsKICAgIAogIH0gZWxzZSBpZiAoa2V5cy5sZW5ndGggPj0gMSkgewogICAgCiAgICAvLyBwbGFjZWhvbGRlciBmb3IgbmV3ICJzZWxlY3Rpb24gdHJhY2VzIgogICAgdmFyIHRyYWNlcyA9IFtdOwogICAgLy8gdGhpcyB2YXJpYWJsZSBpcyBzZXQgaW4gUi9oaWdobGlnaHQuUgogICAgdmFyIHNlbGVjdGlvbkNvbG91ciA9IGNyb3NzdGFsay5ncm91cChncm91cCkudmFyKCJwbG90bHlTZWxlY3Rpb25Db2xvdXIiKS5nZXQoKSB8fCAKICAgICAgdGhpcy5oaWdobGlnaHQuY29sb3JbMF07CgogICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm9yaWdEYXRhLmxlbmd0aDsgaSsrKSB7CiAgICAgIC8vIFRPRE86IHRyeSB1c2luZyBMaWIuZXh0ZW5kRmxhdCgpIGFzIGRvbmUgaW4gIAogICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGxvdGx5L3Bsb3RseS5qcy9wdWxsLzExMzYgCiAgICAgIHZhciB0cmFjZSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5nZC5kYXRhW2ldKSk7CiAgICAgIGlmICghdHJhY2Uua2V5IHx8IHRyYWNlLnNldCAhPT0gZ3JvdXApIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICAvLyBHZXQgc29ydGVkIGFycmF5IG9mIG1hdGNoaW5nIGluZGljZXMgaW4gdHJhY2Uua2V5CiAgICAgIHZhciBtYXRjaEZ1bmMgPSBnZXRNYXRjaEZ1bmModHJhY2UpOwogICAgICB2YXIgbWF0Y2hlcyA9IG1hdGNoRnVuYyh0cmFjZS5rZXksIGtleXMpOwogICAgICAKICAgICAgaWYgKG1hdGNoZXMubGVuZ3RoID4gMCkgewogICAgICAgIC8vIElmIHRoaXMgaXMgYSAic2ltcGxlIiBrZXksIHRoYXQgbWVhbnMgc2VsZWN0IHRoZSBlbnRpcmUgdHJhY2UKICAgICAgICBpZiAoIXRyYWNlLl9pc1NpbXBsZUtleSkgewogICAgICAgICAgdHJhY2UgPSBzdWJzZXRBcnJheUF0dHJzKHRyYWNlLCBtYXRjaGVzKTsKICAgICAgICB9CiAgICAgICAgLy8gcmVhY2ggaW50byB0aGUgZnVsbCB0cmFjZSBvYmplY3Qgc28gd2UgY2FuIHByb3Blcmx5IHJlZmxlY3QgdGhlIAogICAgICAgIC8vIHNlbGVjdGlvbiBhdHRyaWJ1dGVzIGluIGV2ZXJ5IHZpZXcKICAgICAgICB2YXIgZCA9IHRoaXMuZ2QuX2Z1bGxEYXRhW2ldOwogICAgICAgIAogICAgICAgIC8qIAogICAgICAgIC8gUmVjdXJzaXZlbHkgaW5oZXJpdCBzZWxlY3Rpb24gYXR0cmlidXRlcyBmcm9tIHZhcmlvdXMgc291cmNlcywgCiAgICAgICAgLyBpbiBvcmRlciBvZiBwcmVmZXJlbmNlOgogICAgICAgIC8gICgxKSBvZmZpY2lhbCBwbG90bHkuanMgc2VsZWN0ZWQgYXR0cmlidXRlCiAgICAgICAgLyAgKDIpIGhpZ2hsaWdodChzZWxlY3RlZCA9IGF0dHJzX3NlbGVjdGVkKC4uLikpCiAgICAgICAgKi8KICAgICAgICAvLyBUT0RPOiBpdCB3b3VsZCBiZSBuZWF0IHRvIGhhdmUgYSBkcm9wZG93biB0byBkeW5hbWljYWxseSBzcGVjaWZ5IHRoZXNlIQogICAgICAgICQuZXh0ZW5kKHRydWUsIHRyYWNlLCB0aGlzLmhpZ2hsaWdodC5zZWxlY3RlZCk7CiAgICAgICAgCiAgICAgICAgLy8gaWYgaXQgaXMgZGVmaW5lZCwgb3ZlcnJpZGUgY29sb3Igd2l0aCB0aGUgImR5bmFtaWMgYnJ1c2ggY29sb3IiIgogICAgICAgIGlmIChkLm1hcmtlcikgewogICAgICAgICAgdHJhY2UubWFya2VyID0gdHJhY2UubWFya2VyIHx8IHt9OwogICAgICAgICAgdHJhY2UubWFya2VyLmNvbG9yID0gIHNlbGVjdGlvbkNvbG91ciB8fCB0cmFjZS5tYXJrZXIuY29sb3IgfHwgZC5tYXJrZXIuY29sb3I7CiAgICAgICAgfQogICAgICAgIGlmIChkLmxpbmUpIHsKICAgICAgICAgIHRyYWNlLmxpbmUgPSB0cmFjZS5saW5lIHx8IHt9OwogICAgICAgICAgdHJhY2UubGluZS5jb2xvciA9ICBzZWxlY3Rpb25Db2xvdXIgfHwgdHJhY2UubGluZS5jb2xvciB8fCBkLmxpbmUuY29sb3I7CiAgICAgICAgfQogICAgICAgIGlmIChkLnRleHRmb250KSB7CiAgICAgICAgICB0cmFjZS50ZXh0Zm9udCA9IHRyYWNlLnRleHRmb250IHx8IHt9OwogICAgICAgICAgdHJhY2UudGV4dGZvbnQuY29sb3IgPSAgc2VsZWN0aW9uQ29sb3VyIHx8IHRyYWNlLnRleHRmb250LmNvbG9yIHx8IGQudGV4dGZvbnQuY29sb3I7CiAgICAgICAgfQogICAgICAgIGlmIChkLmZpbGxjb2xvcikgewogICAgICAgICAgLy8gVE9ETzogc2hvdWxkIHNlbGVjdGlvbkNvbG91ciBpbmhlcml0IGFscGhhIGZyb20gdGhlIGV4aXN0aW5nIGZpbGxjb2xvcj8KICAgICAgICAgIHRyYWNlLmZpbGxjb2xvciA9IHNlbGVjdGlvbkNvbG91ciB8fCB0cmFjZS5maWxsY29sb3IgfHwgZC5maWxsY29sb3I7CiAgICAgICAgfQogICAgICAgIC8vIGF0dGFjaCBhIHNlbnNpYmxlIG5hbWUvbGVnZW5kZ3JvdXAKICAgICAgICB0cmFjZS5uYW1lID0gdHJhY2UubmFtZSB8fCBrZXlzLmpvaW4oIjxiciAvPiIpOwogICAgICAgIHRyYWNlLmxlZ2VuZGdyb3VwID0gdHJhY2UubGVnZW5kZ3JvdXAgfHwga2V5cy5qb2luKCI8YnIgLz4iKTsKICAgICAgICAKICAgICAgICAvLyBrZWVwIHRyYWNrIG9mIG1hcHBpbmcgYmV0d2VlbiB0aGlzIG5ldyB0cmFjZSBhbmQgdGhlIHRyYWNlIGl0IHRhcmdldHMKICAgICAgICAvLyAobmVjZXNzYXJ5IGZvciB1cGRhdGluZyBmcmFtZXMgdG8gcmVmbGVjdCB0aGUgc2VsZWN0aW9uIHRyYWNlcykKICAgICAgICB0cmFjZS5fb3JpZ2luYWxJbmRleCA9IGk7CiAgICAgICAgdHJhY2UuX25ld0luZGV4ID0gdGhpcy5nZC5fZnVsbERhdGEubGVuZ3RoICsgdHJhY2VzLmxlbmd0aDsKICAgICAgICB0cmFjZXMucHVzaCh0cmFjZSk7CiAgICAgIH0KICAgIH0KICAgIAogICAgaWYgKHRyYWNlcy5sZW5ndGggPiAwKSB7CiAgICAgIAogICAgICBQbG90bHkuYWRkVHJhY2VzKHRoaXMuZ2QsIHRyYWNlcykudGhlbihmdW5jdGlvbihnZCkgewogICAgICAgIC8vIGluY3JlbWVudGFsbHkgYWRkIHNlbGVjdGlvbiB0cmFjZXMgdG8gZnJhbWVzCiAgICAgICAgLy8gKHRoaXMgaXMgaGVhdmlseSBpbnNwaXJlZCBieSBQbG90bHkuUGxvdHMubW9kaWZ5RnJhbWVzKCkgCiAgICAgICAgLy8gaW4gc3JjL3Bsb3RzL3Bsb3RzLmpzKQogICAgICAgIHZhciBfaGFzaCA9IGdkLl90cmFuc2l0aW9uRGF0YS5fZnJhbWVIYXNoOwogICAgICAgIHZhciBfZnJhbWVzID0gZ2QuX3RyYW5zaXRpb25EYXRhLl9mcmFtZXMgfHwgW107CiAgICAgICAgCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBfZnJhbWVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAKICAgICAgICAgIC8vIGFkZCB0byBfZnJhbWVzW2ldLnRyYWNlcyAqaWYqIHRoaXMgZnJhbWUgcmVmZXJlbmNlcyBzZWxlY3RlZCB0cmFjZShzKQogICAgICAgICAgdmFyIG5ld0luZGljZXMgPSBbXTsKICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdHJhY2VzLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgIHZhciB0ciA9IHRyYWNlc1tqXTsKICAgICAgICAgICAgaWYgKF9mcmFtZXNbaV0udHJhY2VzLmluZGV4T2YodHIuX29yaWdpbmFsSW5kZXgpID4gLTEpIHsKICAgICAgICAgICAgICBuZXdJbmRpY2VzLnB1c2godHIuX25ld0luZGV4KTsKICAgICAgICAgICAgICBfZnJhbWVzW2ldLnRyYWNlcy5wdXNoKHRyLl9uZXdJbmRleCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIAogICAgICAgICAgLy8gbm90aGluZyB0byBkby4uLgogICAgICAgICAgaWYgKG5ld0luZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgCiAgICAgICAgICB2YXIgY3RyID0gMDsKICAgICAgICAgIHZhciBuRnJhbWVUcmFjZXMgPSBfZnJhbWVzW2ldLmRhdGEubGVuZ3RoOwogICAgICAgICAgCiAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG5GcmFtZVRyYWNlczsgaisrKSB7CiAgICAgICAgICAgIHZhciBmcmFtZVRyYWNlID0gX2ZyYW1lc1tpXS5kYXRhW2pdOwogICAgICAgICAgICBpZiAoIWZyYW1lVHJhY2Uua2V5IHx8IGZyYW1lVHJhY2Uuc2V0ICE9PSBncm91cCkgewogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICB2YXIgbWF0Y2hGdW5jID0gZ2V0TWF0Y2hGdW5jKGZyYW1lVHJhY2UpOwogICAgICAgICAgICB2YXIgbWF0Y2hlcyA9IG1hdGNoRnVuYyhmcmFtZVRyYWNlLmtleSwga2V5cyk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAobWF0Y2hlcy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgaWYgKCF0cmFjZS5faXNTaW1wbGVLZXkpIHsKICAgICAgICAgICAgICAgIGZyYW1lVHJhY2UgPSBzdWJzZXRBcnJheUF0dHJzKGZyYW1lVHJhY2UsIG1hdGNoZXMpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB2YXIgZCA9IGdkLl9mdWxsRGF0YVtuZXdJbmRpY2VzW2N0cl1dOwogICAgICAgICAgICAgIGlmIChkLm1hcmtlcikgewogICAgICAgICAgICAgICAgZnJhbWVUcmFjZS5tYXJrZXIgPSBkLm1hcmtlcjsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKGQubGluZSkgewogICAgICAgICAgICAgICAgZnJhbWVUcmFjZS5saW5lID0gZC5saW5lOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoZC50ZXh0Zm9udCkgewogICAgICAgICAgICAgICAgZnJhbWVUcmFjZS50ZXh0Zm9udCA9IGQudGV4dGZvbnQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGN0ciA9IGN0ciArIDE7CiAgICAgICAgICAgICAgX2ZyYW1lc1tpXS5kYXRhLnB1c2goZnJhbWVUcmFjZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIAogICAgICAgICAgLy8gdXBkYXRlIGdkLl90cmFuc2l0aW9uRGF0YS5fZnJhbWVIYXNoCiAgICAgICAgICBfaGFzaFtfZnJhbWVzW2ldLm5hbWVdID0gX2ZyYW1lc1tpXTsKICAgICAgICB9CiAgICAgIAogICAgICB9KTsKICAgICAgCiAgICAgIC8vIGRpbSB0cmFjZXMgdGhhdCBoYXZlIGEgc2V0IG1hdGNoaW5nIHRoZSBzZXQgb2Ygc2VsZWN0aW9uIHNldHMKICAgICAgdmFyIHRyYWNlc1RvRGltID0gW10sCiAgICAgICAgICBvcGFjaXRpZXMgPSBbXSwKICAgICAgICAgIHNldHMgPSBPYmplY3Qua2V5cyh0aGlzLmdyb3VwU2VsZWN0aW9ucyksCiAgICAgICAgICBuID0gdGhpcy5vcmlnRGF0YS5sZW5ndGg7CiAgICAgICAgICAKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICB2YXIgb3BhY2l0eSA9IHRoaXMub3JpZ09wYWNpdHlbaV0gfHwgMTsKICAgICAgICAvLyBoYXZlIHdlIGFscmVhZHkgZGltbWVkIHRoaXMgdHJhY2U/IE9yIGlzIHRoaXMgZXZlbiB3b3J0aCBkb2luZz8KICAgICAgICBpZiAob3BhY2l0eSAhPT0gdGhpcy5nZC5fZnVsbERhdGFbaV0ub3BhY2l0eSB8fCB0aGlzLmhpZ2hsaWdodC5vcGFjaXR5RGltID09PSAxKSB7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgLy8gaXMgdGhpcyBzZXQgYW4gZWxlbWVudCBvZiB0aGUgc2V0IG9mIHNlbGVjdGlvbiBzZXRzPwogICAgICAgIHZhciBtYXRjaGVzID0gZmluZE1hdGNoZXMoc2V0cywgW3RoaXMuZ2QuZGF0YVtpXS5zZXRdKTsKICAgICAgICBpZiAobWF0Y2hlcy5sZW5ndGgpIHsKICAgICAgICAgIHRyYWNlc1RvRGltLnB1c2goaSk7CiAgICAgICAgICBvcGFjaXRpZXMucHVzaChvcGFjaXR5ICogdGhpcy5oaWdobGlnaHQub3BhY2l0eURpbSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIAogICAgICBpZiAodHJhY2VzVG9EaW0ubGVuZ3RoID4gMCkgewogICAgICAgIFBsb3RseS5yZXN0eWxlKHRoaXMuZ2QsIHsib3BhY2l0eSI6IG9wYWNpdGllc30sIHRyYWNlc1RvRGltKTsKICAgICAgICAvLyB0dXJuIG9mZiB0aGUgc2VsZWN0ZWQvdW5zZWxlY3RlZCBBUEkKICAgICAgICBQbG90bHkucmVzdHlsZSh0aGlzLmdkLCB7InNlbGVjdGVkcG9pbnRzIjogbnVsbH0pOwogICAgICB9CiAgICAgIAogICAgfQogICAgCiAgfQp9OwoKLyogCk5vdGU6IGluIGFsbCBvZiB0aGVzZSBtYXRjaCBmdW5jdGlvbnMsIHdlIGFzc3VtZSBuZWVkbGVTZXQgKGkuZS4gdGhlIHNlbGVjdGVkIGtleXMpCmlzIGEgMUQgKG9yIGZsYXQpIGFycmF5LiBUaGUgcmVhbCBkaWZmZXJlbmNlIGlzIHRoZSBtZWFuaW5nIG9mIGhheXN0YWNrLgpmaW5kTWF0Y2hlcygpIGRvZXMgdGhlIHVzdWFsIHRoaW5nIHlvdSdkIGV4cGVjdCBmb3IgCmxpbmtlZCBicnVzaGluZyBvbiBhIHNjYXR0ZXJwbG90IG1hdHJpeC4gZmluZFNpbXBsZU1hdGNoZXMoKSByZXR1cm5zIGEgbWF0Y2ggaWZmIApoYXlzdGFjayBpcyBhIHN1YnNldCBvZiB0aGUgbmVlZGxlU2V0LiBmaW5kTmVzdGVkTWF0Y2hlcygpIHJldHVybnMgCiovCgpmdW5jdGlvbiBnZXRNYXRjaEZ1bmModHJhY2UpIHsKICByZXR1cm4gKHRyYWNlLl9pc05lc3RlZEtleSkgPyBmaW5kTmVzdGVkTWF0Y2hlcyA6IAogICAgKHRyYWNlLl9pc1NpbXBsZUtleSkgPyBmaW5kU2ltcGxlTWF0Y2hlcyA6IGZpbmRNYXRjaGVzOwp9CgovLyBmaW5kIG1hdGNoZXMgZm9yICJmbGF0IiBrZXlzCmZ1bmN0aW9uIGZpbmRNYXRjaGVzKGhheXN0YWNrLCBuZWVkbGVTZXQpIHsKICB2YXIgbWF0Y2hlcyA9IFtdOwogIGhheXN0YWNrLmZvckVhY2goZnVuY3Rpb24ob2JqLCBpKSB7CiAgICBpZiAob2JqID09PSBudWxsIHx8IG5lZWRsZVNldC5pbmRleE9mKG9iaikgPj0gMCkgewogICAgICBtYXRjaGVzLnB1c2goaSk7CiAgICB9CiAgfSk7CiAgcmV0dXJuIG1hdGNoZXM7Cn0KCi8vIGZpbmQgbWF0Y2hlcyBmb3IgInNpbXBsZSIga2V5cwpmdW5jdGlvbiBmaW5kU2ltcGxlTWF0Y2hlcyhoYXlzdGFjaywgbmVlZGxlU2V0KSB7CiAgdmFyIG1hdGNoID0gaGF5c3RhY2suZXZlcnkoZnVuY3Rpb24odmFsKSB7CiAgICByZXR1cm4gdmFsID09PSBudWxsIHx8IG5lZWRsZVNldC5pbmRleE9mKHZhbCkgPj0gMDsKICB9KTsKICAvLyB5ZXMsIHRoaXMgZG9lc24ndCBtYWtlIG11Y2ggc2Vuc2Ugb3RoZXIgdGhhbiBjb25mb3JtaW5nIAogIC8vIHRvIHRoZSBvdXRwdXQgdHlwZSBvZiB0aGUgb3RoZXIgbWF0Y2ggZnVuY3Rpb25zCiAgcmV0dXJuIChtYXRjaCkgPyBbMF0gOiBbXQp9CgovLyBmaW5kIG1hdGNoZXMgZm9yIGEgIm5lc3RlZCIgaGF5c3RhY2sgKDJEIGFycmF5cykKZnVuY3Rpb24gZmluZE5lc3RlZE1hdGNoZXMoaGF5c3RhY2ssIG5lZWRsZVNldCkgewogIHZhciBtYXRjaGVzID0gW107CiAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXlzdGFjay5sZW5ndGg7IGkrKykgewogICAgdmFyIGhheSA9IGhheXN0YWNrW2ldOwogICAgdmFyIG1hdGNoID0gaGF5LmV2ZXJ5KGZ1bmN0aW9uKHZhbCkgeyAKICAgICAgcmV0dXJuIHZhbCA9PT0gbnVsbCB8fCBuZWVkbGVTZXQuaW5kZXhPZih2YWwpID49IDA7IAogICAgfSk7CiAgICBpZiAobWF0Y2gpIHsKICAgICAgbWF0Y2hlcy5wdXNoKGkpOwogICAgfQogIH0KICByZXR1cm4gbWF0Y2hlczsKfQoKZnVuY3Rpb24gaXNQbGFpbk9iamVjdChvYmopIHsKICByZXR1cm4gKAogICAgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IE9iamVjdF0nICYmCiAgICBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKSA9PT0gT2JqZWN0LnByb3RvdHlwZQogICk7Cn0KCmZ1bmN0aW9uIHN1YnNldEFycmF5QXR0cnMob2JqLCBpbmRpY2VzKSB7CiAgdmFyIG5ld09iaiA9IHt9OwogIE9iamVjdC5rZXlzKG9iaikuZm9yRWFjaChmdW5jdGlvbihrKSB7CiAgICB2YXIgdmFsID0gb2JqW2tdOwoKICAgIGlmIChrLmNoYXJBdCgwKSA9PT0gIl8iKSB7CiAgICAgIG5ld09ialtrXSA9IHZhbDsKICAgIH0gZWxzZSBpZiAoayA9PT0gInRyYW5zZm9ybXMiICYmIEFycmF5LmlzQXJyYXkodmFsKSkgewogICAgICBuZXdPYmpba10gPSB2YWwubWFwKGZ1bmN0aW9uKHRyYW5zZm9ybSkgewogICAgICAgIHJldHVybiBzdWJzZXRBcnJheUF0dHJzKHRyYW5zZm9ybSwgaW5kaWNlcyk7CiAgICAgIH0pOwogICAgfSBlbHNlIGlmIChrID09PSAiY29sb3JzY2FsZSIgJiYgQXJyYXkuaXNBcnJheSh2YWwpKSB7CiAgICAgIG5ld09ialtrXSA9IHZhbDsKICAgIH0gZWxzZSBpZiAoaXNQbGFpbk9iamVjdCh2YWwpKSB7CiAgICAgIG5ld09ialtrXSA9IHN1YnNldEFycmF5QXR0cnModmFsLCBpbmRpY2VzKTsKICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7CiAgICAgIG5ld09ialtrXSA9IHN1YnNldEFycmF5KHZhbCwgaW5kaWNlcyk7CiAgICB9IGVsc2UgewogICAgICBuZXdPYmpba10gPSB2YWw7CiAgICB9CiAgfSk7CiAgcmV0dXJuIG5ld09iajsKfQoKZnVuY3Rpb24gc3Vic2V0QXJyYXkoYXJyLCBpbmRpY2VzKSB7CiAgdmFyIHJlc3VsdCA9IFtdOwogIGZvciAodmFyIGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykgewogICAgcmVzdWx0LnB1c2goYXJyW2luZGljZXNbaV1dKTsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLy8gQ29udmVuaWVuY2UgZnVuY3Rpb24gZm9yIHJlbW92aW5nIHBsb3RseSdzIGJydXNoIApmdW5jdGlvbiByZW1vdmVCcnVzaChlbCkgewogIHZhciBvdXRsaW5lcyA9IGVsLnF1ZXJ5U2VsZWN0b3JBbGwoIi5zZWxlY3Qtb3V0bGluZSIpOwogIGZvciAodmFyIGkgPSAwOyBpIDwgb3V0bGluZXMubGVuZ3RoOyBpKyspIHsKICAgIG91dGxpbmVzW2ldLnJlbW92ZSgpOwogIH0KfQoKCi8vIGh0dHBzOi8vZGF2aWR3YWxzaC5uYW1lL2phdmFzY3JpcHQtZGVib3VuY2UtZnVuY3Rpb24KCi8vIFJldHVybnMgYSBmdW5jdGlvbiwgdGhhdCwgYXMgbG9uZyBhcyBpdCBjb250aW51ZXMgdG8gYmUgaW52b2tlZCwgd2lsbCBub3QKLy8gYmUgdHJpZ2dlcmVkLiBUaGUgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgYWZ0ZXIgaXQgc3RvcHMgYmVpbmcgY2FsbGVkIGZvcgovLyBOIG1pbGxpc2Vjb25kcy4gSWYgYGltbWVkaWF0ZWAgaXMgcGFzc2VkLCB0cmlnZ2VyIHRoZSBmdW5jdGlvbiBvbiB0aGUKLy8gbGVhZGluZyBlZGdlLCBpbnN0ZWFkIG9mIHRoZSB0cmFpbGluZy4KZnVuY3Rpb24gZGVib3VuY2UoZnVuYywgd2FpdCwgaW1tZWRpYXRlKSB7Cgl2YXIgdGltZW91dDsKCXJldHVybiBmdW5jdGlvbigpIHsKCQl2YXIgY29udGV4dCA9IHRoaXMsIGFyZ3MgPSBhcmd1bWVudHM7CgkJdmFyIGxhdGVyID0gZnVuY3Rpb24oKSB7CgkJCXRpbWVvdXQgPSBudWxsOwoJCQlpZiAoIWltbWVkaWF0ZSkgZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTsKCQl9OwoJCXZhciBjYWxsTm93ID0gaW1tZWRpYXRlICYmICF0aW1lb3V0OwoJCWNsZWFyVGltZW91dCh0aW1lb3V0KTsKCQl0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgd2FpdCk7CgkJaWYgKGNhbGxOb3cpIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7Cgl9Owp9Owo=\"></script>\n",
"<script src=\"data:application/javascript;base64,KGZ1bmN0aW9uKGdsb2JhbCl7InVzZSBzdHJpY3QiO3ZhciB1bmRlZmluZWQ9dm9pZCAwO3ZhciBNQVhfQVJSQVlfTEVOR1RIPTFlNTtmdW5jdGlvbiBUeXBlKHYpe3N3aXRjaCh0eXBlb2Ygdil7Y2FzZSJ1bmRlZmluZWQiOnJldHVybiJ1bmRlZmluZWQiO2Nhc2UiYm9vbGVhbiI6cmV0dXJuImJvb2xlYW4iO2Nhc2UibnVtYmVyIjpyZXR1cm4ibnVtYmVyIjtjYXNlInN0cmluZyI6cmV0dXJuInN0cmluZyI7ZGVmYXVsdDpyZXR1cm4gdj09PW51bGw/Im51bGwiOiJvYmplY3QifX1mdW5jdGlvbiBDbGFzcyh2KXtyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHYpLnJlcGxhY2UoL15cW29iamVjdCAqfFxdJC9nLCIiKX1mdW5jdGlvbiBJc0NhbGxhYmxlKG8pe3JldHVybiB0eXBlb2Ygbz09PSJmdW5jdGlvbiJ9ZnVuY3Rpb24gVG9PYmplY3Qodil7aWYodj09PW51bGx8fHY9PT11bmRlZmluZWQpdGhyb3cgVHlwZUVycm9yKCk7cmV0dXJuIE9iamVjdCh2KX1mdW5jdGlvbiBUb0ludDMyKHYpe3JldHVybiB2Pj4wfWZ1bmN0aW9uIFRvVWludDMyKHYpe3JldHVybiB2Pj4+MH12YXIgTE4yPU1hdGguTE4yLGFicz1NYXRoLmFicyxmbG9vcj1NYXRoLmZsb29yLGxvZz1NYXRoLmxvZyxtYXg9TWF0aC5tYXgsbWluPU1hdGgubWluLHBvdz1NYXRoLnBvdyxyb3VuZD1NYXRoLnJvdW5kOyhmdW5jdGlvbigpe3ZhciBvcmlnPU9iamVjdC5kZWZpbmVQcm9wZXJ0eTt2YXIgZG9tX29ubHk9IWZ1bmN0aW9uKCl7dHJ5e3JldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sIngiLHt9KX1jYXRjaChfKXtyZXR1cm4gZmFsc2V9fSgpO2lmKCFvcmlnfHxkb21fb25seSl7T2JqZWN0LmRlZmluZVByb3BlcnR5PWZ1bmN0aW9uKG8scHJvcCxkZXNjKXtpZihvcmlnKXRyeXtyZXR1cm4gb3JpZyhvLHByb3AsZGVzYyl9Y2F0Y2goXyl7fWlmKG8hPT1PYmplY3QobykpdGhyb3cgVHlwZUVycm9yKCJPYmplY3QuZGVmaW5lUHJvcGVydHkgY2FsbGVkIG9uIG5vbi1vYmplY3QiKTtpZihPYmplY3QucHJvdG90eXBlLl9fZGVmaW5lR2V0dGVyX18mJiJnZXQiaW4gZGVzYylPYmplY3QucHJvdG90eXBlLl9fZGVmaW5lR2V0dGVyX18uY2FsbChvLHByb3AsZGVzYy5nZXQpO2lmKE9iamVjdC5wcm90b3R5cGUuX19kZWZpbmVTZXR0ZXJfXyYmInNldCJpbiBkZXNjKU9iamVjdC5wcm90b3R5cGUuX19kZWZpbmVTZXR0ZXJfXy5jYWxsKG8scHJvcCxkZXNjLnNldCk7aWYoInZhbHVlImluIGRlc2Mpb1twcm9wXT1kZXNjLnZhbHVlO3JldHVybiBvfX19KSgpO2Z1bmN0aW9uIG1ha2VBcnJheUFjY2Vzc29ycyhvYmope2lmKG9iai5sZW5ndGg+TUFYX0FSUkFZX0xFTkdUSCl0aHJvdyBSYW5nZUVycm9yKCJBcnJheSB0b28gbGFyZ2UgZm9yIHBvbHlmaWxsIik7ZnVuY3Rpb24gbWFrZUFycmF5QWNjZXNzb3IoaW5kZXgpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosaW5kZXgse2dldDpmdW5jdGlvbigpe3JldHVybiBvYmouX2dldHRlcihpbmRleCl9LHNldDpmdW5jdGlvbih2KXtvYmouX3NldHRlcihpbmRleCx2KX0sZW51bWVyYWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTpmYWxzZX0pfXZhciBpO2ZvcihpPTA7aTxvYmoubGVuZ3RoO2krPTEpe21ha2VBcnJheUFjY2Vzc29yKGkpfX1mdW5jdGlvbiBhc19zaWduZWQodmFsdWUsYml0cyl7dmFyIHM9MzItYml0cztyZXR1cm4gdmFsdWU8PHM+PnN9ZnVuY3Rpb24gYXNfdW5zaWduZWQodmFsdWUsYml0cyl7dmFyIHM9MzItYml0cztyZXR1cm4gdmFsdWU8PHM+Pj5zfWZ1bmN0aW9uIHBhY2tJOChuKXtyZXR1cm5bbiYyNTVdfWZ1bmN0aW9uIHVucGFja0k4KGJ5dGVzKXtyZXR1cm4gYXNfc2lnbmVkKGJ5dGVzWzBdLDgpfWZ1bmN0aW9uIHBhY2tVOChuKXtyZXR1cm5bbiYyNTVdfWZ1bmN0aW9uIHVucGFja1U4KGJ5dGVzKXtyZXR1cm4gYXNfdW5zaWduZWQoYnl0ZXNbMF0sOCl9ZnVuY3Rpb24gcGFja1U4Q2xhbXBlZChuKXtuPXJvdW5kKE51bWJlcihuKSk7cmV0dXJuW248MD8wOm4+MjU1PzI1NTpuJjI1NV19ZnVuY3Rpb24gcGFja0kxNihuKXtyZXR1cm5bbj4+OCYyNTUsbiYyNTVdfWZ1bmN0aW9uIHVucGFja0kxNihieXRlcyl7cmV0dXJuIGFzX3NpZ25lZChieXRlc1swXTw8OHxieXRlc1sxXSwxNil9ZnVuY3Rpb24gcGFja1UxNihuKXtyZXR1cm5bbj4+OCYyNTUsbiYyNTVdfWZ1bmN0aW9uIHVucGFja1UxNihieXRlcyl7cmV0dXJuIGFzX3Vuc2lnbmVkKGJ5dGVzWzBdPDw4fGJ5dGVzWzFdLDE2KX1mdW5jdGlvbiBwYWNrSTMyKG4pe3JldHVybltuPj4yNCYyNTUsbj4+MTYmMjU1LG4+PjgmMjU1LG4mMjU1XX1mdW5jdGlvbiB1bnBhY2tJMzIoYnl0ZXMpe3JldHVybiBhc19zaWduZWQoYnl0ZXNbMF08PDI0fGJ5dGVzWzFdPDwxNnxieXRlc1syXTw8OHxieXRlc1szXSwzMil9ZnVuY3Rpb24gcGFja1UzMihuKXtyZXR1cm5bbj4+MjQmMjU1LG4+PjE2JjI1NSxuPj44JjI1NSxuJjI1NV19ZnVuY3Rpb24gdW5wYWNrVTMyKGJ5dGVzKXtyZXR1cm4gYXNfdW5zaWduZWQoYnl0ZXNbMF08PDI0fGJ5dGVzWzFdPDwxNnxieXRlc1syXTw8OHxieXRlc1szXSwzMil9ZnVuY3Rpb24gcGFja0lFRUU3NTQodixlYml0cyxmYml0cyl7dmFyIGJpYXM9KDE8PGViaXRzLTEpLTEscyxlLGYsbG4saSxiaXRzLHN0cixieXRlcztmdW5jdGlvbiByb3VuZFRvRXZlbihuKXt2YXIgdz1mbG9vcihuKSxmPW4tdztpZihmPC41KXJldHVybiB3O2lmKGY+LjUpcmV0dXJuIHcrMTtyZXR1cm4gdyUyP3crMTp3fWlmKHYhPT12KXtlPSgxPDxlYml0cyktMTtmPXBvdygyLGZiaXRzLTEpO3M9MH1lbHNlIGlmKHY9PT1JbmZpbml0eXx8dj09PS1JbmZpbml0eSl7ZT0oMTw8ZWJpdHMpLTE7Zj0wO3M9djwwPzE6MH1lbHNlIGlmKHY9PT0wKXtlPTA7Zj0wO3M9MS92PT09LUluZmluaXR5PzE6MH1lbHNle3M9djwwO3Y9YWJzKHYpO2lmKHY+PXBvdygyLDEtYmlhcykpe2U9bWluKGZsb29yKGxvZyh2KS9MTjIpLDEwMjMpO2Y9cm91bmRUb0V2ZW4odi9wb3coMixlKSpwb3coMixmYml0cykpO2lmKGYvcG93KDIsZmJpdHMpPj0yKXtlPWUrMTtmPTF9aWYoZT5iaWFzKXtlPSgxPDxlYml0cyktMTtmPTB9ZWxzZXtlPWUrYmlhcztmPWYtcG93KDIsZmJpdHMpfX1lbHNle2U9MDtmPXJvdW5kVG9FdmVuKHYvcG93KDIsMS1iaWFzLWZiaXRzKSl9fWJpdHM9W107Zm9yKGk9ZmJpdHM7aTtpLT0xKXtiaXRzLnB1c2goZiUyPzE6MCk7Zj1mbG9vcihmLzIpfWZvcihpPWViaXRzO2k7aS09MSl7Yml0cy5wdXNoKGUlMj8xOjApO2U9Zmxvb3IoZS8yKX1iaXRzLnB1c2gocz8xOjApO2JpdHMucmV2ZXJzZSgpO3N0cj1iaXRzLmpvaW4oIiIpO2J5dGVzPVtdO3doaWxlKHN0ci5sZW5ndGgpe2J5dGVzLnB1c2gocGFyc2VJbnQoc3RyLnN1YnN0cmluZygwLDgpLDIpKTtzdHI9c3RyLnN1YnN0cmluZyg4KX1yZXR1cm4gYnl0ZXN9ZnVuY3Rpb24gdW5wYWNrSUVFRTc1NChieXRlcyxlYml0cyxmYml0cyl7dmFyIGJpdHM9W10saSxqLGIsc3RyLGJpYXMscyxlLGY7Zm9yKGk9Ynl0ZXMubGVuZ3RoO2k7aS09MSl7Yj1ieXRlc1tpLTFdO2ZvcihqPTg7ajtqLT0xKXtiaXRzLnB1c2goYiUyPzE6MCk7Yj1iPj4xfX1iaXRzLnJldmVyc2UoKTtzdHI9Yml0cy5qb2luKCIiKTtiaWFzPSgxPDxlYml0cy0xKS0xO3M9cGFyc2VJbnQoc3RyLnN1YnN0cmluZygwLDEpLDIpPy0xOjE7ZT1wYXJzZUludChzdHIuc3Vic3RyaW5nKDEsMStlYml0cyksMik7Zj1wYXJzZUludChzdHIuc3Vic3RyaW5nKDErZWJpdHMpLDIpO2lmKGU9PT0oMTw8ZWJpdHMpLTEpe3JldHVybiBmIT09MD9OYU46cypJbmZpbml0eX1lbHNlIGlmKGU+MCl7cmV0dXJuIHMqcG93KDIsZS1iaWFzKSooMStmL3BvdygyLGZiaXRzKSl9ZWxzZSBpZihmIT09MCl7cmV0dXJuIHMqcG93KDIsLShiaWFzLTEpKSooZi9wb3coMixmYml0cykpfWVsc2V7cmV0dXJuIHM8MD8tMDowfX1mdW5jdGlvbiB1bnBhY2tGNjQoYil7cmV0dXJuIHVucGFja0lFRUU3NTQoYiwxMSw1Mil9ZnVuY3Rpb24gcGFja0Y2NCh2KXtyZXR1cm4gcGFja0lFRUU3NTQodiwxMSw1Mil9ZnVuY3Rpb24gdW5wYWNrRjMyKGIpe3JldHVybiB1bnBhY2tJRUVFNzU0KGIsOCwyMyl9ZnVuY3Rpb24gcGFja0YzMih2KXtyZXR1cm4gcGFja0lFRUU3NTQodiw4LDIzKX0oZnVuY3Rpb24oKXtmdW5jdGlvbiBBcnJheUJ1ZmZlcihsZW5ndGgpe2xlbmd0aD1Ub0ludDMyKGxlbmd0aCk7aWYobGVuZ3RoPDApdGhyb3cgUmFuZ2VFcnJvcigiQXJyYXlCdWZmZXIgc2l6ZSBpcyBub3QgYSBzbWFsbCBlbm91Z2ggcG9zaXRpdmUgaW50ZWdlci4iKTtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiYnl0ZUxlbmd0aCIse3ZhbHVlOmxlbmd0aH0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJfYnl0ZXMiLHt2YWx1ZTpBcnJheShsZW5ndGgpfSk7Zm9yKHZhciBpPTA7aTxsZW5ndGg7aSs9MSl0aGlzLl9ieXRlc1tpXT0wfWdsb2JhbC5BcnJheUJ1ZmZlcj1nbG9iYWwuQXJyYXlCdWZmZXJ8fEFycmF5QnVmZmVyO2Z1bmN0aW9uICRUeXBlZEFycmF5JCgpe2lmKCFhcmd1bWVudHMubGVuZ3RofHx0eXBlb2YgYXJndW1lbnRzWzBdIT09Im9iamVjdCIpe3JldHVybiBmdW5jdGlvbihsZW5ndGgpe2xlbmd0aD1Ub0ludDMyKGxlbmd0aCk7aWYobGVuZ3RoPDApdGhyb3cgUmFuZ2VFcnJvcigibGVuZ3RoIGlzIG5vdCBhIHNtYWxsIGVub3VnaCBwb3NpdGl2ZSBpbnRlZ2VyLiIpO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJsZW5ndGgiLHt2YWx1ZTpsZW5ndGh9KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiYnl0ZUxlbmd0aCIse3ZhbHVlOmxlbmd0aCp0aGlzLkJZVEVTX1BFUl9FTEVNRU5UfSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImJ1ZmZlciIse3ZhbHVlOm5ldyBBcnJheUJ1ZmZlcih0aGlzLmJ5dGVMZW5ndGgpfSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImJ5dGVPZmZzZXQiLHt2YWx1ZTowfSl9LmFwcGx5KHRoaXMsYXJndW1lbnRzKX1pZihhcmd1bWVudHMubGVuZ3RoPj0xJiZUeXBlKGFyZ3VtZW50c1swXSk9PT0ib2JqZWN0IiYmYXJndW1lbnRzWzBdaW5zdGFuY2VvZiAkVHlwZWRBcnJheSQpe3JldHVybiBmdW5jdGlvbih0eXBlZEFycmF5KXtpZih0aGlzLmNvbnN0cnVjdG9yIT09dHlwZWRBcnJheS5jb25zdHJ1Y3Rvcil0aHJvdyBUeXBlRXJyb3IoKTt2YXIgYnl0ZUxlbmd0aD10eXBlZEFycmF5Lmxlbmd0aCp0aGlzLkJZVEVTX1BFUl9FTEVNRU5UO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJidWZmZXIiLHt2YWx1ZTpuZXcgQXJyYXlCdWZmZXIoYnl0ZUxlbmd0aCl9KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiYnl0ZUxlbmd0aCIse3ZhbHVlOmJ5dGVMZW5ndGh9KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiYnl0ZU9mZnNldCIse3ZhbHVlOjB9KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywibGVuZ3RoIix7dmFsdWU6dHlwZWRBcnJheS5sZW5ndGh9KTtmb3IodmFyIGk9MDtpPHRoaXMubGVuZ3RoO2krPTEpdGhpcy5fc2V0dGVyKGksdHlwZWRBcnJheS5fZ2V0dGVyKGkpKX0uYXBwbHkodGhpcyxhcmd1bWVudHMpfWlmKGFyZ3VtZW50cy5sZW5ndGg+PTEmJlR5cGUoYXJndW1lbnRzWzBdKT09PSJvYmplY3QiJiYhKGFyZ3VtZW50c1swXWluc3RhbmNlb2YgJFR5cGVkQXJyYXkkKSYmIShhcmd1bWVudHNbMF1pbnN0YW5jZW9mIEFycmF5QnVmZmVyfHxDbGFzcyhhcmd1bWVudHNbMF0pPT09IkFycmF5QnVmZmVyIikpe3JldHVybiBmdW5jdGlvbihhcnJheSl7dmFyIGJ5dGVMZW5ndGg9YXJyYXkubGVuZ3RoKnRoaXMuQllURVNfUEVSX0VMRU1FTlQ7T2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImJ1ZmZlciIse3ZhbHVlOm5ldyBBcnJheUJ1ZmZlcihieXRlTGVuZ3RoKX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJieXRlTGVuZ3RoIix7dmFsdWU6Ynl0ZUxlbmd0aH0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJieXRlT2Zmc2V0Iix7dmFsdWU6MH0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJsZW5ndGgiLHt2YWx1ZTphcnJheS5sZW5ndGh9KTtmb3IodmFyIGk9MDtpPHRoaXMubGVuZ3RoO2krPTEpe3ZhciBzPWFycmF5W2ldO3RoaXMuX3NldHRlcihpLE51bWJlcihzKSl9fS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9aWYoYXJndW1lbnRzLmxlbmd0aD49MSYmVHlwZShhcmd1bWVudHNbMF0pPT09Im9iamVjdCImJihhcmd1bWVudHNbMF1pbnN0YW5jZW9mIEFycmF5QnVmZmVyfHxDbGFzcyhhcmd1bWVudHNbMF0pPT09IkFycmF5QnVmZmVyIikpe3JldHVybiBmdW5jdGlvbihidWZmZXIsYnl0ZU9mZnNldCxsZW5ndGgpe2J5dGVPZmZzZXQ9VG9VaW50MzIoYnl0ZU9mZnNldCk7aWYoYnl0ZU9mZnNldD5idWZmZXIuYnl0ZUxlbmd0aCl0aHJvdyBSYW5nZUVycm9yKCJieXRlT2Zmc2V0IG91dCBvZiByYW5nZSIpO2lmKGJ5dGVPZmZzZXQldGhpcy5CWVRFU19QRVJfRUxFTUVOVCl0aHJvdyBSYW5nZUVycm9yKCJidWZmZXIgbGVuZ3RoIG1pbnVzIHRoZSBieXRlT2Zmc2V0IGlzIG5vdCBhIG11bHRpcGxlIG9mIHRoZSBlbGVtZW50IHNpemUuIik7aWYobGVuZ3RoPT09dW5kZWZpbmVkKXt2YXIgYnl0ZUxlbmd0aD1idWZmZXIuYnl0ZUxlbmd0aC1ieXRlT2Zmc2V0O2lmKGJ5dGVMZW5ndGgldGhpcy5CWVRFU19QRVJfRUxFTUVOVCl0aHJvdyBSYW5nZUVycm9yKCJsZW5ndGggb2YgYnVmZmVyIG1pbnVzIGJ5dGVPZmZzZXQgbm90IGEgbXVsdGlwbGUgb2YgdGhlIGVsZW1lbnQgc2l6ZSIpO2xlbmd0aD1ieXRlTGVuZ3RoL3RoaXMuQllURVNfUEVSX0VMRU1FTlR9ZWxzZXtsZW5ndGg9VG9VaW50MzIobGVuZ3RoKTtieXRlTGVuZ3RoPWxlbmd0aCp0aGlzLkJZVEVTX1BFUl9FTEVNRU5UfWlmKGJ5dGVPZmZzZXQrYnl0ZUxlbmd0aD5idWZmZXIuYnl0ZUxlbmd0aCl0aHJvdyBSYW5nZUVycm9yKCJieXRlT2Zmc2V0IGFuZCBsZW5ndGggcmVmZXJlbmNlIGFuIGFyZWEgYmV5b25kIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlciIpO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJidWZmZXIiLHt2YWx1ZTpidWZmZXJ9KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiYnl0ZUxlbmd0aCIse3ZhbHVlOmJ5dGVMZW5ndGh9KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiYnl0ZU9mZnNldCIse3ZhbHVlOmJ5dGVPZmZzZXR9KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywibGVuZ3RoIix7dmFsdWU6bGVuZ3RofSl9LmFwcGx5KHRoaXMsYXJndW1lbnRzKX10aHJvdyBUeXBlRXJyb3IoKX1PYmplY3QuZGVmaW5lUHJvcGVydHkoJFR5cGVkQXJyYXkkLCJmcm9tIix7dmFsdWU6ZnVuY3Rpb24oaXRlcmFibGUpe3JldHVybiBuZXcgdGhpcyhpdGVyYWJsZSl9fSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KCRUeXBlZEFycmF5JCwib2YiLHt2YWx1ZTpmdW5jdGlvbigpe3JldHVybiBuZXcgdGhpcyhhcmd1bWVudHMpfX0pO3ZhciAkVHlwZWRBcnJheVByb3RvdHlwZSQ9e307JFR5cGVkQXJyYXkkLnByb3RvdHlwZT0kVHlwZWRBcnJheVByb3RvdHlwZSQ7T2JqZWN0LmRlZmluZVByb3BlcnR5KCRUeXBlZEFycmF5JC5wcm90b3R5cGUsIl9nZXR0ZXIiLHt2YWx1ZTpmdW5jdGlvbihpbmRleCl7aWYoYXJndW1lbnRzLmxlbmd0aDwxKXRocm93IFN5bnRheEVycm9yKCJOb3QgZW5vdWdoIGFyZ3VtZW50cyIpO2luZGV4PVRvVWludDMyKGluZGV4KTtpZihpbmRleD49dGhpcy5sZW5ndGgpcmV0dXJuIHVuZGVmaW5lZDt2YXIgYnl0ZXM9W10saSxvO2ZvcihpPTAsbz10aGlzLmJ5dGVPZmZzZXQraW5kZXgqdGhpcy5CWVRFU19QRVJfRUxFTUVOVDtpPHRoaXMuQllURVNfUEVSX0VMRU1FTlQ7aSs9MSxvKz0xKXtieXRlcy5wdXNoKHRoaXMuYnVmZmVyLl9ieXRlc1tvXSl9cmV0dXJuIHRoaXMuX3VucGFjayhieXRlcyl9fSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KCRUeXBlZEFycmF5JC5wcm90b3R5cGUsImdldCIse3ZhbHVlOiRUeXBlZEFycmF5JC5wcm90b3R5cGUuX2dldHRlcn0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSgkVHlwZWRBcnJheSQucHJvdG90eXBlLCJfc2V0dGVyIix7dmFsdWU6ZnVuY3Rpb24oaW5kZXgsdmFsdWUpe2lmKGFyZ3VtZW50cy5sZW5ndGg8Mil0aHJvdyBTeW50YXhFcnJvcigiTm90IGVub3VnaCBhcmd1bWVudHMiKTtpbmRleD1Ub1VpbnQzMihpbmRleCk7aWYoaW5kZXg+PXRoaXMubGVuZ3RoKXJldHVybjt2YXIgYnl0ZXM9dGhpcy5fcGFjayh2YWx1ZSksaSxvO2ZvcihpPTAsbz10aGlzLmJ5dGVPZmZzZXQraW5kZXgqdGhpcy5CWVRFU19QRVJfRUxFTUVOVDtpPHRoaXMuQllURVNfUEVSX0VMRU1FTlQ7aSs9MSxvKz0xKXt0aGlzLmJ1ZmZlci5fYnl0ZXNbb109Ynl0ZXNbaV19fX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSgkVHlwZWRBcnJheSQucHJvdG90eXBlLCJjb25zdHJ1Y3RvciIse3ZhbHVlOiRUeXBlZEFycmF5JH0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSgkVHlwZWRBcnJheSQucHJvdG90eXBlLCJjb3B5V2l0aGluIix7dmFsdWU6ZnVuY3Rpb24odGFyZ2V0LHN0YXJ0KXt2YXIgZW5kPWFyZ3VtZW50c1syXTt2YXIgbz1Ub09iamVjdCh0aGlzKTt2YXIgbGVuVmFsPW8ubGVuZ3RoO3ZhciBsZW49VG9VaW50MzIobGVuVmFsKTtsZW49bWF4KGxlbiwwKTt2YXIgcmVsYXRpdmVUYXJnZXQ9VG9JbnQzMih0YXJnZXQpO3ZhciB0bztpZihyZWxhdGl2ZVRhcmdldDwwKXRvPW1heChsZW4rcmVsYXRpdmVUYXJnZXQsMCk7ZWxzZSB0bz1taW4ocmVsYXRpdmVUYXJnZXQsbGVuKTt2YXIgcmVsYXRpdmVTdGFydD1Ub0ludDMyKHN0YXJ0KTt2YXIgZnJvbTtpZihyZWxhdGl2ZVN0YXJ0PDApZnJvbT1tYXgobGVuK3JlbGF0aXZlU3RhcnQsMCk7ZWxzZSBmcm9tPW1pbihyZWxhdGl2ZVN0YXJ0LGxlbik7dmFyIHJlbGF0aXZlRW5kO2lmKGVuZD09PXVuZGVmaW5lZClyZWxhdGl2ZUVuZD1sZW47ZWxzZSByZWxhdGl2ZUVuZD1Ub0ludDMyKGVuZCk7dmFyIGZpbmFsO2lmKHJlbGF0aXZlRW5kPDApZmluYWw9bWF4KGxlbityZWxhdGl2ZUVuZCwwKTtlbHNlIGZpbmFsPW1pbihyZWxhdGl2ZUVuZCxsZW4pO3ZhciBjb3VudD1taW4oZmluYWwtZnJvbSxsZW4tdG8pO3ZhciBkaXJlY3Rpb247aWYoZnJvbTx0byYmdG88ZnJvbStjb3VudCl7ZGlyZWN0aW9uPS0xO2Zyb209ZnJvbStjb3VudC0xO3RvPXRvK2NvdW50LTF9ZWxzZXtkaXJlY3Rpb249MX13aGlsZShjb3VudD4wKXtvLl9zZXR0ZXIodG8sby5fZ2V0dGVyKGZyb20pKTtmcm9tPWZyb20rZGlyZWN0aW9uO3RvPXRvK2RpcmVjdGlvbjtjb3VudD1jb3VudC0xfXJldHVybiBvfX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSgkVHlwZWRBcnJheSQucHJvdG90eXBlLCJldmVyeSIse3ZhbHVlOmZ1bmN0aW9uKGNhbGxiYWNrZm4pe2lmKHRoaXM9PT11bmRlZmluZWR8fHRoaXM9PT1udWxsKXRocm93IFR5cGVFcnJvcigpO3ZhciB0PU9iamVjdCh0aGlzKTt2YXIgbGVuPVRvVWludDMyKHQubGVuZ3RoKTtpZighSXNDYWxsYWJsZShjYWxsYmFja2ZuKSl0aHJvdyBUeXBlRXJyb3IoKTt2YXIgdGhpc0FyZz1hcmd1bWVudHNbMV07Zm9yKHZhciBpPTA7aTxsZW47aSsrKXtpZighY2FsbGJhY2tmbi5jYWxsKHRoaXNBcmcsdC5fZ2V0dGVyKGkpLGksdCkpcmV0dXJuIGZhbHNlfXJldHVybiB0cnVlfX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSgkVHlwZWRBcnJheSQucHJvdG90eXBlLCJmaWxsIix7dmFsdWU6ZnVuY3Rpb24odmFsdWUpe3ZhciBzdGFydD1hcmd1bWVudHNbMV0sZW5kPWFyZ3VtZW50c1syXTt2YXIgbz1Ub09iamVjdCh0aGlzKTt2YXIgbGVuVmFsPW8ubGVuZ3RoO3ZhciBsZW49VG9VaW50MzIobGVuVmFsKTtsZW49bWF4KGxlbiwwKTt2YXIgcmVsYXRpdmVTdGFydD1Ub0ludDMyKHN0YXJ0KTt2YXIgaztpZihyZWxhdGl2ZVN0YXJ0PDApaz1tYXgobGVuK3JlbGF0aXZlU3RhcnQsMCk7ZWxzZSBrPW1pbihyZWxhdGl2ZVN0YXJ0LGxlbik7dmFyIHJlbGF0aXZlRW5kO2lmKGVuZD09PXVuZGVmaW5lZClyZWxhdGl2ZUVuZD1sZW47ZWxzZSByZWxhdGl2ZUVuZD1Ub0ludDMyKGVuZCk7dmFyIGZpbmFsO2lmKHJlbGF0aXZlRW5kPDApZmluYWw9bWF4KGxlbityZWxhdGl2ZUVuZCwwKTtlbHNlIGZpbmFsPW1pbihyZWxhdGl2ZUVuZCxsZW4pO3doaWxlKGs8ZmluYWwpe28uX3NldHRlcihrLHZhbHVlKTtrKz0xfXJldHVybiBvfX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSgkVHlwZWRBcnJheSQucHJvdG90eXBlLCJmaWx0ZXIiLHt2YWx1ZTpmdW5jdGlvbihjYWxsYmFja2ZuKXtpZih0aGlzPT09dW5kZWZpbmVkfHx0aGlzPT09bnVsbCl0aHJvdyBUeXBlRXJyb3IoKTt2YXIgdD1PYmplY3QodGhpcyk7dmFyIGxlbj1Ub1VpbnQzMih0Lmxlbmd0aCk7aWYoIUlzQ2FsbGFibGUoY2FsbGJhY2tmbikpdGhyb3cgVHlwZUVycm9yKCk7dmFyIHJlcz1bXTt2YXIgdGhpc3A9YXJndW1lbnRzWzFdO2Zvcih2YXIgaT0wO2k8bGVuO2krKyl7dmFyIHZhbD10Ll9nZXR0ZXIoaSk7aWYoY2FsbGJhY2tmbi5jYWxsKHRoaXNwLHZhbCxpLHQpKXJlcy5wdXNoKHZhbCl9cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHJlcyl9fSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KCRUeXBlZEFycmF5JC5wcm90b3R5cGUsImZpbmQiLHt2YWx1ZTpmdW5jdGlvbihwcmVkaWNhdGUpe3ZhciBvPVRvT2JqZWN0KHRoaXMpO3ZhciBsZW5WYWx1ZT1vLmxlbmd0aDt2YXIgbGVuPVRvVWludDMyKGxlblZhbHVlKTtpZighSXNDYWxsYWJsZShwcmVkaWNhdGUpKXRocm93IFR5cGVFcnJvcigpO3ZhciB0PWFyZ3VtZW50cy5sZW5ndGg+MT9hcmd1bWVudHNbMV06dW5kZWZpbmVkO3ZhciBrPTA7d2hpbGUoazxsZW4pe3ZhciBrVmFsdWU9by5fZ2V0dGVyKGspO3ZhciB0ZXN0UmVzdWx0PXByZWRpY2F0ZS5jYWxsKHQsa1ZhbHVlLGssbyk7aWYoQm9vbGVhbih0ZXN0UmVzdWx0KSlyZXR1cm4ga1ZhbHVlOysra31yZXR1cm4gdW5kZWZpbmVkfX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSgkVHlwZWRBcnJheSQucHJvdG90eXBlLCJmaW5kSW5kZXgiLHt2YWx1ZTpmdW5jdGlvbihwcmVkaWNhdGUpe3ZhciBvPVRvT2JqZWN0KHRoaXMpO3ZhciBsZW5WYWx1ZT1vLmxlbmd0aDt2YXIgbGVuPVRvVWludDMyKGxlblZhbHVlKTtpZighSXNDYWxsYWJsZShwcmVkaWNhdGUpKXRocm93IFR5cGVFcnJvcigpO3ZhciB0PWFyZ3VtZW50cy5sZW5ndGg+MT9hcmd1bWVudHNbMV06dW5kZWZpbmVkO3ZhciBrPTA7d2hpbGUoazxsZW4pe3ZhciBrVmFsdWU9by5fZ2V0dGVyKGspO3ZhciB0ZXN0UmVzdWx0PXByZWRpY2F0ZS5jYWxsKHQsa1ZhbHVlLGssbyk7aWYoQm9vbGVhbih0ZXN0UmVzdWx0KSlyZXR1cm4gazsrK2t9cmV0dXJuLTF9fSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KCRUeXBlZEFycmF5JC5wcm90b3R5cGUsImZvckVhY2giLHt2YWx1ZTpmdW5jdGlvbihjYWxsYmFja2ZuKXtpZih0aGlzPT09dW5kZWZpbmVkfHx0aGlzPT09bnVsbCl0aHJvdyBUeXBlRXJyb3IoKTt2YXIgdD1PYmplY3QodGhpcyk7dmFyIGxlbj1Ub1VpbnQzMih0Lmxlbmd0aCk7aWYoIUlzQ2FsbGFibGUoY2FsbGJhY2tmbikpdGhyb3cgVHlwZUVycm9yKCk7dmFyIHRoaXNwPWFyZ3VtZW50c1sxXTtmb3IodmFyIGk9MDtpPGxlbjtpKyspY2FsbGJhY2tmbi5jYWxsKHRoaXNwLHQuX2dldHRlcihpKSxpLHQpfX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSgkVHlwZWRBcnJheSQucHJvdG90eXBlLCJpbmRleE9mIix7dmFsdWU6ZnVuY3Rpb24oc2VhcmNoRWxlbWVudCl7aWYodGhpcz09PXVuZGVmaW5lZHx8dGhpcz09PW51bGwpdGhyb3cgVHlwZUVycm9yKCk7dmFyIHQ9T2JqZWN0KHRoaXMpO3ZhciBsZW49VG9VaW50MzIodC5sZW5ndGgpO2lmKGxlbj09PTApcmV0dXJuLTE7dmFyIG49MDtpZihhcmd1bWVudHMubGVuZ3RoPjApe249TnVtYmVyKGFyZ3VtZW50c1sxXSk7aWYobiE9PW4pe249MH1lbHNlIGlmKG4hPT0wJiZuIT09MS8wJiZuIT09LSgxLzApKXtuPShuPjB8fC0xKSpmbG9vcihhYnMobikpfX1pZihuPj1sZW4pcmV0dXJuLTE7dmFyIGs9bj49MD9uOm1heChsZW4tYWJzKG4pLDApO2Zvcig7azxsZW47aysrKXtpZih0Ll9nZXR0ZXIoayk9PT1zZWFyY2hFbGVtZW50KXtyZXR1cm4ga319cmV0dXJuLTF9fSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KCRUeXBlZEFycmF5JC5wcm90b3R5cGUsImpvaW4iLHt2YWx1ZTpmdW5jdGlvbihzZXBhcmF0b3Ipe2lmKHRoaXM9PT11bmRlZmluZWR8fHRoaXM9PT1udWxsKXRocm93IFR5cGVFcnJvcigpO3ZhciB0PU9iamVjdCh0aGlzKTt2YXIgbGVuPVRvVWludDMyKHQubGVuZ3RoKTt2YXIgdG1wPUFycmF5KGxlbik7Zm9yKHZhciBpPTA7aTxsZW47KytpKXRtcFtpXT10Ll9nZXR0ZXIoaSk7cmV0dXJuIHRtcC5qb2luKHNlcGFyYXRvcj09PXVuZGVmaW5lZD8iLCI6c2VwYXJhdG9yKX19KTtPYmplY3QuZGVmaW5lUHJvcGVydHkoJFR5cGVkQXJyYXkkLnByb3RvdHlwZSwibGFzdEluZGV4T2YiLHt2YWx1ZTpmdW5jdGlvbihzZWFyY2hFbGVtZW50KXtpZih0aGlzPT09dW5kZWZpbmVkfHx0aGlzPT09bnVsbCl0aHJvdyBUeXBlRXJyb3IoKTt2YXIgdD1PYmplY3QodGhpcyk7dmFyIGxlbj1Ub1VpbnQzMih0Lmxlbmd0aCk7aWYobGVuPT09MClyZXR1cm4tMTt2YXIgbj1sZW47aWYoYXJndW1lbnRzLmxlbmd0aD4xKXtuPU51bWJlcihhcmd1bWVudHNbMV0pO2lmKG4hPT1uKXtuPTB9ZWxzZSBpZihuIT09MCYmbiE9PTEvMCYmbiE9PS0oMS8wKSl7bj0obj4wfHwtMSkqZmxvb3IoYWJzKG4pKX19dmFyIGs9bj49MD9taW4obixsZW4tMSk6bGVuLWFicyhuKTtmb3IoO2s+PTA7ay0tKXtpZih0Ll9nZXR0ZXIoayk9PT1zZWFyY2hFbGVtZW50KXJldHVybiBrfXJldHVybi0xfX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSgkVHlwZWRBcnJheSQucHJvdG90eXBlLCJtYXAiLHt2YWx1ZTpmdW5jdGlvbihjYWxsYmFja2ZuKXtpZih0aGlzPT09dW5kZWZpbmVkfHx0aGlzPT09bnVsbCl0aHJvdyBUeXBlRXJyb3IoKTt2YXIgdD1PYmplY3QodGhpcyk7dmFyIGxlbj1Ub1VpbnQzMih0Lmxlbmd0aCk7aWYoIUlzQ2FsbGFibGUoY2FsbGJhY2tmbikpdGhyb3cgVHlwZUVycm9yKCk7dmFyIHJlcz1bXTtyZXMubGVuZ3RoPWxlbjt2YXIgdGhpc3A9YXJndW1lbnRzWzFdO2Zvcih2YXIgaT0wO2k8bGVuO2krKylyZXNbaV09Y2FsbGJhY2tmbi5jYWxsKHRoaXNwLHQuX2dldHRlcihpKSxpLHQpO3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcihyZXMpfX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSgkVHlwZWRBcnJheSQucHJvdG90eXBlLCJyZWR1Y2UiLHt2YWx1ZTpmdW5jdGlvbihjYWxsYmFja2ZuKXtpZih0aGlzPT09dW5kZWZpbmVkfHx0aGlzPT09bnVsbCl0aHJvdyBUeXBlRXJyb3IoKTt2YXIgdD1PYmplY3QodGhpcyk7dmFyIGxlbj1Ub1VpbnQzMih0Lmxlbmd0aCk7aWYoIUlzQ2FsbGFibGUoY2FsbGJhY2tmbikpdGhyb3cgVHlwZUVycm9yKCk7aWYobGVuPT09MCYmYXJndW1lbnRzLmxlbmd0aD09PTEpdGhyb3cgVHlwZUVycm9yKCk7dmFyIGs9MDt2YXIgYWNjdW11bGF0b3I7aWYoYXJndW1lbnRzLmxlbmd0aD49Mil7YWNjdW11bGF0b3I9YXJndW1lbnRzWzFdfWVsc2V7YWNjdW11bGF0b3I9dC5fZ2V0dGVyKGsrKyl9d2hpbGUoazxsZW4pe2FjY3VtdWxhdG9yPWNhbGxiYWNrZm4uY2FsbCh1bmRlZmluZWQsYWNjdW11bGF0b3IsdC5fZ2V0dGVyKGspLGssdCk7aysrfXJldHVybiBhY2N1bXVsYXRvcn19KTtPYmplY3QuZGVmaW5lUHJvcGVydHkoJFR5cGVkQXJyYXkkLnByb3RvdHlwZSwicmVkdWNlUmlnaHQiLHt2YWx1ZTpmdW5jdGlvbihjYWxsYmFja2ZuKXtpZih0aGlzPT09dW5kZWZpbmVkfHx0aGlzPT09bnVsbCl0aHJvdyBUeXBlRXJyb3IoKTt2YXIgdD1PYmplY3QodGhpcyk7dmFyIGxlbj1Ub1VpbnQzMih0Lmxlbmd0aCk7aWYoIUlzQ2FsbGFibGUoY2FsbGJhY2tmbikpdGhyb3cgVHlwZUVycm9yKCk7aWYobGVuPT09MCYmYXJndW1lbnRzLmxlbmd0aD09PTEpdGhyb3cgVHlwZUVycm9yKCk7dmFyIGs9bGVuLTE7dmFyIGFjY3VtdWxhdG9yO2lmKGFyZ3VtZW50cy5sZW5ndGg+PTIpe2FjY3VtdWxhdG9yPWFyZ3VtZW50c1sxXX1lbHNle2FjY3VtdWxhdG9yPXQuX2dldHRlcihrLS0pfXdoaWxlKGs+PTApe2FjY3VtdWxhdG9yPWNhbGxiYWNrZm4uY2FsbCh1bmRlZmluZWQsYWNjdW11bGF0b3IsdC5fZ2V0dGVyKGspLGssdCk7ay0tfXJldHVybiBhY2N1bXVsYXRvcn19KTtPYmplY3QuZGVmaW5lUHJvcGVydHkoJFR5cGVkQXJyYXkkLnByb3RvdHlwZSwicmV2ZXJzZSIse3ZhbHVlOmZ1bmN0aW9uKCl7aWYodGhpcz09PXVuZGVmaW5lZHx8dGhpcz09PW51bGwpdGhyb3cgVHlwZUVycm9yKCk7dmFyIHQ9T2JqZWN0KHRoaXMpO3ZhciBsZW49VG9VaW50MzIodC5sZW5ndGgpO3ZhciBoYWxmPWZsb29yKGxlbi8yKTtmb3IodmFyIGk9MCxqPWxlbi0xO2k8aGFsZjsrK2ksLS1qKXt2YXIgdG1wPXQuX2dldHRlcihpKTt0Ll9zZXR0ZXIoaSx0Ll9nZXR0ZXIoaikpO3QuX3NldHRlcihqLHRtcCl9cmV0dXJuIHR9fSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KCRUeXBlZEFycmF5JC5wcm90b3R5cGUsInNldCIse3ZhbHVlOmZ1bmN0aW9uKGluZGV4LHZhbHVlKXtpZihhcmd1bWVudHMubGVuZ3RoPDEpdGhyb3cgU3ludGF4RXJyb3IoIk5vdCBlbm91Z2ggYXJndW1lbnRzIik7dmFyIGFycmF5LHNlcXVlbmNlLG9mZnNldCxsZW4saSxzLGQsYnl0ZU9mZnNldCxieXRlTGVuZ3RoLHRtcDtpZih0eXBlb2YgYXJndW1lbnRzWzBdPT09Im9iamVjdCImJmFyZ3VtZW50c1swXS5jb25zdHJ1Y3Rvcj09PXRoaXMuY29uc3RydWN0b3Ipe2FycmF5PWFyZ3VtZW50c1swXTtvZmZzZXQ9VG9VaW50MzIoYXJndW1lbnRzWzFdKTtpZihvZmZzZXQrYXJyYXkubGVuZ3RoPnRoaXMubGVuZ3RoKXt0aHJvdyBSYW5nZUVycm9yKCJPZmZzZXQgcGx1cyBsZW5ndGggb2YgYXJyYXkgaXMgb3V0IG9mIHJhbmdlIil9Ynl0ZU9mZnNldD10aGlzLmJ5dGVPZmZzZXQrb2Zmc2V0KnRoaXMuQllURVNfUEVSX0VMRU1FTlQ7Ynl0ZUxlbmd0aD1hcnJheS5sZW5ndGgqdGhpcy5CWVRFU19QRVJfRUxFTUVOVDtpZihhcnJheS5idWZmZXI9PT10aGlzLmJ1ZmZlcil7dG1wPVtdO2ZvcihpPTAscz1hcnJheS5ieXRlT2Zmc2V0O2k8Ynl0ZUxlbmd0aDtpKz0xLHMrPTEpe3RtcFtpXT1hcnJheS5idWZmZXIuX2J5dGVzW3NdfWZvcihpPTAsZD1ieXRlT2Zmc2V0O2k8Ynl0ZUxlbmd0aDtpKz0xLGQrPTEpe3RoaXMuYnVmZmVyLl9ieXRlc1tkXT10bXBbaV19fWVsc2V7Zm9yKGk9MCxzPWFycmF5LmJ5dGVPZmZzZXQsZD1ieXRlT2Zmc2V0O2k8Ynl0ZUxlbmd0aDtpKz0xLHMrPTEsZCs9MSl7dGhpcy5idWZmZXIuX2J5dGVzW2RdPWFycmF5LmJ1ZmZlci5fYnl0ZXNbc119fX1lbHNlIGlmKHR5cGVvZiBhcmd1bWVudHNbMF09PT0ib2JqZWN0IiYmdHlwZW9mIGFyZ3VtZW50c1swXS5sZW5ndGghPT0idW5kZWZpbmVkIil7c2VxdWVuY2U9YXJndW1lbnRzWzBdO2xlbj1Ub1VpbnQzMihzZXF1ZW5jZS5sZW5ndGgpO29mZnNldD1Ub1VpbnQzMihhcmd1bWVudHNbMV0pO2lmKG9mZnNldCtsZW4+dGhpcy5sZW5ndGgpe3Rocm93IFJhbmdlRXJyb3IoIk9mZnNldCBwbHVzIGxlbmd0aCBvZiBhcnJheSBpcyBvdXQgb2YgcmFuZ2UiKX1mb3IoaT0wO2k8bGVuO2krPTEpe3M9c2VxdWVuY2VbaV07dGhpcy5fc2V0dGVyKG9mZnNldCtpLE51bWJlcihzKSl9fWVsc2V7dGhyb3cgVHlwZUVycm9yKCJVbmV4cGVjdGVkIGFyZ3VtZW50IHR5cGUocykiKX19fSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KCRUeXBlZEFycmF5JC5wcm90b3R5cGUsInNsaWNlIix7dmFsdWU6ZnVuY3Rpb24oc3RhcnQsZW5kKXt2YXIgbz1Ub09iamVjdCh0aGlzKTt2YXIgbGVuVmFsPW8ubGVuZ3RoO3ZhciBsZW49VG9VaW50MzIobGVuVmFsKTt2YXIgcmVsYXRpdmVTdGFydD1Ub0ludDMyKHN0YXJ0KTt2YXIgaz1yZWxhdGl2ZVN0YXJ0PDA/bWF4KGxlbityZWxhdGl2ZVN0YXJ0LDApOm1pbihyZWxhdGl2ZVN0YXJ0LGxlbik7dmFyIHJlbGF0aXZlRW5kPWVuZD09PXVuZGVmaW5lZD9sZW46VG9JbnQzMihlbmQpO3ZhciBmaW5hbD1yZWxhdGl2ZUVuZDwwP21heChsZW4rcmVsYXRpdmVFbmQsMCk6bWluKHJlbGF0aXZlRW5kLGxlbik7dmFyIGNvdW50PWZpbmFsLWs7dmFyIGM9by5jb25zdHJ1Y3Rvcjt2YXIgYT1uZXcgYyhjb3VudCk7dmFyIG49MDt3aGlsZShrPGZpbmFsKXt2YXIga1ZhbHVlPW8uX2dldHRlcihrKTthLl9zZXR0ZXIobixrVmFsdWUpOysrazsrK259cmV0dXJuIGF9fSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KCRUeXBlZEFycmF5JC5wcm90b3R5cGUsInNvbWUiLHt2YWx1ZTpmdW5jdGlvbihjYWxsYmFja2ZuKXtpZih0aGlzPT09dW5kZWZpbmVkfHx0aGlzPT09bnVsbCl0aHJvdyBUeXBlRXJyb3IoKTt2YXIgdD1PYmplY3QodGhpcyk7dmFyIGxlbj1Ub1VpbnQzMih0Lmxlbmd0aCk7aWYoIUlzQ2FsbGFibGUoY2FsbGJhY2tmbikpdGhyb3cgVHlwZUVycm9yKCk7dmFyIHRoaXNwPWFyZ3VtZW50c1sxXTtmb3IodmFyIGk9MDtpPGxlbjtpKyspe2lmKGNhbGxiYWNrZm4uY2FsbCh0aGlzcCx0Ll9nZXR0ZXIoaSksaSx0KSl7cmV0dXJuIHRydWV9fXJldHVybiBmYWxzZX19KTtPYmplY3QuZGVmaW5lUHJvcGVydHkoJFR5cGVkQXJyYXkkLnByb3RvdHlwZSwic29ydCIse3ZhbHVlOmZ1bmN0aW9uKGNvbXBhcmVmbil7aWYodGhpcz09PXVuZGVmaW5lZHx8dGhpcz09PW51bGwpdGhyb3cgVHlwZUVycm9yKCk7dmFyIHQ9T2JqZWN0KHRoaXMpO3ZhciBsZW49VG9VaW50MzIodC5sZW5ndGgpO3ZhciB0bXA9QXJyYXkobGVuKTtmb3IodmFyIGk9MDtpPGxlbjsrK2kpdG1wW2ldPXQuX2dldHRlcihpKTtpZihjb21wYXJlZm4pdG1wLnNvcnQoY29tcGFyZWZuKTtlbHNlIHRtcC5zb3J0KCk7Zm9yKGk9MDtpPGxlbjsrK2kpdC5fc2V0dGVyKGksdG1wW2ldKTtyZXR1cm4gdH19KTtPYmplY3QuZGVmaW5lUHJvcGVydHkoJFR5cGVkQXJyYXkkLnByb3RvdHlwZSwic3ViYXJyYXkiLHt2YWx1ZTpmdW5jdGlvbihzdGFydCxlbmQpe2Z1bmN0aW9uIGNsYW1wKHYsbWluLG1heCl7cmV0dXJuIHY8bWluP21pbjp2Pm1heD9tYXg6dn1zdGFydD1Ub0ludDMyKHN0YXJ0KTtlbmQ9VG9JbnQzMihlbmQpO2lmKGFyZ3VtZW50cy5sZW5ndGg8MSl7c3RhcnQ9MH1pZihhcmd1bWVudHMubGVuZ3RoPDIpe2VuZD10aGlzLmxlbmd0aH1pZihzdGFydDwwKXtzdGFydD10aGlzLmxlbmd0aCtzdGFydH1pZihlbmQ8MCl7ZW5kPXRoaXMubGVuZ3RoK2VuZH1zdGFydD1jbGFtcChzdGFydCwwLHRoaXMubGVuZ3RoKTtlbmQ9Y2xhbXAoZW5kLDAsdGhpcy5sZW5ndGgpO3ZhciBsZW49ZW5kLXN0YXJ0O2lmKGxlbjwwKXtsZW49MH1yZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5idWZmZXIsdGhpcy5ieXRlT2Zmc2V0K3N0YXJ0KnRoaXMuQllURVNfUEVSX0VMRU1FTlQsbGVuKX19KTtmdW5jdGlvbiBtYWtlVHlwZWRBcnJheShlbGVtZW50U2l6ZSxwYWNrLHVucGFjayl7dmFyIFR5cGVkQXJyYXk9ZnVuY3Rpb24oKXtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiY29uc3RydWN0b3IiLHt2YWx1ZTpUeXBlZEFycmF5fSk7JFR5cGVkQXJyYXkkLmFwcGx5KHRoaXMsYXJndW1lbnRzKTttYWtlQXJyYXlBY2Nlc3NvcnModGhpcyl9O2lmKCJfX3Byb3RvX18iaW4gVHlwZWRBcnJheSl7VHlwZWRBcnJheS5fX3Byb3RvX189JFR5cGVkQXJyYXkkfWVsc2V7VHlwZWRBcnJheS5mcm9tPSRUeXBlZEFycmF5JC5mcm9tO1R5cGVkQXJyYXkub2Y9JFR5cGVkQXJyYXkkLm9mfVR5cGVkQXJyYXkuQllURVNfUEVSX0VMRU1FTlQ9ZWxlbWVudFNpemU7dmFyIFR5cGVkQXJyYXlQcm90b3R5cGU9ZnVuY3Rpb24oKXt9O1R5cGVkQXJyYXlQcm90b3R5cGUucHJvdG90eXBlPSRUeXBlZEFycmF5UHJvdG90eXBlJDtUeXBlZEFycmF5LnByb3RvdHlwZT1uZXcgVHlwZWRBcnJheVByb3RvdHlwZTtPYmplY3QuZGVmaW5lUHJvcGVydHkoVHlwZWRBcnJheS5wcm90b3R5cGUsIkJZVEVTX1BFUl9FTEVNRU5UIix7dmFsdWU6ZWxlbWVudFNpemV9KTtPYmplY3QuZGVmaW5lUHJvcGVydHkoVHlwZWRBcnJheS5wcm90b3R5cGUsIl9wYWNrIix7dmFsdWU6cGFja30pO09iamVjdC5kZWZpbmVQcm9wZXJ0eShUeXBlZEFycmF5LnByb3RvdHlwZSwiX3VucGFjayIse3ZhbHVlOnVucGFja30pO3JldHVybiBUeXBlZEFycmF5fXZhciBJbnQ4QXJyYXk9bWFrZVR5cGVkQXJyYXkoMSxwYWNrSTgsdW5wYWNrSTgpO3ZhciBVaW50OEFycmF5PW1ha2VUeXBlZEFycmF5KDEscGFja1U4LHVucGFja1U4KTt2YXIgVWludDhDbGFtcGVkQXJyYXk9bWFrZVR5cGVkQXJyYXkoMSxwYWNrVThDbGFtcGVkLHVucGFja1U4KTt2YXIgSW50MTZBcnJheT1tYWtlVHlwZWRBcnJheSgyLHBhY2tJMTYsdW5wYWNrSTE2KTt2YXIgVWludDE2QXJyYXk9bWFrZVR5cGVkQXJyYXkoMixwYWNrVTE2LHVucGFja1UxNik7dmFyIEludDMyQXJyYXk9bWFrZVR5cGVkQXJyYXkoNCxwYWNrSTMyLHVucGFja0kzMik7dmFyIFVpbnQzMkFycmF5PW1ha2VUeXBlZEFycmF5KDQscGFja1UzMix1bnBhY2tVMzIpO3ZhciBGbG9hdDMyQXJyYXk9bWFrZVR5cGVkQXJyYXkoNCxwYWNrRjMyLHVucGFja0YzMik7dmFyIEZsb2F0NjRBcnJheT1tYWtlVHlwZWRBcnJheSg4LHBhY2tGNjQsdW5wYWNrRjY0KTtnbG9iYWwuSW50OEFycmF5PWdsb2JhbC5JbnQ4QXJyYXl8fEludDhBcnJheTtnbG9iYWwuVWludDhBcnJheT1nbG9iYWwuVWludDhBcnJheXx8VWludDhBcnJheTtnbG9iYWwuVWludDhDbGFtcGVkQXJyYXk9Z2xvYmFsLlVpbnQ4Q2xhbXBlZEFycmF5fHxVaW50OENsYW1wZWRBcnJheTtnbG9iYWwuSW50MTZBcnJheT1nbG9iYWwuSW50MTZBcnJheXx8SW50MTZBcnJheTtnbG9iYWwuVWludDE2QXJyYXk9Z2xvYmFsLlVpbnQxNkFycmF5fHxVaW50MTZBcnJheTtnbG9iYWwuSW50MzJBcnJheT1nbG9iYWwuSW50MzJBcnJheXx8SW50MzJBcnJheTtnbG9iYWwuVWludDMyQXJyYXk9Z2xvYmFsLlVpbnQzMkFycmF5fHxVaW50MzJBcnJheTtnbG9iYWwuRmxvYXQzMkFycmF5PWdsb2JhbC5GbG9hdDMyQXJyYXl8fEZsb2F0MzJBcnJheTtnbG9iYWwuRmxvYXQ2NEFycmF5PWdsb2JhbC5GbG9hdDY0QXJyYXl8fEZsb2F0NjRBcnJheX0pKCk7KGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihhcnJheSxpbmRleCl7cmV0dXJuIElzQ2FsbGFibGUoYXJyYXkuZ2V0KT9hcnJheS5nZXQoaW5kZXgpOmFycmF5W2luZGV4XX12YXIgSVNfQklHX0VORElBTj1mdW5jdGlvbigpe3ZhciB1MTZhcnJheT1uZXcgVWludDE2QXJyYXkoWzQ2NjBdKSx1OGFycmF5PW5ldyBVaW50OEFycmF5KHUxNmFycmF5LmJ1ZmZlcik7cmV0dXJuIHIodThhcnJheSwwKT09PTE4fSgpO2Z1bmN0aW9uIERhdGFWaWV3KGJ1ZmZlcixieXRlT2Zmc2V0LGJ5dGVMZW5ndGgpe2lmKCEoYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXJ8fENsYXNzKGJ1ZmZlcik9PT0iQXJyYXlCdWZmZXIiKSl0aHJvdyBUeXBlRXJyb3IoKTtieXRlT2Zmc2V0PVRvVWludDMyKGJ5dGVPZmZzZXQpO2lmKGJ5dGVPZmZzZXQ+YnVmZmVyLmJ5dGVMZW5ndGgpdGhyb3cgUmFuZ2VFcnJvcigiYnl0ZU9mZnNldCBvdXQgb2YgcmFuZ2UiKTtpZihieXRlTGVuZ3RoPT09dW5kZWZpbmVkKWJ5dGVMZW5ndGg9YnVmZmVyLmJ5dGVMZW5ndGgtYnl0ZU9mZnNldDtlbHNlIGJ5dGVMZW5ndGg9VG9VaW50MzIoYnl0ZUxlbmd0aCk7aWYoYnl0ZU9mZnNldCtieXRlTGVuZ3RoPmJ1ZmZlci5ieXRlTGVuZ3RoKXRocm93IFJhbmdlRXJyb3IoImJ5dGVPZmZzZXQgYW5kIGxlbmd0aCByZWZlcmVuY2UgYW4gYXJlYSBiZXlvbmQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyIik7T2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsImJ1ZmZlciIse3ZhbHVlOmJ1ZmZlcn0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJieXRlTGVuZ3RoIix7dmFsdWU6Ynl0ZUxlbmd0aH0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJieXRlT2Zmc2V0Iix7dmFsdWU6Ynl0ZU9mZnNldH0pfWZ1bmN0aW9uIG1ha2VHZXR0ZXIoYXJyYXlUeXBlKXtyZXR1cm4gZnVuY3Rpb24gR2V0Vmlld1ZhbHVlKGJ5dGVPZmZzZXQsbGl0dGxlRW5kaWFuKXtieXRlT2Zmc2V0PVRvVWludDMyKGJ5dGVPZmZzZXQpO2lmKGJ5dGVPZmZzZXQrYXJyYXlUeXBlLkJZVEVTX1BFUl9FTEVNRU5UPnRoaXMuYnl0ZUxlbmd0aCl0aHJvdyBSYW5nZUVycm9yKCJBcnJheSBpbmRleCBvdXQgb2YgcmFuZ2UiKTtieXRlT2Zmc2V0Kz10aGlzLmJ5dGVPZmZzZXQ7dmFyIHVpbnQ4QXJyYXk9bmV3IFVpbnQ4QXJyYXkodGhpcy5idWZmZXIsYnl0ZU9mZnNldCxhcnJheVR5cGUuQllURVNfUEVSX0VMRU1FTlQpLGJ5dGVzPVtdO2Zvcih2YXIgaT0wO2k8YXJyYXlUeXBlLkJZVEVTX1BFUl9FTEVNRU5UO2krPTEpYnl0ZXMucHVzaChyKHVpbnQ4QXJyYXksaSkpO2lmKEJvb2xlYW4obGl0dGxlRW5kaWFuKT09PUJvb2xlYW4oSVNfQklHX0VORElBTikpYnl0ZXMucmV2ZXJzZSgpO3JldHVybiByKG5ldyBhcnJheVR5cGUobmV3IFVpbnQ4QXJyYXkoYnl0ZXMpLmJ1ZmZlciksMCl9fU9iamVjdC5kZWZpbmVQcm9wZXJ0eShEYXRhVmlldy5wcm90b3R5cGUsImdldFVpbnQ4Iix7dmFsdWU6bWFrZUdldHRlcihVaW50OEFycmF5KX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eShEYXRhVmlldy5wcm90b3R5cGUsImdldEludDgiLHt2YWx1ZTptYWtlR2V0dGVyKEludDhBcnJheSl9KTtPYmplY3QuZGVmaW5lUHJvcGVydHkoRGF0YVZpZXcucHJvdG90eXBlLCJnZXRVaW50MTYiLHt2YWx1ZTptYWtlR2V0dGVyKFVpbnQxNkFycmF5KX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eShEYXRhVmlldy5wcm90b3R5cGUsImdldEludDE2Iix7dmFsdWU6bWFrZUdldHRlcihJbnQxNkFycmF5KX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eShEYXRhVmlldy5wcm90b3R5cGUsImdldFVpbnQzMiIse3ZhbHVlOm1ha2VHZXR0ZXIoVWludDMyQXJyYXkpfSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KERhdGFWaWV3LnByb3RvdHlwZSwiZ2V0SW50MzIiLHt2YWx1ZTptYWtlR2V0dGVyKEludDMyQXJyYXkpfSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KERhdGFWaWV3LnByb3RvdHlwZSwiZ2V0RmxvYXQzMiIse3ZhbHVlOm1ha2VHZXR0ZXIoRmxvYXQzMkFycmF5KX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eShEYXRhVmlldy5wcm90b3R5cGUsImdldEZsb2F0NjQiLHt2YWx1ZTptYWtlR2V0dGVyKEZsb2F0NjRBcnJheSl9KTtmdW5jdGlvbiBtYWtlU2V0dGVyKGFycmF5VHlwZSl7cmV0dXJuIGZ1bmN0aW9uIFNldFZpZXdWYWx1ZShieXRlT2Zmc2V0LHZhbHVlLGxpdHRsZUVuZGlhbil7Ynl0ZU9mZnNldD1Ub1VpbnQzMihieXRlT2Zmc2V0KTtpZihieXRlT2Zmc2V0K2FycmF5VHlwZS5CWVRFU19QRVJfRUxFTUVOVD50aGlzLmJ5dGVMZW5ndGgpdGhyb3cgUmFuZ2VFcnJvcigiQXJyYXkgaW5kZXggb3V0IG9mIHJhbmdlIik7dmFyIHR5cGVBcnJheT1uZXcgYXJyYXlUeXBlKFt2YWx1ZV0pLGJ5dGVBcnJheT1uZXcgVWludDhBcnJheSh0eXBlQXJyYXkuYnVmZmVyKSxieXRlcz1bXSxpLGJ5dGVWaWV3O2ZvcihpPTA7aTxhcnJheVR5cGUuQllURVNfUEVSX0VMRU1FTlQ7aSs9MSlieXRlcy5wdXNoKHIoYnl0ZUFycmF5LGkpKTtpZihCb29sZWFuKGxpdHRsZUVuZGlhbik9PT1Cb29sZWFuKElTX0JJR19FTkRJQU4pKWJ5dGVzLnJldmVyc2UoKTtieXRlVmlldz1uZXcgVWludDhBcnJheSh0aGlzLmJ1ZmZlcixieXRlT2Zmc2V0LGFycmF5VHlwZS5CWVRFU19QRVJfRUxFTUVOVCk7Ynl0ZVZpZXcuc2V0KGJ5dGVzKX19T2JqZWN0LmRlZmluZVByb3BlcnR5KERhdGFWaWV3LnByb3RvdHlwZSwic2V0VWludDgiLHt2YWx1ZTptYWtlU2V0dGVyKFVpbnQ4QXJyYXkpfSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KERhdGFWaWV3LnByb3RvdHlwZSwic2V0SW50OCIse3ZhbHVlOm1ha2VTZXR0ZXIoSW50OEFycmF5KX0pO09iamVjdC5kZWZpbmVQcm9wZXJ0eShEYXRhVmlldy5wcm90b3R5cGUsInNldFVpbnQxNiIse3ZhbHVlOm1ha2VTZXR0ZXIoVWludDE2QXJyYXkpfSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KERhdGFWaWV3LnByb3RvdHlwZSwic2V0SW50MTYiLHt2YWx1ZTptYWtlU2V0dGVyKEludDE2QXJyYXkpfSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KERhdGFWaWV3LnByb3RvdHlwZSwic2V0VWludDMyIix7dmFsdWU6bWFrZVNldHRlcihVaW50MzJBcnJheSl9KTtPYmplY3QuZGVmaW5lUHJvcGVydHkoRGF0YVZpZXcucHJvdG90eXBlLCJzZXRJbnQzMiIse3ZhbHVlOm1ha2VTZXR0ZXIoSW50MzJBcnJheSl9KTtPYmplY3QuZGVmaW5lUHJvcGVydHkoRGF0YVZpZXcucHJvdG90eXBlLCJzZXRGbG9hdDMyIix7dmFsdWU6bWFrZVNldHRlcihGbG9hdDMyQXJyYXkpfSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KERhdGFWaWV3LnByb3RvdHlwZSwic2V0RmxvYXQ2NCIse3ZhbHVlOm1ha2VTZXR0ZXIoRmxvYXQ2NEFycmF5KX0pO2dsb2JhbC5EYXRhVmlldz1nbG9iYWwuRGF0YVZpZXd8fERhdGFWaWV3fSkoKX0pKHRoaXMpOw==\"></script>\n",
"<script src=\"data:application/javascript;base64,LyohIGpRdWVyeSB2MS4xMS4zIHwgKGMpIDIwMDUsIDIwMTUgalF1ZXJ5IEZvdW5kYXRpb24sIEluYy4gfCBqcXVlcnkub3JnL2xpY2Vuc2UgKi8KIWZ1bmN0aW9uKGEsYil7Im9iamVjdCI9PXR5cGVvZiBtb2R1bGUmJiJvYmplY3QiPT10eXBlb2YgbW9kdWxlLmV4cG9ydHM/bW9kdWxlLmV4cG9ydHM9YS5kb2N1bWVudD9iKGEsITApOmZ1bmN0aW9uKGEpe2lmKCFhLmRvY3VtZW50KXRocm93IG5ldyBFcnJvcigialF1ZXJ5IHJlcXVpcmVzIGEgd2luZG93IHdpdGggYSBkb2N1bWVudCIpO3JldHVybiBiKGEpfTpiKGEpfSgidW5kZWZpbmVkIiE9dHlwZW9mIHdpbmRvdz93aW5kb3c6dGhpcyxmdW5jdGlvbihhLGIpe3ZhciBjPVtdLGQ9Yy5zbGljZSxlPWMuY29uY2F0LGY9Yy5wdXNoLGc9Yy5pbmRleE9mLGg9e30saT1oLnRvU3RyaW5nLGo9aC5oYXNPd25Qcm9wZXJ0eSxrPXt9LGw9IjEuMTEuMyIsbT1mdW5jdGlvbihhLGIpe3JldHVybiBuZXcgbS5mbi5pbml0KGEsYil9LG49L15bXHNcdUZFRkZceEEwXSt8W1xzXHVGRUZGXHhBMF0rJC9nLG89L14tbXMtLyxwPS8tKFtcZGEtel0pL2dpLHE9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYi50b1VwcGVyQ2FzZSgpfTttLmZuPW0ucHJvdG90eXBlPXtqcXVlcnk6bCxjb25zdHJ1Y3RvcjptLHNlbGVjdG9yOiIiLGxlbmd0aDowLHRvQXJyYXk6ZnVuY3Rpb24oKXtyZXR1cm4gZC5jYWxsKHRoaXMpfSxnZXQ6ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGwhPWE/MD5hP3RoaXNbYSt0aGlzLmxlbmd0aF06dGhpc1thXTpkLmNhbGwodGhpcyl9LHB1c2hTdGFjazpmdW5jdGlvbihhKXt2YXIgYj1tLm1lcmdlKHRoaXMuY29uc3RydWN0b3IoKSxhKTtyZXR1cm4gYi5wcmV2T2JqZWN0PXRoaXMsYi5jb250ZXh0PXRoaXMuY29udGV4dCxifSxlYWNoOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG0uZWFjaCh0aGlzLGEsYil9LG1hcDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2sobS5tYXAodGhpcyxmdW5jdGlvbihiLGMpe3JldHVybiBhLmNhbGwoYixjLGIpfSkpfSxzbGljZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLnB1c2hTdGFjayhkLmFwcGx5KHRoaXMsYXJndW1lbnRzKSl9LGZpcnN0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZXEoMCl9LGxhc3Q6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lcSgtMSl9LGVxOmZ1bmN0aW9uKGEpe3ZhciBiPXRoaXMubGVuZ3RoLGM9K2ErKDA+YT9iOjApO3JldHVybiB0aGlzLnB1c2hTdGFjayhjPj0wJiZiPmM/W3RoaXNbY11dOltdKX0sZW5kOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucHJldk9iamVjdHx8dGhpcy5jb25zdHJ1Y3RvcihudWxsKX0scHVzaDpmLHNvcnQ6Yy5zb3J0LHNwbGljZTpjLnNwbGljZX0sbS5leHRlbmQ9bS5mbi5leHRlbmQ9ZnVuY3Rpb24oKXt2YXIgYSxiLGMsZCxlLGYsZz1hcmd1bWVudHNbMF18fHt9LGg9MSxpPWFyZ3VtZW50cy5sZW5ndGgsaj0hMTtmb3IoImJvb2xlYW4iPT10eXBlb2YgZyYmKGo9ZyxnPWFyZ3VtZW50c1toXXx8e30saCsrKSwib2JqZWN0Ij09dHlwZW9mIGd8fG0uaXNGdW5jdGlvbihnKXx8KGc9e30pLGg9PT1pJiYoZz10aGlzLGgtLSk7aT5oO2grKylpZihudWxsIT0oZT1hcmd1bWVudHNbaF0pKWZvcihkIGluIGUpYT1nW2RdLGM9ZVtkXSxnIT09YyYmKGomJmMmJihtLmlzUGxhaW5PYmplY3QoYyl8fChiPW0uaXNBcnJheShjKSkpPyhiPyhiPSExLGY9YSYmbS5pc0FycmF5KGEpP2E6W10pOmY9YSYmbS5pc1BsYWluT2JqZWN0KGEpP2E6e30sZ1tkXT1tLmV4dGVuZChqLGYsYykpOnZvaWQgMCE9PWMmJihnW2RdPWMpKTtyZXR1cm4gZ30sbS5leHRlbmQoe2V4cGFuZG86ImpRdWVyeSIrKGwrTWF0aC5yYW5kb20oKSkucmVwbGFjZSgvXEQvZywiIiksaXNSZWFkeTohMCxlcnJvcjpmdW5jdGlvbihhKXt0aHJvdyBuZXcgRXJyb3IoYSl9LG5vb3A6ZnVuY3Rpb24oKXt9LGlzRnVuY3Rpb246ZnVuY3Rpb24oYSl7cmV0dXJuImZ1bmN0aW9uIj09PW0udHlwZShhKX0saXNBcnJheTpBcnJheS5pc0FycmF5fHxmdW5jdGlvbihhKXtyZXR1cm4iYXJyYXkiPT09bS50eXBlKGEpfSxpc1dpbmRvdzpmdW5jdGlvbihhKXtyZXR1cm4gbnVsbCE9YSYmYT09YS53aW5kb3d9LGlzTnVtZXJpYzpmdW5jdGlvbihhKXtyZXR1cm4hbS5pc0FycmF5KGEpJiZhLXBhcnNlRmxvYXQoYSkrMT49MH0saXNFbXB0eU9iamVjdDpmdW5jdGlvbihhKXt2YXIgYjtmb3IoYiBpbiBhKXJldHVybiExO3JldHVybiEwfSxpc1BsYWluT2JqZWN0OmZ1bmN0aW9uKGEpe3ZhciBiO2lmKCFhfHwib2JqZWN0IiE9PW0udHlwZShhKXx8YS5ub2RlVHlwZXx8bS5pc1dpbmRvdyhhKSlyZXR1cm4hMTt0cnl7aWYoYS5jb25zdHJ1Y3RvciYmIWouY2FsbChhLCJjb25zdHJ1Y3RvciIpJiYhai5jYWxsKGEuY29uc3RydWN0b3IucHJvdG90eXBlLCJpc1Byb3RvdHlwZU9mIikpcmV0dXJuITF9Y2F0Y2goYyl7cmV0dXJuITF9aWYoay5vd25MYXN0KWZvcihiIGluIGEpcmV0dXJuIGouY2FsbChhLGIpO2ZvcihiIGluIGEpO3JldHVybiB2b2lkIDA9PT1ifHxqLmNhbGwoYSxiKX0sdHlwZTpmdW5jdGlvbihhKXtyZXR1cm4gbnVsbD09YT9hKyIiOiJvYmplY3QiPT10eXBlb2YgYXx8ImZ1bmN0aW9uIj09dHlwZW9mIGE/aFtpLmNhbGwoYSldfHwib2JqZWN0Ijp0eXBlb2YgYX0sZ2xvYmFsRXZhbDpmdW5jdGlvbihiKXtiJiZtLnRyaW0oYikmJihhLmV4ZWNTY3JpcHR8fGZ1bmN0aW9uKGIpe2EuZXZhbC5jYWxsKGEsYil9KShiKX0sY2FtZWxDYXNlOmZ1bmN0aW9uKGEpe3JldHVybiBhLnJlcGxhY2UobywibXMtIikucmVwbGFjZShwLHEpfSxub2RlTmFtZTpmdW5jdGlvbihhLGIpe3JldHVybiBhLm5vZGVOYW1lJiZhLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk9PT1iLnRvTG93ZXJDYXNlKCl9LGVhY2g6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkLGU9MCxmPWEubGVuZ3RoLGc9cihhKTtpZihjKXtpZihnKXtmb3IoO2Y+ZTtlKyspaWYoZD1iLmFwcGx5KGFbZV0sYyksZD09PSExKWJyZWFrfWVsc2UgZm9yKGUgaW4gYSlpZihkPWIuYXBwbHkoYVtlXSxjKSxkPT09ITEpYnJlYWt9ZWxzZSBpZihnKXtmb3IoO2Y+ZTtlKyspaWYoZD1iLmNhbGwoYVtlXSxlLGFbZV0pLGQ9PT0hMSlicmVha31lbHNlIGZvcihlIGluIGEpaWYoZD1iLmNhbGwoYVtlXSxlLGFbZV0pLGQ9PT0hMSlicmVhaztyZXR1cm4gYX0sdHJpbTpmdW5jdGlvbihhKXtyZXR1cm4gbnVsbD09YT8iIjooYSsiIikucmVwbGFjZShuLCIiKX0sbWFrZUFycmF5OmZ1bmN0aW9uKGEsYil7dmFyIGM9Ynx8W107cmV0dXJuIG51bGwhPWEmJihyKE9iamVjdChhKSk/bS5tZXJnZShjLCJzdHJpbmciPT10eXBlb2YgYT9bYV06YSk6Zi5jYWxsKGMsYSkpLGN9LGluQXJyYXk6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkO2lmKGIpe2lmKGcpcmV0dXJuIGcuY2FsbChiLGEsYyk7Zm9yKGQ9Yi5sZW5ndGgsYz1jPzA+Yz9NYXRoLm1heCgwLGQrYyk6YzowO2Q+YztjKyspaWYoYyBpbiBiJiZiW2NdPT09YSlyZXR1cm4gY31yZXR1cm4tMX0sbWVyZ2U6ZnVuY3Rpb24oYSxiKXt2YXIgYz0rYi5sZW5ndGgsZD0wLGU9YS5sZW5ndGg7d2hpbGUoYz5kKWFbZSsrXT1iW2QrK107aWYoYyE9PWMpd2hpbGUodm9pZCAwIT09YltkXSlhW2UrK109YltkKytdO3JldHVybiBhLmxlbmd0aD1lLGF9LGdyZXA6ZnVuY3Rpb24oYSxiLGMpe2Zvcih2YXIgZCxlPVtdLGY9MCxnPWEubGVuZ3RoLGg9IWM7Zz5mO2YrKylkPSFiKGFbZl0sZiksZCE9PWgmJmUucHVzaChhW2ZdKTtyZXR1cm4gZX0sbWFwOmZ1bmN0aW9uKGEsYixjKXt2YXIgZCxmPTAsZz1hLmxlbmd0aCxoPXIoYSksaT1bXTtpZihoKWZvcig7Zz5mO2YrKylkPWIoYVtmXSxmLGMpLG51bGwhPWQmJmkucHVzaChkKTtlbHNlIGZvcihmIGluIGEpZD1iKGFbZl0sZixjKSxudWxsIT1kJiZpLnB1c2goZCk7cmV0dXJuIGUuYXBwbHkoW10saSl9LGd1aWQ6MSxwcm94eTpmdW5jdGlvbihhLGIpe3ZhciBjLGUsZjtyZXR1cm4ic3RyaW5nIj09dHlwZW9mIGImJihmPWFbYl0sYj1hLGE9ZiksbS5pc0Z1bmN0aW9uKGEpPyhjPWQuY2FsbChhcmd1bWVudHMsMiksZT1mdW5jdGlvbigpe3JldHVybiBhLmFwcGx5KGJ8fHRoaXMsYy5jb25jYXQoZC5jYWxsKGFyZ3VtZW50cykpKX0sZS5ndWlkPWEuZ3VpZD1hLmd1aWR8fG0uZ3VpZCsrLGUpOnZvaWQgMH0sbm93OmZ1bmN0aW9uKCl7cmV0dXJuK25ldyBEYXRlfSxzdXBwb3J0Omt9KSxtLmVhY2goIkJvb2xlYW4gTnVtYmVyIFN0cmluZyBGdW5jdGlvbiBBcnJheSBEYXRlIFJlZ0V4cCBPYmplY3QgRXJyb3IiLnNwbGl0KCIgIiksZnVuY3Rpb24oYSxiKXtoWyJbb2JqZWN0ICIrYisiXSJdPWIudG9Mb3dlckNhc2UoKX0pO2Z1bmN0aW9uIHIoYSl7dmFyIGI9Imxlbmd0aCJpbiBhJiZhLmxlbmd0aCxjPW0udHlwZShhKTtyZXR1cm4iZnVuY3Rpb24iPT09Y3x8bS5pc1dpbmRvdyhhKT8hMToxPT09YS5ub2RlVHlwZSYmYj8hMDoiYXJyYXkiPT09Y3x8MD09PWJ8fCJudW1iZXIiPT10eXBlb2YgYiYmYj4wJiZiLTEgaW4gYX12YXIgcz1mdW5jdGlvbihhKXt2YXIgYixjLGQsZSxmLGcsaCxpLGosayxsLG0sbixvLHAscSxyLHMsdCx1PSJzaXp6bGUiKzEqbmV3IERhdGUsdj1hLmRvY3VtZW50LHc9MCx4PTAseT1oYSgpLHo9aGEoKSxBPWhhKCksQj1mdW5jdGlvbihhLGIpe3JldHVybiBhPT09YiYmKGw9ITApLDB9LEM9MTw8MzEsRD17fS5oYXNPd25Qcm9wZXJ0eSxFPVtdLEY9RS5wb3AsRz1FLnB1c2gsSD1FLnB1c2gsST1FLnNsaWNlLEo9ZnVuY3Rpb24oYSxiKXtmb3IodmFyIGM9MCxkPWEubGVuZ3RoO2Q+YztjKyspaWYoYVtjXT09PWIpcmV0dXJuIGM7cmV0dXJuLTF9LEs9ImNoZWNrZWR8c2VsZWN0ZWR8YXN5bmN8YXV0b2ZvY3VzfGF1dG9wbGF5fGNvbnRyb2xzfGRlZmVyfGRpc2FibGVkfGhpZGRlbnxpc21hcHxsb29wfG11bHRpcGxlfG9wZW58cmVhZG9ubHl8cmVxdWlyZWR8c2NvcGVkIixMPSJbXFx4MjBcXHRcXHJcXG5cXGZdIixNPSIoPzpcXFxcLnxbXFx3LV18W15cXHgwMC1cXHhhMF0pKyIsTj1NLnJlcGxhY2UoInciLCJ3IyIpLE89IlxcWyIrTCsiKigiK00rIikoPzoiK0wrIiooWypeJHwhfl0/PSkiK0wrIiooPzonKCg/OlxcXFwufFteXFxcXCddKSopJ3xcIigoPzpcXFxcLnxbXlxcXFxcIl0pKilcInwoIitOKyIpKXwpIitMKyIqXFxdIixQPSI6KCIrTSsiKSg/OlxcKCgoJygoPzpcXFxcLnxbXlxcXFwnXSkqKSd8XCIoKD86XFxcXC58W15cXFxcXCJdKSopXCIpfCgoPzpcXFxcLnxbXlxcXFwoKVtcXF1dfCIrTysiKSopfC4qKVxcKXwpIixRPW5ldyBSZWdFeHAoTCsiKyIsImciKSxSPW5ldyBSZWdFeHAoIl4iK0wrIit8KCg/Ol58W15cXFxcXSkoPzpcXFxcLikqKSIrTCsiKyQiLCJnIiksUz1uZXcgUmVnRXhwKCJeIitMKyIqLCIrTCsiKiIpLFQ9bmV3IFJlZ0V4cCgiXiIrTCsiKihbPit+XXwiK0wrIikiK0wrIioiKSxVPW5ldyBSZWdFeHAoIj0iK0wrIiooW15cXF0nXCJdKj8pIitMKyIqXFxdIiwiZyIpLFY9bmV3IFJlZ0V4cChQKSxXPW5ldyBSZWdFeHAoIl4iK04rIiQiKSxYPXtJRDpuZXcgUmVnRXhwKCJeIygiK00rIikiKSxDTEFTUzpuZXcgUmVnRXhwKCJeXFwuKCIrTSsiKSIpLFRBRzpuZXcgUmVnRXhwKCJeKCIrTS5yZXBsYWNlKCJ3IiwidyoiKSsiKSIpLEFUVFI6bmV3IFJlZ0V4cCgiXiIrTyksUFNFVURPOm5ldyBSZWdFeHAoIl4iK1ApLENISUxEOm5ldyBSZWdFeHAoIl46KG9ubHl8Zmlyc3R8bGFzdHxudGh8bnRoLWxhc3QpLShjaGlsZHxvZi10eXBlKSg/OlxcKCIrTCsiKihldmVufG9kZHwoKFsrLV18KShcXGQqKW58KSIrTCsiKig/OihbKy1dfCkiK0wrIiooXFxkKyl8KSkiK0wrIipcXCl8KSIsImkiKSxib29sOm5ldyBSZWdFeHAoIl4oPzoiK0srIikkIiwiaSIpLG5lZWRzQ29udGV4dDpuZXcgUmVnRXhwKCJeIitMKyIqWz4rfl18OihldmVufG9kZHxlcXxndHxsdHxudGh8Zmlyc3R8bGFzdCkoPzpcXCgiK0wrIiooKD86LVxcZCk/XFxkKikiK0wrIipcXCl8KSg/PVteLV18JCkiLCJpIil9LFk9L14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxaPS9eaFxkJC9pLCQ9L15bXntdK1x7XHMqXFtuYXRpdmUgXHcvLF89L14oPzojKFtcdy1dKyl8KFx3Kyl8XC4oW1x3LV0rKSkkLyxhYT0vWyt+XS8sYmE9Lyd8XFwvZyxjYT1uZXcgUmVnRXhwKCJcXFxcKFtcXGRhLWZdezEsNn0iK0wrIj98KCIrTCsiKXwuKSIsImlnIiksZGE9ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPSIweCIrYi02NTUzNjtyZXR1cm4gZCE9PWR8fGM/YjowPmQ/U3RyaW5nLmZyb21DaGFyQ29kZShkKzY1NTM2KTpTdHJpbmcuZnJvbUNoYXJDb2RlKGQ+PjEwfDU1Mjk2LDEwMjMmZHw1NjMyMCl9LGVhPWZ1bmN0aW9uKCl7bSgpfTt0cnl7SC5hcHBseShFPUkuY2FsbCh2LmNoaWxkTm9kZXMpLHYuY2hpbGROb2RlcyksRVt2LmNoaWxkTm9kZXMubGVuZ3RoXS5ub2RlVHlwZX1jYXRjaChmYSl7SD17YXBwbHk6RS5sZW5ndGg/ZnVuY3Rpb24oYSxiKXtHLmFwcGx5KGEsSS5jYWxsKGIpKX06ZnVuY3Rpb24oYSxiKXt2YXIgYz1hLmxlbmd0aCxkPTA7d2hpbGUoYVtjKytdPWJbZCsrXSk7YS5sZW5ndGg9Yy0xfX19ZnVuY3Rpb24gZ2EoYSxiLGQsZSl7dmFyIGYsaCxqLGssbCxvLHIscyx3LHg7aWYoKGI/Yi5vd25lckRvY3VtZW50fHxiOnYpIT09biYmbShiKSxiPWJ8fG4sZD1kfHxbXSxrPWIubm9kZVR5cGUsInN0cmluZyIhPXR5cGVvZiBhfHwhYXx8MSE9PWsmJjkhPT1rJiYxMSE9PWspcmV0dXJuIGQ7aWYoIWUmJnApe2lmKDExIT09ayYmKGY9Xy5leGVjKGEpKSlpZihqPWZbMV0pe2lmKDk9PT1rKXtpZihoPWIuZ2V0RWxlbWVudEJ5SWQoaiksIWh8fCFoLnBhcmVudE5vZGUpcmV0dXJuIGQ7aWYoaC5pZD09PWopcmV0dXJuIGQucHVzaChoKSxkfWVsc2UgaWYoYi5vd25lckRvY3VtZW50JiYoaD1iLm93bmVyRG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaikpJiZ0KGIsaCkmJmguaWQ9PT1qKXJldHVybiBkLnB1c2goaCksZH1lbHNle2lmKGZbMl0pcmV0dXJuIEguYXBwbHkoZCxiLmdldEVsZW1lbnRzQnlUYWdOYW1lKGEpKSxkO2lmKChqPWZbM10pJiZjLmdldEVsZW1lbnRzQnlDbGFzc05hbWUpcmV0dXJuIEguYXBwbHkoZCxiLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoaikpLGR9aWYoYy5xc2EmJighcXx8IXEudGVzdChhKSkpe2lmKHM9cj11LHc9Yix4PTEhPT1rJiZhLDE9PT1rJiYib2JqZWN0IiE9PWIubm9kZU5hbWUudG9Mb3dlckNhc2UoKSl7bz1nKGEpLChyPWIuZ2V0QXR0cmlidXRlKCJpZCIpKT9zPXIucmVwbGFjZShiYSwiXFwkJiIpOmIuc2V0QXR0cmlidXRlKCJpZCIscykscz0iW2lkPSciK3MrIiddICIsbD1vLmxlbmd0aDt3aGlsZShsLS0pb1tsXT1zK3JhKG9bbF0pO3c9YWEudGVzdChhKSYmcGEoYi5wYXJlbnROb2RlKXx8Yix4PW8uam9pbigiLCIpfWlmKHgpdHJ5e3JldHVybiBILmFwcGx5KGQsdy5xdWVyeVNlbGVjdG9yQWxsKHgpKSxkfWNhdGNoKHkpe31maW5hbGx5e3J8fGIucmVtb3ZlQXR0cmlidXRlKCJpZCIpfX19cmV0dXJuIGkoYS5yZXBsYWNlKFIsIiQxIiksYixkLGUpfWZ1bmN0aW9uIGhhKCl7dmFyIGE9W107ZnVuY3Rpb24gYihjLGUpe3JldHVybiBhLnB1c2goYysiICIpPmQuY2FjaGVMZW5ndGgmJmRlbGV0ZSBiW2Euc2hpZnQoKV0sYltjKyIgIl09ZX1yZXR1cm4gYn1mdW5jdGlvbiBpYShhKXtyZXR1cm4gYVt1XT0hMCxhfWZ1bmN0aW9uIGphKGEpe3ZhciBiPW4uY3JlYXRlRWxlbWVudCgiZGl2Iik7dHJ5e3JldHVybiEhYShiKX1jYXRjaChjKXtyZXR1cm4hMX1maW5hbGx5e2IucGFyZW50Tm9kZSYmYi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGIpLGI9bnVsbH19ZnVuY3Rpb24ga2EoYSxiKXt2YXIgYz1hLnNwbGl0KCJ8IiksZT1hLmxlbmd0aDt3aGlsZShlLS0pZC5hdHRySGFuZGxlW2NbZV1dPWJ9ZnVuY3Rpb24gbGEoYSxiKXt2YXIgYz1iJiZhLGQ9YyYmMT09PWEubm9kZVR5cGUmJjE9PT1iLm5vZGVUeXBlJiYofmIuc291cmNlSW5kZXh8fEMpLSh+YS5zb3VyY2VJbmRleHx8Qyk7aWYoZClyZXR1cm4gZDtpZihjKXdoaWxlKGM9Yy5uZXh0U2libGluZylpZihjPT09YilyZXR1cm4tMTtyZXR1cm4gYT8xOi0xfWZ1bmN0aW9uIG1hKGEpe3JldHVybiBmdW5jdGlvbihiKXt2YXIgYz1iLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuImlucHV0Ij09PWMmJmIudHlwZT09PWF9fWZ1bmN0aW9uIG5hKGEpe3JldHVybiBmdW5jdGlvbihiKXt2YXIgYz1iLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuKCJpbnB1dCI9PT1jfHwiYnV0dG9uIj09PWMpJiZiLnR5cGU9PT1hfX1mdW5jdGlvbiBvYShhKXtyZXR1cm4gaWEoZnVuY3Rpb24oYil7cmV0dXJuIGI9K2IsaWEoZnVuY3Rpb24oYyxkKXt2YXIgZSxmPWEoW10sYy5sZW5ndGgsYiksZz1mLmxlbmd0aDt3aGlsZShnLS0pY1tlPWZbZ11dJiYoY1tlXT0hKGRbZV09Y1tlXSkpfSl9KX1mdW5jdGlvbiBwYShhKXtyZXR1cm4gYSYmInVuZGVmaW5lZCIhPXR5cGVvZiBhLmdldEVsZW1lbnRzQnlUYWdOYW1lJiZhfWM9Z2Euc3VwcG9ydD17fSxmPWdhLmlzWE1MPWZ1bmN0aW9uKGEpe3ZhciBiPWEmJihhLm93bmVyRG9jdW1lbnR8fGEpLmRvY3VtZW50RWxlbWVudDtyZXR1cm4gYj8iSFRNTCIhPT1iLm5vZGVOYW1lOiExfSxtPWdhLnNldERvY3VtZW50PWZ1bmN0aW9uKGEpe3ZhciBiLGUsZz1hP2Eub3duZXJEb2N1bWVudHx8YTp2O3JldHVybiBnIT09biYmOT09PWcubm9kZVR5cGUmJmcuZG9jdW1lbnRFbGVtZW50PyhuPWcsbz1nLmRvY3VtZW50RWxlbWVudCxlPWcuZGVmYXVsdFZpZXcsZSYmZSE9PWUudG9wJiYoZS5hZGRFdmVudExpc3RlbmVyP2UuYWRkRXZlbnRMaXN0ZW5lcigidW5sb2FkIixlYSwhMSk6ZS5hdHRhY2hFdmVudCYmZS5hdHRhY2hFdmVudCgib251bmxvYWQiLGVhKSkscD0hZihnKSxjLmF0dHJpYnV0ZXM9amEoZnVuY3Rpb24oYSl7cmV0dXJuIGEuY2xhc3NOYW1lPSJpIiwhYS5nZXRBdHRyaWJ1dGUoImNsYXNzTmFtZSIpfSksYy5nZXRFbGVtZW50c0J5VGFnTmFtZT1qYShmdW5jdGlvbihhKXtyZXR1cm4gYS5hcHBlbmRDaGlsZChnLmNyZWF0ZUNvbW1lbnQoIiIpKSwhYS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpLmxlbmd0aH0pLGMuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZT0kLnRlc3QoZy5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKSxjLmdldEJ5SWQ9amEoZnVuY3Rpb24oYSl7cmV0dXJuIG8uYXBwZW5kQ2hpbGQoYSkuaWQ9dSwhZy5nZXRFbGVtZW50c0J5TmFtZXx8IWcuZ2V0RWxlbWVudHNCeU5hbWUodSkubGVuZ3RofSksYy5nZXRCeUlkPyhkLmZpbmQuSUQ9ZnVuY3Rpb24oYSxiKXtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGIuZ2V0RWxlbWVudEJ5SWQmJnApe3ZhciBjPWIuZ2V0RWxlbWVudEJ5SWQoYSk7cmV0dXJuIGMmJmMucGFyZW50Tm9kZT9bY106W119fSxkLmZpbHRlci5JRD1mdW5jdGlvbihhKXt2YXIgYj1hLnJlcGxhY2UoY2EsZGEpO3JldHVybiBmdW5jdGlvbihhKXtyZXR1cm4gYS5nZXRBdHRyaWJ1dGUoImlkIik9PT1ifX0pOihkZWxldGUgZC5maW5kLklELGQuZmlsdGVyLklEPWZ1bmN0aW9uKGEpe3ZhciBiPWEucmVwbGFjZShjYSxkYSk7cmV0dXJuIGZ1bmN0aW9uKGEpe3ZhciBjPSJ1bmRlZmluZWQiIT10eXBlb2YgYS5nZXRBdHRyaWJ1dGVOb2RlJiZhLmdldEF0dHJpYnV0ZU5vZGUoImlkIik7cmV0dXJuIGMmJmMudmFsdWU9PT1ifX0pLGQuZmluZC5UQUc9Yy5nZXRFbGVtZW50c0J5VGFnTmFtZT9mdW5jdGlvbihhLGIpe3JldHVybiJ1bmRlZmluZWQiIT10eXBlb2YgYi5nZXRFbGVtZW50c0J5VGFnTmFtZT9iLmdldEVsZW1lbnRzQnlUYWdOYW1lKGEpOmMucXNhP2IucXVlcnlTZWxlY3RvckFsbChhKTp2b2lkIDB9OmZ1bmN0aW9uKGEsYil7dmFyIGMsZD1bXSxlPTAsZj1iLmdldEVsZW1lbnRzQnlUYWdOYW1lKGEpO2lmKCIqIj09PWEpe3doaWxlKGM9ZltlKytdKTE9PT1jLm5vZGVUeXBlJiZkLnB1c2goYyk7cmV0dXJuIGR9cmV0dXJuIGZ9LGQuZmluZC5DTEFTUz1jLmdldEVsZW1lbnRzQnlDbGFzc05hbWUmJmZ1bmN0aW9uKGEsYil7cmV0dXJuIHA/Yi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGEpOnZvaWQgMH0scj1bXSxxPVtdLChjLnFzYT0kLnRlc3QoZy5xdWVyeVNlbGVjdG9yQWxsKSkmJihqYShmdW5jdGlvbihhKXtvLmFwcGVuZENoaWxkKGEpLmlubmVySFRNTD0iPGEgaWQ9JyIrdSsiJz48L2E+PHNlbGVjdCBpZD0nIit1KyItXGZdJyBtc2FsbG93Y2FwdHVyZT0nJz48b3B0aW9uIHNlbGVjdGVkPScnPjwvb3B0aW9uPjwvc2VsZWN0PiIsYS5xdWVyeVNlbGVjdG9yQWxsKCJbbXNhbGxvd2NhcHR1cmVePScnXSIpLmxlbmd0aCYmcS5wdXNoKCJbKl4kXT0iK0wrIiooPzonJ3xcIlwiKSIpLGEucXVlcnlTZWxlY3RvckFsbCgiW3NlbGVjdGVkXSIpLmxlbmd0aHx8cS5wdXNoKCJcXFsiK0wrIiooPzp2YWx1ZXwiK0srIikiKSxhLnF1ZXJ5U2VsZWN0b3JBbGwoIltpZH49Iit1KyItXSIpLmxlbmd0aHx8cS5wdXNoKCJ+PSIpLGEucXVlcnlTZWxlY3RvckFsbCgiOmNoZWNrZWQiKS5sZW5ndGh8fHEucHVzaCgiOmNoZWNrZWQiKSxhLnF1ZXJ5U2VsZWN0b3JBbGwoImEjIit1KyIrKiIpLmxlbmd0aHx8cS5wdXNoKCIuIy4rWyt+XSIpfSksamEoZnVuY3Rpb24oYSl7dmFyIGI9Zy5jcmVhdGVFbGVtZW50KCJpbnB1dCIpO2Iuc2V0QXR0cmlidXRlKCJ0eXBlIiwiaGlkZGVuIiksYS5hcHBlbmRDaGlsZChiKS5zZXRBdHRyaWJ1dGUoIm5hbWUiLCJEIiksYS5xdWVyeVNlbGVjdG9yQWxsKCJbbmFtZT1kXSIpLmxlbmd0aCYmcS5wdXNoKCJuYW1lIitMKyIqWypeJHwhfl0/PSIpLGEucXVlcnlTZWxlY3RvckFsbCgiOmVuYWJsZWQiKS5sZW5ndGh8fHEucHVzaCgiOmVuYWJsZWQiLCI6ZGlzYWJsZWQiKSxhLnF1ZXJ5U2VsZWN0b3JBbGwoIiosOngiKSxxLnB1c2goIiwuKjoiKX0pKSwoYy5tYXRjaGVzU2VsZWN0b3I9JC50ZXN0KHM9by5tYXRjaGVzfHxvLndlYmtpdE1hdGNoZXNTZWxlY3Rvcnx8by5tb3pNYXRjaGVzU2VsZWN0b3J8fG8ub01hdGNoZXNTZWxlY3Rvcnx8by5tc01hdGNoZXNTZWxlY3RvcikpJiZqYShmdW5jdGlvbihhKXtjLmRpc2Nvbm5lY3RlZE1hdGNoPXMuY2FsbChhLCJkaXYiKSxzLmNhbGwoYSwiW3MhPScnXTp4Iiksci5wdXNoKCIhPSIsUCl9KSxxPXEubGVuZ3RoJiZuZXcgUmVnRXhwKHEuam9pbigifCIpKSxyPXIubGVuZ3RoJiZuZXcgUmVnRXhwKHIuam9pbigifCIpKSxiPSQudGVzdChvLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKSx0PWJ8fCQudGVzdChvLmNvbnRhaW5zKT9mdW5jdGlvbihhLGIpe3ZhciBjPTk9PT1hLm5vZGVUeXBlP2EuZG9jdW1lbnRFbGVtZW50OmEsZD1iJiZiLnBhcmVudE5vZGU7cmV0dXJuIGE9PT1kfHwhKCFkfHwxIT09ZC5ub2RlVHlwZXx8IShjLmNvbnRhaW5zP2MuY29udGFpbnMoZCk6YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiYmMTYmYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihkKSkpfTpmdW5jdGlvbihhLGIpe2lmKGIpd2hpbGUoYj1iLnBhcmVudE5vZGUpaWYoYj09PWEpcmV0dXJuITA7cmV0dXJuITF9LEI9Yj9mdW5jdGlvbihhLGIpe2lmKGE9PT1iKXJldHVybiBsPSEwLDA7dmFyIGQ9IWEuY29tcGFyZURvY3VtZW50UG9zaXRpb24tIWIuY29tcGFyZURvY3VtZW50UG9zaXRpb247cmV0dXJuIGQ/ZDooZD0oYS5vd25lckRvY3VtZW50fHxhKT09PShiLm93bmVyRG9jdW1lbnR8fGIpP2EuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYik6MSwxJmR8fCFjLnNvcnREZXRhY2hlZCYmYi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihhKT09PWQ/YT09PWd8fGEub3duZXJEb2N1bWVudD09PXYmJnQodixhKT8tMTpiPT09Z3x8Yi5vd25lckRvY3VtZW50PT09diYmdCh2LGIpPzE6az9KKGssYSktSihrLGIpOjA6NCZkPy0xOjEpfTpmdW5jdGlvbihhLGIpe2lmKGE9PT1iKXJldHVybiBsPSEwLDA7dmFyIGMsZD0wLGU9YS5wYXJlbnROb2RlLGY9Yi5wYXJlbnROb2RlLGg9W2FdLGk9W2JdO2lmKCFlfHwhZilyZXR1cm4gYT09PWc/LTE6Yj09PWc/MTplPy0xOmY/MTprP0ooayxhKS1KKGssYik6MDtpZihlPT09ZilyZXR1cm4gbGEoYSxiKTtjPWE7d2hpbGUoYz1jLnBhcmVudE5vZGUpaC51bnNoaWZ0KGMpO2M9Yjt3aGlsZShjPWMucGFyZW50Tm9kZSlpLnVuc2hpZnQoYyk7d2hpbGUoaFtkXT09PWlbZF0pZCsrO3JldHVybiBkP2xhKGhbZF0saVtkXSk6aFtkXT09PXY/LTE6aVtkXT09PXY/MTowfSxnKTpufSxnYS5tYXRjaGVzPWZ1bmN0aW9uKGEsYil7cmV0dXJuIGdhKGEsbnVsbCxudWxsLGIpfSxnYS5tYXRjaGVzU2VsZWN0b3I9ZnVuY3Rpb24oYSxiKXtpZigoYS5vd25lckRvY3VtZW50fHxhKSE9PW4mJm0oYSksYj1iLnJlcGxhY2UoVSwiPSckMSddIiksISghYy5tYXRjaGVzU2VsZWN0b3J8fCFwfHxyJiZyLnRlc3QoYil8fHEmJnEudGVzdChiKSkpdHJ5e3ZhciBkPXMuY2FsbChhLGIpO2lmKGR8fGMuZGlzY29ubmVjdGVkTWF0Y2h8fGEuZG9jdW1lbnQmJjExIT09YS5kb2N1bWVudC5ub2RlVHlwZSlyZXR1cm4gZH1jYXRjaChlKXt9cmV0dXJuIGdhKGIsbixudWxsLFthXSkubGVuZ3RoPjB9LGdhLmNvbnRhaW5zPWZ1bmN0aW9uKGEsYil7cmV0dXJuKGEub3duZXJEb2N1bWVudHx8YSkhPT1uJiZtKGEpLHQoYSxiKX0sZ2EuYXR0cj1mdW5jdGlvbihhLGIpeyhhLm93bmVyRG9jdW1lbnR8fGEpIT09biYmbShhKTt2YXIgZT1kLmF0dHJIYW5kbGVbYi50b0xvd2VyQ2FzZSgpXSxmPWUmJkQuY2FsbChkLmF0dHJIYW5kbGUsYi50b0xvd2VyQ2FzZSgpKT9lKGEsYiwhcCk6dm9pZCAwO3JldHVybiB2b2lkIDAhPT1mP2Y6Yy5hdHRyaWJ1dGVzfHwhcD9hLmdldEF0dHJpYnV0ZShiKTooZj1hLmdldEF0dHJpYnV0ZU5vZGUoYikpJiZmLnNwZWNpZmllZD9mLnZhbHVlOm51bGx9LGdhLmVycm9yPWZ1bmN0aW9uKGEpe3Rocm93IG5ldyBFcnJvcigiU3ludGF4IGVycm9yLCB1bnJlY29nbml6ZWQgZXhwcmVzc2lvbjogIithKX0sZ2EudW5pcXVlU29ydD1mdW5jdGlvbihhKXt2YXIgYixkPVtdLGU9MCxmPTA7aWYobD0hYy5kZXRlY3REdXBsaWNhdGVzLGs9IWMuc29ydFN0YWJsZSYmYS5zbGljZSgwKSxhLnNvcnQoQiksbCl7d2hpbGUoYj1hW2YrK10pYj09PWFbZl0mJihlPWQucHVzaChmKSk7d2hpbGUoZS0tKWEuc3BsaWNlKGRbZV0sMSl9cmV0dXJuIGs9bnVsbCxhfSxlPWdhLmdldFRleHQ9ZnVuY3Rpb24oYSl7dmFyIGIsYz0iIixkPTAsZj1hLm5vZGVUeXBlO2lmKGYpe2lmKDE9PT1mfHw5PT09Znx8MTE9PT1mKXtpZigic3RyaW5nIj09dHlwZW9mIGEudGV4dENvbnRlbnQpcmV0dXJuIGEudGV4dENvbnRlbnQ7Zm9yKGE9YS5maXJzdENoaWxkO2E7YT1hLm5leHRTaWJsaW5nKWMrPWUoYSl9ZWxzZSBpZigzPT09Znx8ND09PWYpcmV0dXJuIGEubm9kZVZhbHVlfWVsc2Ugd2hpbGUoYj1hW2QrK10pYys9ZShiKTtyZXR1cm4gY30sZD1nYS5zZWxlY3RvcnM9e2NhY2hlTGVuZ3RoOjUwLGNyZWF0ZVBzZXVkbzppYSxtYXRjaDpYLGF0dHJIYW5kbGU6e30sZmluZDp7fSxyZWxhdGl2ZTp7Ij4iOntkaXI6InBhcmVudE5vZGUiLGZpcnN0OiEwfSwiICI6e2RpcjoicGFyZW50Tm9kZSJ9LCIrIjp7ZGlyOiJwcmV2aW91c1NpYmxpbmciLGZpcnN0OiEwfSwifiI6e2RpcjoicHJldmlvdXNTaWJsaW5nIn19LHByZUZpbHRlcjp7QVRUUjpmdW5jdGlvbihhKXtyZXR1cm4gYVsxXT1hWzFdLnJlcGxhY2UoY2EsZGEpLGFbM109KGFbM118fGFbNF18fGFbNV18fCIiKS5yZXBsYWNlKGNhLGRhKSwifj0iPT09YVsyXSYmKGFbM109IiAiK2FbM10rIiAiKSxhLnNsaWNlKDAsNCl9LENISUxEOmZ1bmN0aW9uKGEpe3JldHVybiBhWzFdPWFbMV0udG9Mb3dlckNhc2UoKSwibnRoIj09PWFbMV0uc2xpY2UoMCwzKT8oYVszXXx8Z2EuZXJyb3IoYVswXSksYVs0XT0rKGFbNF0/YVs1XSsoYVs2XXx8MSk6MiooImV2ZW4iPT09YVszXXx8Im9kZCI9PT1hWzNdKSksYVs1XT0rKGFbN10rYVs4XXx8Im9kZCI9PT1hWzNdKSk6YVszXSYmZ2EuZXJyb3IoYVswXSksYX0sUFNFVURPOmZ1bmN0aW9uKGEpe3ZhciBiLGM9IWFbNl0mJmFbMl07cmV0dXJuIFguQ0hJTEQudGVzdChhWzBdKT9udWxsOihhWzNdP2FbMl09YVs0XXx8YVs1XXx8IiI6YyYmVi50ZXN0KGMpJiYoYj1nKGMsITApKSYmKGI9Yy5pbmRleE9mKCIpIixjLmxlbmd0aC1iKS1jLmxlbmd0aCkmJihhWzBdPWFbMF0uc2xpY2UoMCxiKSxhWzJdPWMuc2xpY2UoMCxiKSksYS5zbGljZSgwLDMpKX19LGZpbHRlcjp7VEFHOmZ1bmN0aW9uKGEpe3ZhciBiPWEucmVwbGFjZShjYSxkYSkudG9Mb3dlckNhc2UoKTtyZXR1cm4iKiI9PT1hP2Z1bmN0aW9uKCl7cmV0dXJuITB9OmZ1bmN0aW9uKGEpe3JldHVybiBhLm5vZGVOYW1lJiZhLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk9PT1ifX0sQ0xBU1M6ZnVuY3Rpb24oYSl7dmFyIGI9eVthKyIgIl07cmV0dXJuIGJ8fChiPW5ldyBSZWdFeHAoIihefCIrTCsiKSIrYSsiKCIrTCsifCQpIikpJiZ5KGEsZnVuY3Rpb24oYSl7cmV0dXJuIGIudGVzdCgic3RyaW5nIj09dHlwZW9mIGEuY2xhc3NOYW1lJiZhLmNsYXNzTmFtZXx8InVuZGVmaW5lZCIhPXR5cGVvZiBhLmdldEF0dHJpYnV0ZSYmYS5nZXRBdHRyaWJ1dGUoImNsYXNzIil8fCIiKX0pfSxBVFRSOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gZnVuY3Rpb24oZCl7dmFyIGU9Z2EuYXR0cihkLGEpO3JldHVybiBudWxsPT1lPyIhPSI9PT1iOmI/KGUrPSIiLCI9Ij09PWI/ZT09PWM6IiE9Ij09PWI/ZSE9PWM6Il49Ij09PWI/YyYmMD09PWUuaW5kZXhPZihjKToiKj0iPT09Yj9jJiZlLmluZGV4T2YoYyk+LTE6IiQ9Ij09PWI/YyYmZS5zbGljZSgtYy5sZW5ndGgpPT09Yzoifj0iPT09Yj8oIiAiK2UucmVwbGFjZShRLCIgIikrIiAiKS5pbmRleE9mKGMpPi0xOiJ8PSI9PT1iP2U9PT1jfHxlLnNsaWNlKDAsYy5sZW5ndGgrMSk9PT1jKyItIjohMSk6ITB9fSxDSElMRDpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBmPSJudGgiIT09YS5zbGljZSgwLDMpLGc9Imxhc3QiIT09YS5zbGljZSgtNCksaD0ib2YtdHlwZSI9PT1iO3JldHVybiAxPT09ZCYmMD09PWU/ZnVuY3Rpb24oYSl7cmV0dXJuISFhLnBhcmVudE5vZGV9OmZ1bmN0aW9uKGIsYyxpKXt2YXIgaixrLGwsbSxuLG8scD1mIT09Zz8ibmV4dFNpYmxpbmciOiJwcmV2aW91c1NpYmxpbmciLHE9Yi5wYXJlbnROb2RlLHI9aCYmYi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLHM9IWkmJiFoO2lmKHEpe2lmKGYpe3doaWxlKHApe2w9Yjt3aGlsZShsPWxbcF0paWYoaD9sLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk9PT1yOjE9PT1sLm5vZGVUeXBlKXJldHVybiExO289cD0ib25seSI9PT1hJiYhbyYmIm5leHRTaWJsaW5nIn1yZXR1cm4hMH1pZihvPVtnP3EuZmlyc3RDaGlsZDpxLmxhc3RDaGlsZF0sZyYmcyl7az1xW3VdfHwocVt1XT17fSksaj1rW2FdfHxbXSxuPWpbMF09PT13JiZqWzFdLG09alswXT09PXcmJmpbMl0sbD1uJiZxLmNoaWxkTm9kZXNbbl07d2hpbGUobD0rK24mJmwmJmxbcF18fChtPW49MCl8fG8ucG9wKCkpaWYoMT09PWwubm9kZVR5cGUmJisrbSYmbD09PWIpe2tbYV09W3csbixtXTticmVha319ZWxzZSBpZihzJiYoaj0oYlt1XXx8KGJbdV09e30pKVthXSkmJmpbMF09PT13KW09alsxXTtlbHNlIHdoaWxlKGw9KytuJiZsJiZsW3BdfHwobT1uPTApfHxvLnBvcCgpKWlmKChoP2wubm9kZU5hbWUudG9Mb3dlckNhc2UoKT09PXI6MT09PWwubm9kZVR5cGUpJiYrK20mJihzJiYoKGxbdV18fChsW3VdPXt9KSlbYV09W3csbV0pLGw9PT1iKSlicmVhaztyZXR1cm4gbS09ZSxtPT09ZHx8bSVkPT09MCYmbS9kPj0wfX19LFBTRVVETzpmdW5jdGlvbihhLGIpe3ZhciBjLGU9ZC5wc2V1ZG9zW2FdfHxkLnNldEZpbHRlcnNbYS50b0xvd2VyQ2FzZSgpXXx8Z2EuZXJyb3IoInVuc3VwcG9ydGVkIHBzZXVkbzogIithKTtyZXR1cm4gZVt1XT9lKGIpOmUubGVuZ3RoPjE/KGM9W2EsYSwiIixiXSxkLnNldEZpbHRlcnMuaGFzT3duUHJvcGVydHkoYS50b0xvd2VyQ2FzZSgpKT9pYShmdW5jdGlvbihhLGMpe3ZhciBkLGY9ZShhLGIpLGc9Zi5sZW5ndGg7d2hpbGUoZy0tKWQ9SihhLGZbZ10pLGFbZF09IShjW2RdPWZbZ10pfSk6ZnVuY3Rpb24oYSl7cmV0dXJuIGUoYSwwLGMpfSk6ZX19LHBzZXVkb3M6e25vdDppYShmdW5jdGlvbihhKXt2YXIgYj1bXSxjPVtdLGQ9aChhLnJlcGxhY2UoUiwiJDEiKSk7cmV0dXJuIGRbdV0/aWEoZnVuY3Rpb24oYSxiLGMsZSl7dmFyIGYsZz1kKGEsbnVsbCxlLFtdKSxoPWEubGVuZ3RoO3doaWxlKGgtLSkoZj1nW2hdKSYmKGFbaF09IShiW2hdPWYpKX0pOmZ1bmN0aW9uKGEsZSxmKXtyZXR1cm4gYlswXT1hLGQoYixudWxsLGYsYyksYlswXT1udWxsLCFjLnBvcCgpfX0pLGhhczppYShmdW5jdGlvbihhKXtyZXR1cm4gZnVuY3Rpb24oYil7cmV0dXJuIGdhKGEsYikubGVuZ3RoPjB9fSksY29udGFpbnM6aWEoZnVuY3Rpb24oYSl7cmV0dXJuIGE9YS5yZXBsYWNlKGNhLGRhKSxmdW5jdGlvbihiKXtyZXR1cm4oYi50ZXh0Q29udGVudHx8Yi5pbm5lclRleHR8fGUoYikpLmluZGV4T2YoYSk+LTF9fSksbGFuZzppYShmdW5jdGlvbihhKXtyZXR1cm4gVy50ZXN0KGF8fCIiKXx8Z2EuZXJyb3IoInVuc3VwcG9ydGVkIGxhbmc6ICIrYSksYT1hLnJlcGxhY2UoY2EsZGEpLnRvTG93ZXJDYXNlKCksZnVuY3Rpb24oYil7dmFyIGM7ZG8gaWYoYz1wP2IubGFuZzpiLmdldEF0dHJpYnV0ZSgieG1sOmxhbmciKXx8Yi5nZXRBdHRyaWJ1dGUoImxhbmciKSlyZXR1cm4gYz1jLnRvTG93ZXJDYXNlKCksYz09PWF8fDA9PT1jLmluZGV4T2YoYSsiLSIpO3doaWxlKChiPWIucGFyZW50Tm9kZSkmJjE9PT1iLm5vZGVUeXBlKTtyZXR1cm4hMX19KSx0YXJnZXQ6ZnVuY3Rpb24oYil7dmFyIGM9YS5sb2NhdGlvbiYmYS5sb2NhdGlvbi5oYXNoO3JldHVybiBjJiZjLnNsaWNlKDEpPT09Yi5pZH0scm9vdDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PW99LGZvY3VzOmZ1bmN0aW9uKGEpe3JldHVybiBhPT09bi5hY3RpdmVFbGVtZW50JiYoIW4uaGFzRm9jdXN8fG4uaGFzRm9jdXMoKSkmJiEhKGEudHlwZXx8YS5ocmVmfHx+YS50YWJJbmRleCl9LGVuYWJsZWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuZGlzYWJsZWQ9PT0hMX0sZGlzYWJsZWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuZGlzYWJsZWQ9PT0hMH0sY2hlY2tlZDpmdW5jdGlvbihhKXt2YXIgYj1hLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuImlucHV0Ij09PWImJiEhYS5jaGVja2VkfHwib3B0aW9uIj09PWImJiEhYS5zZWxlY3RlZH0sc2VsZWN0ZWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGEucGFyZW50Tm9kZSYmYS5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXgsYS5zZWxlY3RlZD09PSEwfSxlbXB0eTpmdW5jdGlvbihhKXtmb3IoYT1hLmZpcnN0Q2hpbGQ7YTthPWEubmV4dFNpYmxpbmcpaWYoYS5ub2RlVHlwZTw2KXJldHVybiExO3JldHVybiEwfSxwYXJlbnQ6ZnVuY3Rpb24oYSl7cmV0dXJuIWQucHNldWRvcy5lbXB0eShhKX0saGVhZGVyOmZ1bmN0aW9uKGEpe3JldHVybiBaLnRlc3QoYS5ub2RlTmFtZSl9LGlucHV0OmZ1bmN0aW9uKGEpe3JldHVybiBZLnRlc3QoYS5ub2RlTmFtZSl9LGJ1dHRvbjpmdW5jdGlvbihhKXt2YXIgYj1hLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuImlucHV0Ij09PWImJiJidXR0b24iPT09YS50eXBlfHwiYnV0dG9uIj09PWJ9LHRleHQ6ZnVuY3Rpb24oYSl7dmFyIGI7cmV0dXJuImlucHV0Ij09PWEubm9kZU5hbWUudG9Mb3dlckNhc2UoKSYmInRleHQiPT09YS50eXBlJiYobnVsbD09KGI9YS5nZXRBdHRyaWJ1dGUoInR5cGUiKSl8fCJ0ZXh0Ij09PWIudG9Mb3dlckNhc2UoKSl9LGZpcnN0Om9hKGZ1bmN0aW9uKCl7cmV0dXJuWzBdfSksbGFzdDpvYShmdW5jdGlvbihhLGIpe3JldHVybltiLTFdfSksZXE6b2EoZnVuY3Rpb24oYSxiLGMpe3JldHVyblswPmM/YytiOmNdfSksZXZlbjpvYShmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz0wO2I+YztjKz0yKWEucHVzaChjKTtyZXR1cm4gYX0pLG9kZDpvYShmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz0xO2I+YztjKz0yKWEucHVzaChjKTtyZXR1cm4gYX0pLGx0Om9hKGZ1bmN0aW9uKGEsYixjKXtmb3IodmFyIGQ9MD5jP2MrYjpjOy0tZD49MDspYS5wdXNoKGQpO3JldHVybiBhfSksZ3Q6b2EoZnVuY3Rpb24oYSxiLGMpe2Zvcih2YXIgZD0wPmM/YytiOmM7KytkPGI7KWEucHVzaChkKTtyZXR1cm4gYX0pfX0sZC5wc2V1ZG9zLm50aD1kLnBzZXVkb3MuZXE7Zm9yKGIgaW57cmFkaW86ITAsY2hlY2tib3g6ITAsZmlsZTohMCxwYXNzd29yZDohMCxpbWFnZTohMH0pZC5wc2V1ZG9zW2JdPW1hKGIpO2ZvcihiIGlue3N1Ym1pdDohMCxyZXNldDohMH0pZC5wc2V1ZG9zW2JdPW5hKGIpO2Z1bmN0aW9uIHFhKCl7fXFhLnByb3RvdHlwZT1kLmZpbHRlcnM9ZC5wc2V1ZG9zLGQuc2V0RmlsdGVycz1uZXcgcWEsZz1nYS50b2tlbml6ZT1mdW5jdGlvbihhLGIpe3ZhciBjLGUsZixnLGgsaSxqLGs9elthKyIgIl07aWYoaylyZXR1cm4gYj8wOmsuc2xpY2UoMCk7aD1hLGk9W10saj1kLnByZUZpbHRlcjt3aGlsZShoKXsoIWN8fChlPVMuZXhlYyhoKSkpJiYoZSYmKGg9aC5zbGljZShlWzBdLmxlbmd0aCl8fGgpLGkucHVzaChmPVtdKSksYz0hMSwoZT1ULmV4ZWMoaCkpJiYoYz1lLnNoaWZ0KCksZi5wdXNoKHt2YWx1ZTpjLHR5cGU6ZVswXS5yZXBsYWNlKFIsIiAiKX0pLGg9aC5zbGljZShjLmxlbmd0aCkpO2ZvcihnIGluIGQuZmlsdGVyKSEoZT1YW2ddLmV4ZWMoaCkpfHxqW2ddJiYhKGU9altnXShlKSl8fChjPWUuc2hpZnQoKSxmLnB1c2goe3ZhbHVlOmMsdHlwZTpnLG1hdGNoZXM6ZX0pLGg9aC5zbGljZShjLmxlbmd0aCkpO2lmKCFjKWJyZWFrfXJldHVybiBiP2gubGVuZ3RoOmg/Z2EuZXJyb3IoYSk6eihhLGkpLnNsaWNlKDApfTtmdW5jdGlvbiByYShhKXtmb3IodmFyIGI9MCxjPWEubGVuZ3RoLGQ9IiI7Yz5iO2IrKylkKz1hW2JdLnZhbHVlO3JldHVybiBkfWZ1bmN0aW9uIHNhKGEsYixjKXt2YXIgZD1iLmRpcixlPWMmJiJwYXJlbnROb2RlIj09PWQsZj14Kys7cmV0dXJuIGIuZmlyc3Q/ZnVuY3Rpb24oYixjLGYpe3doaWxlKGI9YltkXSlpZigxPT09Yi5ub2RlVHlwZXx8ZSlyZXR1cm4gYShiLGMsZil9OmZ1bmN0aW9uKGIsYyxnKXt2YXIgaCxpLGo9W3csZl07aWYoZyl7d2hpbGUoYj1iW2RdKWlmKCgxPT09Yi5ub2RlVHlwZXx8ZSkmJmEoYixjLGcpKXJldHVybiEwfWVsc2Ugd2hpbGUoYj1iW2RdKWlmKDE9PT1iLm5vZGVUeXBlfHxlKXtpZihpPWJbdV18fChiW3VdPXt9KSwoaD1pW2RdKSYmaFswXT09PXcmJmhbMV09PT1mKXJldHVybiBqWzJdPWhbMl07aWYoaVtkXT1qLGpbMl09YShiLGMsZykpcmV0dXJuITB9fX1mdW5jdGlvbiB0YShhKXtyZXR1cm4gYS5sZW5ndGg+MT9mdW5jdGlvbihiLGMsZCl7dmFyIGU9YS5sZW5ndGg7d2hpbGUoZS0tKWlmKCFhW2VdKGIsYyxkKSlyZXR1cm4hMTtyZXR1cm4hMH06YVswXX1mdW5jdGlvbiB1YShhLGIsYyl7Zm9yKHZhciBkPTAsZT1iLmxlbmd0aDtlPmQ7ZCsrKWdhKGEsYltkXSxjKTtyZXR1cm4gY31mdW5jdGlvbiB2YShhLGIsYyxkLGUpe2Zvcih2YXIgZixnPVtdLGg9MCxpPWEubGVuZ3RoLGo9bnVsbCE9YjtpPmg7aCsrKShmPWFbaF0pJiYoIWN8fGMoZixkLGUpKSYmKGcucHVzaChmKSxqJiZiLnB1c2goaCkpO3JldHVybiBnfWZ1bmN0aW9uIHdhKGEsYixjLGQsZSxmKXtyZXR1cm4gZCYmIWRbdV0mJihkPXdhKGQpKSxlJiYhZVt1XSYmKGU9d2EoZSxmKSksaWEoZnVuY3Rpb24oZixnLGgsaSl7dmFyIGosayxsLG09W10sbj1bXSxvPWcubGVuZ3RoLHA9Znx8dWEoYnx8IioiLGgubm9kZVR5cGU/W2hdOmgsW10pLHE9IWF8fCFmJiZiP3A6dmEocCxtLGEsaCxpKSxyPWM/ZXx8KGY/YTpvfHxkKT9bXTpnOnE7aWYoYyYmYyhxLHIsaCxpKSxkKXtqPXZhKHIsbiksZChqLFtdLGgsaSksaz1qLmxlbmd0aDt3aGlsZShrLS0pKGw9altrXSkmJihyW25ba11dPSEocVtuW2tdXT1sKSl9aWYoZil7aWYoZXx8YSl7aWYoZSl7aj1bXSxrPXIubGVuZ3RoO3doaWxlKGstLSkobD1yW2tdKSYmai5wdXNoKHFba109bCk7ZShudWxsLHI9W10saixpKX1rPXIubGVuZ3RoO3doaWxlKGstLSkobD1yW2tdKSYmKGo9ZT9KKGYsbCk6bVtrXSk+LTEmJihmW2pdPSEoZ1tqXT1sKSl9fWVsc2Ugcj12YShyPT09Zz9yLnNwbGljZShvLHIubGVuZ3RoKTpyKSxlP2UobnVsbCxnLHIsaSk6SC5hcHBseShnLHIpfSl9ZnVuY3Rpb24geGEoYSl7Zm9yKHZhciBiLGMsZSxmPWEubGVuZ3RoLGc9ZC5yZWxhdGl2ZVthWzBdLnR5cGVdLGg9Z3x8ZC5yZWxhdGl2ZVsiICJdLGk9Zz8xOjAsaz1zYShmdW5jdGlvbihhKXtyZXR1cm4gYT09PWJ9LGgsITApLGw9c2EoZnVuY3Rpb24oYSl7cmV0dXJuIEooYixhKT4tMX0saCwhMCksbT1bZnVuY3Rpb24oYSxjLGQpe3ZhciBlPSFnJiYoZHx8YyE9PWopfHwoKGI9Yykubm9kZVR5cGU/ayhhLGMsZCk6bChhLGMsZCkpO3JldHVybiBiPW51bGwsZX1dO2Y+aTtpKyspaWYoYz1kLnJlbGF0aXZlW2FbaV0udHlwZV0pbT1bc2EodGEobSksYyldO2Vsc2V7aWYoYz1kLmZpbHRlclthW2ldLnR5cGVdLmFwcGx5KG51bGwsYVtpXS5tYXRjaGVzKSxjW3VdKXtmb3IoZT0rK2k7Zj5lO2UrKylpZihkLnJlbGF0aXZlW2FbZV0udHlwZV0pYnJlYWs7cmV0dXJuIHdhKGk+MSYmdGEobSksaT4xJiZyYShhLnNsaWNlKDAsaS0xKS5jb25jYXQoe3ZhbHVlOiIgIj09PWFbaS0yXS50eXBlPyIqIjoiIn0pKS5yZXBsYWNlKFIsIiQxIiksYyxlPmkmJnhhKGEuc2xpY2UoaSxlKSksZj5lJiZ4YShhPWEuc2xpY2UoZSkpLGY+ZSYmcmEoYSkpfW0ucHVzaChjKX1yZXR1cm4gdGEobSl9ZnVuY3Rpb24geWEoYSxiKXt2YXIgYz1iLmxlbmd0aD4wLGU9YS5sZW5ndGg+MCxmPWZ1bmN0aW9uKGYsZyxoLGksayl7dmFyIGwsbSxvLHA9MCxxPSIwIixyPWYmJltdLHM9W10sdD1qLHU9Znx8ZSYmZC5maW5kLlRBRygiKiIsayksdj13Kz1udWxsPT10PzE6TWF0aC5yYW5kb20oKXx8LjEseD11Lmxlbmd0aDtmb3IoayYmKGo9ZyE9PW4mJmcpO3EhPT14JiZudWxsIT0obD11W3FdKTtxKyspe2lmKGUmJmwpe209MDt3aGlsZShvPWFbbSsrXSlpZihvKGwsZyxoKSl7aS5wdXNoKGwpO2JyZWFrfWsmJih3PXYpfWMmJigobD0hbyYmbCkmJnAtLSxmJiZyLnB1c2gobCkpfWlmKHArPXEsYyYmcSE9PXApe209MDt3aGlsZShvPWJbbSsrXSlvKHIscyxnLGgpO2lmKGYpe2lmKHA+MCl3aGlsZShxLS0pcltxXXx8c1txXXx8KHNbcV09Ri5jYWxsKGkpKTtzPXZhKHMpfUguYXBwbHkoaSxzKSxrJiYhZiYmcy5sZW5ndGg+MCYmcCtiLmxlbmd0aD4xJiZnYS51bmlxdWVTb3J0KGkpfXJldHVybiBrJiYodz12LGo9dCkscn07cmV0dXJuIGM/aWEoZik6Zn1yZXR1cm4gaD1nYS5jb21waWxlPWZ1bmN0aW9uKGEsYil7dmFyIGMsZD1bXSxlPVtdLGY9QVthKyIgIl07aWYoIWYpe2J8fChiPWcoYSkpLGM9Yi5sZW5ndGg7d2hpbGUoYy0tKWY9eGEoYltjXSksZlt1XT9kLnB1c2goZik6ZS5wdXNoKGYpO2Y9QShhLHlhKGUsZCkpLGYuc2VsZWN0b3I9YX1yZXR1cm4gZn0saT1nYS5zZWxlY3Q9ZnVuY3Rpb24oYSxiLGUsZil7dmFyIGksaixrLGwsbSxuPSJmdW5jdGlvbiI9PXR5cGVvZiBhJiZhLG89IWYmJmcoYT1uLnNlbGVjdG9yfHxhKTtpZihlPWV8fFtdLDE9PT1vLmxlbmd0aCl7aWYoaj1vWzBdPW9bMF0uc2xpY2UoMCksai5sZW5ndGg+MiYmIklEIj09PShrPWpbMF0pLnR5cGUmJmMuZ2V0QnlJZCYmOT09PWIubm9kZVR5cGUmJnAmJmQucmVsYXRpdmVbalsxXS50eXBlXSl7aWYoYj0oZC5maW5kLklEKGsubWF0Y2hlc1swXS5yZXBsYWNlKGNhLGRhKSxiKXx8W10pWzBdLCFiKXJldHVybiBlO24mJihiPWIucGFyZW50Tm9kZSksYT1hLnNsaWNlKGouc2hpZnQoKS52YWx1ZS5sZW5ndGgpfWk9WC5uZWVkc0NvbnRleHQudGVzdChhKT8wOmoubGVuZ3RoO3doaWxlKGktLSl7aWYoaz1qW2ldLGQucmVsYXRpdmVbbD1rLnR5cGVdKWJyZWFrO2lmKChtPWQuZmluZFtsXSkmJihmPW0oay5tYXRjaGVzWzBdLnJlcGxhY2UoY2EsZGEpLGFhLnRlc3QoalswXS50eXBlKSYmcGEoYi5wYXJlbnROb2RlKXx8YikpKXtpZihqLnNwbGljZShpLDEpLGE9Zi5sZW5ndGgmJnJhKGopLCFhKXJldHVybiBILmFwcGx5KGUsZiksZTticmVha319fXJldHVybihufHxoKGEsbykpKGYsYiwhcCxlLGFhLnRlc3QoYSkmJnBhKGIucGFyZW50Tm9kZSl8fGIpLGV9LGMuc29ydFN0YWJsZT11LnNwbGl0KCIiKS5zb3J0KEIpLmpvaW4oIiIpPT09dSxjLmRldGVjdER1cGxpY2F0ZXM9ISFsLG0oKSxjLnNvcnREZXRhY2hlZD1qYShmdW5jdGlvbihhKXtyZXR1cm4gMSZhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKG4uY3JlYXRlRWxlbWVudCgiZGl2IikpfSksamEoZnVuY3Rpb24oYSl7cmV0dXJuIGEuaW5uZXJIVE1MPSI8YSBocmVmPScjJz48L2E+IiwiIyI9PT1hLmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKCJocmVmIil9KXx8a2EoInR5cGV8aHJlZnxoZWlnaHR8d2lkdGgiLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gYz92b2lkIDA6YS5nZXRBdHRyaWJ1dGUoYiwidHlwZSI9PT1iLnRvTG93ZXJDYXNlKCk/MToyKX0pLGMuYXR0cmlidXRlcyYmamEoZnVuY3Rpb24oYSl7cmV0dXJuIGEuaW5uZXJIVE1MPSI8aW5wdXQvPiIsYS5maXJzdENoaWxkLnNldEF0dHJpYnV0ZSgidmFsdWUiLCIiKSwiIj09PWEuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoInZhbHVlIil9KXx8a2EoInZhbHVlIixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGN8fCJpbnB1dCIhPT1hLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk/dm9pZCAwOmEuZGVmYXVsdFZhbHVlfSksamEoZnVuY3Rpb24oYSl7cmV0dXJuIG51bGw9PWEuZ2V0QXR0cmlidXRlKCJkaXNhYmxlZCIpfSl8fGthKEssZnVuY3Rpb24oYSxiLGMpe3ZhciBkO3JldHVybiBjP3ZvaWQgMDphW2JdPT09ITA/Yi50b0xvd2VyQ2FzZSgpOihkPWEuZ2V0QXR0cmlidXRlTm9kZShiKSkmJmQuc3BlY2lmaWVkP2QudmFsdWU6bnVsbH0pLGdhfShhKTttLmZpbmQ9cyxtLmV4cHI9cy5zZWxlY3RvcnMsbS5leHByWyI6Il09bS5leHByLnBzZXVkb3MsbS51bmlxdWU9cy51bmlxdWVTb3J0LG0udGV4dD1zLmdldFRleHQsbS5pc1hNTERvYz1zLmlzWE1MLG0uY29udGFpbnM9cy5jb250YWluczt2YXIgdD1tLmV4cHIubWF0Y2gubmVlZHNDb250ZXh0LHU9L148KFx3KylccypcLz8+KD86PFwvXDE+fCkkLyx2PS9eLlteOiNcW1wuLF0qJC87ZnVuY3Rpb24gdyhhLGIsYyl7aWYobS5pc0Z1bmN0aW9uKGIpKXJldHVybiBtLmdyZXAoYSxmdW5jdGlvbihhLGQpe3JldHVybiEhYi5jYWxsKGEsZCxhKSE9PWN9KTtpZihiLm5vZGVUeXBlKXJldHVybiBtLmdyZXAoYSxmdW5jdGlvbihhKXtyZXR1cm4gYT09PWIhPT1jfSk7aWYoInN0cmluZyI9PXR5cGVvZiBiKXtpZih2LnRlc3QoYikpcmV0dXJuIG0uZmlsdGVyKGIsYSxjKTtiPW0uZmlsdGVyKGIsYSl9cmV0dXJuIG0uZ3JlcChhLGZ1bmN0aW9uKGEpe3JldHVybiBtLmluQXJyYXkoYSxiKT49MCE9PWN9KX1tLmZpbHRlcj1mdW5jdGlvbihhLGIsYyl7dmFyIGQ9YlswXTtyZXR1cm4gYyYmKGE9Ijpub3QoIithKyIpIiksMT09PWIubGVuZ3RoJiYxPT09ZC5ub2RlVHlwZT9tLmZpbmQubWF0Y2hlc1NlbGVjdG9yKGQsYSk/W2RdOltdOm0uZmluZC5tYXRjaGVzKGEsbS5ncmVwKGIsZnVuY3Rpb24oYSl7cmV0dXJuIDE9PT1hLm5vZGVUeXBlfSkpfSxtLmZuLmV4dGVuZCh7ZmluZDpmdW5jdGlvbihhKXt2YXIgYixjPVtdLGQ9dGhpcyxlPWQubGVuZ3RoO2lmKCJzdHJpbmciIT10eXBlb2YgYSlyZXR1cm4gdGhpcy5wdXNoU3RhY2sobShhKS5maWx0ZXIoZnVuY3Rpb24oKXtmb3IoYj0wO2U+YjtiKyspaWYobS5jb250YWlucyhkW2JdLHRoaXMpKXJldHVybiEwfSkpO2ZvcihiPTA7ZT5iO2IrKyltLmZpbmQoYSxkW2JdLGMpO3JldHVybiBjPXRoaXMucHVzaFN0YWNrKGU+MT9tLnVuaXF1ZShjKTpjKSxjLnNlbGVjdG9yPXRoaXMuc2VsZWN0b3I/dGhpcy5zZWxlY3RvcisiICIrYTphLGN9LGZpbHRlcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2sodyh0aGlzLGF8fFtdLCExKSl9LG5vdDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2sodyh0aGlzLGF8fFtdLCEwKSl9LGlzOmZ1bmN0aW9uKGEpe3JldHVybiEhdyh0aGlzLCJzdHJpbmciPT10eXBlb2YgYSYmdC50ZXN0KGEpP20oYSk6YXx8W10sITEpLmxlbmd0aH19KTt2YXIgeCx5PWEuZG9jdW1lbnQsej0vXig/OlxzKig8W1x3XFddKz4pW14+XSp8IyhbXHctXSopKSQvLEE9bS5mbi5pbml0PWZ1bmN0aW9uKGEsYil7dmFyIGMsZDtpZighYSlyZXR1cm4gdGhpcztpZigic3RyaW5nIj09dHlwZW9mIGEpe2lmKGM9IjwiPT09YS5jaGFyQXQoMCkmJiI+Ij09PWEuY2hhckF0KGEubGVuZ3RoLTEpJiZhLmxlbmd0aD49Mz9bbnVsbCxhLG51bGxdOnouZXhlYyhhKSwhY3x8IWNbMV0mJmIpcmV0dXJuIWJ8fGIuanF1ZXJ5PyhifHx4KS5maW5kKGEpOnRoaXMuY29uc3RydWN0b3IoYikuZmluZChhKTtpZihjWzFdKXtpZihiPWIgaW5zdGFuY2VvZiBtP2JbMF06YixtLm1lcmdlKHRoaXMsbS5wYXJzZUhUTUwoY1sxXSxiJiZiLm5vZGVUeXBlP2Iub3duZXJEb2N1bWVudHx8Yjp5LCEwKSksdS50ZXN0KGNbMV0pJiZtLmlzUGxhaW5PYmplY3QoYikpZm9yKGMgaW4gYiltLmlzRnVuY3Rpb24odGhpc1tjXSk/dGhpc1tjXShiW2NdKTp0aGlzLmF0dHIoYyxiW2NdKTtyZXR1cm4gdGhpc31pZihkPXkuZ2V0RWxlbWVudEJ5SWQoY1syXSksZCYmZC5wYXJlbnROb2RlKXtpZihkLmlkIT09Y1syXSlyZXR1cm4geC5maW5kKGEpO3RoaXMubGVuZ3RoPTEsdGhpc1swXT1kfXJldHVybiB0aGlzLmNvbnRleHQ9eSx0aGlzLnNlbGVjdG9yPWEsdGhpc31yZXR1cm4gYS5ub2RlVHlwZT8odGhpcy5jb250ZXh0PXRoaXNbMF09YSx0aGlzLmxlbmd0aD0xLHRoaXMpOm0uaXNGdW5jdGlvbihhKT8idW5kZWZpbmVkIiE9dHlwZW9mIHgucmVhZHk/eC5yZWFkeShhKTphKG0pOih2b2lkIDAhPT1hLnNlbGVjdG9yJiYodGhpcy5zZWxlY3Rvcj1hLnNlbGVjdG9yLHRoaXMuY29udGV4dD1hLmNvbnRleHQpLG0ubWFrZUFycmF5KGEsdGhpcykpfTtBLnByb3RvdHlwZT1tLmZuLHg9bSh5KTt2YXIgQj0vXig/OnBhcmVudHN8cHJldig/OlVudGlsfEFsbCkpLyxDPXtjaGlsZHJlbjohMCxjb250ZW50czohMCxuZXh0OiEwLHByZXY6ITB9O20uZXh0ZW5kKHtkaXI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPVtdLGU9YVtiXTt3aGlsZShlJiY5IT09ZS5ub2RlVHlwZSYmKHZvaWQgMD09PWN8fDEhPT1lLm5vZGVUeXBlfHwhbShlKS5pcyhjKSkpMT09PWUubm9kZVR5cGUmJmQucHVzaChlKSxlPWVbYl07cmV0dXJuIGR9LHNpYmxpbmc6ZnVuY3Rpb24oYSxiKXtmb3IodmFyIGM9W107YTthPWEubmV4dFNpYmxpbmcpMT09PWEubm9kZVR5cGUmJmEhPT1iJiZjLnB1c2goYSk7cmV0dXJuIGN9fSksbS5mbi5leHRlbmQoe2hhczpmdW5jdGlvbihhKXt2YXIgYixjPW0oYSx0aGlzKSxkPWMubGVuZ3RoO3JldHVybiB0aGlzLmZpbHRlcihmdW5jdGlvbigpe2ZvcihiPTA7ZD5iO2IrKylpZihtLmNvbnRhaW5zKHRoaXMsY1tiXSkpcmV0dXJuITB9KX0sY2xvc2VzdDpmdW5jdGlvbihhLGIpe2Zvcih2YXIgYyxkPTAsZT10aGlzLmxlbmd0aCxmPVtdLGc9dC50ZXN0KGEpfHwic3RyaW5nIiE9dHlwZW9mIGE/bShhLGJ8fHRoaXMuY29udGV4dCk6MDtlPmQ7ZCsrKWZvcihjPXRoaXNbZF07YyYmYyE9PWI7Yz1jLnBhcmVudE5vZGUpaWYoYy5ub2RlVHlwZTwxMSYmKGc/Zy5pbmRleChjKT4tMToxPT09Yy5ub2RlVHlwZSYmbS5maW5kLm1hdGNoZXNTZWxlY3RvcihjLGEpKSl7Zi5wdXNoKGMpO2JyZWFrfXJldHVybiB0aGlzLnB1c2hTdGFjayhmLmxlbmd0aD4xP20udW5pcXVlKGYpOmYpfSxpbmRleDpmdW5jdGlvbihhKXtyZXR1cm4gYT8ic3RyaW5nIj09dHlwZW9mIGE/bS5pbkFycmF5KHRoaXNbMF0sbShhKSk6bS5pbkFycmF5KGEuanF1ZXJ5P2FbMF06YSx0aGlzKTp0aGlzWzBdJiZ0aGlzWzBdLnBhcmVudE5vZGU/dGhpcy5maXJzdCgpLnByZXZBbGwoKS5sZW5ndGg6LTF9LGFkZDpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnB1c2hTdGFjayhtLnVuaXF1ZShtLm1lcmdlKHRoaXMuZ2V0KCksbShhLGIpKSkpfSxhZGRCYWNrOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmFkZChudWxsPT1hP3RoaXMucHJldk9iamVjdDp0aGlzLnByZXZPYmplY3QuZmlsdGVyKGEpKX19KTtmdW5jdGlvbiBEKGEsYil7ZG8gYT1hW2JdO3doaWxlKGEmJjEhPT1hLm5vZGVUeXBlKTtyZXR1cm4gYX1tLmVhY2goe3BhcmVudDpmdW5jdGlvbihhKXt2YXIgYj1hLnBhcmVudE5vZGU7cmV0dXJuIGImJjExIT09Yi5ub2RlVHlwZT9iOm51bGx9LHBhcmVudHM6ZnVuY3Rpb24oYSl7cmV0dXJuIG0uZGlyKGEsInBhcmVudE5vZGUiKX0scGFyZW50c1VudGlsOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbS5kaXIoYSwicGFyZW50Tm9kZSIsYyl9LG5leHQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEQoYSwibmV4dFNpYmxpbmciKX0scHJldjpmdW5jdGlvbihhKXtyZXR1cm4gRChhLCJwcmV2aW91c1NpYmxpbmciKX0sbmV4dEFsbDpmdW5jdGlvbihhKXtyZXR1cm4gbS5kaXIoYSwibmV4dFNpYmxpbmciKX0scHJldkFsbDpmdW5jdGlvbihhKXtyZXR1cm4gbS5kaXIoYSwicHJldmlvdXNTaWJsaW5nIil9LG5leHRVbnRpbDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG0uZGlyKGEsIm5leHRTaWJsaW5nIixjKX0scHJldlVudGlsOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbS5kaXIoYSwicHJldmlvdXNTaWJsaW5nIixjKX0sc2libGluZ3M6ZnVuY3Rpb24oYSl7cmV0dXJuIG0uc2libGluZygoYS5wYXJlbnROb2RlfHx7fSkuZmlyc3RDaGlsZCxhKX0sY2hpbGRyZW46ZnVuY3Rpb24oYSl7cmV0dXJuIG0uc2libGluZyhhLmZpcnN0Q2hpbGQpfSxjb250ZW50czpmdW5jdGlvbihhKXtyZXR1cm4gbS5ub2RlTmFtZShhLCJpZnJhbWUiKT9hLmNvbnRlbnREb2N1bWVudHx8YS5jb250ZW50V2luZG93LmRvY3VtZW50Om0ubWVyZ2UoW10sYS5jaGlsZE5vZGVzKX19LGZ1bmN0aW9uKGEsYil7bS5mblthXT1mdW5jdGlvbihjLGQpe3ZhciBlPW0ubWFwKHRoaXMsYixjKTtyZXR1cm4iVW50aWwiIT09YS5zbGljZSgtNSkmJihkPWMpLGQmJiJzdHJpbmciPT10eXBlb2YgZCYmKGU9bS5maWx0ZXIoZCxlKSksdGhpcy5sZW5ndGg+MSYmKENbYV18fChlPW0udW5pcXVlKGUpKSxCLnRlc3QoYSkmJihlPWUucmV2ZXJzZSgpKSksdGhpcy5wdXNoU3RhY2soZSl9fSk7dmFyIEU9L1xTKy9nLEY9e307ZnVuY3Rpb24gRyhhKXt2YXIgYj1GW2FdPXt9O3JldHVybiBtLmVhY2goYS5tYXRjaChFKXx8W10sZnVuY3Rpb24oYSxjKXtiW2NdPSEwfSksYn1tLkNhbGxiYWNrcz1mdW5jdGlvbihhKXthPSJzdHJpbmciPT10eXBlb2YgYT9GW2FdfHxHKGEpOm0uZXh0ZW5kKHt9LGEpO3ZhciBiLGMsZCxlLGYsZyxoPVtdLGk9IWEub25jZSYmW10saj1mdW5jdGlvbihsKXtmb3IoYz1hLm1lbW9yeSYmbCxkPSEwLGY9Z3x8MCxnPTAsZT1oLmxlbmd0aCxiPSEwO2gmJmU+ZjtmKyspaWYoaFtmXS5hcHBseShsWzBdLGxbMV0pPT09ITEmJmEuc3RvcE9uRmFsc2Upe2M9ITE7YnJlYWt9Yj0hMSxoJiYoaT9pLmxlbmd0aCYmaihpLnNoaWZ0KCkpOmM/aD1bXTprLmRpc2FibGUoKSl9LGs9e2FkZDpmdW5jdGlvbigpe2lmKGgpe3ZhciBkPWgubGVuZ3RoOyFmdW5jdGlvbiBmKGIpe20uZWFjaChiLGZ1bmN0aW9uKGIsYyl7dmFyIGQ9bS50eXBlKGMpOyJmdW5jdGlvbiI9PT1kP2EudW5pcXVlJiZrLmhhcyhjKXx8aC5wdXNoKGMpOmMmJmMubGVuZ3RoJiYic3RyaW5nIiE9PWQmJmYoYyl9KX0oYXJndW1lbnRzKSxiP2U9aC5sZW5ndGg6YyYmKGc9ZCxqKGMpKX1yZXR1cm4gdGhpc30scmVtb3ZlOmZ1bmN0aW9uKCl7cmV0dXJuIGgmJm0uZWFjaChhcmd1bWVudHMsZnVuY3Rpb24oYSxjKXt2YXIgZDt3aGlsZSgoZD1tLmluQXJyYXkoYyxoLGQpKT4tMSloLnNwbGljZShkLDEpLGImJihlPj1kJiZlLS0sZj49ZCYmZi0tKX0pLHRoaXN9LGhhczpmdW5jdGlvbihhKXtyZXR1cm4gYT9tLmluQXJyYXkoYSxoKT4tMTohKCFofHwhaC5sZW5ndGgpfSxlbXB0eTpmdW5jdGlvbigpe3JldHVybiBoPVtdLGU9MCx0aGlzfSxkaXNhYmxlOmZ1bmN0aW9uKCl7cmV0dXJuIGg9aT1jPXZvaWQgMCx0aGlzfSxkaXNhYmxlZDpmdW5jdGlvbigpe3JldHVybiFofSxsb2NrOmZ1bmN0aW9uKCl7cmV0dXJuIGk9dm9pZCAwLGN8fGsuZGlzYWJsZSgpLHRoaXN9LGxvY2tlZDpmdW5jdGlvbigpe3JldHVybiFpfSxmaXJlV2l0aDpmdW5jdGlvbihhLGMpe3JldHVybiFofHxkJiYhaXx8KGM9Y3x8W10sYz1bYSxjLnNsaWNlP2Muc2xpY2UoKTpjXSxiP2kucHVzaChjKTpqKGMpKSx0aGlzfSxmaXJlOmZ1bmN0aW9uKCl7cmV0dXJuIGsuZmlyZVdpdGgodGhpcyxhcmd1bWVudHMpLHRoaXN9LGZpcmVkOmZ1bmN0aW9uKCl7cmV0dXJuISFkfX07cmV0dXJuIGt9LG0uZXh0ZW5kKHtEZWZlcnJlZDpmdW5jdGlvbihhKXt2YXIgYj1bWyJyZXNvbHZlIiwiZG9uZSIsbS5DYWxsYmFja3MoIm9uY2UgbWVtb3J5IiksInJlc29sdmVkIl0sWyJyZWplY3QiLCJmYWlsIixtLkNhbGxiYWNrcygib25jZSBtZW1vcnkiKSwicmVqZWN0ZWQiXSxbIm5vdGlmeSIsInByb2dyZXNzIixtLkNhbGxiYWNrcygibWVtb3J5IildXSxjPSJwZW5kaW5nIixkPXtzdGF0ZTpmdW5jdGlvbigpe3JldHVybiBjfSxhbHdheXM6ZnVuY3Rpb24oKXtyZXR1cm4gZS5kb25lKGFyZ3VtZW50cykuZmFpbChhcmd1bWVudHMpLHRoaXN9LHRoZW46ZnVuY3Rpb24oKXt2YXIgYT1hcmd1bWVudHM7cmV0dXJuIG0uRGVmZXJyZWQoZnVuY3Rpb24oYyl7bS5lYWNoKGIsZnVuY3Rpb24oYixmKXt2YXIgZz1tLmlzRnVuY3Rpb24oYVtiXSkmJmFbYl07ZVtmWzFdXShmdW5jdGlvbigpe3ZhciBhPWcmJmcuYXBwbHkodGhpcyxhcmd1bWVudHMpO2EmJm0uaXNGdW5jdGlvbihhLnByb21pc2UpP2EucHJvbWlzZSgpLmRvbmUoYy5yZXNvbHZlKS5mYWlsKGMucmVqZWN0KS5wcm9ncmVzcyhjLm5vdGlmeSk6Y1tmWzBdKyJXaXRoIl0odGhpcz09PWQ/Yy5wcm9taXNlKCk6dGhpcyxnP1thXTphcmd1bWVudHMpfSl9KSxhPW51bGx9KS5wcm9taXNlKCl9LHByb21pc2U6ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGwhPWE/bS5leHRlbmQoYSxkKTpkfX0sZT17fTtyZXR1cm4gZC5waXBlPWQudGhlbixtLmVhY2goYixmdW5jdGlvbihhLGYpe3ZhciBnPWZbMl0saD1mWzNdO2RbZlsxXV09Zy5hZGQsaCYmZy5hZGQoZnVuY3Rpb24oKXtjPWh9LGJbMV5hXVsyXS5kaXNhYmxlLGJbMl1bMl0ubG9jayksZVtmWzBdXT1mdW5jdGlvbigpe3JldHVybiBlW2ZbMF0rIldpdGgiXSh0aGlzPT09ZT9kOnRoaXMsYXJndW1lbnRzKSx0aGlzfSxlW2ZbMF0rIldpdGgiXT1nLmZpcmVXaXRofSksZC5wcm9taXNlKGUpLGEmJmEuY2FsbChlLGUpLGV9LHdoZW46ZnVuY3Rpb24oYSl7dmFyIGI9MCxjPWQuY2FsbChhcmd1bWVudHMpLGU9Yy5sZW5ndGgsZj0xIT09ZXx8YSYmbS5pc0Z1bmN0aW9uKGEucHJvbWlzZSk/ZTowLGc9MT09PWY/YTptLkRlZmVycmVkKCksaD1mdW5jdGlvbihhLGIsYyl7cmV0dXJuIGZ1bmN0aW9uKGUpe2JbYV09dGhpcyxjW2FdPWFyZ3VtZW50cy5sZW5ndGg+MT9kLmNhbGwoYXJndW1lbnRzKTplLGM9PT1pP2cubm90aWZ5V2l0aChiLGMpOi0tZnx8Zy5yZXNvbHZlV2l0aChiLGMpfX0saSxqLGs7aWYoZT4xKWZvcihpPW5ldyBBcnJheShlKSxqPW5ldyBBcnJheShlKSxrPW5ldyBBcnJheShlKTtlPmI7YisrKWNbYl0mJm0uaXNGdW5jdGlvbihjW2JdLnByb21pc2UpP2NbYl0ucHJvbWlzZSgpLmRvbmUoaChiLGssYykpLmZhaWwoZy5yZWplY3QpLnByb2dyZXNzKGgoYixqLGkpKTotLWY7cmV0dXJuIGZ8fGcucmVzb2x2ZVdpdGgoayxjKSxnLnByb21pc2UoKX19KTt2YXIgSDttLmZuLnJlYWR5PWZ1bmN0aW9uKGEpe3JldHVybiBtLnJlYWR5LnByb21pc2UoKS5kb25lKGEpLHRoaXN9LG0uZXh0ZW5kKHtpc1JlYWR5OiExLHJlYWR5V2FpdDoxLGhvbGRSZWFkeTpmdW5jdGlvbihhKXthP20ucmVhZHlXYWl0Kys6bS5yZWFkeSghMCl9LHJlYWR5OmZ1bmN0aW9uKGEpe2lmKGE9PT0hMD8hLS1tLnJlYWR5V2FpdDohbS5pc1JlYWR5KXtpZigheS5ib2R5KXJldHVybiBzZXRUaW1lb3V0KG0ucmVhZHkpO20uaXNSZWFkeT0hMCxhIT09ITAmJi0tbS5yZWFkeVdhaXQ+MHx8KEgucmVzb2x2ZVdpdGgoeSxbbV0pLG0uZm4udHJpZ2dlckhhbmRsZXImJihtKHkpLnRyaWdnZXJIYW5kbGVyKCJyZWFkeSIpLG0oeSkub2ZmKCJyZWFkeSIpKSl9fX0pO2Z1bmN0aW9uIEkoKXt5LmFkZEV2ZW50TGlzdGVuZXI/KHkucmVtb3ZlRXZlbnRMaXN0ZW5lcigiRE9NQ29udGVudExvYWRlZCIsSiwhMSksYS5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2FkIixKLCExKSk6KHkuZGV0YWNoRXZlbnQoIm9ucmVhZHlzdGF0ZWNoYW5nZSIsSiksYS5kZXRhY2hFdmVudCgib25sb2FkIixKKSl9ZnVuY3Rpb24gSigpeyh5LmFkZEV2ZW50TGlzdGVuZXJ8fCJsb2FkIj09PWV2ZW50LnR5cGV8fCJjb21wbGV0ZSI9PT15LnJlYWR5U3RhdGUpJiYoSSgpLG0ucmVhZHkoKSl9bS5yZWFkeS5wcm9taXNlPWZ1bmN0aW9uKGIpe2lmKCFIKWlmKEg9bS5EZWZlcnJlZCgpLCJjb21wbGV0ZSI9PT15LnJlYWR5U3RhdGUpc2V0VGltZW91dChtLnJlYWR5KTtlbHNlIGlmKHkuYWRkRXZlbnRMaXN0ZW5lcil5LmFkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLEosITEpLGEuYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsSiwhMSk7ZWxzZXt5LmF0dGFjaEV2ZW50KCJvbnJlYWR5c3RhdGVjaGFuZ2UiLEopLGEuYXR0YWNoRXZlbnQoIm9ubG9hZCIsSik7dmFyIGM9ITE7dHJ5e2M9bnVsbD09YS5mcmFtZUVsZW1lbnQmJnkuZG9jdW1lbnRFbGVtZW50fWNhdGNoKGQpe31jJiZjLmRvU2Nyb2xsJiYhZnVuY3Rpb24gZSgpe2lmKCFtLmlzUmVhZHkpe3RyeXtjLmRvU2Nyb2xsKCJsZWZ0Iil9Y2F0Y2goYSl7cmV0dXJuIHNldFRpbWVvdXQoZSw1MCl9SSgpLG0ucmVhZHkoKX19KCl9cmV0dXJuIEgucHJvbWlzZShiKX07dmFyIEs9InVuZGVmaW5lZCIsTDtmb3IoTCBpbiBtKGspKWJyZWFrO2sub3duTGFzdD0iMCIhPT1MLGsuaW5saW5lQmxvY2tOZWVkc0xheW91dD0hMSxtKGZ1bmN0aW9uKCl7dmFyIGEsYixjLGQ7Yz15LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJib2R5IilbMF0sYyYmYy5zdHlsZSYmKGI9eS5jcmVhdGVFbGVtZW50KCJkaXYiKSxkPXkuY3JlYXRlRWxlbWVudCgiZGl2IiksZC5zdHlsZS5jc3NUZXh0PSJwb3NpdGlvbjphYnNvbHV0ZTtib3JkZXI6MDt3aWR0aDowO2hlaWdodDowO3RvcDowO2xlZnQ6LTk5OTlweCIsYy5hcHBlbmRDaGlsZChkKS5hcHBlbmRDaGlsZChiKSx0eXBlb2YgYi5zdHlsZS56b29tIT09SyYmKGIuc3R5bGUuY3NzVGV4dD0iZGlzcGxheTppbmxpbmU7bWFyZ2luOjA7Ym9yZGVyOjA7cGFkZGluZzoxcHg7d2lkdGg6MXB4O3pvb206MSIsay5pbmxpbmVCbG9ja05lZWRzTGF5b3V0PWE9Mz09PWIub2Zmc2V0V2lkdGgsYSYmKGMuc3R5bGUuem9vbT0xKSksYy5yZW1vdmVDaGlsZChkKSl9KSxmdW5jdGlvbigpe3ZhciBhPXkuY3JlYXRlRWxlbWVudCgiZGl2Iik7aWYobnVsbD09ay5kZWxldGVFeHBhbmRvKXtrLmRlbGV0ZUV4cGFuZG89ITA7dHJ5e2RlbGV0ZSBhLnRlc3R9Y2F0Y2goYil7ay5kZWxldGVFeHBhbmRvPSExfX1hPW51bGx9KCksbS5hY2NlcHREYXRhPWZ1bmN0aW9uKGEpe3ZhciBiPW0ubm9EYXRhWyhhLm5vZGVOYW1lKyIgIikudG9Mb3dlckNhc2UoKV0sYz0rYS5ub2RlVHlwZXx8MTtyZXR1cm4gMSE9PWMmJjkhPT1jPyExOiFifHxiIT09ITAmJmEuZ2V0QXR0cmlidXRlKCJjbGFzc2lkIik9PT1ifTt2YXIgTT0vXig/Olx7W1x3XFddKlx9fFxbW1x3XFddKlxdKSQvLE49LyhbQS1aXSkvZztmdW5jdGlvbiBPKGEsYixjKXtpZih2b2lkIDA9PT1jJiYxPT09YS5ub2RlVHlwZSl7dmFyIGQ9ImRhdGEtIitiLnJlcGxhY2UoTiwiLSQxIikudG9Mb3dlckNhc2UoKTtpZihjPWEuZ2V0QXR0cmlidXRlKGQpLCJzdHJpbmciPT10eXBlb2YgYyl7dHJ5e2M9InRydWUiPT09Yz8hMDoiZmFsc2UiPT09Yz8hMToibnVsbCI9PT1jP251bGw6K2MrIiI9PT1jPytjOk0udGVzdChjKT9tLnBhcnNlSlNPTihjKTpjfWNhdGNoKGUpe31tLmRhdGEoYSxiLGMpfWVsc2UgYz12b2lkIDB9cmV0dXJuIGN9ZnVuY3Rpb24gUChhKXt2YXIgYjtmb3IoYiBpbiBhKWlmKCgiZGF0YSIhPT1ifHwhbS5pc0VtcHR5T2JqZWN0KGFbYl0pKSYmInRvSlNPTiIhPT1iKXJldHVybiExOwoKcmV0dXJuITB9ZnVuY3Rpb24gUShhLGIsZCxlKXtpZihtLmFjY2VwdERhdGEoYSkpe3ZhciBmLGcsaD1tLmV4cGFuZG8saT1hLm5vZGVUeXBlLGo9aT9tLmNhY2hlOmEsaz1pP2FbaF06YVtoXSYmaDtpZihrJiZqW2tdJiYoZXx8altrXS5kYXRhKXx8dm9pZCAwIT09ZHx8InN0cmluZyIhPXR5cGVvZiBiKXJldHVybiBrfHwoaz1pP2FbaF09Yy5wb3AoKXx8bS5ndWlkKys6aCksaltrXXx8KGpba109aT97fTp7dG9KU09OOm0ubm9vcH0pLCgib2JqZWN0Ij09dHlwZW9mIGJ8fCJmdW5jdGlvbiI9PXR5cGVvZiBiKSYmKGU/altrXT1tLmV4dGVuZChqW2tdLGIpOmpba10uZGF0YT1tLmV4dGVuZChqW2tdLmRhdGEsYikpLGc9altrXSxlfHwoZy5kYXRhfHwoZy5kYXRhPXt9KSxnPWcuZGF0YSksdm9pZCAwIT09ZCYmKGdbbS5jYW1lbENhc2UoYildPWQpLCJzdHJpbmciPT10eXBlb2YgYj8oZj1nW2JdLG51bGw9PWYmJihmPWdbbS5jYW1lbENhc2UoYildKSk6Zj1nLGZ9fWZ1bmN0aW9uIFIoYSxiLGMpe2lmKG0uYWNjZXB0RGF0YShhKSl7dmFyIGQsZSxmPWEubm9kZVR5cGUsZz1mP20uY2FjaGU6YSxoPWY/YVttLmV4cGFuZG9dOm0uZXhwYW5kbztpZihnW2hdKXtpZihiJiYoZD1jP2dbaF06Z1toXS5kYXRhKSl7bS5pc0FycmF5KGIpP2I9Yi5jb25jYXQobS5tYXAoYixtLmNhbWVsQ2FzZSkpOmIgaW4gZD9iPVtiXTooYj1tLmNhbWVsQ2FzZShiKSxiPWIgaW4gZD9bYl06Yi5zcGxpdCgiICIpKSxlPWIubGVuZ3RoO3doaWxlKGUtLSlkZWxldGUgZFtiW2VdXTtpZihjPyFQKGQpOiFtLmlzRW1wdHlPYmplY3QoZCkpcmV0dXJufShjfHwoZGVsZXRlIGdbaF0uZGF0YSxQKGdbaF0pKSkmJihmP20uY2xlYW5EYXRhKFthXSwhMCk6ay5kZWxldGVFeHBhbmRvfHxnIT1nLndpbmRvdz9kZWxldGUgZ1toXTpnW2hdPW51bGwpfX19bS5leHRlbmQoe2NhY2hlOnt9LG5vRGF0YTp7ImFwcGxldCAiOiEwLCJlbWJlZCAiOiEwLCJvYmplY3QgIjoiY2xzaWQ6RDI3Q0RCNkUtQUU2RC0xMWNmLTk2QjgtNDQ0NTUzNTQwMDAwIn0saGFzRGF0YTpmdW5jdGlvbihhKXtyZXR1cm4gYT1hLm5vZGVUeXBlP20uY2FjaGVbYVttLmV4cGFuZG9dXTphW20uZXhwYW5kb10sISFhJiYhUChhKX0sZGF0YTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIFEoYSxiLGMpfSxyZW1vdmVEYXRhOmZ1bmN0aW9uKGEsYil7cmV0dXJuIFIoYSxiKX0sX2RhdGE6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBRKGEsYixjLCEwKX0sX3JlbW92ZURhdGE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUihhLGIsITApfX0pLG0uZm4uZXh0ZW5kKHtkYXRhOmZ1bmN0aW9uKGEsYil7dmFyIGMsZCxlLGY9dGhpc1swXSxnPWYmJmYuYXR0cmlidXRlcztpZih2b2lkIDA9PT1hKXtpZih0aGlzLmxlbmd0aCYmKGU9bS5kYXRhKGYpLDE9PT1mLm5vZGVUeXBlJiYhbS5fZGF0YShmLCJwYXJzZWRBdHRycyIpKSl7Yz1nLmxlbmd0aDt3aGlsZShjLS0pZ1tjXSYmKGQ9Z1tjXS5uYW1lLDA9PT1kLmluZGV4T2YoImRhdGEtIikmJihkPW0uY2FtZWxDYXNlKGQuc2xpY2UoNSkpLE8oZixkLGVbZF0pKSk7bS5fZGF0YShmLCJwYXJzZWRBdHRycyIsITApfXJldHVybiBlfXJldHVybiJvYmplY3QiPT10eXBlb2YgYT90aGlzLmVhY2goZnVuY3Rpb24oKXttLmRhdGEodGhpcyxhKX0pOmFyZ3VtZW50cy5sZW5ndGg+MT90aGlzLmVhY2goZnVuY3Rpb24oKXttLmRhdGEodGhpcyxhLGIpfSk6Zj9PKGYsYSxtLmRhdGEoZixhKSk6dm9pZCAwfSxyZW1vdmVEYXRhOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXttLnJlbW92ZURhdGEodGhpcyxhKX0pfX0pLG0uZXh0ZW5kKHtxdWV1ZTpmdW5jdGlvbihhLGIsYyl7dmFyIGQ7cmV0dXJuIGE/KGI9KGJ8fCJmeCIpKyJxdWV1ZSIsZD1tLl9kYXRhKGEsYiksYyYmKCFkfHxtLmlzQXJyYXkoYyk/ZD1tLl9kYXRhKGEsYixtLm1ha2VBcnJheShjKSk6ZC5wdXNoKGMpKSxkfHxbXSk6dm9pZCAwfSxkZXF1ZXVlOmZ1bmN0aW9uKGEsYil7Yj1ifHwiZngiO3ZhciBjPW0ucXVldWUoYSxiKSxkPWMubGVuZ3RoLGU9Yy5zaGlmdCgpLGY9bS5fcXVldWVIb29rcyhhLGIpLGc9ZnVuY3Rpb24oKXttLmRlcXVldWUoYSxiKX07ImlucHJvZ3Jlc3MiPT09ZSYmKGU9Yy5zaGlmdCgpLGQtLSksZSYmKCJmeCI9PT1iJiZjLnVuc2hpZnQoImlucHJvZ3Jlc3MiKSxkZWxldGUgZi5zdG9wLGUuY2FsbChhLGcsZikpLCFkJiZmJiZmLmVtcHR5LmZpcmUoKX0sX3F1ZXVlSG9va3M6ZnVuY3Rpb24oYSxiKXt2YXIgYz1iKyJxdWV1ZUhvb2tzIjtyZXR1cm4gbS5fZGF0YShhLGMpfHxtLl9kYXRhKGEsYyx7ZW1wdHk6bS5DYWxsYmFja3MoIm9uY2UgbWVtb3J5IikuYWRkKGZ1bmN0aW9uKCl7bS5fcmVtb3ZlRGF0YShhLGIrInF1ZXVlIiksbS5fcmVtb3ZlRGF0YShhLGMpfSl9KX19KSxtLmZuLmV4dGVuZCh7cXVldWU6ZnVuY3Rpb24oYSxiKXt2YXIgYz0yO3JldHVybiJzdHJpbmciIT10eXBlb2YgYSYmKGI9YSxhPSJmeCIsYy0tKSxhcmd1bWVudHMubGVuZ3RoPGM/bS5xdWV1ZSh0aGlzWzBdLGEpOnZvaWQgMD09PWI/dGhpczp0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgYz1tLnF1ZXVlKHRoaXMsYSxiKTttLl9xdWV1ZUhvb2tzKHRoaXMsYSksImZ4Ij09PWEmJiJpbnByb2dyZXNzIiE9PWNbMF0mJm0uZGVxdWV1ZSh0aGlzLGEpfSl9LGRlcXVldWU6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe20uZGVxdWV1ZSh0aGlzLGEpfSl9LGNsZWFyUXVldWU6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMucXVldWUoYXx8ImZ4IixbXSl9LHByb21pc2U6ZnVuY3Rpb24oYSxiKXt2YXIgYyxkPTEsZT1tLkRlZmVycmVkKCksZj10aGlzLGc9dGhpcy5sZW5ndGgsaD1mdW5jdGlvbigpey0tZHx8ZS5yZXNvbHZlV2l0aChmLFtmXSl9OyJzdHJpbmciIT10eXBlb2YgYSYmKGI9YSxhPXZvaWQgMCksYT1hfHwiZngiO3doaWxlKGctLSljPW0uX2RhdGEoZltnXSxhKyJxdWV1ZUhvb2tzIiksYyYmYy5lbXB0eSYmKGQrKyxjLmVtcHR5LmFkZChoKSk7cmV0dXJuIGgoKSxlLnByb21pc2UoYil9fSk7dmFyIFM9L1srLV0/KD86XGQqXC58KVxkKyg/OltlRV1bKy1dP1xkK3wpLy5zb3VyY2UsVD1bIlRvcCIsIlJpZ2h0IiwiQm90dG9tIiwiTGVmdCJdLFU9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT1ifHxhLCJub25lIj09PW0uY3NzKGEsImRpc3BsYXkiKXx8IW0uY29udGFpbnMoYS5vd25lckRvY3VtZW50LGEpfSxWPW0uYWNjZXNzPWZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBoPTAsaT1hLmxlbmd0aCxqPW51bGw9PWM7aWYoIm9iamVjdCI9PT1tLnR5cGUoYykpe2U9ITA7Zm9yKGggaW4gYyltLmFjY2VzcyhhLGIsaCxjW2hdLCEwLGYsZyl9ZWxzZSBpZih2b2lkIDAhPT1kJiYoZT0hMCxtLmlzRnVuY3Rpb24oZCl8fChnPSEwKSxqJiYoZz8oYi5jYWxsKGEsZCksYj1udWxsKTooaj1iLGI9ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBqLmNhbGwobShhKSxjKX0pKSxiKSlmb3IoO2k+aDtoKyspYihhW2hdLGMsZz9kOmQuY2FsbChhW2hdLGgsYihhW2hdLGMpKSk7cmV0dXJuIGU/YTpqP2IuY2FsbChhKTppP2IoYVswXSxjKTpmfSxXPS9eKD86Y2hlY2tib3h8cmFkaW8pJC9pOyFmdW5jdGlvbigpe3ZhciBhPXkuY3JlYXRlRWxlbWVudCgiaW5wdXQiKSxiPXkuY3JlYXRlRWxlbWVudCgiZGl2IiksYz15LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtpZihiLmlubmVySFRNTD0iICA8bGluay8+PHRhYmxlPjwvdGFibGU+PGEgaHJlZj0nL2EnPmE8L2E+PGlucHV0IHR5cGU9J2NoZWNrYm94Jy8+IixrLmxlYWRpbmdXaGl0ZXNwYWNlPTM9PT1iLmZpcnN0Q2hpbGQubm9kZVR5cGUsay50Ym9keT0hYi5nZXRFbGVtZW50c0J5VGFnTmFtZSgidGJvZHkiKS5sZW5ndGgsay5odG1sU2VyaWFsaXplPSEhYi5nZXRFbGVtZW50c0J5VGFnTmFtZSgibGluayIpLmxlbmd0aCxrLmh0bWw1Q2xvbmU9Ijw6bmF2PjwvOm5hdj4iIT09eS5jcmVhdGVFbGVtZW50KCJuYXYiKS5jbG9uZU5vZGUoITApLm91dGVySFRNTCxhLnR5cGU9ImNoZWNrYm94IixhLmNoZWNrZWQ9ITAsYy5hcHBlbmRDaGlsZChhKSxrLmFwcGVuZENoZWNrZWQ9YS5jaGVja2VkLGIuaW5uZXJIVE1MPSI8dGV4dGFyZWE+eDwvdGV4dGFyZWE+IixrLm5vQ2xvbmVDaGVja2VkPSEhYi5jbG9uZU5vZGUoITApLmxhc3RDaGlsZC5kZWZhdWx0VmFsdWUsYy5hcHBlbmRDaGlsZChiKSxiLmlubmVySFRNTD0iPGlucHV0IHR5cGU9J3JhZGlvJyBjaGVja2VkPSdjaGVja2VkJyBuYW1lPSd0Jy8+IixrLmNoZWNrQ2xvbmU9Yi5jbG9uZU5vZGUoITApLmNsb25lTm9kZSghMCkubGFzdENoaWxkLmNoZWNrZWQsay5ub0Nsb25lRXZlbnQ9ITAsYi5hdHRhY2hFdmVudCYmKGIuYXR0YWNoRXZlbnQoIm9uY2xpY2siLGZ1bmN0aW9uKCl7ay5ub0Nsb25lRXZlbnQ9ITF9KSxiLmNsb25lTm9kZSghMCkuY2xpY2soKSksbnVsbD09ay5kZWxldGVFeHBhbmRvKXtrLmRlbGV0ZUV4cGFuZG89ITA7dHJ5e2RlbGV0ZSBiLnRlc3R9Y2F0Y2goZCl7ay5kZWxldGVFeHBhbmRvPSExfX19KCksZnVuY3Rpb24oKXt2YXIgYixjLGQ9eS5jcmVhdGVFbGVtZW50KCJkaXYiKTtmb3IoYiBpbntzdWJtaXQ6ITAsY2hhbmdlOiEwLGZvY3VzaW46ITB9KWM9Im9uIitiLChrW2IrIkJ1YmJsZXMiXT1jIGluIGEpfHwoZC5zZXRBdHRyaWJ1dGUoYywidCIpLGtbYisiQnViYmxlcyJdPWQuYXR0cmlidXRlc1tjXS5leHBhbmRvPT09ITEpO2Q9bnVsbH0oKTt2YXIgWD0vXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYSkkL2ksWT0vXmtleS8sWj0vXig/Om1vdXNlfHBvaW50ZXJ8Y29udGV4dG1lbnUpfGNsaWNrLywkPS9eKD86Zm9jdXNpbmZvY3VzfGZvY3Vzb3V0Ymx1cikkLyxfPS9eKFteLl0qKSg/OlwuKC4rKXwpJC87ZnVuY3Rpb24gYWEoKXtyZXR1cm4hMH1mdW5jdGlvbiBiYSgpe3JldHVybiExfWZ1bmN0aW9uIGNhKCl7dHJ5e3JldHVybiB5LmFjdGl2ZUVsZW1lbnR9Y2F0Y2goYSl7fX1tLmV2ZW50PXtnbG9iYWw6e30sYWRkOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIGYsZyxoLGksaixrLGwsbixvLHAscSxyPW0uX2RhdGEoYSk7aWYocil7Yy5oYW5kbGVyJiYoaT1jLGM9aS5oYW5kbGVyLGU9aS5zZWxlY3RvciksYy5ndWlkfHwoYy5ndWlkPW0uZ3VpZCsrKSwoZz1yLmV2ZW50cyl8fChnPXIuZXZlbnRzPXt9KSwoaz1yLmhhbmRsZSl8fChrPXIuaGFuZGxlPWZ1bmN0aW9uKGEpe3JldHVybiB0eXBlb2YgbT09PUt8fGEmJm0uZXZlbnQudHJpZ2dlcmVkPT09YS50eXBlP3ZvaWQgMDptLmV2ZW50LmRpc3BhdGNoLmFwcGx5KGsuZWxlbSxhcmd1bWVudHMpfSxrLmVsZW09YSksYj0oYnx8IiIpLm1hdGNoKEUpfHxbIiJdLGg9Yi5sZW5ndGg7d2hpbGUoaC0tKWY9Xy5leGVjKGJbaF0pfHxbXSxvPXE9ZlsxXSxwPShmWzJdfHwiIikuc3BsaXQoIi4iKS5zb3J0KCksbyYmKGo9bS5ldmVudC5zcGVjaWFsW29dfHx7fSxvPShlP2ouZGVsZWdhdGVUeXBlOmouYmluZFR5cGUpfHxvLGo9bS5ldmVudC5zcGVjaWFsW29dfHx7fSxsPW0uZXh0ZW5kKHt0eXBlOm8sb3JpZ1R5cGU6cSxkYXRhOmQsaGFuZGxlcjpjLGd1aWQ6Yy5ndWlkLHNlbGVjdG9yOmUsbmVlZHNDb250ZXh0OmUmJm0uZXhwci5tYXRjaC5uZWVkc0NvbnRleHQudGVzdChlKSxuYW1lc3BhY2U6cC5qb2luKCIuIil9LGkpLChuPWdbb10pfHwobj1nW29dPVtdLG4uZGVsZWdhdGVDb3VudD0wLGouc2V0dXAmJmouc2V0dXAuY2FsbChhLGQscCxrKSE9PSExfHwoYS5hZGRFdmVudExpc3RlbmVyP2EuYWRkRXZlbnRMaXN0ZW5lcihvLGssITEpOmEuYXR0YWNoRXZlbnQmJmEuYXR0YWNoRXZlbnQoIm9uIitvLGspKSksai5hZGQmJihqLmFkZC5jYWxsKGEsbCksbC5oYW5kbGVyLmd1aWR8fChsLmhhbmRsZXIuZ3VpZD1jLmd1aWQpKSxlP24uc3BsaWNlKG4uZGVsZWdhdGVDb3VudCsrLDAsbCk6bi5wdXNoKGwpLG0uZXZlbnQuZ2xvYmFsW29dPSEwKTthPW51bGx9fSxyZW1vdmU6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgZixnLGgsaSxqLGssbCxuLG8scCxxLHI9bS5oYXNEYXRhKGEpJiZtLl9kYXRhKGEpO2lmKHImJihrPXIuZXZlbnRzKSl7Yj0oYnx8IiIpLm1hdGNoKEUpfHxbIiJdLGo9Yi5sZW5ndGg7d2hpbGUoai0tKWlmKGg9Xy5leGVjKGJbal0pfHxbXSxvPXE9aFsxXSxwPShoWzJdfHwiIikuc3BsaXQoIi4iKS5zb3J0KCksbyl7bD1tLmV2ZW50LnNwZWNpYWxbb118fHt9LG89KGQ/bC5kZWxlZ2F0ZVR5cGU6bC5iaW5kVHlwZSl8fG8sbj1rW29dfHxbXSxoPWhbMl0mJm5ldyBSZWdFeHAoIihefFxcLikiK3Auam9pbigiXFwuKD86LipcXC58KSIpKyIoXFwufCQpIiksaT1mPW4ubGVuZ3RoO3doaWxlKGYtLSlnPW5bZl0sIWUmJnEhPT1nLm9yaWdUeXBlfHxjJiZjLmd1aWQhPT1nLmd1aWR8fGgmJiFoLnRlc3QoZy5uYW1lc3BhY2UpfHxkJiZkIT09Zy5zZWxlY3RvciYmKCIqKiIhPT1kfHwhZy5zZWxlY3Rvcil8fChuLnNwbGljZShmLDEpLGcuc2VsZWN0b3ImJm4uZGVsZWdhdGVDb3VudC0tLGwucmVtb3ZlJiZsLnJlbW92ZS5jYWxsKGEsZykpO2kmJiFuLmxlbmd0aCYmKGwudGVhcmRvd24mJmwudGVhcmRvd24uY2FsbChhLHAsci5oYW5kbGUpIT09ITF8fG0ucmVtb3ZlRXZlbnQoYSxvLHIuaGFuZGxlKSxkZWxldGUga1tvXSl9ZWxzZSBmb3IobyBpbiBrKW0uZXZlbnQucmVtb3ZlKGEsbytiW2pdLGMsZCwhMCk7bS5pc0VtcHR5T2JqZWN0KGspJiYoZGVsZXRlIHIuaGFuZGxlLG0uX3JlbW92ZURhdGEoYSwiZXZlbnRzIikpfX0sdHJpZ2dlcjpmdW5jdGlvbihiLGMsZCxlKXt2YXIgZixnLGgsaSxrLGwsbixvPVtkfHx5XSxwPWouY2FsbChiLCJ0eXBlIik/Yi50eXBlOmIscT1qLmNhbGwoYiwibmFtZXNwYWNlIik/Yi5uYW1lc3BhY2Uuc3BsaXQoIi4iKTpbXTtpZihoPWw9ZD1kfHx5LDMhPT1kLm5vZGVUeXBlJiY4IT09ZC5ub2RlVHlwZSYmISQudGVzdChwK20uZXZlbnQudHJpZ2dlcmVkKSYmKHAuaW5kZXhPZigiLiIpPj0wJiYocT1wLnNwbGl0KCIuIikscD1xLnNoaWZ0KCkscS5zb3J0KCkpLGc9cC5pbmRleE9mKCI6Iik8MCYmIm9uIitwLGI9YlttLmV4cGFuZG9dP2I6bmV3IG0uRXZlbnQocCwib2JqZWN0Ij09dHlwZW9mIGImJmIpLGIuaXNUcmlnZ2VyPWU/MjozLGIubmFtZXNwYWNlPXEuam9pbigiLiIpLGIubmFtZXNwYWNlX3JlPWIubmFtZXNwYWNlP25ldyBSZWdFeHAoIihefFxcLikiK3Euam9pbigiXFwuKD86LipcXC58KSIpKyIoXFwufCQpIik6bnVsbCxiLnJlc3VsdD12b2lkIDAsYi50YXJnZXR8fChiLnRhcmdldD1kKSxjPW51bGw9PWM/W2JdOm0ubWFrZUFycmF5KGMsW2JdKSxrPW0uZXZlbnQuc3BlY2lhbFtwXXx8e30sZXx8IWsudHJpZ2dlcnx8ay50cmlnZ2VyLmFwcGx5KGQsYykhPT0hMSkpe2lmKCFlJiYhay5ub0J1YmJsZSYmIW0uaXNXaW5kb3coZCkpe2ZvcihpPWsuZGVsZWdhdGVUeXBlfHxwLCQudGVzdChpK3ApfHwoaD1oLnBhcmVudE5vZGUpO2g7aD1oLnBhcmVudE5vZGUpby5wdXNoKGgpLGw9aDtsPT09KGQub3duZXJEb2N1bWVudHx8eSkmJm8ucHVzaChsLmRlZmF1bHRWaWV3fHxsLnBhcmVudFdpbmRvd3x8YSl9bj0wO3doaWxlKChoPW9bbisrXSkmJiFiLmlzUHJvcGFnYXRpb25TdG9wcGVkKCkpYi50eXBlPW4+MT9pOmsuYmluZFR5cGV8fHAsZj0obS5fZGF0YShoLCJldmVudHMiKXx8e30pW2IudHlwZV0mJm0uX2RhdGEoaCwiaGFuZGxlIiksZiYmZi5hcHBseShoLGMpLGY9ZyYmaFtnXSxmJiZmLmFwcGx5JiZtLmFjY2VwdERhdGEoaCkmJihiLnJlc3VsdD1mLmFwcGx5KGgsYyksYi5yZXN1bHQ9PT0hMSYmYi5wcmV2ZW50RGVmYXVsdCgpKTtpZihiLnR5cGU9cCwhZSYmIWIuaXNEZWZhdWx0UHJldmVudGVkKCkmJighay5fZGVmYXVsdHx8ay5fZGVmYXVsdC5hcHBseShvLnBvcCgpLGMpPT09ITEpJiZtLmFjY2VwdERhdGEoZCkmJmcmJmRbcF0mJiFtLmlzV2luZG93KGQpKXtsPWRbZ10sbCYmKGRbZ109bnVsbCksbS5ldmVudC50cmlnZ2VyZWQ9cDt0cnl7ZFtwXSgpfWNhdGNoKHIpe31tLmV2ZW50LnRyaWdnZXJlZD12b2lkIDAsbCYmKGRbZ109bCl9cmV0dXJuIGIucmVzdWx0fX0sZGlzcGF0Y2g6ZnVuY3Rpb24oYSl7YT1tLmV2ZW50LmZpeChhKTt2YXIgYixjLGUsZixnLGg9W10saT1kLmNhbGwoYXJndW1lbnRzKSxqPShtLl9kYXRhKHRoaXMsImV2ZW50cyIpfHx7fSlbYS50eXBlXXx8W10saz1tLmV2ZW50LnNwZWNpYWxbYS50eXBlXXx8e307aWYoaVswXT1hLGEuZGVsZWdhdGVUYXJnZXQ9dGhpcywhay5wcmVEaXNwYXRjaHx8ay5wcmVEaXNwYXRjaC5jYWxsKHRoaXMsYSkhPT0hMSl7aD1tLmV2ZW50LmhhbmRsZXJzLmNhbGwodGhpcyxhLGopLGI9MDt3aGlsZSgoZj1oW2IrK10pJiYhYS5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpKXthLmN1cnJlbnRUYXJnZXQ9Zi5lbGVtLGc9MDt3aGlsZSgoZT1mLmhhbmRsZXJzW2crK10pJiYhYS5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCgpKSghYS5uYW1lc3BhY2VfcmV8fGEubmFtZXNwYWNlX3JlLnRlc3QoZS5uYW1lc3BhY2UpKSYmKGEuaGFuZGxlT2JqPWUsYS5kYXRhPWUuZGF0YSxjPSgobS5ldmVudC5zcGVjaWFsW2Uub3JpZ1R5cGVdfHx7fSkuaGFuZGxlfHxlLmhhbmRsZXIpLmFwcGx5KGYuZWxlbSxpKSx2b2lkIDAhPT1jJiYoYS5yZXN1bHQ9Yyk9PT0hMSYmKGEucHJldmVudERlZmF1bHQoKSxhLnN0b3BQcm9wYWdhdGlvbigpKSl9cmV0dXJuIGsucG9zdERpc3BhdGNoJiZrLnBvc3REaXNwYXRjaC5jYWxsKHRoaXMsYSksYS5yZXN1bHR9fSxoYW5kbGVyczpmdW5jdGlvbihhLGIpe3ZhciBjLGQsZSxmLGc9W10saD1iLmRlbGVnYXRlQ291bnQsaT1hLnRhcmdldDtpZihoJiZpLm5vZGVUeXBlJiYoIWEuYnV0dG9ufHwiY2xpY2siIT09YS50eXBlKSlmb3IoO2khPXRoaXM7aT1pLnBhcmVudE5vZGV8fHRoaXMpaWYoMT09PWkubm9kZVR5cGUmJihpLmRpc2FibGVkIT09ITB8fCJjbGljayIhPT1hLnR5cGUpKXtmb3IoZT1bXSxmPTA7aD5mO2YrKylkPWJbZl0sYz1kLnNlbGVjdG9yKyIgIix2b2lkIDA9PT1lW2NdJiYoZVtjXT1kLm5lZWRzQ29udGV4dD9tKGMsdGhpcykuaW5kZXgoaSk+PTA6bS5maW5kKGMsdGhpcyxudWxsLFtpXSkubGVuZ3RoKSxlW2NdJiZlLnB1c2goZCk7ZS5sZW5ndGgmJmcucHVzaCh7ZWxlbTppLGhhbmRsZXJzOmV9KX1yZXR1cm4gaDxiLmxlbmd0aCYmZy5wdXNoKHtlbGVtOnRoaXMsaGFuZGxlcnM6Yi5zbGljZShoKX0pLGd9LGZpeDpmdW5jdGlvbihhKXtpZihhW20uZXhwYW5kb10pcmV0dXJuIGE7dmFyIGIsYyxkLGU9YS50eXBlLGY9YSxnPXRoaXMuZml4SG9va3NbZV07Z3x8KHRoaXMuZml4SG9va3NbZV09Zz1aLnRlc3QoZSk/dGhpcy5tb3VzZUhvb2tzOlkudGVzdChlKT90aGlzLmtleUhvb2tzOnt9KSxkPWcucHJvcHM/dGhpcy5wcm9wcy5jb25jYXQoZy5wcm9wcyk6dGhpcy5wcm9wcyxhPW5ldyBtLkV2ZW50KGYpLGI9ZC5sZW5ndGg7d2hpbGUoYi0tKWM9ZFtiXSxhW2NdPWZbY107cmV0dXJuIGEudGFyZ2V0fHwoYS50YXJnZXQ9Zi5zcmNFbGVtZW50fHx5KSwzPT09YS50YXJnZXQubm9kZVR5cGUmJihhLnRhcmdldD1hLnRhcmdldC5wYXJlbnROb2RlKSxhLm1ldGFLZXk9ISFhLm1ldGFLZXksZy5maWx0ZXI/Zy5maWx0ZXIoYSxmKTphfSxwcm9wczoiYWx0S2V5IGJ1YmJsZXMgY2FuY2VsYWJsZSBjdHJsS2V5IGN1cnJlbnRUYXJnZXQgZXZlbnRQaGFzZSBtZXRhS2V5IHJlbGF0ZWRUYXJnZXQgc2hpZnRLZXkgdGFyZ2V0IHRpbWVTdGFtcCB2aWV3IHdoaWNoIi5zcGxpdCgiICIpLGZpeEhvb2tzOnt9LGtleUhvb2tzOntwcm9wczoiY2hhciBjaGFyQ29kZSBrZXkga2V5Q29kZSIuc3BsaXQoIiAiKSxmaWx0ZXI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbD09YS53aGljaCYmKGEud2hpY2g9bnVsbCE9Yi5jaGFyQ29kZT9iLmNoYXJDb2RlOmIua2V5Q29kZSksYX19LG1vdXNlSG9va3M6e3Byb3BzOiJidXR0b24gYnV0dG9ucyBjbGllbnRYIGNsaWVudFkgZnJvbUVsZW1lbnQgb2Zmc2V0WCBvZmZzZXRZIHBhZ2VYIHBhZ2VZIHNjcmVlblggc2NyZWVuWSB0b0VsZW1lbnQiLnNwbGl0KCIgIiksZmlsdGVyOmZ1bmN0aW9uKGEsYil7dmFyIGMsZCxlLGY9Yi5idXR0b24sZz1iLmZyb21FbGVtZW50O3JldHVybiBudWxsPT1hLnBhZ2VYJiZudWxsIT1iLmNsaWVudFgmJihkPWEudGFyZ2V0Lm93bmVyRG9jdW1lbnR8fHksZT1kLmRvY3VtZW50RWxlbWVudCxjPWQuYm9keSxhLnBhZ2VYPWIuY2xpZW50WCsoZSYmZS5zY3JvbGxMZWZ0fHxjJiZjLnNjcm9sbExlZnR8fDApLShlJiZlLmNsaWVudExlZnR8fGMmJmMuY2xpZW50TGVmdHx8MCksYS5wYWdlWT1iLmNsaWVudFkrKGUmJmUuc2Nyb2xsVG9wfHxjJiZjLnNjcm9sbFRvcHx8MCktKGUmJmUuY2xpZW50VG9wfHxjJiZjLmNsaWVudFRvcHx8MCkpLCFhLnJlbGF0ZWRUYXJnZXQmJmcmJihhLnJlbGF0ZWRUYXJnZXQ9Zz09PWEudGFyZ2V0P2IudG9FbGVtZW50OmcpLGEud2hpY2h8fHZvaWQgMD09PWZ8fChhLndoaWNoPTEmZj8xOjImZj8zOjQmZj8yOjApLGF9fSxzcGVjaWFsOntsb2FkOntub0J1YmJsZTohMH0sZm9jdXM6e3RyaWdnZXI6ZnVuY3Rpb24oKXtpZih0aGlzIT09Y2EoKSYmdGhpcy5mb2N1cyl0cnl7cmV0dXJuIHRoaXMuZm9jdXMoKSwhMX1jYXRjaChhKXt9fSxkZWxlZ2F0ZVR5cGU6ImZvY3VzaW4ifSxibHVyOnt0cmlnZ2VyOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXM9PT1jYSgpJiZ0aGlzLmJsdXI/KHRoaXMuYmx1cigpLCExKTp2b2lkIDB9LGRlbGVnYXRlVHlwZToiZm9jdXNvdXQifSxjbGljazp7dHJpZ2dlcjpmdW5jdGlvbigpe3JldHVybiBtLm5vZGVOYW1lKHRoaXMsImlucHV0IikmJiJjaGVja2JveCI9PT10aGlzLnR5cGUmJnRoaXMuY2xpY2s/KHRoaXMuY2xpY2soKSwhMSk6dm9pZCAwfSxfZGVmYXVsdDpmdW5jdGlvbihhKXtyZXR1cm4gbS5ub2RlTmFtZShhLnRhcmdldCwiYSIpfX0sYmVmb3JldW5sb2FkOntwb3N0RGlzcGF0Y2g6ZnVuY3Rpb24oYSl7dm9pZCAwIT09YS5yZXN1bHQmJmEub3JpZ2luYWxFdmVudCYmKGEub3JpZ2luYWxFdmVudC5yZXR1cm5WYWx1ZT1hLnJlc3VsdCl9fX0sc2ltdWxhdGU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGU9bS5leHRlbmQobmV3IG0uRXZlbnQsYyx7dHlwZTphLGlzU2ltdWxhdGVkOiEwLG9yaWdpbmFsRXZlbnQ6e319KTtkP20uZXZlbnQudHJpZ2dlcihlLG51bGwsYik6bS5ldmVudC5kaXNwYXRjaC5jYWxsKGIsZSksZS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSYmYy5wcmV2ZW50RGVmYXVsdCgpfX0sbS5yZW1vdmVFdmVudD15LnJlbW92ZUV2ZW50TGlzdGVuZXI/ZnVuY3Rpb24oYSxiLGMpe2EucmVtb3ZlRXZlbnRMaXN0ZW5lciYmYS5yZW1vdmVFdmVudExpc3RlbmVyKGIsYywhMSl9OmZ1bmN0aW9uKGEsYixjKXt2YXIgZD0ib24iK2I7YS5kZXRhY2hFdmVudCYmKHR5cGVvZiBhW2RdPT09SyYmKGFbZF09bnVsbCksYS5kZXRhY2hFdmVudChkLGMpKX0sbS5FdmVudD1mdW5jdGlvbihhLGIpe3JldHVybiB0aGlzIGluc3RhbmNlb2YgbS5FdmVudD8oYSYmYS50eXBlPyh0aGlzLm9yaWdpbmFsRXZlbnQ9YSx0aGlzLnR5cGU9YS50eXBlLHRoaXMuaXNEZWZhdWx0UHJldmVudGVkPWEuZGVmYXVsdFByZXZlbnRlZHx8dm9pZCAwPT09YS5kZWZhdWx0UHJldmVudGVkJiZhLnJldHVyblZhbHVlPT09ITE/YWE6YmEpOnRoaXMudHlwZT1hLGImJm0uZXh0ZW5kKHRoaXMsYiksdGhpcy50aW1lU3RhbXA9YSYmYS50aW1lU3RhbXB8fG0ubm93KCksdm9pZCh0aGlzW20uZXhwYW5kb109ITApKTpuZXcgbS5FdmVudChhLGIpfSxtLkV2ZW50LnByb3RvdHlwZT17aXNEZWZhdWx0UHJldmVudGVkOmJhLGlzUHJvcGFnYXRpb25TdG9wcGVkOmJhLGlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOmJhLHByZXZlbnREZWZhdWx0OmZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5vcmlnaW5hbEV2ZW50O3RoaXMuaXNEZWZhdWx0UHJldmVudGVkPWFhLGEmJihhLnByZXZlbnREZWZhdWx0P2EucHJldmVudERlZmF1bHQoKTphLnJldHVyblZhbHVlPSExKX0sc3RvcFByb3BhZ2F0aW9uOmZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5vcmlnaW5hbEV2ZW50O3RoaXMuaXNQcm9wYWdhdGlvblN0b3BwZWQ9YWEsYSYmKGEuc3RvcFByb3BhZ2F0aW9uJiZhLnN0b3BQcm9wYWdhdGlvbigpLGEuY2FuY2VsQnViYmxlPSEwKX0sc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uOmZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5vcmlnaW5hbEV2ZW50O3RoaXMuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQ9YWEsYSYmYS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24mJmEuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksdGhpcy5zdG9wUHJvcGFnYXRpb24oKX19LG0uZWFjaCh7bW91c2VlbnRlcjoibW91c2VvdmVyIixtb3VzZWxlYXZlOiJtb3VzZW91dCIscG9pbnRlcmVudGVyOiJwb2ludGVyb3ZlciIscG9pbnRlcmxlYXZlOiJwb2ludGVyb3V0In0sZnVuY3Rpb24oYSxiKXttLmV2ZW50LnNwZWNpYWxbYV09e2RlbGVnYXRlVHlwZTpiLGJpbmRUeXBlOmIsaGFuZGxlOmZ1bmN0aW9uKGEpe3ZhciBjLGQ9dGhpcyxlPWEucmVsYXRlZFRhcmdldCxmPWEuaGFuZGxlT2JqO3JldHVybighZXx8ZSE9PWQmJiFtLmNvbnRhaW5zKGQsZSkpJiYoYS50eXBlPWYub3JpZ1R5cGUsYz1mLmhhbmRsZXIuYXBwbHkodGhpcyxhcmd1bWVudHMpLGEudHlwZT1iKSxjfX19KSxrLnN1Ym1pdEJ1YmJsZXN8fChtLmV2ZW50LnNwZWNpYWwuc3VibWl0PXtzZXR1cDpmdW5jdGlvbigpe3JldHVybiBtLm5vZGVOYW1lKHRoaXMsImZvcm0iKT8hMTp2b2lkIG0uZXZlbnQuYWRkKHRoaXMsImNsaWNrLl9zdWJtaXQga2V5cHJlc3MuX3N1Ym1pdCIsZnVuY3Rpb24oYSl7dmFyIGI9YS50YXJnZXQsYz1tLm5vZGVOYW1lKGIsImlucHV0Iil8fG0ubm9kZU5hbWUoYiwiYnV0dG9uIik/Yi5mb3JtOnZvaWQgMDtjJiYhbS5fZGF0YShjLCJzdWJtaXRCdWJibGVzIikmJihtLmV2ZW50LmFkZChjLCJzdWJtaXQuX3N1Ym1pdCIsZnVuY3Rpb24oYSl7YS5fc3VibWl0X2J1YmJsZT0hMH0pLG0uX2RhdGEoYywic3VibWl0QnViYmxlcyIsITApKX0pfSxwb3N0RGlzcGF0Y2g6ZnVuY3Rpb24oYSl7YS5fc3VibWl0X2J1YmJsZSYmKGRlbGV0ZSBhLl9zdWJtaXRfYnViYmxlLHRoaXMucGFyZW50Tm9kZSYmIWEuaXNUcmlnZ2VyJiZtLmV2ZW50LnNpbXVsYXRlKCJzdWJtaXQiLHRoaXMucGFyZW50Tm9kZSxhLCEwKSl9LHRlYXJkb3duOmZ1bmN0aW9uKCl7cmV0dXJuIG0ubm9kZU5hbWUodGhpcywiZm9ybSIpPyExOnZvaWQgbS5ldmVudC5yZW1vdmUodGhpcywiLl9zdWJtaXQiKX19KSxrLmNoYW5nZUJ1YmJsZXN8fChtLmV2ZW50LnNwZWNpYWwuY2hhbmdlPXtzZXR1cDpmdW5jdGlvbigpe3JldHVybiBYLnRlc3QodGhpcy5ub2RlTmFtZSk/KCgiY2hlY2tib3giPT09dGhpcy50eXBlfHwicmFkaW8iPT09dGhpcy50eXBlKSYmKG0uZXZlbnQuYWRkKHRoaXMsInByb3BlcnR5Y2hhbmdlLl9jaGFuZ2UiLGZ1bmN0aW9uKGEpeyJjaGVja2VkIj09PWEub3JpZ2luYWxFdmVudC5wcm9wZXJ0eU5hbWUmJih0aGlzLl9qdXN0X2NoYW5nZWQ9ITApfSksbS5ldmVudC5hZGQodGhpcywiY2xpY2suX2NoYW5nZSIsZnVuY3Rpb24oYSl7dGhpcy5fanVzdF9jaGFuZ2VkJiYhYS5pc1RyaWdnZXImJih0aGlzLl9qdXN0X2NoYW5nZWQ9ITEpLG0uZXZlbnQuc2ltdWxhdGUoImNoYW5nZSIsdGhpcyxhLCEwKX0pKSwhMSk6dm9pZCBtLmV2ZW50LmFkZCh0aGlzLCJiZWZvcmVhY3RpdmF0ZS5fY2hhbmdlIixmdW5jdGlvbihhKXt2YXIgYj1hLnRhcmdldDtYLnRlc3QoYi5ub2RlTmFtZSkmJiFtLl9kYXRhKGIsImNoYW5nZUJ1YmJsZXMiKSYmKG0uZXZlbnQuYWRkKGIsImNoYW5nZS5fY2hhbmdlIixmdW5jdGlvbihhKXshdGhpcy5wYXJlbnROb2RlfHxhLmlzU2ltdWxhdGVkfHxhLmlzVHJpZ2dlcnx8bS5ldmVudC5zaW11bGF0ZSgiY2hhbmdlIix0aGlzLnBhcmVudE5vZGUsYSwhMCl9KSxtLl9kYXRhKGIsImNoYW5nZUJ1YmJsZXMiLCEwKSl9KX0saGFuZGxlOmZ1bmN0aW9uKGEpe3ZhciBiPWEudGFyZ2V0O3JldHVybiB0aGlzIT09Ynx8YS5pc1NpbXVsYXRlZHx8YS5pc1RyaWdnZXJ8fCJyYWRpbyIhPT1iLnR5cGUmJiJjaGVja2JveCIhPT1iLnR5cGU/YS5oYW5kbGVPYmouaGFuZGxlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk6dm9pZCAwfSx0ZWFyZG93bjpmdW5jdGlvbigpe3JldHVybiBtLmV2ZW50LnJlbW92ZSh0aGlzLCIuX2NoYW5nZSIpLCFYLnRlc3QodGhpcy5ub2RlTmFtZSl9fSksay5mb2N1c2luQnViYmxlc3x8bS5lYWNoKHtmb2N1czoiZm9jdXNpbiIsYmx1cjoiZm9jdXNvdXQifSxmdW5jdGlvbihhLGIpe3ZhciBjPWZ1bmN0aW9uKGEpe20uZXZlbnQuc2ltdWxhdGUoYixhLnRhcmdldCxtLmV2ZW50LmZpeChhKSwhMCl9O20uZXZlbnQuc3BlY2lhbFtiXT17c2V0dXA6ZnVuY3Rpb24oKXt2YXIgZD10aGlzLm93bmVyRG9jdW1lbnR8fHRoaXMsZT1tLl9kYXRhKGQsYik7ZXx8ZC5hZGRFdmVudExpc3RlbmVyKGEsYywhMCksbS5fZGF0YShkLGIsKGV8fDApKzEpfSx0ZWFyZG93bjpmdW5jdGlvbigpe3ZhciBkPXRoaXMub3duZXJEb2N1bWVudHx8dGhpcyxlPW0uX2RhdGEoZCxiKS0xO2U/bS5fZGF0YShkLGIsZSk6KGQucmVtb3ZlRXZlbnRMaXN0ZW5lcihhLGMsITApLG0uX3JlbW92ZURhdGEoZCxiKSl9fX0pLG0uZm4uZXh0ZW5kKHtvbjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBmLGc7aWYoIm9iamVjdCI9PXR5cGVvZiBhKXsic3RyaW5nIiE9dHlwZW9mIGImJihjPWN8fGIsYj12b2lkIDApO2ZvcihmIGluIGEpdGhpcy5vbihmLGIsYyxhW2ZdLGUpO3JldHVybiB0aGlzfWlmKG51bGw9PWMmJm51bGw9PWQ/KGQ9YixjPWI9dm9pZCAwKTpudWxsPT1kJiYoInN0cmluZyI9PXR5cGVvZiBiPyhkPWMsYz12b2lkIDApOihkPWMsYz1iLGI9dm9pZCAwKSksZD09PSExKWQ9YmE7ZWxzZSBpZighZClyZXR1cm4gdGhpcztyZXR1cm4gMT09PWUmJihnPWQsZD1mdW5jdGlvbihhKXtyZXR1cm4gbSgpLm9mZihhKSxnLmFwcGx5KHRoaXMsYXJndW1lbnRzKX0sZC5ndWlkPWcuZ3VpZHx8KGcuZ3VpZD1tLmd1aWQrKykpLHRoaXMuZWFjaChmdW5jdGlvbigpe20uZXZlbnQuYWRkKHRoaXMsYSxkLGMsYil9KX0sb25lOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiB0aGlzLm9uKGEsYixjLGQsMSl9LG9mZjpmdW5jdGlvbihhLGIsYyl7dmFyIGQsZTtpZihhJiZhLnByZXZlbnREZWZhdWx0JiZhLmhhbmRsZU9iailyZXR1cm4gZD1hLmhhbmRsZU9iaixtKGEuZGVsZWdhdGVUYXJnZXQpLm9mZihkLm5hbWVzcGFjZT9kLm9yaWdUeXBlKyIuIitkLm5hbWVzcGFjZTpkLm9yaWdUeXBlLGQuc2VsZWN0b3IsZC5oYW5kbGVyKSx0aGlzO2lmKCJvYmplY3QiPT10eXBlb2YgYSl7Zm9yKGUgaW4gYSl0aGlzLm9mZihlLGIsYVtlXSk7cmV0dXJuIHRoaXN9cmV0dXJuKGI9PT0hMXx8ImZ1bmN0aW9uIj09dHlwZW9mIGIpJiYoYz1iLGI9dm9pZCAwKSxjPT09ITEmJihjPWJhKSx0aGlzLmVhY2goZnVuY3Rpb24oKXttLmV2ZW50LnJlbW92ZSh0aGlzLGEsYyxiKX0pfSx0cmlnZ2VyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe20uZXZlbnQudHJpZ2dlcihhLGIsdGhpcyl9KX0sdHJpZ2dlckhhbmRsZXI6ZnVuY3Rpb24oYSxiKXt2YXIgYz10aGlzWzBdO3JldHVybiBjP20uZXZlbnQudHJpZ2dlcihhLGIsYywhMCk6dm9pZCAwfX0pO2Z1bmN0aW9uIGRhKGEpe3ZhciBiPWVhLnNwbGl0KCJ8IiksYz1hLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtpZihjLmNyZWF0ZUVsZW1lbnQpd2hpbGUoYi5sZW5ndGgpYy5jcmVhdGVFbGVtZW50KGIucG9wKCkpO3JldHVybiBjfXZhciBlYT0iYWJicnxhcnRpY2xlfGFzaWRlfGF1ZGlvfGJkaXxjYW52YXN8ZGF0YXxkYXRhbGlzdHxkZXRhaWxzfGZpZ2NhcHRpb258ZmlndXJlfGZvb3RlcnxoZWFkZXJ8aGdyb3VwfG1hcmt8bWV0ZXJ8bmF2fG91dHB1dHxwcm9ncmVzc3xzZWN0aW9ufHN1bW1hcnl8dGltZXx2aWRlbyIsZmE9LyBqUXVlcnlcZCs9Iig/Om51bGx8XGQrKSIvZyxnYT1uZXcgUmVnRXhwKCI8KD86IitlYSsiKVtcXHMvPl0iLCJpIiksaGE9L15ccysvLGlhPS88KD8hYXJlYXxicnxjb2x8ZW1iZWR8aHJ8aW1nfGlucHV0fGxpbmt8bWV0YXxwYXJhbSkoKFtcdzpdKylbXj5dKilcLz4vZ2ksamE9LzwoW1x3Ol0rKS8sa2E9Lzx0Ym9keS9pLGxhPS88fCYjP1x3KzsvLG1hPS88KD86c2NyaXB0fHN0eWxlfGxpbmspL2ksbmE9L2NoZWNrZWRccyooPzpbXj1dfD1ccyouY2hlY2tlZC4pL2ksb2E9L14kfFwvKD86amF2YXxlY21hKXNjcmlwdC9pLHBhPS9edHJ1ZVwvKC4qKS8scWE9L15ccyo8ISg/OlxbQ0RBVEFcW3wtLSl8KD86XF1cXXwtLSk+XHMqJC9nLHJhPXtvcHRpb246WzEsIjxzZWxlY3QgbXVsdGlwbGU9J211bHRpcGxlJz4iLCI8L3NlbGVjdD4iXSxsZWdlbmQ6WzEsIjxmaWVsZHNldD4iLCI8L2ZpZWxkc2V0PiJdLGFyZWE6WzEsIjxtYXA+IiwiPC9tYXA+Il0scGFyYW06WzEsIjxvYmplY3Q+IiwiPC9vYmplY3Q+Il0sdGhlYWQ6WzEsIjx0YWJsZT4iLCI8L3RhYmxlPiJdLHRyOlsyLCI8dGFibGU+PHRib2R5PiIsIjwvdGJvZHk+PC90YWJsZT4iXSxjb2w6WzIsIjx0YWJsZT48dGJvZHk+PC90Ym9keT48Y29sZ3JvdXA+IiwiPC9jb2xncm91cD48L3RhYmxlPiJdLHRkOlszLCI8dGFibGU+PHRib2R5Pjx0cj4iLCI8L3RyPjwvdGJvZHk+PC90YWJsZT4iXSxfZGVmYXVsdDprLmh0bWxTZXJpYWxpemU/WzAsIiIsIiJdOlsxLCJYPGRpdj4iLCI8L2Rpdj4iXX0sc2E9ZGEoeSksdGE9c2EuYXBwZW5kQ2hpbGQoeS5jcmVhdGVFbGVtZW50KCJkaXYiKSk7cmEub3B0Z3JvdXA9cmEub3B0aW9uLHJhLnRib2R5PXJhLnRmb290PXJhLmNvbGdyb3VwPXJhLmNhcHRpb249cmEudGhlYWQscmEudGg9cmEudGQ7ZnVuY3Rpb24gdWEoYSxiKXt2YXIgYyxkLGU9MCxmPXR5cGVvZiBhLmdldEVsZW1lbnRzQnlUYWdOYW1lIT09Sz9hLmdldEVsZW1lbnRzQnlUYWdOYW1lKGJ8fCIqIik6dHlwZW9mIGEucXVlcnlTZWxlY3RvckFsbCE9PUs/YS5xdWVyeVNlbGVjdG9yQWxsKGJ8fCIqIik6dm9pZCAwO2lmKCFmKWZvcihmPVtdLGM9YS5jaGlsZE5vZGVzfHxhO251bGwhPShkPWNbZV0pO2UrKykhYnx8bS5ub2RlTmFtZShkLGIpP2YucHVzaChkKTptLm1lcmdlKGYsdWEoZCxiKSk7cmV0dXJuIHZvaWQgMD09PWJ8fGImJm0ubm9kZU5hbWUoYSxiKT9tLm1lcmdlKFthXSxmKTpmfWZ1bmN0aW9uIHZhKGEpe1cudGVzdChhLnR5cGUpJiYoYS5kZWZhdWx0Q2hlY2tlZD1hLmNoZWNrZWQpfWZ1bmN0aW9uIHdhKGEsYil7cmV0dXJuIG0ubm9kZU5hbWUoYSwidGFibGUiKSYmbS5ub2RlTmFtZSgxMSE9PWIubm9kZVR5cGU/YjpiLmZpcnN0Q2hpbGQsInRyIik/YS5nZXRFbGVtZW50c0J5VGFnTmFtZSgidGJvZHkiKVswXXx8YS5hcHBlbmRDaGlsZChhLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGJvZHkiKSk6YX1mdW5jdGlvbiB4YShhKXtyZXR1cm4gYS50eXBlPShudWxsIT09bS5maW5kLmF0dHIoYSwidHlwZSIpKSsiLyIrYS50eXBlLGF9ZnVuY3Rpb24geWEoYSl7dmFyIGI9cGEuZXhlYyhhLnR5cGUpO3JldHVybiBiP2EudHlwZT1iWzFdOmEucmVtb3ZlQXR0cmlidXRlKCJ0eXBlIiksYX1mdW5jdGlvbiB6YShhLGIpe2Zvcih2YXIgYyxkPTA7bnVsbCE9KGM9YVtkXSk7ZCsrKW0uX2RhdGEoYywiZ2xvYmFsRXZhbCIsIWJ8fG0uX2RhdGEoYltkXSwiZ2xvYmFsRXZhbCIpKX1mdW5jdGlvbiBBYShhLGIpe2lmKDE9PT1iLm5vZGVUeXBlJiZtLmhhc0RhdGEoYSkpe3ZhciBjLGQsZSxmPW0uX2RhdGEoYSksZz1tLl9kYXRhKGIsZiksaD1mLmV2ZW50cztpZihoKXtkZWxldGUgZy5oYW5kbGUsZy5ldmVudHM9e307Zm9yKGMgaW4gaClmb3IoZD0wLGU9aFtjXS5sZW5ndGg7ZT5kO2QrKyltLmV2ZW50LmFkZChiLGMsaFtjXVtkXSl9Zy5kYXRhJiYoZy5kYXRhPW0uZXh0ZW5kKHt9LGcuZGF0YSkpfX1mdW5jdGlvbiBCYShhLGIpe3ZhciBjLGQsZTtpZigxPT09Yi5ub2RlVHlwZSl7aWYoYz1iLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCksIWsubm9DbG9uZUV2ZW50JiZiW20uZXhwYW5kb10pe2U9bS5fZGF0YShiKTtmb3IoZCBpbiBlLmV2ZW50cyltLnJlbW92ZUV2ZW50KGIsZCxlLmhhbmRsZSk7Yi5yZW1vdmVBdHRyaWJ1dGUobS5leHBhbmRvKX0ic2NyaXB0Ij09PWMmJmIudGV4dCE9PWEudGV4dD8oeGEoYikudGV4dD1hLnRleHQseWEoYikpOiJvYmplY3QiPT09Yz8oYi5wYXJlbnROb2RlJiYoYi5vdXRlckhUTUw9YS5vdXRlckhUTUwpLGsuaHRtbDVDbG9uZSYmYS5pbm5lckhUTUwmJiFtLnRyaW0oYi5pbm5lckhUTUwpJiYoYi5pbm5lckhUTUw9YS5pbm5lckhUTUwpKToiaW5wdXQiPT09YyYmVy50ZXN0KGEudHlwZSk/KGIuZGVmYXVsdENoZWNrZWQ9Yi5jaGVja2VkPWEuY2hlY2tlZCxiLnZhbHVlIT09YS52YWx1ZSYmKGIudmFsdWU9YS52YWx1ZSkpOiJvcHRpb24iPT09Yz9iLmRlZmF1bHRTZWxlY3RlZD1iLnNlbGVjdGVkPWEuZGVmYXVsdFNlbGVjdGVkOigiaW5wdXQiPT09Y3x8InRleHRhcmVhIj09PWMpJiYoYi5kZWZhdWx0VmFsdWU9YS5kZWZhdWx0VmFsdWUpfX1tLmV4dGVuZCh7Y2xvbmU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkLGUsZixnLGgsaT1tLmNvbnRhaW5zKGEub3duZXJEb2N1bWVudCxhKTtpZihrLmh0bWw1Q2xvbmV8fG0uaXNYTUxEb2MoYSl8fCFnYS50ZXN0KCI8IithLm5vZGVOYW1lKyI+Iik/Zj1hLmNsb25lTm9kZSghMCk6KHRhLmlubmVySFRNTD1hLm91dGVySFRNTCx0YS5yZW1vdmVDaGlsZChmPXRhLmZpcnN0Q2hpbGQpKSwhKGsubm9DbG9uZUV2ZW50JiZrLm5vQ2xvbmVDaGVja2VkfHwxIT09YS5ub2RlVHlwZSYmMTEhPT1hLm5vZGVUeXBlfHxtLmlzWE1MRG9jKGEpKSlmb3IoZD11YShmKSxoPXVhKGEpLGc9MDtudWxsIT0oZT1oW2ddKTsrK2cpZFtnXSYmQmEoZSxkW2ddKTtpZihiKWlmKGMpZm9yKGg9aHx8dWEoYSksZD1kfHx1YShmKSxnPTA7bnVsbCE9KGU9aFtnXSk7ZysrKUFhKGUsZFtnXSk7ZWxzZSBBYShhLGYpO3JldHVybiBkPXVhKGYsInNjcmlwdCIpLGQubGVuZ3RoPjAmJnphKGQsIWkmJnVhKGEsInNjcmlwdCIpKSxkPWg9ZT1udWxsLGZ9LGJ1aWxkRnJhZ21lbnQ6ZnVuY3Rpb24oYSxiLGMsZCl7Zm9yKHZhciBlLGYsZyxoLGksaixsLG49YS5sZW5ndGgsbz1kYShiKSxwPVtdLHE9MDtuPnE7cSsrKWlmKGY9YVtxXSxmfHwwPT09ZilpZigib2JqZWN0Ij09PW0udHlwZShmKSltLm1lcmdlKHAsZi5ub2RlVHlwZT9bZl06Zik7ZWxzZSBpZihsYS50ZXN0KGYpKXtoPWh8fG8uYXBwZW5kQ2hpbGQoYi5jcmVhdGVFbGVtZW50KCJkaXYiKSksaT0oamEuZXhlYyhmKXx8WyIiLCIiXSlbMV0udG9Mb3dlckNhc2UoKSxsPXJhW2ldfHxyYS5fZGVmYXVsdCxoLmlubmVySFRNTD1sWzFdK2YucmVwbGFjZShpYSwiPCQxPjwvJDI+IikrbFsyXSxlPWxbMF07d2hpbGUoZS0tKWg9aC5sYXN0Q2hpbGQ7aWYoIWsubGVhZGluZ1doaXRlc3BhY2UmJmhhLnRlc3QoZikmJnAucHVzaChiLmNyZWF0ZVRleHROb2RlKGhhLmV4ZWMoZilbMF0pKSwhay50Ym9keSl7Zj0idGFibGUiIT09aXx8a2EudGVzdChmKT8iPHRhYmxlPiIhPT1sWzFdfHxrYS50ZXN0KGYpPzA6aDpoLmZpcnN0Q2hpbGQsZT1mJiZmLmNoaWxkTm9kZXMubGVuZ3RoO3doaWxlKGUtLSltLm5vZGVOYW1lKGo9Zi5jaGlsZE5vZGVzW2VdLCJ0Ym9keSIpJiYhai5jaGlsZE5vZGVzLmxlbmd0aCYmZi5yZW1vdmVDaGlsZChqKX1tLm1lcmdlKHAsaC5jaGlsZE5vZGVzKSxoLnRleHRDb250ZW50PSIiO3doaWxlKGguZmlyc3RDaGlsZCloLnJlbW92ZUNoaWxkKGguZmlyc3RDaGlsZCk7aD1vLmxhc3RDaGlsZH1lbHNlIHAucHVzaChiLmNyZWF0ZVRleHROb2RlKGYpKTtoJiZvLnJlbW92ZUNoaWxkKGgpLGsuYXBwZW5kQ2hlY2tlZHx8bS5ncmVwKHVhKHAsImlucHV0IiksdmEpLHE9MDt3aGlsZShmPXBbcSsrXSlpZigoIWR8fC0xPT09bS5pbkFycmF5KGYsZCkpJiYoZz1tLmNvbnRhaW5zKGYub3duZXJEb2N1bWVudCxmKSxoPXVhKG8uYXBwZW5kQ2hpbGQoZiksInNjcmlwdCIpLGcmJnphKGgpLGMpKXtlPTA7d2hpbGUoZj1oW2UrK10pb2EudGVzdChmLnR5cGV8fCIiKSYmYy5wdXNoKGYpfXJldHVybiBoPW51bGwsb30sY2xlYW5EYXRhOmZ1bmN0aW9uKGEsYil7Zm9yKHZhciBkLGUsZixnLGg9MCxpPW0uZXhwYW5kbyxqPW0uY2FjaGUsbD1rLmRlbGV0ZUV4cGFuZG8sbj1tLmV2ZW50LnNwZWNpYWw7bnVsbCE9KGQ9YVtoXSk7aCsrKWlmKChifHxtLmFjY2VwdERhdGEoZCkpJiYoZj1kW2ldLGc9ZiYmaltmXSkpe2lmKGcuZXZlbnRzKWZvcihlIGluIGcuZXZlbnRzKW5bZV0/bS5ldmVudC5yZW1vdmUoZCxlKTptLnJlbW92ZUV2ZW50KGQsZSxnLmhhbmRsZSk7altmXSYmKGRlbGV0ZSBqW2ZdLGw/ZGVsZXRlIGRbaV06dHlwZW9mIGQucmVtb3ZlQXR0cmlidXRlIT09Sz9kLnJlbW92ZUF0dHJpYnV0ZShpKTpkW2ldPW51bGwsYy5wdXNoKGYpKX19fSksbS5mbi5leHRlbmQoe3RleHQ6ZnVuY3Rpb24oYSl7cmV0dXJuIFYodGhpcyxmdW5jdGlvbihhKXtyZXR1cm4gdm9pZCAwPT09YT9tLnRleHQodGhpcyk6dGhpcy5lbXB0eSgpLmFwcGVuZCgodGhpc1swXSYmdGhpc1swXS5vd25lckRvY3VtZW50fHx5KS5jcmVhdGVUZXh0Tm9kZShhKSl9LG51bGwsYSxhcmd1bWVudHMubGVuZ3RoKX0sYXBwZW5kOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZG9tTWFuaXAoYXJndW1lbnRzLGZ1bmN0aW9uKGEpe2lmKDE9PT10aGlzLm5vZGVUeXBlfHwxMT09PXRoaXMubm9kZVR5cGV8fDk9PT10aGlzLm5vZGVUeXBlKXt2YXIgYj13YSh0aGlzLGEpO2IuYXBwZW5kQ2hpbGQoYSl9fSl9LHByZXBlbmQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kb21NYW5pcChhcmd1bWVudHMsZnVuY3Rpb24oYSl7aWYoMT09PXRoaXMubm9kZVR5cGV8fDExPT09dGhpcy5ub2RlVHlwZXx8OT09PXRoaXMubm9kZVR5cGUpe3ZhciBiPXdhKHRoaXMsYSk7Yi5pbnNlcnRCZWZvcmUoYSxiLmZpcnN0Q2hpbGQpfX0pfSxiZWZvcmU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kb21NYW5pcChhcmd1bWVudHMsZnVuY3Rpb24oYSl7dGhpcy5wYXJlbnROb2RlJiZ0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsdGhpcyl9KX0sYWZ0ZXI6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kb21NYW5pcChhcmd1bWVudHMsZnVuY3Rpb24oYSl7dGhpcy5wYXJlbnROb2RlJiZ0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsdGhpcy5uZXh0U2libGluZyl9KX0scmVtb3ZlOmZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjLGQ9YT9tLmZpbHRlcihhLHRoaXMpOnRoaXMsZT0wO251bGwhPShjPWRbZV0pO2UrKylifHwxIT09Yy5ub2RlVHlwZXx8bS5jbGVhbkRhdGEodWEoYykpLGMucGFyZW50Tm9kZSYmKGImJm0uY29udGFpbnMoYy5vd25lckRvY3VtZW50LGMpJiZ6YSh1YShjLCJzY3JpcHQiKSksYy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGMpKTtyZXR1cm4gdGhpc30sZW1wdHk6ZnVuY3Rpb24oKXtmb3IodmFyIGEsYj0wO251bGwhPShhPXRoaXNbYl0pO2IrKyl7MT09PWEubm9kZVR5cGUmJm0uY2xlYW5EYXRhKHVhKGEsITEpKTt3aGlsZShhLmZpcnN0Q2hpbGQpYS5yZW1vdmVDaGlsZChhLmZpcnN0Q2hpbGQpO2Eub3B0aW9ucyYmbS5ub2RlTmFtZShhLCJzZWxlY3QiKSYmKGEub3B0aW9ucy5sZW5ndGg9MCl9cmV0dXJuIHRoaXN9LGNsb25lOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9bnVsbD09YT8hMTphLGI9bnVsbD09Yj9hOmIsdGhpcy5tYXAoZnVuY3Rpb24oKXtyZXR1cm4gbS5jbG9uZSh0aGlzLGEsYil9KX0saHRtbDpmdW5jdGlvbihhKXtyZXR1cm4gVih0aGlzLGZ1bmN0aW9uKGEpe3ZhciBiPXRoaXNbMF18fHt9LGM9MCxkPXRoaXMubGVuZ3RoO2lmKHZvaWQgMD09PWEpcmV0dXJuIDE9PT1iLm5vZGVUeXBlP2IuaW5uZXJIVE1MLnJlcGxhY2UoZmEsIiIpOnZvaWQgMDtpZighKCJzdHJpbmciIT10eXBlb2YgYXx8bWEudGVzdChhKXx8IWsuaHRtbFNlcmlhbGl6ZSYmZ2EudGVzdChhKXx8IWsubGVhZGluZ1doaXRlc3BhY2UmJmhhLnRlc3QoYSl8fHJhWyhqYS5leGVjKGEpfHxbIiIsIiJdKVsxXS50b0xvd2VyQ2FzZSgpXSkpe2E9YS5yZXBsYWNlKGlhLCI8JDE+PC8kMj4iKTt0cnl7Zm9yKDtkPmM7YysrKWI9dGhpc1tjXXx8e30sMT09PWIubm9kZVR5cGUmJihtLmNsZWFuRGF0YSh1YShiLCExKSksYi5pbm5lckhUTUw9YSk7Yj0wfWNhdGNoKGUpe319YiYmdGhpcy5lbXB0eSgpLmFwcGVuZChhKX0sbnVsbCxhLGFyZ3VtZW50cy5sZW5ndGgpfSxyZXBsYWNlV2l0aDpmdW5jdGlvbigpe3ZhciBhPWFyZ3VtZW50c1swXTtyZXR1cm4gdGhpcy5kb21NYW5pcChhcmd1bWVudHMsZnVuY3Rpb24oYil7YT10aGlzLnBhcmVudE5vZGUsbS5jbGVhbkRhdGEodWEodGhpcykpLGEmJmEucmVwbGFjZUNoaWxkKGIsdGhpcyl9KSxhJiYoYS5sZW5ndGh8fGEubm9kZVR5cGUpP3RoaXM6dGhpcy5yZW1vdmUoKX0sZGV0YWNoOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnJlbW92ZShhLCEwKX0sZG9tTWFuaXA6ZnVuY3Rpb24oYSxiKXthPWUuYXBwbHkoW10sYSk7dmFyIGMsZCxmLGcsaCxpLGo9MCxsPXRoaXMubGVuZ3RoLG49dGhpcyxvPWwtMSxwPWFbMF0scT1tLmlzRnVuY3Rpb24ocCk7aWYocXx8bD4xJiYic3RyaW5nIj09dHlwZW9mIHAmJiFrLmNoZWNrQ2xvbmUmJm5hLnRlc3QocCkpcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihjKXt2YXIgZD1uLmVxKGMpO3EmJihhWzBdPXAuY2FsbCh0aGlzLGMsZC5odG1sKCkpKSxkLmRvbU1hbmlwKGEsYil9KTtpZihsJiYoaT1tLmJ1aWxkRnJhZ21lbnQoYSx0aGlzWzBdLm93bmVyRG9jdW1lbnQsITEsdGhpcyksYz1pLmZpcnN0Q2hpbGQsMT09PWkuY2hpbGROb2Rlcy5sZW5ndGgmJihpPWMpLGMpKXtmb3IoZz1tLm1hcCh1YShpLCJzY3JpcHQiKSx4YSksZj1nLmxlbmd0aDtsPmo7aisrKWQ9aSxqIT09byYmKGQ9bS5jbG9uZShkLCEwLCEwKSxmJiZtLm1lcmdlKGcsdWEoZCwic2NyaXB0IikpKSxiLmNhbGwodGhpc1tqXSxkLGopO2lmKGYpZm9yKGg9Z1tnLmxlbmd0aC0xXS5vd25lckRvY3VtZW50LG0ubWFwKGcseWEpLGo9MDtmPmo7aisrKWQ9Z1tqXSxvYS50ZXN0KGQudHlwZXx8IiIpJiYhbS5fZGF0YShkLCJnbG9iYWxFdmFsIikmJm0uY29udGFpbnMoaCxkKSYmKGQuc3JjP20uX2V2YWxVcmwmJm0uX2V2YWxVcmwoZC5zcmMpOm0uZ2xvYmFsRXZhbCgoZC50ZXh0fHxkLnRleHRDb250ZW50fHxkLmlubmVySFRNTHx8IiIpLnJlcGxhY2UocWEsIiIpKSk7aT1jPW51bGx9cmV0dXJuIHRoaXN9fSksbS5lYWNoKHthcHBlbmRUbzoiYXBwZW5kIixwcmVwZW5kVG86InByZXBlbmQiLGluc2VydEJlZm9yZToiYmVmb3JlIixpbnNlcnRBZnRlcjoiYWZ0ZXIiLHJlcGxhY2VBbGw6InJlcGxhY2VXaXRoIn0sZnVuY3Rpb24oYSxiKXttLmZuW2FdPWZ1bmN0aW9uKGEpe2Zvcih2YXIgYyxkPTAsZT1bXSxnPW0oYSksaD1nLmxlbmd0aC0xO2g+PWQ7ZCsrKWM9ZD09PWg/dGhpczp0aGlzLmNsb25lKCEwKSxtKGdbZF0pW2JdKGMpLGYuYXBwbHkoZSxjLmdldCgpKTtyZXR1cm4gdGhpcy5wdXNoU3RhY2soZSl9fSk7dmFyIENhLERhPXt9O2Z1bmN0aW9uIEVhKGIsYyl7dmFyIGQsZT1tKGMuY3JlYXRlRWxlbWVudChiKSkuYXBwZW5kVG8oYy5ib2R5KSxmPWEuZ2V0RGVmYXVsdENvbXB1dGVkU3R5bGUmJihkPWEuZ2V0RGVmYXVsdENvbXB1dGVkU3R5bGUoZVswXSkpP2QuZGlzcGxheTptLmNzcyhlWzBdLCJkaXNwbGF5Iik7cmV0dXJuIGUuZGV0YWNoKCksZn1mdW5jdGlvbiBGYShhKXt2YXIgYj15LGM9RGFbYV07cmV0dXJuIGN8fChjPUVhKGEsYiksIm5vbmUiIT09YyYmY3x8KENhPShDYXx8bSgiPGlmcmFtZSBmcmFtZWJvcmRlcj0nMCcgd2lkdGg9JzAnIGhlaWdodD0nMCcvPiIpKS5hcHBlbmRUbyhiLmRvY3VtZW50RWxlbWVudCksYj0oQ2FbMF0uY29udGVudFdpbmRvd3x8Q2FbMF0uY29udGVudERvY3VtZW50KS5kb2N1bWVudCxiLndyaXRlKCksYi5jbG9zZSgpLGM9RWEoYSxiKSxDYS5kZXRhY2goKSksRGFbYV09YyksY30hZnVuY3Rpb24oKXt2YXIgYTtrLnNocmlua1dyYXBCbG9ja3M9ZnVuY3Rpb24oKXtpZihudWxsIT1hKXJldHVybiBhO2E9ITE7dmFyIGIsYyxkO3JldHVybiBjPXkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImJvZHkiKVswXSxjJiZjLnN0eWxlPyhiPXkuY3JlYXRlRWxlbWVudCgiZGl2IiksZD15LmNyZWF0ZUVsZW1lbnQoImRpdiIpLGQuc3R5bGUuY3NzVGV4dD0icG9zaXRpb246YWJzb2x1dGU7Ym9yZGVyOjA7d2lkdGg6MDtoZWlnaHQ6MDt0b3A6MDtsZWZ0Oi05OTk5cHgiLGMuYXBwZW5kQ2hpbGQoZCkuYXBwZW5kQ2hpbGQoYiksdHlwZW9mIGIuc3R5bGUuem9vbSE9PUsmJihiLnN0eWxlLmNzc1RleHQ9Ii13ZWJraXQtYm94LXNpemluZzpjb250ZW50LWJveDstbW96LWJveC1zaXppbmc6Y29udGVudC1ib3g7Ym94LXNpemluZzpjb250ZW50LWJveDtkaXNwbGF5OmJsb2NrO21hcmdpbjowO2JvcmRlcjowO3BhZGRpbmc6MXB4O3dpZHRoOjFweDt6b29tOjEiLGIuYXBwZW5kQ2hpbGQoeS5jcmVhdGVFbGVtZW50KCJkaXYiKSkuc3R5bGUud2lkdGg9IjVweCIsYT0zIT09Yi5vZmZzZXRXaWR0aCksYy5yZW1vdmVDaGlsZChkKSxhKTp2b2lkIDB9fSgpO3ZhciBHYT0vXm1hcmdpbi8sSGE9bmV3IFJlZ0V4cCgiXigiK1MrIikoPyFweClbYS16JV0rJCIsImkiKSxJYSxKYSxLYT0vXih0b3B8cmlnaHR8Ym90dG9tfGxlZnQpJC87YS5nZXRDb21wdXRlZFN0eWxlPyhJYT1mdW5jdGlvbihiKXtyZXR1cm4gYi5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3Lm9wZW5lcj9iLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShiLG51bGwpOmEuZ2V0Q29tcHV0ZWRTdHlsZShiLG51bGwpfSxKYT1mdW5jdGlvbihhLGIsYyl7dmFyIGQsZSxmLGcsaD1hLnN0eWxlO3JldHVybiBjPWN8fElhKGEpLGc9Yz9jLmdldFByb3BlcnR5VmFsdWUoYil8fGNbYl06dm9pZCAwLGMmJigiIiE9PWd8fG0uY29udGFpbnMoYS5vd25lckRvY3VtZW50LGEpfHwoZz1tLnN0eWxlKGEsYikpLEhhLnRlc3QoZykmJkdhLnRlc3QoYikmJihkPWgud2lkdGgsZT1oLm1pbldpZHRoLGY9aC5tYXhXaWR0aCxoLm1pbldpZHRoPWgubWF4V2lkdGg9aC53aWR0aD1nLGc9Yy53aWR0aCxoLndpZHRoPWQsaC5taW5XaWR0aD1lLGgubWF4V2lkdGg9ZikpLHZvaWQgMD09PWc/ZzpnKyIifSk6eS5kb2N1bWVudEVsZW1lbnQuY3VycmVudFN0eWxlJiYoSWE9ZnVuY3Rpb24oYSl7cmV0dXJuIGEuY3VycmVudFN0eWxlfSxKYT1mdW5jdGlvbihhLGIsYyl7dmFyIGQsZSxmLGcsaD1hLnN0eWxlO3JldHVybiBjPWN8fElhKGEpLGc9Yz9jW2JdOnZvaWQgMCxudWxsPT1nJiZoJiZoW2JdJiYoZz1oW2JdKSxIYS50ZXN0KGcpJiYhS2EudGVzdChiKSYmKGQ9aC5sZWZ0LGU9YS5ydW50aW1lU3R5bGUsZj1lJiZlLmxlZnQsZiYmKGUubGVmdD1hLmN1cnJlbnRTdHlsZS5sZWZ0KSxoLmxlZnQ9ImZvbnRTaXplIj09PWI/IjFlbSI6ZyxnPWgucGl4ZWxMZWZ0KyJweCIsaC5sZWZ0PWQsZiYmKGUubGVmdD1mKSksdm9pZCAwPT09Zz9nOmcrIiJ8fCJhdXRvIn0pO2Z1bmN0aW9uIExhKGEsYil7cmV0dXJue2dldDpmdW5jdGlvbigpe3ZhciBjPWEoKTtpZihudWxsIT1jKXJldHVybiBjP3ZvaWQgZGVsZXRlIHRoaXMuZ2V0Oih0aGlzLmdldD1iKS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fX0hZnVuY3Rpb24oKXt2YXIgYixjLGQsZSxmLGcsaDtpZihiPXkuY3JlYXRlRWxlbWVudCgiZGl2IiksYi5pbm5lckhUTUw9IiAgPGxpbmsvPjx0YWJsZT48L3RhYmxlPjxhIGhyZWY9Jy9hJz5hPC9hPjxpbnB1dCB0eXBlPSdjaGVja2JveCcvPiIsZD1iLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhIilbMF0sYz1kJiZkLnN0eWxlKXtjLmNzc1RleHQ9ImZsb2F0OmxlZnQ7b3BhY2l0eTouNSIsay5vcGFjaXR5PSIwLjUiPT09Yy5vcGFjaXR5LGsuY3NzRmxvYXQ9ISFjLmNzc0Zsb2F0LGIuc3R5bGUuYmFja2dyb3VuZENsaXA9ImNvbnRlbnQtYm94IixiLmNsb25lTm9kZSghMCkuc3R5bGUuYmFja2dyb3VuZENsaXA9IiIsay5jbGVhckNsb25lU3R5bGU9ImNvbnRlbnQtYm94Ij09PWIuc3R5bGUuYmFja2dyb3VuZENsaXAsay5ib3hTaXppbmc9IiI9PT1jLmJveFNpemluZ3x8IiI9PT1jLk1vekJveFNpemluZ3x8IiI9PT1jLldlYmtpdEJveFNpemluZyxtLmV4dGVuZChrLHtyZWxpYWJsZUhpZGRlbk9mZnNldHM6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbD09ZyYmaSgpLGd9LGJveFNpemluZ1JlbGlhYmxlOmZ1bmN0aW9uKCl7cmV0dXJuIG51bGw9PWYmJmkoKSxmfSxwaXhlbFBvc2l0aW9uOmZ1bmN0aW9uKCl7cmV0dXJuIG51bGw9PWUmJmkoKSxlfSxyZWxpYWJsZU1hcmdpblJpZ2h0OmZ1bmN0aW9uKCl7cmV0dXJuIG51bGw9PWgmJmkoKSxofX0pO2Z1bmN0aW9uIGkoKXt2YXIgYixjLGQsaTtjPXkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImJvZHkiKVswXSxjJiZjLnN0eWxlJiYoYj15LmNyZWF0ZUVsZW1lbnQoImRpdiIpLGQ9eS5jcmVhdGVFbGVtZW50KCJkaXYiKSxkLnN0eWxlLmNzc1RleHQ9InBvc2l0aW9uOmFic29sdXRlO2JvcmRlcjowO3dpZHRoOjA7aGVpZ2h0OjA7dG9wOjA7bGVmdDotOTk5OXB4IixjLmFwcGVuZENoaWxkKGQpLmFwcGVuZENoaWxkKGIpLGIuc3R5bGUuY3NzVGV4dD0iLXdlYmtpdC1ib3gtc2l6aW5nOmJvcmRlci1ib3g7LW1vei1ib3gtc2l6aW5nOmJvcmRlci1ib3g7Ym94LXNpemluZzpib3JkZXItYm94O2Rpc3BsYXk6YmxvY2s7bWFyZ2luLXRvcDoxJTt0b3A6MSU7Ym9yZGVyOjFweDtwYWRkaW5nOjFweDt3aWR0aDo0cHg7cG9zaXRpb246YWJzb2x1dGUiLGU9Zj0hMSxoPSEwLGEuZ2V0Q29tcHV0ZWRTdHlsZSYmKGU9IjElIiE9PShhLmdldENvbXB1dGVkU3R5bGUoYixudWxsKXx8e30pLnRvcCxmPSI0cHgiPT09KGEuZ2V0Q29tcHV0ZWRTdHlsZShiLG51bGwpfHx7d2lkdGg6IjRweCJ9KS53aWR0aCxpPWIuYXBwZW5kQ2hpbGQoeS5jcmVhdGVFbGVtZW50KCJkaXYiKSksaS5zdHlsZS5jc3NUZXh0PWIuc3R5bGUuY3NzVGV4dD0iLXdlYmtpdC1ib3gtc2l6aW5nOmNvbnRlbnQtYm94Oy1tb3otYm94LXNpemluZzpjb250ZW50LWJveDtib3gtc2l6aW5nOmNvbnRlbnQtYm94O2Rpc3BsYXk6YmxvY2s7bWFyZ2luOjA7Ym9yZGVyOjA7cGFkZGluZzowIixpLnN0eWxlLm1hcmdpblJpZ2h0PWkuc3R5bGUud2lkdGg9IjAiLGIuc3R5bGUud2lkdGg9IjFweCIsaD0hcGFyc2VGbG9hdCgoYS5nZXRDb21wdXRlZFN0eWxlKGksbnVsbCl8fHt9KS5tYXJnaW5SaWdodCksYi5yZW1vdmVDaGlsZChpKSksYi5pbm5lckhUTUw9Ijx0YWJsZT48dHI+PHRkPjwvdGQ+PHRkPnQ8L3RkPjwvdHI+PC90YWJsZT4iLGk9Yi5nZXRFbGVtZW50c0J5VGFnTmFtZSgidGQiKSxpWzBdLnN0eWxlLmNzc1RleHQ9Im1hcmdpbjowO2JvcmRlcjowO3BhZGRpbmc6MDtkaXNwbGF5Om5vbmUiLGc9MD09PWlbMF0ub2Zmc2V0SGVpZ2h0LGcmJihpWzBdLnN0eWxlLmRpc3BsYXk9IiIsaVsxXS5zdHlsZS5kaXNwbGF5PSJub25lIixnPTA9PT1pWzBdLm9mZnNldEhlaWdodCksYy5yZW1vdmVDaGlsZChkKSl9fX0oKSxtLnN3YXA9ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGUsZixnPXt9O2ZvcihmIGluIGIpZ1tmXT1hLnN0eWxlW2ZdLGEuc3R5bGVbZl09YltmXTtlPWMuYXBwbHkoYSxkfHxbXSk7Zm9yKGYgaW4gYilhLnN0eWxlW2ZdPWdbZl07cmV0dXJuIGV9O3ZhciBNYT0vYWxwaGFcKFteKV0qXCkvaSxOYT0vb3BhY2l0eVxzKj1ccyooW14pXSopLyxPYT0vXihub25lfHRhYmxlKD8hLWNbZWFdKS4rKS8sUGE9bmV3IFJlZ0V4cCgiXigiK1MrIikoLiopJCIsImkiKSxRYT1uZXcgUmVnRXhwKCJeKFsrLV0pPSgiK1MrIikiLCJpIiksUmE9e3Bvc2l0aW9uOiJhYnNvbHV0ZSIsdmlzaWJpbGl0eToiaGlkZGVuIixkaXNwbGF5OiJibG9jayJ9LFNhPXtsZXR0ZXJTcGFjaW5nOiIwIixmb250V2VpZ2h0OiI0MDAifSxUYT1bIldlYmtpdCIsIk8iLCJNb3oiLCJtcyJdO2Z1bmN0aW9uIFVhKGEsYil7aWYoYiBpbiBhKXJldHVybiBiO3ZhciBjPWIuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrYi5zbGljZSgxKSxkPWIsZT1UYS5sZW5ndGg7d2hpbGUoZS0tKWlmKGI9VGFbZV0rYyxiIGluIGEpcmV0dXJuIGI7cmV0dXJuIGR9ZnVuY3Rpb24gVmEoYSxiKXtmb3IodmFyIGMsZCxlLGY9W10sZz0wLGg9YS5sZW5ndGg7aD5nO2crKylkPWFbZ10sZC5zdHlsZSYmKGZbZ109bS5fZGF0YShkLCJvbGRkaXNwbGF5IiksYz1kLnN0eWxlLmRpc3BsYXksYj8oZltnXXx8Im5vbmUiIT09Y3x8KGQuc3R5bGUuZGlzcGxheT0iIiksIiI9PT1kLnN0eWxlLmRpc3BsYXkmJlUoZCkmJihmW2ddPW0uX2RhdGEoZCwib2xkZGlzcGxheSIsRmEoZC5ub2RlTmFtZSkpKSk6KGU9VShkKSwoYyYmIm5vbmUiIT09Y3x8IWUpJiZtLl9kYXRhKGQsIm9sZGRpc3BsYXkiLGU/YzptLmNzcyhkLCJkaXNwbGF5IikpKSk7Zm9yKGc9MDtoPmc7ZysrKWQ9YVtnXSxkLnN0eWxlJiYoYiYmIm5vbmUiIT09ZC5zdHlsZS5kaXNwbGF5JiYiIiE9PWQuc3R5bGUuZGlzcGxheXx8KGQuc3R5bGUuZGlzcGxheT1iP2ZbZ118fCIiOiJub25lIikpO3JldHVybiBhfWZ1bmN0aW9uIFdhKGEsYixjKXt2YXIgZD1QYS5leGVjKGIpO3JldHVybiBkP01hdGgubWF4KDAsZFsxXS0oY3x8MCkpKyhkWzJdfHwicHgiKTpifWZ1bmN0aW9uIFhhKGEsYixjLGQsZSl7Zm9yKHZhciBmPWM9PT0oZD8iYm9yZGVyIjoiY29udGVudCIpPzQ6IndpZHRoIj09PWI/MTowLGc9MDs0PmY7Zis9MikibWFyZ2luIj09PWMmJihnKz1tLmNzcyhhLGMrVFtmXSwhMCxlKSksZD8oImNvbnRlbnQiPT09YyYmKGctPW0uY3NzKGEsInBhZGRpbmciK1RbZl0sITAsZSkpLCJtYXJnaW4iIT09YyYmKGctPW0uY3NzKGEsImJvcmRlciIrVFtmXSsiV2lkdGgiLCEwLGUpKSk6KGcrPW0uY3NzKGEsInBhZGRpbmciK1RbZl0sITAsZSksInBhZGRpbmciIT09YyYmKGcrPW0uY3NzKGEsImJvcmRlciIrVFtmXSsiV2lkdGgiLCEwLGUpKSk7cmV0dXJuIGd9ZnVuY3Rpb24gWWEoYSxiLGMpe3ZhciBkPSEwLGU9IndpZHRoIj09PWI/YS5vZmZzZXRXaWR0aDphLm9mZnNldEhlaWdodCxmPUlhKGEpLGc9ay5ib3hTaXppbmcmJiJib3JkZXItYm94Ij09PW0uY3NzKGEsImJveFNpemluZyIsITEsZik7aWYoMD49ZXx8bnVsbD09ZSl7aWYoZT1KYShhLGIsZiksKDA+ZXx8bnVsbD09ZSkmJihlPWEuc3R5bGVbYl0pLEhhLnRlc3QoZSkpcmV0dXJuIGU7ZD1nJiYoay5ib3hTaXppbmdSZWxpYWJsZSgpfHxlPT09YS5zdHlsZVtiXSksZT1wYXJzZUZsb2F0KGUpfHwwfXJldHVybiBlK1hhKGEsYixjfHwoZz8iYm9yZGVyIjoiY29udGVudCIpLGQsZikrInB4In1tLmV4dGVuZCh7Y3NzSG9va3M6e29wYWNpdHk6e2dldDpmdW5jdGlvbihhLGIpe2lmKGIpe3ZhciBjPUphKGEsIm9wYWNpdHkiKTtyZXR1cm4iIj09PWM/IjEiOmN9fX19LGNzc051bWJlcjp7Y29sdW1uQ291bnQ6ITAsZmlsbE9wYWNpdHk6ITAsZmxleEdyb3c6ITAsZmxleFNocmluazohMCxmb250V2VpZ2h0OiEwLGxpbmVIZWlnaHQ6ITAsb3BhY2l0eTohMCxvcmRlcjohMCxvcnBoYW5zOiEwLHdpZG93czohMCx6SW5kZXg6ITAsem9vbTohMH0sY3NzUHJvcHM6eyJmbG9hdCI6ay5jc3NGbG9hdD8iY3NzRmxvYXQiOiJzdHlsZUZsb2F0In0sc3R5bGU6ZnVuY3Rpb24oYSxiLGMsZCl7aWYoYSYmMyE9PWEubm9kZVR5cGUmJjghPT1hLm5vZGVUeXBlJiZhLnN0eWxlKXt2YXIgZSxmLGcsaD1tLmNhbWVsQ2FzZShiKSxpPWEuc3R5bGU7aWYoYj1tLmNzc1Byb3BzW2hdfHwobS5jc3NQcm9wc1toXT1VYShpLGgpKSxnPW0uY3NzSG9va3NbYl18fG0uY3NzSG9va3NbaF0sdm9pZCAwPT09YylyZXR1cm4gZyYmImdldCJpbiBnJiZ2b2lkIDAhPT0oZT1nLmdldChhLCExLGQpKT9lOmlbYl07aWYoZj10eXBlb2YgYywic3RyaW5nIj09PWYmJihlPVFhLmV4ZWMoYykpJiYoYz0oZVsxXSsxKSplWzJdK3BhcnNlRmxvYXQobS5jc3MoYSxiKSksZj0ibnVtYmVyIiksbnVsbCE9YyYmYz09PWMmJigibnVtYmVyIiE9PWZ8fG0uY3NzTnVtYmVyW2hdfHwoYys9InB4Iiksay5jbGVhckNsb25lU3R5bGV8fCIiIT09Y3x8MCE9PWIuaW5kZXhPZigiYmFja2dyb3VuZCIpfHwoaVtiXT0iaW5oZXJpdCIpLCEoZyYmInNldCJpbiBnJiZ2b2lkIDA9PT0oYz1nLnNldChhLGMsZCkpKSkpdHJ5e2lbYl09Y31jYXRjaChqKXt9fX0sY3NzOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlLGYsZyxoPW0uY2FtZWxDYXNlKGIpO3JldHVybiBiPW0uY3NzUHJvcHNbaF18fChtLmNzc1Byb3BzW2hdPVVhKGEuc3R5bGUsaCkpLGc9bS5jc3NIb29rc1tiXXx8bS5jc3NIb29rc1toXSxnJiYiZ2V0ImluIGcmJihmPWcuZ2V0KGEsITAsYykpLHZvaWQgMD09PWYmJihmPUphKGEsYixkKSksIm5vcm1hbCI9PT1mJiZiIGluIFNhJiYoZj1TYVtiXSksIiI9PT1jfHxjPyhlPXBhcnNlRmxvYXQoZiksYz09PSEwfHxtLmlzTnVtZXJpYyhlKT9lfHwwOmYpOmZ9fSksbS5lYWNoKFsiaGVpZ2h0Iiwid2lkdGgiXSxmdW5jdGlvbihhLGIpe20uY3NzSG9va3NbYl09e2dldDpmdW5jdGlvbihhLGMsZCl7cmV0dXJuIGM/T2EudGVzdChtLmNzcyhhLCJkaXNwbGF5IikpJiYwPT09YS5vZmZzZXRXaWR0aD9tLnN3YXAoYSxSYSxmdW5jdGlvbigpe3JldHVybiBZYShhLGIsZCl9KTpZYShhLGIsZCk6dm9pZCAwfSxzZXQ6ZnVuY3Rpb24oYSxjLGQpe3ZhciBlPWQmJklhKGEpO3JldHVybiBXYShhLGMsZD9YYShhLGIsZCxrLmJveFNpemluZyYmImJvcmRlci1ib3giPT09bS5jc3MoYSwiYm94U2l6aW5nIiwhMSxlKSxlKTowKX19fSksay5vcGFjaXR5fHwobS5jc3NIb29rcy5vcGFjaXR5PXtnZXQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gTmEudGVzdCgoYiYmYS5jdXJyZW50U3R5bGU/YS5jdXJyZW50U3R5bGUuZmlsdGVyOmEuc3R5bGUuZmlsdGVyKXx8IiIpPy4wMSpwYXJzZUZsb2F0KFJlZ0V4cC4kMSkrIiI6Yj8iMSI6IiJ9LHNldDpmdW5jdGlvbihhLGIpe3ZhciBjPWEuc3R5bGUsZD1hLmN1cnJlbnRTdHlsZSxlPW0uaXNOdW1lcmljKGIpPyJhbHBoYShvcGFjaXR5PSIrMTAwKmIrIikiOiIiLGY9ZCYmZC5maWx0ZXJ8fGMuZmlsdGVyfHwiIjtjLnpvb209MSwoYj49MXx8IiI9PT1iKSYmIiI9PT1tLnRyaW0oZi5yZXBsYWNlKE1hLCIiKSkmJmMucmVtb3ZlQXR0cmlidXRlJiYoYy5yZW1vdmVBdHRyaWJ1dGUoImZpbHRlciIpLCIiPT09Ynx8ZCYmIWQuZmlsdGVyKXx8KGMuZmlsdGVyPU1hLnRlc3QoZik/Zi5yZXBsYWNlKE1hLGUpOmYrIiAiK2UpfX0pLG0uY3NzSG9va3MubWFyZ2luUmlnaHQ9TGEoay5yZWxpYWJsZU1hcmdpblJpZ2h0LGZ1bmN0aW9uKGEsYil7cmV0dXJuIGI/bS5zd2FwKGEse2Rpc3BsYXk6ImlubGluZS1ibG9jayJ9LEphLFthLCJtYXJnaW5SaWdodCJdKTp2b2lkIDB9KSxtLmVhY2goe21hcmdpbjoiIixwYWRkaW5nOiIiLGJvcmRlcjoiV2lkdGgifSxmdW5jdGlvbihhLGIpe20uY3NzSG9va3NbYStiXT17ZXhwYW5kOmZ1bmN0aW9uKGMpe2Zvcih2YXIgZD0wLGU9e30sZj0ic3RyaW5nIj09dHlwZW9mIGM/Yy5zcGxpdCgiICIpOltjXTs0PmQ7ZCsrKWVbYStUW2RdK2JdPWZbZF18fGZbZC0yXXx8ZlswXTtyZXR1cm4gZX19LEdhLnRlc3QoYSl8fChtLmNzc0hvb2tzW2ErYl0uc2V0PVdhKX0pLG0uZm4uZXh0ZW5kKHtjc3M6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gVih0aGlzLGZ1bmN0aW9uKGEsYixjKXt2YXIgZCxlLGY9e30sZz0wO2lmKG0uaXNBcnJheShiKSl7Zm9yKGQ9SWEoYSksZT1iLmxlbmd0aDtlPmc7ZysrKWZbYltnXV09bS5jc3MoYSxiW2ddLCExLGQpO3JldHVybiBmfXJldHVybiB2b2lkIDAhPT1jP20uc3R5bGUoYSxiLGMpOm0uY3NzKGEsYil9LGEsYixhcmd1bWVudHMubGVuZ3RoPjEpfSxzaG93OmZ1bmN0aW9uKCl7cmV0dXJuIFZhKHRoaXMsITApfSxoaWRlOmZ1bmN0aW9uKCl7cmV0dXJuIFZhKHRoaXMpfSx0b2dnbGU6ZnVuY3Rpb24oYSl7cmV0dXJuImJvb2xlYW4iPT10eXBlb2YgYT9hP3RoaXMuc2hvdygpOnRoaXMuaGlkZSgpOnRoaXMuZWFjaChmdW5jdGlvbigpe1UodGhpcyk/bSh0aGlzKS5zaG93KCk6bSh0aGlzKS5oaWRlKCl9KX19KTtmdW5jdGlvbiBaYShhLGIsYyxkLGUpewpyZXR1cm4gbmV3IFphLnByb3RvdHlwZS5pbml0KGEsYixjLGQsZSl9bS5Ud2Vlbj1aYSxaYS5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOlphLGluaXQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3RoaXMuZWxlbT1hLHRoaXMucHJvcD1jLHRoaXMuZWFzaW5nPWV8fCJzd2luZyIsdGhpcy5vcHRpb25zPWIsdGhpcy5zdGFydD10aGlzLm5vdz10aGlzLmN1cigpLHRoaXMuZW5kPWQsdGhpcy51bml0PWZ8fChtLmNzc051bWJlcltjXT8iIjoicHgiKX0sY3VyOmZ1bmN0aW9uKCl7dmFyIGE9WmEucHJvcEhvb2tzW3RoaXMucHJvcF07cmV0dXJuIGEmJmEuZ2V0P2EuZ2V0KHRoaXMpOlphLnByb3BIb29rcy5fZGVmYXVsdC5nZXQodGhpcyl9LHJ1bjpmdW5jdGlvbihhKXt2YXIgYixjPVphLnByb3BIb29rc1t0aGlzLnByb3BdO3JldHVybiB0aGlzLm9wdGlvbnMuZHVyYXRpb24/dGhpcy5wb3M9Yj1tLmVhc2luZ1t0aGlzLmVhc2luZ10oYSx0aGlzLm9wdGlvbnMuZHVyYXRpb24qYSwwLDEsdGhpcy5vcHRpb25zLmR1cmF0aW9uKTp0aGlzLnBvcz1iPWEsdGhpcy5ub3c9KHRoaXMuZW5kLXRoaXMuc3RhcnQpKmIrdGhpcy5zdGFydCx0aGlzLm9wdGlvbnMuc3RlcCYmdGhpcy5vcHRpb25zLnN0ZXAuY2FsbCh0aGlzLmVsZW0sdGhpcy5ub3csdGhpcyksYyYmYy5zZXQ/Yy5zZXQodGhpcyk6WmEucHJvcEhvb2tzLl9kZWZhdWx0LnNldCh0aGlzKSx0aGlzfX0sWmEucHJvdG90eXBlLmluaXQucHJvdG90eXBlPVphLnByb3RvdHlwZSxaYS5wcm9wSG9va3M9e19kZWZhdWx0OntnZXQ6ZnVuY3Rpb24oYSl7dmFyIGI7cmV0dXJuIG51bGw9PWEuZWxlbVthLnByb3BdfHxhLmVsZW0uc3R5bGUmJm51bGwhPWEuZWxlbS5zdHlsZVthLnByb3BdPyhiPW0uY3NzKGEuZWxlbSxhLnByb3AsIiIpLGImJiJhdXRvIiE9PWI/YjowKTphLmVsZW1bYS5wcm9wXX0sc2V0OmZ1bmN0aW9uKGEpe20uZnguc3RlcFthLnByb3BdP20uZnguc3RlcFthLnByb3BdKGEpOmEuZWxlbS5zdHlsZSYmKG51bGwhPWEuZWxlbS5zdHlsZVttLmNzc1Byb3BzW2EucHJvcF1dfHxtLmNzc0hvb2tzW2EucHJvcF0pP20uc3R5bGUoYS5lbGVtLGEucHJvcCxhLm5vdythLnVuaXQpOmEuZWxlbVthLnByb3BdPWEubm93fX19LFphLnByb3BIb29rcy5zY3JvbGxUb3A9WmEucHJvcEhvb2tzLnNjcm9sbExlZnQ9e3NldDpmdW5jdGlvbihhKXthLmVsZW0ubm9kZVR5cGUmJmEuZWxlbS5wYXJlbnROb2RlJiYoYS5lbGVtW2EucHJvcF09YS5ub3cpfX0sbS5lYXNpbmc9e2xpbmVhcjpmdW5jdGlvbihhKXtyZXR1cm4gYX0sc3dpbmc6ZnVuY3Rpb24oYSl7cmV0dXJuLjUtTWF0aC5jb3MoYSpNYXRoLlBJKS8yfX0sbS5meD1aYS5wcm90b3R5cGUuaW5pdCxtLmZ4LnN0ZXA9e307dmFyICRhLF9hLGFiPS9eKD86dG9nZ2xlfHNob3d8aGlkZSkkLyxiYj1uZXcgUmVnRXhwKCJeKD86KFsrLV0pPXwpKCIrUysiKShbYS16JV0qKSQiLCJpIiksY2I9L3F1ZXVlSG9va3MkLyxkYj1baWJdLGViPXsiKiI6W2Z1bmN0aW9uKGEsYil7dmFyIGM9dGhpcy5jcmVhdGVUd2VlbihhLGIpLGQ9Yy5jdXIoKSxlPWJiLmV4ZWMoYiksZj1lJiZlWzNdfHwobS5jc3NOdW1iZXJbYV0/IiI6InB4IiksZz0obS5jc3NOdW1iZXJbYV18fCJweCIhPT1mJiYrZCkmJmJiLmV4ZWMobS5jc3MoYy5lbGVtLGEpKSxoPTEsaT0yMDtpZihnJiZnWzNdIT09Zil7Zj1mfHxnWzNdLGU9ZXx8W10sZz0rZHx8MTtkbyBoPWh8fCIuNSIsZy89aCxtLnN0eWxlKGMuZWxlbSxhLGcrZik7d2hpbGUoaCE9PShoPWMuY3VyKCkvZCkmJjEhPT1oJiYtLWkpfXJldHVybiBlJiYoZz1jLnN0YXJ0PStnfHwrZHx8MCxjLnVuaXQ9ZixjLmVuZD1lWzFdP2crKGVbMV0rMSkqZVsyXTorZVsyXSksY31dfTtmdW5jdGlvbiBmYigpe3JldHVybiBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7JGE9dm9pZCAwfSksJGE9bS5ub3coKX1mdW5jdGlvbiBnYihhLGIpe3ZhciBjLGQ9e2hlaWdodDphfSxlPTA7Zm9yKGI9Yj8xOjA7ND5lO2UrPTItYiljPVRbZV0sZFsibWFyZ2luIitjXT1kWyJwYWRkaW5nIitjXT1hO3JldHVybiBiJiYoZC5vcGFjaXR5PWQud2lkdGg9YSksZH1mdW5jdGlvbiBoYihhLGIsYyl7Zm9yKHZhciBkLGU9KGViW2JdfHxbXSkuY29uY2F0KGViWyIqIl0pLGY9MCxnPWUubGVuZ3RoO2c+ZjtmKyspaWYoZD1lW2ZdLmNhbGwoYyxiLGEpKXJldHVybiBkfWZ1bmN0aW9uIGliKGEsYixjKXt2YXIgZCxlLGYsZyxoLGksaixsLG49dGhpcyxvPXt9LHA9YS5zdHlsZSxxPWEubm9kZVR5cGUmJlUoYSkscj1tLl9kYXRhKGEsImZ4c2hvdyIpO2MucXVldWV8fChoPW0uX3F1ZXVlSG9va3MoYSwiZngiKSxudWxsPT1oLnVucXVldWVkJiYoaC51bnF1ZXVlZD0wLGk9aC5lbXB0eS5maXJlLGguZW1wdHkuZmlyZT1mdW5jdGlvbigpe2gudW5xdWV1ZWR8fGkoKX0pLGgudW5xdWV1ZWQrKyxuLmFsd2F5cyhmdW5jdGlvbigpe24uYWx3YXlzKGZ1bmN0aW9uKCl7aC51bnF1ZXVlZC0tLG0ucXVldWUoYSwiZngiKS5sZW5ndGh8fGguZW1wdHkuZmlyZSgpfSl9KSksMT09PWEubm9kZVR5cGUmJigiaGVpZ2h0ImluIGJ8fCJ3aWR0aCJpbiBiKSYmKGMub3ZlcmZsb3c9W3Aub3ZlcmZsb3cscC5vdmVyZmxvd1gscC5vdmVyZmxvd1ldLGo9bS5jc3MoYSwiZGlzcGxheSIpLGw9Im5vbmUiPT09aj9tLl9kYXRhKGEsIm9sZGRpc3BsYXkiKXx8RmEoYS5ub2RlTmFtZSk6aiwiaW5saW5lIj09PWwmJiJub25lIj09PW0uY3NzKGEsImZsb2F0IikmJihrLmlubGluZUJsb2NrTmVlZHNMYXlvdXQmJiJpbmxpbmUiIT09RmEoYS5ub2RlTmFtZSk/cC56b29tPTE6cC5kaXNwbGF5PSJpbmxpbmUtYmxvY2siKSksYy5vdmVyZmxvdyYmKHAub3ZlcmZsb3c9ImhpZGRlbiIsay5zaHJpbmtXcmFwQmxvY2tzKCl8fG4uYWx3YXlzKGZ1bmN0aW9uKCl7cC5vdmVyZmxvdz1jLm92ZXJmbG93WzBdLHAub3ZlcmZsb3dYPWMub3ZlcmZsb3dbMV0scC5vdmVyZmxvd1k9Yy5vdmVyZmxvd1syXX0pKTtmb3IoZCBpbiBiKWlmKGU9YltkXSxhYi5leGVjKGUpKXtpZihkZWxldGUgYltkXSxmPWZ8fCJ0b2dnbGUiPT09ZSxlPT09KHE/ImhpZGUiOiJzaG93Iikpe2lmKCJzaG93IiE9PWV8fCFyfHx2b2lkIDA9PT1yW2RdKWNvbnRpbnVlO3E9ITB9b1tkXT1yJiZyW2RdfHxtLnN0eWxlKGEsZCl9ZWxzZSBqPXZvaWQgMDtpZihtLmlzRW1wdHlPYmplY3QobykpImlubGluZSI9PT0oIm5vbmUiPT09aj9GYShhLm5vZGVOYW1lKTpqKSYmKHAuZGlzcGxheT1qKTtlbHNle3I/ImhpZGRlbiJpbiByJiYocT1yLmhpZGRlbik6cj1tLl9kYXRhKGEsImZ4c2hvdyIse30pLGYmJihyLmhpZGRlbj0hcSkscT9tKGEpLnNob3coKTpuLmRvbmUoZnVuY3Rpb24oKXttKGEpLmhpZGUoKX0pLG4uZG9uZShmdW5jdGlvbigpe3ZhciBiO20uX3JlbW92ZURhdGEoYSwiZnhzaG93Iik7Zm9yKGIgaW4gbyltLnN0eWxlKGEsYixvW2JdKX0pO2ZvcihkIGluIG8pZz1oYihxP3JbZF06MCxkLG4pLGQgaW4gcnx8KHJbZF09Zy5zdGFydCxxJiYoZy5lbmQ9Zy5zdGFydCxnLnN0YXJ0PSJ3aWR0aCI9PT1kfHwiaGVpZ2h0Ij09PWQ/MTowKSl9fWZ1bmN0aW9uIGpiKGEsYil7dmFyIGMsZCxlLGYsZztmb3IoYyBpbiBhKWlmKGQ9bS5jYW1lbENhc2UoYyksZT1iW2RdLGY9YVtjXSxtLmlzQXJyYXkoZikmJihlPWZbMV0sZj1hW2NdPWZbMF0pLGMhPT1kJiYoYVtkXT1mLGRlbGV0ZSBhW2NdKSxnPW0uY3NzSG9va3NbZF0sZyYmImV4cGFuZCJpbiBnKXtmPWcuZXhwYW5kKGYpLGRlbGV0ZSBhW2RdO2ZvcihjIGluIGYpYyBpbiBhfHwoYVtjXT1mW2NdLGJbY109ZSl9ZWxzZSBiW2RdPWV9ZnVuY3Rpb24ga2IoYSxiLGMpe3ZhciBkLGUsZj0wLGc9ZGIubGVuZ3RoLGg9bS5EZWZlcnJlZCgpLmFsd2F5cyhmdW5jdGlvbigpe2RlbGV0ZSBpLmVsZW19KSxpPWZ1bmN0aW9uKCl7aWYoZSlyZXR1cm4hMTtmb3IodmFyIGI9JGF8fGZiKCksYz1NYXRoLm1heCgwLGouc3RhcnRUaW1lK2ouZHVyYXRpb24tYiksZD1jL2ouZHVyYXRpb258fDAsZj0xLWQsZz0wLGk9ai50d2VlbnMubGVuZ3RoO2k+ZztnKyspai50d2VlbnNbZ10ucnVuKGYpO3JldHVybiBoLm5vdGlmeVdpdGgoYSxbaixmLGNdKSwxPmYmJmk/YzooaC5yZXNvbHZlV2l0aChhLFtqXSksITEpfSxqPWgucHJvbWlzZSh7ZWxlbTphLHByb3BzOm0uZXh0ZW5kKHt9LGIpLG9wdHM6bS5leHRlbmQoITAse3NwZWNpYWxFYXNpbmc6e319LGMpLG9yaWdpbmFsUHJvcGVydGllczpiLG9yaWdpbmFsT3B0aW9uczpjLHN0YXJ0VGltZTokYXx8ZmIoKSxkdXJhdGlvbjpjLmR1cmF0aW9uLHR3ZWVuczpbXSxjcmVhdGVUd2VlbjpmdW5jdGlvbihiLGMpe3ZhciBkPW0uVHdlZW4oYSxqLm9wdHMsYixjLGoub3B0cy5zcGVjaWFsRWFzaW5nW2JdfHxqLm9wdHMuZWFzaW5nKTtyZXR1cm4gai50d2VlbnMucHVzaChkKSxkfSxzdG9wOmZ1bmN0aW9uKGIpe3ZhciBjPTAsZD1iP2oudHdlZW5zLmxlbmd0aDowO2lmKGUpcmV0dXJuIHRoaXM7Zm9yKGU9ITA7ZD5jO2MrKylqLnR3ZWVuc1tjXS5ydW4oMSk7cmV0dXJuIGI/aC5yZXNvbHZlV2l0aChhLFtqLGJdKTpoLnJlamVjdFdpdGgoYSxbaixiXSksdGhpc319KSxrPWoucHJvcHM7Zm9yKGpiKGssai5vcHRzLnNwZWNpYWxFYXNpbmcpO2c+ZjtmKyspaWYoZD1kYltmXS5jYWxsKGosYSxrLGoub3B0cykpcmV0dXJuIGQ7cmV0dXJuIG0ubWFwKGssaGIsaiksbS5pc0Z1bmN0aW9uKGoub3B0cy5zdGFydCkmJmoub3B0cy5zdGFydC5jYWxsKGEsaiksbS5meC50aW1lcihtLmV4dGVuZChpLHtlbGVtOmEsYW5pbTpqLHF1ZXVlOmoub3B0cy5xdWV1ZX0pKSxqLnByb2dyZXNzKGoub3B0cy5wcm9ncmVzcykuZG9uZShqLm9wdHMuZG9uZSxqLm9wdHMuY29tcGxldGUpLmZhaWwoai5vcHRzLmZhaWwpLmFsd2F5cyhqLm9wdHMuYWx3YXlzKX1tLkFuaW1hdGlvbj1tLmV4dGVuZChrYix7dHdlZW5lcjpmdW5jdGlvbihhLGIpe20uaXNGdW5jdGlvbihhKT8oYj1hLGE9WyIqIl0pOmE9YS5zcGxpdCgiICIpO2Zvcih2YXIgYyxkPTAsZT1hLmxlbmd0aDtlPmQ7ZCsrKWM9YVtkXSxlYltjXT1lYltjXXx8W10sZWJbY10udW5zaGlmdChiKX0scHJlZmlsdGVyOmZ1bmN0aW9uKGEsYil7Yj9kYi51bnNoaWZ0KGEpOmRiLnB1c2goYSl9fSksbS5zcGVlZD1mdW5jdGlvbihhLGIsYyl7dmFyIGQ9YSYmIm9iamVjdCI9PXR5cGVvZiBhP20uZXh0ZW5kKHt9LGEpOntjb21wbGV0ZTpjfHwhYyYmYnx8bS5pc0Z1bmN0aW9uKGEpJiZhLGR1cmF0aW9uOmEsZWFzaW5nOmMmJmJ8fGImJiFtLmlzRnVuY3Rpb24oYikmJmJ9O3JldHVybiBkLmR1cmF0aW9uPW0uZngub2ZmPzA6Im51bWJlciI9PXR5cGVvZiBkLmR1cmF0aW9uP2QuZHVyYXRpb246ZC5kdXJhdGlvbiBpbiBtLmZ4LnNwZWVkcz9tLmZ4LnNwZWVkc1tkLmR1cmF0aW9uXTptLmZ4LnNwZWVkcy5fZGVmYXVsdCwobnVsbD09ZC5xdWV1ZXx8ZC5xdWV1ZT09PSEwKSYmKGQucXVldWU9ImZ4IiksZC5vbGQ9ZC5jb21wbGV0ZSxkLmNvbXBsZXRlPWZ1bmN0aW9uKCl7bS5pc0Z1bmN0aW9uKGQub2xkKSYmZC5vbGQuY2FsbCh0aGlzKSxkLnF1ZXVlJiZtLmRlcXVldWUodGhpcyxkLnF1ZXVlKX0sZH0sbS5mbi5leHRlbmQoe2ZhZGVUbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gdGhpcy5maWx0ZXIoVSkuY3NzKCJvcGFjaXR5IiwwKS5zaG93KCkuZW5kKCkuYW5pbWF0ZSh7b3BhY2l0eTpifSxhLGMsZCl9LGFuaW1hdGU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGU9bS5pc0VtcHR5T2JqZWN0KGEpLGY9bS5zcGVlZChiLGMsZCksZz1mdW5jdGlvbigpe3ZhciBiPWtiKHRoaXMsbS5leHRlbmQoe30sYSksZik7KGV8fG0uX2RhdGEodGhpcywiZmluaXNoIikpJiZiLnN0b3AoITApfTtyZXR1cm4gZy5maW5pc2g9ZyxlfHxmLnF1ZXVlPT09ITE/dGhpcy5lYWNoKGcpOnRoaXMucXVldWUoZi5xdWV1ZSxnKX0sc3RvcDpmdW5jdGlvbihhLGIsYyl7dmFyIGQ9ZnVuY3Rpb24oYSl7dmFyIGI9YS5zdG9wO2RlbGV0ZSBhLnN0b3AsYihjKX07cmV0dXJuInN0cmluZyIhPXR5cGVvZiBhJiYoYz1iLGI9YSxhPXZvaWQgMCksYiYmYSE9PSExJiZ0aGlzLnF1ZXVlKGF8fCJmeCIsW10pLHRoaXMuZWFjaChmdW5jdGlvbigpe3ZhciBiPSEwLGU9bnVsbCE9YSYmYSsicXVldWVIb29rcyIsZj1tLnRpbWVycyxnPW0uX2RhdGEodGhpcyk7aWYoZSlnW2VdJiZnW2VdLnN0b3AmJmQoZ1tlXSk7ZWxzZSBmb3IoZSBpbiBnKWdbZV0mJmdbZV0uc3RvcCYmY2IudGVzdChlKSYmZChnW2VdKTtmb3IoZT1mLmxlbmd0aDtlLS07KWZbZV0uZWxlbSE9PXRoaXN8fG51bGwhPWEmJmZbZV0ucXVldWUhPT1hfHwoZltlXS5hbmltLnN0b3AoYyksYj0hMSxmLnNwbGljZShlLDEpKTsoYnx8IWMpJiZtLmRlcXVldWUodGhpcyxhKX0pfSxmaW5pc2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEhPT0hMSYmKGE9YXx8ImZ4IiksdGhpcy5lYWNoKGZ1bmN0aW9uKCl7dmFyIGIsYz1tLl9kYXRhKHRoaXMpLGQ9Y1thKyJxdWV1ZSJdLGU9Y1thKyJxdWV1ZUhvb2tzIl0sZj1tLnRpbWVycyxnPWQ/ZC5sZW5ndGg6MDtmb3IoYy5maW5pc2g9ITAsbS5xdWV1ZSh0aGlzLGEsW10pLGUmJmUuc3RvcCYmZS5zdG9wLmNhbGwodGhpcywhMCksYj1mLmxlbmd0aDtiLS07KWZbYl0uZWxlbT09PXRoaXMmJmZbYl0ucXVldWU9PT1hJiYoZltiXS5hbmltLnN0b3AoITApLGYuc3BsaWNlKGIsMSkpO2ZvcihiPTA7Zz5iO2IrKylkW2JdJiZkW2JdLmZpbmlzaCYmZFtiXS5maW5pc2guY2FsbCh0aGlzKTtkZWxldGUgYy5maW5pc2h9KX19KSxtLmVhY2goWyJ0b2dnbGUiLCJzaG93IiwiaGlkZSJdLGZ1bmN0aW9uKGEsYil7dmFyIGM9bS5mbltiXTttLmZuW2JdPWZ1bmN0aW9uKGEsZCxlKXtyZXR1cm4gbnVsbD09YXx8ImJvb2xlYW4iPT10eXBlb2YgYT9jLmFwcGx5KHRoaXMsYXJndW1lbnRzKTp0aGlzLmFuaW1hdGUoZ2IoYiwhMCksYSxkLGUpfX0pLG0uZWFjaCh7c2xpZGVEb3duOmdiKCJzaG93Iiksc2xpZGVVcDpnYigiaGlkZSIpLHNsaWRlVG9nZ2xlOmdiKCJ0b2dnbGUiKSxmYWRlSW46e29wYWNpdHk6InNob3cifSxmYWRlT3V0OntvcGFjaXR5OiJoaWRlIn0sZmFkZVRvZ2dsZTp7b3BhY2l0eToidG9nZ2xlIn19LGZ1bmN0aW9uKGEsYil7bS5mblthXT1mdW5jdGlvbihhLGMsZCl7cmV0dXJuIHRoaXMuYW5pbWF0ZShiLGEsYyxkKX19KSxtLnRpbWVycz1bXSxtLmZ4LnRpY2s9ZnVuY3Rpb24oKXt2YXIgYSxiPW0udGltZXJzLGM9MDtmb3IoJGE9bS5ub3coKTtjPGIubGVuZ3RoO2MrKylhPWJbY10sYSgpfHxiW2NdIT09YXx8Yi5zcGxpY2UoYy0tLDEpO2IubGVuZ3RofHxtLmZ4LnN0b3AoKSwkYT12b2lkIDB9LG0uZngudGltZXI9ZnVuY3Rpb24oYSl7bS50aW1lcnMucHVzaChhKSxhKCk/bS5meC5zdGFydCgpOm0udGltZXJzLnBvcCgpfSxtLmZ4LmludGVydmFsPTEzLG0uZnguc3RhcnQ9ZnVuY3Rpb24oKXtfYXx8KF9hPXNldEludGVydmFsKG0uZngudGljayxtLmZ4LmludGVydmFsKSl9LG0uZnguc3RvcD1mdW5jdGlvbigpe2NsZWFySW50ZXJ2YWwoX2EpLF9hPW51bGx9LG0uZnguc3BlZWRzPXtzbG93OjYwMCxmYXN0OjIwMCxfZGVmYXVsdDo0MDB9LG0uZm4uZGVsYXk9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT1tLmZ4P20uZnguc3BlZWRzW2FdfHxhOmEsYj1ifHwiZngiLHRoaXMucXVldWUoYixmdW5jdGlvbihiLGMpe3ZhciBkPXNldFRpbWVvdXQoYixhKTtjLnN0b3A9ZnVuY3Rpb24oKXtjbGVhclRpbWVvdXQoZCl9fSl9LGZ1bmN0aW9uKCl7dmFyIGEsYixjLGQsZTtiPXkuY3JlYXRlRWxlbWVudCgiZGl2IiksYi5zZXRBdHRyaWJ1dGUoImNsYXNzTmFtZSIsInQiKSxiLmlubmVySFRNTD0iICA8bGluay8+PHRhYmxlPjwvdGFibGU+PGEgaHJlZj0nL2EnPmE8L2E+PGlucHV0IHR5cGU9J2NoZWNrYm94Jy8+IixkPWIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImEiKVswXSxjPXkuY3JlYXRlRWxlbWVudCgic2VsZWN0IiksZT1jLmFwcGVuZENoaWxkKHkuY3JlYXRlRWxlbWVudCgib3B0aW9uIikpLGE9Yi5nZXRFbGVtZW50c0J5VGFnTmFtZSgiaW5wdXQiKVswXSxkLnN0eWxlLmNzc1RleHQ9InRvcDoxcHgiLGsuZ2V0U2V0QXR0cmlidXRlPSJ0IiE9PWIuY2xhc3NOYW1lLGsuc3R5bGU9L3RvcC8udGVzdChkLmdldEF0dHJpYnV0ZSgic3R5bGUiKSksay5ocmVmTm9ybWFsaXplZD0iL2EiPT09ZC5nZXRBdHRyaWJ1dGUoImhyZWYiKSxrLmNoZWNrT249ISFhLnZhbHVlLGsub3B0U2VsZWN0ZWQ9ZS5zZWxlY3RlZCxrLmVuY3R5cGU9ISF5LmNyZWF0ZUVsZW1lbnQoImZvcm0iKS5lbmN0eXBlLGMuZGlzYWJsZWQ9ITAsay5vcHREaXNhYmxlZD0hZS5kaXNhYmxlZCxhPXkuY3JlYXRlRWxlbWVudCgiaW5wdXQiKSxhLnNldEF0dHJpYnV0ZSgidmFsdWUiLCIiKSxrLmlucHV0PSIiPT09YS5nZXRBdHRyaWJ1dGUoInZhbHVlIiksYS52YWx1ZT0idCIsYS5zZXRBdHRyaWJ1dGUoInR5cGUiLCJyYWRpbyIpLGsucmFkaW9WYWx1ZT0idCI9PT1hLnZhbHVlfSgpO3ZhciBsYj0vXHIvZzttLmZuLmV4dGVuZCh7dmFsOmZ1bmN0aW9uKGEpe3ZhciBiLGMsZCxlPXRoaXNbMF07e2lmKGFyZ3VtZW50cy5sZW5ndGgpcmV0dXJuIGQ9bS5pc0Z1bmN0aW9uKGEpLHRoaXMuZWFjaChmdW5jdGlvbihjKXt2YXIgZTsxPT09dGhpcy5ub2RlVHlwZSYmKGU9ZD9hLmNhbGwodGhpcyxjLG0odGhpcykudmFsKCkpOmEsbnVsbD09ZT9lPSIiOiJudW1iZXIiPT10eXBlb2YgZT9lKz0iIjptLmlzQXJyYXkoZSkmJihlPW0ubWFwKGUsZnVuY3Rpb24oYSl7cmV0dXJuIG51bGw9PWE/IiI6YSsiIn0pKSxiPW0udmFsSG9va3NbdGhpcy50eXBlXXx8bS52YWxIb29rc1t0aGlzLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCldLGImJiJzZXQiaW4gYiYmdm9pZCAwIT09Yi5zZXQodGhpcyxlLCJ2YWx1ZSIpfHwodGhpcy52YWx1ZT1lKSl9KTtpZihlKXJldHVybiBiPW0udmFsSG9va3NbZS50eXBlXXx8bS52YWxIb29rc1tlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCldLGImJiJnZXQiaW4gYiYmdm9pZCAwIT09KGM9Yi5nZXQoZSwidmFsdWUiKSk/YzooYz1lLnZhbHVlLCJzdHJpbmciPT10eXBlb2YgYz9jLnJlcGxhY2UobGIsIiIpOm51bGw9PWM/IiI6Yyl9fX0pLG0uZXh0ZW5kKHt2YWxIb29rczp7b3B0aW9uOntnZXQ6ZnVuY3Rpb24oYSl7dmFyIGI9bS5maW5kLmF0dHIoYSwidmFsdWUiKTtyZXR1cm4gbnVsbCE9Yj9iOm0udHJpbShtLnRleHQoYSkpfX0sc2VsZWN0OntnZXQ6ZnVuY3Rpb24oYSl7Zm9yKHZhciBiLGMsZD1hLm9wdGlvbnMsZT1hLnNlbGVjdGVkSW5kZXgsZj0ic2VsZWN0LW9uZSI9PT1hLnR5cGV8fDA+ZSxnPWY/bnVsbDpbXSxoPWY/ZSsxOmQubGVuZ3RoLGk9MD5lP2g6Zj9lOjA7aD5pO2krKylpZihjPWRbaV0sISghYy5zZWxlY3RlZCYmaSE9PWV8fChrLm9wdERpc2FibGVkP2MuZGlzYWJsZWQ6bnVsbCE9PWMuZ2V0QXR0cmlidXRlKCJkaXNhYmxlZCIpKXx8Yy5wYXJlbnROb2RlLmRpc2FibGVkJiZtLm5vZGVOYW1lKGMucGFyZW50Tm9kZSwib3B0Z3JvdXAiKSkpe2lmKGI9bShjKS52YWwoKSxmKXJldHVybiBiO2cucHVzaChiKX1yZXR1cm4gZ30sc2V0OmZ1bmN0aW9uKGEsYil7dmFyIGMsZCxlPWEub3B0aW9ucyxmPW0ubWFrZUFycmF5KGIpLGc9ZS5sZW5ndGg7d2hpbGUoZy0tKWlmKGQ9ZVtnXSxtLmluQXJyYXkobS52YWxIb29rcy5vcHRpb24uZ2V0KGQpLGYpPj0wKXRyeXtkLnNlbGVjdGVkPWM9ITB9Y2F0Y2goaCl7ZC5zY3JvbGxIZWlnaHR9ZWxzZSBkLnNlbGVjdGVkPSExO3JldHVybiBjfHwoYS5zZWxlY3RlZEluZGV4PS0xKSxlfX19fSksbS5lYWNoKFsicmFkaW8iLCJjaGVja2JveCJdLGZ1bmN0aW9uKCl7bS52YWxIb29rc1t0aGlzXT17c2V0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG0uaXNBcnJheShiKT9hLmNoZWNrZWQ9bS5pbkFycmF5KG0oYSkudmFsKCksYik+PTA6dm9pZCAwfX0say5jaGVja09ufHwobS52YWxIb29rc1t0aGlzXS5nZXQ9ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGw9PT1hLmdldEF0dHJpYnV0ZSgidmFsdWUiKT8ib24iOmEudmFsdWV9KX0pO3ZhciBtYixuYixvYj1tLmV4cHIuYXR0ckhhbmRsZSxwYj0vXig/OmNoZWNrZWR8c2VsZWN0ZWQpJC9pLHFiPWsuZ2V0U2V0QXR0cmlidXRlLHJiPWsuaW5wdXQ7bS5mbi5leHRlbmQoe2F0dHI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gVih0aGlzLG0uYXR0cixhLGIsYXJndW1lbnRzLmxlbmd0aD4xKX0scmVtb3ZlQXR0cjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7bS5yZW1vdmVBdHRyKHRoaXMsYSl9KX19KSxtLmV4dGVuZCh7YXR0cjpmdW5jdGlvbihhLGIsYyl7dmFyIGQsZSxmPWEubm9kZVR5cGU7aWYoYSYmMyE9PWYmJjghPT1mJiYyIT09ZilyZXR1cm4gdHlwZW9mIGEuZ2V0QXR0cmlidXRlPT09Sz9tLnByb3AoYSxiLGMpOigxPT09ZiYmbS5pc1hNTERvYyhhKXx8KGI9Yi50b0xvd2VyQ2FzZSgpLGQ9bS5hdHRySG9va3NbYl18fChtLmV4cHIubWF0Y2guYm9vbC50ZXN0KGIpP25iOm1iKSksdm9pZCAwPT09Yz9kJiYiZ2V0ImluIGQmJm51bGwhPT0oZT1kLmdldChhLGIpKT9lOihlPW0uZmluZC5hdHRyKGEsYiksbnVsbD09ZT92b2lkIDA6ZSk6bnVsbCE9PWM/ZCYmInNldCJpbiBkJiZ2b2lkIDAhPT0oZT1kLnNldChhLGMsYikpP2U6KGEuc2V0QXR0cmlidXRlKGIsYysiIiksYyk6dm9pZCBtLnJlbW92ZUF0dHIoYSxiKSl9LHJlbW92ZUF0dHI6ZnVuY3Rpb24oYSxiKXt2YXIgYyxkLGU9MCxmPWImJmIubWF0Y2goRSk7aWYoZiYmMT09PWEubm9kZVR5cGUpd2hpbGUoYz1mW2UrK10pZD1tLnByb3BGaXhbY118fGMsbS5leHByLm1hdGNoLmJvb2wudGVzdChjKT9yYiYmcWJ8fCFwYi50ZXN0KGMpP2FbZF09ITE6YVttLmNhbWVsQ2FzZSgiZGVmYXVsdC0iK2MpXT1hW2RdPSExOm0uYXR0cihhLGMsIiIpLGEucmVtb3ZlQXR0cmlidXRlKHFiP2M6ZCl9LGF0dHJIb29rczp7dHlwZTp7c2V0OmZ1bmN0aW9uKGEsYil7aWYoIWsucmFkaW9WYWx1ZSYmInJhZGlvIj09PWImJm0ubm9kZU5hbWUoYSwiaW5wdXQiKSl7dmFyIGM9YS52YWx1ZTtyZXR1cm4gYS5zZXRBdHRyaWJ1dGUoInR5cGUiLGIpLGMmJihhLnZhbHVlPWMpLGJ9fX19fSksbmI9e3NldDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGI9PT0hMT9tLnJlbW92ZUF0dHIoYSxjKTpyYiYmcWJ8fCFwYi50ZXN0KGMpP2Euc2V0QXR0cmlidXRlKCFxYiYmbS5wcm9wRml4W2NdfHxjLGMpOmFbbS5jYW1lbENhc2UoImRlZmF1bHQtIitjKV09YVtjXT0hMCxjfX0sbS5lYWNoKG0uZXhwci5tYXRjaC5ib29sLnNvdXJjZS5tYXRjaCgvXHcrL2cpLGZ1bmN0aW9uKGEsYil7dmFyIGM9b2JbYl18fG0uZmluZC5hdHRyO29iW2JdPXJiJiZxYnx8IXBiLnRlc3QoYik/ZnVuY3Rpb24oYSxiLGQpe3ZhciBlLGY7cmV0dXJuIGR8fChmPW9iW2JdLG9iW2JdPWUsZT1udWxsIT1jKGEsYixkKT9iLnRvTG93ZXJDYXNlKCk6bnVsbCxvYltiXT1mKSxlfTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGM/dm9pZCAwOmFbbS5jYW1lbENhc2UoImRlZmF1bHQtIitiKV0/Yi50b0xvd2VyQ2FzZSgpOm51bGx9fSkscmImJnFifHwobS5hdHRySG9va3MudmFsdWU9e3NldDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG0ubm9kZU5hbWUoYSwiaW5wdXQiKT92b2lkKGEuZGVmYXVsdFZhbHVlPWIpOm1iJiZtYi5zZXQoYSxiLGMpfX0pLHFifHwobWI9e3NldDpmdW5jdGlvbihhLGIsYyl7dmFyIGQ9YS5nZXRBdHRyaWJ1dGVOb2RlKGMpO3JldHVybiBkfHxhLnNldEF0dHJpYnV0ZU5vZGUoZD1hLm93bmVyRG9jdW1lbnQuY3JlYXRlQXR0cmlidXRlKGMpKSxkLnZhbHVlPWIrPSIiLCJ2YWx1ZSI9PT1jfHxiPT09YS5nZXRBdHRyaWJ1dGUoYyk/Yjp2b2lkIDB9fSxvYi5pZD1vYi5uYW1lPW9iLmNvb3Jkcz1mdW5jdGlvbihhLGIsYyl7dmFyIGQ7cmV0dXJuIGM/dm9pZCAwOihkPWEuZ2V0QXR0cmlidXRlTm9kZShiKSkmJiIiIT09ZC52YWx1ZT9kLnZhbHVlOm51bGx9LG0udmFsSG9va3MuYnV0dG9uPXtnZXQ6ZnVuY3Rpb24oYSxiKXt2YXIgYz1hLmdldEF0dHJpYnV0ZU5vZGUoYik7cmV0dXJuIGMmJmMuc3BlY2lmaWVkP2MudmFsdWU6dm9pZCAwfSxzZXQ6bWIuc2V0fSxtLmF0dHJIb29rcy5jb250ZW50ZWRpdGFibGU9e3NldDpmdW5jdGlvbihhLGIsYyl7bWIuc2V0KGEsIiI9PT1iPyExOmIsYyl9fSxtLmVhY2goWyJ3aWR0aCIsImhlaWdodCJdLGZ1bmN0aW9uKGEsYil7bS5hdHRySG9va3NbYl09e3NldDpmdW5jdGlvbihhLGMpe3JldHVybiIiPT09Yz8oYS5zZXRBdHRyaWJ1dGUoYiwiYXV0byIpLGMpOnZvaWQgMH19fSkpLGsuc3R5bGV8fChtLmF0dHJIb29rcy5zdHlsZT17Z2V0OmZ1bmN0aW9uKGEpe3JldHVybiBhLnN0eWxlLmNzc1RleHR8fHZvaWQgMH0sc2V0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIGEuc3R5bGUuY3NzVGV4dD1iKyIifX0pO3ZhciBzYj0vXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b258b2JqZWN0KSQvaSx0Yj0vXig/OmF8YXJlYSkkL2k7bS5mbi5leHRlbmQoe3Byb3A6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gVih0aGlzLG0ucHJvcCxhLGIsYXJndW1lbnRzLmxlbmd0aD4xKX0scmVtb3ZlUHJvcDpmdW5jdGlvbihhKXtyZXR1cm4gYT1tLnByb3BGaXhbYV18fGEsdGhpcy5lYWNoKGZ1bmN0aW9uKCl7dHJ5e3RoaXNbYV09dm9pZCAwLGRlbGV0ZSB0aGlzW2FdfWNhdGNoKGIpe319KX19KSxtLmV4dGVuZCh7cHJvcEZpeDp7ImZvciI6Imh0bWxGb3IiLCJjbGFzcyI6ImNsYXNzTmFtZSJ9LHByb3A6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkLGUsZixnPWEubm9kZVR5cGU7aWYoYSYmMyE9PWcmJjghPT1nJiYyIT09ZylyZXR1cm4gZj0xIT09Z3x8IW0uaXNYTUxEb2MoYSksZiYmKGI9bS5wcm9wRml4W2JdfHxiLGU9bS5wcm9wSG9va3NbYl0pLHZvaWQgMCE9PWM/ZSYmInNldCJpbiBlJiZ2b2lkIDAhPT0oZD1lLnNldChhLGMsYikpP2Q6YVtiXT1jOmUmJiJnZXQiaW4gZSYmbnVsbCE9PShkPWUuZ2V0KGEsYikpP2Q6YVtiXX0scHJvcEhvb2tzOnt0YWJJbmRleDp7Z2V0OmZ1bmN0aW9uKGEpe3ZhciBiPW0uZmluZC5hdHRyKGEsInRhYmluZGV4Iik7cmV0dXJuIGI/cGFyc2VJbnQoYiwxMCk6c2IudGVzdChhLm5vZGVOYW1lKXx8dGIudGVzdChhLm5vZGVOYW1lKSYmYS5ocmVmPzA6LTF9fX19KSxrLmhyZWZOb3JtYWxpemVkfHxtLmVhY2goWyJocmVmIiwic3JjIl0sZnVuY3Rpb24oYSxiKXttLnByb3BIb29rc1tiXT17Z2V0OmZ1bmN0aW9uKGEpe3JldHVybiBhLmdldEF0dHJpYnV0ZShiLDQpfX19KSxrLm9wdFNlbGVjdGVkfHwobS5wcm9wSG9va3Muc2VsZWN0ZWQ9e2dldDpmdW5jdGlvbihhKXt2YXIgYj1hLnBhcmVudE5vZGU7cmV0dXJuIGImJihiLnNlbGVjdGVkSW5kZXgsYi5wYXJlbnROb2RlJiZiLnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleCksbnVsbH19KSxtLmVhY2goWyJ0YWJJbmRleCIsInJlYWRPbmx5IiwibWF4TGVuZ3RoIiwiY2VsbFNwYWNpbmciLCJjZWxsUGFkZGluZyIsInJvd1NwYW4iLCJjb2xTcGFuIiwidXNlTWFwIiwiZnJhbWVCb3JkZXIiLCJjb250ZW50RWRpdGFibGUiXSxmdW5jdGlvbigpe20ucHJvcEZpeFt0aGlzLnRvTG93ZXJDYXNlKCldPXRoaXN9KSxrLmVuY3R5cGV8fChtLnByb3BGaXguZW5jdHlwZT0iZW5jb2RpbmciKTt2YXIgdWI9L1tcdFxyXG5cZl0vZzttLmZuLmV4dGVuZCh7YWRkQ2xhc3M6ZnVuY3Rpb24oYSl7dmFyIGIsYyxkLGUsZixnLGg9MCxpPXRoaXMubGVuZ3RoLGo9InN0cmluZyI9PXR5cGVvZiBhJiZhO2lmKG0uaXNGdW5jdGlvbihhKSlyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKGIpe20odGhpcykuYWRkQ2xhc3MoYS5jYWxsKHRoaXMsYix0aGlzLmNsYXNzTmFtZSkpfSk7aWYoailmb3IoYj0oYXx8IiIpLm1hdGNoKEUpfHxbXTtpPmg7aCsrKWlmKGM9dGhpc1toXSxkPTE9PT1jLm5vZGVUeXBlJiYoYy5jbGFzc05hbWU/KCIgIitjLmNsYXNzTmFtZSsiICIpLnJlcGxhY2UodWIsIiAiKToiICIpKXtmPTA7d2hpbGUoZT1iW2YrK10pZC5pbmRleE9mKCIgIitlKyIgIik8MCYmKGQrPWUrIiAiKTtnPW0udHJpbShkKSxjLmNsYXNzTmFtZSE9PWcmJihjLmNsYXNzTmFtZT1nKX1yZXR1cm4gdGhpc30scmVtb3ZlQ2xhc3M6ZnVuY3Rpb24oYSl7dmFyIGIsYyxkLGUsZixnLGg9MCxpPXRoaXMubGVuZ3RoLGo9MD09PWFyZ3VtZW50cy5sZW5ndGh8fCJzdHJpbmciPT10eXBlb2YgYSYmYTtpZihtLmlzRnVuY3Rpb24oYSkpcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihiKXttKHRoaXMpLnJlbW92ZUNsYXNzKGEuY2FsbCh0aGlzLGIsdGhpcy5jbGFzc05hbWUpKX0pO2lmKGopZm9yKGI9KGF8fCIiKS5tYXRjaChFKXx8W107aT5oO2grKylpZihjPXRoaXNbaF0sZD0xPT09Yy5ub2RlVHlwZSYmKGMuY2xhc3NOYW1lPygiICIrYy5jbGFzc05hbWUrIiAiKS5yZXBsYWNlKHViLCIgIik6IiIpKXtmPTA7d2hpbGUoZT1iW2YrK10pd2hpbGUoZC5pbmRleE9mKCIgIitlKyIgIik+PTApZD1kLnJlcGxhY2UoIiAiK2UrIiAiLCIgIik7Zz1hP20udHJpbShkKToiIixjLmNsYXNzTmFtZSE9PWcmJihjLmNsYXNzTmFtZT1nKX1yZXR1cm4gdGhpc30sdG9nZ2xlQ2xhc3M6ZnVuY3Rpb24oYSxiKXt2YXIgYz10eXBlb2YgYTtyZXR1cm4iYm9vbGVhbiI9PXR5cGVvZiBiJiYic3RyaW5nIj09PWM/Yj90aGlzLmFkZENsYXNzKGEpOnRoaXMucmVtb3ZlQ2xhc3MoYSk6dGhpcy5lYWNoKG0uaXNGdW5jdGlvbihhKT9mdW5jdGlvbihjKXttKHRoaXMpLnRvZ2dsZUNsYXNzKGEuY2FsbCh0aGlzLGMsdGhpcy5jbGFzc05hbWUsYiksYil9OmZ1bmN0aW9uKCl7aWYoInN0cmluZyI9PT1jKXt2YXIgYixkPTAsZT1tKHRoaXMpLGY9YS5tYXRjaChFKXx8W107d2hpbGUoYj1mW2QrK10pZS5oYXNDbGFzcyhiKT9lLnJlbW92ZUNsYXNzKGIpOmUuYWRkQ2xhc3MoYil9ZWxzZShjPT09S3x8ImJvb2xlYW4iPT09YykmJih0aGlzLmNsYXNzTmFtZSYmbS5fZGF0YSh0aGlzLCJfX2NsYXNzTmFtZV9fIix0aGlzLmNsYXNzTmFtZSksdGhpcy5jbGFzc05hbWU9dGhpcy5jbGFzc05hbWV8fGE9PT0hMT8iIjptLl9kYXRhKHRoaXMsIl9fY2xhc3NOYW1lX18iKXx8IiIpfSl9LGhhc0NsYXNzOmZ1bmN0aW9uKGEpe2Zvcih2YXIgYj0iICIrYSsiICIsYz0wLGQ9dGhpcy5sZW5ndGg7ZD5jO2MrKylpZigxPT09dGhpc1tjXS5ub2RlVHlwZSYmKCIgIit0aGlzW2NdLmNsYXNzTmFtZSsiICIpLnJlcGxhY2UodWIsIiAiKS5pbmRleE9mKGIpPj0wKXJldHVybiEwO3JldHVybiExfX0pLG0uZWFjaCgiYmx1ciBmb2N1cyBmb2N1c2luIGZvY3Vzb3V0IGxvYWQgcmVzaXplIHNjcm9sbCB1bmxvYWQgY2xpY2sgZGJsY2xpY2sgbW91c2Vkb3duIG1vdXNldXAgbW91c2Vtb3ZlIG1vdXNlb3ZlciBtb3VzZW91dCBtb3VzZWVudGVyIG1vdXNlbGVhdmUgY2hhbmdlIHNlbGVjdCBzdWJtaXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBlcnJvciBjb250ZXh0bWVudSIuc3BsaXQoIiAiKSxmdW5jdGlvbihhLGIpe20uZm5bYl09ZnVuY3Rpb24oYSxjKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD4wP3RoaXMub24oYixudWxsLGEsYyk6dGhpcy50cmlnZ2VyKGIpfX0pLG0uZm4uZXh0ZW5kKHtob3ZlcjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLm1vdXNlZW50ZXIoYSkubW91c2VsZWF2ZShifHxhKX0sYmluZDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMub24oYSxudWxsLGIsYyl9LHVuYmluZDpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLm9mZihhLG51bGwsYil9LGRlbGVnYXRlOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiB0aGlzLm9uKGIsYSxjLGQpfSx1bmRlbGVnYXRlOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gMT09PWFyZ3VtZW50cy5sZW5ndGg/dGhpcy5vZmYoYSwiKioiKTp0aGlzLm9mZihiLGF8fCIqKiIsYyl9fSk7dmFyIHZiPW0ubm93KCksd2I9L1w/Lyx4Yj0vKCwpfChcW3x7KXwofXxdKXwiKD86W14iXFxcclxuXXxcXFsiXFxcL2JmbnJ0XXxcXHVbXGRhLWZBLUZdezR9KSoiXHMqOj98dHJ1ZXxmYWxzZXxudWxsfC0/KD8hMFxkKVxkKyg/OlwuXGQrfCkoPzpbZUVdWystXT9cZCt8KS9nO20ucGFyc2VKU09OPWZ1bmN0aW9uKGIpe2lmKGEuSlNPTiYmYS5KU09OLnBhcnNlKXJldHVybiBhLkpTT04ucGFyc2UoYisiIik7dmFyIGMsZD1udWxsLGU9bS50cmltKGIrIiIpO3JldHVybiBlJiYhbS50cmltKGUucmVwbGFjZSh4YixmdW5jdGlvbihhLGIsZSxmKXtyZXR1cm4gYyYmYiYmKGQ9MCksMD09PWQ/YTooYz1lfHxiLGQrPSFmLSFlLCIiKX0pKT9GdW5jdGlvbigicmV0dXJuICIrZSkoKTptLmVycm9yKCJJbnZhbGlkIEpTT046ICIrYil9LG0ucGFyc2VYTUw9ZnVuY3Rpb24oYil7dmFyIGMsZDtpZighYnx8InN0cmluZyIhPXR5cGVvZiBiKXJldHVybiBudWxsO3RyeXthLkRPTVBhcnNlcj8oZD1uZXcgRE9NUGFyc2VyLGM9ZC5wYXJzZUZyb21TdHJpbmcoYiwidGV4dC94bWwiKSk6KGM9bmV3IEFjdGl2ZVhPYmplY3QoIk1pY3Jvc29mdC5YTUxET00iKSxjLmFzeW5jPSJmYWxzZSIsYy5sb2FkWE1MKGIpKX1jYXRjaChlKXtjPXZvaWQgMH1yZXR1cm4gYyYmYy5kb2N1bWVudEVsZW1lbnQmJiFjLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwYXJzZXJlcnJvciIpLmxlbmd0aHx8bS5lcnJvcigiSW52YWxpZCBYTUw6ICIrYiksY307dmFyIHliLHpiLEFiPS8jLiokLyxCYj0vKFs/Jl0pXz1bXiZdKi8sQ2I9L14oLio/KTpbIFx0XSooW15cclxuXSopXHI/JC9nbSxEYj0vXig/OmFib3V0fGFwcHxhcHAtc3RvcmFnZXwuKy1leHRlbnNpb258ZmlsZXxyZXN8d2lkZ2V0KTokLyxFYj0vXig/OkdFVHxIRUFEKSQvLEZiPS9eXC9cLy8sR2I9L14oW1x3ListXSs6KSg/OlwvXC8oPzpbXlwvPyNdKkB8KShbXlwvPyM6XSopKD86OihcZCspfCl8KS8sSGI9e30sSWI9e30sSmI9IiovIi5jb25jYXQoIioiKTt0cnl7emI9bG9jYXRpb24uaHJlZn1jYXRjaChLYil7emI9eS5jcmVhdGVFbGVtZW50KCJhIiksemIuaHJlZj0iIix6Yj16Yi5ocmVmfXliPUdiLmV4ZWMoemIudG9Mb3dlckNhc2UoKSl8fFtdO2Z1bmN0aW9uIExiKGEpe3JldHVybiBmdW5jdGlvbihiLGMpeyJzdHJpbmciIT10eXBlb2YgYiYmKGM9YixiPSIqIik7dmFyIGQsZT0wLGY9Yi50b0xvd2VyQ2FzZSgpLm1hdGNoKEUpfHxbXTtpZihtLmlzRnVuY3Rpb24oYykpd2hpbGUoZD1mW2UrK10pIisiPT09ZC5jaGFyQXQoMCk/KGQ9ZC5zbGljZSgxKXx8IioiLChhW2RdPWFbZF18fFtdKS51bnNoaWZ0KGMpKTooYVtkXT1hW2RdfHxbXSkucHVzaChjKX19ZnVuY3Rpb24gTWIoYSxiLGMsZCl7dmFyIGU9e30sZj1hPT09SWI7ZnVuY3Rpb24gZyhoKXt2YXIgaTtyZXR1cm4gZVtoXT0hMCxtLmVhY2goYVtoXXx8W10sZnVuY3Rpb24oYSxoKXt2YXIgaj1oKGIsYyxkKTtyZXR1cm4ic3RyaW5nIiE9dHlwZW9mIGp8fGZ8fGVbal0/Zj8hKGk9aik6dm9pZCAwOihiLmRhdGFUeXBlcy51bnNoaWZ0KGopLGcoaiksITEpfSksaX1yZXR1cm4gZyhiLmRhdGFUeXBlc1swXSl8fCFlWyIqIl0mJmcoIioiKX1mdW5jdGlvbiBOYihhLGIpe3ZhciBjLGQsZT1tLmFqYXhTZXR0aW5ncy5mbGF0T3B0aW9uc3x8e307Zm9yKGQgaW4gYil2b2lkIDAhPT1iW2RdJiYoKGVbZF0/YTpjfHwoYz17fSkpW2RdPWJbZF0pO3JldHVybiBjJiZtLmV4dGVuZCghMCxhLGMpLGF9ZnVuY3Rpb24gT2IoYSxiLGMpe3ZhciBkLGUsZixnLGg9YS5jb250ZW50cyxpPWEuZGF0YVR5cGVzO3doaWxlKCIqIj09PWlbMF0paS5zaGlmdCgpLHZvaWQgMD09PWUmJihlPWEubWltZVR5cGV8fGIuZ2V0UmVzcG9uc2VIZWFkZXIoIkNvbnRlbnQtVHlwZSIpKTtpZihlKWZvcihnIGluIGgpaWYoaFtnXSYmaFtnXS50ZXN0KGUpKXtpLnVuc2hpZnQoZyk7YnJlYWt9aWYoaVswXWluIGMpZj1pWzBdO2Vsc2V7Zm9yKGcgaW4gYyl7aWYoIWlbMF18fGEuY29udmVydGVyc1tnKyIgIitpWzBdXSl7Zj1nO2JyZWFrfWR8fChkPWcpfWY9Znx8ZH1yZXR1cm4gZj8oZiE9PWlbMF0mJmkudW5zaGlmdChmKSxjW2ZdKTp2b2lkIDB9ZnVuY3Rpb24gUGIoYSxiLGMsZCl7dmFyIGUsZixnLGgsaSxqPXt9LGs9YS5kYXRhVHlwZXMuc2xpY2UoKTtpZihrWzFdKWZvcihnIGluIGEuY29udmVydGVycylqW2cudG9Mb3dlckNhc2UoKV09YS5jb252ZXJ0ZXJzW2ddO2Y9ay5zaGlmdCgpO3doaWxlKGYpaWYoYS5yZXNwb25zZUZpZWxkc1tmXSYmKGNbYS5yZXNwb25zZUZpZWxkc1tmXV09YiksIWkmJmQmJmEuZGF0YUZpbHRlciYmKGI9YS5kYXRhRmlsdGVyKGIsYS5kYXRhVHlwZSkpLGk9ZixmPWsuc2hpZnQoKSlpZigiKiI9PT1mKWY9aTtlbHNlIGlmKCIqIiE9PWkmJmkhPT1mKXtpZihnPWpbaSsiICIrZl18fGpbIiogIitmXSwhZylmb3IoZSBpbiBqKWlmKGg9ZS5zcGxpdCgiICIpLGhbMV09PT1mJiYoZz1qW2krIiAiK2hbMF1dfHxqWyIqICIraFswXV0pKXtnPT09ITA/Zz1qW2VdOmpbZV0hPT0hMCYmKGY9aFswXSxrLnVuc2hpZnQoaFsxXSkpO2JyZWFrfWlmKGchPT0hMClpZihnJiZhWyJ0aHJvd3MiXSliPWcoYik7ZWxzZSB0cnl7Yj1nKGIpfWNhdGNoKGwpe3JldHVybntzdGF0ZToicGFyc2VyZXJyb3IiLGVycm9yOmc/bDoiTm8gY29udmVyc2lvbiBmcm9tICIraSsiIHRvICIrZn19fXJldHVybntzdGF0ZToic3VjY2VzcyIsZGF0YTpifX1tLmV4dGVuZCh7YWN0aXZlOjAsbGFzdE1vZGlmaWVkOnt9LGV0YWc6e30sYWpheFNldHRpbmdzOnt1cmw6emIsdHlwZToiR0VUIixpc0xvY2FsOkRiLnRlc3QoeWJbMV0pLGdsb2JhbDohMCxwcm9jZXNzRGF0YTohMCxhc3luYzohMCxjb250ZW50VHlwZToiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04IixhY2NlcHRzOnsiKiI6SmIsdGV4dDoidGV4dC9wbGFpbiIsaHRtbDoidGV4dC9odG1sIix4bWw6ImFwcGxpY2F0aW9uL3htbCwgdGV4dC94bWwiLGpzb246ImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdCJ9LGNvbnRlbnRzOnt4bWw6L3htbC8saHRtbDovaHRtbC8sanNvbjovanNvbi99LHJlc3BvbnNlRmllbGRzOnt4bWw6InJlc3BvbnNlWE1MIix0ZXh0OiJyZXNwb25zZVRleHQiLGpzb246InJlc3BvbnNlSlNPTiJ9LGNvbnZlcnRlcnM6eyIqIHRleHQiOlN0cmluZywidGV4dCBodG1sIjohMCwidGV4dCBqc29uIjptLnBhcnNlSlNPTiwidGV4dCB4bWwiOm0ucGFyc2VYTUx9LGZsYXRPcHRpb25zOnt1cmw6ITAsY29udGV4dDohMH19LGFqYXhTZXR1cDpmdW5jdGlvbihhLGIpe3JldHVybiBiP05iKE5iKGEsbS5hamF4U2V0dGluZ3MpLGIpOk5iKG0uYWpheFNldHRpbmdzLGEpfSxhamF4UHJlZmlsdGVyOkxiKEhiKSxhamF4VHJhbnNwb3J0OkxiKEliKSxhamF4OmZ1bmN0aW9uKGEsYil7Im9iamVjdCI9PXR5cGVvZiBhJiYoYj1hLGE9dm9pZCAwKSxiPWJ8fHt9O3ZhciBjLGQsZSxmLGcsaCxpLGosaz1tLmFqYXhTZXR1cCh7fSxiKSxsPWsuY29udGV4dHx8ayxuPWsuY29udGV4dCYmKGwubm9kZVR5cGV8fGwuanF1ZXJ5KT9tKGwpOm0uZXZlbnQsbz1tLkRlZmVycmVkKCkscD1tLkNhbGxiYWNrcygib25jZSBtZW1vcnkiKSxxPWsuc3RhdHVzQ29kZXx8e30scj17fSxzPXt9LHQ9MCx1PSJjYW5jZWxlZCIsdj17cmVhZHlTdGF0ZTowLGdldFJlc3BvbnNlSGVhZGVyOmZ1bmN0aW9uKGEpe3ZhciBiO2lmKDI9PT10KXtpZighail7aj17fTt3aGlsZShiPUNiLmV4ZWMoZikpaltiWzFdLnRvTG93ZXJDYXNlKCldPWJbMl19Yj1qW2EudG9Mb3dlckNhc2UoKV19cmV0dXJuIG51bGw9PWI/bnVsbDpifSxnZXRBbGxSZXNwb25zZUhlYWRlcnM6ZnVuY3Rpb24oKXtyZXR1cm4gMj09PXQ/ZjpudWxsfSxzZXRSZXF1ZXN0SGVhZGVyOmZ1bmN0aW9uKGEsYil7dmFyIGM9YS50b0xvd2VyQ2FzZSgpO3JldHVybiB0fHwoYT1zW2NdPXNbY118fGEsclthXT1iKSx0aGlzfSxvdmVycmlkZU1pbWVUeXBlOmZ1bmN0aW9uKGEpe3JldHVybiB0fHwoay5taW1lVHlwZT1hKSx0aGlzfSxzdGF0dXNDb2RlOmZ1bmN0aW9uKGEpe3ZhciBiO2lmKGEpaWYoMj50KWZvcihiIGluIGEpcVtiXT1bcVtiXSxhW2JdXTtlbHNlIHYuYWx3YXlzKGFbdi5zdGF0dXNdKTtyZXR1cm4gdGhpc30sYWJvcnQ6ZnVuY3Rpb24oYSl7dmFyIGI9YXx8dTtyZXR1cm4gaSYmaS5hYm9ydChiKSx4KDAsYiksdGhpc319O2lmKG8ucHJvbWlzZSh2KS5jb21wbGV0ZT1wLmFkZCx2LnN1Y2Nlc3M9di5kb25lLHYuZXJyb3I9di5mYWlsLGsudXJsPSgoYXx8ay51cmx8fHpiKSsiIikucmVwbGFjZShBYiwiIikucmVwbGFjZShGYix5YlsxXSsiLy8iKSxrLnR5cGU9Yi5tZXRob2R8fGIudHlwZXx8ay5tZXRob2R8fGsudHlwZSxrLmRhdGFUeXBlcz1tLnRyaW0oay5kYXRhVHlwZXx8IioiKS50b0xvd2VyQ2FzZSgpLm1hdGNoKEUpfHxbIiJdLG51bGw9PWsuY3Jvc3NEb21haW4mJihjPUdiLmV4ZWMoay51cmwudG9Mb3dlckNhc2UoKSksay5jcm9zc0RvbWFpbj0hKCFjfHxjWzFdPT09eWJbMV0mJmNbMl09PT15YlsyXSYmKGNbM118fCgiaHR0cDoiPT09Y1sxXT8iODAiOiI0NDMiKSk9PT0oeWJbM118fCgiaHR0cDoiPT09eWJbMV0/IjgwIjoiNDQzIikpKSksay5kYXRhJiZrLnByb2Nlc3NEYXRhJiYic3RyaW5nIiE9dHlwZW9mIGsuZGF0YSYmKGsuZGF0YT1tLnBhcmFtKGsuZGF0YSxrLnRyYWRpdGlvbmFsKSksTWIoSGIsayxiLHYpLDI9PT10KXJldHVybiB2O2g9bS5ldmVudCYmay5nbG9iYWwsaCYmMD09PW0uYWN0aXZlKysmJm0uZXZlbnQudHJpZ2dlcigiYWpheFN0YXJ0Iiksay50eXBlPWsudHlwZS50b1VwcGVyQ2FzZSgpLGsuaGFzQ29udGVudD0hRWIudGVzdChrLnR5cGUpLGU9ay51cmwsay5oYXNDb250ZW50fHwoay5kYXRhJiYoZT1rLnVybCs9KHdiLnRlc3QoZSk/IiYiOiI/Iikray5kYXRhLGRlbGV0ZSBrLmRhdGEpLGsuY2FjaGU9PT0hMSYmKGsudXJsPUJiLnRlc3QoZSk/ZS5yZXBsYWNlKEJiLCIkMV89Iit2YisrKTplKyh3Yi50ZXN0KGUpPyImIjoiPyIpKyJfPSIrdmIrKykpLGsuaWZNb2RpZmllZCYmKG0ubGFzdE1vZGlmaWVkW2VdJiZ2LnNldFJlcXVlc3RIZWFkZXIoIklmLU1vZGlmaWVkLVNpbmNlIixtLmxhc3RNb2RpZmllZFtlXSksbS5ldGFnW2VdJiZ2LnNldFJlcXVlc3RIZWFkZXIoIklmLU5vbmUtTWF0Y2giLG0uZXRhZ1tlXSkpLChrLmRhdGEmJmsuaGFzQ29udGVudCYmay5jb250ZW50VHlwZSE9PSExfHxiLmNvbnRlbnRUeXBlKSYmdi5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5cGUiLGsuY29udGVudFR5cGUpLHYuc2V0UmVxdWVzdEhlYWRlcigiQWNjZXB0IixrLmRhdGFUeXBlc1swXSYmay5hY2NlcHRzW2suZGF0YVR5cGVzWzBdXT9rLmFjY2VwdHNbay5kYXRhVHlwZXNbMF1dKygiKiIhPT1rLmRhdGFUeXBlc1swXT8iLCAiK0piKyI7IHE9MC4wMSI6IiIpOmsuYWNjZXB0c1siKiJdKTtmb3IoZCBpbiBrLmhlYWRlcnMpdi5zZXRSZXF1ZXN0SGVhZGVyKGQsay5oZWFkZXJzW2RdKTtpZihrLmJlZm9yZVNlbmQmJihrLmJlZm9yZVNlbmQuY2FsbChsLHYsayk9PT0hMXx8Mj09PXQpKXJldHVybiB2LmFib3J0KCk7dT0iYWJvcnQiO2ZvcihkIGlue3N1Y2Nlc3M6MSxlcnJvcjoxLGNvbXBsZXRlOjF9KXZbZF0oa1tkXSk7aWYoaT1NYihJYixrLGIsdikpe3YucmVhZHlTdGF0ZT0xLGgmJm4udHJpZ2dlcigiYWpheFNlbmQiLFt2LGtdKSxrLmFzeW5jJiZrLnRpbWVvdXQ+MCYmKGc9c2V0VGltZW91dChmdW5jdGlvbigpe3YuYWJvcnQoInRpbWVvdXQiKX0say50aW1lb3V0KSk7dHJ5e3Q9MSxpLnNlbmQocix4KX1jYXRjaCh3KXtpZighKDI+dCkpdGhyb3cgdzt4KC0xLHcpfX1lbHNlIHgoLTEsIk5vIFRyYW5zcG9ydCIpO2Z1bmN0aW9uIHgoYSxiLGMsZCl7dmFyIGoscixzLHUsdyx4PWI7MiE9PXQmJih0PTIsZyYmY2xlYXJUaW1lb3V0KGcpLGk9dm9pZCAwLGY9ZHx8IiIsdi5yZWFkeVN0YXRlPWE+MD80OjAsaj1hPj0yMDAmJjMwMD5hfHwzMDQ9PT1hLGMmJih1PU9iKGssdixjKSksdT1QYihrLHUsdixqKSxqPyhrLmlmTW9kaWZpZWQmJih3PXYuZ2V0UmVzcG9uc2VIZWFkZXIoIkxhc3QtTW9kaWZpZWQiKSx3JiYobS5sYXN0TW9kaWZpZWRbZV09dyksdz12LmdldFJlc3BvbnNlSGVhZGVyKCJldGFnIiksdyYmKG0uZXRhZ1tlXT13KSksMjA0PT09YXx8IkhFQUQiPT09ay50eXBlP3g9Im5vY29udGVudCI6MzA0PT09YT94PSJub3Rtb2RpZmllZCI6KHg9dS5zdGF0ZSxyPXUuZGF0YSxzPXUuZXJyb3Isaj0hcykpOihzPXgsKGF8fCF4KSYmKHg9ImVycm9yIiwwPmEmJihhPTApKSksdi5zdGF0dXM9YSx2LnN0YXR1c1RleHQ9KGJ8fHgpKyIiLGo/by5yZXNvbHZlV2l0aChsLFtyLHgsdl0pOm8ucmVqZWN0V2l0aChsLFt2LHgsc10pLHYuc3RhdHVzQ29kZShxKSxxPXZvaWQgMCxoJiZuLnRyaWdnZXIoaj8iYWpheFN1Y2Nlc3MiOiJhamF4RXJyb3IiLFt2LGssaj9yOnNdKSxwLmZpcmVXaXRoKGwsW3YseF0pLGgmJihuLnRyaWdnZXIoImFqYXhDb21wbGV0ZSIsW3Ysa10pLC0tbS5hY3RpdmV8fG0uZXZlbnQudHJpZ2dlcigiYWpheFN0b3AiKSkpfXJldHVybiB2fSxnZXRKU09OOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbS5nZXQoYSxiLGMsImpzb24iKX0sZ2V0U2NyaXB0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG0uZ2V0KGEsdm9pZCAwLGIsInNjcmlwdCIpfX0pLG0uZWFjaChbImdldCIsInBvc3QiXSxmdW5jdGlvbihhLGIpe21bYl09ZnVuY3Rpb24oYSxjLGQsZSl7cmV0dXJuIG0uaXNGdW5jdGlvbihjKSYmKGU9ZXx8ZCxkPWMsYz12b2lkIDApLG0uYWpheCh7dXJsOmEsdHlwZTpiLGRhdGFUeXBlOmUsZGF0YTpjLHN1Y2Nlc3M6ZH0pfX0pLG0uX2V2YWxVcmw9ZnVuY3Rpb24oYSl7cmV0dXJuIG0uYWpheCh7dXJsOmEsdHlwZToiR0VUIixkYXRhVHlwZToic2NyaXB0Iixhc3luYzohMSxnbG9iYWw6ITEsInRocm93cyI6ITB9KX0sbS5mbi5leHRlbmQoe3dyYXBBbGw6ZnVuY3Rpb24oYSl7aWYobS5pc0Z1bmN0aW9uKGEpKXJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oYil7bSh0aGlzKS53cmFwQWxsKGEuY2FsbCh0aGlzLGIpKX0pO2lmKHRoaXNbMF0pe3ZhciBiPW0oYSx0aGlzWzBdLm93bmVyRG9jdW1lbnQpLmVxKDApLmNsb25lKCEwKTt0aGlzWzBdLnBhcmVudE5vZGUmJmIuaW5zZXJ0QmVmb3JlKHRoaXNbMF0pLGIubWFwKGZ1bmN0aW9uKCl7dmFyIGE9dGhpczt3aGlsZShhLmZpcnN0Q2hpbGQmJjE9PT1hLmZpcnN0Q2hpbGQubm9kZVR5cGUpYT1hLmZpcnN0Q2hpbGQ7cmV0dXJuIGF9KS5hcHBlbmQodGhpcyl9cmV0dXJuIHRoaXN9LHdyYXBJbm5lcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lYWNoKG0uaXNGdW5jdGlvbihhKT9mdW5jdGlvbihiKXttKHRoaXMpLndyYXBJbm5lcihhLmNhbGwodGhpcyxiKSl9OmZ1bmN0aW9uKCl7dmFyIGI9bSh0aGlzKSxjPWIuY29udGVudHMoKTtjLmxlbmd0aD9jLndyYXBBbGwoYSk6Yi5hcHBlbmQoYSl9KX0sd3JhcDpmdW5jdGlvbihhKXt2YXIgYj1tLmlzRnVuY3Rpb24oYSk7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihjKXttKHRoaXMpLndyYXBBbGwoYj9hLmNhbGwodGhpcyxjKTphKX0pfSx1bndyYXA6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wYXJlbnQoKS5lYWNoKGZ1bmN0aW9uKCl7bS5ub2RlTmFtZSh0aGlzLCJib2R5Iil8fG0odGhpcykucmVwbGFjZVdpdGgodGhpcy5jaGlsZE5vZGVzKX0pLmVuZCgpfX0pLG0uZXhwci5maWx0ZXJzLmhpZGRlbj1mdW5jdGlvbihhKXtyZXR1cm4gYS5vZmZzZXRXaWR0aDw9MCYmYS5vZmZzZXRIZWlnaHQ8PTB8fCFrLnJlbGlhYmxlSGlkZGVuT2Zmc2V0cygpJiYibm9uZSI9PT0oYS5zdHlsZSYmYS5zdHlsZS5kaXNwbGF5fHxtLmNzcyhhLCJkaXNwbGF5IikpfSxtLmV4cHIuZmlsdGVycy52aXNpYmxlPWZ1bmN0aW9uKGEpe3JldHVybiFtLmV4cHIuZmlsdGVycy5oaWRkZW4oYSl9O3ZhciBRYj0vJTIwL2csUmI9L1xbXF0kLyxTYj0vXHI/XG4vZyxUYj0vXig/OnN1Ym1pdHxidXR0b258aW1hZ2V8cmVzZXR8ZmlsZSkkL2ksVWI9L14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8a2V5Z2VuKS9pO2Z1bmN0aW9uIFZiKGEsYixjLGQpe3ZhciBlO2lmKG0uaXNBcnJheShiKSltLmVhY2goYixmdW5jdGlvbihiLGUpe2N8fFJiLnRlc3QoYSk/ZChhLGUpOlZiKGErIlsiKygib2JqZWN0Ij09dHlwZW9mIGU/YjoiIikrIl0iLGUsYyxkKX0pO2Vsc2UgaWYoY3x8Im9iamVjdCIhPT1tLnR5cGUoYikpZChhLGIpO2Vsc2UgZm9yKGUgaW4gYilWYihhKyJbIitlKyJdIixiW2VdLGMsZCl9bS5wYXJhbT1mdW5jdGlvbihhLGIpe3ZhciBjLGQ9W10sZT1mdW5jdGlvbihhLGIpe2I9bS5pc0Z1bmN0aW9uKGIpP2IoKTpudWxsPT1iPyIiOmIsZFtkLmxlbmd0aF09ZW5jb2RlVVJJQ29tcG9uZW50KGEpKyI9IitlbmNvZGVVUklDb21wb25lbnQoYil9O2lmKHZvaWQgMD09PWImJihiPW0uYWpheFNldHRpbmdzJiZtLmFqYXhTZXR0aW5ncy50cmFkaXRpb25hbCksbS5pc0FycmF5KGEpfHxhLmpxdWVyeSYmIW0uaXNQbGFpbk9iamVjdChhKSltLmVhY2goYSxmdW5jdGlvbigpe2UodGhpcy5uYW1lLHRoaXMudmFsdWUpfSk7ZWxzZSBmb3IoYyBpbiBhKVZiKGMsYVtjXSxiLGUpO3JldHVybiBkLmpvaW4oIiYiKS5yZXBsYWNlKFFiLCIrIil9LG0uZm4uZXh0ZW5kKHtzZXJpYWxpemU6ZnVuY3Rpb24oKXtyZXR1cm4gbS5wYXJhbSh0aGlzLnNlcmlhbGl6ZUFycmF5KCkpfSxzZXJpYWxpemVBcnJheTpmdW5jdGlvbigpe3JldHVybiB0aGlzLm1hcChmdW5jdGlvbigpe3ZhciBhPW0ucHJvcCh0aGlzLCJlbGVtZW50cyIpO3JldHVybiBhP20ubWFrZUFycmF5KGEpOnRoaXN9KS5maWx0ZXIoZnVuY3Rpb24oKXt2YXIgYT10aGlzLnR5cGU7cmV0dXJuIHRoaXMubmFtZSYmIW0odGhpcykuaXMoIjpkaXNhYmxlZCIpJiZVYi50ZXN0KHRoaXMubm9kZU5hbWUpJiYhVGIudGVzdChhKSYmKHRoaXMuY2hlY2tlZHx8IVcudGVzdChhKSl9KS5tYXAoZnVuY3Rpb24oYSxiKXt2YXIgYz1tKHRoaXMpLnZhbCgpO3JldHVybiBudWxsPT1jP251bGw6bS5pc0FycmF5KGMpP20ubWFwKGMsZnVuY3Rpb24oYSl7cmV0dXJue25hbWU6Yi5uYW1lLHZhbHVlOmEucmVwbGFjZShTYiwiXHJcbiIpfX0pOntuYW1lOmIubmFtZSx2YWx1ZTpjLnJlcGxhY2UoU2IsIlxyXG4iKX19KS5nZXQoKX19KSxtLmFqYXhTZXR0aW5ncy54aHI9dm9pZCAwIT09YS5BY3RpdmVYT2JqZWN0P2Z1bmN0aW9uKCl7cmV0dXJuIXRoaXMuaXNMb2NhbCYmL14oZ2V0fHBvc3R8aGVhZHxwdXR8ZGVsZXRlfG9wdGlvbnMpJC9pLnRlc3QodGhpcy50eXBlKSYmWmIoKXx8JGIoKX06WmI7dmFyIFdiPTAsWGI9e30sWWI9bS5hamF4U2V0dGluZ3MueGhyKCk7YS5hdHRhY2hFdmVudCYmYS5hdHRhY2hFdmVudCgib251bmxvYWQiLGZ1bmN0aW9uKCl7Zm9yKHZhciBhIGluIFhiKVhiW2FdKHZvaWQgMCwhMCl9KSxrLmNvcnM9ISFZYiYmIndpdGhDcmVkZW50aWFscyJpbiBZYixZYj1rLmFqYXg9ISFZYixZYiYmbS5hamF4VHJhbnNwb3J0KGZ1bmN0aW9uKGEpe2lmKCFhLmNyb3NzRG9tYWlufHxrLmNvcnMpe3ZhciBiO3JldHVybntzZW5kOmZ1bmN0aW9uKGMsZCl7dmFyIGUsZj1hLnhocigpLGc9KytXYjtpZihmLm9wZW4oYS50eXBlLGEudXJsLGEuYXN5bmMsYS51c2VybmFtZSxhLnBhc3N3b3JkKSxhLnhockZpZWxkcylmb3IoZSBpbiBhLnhockZpZWxkcylmW2VdPWEueGhyRmllbGRzW2VdO2EubWltZVR5cGUmJmYub3ZlcnJpZGVNaW1lVHlwZSYmZi5vdmVycmlkZU1pbWVUeXBlKGEubWltZVR5cGUpLGEuY3Jvc3NEb21haW58fGNbIlgtUmVxdWVzdGVkLVdpdGgiXXx8KGNbIlgtUmVxdWVzdGVkLVdpdGgiXT0iWE1MSHR0cFJlcXVlc3QiKTtmb3IoZSBpbiBjKXZvaWQgMCE9PWNbZV0mJmYuc2V0UmVxdWVzdEhlYWRlcihlLGNbZV0rIiIpO2Yuc2VuZChhLmhhc0NvbnRlbnQmJmEuZGF0YXx8bnVsbCksYj1mdW5jdGlvbihjLGUpe3ZhciBoLGksajtpZihiJiYoZXx8ND09PWYucmVhZHlTdGF0ZSkpaWYoZGVsZXRlIFhiW2ddLGI9dm9pZCAwLGYub25yZWFkeXN0YXRlY2hhbmdlPW0ubm9vcCxlKTQhPT1mLnJlYWR5U3RhdGUmJmYuYWJvcnQoKTtlbHNle2o9e30saD1mLnN0YXR1cywic3RyaW5nIj09dHlwZW9mIGYucmVzcG9uc2VUZXh0JiYoai50ZXh0PWYucmVzcG9uc2VUZXh0KTt0cnl7aT1mLnN0YXR1c1RleHR9Y2F0Y2goayl7aT0iIn1ofHwhYS5pc0xvY2FsfHxhLmNyb3NzRG9tYWluPzEyMjM9PT1oJiYoaD0yMDQpOmg9ai50ZXh0PzIwMDo0MDR9aiYmZChoLGksaixmLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKX0sYS5hc3luYz80PT09Zi5yZWFkeVN0YXRlP3NldFRpbWVvdXQoYik6Zi5vbnJlYWR5c3RhdGVjaGFuZ2U9WGJbZ109YjpiKCl9LGFib3J0OmZ1bmN0aW9uKCl7YiYmYih2b2lkIDAsITApfX19fSk7ZnVuY3Rpb24gWmIoKXt0cnl7cmV0dXJuIG5ldyBhLlhNTEh0dHBSZXF1ZXN0fWNhdGNoKGIpe319ZnVuY3Rpb24gJGIoKXt0cnl7cmV0dXJuIG5ldyBhLkFjdGl2ZVhPYmplY3QoIk1pY3Jvc29mdC5YTUxIVFRQIil9Y2F0Y2goYil7fX1tLmFqYXhTZXR1cCh7YWNjZXB0czp7c2NyaXB0OiJ0ZXh0L2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2VjbWFzY3JpcHQsIGFwcGxpY2F0aW9uL3gtZWNtYXNjcmlwdCJ9LGNvbnRlbnRzOntzY3JpcHQ6Lyg/OmphdmF8ZWNtYSlzY3JpcHQvfSxjb252ZXJ0ZXJzOnsidGV4dCBzY3JpcHQiOmZ1bmN0aW9uKGEpe3JldHVybiBtLmdsb2JhbEV2YWwoYSksYX19fSksbS5hamF4UHJlZmlsdGVyKCJzY3JpcHQiLGZ1bmN0aW9uKGEpe3ZvaWQgMD09PWEuY2FjaGUmJihhLmNhY2hlPSExKSxhLmNyb3NzRG9tYWluJiYoYS50eXBlPSJHRVQiLGEuZ2xvYmFsPSExKX0pLG0uYWpheFRyYW5zcG9ydCgic2NyaXB0IixmdW5jdGlvbihhKXtpZihhLmNyb3NzRG9tYWluKXt2YXIgYixjPXkuaGVhZHx8bSgiaGVhZCIpWzBdfHx5LmRvY3VtZW50RWxlbWVudDtyZXR1cm57c2VuZDpmdW5jdGlvbihkLGUpe2I9eS5jcmVhdGVFbGVtZW50KCJzY3JpcHQiKSxiLmFzeW5jPSEwLGEuc2NyaXB0Q2hhcnNldCYmKGIuY2hhcnNldD1hLnNjcmlwdENoYXJzZXQpLGIuc3JjPWEudXJsLGIub25sb2FkPWIub25yZWFkeXN0YXRlY2hhbmdlPWZ1bmN0aW9uKGEsYyl7KGN8fCFiLnJlYWR5U3RhdGV8fC9sb2FkZWR8Y29tcGxldGUvLnRlc3QoYi5yZWFkeVN0YXRlKSkmJihiLm9ubG9hZD1iLm9ucmVhZHlzdGF0ZWNoYW5nZT1udWxsLGIucGFyZW50Tm9kZSYmYi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGIpLGI9bnVsbCxjfHxlKDIwMCwic3VjY2VzcyIpKX0sYy5pbnNlcnRCZWZvcmUoYixjLmZpcnN0Q2hpbGQpfSxhYm9ydDpmdW5jdGlvbigpe2ImJmIub25sb2FkKHZvaWQgMCwhMCl9fX19KTt2YXIgX2I9W10sYWM9Lyg9KVw/KD89JnwkKXxcP1w/LzttLmFqYXhTZXR1cCh7anNvbnA6ImNhbGxiYWNrIixqc29ucENhbGxiYWNrOmZ1bmN0aW9uKCl7dmFyIGE9X2IucG9wKCl8fG0uZXhwYW5kbysiXyIrdmIrKztyZXR1cm4gdGhpc1thXT0hMCxhfX0pLG0uYWpheFByZWZpbHRlcigianNvbiBqc29ucCIsZnVuY3Rpb24oYixjLGQpe3ZhciBlLGYsZyxoPWIuanNvbnAhPT0hMSYmKGFjLnRlc3QoYi51cmwpPyJ1cmwiOiJzdHJpbmciPT10eXBlb2YgYi5kYXRhJiYhKGIuY29udGVudFR5cGV8fCIiKS5pbmRleE9mKCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiKSYmYWMudGVzdChiLmRhdGEpJiYiZGF0YSIpO3JldHVybiBofHwianNvbnAiPT09Yi5kYXRhVHlwZXNbMF0/KGU9Yi5qc29ucENhbGxiYWNrPW0uaXNGdW5jdGlvbihiLmpzb25wQ2FsbGJhY2spP2IuanNvbnBDYWxsYmFjaygpOmIuanNvbnBDYWxsYmFjayxoP2JbaF09YltoXS5yZXBsYWNlKGFjLCIkMSIrZSk6Yi5qc29ucCE9PSExJiYoYi51cmwrPSh3Yi50ZXN0KGIudXJsKT8iJiI6Ij8iKStiLmpzb25wKyI9IitlKSxiLmNvbnZlcnRlcnNbInNjcmlwdCBqc29uIl09ZnVuY3Rpb24oKXtyZXR1cm4gZ3x8bS5lcnJvcihlKyIgd2FzIG5vdCBjYWxsZWQiKSxnWzBdfSxiLmRhdGFUeXBlc1swXT0ianNvbiIsZj1hW2VdLGFbZV09ZnVuY3Rpb24oKXtnPWFyZ3VtZW50c30sZC5hbHdheXMoZnVuY3Rpb24oKXthW2VdPWYsYltlXSYmKGIuanNvbnBDYWxsYmFjaz1jLmpzb25wQ2FsbGJhY2ssX2IucHVzaChlKSksZyYmbS5pc0Z1bmN0aW9uKGYpJiZmKGdbMF0pLGc9Zj12b2lkIDB9KSwic2NyaXB0Iik6dm9pZCAwfSksbS5wYXJzZUhUTUw9ZnVuY3Rpb24oYSxiLGMpe2lmKCFhfHwic3RyaW5nIiE9dHlwZW9mIGEpcmV0dXJuIG51bGw7ImJvb2xlYW4iPT10eXBlb2YgYiYmKGM9YixiPSExKSxiPWJ8fHk7dmFyIGQ9dS5leGVjKGEpLGU9IWMmJltdO3JldHVybiBkP1tiLmNyZWF0ZUVsZW1lbnQoZFsxXSldOihkPW0uYnVpbGRGcmFnbWVudChbYV0sYixlKSxlJiZlLmxlbmd0aCYmbShlKS5yZW1vdmUoKSxtLm1lcmdlKFtdLGQuY2hpbGROb2RlcykpfTt2YXIgYmM9bS5mbi5sb2FkO20uZm4ubG9hZD1mdW5jdGlvbihhLGIsYyl7aWYoInN0cmluZyIhPXR5cGVvZiBhJiZiYylyZXR1cm4gYmMuYXBwbHkodGhpcyxhcmd1bWVudHMpO3ZhciBkLGUsZixnPXRoaXMsaD1hLmluZGV4T2YoIiAiKTtyZXR1cm4gaD49MCYmKGQ9bS50cmltKGEuc2xpY2UoaCxhLmxlbmd0aCkpLGE9YS5zbGljZSgwLGgpKSxtLmlzRnVuY3Rpb24oYik/KGM9YixiPXZvaWQgMCk6YiYmIm9iamVjdCI9PXR5cGVvZiBiJiYoZj0iUE9TVCIpLGcubGVuZ3RoPjAmJm0uYWpheCh7dXJsOmEsdHlwZTpmLGRhdGFUeXBlOiJodG1sIixkYXRhOmJ9KS5kb25lKGZ1bmN0aW9uKGEpe2U9YXJndW1lbnRzLGcuaHRtbChkP20oIjxkaXY+IikuYXBwZW5kKG0ucGFyc2VIVE1MKGEpKS5maW5kKGQpOmEpfSkuY29tcGxldGUoYyYmZnVuY3Rpb24oYSxiKXtnLmVhY2goYyxlfHxbYS5yZXNwb25zZVRleHQsYixhXSl9KSx0aGlzfSxtLmVhY2goWyJhamF4U3RhcnQiLCJhamF4U3RvcCIsImFqYXhDb21wbGV0ZSIsImFqYXhFcnJvciIsImFqYXhTdWNjZXNzIiwiYWpheFNlbmQiXSxmdW5jdGlvbihhLGIpe20uZm5bYl09ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMub24oYixhKX19KSxtLmV4cHIuZmlsdGVycy5hbmltYXRlZD1mdW5jdGlvbihhKXtyZXR1cm4gbS5ncmVwKG0udGltZXJzLGZ1bmN0aW9uKGIpe3JldHVybiBhPT09Yi5lbGVtfSkubGVuZ3RofTt2YXIgY2M9YS5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7ZnVuY3Rpb24gZGMoYSl7cmV0dXJuIG0uaXNXaW5kb3coYSk/YTo5PT09YS5ub2RlVHlwZT9hLmRlZmF1bHRWaWV3fHxhLnBhcmVudFdpbmRvdzohMX1tLm9mZnNldD17c2V0T2Zmc2V0OmZ1bmN0aW9uKGEsYixjKXt2YXIgZCxlLGYsZyxoLGksaixrPW0uY3NzKGEsInBvc2l0aW9uIiksbD1tKGEpLG49e307InN0YXRpYyI9PT1rJiYoYS5zdHlsZS5wb3NpdGlvbj0icmVsYXRpdmUiKSxoPWwub2Zmc2V0KCksZj1tLmNzcyhhLCJ0b3AiKSxpPW0uY3NzKGEsImxlZnQiKSxqPSgiYWJzb2x1dGUiPT09a3x8ImZpeGVkIj09PWspJiZtLmluQXJyYXkoImF1dG8iLFtmLGldKT4tMSxqPyhkPWwucG9zaXRpb24oKSxnPWQudG9wLGU9ZC5sZWZ0KTooZz1wYXJzZUZsb2F0KGYpfHwwLGU9cGFyc2VGbG9hdChpKXx8MCksbS5pc0Z1bmN0aW9uKGIpJiYoYj1iLmNhbGwoYSxjLGgpKSxudWxsIT1iLnRvcCYmKG4udG9wPWIudG9wLWgudG9wK2cpLG51bGwhPWIubGVmdCYmKG4ubGVmdD1iLmxlZnQtaC5sZWZ0K2UpLCJ1c2luZyJpbiBiP2IudXNpbmcuY2FsbChhLG4pOmwuY3NzKG4pfX0sbS5mbi5leHRlbmQoe29mZnNldDpmdW5jdGlvbihhKXtpZihhcmd1bWVudHMubGVuZ3RoKXJldHVybiB2b2lkIDA9PT1hP3RoaXM6dGhpcy5lYWNoKGZ1bmN0aW9uKGIpe20ub2Zmc2V0LnNldE9mZnNldCh0aGlzLGEsYil9KTt2YXIgYixjLGQ9e3RvcDowLGxlZnQ6MH0sZT10aGlzWzBdLGY9ZSYmZS5vd25lckRvY3VtZW50O2lmKGYpcmV0dXJuIGI9Zi5kb2N1bWVudEVsZW1lbnQsbS5jb250YWlucyhiLGUpPyh0eXBlb2YgZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QhPT1LJiYoZD1lLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKSxjPWRjKGYpLHt0b3A6ZC50b3ArKGMucGFnZVlPZmZzZXR8fGIuc2Nyb2xsVG9wKS0oYi5jbGllbnRUb3B8fDApLGxlZnQ6ZC5sZWZ0KyhjLnBhZ2VYT2Zmc2V0fHxiLnNjcm9sbExlZnQpLShiLmNsaWVudExlZnR8fDApfSk6ZH0scG9zaXRpb246ZnVuY3Rpb24oKXtpZih0aGlzWzBdKXt2YXIgYSxiLGM9e3RvcDowLGxlZnQ6MH0sZD10aGlzWzBdO3JldHVybiJmaXhlZCI9PT1tLmNzcyhkLCJwb3NpdGlvbiIpP2I9ZC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTooYT10aGlzLm9mZnNldFBhcmVudCgpLGI9dGhpcy5vZmZzZXQoKSxtLm5vZGVOYW1lKGFbMF0sImh0bWwiKXx8KGM9YS5vZmZzZXQoKSksYy50b3ArPW0uY3NzKGFbMF0sImJvcmRlclRvcFdpZHRoIiwhMCksYy5sZWZ0Kz1tLmNzcyhhWzBdLCJib3JkZXJMZWZ0V2lkdGgiLCEwKSkse3RvcDpiLnRvcC1jLnRvcC1tLmNzcyhkLCJtYXJnaW5Ub3AiLCEwKSxsZWZ0OmIubGVmdC1jLmxlZnQtbS5jc3MoZCwibWFyZ2luTGVmdCIsITApfX19LG9mZnNldFBhcmVudDpmdW5jdGlvbigpe3JldHVybiB0aGlzLm1hcChmdW5jdGlvbigpe3ZhciBhPXRoaXMub2Zmc2V0UGFyZW50fHxjYzt3aGlsZShhJiYhbS5ub2RlTmFtZShhLCJodG1sIikmJiJzdGF0aWMiPT09bS5jc3MoYSwicG9zaXRpb24iKSlhPWEub2Zmc2V0UGFyZW50O3JldHVybiBhfHxjY30pfX0pLG0uZWFjaCh7c2Nyb2xsTGVmdDoicGFnZVhPZmZzZXQiLHNjcm9sbFRvcDoicGFnZVlPZmZzZXQifSxmdW5jdGlvbihhLGIpe3ZhciBjPS9ZLy50ZXN0KGIpO20uZm5bYV09ZnVuY3Rpb24oZCl7cmV0dXJuIFYodGhpcyxmdW5jdGlvbihhLGQsZSl7dmFyIGY9ZGMoYSk7cmV0dXJuIHZvaWQgMD09PWU/Zj9iIGluIGY/ZltiXTpmLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudFtkXTphW2RdOnZvaWQoZj9mLnNjcm9sbFRvKGM/bShmKS5zY3JvbGxMZWZ0KCk6ZSxjP2U6bShmKS5zY3JvbGxUb3AoKSk6YVtkXT1lKX0sYSxkLGFyZ3VtZW50cy5sZW5ndGgsbnVsbCl9fSksbS5lYWNoKFsidG9wIiwibGVmdCJdLGZ1bmN0aW9uKGEsYil7bS5jc3NIb29rc1tiXT1MYShrLnBpeGVsUG9zaXRpb24sZnVuY3Rpb24oYSxjKXtyZXR1cm4gYz8oYz1KYShhLGIpLEhhLnRlc3QoYyk/bShhKS5wb3NpdGlvbigpW2JdKyJweCI6Yyk6dm9pZCAwfSl9KSxtLmVhY2goe0hlaWdodDoiaGVpZ2h0IixXaWR0aDoid2lkdGgifSxmdW5jdGlvbihhLGIpe20uZWFjaCh7cGFkZGluZzoiaW5uZXIiK2EsY29udGVudDpiLCIiOiJvdXRlciIrYX0sZnVuY3Rpb24oYyxkKXttLmZuW2RdPWZ1bmN0aW9uKGQsZSl7dmFyIGY9YXJndW1lbnRzLmxlbmd0aCYmKGN8fCJib29sZWFuIiE9dHlwZW9mIGQpLGc9Y3x8KGQ9PT0hMHx8ZT09PSEwPyJtYXJnaW4iOiJib3JkZXIiKTtyZXR1cm4gVih0aGlzLGZ1bmN0aW9uKGIsYyxkKXt2YXIgZTtyZXR1cm4gbS5pc1dpbmRvdyhiKT9iLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudFsiY2xpZW50IithXTo5PT09Yi5ub2RlVHlwZT8oZT1iLmRvY3VtZW50RWxlbWVudCxNYXRoLm1heChiLmJvZHlbInNjcm9sbCIrYV0sZVsic2Nyb2xsIithXSxiLmJvZHlbIm9mZnNldCIrYV0sZVsib2Zmc2V0IithXSxlWyJjbGllbnQiK2FdKSk6dm9pZCAwPT09ZD9tLmNzcyhiLGMsZyk6bS5zdHlsZShiLGMsZCxnKX0sYixmP2Q6dm9pZCAwLGYsbnVsbCl9fSl9KSxtLmZuLnNpemU9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5sZW5ndGh9LG0uZm4uYW5kU2VsZj1tLmZuLmFkZEJhY2ssImZ1bmN0aW9uIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZCYmZGVmaW5lKCJqcXVlcnkiLFtdLGZ1bmN0aW9uKCl7cmV0dXJuIG19KTt2YXIgZWM9YS5qUXVlcnksZmM9YS4kO3JldHVybiBtLm5vQ29uZmxpY3Q9ZnVuY3Rpb24oYil7cmV0dXJuIGEuJD09PW0mJihhLiQ9ZmMpLGImJmEualF1ZXJ5PT09bSYmKGEualF1ZXJ5PWVjKSxtfSx0eXBlb2YgYj09PUsmJihhLmpRdWVyeT1hLiQ9bSksbX0pOwo=\"></script>\n",
"<script src=\"data:application/javascript;base64,IWZ1bmN0aW9uIGEoYixjLGQpe2Z1bmN0aW9uIGUoZyxoKXtpZighY1tnXSl7aWYoIWJbZ10pe3ZhciBpPSJmdW5jdGlvbiI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFoJiZpKXJldHVybiBpKGcsITApO2lmKGYpcmV0dXJuIGYoZywhMCk7dmFyIGo9bmV3IEVycm9yKCJDYW5ub3QgZmluZCBtb2R1bGUgJyIrZysiJyIpO3Rocm93IGouY29kZT0iTU9EVUxFX05PVF9GT1VORCIsan12YXIgaz1jW2ddPXtleHBvcnRzOnt9fTtiW2ddWzBdLmNhbGwoay5leHBvcnRzLGZ1bmN0aW9uKGEpe3ZhciBjPWJbZ11bMV1bYV07cmV0dXJuIGUoYz9jOmEpfSxrLGsuZXhwb3J0cyxhLGIsYyxkKX1yZXR1cm4gY1tnXS5leHBvcnRzfWZvcih2YXIgZj0iZnVuY3Rpb24iPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxnPTA7ZzxkLmxlbmd0aDtnKyspZShkW2ddKTtyZXR1cm4gZX0oezE6W2Z1bmN0aW9uKGEsYixjKXsidXNlIHN0cmljdCI7ZnVuY3Rpb24gZChhLGIpe2lmKCEoYSBpbnN0YW5jZW9mIGIpKXRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpfU9iamVjdC5kZWZpbmVQcm9wZXJ0eShjLCJfX2VzTW9kdWxlIix7dmFsdWU6ITB9KTt2YXIgZT1mdW5jdGlvbigpe2Z1bmN0aW9uIGEoYSxiKXtmb3IodmFyIGM9MDtjPGIubGVuZ3RoO2MrKyl7dmFyIGQ9YltjXTtkLmVudW1lcmFibGU9ZC5lbnVtZXJhYmxlfHwhMSxkLmNvbmZpZ3VyYWJsZT0hMCwidmFsdWUiaW4gZCYmKGQud3JpdGFibGU9ITApLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLGQua2V5LGQpfX1yZXR1cm4gZnVuY3Rpb24oYixjLGQpe3JldHVybiBjJiZhKGIucHJvdG90eXBlLGMpLGQmJmEoYixkKSxifX0oKSxmPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gYSgpe2QodGhpcyxhKSx0aGlzLl90eXBlcz17fSx0aGlzLl9zZXE9MH1yZXR1cm4gZShhLFt7a2V5OiJvbiIsdmFsdWU6ZnVuY3Rpb24oYSxiKXt2YXIgYz10aGlzLl90eXBlc1thXTtjfHwoYz10aGlzLl90eXBlc1thXT17fSk7dmFyIGQ9InN1YiIrdGhpcy5fc2VxKys7cmV0dXJuIGNbZF09YixkfX0se2tleToib2ZmIix2YWx1ZTpmdW5jdGlvbihhLGIpe3ZhciBjPXRoaXMuX3R5cGVzW2FdO2lmKCJmdW5jdGlvbiI9PXR5cGVvZiBiKXtmb3IodmFyIGQgaW4gYylpZihjLmhhc093blByb3BlcnR5KGQpJiZjW2RdPT09YilyZXR1cm4gZGVsZXRlIGNbZF0sZDtyZXR1cm4hMX1pZigic3RyaW5nIj09dHlwZW9mIGIpcmV0dXJuISghY3x8IWNbYl0pJiYoZGVsZXRlIGNbYl0sYik7dGhyb3cgbmV3IEVycm9yKCJVbmV4cGVjdGVkIHR5cGUgZm9yIGxpc3RlbmVyIil9fSx7a2V5OiJ0cmlnZ2VyIix2YWx1ZTpmdW5jdGlvbihhLGIsYyl7dmFyIGQ9dGhpcy5fdHlwZXNbYV07Zm9yKHZhciBlIGluIGQpZC5oYXNPd25Qcm9wZXJ0eShlKSYmZFtlXS5jYWxsKGMsYil9fV0pLGF9KCk7Yy5kZWZhdWx0PWZ9LHt9XSwyOltmdW5jdGlvbihhLGIsYyl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIGQoYSl7aWYoYSYmYS5fX2VzTW9kdWxlKXJldHVybiBhO3ZhciBiPXt9O2lmKG51bGwhPWEpZm9yKHZhciBjIGluIGEpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGEsYykmJihiW2NdPWFbY10pO3JldHVybiBiLmRlZmF1bHQ9YSxifWZ1bmN0aW9uIGUoYSl7cmV0dXJuIGEmJmEuX19lc01vZHVsZT9hOntkZWZhdWx0OmF9fWZ1bmN0aW9uIGYoYSxiKXtpZighKGEgaW5zdGFuY2VvZiBiKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKX1mdW5jdGlvbiBnKGEpe3ZhciBiPWEudmFyKCJmaWx0ZXJzZXQiKSxjPWIuZ2V0KCk7cmV0dXJuIGN8fChjPW5ldyBtLmRlZmF1bHQsYi5zZXQoYykpLGN9ZnVuY3Rpb24gaCgpe3JldHVybiByKyt9T2JqZWN0LmRlZmluZVByb3BlcnR5KGMsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLGMuRmlsdGVySGFuZGxlPXZvaWQgMDt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIGEoYSxiKXtmb3IodmFyIGM9MDtjPGIubGVuZ3RoO2MrKyl7dmFyIGQ9YltjXTtkLmVudW1lcmFibGU9ZC5lbnVtZXJhYmxlfHwhMSxkLmNvbmZpZ3VyYWJsZT0hMCwidmFsdWUiaW4gZCYmKGQud3JpdGFibGU9ITApLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLGQua2V5LGQpfX1yZXR1cm4gZnVuY3Rpb24oYixjLGQpe3JldHVybiBjJiZhKGIucHJvdG90eXBlLGMpLGQmJmEoYixkKSxifX0oKSxqPWEoIi4vZXZlbnRzIiksaz1lKGopLGw9YSgiLi9maWx0ZXJzZXQiKSxtPWUobCksbj1hKCIuL2dyb3VwIiksbz1lKG4pLHA9YSgiLi91dGlsIikscT1kKHApLHI9MTtjLkZpbHRlckhhbmRsZT1mdW5jdGlvbigpe2Z1bmN0aW9uIGEoYixjKXtmKHRoaXMsYSksdGhpcy5fZXZlbnRSZWxheT1uZXcgay5kZWZhdWx0LHRoaXMuX2VtaXR0ZXI9bmV3IHEuU3Vic2NyaXB0aW9uVHJhY2tlcih0aGlzLl9ldmVudFJlbGF5KSx0aGlzLl9ncm91cD1udWxsLHRoaXMuX2ZpbHRlclNldD1udWxsLHRoaXMuX2ZpbHRlclZhcj1udWxsLHRoaXMuX3Zhck9uQ2hhbmdlU3ViPW51bGwsdGhpcy5fZXh0cmFJbmZvPXEuZXh0ZW5kKHtzZW5kZXI6dGhpc30sYyksdGhpcy5faWQ9ImZpbHRlciIraCgpLHRoaXMuc2V0R3JvdXAoYil9cmV0dXJuIGkoYSxbe2tleToic2V0R3JvdXAiLHZhbHVlOmZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7aWYodGhpcy5fZ3JvdXAhPT1hJiYodGhpcy5fZ3JvdXB8fGEpJiYodGhpcy5fZmlsdGVyVmFyJiYodGhpcy5fZmlsdGVyVmFyLm9mZigiY2hhbmdlIix0aGlzLl92YXJPbkNoYW5nZVN1YiksdGhpcy5jbGVhcigpLHRoaXMuX3Zhck9uQ2hhbmdlU3ViPW51bGwsdGhpcy5fZmlsdGVyVmFyPW51bGwsdGhpcy5fZmlsdGVyU2V0PW51bGwpLHRoaXMuX2dyb3VwPWEsYSkpe2E9KDAsby5kZWZhdWx0KShhKSx0aGlzLl9maWx0ZXJTZXQ9ZyhhKSx0aGlzLl9maWx0ZXJWYXI9KDAsby5kZWZhdWx0KShhKS52YXIoImZpbHRlciIpO3ZhciBjPXRoaXMuX2ZpbHRlclZhci5vbigiY2hhbmdlIixmdW5jdGlvbihhKXtiLl9ldmVudFJlbGF5LnRyaWdnZXIoImNoYW5nZSIsYSxiKX0pO3RoaXMuX3Zhck9uQ2hhbmdlU3ViPWN9fX0se2tleToiX21lcmdlRXh0cmFJbmZvIix2YWx1ZTpmdW5jdGlvbihhKXtyZXR1cm4gcS5leHRlbmQoe30sdGhpcy5fZXh0cmFJbmZvP3RoaXMuX2V4dHJhSW5mbzpudWxsLGE/YTpudWxsKX19LHtrZXk6ImNsb3NlIix2YWx1ZTpmdW5jdGlvbigpe3RoaXMuX2VtaXR0ZXIucmVtb3ZlQWxsTGlzdGVuZXJzKCksdGhpcy5jbGVhcigpLHRoaXMuc2V0R3JvdXAobnVsbCl9fSx7a2V5OiJjbGVhciIsdmFsdWU6ZnVuY3Rpb24oYSl7dGhpcy5fZmlsdGVyU2V0JiYodGhpcy5fZmlsdGVyU2V0LmNsZWFyKHRoaXMuX2lkKSx0aGlzLl9vbkNoYW5nZShhKSl9fSx7a2V5OiJzZXQiLHZhbHVlOmZ1bmN0aW9uKGEsYil7dGhpcy5fZmlsdGVyU2V0JiYodGhpcy5fZmlsdGVyU2V0LnVwZGF0ZSh0aGlzLl9pZCxhKSx0aGlzLl9vbkNoYW5nZShiKSl9fSx7a2V5OiJvbiIsdmFsdWU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5fZW1pdHRlci5vbihhLGIpfX0se2tleToib2ZmIix2YWx1ZTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLl9lbWl0dGVyLm9mZihhLGIpfX0se2tleToiX29uQ2hhbmdlIix2YWx1ZTpmdW5jdGlvbihhKXt0aGlzLl9maWx0ZXJTZXQmJnRoaXMuX2ZpbHRlclZhci5zZXQodGhpcy5fZmlsdGVyU2V0LnZhbHVlLHRoaXMuX21lcmdlRXh0cmFJbmZvKGEpKX19LHtrZXk6ImZpbHRlcmVkS2V5cyIsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX2ZpbHRlclNldD90aGlzLl9maWx0ZXJTZXQudmFsdWU6bnVsbH19XSksYX0oKX0seyIuL2V2ZW50cyI6MSwiLi9maWx0ZXJzZXQiOjMsIi4vZ3JvdXAiOjQsIi4vdXRpbCI6MTF9XSwzOltmdW5jdGlvbihhLGIsYyl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIGQoYSxiKXtpZighKGEgaW5zdGFuY2VvZiBiKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKX1mdW5jdGlvbiBlKGEsYil7cmV0dXJuIGE9PT1iPzA6YTxiPy0xOmE+Yj8xOnZvaWQgMH1PYmplY3QuZGVmaW5lUHJvcGVydHkoYywiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7dmFyIGY9ZnVuY3Rpb24oKXtmdW5jdGlvbiBhKGEsYil7Zm9yKHZhciBjPTA7YzxiLmxlbmd0aDtjKyspe3ZhciBkPWJbY107ZC5lbnVtZXJhYmxlPWQuZW51bWVyYWJsZXx8ITEsZC5jb25maWd1cmFibGU9ITAsInZhbHVlImluIGQmJihkLndyaXRhYmxlPSEwKSxPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxkLmtleSxkKX19cmV0dXJuIGZ1bmN0aW9uKGIsYyxkKXtyZXR1cm4gYyYmYShiLnByb3RvdHlwZSxjKSxkJiZhKGIsZCksYn19KCksZz1hKCIuL3V0aWwiKSxoPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gYSgpe2QodGhpcyxhKSx0aGlzLnJlc2V0KCl9cmV0dXJuIGYoYSxbe2tleToicmVzZXQiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5faGFuZGxlcz17fSx0aGlzLl9rZXlzPXt9LHRoaXMuX3ZhbHVlPW51bGwsdGhpcy5fYWN0aXZlSGFuZGxlcz0wfX0se2tleToidXBkYXRlIix2YWx1ZTpmdW5jdGlvbihhLGIpe251bGwhPT1iJiYoYj1iLnNsaWNlKDApLGIuc29ydChlKSk7dmFyIGM9KDAsZy5kaWZmU29ydGVkTGlzdHMpKHRoaXMuX2hhbmRsZXNbYV0sYiksZD1jLmFkZGVkLGY9Yy5yZW1vdmVkO3RoaXMuX2hhbmRsZXNbYV09Yjtmb3IodmFyIGg9MDtoPGQubGVuZ3RoO2grKyl0aGlzLl9rZXlzW2RbaF1dPSh0aGlzLl9rZXlzW2RbaF1dfHwwKSsxO2Zvcih2YXIgaT0wO2k8Zi5sZW5ndGg7aSsrKXRoaXMuX2tleXNbZltpXV0tLTt0aGlzLl91cGRhdGVWYWx1ZShiKX19LHtrZXk6Il91cGRhdGVWYWx1ZSIsdmFsdWU6ZnVuY3Rpb24oKXt2YXIgYT1hcmd1bWVudHMubGVuZ3RoPjAmJnZvaWQgMCE9PWFyZ3VtZW50c1swXT9hcmd1bWVudHNbMF06dGhpcy5fYWxsS2V5cyxiPU9iamVjdC5rZXlzKHRoaXMuX2hhbmRsZXMpLmxlbmd0aDtpZigwPT09Yil0aGlzLl92YWx1ZT1udWxsO2Vsc2V7dGhpcy5fdmFsdWU9W107Zm9yKHZhciBjPTA7YzxhLmxlbmd0aDtjKyspe3ZhciBkPXRoaXMuX2tleXNbYVtjXV07ZD09PWImJnRoaXMuX3ZhbHVlLnB1c2goYVtjXSl9fX19LHtrZXk6ImNsZWFyIix2YWx1ZTpmdW5jdGlvbihhKXtpZigidW5kZWZpbmVkIiE9dHlwZW9mIHRoaXMuX2hhbmRsZXNbYV0pe3ZhciBiPXRoaXMuX2hhbmRsZXNbYV07Ynx8KGI9W10pO2Zvcih2YXIgYz0wO2M8Yi5sZW5ndGg7YysrKXRoaXMuX2tleXNbYltjXV0tLTtkZWxldGUgdGhpcy5faGFuZGxlc1thXSx0aGlzLl91cGRhdGVWYWx1ZSgpfX19LHtrZXk6InZhbHVlIixnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fdmFsdWV9fSx7a2V5OiJfYWxsS2V5cyIsZ2V0OmZ1bmN0aW9uKCl7dmFyIGE9T2JqZWN0LmtleXModGhpcy5fa2V5cyk7cmV0dXJuIGEuc29ydChlKSxhfX1dKSxhfSgpO2MuZGVmYXVsdD1ofSx7Ii4vdXRpbCI6MTF9XSw0OltmdW5jdGlvbihhLGIsYyl7KGZ1bmN0aW9uKGIpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBkKGEpe3JldHVybiBhJiZhLl9fZXNNb2R1bGU/YTp7ZGVmYXVsdDphfX1mdW5jdGlvbiBlKGEsYil7aWYoIShhIGluc3RhbmNlb2YgYikpdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIil9ZnVuY3Rpb24gZihhKXtpZihhJiYic3RyaW5nIj09dHlwZW9mIGEpcmV0dXJuIGsuaGFzT3duUHJvcGVydHkoYSl8fChrW2FdPW5ldyBsKGEpKSxrW2FdO2lmKCJvYmplY3QiPT09KCJ1bmRlZmluZWQiPT10eXBlb2YgYT8idW5kZWZpbmVkIjpoKGEpKSYmYS5fdmFycyYmYS52YXIpcmV0dXJuIGE7aWYoQXJyYXkuaXNBcnJheShhKSYmMT09YS5sZW5ndGgmJiJzdHJpbmciPT10eXBlb2YgYVswXSlyZXR1cm4gZihhWzBdKTt0aHJvdyBuZXcgRXJyb3IoIkludmFsaWQgZ3JvdXBOYW1lIGFyZ3VtZW50Iil9T2JqZWN0LmRlZmluZVByb3BlcnR5KGMsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pO3ZhciBnPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gYShhLGIpe2Zvcih2YXIgYz0wO2M8Yi5sZW5ndGg7YysrKXt2YXIgZD1iW2NdO2QuZW51bWVyYWJsZT1kLmVudW1lcmFibGV8fCExLGQuY29uZmlndXJhYmxlPSEwLCJ2YWx1ZSJpbiBkJiYoZC53cml0YWJsZT0hMCksT2JqZWN0LmRlZmluZVByb3BlcnR5KGEsZC5rZXksZCl9fXJldHVybiBmdW5jdGlvbihiLGMsZCl7cmV0dXJuIGMmJmEoYi5wcm90b3R5cGUsYyksZCYmYShiLGQpLGJ9fSgpLGg9ImZ1bmN0aW9uIj09dHlwZW9mIFN5bWJvbCYmInN5bWJvbCI9PXR5cGVvZiBTeW1ib2wuaXRlcmF0b3I/ZnVuY3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhfTpmdW5jdGlvbihhKXtyZXR1cm4gYSYmImZ1bmN0aW9uIj09dHlwZW9mIFN5bWJvbCYmYS5jb25zdHJ1Y3Rvcj09PVN5bWJvbCYmYSE9PVN5bWJvbC5wcm90b3R5cGU/InN5bWJvbCI6dHlwZW9mIGF9O2MuZGVmYXVsdD1mO3ZhciBpPWEoIi4vdmFyIiksaj1kKGkpO2IuX19jcm9zc3RhbGtfZ3JvdXBzPWIuX19jcm9zc3RhbGtfZ3JvdXBzfHx7fTt2YXIgaz1iLl9fY3Jvc3N0YWxrX2dyb3VwcyxsPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gYShiKXtlKHRoaXMsYSksdGhpcy5uYW1lPWIsdGhpcy5fdmFycz17fX1yZXR1cm4gZyhhLFt7a2V5OiJ2YXIiLHZhbHVlOmZ1bmN0aW9uKGEpe2lmKCFhfHwic3RyaW5nIiE9dHlwZW9mIGEpdGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIHZhciBuYW1lIik7cmV0dXJuIHRoaXMuX3ZhcnMuaGFzT3duUHJvcGVydHkoYSl8fCh0aGlzLl92YXJzW2FdPW5ldyBqLmRlZmF1bHQodGhpcyxhKSksdGhpcy5fdmFyc1thXX19LHtrZXk6ImhhcyIsdmFsdWU6ZnVuY3Rpb24oYSl7aWYoIWF8fCJzdHJpbmciIT10eXBlb2YgYSl0aHJvdyBuZXcgRXJyb3IoIkludmFsaWQgdmFyIG5hbWUiKTtyZXR1cm4gdGhpcy5fdmFycy5oYXNPd25Qcm9wZXJ0eShhKX19XSksYX0oKX0pLmNhbGwodGhpcywidW5kZWZpbmVkIiE9dHlwZW9mIGdsb2JhbD9nbG9iYWw6InVuZGVmaW5lZCIhPXR5cGVvZiBzZWxmP3NlbGY6InVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3c/d2luZG93Ont9KX0seyIuL3ZhciI6MTJ9XSw1OltmdW5jdGlvbihhLGIsYyl7KGZ1bmN0aW9uKGIpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBkKGEpe3JldHVybiBhJiZhLl9fZXNNb2R1bGU/YTp7ZGVmYXVsdDphfX1mdW5jdGlvbiBlKGEpe3JldHVybiBrLnZhcihhKX1mdW5jdGlvbiBmKGEpe3JldHVybiBrLmhhcyhhKX1PYmplY3QuZGVmaW5lUHJvcGVydHkoYywiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7dmFyIGc9YSgiLi9ncm91cCIpLGg9ZChnKSxpPWEoIi4vc2VsZWN0aW9uIiksaj1hKCIuL2ZpbHRlciIpO2EoIi4vaW5wdXQiKSxhKCIuL2lucHV0X3NlbGVjdGl6ZSIpLGEoIi4vaW5wdXRfY2hlY2tib3hncm91cCIpLGEoIi4vaW5wdXRfc2xpZGVyIik7dmFyIGs9KDAsaC5kZWZhdWx0KSgiZGVmYXVsdCIpO2IuU2hpbnkmJmIuU2hpbnkuYWRkQ3VzdG9tTWVzc2FnZUhhbmRsZXIoInVwZGF0ZS1jbGllbnQtdmFsdWUiLGZ1bmN0aW9uKGEpeyJzdHJpbmciPT10eXBlb2YgYS5ncm91cD8oMCxoLmRlZmF1bHQpKGEuZ3JvdXApLnZhcihhLm5hbWUpLnNldChhLnZhbHVlKTplKGEubmFtZSkuc2V0KGEudmFsdWUpfSk7dmFyIGw9e2dyb3VwOmguZGVmYXVsdCx2YXI6ZSxoYXM6ZixTZWxlY3Rpb25IYW5kbGU6aS5TZWxlY3Rpb25IYW5kbGUsRmlsdGVySGFuZGxlOmouRmlsdGVySGFuZGxlfTtjLmRlZmF1bHQ9bCxiLmNyb3NzdGFsaz1sfSkuY2FsbCh0aGlzLCJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsP2dsb2JhbDoidW5kZWZpbmVkIiE9dHlwZW9mIHNlbGY/c2VsZjoidW5kZWZpbmVkIiE9dHlwZW9mIHdpbmRvdz93aW5kb3c6e30pfSx7Ii4vZmlsdGVyIjoyLCIuL2dyb3VwIjo0LCIuL2lucHV0Ijo2LCIuL2lucHV0X2NoZWNrYm94Z3JvdXAiOjcsIi4vaW5wdXRfc2VsZWN0aXplIjo4LCIuL2lucHV0X3NsaWRlciI6OSwiLi9zZWxlY3Rpb24iOjEwfV0sNjpbZnVuY3Rpb24oYSxiLGMpeyhmdW5jdGlvbihhKXsidXNlIHN0cmljdCI7ZnVuY3Rpb24gYihiKXtpW2IuY2xhc3NOYW1lXT1iLGEuZG9jdW1lbnQmJiJjb21wbGV0ZSIhPT1hLmRvY3VtZW50LnJlYWR5U3RhdGU/aChmdW5jdGlvbigpe2QoKX0pOmEuZG9jdW1lbnQmJnNldFRpbWVvdXQoZCwxMDApfWZ1bmN0aW9uIGQoKXtPYmplY3Qua2V5cyhpKS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3ZhciBiPWlbYV07aCgiLiIrYi5jbGFzc05hbWUpLm5vdCgiLmNyb3NzdGFsay1pbnB1dC1ib3VuZCIpLmVhY2goZnVuY3Rpb24oYSxjKXtnKGIsYyl9KX0pfWZ1bmN0aW9uIGUoYSl7cmV0dXJuIGEucmVwbGFjZSgvKFshIiMkJSYnKCkqKywuXC86Ozw9Pj9AXFtcXFxdXmB7fH1+XSkvZywiXFwkMSIpfWZ1bmN0aW9uIGYoYSl7dmFyIGI9aChhKTtPYmplY3Qua2V5cyhpKS5mb3JFYWNoKGZ1bmN0aW9uKGMpe2lmKGIuaGFzQ2xhc3MoYykmJiFiLmhhc0NsYXNzKCJjcm9zc3RhbGstaW5wdXQtYm91bmQiKSl7dmFyIGQ9aVtjXTtnKGQsYSl9fSl9ZnVuY3Rpb24gZyhhLGIpe3ZhciBjPWgoYikuZmluZCgic2NyaXB0W3R5cGU9J2FwcGxpY2F0aW9uL2pzb24nXVtkYXRhLWZvcj0nIitlKGIuaWQpKyInXSIpLGQ9SlNPTi5wYXJzZShjWzBdLmlubmVyVGV4dCksZj1hLmZhY3RvcnkoYixkKTtoKGIpLmRhdGEoImNyb3NzdGFsay1pbnN0YW5jZSIsZiksaChiKS5hZGRDbGFzcygiY3Jvc3N0YWxrLWlucHV0LWJvdW5kIil9T2JqZWN0LmRlZmluZVByb3BlcnR5KGMsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLGMucmVnaXN0ZXI9Yjt2YXIgaD1hLmpRdWVyeSxpPXt9O2EuU2hpbnkmJiFmdW5jdGlvbigpe3ZhciBiPW5ldyBhLlNoaW55LklucHV0QmluZGluZyxjPWEualF1ZXJ5O2MuZXh0ZW5kKGIse2ZpbmQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGMoYSkuZmluZCgiLmNyb3NzdGFsay1pbnB1dCIpfSxpbml0aWFsaXplOmZ1bmN0aW9uKGEpe2MoYSkuaGFzQ2xhc3MoImNyb3NzdGFsay1pbnB1dC1ib3VuZCIpfHxmKGEpfSxnZXRJZDpmdW5jdGlvbihhKXtyZXR1cm4gYS5pZH0sZ2V0VmFsdWU6ZnVuY3Rpb24oYSl7fSxzZXRWYWx1ZTpmdW5jdGlvbihhLGIpe30scmVjZWl2ZU1lc3NhZ2U6ZnVuY3Rpb24oYSxiKXt9LHN1YnNjcmliZTpmdW5jdGlvbihhLGIpe2MoYSkuZGF0YSgiY3Jvc3N0YWxrLWluc3RhbmNlIikucmVzdW1lKCl9LHVuc3Vic2NyaWJlOmZ1bmN0aW9uKGEpe2MoYSkuZGF0YSgiY3Jvc3N0YWxrLWluc3RhbmNlIikuc3VzcGVuZCgpfX0pLGEuU2hpbnkuaW5wdXRCaW5kaW5ncy5yZWdpc3RlcihiLCJjcm9zc3RhbGsuaW5wdXRCaW5kaW5nIil9KCl9KS5jYWxsKHRoaXMsInVuZGVmaW5lZCIhPXR5cGVvZiBnbG9iYWw/Z2xvYmFsOiJ1bmRlZmluZWQiIT10eXBlb2Ygc2VsZj9zZWxmOiJ1bmRlZmluZWQiIT10eXBlb2Ygd2luZG93P3dpbmRvdzp7fSl9LHt9XSw3OltmdW5jdGlvbihhLGIsYyl7KGZ1bmN0aW9uKGIpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBjKGEpe2lmKGEmJmEuX19lc01vZHVsZSlyZXR1cm4gYTt2YXIgYj17fTtpZihudWxsIT1hKWZvcih2YXIgYyBpbiBhKU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChhLGMpJiYoYltjXT1hW2NdKTtyZXR1cm4gYi5kZWZhdWx0PWEsYn12YXIgZD1hKCIuL2lucHV0IiksZT1jKGQpLGY9YSgiLi9maWx0ZXIiKSxnPWIualF1ZXJ5O2UucmVnaXN0ZXIoe2NsYXNzTmFtZToiY3Jvc3N0YWxrLWlucHV0LWNoZWNrYm94Z3JvdXAiLGZhY3Rvcnk6ZnVuY3Rpb24oYSxiKXt2YXIgYz1uZXcgZi5GaWx0ZXJIYW5kbGUoYi5ncm91cCksZD12b2lkIDAsZT1nKGEpO3JldHVybiBlLm9uKCJjaGFuZ2UiLCJpbnB1dFt0eXBlPSdjaGVja2JveCddIixmdW5jdGlvbigpe3ZhciBhPWUuZmluZCgiaW5wdXRbdHlwZT0nY2hlY2tib3gnXTpjaGVja2VkIik7MD09PWEubGVuZ3RoPyhkPW51bGwsYy5jbGVhcigpKTohZnVuY3Rpb24oKXt2YXIgZT17fTthLmVhY2goZnVuY3Rpb24oKXtiLm1hcFt0aGlzLnZhbHVlXS5mb3JFYWNoKGZ1bmN0aW9uKGEpe2VbYV09ITB9KX0pO3ZhciBmPU9iamVjdC5rZXlzKGUpO2Yuc29ydCgpLGQ9ZixjLnNldChmKX0oKX0pLHtzdXNwZW5kOmZ1bmN0aW9uKCl7Yy5jbGVhcigpfSxyZXN1bWU6ZnVuY3Rpb24oKXtkJiZjLnNldChkKX19fX0pfSkuY2FsbCh0aGlzLCJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsP2dsb2JhbDoidW5kZWZpbmVkIiE9dHlwZW9mIHNlbGY/c2VsZjoidW5kZWZpbmVkIiE9dHlwZW9mIHdpbmRvdz93aW5kb3c6e30pfSx7Ii4vZmlsdGVyIjoyLCIuL2lucHV0Ijo2fV0sODpbZnVuY3Rpb24oYSxiLGMpeyhmdW5jdGlvbihiKXsidXNlIHN0cmljdCI7ZnVuY3Rpb24gYyhhKXtpZihhJiZhLl9fZXNNb2R1bGUpcmV0dXJuIGE7dmFyIGI9e307aWYobnVsbCE9YSlmb3IodmFyIGMgaW4gYSlPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxjKSYmKGJbY109YVtjXSk7cmV0dXJuIGIuZGVmYXVsdD1hLGJ9dmFyIGQ9YSgiLi9pbnB1dCIpLGU9YyhkKSxmPWEoIi4vdXRpbCIpLGc9YyhmKSxoPWEoIi4vZmlsdGVyIiksaT1iLmpRdWVyeTtlLnJlZ2lzdGVyKHtjbGFzc05hbWU6ImNyb3NzdGFsay1pbnB1dC1zZWxlY3QiLGZhY3Rvcnk6ZnVuY3Rpb24oYSxiKXt2YXIgYz1be3ZhbHVlOiIiLGxhYmVsOiIoQWxsKSJ9XSxkPWcuZGF0YWZyYW1lVG9EMyhiLml0ZW1zKSxlPXtvcHRpb25zOmMuY29uY2F0KGQpLHZhbHVlRmllbGQ6InZhbHVlIixsYWJlbEZpZWxkOiJsYWJlbCIsc2VhcmNoRmllbGQ6ImxhYmVsIn0sZj1pKGEpLmZpbmQoInNlbGVjdCIpWzBdLGo9aShmKS5zZWxlY3RpemUoZSlbMF0uc2VsZWN0aXplLGs9bmV3IGguRmlsdGVySGFuZGxlKGIuZ3JvdXApLGw9dm9pZCAwO3JldHVybiBqLm9uKCJjaGFuZ2UiLGZ1bmN0aW9uKCl7MD09PWouaXRlbXMubGVuZ3RoPyhsPW51bGwsay5jbGVhcigpKTohZnVuY3Rpb24oKXt2YXIgYT17fTtqLml0ZW1zLmZvckVhY2goZnVuY3Rpb24oYyl7Yi5tYXBbY10uZm9yRWFjaChmdW5jdGlvbihiKXthW2JdPSEwfSl9KTt2YXIgYz1PYmplY3Qua2V5cyhhKTtjLnNvcnQoKSxsPWMsay5zZXQoYyl9KCl9KSx7c3VzcGVuZDpmdW5jdGlvbigpe2suY2xlYXIoKX0scmVzdW1lOmZ1bmN0aW9uKCl7bCYmay5zZXQobCl9fX19KX0pLmNhbGwodGhpcywidW5kZWZpbmVkIiE9dHlwZW9mIGdsb2JhbD9nbG9iYWw6InVuZGVmaW5lZCIhPXR5cGVvZiBzZWxmP3NlbGY6InVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3c/d2luZG93Ont9KX0seyIuL2ZpbHRlciI6MiwiLi9pbnB1dCI6NiwiLi91dGlsIjoxMX1dLDk6W2Z1bmN0aW9uKGEsYixjKXsoZnVuY3Rpb24oYil7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIGMoYSl7aWYoYSYmYS5fX2VzTW9kdWxlKXJldHVybiBhO3ZhciBiPXt9O2lmKG51bGwhPWEpZm9yKHZhciBjIGluIGEpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGEsYykmJihiW2NdPWFbY10pO3JldHVybiBiLmRlZmF1bHQ9YSxifWZ1bmN0aW9uIGQoYSxiKXtmb3IodmFyIGM9YS50b1N0cmluZygpO2MubGVuZ3RoPGI7KWM9IjAiK2M7cmV0dXJuIGN9ZnVuY3Rpb24gZShhKXtyZXR1cm4gYSBpbnN0YW5jZW9mIERhdGU/YS5nZXRVVENGdWxsWWVhcigpKyItIitkKGEuZ2V0VVRDTW9udGgoKSsxLDIpKyItIitkKGEuZ2V0VVRDRGF0ZSgpLDIpOm51bGx9dmFyIGY9ZnVuY3Rpb24oKXtmdW5jdGlvbiBhKGEsYil7dmFyIGM9W10sZD0hMCxlPSExLGY9dm9pZCAwO3RyeXtmb3IodmFyIGcsaD1hW1N5bWJvbC5pdGVyYXRvcl0oKTshKGQ9KGc9aC5uZXh0KCkpLmRvbmUpJiYoYy5wdXNoKGcudmFsdWUpLCFifHxjLmxlbmd0aCE9PWIpO2Q9ITApO31jYXRjaChhKXtlPSEwLGY9YX1maW5hbGx5e3RyeXshZCYmaC5yZXR1cm4mJmgucmV0dXJuKCl9ZmluYWxseXtpZihlKXRocm93IGZ9fXJldHVybiBjfXJldHVybiBmdW5jdGlvbihiLGMpe2lmKEFycmF5LmlzQXJyYXkoYikpcmV0dXJuIGI7aWYoU3ltYm9sLml0ZXJhdG9yIGluIE9iamVjdChiKSlyZXR1cm4gYShiLGMpO3Rocm93IG5ldyBUeXBlRXJyb3IoIkludmFsaWQgYXR0ZW1wdCB0byBkZXN0cnVjdHVyZSBub24taXRlcmFibGUgaW5zdGFuY2UiKX19KCksZz1hKCIuL2lucHV0IiksaD1jKGcpLGk9YSgiLi9maWx0ZXIiKSxqPWIualF1ZXJ5LGs9Yi5zdHJmdGltZTtoLnJlZ2lzdGVyKHtjbGFzc05hbWU6ImNyb3NzdGFsay1pbnB1dC1zbGlkZXIiLGZhY3Rvcnk6ZnVuY3Rpb24oYSxiKXtmdW5jdGlvbiBjKCl7dmFyIGE9aC5kYXRhKCJpb25SYW5nZVNsaWRlciIpLnJlc3VsdCxiPXZvaWQgMCxjPWguZGF0YSgiZGF0YS10eXBlIik7cmV0dXJuIGI9ImRhdGUiPT09Yz9mdW5jdGlvbihhKXtyZXR1cm4gZShuZXcgRGF0ZSgrYSkpfToiZGF0ZXRpbWUiPT09Yz9mdW5jdGlvbihhKXtyZXR1cm4rYS8xZTN9OmZ1bmN0aW9uKGEpe3JldHVybithfSwiZG91YmxlIj09PWguZGF0YSgiaW9uUmFuZ2VTbGlkZXIiKS5vcHRpb25zLnR5cGU/W2IoYS5mcm9tKSxiKGEudG8pXTpiKGEuZnJvbSl9dmFyIGQ9bmV3IGkuRmlsdGVySGFuZGxlKGIuZ3JvdXApLGc9e30saD1qKGEpLmZpbmQoImlucHV0IiksbD1oLmRhdGEoImRhdGEtdHlwZSIpLG09aC5kYXRhKCJ0aW1lLWZvcm1hdCIpLG49dm9pZCAwO2lmKCJkYXRlIj09PWwpbj1rLnV0YygpLGcucHJldHRpZnk9ZnVuY3Rpb24oYSl7cmV0dXJuIG4obSxuZXcgRGF0ZShhKSl9O2Vsc2UgaWYoImRhdGV0aW1lIj09PWwpe3ZhciBvPWguZGF0YSgidGltZXpvbmUiKTtuPW8/ay50aW1lem9uZShvKTprLGcucHJldHRpZnk9ZnVuY3Rpb24oYSl7cmV0dXJuIG4obSxuZXcgRGF0ZShhKSl9fWguaW9uUmFuZ2VTbGlkZXIoZyk7dmFyIHA9bnVsbDtyZXR1cm4gaC5vbigiY2hhbmdlLmNyb3NzdGFsa1NsaWRlcklucHV0IixmdW5jdGlvbihhKXtpZighaC5kYXRhKCJ1cGRhdGluZyIpJiYhaC5kYXRhKCJhbmltYXRpbmciKSl7Zm9yKHZhciBlPWMoKSxnPWYoZSwyKSxpPWdbMF0saj1nWzFdLGs9W10sbD0wO2w8Yi52YWx1ZXMubGVuZ3RoO2wrKyl7dmFyIG09Yi52YWx1ZXNbbF07bT49aSYmbTw9aiYmay5wdXNoKGIua2V5c1tsXSl9ay5zb3J0KCksZC5zZXQoaykscD1rfX0pLHtzdXNwZW5kOmZ1bmN0aW9uKCl7ZC5jbGVhcigpfSxyZXN1bWU6ZnVuY3Rpb24oKXtwJiZkLnNldChwKX19fX0pfSkuY2FsbCh0aGlzLCJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsP2dsb2JhbDoidW5kZWZpbmVkIiE9dHlwZW9mIHNlbGY/c2VsZjoidW5kZWZpbmVkIiE9dHlwZW9mIHdpbmRvdz93aW5kb3c6e30pfSx7Ii4vZmlsdGVyIjoyLCIuL2lucHV0Ijo2fV0sMTA6W2Z1bmN0aW9uKGEsYixjKXsidXNlIHN0cmljdCI7ZnVuY3Rpb24gZChhKXtpZihhJiZhLl9fZXNNb2R1bGUpcmV0dXJuIGE7dmFyIGI9e307aWYobnVsbCE9YSlmb3IodmFyIGMgaW4gYSlPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxjKSYmKGJbY109YVtjXSk7cmV0dXJuIGIuZGVmYXVsdD1hLGJ9ZnVuY3Rpb24gZShhKXtyZXR1cm4gYSYmYS5fX2VzTW9kdWxlP2E6e2RlZmF1bHQ6YX19ZnVuY3Rpb24gZihhLGIpe2lmKCEoYSBpbnN0YW5jZW9mIGIpKXRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpfU9iamVjdC5kZWZpbmVQcm9wZXJ0eShjLCJfX2VzTW9kdWxlIix7dmFsdWU6ITB9KSxjLlNlbGVjdGlvbkhhbmRsZT12b2lkIDA7dmFyIGc9ZnVuY3Rpb24oKXtmdW5jdGlvbiBhKGEsYil7Zm9yKHZhciBjPTA7YzxiLmxlbmd0aDtjKyspe3ZhciBkPWJbY107ZC5lbnVtZXJhYmxlPWQuZW51bWVyYWJsZXx8ITEsZC5jb25maWd1cmFibGU9ITAsInZhbHVlImluIGQmJihkLndyaXRhYmxlPSEwKSxPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxkLmtleSxkKX19cmV0dXJuIGZ1bmN0aW9uKGIsYyxkKXtyZXR1cm4gYyYmYShiLnByb3RvdHlwZSxjKSxkJiZhKGIsZCksYn19KCksaD1hKCIuL2V2ZW50cyIpLGk9ZShoKSxqPWEoIi4vZ3JvdXAiKSxrPWUoaiksbD1hKCIuL3V0aWwiKSxtPWQobCk7Yy5TZWxlY3Rpb25IYW5kbGU9ZnVuY3Rpb24oKXtmdW5jdGlvbiBhKCl7dmFyIGI9YXJndW1lbnRzLmxlbmd0aD4wJiZ2b2lkIDAhPT1hcmd1bWVudHNbMF0/YXJndW1lbnRzWzBdOm51bGwsYz1hcmd1bWVudHMubGVuZ3RoPjEmJnZvaWQgMCE9PWFyZ3VtZW50c1sxXT9hcmd1bWVudHNbMV06bnVsbDtmKHRoaXMsYSksdGhpcy5fZXZlbnRSZWxheT1uZXcgaS5kZWZhdWx0LHRoaXMuX2VtaXR0ZXI9bmV3IG0uU3Vic2NyaXB0aW9uVHJhY2tlcih0aGlzLl9ldmVudFJlbGF5KSx0aGlzLl9ncm91cD1udWxsLHRoaXMuX3Zhcj1udWxsLHRoaXMuX3Zhck9uQ2hhbmdlU3ViPW51bGwsdGhpcy5fZXh0cmFJbmZvPW0uZXh0ZW5kKHtzZW5kZXI6dGhpc30sYyksdGhpcy5zZXRHcm91cChiKX1yZXR1cm4gZyhhLFt7a2V5OiJzZXRHcm91cCIsdmFsdWU6ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcztpZih0aGlzLl9ncm91cCE9PWEmJih0aGlzLl9ncm91cHx8YSkmJih0aGlzLl92YXImJih0aGlzLl92YXIub2ZmKCJjaGFuZ2UiLHRoaXMuX3Zhck9uQ2hhbmdlU3ViKSx0aGlzLl92YXI9bnVsbCx0aGlzLl92YXJPbkNoYW5nZVN1Yj1udWxsKSx0aGlzLl9ncm91cD1hLGEpKXt0aGlzLl92YXI9KDAsay5kZWZhdWx0KShhKS52YXIoInNlbGVjdGlvbiIpO3ZhciBjPXRoaXMuX3Zhci5vbigiY2hhbmdlIixmdW5jdGlvbihhKXtiLl9ldmVudFJlbGF5LnRyaWdnZXIoImNoYW5nZSIsYSxiKX0pO3RoaXMuX3Zhck9uQ2hhbmdlU3ViPWN9fX0se2tleToiX21lcmdlRXh0cmFJbmZvIix2YWx1ZTpmdW5jdGlvbihhKXtyZXR1cm4gbS5leHRlbmQoe30sdGhpcy5fZXh0cmFJbmZvP3RoaXMuX2V4dHJhSW5mbzpudWxsLGE/YTpudWxsKX19LHtrZXk6InNldCIsdmFsdWU6ZnVuY3Rpb24oYSxiKXt0aGlzLl92YXImJnRoaXMuX3Zhci5zZXQoYSx0aGlzLl9tZXJnZUV4dHJhSW5mbyhiKSl9fSx7a2V5OiJjbGVhciIsdmFsdWU6ZnVuY3Rpb24oYSl7dGhpcy5fdmFyJiZ0aGlzLnNldCh2b2lkIDAsdGhpcy5fbWVyZ2VFeHRyYUluZm8oYSkpfX0se2tleToib24iLHZhbHVlOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuX2VtaXR0ZXIub24oYSxiKX19LHtrZXk6Im9mZiIsdmFsdWU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5fZW1pdHRlci5vZmYoYSxiKX19LHtrZXk6ImNsb3NlIix2YWx1ZTpmdW5jdGlvbigpe3RoaXMuX2VtaXR0ZXIucmVtb3ZlQWxsTGlzdGVuZXJzKCksdGhpcy5zZXRHcm91cChudWxsKX19LHtrZXk6InZhbHVlIixnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fdmFyP3RoaXMuX3Zhci5nZXQoKTpudWxsfX1dKSxhfSgpfSx7Ii4vZXZlbnRzIjoxLCIuL2dyb3VwIjo0LCIuL3V0aWwiOjExfV0sMTE6W2Z1bmN0aW9uKGEsYixjKXsidXNlIHN0cmljdCI7ZnVuY3Rpb24gZChhLGIpe2lmKCEoYSBpbnN0YW5jZW9mIGIpKXRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpfWZ1bmN0aW9uIGUoYSl7Zm9yKHZhciBiPWFyZ3VtZW50cy5sZW5ndGgsYz1BcnJheShiPjE/Yi0xOjApLGQ9MTtkPGI7ZCsrKWNbZC0xXT1hcmd1bWVudHNbZF07Zm9yKHZhciBlPTA7ZTxjLmxlbmd0aDtlKyspe3ZhciBmPWNbZV07aWYoInVuZGVmaW5lZCIhPXR5cGVvZiBmJiZudWxsIT09Zilmb3IodmFyIGcgaW4gZilmLmhhc093blByb3BlcnR5KGcpJiYoYVtnXT1mW2ddKX1yZXR1cm4gYX1mdW5jdGlvbiBmKGEpe2Zvcih2YXIgYj0xO2I8YS5sZW5ndGg7YisrKWlmKGFbYl08PWFbYi0xXSl0aHJvdyBuZXcgRXJyb3IoIkxpc3QgaXMgbm90IHNvcnRlZCBvciBjb250YWlucyBkdXBsaWNhdGUiKX1mdW5jdGlvbiBnKGEsYil7dmFyIGM9MCxkPTA7YXx8KGE9W10pLGJ8fChiPVtdKTt2YXIgZT1bXSxnPVtdO2ZvcihmKGEpLGYoYik7YzxhLmxlbmd0aCYmZDxiLmxlbmd0aDspYVtjXT09PWJbZF0/KGMrKyxkKyspOmFbY108YltkXT9lLnB1c2goYVtjKytdKTpnLnB1c2goYltkKytdKTtyZXR1cm4gYzxhLmxlbmd0aCYmKGU9ZS5jb25jYXQoYS5zbGljZShjKSkpLGQ8Yi5sZW5ndGgmJihnPWcuY29uY2F0KGIuc2xpY2UoZCkpKSx7cmVtb3ZlZDplLGFkZGVkOmd9fWZ1bmN0aW9uIGgoYSl7dmFyIGI9W10sYz12b2lkIDA7Zm9yKHZhciBkIGluIGEpe2lmKGEuaGFzT3duUHJvcGVydHkoZCkmJmIucHVzaChkKSwib2JqZWN0IiE9PWooYVtkXSl8fCJ1bmRlZmluZWQiPT10eXBlb2YgYVtkXS5sZW5ndGgpdGhyb3cgbmV3IEVycm9yKCJBbGwgZmllbGRzIG11c3QgYmUgYXJyYXlzIik7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiBjJiZjIT09YVtkXS5sZW5ndGgpdGhyb3cgbmV3IEVycm9yKCJBbGwgZmllbGRzIG11c3QgYmUgYXJyYXlzIG9mIHRoZSBzYW1lIGxlbmd0aCIpO2M9YVtkXS5sZW5ndGh9Zm9yKHZhciBlPVtdLGY9dm9pZCAwLGc9MDtnPGM7ZysrKXtmPXt9O2Zvcih2YXIgaD0wO2g8Yi5sZW5ndGg7aCsrKWZbYltoXV09YVtiW2hdXVtnXTtlLnB1c2goZil9cmV0dXJuIGV9T2JqZWN0LmRlZmluZVByb3BlcnR5KGMsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pO3ZhciBpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gYShhLGIpe2Zvcih2YXIgYz0wO2M8Yi5sZW5ndGg7YysrKXt2YXIgZD1iW2NdO2QuZW51bWVyYWJsZT1kLmVudW1lcmFibGV8fCExLGQuY29uZmlndXJhYmxlPSEwLCJ2YWx1ZSJpbiBkJiYoZC53cml0YWJsZT0hMCksT2JqZWN0LmRlZmluZVByb3BlcnR5KGEsZC5rZXksZCl9fXJldHVybiBmdW5jdGlvbihiLGMsZCl7cmV0dXJuIGMmJmEoYi5wcm90b3R5cGUsYyksZCYmYShiLGQpLGJ9fSgpLGo9ImZ1bmN0aW9uIj09dHlwZW9mIFN5bWJvbCYmInN5bWJvbCI9PXR5cGVvZiBTeW1ib2wuaXRlcmF0b3I/ZnVuY3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhfTpmdW5jdGlvbihhKXtyZXR1cm4gYSYmImZ1bmN0aW9uIj09dHlwZW9mIFN5bWJvbCYmYS5jb25zdHJ1Y3Rvcj09PVN5bWJvbCYmYSE9PVN5bWJvbC5wcm90b3R5cGU/InN5bWJvbCI6dHlwZW9mIGF9O2MuZXh0ZW5kPWUsYy5jaGVja1NvcnRlZD1mLGMuZGlmZlNvcnRlZExpc3RzPWcsYy5kYXRhZnJhbWVUb0QzPWg7Yy5TdWJzY3JpcHRpb25UcmFja2VyPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gYShiKXtkKHRoaXMsYSksdGhpcy5fZW1pdHRlcj1iLHRoaXMuX3N1YnM9e319cmV0dXJuIGkoYSxbe2tleToib24iLHZhbHVlOmZ1bmN0aW9uKGEsYil7dmFyIGM9dGhpcy5fZW1pdHRlci5vbihhLGIpO3JldHVybiB0aGlzLl9zdWJzW2NdPWEsY319LHtrZXk6Im9mZiIsdmFsdWU6ZnVuY3Rpb24oYSxiKXt2YXIgYz10aGlzLl9lbWl0dGVyLm9mZihhLGIpO3JldHVybiBjJiZkZWxldGUgdGhpcy5fc3Vic1tjXSxjfX0se2tleToicmVtb3ZlQWxsTGlzdGVuZXJzIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBhPXRoaXMsYj10aGlzLl9zdWJzO3RoaXMuX3N1YnM9e30sT2JqZWN0LmtleXMoYikuZm9yRWFjaChmdW5jdGlvbihjKXthLl9lbWl0dGVyLm9mZihiW2NdLGMpfSl9fV0pLGF9KCl9LHt9XSwxMjpbZnVuY3Rpb24oYSxiLGMpeyhmdW5jdGlvbihiKXsidXNlIHN0cmljdCI7ZnVuY3Rpb24gZChhKXtyZXR1cm4gYSYmYS5fX2VzTW9kdWxlP2E6e2RlZmF1bHQ6YX19ZnVuY3Rpb24gZShhLGIpe2lmKCEoYSBpbnN0YW5jZW9mIGIpKXRocm93IG5ldyBUeXBlRXJyb3IoIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbiIpfU9iamVjdC5kZWZpbmVQcm9wZXJ0eShjLCJfX2VzTW9kdWxlIix7dmFsdWU6ITB9KTt2YXIgZj0iZnVuY3Rpb24iPT10eXBlb2YgU3ltYm9sJiYic3ltYm9sIj09dHlwZW9mIFN5bWJvbC5pdGVyYXRvcj9mdW5jdGlvbihhKXtyZXR1cm4gdHlwZW9mIGF9OmZ1bmN0aW9uKGEpe3JldHVybiBhJiYiZnVuY3Rpb24iPT10eXBlb2YgU3ltYm9sJiZhLmNvbnN0cnVjdG9yPT09U3ltYm9sJiZhIT09U3ltYm9sLnByb3RvdHlwZT8ic3ltYm9sIjp0eXBlb2YgYX0sZz1mdW5jdGlvbigpe2Z1bmN0aW9uIGEoYSxiKXtmb3IodmFyIGM9MDtjPGIubGVuZ3RoO2MrKyl7dmFyIGQ9YltjXTtkLmVudW1lcmFibGU9ZC5lbnVtZXJhYmxlfHwhMSxkLmNvbmZpZ3VyYWJsZT0hMCwidmFsdWUiaW4gZCYmKGQud3JpdGFibGU9ITApLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLGQua2V5LGQpfX1yZXR1cm4gZnVuY3Rpb24oYixjLGQpe3JldHVybiBjJiZhKGIucHJvdG90eXBlLGMpLGQmJmEoYixkKSxifX0oKSxoPWEoIi4vZXZlbnRzIiksaT1kKGgpLGo9ZnVuY3Rpb24oKXtmdW5jdGlvbiBhKGIsYyxkKXtlKHRoaXMsYSksdGhpcy5fZ3JvdXA9Yix0aGlzLl9uYW1lPWMsdGhpcy5fdmFsdWU9ZCx0aGlzLl9ldmVudHM9bmV3IGkuZGVmYXVsdH1yZXR1cm4gZyhhLFt7a2V5OiJnZXQiLHZhbHVlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3ZhbHVlfX0se2tleToic2V0Iix2YWx1ZTpmdW5jdGlvbihhLGMpe2lmKHRoaXMuX3ZhbHVlIT09YSl7dmFyIGQ9dGhpcy5fdmFsdWU7dGhpcy5fdmFsdWU9YTt2YXIgZT17fTtpZihjJiYib2JqZWN0Ij09PSgidW5kZWZpbmVkIj09dHlwZW9mIGM/InVuZGVmaW5lZCI6ZihjKSkpZm9yKHZhciBnIGluIGMpYy5oYXNPd25Qcm9wZXJ0eShnKSYmKGVbZ109Y1tnXSk7ZS5vbGRWYWx1ZT1kLGUudmFsdWU9YSx0aGlzLl9ldmVudHMudHJpZ2dlcigiY2hhbmdlIixlLHRoaXMpLGIuU2hpbnkmJmIuU2hpbnkub25JbnB1dENoYW5nZSYmYi5TaGlueS5vbklucHV0Q2hhbmdlKCIuY2xpZW50VmFsdWUtIisobnVsbCE9PXRoaXMuX2dyb3VwLm5hbWU/dGhpcy5fZ3JvdXAubmFtZSsiLSI6IiIpK3RoaXMuX25hbWUsInVuZGVmaW5lZCI9PXR5cGVvZiBhP251bGw6YSl9fX0se2tleToib24iLHZhbHVlOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuX2V2ZW50cy5vbihhLGIpfX0se2tleToib2ZmIix2YWx1ZTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLl9ldmVudHMub2ZmKGEsYil9fV0pLGF9KCk7Yy5kZWZhdWx0PWp9KS5jYWxsKHRoaXMsInVuZGVmaW5lZCIhPXR5cGVvZiBnbG9iYWw/Z2xvYmFsOiJ1bmRlZmluZWQiIT10eXBlb2Ygc2VsZj9zZWxmOiJ1bmRlZmluZWQiIT10eXBlb2Ygd2luZG93P3dpbmRvdzp7fSl9LHsiLi9ldmVudHMiOjF9XX0se30sWzVdKTsKLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3Jvc3N0YWxrLm1pbi5qcy5tYXA=\"></script>\n",
"<link href=\"data:text/css;charset-utf-8;base64,LyogQWRqdXN0IG1hcmdpbnMgb3V0d2FyZHMsIHNvIGNvbHVtbiBjb250ZW50cyBsaW5lIHVwIHdpdGggdGhlIGVkZ2VzIG9mIHRoZQogICBwYXJlbnQgb2YgY29udGFpbmVyLWZsdWlkLiAqLwouY29udGFpbmVyLWZsdWlkLmNyb3NzdGFsay1ic2NvbHMgewogIG1hcmdpbi1sZWZ0OiAtMzBweDsKICBtYXJnaW4tcmlnaHQ6IC0zMHB4OwogIHdoaXRlLXNwYWNlOiBub3JtYWw7Cn0KCi8qIEJ1dCBkb24ndCBhZGp1c3QgdGhlIG1hcmdpbnMgb3V0d2FyZHMgaWYgd2UncmUgZGlyZWN0bHkgdW5kZXIgdGhlIGJvZHksCiAgIGkuZS4gd2Ugd2VyZSB0aGUgdG9wLWxldmVsIG9mIHNvbWV0aGluZyBhdCB0aGUgY29uc29sZS4gKi8KYm9keSA+IC5jb250YWluZXItZmx1aWQuY3Jvc3N0YWxrLWJzY29scyB7CiAgbWFyZ2luLWxlZnQ6IGF1dG87CiAgbWFyZ2luLXJpZ2h0OiBhdXRvOwp9CgouY3Jvc3N0YWxrLWlucHV0LWNoZWNrYm94Z3JvdXAgLmNyb3NzdGFsay1vcHRpb25zLWdyb3VwIC5jcm9zc3RhbGstb3B0aW9ucy1jb2x1bW4gewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBwYWRkaW5nLXJpZ2h0OiAxMnB4OwogIHZlcnRpY2FsLWFsaWduOiB0b3A7Cn0KCkBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aDo0ODBweCkgewogIC5jcm9zc3RhbGstaW5wdXQtY2hlY2tib3hncm91cCAuY3Jvc3N0YWxrLW9wdGlvbnMtZ3JvdXAgLmNyb3NzdGFsay1vcHRpb25zLWNvbHVtbiB7CiAgICBkaXNwbGF5OiBibG9jazsKICAgIHBhZGRpbmctcmlnaHQ6IGluaGVyaXQ7CiAgfQp9Cg==\" rel=\"stylesheet\" />\n",
"<link href=\"data:text/css;charset-utf-8;base64,LyoKanVzdCBoZXJlIHNvIHRoYXQgcGxvdGx5IHdvcmtzCmNvcnJlY3RseSB3aXRoIGlvc2xpZGVzLgpzZWUgaHR0cHM6Ly9naXRodWIuY29tL3JvcGVuc2NpL3Bsb3RseS9pc3N1ZXMvNDYzCiovCgpzbGlkZTpub3QoLmN1cnJlbnQpIC5wbG90bHkuaHRtbC13aWRnZXR7CiAgZGlzcGxheTogbm9uZTsKfQo=\" rel=\"stylesheet\" />\n",
@larskuhtz

Copy link
Copy Markdown
Author

results

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