[Zope-dev] Added rename to ZOPE FTP server

Tom Vijlbrief tom.vijlbrief@ision.nl
Sat, 20 Jan 2001 17:24:04 +0100


This is a multi-part message in MIME format.
--------------CF3F10DD56A7538D09BE4E14
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi,

I've added the rename capability to the Zope FTP-server,
so I could use the KDE FTP client (this is a known Zope bug).

I attached the 3 modified files (from the 2.2.5 src distro).

There is however another problem in the ZOPE ftpd which
is probably not related to my patches, but for which I have
not found the cause.

The SIZE command (used by the KDE ftp-client as a 
kind of file-exists probe)
reports the size of identical named objects
higher in the tree, to reproduce:

copy with the KDE FTP client a directory tree which has
fileabc in the top directory and a file "fileabc" in a subdirectory
to the Zope ftp server.

The SIZE command returns a size (for a
non existing object!) but the LIST command works o.k.
(reports an error: could not list directory)


127.0.0.1:3771 <== mkd testdir
127.0.0.1:3771 ==> 257 MKD command successful.
127.0.0.1:3771 <== mkd testdir/adir
127.0.0.1:3771 ==> 257 MKD command successful.
127.0.0.1:3771 <== type I
127.0.0.1:3771 ==> 200 Type set to Binary.
127.0.0.1:3771 <== SIZE testdir/fileabc
127.0.0.1:3771 ==> 550 Error getting file size.
127.0.0.1:3771 <== type I
127.0.0.1:3771 ==> 200 Type set to Binary.
127.0.0.1:3771 <== SIZE testdir/fileabc.part
127.0.0.1:3771 ==> 550 Error getting file size.
127.0.0.1:3771 <== type I
127.0.0.1:3771 ==> 200 Type set to Binary.
127.0.0.1:3771 <== PASV
127.0.0.1:3771 ==> 227 Entering Passive Mode (127,0,0,1,14,190)
127.0.0.1:3771 <== stor testdir/fileabc.part
127.0.0.1:3771 ==> 150 Opening Binary connection for
testdir/fileabc.part
127.0.0.1:3771 ==> 226 Transfer complete.
127.0.0.1:3771 <== RNFR testdir/fileabc.part
127.0.0.1:3771 ==> 350 RNFR command successful.
127.0.0.1:3771 <== RNTO testdir/fileabc
127.0.0.1:3771 ==> 250 RNTO command successful.
127.0.0.1:3771 <== SITE CHMOD 644 testdir/fileabc
127.0.0.1:3771 ==> 500 'SITE': command not understood.
127.0.0.1:3771 <== type I
127.0.0.1:3771 ==> 200 Type set to Binary.
127.0.0.1:3771 <== SIZE testdir/adir/fileabc
127.0.0.1:3771 ==> 213 2
127.0.0.1:3771 <== cwd testdir/adir/fileabc
127.0.0.1:3771 ==> 550 No such directory.
127.0.0.1:3771 <== type A
127.0.0.1:3771 ==> 200 Type set to ASCII.
127.0.0.1:3771 <== PASV
127.0.0.1:3771 ==> 227 Entering Passive Mode (127,0,0,1,14,192)
127.0.0.1:3771 <== list testdir/adir/fileabc
127.0.0.1:3771 ==> 550 Could not list directory.                     

-- 
Tom Vijlbrief       tom.vijlbrief@ision.nl
--------------CF3F10DD56A7538D09BE4E14
Content-Type: application/octet-stream;
 name="FTPRequest.py"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="FTPRequest.py"

IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgCiMgWm9wZSBQdWJsaWMgTGljZW5zZSAoWlBM
KSBWZXJzaW9uIDEuMAojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0K
IyAKIyBDb3B5cmlnaHQgKGMpIERpZ2l0YWwgQ3JlYXRpb25zLiAgQWxsIHJpZ2h0cyByZXNl
cnZlZC4KIyAKIyBUaGlzIGxpY2Vuc2UgaGFzIGJlZW4gY2VydGlmaWVkIGFzIE9wZW4gU291
cmNlKHRtKS4KIyAKIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmlu
YXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0
ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCiMgbWV0Ogoj
IAojIDEuIFJlZGlzdHJpYnV0aW9ucyBpbiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUg
YWJvdmUgY29weXJpZ2h0CiMgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucywg
YW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KIyAKIyAyLiBSZWRpc3RyaWJ1dGlvbnMg
aW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAojICAg
IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMsIGFuZCB0aGUgZm9sbG93aW5nIGRp
c2NsYWltZXIgaW4KIyAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJp
YWxzIHByb3ZpZGVkIHdpdGggdGhlCiMgICAgZGlzdHJpYnV0aW9uLgojIAojIDMuIERpZ2l0
YWwgQ3JlYXRpb25zIHJlcXVlc3RzIHRoYXQgYXR0cmlidXRpb24gYmUgZ2l2ZW4gdG8gWm9w
ZQojICAgIGluIGFueSBtYW5uZXIgcG9zc2libGUuIFpvcGUgaW5jbHVkZXMgYSAiUG93ZXJl
ZCBieSBab3BlIgojICAgIGJ1dHRvbiB0aGF0IGlzIGluc3RhbGxlZCBieSBkZWZhdWx0LiBX
aGlsZSBpdCBpcyBub3QgYSBsaWNlbnNlCiMgICAgdmlvbGF0aW9uIHRvIHJlbW92ZSB0aGlz
IGJ1dHRvbiwgaXQgaXMgcmVxdWVzdGVkIHRoYXQgdGhlCiMgICAgYXR0cmlidXRpb24gcmVt
YWluLiBBIHNpZ25pZmljYW50IGludmVzdG1lbnQgaGFzIGJlZW4gcHV0CiMgICAgaW50byBa
b3BlLCBhbmQgdGhpcyBlZmZvcnQgd2lsbCBjb250aW51ZSBpZiB0aGUgWm9wZSBjb21tdW5p
dHkKIyAgICBjb250aW51ZXMgdG8gZ3Jvdy4gVGhpcyBpcyBvbmUgd2F5IHRvIGFzc3VyZSB0
aGF0IGdyb3d0aC4KIyAKIyA0LiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIGFuZCBkb2N1
bWVudGF0aW9uIG1lbnRpb25pbmcKIyAgICBmZWF0dXJlcyBkZXJpdmVkIGZyb20gb3IgdXNl
IG9mIHRoaXMgc29mdHdhcmUgbXVzdCBkaXNwbGF5CiMgICAgdGhlIGZvbGxvd2luZyBhY2tu
b3dsZWRnZW1lbnQ6CiMgCiMgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJl
IGRldmVsb3BlZCBieSBEaWdpdGFsIENyZWF0aW9ucwojICAgICAgZm9yIHVzZSBpbiB0aGUg
WiBPYmplY3QgUHVibGlzaGluZyBFbnZpcm9ubWVudAojICAgICAgKGh0dHA6Ly93d3cuem9w
ZS5vcmcvKS4iCiMgCiMgICAgSW4gdGhlIGV2ZW50IHRoYXQgdGhlIHByb2R1Y3QgYmVpbmcg
YWR2ZXJ0aXNlZCBpbmNsdWRlcyBhbgojICAgIGludGFjdCBab3BlIGRpc3RyaWJ1dGlvbiAo
d2l0aCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5jbHVkZWQpCiMgICAgdGhlbiB0aGlzIGNs
YXVzZSBpcyB3YWl2ZWQuCiMgCiMgNS4gTmFtZXMgYXNzb2NpYXRlZCB3aXRoIFpvcGUgb3Ig
RGlnaXRhbCBDcmVhdGlvbnMgbXVzdCBub3QgYmUgdXNlZCB0bwojICAgIGVuZG9yc2Ugb3Ig
cHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0CiMg
ICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGZyb20gRGlnaXRhbCBDcmVhdGlvbnMuCiMg
CiMgNi4gTW9kaWZpZWQgcmVkaXN0cmlidXRpb25zIG9mIGFueSBmb3JtIHdoYXRzb2V2ZXIg
bXVzdCByZXRhaW4KIyAgICB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgojIAojICAg
ICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgRGlnaXRh
bCBDcmVhdGlvbnMKIyAgICAgIGZvciB1c2UgaW4gdGhlIFogT2JqZWN0IFB1Ymxpc2hpbmcg
RW52aXJvbm1lbnQKIyAgICAgIChodHRwOi8vd3d3LnpvcGUub3JnLykuIgojIAojICAgIElu
dGFjdCAocmUtKWRpc3RyaWJ1dGlvbnMgb2YgYW55IG9mZmljaWFsIFpvcGUgcmVsZWFzZSBk
byBub3QKIyAgICByZXF1aXJlIGFuIGV4dGVybmFsIGFja25vd2xlZGdlbWVudC4KIyAKIyA3
LiBNb2RpZmljYXRpb25zIGFyZSBlbmNvdXJhZ2VkIGJ1dCBtdXN0IGJlIHBhY2thZ2VkIHNl
cGFyYXRlbHkgYXMKIyAgICBwYXRjaGVzIHRvIG9mZmljaWFsIFpvcGUgcmVsZWFzZXMuICBE
aXN0cmlidXRpb25zIHRoYXQgZG8gbm90CiMgICAgY2xlYXJseSBzZXBhcmF0ZSB0aGUgcGF0
Y2hlcyBmcm9tIHRoZSBvcmlnaW5hbCB3b3JrIG11c3QgYmUgY2xlYXJseQojICAgIGxhYmVs
ZWQgYXMgdW5vZmZpY2lhbCBkaXN0cmlidXRpb25zLiAgTW9kaWZpY2F0aW9ucyB3aGljaCBk
byBub3QKIyAgICBjYXJyeSB0aGUgbmFtZSBab3BlIG1heSBiZSBwYWNrYWdlZCBpbiBhbnkg
Zm9ybSwgYXMgbG9uZyBhcyB0aGV5CiMgICAgY29uZm9ybSB0byBhbGwgb2YgdGhlIGNsYXVz
ZXMgYWJvdmUuCiMgCiMgCiMgRGlzY2xhaW1lcgojIAojICAgVEhJUyBTT0ZUV0FSRSBJUyBQ
Uk9WSURFRCBCWSBESUdJVEFMIENSRUFUSU9OUyBgYEFTIElTJycgQU5EIEFOWQojICAgRVhQ
UkVTU0VEIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlU
RUQgVE8sIFRIRQojICAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBB
TkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCiMgICBQVVJQT1NFIEFSRSBESVNDTEFJTUVE
LiAgSU4gTk8gRVZFTlQgU0hBTEwgRElHSVRBTCBDUkVBVElPTlMgT1IgSVRTCiMgICBDT05U
UklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRB
TCwKIyAgIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJ
TkNMVURJTkcsIEJVVCBOT1QKIyAgIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNU
SVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKIyAgIFVTRSwgREFUQSwgT1IgUFJP
RklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKIyAg
IE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJ
Q1QgTElBQklMSVRZLAojICAgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RI
RVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCiMgICBPRiBUSEUgVVNFIE9GIFRISVMg
U09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKIyAgIFNV
Q0ggREFNQUdFLgojIAojIAojIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2YgY29udHJpYnV0
aW9ucyBtYWRlIGJ5IERpZ2l0YWwgQ3JlYXRpb25zIGFuZAojIG1hbnkgaW5kaXZpZHVhbHMg
b24gYmVoYWxmIG9mIERpZ2l0YWwgQ3JlYXRpb25zLiAgU3BlY2lmaWMKIyBhdHRyaWJ1dGlv
bnMgYXJlIGxpc3RlZCBpbiB0aGUgYWNjb21wYW55aW5nIGNyZWRpdHMgZmlsZS4KIyAKIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjCiIiIgpGVFAgUmVxdWVzdCBjbGFzcyBmb3IgRlRQIHNl
cnZlci4KClRoZSBGVFAgUmVxdWVzdCBkb2VzIHRoZSBkaXJ0eSB3b3JrIG9mIHR1cm5pbmcg
YW4gRlRQIHJlcXVlc3QgaW50byBzb21ldGhpbmcKdGhhdCBaUHVibGlzaGVyIGNhbiB1bmRl
cnN0YW5kLgoiIiIKCmZyb20gWlB1Ymxpc2hlci5IVFRQUmVxdWVzdCBpbXBvcnQgSFRUUFJl
cXVlc3QKCmZyb20gY1N0cmluZ0lPIGltcG9ydCBTdHJpbmdJTwppbXBvcnQgb3MKZnJvbSBy
ZWdzdWIgaW1wb3J0IGdzdWIKZnJvbSBiYXNlNjQgaW1wb3J0IGVuY29kZXN0cmluZwppbXBv
cnQgc3RyaW5nCgpjbGFzcyBGVFBSZXF1ZXN0KEhUVFBSZXF1ZXN0KToKCiAgICBkZWYgX19p
bml0X18oc2VsZiwgcGF0aCwgY29tbWFuZCwgY2hhbm5lbCwgcmVzcG9uc2UsIHN0ZGluPU5v
bmUsCiAgICAgICAgICAgICAgICAgZW52aXJvbj1Ob25lKToKICAgICAgICBpZiBzdGRpbiBp
cyBOb25lOiBzdGRpbj1TdHJpbmdJTygpCiAgICAgICAgaWYgZW52aXJvbiBpcyBOb25lOgog
ICAgICAgICAgICBlbnZpcm9uPXNlbGYuX2dldF9lbnYocGF0aCwgY29tbWFuZCwgY2hhbm5l
bCwgc3RkaW4pCiAgICAgICAgc2VsZi5fb3JpZ19lbnY9ZW52aXJvbgogICAgICAgIEhUVFBS
ZXF1ZXN0Ll9faW5pdF9fKHNlbGYsIHN0ZGluLCBlbnZpcm9uLCByZXNwb25zZSwgY2xlYW49
MSkKICAgICAgICAKICAgICAgICAjIHN1cHBvcnQgZm9yIGNvb2tpZXMgYW5kIGNvb2tpZSBh
dXRoZW50aWNhdGlvbgogICAgICAgIHNlbGYuY29va2llcz1jaGFubmVsLmNvb2tpZXMKICAg
ICAgICBpZiBub3Qgc2VsZi5jb29raWVzLmhhc19rZXkoJ19fYWMnKSBhbmQgY2hhbm5lbC51
c2VyaWQgIT0gJ2Fub255bW91cyc6CiAgICAgICAgICAgIHNlbGYub3RoZXJbJ19fYWNfbmFt
ZSddPWNoYW5uZWwudXNlcmlkCiAgICAgICAgICAgIHNlbGYub3RoZXJbJ19fYWNfcGFzc3dv
cmQnXT1jaGFubmVsLnBhc3N3b3JkCiAgICAgICAgZm9yIGssdiBpbiBzZWxmLmNvb2tpZXMu
aXRlbXMoKToKICAgICAgICAgICAgaWYgbm90IHNlbGYub3RoZXIuaGFzX2tleShrKToKICAg
ICAgICAgICAgICAgIHNlbGYub3RoZXJba109dgogICAgICAgIAogICAKICAgIGRlZiByZXRy
eShzZWxmKToKICAgICAgICBzZWxmLnJldHJ5X2NvdW50PXNlbGYucmV0cnlfY291bnQrMQog
ICAgICAgIHI9c2VsZi5fX2NsYXNzX18oc3RkaW49c2VsZi5zdGRpbiwKICAgICAgICAgICAg
ICAgICAgICAgICAgIGVudmlyb249c2VsZi5fb3JpZ19lbnYsCiAgICAgICAgICAgICAgICAg
ICAgICAgICByZXNwb25zZT1zZWxmLnJlc3BvbnNlLnJldHJ5KCksCiAgICAgICAgICAgICAg
ICAgICAgICAgICBjaGFubmVsPXNlbGYsICMgRm9yIG15IGNvb2tpZXMKICAgICAgICAgICAg
ICAgICAgICAgICAgICkKICAgICAgICByZXR1cm4gcgogICAgCiAgICBkZWYgX2dldF9lbnYo
c2VsZiwgcGF0aCwgY29tbWFuZCwgY2hhbm5lbCwgc3RkaW4pOgogICAgICAgICJSZXR1cm5z
IGEgQ0dJIHN0eWxlIGVudmlyb25tZW50IgogICAgICAgIGVudj17fQogICAgICAgIGVudlsn
U0NSSVBUX05BTUUnXT0nLyVzJyAlIGNoYW5uZWwubW9kdWxlCiAgICAgICAgZW52WydSRVFV
RVNUX01FVEhPRCddPSdHRVQnICMgWFhYIHdoYXQgc2hvdWxkIHRoaXMgYmU/CiAgICAgICAg
ZW52WydTRVJWRVJfU09GVFdBUkUnXT1jaGFubmVsLnNlcnZlci5TRVJWRVJfSURFTlQKICAg
ICAgICBpZiBjaGFubmVsLnVzZXJpZCAhPSAnYW5vbnltb3VzJzoKICAgICAgICAgICAgZW52
WydIVFRQX0FVVEhPUklaQVRJT04nXT0nQmFzaWMgJXMnICUgZ3N1YignXDAxMicsJycsCiAg
ICAgICAgICAgICAgICAgICAgZW5jb2Rlc3RyaW5nKCclczolcycgJSAoY2hhbm5lbC51c2Vy
aWQsIGNoYW5uZWwucGFzc3dvcmQpKSkKICAgICAgICBlbnZbJ1NFUlZFUl9OQU1FJ109Y2hh
bm5lbC5zZXJ2ZXIuaG9zdG5hbWUKICAgICAgICBlbnZbJ1NFUlZFUl9QT1JUJ109c3RyKGNo
YW5uZWwuc2VydmVyLnBvcnQpCiAgICAgICAgZW52WydSRU1PVEVfQUREUiddPWNoYW5uZWwu
Y2xpZW50X2FkZHJbMF0KICAgICAgICBlbnZbJ0dBVEVXQVlfSU5URVJGQUNFJ109J0NHSS8x
LjEnICMgdGhhdCdzIHN0cmV0Y2hpbmcgaXQgOy0pCiAgICAgICAKICAgICAgICAjIEZUUCBj
b21tYW5kcwogICAgICAgICMKICAgICAgICBpZiB0eXBlKGNvbW1hbmQpPT10eXBlKCgpKToK
ICAgICAgICAgICAgYXJncz1jb21tYW5kWzE6XQogICAgICAgICAgICBjb21tYW5kPWNvbW1h
bmRbMF0KICAgICAgICBpZiBjb21tYW5kIGluICgnTFNUJywnQ1dEJywnUEFTUycpOgogICAg
ICAgICAgICBlbnZbJ1BBVEhfSU5GTyddPXNlbGYuX2pvaW5fcGF0aHMoY2hhbm5lbC5wYXRo
LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGgs
ICdtYW5hZ2VfRlRQbGlzdCcpCiAgICAgICAgZWxpZiBjb21tYW5kIGluICgnTURUTScsJ1NJ
WkUnKToKICAgICAgICAgICAgZW52WydQQVRIX0lORk8nXT1zZWxmLl9qb2luX3BhdGhzKGNo
YW5uZWwucGF0aCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICBwYXRoLCAnbWFuYWdlX0ZUUHN0YXQnKQogICAgICAgIGVsaWYgY29tbWFuZD09J1JF
VFInOgogICAgICAgICAgICBlbnZbJ1BBVEhfSU5GTyddPXNlbGYuX2pvaW5fcGF0aHMoY2hh
bm5lbC5wYXRoLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgIHBhdGgsICdtYW5hZ2VfRlRQZ2V0JykKICAgICAgICBlbGlmIGNvbW1hbmQgaW4gKCdS
TUQnLCdERUxFJyk6CiAgICAgICAgICAgIGVudlsnUEFUSF9JTkZPJ109c2VsZi5fam9pbl9w
YXRocyhjaGFubmVsLnBhdGgsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgcGF0aCwgJ21hbmFnZV9kZWxPYmplY3RzJykKICAgICAgICAgICAgZW52
WydRVUVSWV9TVFJJTkcnXT0naWRzPSVzJyAlIGFyZ3NbMF0KICAgICAgICBlbGlmIGNvbW1h
bmQ9PSdNS0QnOgogICAgICAgICAgICBlbnZbJ1BBVEhfSU5GTyddPXNlbGYuX2pvaW5fcGF0
aHMoY2hhbm5lbC5wYXRoLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIHBhdGgsICdtYW5hZ2VfYWRkRm9sZGVyJykKICAgICAgICAgICAgZW52WydR
VUVSWV9TVFJJTkcnXT0naWQ9JXMnICUgYXJnc1swXQogICAgICAgIGVsaWYgY29tbWFuZD09
J1JOVE8nOgogICAgICAgICAgICBlbnZbJ1BBVEhfSU5GTyddPXNlbGYuX2pvaW5fcGF0aHMo
Y2hhbm5lbC5wYXRoLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgIHBhdGgsICdtYW5hZ2VfcmVuYW1lT2JqZWN0JykKICAgICAgICAgICAgZW52WydR
VUVSWV9TVFJJTkcnXT0naWQ9JXMmbmV3X2lkPSVzJyAlIChhcmdzWzBdLGFyZ3NbMV0pCiAg
ICAgICAgZWxpZiBjb21tYW5kPT0nU1RPUic6CiAgICAgICAgICAgIGVudlsnUEFUSF9JTkZP
J109c2VsZi5fam9pbl9wYXRocyhjaGFubmVsLnBhdGgsIHBhdGgpCiAgICAgICAgICAgIGVu
dlsnUkVRVUVTVF9NRVRIT0QnXT0nUFVUJwogICAgICAgICAgICBlbnZbJ0NPTlRFTlRfTEVO
R1RIJ109bGVuKHN0ZGluLmdldHZhbHVlKCkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAg
ZW52WydQQVRIX0lORk8nXT1zZWxmLl9qb2luX3BhdGhzKGNoYW5uZWwucGF0aCwgcGF0aCwg
Y29tbWFuZCkKICAgICAgICByZXR1cm4gZW52CiAgICAKICAgIGRlZiBfam9pbl9wYXRocyhz
ZWxmLCphcmdzKToKICAgICAgICBwYXRoPWFwcGx5KG9zLnBhdGguam9pbixhcmdzKQogICAg
ICAgIHBhdGg9b3MucGF0aC5ub3JtcGF0aChwYXRoKQogICAgICAgIGlmIG9zLnNlcCAhPSAn
Lyc6CiAgICAgICAgICAgIHBhdGg9c3RyaW5nLnJlcGxhY2UocGF0aCxvcy5zZXAsJy8nKQog
ICAgICAgIHJldHVybiBwYXRoCiAgICAgICAgCgoKCgoKCg==
--------------CF3F10DD56A7538D09BE4E14
Content-Type: application/octet-stream;
 name="FTPServer.py"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="FTPServer.py"

IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgCiMgWm9wZSBQdWJsaWMgTGljZW5zZSAoWlBM
KSBWZXJzaW9uIDEuMAojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0K
IyAKIyBDb3B5cmlnaHQgKGMpIERpZ2l0YWwgQ3JlYXRpb25zLiAgQWxsIHJpZ2h0cyByZXNl
cnZlZC4KIyAKIyBUaGlzIGxpY2Vuc2UgaGFzIGJlZW4gY2VydGlmaWVkIGFzIE9wZW4gU291
cmNlKHRtKS4KIyAKIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmlu
YXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0
ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCiMgbWV0Ogoj
IAojIDEuIFJlZGlzdHJpYnV0aW9ucyBpbiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUg
YWJvdmUgY29weXJpZ2h0CiMgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucywg
YW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KIyAKIyAyLiBSZWRpc3RyaWJ1dGlvbnMg
aW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAojICAg
IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMsIGFuZCB0aGUgZm9sbG93aW5nIGRp
c2NsYWltZXIgaW4KIyAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJp
YWxzIHByb3ZpZGVkIHdpdGggdGhlCiMgICAgZGlzdHJpYnV0aW9uLgojIAojIDMuIERpZ2l0
YWwgQ3JlYXRpb25zIHJlcXVlc3RzIHRoYXQgYXR0cmlidXRpb24gYmUgZ2l2ZW4gdG8gWm9w
ZQojICAgIGluIGFueSBtYW5uZXIgcG9zc2libGUuIFpvcGUgaW5jbHVkZXMgYSAiUG93ZXJl
ZCBieSBab3BlIgojICAgIGJ1dHRvbiB0aGF0IGlzIGluc3RhbGxlZCBieSBkZWZhdWx0LiBX
aGlsZSBpdCBpcyBub3QgYSBsaWNlbnNlCiMgICAgdmlvbGF0aW9uIHRvIHJlbW92ZSB0aGlz
IGJ1dHRvbiwgaXQgaXMgcmVxdWVzdGVkIHRoYXQgdGhlCiMgICAgYXR0cmlidXRpb24gcmVt
YWluLiBBIHNpZ25pZmljYW50IGludmVzdG1lbnQgaGFzIGJlZW4gcHV0CiMgICAgaW50byBa
b3BlLCBhbmQgdGhpcyBlZmZvcnQgd2lsbCBjb250aW51ZSBpZiB0aGUgWm9wZSBjb21tdW5p
dHkKIyAgICBjb250aW51ZXMgdG8gZ3Jvdy4gVGhpcyBpcyBvbmUgd2F5IHRvIGFzc3VyZSB0
aGF0IGdyb3d0aC4KIyAKIyA0LiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIGFuZCBkb2N1
bWVudGF0aW9uIG1lbnRpb25pbmcKIyAgICBmZWF0dXJlcyBkZXJpdmVkIGZyb20gb3IgdXNl
IG9mIHRoaXMgc29mdHdhcmUgbXVzdCBkaXNwbGF5CiMgICAgdGhlIGZvbGxvd2luZyBhY2tu
b3dsZWRnZW1lbnQ6CiMgCiMgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJl
IGRldmVsb3BlZCBieSBEaWdpdGFsIENyZWF0aW9ucwojICAgICAgZm9yIHVzZSBpbiB0aGUg
WiBPYmplY3QgUHVibGlzaGluZyBFbnZpcm9ubWVudAojICAgICAgKGh0dHA6Ly93d3cuem9w
ZS5vcmcvKS4iCiMgCiMgICAgSW4gdGhlIGV2ZW50IHRoYXQgdGhlIHByb2R1Y3QgYmVpbmcg
YWR2ZXJ0aXNlZCBpbmNsdWRlcyBhbgojICAgIGludGFjdCBab3BlIGRpc3RyaWJ1dGlvbiAo
d2l0aCBjb3B5cmlnaHQgYW5kIGxpY2Vuc2UgaW5jbHVkZWQpCiMgICAgdGhlbiB0aGlzIGNs
YXVzZSBpcyB3YWl2ZWQuCiMgCiMgNS4gTmFtZXMgYXNzb2NpYXRlZCB3aXRoIFpvcGUgb3Ig
RGlnaXRhbCBDcmVhdGlvbnMgbXVzdCBub3QgYmUgdXNlZCB0bwojICAgIGVuZG9yc2Ugb3Ig
cHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0CiMg
ICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGZyb20gRGlnaXRhbCBDcmVhdGlvbnMuCiMg
CiMgNi4gTW9kaWZpZWQgcmVkaXN0cmlidXRpb25zIG9mIGFueSBmb3JtIHdoYXRzb2V2ZXIg
bXVzdCByZXRhaW4KIyAgICB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgojIAojICAg
ICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgRGlnaXRh
bCBDcmVhdGlvbnMKIyAgICAgIGZvciB1c2UgaW4gdGhlIFogT2JqZWN0IFB1Ymxpc2hpbmcg
RW52aXJvbm1lbnQKIyAgICAgIChodHRwOi8vd3d3LnpvcGUub3JnLykuIgojIAojICAgIElu
dGFjdCAocmUtKWRpc3RyaWJ1dGlvbnMgb2YgYW55IG9mZmljaWFsIFpvcGUgcmVsZWFzZSBk
byBub3QKIyAgICByZXF1aXJlIGFuIGV4dGVybmFsIGFja25vd2xlZGdlbWVudC4KIyAKIyA3
LiBNb2RpZmljYXRpb25zIGFyZSBlbmNvdXJhZ2VkIGJ1dCBtdXN0IGJlIHBhY2thZ2VkIHNl
cGFyYXRlbHkgYXMKIyAgICBwYXRjaGVzIHRvIG9mZmljaWFsIFpvcGUgcmVsZWFzZXMuICBE
aXN0cmlidXRpb25zIHRoYXQgZG8gbm90CiMgICAgY2xlYXJseSBzZXBhcmF0ZSB0aGUgcGF0
Y2hlcyBmcm9tIHRoZSBvcmlnaW5hbCB3b3JrIG11c3QgYmUgY2xlYXJseQojICAgIGxhYmVs
ZWQgYXMgdW5vZmZpY2lhbCBkaXN0cmlidXRpb25zLiAgTW9kaWZpY2F0aW9ucyB3aGljaCBk
byBub3QKIyAgICBjYXJyeSB0aGUgbmFtZSBab3BlIG1heSBiZSBwYWNrYWdlZCBpbiBhbnkg
Zm9ybSwgYXMgbG9uZyBhcyB0aGV5CiMgICAgY29uZm9ybSB0byBhbGwgb2YgdGhlIGNsYXVz
ZXMgYWJvdmUuCiMgCiMgCiMgRGlzY2xhaW1lcgojIAojICAgVEhJUyBTT0ZUV0FSRSBJUyBQ
Uk9WSURFRCBCWSBESUdJVEFMIENSRUFUSU9OUyBgYEFTIElTJycgQU5EIEFOWQojICAgRVhQ
UkVTU0VEIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlU
RUQgVE8sIFRIRQojICAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBB
TkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSCiMgICBQVVJQT1NFIEFSRSBESVNDTEFJTUVE
LiAgSU4gTk8gRVZFTlQgU0hBTEwgRElHSVRBTCBDUkVBVElPTlMgT1IgSVRTCiMgICBDT05U
UklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRB
TCwKIyAgIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJ
TkNMVURJTkcsIEJVVCBOT1QKIyAgIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNU
SVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKIyAgIFVTRSwgREFUQSwgT1IgUFJP
RklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKIyAg
IE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJ
Q1QgTElBQklMSVRZLAojICAgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RI
RVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCiMgICBPRiBUSEUgVVNFIE9GIFRISVMg
U09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKIyAgIFNV
Q0ggREFNQUdFLgojIAojIAojIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2YgY29udHJpYnV0
aW9ucyBtYWRlIGJ5IERpZ2l0YWwgQ3JlYXRpb25zIGFuZAojIG1hbnkgaW5kaXZpZHVhbHMg
b24gYmVoYWxmIG9mIERpZ2l0YWwgQ3JlYXRpb25zLiAgU3BlY2lmaWMKIyBhdHRyaWJ1dGlv
bnMgYXJlIGxpc3RlZCBpbiB0aGUgYWNjb21wYW55aW5nIGNyZWRpdHMgZmlsZS4KIyAKIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjCgojCVJlbmFtZSBjYXBhYmlsaXR5IGFkZGVkLCBkLmQu
IDIwMDEwMTIwIGJ5IHRvbS52aWpsYnJpZWZAaXNpb24ubmwKIwoKIiIiWlNlcnZlciBGVFAg
Q2hhbm5lbCBmb3IgdXNlIHRoZSBtZWR1c2EncyBmdHAgc2VydmVyLgoKRlRQIFNlcnZpY2Ug
Zm9yIFpvcGUuCgogIFRoaXMgc2VydmVyIGFsbG93cyBGVFAgY29ubmVjdGlvbnMgdG8gWm9w
ZS4gSW4gZ2VuZXJhbCBGVFAgaXMgdXNlZAogIHRvIG1hbmFnZSBjb250ZW50LiBZb3UgY2Fu
OgoKICAgICogQ3JlYXRlIGFuZCBkZWxldGUgRm9sZGVycywgRG9jdW1lbnRzLCBGaWxlcywg
YW5kIEltYWdlcwoKICAgICogRWRpdCB0aGUgY29udGVudHMgb2YgRG9jdW1lbnRzLCBGaWxl
cywgSW1hZ2VzCgogIEluIHRoZSBmdXR1cmUsIEZUUCBtYXkgYmUgdXNlZCB0byBlZGl0IG9i
amVjdCBwcm9wZXJ0aWVzLgoKRlRQIFByb3RvY29sCgogIFRoZSBGVFAgcHJvdG9jb2wgZm9y
IFpvcGUgZ2l2ZXMgWm9wZSBvYmplY3RzIGEgd2F5IHRvIG1ha2UgdGhlbXNlbHZlcwogIGF2
YWlsYWJsZSB0byBGVFAgc2VydmljZXMuIFNlZSB0aGUgJ2xpYi9weXRob24vT0ZTL0ZUUElu
dGVyZmFjZS5weScgZm9yCiAgbW9yZSBkZXRhaWxzLgoKRlRQIFBlcm1pc3Npb25zCgogIEZU
UCBhY2Nlc3MgaXMgY29udHJvbGxlZCBieSBvbmUgcGVybWlzc2lvbjogJ0ZUUCBhY2Nlc3Mn
IGlmIGJvdW5kIHRvIGEKICByb2xlLCB1c2VycyBvZiB0aGF0IHJvbGUgd2lsbCBiZSBhYmxl
IHRvIGxpc3QgZGlyZWN0b3JpZXMsIGFuZCBjZCB0bwogIHRoZW0uIENyZWF0aW5nIGFuZCBk
ZWxldGluZyBhbmQgY2hhbmdpbmcgb2JqZWN0cyBhcmUgYWxsIGdvdmVybmVkIGJ5CiAgZXhp
c3RpbmcgWm9wZSBwZXJtaXNzaW9ucy4KCiAgUGVybWlzc2lvbnMgYXJlIHRvIGEgY2VydGFp
biBleHRlbnQgcmVmbGVjdGVkIGluIHRoZSBwZXJtaXNzaW9uIGJpdHMKICBsaXN0ZWQgaW4g
RlRQIGZpbGUgbGlzdGluZ3MuCgpGVFAgQXV0aG9yaXphdGlvbgoKICBab3BlIHN1cHBvcnRz
IGJvdGggbm9ybWFsIGFuZCBhbm9ueW1vdXMgbG9naW5zLiBJdCBjYW4gYmUgZGlmZmljdWx0
CiAgdG8gYXV0aG9yaXplIFpvcGUgdXNlcnMgc2luY2UgdGhleSBhcmUgZGVmaW5lZCBpbiBk
aXN0cmlidXRlZCB1c2VyCiAgZGF0YWJhc2VzLiBOb3JtYWxseSwgYWxsIGxvZ2lucyB3aWxs
IGJlIGFjY2VwdGVkIGFuZCB0aGVuIHRoZSB1c2VyIG11c3QKICBwcm9jZWVkIHRvICdjZCcg
dG8gYSBkaXJlY3RvcnkgaW4gd2hpY2ggdGhleSBhcmUgYXV0aG9yaXplZC4gSW4gdGhpcwog
IGNhc2UgZm9yIHRoZSBwdXJwb3NlIG9mIEZUUCBsaW1pdHMsIHRoZSB1c2VyIGlzIGNvbnNp
ZGVyZWQgYW5vbnltb3VzCiAgdW50aWwgdGhleSBjZCB0byBhbiBhdXRob3JpemVkIGRpcmVj
dG9yeS4KCiAgT3B0aW9uYWxseSwgdXNlcnMgY2FuIGxvZ2luIHdpdGggYSBzcGVjaWFsIHVz
ZXJuYW1lIHdoaWNoIGluZGljYXRlcwogIHdoZXJlIHRoZXkgYXJlIGRlZmluZWQuIFRoZWly
IGxvZ2luIHdpbGwgdGhlbiBiZSBhdXRoZW50aWNhdGVkIGluCiAgdGhlIGluZGljYXRlZCBk
aXJlY3RvcnksIGFuZCB0aGV5IHdpbGwgbm90IGJlIGNvbnNpZGVyZWQgYW5vbnltb3VzLgog
IFRoZSBmb3JtIG9mIHRoZSBuYW1lIGlzICc8dXNlcm5hbWU+QDxwYXRoPicgd2hlcmUgcGF0
aCB0YWtlcyB0aGUgZm9ybQogICc8Zm9sZGVyIGlkPlsvPGZvbGRlciBpZD4uLi5dJyBGb3Ig
ZXhhbXBsZTogJ2Ftb3NARm9vL0JhcicgVGhpcyB3aWxsCiAgYXV0aGVudGljYXRlIHRoZSB1
c2VyICdhbW9zJyBpbiB0aGUgZGlyZWN0b3J5ICcvRm9vL0JhcicuIEluIGFkZGl0aW9uCiAg
dGhlIHVzZXIncyBGVFAgc2Vzc2lvbiB3aWxsIGJlIHJvb3RlZCBpbiB0aGUgYXV0aGVudGlj
YXRlZCBkaXJlY3RvcnksCiAgaS5lLiB0aGV5IHdpbGwgbm90IGJlIGFibGUgdG8gY2Qgb3V0
IG9mIHRoZSBkaXJlY3RvcnkuCgogIFRoZSBtYWluIHJlYXNvbiB0byB1c2UgdGhlIHJvb3Rl
ZCBGVFAgbG9naW4sIGlzIHRvIGFsbG93IG5vbi1hbm9ueW1vdXMKICBsb2dpbnMuIFRoaXMg
bWF5IGJlIGhhbmR5LCBpZiBmb3IgZXhhbXBsZSwgeW91IGRpc2FsbG93IGFub255bW91cyBs
b2dpbnMsCiAgb3IgaWYgeW91IHNldCB0aGUgbGltaXQgZm9yIHNpbXVsdGFuZW91cyBhbm9u
eW1vdXMgbG9naW5zIHZlcnkgbG93LgoKIiIiCgpmcm9tIFB1YkNvcmUgaW1wb3J0IGhhbmRs
ZQpmcm9tIG1lZHVzYS5mdHBfc2VydmVyIGltcG9ydCBmdHBfY2hhbm5lbCwgZnRwX3NlcnZl
ciwgcmVjdl9jaGFubmVsCmZyb20gbWVkdXNhIGltcG9ydCBhc3luY29yZSwgYXN5bmNoYXQs
IGZpbGVzeXMKZnJvbSBGVFBSZXNwb25zZSBpbXBvcnQgbWFrZV9yZXNwb25zZQpmcm9tIEZU
UFJlcXVlc3QgaW1wb3J0IEZUUFJlcXVlc3QKCmZyb20gWlNlcnZlciBpbXBvcnQgQ09OTkVD
VElPTl9MSU1JVCwgcmVxdWVzdENsb3NlT25FeGVjCgpmcm9tIGNTdHJpbmdJTyBpbXBvcnQg
U3RyaW5nSU8KaW1wb3J0IHN0cmluZwppbXBvcnQgb3MKZnJvbSBtaW1ldHlwZXMgaW1wb3J0
IGd1ZXNzX3R5cGUKaW1wb3J0IG1hcnNoYWwKaW1wb3J0IHN0YXQKaW1wb3J0IHRpbWUKCgpj
bGFzcyB6b3BlX2Z0cF9jaGFubmVsKGZ0cF9jaGFubmVsKToKICAgICJQYXNzZXMgaXRzIGNv
bW1hbmRzIHRvIFpvcGUsIG5vdCBhIGZpbGVzeXN0ZW0iCiAgICAKICAgIHJlYWRfb25seT0w
CiAgICBhbm9ueW1vdXM9MQogICAgCiAgICBkZWYgX19pbml0X18gKHNlbGYsIHNlcnZlciwg
Y29ubiwgYWRkciwgbW9kdWxlKToKICAgICAgICBmdHBfY2hhbm5lbC5fX2luaXRfXyhzZWxm
LHNlcnZlcixjb25uLGFkZHIpCiAgICAgICAgcmVxdWVzdENsb3NlT25FeGVjKGNvbm4pCiAg
ICAgICAgc2VsZi5tb2R1bGU9bW9kdWxlCiAgICAgICAgc2VsZi51c2VyaWQ9JycKICAgICAg
ICBzZWxmLnBhc3N3b3JkPScnCiAgICAgICAgc2VsZi5wYXRoPScvJwogICAgICAgIHNlbGYu
Y29va2llcz17fQogICAgCiAgICBkZWYgX2pvaW5fcGF0aHMoc2VsZiwqYXJncyk6CiAgICAg
ICAgcGF0aD1hcHBseShvcy5wYXRoLmpvaW4sYXJncykKICAgICAgICBwYXRoPW9zLnBhdGgu
bm9ybXBhdGgocGF0aCkKICAgICAgICBpZiBvcy5zZXAgIT0gJy8nOgogICAgICAgICAgICBw
YXRoPXN0cmluZy5yZXBsYWNlKHBhdGgsb3Muc2VwLCcvJykKICAgICAgICByZXR1cm4gcGF0
aAogICAgCiAgICAjIE92ZXJyaWRlbiBhc3luY19jaGF0IG1ldGhvZHMKCiAgICBkZWYgcHVz
aChzZWxmLCBwcm9kdWNlciwgc2VuZD0xKToKICAgICAgICAjIHRoaXMgaXMgdGhyZWFkLXNh
ZmUgd2hlbiBzZW5kIGlzIGZhbHNlCiAgICAgICAgIyBub3RlLCB0aGF0IHN0cmluZ3MgYXJl
IG5vdCB3cmFwcGVkIGluIAogICAgICAgICMgcHJvZHVjZXJzIGJ5IGRlZmF1bHQKICAgICAg
ICBzZWxmLnByb2R1Y2VyX2ZpZm8ucHVzaChwcm9kdWNlcikKICAgICAgICBpZiBzZW5kOiBz
ZWxmLmluaXRpYXRlX3NlbmQoKQogICAgICAgIAogICAgcHVzaF93aXRoX3Byb2R1Y2VyPXB1
c2gKICAgIAogICAgCiAgICAjIE92ZXJyaWRlbiBmdHBfY2hhbm5lbCBtZXRob2RzCgogICAg
ZGVmIGNtZF9ubHN0IChzZWxmLCBsaW5lKToKICAgICAgICAnZ2l2ZSBuYW1lIGxpc3Qgb2Yg
ZmlsZXMgaW4gZGlyZWN0b3J5JwogICAgICAgIHNlbGYuZ2V0X2Rpcl9saXN0KGxpbmUsMCkK
CiAgICBkZWYgY21kX2xpc3QgKHNlbGYsIGxpbmUpOgogICAgICAgICdnaXZlIGxpc3QgZmls
ZXMgaW4gYSBkaXJlY3RvcnknCiAgICAgICAgCiAgICAgICAgIyBoYW5kbGVzIGZpbGVzIGFz
IHdlbGwgYXMgZGlyZWN0b3JpZXMuCiAgICAgICAgIyBYWFggYWxzbyBzaG91bGQgbWF5YmUg
aGFuZGxlIGdsb2JiaW5nLCB5dWNrLgogIAogICAgICAgIHNlbGYuZ2V0X2Rpcl9saXN0KGxp
bmUsMSkKICAgIAogICAgZGVmIGdldF9kaXJfbGlzdChzZWxmLCBsaW5lLCBsb25nPTApOgog
ICAgICAgICMgd2UgbmVlZCB0byBzY2FuIHRoZSBjb21tYW5kIGxpbmUgZm9yIGFyZ3VtZW50
cyB0byAnL2Jpbi9scycuLi4KICAgICAgICAjIFhYWCBjbGVhbiB0aGlzIHVwLCBtYXliZSB3
aXRoIGdldG9wdHMKICAgICAgICBpZiBsZW4obGluZSkgPiAxOgogICAgICAgICAgICBhcmdz
ID0gc3RyaW5nLnNwbGl0KGxpbmVbMV0pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYXJn
cyA9W10KICAgICAgICBwYXRoX2FyZ3MgPSBbXQogICAgICAgIGZvciBhcmcgaW4gYXJnczoK
ICAgICAgICAgICAgaWYgYXJnWzBdICE9ICctJzoKICAgICAgICAgICAgICAgIHBhdGhfYXJn
cy5hcHBlbmQgKGFyZykKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGlmICds
JyBpbiBhcmc6CiAgICAgICAgICAgICAgICAgICAgbG9uZz0xCiAgICAgICAgaWYgbGVuKHBh
dGhfYXJncykgPCAxOgogICAgICAgICAgICBkaXIgPSAnLicKICAgICAgICBlbHNlOgogICAg
ICAgICAgICBkaXIgPSBwYXRoX2FyZ3NbMF0KICAgICAgICBzZWxmLmxpc3RkaXIoZGlyLCBs
b25nKQogICAgCiAgICBkZWYgbGlzdGRpciAoc2VsZiwgcGF0aCwgbG9uZz0wKToKICAgICAg
ICByZXNwb25zZT1tYWtlX3Jlc3BvbnNlKHNlbGYsIHNlbGYubGlzdGRpcl9jb21wbGV0aW9u
LCBsb25nKQogICAgICAgIHJlcXVlc3Q9RlRQUmVxdWVzdChwYXRoLCAnTFNUJywgc2VsZiwg
cmVzcG9uc2UpCiAgICAgICAgaGFuZGxlKHNlbGYubW9kdWxlLCByZXF1ZXN0LCByZXNwb25z
ZSkgICAgICAgICAKICAgICAgICAKICAgIGRlZiBsaXN0ZGlyX2NvbXBsZXRpb24oc2VsZiwg
bG9uZywgcmVzcG9uc2UpOgogICAgICAgIHN0YXR1cz1yZXNwb25zZS5nZXRTdGF0dXMoKQog
ICAgICAgIGlmIHN0YXR1cz09MjAwOgogICAgICAgICAgICBpZiBzZWxmLmFub255bW91cyBh
bmQgbm90IHNlbGYudXNlcmlkPT0nYW5vbnltb3VzJzoKICAgICAgICAgICAgICAgIHNlbGYu
YW5vbnltb3VzPU5vbmUKICAgICAgICAgICAgZGlyX2xpc3Q9JycKICAgICAgICAgICAgZmls
ZV9pbmZvcz1yZXNwb25zZS5fbWFyc2hhbGxlZEJvZHkoKQogICAgICAgICAgICBpZiB0eXBl
KGZpbGVfaW5mb3NbMF0pPT10eXBlKCcnKToKICAgICAgICAgICAgICAgIGZpbGVfaW5mb3M9
KGZpbGVfaW5mb3MsKSAgICAKICAgICAgICAgICAgaWYgbG9uZzoKICAgICAgICAgICAgICAg
IGZvciBpZCwgc3RhdF9pbmZvIGluIGZpbGVfaW5mb3M6CiAgICAgICAgICAgICAgICAgICAg
ZGlyX2xpc3Q9ZGlyX2xpc3QrZmlsZXN5cy51bml4X2xvbmdpZnkoaWQsc3RhdF9pbmZvKSsn
XHJcbicKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGZvciBpZCwgc3RhdF9p
bmZvIGluIGZpbGVfaW5mb3M6CiAgICAgICAgICAgICAgICAgICAgZGlyX2xpc3Q9ZGlyX2xp
c3QraWQrJ1xyXG4nCiAgICAgICAgICAgIHNlbGYubWFrZV94bWl0X2NoYW5uZWwoKQogICAg
ICAgICAgICBzZWxmLmNsaWVudF9kYy5wdXNoKGRpcl9saXN0KQogICAgICAgICAgICBzZWxm
LmNsaWVudF9kYy5jbG9zZV93aGVuX2RvbmUoKSAgICAgICAgICAgICAgICAKICAgICAgICAg
ICAgc2VsZi5yZXNwb25kKAogICAgICAgICAgICAgICAgJzE1MCBPcGVuaW5nICVzIG1vZGUg
ZGF0YSBjb25uZWN0aW9uIGZvciBmaWxlIGxpc3QnICUgKAogICAgICAgICAgICAgICAgICAg
IHNlbGYudHlwZV9tYXBbc2VsZi5jdXJyZW50X21vZGVdCiAgICAgICAgICAgICAgICAgICAg
KQogICAgICAgICAgICAgICAgKSAgIAogICAgICAgIGVsaWYgc3RhdHVzPT00MDE6CiAgICAg
ICAgICAgIHNlbGYucmVzcG9uZCgnNTMwIFVuYXV0aG9yaXplZC4nKQogICAgICAgIGVsc2U6
CiAgICAgICAgICAgIHNlbGYucmVzcG9uZCgnNTUwIENvdWxkIG5vdCBsaXN0IGRpcmVjdG9y
eS4nKQoKICAgIGRlZiBjbWRfY3dkIChzZWxmLCBsaW5lKToKICAgICAgICAnY2hhbmdlIHdv
cmtpbmcgZGlyZWN0b3J5JwogICAgICAgIHJlc3BvbnNlPW1ha2VfcmVzcG9uc2Uoc2VsZiwg
c2VsZi5jd2RfY29tcGxldGlvbiwgCiAgICAgICAgICAgICAgICBzZWxmLl9qb2luX3BhdGhz
KHNlbGYucGF0aCxsaW5lWzFdKSkKICAgICAgICByZXF1ZXN0PUZUUFJlcXVlc3QobGluZVsx
XSwnQ1dEJyxzZWxmLHJlc3BvbnNlKQogICAgICAgIGhhbmRsZShzZWxmLm1vZHVsZSxyZXF1
ZXN0LHJlc3BvbnNlKSAgICAgICAKCiAgICBkZWYgY3dkX2NvbXBsZXRpb24oc2VsZixwYXRo
LHJlc3BvbnNlKToKICAgICAgICAnY3dkIGNvbXBsZXRpb24gY2FsbGJhY2snCiAgICAgICAg
c3RhdHVzPXJlc3BvbnNlLmdldFN0YXR1cygpCiAgICAgICAgaWYgc3RhdHVzPT0yMDA6CiAg
ICAgICAgICAgIGxpc3Rpbmc9cmVzcG9uc2UuX21hcnNoYWxsZWRCb2R5KCkKICAgICAgICAg
ICAgIyBjaGVjayB0byBzZWUgaWYgd2UgYXJlIGNkaW5nIHRvIGEgbm9uLWZvbGRvaWQgb2Jq
ZWN0CiAgICAgICAgICAgIGlmIHR5cGUobGlzdGluZ1swXSk9PXR5cGUoJycpOgogICAgICAg
ICAgICAgICAgc2VsZi5yZXNwb25kKCc1NTAgTm8gc3VjaCBkaXJlY3RvcnkuJykKICAgICAg
ICAgICAgICAgIHJldHVybgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2Vs
Zi5wYXRoPXBhdGggb3IgJy8nCiAgICAgICAgICAgICAgICBzZWxmLnJlc3BvbmQoJzI1MCBD
V0QgY29tbWFuZCBzdWNjZXNzZnVsLicpCiAgICAgICAgICAgICAgICAjIG5vdyB0aGF0IHdl
J3ZlIHN1Y3Vzc2Z1bGx5IGNkJ2QgcGVyaGFwcyB3ZSBhcmUgbm8KICAgICAgICAgICAgICAg
ICMgbG9uZ2VyIGFub255bW91cwogICAgICAgICAgICAgICAgaWYgc2VsZi5hbm9ueW1vdXMg
YW5kIG5vdCBzZWxmLnVzZXJpZD09J2Fub255bW91cyc6CiAgICAgICAgICAgICAgICAgICAg
c2VsZi5hbm9ueW1vdXM9Tm9uZQogICAgICAgIGVsaWYgc3RhdHVzPT00MDE6CiAgICAgICAg
ICAgIHNlbGYucmVzcG9uZCgnNTMwIFVuYXV0aG9yaXplZC4nKQogICAgICAgIGVsc2U6CiAg
ICAgICAgICAgIHNlbGYucmVzcG9uZCgnNTUwIE5vIHN1Y2ggZGlyZWN0b3J5LicpCgogICAg
ZGVmIGNtZF9jZHVwIChzZWxmLCBsaW5lKToKICAgICAgICAnY2hhbmdlIHRvIHBhcmVudCBv
ZiBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5JwogICAgICAgIHNlbGYuY21kX2N3ZCgoTm9u
ZSwnLi4nKSkKCiAgICBkZWYgY21kX3B3ZCAoc2VsZiwgbGluZSk6CiAgICAgICAgJ3ByaW50
IHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5JwogICAgICAgIHNlbGYucmVzcG9uZCAo
CiAgICAgICAgICAgICcyNTcgIiVzIiBpcyB0aGUgY3VycmVudCBkaXJlY3RvcnkuJyAlICgK
ICAgICAgICAgICAgICAgIHNlbGYucGF0aAogICAgICAgICAgICAgICAgKQogICAgICAgICAg
ICApCiAgICAKICAgIGNtZF94cHdkPWNtZF9wd2QKICAgIAogICAgZGVmIGNtZF9tZHRtKHNl
bGYsIGxpbmUpOgogICAgICAgICdzaG93IGxhc3QgbW9kaWZpY2F0aW9uIHRpbWUgb2YgZmls
ZScKICAgICAgICBpZiBsZW4gKGxpbmUpICE9IDI6CiAgICAgICAgICAgIHNlbGYuY29tbWFu
ZC5ub3RfdW5kZXJzdG9vZCAoc3RyaW5nLmpvaW4gKGxpbmUpKQogICAgICAgICAgICByZXR1
cm4KICAgICAgICByZXNwb25zZT1tYWtlX3Jlc3BvbnNlKHNlbGYsIHNlbGYubWR0bV9jb21w
bGV0aW9uKQogICAgICAgIHJlcXVlc3Q9RlRQUmVxdWVzdChsaW5lWzFdLCdNRFRNJyxzZWxm
LHJlc3BvbnNlKQogICAgICAgIGhhbmRsZShzZWxmLm1vZHVsZSxyZXF1ZXN0LHJlc3BvbnNl
KSAgICAgICAKICAgIAogICAgZGVmIG1kdG1fY29tcGxldGlvbihzZWxmLCByZXNwb25zZSk6
CiAgICAgICAgc3RhdHVzPXJlc3BvbnNlLmdldFN0YXR1cygpCiAgICAgICAgaWYgc3RhdHVz
PT0yMDA6CiAgICAgICAgICAgIG10aW1lPXJlc3BvbnNlLl9tYXJzaGFsbGVkQm9keSgpW3N0
YXQuU1RfTVRJTUVdCiAgICAgICAgICAgIG10aW1lPXRpbWUuZ210aW1lKG10aW1lKQogICAg
ICAgICAgICBzZWxmLnJlc3BvbmQoJzIxMyAlNGQlMDJkJTAyZCUwMmQlMDJkJTAyZCcgJSAo
CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXRpbWVbMF0sCiAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgbXRpbWVbMV0sCiAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgbXRpbWVbMl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXRp
bWVbM10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXRpbWVbNF0sCiAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgbXRpbWVbNV0KICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICApKQogICAgICAgIGVsaWYgc3RhdHVzPT00MDE6CiAgICAgICAgICAg
IHNlbGYucmVzcG9uZCgnNTMwIFVuYXV0aG9yaXplZC4nKSAKICAgICAgICBlbHNlOgogICAg
ICAgICAgICBzZWxmLnJlc3BvbmQoJzU1MCBFcnJvciBnZXR0aW5nIGZpbGUgbW9kaWZpY2F0
aW9uIHRpbWUuJykgIAogICAgICAgICAgICAgICAgCiAgICBkZWYgY21kX3NpemUoc2VsZiwg
bGluZSk6CiAgICAgICAgJ3JldHVybiBzaXplIG9mIGZpbGUnCiAgICAgICAgIyBUaGUgc2l6
ZSBjb21tYW5kIHNvbWV0aW1lcyByZXR1cm5zIHRoZQogICAgICAgICMgc2l6ZSBvZiBpZGVu
dGljYWwgbmFtZWQgb2JqZWN0cyBpbiBvdGhlciBkaXJzLi4uLgoJIyBUaGlzIGNvbmZ1c2Vz
IHRoZSBLREUgRlRQIGNsaWVudAogICAgICAgICMgSSd2ZSBub3QgZm91bmQgdGhlIGNhdXNl
ICh5ZXQpIC0tIFRvbVYKICAgICAgICBpZiBsZW4gKGxpbmUpICE9IDI6CiAgICAgICAgICBz
ZWxmLmNvbW1hbmQubm90X3VuZGVyc3Rvb2QgKHN0cmluZy5qb2luIChsaW5lKSkKICAgICAg
ICAgIHJldHVybgogICAgICAgIHJlc3BvbnNlPW1ha2VfcmVzcG9uc2Uoc2VsZiwgc2VsZi5z
aXplX2NvbXBsZXRpb24pCiAgICAgICAgcmVxdWVzdD1GVFBSZXF1ZXN0KGxpbmVbMV0sJ1NJ
WkUnLHNlbGYscmVzcG9uc2UpCiAgICAgICAgaGFuZGxlKHNlbGYubW9kdWxlLHJlcXVlc3Qs
cmVzcG9uc2UpICAgICAgIAogICAgICAgIAogICAgZGVmIHNpemVfY29tcGxldGlvbihzZWxm
LHJlc3BvbnNlKToKICAgICAgICBzdGF0dXM9cmVzcG9uc2UuZ2V0U3RhdHVzKCkKICAgICAg
ICBpZiBzdGF0dXM9PTIwMDoKICAgICAgICAgICAgc2VsZi5yZXNwb25kKCcyMTMgJWQnJSBy
ZXNwb25zZS5fbWFyc2hhbGxlZEJvZHkoKVtzdGF0LlNUX1NJWkVdKQogICAgICAgIGVsaWYg
c3RhdHVzPT00MDE6CiAgICAgICAgICAgIHNlbGYucmVzcG9uZCgnNTMwIFVuYXV0aG9yaXpl
ZC4nKSAKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnJlc3BvbmQoJzU1MCBFcnJv
ciBnZXR0aW5nIGZpbGUgc2l6ZS4nKSAgIAogICAgICAgICAgICAKICAgICAgICAgICAgI3Nl
bGYuY2xpZW50X2RjLmNsb3NlX3doZW5fZG9uZSgpCgogICAgZGVmIGNtZF9yZXRyKHNlbGYs
bGluZSk6CiAgICAgICAgaWYgbGVuKGxpbmUpIDwgMjoKICAgICAgICAgICAgc2VsZi5jb21t
YW5kX25vdF91bmRlcnN0b29kIChzdHJpbmcuam9pbiAobGluZSkpCiAgICAgICAgICAgIHJl
dHVybgogICAgICAgIHJlc3BvbnNlPW1ha2VfcmVzcG9uc2Uoc2VsZiwgc2VsZi5yZXRyX2Nv
bXBsZXRpb24sIGxpbmVbMV0pCiAgICAgICAgc2VsZi5fcmVzcG9uc2VfcHJvZHVjZXJzID0g
cmVzcG9uc2Uuc3Rkb3V0Ll9wcm9kdWNlcnMKICAgICAgICByZXF1ZXN0PUZUUFJlcXVlc3Qo
bGluZVsxXSwnUkVUUicsc2VsZixyZXNwb25zZSkKICAgICAgICBoYW5kbGUoc2VsZi5tb2R1
bGUscmVxdWVzdCxyZXNwb25zZSkgCgogICAgZGVmIHJldHJfY29tcGxldGlvbihzZWxmLCBm
aWxlLCByZXNwb25zZSk6ICAgICAgICAKICAgICAgICBzdGF0dXM9cmVzcG9uc2UuZ2V0U3Rh
dHVzKCkKICAgICAgICBpZiBzdGF0dXM9PTIwMDoKICAgICAgICAgICAgc2VsZi5tYWtlX3ht
aXRfY2hhbm5lbCgpCiAgICAgICAgICAgIGlmIG5vdCByZXNwb25zZS5fd3JvdGU6CiAgICAg
ICAgICAgICAgICBzZWxmLmNsaWVudF9kYy5wdXNoKHJlc3BvbnNlLmJvZHkpCiAgICAgICAg
ICAgIGVsc2U6CiAgICAgICAgICAgICAgICBmb3IgcHJvZHVjZXIgaW4gc2VsZi5fcmVzcG9u
c2VfcHJvZHVjZXJzOgogICAgICAgICAgICAgICAgICAgIHNlbGYuY2xpZW50X2RjLnB1c2hf
d2l0aF9wcm9kdWNlcihwcm9kdWNlcikKICAgICAgICAgICAgc2VsZi5fcmVzcG9uc2VfcHJv
ZHVjZXJzID0gTm9uZQogICAgICAgICAgICBzZWxmLmNsaWVudF9kYy5jbG9zZV93aGVuX2Rv
bmUoKQogICAgICAgICAgICBzZWxmLnJlc3BvbmQoCiAgICAgICAgICAgICAgICAgICAgIjE1
MCBPcGVuaW5nICVzIG1vZGUgZGF0YSBjb25uZWN0aW9uIGZvciBmaWxlICclcyciICUgKAog
ICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnR5cGVfbWFwW3NlbGYuY3VycmVudF9tb2Rl
XSwKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZQogICAgICAgICAgICAgICAgICAgICAg
ICApKQogICAgICAgIGVsaWYgc3RhdHVzPT00MDE6CiAgICAgICAgICAgIHNlbGYucmVzcG9u
ZCgnNTMwIFVuYXV0aG9yaXplZC4nKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYu
cmVzcG9uZCgnNTUwIEVycm9yIG9wZW5pbmcgZmlsZS4nKSAgICAKCiAgICBkZWYgY21kX3N0
b3IgKHNlbGYsIGxpbmUsIG1vZGU9J3diJyk6CiAgICAgICAgJ3N0b3JlIGEgZmlsZScKICAg
ICAgICBpZiBsZW4gKGxpbmUpIDwgMjoKICAgICAgICAgICAgc2VsZi5jb21tYW5kX25vdF91
bmRlcnN0b29kIChzdHJpbmcuam9pbiAobGluZSkpCiAgICAgICAgICAgIHJldHVybgogICAg
ICAgIGVsaWYgc2VsZi5yZXN0YXJ0X3Bvc2l0aW9uOgogICAgICAgICAgICByZXN0YXJ0X3Bv
c2l0aW9uID0gMAogICAgICAgICAgICBzZWxmLnJlc3BvbmQgKCc1NTMgcmVzdGFydCBvbiBT
VE9SIG5vdCB5ZXQgc3VwcG9ydGVkJykKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAg
IAogICAgICAgICMgWFhYIENoZWNrIGZvciBwb3NzaWJsZSBwcm9ibGVtcyBmaXJzdD8KICAg
ICAgICAjICAgICBSaWdodCBub3cgd2UgYXJlIGxpbWl0ZWQgaW4gdGhlIGVycm9ycyB3ZSBj
YW4gaXNzdWUsIHNpbmNlCiAgICAgICAgIyAgICAgd2UgYWdyZWUgdG8gYWNjZXB0IHRoZSBm
aWxlIGJlZm9yZSBjaGVja2luZyBhdXRob3JpemF0aW9uCiAgICAgICAgCiAgICAgICAgZmQ9
Q29udGVudFJlY2VpdmVyKHNlbGYuc3Rvcl9jYWxsYmFjaywgbGluZVsxXSkKICAgICAgICBz
ZWxmLnJlc3BvbmQgKAogICAgICAgICAgICAnMTUwIE9wZW5pbmcgJXMgY29ubmVjdGlvbiBm
b3IgJXMnICUgKAogICAgICAgICAgICAgICAgc2VsZi50eXBlX21hcFtzZWxmLmN1cnJlbnRf
bW9kZV0sCiAgICAgICAgICAgICAgICBsaW5lWzFdCiAgICAgICAgICAgICAgICApCiAgICAg
ICAgICAgICkKICAgICAgICBzZWxmLm1ha2VfcmVjdl9jaGFubmVsKGZkKQogICAgCiAgICBk
ZWYgc3Rvcl9jYWxsYmFjayhzZWxmLHBhdGgsZGF0YSk6CiAgICAgICAgJ2NhbGxiYWNrIHRv
IGRvIHRoZSBTVE9SLCBhZnRlciB3ZSBoYXZlIHRoZSBpbnB1dCcKICAgICAgICByZXNwb25z
ZT1tYWtlX3Jlc3BvbnNlKHNlbGYsIHNlbGYuc3Rvcl9jb21wbGV0aW9uKQogICAgICAgIHJl
cXVlc3Q9RlRQUmVxdWVzdChwYXRoLCdTVE9SJyxzZWxmLHJlc3BvbnNlLHN0ZGluPWRhdGEp
CiAgICAgICAgaGFuZGxlKHNlbGYubW9kdWxlLHJlcXVlc3QscmVzcG9uc2UpICAgICAgIAog
ICAgICAgICAgIAogICAgZGVmIHN0b3JfY29tcGxldGlvbihzZWxmLHJlc3BvbnNlKToKICAg
ICAgICBzdGF0dXM9cmVzcG9uc2UuZ2V0U3RhdHVzKCkgICAgICAgIAogICAgICAgIGlmIHN0
YXR1cyBpbiAoMjAwLDIwMSwyMDQsMzAyKToKICAgICAgICAgICAgc2VsZi5jbGllbnRfZGMu
Y2hhbm5lbC5yZXNwb25kKCcyMjYgVHJhbnNmZXIgY29tcGxldGUuJykKICAgICAgICBlbGlm
IHN0YXR1cz09NDAxOgogICAgICAgICAgICBzZWxmLmNsaWVudF9kYy5jaGFubmVsLnJlc3Bv
bmQoJzQyNiBVbmF1dGhvcml6ZWQuJykKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxm
LmNsaWVudF9kYy5jaGFubmVsLnJlc3BvbmQoJzQyNiBFcnJvciBjcmVhdGluZyBmaWxlLicp
ICAgICAgIAogICAgICAgIHNlbGYuY2xpZW50X2RjLmNsb3NlKCkKICAgICAgICAKICAgIGRl
ZiBjbWRfcm50byAoc2VsZiwgbGluZSk6CglpZiBsZW4gKGxpbmUpICE9IDI6CgkJc2VsZi5j
b21tYW5kX25vdF91bmRlcnN0b29kIChzdHJpbmcuam9pbiAobGluZSkpCgkJcmV0dXJuCiAg
ICAgICAgcGF0aGYsaWRmPW9zLnBhdGguc3BsaXQoc2VsZi5mcm9tZmlsZSkKICAgICAgICBw
YXRodCxpZHQ9b3MucGF0aC5zcGxpdChsaW5lWzFdKQogICAgICAgIHJlc3BvbnNlPW1ha2Vf
cmVzcG9uc2Uoc2VsZiwgc2VsZi5ybnRvX2NvbXBsZXRpb24pCiAgICAgICAgcmVxdWVzdD1G
VFBSZXF1ZXN0KHBhdGhmLCgnUk5UTycsaWRmLGlkdCksc2VsZixyZXNwb25zZSkKICAgICAg
ICBoYW5kbGUoc2VsZi5tb2R1bGUscmVxdWVzdCxyZXNwb25zZSkgICAgICAgCgogICAgZGVm
IHJudG9fY29tcGxldGlvbihzZWxmLHJlc3BvbnNlKTogICAKICAgICAgICBzdGF0dXM9cmVz
cG9uc2UuZ2V0U3RhdHVzKCkKICAgICAgICBpZiBzdGF0dXM9PTIwMDoKCQlzZWxmLnJlc3Bv
bmQgKCcyNTAgUk5UTyBjb21tYW5kIHN1Y2Nlc3NmdWwuJykKCWVsc2U6CgkJc2VsZi5yZXNw
b25kICgnNTUwIGVycm9yIHJlbmFtaW5nIGZpbGUuJykKCQkKICAgIGRlZiBjbWRfZGVsZShz
ZWxmLCBsaW5lKToKICAgICAgICBpZiBsZW4gKGxpbmUpICE9IDI6CiAgICAgICAgICAgIHNl
bGYuY29tbWFuZC5ub3RfdW5kZXJzdG9vZCAoc3RyaW5nLmpvaW4gKGxpbmUpKQogICAgICAg
ICAgICByZXR1cm4KICAgICAgICBwYXRoLGlkPW9zLnBhdGguc3BsaXQobGluZVsxXSkKICAg
ICAgICByZXNwb25zZT1tYWtlX3Jlc3BvbnNlKHNlbGYsIHNlbGYuZGVsZV9jb21wbGV0aW9u
KQogICAgICAgIHJlcXVlc3Q9RlRQUmVxdWVzdChwYXRoLCgnREVMRScsaWQpLHNlbGYscmVz
cG9uc2UpCiAgICAgICAgaGFuZGxlKHNlbGYubW9kdWxlLHJlcXVlc3QscmVzcG9uc2UpICAg
ICAgIAogICAgICAgIAogICAgZGVmIGRlbGVfY29tcGxldGlvbihzZWxmLHJlc3BvbnNlKTog
ICAKICAgICAgICBzdGF0dXM9cmVzcG9uc2UuZ2V0U3RhdHVzKCkKICAgICAgICBpZiBzdGF0
dXM9PTIwMCBhbmQgc3RyaW5nLmZpbmQocmVzcG9uc2UuYm9keSwnTm90IERlbGV0YWJsZScp
PT0tMToKICAgICAgICAgICAgc2VsZi5yZXNwb25kKCcyNTAgREVMRSBjb21tYW5kIHN1Y2Nl
c3NmdWwuJykKICAgICAgICBlbGlmIHN0YXR1cz09NDAxOgogICAgICAgICAgICBzZWxmLnJl
c3BvbmQoJzUzMCBVbmF1dGhvcml6ZWQuJykgCiAgICAgICAgZWxzZToKICAgICAgICAgICAg
c2VsZi5yZXNwb25kKCc1NTAgRXJyb3IgZGVsZXRpbmcgZmlsZS4nKSAgICAgICAKCiAgICBk
ZWYgY21kX21rZChzZWxmLCBsaW5lKToKICAgICAgICBpZiBsZW4gKGxpbmUpICE9IDI6CiAg
ICAgICAgICAgIHNlbGYuY29tbWFuZC5ub3RfdW5kZXJzdG9vZCAoc3RyaW5nLmpvaW4gKGxp
bmUpKQogICAgICAgICAgICByZXR1cm4KICAgICAgICBwYXRoLGlkPW9zLnBhdGguc3BsaXQo
bGluZVsxXSkKICAgICAgICByZXNwb25zZT1tYWtlX3Jlc3BvbnNlKHNlbGYsIHNlbGYubWtk
X2NvbXBsZXRpb24pCiAgICAgICAgcmVxdWVzdD1GVFBSZXF1ZXN0KHBhdGgsKCdNS0QnLGlk
KSxzZWxmLHJlc3BvbnNlKQogICAgICAgIGhhbmRsZShzZWxmLm1vZHVsZSxyZXF1ZXN0LHJl
c3BvbnNlKSAgICAgICAKICAgIAogICAgY21kX3hta2Q9Y21kX21rZAogICAgCiAgICBkZWYg
bWtkX2NvbXBsZXRpb24oc2VsZixyZXNwb25zZSk6CiAgICAgICAgc3RhdHVzPXJlc3BvbnNl
LmdldFN0YXR1cygpCiAgICAgICAgaWYgc3RhdHVzPT0yMDA6CiAgICAgICAgICAgIHNlbGYu
cmVzcG9uZCgnMjU3IE1LRCBjb21tYW5kIHN1Y2Nlc3NmdWwuJykKICAgICAgICBlbGlmIHN0
YXR1cz09NDAxOgogICAgICAgICAgICBzZWxmLnJlc3BvbmQoJzUzMCBVbmF1dGhvcml6ZWQu
JykKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnJlc3BvbmQoJzU1MCBFcnJvciBj
cmVhdGluZyBkaXJlY3RvcnkuJykKCiAgICBkZWYgY21kX3JtZChzZWxmLCBsaW5lKToKICAg
ICAgICAjIFhYWCBzaG91bGQgb2JqZWN0IGJlIGNoZWNrZWQgdG8gc2VlIGlmIGl0J3MgZm9s
ZGVyaXNoCiAgICAgICAgIyAgICAgYmVmb3JlIHdlIGFsbG93IGl0IHRvIGJlIFJNRCdkPwog
ICAgICAgIGlmIGxlbiAobGluZSkgIT0gMjoKICAgICAgICAgICAgc2VsZi5jb21tYW5kLm5v
dF91bmRlcnN0b29kIChzdHJpbmcuam9pbiAobGluZSkpCiAgICAgICAgICAgIHJldHVybgog
ICAgICAgIHBhdGgsaWQ9b3MucGF0aC5zcGxpdChsaW5lWzFdKQogICAgICAgIHJlc3BvbnNl
PW1ha2VfcmVzcG9uc2Uoc2VsZiwgc2VsZi5ybWRfY29tcGxldGlvbikKICAgICAgICByZXF1
ZXN0PUZUUFJlcXVlc3QocGF0aCwoJ1JNRCcsaWQpLHNlbGYscmVzcG9uc2UpCiAgICAgICAg
aGFuZGxlKHNlbGYubW9kdWxlLHJlcXVlc3QscmVzcG9uc2UpICAgICAgIAogICAgICAgIAog
ICAgY21kX3hybWQ9Y21kX3JtZAoKICAgIGRlZiBybWRfY29tcGxldGlvbihzZWxmLHJlc3Bv
bnNlKToKICAgICAgICBzdGF0dXM9cmVzcG9uc2UuZ2V0U3RhdHVzKCkKICAgICAgICBpZiBz
dGF0dXM9PTIwMCBhbmQgc3RyaW5nLmZpbmQocmVzcG9uc2UuYm9keSwnTm90IERlbGV0YWJs
ZScpPT0tMToKICAgICAgICAgICAgc2VsZi5yZXNwb25kKCcyNTAgUk1EIGNvbW1hbmQgc3Vj
Y2Vzc2Z1bC4nKQogICAgICAgIGVsaWYgc3RhdHVzPT00MDE6CiAgICAgICAgICAgIHNlbGYu
cmVzcG9uZCgnNTMwIFVuYXV0aG9yaXplZC4nKSAKICAgICAgICBlbHNlOgogICAgICAgICAg
ICBzZWxmLnJlc3BvbmQoJzU1MCBFcnJvciByZW1vdmluZyBkaXJlY3RvcnkuJykgICAgICAg
ICAgCgogICAgZGVmIGNtZF91c2VyKHNlbGYsIGxpbmUpOgogICAgICAgICdzcGVjaWZ5IHVz
ZXIgbmFtZScKICAgICAgICBpZiBsZW4obGluZSkgPiAxOgogICAgICAgICAgICBzZWxmLnVz
ZXJpZCA9IGxpbmVbMV0KICAgICAgICAgICAgc2VsZi5yZXNwb25kKCczMzEgUGFzc3dvcmQg
cmVxdWlyZWQuJykKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLmNvbW1hbmRfbm90
X3VuZGVyc3Rvb2QgKHN0cmluZy5qb2luIChsaW5lKSkKCiAgICBkZWYgY21kX3Bhc3Moc2Vs
ZiwgbGluZSk6CiAgICAgICAgJ3NwZWNpZnkgcGFzc3dvcmQnCiAgICAgICAgaWYgbGVuKGxp
bmUpIDwgMjoKICAgICAgICAgICAgcHcgPSAnJwogICAgICAgIGVsc2U6CiAgICAgICAgICAg
IHB3ID0gbGluZVsxXQogICAgICAgIHNlbGYucGFzc3dvcmQ9cHcKICAgICAgICBpPXN0cmlu
Zy5maW5kKHNlbGYudXNlcmlkLCdAJykKICAgICAgICBpZiBpID09LTE6CiAgICAgICAgICAg
IGlmIHNlbGYuc2VydmVyLmxpbWl0ZXIuY2hlY2tfbGltaXQoc2VsZik6CiAgICAgICAgICAg
ICAgICBzZWxmLnJlc3BvbmQgKCcyMzAgTG9naW4gc3VjY2Vzc2Z1bC4nKQogICAgICAgICAg
ICAgICAgc2VsZi5hdXRob3JpemVkID0gMQogICAgICAgICAgICAgICAgc2VsZi5hbm9ueW1v
dXMgPSAxCiAgICAgICAgICAgICAgICBzZWxmLmxvZ19pbmZvICgnU3VjY2Vzc2Z1bCBsb2dp
bi4nKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5yZXNwb25kKCc0
MjEgVXNlciBsaW1pdCByZWFjaGVkLiBDbG9zaW5nIGNvbm5lY3Rpb24uJykKICAgICAgICAg
ICAgICAgIHNlbGYuY2xvc2Vfd2hlbl9kb25lKCkKICAgICAgICBlbHNlOiAgIAogICAgICAg
ICAgICBwYXRoPXNlbGYudXNlcmlkW2krMTpdCiAgICAgICAgICAgIHNlbGYudXNlcmlkPXNl
bGYudXNlcmlkWzppXQogICAgICAgICAgICBzZWxmLmFub255bW91cz1Ob25lCiAgICAgICAg
ICAgIHJlc3BvbnNlPW1ha2VfcmVzcG9uc2Uoc2VsZiwgc2VsZi5wYXNzX2NvbXBsZXRpb24s
CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fam9pbl9wYXRocygnLycscGF0aCkpCiAgICAg
ICAgICAgIHJlcXVlc3Q9RlRQUmVxdWVzdChwYXRoLCdQQVNTJyxzZWxmLHJlc3BvbnNlKQog
ICAgICAgICAgICBoYW5kbGUoc2VsZi5tb2R1bGUscmVxdWVzdCxyZXNwb25zZSkgCgoKICAg
IGRlZiBwYXNzX2NvbXBsZXRpb24oc2VsZixwYXRoLHJlc3BvbnNlKToKICAgICAgICBzdGF0
dXM9cmVzcG9uc2UuZ2V0U3RhdHVzKCkKICAgICAgICBpZiBzdGF0dXM9PTIwMDoKICAgICAg
ICAgICAgaWYgbm90IHNlbGYuc2VydmVyLmxpbWl0ZXIuY2hlY2tfbGltaXQoc2VsZik6CiAg
ICAgICAgICAgICAgICBzZWxmLmNsb3NlX3doZW5fZG9uZSgpCiAgICAgICAgICAgICAgICBz
ZWxmLnJlc3BvbmQoJzQyMSBVc2VyIGxpbWl0IHJlYWNoZWQuIENsb3NpbmcgY29ubmVjdGlv
bi4nKSAgICAKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBsaXN0aW5nPXJl
c3BvbnNlLl9tYXJzaGFsbGVkQm9keSgpCiAgICAgICAgICAgICMgY2hlY2sgdG8gc2VlIGlm
IHdlIGFyZSBjZGluZyB0byBhIG5vbi1mb2xkb2lkIG9iamVjdAogICAgICAgICAgICBpZiB0
eXBlKGxpc3RpbmdbMF0pPT10eXBlKCcnKToKICAgICAgICAgICAgICAgIHNlbGYucmVzcG9u
ZCgnNTMwIFVuYXV0aG9yaXplZC4nKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAg
ICAgIHNlbGYucGF0aD1wYXRoIG9yICcvJwogICAgICAgICAgICBzZWxmLmF1dGhvcml6ZWQg
PSAxCiAgICAgICAgICAgIGlmIHNlbGYudXNlcmlkPT0nYW5vbnltb3VzJzoKICAgICAgICAg
ICAgICAgIHNlbGYuYW5vbnltb3VzPTEKICAgICAgICAgICAgc2VsZi5sb2dfaW5mbygnU3Vj
Y2Vzc2Z1bCBsb2dpbi4nKSAgICAgICAgICAgCiAgICAgICAgICAgIHNlbGYucmVzcG9uZCgn
MjMwIExvZ2luIHN1Y2Nlc3NmdWwuJykKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxm
LnJlc3BvbmQoJzUzMCBVbmF1dGhvcml6ZWQuJykKICAgICAgICAKICAgIGRlZiBjbWRfYXBw
ZShzZWxmLCBsaW5lKToKICAgICAgICBzZWxmLnJlc3BvbmQoJzUwMiBDb21tYW5kIG5vdCBp
bXBsZW1lbnRlZC4nKQoKCiMgT3ZlcnJpZGUgZnRwIHNlcnZlciByZWNlaXZlIGNoYW5uZWwg
cmVwb25zZSBtZWNoYW5pc20gCiMgWFhYIGhhY2sgYWxlcnQsIHRoaXMgc2hvdWxkIHByb2Jh
Ymx5IGJlIHJlZG9uZSBpbiBhIG1vcmUgT08gd2F5LgoKZGVmIGhhbmRsZV9jbG9zZSAoc2Vs
Zik6CiAgICAiIiJyZXNwb25zZSBhbmQgY2xvc3VyZSBvZiBjaGFubmVsIGlzIGRlbGF5ZWQu
IiIiCiAgICBzID0gc2VsZi5jaGFubmVsLnNlcnZlcgogICAgcy50b3RhbF9maWxlc19pbi5p
bmNyZW1lbnQoKQogICAgcy50b3RhbF9ieXRlc19pbi5pbmNyZW1lbnQoc2VsZi5ieXRlc19p
bi5hc19sb25nKCkpCiAgICBzZWxmLmZkLmNsb3NlKCkKICAgIHNlbGYucmVhZGFibGU9bGFt
YmRhIDowICMgZG9uJ3QgY2FsbCBjbG9zZSBhZ2FpbgoKcmVjdl9jaGFubmVsLmhhbmRsZV9j
bG9zZT1oYW5kbGVfY2xvc2UKCiAgCmNsYXNzIENvbnRlbnRSZWNlaXZlcjoKICAgICJXcml0
ZS1vbmx5IGZpbGUgb2JqZWN0IHVzZWQgdG8gcmVjZWl2ZSBkYXRhIGZyb20gRlRQIgogICAg
CiAgICBkZWYgX19pbml0X18oc2VsZixjYWxsYmFjaywqYXJncyk6CiAgICAgICAgc2VsZi5k
YXRhPVN0cmluZ0lPKCkKICAgICAgICBzZWxmLmNhbGxiYWNrPWNhbGxiYWNrCiAgICAgICAg
c2VsZi5hcmdzPWFyZ3MKICAgICAgICAKICAgIGRlZiB3cml0ZShzZWxmLGRhdGEpOgogICAg
ICAgIHNlbGYuZGF0YS53cml0ZShkYXRhKQogICAgCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAg
ICAgICAgc2VsZi5kYXRhLnNlZWsoMCkKICAgICAgICBhcmdzPXNlbGYuYXJncysoc2VsZi5k
YXRhLCkKICAgICAgICBjPXNlbGYuY2FsbGJhY2sKICAgICAgICBzZWxmLmNhbGxiYWNrPU5v
bmUKICAgICAgICBzZWxmLmFyZ3M9Tm9uZQogICAgICAgIGFwcGx5KGMsYXJncykKCgpjbGFz
cyBGVFBMaW1pdGVyOgogICAgIiIiUnVkaW1lbnRhcnkgRlRQIGxpbWl0cy4gSGVscHMgcHJl
dmVudCBkZW5pYWwgb2Ygc2VydmljZQogICAgYXR0YWNrcy4gSXQgd29ya3MgYnkgbGltaXRp
bmcgdGhlIG51bWJlciBvZiBzaW11bHRhbmVvdXMKICAgIGNvbm5lY3Rpb25zIGJ5IHVzZXJp
ZC4gVGhlcmUgYXJlIHRocmVlIGxpbWl0cywgb25lIGZvciBhbm9ueW1vdXMKICAgIGNvbm5l
Y3Rpb25zLCBhbmQgb25lIGZvciBhdXRoZW50aWNhdGVkIGxvZ2lucy4gVGhlIHRvdGFsIG51
bWJlcgogICAgb2Ygc2ltdWx0YW5lb3VzIGFub255bW91cyBsb2dpbnMgbXkgYmUgbGVzcyB0
aGFuIG9yIGVxdWFsIHRvIHRoZQogICAgYW5vbnltb3VzIGxpbWl0LiBFYWNoIGF1dGhlbnRp
Y2F0ZWQgdXNlciBjYW4gaGF2ZSB1cCB0byB0aGUgdXNlcgogICAgbGltaXQgbnVtYmVyIG9m
IHNpbXVsdGFuZW91cyBjb25uZWN0aW9ucy4gVGhlIHRvdGFsIGxpbWl0IGlzIHRoZQogICAg
bWF4aW11bSBudW1iZXIgb2Ygc2ltdWx0YW5lb3VzIGNvbm5lY3Rpb25zIG9mIGFueSBzb3J0
LiBEbyAqbm90KgogICAgc2V0IHRoZSB0b3RhbCBsaW1pdCBsb3dlciB0aGFuIG9yIGVxdWFs
IHRvIHRoZSBhbm9ueW1vdXMgbGltaXQuIiIiCiAgICAKICAgIGRlZiBfX2luaXRfXyhzZWxm
LGFub25fbGltaXQ9MTAsdXNlcl9saW1pdD00LHRvdGFsX2xpbWl0PTI1KToKICAgICAgICBz
ZWxmLmFub25fbGltaXQ9YW5vbl9saW1pdAogICAgICAgIHNlbGYudXNlcl9saW1pdD11c2Vy
X2xpbWl0CiAgICAgICAgc2VsZi50b3RhbF9saW1pdD10b3RhbF9saW1pdAogICAgCiAgICBk
ZWYgY2hlY2tfbGltaXQoc2VsZixjaGFubmVsKToKICAgICAgICAiIiJDaGVjayB0byBzZWUg
aWYgdGhlIHVzZXIgaGFzIGV4aGF1c3RlZCB0aGVpciBsaW1pdCBvciBub3QuCiAgICAgICAg
Q2hlY2sgZm9yIGV4aXN0aW5nIGNoYW5uZWxzIHdpdGggdGhlIHNhbWUgdXNlcmlkIGFuZCB0
aGUgc2FtZQogICAgICAgIGZ0cCBzZXJ2ZXIuIiIiCiAgICAgICAgdG90YWw9MAogICAgICAg
IGNsYXNzX3RvdGFsPTAKICAgICAgICBpZiBjaGFubmVsLmFub255bW91czoKICAgICAgICAg
ICAgZm9yIGV4aXN0aW5nX2NoYW5uZWwgaW4gYXN5bmNvcmUuc29ja2V0X21hcC52YWx1ZXMo
KToKICAgICAgICAgICAgICAgIGlmIChoYXNhdHRyKGV4aXN0aW5nX2NoYW5uZWwsJ3NlcnZl
cicpIGFuZAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ19jaGFubmVsLnNlcnZl
ciBpcyBjaGFubmVsLnNlcnZlcik6CiAgICAgICAgICAgICAgICAgICAgdG90YWw9dG90YWwr
MQogICAgICAgICAgICAgICAgICAgIGlmIGV4aXN0aW5nX2NoYW5uZWwuYW5vbnltb3VzOgog
ICAgICAgICAgICAgICAgICAgICAgICBjbGFzc190b3RhbD1jbGFzc190b3RhbCsxCiAgICAg
ICAgICAgIGlmIGNsYXNzX3RvdGFsID4gc2VsZi5hbm9uX2xpbWl0OgogICAgICAgICAgICAg
ICAgcmV0dXJuIE5vbmUKICAgICAgICBlbHNlOiAgICAgICAgICAgICAgICAKICAgICAgICAg
ICAgZm9yIGV4aXN0aW5nX2NoYW5uZWwgaW4gYXN5bmNvcmUuc29ja2V0X21hcC52YWx1ZXMo
KToKICAgICAgICAgICAgICAgIGlmIChoYXNhdHRyKGV4aXN0aW5nX2NoYW5uZWwsJ3NlcnZl
cicpIGFuZAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ19jaGFubmVsLnNlcnZl
ciBpcyBjaGFubmVsLnNlcnZlcik6CiAgICAgICAgICAgICAgICAgICAgdG90YWw9dG90YWwr
MQogICAgICAgICAgICAgICAgICAgIGlmIGNoYW5uZWwudXNlcmlkPT1leGlzdGluZ19jaGFu
bmVsLnVzZXJpZDoKICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NfdG90YWw9Y2xhc3Nf
dG90YWwrMQogICAgICAgICAgICBpZiBjbGFzc190b3RhbCA+IHNlbGYudXNlcl9saW1pdDoK
ICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgaWYgdG90YWwgPD0gc2VsZi50
b3RhbF9saW1pdDoKICAgICAgICAgICAgcmV0dXJuIDEKCiAgICAgICAgCmNsYXNzIEZUUFNl
cnZlcihmdHBfc2VydmVyKToKICAgICIiIkZUUCBzZXJ2ZXIgZm9yIFpvcGUuIiIiCiAgICAK
ICAgIGZ0cF9jaGFubmVsX2NsYXNzID0gem9wZV9mdHBfY2hhbm5lbAogICAgbGltaXRlcj1G
VFBMaW1pdGVyKDEwLDEpCiAgICBzaHV0dXA9MAoKICAgIGRlZiBfX2luaXRfXyhzZWxmLG1v
ZHVsZSwqYXJncywqKmt3KToKICAgICAgICBzZWxmLnNodXR1cD0xCiAgICAgICAgYXBwbHko
ZnRwX3NlcnZlci5fX2luaXRfXywgKHNlbGYsIE5vbmUpICsgYXJncywga3cpCiAgICAgICAg
c2VsZi5zaHV0dXA9MAogICAgICAgIHNlbGYubW9kdWxlPW1vZHVsZQogICAgICAgIHNlbGYu
bG9nX2luZm8oJ0ZUUCBzZXJ2ZXIgc3RhcnRlZCBhdCAlc1xuJwogICAgICAgICAgICAgICAg
ICAgICAgJ1x0SG9zdG5hbWU6ICVzXG5cdFBvcnQ6ICVkJyAlICgKCQkJdGltZS5jdGltZSh0
aW1lLnRpbWUoKSksCgkJCXNlbGYuaG9zdG5hbWUsCgkJCXNlbGYucG9ydAoJCQkpKQoKICAg
IGRlZiBsb2dfaW5mbyhzZWxmLCBtZXNzYWdlLCB0eXBlPSdpbmZvJyk6CiAgICAgICAgaWYg
c2VsZi5zaHV0dXA6IHJldHVybgogICAgICAgIGFzeW5jb3JlLmRpc3BhdGNoZXIubG9nX2lu
Zm8oc2VsZiwgbWVzc2FnZSwgdHlwZSkKICAgICAgICAKICAgIGRlZiBoYW5kbGVfYWNjZXB0
IChzZWxmKToKICAgICAgICBjb25uLCBhZGRyID0gc2VsZi5hY2NlcHQoKQogICAgICAgIHNl
bGYudG90YWxfc2Vzc2lvbnMuaW5jcmVtZW50KCkKICAgICAgICBzZWxmLmxvZ19pbmZvKCdJ
bmNvbWluZyBjb25uZWN0aW9uIGZyb20gJXM6JWQnICUgKGFkZHJbMF0sIGFkZHJbMV0pKQog
ICAgICAgIHNlbGYuZnRwX2NoYW5uZWxfY2xhc3MgKHNlbGYsIGNvbm4sIGFkZHIsIHNlbGYu
bW9kdWxlKSAgCgogICAgZGVmIHJlYWRhYmxlKHNlbGYpOgogICAgICAgIHJldHVybiBsZW4o
YXN5bmNvcmUuc29ja2V0X21hcCkgPCBDT05ORUNUSU9OX0xJTUlUCgogICAgZGVmIGxpc3Rl
bihzZWxmLCBudW0pOgogICAgICAgICMgb3ZlcnJpZGUgYXN5bmNvcmUgbGltaXRzIGZvciBu
dCdzIGxpc3RlbiBxdWV1ZSBzaXplCiAgICAgICAgc2VsZi5hY2NlcHRpbmcgPSAxCiAgICAg
ICAgcmV0dXJuIHNlbGYuc29ja2V0Lmxpc3RlbiAobnVtKQo=
--------------CF3F10DD56A7538D09BE4E14
Content-Type: application/octet-stream;
 name="ftp_server.py"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="ftp_server.py"

