[Pythonmac-SIG] Mach{ho}Python IDE with syntax colouring

Tony McDonald tony.mcdonald@ncl.ac.uk
Sun, 04 Aug 2002 17:39:12 +0100


> This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.

--B_3111327557_3186067
Content-type: text/plain; charset="US-ASCII"
Content-transfer-encoding: 7bit

> 
> *Very* nice! - now, about that AdvancedEditor patch ...
> 

Ok, been fiddling all afternoon. I hope my ignorance doesn't show too much.
I've edited the PyEdit.py and PyAdvancedEditor.py files and now get syntax
colouring (sp! :) in the IDE.

Bear in mind that this is a very hacky solution - I've just edited things
until they 'work', I hope this helps other people.

To get to this happy state of affairs I'd suggest you follow the
instructions that Donovan has posted on his blog at
http://www.ulaluma.com/pyx. That should sort out problems with people who've
used fink.

If you've messed about with /usr/local, then it's assumed you're an adult
and you need to take some responsibility for your actions. I had to edit
some lines (384-386) in setup.py

                readline_libs.append('termcap')
#            exts.append( Extension('readline', ['readline.c'],
#                                   library_dirs=['/usr/lib/termcap'],
#                                   libraries=readline_libs) )

If you then copy the PyEdit.py file (attached) and PyAdvancedEdit.py from
<http://www.strout.net/python/mac/> into dist/src/Mac/Tools/IDE you'll
hopefully be set. The PyAdvancedEdit.py is all Joe Strouts' work, all I did
was edit it so:

from Carbon import Qd
from Carbon import Fm
from Carbon import Evt
from Carbon import Events


I then followed Jacks instructions
% ./configure --enable-framework
% make
% make frameworkinstall
% make osxapps

You *should* get a Python IDE application in /Applications/Python.

A bonus (at least from my PoV) is that if you install modules using the
following;
% /Library/Frameworks/Python.framework/Versions/Current/bin/python setup.py
Then they'll get installed into the Framework and not
/usr/local/lib/python2.x. This then makes those modules available to the IDE
(at least MySQLdb anyhow)

As I said earlier, I'm no expert in this, so if someone knows a cleaner way
of doing this, please let us all know.

It goes without saying that my thanks go to Jack and Donovan in particular.

Hope this helps,
Tone.
-- 
Dr Tony McDonald,  Assistant Director, FMCC, http://www.fmcc.org.uk/
The Medical School, Newcastle University Tel: +44 191 243 6140
A Zope list for UK HE/FE  http://www.fmcc.org.uk/mailman/listinfo/zope


--B_3111327557_3186067
Content-type: multipart/appledouble; boundary="B_3111327552_3212811"


--B_3111327552_3212811
Content-type: application/applefile; name="PyEdit.py"
Content-transfer-encoding: base64
Content-disposition: attachment

AAUWBwACAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAJAAAAPgAAACAAAAADAAAAXgAAAAkAAAAC
AAAAZwAAAdJURVhUUGVwcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFB5RWRpdC5weQAAAQAA
AAGgAAAAoAAAADIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACcUHl0aG9uAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAFAAAAAAAAAa6wAAAAAAABrrAAAAALly2c4A
ABelAAAABAAAADsAAAIzAAAC0gAABEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIHdAAABAAAAAaAAAACgAAAAMgAP8JAA
pgAAABwAMgAAUHBycwAAAAoAgf//AAAAAAPDoJQ=

--B_3111327552_3212811
Content-type: text/plain; name="PyEdit.py";
 x-mac-creator="50657072";
 x-mac-type="54455854"
Content-disposition: attachment
Content-transfer-encoding: base64

