the ns-3 build tool default tip
authorMathieu Lacage <mathieu.lacage@gmail.com>
Tue, 01 Nov 2011 11:27:35 +0100
changeset 0 8cecfe371162
the ns-3 build tool
README.rst
bake
bakeconf.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.rst	Tue Nov 01 11:27:35 2011 +0100
@@ -0,0 +1,160 @@
+Building ns-3 with Bake
+=======================
+
+
+Instructions for the impatient
+------------------------------
+
+First, download bake itself:::
+
+  [mathieu@mathieu tmp]$ hg clone http://code.nsnam.org/mathieu/bake
+  [mathieu@mathieu tmp]$ cd bake
+
+Second, pick the kind of build you want to create (debug build here):::
+
+  [mathieu@mathieu bake]$ mkdir dbg
+  [mathieu@mathieu bake]$ cd dbg
+  [mathieu@mathieu dbg]$ ../bake configure -c ../bakeconf.xml -p ns3,nopython,dbg
+
+Check that everything is enabled correctly:::
+
+  [mathieu@mathieu dbg]$ ../bake show --directories --enabled
+  installdir   : /home/mathieu/code/bake/dbg
+  sourcedir    : /home/mathieu/code/bake/source
+  objdir       : dbg
+  module: click-1.8.0 (enabled)
+  module: openflow-ns3 (enabled)
+  module: nsc (enabled)
+  module: ns-3-dev (enabled)
+
+Download everything:::
+
+  [mathieu@mathieu dbg]$ ../bake download
+  ...
+
+Build it:::
+
+  [mathieu@mathieu dbg]$ ../bake build
+
+Run it:::
+
+  [mathieu@mathieu dbg]$ ../bake shell
+
+
+A longer tour
+-------------
+
+When you configure, bake reads a so-called 'configuration' file which describes
+which modules exist, where they can be downloaded, and how they can be built. The 
+configuration file read below is bakeconf.xml located in the parent directory. 
+At the end of this 'configure' step, Bake records in a new file (by default,
+bakefile.xml located in the current working directory) the details of what
+the user requested to download and build:::
+
+  [mathieu@mathieu dbg]$ ../bake configure -c ../bakeconf.xml -p ns3,nopython,dbg
+
+The above command thus reads ../bakeconf.xml and generates ./bakefile.xml based on its content
+and the user-requested modules and options. In this case, we request first the "ns3" 
+predefined configuration which is defined in ../bakeconf.xml:::
+
+  <predefined name="ns3">
+    <enable name="ns-3-dev"/>
+    <configuration installdir="." sourcedir="../source"/>
+    <append module="ns-3-dev" name="configure_arguments" value="--enable-examples --enable-tests"/>
+  </predefined>
+
+This configuration merely selects the ns-3-dev module and specifies that it should 
+build it example and test programs. Second, we request the "nopython" configuration defined
+in ../bakeconf.xml to make sure that we do not build the ns-3 python bindings:::
+
+  <predefined name="nopython">
+    <disable name="pybindgen"/>
+  </predefined>
+
+Finally, we select the "dbg" (debug) configuration defined in ../bakeconf.xml:
+
+  <predefined name="dbg">
+    <configuration objdir="dbg"/>
+    <append name="CFLAGS" value="-g -O0"/>
+    <append name="CXXFLAGS" value="-g -O0"/>
+  </predefined>
+
+Note that the above could have been configured without the use of predefined 
+configurations:::
+
+  [mathieu@mathieu dbg]$ ../bake configure -c ../bakeconf.xml --installdir=. --sourcedir=../ --objdir=dbg --enable=ns-3-dev --disable=pybindgen "--append=CFLAGS=-g -O0" "--append=CXXFLAGS=-g -O0"
+
+However, it could be said that the original is easier to read and remember:::
+
+  [mathieu@mathieu dbg]$ ../bake configure -c ../bakeconf.xml -p ns3,nopython,dbg
+
+One should also keep in mind that these two alternative notations can be mixed
+together. The following can be used, for example, to disable the nsc module:::
+
+  [mathieu@mathieu dbg]$ ../bake configure -c ../bakeconf.xml -p ns3,nopython,dbg --disable=nsc
+
+Once configuration is completed, it is possible to look at what has been enabled. 
+The above would result in the following for example:::
+
+  [mathieu@mathieu dbg]$ ../bake show --enabled
+  module: click-1.8.0 (enabled)
+  module: openflow-ns3 (enabled)
+  module: ns-3-dev (enabled)
+  [mathieu@mathieu dbg]$ ../bake show --disabled
+  module: gccxml-ns3 (disabled)
+  module: pygccxml (disabled)
+  module: pybindgen (disabled)
+  module: nsc (disabled)
+
+The details of how each module has been configured can be displayed with the --variables option:::
+
+  [mathieu@mathieu dbg]$ ../bake show --enabled --variables
+  module: click-1.8.0 (enabled)
+    source archive
+      url=http://read.cs.ucla.edu/click/click-1.8.0.tar.gz
+      extract_directory=None
+    build autotools
+      configure_arguments=--enable-userlevel --disable-linuxmodule --enable-nsclick --enable-wifi
+      maintainer=no
+      CFLAGS= -g -O3
+      CXXFLAGS= -g -O3  
+  module: openflow-ns3 (enabled)
+    source mercurial
+  ...
+
+Once everything has been configured, the download, and build steps can proceed:::
+
+  [mathieu@mathieu dbg]$ ../bake download
+  [mathieu@mathieu dbg]$ ../bake build
+
+As per the configuration specified, the downloaded source code will be located in 
+the "source" directory of the parent directory, "../source". The code
+built during the build process for module X will be stored within ../source/X/dbg/
+or within ../source/X depending on whether that module's objdir variable is set to "yes"
+or "no". During the build process, each module will be installed in the current
+directory and, at the end, we can see:::
+
+  [mathieu@mathieu dbg]$ ls
+  bakefile.xml  bin  include  lib
+  [mathieu@mathieu-laptop dbg]$ ls lib/
+  liblinux2.6.18.so            libns3-energy-test.so         ...
+  ...
+
+Finally, we can drop in the associated shell:::
+
+  [mathieu@mathieu dbg]$ ../bake shell
+
+And then execute a number of simulation scenarios thanks to the automatic
+configuration of a number of environmental variables.
+
+After a while playing with this, if we make modifications to the source code
+downloaded in ../source, and if we want to update our local source tree
+with the latest commits that have been pushed on the main ns-3 repository
+on code.nsnam.org, we can "update":
+
+  [mathieu@mathieu dbg]$ ../bake update
+  [mathieu@mathieu dbg]$ ../bake build
+
+  
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bake	Tue Nov 01 11:27:35 2011 +0100
@@ -0,0 +1,1693 @@
+#!/usr/bin/env python
+sources = ['bake/ModuleEnvironment.py','bake/ModuleBuild.py','bake/Module.py','bake/Configuration.py','bake/FilesystemMonitor.py','bake/Utils.py','bake/ModuleLogger.py','bake/Exceptions.py','bake/__init__.py','bake/Bake.py','bake/ModuleSource.py','bake/Dependencies.py']
+sources_md5 = "0a06a296402db1cde388590386af8134"
+zipdata = """UEsDBBQAAAAAAIhcrj5O0QAyVRwAAFUcAAAZAAAAYmFrZS9Nb2R1bGVFbnZpcm9ubWVudC5weWlt
+cG9ydCBvcwppbXBvcnQgc3VicHJvY2VzcwppbXBvcnQgc3lzCmltcG9ydCBwbGF0Zm9ybQoKY2xh
+c3MgTW9kdWxlRW52aXJvbm1lbnQ6CiAgICAoSElHSEVSLCBMT1dFUiwgRVFVQUwpID0gcmFuZ2Uo
+MCwzKQoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBsb2dnZXIsIGluc3RhbGxkaXIsIHNvdXJjZWRp
+ciwgb2JqZGlyKToKICAgICAgICBzZWxmLl9sb2dnZXIgPSBsb2dnZXIKICAgICAgICBzZWxmLl9p
+bnN0YWxsZGlyID0gaW5zdGFsbGRpcgogICAgICAgIHNlbGYuX3NvdXJjZWRpciA9IHNvdXJjZWRp
+cgogICAgICAgIHNlbGYuX29iamRpciA9IG9iamRpcgogICAgICAgIHNlbGYuX21vZHVsZV9uYW1l
+ID0gTm9uZQogICAgICAgIHNlbGYuX21vZHVsZV9zdXBwb3J0c19vYmpkaXIgPSBOb25lCiAgICAg
+ICAgc2VsZi5fbGlicGF0aHMgPSBbXQoKICAgIGRlZiBfbW9kdWxlX2RpcmVjdG9yeShzZWxmKToK
+ICAgICAgICByZXR1cm4gc2VsZi5fbW9kdWxlX25hbWUKCiAgICBAcHJvcGVydHkKICAgIGRlZiBp
+bnN0YWxsZGlyKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9pbnN0YWxsZGlyCiAgICBAcHJv
+cGVydHkKICAgIGRlZiBzcmNkaXIoc2VsZik6CiAgICAgICAgcmV0dXJuIG9zLnBhdGguam9pbihz
+ZWxmLl9zb3VyY2VkaXIsIHNlbGYuX21vZHVsZV9kaXJlY3RvcnkoKSkKICAgIEBwcm9wZXJ0eQog
+ICAgZGVmIHNyY3JlcG8oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX3NvdXJjZWRpcgogICAg
+QHByb3BlcnR5CiAgICBkZWYgb2JqZGlyKHNlbGYpOgogICAgICAgIGlmIG5vdCBzZWxmLl9tb2R1
+bGVfc3VwcG9ydHNfb2JqZGlyOgogICAgICAgICAgICBvYmogPSBzZWxmLnNyY2RpcgogICAgICAg
+IGVsc2U6CiAgICAgICAgICAgIG9iaiA9IG9zLnBhdGguam9pbihzZWxmLnNyY2Rpciwgc2VsZi5f
+b2JqZGlyKQogICAgICAgIHJldHVybiBvYmoKCiAgICBkZWYgX3BrZ2NvbmZpZ192YXIoc2VsZik6
+CiAgICAgICAgcmV0dXJuICdQS0dfQ09ORklHX1BBVEgnCiAgICBkZWYgX3BrZ2NvbmZpZ19wYXRo
+KHNlbGYpOgogICAgICAgIHJldHVybiBvcy5wYXRoLmpvaW4oc2VsZi5fbGliX3BhdGgoKSwgJ3Br
+Z2NvbmZpZycpCiAgICBkZWYgX2xpYl92YXIoc2VsZik6CiAgICAgICAgbGliX3ZhciA9IHsnTGlu
+dXgnIDogJ0xEX0xJQlJBUllfUEFUSCcsCiAgICAgICAgICAgICAgICAgICAgJ0RhcndpbicgOiAn
+RFlMRF9MSUJSQVJZX1BBVEgnLAogICAgICAgICAgICAgICAgICAgICdXaW5kb3dzJyA6ICdQQVRI
+J30KICAgICAgICBpZiBub3QgbGliX3Zhci5oYXNfa2V5KHBsYXRmb3JtLnN5c3RlbSgpKToKICAg
+ICAgICAgICAgc3lzLnN0ZGVycignRXJyb3I6IFVuc3VwcG9ydGVkIHBsYXRmb3JtLiBTZW5kIGVt
+YWlsIHRvIG1hdGhpZXUubGFjYWdlQGdtYWlsLmNvbSAoJXMpJyAlCiAgICAgICAgICAgICAgICAg
+ICAgICAgcGxhdGZvcm0uc3lzdGVtKCkpCiAgICAgICAgICAgIHN5cy5leGl0KDEpCiAgICAgICAg
+cmV0dXJuIGxpYl92YXJbcGxhdGZvcm0uc3lzdGVtKCldCiAgICBkZWYgX2xpYl9wYXRoKHNlbGYp
+OgogICAgICAgIHJldHVybiBvcy5wYXRoLmpvaW4oc2VsZi5faW5zdGFsbGRpciwgJ2xpYicpCiAg
+ICBkZWYgX2Jpbl92YXIoc2VsZik6CiAgICAgICAgcmV0dXJuICdQQVRIJwogICAgZGVmIF9iaW5f
+cGF0aChzZWxmKToKICAgICAgICByZXR1cm4gb3MucGF0aC5qb2luKHNlbGYuX2luc3RhbGxkaXIs
+ICdiaW4nKQogICAgZGVmIF9weV92YXIoc2VsZik6CiAgICAgICAgcmV0dXJuICdQWVRIT05QQVRI
+JwogICAgZGVmIF9weV9wYXRoKHNlbGYpOgogICAgICAgIHJldHVybiBvcy5wYXRoLmpvaW4oc2Vs
+Zi5faW5zdGFsbGRpciwgJ2xpYicsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3B5dGhv
+bicgKyAnLicuam9pbihwbGF0Zm9ybS5weXRob25fdmVyc2lvbl90dXBsZSgpWzA6Ml0pLCAnc2l0
+ZS1wYWNrYWdlcycpCiAgICBkZWYgX2FwcGVuZF9wYXRoKHNlbGYsIGQsIG5hbWUsIHZhbHVlLCBz
+ZXApOgogICAgICAgIGlmIG5vdCBkLmhhc19rZXkobmFtZSk6CiAgICAgICAgICAgIGRbbmFtZV0g
+PSB2YWx1ZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGRbbmFtZV0gPSBkW25hbWVdICsgc2Vw
+ICsgdmFsdWUKCiAgICBkZWYgc3RhcnRfc291cmNlKHNlbGYsIG5hbWUpOgogICAgICAgIGFzc2Vy
+dCBzZWxmLl9tb2R1bGVfc3VwcG9ydHNfb2JqZGlyIGlzIE5vbmUKICAgICAgICBzZWxmLl9tb2R1
+bGVfbmFtZSA9IG5hbWUKICAgICAgICBzZWxmLl9sb2dnZXIuc2V0X2N1cnJlbnRfbW9kdWxlKG5h
+bWUpCiAgICAgICAgIyBlbnN1cmUgc291cmNlIGRpcmVjdG9yeSBleGlzdHMKICAgICAgICBpZiBu
+b3Qgb3MucGF0aC5pc2RpcihzZWxmLl9zb3VyY2VkaXIpOgogICAgICAgICAgICBvcy5ta2Rpcihz
+ZWxmLl9zb3VyY2VkaXIpCgogICAgZGVmIGVuZF9zb3VyY2Uoc2VsZik6CiAgICAgICAgc2VsZi5f
+bW9kdWxlX25hbWUgPSBOb25lCiAgICAgICAgc2VsZi5fbG9nZ2VyLmNsZWFyX2N1cnJlbnRfbW9k
+dWxlKCkKCiAgICBkZWYgc3RhcnRfYnVpbGQoc2VsZiwgbmFtZSwgc3VwcG9ydHNfb2JqZGlyKToK
+ICAgICAgICBhc3NlcnQgc2VsZi5fbW9kdWxlX3N1cHBvcnRzX29iamRpciBpcyBOb25lCiAgICAg
+ICAgc2VsZi5fbW9kdWxlX25hbWUgPSBuYW1lCiAgICAgICAgc2VsZi5fbW9kdWxlX3N1cHBvcnRz
+X29iamRpciA9IHN1cHBvcnRzX29iamRpcgogICAgICAgIHNlbGYuX2xvZ2dlci5zZXRfY3VycmVu
+dF9tb2R1bGUobmFtZSkKCiAgICBkZWYgZW5kX2J1aWxkKHNlbGYpOgogICAgICAgIHNlbGYuX21v
+ZHVsZV9uYW1lID0gTm9uZQogICAgICAgIHNlbGYuX21vZHVsZV9zdXBwb3J0c19vYmpkaXIgPSBO
+b25lCiAgICAgICAgc2VsZi5fbG9nZ2VyLmNsZWFyX2N1cnJlbnRfbW9kdWxlKCkKCiAgICBkZWYg
+X3Byb2dyYW1fbG9jYXRpb24oc2VsZiwgcHJvZ3JhbSk6CiAgICAgICAgZGVmIGlzX2V4ZShwYXRo
+KToKICAgICAgICAgICAgcmV0dXJuIG9zLnBhdGguZXhpc3RzKHBhdGgpIGFuZCBvcy5hY2Nlc3Mo
+cGF0aCwgb3MuWF9PSykKICAgICAgICBwYXRoLCBuYW1lID0gb3MucGF0aC5zcGxpdChwcm9ncmFt
+KQogICAgICAgIGlmIHBhdGg6CiAgICAgICAgICAgIGlmIGlzX2V4ZShwcm9ncmFtKToKICAgICAg
+ICAgICAgICAgIHJldHVybiBwcm9ncmFtCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZm9yIHBh
+dGggaW4gb3MuZW52aXJvblsiUEFUSCJdLnNwbGl0KG9zLnBhdGhzZXApICsgW3NlbGYuX2Jpbl9w
+YXRoKCldOgogICAgICAgICAgICAgICAgZXhlX2ZpbGUgPSBvcy5wYXRoLmpvaW4ocGF0aCwgcHJv
+Z3JhbSkKICAgICAgICAgICAgICAgIGlmIGlzX2V4ZShleGVfZmlsZSk6CiAgICAgICAgICAgICAg
+ICAgICAgcmV0dXJuIGV4ZV9maWxlCiAgICAgICAgcmV0dXJuIE5vbmUKCiAgICBkZWYgX2NoZWNr
+X3ZlcnNpb24oc2VsZiwgZm91bmQsIHJlcXVpcmVkLCBtYXRjaF90eXBlKToKICAgICAgICBhc3Nl
+cnQgbGVuKGZvdW5kKSA9PSBsZW4ocmVxdWlyZWQpCiAgICAgICAgaWYgbWF0Y2hfdHlwZSA9PSBz
+ZWxmLkhJR0hFUjoKICAgICAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMCxsZW4oZm91bmQpKToKICAg
+ICAgICAgICAgICAgIGlmIGludChmb3VuZFtpXSkgPCBpbnQocmVxdWlyZWRbaV0pOgogICAgICAg
+ICAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgICAgICAgICAgZWxpZiBpbnQoZm91bmRb
+aV0pID4gaW50KHJlcXVpcmVkW2ldKToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHJ1ZQog
+ICAgICAgICAgICByZXR1cm4gVHJ1ZQogICAgICAgIGVsaWYgbWF0Y2hfdHlwZSA9PSBzZWxmLkxP
+V0VSOgogICAgICAgICAgICBmb3IgaSBpbiByYW5nZSgwLGxlbihmb3VuZCkpOgogICAgICAgICAg
+ICAgICAgaWYgaW50KGZvdW5kW2ldKSA+IGludChyZXF1aXJlZFtpXSk6CiAgICAgICAgICAgICAg
+ICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgICAgICAgICBlbGlmIGludChmb3VuZFtpXSkgPCBp
+bnQocmVxdWlyZWRbaV0pOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBUcnVlCiAgICAgICAg
+ICAgIHJldHVybiBUcnVlCiAgICAgICAgZWxpZiBtYXRjaF90eXBlID09IHNlbGYuRVFVQUw6CiAg
+ICAgICAgICAgIGZvciBpIGluIHJhbmdlKDAsbGVuKGZvdW5kKSk6CiAgICAgICAgICAgICAgICBp
+ZiBpbnQoZm91bmRbaV0pICE9IGludChyZXF1aXJlZFtpXSk6CiAgICAgICAgICAgICAgICAgICAg
+cmV0dXJuIEZhbHNlCiAgICAgICAgICAgIHJldHVybiBUcnVlCiAgICAgICAgZWxzZToKICAgICAg
+ICAgICAgYXNzZXJ0IEZhbHNlCgogICAgZGVmIGFkZF9saWJwYXRocyhzZWxmLCBsaWJwYXRocyk6
+CiAgICAgICAgc2VsZi5fbGlicGF0aHMuZXh0ZW5kKFtzZWxmLnJlcGxhY2VfdmFyaWFibGVzKHBh
+dGgpIGZvciBwYXRoIGluIGxpYnBhdGhzXSkKCiAgICBkZWYgcmVwbGFjZV92YXJpYWJsZXMoc2Vs
+Ziwgc3RyaW5nKToKICAgICAgICBpbXBvcnQgcmUKICAgICAgICB0bXAgPSBzdHJpbmcKICAgICAg
+ICB0bXAgPSByZS5zdWIoJ1wkSU5TVEFMTERJUicsIHNlbGYuaW5zdGFsbGRpciwgdG1wKQogICAg
+ICAgIHRtcCA9IHJlLnN1YignXCRPQkpESVInLCBzZWxmLm9iamRpciwgdG1wKQogICAgICAgIHRt
+cCA9IHJlLnN1YignXCRTUkNESVInLCBzZWxmLnNyY2RpciwgdG1wKQogICAgICAgIHJldHVybiB0
+bXAKCiAgICBkZWYgY2hlY2tfcHJvZ3JhbShzZWxmLCBwcm9ncmFtLCB2ZXJzaW9uX2FyZyA9IE5v
+bmUsCiAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uX3JlZ2V4cCA9IE5vbmUsIHZlcnNpb25f
+cmVxdWlyZWQgPSBOb25lLAogICAgICAgICAgICAgICAgICAgICAgbWF0Y2hfdHlwZT1ISUdIRVIp
+OgogICAgICAgIGlmIHNlbGYuX3Byb2dyYW1fbG9jYXRpb24ocHJvZ3JhbSkgaXMgTm9uZToKICAg
+ICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgaWYgdmVyc2lvbl9hcmcgaXMgTm9uZSBhbmQg
+dmVyc2lvbl9yZWdleHAgaXMgTm9uZSBhbmQgdmVyc2lvbl9yZXF1aXJlZCBpcyBOb25lOgogICAg
+ICAgICAgICByZXR1cm4gVHJ1ZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGFzc2VydCBub3Qg
+KHZlcnNpb25fYXJnIGlzIE5vbmUgb3IgdmVyc2lvbl9yZWdleHAgaXMgTm9uZSBvciB2ZXJzaW9u
+X3JlcXVpcmVkIGlzIE5vbmUpCiAgICAgICAgICAgIHBvcGVuID0gc3VicHJvY2Vzcy5Qb3Blbihb
+c2VsZi5fcHJvZ3JhbV9sb2NhdGlvbihwcm9ncmFtKSwgdmVyc2lvbl9hcmddLAogICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Rkb3V0ID0gc3VicHJvY2Vzcy5QSVBFLAogICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkZXJyID0gc3VicHJvY2Vzcy5TVERP
+VVQpCiAgICAgICAgICAgIChvdXQsIGVycikgPSBwb3Blbi5jb21tdW5pY2F0ZSgnJykKICAgICAg
+ICAgICAgaW1wb3J0IHJlCiAgICAgICAgICAgIHJlZyA9IHJlLmNvbXBpbGUodmVyc2lvbl9yZWdl
+eHApCiAgICAgICAgICAgIGZvciBsaW5lIGluIG91dC5zcGxpdGxpbmVzKCk6CiAgICAgICAgICAg
+ICAgICBtID0gcmVnLnNlYXJjaChsaW5lKQogICAgICAgICAgICAgICAgaWYgbm90IG0gaXMgTm9u
+ZToKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IG0uZ3JvdXBzKCkKICAgICAgICAgICAgICAg
+ICAgICByZXR1cm4gc2VsZi5fY2hlY2tfdmVyc2lvbihmb3VuZCwgdmVyc2lvbl9yZXF1aXJlZCwg
+bWF0Y2hfdHlwZSkKCiAgICBkZWYgcnVuKHNlbGYsIGFyZ3MsIGRpcmVjdG9yeSA9IE5vbmUsIGVu
+diA9IGRpY3QoKSwgaW50ZXJhY3RpdmUgPSBGYWxzZSk6CiAgICAgICAgaWYgbm90IGludGVyYWN0
+aXZlOgogICAgICAgICAgICBlbnZfc3RyaW5nID0gJycKICAgICAgICAgICAgaWYgbGVuKGVudikg
+IT0gMDoKICAgICAgICAgICAgICAgIGVudl9zdHJpbmcgPSAnICcuam9pbihbYSArICc9JyArIGIg
+Zm9yIGEsYiBpbiBlbnYuaXRlbXMoKV0pCiAgICAgICAgICAgIGFyZ3Nfc3RyaW5nID0gJyAnLmpv
+aW4oYXJncykKICAgICAgICAgICAgc2VsZi5fbG9nZ2VyLmNvbW1hbmRzLndyaXRlKGVudl9zdHJp
+bmcgKyAnICcgKyBhcmdzX3N0cmluZyArICcgZGlyPScgKyBzdHIoZGlyZWN0b3J5KSArICdcbicp
+CiAgICAgICAgICAgIHN0ZGluID0gTm9uZQogICAgICAgICAgICBzdGRvdXQgPSBzZWxmLl9sb2dn
+ZXIuc3Rkb3V0CiAgICAgICAgICAgIHN0ZGVyciA9IHNlbGYuX2xvZ2dlci5zdGRlcnIKICAgICAg
+ICBlbHNlOgogICAgICAgICAgICBzdGRpbiA9IHN5cy5zdGRpbgogICAgICAgICAgICBzdGRvdXQg
+PSBzeXMuc3Rkb3V0CiAgICAgICAgICAgIHN0ZGVyciA9IHN5cy5zdGRlcnIgICAgICAgICAgICAK
+ICAgICAgICB0bXAgPSBkaWN0KG9zLmVudmlyb24uaXRlbXMoKSArIGVudi5pdGVtcygpKQogICAg
+ICAgIGZvciBsaWJwYXRoIGluIHNlbGYuX2xpYnBhdGhzOgogICAgICAgICAgICBzZWxmLl9hcHBl
+bmRfcGF0aCh0bXAsIHNlbGYuX2xpYl92YXIoKSwgbGlicGF0aCwgb3MucGF0aHNlcCkKICAgICAg
+ICBzZWxmLl9hcHBlbmRfcGF0aCh0bXAsIHNlbGYuX2xpYl92YXIoKSwgc2VsZi5fbGliX3BhdGgo
+KSwgb3MucGF0aHNlcCkKICAgICAgICBzZWxmLl9hcHBlbmRfcGF0aCh0bXAsIHNlbGYuX2Jpbl92
+YXIoKSwgc2VsZi5fYmluX3BhdGgoKSwgb3MucGF0aHNlcCkKICAgICAgICBzZWxmLl9hcHBlbmRf
+cGF0aCh0bXAsIHNlbGYuX3B5X3ZhcigpLCBzZWxmLl9weV9wYXRoKCksIG9zLnBhdGhzZXApCiAg
+ICAgICAgc2VsZi5fYXBwZW5kX3BhdGgodG1wLCBzZWxmLl9wa2djb25maWdfdmFyKCksIHNlbGYu
+X3BrZ2NvbmZpZ19wYXRoKCksIG9zLnBhdGhzZXApCiAgICAgICAgcG9wZW4gPSBzdWJwcm9jZXNz
+LlBvcGVuKGFyZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZGluID0gc3Rk
+aW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZG91dCA9IHN0ZG91dCwKICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkZXJyID0gc3RkZXJyLAogICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICBjd2QgPSBkaXJlY3RvcnksCiAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgIGVudiA9IHRtcCkKICAgICAgICByZXRjb2RlID0gcG9wZW4ud2FpdCgp
+CiAgICAgICAgaWYgcmV0Y29kZSAhPSAwOgogICAgICAgICAgICByYWlzZSBUYXNrRXJyb3IoJ1N1
+YnByb2Nlc3MgZmFpbGVkIHdpdGggZXJyb3IgJWQ6ICVzJyAlIChyZXRjb2RlLCBzdHIoYXJncykp
+KQoKICAgICAgICAKUEsDBBQAAAAAANSsXz/S4ZCSeSoAAHkqAAATAAAAYmFrZS9Nb2R1bGVCdWls
+ZC5weWltcG9ydCBVdGlscwppbXBvcnQgb3MKZnJvbSBVdGlscyBpbXBvcnQgTW9kdWxlQXR0cmli
+dXRlQmFzZQpmcm9tIEV4Y2VwdGlvbnMgaW1wb3J0IE5vdEltcGxlbWVudGVkCgpjbGFzcyBNb2R1
+bGVCdWlsZChNb2R1bGVBdHRyaWJ1dGVCYXNlKToKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAg
+ICAgICBNb2R1bGVBdHRyaWJ1dGVCYXNlLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5fbGli
+cGF0aHMgPSBbXQogICAgICAgIHNlbGYuYWRkX2F0dHJpYnV0ZSgnb2JqZGlyJywgJ25vJywgJ01v
+ZHVsZSBzdXBwb3J0cyBvYmpkaXIgIT0gc3JjZGlyLicpCiAgICBAY2xhc3NtZXRob2QKICAgIGRl
+ZiBzdWJjbGFzc2VzKHNlbGYpOgogICAgICAgIHJldHVybiBNb2R1bGVCdWlsZC5fX3N1YmNsYXNz
+ZXNfXygpCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBjcmVhdGUoY2xzLCBuYW1lKToKICAgICAg
+ICBmb3Igc3ViY2xhc3MgaW4gTW9kdWxlQnVpbGQuc3ViY2xhc3NlcygpOgogICAgICAgICAgICBp
+ZiBzdWJjbGFzcy5uYW1lKCkgPT0gbmFtZToKICAgICAgICAgICAgICAgIGluc3RhbmNlID0gc3Vi
+Y2xhc3MoKQogICAgICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlCiAgICAgICAgcmV0dXJuIE5v
+bmUKICAgIEBwcm9wZXJ0eQogICAgZGVmIGxpYnBhdGhzKHNlbGYpOgogICAgICAgIHJldHVybiBz
+ZWxmLl9saWJwYXRocwogICAgZGVmIGFkZF9saWJwYXRoKHNlbGYsIHBhdGgpOgogICAgICAgIHNl
+bGYuX2xpYnBhdGhzLmFwcGVuZChwYXRoKQogICAgQHByb3BlcnR5CiAgICBkZWYgc3VwcG9ydHNf
+b2JqZGlyKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLmF0dHJpYnV0ZSgnb2JqZGlyJykudmFs
+dWUgPT0gJ3llcycKICAgIGRlZiBidWlsZChzZWxmLCBlbnYsIGpvYnMpOgogICAgICAgIHJhaXNl
+IE5vdEltcGxlbWVudGVkKCkKICAgIGRlZiBjbGVhbihzZWxmLCBlbnYpOgogICAgICAgIHJhaXNl
+IE5vdEltcGxlbWVudGVkKCkKICAgIGRlZiBjaGVja192ZXJzaW9uKHNlbGYsIGVudik6CiAgICAg
+ICAgcmFpc2UgTm90SW1wbGVtZW50ZWQoKQoKY2xhc3MgTm9uZU1vZHVsZUJ1aWxkKE1vZHVsZUJ1
+aWxkKToKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBNb2R1bGVCdWlsZC5fX2luaXRf
+XyhzZWxmKQogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgbmFtZShjbHMpOgogICAgICAgIHJldHVy
+biAnbm9uZScKICAgIGRlZiBidWlsZChzZWxmLCBlbnYsIGpvYnMpOgogICAgICAgIHBhc3MKICAg
+IGRlZiBjbGVhbihzZWxmLCBlbnYpOgogICAgICAgIHBhc3MKICAgIGRlZiBjaGVja192ZXJzaW9u
+KHNlbGYsIGVudik6CiAgICAgICAgcmV0dXJuIFRydWUKCgpjbGFzcyBJbmxpbmVNb2R1bGVCdWls
+ZChNb2R1bGVCdWlsZCk6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgTW9kdWxlQnVp
+bGQuX19pbml0X18oc2VsZikKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIG5hbWUoY2xzKToKICAg
+ICAgICByZXR1cm4gJ2lubGluZScKCmNsYXNzIFB5dGhvbk1vZHVsZUJ1aWxkKE1vZHVsZUJ1aWxk
+KToKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBNb2R1bGVCdWlsZC5fX2luaXRfXyhz
+ZWxmKQogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgbmFtZShjbHMpOgogICAgICAgIHJldHVybiAn
+cHl0aG9uJwogICAgZGVmIGJ1aWxkKHNlbGYsIGVudiwgam9icyk6CiAgICAgICAgZW52LnJ1bihb
+J3B5dGhvbicsIG9zLnBhdGguam9pbihlbnYuc3JjZGlyLCAnc2V0dXAucHknKSwgJ2J1aWxkJywg
+CiAgICAgICAgICAgICAgICAgICctLWJ1aWxkLWJhc2U9JyArIGVudi5vYmpkaXIsIAogICAgICAg
+ICAgICAgICAgICAnaW5zdGFsbCcsICctLXByZWZpeD0nICsgZW52Lmluc3RhbGxkaXJdLCAKICAg
+ICAgICAgICAgICAgICBkaXJlY3RvcnkgPSBlbnYuc3JjZGlyKQogICAgZGVmIGNsZWFuKHNlbGYs
+IGVudik6CiAgICAgICAgZW52LnJ1bihbJ3B5dGhvbicsIG9zLnBhdGguam9pbihlbnYuc3JjZGly
+LCAnc2V0dXAucHknKSwgJ2NsZWFuJywgCiAgICAgICAgICAgICAgICAgJy0tYnVpbGQtYmFzZT0n
+ICsgZW52Lm9iamRpcl0sCiAgICAgICAgICAgICAgICBkaXJlY3RvcnkgPSBlbnYuc3JjZGlyKQog
+ICAgZGVmIGNoZWNrX3ZlcnNpb24oc2VsZiwgZW52KToKICAgICAgICByZXR1cm4gVHJ1ZQoKCgpj
+bGFzcyBXYWZNb2R1bGVCdWlsZChNb2R1bGVCdWlsZCk6CiAgICBkZWYgX19pbml0X18oc2VsZik6
+CiAgICAgICAgTW9kdWxlQnVpbGQuX19pbml0X18oc2VsZikKICAgICAgICBzZWxmLmFkZF9hdHRy
+aWJ1dGUoJ0NDJywgICAgICAgJycsICdDIGNvbXBpbGVyIHRvIHVzZScpCiAgICAgICAgc2VsZi5h
+ZGRfYXR0cmlidXRlKCdDWFgnLCAgICAgICcnLCAnQysrIGNvbXBpbGVyIHRvIHVzZScpCiAgICAg
+ICAgc2VsZi5hZGRfYXR0cmlidXRlKCdDRkxBR1MnLCAgICcnLCAnRmxhZ3MgdG8gdXNlIGZvciBD
+IGNvbXBpbGVyJykKICAgICAgICBzZWxmLmFkZF9hdHRyaWJ1dGUoJ0NYWEZMQUdTJywgJycsICdG
+bGFncyB0byB1c2UgZm9yIEMrKyBjb21waWxlcicpCiAgICAgICAgc2VsZi5hZGRfYXR0cmlidXRl
+KCdMREZMQUdTJywgICcnLCAnRmxhZ3MgdG8gdXNlIGZvciBMaW5rZXInKQogICAgICAgIHNlbGYu
+YWRkX2F0dHJpYnV0ZSgnY29uZmlndXJlX2FyZ3VtZW50cycsICAnJywgJ0FyZ3VtZW50cyB0byBw
+YXNzIHRvICJ3YWYgY29uZmlndXJlIicpCiAgICAgICAgc2VsZi5hZGRfYXR0cmlidXRlKCdidWls
+ZF9hcmd1bWVudHMnLCAgJycsICdBcmd1bWVudHMgdG8gcGFzcyB0byAid2FmIicpCiAgICBAY2xh
+c3NtZXRob2QKICAgIGRlZiBuYW1lKGNscyk6CiAgICAgICAgcmV0dXJuICd3YWYnCiAgICBkZWYg
+X2JpbmFyeShzZWxmLCBzcmNkaXIpOgogICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKG9zLnBhdGgu
+am9pbihzcmNkaXIsICd3YWYnKSk6CiAgICAgICAgICAgIHdhZl9iaW5hcnkgPSBvcy5wYXRoLmpv
+aW4oc3JjZGlyLCAnd2FmJykKICAgICAgICBlbHNlOgogICAgICAgICAgICB3YWZfYmluYXJ5ID0g
+J3dhZicKICAgICAgICByZXR1cm4gd2FmX2JpbmFyeQogICAgZGVmIF9lbnYoc2VsZiwgb2JqZGly
+KToKICAgICAgICBlbnYgPSBkaWN0KCkKICAgICAgICBmb3IgYSxiIGluIFtbJ0NDJywgJ0NDJ10s
+IAogICAgICAgICAgICAgICAgICAgIFsnQ1hYJywgJ0NYWCddLAogICAgICAgICAgICAgICAgICAg
+IFsnQ0ZMQUdTJywgJ0NGTEFHUyddLAogICAgICAgICAgICAgICAgICAgIFsnQ1hYRkxBR1MnLCAn
+Q1hYRkxBR1MnXSwKICAgICAgICAgICAgICAgICAgICBbJ0xERkxBR1MnLCAnTElOS0ZMQUdTJ11d
+OgogICAgICAgICAgICBpZiBzZWxmLmF0dHJpYnV0ZShhKS52YWx1ZSAhPSAnJzoKICAgICAgICAg
+ICAgICAgIGVudltiXSA9IHNlbGYuYXR0cmlidXRlKGEpLnZhbHVlCiAgICAgICAgZW52WydXQUZM
+T0NLJ10gPSAnLmxvY2stJXMnICUgb3MucGF0aC5iYXNlbmFtZShvYmpkaXIpCiAgICAgICAgcmV0
+dXJuIGVudgogICAgZGVmIF9pc18xXzZfeChzZWxmLCBlbnYpOgogICAgICAgIHJldHVybiBlbnYu
+Y2hlY2tfcHJvZ3JhbShzZWxmLl9iaW5hcnkoZW52LnNyY2RpciksIHZlcnNpb25fYXJnID0gJy0t
+dmVyc2lvbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnNpb25fcmVnZXhw
+ID0gJyhcZCspXC4oXGQrKVwuKFxkKyknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICB2ZXJzaW9uX3JlcXVpcmVkID0gKDEsNiwwKSkKICAgIGRlZiBidWlsZChzZWxmLCBlbnYsIGpv
+YnMpOgogICAgICAgIGV4dHJhX2NvbmZpZ3VyZV9vcHRpb25zID0gW10KICAgICAgICBpZiBzZWxm
+LmF0dHJpYnV0ZSgnY29uZmlndXJlX2FyZ3VtZW50cycpLnZhbHVlICE9ICcnOgogICAgICAgICAg
+ICBleHRyYV9jb25maWd1cmVfb3B0aW9ucyA9IFtlbnYucmVwbGFjZV92YXJpYWJsZXModG1wKSBm
+b3IgdG1wIGluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXR0
+cmlidXRlKCdjb25maWd1cmVfYXJndW1lbnRzJykudmFsdWUuc3BsaXQoJyAnKV0KICAgICAgICBl
+eHRyYV9idWlsZF9vcHRpb25zID0gW10KICAgICAgICBpZiBzZWxmLmF0dHJpYnV0ZSgnYnVpbGRf
+YXJndW1lbnRzJykudmFsdWUgIT0gJyc6CiAgICAgICAgICAgIGV4dHJhX2J1aWxkX29wdGlvbnMg
+PSBbZW52LnJlcGxhY2VfdmFyaWFibGVzKHRtcCkgZm9yIHRtcCBpbgogICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgIHNlbGYuYXR0cmlidXRlKCdidWlsZF9hcmd1bWVudHMnKS52YWx1
+ZS5zcGxpdCgnICcpXQogICAgICAgIGlmIHNlbGYuX2lzXzFfNl94KGVudik6CiAgICAgICAgICAg
+IGVudi5ydW4oW3NlbGYuX2JpbmFyeShlbnYuc3JjZGlyKSwgJy0tdG9wPScgKyBlbnYuc3JjZGly
+LCAnLS1vdXQ9JyArIGVudi5vYmpkaXIsIAogICAgICAgICAgICAgICAgICAgICAnLS1wcmVmaXg9
+JyArIGVudi5pbnN0YWxsZGlyLCAnY29uZmlndXJlJ10gKyBleHRyYV9jb25maWd1cmVfb3B0aW9u
+cywKICAgICAgICAgICAgICAgICAgICBkaXJlY3RvcnkgPSBlbnYuc3JjZGlyLAogICAgICAgICAg
+ICAgICAgICAgIGVudiA9IHNlbGYuX2VudihlbnYub2JqZGlyKSkKICAgICAgICBlbHNlOgogICAg
+ICAgICAgICBlbnYucnVuKFtzZWxmLl9iaW5hcnkoZW52LnNyY2RpciksICctLXNyY2Rpcj0nICsg
+ZW52LnNyY2RpciwgJy0tYmxkZGlyPScgKyBlbnYub2JqZGlyLCAKICAgICAgICAgICAgICAgICAg
+ICAgJy0tcHJlZml4PScgKyBlbnYuaW5zdGFsbGRpciwgJ2NvbmZpZ3VyZSddICsgZXh0cmFfY29u
+ZmlndXJlX29wdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgZGlyZWN0b3J5ID0gZW52LnNyY2Rp
+ciwKICAgICAgICAgICAgICAgICAgICBlbnYgPSBzZWxmLl9lbnYoZW52Lm9iamRpcikpCiAgICAg
+ICAgZW52LnJ1bihbc2VsZi5fYmluYXJ5KGVudi5zcmNkaXIpXSArIGV4dHJhX2J1aWxkX29wdGlv
+bnMgKyBbJy1qJywgc3RyKGpvYnMpXSwKICAgICAgICAgICAgICAgIGRpcmVjdG9yeSA9IGVudi5z
+cmNkaXIsCiAgICAgICAgICAgICAgICBlbnYgPSBzZWxmLl9lbnYoZW52Lm9iamRpcikpCiAgICAg
+ICAgZW52LnJ1bihbc2VsZi5fYmluYXJ5KGVudi5zcmNkaXIpLCAnaW5zdGFsbCddLAogICAgICAg
+ICAgICAgICAgZGlyZWN0b3J5ID0gZW52LnNyY2RpciwKICAgICAgICAgICAgICAgIGVudiA9IHNl
+bGYuX2VudihlbnYub2JqZGlyKSkKICAgICAgICAKICAgIGRlZiBjbGVhbihzZWxmLCBlbnYpOgog
+ICAgICAgIHdsb2NrZmlsZSA9ICcubG9jay0lcycgJSBvcy5wYXRoLmJhc2VuYW1lKGVudi5vYmpk
+aXIpCiAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUob3MucGF0aC5qb2luKGVudi5zcmNkaXIsIHds
+b2NrZmlsZSkpOgogICAgICAgICAgICBlbnYucnVuKFtzZWxmLl9iaW5hcnkoZW52LnNyY2Rpciks
+ICctaycsICdjbGVhbiddLAogICAgICAgICAgICAgICAgICAgIGRpcmVjdG9yeSA9IGVudi5zcmNk
+aXIsCiAgICAgICAgICAgICAgICAgICAgZW52ID0gc2VsZi5fZW52KGVudi5vYmpkaXIpKQogICAg
+ZGVmIGNoZWNrX3ZlcnNpb24oc2VsZiwgZW52KToKICAgICAgICBmb3IgcGF0aCBpbiBbb3MucGF0
+aC5qb2luKGVudi5zcmNkaXIsICd3YWYnKSwgJ3dhZiddOgogICAgICAgICAgICBpZiBlbnYuY2hl
+Y2tfcHJvZ3JhbShwYXRoLCB2ZXJzaW9uX2FyZyA9ICctLXZlcnNpb24nLAogICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uX3JlZ2V4cCA9ICcoXGQrKVwuKFxkKylcLihcZCsp
+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyc2lvbl9yZXF1aXJlZCA9ICgx
+LDUsOSkpOgogICAgICAgICAgICAgICAgcmV0dXJuIFRydWUKICAgICAgICByZXR1cm4gRmFsc2UK
+CgpjbGFzcyBDbWFrZShNb2R1bGVCdWlsZCk6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAg
+ICAgTW9kdWxlQnVpbGQuX19pbml0X18oc2VsZikKICAgICAgICBzZWxmLmFkZF9hdHRyaWJ1dGUo
+J0NDJywgICAgICAgJycsICdDIGNvbXBpbGVyIHRvIHVzZScpCiAgICAgICAgc2VsZi5hZGRfYXR0
+cmlidXRlKCdDWFgnLCAgICAgICcnLCAnQysrIGNvbXBpbGVyIHRvIHVzZScpCiAgICAgICAgc2Vs
+Zi5hZGRfYXR0cmlidXRlKCdDRkxBR1MnLCAgICcnLCAnRmxhZ3MgdG8gdXNlIGZvciBDIGNvbXBp
+bGVyJykKICAgICAgICBzZWxmLmFkZF9hdHRyaWJ1dGUoJ0NYWEZMQUdTJywgJycsICdGbGFncyB0
+byB1c2UgZm9yIEMrKyBjb21waWxlcicpCiAgICAgICAgc2VsZi5hZGRfYXR0cmlidXRlKCdMREZM
+QUdTJywgICcnLCAnRmxhZ3MgdG8gdXNlIGZvciBMaW5rZXInKQogICAgICAgIHNlbGYuYWRkX2F0
+dHJpYnV0ZSgnYnVpbGRfdGFyZ2V0cycsICcnLCAnVGFyZ2V0cyB0byBtYWtlIGJlZm9yZSBpbnN0
+YWxsJykKICAgICAgICBzZWxmLmFkZF9hdHRyaWJ1dGUoJ2NtYWtlX2FyZ3VtZW50cycsICcnLCAn
+Q29tbWFuZC1saW5lIGFyZ3VtZW50cyB0byBwYXNzIHRvIGNtYWtlJykKICAgIEBjbGFzc21ldGhv
+ZAogICAgZGVmIG5hbWUoY2xzKToKICAgICAgICByZXR1cm4gJ2NtYWtlJwogICAgZGVmIF92YXJp
+YWJsZXMoc2VsZik6CiAgICAgICAgdmFyaWFibGVzID0gW10KICAgICAgICBmb3IgYSxiIGluIFtb
+J0NDJywgJ0NfQ09NUElMRVInXSwgCiAgICAgICAgICAgICAgICAgICAgWydDWFgnLCAnQ1hYX0NP
+TVBJTEVSJ10sCiAgICAgICAgICAgICAgICAgICAgWydDRkxBR1MnLCAnQ0ZMQUdTJ10sCiAgICAg
+ICAgICAgICAgICAgICAgWydDWFhGTEFHUycsICdDWFhGTEFHUyddLAogICAgICAgICAgICAgICAg
+ICAgIFsnTERGTEFHUycsICdFWEVfTElOS0VSX0ZMQUdTJ11dOgogICAgICAgICAgICBpZiBzZWxm
+LmF0dHJpYnV0ZShhKS52YWx1ZSAhPSAnJzoKICAgICAgICAgICAgICAgIHZhcmlhYmxlcy5hcHBl
+bmQoJy1EQ01BS0VfJXM9JXMnICUoYiwgc2VsZi5hdHRyaWJ1dGUoYSkudmFsdWUpKQogICAgICAg
+IHJldHVybiB2YXJpYWJsZXMKCiAgICBkZWYgYnVpbGQoc2VsZiwgZW52LCBqb2JzKToKICAgICAg
+ICBvcHRpb25zID0gW10KICAgICAgICBpZiBzZWxmLmF0dHJpYnV0ZSgnY21ha2VfYXJndW1lbnRz
+JykudmFsdWUgIT0gJyc6CiAgICAgICAgICAgIG9wdGlvbnMgPSBzZWxmLmF0dHJpYnV0ZSgnY21h
+a2VfYXJndW1lbnRzJykudmFsdWUuc3BsaXQoJyAnKQogICAgICAgIGVudi5ydW4oWydjbWFrZScs
+IGVudi5zcmNkaXIsICctRENNQUtFX0lOU1RBTExfUFJFRklYPScgKyBlbnYuaW5zdGFsbGRpcl0g
+KyAKICAgICAgICAgICAgICAgIHNlbGYuX3ZhcmlhYmxlcygpICsgb3B0aW9ucywKICAgICAgICAg
+ICAgICAgIGRpcmVjdG9yeT1lbnYub2JqZGlyKQogICAgICAgIGVudi5ydW4oWydtYWtlJywgJy1q
+Jywgc3RyKGpvYnMpXSwgZGlyZWN0b3J5ID0gZW52Lm9iamRpcikKICAgICAgICBpZiBzZWxmLmF0
+dHJpYnV0ZSgnYnVpbGRfdGFyZ2V0cycpLnZhbHVlICE9ICcnOgogICAgICAgICAgICBlbnYucnVu
+KFsnbWFrZSddICsgc2VsZi5hdHRyaWJ1dGUoJ2J1aWxkX3RhcmdldHMnKS52YWx1ZS5zcGxpdCgn
+ICcpLCAKICAgICAgICAgICAgICAgICAgICBkaXJlY3RvcnkgPSBlbnYub2JqZGlyKQogICAgICAg
+IGVudi5ydW4oWydtYWtlJywgJ2luc3RhbGwnXSwgZGlyZWN0b3J5ID0gZW52Lm9iamRpcikKICAg
+IGRlZiBjbGVhbihzZWxmLCBlbnYpOgogICAgICAgIGlmIG5vdCBvcy5wYXRoLmlzZmlsZShvcy5w
+YXRoLmpvaW4oZW52Lm9iamRpciwgJ01ha2VmaWxlJykpOgogICAgICAgICAgICByZXR1cm4KICAg
+ICAgICBlbnYucnVuKFsnbWFrZScsICdjbGVhbiddLCBkaXJlY3RvcnkgPSBlbnYub2JqZGlyKQog
+ICAgZGVmIGNoZWNrX3ZlcnNpb24oc2VsZiwgZW52KToKICAgICAgICBpZiBub3QgZW52LmNoZWNr
+X3Byb2dyYW0oJ2NtYWtlJywgdmVyc2lvbl9hcmcgPSAnLS12ZXJzaW9uJywKICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgdmVyc2lvbl9yZWdleHAgPSAnKFxkKylcLihcZCspXC4oXGQr
+KScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnNpb25fcmVxdWlyZWQgPSAo
+Miw4LDIpKToKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgaWYgbm90IGVudi5jaGVj
+a19wcm9ncmFtKCdtYWtlJywgdmVyc2lvbl9hcmcgPSAnLS12ZXJzaW9uJywKICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgdmVyc2lvbl9yZWdleHAgPSAnKFxkKylcLihcZCspJywKICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyc2lvbl9yZXF1aXJlZCA9ICgzLDgwKSk6
+CiAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIHJldHVybiBUcnVlCgoKY2xhc3MgQXV0
+b3Rvb2xzKE1vZHVsZUJ1aWxkKToKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBNb2R1
+bGVCdWlsZC5fX2luaXRfXyhzZWxmKQogICAgICAgIHNlbGYuYWRkX2F0dHJpYnV0ZSgnQ0MnLCAg
+ICAgICAnJywgJ0MgY29tcGlsZXIgdG8gdXNlJykKICAgICAgICBzZWxmLmFkZF9hdHRyaWJ1dGUo
+J0NYWCcsICAgICAgJycsICdDKysgY29tcGlsZXIgdG8gdXNlJykKICAgICAgICBzZWxmLmFkZF9h
+dHRyaWJ1dGUoJ0NGTEFHUycsICAgJycsICdGbGFncyB0byB1c2UgZm9yIEMgY29tcGlsZXInKQog
+ICAgICAgIHNlbGYuYWRkX2F0dHJpYnV0ZSgnQ1hYRkxBR1MnLCAnJywgJ0ZsYWdzIHRvIHVzZSBm
+b3IgQysrIGNvbXBpbGVyJykKICAgICAgICBzZWxmLmFkZF9hdHRyaWJ1dGUoJ0xERkxBR1MnLCAg
+JycsICdGbGFncyB0byB1c2UgZm9yIExpbmtlcicpCiAgICAgICAgc2VsZi5hZGRfYXR0cmlidXRl
+KCdtYWludGFpbmVyJywgJ25vJywgJ01haW50YWluZXIgbW9kZSA/JykKICAgICAgICBzZWxmLmFk
+ZF9hdHRyaWJ1dGUoJ2NvbmZpZ3VyZV9hcmd1bWVudHMnLCAnJywgJ0NvbW1hbmQtbGluZSBhcmd1
+bWVudHMgdG8gcGFzcyB0byBjb25maWd1cmUnKQogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgbmFt
+ZShjbHMpOgogICAgICAgIHJldHVybiAnYXV0b3Rvb2xzJwogICAgZGVmIF92YXJpYWJsZXMoc2Vs
+Zik6CiAgICAgICAgdmFyaWFibGVzID0gW10KICAgICAgICBmb3IgdG1wIGluIFsnQ0MnLCdDWFgn
+LCAnQ0ZMQUdTJywgJ0NYWEZMQUdTJywgJ0xERkxBR1MnXToKICAgICAgICAgICAgaWYgc2VsZi5h
+dHRyaWJ1dGUodG1wKS52YWx1ZSAhPSAnJzoKICAgICAgICAgICAgICAgIHZhcmlhYmxlcy5hcHBl
+bmQoJyVzPSVzJyAlICh0bXAsIHNlbGYuYXR0cmlidXRlKHRtcCkudmFsdWUpKQogICAgICAgIHJl
+dHVybiB2YXJpYWJsZXMKICAgIGRlZiBidWlsZChzZWxmLCBlbnYsIGpvYnMpOgogICAgICAgIGlm
+IHNlbGYuYXR0cmlidXRlKCdtYWludGFpbmVyJykudmFsdWUgIT0gJ25vJzoKICAgICAgICAgICAg
+ZW52LnJ1bihbJ2F1dG9yZWNvbmYnLCAnLS1pbnN0YWxsJ10sIAogICAgICAgICAgICAgICAgICAg
+IGRpcmVjdG9yeSA9IGVudi5zcmNkaXIpCiAgICAgICAgb3B0aW9ucyA9IFtdCiAgICAgICAgaWYg
+c2VsZi5hdHRyaWJ1dGUoJ2NvbmZpZ3VyZV9hcmd1bWVudHMnKS52YWx1ZSAhPSAnJzoKICAgICAg
+ICAgICAgb3B0aW9ucyA9IHNlbGYuYXR0cmlidXRlKCdjb25maWd1cmVfYXJndW1lbnRzJykudmFs
+dWUuc3BsaXQoJyAnKQogICAgICAgIGVudi5ydW4oW29zLnBhdGguam9pbihlbnYuc3JjZGlyLCAn
+Y29uZmlndXJlJyksCiAgICAgICAgICAgICAgICAgJy0tcHJlZml4PScgKyBlbnYuaW5zdGFsbGRp
+cl0gKyAKICAgICAgICAgICAgICAgIHNlbGYuX3ZhcmlhYmxlcygpICsgb3B0aW9ucywgCiAgICAg
+ICAgICAgICAgICBkaXJlY3RvcnkgPSBlbnYub2JqZGlyKQogICAgICAgIGVudi5ydW4oWydtYWtl
+JywgJy1qJywgc3RyKGpvYnMpXSwgZGlyZWN0b3J5ID0gZW52Lm9iamRpcikKICAgICAgICBlbnYu
+cnVuKFsnbWFrZScsICdpbnN0YWxsJ10sIGRpcmVjdG9yeSA9IGVudi5vYmpkaXIpCgogICAgZGVm
+IGNsZWFuKHNlbGYsIGVudik6CiAgICAgICAgaWYgbm90IG9zLnBhdGguaXNmaWxlKG9zLnBhdGgu
+am9pbihlbnYub2JqZGlyLCdNYWtlZmlsZScpKToKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAg
+aWYgc2VsZi5hdHRyaWJ1dGUoJ21haW50YWluZXInKS52YWx1ZSAhPSAnbm8nOgogICAgICAgICAg
+ICBlbnYucnVuKFsnbWFrZScsICctaycsICdtYWludGFpbmVyY2xlYW4nXSwgZGlyZWN0b3J5ID0g
+ZW52Lm9iamRpcikKICAgICAgICBlbHNlOgogICAgICAgICAgICBlbnYucnVuKFsnbWFrZScsICct
+aycsICdkaXN0Y2xlYW4nXSwgZGlyZWN0b3J5ID0gZW52Lm9iamRpcikKICAgICAgICB0cnk6CiAg
+ICAgICAgICAgIG9zLnJlbW92ZShvcy5wYXRoLmpvaW4oZW52Lm9iamRpciwgJ2NvbmZpZy5jYWNo
+ZScpKQogICAgICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgICAgICBwYXNzCiAgICBkZWYgY2hl
+Y2tfdmVyc2lvbihzZWxmLCBlbnYpOgogICAgICAgIGlmIG5vdCBlbnYuY2hlY2tfcHJvZ3JhbSgn
+YXV0b3JlY29uZicsIHZlcnNpb25fYXJnID0gJy0tdmVyc2lvbicsCiAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgIHZlcnNpb25fcmVnZXhwID0gJyhcZCspXC4oXGQrKScsCiAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnNpb25fcmVxdWlyZWQgPSAoMiw2NikpOgogICAg
+ICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICBpZiBub3QgZW52LmNoZWNrX3Byb2dyYW0oJ21h
+a2UnLCB2ZXJzaW9uX2FyZyA9ICctLXZlcnNpb24nLAogICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICB2ZXJzaW9uX3JlZ2V4cCA9ICcoXGQrKVwuKFxkKyknLAogICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICB2ZXJzaW9uX3JlcXVpcmVkID0gKDMsODApKToKICAgICAgICAgICAg
+cmV0dXJuIEZhbHNlCiAgICAgICAgcmV0dXJuIFRydWUKICAgICAgICAgICAgCgpQSwMEFAAAAAAA
+FpmuPlffrantFAAA7RQAAA4AAABiYWtlL01vZHVsZS5weWltcG9ydCBjb3B5CmltcG9ydCBvcwpm
+cm9tIEZpbGVzeXN0ZW1Nb25pdG9yIGltcG9ydCBGaWxlc3lzdGVtTW9uaXRvcgoKY2xhc3MgTW9k
+dWxlRGVwZW5kZW5jeToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lLCBvcHRpb25hbCA9IEZh
+bHNlKToKICAgICAgICBzZWxmLl9uYW1lID0gbmFtZQogICAgICAgIHNlbGYuX29wdGlvbmFsID0g
+b3B0aW9uYWwKICAgIGRlZiBuYW1lKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9uYW1lCiAg
+ICBkZWYgaXNfb3B0aW9uYWwoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX29wdGlvbmFsCgpj
+bGFzcyBNb2R1bGU6CiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgCiAgICAgICAgICAgICAg
+ICAgc291cmNlLAogICAgICAgICAgICAgICAgIGJ1aWxkLAogICAgICAgICAgICAgICAgIGRlcGVu
+ZGVuY2llcyA9IFtdLAogICAgICAgICAgICAgICAgIGJ1aWx0X29uY2UgPSBGYWxzZSwKICAgICAg
+ICAgICAgICAgICBpbnN0YWxsZWQgPSBbXSk6CiAgICAgICAgc2VsZi5fbmFtZSA9IG5hbWUKICAg
+ICAgICBzZWxmLl9kZXBlbmRlbmNpZXMgPSBjb3B5LmNvcHkoZGVwZW5kZW5jaWVzKQogICAgICAg
+IHNlbGYuX3NvdXJjZSA9IHNvdXJjZQogICAgICAgIHNlbGYuX2J1aWxkID0gYnVpbGQKICAgICAg
+ICBzZWxmLl9idWlsdF9vbmNlID0gYnVpbHRfb25jZQogICAgICAgIHNlbGYuX2luc3RhbGxlZCA9
+IGluc3RhbGxlZAoKICAgIEBwcm9wZXJ0eQogICAgZGVmIGluc3RhbGxlZChzZWxmKToKICAgICAg
+ICByZXR1cm4gc2VsZi5faW5zdGFsbGVkCiAgICBAaW5zdGFsbGVkLnNldHRlcgogICAgZGVmIGlu
+c3RhbGxlZChzZWxmLCB2YWx1ZSk6CiAgICAgICAgc2VsZi5faW5zdGFsbGVkID0gY29weS5jb3B5
+KHZhbHVlKQoKICAgIGRlZiBfZGlyZWN0b3J5KHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9u
+YW1lCgogICAgZGVmIF9kb19kb3dubG9hZChzZWxmLCBlbnYsIHNvdXJjZSwgbmFtZSk6CiAgICAg
+ICAgZW52LnN0YXJ0X3NvdXJjZShuYW1lKQogICAgICAgIGlmIG9zLnBhdGguaXNkaXIoZW52LnNy
+Y2Rpcik6CiAgICAgICAgICAgIGVudi5lbmRfc291cmNlKCkKICAgICAgICBlbHNlOgogICAgICAg
+ICAgICB0cnk6CiAgICAgICAgICAgICAgICBzb3VyY2UuZG93bmxvYWQoZW52KQogICAgICAgICAg
+ICBmaW5hbGx5OgogICAgICAgICAgICAgICAgZW52LmVuZF9zb3VyY2UoKQogICAgICAgIGZvciBj
+aGlsZCwgY2hpbGRfbmFtZSBpbiBzb3VyY2UuY2hpbGRyZW4oKToKICAgICAgICAgICAgc2VsZi5f
+ZG9fZG93bmxvYWQoZW52LCBjaGlsZCwgb3MucGF0aC5qb2luKG5hbWUsIGNoaWxkX25hbWUpKQoK
+ICAgIGRlZiBkb3dubG9hZChzZWxmLCBlbnYpOgogICAgICAgIHRyeToKICAgICAgICAgICAgc2Vs
+Zi5fZG9fZG93bmxvYWQoZW52LCBzZWxmLl9zb3VyY2UsIHNlbGYuX25hbWUpCiAgICAgICAgICAg
+IHJldHVybiBUcnVlCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBpbXBvcnQgVXRpbHMKICAg
+ICAgICAgICAgVXRpbHMucHJpbnRfYmFja3RyYWNlKCkKICAgICAgICAgICAgcmV0dXJuIEZhbHNl
+CgoKICAgIGRlZiBfZG9fdXBkYXRlKHNlbGYsIGVudiwgc291cmNlLCBuYW1lKToKICAgICAgICBl
+bnYuc3RhcnRfc291cmNlKG5hbWUpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBzb3VyY2UudXBk
+YXRlKGVudikKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBlbnYuZW5kX3NvdXJjZSgpCiAg
+ICAgICAgZm9yIGNoaWxkLCBjaGlsZF9uYW1lIGluIHNvdXJjZS5jaGlsZHJlbigpOgogICAgICAg
+ICAgICBzZWxmLl9kb191cGRhdGUoZW52LCBjaGlsZCwgb3MucGF0aC5qb2luKG5hbWUsIGNoaWxk
+X25hbWUpKQoKICAgIGRlZiB1cGRhdGUoc2VsZiwgZW52KToKICAgICAgICB0cnk6CiAgICAgICAg
+ICAgIHNlbGYuX2RvX3VwZGF0ZShlbnYsIHNlbGYuX3NvdXJjZSwgc2VsZi5fbmFtZSkKICAgICAg
+ICAgICAgcmV0dXJuIFRydWUKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIGltcG9ydCBVdGls
+cwogICAgICAgICAgICBVdGlscy5wcmludF9iYWNrdHJhY2UoKQogICAgICAgICAgICByZXR1cm4g
+RmFsc2UKCiAgICBkZWYgdW5pbnN0YWxsKHNlbGYsIGVudik6CiAgICAgICAgIyBkZWxldGUgaW5z
+dGFsbGVkIGZpbGVzCiAgICAgICAgZm9yIGluc3RhbGxlZCBpbiBzZWxmLl9pbnN0YWxsZWQ6CiAg
+ICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9zLnJlbW92ZShpbnN0YWxsZWQpCiAgICAg
+ICAgICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgICMgZGVs
+ZXRlIGRpcmVjdG9yaWVzIHdoZXJlIGZpbGVzIHdlcmUgaW5zdGFsbGVkIGlmIHRoZXkgYXJlIGVt
+cHR5CiAgICAgICAgZGlycyA9IFtvcy5wYXRoLmRpcm5hbWUoaW5zdGFsbGVkKSBmb3IgaW5zdGFs
+bGVkIGluIHNlbGYuX2luc3RhbGxlZF0KICAgICAgICBkZWYgdW5pcShzZXEpOgogICAgICAgICAg
+ICBrZXlzID0ge30KICAgICAgICAgICAgZm9yIGUgaW4gc2VxOgogICAgICAgICAgICAgICAga2V5
+c1tlXSA9IDEKICAgICAgICAgICAgcmV0dXJuIGtleXMua2V5cygpCiAgICAgICAgZm9yIGQgaW4g
+dW5pcShkaXJzKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb3MucmVtb3ZlZGly
+cyhkKQogICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MKICAg
+ICAgICBzZWxmLl9pbnN0YWxsZWQgPSBbXQoKICAgIGRlZiBidWlsZChzZWxmLCBlbnYsIGpvYnMp
+OgogICAgICAgIHNlbGYudW5pbnN0YWxsKGVudikKICAgICAgICAjIGRlbGV0ZSBpbiBjYXNlIHRo
+aXMgaXMgYSBuZXcgYnVpbGQgY29uZmlndXJhdGlvbgogICAgICAgICMgYW5kIHRoZXJlIGFyZSBv
+bGQgZmlsZXMgYXJvdW5kCiAgICAgICAgaWYgbm90IHNlbGYuX2J1aWx0X29uY2U6CiAgICAgICAg
+ICAgIHNlbGYuY2xlYW4oZW52KQogICAgICAgICMgc2V0dXAgdGhlIG1vbml0b3IKICAgICAgICBt
+b25pdG9yID0gRmlsZXN5c3RlbU1vbml0b3IoZW52Lmluc3RhbGxkaXIpCiAgICAgICAgbW9uaXRv
+ci5zdGFydCgpCgogICAgICAgIGVudi5zdGFydF9idWlsZChzZWxmLl9uYW1lLCAKICAgICAgICAg
+ICAgICAgICAgICAgICAgc2VsZi5fYnVpbGQuc3VwcG9ydHNfb2JqZGlyKQogICAgICAgIGlmIG5v
+dCBvcy5wYXRoLmlzZGlyKGVudi5pbnN0YWxsZGlyKToKICAgICAgICAgICAgb3MubWtkaXIoZW52
+Lmluc3RhbGxkaXIpCiAgICAgICAgaWYgc2VsZi5fYnVpbGQuc3VwcG9ydHNfb2JqZGlyIGFuZCBu
+b3Qgb3MucGF0aC5pc2RpcihlbnYub2JqZGlyKToKICAgICAgICAgICAgb3MubWtkaXIoZW52Lm9i
+amRpcikKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBzZWxmLl9idWlsZC5idWlsZChlbnYsIGpv
+YnMpCiAgICAgICAgICAgIHNlbGYuX2luc3RhbGxlZCA9IG1vbml0b3IuZW5kKCkKICAgICAgICAg
+ICAgZW52LmVuZF9idWlsZCgpCiAgICAgICAgICAgIHNlbGYuX2J1aWx0X29uY2UgPSBUcnVlCiAg
+ICAgICAgICAgIHJldHVybiBUcnVlCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLl9p
+bnN0YWxsZWQgPSBtb25pdG9yLmVuZCgpCiAgICAgICAgICAgIGVudi5lbmRfYnVpbGQoKQogICAg
+ICAgICAgICBpbXBvcnQgVXRpbHMKICAgICAgICAgICAgVXRpbHMucHJpbnRfYmFja3RyYWNlKCkK
+ICAgICAgICAgICAgcmV0dXJuIEZhbHNlCgogICAgZGVmIGNoZWNrX2J1aWxkX3ZlcnNpb24oc2Vs
+ZiwgZW52KToKICAgICAgICBlbnYuc3RhcnRfYnVpbGQoc2VsZi5fbmFtZSwgCiAgICAgICAgICAg
+ICAgICAgICAgICAgIHNlbGYuX2J1aWxkLnN1cHBvcnRzX29iamRpcikKICAgICAgICBpZiBub3Qg
+b3MucGF0aC5pc2RpcihlbnYub2JqZGlyKSBvciBub3Qgb3MucGF0aC5pc2RpcihlbnYuc3JjZGly
+KToKICAgICAgICAgICAgcmV0dmFsID0gVHJ1ZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJl
+dHZhbCA9IHNlbGYuX2J1aWxkLmNoZWNrX3ZlcnNpb24oZW52KQogICAgICAgIGVudi5lbmRfYnVp
+bGQoKQogICAgICAgIHJldHVybiByZXR2YWwKCiAgICBkZWYgaXNfZG93bmxvYWRlZChzZWxmLCBl
+bnYpOgogICAgICAgIGVudi5zdGFydF9zb3VyY2Uoc2VsZi5fbmFtZSkKICAgICAgICByZXR2YWwg
+PSBvcy5wYXRoLmlzZGlyKGVudi5zcmNkaXIpCiAgICAgICAgZW52LmVuZF9zb3VyY2UoKQogICAg
+ICAgIHJldHVybiByZXR2YWwKCiAgICBkZWYgY2hlY2tfc291cmNlX3ZlcnNpb24oc2VsZiwgZW52
+KToKICAgICAgICBlbnYuc3RhcnRfc291cmNlKHNlbGYuX25hbWUpCiAgICAgICAgcmV0dmFsID0g
+c2VsZi5fc291cmNlLmNoZWNrX3ZlcnNpb24oZW52KQogICAgICAgIGVudi5lbmRfc291cmNlKCkK
+ICAgICAgICByZXR1cm4gcmV0dmFsCgoKICAgIGRlZiB1cGRhdGVfbGlicGF0aChzZWxmLCBlbnYp
+OgogICAgICAgIGVudi5zdGFydF9idWlsZChzZWxmLl9uYW1lLCAKICAgICAgICAgICAgICAgICAg
+ICAgICAgc2VsZi5fYnVpbGQuc3VwcG9ydHNfb2JqZGlyKQogICAgICAgIGVudi5hZGRfbGlicGF0
+aHMoc2VsZi5fYnVpbGQubGlicGF0aHMpCiAgICAgICAgZW52LmVuZF9idWlsZCgpCgogICAgZGVm
+IGNsZWFuKHNlbGYsIGVudik6CiAgICAgICAgZW52LnN0YXJ0X2J1aWxkKHNlbGYuX25hbWUsIAog
+ICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9idWlsZC5zdXBwb3J0c19vYmpkaXIpCiAgICAg
+ICAgaWYgbm90IG9zLnBhdGguaXNkaXIoZW52Lm9iamRpcikgb3Igbm90IG9zLnBhdGguaXNkaXIo
+ZW52LnNyY2Rpcik6CiAgICAgICAgICAgIGVudi5lbmRfYnVpbGQoKQogICAgICAgICAgICByZXR1
+cm4KICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuX2J1aWxkLmNsZWFuKGVudikKICAgICAg
+ICAgICAgZW52LmVuZF9idWlsZCgpCiAgICAgICAgICAgIHNlbGYuX2J1aWx0X29uY2UgPSBGYWxz
+ZQogICAgICAgICAgICByZXR1cm4gVHJ1ZQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgZW52
+LmVuZF9idWlsZCgpCiAgICAgICAgICAgIGltcG9ydCBVdGlscwogICAgICAgICAgICBVdGlscy5w
+cmludF9iYWNrdHJhY2UoKQogICAgICAgICAgICByZXR1cm4gRmFsc2UKCiAgICBkZWYgaXNfYnVp
+bHRfb25jZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fYnVpbHRfb25jZQogICAgZGVmIGdl
+dF9zb3VyY2Uoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX3NvdXJjZQogICAgZGVmIGdldF9i
+dWlsZChzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fYnVpbGQKICAgIGRlZiBuYW1lKHNlbGYp
+OgogICAgICAgIHJldHVybiBzZWxmLl9uYW1lCiAgICBkZWYgZGVwZW5kZW5jaWVzKHNlbGYpOgog
+ICAgICAgIHJldHVybiBzZWxmLl9kZXBlbmRlbmNpZXMKUEsDBBQAAAAAALtJYT/0XvzRzD0AAMw9
+AAAVAAAAYmFrZS9Db25maWd1cmF0aW9uLnB5ZnJvbSBNb2R1bGUgaW1wb3J0IE1vZHVsZSxNb2R1
+bGVEZXBlbmRlbmN5CmZyb20gTW9kdWxlU291cmNlIGltcG9ydCBNb2R1bGVTb3VyY2UsSW5saW5l
+TW9kdWxlU291cmNlCmZyb20gTW9kdWxlQnVpbGQgaW1wb3J0IE1vZHVsZUJ1aWxkLElubGluZU1v
+ZHVsZUJ1aWxkCmltcG9ydCB4bWwuZXRyZWUuRWxlbWVudFRyZWUgYXMgRVQKZnJvbSBFeGNlcHRp
+b25zIGltcG9ydCBNZXRhZGF0YUVycm9yCmltcG9ydCBvcwppbXBvcnQgc3lzCgpjbGFzcyBNZXRh
+ZGF0YUZpbGU6CiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW5hbWUsIGg9JycpOgogICAgICAg
+IGltcG9ydCBvcwogICAgICAgIHNlbGYuX2ZpbGVuYW1lID0gb3MucGF0aC5yZWFscGF0aChmaWxl
+bmFtZSkKICAgICAgICBzZWxmLl9oID0gaAogICAgZGVmIGZpbGVuYW1lKHNlbGYpOgogICAgICAg
+IHJldHVybiBzZWxmLl9maWxlbmFtZQogICAgZGVmIGgoc2VsZik6CiAgICAgICAgIGltcG9ydCBo
+YXNobGliCiAgICAgICAgIG0gPSBoYXNobGliLm1kNSgpCiAgICAgICAgIHRyeToKICAgICAgICAg
+ICAgIGYgPSBvcGVuKHNlbGYuX2ZpbGVuYW1lKQogICAgICAgICAgICAgbS51cGRhdGUoZi5yZWFk
+KCkpCiAgICAgICAgICAgICBmLmNsb3NlKCkKICAgICAgICAgICAgIHJldHVybiBtLmhleGRpZ2Vz
+dCgpCiAgICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgIHJldHVybiAnJwogICAgZGVmIGlzX2hh
+c2hfb2soc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuaCgpID09IHNlbGYuX2gKCmNsYXNzIFBy
+ZWRlZmluZWRDb25maWd1cmF0aW9uOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIGVuYWJs
+ZSwgZGlzYWJsZSwgdmFyaWFibGVzX3NldCwgdmFyaWFibGVzX2FwcGVuZCwKICAgICAgICAgICAg
+ICAgICBkaXJlY3Rvcmllcyk6CiAgICAgICAgc2VsZi5uYW1lID0gbmFtZQogICAgICAgIHNlbGYu
+ZW5hYmxlID0gZW5hYmxlCiAgICAgICAgc2VsZi5kaXNhYmxlID0gZGlzYWJsZQogICAgICAgIHNl
+bGYudmFyaWFibGVzX3NldCA9IHZhcmlhYmxlc19zZXQKICAgICAgICBzZWxmLnZhcmlhYmxlc19h
+cHBlbmQgPSB2YXJpYWJsZXNfYXBwZW5kCiAgICAgICAgc2VsZi5kaXJlY3RvcmllcyA9IGRpcmVj
+dG9yaWVzCiAgICAgICAgCgpjbGFzcyBDb25maWd1cmF0aW9uOgogICAgZGVmIF9faW5pdF9fKHNl
+bGYsIGJha2VmaWxlLCByZWxhdGl2ZV9kaXJlY3Rvcnlfcm9vdCA9IE5vbmUpOgogICAgICAgIHNl
+bGYuX2VuYWJsZWQgPSBbXQogICAgICAgIHNlbGYuX2Rpc2FibGVkID0gW10KICAgICAgICBzZWxm
+Ll9tb2R1bGVzID0gW10KICAgICAgICBzZWxmLl9pbnN0YWxsZGlyID0gTm9uZQogICAgICAgIHNl
+bGYuX29iamRpciA9IE5vbmUKICAgICAgICBzZWxmLl9zb3VyY2VkaXIgPSBOb25lCiAgICAgICAg
+c2VsZi5fbWV0YWRhdGFfZmlsZSA9IE5vbmUKICAgICAgICBzZWxmLl9iYWtlZmlsZSA9IG9zLnBh
+dGguYWJzcGF0aChiYWtlZmlsZSkKICAgICAgICBpZiByZWxhdGl2ZV9kaXJlY3Rvcnlfcm9vdCBp
+cyBOb25lOgogICAgICAgICAgICBzZWxmLl9yZWxhdGl2ZV9kaXJlY3Rvcnlfcm9vdCA9IG9zLnBh
+dGgucmVscGF0aChvcy5nZXRjd2QoKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zLnBhdGguZGlybmFtZShzZWxmLl9iYWtlZmls
+ZSkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5fcmVsYXRpdmVfZGlyZWN0b3J5X3Jv
+b3QgPSByZWxhdGl2ZV9kaXJlY3Rvcnlfcm9vdAoKICAgIGRlZiByZWFkX21ldGFkYXRhKHNlbGYs
+IGZpbGVuYW1lKToKICAgICAgICBpZiBub3Qgb3MucGF0aC5leGlzdHMoZmlsZW5hbWUpOgogICAg
+ICAgICAgICBzZWxmLl9lcnJvcignQ291bGQgbm90IGZpbmQgIiVzIicgJSBmaWxlbmFtZSkKICAg
+ICAgICBzZWxmLl9tZXRhZGF0YV9maWxlID0gTWV0YWRhdGFGaWxlKGZpbGVuYW1lKQogICAgICAg
+IGV0ID0gRVQucGFyc2UoZmlsZW5hbWUpCiAgICAgICAgc2VsZi5fcmVhZF9tZXRhZGF0YShldCkK
+ICAgIGRlZiByZWFkX3ByZWRlZmluZWQoc2VsZiwgZmlsZW5hbWUpOgogICAgICAgIGV0ID0gRVQu
+cGFyc2UoZmlsZW5hbWUpCiAgICAgICAgcHJlZGVmaW5lZCA9IFtdCiAgICAgICAgZm9yIHByZWRf
+bm9kZSBpbiBldC5nZXRyb290KCkuZmluZGFsbCgncHJlZGVmaW5lZCcpOgogICAgICAgICAgICBu
+YW1lID0gcHJlZF9ub2RlLmdldCgnbmFtZScsIE5vbmUpCiAgICAgICAgICAgIGlmIG5vdCBuYW1l
+OgogICAgICAgICAgICAgICAgc2VsZi5fZXJyb3IoJzxwcmVkZWZpbmVkPiBtdXN0IGRlZmluZSBh
+ICJuYW1lIiBhdHRyaWJ1dGUuJykKICAgICAgICAgICAgZW5hYmxlID0gW10KICAgICAgICAgICAg
+Zm9yIGVuYWJsZV9ub2RlIGluIHByZWRfbm9kZS5maW5kYWxsKCdlbmFibGUnKToKICAgICAgICAg
+ICAgICAgIGVuYWJsZV9uYW1lID0gZW5hYmxlX25vZGUuZ2V0KCduYW1lJywgTm9uZSkKICAgICAg
+ICAgICAgICAgIGlmIG5vdCBlbmFibGVfbmFtZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9l
+cnJvcignPGVuYWJsZT4gbXVzdCBkZWZpbmUgYSAibmFtZSIgYXR0cmlidXRlLicpCiAgICAgICAg
+ICAgICAgICBlbmFibGUuYXBwZW5kKGVuYWJsZV9uYW1lKQogICAgICAgICAgICBkaXNhYmxlID0g
+W10KICAgICAgICAgICAgZm9yIGRpc2FibGVfbm9kZSBpbiBwcmVkX25vZGUuZmluZGFsbCgnZGlz
+YWJsZScpOgogICAgICAgICAgICAgICAgZGlzYWJsZV9uYW1lID0gZGlzYWJsZV9ub2RlLmdldCgn
+bmFtZScsIE5vbmUpCiAgICAgICAgICAgICAgICBpZiBub3QgZGlzYWJsZV9uYW1lOgogICAgICAg
+ICAgICAgICAgICAgIHNlbGYuX2Vycm9yKCc8ZGlzYWJsZT4gbXVzdCBkZWZpbmUgYSAibmFtZSIg
+YXR0cmlidXRlLicpCiAgICAgICAgICAgICAgICBkaXNhYmxlLmFwcGVuZChkaXNhYmxlX25hbWUp
+CiAgICAgICAgICAgIHZhcmlhYmxlc19zZXQgPSBbXQogICAgICAgICAgICBmb3Igc2V0X25vZGUg
+aW4gcHJlZF9ub2RlLmZpbmRhbGwoJ3NldCcpOgogICAgICAgICAgICAgICAgc2V0X25hbWUgPSBz
+ZXRfbm9kZS5nZXQoJ25hbWUnLCBOb25lKQogICAgICAgICAgICAgICAgc2V0X3ZhbHVlID0gc2V0
+X25vZGUuZ2V0KCd2YWx1ZScsIE5vbmUpCiAgICAgICAgICAgICAgICBzZXRfbW9kdWxlID0gc2V0
+X25vZGUuZ2V0KCdtb2R1bGUnLCBOb25lKQogICAgICAgICAgICAgICAgaWYgbm90IHNldF9uYW1l
+IG9yIG5vdCBzZXRfdmFsdWU6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZXJyb3IoJzxzZXQ+
+IG11c3QgZGVmaW5lIGEgIm5hbWUiIGFuZCBhICJ2YWx1ZSIgYXR0cmlidXRlLicpCiAgICAgICAg
+ICAgICAgICB2YXJpYWJsZXNfc2V0LmFwcGVuZCgoc2V0X21vZHVsZSwgc2V0X25hbWUsIHNldF92
+YWx1ZSkpCiAgICAgICAgICAgIHZhcmlhYmxlc19hcHBlbmQgPSBbXQogICAgICAgICAgICBmb3Ig
+YXBwZW5kX25vZGUgaW4gcHJlZF9ub2RlLmZpbmRhbGwoJ2FwcGVuZCcpOgogICAgICAgICAgICAg
+ICAgYXBwZW5kX25hbWUgPSBhcHBlbmRfbm9kZS5nZXQoJ25hbWUnLCBOb25lKQogICAgICAgICAg
+ICAgICAgYXBwZW5kX3ZhbHVlID0gYXBwZW5kX25vZGUuZ2V0KCd2YWx1ZScsIE5vbmUpCiAgICAg
+ICAgICAgICAgICBhcHBlbmRfbW9kdWxlID0gYXBwZW5kX25vZGUuZ2V0KCdtb2R1bGUnLCBOb25l
+KQogICAgICAgICAgICAgICAgaWYgbm90IGFwcGVuZF9uYW1lIG9yIG5vdCBhcHBlbmRfdmFsdWU6
+CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZXJyb3IoJzxhcHBlbmQ+IG11c3QgZGVmaW5lIGEg
+Im5hbWUiIGFuZCBhICJ2YWx1ZSIgYXR0cmlidXRlLicpCiAgICAgICAgICAgICAgICB2YXJpYWJs
+ZXNfYXBwZW5kLmFwcGVuZCgoYXBwZW5kX21vZHVsZSwgYXBwZW5kX25hbWUsIGFwcGVuZF92YWx1
+ZSkpCiAgICAgICAgICAgIGRpcmVjdG9yaWVzID0ge30KICAgICAgICAgICAgZm9yIGNvbmZpZ19u
+b2RlIGluIHByZWRfbm9kZS5maW5kYWxsKCdjb25maWd1cmF0aW9uJyk6CiAgICAgICAgICAgICAg
+ICBvYmpkaXIgPSBjb25maWdfbm9kZS5nZXQoJ29iamRpcicsIE5vbmUpCiAgICAgICAgICAgICAg
+ICBpbnN0YWxsZGlyID0gY29uZmlnX25vZGUuZ2V0KCdpbnN0YWxsZGlyJywgTm9uZSkKICAgICAg
+ICAgICAgICAgIHNvdXJjZWRpciA9IGNvbmZpZ19ub2RlLmdldCgnc291cmNlZGlyJywgTm9uZSkK
+ICAgICAgICAgICAgICAgIGlmIG9iamRpcjoKICAgICAgICAgICAgICAgICAgICBkaXJlY3Rvcmll
+c1snb2JqZGlyJ10gPSBvYmpkaXIKICAgICAgICAgICAgICAgIGlmIGluc3RhbGxkaXI6CiAgICAg
+ICAgICAgICAgICAgICAgZGlyZWN0b3JpZXNbJ2luc3RhbGxkaXInXSA9IGluc3RhbGxkaXIKICAg
+ICAgICAgICAgICAgIGlmIHNvdXJjZWRpcjoKICAgICAgICAgICAgICAgICAgICBkaXJlY3Rvcmll
+c1snc291cmNlZGlyJ10gPSBzb3VyY2VkaXIKICAgICAgICAgICAgcHJlZGVmaW5lZC5hcHBlbmQo
+UHJlZGVmaW5lZENvbmZpZ3VyYXRpb24obmFtZSwgZW5hYmxlLCBkaXNhYmxlLCAKICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzX3Nl
+dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+dmFyaWFibGVzX2FwcGVuZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgIGRpcmVjdG9yaWVzKSkKICAgICAgICByZXR1cm4gcHJlZGVmaW5lZAoK
+ICAgIGRlZiBfZXJyb3Ioc2VsZiwgc3RyaW5nKToKICAgICAgICByYWlzZSBFeGNlcHRpb24oc3Ry
+aW5nKQoKICAgIGRlZiBfY2hlY2tfbWFuZGF0b3J5X2F0dHJpYnV0ZXMoc2VsZiwgYXR0cmlidXRl
+X2Jhc2UsIG5vZGUsIHR5cGVfc3RyaW5nLCBtb2R1bGVfc3RyaW5nKToKICAgICAgICAjIGdldCBs
+aXN0IG9mIG5hbWVzIGluIDxhdHRyaWJ1dGUgbmFtZT0iIiB2YWx1ZT0iIj4gdGFncwogICAgICAg
+IGF0dHJpYnV0ZXNfcHJlc2VudCA9IFtjaGlsZC5nZXQoJ25hbWUnKSBmb3IgY2hpbGQgaW4gbm9k
+ZS5maW5kYWxsKCdhdHRyaWJ1dGUnKV0KICAgICAgICAjIGdldCBsaXN0IG9mIG5hbWVzIGluIDx0
+eXBlX3N0cmluZyBuYW1lPSJ2YWx1ZSI+IGF0dHJpYnV0ZXMKICAgICAgICBhdHRyaWJ1dGVzX3By
+ZXNlbnQgPSBhdHRyaWJ1dGVzX3ByZXNlbnQgKyBub2RlLmF0dHJpYi5rZXlzKCkKICAgICAgICBm
+b3IgYXR0cmlidXRlIGluIGF0dHJpYnV0ZV9iYXNlLmF0dHJpYnV0ZXMoKToKICAgICAgICAgICAg
+aWYgYXR0cmlidXRlLmlzX21hbmRhdG9yeSBhbmQgbm90IGF0dHJpYnV0ZS5uYW1lIGluIGF0dHJp
+YnV0ZXNfcHJlc2VudDoKICAgICAgICAgICAgICAgIHN5cy5zdGRlcnIud3JpdGUoJ0Vycm9yOiBt
+YW5kYXRvcnkgYXR0cmlidXRlICIlcyIgaXMgbWlzc2luZyBmcm9tICcKICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgJ21vZHVsZSAiJXMiIGluIG5vZGUgIiVzIlxuJyAlIChhdHRyaWJ1
+dGUubmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgbW9kdWxlX3N0cmluZywgCiAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZV9zdHJpbmcpKQog
+ICAgICAgICAgICAgICAgc3lzLmV4aXQoMSkKCiAgICBkZWYgX3JlYWRfYXR0cmlidXRlcyhzZWxm
+LCBvYmosIG5vZGUsIHR5cGVfc3RyaW5nLCBtb2R1bGVfc3RyaW5nKToKICAgICAgICAjIHJlYWQg
+PHR5cGVfc3RyaW5nPjxhdHRyaWJ1dGUgbmFtZT0iIiB2YWx1ZT0iIj48L3R5cGVfc3RyaW5nPiB0
+YWdzCiAgICAgICAgZm9yIGF0dHJpYnV0ZV9ub2RlIGluIG5vZGUuZmluZGFsbCgnYXR0cmlidXRl
+Jyk6CiAgICAgICAgICAgIGF0dHJfbmFtZSA9IGF0dHJpYnV0ZV9ub2RlLmdldCgnbmFtZScpCiAg
+ICAgICAgICAgIGF0dHJfdmFsdWUgPSBhdHRyaWJ1dGVfbm9kZS5nZXQoJ3ZhbHVlJywgTm9uZSkK
+ICAgICAgICAgICAgaWYgb2JqLmF0dHJpYnV0ZShhdHRyX25hbWUpIGlzIE5vbmU6CiAgICAgICAg
+ICAgICAgICBzeXMuc3RkZXJyLndyaXRlKCdFcnJvcjogYXR0cmlidXRlICIlcyIgaXMgbm90IHN1
+cHBvcnRlZCBieSAlcyBub2RlIG9mIHR5cGUgIiVzIlxuJyAlIAogICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAoYXR0cl9uYW1lLCB0eXBlX3N0cmluZywgbm9kZS5nZXQoJ3R5cGUnKSkp
+CiAgICAgICAgICAgICAgICBzeXMuZXhpdCgxKQogICAgICAgICAgICBvYmouYXR0cmlidXRlKGF0
+dHJfbmFtZSkudmFsdWUgPSBhdHRyX3ZhbHVlCiAgICAgICAgIyBhcyBhIGZhbGxiYWNrLCByZWFk
+IDx0eXBlX3N0cmluZyBuYW1lPSJ2YWx1ZSI+IGF0dHJpYnV0ZXMKICAgICAgICAjIG5vdGU6IHRo
+aXMgd2lsbCBub3QgZ2VuZXJhdGUgZXJyb3JzIHVwb24gaW52YWxpZCBhdHRyaWJ1dGUgbmFtZXMK
+ICAgICAgICAjIGJlY2F1c2UgY2VydGFpbiBraW5kcyBvZiA8Zm9vIG5hbWU9InZhbHVlIi8+IFhN
+TCBhdHRyaWJ1dGVzIGFyZQogICAgICAgICMgbm90IGhhbmRsZWQgYXMgYmFrZSBhdHRyaWJ1dGVz
+LgogICAgICAgIGZvciBhdHRyX25hbWUgaW4gbm9kZS5hdHRyaWIua2V5cygpOgogICAgICAgICAg
+ICBpZiBub3Qgb2JqLmF0dHJpYnV0ZShhdHRyX25hbWUpIGlzIE5vbmU6CiAgICAgICAgICAgICAg
+ICBvYmouYXR0cmlidXRlKGF0dHJfbmFtZSkudmFsdWUgPSBub2RlLmdldChhdHRyX25hbWUpCgog
+ICAgZGVmIF93cml0ZV9hdHRyaWJ1dGVzKHNlbGYsIGF0dHJpYnV0ZV9iYXNlLCBvYmpfbm9kZSk6
+CiAgICAgICAgIyBnZW5lcmF0ZSA8YXR0cmlidXRlIG5hbWU9IiIgdmFsdWU9IiIvPiB0YWdzCiAg
+ICAgICAgZm9yIGF0dHJpYnV0ZSBpbiBhdHRyaWJ1dGVfYmFzZS5hdHRyaWJ1dGVzKCk6CiAgICAg
+ICAgICAgIGlmIG5vdCBhdHRyaWJ1dGUudmFsdWUgaXMgTm9uZToKICAgICAgICAgICAgICAgIGF0
+dHJpYnV0ZV9ub2RlID0gRVQuRWxlbWVudCgnYXR0cmlidXRlJywgeyduYW1lJyA6IGF0dHJpYnV0
+ZS5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgJ3ZhbHVlJyA6IGF0dHJpYnV0ZS52YWx1ZX0pCiAgICAgICAgICAgICAgICBvYmpf
+bm9kZS5hcHBlbmQoYXR0cmlidXRlX25vZGUpCgogICAgZGVmIF9jcmVhdGVfb2JqX2Zyb21fbm9k
+ZShzZWxmLCBub2RlLCBjbGFzc0Jhc2UsIG5vZGVfc3RyaW5nLCBtb2R1bGVfbmFtZSk6CiAgICAg
+ICAgIyByZWFkIDxub2RlX3N0cmluZyB0eXBlPSIiPiB0YWc6IGhhbmRsZSB0eXBlPSJpbmxpbmUi
+IHNwZWNpYWxseSBieQogICAgICAgICMgbG9va2luZyB1cCBhIGNoaWxkIG5vZGUgPGNvZGU+PC9j
+b2RlPgogICAgICAgIGlmIG5vZGUuZ2V0KCd0eXBlJykgPT0gJ2lubGluZSc6CiAgICAgICAgICAg
+IGNvZGVfbm9kZSA9IG5vZGUuZmluZCgnY29kZScpCiAgICAgICAgICAgIGlmIG5vZGUgaXMgTm9u
+ZToKICAgICAgICAgICAgICAgIHN5cy5zdGRlcnIud3JpdGUoJ0Vycm9yOiBubyBjb2RlIHRhZyBp
+biBpbmxpbmUgbW9kdWxlXG4nKQogICAgICAgICAgICAgICAgc3lzLmV4aXQoMSkKICAgICAgICAg
+ICAgY2xhc3NuYW1lID0gbm9kZS5nZXQoJ2NsYXNzbmFtZScpCiAgICAgICAgICAgIGltcG9ydCBj
+b2Rlb3AKICAgICAgICAgICAgZXhlYyBjb2RlX25vZGUudGV4dCBpbiBnbG9iYWxzKCksIGxvY2Fs
+cygpCiAgICAgICAgICAgIG9iaiA9IGV2YWwoY2xhc3NuYW1lICsgJygpJykKICAgICAgICAgICAg
+b2JqLl9faGlkZGVuX3NvdXJjZV9jb2RlID0gY29kZV9ub2RlLnRleHQKICAgICAgICBlbHNlOgog
+ICAgICAgICAgICBvYmogPSBjbGFzc0Jhc2UuY3JlYXRlKG5vZGUuZ2V0KCd0eXBlJykpCgogICAg
+ICAgIHNlbGYuX2NoZWNrX21hbmRhdG9yeV9hdHRyaWJ1dGVzKG9iaiwgbm9kZSwgbm9kZV9zdHJp
+bmcsIG1vZHVsZV9uYW1lKQogICAgICAgIHNlbGYuX3JlYWRfYXR0cmlidXRlcyhvYmosIG5vZGUs
+IG5vZGVfc3RyaW5nLCBtb2R1bGVfbmFtZSkKICAgICAgICAjIGlmIDx0eXBlX3N0cmluZz4gaGFz
+IDxjaGlsZD4gbm9kZXMsIGxvb2sgdGhlbSB1cC4KICAgICAgICBmb3IgY2hpbGRfbm9kZSBpbiBu
+b2RlLmZpbmRhbGwoJ2NoaWxkJyk6CiAgICAgICAgICAgIGNoaWxkX25hbWUgPSBjaGlsZF9ub2Rl
+LmdldCgnbmFtZScpCiAgICAgICAgICAgIGNoaWxkID0gc2VsZi5fY3JlYXRlX29ial9mcm9tX25v
+ZGUoY2hpbGRfbm9kZSwgY2xhc3NCYXNlLCAnY2hpbGQnLCBtb2R1bGVfbmFtZSkKICAgICAgICAg
+ICAgb2JqLmFkZF9jaGlsZChjaGlsZCwgY2hpbGRfbmFtZSkKCiAgICAgICAgcmV0dXJuIG9iagoK
+ICAgIGRlZiBfY3JlYXRlX25vZGVfZnJvbV9vYmooc2VsZiwgb2JqLCBub2RlX3N0cmluZyk6CiAg
+ICAgICAgaWYgb2JqLl9fY2xhc3NfXy5uYW1lKCkgPT0gJ2lubGluZSc6CiAgICAgICAgICAgIG5v
+ZGUgPSBFVC5FbGVtZW50KG5vZGVfc3RyaW5nLCB7J3R5cGUnIDogJ2lubGluZScsCiAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NsYXNzbmFtZScgOiBvYmouX19j
+bGFzc19fLl9fbmFtZV9ffSkKICAgICAgICAgICAgY29kZSA9IEVULkVsZW1lbnQoJ2NvZGUnKQog
+ICAgICAgICAgICBjb2RlLnRleHQgPSBvYmouX19oaWRkZW5fc291cmNlX2NvZGUKICAgICAgICAg
+ICAgbm9kZS5hcHBlbmQoY29kZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBub2RlID0gRVQu
+RWxlbWVudChub2RlX3N0cmluZywgeyd0eXBlJyA6IG9iai5fX2NsYXNzX18ubmFtZSgpfSkKCiAg
+ICAgICAgc2VsZi5fd3JpdGVfYXR0cmlidXRlcyhvYmosIG5vZGUpCgogICAgICAgIGZvciBjaGls
+ZCwgY2hpbGRfbmFtZSBpbiBvYmouY2hpbGRyZW4oKToKICAgICAgICAgICAgY2hpbGRfbm9kZSA9
+IHNlbGYuX2NyZWF0ZV9ub2RlX2Zyb21fb2JqKGNoaWxkLCAnY2hpbGQnKQogICAgICAgICAgICBj
+aGlsZF9ub2RlLmF0dHJpYlsnbmFtZSddID0gY2hpbGRfbmFtZQogICAgICAgICAgICBub2RlLmFw
+cGVuZChjaGlsZF9ub2RlKQoKICAgICAgICByZXR1cm4gbm9kZQoKICAgIGRlZiBfcmVhZF9saWJw
+YXRoKHNlbGYsIG5vZGUsIGJ1aWxkKToKICAgICAgICBmb3IgbGlicGF0aCBpbiBub2RlLmZpbmRh
+bGwoJ2FkZGxpYnBhdGgnKToKICAgICAgICAgICAgbG9jYXRpb24gPSBsaWJwYXRoLmdldCgnbG9j
+YXRpb24nLCBOb25lKQogICAgICAgICAgICBhc3NlcnQgbG9jYXRpb24gIT0gTm9uZQogICAgICAg
+ICAgICBidWlsZC5hZGRfbGlicGF0aChsb2NhdGlvbikKCiAgICBkZWYgX3dyaXRlX2xpYnBhdGgo
+c2VsZiwgbm9kZSwgYnVpbGQpOgogICAgICAgIGZvciBsaWJwYXRoIGluIGJ1aWxkLmxpYnBhdGhz
+OgogICAgICAgICAgICBsaWJwYXRoX25vZGUgPSBFVC5FbGVtZW50KCdhZGRsaWJwYXRoJywgeyds
+b2NhdGlvbicgOiBsaWJwYXRofSkKICAgICAgICAgICAgbm9kZS5hcHBlbmQobGlicGF0aF9ub2Rl
+KQoKICAgIGRlZiBfcmVhZF9pbnN0YWxsZWQoc2VsZiwgbm9kZSk6CiAgICAgICAgaW5zdGFsbGVk
+ID0gW10KICAgICAgICBmb3IgaW5zdGFsbGVkX25vZGUgaW4gbm9kZS5maW5kYWxsKCdpbnN0YWxs
+ZWQnKToKICAgICAgICAgICAgaW5zdGFsbGVkLmFwcGVuZChpbnN0YWxsZWRfbm9kZS5nZXQoJ3Zh
+bHVlJywgTm9uZSkpCiAgICAgICAgcmV0dXJuIGluc3RhbGxlZAoKICAgIGRlZiBfd3JpdGVfaW5z
+dGFsbGVkKHNlbGYsIG5vZGUsIGluc3RhbGxlZCk6CiAgICAgICAgZm9yIGluc3RhbGxlZCBpbiBp
+bnN0YWxsZWQ6CiAgICAgICAgICAgIGluc3RhbGxlZF9ub2RlID0gRVQuRWxlbWVudCgnaW5zdGFs
+bGVkJywgeyd2YWx1ZScgOiBpbnN0YWxsZWR9KQogICAgICAgICAgICBub2RlLmFwcGVuZChpbnN0
+YWxsZWRfbm9kZSkKCiAgICAKICAgIGRlZiBfcmVhZF9tZXRhZGF0YShzZWxmLCBldCk6CiAgICAg
+ICAgIyBmdW5jdGlvbiBkZXNpZ25lZCB0byBiZSBjYWxsZWQgb24gdHdvIGtpbmRzIG9mIHhtbCBm
+aWxlcy4KICAgICAgICBtb2R1bGVzID0gZXQuZmluZGFsbCgnbW9kdWxlcy9tb2R1bGUnKQogICAg
+ICAgIGZvciBtb2R1bGVfbm9kZSBpbiBtb2R1bGVzOgogICAgICAgICAgICBuYW1lID0gbW9kdWxl
+X25vZGUuZ2V0KCduYW1lJykKICAgICAgICAgICAgaW5zdGFsbGVkID0gc2VsZi5fcmVhZF9pbnN0
+YWxsZWQobW9kdWxlX25vZGUpCgogICAgICAgICAgICBzb3VyY2Vfbm9kZSA9IG1vZHVsZV9ub2Rl
+LmZpbmQoJ3NvdXJjZScpCiAgICAgICAgICAgIHNvdXJjZSA9IHNlbGYuX2NyZWF0ZV9vYmpfZnJv
+bV9ub2RlKHNvdXJjZV9ub2RlLCBNb2R1bGVTb3VyY2UsICdzb3VyY2UnLCBuYW1lKQoKICAgICAg
+ICAgICAgYnVpbGRfbm9kZSA9IG1vZHVsZV9ub2RlLmZpbmQoJ2J1aWxkJykKICAgICAgICAgICAg
+YnVpbGQgPSBzZWxmLl9jcmVhdGVfb2JqX2Zyb21fbm9kZShidWlsZF9ub2RlLCBNb2R1bGVCdWls
+ZCwgJ2J1aWxkJywgbmFtZSkKICAgICAgICAgICAgc2VsZi5fcmVhZF9saWJwYXRoKGJ1aWxkX25v
+ZGUsIGJ1aWxkKQoKICAgICAgICAgICAgZGVwZW5kZW5jaWVzID0gW10KICAgICAgICAgICAgZm9y
+IGRlcF9ub2RlIGluIG1vZHVsZV9ub2RlLmZpbmRhbGwoJ2RlcGVuZHNfb24nKToKICAgICAgICAg
+ICAgICAgIGRlcGVuZGVuY2llcy5hcHBlbmQoTW9kdWxlRGVwZW5kZW5jeShkZXBfbm9kZS5nZXQo
+J25hbWUnKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgYm9vbChkZXBfbm9kZS5nZXQoJ29wdGlvbmFsJywgJycpKSkpCiAgICAgICAgICAgIG1v
+ZHVsZSA9IE1vZHVsZShuYW1lLCBzb3VyY2UsIGJ1aWxkLCBkZXBlbmRlbmNpZXMgPSBkZXBlbmRl
+bmNpZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWlsdF9vbmNlID0gYm9vbChtb2R1
+bGVfbm9kZS5nZXQoJ2J1aWx0X29uY2UnLCAnJykpLAogICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgaW5zdGFsbGVkID0gaW5zdGFsbGVkKQogICAgICAgICAgICBzZWxmLl9tb2R1bGVzLmFwcGVu
+ZChtb2R1bGUpCgogICAgZGVmIF93cml0ZV9tZXRhZGF0YShzZWxmLCByb290KToKICAgICAgICBt
+b2R1bGVzX25vZGUgPSBFVC5FbGVtZW50KCdtb2R1bGVzJykKICAgICAgICByb290LmFwcGVuZCht
+b2R1bGVzX25vZGUpCiAgICAgICAgZm9yIG1vZHVsZSBpbiBzZWxmLl9tb2R1bGVzOgogICAgICAg
+ICAgICBtb2R1bGVfYXR0cnMgPSB7J25hbWUnIDogbW9kdWxlLm5hbWUoKX0KICAgICAgICAgICAg
+aWYgbW9kdWxlLmlzX2J1aWx0X29uY2UoKToKICAgICAgICAgICAgICAgIG1vZHVsZV9hdHRyc1sn
+YnVpbHRfb25jZSddID0gJ1RydWUnCiAgICAgICAgICAgIG1vZHVsZV9ub2RlID0gRVQuRWxlbWVu
+dCgnbW9kdWxlJywgbW9kdWxlX2F0dHJzKQogICAgICAgICAgICBzZWxmLl93cml0ZV9pbnN0YWxs
+ZWQobW9kdWxlX25vZGUsIG1vZHVsZS5pbnN0YWxsZWQpCgogICAgICAgICAgICBzb3VyY2Vfbm9k
+ZSA9IHNlbGYuX2NyZWF0ZV9ub2RlX2Zyb21fb2JqKG1vZHVsZS5nZXRfc291cmNlKCksICdzb3Vy
+Y2UnKQogICAgICAgICAgICBtb2R1bGVfbm9kZS5hcHBlbmQoc291cmNlX25vZGUpCgogICAgICAg
+ICAgICBidWlsZF9ub2RlID0gc2VsZi5fY3JlYXRlX25vZGVfZnJvbV9vYmoobW9kdWxlLmdldF9i
+dWlsZCgpLCAnYnVpbGQnKQogICAgICAgICAgICBtb2R1bGVfbm9kZS5hcHBlbmQoYnVpbGRfbm9k
+ZSkKICAgICAgICAgICAgc2VsZi5fd3JpdGVfbGlicGF0aChidWlsZF9ub2RlLCBtb2R1bGUuZ2V0
+X2J1aWxkKCkpCiAgICAgICAgICAgIAogICAgICAgICAgICBmb3IgZGVwZW5kZW5jeSBpbiBtb2R1
+bGUuZGVwZW5kZW5jaWVzKCk6CiAgICAgICAgICAgICAgICBhdHRycyA9IHsnbmFtZScgOiBkZXBl
+bmRlbmN5Lm5hbWUoKSB9CiAgICAgICAgICAgICAgICBpZiBkZXBlbmRlbmN5LmlzX29wdGlvbmFs
+KCk6CiAgICAgICAgICAgICAgICAgICAgYXR0cnNbJ29wdGlvbmFsJ10gPSAnVHJ1ZScKICAgICAg
+ICAgICAgICAgIGRlcF9ub2RlID0gRVQuRWxlbWVudCgnZGVwZW5kc19vbicsIGF0dHJzKQogICAg
+ICAgICAgICAgICAgbW9kdWxlX25vZGUuYXBwZW5kKGRlcF9ub2RlKQogICAgICAgICAgICBtb2R1
+bGVzX25vZGUuYXBwZW5kKG1vZHVsZV9ub2RlKQoKICAgIGRlZiB3cml0ZShzZWxmKToKICAgICAg
+ICByb290ID0gRVQuRWxlbWVudCgnY29uZmlndXJhdGlvbicsIAogICAgICAgICAgICAgICAgICAg
+ICAgICAgIHsnaW5zdGFsbGRpcicgOiBzZWxmLl9pbnN0YWxsZGlyLAogICAgICAgICAgICAgICAg
+ICAgICAgICAgICAnc291cmNlZGlyJyA6IHNlbGYuX3NvdXJjZWRpciwKICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgJ29iamRpcicgOiBzZWxmLl9vYmpkaXIsCiAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICdyZWxhdGl2ZV9kaXJlY3Rvcnlfcm9vdCcgOiBzZWxmLl9yZWxhdGl2ZV9kaXJlY3Rv
+cnlfcm9vdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2Jha2VmaWxlJyA6IHNlbGYuX2Jh
+a2VmaWxlfSkKICAgICAgICBpZiBub3Qgc2VsZi5fbWV0YWRhdGFfZmlsZSBpcyBOb25lOgogICAg
+ICAgICAgICBtZXRhZGF0YSA9IEVULkVsZW1lbnQoJ21ldGFkYXRhJywgeydmaWxlbmFtZScgOiBz
+ZWxmLl9tZXRhZGF0YV9maWxlLmZpbGVuYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgJ2hhc2gnIDogc2VsZi5fbWV0YWRhdGFfZmlsZS5oKCl9KQog
+ICAgICAgICAgICByb290LmFwcGVuZChtZXRhZGF0YSkKCiAgICAgICAgIyB3cml0ZSBlbmFibGVk
+IG5vZGVzCiAgICAgICAgZm9yIGUgaW4gc2VsZi5fZW5hYmxlZDoKICAgICAgICAgICAgZW5hYmxl
+X25vZGUgPSBFVC5FbGVtZW50KCdlbmFibGVkJywgeyduYW1lJyA6IGUubmFtZSgpfSkKICAgICAg
+ICAgICAgcm9vdC5hcHBlbmQoZW5hYmxlX25vZGUpCgogICAgICAgICMgd3JpdGUgZGlzYWJsZWQg
+bm9kZXMKICAgICAgICBmb3IgZSBpbiBzZWxmLl9kaXNhYmxlZDoKICAgICAgICAgICAgZGlzYWJs
+ZV9ub2RlID0gRVQuRWxlbWVudCgnZGlzYWJsZWQnLCB7J25hbWUnIDogZS5uYW1lKCl9KQogICAg
+ICAgICAgICByb290LmFwcGVuZChkaXNhYmxlX25vZGUpCgogICAgICAgIHNlbGYuX3dyaXRlX21l
+dGFkYXRhKHJvb3QpCiAgICAgICAgZXQgPSBFVC5FbGVtZW50VHJlZShlbGVtZW50PXJvb3QpCiAg
+ICAgICAgZXQud3JpdGUoc2VsZi5fYmFrZWZpbGUpCgogICAgZGVmIHJlYWQoc2VsZik6CiAgICAg
+ICAgZXQgPSBFVC5wYXJzZShzZWxmLl9iYWtlZmlsZSkKICAgICAgICBzZWxmLl9yZWFkX21ldGFk
+YXRhKGV0KQogICAgICAgIHJvb3QgPSBldC5nZXRyb290KCkKICAgICAgICBzZWxmLl9pbnN0YWxs
+ZGlyID0gcm9vdC5nZXQoJ2luc3RhbGxkaXInKQogICAgICAgIHNlbGYuX29iamRpciA9IHJvb3Qu
+Z2V0KCdvYmpkaXInKQogICAgICAgIHNlbGYuX3NvdXJjZWRpciA9IHJvb3QuZ2V0KCdzb3VyY2Vk
+aXInKQogICAgICAgIHNlbGYuX3JlbGF0aXZlX2RpcmVjdG9yeV9yb290ID0gcm9vdC5nZXQoJ3Jl
+bGF0aXZlX2RpcmVjdG9yeV9yb290JykKICAgICAgICBvcmlnaW5hbF9iYWtlZmlsZSA9IHJvb3Qu
+Z2V0KCdiYWtlZmlsZScpCiAgICAgICAgbWV0YWRhdGEgPSByb290LmZpbmQoJ21ldGFkYXRhJykK
+ICAgICAgICBzZWxmLl9tZXRhZGF0YV9maWxlID0gTWV0YWRhdGFGaWxlIChtZXRhZGF0YS5nZXQo
+J2ZpbGVuYW1lJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+aCA9IG1ldGFkYXRhLmdldCgnaGFzaCcpKQoKICAgICAgICAjIHJlYWQgd2hpY2ggbW9kdWxlcyBh
+cmUgZW5hYmxlZAogICAgICAgIG1vZHVsZXMgPSByb290LmZpbmRhbGwoJ2VuYWJsZWQnKQogICAg
+ICAgIGZvciBtb2R1bGUgaW4gbW9kdWxlczoKICAgICAgICAgICAgZW5hYmxlZCA9IHNlbGYubG9v
+a3VwKG1vZHVsZS5nZXQoJ25hbWUnKSkKICAgICAgICAgICAgc2VsZi5lbmFibGUoZW5hYmxlZCkK
+CiAgICAgICAgIyByZWFkIHdoaWNoIG1vZHVsZXMgYXJlIGRpc2FibGVkCiAgICAgICAgbW9kdWxl
+cyA9IHJvb3QuZmluZGFsbCgnZGlzYWJsZWQnKQogICAgICAgIGZvciBtb2R1bGUgaW4gbW9kdWxl
+czoKICAgICAgICAgICAgZGlzYWJsZWQgPSBzZWxmLmxvb2t1cChtb2R1bGUuZ2V0KCduYW1lJykp
+CiAgICAgICAgICAgIHNlbGYuZGlzYWJsZShkaXNhYmxlZCkKCiAgICAgICAgcmV0dXJuIHNlbGYu
+X21ldGFkYXRhX2ZpbGUuaXNfaGFzaF9vaygpIGFuZCBvcmlnaW5hbF9iYWtlZmlsZSA9PSBzZWxm
+Ll9iYWtlZmlsZQoKICAgIGRlZiBzZXRfaW5zdGFsbGRpcihzZWxmLCBpbnN0YWxsZGlyKToKICAg
+ICAgICBzZWxmLl9pbnN0YWxsZGlyID0gaW5zdGFsbGRpcgogICAgZGVmIGdldF9pbnN0YWxsZGly
+KHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9pbnN0YWxsZGlyCiAgICBkZWYgc2V0X29iamRp
+cihzZWxmLCBvYmpkaXIpOgogICAgICAgIHNlbGYuX29iamRpciA9IG9iamRpcgogICAgZGVmIGdl
+dF9vYmpkaXIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX29iamRpcgogICAgZGVmIHNldF9z
+b3VyY2VkaXIoc2VsZiwgc291cmNlZGlyKToKICAgICAgICBzZWxmLl9zb3VyY2VkaXIgPSBzb3Vy
+Y2VkaXIKICAgIGRlZiBnZXRfc291cmNlZGlyKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9z
+b3VyY2VkaXIKICAgIGRlZiBnZXRfcmVsYXRpdmVfZGlyZWN0b3J5X3Jvb3Qoc2VsZik6CiAgICAg
+ICAgcmV0dXJuIHNlbGYuX3JlbGF0aXZlX2RpcmVjdG9yeV9yb290CiAgICBkZWYgX2NvbXB1dGVf
+cGF0aChzZWxmLCBwKToKICAgICAgICBpZiBvcy5wYXRoLmlzYWJzKHApOgogICAgICAgICAgICBy
+ZXR1cm4gcAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRtcCA9IG9zLnBhdGguam9pbihvcy5w
+YXRoLmRpcm5hbWUoc2VsZi5fYmFrZWZpbGUpLCBzZWxmLl9yZWxhdGl2ZV9kaXJlY3Rvcnlfcm9v
+dCwgcCkKICAgICAgICAgICAgcmV0dXJuIG9zLnBhdGgubm9ybXBhdGgodG1wKQogICAgZGVmIGNv
+bXB1dGVfc291cmNlZGlyKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9jb21wdXRlX3BhdGgo
+c2VsZi5fc291cmNlZGlyKQogICAgZGVmIGNvbXB1dGVfaW5zdGFsbGRpcihzZWxmKToKICAgICAg
+ICByZXR1cm4gc2VsZi5fY29tcHV0ZV9wYXRoKHNlbGYuX2luc3RhbGxkaXIpCiAgICBkZWYgZW5h
+YmxlKHNlbGYsIG1vZHVsZSk6CiAgICAgICAgaWYgbW9kdWxlIGluIHNlbGYuX2Rpc2FibGVkOgog
+ICAgICAgICAgICBzZWxmLl9kaXNhYmxlZC5yZW1vdmUobW9kdWxlKQogICAgICAgIGVsc2U6CiAg
+ICAgICAgICAgIHNlbGYuX2VuYWJsZWQuYXBwZW5kKG1vZHVsZSkKICAgIGRlZiBkaXNhYmxlKHNl
+bGYsIG1vZHVsZSk6CiAgICAgICAgaWYgbW9kdWxlIGluIHNlbGYuX2VuYWJsZWQ6CiAgICAgICAg
+ICAgIHNlbGYuX2VuYWJsZWQucmVtb3ZlKG1vZHVsZSkKICAgICAgICBlbHNlOgogICAgICAgICAg
+ICBzZWxmLl9kaXNhYmxlZC5hcHBlbmQobW9kdWxlKQogICAgZGVmIGxvb2t1cChzZWxmLCBuYW1l
+KToKICAgICAgICBmb3IgbW9kdWxlIGluIHNlbGYuX21vZHVsZXM6CiAgICAgICAgICAgIGlmIG1v
+ZHVsZS5uYW1lKCkgPT0gbmFtZToKICAgICAgICAgICAgICAgIHJldHVybiBtb2R1bGUKICAgICAg
+ICByZXR1cm4gTm9uZQogICAgZGVmIGVuYWJsZWQoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYu
+X2VuYWJsZWQKICAgIGRlZiBkaXNhYmxlZChzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fZGlz
+YWJsZWQKICAgIGRlZiBtb2R1bGVzKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9tb2R1bGVz
+ClBLAwQUAAAAAAA4V64+tCqnBUYFAABGBQAAGQAAAGJha2UvRmlsZXN5c3RlbU1vbml0b3IucHlp
+bXBvcnQgb3MKCiMgVGhlIGlkZWEgaXMgdGhhdCB3ZSB3YW50IHRvIGltcGxlbWVudCBhIHZlcnNp
+b24gb2YgdGhpcyBjbGFzcwojIHRoYXQgdXNlcyB0aGUgT1MgbmF0aXZlIEZTIG1vbml0b3Jpbmcg
+QVBJLiBTb21lZGF5LCB3aWxsIGRvIHRoaXMKIyBidXQgdGhpcyBjb2RlIHdvcmtzIHdlbGwgYW55
+d2hlcmUuCgpjbGFzcyBGaWxlc3lzdGVtTW9uaXRvcjoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBk
+aXJuYW1lKToKICAgICAgICBzZWxmLl9maWxlcyA9IE5vbmUKICAgICAgICBzZWxmLl9kaXJuYW1l
+ID0gZGlybmFtZQogICAgZGVmIF9wYXJzZShzZWxmLCBkaXJuYW1lKToKICAgICAgICByZXN1bHQg
+PSBbXQogICAgICAgIGZvciByb290LCBkaXJzLCBmaWxlcyBpbiBvcy53YWxrKGRpcm5hbWUpOgog
+ICAgICAgICAgICByZXN1bHQuZXh0ZW5kKFtvcy5wYXRoLmpvaW4ocm9vdCwgZikgZm9yIGYgaW4g
+ZmlsZXNdKQogICAgICAgIHJlc3VsdC5zb3J0KCkKICAgICAgICByZXR1cm4gcmVzdWx0CiAgICBk
+ZWYgc3RhcnQoc2VsZik6CiAgICAgICAgc2VsZi5fZmlsZXMgPSBzZWxmLl9wYXJzZShzZWxmLl9k
+aXJuYW1lKQogICAgZGVmIF9za2lwX3VudGlsX2RpZmZlcmVudChzZWxmLCBhLCBhaSwgYiwgYmkp
+OgogICAgICAgIHdoaWxlIGFpIDwgbGVuKGEpIGFuZCBiaSA8IGxlbihiKSBhbmQgYVthaV0gPT0g
+YltiaV06CiAgICAgICAgICAgIGFpID0gYWkgKyAxCiAgICAgICAgICAgIGJpID0gYmkgKyAxCiAg
+ICAgICAgcmV0dXJuIChhaSxiaSkKICAgIGRlZiBfc2tpcF91bnRpbF9lcXVhbChzZWxmLCBmaWxl
+cywgaSwgdmFsdWUpOgogICAgICAgIHdoaWxlIGkgPCBsZW4oZmlsZXMpIGFuZCBmaWxlc1tpXSAh
+PSB2YWx1ZToKICAgICAgICAgICAgaSA9IGkgKyAxCiAgICAgICAgcmV0dXJuIGkKICAgIGRlZiBl
+bmQoc2VsZik6CiAgICAgICAgZmlsZXMgPSBzZWxmLl9wYXJzZShzZWxmLl9kaXJuYW1lKQogICAg
+ICAgIHJlc3VsdCA9IFtdCiAgICAgICAgaSA9IDAKICAgICAgICBqID0gMAogICAgICAgIHdoaWxl
+IGogPCBsZW4oZmlsZXMpOgogICAgICAgICAgICBpLCBqID0gc2VsZi5fc2tpcF91bnRpbF9kaWZm
+ZXJlbnQoc2VsZi5fZmlsZXMsIGksIGZpbGVzLCBqKQogICAgICAgICAgICBpZiBpICE9IGxlbihz
+ZWxmLl9maWxlcyk6CiAgICAgICAgICAgICAgICBrID0gc2VsZi5fc2tpcF91bnRpbF9lcXVhbChm
+aWxlcywgaiwgc2VsZi5fZmlsZXNbaV0pCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAg
+ICBrID0gbGVuKGZpbGVzKQogICAgICAgICAgICByZXN1bHQuZXh0ZW5kKGZpbGVzW2o6a10pCiAg
+ICAgICAgICAgIGogPSBrCiAgICAgICAgcmV0dXJuIHJlc3VsdApQSwMEFAAAAAAAemOuPq/eWEHj
+BQAA4wUAAA0AAABiYWtlL1V0aWxzLnB5aW1wb3J0IHN1YnByb2Nlc3MKZnJvbSBFeGNlcHRpb25z
+IGltcG9ydCBUYXNrRXJyb3IKaW1wb3J0IG9zCgpkZWYgcHJpbnRfYmFja3RyYWNlKCk6CiAgICBp
+bXBvcnQgc3lzCiAgICBpbXBvcnQgdHJhY2ViYWNrCiAgICB0cmFjZSA9ICIiCiAgICBleGNlcHRp
+b24gPSAiIgogICAgZXhjX2xpc3QgPSB0cmFjZWJhY2suZm9ybWF0X2V4Y2VwdGlvbl9vbmx5IChz
+eXMuZXhjX3R5cGUsIHN5cy5leGNfdmFsdWUpCiAgICBmb3IgZW50cnkgaW4gZXhjX2xpc3Q6CiAg
+ICAgICAgZXhjZXB0aW9uICs9IGVudHJ5CiAgICB0Yl9saXN0ID0gdHJhY2ViYWNrLmZvcm1hdF90
+YihzeXMuZXhjX2luZm8oKVsyXSkKICAgIGZvciBlbnRyeSBpbiB0Yl9saXN0OgogICAgICAgIHRy
+YWNlICs9IGVudHJ5CiAgICBzeXMuc3RkZXJyLndyaXRlKCIlc1xuJXMiICUgKGV4Y2VwdGlvbiwg
+dHJhY2UpKQoKY2xhc3MgTW9kdWxlQXR0cmlidXRlOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5h
+bWUsIHZhbHVlLCBoZWxwLCBtYW5kYXRvcnkpOgogICAgICAgIHNlbGYuX25hbWUgPSBuYW1lCiAg
+ICAgICAgc2VsZi52YWx1ZSA9IHZhbHVlCiAgICAgICAgc2VsZi5faGVscCA9IGhlbHAKICAgICAg
+ICBzZWxmLl9tYW5kYXRvcnkgPSBtYW5kYXRvcnkKICAgIEBwcm9wZXJ0eQogICAgZGVmIG5hbWUo
+c2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX25hbWUKICAgIEBwcm9wZXJ0eQogICAgZGVmIGhl
+bHAoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX2hlbHAKICAgIEBwcm9wZXJ0eQogICAgZGVm
+IGlzX21hbmRhdG9yeShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fbWFuZGF0b3J5CgpjbGFz
+cyBNb2R1bGVBdHRyaWJ1dGVCYXNlKG9iamVjdCk6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAg
+ICAgICAgc2VsZi5fYXR0cmlidXRlcyA9IGRpY3QoKQogICAgICAgIHNlbGYuX2NoaWxkcmVuID0g
+W10KICAgIGRlZiBjaGlsZHJlbihzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fY2hpbGRyZW4K
+ICAgIGRlZiBhZGRfY2hpbGQoc2VsZiwgY2hpbGQsIG5hbWUpOgogICAgICAgIHNlbGYuX2NoaWxk
+cmVuLmFwcGVuZChbY2hpbGQsIG5hbWVdKQogICAgZGVmIGFkZF9hdHRyaWJ1dGUoc2VsZiwgbmFt
+ZSwgdmFsdWUsIGhlbHAsIG1hbmRhdG9yeSA9IEZhbHNlKToKICAgICAgICBhc3NlcnQgbm90IHNl
+bGYuX2F0dHJpYnV0ZXMuaGFzX2tleShuYW1lKQogICAgICAgIHNlbGYuX2F0dHJpYnV0ZXNbbmFt
+ZV0gPSBNb2R1bGVBdHRyaWJ1dGUobmFtZSwgdmFsdWUsIGhlbHAsIG1hbmRhdG9yeSkKICAgIGRl
+ZiBhdHRyaWJ1dGVzKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9hdHRyaWJ1dGVzLnZhbHVl
+cygpCiAgICBkZWYgYXR0cmlidXRlKHNlbGYsIG5hbWUpOgogICAgICAgIGlmIG5vdCBzZWxmLl9h
+dHRyaWJ1dGVzLmhhc19rZXkobmFtZSk6CiAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAg
+ZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX2F0dHJpYnV0ZXNbbmFtZV0KClBLAwQUAAAA
+AABdma4+5oxWPnsIAAB7CAAAFAAAAGJha2UvTW9kdWxlTG9nZ2VyLnB5aW1wb3J0IHN5cwppbXBv
+cnQgb3MKZnJvbSBFeGNlcHRpb25zIGltcG9ydCBOb3RJbXBsZW1lbnRlZAoKY2xhc3MgTW9kdWxl
+TG9nZ2VyOgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYuX3ZlcmJvc2UgPSBO
+b25lCiAgICAgICAgc2VsZi5fY29tbWFuZF9maWxlID0gTm9uZQogICAgICAgIHNlbGYuX3N0ZF9m
+aWxlID0gTm9uZQogICAgZGVmIF91cGRhdGVfZmlsZShzZWxmLCBmKToKICAgICAgICBpZiBzZWxm
+Ll92ZXJib3NlID09IDA6CiAgICAgICAgICAgIHNlbGYuX2NvbW1hbmRfZmlsZSA9IG9wZW4ob3Mu
+ZGV2bnVsbCwgJ3cnKQogICAgICAgICAgICBzZWxmLl9zdGRfZmlsZSA9IG9wZW4ob3MuZGV2bnVs
+bCwgJ3cnKQogICAgICAgIGVsaWYgc2VsZi5fdmVyYm9zZSA9PSAxOgogICAgICAgICAgICBzZWxm
+Ll9jb21tYW5kX2ZpbGUgPSBmCiAgICAgICAgICAgIHNlbGYuX3N0ZF9maWxlID0gb3Blbihvcy5k
+ZXZudWxsLCAndycpCiAgICAgICAgZWxpZiBzZWxmLl92ZXJib3NlID09IDI6CiAgICAgICAgICAg
+IHNlbGYuX2NvbW1hbmRfZmlsZSA9IGYKICAgICAgICAgICAgc2VsZi5fc3RkX2ZpbGUgPSBmCiAg
+ICBkZWYgc2V0X3ZlcmJvc2Uoc2VsZiwgdmVyYm9zZSk6CiAgICAgICAgc2VsZi5fdmVyYm9zZSA9
+IHZlcmJvc2UgaWYgdmVyYm9zZSA8PSAyIGVsc2UgMgogICAgZGVmIHNldF9jdXJyZW50X21vZHVs
+ZShzZWxmLCBuYW1lKToKICAgICAgICByYWlzZSBOb3RJbXBsZW1lbnRlZCgpCiAgICBkZWYgY2xl
+YXJfY3VycmVudF9tb2R1bGUoc2VsZik6CiAgICAgICAgcmFpc2UgTm90SW1wbGVtZW50ZWQoKQog
+ICAgQHByb3BlcnR5CiAgICBkZWYgc3Rkb3V0KHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9z
+dGRfZmlsZQogICAgQHByb3BlcnR5CiAgICBkZWYgc3RkZXJyKHNlbGYpOgogICAgICAgIHJldHVy
+biBzZWxmLl9zdGRfZmlsZQogICAgQHByb3BlcnR5CiAgICBkZWYgY29tbWFuZHMoc2VsZik6CiAg
+ICAgICAgcmV0dXJuIHNlbGYuX2NvbW1hbmRfZmlsZQoKY2xhc3MgU3Rkb3V0TW9kdWxlTG9nZ2Vy
+KE1vZHVsZUxvZ2dlcik6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgTW9kdWxlTG9n
+Z2VyLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5fdXBkYXRlX2ZpbGUoc3lzLnN0ZG91dCkK
+ICAgIGRlZiBzZXRfY3VycmVudF9tb2R1bGUoc2VsZiwgbmFtZSk6CiAgICAgICAgc2VsZi5fdXBk
+YXRlX2ZpbGUoc3lzLnN0ZG91dCkKICAgIGRlZiBjbGVhcl9jdXJyZW50X21vZHVsZShzZWxmKToK
+ICAgICAgICBwYXNzCgpjbGFzcyBMb2dmaWxlTW9kdWxlTG9nZ2VyKE1vZHVsZUxvZ2dlcik6CiAg
+ICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW5hbWUpOgogICAgICAgIE1vZHVsZUxvZ2dlci5fX2lu
+aXRfXyhzZWxmKQogICAgICAgIHNlbGYuX2ZpbGUgPSBvcGVuKGZpbGVuYW1lLCAndycpCiAgICBk
+ZWYgc2V0X2N1cnJlbnRfbW9kdWxlKHNlbGYsIG5hbWUpOgogICAgICAgIHNlbGYuX3VwZGF0ZV9m
+aWxlKHNlbGYuX2ZpbGUpCiAgICBkZWYgY2xlYXJfY3VycmVudF9tb2R1bGUoc2VsZik6CiAgICAg
+ICAgcGFzcwoKY2xhc3MgTG9nZGlyTW9kdWxlTG9nZ2VyKE1vZHVsZUxvZ2dlcik6CiAgICBkZWYg
+X19pbml0X18oc2VsZiwgZGlybmFtZSk6CiAgICAgICAgaWYgbm90IG9zLnBhdGguaXNkaXIoZGly
+bmFtZSk6CiAgICAgICAgICAgIG9zLm1rZGlyKGRpcm5hbWUpCiAgICAgICAgc2VsZi5fZGlybmFt
+ZSA9IGRpcm5hbWUKICAgICAgICBzZWxmLl9maWxlID0gTm9uZQogICAgZGVmIHNldF9jdXJyZW50
+X21vZHVsZShzZWxmLCBuYW1lKToKICAgICAgICAjIFhYWDogd2Ugc2hvdWxkIGJlIGNoZWNraW5n
+IGZvciBvdGhlciByZXNlcnZlZCBjaGFyYWN0ZXJzCiAgICAgICAgaW1wb3J0IHJlCiAgICAgICAg
+ZmlsZW5hbWUgPSByZS5zdWIoJy8nLCAnXycsIG5hbWUpCiAgICAgICAgYXNzZXJ0IHNlbGYuX2Zp
+bGUgaXMgTm9uZQogICAgICAgIHNlbGYuX2ZpbGUgPSBvcGVuKG9zLnBhdGguam9pbihzZWxmLl9k
+aXJuYW1lLCBmaWxlbmFtZSArICcubG9nJyksICd3JykKICAgICAgICBzZWxmLl91cGRhdGVfZmls
+ZShzZWxmLl9maWxlKQogICAgZGVmIGNsZWFyX2N1cnJlbnRfbW9kdWxlKHNlbGYpOgogICAgICAg
+IHNlbGYuX2ZpbGUuY2xvc2UoKQogICAgICAgIHNlbGYuX2ZpbGUgPSBOb25lCgpQSwMEFAAAAAAA
+91SmPgPEPqg5AQAAOQEAABIAAABiYWtlL0V4Y2VwdGlvbnMucHljbGFzcyBUYXNrRXJyb3I6CiAg
+ICBkZWYgX19pbml0X18oc2VsZiwgcmVhc29uID0gJycpOgogICAgICAgIHNlbGYuX3JlYXNvbiA9
+IHJlYXNvbgogICAgICAgIHJldHVybgoKY2xhc3MgTWV0YWRhdGFFcnJvcjoKICAgIGRlZiBfX2lu
+aXRfXyhzZWxmLCByZWFzb24gPSAnJyk6CiAgICAgICAgc2VsZi5fcmVhc29uID0gcmVhc29uCiAg
+ICAgICAgcmV0dXJuCiAgICBkZWYgcmVhc29uKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9y
+ZWFzb24KCmNsYXNzIE5vdEltcGxlbWVudGVkOgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAg
+ICAgIHBhc3MKUEsDBBQAAAAAAL1TYT9nBakppgAAAKYAAAAQAAAAYmFrZS9fX2luaXRfXy5weWZy
+b20gRGVwZW5kZW5jaWVzIGltcG9ydCBEZXBlbmRlbmNpZXMsRGVwZW5kZW5jeVVubWV0LEN5Y2xl
+RGV0ZWN0ZWQKZnJvbSBCYWtlIGltcG9ydCBCYWtlCmZyb20gRXhjZXB0aW9ucyBpbXBvcnQgTWV0
+YWRhdGFFcnJvcgpkZWYgbWFpbihhcmdzKToKICAgIEJha2UoKS5tYWluKGFyZ3MpCgpQSwMEFAAA
+AAAAqVRhP6lyYo0JdwAACXcAAAwAAABiYWtlL0Jha2UucHlmcm9tIENvbmZpZ3VyYXRpb24gaW1w
+b3J0IENvbmZpZ3VyYXRpb24KZnJvbSBNb2R1bGVFbnZpcm9ubWVudCBpbXBvcnQgTW9kdWxlRW52
+aXJvbm1lbnQKZnJvbSBNb2R1bGVMb2dnZXIgaW1wb3J0IFN0ZG91dE1vZHVsZUxvZ2dlcixMb2dm
+aWxlTW9kdWxlTG9nZ2VyLExvZ2Rpck1vZHVsZUxvZ2dlcgpmcm9tIG9wdHBhcnNlIGltcG9ydCBP
+cHRpb25QYXJzZXIKZnJvbSBEZXBlbmRlbmNpZXMgaW1wb3J0IERlcGVuZGVuY2llcyxEZXBlbmRl
+bmN5VW5tZXQKZnJvbSBFeGNlcHRpb25zIGltcG9ydCBNZXRhZGF0YUVycm9yCmltcG9ydCBzeXMK
+CmNsYXNzIE15T3B0aW9uUGFyc2VyKE9wdGlvblBhcnNlcik6CiAgICBkZWYgZm9ybWF0X2Rlc2Ny
+aXB0aW9uKHNlbGYsIGZvcm1hdHRlcik6CiAgICAgICAgaW1wb3J0IG9zCiAgICAgICAgaW1wb3J0
+IHN5cwogICAgICAgIHJldHVybiBzZWxmLmRlc2NyaXB0aW9uICUgb3MucGF0aC5iYXNlbmFtZShz
+eXMuYXJndlswXSkKICAgICAgICAKCmNsYXNzIEJha2U6CiAgICBkZWYgX19pbml0X18oc2VsZik6
+CiAgICAgICAgcGFzcwoKICAgIGRlZiBfZXJyb3Ioc2VsZiwgc3RyaW5nKToKICAgICAgICByYWlz
+ZSBFeGNlcHRpb24oJ0Vycm9yOiAlcycgJSBzdHJpbmcpCgogICAgZGVmIF9yZWNvbmZpZ3VyZShz
+ZWxmLGNvbmZpZyxhcmdzKToKICAgICAgICBwYXJzZXIgPSBPcHRpb25QYXJzZXIodXNhZ2UgPSAn
+dXNhZ2U6ICVwcm9nIHJlY29uZmlndXJlIFtvcHRpb25zXScpCiAgICAgICAgc2VsZi5fZW5hYmxl
+X2Rpc2FibGVfb3B0aW9ucyhwYXJzZXIpCiAgICAgICAgcGFyc2VyLmFkZF9vcHRpb24oIi1jIiwg
+Ii0tY29uZmZpbGUiLCBhY3Rpb249InN0b3JlIiwgdHlwZT0ic3RyaW5nIiwgCiAgICAgICAgICAg
+ICAgICAgICAgICAgICAgZGVzdD0iYmFrZWNvbmYiLCBkZWZhdWx0PSJiYWtlY29uZi54bWwiLCAK
+ICAgICAgICAgICAgICAgICAgICAgICAgICBoZWxwPSJUaGUgQmFrZSBtZXRhZGF0YSBjb25maWd1
+cmF0aW9uIGZpbGUgdG8gdXNlLiBEZWZhdWx0OiAlZGVmYXVsdC4iKQogICAgICAgIChvcHRpb25z
+LCBhcmdzX2xlZnQpID0gcGFyc2VyLnBhcnNlX2FyZ3MoYXJncykKICAgICAgICBvbGRfY29uZmln
+ID0gQ29uZmlndXJhdGlvbihjb25maWcpCiAgICAgICAgb2xkX2NvbmZpZy5yZWFkKCkKICAgICAg
+ICBuZXdfY29uZmlnID0gQ29uZmlndXJhdGlvbihjb25maWcsIAogICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgIHJlbGF0aXZlX2RpcmVjdG9yeV9yb290ID0gb2xkX2NvbmZpZy5nZXRf
+cmVsYXRpdmVfZGlyZWN0b3J5X3Jvb3QoKSkKICAgICAgICBuZXdfY29uZmlnLnJlYWRfbWV0YWRh
+dGEob3B0aW9ucy5iYWtlY29uZikKICAgICAgICBuZXdfY29uZmlnLnNldF9pbnN0YWxsZGlyKG9s
+ZF9jb25maWcuZ2V0X2luc3RhbGxkaXIoKSkKICAgICAgICBuZXdfY29uZmlnLnNldF9vYmpkaXIo
+b2xkX2NvbmZpZy5nZXRfb2JqZGlyKCkpCiAgICAgICAgbmV3X2NvbmZpZy5zZXRfc291cmNlZGly
+KG9sZF9jb25maWcuZ2V0X3NvdXJjZWRpcigpKQoKICAgICAgICAjIGNvcHkgaW5zdGFsbGVkIGZp
+bGVzLgogICAgICAgIGZvciBvbGRfbW9kdWxlIGluIG9sZF9jb25maWcubW9kdWxlcygpOgogICAg
+ICAgICAgICBuZXdfbW9kdWxlID0gbmV3X2NvbmZpZy5sb29rdXAob2xkX21vZHVsZS5uYW1lKCkp
+CiAgICAgICAgICAgIGlmIG5ld19tb2R1bGUgaXMgTm9uZToKICAgICAgICAgICAgICAgICMgaWdu
+b3JlIG9sZCBtb2R1bGVzIHRoYXQgZG8gbm90IGV4aXN0IGluIHRoZSBuZXcgY29uZmlndXJhdGlv
+bgogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgbmV3X21vZHVsZS5pbnN0YWxs
+ZWQgPSBvbGRfbW9kdWxlLmluc3RhbGxlZAoKICAgICAgICAjIGNvcHkgd2hpY2ggbW9kdWxlcyBh
+cmUgZW5hYmxlZCBpbnRvIG5ldyBjb25maWcKICAgICAgICBmb3Igb2xkX21vZHVsZSBpbiBvbGRf
+Y29uZmlnLmVuYWJsZWQoKToKICAgICAgICAgICAgbmV3X21vZHVsZSA9IG5ld19jb25maWcubG9v
+a3VwKG9sZF9tb2R1bGUubmFtZSgpKQogICAgICAgICAgICBpZiBuZXdfbW9kdWxlIGlzIE5vbmU6
+CiAgICAgICAgICAgICAgICAjIGlnbm9yZSBvbGQgZW5hYmxlZCBtb2R1bGVzIHRoYXQgZG8gbm90
+IGV4aXN0IGluIHRoZSBuZXcgY29uZmlndXJhdGlvbgogICAgICAgICAgICAgICAgY29udGludWUK
+ICAgICAgICAgICAgbmV3X2NvbmZpZy5lbmFibGUobmV3X21vZHVsZSkKCiAgICAgICAgIyBjb3B5
+IHdoaWNoIG1vZHVsZXMgYXJlIGRpc2FibGVkIGludG8gbmV3IGNvbmZpZwogICAgICAgIGZvciBv
+bGRfbW9kdWxlIGluIG9sZF9jb25maWcuZGlzYWJsZWQoKToKICAgICAgICAgICAgbmV3X21vZHVs
+ZSA9IG5ld19jb25maWcubG9va3VwKG9sZF9tb2R1bGUubmFtZSgpKQogICAgICAgICAgICBpZiBu
+ZXdfbW9kdWxlIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAjIGlnbm9yZSBvbGQgZGlzYWJsZWQg
+bW9kdWxlcyB0aGF0IGRvIG5vdCBleGlzdCBpbiB0aGUgbmV3IGNvbmZpZ3VyYXRpb24KICAgICAg
+ICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIG5ld19jb25maWcuZGlzYWJsZShuZXdfbW9k
+dWxlKQoKICAgICAgICAjIG5vdywgcGFyc2UgbmV3IGVuYWJsZWQvZGlzYWJsZWQgb3B0aW9ucwog
+ICAgICAgIHNlbGYuX3BhcnNlX2VuYWJsZV9kaXNhYmxlKG9wdGlvbnMsIG5ld19jb25maWcpCgog
+ICAgICAgICMgY29weSBvbGQgdmFyaWFibGVzIGludG8gbmV3IGNvbmZpZyBmb3IgYWxsIG1vZHVs
+ZXMKICAgICAgICBmb3Igb2xkX21vZHVsZSBpbiBvbGRfY29uZmlnLm1vZHVsZXMoKToKICAgICAg
+ICAgICAgbmV3X21vZHVsZSA9IG5ld19jb25maWcubG9va3VwKG9sZF9tb2R1bGUubmFtZSgpKQog
+ICAgICAgICAgICBpZiBuZXdfbW9kdWxlIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAjIGlnbm9y
+ZSBvbGQgbW9kdWxlcyB0aGF0IGRvIG5vdCBleGlzdCBpbiB0aGUgbmV3IGNvbmZpZ3VyYXRpb24K
+ICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIG9sZF9idWlsZCA9IG9sZF9tb2R1
+bGUuZ2V0X2J1aWxkKCkKICAgICAgICAgICAgbmV3X2J1aWxkID0gbmV3X21vZHVsZS5nZXRfYnVp
+bGQoKQogICAgICAgICAgICBmb3Igb2xkX2F0dHJpYnV0ZSBpbiBvbGRfYnVpbGQuYXR0cmlidXRl
+cygpOgogICAgICAgICAgICAgICAgaWYgbmV3X2J1aWxkLmF0dHJpYnV0ZShvbGRfYXR0cmlidXRl
+LnZhbHVlKSBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAg
+ICAgICBuZXdfYnVpbGQuYXR0cmlidXRlKG9sZF92YXJpYWJsZS5uYW1lKS52YWx1ZSA9IG9sZF9h
+dHRyaWJ1dGUudmFsdWUKCiAgICAgICAgbmV3X2NvbmZpZy53cml0ZSgpCgogICAgZGVmIF9lbmFi
+bGVfZGlzYWJsZV9vcHRpb25zKHNlbGYsIHBhcnNlcik6CiAgICAgICAgcGFyc2VyLmFkZF9vcHRp
+b24oIi1lIiwgIi0tZW5hYmxlIiwgYWN0aW9uPSJhcHBlbmQiLCB0eXBlPSJzdHJpbmciLCBkZXN0
+PSJlbmFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ9W10sCiAgICAgICAg
+ICAgICAgICAgICAgICAgICAgaGVscD0iQSBtb2R1bGUgdG8gZW5hYmxlIGluIHRoZSBCYWtlIGNv
+bmZpZ3VyYXRpb24iKQogICAgICAgIHBhcnNlci5hZGRfb3B0aW9uKCItZCIsICItLWRpc2FibGUi
+LCBhY3Rpb249ImFwcGVuZCIsIHR5cGU9InN0cmluZyIsIGRlc3Q9ImRpc2FibGUiLAogICAgICAg
+ICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ9W10sCiAgICAgICAgICAgICAgICAgICAgICAgICAg
+aGVscD0iQSBtb2R1bGUgdG8gZGlzYWJsZSBpbiB0aGUgQmFrZSBjb25maWd1cmF0aW9uIikKICAg
+ICAgICBwYXJzZXIuYWRkX29wdGlvbigiLWEiLCAiLS1lbmFibGUtYWxsIiwgYWN0aW9uPSJzdG9y
+ZV90cnVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0PSJlbmFibGVfYWxsIiwgZGVm
+YXVsdD1Ob25lLAogICAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9IkVuYWJsZSBhbGwgbW9k
+dWxlcy4iKQogICAgICAgIHBhcnNlci5hZGRfb3B0aW9uKCItbSIsICItLWVuYWJsZS1taW5pbWFs
+IiwgYWN0aW9uPSJzdG9yZV90cnVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0PSJl
+bmFibGVfbWluaW1hbCIsIGRlZmF1bHQ9Tm9uZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBo
+ZWxwPSJEaXNhYmxlIGFsbCBub24tbWFuZGF0b3J5IGRlcGVuZGVuY2llcy4iKQoKICAgIGRlZiBf
+ZW5hYmxlKHNlbGYsIGVuYWJsZSwgY29uZmlndXJhdGlvbik6CiAgICAgICAgZm9yIG1vZHVsZV9u
+YW1lIGluIGVuYWJsZToKICAgICAgICAgICAgbW9kdWxlID0gY29uZmlndXJhdGlvbi5sb29rdXAo
+bW9kdWxlX25hbWUpCiAgICAgICAgICAgIGlmIG5vdCBtb2R1bGU6CiAgICAgICAgICAgICAgICBz
+ZWxmLl9lcnJvcignTW9kdWxlICIlcyIgbm90IGZvdW5kJyAlIG1vZHVsZV9uYW1lKQogICAgICAg
+ICAgICBjb25maWd1cmF0aW9uLmVuYWJsZShtb2R1bGUpCiAgICBkZWYgX2Rpc2FibGUoc2VsZiwg
+ZGlzYWJsZSwgY29uZmlndXJhdGlvbik6CiAgICAgICAgZm9yIG1vZHVsZV9uYW1lIGluIGRpc2Fi
+bGU6CiAgICAgICAgICAgIG1vZHVsZSA9IGNvbmZpZ3VyYXRpb24ubG9va3VwKG1vZHVsZV9uYW1l
+KQogICAgICAgICAgICBpZiBub3QgbW9kdWxlOgogICAgICAgICAgICAgICAgc2VsZi5fZXJyb3Io
+J01vZHVsZSAiJXMiIG5vdCBmb3VuZCcgJSBtb2R1bGVfbmFtZSkKICAgICAgICAgICAgY29uZmln
+dXJhdGlvbi5kaXNhYmxlKG1vZHVsZSkKICAgIGRlZiBfdmFyaWFibGVzX3Byb2Nlc3Moc2VsZiwg
+aXRlbXMsIGNvbmZpZ3VyYXRpb24sIGlzX2FwcGVuZCk6CiAgICAgICAgZm9yIG1vZHVsZV9uYW1l
+LCBuYW1lLCB2YWx1ZSBpbiBpdGVtczoKICAgICAgICAgICAgaWYgbW9kdWxlX25hbWU6CiAgICAg
+ICAgICAgICAgICBtb2R1bGUgPSBjb25maWd1cmF0aW9uLmxvb2t1cChtb2R1bGVfbmFtZSkKICAg
+ICAgICAgICAgICAgIGlmIG5vdCBtb2R1bGU6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZXJy
+b3IoJ01vZHVsZSAiJXMiIG5vdCBmb3VuZCcgJSBtb2R1bGVfbmFtZSkKICAgICAgICAgICAgICAg
+IGlmIG5vdCBtb2R1bGUuZ2V0X2J1aWxkKCkuYXR0cmlidXRlKG5hbWUpOgogICAgICAgICAgICAg
+ICAgICAgIHNlbGYuX2Vycm9yKCdNb2R1bGUgIiVzIiBoYXMgbm8gYXR0cmlidXRlICIlcyInICUg
+KG1vZHVsZV9uYW1lLCBuYW1lKSkKICAgICAgICAgICAgICAgIGlmIGlzX2FwcGVuZDoKICAgICAg
+ICAgICAgICAgICAgICBtb2R1bGUuZ2V0X2J1aWxkKCkuYXR0cmlidXRlKG5hbWUpLnZhbHVlID0g
+XAogICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGUuZ2V0X2J1aWxkKCkuYXR0cmlidXRlKG5h
+bWUpLnZhbHVlICsgJyAnICsgdmFsdWUKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAg
+ICAgICAgICAgbW9kdWxlLmdldF9idWlsZCgpLmF0dHJpYnV0ZShuYW1lKS52YWx1ZSA9IHZhbHVl
+CiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBmb3IgbW9kdWxlIGluIGNvbmZpZ3Vy
+YXRpb24ubW9kdWxlcygpOgogICAgICAgICAgICAgICAgICAgIGlmIG1vZHVsZS5nZXRfYnVpbGQo
+KS5hdHRyaWJ1dGUobmFtZSk6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGlzX2FwcGVuZDoK
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZS5nZXRfYnVpbGQoKS5hdHRyaWJ1dGUo
+bmFtZSkudmFsdWUgPSBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlLmdl
+dF9idWlsZCgpLmF0dHJpYnV0ZShuYW1lKS52YWx1ZSArICcgJyArIHZhbHVlCiAgICAgICAgICAg
+ICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGUuZ2V0
+X2J1aWxkKCkuYXR0cmlidXRlKG5hbWUpLnZhbHVlID0gdmFsdWUKICAgICAgICAKICAgIGRlZiBf
+cGFyc2VfZW5hYmxlX2Rpc2FibGUoc2VsZiwgb3B0aW9ucywgY29uZmlndXJhdGlvbik6CiAgICAg
+ICAgc2VsZi5fZW5hYmxlKG9wdGlvbnMuZW5hYmxlLCBjb25maWd1cmF0aW9uKQogICAgICAgIHNl
+bGYuX2Rpc2FibGUob3B0aW9ucy5kaXNhYmxlLCBjb25maWd1cmF0aW9uKQogICAgICAgIGlmIG9w
+dGlvbnMuZW5hYmxlX2FsbDoKICAgICAgICAgICAgZm9yIG1vZHVsZSBpbiBjb25maWd1cmF0aW9u
+Lm1vZHVsZXMoKToKICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb24uZW5hYmxlKG1vZHVsZSkK
+ICAgICAgICBpZiBvcHRpb25zLmVuYWJsZV9taW5pbWFsOgogICAgICAgICAgICBlbmFibGVkID0g
+W10KICAgICAgICAgICAgZGVmIF9lbmFibGVkX2l0ZXJhdG9yKG1vZHVsZSk6CiAgICAgICAgICAg
+ICAgICBlbmFibGVkLmFwcGVuZChtb2R1bGUpCiAgICAgICAgICAgICAgICByZXR1cm4gVHJ1ZQog
+ICAgICAgICAgICBzZWxmLl9pdGVyYXRlKGNvbmZpZ3VyYXRpb24sIF9lbmFibGVkX2l0ZXJhdG9y
+LCAKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uLmVuYWJsZWQoKSwgCiAg
+ICAgICAgICAgICAgICAgICAgICAgICAgZm9sbG93X29wdGlvbmFsID0gVHJ1ZSkKICAgICAgICAg
+ICAgZW5hYmxlZF9vcHRpb25hbCA9IFtdCiAgICAgICAgICAgIGRlZiBfZW5hYmxlZF9vcHRpb25h
+bF9pdGVyYXRvcihtb2R1bGUpOgogICAgICAgICAgICAgICAgZW5hYmxlZF9vcHRpb25hbC5hcHBl
+bmQobW9kdWxlKQogICAgICAgICAgICAgICAgcmV0dXJuIFRydWUKICAgICAgICAgICAgc2VsZi5f
+aXRlcmF0ZShjb25maWd1cmF0aW9uLCBfZW5hYmxlZF9vcHRpb25hbF9pdGVyYXRvciwgCiAgICAg
+ICAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhdGlvbi5lbmFibGVkKCksCiAgICAgICAgICAg
+ICAgICAgICAgICAgICAgZm9sbG93X29wdGlvbmFsID0gRmFsc2UpCiAgICAgICAgICAgIGZvciBt
+b2R1bGUgaW4gZW5hYmxlZDoKICAgICAgICAgICAgICAgIGlmIG5vdCBtb2R1bGUgaW4gZW5hYmxl
+ZF9vcHRpb25hbDoKICAgICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uLmRpc2FibGUobW9k
+dWxlKQoKICAgIGRlZiBfcGFyc2VfdmFyaWFibGUoc2VsZiwgc3RyaW5nKToKICAgICAgICByZXR2
+YWwgPSBbXQogICAgICAgIGRhdGEgPSBzdHJpbmcuc3BsaXQoIjoiKQogICAgICAgIGlmIGxlbihk
+YXRhKSA9PSAxOgogICAgICAgICAgICBuYW1lLCB2YWx1ZSA9IHZhcmlhYmxlLnNwbGl0KCI9IikK
+ICAgICAgICAgICAgZm91bmQgPSBGYWxzZQogICAgICAgICAgICAKICAgICAgICAgICAgZm9yIG1v
+ZHVsZSBpbiBjb25maWd1cmF0aW9uLm1vZHVsZXMoKToKICAgICAgICAgICAgICAgIGlmIG1vZHVs
+ZS5nZXRfYnVpbGQoKS5hdHRyaWJ1dGUobmFtZSk6CiAgICAgICAgICAgICAgICAgICAgcmV0dmFs
+LmFwcGVuZCgobW9kdWxlLCBuYW1lLCB2YWx1ZSkpCiAgICAgICAgICAgIGlmIG5vdCByZXR2YWw6
+CiAgICAgICAgICAgICAgICBwcmludCAnRXJyb3I6IG5vIG1vZHVsZSBjb250YWlucyB2YXJpYWJs
+ZSAlcycgJSBuYW1lCiAgICAgICAgZWxpZiBsZW4oZGF0YSkgPT0gMjoKICAgICAgICAgICAgbmFt
+ZSwgdmFsdWUgPSBkYXRhWzFdLnNwbGl0KCI9IikKICAgICAgICAgICAgbW9kdWxlID0gY29uZmln
+dXJhdGlvbi5sb29rdXAobW9kdWxlX25hbWUpCiAgICAgICAgICAgIGlmIG5vdCBtb2R1bGU6CiAg
+ICAgICAgICAgICAgICBzZWxmLl9lcnJvcignbm9uLWV4aXN0aW5nIG1vZHVsZSAlcyBpbiB2YXJp
+YWJsZSBzcGVjaWZpY2F0aW9uICVzJyAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAobW9kdWxlX25hbWUsIHZhcmlhYmxlKSkKICAgICAgICAgICAgaWYgbm90IG1vZHVsZS5nZXRf
+YnVpbGQoKS5hdHRyaWJ1dGUobmFtZSk6CiAgICAgICAgICAgICAgICBzZWxmLl9lcnJvcignbm9u
+LWV4aXN0aW5nIHZhcmlhYmxlICVzIGluIG1vZHVsZSAlcycgJSAobmFtZSwgbW9kdWxlX25hbWUp
+KQogICAgICAgICAgICByZXR2YWwuYXBwZW5kKChtb2R1bGUsIG5hbWUsIHZhbHVlKSkKICAgICAg
+ICBlbHNlOgogICAgICAgICAgICBzZWxmLl9lcnJvcignaW52YWxpZCB2YXJpYWJsZSBzcGVjaWZp
+Y2F0aW9uOiAiJXMiJyAlIHZhcmlhYmxlKQogICAgICAgIHJldHVybiByZXR2YWwKICAgICAgICAK
+ICAgIGRlZiBfY29uZmlndXJlKHNlbGYsY29uZmlnLGFyZ3MpOgogICAgICAgIHBhcnNlciA9IE9w
+dGlvblBhcnNlcih1c2FnZSA9ICd1c2FnZTogJXByb2cgY29uZmlndXJlIFtvcHRpb25zXScpCiAg
+ICAgICAgc2VsZi5fZW5hYmxlX2Rpc2FibGVfb3B0aW9ucyhwYXJzZXIpCiAgICAgICAgcGFyc2Vy
+LmFkZF9vcHRpb24oIi1jIiwgIi0tY29uZmZpbGUiLCBhY3Rpb249InN0b3JlIiwgdHlwZT0ic3Ry
+aW5nIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdD0iYmFrZWNvbmYiLCBkZWZhdWx0
+PSJiYWtlY29uZi54bWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBoZWxwPSJUaGUgQmFr
+ZSBtZXRhZGF0YSBjb25maWd1cmF0aW9uIGZpbGUgdG8gdXNlLiBEZWZhdWx0OiAlZGVmYXVsdC4i
+KQogICAgICAgIHBhcnNlci5hZGRfb3B0aW9uKCItZyIsICItLWd1aSIsIGFjdGlvbj0ic3RvcmVf
+dHJ1ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3Q9Imd1aSIsIGRlZmF1bHQ9IkZh
+bHNlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaGVscD0iVXNlIGEgR1VJIHRvIGRlZmlu
+ZSB0aGUgY29uZmlndXJhdGlvbi4iKQogICAgICAgIHBhcnNlci5hZGRfb3B0aW9uKCItcyIsICIt
+LXNldCIsIGFjdGlvbj0iYXBwZW5kIiwgdHlwZT0ic3RyaW5nIiwgZGVzdD0ic2V0IiwKICAgICAg
+ICAgICAgICAgICAgICAgICAgICBkZWZhdWx0PVtdLAogICAgICAgICAgICAgICAgICAgICAgICAg
+IGhlbHA9IkZvcm1hdDogbW9kdWxlOm5hbWU9dmFsdWUuIEEgdmFyaWFibGUgdG8gc2V0IGluIHRo
+ZSBCYWtlICIKICAgICAgICAgICAgICAgICAgICAgICAgICAiY29uZmlndXJhdGlvbiBmb3IgdGhl
+IG1hdGNoaW5nIG1vZHVsZS4iKQogICAgICAgIHBhcnNlci5hZGRfb3B0aW9uKCItLWFwcGVuZCIs
+IGFjdGlvbj0iYXBwZW5kIiwgdHlwZT0ic3RyaW5nIiwgZGVzdD0iYXBwZW5kIiwgZGVmYXVsdD1b
+XSwKICAgICAgICAgICAgICAgICAgICAgICAgICBoZWxwPSJGb3JtYXQ6IG1vZHVsZTpuYW1lPXZh
+bHVlLiBBIHZhcmlhYmxlIHRvIGFwcGVuZCB0byBpbiB0aGUgQmFrZSAiCiAgICAgICAgICAgICAg
+ICAgICAgICAgICAgImNvbmZpZ3VyYXRpb24gZm9yIHRoZSBtYXRjaGluZyBtb2R1bGUuIikKICAg
+ICAgICBwYXJzZXIuYWRkX29wdGlvbigiLS1vYmpkaXIiLCBhY3Rpb249InN0b3JlIiwgdHlwZT0i
+c3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0PSJvYmpkaXIiLCBkZWZhdWx0
+PSJvYmpkaXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9IlRoZSBwZXItbW9kdWxl
+IGRpcmVjdG9yeSB3aGVyZSB0aGUgb2JqZWN0IGZpbGVzIG9mIGVhY2ggbW9kdWxlICIKICAgICAg
+ICAgICAgICAgICAgICAgICAgICAid2lsbCBiZSBjb21waWxlZC4iKQogICAgICAgIHBhcnNlci5h
+ZGRfb3B0aW9uKCItLXNvdXJjZWRpciIsIGFjdGlvbj0ic3RvcmUiLCB0eXBlPSJzdHJpbmciLAog
+ICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3Q9InNvdXJjZWRpciIsIGRlZmF1bHQ9InNvdXJj
+ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaGVscD0iVGhlIGRpcmVjdG9yeSB3aGVyZSB0
+aGUgc291cmNlIGNvZGUgb2YgYWxsIG1vZHVsZXMgIgogICAgICAgICAgICAgICAgICAgICAgICAg
+ICJ3aWxsIGJlIGRvd25sb2FkZWQuIikKICAgICAgICBwYXJzZXIuYWRkX29wdGlvbigiLWkiLCAi
+LS1pbnN0YWxsZGlyIiwgYWN0aW9uPSJzdG9yZSIsIHR5cGU9InN0cmluZyIsCiAgICAgICAgICAg
+ICAgICAgICAgICAgICAgZGVzdD0iaW5zdGFsbGRpciIsIGRlZmF1bHQ9ImJ1aWxkIiwKICAgICAg
+ICAgICAgICAgICAgICAgICAgICBoZWxwPSJUaGUgZGlyZWN0b3J5IHdoZXJlIGFsbCBtb2R1bGVz
+IHdpbGwgYmUgaW5zdGFsbGVkLiIpCiAgICAgICAgcGFyc2VyLmFkZF9vcHRpb24oIi1wIiwgIi0t
+cHJlZGVmaW5lZCIsIGFjdGlvbj0ic3RvcmUiLCB0eXBlPSJzdHJpbmciLAogICAgICAgICAgICAg
+ICAgICAgICAgICAgIGRlc3Q9InByZWRlZmluZWQiLCBkZWZhdWx0PU5vbmUsCiAgICAgICAgICAg
+ICAgICAgICAgICAgICAgaGVscD0iQSBwcmVkZWZpbmVkIGNvbmZpZ3VyYXRpb24gdG8gYXBwbHki
+KQogICAgICAgIChvcHRpb25zLCBhcmdzX2xlZnQpID0gcGFyc2VyLnBhcnNlX2FyZ3MoYXJncykK
+ICAgICAgICBjb25maWd1cmF0aW9uID0gQ29uZmlndXJhdGlvbihjb25maWcpCiAgICAgICAgY29u
+ZmlndXJhdGlvbi5yZWFkX21ldGFkYXRhKG9wdGlvbnMuYmFrZWNvbmYpCiAgICAgICAgY29uZmln
+dXJhdGlvbi5zZXRfc291cmNlZGlyKG9wdGlvbnMuc291cmNlZGlyKQogICAgICAgIGNvbmZpZ3Vy
+YXRpb24uc2V0X29iamRpcihvcHRpb25zLm9iamRpcikKICAgICAgICBjb25maWd1cmF0aW9uLnNl
+dF9pbnN0YWxsZGlyKG9wdGlvbnMuaW5zdGFsbGRpcikKICAgICAgICBpZiBvcHRpb25zLnByZWRl
+ZmluZWQ6CiAgICAgICAgICAgIGRhdGEgPSBvcHRpb25zLnByZWRlZmluZWQuc3BsaXQoJzonKQog
+ICAgICAgICAgICByZXF1ZXN0ZWQgPSBOb25lCiAgICAgICAgICAgIHByZWRlZmluZWQgPSBjb25m
+aWd1cmF0aW9uLnJlYWRfcHJlZGVmaW5lZChvcHRpb25zLmJha2Vjb25mKQogICAgICAgICAgICBp
+ZiBsZW4oZGF0YSkgPT0gMToKICAgICAgICAgICAgICAgIHJlcXVlc3RlZCA9IGRhdGFbMF0KICAg
+ICAgICAgICAgZWxpZiBsZW4oZGF0YSkgPT0gMjoKICAgICAgICAgICAgICAgIHByZWRlZmluZWQg
+Kz0gY29uZmlndXJhdGlvbi5yZWFkX3ByZWRlZmluZWQoZGF0YVswXSkKICAgICAgICAgICAgICAg
+IHJlcXVlc3RlZCA9IGRhdGFbMV0KICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNl
+bGYuX2Vycm9yKCdJbnZhbGlkIC0tcHJlZGVmaW5lZCBjb250ZW50OiAiJXMiJyAlIHByZWRlZmlu
+ZWQpCiAgICAgICAgICAgIGZvciBwIGluIHJlcXVlc3RlZC5zcGxpdCgnLCcpOgogICAgICAgICAg
+ICAgICAgZm91bmQgPSBGYWxzZQogICAgICAgICAgICAgICAgZm9yIHByZWRlZiBpbiBwcmVkZWZp
+bmVkOgogICAgICAgICAgICAgICAgICAgIGlmIHByZWRlZi5uYW1lID09IHA6CiAgICAgICAgICAg
+ICAgICAgICAgICAgIGZvdW5kID0gVHJ1ZQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9l
+bmFibGUocHJlZGVmLmVuYWJsZSwgY29uZmlndXJhdGlvbikKICAgICAgICAgICAgICAgICAgICAg
+ICAgc2VsZi5fZGlzYWJsZShwcmVkZWYuZGlzYWJsZSwgY29uZmlndXJhdGlvbikKICAgICAgICAg
+ICAgICAgICAgICAgICAgc2VsZi5fdmFyaWFibGVzX3Byb2Nlc3MocHJlZGVmLnZhcmlhYmxlc19z
+ZXQsIGNvbmZpZ3VyYXRpb24sIGlzX2FwcGVuZCA9IEZhbHNlKQogICAgICAgICAgICAgICAgICAg
+ICAgICBzZWxmLl92YXJpYWJsZXNfcHJvY2VzcyhwcmVkZWYudmFyaWFibGVzX2FwcGVuZCwgY29u
+ZmlndXJhdGlvbiwgaXNfYXBwZW5kID0gVHJ1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgZGly
+ZWN0b3JpZXMgPSBwcmVkZWYuZGlyZWN0b3JpZXMKICAgICAgICAgICAgICAgICAgICAgICAgaWYg
+J3NvdXJjZWRpcicgaW4gZGlyZWN0b3JpZXM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBj
+b25maWd1cmF0aW9uLnNldF9zb3VyY2VkaXIoZGlyZWN0b3JpZXNbJ3NvdXJjZWRpciddKQogICAg
+ICAgICAgICAgICAgICAgICAgICBpZiAnb2JqZGlyJyBpbiBkaXJlY3RvcmllczoKICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb24uc2V0X29iamRpcihkaXJlY3Rvcmllc1sn
+b2JqZGlyJ10pCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICdpbnN0YWxsZGlyJyBpbiBkaXJl
+Y3RvcmllczoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb24uc2V0X2lu
+c3RhbGxkaXIoZGlyZWN0b3JpZXNbJ2luc3RhbGxkaXInXSkKICAgICAgICAgICAgICAgICAgICAg
+ICAgYnJlYWsKICAgICAgICAgICAgICAgIGlmIG5vdCBmb3VuZDoKICAgICAgICAgICAgICAgICAg
+ICBzZWxmLl9lcnJvcignLS1wcmVkZWZpbmVkOiAiJXMiIG5vdCBmb3VuZC4nICUgcCkKICAgICAg
+ICAgICAgICAgICAgICAKICAgICAgICBzZWxmLl9wYXJzZV9lbmFibGVfZGlzYWJsZShvcHRpb25z
+LCBjb25maWd1cmF0aW9uKQogICAgICAgIGZvciB2YXJpYWJsZSBpbiBvcHRpb25zLnNldDoKICAg
+ICAgICAgICAgbWF0Y2hlcyA9IHNlbGYuX3BhcnNlX3ZhcmlhYmxlKHZhcmlhYmxlKQogICAgICAg
+ICAgICBmb3IgbW9kdWxlLCBuYW1lLCB2YWx1ZSBpbiBtYXRjaGVzOgogICAgICAgICAgICAgICAg
+bW9kdWxlLmdldF9idWlsZCgpLmF0dHJpYnV0ZShuYW1lKS52YWx1ZSA9IHZhbHVlCiAgICAgICAg
+Zm9yIHZhcmlhYmxlIGluIG9wdGlvbnMuYXBwZW5kOgogICAgICAgICAgICBtYXRjaGVzID0gc2Vs
+Zi5fcGFyc2VfdmFyaWFibGUodmFyaWFibGUpCiAgICAgICAgICAgIGZvciBtb2R1bGUsIG5hbWUs
+IHZhbHVlIGluIG1hdGNoZXM6CiAgICAgICAgICAgICAgICBjdXJyZW50X3ZhbHVlID0gbW9kdWxl
+LmdldF9idWlsZCgpLmF0dHJpYnV0ZShuYW1lKS52YWx1ZQogICAgICAgICAgICAgICAgbW9kdWxl
+LmdldF9idWlsZCgpLmF0dHJpYnV0ZShuYW1lKS52YWx1ZSA9IGN1cnJlbnRfdmFsdWUgKyAnICcg
+KyB2YWx1ZQogICAgICAgIGNvbmZpZ3VyYXRpb24ud3JpdGUoKQoKICAgIGRlZiBfaXRlcmF0ZShz
+ZWxmLCBjb25maWd1cmF0aW9uLCBmdW5jdG9yLCB0YXJnZXRzLCBmb2xsb3dfb3B0aW9uYWw9VHJ1
+ZSk6CiAgICAgICAgZGVwcyA9IERlcGVuZGVuY2llcygpCiAgICAgICAgY2xhc3MgV3JhcHBlcjoK
+ICAgICAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIG1vZHVsZSk6CiAgICAgICAgICAgICAgICBz
+ZWxmLl9tb2R1bGUgPSBtb2R1bGUKICAgICAgICAgICAgZGVmIGZ1bmN0aW9uKHNlbGYpOgogICAg
+ICAgICAgICAgICAgcmV0dmFsID0gZnVuY3RvcihzZWxmLl9tb2R1bGUpCiAgICAgICAgICAgICAg
+ICBjb25maWd1cmF0aW9uLndyaXRlKCkKICAgICAgICAgICAgICAgIHJldHVybiByZXR2YWwKICAg
+ICAgICBmb3IgbSBpbiBjb25maWd1cmF0aW9uLm1vZHVsZXMoKToKICAgICAgICAgICAgd3JhcHBl
+ciA9IFdyYXBwZXIobSkKICAgICAgICAgICAgZGVwcy5hZGRfZHN0KG0sIHdyYXBwZXIuZnVuY3Rp
+b24pCiAgICAgICAgZm9yIG0gaW4gY29uZmlndXJhdGlvbi5tb2R1bGVzKCk6CiAgICAgICAgICAg
+IGZvciBkZXBlbmRlbmN5IGluIG0uZGVwZW5kZW5jaWVzKCk6CiAgICAgICAgICAgICAgICBzcmMg
+PSBjb25maWd1cmF0aW9uLmxvb2t1cCAoZGVwZW5kZW5jeS5uYW1lKCkpCiAgICAgICAgICAgICAg
+ICBpZiBub3Qgc3JjIGluIGNvbmZpZ3VyYXRpb24uZGlzYWJsZWQoKToKICAgICAgICAgICAgICAg
+ICAgICBpZiBmb2xsb3dfb3B0aW9uYWwgb3Igbm90IGRlcGVuZGVuY3kuaXNfb3B0aW9uYWwoKToK
+ICAgICAgICAgICAgICAgICAgICAgICAgZGVwcy5hZGRfZGVwKHNyYywgbSwgb3B0aW9uYWwgPSBk
+ZXBlbmRlbmN5LmlzX29wdGlvbmFsKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAg
+IHRyeToKICAgICAgICAgICAgZGVwcy5yZXNvbHZlKHRhcmdldHMpCiAgICAgICAgZXhjZXB0IERl
+cGVuZGVuY3lVbm1ldCBhcyBlcnJvcjoKICAgICAgICAgICAgc2VsZi5fZXJyb3IoJyVzIGZhaWxl
+ZCcgJSBlcnJvci5mYWlsZWQoKS5uYW1lKCkpCgogICAgZGVmIF9yZWFkX2NvbmZpZyhzZWxmLCBj
+b25maWcpOgogICAgICAgIGNvbmZpZ3VyYXRpb24gPSBDb25maWd1cmF0aW9uKGNvbmZpZykKICAg
+ICAgICBpZiBub3QgY29uZmlndXJhdGlvbi5yZWFkKCk6CiAgICAgICAgICAgIHN5cy5zdGRlcnIu
+d3JpdGUoJ1RoZSBjb25maWd1cmF0aW9uIGZpbGUgaGFzIGJlZW4gY2hhbmdlZCBvciBoYXMgbW92
+ZWQuXG4nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1J1bm5pbmcgXCdyZWNvbmZpZ3Vy
+ZVwnLiBZb3Ugc2hvdWxkIGNvbnNpZGVyIHJ1bm5pbmcgaXRcbicKICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAneW91cnNlbGYgdG8gdHdlYWsgc29tZSBwYXJhbWV0ZXJzIGlmIG5lZWRlZC5c
+bicpCiAgICAgICAgICAgIHNlbGYuX3JlY29uZmlndXJlKGNvbmZpZywgW10pCiAgICAgICAgICAg
+IGNvbmZpZ3VyYXRpb24gPSBDb25maWd1cmF0aW9uKGNvbmZpZykKICAgICAgICAgICAgaWYgbm90
+IGNvbmZpZ3VyYXRpb24ucmVhZCgpOgogICAgICAgICAgICAgICAgc2VsZi5fZXJyb3IoJ09vcHMu
+IFwncmVjb25maWd1cmVcJyBkaWQgbm90IHN1Y2NlZWQuIFlvdSBzaG91bGQgY29uc2lkZXJcbicK
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZWxldGluZyB5b3VyIGJha2VmaWxlIGFuZCBy
+dW5uaW5nIFwnY29uZmlndXJlXCcgYWdhaW4uJykKCiAgICAgICAgcmV0dXJuIGNvbmZpZ3VyYXRp
+b24KCiAgICBkZWYgX29wdGlvbl9wYXJzZXIoc2VsZiwgb3BlcmF0aW9uX25hbWUpOgogICAgICAg
+IHBhcnNlciA9IE9wdGlvblBhcnNlcih1c2FnZT0ndXNhZ2U6ICVwcm9nICcgKyBvcGVyYXRpb25f
+bmFtZSArICcgW29wdGlvbnNdJykKICAgICAgICBwYXJzZXIuYWRkX29wdGlvbignLS1sb2dmaWxl
+JywgaGVscD0nRmlsZSBpbiB3aGljaCB3ZSB3YW50IHRvIHN0b3JlIGxvZyBvdXRwdXQgJwogICAg
+ICAgICAgICAgICAgICAgICAgICAgICdvZiByZXF1ZXN0ZWQgb3BlcmF0aW9uJywgYWN0aW9uPSJz
+dG9yZSIsIHR5cGU9InN0cmluZyIsIGRlc3Q9ImxvZ2ZpbGUiLAogICAgICAgICAgICAgICAgICAg
+ICAgICAgIGRlZmF1bHQ9JycpCiAgICAgICAgcGFyc2VyLmFkZF9vcHRpb24oJy0tbG9nZGlyJywg
+aGVscD0nRGlyZWN0b3J5IGluIHdoaWNoIHdlIHdhbnQgdG8gc3RvcmUgbG9nIG91dHB1dCAnCiAg
+ICAgICAgICAgICAgICAgICAgICAgICAgJ29mIHJlcXVlc3RlZCBvcGVyYXRpb24uIE9uZSBmaWxl
+IHBlciBtb2R1bGUuJywgYWN0aW9uPSJzdG9yZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAg
+IHR5cGU9InN0cmluZyIsIGRlc3Q9ImxvZ2RpciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAg
+ZGVmYXVsdD0nJykKICAgICAgICBwYXJzZXIuYWRkX29wdGlvbignLXYnLCAnLS12ZXJib3NlJywg
+YWN0aW9uPSdjb3VudCcsIGRlc3Q9J3ZlcmJvc2UnLCBkZWZhdWx0PTIsCiAgICAgICAgICAgICAg
+ICAgICAgICAgICAgaGVscD0nSW5jcmVhc2UgdGhlIGxvZyB2ZXJib3NpdHkgbGV2ZWwnKQogICAg
+ICAgIHBhcnNlci5hZGRfb3B0aW9uKCctcScsICctLXF1aWV0JywgYWN0aW9uPSdjb3VudCcsIGRl
+c3Q9J3F1aWV0JywgZGVmYXVsdD0wLAogICAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9J0lu
+Y3JlYXNlIHRoZSBsb2cgcXVpZXRuZXNzIGxldmVsJykKICAgICAgICBwYXJzZXIuYWRkX29wdGlv
+bigiLW8iLCAiLS1vbmUiLCBhY3Rpb249InN0b3JlIiwgdHlwZT0ic3RyaW5nIiwKICAgICAgICAg
+ICAgICAgICAgICAgICAgICBkZXN0PSJvbmUiLCBkZWZhdWx0PSIiLCAKICAgICAgICAgICAgICAg
+ICAgICAgICAgICBoZWxwPSJQcm9jZXNzIG9ubHkgdGhlIG1vZHVsZSBzcGVjaWZpZWQuIikKICAg
+ICAgICBwYXJzZXIuYWRkX29wdGlvbigiLWEiLCAiLS1hbGwiLCBhY3Rpb249InN0b3JlX3RydWUi
+LAogICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3Q9ImFsbCIsIGRlZmF1bHQ9RmFsc2UsIAog
+ICAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9IlByb2Nlc3MgYWxsIG1vZHVsZXMiKQogICAg
+ICAgIHBhcnNlci5hZGRfb3B0aW9uKCItcyIsICItLXN0YXJ0IiwgYWN0aW9uPSJzdG9yZSIsIHR5
+cGU9InN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdD0ic3RhcnQiLCBkZWZh
+dWx0PSIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBoZWxwPSJQcm9jZXNzIGFsbCBtb2R1
+bGVzIGVuYWJsZWQgc3RhcnRpbmcgZnJvbSB0aGUgbW9kdWxlIHNwZWNpZmllZC4iKQogICAgICAg
+IHBhcnNlci5hZGRfb3B0aW9uKCItLWFmdGVyIiwgYWN0aW9uPSJzdG9yZSIsIHR5cGU9InN0cmlu
+ZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdD0iYWZ0ZXIiLCBkZWZhdWx0PSIiLCAK
+ICAgICAgICAgICAgICAgICAgICAgICAgICBoZWxwPSJQcm9jZXNzIGFsbCBtb2R1bGVzIGVuYWJs
+ZWQgc3RhcnRpbmcgYWZ0ZXIgdGhlIG1vZHVsZSBzcGVjaWZpZWQuIikKICAgICAgICByZXR1cm4g
+cGFyc2VyCgogICAgZGVmIF9kb19vcGVyYXRpb24oc2VsZiwgY29uZmlnLCBvcHRpb25zLCBmdW5j
+dG9yKToKICAgICAgICBjb25maWd1cmF0aW9uID0gc2VsZi5fcmVhZF9jb25maWcoY29uZmlnKQog
+ICAgICAgIGlmIG9wdGlvbnMubG9nZGlyID09ICcnIGFuZCBvcHRpb25zLmxvZ2ZpbGUgPT0gJyc6
+CiAgICAgICAgICAgIGxvZ2dlciA9IFN0ZG91dE1vZHVsZUxvZ2dlcigpCiAgICAgICAgZWxpZiBv
+cHRpb25zLmxvZ2RpciAhPSAnJzoKICAgICAgICAgICAgYXNzZXJ0IG9wdGlvbnMubG9nZmlsZSA9
+PSAnJwogICAgICAgICAgICBsb2dnZXIgPSBMb2dkaXJNb2R1bGVMb2dnZXIob3B0aW9ucy5sb2dk
+aXIpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYXNzZXJ0IG9wdGlvbnMubG9nZmlsZSAhPSAn
+JwogICAgICAgICAgICBsb2dnZXIgPSBMb2dmaWxlTW9kdWxlTG9nZ2VyKG9wdGlvbnMubG9nZmls
+ZSkKICAgICAgICB2ZXJib3NlID0gb3B0aW9ucy52ZXJib3NlIC0gb3B0aW9ucy5xdWlldAogICAg
+ICAgIHZlcmJvc2UgPSB2ZXJib3NlIGlmIHZlcmJvc2UgPj0gMCBlbHNlIDAKICAgICAgICBsb2dn
+ZXIuc2V0X3ZlcmJvc2UodmVyYm9zZSkKCiAgICAgICAgZW52ID0gTW9kdWxlRW52aXJvbm1lbnQo
+bG9nZ2VyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb24uY29t
+cHV0ZV9pbnN0YWxsZGlyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1
+cmF0aW9uLmNvbXB1dGVfc291cmNlZGlyKCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgY29uZmlndXJhdGlvbi5nZXRfb2JqZGlyKCkpCiAgICAgICAgbXVzdF9kaXNhYmxlID0gW10K
+ICAgICAgICBpZiBvcHRpb25zLm9uZSAhPSAnJzoKICAgICAgICAgICAgaWYgb3B0aW9ucy5hbGwg
+b3Igb3B0aW9ucy5zdGFydCAhPSAnJyBvciBvcHRpb25zLmFmdGVyICE9ICcnOgogICAgICAgICAg
+ICAgICAgc2VsZi5fZXJyb3IoJ2luY29tcGF0aWJsZSBvcHRpb25zJykKICAgICAgICAgICAgbW9k
+dWxlID0gY29uZmlndXJhdGlvbi5sb29rdXAob3B0aW9ucy5vbmUpCiAgICAgICAgICAgIGZ1bmN0
+b3IoY29uZmlndXJhdGlvbiwgbW9kdWxlLCBlbnYpCiAgICAgICAgICAgIGNvbmZpZ3VyYXRpb24u
+d3JpdGUoKQogICAgICAgIGVsaWYgb3B0aW9ucy5hbGw6CiAgICAgICAgICAgIGlmIG9wdGlvbnMu
+c3RhcnQgIT0gJycgb3Igb3B0aW9ucy5hZnRlciAhPSAnJzoKICAgICAgICAgICAgICAgIHNlbGYu
+X2Vycm9yKCdpbmNvbXBhdGlibGUgb3B0aW9ucycpCiAgICAgICAgICAgIGRlZiBfaXRlcmF0b3Io
+bW9kdWxlKToKICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdG9yIChjb25maWd1cmF0aW9uLCBt
+b2R1bGUsIGVudikKICAgICAgICAgICAgc2VsZi5faXRlcmF0ZShjb25maWd1cmF0aW9uLCBfaXRl
+cmF0b3IsIGNvbmZpZ3VyYXRpb24ubW9kdWxlcygpKQogICAgICAgIGVsaWYgb3B0aW9ucy5zdGFy
+dCAhPSAnJzoKICAgICAgICAgICAgaWYgb3B0aW9ucy5hZnRlciAhPSAnJzoKICAgICAgICAgICAg
+ICAgIHNlbGYuX2Vycm9yKCdpbmNvbXBhdGlibGUgb3B0aW9ucycpCiAgICAgICAgICAgIG11c3Rf
+cHJvY2VzcyA9IFtdCiAgICAgICAgICAgIGZpcnN0X21vZHVsZSA9IGNvbmZpZ3VyYXRpb24ubG9v
+a3VwKG9wdGlvbnMuc3RhcnQpCiAgICAgICAgICAgIGRlZiBfaXRlcmF0b3IobW9kdWxlKToKICAg
+ICAgICAgICAgICAgIGlmIG1vZHVsZSA9PSBmaXJzdF9tb2R1bGU6CiAgICAgICAgICAgICAgICAg
+ICAgbXVzdF9wcm9jZXNzLmFwcGVuZCgwKQogICAgICAgICAgICAgICAgaWYgbGVuKG11c3RfcHJv
+Y2VzcykgIT0gMDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3RvciAoY29uZmlndXJh
+dGlvbiwgbW9kdWxlLCBlbnYpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAg
+ICAgIHJldHVybiBUcnVlCiAgICAgICAgICAgIHNlbGYuX2l0ZXJhdGUoY29uZmlndXJhdGlvbiwg
+X2l0ZXJhdG9yLCBjb25maWd1cmF0aW9uLmVuYWJsZWQoKSkKICAgICAgICBlbGlmIG9wdGlvbnMu
+YWZ0ZXIgIT0gJyc6CiAgICAgICAgICAgICMgdGhpcyBpcyBhIGxpc3QgYmVjYXVzZSB0aGUgaW5u
+ZXIgZnVuY3Rpb24gYmVsb3cKICAgICAgICAgICAgIyBpcyBub3QgYWxsb3dlZCB0byBtb2RpZnkg
+dGhlIG91dGVyIGZ1bmN0aW9uIHJlZmVyZW5jZQogICAgICAgICAgICBtdXN0X3Byb2Nlc3MgPSBb
+XSAKICAgICAgICAgICAgZmlyc3RfbW9kdWxlID0gY29uZmlndXJhdGlvbi5sb29rdXAob3B0aW9u
+cy5hZnRlcikKICAgICAgICAgICAgZGVmIF9pdGVyYXRvcihtb2R1bGUpOgogICAgICAgICAgICAg
+ICAgaWYgbGVuKG11c3RfcHJvY2VzcykgIT0gMDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4g
+ZnVuY3RvciAoY29uZmlndXJhdGlvbiwgbW9kdWxlLCBlbnYpCiAgICAgICAgICAgICAgICBlbGlm
+IG1vZHVsZSA9PSBmaXJzdF9tb2R1bGU6CiAgICAgICAgICAgICAgICAgICAgbXVzdF9wcm9jZXNz
+LmFwcGVuZCgxKQogICAgICAgICAgICAgICAgcmV0dXJuIFRydWUKICAgICAgICAgICAgc2VsZi5f
+aXRlcmF0ZShjb25maWd1cmF0aW9uLCBfaXRlcmF0b3IsIGNvbmZpZ3VyYXRpb24uZW5hYmxlZCgp
+KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGRlZiBfaXRlcmF0b3IobW9kdWxlKToKICAgICAg
+ICAgICAgICAgIHJldHVybiBmdW5jdG9yIChjb25maWd1cmF0aW9uLCBtb2R1bGUsIGVudikKICAg
+ICAgICAgICAgc2VsZi5faXRlcmF0ZShjb25maWd1cmF0aW9uLCBfaXRlcmF0b3IsIGNvbmZpZ3Vy
+YXRpb24uZW5hYmxlZCgpKQogICAgICAgIHJldHVybiBlbnYKCiAgICBkZWYgX2Rvd25sb2FkKHNl
+bGYsY29uZmlnLGFyZ3MpOgogICAgICAgIHBhcnNlciA9IHNlbGYuX29wdGlvbl9wYXJzZXIoJ2Rv
+d25sb2FkJykKICAgICAgICAob3B0aW9ucywgYXJnc19sZWZ0KSA9IHBhcnNlci5wYXJzZV9hcmdz
+KGFyZ3MpCiAgICAgICAgc2VsZi5fY2hlY2tfc291cmNlX3ZlcnNpb24oY29uZmlnLCBvcHRpb25z
+KQogICAgICAgIGRlZiBfZG9fZG93bmxvYWQoY29uZmlndXJhdGlvbiwgbW9kdWxlLCBlbnYpOgog
+ICAgICAgICAgICByZXR1cm4gbW9kdWxlLmRvd25sb2FkKGVudikKICAgICAgICBzZWxmLl9kb19v
+cGVyYXRpb24oY29uZmlnLCBvcHRpb25zLCBfZG9fZG93bmxvYWQpCgogICAgZGVmIF91cGRhdGUo
+c2VsZixjb25maWcsYXJncyk6CiAgICAgICAgcGFyc2VyID0gc2VsZi5fb3B0aW9uX3BhcnNlcign
+dXBkYXRlJykKICAgICAgICAob3B0aW9ucywgYXJnc19sZWZ0KSA9IHBhcnNlci5wYXJzZV9hcmdz
+KGFyZ3MpCiAgICAgICAgc2VsZi5fY2hlY2tfc291cmNlX3ZlcnNpb24oY29uZmlnLCBvcHRpb25z
+KQogICAgICAgIGRlZiBfZG9fdXBkYXRlKGNvbmZpZ3VyYXRpb24sIG1vZHVsZSwgZW52KToKICAg
+ICAgICAgICAgcmV0dXJuIG1vZHVsZS51cGRhdGUoZW52KQogICAgICAgIHNlbGYuX2RvX29wZXJh
+dGlvbihjb25maWcsIG9wdGlvbnMsIF9kb191cGRhdGUpCgogICAgZGVmIF9jaGVja19idWlsZF92
+ZXJzaW9uKHNlbGYsIGNvbmZpZywgb3B0aW9ucyk6CiAgICAgICAgZGVmIF9kb19jaGVjayhjb25m
+aWd1cmF0aW9uLCBtb2R1bGUsIGVudik6CiAgICAgICAgICAgIGlmIG5vdCBtb2R1bGUuY2hlY2tf
+YnVpbGRfdmVyc2lvbihlbnYpOgogICAgICAgICAgICAgICAgc2VsZi5fZXJyb3IoJ0NvdWxkIG5v
+dCBmaW5kIGJ1aWxkIHRvb2wgZm9yIG1vZHVsZSAiJXMiJyAlIG1vZHVsZS5uYW1lKCkpCiAgICAg
+ICAgICAgIHJldHVybiBUcnVlCiAgICAgICAgc2VsZi5fZG9fb3BlcmF0aW9uKGNvbmZpZywgb3B0
+aW9ucywgX2RvX2NoZWNrKQoKICAgIGRlZiBfY2hlY2tfc291cmNlX3ZlcnNpb24oc2VsZiwgY29u
+ZmlnLCBvcHRpb25zKToKICAgICAgICBkZWYgX2RvX2NoZWNrKGNvbmZpZ3VyYXRpb24sIG1vZHVs
+ZSwgZW52KToKICAgICAgICAgICAgaWYgbm90IG1vZHVsZS5jaGVja19zb3VyY2VfdmVyc2lvbihl
+bnYpOgogICAgICAgICAgICAgICAgc2VsZi5fZXJyb3IoJ0NvdWxkIG5vdCBmaW5kIHNvdXJjZSB0
+b29sIGZvciBtb2R1bGUgJXMnICUgbW9kdWxlLm5hbWUoKSkKICAgICAgICAgICAgcmV0dXJuIFRy
+dWUKICAgICAgICBzZWxmLl9kb19vcGVyYXRpb24oY29uZmlnLCBvcHRpb25zLCBfZG9fY2hlY2sp
+CgogICAgZGVmIF9jaGVja19zb3VyY2VfY29kZShzZWxmLCBjb25maWcsIG9wdGlvbnMpOgogICAg
+ICAgICMgbGV0J3MgY2hlY2sgdGhhdCB3ZSBoYXZlIGRvd25sb2FkZWQgdGhlIG1hdGNoaW5nIHNv
+dXJjZSBjb2RlCiAgICAgICAgZGVmIF9kb19jaGVjayhjb25maWd1cmF0aW9uLCBtb2R1bGUsIGVu
+dik6CiAgICAgICAgICAgIGlmIG5vdCBtb2R1bGUuaXNfZG93bmxvYWRlZChlbnYpOgogICAgICAg
+ICAgICAgICAgc2VsZi5fZXJyb3IoJ0NvdWxkIG5vdCBmaW5kIHNvdXJjZSBjb2RlIGZvciBtb2R1
+bGUgJXMuIFRyeSAlcyBkb3dubG9hZCBmaXJzdC4nICUgXAogICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgIChtb2R1bGUubmFtZSgpLCBzeXMuYXJndlswXSkpCiAgICAgICAgICAgIHJldHVy
+biBUcnVlCiAgICAgICAgc2VsZi5fZG9fb3BlcmF0aW9uKGNvbmZpZywgb3B0aW9ucywgX2RvX2No
+ZWNrKQoKCiAgICBkZWYgX2J1aWxkKHNlbGYsY29uZmlnLGFyZ3MpOgogICAgICAgIHBhcnNlciA9
+IHNlbGYuX29wdGlvbl9wYXJzZXIoJ2J1aWxkJykKICAgICAgICBwYXJzZXIuYWRkX29wdGlvbign
+LWonLCAnLS1qb2JzJywgaGVscD0nQWxsb3cgTiBqb2JzIGF0IG9uY2UuIERlZmF1bHQgaXMgMS4n
+LAogICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9J2ludCcsIGFjdGlvbj0nc3RvcmUnLCBk
+ZXN0PSdqb2JzJywgZGVmYXVsdD0xKQogICAgICAgIChvcHRpb25zLCBhcmdzX2xlZnQpID0gcGFy
+c2VyLnBhcnNlX2FyZ3MoYXJncykKICAgICAgICBzZWxmLl9jaGVja19zb3VyY2VfY29kZShjb25m
+aWcsIG9wdGlvbnMpCiAgICAgICAgc2VsZi5fY2hlY2tfYnVpbGRfdmVyc2lvbihjb25maWcsIG9w
+dGlvbnMpCiAgICAgICAgZGVmIF9kb19idWlsZChjb25maWd1cmF0aW9uLCBtb2R1bGUsIGVudik6
+CiAgICAgICAgICAgIHJldHZhbCA9IG1vZHVsZS5idWlsZChlbnYsIG9wdGlvbnMuam9icykKICAg
+ICAgICAgICAgaWYgcmV0dmFsOgogICAgICAgICAgICAgICAgbW9kdWxlLnVwZGF0ZV9saWJwYXRo
+KGVudikKICAgICAgICAgICAgcmV0dXJuIHJldHZhbAogICAgICAgIHNlbGYuX2RvX29wZXJhdGlv
+bihjb25maWcsIG9wdGlvbnMsIF9kb19idWlsZCkKCiAgICBkZWYgX2NsZWFuKHNlbGYsIGNvbmZp
+ZywgYXJncyk6CiAgICAgICAgcGFyc2VyID0gc2VsZi5fb3B0aW9uX3BhcnNlcignY2xlYW4nKQog
+ICAgICAgIChvcHRpb25zLCBhcmdzX2xlZnQpID0gcGFyc2VyLnBhcnNlX2FyZ3MoYXJncykKICAg
+ICAgICBzZWxmLl9jaGVja19idWlsZF92ZXJzaW9uKGNvbmZpZywgb3B0aW9ucykKICAgICAgICBk
+ZWYgX2RvX2NsZWFuKGNvbmZpZ3VyYXRpb24sIG1vZHVsZSwgZW52KToKICAgICAgICAgICAgbW9k
+dWxlLmNsZWFuKGVudikKICAgICAgICAgICAgcmV0dXJuIFRydWUKICAgICAgICBzZWxmLl9kb19v
+cGVyYXRpb24oY29uZmlnLCBvcHRpb25zLCBfZG9fY2xlYW4pCgogICAgZGVmIF91bmluc3RhbGwo
+c2VsZiwgY29uZmlnLCBhcmdzKToKICAgICAgICBwYXJzZXIgPSBzZWxmLl9vcHRpb25fcGFyc2Vy
+KCd1bmluc3RhbGwnKQogICAgICAgIChvcHRpb25zLCBhcmdzX2xlZnQpID0gcGFyc2VyLnBhcnNl
+X2FyZ3MoYXJncykKICAgICAgICBkZWYgX2RvX3VuaW5zdGFsbChjb25maWd1cmF0aW9uLCBtb2R1
+bGUsIGVudik6CiAgICAgICAgICAgIG1vZHVsZS51bmluc3RhbGwoZW52KQogICAgICAgICAgICBy
+ZXR1cm4gVHJ1ZQogICAgICAgIHNlbGYuX2RvX29wZXJhdGlvbihjb25maWcsIG9wdGlvbnMsIF9k
+b191bmluc3RhbGwpCgogICAgZGVmIF9zaGVsbChzZWxmLCBjb25maWcsIGFyZ3MpOgogICAgICAg
+IHBhcnNlciA9IHNlbGYuX29wdGlvbl9wYXJzZXIoJ2J1aWxkJykKICAgICAgICAob3B0aW9ucywg
+YXJnc19sZWZ0KSA9IHBhcnNlci5wYXJzZV9hcmdzKGFyZ3MpCiAgICAgICAgZGVmIF9kb19lbnZf
+dXBkYXRlKGNvbmZpZ3VyYXRpb24sIG1vZHVsZSwgZW52KToKICAgICAgICAgICAgbW9kdWxlLnVw
+ZGF0ZV9saWJwYXRoKGVudikKICAgICAgICAgICAgcmV0dXJuIFRydWUKICAgICAgICBlbnYgPSBz
+ZWxmLl9kb19vcGVyYXRpb24oY29uZmlnLCBvcHRpb25zLCBfZG9fZW52X3VwZGF0ZSkKICAgICAg
+ICBpbXBvcnQgb3MKICAgICAgICBlbnYucnVuKFtvcy5lbnZpcm9uWydTSEVMTCddXSwgZGlyZWN0
+b3J5PWVudi5pbnN0YWxsZGlyLCBpbnRlcmFjdGl2ZSA9IFRydWUpCgogICAgZGVmIF9zaG93X29u
+ZV9idWlsdGluKHNlbGYsIGJ1aWx0aW4sIHN0cmluZywgdmFyaWFibGVzKToKICAgICAgICBpbXBv
+cnQgdGV4dHdyYXAKICAgICAgICBpZiBidWlsdGluLm5hbWUoKSAhPSAnbm9uZSc6CiAgICAgICAg
+ICAgIHByaW50ICclcyAlcycgJSAoc3RyaW5nLCBidWlsdGluLm5hbWUoKSkKICAgICAgICAgICAg
+aWYgdmFyaWFibGVzOgogICAgICAgICAgICAgICAgZm9yIGF0dHJpYnV0ZSBpbiBidWlsdGluKCku
+YXR0cmlidXRlcygpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICcgICAgJXM9JXMnICUgKGF0
+dHJpYnV0ZS5uYW1lLCBhdHRyaWJ1dGUudmFsdWUpCiAgICAgICAgICAgICAgICAgICAgbGluZXMg
+PSBbJyAgICAgICVzJyAlIGxpbmUgZm9yIGxpbmUgaW4gdGV4dHdyYXAud3JhcChhdHRyaWJ1dGUu
+aGVscCldCiAgICAgICAgICAgICAgICAgICAgcHJpbnQgJ1xuJy5qb2luKGxpbmVzKQoKICAgIGRl
+ZiBfc2hvd19idWlsdGluKHNlbGYsIGNvbmZpZywgYXJncyk6CiAgICAgICAgZnJvbSBNb2R1bGVT
+b3VyY2UgaW1wb3J0IE1vZHVsZVNvdXJjZQogICAgICAgIGZyb20gTW9kdWxlQnVpbGQgaW1wb3J0
+IE1vZHVsZUJ1aWxkCiAgICAgICAgcGFyc2VyID0gT3B0aW9uUGFyc2VyKHVzYWdlPSd1c2FnZTog
+JXByb2cgc2hvdyBbb3B0aW9uc10nKQogICAgICAgIHBhcnNlci5hZGRfb3B0aW9uKCctYScsICct
+LWFsbCcsIGFjdGlvbj0nc3RvcmVfdHJ1ZScsIGRlc3Q9J2FsbCcsIGRlZmF1bHQ9RmFsc2UsCiAg
+ICAgICAgICAgICAgICAgICAgICAgICAgaGVscD0nRGlzcGxheSBhbGwga25vd24gaW5mb3JtYXRp
+b24gYWJvdXQgYnVpbHRpbiBzb3VyY2UgYW5kIGJ1aWxkIGNvbW1hbmRzJykKICAgICAgICBwYXJz
+ZXIuYWRkX29wdGlvbignLS1zb3VyY2UnLCBhY3Rpb249J3N0b3JlX3RydWUnLCBkZXN0PSdzb3Vy
+Y2UnLCBkZWZhdWx0PUZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9J0Rpc3Bs
+YXkgaW5mb3JtYXRpb24gYWJvdXQgYnVpbHRpbiBzb3VyY2UgY29tbWFuZHMnKQogICAgICAgIHBh
+cnNlci5hZGRfb3B0aW9uKCctLWJ1aWxkJywgYWN0aW9uPSdzdG9yZV90cnVlJywgZGVzdD0nYnVp
+bGQnLCBkZWZhdWx0PUZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9J0Rpc3Bs
+YXkgaW5mb3JtYXRpb24gYWJvdXQgYnVpbHRpbiBidWlsZCBjb21tYW5kcycpCiAgICAgICAgcGFy
+c2VyLmFkZF9vcHRpb24oJy0tdmFyaWFibGVzJywgYWN0aW9uPSdzdG9yZV90cnVlJywgZGVzdD0n
+dmFyaWFibGVzJywgZGVmYXVsdD1GYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBoZWxw
+PSdEaXNwbGF5IHZhcmlhYmxlcyBmb3IgYnVpbHRpbiBjb21tYW5kcycpCiAgICAgICAgKG9wdGlv
+bnMsIGFyZ3NfbGVmdCkgPSBwYXJzZXIucGFyc2VfYXJncyhhcmdzKQogICAgICAgIGlmIG9wdGlv
+bnMuYWxsOgogICAgICAgICAgICBvcHRpb25zLnNvdXJjZSA9IFRydWUKICAgICAgICAgICAgb3B0
+aW9ucy5idWlsZCA9IFRydWUKICAgICAgICAgICAgb3B0aW9ucy52YXJpYWJsZXMgPSBUcnVlCiAg
+ICAgICAgaWYgb3B0aW9ucy5zb3VyY2U6CiAgICAgICAgICAgIGZvciBzb3VyY2UgaW4gTW9kdWxl
+U291cmNlLnN1YmNsYXNzZXMoKToKICAgICAgICAgICAgICAgIHNlbGYuX3Nob3dfb25lX2J1aWx0
+aW4oc291cmNlLCAnc291cmNlJywgb3B0aW9ucy52YXJpYWJsZXMpCiAgICAgICAgaWYgb3B0aW9u
+cy5idWlsZDoKICAgICAgICAgICAgZm9yIGJ1aWxkIGluIE1vZHVsZUJ1aWxkLnN1YmNsYXNzZXMo
+KToKICAgICAgICAgICAgICAgIHNlbGYuX3Nob3dfb25lX2J1aWx0aW4oYnVpbGQsICdidWlsZCcs
+IG9wdGlvbnMudmFyaWFibGVzKQoKICAgIGRlZiBfc2hvd192YXJpYWJsZXMoc2VsZiwgbW9kdWxl
+KToKICAgICAgICBzb3VyY2UgPSBtb2R1bGUuZ2V0X3NvdXJjZSgpCiAgICAgICAgaWYgc291cmNl
+LmF0dHJpYnV0ZXMoKToKICAgICAgICAgICAgcHJpbnQgJyAgc291cmNlICVzJyAlIHNvdXJjZS5u
+YW1lKCkKICAgICAgICAgICAgZm9yIGF0dHJpYnV0ZSBpbiBzb3VyY2UuYXR0cmlidXRlcygpOgog
+ICAgICAgICAgICAgICAgcHJpbnQgJyAgICAlcz0lcycgJSAoYXR0cmlidXRlLm5hbWUsIGF0dHJp
+YnV0ZS52YWx1ZSkKICAgICAgICBidWlsZCA9IG1vZHVsZS5nZXRfYnVpbGQoKQogICAgICAgIGlm
+IGJ1aWxkLmF0dHJpYnV0ZXMoKToKICAgICAgICAgICAgcHJpbnQgJyAgYnVpbGQgJXMnICUgYnVp
+bGQubmFtZSgpCiAgICAgICAgICAgIGZvciBhdHRyaWJ1dGUgaW4gYnVpbGQuYXR0cmlidXRlcygp
+OgogICAgICAgICAgICAgICAgcHJpbnQgJyAgICAlcz0lcycgJSAoYXR0cmlidXRlLm5hbWUsIGF0
+dHJpYnV0ZS52YWx1ZSkKCiAgICBkZWYgX3Nob3coc2VsZiwgY29uZmlnLCBhcmdzKToKICAgICAg
+ICBwYXJzZXIgPSBPcHRpb25QYXJzZXIodXNhZ2U9J3VzYWdlOiAlcHJvZyBzaG93IFtvcHRpb25z
+XScpCiAgICAgICAgcGFyc2VyLmFkZF9vcHRpb24oIi1jIiwgIi0tY29uZmZpbGUiLCBhY3Rpb249
+InN0b3JlIiwgdHlwZT0ic3RyaW5nIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdD0i
+YmFrZWNvbmYiLCBkZWZhdWx0PSJiYWtlY29uZi54bWwiLAogICAgICAgICAgICAgICAgICAgICAg
+ICAgIGhlbHA9IlRoZSBCYWtlIG1ldGFkYXRhIGNvbmZpZ3VyYXRpb24gZmlsZSB0byB1c2UgaWYg
+YSBCYWtlIGZpbGUgaXMgIgogICAgICAgICAgICAgICAgICAgICAgICAgICJub3Qgc3BlY2lmaWVk
+LiBEZWZhdWx0OiAlZGVmYXVsdC4iKQogICAgICAgIHBhcnNlci5hZGRfb3B0aW9uKCctYScsICct
+LWFsbCcsIGFjdGlvbj0nc3RvcmVfdHJ1ZScsIGRlc3Q9J2FsbCcsIGRlZmF1bHQ9RmFsc2UsCiAg
+ICAgICAgICAgICAgICAgICAgICAgICAgaGVscD0nRGlzcGxheSBhbGwga25vd24gaW5mb3JtYXRp
+b24gYWJvdXQgY3VycmVudCBjb25maWd1cmF0aW9uJykKICAgICAgICBwYXJzZXIuYWRkX29wdGlv
+bignLS1lbmFibGVkJywgYWN0aW9uPSdzdG9yZV90cnVlJywgZGVzdD0nZW5hYmxlZCcsCiAgICAg
+ICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdD1GYWxzZSwgaGVscD0nRGlzcGxheSBpbmZvcm1h
+dGlvbiBhYm91dCBleGlzdGluZyBlbmFibGVkIG1vZHVsZXMnKQogICAgICAgIHBhcnNlci5hZGRf
+b3B0aW9uKCctLWRpc2FibGVkJywgYWN0aW9uPSdzdG9yZV90cnVlJywgZGVzdD0nZGlzYWJsZWQn
+LAogICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ9RmFsc2UsIGhlbHA9J0Rpc3BsYXkg
+aW5mb3JtYXRpb24gYWJvdXQgZXhpc3RpbmcgZGlzYWJsZWQgbW9kdWxlcycpCiAgICAgICAgcGFy
+c2VyLmFkZF9vcHRpb24oJy0tdmFyaWFibGVzJywgYWN0aW9uPSdzdG9yZV90cnVlJywgZGVzdD0n
+dmFyaWFibGVzJywgZGVmYXVsdD1GYWxzZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaGVs
+cD0nRGlzcGxheSBpbmZvcm1hdGlvbiBvbiB0aGUgdmFyaWFibGVzIHNldCBmb3IgdGhlIG1vZHVs
+ZXMgc2VsZWN0ZWQnKQogICAgICAgIHBhcnNlci5hZGRfb3B0aW9uKCctLXByZWRlZmluZWQnLCBh
+Y3Rpb249J3N0b3JlX3RydWUnLCBkZXN0PSdwcmVkZWZpbmVkJywgZGVmYXVsdD1GYWxzZSwgCiAg
+ICAgICAgICAgICAgICAgICAgICAgICAgaGVscD0nRGlzcGxheSBpbmZvcm1hdGlvbiBvbiB0aGUg
+aXRlbXMgcHJlZGVmaW5lZCcpCiAgICAgICAgcGFyc2VyLmFkZF9vcHRpb24oJy0tZGlyZWN0b3Jp
+ZXMnLCBhY3Rpb249J3N0b3JlX3RydWUnLCBkZXN0PSdkaXJlY3RvcmllcycsIGRlZmF1bHQ9RmFs
+c2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaGVscD0nRGlzcGxheSBpbmZvcm1hdGlvbiBh
+Ym91dCB3aGljaCBkaXJlY3RvcmllcyBoYXZlIGJlZW4gY29uZmlndXJlZCcpCiAgICAgICAgKG9w
+dGlvbnMsIGFyZ3NfbGVmdCkgPSBwYXJzZXIucGFyc2VfYXJncyhhcmdzKQogICAgICAgIGltcG9y
+dCBvcwogICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKGNvbmZpZyk6CiAgICAgICAgICAgIGNvbmZp
+Z3VyYXRpb24gPSBzZWxmLl9yZWFkX2NvbmZpZyhjb25maWcpCiAgICAgICAgZWxzZToKICAgICAg
+ICAgICAgY29uZmlndXJhdGlvbiA9IENvbmZpZ3VyYXRpb24oY29uZmlnKQogICAgICAgICAgICBj
+b25maWd1cmF0aW9uLnJlYWRfbWV0YWRhdGEob3B0aW9ucy5iYWtlY29uZikKICAgICAgICBpZiBv
+cHRpb25zLmFsbDoKICAgICAgICAgICAgb3B0aW9ucy5lbmFibGVkID0gVHJ1ZQogICAgICAgICAg
+ICBvcHRpb25zLmRpc2FibGVkID0gVHJ1ZQogICAgICAgICAgICBvcHRpb25zLmRpcmVjdG9yaWVz
+ID0gVHJ1ZQogICAgICAgICAgICBvcHRpb25zLnZhcmlhYmxlcyA9IFRydWUKICAgICAgICAgICAg
+b3B0aW9ucy5wcmVkZWZpbmVkID0gVHJ1ZQogICAgICAgIGlmIG9wdGlvbnMuZGlyZWN0b3JpZXM6
+CiAgICAgICAgICAgIHByaW50ICdpbnN0YWxsZGlyICAgOiAnICsgY29uZmlndXJhdGlvbi5jb21w
+dXRlX2luc3RhbGxkaXIoKQogICAgICAgICAgICBwcmludCAnc291cmNlZGlyICAgIDogJyArIGNv
+bmZpZ3VyYXRpb24uY29tcHV0ZV9zb3VyY2VkaXIoKQogICAgICAgICAgICBwcmludCAnb2JqZGly
+ICAgICAgIDogJyArIGNvbmZpZ3VyYXRpb24uZ2V0X29iamRpcigpCgogICAgICAgIGVuYWJsZWQg
+PSBbXQogICAgICAgIGRlZiBfaXRlcmF0b3IobW9kdWxlKToKICAgICAgICAgICAgZW5hYmxlZC5h
+cHBlbmQobW9kdWxlKQogICAgICAgICAgICByZXR1cm4gVHJ1ZQogICAgICAgIHNlbGYuX2l0ZXJh
+dGUoY29uZmlndXJhdGlvbiwgX2l0ZXJhdG9yLCBjb25maWd1cmF0aW9uLmVuYWJsZWQoKSkKICAg
+ICAgICBkaXNhYmxlZCA9IGZpbHRlcihsYW1iZGEgbW9kdWxlOiBub3QgbW9kdWxlIGluIGVuYWJs
+ZWQsIGNvbmZpZ3VyYXRpb24ubW9kdWxlcygpKQoKICAgICAgICBpZiBvcHRpb25zLmVuYWJsZWQ6
+CiAgICAgICAgICAgIGZvciBtb2R1bGUgaW4gZW5hYmxlZDoKICAgICAgICAgICAgICAgIHByaW50
+ICdtb2R1bGU6ICVzIChlbmFibGVkKScgJSBtb2R1bGUubmFtZSgpCiAgICAgICAgICAgICAgICBp
+ZiBvcHRpb25zLnZhcmlhYmxlczoKICAgICAgICAgICAgICAgICAgICBzZWxmLl9zaG93X3Zhcmlh
+Ymxlcyhtb2R1bGUpCiAgICAgICAgaWYgb3B0aW9ucy5kaXNhYmxlZDoKICAgICAgICAgICAgZm9y
+IG1vZHVsZSBpbiBkaXNhYmxlZDoKICAgICAgICAgICAgICAgIHByaW50ICdtb2R1bGU6ICVzIChk
+aXNhYmxlZCknICUgbW9kdWxlLm5hbWUoKQogICAgICAgICAgICAgICAgaWYgb3B0aW9ucy52YXJp
+YWJsZXM6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fc2hvd192YXJpYWJsZXMobW9kdWxlKQoK
+ICAgIGRlZiBtYWluKHNlbGYsIGFyZ3YpOgogICAgICAgIHBhcnNlciA9IE15T3B0aW9uUGFyc2Vy
+KHVzYWdlID0gJ3VzYWdlOiAlcHJvZyBbb3B0aW9uc10gY29tbWFuZCBbY29tbWFuZCBvcHRpb25z
+XScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAiIiJXaGVy
+ZSBjb21tYW5kIGlzIG9uZSBvZjoKICBjb25maWd1cmUgICAgOiBTZXR1cCB0aGUgYnVpbGQgY29u
+ZmlndXJhdGlvbiAoc291cmNlLCBidWlsZCwgaW5zdGFsbCBkaXJlY3RvcnksCiAgICAgICAgICAg
+ICAgICAgYW5kIHBlci1tb2R1bGUgYnVpbGQgb3B0aW9ucykgZnJvbSB0aGUgbW9kdWxlIGRlc2Ny
+aXB0aW9ucwogIHJlY29uZmlndXJlICA6IFVwZGF0ZSB0aGUgYnVpbGQgY29uZmlndXJhdGlvbiBm
+cm9tIGEgbmV3ZXIgbW9kdWxlIGRlc2NyaXB0aW9uCiAgZG93bmxvYWQgICAgIDogRG93bmxvYWQg
+YWxsIG1vZHVsZXMgZW5hYmxlZCBkdXJpbmcgY29uZmlndXJlCiAgdXBkYXRlICAgICAgIDogVXBk
+YXRlIHRoZSBzb3VyY2UgdHJlZSBvZiBhbGwgbW9kdWxlcyBlbmFibGVkIGR1cmluZyBjb25maWd1
+cmUKICBidWlsZCAgICAgICAgOiBCdWlsZCBhbGwgbW9kdWxlcyBlbmFibGVkIGR1cmluZyBjb25m
+aWd1cmUKICBjbGVhbiAgICAgICAgOiBDbGVhbnVwIHRoZSBzb3VyY2UgdHJlZSBvZiBhbGwgbW9k
+dWxlcyBidWlsdCBwcmV2aW91c2x5CiAgc2hlbGwgICAgICAgIDogU3RhcnQgYSBzaGVsbCBhbmQg
+c2V0dXAgcmVsZXZhbnQgZW52aXJvbm1lbnQgdmFyaWFibGVzCiAgdW5pbnN0YWxsICAgIDogUmVt
+b3ZlIGFsbCBmaWxlcyB0aGF0IHdlcmUgaW5zdGFsbGVkIGR1cmluZyBidWlsZAogIHNob3cgICAg
+ICAgICA6IFJlcG9ydCBvbiBidWlsZCBjb25maWd1cmF0aW9uCiAgc2hvdy1idWlsdGluIDogUmVw
+b3J0IG9uIGJ1aWx0aW4gc291cmNlIGFuZCBidWlsZCBjb21tYW5kcwoKVG8gZ2V0IG1vcmUgaGVs
+cCBhYm91dCBlYWNoIGNvbW1hbmQsIHRyeToKICAlcyBjb21tYW5kIC0taGVscAoiIiIpCiAgICAg
+ICAgcGFyc2VyLmFkZF9vcHRpb24oIi1mIiwgIi0tZmlsZSIsIGFjdGlvbj0ic3RvcmUiLCB0eXBl
+PSJzdHJpbmciLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0PSJjb25maWdfZmlsZSIs
+IGRlZmF1bHQ9ImJha2VmaWxlLnhtbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9
+IlRoZSBCYWtlIGZpbGUgdG8gdXNlLiBEZWZhdWx0OiAlZGVmYXVsdC4iKQogICAgICAgIHBhcnNl
+ci5hZGRfb3B0aW9uKCItLWRlYnVnIiwgYWN0aW9uPSJzdG9yZV90cnVlIiwgCiAgICAgICAgICAg
+ICAgICAgICAgICAgICAgZGVzdD0iZGVidWciLCBkZWZhdWx0PUZhbHNlLCAKICAgICAgICAgICAg
+ICAgICAgICAgICAgICBoZWxwPSJTaG91bGQgd2UgZW5hYmxlIGV4dHJhIEJha2UgZGVidWdnaW5n
+IG91dHB1dCA/IikKICAgICAgICBwYXJzZXIuZGlzYWJsZV9pbnRlcnNwZXJzZWRfYXJncygpCiAg
+ICAgICAgKG9wdGlvbnMsIGFyZ3NfbGVmdCkgPSBwYXJzZXIucGFyc2VfYXJncyhhcmd2WzE6XSkK
+ICAgICAgICBpZiBsZW4oYXJnc19sZWZ0KSA9PSAwOgogICAgICAgICAgICBwYXJzZXIucHJpbnRf
+aGVscCgpCiAgICAgICAgICAgIHN5cy5leGl0KDEpCiAgICAgICAgb3BzID0gWyBbJ2NvbmZpZ3Vy
+ZScsIHNlbGYuX2NvbmZpZ3VyZV0sCiAgICAgICAgICAgICAgICBbJ3JlY29uZmlndXJlJywgc2Vs
+Zi5fcmVjb25maWd1cmVdLAogICAgICAgICAgICAgICAgWydkb3dubG9hZCcsIHNlbGYuX2Rvd25s
+b2FkXSwKICAgICAgICAgICAgICAgIFsndXBkYXRlJywgc2VsZi5fdXBkYXRlXSwKICAgICAgICAg
+ICAgICAgIFsnYnVpbGQnLCBzZWxmLl9idWlsZF0sCiAgICAgICAgICAgICAgICBbJ2NsZWFuJywg
+c2VsZi5fY2xlYW5dLAogICAgICAgICAgICAgICAgWydzaGVsbCcsIHNlbGYuX3NoZWxsXSwKICAg
+ICAgICAgICAgICAgIFsndW5pbnN0YWxsJywgc2VsZi5fdW5pbnN0YWxsXSwKICAgICAgICAgICAg
+ICAgIFsnc2hvdycsIHNlbGYuX3Nob3ddLAogICAgICAgICAgICAgICAgWydzaG93LWJ1aWx0aW4n
+LCBzZWxmLl9zaG93X2J1aWx0aW5dCiAgICAgICAgICAgICAgIF0KICAgICAgICBmb3IgbmFtZSwg
+ZnVuY3Rpb24gaW4gb3BzOgogICAgICAgICAgICBpZiBhcmdzX2xlZnRbMF0gPT0gbmFtZToKICAg
+ICAgICAgICAgICAgIGlmIG9wdGlvbnMuZGVidWc6CiAgICAgICAgICAgICAgICAgICAgZnVuY3Rp
+b24oY29uZmlnPW9wdGlvbnMuY29uZmlnX2ZpbGUsIGFyZ3M9YXJnc19sZWZ0WzE6XSkKICAgICAg
+ICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAg
+ICAgICAgICBmdW5jdGlvbihjb25maWc9b3B0aW9ucy5jb25maWdfZmlsZSwgYXJncz1hcmdzX2xl
+ZnRbMTpdKQogICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAg
+ICAgICAgICAgICAgICAgICAgcHJpbnQgZS5tZXNzYWdlCiAgICAgICAgICAgICAgICAgICAgICAg
+IHN5cy5leGl0KDEpClBLAwQUAAAAAADarF8/R0Yq3xwiAAAcIgAAFAAAAGJha2UvTW9kdWxlU291
+cmNlLnB5ZnJvbSBFeGNlcHRpb25zIGltcG9ydCBUYXNrRXJyb3IKaW1wb3J0IFV0aWxzCmZyb20g
+VXRpbHMgaW1wb3J0IE1vZHVsZUF0dHJpYnV0ZUJhc2UKaW1wb3J0IG9zCmltcG9ydCB1cmxwYXJz
+ZQoKY2xhc3MgTW9kdWxlU291cmNlKE1vZHVsZUF0dHJpYnV0ZUJhc2UpOgogICAgZGVmIF9faW5p
+dF9fKHNlbGYpOgogICAgICAgIE1vZHVsZUF0dHJpYnV0ZUJhc2UuX19pbml0X18oc2VsZikKICAg
+IEBjbGFzc21ldGhvZAogICAgZGVmIHN1YmNsYXNzZXMoc2VsZik6CiAgICAgICAgcmV0dXJuIE1v
+ZHVsZVNvdXJjZS5fX3N1YmNsYXNzZXNfXygpCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBjcmVh
+dGUoY2xzLCBuYW1lKToKICAgICAgICBmb3Igc3ViY2xhc3MgaW4gTW9kdWxlU291cmNlLnN1YmNs
+YXNzZXMoKToKICAgICAgICAgICAgaWYgc3ViY2xhc3MubmFtZSgpID09IG5hbWU6CiAgICAgICAg
+ICAgICAgICByZXR1cm4gc3ViY2xhc3MoKQogICAgICAgIHJldHVybiBOb25lCiAgICBkZWYgZGlm
+ZihzZWxmLCBlbnYpOgogICAgICAgIHJhaXNlIE5vdEltcGxlbWVudGVkKCkKICAgIGRlZiBkb3du
+bG9hZChzZWxmLCBlbnYpOgogICAgICAgIHJhaXNlIE5vdEltcGxlbWVudGVkKCkKICAgIGRlZiB1
+cGRhdGUoc2VsZiwgZW52KToKICAgICAgICByYWlzZSBOb3RJbXBsZW1lbnRlZCgpCiAgICBkZWYg
+Y2hlY2tfdmVyc2lvbihzZWxmLCBlbnYpOgogICAgICAgIHJhaXNlIE5vdEltcGxlbWVudGVkKCkK
+CmNsYXNzIE5vbmVNb2R1bGVTb3VyY2UoTW9kdWxlU291cmNlKToKICAgIGRlZiBfX2luaXRfXyhz
+ZWxmKToKICAgICAgICBNb2R1bGVTb3VyY2UuX19pbml0X18oc2VsZikKICAgIEBjbGFzc21ldGhv
+ZAogICAgZGVmIG5hbWUoY2xzKToKICAgICAgICByZXR1cm4gJ25vbmUnCiAgICBkZWYgZGlmZihz
+ZWxmLCBlbnYpOgogICAgICAgIHBhc3MKICAgIGRlZiBkb3dubG9hZChzZWxmLCBlbnYpOgogICAg
+ICAgIHBhc3MKICAgIGRlZiB1cGRhdGUoc2VsZiwgZW52KToKICAgICAgICBwYXNzCiAgICBkZWYg
+Y2hlY2tfdmVyc2lvbihzZWxmLCBlbnYpOgogICAgICAgIHJldHVybiBUcnVlCgpjbGFzcyBJbmxp
+bmVNb2R1bGVTb3VyY2UoTW9kdWxlU291cmNlKToKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAg
+ICAgICBNb2R1bGVTb3VyY2UuX19pbml0X18oc2VsZikKICAgIEBjbGFzc21ldGhvZAogICAgZGVm
+IG5hbWUoY2xzKToKICAgICAgICByZXR1cm4gJ2lubGluZScKCmNsYXNzIEJhemFhck1vZHVsZVNv
+dXJjZShNb2R1bGVTb3VyY2UpOgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIE1vZHVs
+ZVNvdXJjZS5fX2luaXRfXyhzZWxmKQogICAgICAgIHNlbGYuYWRkX2F0dHJpYnV0ZSgndXJsJywg
+JycsICdUaGUgdXJsIHRvIGNsb25lIGZyb20nLAogICAgICAgICAgICAgICAgICAgICAgICAgICBt
+YW5kYXRvcnkgPSBUcnVlKQogICAgICAgIHNlbGYuYWRkX2F0dHJpYnV0ZSgncmV2aXNpb24nLCBO
+b25lLCAnVGhlIHJldmlzaW9uIHRvIHVwZGF0ZSB0byBhZnRlciB0aGUgY2xvbmUuJykKICAgIEBj
+bGFzc21ldGhvZAogICAgZGVmIG5hbWUoY2xzKToKICAgICAgICByZXR1cm4gJ2JhemFhcicKICAg
+IGRlZiBkaWZmKHNlbGYsIGVudik6CiAgICAgICAgcGFzcwogICAgZGVmIGRvd25sb2FkKHNlbGYs
+IGVudik6CiAgICAgICAgcmV2X2FyZyA9IFtdCiAgICAgICAgaWYgbm90IHNlbGYuYXR0cmlidXRl
+KCdyZXZpc2lvbicpLnZhbHVlIGlzIE5vbmU6CiAgICAgICAgICAgIHJldl9hcmcuZXh0ZW5kKFsn
+LXInLCBzZWxmLmF0dHJpYnV0ZSgncmV2aXNpb24nKS52YWx1ZV0pCiAgICAgICAgZW52LnJ1bihb
+J2J6cicsICdjbG9uZSddICsgcmV2X2FyZyArIFtzZWxmLmF0dHJpYnV0ZSgndXJsJykudmFsdWUs
+IGVudi5zcmNkaXJdKQoKICAgIGRlZiB1cGRhdGUoc2VsZiwgZW52KToKICAgICAgICByZXZfYXJn
+ID0gW10KICAgICAgICBpZiBub3Qgc2VsZi5hdHRyaWJ1dGUoJ3JldmlzaW9uJykudmFsdWUgaXMg
+Tm9uZToKICAgICAgICAgICAgcmV2X2FyZy5leHRlbmQoWyctcicsIHNlbGYuYXR0cmlidXRlKCdy
+ZXZpc2lvbicpLnZhbHVlXSkKICAgICAgICBlbnYucnVuKFsnYnpyJywgJ3B1bGwnXSArIHJldl9h
+cmcgKyBbc2VsZi5hdHRyaWJ1dGUoJ3VybCcpLnZhbHVlXSwgZGlyZWN0b3J5ID0gZW52LnNyY2Rp
+cikKICAgIGRlZiBjaGVja192ZXJzaW9uKHNlbGYsIGVudik6CiAgICAgICAgcmV0dXJuIGVudi5j
+aGVja19wcm9ncmFtKCdienInKQoKICAgIApjbGFzcyBNZXJjdXJpYWxNb2R1bGVTb3VyY2UoTW9k
+dWxlU291cmNlKToKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBNb2R1bGVTb3VyY2Uu
+X19pbml0X18oc2VsZikKICAgICAgICBzZWxmLmFkZF9hdHRyaWJ1dGUoJ3VybCcsICcnLCAnVGhl
+IHVybCB0byBjbG9uZSBmcm9tJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hbmRhdG9y
+eSA9IFRydWUpCiAgICAgICAgc2VsZi5hZGRfYXR0cmlidXRlKCdyZXZpc2lvbicsICd0aXAnLCAn
+VGhlIHJldmlzaW9uIHRvIHVwZGF0ZSB0byBhZnRlciB0aGUgY2xvbmUuICcKICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgJ0lmIG5vIHZhbHVlIGlzIHNwZWNpZmllZCwgdGhlIGRlZmF1bHQgaXMg
+InRpcCInKQogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgbmFtZShjbHMpOgogICAgICAgIHJldHVy
+biAnbWVyY3VyaWFsJwogICAgZGVmIGRvd25sb2FkKHNlbGYsIGVudik6CiAgICAgICAgZW52LnJ1
+bihbJ2hnJywgJ2Nsb25lJywgJy1VJywgc2VsZi5hdHRyaWJ1dGUoJ3VybCcpLnZhbHVlLCBlbnYu
+c3JjZGlyXSkKICAgICAgICBlbnYucnVuKFsnaGcnLCAndXBkYXRlJywgJy1yJywgc2VsZi5hdHRy
+aWJ1dGUoJ3JldmlzaW9uJykudmFsdWVdLAogICAgICAgICAgICAgICAgZGlyZWN0b3J5ID0gZW52
+LnNyY2RpcikKICAgIGRlZiB1cGRhdGUoc2VsZiwgZW52KToKICAgICAgICBlbnYucnVuKFsnaGcn
+LCAncHVsbCcsIHNlbGYuYXR0cmlidXRlKCd1cmwnKS52YWx1ZV0sIGRpcmVjdG9yeSA9IGVudi5z
+cmNkaXIpCiAgICAgICAgZW52LnJ1bihbJ2hnJywgJ3VwZGF0ZScsICctcicsIHNlbGYuYXR0cmli
+dXRlKCdyZXZpc2lvbicpLnZhbHVlXSwKICAgICAgICAgICAgICAgIGRpcmVjdG9yeSA9IGVudi5z
+cmNkaXIpCiAgICBkZWYgY2hlY2tfdmVyc2lvbihzZWxmLCBlbnYpOgogICAgICAgIHJldHVybiBl
+bnYuY2hlY2tfcHJvZ3JhbSgnaGcnKQoKICAgICAgICAKY2xhc3MgQXJjaGl2ZU1vZHVsZVNvdXJj
+ZShNb2R1bGVTb3VyY2UpOgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIE1vZHVsZVNv
+dXJjZS5fX2luaXRfXyhzZWxmKQogICAgICAgIHNlbGYuYWRkX2F0dHJpYnV0ZSgndXJsJywgTm9u
+ZSwgJ1RoZSB1cmwgdG8gY2xvbmUgZnJvbScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1h
+bmRhdG9yeSA9IFRydWUpCiAgICAgICAgc2VsZi5hZGRfYXR0cmlidXRlKCdleHRyYWN0X2RpcmVj
+dG9yeScsIE5vbmUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAnVGhlIG5hbWUgb2YgdGhl
+IGRpcmVjdG9yeSB0aGUgc291cmNlIGNvZGUgd2lsbCBiZSBleHRyYWN0ZWQgdG8gbmF0dXJhbGx5
+LicKICAgICAgICAgICAgICAgICAgICAgICAgICAgJyBJZiBubyB2YWx1ZSBpcyBzcGVjaWZpZWQs
+IGRpcmVjdG9yeSBpcyBhc3N1bWVkIHRvIGJlIGVxdWFsIHRvIHRoZSAnCiAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICdvZiB0aGUgYXJjaGl2ZSB3aXRob3V0IHRoZSBmaWxlIGV4dGVuc2lvbi4n
+KQogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgbmFtZShjbHMpOgogICAgICAgIHJldHVybiAnYXJj
+aGl2ZScKICAgIGRlZiBfZGVjb21wcmVzcyhzZWxmLCBmaWxlbmFtZSwgZW52KToKICAgICAgICBp
+bXBvcnQgdGVtcGZpbGUKICAgICAgICBpbXBvcnQgb3MKICAgICAgICB0ZW1wZGlyID0gdGVtcGZp
+bGUubWtkdGVtcChkaXI9ZW52LnNyY3JlcG8pCiAgICAgICAgZXh0ZW5zaW9ucyA9IFsKICAgICAg
+ICAgICAgWyd0YXInLCBbJ3RhcicsICd4ZiddXSwKICAgICAgICAgICAgWyd0YXIuZ3onLCBbJ3Rh
+cicsICd6eGYnXV0sCiAgICAgICAgICAgIFsndGFyLlonLCBbJ3RhcicsICd6eGYnXV0sCiAgICAg
+ICAgICAgIFsndGFyLmJ6MicsIFsndGFyJywgJ2p4ZiddXSwKICAgICAgICAgICAgWyd6aXAnLCBb
+J3VuemlwJ11dLAogICAgICAgICAgICBbJ3JhcicsIFsndW5yYXInLCAnZSddXQogICAgICAgICAg
+ICBdCiAgICAgICAgZm9yIGV4dGVuc2lvbiwgY29tbWFuZCBpbiBleHRlbnNpb25zOgogICAgICAg
+ICAgICBpZiBmaWxlbmFtZS5lbmRzd2l0aChleHRlbnNpb24pOgogICAgICAgICAgICAgICAgZW52
+LnJ1bihjb21tYW5kICsgW2ZpbGVuYW1lXSwgZGlyZWN0b3J5ID0gdGVtcGRpcikKICAgICAgICAg
+ICAgICAgIGlmIHNlbGYuYXR0cmlidXRlKCdleHRyYWN0X2RpcmVjdG9yeScpLnZhbHVlIGlzIG5v
+dCBOb25lOgogICAgICAgICAgICAgICAgICAgIGFjdHVhbF9leHRyYWN0X2RpciA9IHNlbGYuYXR0
+cmlidXRlKCdleHRyYWN0X2RpcmVjdG9yeScpLnZhbHVlCiAgICAgICAgICAgICAgICBlbHNlOgog
+ICAgICAgICAgICAgICAgICAgIGFjdHVhbF9leHRyYWN0X2RpciA9IG9zLnBhdGguYmFzZW5hbWUo
+ZmlsZW5hbWUpWzA6LWxlbihleHRlbnNpb24pLTFdCiAgICAgICAgICAgICAgICAjIGZpbmFsbHks
+IHJlbmFtZSB0aGUgZXh0cmFjdGlvbiBkaXJlY3RvcnkgdG8gdGhlIHRhcmdldCBkaXJlY3Rvcnkg
+bmFtZS4KICAgICAgICAgICAgICAgIG9zLnJlbmFtZShvcy5wYXRoLmpvaW4odGVtcGRpciwgYWN0
+dWFsX2V4dHJhY3RfZGlyKSwgZW52LnNyY2RpcikKICAgICAgICAgICAgICAgIHJldHVybgogICAg
+ICAgIHJhaXNlIFRhc2tFcnJvcignVW5rbm93biBBcmNoaXZlIFR5cGUnKQoKICAgIGRlZiBkb3du
+bG9hZChzZWxmLCBlbnYpOgogICAgICAgIGltcG9ydCB1cmxsaWIKICAgICAgICBpbXBvcnQgdXJs
+cGFyc2UKICAgICAgICBpbXBvcnQgb3MKICAgICAgICBmaWxlbmFtZSA9IG9zLnBhdGguYmFzZW5h
+bWUodXJscGFyc2UudXJscGFyc2Uoc2VsZi5hdHRyaWJ1dGUoJ3VybCcpLnZhbHVlKS5wYXRoKQog
+ICAgICAgIHRtcGZpbGUgPSBvcy5wYXRoLmpvaW4oZW52LnNyY3JlcG8sIGZpbGVuYW1lKQogICAg
+ICAgIHVybGxpYi51cmxyZXRyaWV2ZShzZWxmLmF0dHJpYnV0ZSgndXJsJykudmFsdWUsIGZpbGVu
+YW1lPXRtcGZpbGUpCiAgICAgICAgc2VsZi5fZGVjb21wcmVzcyh0bXBmaWxlLCBlbnYpCiAgICAg
+ICAgCiAgICBkZWYgdXBkYXRlKHNlbGYsIGVudik6CiAgICAgICAgIyB3ZSByZWFsbHkgaGF2ZSBu
+b3RoaW5nIHRvIGRvIGZvciBhcmNoaXZlcy4gCiAgICAgICAgcGFzcwoKICAgIGRlZiBjaGVja192
+ZXJzaW9uKHNlbGYsIGVudik6CiAgICAgICAgZXh0ZW5zaW9ucyA9IFsKICAgICAgICAgICAgWyd0
+YXInLCAndGFyJ10sCiAgICAgICAgICAgIFsndGFyLmd6JywgJ3RhciddLAogICAgICAgICAgICBb
+J3Rhci5aJywgJ3RhciddLAogICAgICAgICAgICBbJ3Rhci5iejInLCAndGFyJ10sCiAgICAgICAg
+ICAgIFsnemlwJywgJ3VuemlwJ10sCiAgICAgICAgICAgIFsncmFyJywgJ3VucmFyJ10KICAgICAg
+ICAgICAgXQogICAgICAgIGZpbGVuYW1lID0gb3MucGF0aC5iYXNlbmFtZSh1cmxwYXJzZS51cmxw
+YXJzZShzZWxmLmF0dHJpYnV0ZSgndXJsJykudmFsdWUpLnBhdGgpCiAgICAgICAgZm9yIGV4dGVu
+c2lvbixwcm9ncmFtIGluIGV4dGVuc2lvbnM6CiAgICAgICAgICAgIGlmIGZpbGVuYW1lLmVuZHN3
+aXRoKGV4dGVuc2lvbik6CiAgICAgICAgICAgICAgICByZXR1cm4gZW52LmNoZWNrX3Byb2dyYW0o
+cHJvZ3JhbSkKICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICAKY2xhc3MgQ3ZzTW9kdWxlU291
+cmNlKE1vZHVsZVNvdXJjZSk6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgTW9kdWxl
+U291cmNlLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5hZGRfYXR0cmlidXRlKCdyb290Jywg
+JycsICdSZXBvc2l0b3J5IHJvb3Qgc3BlY2lmaWNhdGlvbiB0byBjaGVja291dCBmcm9tLicsCiAg
+ICAgICAgICAgICAgICAgICAgICAgICAgIG1hbmRhdG9yeSA9IFRydWUpCiAgICAgICAgc2VsZi5h
+ZGRfYXR0cmlidXRlKCdtb2R1bGUnLCAnJywgJ01vZHVsZSB0byBjaGVja291dC4nLCBtYW5kYXRv
+cnkgPSBUcnVlKQogICAgICAgIHNlbGYuYWRkX2F0dHJpYnV0ZSgnY2hlY2tvdXRfZGlyZWN0b3J5
+JywgTm9uZSwgJ05hbWUgb2YgZGlyZWN0b3J5IGNoZWNrb3V0IGRlZmF1bHRzIHRvLiAnCiAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICdJZiB1bnNwZWNpZmllZCwgZGVmYXVsdHMgdG8gdGhlIG5h
+bWUgb2YgdGhlIG1vZHVsZSBiZWluZyBjaGVja2VkIG91dC4nKQogICAgICAgIHNlbGYuYWRkX2F0
+dHJpYnV0ZSgnZGF0ZScsIE5vbmUsICdEYXRlIHRvIGNoZWNrb3V0JykKCiAgICBAY2xhc3NtZXRo
+b2QKICAgIGRlZiBuYW1lKGNscyk6CiAgICAgICAgcmV0dXJuICdjdnMnCiAgICBkZWYgZG93bmxv
+YWQoc2VsZiwgZW52KToKICAgICAgICBpbXBvcnQgdGVtcGZpbGUKICAgICAgICB0ZW1wZGlyID0g
+dGVtcGZpbGUubWtkdGVtcChkaXI9ZW52LnNyY3JlcG8pCiAgICAgICAgZW52LnJ1bihbJ2N2cycs
+ICctZCcsIHNlbGYuYXR0cmlidXRlKCdyb290JykudmFsdWUsICdsb2dpbiddLCAKICAgICAgICAg
+ICAgICAgIGRpcmVjdG9yeSA9IHRlbXBkaXIpCiAgICAgICAgY2hlY2tvdXRfb3B0aW9ucyA9IFtd
+CiAgICAgICAgaWYgbm90IHNlbGYuYXR0cmlidXRlKCdkYXRlJykudmFsdWUgaXMgTm9uZToKICAg
+ICAgICAgICAgY2hlY2tvdXRfb3B0aW9ucy5leHRlbmQoWyctRCcsIHNlbGYuYXR0cmlidXRlKCdk
+YXRlJykudmFsdWVdKQogICAgICAgIGVudi5ydW4oWydjdnMnLCAnLWQnLCBzZWxmLmF0dHJpYnV0
+ZSgncm9vdCcpLnZhbHVlLCAnY2hlY2tvdXQnXSArIGNoZWNrb3V0X29wdGlvbnMgKwogICAgICAg
+ICAgICAgICAgW3NlbGYuYXR0cmlidXRlKCdtb2R1bGUnKS52YWx1ZV0sCiAgICAgICAgICAgICAg
+ICBkaXJlY3RvcnkgPSB0ZW1wZGlyKQogICAgICAgIGlmIHNlbGYuYXR0cmlidXRlKCdjaGVja291
+dF9kaXJlY3RvcnknKS52YWx1ZSBpcyBub3QgTm9uZToKICAgICAgICAgICAgYWN0dWFsX2NoZWNr
+b3V0X2RpciA9IHNlbGYuYXR0cmlidXRlKCdjaGVja291dF9kaXJlY3RvcnknKS52YWx1ZQogICAg
+ICAgIGVsc2U6CiAgICAgICAgICAgIGFjdHVhbF9jaGVja291dF9kaXIgPSBzZWxmLmF0dHJpYnV0
+ZSgnbW9kdWxlJykudmFsdWUKICAgICAgICBpbXBvcnQgb3MKICAgICAgICBvcy5yZW5hbWUob3Mu
+cGF0aC5qb2luKHRlbXBkaXIsIGFjdHVhbF9jaGVja291dF9kaXIpLCBlbnYuc3JjZGlyKQoKICAg
+IGRlZiB1cGRhdGUoc2VsZiwgZW52KToKICAgICAgICBlbnYucnVuKFsnY3ZzJywgJ3VwJ10sIGRp
+cmVjdG9yeSA9IGVudi5zcmNkaXIpCiAgICBkZWYgY2hlY2tfdmVyc2lvbihzZWxmLCBlbnYpOgog
+ICAgICAgIHJldHVybiBlbnYuY2hlY2tfcHJvZ3JhbSgnY3ZzJykKCmNsYXNzIEdpdE1vZHVsZVNv
+dXJjZShNb2R1bGVTb3VyY2UpOgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIE1vZHVs
+ZVNvdXJjZS5fX2luaXRfXyhzZWxmKQogICAgICAgIHNlbGYuYWRkX2F0dHJpYnV0ZSgndXJsJywg
+JycsICdVcmwgdG8gY2xvbmUgdGhlIHNvdXJjZSB0cmVlIGZyb20uJywKICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgbWFuZGF0b3J5ID0gVHJ1ZSkKICAgICAgICBzZWxmLmFkZF9hdHRyaWJ1dGUo
+J3JldmlzaW9uJywgJ3JlZnMvcmVtb3Rlcy9vcmlnaW4vbWFzdGVyJywgCiAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICdSZXZpc2lvbiB0byBjaGVja291dC4gRGVmYXVsdHMgdG8gb3JpZ2luL21h
+c3RlciByZWZlcmVuY2UuJykKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIG5hbWUoY2xzKToKICAg
+ICAgICByZXR1cm4gJ2dpdCcKICAgIGRlZiBkb3dubG9hZChzZWxmLCBlbnYpOgogICAgICAgIGlt
+cG9ydCB0ZW1wZmlsZQogICAgICAgIGltcG9ydCBvcwogICAgICAgIHRlbXBkaXIgPSB0ZW1wZmls
+ZS5ta2R0ZW1wKGRpcj1lbnYuc3JjcmVwbykKICAgICAgICBlbnYucnVuKFsnZ2l0JywgJ2luaXQn
+XSwgZGlyZWN0b3J5ID0gdGVtcGRpcikKICAgICAgICBlbnYucnVuKFsnZ2l0JywgJ3JlbW90ZScs
+ICdhZGQnLCAnb3JpZ2luJywgc2VsZi5hdHRyaWJ1dGUoJ3VybCcpLnZhbHVlXSwgCiAgICAgICAg
+ICAgICAgICBkaXJlY3RvcnkgPSB0ZW1wZGlyKQogICAgICAgIGVudi5ydW4oWydnaXQnLCAnZmV0
+Y2gnXSwgCiAgICAgICAgICAgICAgICBkaXJlY3RvcnkgPSB0ZW1wZGlyKQogICAgICAgIGVudi5y
+dW4oWydnaXQnLCAnY2hlY2tvdXQnLCBzZWxmLmF0dHJpYnV0ZSgncmV2aXNpb24nKS52YWx1ZV0s
+CiAgICAgICAgICAgICAgICBkaXJlY3RvcnkgPSB0ZW1wZGlyKQogICAgICAgIG9zLnJlbmFtZSh0
+ZW1wZGlyLCBlbnYuc3JjZGlyKQoKICAgIGRlZiB1cGRhdGUoc2VsZiwgZW52KToKICAgICAgICBl
+bnYucnVuKFsnZ2l0JywgJ2ZldGNoJ10sIGRpcmVjdG9yeSA9IGVudi5zcmNkaXIpCiAgICAgICAg
+ZW52LnJ1bihbJ2dpdCcsICdjaGVja291dCcsIHNlbGYuYXR0cmlidXRlKCdyZXZpc2lvbicpLnZh
+bHVlXSwKICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RvcnkgPSBlbnYuc3JjZGlyKQoK
+ICAgIGRlZiBjaGVja192ZXJzaW9uKHNlbGYsIGVudik6CiAgICAgICAgcmV0dXJuIGVudi5jaGVj
+a19wcm9ncmFtKCdnaXQnKQpQSwMEFAAAAAAAj2V1Ptt4miGoJAAAqCQAABQAAABiYWtlL0RlcGVu
+ZGVuY2llcy5weSMgVGhlIHB1cnBvc2Ugb2YgdGhpcyBjbGFzcyBpcyB0byBjYXB0dXJlIGEgc2V0
+IG9mIGRlcGVuZGVuY2llcwojIGJldHdlZW4gYSBzZXQgb2Ygb2JqZWN0cy4gVGhlIGlkZWEgaXMg
+dGhhdCB5b3UgaGF2ZSBhIHNldCBvZiAndGFyZ2V0cycKIyB3aGljaCBkZXBlbmQgb24gYSBzZXQg
+b2Ygc291cmNlcy4gRWFjaCB0YXJnZXQgY2FuIGJlIHRoZSBzb3VyY2Ugb2YgYW5vdGhlcgojIHRh
+cmdldC4gVGhlcmUgbWlnaHQgYmUgY3ljbGVzIGJ1dCBpdCdzIGEgYnVnIGFuZCB3ZSBuZWVkIHRv
+IGRldGVjdCBpdC4KIwojIE9uY2Ugd2UgaGF2ZSBhbGwgZGVwZW5kZW5jaWVzLCB3ZSBuZWVkIHRv
+ICdyZXNvbHZlJyB0aGVtLiBUaGlzIG1lYW5zCiMgdGhhdCB3ZSBuZWVkIHRvIGl0ZXJhdGUgb3Zl
+ciBhbGwgdGFyZ2V0cyBhbmQgaW52b2tlIGEgdXNlci1wcm92aWRlZAojIGNhbGxiYWNrIG9uIGVh
+Y2ggdGFyZ2V0LiBUaGUgdHJpY2t5IHRoaW5nIGhlcmUgaXMgdGhhdCB0aGUgdXNlci1wcm92aWRl
+ZAojIGNhbGxiYWNrIGlzIGFsbG93ZWQgdG8gcmVjdXJzaXZlbHkgYWRkIG5ldyBhcmJpdHJhcnkg
+ZGVwZW5kZW5jaWVzLCBldmVuCiMgdG8gdGFyZ2V0cyB3aGljaCBoYXZlIGFscmVhZHkgYmVlbiAn
+cmVzb2x2ZWQnIHNvLCB3ZSBuZWVkIHRvIGJlIGNhcmVmdWwKIyB0byByZS1yZXNvbHZlIHRoZSB0
+YXJnZXRzIHRvIHdoaWNoIGRlcGVuZGVuY2llcyBoYXZlIGJlZW4gcmVjdXJzaXZlbHkgCiMgYWRk
+ZWQuCgppbXBvcnQgY29weQoKY2xhc3MgQ3ljbGVEZXRlY3RlZDoKICAgIGRlZiBfX2luaXRfXyhz
+ZWxmKToKICAgICAgICByZXR1cm4KCmNsYXNzIERlcGVuZGVuY3lVbm1ldDoKICAgIGRlZiBfX2lu
+aXRfXyhzZWxmLCBmYWlsZWQpOgogICAgICAgIHNlbGYuX2ZhaWxlZCA9IGZhaWxlZAogICAgZGVm
+IGZhaWxlZChzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fZmFpbGVkCgpjbGFzcyBUYXJnZXQ6
+CiAgICBkZWYgX19pbml0X18oc2VsZiwgZHN0LCBjb250ZXh0KToKICAgICAgICBzZWxmLl9kc3Qg
+PSBkc3QKICAgICAgICBzZWxmLl9zcmMgPSBbXQogICAgICAgIHNlbGYuX29wdGlvbmFsID0gZGlj
+dCgpCiAgICAgICAgc2VsZi5fY29udGV4dCA9IGNvbnRleHQKICAgICAgICBzZWxmLl9kaXJ0eSA9
+IFRydWUKICAgIGRlZiBpc19kaXJ0eShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fZGlydHkK
+ICAgIGRlZiBkaXJ0eShzZWxmKToKICAgICAgICBzZWxmLl9kaXJ0eSA9IFRydWUKICAgIGRlZiBj
+bGVhbihzZWxmKToKICAgICAgICBzZWxmLl9kaXJ0eSA9IEZhbHNlCiAgICBkZWYgYWRkX3NyYyhz
+ZWxmLCBzcmMsIG9wdGlvbmFsKToKICAgICAgICBhc3NlcnQgc3JjIG5vdCBpbiBzZWxmLl9zcmMK
+ICAgICAgICBzZWxmLl9zcmMuYXBwZW5kKHNyYykKICAgICAgICBzZWxmLl9vcHRpb25hbFtzcmNd
+ID0gb3B0aW9uYWwKICAgIGRlZiBkc3Qoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX2RzdAog
+ICAgZGVmIHNyYyhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fc3JjCiAgICBkZWYgaXNfc3Jj
+X29wdGlvbmFsKHNlbGYsc3JjKToKICAgICAgICBhc3NlcnQgc2VsZi5fb3B0aW9uYWwuaGFzX2tl
+eShzcmMpCiAgICAgICAgcmV0dXJuIHNlbGYuX29wdGlvbmFsW3NyY10KICAgIGRlZiBjb250ZXh0
+KHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9jb250ZXh0CgpjbGFzcyBEZXBlbmRlbmNpZXM6
+CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgIyBhIGRpY3Rpb25uYXJ5IHRoYXQgbWFw
+cyBhIHN0cmluZyAoa2V5KSB0byB0aGUgb25seSBpbnN0YW5jZQogICAgICAgICMgb2YgdGhlIGNs
+YXNzIFRhcmdldCB0aGF0IGhhcyB0aGlzIHN0cmluZyBhcyBpdHMgdGFyZ2V0LgogICAgICAgIHNl
+bGYuX3RhcmdldHMgPSBkaWN0KCkKICAgICAgICAjIGEgZGljdGlvbm5hcnkgdGhhdCBtYXBzIGEg
+c3RyaW5nIChrZXkpIHRvIHRoZSBsaXN0IG9mIAogICAgICAgICMgaW5zdGFuY2VzIG9mIHRoZSBj
+bGFzcyBUYXJnZXQgdGhhdCBoYXZlIHRoaXMgc3RyaW5nIGluIHRoZWlyCiAgICAgICAgIyBzb3Vy
+Y2UgbGlzdAogICAgICAgIHNlbGYuX3NvdXJjZXMgPSBkaWN0KCkKICAgICAgICAjIHRoZSBsaXN0
+IG9mIGFsbCBpdGVtcyAKICAgICAgICBzZWxmLl9pdGVtcyA9IFtdCiAgICAgICAgIyBBcmUgd2Ug
+Y3VycmVudGx5IGV4ZWN1dGluZyB0aGUgcmVzb2x2ZSBtZXRob2QuID8KICAgICAgICBzZWxmLl9y
+ZXNvbHZpbmcgPSBGYWxzZQogICAgICAgICMgaXMgdGhlcmUgYW55IHRhcmdldCB0aGF0IGlzIGRp
+cnR5ID8KICAgICAgICBzZWxmLl9kaXJ0eSA9IEZhbHNlCiAgICBkZWYgYWRkX2RzdChzZWxmLCBk
+c3QsIGNvbnRleHQgPSBOb25lKToKICAgICAgICBpZiBpc2luc3RhbmNlKGRzdCxsaXN0KToKICAg
+ICAgICAgICAgcmV0dXJuIFtzZWxmLmFkZF9kc3QoZCxjb250ZXh0KSBmb3IgZCBpbiBkc3RdCiAg
+ICAgICAgIyB0aGUgZGVwZW5kZW5jeSBpcyBhbHJlYWR5IHJlY29yZGVkLiBub3RoaW5nIHRvIGRv
+LgogICAgICAgIGlmIHNlbGYuX3RhcmdldHMuaGFzX2tleShkc3QpOgogICAgICAgICAgICByZXR1
+cm4KICAgICAgICAjIHVwZGF0ZSBkZXBlbmRlbmN5IGluZm9ybWF0aW9uCiAgICAgICAgdGFyZ2V0
+ID0gVGFyZ2V0KGRzdCwgY29udGV4dCkKICAgICAgICBzZWxmLl90YXJnZXRzW2RzdF0gPSB0YXJn
+ZXQKICAgICAgICAjIG1hcmsgZGlydHkgdGFyZ2V0IGFuZCBpdHMgZGVwZW5kaW5nIHRhcmdldHMK
+ICAgICAgICBzZWxmLl91cGRhdGVfZGlydHkodGFyZ2V0KQoKICAgIGRlZiBhZGRfZGVwKHNlbGYs
+IHNyYywgZHN0LCBvcHRpb25hbCA9IEZhbHNlKToKICAgICAgICBpZiBpc2luc3RhbmNlKHNyYyxs
+aXN0KToKICAgICAgICAgICAgcmV0dXJuIFtzZWxmLmFkZF9kZXAocyxkc3QpIGZvciBzIGluIHNy
+Y10KICAgICAgICBhc3NlcnQgc2VsZi5fdGFyZ2V0cy5oYXNfa2V5KGRzdCkKICAgICAgICAjIHRo
+ZSBkZXBlbmRlbmN5IGlzIGFscmVhZHkgcmVjb3JkZWQuIG5vdGhpbmcgdG8gZG8uCiAgICAgICAg
+dGFyZ2V0ID0gc2VsZi5fdGFyZ2V0c1tkc3RdCiAgICAgICAgaWYgc3JjIGluIHRhcmdldC5zcmMg
+KCk6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICAjIHJlY29yZCBuZXcgZGVwZW5kZW5jeQog
+ICAgICAgIHRhcmdldCA9IHNlbGYuX3RhcmdldHNbZHN0XQogICAgICAgIHRhcmdldC5hZGRfc3Jj
+KHNyYywgb3B0aW9uYWwpCiAgICAgICAgaWYgbm90IHNlbGYuX3NvdXJjZXMuaGFzX2tleShzcmMp
+OgogICAgICAgICAgICBzZWxmLl9zb3VyY2VzW3NyY10gPSBbdGFyZ2V0XQogICAgICAgIGVsaWYg
+dGFyZ2V0IG5vdCBpbiBzZWxmLl9zb3VyY2VzW3NyY106CiAgICAgICAgICAgIHNlbGYuX3NvdXJj
+ZXNbc3JjXS5hcHBlbmQodGFyZ2V0KQoKICAgICAgICAjIG1hcmsgZGlydHkgdGFyZ2V0IGFuZCBp
+dHMgZGVwZW5kaW5nIHRhcmdldHMKICAgICAgICBzZWxmLl91cGRhdGVfZGlydHkodGFyZ2V0KQoK
+ICAgIGRlZiBkdW1wKHNlbGYsZixkb3Q9VHJ1ZSk6CiAgICAgICAgZi53cml0ZSgnZGlncmFwaCB7
+XG4nKQogICAgICAgIGZvciB0YXJnZXQgaW4gc2VsZi5fdGFyZ2V0cy52YWx1ZXMoKToKICAgICAg
+ICAgICAgZm9yIHNyYyBpbiB0YXJnZXQuc3JjICgpOgogICAgICAgICAgICAgICAgZi53cml0ZSgn
+IicgKyBzcmMgKyAnIiAtPiAiJyArIHRhcmdldC5kc3QoKSArICciO1xuJykKICAgICAgICBmLndy
+aXRlKCd9JykKCiAgICBkZWYgcmVzb2x2ZShzZWxmLCB0YXJnZXRzLCBjYWxsYmFjayA9IE5vbmUs
+IG49MSk6CiAgICAgICAgIyByYWlzZSBleGNlcHRpb25zIHRvIHNpZ25hbCBlcnJvcnM6CiAgICAg
+ICAgIyAgQ3ljbGVEZXRlY3RlZCAoKQogICAgICAgICMgIERlcGVuZGVuY3lVbm1ldCAoKQogICAg
+ICAgIGlmIGlzaW5zdGFuY2UodGFyZ2V0cyxzdHIpOgogICAgICAgICAgICB0YXJnZXRzID0gW3Rh
+cmdldHNdCiAgICAgICAgc2VsZi5fcmVzb2x2aW5nID0gVHJ1ZQogICAgICAgIGlmIG4gPT0gMToK
+ICAgICAgICAgICAgc2VsZi5fcmVzb2x2ZV9zZXJpYWwodGFyZ2V0cywgY2FsbGJhY2spCiAgICAg
+ICAgZWxzZToKICAgICAgICAgICAgc2VsZi5fcmVzb2x2ZV9wYXJhbGxlbCh0YXJnZXRzLCBjYWxs
+YmFjaywgbikKICAgICAgICBzZWxmLl9yZXNvbHZpbmcgPSBGYWxzZQoKICAgIGRlZiBfdXBkYXRl
+X2RpcnR5KHNlbGYsdGFyZ2V0KToKICAgICAgICBpZiBzZWxmLl9yZXNvbHZpbmc6CiAgICAgICAg
+ICAgIGRlcGVuZGluZyA9IHNlbGYuX2RlcGVuZF9vbihbdGFyZ2V0XSkKICAgICAgICAgICAgZm9y
+IGkgaW4gZGVwZW5kaW5nOgogICAgICAgICAgICAgICAgaS5kaXJ0eSgpCiAgICAgICAgICAgIHNl
+bGYuX2RpcnR5ID0gVHJ1ZQoKICAgICMgcmV0dXJuIGxpc3Qgb2YgdGFyZ2V0cyB3aGljaCBkZXBl
+bmQgb24gdGhlIGlucHV0CiAgICAjIHRhcmdldCwgaW5jbHVkaW5nIHRoZSBpbnB1dCB0YXJnZXQg
+aXRzZWxmLgogICAgZGVmIF9kZXBlbmRfb24oc2VsZix0YXJnZXRzKToKICAgICAgICB3b3JrcXVl
+dWUgPSBjb3B5LmNvcHkodGFyZ2V0cykKICAgICAgICBkZXBzID0gW10KICAgICAgICB3aGlsZSBs
+ZW4od29ya3F1ZXVlKSA+IDA6CiAgICAgICAgICAgIGkgPSB3b3JrcXVldWUucG9wKCkKICAgICAg
+ICAgICAgaWYgaSBub3QgaW4gZGVwczoKICAgICAgICAgICAgICAgIGRlcHMuYXBwZW5kKGkpCiAg
+ICAgICAgICAgIGlmIHNlbGYuX3NvdXJjZXMuaGFzX2tleShpLmRzdCgpKToKICAgICAgICAgICAg
+ICAgIHdvcmtxdWV1ZS5leHRlbmQoc2VsZi5fc291cmNlc1tpLmRzdCgpXSkKICAgICAgICByZXR1
+cm4gZGVwcwoKICAgICMgcmV0dXJuIGxpc3Qgb2YgdGFyZ2V0cyB3aGljaCBuZWVkIHRvIGJlIHJl
+c29sdmVkCiAgICAjIHRvIHJlc29sdmUgdGhlIGlucHV0IHRhcmdldHMKICAgIGRlZiBfZGVwZW5k
+ZW5jaWVzX29mKHNlbGYsdGFyZ2V0cyk6CiAgICAgICAgIyBYWFg6IHNob3VsZCBkZXRlY3QgY3lj
+bGVzIGhlcmUuCiAgICAgICAgd29ya3F1ZXVlID0gW3NlbGYuX3RhcmdldHNbdGFyZ2V0XSBmb3Ig
+dGFyZ2V0IGluIHRhcmdldHMgaWYgc2VsZi5fdGFyZ2V0cy5oYXNfa2V5KHRhcmdldCldCiAgICAg
+ICAgZGVwcyA9IFtdCiAgICAgICAgd2hpbGUgbGVuKHdvcmtxdWV1ZSkgPiAwOgogICAgICAgICAg
+ICBpID0gd29ya3F1ZXVlLnBvcCgpCiAgICAgICAgICAgIGlmIGkgbm90IGluIGRlcHM6CiAgICAg
+ICAgICAgICAgICBkZXBzLmFwcGVuZChpKQogICAgICAgICAgICBmb3Igc3JjIGluIGkuc3JjKCk6
+CiAgICAgICAgICAgICAgICBpZiBzZWxmLl90YXJnZXRzLmhhc19rZXkoc3JjKToKICAgICAgICAg
+ICAgICAgICAgICB3b3JrcXVldWUuYXBwZW5kKHNlbGYuX3RhcmdldHNbc3JjXSkKICAgICAgICBy
+ZXR1cm4gZGVwcwoKICAgIGRlZiBfaXNfbGVhZihzZWxmLCB0YXJnZXQpOgogICAgICAgIGFzc2Vy
+dCBzZWxmLl90YXJnZXRzLmhhc19rZXkodGFyZ2V0LmRzdCgpKQogICAgICAgICMgYSAnbGVhZicg
+aXMgYSB0YXJnZXQgd2hpY2ggZWl0aGVyIGhhcwogICAgICAgICMgbm8gc291cmNlIG9yIHdob3Nl
+IHNvdXJjZXMgYXJlIG5vdAogICAgICAgICMgdGFyZ2V0cyB0aGVtc2VsdmVzLgogICAgICAgIGZv
+ciBzcmMgaW4gdGFyZ2V0LnNyYygpOgogICAgICAgICAgICBpZiBzZWxmLl90YXJnZXRzLmhhc19r
+ZXkgKHNyYyk6CiAgICAgICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICByZXR1cm4gVHJ1
+ZQoKICAgICMgcmV0dXJuIHNvcnRlZCBsaXN0IG9mIHRhcmdldHMgc3VjaCB0aGF0IHRoZSBmaXJz
+dAogICAgIyBpdGVtcyBtdXN0IGJlICdyZXNvbHZlZCcgZmlyc3QuCiAgICBkZWYgX3NvcnQoc2Vs
+Zix0YXJnZXRzKToKICAgICAgICAjIHRvIGNhbGN1bGF0ZSB0aGlzLCB3ZSBmaXJzdCBjb2xsZWN0
+IHRoZSBzZXQgb2YgdGFyZ2V0cyB0bwogICAgICAgICMgJ3Jlc29sdmUnLiBpLmUuLCB0aGUgdGFy
+Z2V0cyB0aGF0ICd0YXJnZXRzJyBkZXBlbmRzIHVwb24uCiAgICAgICAgdG9fcmVzb2x2ZSA9IHNl
+bGYuX2RlcGVuZGVuY2llc19vZih0YXJnZXRzKQogICAgICAgICMgdGhlbiwgd2UgY29sbGVjdCB0
+aGUgc2V0IG9mIHRhcmdldHMgdGhhdCBhcmUgdGhlIGxlYXZlcwogICAgICAgICMgb2YgdGhlIGRl
+cGVuZGVuY3kgZ3JhcGggdG8gaW5pdGlhbGl6ZSBvdXIgd29ya3F1ZXVlCiAgICAgICAgbGVhdmVz
+ID0gW2kgZm9yIGkgaW4gdG9fcmVzb2x2ZSBpZiBzZWxmLl9pc19sZWFmKGkpXQogICAgICAgIHdv
+cmtxdWV1ZSA9IGxlYXZlcwogICAgICAgIHByaW8gPSBkaWN0KCkKICAgICAgICAjIGxldCdzIGlu
+aXRpYWxpemUgdGhlIHBpb3JpdHkgb2YgZXZlcnkgaXRlbSB0byB6ZXJvLgogICAgICAgIGZvciB3
+b3JrIGluIHRvX3Jlc29sdmU6CiAgICAgICAgICAgIHByaW9bd29ya10gPSAwCiAgICAgICAgIyBh
+bmQsIG5vdywgd2UgdXBkYXRlIHRoZSBwcmlvcml0eSBzbyB0aGF0IHRoZQogICAgICAgICMgZGVl
+cGVzdCB0YXJnZXRzIG9mIHRoZSBkZXBlbmRlbmN5IHRyZWUgaGF2ZSB0aGUgaGlnaGVzdAogICAg
+ICAgICMgcHJpb3JpdHkuCiAgICAgICAgd2hpbGUgbGVuKHdvcmtxdWV1ZSkgPiAwOgogICAgICAg
+ICAgICBzb3VyY2UgPSB3b3JrcXVldWUucG9wKCkKICAgICAgICAgICAgaWYgbm90IHNlbGYuX3Nv
+dXJjZXMuaGFzX2tleSAoc291cmNlLmRzdCgpKToKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAg
+ICAgICAgICAgIGZvciBkc3QgaW4gc2VsZi5fc291cmNlc1tzb3VyY2UuZHN0KCldOgogICAgICAg
+ICAgICAgICAgaWYgZHN0IG5vdCBpbiB0b19yZXNvbHZlOgogICAgICAgICAgICAgICAgICAgIGNv
+bnRpbnVlCiAgICAgICAgICAgICAgICBwcmlvW2RzdF0gPSBtYXgocHJpb1tkc3RdLCBwcmlvW3Nv
+dXJjZV0gKyAxKQogICAgICAgICAgICAgICAgd29ya3F1ZXVlLmFwcGVuZChkc3QpCgogICAgICAg
+ICMgbm93LCBidWlsZCBhbiBpbnZlcnRlZCBkaWN0aW9uYXJ5IG9mIHByaW9yaXRpZXMKICAgICAg
+ICAjIHdlIHdhbnQgdG8gZmluZCB0aGUgbGlzdCBvZiB0YXJnZXRzIGZvciBlYWNoIHByaW9yaXR5
+CiAgICAgICAgcHJpb19pbnZlcnRlZCA9IGRpY3QoKQogICAgICAgIGZvciB0YXJnZXQgaW4gdG9f
+cmVzb2x2ZToKICAgICAgICAgICAgaWYgcHJpb19pbnZlcnRlZC5oYXNfa2V5KHByaW9bdGFyZ2V0
+XSk6CiAgICAgICAgICAgICAgICBwcmlvX2ludmVydGVkW3ByaW9bdGFyZ2V0XV0uYXBwZW5kKHRh
+cmdldCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHByaW9faW52ZXJ0ZWRbcHJp
+b1t0YXJnZXRdXSA9IFt0YXJnZXRdCiAgICAgICAgIyBnZW5lcmF0ZSBhIHNvcnRlZCBsaXN0IG9m
+IHRhcmdldHMsIGxvd2VzdC1wcmlvcml0eSBmaXJzdAogICAgICAgIHNvcnRlZF90YXJnZXRzID0g
+W10KICAgICAgICBmb3Iga2V5IGluIHNvcnRlZChwcmlvX2ludmVydGVkLmtleXMoKSk6CiAgICAg
+ICAgICAgIHNvcnRlZF90YXJnZXRzLmV4dGVuZChzb3J0ZWQocHJpb19pbnZlcnRlZFtrZXldLCBz
+ZWxmLl9jbXApKQogICAgICAgICMgY29udmVydCB0aGUgbGlzdCBvZiB0YXJnZXRzIGludG8gYSBs
+aXN0IG9mIHN0ZXBzCiAgICAgICAgcmV0dXJuIHNvcnRlZF90YXJnZXRzCgogICAgZGVmIF9jbXAo
+c2VsZiwgYSwgYik6CiAgICAgICAgcmV0dXJuIGNtcChhLmRzdCgpLCBiLmRzdCgpKTsKCiAgICBk
+ZWYgX2lzX2NsZWFuKHNlbGYsdGFyZ2V0cyk6CiAgICAgICAgZm9yIHRhcmdldCBpbiB0YXJnZXRz
+OgogICAgICAgICAgICBpZiBzZWxmLl90YXJnZXRzLmhhc19rZXkgKHRhcmdldCk6CiAgICAgICAg
+ICAgICAgICBpZiBzZWxmLl90YXJnZXRzW3RhcmdldF0uaXNfZGlydHkoKToKICAgICAgICAgICAg
+ICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICByZXR1cm4gVHJ1ZQoKICAgICMgJ3Jlc29sdmUn
+IGFsbCB0YXJnZXRzIHdoaWNoIHRoZSBpbnB1dCB0YXJnZXRzIGRlcGVuZCB1cG9uCiAgICAjIGlu
+IHRoZSByaWdodCBvcmRlci4gSWYgcmVzb2x2aW5nIG9uZSBvZiB0aGVzZSB0YXJnZXRzCiAgICAj
+IGNyZWF0ZXMgbmV3IHRhcmdldHMsIHRoZSBmdW5jdGlvbiBpcyBpbnRlcnJ1cHRlZCBhbmQgcmV0
+dXJucwogICAgIyBGYWxzZS4gT3RoZXJ3aXNlLCB0aGUgZnVuY3Rpb24gY29tcGxldGVzIGFuZCBy
+ZXR1cm5zIFRydWUuCiAgICBkZWYgX3Jlc29sdmVfb25lX2l0ZXJhdGlvbihzZWxmLCB0YXJnZXRz
+LCBjYWxsYmFjayk6CiAgICAgICAgc2VsZi5fZGlydHkgPSBGYWxzZQogICAgICAgIHF1ZXVlID0g
+c2VsZi5fc29ydCh0YXJnZXRzKQogICAgICAgIGRpcnR5ID0gW2kgZm9yIGkgaW4gcXVldWUgaWYg
+aS5pc19kaXJ0eSgpXQogICAgICAgIGZvciBpIGluIGRpcnR5OgogICAgICAgICAgICBpLmNsZWFu
+KCk7CiAgICAgICAgICAgIGFzc2VydCBzZWxmLl9pc19jbGVhbihpLnNyYygpKQogICAgICAgICAg
+ICBzdWNjZXNzID0gVHJ1ZQogICAgICAgICAgICBpZiBjYWxsYmFjayBpcyBOb25lIGFuZCBpLmNv
+bnRleHQoKSBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBpLmNvbnRleHQo
+KSgpCiAgICAgICAgICAgIGVsaWYgY2FsbGJhY2sgaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAg
+ICBzdWNjZXNzID0gY2FsbGJhY2soaS5kc3QoKSwgaS5jb250ZXh0KCkpCiAgICAgICAgICAgIGlm
+IG5vdCBzdWNjZXNzOgogICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX3NvdXJjZXMuaGFzX2tl
+eShpLmRzdCgpKToKICAgICAgICAgICAgICAgICAgICByYWlzZSBEZXBlbmRlbmN5VW5tZXQoaS5k
+c3QoKSkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgZm9yIGogaW4g
+c2VsZi5fc291cmNlc1tpLmRzdCgpXToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm90IGou
+aXNfc3JjX29wdGlvbmFsKGkuZHN0KCkpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFp
+c2UgRGVwZW5kZW5jeVVubWV0KGkuZHN0KCkpCiAgICAgICAgICAgIGlmIHNlbGYuX2RpcnR5Ogog
+ICAgICAgICAgICAgICAgc2VsZi5fZGlydHkgPSBGYWxzZQogICAgICAgICAgICAgICAgcmV0dXJu
+IEZhbHNlCiAgICAgICAgcmV0dXJuIFRydWUKCiAgICBkZWYgX3Jlc29sdmVfc2VyaWFsKHNlbGYs
+IHRhcmdldHMsIGNhbGxiYWNrKToKICAgICAgICBmaW5pc2hlZCA9IHNlbGYuX3Jlc29sdmVfb25l
+X2l0ZXJhdGlvbih0YXJnZXRzLCBjYWxsYmFjaykKICAgICAgICB3aGlsZSBub3QgZmluaXNoZWQ6
+CiAgICAgICAgICAgIGZpbmlzaGVkID0gc2VsZi5fcmVzb2x2ZV9vbmVfaXRlcmF0aW9uKHRhcmdl
+dHMsIGNhbGxiYWNrKQoKICAgIGRlZiBfcmVzb2x2ZV9wYXJhbGxlbChzZWxmLCB0YXJnZXRzLCBj
+YWxsYmFjaywgbik6CiAgICAgICAgIyBYWFg6IGltcGxlbWVudCBwYXJhbGxlbCB2ZXJzaW9uCiAg
+ICAgICAgc2VsZi5fcmVzb2x2ZV9zZXJpYWwodGFyZ2V0cywgY2FsbGJhY2spClBLAQIUAxQAAAAA
+AIhcrj5O0QAyVRwAAFUcAAAZAAAAAAAAAAAAAAC0gQAAAABiYWtlL01vZHVsZUVudmlyb25tZW50
+LnB5UEsBAhQDFAAAAAAA1KxfP9LhkJJ5KgAAeSoAABMAAAAAAAAAAAAAALSBjBwAAGJha2UvTW9k
+dWxlQnVpbGQucHlQSwECFAMUAAAAAAAWma4+V9+tqe0UAADtFAAADgAAAAAAAAAAAAAAtIE2RwAA
+YmFrZS9Nb2R1bGUucHlQSwECFAMUAAAAAAC7SWE/9F780cw9AADMPQAAFQAAAAAAAAAAAAAAtIFP
+XAAAYmFrZS9Db25maWd1cmF0aW9uLnB5UEsBAhQDFAAAAAAAOFeuPrQqpwVGBQAARgUAABkAAAAA
+AAAAAAAAALSBTpoAAGJha2UvRmlsZXN5c3RlbU1vbml0b3IucHlQSwECFAMUAAAAAAB6Y64+r95Y
+QeMFAADjBQAADQAAAAAAAAAAAAAAtIHLnwAAYmFrZS9VdGlscy5weVBLAQIUAxQAAAAAAF2Zrj7m
+jFY+ewgAAHsIAAAUAAAAAAAAAAAAAAC0gdmlAABiYWtlL01vZHVsZUxvZ2dlci5weVBLAQIUAxQA
+AAAAAPdUpj4DxD6oOQEAADkBAAASAAAAAAAAAAAAAAC0gYauAABiYWtlL0V4Y2VwdGlvbnMucHlQ
+SwECFAMUAAAAAAC9U2E/ZwWpKaYAAACmAAAAEAAAAAAAAAAAAAAAtIHvrwAAYmFrZS9fX2luaXRf
+Xy5weVBLAQIUAxQAAAAAAKlUYT+pcmKNCXcAAAl3AAAMAAAAAAAAAAAAAAC0gcOwAABiYWtlL0Jh
+a2UucHlQSwECFAMUAAAAAADarF8/R0Yq3xwiAAAcIgAAFAAAAAAAAAAAAAAAtIH2JwEAYmFrZS9N
+b2R1bGVTb3VyY2UucHlQSwECFAMUAAAAAACPZXU+23iaIagkAACoJAAAFAAAAAAAAAAAAAAAtIFE
+SgEAYmFrZS9EZXBlbmRlbmNpZXMucHlQSwUGAAAAAAwADAAHAwAAHm8BAAAA
+"""
+
+def decompress(output):
+    import StringIO
+    import zipfile
+    import base64
+    decoded = StringIO.StringIO()
+    base64.decode(StringIO.StringIO(zipdata), decoded)
+    f = zipfile.ZipFile(decoded, 'r')
+    f.extractall(pathname)
+    f.close()
+    
+
+import os
+import sys
+pathname = os.path.join('.bake', sources_md5)
+if not os.path.exists(pathname):
+    os.makedirs(pathname)
+    decompress(pathname)
+elif not os.path.isdir(pathname):
+    import tempfile
+    pathname = tempfile.mkdtemp()
+    decompress(pathname)
+sys.path.append(pathname)
+import bake as source
+source.main(sys.argv)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bakeconf.xml	Tue Nov 01 11:27:35 2011 +0100
@@ -0,0 +1,110 @@
+<configuration>
+  <modules>
+
+    <module name="click-1.8.0">
+      <source type="archive">
+	<attribute name="url" value="http://read.cs.ucla.edu/click/click-1.8.0.tar.gz"/>
+      </source>
+      <build type="autotools" objdir="yes">
+	<attribute name="configure_arguments" value="--enable-userlevel --disable-linuxmodule --enable-nsclick --enable-wifi"/>
+      </build>
+    </module>
+
+    <module name="openflow-ns3">
+      <source type="mercurial">
+	<attribute name="url" value="http://code.nsnam.org/bhurd/openflow"/>
+      </source>
+      <build type="waf" objdir="yes"/>
+    </module>
+
+    <module name="gccxml-ns3">
+      <source type="cvs">
+	<attribute name="root" value=":pserver:anoncvs:@www.gccxml.org:/cvsroot/GCC_XML"/>
+	<attribute name="module" value="gccxml"/>
+	<attribute name="date" value="2009-09-21"/>
+      </source>
+      <build type="cmake" objdir="yes">
+      </build>
+    </module>
+
+    <module name="pygccxml">
+      <source type="archive">
+	<attribute name="url" value="http://mesh.dl.sourceforge.net/project/pygccxml/pygccxml/pygccxml-1.0/pygccxml-1.0.0.zip"/>
+      </source>
+      <build type="python" objdir="yes">
+      </build>
+      <depends_on name="gccxml"/>
+    </module>
+
+    <module name="pybindgen">
+      <source type="bazaar">
+	<attribute name="url" value="https://launchpad.net/pybindgen"/>
+	<attribute name="revision" value="revno:795"/>
+      </source>
+      <build type="waf" objdir="yes">
+	<attribute name="build_arguments" value="--generate-version"/>
+      </build>
+      <depends_on name="pygccxml" optional="True"/>
+    </module>
+
+    <module name="nsc">
+      <source type="mercurial">
+	<attribute name="url" value="https://secure.wand.net.nz/mercurial/nsc"/>
+      </source>
+      <!-- problem: scons has no generic command-line support for builddir and installdir -->
+      <build type="inline"  classname="NscModuleBuild">
+	<code>class NscModuleBuild(InlineModuleBuild):
+    def __init__(self):
+        InlineModuleBuild.__init__(self)
+    def build(self, env, jobs):
+        env.run(['python', os.path.join(env.srcdir, 'scons.py'), 
+                 '-j', str(jobs), '--prefix=' + env.installdir, 'install'],
+                directory=env.srcdir)
+    def clean(self, env):
+        env.run(['python', os.path.join(env.srcdir, 'scons.py'), '-c'],
+                directory=env.srcdir)
+    def check_version(self, env):
+        return True</code>
+      </build>
+    </module>
+    
+    <module name="ns-3-dev">
+      <source type="mercurial">
+	<attribute name="url" value="http://code.nsnam.org/ns-3-dev"/>
+      </source>
+      <depends_on name="nsc" optional="True"/>
+      <depends_on name="pybindgen" optional="True"/>
+      <depends_on name="click-1.8.0" optional="True"/>
+      <depends_on name="openflow-ns3" optional="True"/>
+      <build type="waf" objdir="yes">
+	<attribute name="configure_arguments" value="--with-nsc=$INSTALLDIR --with-nsclick=$INSTALLDIR --with-openflow=$INSTALLDIR"/>
+      </build>
+    </module>
+
+  </modules>
+
+  <predefined name="ns3">
+    <enable name="ns-3-dev"/>
+    <configuration installdir="." sourcedir="../source"/>
+    <append module="ns-3-dev" name="configure_arguments" value="--enable-examples --enable-tests"/>
+  </predefined>
+  <predefined name="nopython">
+    <disable name="pybindgen"/>
+  </predefined>
+  <predefined name="dbg">
+    <configuration objdir="dbg"/>
+    <append name="CFLAGS" value="-g -O0"/>
+    <append name="CXXFLAGS" value="-g -O0"/>
+  </predefined>
+  <predefined name="opt">
+    <configuration objdir="opt"/>
+    <append name="CFLAGS" value="-g -O3"/>
+    <append name="CXXFLAGS" value="-g -O3"/>
+  </predefined>
+  <predefined name="cov">
+    <configuration objdir="cov"/>
+    <append name="CFLAGS" value="-fprofile-arcs -ftest-coverage "/>
+    <append name="CXXFLAGS" value="-fprofile-arcs -ftest-coverage "/>
+    <append name="LDFLAGS" value="-lgcov"/>
+  </predefined>
+</configuration>