IyAtKi0gTW9kZTogUHl0aG9uOyB0YWItd2lkdGg6IDQgLSotCgojCUF1dGhvcjogU2FtIFJ1
c2hpbmcgPHJ1c2hpbmdAbmlnaHRtYXJlLmNvbT4KIwlDb3B5cmlnaHQgMTk5Ni0yMDAwIGJ5
IFNhbSBSdXNoaW5nCiMJCQkJCQkgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KIwoKIwlSZW5hbWUg
Y2FwYWJpbGl0eSBhZGRlZCwgZC5kLiAyMDAxMDEyMCBieSB0b20udmlqbGJyaWVmQGlzaW9u
Lm5sCiMKClJDU19JRCA9ICAnJElkOiBmdHBfc2VydmVyLnB5LHYgMS4xMi40LjEgMjAwMC8w
Ny8wNSAxNDoyMTo0NCBicmlhbiBFeHAgJCcKCiMgQW4gZXh0ZW5zaWJsZSwgY29uZmlndXJh
YmxlLCBhc3luY2hyb25vdXMgRlRQIHNlcnZlci4KIyAKIyBBbGwgc29ja2V0IEkvTyBpcyBu
b24tYmxvY2tpbmcsIGhvd2V2ZXIgZmlsZSBJL08gaXMgY3VycmVudGx5CiMgYmxvY2tpbmcu
ICBFdmVudHVhbGx5IGZpbGUgSS9PIG1heSBiZSBtYWRlIG5vbi1ibG9ja2luZywgdG9vLCBp
ZiBpdAojIHNlZW1zIG5lY2Vzc2FyeS4gIEN1cnJlbnRseSB0aGUgb25seSBDUFUtaW50ZW5z
aXZlIG9wZXJhdGlvbiBpcwojIGdldHRpbmcgYW5kIGZvcm1hdHRpbmcgYSBkaXJlY3Rvcnkg
bGlzdGluZy4gIFt0aGlzIGNvdWxkIGJlIG1vdmVkCiMgaW50byBhbm90aGVyIHByb2Nlc3Mv
ZGlyZWN0b3J5IHNlcnZlciwgb3IgYW5vdGhlciB0aHJlYWQ/XQojCiMgT25seSBhIHN1YnNl
dCBvZiBSRkMgOTU5IGlzIGltcGxlbWVudGVkLCBidXQgbXVjaCBvZiB0aGF0IFJGQyBpcwoj
IHZlc3RpZ2lhbCBhbnl3YXkuICBJJ3ZlIGF0dGVtcHRlZCB0byBpbmNsdWRlIHRoZSBtb3N0
IGNvbW1vbmx5LXVzZWQKIyBjb21tYW5kcywgdXNpbmcgdGhlIGZlYXR1cmUgc2V0IG9mIHd1
LWZ0cGQgYXMgYSBndWlkZS4KCmltcG9ydCBhc3luY29yZQppbXBvcnQgYXN5bmNoYXQKCmlt
cG9ydCBvcwppbXBvcnQgcmVnc3ViCmltcG9ydCBzb2NrZXQKaW1wb3J0IHN0YXQKaW1wb3J0
IHN0cmluZwppbXBvcnQgc3lzCmltcG9ydCB0aW1lCgojIFRPRE86IGltcGxlbWVudCBhIGRp
cmVjdG9yeSBsaXN0aW5nIGNhY2hlLiAgT24gdmVyeS1oaWdoLWxvYWQKIyBzZXJ2ZXJzIHRo
aXMgY291bGQgc2F2ZSBhIGxvdCBvZiBkaXNrIGFidXNlLCBhbmQgcG9zc2libHkgdGhlCiMg
d29yayBvZiBjb21wdXRpbmcgZW11bGF0ZWQgdW5peCBscyBvdXRwdXQuCgojIFBvdGVudGlh
bCBzZWN1cml0eSBwcm9ibGVtIHdpdGggdGhlIEZUUCBwcm90b2NvbD8gIEkgZG9uJ3QgdGhp
bmsKIyB0aGVyZSdzIGFueSB2ZXJpZmljYXRpb24gb2YgdGhlIG9yaWdpbiBvZiBhIGRhdGEg
Y29ubmVjdGlvbi4gIE5vdAojIHJlYWxseSBhIHByb2JsZW0gZm9yIHRoZSBzZXJ2ZXIgKHNp
bmNlIGl0IGRvZXNuJ3Qgc2VuZCB0aGUgcG9ydAojIGNvbW1hbmQsIGV4Y2VwdCB3aGVuIGlu
IFBBU1YgbW9kZSkgQnV0IEkgdGhpbmsgYSBkYXRhIGNvbm5lY3Rpb24KIyBjb3VsZCBiZSBz
cG9vZmVkIGJ5IGEgcHJvZ3JhbSB3aXRoIGFjY2VzcyB0byBhIHNuaWZmZXIgLSBpdCBjb3Vs
ZAojIHdhdGNoIGZvciBhIFBPUlQgY29tbWFuZCB0byBnbyBvdmVyIGEgY29tbWFuZCBjaGFu
bmVsLCBhbmQgdGhlbgojIGNvbm5lY3QgdG8gdGhhdCBwb3J0IGJlZm9yZSB0aGUgc2VydmVy
IGRvZXMuCgojIFVuaXggdXNlciBpZCdzOgojIEluIG9yZGVyIHRvIHN1cHBvcnQgYXNzdW1p
bmcgdGhlIGlkIG9mIGEgcGFydGljdWxhciB1c2VyLAojIGl0IHNlZW1zIHRoZXJlIGFyZSB0
d28gb3B0aW9uczoKIyAxKSBmb3JrLCBhbmQgc2V0ZXVpZCBpbiB0aGUgY2hpbGQKIyAyKSBj
YXJlZnVsbHkgY29udHJvbCB0aGUgZWZmZWN0aXZlIHVpZCBhcm91bmQgZmlsZXN5c3RlbSBh
Y2Nlc3NpbmcKIyAgICBtZXRob2RzLCB1c2luZyB0cnkvZmluYWxseS4gW3RoaXMgc2VlbXMg
dG8gd29ya10KClZFUlNJT04gPSBzdHJpbmcuc3BsaXQoUkNTX0lEKVsyXQoKZnJvbSBjb3Vu
dGVyIGltcG9ydCBjb3VudGVyCmltcG9ydCBwcm9kdWNlcnMKaW1wb3J0IHN0YXR1c19oYW5k
bGVyCmltcG9ydCBsb2dnZXIKaW1wb3J0IHN0cmluZwoKY2xhc3MgZnRwX2NoYW5uZWwgKGFz
eW5jaGF0LmFzeW5jX2NoYXQpOgoKCSMgZGVmYXVsdHMgZm9yIGEgcmVsaWFibGUgX19yZXBy
X18KCWFkZHIgPSAoJ3Vua25vd24nLCcwJykKCgkjIHVuc2V0IHRoaXMgaW4gYSBkZXJpdmVk
IGNsYXNzIGluIG9yZGVyCgkjIHRvIGVuYWJsZSB0aGUgY29tbWFuZHMgaW4gJ3NlbGYud3Jp
dGVfY29tbWFuZHMnCglyZWFkX29ubHkgPSAxCgl3cml0ZV9jb21tYW5kcyA9IFsnYXBwZScs
J2RlbGUnLCdta2QnLCdybWQnLCdybmZyJywncm50bycsJ3N0b3InLCdzdG91J10KCglyZXN0
YXJ0X3Bvc2l0aW9uID0gMAoKCSMgY29tcGx5IHdpdGggKHBvc3NpYmx5IHRyb3VibGVzb21l
KSBSRkM5NTkgcmVxdWlyZW1lbnRzCgkjIFRoaXMgaXMgbmVjZXNzYXJ5IHRvIGNvcnJlY3Rs
eSBydW4gYW4gYWN0aXZlIGRhdGEgY29ubmVjdGlvbgoJIyB0aHJvdWdoIGEgZmlyZXdhbGwg
dGhhdCB0cmlnZ2VycyBvbiB0aGUgc291cmNlIHBvcnQgKGV4cGVjdGVkCgkjIHRvIGJlICdM
LTEnLCBvciAyMCBpbiB0aGUgbm9ybWFsIGNhc2UpLgoJYmluZF9sb2NhbF9taW51c19vbmUg
PSAwCgoJZGVmIF9faW5pdF9fIChzZWxmLCBzZXJ2ZXIsIGNvbm4sIGFkZHIpOgoJCXNlbGYu
c2VydmVyID0gc2VydmVyCgkJc2VsZi5jdXJyZW50X21vZGUgPSAnYScKCQlzZWxmLmFkZHIg
PSBhZGRyCgkJYXN5bmNoYXQuYXN5bmNfY2hhdC5fX2luaXRfXyAoc2VsZiwgY29ubikKCQlz
ZWxmLnNldF90ZXJtaW5hdG9yICgnXHJcbicpCgoJCSMgY2xpZW50IGRhdGEgcG9ydC4gIERl
ZmF1bHRzIHRvICd0aGUgc2FtZSBhcyB0aGUgY29udHJvbCBjb25uZWN0aW9uJy4KCQlzZWxm
LmNsaWVudF9hZGRyID0gKGFkZHJbMF0sIDIxKQoKCQlzZWxmLmNsaWVudF9kYyA9IE5vbmUK
CQlzZWxmLmluX2J1ZmZlciA9ICcnCgkJc2VsZi5jbG9zaW5nID0gMAoJCXNlbGYucGFzc2l2
ZV9hY2NlcHRvciA9IE5vbmUKCQlzZWxmLnBhc3NpdmVfY29ubmVjdGlvbiA9IE5vbmUKCQlz
ZWxmLmZpbGVzeXN0ZW0gPSBOb25lCgkJc2VsZi5hdXRob3JpemVkID0gMAoJCSMgc2VuZCB0
aGUgZ3JlZXRpbmcKCQlzZWxmLnJlc3BvbmQgKAoJCQknMjIwICVzIEZUUCBzZXJ2ZXIgKE1l
ZHVzYSBBc3luYyBWJXMgW2V4cGVyaW1lbnRhbF0pIHJlYWR5LicgJSAoCgkJCQlzZWxmLnNl
cnZlci5ob3N0bmFtZSwKCQkJCVZFUlNJT04KCQkJCSkKCQkJKQoKIwlkZWYgX19kZWxfXyAo
c2VsZik6CiMJCXByaW50ICdmdHBfY2hhbm5lbC5fX2RlbF9fKCknCgoJIyAtLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJIyBhc3luYy1saWJy
YXJ5IG1ldGhvZHMKCSMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0KCglkZWYgaGFuZGxlX2V4cHQgKHNlbGYpOgoJCSMgdGhpcyBpcyBoYW5k
bGVkIGJlbG93LiAgbm90IHN1cmUgd2hhdCBJIGNvdWxkCgkJIyBkbyBoZXJlIHRvIG1ha2Ug
dGhhdCBjb2RlIGxlc3Mga2x1ZGdpc2guCgkJcGFzcwoKCWRlZiBjb2xsZWN0X2luY29taW5n
X2RhdGEgKHNlbGYsIGRhdGEpOgoJCXNlbGYuaW5fYnVmZmVyID0gc2VsZi5pbl9idWZmZXIg
KyBkYXRhCgkJaWYgbGVuKHNlbGYuaW5fYnVmZmVyKSA+IDQwOTY6CgkJCSMgc2lsZW50bHkg
dHJ1bmNhdGUgcmVhbGx5IGxvbmcgbGluZXMKCQkJIyAocG9zc2libGUgZGVuaWFsLW9mLXNl
cnZpY2UgYXR0YWNrKQoJCQlzZWxmLmluX2J1ZmZlciA9ICcnCgoJZGVmIGZvdW5kX3Rlcm1p
bmF0b3IgKHNlbGYpOgoKCQlsaW5lID0gc2VsZi5pbl9idWZmZXIKCgkJaWYgbm90IGxlbihs
aW5lKToKCQkJcmV0dXJuCgoJCXNwID0gc3RyaW5nLmZpbmQgKGxpbmUsICcgJykKCQlpZiBz
cCAhPSAtMToKCQkJbGluZSA9IFtsaW5lWzpzcF0sIGxpbmVbc3ArMTpdXQoJCWVsc2U6CgkJ
CWxpbmUgPSBbbGluZV0KCgkJY29tbWFuZCA9IHN0cmluZy5sb3dlciAobGluZVswXSkKCQkj
IHdhdGNoIGVzcGVjaWFsbHkgZm9yICd1cmdlbnQnIGFib3J0IGNvbW1hbmRzLgoJCWlmIHN0
cmluZy5maW5kIChjb21tYW5kLCAnYWJvcicpICE9IC0xOgoJCQkjIHN0cmlwIG9mZiB0ZWxu
ZXQgc3luYyBjaGFycyBhbmQgdGhlIGxpa2UuLi4KCQkJd2hpbGUgY29tbWFuZCBhbmQgY29t
bWFuZFswXSBub3QgaW4gc3RyaW5nLmxldHRlcnM6CgkJCQljb21tYW5kID0gY29tbWFuZFsx
Ol0KCQlmdW5fbmFtZSA9ICdjbWRfJXMnICUgY29tbWFuZAoJCWlmIGNvbW1hbmQgIT0gJ3Bh
c3MnOgoJCQlzZWxmLmxvZyAoJzw9PSAlcycgJSByZXByKHNlbGYuaW5fYnVmZmVyKVsxOi0x
XSkKCQllbHNlOgoJCQlzZWxmLmxvZyAoJzw9PSAlcycgJSBsaW5lWzBdKycgPHBhc3N3b3Jk
PicpCgkJc2VsZi5pbl9idWZmZXIgPSAnJwoJCWlmIG5vdCBoYXNhdHRyIChzZWxmLCBmdW5f
bmFtZSk6CgkJCXNlbGYuY29tbWFuZF9ub3RfdW5kZXJzdG9vZCAobGluZVswXSkKCQkJcmV0
dXJuCgkJZnVuID0gZ2V0YXR0ciAoc2VsZiwgZnVuX25hbWUpCgkJaWYgKG5vdCBzZWxmLmF1
dGhvcml6ZWQpIGFuZCAoY29tbWFuZCBub3QgaW4gKCd1c2VyJywgJ3Bhc3MnLCAnaGVscCcs
ICdxdWl0JykpOgoJCQlzZWxmLnJlc3BvbmQgKCc1MzAgUGxlYXNlIGxvZyBpbiB3aXRoIFVT
RVIgYW5kIFBBU1MnKQoJCWVsaWYgKG5vdCBzZWxmLmNoZWNrX2NvbW1hbmRfYXV0aG9yaXph
dGlvbiAoY29tbWFuZCkpOgoJCQlzZWxmLmNvbW1hbmRfbm90X2F1dGhvcml6ZWQgKGNvbW1h
bmQpCgkJZWxzZToKCQkJdHJ5OgoJCQkJcmVzdWx0ID0gYXBwbHkgKGZ1biwgKGxpbmUsKSkK
CQkJZXhjZXB0OgoJCQkJc2VsZi5zZXJ2ZXIudG90YWxfZXhjZXB0aW9ucy5pbmNyZW1lbnQo
KQoJCQkJKGZpbGUsIGZ1biwgbGluZSksIHQsdiwgdGJpbmZvID0gYXN5bmNvcmUuY29tcGFj
dF90cmFjZWJhY2soKQoJCQkJaWYgc2VsZi5jbGllbnRfZGM6CgkJCQkJdHJ5OgoJCQkJCQlz
ZWxmLmNsaWVudF9kYy5jbG9zZSgpCgkJCQkJZXhjZXB0OgoJCQkJCQlwYXNzCgkJCQlzZWxm
LnJlc3BvbmQgKAoJCQkJCSc0NTEgU2VydmVyIEVycm9yOiAlcywgJXM6IGZpbGU6ICVzIGxp
bmU6ICVzJyAlICgKCQkJCQkJdCx2LGZpbGUsbGluZSwKCQkJCQkJKQoJCQkJCSkKCgljbG9z
ZWQgPSAwCglkZWYgY2xvc2UgKHNlbGYpOgoJCWlmIG5vdCBzZWxmLmNsb3NlZDoKCQkJc2Vs
Zi5jbG9zZWQgPSAxCgkJCWlmIHNlbGYucGFzc2l2ZV9hY2NlcHRvcjoKCQkJCXNlbGYucGFz
c2l2ZV9hY2NlcHRvci5jbG9zZSgpCgkJCWlmIHNlbGYuY2xpZW50X2RjOgoJCQkJc2VsZi5j
bGllbnRfZGMuY2xvc2UoKQoJCQlzZWxmLnNlcnZlci5jbG9zZWRfc2Vzc2lvbnMuaW5jcmVt
ZW50KCkKCQkJYXN5bmNoYXQuYXN5bmNfY2hhdC5jbG9zZSAoc2VsZikKCgkjIC0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkjIGZpbGVzeXN0
ZW0gaW50ZXJmYWNlIGZ1bmN0aW9ucy4KCSMgb3ZlcnJpZGUgdGhlc2UgdG8gcHJvdmlkZSBh
Y2Nlc3MgY29udHJvbCBvciBwZXJmb3JtCgkjIG90aGVyIGZ1bmN0aW9ucy4KCSMgLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCglkZWYgY3dk
IChzZWxmLCBsaW5lKToKCQlyZXR1cm4gc2VsZi5maWxlc3lzdGVtLmN3ZCAobGluZVsxXSkK
CglkZWYgY2R1cCAoc2VsZiwgbGluZSk6CgkJcmV0dXJuIHNlbGYuZmlsZXN5c3RlbS5jZHVw
KCkKCglkZWYgb3BlbiAoc2VsZiwgcGF0aCwgbW9kZSk6CgkJcmV0dXJuIHNlbGYuZmlsZXN5
c3RlbS5vcGVuIChwYXRoLCBtb2RlKQoKCSMgcmV0dXJucyBhIHByb2R1Y2VyCglkZWYgbGlz
dGRpciAoc2VsZiwgcGF0aCwgbG9uZz0wKToKCQlyZXR1cm4gc2VsZi5maWxlc3lzdGVtLmxp
c3RkaXIgKHBhdGgsIGxvbmcpCgoJZGVmIGdldF9kaXJfbGlzdCAoc2VsZiwgbGluZSwgbG9u
Zz0wKToKCQkjIHdlIG5lZWQgdG8gc2NhbiB0aGUgY29tbWFuZCBsaW5lIGZvciBhcmd1bWVu
dHMgdG8gJy9iaW4vbHMnLi4uCgkJYXJncyA9IGxpbmVbMTpdCgkJcGF0aF9hcmdzID0gW10K
CQlmb3IgYXJnIGluIGFyZ3M6CgkJCWlmIGFyZ1swXSAhPSAnLSc6CgkJCQlwYXRoX2FyZ3Mu
YXBwZW5kIChhcmcpCgkJCWVsc2U6CgkJCQkjIGlnbm9yZSBhcmd1bWVudHMKCQkJCXBhc3MK
CQlpZiBsZW4ocGF0aF9hcmdzKSA8IDE6CgkJCWRpciA9ICcuJwoJCWVsc2U6CgkJCWRpciA9
IHBhdGhfYXJnc1swXQoJCXJldHVybiBzZWxmLmxpc3RkaXIgKGRpciwgbG9uZykKCgkjIC0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkjIGF1
dGhvcml6YXRpb24gbWV0aG9kcwoJIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLQoKCWRlZiBjaGVja19jb21tYW5kX2F1dGhvcml6YXRpb24g
KHNlbGYsIGNvbW1hbmQpOgoJCWlmIGNvbW1hbmQgaW4gc2VsZi53cml0ZV9jb21tYW5kcyBh
bmQgc2VsZi5yZWFkX29ubHk6CgkJCXJldHVybiAwCgkJZWxzZToKCQkJcmV0dXJuIDEKCgkj
IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkj
IHV0aWxpdHkgbWV0aG9kcwoJIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLQoKCWRlZiBsb2cgKHNlbGYsIG1lc3NhZ2UpOgoJCXNlbGYuc2Vy
dmVyLmxvZ2dlci5sb2cgKAoJCQlzZWxmLmFkZHJbMF0sCgkJCSclZCAlcycgJSAoCgkJCQlz
ZWxmLmFkZHJbMV0sIG1lc3NhZ2UKCQkJCSkKCQkJKQoKCWRlZiByZXNwb25kIChzZWxmLCBy
ZXNwKToKCQlzZWxmLmxvZyAoJz09PiAlcycgJSByZXNwKQoJCXNlbGYucHVzaCAocmVzcCAr
ICdcclxuJykKCglkZWYgY29tbWFuZF9ub3RfdW5kZXJzdG9vZCAoc2VsZiwgY29tbWFuZCk6
CgkJc2VsZi5yZXNwb25kICgiNTAwICclcyc6IGNvbW1hbmQgbm90IHVuZGVyc3Rvb2QuIiAl
IGNvbW1hbmQpCgoJZGVmIGNvbW1hbmRfbm90X2F1dGhvcml6ZWQgKHNlbGYsIGNvbW1hbmQp
OgoJCXNlbGYucmVzcG9uZCAoCgkJCSI1MzAgWW91IGFyZSBub3QgYXV0aG9yaXplZCB0byBw
ZXJmb3JtIHRoZSAnJXMnIGNvbW1hbmQiICUgKAoJCQkJY29tbWFuZAoJCQkJKQoJCQkpCgoJ
ZGVmIG1ha2VfeG1pdF9jaGFubmVsIChzZWxmKToKCQkjIEluIFBBU1YgbW9kZSwgdGhlIGNv
bm5lY3Rpb24gbWF5IG9yIG1heSBfbm90XyBoYXZlIGJlZW4gbWFkZQoJCSMgeWV0LiAgW2Fs
dGhvdWdoIGluIG1vc3QgY2FzZXMgaXQgaXMuLi4gRlRQIEV4cGxvcmVyIGJlaW5nCgkJIyB0
aGUgb25seSBleGNlcHRpb24gSSd2ZSB5ZXQgc2Vlbl0uICBUaGlzIGdldHMgc29tZXdoYXQg
Y29uZnVzaW5nCgkJIyBiZWNhdXNlIHRoaW5ncyBtYXkgaGFwcGVuIGluIGFueSBvcmRlci4u
LgoJCXBhID0gc2VsZi5wYXNzaXZlX2FjY2VwdG9yCgkJaWYgcGE6CgkJCWlmIHBhLnJlYWR5
OgoJCQkJIyBhIGNvbm5lY3Rpb24gaGFzIGFscmVhZHkgYmVlbiBtYWRlLgoJCQkJY29ubiwg
YWRkciA9IHNlbGYucGFzc2l2ZV9hY2NlcHRvci5yZWFkeQoJCQkJY2RjID0geG1pdF9jaGFu
bmVsIChzZWxmLCBhZGRyKQoJCQkJY2RjLnNldF9zb2NrZXQgKGNvbm4pCgkJCQljZGMuY29u
bmVjdGVkID0gMQoJCQkJc2VsZi5wYXNzaXZlX2FjY2VwdG9yLmNsb3NlKCkKCQkJCXNlbGYu
cGFzc2l2ZV9hY2NlcHRvciA9IE5vbmUJCQkJCgkJCWVsc2U6CgkJCQkjIHdlJ3JlIHN0aWxs
IHdhaXRpbmcgZm9yIGEgY29ubmVjdCB0byB0aGUgUEFTViBwb3J0LgoJCQkJY2RjID0geG1p
dF9jaGFubmVsIChzZWxmKQoJCWVsc2U6CgkJCSMgbm90IGluIFBBU1YgbW9kZS4KCQkJaXAs
IHBvcnQgPSBzZWxmLmNsaWVudF9hZGRyCgkJCWNkYyA9IHhtaXRfY2hhbm5lbCAoc2VsZiwg
c2VsZi5jbGllbnRfYWRkcikKCQkJY2RjLmNyZWF0ZV9zb2NrZXQgKHNvY2tldC5BRl9JTkVU
LCBzb2NrZXQuU09DS19TVFJFQU0pCgkJCWlmIHNlbGYuYmluZF9sb2NhbF9taW51c19vbmU6
CgkJCQljZGMuYmluZCAoKCcnLCBzZWxmLnNlcnZlci5wb3J0IC0gMSkpCgkJCXRyeToKCQkJ
CWNkYy5jb25uZWN0ICgoaXAsIHBvcnQpKQoJCQlleGNlcHQgc29ja2V0LmVycm9yLCB3aHk6
CgkJCQlzZWxmLnJlc3BvbmQgKCI0MjUgQ2FuJ3QgYnVpbGQgZGF0YSBjb25uZWN0aW9uIikK
CQlzZWxmLmNsaWVudF9kYyA9IGNkYwoKCSMgcHJldHR5IG11Y2ggdGhlIHNhbWUgYXMgeG1p
dCwgYnV0IG9ubHkgcmlnaHQgb24gdGhlIHZlcmdlIG9mCgkjIGJlaW5nIHdvcnRoIGEgbWVy
Z2UuCglkZWYgbWFrZV9yZWN2X2NoYW5uZWwgKHNlbGYsIGZkKToKCQlwYSA9IHNlbGYucGFz
c2l2ZV9hY2NlcHRvcgoJCWlmIHBhOgoJCQlpZiBwYS5yZWFkeToKCQkJCSMgYSBjb25uZWN0
aW9uIGhhcyBhbHJlYWR5IGJlZW4gbWFkZS4KCQkJCWNvbm4sIGFkZHIgPSBwYS5yZWFkeQoJ
CQkJY2RjID0gcmVjdl9jaGFubmVsIChzZWxmLCBhZGRyLCBmZCkKCQkJCWNkYy5zZXRfc29j
a2V0IChjb25uKQoJCQkJY2RjLmNvbm5lY3RlZCA9IDEKCQkJCXNlbGYucGFzc2l2ZV9hY2Nl
cHRvci5jbG9zZSgpCgkJCQlzZWxmLnBhc3NpdmVfYWNjZXB0b3IgPSBOb25lCQkJCQoJCQll
bHNlOgoJCQkJIyB3ZSdyZSBzdGlsbCB3YWl0aW5nIGZvciBhIGNvbm5lY3QgdG8gdGhlIFBB
U1YgcG9ydC4KCQkJCWNkYyA9IHJlY3ZfY2hhbm5lbCAoc2VsZiwgTm9uZSwgZmQpCgkJZWxz
ZToKCQkJIyBub3QgaW4gUEFTViBtb2RlLgoJCQlpcCwgcG9ydCA9IHNlbGYuY2xpZW50X2Fk
ZHIKCQkJY2RjID0gcmVjdl9jaGFubmVsIChzZWxmLCBzZWxmLmNsaWVudF9hZGRyLCBmZCkK
CQkJY2RjLmNyZWF0ZV9zb2NrZXQgKHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19TVFJF
QU0pCgkJCXRyeToKCQkJCWNkYy5jb25uZWN0ICgoaXAsIHBvcnQpKQoJCQlleGNlcHQgc29j
a2V0LmVycm9yLCB3aHk6CgkJCQlzZWxmLnJlc3BvbmQgKCI0MjUgQ2FuJ3QgYnVpbGQgZGF0
YSBjb25uZWN0aW9uIikKCQlzZWxmLmNsaWVudF9kYyA9IGNkYwoKCXR5cGVfbWFwID0gewoJ
CSdhJzonQVNDSUknLAoJCSdpJzonQmluYXJ5JywKCQknZSc6J0VCQ0RJQycsCgkJJ2wnOidC
aW5hcnknCgkJfQoKCXR5cGVfbW9kZV9tYXAgPSB7CgkJJ2EnOid0JywKCQknaSc6J2InLAoJ
CSdlJzonYicsCgkJJ2wnOidiJwoJCX0KCgkjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkjIGNvbW1hbmQgbWV0aG9kcwoJIyAtLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWRlZiBjbWRf
dHlwZSAoc2VsZiwgbGluZSk6CgkJJ3NwZWNpZnkgZGF0YSB0cmFuc2ZlciB0eXBlJwoJCSMg
YXNjaWksIGViY2RpYywgaW1hZ2UsIGxvY2FsIDxieXRlIHNpemU+CgkJdCA9IHN0cmluZy5s
b3dlciAobGluZVsxXSkKCQkjIG5vIHN1cHBvcnQgZm9yIEVCQ0RJQwoJCSMgaWYgdCBub3Qg
aW4gWydhJywnZScsJ2knLCdsJ106CgkJaWYgdCBub3QgaW4gWydhJywnaScsJ2wnXToKCQkJ
c2VsZi5jb21tYW5kX25vdF91bmRlcnN0b29kIChzdHJpbmcuam9pbiAobGluZSkpCgkJZWxp
ZiB0ID09ICdsJyBhbmQgKGxlbihsaW5lKSA+IDIgYW5kIGxpbmVbMl0gIT0gJzgnKToKCQkJ
c2VsZi5yZXNwb25kICgnNTA0IEJ5dGUgc2l6ZSBtdXN0IGJlIDgnKQoJCWVsc2U6CgkJCXNl
bGYuY3VycmVudF9tb2RlID0gdAoJCQlzZWxmLnJlc3BvbmQgKCcyMDAgVHlwZSBzZXQgdG8g
JXMuJyAlIHNlbGYudHlwZV9tYXBbdF0pCgoKCWRlZiBjbWRfcXVpdCAoc2VsZiwgbGluZSk6
CgkJJ3Rlcm1pbmF0ZSBzZXNzaW9uJwoJCXNlbGYucmVzcG9uZCAoJzIyMSBHb29kYnllLicp
CgkJc2VsZi5jbG9zZV93aGVuX2RvbmUoKQoKCWRlZiBjbWRfcG9ydCAoc2VsZiwgbGluZSk6
CgkJJ3NwZWNpZnkgZGF0YSBjb25uZWN0aW9uIHBvcnQnCgkJaW5mbyA9IHN0cmluZy5zcGxp
dCAobGluZVsxXSwgJywnKQoJCWlwID0gc3RyaW5nLmpvaW4gKGluZm9bOjRdLCAnLicpCgkJ
cG9ydCA9IHN0cmluZy5hdG9pKGluZm9bNF0pKjI1NiArIHN0cmluZy5hdG9pKGluZm9bNV0p
CgkJIyBob3cgbWFueSBkYXRhIGNvbm5lY3Rpb25zIGF0IGEgdGltZT8KCQkjIEknbSBhc3N1
bWluZyBvbmUgZm9yIG5vdy4uLgoJCSMgVE9ETzogd2Ugc2hvdWxkIChvcHRpb25hbGx5KSB2
ZXJpZnkgdGhhdCB0aGUKCQkjIGlwIG51bWJlciBiZWxvbmdzIHRvIHRoZSBjbGllbnQuICBb
d3UtZnRwZCBkb2VzIHRoaXM/XQoJCXNlbGYuY2xpZW50X2FkZHIgPSAoaXAsIHBvcnQpCgkJ
c2VsZi5yZXNwb25kICgnMjAwIFBPUlQgY29tbWFuZCBzdWNjZXNzZnVsLicpCgoJZGVmIG5l
d19wYXNzaXZlX2FjY2VwdG9yIChzZWxmKToKCQkjIGVuc3VyZSB0aGF0IG9ubHkgb25lIG9m
IHRoZXNlIGV4aXN0cyBhdCBhIHRpbWUuCgkJaWYgc2VsZi5wYXNzaXZlX2FjY2VwdG9yIGlz
IG5vdCBOb25lOgoJCQlzZWxmLnBhc3NpdmVfYWNjZXB0b3IuY2xvc2UoKQoJCQlzZWxmLnBh
c3NpdmVfYWNjZXB0b3IgPSBOb25lCgkJc2VsZi5wYXNzaXZlX2FjY2VwdG9yID0gcGFzc2l2
ZV9hY2NlcHRvciAoc2VsZikKCQlyZXR1cm4gc2VsZi5wYXNzaXZlX2FjY2VwdG9yCgoJZGVm
IGNtZF9wYXN2IChzZWxmLCBsaW5lKToKCQkncHJlcGFyZSBmb3Igc2VydmVyLXRvLXNlcnZl
ciB0cmFuc2ZlcicKCQlwYyA9IHNlbGYubmV3X3Bhc3NpdmVfYWNjZXB0b3IoKQoJCXBvcnQg
PSBwYy5hZGRyWzFdCgkJaXBfYWRkciA9IHBjLmNvbnRyb2xfY2hhbm5lbC5nZXRzb2NrbmFt
ZSgpWzBdCgkJc2VsZi5yZXNwb25kICgKCQkJJzIyNyBFbnRlcmluZyBQYXNzaXZlIE1vZGUg
KCVzLCVkLCVkKScgJSAoCgkJCQlzdHJpbmcuam9pbiAoc3RyaW5nLnNwbGl0IChpcF9hZGRy
LCAnLicpLCAnLCcpLAoJCQkJcG9ydC8yNTYsCgkJCQlwb3J0JTI1NgoJCQkJKQoJCQkpCgkJ
c2VsZi5jbGllbnRfZGMgPSBOb25lCgoJZGVmIGNtZF9ubHN0IChzZWxmLCBsaW5lKToKCQkn
Z2l2ZSBuYW1lIGxpc3Qgb2YgZmlsZXMgaW4gZGlyZWN0b3J5JwoJCSMgbmNmdHAgYWRkcyB0
aGUgLUZDIGFyZ3VtZW50IGZvciB0aGUgdXNlci12aXNpYmxlICdubGlzdCcKCQkjIGNvbW1h
bmQuICBXZSBjb3VsZCB0cnkgdG8gZW11bGF0ZSBscyBmbGFncywgYnV0IG5vdCBqdXN0IHll
dC4KCQlpZiAnLUZDJyBpbiBsaW5lOgoJCQlsaW5lLnJlbW92ZSAoJy1GQycpCgkJdHJ5OgoJ
CQlkaXJfbGlzdF9wcm9kdWNlciA9IHNlbGYuZ2V0X2Rpcl9saXN0IChsaW5lLCAwKQoJCWV4
Y2VwdCBvcy5lcnJvciwgd2h5OgoJCQlzZWxmLnJlc3BvbmQgKCc1NTAgQ291bGQgbm90IGxp
c3QgZGlyZWN0b3J5OiAlcycgJSByZXByKHdoeSkpCgkJCXJldHVybgoJCXNlbGYucmVzcG9u
ZCAoCgkJCScxNTAgT3BlbmluZyAlcyBtb2RlIGRhdGEgY29ubmVjdGlvbiBmb3IgZmlsZSBs
aXN0JyAlICgKCQkJCXNlbGYudHlwZV9tYXBbc2VsZi5jdXJyZW50X21vZGVdCgkJCQkpCgkJ
CSkKCQlzZWxmLm1ha2VfeG1pdF9jaGFubmVsKCkKCQlzZWxmLmNsaWVudF9kYy5wdXNoX3dp
dGhfcHJvZHVjZXIgKGRpcl9saXN0X3Byb2R1Y2VyKQoJCXNlbGYuY2xpZW50X2RjLmNsb3Nl
X3doZW5fZG9uZSgpCgoJZGVmIGNtZF9saXN0IChzZWxmLCBsaW5lKToKCQknZ2l2ZSBsaXN0
IGZpbGVzIGluIGEgZGlyZWN0b3J5JwoJCXRyeToKCQkJZGlyX2xpc3RfcHJvZHVjZXIgPSBz
ZWxmLmdldF9kaXJfbGlzdCAobGluZSwgMSkKCQlleGNlcHQgb3MuZXJyb3IsIHdoeToKCQkJ
c2VsZi5yZXNwb25kICgnNTUwIENvdWxkIG5vdCBsaXN0IGRpcmVjdG9yeTogJXMnICUgcmVw
cih3aHkpKQoJCQlyZXR1cm4KCQlzZWxmLnJlc3BvbmQgKAoJCQknMTUwIE9wZW5pbmcgJXMg
bW9kZSBkYXRhIGNvbm5lY3Rpb24gZm9yIGZpbGUgbGlzdCcgJSAoCgkJCQlzZWxmLnR5cGVf
bWFwW3NlbGYuY3VycmVudF9tb2RlXQoJCQkJKQoJCQkpCgkJc2VsZi5tYWtlX3htaXRfY2hh
bm5lbCgpCgkJc2VsZi5jbGllbnRfZGMucHVzaF93aXRoX3Byb2R1Y2VyIChkaXJfbGlzdF9w
cm9kdWNlcikKCQlzZWxmLmNsaWVudF9kYy5jbG9zZV93aGVuX2RvbmUoKQoKCWRlZiBjbWRf
Y3dkIChzZWxmLCBsaW5lKToKCQknY2hhbmdlIHdvcmtpbmcgZGlyZWN0b3J5JwoJCWlmIHNl
bGYuY3dkIChsaW5lKToKCQkJc2VsZi5yZXNwb25kICgnMjUwIENXRCBjb21tYW5kIHN1Y2Nl
c3NmdWwuJykKCQllbHNlOgoJCQlzZWxmLnJlc3BvbmQgKCc1NTAgTm8gc3VjaCBkaXJlY3Rv
cnkuJykJCQkKCglkZWYgY21kX2NkdXAgKHNlbGYsIGxpbmUpOgoJCSdjaGFuZ2UgdG8gcGFy
ZW50IG9mIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnknCgkJaWYgc2VsZi5jZHVwKGxpbmUp
OgoJCQlzZWxmLnJlc3BvbmQgKCcyNTAgQ0RVUCBjb21tYW5kIHN1Y2Nlc3NmdWwuJykKCQll
bHNlOgoJCQlzZWxmLnJlc3BvbmQgKCc1NTAgTm8gc3VjaCBkaXJlY3RvcnkuJykKCQkKCWRl
ZiBjbWRfcHdkIChzZWxmLCBsaW5lKToKCQkncHJpbnQgdGhlIGN1cnJlbnQgd29ya2luZyBk
aXJlY3RvcnknCgkJc2VsZi5yZXNwb25kICgKCQkJJzI1NyAiJXMiIGlzIHRoZSBjdXJyZW50
IGRpcmVjdG9yeS4nICUgKAoJCQkJc2VsZi5maWxlc3lzdGVtLmN1cnJlbnRfZGlyZWN0b3J5
KCkKCQkJCSkKCQkJKQoKCSMgbW9kaWZpY2F0aW9uIHRpbWUKCSMgZXhhbXBsZSBvdXRwdXQ6
CgkjIDIxMyAxOTk2MDMwMTIwNDMyMAoJZGVmIGNtZF9tZHRtIChzZWxmLCBsaW5lKToKCQkn
c2hvdyBsYXN0IG1vZGlmaWNhdGlvbiB0aW1lIG9mIGZpbGUnCgkJZmlsZW5hbWUgPSBsaW5l
WzFdCgkJaWYgbm90IHNlbGYuZmlsZXN5c3RlbS5pc2ZpbGUgKGZpbGVuYW1lKToKCQkJc2Vs
Zi5yZXNwb25kICgnNTUwICIlcyIgaXMgbm90IGEgZmlsZScgJSBmaWxlbmFtZSkKCQllbHNl
OgoJCQltdGltZSA9IHRpbWUuZ210aW1lKHNlbGYuZmlsZXN5c3RlbS5zdGF0KGZpbGVuYW1l
KVtzdGF0LlNUX01USU1FXSkKCQkJc2VsZi5yZXNwb25kICgKCQkJCScyMTMgJTRkJTAyZCUw
MmQlMDJkJTAyZCUwMmQnICUgKAoJCQkJCW10aW1lWzBdLAoJCQkJCW10aW1lWzFdLAoJCQkJ
CW10aW1lWzJdLAoJCQkJCW10aW1lWzNdLAoJCQkJCW10aW1lWzRdLAoJCQkJCW10aW1lWzVd
CgkJCQkJKQoJCQkJKQoKCWRlZiBjbWRfbm9vcCAoc2VsZiwgbGluZSk6CgkJJ2RvIG5vdGhp
bmcnCgkJc2VsZi5yZXNwb25kICgnMjAwIE5PT1AgY29tbWFuZCBzdWNjZXNzZnVsLicpCgoJ
ZGVmIGNtZF9zaXplIChzZWxmLCBsaW5lKToKCQkncmV0dXJuIHNpemUgb2YgZmlsZScKCQlm
aWxlbmFtZSA9IGxpbmVbMV0KCQlpZiBub3Qgc2VsZi5maWxlc3lzdGVtLmlzZmlsZSAoZmls
ZW5hbWUpOgoJCQlzZWxmLnJlc3BvbmQgKCc1NTAgIiVzIiBpcyBub3QgYSBmaWxlJyAlIGZp
bGVuYW1lKQoJCWVsc2U6CgkJCXNlbGYucmVzcG9uZCAoCgkJCQknMjEzICVkJyAlIChzZWxm
LmZpbGVzeXN0ZW0uc3RhdChmaWxlbmFtZSlbc3RhdC5TVF9TSVpFXSkKCQkJCSkKCglkZWYg
Y21kX3JldHIgKHNlbGYsIGxpbmUpOgoJCSdyZXRyaWV2ZSBhIGZpbGUnCgkJaWYgbGVuKGxp
bmUpIDwgMjoKCQkJc2VsZi5jb21tYW5kX25vdF91bmRlcnN0b29kIChzdHJpbmcuam9pbiAo
bGluZSkpCgkJZWxzZToKCQkJZmlsZSA9IGxpbmVbMV0KCQkJaWYgbm90IHNlbGYuZmlsZXN5
c3RlbS5pc2ZpbGUgKGZpbGUpOgoJCQkJc2VsZi5sb2dfaW5mbyAoJ2NoZWNraW5nICVzJyAl
IGZpbGUpCgkJCQlzZWxmLnJlc3BvbmQgKCc1NTAgTm8gc3VjaCBmaWxlJykKCQkJZWxzZToK
CQkJCXRyeToKCQkJCQkjIEZJWE1FOiBmb3Igc29tZSByZWFzb24sICdydCcgaXNuJ3Qgd29y
a2luZyBvbiB3aW45NQoJCQkJCW1vZGUgPSAncicrc2VsZi50eXBlX21vZGVfbWFwW3NlbGYu
Y3VycmVudF9tb2RlXQoJCQkJCWZkID0gc2VsZi5vcGVuIChmaWxlLCBtb2RlKQoJCQkJZXhj
ZXB0IElPRXJyb3IsIHdoeToKCQkJCQlzZWxmLnJlc3BvbmQgKCc1NTMgY291bGQgbm90IG9w
ZW4gZmlsZSBmb3IgcmVhZGluZzogJXMnICUgKHJlcHIod2h5KSkpCgkJCQkJcmV0dXJuCgkJ
CQlzZWxmLnJlc3BvbmQgKAoJCQkJCSIxNTAgT3BlbmluZyAlcyBtb2RlIGRhdGEgY29ubmVj
dGlvbiBmb3IgZmlsZSAnJXMnIiAlICgKCQkJCQkJc2VsZi50eXBlX21hcFtzZWxmLmN1cnJl
bnRfbW9kZV0sCgkJCQkJCWZpbGUKCQkJCQkJKQoJCQkJCSkKCQkJCXNlbGYubWFrZV94bWl0
X2NoYW5uZWwoKQoKCQkJCWlmIHNlbGYucmVzdGFydF9wb3NpdGlvbjoKCQkJCQkjIHRyeSB0
byBwb3NpdGlvbiB0aGUgZmlsZSBhcyByZXF1ZXN0ZWQsIGJ1dAoJCQkJCSMgZ2l2ZSB1cCBz
aWxlbnRseSBvbiBmYWlsdXJlICh0aGUgJ2ZpbGUgb2JqZWN0JwoJCQkJCSMgbWF5IG5vdCBz
dXBwb3J0IHNlZWsoKSkKCQkJCQl0cnk6CgkJCQkJCWZkLnNlZWsgKHNlbGYucmVzdGFydF9w
b3NpdGlvbikKCQkJCQlleGNlcHQ6CgkJCQkJCXBhc3MKCQkJCQlzZWxmLnJlc3RhcnRfcG9z
aXRpb24gPSAwCgoJCQkJc2VsZi5jbGllbnRfZGMucHVzaF93aXRoX3Byb2R1Y2VyICgKCQkJ
CQlmaWxlX3Byb2R1Y2VyIChzZWxmLCBzZWxmLmNsaWVudF9kYywgZmQpCgkJCQkJKQoJCQkJ
c2VsZi5jbGllbnRfZGMuY2xvc2Vfd2hlbl9kb25lKCkKCglkZWYgY21kX3N0b3IgKHNlbGYs
IGxpbmUsIG1vZGU9J3diJyk6CgkJJ3N0b3JlIGEgZmlsZScKCQlpZiBsZW4gKGxpbmUpIDwg
MjoKCQkJc2VsZi5jb21tYW5kX25vdF91bmRlcnN0b29kIChzdHJpbmcuam9pbiAobGluZSkp
CgkJZWxzZToKCQkJaWYgc2VsZi5yZXN0YXJ0X3Bvc2l0aW9uOgoJCQkJcmVzdGFydF9wb3Np
dGlvbiA9IDAKCQkJCXNlbGYucmVzcG9uZCAoJzU1MyByZXN0YXJ0IG9uIFNUT1Igbm90IHll
dCBzdXBwb3J0ZWQnKQoJCQkJcmV0dXJuCgkJCWZpbGUgPSBsaW5lWzFdCgkJCSMgdG9kbzog
aGFuZGxlIHRoYXQgdHlwZSBmbGFnCgkJCXRyeToKCQkJCWZkID0gc2VsZi5vcGVuIChmaWxl
LCBtb2RlKQoJCQlleGNlcHQgSU9FcnJvciwgd2h5OgoJCQkJc2VsZi5yZXNwb25kICgnNTUz
IGNvdWxkIG5vdCBvcGVuIGZpbGUgZm9yIHdyaXRpbmc6ICVzJyAlIChyZXByKHdoeSkpKQoJ
CQkJcmV0dXJuCgkJCXNlbGYucmVzcG9uZCAoCgkJCQknMTUwIE9wZW5pbmcgJXMgY29ubmVj
dGlvbiBmb3IgJXMnICUgKAoJCQkJCXNlbGYudHlwZV9tYXBbc2VsZi5jdXJyZW50X21vZGVd
LAoJCQkJCWZpbGUKCQkJCQkpCgkJCQkpCgkJCXNlbGYubWFrZV9yZWN2X2NoYW5uZWwgKGZk
KQoKCWRlZiBjbWRfYWJvciAoc2VsZiwgbGluZSk6CgkJJ2Fib3J0IG9wZXJhdGlvbicKCQlp
ZiBzZWxmLmNsaWVudF9kYzoKCQkJc2VsZi5jbGllbnRfZGMuY2xvc2UoKQoJCXNlbGYucmVz
cG9uZCAoJzIyNiBBQk9SIGNvbW1hbmQgc3VjY2Vzc2Z1bC4nKQoKCWRlZiBjbWRfYXBwZSAo
c2VsZiwgbGluZSk6CgkJJ2FwcGVuZCB0byBhIGZpbGUnCgkJcmV0dXJuIHNlbGYuY21kX3N0
b3IgKGxpbmUsICdhYicpCgoJZGVmIGNtZF9ybmZyIChzZWxmLCBsaW5lKToKCQkncmVuYW1l
IGZyb20nCgkJaWYgbGVuIChsaW5lKSAhPSAyOgoJCQlzZWxmLmNvbW1hbmRfbm90X3VuZGVy
c3Rvb2QgKHN0cmluZy5qb2luIChsaW5lKSkKCQllbHNlOgoJCQlzZWxmLmZyb21maWxlID0g
bGluZVsxXQoJCQlzZWxmLnJlc3BvbmQgKCczNTAgUk5GUiBjb21tYW5kIHN1Y2Nlc3NmdWwu
JykKCglkZWYgY21kX3JudG8gKHNlbGYsIGxpbmUpOgoJCSdyZW5hbWUgdG8nCgkJaWYgbGVu
IChsaW5lKSAhPSAyOgoJCQlzZWxmLmNvbW1hbmRfbm90X3VuZGVyc3Rvb2QgKHN0cmluZy5q
b2luIChsaW5lKSkKCQllbHNlOgoJCQl0cnk6CgkJCQlzZWxmLmZpbGVzeXN0ZW0ucmVuYW1l
IChzZWxmLmZyb21maWxlLCBsaW5lWzFdKQoJCQkJc2VsZi5yZXNwb25kICgnMjUwIFJOVE8g
Y29tbWFuZCBzdWNjZXNzZnVsLicpCgkJCWV4Y2VwdDoKCQkJCXNlbGYucmVzcG9uZCAoJzU1
MCBlcnJvciByZW5hbWluZyBmaWxlLicpCgkJCglkZWYgY21kX2RlbGUgKHNlbGYsIGxpbmUp
OgoJCWlmIGxlbiAobGluZSkgIT0gMjoKCQkJc2VsZi5jb21tYW5kX25vdF91bmRlcnN0b29k
IChzdHJpbmcuam9pbiAobGluZSkpCgkJZWxzZToKCQkJZmlsZSA9IGxpbmVbMV0KCQkJaWYg
c2VsZi5maWxlc3lzdGVtLmlzZmlsZSAoZmlsZSk6CgkJCQl0cnk6CgkJCQkJc2VsZi5maWxl
c3lzdGVtLnVubGluayAoZmlsZSkKCQkJCQlzZWxmLnJlc3BvbmQgKCcyNTAgREVMRSBjb21t
YW5kIHN1Y2Nlc3NmdWwuJykKCQkJCWV4Y2VwdDoKCQkJCQlzZWxmLnJlc3BvbmQgKCc1NTAg
ZXJyb3IgZGVsZXRpbmcgZmlsZS4nKQoJCQllbHNlOgoJCQkJc2VsZi5yZXNwb25kICgnNTUw
ICVzOiBObyBzdWNoIGZpbGUuJyAlIGZpbGUpCgoJZGVmIGNtZF9ta2QgKHNlbGYsIGxpbmUp
OgoJCWlmIGxlbiAobGluZSkgIT0gMjoKCQkJc2VsZi5jb21tYW5kLm5vdF91bmRlcnN0b29k
IChzdHJpbmcuam9pbiAobGluZSkpCgkJZWxzZToKCQkJcGF0aCA9IGxpbmVbMV0KCQkJdHJ5
OgoJCQkJcHJpbnQgJ0hpIFRoZXJlJwoJCQkJcHJpbnQgc2VsZi5maWxlc3lzdGVtCgkJCQlz
ZWxmLmZpbGVzeXN0ZW0ubWtkaXIgKHBhdGgpCgkJCQlzZWxmLnJlc3BvbmQgKCcyNTcgTUtE
IGNvbW1hbmQgc3VjY2Vzc2Z1bC4nKQoJCQlleGNlcHQ6CgkJCQlzZWxmLnJlc3BvbmQgKCc1
NTAgZXJyb3IgY3JlYXRpbmcgZGlyZWN0b3J5LicpCgoJZGVmIGNtZF9ybWQgKHNlbGYsIGxp
bmUpOgoJCWlmIGxlbiAobGluZSkgIT0gMjoKCQkJc2VsZi5jb21tYW5kLm5vdF91bmRlcnN0
b29kIChzdHJpbmcuam9pbiAobGluZSkpCgkJZWxzZToKCQkJcGF0aCA9IGxpbmVbMV0KCQkJ
dHJ5OgoJCQkJc2VsZi5maWxlc3lzdGVtLnJtZGlyIChwYXRoKQoJCQkJc2VsZi5yZXNwb25k
ICgnMjUwIFJNRCBjb21tYW5kIHN1Y2Nlc3NmdWwuJykKCQkJZXhjZXB0OgoJCQkJc2VsZi5y
ZXNwb25kICgnNTUwIGVycm9yIHJlbW92aW5nIGRpcmVjdG9yeS4nKQoKCWRlZiBjbWRfdXNl
ciAoc2VsZiwgbGluZSk6CgkJJ3NwZWNpZnkgdXNlciBuYW1lJwoJCWlmIGxlbihsaW5lKSA+
IDE6CgkJCXNlbGYudXNlciA9IGxpbmVbMV0KCQkJc2VsZi5yZXNwb25kICgnMzMxIFBhc3N3
b3JkIHJlcXVpcmVkLicpCgkJZWxzZToKCQkJc2VsZi5jb21tYW5kX25vdF91bmRlcnN0b29k
IChzdHJpbmcuam9pbiAobGluZSkpCgoJZGVmIGNtZF9wYXNzIChzZWxmLCBsaW5lKToKCQkn
c3BlY2lmeSBwYXNzd29yZCcKCQlpZiBsZW4obGluZSkgPCAyOgoJCQlwdyA9ICcnCgkJZWxz
ZToKCQkJcHcgPSBsaW5lWzFdCgkJcmVzdWx0LCBtZXNzYWdlLCBmcyA9IHNlbGYuc2VydmVy
LmF1dGhvcml6ZXIuYXV0aG9yaXplIChzZWxmLCBzZWxmLnVzZXIsIHB3KQoJCWlmIHJlc3Vs
dDoKCQkJc2VsZi5yZXNwb25kICgnMjMwICVzJyAlIG1lc3NhZ2UpCgkJCXNlbGYuZmlsZXN5
c3RlbSA9IGZzCgkJCXNlbGYuYXV0aG9yaXplZCA9IDEKCQkJc2VsZi5sb2dfaW5mbygnU3Vj
Y2Vzc2Z1bCBsb2dpbjogRmlsZXN5c3RlbT0lcycgJSByZXByKGZzKSkKCQllbHNlOgoJCQlz
ZWxmLnJlc3BvbmQgKCc1MzAgJXMnICUgbWVzc2FnZSkKCglkZWYgY21kX3Jlc3QgKHNlbGYs
IGxpbmUpOgoJCSdyZXN0YXJ0IGluY29tcGxldGUgdHJhbnNmZXInCgkJdHJ5OgoJCQlwb3Mg
PSBzdHJpbmcuYXRvaSAobGluZVsxXSkKCQlleGNlcHQgVmFsdWVFcnJvcjoKCQkJc2VsZi5j
b21tYW5kX25vdF91bmRlcnN0b29kIChzdHJpbmcuam9pbiAobGluZSkpCgkJc2VsZi5yZXN0
YXJ0X3Bvc2l0aW9uID0gcG9zCgkJc2VsZi5yZXNwb25kICgKCQkJJzM1MCBSZXN0YXJ0aW5n
IGF0ICVkLiBTZW5kIFNUT1JFIG9yIFJFVFJJRVZFIHRvIGluaXRpYXRlIHRyYW5zZmVyLicg
JSBwb3MKCQkJKQoKCWRlZiBjbWRfc3RydSAoc2VsZiwgbGluZSk6CgkJJ29ic29sZXRlIC0g
c2V0IGZpbGUgdHJhbnNmZXIgc3RydWN0dXJlJwoJCWlmIGxpbmVbMV0gaW4gJ2ZGJzoKCQkJ
IyBmID09ICdmaWxlJwoJCQlzZWxmLnJlc3BvbmQgKCcyMDAgU1RSVSBGIE9rJykKCQllbHNl
OgoJCQlzZWxmLnJlc3BvbmQgKCc1MDQgVW5pbXBsZW1lbnRlZCBTVFJVIHR5cGUnKQoKCWRl
ZiBjbWRfbW9kZSAoc2VsZiwgbGluZSk6CgkJJ29ic29sZXRlIC0gc2V0IGZpbGUgdHJhbnNm
ZXIgbW9kZScKCQlpZiBsaW5lWzFdIGluICdzUyc6CgkJCSMgZiA9PSAnZmlsZScKCQkJc2Vs
Zi5yZXNwb25kICgnMjAwIE1PREUgUyBPaycpCgkJZWxzZToKCQkJc2VsZi5yZXNwb25kICgn
NTAyIFVuaW1wbGVtZW50ZWQgTU9ERSB0eXBlJykKCiMgVGhlIHN0YXQgY29tbWFuZCBoYXMg
dHdvIHBlcnNvbmFsaXRpZXMuICBOb3JtYWxseSBpdCByZXR1cm5zIHN0YXR1cwojIGluZm9y
bWF0aW9uIGFib3V0IHRoZSBjdXJyZW50IGNvbm5lY3Rpb24uICBCdXQgaWYgZ2l2ZW4gYW4g
YXJndW1lbnQsCiMgaXQgaXMgZXF1aXZhbGVudCB0byB0aGUgTElTVCBjb21tYW5kLCB3aXRo
IHRoZSBkYXRhIHNlbnQgb3ZlciB0aGUKIyBjb250cm9sIGNvbm5lY3Rpb24uICBTdHJhbmdl
LiAgQnV0IHd1ZnRwZCwgZnRwZCwgYW5kIG50J3MgZnRwIHNlcnZlcgojIGFsbCBzdXBwb3J0
IGl0LgojCiMjCWRlZiBjbWRfc3RhdCAoc2VsZiwgbGluZSk6CiMjCQkncmV0dXJuIHN0YXR1
cyBvZiBzZXJ2ZXInCiMjCQlwYXNzCgoJZGVmIGNtZF9zeXN0IChzZWxmLCBsaW5lKToKCQkn
c2hvdyBvcGVyYXRpbmcgc3lzdGVtIHR5cGUgb2Ygc2VydmVyIHN5c3RlbScKCQkjIFJlcGx5
aW5nIHRvIHRoaXMgY29tbWFuZCBpcyBvZiBxdWVzdGlvbmFibGUgdXRpbGl0eSwgYmVjYXVz
ZQoJCSMgdGhpcyBzZXJ2ZXIgZG9lcyBub3QgYmVoYXZlIGluIGEgcHJlZGljdGFibGUgd2F5
IHcuci50LiB0aGUKCQkjIG91dHB1dCBvZiB0aGUgTElTVCBjb21tYW5kLiAgV2UgZW11bGF0
ZSBVbml4IGxzIG91dHB1dCwgYnV0CgkJIyBvbiB3aW4zMiB0aGUgcGF0aG5hbWUgY2FuIGNv
bnRhaW4gZHJpdmUgaW5mb3JtYXRpb24gYXQgdGhlIGZyb250CgkJIyBDdXJyZW50bHksIHRo
ZSBjb21iaW5hdGlvbiBvZiBlbnN1cmluZyB0aGF0IG9zLnNlcCA9PSAnLycKCQkjIGFuZCBy
ZW1vdmluZyB0aGUgbGVhZGluZyBzbGFzaCB3aGVuIG5lY2Vzc2FyeSBzZWVtcyB0byB3b3Jr
LgoJCSMgW2NkJ2luZyB0byBhbm90aGVyIGRyaXZlIGFsc28gd29ya3NdCgkJIwoJCSMgVGhp
cyBpcyBob3cgd3VmdHBkIHJlc3BvbmRzLCBhbmQgaXMgcHJvYmFibHkKCQkjIHRoZSBtb3N0
IGV4cGVjdGVkLiAgVGhlIG1haW4gcHVycG9zZSBvZiB0aGlzIHJlcGx5IGlzIHNvIHRoYXQK
CQkjIHRoZSBjbGllbnQga25vd3MgdG8gZXhwZWN0IFVuaXggbHMtc3R5bGUgTElTVCBvdXRw
dXQuCgkJc2VsZi5yZXNwb25kICgnMjE1IFVOSVggVHlwZTogTDgnKQoJCSMgb25lIGRpc2Fk
dmFudGFnZSB0byB0aGlzIGlzIHRoYXQgc29tZSBjbGllbnQgcHJvZ3JhbXMKCQkjIGFzc3Vt
ZSB0aGV5IGNhbiBwYXNzIGFyZ3MgdG8gL2Jpbi9scy4KCQkjIGEgZmV3IHR5cGljYWwgcmVz
cG9uc2VzOgoJCSMgMjE1IFVOSVggVHlwZTogTDggKHd1ZnRwZCkKCQkjIDIxNSBXaW5kb3dz
X05UIHZlcnNpb24gMy41MQoJCSMgMjE1IFZNUyBNdWx0aU5ldCBWMy4zCgkJIyA1MDAgJ1NZ
U1QnOiBjb21tYW5kIG5vdCB1bmRlcnN0b29kLiAoU1ZSNCkKCglkZWYgY21kX2hlbHAgKHNl
bGYsIGxpbmUpOgoJCSdnaXZlIGhlbHAgaW5mb3JtYXRpb24nCgkJIyBmaW5kIGFsbCB0aGUg
bWV0aG9kcyB0aGF0IG1hdGNoICdjbWRfeHh4eCcsCgkJIyB1c2UgdGhlaXIgZG9jc3RyaW5n
cyBmb3IgdGhlIGhlbHAgcmVzcG9uc2UuCgkJYXR0cnMgPSBkaXIoc2VsZi5fX2NsYXNzX18p
CgkJaGVscF9saW5lcyA9IFtdCgkJZm9yIGF0dHIgaW4gYXR0cnM6CgkJCWlmIGF0dHJbOjRd
ID09ICdjbWRfJzoKCQkJCXggPSBnZXRhdHRyIChzZWxmLCBhdHRyKQoJCQkJaWYgdHlwZSh4
KSA9PSB0eXBlKHNlbGYuY21kX2hlbHApOgoJCQkJCWlmIHguX19kb2NfXzoKCQkJCQkJaGVs
cF9saW5lcy5hcHBlbmQgKCdcdCVzXHQlcycgJSAoYXR0cls0Ol0sIHguX19kb2NfXykpCgkJ
aWYgaGVscF9saW5lczoKCQkJc2VsZi5wdXNoICgnMjE0LVRoZSBmb2xsb3dpbmcgY29tbWFu
ZHMgYXJlIHJlY29nbml6ZWRcclxuJykKCQkJc2VsZi5wdXNoX3dpdGhfcHJvZHVjZXIgKHBy
b2R1Y2Vycy5saW5lc19wcm9kdWNlciAoaGVscF9saW5lcykpCgkJCXNlbGYucHVzaCAoJzIx
NFxyXG4nKQoJCWVsc2U6CgkJCXNlbGYucHVzaCAoJzIxNC1cclxuXHRIZWxwIFVuYXZhaWxh
YmxlXHJcbjIxNFxyXG4nKQoKY2xhc3MgZnRwX3NlcnZlciAoYXN5bmNvcmUuZGlzcGF0Y2hl
cik6CgkjIG92ZXJyaWRlIHRoaXMgdG8gc3Bhd24gYSBkaWZmZXJlbnQgRlRQIGNoYW5uZWwg
Y2xhc3MuCglmdHBfY2hhbm5lbF9jbGFzcyA9IGZ0cF9jaGFubmVsCgoJU0VSVkVSX0lERU5U
ID0gJ0ZUUCBTZXJ2ZXIgKFYlcyknICUgVkVSU0lPTgoKCWRlZiBfX2luaXRfXyAoCgkJc2Vs
ZiwKCQlhdXRob3JpemVyLAoJCWhvc3RuYW1lCT1Ob25lLAoJCWlwCQkJPScnLAoJCXBvcnQJ
CT0yMSwKCQlyZXNvbHZlcgk9Tm9uZSwKCQlsb2dnZXJfb2JqZWN0PWxvZ2dlci5maWxlX2xv
Z2dlciAoc3lzLnN0ZG91dCkKCQkpOgoJCXNlbGYuaXAgPSBpcAoJCXNlbGYucG9ydCA9IHBv
cnQKCQlzZWxmLmF1dGhvcml6ZXIgPSBhdXRob3JpemVyCgoJCWlmIGhvc3RuYW1lIGlzIE5v
bmU6CgkJCXNlbGYuaG9zdG5hbWUgPSBzb2NrZXQuZ2V0aG9zdG5hbWUoKQoJCWVsc2U6CgkJ
CXNlbGYuaG9zdG5hbWUgPSBob3N0bmFtZQoKCQkjIHN0YXRpc3RpY3MKCQlzZWxmLnRvdGFs
X3Nlc3Npb25zID0gY291bnRlcigpCgkJc2VsZi5jbG9zZWRfc2Vzc2lvbnMgPSBjb3VudGVy
KCkKCQlzZWxmLnRvdGFsX2ZpbGVzX291dCA9IGNvdW50ZXIoKQoJCXNlbGYudG90YWxfZmls
ZXNfaW4gPSBjb3VudGVyKCkKCQlzZWxmLnRvdGFsX2J5dGVzX291dCA9IGNvdW50ZXIoKQoJ
CXNlbGYudG90YWxfYnl0ZXNfaW4gPSBjb3VudGVyKCkKCQlzZWxmLnRvdGFsX2V4Y2VwdGlv
bnMgPSBjb3VudGVyKCkKCQkjCgkJYXN5bmNvcmUuZGlzcGF0Y2hlci5fX2luaXRfXyAoc2Vs
ZikKCQlzZWxmLmNyZWF0ZV9zb2NrZXQgKHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19T
VFJFQU0pCgoJCXNlbGYuc2V0X3JldXNlX2FkZHIoKQoJCXNlbGYuYmluZCAoKHNlbGYuaXAs
IHNlbGYucG9ydCkpCgkJc2VsZi5saXN0ZW4gKDUpCgoJCWlmIG5vdCBsb2dnZXJfb2JqZWN0
OgoJCQlsb2dnZXJfb2JqZWN0ID0gc3lzLnN0ZG91dAoKCQlpZiByZXNvbHZlcjoKCQkJc2Vs
Zi5sb2dnZXIgPSBsb2dnZXIucmVzb2x2aW5nX2xvZ2dlciAocmVzb2x2ZXIsIGxvZ2dlcl9v
YmplY3QpCgkJZWxzZToKCQkJc2VsZi5sb2dnZXIgPSBsb2dnZXIudW5yZXNvbHZpbmdfbG9n
Z2VyIChsb2dnZXJfb2JqZWN0KQoKCQlzZWxmLmxvZ19pbmZvKCdGVFAgc2VydmVyIHN0YXJ0
ZWQgYXQgJXNcblx0QXV0aG9yaXplcjolc1xuXHRIb3N0bmFtZTogJXNcblx0UG9ydDogJWQn
ICUgKAoJCQl0aW1lLmN0aW1lKHRpbWUudGltZSgpKSwKCQkJcmVwciAoc2VsZi5hdXRob3Jp
emVyKSwKCQkJc2VsZi5ob3N0bmFtZSwKCQkJc2VsZi5wb3J0KQoJCQkpCgoJZGVmIHdyaXRh
YmxlIChzZWxmKToKCQlyZXR1cm4gMAoKCWRlZiBoYW5kbGVfcmVhZCAoc2VsZik6CgkJcGFz
cwoKCWRlZiBoYW5kbGVfY29ubmVjdCAoc2VsZik6CgkJcGFzcwoKCWRlZiBoYW5kbGVfYWNj
ZXB0IChzZWxmKToKCQljb25uLCBhZGRyID0gc2VsZi5hY2NlcHQoKQoJCXNlbGYudG90YWxf
c2Vzc2lvbnMuaW5jcmVtZW50KCkKCQlzZWxmLmxvZ19pbmZvKCdJbmNvbWluZyBjb25uZWN0
aW9uIGZyb20gJXM6JWQnICUgKGFkZHJbMF0sIGFkZHJbMV0pKQoJCXNlbGYuZnRwX2NoYW5u
ZWxfY2xhc3MgKHNlbGYsIGNvbm4sIGFkZHIpCgoJIyByZXR1cm4gYSBwcm9kdWNlciBkZXNj
cmliaW5nIHRoZSBzdGF0ZSBvZiB0aGUgc2VydmVyCglkZWYgc3RhdHVzIChzZWxmKToKCgkJ
ZGVmIG5pY2VfYnl0ZXMgKG4pOgoJCQlyZXR1cm4gc3RyaW5nLmpvaW4gKHN0YXR1c19oYW5k
bGVyLmVuZ2xpc2hfYnl0ZXMgKG4pKQoKCQlyZXR1cm4gcHJvZHVjZXJzLmxpbmVzX3Byb2R1
Y2VyICgKCQkJWyc8aDI+JXM8L2gyPicJCQkJJSBzZWxmLlNFUlZFUl9JREVOVCwKCQkJICc8
YnI+TGlzdGVuaW5nIG9uIDxiPkhvc3Q6PC9iPiAlcycgJSBzZWxmLmhvc3RuYW1lLAoJCQkg
JzxiPlBvcnQ6PC9iPiAlZCcJCQklIHNlbGYucG9ydCwKCQkJICc8YnI+U2Vzc2lvbnMnLAoJ
CQkgJzxiPlRvdGFsOjwvYj4gJXMnCQkJJSBzZWxmLnRvdGFsX3Nlc3Npb25zLAoJCQkgJzxi
PkN1cnJlbnQ6PC9iPiAlZCcJCSUgKHNlbGYudG90YWxfc2Vzc2lvbnMuYXNfbG9uZygpIC0g
c2VsZi5jbG9zZWRfc2Vzc2lvbnMuYXNfbG9uZygpKSwKCQkJICc8YnI+RmlsZXMnLAoJCQkg
JzxiPlNlbnQ6PC9iPiAlcycJCQklIHNlbGYudG90YWxfZmlsZXNfb3V0LAoJCQkgJzxiPlJl
Y2VpdmVkOjwvYj4gJXMnCQklIHNlbGYudG90YWxfZmlsZXNfaW4sCgkJCSAnPGJyPkJ5dGVz
JywKCQkJICc8Yj5TZW50OjwvYj4gJXMnCQkJJSBuaWNlX2J5dGVzIChzZWxmLnRvdGFsX2J5
dGVzX291dC5hc19sb25nKCkpLAoJCQkgJzxiPlJlY2VpdmVkOjwvYj4gJXMnCQklIG5pY2Vf
Ynl0ZXMgKHNlbGYudG90YWxfYnl0ZXNfaW4uYXNfbG9uZygpKSwKCQkJICc8YnI+RXhjZXB0
aW9uczogJXMnCQklIHNlbGYudG90YWxfZXhjZXB0aW9ucywKCQkJIF0KCQkJKQoKIyA9PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09CiMJCQkJCQkgRGF0YSBDaGFubmVsIENsYXNzZXMKIyA9PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09CgojIFRoaXMgc29ja2V0IGFjY2VwdHMgYSBkYXRhIGNvbm5lY3Rpb24sIHVzZWQg
d2hlbiB0aGUgc2VydmVyIGhhcyBiZWVuCiMgcGxhY2VkIGluIHBhc3NpdmUgbW9kZS4gIEFs
dGhvdWdoIHRoZSBSRkMgaW1wbGllcyB0aGF0IHdlIG91Z2h0IHRvCiMgYmUgYWJsZSB0byB1
c2UgdGhlIHNhbWUgYWNjZXB0b3Igb3ZlciBhbmQgb3ZlciBhZ2FpbiwgdGhpcyBwcmVzZW50
cwojIGEgcHJvYmxlbTogaG93IGRvIHdlIHNodXQgaXQgb2ZmLCBzbyB0aGF0IHdlIGFyZSBh
Y2NlcHRpbmcKIyBjb25uZWN0aW9ucyBvbmx5IHdoZW4gd2UgZXhwZWN0IHRoZW0/ICBbd2Ug
Y2FuJ3RdCiMKIyB3dWZ0cGQsIGFuZCBwcm9iYWJseSBhbGwgdGhlIG90aGVyIHNlcnZlcnMs
IHNvbHZlIHRoaXMgYnkgYWxsb3dpbmcKIyBvbmx5IG9uZSBjb25uZWN0aW9uIHRvIGhpdCB0
aGlzIGFjY2VwdG9yLiAgVGhleSB0aGVuIGNsb3NlIGl0LiAgQW55CiMgc3Vic2VxdWVudCBk
YXRhLWNvbm5lY3Rpb24gY29tbWFuZCB3aWxsIHRoZW4gdHJ5IGZvciB0aGUgZGVmYXVsdAoj
IHBvcnQgb24gdGhlIGNsaWVudCBzaWRlIFt3aGljaCBpcyBvZiBjb3Vyc2UgbmV2ZXIgdGhl
cmVdLiAgU28gdGhlCiMgJ2Fsd2F5cy1zZW5kLVBPUlQvUEFTVicgYmVoYXZpb3Igc2VlbXMg
cmVxdWlyZWQuCiMKIyBBbm90aGVyIG5vdGU6IHd1ZnRwZCB3aWxsIGFsc28gYmUgbGlzdGVu
aW5nIG9uIHRoZSBjaGFubmVsIGFzIHNvb24KIyBhcyB0aGUgUEFTViBjb21tYW5kIGlzIHNl
bnQuICBJdCBkb2VzIG5vdCB3YWl0IGZvciBhIGRhdGEgY29tbWFuZAojIGZpcnN0LgoKIyAt
LS0gd2UgbmVlZCB0byBxdWV1ZSB1cCBhIHBhcnRpY3VsYXIgYmVoYXZpb3I6CiMgIDEpIHht
aXQgOiBxdWV1ZSB1cCBwcm9kdWNlcltzXQojICAyKSByZWN2IDogdGhlIGZpbGUgb2JqZWN0
CiMKIyBJdCB3b3VsZCBiZSBuaWNlIGlmIHdlIGNvdWxkIG1ha2UgYm90aCBjaGFubmVscyB0
aGUgc2FtZS4gIEhtbW0uLgojCgpjbGFzcyBwYXNzaXZlX2FjY2VwdG9yIChhc3luY29yZS5k
aXNwYXRjaGVyKToKCXJlYWR5ID0gTm9uZQoKCWRlZiBfX2luaXRfXyAoc2VsZiwgY29udHJv
bF9jaGFubmVsKToKCQkjIGNvbm5lY3RfZnVuIChjb25uLCBhZGRyKQoJCWFzeW5jb3JlLmRp
c3BhdGNoZXIuX19pbml0X18gKHNlbGYpCgkJc2VsZi5jb250cm9sX2NoYW5uZWwgPSBjb250
cm9sX2NoYW5uZWwKCQlzZWxmLmNyZWF0ZV9zb2NrZXQgKHNvY2tldC5BRl9JTkVULCBzb2Nr
ZXQuU09DS19TVFJFQU0pCgkJIyBiaW5kIHRvIGFuIGFkZHJlc3Mgb24gdGhlIGludGVyZmFj
ZSB0aGF0IHRoZQoJCSMgY29udHJvbCBjb25uZWN0aW9uIGlzIGNvbWluZyBmcm9tLgoJCXNl
bGYuYmluZCAoKAoJCQlzZWxmLmNvbnRyb2xfY2hhbm5lbC5nZXRzb2NrbmFtZSgpWzBdLAoJ
CQkwCgkJCSkpCgkJc2VsZi5hZGRyID0gc2VsZi5nZXRzb2NrbmFtZSgpCgkJc2VsZi5saXN0
ZW4gKDEpCgojCWRlZiBfX2RlbF9fIChzZWxmKToKIwkJcHJpbnQgJ3Bhc3NpdmVfYWNjZXB0
b3IuX19kZWxfXygpJwoKCWRlZiBsb2cgKHNlbGYsICppZ25vcmUpOgoJCXBhc3MKCglkZWYg
aGFuZGxlX2FjY2VwdCAoc2VsZik6CgkJY29ubiwgYWRkciA9IHNlbGYuYWNjZXB0KCkKCQlk
YyA9IHNlbGYuY29udHJvbF9jaGFubmVsLmNsaWVudF9kYwoJCWlmIGRjIGlzIG5vdCBOb25l
OgoJCQlkYy5zZXRfc29ja2V0IChjb25uKQoJCQlkYy5hZGRyID0gYWRkcgoJCQlkYy5jb25u
ZWN0ZWQgPSAxCgkJCXNlbGYuY29udHJvbF9jaGFubmVsLnBhc3NpdmVfYWNjZXB0b3IgPSBO
b25lCgkJZWxzZToKCQkJc2VsZi5yZWFkeSA9IGNvbm4sIGFkZHIKCQlzZWxmLmNsb3NlKCkK
CgpjbGFzcyB4bWl0X2NoYW5uZWwgKGFzeW5jaGF0LmFzeW5jX2NoYXQpOgoKCSMgZm9yIGFu
IGV0aGVybmV0LCB5b3Ugd2FudCB0aGlzIHRvIGJlIGZhaXJseSBsYXJnZSwgaW4gZmFjdCwg
aXQKCSMgX211c3RfIGJlIGxhcmdlIGZvciBwZXJmb3JtYW5jZSBjb21wYXJhYmxlIHRvIGFu
IGZ0cGQuICBbNjRrXSB3ZQoJIyBvdWdodCB0byBpbnZlc3RpZ2F0ZSBhdXRvbWF0aWNhbGx5
LXNpemVkIGJ1ZmZlcnMuLi4KCglhY19vdXRfYnVmZmVyX3NpemUgPSAxNjM4NAoJYnl0ZXNf
b3V0ID0gMAoKCWRlZiBfX2luaXRfXyAoc2VsZiwgY2hhbm5lbCwgY2xpZW50X2FkZHI9Tm9u
ZSk6CgkJc2VsZi5jaGFubmVsID0gY2hhbm5lbAoJCXNlbGYuY2xpZW50X2FkZHIgPSBjbGll
bnRfYWRkcgoJCWFzeW5jaGF0LmFzeW5jX2NoYXQuX19pbml0X18gKHNlbGYpCgkJCiMJZGVm
IF9fZGVsX18gKHNlbGYpOgojCQlwcmludCAneG1pdF9jaGFubmVsLl9fZGVsX18oKScKCglk
ZWYgbG9nICgqYXJncyk6CgkJcGFzcwoKCWRlZiByZWFkYWJsZSAoc2VsZik6CgkJcmV0dXJu
IG5vdCBzZWxmLmNvbm5lY3RlZAoKCWRlZiB3cml0YWJsZSAoc2VsZik6CgkJcmV0dXJuIDEK
CglkZWYgc2VuZCAoc2VsZiwgZGF0YSk6CgkJcmVzdWx0ID0gYXN5bmNoYXQuYXN5bmNfY2hh
dC5zZW5kIChzZWxmLCBkYXRhKQoJCXNlbGYuYnl0ZXNfb3V0ID0gc2VsZi5ieXRlc19vdXQg
KyByZXN1bHQKCQlyZXR1cm4gcmVzdWx0CgoJZGVmIGhhbmRsZV9lcnJvciAoc2VsZik6CgkJ
IyB1c3VhbGx5IHRoaXMgaXMgdG8gY2F0Y2ggYW4gdW5leHBlY3RlZCBkaXNjb25uZWN0LgoJ
CXNlbGYubG9nX2luZm8gKCd1bmV4cGVjdGVkIGRpc2Nvbm5lY3Qgb24gZGF0YSB4bWl0IGNo
YW5uZWwnLCAnZXJyb3InKQoJCXRyeToKCQkJc2VsZi5jbG9zZSgpCgkJZXhjZXB0OgoJCQlw
YXNzCgoJIyBUT0RPOiB0aGVyZSdzIGEgYmV0dGVyIHdheSB0byBkbyB0aGlzLiAgd2UgbmVl
ZCB0byBiZSBhYmxlIHRvCgkjIHB1dCAnZXZlbnRzJyBpbiB0aGUgcHJvZHVjZXIgZmlmby4g
IHRvIGRvIHRoaXMgY2xlYW5seSB3ZSBuZWVkCgkjIHRvIHJlcG9zaXRpb24gdGhlICdwcm9k
dWNlcicgZmlmbyBhcyBhbiAnZXZlbnQnIGZpZm8uCgoJZGVmIGNsb3NlIChzZWxmKToKCQlj
ID0gc2VsZi5jaGFubmVsCgkJcyA9IGMuc2VydmVyCgkJYy5jbGllbnRfZGMgPSBOb25lCgkJ
cy50b3RhbF9maWxlc19vdXQuaW5jcmVtZW50KCkKCQlzLnRvdGFsX2J5dGVzX291dC5pbmNy
ZW1lbnQgKHNlbGYuYnl0ZXNfb3V0KQoJCWlmIG5vdCBsZW4oc2VsZi5wcm9kdWNlcl9maWZv
KToKCQkJYy5yZXNwb25kICgnMjI2IFRyYW5zZmVyIGNvbXBsZXRlJykKCQllbGlmIG5vdCBj
LmNsb3NlZDoKCQkJYy5yZXNwb25kICgnNDI2IENvbm5lY3Rpb24gY2xvc2VkOyB0cmFuc2Zl
ciBhYm9ydGVkJykKCQlkZWwgYwoJCWRlbCBzCgkJZGVsIHNlbGYuY2hhbm5lbAoJCWFzeW5j
aGF0LmFzeW5jX2NoYXQuY2xvc2UgKHNlbGYpCgpjbGFzcyByZWN2X2NoYW5uZWwgKGFzeW5j
b3JlLmRpc3BhdGNoZXIpOgoJZGVmIF9faW5pdF9fIChzZWxmLCBjaGFubmVsLCBjbGllbnRf
YWRkciwgZmQpOgoJCXNlbGYuY2hhbm5lbCA9IGNoYW5uZWwKCQlzZWxmLmNsaWVudF9hZGRy
ID0gY2xpZW50X2FkZHIKCQlzZWxmLmZkID0gZmQKCQlhc3luY29yZS5kaXNwYXRjaGVyLl9f
aW5pdF9fIChzZWxmKQoJCXNlbGYuYnl0ZXNfaW4gPSBjb3VudGVyKCkKCglkZWYgbG9nIChz
ZWxmLCAqaWdub3JlKToKCQlwYXNzCgoJZGVmIGhhbmRsZV9jb25uZWN0IChzZWxmKToKCQlw
YXNzCgoJZGVmIHdyaXRhYmxlIChzZWxmKToKCQlyZXR1cm4gMAoKCWRlZiByZWN2ICgqYXJn
cyk6CgkJcmVzdWx0ID0gYXBwbHkgKGFzeW5jb3JlLmRpc3BhdGNoZXIucmVjdiwgYXJncykK
CQlzZWxmID0gYXJnc1swXQoJCXNlbGYuYnl0ZXNfaW4uaW5jcmVtZW50KGxlbihyZXN1bHQp
KQoJCXJldHVybiByZXN1bHQKCglidWZmZXJfc2l6ZSA9IDgxOTIKCglkZWYgaGFuZGxlX3Jl
YWQgKHNlbGYpOgoJCWJsb2NrID0gc2VsZi5yZWN2IChzZWxmLmJ1ZmZlcl9zaXplKQoJCWlm
IGJsb2NrOgoJCQl0cnk6CgkJCQlzZWxmLmZkLndyaXRlIChibG9jaykKCQkJZXhjZXB0IElP
RXJyb3I6CgkJCQlzZWxmLmxvZ19pbmZvICgnZ290IGV4Y2VwdGlvbiB3cml0aW5nIGJsb2Nr
Li4uJywgJ2Vycm9yJykKCglkZWYgaGFuZGxlX2Nsb3NlIChzZWxmKToKCQlzID0gc2VsZi5j
aGFubmVsLnNlcnZlcgoJCXMudG90YWxfZmlsZXNfaW4uaW5jcmVtZW50KCkKCQlzLnRvdGFs
X2J5dGVzX2luLmluY3JlbWVudChzZWxmLmJ5dGVzX2luLmFzX2xvbmcoKSkKCQlzZWxmLmZk
LmNsb3NlKCkKCQlzZWxmLmNoYW5uZWwucmVzcG9uZCAoJzIyNiBUcmFuc2ZlciBjb21wbGV0
ZS4nKQoJCXNlbGYuY2xvc2UoKQoKaW1wb3J0IGZpbGVzeXMKCiMgbm90IG11Y2ggb2YgYSBk
b29ybWFuISA4XikKY2xhc3MgZHVtbXlfYXV0aG9yaXplcjoKCWRlZiBfX2luaXRfXyAoc2Vs
Ziwgcm9vdD0nLycpOgoJCXNlbGYucm9vdCA9IHJvb3QKCWRlZiBhdXRob3JpemUgKHNlbGYs
IGNoYW5uZWwsIHVzZXJuYW1lLCBwYXNzd29yZCk6CgkJY2hhbm5lbC5wZXJzb25hID0gLTEs
IC0xCgkJY2hhbm5lbC5yZWFkX29ubHkgPSAxCgkJcmV0dXJuIDEsICdPay4nLCBmaWxlc3lz
Lm9zX2ZpbGVzeXN0ZW0gKHNlbGYucm9vdCkKCmNsYXNzIGFub25fYXV0aG9yaXplcjoKCWRl
ZiBfX2luaXRfXyAoc2VsZiwgcm9vdD0nLycpOgoJCXNlbGYucm9vdCA9IHJvb3QKCQkKCWRl
ZiBhdXRob3JpemUgKHNlbGYsIGNoYW5uZWwsIHVzZXJuYW1lLCBwYXNzd29yZCk6CgkJaWYg
dXNlcm5hbWUgaW4gKCdmdHAnLCAnYW5vbnltb3VzJyk6CgkJCWNoYW5uZWwucGVyc29uYSA9
IC0xLCAtMQoJCQljaGFubmVsLnJlYWRfb25seSA9IDEKCQkJcmV0dXJuIDEsICdPay4nLCBm
aWxlc3lzLm9zX2ZpbGVzeXN0ZW0gKHNlbGYucm9vdCkKCQllbHNlOgoJCQlyZXR1cm4gMCwg
J1Bhc3N3b3JkIGludmFsaWQuJywgTm9uZQoKIyA9PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIyBV
bml4LXNwZWNpZmljIGltcHJvdmVtZW50cwojID09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKaWYg
b3MubmFtZSA9PSAncG9zaXgnOgoKCWNsYXNzIHVuaXhfYXV0aG9yaXplcjoKCQkjIHJldHVy
biBhIHRyaW8gb2YgKHN1Y2Nlc3MsIHJlcGx5X3N0cmluZywgZmlsZXN5c3RlbSkKCQlkZWYg
YXV0aG9yaXplIChzZWxmLCBjaGFubmVsLCB1c2VybmFtZSwgcGFzc3dvcmQpOgoJCQlpbXBv
cnQgY3J5cHQKCQkJaW1wb3J0IHB3ZAoJCQl0cnk6CgkJCQlpbmZvID0gcHdkLmdldHB3bmFt
ICh1c2VybmFtZSkKCQkJZXhjZXB0IEtleUVycm9yOgoJCQkJcmV0dXJuIDAsICdObyBzdWNo
IHVzZXIuJywgTm9uZQoJCQltYW5nbGVkID0gaW5mb1sxXQoJCQlpZiBjcnlwdC5jcnlwdCAo
cGFzc3dvcmQsIG1hbmdsZWRbOjJdKSA9PSBtYW5nbGVkOgoJCQkJY2hhbm5lbC5yZWFkX29u
bHkgPSAwCgkJCQlmcyA9IGZpbGVzeXMuc2NoaXpvcGhyZW5pY191bml4X2ZpbGVzeXN0ZW0g
KAoJCQkJCScvJywKCQkJCQlpbmZvWzVdLAoJCQkJCXBlcnNvbmEgPSAoaW5mb1syXSwgaW5m
b1szXSkKCQkJCQkpCgkJCQlyZXR1cm4gMSwgJ0xvZ2luIHN1Y2Nlc3NmdWwuJywgZnMKCQkJ
ZWxzZToKCQkJCXJldHVybiAwLCAnUGFzc3dvcmQgaW52YWxpZC4nLCBOb25lCgoJCWRlZiBf
X3JlcHJfXyAoc2VsZik6CgkJCXJldHVybiAnPHN0YW5kYXJkIHVuaXggYXV0aG9yaXplcj4n
CgoJIyBzaW1wbGUgYW5vbnltb3VzIGZ0cCBzdXBwb3J0CgljbGFzcyB1bml4X2F1dGhvcml6
ZXJfd2l0aF9hbm9ueW1vdXMgKHVuaXhfYXV0aG9yaXplcik6CgkJZGVmIF9faW5pdF9fIChz
ZWxmLCByb290PU5vbmUsIHJlYWxfdXNlcnM9MCk6CgkJCXNlbGYucm9vdCA9IHJvb3QKCQkJ
c2VsZi5yZWFsX3VzZXJzID0gcmVhbF91c2VycwoKCQlkZWYgYXV0aG9yaXplIChzZWxmLCBj
aGFubmVsLCB1c2VybmFtZSwgcGFzc3dvcmQpOgoJCQlpZiBzdHJpbmcubG93ZXIodXNlcm5h
bWUpIGluIFsnYW5vbnltb3VzJywgJ2Z0cCddOgoJCQkJaW1wb3J0IHB3ZAoJCQkJdHJ5OgoJ
CQkJCSMgb2ssIGhlcmUgd2UgcnVuIGludG8gbG90cyBvZiBjb25mdXNpb24uCgkJCQkJIyBv
biBzb21lIG9zJywgYW5vbiBydW5zIHVuZGVyIHVzZXIgJ25vYm9keScsCgkJCQkJIyBvbiBv
dGhlcnMgYXMgJ2Z0cCcuICBvd25lcnNoaXAgaXMgYWxzbyBjcml0aWNhbC4KCQkJCQkjIG5l
ZWQgdG8gaW52ZXN0aWdhdGUuCgkJCQkJIyBsaW51eDogbmV3IGxpbnV4ZW4gc2VlbSB0byBo
YXZlIG5vYm9keSdzIFVJRD0tMSwKCQkJCQkjICAgIHdoaWNoIGlzIGFuIGlsbGVnYWwgdmFs
dWUuICBVc2UgZnRwLgoJCQkJCWZ0cF91c2VyX2luZm8gPSBwd2QuZ2V0cHduYW0gKCdmdHAn
KQoJCQkJCWlmIHN0cmluZy5sb3dlcihvcy51bmFtZSgpWzBdKSA9PSAnbGludXgnOgoJCQkJ
CQlub2JvZHlfdXNlcl9pbmZvID0gcHdkLmdldHB3bmFtICgnZnRwJykKCQkJCQllbHNlOgoJ
CQkJCQlub2JvZHlfdXNlcl9pbmZvID0gcHdkLmdldHB3bmFtICgnbm9ib2R5JykKCQkJCQlj
aGFubmVsLnJlYWRfb25seSA9IDEKCQkJCQlpZiBzZWxmLnJvb3QgaXMgTm9uZToKCQkJCQkJ
c2VsZi5yb290ID0gZnRwX3VzZXJfaW5mb1s1XQoJCQkJCWZzID0gZmlsZXN5cy51bml4X2Zp
bGVzeXN0ZW0gKHNlbGYucm9vdCwgJy8nKQoJCQkJCXJldHVybiAxLCAnQW5vbnltb3VzIExv
Z2luIFN1Y2Nlc3NmdWwnLCBmcwoJCQkJZXhjZXB0IEtleUVycm9yOgoJCQkJCXJldHVybiAw
LCAnQW5vbnltb3VzIGFjY291bnQgbm90IHNldCB1cCcsIE5vbmUKCQkJZWxpZiBzZWxmLnJl
YWxfdXNlcnM6CgkJCQlyZXR1cm4gdW5peF9hdXRob3JpemVyLmF1dGhvcml6ZSAoCgkJCQkJ
c2VsZiwKCQkJCQljaGFubmVsLAoJCQkJCXVzZXJuYW1lLAoJCQkJCXBhc3N3b3JkCgkJCQkJ
KQoJCQllbHNlOgoJCQkJcmV0dXJuIDAsICdVc2VyIGxvZ2lucyBub3QgYWxsb3dlZCcsIE5v
bmUKCmNsYXNzIGZpbGVfcHJvZHVjZXI6CglibG9ja19zaXplID0gMTYzODQKCWRlZiBfX2lu
aXRfXyAoc2VsZiwgc2VydmVyLCBkYywgZmQpOgoJCXNlbGYuZmQgPSBmZAoJCXNlbGYuZG9u
ZSA9IDAKCQkKCWRlZiBtb3JlIChzZWxmKToKCQlpZiBzZWxmLmRvbmU6CgkJCXJldHVybiAn
JwoJCWVsc2U6CgkJCWJsb2NrID0gc2VsZi5mZC5yZWFkIChzZWxmLmJsb2NrX3NpemUpCgkJ
CWlmIG5vdCBibG9jazoKCQkJCXNlbGYuZmQuY2xvc2UoKQoJCQkJc2VsZi5kb25lID0gMQoJ
CQlyZXR1cm4gYmxvY2sKCiMgdXNhZ2U6IGZ0cF9zZXJ2ZXIgL1BBVEgvVE8vRlRQL1JPT1Qg
UE9SVAojIGZvciBleGFtcGxlOgojICQgZnRwX3NlcnZlciAvaG9tZS91c2Vycy9mdHAgODAy
MQoKaWYgb3MubmFtZSA9PSAncG9zaXgnOgoJZGVmIHRlc3QgKHBvcnQ9JzgwMjEnKToKCQlp
bXBvcnQgc3lzCgkJZnMgPSBmdHBfc2VydmVyICgKCQkJdW5peF9hdXRob3JpemVyKCksCgkJ
CXBvcnQ9c3RyaW5nLmF0b2kgKHBvcnQpCgkJCSkKCQl0cnk6CgkJCWFzeW5jb3JlLmxvb3Ao
KQoJCWV4Y2VwdCBLZXlib2FyZEludGVycnVwdDoKCQkJc2VsZi5sb2dfaW5mbygnRlRQIHNl
cnZlciBzaHV0dGluZyBkb3duLiAocmVjZWl2ZWQgU0lHSU5UKScsICd3YXJuaW5nJykKCQkJ
IyBjbG9zZSBldmVyeXRoaW5nIGRvd24gb24gU0lHSU5ULgoJCQkjIG9mIGNvdXJzZSB0aGlz
IHNob3VsZCBiZSBhIGNsZWFuZXIgc2h1dGRvd24uCgkJCWFzeW5jb3JlLmNsb3NlX2FsbCgp
CgoJaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKCQl0ZXN0IChzeXMuYXJndlsxXSkKIyBu
b3QgdW5peAplbHNlOgoJZGVmIHRlc3QgKCk6CgkJZnMgPSBmdHBfc2VydmVyIChkdW1teV9h
dXRob3JpemVyKCkpCglpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgoJCXRlc3QgKCkKCiMg
dGhpcyBpcyB0aGUgY29tbWFuZCBsaXN0IGZyb20gdGhlIHd1ZnRwZCBtYW4gcGFnZQojICcq
JyBtZWFucyB3ZSd2ZSBpbXBsZW1lbnRlZCBpdC4KIyAnIScgcmVxdWlyZXMgd3JpdGUgYWNj
ZXNzCiMKY29tbWFuZF9kb2N1bWVudGF0aW9uID0gewoJJ2Fib3InOgknYWJvcnQgcHJldmlv
dXMgY29tbWFuZCcsCQkJCQkJCSMqCgknYWNjdCc6CSdzcGVjaWZ5IGFjY291bnQgKGlnbm9y
ZWQpJywKCSdhbGxvJzoJJ2FsbG9jYXRlIHN0b3JhZ2UgKHZhY3VvdXNseSknLAoJJ2FwcGUn
OgknYXBwZW5kIHRvIGEgZmlsZScsCQkJCQkJCQkJIyohCgknY2R1cCc6CSdjaGFuZ2UgdG8g
cGFyZW50IG9mIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnknLAkjKgoJJ2N3ZCc6CSdjaGFu
Z2Ugd29ya2luZyBkaXJlY3RvcnknLAkJCQkJCQkjKgoJJ2RlbGUnOgknZGVsZXRlIGEgZmls
ZScsCQkJCQkJCQkJIyEKCSdoZWxwJzoJJ2dpdmUgaGVscCBpbmZvcm1hdGlvbicsCQkJCQkJ
CSMqCgknbGlzdCc6CSdnaXZlIGxpc3QgZmlsZXMgaW4gYSBkaXJlY3RvcnknLAkJCQkJIyoK
CSdta2QnOgknbWFrZSBhIGRpcmVjdG9yeScsCQkJCQkJCQkJIyEKCSdtZHRtJzoJJ3Nob3cg
bGFzdCBtb2RpZmljYXRpb24gdGltZSBvZiBmaWxlJywJCQkJIyoKCSdtb2RlJzoJJ3NwZWNp
ZnkgZGF0YSB0cmFuc2ZlciBtb2RlJywKCSdubHN0JzoJJ2dpdmUgbmFtZSBsaXN0IG9mIGZp
bGVzIGluIGRpcmVjdG9yeScsCQkJCSMqCgknbm9vcCc6CSdkbyBub3RoaW5nJywJCQkJCQkJ
CQkJIyoKCSdwYXNzJzoJJ3NwZWNpZnkgcGFzc3dvcmQnLAkJCQkJCQkJCSMqCgkncGFzdic6
CSdwcmVwYXJlIGZvciBzZXJ2ZXItdG8tc2VydmVyIHRyYW5zZmVyJywJCQkjKgoJJ3BvcnQn
Ogknc3BlY2lmeSBkYXRhIGNvbm5lY3Rpb24gcG9ydCcsCQkJCQkJIyoKCSdwd2QnOgkncHJp
bnQgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnknLAkJCQkjKgoJJ3F1aXQnOgkndGVy
bWluYXRlIHNlc3Npb24nLAkJCQkJCQkJIyoKCSdyZXN0JzoJJ3Jlc3RhcnQgaW5jb21wbGV0
ZSB0cmFuc2ZlcicsCQkJCQkJIyoKCSdyZXRyJzoJJ3JldHJpZXZlIGEgZmlsZScsCQkJCQkJ
CQkJIyoKCSdybWQnOgkncmVtb3ZlIGEgZGlyZWN0b3J5JywJCQkJCQkJCSMhCgkncm5mcic6
CSdzcGVjaWZ5IHJlbmFtZS1mcm9tIGZpbGUgbmFtZScsCQkJCQkjIQoJJ3JudG8nOgknc3Bl
Y2lmeSByZW5hbWUtdG8gZmlsZSBuYW1lJywJCQkJCQkjIQoJJ3NpdGUnOgknbm9uLXN0YW5k
YXJkIGNvbW1hbmRzIChzZWUgbmV4dCBzZWN0aW9uKScsCgknc2l6ZSc6CSdyZXR1cm4gc2l6
ZSBvZiBmaWxlJywJCQkJCQkJCSMqCgknc3RhdCc6CSdyZXR1cm4gc3RhdHVzIG9mIHNlcnZl
cicsCQkJCQkJCSMqCgknc3Rvcic6CSdzdG9yZSBhIGZpbGUnLAkJCQkJCQkJCQkjKiEKCSdz
dG91JzoJJ3N0b3JlIGEgZmlsZSB3aXRoIGEgdW5pcXVlIG5hbWUnLAkJCQkJIyEKCSdzdHJ1
JzoJJ3NwZWNpZnkgZGF0YSB0cmFuc2ZlciBzdHJ1Y3R1cmUnLAoJJ3N5c3QnOgknc2hvdyBv
cGVyYXRpbmcgc3lzdGVtIHR5cGUgb2Ygc2VydmVyIHN5c3RlbScsCQkjKgoJJ3R5cGUnOgkn
c3BlY2lmeSBkYXRhIHRyYW5zZmVyIHR5cGUnLAkJCQkJCSMqCgkndXNlcic6CSdzcGVjaWZ5
IHVzZXIgbmFtZScsCQkJCQkJCQkjKgoJJ3hjdXAnOgknY2hhbmdlIHRvIHBhcmVudCBvZiBj
dXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IChkZXByZWNhdGVkKScsCgkneGN3ZCc6CSdjaGFu
Z2Ugd29ya2luZyBkaXJlY3RvcnkgKGRlcHJlY2F0ZWQpJywKCSd4bWtkJzoJJ21ha2UgYSBk
aXJlY3RvcnkgKGRlcHJlY2F0ZWQpJywJCQkJCSMhCgkneHB3ZCc6CSdwcmludCB0aGUgY3Vy
cmVudCB3b3JraW5nIGRpcmVjdG9yeSAoZGVwcmVjYXRlZCknLAoJJ3hybWQnOgkncmVtb3Zl
IGEgZGlyZWN0b3J5IChkZXByZWNhdGVkKScsCQkJCQkjIQp9CgoKIyBkZWJ1Z2dpbmcgYWlk
IChsaW51eCkKZGVmIGdldF92bV9zaXplICgpOgoJcmV0dXJuIHN0cmluZy5hdG9pIChzdHJp
bmcuc3BsaXQob3BlbiAoJy9wcm9jL3NlbGYvc3RhdCcpLnJlYWRsaW5lKCkpWzIyXSkKCmRl
ZiBwcmludF92bSgpOgoJcHJpbnQgJ3ZtOiAlOGRrJyAlIChnZXRfdm1fc2l6ZSgpLzEwMjQp
Cg==
--------------CF3F10DD56A7538D09BE4E14--