IiIiQSAobGVzcyAmIGxlc3MpIHNpbXBsZSBQeXRob24gZWRpdG9yIiIiCgppbXBvcnQgVwpp
bXBvcnQgV3RyYWNlYmFjawpmcm9tIFdrZXlzIGltcG9ydCAqCmZyb20gUHlBZHZhbmNlZEVk
aXRvciBpbXBvcnQgUHlBZHZhbmNlZEVkaXRvcgoKaW1wb3J0IG1hY2ZzCmltcG9ydCBNQUNG
UwppbXBvcnQgTWFjT1MKZnJvbSBDYXJib24gaW1wb3J0IFdpbgpmcm9tIENhcmJvbiBpbXBv
cnQgUmVzCmZyb20gQ2FyYm9uIGltcG9ydCBFdnQKZnJvbSBDYXJib24gaW1wb3J0IFFkCmlt
cG9ydCBvcwppbXBvcnQgaW1wCmltcG9ydCBzeXMKaW1wb3J0IHN0cmluZwppbXBvcnQgbWFy
c2hhbAppbXBvcnQgcmUKCmlmIGhhc2F0dHIoV2luLCAiRnJvbnROb25GbG9hdGluZ1dpbmRv
dyIpOgoJTXlGcm9udFdpbmRvdyA9IFdpbi5Gcm9udE5vbkZsb2F0aW5nV2luZG93CmVsc2U6
CglNeUZyb250V2luZG93ID0gV2luLkZyb250V2luZG93CgoKdHJ5OgoJaW1wb3J0IFd0aHJl
YWRpbmcKZXhjZXB0IEltcG9ydEVycm9yOgoJaGF2ZVRocmVhZGluZyA9IDAKZWxzZToKCWhh
dmVUaHJlYWRpbmcgPSBXdGhyZWFkaW5nLmhhdmVUaHJlYWRpbmcKCl9zY3JpcHR1bnRpdGxl
ZGNvdW50ZXIgPSAxCl93b3JkY2hhcnMgPSBzdHJpbmcuYXNjaWlfbGV0dGVycyArIHN0cmlu
Zy5kaWdpdHMgKyAiXyIKCgpydW5CdXR0b25MYWJlbHMgPSBbIlJ1biBhbGwiLCAiU3RvcCEi
XQpydW5TZWxCdXR0b25MYWJlbHMgPSBbIlJ1biBzZWxlY3Rpb24iLCAiUGF1c2UhIiwgIlJl
c3VtZSJdCgoKY2xhc3MgRWRpdG9yKFcuV2luZG93KToKCQoJZGVmIF9faW5pdF9fKHNlbGYs
IHBhdGggPSAiIiwgdGl0bGUgPSAiIik6CgkJZGVmYXVsdGZvbnRzZXR0aW5ncywgZGVmYXVs
dHRhYnNldHRpbmdzLCBkZWZhdWx0d2luZG93c2l6ZSA9IGdldGVkaXRvcnByZWZzKCkKCQln
bG9iYWwgX3NjcmlwdHVudGl0bGVkY291bnRlcgoJCWlmIG5vdCBwYXRoOgoJCQlpZiB0aXRs
ZToKCQkJCXNlbGYudGl0bGUgPSB0aXRsZQoJCQllbHNlOgoJCQkJc2VsZi50aXRsZSA9ICJV
bnRpdGxlZCBTY3JpcHQgIiArIGBfc2NyaXB0dW50aXRsZWRjb3VudGVyYAoJCQkJX3Njcmlw
dHVudGl0bGVkY291bnRlciA9IF9zY3JpcHR1bnRpdGxlZGNvdW50ZXIgKyAxCgkJCXRleHQg
PSAiIgoJCQlzZWxmLl9jcmVhdG9yID0gVy5fc2lnbmF0dXJlCgkJCXNlbGYuX2VvbG4gPSBv
cy5saW5lc2VwCgkJZWxpZiBvcy5wYXRoLmV4aXN0cyhwYXRoKToKCQkJcGF0aCA9IHJlc29s
dmVhbGlhc2VzKHBhdGgpCgkJCWRpciwgbmFtZSA9IG9zLnBhdGguc3BsaXQocGF0aCkKCQkJ
c2VsZi50aXRsZSA9IG5hbWUKCQkJZiA9IG9wZW4ocGF0aCwgInJiIikKCQkJdGV4dCA9IGYu
cmVhZCgpCgkJCWYuY2xvc2UoKQoJCQlmc3MgPSBtYWNmcy5GU1NwZWMocGF0aCkKCQkJc2Vs
Zi5fY3JlYXRvciwgZmlsZXR5cGUgPSBmc3MuR2V0Q3JlYXRvclR5cGUoKQoJCWVsc2U6CgkJ
CXJhaXNlIElPRXJyb3IsICJmaWxlICclcycgZG9lcyBub3QgZXhpc3QiICUgcGF0aAoJCXNl
bGYucGF0aCA9IHBhdGgKCQkKCQlpZiAnXG4nIGluIHRleHQ6CgkJCWltcG9ydCBFYXN5RGlh
bG9ncwoJCQlpZiBzdHJpbmcuZmluZCh0ZXh0LCAnXHJcbicpID49IDA6CgkJCQlzZWxmLl9l
b2xuID0gJ1xyXG4nCgkJCWVsc2U6CgkJCQlzZWxmLl9lb2xuID0gJ1xuJwoJCQl0ZXh0ID0g
c3RyaW5nLnJlcGxhY2UodGV4dCwgc2VsZi5fZW9sbiwgJ1xyJykKCQkJY2hhbmdlID0gMAoJ
CWVsc2U6CgkJCWNoYW5nZSA9IDAKCQkJc2VsZi5fZW9sbiA9ICdccicKCQkKCQlzZWxmLnNl
dHRpbmdzID0ge30KCQlpZiBzZWxmLnBhdGg6CgkJCXNlbGYucmVhZHdpbmRvd3NldHRpbmdz
KCkKCQlpZiBzZWxmLnNldHRpbmdzLmhhc19rZXkoIndpbmRvd2JvdW5kcyIpOgoJCQlib3Vu
ZHMgPSBzZWxmLnNldHRpbmdzWyJ3aW5kb3dib3VuZHMiXQoJCWVsc2U6CgkJCWJvdW5kcyA9
IGRlZmF1bHR3aW5kb3dzaXplCgkJaWYgc2VsZi5zZXR0aW5ncy5oYXNfa2V5KCJmb250c2V0
dGluZ3MiKToKCQkJc2VsZi5mb250c2V0dGluZ3MgPSBzZWxmLnNldHRpbmdzWyJmb250c2V0
dGluZ3MiXQoJCWVsc2U6CgkJCXNlbGYuZm9udHNldHRpbmdzID0gZGVmYXVsdGZvbnRzZXR0
aW5ncwoJCWlmIHNlbGYuc2V0dGluZ3MuaGFzX2tleSgidGFic2l6ZSIpOgoJCQl0cnk6CgkJ
CQlzZWxmLnRhYnNldHRpbmdzID0gKHRhYnNpemUsIHRhYm1vZGUpID0gc2VsZi5zZXR0aW5n
c1sidGFic2l6ZSJdCgkJCWV4Y2VwdDoKCQkJCXNlbGYudGFic2V0dGluZ3MgPSBkZWZhdWx0
dGFic2V0dGluZ3MKCQllbHNlOgoJCQlzZWxmLnRhYnNldHRpbmdzID0gZGVmYXVsdHRhYnNl
dHRpbmdzCgkJCgkJVy5XaW5kb3cuX19pbml0X18oc2VsZiwgYm91bmRzLCBzZWxmLnRpdGxl
LCBtaW5zaXplID0gKDMzMCwgMTIwKSwgdGFiYmFibGUgPSAwKQoJCXNlbGYuc2V0dXB3aWRn
ZXRzKHRleHQpCgkJaWYgY2hhbmdlID4gMDoKCQkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnRl
eHRjaGFuZ2VkKCkKCQkKCQlpZiBzZWxmLnNldHRpbmdzLmhhc19rZXkoInNlbGVjdGlvbiIp
OgoJCQlzZWxzdGFydCwgc2VsZW5kID0gc2VsZi5zZXR0aW5nc1sic2VsZWN0aW9uIl0KCQkJ
c2VsZi5zZXRzZWxlY3Rpb24oc2Vsc3RhcnQsIHNlbGVuZCkKCQlzZWxmLm9wZW4oKQoJCXNl
bGYuc2V0aW5mb3RleHQoKQoJCXNlbGYuZ2xvYmFscyA9IHt9CgkJc2VsZi5fYnVmID0gIiIg
ICMgZm9yIHdyaXRlIG1ldGhvZAoJCXNlbGYuZGVidWdnaW5nID0gMAoJCXNlbGYucHJvZmls
aW5nID0gMAoJCXNlbGYucnVuX2FzX21haW4gPSBzZWxmLnNldHRpbmdzLmdldCgicnVuX2Fz
X21haW4iLCAwKQoJCXNlbGYucnVuX3dpdGhfaW50ZXJwcmV0ZXIgPSBzZWxmLnNldHRpbmdz
LmdldCgicnVuX3dpdGhfaW50ZXJwcmV0ZXIiLCAwKQoJCXNlbGYucnVuX3dpdGhfY2xfaW50
ZXJwcmV0ZXIgPSBzZWxmLnNldHRpbmdzLmdldCgicnVuX3dpdGhfY2xfaW50ZXJwcmV0ZXIi
LCAwKQoJCXNlbGYuX3RocmVhZHN0YXRlID0gKDAsIDApCgkJc2VsZi5fdGhyZWFkID0gTm9u
ZQoJCglkZWYgcmVhZHdpbmRvd3NldHRpbmdzKHNlbGYpOgoJCXRyeToKCQkJcmVzcmVmID0g
UmVzLkZTcE9wZW5SZXNGaWxlKHNlbGYucGF0aCwgMSkKCQlleGNlcHQgUmVzLkVycm9yOgoJ
CQlyZXR1cm4KCQl0cnk6CgkJCVJlcy5Vc2VSZXNGaWxlKHJlc3JlZikKCQkJZGF0YSA9IFJl
cy5HZXQxUmVzb3VyY2UoJ1B5V1MnLCAxMjgpCgkJCXNlbGYuc2V0dGluZ3MgPSBtYXJzaGFs
LmxvYWRzKGRhdGEuZGF0YSkKCQlleGNlcHQ6CgkJCXBhc3MKCQlSZXMuQ2xvc2VSZXNGaWxl
KHJlc3JlZikKCQkKCWRlZiB3cml0ZXdpbmRvd3NldHRpbmdzKHNlbGYpOgoJCXRyeToKCQkJ
cmVzcmVmID0gUmVzLkZTcE9wZW5SZXNGaWxlKHNlbGYucGF0aCwgMykKCQlleGNlcHQgUmVz
LkVycm9yOgoJCQlSZXMuRlNwQ3JlYXRlUmVzRmlsZShzZWxmLnBhdGgsIHNlbGYuX2NyZWF0
b3IsICdURVhUJywgTUFDRlMuc21BbGxTY3JpcHRzKQoJCQlyZXNyZWYgPSBSZXMuRlNwT3Bl
blJlc0ZpbGUoc2VsZi5wYXRoLCAzKQoJCXRyeToKCQkJZGF0YSA9IFJlcy5SZXNvdXJjZSht
YXJzaGFsLmR1bXBzKHNlbGYuc2V0dGluZ3MpKQoJCQlSZXMuVXNlUmVzRmlsZShyZXNyZWYp
CgkJCXRyeToKCQkJCXRlbXAgPSBSZXMuR2V0MVJlc291cmNlKCdQeVdTJywgMTI4KQoJCQkJ
dGVtcC5SZW1vdmVSZXNvdXJjZSgpCgkJCWV4Y2VwdCBSZXMuRXJyb3I6CgkJCQlwYXNzCgkJ
CWRhdGEuQWRkUmVzb3VyY2UoJ1B5V1MnLCAxMjgsICJ3aW5kb3cgc2V0dGluZ3MiKQoJCWZp
bmFsbHk6CgkJCVJlcy5VcGRhdGVSZXNGaWxlKHJlc3JlZikKCQkJUmVzLkNsb3NlUmVzRmls
ZShyZXNyZWYpCgkKCWRlZiBnZXRzZXR0aW5ncyhzZWxmKToKCQlzZWxmLnNldHRpbmdzID0g
e30KCQlzZWxmLnNldHRpbmdzWyJ3aW5kb3dib3VuZHMiXSA9IHNlbGYuZ2V0Ym91bmRzKCkK
CQlzZWxmLnNldHRpbmdzWyJzZWxlY3Rpb24iXSA9IHNlbGYuZ2V0c2VsZWN0aW9uKCkKCQlz
ZWxmLnNldHRpbmdzWyJmb250c2V0dGluZ3MiXSA9IHNlbGYuZWRpdGdyb3VwLmVkaXRvci5n
ZXRmb250c2V0dGluZ3MoKQoJCXNlbGYuc2V0dGluZ3NbInRhYnNpemUiXSA9IHNlbGYuZWRp
dGdyb3VwLmVkaXRvci5nZXR0YWJzZXR0aW5ncygpCgkJc2VsZi5zZXR0aW5nc1sicnVuX2Fz
X21haW4iXSA9IHNlbGYucnVuX2FzX21haW4KCQlzZWxmLnNldHRpbmdzWyJydW5fd2l0aF9p
bnRlcnByZXRlciJdID0gc2VsZi5ydW5fd2l0aF9pbnRlcnByZXRlcgoJCXNlbGYuc2V0dGlu
Z3NbInJ1bl93aXRoX2NsX2ludGVycHJldGVyIl0gPSBzZWxmLnJ1bl93aXRoX2NsX2ludGVy
cHJldGVyCgkKCWRlZiBnZXQoc2VsZik6CgkJcmV0dXJuIHNlbGYuZWRpdGdyb3VwLmVkaXRv
ci5nZXQoKQoJCglkZWYgZ2V0c2VsZWN0aW9uKHNlbGYpOgoJCXJldHVybiBzZWxmLmVkaXRn
cm91cC5lZGl0b3IudGVkLldFR2V0U2VsZWN0aW9uKCkKCQoJZGVmIHNldHNlbGVjdGlvbihz
ZWxmLCBzZWxzdGFydCwgc2VsZW5kKToKCQlzZWxmLmVkaXRncm91cC5lZGl0b3Iuc2V0c2Vs
ZWN0aW9uKHNlbHN0YXJ0LCBzZWxlbmQpCgkKCWRlZiBnZXRmaWxlbmFtZShzZWxmKToKCQlp
ZiBzZWxmLnBhdGg6CgkJCXJldHVybiBzZWxmLnBhdGgKCQlyZXR1cm4gJzwlcz4nICUgc2Vs
Zi50aXRsZQoJCglkZWYgc2V0dXB3aWRnZXRzKHNlbGYsIHRleHQpOgoJCXRvcGJhcmhlaWdo
dCA9IDI0CgkJcG9wZmllbGR3aWR0aCA9IDgwCgkJc2VsZi5sYXN0bGluZW5vID0gTm9uZQoJ
CQoJCSMgbWFrZSBhbiBlZGl0b3IKCQlzZWxmLmVkaXRncm91cCA9IFcuR3JvdXAoKDAsIHRv
cGJhcmhlaWdodCArIDEsIDAsIDApKQoJCVB5QWR2YW5jZWRFZGl0b3IoKDAsIDAsIC0xNSwt
MTUpLCB0ZXh0LCAKCQkJCWZvbnRzZXR0aW5ncyA9IHNlbGYuZm9udHNldHRpbmdzLCAKCQkJ
CXRhYnNldHRpbmdzID0gc2VsZi50YWJzZXR0aW5ncywKCQkJCWZpbGUgPSBzZWxmLmdldGZp
bGVuYW1lKCkpCgkJZWRpdG9yLmdldGVudmlyb25tZW50ID0gc2VsZi5nZXRlbnZpcm9ubWVu
dAoJCQkJCgkJIyBtYWtlIHRoZSB3aWRnZXRzCgkJc2VsZi5wb3BmaWVsZCA9IENsYXNzRmlu
ZGVyKChwb3BmaWVsZHdpZHRoIC0gMTcsIC0xNSwgMTYsIDE2KSwgW10sIHNlbGYucG9wc2Vs
ZWN0bGluZSkKCQlzZWxmLmxpbmVmaWVsZCA9IFcuRWRpdFRleHQoKC0xLCAtMTUsIHBvcGZp
ZWxkd2lkdGggLSAxNSwgMTYpLCBpbnNldCA9ICg2LCAxKSkKCQlzZWxmLmVkaXRncm91cC5f
YmFyeCA9IFcuU2Nyb2xsYmFyKChwb3BmaWVsZHdpZHRoIC0gMiwgLTE1LCAtMTQsIDE2KSwg
ZWRpdG9yLmhzY3JvbGwsIG1heCA9IDMyNzY3KQoJCXNlbGYuZWRpdGdyb3VwLl9iYXJ5ID0g
Vy5TY3JvbGxiYXIoKC0xNSwgMTQsIDE2LCAtMTQpLCBlZGl0b3IudnNjcm9sbCwgbWF4ID0g
MzI3NjcpCgkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yID0gZWRpdG9yCSMgYWRkIGVkaXRvciAq
YWZ0ZXIqIHNjcm9sbGJhcnMKCQkKCQlzZWxmLmVkaXRncm91cC5vcHRpb25zbWVudSA9IFcu
UG9wdXBNZW51KCgtMTUsIC0xLCAxNiwgMTYpLCBbXSkKCQlzZWxmLmVkaXRncm91cC5vcHRp
b25zbWVudS5iaW5kKCc8Y2xpY2s+Jywgc2VsZi5tYWtlb3B0aW9uc21lbnUpCgkJCgkJc2Vs
Zi5iZXZlbGJveCA9IFcuQmV2ZWxCb3goKDAsIDAsIDAsIHRvcGJhcmhlaWdodCkpCgkJc2Vs
Zi5obGluZSA9IFcuSG9yaXpvbnRhbExpbmUoKDAsIHRvcGJhcmhlaWdodCwgMCwgMCkpCgkJ
c2VsZi5pbmZvdGV4dCA9IFcuVGV4dEJveCgoMTc1LCA2LCAtNCwgMTQpLCBiYWNrZ3JvdW5k
Y29sb3IgPSAoMHhlMDAwLCAweGUwMDAsIDB4ZTAwMCkpCgkJc2VsZi5ydW5idXR0b24gPSBX
LkJldmVsQnV0dG9uKCg2LCA0LCA4MCwgMTYpLCBydW5CdXR0b25MYWJlbHNbMF0sIHNlbGYu
cnVuKQoJCXNlbGYucnVuc2VsYnV0dG9uID0gVy5CZXZlbEJ1dHRvbigoOTAsIDQsIDgwLCAx
NiksIHJ1blNlbEJ1dHRvbkxhYmVsc1swXSwgc2VsZi5ydW5zZWxlY3Rpb24pCgkJCgkJIyBi
aW5kIHNvbWUga2V5cwoJCWVkaXRvci5iaW5kKCJjbWRyIiwgc2VsZi5ydW5idXR0b24ucHVz
aCkKCQllZGl0b3IuYmluZCgiZW50ZXIiLCBzZWxmLnJ1bnNlbGJ1dHRvbi5wdXNoKQoJCWVk
aXRvci5iaW5kKCJjbWRqIiwgc2VsZi5kb21lbnVfZ290b2xpbmUpCgkJZWRpdG9yLmJpbmQo
ImNtZGQiLCBzZWxmLmRvbWVudV90b2dnbGVkZWJ1Z2dlcikKCQllZGl0b3IuYmluZCgiPGlk
bGU+Iiwgc2VsZi51cGRhdGVzZWxlY3Rpb24pCgkJCgkJZWRpdG9yLmJpbmQoImNtZGUiLCBz
ZWFyY2hlbmdpbmUuc2V0ZmluZHN0cmluZykKCQllZGl0b3IuYmluZCgiY21kZiIsIHNlYXJj
aGVuZ2luZS5zaG93KQoJCWVkaXRvci5iaW5kKCJjbWRnIiwgc2VhcmNoZW5naW5lLmZpbmRu
ZXh0KQoJCWVkaXRvci5iaW5kKCJjbWRzaGlmdHIiLCBzZWFyY2hlbmdpbmUucmVwbGFjZSkK
CQllZGl0b3IuYmluZCgiY21kdCIsIHNlYXJjaGVuZ2luZS5yZXBsYWNlZmluZCkKCQkKCQlz
ZWxmLmxpbmVmaWVsZC5iaW5kKCJyZXR1cm4iLCBzZWxmLmRvbGluZWZpZWxkKQoJCXNlbGYu
bGluZWZpZWxkLmJpbmQoImVudGVyIiwgc2VsZi5kb2xpbmVmaWVsZCkKCQlzZWxmLmxpbmVm
aWVsZC5iaW5kKCJ0YWIiLCBzZWxmLmRvbGluZWZpZWxkKQoJCQoJCSMgaW50ZXJjZXB0IGNs
aWNrcwoJCWVkaXRvci5iaW5kKCI8Y2xpY2s+Iiwgc2VsZi5jbGlja2VkaXRvcikKCQlzZWxm
LmxpbmVmaWVsZC5iaW5kKCI8Y2xpY2s+Iiwgc2VsZi5jbGlja2xpbmVmaWVsZCkKCQoJZGVm
IG1ha2VvcHRpb25zbWVudShzZWxmKToKCQltZW51aXRlbXMgPSBbKCdGb250IHNldHRpbmdz
XHhjOScsIHNlbGYuZG9tZW51X2ZvbnRzZXR0aW5ncyksIAoJCQkJKCJTYXZlIG9wdGlvbnNc
eGM5Iiwgc2VsZi5kb21lbnVfb3B0aW9ucyksCgkJCQknLScsCgkJCQkoJ1wwJyArIGNocihz
ZWxmLnJ1bl9hc19tYWluKSArICdSdW4gYXMgX19tYWluX18nLCBzZWxmLmRvbWVudV90b2dn
bGVfcnVuX2FzX21haW4pLCAKCQkJCSMoJ1wwJyArIGNocihzZWxmLnJ1bl93aXRoX2ludGVy
cHJldGVyKSArICdSdW4gd2l0aCBJbnRlcnByZXRlcicsIHNlbGYuZG9tZW51X2R0b2dnbGVf
cnVuX3dpdGhfaW50ZXJwcmV0ZXIpLCAKCQkJCSgnXDAnICsgY2hyKHNlbGYucnVuX3dpdGhf
Y2xfaW50ZXJwcmV0ZXIpICsgJ1J1biB3aXRoIGNvbW1hbmRsaW5lIFB5dGhvbicsIHNlbGYu
ZG9tZW51X3RvZ2dsZV9ydW5fd2l0aF9jbF9pbnRlcnByZXRlciksIAoJCQkJJy0nLAoJCQkJ
KCdNb2R1bGFyaXplJywgc2VsZi5kb21lbnVfbW9kdWxhcml6ZSksCgkJCQkoJ1wwJyArIGNo
cihzZWxmLnN5bnRheF9jb2xvcmluZykgKyAnU3ludGF4IENvbG9yaW5nJywgc2VsZi5kb21l
bnVfdG9nZ2xlX3N5bnRheF9jb2xvcmluZyksIAoJCQkJKCdCcm93c2UgbmFtZXNwYWNlXHhj
OScsIHNlbGYuZG9tZW51X2Jyb3dzZW5hbWVzcGFjZSksIAoJCQkJJy0nXQoJCWlmIHNlbGYu
cHJvZmlsaW5nOgoJCQltZW51aXRlbXMgPSBtZW51aXRlbXMgKyBbKCdEaXNhYmxlIHByb2Zp
bGVyJywgc2VsZi5kb21lbnVfdG9nZ2xlcHJvZmlsZXIpXQoJCWVsc2U6CgkJCW1lbnVpdGVt
cyA9IG1lbnVpdGVtcyArIFsoJ0VuYWJsZSBwcm9maWxlcicsIHNlbGYuZG9tZW51X3RvZ2ds
ZXByb2ZpbGVyKV0KCQlpZiBzZWxmLmVkaXRncm91cC5lZGl0b3IuX2RlYnVnZ2VyOgoJCQlt
ZW51aXRlbXMgPSBtZW51aXRlbXMgKyBbKCdEaXNhYmxlIGRlYnVnZ2VyJywgc2VsZi5kb21l
bnVfdG9nZ2xlZGVidWdnZXIpLAoJCQkJKCdDbGVhciBicmVha3BvaW50cycsIHNlbGYuZG9t
ZW51X2NsZWFyYnJlYWtwb2ludHMpLAoJCQkJKCdFZGl0IGJyZWFrcG9pbnRzXHhjOScsIHNl
bGYuZG9tZW51X2VkaXRicmVha3BvaW50cyldCgkJZWxzZToKCQkJbWVudWl0ZW1zID0gbWVu
dWl0ZW1zICsgWygnRW5hYmxlIGRlYnVnZ2VyJywgc2VsZi5kb21lbnVfdG9nZ2xlZGVidWdn
ZXIpXQoJCXNlbGYuZWRpdGdyb3VwLm9wdGlvbnNtZW51LnNldChtZW51aXRlbXMpCgkKCWRl
ZiBkb21lbnVfdG9nZ2xlX3N5bnRheF9jb2xvcmluZyhzZWxmKToKCQlzZWxmLnN5bnRheF9j
b2xvcmluZyA9IG5vdCBzZWxmLnN5bnRheF9jb2xvcmluZwoJCXNlbGYuZWRpdGdyb3VwLmVk
aXRvci5zZXRjb2xvcmluZyhzZWxmLnN5bnRheF9jb2xvcmluZykKCglkZWYgZG9tZW51X3Rv
Z2dsZV9ydW5fYXNfbWFpbihzZWxmKToKCQlzZWxmLnJ1bl9hc19tYWluID0gbm90IHNlbGYu
cnVuX2FzX21haW4KCQlzZWxmLnJ1bl93aXRoX2ludGVycHJldGVyID0gMAoJCXNlbGYucnVu
X3dpdGhfY2xfaW50ZXJwcmV0ZXIgPSAwCgkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnNlbGVj
dGlvbmNoYW5nZWQoKQoJCglkZWYgWFhkb21lbnVfdG9nZ2xlX3J1bl93aXRoX2ludGVycHJl
dGVyKHNlbGYpOgoJCXNlbGYucnVuX3dpdGhfaW50ZXJwcmV0ZXIgPSBub3Qgc2VsZi5ydW5f
d2l0aF9pbnRlcnByZXRlcgoJCXNlbGYucnVuX2FzX21haW4gPSAwCgkJaWYgc2VsZi5zZXR0
aW5ncy5oYXNfa2V5KCJzeW50YXhfY29sb3JpbmciKToKCQkJc2VsZi5zeW50YXhfY29sb3Jp
bmcgPSBzZWxmLnNldHRpbmdzWyJzeW50YXhfY29sb3JpbmciXQoJCWVsc2U6CgkJCXNlbGYu
c3ludGF4X2NvbG9yaW5nID0gMQoKCQlzZWxmLnJ1bl93aXRoX2NsX2ludGVycHJldGVyID0g
MAoJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5zZWxlY3Rpb25jaGFuZ2VkKCkKCQoJZGVmIGRv
bWVudV90b2dnbGVfcnVuX3dpdGhfY2xfaW50ZXJwcmV0ZXIoc2VsZik6CgkJc2VsZi5ydW5f
d2l0aF9jbF9pbnRlcnByZXRlciA9IG5vdCBzZWxmLnJ1bl93aXRoX2NsX2ludGVycHJldGVy
CgkJc2VsZi5ydW5fYXNfbWFpbiA9IDAKCQlpZiBzZWxmLnNldHRpbmdzLmhhc19rZXkoInN5
bnRheF9jb2xvcmluZyIpOgoJCQlzZWxmLnN5bnRheF9jb2xvcmluZyA9IHNlbGYuc2V0dGlu
Z3NbInN5bnRheF9jb2xvcmluZyJdCgkJZWxzZToKCQkJc2VsZi5zeW50YXhfY29sb3Jpbmcg
PSAxCgoJCXNlbGYucnVuX3dpdGhfaW50ZXJwcmV0ZXIgPSAwCgkJc2VsZi5lZGl0Z3JvdXAu
ZWRpdG9yLnNlbGVjdGlvbmNoYW5nZWQoKQoJCglkZWYgc2hvd2JyZWFrcG9pbnRzKHNlbGYs
IG9ub2ZmKToKCQlzZWxmLmVkaXRncm91cC5lZGl0b3Iuc2hvd2JyZWFrcG9pbnRzKG9ub2Zm
KQoJCXNlbGYuZGVidWdnaW5nID0gb25vZmYKCQoJZGVmIGRvbWVudV9jbGVhcmJyZWFrcG9p
bnRzKHNlbGYsICphcmdzKToKCQlzZWxmLmVkaXRncm91cC5lZGl0b3IuY2xlYXJicmVha3Bv
aW50cygpCgkKCWRlZiBkb21lbnVfZWRpdGJyZWFrcG9pbnRzKHNlbGYsICphcmdzKToKCQlz
ZWxmLmVkaXRncm91cC5lZGl0b3IuZWRpdGJyZWFrcG9pbnRzKCkKCQoJZGVmIGRvbWVudV90
b2dnbGVkZWJ1Z2dlcihzZWxmLCAqYXJncyk6CgkJaWYgbm90IHNlbGYuZGVidWdnaW5nOgoJ
CQlXLlNldEN1cnNvcignd2F0Y2gnKQoJCXNlbGYuZGVidWdnaW5nID0gbm90IHNlbGYuZGVi
dWdnaW5nCgkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnRvZ2dsZWJyZWFrcG9pbnRzKCkKCQkK
CWRlZiBkb21lbnVfdG9nZ2xlcHJvZmlsZXIoc2VsZiwgKmFyZ3MpOgoJCXNlbGYucHJvZmls
aW5nID0gbm90IHNlbGYucHJvZmlsaW5nCgkKCWRlZiBkb21lbnVfYnJvd3NlbmFtZXNwYWNl
KHNlbGYsICphcmdzKToKCQlpbXBvcnQgUHlCcm93c2VyLCBXCgkJVy5TZXRDdXJzb3IoJ3dh
dGNoJykKCQlnbG9iYWxzLCBmaWxlLCBtb2RuYW1lID0gc2VsZi5nZXRlbnZpcm9ubWVudCgp
CgkJaWYgbm90IG1vZG5hbWU6CgkJCW1vZG5hbWUgPSBzZWxmLnRpdGxlCgkJUHlCcm93c2Vy
LkJyb3dzZXIoZ2xvYmFscywgIk9iamVjdCBicm93c2VyOiAiICsgbW9kbmFtZSkKCQoJZGVm
IGRvbWVudV9tb2R1bGFyaXplKHNlbGYsICphcmdzKToKCQltb2RuYW1lID0gX2ZpbGVuYW1l
X2FzX21vZG5hbWUoc2VsZi50aXRsZSkKCQlpZiBub3QgbW9kbmFtZToKCQkJcmFpc2UgVy5B
bGVydEVycm9yLCAiQ2FuJ3QgbW9kdWxhcml6ZSBcIiVzXCIiICUgc2VsZi50aXRsZQoJCXJ1
bl9hc19tYWluID0gc2VsZi5ydW5fYXNfbWFpbgoJCXNlbGYucnVuX2FzX21haW4gPSAwCgkJ
aWYgc2VsZi5zZXR0aW5ncy5oYXNfa2V5KCJzeW50YXhfY29sb3JpbmciKToKCQkJc2VsZi5z
eW50YXhfY29sb3JpbmcgPSBzZWxmLnNldHRpbmdzWyJzeW50YXhfY29sb3JpbmciXQoJCWVs
c2U6CgkJCXNlbGYuc3ludGF4X2NvbG9yaW5nID0gMQoKCQlzZWxmLnJ1bigpCgkJc2VsZi5y
dW5fYXNfbWFpbiA9IHJ1bl9hc19tYWluCgkJaWYgc2VsZi5wYXRoOgoJCQlmaWxlID0gc2Vs
Zi5wYXRoCgkJZWxzZToKCQkJZmlsZSA9IHNlbGYudGl0bGUKCQkKCQlpZiBzZWxmLmdsb2Jh
bHMgYW5kIG5vdCBzeXMubW9kdWxlcy5oYXNfa2V5KG1vZG5hbWUpOgoJCQltb2R1bGUgPSBp
bXAubmV3X21vZHVsZShtb2RuYW1lKQoJCQlmb3IgYXR0ciBpbiBzZWxmLmdsb2JhbHMua2V5
cygpOgoJCQkJc2V0YXR0cihtb2R1bGUsYXR0cixzZWxmLmdsb2JhbHNbYXR0cl0pCgkJCXN5
cy5tb2R1bGVzW21vZG5hbWVdID0gbW9kdWxlCgkJCXNlbGYuZ2xvYmFscyA9IHt9CgkKCWRl
ZiBkb21lbnVfZm9udHNldHRpbmdzKHNlbGYsICphcmdzKToKCQlpbXBvcnQgRm9udFNldHRp
bmdzCgkJZm9udHNldHRpbmdzID0gc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmdldGZvbnRzZXR0
aW5ncygpCgkJdGFic2V0dGluZ3MgPSBzZWxmLmVkaXRncm91cC5lZGl0b3IuZ2V0dGFic2V0
dGluZ3MoKQoJCXNldHRpbmdzID0gRm9udFNldHRpbmdzLkZvbnREaWFsb2coZm9udHNldHRp
bmdzLCB0YWJzZXR0aW5ncykKCQlpZiBzZXR0aW5nczoKCQkJZm9udHNldHRpbmdzLCB0YWJz
ZXR0aW5ncyA9IHNldHRpbmdzCgkJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5zZXRmb250c2V0
dGluZ3MoZm9udHNldHRpbmdzKQoJCQlzZWxmLmVkaXRncm91cC5lZGl0b3Iuc2V0dGFic2V0
dGluZ3ModGFic2V0dGluZ3MpCgkKCWRlZiBkb21lbnVfb3B0aW9ucyhzZWxmLCAqYXJncyk6
CgkJcnYgPSBTYXZlT3B0aW9ucyhzZWxmLl9jcmVhdG9yLCBzZWxmLl9lb2xuKQoJCWlmIHJ2
OgoJCQlzZWxmLmVkaXRncm91cC5lZGl0b3Iuc2VsZWN0aW9uY2hhbmdlZCgpICMgb3VjaC4u
LgoJCQlzZWxmLl9jcmVhdG9yLCBzZWxmLl9lb2xuID0gcnYKCQoJZGVmIGNsaWNrbGluZWZp
ZWxkKHNlbGYpOgoJCWlmIHNlbGYuX2N1cnJlbnR3aWRnZXQgPD4gc2VsZi5saW5lZmllbGQ6
CgkJCXNlbGYubGluZWZpZWxkLnNlbGVjdCgxKQoJCQlzZWxmLmxpbmVmaWVsZC5zZWxlY3Rh
bGwoKQoJCQlyZXR1cm4gMQoJCglkZWYgY2xpY2tlZGl0b3Ioc2VsZik6CgkJaWYgc2VsZi5f
Y3VycmVudHdpZGdldCA8PiBzZWxmLmVkaXRncm91cC5lZGl0b3I6CgkJCXNlbGYuZG9saW5l
ZmllbGQoKQoJCQlyZXR1cm4gMQoJCglkZWYgdXBkYXRlc2VsZWN0aW9uKHNlbGYsIGZvcmNl
ID0gMCk6CgkJc2VsID0gbWluKHNlbGYuZWRpdGdyb3VwLmVkaXRvci5nZXRzZWxlY3Rpb24o
KSkKCQlsaW5lbm8gPSBzZWxmLmVkaXRncm91cC5lZGl0b3Iub2Zmc2V0dG9saW5lKHNlbCkK
CQlpZiBsaW5lbm8gPD4gc2VsZi5sYXN0bGluZW5vIG9yIGZvcmNlOgoJCQlzZWxmLmxhc3Rs
aW5lbm8gPSBsaW5lbm8KCQkJc2VsZi5saW5lZmllbGQuc2V0KHN0cihsaW5lbm8gKyAxKSkK
CQkJc2VsZi5saW5lZmllbGQuc2VsdmlldygpCgkKCWRlZiBkb2xpbmVmaWVsZChzZWxmKToK
CQl0cnk6CgkJCWxpbmVubyA9IHN0cmluZy5hdG9pKHNlbGYubGluZWZpZWxkLmdldCgpKSAt
IDEKCQkJaWYgbGluZW5vIDw+IHNlbGYubGFzdGxpbmVubzoKCQkJCXNlbGYuZWRpdGdyb3Vw
LmVkaXRvci5zZWxlY3RsaW5lKGxpbmVubykKCQkJCXNlbGYudXBkYXRlc2VsZWN0aW9uKDEp
CgkJZXhjZXB0OgoJCQlzZWxmLnVwZGF0ZXNlbGVjdGlvbigxKQoJCXNlbGYuZWRpdGdyb3Vw
LmVkaXRvci5zZWxlY3QoMSkKCQoJZGVmIHNldGluZm90ZXh0KHNlbGYpOgoJCWlmIG5vdCBo
YXNhdHRyKHNlbGYsICdpbmZvdGV4dCcpOgoJCQlyZXR1cm4KCQlpZiBzZWxmLnBhdGg6CgkJ
CXNlbGYuaW5mb3RleHQuc2V0KHNlbGYucGF0aCkKCQllbHNlOgoJCQlzZWxmLmluZm90ZXh0
LnNldCgiIikKCQoJZGVmIGNsb3NlKHNlbGYpOgoJCWlmIHNlbGYuZWRpdGdyb3VwLmVkaXRv
ci5jaGFuZ2VkOgoJCQlpbXBvcnQgRWFzeURpYWxvZ3MKCQkJUWQuSW5pdEN1cnNvcigpCgkJ
CXNhdmUgPSBFYXN5RGlhbG9ncy5Bc2tZZXNOb0NhbmNlbCgnU2F2ZSB3aW5kb3cgIiVzIiBi
ZWZvcmUgY2xvc2luZz8nICUgc2VsZi50aXRsZSwKCQkJCQlkZWZhdWx0PTEsIG5vPSJEb25c
eGQ1dCBzYXZlIikKCQkJaWYgc2F2ZSA+IDA6CgkJCQlpZiBzZWxmLmRvbWVudV9zYXZlKCk6
CgkJCQkJcmV0dXJuIDEKCQkJZWxpZiBzYXZlIDwgMDoKCQkJCXJldHVybiAxCgkJc2VsZi5n
bG9iYWxzID0gTm9uZQoJCVcuV2luZG93LmNsb3NlKHNlbGYpCgkKCWRlZiBkb21lbnVfY2xv
c2Uoc2VsZiwgKmFyZ3MpOgoJCXJldHVybiBzZWxmLmNsb3NlKCkKCQoJZGVmIGRvbWVudV9z
YXZlKHNlbGYsICphcmdzKToKCQlpZiBub3Qgc2VsZi5wYXRoOgoJCQkjIFdpbGwgY2FsbCB1
cyByZWN1cnNpdmVseQoJCQlyZXR1cm4gc2VsZi5kb21lbnVfc2F2ZV9hcygpCgkJZGF0YSA9
IHNlbGYuZWRpdGdyb3VwLmVkaXRvci5nZXQoKQoJCWlmIHNlbGYuX2VvbG4gIT0gJ1xyJzoK
CQkJZGF0YSA9IHN0cmluZy5yZXBsYWNlKGRhdGEsICdccicsIHNlbGYuX2VvbG4pCgkJZnAg
PSBvcGVuKHNlbGYucGF0aCwgJ3diJykgICMgb3BlbiBmaWxlIGluIGJpbmFyeSBtb2RlLCBk
YXRhIGhhcyAnXHInIGxpbmUtZW5kaW5ncwoJCWZwLndyaXRlKGRhdGEpCgkJZnAuY2xvc2Uo
KQoJCWZzcyA9IG1hY2ZzLkZTU3BlYyhzZWxmLnBhdGgpCgkJZnNzLlNldENyZWF0b3JUeXBl
KHNlbGYuX2NyZWF0b3IsICdURVhUJykKCQlzZWxmLmdldHNldHRpbmdzKCkKCQlzZWxmLndy
aXRld2luZG93c2V0dGluZ3MoKQoJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5jaGFuZ2VkID0g
MAoJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5zZWxjaGFuZ2VkID0gMAoJCWltcG9ydCBsaW5l
Y2FjaGUKCQlpZiBsaW5lY2FjaGUuY2FjaGUuaGFzX2tleShzZWxmLnBhdGgpOgoJCQlkZWwg
bGluZWNhY2hlLmNhY2hlW3NlbGYucGF0aF0KCQlpbXBvcnQgbWFjb3N0b29scwoJCW1hY29z
dG9vbHMudG91Y2hlZChzZWxmLnBhdGgpCgkKCWRlZiBjYW5fc2F2ZShzZWxmLCBtZW51aXRl
bSk6CgkJcmV0dXJuIHNlbGYuZWRpdGdyb3VwLmVkaXRvci5jaGFuZ2VkIG9yIHNlbGYuZWRp
dGdyb3VwLmVkaXRvci5zZWxjaGFuZ2VkCgkKCWRlZiBkb21lbnVfc2F2ZV9hcyhzZWxmLCAq
YXJncyk6CgkJZnNzLCBvayA9IG1hY2ZzLlN0YW5kYXJkUHV0RmlsZSgnU2F2ZSBhczonLCBz
ZWxmLnRpdGxlKQoJCWlmIG5vdCBvazogCgkJCXJldHVybiAxCgkJc2VsZi5zaG93YnJlYWtw
b2ludHMoMCkKCQlzZWxmLnBhdGggPSBmc3MuYXNfcGF0aG5hbWUoKQoJCXNlbGYuc2V0aW5m
b3RleHQoKQoJCXNlbGYudGl0bGUgPSBvcy5wYXRoLnNwbGl0KHNlbGYucGF0aClbLTFdCgkJ
c2VsZi53aWQuU2V0V1RpdGxlKHNlbGYudGl0bGUpCgkJc2VsZi5kb21lbnVfc2F2ZSgpCgkJ
c2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnNldGZpbGUoc2VsZi5nZXRmaWxlbmFtZSgpKQoJCWFw
cCA9IFcuZ2V0YXBwbGljYXRpb24oKQoJCWFwcC5tYWtlb3BlbndpbmRvd3NtZW51KCkKCQlp
ZiBoYXNhdHRyKGFwcCwgJ21ha2VzY3JpcHRzbWVudScpOgoJCQlhcHAgPSBXLmdldGFwcGxp
Y2F0aW9uKCkKCQkJZnNzLCBmc3NfY2hhbmdlZCA9IGFwcC5zY3JpcHRzZm9sZGVyLlJlc29s
dmUoKQoJCQlwYXRoID0gZnNzLmFzX3BhdGhuYW1lKCkKCQkJaWYgcGF0aCA9PSBzZWxmLnBh
dGhbOmxlbihwYXRoKV06CgkJCQlXLmdldGFwcGxpY2F0aW9uKCkubWFrZXNjcmlwdHNtZW51
KCkKCQoJZGVmIGRvbWVudV9zYXZlX2FzX2FwcGxldChzZWxmLCAqYXJncyk6CgkJaW1wb3J0
IGJ1aWxkdG9vbHMKCQkKCQlidWlsZHRvb2xzLkRFQlVHID0gMAkjIG91Y2guCgkJCgkJaWYg
c2VsZi50aXRsZVstMzpdID09ICIucHkiOgoJCQlkZXN0bmFtZSA9IHNlbGYudGl0bGVbOi0z
XQoJCWVsc2U6CgkJCWRlc3RuYW1lID0gc2VsZi50aXRsZSArICIuYXBwbGV0IgoJCWZzcywg
b2sgPSBtYWNmcy5TdGFuZGFyZFB1dEZpbGUoJ1NhdmUgYXMgQXBwbGV0OicsIGRlc3RuYW1l
KQoJCWlmIG5vdCBvazogCgkJCXJldHVybiAxCgkJVy5TZXRDdXJzb3IoIndhdGNoIikKCQlk
ZXN0bmFtZSA9IGZzcy5hc19wYXRobmFtZSgpCgkJaWYgc2VsZi5wYXRoOgoJCQlmaWxlbmFt
ZSA9IHNlbGYucGF0aAoJCQlpZiBmaWxlbmFtZVstMzpdID09ICIucHkiOgoJCQkJcnNyY25h
bWUgPSBmaWxlbmFtZVs6LTNdICsgJy5yc3JjJwoJCQllbHNlOgoJCQkJcnNyY25hbWUgPSBm
aWxlbmFtZSArICcucnNyYycKCQllbHNlOgoJCQlmaWxlbmFtZSA9IHNlbGYudGl0bGUKCQkJ
cnNyY25hbWUgPSAiIgoJCQoJCXB5dGV4dCA9IHNlbGYuZWRpdGdyb3VwLmVkaXRvci5nZXQo
KQoJCXB5dGV4dCA9IHN0cmluZy5zcGxpdChweXRleHQsICdccicpCgkJcHl0ZXh0ID0gc3Ry
aW5nLmpvaW4ocHl0ZXh0LCAnXG4nKSArICdcbicKCQl0cnk6CgkJCWNvZGUgPSBjb21waWxl
KHB5dGV4dCwgZmlsZW5hbWUsICJleGVjIikKCQlleGNlcHQgKFN5bnRheEVycm9yLCBFT0ZF
cnJvcik6CgkJCXJhaXNlIGJ1aWxkdG9vbHMuQnVpbGRFcnJvciwgIlN5bnRheCBlcnJvciBp
biBzY3JpcHQgJXMiICUgYGZpbGVuYW1lYAoJCQoJCSMgVHJ5IHJlbW92aW5nIHRoZSBvdXRw
dXQgZmlsZQoJCXRyeToKCQkJb3MucmVtb3ZlKGRlc3RuYW1lKQoJCWV4Y2VwdCBvcy5lcnJv
cjoKCQkJcGFzcwoJCXRlbXBsYXRlID0gYnVpbGR0b29scy5maW5kdGVtcGxhdGUoKQoJCWJ1
aWxkdG9vbHMucHJvY2Vzc19jb21tb24odGVtcGxhdGUsIE5vbmUsIGNvZGUsIHJzcmNuYW1l
LCBkZXN0bmFtZSwgMCwgMSkKCQoJZGVmIGRvbWVudV9nb3RvbGluZShzZWxmLCAqYXJncyk6
CgkJc2VsZi5saW5lZmllbGQuc2VsZWN0YWxsKCkKCQlzZWxmLmxpbmVmaWVsZC5zZWxlY3Qo
MSkKCQlzZWxmLmxpbmVmaWVsZC5zZWxlY3RhbGwoKQoJCglkZWYgZG9tZW51X3NlbGVjdGxp
bmUoc2VsZiwgKmFyZ3MpOgoJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5leHBhbmRzZWxlY3Rp
b24oKQoJCglkZWYgZG9tZW51X2ZpbmQoc2VsZiwgKmFyZ3MpOgoJCXNlYXJjaGVuZ2luZS5z
aG93KCkKCQoJZGVmIGRvbWVudV9lbnRlcnNlYXJjaHN0cmluZyhzZWxmLCAqYXJncyk6CgkJ
c2VhcmNoZW5naW5lLnNldGZpbmRzdHJpbmcoKQoJCglkZWYgZG9tZW51X3JlcGxhY2Uoc2Vs
ZiwgKmFyZ3MpOgoJCXNlYXJjaGVuZ2luZS5yZXBsYWNlKCkKCQoJZGVmIGRvbWVudV9maW5k
bmV4dChzZWxmLCAqYXJncyk6CgkJc2VhcmNoZW5naW5lLmZpbmRuZXh0KCkKCQoJZGVmIGRv
bWVudV9yZXBsYWNlZmluZChzZWxmLCAqYXJncyk6CgkJc2VhcmNoZW5naW5lLnJlcGxhY2Vm
aW5kKCkKCQoJZGVmIGRvbWVudV9ydW4oc2VsZiwgKmFyZ3MpOgoJCXNlbGYucnVuYnV0dG9u
LnB1c2goKQoJCglkZWYgZG9tZW51X3J1bnNlbGVjdGlvbihzZWxmLCAqYXJncyk6CgkJc2Vs
Zi5ydW5zZWxidXR0b24ucHVzaCgpCgkKCWRlZiBydW4oc2VsZik6CgkJaWYgc2VsZi5fdGhy
ZWFkc3RhdGUgPT0gKDAsIDApOgoJCQlzZWxmLl9ydW4oKQoJCWVsc2U6CgkJCWxvY2sgPSBX
dGhyZWFkaW5nLkxvY2soKQoJCQlsb2NrLmFjcXVpcmUoKQoJCQlzZWxmLl90aHJlYWQucG9z
dEV4Y2VwdGlvbihLZXlib2FyZEludGVycnVwdCkKCQkJaWYgc2VsZi5fdGhyZWFkLmlzQmxv
Y2tlZCgpOgoJCQkJc2VsZi5fdGhyZWFkLnN0YXJ0KCkKCQkJbG9jay5yZWxlYXNlKCkKCQoJ
ZGVmIF9ydW4oc2VsZik6CgkJaWYgc2VsZi5ydW5fd2l0aF9pbnRlcnByZXRlcjoKCQkJaWYg
c2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmNoYW5nZWQ6CgkJCQlpbXBvcnQgRWFzeURpYWxvZ3MK
CQkJCVFkLkluaXRDdXJzb3IoKQoJCQkJc2F2ZSA9IEVhc3lEaWFsb2dzLkFza1llc05vQ2Fu
Y2VsKCdTYXZlICIlcyIgYmVmb3JlIHJ1bm5pbmc/JyAlIHNlbGYudGl0bGUsIDEpCgkJCQlp
ZiBzYXZlID4gMDoKCQkJCQlpZiBzZWxmLmRvbWVudV9zYXZlKCk6CgkJCQkJCXJldHVybgoJ
CQkJZWxpZiBzYXZlIDwgMDoKCQkJCQlyZXR1cm4KCQkJaWYgbm90IHNlbGYucGF0aDoKCQkJ
CXJhaXNlIFcuQWxlcnRFcnJvciwgIkNhbid0IHJ1biB1bnNhdmVkIGZpbGUiCgkJCXNlbGYu
X3J1bl93aXRoX2ludGVycHJldGVyKCkKCQllbGlmIHNlbGYucnVuX3dpdGhfY2xfaW50ZXJw
cmV0ZXI6CgkJCWlmIHNlbGYuZWRpdGdyb3VwLmVkaXRvci5jaGFuZ2VkOgoJCQkJaW1wb3J0
IEVhc3lEaWFsb2dzCgkJCQlRZC5Jbml0Q3Vyc29yKCkKCQkJCXNhdmUgPSBFYXN5RGlhbG9n
cy5Bc2tZZXNOb0NhbmNlbCgnU2F2ZSAiJXMiIGJlZm9yZSBydW5uaW5nPycgJSBzZWxmLnRp
dGxlLCAxKQoJCQkJaWYgc2F2ZSA+IDA6CgkJCQkJaWYgc2VsZi5kb21lbnVfc2F2ZSgpOgoJ
CQkJCQlyZXR1cm4KCQkJCWVsaWYgc2F2ZSA8IDA6CgkJCQkJcmV0dXJuCgkJCWlmIG5vdCBz
ZWxmLnBhdGg6CgkJCQlyYWlzZSBXLkFsZXJ0RXJyb3IsICJDYW4ndCBydW4gdW5zYXZlZCBm
aWxlIgoJCQlzZWxmLl9ydW5fd2l0aF9jbF9pbnRlcnByZXRlcigpCgkJZWxzZToKCQkJcHl0
ZXh0ID0gc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmdldCgpCgkJCWdsb2JhbHMsIGZpbGUsIG1v
ZG5hbWUgPSBzZWxmLmdldGVudmlyb25tZW50KCkKCQkJc2VsZi5leGVjc3RyaW5nKHB5dGV4
dCwgZ2xvYmFscywgZ2xvYmFscywgZmlsZSwgbW9kbmFtZSkKCQoJZGVmIF9ydW5fd2l0aF9p
bnRlcnByZXRlcihzZWxmKToKCQlpbnRlcnBfcGF0aCA9IG9zLnBhdGguam9pbihzeXMuZXhl
Y19wcmVmaXgsICJQeXRob25JbnRlcnByZXRlciIpCgkJaWYgbm90IG9zLnBhdGguZXhpc3Rz
KGludGVycF9wYXRoKToKCQkJcmFpc2UgVy5BbGVydEVycm9yLCAiQ2FuJ3QgZmluZCBpbnRl
cnByZXRlciIKCQlpbXBvcnQgZmluZGVydG9vbHMKCQlYWFgKCglkZWYgX3J1bl93aXRoX2Ns
X2ludGVycHJldGVyKHNlbGYpOgoJCWltcG9ydCBUZXJtaW5hbAoJCWludGVycF9wYXRoID0g
b3MucGF0aC5qb2luKHN5cy5leGVjX3ByZWZpeCwgImJpbiIsICJweXRob24iKQoJCWZpbGVf
cGF0aCA9IHNlbGYucGF0aAoJCWlmIG5vdCBvcy5wYXRoLmV4aXN0cyhpbnRlcnBfcGF0aCk6
CgkJCSMgVGhpcyAiY2FuIGhhcHBlbiIgaWYgd2UgYXJlIHJ1bm5pbmcgSURFIHVuZGVyIE1h
Y1B5dGhvbi4gVHJ5CgkJCSMgdGhlIHN0YW5kYXJkIGxvY2F0aW9uLgoJCQlpbnRlcnBfcGF0
aCA9ICIvTGlicmFyeS9GcmFtZXdvcmtzL1B5dGhvbi5mcmFtZXdvcmsvVmVyc2lvbnMvMi4z
L2Jpbi9weXRob24iCgkJCXRyeToKCQkJCWZzciA9IG1hY2ZzLkZTUmVmKGludGVycF9wYXRo
KQoJCQlleGNlcHQgbWFjZnMuRXJyb3I6CgkJCQlyYWlzZSBXLkFsZXJ0RXJyb3IsICJDYW4n
dCBmaW5kIGNvbW1hbmQtbGluZSBQeXRob24iCgkJCWZpbGVfcGF0aCA9IG1hY2ZzLkZTUmVm
KG1hY2ZzLkZTU3BlYyhzZWxmLnBhdGgpKS5hc19wYXRobmFtZSgpCgkJY21kID0gJyIlcyIg
IiVzIiA7IGV4aXQnICUgKGludGVycF9wYXRoLCBmaWxlX3BhdGgpCgkJdCA9IFRlcm1pbmFs
LlRlcm1pbmFsKCkKCQl0LmRvX3NjcmlwdCh3aXRoX2NvbW1hbmQ9Y21kKQoJCglkZWYgcnVu
c2VsZWN0aW9uKHNlbGYpOgoJCWlmIHNlbGYuX3RocmVhZHN0YXRlID09ICgwLCAwKToKCQkJ
c2VsZi5fcnVuc2VsZWN0aW9uKCkKCQllbGlmIHNlbGYuX3RocmVhZHN0YXRlID09ICgxLCAx
KToKCQkJc2VsZi5fdGhyZWFkLmJsb2NrKCkKCQkJc2VsZi5zZXR0aHJlYWRzdGF0ZSgoMSwg
MikpCgkJZWxpZiBzZWxmLl90aHJlYWRzdGF0ZSA9PSAoMSwgMik6CgkJCXNlbGYuX3RocmVh
ZC5zdGFydCgpCgkJCXNlbGYuc2V0dGhyZWFkc3RhdGUoKDEsIDEpKQoJCglkZWYgX3J1bnNl
bGVjdGlvbihzZWxmKToKCQlpZiBzZWxmLnJ1bl93aXRoX2ludGVycHJldGVyIG9yIHNlbGYu
cnVuX3dpdGhfY2xfaW50ZXJwcmV0ZXI6CgkJCXJhaXNlIFcuQWxlcnRFcnJvciwgIkNhbid0
IHJ1biBzZWxlY3Rpb24gd2l0aCBJbnRlcnByZXRlciIKCQlnbG9iYWxzLCBmaWxlLCBtb2Ru
YW1lID0gc2VsZi5nZXRlbnZpcm9ubWVudCgpCgkJbG9jYWxzID0gZ2xvYmFscwoJCSMgc2Vs
ZWN0IHdob2xlIGxpbmVzCgkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmV4cGFuZHNlbGVjdGlv
bigpCgkJCgkJIyBnZXQgbGluZW5vIG9mIGZpcnN0IHNlbGVjdGVkIGxpbmUKCQlzZWxzdGFy
dCwgc2VsZW5kID0gc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmdldHNlbGVjdGlvbigpCgkJc2Vs
c3RhcnQsIHNlbGVuZCA9IG1pbihzZWxzdGFydCwgc2VsZW5kKSwgbWF4KHNlbHN0YXJ0LCBz
ZWxlbmQpCgkJc2VsZmlyc3RsaW5lID0gc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLm9mZnNldHRv
bGluZShzZWxzdGFydCkKCQlhbGx0ZXh0ID0gc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmdldCgp
CgkJcHl0ZXh0ID0gYWxsdGV4dFtzZWxzdGFydDpzZWxlbmRdCgkJbGluZXMgPSBzdHJpbmcu
c3BsaXQocHl0ZXh0LCAnXHInKQoJCWluZGVudCA9IGdldG1pbmluZGVudChsaW5lcykKCQlp
ZiBpbmRlbnQgPT0gMToKCQkJY2xhc3NuYW1lID0gJycKCQkJYWxsbGluZXMgPSBzdHJpbmcu
c3BsaXQoYWxsdGV4dCwgJ1xyJykKCQkJZm9yIGkgaW4gcmFuZ2Uoc2VsZmlyc3RsaW5lIC0g
MSwgLTEsIC0xKToKCQkJCWxpbmUgPSBhbGxsaW5lc1tpXQoJCQkJaWYgbGluZVs6Nl0gPT0g
J2NsYXNzICc6CgkJCQkJY2xhc3NuYW1lID0gc3RyaW5nLnNwbGl0KHN0cmluZy5zdHJpcChs
aW5lWzY6XSkpWzBdCgkJCQkJY2xhc3NlbmQgPSBpZGVudGlmaWVSRV9tYXRjaChjbGFzc25h
bWUpCgkJCQkJaWYgY2xhc3NlbmQgPCAxOgoJCQkJCQlyYWlzZSBXLkFsZXJ0RXJyb3IsICJD
YW4ndCBmaW5kIGEgY2xhc3MuIgoJCQkJCWNsYXNzbmFtZSA9IGNsYXNzbmFtZVs6Y2xhc3Nl
bmRdCgkJCQkJYnJlYWsKCQkJCWVsaWYgbGluZSBhbmQgbGluZVswXSBub3QgaW4gJ1x0Iyc6
CgkJCQkJcmFpc2UgVy5BbGVydEVycm9yLCAiQ2FuJ3QgZmluZCBhIGNsYXNzLiIKCQkJZWxz
ZToKCQkJCXJhaXNlIFcuQWxlcnRFcnJvciwgIkNhbid0IGZpbmQgYSBjbGFzcy4iCgkJCWlm
IGdsb2JhbHMuaGFzX2tleShjbGFzc25hbWUpOgoJCQkJa2xhc3MgPSBnbG9iYWxzW2NsYXNz
bmFtZV0KCQkJZWxzZToKCQkJCXJhaXNlIFcuQWxlcnRFcnJvciwgIkNhbid0IGZpbmQgY2xh
c3MgXCIlc1wiLiIgJSBjbGFzc25hbWUKCQkJIyBhZGQgY2xhc3MgZGVmCgkJCXB5dGV4dCA9
ICgiY2xhc3MgJXM6XG4iICUgY2xhc3NuYW1lKSArIHB5dGV4dAoJCQlzZWxmaXJzdGxpbmUg
PSBzZWxmaXJzdGxpbmUgLSAxCgkJZWxpZiBpbmRlbnQgPiAwOgoJCQlyYWlzZSBXLkFsZXJ0
RXJyb3IsICJDYW4ndCBydW4gaW5kZW50ZWQgY29kZS4iCgkJCgkJIyBhZGQgIm5ld2xpbmVz
IiB0byBmb29sIGNvbXBpbGUvZXhlYzogCgkJIyBub3cgYSB0cmFjZWJhY2sgd2lsbCBnaXZl
IHRoZSByaWdodCBsaW5lIG51bWJlcgoJCXB5dGV4dCA9IHNlbGZpcnN0bGluZSAqICdccicg
KyBweXRleHQKCQlzZWxmLmV4ZWNzdHJpbmcocHl0ZXh0LCBnbG9iYWxzLCBsb2NhbHMsIGZp
bGUsIG1vZG5hbWUpCgkJaWYgaW5kZW50ID09IDEgYW5kIGdsb2JhbHNbY2xhc3NuYW1lXSBp
cyBub3Qga2xhc3M6CgkJCSMgdXBkYXRlIHRoZSBjbGFzcyBpbiBwbGFjZQoJCQlrbGFzcy5f
X2RpY3RfXy51cGRhdGUoZ2xvYmFsc1tjbGFzc25hbWVdLl9fZGljdF9fKQoJCQlnbG9iYWxz
W2NsYXNzbmFtZV0gPSBrbGFzcwoJCglkZWYgc2V0dGhyZWFkc3RhdGUoc2VsZiwgc3RhdGUp
OgoJCW9sZHN0YXRlID0gc2VsZi5fdGhyZWFkc3RhdGUKCQlpZiBvbGRzdGF0ZVswXSA8PiBz
dGF0ZVswXToKCQkJc2VsZi5ydW5idXR0b24uc2V0dGl0bGUocnVuQnV0dG9uTGFiZWxzW3N0
YXRlWzBdXSkKCQlpZiBvbGRzdGF0ZVsxXSA8PiBzdGF0ZVsxXToKCQkJc2VsZi5ydW5zZWxi
dXR0b24uc2V0dGl0bGUocnVuU2VsQnV0dG9uTGFiZWxzW3N0YXRlWzFdXSkKCQlzZWxmLl90
aHJlYWRzdGF0ZSA9IHN0YXRlCgkKCWRlZiBfZXhlY190aHJlYWR3cmFwcGVyKHNlbGYsICph
cmdzLCAqKmt3YXJncyk6CgkJYXBwbHkoZXhlY3N0cmluZywgYXJncywga3dhcmdzKQoJCXNl
bGYuc2V0dGhyZWFkc3RhdGUoKDAsIDApKQoJCXNlbGYuX3RocmVhZCA9IE5vbmUKCQoJZGVm
IGV4ZWNzdHJpbmcoc2VsZiwgcHl0ZXh0LCBnbG9iYWxzLCBsb2NhbHMsIGZpbGUsIG1vZG5h
bWUpOgoJCXRyYWNlYmFja3dpbmRvdy5oaWRlKCkKCQkjIHVwZGF0ZSB3aW5kb3dzCgkJVy5n
ZXRhcHBsaWNhdGlvbigpLnJlZnJlc2h3aW5kb3dzKCkKCQlpZiBzZWxmLnJ1bl9hc19tYWlu
OgoJCQltb2RuYW1lID0gIl9fbWFpbl9fIgoJCWlmIHNlbGYucGF0aDoKCQkJZGlyID0gb3Mu
cGF0aC5kaXJuYW1lKHNlbGYucGF0aCkKCQkJc2F2ZWRpciA9IG9zLmdldGN3ZCgpCgkJCW9z
LmNoZGlyKGRpcikKCQkJc3lzLnBhdGguaW5zZXJ0KDAsIGRpcikKCQllbHNlOgoJCQljd2Rp
bmRleCA9IE5vbmUKCQl0cnk6CgkJCWlmIGhhdmVUaHJlYWRpbmc6CgkJCQlzZWxmLl90aHJl
YWQgPSBXdGhyZWFkaW5nLlRocmVhZChvcy5wYXRoLmJhc2VuYW1lKGZpbGUpLCAKCQkJCQkJ
CXNlbGYuX2V4ZWNfdGhyZWFkd3JhcHBlciwgcHl0ZXh0LCBnbG9iYWxzLCBsb2NhbHMsIGZp
bGUsIHNlbGYuZGVidWdnaW5nLCAKCQkJCQkJCW1vZG5hbWUsIHNlbGYucHJvZmlsaW5nKQoJ
CQkJc2VsZi5zZXR0aHJlYWRzdGF0ZSgoMSwgMSkpCgkJCQlzZWxmLl90aHJlYWQuc3RhcnQo
KQoJCQllbHNlOgoJCQkJZXhlY3N0cmluZyhweXRleHQsIGdsb2JhbHMsIGxvY2FscywgZmls
ZSwgc2VsZi5kZWJ1Z2dpbmcsIAoJCQkJCQkJbW9kbmFtZSwgc2VsZi5wcm9maWxpbmcpCgkJ
ZmluYWxseToKCQkJaWYgc2VsZi5wYXRoOgoJCQkJb3MuY2hkaXIoc2F2ZWRpcikKCQkJCWRl
bCBzeXMucGF0aFswXQoJCglkZWYgZ2V0ZW52aXJvbm1lbnQoc2VsZik6CgkJaWYgc2VsZi5w
YXRoOgoJCQlmaWxlID0gc2VsZi5wYXRoCgkJCWRpciA9IG9zLnBhdGguZGlybmFtZShmaWxl
KQoJCQkjIGNoZWNrIGlmIHdlJ3JlIHBhcnQgb2YgYSBwYWNrYWdlCgkJCW1vZG5hbWUgPSAi
IgoJCQl3aGlsZSBvcy5wYXRoLmV4aXN0cyhvcy5wYXRoLmpvaW4oZGlyLCAiX19pbml0X18u
cHkiKSk6CgkJCQlkaXIsIGRpcm5hbWUgPSBvcy5wYXRoLnNwbGl0KGRpcikKCQkJCW1vZG5h
bWUgPSBkaXJuYW1lICsgJy4nICsgbW9kbmFtZQoJCQlzdWJuYW1lID0gX2ZpbGVuYW1lX2Fz
X21vZG5hbWUoc2VsZi50aXRsZSkKCQkJaWYgc3VibmFtZSBpcyBOb25lOgoJCQkJcmV0dXJu
IHNlbGYuZ2xvYmFscywgZmlsZSwgTm9uZQoJCQlpZiBtb2RuYW1lOgoJCQkJaWYgc3VibmFt
ZSA9PSAiX19pbml0X18iOgoJCQkJCSMgc3RyaXAgdHJhaWxpbmcgcGVyaW9kCgkJCQkJbW9k
bmFtZSA9IG1vZG5hbWVbOi0xXQoJCQkJZWxzZToKCQkJCQltb2RuYW1lID0gbW9kbmFtZSAr
IHN1Ym5hbWUKCQkJZWxzZToKCQkJCW1vZG5hbWUgPSBzdWJuYW1lCgkJCWlmIHN5cy5tb2R1
bGVzLmhhc19rZXkobW9kbmFtZSk6CgkJCQlnbG9iYWxzID0gc3lzLm1vZHVsZXNbbW9kbmFt
ZV0uX19kaWN0X18KCQkJCXNlbGYuZ2xvYmFscyA9IHt9CgkJCWVsc2U6CgkJCQlnbG9iYWxz
ID0gc2VsZi5nbG9iYWxzCgkJCQltb2RuYW1lID0gc3VibmFtZQoJCWVsc2U6CgkJCWZpbGUg
PSAnPCVzPicgJSBzZWxmLnRpdGxlCgkJCWdsb2JhbHMgPSBzZWxmLmdsb2JhbHMKCQkJbW9k
bmFtZSA9IGZpbGUKCQlyZXR1cm4gZ2xvYmFscywgZmlsZSwgbW9kbmFtZQoJCglkZWYgd3Jp
dGUoc2VsZiwgc3R1ZmYpOgoJCSIiImZvciB1c2UgYXMgc3Rkb3V0IiIiCgkJc2VsZi5fYnVm
ID0gc2VsZi5fYnVmICsgc3R1ZmYKCQlpZiAnXG4nIGluIHNlbGYuX2J1ZjoKCQkJc2VsZi5m
bHVzaCgpCgkKCWRlZiBmbHVzaChzZWxmKToKCQlzdHVmZiA9IHN0cmluZy5zcGxpdChzZWxm
Ll9idWYsICdcbicpCgkJc3R1ZmYgPSBzdHJpbmcuam9pbihzdHVmZiwgJ1xyJykKCQllbmQg
PSBzZWxmLmVkaXRncm91cC5lZGl0b3IudGVkLldFR2V0VGV4dExlbmd0aCgpCgkJc2VsZi5l
ZGl0Z3JvdXAuZWRpdG9yLnRlZC5XRVNldFNlbGVjdGlvbihlbmQsIGVuZCkKCQlzZWxmLmVk
aXRncm91cC5lZGl0b3IudGVkLldFSW5zZXJ0KHN0dWZmLCBOb25lLCBOb25lKQoJCXNlbGYu
ZWRpdGdyb3VwLmVkaXRvci51cGRhdGVzY3JvbGxiYXJzKCkKCQlzZWxmLl9idWYgPSAiIgoJ
CSMgPyBvcHRpb25hbDoKCQkjc2VsZi53aWQuU2VsZWN0V2luZG93KCkKCQoJZGVmIGdldGNs
YXNzbGlzdChzZWxmKToKCQlmcm9tIHN0cmluZyBpbXBvcnQgZmluZCwgc3RyaXAKCQltZXRo
b2RSRSA9IHJlLmNvbXBpbGUociJcclsgXHRdK2RlZiAiKQoJCWZpbmRNZXRob2QgPSBtZXRo
b2RSRS5zZWFyY2gKCQllZGl0b3IgPSBzZWxmLmVkaXRncm91cC5lZGl0b3IKCQl0ZXh0ID0g
ZWRpdG9yLmdldCgpCgkJbGlzdCA9IFtdCgkJYXBwZW5kID0gbGlzdC5hcHBlbmQKCQlmdW5j
dGFnID0gImZ1bmMiCgkJY2xhc3N0YWcgPSAiY2xhc3MiCgkJbWV0aG9kdGFnID0gIm1ldGhv
ZCIKCQlwb3MgPSAtMQoJCWlmIHRleHRbOjRdID09ICdkZWYgJzoKCQkJYXBwZW5kKChwb3Mg
KyA0LCBmdW5jdGFnKSkKCQkJcG9zID0gNAoJCXdoaWxlIDE6CgkJCXBvcyA9IGZpbmQodGV4
dCwgJ1xyZGVmICcsIHBvcyArIDEpCgkJCWlmIHBvcyA8IDA6CgkJCQlicmVhawoJCQlhcHBl
bmQoKHBvcyArIDUsIGZ1bmN0YWcpKQoJCXBvcyA9IC0xCgkJaWYgdGV4dFs6Nl0gPT0gJ2Ns
YXNzICc6CgkJCWFwcGVuZCgocG9zICsgNiwgY2xhc3N0YWcpKQoJCQlwb3MgPSA2CgkJd2hp
bGUgMToKCQkJcG9zID0gZmluZCh0ZXh0LCAnXHJjbGFzcyAnLCBwb3MgKyAxKQoJCQlpZiBw
b3MgPCAwOgoJCQkJYnJlYWsKCQkJYXBwZW5kKChwb3MgKyA3LCBjbGFzc3RhZykpCgkJcG9z
ID0gMAoJCXdoaWxlIDE6CgkJCW0gPSBmaW5kTWV0aG9kKHRleHQsIHBvcyArIDEpCgkJCWlm
IG0gaXMgTm9uZToKCQkJCWJyZWFrCgkJCXBvcyA9IG0ucmVnc1swXVswXQoJCQkjcG9zID0g
ZmluZCh0ZXh0LCAnXHJcdGRlZiAnLCBwb3MgKyAxKQoJCQlhcHBlbmQoKG0ucmVnc1swXVsx
XSwgbWV0aG9kdGFnKSkKCQlsaXN0LnNvcnQoKQoJCWNsYXNzbGlzdCA9IFtdCgkJbWV0aG9k
bGlzdGFwcGVuZCA9IE5vbmUKCQlvZmZzZXRUb0xpbmUgPSBlZGl0b3IudGVkLldFT2Zmc2V0
VG9MaW5lCgkJZ2V0TGluZVJhbmdlID0gZWRpdG9yLnRlZC5XRUdldExpbmVSYW5nZQoJCWFw
cGVuZCA9IGNsYXNzbGlzdC5hcHBlbmQKCQlmb3IgcG9zLCB0YWcgaW4gbGlzdDoKCQkJbGlu
ZW5vID0gb2Zmc2V0VG9MaW5lKHBvcykKCQkJbGluZVN0YXJ0LCBsaW5lRW5kID0gZ2V0TGlu
ZVJhbmdlKGxpbmVubykKCQkJbGluZSA9IHN0cmlwKHRleHRbcG9zOmxpbmVFbmRdKQoJCQls
aW5lID0gbGluZVs6aWRlbnRpZmllUkVfbWF0Y2gobGluZSldCgkJCWlmIHRhZyBpcyBmdW5j
dGFnOgoJCQkJYXBwZW5kKCgiZGVmICIgKyBsaW5lLCBsaW5lbm8gKyAxKSkKCQkJCW1ldGhv
ZGxpc3RhcHBlbmQgPSBOb25lCgkJCWVsaWYgdGFnIGlzIGNsYXNzdGFnOgoJCQkJYXBwZW5k
KFsiY2xhc3MgIiArIGxpbmVdKQoJCQkJbWV0aG9kbGlzdGFwcGVuZCA9IGNsYXNzbGlzdFst
MV0uYXBwZW5kCgkJCWVsaWYgbWV0aG9kbGlzdGFwcGVuZCBhbmQgdGFnIGlzIG1ldGhvZHRh
ZzoKCQkJCW1ldGhvZGxpc3RhcHBlbmQoKCJkZWYgIiArIGxpbmUsIGxpbmVubyArIDEpKQoJ
CXJldHVybiBjbGFzc2xpc3QKCQoJZGVmIHBvcHNlbGVjdGxpbmUoc2VsZiwgbGluZW5vKToK
CQlzZWxmLmVkaXRncm91cC5lZGl0b3Iuc2VsZWN0bGluZShsaW5lbm8gLSAxKQoJCglkZWYg
c2VsZWN0bGluZShzZWxmLCBsaW5lbm8sIGNoYXJvZmZzZXQgPSAwKToKCQlzZWxmLmVkaXRn
cm91cC5lZGl0b3Iuc2VsZWN0bGluZShsaW5lbm8gLSAxLCBjaGFyb2Zmc2V0KQoKY2xhc3Mg
X3NhdmVvcHRpb25zOgoJCglkZWYgX19pbml0X18oc2VsZiwgY3JlYXRvciwgZW9sbik6CgkJ
c2VsZi5ydiA9IE5vbmUKCQlzZWxmLmVvbG4gPSBlb2xuCgkJc2VsZi53ID0gdyA9IFcuTW9k
YWxEaWFsb2coKDI2MCwgMTYwKSwgJ1NhdmUgb3B0aW9ucycpCgkJcmFkaW9idXR0b25zID0g
W10KCQl3LmxhYmVsID0gVy5UZXh0Qm94KCg4LCA4LCA4MCwgMTgpLCAiRmlsZSBjcmVhdG9y
OiIpCgkJdy5pZGVfcmFkaW8gPSBXLlJhZGlvQnV0dG9uKCg4LCAyMiwgMTYwLCAxOCksICJU
aGlzIGFwcGxpY2F0aW9uIiwgcmFkaW9idXR0b25zLCBzZWxmLmlkZV9oaXQpCgkJdy5pbnRl
cnBfcmFkaW8gPSBXLlJhZGlvQnV0dG9uKCg4LCA0MiwgMTYwLCAxOCksICJNYWNQeXRob24g
SW50ZXJwcmV0ZXIiLCByYWRpb2J1dHRvbnMsIHNlbGYuaW50ZXJwX2hpdCkKCQl3LmludGVy
cHhfcmFkaW8gPSBXLlJhZGlvQnV0dG9uKCg4LCA2MiwgMTYwLCAxOCksICJPU1ggUHl0aG9u
VyBJbnRlcnByZXRlciIsIHJhZGlvYnV0dG9ucywgc2VsZi5pbnRlcnB4X2hpdCkKCQl3Lm90
aGVyX3JhZGlvID0gVy5SYWRpb0J1dHRvbigoOCwgODIsIDUwLCAxOCksICJPdGhlcjoiLCBy
YWRpb2J1dHRvbnMpCgkJdy5vdGhlcl9jcmVhdG9yID0gVy5FZGl0VGV4dCgoNjIsIDgyLCA0
MCwgMjApLCBjcmVhdG9yLCBzZWxmLm90aGVyc2VsZWN0KQoJCXcubm9uZV9yYWRpbyA9IFcu
UmFkaW9CdXR0b24oKDgsIDEwMiwgMTYwLCAxOCksICJOb25lIiwgcmFkaW9idXR0b25zLCBz
ZWxmLm5vbmVfaGl0KQoJCXcuY2FuY2VsYnV0dG9uID0gVy5CdXR0b24oKC0xODAsIC0zMCwg
ODAsIDE2KSwgIkNhbmNlbCIsIHNlbGYuY2FuY2VsYnV0dG9uaGl0KQoJCXcub2tidXR0b24g
PSBXLkJ1dHRvbigoLTkwLCAtMzAsIDgwLCAxNiksICJEb25lIiwgc2VsZi5va2J1dHRvbmhp
dCkKCQl3LnNldGRlZmF1bHRidXR0b24ody5va2J1dHRvbikKCQlpZiBjcmVhdG9yID09ICdQ
eXRoJzoKCQkJdy5pbnRlcnBfcmFkaW8uc2V0KDEpCgkJZWxpZiBjcmVhdG9yID09IFcuX3Np
Z25hdHVyZToKCQkJdy5pZGVfcmFkaW8uc2V0KDEpCgkJZWxpZiBjcmVhdG9yID09ICdQeXRY
JzoKCQkJdy5pbnRlcnB4X3JhZGlvLnNldCgxKQoJCWVsaWYgY3JlYXRvciA9PSAnXDBcMFww
XDAnOgoJCQl3Lm5vbmVfcmFkaW8uc2V0KDEpCgkJZWxzZToKCQkJdy5vdGhlcl9yYWRpby5z
ZXQoMSkKCQkJCgkJdy5lb2xubGFiZWwgPSBXLlRleHRCb3goKDE2OCwgOCwgODAsIDE4KSwg
Ik5ld2xpbmUgc3R5bGU6IikKCQlyYWRpb2J1dHRvbnMgPSBbXQoJCXcudW5peF9yYWRpbyA9
IFcuUmFkaW9CdXR0b24oKDE2OCwgMjIsIDgwLCAxOCksICJVbml4IiwgcmFkaW9idXR0b25z
LCBzZWxmLnVuaXhfaGl0KQoJCXcubWFjX3JhZGlvID0gVy5SYWRpb0J1dHRvbigoMTY4LCA0
MiwgODAsIDE4KSwgIk1hY2ludG9zaCIsIHJhZGlvYnV0dG9ucywgc2VsZi5tYWNfaGl0KQoJ
CXcud2luX3JhZGlvID0gVy5SYWRpb0J1dHRvbigoMTY4LCA2MiwgODAsIDE4KSwgIldpbmRv
d3MiLCByYWRpb2J1dHRvbnMsIHNlbGYud2luX2hpdCkKCQlpZiBzZWxmLmVvbG4gPT0gJ1xu
JzoKCQkJdy51bml4X3JhZGlvLnNldCgxKQoJCWVsaWYgc2VsZi5lb2xuID09ICdcclxuJzoK
CQkJdy53aW5fcmFkaW8uc2V0KDEpCgkJZWxzZToKCQkJdy5tYWNfcmFkaW8uc2V0KDEpCgkJ
CgkJdy5iaW5kKCJjbWQuIiwgdy5jYW5jZWxidXR0b24ucHVzaCkKCQl3Lm9wZW4oKQoJCglk
ZWYgaWRlX2hpdChzZWxmKToKCQlzZWxmLncub3RoZXJfY3JlYXRvci5zZXQoVy5fc2lnbmF0
dXJlKQoJCglkZWYgaW50ZXJwX2hpdChzZWxmKToKCQlzZWxmLncub3RoZXJfY3JlYXRvci5z
ZXQoIlB5dGgiKQoJCglkZWYgaW50ZXJweF9oaXQoc2VsZik6CgkJc2VsZi53Lm90aGVyX2Ny
ZWF0b3Iuc2V0KCJQeXRYIikKCQoJZGVmIG5vbmVfaGl0KHNlbGYpOgoJCXNlbGYudy5vdGhl
cl9jcmVhdG9yLnNldCgiXDBcMFwwXDAiKQoJCglkZWYgb3RoZXJzZWxlY3Qoc2VsZiwgKmFy
Z3MpOgoJCXNlbF9mcm9tLCBzZWxfdG8gPSBzZWxmLncub3RoZXJfY3JlYXRvci5nZXRzZWxl
Y3Rpb24oKQoJCWNyZWF0b3IgPSBzZWxmLncub3RoZXJfY3JlYXRvci5nZXQoKVs6NF0KCQlj
cmVhdG9yID0gY3JlYXRvciArICIgIiAqICg0IC0gbGVuKGNyZWF0b3IpKQoJCXNlbGYudy5v
dGhlcl9jcmVhdG9yLnNldChjcmVhdG9yKQoJCXNlbGYudy5vdGhlcl9jcmVhdG9yLnNldHNl
bGVjdGlvbihzZWxfZnJvbSwgc2VsX3RvKQoJCXNlbGYudy5vdGhlcl9yYWRpby5zZXQoMSkK
CQoJZGVmIG1hY19oaXQoc2VsZik6CgkJc2VsZi5lb2xuID0gJ1xyJwoJCQoJZGVmIHVuaXhf
aGl0KHNlbGYpOgoJCXNlbGYuZW9sbiA9ICdcbicKCQkKCWRlZiB3aW5faGl0KHNlbGYpOgoJ
CXNlbGYuZW9sbiA9ICdcclxuJwoJCQoJZGVmIGNhbmNlbGJ1dHRvbmhpdChzZWxmKToKCQlz
ZWxmLncuY2xvc2UoKQoJCglkZWYgb2tidXR0b25oaXQoc2VsZik6CgkJc2VsZi5ydiA9IChz
ZWxmLncub3RoZXJfY3JlYXRvci5nZXQoKVs6NF0sIHNlbGYuZW9sbikKCQlzZWxmLncuY2xv
c2UoKQoKCmRlZiBTYXZlT3B0aW9ucyhjcmVhdG9yLCBlb2xuKToKCXMgPSBfc2F2ZW9wdGlv
bnMoY3JlYXRvciwgZW9sbikKCXJldHVybiBzLnJ2CgoKZGVmIF9lc2NhcGUod2hlcmUsIHdo
YXQpIDogCglyZXR1cm4gc3RyaW5nLmpvaW4oc3RyaW5nLnNwbGl0KHdoZXJlLCB3aGF0KSwg
J1xcJyArIHdoYXQpCgpkZWYgX21ha2V3aG9sZXdvcmRwYXR0ZXJuKHdvcmQpOgoJIyBmaXJz
dCwgZXNjYXBlIHNwZWNpYWwgcmVnZXggY2hhcnMKCWZvciBlc2MgaW4gIlxcW10oKXwuKl4r
JD8iOgoJCXdvcmQgPSBfZXNjYXBlKHdvcmQsIGVzYykKCW5vdHdvcmRjaGFyc3BhdCA9ICdb
XicgKyBfd29yZGNoYXJzICsgJ10nCglwYXR0ZXJuID0gJygnICsgd29yZCArICcpJwoJaWYg
d29yZFswXSBpbiBfd29yZGNoYXJzOgoJCXBhdHRlcm4gPSBub3R3b3JkY2hhcnNwYXQgKyBw
YXR0ZXJuCglpZiB3b3JkWy0xXSBpbiBfd29yZGNoYXJzOgoJCXBhdHRlcm4gPSBwYXR0ZXJu
ICsgbm90d29yZGNoYXJzcGF0CglyZXR1cm4gcmUuY29tcGlsZShwYXR0ZXJuKQoKCmNsYXNz
IFNlYXJjaEVuZ2luZToKCQoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCXNlbGYudmlzaWJsZSA9
IDAKCQlzZWxmLncgPSBOb25lCgkJc2VsZi5wYXJtcyA9IHsgICJmaW5kIjogIiIsCgkJCQkJ
InJlcGxhY2UiOiAiIiwKCQkJCQkid3JhcCI6IDEsCgkJCQkJImNhc2VzZW5zIjogMSwKCQkJ
CQkid2hvbGV3b3JkIjogMQoJCQkJfQoJCWltcG9ydCBNYWNQcmVmcwoJCXByZWZzID0gTWFj
UHJlZnMuR2V0UHJlZnMoVy5nZXRhcHBsaWNhdGlvbigpLnByZWZmaWxlcGF0aCkKCQlpZiBw
cmVmcy5zZWFyY2hlbmdpbmU6CgkJCXNlbGYucGFybXNbImNhc2VzZW5zIl0gPSBwcmVmcy5z
ZWFyY2hlbmdpbmUuY2FzZXNlbnMKCQkJc2VsZi5wYXJtc1sid3JhcCJdID0gcHJlZnMuc2Vh
cmNoZW5naW5lLndyYXAKCQkJc2VsZi5wYXJtc1sid2hvbGV3b3JkIl0gPSBwcmVmcy5zZWFy
Y2hlbmdpbmUud2hvbGV3b3JkCgkKCWRlZiBzaG93KHNlbGYpOgoJCXNlbGYudmlzaWJsZSA9
IDEKCQlpZiBzZWxmLnc6CgkJCXNlbGYudy53aWQuU2hvd1dpbmRvdygpCgkJCXNlbGYudy53
aWQuU2VsZWN0V2luZG93KCkKCQkJc2VsZi53LmZpbmQuZWRpdC5zZWxlY3QoMSkKCQkJc2Vs
Zi53LmZpbmQuZWRpdC5zZWxlY3RhbGwoKQoJCQlyZXR1cm4KCQlzZWxmLncgPSBXLkRpYWxv
ZygoNDIwLCAxNTApLCAiRmluZCIpCgkJCgkJc2VsZi53LmZpbmQgPSBUaXRsZWRFZGl0VGV4
dCgoMTAsIDQsIDMwMCwgMzYpLCAiU2VhcmNoIGZvcjoiKQoJCXNlbGYudy5yZXBsYWNlID0g
VGl0bGVkRWRpdFRleHQoKDEwLCAxMDAsIDMwMCwgMzYpLCAiUmVwbGFjZSB3aXRoOiIpCgkJ
CgkJc2VsZi53LmJveGVzID0gVy5Hcm91cCgoMTAsIDUwLCAzMDAsIDQwKSkKCQlzZWxmLncu
Ym94ZXMuY2FzZXNlbnMgPSBXLkNoZWNrQm94KCgwLCAwLCAxMDAsIDE2KSwgIkNhc2Ugc2Vu
c2l0aXZlIikKCQlzZWxmLncuYm94ZXMud2hvbGV3b3JkID0gVy5DaGVja0JveCgoMCwgMjAs
IDEwMCwgMTYpLCAiV2hvbGUgd29yZCIpCgkJc2VsZi53LmJveGVzLndyYXAgPSBXLkNoZWNr
Qm94KCgxMTAsIDAsIDEwMCwgMTYpLCAiV3JhcCBhcm91bmQiKQoJCQoJCXNlbGYuYnV0dG9u
cyA9IFsJKCJGaW5kIiwJCSJjbWRmIiwJIHNlbGYuZmluZCksIAoJCQkJCSgiUmVwbGFjZSIs
CSAgICAgImNtZHIiLAkgc2VsZi5yZXBsYWNlKSwgCgkJCQkJKCJSZXBsYWNlIGFsbCIsCSBO
b25lLCAgIHNlbGYucmVwbGFjZWFsbCksIAoJCQkJCSgiRG9uJ3QgZmluZCIsICAiY21kZCIs
CSBzZWxmLmRvbnQpLCAKCQkJCQkoIkNhbmNlbCIsCSAgICAgICJjbWQuIiwJIHNlbGYuY2Fu
Y2VsKQoJCQkJXQoJCWZvciBpIGluIHJhbmdlKGxlbihzZWxmLmJ1dHRvbnMpKToKCQkJYm91
bmRzID0gLTkwLCAyMiArIGkgKiAyNCwgODAsIDE2CgkJCXRpdGxlLCBzaG9ydGN1dCwgY2Fs
bGJhY2sgPSBzZWxmLmJ1dHRvbnNbaV0KCQkJc2VsZi53W3RpdGxlXSA9IFcuQnV0dG9uKGJv
dW5kcywgdGl0bGUsIGNhbGxiYWNrKQoJCQlpZiBzaG9ydGN1dDoKCQkJCXNlbGYudy5iaW5k
KHNob3J0Y3V0LCBzZWxmLndbdGl0bGVdLnB1c2gpCgkJc2VsZi53LnNldGRlZmF1bHRidXR0
b24oc2VsZi53WyJEb24ndCBmaW5kIl0pCgkJc2VsZi53LmZpbmQuZWRpdC5iaW5kKCI8a2V5
PiIsIHNlbGYua2V5KQoJCXNlbGYudy5iaW5kKCI8YWN0aXZhdGU+Iiwgc2VsZi5hY3RpdmF0
ZSkKCQlzZWxmLncuYmluZCgiPGNsb3NlPiIsIHNlbGYuY2xvc2UpCgkJc2VsZi53Lm9wZW4o
KQoJCXNlbGYuc2V0cGFybXMoKQoJCXNlbGYudy5maW5kLmVkaXQuc2VsZWN0KDEpCgkJc2Vs
Zi53LmZpbmQuZWRpdC5zZWxlY3RhbGwoKQoJCXNlbGYuY2hlY2tidXR0b25zKCkKCQoJZGVm
IGNsb3NlKHNlbGYpOgoJCXNlbGYuaGlkZSgpCgkJcmV0dXJuIC0xCgkKCWRlZiBrZXkoc2Vs
ZiwgY2hhciwgbW9kaWZpZXJzKToKCQlzZWxmLncuZmluZC5lZGl0LmtleShjaGFyLCBtb2Rp
ZmllcnMpCgkJc2VsZi5jaGVja2J1dHRvbnMoKQoJCXJldHVybiAxCgkKCWRlZiBhY3RpdmF0
ZShzZWxmLCBvbm9mZik6CgkJaWYgb25vZmY6CgkJCXNlbGYuY2hlY2tidXR0b25zKCkKCQoJ
ZGVmIGNoZWNrYnV0dG9ucyhzZWxmKToKCQllZGl0b3IgPSBmaW5kZWRpdG9yKHNlbGYpCgkJ
aWYgZWRpdG9yOgoJCQlpZiBzZWxmLncuZmluZC5nZXQoKToKCQkJCWZvciB0aXRsZSwgY21k
LCBjYWxsIGluIHNlbGYuYnV0dG9uc1s6LTJdOgoJCQkJCXNlbGYud1t0aXRsZV0uZW5hYmxl
KDEpCgkJCQlzZWxmLncuc2V0ZGVmYXVsdGJ1dHRvbihzZWxmLndbIkZpbmQiXSkKCQkJZWxz
ZToKCQkJCWZvciB0aXRsZSwgY21kLCBjYWxsIGluIHNlbGYuYnV0dG9uc1s6LTJdOgoJCQkJ
CXNlbGYud1t0aXRsZV0uZW5hYmxlKDApCgkJCQlzZWxmLncuc2V0ZGVmYXVsdGJ1dHRvbihz
ZWxmLndbIkRvbid0IGZpbmQiXSkKCQllbHNlOgoJCQlmb3IgdGl0bGUsIGNtZCwgY2FsbCBp
biBzZWxmLmJ1dHRvbnNbOi0yXToKCQkJCXNlbGYud1t0aXRsZV0uZW5hYmxlKDApCgkJCXNl
bGYudy5zZXRkZWZhdWx0YnV0dG9uKHNlbGYud1siRG9uJ3QgZmluZCJdKQoJCglkZWYgZmlu
ZChzZWxmKToKCQlzZWxmLmdldHBhcm1zZnJvbXdpbmRvdygpCgkJaWYgc2VsZi5maW5kbmV4
dCgpOgoJCQlzZWxmLmhpZGUoKQoJCglkZWYgcmVwbGFjZShzZWxmKToKCQllZGl0b3IgPSBm
aW5kZWRpdG9yKHNlbGYpCgkJaWYgbm90IGVkaXRvcjoKCQkJcmV0dXJuCgkJaWYgc2VsZi52
aXNpYmxlOgoJCQlzZWxmLmdldHBhcm1zZnJvbXdpbmRvdygpCgkJdGV4dCA9IGVkaXRvci5n
ZXRzZWxlY3RlZHRleHQoKQoJCWZpbmQgPSBzZWxmLnBhcm1zWyJmaW5kIl0KCQlpZiBub3Qg
c2VsZi5wYXJtc1siY2FzZXNlbnMiXToKCQkJZmluZCA9IHN0cmluZy5sb3dlcihmaW5kKQoJ
CQl0ZXh0ID0gc3RyaW5nLmxvd2VyKHRleHQpCgkJaWYgdGV4dCA9PSBmaW5kOgoJCQlzZWxm
LmhpZGUoKQoJCQllZGl0b3IuaW5zZXJ0KHNlbGYucGFybXNbInJlcGxhY2UiXSkKCQoJZGVm
IHJlcGxhY2VhbGwoc2VsZik6CgkJZWRpdG9yID0gZmluZGVkaXRvcihzZWxmKQoJCWlmIG5v
dCBlZGl0b3I6CgkJCXJldHVybgoJCWlmIHNlbGYudmlzaWJsZToKCQkJc2VsZi5nZXRwYXJt
c2Zyb213aW5kb3coKQoJCVcuU2V0Q3Vyc29yKCJ3YXRjaCIpCgkJZmluZCA9IHNlbGYucGFy
bXNbImZpbmQiXQoJCWlmIG5vdCBmaW5kOgoJCQlyZXR1cm4KCQlmaW5kbGVuID0gbGVuKGZp
bmQpCgkJcmVwbGFjZSA9IHNlbGYucGFybXNbInJlcGxhY2UiXQoJCXJlcGxhY2VsZW4gPSBs
ZW4ocmVwbGFjZSkKCQlUZXh0ID0gZWRpdG9yLmdldCgpCgkJaWYgbm90IHNlbGYucGFybXNb
ImNhc2VzZW5zIl06CgkJCWZpbmQgPSBzdHJpbmcubG93ZXIoZmluZCkKCQkJdGV4dCA9IHN0
cmluZy5sb3dlcihUZXh0KQoJCWVsc2U6CgkJCXRleHQgPSBUZXh0CgkJbmV3dGV4dCA9ICIi
CgkJcG9zID0gMAoJCWNvdW50ZXIgPSAwCgkJd2hpbGUgMToKCQkJaWYgc2VsZi5wYXJtc1si
d2hvbGV3b3JkIl06CgkJCQl3aG9sZXdvcmRSRSA9IF9tYWtld2hvbGV3b3JkcGF0dGVybihm
aW5kKQoJCQkJbWF0Y2ggPSB3aG9sZXdvcmRSRS5zZWFyY2godGV4dCwgcG9zKQoJCQkJaWYg
bWF0Y2g6CgkJCQkJcG9zID0gbWF0Y2guc3RhcnQoMSkKCQkJCWVsc2U6CgkJCQkJcG9zID0g
LTEKCQkJZWxzZToKCQkJCXBvcyA9IHN0cmluZy5maW5kKHRleHQsIGZpbmQsIHBvcykKCQkJ
aWYgcG9zIDwgMDoKCQkJCWJyZWFrCgkJCWNvdW50ZXIgPSBjb3VudGVyICsgMQoJCQl0ZXh0
ID0gdGV4dFs6cG9zXSArIHJlcGxhY2UgKyB0ZXh0W3BvcyArIGZpbmRsZW46XQoJCQlUZXh0
ID0gVGV4dFs6cG9zXSArIHJlcGxhY2UgKyBUZXh0W3BvcyArIGZpbmRsZW46XQoJCQlwb3Mg
PSBwb3MgKyByZXBsYWNlbGVuCgkJVy5TZXRDdXJzb3IoImFycm93IikKCQlpZiBjb3VudGVy
OgoJCQlzZWxmLmhpZGUoKQoJCQlpbXBvcnQgRWFzeURpYWxvZ3MKCQkJZnJvbSBDYXJib24g
aW1wb3J0IFJlcwoJCQllZGl0b3IudGV4dGNoYW5nZWQoKQoJCQllZGl0b3Iuc2VsZWN0aW9u
Y2hhbmdlZCgpCgkJCWVkaXRvci50ZWQuV0VVc2VUZXh0KFJlcy5SZXNvdXJjZShUZXh0KSkK
CQkJZWRpdG9yLnRlZC5XRUNhbFRleHQoKQoJCQllZGl0b3IuU2V0UG9ydCgpCgkJCWVkaXRv
ci5HZXRXaW5kb3coKS5JbnZhbFdpbmRvd1JlY3QoZWRpdG9yLl9ib3VuZHMpCgkJCSNlZGl0
b3IudGVkLldFVXBkYXRlKHNlbGYudy53aWQuR2V0V2luZG93UG9ydCgpLnZpc1JnbikKCQkJ
RWFzeURpYWxvZ3MuTWVzc2FnZSgiUmVwbGFjZWQgJWQgb2NjdXJyZW5jZXMiICUgY291bnRl
cikKCQoJZGVmIGRvbnQoc2VsZik6CgkJc2VsZi5nZXRwYXJtc2Zyb213aW5kb3coKQoJCXNl
bGYuaGlkZSgpCgkKCWRlZiByZXBsYWNlZmluZChzZWxmKToKCQlzZWxmLnJlcGxhY2UoKQoJ
CXNlbGYuZmluZG5leHQoKQoJCglkZWYgc2V0ZmluZHN0cmluZyhzZWxmKToKCQllZGl0b3Ig
PSBmaW5kZWRpdG9yKHNlbGYpCgkJaWYgbm90IGVkaXRvcjoKCQkJcmV0dXJuCgkJZmluZCA9
IGVkaXRvci5nZXRzZWxlY3RlZHRleHQoKQoJCWlmIG5vdCBmaW5kOgoJCQlyZXR1cm4KCQlz
ZWxmLnBhcm1zWyJmaW5kIl0gPSBmaW5kCgkJaWYgc2VsZi53OgoJCQlzZWxmLncuZmluZC5l
ZGl0LnNldChzZWxmLnBhcm1zWyJmaW5kIl0pCgkJCXNlbGYudy5maW5kLmVkaXQuc2VsZWN0
YWxsKCkKCQoJZGVmIGZpbmRuZXh0KHNlbGYpOgoJCWVkaXRvciA9IGZpbmRlZGl0b3Ioc2Vs
ZikKCQlpZiBub3QgZWRpdG9yOgoJCQlyZXR1cm4KCQlmaW5kID0gc2VsZi5wYXJtc1siZmlu
ZCJdCgkJaWYgbm90IGZpbmQ6CgkJCXJldHVybgoJCXRleHQgPSBlZGl0b3IuZ2V0KCkKCQlp
ZiBub3Qgc2VsZi5wYXJtc1siY2FzZXNlbnMiXToKCQkJZmluZCA9IHN0cmluZy5sb3dlcihm
aW5kKQoJCQl0ZXh0ID0gc3RyaW5nLmxvd2VyKHRleHQpCgkJc2Vsc3RhcnQsIHNlbGVuZCA9
IGVkaXRvci5nZXRzZWxlY3Rpb24oKQoJCXNlbHN0YXJ0LCBzZWxlbmQgPSBtaW4oc2Vsc3Rh
cnQsIHNlbGVuZCksIG1heChzZWxzdGFydCwgc2VsZW5kKQoJCWlmIHNlbGYucGFybXNbIndo
b2xld29yZCJdOgoJCQl3aG9sZXdvcmRSRSA9IF9tYWtld2hvbGV3b3JkcGF0dGVybihmaW5k
KQoJCQltYXRjaCA9IHdob2xld29yZFJFLnNlYXJjaCh0ZXh0LCBzZWxlbmQpCgkJCWlmIG1h
dGNoOgoJCQkJcG9zID0gbWF0Y2guc3RhcnQoMSkKCQkJZWxzZToKCQkJCXBvcyA9IC0xCgkJ
ZWxzZToKCQkJcG9zID0gc3RyaW5nLmZpbmQodGV4dCwgZmluZCwgc2VsZW5kKQoJCWlmIHBv
cyA+PSAwOgoJCQllZGl0b3Iuc2V0c2VsZWN0aW9uKHBvcywgcG9zICsgbGVuKGZpbmQpKQoJ
CQlyZXR1cm4gMQoJCWVsaWYgc2VsZi5wYXJtc1sid3JhcCJdOgoJCQlpZiBzZWxmLnBhcm1z
WyJ3aG9sZXdvcmQiXToKCQkJCW1hdGNoID0gd2hvbGV3b3JkUkUuc2VhcmNoKHRleHQsIDAp
CgkJCQlpZiBtYXRjaDoKCQkJCQlwb3MgPSBtYXRjaC5zdGFydCgxKQoJCQkJZWxzZToKCQkJ
CQlwb3MgPSAtMQoJCQllbHNlOgoJCQkJcG9zID0gc3RyaW5nLmZpbmQodGV4dCwgZmluZCkK
CQkJaWYgc2Vsc3RhcnQgPiBwb3MgPj0gMDoKCQkJCWVkaXRvci5zZXRzZWxlY3Rpb24ocG9z
LCBwb3MgKyBsZW4oZmluZCkpCgkJCQlyZXR1cm4gMQoJCglkZWYgc2V0cGFybXMoc2VsZik6
CgkJZm9yIGtleSwgdmFsdWUgaW4gc2VsZi5wYXJtcy5pdGVtcygpOgoJCQl0cnk6CgkJCQlz
ZWxmLndba2V5XS5zZXQodmFsdWUpCgkJCWV4Y2VwdCBLZXlFcnJvcjoKCQkJCXNlbGYudy5i
b3hlc1trZXldLnNldCh2YWx1ZSkKCQoJZGVmIGdldHBhcm1zZnJvbXdpbmRvdyhzZWxmKToK
CQlpZiBub3Qgc2VsZi53OgoJCQlyZXR1cm4KCQlmb3Iga2V5LCB2YWx1ZSBpbiBzZWxmLnBh
cm1zLml0ZW1zKCk6CgkJCXRyeToKCQkJCXZhbHVlID0gc2VsZi53W2tleV0uZ2V0KCkKCQkJ
ZXhjZXB0IEtleUVycm9yOgoJCQkJdmFsdWUgPSBzZWxmLncuYm94ZXNba2V5XS5nZXQoKQoJ
CQlzZWxmLnBhcm1zW2tleV0gPSB2YWx1ZQoJCglkZWYgY2FuY2VsKHNlbGYpOgoJCXNlbGYu
aGlkZSgpCgkJc2VsZi5zZXRwYXJtcygpCgkKCWRlZiBoaWRlKHNlbGYpOgoJCWlmIHNlbGYu
dzoKCQkJc2VsZi53LndpZC5IaWRlV2luZG93KCkKCQkJc2VsZi52aXNpYmxlID0gMAoJCglk
ZWYgd3JpdGVwcmVmcyhzZWxmKToKCQlpbXBvcnQgTWFjUHJlZnMKCQlzZWxmLmdldHBhcm1z
ZnJvbXdpbmRvdygpCgkJcHJlZnMgPSBNYWNQcmVmcy5HZXRQcmVmcyhXLmdldGFwcGxpY2F0
aW9uKCkucHJlZmZpbGVwYXRoKQoJCXByZWZzLnNlYXJjaGVuZ2luZS5jYXNlc2VucyA9IHNl
bGYucGFybXNbImNhc2VzZW5zIl0KCQlwcmVmcy5zZWFyY2hlbmdpbmUud3JhcCA9IHNlbGYu
cGFybXNbIndyYXAiXQoJCXByZWZzLnNlYXJjaGVuZ2luZS53aG9sZXdvcmQgPSBzZWxmLnBh
cm1zWyJ3aG9sZXdvcmQiXQoJCXByZWZzLnNhdmUoKQoJCgpjbGFzcyBUaXRsZWRFZGl0VGV4
dChXLkdyb3VwKToKCQoJZGVmIF9faW5pdF9fKHNlbGYsIHBvc3NpemUsIHRpdGxlLCB0ZXh0
ID0gIiIpOgoJCVcuR3JvdXAuX19pbml0X18oc2VsZiwgcG9zc2l6ZSkKCQlzZWxmLnRpdGxl
ID0gVy5UZXh0Qm94KCgwLCAwLCAwLCAxNiksIHRpdGxlKQoJCXNlbGYuZWRpdCA9IFcuRWRp
dFRleHQoKDAsIDE2LCAwLCAwKSwgdGV4dCkKCQoJZGVmIHNldChzZWxmLCB2YWx1ZSk6CgkJ
c2VsZi5lZGl0LnNldCh2YWx1ZSkKCQoJZGVmIGdldChzZWxmKToKCQlyZXR1cm4gc2VsZi5l
ZGl0LmdldCgpCgoKY2xhc3MgQ2xhc3NGaW5kZXIoVy5Qb3B1cFdpZGdldCk6CgkKCWRlZiBj
bGljayhzZWxmLCBwb2ludCwgbW9kaWZpZXJzKToKCQlXLlNldEN1cnNvcigid2F0Y2giKQoJ
CXNlbGYuc2V0KHNlbGYuX3BhcmVudHdpbmRvdy5nZXRjbGFzc2xpc3QoKSkKCQlXLlBvcHVw
V2lkZ2V0LmNsaWNrKHNlbGYsIHBvaW50LCBtb2RpZmllcnMpCgoKZGVmIGdldG1pbmluZGVu
dChsaW5lcyk6CglpbmRlbnQgPSAtMQoJZm9yIGxpbmUgaW4gbGluZXM6CgkJc3RyaXBwZWQg
PSBzdHJpbmcuc3RyaXAobGluZSkKCQlpZiBub3Qgc3RyaXBwZWQgb3Igc3RyaXBwZWRbMF0g
PT0gJyMnOgoJCQljb250aW51ZQoJCWlmIGluZGVudCA8IDAgb3IgbGluZVs6aW5kZW50XSA8
PiBpbmRlbnQgKiAnXHQnOgoJCQlpbmRlbnQgPSAwCgkJCWZvciBjIGluIGxpbmU6CgkJCQlp
ZiBjIDw+ICdcdCc6CgkJCQkJYnJlYWsKCQkJCWluZGVudCA9IGluZGVudCArIDEKCXJldHVy
biBpbmRlbnQKCgpkZWYgZ2V0b3B0aW9ua2V5KCk6CglyZXR1cm4gbm90IG5vdCBvcmQoRXZ0
LkdldEtleXMoKVs3XSkgJiAweDA0CgoKZGVmIGV4ZWNzdHJpbmcocHl0ZXh0LCBnbG9iYWxz
LCBsb2NhbHMsIGZpbGVuYW1lPSI8c3RyaW5nPiIsIGRlYnVnZ2luZz0wLCAKCQkJbW9kbmFt
ZT0iX19tYWluX18iLCBwcm9maWxpbmc9MCk6CglpZiBkZWJ1Z2dpbmc6CgkJaW1wb3J0IFB5
RGVidWdnZXIsIGJkYgoJCUJkYlF1aXQgPSBiZGIuQmRiUXVpdAoJZWxzZToKCQlCZGJRdWl0
ID0gJ0JkYlF1aXREdW1teUV4Y2VwdGlvbicKCXB5dGV4dCA9IHN0cmluZy5zcGxpdChweXRl
eHQsICdccicpCglweXRleHQgPSBzdHJpbmcuam9pbihweXRleHQsICdcbicpICsgJ1xuJwoJ
Vy5TZXRDdXJzb3IoIndhdGNoIikKCWdsb2JhbHNbJ19fbmFtZV9fJ10gPSBtb2RuYW1lCgln
bG9iYWxzWydfX2ZpbGVfXyddID0gZmlsZW5hbWUKCXN5cy5hcmd2ID0gW2ZpbGVuYW1lXQoJ
dHJ5OgoJCWNvZGUgPSBjb21waWxlKHB5dGV4dCwgZmlsZW5hbWUsICJleGVjIikKCWV4Y2Vw
dDoKCQkjIFhYWFggQkFBQUFEREQuLi4uIFdlIGxldCB0cmFjZWJhY2t3aW5kb3cgZGVjaWRl
IHRvIHRyZWF0IFN5bnRheEVycm9yIAoJCSMgc3BlY2lhbC4gVGhhdCdzIHdyb25nIGJlY2F1
c2UgVEhJUyBjYXNlIGlzIHNwZWNpYWwgKGNvdWxkIGJlIGxpdGVyYWwgCgkJIyBvdmVyZmxv
dyEpIGFuZCBTeW50YXhFcnJvciBjb3VsZCBtZWFuIHdlIG5lZWQgYSB0cmFjZWJhY2sgKHN5
bnRheCBlcnJvciAKCQkjIGluIGltcG9ydGVkIG1vZHVsZSEhIQoJCXRyYWNlYmFja3dpbmRv
dy50cmFjZWJhY2soMSwgZmlsZW5hbWUpCgkJcmV0dXJuCgl0cnk6CgkJaWYgZGVidWdnaW5n
OgoJCQlpZiBoYXZlVGhyZWFkaW5nOgoJCQkJbG9jayA9IFd0aHJlYWRpbmcuTG9jaygpCgkJ
CQlsb2NrLmFjcXVpcmUoKQoJCQkJUHlEZWJ1Z2dlci5zdGFydGZyb21oZXJlKCkKCQkJCWxv
Y2sucmVsZWFzZSgpCgkJCWVsc2U6CgkJCQlQeURlYnVnZ2VyLnN0YXJ0ZnJvbWhlcmUoKQoJ
CWVsaWYgbm90IGhhdmVUaHJlYWRpbmc6CgkJCWlmIGhhc2F0dHIoTWFjT1MsICdFbmFibGVB
cHBzd2l0Y2gnKToKCQkJCU1hY09TLkVuYWJsZUFwcHN3aXRjaCgwKQoJCXRyeToKCQkJaWYg
cHJvZmlsaW5nOgoJCQkJaW1wb3J0IHByb2ZpbGUsIFByb2ZpbGVCcm93c2VyCgkJCQlwID0g
cHJvZmlsZS5Qcm9maWxlKCkKCQkJCXAuc2V0X2NtZChmaWxlbmFtZSkKCQkJCXRyeToKCQkJ
CQlwLnJ1bmN0eChjb2RlLCBnbG9iYWxzLCBsb2NhbHMpCgkJCQlmaW5hbGx5OgoJCQkJCWlt
cG9ydCBwc3RhdHMKCQkJCQkKCQkJCQlzdGF0cyA9IHBzdGF0cy5TdGF0cyhwKQoJCQkJCVBy
b2ZpbGVCcm93c2VyLlByb2ZpbGVCcm93c2VyKHN0YXRzKQoJCQllbHNlOgoJCQkJZXhlYyBj
b2RlIGluIGdsb2JhbHMsIGxvY2FscwoJCWZpbmFsbHk6CgkJCWlmIG5vdCBoYXZlVGhyZWFk
aW5nOgoJCQkJaWYgaGFzYXR0cihNYWNPUywgJ0VuYWJsZUFwcHN3aXRjaCcpOgoJCQkJCU1h
Y09TLkVuYWJsZUFwcHN3aXRjaCgtMSkKCWV4Y2VwdCBXLkFsZXJ0RXJyb3IsIGRldGFpbDoK
CQlyYWlzZSBXLkFsZXJ0RXJyb3IsIGRldGFpbAoJZXhjZXB0IChLZXlib2FyZEludGVycnVw
dCwgQmRiUXVpdCk6CgkJcGFzcwoJZXhjZXB0IFN5c3RlbUV4aXQsIGFyZzoKCQlpZiBhcmcu
Y29kZToKCQkJc3lzLnN0ZGVyci53cml0ZSgiU2NyaXB0IGV4aXRlZCB3aXRoIHN0YXR1cyBj
b2RlOiAlc1xuIiAlIHJlcHIoYXJnLmNvZGUpKQoJZXhjZXB0OgoJCWlmIGhhdmVUaHJlYWRp
bmc6CgkJCWltcG9ydCBjb250aW51YXRpb24KCQkJbG9jayA9IFd0aHJlYWRpbmcuTG9jaygp
CgkJCWxvY2suYWNxdWlyZSgpCgkJaWYgZGVidWdnaW5nOgoJCQlzeXMuc2V0dHJhY2UoTm9u
ZSkKCQkJUHlEZWJ1Z2dlci5wb3N0bW9ydGVtKHN5cy5leGNfdHlwZSwgc3lzLmV4Y192YWx1
ZSwgc3lzLmV4Y190cmFjZWJhY2spCgkJCXJldHVybgoJCWVsc2U6CgkJCXRyYWNlYmFja3dp
bmRvdy50cmFjZWJhY2soMSwgZmlsZW5hbWUpCgkJaWYgaGF2ZVRocmVhZGluZzoKCQkJbG9j
ay5yZWxlYXNlKCkKCWlmIGRlYnVnZ2luZzoKCQlzeXMuc2V0dHJhY2UoTm9uZSkKCQlQeURl
YnVnZ2VyLnN0b3AoKQoKCl9pZGVudGlmaWVSRSA9IHJlLmNvbXBpbGUociJbQS1aYS16X11b
QS1aYS16XzAtOV0qIikKCmRlZiBpZGVudGlmaWVSRV9tYXRjaChzdHIpOgoJbWF0Y2ggPSBf
aWRlbnRpZmllUkUubWF0Y2goc3RyKQoJaWYgbm90IG1hdGNoOgoJCXJldHVybiAtMQoJcmV0
dXJuIG1hdGNoLmVuZCgpCgpkZWYgX2ZpbGVuYW1lX2FzX21vZG5hbWUoZm5hbWUpOgoJaWYg
Zm5hbWVbLTM6XSA9PSAnLnB5JzoKCQltb2RuYW1lID0gZm5hbWVbOi0zXQoJCW1hdGNoID0g
X2lkZW50aWZpZVJFLm1hdGNoKG1vZG5hbWUpCgkJaWYgbWF0Y2ggYW5kIG1hdGNoLnN0YXJ0
KCkgPT0gMCBhbmQgbWF0Y2guZW5kKCkgPT0gbGVuKG1vZG5hbWUpOgoJCQlyZXR1cm4gc3Ry
aW5nLmpvaW4oc3RyaW5nLnNwbGl0KG1vZG5hbWUsICcuJyksICdfJykKCmRlZiBmaW5kZWRp
dG9yKHRvcHdpbmRvdywgZnJvbXRvcCA9IDApOgoJd2lkID0gTXlGcm9udFdpbmRvdygpCglp
ZiBub3QgZnJvbXRvcDoKCQlpZiB0b3B3aW5kb3cudyBhbmQgd2lkID09IHRvcHdpbmRvdy53
LndpZDoKCQkJd2lkID0gdG9wd2luZG93Lncud2lkLkdldE5leHRXaW5kb3coKQoJaWYgbm90
IHdpZDoKCQlyZXR1cm4KCWFwcCA9IFcuZ2V0YXBwbGljYXRpb24oKQoJaWYgYXBwLl93aW5k
b3dzLmhhc19rZXkod2lkKTogIyBLZXlFcnJvciBvdGhlcndpc2UgY2FuIGhhcHBlbiBpbiBS
b2JvRm9nIDotKAoJCXdpbmRvdyA9IFcuZ2V0YXBwbGljYXRpb24oKS5fd2luZG93c1t3aWRd
CgllbHNlOgoJCXJldHVybgoJaWYgbm90IGlzaW5zdGFuY2Uod2luZG93LCBFZGl0b3IpOgoJ
CXJldHVybgoJcmV0dXJuIHdpbmRvdy5lZGl0Z3JvdXAuZWRpdG9yCgoKY2xhc3MgX0VkaXRv
ckRlZmF1bHRTZXR0aW5nczoKCQoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCXNlbGYudGVtcGxh
dGUgPSAiJXMsICVkIHBvaW50IgoJCXNlbGYuZm9udHNldHRpbmdzLCBzZWxmLnRhYnNldHRp
bmdzLCBzZWxmLndpbmRvd3NpemUgPSBnZXRlZGl0b3JwcmVmcygpCgkJc2VsZi53ID0gVy5E
aWFsb2coKDMyOCwgMTIwKSwgIkVkaXRvciBkZWZhdWx0IHNldHRpbmdzIikKCQlzZWxmLncu
c2V0Zm9udGJ1dHRvbiA9IFcuQnV0dG9uKCg4LCA4LCA4MCwgMTYpLCAiU2V0IGZvbnRceGM5
Iiwgc2VsZi5kb2ZvbnQpCgkJc2VsZi53LmZvbnR0ZXh0ID0gVy5UZXh0Qm94KCg5OCwgMTAs
IC04LCAxNCksIHNlbGYudGVtcGxhdGUgJSAoc2VsZi5mb250c2V0dGluZ3NbMF0sIHNlbGYu
Zm9udHNldHRpbmdzWzJdKSkKCQkKCQlzZWxmLncucGlja3NpemVidXR0b24gPSBXLkJ1dHRv
bigoOCwgNTAsIDgwLCAxNiksICJGcm9udCB3aW5kb3ciLCBzZWxmLnBpY2tzaXplKQoJCXNl
bGYudy54c2l6ZWxhYmVsID0gVy5UZXh0Qm94KCg5OCwgMzIsIDQwLCAxNCksICJXaWR0aDoi
KQoJCXNlbGYudy55c2l6ZWxhYmVsID0gVy5UZXh0Qm94KCgxNDgsIDMyLCA0MCwgMTQpLCAi
SGVpZ2h0OiIpCgkJc2VsZi53LnhzaXplID0gVy5FZGl0VGV4dCgoOTgsIDQ4LCA0MCwgMjAp
LCBgc2VsZi53aW5kb3dzaXplWzBdYCkKCQlzZWxmLncueXNpemUgPSBXLkVkaXRUZXh0KCgx
NDgsIDQ4LCA0MCwgMjApLCBgc2VsZi53aW5kb3dzaXplWzFdYCkKCQkKCQlzZWxmLncuY2Fu
Y2VsYnV0dG9uID0gVy5CdXR0b24oKC0xODAsIC0yNiwgODAsIDE2KSwgIkNhbmNlbCIsIHNl
bGYuY2FuY2VsKQoJCXNlbGYudy5va2J1dHRvbiA9IFcuQnV0dG9uKCgtOTAsIC0yNiwgODAs
IDE2KSwgIkRvbmUiLCBzZWxmLm9rKQoJCXNlbGYudy5zZXRkZWZhdWx0YnV0dG9uKHNlbGYu
dy5va2J1dHRvbikKCQlzZWxmLncuYmluZCgnY21kLicsIHNlbGYudy5jYW5jZWxidXR0b24u
cHVzaCkKCQlzZWxmLncub3BlbigpCgkKCWRlZiBwaWNrc2l6ZShzZWxmKToKCQlhcHAgPSBX
LmdldGFwcGxpY2F0aW9uKCkKCQllZGl0b3IgPSBmaW5kZWRpdG9yKHNlbGYpCgkJaWYgZWRp
dG9yIGlzIG5vdCBOb25lOgoJCQl3aWR0aCwgaGVpZ2h0ID0gZWRpdG9yLl9wYXJlbnR3aW5k
b3cuX2JvdW5kc1syOl0KCQkJc2VsZi53LnhzaXplLnNldChgd2lkdGhgKQoJCQlzZWxmLncu
eXNpemUuc2V0KGBoZWlnaHRgKQoJCWVsc2U6CgkJCXJhaXNlIFcuQWxlcnRFcnJvciwgIk5v
IGVkaXQgd2luZG93IGZvdW5kIgoJCglkZWYgZG9mb250KHNlbGYpOgoJCWltcG9ydCBGb250
U2V0dGluZ3MKCQlzZXR0aW5ncyA9IEZvbnRTZXR0aW5ncy5Gb250RGlhbG9nKHNlbGYuZm9u
dHNldHRpbmdzLCBzZWxmLnRhYnNldHRpbmdzKQoJCWlmIHNldHRpbmdzOgoJCQlzZWxmLmZv
bnRzZXR0aW5ncywgc2VsZi50YWJzZXR0aW5ncyA9IHNldHRpbmdzCgkJCXN5cy5leGNfdHJh
Y2ViYWNrID0gTm9uZQoJCQlzZWxmLncuZm9udHRleHQuc2V0KHNlbGYudGVtcGxhdGUgJSAo
c2VsZi5mb250c2V0dGluZ3NbMF0sIHNlbGYuZm9udHNldHRpbmdzWzJdKSkKCQoJZGVmIGNs
b3NlKHNlbGYpOgoJCXNlbGYudy5jbG9zZSgpCgkJZGVsIHNlbGYudwoJCglkZWYgY2FuY2Vs
KHNlbGYpOgoJCXNlbGYuY2xvc2UoKQoJCglkZWYgb2soc2VsZik6CgkJdHJ5OgoJCQl3aWR0
aCA9IHN0cmluZy5hdG9pKHNlbGYudy54c2l6ZS5nZXQoKSkKCQlleGNlcHQ6CgkJCXNlbGYu
dy54c2l6ZS5zZWxlY3QoMSkKCQkJc2VsZi53LnhzaXplLnNlbGVjdGFsbCgpCgkJCXJhaXNl
IFcuQWxlcnRFcnJvciwgIkJhZCBudW1iZXIgZm9yIHdpbmRvdyB3aWR0aCIKCQl0cnk6CgkJ
CWhlaWdodCA9IHN0cmluZy5hdG9pKHNlbGYudy55c2l6ZS5nZXQoKSkKCQlleGNlcHQ6CgkJ
CXNlbGYudy55c2l6ZS5zZWxlY3QoMSkKCQkJc2VsZi53LnlzaXplLnNlbGVjdGFsbCgpCgkJ
CXJhaXNlIFcuQWxlcnRFcnJvciwgIkJhZCBudW1iZXIgZm9yIHdpbmRvdyBoZWlnaHQiCgkJ
c2VsZi53aW5kb3dzaXplID0gd2lkdGgsIGhlaWdodAoJCXNldGVkaXRvcnByZWZzKHNlbGYu
Zm9udHNldHRpbmdzLCBzZWxmLnRhYnNldHRpbmdzLCBzZWxmLndpbmRvd3NpemUpCgkJc2Vs
Zi5jbG9zZSgpCgpkZWYgZ2V0ZWRpdG9ycHJlZnMoKToKCWltcG9ydCBNYWNQcmVmcwoJcHJl
ZnMgPSBNYWNQcmVmcy5HZXRQcmVmcyhXLmdldGFwcGxpY2F0aW9uKCkucHJlZmZpbGVwYXRo
KQoJdHJ5OgoJCWZvbnRzZXR0aW5ncyA9IHByZWZzLnB5ZWRpdC5mb250c2V0dGluZ3MKCQl0
YWJzZXR0aW5ncyA9IHByZWZzLnB5ZWRpdC50YWJzZXR0aW5ncwoJCXdpbmRvd3NpemUgPSBw
cmVmcy5weWVkaXQud2luZG93c2l6ZQoJZXhjZXB0OgoJCWZvbnRzZXR0aW5ncyA9IHByZWZz
LnB5ZWRpdC5mb250c2V0dGluZ3MgPSAoIkdlbmV2YSIsIDAsIDEwLCAoMCwgMCwgMCkpCgkJ
dGFic2V0dGluZ3MgPSBwcmVmcy5weWVkaXQudGFic2V0dGluZ3MgPSAoOCwgMSkKCQl3aW5k
b3dzaXplID0gcHJlZnMucHllZGl0LndpbmRvd3NpemUgPSAoNTAwLCAyNTApCgkJc3lzLmV4
Y190cmFjZWJhY2sgPSBOb25lCglyZXR1cm4gZm9udHNldHRpbmdzLCB0YWJzZXR0aW5ncywg
d2luZG93c2l6ZQoKZGVmIHNldGVkaXRvcnByZWZzKGZvbnRzZXR0aW5ncywgdGFic2V0dGlu
Z3MsIHdpbmRvd3NpemUpOgoJaW1wb3J0IE1hY1ByZWZzCglwcmVmcyA9IE1hY1ByZWZzLkdl
dFByZWZzKFcuZ2V0YXBwbGljYXRpb24oKS5wcmVmZmlsZXBhdGgpCglwcmVmcy5weWVkaXQu
Zm9udHNldHRpbmdzID0gZm9udHNldHRpbmdzCglwcmVmcy5weWVkaXQudGFic2V0dGluZ3Mg
PSB0YWJzZXR0aW5ncwoJcHJlZnMucHllZGl0LndpbmRvd3NpemUgPSB3aW5kb3dzaXplCglw
cmVmcy5zYXZlKCkKCl9kZWZhdWx0U2V0dGluZ3NFZGl0b3IgPSBOb25lCgpkZWYgRWRpdG9y
RGVmYXVsdFNldHRpbmdzKCk6CglnbG9iYWwgX2RlZmF1bHRTZXR0aW5nc0VkaXRvcgoJaWYg
X2RlZmF1bHRTZXR0aW5nc0VkaXRvciBpcyBOb25lIG9yIG5vdCBoYXNhdHRyKF9kZWZhdWx0
U2V0dGluZ3NFZGl0b3IsICJ3Iik6CgkJX2RlZmF1bHRTZXR0aW5nc0VkaXRvciA9IF9FZGl0
b3JEZWZhdWx0U2V0dGluZ3MoKQoJZWxzZToKCQlfZGVmYXVsdFNldHRpbmdzRWRpdG9yLncu
c2VsZWN0KCkKCmRlZiByZXNvbHZlYWxpYXNlcyhwYXRoKToKCXRyeToKCQlyZXR1cm4gbWFj
ZnMuUmVzb2x2ZUFsaWFzRmlsZShwYXRoKVswXS5hc19wYXRobmFtZSgpCglleGNlcHQgKG1h
Y2ZzLmVycm9yLCBWYWx1ZUVycm9yKSwgKGVycm9yLCBzdHIpOgoJCWlmIGVycm9yIDw+IC0x
MjA6CgkJCXJhaXNlCgkJZGlyLCBmaWxlID0gb3MucGF0aC5zcGxpdChwYXRoKQoJCXJldHVy
biBvcy5wYXRoLmpvaW4ocmVzb2x2ZWFsaWFzZXMoZGlyKSwgZmlsZSkKCnNlYXJjaGVuZ2lu
ZSA9IFNlYXJjaEVuZ2luZSgpCnRyYWNlYmFja3dpbmRvdyA9IFd0cmFjZWJhY2suVHJhY2VC
YWNrKCkK


--B_3111327552_3212811--


--B_3111327557_3186067--