Transaction executed successfully
Transaction Details
Inspect execution, participants, message data, gas usage, events and raw transaction data.
Transaction hash
86009E6A0DEB866DB977FA93D8B53FE4973348C99D884F9C44097F4183CCBDAC
Transaction overview
Execution summary
TX INDEX
1
Position in block
GAS WANTED
90,000,000
Requested gas limit
GAS USED
55,928,771
Gas consumed
FEE
180000ugnot
Transaction fee
Participants
Message
Message #1
m_addpkg
Arguments
g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf14000000ugnot
Execution log
msg:0,success:true,log:,events:[]
Events
No events emitted by this transaction.
Raw encoded transaction
CvuyAgoML3ZtLm1fYWRkcGtnEumyAgooZzEzNmowbTA4cGttMmx3d2RlOWRtbHg4dWVlMjZsbGVudDlzNWNwZhKssgIKDW1lbWJhX2ZlZWRfdjESIGduby5sYW5kL3Ivc2FtY3Jldy9tZW1iYV9mZWVkX3YxGkcKC2dub21vZC50b21sEjhtb2R1bGUgPSAiZ25vLmxhbmQvci9zYW1jcmV3L21lbWJhX2ZlZWRfdjEiCmdubyA9ICIwLjkiChq1AQoUZ292ZXJuYW5jZV9yZWFkcy5nbm8SnAFwYWNrYWdlIG1lbWJhX2ZlZWRfdjEKCi8vIEdldE1vZGVyYXRvckNvdW50IGV4cG9zZXMgdGhlIGV4YWN0IGdyYW50IGNvdW50IGZvciBEQU8gcG9zdGNvbmRpdGlvbnMuCmZ1bmMgR2V0TW9kZXJhdG9yQ291bnQoKSBpbnQgeyByZXR1cm4gbW9kZXJhdG9ycy5TaXplKCkgfQoa0q8CChFtZW1iYV9mZWVkX3YxLmdubxK7rwJwYWNrYWdlIG1lbWJhX2ZlZWRfdjEKCi8vIG1lbWJhX2ZlZWRfdjEg4oCUIEdsb2JhbCBzb2NpYWwgZmVlZCByZWFsbSBmb3IgTWVtYmEgKFc3LjIgUDApLgovLwovLyBPUEVOLVdSSVRFOiBhbnkgd2FsbGV0IG1heSBwb3N0LiBUaGlzIGludmVydHMgZXZlcnkgYXNzdW1wdGlvbiBvZiB0aGUKLy8gREFPLXNjb3BlZCBtZW1iYV9kYW9fY2hhbm5lbHNfdjIgKG1lbWJlcnMtb25seSwgMjAgY2hhbm5lbHMgLyA1MDAgdGhyZWFkcyksCi8vIHNvIHRoZSByZWFsbSBpcyBORVcg4oCUIHdoYXQgaXMgcG9ydGVkIFZFUkJBVElNIGZyb20gY2hhbm5lbHNfdjIgaXMgaXRzCi8vIGhhcmRlbmluZyBkaXNjaXBsaW5lOgovLwovLyAgIEIxIHJlbmRlci1Eb1MgYm91bmRzIOKAlCByZWFkcyBORVZFUiBpdGVyYXRlIHRoZSBtb25vdG9uaWMgbmV4dFBvc3RJRC4KLy8gICAgIExpdmUgKHZpc2libGUpIHBvc3RzIGFyZSB0cmFja2VkIGluIGRlZGljYXRlZCBBVkwgaW5kZXhlcyBhbmQgZXZlcnkKLy8gICAgIHJlYWQgcGF0aCBpcyBwYWdpbmF0ZWQgdG8gYSBmaXhlZCB3aW5kb3cuIGNoYW5uZWxzX3YyIHVzZWQgW111aW50NjQKLy8gICAgIHNsaWNlcyAoc2FmZSB1bmRlciBpdHMgNTAwLXBlci1jaGFubmVsIGNhcCk7IGFuIG9wZW4gZmVlZCBpcyB1bmJvdW5kZWQsCi8vICAgICBzbyB0aGUgbGl2ZSBpbmRleGVzIGhlcmUgYXJlIGNvbXBvc2l0ZS1rZXkgQVZMIHRyZWVzIGluc3RlYWQg4oCUCi8vICAgICBPKGxvZyBuKSBpbnNlcnQvcmVtb3ZlLCBPKHBhZ2UpIHNjYW4sIG5vIHNpbmdsZSBub2RlIHRoYXQgZ3Jvd3MgZm9yZXZlci4KLy8gICBCMiBzdGF0ZS1zaHJpbmsg4oCUIGF1dGhvciBkZWxldGVzIHNvZnQtZGVsZXRlICsgZW5xdWV1ZSBhIHRvbWJzdG9uZTsKLy8gICAgIFN3ZWVwVG9tYnN0b25lcyBoYXJkLXJlbW92ZXMgbm9kZXMgKGJvdW5kZWQsIHBlcm1pc3Npb25sZXNzIEdDKS4KLy8gICBCMyBwYXVzZSBwb2xpY3kg4oCUIGV2ZXJ5IHVzZXItZmFjaW5nIHdyaXRlIGlzIGJsb2NrZWQgd2hpbGUgcGF1c2VkOwovLyAgICAgb3duZXIvbW9kZXJhdGlvbiBzdGF5cyBvcGVyYXRpb25hbCAobm8gZnVuZHMgaW4gdGhpcyByZWFsbSkuCi8vICAgRmxhZyBwaXBlbGluZSDigJQgb25lIGZsYWcgcGVyIGFkZHJlc3MgcGVyIHBvc3QsIHRocmVzaG9sZCBhdXRvLWhpZGUuCi8vICAgICBPcGVuIHdyaXRlIGludml0ZXMgYnJpZ2FkaW5nLCBzbyB0aGUgdGhyZXNob2xkIGlzIGhpZ2hlciB0aGFuCi8vICAgICBjaGFubmVsc192MidzIDMgYW5kIGZsYWdnaW5nIGlzIGZ1cnRoZXIgZ2F0ZWQgYnkgYWNjb3VudCBhZ2UgYW5kIGEKLy8gICAgIHBlci1kYXkgZmxhZyBidWRnZXQuCi8vCi8vIEFudGktc3BhbSAob3BlbiB3cml0ZSBoYXMgbm8gbWVtYmVyc2hpcCBnYXRlIHRvIGxlYW4gb24pOgovLyAgIC0gcGVyLWFkZHJlc3MgYmxvY2sgY29vbGRvd24gYmV0d2VlbiBwb3N0cywgc3RyaWN0ZXIgZm9yIGFjY291bnRzIGZpcnN0Ci8vICAgICBzZWVuIGZld2VyIHRoYW4gWW91bmdBY2NvdW50QmxvY2tzIGFnbzsKLy8gICAtIGJvZHkgbGVuZ3RoIGNhcDsgbWVkaWEgQ0lEIGNvdW50IGNhcCAoQ0lEcyBzdG9yZWQgb24tY2hhaW4gb25seSDigJQKLy8gICAgIHBpbm5pbmcvc2VydmluZyBpcyB0aGUgYmFja2VuZCdzIFBpbk1lZGlhIHBpcGVsaW5lLCBQMikuCi8vCi8vIFJlYWRzOiBleHBvcnRlZCAqSlNPTiBmdW5jcyB2aWEgUlBDIHZtL3FldmFsIOKAlCBjdXJzb3ItcGFnaW5hdGVkLCBPKGxpbWl0KQovLyBhdCBhbnkgZGVwdGggKHRoZSBhcHAgcmVhZHMgZnJvbSB0aGUgaW5kZXhlcjsgdGhlc2UgYXJlIHRoZSBmYWxsYmFjaykuCi8vIFJlbmRlcigpIGlzIHRoZSBodW1hbiBnbm93ZWIgdmlldzogYm91bmRlZCBwYWdlcyB3aXRoIGEgaGFyZCBkZXB0aCBjYXAKLy8gKE1heFJlbmRlclBhZ2UpIOKAlCBkZWVwIGhpc3RvcnkgYmVsb25ncyB0byB0aGUgY3Vyc29yIEFQSSwgbm90IHFyZW5kZXIuCi8vCi8vIE1vZGVyYXRpb24gUDA6IHJlYWxtIG93bmVyIG9ubHkgKE1vZFJlbW92ZVBvc3QgLyBVbmhpZGVQb3N0IC8gQmFuQXV0aG9yIGlzCi8vIFc4LjIncyBtb2RlcmF0aW9uIGJvYXJkIHZpYSBhIGRhb2tpdCBtb2RlcmF0b3Igcm9sZSDigJQgcC9zYW1jcmV3L21vZGJvYXJkKS4KLy8gRXZlcnkgbW9kZXJhdGlvbiBhY3Rpb24gZW1pdHMgZm9yIHB1YmxpYyBhdWRpdC4KLy8KLy8gVGhpcyByZWFsbSBob2xkcyBOTyBmdW5kczogbm8gYmFua2VyLCBubyBPcmlnaW5TZW5kLCBubyBmZWUgbGFuZS4gQSBmdXR1cmUKLy8gdGlwcGluZyBsYW5lIGlzIGEgc2VwYXJhdGUgU0FGRVRZX0dBVEVEIGZsYWcgKyBmZWUtc3BpbmUgbGFuZSAiZmVlZCIuCgppbXBvcnQgKAoJInN0cmNvbnYiCgkic3RyaW5ncyIKCgkiZ25vLmxhbmQvcC9zYW1jcmV3L2F2bCIKCSJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgoJImNoYWluIgoJImNoYWluL3J1bnRpbWUiCgkiY2hhaW4vcnVudGltZS91bnNhZmUiCikKCi8vIOKUgOKUgCBDb25zdGFudHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgpjb25zdCAoCglNYXhCb2R5TGVuICAgPSAxMDAwIC8vIHBvc3QgYm9keSAocm9hZG1hcCA0LjEpCglNYXhNZWRpYUNJRHMgPSA0ICAgIC8vIHN0b3JlZCBwZXIgcG9zdDsgcGluL3NlcnZlIHBpcGVsaW5lIGlzIFAyCglNYXhDSURMZW4gICAgPSAxMjggIC8vIGRlZmVuc2l2ZSBjYXAgb24gYSBzaW5nbGUgQ0lEIHN0cmluZwoKCUZlZWRQYWdlU2l6ZSAgPSAyMCAgLy8gcG9zdHMgcGVyIHJlbmRlcmVkIHBhZ2UgLyBkZWZhdWx0IEpTT04gd2luZG93CglNYXhQYWdlTGltaXQgID0gMTAwIC8vIGhhcmQgY2FwIG9uIGFueSBKU09OIHJlYWQgd2luZG93IChEb1MgZ3VhcmQpCglNYXhSZW5kZXJQYWdlID0gNTAgIC8vIGRlZXBlc3QgZ25vd2ViIHBhZ2U7IGJleW9uZCDihpIgdXNlIHRoZSBjdXJzb3IgQVBJCgoJLy8gQjEgcmVwbHkgYm91bmQgKG1pcnJvcnMgY2hhbm5lbHNfdjIncyBNYXhSZXBsaWVzUGVyVGhyZWFkKS4gQ2FwcyB0aGUKCS8vIExJVkUgcmVwbHkgc2V0IHBlciBwb3N0IHNvIChhKSB0aGUgYnlQYXJlbnQgaW5kZXggdW5kZXIgYW55IG9uZSBwYXJlbnQgaXMKCS8vIGJvdW5kZWQsIGFuZCAoYikgU3dlZXBUb21ic3RvbmVzIGNhbiByYW5nZS1kZWxldGUgYSBzd2VwdCBwYXJlbnQncyByZXBseQoJLy8gbGlua3MgaW4gYm91bmRlZCB3b3JrLiBEZWxldGluZyBhIHJlcGx5IGZyZWVzIGEgc2xvdC4KCU1heFJlcGxpZXNQZXJQb3N0ID0gNTAwCgoJLy8gRmxhZyBwaXBlbGluZS4gY2hhbm5lbHNfdjIgYXV0by1oaWRlcyBhdCAzIG1lbWJlciBmbGFnczsgdGhlIGZlZWQgaXMKCS8vIG9wZW4td3JpdGUsIHNvIHRoZSB0aHJlc2hvbGQgc3RhcnRzIGhpZ2hlciBhbmQgZmxhZ2dpbmcgaXMgcmF0ZS1saW1pdGVkLgoJLy8gVGhlc2UgYXJlIGRhbXBpbmcga25vYnMsIG5vdCBhIGJyaWdhZGUtcHJvb2YgZ2F0ZTogNSBhZ2VkIHN5YmlscyBjYW4KCS8vIHN0aWxsIGhpZGUgYSBwb3N0ICh0aGUgYWdlIGdhdGUgaXMgb25lIHBvc3QgKyBhIG9uZS10aW1lIHdhaXQsIGZhcm1hYmxlCgkvLyBpbiBwYXJhbGxlbCkuIFRoZXkgcmFpc2UgdGhlIGNvc3QgYW5kIHNsb3cgY29vcmRpbmF0aW9uOyBnZW51aW5lIGJyaWdhZGUKCS8vIHJlc2lzdGFuY2UgaXMgdGhlIFc4LjIgbW9kZXJhdGlvbiBib2FyZCAocmV2ZXJzaWJsZSBtb2QgYWN0aW9ucyArIGF1ZGl0KS4KCS8vIEFsbCBhcmUgZ292ZXJuYW5jZS10dW5hYmxlIHBvc3QtZGVwbG95IHZpYSBhIGZ1dHVyZSByZWFsbSB2ZXJzaW9uOyB0aGV5CgkvLyBhcmUgY29uc3RhbnRzIGhlcmUgc28gdGhlIGFkdmVyc2FyaWFsIHRlc3RzIHBpbiB0aGVpciBiZWhhdmlvci4KCUZsYWdUaHJlc2hvbGQgICAgICAgID0gNSAgICAgLy8gdW5pcXVlIGZsYWdzIGJlZm9yZSBhdXRvLWhpZGUKCU1pbkFjY291bnRBZ2VGb3JGbGFnID0gMTIwMCAgLy8gYmxvY2tzIHNpbmNlIGZpcnN0IHBvc3QgKH4xLTJoKQoJRmxhZ3NQZXJEYXlCdWRnZXQgICAgPSAxMCAgICAvLyBwZXIgYWRkcmVzcyBwZXIgQmxvY2tzUGVyRGF5IHdpbmRvdwoJQmxvY2tzUGVyRGF5ICAgICAgICAgPSAxNzI4MCAvLyB+NXMgYmxvY2tzOyBhcHByb3hpbWF0aW9uIGlzIGZpbmUKCgkvLyBQb3N0aW5nIGNvb2xkb3ducyAoYmxvY2tzKS4gWW91bmcgYWNjb3VudHMgKGZpcnN0IHNlZW4gPCBZb3VuZ0FjY291bnRCbG9ja3MKCS8vIGFnbykgd2FpdCBsb25nZXIgYmV0d2VlbiBwb3N0cyDigJQgY2hlYXAgc3liaWwgdGhyb3R0bGUuCglNaW5Qb3N0SW50ZXJ2YWxCbG9ja3MgICAgICA9IDIKCVlvdW5nTWluUG9zdEludGVydmFsQmxvY2tzID0gMTIKCVlvdW5nQWNjb3VudEJsb2NrcyAgICAgICAgID0gMTcyODAgLy8gZmlyc3QgfmRheQopCgovLyDilIDilIAgVHlwZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgp0eXBlIFBvc3Qgc3RydWN0IHsKCUlEICAgICAgICB1aW50NjQKCUF1dGhvciAgICBhZGRyZXNzCglCb2R5ICAgICAgc3RyaW5nCglNZWRpYUNJRHMgW11zdHJpbmcgLy8gSVBGUyBDSURzIG9ubHk7IHNlcnZpbmcgZ29lcyB0aHJvdWdoIHRoZSBiYWNrZW5kIHByb3h5CglSZXBseVRvICAgdWludDY0ICAgLy8gMCA9IHRvcC1sZXZlbAoJUmVwb3N0T2YgIHVpbnQ2NCAgIC8vIDAgPSBvcmlnaW5hbCAoZW50cnlwb2ludCBsYW5kcyBpbiBQMTsgZmllbGQgaXMgc2NoZW1hLXN0YWJsZSkKCUJsb2NrSCAgICBpbnQ2NAoJRWRpdGVkQXQgIGludDY0IC8vIGJsb2NrIGhlaWdodCBvZiBsYXN0IGVkaXQgKDAgPSBuZXZlcikKCUZsYWdDb3VudCBpbnQKCUhpZGRlbiAgICBib29sIC8vIGZsYWcgYXV0by1oaWRlIG9yIG1vZGVyYXRpb24gaGlkZQoJRGVsZXRlZCAgIGJvb2wgLy8gYXV0aG9yIHRvbWJzdG9uZSAoYXdhaXRpbmcgU3dlZXBUb21ic3RvbmVzIGhhcmQtR0MpCn0KCnR5cGUgZmxhZ0J1ZGdldCBzdHJ1Y3QgewoJRGF5U3RhcnRIIGludDY0CglVc2VkICAgICAgaW50Cn0KCi8vIOKUgOKUgCBTdGF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCnZhciAoCglwb3N0cyAqYXZsLlRyZWUgLy8gcGFkSUQoaWQpIC0+ICpQb3N0IChsaXZlICsgaGlkZGVuICsgbm90LXlldC1zd2VwdCB0b21ic3RvbmVzKQoKCS8vIExpdmUgaW5kZXhlcyAoQjEpOiBPTkxZIHZpc2libGUgKG5vdCBoaWRkZW4sIG5vdCBkZWxldGVkKSBwb3N0cy4KCS8vIEV2ZXJ5IHJlYWQgcGF0aCBpdGVyYXRlcyBvbmUgb2YgdGhlc2Ug4oCUIG5ldmVyIGBwb3N0c2AsIG5ldmVyIG5leHRQb3N0SUQuCglsaXZlRmVlZCAgICphdmwuVHJlZSAvLyBwYWRJRChpZCkgLT4gdHJ1ZQoJYnlBdXRob3IgICAqYXZsLlRyZWUgLy8gYXV0aG9yICsgIjoiICsgcGFkSUQoaWQpIC0+IHRydWUKCWJ5UGFyZW50ICAgKmF2bC5UcmVlIC8vIHBhZElEKHBhcmVudCkgKyAiOiIgKyBwYWRJRChjaGlsZCkgLT4gdHJ1ZQoJbGl2ZUNvdW50ICB1aW50NjQgICAgLy8gbnVtYmVyIG9mIGtleXMgaW4gbGl2ZUZlZWQKCXJlcGx5Q291bnQgKmF2bC5UcmVlIC8vIHBhZElEKHBhcmVudCkgLT4gdWludDY0IChsaXZlIHJlcGxpZXMpCgoJbmV4dFBvc3RJRCB1aW50NjQgLy8gbW9ub3RvbmljOyBORVZFUiBpdGVyYXRlZCBieSByZWFkcwoKCS8vIEFudGktc3BhbSAvIGZsYWcgc3RhdGUuCglsYXN0UG9zdEggICphdmwuVHJlZSAvLyBhZGRyIC0+IGludDY0IChsYXN0IENyZWF0ZVBvc3QgaGVpZ2h0KQoJZmlyc3RTZWVuSCAqYXZsLlRyZWUgLy8gYWRkciAtPiBpbnQ2NCAoZmlyc3Qgd3JpdGUgaW50ZXJhY3Rpb24gaGVpZ2h0KQoJZmxhZ3MgICAgICAqYXZsLlRyZWUgLy8gcGFkSUQoaWQpIC0+ICphdmwuVHJlZSAoZmxhZ2dlciBhZGRyIC0+IHRydWUpCglmbGFnU3BlbmQgICphdmwuVHJlZSAvLyBhZGRyIC0+ICpmbGFnQnVkZ2V0CgoJLy8gUmVhY3Rpb25zIChvbmUtcGVyLWVtb2ppIHRvZ2dsZSkuIHBhZElEKGlkKSAtPiAqYXZsLlRyZWUga2V5ZWQgYnkKCS8vIHJlYWN0aW9uU3ViS2V5KGVtb2ppLCBhZGRyKSAtPiB0cnVlLiBFbmZvcmNlcyBwZXItKHBvc3QsZW1vamksYWRkcikKCS8vIHVuaXF1ZW5lc3Mgb24tY2hhaW47IHBlci1lbW9qaSBDT1VOVFMgYXJlIGFnZ3JlZ2F0ZWQgb2ZmLWNoYWluIGJ5IHRoZQoJLy8gaW5kZXhlciBmcm9tIFJlYWN0aW9uQWRkZWQvUmVhY3Rpb25SZW1vdmVkIChubyB1bmJvdW5kZWQgb24tY2hhaW4gc2NhbiDigJQKCS8vIEIxIHJlbmRlciBib3VuZHMgaG9sZDsgYSBob3QgcG9zdCdzIHJlYWN0aW9uIHNldCBpcyBuZXZlciBpdGVyYXRlZCBoZXJlKS4KCXJlYWN0aW9ucyAqYXZsLlRyZWUKCgkvLyBTb2Z0LWRlbGV0ZWQgcG9zdCBJRHMgYXdhaXRpbmcgaGFyZC1HQyAoQjIpLiBBbiBBVkwgdHJlZSAobm90IGEgc2xpY2UpOgoJLy8gYSBzbGljZSByZS1zZXJpYWxpemVzIHdob2xlc2FsZSBvbiBldmVyeSBlbnF1ZXVlLCBzbyBwb3N0K2RlbGV0ZSBzcGFtCgkvLyB3b3VsZCBpbmZsYXRlIHRoZSBnYXMgb2YgZXZlcnkgd3JpdGUgdG91Y2hpbmcgaXQgKGEgc2xvdyB3cml0ZS1wYXRoIERvUykuCgkvLyBUaGUgdHJlZSBnaXZlcyBPKGxvZyBuKSBlbnF1ZXVlIGFuZCBsZXRzIHRoZSBzd2VlcCBkcmFpbiBhIGJvdW5kZWQKCS8vIGFzY2VuZGluZyB3aW5kb3cgd2l0aG91dCByZXdyaXRpbmcgdGhlIGJhY2tsb2cuCgl0b21ic3RvbmVzICphdmwuVHJlZSAvLyBwYWRJRChpZCkgLT4gdHJ1ZQoKCS8vIE1vZGVyYXRvciBzZXQgKFc4LjIpOiBvd25lci1ncmFudGVkIGFkZHJlc3NlcyB0aGF0IGNhbiBNb2RSZW1vdmVQb3N0IC8KCS8vIFVuaGlkZVBvc3QgV0lUSE9VVCBvd25lci1tdWx0aXNpZy1wZXItcG9zdCDigJQgZmFzdCwgcmV2ZXJzaWJsZSBtb2RlcmF0aW9uLgoJLy8gR3JhbnRpbmcvcmV2b2tpbmcgc3RheXMgb3duZXItb25seS4gYWRkciAtPiB0cnVlLgoJbW9kZXJhdG9ycyAqYXZsLlRyZWUKCglwYXVzZWQgYm9vbAoJLy8gb3duZXIgaXMgdGhlIHB1Ymxpc2hpbmcgdHJhbnNhY3Rpb24ncyBzaWduZXIsIGNhcHR1cmVkIGF0IHBhY2thZ2UgbG9hZAoJLy8gKG9uIGdub2xhbmQtMSB0aGUgc2FtY3JldyBuYW1lc3BhY2UgbXVsdGlzaWcsIHRoZSBzdGFtcGVkIGNyZWF0b3IgYXQgZW5hYmxlCgkvLyB0aW1lKSDigJQgc2FtZSBwYXR0ZXJuIGFzIGNoYW5uZWxzX3YyLiBwZW5kaW5nT3duZXIgaXMgdGhlIHN0YWdlZCBzdWNjZXNzb3Igb2YKCS8vIGEgdHdvLXN0ZXAgaGFuZG9mZiwgb3IgZW1wdHkuCglvd25lciAgICAgICAgPSB1bnNhZmUuT3JpZ2luQ2FsbGVyKCkKCXBlbmRpbmdPd25lciBhZGRyZXNzCikKCmZ1bmMgaW5pdCgpIHsKCXBvc3RzID0gYXZsLk5ld1RyZWUoKQoJbGl2ZUZlZWQgPSBhdmwuTmV3VHJlZSgpCglieUF1dGhvciA9IGF2bC5OZXdUcmVlKCkKCWJ5UGFyZW50ID0gYXZsLk5ld1RyZWUoKQoJcmVwbHlDb3VudCA9IGF2bC5OZXdUcmVlKCkKCWxhc3RQb3N0SCA9IGF2bC5OZXdUcmVlKCkKCWZpcnN0U2VlbkggPSBhdmwuTmV3VHJlZSgpCglmbGFncyA9IGF2bC5OZXdUcmVlKCkKCWZsYWdTcGVuZCA9IGF2bC5OZXdUcmVlKCkKCXJlYWN0aW9ucyA9IGF2bC5OZXdUcmVlKCkKCW1vZGVyYXRvcnMgPSBhdmwuTmV3VHJlZSgpCgl0b21ic3RvbmVzID0gYXZsLk5ld1RyZWUoKQoJbmV4dFBvc3RJRCA9IDEKfQoKLy8g4pSA4pSAIEhlbHBlcnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgovLyBwYWRJRCB6ZXJvLXBhZHMgdG8gMTIgZGlnaXRzIHNvIEFWTCBzdHJpbmcgb3JkZXIgPT0gbnVtZXJpYyBvcmRlci4KLy8gMTIgZGlnaXRzIOKJpSAzMSwwMDAgeWVhcnMgb2Ygb25lIHBvc3QgcGVyIGJsb2NrIOKAlCBlZmZlY3RpdmVseSB1bmJvdW5kZWQuCmZ1bmMgcGFkSUQoaWQgdWludDY0KSBzdHJpbmcgewoJcyA6PSBzdHJjb252LkZvcm1hdFVpbnQoaWQsIDEwKQoJZm9yIGxlbihzKSA8IDEyIHsKCQlzID0gIjAiICsgcwoJfQoJcmV0dXJuIHMKfQoKZnVuYyBnZXRQb3N0KGlkIHVpbnQ2NCkgKCpQb3N0LCBib29sKSB7Cgl2LCBvayA6PSBwb3N0cy5HZXQocGFkSUQoaWQpKQoJaWYgIW9rIHsKCQlyZXR1cm4gbmlsLCBmYWxzZQoJfQoJcmV0dXJuIHYuKCpQb3N0KSwgdHJ1ZQp9CgpmdW5jIG11c3RHZXRQb3N0KGlkIHVpbnQ2NCkgKlBvc3QgewoJcCwgb2sgOj0gZ2V0UG9zdChpZCkKCWlmICFvayB7CgkJcGFuaWMoInBvc3Qgbm90IGZvdW5kOiAiICsgc3RyY29udi5Gb3JtYXRVaW50KGlkLCAxMCkpCgl9CglyZXR1cm4gcAp9CgpmdW5jIGF1dGhvcktleShhZGRyIGFkZHJlc3MsIGlkIHVpbnQ2NCkgc3RyaW5nIHsgcmV0dXJuIGFkZHIuU3RyaW5nKCkgKyAiOiIgKyBwYWRJRChpZCkgfQpmdW5jIHBhcmVudEtleShwYXJlbnQsIGNoaWxkIHVpbnQ2NCkgc3RyaW5nICAgIHsgcmV0dXJuIHBhZElEKHBhcmVudCkgKyAiOiIgKyBwYWRJRChjaGlsZCkgfQoKZnVuYyBnZXRSZXBseUNvdW50KHBhcmVudCB1aW50NjQpIHVpbnQ2NCB7CglpZiB2LCBvayA6PSByZXBseUNvdW50LkdldChwYWRJRChwYXJlbnQpKTsgb2sgewoJCXJldHVybiB2Lih1aW50NjQpCgl9CglyZXR1cm4gMAp9CgovLyBhZGRUb0xpdmVJbmRleGVzIHJlZ2lzdGVycyBhIHZpc2libGUgcG9zdCBpbiBldmVyeSBsaXZlIGluZGV4IChCMSkuCi8vCi8vIEEgcmVwbHkgaXMgb25seSBsaW5rZWQgaW50byBpdHMgcGFyZW50J3MgYnlQYXJlbnQvcmVwbHlDb3VudCBpbmRleGVzIHdoZW4gdGhlCi8vIHBhcmVudCBpcyBzdGlsbCBMSVZFLiBPbiBDcmVhdGVQb3N0IHRoZSBwYXJlbnQgd2FzIGp1c3QgdmVyaWZpZWQgbGl2ZSwgc28gdGhpcwovLyBpcyBhbHdheXMgdHJ1ZSB0aGVyZS4gVGhlIGd1YXJkIG1hdHRlcnMgb24gdGhlIFVuaGlkZVBvc3QgcmUtYWRkIHBhdGg6IGlmIHRoZQovLyBwYXJlbnQgd2FzIGRlbGV0ZWQrc3dlcHQgd2hpbGUgdGhlIHJlcGx5IHNhdCBoaWRkZW4sIHJlLWxpbmtpbmcgd291bGQgcmVjcmVhdGUKLy8gYW4gb3JwaGFuIGJ5UGFyZW50L3JlcGx5Q291bnQgZW50cnkgdW5kZXIgYSBwYXJlbnQgaWQgbm8gbG9uZ2VyIGluIGBwb3N0c2AKLy8gKG5ldmVyIHN3ZWVwYWJsZSBhZ2Fpbikg4oCUIHRoZSBleGFjdCBsZWFrIFN3ZWVwVG9tYnN0b25lcycgYnlQYXJlbnQtcHJlZml4Ci8vIGNsZWFudXAgd2FzIGFkZGVkIHRvIHByZXZlbnQuIEFuIHVuaGlkZGVuIHJlcGx5IHdob3NlIHBhcmVudCBpcyBnb25lIHNpbXBseQovLyBiZWNvbWVzIHN0YW5kYWxvbmUgbGl2ZSBjb250ZW50LCB3aGljaCBpcyBob3cgYSByZXBseSB0byBhIHJlbW92ZWQgcGFyZW50IGlzCi8vIGFscmVhZHkgdHJlYXRlZCBldmVyeXdoZXJlIGVsc2UuCmZ1bmMgYWRkVG9MaXZlSW5kZXhlcyhwICpQb3N0KSB7CglsaXZlRmVlZC5TZXQocGFkSUQocC5JRCksIHRydWUpCglieUF1dGhvci5TZXQoYXV0aG9yS2V5KHAuQXV0aG9yLCBwLklEKSwgdHJ1ZSkKCWxpdmVDb3VudCsrCglpZiBwLlJlcGx5VG8gIT0gMCAmJiBsaXZlRmVlZC5IYXMocGFkSUQocC5SZXBseVRvKSkgewoJCWJ5UGFyZW50LlNldChwYXJlbnRLZXkocC5SZXBseVRvLCBwLklEKSwgdHJ1ZSkKCQlyZXBseUNvdW50LlNldChwYWRJRChwLlJlcGx5VG8pLCBnZXRSZXBseUNvdW50KHAuUmVwbHlUbykrMSkKCX0KfQoKLy8gcmVtb3ZlRnJvbUxpdmVJbmRleGVzIGRyb3BzIGEgcG9zdCBmcm9tIGV2ZXJ5IGxpdmUgaW5kZXggKGhpZGUvZGVsZXRlKS4KZnVuYyByZW1vdmVGcm9tTGl2ZUluZGV4ZXMocCAqUG9zdCkgewoJaWYgXywgb2sgOj0gbGl2ZUZlZWQuR2V0KHBhZElEKHAuSUQpKTsgIW9rIHsKCQlyZXR1cm4gLy8gYWxyZWFkeSBpbnZpc2libGUgKGUuZy4gZGVsZXRlIGFmdGVyIGF1dG8taGlkZSkKCX0KCWxpdmVGZWVkLlJlbW92ZShwYWRJRChwLklEKSkKCWJ5QXV0aG9yLlJlbW92ZShhdXRob3JLZXkocC5BdXRob3IsIHAuSUQpKQoJaWYgbGl2ZUNvdW50ID4gMCB7CgkJbGl2ZUNvdW50LS0KCX0KCWlmIHAuUmVwbHlUbyAhPSAwIHsKCQlieVBhcmVudC5SZW1vdmUocGFyZW50S2V5KHAuUmVwbHlUbywgcC5JRCkpCgkJaWYgcmMgOj0gZ2V0UmVwbHlDb3VudChwLlJlcGx5VG8pOyByYyA+IDAgewoJCQlyZXBseUNvdW50LlNldChwYWRJRChwLlJlcGx5VG8pLCByYy0xKQoJCX0KCX0KfQoKZnVuYyBhc3NlcnROb3RQYXVzZWQoKSB7CglpZiBwYXVzZWQgewoJCXBhbmljKCJyZWFsbSBpcyBwYXVzZWQg4oCUIGVtZXJnZW5jeSBtYWludGVuYW5jZSIpCgl9Cn0KCmZ1bmMgYXNzZXJ0Q2FsbGVySXNPd25lcigpIHsKCWNhbGxlciA6PSB1bnNhZmUuUHJldmlvdXNSZWFsbSgpLkFkZHJlc3MoKQoJaWYgY2FsbGVyICE9IG93bmVyIHsKCQlwYW5pYygidW5hdXRob3JpemVkOiBjYWxsZXIgIiArIGNhbGxlci5TdHJpbmcoKSArICIgaXMgbm90IHRoZSBvd25lciIpCgl9Cn0KCi8vIHRvdWNoRmlyc3RTZWVuIHJlY29yZHMgdGhlIGZpcnN0IHdyaXRlIGludGVyYWN0aW9uIGhlaWdodCBmb3IgYW4gYWRkcmVzcy4KZnVuYyB0b3VjaEZpcnN0U2VlbihhZGRyIGFkZHJlc3MsIGggaW50NjQpIHsKCWlmIF8sIG9rIDo9IGZpcnN0U2VlbkguR2V0KGFkZHIuU3RyaW5nKCkpOyAhb2sgewoJCWZpcnN0U2VlbkguU2V0KGFkZHIuU3RyaW5nKCksIGgpCgl9Cn0KCmZ1bmMgYWNjb3VudEFnZShhZGRyIGFkZHJlc3MsIG5vdyBpbnQ2NCkgaW50NjQgewoJaWYgdiwgb2sgOj0gZmlyc3RTZWVuSC5HZXQoYWRkci5TdHJpbmcoKSk7IG9rIHsKCQlyZXR1cm4gbm93IC0gdi4oaW50NjQpCgl9CglyZXR1cm4gMAp9CgovLyDilIDilIAgRW1lcmdlbmN5IHBhdXNlIChCMyDigJQgb25lIHBvbGljeSwgZW5mb3JjZWQgZXZlcnl3aGVyZSkg4pSA4pSA4pSACi8vIFdoaWxlIHBhdXNlZCBldmVyeSB1c2VyLWZhY2luZyBjb250ZW50IHdyaXRlIGlzIGJsb2NrZWQuIE93bmVyIG1vZGVyYXRpb24KLy8gYW5kIHBhdXNlIG1hbmFnZW1lbnQgc3RheSBsaXZlOiBwYXVzZSBoYWx0cyB1c2VyIGFjdGl2aXR5IGR1cmluZyBhbgovLyBpbmNpZGVudCwgYnV0IHRoZSBvd25lciBtdXN0IHN0YXkgYWJsZSB0byBhY3QuIE5vIGZ1bmRzIGhlcmUsIHNvIHRoZXJlIGlzCi8vIG5vIHZhbHVlLWV4aXQgZXhlbXB0aW9uIHRvIGNhcnZlIG91dC4KCmZ1bmMgUGF1c2VSZWFsbShjdXIgcmVhbG0pIHsKCWFzc2VydENhbGxlcklzT3duZXIoKQoJcGF1c2VkID0gdHJ1ZQoJY2hhaW4uRW1pdCgiUmVhbG1QYXVzZWQiLCAiYnkiLCBvd25lci5TdHJpbmcoKSkKfQoKZnVuYyBVbnBhdXNlUmVhbG0oY3VyIHJlYWxtKSB7Cglhc3NlcnRDYWxsZXJJc093bmVyKCkKCXBhdXNlZCA9IGZhbHNlCgljaGFpbi5FbWl0KCJSZWFsbVVucGF1c2VkIiwgImJ5Iiwgb3duZXIuU3RyaW5nKCkpCn0KCmZ1bmMgSXNQYXVzZWQoKSBib29sIHsgcmV0dXJuIHBhdXNlZCB9CgovLyBUcmFuc2Zlck93bmVyc2hpcCBzdGFnZXMgYSBzdWNjZXNzb3Igb3duZXIuIE5vdGhpbmcgbW92ZXMgdW50aWwgdGhhdCBhZGRyZXNzCi8vIGNhbGxzIEFjY2VwdE93bmVyc2hpcCB3aXRoIGl0cyBvd24gdHJhbnNhY3Rpb24sIHNvIG93bmVyc2hpcCBjYW4gbmV2ZXIgbGFuZCBvbgovLyBhbiBhZGRyZXNzIHRoYXQgY2Fubm90IGFjdC4gQSBsYXRlciBjYWxsIHJlcGxhY2VzIHRoZSBzdGFnZWQgYWRkcmVzczsKLy8gQ2FuY2VsT3duZXJzaGlwVHJhbnNmZXIgd2l0aGRyYXdzIGl0LgpmdW5jIFRyYW5zZmVyT3duZXJzaGlwKGN1ciByZWFsbSwgbmV3T3duZXIgYWRkcmVzcykgewoJYXNzZXJ0Q2FsbGVySXNPd25lcigpCglpZiBuZXdPd25lciA9PSAiIiB7CgkJcGFuaWMoImFkZHJlc3MgY2Fubm90IGJlIGVtcHR5IikKCX0KCWlmICFuZXdPd25lci5Jc1ZhbGlkKCkgewoJCXBhbmljKCJpbnZhbGlkIGFkZHJlc3M6ICIgKyBuZXdPd25lci5TdHJpbmcoKSkKCX0KCWlmIG5ld093bmVyID09IG93bmVyIHsKCQlwYW5pYygibmV3IG93bmVyIGlzIHRoZSBzYW1lIGFzIGN1cnJlbnQgb3duZXIiKQoJfQoJcGVuZGluZ093bmVyID0gbmV3T3duZXIKCWNoYWluLkVtaXQoIk93bmVyc2hpcFRyYW5zZmVyU3RhcnRlZCIsICJwZW5kaW5nIiwgbmV3T3duZXIuU3RyaW5nKCkpCn0KCi8vIENhbmNlbE93bmVyc2hpcFRyYW5zZmVyIHdpdGhkcmF3cyBhIHN0YWdlZCBoYW5kb2ZmLiBPd25lciBvbmx5LgpmdW5jIENhbmNlbE93bmVyc2hpcFRyYW5zZmVyKGN1ciByZWFsbSkgewoJYXNzZXJ0Q2FsbGVySXNPd25lcigpCglpZiBwZW5kaW5nT3duZXIgPT0gIiIgewoJCXBhbmljKCJubyBwZW5kaW5nIG93bmVyc2hpcCB0cmFuc2ZlciIpCgl9CgljYW5jZWxsZWQgOj0gcGVuZGluZ093bmVyCglwZW5kaW5nT3duZXIgPSAiIgoJY2hhaW4uRW1pdCgiT3duZXJzaGlwVHJhbnNmZXJDYW5jZWxsZWQiLCAicGVuZGluZyIsIGNhbmNlbGxlZC5TdHJpbmcoKSkKfQoKLy8gQWNjZXB0T3duZXJzaGlwIGNvbXBsZXRlcyB0aGUgaGFuZG9mZi4gT25seSB0aGUgc3RhZ2VkIHBlbmRpbmdPd25lciBtYXkgY2FsbCBpdC4KZnVuYyBBY2NlcHRPd25lcnNoaXAoY3VyIHJlYWxtKSB7CglpZiAhY3VyLklzQ3VycmVudCgpIHsKCQlwYW5pYygic3Bvb2ZlZCByZWFsbSIpCgl9CgljYWxsZXIgOj0gY3VyLlByZXZpb3VzKCkuQWRkcmVzcygpCglpZiBwZW5kaW5nT3duZXIgPT0gIiIgfHwgY2FsbGVyICE9IHBlbmRpbmdPd25lciB7CgkJcGFuaWMoInVuYXV0aG9yaXplZDogY2FsbGVyICIgKyBjYWxsZXIuU3RyaW5nKCkgKyAiIGlzIG5vdCB0aGUgcGVuZGluZyBvd25lciIpCgl9CglwcmV2IDo9IG93bmVyCglvd25lciA9IGNhbGxlcgoJcGVuZGluZ093bmVyID0gIiIKCWNoYWluLkVtaXQoIk93bmVyc2hpcFRyYW5zZmVycmVkIiwKCQkicHJldmlvdXNPd25lciIsIHByZXYuU3RyaW5nKCksCgkJIm5ld093bmVyIiwgY2FsbGVyLlN0cmluZygpLAoJKQp9CgovLyBHZXRPd25lciByZXR1cm5zIHRoZSBjdXJyZW50IHJlYWxtIG93bmVyIGFkZHJlc3MuCmZ1bmMgR2V0T3duZXIoKSBhZGRyZXNzIHsgcmV0dXJuIG93bmVyIH0KCi8vIEdldFBlbmRpbmdPd25lciByZXR1cm5zIHRoZSBzdGFnZWQgc3VjY2Vzc29yLCBvciB0aGUgZW1wdHkgYWRkcmVzcy4KZnVuYyBHZXRQZW5kaW5nT3duZXIoKSBhZGRyZXNzIHsgcmV0dXJuIHBlbmRpbmdPd25lciB9CgovLyDilIDilIAgV3JpdGVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAoKLy8gQ3JlYXRlUG9zdCBwdWJsaXNoZXMgYSBwb3N0IChyZXBseVRvID09IDApIG9yIGEgcmVwbHkgKHJlcGx5VG8gPT0gcGFyZW50IGlkKS4KLy8gT3BlbiB3cml0ZTogYW55IHdhbGxldCwgc3ViamVjdCB0byB0aGUgYmxvY2sgY29vbGRvd24gYW5kIGJvZHkgY2Fwcy4KLy8gUmV0dXJucyB0aGUgbmV3IHBvc3QgaWQuCmZ1bmMgQ3JlYXRlUG9zdChjdXIgcmVhbG0sIGJvZHkgc3RyaW5nLCByZXBseVRvIHVpbnQ2NCkgdWludDY0IHsKCWFzc2VydE5vdFBhdXNlZCgpCgljYWxsZXIgOj0gdW5zYWZlLlByZXZpb3VzUmVhbG0oKS5BZGRyZXNzKCkKCW5vdyA6PSBydW50aW1lLkNoYWluSGVpZ2h0KCkKCgkvLyBDb29sZG93biBCRUZPUkUgdG91Y2hpbmcgc3RhdGU6IHlvdW5nIGFjY291bnRzIHdhaXQgbG9uZ2VyLgoJdG91Y2hGaXJzdFNlZW4oY2FsbGVyLCBub3cpCglpbnRlcnZhbCA6PSBpbnQ2NChNaW5Qb3N0SW50ZXJ2YWxCbG9ja3MpCglpZiBhY2NvdW50QWdlKGNhbGxlciwgbm93KSA8IFlvdW5nQWNjb3VudEJsb2NrcyB7CgkJaW50ZXJ2YWwgPSBZb3VuZ01pblBvc3RJbnRlcnZhbEJsb2NrcwoJfQoJaWYgdiwgb2sgOj0gbGFzdFBvc3RILkdldChjYWxsZXIuU3RyaW5nKCkpOyBvayB7CgkJaWYgbm93LXYuKGludDY0KSA8IGludGVydmFsIHsKCQkJcGFuaWModWZtdC5TcHJpbnRmKCJwb3N0aW5nIHRvbyBmYXN0OiB3YWl0ICVkIGJsb2NrcyBiZXR3ZWVuIHBvc3RzIiwgaW50ZXJ2YWwpKQoJCX0KCX0KCglpZiBsZW4oYm9keSkgPT0gMCB8fCBsZW4oYm9keSkgPiBNYXhCb2R5TGVuIHsKCQlwYW5pYyh1Zm10LlNwcmludGYoImJvZHkgbXVzdCBiZSAxLSVkIGNoYXJhY3RlcnMiLCBNYXhCb2R5TGVuKSkKCX0KCgl2YXIgcGFyZW50ICpQb3N0CglpZiByZXBseVRvICE9IDAgewoJCXBhcmVudCA9IG11c3RHZXRQb3N0KHJlcGx5VG8pCgkJaWYgcGFyZW50LkRlbGV0ZWQgewoJCQlwYW5pYygiY2Fubm90IHJlcGx5IHRvIGEgZGVsZXRlZCBwb3N0IikKCQl9CgkJaWYgcGFyZW50LkhpZGRlbiB7CgkJCXBhbmljKCJjYW5ub3QgcmVwbHkgdG8gYSBoaWRkZW4gcG9zdCIpCgkJfQoJCS8vIEIxOiBib3VuZCB0aGUgTElWRSByZXBseSBzZXQgc28gdGhlIGJ5UGFyZW50IGluZGV4IHVuZGVyIG9uZSBwYXJlbnQKCQkvLyBzdGF5cyBib3VuZGVkIChhbmQgYSBzd2VwdCBwYXJlbnQncyBsaW5rIGNsZWFudXAgc3RheXMgYm91bmRlZCkuCgkJaWYgZ2V0UmVwbHlDb3VudChyZXBseVRvKSA+PSBNYXhSZXBsaWVzUGVyUG9zdCB7CgkJCXBhbmljKHVmbXQuU3ByaW50ZigicmVwbHkgbGltaXQgcmVhY2hlZDogJWQgcGVyIHBvc3QiLCBNYXhSZXBsaWVzUGVyUG9zdCkpCgkJfQoJfQoKCWlkIDo9IG5leHRQb3N0SUQKCW5leHRQb3N0SUQrKwoKCXAgOj0gJlBvc3R7CgkJSUQ6ICAgICAgaWQsCgkJQXV0aG9yOiAgY2FsbGVyLAoJCUJvZHk6ICAgIGJvZHksCgkJUmVwbHlUbzogcmVwbHlUbywKCQlCbG9ja0g6ICBub3csCgl9Cglwb3N0cy5TZXQocGFkSUQoaWQpLCBwKQoJYWRkVG9MaXZlSW5kZXhlcyhwKQoJbGFzdFBvc3RILlNldChjYWxsZXIuU3RyaW5nKCksIG5vdykKCgljaGFpbi5FbWl0KCJQb3N0Q3JlYXRlZCIsCgkJInBvc3RJZCIsIHN0cmNvbnYuRm9ybWF0VWludChpZCwgMTApLAoJCSJhdXRob3IiLCBjYWxsZXIuU3RyaW5nKCksCgkJInJlcGx5VG8iLCBzdHJjb252LkZvcm1hdFVpbnQocmVwbHlUbywgMTApLAoJCSJib2R5IiwgYm9keSwKCSkKCXJldHVybiBpZAp9CgovLyBFZGl0UG9zdCBsZXRzIHRoZSBhdXRob3IgcmVwbGFjZSB0aGUgYm9keSBvZiBhIHZpc2libGUgcG9zdC4KZnVuYyBFZGl0UG9zdChjdXIgcmVhbG0sIGlkIHVpbnQ2NCwgbmV3Qm9keSBzdHJpbmcpIHsKCWFzc2VydE5vdFBhdXNlZCgpCgljYWxsZXIgOj0gdW5zYWZlLlByZXZpb3VzUmVhbG0oKS5BZGRyZXNzKCkKCglwIDo9IG11c3RHZXRQb3N0KGlkKQoJaWYgcC5BdXRob3IgIT0gY2FsbGVyIHsKCQlwYW5pYygib25seSB0aGUgYXV0aG9yIGNhbiBlZGl0IikKCX0KCWlmIHAuRGVsZXRlZCB7CgkJcGFuaWMoImNhbm5vdCBlZGl0IGEgZGVsZXRlZCBwb3N0IikKCX0KCWlmIHAuSGlkZGVuIHsKCQlwYW5pYygiY2Fubm90IGVkaXQgYSBoaWRkZW4gcG9zdCIpCgl9CglpZiBsZW4obmV3Qm9keSkgPT0gMCB8fCBsZW4obmV3Qm9keSkgPiBNYXhCb2R5TGVuIHsKCQlwYW5pYyh1Zm10LlNwcmludGYoImJvZHkgbXVzdCBiZSAxLSVkIGNoYXJhY3RlcnMiLCBNYXhCb2R5TGVuKSkKCX0KCglwLkJvZHkgPSBuZXdCb2R5CglwLkVkaXRlZEF0ID0gcnVudGltZS5DaGFpbkhlaWdodCgpCglwb3N0cy5TZXQocGFkSUQoaWQpLCBwKQoKCWNoYWluLkVtaXQoIlBvc3RFZGl0ZWQiLAoJCSJwb3N0SWQiLCBzdHJjb252LkZvcm1hdFVpbnQoaWQsIDEwKSwKCQkiYXV0aG9yIiwgY2FsbGVyLlN0cmluZygpLAoJCSJib2R5IiwgbmV3Qm9keSwKCSkKfQoKLy8gRGVsZXRlUG9zdCBzb2Z0LWRlbGV0ZXMgdGhlIGF1dGhvcidzIG93biBwb3N0OiBjb250ZW50IGNsZWFyZWQsIGRyb3BwZWQgZnJvbQovLyBldmVyeSBsaXZlIGluZGV4IChmcmVlcyByZW5kZXIgc2xvdHMgaW1tZWRpYXRlbHkg4oCUIEIxKSwgcXVldWVkIGZvciBoYXJkLUdDCi8vIChCMikuIFJlcGxpZXMgc3RheTogdGhleSByZW5kZXIgYXMgcmVwbGllcyB0byBhbiB1bmF2YWlsYWJsZSBwb3N0LgpmdW5jIERlbGV0ZVBvc3QoY3VyIHJlYWxtLCBpZCB1aW50NjQpIHsKCWFzc2VydE5vdFBhdXNlZCgpCgljYWxsZXIgOj0gdW5zYWZlLlByZXZpb3VzUmVhbG0oKS5BZGRyZXNzKCkKCglwIDo9IG11c3RHZXRQb3N0KGlkKQoJaWYgcC5BdXRob3IgIT0gY2FsbGVyIHsKCQlwYW5pYygib25seSB0aGUgYXV0aG9yIGNhbiBkZWxldGUiKQoJfQoJaWYgcC5EZWxldGVkIHsKCQlwYW5pYygicG9zdCBhbHJlYWR5IGRlbGV0ZWQiKQoJfQoKCXJlbW92ZUZyb21MaXZlSW5kZXhlcyhwKQoJcC5EZWxldGVkID0gdHJ1ZQoJcC5Cb2R5ID0gIiIKCXAuTWVkaWFDSURzID0gbmlsCglwb3N0cy5TZXQocGFkSUQoaWQpLCBwKQoJdG9tYnN0b25lcy5TZXQocGFkSUQoaWQpLCB0cnVlKQoKCWNoYWluLkVtaXQoIlBvc3REZWxldGVkIiwKCQkicG9zdElkIiwgc3RyY29udi5Gb3JtYXRVaW50KGlkLCAxMCksCgkJImF1dGhvciIsIGNhbGxlci5TdHJpbmcoKSwKCSkKfQoKLy8g4pSA4pSAIEZsYWcgcGlwZWxpbmUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgovLyBGbGFnUG9zdCBmaWxlcyBhIGNvbW11bml0eSBmbGFnLiBHdWFyZHMsIGluIG9yZGVyOgovLyAgIC0gZmxhZyByaWdodHMgYXJlIEVBUk5FRCBCWSBQQVJUSUNJUEFUSU9OOiB0aGUgY2FsbGVyIG11c3QgaGF2ZSBhCi8vICAgICBmaXJzdFNlZW4gcmVjb3JkIChhbmNob3JlZCBieSB0aGVpciBmaXJzdCBzdWNjZXNzZnVsIENyZWF0ZVBvc3QpIGF0Ci8vICAgICBsZWFzdCBNaW5BY2NvdW50QWdlRm9yRmxhZyBibG9ja3Mgb2xkLiBBIGZhaWxlZCBmbGFnIGNhbm5vdCBhbmNob3IgYWdlCi8vICAgICBpdHNlbGYg4oCUIGFuIG9uLWNoYWluIGFib3J0IHJldmVydHMgZXZlcnkgd3JpdGUgaW4gdGhlIHR4LCBzbyByZWNvcmRpbmcKLy8gICAgIGZpcnN0U2VlbiBoZXJlIGFuZCB0aGVuIHBhbmlja2luZyB3b3VsZCByZXZlcnQgdGhlIHJlY29yZCBhbmQgZGVhZGxvY2sKLy8gICAgIHB1cmUgZmxhZ2dlcnM7IHJlcXVpcmluZyBhIHByaW9yIHBvc3QgaXMgdGhlIGhvbmVzdCwgaW1wbGVtZW50YWJsZQovLyAgICAgYWNjb3VudC1hZ2UgZ2F0ZSAocmVhbG1zIGNhbm5vdCBxdWVyeSBnbG9iYWwgYWNjb3VudCBhZ2UpOwovLyAgIC0gb25lIGZsYWcgcGVyIGFkZHJlc3MgcGVyIHBvc3Q7Ci8vICAgLSBwZXItZGF5IGZsYWcgYnVkZ2V0IHBlciBhZGRyZXNzIChibHVudHMgY29vcmRpbmF0ZWQgZmxhZy1icmlnYWRlcykuCi8vCi8vIEF0IEZsYWdUaHJlc2hvbGQgdW5pcXVlIGZsYWdzIHRoZSBwb3N0IGF1dG8taGlkZXMgKHJldmVyc2libGUgdmlhIFVuaGlkZVBvc3QpLgpmdW5jIEZsYWdQb3N0KGN1ciByZWFsbSwgaWQgdWludDY0KSB7Cglhc3NlcnROb3RQYXVzZWQoKQoJY2FsbGVyIDo9IHVuc2FmZS5QcmV2aW91c1JlYWxtKCkuQWRkcmVzcygpCglub3cgOj0gcnVudGltZS5DaGFpbkhlaWdodCgpCgoJaWYgYWNjb3VudEFnZShjYWxsZXIsIG5vdykgPCBNaW5BY2NvdW50QWdlRm9yRmxhZyB7CgkJcGFuaWModWZtdC5TcHJpbnRmKCJmbGFnZ2luZyByZXF1aXJlcyBoYXZpbmcgcG9zdGVkIGF0IGxlYXN0ICVkIGJsb2NrcyBhZ28iLCBNaW5BY2NvdW50QWdlRm9yRmxhZykpCgl9CgoJcCA6PSBtdXN0R2V0UG9zdChpZCkKCWlmIHAuRGVsZXRlZCB7CgkJcGFuaWMoImNhbm5vdCBmbGFnIGEgZGVsZXRlZCBwb3N0IikKCX0KCWlmIHAuSGlkZGVuIHsKCQlwYW5pYygicG9zdCBpcyBhbHJlYWR5IGhpZGRlbiIpCgl9CgoJLy8gUGVyLWRheSBidWRnZXQgd2luZG93LgoJdmFyIGZiICpmbGFnQnVkZ2V0CglpZiB2LCBvayA6PSBmbGFnU3BlbmQuR2V0KGNhbGxlci5TdHJpbmcoKSk7IG9rIHsKCQlmYiA9IHYuKCpmbGFnQnVkZ2V0KQoJfSBlbHNlIHsKCQlmYiA9ICZmbGFnQnVkZ2V0e0RheVN0YXJ0SDogbm93fQoJfQoJaWYgbm93LWZiLkRheVN0YXJ0SCA+PSBCbG9ja3NQZXJEYXkgewoJCWZiLkRheVN0YXJ0SCA9IG5vdwoJCWZiLlVzZWQgPSAwCgl9CglpZiBmYi5Vc2VkID49IEZsYWdzUGVyRGF5QnVkZ2V0IHsKCQlwYW5pYyh1Zm10LlNwcmludGYoImRhaWx5IGZsYWcgYnVkZ2V0IHJlYWNoZWQ6ICVkIHBlciAlZCBibG9ja3MiLCBGbGFnc1BlckRheUJ1ZGdldCwgQmxvY2tzUGVyRGF5KSkKCX0KCgkvLyBVbmlxdWUgZmxhZ2dlcnMgcGVyIHBvc3QuCgl2YXIgZmxhZ1RyZWUgKmF2bC5UcmVlCglpZiB2LCBvayA6PSBmbGFncy5HZXQocGFkSUQoaWQpKTsgb2sgewoJCWZsYWdUcmVlID0gdi4oKmF2bC5UcmVlKQoJfSBlbHNlIHsKCQlmbGFnVHJlZSA9IGF2bC5OZXdUcmVlKCkKCX0KCWlmIF8sIGFscmVhZHkgOj0gZmxhZ1RyZWUuR2V0KGNhbGxlci5TdHJpbmcoKSk7IGFscmVhZHkgewoJCXBhbmljKCJhbHJlYWR5IGZsYWdnZWQiKQoJfQoJZmxhZ1RyZWUuU2V0KGNhbGxlci5TdHJpbmcoKSwgdHJ1ZSkKCWZsYWdzLlNldChwYWRJRChpZCksIGZsYWdUcmVlKQoKCWZiLlVzZWQrKwoJZmxhZ1NwZW5kLlNldChjYWxsZXIuU3RyaW5nKCksIGZiKQoKCXAuRmxhZ0NvdW50ID0gZmxhZ1RyZWUuU2l6ZSgpCgl3YXNIaWRkZW4gOj0gcC5IaWRkZW4KCWlmIHAuRmxhZ0NvdW50ID49IEZsYWdUaHJlc2hvbGQgewoJCXAuSGlkZGVuID0gdHJ1ZQoJCXJlbW92ZUZyb21MaXZlSW5kZXhlcyhwKQoJCS8vIEEgZmxhZy1oaWRkZW4gcG9zdCBpcyBkZWxpYmVyYXRlbHkgTk9UIHRvbWJzdG9uZWQ6IGl0cyBub2RlIGFuZCBpdHMKCQkvLyBgZmxhZ3NgIHN1YnRyZWUgKHRoZSBmbGFnZ2VyIHNldCkgYXJlIHJldGFpbmVkIG9uIHB1cnBvc2UgYXMgdGhlIGF1ZGl0CgkJLy8gdHJhaWwgdGhlIFc4LjIgbW9kZXJhdGlvbiBib2FyZCByZXZpZXdzIChhbmQgVW5oaWRlUG9zdCBuZWVkcywgdG8KCQkvLyByZXZlcnNlIGEgYnJpZ2FkZSkuIEl0IGxlYXZlcyB0aGUgbGl2ZSBpbmRleGVzIChCMSByZW5kZXIgYm91bmRzIHN0aWxsCgkJLy8gaG9sZCksIHNvIHRoaXMgaXMgYm91bmRlZCwgaW50ZW50aW9uYWwgcmV0ZW50aW9uIOKAlCBub3QgYSBsZWFrLiBBdXRob3IKCQkvLyBkZWxldGUgLyBtb2QtcmVtb3ZlIGFyZSB0aGUgcGF0aHMgdGhhdCB0b21ic3RvbmUgZm9yIEdDLgoJfQoJcG9zdHMuU2V0KHBhZElEKGlkKSwgcCkKCgljaGFpbi5FbWl0KCJQb3N0RmxhZ2dlZCIsCgkJInBvc3RJZCIsIHN0cmNvbnYuRm9ybWF0VWludChpZCwgMTApLAoJCSJmbGFnZ2VyIiwgY2FsbGVyLlN0cmluZygpLAoJCSJmbGFnQ291bnQiLCBzdHJjb252Lkl0b2EocC5GbGFnQ291bnQpLAoJKQoJaWYgIXdhc0hpZGRlbiAmJiBwLkhpZGRlbiB7CgkJY2hhaW4uRW1pdCgiUG9zdEF1dG9IaWRkZW4iLCAicG9zdElkIiwgc3RyY29udi5Gb3JtYXRVaW50KGlkLCAxMCkpCgl9Cn0KCi8vIOKUgOKUgCBSZWFjdGlvbnMgKG9uZS1wZXItZW1vamkgdG9nZ2xlOyBvcGVuLXdyaXRlLCBnYXMgaXMgdGhlIHRocm90dGxlKSDilIAKLy8KLy8gQSB3YWxsZXQgbWF5IGFkZCBlYWNoIHN1cHBvcnRlZCBlbW9qaSBhdCBtb3N0IG9uY2UgcGVyIHBvc3QsIGFuZCByZW1vdmUgaXQKLy8gYWdhaW4uIFJlYWN0aW9ucyBjYXJyeSBubyBjb250ZW50IChubyBEb1MvR0RQUiBzdXJmYWNlIGxpa2UgYSBwb3N0IGJvZHkpLCBzbwovLyB0aGVyZSBpcyBubyBhY2NvdW50LWFnZSBnYXRlIOKAlCB0aGUgcGVyLShwb3N0LGVtb2ppLGFkZHIpIGRlZHVwIHBsdXMgdGhlIGdhcwovLyBjb3N0IG9mIGFuIG9uLWNoYWluIHR4IGFyZSB0aGUgdGhyb3R0bGUuIFBlci1lbW9qaSBDT1VOVFMgYXJlIGFnZ3JlZ2F0ZWQKLy8gb2ZmLWNoYWluIGJ5IHRoZSBpbmRleGVyIGZyb20gdGhlIGV2ZW50cyBiZWxvdzsgdGhlIHJlYWxtIE5FVkVSIHNjYW5zIGEKLy8gcG9zdCdzIHJlYWN0aW9uIHNldCwgc28gdGhlIEIxIHJlbmRlciBib3VuZHMgYXJlIHVudG91Y2hlZC4KCi8vIHJlYWN0aW9uRW1vamlzIGlzIHRoZSBmaXhlZCBvbi1jaGFpbiByZWFjdGlvbiBzZXQuIENoYW5naW5nIGl0IGlzIGEgcmVhbG0KLy8gdmVyc2lvbiBidW1wIChyZWRlcGxveSksIHNvIGl0IGlzIGRlbGliZXJhdGVseSBzbWFsbCBhbmQgc3RhYmxlLgp2YXIgcmVhY3Rpb25FbW9qaXMgPSBbXXN0cmluZ3si8J+RjSIsICLinaTvuI8iLCAi8J+YgiIsICLwn5iuIiwgIvCfmKIiLCAi8J+UpSIsICLwn46JIiwgIvCfkYAiLCAi8J+agCJ9CgpmdW5jIGlzUmVhY3Rpb25FbW9qaShlIHN0cmluZykgYm9vbCB7Cglmb3IgXywgciA6PSByYW5nZSByZWFjdGlvbkVtb2ppcyB7CgkJaWYgciA9PSBlIHsKCQkJcmV0dXJuIHRydWUKCQl9Cgl9CglyZXR1cm4gZmFsc2UKfQoKLy8gcmVhY3Rpb25TdWJLZXkgbmFtZXNwYWNlcyBhIHJlYWN0b3IncyBlbnRyeSB3aXRoaW4gYSBwb3N0J3MgcmVhY3Rpb24gdHJlZS4KLy8gVGhlIE5VTCBzZXBhcmF0b3IgY2Fubm90IGFwcGVhciBpbiBhIGZpeGVkLXNldCBlbW9qaSBvciBhIGJlY2gzMiBhZGRyZXNzLCBzbwovLyAoZW1vamksIGFkZHIpIHJvdW5kLXRyaXBzIHVuYW1iaWd1b3VzbHkuCmZ1bmMgcmVhY3Rpb25TdWJLZXkoZW1vamkgc3RyaW5nLCBhZGRyIGFkZHJlc3MpIHN0cmluZyB7CglyZXR1cm4gZW1vamkgKyAiXHgwMCIgKyBhZGRyLlN0cmluZygpCn0KCi8vIEhhc1JlYWN0ZWQgcmVwb3J0cyB3aGV0aGVyIGFkZHIgY3VycmVudGx5IGhhcyB0aGUgZ2l2ZW4gZW1vamkgb24gdGhlIHBvc3QuCi8vIE8obG9nIG4pIHBvaW50IGxvb2t1cCDigJQgbmV2ZXIgYSBzY2FuLgpmdW5jIEhhc1JlYWN0ZWQoaWQgdWludDY0LCBlbW9qaSBzdHJpbmcsIGFkZHIgYWRkcmVzcykgYm9vbCB7Cgl2LCBvayA6PSByZWFjdGlvbnMuR2V0KHBhZElEKGlkKSkKCWlmICFvayB7CgkJcmV0dXJuIGZhbHNlCgl9CglfLCBleGlzdHMgOj0gdi4oKmF2bC5UcmVlKS5HZXQocmVhY3Rpb25TdWJLZXkoZW1vamksIGFkZHIpKQoJcmV0dXJuIGV4aXN0cwp9CgovLyBBZGRSZWFjdGlvbiByZWNvcmRzIHRoZSBjYWxsZXIncyBlbW9qaSByZWFjdGlvbi4gQSByZXBlYXQgYWJvcnRzIChyYXRoZXIgdGhhbgovLyBuby1vcCkgc28gYW4gb3B0aW1pc3RpYyBjbGllbnQncyBkb3VibGUtdGFwIGNhbm5vdCBzaWxlbnRseSBidXJuIGdhcyB0d2ljZSDigJQKLy8gdGhlIGNsaWVudCBnYXRlcyB0aGUgYnV0dG9uIG9uIEhhc1JlYWN0ZWQgLyBpbmRleGVkIHN0YXRlLgpmdW5jIEFkZFJlYWN0aW9uKGN1ciByZWFsbSwgaWQgdWludDY0LCBlbW9qaSBzdHJpbmcpIHsKCWFzc2VydE5vdFBhdXNlZCgpCglpZiAhaXNSZWFjdGlvbkVtb2ppKGVtb2ppKSB7CgkJcGFuaWMoInVuc3VwcG9ydGVkIHJlYWN0aW9uIikKCX0KCWNhbGxlciA6PSB1bnNhZmUuUHJldmlvdXNSZWFsbSgpLkFkZHJlc3MoKQoJbm93IDo9IHJ1bnRpbWUuQ2hhaW5IZWlnaHQoKQoKCXAgOj0gbXVzdEdldFBvc3QoaWQpCglpZiBwLkRlbGV0ZWQgewoJCXBhbmljKCJjYW5ub3QgcmVhY3QgdG8gYSBkZWxldGVkIHBvc3QiKQoJfQoJaWYgcC5IaWRkZW4gewoJCXBhbmljKCJjYW5ub3QgcmVhY3QgdG8gYSBoaWRkZW4gcG9zdCIpCgl9Cgl0b3VjaEZpcnN0U2VlbihjYWxsZXIsIG5vdykKCgl2YXIgdHJlZSAqYXZsLlRyZWUKCWlmIHYsIG9rIDo9IHJlYWN0aW9ucy5HZXQocGFkSUQoaWQpKTsgb2sgewoJCXRyZWUgPSB2LigqYXZsLlRyZWUpCgl9IGVsc2UgewoJCXRyZWUgPSBhdmwuTmV3VHJlZSgpCgl9CglrZXkgOj0gcmVhY3Rpb25TdWJLZXkoZW1vamksIGNhbGxlcikKCWlmIF8sIGFscmVhZHkgOj0gdHJlZS5HZXQoa2V5KTsgYWxyZWFkeSB7CgkJcGFuaWMoImFscmVhZHkgcmVhY3RlZCB3aXRoIHRoaXMgZW1vamkiKQoJfQoJdHJlZS5TZXQoa2V5LCB0cnVlKQoJcmVhY3Rpb25zLlNldChwYWRJRChpZCksIHRyZWUpCgoJY2hhaW4uRW1pdCgiUmVhY3Rpb25BZGRlZCIsCgkJInBvc3RJZCIsIHN0cmNvbnYuRm9ybWF0VWludChpZCwgMTApLAoJCSJlbW9qaSIsIGVtb2ppLAoJCSJieSIsIGNhbGxlci5TdHJpbmcoKSwKCSkKfQoKLy8gUmVtb3ZlUmVhY3Rpb24gcmVtb3ZlcyB0aGUgY2FsbGVyJ3MgZW1vamkgcmVhY3Rpb24gKHRvZ2dsZS1vZmYpLiBBbGxvd2VkIGV2ZW4KLy8gb24gYSBoaWRkZW4vZGVsZXRlZCBwb3N0IHNvIGEgcmVhY3RvciBjYW4gYWx3YXlzIHJldHJhY3Q7IGFib3J0cyBpZiB0aGUgY2FsbGVyCi8vIGhhZCBub3QgcmVhY3RlZCB3aXRoIHRoYXQgZW1vamkuCmZ1bmMgUmVtb3ZlUmVhY3Rpb24oY3VyIHJlYWxtLCBpZCB1aW50NjQsIGVtb2ppIHN0cmluZykgewoJYXNzZXJ0Tm90UGF1c2VkKCkKCWlmICFpc1JlYWN0aW9uRW1vamkoZW1vamkpIHsKCQlwYW5pYygidW5zdXBwb3J0ZWQgcmVhY3Rpb24iKQoJfQoJY2FsbGVyIDo9IHVuc2FmZS5QcmV2aW91c1JlYWxtKCkuQWRkcmVzcygpCgltdXN0R2V0UG9zdChpZCkgLy8gYWJvcnRzIGlmIHRoZSBwb3N0IG5ldmVyIGV4aXN0ZWQKCgl2LCBvayA6PSByZWFjdGlvbnMuR2V0KHBhZElEKGlkKSkKCWlmICFvayB7CgkJcGFuaWMoInlvdSBoYXZlIG5vdCByZWFjdGVkIHRvIHRoaXMgcG9zdCIpCgl9Cgl0cmVlIDo9IHYuKCphdmwuVHJlZSkKCWtleSA6PSByZWFjdGlvblN1YktleShlbW9qaSwgY2FsbGVyKQoJaWYgXywgZXhpc3RzIDo9IHRyZWUuR2V0KGtleSk7ICFleGlzdHMgewoJCXBhbmljKCJ5b3UgaGF2ZSBub3QgcmVhY3RlZCB3aXRoIHRoaXMgZW1vamkiKQoJfQoJdHJlZS5SZW1vdmUoa2V5KQoJaWYgdHJlZS5TaXplKCkgPT0gMCB7CgkJcmVhY3Rpb25zLlJlbW92ZShwYWRJRChpZCkpIC8vIEdDIHRoZSBlbXB0eSBzdWJ0cmVlCgl9IGVsc2UgewoJCXJlYWN0aW9ucy5TZXQocGFkSUQoaWQpLCB0cmVlKQoJfQoKCWNoYWluLkVtaXQoIlJlYWN0aW9uUmVtb3ZlZCIsCgkJInBvc3RJZCIsIHN0cmNvbnYuRm9ybWF0VWludChpZCwgMTApLAoJCSJlbW9qaSIsIGVtb2ppLAoJCSJieSIsIGNhbGxlci5TdHJpbmcoKSwKCSkKfQoKLy8g4pSA4pSAIE1vZGVyYXRvciByb2xlIChXOC4yKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKLy8gVGhlIG93bmVyIGdyYW50cy9yZXZva2VzIG1vZGVyYXRvciBhZGRyZXNzZXMgdGhhdCBjYW4gTW9kUmVtb3ZlUG9zdCAvCi8vIFVuaGlkZVBvc3QuIEZhc3QgKG5vIG93bmVyLW11bHRpc2lnLXBlci1wb3N0KSBhbmQgcmV2ZXJzaWJsZTsgZ3JhbnQvcmV2b2tlCi8vIHN0YXlzIG93bmVyLW9ubHkuIEV2ZXJ5IG11dGF0aW9uIGlzIGVtaXR0ZWQgZm9yIHB1YmxpYyBhdWRpdC4KCmZ1bmMgYXNzZXJ0Q2FsbGVySXNPd25lck9yTW9kZXJhdG9yKCkgewoJY2FsbGVyIDo9IHVuc2FmZS5QcmV2aW91c1JlYWxtKCkuQWRkcmVzcygpCglpZiBjYWxsZXIgPT0gb3duZXIgewoJCXJldHVybgoJfQoJaWYgXywgb2sgOj0gbW9kZXJhdG9ycy5HZXQoY2FsbGVyLlN0cmluZygpKTsgb2sgewoJCXJldHVybgoJfQoJcGFuaWMoInVuYXV0aG9yaXplZDogY2FsbGVyICIgKyBjYWxsZXIuU3RyaW5nKCkgKyAiIGlzIG5vdCB0aGUgb3duZXIgb3IgYSBtb2RlcmF0b3IiKQp9CgovLyBJc01vZGVyYXRvciByZXBvcnRzIHdoZXRoZXIgYWRkciBjdXJyZW50bHkgaG9sZHMgdGhlIG1vZGVyYXRvciByb2xlLgpmdW5jIElzTW9kZXJhdG9yKGFkZHIgYWRkcmVzcykgYm9vbCB7CglfLCBvayA6PSBtb2RlcmF0b3JzLkdldChhZGRyLlN0cmluZygpKQoJcmV0dXJuIG9rCn0KCi8vIEFkZE1vZGVyYXRvciBncmFudHMgdGhlIG1vZGVyYXRvciByb2xlIChvd25lciBvbmx5KS4KZnVuYyBBZGRNb2RlcmF0b3IoY3VyIHJlYWxtLCBhZGRyIGFkZHJlc3MpIHsKCWFzc2VydENhbGxlcklzT3duZXIoKQoJaWYgYWRkciA9PSAiIiB7CgkJcGFuaWMoImFkZHJlc3MgY2Fubm90IGJlIGVtcHR5IikKCX0KCW1vZGVyYXRvcnMuU2V0KGFkZHIuU3RyaW5nKCksIHRydWUpCgljaGFpbi5FbWl0KCJNb2RlcmF0b3JBZGRlZCIsICJtb2RlcmF0b3IiLCBhZGRyLlN0cmluZygpLCAiYnkiLCBvd25lci5TdHJpbmcoKSkKfQoKLy8gUmVtb3ZlTW9kZXJhdG9yIHJldm9rZXMgdGhlIG1vZGVyYXRvciByb2xlIChvd25lciBvbmx5KS4KZnVuYyBSZW1vdmVNb2RlcmF0b3IoY3VyIHJlYWxtLCBhZGRyIGFkZHJlc3MpIHsKCWFzc2VydENhbGxlcklzT3duZXIoKQoJaWYgXywgb2sgOj0gbW9kZXJhdG9ycy5HZXQoYWRkci5TdHJpbmcoKSk7ICFvayB7CgkJcGFuaWMoImFkZHJlc3MgaXMgbm90IGEgbW9kZXJhdG9yIikKCX0KCW1vZGVyYXRvcnMuUmVtb3ZlKGFkZHIuU3RyaW5nKCkpCgljaGFpbi5FbWl0KCJNb2RlcmF0b3JSZW1vdmVkIiwgIm1vZGVyYXRvciIsIGFkZHIuU3RyaW5nKCksICJieSIsIG93bmVyLlN0cmluZygpKQp9CgovLyDilIDilIAgTW9kZXJhdGlvbiAob3duZXIgT1IgbW9kZXJhdG9yOyBXOC4yIGhvdC1rZXkgbGV2ZXIpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgAoKLy8gTW9kUmVtb3ZlUG9zdCBwZXJtYW5lbnRseSBoaWRlcyBhIHBvc3QgYnkgbW9kZXJhdGlvbi4gRW1pdHMgYW4gYXVkaXRlZAovLyBNb2RBY3Rpb24uIFRoZSBub2RlIGlzIHRvbWJzdG9uZWQgZm9yIGhhcmQtR0MgbGlrZSBhbiBhdXRob3IgZGVsZXRlLgpmdW5jIE1vZFJlbW92ZVBvc3QoY3VyIHJlYWxtLCBpZCB1aW50NjQpIHsKCWFzc2VydENhbGxlcklzT3duZXJPck1vZGVyYXRvcigpCgoJcCA6PSBtdXN0R2V0UG9zdChpZCkKCWlmICFwLkRlbGV0ZWQgewoJCXJlbW92ZUZyb21MaXZlSW5kZXhlcyhwKQoJCXRvbWJzdG9uZXMuU2V0KHBhZElEKGlkKSwgdHJ1ZSkKCX0KCXAuRGVsZXRlZCA9IHRydWUKCXAuSGlkZGVuID0gdHJ1ZQoJcC5Cb2R5ID0gIiIKCXAuTWVkaWFDSURzID0gbmlsCglwb3N0cy5TZXQocGFkSUQoaWQpLCBwKQoKCWNoYWluLkVtaXQoIk1vZEFjdGlvbiIsCgkJImFjdGlvbiIsICJyZW1vdmUiLAoJCSJwb3N0SWQiLCBzdHJjb252LkZvcm1hdFVpbnQoaWQsIDEwKSwKCQkibW9kZXJhdG9yIiwgdW5zYWZlLlByZXZpb3VzUmVhbG0oKS5BZGRyZXNzKCkuU3RyaW5nKCksCgkpCn0KCi8vIFVuaGlkZVBvc3QgY2xlYXJzIGZsYWdzIGFuZCByZXN0b3JlcyBhIGZsYWctaGlkZGVuIHBvc3QgdG8gdGhlIGxpdmUgc2V0LgpmdW5jIFVuaGlkZVBvc3QoY3VyIHJlYWxtLCBpZCB1aW50NjQpIHsKCWFzc2VydENhbGxlcklzT3duZXJPck1vZGVyYXRvcigpCgoJcCA6PSBtdXN0R2V0UG9zdChpZCkKCWlmIHAuRGVsZXRlZCB7CgkJcGFuaWMoImNhbm5vdCB1bmhpZGUgYSBkZWxldGVkIHBvc3QiKQoJfQoJaWYgIXAuSGlkZGVuIHsKCQlwYW5pYygicG9zdCBpcyBub3QgaGlkZGVuIikKCX0KCXAuSGlkZGVuID0gZmFsc2UKCXAuRmxhZ0NvdW50ID0gMAoJcG9zdHMuU2V0KHBhZElEKGlkKSwgcCkKCWZsYWdzLlJlbW92ZShwYWRJRChpZCkpCglhZGRUb0xpdmVJbmRleGVzKHApCgoJY2hhaW4uRW1pdCgiTW9kQWN0aW9uIiwKCQkiYWN0aW9uIiwgInVuaGlkZSIsCgkJInBvc3RJZCIsIHN0cmNvbnYuRm9ybWF0VWludChpZCwgMTApLAoJCSJtb2RlcmF0b3IiLCB1bnNhZmUuUHJldmlvdXNSZWFsbSgpLkFkZHJlc3MoKS5TdHJpbmcoKSwKCSkKfQoKLy8g4pSA4pSAIFRvbWJzdG9uZSBzd2VlcCAoQjIgaGFyZC1HQywgcG9ydGVkIGZyb20gY2hhbm5lbHNfdjIpIOKUgOKUgOKUgOKUgAoKLy8gU3dlZXBUb21ic3RvbmVzIGhhcmQtcmVtb3ZlcyB1cCB0byBgbGltaXRgIHNvZnQtZGVsZXRlZCBwb3N0cywgcmVjbGFpbWluZwovLyBBVkwgc3RvcmFnZSBzbyBwb3N0K2RlbGV0ZSBzcGFtIGNhbm5vdCBhY2NyZXRlIHBlcm1hbmVudCBzdGF0ZS4KLy8gUGVybWlzc2lvbmxlc3MgYnkgZGVzaWduIChzdGF0ZS1zaHJpbmsgaHlnaWVuZSBwcmltaXRpdmUsIG5vdCBhIHJlZnVuZAovLyBwYXRoKS4gQm91bmRlZCArIGlkZW1wb3RlbnQ6IGtlZXAgYGxpbWl0YCBzbWFsbCAoMS0xMCk7IHJlLXJ1bm5pbmcgZHJhaW5zCi8vIHRoZSBuZXh0IGJhdGNoIGFuZCBzdG9wcyBhdCAwLiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcG9zdHMgc3dlcHQuCi8vCi8vIEZvciBhIHN3ZXB0IHBvc3QgdGhhdCB3YXMgYSBQQVJFTlQsIGl0cyBzdXJ2aXZpbmcgcmVwbGllcycgYnlQYXJlbnQgbGlua3MKLy8gKGBwYWRJRChwYXJlbnQpOnBhZElEKGNoaWxkKWApIHdvdWxkIG90aGVyd2lzZSBiZSBvcnBoYW5lZCB1bmRlciBhbiBpZCBubwovLyBsb25nZXIgaW4gYHBvc3RzYCDigJQgYSBwZXJtYW5lbnQgbGVhayBwbHVzIGEgcmVhZCBpbmNvbnNpc3RlbmN5IChyZXBsaWVzCi8vIHN0aWxsIGVudW1lcmFibGUsIGdldFJlcGx5Q291bnQoKSBkaXNhZ3JlZWluZykuIFNvIHRoZSBzd2VlcCByYW5nZS1kZWxldGVzCi8vIHRoYXQgYnlQYXJlbnQgcHJlZml4OyB0aGUgcmVwbHkgcG9zdHMgdGhlbXNlbHZlcyBzdGF5IGFzIHN0YW5kYWxvbmUgbGl2ZQovLyBjb250ZW50ICh0aGVpciBwYXJlbnQgd2FzIHJlbW92ZWQgYnkgaXRzIG93biBhdXRob3IpLiBCb3VuZGVkIGJlY2F1c2UgdGhlCi8vIGxpdmUgcmVwbHkgc2V0IHBlciBwb3N0IGlzIGNhcHBlZCBhdCBNYXhSZXBsaWVzUGVyUG9zdCDigJQgYnV0IGEgcmVwbHktaGVhdnkKLy8gcGFyZW50IG1ha2VzIG9uZSBzd2VlcCBzdGVwIGRvIHVwIHRvIHRoYXQgbWFueSByZW1vdmVzLCBzbyBrZWVwIGBsaW1pdGAKLy8gc21hbGwgKDEpIHdoZW4gZHJhaW5pbmcga25vd24gcmVwbHktaGVhdnkgdG9tYnN0b25lcy4KZnVuYyBTd2VlcFRvbWJzdG9uZXMoY3VyIHJlYWxtLCBsaW1pdCBpbnQpIGludCB7Cglhc3NlcnROb3RQYXVzZWQoKQoJaWYgbGltaXQgPD0gMCB7CgkJcmV0dXJuIDAKCX0KCgkvLyBDb2xsZWN0IHRoZSBvbGRlc3QgYGxpbWl0YCB0b21ic3RvbmVkIGlkcyAoYXNjZW5kaW5nKSwgdGhlbiBtdXRhdGUg4oCUCgkvLyBuZXZlciByZW1vdmUgZnJvbSB0aGUgdHJlZSB3ZSBhcmUgaXRlcmF0aW5nIChBVkwgZm9vdGd1bikuCglpZHMgOj0gW111aW50NjR7fQoJdG9tYnN0b25lcy5JdGVyYXRlKCIiLCAiIiwgZnVuYyhrZXkgc3RyaW5nLCBfIGludGVyZmFjZXt9KSBib29sIHsKCQlpZHMgPSBhcHBlbmQoaWRzLCBpZEZyb21QYWRkZWQoa2V5KSkKCQlyZXR1cm4gbGVuKGlkcykgPj0gbGltaXQKCX0pCgoJZm9yIF8sIGlkIDo9IHJhbmdlIGlkcyB7CgkJLy8gRHJvcCB0aGlzIHBhcmVudCdzIHJlbWFpbmluZyBjaGlsZCBsaW5rcyAoaWYgYW55KSBzbyBubyBieVBhcmVudAoJCS8vIGVudHJ5IG91dGxpdmVzIGl0cyBwYXJlbnQuIENvbGxlY3QtdGhlbi1yZW1vdmUgb3ZlciB0aGUgcHJlZml4LgoJCXByZWZpeCA6PSBwYWRJRChpZCkgKyAiOiIKCQljaGlsZEtleXMgOj0gW11zdHJpbmd7fQoJCWJ5UGFyZW50Lkl0ZXJhdGUocHJlZml4LCBwcmVmaXgrIlx4ZmYiLCBmdW5jKGsgc3RyaW5nLCBfIGludGVyZmFjZXt9KSBib29sIHsKCQkJY2hpbGRLZXlzID0gYXBwZW5kKGNoaWxkS2V5cywgaykKCQkJcmV0dXJuIGZhbHNlCgkJfSkKCQlmb3IgXywgayA6PSByYW5nZSBjaGlsZEtleXMgewoJCQlieVBhcmVudC5SZW1vdmUoaykKCQl9CgoJCXBvc3RzLlJlbW92ZShwYWRJRChpZCkpCgkJZmxhZ3MuUmVtb3ZlKHBhZElEKGlkKSkKCQlyZXBseUNvdW50LlJlbW92ZShwYWRJRChpZCkpCgkJdG9tYnN0b25lcy5SZW1vdmUocGFkSUQoaWQpKQoJfQoKCWlmIGxlbihpZHMpID4gMCB7CgkJY2hhaW4uRW1pdCgiVG9tYnN0b25lc1N3ZXB0IiwgImNvdW50Iiwgc3RyY29udi5JdG9hKGxlbihpZHMpKSkKCX0KCXJldHVybiBsZW4oaWRzKQp9CgovLyBHZXRUb21ic3RvbmVDb3VudCByZXR1cm5zIGhvdyBtYW55IHNvZnQtZGVsZXRlZCBwb3N0cyBhd2FpdCBoYXJkLUdDLgpmdW5jIEdldFRvbWJzdG9uZUNvdW50KCkgaW50IHsgcmV0dXJuIHRvbWJzdG9uZXMuU2l6ZSgpIH0KCi8vIOKUgOKUgCBKU09OIHJlYWRzICh2bS9xZXZhbDsgY3Vyc29yLXBhZ2luYXRlZCwgTyhsaW1pdCkgYXQgYW55IGRlcHRoKSDilIDilIAKCi8vIGpzb25Fc2NhcGUgZXNjYXBlcyBhIHN0cmluZyBmb3IgZW1iZWRkaW5nIGluIGEgSlNPTiBzdHJpbmcgbGl0ZXJhbC4KZnVuYyBqc29uRXNjYXBlKHMgc3RyaW5nKSBzdHJpbmcgewoJdmFyIHNiIHN0cmluZ3MuQnVpbGRlcgoJZm9yIF8sIGMgOj0gcmFuZ2UgcyB7CgkJc3dpdGNoIGMgewoJCWNhc2UgJyInOgoJCQlzYi5Xcml0ZVN0cmluZygiXFxcIiIpCgkJY2FzZSAnXFwnOgoJCQlzYi5Xcml0ZVN0cmluZygiXFxcXCIpCgkJY2FzZSAnXG4nOgoJCQlzYi5Xcml0ZVN0cmluZygiXFxuIikKCQljYXNlICdccic6CgkJCXNiLldyaXRlU3RyaW5nKCJcXHIiKQoJCWNhc2UgJ1x0JzoKCQkJc2IuV3JpdGVTdHJpbmcoIlxcdCIpCgkJZGVmYXVsdDoKCQkJaWYgYyA8IDB4MjAgewoJCQkJY29udGludWUgLy8gZHJvcCByYXcgY29udHJvbCBjaGFycyAodWZtdCBoYXMgbm8gXHVYWFhYIHN1cHBvcnQpCgkJCX0KCQkJc2IuV3JpdGVSdW5lKGMpCgkJfQoJfQoJcmV0dXJuIHNiLlN0cmluZygpCn0KCi8vIHBvc3RKU09OIGlzIHRoZSBxZXZhbCByZWFkIGZhbGxiYWNrLiBOb3RlIGl0IGV4cG9zZXMgYG1lZGlhQ2lkc2AgKFAyKSBhbmQKLy8gYHJlcG9zdE9mYCAoUDEpIHdoaWNoIHRoZSBDQU5PTklDQUwgaW5kZXhlZCBwYXRoIChjaGFpbi5FbWl0IOKGkiBiYWNrZW5kIOKGkgovLyBmZWVkX3JwYyDihpIgVUkpIGRvZXMgTk9UIGNhcnJ5IHlldCDigJQgUG9zdENyZWF0ZWQgZW1pdHMgbmVpdGhlciwgdGhlIHByb3RvCi8vIHJlc2VydmVzIHJlcG9zdF9vZiwgYW5kIHRoZXJlIGlzIG5vIG1lZGlhIGNvbHVtbi4gQSBmdXR1cmUgZGV2IHdpcmluZyB0aGUKLy8gcWV2YWwgZmFsbGJhY2sgbXVzdCBub3QgYXNzdW1lIHRob3NlIHR3byBhcmUgcGx1bWJlZCBlbmQtdG8tZW5kLgpmdW5jIHBvc3RKU09OKHAgKlBvc3QpIHN0cmluZyB7Cgl2YXIgbWVkaWEgc3RyaW5ncy5CdWlsZGVyCgltZWRpYS5Xcml0ZVN0cmluZygiWyIpCglmb3IgaSwgY2lkIDo9IHJhbmdlIHAuTWVkaWFDSURzIHsKCQlpZiBpID4gMCB7CgkJCW1lZGlhLldyaXRlU3RyaW5nKCIsIikKCQl9CgkJbWVkaWEuV3JpdGVTdHJpbmcoIlwiIiArIGpzb25Fc2NhcGUoY2lkKSArICJcIiIpCgl9CgltZWRpYS5Xcml0ZVN0cmluZygiXSIpCgoJcmV0dXJuIHVmbXQuU3ByaW50ZigKCQlgeyJpZCI6JWQsImF1dGhvciI6IiVzIiwiYm9keSI6IiVzIiwibWVkaWFDaWRzIjolcywicmVwbHlUbyI6JWQsInJlcG9zdE9mIjolZCwiYmxvY2tIIjolZCwiZWRpdGVkQXQiOiVkLCJmbGFnQ291bnQiOiVkLCJoaWRkZW4iOiVzLCJkZWxldGVkIjolcywicmVwbGllcyI6JWR9YCwKCQlwLklELCBwLkF1dGhvci5TdHJpbmcoKSwganNvbkVzY2FwZShwLkJvZHkpLCBtZWRpYS5TdHJpbmcoKSwKCQlwLlJlcGx5VG8sIHAuUmVwb3N0T2YsIHAuQmxvY2tILCBwLkVkaXRlZEF0LCBwLkZsYWdDb3VudCwKCQlib29sU3RyKHAuSGlkZGVuKSwgYm9vbFN0cihwLkRlbGV0ZWQpLCBnZXRSZXBseUNvdW50KHAuSUQpLAoJKQp9CgpmdW5jIGJvb2xTdHIoYiBib29sKSBzdHJpbmcgewoJaWYgYiB7CgkJcmV0dXJuICJ0cnVlIgoJfQoJcmV0dXJuICJmYWxzZSIKfQoKZnVuYyBjbGFtcExpbWl0KGxpbWl0IGludCkgaW50IHsKCWlmIGxpbWl0IDw9IDAgewoJCXJldHVybiBGZWVkUGFnZVNpemUKCX0KCWlmIGxpbWl0ID4gTWF4UGFnZUxpbWl0IHsKCQlyZXR1cm4gTWF4UGFnZUxpbWl0Cgl9CglyZXR1cm4gbGltaXQKfQoKLy8gR2V0UG9zdEpTT04gcmV0dXJucyBvbmUgcG9zdCAoYW55IHN0YXRlIOKAlCB0aGUgaW5kZXhlciBuZWVkcyB0b21ic3RvbmVzIHRvbykuCmZ1bmMgR2V0UG9zdEpTT04oaWQgdWludDY0KSBzdHJpbmcgewoJcCwgb2sgOj0gZ2V0UG9zdChpZCkKCWlmICFvayB7CgkJcmV0dXJuICJudWxsIgoJfQoJcmV0dXJuIHBvc3RKU09OKHApCn0KCi8vIGxpc3RXaW5kb3cgd2Fsa3MgYHRyZWVgIFJFVkVSU0UgKG5ld2VzdCBmaXJzdCkgc3RhcnRpbmcgYmVsb3cgY3Vyc29yS2V5Ci8vICgiIiA9IGZyb20gdGhlIG5ld2VzdCksIGNvbGxlY3RpbmcgdXAgdG8gbGltaXQgaWRzIHZpYSBleHRyYWN0LgpmdW5jIGxpc3RXaW5kb3codHJlZSAqYXZsLlRyZWUsIGN1cnNvcktleSBzdHJpbmcsIGxpbWl0IGludCwgZXh0cmFjdCBmdW5jKGtleSBzdHJpbmcpIHVpbnQ2NCkgW111aW50NjQgewoJaWRzIDo9IFtddWludDY0e30KCWNvdW50IDo9IDAKCXRyZWUuUmV2ZXJzZUl0ZXJhdGUoIiIsIGN1cnNvcktleSwgZnVuYyhrZXkgc3RyaW5nLCBfIGludGVyZmFjZXt9KSBib29sIHsKCQlpZCA6PSBleHRyYWN0KGtleSkKCQlpZiBpZCAhPSAwIHsKCQkJaWRzID0gYXBwZW5kKGlkcywgaWQpCgkJCWNvdW50KysKCQl9CgkJcmV0dXJuIGNvdW50ID49IGxpbWl0Cgl9KQoJcmV0dXJuIGlkcwp9CgpmdW5jIGlkRnJvbVBhZGRlZChrZXkgc3RyaW5nKSB1aW50NjQgewoJbiwgZXJyIDo9IHN0cmNvbnYuUGFyc2VVaW50KGtleSwgMTAsIDY0KQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAKCX0KCXJldHVybiBuCn0KCmZ1bmMgaWRGcm9tQ29tcG9zaXRlKGtleSBzdHJpbmcpIHVpbnQ2NCB7CglpIDo9IHN0cmluZ3MuTGFzdEluZGV4Qnl0ZShrZXksICc6JykKCWlmIGkgPCAwIHsKCQlyZXR1cm4gMAoJfQoJcmV0dXJuIGlkRnJvbVBhZGRlZChrZXlbaSsxOl0pCn0KCmZ1bmMgaWRzVG9KU09OKGlkcyBbXXVpbnQ2NCkgc3RyaW5nIHsKCXZhciBzYiBzdHJpbmdzLkJ1aWxkZXIKCXNiLldyaXRlU3RyaW5nKCJbIikKCWZvciBpLCBpZCA6PSByYW5nZSBpZHMgewoJCWlmIGkgPiAwIHsKCQkJc2IuV3JpdGVTdHJpbmcoIiwiKQoJCX0KCQlpZiBwLCBvayA6PSBnZXRQb3N0KGlkKTsgb2sgewoJCQlzYi5Xcml0ZVN0cmluZyhwb3N0SlNPTihwKSkKCQl9Cgl9CglzYi5Xcml0ZVN0cmluZygiXSIpCglyZXR1cm4gc2IuU3RyaW5nKCkKfQoKLy8gTGlzdEZlZWRKU09OIHJldHVybnMgdGhlIG5ld2VzdCBsaXZlIHBvc3RzIHN0cmljdGx5IG9sZGVyIHRoYW4gY3Vyc29yCi8vIChjdXJzb3IgPT0gMCDihpIgZnJvbSB0aGUgdG9wKS4gUGFzcyB0aGUgbGFzdCBpZCBvZiB0aGUgcHJldmlvdXMgd2luZG93IGFzCi8vIHRoZSBuZXh0IGN1cnNvci4KLy8KLy8gUmV2ZXJzZUl0ZXJhdGUgdHJlYXRzIEJPVEggYm91bmRzIGFzIGluY2x1c2l2ZSAoYXZsL3YwIFRyYXZlcnNlSW5SYW5nZSksIHNvCi8vICJzdHJpY3RseSBvbGRlciB0aGFuIGN1cnNvciIgPSBlbmQgYm91bmQgcGFkSUQoY3Vyc29yLTEpOiBpZHMgYXJlIGludGVnZXJzLAovLyBrZXlzIGFyZSBmaXhlZC13aWR0aCwgaGVuY2Uga2V5IDwgcGFkSUQoY3Vyc29yKSDin7oga2V5IOKJpCBwYWRJRChjdXJzb3ItMSkuCmZ1bmMgTGlzdEZlZWRKU09OKGN1cnNvciB1aW50NjQsIGxpbWl0IGludCkgc3RyaW5nIHsKCWxpbWl0ID0gY2xhbXBMaW1pdChsaW1pdCkKCWN1cnNvcktleSA6PSAiIgoJaWYgY3Vyc29yICE9IDAgewoJCWN1cnNvcktleSA9IHBhZElEKGN1cnNvciAtIDEpCgl9CglyZXR1cm4gaWRzVG9KU09OKGxpc3RXaW5kb3cobGl2ZUZlZWQsIGN1cnNvcktleSwgbGltaXQsIGlkRnJvbVBhZGRlZCkpCn0KCi8vIExpc3RVc2VySlNPTiByZXR1cm5zIGEgdXNlcidzIG5ld2VzdCBsaXZlIHBvc3RzIHN0cmljdGx5IG9sZGVyIHRoYW4gY3Vyc29yCi8vIChzYW1lIGluY2x1c2l2ZS1ib3VuZCBydWxlIGFzIExpc3RGZWVkSlNPTikuCmZ1bmMgTGlzdFVzZXJKU09OKGFkZHIgc3RyaW5nLCBjdXJzb3IgdWludDY0LCBsaW1pdCBpbnQpIHN0cmluZyB7CglsaW1pdCA9IGNsYW1wTGltaXQobGltaXQpCgljdXJzb3JLZXkgOj0gIiIKCWlmIGN1cnNvciAhPSAwIHsKCQljdXJzb3JLZXkgPSBhZGRyICsgIjoiICsgcGFkSUQoY3Vyc29yLTEpCgl9IGVsc2UgewoJCS8vIEVuZCBib3VuZCBqdXN0IHBhc3QgZXZlcnkgImFkZHI6WFhYWFhYWFhYWFhYIiBrZXk6ICc6JyArIDB4ZmYuCgkJY3Vyc29yS2V5ID0gYWRkciArICI6XHhmZiIKCX0KCWlkcyA6PSBbXXVpbnQ2NHt9Cgljb3VudCA6PSAwCglieUF1dGhvci5SZXZlcnNlSXRlcmF0ZShhZGRyKyI6IiwgY3Vyc29yS2V5LCBmdW5jKGtleSBzdHJpbmcsIF8gaW50ZXJmYWNle30pIGJvb2wgewoJCWlmIGlkIDo9IGlkRnJvbUNvbXBvc2l0ZShrZXkpOyBpZCAhPSAwIHsKCQkJaWRzID0gYXBwZW5kKGlkcywgaWQpCgkJCWNvdW50KysKCQl9CgkJcmV0dXJuIGNvdW50ID49IGxpbWl0Cgl9KQoJcmV0dXJuIGlkc1RvSlNPTihpZHMpCn0KCi8vIExpc3RSZXBsaWVzSlNPTiByZXR1cm5zIGEgcG9zdCdzIGxpdmUgcmVwbGllcywgT0xERVNUIGZpcnN0IChjb252ZXJzYXRpb24KLy8gb3JkZXIpLCBzdGFydGluZyBzdHJpY3RseSBhZnRlciBjdXJzb3IgKDAg4oaSIGZyb20gdGhlIGJlZ2lubmluZykuCmZ1bmMgTGlzdFJlcGxpZXNKU09OKHBhcmVudCB1aW50NjQsIGN1cnNvciB1aW50NjQsIGxpbWl0IGludCkgc3RyaW5nIHsKCWxpbWl0ID0gY2xhbXBMaW1pdChsaW1pdCkKCXN0YXJ0IDo9IHBhZElEKHBhcmVudCkgKyAiOiIKCWlmIGN1cnNvciAhPSAwIHsKCQlzdGFydCA9IHBhcmVudEtleShwYXJlbnQsIGN1cnNvcikgKyAiXHgwMCIgLy8gc3RyaWN0bHkgYWZ0ZXIgdGhlIGN1cnNvciBjaGlsZAoJfQoJaWRzIDo9IFtddWludDY0e30KCWNvdW50IDo9IDAKCWJ5UGFyZW50Lkl0ZXJhdGUoc3RhcnQsIHBhZElEKHBhcmVudCkrIjpceGZmIiwgZnVuYyhrZXkgc3RyaW5nLCBfIGludGVyZmFjZXt9KSBib29sIHsKCQlpZiBpZCA6PSBpZEZyb21Db21wb3NpdGUoa2V5KTsgaWQgIT0gMCB7CgkJCWlkcyA9IGFwcGVuZChpZHMsIGlkKQoJCQljb3VudCsrCgkJfQoJCXJldHVybiBjb3VudCA+PSBsaW1pdAoJfSkKCXJldHVybiBpZHNUb0pTT04oaWRzKQp9CgovLyBHZXRTdGF0c0pTT04gcmV0dXJucyByZWFsbS1sZXZlbCBjb3VudGVycyAobW9ub3RvbmljIGlkIGlzIGluZm9ybWF0aW9uYWwg4oCUCi8vIG5vIHJlYWQgaXRlcmF0ZXMgaXQpLgpmdW5jIEdldFN0YXRzSlNPTigpIHN0cmluZyB7CglyZXR1cm4gdWZtdC5TcHJpbnRmKGB7ImxpdmVQb3N0cyI6JWQsIm5leHRQb3N0SWQiOiVkLCJ0b21ic3RvbmVzIjolZCwicGF1c2VkIjolc31gLAoJCWxpdmVDb3VudCwgbmV4dFBvc3RJRCwgdG9tYnN0b25lcy5TaXplKCksIGJvb2xTdHIocGF1c2VkKSkKfQoKLy8g4pSA4pSAIFJlbmRlciAoZ25vd2ViIGh1bWFuIHZpZXc7IGJvdW5kZWQg4oCUIEIxKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKLy8KLy8gUGF0aHM6Ci8vICAgIiIgICAgICAgICAgICDihpIgbmV3ZXN0IHdpbmRvdyAocGFnZSAxKQovLyAgIHBhZ2UvSyAgICAgICAg4oaSIEstdGggbmV3ZXN0IHdpbmRvdywgSyDiiaQgTWF4UmVuZGVyUGFnZQovLyAgIHVzZXIvQUREUiAgICAg4oaSIEFERFIncyBuZXdlc3Qgd2luZG93Ci8vICAgdXNlci9BRERSL0sgICDihpIgSy10aCB3aW5kb3cgb2YgQUREUidzIHBvc3RzCi8vICAgcG9zdC9JRCAgICAgICDihpIgb25lIHBvc3QgKyBpdHMgbmV3ZXN0IHJlcGx5IHdpbmRvdwovLwovLyBFdmVyeSBwYWdlIHNjYW5zIGF0IG1vc3QgTWF4UmVuZGVyUGFnZSpGZWVkUGFnZVNpemUgbGl2ZS1pbmRleCBrZXlzIGFuZAovLyBmZXRjaGVzIGF0IG1vc3QgRmVlZFBhZ2VTaXplIHBvc3RzIOKAlCBib3VuZGVkIHJlZ2FyZGxlc3Mgb2YgZmVlZCBzaXplIG9yCi8vIGNodXJuIChkZWxldGVkL2hpZGRlbiBwb3N0cyBhcmUgbm90IGluIHRoZSBsaXZlIGluZGV4ZXMgYXQgYWxsKS4KCmZ1bmMgUmVuZGVyKHBhdGggc3RyaW5nKSBzdHJpbmcgewoJaWYgcGF0aCA9PSAiIiB7CgkJcmV0dXJuIHJlbmRlckZlZWRQYWdlKDEpCgl9CglpZiBzdHJpbmdzLkhhc1ByZWZpeChwYXRoLCAicGFnZS8iKSB7CgkJaywgZXJyIDo9IHN0cmNvbnYuUGFyc2VVaW50KHN0cmluZ3MuVHJpbVByZWZpeChwYXRoLCAicGFnZS8iKSwgMTAsIDY0KQoJCWlmIGVyciAhPSBuaWwgfHwgayA9PSAwIHsKCQkJcmV0dXJuICIjIDQwNFxuQmFkIHBhZ2UiCgkJfQoJCXJldHVybiByZW5kZXJGZWVkUGFnZShrKQoJfQoJaWYgc3RyaW5ncy5IYXNQcmVmaXgocGF0aCwgInVzZXIvIikgewoJCXJlc3QgOj0gc3RyaW5ncy5UcmltUHJlZml4KHBhdGgsICJ1c2VyLyIpCgkJYWRkciA6PSByZXN0CgkJayA6PSB1aW50NjQoMSkKCQlpZiBpIDo9IHN0cmluZ3MuSW5kZXhCeXRlKHJlc3QsICcvJyk7IGkgPj0gMCB7CgkJCWFkZHIgPSByZXN0WzppXQoJCQluLCBlcnIgOj0gc3RyY29udi5QYXJzZVVpbnQocmVzdFtpKzE6XSwgMTAsIDY0KQoJCQlpZiBlcnIgIT0gbmlsIHx8IG4gPT0gMCB7CgkJCQlyZXR1cm4gIiMgNDA0XG5CYWQgcGFnZSIKCQkJfQoJCQlrID0gbgoJCX0KCQlyZXR1cm4gcmVuZGVyVXNlclBhZ2UoYWRkciwgaykKCX0KCWlmIHN0cmluZ3MuSGFzUHJlZml4KHBhdGgsICJwb3N0LyIpIHsKCQlpZCwgZXJyIDo9IHN0cmNvbnYuUGFyc2VVaW50KHN0cmluZ3MuVHJpbVByZWZpeChwYXRoLCAicG9zdC8iKSwgMTAsIDY0KQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gIiMgNDA0XG5CYWQgcG9zdCBpZCIKCQl9CgkJcmV0dXJuIHJlbmRlclBvc3QoaWQpCgl9CglyZXR1cm4gIiMgNDA0XG5QYWdlIG5vdCBmb3VuZDogIiArIHBhdGgKfQoKLy8gY29sbGVjdFBhZ2Ugd2Fsa3MgYSBsaXZlIGluZGV4IHJldmVyc2UgYW5kIHJldHVybnMgdGhlIGlkcyBmb3Igd2luZG93IGsKLy8gKDEtYmFzZWQpLiBTY2FuIGlzIGJvdW5kZWQ6IGsgaXMgY2FwcGVkIGF0IE1heFJlbmRlclBhZ2UgYnkgY2FsbGVycy4KZnVuYyBjb2xsZWN0UGFnZSh0cmVlICphdmwuVHJlZSwgcHJlZml4LCBlbmRLZXkgc3RyaW5nLCBrIHVpbnQ2NCkgW111aW50NjQgewoJc2tpcCA6PSAoayAtIDEpICogRmVlZFBhZ2VTaXplCglpZHMgOj0gW111aW50NjR7fQoJc2VlbiA6PSB1aW50NjQoMCkKCXRyZWUuUmV2ZXJzZUl0ZXJhdGUocHJlZml4LCBlbmRLZXksIGZ1bmMoa2V5IHN0cmluZywgXyBpbnRlcmZhY2V7fSkgYm9vbCB7CgkJaWYgc2VlbiA+PSBza2lwIHsKCQkJdmFyIGlkIHVpbnQ2NAoJCQlpZiBwcmVmaXggPT0gIiIgewoJCQkJaWQgPSBpZEZyb21QYWRkZWQoa2V5KQoJCQl9IGVsc2UgewoJCQkJaWQgPSBpZEZyb21Db21wb3NpdGUoa2V5KQoJCQl9CgkJCWlmIGlkICE9IDAgewoJCQkJaWRzID0gYXBwZW5kKGlkcywgaWQpCgkJCX0KCQl9CgkJc2VlbisrCgkJcmV0dXJuIGxlbihpZHMpID49IEZlZWRQYWdlU2l6ZQoJfSkKCXJldHVybiBpZHMKfQoKZnVuYyByZW5kZXJQb3N0TGluZShzYiAqc3RyaW5ncy5CdWlsZGVyLCBwICpQb3N0KSB7CglzYi5Xcml0ZVN0cmluZyh1Zm10LlNwcmludGYoIioqJXMqKiAoYmxvY2sgJWQpIiwgdHJ1bmNBZGRyKHAuQXV0aG9yKSwgcC5CbG9ja0gpKQoJaWYgcC5FZGl0ZWRBdCAhPSAwIHsKCQlzYi5Xcml0ZVN0cmluZygiICooZWRpdGVkKSoiKQoJfQoJaWYgcC5SZXBseVRvICE9IDAgewoJCXNiLldyaXRlU3RyaW5nKHVmbXQuU3ByaW50ZigiIOKAlCByZXBseSB0byBbcG9zdCAlZF0oOnBvc3QvJWQpIiwgcC5SZXBseVRvLCBwLlJlcGx5VG8pKQoJfQoJc2IuV3JpdGVTdHJpbmcoIlxuXG4iKQoJc2IuV3JpdGVTdHJpbmcoc2FuaXRpemVGb3JSZW5kZXIocC5Cb2R5KSArICJcblxuIikKCXJjIDo9IGdldFJlcGx5Q291bnQocC5JRCkKCXNiLldyaXRlU3RyaW5nKHVmbXQuU3ByaW50ZigiW3Blcm1hbGlua10oOnBvc3QvJWQpIHwgJWQgcmVwbGllc1xuXG4tLS1cblxuIiwgcC5JRCwgcmMpKQp9CgpmdW5jIHJlbmRlckZlZWRQYWdlKGsgdWludDY0KSBzdHJpbmcgewoJaWYgayA+IE1heFJlbmRlclBhZ2UgewoJCXJldHVybiB1Zm10LlNwcmludGYoIiMgTWVtYmEgRmVlZFxuXG4qUGFnZXMgYmV5b25kICVkIGFyZSBub3QgcmVuZGVyZWQg4oCUIHVzZSB0aGUgSlNPTiBjdXJzb3IgQVBJIChMaXN0RmVlZEpTT04pIG9yIHRoZSBNZW1iYSBhcHAuKlxuIiwgTWF4UmVuZGVyUGFnZSkKCX0KCXZhciBzYiBzdHJpbmdzLkJ1aWxkZXIKCXNiLldyaXRlU3RyaW5nKCIjIE1lbWJhIEZlZWRcblxuIikKCXNiLldyaXRlU3RyaW5nKHVmbXQuU3ByaW50ZigiKipMaXZlIHBvc3RzOioqICVkXG5cbiIsIGxpdmVDb3VudCkpCgoJaWRzIDo9IGNvbGxlY3RQYWdlKGxpdmVGZWVkLCAiIiwgIiIsIGspCglpZiBsZW4oaWRzKSA9PSAwIHsKCQlzYi5Xcml0ZVN0cmluZygiKk5vIHBvc3RzIG9uIHRoaXMgcGFnZS4qXG4iKQoJCXJldHVybiBzYi5TdHJpbmcoKQoJfQoJZm9yIF8sIGlkIDo9IHJhbmdlIGlkcyB7CgkJaWYgcCwgb2sgOj0gZ2V0UG9zdChpZCk7IG9rIHsKCQkJcmVuZGVyUG9zdExpbmUoJnNiLCBwKQoJCX0KCX0KCXNiLldyaXRlU3RyaW5nKHVmbXQuU3ByaW50ZigiKnBhZ2UgJWQg4oCUIG9sZGVyOiBgOnBhZ2UvJWRgKlxuIiwgaywgaysxKSkKCXJldHVybiBzYi5TdHJpbmcoKQp9CgpmdW5jIHJlbmRlclVzZXJQYWdlKGFkZHIgc3RyaW5nLCBrIHVpbnQ2NCkgc3RyaW5nIHsKCWlmIGsgPiBNYXhSZW5kZXJQYWdlIHsKCQlyZXR1cm4gdWZtdC5TcHJpbnRmKCIjIEZlZWQg4oCUICVzXG5cbipQYWdlcyBiZXlvbmQgJWQgYXJlIG5vdCByZW5kZXJlZCDigJQgdXNlIExpc3RVc2VySlNPTiBvciB0aGUgTWVtYmEgYXBwLipcbiIsIGFkZHIsIE1heFJlbmRlclBhZ2UpCgl9Cgl2YXIgc2Igc3RyaW5ncy5CdWlsZGVyCglzYi5Xcml0ZVN0cmluZyh1Zm10LlNwcmludGYoIiMgRmVlZCDigJQgJXNcblxuIiwgYWRkcikpCglpZHMgOj0gY29sbGVjdFBhZ2UoYnlBdXRob3IsIGFkZHIrIjoiLCBhZGRyKyI6XHhmZiIsIGspCglpZiBsZW4oaWRzKSA9PSAwIHsKCQlzYi5Xcml0ZVN0cmluZygiKk5vIHBvc3RzIG9uIHRoaXMgcGFnZS4qXG4iKQoJCXJldHVybiBzYi5TdHJpbmcoKQoJfQoJZm9yIF8sIGlkIDo9IHJhbmdlIGlkcyB7CgkJaWYgcCwgb2sgOj0gZ2V0UG9zdChpZCk7IG9rIHsKCQkJcmVuZGVyUG9zdExpbmUoJnNiLCBwKQoJCX0KCX0KCXNiLldyaXRlU3RyaW5nKHVmbXQuU3ByaW50ZigiKnBhZ2UgJWQg4oCUIG9sZGVyOiBgOnVzZXIvJXMvJWRgKlxuIiwgaywgYWRkciwgaysxKSkKCXJldHVybiBzYi5TdHJpbmcoKQp9CgpmdW5jIHJlbmRlclBvc3QoaWQgdWludDY0KSBzdHJpbmcgewoJcCwgb2sgOj0gZ2V0UG9zdChpZCkKCWlmICFvayB7CgkJcmV0dXJuICIjIDQwNFxuUG9zdCBub3QgZm91bmQiCgl9CgkvLyBTYW1lIHN1cHByZXNzaW9uIHJ1bGUgYXMgY2hhbm5lbHNfdjI6IHRoZSBkaXJlY3QgcGF0aCBtdXN0IG5vdCBsZWFrCgkvLyBoaWRkZW4vZGVsZXRlZCBjb250ZW50LgoJaWYgcC5IaWRkZW4gfHwgcC5EZWxldGVkIHsKCQlyZXR1cm4gIiMgUG9zdCB1bmF2YWlsYWJsZVxuXG4qVGhpcyBwb3N0IGhhcyBiZWVuIGhpZGRlbiBvciByZW1vdmVkLipcbiIKCX0KCgl2YXIgc2Igc3RyaW5ncy5CdWlsZGVyCglzYi5Xcml0ZVN0cmluZyh1Zm10LlNwcmludGYoIiMgUG9zdCAlZFxuXG4iLCBwLklEKSkKCXJlbmRlclBvc3RMaW5lKCZzYiwgcCkKCgkvLyBOZXdlc3QgcmVwbHkgd2luZG93IG9ubHkgKGZpeGVkIHNpemUpOyBmdWxsIHRocmVhZCA9IEpTT04gY3Vyc29yIEFQSS4KCXJjIDo9IGdldFJlcGx5Q291bnQocC5JRCkKCWlmIHJjID4gMCB7CgkJc2IuV3JpdGVTdHJpbmcoIiMjIFJlcGxpZXNcblxuIikKCQlpZiByYyA+IEZlZWRQYWdlU2l6ZSB7CgkJCXNiLldyaXRlU3RyaW5nKHVmbXQuU3ByaW50ZigiKlNob3dpbmcgdGhlICVkIG5ld2VzdCBvZiAlZCDigJQgZnVsbCB0aHJlYWQgdmlhIExpc3RSZXBsaWVzSlNPTiBvciB0aGUgYXBwLipcblxuIiwgRmVlZFBhZ2VTaXplLCByYykpCgkJfQoJCWlkcyA6PSBjb2xsZWN0UGFnZShieVBhcmVudCwgcGFkSUQocC5JRCkrIjoiLCBwYWRJRChwLklEKSsiOlx4ZmYiLCAxKQoJCS8vIGNvbGxlY3RQYWdlIHdhbGtzIHJldmVyc2UgKG5ld2VzdCBmaXJzdCk7IHNob3cgb2xkZXN04oaSbmV3ZXN0LgoJCWZvciBpIDo9IGxlbihpZHMpIC0gMTsgaSA+PSAwOyBpLS0gewoJCQlpZiByLCBvayA6PSBnZXRQb3N0KGlkc1tpXSk7IG9rIHsKCQkJCXJlbmRlclBvc3RMaW5lKCZzYiwgcikKCQkJfQoJCX0KCX0KCXJldHVybiBzYi5TdHJpbmcoKQp9CgovLyDilIDilIAgU2hhcmVkIHJlbmRlciBoZWxwZXJzIChwb3J0ZWQgdmVyYmF0aW0gZnJvbSBjaGFubmVsc192Mikg4pSACgpmdW5jIHRydW5jQWRkcihhZGRyIGFkZHJlc3MpIHN0cmluZyB7CglzIDo9IHN0cmluZyhhZGRyKQoJaWYgbGVuKHMpID4gMTMgewoJCXJldHVybiBzWzoxMF0gKyAiLi4uIgoJfQoJcmV0dXJuIHMKfQoKLy8gc2FuaXRpemVGb3JSZW5kZXIgc3RyaXBzIG1hcmtkb3duLXNlbnNpdGl2ZSBjaGFyYWN0ZXJzIHRvIHByZXZlbnQgaW5qZWN0aW9uLgpmdW5jIHNhbml0aXplRm9yUmVuZGVyKHMgc3RyaW5nKSBzdHJpbmcgewoJdmFyIG91dCBzdHJpbmdzLkJ1aWxkZXIKCWZvciBfLCBjIDo9IHJhbmdlIHMgewoJCXN3aXRjaCBjIHsKCQljYXNlICdbJywgJ10nLCAnKCcsICcpJywgJyMnLCAnKicsICdgJywgJyEnLCAnPCcsICc+JywgJ3wnLCAnXFwnLCAnXycsICd+JywgJ1xuJywgJ1xyJywgJ1x0JzoKCQkJY29udGludWUKCQlkZWZhdWx0OgoJCQlvdXQuV3JpdGVSdW5lKGMpCgkJfQoJfQoJcmV0dXJuIG91dC5TdHJpbmcoKQp9CiIiChMvZ25vLk1lbVBhY2thZ2VUeXBlEgsKCU1QVXNlckFsbCINMTQwMDAwMDB1Z25vdBISCICq6lUSCzE4MDAwMHVnbm90GogDCs0BChIvdG0uUHViS2V5TXVsdGlzaWcStgEIAhI6ChMvdG0uUHViS2V5U2VjcDI1NmsxEiMKIQNdTsrzjy2oA1bKxxCiASBMVUReZbe8FQo/n1GUQS9f7RI6ChMvdG0uUHViS2V5U2VjcDI1NmsxEiMKIQMo44neuGQmEOBJpWfwt5YFd/18PcgdS1Pidavq3ZGmeBI6ChMvdG0uUHViS2V5U2VjcDI1NmsxEiMKIQMg5X9eKuwtmgamq/0K8oenVUfVQAsVWVenzmjN1+WBABKLAQoFCAMSAaASQLYPcdvoy/r2UVOwXCdspOdgD07Xl96pNLGhe3BsiIyWXWSuvh0FHs5y9pY6O0flbG6cmbwjaAr9JNUbUfUA1XUSQMpTEphW3eZ4HPXZudXvyGR+9ydy923gaaZ9HdHOmL9wZfFKRFdHsYJw3OqvnvGWGItVrq4WwHwMqSjtC+b+8ZgaKGcxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxbHV1eGU=