Transaction executed successfully
Transaction Details
Inspect execution, participants, message data, gas usage, events and raw transaction data.
Transaction hash
8C2A8C2FE8B9A34B2991E57B1D464050233381D1B728A24946646600BF4E4606
Transaction overview
Execution summary
TX INDEX
0
Position in block
GAS WANTED
219,548,157
Requested gas limit
GAS USED
182,956,847
Gas consumed
FEE
219549ugnot
Transaction fee
Participants
Message
Message #1
m_addpkg
Arguments
g1q5tjjv3kkslzwf2na9y9wk7e5a8ugph8xfsk04
Execution log
msg:0,success:true,log:,events:[]
Events
No events emitted by this transaction.
Raw encoded transaction
CoX8CAoML3ZtLm1fYWRkcGtnEvP7CAooZzFxNXRqanYza2tzbHp3ZjJuYTl5OXdrN2U1YTh1Z3BoOHhmc2swNBLF+wgKCmdvdmVybmFuY2USJGduby5sYW5kL3IvZ25vc3dhcC9nb3YvZ292ZXJuYW5jZS92MRrhOwoJUkVBRE1FLm1kEtM7IyBHb3Zlcm5hbmNlCgpEZWNlbnRyYWxpemVkIHByb3RvY29sIGdvdmVybmFuY2UgdmlhIEdOUyBzdGFraW5nIGFuZCB2b3RpbmcuCgojIyBPdmVydmlldwoKR292ZXJuYW5jZSBlbmFibGVzIEdOUyBob2xkZXJzIHRvIHN0YWtlIHRocm91Z2ggYGdvdi9zdGFrZXJgLCByZWNlaXZlIHhHTlMsIGRlbGVnYXRlIHZvdGluZyBwb3dlciwgY3JlYXRlIHByb3Bvc2FscywgYW5kIHZvdGUgb24gcHJvdG9jb2wgY2hhbmdlcy4gRm9yIG1vcmUgZGV0YWlscywgY2hlY2sgb3V0IFtkb2NzXShodHRwczovL2RvY3MuZ25vc3dhcC5pby9jb3JlLWNvbmNlcHRzL2dvdmVybmFuY2UpLgoKIyMgQ29uZmlndXJhdGlvbgoKVGhlIGBnb3Zlcm5hbmNlLkNvbmZpZ2AgdHlwZSBkZWZpbmVzIHRoZSBnb3Zlcm5hbmNlIHBhcmFtZXRlcnMuIFRoZSB2YWx1ZXMgdXNlZCBieSBhIHByb3Bvc2FsIGFyZSBzdG9yZWQgd2l0aCB0aGF0IHByb3Bvc2FsOyBsYXRlciByZWNvbmZpZ3VyYXRpb24gZG9lcyBub3QgcmV3cml0ZSBhbiBleGlzdGluZyBwcm9wb3NhbC4gVGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbiBjYW4gYmUgY2hhbmdlZCB0aHJvdWdoIHRoZSBnb3Zlcm5hbmNlIGBSZWNvbmZpZ3VyZWAgaGFuZGxlci4gVGhpcyB0eXBlIGNhbiBiZSBmb3VuZCBpbiBbLi4vY29uZmlnLmdub10oLi4vY29uZmlnLmdubykuCgp8IEZpZWxkIHwgRGVzY3JpcHRpb24gfCBEZWZhdWx0IHwKfC0tLS0tLS18LS0tLS0tLS0tLS0tLXwtLS0tLS0tLS18CnwgYFZvdGluZ1N0YXJ0RGVsYXlgIHwgRGVsYXkgYmVmb3JlIHZvdGluZyBzdGFydHMgYWZ0ZXIgcHJvcG9zYWwgY3JlYXRpb24gfCAxIGRheSB8CnwgYFZvdGluZ1BlcmlvZGAgfCBEdXJhdGlvbiBmb3IgY29sbGVjdGluZyB2b3RlcyB8IDcgZGF5cyB8CnwgYFZvdGluZ1dlaWdodFNtb290aGluZ0R1cmF0aW9uYCB8IER1cmF0aW9uIHVzZWQgZm9yIHRpbWVzdGFtcC1iYXNlZCB2b3Rpbmctd2VpZ2h0IGF2ZXJhZ2luZyB8IDEgZGF5IHwKfCBgUXVvcnVtYCB8IFBlcmNlbnRhZ2Ugb2YgdG90YWwgeEdOUyBzdXBwbHkgcmVxdWlyZWQgZm9yIHByb3Bvc2FsIHBhc3NhZ2U7IHRvdGFsIHN1cHBseSBpbmNsdWRlcyBsYXVuY2hwYWQtaGVsZCBpc3N1YW5jZSB8IDUwJSB8CnwgYFByb3Bvc2FsQ3JlYXRpb25UaHJlc2hvbGRgIHwgTWluaW11bSB4R05TIGJhbGFuY2UgcmVxdWlyZWQgdG8gY3JlYXRlIGEgcHJvcG9zYWwgfCAxLDAwMCwwMDAsMDAwIHhHTlMgfAp8IGBFeGVjdXRpb25EZWxheWAgfCBXYWl0aW5nIHBlcmlvZCBhZnRlciB2b3RpbmcgZW5kcyBiZWZvcmUgZXhlY3V0aW9uIHwgMSBkYXkgfAp8IGBFeGVjdXRpb25XaW5kb3dgIHwgVGltZSB3aW5kb3cgZHVyaW5nIHdoaWNoIGFuIGFwcHJvdmVkIHByb3Bvc2FsIGNhbiBiZSBleGVjdXRlZCB8IDMwIGRheXMgfAoKQWxsIHZhbHVlcyBhcmUgY29uZmlndXJhYmxlOyB0aGUgdmFsdWVzIGFib3ZlIGFyZSB0aGUgZGVmYXVsdHMgaW4gYE5ld0RlZmF1bHRDb25maWdgLgoKIyMgQ29yZSBNZWNoYW5pY3MKCiMjIyBTdGFraW5nIEZsb3cKCmBgYHBsYWluCkdOUyDihpIgRGVsZWdhdGUg4oaSIHhHTlMgKyBkZWxlZ2F0ZWQgdm90aW5nIGhpc3Rvcnkg4oaSIFZvdGUKYGBgCgoxLiBEZWxlZ2F0ZSBHTlMgdGhyb3VnaCBgZ292L3N0YWtlcmAgdG8gcmVjZWl2ZSBhbiBlcXVhbCBhbW91bnQgb2YgeEdOUy4KMi4gQXNzaWduIHZvdGluZyBwb3dlciB0byBhIGRlbGVnYXRlZSAod2hpY2ggbWF5IGJlIHRoZSBkZWxlZ2F0b3IgaXRzZWxmKS4KMy4gVm90ZSBvbiBwcm9wb3NhbHMgd2l0aCB0aGUgZGVsZWdhdGVlJ3MgdGltZXN0YW1wZWQgZGVsZWdhdGlvbiB3ZWlnaHQuCjQuIFVuZGVsZWdhdGlvbiByZW1vdmVzIHZvdGluZyBwb3dlciBpbW1lZGlhdGVseTsgdGhlIGRlZmF1bHQgbG9ja3VwIGJlZm9yZSBjb2xsZWN0aW5nIEdOUyBpcyA3IGRheXMgYW5kIGlzIGNvbmZpZ3VyYWJsZS4KCkxhdW5jaHBhZC1iYWNrZWQgeEdOUyBpcyBpbmNsdWRlZCBpbiB0b3RhbCB4R05TIHN1cHBseSBmb3IgcXVvcnVtLCBidXQgaXMgbm90IGFuIG9yZGluYXJ5IHVzZXIgZGVsZWdhdGlvbiByZWNvcmQuCgojIyMgUHJvcG9zYWwgVHlwZXMKCi0gKipUZXh0Kio6IFNpZ25hbCBwcm9wb3NhbHMgd2l0aG91dCBleGVjdXRpb24uCi0gKipDb21tdW5pdHlQb29sU3BlbmQqKjogVHJlYXN1cnkgZGlzYnVyc2VtZW50cyBlbmNvZGVkIGFzIGEgY29tbXVuaXR5LXBvb2wgdHJhbnNmZXIgb24gZXhlY3V0aW9uLgotICoqUGFyYW1ldGVyQ2hhbmdlKio6IFByb3RvY29sIHBhcmFtZXRlciB1cGRhdGVzIGRpc3BhdGNoZWQgdG8gcmVnaXN0ZXJlZCBoYW5kbGVycy4KCiMjIFByb3Bvc2FsIExpZmVjeWNsZQoKIyMjIENyZWF0aW9uCgotIFJlcXVpcmVzIHRoZSBjb25maWd1cmVkIGBQcm9wb3NhbENyZWF0aW9uVGhyZXNob2xkYCB4R05TIGJhbGFuY2UgKDEsMDAwLDAwMCwwMDAgeEdOUyBieSBkZWZhdWx0KS4KLSBPbmUgYWN0aXZlIHByb3Bvc2FsIHBlciBhZGRyZXNzLgotIFZhbGlkIHR5cGUgYW5kIHBhcmFtZXRlcnMgYXJlIHJlcXVpcmVkLiBDb21tdW5pdHktcG9vbCBzcGVuZCBhbW91bnRzIG11c3QgYmUgc3RyaWN0bHkgcG9zaXRpdmUsIHJlY2lwaWVudHMgbXVzdCBiZSB2YWxpZCwgYW5kIHRva2VuIHBhdGhzIG11c3QgYmUgcmVnaXN0ZXJlZC4KLSBBIHByb3Bvc2FsIHN0b3JlcyBpdHMgY29uZmlndXJhdGlvbiB2ZXJzaW9uLCBjcmVhdGlvbiB0aW1lc3RhbXAsIGNyZWF0aW9uIGJsb2NrIGhlaWdodCwgcXVvcnVtIGFtb3VudCwgYW5kIHRpbWVzdGFtcCB1c2VkIGZvciBoaXN0b3JpY2FsIGRlbGVnYXRpb24gbG9va3VwLiBUaGUgYmxvY2sgaGVpZ2h0IGlzIG1ldGFkYXRhOyB2b3Rpbmctd2VpZ2h0IGxvb2t1cCBpcyB0aW1lc3RhbXAtYmFzZWQuCgojIyMgVm90aW5nCgotIFZvdGluZyBzdGFydHMgYWZ0ZXIgdGhlIGNvbmZpZ3VyZWQgc3RhcnQgZGVsYXkgKDEgZGF5IGJ5IGRlZmF1bHQpIGFuZCBydW5zIGZvciB0aGUgY29uZmlndXJlZCB2b3RpbmcgcGVyaW9kICg3IGRheXMgYnkgZGVmYXVsdCkuCi0gV2VpZ2h0IGlzIHRoZSBhdmVyYWdlIG9mIHRoZSBjYWxsZXIncyBkZWxlZ2F0aW9uIGF0IHRoZSBwcm9wb3NhbCdzIHN0b3JlZCBzbmFwc2hvdCB0aW1lc3RhbXAgYW5kIGF0IHByb3Bvc2FsIGNyZWF0aW9uIHRpbWUuIFRoZSBzbmFwc2hvdCB0aW1lc3RhbXAgaXMgYGNyZWF0ZWRBdCAtIFZvdGluZ1dlaWdodFNtb290aGluZ0R1cmF0aW9uYCAoY2xhbXBlZCBhdCB6ZXJvKSwgYW5kIHRoZSBzbW9vdGhpbmcgZHVyYXRpb24gZGVmYXVsdHMgdG8gMjQgaG91cnMuCi0gRWFjaCBhZGRyZXNzIGNhbiB2b3RlIG9ubHkgb25jZSBvbiBhIHByb3Bvc2FsLiBgVm90ZWAgcmV0dXJucyB0aGUgYXBwbGllZCB2b3RlIHdlaWdodCBhcyBhIGRlY2ltYWwgc3RyaW5nLgoKIyMjIEV4ZWN1dGlvbgoKQSBwcm9wb3NhbCBpcyBjb25zaWRlcmVkIHZhbGlkIGFuZCBleGVjdXRhYmxlIHdoZW46CgotIFRoZSB2b3RpbmcgcGVyaW9kIGhhcyBlbmRlZC4KLSBUb3RhbCB2b3RlcyBtZWV0IHRoZSBxdW9ydW0gYW1vdW50IGNvbXB1dGVkIGF0IGNyZWF0aW9uIGZyb20gdGhlIHRvdGFsIHhHTlMgc3VwcGx5IChpbmNsdWRpbmcgbGF1bmNocGFkLWhlbGQgaXNzdWFuY2UpIGFuZCB0aGUgcHJvcG9zYWwncyBjb25maWd1cmVkIHF1b3J1bSBwZXJjZW50YWdlLgotIGBZRVNgIHZvdGVzIHN0cmljdGx5IGV4Y2VlZCBgTk9gIHZvdGVzICh0aWVzIGRvIG5vdCBwYXNzKS4KLSBUaGUgY29uZmlndXJlZCBleGVjdXRpb24gZGVsYXkgKDEgZGF5IGJ5IGRlZmF1bHQpIGhhcyBwYXNzZWQgYWZ0ZXIgdm90aW5nIGVuZHMuCi0gRXhlY3V0aW9uIG9jY3VycyB3aXRoaW4gdGhlIGNvbmZpZ3VyZWQgZXhlY3V0aW9uIHdpbmRvdyAoMzAgZGF5cyBieSBkZWZhdWx0KS4KLSBUZXh0IHByb3Bvc2FscyBhcmUgaW5mb3JtYXRpb25hbCBhbmQgY2Fubm90IGJlIGV4ZWN1dGVkOyBhbnlvbmUgY2FuIHRyaWdnZXIgZXhlY3V0aW9uIG9mIGFuIGFwcHJvdmVkIGV4ZWN1dGFibGUgcHJvcG9zYWwuCgpBbiBhcHByb3ZlZCBjb21tdW5pdHktcG9vbCBzcGVuZCBjYW4gc3RpbGwgZmFpbCBhdCBleGVjdXRpb24gaWYgdGhlIHBvb2wgbm8gbG9uZ2VyIGhhcyBlbm91Z2ggb2YgdGhlIHJlZ2lzdGVyZWQgdG9rZW4uCgojIyBUZWNobmljYWwgRGV0YWlscwoKIyMjIFZvdGUgV2VpZ2h0IENhbGN1bGF0aW9uCgpgYGBnbwovLyBgc21vb3RoaW5nYCBpcyB0aGUgcHJvcG9zYWwncyBjb25maWd1cmVkIFZvdGluZ1dlaWdodFNtb290aGluZ0R1cmF0aW9uLgpzbmFwc2hvdFRpbWUgPSBtYXgoY3JlYXRlZEF0IC0gc21vb3RoaW5nLCAwKQp3ZWlnaHRBdFNuYXBzaG90ID0gZ2V0RGVsZWdhdGlvbkF0KHZvdGVyLCBzbmFwc2hvdFRpbWUpCndlaWdodEF0Q3JlYXRpb24gPSBnZXREZWxlZ2F0aW9uQXQodm90ZXIsIGNyZWF0ZWRBdCkKdm90ZVdlaWdodCA9ICh3ZWlnaHRBdFNuYXBzaG90ICsgd2VpZ2h0QXRDcmVhdGlvbikgLyAyCmBgYAoKVGhlIGxvb2t1cHMgcmVhZCBkZWxlZ2F0aW9uIGhpc3RvcnkgYnkgVW5peCB0aW1lc3RhbXAuIFRoaXMgaXMgbm90IGEgYmxvY2staGVpZ2h0IHNuYXBzaG90LgoKIyMjIFF1b3J1bSBDYWxjdWxhdGlvbgoKYGBgZ28KcXVvcnVtV2VpZ2h0ID0gdG90YWxYR25zU3VwcGx5QXRQcm9wb3NhbENyZWF0aW9uIC8vIGluY2x1ZGVzIGxhdW5jaHBhZC1oZWxkIHhHTlMKcXVvcnVtQW1vdW50ID0gcXVvcnVtV2VpZ2h0ICogcXVvcnVtUGVyY2VudCAvIDEwMCAgLy8gcXVvcnVtUGVyY2VudCBkZWZhdWx0cyB0byA1MApgYGAKClRoZSBxdW9ydW0gYW1vdW50IGlzIHN0b3JlZCBvbiB0aGUgcHJvcG9zYWwgYW5kIGlzIG5vdCByZWNvbXB1dGVkIGZyb20gdGhlIHByb3Bvc2VyJ3Mgb3Igdm90ZXJzJyBzbW9vdGhlZCB2b3Rpbmcgd2VpZ2h0LiBBIHByb3Bvc2FsIHBhc3NlcyBvbmx5IHdoZW4gdG90YWwgdm90ZXMgcmVhY2ggcXVvcnVtIGFuZCBhY2N1bXVsYXRlZCBgWUVTYCB2b3RlcyBzdHJpY3RseSBleGNlZWQgYWNjdW11bGF0ZWQgYE5PYCB2b3Rlcy4KCiMjIyBSZXdhcmRzIERpc3RyaWJ1dGlvbgoKR292L3N0YWtlciBleHBvc2VzIHR3byByZXdhcmQgc3RyZWFtczoKCjEuICoqR05TIGVtaXNzaW9uIHJld2FyZHMqKiB1c2UgdGhlIGVtaXNzaW9uIGFjY3VtdWxhdG9yIGFuZCBlYWNoIHN0YWtlcidzIG93biBzdGFrZSBoaXN0b3J5LgoyLiAqKlByb3RvY29sLWZlZSByZXdhcmRzKiogYXJlIHRyYWNrZWQgcGVyIHRva2VuIGFuZCBhY2NydWFsIGVwb2NoLiBFYWNoIGNvbnN1bWVkIGJ1Y2tldCBpcyBkaXZpZGVkIGJ5IHRoZSB0b3RhbCBzdGFrZSBpbiBmb3JjZSBkdXJpbmcgdGhhdCBlcG9jaCwgYWRkZWQgdG8gdGhhdCB0b2tlbidzIFExMjggYWNjdW11bGF0b3IsIGFuZCBzZXR0bGVkIG92ZXIgdGhlIHN0YWtlcidzIHN0YWtlLWV2ZW50IHNlZ21lbnRzLiBTdWItdW5pdCBRMTI4IHJlbWFpbmRlcnMgYXJlIHJldGFpbmVkIGZvciBsYXRlciBjb2xsZWN0aW9uLgoKYENvbGxlY3RSZXdhcmRgIHNldHRsZXMgdGhlIGVtaXNzaW9uIHN0cmVhbSBhbmQgZXZlcnkga25vd24gcHJvdG9jb2wtZmVlIHRva2VuLiBgQ29sbGVjdEVtaXNzaW9uUmV3YXJkYCBhbmQgYENvbGxlY3RQcm90b2NvbEZlZVJld2FyZCh0b2tlblBhdGgpYCBhcmUgbmFycm93ZXIgcGF0aHM7IHRoZSB0b2tlbi1zcGVjaWZpYyBwcm90b2NvbC1mZWUgcGF0aCBib3VuZHMgYm90aCBwZW5kaW5nIGFjY3J1YWwgYnVja2V0cyBhbmQgc3Rha2UgZXZlbnRzIHBlciBjYWxsLCBzbyByZW1haW5pbmcgd29yayBpcyBjb2xsZWN0ZWQgbGF0ZXIuIExhdW5jaHBhZCBwcm9qZWN0IHdhbGxldHMgdXNlIHRoZSBjb3JyZXNwb25kaW5nIGxhdW5jaHBhZC1vbmx5IGVudHJ5IHBvaW50cy4KCiMjIFVzYWdlCgpUaGVzZSBzbmlwcGV0cyBjYWxsIHRoZSBwdWJsaWMgZG9tYWluIHByb3hpZXMgZnJvbSBhIHJlYWxtIGZ1bmN0aW9uIHdpdGggYSBjdXJyZW50IGBjdXJgIHRva2VuLgpJbXBvcnQgdGhlIGNvcnJlc3BvbmRpbmcgcHJveHkgcGFja2FnZXMgYW5kIHF1YWxpZnkgdGhlaXIgZnVuY3Rpb24gbmFtZXMgaW4gaW50ZWdyYXRpbmcgY29kZS4KCmBgYGdvCi8vIFRocm91Z2ggZ292L3N0YWtlcjogZGVsZWdhdGUgR05TIGZvciB4R05TIHZvdGluZyBwb3dlci4KRGVsZWdhdGUoY3Jvc3MoY3VyKSwgZGVsZWdhdGVlLCAxXzAwMF8wMDBfMDAwLCAiZzFyZWZlcnJlci4uLiIpCgovLyBDcmVhdGUgYSB0ZXh0IG9yIGNvbW11bml0eS1wb29sIHByb3Bvc2FsLgpQcm9wb3NlVGV4dChjcm9zcyhjdXIpLCAiVGl0bGUiLCAiRGVzY3JpcHRpb24iKQpQcm9wb3NlQ29tbXVuaXR5UG9vbFNwZW5kKGNyb3NzKGN1ciksICJUaXRsZSIsICJEZXNjcmlwdGlvbiIsIHJlY2lwaWVudCwgdG9rZW5QYXRoLCBhbW91bnQpCgovLyBBIHBhcmFtZXRlci1jaGFuZ2UgZXhlY3V0aW9uIHVzZXMgYSByZWdpc3RlcmVkIGhhbmRsZXIuIFRoaXMgaXMgb25lIHZhbGlkCi8vIFJlY29uZmlndXJlIG1lc3NhZ2UgKGFsbCBzZXZlbiBwYXJhbWV0ZXJzIGFyZSByZXF1aXJlZCkuCmV4ZWN1dGlvbiA6PSAiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9nb3Zlcm5hbmNlKkVYRSpSZWNvbmZpZ3VyZSpFWEUqODY0MDAsNjA0ODAwLDg2NDAwLDUwLDEwMDAwMDAwMDAsODY0MDAsMjU5MjAwMCIKUHJvcG9zZVBhcmFtZXRlckNoYW5nZShjcm9zcyhjdXIpLCAiVXBkYXRlIGNvbmZpZyIsICJSYXRpb25hbGUiLCAxLCBleGVjdXRpb24pCgovLyBWb3RlOyB0aGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBhcHBsaWVkIHdlaWdodCBmb3JtYXR0ZWQgYXMgYSBkZWNpbWFsIHN0cmluZy4Kdm90ZVdlaWdodCA6PSBWb3RlKGNyb3NzKGN1ciksIHByb3Bvc2FsSWQsIHRydWUpIC8vIFlFUwoKLy8gRXhlY3V0ZSBhZnRlciB0aGUgY29uZmlndXJlZCB0aW1lbG9jayBhbmQgdGhlbiwgaWYgbmVlZGVkLCBzdGFydCB1bmRlbGVnYXRpb24uCkV4ZWN1dGUoY3Jvc3MoY3VyKSwgcHJvcG9zYWxJZCkKVW5kZWxlZ2F0ZShjcm9zcyhjdXIpLCBkZWxlZ2F0ZWUsIDI1MF8wMDBfMDAwKQoKLy8gQ29sbGVjdCBvbmx5IGFmdGVyIHRoZSBjb25maWd1cmVkIHVuZGVsZWdhdGlvbiBsb2NrdXAgaGFzIGV4cGlyZWQuCkNvbGxlY3RVbmRlbGVnYXRlZEducyhjcm9zcyhjdXIpKQpgYGAKCiMjIFNlY3VyaXR5CgotIFRpbWVzdGFtcC1iYXNlZCBzbW9vdGhpbmcgcmVkdWNlcyBmbGFzaC1sb2FuLXN0eWxlIHZvdGluZyBtYW5pcHVsYXRpb247IGl0IGlzIG5vdCBhIGJsb2NrIHNuYXBzaG90LgotIFN5YmlsIHJlc2lzdGFuY2UgY29tZXMgZnJvbSBzdGFrZS13ZWlnaHRlZCBkZWxlZ2F0aW9uLgotIFRoZSBleGVjdXRpb24gZGVsYXkgYW5kIHdpbmRvdyBjb25zdHJhaW4gd2hlbiBhcHByb3ZlZCBleGVjdXRhYmxlIHByb3Bvc2FscyBjYW4gcnVuLgotIEEgc2luZ2xlIGFjdGl2ZSBwcm9wb3NhbCBpcyBhbGxvd2VkIHBlciBwcm9wb3NlciBhZGRyZXNzLgotIFF1b3J1bSBpcyBmaXhlZCBmcm9tIHRoZSBjcmVhdGlvbi10aW1lIHRvdGFsIHhHTlMgc3VwcGx5LCBpbmNsdWRpbmcgbGF1bmNocGFkLWhlbGQgaXNzdWFuY2UuCi0gQ29tbXVuaXR5LXBvb2wgYmFsYW5jZSBpcyBjaGVja2VkIHdoZW4gdGhlIGFwcHJvdmVkIHRyYW5zZmVyIGV4ZWN1dGVzLCBub3Qgd2hlbiB0aGUgcHJvcG9zYWwgaXMgY3JlYXRlZC4KGuwSCgphc3NlcnQuZ25vEt0ScGFja2FnZSBnb3Zlcm5hbmNlCgppbXBvcnQgKAoJImVycm9ycyIKCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgkiZ25vLmxhbmQvci9nbm9zd2FwL2NvbW1vbiIKCSJnbm8ubGFuZC9yL2dub3N3YXAvaGFsdC92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9nb3Zlcm5hbmNlIgopCgovLyBhc3NlcnRJc05vdEhhbHRlZEdvdmVybmFuY2VGb3JQcm9wb3NhbERhdGEgcGFuaWNzIGlmIGdvdmVybmFuY2UgaXMgaGFsdGVkLAovLyB1bmxlc3MgdGhlIHByb3Bvc2FsIG9ubHkgdGFyZ2V0cyB0aGUgaGFsdCByZWFsbS4KLy8gVGhpcyBrZWVwcyBhIHJlY292ZXJ5IHBhdGggb3BlbiBzbyBnb3Zlcm5hbmNlIGNhbiB1bmhhbHQgaXRzZWxmLgpmdW5jIGFzc2VydElzTm90SGFsdGVkR292ZXJuYW5jZUZvclByb3Bvc2FsRGF0YShwcm9wb3NhbERhdGEgKmdvdmVybmFuY2UuUHJvcG9zYWxEYXRhKSB7CglpZiBpc0hhbHRSZWNvdmVyeVByb3Bvc2FsRGF0YShwcm9wb3NhbERhdGEpIHsKCQlyZXR1cm4KCX0KCgloYWx0LkFzc2VydElzTm90SGFsdGVkR292ZXJuYW5jZSgpCn0KCi8vIGFzc2VydElzTm90SGFsdGVkR292ZXJuYW5jZUZvclByb3Bvc2FsIHBhbmljcyBpZiBnb3Zlcm5hbmNlIGlzIGhhbHRlZCwKLy8gdW5sZXNzIHRoZSBwcm9wb3NhbCBvbmx5IHRhcmdldHMgdGhlIGhhbHQgcmVhbG0uCmZ1bmMgYXNzZXJ0SXNOb3RIYWx0ZWRHb3Zlcm5hbmNlRm9yUHJvcG9zYWwoZ3YgKmdvdmVybmFuY2VWMSwgcHJvcG9zYWxJRCBpbnQ2NCkgewoJcHJvcG9zYWwsIGV4aXN0cyA6PSBndi5nZXRQcm9wb3NhbChwcm9wb3NhbElEKQoJaWYgIWV4aXN0cyB7CgkJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZEdvdmVybmFuY2UoKQoJCXJldHVybgoJfQoKCWFzc2VydElzTm90SGFsdGVkR292ZXJuYW5jZUZvclByb3Bvc2FsRGF0YShwcm9wb3NhbC5EYXRhKCkpCn0KCi8vIGlzSGFsdFJlY292ZXJ5UHJvcG9zYWxEYXRhIHJldHVybnMgdHJ1ZSBpZiB0aGUgcHJvcG9zYWwgaXMgYSBwYXJhbWV0ZXIgY2hhbmdlCi8vIHdob3NlIGV2ZXJ5IGV4ZWN1dGlvbiB0YXJnZXRzIHRoZSBoYWx0IHJlYWxtLgpmdW5jIGlzSGFsdFJlY292ZXJ5UHJvcG9zYWxEYXRhKHByb3Bvc2FsRGF0YSAqZ292ZXJuYW5jZS5Qcm9wb3NhbERhdGEpIGJvb2wgewoJaWYgcHJvcG9zYWxEYXRhID09IG5pbCB8fCBwcm9wb3NhbERhdGEuUHJvcG9zYWxUeXBlKCkgIT0gZ292ZXJuYW5jZS5QYXJhbWV0ZXJDaGFuZ2UgewoJCXJldHVybiBmYWxzZQoJfQoKCWluZm9zLCBlcnIgOj0gTmV3UHJvcG9zYWxEYXRhUmVzb2x2ZXIocHJvcG9zYWxEYXRhKS5QYXJhbWV0ZXJDaGFuZ2VzSW5mb3MoKQoJaWYgZXJyICE9IG5pbCB8fCBsZW4oaW5mb3MpID09IDAgewoJCXJldHVybiBmYWxzZQoJfQoKCWZvciBfLCBpbmZvIDo9IHJhbmdlIGluZm9zIHsKCQlpZiBpbmZvLlBrZ1BhdGgoKSAhPSBIQUxUX1BBVEggewoJCQlyZXR1cm4gZmFsc2UKCQl9Cgl9CgoJcmV0dXJuIHRydWUKfQoKLy8gYXNzZXJ0Q2FsbGVySXNQcm9wb3NlciBwYW5pY3MgaWYgdGhlIGNhbGxlciBpcyBub3QgdGhlIHByb3Bvc2VyIG9mIHRoZSBnaXZlbiBwcm9wb3NhbC4KZnVuYyBhc3NlcnRDYWxsZXJJc1Byb3Bvc2VyKGd2ICpnb3Zlcm5hbmNlVjEsIHByb3Bvc2FsSUQgaW50NjQsIGNhbGxlciBhZGRyZXNzKSB7Cglwcm9wb3NhbCwgZXhpc3RzIDo9IGd2LmdldFByb3Bvc2FsKHByb3Bvc2FsSUQpCglpZiAhZXhpc3RzIHsKCQlwYW5pYyhlcnJvcnMuTmV3KGVyclByb3Bvc2FsTm90Rm91bmQpKQoJfQoKCWlmICFwcm9wb3NhbC5Jc1Byb3Bvc2VyKGNhbGxlcikgewoJCXBhbmljKGVycm9ycy5OZXcoZXJyTm90UHJvcG9zZXIpKQoJfQp9CgpmdW5jIGFzc2VydElzVmFsaWRTbW9vdGhpbmdQZXJpb2Qoc21vb3RoaW5nUGVyaW9kIGludDY0KSB7CglpZiBzbW9vdGhpbmdQZXJpb2QgPCAwIHsKCQlwYW5pYyhlcnJvcnMuTmV3KGVyckludmFsaWRTbW9vdGhpbmdQZXJpb2QpKQoJfQoKCWlmIHNtb290aGluZ1BlcmlvZCA+IG1heFNtb290aGluZ1BlcmlvZCB7CgkJcGFuaWMoZXJyb3JzLk5ldyhlcnJJbnZhbGlkU21vb3RoaW5nUGVyaW9kKSkKCX0KfQoKZnVuYyBhc3NlcnRJc1ZhbGlkVG9rZW4odG9rZW5QYXRoIHN0cmluZykgewoJaWYgdG9rZW5QYXRoID09ICIiIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZElucHV0LCAidG9rZW5QYXRoIGlzIGVtcHR5IikpCgl9CgoJaWYgZXJyIDo9IGNvbW1vbi5Jc1JlZ2lzdGVyZWQodG9rZW5QYXRoKTsgZXJyICE9IG5pbCB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRJbnB1dCwKCQkJdWZtdC5TcHJpbnRmKCJ0b2tlbiglcykgaXMgbm90IHJlZ2lzdGVyZWQiLCB0b2tlblBhdGgpLAoJCSkpCgl9Cn0KGoAhCgpjb25maWcuZ25vEvEgcGFja2FnZSBnb3Zlcm5hbmNlCgppbXBvcnQgKAoJImNoYWluIgoJInRpbWUiCgoJImduby5sYW5kL3AvZ25vc3dhcC91dGlscy92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKCWVuICJnbm8ubGFuZC9yL2dub3N3YXAvZW1pc3Npb24iCgkiZ25vLmxhbmQvci9nbm9zd2FwL2hhbHQvdjEiCgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3YvZ292ZXJuYW5jZSIKKQoKLy8gbWFrZUNvbmZpZyBjcmVhdGVzIGEgbmV3IGdvdmVybmFuY2UgY29uZmlndXJhdGlvbi4KZnVuYyBtYWtlQ29uZmlnKAoJdm90aW5nU3RhcnREZWxheSBpbnQ2NCwKCXZvdGluZ1BlcmlvZCBpbnQ2NCwKCXZvdGluZ1dlaWdodFNtb290aGluZ0R1cmF0aW9uIGludDY0LAoJcXVvcnVtIGludDY0LAoJcHJvcG9zYWxDcmVhdGlvblRocmVzaG9sZCBpbnQ2NCwKCWV4ZWN1dGlvbkRlbGF5IGludDY0LAoJZXhlY3V0aW9uV2luZG93IGludDY0LAopIGdvdmVybmFuY2UuQ29uZmlnIHsKCS8vIENyZWF0ZSBuZXcgY29uZmlndXJhdGlvbiB3aXRoIHByb3ZpZGVkIHBhcmFtZXRlcnMuIENvbnN0cnVjdGVkIHZpYSB0aGUKCS8vIGRvbWFpbiBjb25zdHJ1Y3RvciBzbyB0aGUgQ29uZmlnIHZhbHVlIGlzIGFsbG9jYXRlZCBpbnNpZGUgdGhlIGdvdmVybmFuY2UKCS8vIGRvbWFpbiByZWFsbSAoc2F0aXNmaWVzIHRoZSByZWFsbSBhbGxvY2F0aW9uIGNoZWNrKS4KCXJldHVybiBnb3Zlcm5hbmNlLk5ld0NvbmZpZygKCQl2b3RpbmdTdGFydERlbGF5LAoJCXZvdGluZ1BlcmlvZCwKCQl2b3RpbmdXZWlnaHRTbW9vdGhpbmdEdXJhdGlvbiwKCQlxdW9ydW0sCgkJcHJvcG9zYWxDcmVhdGlvblRocmVzaG9sZCwKCQlleGVjdXRpb25EZWxheSwKCQlleGVjdXRpb25XaW5kb3csCgkpCn0KCi8vIFJlY29uZmlndXJlIHVwZGF0ZXMgZ292ZXJuYW5jZSBjb25maWd1cmF0aW9uLgovLyBPbmx5IGFkbWluIG9yIGdvdmVybmFuY2UgY29udHJhY3QgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbi4KLy8gVXBkYXRlcyBhbGwgZ292ZXJuYW5jZSBwYXJhbWV0ZXJzIGFuZCBlbWl0cyBhICJSZWNvbmZpZ3VyZSIgZXZlbnQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCB1bmNoYW5nZWQgYnkgdGhlIGdvdmVybmFuY2UgcHJveHk7IHZhbGlkYXRlZCBiZWZvcmUgZXh0ZXJuYWwgY2FsbHMuCi8vICAgLSB2b3RpbmdTdGFydERlbGF5OiBkZWxheSBpbiBzZWNvbmRzIGZyb20gcHJvcG9zYWwgY3JlYXRpb24gdW50aWwgdm90aW5nIHN0YXJ0cwovLyAgIC0gdm90aW5nUGVyaW9kOiBkdXJhdGlvbiBpbiBzZWNvbmRzIGZvciB3aGljaCB2b3RpbmcgcmVtYWlucyBvcGVuCi8vICAgLSB2b3RpbmdXZWlnaHRTbW9vdGhpbmdEdXJhdGlvbjogZHVyYXRpb24gaW4gc2Vjb25kcyB1c2VkIHRvIHNtb290aCB2b3Rpbmcgd2VpZ2h0IHNuYXBzaG90cwovLyAgIC0gcXVvcnVtOiBxdW9ydW0gcGVyY2VudGFnZSBhcHBsaWVkIHRvIHRoZSBwcm9wb3NhbCdzIHF1b3J1bS13ZWlnaHQgYmFzZQovLyAgIC0gcHJvcG9zYWxDcmVhdGlvblRocmVzaG9sZDogbWluaW11bSB2b3Rpbmcgd2VpZ2h0IHJlcXVpcmVkIHRvIGNyZWF0ZSBhIHByb3Bvc2FsCi8vICAgLSBleGVjdXRpb25EZWxheTogZGVsYXkgaW4gc2Vjb25kcyBmcm9tIHZvdGluZyBlbmQgdW50aWwgZXhlY3V0aW9uIGJlY29tZXMgYXZhaWxhYmxlCi8vICAgLSBleGVjdXRpb25XaW5kb3c6IGR1cmF0aW9uIGluIHNlY29uZHMgZHVyaW5nIHdoaWNoIGFuIGV4ZWN1dGFibGUgcHJvcG9zYWwgbWF5IHJ1bgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IG5ld2x5IHN0b3JlZCBnb3Zlcm5hbmNlIGNvbmZpZ3VyYXRpb24gdmVyc2lvbgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBSZWNvbmZpZ3VyZSgKCV8gaW50LCBybG0gcmVhbG0sCgl2b3RpbmdTdGFydERlbGF5IGludDY0LAoJdm90aW5nUGVyaW9kIGludDY0LAoJdm90aW5nV2VpZ2h0U21vb3RoaW5nRHVyYXRpb24gaW50NjQsCglxdW9ydW0gaW50NjQsCglwcm9wb3NhbENyZWF0aW9uVGhyZXNob2xkIGludDY0LAoJZXhlY3V0aW9uRGVsYXkgaW50NjQsCglleGVjdXRpb25XaW5kb3cgaW50NjQsCikgaW50NjQgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJLy8gQ2hlY2sgaWYgc3lzdGVtIGlzIGhhbHRlZCBiZWZvcmUgcHJvY2VlZGluZwoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZEdvdmVybmFuY2UoKQoKCXByZXYgOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2LkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzQWRtaW5PckdvdmVybmFuY2UoY2FsbGVyKQoKCWFzc2VydElzVmFsaWRTbW9vdGhpbmdQZXJpb2Qodm90aW5nV2VpZ2h0U21vb3RoaW5nRHVyYXRpb24pCgoJLy8gQ3JlYXRlIGFuZCB2YWxpZGF0ZSBuZXcgY29uZmlndXJhdGlvbgoJbmV3Q2ZnIDo9IG1ha2VDb25maWcoCgkJdm90aW5nU3RhcnREZWxheSwKCQl2b3RpbmdQZXJpb2QsCgkJdm90aW5nV2VpZ2h0U21vb3RoaW5nRHVyYXRpb24sCgkJcXVvcnVtLAoJCXByb3Bvc2FsQ3JlYXRpb25UaHJlc2hvbGQsCgkJZXhlY3V0aW9uRGVsYXksCgkJZXhlY3V0aW9uV2luZG93LAoJKQoKCWN1cnJlbnRUaW1lIDo9IHRpbWUuTm93KCkuVW5peCgpCgoJaWYgZXJyIDo9IG5ld0NmZy5Jc1ZhbGlkKGN1cnJlbnRUaW1lKTsgZXJyICE9IG5pbCB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoZXJySW52YWxpZENvbmZpZ3VyYXRpb24sIGVyci5FcnJvcigpKSkKCX0KCgkvLyBNaW50IGFuZCBkaXN0cmlidXRlIEdOUyB0b2tlbnMgYXMgcGFydCBvZiB0aGUgcHJvY2VzcwoJZW4uTWludEFuZERpc3RyaWJ1dGVHbnMoY3Jvc3MocmxtKSkKCgkvLyBTdG9yZSBwcmV2aW91cyB2ZXJzaW9uIGZvciBldmVudCBlbWlzc2lvbgoJcHJldmlvdXNWZXJzaW9uIDo9IGd2LmdldEN1cnJlbnRDb25maWdWZXJzaW9uKCkKCgkvLyBBcHBseSB0aGUgbmV3IGNvbmZpZ3VyYXRpb24KCW5leHRWZXJzaW9uIDo9IGd2LnJlY29uZmlndXJlKDAsIHJsbSwgbmV3Q2ZnKQoKCWNoYWluLkVtaXQoCgkJIlJlY29uZmlndXJlIiwKCQkicHJldkFkZHIiLCBjYWxsZXIuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXYuUGtnUGF0aCgpLAoJCSJ2b3RpbmdTdGFydERlbGF5IiwgdXRpbHMuRm9ybWF0SW50KG5ld0NmZy5Wb3RpbmdTdGFydERlbGF5KSwKCQkidm90aW5nUGVyaW9kIiwgdXRpbHMuRm9ybWF0SW50KG5ld0NmZy5Wb3RpbmdQZXJpb2QpLAoJCSJ2b3RpbmdXZWlnaHRTbW9vdGhpbmdEdXJhdGlvbiIsIHV0aWxzLkZvcm1hdEludChuZXdDZmcuVm90aW5nV2VpZ2h0U21vb3RoaW5nRHVyYXRpb24pLAoJCSJxdW9ydW0iLCB1dGlscy5Gb3JtYXRJbnQobmV3Q2ZnLlF1b3J1bSksCgkJInByb3Bvc2FsQ3JlYXRpb25UaHJlc2hvbGQiLCB1dGlscy5Gb3JtYXRJbnQobmV3Q2ZnLlByb3Bvc2FsQ3JlYXRpb25UaHJlc2hvbGQpLAoJCSJleGVjdXRpb25EZWxheSIsIHV0aWxzLkZvcm1hdEludChuZXdDZmcuRXhlY3V0aW9uRGVsYXkpLAoJCSJleGVjdXRpb25QZXJpb2QiLCB1dGlscy5Gb3JtYXRJbnQobmV3Q2ZnLkV4ZWN1dGlvbldpbmRvdyksCgkJIm5ld0NvbmZpZ1ZlcnNpb24iLCB1dGlscy5Gb3JtYXRJbnQobmV4dFZlcnNpb24pLAoJCSJwcmV2Q29uZmlnVmVyc2lvbiIsIHV0aWxzLkZvcm1hdEludChwcmV2aW91c1ZlcnNpb24pLAoJKQoKCXJldHVybiBuZXh0VmVyc2lvbgp9CgovLyByZWNvbmZpZ3VyZSBzdG9yZXMgdGhlIHZhbGlkYXRlZCBjb25maWd1cmF0aW9uIHdpdGggaW5jcmVtZW50ZWQgdmVyc2lvbiBudW1iZXIuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIHJlY29uZmlndXJlKF8gaW50LCBybG0gcmVhbG0sIGNmZyBnb3Zlcm5hbmNlLkNvbmZpZykgaW50NjQgewoJLy8gR2VuZXJhdGUgbmV4dCB2ZXJzaW9uIG51bWJlcgoJbmV4dFZlcnNpb24gOj0gZ3YubmV4dENvbmZpZ1ZlcnNpb24oMCwgcmxtKQoKCS8vIFN0b3JlIHRoZSBuZXcgY29uZmlndXJhdGlvbiB3aXRoIHZlcnNpb24KCWVyciA6PSBndi5zZXRDb25maWcoMCwgcmxtLCBuZXh0VmVyc2lvbiwgY2ZnKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoImZhaWxlZCB0byBzZXQgY29uZmlnOiAiICsgZXJyLkVycm9yKCkpCgl9CgoJcmV0dXJuIG5leHRWZXJzaW9uCn0KGpEECgpjb25zdHMuZ25vEoIEcGFja2FnZSBnb3Zlcm5hbmNlCgpjb25zdCAoCgkvLyBHb3Zlcm5hbmNlIGNhbiBleGVjdXRlIG11bHRpcGxlIG1lc3NhZ2VzIGluIGEgc2luZ2xlIHByb3Bvc2FsCgkvLyBlYWNoIG1lc3NhZ2UgaXMgYSBzdHJpbmcgd2l0aCB0aGUgZm9sbG93aW5nIGZvcm1hdDoKCS8vIDxwa2dQYXRoPipFWEUqPGZ1bmN0aW9uPipFWEUqPHBhcmFtcz4KCS8vIFRvIGV4ZWN1dGUgYSBtZXNzYWdlLCB3ZSBuZWVkIHRvIHBhcnNlIHRoZSBtZXNzYWdlIGFuZCBjYWxsIHRoZSBjb3JyZXNwb25kaW5nIGZ1bmN0aW9uCgkvLyB3aXRoIHRoZSBnaXZlbiBwYXJhbWV0ZXJzCglwYXJhbWV0ZXJTZXBhcmF0b3IgPSAiKkVYRSoiCgoJbWVzc2FnZVNlcGFyYXRvciA9ICIqR09WKiIKCgltYXhUaXRsZUxlbmd0aCAgICAgICA9IDI1NQoJbWF4RGVzY3JpcHRpb25MZW5ndGggPSAxMF8wMDAKCW1heE51bWJlck9mRXhlY3V0aW9uID0gMTAKCW1heFNtb290aGluZ1BlcmlvZCAgID0gMzAgKiA2MCAqIDYwICogMjQgLy8gMzAgZGF5cwopChoeCgdkb2MuZ25vEhNwYWNrYWdlIGdvdmVybmFuY2UKGroOCgplcnJvcnMuZ25vEqsOcGFja2FnZSBnb3Zlcm5hbmNlCgppbXBvcnQgKAoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgopCgpjb25zdCAoCgllcnJJbnZhbGlkSW5wdXQgICAgICAgICAgICAgICAgID0gIltHTk9TV0FQLUdPVkVSTkFOQ0UtMDAxXSBpbnZhbGlkIGlucHV0IgoJZXJyRGF0YU5vdEZvdW5kICAgICAgICAgICAgICAgICA9ICJbR05PU1dBUC1HT1ZFUk5BTkNFLTAwMl0gcmVxdWVzdGVkIGRhdGEgbm90IGZvdW5kIgoJZXJyTm90RW5vdWdoQmFsYW5jZSAgICAgICAgICAgICA9ICJbR05PU1dBUC1HT1ZFUk5BTkNFLTAwM10gbm90IGVub3VnaCBiYWxhbmNlIgoJZXJyQWxyZWFkeVZvdGVkICAgICAgICAgICAgICAgICA9ICJbR05PU1dBUC1HT1ZFUk5BTkNFLTAwNF0gY2Fubm90IHZvdGUgdHdpY2UiCgllcnJOb3RFbm91Z2hWb3RpbmdXZWlnaHQgICAgICAgID0gIltHTk9TV0FQLUdPVkVSTkFOQ0UtMDA1XSBub3QgZW5vdWdoIHZvdGluZyBwb3dlciIKCWVyckFscmVhZHlDYW5jZWxlZFByb3Bvc2FsICAgICAgPSAiW0dOT1NXQVAtR09WRVJOQU5DRS0wMDZdIGNhbm5vdCBjYW5jZWwgYWxyZWFkeSBjYW5jZWxlZCBwcm9wb3NhbCIKCWVyclVuYWJsZVRvQ2FuY2VsVm90aW5nUHJvcG9zYWwgPSAiW0dOT1NXQVAtR09WRVJOQU5DRS0wMDddIHVuYWJsZSB0byBjYW5jZWwgdm90aW5nIHByb3Bvc2FsIgoJZXJyVGV4dFByb3Bvc2FsTm90RXhlY3V0YWJsZSAgICA9ICJbR05PU1dBUC1HT1ZFUk5BTkNFLTAwOF0gY2Fubm90IGV4ZWN1dGUgdGV4dCBwcm9wb3NhbCIKCWVyclVuYWJsZVRvVm90ZU91dE9mUGVyaW9kICAgICAgPSAiW0dOT1NXQVAtR09WRVJOQU5DRS0wMDldIHVuYWJsZSB0byB2b3RlIG91dCBvZiB2b3RpbmcgcGVyaW9kIgoJZXJySW52YWxpZE1lc3NhZ2VGb3JtYXQgICAgICAgICA9ICJbR05PU1dBUC1HT1ZFUk5BTkNFLTAxMF0gaW52YWxpZCBtZXNzYWdlIGZvcm1hdCIKCWVyckFscmVhZHlBY3RpdmVQcm9wb3NhbCAgICAgICAgPSAiW0dOT1NXQVAtR09WRVJOQU5DRS0wMTFdIGFscmVhZHkgYWN0aXZlIHByb3Bvc2FsIgoJZXJyUHJvcG9zYWxOb3RGb3VuZCAgICAgICAgICAgICA9ICJbR05PU1dBUC1HT1ZFUk5BTkNFLTAxMl0gcHJvcG9zYWwgbm90IGZvdW5kIgoJZXJyUHJvcG9zYWxOb3RFeGVjdXRhYmxlICAgICAgICA9ICJbR05PU1dBUC1HT1ZFUk5BTkNFLTAxM10gcHJvcG9zYWwgbm90IGV4ZWN1dGFibGUiCgllcnJOb3RQcm9wb3NlciAgICAgICAgICAgICAgICAgID0gIltHTk9TV0FQLUdPVkVSTkFOQ0UtMDE0XSBub3QgcHJvcG9zZXIiCgllcnJJbnZhbGlkQ29uZmlndXJhdGlvbiAgICAgICAgID0gIltHTk9TV0FQLUdPVkVSTkFOQ0UtMDE1XSBpbnZhbGlkIGNvbmZpZ3VyYXRpb24iCgllcnJJbnZhbGlkRXhlY3V0aW9uICAgICAgICAgICAgID0gIltHTk9TV0FQLUdPVkVSTkFOQ0UtMDE2XSBpbnZhbGlkIGV4ZWN1dGlvbjogaGFuZGxlciBub3QgZm91bmQiCgllcnJJbnZhbGlkU21vb3RoaW5nUGVyaW9kICAgICAgID0gIltHTk9TV0FQLUdPVkVSTkFOQ0UtMDE3XSBpbnZhbGlkIHNtb290aGluZyBwZXJpb2QiCgllcnJQcm9wb3NhbEluZGV4TmVlZHNDbGVhbnVwICAgID0gIltHTk9TV0FQLUdPVkVSTkFOQ0UtMDE4XSBhY3RpdmUgcHJvcG9zYWwgaW5kZXggcmVxdWlyZXMgcHJ1bmluZyIKKQoKLy8gbWFrZUVycm9yV2l0aERldGFpbHMgY3JlYXRlcyBhbiBlcnJvciB3aXRoIGFkZGl0aW9uYWwgY29udGV4dC4KZnVuYyBtYWtlRXJyb3JXaXRoRGV0YWlscyhtZXNzYWdlIHN0cmluZywgZGV0YWlsIHN0cmluZykgZXJyb3IgewoJcmV0dXJuIHVmbXQuRXJyb3JmKCIlcyB8fCAlcyIsIG1lc3NhZ2UsIGRldGFpbCkKfQoa94YBCgpnZXR0ZXIuZ25vEueGAXBhY2thZ2UgZ292ZXJuYW5jZQoKaW1wb3J0ICgKCSJlcnJvcnMiCgkidGltZSIKCglyb3RyZWUgImduby5sYW5kL3AvbnQvYnB0cmVlL3JvdHJlZS92MCIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9nb3Zlcm5hbmNlIgopCgovLyBHZXRMYXRlc3RDb25maWdWZXJzaW9uIHJldHVybnMgdGhlIGN1cnJlbnQgZ292ZXJuYW5jZSBjb25maWd1cmF0aW9uIHZlcnNpb24uCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogbGF0ZXN0IGNvbmZpZ3VyYXRpb24gdmVyc2lvbiBzdG9yZWQgYnkgZ292ZXJuYW5jZS4KZnVuYyAoZ3YgKmdvdmVybmFuY2VWMSkgR2V0TGF0ZXN0Q29uZmlnVmVyc2lvbigpIGludDY0IHsKCXJldHVybiBndi5nZXRDdXJyZW50Q29uZmlnVmVyc2lvbigpCn0KCi8vIEdldEN1cnJlbnRQcm9wb3NhbElEIHJldHVybnMgdGhlIGN1cnJlbnQgcHJvcG9zYWwgSUQgY291bnRlci4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBjdXJyZW50IHByb3Bvc2FsIElEIGNvdW50ZXIgdXNlZCBmb3IgbmV3bHkgY3JlYXRlZCBwcm9wb3NhbHMuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEdldEN1cnJlbnRQcm9wb3NhbElEKCkgaW50NjQgewoJcmV0dXJuIGd2LmdldEN1cnJlbnRQcm9wb3NhbElEKCkKfQoKLy8gR2V0TWF4U21vb3RoaW5nUGVyaW9kIHJldHVybnMgdGhlIG1heGltdW0gc21vb3RoaW5nIHBlcmlvZCBmb3IgZGVsZWdhdGlvbiBoaXN0b3J5IGNsZWFudXAuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogbWF4aW11bSBwZXJtaXR0ZWQgc21vb3RoaW5nIHBlcmlvZCwgaW4gc2Vjb25kcy4KZnVuYyAoZ3YgKmdvdmVybmFuY2VWMSkgR2V0TWF4U21vb3RoaW5nUGVyaW9kKCkgaW50NjQgewoJcmV0dXJuIG1heFNtb290aGluZ1BlcmlvZAp9CgovLyBHZXRMYXRlc3RDb25maWcgcmV0dXJucyB0aGUgbGF0ZXN0IGdvdmVybmFuY2UgY29uZmlndXJhdGlvbi4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGdvdmVybmFuY2UuQ29uZmlnOiBsYXRlc3Qgc3RvcmVkIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBjdXJyZW50IHZlcnNpb24uCi8vICAgLSBlcnJvcjogbmlsIG9uIHN1Y2Nlc3M7IGFuIGVycm9yIHdoZW4gdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbiBpcyBtaXNzaW5nLgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBHZXRMYXRlc3RDb25maWcoKSAoZ292ZXJuYW5jZS5Db25maWcsIGVycm9yKSB7CgljdXJyZW50VmVyc2lvbiA6PSBndi5nZXRDdXJyZW50Q29uZmlnVmVyc2lvbigpCgljb25maWcsIG9rIDo9IGd2LmdldENvbmZpZyhjdXJyZW50VmVyc2lvbikKCWlmICFvayB7CgkJcmV0dXJuIGdvdmVybmFuY2UuTmV3Q29uZmlnKDAsIDAsIDAsIDAsIDAsIDAsIDApLCBlcnJvcnMuTmV3KGVyckRhdGFOb3RGb3VuZCkKCX0KCglyZXR1cm4gY29uZmlnLCBuaWwKfQoKLy8gR2V0Q29uZmlnIHJldHVybnMgYSBzcGVjaWZpYyBnb3Zlcm5hbmNlIGNvbmZpZ3VyYXRpb24gYnkgdmVyc2lvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGNvbmZpZ1ZlcnNpb246IGNvbmZpZ3VyYXRpb24gdmVyc2lvbiB0byByZXRyaWV2ZS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGdvdmVybmFuY2UuQ29uZmlnOiBjb25maWd1cmF0aW9uIHN0b3JlZCB1bmRlciBjb25maWdWZXJzaW9uLgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzOyBhbiBlcnJvciB3aGVuIGNvbmZpZ1ZlcnNpb24gaXMgbm90IGZvdW5kLgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBHZXRDb25maWcoY29uZmlnVmVyc2lvbiBpbnQ2NCkgKGdvdmVybmFuY2UuQ29uZmlnLCBlcnJvcikgewoJY29uZmlnLCBvayA6PSBndi5nZXRDb25maWcoY29uZmlnVmVyc2lvbikKCWlmICFvayB7CgkJLy8gQ29uc3RydWN0IHRoZSB6ZXJvIENvbmZpZyB2aWEgdGhlIGRvbWFpbiBjb25zdHJ1Y3RvciBzbyBpdCBpcwoJCS8vIGFsbG9jYXRlZCBpbnNpZGUgdGhlIGdvdmVybmFuY2UgZG9tYWluIHJlYWxtIChyZWFsbSBhbGxvY2F0aW9uIGNoZWNrKS4KCQlyZXR1cm4gZ292ZXJuYW5jZS5OZXdDb25maWcoMCwgMCwgMCwgMCwgMCwgMCwgMCksIHVmbXQuRXJyb3JmKCJjb25maWcgdmVyc2lvbiAlZCBub3QgZm91bmQiLCBjb25maWdWZXJzaW9uKQoJfQoKCXJldHVybiBjb25maWcsIG5pbAp9CgovLyBHZXRQcm9wb3NhbHMgcmV0dXJucyBhIHJlYWQtb25seSB2aWV3IG9mIGV2ZXJ5IHByb3Bvc2FsLCBrZXllZCBieSB0aGUgZGVjaW1hbAovLyBzdHJpbmcgZm9ybSBvZiB0aGUgcHJvcG9zYWwgSUQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqcm90cmVlLlJlYWRPbmx5VHJlZTogcmVhZC1vbmx5IHByb3Bvc2FsIHRyZWUgd2l0aCBkZWNpbWFsIHByb3Bvc2FsIElEcyBhcyBrZXlzLgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBHZXRQcm9wb3NhbHMoKSAqcm90cmVlLlJlYWRPbmx5VHJlZSB7CglyZXR1cm4gcm90cmVlLldyYXAoZ3Yuc3RvcmUuR2V0UHJvcG9zYWxzKCksIGNsb25lUHJvcG9zYWxFbnRyeSkKfQoKLy8gRXhpc3RzUHJvcG9zYWwgY2hlY2tzIGlmIGEgcHJvcG9zYWwgZXhpc3RzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcHJvcG9zYWxJRDogcHJvcG9zYWwgaWRlbnRpZmllciB0byBsb29rIHVwLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSB3aGVuIHByb3Bvc2FsSUQgaXMgc3RvcmVkLCBvdGhlcndpc2UgZmFsc2UuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEV4aXN0c1Byb3Bvc2FsKHByb3Bvc2FsSUQgaW50NjQpIGJvb2wgewoJXywgZXhpc3RzIDo9IGd2LnN0b3JlLkdldFByb3Bvc2FsKHByb3Bvc2FsSUQpCglyZXR1cm4gZXhpc3RzCn0KCi8vIEdldFByb3Bvc2VyQnlQcm9wb3NhbElkIHJldHVybnMgdGhlIHByb3Bvc2VyIGFkZHJlc3Mgb2YgYSBwcm9wb3NhbC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHByb3Bvc2FsSWQ6IHByb3Bvc2FsIGlkZW50aWZpZXIgdG8gbG9vayB1cC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGFkZHJlc3M6IGFkZHJlc3MgdGhhdCBzdWJtaXR0ZWQgdGhlIHByb3Bvc2FsLgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzOyBhbiBlcnJvciB3aGVuIHRoZSBwcm9wb3NhbCBkb2VzIG5vdCBleGlzdC4KZnVuYyAoZ3YgKmdvdmVybmFuY2VWMSkgR2V0UHJvcG9zZXJCeVByb3Bvc2FsSWQocHJvcG9zYWxJZCBpbnQ2NCkgKGFkZHJlc3MsIGVycm9yKSB7Cglwcm9wb3NhbCwgZXhpc3RzIDo9IGd2LnN0b3JlLkdldFByb3Bvc2FsKHByb3Bvc2FsSWQpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gIiIsIHVmbXQuRXJyb3JmKCJwcm9wb3NhbCAlZCBub3QgZm91bmQiLCBwcm9wb3NhbElkKQoJfQoJcmV0dXJuIHByb3Bvc2FsLlByb3Bvc2VyKCksIG5pbAp9CgovLyBHZXRQcm9wb3NhbFR5cGVCeVByb3Bvc2FsSWQgcmV0dXJucyB0aGUgdHlwZSBvZiBhIHByb3Bvc2FsLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcHJvcG9zYWxJZDogcHJvcG9zYWwgaWRlbnRpZmllciB0byBsb29rIHVwLgovLwovLyBSZXR1cm5zOgovLyAgIC0gZ292ZXJuYW5jZS5Qcm9wb3NhbFR5cGU6IHR5cGUgcmVjb3JkZWQgZm9yIHRoZSBwcm9wb3NhbC4KLy8gICAtIGVycm9yOiBuaWwgb24gc3VjY2VzczsgYW4gZXJyb3Igd2hlbiB0aGUgcHJvcG9zYWwgZG9lcyBub3QgZXhpc3QuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEdldFByb3Bvc2FsVHlwZUJ5UHJvcG9zYWxJZChwcm9wb3NhbElkIGludDY0KSAoZ292ZXJuYW5jZS5Qcm9wb3NhbFR5cGUsIGVycm9yKSB7Cglwcm9wb3NhbCwgZXhpc3RzIDo9IGd2LnN0b3JlLkdldFByb3Bvc2FsKHByb3Bvc2FsSWQpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gZ292ZXJuYW5jZS5Qcm9wb3NhbFR5cGUoMCksIHVmbXQuRXJyb3JmKCJwcm9wb3NhbCAlZCBub3QgZm91bmQiLCBwcm9wb3NhbElkKQoJfQoJcmV0dXJuIHByb3Bvc2FsLlR5cGUoKSwgbmlsCn0KCi8vIEdldFByb3Bvc2FsQ3JlYXRlZEF0IHJldHVybnMgdGhlIGNyZWF0aW9uIHRpbWVzdGFtcCBvZiBhIHByb3Bvc2FsLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcHJvcG9zYWxJZDogcHJvcG9zYWwgaWRlbnRpZmllciB0byBsb29rIHVwLgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IFVuaXggdGltZXN0YW1wIGF0IHdoaWNoIHRoZSBwcm9wb3NhbCB3YXMgY3JlYXRlZC4KLy8gICAtIGVycm9yOiBuaWwgb24gc3VjY2VzczsgYW4gZXJyb3Igd2hlbiB0aGUgcHJvcG9zYWwgZG9lcyBub3QgZXhpc3QuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEdldFByb3Bvc2FsQ3JlYXRlZEF0KHByb3Bvc2FsSWQgaW50NjQpIChpbnQ2NCwgZXJyb3IpIHsKCXByb3Bvc2FsLCBleGlzdHMgOj0gZ3Yuc3RvcmUuR2V0UHJvcG9zYWwocHJvcG9zYWxJZCkKCWlmICFleGlzdHMgewoJCXJldHVybiAwLCB1Zm10LkVycm9yZigicHJvcG9zYWwgJWQgbm90IGZvdW5kIiwgcHJvcG9zYWxJZCkKCX0KCXJldHVybiBwcm9wb3NhbC5DcmVhdGVkQXQoKSwgbmlsCn0KCi8vIEdldFByb3Bvc2FsQ3JlYXRlZEhlaWdodCByZXR1cm5zIHRoZSBjcmVhdGlvbiBibG9jayBoZWlnaHQgb2YgYSBwcm9wb3NhbC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHByb3Bvc2FsSWQ6IHByb3Bvc2FsIGlkZW50aWZpZXIgdG8gbG9vayB1cC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBibG9jayBoZWlnaHQgYXQgd2hpY2ggdGhlIHByb3Bvc2FsIHdhcyBjcmVhdGVkLgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzOyBhbiBlcnJvciB3aGVuIHRoZSBwcm9wb3NhbCBkb2VzIG5vdCBleGlzdC4KZnVuYyAoZ3YgKmdvdmVybmFuY2VWMSkgR2V0UHJvcG9zYWxDcmVhdGVkSGVpZ2h0KHByb3Bvc2FsSWQgaW50NjQpIChpbnQ2NCwgZXJyb3IpIHsKCXByb3Bvc2FsLCBleGlzdHMgOj0gZ3Yuc3RvcmUuR2V0UHJvcG9zYWwocHJvcG9zYWxJZCkKCWlmICFleGlzdHMgewoJCXJldHVybiAwLCB1Zm10LkVycm9yZigicHJvcG9zYWwgJWQgbm90IGZvdW5kIiwgcHJvcG9zYWxJZCkKCX0KCXJldHVybiBwcm9wb3NhbC5DcmVhdGVkSGVpZ2h0KCksIG5pbAp9CgovLyBHZXRQcm9wb3NhbENvbW11bml0eVBvb2xTcGVuZEluZm8gcmV0dXJucyB0aGUgY29tbXVuaXR5IHBvb2wgc3BlbmQgaW5mbyBmb3IgYSBwcm9wb3NhbC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHByb3Bvc2FsSUQ6IHByb3Bvc2FsIGlkZW50aWZpZXIgdG8gaW5zcGVjdC4KLy8KLy8gUmV0dXJuczoKLy8gICAtICpnb3Zlcm5hbmNlLkNvbW11bml0eVBvb2xTcGVuZEluZm86IHNwZW5kIGRldGFpbHMgc3RvcmVkIGluIHRoZSBwcm9wb3NhbC4KLy8gICAtIGVycm9yOiBuaWwgb24gc3VjY2VzczsgYW4gZXJyb3Igd2hlbiB0aGUgcHJvcG9zYWwgaXMgbWlzc2luZyBvciBpcyBub3QgYQovLyAgICAgY29tbXVuaXR5IHBvb2wgc3BlbmQgcHJvcG9zYWwuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEdldFByb3Bvc2FsQ29tbXVuaXR5UG9vbFNwZW5kSW5mbyhwcm9wb3NhbElEIGludDY0KSAoKmdvdmVybmFuY2UuQ29tbXVuaXR5UG9vbFNwZW5kSW5mbywgZXJyb3IpIHsKCXByb3Bvc2FsLCBleGlzdHMgOj0gZ3Yuc3RvcmUuR2V0UHJvcG9zYWwocHJvcG9zYWxJRCkKCWlmICFleGlzdHMgewoJCXJldHVybiBuaWwsIHVmbXQuRXJyb3JmKCJwcm9wb3NhbCAlZCBub3QgZm91bmQiLCBwcm9wb3NhbElEKQoJfQoKCXByb3Bvc2FsRGF0YSA6PSBwcm9wb3NhbC5EYXRhKCkKCWlmIHByb3Bvc2FsRGF0YSA9PSBuaWwgfHwgcHJvcG9zYWxEYXRhLkNvbW11bml0eVBvb2xTcGVuZCgpID09IG5pbCB7CgkJcmV0dXJuIG5pbCwgdWZtdC5FcnJvcmYoInByb3Bvc2FsIGlzIG5vdCBhIGNvbW11bml0eSBwb29sIHNwZW5kIHByb3Bvc2FsIikKCX0KCglyZXR1cm4gcHJvcG9zYWxEYXRhLkNvbW11bml0eVBvb2xTcGVuZCgpLCBuaWwKfQoKLy8gR2V0UHJvcG9zYWxFeGVjdXRpb25JbmZvIHJldHVybnMgdGhlIGV4ZWN1dGlvbiBpbmZvIGZvciBhIHByb3Bvc2FsLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcHJvcG9zYWxJRDogcHJvcG9zYWwgaWRlbnRpZmllciB0byBpbnNwZWN0LgovLwovLyBSZXR1cm5zOgovLyAgIC0gKmdvdmVybmFuY2UuRXhlY3V0aW9uSW5mbzogZXhlY3V0aW9uIG1lc3NhZ2VzIGFuZCBjb3VudCBzdG9yZWQgaW4gdGhlIHByb3Bvc2FsLgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzOyBhbiBlcnJvciB3aGVuIHRoZSBwcm9wb3NhbCBpcyBtaXNzaW5nIG9yIGlzIG5vdCBhCi8vICAgICBwYXJhbWV0ZXIgY2hhbmdlIHByb3Bvc2FsLgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBHZXRQcm9wb3NhbEV4ZWN1dGlvbkluZm8ocHJvcG9zYWxJRCBpbnQ2NCkgKCpnb3Zlcm5hbmNlLkV4ZWN1dGlvbkluZm8sIGVycm9yKSB7Cglwcm9wb3NhbCwgZXhpc3RzIDo9IGd2LnN0b3JlLkdldFByb3Bvc2FsKHByb3Bvc2FsSUQpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gbmlsLCB1Zm10LkVycm9yZigicHJvcG9zYWwgJWQgbm90IGZvdW5kIiwgcHJvcG9zYWxJRCkKCX0KCglwcm9wb3NhbERhdGEgOj0gcHJvcG9zYWwuRGF0YSgpCglpZiBwcm9wb3NhbERhdGEgPT0gbmlsIHx8IHByb3Bvc2FsRGF0YS5FeGVjdXRpb24oKSA9PSBuaWwgewoJCXJldHVybiBuaWwsIHVmbXQuRXJyb3JmKCJwcm9wb3NhbCBpcyBub3QgYSBwYXJhbWV0ZXIgY2hhbmdlIHByb3Bvc2FsIikKCX0KCglyZXR1cm4gcHJvcG9zYWxEYXRhLkV4ZWN1dGlvbigpLCBuaWwKfQoKLy8gR2V0WWVhQnlQcm9wb3NhbElkIHJldHVybnMgdGhlIHllcyB2b3RlIHdlaWdodCBvZiBhIHByb3Bvc2FsLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcHJvcG9zYWxJZDogcHJvcG9zYWwgaWRlbnRpZmllciB0byBpbnNwZWN0LgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IHRvdGFsIHZvdGluZyB3ZWlnaHQgcmVjb3JkZWQgZm9yIHllcyB2b3Rlcy4KLy8gICAtIGVycm9yOiBuaWwgb24gc3VjY2VzczsgYW4gZXJyb3Igd2hlbiB0aGUgcHJvcG9zYWwgZG9lcyBub3QgZXhpc3QuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEdldFllYUJ5UHJvcG9zYWxJZChwcm9wb3NhbElkIGludDY0KSAoaW50NjQsIGVycm9yKSB7Cglwcm9wb3NhbCwgZXhpc3RzIDo9IGd2LnN0b3JlLkdldFByb3Bvc2FsKHByb3Bvc2FsSWQpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gMCwgdWZtdC5FcnJvcmYoInByb3Bvc2FsICVkIG5vdCBmb3VuZCIsIHByb3Bvc2FsSWQpCgl9CglyZXR1cm4gcHJvcG9zYWwuU3RhdHVzKCkuWWVzV2VpZ2h0KCksIG5pbAp9CgovLyBHZXROYXlCeVByb3Bvc2FsSWQgcmV0dXJucyB0aGUgbm8gdm90ZSB3ZWlnaHQgb2YgYSBwcm9wb3NhbC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHByb3Bvc2FsSWQ6IHByb3Bvc2FsIGlkZW50aWZpZXIgdG8gaW5zcGVjdC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiB0b3RhbCB2b3Rpbmcgd2VpZ2h0IHJlY29yZGVkIGZvciBubyB2b3Rlcy4KLy8gICAtIGVycm9yOiBuaWwgb24gc3VjY2VzczsgYW4gZXJyb3Igd2hlbiB0aGUgcHJvcG9zYWwgZG9lcyBub3QgZXhpc3QuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEdldE5heUJ5UHJvcG9zYWxJZChwcm9wb3NhbElkIGludDY0KSAoaW50NjQsIGVycm9yKSB7Cglwcm9wb3NhbCwgZXhpc3RzIDo9IGd2LnN0b3JlLkdldFByb3Bvc2FsKHByb3Bvc2FsSWQpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gMCwgdWZtdC5FcnJvcmYoInByb3Bvc2FsICVkIG5vdCBmb3VuZCIsIHByb3Bvc2FsSWQpCgl9CglyZXR1cm4gcHJvcG9zYWwuU3RhdHVzKCkuTm9XZWlnaHQoKSwgbmlsCn0KCi8vIEdldENvbmZpZ1ZlcnNpb25CeVByb3Bvc2FsSWQgcmV0dXJucyB0aGUgY29uZmlnIHZlcnNpb24gdXNlZCBieSBhIHByb3Bvc2FsLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcHJvcG9zYWxJZDogcHJvcG9zYWwgaWRlbnRpZmllciB0byBpbnNwZWN0LgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IGdvdmVybmFuY2UgY29uZmlndXJhdGlvbiB2ZXJzaW9uIGNhcHR1cmVkIGJ5IHRoZSBwcm9wb3NhbC4KLy8gICAtIGVycm9yOiBuaWwgb24gc3VjY2VzczsgYW4gZXJyb3Igd2hlbiB0aGUgcHJvcG9zYWwgZG9lcyBub3QgZXhpc3QuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEdldENvbmZpZ1ZlcnNpb25CeVByb3Bvc2FsSWQocHJvcG9zYWxJZCBpbnQ2NCkgKGludDY0LCBlcnJvcikgewoJcHJvcG9zYWwsIGV4aXN0cyA6PSBndi5zdG9yZS5HZXRQcm9wb3NhbChwcm9wb3NhbElkKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuIDAsIHVmbXQuRXJyb3JmKCJwcm9wb3NhbCAlZCBub3QgZm91bmQiLCBwcm9wb3NhbElkKQoJfQoJcmV0dXJuIHByb3Bvc2FsLkNvbmZpZ1ZlcnNpb24oKSwgbmlsCn0KCi8vIEdldFF1b3J1bUFtb3VudEJ5UHJvcG9zYWxJZCByZXR1cm5zIHRoZSBxdW9ydW0gcmVxdWlyZW1lbnQgZm9yIGEgcHJvcG9zYWwuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwcm9wb3NhbElkOiBwcm9wb3NhbCBpZGVudGlmaWVyIHRvIGluc3BlY3QuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogbWluaW11bSB2b3Rpbmcgd2VpZ2h0IHJlcXVpcmVkIGZvciB0aGUgcHJvcG9zYWwncyBxdW9ydW0uCi8vICAgLSBlcnJvcjogbmlsIG9uIHN1Y2Nlc3M7IGFuIGVycm9yIHdoZW4gdGhlIHByb3Bvc2FsIGRvZXMgbm90IGV4aXN0LgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBHZXRRdW9ydW1BbW91bnRCeVByb3Bvc2FsSWQocHJvcG9zYWxJZCBpbnQ2NCkgKGludDY0LCBlcnJvcikgewoJcHJvcG9zYWwsIGV4aXN0cyA6PSBndi5zdG9yZS5HZXRQcm9wb3NhbChwcm9wb3NhbElkKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuIDAsIHVmbXQuRXJyb3JmKCJwcm9wb3NhbCAlZCBub3QgZm91bmQiLCBwcm9wb3NhbElkKQoJfQoJcmV0dXJuIHByb3Bvc2FsLlN0YXR1cygpLlZvdGVTdGF0dXMoKS5RdW9ydW1BbW91bnQoKSwgbmlsCn0KCi8vIEdldFRpdGxlQnlQcm9wb3NhbElkIHJldHVybnMgdGhlIHRpdGxlIG9mIGEgcHJvcG9zYWwuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwcm9wb3NhbElkOiBwcm9wb3NhbCBpZGVudGlmaWVyIHRvIGluc3BlY3QuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBzdHJpbmc6IHByb3Bvc2FsIHRpdGxlLgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzOyBhbiBlcnJvciB3aGVuIHRoZSBwcm9wb3NhbCBkb2VzIG5vdCBleGlzdC4KZnVuYyAoZ3YgKmdvdmVybmFuY2VWMSkgR2V0VGl0bGVCeVByb3Bvc2FsSWQocHJvcG9zYWxJZCBpbnQ2NCkgKHN0cmluZywgZXJyb3IpIHsKCXByb3Bvc2FsLCBleGlzdHMgOj0gZ3Yuc3RvcmUuR2V0UHJvcG9zYWwocHJvcG9zYWxJZCkKCWlmICFleGlzdHMgewoJCXJldHVybiAiIiwgdWZtdC5FcnJvcmYoInByb3Bvc2FsICVkIG5vdCBmb3VuZCIsIHByb3Bvc2FsSWQpCgl9CglyZXR1cm4gcHJvcG9zYWwuTWV0YWRhdGEoKS5UaXRsZSgpLCBuaWwKfQoKLy8gR2V0RGVzY3JpcHRpb25CeVByb3Bvc2FsSWQgcmV0dXJucyB0aGUgZGVzY3JpcHRpb24gb2YgYSBwcm9wb3NhbC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHByb3Bvc2FsSWQ6IHByb3Bvc2FsIGlkZW50aWZpZXIgdG8gaW5zcGVjdC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHN0cmluZzogcHJvcG9zYWwgZGVzY3JpcHRpb24uCi8vICAgLSBlcnJvcjogbmlsIG9uIHN1Y2Nlc3M7IGFuIGVycm9yIHdoZW4gdGhlIHByb3Bvc2FsIGRvZXMgbm90IGV4aXN0LgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBHZXREZXNjcmlwdGlvbkJ5UHJvcG9zYWxJZChwcm9wb3NhbElkIGludDY0KSAoc3RyaW5nLCBlcnJvcikgewoJcHJvcG9zYWwsIGV4aXN0cyA6PSBndi5zdG9yZS5HZXRQcm9wb3NhbChwcm9wb3NhbElkKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuICIiLCB1Zm10LkVycm9yZigicHJvcG9zYWwgJWQgbm90IGZvdW5kIiwgcHJvcG9zYWxJZCkKCX0KCXJldHVybiBwcm9wb3NhbC5NZXRhZGF0YSgpLkRlc2NyaXB0aW9uKCksIG5pbAp9CgovLyBHZXRQcm9wb3NhbFN0YXR1c0J5UHJvcG9zYWxJZCByZXR1cm5zIHRoZSBjdXJyZW50IHN0YXR1cyBvZiBhIHByb3Bvc2FsLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcHJvcG9zYWxJZDogcHJvcG9zYWwgaWRlbnRpZmllciB0byBpbnNwZWN0LgovLwovLyBSZXR1cm5zOgovLyAgIC0gc3RyaW5nOiBzdGF0dXMgY29tcHV0ZWQgZnJvbSB0aGUgcHJvcG9zYWwgYW5kIHRoZSBjdXJyZW50IFVuaXggdGltZS4KLy8gICAtIGVycm9yOiBuaWwgb24gc3VjY2VzczsgYW4gZXJyb3Igd2hlbiB0aGUgcHJvcG9zYWwgZG9lcyBub3QgZXhpc3QuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEdldFByb3Bvc2FsU3RhdHVzQnlQcm9wb3NhbElkKHByb3Bvc2FsSWQgaW50NjQpIChzdHJpbmcsIGVycm9yKSB7Cglwcm9wb3NhbCwgZXhpc3RzIDo9IGd2LnN0b3JlLkdldFByb3Bvc2FsKHByb3Bvc2FsSWQpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gIiIsIHVmbXQuRXJyb3JmKCJwcm9wb3NhbCAlZCBub3QgZm91bmQiLCBwcm9wb3NhbElkKQoJfQoJcHJvcG9zYWxSZXNvbHZlciA6PSBOZXdQcm9wb3NhbFJlc29sdmVyKHByb3Bvc2FsKQoJcmV0dXJuIHByb3Bvc2FsUmVzb2x2ZXIuU3RhdHVzKHRpbWUuTm93KCkuVW5peCgpKSwgbmlsCn0KCi8vIEdldFZvdGVTdGF0dXMgcmV0dXJucyB0aGUgdm90ZSBzdGF0dXMgb2YgYSBwcm9wb3NhbC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHByb3Bvc2FsSWQ6IHByb3Bvc2FsIGlkZW50aWZpZXIgdG8gaW5zcGVjdC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHF1b3J1bTogbWluaW11bSB2b3RlIHdlaWdodCByZXF1aXJlZCBmb3IgcHJvcG9zYWwgdG8gcGFzcy4KLy8gICAtIG1heFZvdGluZ1dlaWdodDogbWF4aW11bSBwb3NzaWJsZSB2b3Rpbmcgd2VpZ2h0IHJlY29yZGVkIGZvciB0aGUgcHJvcG9zYWwuCi8vICAgLSB5ZXNXZWlnaHQ6IHRvdGFsIHdlaWdodCBvZiAieWVzIiB2b3Rlcy4KLy8gICAtIG5vV2VpZ2h0OiB0b3RhbCB3ZWlnaHQgb2YgIm5vIiB2b3Rlcy4KLy8gICAtIGVycjogbmlsIG9uIHN1Y2Nlc3M7IGFuIGVycm9yIHdoZW4gdGhlIHByb3Bvc2FsIGRvZXMgbm90IGV4aXN0LgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBHZXRWb3RlU3RhdHVzKHByb3Bvc2FsSWQgaW50NjQpIChxdW9ydW0sIG1heFZvdGluZ1dlaWdodCwgeWVzV2VpZ2h0LCBub1dlaWdodCBpbnQ2NCwgZXJyIGVycm9yKSB7Cglwcm9wb3NhbCwgZXhpc3RzIDo9IGd2LnN0b3JlLkdldFByb3Bvc2FsKHByb3Bvc2FsSWQpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gMCwgMCwgMCwgMCwgdWZtdC5FcnJvcmYoInByb3Bvc2FsICVkIG5vdCBmb3VuZCIsIHByb3Bvc2FsSWQpCgl9Cgl2b3RpbmcgOj0gcHJvcG9zYWwuU3RhdHVzKCkuVm90ZVN0YXR1cygpCglyZXR1cm4gdm90aW5nLlF1b3J1bUFtb3VudCgpLCB2b3RpbmcuTWF4Vm90aW5nV2VpZ2h0KCksIHZvdGluZy5ZZXNXZWlnaHQoKSwgdm90aW5nLk5vV2VpZ2h0KCksIG5pbAp9CgovLyBHZXRWb3RpbmdJbmZvcyByZXR1cm5zIGEgcmVhZC1vbmx5IHZpZXcgb2YgYSBwcm9wb3NhbCdzIHZhbHVlLWJhY2tlZCB2b3RpbmcKLy8gaW5mb3MsIGtleWVkIGJ5IHZvdGVyIGFkZHJlc3MuIEV4aXN0aW5nIHByb3Bvc2FscyBoYXZlIGFuIGVtcHR5IHZpZXcgYmVmb3JlCi8vIHRoZSBmaXJzdCB2b3RlOyBuaWwgaXMgcmV0dXJuZWQgb25seSB3aGVuIHRoZSBzdG9yZWQgdm90aW5nLWluZm8gdHJlZSBpcyBhYnNlbnQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwcm9wb3NhbElEOiBwcm9wb3NhbCBpZGVudGlmaWVyIHdob3NlIHZvdGluZyBpbmZvcm1hdGlvbiBpcyByZXF1ZXN0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqcm90cmVlLlJlYWRPbmx5VHJlZTogcmVhZC1vbmx5IHZvdGluZy1pbmZvIHRyZWUga2V5ZWQgYnkgdm90ZXIgYWRkcmVzcywgb3IKLy8gICAgIG5pbCB3aGVuIG5vIHRyZWUgaXMgc3RvcmVkIGZvciBwcm9wb3NhbElELgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBHZXRWb3RpbmdJbmZvcyhwcm9wb3NhbElEIGludDY0KSAqcm90cmVlLlJlYWRPbmx5VHJlZSB7Cgl2b3RpbmdJbmZvcywgZXhpc3RzIDo9IGd2LmdldFByb3Bvc2FsVXNlclZvdGluZ0luZm9zKHByb3Bvc2FsSUQpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gbmlsCgl9CglyZXR1cm4gcm90cmVlLldyYXAodm90aW5nSW5mb3MsIG5pbCkKfQoKLy8gRXhpc3RzVm90aW5nSW5mbyBjaGVja3MgaWYgYSB2b3RpbmcgaW5mbyBleGlzdHMgZm9yIGEgdXNlciBvbiBhIHByb3Bvc2FsLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcHJvcG9zYWxJRDogcHJvcG9zYWwgaWRlbnRpZmllciB0byBpbnNwZWN0LgovLyAgIC0gYWRkcjogdm90ZXIgYWRkcmVzcyB0byBsb29rIHVwIHdpdGhpbiBwcm9wb3NhbElELgovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSB3aGVuIHZvdGluZyBpbmZvcm1hdGlvbiBleGlzdHMgZm9yIHRoZSBwcm9wb3NhbCBhbmQgYWRkcmVzcy4KZnVuYyAoZ3YgKmdvdmVybmFuY2VWMSkgRXhpc3RzVm90aW5nSW5mbyhwcm9wb3NhbElEIGludDY0LCBhZGRyIGFkZHJlc3MpIGJvb2wgewoJXywgZXhpc3RzIDo9IGd2LmdldFByb3Bvc2FsVXNlclZvdGluZ0luZm8ocHJvcG9zYWxJRCwgYWRkcikKCXJldHVybiBleGlzdHMKfQoKLy8gR2V0Vm90ZVdlaWdodCByZXR1cm5zIHRoZSB2b3Rpbmcgd2VpZ2h0IG9mIGFuIGFkZHJlc3MgZm9yIGEgcHJvcG9zYWwuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwcm9wb3NhbElEOiBwcm9wb3NhbCBpZGVudGlmaWVyIHRvIGluc3BlY3QuCi8vICAgLSBhZGRyOiB2b3RlciBhZGRyZXNzIHdob3NlIHJlY29yZGVkIHZvdGUgd2VpZ2h0IGlzIHJlcXVlc3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiB3ZWlnaHQgcmVjb3JkZWQgZm9yIGFkZHIncyB2b3RlLgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzOyBhbiBlcnJvciB3aGVuIG5vIHZvdGluZyBpbmZvcm1hdGlvbiBleGlzdHMgZm9yIHRoZQovLyAgICAgcHJvcG9zYWwgYW5kIGFkZHJlc3MuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEdldFZvdGVXZWlnaHQocHJvcG9zYWxJRCBpbnQ2NCwgYWRkciBhZGRyZXNzKSAoaW50NjQsIGVycm9yKSB7Cgl2b3RpbmdJbmZvLCBleGlzdHMgOj0gZ3YuZ2V0UHJvcG9zYWxVc2VyVm90aW5nSW5mbyhwcm9wb3NhbElELCBhZGRyKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuIDAsIHVmbXQuRXJyb3JmKCJ2b3RpbmcgaW5mbyBub3QgZm91bmQgZm9yIHByb3Bvc2FsICVkIGFuZCBhZGRyZXNzICVzIiwgcHJvcG9zYWxJRCwgYWRkci5TdHJpbmcoKSkKCX0KCXJldHVybiB2b3RpbmdJbmZvLlZvdGVkV2VpZ2h0KCksIG5pbAp9CgovLyBHZXRWb3RlZEhlaWdodCByZXR1cm5zIHRoZSBibG9jayBoZWlnaHQgd2hlbiBhbiBhZGRyZXNzIHZvdGVkIG9uIGEgcHJvcG9zYWwuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwcm9wb3NhbElEOiBwcm9wb3NhbCBpZGVudGlmaWVyIHRvIGluc3BlY3QuCi8vICAgLSBhZGRyOiB2b3RlciBhZGRyZXNzIHdob3NlIHZvdGUgaGVpZ2h0IGlzIHJlcXVlc3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBibG9jayBoZWlnaHQgcmVjb3JkZWQgZm9yIGFkZHIncyB2b3RlLgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzOyBhbiBlcnJvciB3aGVuIG5vIHZvdGluZyBpbmZvcm1hdGlvbiBleGlzdHMgZm9yIHRoZQovLyAgICAgcHJvcG9zYWwgYW5kIGFkZHJlc3MuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEdldFZvdGVkSGVpZ2h0KHByb3Bvc2FsSUQgaW50NjQsIGFkZHIgYWRkcmVzcykgKGludDY0LCBlcnJvcikgewoJdm90aW5nSW5mbywgZXhpc3RzIDo9IGd2LmdldFByb3Bvc2FsVXNlclZvdGluZ0luZm8ocHJvcG9zYWxJRCwgYWRkcikKCWlmICFleGlzdHMgewoJCXJldHVybiAwLCB1Zm10LkVycm9yZigidm90aW5nIGluZm8gbm90IGZvdW5kIGZvciBwcm9wb3NhbCAlZCBhbmQgYWRkcmVzcyAlcyIsIHByb3Bvc2FsSUQsIGFkZHIuU3RyaW5nKCkpCgl9CglyZXR1cm4gdm90aW5nSW5mby5Wb3RlZEhlaWdodCgpLCBuaWwKfQoKLy8gR2V0Vm90ZWRBdCByZXR1cm5zIHRoZSB0aW1lc3RhbXAgd2hlbiBhbiBhZGRyZXNzIHZvdGVkIG9uIGEgcHJvcG9zYWwuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwcm9wb3NhbElEOiBwcm9wb3NhbCBpZGVudGlmaWVyIHRvIGluc3BlY3QuCi8vICAgLSBhZGRyOiB2b3RlciBhZGRyZXNzIHdob3NlIHZvdGUgdGltZXN0YW1wIGlzIHJlcXVlc3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBVbml4IHRpbWVzdGFtcCByZWNvcmRlZCBmb3IgYWRkcidzIHZvdGUuCi8vICAgLSBlcnJvcjogbmlsIG9uIHN1Y2Nlc3M7IGFuIGVycm9yIHdoZW4gbm8gdm90aW5nIGluZm9ybWF0aW9uIGV4aXN0cyBmb3IgdGhlCi8vICAgICBwcm9wb3NhbCBhbmQgYWRkcmVzcy4KZnVuYyAoZ3YgKmdvdmVybmFuY2VWMSkgR2V0Vm90ZWRBdChwcm9wb3NhbElEIGludDY0LCBhZGRyIGFkZHJlc3MpIChpbnQ2NCwgZXJyb3IpIHsKCXZvdGluZ0luZm8sIGV4aXN0cyA6PSBndi5nZXRQcm9wb3NhbFVzZXJWb3RpbmdJbmZvKHByb3Bvc2FsSUQsIGFkZHIpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gMCwgdWZtdC5FcnJvcmYoInZvdGluZyBpbmZvIG5vdCBmb3VuZCBmb3IgcHJvcG9zYWwgJWQgYW5kIGFkZHJlc3MgJXMiLCBwcm9wb3NhbElELCBhZGRyLlN0cmluZygpKQoJfQoJcmV0dXJuIHZvdGluZ0luZm8uVm90ZWRBdCgpLCBuaWwKfQoKLy8gR2V0VXNlclByb3Bvc2FscyByZXR1cm5zIGEgcmVhZC1vbmx5IHZpZXcgb2YgdGhlIHByb3Bvc2FscyBjcmVhdGVkIHBlciB1c2VyLAovLyBrZXllZCBieSBjcmVhdG9yIGFkZHJlc3Mgd2l0aCB0aGUgY3JlYXRvcidzIHByb3Bvc2FsIElEcyBhcyB0aGUgdmFsdWUuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqcm90cmVlLlJlYWRPbmx5VHJlZTogcmVhZC1vbmx5IHVzZXItcHJvcG9zYWwgdHJlZSBrZXllZCBieSBjcmVhdG9yIGFkZHJlc3MuCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIEdldFVzZXJQcm9wb3NhbHMoKSAqcm90cmVlLlJlYWRPbmx5VHJlZSB7CglyZXR1cm4gcm90cmVlLldyYXAoZ3Yuc3RvcmUuR2V0VXNlclByb3Bvc2FscygpLCBjbG9uZVByb3Bvc2FsSURzRW50cnkpCn0KCi8vIEdldE9sZGVzdEFjdGl2ZVByb3Bvc2FsU25hcHNob3RUaW1lIGV4YW1pbmVzIG9ubHkgdGhlIGZpcnN0IHRpbWVzdGFtcC1vcmRlcmVkIGluZGV4IGVudHJ5LgovLyBJZiBpdCBpcyBpbmFjdGl2ZSwgdGhlIGVycm9yIGlkZW50aWZpZXMgdGhlIHByb3Bvc2FsIHJlcXVpcmluZyBtYWludGVuYW5jZQovLyBjbGVhbnVwLiBBbiBlcnJvciBtdXN0IG5ldmVyIGJlIHRyZWF0ZWQgYXMgYW4gZW1wdHkgaW5kZXggd2hlbiBkZWxldGluZwovLyBkZWxlZ2F0aW9uIGhpc3RvcnkuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogc25hcHNob3QgdGltZXN0YW1wIG9mIHRoZSBvbGRlc3QgYWN0aXZlIHByb3Bvc2FsLCBvciB6ZXJvIHdoZW4gdGhlCi8vICAgICBpbmRleCBpcyBlbXB0eSBvciBhbiBlcnJvciBvY2N1cnMuCi8vICAgLSBib29sOiB0cnVlIHdoZW4gYW4gYWN0aXZlIHByb3Bvc2FsIHdhcyBmb3VuZCBhdCB0aGUgb2xkZXN0IGluZGV4IGVudHJ5LgovLyAgIC0gZXJyb3I6IG5pbCBmb3IgYW4gZW1wdHkgaW5kZXggb3IgYWN0aXZlIGVudHJ5OyBhbiBlcnJvciB3aGVuIHRoZSBlbnRyeSdzCi8vICAgICBwcm9wb3NhbCBpcyBtaXNzaW5nIG9yIGluYWN0aXZlIGFuZCB0aGUgaW5kZXggbmVlZHMgY2xlYW51cC4KZnVuYyAoZ3YgKmdvdmVybmFuY2VWMSkgR2V0T2xkZXN0QWN0aXZlUHJvcG9zYWxTbmFwc2hvdFRpbWUoKSAoaW50NjQsIGJvb2wsIGVycm9yKSB7CglpbmRleCA6PSBndi5zdG9yZS5HZXRBY3RpdmVQcm9wb3NhbHNCeVNuYXBzaG90KCkKCWlmIGluZGV4LlNpemUoKSA9PSAwIHsKCQlyZXR1cm4gMCwgZmFsc2UsIG5pbAoJfQoKCV8sIHZhbHVlIDo9IGluZGV4LkdldEJ5SW5kZXgoMCkKCXByb3Bvc2FsSUQsIG9rIDo9IHZhbHVlLihpbnQ2NCkKCWlmICFvayB7CgkJcGFuaWModWZtdC5TcHJpbnRmKCJmYWlsZWQgdG8gY2FzdCBhY3RpdmUgcHJvcG9zYWwgSUQgdG8gaW50NjQ6ICVUIiwgdmFsdWUpKQoJfQoKCXByb3Bvc2FsLCBleGlzdHMgOj0gZ3YuZ2V0UHJvcG9zYWwocHJvcG9zYWxJRCkKCWlmICFleGlzdHMgewoJCXJldHVybiAwLCBmYWxzZSwgbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyclByb3Bvc2FsTm90Rm91bmQsIHVmbXQuU3ByaW50ZigicHJvcG9zYWxJRDogJWQiLCBwcm9wb3NhbElEKSwKCQkpCgl9CglpZiAhTmV3UHJvcG9zYWxSZXNvbHZlcihwcm9wb3NhbCkuSXNBY3RpdmUodGltZS5Ob3coKS5Vbml4KCkpIHsKCQlyZXR1cm4gMCwgZmFsc2UsIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJQcm9wb3NhbEluZGV4TmVlZHNDbGVhbnVwLCB1Zm10LlNwcmludGYoInByb3Bvc2FsSUQ6ICVkIiwgcHJvcG9zYWxJRCksCgkJKQoJfQoKCXJldHVybiBwcm9wb3NhbC5TbmFwc2hvdFRpbWUoKSwgdHJ1ZSwgbmlsCn0KCi8vIEdldEN1cnJlbnRWb3RpbmdXZWlnaHRTbmFwc2hvdCByZXR1cm5zIHRoZSBjdXJyZW50IHRvdGFsIHZvdGluZyB3ZWlnaHQgYW5kCi8vIHRpbWVzdGFtcCBhbmNob3IgY29tcHV0ZWQgd2l0aCB0aGUgY29uZmlndXJlZCBzbW9vdGhpbmcgZHVyYXRpb24uCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogdG90YWwgdm90aW5nIHdlaWdodCBhdmVyYWdlZCBvdmVyIHRoZSBjb25maWd1cmVkIHNtb290aGluZyB3aW5kb3cuCi8vICAgLSBpbnQ2NDogVW5peCB0aW1lc3RhbXAgdXNlZCBhcyB0aGUgc25hcHNob3QgaGlzdG9yeSBhbmNob3IuCi8vICAgLSBlcnJvcjogbmlsIG9uIHN1Y2Nlc3M7IGFuIGVycm9yIHdoZW4gdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbiBvciBzbmFwc2hvdAovLyAgICAgZGF0YSBjYW5ub3QgYmUgcmV0cmlldmVkLgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBHZXRDdXJyZW50Vm90aW5nV2VpZ2h0U25hcHNob3QoKSAoaW50NjQsIGludDY0LCBlcnJvcikgewoJY3VycmVudCA6PSB0aW1lLk5vdygpLlVuaXgoKQoJY29uZmlnLCBvayA6PSBndi5nZXRDdXJyZW50Q29uZmlnKCkKCWlmICFvayB7CgkJcmV0dXJuIDAsIDAsIHVmbXQuRXJyb3JmKCJjdXJyZW50IGNvbmZpZyBub3QgZm91bmQiKQoJfQoKCXJldHVybiBndi5nZXRWb3RpbmdXZWlnaHRTbmFwc2hvdChjdXJyZW50LCBjb25maWcuVm90aW5nV2VpZ2h0U21vb3RoaW5nRHVyYXRpb24pCn0KGpwJChBnZXR0ZXJfdXRpbHMuZ25vEocJcGFja2FnZSBnb3Zlcm5hbmNlCgppbXBvcnQgKAoJImduby5sYW5kL3IvZ25vc3dhcC9nb3YvZ292ZXJuYW5jZSIKKQoKLy8gVGhlIGZ1bmN0aW9ucyBiZWxvdyBhcmUgbWFrZUVudHJ5U2FmZUZuIHRyYW5zZm9ybWF0aW9ucyBoYW5kZWQgdG8KLy8gcm90cmVlLldyYXAuIFRoZXkgcnVuIG9uIGV2ZXJ5IHJlYWQgdGhyb3VnaCBhIHJlYWQtb25seSB2aWV3LCBzbyBlYWNoIG9uZQovLyByZXR1cm5zIGEgdmFsdWUgdGhlIGNhbGxlciBtYXkgaG9sZCB3aXRob3V0IHJlYWNoaW5nIHJlYWxtLW93bmVkIHN0YXRlLgoKLy8gY2xvbmVQcm9wb3NhbEVudHJ5IGlzIHRoZSB0cmFuc2Zvcm1hdGlvbiBmb3IgdGhlIHByb3Bvc2FsIHRyZWUuIFByb3Bvc2FsIGlzCi8vIG11dGFibGUgYW5kIGl0cyBzZXR0ZXJzIGFyZSBkZWNsYXJlZCBpbiAvci9nbm9zd2FwL2dvdi9nb3Zlcm5hbmNlLCBzbyBhbgovLyBleHRlcm5hbCBob2xkZXIgb2YgdGhlIHN0b3JlZCBwb2ludGVyIGNvdWxkIHdyaXRlIHJlYWxtIHN0YXRlIHRocm91Z2ggaXQuCi8vCi8vIFByb3Bvc2FsLkNsb25lIGxlYXZlcyB0aGUgdHlwZS1zcGVjaWZpYyBkYXRhIG5pbDsgc2VlIGl0IGZvciB3aGljaCBsb29rdXBzCi8vIHJlYWQgaXQgaW5zdGVhZC4KZnVuYyBjbG9uZVByb3Bvc2FsRW50cnkodmFsdWUgYW55KSBhbnkgewoJcHJvcG9zYWwsIG9rIDo9IHZhbHVlLigqZ292ZXJuYW5jZS5Qcm9wb3NhbCkKCWlmICFvayB7CgkJcmV0dXJuIG5pbAoJfQoKCXJldHVybiBwcm9wb3NhbC5DbG9uZSgpCn0KCi8vIGNsb25lUHJvcG9zYWxJRHNFbnRyeSBpcyB0aGUgdHJhbnNmb3JtYXRpb24gZm9yIHRoZSB1c2VyIHByb3Bvc2FsIHRyZWUuIFRoZQovLyBzdG9yZWQgdmFsdWUgaXMgYSBzbGljZSwgc28gaGFuZCBvdXQgYSBjb3B5IHJhdGhlciB0aGFuIGxldHRpbmcgYSByZWFkZXIKLy8gd3JpdGUgdGhyb3VnaCB0aGUgc2hhcmVkIGJhY2tpbmcgYXJyYXkuCmZ1bmMgY2xvbmVQcm9wb3NhbElEc0VudHJ5KHZhbHVlIGFueSkgYW55IHsKCXByb3Bvc2FsSURzLCBvayA6PSB2YWx1ZS4oW11pbnQ2NCkKCWlmICFvayB7CgkJcmV0dXJuIG5pbAoJfQoKCWNsb25lZCA6PSBtYWtlKFtdaW50NjQsIGxlbihwcm9wb3NhbElEcykpCgljb3B5KGNsb25lZCwgcHJvcG9zYWxJRHMpCgoJcmV0dXJuIGNsb25lZAp9ChpKCgtnbm9tb2QudG9tbBI7bW9kdWxlID0gImduby5sYW5kL3IvZ25vc3dhcC9nb3YvZ292ZXJuYW5jZS92MSIKZ25vID0gIjAuOSIa+U4KFmdvdmVybmFuY2VfZXhlY3V0ZS5nbm8S3k5wYWNrYWdlIGdvdmVybmFuY2UKCmltcG9ydCAoCgkiY2hhaW4iCgkiY2hhaW4vcnVudGltZSIKCSJlcnJvcnMiCgkidGltZSIKCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKCgkiZ25vLmxhbmQvcC9nbm9zd2FwL3V0aWxzL3YxIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvY29tbW9uIgoJImduby5sYW5kL3IvZ25vc3dhcC9lbWlzc2lvbiIKCSJnbm8ubGFuZC9yL2dub3N3YXAvaGFsdC92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9nb3Zlcm5hbmNlIgopCgovLyBFeGVjdXRlIGV4ZWN1dGVzIGFuIGFwcHJvdmVkIHByb3Bvc2FsLgovLwovLyBQcm9jZXNzZXMgYW5kIGltcGxlbWVudHMgZ292ZXJuYW5jZSBkZWNpc2lvbnMgYWZ0ZXIgc3VjY2Vzc2Z1bCB2b3RpbmcuCi8vIEVuZm9yY2VzIHRoZSBjb25maWd1cmVkIGV4ZWN1dGlvbiBkZWxheSBhbmQgZXhlY3V0aW9uIHdpbmRvdy4KLy8gQW55b25lIGNhbiB0cmlnZ2VyIGV4ZWN1dGlvbiB0byBlbnN1cmUgZGVjZW50cmFsaXphdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IEludGVybmFsIGNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBQcm9wYWdhdGVkIHJlYWxtIGNvbnRleHQ7IG11c3QgYmUgY3VycmVudCBmb3IgYXV0aG9yaXplZCBnb3Zlcm5hbmNlIHN0YXRlIHVwZGF0ZXMgYW5kIGlzIGNyb3NzZWQgaW50byBleGVjdXRpb24tZGVwZW5kZW50IGNhbGxzLgovLyAgIC0gcHJvcG9zYWxJRDogSUQgb2YgdGhlIHByb3Bvc2FsIHRvIGV4ZWN1dGUKLy8KLy8gUmVxdWlyZW1lbnRzOgovLyAgIC0gUHJvcG9zYWwgbXVzdCBoYXZlIHBhc3NlZCAocXVvcnVtIGFuZCBzdHJpY3QgeWVzLW92ZXItbm8gbWFqb3JpdHkpCi8vICAgLSBRdW9ydW0gbXVzdCBiZSByZWFjaGVkIHVzaW5nIHRoZSBwcm9wb3NhbCdzIHN0b3JlZCBhbW91bnQsIGRlcml2ZWQgZnJvbQovLyAgICAgdGhlIHRvdGFsIHhHTlMgc3VwcGx5IGFuZCBjb25maWd1cmVkIHF1b3J1bSBwZXJjZW50YWdlIGF0IGNyZWF0aW9uCi8vICAgLSBFeGVjdXRpb24gZGVsYXkgbXVzdCBoYXZlIGVsYXBzZWQgKDEgZGF5IGJ5IGRlZmF1bHQpCi8vICAgLSBNdXN0IGJlIHdpdGhpbiB0aGUgZXhlY3V0aW9uIHdpbmRvdyAoMzAgZGF5cyBieSBkZWZhdWx0KQovLyAgIC0gUHJvcG9zYWwgbm90IGFscmVhZHkgZXhlY3V0ZWQgb3IgY2FuY2VsbGVkCi8vCi8vIEVmZmVjdHM6Ci8vICAgLSBFeGVjdXRlcyBwcm9wb3NhbCBhY3Rpb25zIChwYXJhbWV0ZXIgY2hhbmdlcywgdHJlYXN1cnkgdHJhbnNmZXJzKQovLyAgIC0gTWFya3MgcHJvcG9zYWwgYXMgZXhlY3V0ZWQKLy8gICAtIEVtaXRzIGV4ZWN1dGlvbiBldmVudAovLwovLyBSZXR1cm5zOgovLyAgIC0gcHJvcG9zYWxJRDogSUQgb2YgdGhlIGV4ZWN1dGVkIHByb3Bvc2FsCi8vCi8vIENhbGxhYmxlIGJ5IGFueW9uZSBvbmNlIHRoZSBwcm9wb3NhbCBpcyBleGVjdXRhYmxlLgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBFeGVjdXRlKF8gaW50LCBybG0gcmVhbG0sIHByb3Bvc2FsSUQgaW50NjQpIGludDY0IHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCS8vIENoZWNrIGlmIGV4ZWN1dGlvbiBpcyBhbGxvd2VkIChzeXN0ZW0gbm90IGhhbHRlZCBmb3IgZXhlY3V0aW9uKS4KCS8vIEhhbHQgcmVjb3ZlcnkgcHJvcG9zYWxzIHJlbWFpbiBleGVjdXRhYmxlIHdoaWxlIGdvdmVybmFuY2UgaXMgaGFsdGVkLgoJYXNzZXJ0SXNOb3RIYWx0ZWRHb3Zlcm5hbmNlRm9yUHJvcG9zYWwoZ3YsIHByb3Bvc2FsSUQpCgoJLy8gR2V0IGNhbGxlciBpbmZvcm1hdGlvbiBhbmQgY3VycmVudCBibG9ja2NoYWluIHN0YXRlCglwcmV2IDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldi5BZGRyZXNzKCkKCWN1cnJlbnRIZWlnaHQgOj0gcnVudGltZS5DaGFpbkhlaWdodCgpCgljdXJyZW50QXQgOj0gdGltZS5Ob3coKS5Vbml4KCkKCgkvLyBNaW50IGFuZCBkaXN0cmlidXRlIEdOUyB0b2tlbnMgYXMgcGFydCBvZiB0aGUgZXhlY3V0aW9uIHByb2Nlc3MKCWVtaXNzaW9uLk1pbnRBbmREaXN0cmlidXRlR25zKGNyb3NzKHJsbSkpCgoJLy8gQXR0ZW1wdCB0byBleGVjdXRlIHRoZSBwcm9wb3NhbCB3aXRoIGN1cnJlbnQgY29udGV4dAoJcHJvcG9zYWwsIGVyciA6PSBndi5leGVjdXRlUHJvcG9zYWwoCgkJMCwgcmxtLAoJCXByb3Bvc2FsSUQsCgkJY3VycmVudEF0LAoJCWN1cnJlbnRIZWlnaHQsCgkJY2FsbGVyLAoJKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoJaWYgZXJyIDo9IGd2LnJlbW92ZUFjdGl2ZVByb3Bvc2FsKDAsIHJsbSwgcHJvcG9zYWwpOyBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJLy8gRW1pdCBleGVjdXRpb24gZXZlbnQgZm9yIHRyYWNraW5nIGFuZCBhdWRpdGluZwoJY2hhaW4uRW1pdCgKCQkiRXhlY3V0ZSIsCgkJInByZXZBZGRyIiwgcHJldi5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXYuUGtnUGF0aCgpLAoJCSJwcm9wb3NhbElkIiwgdXRpbHMuRm9ybWF0SW50KHByb3Bvc2FsSUQpLAoJKQoKCXJldHVybiBwcm9wb3NhbC5JRCgpCn0KCi8vIGV4ZWN1dGVQcm9wb3NhbCBoYW5kbGVzIGNvcmUgbG9naWMgb2YgcHJvcG9zYWwgZXhlY3V0aW9uLgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBleGVjdXRlUHJvcG9zYWwoCglfIGludCwgcmxtIHJlYWxtLAoJcHJvcG9zYWxJRCBpbnQ2NCwKCWV4ZWN1dGVkQXQgaW50NjQsCglleGVjdXRlZEhlaWdodCBpbnQ2NCwKCWV4ZWN1dGVkQnkgYWRkcmVzcywKKSAoKmdvdmVybmFuY2UuUHJvcG9zYWwsIGVycm9yKSB7CgkvLyBSZXRyaWV2ZSB0aGUgcHJvcG9zYWwgZnJvbSBzdG9yYWdlCglwcm9wb3NhbCwgb2sgOj0gZ3YuZ2V0UHJvcG9zYWwocHJvcG9zYWxJRCkKCWlmICFvayB7CgkJcmV0dXJuIG5pbCwgZXJyb3JzLk5ldyhlcnJEYXRhTm90Rm91bmQpCgl9CgoJLy8gVGV4dCBwcm9wb3NhbHMgY2Fubm90IGJlIGV4ZWN1dGVkICh0aGV5IGFyZSBpbmZvcm1hdGlvbmFsIG9ubHkpCglpZiBwcm9wb3NhbC5Jc1RleHRUeXBlKCkgewoJCXJldHVybiBuaWwsIGVycm9ycy5OZXcoZXJyVGV4dFByb3Bvc2FsTm90RXhlY3V0YWJsZSkKCX0KCglwcm9wb3NhbFJlc29sdmVyIDo9IE5ld1Byb3Bvc2FsUmVzb2x2ZXIocHJvcG9zYWwpCgoJLy8gVmVyaWZ5IHByb3Bvc2FsIGlzIGluIGV4ZWN1dGFibGUgc3RhdGUgKHRpbWluZyBhbmQgdm90aW5nIHJlcXVpcmVtZW50cyBtZXQpCglpZiAhcHJvcG9zYWxSZXNvbHZlci5Jc0V4ZWN1dGFibGUoZXhlY3V0ZWRBdCkgewoJCXJldHVybiBuaWwsIGVycm9ycy5OZXcoZXJyUHJvcG9zYWxOb3RFeGVjdXRhYmxlKQoJfQoKCS8vIE1hcmsgcHJvcG9zYWwgYXMgZXhlY3V0ZWQgaW4gaXRzIHN0YXR1cwoJZXJyIDo9IHByb3Bvc2FsUmVzb2x2ZXIuZXhlY3V0ZShleGVjdXRlZEF0LCBleGVjdXRlZEhlaWdodCwgZXhlY3V0ZWRCeSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBuaWwsIGVycgoJfQoKCS8vIEV4ZWN1dGUgcHJvcG9zYWwgYmFzZWQgb24gaXRzIHR5cGUKCXN3aXRjaCBwcm9wb3NhbC5UeXBlKCkgewoJY2FzZSBnb3Zlcm5hbmNlLkNvbW11bml0eVBvb2xTcGVuZDoKCQkvLyBFeGVjdXRlIGNvbW11bml0eSBwb29sIHNwZW5kaW5nICh0b2tlbiB0cmFuc2ZlcnMpCgkJZXJyID0gZXhlY3V0ZUNvbW11bml0eVBvb2xTcGVuZCgwLCBybG0sIHByb3Bvc2FsLCBnbG9iYWxQYXJhbWV0ZXJSZWdpc3RyeSwgZXhlY3V0ZWRBdCwgZXhlY3V0ZWRIZWlnaHQsIGV4ZWN1dGVkQnkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBuaWwsIGVycgoJCX0KCWNhc2UgZ292ZXJuYW5jZS5QYXJhbWV0ZXJDaGFuZ2U6CgkJLy8gRXhlY3V0ZSBwYXJhbWV0ZXIgY2hhbmdlcyAoZ292ZXJuYW5jZSBjb25maWd1cmF0aW9uIHVwZGF0ZXMpCgkJZXJyID0gZXhlY3V0ZVBhcmFtZXRlckNoYW5nZSgwLCBybG0sIHByb3Bvc2FsLCBnbG9iYWxQYXJhbWV0ZXJSZWdpc3RyeSwgZXhlY3V0ZWRBdCwgZXhlY3V0ZWRIZWlnaHQsIGV4ZWN1dGVkQnkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBuaWwsIGVycgoJCX0KCX0KCglyZXR1cm4gcHJvcG9zYWwsIG5pbAp9CgovLyBDYW5jZWwgY2FuY2VscyBhIHByb3Bvc2FsIGluIHVwY29taW5nIHN0YXR1cy4KLy8KLy8gQWxsb3dzIHByb3Bvc2VycyB0byB3aXRoZHJhdyB0aGVpciBwcm9wb3NhbHMgYmVmb3JlIHZvdGluZyBiZWdpbnMuCi8vIFByZXZlbnRzIGFjY2lkZW50YWwgb3IgbWFsaWNpb3VzIHByb3Bvc2FscyBmcm9tIHJlYWNoaW5nIHZvdGUuCi8vIFNhZmV0eSBtZWNoYW5pc20gZm9yIHByb3Bvc2FsIGVycm9ycyBvciBjaGFuZ2VkIGNpcmN1bXN0YW5jZXMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBJbnRlcm5hbCBjYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogUHJvcGFnYXRlZCByZWFsbSBjb250ZXh0OyBtdXN0IGJlIGN1cnJlbnQgZm9yIGF1dGhvcml6ZWQgZ292ZXJuYW5jZSBzdGF0ZSB1cGRhdGVzIGFuZCBpcyBjcm9zc2VkIGludG8gcmV3YXJkLWRpc3RyaWJ1dGlvbiBjYWxscy4KLy8gICAtIHByb3Bvc2FsSUQ6IElEIG9mIHRoZSBwcm9wb3NhbCB0byBjYW5jZWwKLy8KLy8gUmVxdWlyZW1lbnRzOgovLyAgIC0gTXVzdCBiZSBjYWxsZWQgYnkgb3JpZ2luYWwgcHJvcG9zZXIKLy8gICAtIFByb3Bvc2FsIG11c3QgYmUgaW4gInVwY29taW5nIiBzdGF0dXMKLy8gICAtIFZvdGluZyBtdXN0IG5vdCBoYXZlIHN0YXJ0ZWQgeWV0Ci8vICAgLSBQcm9wb3NhbCBub3QgYWxyZWFkeSBjYW5jZWxsZWQgb3IgZXhlY3V0ZWQKLy8KLy8gRWZmZWN0czoKLy8gICAtIFNldHMgcHJvcG9zYWwgc3RhdHVzIHRvICJjYW5jZWxsZWQiCi8vICAgLSBQcmV2ZW50cyBmdXR1cmUgdm90aW5nIG9yIGV4ZWN1dGlvbgovLyAgIC0gRW1pdHMgY2FuY2VsbGF0aW9uIGV2ZW50Ci8vICAgLSBGcmVlcyB1cCBwcm9wb3NlcidzIHByb3Bvc2FsIHNsb3QKLy8KLy8gUmV0dXJuczoKLy8gICAtIHByb3Bvc2FsSUQ6IElEIG9mIHRoZSBjYW5jZWxsZWQgcHJvcG9zYWwKLy8KLy8gT25seSBjYWxsYWJsZSBieSBvcmlnaW5hbCBwcm9wb3NlciBiZWZvcmUgdm90aW5nIGJlZ2lucy4KZnVuYyAoZ3YgKmdvdmVybmFuY2VWMSkgQ2FuY2VsKF8gaW50LCBybG0gcmVhbG0sIHByb3Bvc2FsSUQgaW50NjQpIGludDY0IHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRHb3Zlcm5hbmNlKCkKCglwcmV2IDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldi5BZGRyZXNzKCkKCWFzc2VydENhbGxlcklzUHJvcG9zZXIoZ3YsIHByb3Bvc2FsSUQsIGNhbGxlcikKCgkvLyBHZXQgY3VycmVudCBibG9ja2NoYWluIHN0YXRlIGFuZCBjYWxsZXIgaW5mb3JtYXRpb24KCWN1cnJlbnRIZWlnaHQgOj0gcnVudGltZS5DaGFpbkhlaWdodCgpCgljdXJyZW50QXQgOj0gdGltZS5Ob3coKS5Vbml4KCkKCgkvLyBNaW50IGFuZCBkaXN0cmlidXRlIEdOUyB0b2tlbnMgYXMgcGFydCBvZiB0aGUgcHJvY2VzcwoJZW1pc3Npb24uTWludEFuZERpc3RyaWJ1dGVHbnMoY3Jvc3MocmxtKSkKCgkvLyBBdHRlbXB0IHRvIGNhbmNlbCB0aGUgcHJvcG9zYWwKCXByb3Bvc2FsLCBlcnIgOj0gZ3YuY2FuY2VsKHByb3Bvc2FsSUQsIGN1cnJlbnRBdCwgY3VycmVudEhlaWdodCwgY2FsbGVyKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoJaWYgZXJyIDo9IGd2LnJlbW92ZUFjdGl2ZVByb3Bvc2FsKDAsIHJsbSwgcHJvcG9zYWwpOyBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJLy8gRW1pdCBjYW5jZWxsYXRpb24gZXZlbnQgZm9yIHRyYWNraW5nCgljaGFpbi5FbWl0KAoJCSJDYW5jZWwiLAoJCSJwcmV2QWRkciIsIHByZXYuQWRkcmVzcygpLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2LlBrZ1BhdGgoKSwKCQkicHJvcG9zYWxJZCIsIHV0aWxzLkZvcm1hdEludChwcm9wb3NhbElEKSwKCSkKCglyZXR1cm4gcHJvcG9zYWwuSUQoKQp9CgovLyBSZW1vdmVJbmFjdGl2ZVByb3Bvc2FsRnJvbUluZGV4IHJlbW92ZXMgb25lIGluYWN0aXZlIHByb3Bvc2FsIGZyb20gdGhlCi8vIHNuYXBzaG90IGluZGV4IHdpdGhvdXQgZGVsZXRpbmcgaXRzIHByb3Bvc2FsIG9yIHZvdGluZyBoaXN0b3J5LgovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogSW50ZXJuYWwgY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IFByb3BhZ2F0ZWQgcmVhbG0gY29udGV4dCB1c2VkIGZvciB0aGUgYXV0aG9yaXplZCBzbmFwc2hvdC1pbmRleCB1cGRhdGUuCi8vICAgLSBwcm9wb3NhbElEOiBJZGVudGlmaWVyIG9mIHRoZSBpbmFjdGl2ZSBwcm9wb3NhbCB0byByZW1vdmUgZnJvbSB0aGUgc25hcHNob3QgaW5kZXguCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIFJlbW92ZUluYWN0aXZlUHJvcG9zYWxGcm9tSW5kZXgoXyBpbnQsIHJsbSByZWFsbSwgcHJvcG9zYWxJRCBpbnQ2NCkgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZEdvdmVybmFuY2UoKQoKCXByb3Bvc2FsLCBleGlzdHMgOj0gZ3YuZ2V0UHJvcG9zYWwocHJvcG9zYWxJRCkKCWlmICFleGlzdHMgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKGVyclByb3Bvc2FsTm90Rm91bmQsIHVmbXQuU3ByaW50ZigicHJvcG9zYWxJRDogJWQiLCBwcm9wb3NhbElEKSkpCgl9CglpZiBOZXdQcm9wb3NhbFJlc29sdmVyKHByb3Bvc2FsKS5Jc0FjdGl2ZSh0aW1lLk5vdygpLlVuaXgoKSkgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKGVyckludmFsaWRJbnB1dCwgdWZtdC5TcHJpbnRmKCJwcm9wb3NhbCAlZCBpcyBzdGlsbCBhY3RpdmUiLCBwcm9wb3NhbElEKSkpCgl9CglpZiBlcnIgOj0gZ3YucmVtb3ZlQWN0aXZlUHJvcG9zYWwoMCwgcmxtLCBwcm9wb3NhbCk7IGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglwcmV2IDo9IHJsbS5QcmV2aW91cygpCgljaGFpbi5FbWl0KAoJCSJSZW1vdmVJbmFjdGl2ZVByb3Bvc2FsRnJvbUluZGV4IiwKCQkicHJldkFkZHIiLCBwcmV2LkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldi5Qa2dQYXRoKCksCgkJInByb3Bvc2FsSWQiLCB1dGlscy5Gb3JtYXRJbnQocHJvcG9zYWxJRCksCgkpCn0KCi8vIGNhbmNlbCBoYW5kbGVzIGNvcmUgbG9naWMgb2YgcHJvcG9zYWwgY2FuY2VsbGF0aW9uLgovLyBWYWxpZGF0ZXMgcHJvcG9zYWwgc3RhdGUgYW5kIHVwZGF0ZXMgc3RhdHVzIHRvIGNhbmNlbGVkLgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBjYW5jZWwoCglwcm9wb3NhbElELCBjYW5jZWxlZEF0LCBjYW5jZWxlZEhlaWdodCBpbnQ2NCwKCWNhbmNlbGVkQnkgYWRkcmVzcywKKSAocHJvcG9zYWwgKmdvdmVybmFuY2UuUHJvcG9zYWwsIGVyciBlcnJvcikgewoJLy8gUmV0cmlldmUgdGhlIHByb3Bvc2FsIGZyb20gc3RvcmFnZQoJcHJvcG9zYWwsIG9rIDo9IGd2LmdldFByb3Bvc2FsKHByb3Bvc2FsSUQpCglpZiAhb2sgewoJCXJldHVybiBuaWwsIGVycm9ycy5OZXcoZXJyRGF0YU5vdEZvdW5kKQoJfQoKCXByb3Bvc2FsUmVzb2x2ZXIgOj0gTmV3UHJvcG9zYWxSZXNvbHZlcihwcm9wb3NhbCkKCgkvLyBBdHRlbXB0IHRvIGNhbmNlbCB0aGUgcHJvcG9zYWwgKHRoaXMgdmFsaWRhdGVzIGNhbmNlbGxhdGlvbiBjb25kaXRpb25zKQoJZXJyID0gcHJvcG9zYWxSZXNvbHZlci5jYW5jZWwoY2FuY2VsZWRBdCwgY2FuY2VsZWRIZWlnaHQsIGNhbmNlbGVkQnkpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBlcnIKCX0KCglyZXR1cm4gcHJvcG9zYWwsIG5pbAp9CgovLyBleGVjdXRlQ29tbXVuaXR5UG9vbFNwZW5kIGV4ZWN1dGVzIGNvbW11bml0eSBwb29sIHNwZW5kaW5nIHByb3Bvc2Fscy4KLy8gSGFuZGxlcyB0b2tlbiB0cmFuc2ZlcnMgZnJvbSBjb21tdW5pdHkgcG9vbCB0byBzcGVjaWZpZWQgcmVjaXBpZW50cy4KZnVuYyBleGVjdXRlQ29tbXVuaXR5UG9vbFNwZW5kKAoJXyBpbnQsIHJsbSByZWFsbSwKCXByb3Bvc2FsICpnb3Zlcm5hbmNlLlByb3Bvc2FsLAoJcGFyYW1ldGVyUmVnaXN0cnkgKlBhcmFtZXRlclJlZ2lzdHJ5LAoJZXhlY3V0ZWRBdCBpbnQ2NCwKCWV4ZWN1dGVkSGVpZ2h0IGludDY0LAoJZXhlY3V0ZWRCeSBhZGRyZXNzLAopIGVycm9yIHsKCS8vIFZlcmlmeSB0b2tlbiByZWdpc3RyYXRpb24gZm9yIGNvbW11bml0eSBwb29sIHNwZW5kaW5nCglpZiBwcm9wb3NhbC5Jc0NvbW11bml0eVBvb2xTcGVuZFR5cGUoKSB7CgkJY29tbW9uLk11c3RSZWdpc3RlcmVkKHByb3Bvc2FsLkRhdGEoKS5Db21tdW5pdHlQb29sU3BlbmQoKS5Ub2tlblBhdGgoKSkKCX0KCgkvLyBFeGVjdXRlIGFsbCBwYXJhbWV0ZXIgY2hhbmdlcyBkZWZpbmVkIGluIHRoZSBwcm9wb3NhbAoJZGF0YVJlc29sdmVyIDo9IE5ld1Byb3Bvc2FsRGF0YVJlc29sdmVyKHByb3Bvc2FsLkRhdGEoKSkKCXBhcmFtZXRlckNoYW5nZXNJbmZvcywgZXJyIDo9IGRhdGFSZXNvbHZlci5QYXJhbWV0ZXJDaGFuZ2VzSW5mb3MoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJZm9yIF8sIHBhcmFtZXRlckNoYW5nZUluZm8gOj0gcmFuZ2UgcGFyYW1ldGVyQ2hhbmdlc0luZm9zIHsKCQkvLyBHZXQgdGhlIGFwcHJvcHJpYXRlIGhhbmRsZXIgZm9yIHRoaXMgcGFyYW1ldGVyIGNoYW5nZQoJCWtleSA6PSBtYWtlSGFuZGxlcktleShwYXJhbWV0ZXJDaGFuZ2VJbmZvLlBrZ1BhdGgoKSwgcGFyYW1ldGVyQ2hhbmdlSW5mby5GdW5jdGlvbigpKQoJCWhhbmRsZXIsIGVyciA6PSBwYXJhbWV0ZXJSZWdpc3RyeS5IYW5kbGVyKGtleSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCgkJLy8gRXhlY3V0ZSB0aGUgcGFyYW1ldGVyIGNoYW5nZSB3aXRoIHByb3ZpZGVkIHBhcmFtZXRlcnMKCQllcnIgPSBoYW5kbGVyLkV4ZWN1dGUoMCwgcmxtLCBwYXJhbWV0ZXJDaGFuZ2VJbmZvLlBhcmFtcygpKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCXJldHVybiBuaWwKfQoKLy8gZXhlY3V0ZVBhcmFtZXRlckNoYW5nZSBleGVjdXRlcyBwYXJhbWV0ZXIgY2hhbmdlIHByb3Bvc2Fscy4KLy8gSGFuZGxlcyBnb3Zlcm5hbmNlIGNvbmZpZ3VyYXRpb24gdXBkYXRlcyBhbmQgc3lzdGVtIHBhcmFtZXRlciBtb2RpZmljYXRpb25zLgpmdW5jIGV4ZWN1dGVQYXJhbWV0ZXJDaGFuZ2UoCglfIGludCwgcmxtIHJlYWxtLAoJcHJvcG9zYWwgKmdvdmVybmFuY2UuUHJvcG9zYWwsCglwYXJhbWV0ZXJSZWdpc3RyeSAqUGFyYW1ldGVyUmVnaXN0cnksCglleGVjdXRlZEF0IGludDY0LAoJZXhlY3V0ZWRIZWlnaHQgaW50NjQsCglleGVjdXRlZEJ5IGFkZHJlc3MsCikgZXJyb3IgewoJLy8gRXhlY3V0ZSBhbGwgcGFyYW1ldGVyIGNoYW5nZXMgZGVmaW5lZCBpbiB0aGUgcHJvcG9zYWwKCWRhdGFSZXNvbHZlciA6PSBOZXdQcm9wb3NhbERhdGFSZXNvbHZlcihwcm9wb3NhbC5EYXRhKCkpCglwYXJhbWV0ZXJDaGFuZ2VzSW5mb3MsIGVyciA6PSBkYXRhUmVzb2x2ZXIuUGFyYW1ldGVyQ2hhbmdlc0luZm9zKCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCWZvciBfLCBwYXJhbWV0ZXJDaGFuZ2VJbmZvIDo9IHJhbmdlIHBhcmFtZXRlckNoYW5nZXNJbmZvcyB7CgkJLy8gR2V0IHRoZSBhcHByb3ByaWF0ZSBoYW5kbGVyIGZvciB0aGlzIHBhcmFtZXRlciBjaGFuZ2UKCQlrZXkgOj0gbWFrZUhhbmRsZXJLZXkocGFyYW1ldGVyQ2hhbmdlSW5mby5Qa2dQYXRoKCksIHBhcmFtZXRlckNoYW5nZUluZm8uRnVuY3Rpb24oKSkKCQloYW5kbGVyLCBlcnIgOj0gcGFyYW1ldGVyUmVnaXN0cnkuSGFuZGxlcihrZXkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9CgoJCS8vIEV4ZWN1dGUgdGhlIHBhcmFtZXRlciBjaGFuZ2Ugd2l0aCBwcm92aWRlZCBwYXJhbWV0ZXJzCgkJZXJyID0gaGFuZGxlci5FeGVjdXRlKDAsIHJsbSwgcGFyYW1ldGVyQ2hhbmdlSW5mby5QYXJhbXMoKSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCglyZXR1cm4gbmlsCn0KGoxsChZnb3Zlcm5hbmNlX3Byb3Bvc2UuZ25vEvFrcGFja2FnZSBnb3Zlcm5hbmNlCgppbXBvcnQgKAoJImNoYWluIgoJImNoYWluL3J1bnRpbWUiCgkiZXJyb3JzIgoJInRpbWUiCgoJImduby5sYW5kL3IvZ25vc3dhcC9hY2Nlc3MvdjEiCgoJZ25zbWF0aCAiZ25vLmxhbmQvcC9nbm9zd2FwL2duc21hdGgvdjEiCgkiZ25vLmxhbmQvcC9nbm9zd2FwL3V0aWxzL3YxIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvZ292L3hnbnMiCgkiZ25vLmxhbmQvci9nbm9zd2FwL2hhbHQvdjEiCgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3YvZ292ZXJuYW5jZSIKKQoKLy8gUHJvcG9zZVRleHQgY3JlYXRlcyBhIHRleHQgcHJvcG9zYWwgZm9yIGNvbW11bml0eSBkaXNjdXNzaW9uLgovLwovLyBTaWduYWwgcHJvcG9zYWxzIGZvciBub24tYmluZGluZyBjb21tdW5pdHkgc2VudGltZW50LgovLyBVc2VkIGZvciBwb2xpY3kgZGlzY3Vzc2lvbnMsIHJvYWRtYXAgcGxhbm5pbmcsIGFuZCBjb21tdW5pdHkgZmVlZGJhY2suCi8vIE5vIG9uLWNoYWluIGV4ZWN1dGlvbiwgc2VydmVzIGFzIGZvcm1hbCBnb3Zlcm5hbmNlIHJlY29yZC4KLy8KLy8gUGFyYW1ldGVyczoKLy8KLy8gICAtIF86IEludGVybmFsIGNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLwovLyAgIC0gcmxtOiBQcm9wYWdhdGVkIHJlYWxtIGNvbnRleHQ7IHZhbGlkYXRlZCBhcyBjdXJyZW50IGJlZm9yZSBwcm9wb3NhbCBzdGF0ZSB3cml0ZXMuCi8vCi8vICAgLSB0aXRsZTogU2hvcnQsIGRlc2NyaXB0aXZlIHByb3Bvc2FsIHRpdGxlICh1cCB0byAyNTUgY2hhcmFjdGVyczsgMTAwIGlzIGEgVVggcmVjb21tZW5kYXRpb24pCi8vCi8vICAgLSBkZXNjcmlwdGlvbjogRnVsbCBwcm9wb3NhbCBjb250ZW50IHdpdGggcmF0aW9uYWxlIGFuZCBjb250ZXh0Ci8vCi8vIFJlcXVpcmVtZW50czoKLy8gICAtIENhbGxlciBtdXN0IGhvbGQgYXQgbGVhc3QgdGhlIGNvbmZpZ3VyZWQgUHJvcG9zYWxDcmVhdGlvblRocmVzaG9sZCBhbW91bnQgaW4geEdOUwovLyAgIC0gTm8gb3RoZXIgYWN0aXZlIHByb3Bvc2FsIGZyb20gc2FtZSBhZGRyZXNzCi8vICAgLSBUaXRsZSBhbmQgZGVzY3JpcHRpb24gbXVzdCBiZSBub24tZW1wdHkKLy8KLy8gUHJvY2VzczoKLy8gICAtIENvbmZpZ3VyZWQgZGVsYXkgYmVmb3JlIHZvdGluZyBzdGFydHMgKDEgZGF5IGJ5IGRlZmF1bHQpCi8vICAgLSBDb25maWd1cmVkIHZvdGluZyBwZXJpb2QgKDcgZGF5cyBieSBkZWZhdWx0KQovLyAgIC0gUXVvcnVtIGFuZCBhIHN0cmljdCB5ZXMtb3Zlci1ubyBtYWpvcml0eSBkZXRlcm1pbmUgdGhlIG91dGNvbWUKLy8gICAtIE5vIGV4ZWN1dGlvbiBwaGFzZSAoc2lnbmFsIG9ubHkpCi8vCi8vIFJldHVybnM6Ci8vICAgLSBuZXdQcm9wb3NhbElkOiBJRCBvZiB0aGUgbmV3bHkgY3JlYXRlZCB0ZXh0IHByb3Bvc2FsCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIFByb3Bvc2VUZXh0KAoJXyBpbnQsIHJsbSByZWFsbSwKCXRpdGxlIHN0cmluZywKCWRlc2NyaXB0aW9uIHN0cmluZywKKSAobmV3UHJvcG9zYWxJZCBpbnQ2NCkgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZEdvdmVybmFuY2UoKQoKCXByZXYgOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlckFkZHJlc3MgOj0gcHJldi5BZGRyZXNzKCkKCgljcmVhdGVkQXQgOj0gdGltZS5Ob3coKS5Vbml4KCkKCWNyZWF0ZWRIZWlnaHQgOj0gcnVudGltZS5DaGFpbkhlaWdodCgpCgl4Z25zQmFsYW5jZSA6PSB4Z25zLkJhbGFuY2VPZihjYWxsZXJBZGRyZXNzKQoKCWNvbmZpZywgb2sgOj0gZ3YuZ2V0Q3VycmVudENvbmZpZygpCglpZiAhb2sgewoJCXBhbmljKGVycm9ycy5OZXcoZXJyRGF0YU5vdEZvdW5kKSkKCX0KCgkvLyBDbGVhbiB1cCBpbmFjdGl2ZSB1c2VyIHByb3Bvc2FscyBiZWZvcmUgY2hlY2tpbmcgaWYgY2FsbGVyIGFscmVhZHkgaGFzIGFuIGFjdGl2ZSBwcm9wb3NhbAoJZXJyIDo9IGd2LnJlbW92ZUluYWN0aXZlVXNlclByb3Bvc2FscygwLCBybG0sIGNhbGxlckFkZHJlc3MsIGNyZWF0ZWRBdCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgkvLyBDaGVjayBpZiBjYWxsZXIgYWxyZWFkeSBoYXMgYW4gYWN0aXZlIHByb3Bvc2FsIChvbmUgcHJvcG9zYWwgcGVyIGFkZHJlc3MpCglpZiBndi5oYXNBY3RpdmVQcm9wb3NhbChjYWxsZXJBZGRyZXNzKSB7CgkJcGFuaWMoZXJyb3JzLk5ldyhlcnJBbHJlYWR5QWN0aXZlUHJvcG9zYWwpKQoJfQoKCS8vIEdldCB0aW1lc3RhbXAgYW5jaG9yIGFuZCB0b3RhbCB2b3Rpbmcgd2VpZ2h0IGZvciBwcm9wb3NhbCBjcmVhdGlvbgoJbWF4Vm90aW5nV2VpZ2h0LCBzbmFwc2hvdFRpbWUsIGVyciA6PSBndi5nZXRWb3RpbmdXZWlnaHRTbmFwc2hvdCgKCQljcmVhdGVkQXQsCgkJY29uZmlnLlZvdGluZ1dlaWdodFNtb290aGluZ0R1cmF0aW9uLAoJKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoJcXVvcnVtV2VpZ2h0IDo9IGd2LnN0YWtlckFjY2Vzc29yLkdldFRvdGFseEduc1N1cHBseSgpCgoJLy8gQ3JlYXRlIHRoZSB0ZXh0IHByb3Bvc2FsIHdpdGggbWV0YWRhdGEKCXByb3Bvc2FsLCBlcnIgOj0gZ3YuY3JlYXRlUHJvcG9zYWwoCgkJMCwgcmxtLAoJCWdvdmVybmFuY2UuVGV4dCwKCQljb25maWcsCgkJbWF4Vm90aW5nV2VpZ2h0LAoJCXF1b3J1bVdlaWdodCwKCQlzbmFwc2hvdFRpbWUsCgkJZ292ZXJuYW5jZS5OZXdQcm9wb3NhbE1ldGFkYXRhKHRpdGxlLCBkZXNjcmlwdGlvbiksCgkJTmV3UHJvcG9zYWxUZXh0RGF0YSgpLAoJCWNhbGxlckFkZHJlc3MsCgkJeGduc0JhbGFuY2UsCgkJY3JlYXRlZEF0LAoJCWNyZWF0ZWRIZWlnaHQsCgkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJLy8gSW5pdGlhbGl6ZSBlbXB0eSB2b3RpbmcgaW5mbyB0cmVlIGZvciB0aGlzIHByb3Bvc2FsICh2b3RlcyB3aWxsIGJlIGFkZGVkIGFzIHVzZXJzIHZvdGUpCgllcnIgPSBndi51cGRhdGVQcm9wb3NhbFVzZXJWb3RlcygwLCBybG0sIHByb3Bvc2FsLCBnb3Zlcm5hbmNlLk5ld1Byb3Bvc2FsVXNlclZvdGluZ0luZm9UcmVlKCkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJLy8gRW1pdCBwcm9wb3NhbCBjcmVhdGlvbiBldmVudCBmb3IgaW5kZXhpbmcgYW5kIHRyYWNraW5nCgljaGFpbi5FbWl0KAoJCSJQcm9wb3NlVGV4dCIsCgkJInByZXZBZGRyIiwgcHJldi5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXYuUGtnUGF0aCgpLAoJCSJ0aXRsZSIsIHRpdGxlLAoJCSJwcm9wb3NhbElkIiwgdXRpbHMuRm9ybWF0SW50KHByb3Bvc2FsLklEKCkpLAoJCSJxdW9ydW1BbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQocHJvcG9zYWwuVm90aW5nUXVvcnVtQW1vdW50KCkpLAoJCSJtYXhWb3RpbmdXZWlnaHQiLCB1dGlscy5Gb3JtYXRJbnQocHJvcG9zYWwuVm90aW5nTWF4V2VpZ2h0KCkpLAoJCSJjb25maWdWZXJzaW9uIiwgdXRpbHMuRm9ybWF0SW50KHByb3Bvc2FsLkNvbmZpZ1ZlcnNpb24oKSksCgkJImNyZWF0ZWRBdCIsIHV0aWxzLkZvcm1hdEludChwcm9wb3NhbC5DcmVhdGVkQXQoKSksCgkpCgoJcmV0dXJuIHByb3Bvc2FsLklEKCkKfQoKLy8gUHJvcG9zZUNvbW11bml0eVBvb2xTcGVuZCBjcmVhdGVzIGEgdHJlYXN1cnkgZGlzYnVyc2VtZW50IHByb3Bvc2FsLgovLwovLyBBbGxvY2F0ZXMgY29tbXVuaXR5IHBvb2wgZnVuZHMgZm9yIGFwcHJvdmVkIHB1cnBvc2VzLgovLyBTdXBwb3J0cyBncmFudHMsIGRldmVsb3BtZW50IGZ1bmRpbmcsIGFuZCBwcm90b2NvbCBpbmNlbnRpdmVzLgovLyBUaGUgdHJhbnNmZXIgaXMgYXR0ZW1wdGVkIHdoZW4gdGhlIGFwcHJvdmVkIHByb3Bvc2FsIGV4ZWN1dGVzLgovLwovLyBQYXJhbWV0ZXJzOgovLwovLyAgIC0gXzogSW50ZXJuYWwgY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vCi8vICAgLSBybG06IFByb3BhZ2F0ZWQgcmVhbG0gY29udGV4dDsgdmFsaWRhdGVkIGFzIGN1cnJlbnQgYmVmb3JlIHByb3Bvc2FsIHN0YXRlIHdyaXRlcy4KLy8KLy8gICAtIHRpdGxlOiBQcm9wb3NhbCB0aXRsZSBkZXNjcmliaW5nIHB1cnBvc2UKLy8KLy8gICAtIGRlc2NyaXB0aW9uOiBEZXRhaWxlZCBqdXN0aWZpY2F0aW9uIGFuZCBidWRnZXQgYnJlYWtkb3duCi8vCi8vICAgLSB0bzogUmVjaXBpZW50IGFkZHJlc3MgZm9yIGZ1bmRzCi8vCi8vICAgLSB0b2tlblBhdGg6IFJlZ2lzdGVyZWQgdG9rZW4gY29udHJhY3QgcGF0aCAoZS5nLiwgImduby5sYW5kL3IvZ25vc3dhcC9nbnMiKQovLwovLyAgIC0gYW1vdW50OiBTdHJpY3RseSBwb3NpdGl2ZSBhbW91bnQgdG8gdHJhbnNmZXIgKGluIHNtYWxsZXN0IHVuaXQpCi8vCi8vIFJlcXVpcmVtZW50czoKLy8gICAtIENhbGxlciBtdXN0IGhvbGQgYXQgbGVhc3QgdGhlIGNvbmZpZ3VyZWQgUHJvcG9zYWxDcmVhdGlvblRocmVzaG9sZCBhbW91bnQgaW4geEdOUwovLyAgIC0gVmFsaWQgcmVjaXBpZW50IGFkZHJlc3MKLy8gICAtIFJlZ2lzdGVyZWQgdG9rZW4gcGF0aAovLyAgIC0gQ29tbXVuaXR5LXBvb2wgYmFsYW5jZSBpcyBjaGVja2VkIGF0IGV4ZWN1dGlvbiwgbm90IHByb3Bvc2FsIGNyZWF0aW9uCi8vCi8vIFNlY3VyaXR5OgovLyAgIC0gRW5mb3JjZXMgdGltZWxvY2sgYWZ0ZXIgYXBwcm92YWwKLy8gICAtIFNpbmdsZSB0cmFuc2ZlciBwZXIgcHJvcG9zYWwKLy8gICAtIFRyYWNrcyBhbGwgZGlzYnVyc2VtZW50cyBvbi1jaGFpbgovLwovLyBSZXR1cm5zOgovLyAgIC0gbmV3UHJvcG9zYWxJZDogSUQgb2YgdGhlIG5ld2x5IGNyZWF0ZWQgY29tbXVuaXR5LXBvb2wtc3BlbmQgcHJvcG9zYWwKZnVuYyAoZ3YgKmdvdmVybmFuY2VWMSkgUHJvcG9zZUNvbW11bml0eVBvb2xTcGVuZCgKCV8gaW50LCBybG0gcmVhbG0sCgl0aXRsZSBzdHJpbmcsCglkZXNjcmlwdGlvbiBzdHJpbmcsCgl0byBhZGRyZXNzLAoJdG9rZW5QYXRoIHN0cmluZywKCWFtb3VudCBpbnQ2NCwKKSAobmV3UHJvcG9zYWxJZCBpbnQ2NCkgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZEdvdmVybmFuY2UoKQoKCWFzc2VydElzVmFsaWRUb2tlbih0b2tlblBhdGgpCgoJY3JlYXRlZEF0IDo9IHRpbWUuTm93KCkuVW5peCgpCgljcmVhdGVkSGVpZ2h0IDo9IHJ1bnRpbWUuQ2hhaW5IZWlnaHQoKQoKCXByZXYgOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlckFkZHJlc3MgOj0gcHJldi5BZGRyZXNzKCkKCXhnbnNCYWxhbmNlIDo9IHhnbnMuQmFsYW5jZU9mKGNhbGxlckFkZHJlc3MpCgoJY29uZmlnLCBvayA6PSBndi5nZXRDdXJyZW50Q29uZmlnKCkKCWlmICFvayB7CgkJcGFuaWMoZXJyb3JzLk5ldyhlcnJEYXRhTm90Rm91bmQpKQoJfQoKCS8vIENsZWFuIHVwIGluYWN0aXZlIHVzZXIgcHJvcG9zYWxzIGJlZm9yZSBjaGVja2luZyBpZiBjYWxsZXIgYWxyZWFkeSBoYXMgYW4gYWN0aXZlIHByb3Bvc2FsCgllcnIgOj0gZ3YucmVtb3ZlSW5hY3RpdmVVc2VyUHJvcG9zYWxzKDAsIHJsbSwgY2FsbGVyQWRkcmVzcywgY3JlYXRlZEF0KQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCS8vIENoZWNrIGlmIGNhbGxlciBhbHJlYWR5IGhhcyBhbiBhY3RpdmUgcHJvcG9zYWwgKG9uZSBwcm9wb3NhbCBwZXIgYWRkcmVzcykKCWlmIGd2Lmhhc0FjdGl2ZVByb3Bvc2FsKGNhbGxlckFkZHJlc3MpIHsKCQlwYW5pYyhlcnJvcnMuTmV3KGVyckFscmVhZHlBY3RpdmVQcm9wb3NhbCkpCgl9CgoJLy8gR2V0IHRpbWVzdGFtcCBhbmNob3IgYW5kIHRvdGFsIHZvdGluZyB3ZWlnaHQgZm9yIHByb3Bvc2FsIGNyZWF0aW9uCgltYXhWb3RpbmdXZWlnaHQsIHNuYXBzaG90VGltZSwgZXJyIDo9IGd2LmdldFZvdGluZ1dlaWdodFNuYXBzaG90KAoJCWNyZWF0ZWRBdCwKCQljb25maWcuVm90aW5nV2VpZ2h0U21vb3RoaW5nRHVyYXRpb24sCgkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CglxdW9ydW1XZWlnaHQgOj0gZ3Yuc3Rha2VyQWNjZXNzb3IuR2V0VG90YWx4R25zU3VwcGx5KCkKCgkvLyBDcmVhdGUgdGhlIGNvbW11bml0eSBwb29sIHNwZW5kIHByb3Bvc2FsIHdpdGggZXhlY3V0aW9uIGRhdGEKCXByb3Bvc2FsLCBlcnIgOj0gZ3YuY3JlYXRlUHJvcG9zYWwoCgkJMCwgcmxtLAoJCWdvdmVybmFuY2UuQ29tbXVuaXR5UG9vbFNwZW5kLAoJCWNvbmZpZywKCQltYXhWb3RpbmdXZWlnaHQsCgkJcXVvcnVtV2VpZ2h0LAoJCXNuYXBzaG90VGltZSwKCQlnb3Zlcm5hbmNlLk5ld1Byb3Bvc2FsTWV0YWRhdGEodGl0bGUsIGRlc2NyaXB0aW9uKSwKCQlOZXdQcm9wb3NhbENvbW11bml0eVBvb2xTcGVuZERhdGEodG9rZW5QYXRoLCB0bywgYW1vdW50LCBDT01NVU5JVFlfUE9PTF9QQVRIKSwKCQljYWxsZXJBZGRyZXNzLAoJCXhnbnNCYWxhbmNlLAoJCWNyZWF0ZWRBdCwKCQljcmVhdGVkSGVpZ2h0LAoJKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCS8vIEluaXRpYWxpemUgZW1wdHkgdm90aW5nIGluZm8gdHJlZSBmb3IgdGhpcyBwcm9wb3NhbCAodm90ZXMgd2lsbCBiZSBhZGRlZCBhcyB1c2VycyB2b3RlKQoJZXJyID0gZ3YudXBkYXRlUHJvcG9zYWxVc2VyVm90ZXMoMCwgcmxtLCBwcm9wb3NhbCwgZ292ZXJuYW5jZS5OZXdQcm9wb3NhbFVzZXJWb3RpbmdJbmZvVHJlZSgpKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCS8vIEVtaXQgcHJvcG9zYWwgY3JlYXRpb24gZXZlbnQgZm9yIGluZGV4aW5nIGFuZCB0cmFja2luZwoJY2hhaW4uRW1pdCgKCQkiUHJvcG9zZUNvbW11bml0eVBvb2xTcGVuZCIsCgkJInByZXZBZGRyIiwgcHJldi5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXYuUGtnUGF0aCgpLAoJCSJ0aXRsZSIsIHRpdGxlLAoJCSJ0byIsIHRvLlN0cmluZygpLAoJCSJ0b2tlblBhdGgiLCB0b2tlblBhdGgsCgkJImFtb3VudCIsIHV0aWxzLkZvcm1hdEludChhbW91bnQpLAoJCSJwcm9wb3NhbElkIiwgdXRpbHMuRm9ybWF0SW50KHByb3Bvc2FsLklEKCkpLAoJCSJxdW9ydW1BbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQocHJvcG9zYWwuVm90aW5nUXVvcnVtQW1vdW50KCkpLAoJCSJtYXhWb3RpbmdXZWlnaHQiLCB1dGlscy5Gb3JtYXRJbnQocHJvcG9zYWwuVm90aW5nTWF4V2VpZ2h0KCkpLAoJCSJjb25maWdWZXJzaW9uIiwgdXRpbHMuRm9ybWF0SW50KHByb3Bvc2FsLkNvbmZpZ1ZlcnNpb24oKSksCgkJImNyZWF0ZWRBdCIsIHV0aWxzLkZvcm1hdEludChwcm9wb3NhbC5DcmVhdGVkQXQoKSksCgkpCgoJcmV0dXJuIHByb3Bvc2FsLklEKCkKfQoKLy8gUHJvcG9zZVBhcmFtZXRlckNoYW5nZSBjcmVhdGVzIGEgcHJvdG9jb2wgcGFyYW1ldGVyIHVwZGF0ZSBwcm9wb3NhbC4KLy8KLy8gTW9kaWZpZXMgc3lzdGVtIHBhcmFtZXRlcnMgdGhyb3VnaCBnb3Zlcm5hbmNlLgovLyBTdXBwb3J0cyBtdWx0aXBsZSBwYXJhbWV0ZXIgY2hhbmdlcyBpbiBzaW5nbGUgcHJvcG9zYWwuCi8vIENoYW5nZXMgYXBwbHkgYXRvbWljYWxseSBvbiBleGVjdXRpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vCi8vICAgLSBfOiBJbnRlcm5hbCBjYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8KLy8gICAtIHJsbTogUHJvcGFnYXRlZCByZWFsbSBjb250ZXh0OyB2YWxpZGF0ZWQgYXMgY3VycmVudCBiZWZvcmUgcHJvcG9zYWwgc3RhdGUgd3JpdGVzLgovLwovLyAgIC0gdGl0bGU6IENsZWFyIGRlc2NyaXB0aW9uIG9mIGNoYW5nZXMKLy8KLy8gICAtIGRlc2NyaXB0aW9uOiBSYXRpb25hbGUgYW5kIGltcGFjdCBhbmFseXNpcwovLwovLyAgIC0gbnVtVG9FeGVjdXRlOiBOdW1iZXIgb2YgcGFyYW1ldGVyIGNoYW5nZXMKLy8KLy8gICAtIGV4ZWN1dGlvbnM6IFJhdyBleGVjdXRpb24gc3RyaW5nIGVuY29kZWQgYXMgbWVzc2FnZXMgc2VwYXJhdGVkIGJ5ICpHT1YqLgovLyAgICAgRWFjaCBtZXNzYWdlIGlzIGZvcm1hdHRlZCBhcyA8cGtnUGF0aD4qRVhFKjxmdW5jdGlvbj4qRVhFKjxwYXJhbXM+LgovLwovLyBFeGFtcGxlIGV4ZWN1dGlvbiBmb3JtYXQgKG9uZSByZWdpc3RlcmVkIGhhbmRsZXI7IGFsbCBzZXZlbiBhcmd1bWVudHMgYXJlIHJlcXVpcmVkKToKLy8KLy8JZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9nb3Zlcm5hbmNlKkVYRSpSZWNvbmZpZ3VyZSpFWEUqODY0MDAsNjA0ODAwLDg2NDAwLDUwLDEwMDAwMDAwMDAsODY0MDAsMjU5MjAwMAovLwovLyBSZXF1aXJlbWVudHM6Ci8vICAgLSBDYWxsZXIgbXVzdCBob2xkIGF0IGxlYXN0IHRoZSBjb25maWd1cmVkIFByb3Bvc2FsQ3JlYXRpb25UaHJlc2hvbGQgYW1vdW50IGluIHhHTlMKLy8gICAtIEVuY29kZWQgZXhlY3V0aW9uIG1lc3NhZ2VzIG11c3QgbWF0Y2ggbnVtVG9FeGVjdXRlCi8vICAgLSBUYXJnZXQgaGFuZGxlcnMgbXVzdCBleGlzdCBpbiB0aGUgcGFyYW1ldGVyIHJlZ2lzdHJ5Ci8vICAgLSBQYXJhbWV0ZXJzIG11c3QgbWF0Y2ggcmVnaXN0ZXJlZCBmdW5jdGlvbiBzaWduYXR1cmVzCi8vCi8vIFJldHVybnM6Ci8vICAgLSBuZXdQcm9wb3NhbElkOiBJRCBvZiB0aGUgbmV3bHkgY3JlYXRlZCBwYXJhbWV0ZXItY2hhbmdlIHByb3Bvc2FsCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIFByb3Bvc2VQYXJhbWV0ZXJDaGFuZ2UoCglfIGludCwgcmxtIHJlYWxtLAoJdGl0bGUgc3RyaW5nLAoJZGVzY3JpcHRpb24gc3RyaW5nLAoJbnVtVG9FeGVjdXRlIGludDY0LAoJZXhlY3V0aW9ucyBzdHJpbmcsCikgKG5ld1Byb3Bvc2FsSWQgaW50NjQpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCXByb3Bvc2FsRGF0YSA6PSBOZXdQcm9wb3NhbEV4ZWN1dGlvbkRhdGEobnVtVG9FeGVjdXRlLCBleGVjdXRpb25zKQoJYXNzZXJ0SXNOb3RIYWx0ZWRHb3Zlcm5hbmNlRm9yUHJvcG9zYWxEYXRhKHByb3Bvc2FsRGF0YSkKCglwcmV2IDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXJBZGRyZXNzIDo9IHByZXYuQWRkcmVzcygpCgoJY3JlYXRlZEF0IDo9IHRpbWUuTm93KCkuVW5peCgpCgljcmVhdGVkSGVpZ2h0IDo9IHJ1bnRpbWUuQ2hhaW5IZWlnaHQoKQoJeGduc0JhbGFuY2UgOj0geGducy5CYWxhbmNlT2YoY2FsbGVyQWRkcmVzcykKCgljb25maWcsIG9rIDo9IGd2LmdldEN1cnJlbnRDb25maWcoKQoJaWYgIW9rIHsKCQlwYW5pYyhlcnJvcnMuTmV3KGVyckRhdGFOb3RGb3VuZCkpCgl9CgoJLy8gQ2xlYW4gdXAgaW5hY3RpdmUgdXNlciBwcm9wb3NhbHMgYmVmb3JlIGNoZWNraW5nIGlmIGNhbGxlciBhbHJlYWR5IGhhcyBhbiBhY3RpdmUgcHJvcG9zYWwKCWVyciA6PSBndi5yZW1vdmVJbmFjdGl2ZVVzZXJQcm9wb3NhbHMoMCwgcmxtLCBjYWxsZXJBZGRyZXNzLCBjcmVhdGVkQXQpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJLy8gQ2hlY2sgaWYgY2FsbGVyIGFscmVhZHkgaGFzIGFuIGFjdGl2ZSBwcm9wb3NhbCAob25lIHByb3Bvc2FsIHBlciBhZGRyZXNzKQoJaWYgZ3YuaGFzQWN0aXZlUHJvcG9zYWwoY2FsbGVyQWRkcmVzcykgewoJCXBhbmljKGVycm9ycy5OZXcoZXJyQWxyZWFkeUFjdGl2ZVByb3Bvc2FsKSkKCX0KCgkvLyBHZXQgdGltZXN0YW1wIGFuY2hvciBhbmQgdG90YWwgdm90aW5nIHdlaWdodCBmb3IgcHJvcG9zYWwgY3JlYXRpb24KCW1heFZvdGluZ1dlaWdodCwgc25hcHNob3RUaW1lLCBlcnIgOj0gZ3YuZ2V0Vm90aW5nV2VpZ2h0U25hcHNob3QoCgkJY3JlYXRlZEF0LAoJCWNvbmZpZy5Wb3RpbmdXZWlnaHRTbW9vdGhpbmdEdXJhdGlvbiwKCSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCXF1b3J1bVdlaWdodCA6PSBndi5zdGFrZXJBY2Nlc3Nvci5HZXRUb3RhbHhHbnNTdXBwbHkoKQoKCS8vIENyZWF0ZSB0aGUgcGFyYW1ldGVyIGNoYW5nZSBwcm9wb3NhbCB3aXRoIGV4ZWN1dGlvbiBkYXRhCglwcm9wb3NhbCwgZXJyIDo9IGd2LmNyZWF0ZVByb3Bvc2FsKAoJCTAsIHJsbSwKCQlnb3Zlcm5hbmNlLlBhcmFtZXRlckNoYW5nZSwKCQljb25maWcsCgkJbWF4Vm90aW5nV2VpZ2h0LAoJCXF1b3J1bVdlaWdodCwKCQlzbmFwc2hvdFRpbWUsCgkJZ292ZXJuYW5jZS5OZXdQcm9wb3NhbE1ldGFkYXRhKHRpdGxlLCBkZXNjcmlwdGlvbiksCgkJcHJvcG9zYWxEYXRhLAoJCWNhbGxlckFkZHJlc3MsCgkJeGduc0JhbGFuY2UsCgkJY3JlYXRlZEF0LAoJCWNyZWF0ZWRIZWlnaHQsCgkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJLy8gSW5pdGlhbGl6ZSBlbXB0eSB2b3RpbmcgaW5mbyB0cmVlIGZvciB0aGlzIHByb3Bvc2FsICh2b3RlcyB3aWxsIGJlIGFkZGVkIGFzIHVzZXJzIHZvdGUpCgllcnIgPSBndi51cGRhdGVQcm9wb3NhbFVzZXJWb3RlcygwLCBybG0sIHByb3Bvc2FsLCBnb3Zlcm5hbmNlLk5ld1Byb3Bvc2FsVXNlclZvdGluZ0luZm9UcmVlKCkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJLy8gRW1pdCBwcm9wb3NhbCBjcmVhdGlvbiBldmVudCBmb3IgaW5kZXhpbmcgYW5kIHRyYWNraW5nCgljaGFpbi5FbWl0KAoJCSJQcm9wb3NlUGFyYW1ldGVyQ2hhbmdlIiwKCQkicHJldkFkZHIiLCBwcmV2LkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldi5Qa2dQYXRoKCksCgkJInRpdGxlIiwgdGl0bGUsCgkJIm51bVRvRXhlY3V0ZSIsIHV0aWxzLkZvcm1hdEludChudW1Ub0V4ZWN1dGUpLAoJCSJwcm9wb3NhbElkIiwgdXRpbHMuRm9ybWF0SW50KHByb3Bvc2FsLklEKCkpLAoJCSJxdW9ydW1BbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQocHJvcG9zYWwuVm90aW5nUXVvcnVtQW1vdW50KCkpLAoJCSJtYXhWb3RpbmdXZWlnaHQiLCB1dGlscy5Gb3JtYXRJbnQocHJvcG9zYWwuVm90aW5nTWF4V2VpZ2h0KCkpLAoJCSJjb25maWdWZXJzaW9uIiwgdXRpbHMuRm9ybWF0SW50KHByb3Bvc2FsLkNvbmZpZ1ZlcnNpb24oKSksCgkJImNyZWF0ZWRBdCIsIHV0aWxzLkZvcm1hdEludChwcm9wb3NhbC5DcmVhdGVkQXQoKSksCgkpCgoJcmV0dXJuIHByb3Bvc2FsLklEKCkKfQoKLy8gY3JlYXRlUHJvcG9zYWwgaGFuZGxlcyBwcm9wb3NhbCBjcmVhdGlvbiBsb2dpYy4KLy8gVmFsaWRhdGVzIGlucHV0IGRhdGEsIGNoZWNrcyBwcm9wb3NlciBlbGlnaWJpbGl0eSwgYW5kIGNyZWF0ZXMgcHJvcG9zYWwgb2JqZWN0LgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSBjcmVhdGVQcm9wb3NhbCgKCV8gaW50LCBybG0gcmVhbG0sCglwcm9wb3NhbFR5cGUgZ292ZXJuYW5jZS5Qcm9wb3NhbFR5cGUsCgljb25maWcgZ292ZXJuYW5jZS5Db25maWcsCgltYXhWb3RpbmdXZWlnaHQgaW50NjQsCglxdW9ydW1XZWlnaHQgaW50NjQsCglzbmFwc2hvdFRpbWUgaW50NjQsCglwcm9wb3NhbE1ldGFkYXRhICpnb3Zlcm5hbmNlLlByb3Bvc2FsTWV0YWRhdGEsCglwcm9wb3NhbERhdGEgKmdvdmVybmFuY2UuUHJvcG9zYWxEYXRhLAoJcHJvcG9zZXJBZGRyZXNzIGFkZHJlc3MsCglwcm9wb3NlclhHbnNCYWxhbmNlIGludDY0LAoJY3JlYXRlZEF0IGludDY0LAoJY3JlYXRlZEhlaWdodCBpbnQ2NCwKKSAoKmdvdmVybmFuY2UuUHJvcG9zYWwsIGVycm9yKSB7CgkvLyBWYWxpZGF0ZSBwcm9wb3NhbCBtZXRhZGF0YSAodGl0bGUgYW5kIGRlc2NyaXB0aW9uKQoJbWV0YWRhdGFSZXNvbHZlciA6PSBOZXdQcm9wb3NhbE1ldGFkYXRhUmVzb2x2ZXIocHJvcG9zYWxNZXRhZGF0YSkKCWVyciA6PSBtZXRhZGF0YVJlc29sdmVyLlZhbGlkYXRlKCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBuaWwsIGVycgoJfQoKCS8vIFZhbGlkYXRlIHByb3Bvc2FsIGRhdGEgKHR5cGUtc3BlY2lmaWMgdmFsaWRhdGlvbikKCWRhdGFSZXNvbHZlciA6PSBOZXdQcm9wb3NhbERhdGFSZXNvbHZlcihwcm9wb3NhbERhdGEpCgllcnIgPSBkYXRhUmVzb2x2ZXIuVmFsaWRhdGUoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIG5pbCwgZXJyCgl9CgoJLy8gQ2hlY2sgaWYgcHJvcG9zZXIgaGFzIGVub3VnaCB4R05TIGJhbGFuY2UgdG8gY3JlYXRlIHByb3Bvc2FsCglpZiBwcm9wb3NlclhHbnNCYWxhbmNlIDwgY29uZmlnLlByb3Bvc2FsQ3JlYXRpb25UaHJlc2hvbGQgewoJCXJldHVybiBuaWwsIGVycm9ycy5OZXcoZXJyTm90RW5vdWdoQmFsYW5jZSkKCX0KCgkvLyBHZW5lcmF0ZSB1bmlxdWUgcHJvcG9zYWwgSUQKCXByb3Bvc2FsSUQgOj0gZ3YubmV4dFByb3Bvc2FsSUQoMCwgcmxtKQoKCS8vIENyZWF0ZSBwcm9wb3NhbCBzdGF0dXMgd2l0aCB2b3Rpbmcgc2NoZWR1bGUgYW5kIHJlcXVpcmVtZW50cwoJcHJvcG9zYWxTdGF0dXMgOj0gTmV3UHJvcG9zYWxTdGF0dXMoCgkJY29uZmlnLAoJCW1heFZvdGluZ1dlaWdodCwKCQlwcm9wb3NhbFR5cGUuSXNFeGVjdXRhYmxlKCksCgkJY3JlYXRlZEF0LAoJCXF1b3J1bVdlaWdodCwKCSkKCgkvLyBHZXQgY3VycmVudCBjb25maWd1cmF0aW9uIHZlcnNpb24gZm9yIHRyYWNraW5nCgljb25maWdWZXJzaW9uIDo9IGd2LmdldEN1cnJlbnRDb25maWdWZXJzaW9uKCkKCgkvLyBDcmVhdGUgdGhlIHByb3Bvc2FsIG9iamVjdCB3aXRoIGEgdGltZXN0YW1wIGFuY2hvciBmb3IgbGF6eSB2b3Rpbmctd2VpZ2h0IGxvb2t1cAoJcHJvcG9zYWwgOj0gZ292ZXJuYW5jZS5OZXdQcm9wb3NhbCgKCQlwcm9wb3NhbElELAoJCXByb3Bvc2FsU3RhdHVzLAoJCXByb3Bvc2FsTWV0YWRhdGEsCgkJcHJvcG9zYWxEYXRhLAoJCXByb3Bvc2VyQWRkcmVzcywKCQljb25maWdWZXJzaW9uLAoJCXNuYXBzaG90VGltZSwKCQljcmVhdGVkSGVpZ2h0LAoJKQoKCS8vIFN0b3JlIHRoZSBwcm9wb3NhbCBpbiBzdGF0ZQoJc3VjY2VzcyA6PSBndi5hZGRQcm9wb3NhbCgwLCBybG0sIHByb3Bvc2FsKQoJaWYgIXN1Y2Nlc3MgewoJCXJldHVybiBuaWwsIGVycm9ycy5OZXcoZXJyRGF0YU5vdEZvdW5kKQoJfQoKCXJldHVybiBwcm9wb3NhbCwgbmlsCn0KCi8vIGdldFZvdGluZ1dlaWdodFNuYXBzaG90IHJldHJpZXZlcyB0aGUgYXZlcmFnZWQgdG90YWwgdm90aW5nIHdlaWdodCBmb3IgcHJvcG9zYWwgY3JlYXRpb24uCi8vIEl0IHVzZXMgdHdvIHNuYXBzaG90cyAoY3VycmVudCBhbmQgY3VycmVudCAtIHNtb290aGluZ1BlcmlvZCkgYW5kIGF2ZXJhZ2VzIHRoZW0uCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIGdldFZvdGluZ1dlaWdodFNuYXBzaG90KAoJY3VycmVudCwKCXNtb290aGluZ1BlcmlvZCBpbnQ2NCwKKSAoaW50NjQsIGludDY0LCBlcnJvcikgewoJLy8gQ2FsY3VsYXRlIHRoZSBlYXJsaWVyIHRpbWVzdGFtcCBieSBzdWJ0cmFjdGluZyB0aGUgc21vb3RoaW5nIGR1cmF0aW9uCglzbmFwc2hvdFRpbWUgOj0gY3VycmVudCAtIHNtb290aGluZ1BlcmlvZAoJaWYgc25hcHNob3RUaW1lIDwgMCB7CgkJc25hcHNob3RUaW1lID0gMAoJfQoKCS8vIEdldCB0b3RhbCBkZWxlZ2F0aW9uIGF0IHRoZSBlYXJsaWVyIHRpbWVzdGFtcCBmcm9tIHN0YWtlciBoaXN0b3J5Cgl0b3RhbEF0U25hcHNob3QsIG9rIDo9IGd2LnN0YWtlckFjY2Vzc29yLkdldFRvdGFsRGVsZWdhdGlvbkFtb3VudEF0U25hcHNob3Qoc25hcHNob3RUaW1lKQoJaWYgIW9rIHsKCQl0b3RhbEF0U25hcHNob3QgPSAwCgl9CgoJdG90YWxBdEN1cnJlbnQsIG9rIDo9IGd2LnN0YWtlckFjY2Vzc29yLkdldFRvdGFsRGVsZWdhdGlvbkFtb3VudEF0U25hcHNob3QoY3VycmVudCkKCWlmICFvayB7CgkJdG90YWxBdEN1cnJlbnQgPSAwCgl9CgoJdG90YWxWb3RpbmdXZWlnaHQgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQodG90YWxBdFNuYXBzaG90LCB0b3RhbEF0Q3VycmVudCkgLyAyCglpZiB0b3RhbFZvdGluZ1dlaWdodCA8PSAwIHsKCQlyZXR1cm4gMCwgc25hcHNob3RUaW1lLCBlcnJvcnMuTmV3KGVyck5vdEVub3VnaFZvdGluZ1dlaWdodCkKCX0KCglyZXR1cm4gdG90YWxWb3RpbmdXZWlnaHQsIHNuYXBzaG90VGltZSwgbmlsCn0KGrwoChNnb3Zlcm5hbmNlX3ZvdGUuZ25vEqQocGFja2FnZSBnb3Zlcm5hbmNlCgppbXBvcnQgKAoJImNoYWluIgoJImNoYWluL3J1bnRpbWUiCgkidGltZSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKCglnbnNtYXRoICJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCSJnbm8ubGFuZC9wL2dub3N3YXAvdXRpbHMvdjEiCgoJImduby5sYW5kL3IvZ25vc3dhcC9lbWlzc2lvbiIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9nb3Zlcm5hbmNlIgopCgovLyBWb3RlIGNhc3RzIGEgdm90ZSBvbiBhIHByb3Bvc2FsLgovLwovLyBSZWNvcmRzIGFuIG9uLWNoYWluIHZvdGUgd2l0aCB3ZWlnaHQgYmFzZWQgb24gZGVsZWdhdGVkIHhHTlMuCi8vIFVzZXMgdGhlIHByb3Bvc2FsJ3MgdGltZXN0YW1wIGFuY2hvcnMgYW5kIGNvbmZpZ3VyZWQgc21vb3RoaW5nIGR1cmF0aW9uIHRvCi8vIHByZXZlbnQgbWFuaXB1bGF0aW9uLiBWb3RlcyBhcmUgZmluYWwgYW5kIGNhbm5vdCBiZSBjaGFuZ2VkLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogbGVhZGluZyByZWFsbS1jYWxsIGRpc2NyaW1pbmF0b3I7IGNhbGxlcnMgcGFzcyAwIHdoaWxlIHRocmVhZGluZyB0aGUgcmVhbG0gY29udGV4dAovLyAgIC0gcmxtOiBjdXJyZW50IHJlYWxtIGNvbnRleHQ7IGltcGxlbWVudGF0aW9uIHZhbGlkYXRlcyBpdCBiZWZvcmUgcmVhZGluZyBvciB3cml0aW5nIGdvdmVybmFuY2Ugc3RhdGUKLy8gICAtIHByb3Bvc2FsSUQ6IElEIG9mIHRoZSBwcm9wb3NhbCB0byB2b3RlIG9uCi8vICAgLSB5ZXM6IHRydWUgZm9yIHllcyB2b3RlLCBmYWxzZSBmb3Igbm8gdm90ZQovLwovLyBWb3RlIFdlaWdodCBDYWxjdWxhdGlvbjoKLy8gICAtIEJhc2VkIG9uIHRoZSB2b3RlcidzIGRlbGVnYXRlZCB4R05TIGFtb3VudAovLyAgIC0gQXZlcmFnZXMgZGVsZWdhdGlvbiBhdCB0aGUgc3RvcmVkIHNtb290aGluZyB0aW1lc3RhbXAgYW5kIHByb3Bvc2FsIGNyZWF0aW9uIHRpbWUKLy8gICAtIFVzZXMgVW5peCB0aW1lc3RhbXAgaGlzdG9yeSwgbm90IGEgYmxvY2staGVpZ2h0IHNuYXBzaG90Ci8vICAgLSBJbmNsdWRlcyBzZWxmLWRlbGVnYXRpb24gYW5kIGRlbGVnYXRpb25zIHJlY2VpdmVkIGJ5IHRoZSB2b3RlcgovLwovLyBSZXF1aXJlbWVudHM6Ci8vICAgLSBQcm9wb3NhbCBtdXN0IGJlIGluIHZvdGluZyBwZXJpb2QKLy8gICAtIFZvdGVyIG11c3QgaGF2ZSB4R05TIGRlbGVnYXRlZCBhdCBvbmUgb2YgdGhlIGxvb2t1cCB0aW1lc3RhbXBzCi8vICAgLSBDYW5ub3Qgdm90ZSB0d2ljZSBvbiBzYW1lIHByb3Bvc2FsCi8vICAgLSBWb3RpbmcgcGVyaW9kIGlzIDcgZGF5cyBieSBkZWZhdWx0IGFuZCBpcyBjb25maWd1cmFibGUKLy8KLy8gUmV0dXJuczoKLy8gICAtIHZvdGVXZWlnaHQ6IHZvdGluZyB3ZWlnaHQgYXBwbGllZCB0byB0aGUgY2FsbGVyJ3Mgdm90ZSwgZm9ybWF0dGVkIGFzIGEgc3RyaW5nCmZ1bmMgKGd2ICpnb3Zlcm5hbmNlVjEpIFZvdGUoXyBpbnQsIHJsbSByZWFsbSwgcHJvcG9zYWxJRCBpbnQ2NCwgeWVzIGJvb2wpIHN0cmluZyB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCglhc3NlcnRJc05vdEhhbHRlZEdvdmVybmFuY2VGb3JQcm9wb3NhbChndiwgcHJvcG9zYWxJRCkKCgkvLyBHZXQgY3VycmVudCBibG9ja2NoYWluIHN0YXRlIGFuZCBjYWxsZXIgaW5mb3JtYXRpb24KCWN1cnJlbnRIZWlnaHQgOj0gcnVudGltZS5DaGFpbkhlaWdodCgpCgljdXJyZW50QXQgOj0gdGltZS5Ob3coKQoKCS8vIE1pbnQgYW5kIGRpc3RyaWJ1dGUgR05TIHRva2VucyBhcyBwYXJ0IG9mIHRoZSB2b3RpbmcgcHJvY2VzcwoJZW1pc3Npb24uTWludEFuZERpc3RyaWJ1dGVHbnMoY3Jvc3MocmxtKSkKCgkvLyBFeHRyYWN0IHZvdGVyIGFkZHJlc3MgZnJvbSByZWFsbSBjb250ZXh0Cgl2b3RlclJlYWxtIDo9IHJsbS5QcmV2aW91cygpCgl2b3RlciA6PSB2b3RlclJlYWxtLkFkZHJlc3MoKQoKCS8vIFByb2Nlc3MgdGhlIHZvdGUgYW5kIGdldCB1cGRhdGVkIHZvdGUgdGFsbGllcwoJdXNlclZvdGUsIHRvdGFsWWVzVm90ZVdlaWdodCwgdG90YWxOb1ZvdGVXZWlnaHQsIGVyciA6PSBndi52b3RlKAoJCTAsIHJsbSwKCQlwcm9wb3NhbElELAoJCXZvdGVyLAoJCXllcywKCQljdXJyZW50SGVpZ2h0LAoJCWN1cnJlbnRBdC5Vbml4KCksCgkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJLy8gRW1pdCB2b3RpbmcgZXZlbnQgZm9yIHRyYWNraW5nIGFuZCB0cmFuc3BhcmVuY3kKCXZvdGVXZWlnaHQgOj0gdXRpbHMuRm9ybWF0SW50KHVzZXJWb3RlLlZvdGVkV2VpZ2h0KCkpCgl2b3RlclN0ciA6PSB2b3Rlci5TdHJpbmcoKQoKCWNoYWluLkVtaXQoCgkJIlZvdGUiLAoJCSJwcmV2QWRkciIsIHZvdGVyU3RyLAoJCSJwcmV2UGtnUGF0aCIsIHZvdGVyUmVhbG0uUGtnUGF0aCgpLAoJCSJwcm9wb3NhbElkIiwgdXRpbHMuRm9ybWF0SW50KHByb3Bvc2FsSUQpLAoJCSJ2b3RlciIsIHZvdGVyU3RyLAoJCSJ5ZXMiLCB1c2VyVm90ZS5Wb3RpbmdUeXBlKCksCgkJInZvdGVXZWlnaHQiLCB2b3RlV2VpZ2h0LAoJCSJ2b3RlWWVzIiwgdXRpbHMuRm9ybWF0SW50KHRvdGFsWWVzVm90ZVdlaWdodCksCgkJInZvdGVObyIsIHV0aWxzLkZvcm1hdEludCh0b3RhbE5vVm90ZVdlaWdodCksCgkpCgoJcmV0dXJuIHZvdGVXZWlnaHQKfQoKLy8gdm90ZSBoYW5kbGVzIGNvcmUgdm90aW5nIGxvZ2ljLgpmdW5jIChndiAqZ292ZXJuYW5jZVYxKSB2b3RlKAoJXyBpbnQsIHJsbSByZWFsbSwKCXByb3Bvc2FsSUQgaW50NjQsCgl2b3RlckFkZHJlc3MgYWRkcmVzcywKCXZvdGVkWWVzIGJvb2wsCgl2b3RlZEhlaWdodCwKCXZvdGVkQXQgaW50NjQsCikgKGdvdmVybmFuY2UuVm90aW5nSW5mbywgaW50NjQsIGludDY0LCBlcnJvcikgewoJLy8gUmV0cmlldmUgdGhlIHByb3Bvc2FsIGZyb20gc3RvcmFnZQoJcHJvcG9zYWwsIG9rIDo9IGd2LmdldFByb3Bvc2FsKHByb3Bvc2FsSUQpCglpZiAhb2sgewoJCXJldHVybiBnb3Zlcm5hbmNlLkRlZmF1bHRWb3RpbmdJbmZvKCksIDAsIDAsIG1ha2VFcnJvcldpdGhEZXRhaWxzKGVyckRhdGFOb3RGb3VuZCwgIm5vdCBmb3VuZCBwcm9wb3NhbCIpCgl9CgoJcHJvcG9zYWxSZXNvbHZlciA6PSBOZXdQcm9wb3NhbFJlc29sdmVyKHByb3Bvc2FsKQoKCS8vIENoZWNrIGlmIGN1cnJlbnQgdGltZSBpcyB3aXRoaW4gdm90aW5nIHBlcmlvZAoJaWYgIXByb3Bvc2FsUmVzb2x2ZXIuSXNWb3RpbmdQZXJpb2Qodm90ZWRBdCkgewoJCXJldHVybiBnb3Zlcm5hbmNlLkRlZmF1bHRWb3RpbmdJbmZvKCksIDAsIDAsIG1ha2VFcnJvcldpdGhEZXRhaWxzKGVyclVuYWJsZVRvVm90ZU91dE9mUGVyaW9kLCAiY2Fubm90IHZvdGUgb3V0IG9mIHZvdGluZyBwZXJpb2QiKQoJfQoKCS8vIEdldCB1c2VyJ3Mgdm90aW5nIHdlaWdodCBieSBhdmVyYWdpbmcgdGltZXN0YW1wLWhpc3RvcnkgdmFsdWVzIGF0IHRoZQoJLy8gcHJvcG9zYWwncyBzdG9yZWQgc21vb3RoaW5nIGFuY2hvciBhbmQgY3JlYXRpb24gdGltZS4KCXNuYXBzaG90VGltZSA6PSBwcm9wb3NhbC5TbmFwc2hvdFRpbWUoKQoJY3JlYXRlZEF0IDo9IHByb3Bvc2FsLkNyZWF0ZWRBdCgpCgoJd2VpZ2h0QXRTbmFwc2hvdCwgb2sgOj0gZ3Yuc3Rha2VyQWNjZXNzb3IuR2V0VXNlckRlbGVnYXRpb25BbW91bnRBdFNuYXBzaG90KHZvdGVyQWRkcmVzcywgc25hcHNob3RUaW1lKQoJaWYgIW9rIHsKCQl3ZWlnaHRBdFNuYXBzaG90ID0gMAoJfQoKCXdlaWdodEF0Q3JlYXRlZCwgb2sgOj0gZ3Yuc3Rha2VyQWNjZXNzb3IuR2V0VXNlckRlbGVnYXRpb25BbW91bnRBdFNuYXBzaG90KHZvdGVyQWRkcmVzcywgY3JlYXRlZEF0KQoJaWYgIW9rIHsKCQl3ZWlnaHRBdENyZWF0ZWQgPSAwCgl9CgoJdm90aW5nV2VpZ2h0IDo9IGduc21hdGguU2FmZUFkZEludDY0KHdlaWdodEF0U25hcHNob3QsIHdlaWdodEF0Q3JlYXRlZCkgLyAyCglpZiB2b3RpbmdXZWlnaHQgPD0gMCB7CgkJcmV0dXJuIGdvdmVybmFuY2UuRGVmYXVsdFZvdGluZ0luZm8oKSwgMCwgMCwgbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyck5vdEVub3VnaFZvdGluZ1dlaWdodCwgIm5vIHZvdGluZyB3ZWlnaHQgYXQgc25hcHNob3QgdGltZSIpCgl9CgoJdXNlclZvdGUsIGV4aXN0cyA6PSBndi5nZXRQcm9wb3NhbFVzZXJWb3RpbmdJbmZvKHByb3Bvc2FsSUQsIHZvdGVyQWRkcmVzcykKCWlmICFleGlzdHMgewoJCXVzZXJWb3RlID0gZ292ZXJuYW5jZS5OZXdWb3RpbmdJbmZvKHZvdGluZ1dlaWdodCkKCX0KCglpZiB1c2VyVm90ZS5Jc1ZvdGVkKCkgewoJCXJldHVybiBnb3Zlcm5hbmNlLkRlZmF1bHRWb3RpbmdJbmZvKCksIDAsIDAsIG1ha2VFcnJvcldpdGhEZXRhaWxzKGVyckFscmVhZHlWb3RlZCwgInVzZXIgaGFzIGFscmVhZHkgdm90ZWQiKQoJfQoJdXNlclZvdGUgPSBnb3Zlcm5hbmNlLk5ld1ZvdGVkVm90aW5nSW5mbyh2b3RpbmdXZWlnaHQsIHZvdGVkWWVzLCB2b3RpbmdXZWlnaHQsIHZvdGVkSGVpZ2h0LCB2b3RlZEF0KQoKCXZvdGluZ0luZm9zVHJlZSwgXyA6PSBndi5nZXRQcm9wb3NhbFVzZXJWb3RpbmdJbmZvcyhwcm9wb3NhbElEKQoJaWYgdm90aW5nSW5mb3NUcmVlID09IG5pbCB7CgkJcmV0dXJuIGdvdmVybmFuY2UuRGVmYXVsdFZvdGluZ0luZm8oKSwgMCwgMCwgbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckRhdGFOb3RGb3VuZCwgInZvdGluZyBpbmZvcyB0cmVlIG5vdCBmb3VuZCBmb3IgcHJvcG9zYWwiKQoJfQoKCXZvdGluZ0luZm9zVHJlZS5TZXQodm90ZXJBZGRyZXNzLlN0cmluZygpLCB1c2VyVm90ZSkKCWVyciA6PSBndi5zdG9yZS5TZXRQcm9wb3NhbFZvdGluZ0luZm9zKDAsIHJsbSwgcHJvcG9zYWxJRCwgdm90aW5nSW5mb3NUcmVlKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGdvdmVybmFuY2UuRGVmYXVsdFZvdGluZ0luZm8oKSwgMCwgMCwgZXJyCgl9CgoJLy8gVXBkYXRlIHByb3Bvc2FsIHZvdGUgdGFsbGllcwoJZXJyID0gcHJvcG9zYWxSZXNvbHZlci5Wb3RlKHZvdGVkWWVzLCB2b3RpbmdXZWlnaHQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZ292ZXJuYW5jZS5EZWZhdWx0Vm90aW5nSW5mbygpLCAwLCAwLCBlcnIKCX0KCglyZXR1cm4gdXNlclZvdGUsIHByb3Bvc2FsLlZvdGluZ1llc1dlaWdodCgpLCBwcm9wb3NhbC5Wb3RpbmdOb1dlaWdodCgpLCBuaWwKfQoauBQKCGluaXQuZ25vEqsUcGFja2FnZSBnb3Zlcm5hbmNlCgppbXBvcnQgKAoJInN0cmNvbnYiCgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3YvZ292ZXJuYW5jZSIKKQoKZnVuYyBpbml0KGN1ciByZWFsbSkgewoJcmVnaXN0ZXJHb3Zlcm5hbmNlVjEoY3VyKQp9CgpmdW5jIHJlZ2lzdGVyR292ZXJuYW5jZVYxKGN1ciByZWFsbSkgewoJZ292ZXJuYW5jZS5SZWdpc3RlckluaXRpYWxpemVyKGNyb3NzKGN1ciksIGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgZ292ZXJuYW5jZVN0b3JlIGdvdmVybmFuY2UuSUdvdmVybmFuY2VTdG9yZSwgc3Rha2VyQWNjZXNzb3IgZ292ZXJuYW5jZS5Hb3ZTdGFrZXJBY2Nlc3NvcikgZ292ZXJuYW5jZS5JR292ZXJuYW5jZSB7CgkJLy8gYHJsbWAgaGVyZSBpcyB0aGUgZ292ZXJuYW5jZSBwcm94eSByZWFsbSB0aHJlYWRlZCBpbiBieQoJCS8vIGdvdmVybmFuY2UuUmVnaXN0ZXJJbml0aWFsaXplci4gUGVyLXZlcnNpb24gc3RvcmUgYm9vdHN0cmFwCgkJLy8gd3JpdGVzIHRoZXJlZm9yZSBwYXNzIHRoZSBwcm94eSdzIEtWLXN0b3JlIEFDTC4KCQllcnIgOj0gaW5pdFN0b3JlRGF0YSgwLCBybG0sIGdvdmVybmFuY2VTdG9yZSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcGFuaWMoZXJyKQoJCX0KCgkJcmV0dXJuIE5ld0dvdmVybmFuY2VWMShnb3Zlcm5hbmNlU3RvcmUsIHN0YWtlckFjY2Vzc29yKQoJfSkKfQoKZnVuYyBpbml0U3RvcmVEYXRhKF8gaW50LCBybG0gcmVhbG0sIGdvdmVybmFuY2VTdG9yZSBnb3Zlcm5hbmNlLklHb3Zlcm5hbmNlU3RvcmUpIGVycm9yIHsKCS8vIEluaXRpYWxpemUgY291bnRlcnMgaWYgbm90IGFscmVhZHkgc2V0CglpZiAhZ292ZXJuYW5jZVN0b3JlLkhhc0NvbmZpZ0NvdW50ZXJTdG9yZUtleSgpIHsKCQllcnIgOj0gZ292ZXJuYW5jZVN0b3JlLlNldENvbmZpZ0NvdW50ZXIoMCwgcmxtLCBnb3Zlcm5hbmNlLk5ld0NvdW50ZXIoKSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCglpZiAhZ292ZXJuYW5jZVN0b3JlLkhhc1Byb3Bvc2FsQ291bnRlclN0b3JlS2V5KCkgewoJCWVyciA6PSBnb3Zlcm5hbmNlU3RvcmUuU2V0UHJvcG9zYWxDb3VudGVyKDAsIHJsbSwgZ292ZXJuYW5jZS5OZXdDb3VudGVyKCkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJLy8gSW5pdGlhbGl6ZSBDb25maWdzIHdpdGggZGVmYXVsdCBjb25maWd1cmF0aW9uIGlmIG5vdCBhbHJlYWR5IHNldAoJaWYgIWdvdmVybmFuY2VTdG9yZS5IYXNDb25maWdzU3RvcmVLZXkoKSB7CgkJY29uZmlncyA6PSBnb3Zlcm5hbmNlLk5ld0NvbmZpZ1RyZWUoKQoJCWNvdW50ZXIgOj0gZ292ZXJuYW5jZVN0b3JlLkdldENvbmZpZ0NvdW50ZXIoKQoJCW5leHRDb25maWdWZXJzaW9uIDo9IGNvdW50ZXIuTmV4dCgpCgoJCWNvbmZpZ3MuU2V0KGZvcm1hdENvbmZpZ0tleShuZXh0Q29uZmlnVmVyc2lvbiksIGdvdmVybmFuY2UuTmV3RGVmYXVsdENvbmZpZygpKQoKCQllcnIgOj0gZ292ZXJuYW5jZVN0b3JlLlNldENvbmZpZ3MoMCwgcmxtLCBjb25maWdzKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJCS8vIFBlcnNpc3QgdGhlIG11dGF0ZWQgY291bnRlciBzbyB0aGUgYnVtcGVkIHZlcnNpb24gc3Vydml2ZXMgdGhlCgkJLy8gYm91bmRhcnkgaW50byB0aGUgcHJveHkncyBLViBzdG9yZS4KCQlpZiBlcnIgOj0gZ292ZXJuYW5jZVN0b3JlLlNldENvbmZpZ0NvdW50ZXIoMCwgcmxtLCBjb3VudGVyKTsgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJaWYgIWdvdmVybmFuY2VTdG9yZS5IYXNQcm9wb3NhbHNTdG9yZUtleSgpIHsKCQllcnIgOj0gZ292ZXJuYW5jZVN0b3JlLlNldFByb3Bvc2FscygwLCBybG0sIGdvdmVybmFuY2UuTmV3UHJvcG9zYWxUcmVlKCkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJaWYgIWdvdmVybmFuY2VTdG9yZS5IYXNBY3RpdmVQcm9wb3NhbHNCeVNuYXBzaG90U3RvcmVLZXkoKSB7CgkJaWYgZXJyIDo9IGdvdmVybmFuY2VTdG9yZS5TZXRBY3RpdmVQcm9wb3NhbHNCeVNuYXBzaG90KDAsIHJsbSwgZ292ZXJuYW5jZS5OZXdQcm9wb3NhbFRyZWUoKSk7IGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFnb3Zlcm5hbmNlU3RvcmUuSGFzUHJvcG9zYWxVc2VyVm90aW5nSW5mb3NTdG9yZUtleSgpIHsKCQllcnIgOj0gZ292ZXJuYW5jZVN0b3JlLlNldFByb3Bvc2FsVXNlclZvdGluZ0luZm9zKDAsIHJsbSwgZ292ZXJuYW5jZS5OZXdQcm9wb3NhbFVzZXJWb3RpbmdJbmZvVHJlZSgpKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFnb3Zlcm5hbmNlU3RvcmUuSGFzVXNlclByb3Bvc2Fsc1N0b3JlS2V5KCkgewoJCWVyciA6PSBnb3Zlcm5hbmNlU3RvcmUuU2V0VXNlclByb3Bvc2FscygwLCBybG0sIGdvdmVybmFuY2UuTmV3VXNlclByb3Bvc2FsVHJlZSgpKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCXJldHVybiBuaWwKfQoKZnVuYyBmb3JtYXRDb25maWdLZXkodmVyc2lvbiBpbnQ2NCkgc3RyaW5nIHsKCXJldHVybiBzdHJjb252LkZvcm1hdEludCh2ZXJzaW9uLCAxMCkKfQoalDMKDGluc3RhbmNlLmdubxKDM3BhY2thZ2UgZ292ZXJuYW5jZQoKaW1wb3J0ICgKCSJnbm8ubGFuZC9wL2dub3N3YXAvdXRpbHMvdjEiCglicHRyZWUgImduby5sYW5kL3AvbnQvYnB0cmVlL3YwIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3YvZ292ZXJuYW5jZSIKKQoKdHlwZSBnb3Zlcm5hbmNlVjEgc3RydWN0IHsKCXN0b3JlICAgICAgICAgIGdvdmVybmFuY2UuSUdvdmVybmFuY2VTdG9yZQoJc3Rha2VyQWNjZXNzb3IgZ292ZXJuYW5jZS5Hb3ZTdGFrZXJBY2Nlc3Nvcgp9CgovLyBOZXdHb3Zlcm5hbmNlVjEgY3JlYXRlcyBhIGdvdmVybmFuY2UgdjEgaW1wbGVtZW50YXRpb24gYmFja2VkIGJ5IHRoZSBzdXBwbGllZAovLyBzdGF0ZSBzdG9yZSBhbmQgc3Rha2VyIHZvdGluZy13ZWlnaHQgYWNjZXNzb3IuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBnb3Zlcm5hbmNlU3RvcmU6IHBlcnNpc3RlbmNlIGFkYXB0ZXIgZm9yIGNvbmZpZ3VyYXRpb24sIHByb3Bvc2FscywgY291bnRlcnMsIGFuZCB2b3RpbmcgaW5mb3JtYXRpb24KLy8gICAtIHN0YWtlckFjY2Vzc29yOiBhY2Nlc3NvciB0aGF0IHN1cHBsaWVzIGRlbGVnYXRpb24gc25hcHNob3RzIGFuZCB0b3RhbCB4R05TIHN1cHBseSBmb3IgZ292ZXJuYW5jZSBkZWNpc2lvbnMKLy8KLy8gUmV0dXJuczoKLy8gICAtIGdvdmVybmFuY2UuSUdvdmVybmFuY2U6IGdvdmVybmFuY2UgbWFuYWdlciBhbmQgZ2V0dGVyIGltcGxlbWVudGF0aW9uIHVzaW5nIHRoZSBzdXBwbGllZCBkZXBlbmRlbmNpZXMKZnVuYyBOZXdHb3Zlcm5hbmNlVjEoCglnb3Zlcm5hbmNlU3RvcmUgZ292ZXJuYW5jZS5JR292ZXJuYW5jZVN0b3JlLAoJc3Rha2VyQWNjZXNzb3IgZ292ZXJuYW5jZS5Hb3ZTdGFrZXJBY2Nlc3NvciwKKSBnb3Zlcm5hbmNlLklHb3Zlcm5hbmNlIHsKCXJldHVybiAmZ292ZXJuYW5jZVYxewoJCXN0b3JlOiAgICAgICAgICBnb3Zlcm5hbmNlU3RvcmUsCgkJc3Rha2VyQWNjZXNzb3I6IHN0YWtlckFjY2Vzc29yLAoJfQp9CgovLyBDb25maWcgdmVyc2lvbiBtZXRob2RzCmZ1bmMgKGcgKmdvdmVybmFuY2VWMSkgZ2V0Q3VycmVudENvbmZpZ1ZlcnNpb24oKSBpbnQ2NCB7CglyZXR1cm4gZy5zdG9yZS5HZXRDb25maWdDb3VudGVyKCkuR2V0KCkKfQoKLy8gbmV4dENvbmZpZ1ZlcnNpb24gaW5jcmVtZW50cyBhbmQgcGVyc2lzdHMgdGhlIGNvbmZpZyBjb3VudGVyLiBJdCBtdXRhdGVzIHRoZQovLyB1bmRlcmx5aW5nIEtWIHN0b3JlLCBzbyBpdCByZXF1aXJlcyBhIHJlYWxtIHZhbHVlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlCi8vIGdvdmVybmFuY2UgcHJveHkgcmVhbG0gKHRoZSBvbmx5IHdyaXRlci1wZXJtaXR0ZWQgYWRkcmVzcykuCmZ1bmMgKGcgKmdvdmVybmFuY2VWMSkgbmV4dENvbmZpZ1ZlcnNpb24oXyBpbnQsIHJsbSByZWFsbSkgaW50NjQgewoJY291bnRlciA6PSBnLnN0b3JlLkdldENvbmZpZ0NvdW50ZXIoKQoJbmV4dCA6PSBjb3VudGVyLk5leHQoKQoJaWYgZXJyIDo9IGcuc3RvcmUuU2V0Q29uZmlnQ291bnRlcigwLCBybG0sIGNvdW50ZXIpOyBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CglyZXR1cm4gbmV4dAp9CgovLyBQcm9wb3NhbCBJRCBtZXRob2RzCmZ1bmMgKGcgKmdvdmVybmFuY2VWMSkgZ2V0Q3VycmVudFByb3Bvc2FsSUQoKSBpbnQ2NCB7CglyZXR1cm4gZy5zdG9yZS5HZXRQcm9wb3NhbENvdW50ZXIoKS5HZXQoKQp9CgovLyBuZXh0UHJvcG9zYWxJRCBpbmNyZW1lbnRzIGFuZCBwZXJzaXN0cyB0aGUgcHJvcG9zYWwgY291bnRlci4gU2FtZSByZWFsbQovLyBydWxlcyBhcyBuZXh0Q29uZmlnVmVyc2lvbi4KZnVuYyAoZyAqZ292ZXJuYW5jZVYxKSBuZXh0UHJvcG9zYWxJRChfIGludCwgcmxtIHJlYWxtKSBpbnQ2NCB7Cgljb3VudGVyIDo9IGcuc3RvcmUuR2V0UHJvcG9zYWxDb3VudGVyKCkKCW5leHQgOj0gY291bnRlci5OZXh0KCkKCWlmIGVyciA6PSBnLnN0b3JlLlNldFByb3Bvc2FsQ291bnRlcigwLCBybG0sIGNvdW50ZXIpOyBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CglyZXR1cm4gbmV4dAp9CgovLyBDb25maWcgbWV0aG9kcwpmdW5jIChnICpnb3Zlcm5hbmNlVjEpIGdldENvbmZpZyh2ZXJzaW9uIGludDY0KSAoZ292ZXJuYW5jZS5Db25maWcsIGJvb2wpIHsKCXJldHVybiBnLnN0b3JlLkdldENvbmZpZyh2ZXJzaW9uKQp9CgpmdW5jIChnICpnb3Zlcm5hbmNlVjEpIHNldENvbmZpZyhfIGludCwgcmxtIHJlYWxtLCB2ZXJzaW9uIGludDY0LCBjb25maWcgZ292ZXJuYW5jZS5Db25maWcpIGVycm9yIHsKCXJldHVybiBnLnN0b3JlLlNldENvbmZpZygwLCBybG0sIHZlcnNpb24sIGNvbmZpZykKfQoKZnVuYyAoZyAqZ292ZXJuYW5jZVYxKSBnZXRDdXJyZW50Q29uZmlnKCkgKGdvdmVybmFuY2UuQ29uZmlnLCBib29sKSB7CglyZXR1cm4gZy5nZXRDb25maWcoZy5nZXRDdXJyZW50Q29uZmlnVmVyc2lvbigpKQp9CgovLyBQcm9wb3NhbCBtZXRob2RzCmZ1bmMgKGcgKmdvdmVybmFuY2VWMSkgZ2V0UHJvcG9zYWwoaWQgaW50NjQpICgqZ292ZXJuYW5jZS5Qcm9wb3NhbCwgYm9vbCkgewoJcHJvcG9zYWwsIGV4aXN0cyA6PSBnLnN0b3JlLkdldFByb3Bvc2FsKGlkKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuIG5pbCwgZmFsc2UKCX0KCglyZXR1cm4gcHJvcG9zYWwsIHRydWUKfQoKZnVuYyBhY3RpdmVQcm9wb3NhbFNuYXBzaG90S2V5KHByb3Bvc2FsICpnb3Zlcm5hbmNlLlByb3Bvc2FsKSBzdHJpbmcgewoJcmV0dXJuIHV0aWxzLkVuY29kZVVpbnQ2NCh1aW50NjQocHJvcG9zYWwuU25hcHNob3RUaW1lKCkpKSArIHV0aWxzLkVuY29kZVVpbnQ2NCh1aW50NjQocHJvcG9zYWwuSUQoKSkpCn0KCmZ1bmMgKGcgKmdvdmVybmFuY2VWMSkgYWRkUHJvcG9zYWwoXyBpbnQsIHJsbSByZWFsbSwgcHJvcG9zYWwgKmdvdmVybmFuY2UuUHJvcG9zYWwpIGJvb2wgewoJLy8gU2V0IHRoZSBwcm9wb3NhbCAoSUQgYWxyZWFkeSBzZXQgaW4gcHJvcG9zYWwpCgllcnIgOj0gZy5zdG9yZS5TZXRQcm9wb3NhbCgwLCBybG0sIHByb3Bvc2FsLklEKCksIHByb3Bvc2FsKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGZhbHNlCgl9CgoJLy8gQWRkIHRvIHRoZSBhY3RpdmUgc25hcHNob3QgaW5kZXguCglzbmFwc2hvdEluZGV4IDo9IGcuc3RvcmUuR2V0QWN0aXZlUHJvcG9zYWxzQnlTbmFwc2hvdCgpCglzbmFwc2hvdEluZGV4LlNldChhY3RpdmVQcm9wb3NhbFNuYXBzaG90S2V5KHByb3Bvc2FsKSwgcHJvcG9zYWwuSUQoKSkKCWlmIGVyciA6PSBnLnN0b3JlLlNldEFjdGl2ZVByb3Bvc2Fsc0J5U25hcHNob3QoMCwgcmxtLCBzbmFwc2hvdEluZGV4KTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGZhbHNlCgl9CgoJLy8gQWRkIHRvIHVzZXIgcHJvcG9zYWxzCgllcnIgPSBnLnN0b3JlLkFkZFVzZXJQcm9wb3NhbCgwLCBybG0sIHByb3Bvc2FsLlByb3Bvc2VyKCkuU3RyaW5nKCksIHByb3Bvc2FsLklEKCkpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZmFsc2UKCX0KCglyZXR1cm4gdHJ1ZQp9CgovLyByZW1vdmVBY3RpdmVQcm9wb3NhbCByZW1vdmVzIGEgcHJvcG9zYWwgZnJvbSB0aGUgYWN0aXZlIHNuYXBzaG90IGluZGV4LgpmdW5jIChnICpnb3Zlcm5hbmNlVjEpIHJlbW92ZUFjdGl2ZVByb3Bvc2FsKF8gaW50LCBybG0gcmVhbG0sIHByb3Bvc2FsICpnb3Zlcm5hbmNlLlByb3Bvc2FsKSBlcnJvciB7CglzbmFwc2hvdEluZGV4IDo9IGcuc3RvcmUuR2V0QWN0aXZlUHJvcG9zYWxzQnlTbmFwc2hvdCgpCglrZXkgOj0gYWN0aXZlUHJvcG9zYWxTbmFwc2hvdEtleShwcm9wb3NhbCkKCWlmICFzbmFwc2hvdEluZGV4LkhhcyhrZXkpIHsKCQlyZXR1cm4gbWFrZUVycm9yV2l0aERldGFpbHMoZXJyRGF0YU5vdEZvdW5kLCB1Zm10LlNwcmludGYoImFjdGl2ZSBwcm9wb3NhbCBpbmRleCBlbnRyeSBub3QgZm91bmQsIHByb3Bvc2FsSUQ6ICVkIiwgcHJvcG9zYWwuSUQoKSkpCgl9CglzbmFwc2hvdEluZGV4LlJlbW92ZShrZXkpCgoJcmV0dXJuIGcuc3RvcmUuU2V0QWN0aXZlUHJvcG9zYWxzQnlTbmFwc2hvdCgwLCBybG0sIHNuYXBzaG90SW5kZXgpCn0KCi8vIFVzZXIgcHJvcG9zYWxzIG1ldGhvZHMKZnVuYyAoZyAqZ292ZXJuYW5jZVYxKSBnZXRVc2VyUHJvcG9zYWxzKHVzZXIgc3RyaW5nKSBbXSpnb3Zlcm5hbmNlLlByb3Bvc2FsIHsKCXByb3Bvc2FsSURzLCBleGlzdHMgOj0gZy5zdG9yZS5HZXRVc2VyUHJvcG9zYWxJRHModXNlcikKCWlmICFleGlzdHMgewoJCXJldHVybiBbXSpnb3Zlcm5hbmNlLlByb3Bvc2Fse30KCX0KCglwcm9wb3NhbHMgOj0gbWFrZShbXSpnb3Zlcm5hbmNlLlByb3Bvc2FsLCAwKQoKCWZvciBfLCBpZCA6PSByYW5nZSBwcm9wb3NhbElEcyB7CgkJcHJvcG9zYWwsIGV4aXN0cyA6PSBnLnN0b3JlLkdldFByb3Bvc2FsKGlkKQoJCWlmICFleGlzdHMgewoJCQljb250aW51ZQoJCX0KCgkJcHJvcG9zYWxzID0gYXBwZW5kKHByb3Bvc2FscywgcHJvcG9zYWwpCgl9CgoJcmV0dXJuIHByb3Bvc2Fscwp9CgovLyBoYXNBY3RpdmVQcm9wb3NhbCBhc3N1bWVzIHJlbW92ZUluYWN0aXZlVXNlclByb3Bvc2FscyBoYXMgYWxyZWFkeSBwcnVuZWQgc3RhbGUgcHJvcG9zYWxzLgpmdW5jIChnICpnb3Zlcm5hbmNlVjEpIGhhc0FjdGl2ZVByb3Bvc2FsKHByb3Bvc2VyQWRkcmVzcyBhZGRyZXNzKSBib29sIHsKCXByb3Bvc2FscyA6PSBnLmdldFVzZXJQcm9wb3NhbHMocHJvcG9zZXJBZGRyZXNzLlN0cmluZygpKQoKCXJldHVybiBsZW4ocHJvcG9zYWxzKSA+IDAKfQoKLy8gUmVtb3ZlIGluYWN0aXZlIHVzZXIgcHJvcG9zYWxzCi8vIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byByZW1vdmUgaW5hY3RpdmUgcHJvcG9zYWxzIGZyb20gdGhlIHVzZXIgcHJvcG9zYWxzIGxpc3QuCi8vIEl0IGlzIHVzZWQgdG8gY2xlYW4gdXAgdXNlcidzIGFjdGl2ZSBwcm9wb3NhbCBsaXN0IHdoZW4gY3JlYXRpbmcgYSBuZXcgcHJvcG9zYWwuCmZ1bmMgKGcgKmdvdmVybmFuY2VWMSkgcmVtb3ZlSW5hY3RpdmVVc2VyUHJvcG9zYWxzKF8gaW50LCBybG0gcmVhbG0sIHByb3Bvc2VyQWRkcmVzcyBhZGRyZXNzLCBjdXJyZW50IGludDY0KSBlcnJvciB7Cglwcm9wb3NhbHMgOj0gZy5nZXRVc2VyUHJvcG9zYWxzKHByb3Bvc2VyQWRkcmVzcy5TdHJpbmcoKSkKCglmb3IgXywgcHJvcG9zYWwgOj0gcmFuZ2UgcHJvcG9zYWxzIHsKCQlwcm9wb3NhbFJlc29sdmVyIDo9IE5ld1Byb3Bvc2FsUmVzb2x2ZXIocHJvcG9zYWwpCgoJCWlmICFwcm9wb3NhbFJlc29sdmVyLklzQWN0aXZlKGN1cnJlbnQpIHsKCQkJZXJyIDo9IGcuc3RvcmUuUmVtb3ZlVXNlclByb3Bvc2FsKDAsIHJsbSwgcHJvcG9zZXJBZGRyZXNzLlN0cmluZygpLCBwcm9wb3NhbC5JRCgpKQoJCQlpZiBlcnIgIT0gbmlsIHsKCQkJCXJldHVybiBlcnIKCQkJfQoJCX0KCX0KCglyZXR1cm4gbmlsCn0KCi8vIFByb3Bvc2FsIHZvdGluZyBpbmZvIG1ldGhvZHMKZnVuYyAoZyAqZ292ZXJuYW5jZVYxKSBnZXRQcm9wb3NhbFVzZXJWb3RpbmdJbmZvcyhwcm9wb3NhbElEIGludDY0KSAoKmJwdHJlZS5CUFRyZWUsIGJvb2wpIHsKCXJldHVybiBnLnN0b3JlLkdldFByb3Bvc2FsVm90aW5nSW5mb3MocHJvcG9zYWxJRCkKfQoKZnVuYyAoZyAqZ292ZXJuYW5jZVYxKSB1cGRhdGVQcm9wb3NhbFVzZXJWb3RlcyhfIGludCwgcmxtIHJlYWxtLCBwcm9wb3NhbCAqZ292ZXJuYW5jZS5Qcm9wb3NhbCwgdXNlclZvdGluZ0luZm9zICpicHRyZWUuQlBUcmVlKSBlcnJvciB7CglyZXR1cm4gZy5zdG9yZS5TZXRQcm9wb3NhbFZvdGluZ0luZm9zKDAsIHJsbSwgcHJvcG9zYWwuSUQoKSwgdXNlclZvdGluZ0luZm9zKQp9CgovLyBIZWxwZXIgbWV0aG9kcyBmb3IgQVBJCmZ1bmMgKGcgKmdvdmVybmFuY2VWMSkgbXVzdEdldFByb3Bvc2FsKGlkIGludDY0KSAqZ292ZXJuYW5jZS5Qcm9wb3NhbCB7Cglwcm9wb3NhbCwgZXhpc3RzIDo9IGcuZ2V0UHJvcG9zYWwoaWQpCglpZiAhZXhpc3RzIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscyhlcnJQcm9wb3NhbE5vdEZvdW5kLCB1Zm10LlNwcmludGYoInByb3Bvc2FsKCVkKSBub3QgZm91bmQiLCBpZCkpKQoJfQoJcmV0dXJuIHByb3Bvc2FsCn0KCmZ1bmMgKGcgKmdvdmVybmFuY2VWMSkgZ2V0UHJvcG9zYWxVc2VyVm90aW5nSW5mbyhwcm9wb3NhbElEIGludDY0LCBhZGRyIGFkZHJlc3MpIChnb3Zlcm5hbmNlLlZvdGluZ0luZm8sIGJvb2wpIHsKCXZvdGluZ0luZm9zVHJlZSwgZXhpc3RzIDo9IGcuZ2V0UHJvcG9zYWxVc2VyVm90aW5nSW5mb3MocHJvcG9zYWxJRCkKCWlmICFleGlzdHMgewoJCXJldHVybiBnb3Zlcm5hbmNlLkRlZmF1bHRWb3RpbmdJbmZvKCksIGZhbHNlCgl9CgoJdm90aW5nSW5mb1JhdyA6PSB2b3RpbmdJbmZvc1RyZWUuR2V0KGFkZHIuU3RyaW5nKCkpCglpZiB2b3RpbmdJbmZvUmF3ID09IG5pbCB7CgkJcmV0dXJuIGdvdmVybmFuY2UuRGVmYXVsdFZvdGluZ0luZm8oKSwgZmFsc2UKCX0KCXZvdGluZ0luZm8sIG9rIDo9IHZvdGluZ0luZm9SYXcuKGdvdmVybmFuY2UuVm90aW5nSW5mbykKCXJldHVybiB2b3RpbmdJbmZvLCBvawp9ChqVqAIKFnBhcmFtZXRlcl9yZWdpc3RyeS5nbm8S+acCcGFja2FnZSBnb3Zlcm5hbmNlCgppbXBvcnQgKAoJInN0cmluZ3MiCgoJcHJiYWMgImduby5sYW5kL3AvZ25vc3dhcC9yYmFjL3YxIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoKCWNtICJnbm8ubGFuZC9yL2dub3N3YXAvY29tbW9uIgoJY3AgImduby5sYW5kL3IvZ25vc3dhcC9jb21tdW5pdHlfcG9vbC92MSIKCWVuICJnbm8ubGFuZC9yL2dub3N3YXAvZW1pc3Npb24iCgkiZ25vLmxhbmQvci9nbm9zd2FwL3JiYWMvdjEiCgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3YvZ292ZXJuYW5jZSIKCWdzICJnbm8ubGFuZC9yL2dub3N3YXAvZ292L3N0YWtlciIKCWxwICJnbm8ubGFuZC9yL2dub3N3YXAvbGF1bmNocGFkIgoJcGwgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgoJcG9zICJnbm8ubGFuZC9yL2dub3N3YXAvcG9zaXRpb24iCglwZiAiZ25vLmxhbmQvci9nbm9zd2FwL3Byb3RvY29sX2ZlZSIKCXJyICJnbm8ubGFuZC9yL2dub3N3YXAvcm91dGVyIgoJc3IgImduby5sYW5kL3IvZ25vc3dhcC9zdGFrZXIiCgoJImduby5sYW5kL3IvZ25vc3dhcC9oYWx0L3YxIgopCgovLyBnbG9iYWxQYXJhbWV0ZXJSZWdpc3RyeSBpcyBpbml0aWFsaXplZCBvbmNlIGFuZCByZXVzZWQgZm9yIGFsbCB2YWxpZGF0aW9uIGFuZCBleGVjdXRpb24uCi8vIFRoaXMgcHJvdmlkZXMgY29uc2lzdGVudCB2YWxpZGF0aW9uIGF0IHByb3Bvc2FsIGNyZWF0aW9uIHRpbWUgYW5kIGV4ZWN1dGlvbiB0aW1lLgp2YXIgZ2xvYmFsUGFyYW1ldGVyUmVnaXN0cnkgKlBhcmFtZXRlclJlZ2lzdHJ5CgpmdW5jIGluaXQoKSB7CglnbG9iYWxQYXJhbWV0ZXJSZWdpc3RyeSA9IENyZWF0ZVBhcmFtZXRlckhhbmRsZXJzKCkKfQoKLy8gUGFja2FnZSBwYXRocwpjb25zdCAoCglHTlNfVE9LRU5fS0VZICAgICAgID0gImduby5sYW5kL3IvZ25vc3dhcC9nbnMuR05TIgoJSEFMVF9QQVRIICAgICAgICAgICA9ICJnbm8ubGFuZC9yL2dub3N3YXAvaGFsdC92MSIKCVJCQUNfUEFUSCAgICAgICAgICAgPSAiZ25vLmxhbmQvci9nbm9zd2FwL3JiYWMvdjEiCglBQ0NFU1NfUEFUSCAgICAgICAgID0gImduby5sYW5kL3IvZ25vc3dhcC9hY2Nlc3MvdjEiCglFTUlTU0lPTl9QQVRIICAgICAgID0gImduby5sYW5kL3IvZ25vc3dhcC9lbWlzc2lvbiIKCUNPTU1PTl9QQVRIICAgICAgICAgPSAiZ25vLmxhbmQvci9nbm9zd2FwL2NvbW1vbiIKCVBPT0xfUEFUSCAgICAgICAgICAgPSAiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiCglQT1NJVElPTl9QQVRIICAgICAgID0gImduby5sYW5kL3IvZ25vc3dhcC9wb3NpdGlvbiIKCVJPVVRFUl9QQVRIICAgICAgICAgPSAiZ25vLmxhbmQvci9nbm9zd2FwL3JvdXRlciIKCVNUQUtFUl9QQVRIICAgICAgICAgPSAiZ25vLmxhbmQvci9nbm9zd2FwL3N0YWtlciIKCUxBVU5DSFBBRF9QQVRIICAgICAgPSAiZ25vLmxhbmQvci9nbm9zd2FwL2xhdW5jaHBhZCIKCVBST1RPQ09MX0ZFRV9QQVRIICAgPSAiZ25vLmxhbmQvci9nbm9zd2FwL3Byb3RvY29sX2ZlZSIKCUNPTU1VTklUWV9QT09MX1BBVEggPSAiZ25vLmxhbmQvci9nbm9zd2FwL2NvbW11bml0eV9wb29sL3YxIgoJR09WX0dPVkVSTkFOQ0VfUEFUSCA9ICJnbm8ubGFuZC9yL2dub3N3YXAvZ292L2dvdmVybmFuY2UiCglHT1ZfU1RBS0VSX1BBVEggICAgID0gImduby5sYW5kL3IvZ25vc3dhcC9nb3Yvc3Rha2VyIgopCgovLyBQYXJhbWV0ZXJIYW5kbGVyIGludGVyZmFjZSBkZWZpbmVzIHRoZSBjb250cmFjdCBmb3IgcGFyYW1ldGVyIGV4ZWN1dGlvbiBoYW5kbGVycy4KLy8gRWFjaCBoYW5kbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBleGVjdXRpbmcgc3BlY2lmaWMgcGFyYW1ldGVyIGNoYW5nZXMgaW4gdGhlIHN5c3RlbS4KdHlwZSBQYXJhbWV0ZXJIYW5kbGVyIGludGVyZmFjZSB7CgkvLyBFeGVjdXRlIHByb2Nlc3NlcyB0aGUgcGFyYW1ldGVycyBhbmQgYXBwbGllcyB0aGUgY2hhbmdlcyB0byB0aGUgc3lzdGVtLgoJLy8gVGhlIGBfIGludCwgcmxtIHJlYWxtYCBkaXNjcmltaW5hdG9yIHBhaXIgZm9yd2FyZHMgdGhlIGdvdmVybmFuY2UgcHJveHkncwoJLy8gcmVhbG0gdmFsdWUgaW50byB0aGUgaGFuZGxlciBzbyBhbnkgY3Jvc3MtcmVhbG0gY2FsbHMgaW5zaWRlIHRoZSBjbG9zdXJlCgkvLyBydW4gdW5kZXIgdGhlIHByb3h5J3MgaWRlbnRpdHkgKHRoZSBvbmx5IGFkZHJlc3Mgd2l0aCBjYWxsZXItYWxsb3dsaXN0CgkvLyBwZXJtaXNzaW9uIGFnYWluc3QgdGhlIHRhcmdldGVkIC9yLyByZWFsbXMpLgoJLy8KCS8vIFBhcmFtZXRlcnM6CgkvLyAgIC0gXzogaW50ZWdlciBkaXNjcmltaW5hdG9yIHJlcXVpcmVkIGJ5IHRoZSBjcm9zc2luZyBlbnRyeXBvaW50OyBjYWxsZXJzIHVzZSAwCgkvLyAgIC0gcmxtOiBjdXJyZW50IGdvdmVybmFuY2UgcHJveHkgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdG8gdGhlIGhhbmRsZXIKCS8vICAgLSBwYXJhbXM6IHNlcmlhbGl6ZWQgcGFyYW1ldGVyIHZhbHVlcyB0byB2YWxpZGF0ZSBhbmQgYXBwbHkgaW4gaGFuZGxlciBvcmRlcgoJLy8KCS8vIFJldHVybnM6CgkvLyAgIC0gZXJyb3I6IG5pbCB3aGVuIHRoZSBwYXJhbWV0ZXIgY2hhbmdlIHN1Y2NlZWRzLCBvciBhbiBleGVjdXRpb24vdmFsaWRhdGlvbiBlcnJvcgoJRXhlY3V0ZShfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yCn0KCi8vIFBhcmFtZXRlckhhbmRsZXJPcHRpb25zIGNvbnRhaW5zIHRoZSBjb25maWd1cmF0aW9uIGFuZCBleGVjdXRpb24gbG9naWMgZm9yIGEgcGFyYW1ldGVyIGhhbmRsZXIuCi8vIFRoaXMgc3RydWN0IGVuY2Fwc3VsYXRlcyBhbGwgaW5mb3JtYXRpb24gbmVlZGVkIHRvIGlkZW50aWZ5IGFuZCBleGVjdXRlIGEgcGFyYW1ldGVyIGNoYW5nZS4KLy8KLy8gTk9URTogaGFuZGxlckZ1bmMgdXNlcyBgcmxtIHJlYWxtYCAocmF0aGVyIHRoYW4gYGN1ciByZWFsbWApIGFzIHRoZSByZWFsbQovLyBwYXJhbWV0ZXIgbmFtZS4gVGhlIHYyIHByZXByb2Nlc3NvciByZXNlcnZlcyB0aGUgYGN1cmAgbmFtZSBmb3IgdGhlIGZpcnN0Ci8vIHJlYWxtLXR5cGUgcGFyYW1ldGVyIG9mIHRvcC1sZXZlbCBjcm9zc2luZyBmdW5jdGlvbiBkZWNsYXJhdGlvbnMgYW5kCi8vIGB0LlJ1bmAgY2xvc3VyZXMgb25seTsgdXNpbmcgaXQgYXMgdGhlIHJlYWxtLXBhcmFtZXRlciBuYW1lIG9uIGEKLy8gbXVsdGktcGFyYW1ldGVyIHN0cnVjdC1maWVsZCBmdW5jdGlvbiB2YWx1ZSB0cmlwcyBhIHBhcnNlciBjaGVjawovLyAoIm9ubHkgdGhlIGZpcnN0IHJlYWxtIHR5cGUgYXJndW1lbnQgb2YgYSBjcm9zc2luZyBmdW5jdGlvbiBtYXkgaGF2ZSBuYW1lCi8vIGBjdXJgIikuIE5hbWluZyBpdCBgcmxtYCBrZWVwcyB0aGUgbG93ZXJpbmcgaWRlbnRpY2FsIHdpdGhvdXQgdGhlIHN5bnRheAovLyBjb25zdHJhaW50Lgp0eXBlIFBhcmFtZXRlckhhbmRsZXJPcHRpb25zIHN0cnVjdCB7Cglwa2dQYXRoICAgICAgICAgICAgc3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQYWNrYWdlIHBhdGggb2YgdGhlIHRhcmdldCBjb250cmFjdAoJZnVuY3Rpb24gICAgICAgICAgIHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRnVuY3Rpb24gbmFtZSB0byBiZSBjYWxsZWQKCXBhcmFtQ291bnQgICAgICAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV4cGVjdGVkIG51bWJlciBvZiBwYXJhbWV0ZXJzCgloYW5kbGVyRnVuYyAgICAgICAgZnVuYyhfIGludCwgcmxtIHJlYWxtLCBfIFtdc3RyaW5nKSBlcnJvciAvLyBGdW5jdGlvbiB0aGF0IGV4ZWN1dGVzIHRoZSBwYXJhbWV0ZXIgY2hhbmdlCglwYXJhbVZhbGlkYXRvcnMgICAgW11wYXJhbVZhbGlkYXRvciAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcHRpb25hbCBwZXItcGFyYW1ldGVyIHZhbGlkYXRvcnMgZm9yIHByb3Bvc2FsLXRpbWUgY2hlY2tzCgljb21wb3NpdGVWYWxpZGF0b3IgY29tcG9zaXRlVmFsaWRhdG9yICAgICAgICAgICAgICAgICAgICAgICAvLyBPcHRpb25hbCBjcm9zcy1wYXJhbWV0ZXIgdmFsaWRhdG9yIGZvciBzdGF0aWMgYnVzaW5lc3MgcnVsZXMKfQoKLy8gcGFyYW1WYWxpZGF0b3IgdmFsaWRhdGVzIGEgc2luZ2xlIHBhcmFtZXRlciB2YWx1ZSBhbmQgcmV0dXJucyBhbiBlcnJvciBvbiBmYWlsdXJlLgp0eXBlIHBhcmFtVmFsaWRhdG9yIGZ1bmMoc3RyaW5nKSBlcnJvcgoKLy8gY29tcG9zaXRlVmFsaWRhdG9yIHZhbGlkYXRlcyByZWxhdGlvbnNoaXBzIGJldHdlZW4gYSBoYW5kbGVyJ3MgcGFyYW1ldGVycy4KLy8gSXQgbXVzdCBvbmx5IGVuZm9yY2UgZGV0ZXJtaW5pc3RpYywgc3RhdGUtaW5kZXBlbmRlbnQgcnVsZXMgc28gdGhhdCBhCi8vIHByb3Bvc2FsIGlzIG5vdCByZWplY3RlZCBtZXJlbHkgYmVjYXVzZSBvbi1jaGFpbiBzdGF0ZSBjaGFuZ2VzIHdoaWxlIHZvdGluZy4KdHlwZSBjb21wb3NpdGVWYWxpZGF0b3IgZnVuYyhbXXN0cmluZykgZXJyb3IKCi8vIE5ld1BhcmFtZXRlckhhbmRsZXJPcHRpb25zIGNyZWF0ZXMgYSBuZXcgcGFyYW1ldGVyIGhhbmRsZXIgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbmZpZ3VyYXRpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwa2dQYXRoOiBwYWNrYWdlIHBhdGggb2YgdGhlIHRhcmdldCBjb250cmFjdAovLyAgIC0gZnVuY3Rpb246IGZ1bmN0aW9uIG5hbWUgdG8gYmUgY2FsbGVkCi8vICAgLSBwYXJhbUNvdW50OiBleHBlY3RlZCBudW1iZXIgb2YgcGFyYW1ldGVycwovLyAgIC0gaGFuZGxlckZ1bmM6IGNhbGxiYWNrIHJlY2VpdmluZyB0aGUgZGlzY3JpbWluYXRvciwgcHJvcGFnYXRlZCByZWFsbSwgYW5kIHNlcmlhbGl6ZWQgcGFyYW1ldGVycyB0byBleGVjdXRlIHRoZSBjaGFuZ2UKLy8gICAtIHBhcmFtVmFsaWRhdG9yczogb3B0aW9uYWwgdmFsaWRhdG9ycyBmb3IgZWFjaCBwYXJhbWV0ZXIgKG11c3QgbWF0Y2ggcGFyYW1Db3VudCBpZiBwcm92aWRlZCkKLy8KLy8gUmV0dXJuczoKLy8gICAtIFBhcmFtZXRlckhhbmRsZXI6IGNvbmZpZ3VyZWQgcGFyYW1ldGVyIGhhbmRsZXIgaW50ZXJmYWNlCmZ1bmMgTmV3UGFyYW1ldGVySGFuZGxlck9wdGlvbnMoCglwa2dQYXRoLAoJZnVuY3Rpb24gc3RyaW5nLAoJcGFyYW1Db3VudCBpbnQsCgloYW5kbGVyRnVuYyBmdW5jKF8gaW50LCBybG0gcmVhbG0sIF8gW11zdHJpbmcpIGVycm9yLAoJcGFyYW1WYWxpZGF0b3JzIC4uLnBhcmFtVmFsaWRhdG9yLAopIFBhcmFtZXRlckhhbmRsZXIgewoJaWYgbGVuKHBhcmFtVmFsaWRhdG9ycykgPiAwICYmIGxlbihwYXJhbVZhbGlkYXRvcnMpICE9IHBhcmFtQ291bnQgewoJCXBhbmljKHVmbXQuU3ByaW50ZigKCQkJImludmFsaWQgdmFsaWRhdG9yIGNvdW50IGZvciAlczolczogZXhwZWN0ZWQgJWQsIGdvdCAlZCIsCgkJCXBrZ1BhdGgsIGZ1bmN0aW9uLCBwYXJhbUNvdW50LCBsZW4ocGFyYW1WYWxpZGF0b3JzKSwKCQkpKQoJfQoKCXJldHVybiAmUGFyYW1ldGVySGFuZGxlck9wdGlvbnN7CgkJcGtnUGF0aDogICAgICAgICBwa2dQYXRoLAoJCWZ1bmN0aW9uOiAgICAgICAgZnVuY3Rpb24sCgkJcGFyYW1Db3VudDogICAgICBwYXJhbUNvdW50LAoJCWhhbmRsZXJGdW5jOiAgICAgaGFuZGxlckZ1bmMsCgkJcGFyYW1WYWxpZGF0b3JzOiBwYXJhbVZhbGlkYXRvcnMsCgl9Cn0KCi8vIEhhbmRsZXJLZXkgZ2VuZXJhdGVzIGEgdW5pcXVlIGtleSBmb3IgdGhpcyBoYW5kbGVyIGJhc2VkIG9uIHBhY2thZ2UgcGF0aCBhbmQgZnVuY3Rpb24gbmFtZS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHN0cmluZzogdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBoYW5kbGVyCmZ1bmMgKGggKlBhcmFtZXRlckhhbmRsZXJPcHRpb25zKSBIYW5kbGVyS2V5KCkgc3RyaW5nIHsKCXJldHVybiBtYWtlSGFuZGxlcktleShoLnBrZ1BhdGgsIGguZnVuY3Rpb24pCn0KCi8vIEV4ZWN1dGUgdmFsaWRhdGVzIHBhcmFtZXRlciBjb3VudCBhbmQgZXhlY3V0ZXMgdGhlIGhhbmRsZXIgZnVuY3Rpb24uCi8vIFRoaXMgbWV0aG9kIGVuc3VyZXMgdGhlIGNvcnJlY3QgbnVtYmVyIG9mIHBhcmFtZXRlcnMgYXJlIHByb3ZpZGVkIGJlZm9yZSBleGVjdXRpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBpbnRlZ2VyIGRpc2NyaW1pbmF0b3IgcmVxdWlyZWQgYnkgdGhlIGNyb3NzaW5nIGVudHJ5cG9pbnQ7IGNhbGxlcnMgdXNlIDAKLy8gICAtIHJsbTogZ292ZXJuYW5jZSBwcm94eSByZWFsbSB0aHJlYWRlZCBpbnRvIHRoZSB3cmFwcGVkIGhhbmRsZXIKLy8gICAtIHBhcmFtczogc2VyaWFsaXplZCBwYXJhbWV0ZXIgdmFsdWVzIHRvIHBhc3MgdG8gdGhlIGhhbmRsZXIKLy8KLy8gUmV0dXJuczoKLy8gICAtIGVycm9yOiBwYXJhbWV0ZXItY291bnQgZXJyb3Igb3IgdGhlIGVycm9yIHJldHVybmVkIGJ5IHRoZSB3cmFwcGVkIGhhbmRsZXIKZnVuYyAoaCAqUGFyYW1ldGVySGFuZGxlck9wdGlvbnMpIEV4ZWN1dGUoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CglpZiBsZW4ocGFyYW1zKSAhPSBoLnBhcmFtQ291bnQgewoJCXJldHVybiB1Zm10LkVycm9yZigiZXhwZWN0ZWQgJWQgcGFyYW1ldGVycywgZ290ICVkIiwgaC5wYXJhbUNvdW50LCBsZW4ocGFyYW1zKSkKCX0KCglyZXR1cm4gaC5oYW5kbGVyRnVuYygwLCBybG0sIHBhcmFtcykKfQoKLy8gVmFsaWRhdGVQYXJhbXMgY2hlY2tzIHRoZSBwYXJhbWV0ZXIgY291bnQgYW5kIHJ1bnMgY29uZmlndXJlZCBpbmRpdmlkdWFsIGFuZCBjb21wb3NpdGUgdmFsaWRhdG9ycyB3aXRob3V0IGV4ZWN1dGluZyB0aGUgaGFuZGxlci4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBhcmFtczogc2VyaWFsaXplZCBwYXJhbWV0ZXIgdmFsdWVzIHRvIHZhbGlkYXRlIGluIGhhbmRsZXIgb3JkZXIKLy8KLy8gUmV0dXJuczoKLy8gICAtIGVycm9yOiBuaWwgd2hlbiBhbGwgY29uZmlndXJlZCBjaGVja3MgcGFzcywgb3IgdGhlIGZpcnN0IGNvdW50L3R5cGUvYnVzaW5lc3MtcnVsZSB2YWxpZGF0aW9uIGVycm9yCmZ1bmMgKGggKlBhcmFtZXRlckhhbmRsZXJPcHRpb25zKSBWYWxpZGF0ZVBhcmFtcyhwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCWlmIGxlbihwYXJhbXMpICE9IGgucGFyYW1Db3VudCB7CgkJcmV0dXJuIHVmbXQuRXJyb3JmKAoJCQkiZXhwZWN0ZWQgJWQgcGFyYW1ldGVycyBmb3IgJXMsIGdvdCAlZCIsCgkJCWgucGFyYW1Db3VudCwgaC5IYW5kbGVyS2V5KCksIGxlbihwYXJhbXMpLAoJCSkKCX0KCglpZiBsZW4oaC5wYXJhbVZhbGlkYXRvcnMpID4gMCB7CgkJaWYgbGVuKGgucGFyYW1WYWxpZGF0b3JzKSAhPSBoLnBhcmFtQ291bnQgewoJCQlyZXR1cm4gdWZtdC5FcnJvcmYoCgkJCQkidmFsaWRhdG9yIGNvdW50IG1pc21hdGNoIGZvciAlczogZXhwZWN0ZWQgJWQgdmFsaWRhdG9yKHMpLCBnb3QgJWQiLAoJCQkJaC5IYW5kbGVyS2V5KCksIGgucGFyYW1Db3VudCwgbGVuKGgucGFyYW1WYWxpZGF0b3JzKSwKCQkJKQoJCX0KCgkJZm9yIGksIHZhbGlkYXRvciA6PSByYW5nZSBoLnBhcmFtVmFsaWRhdG9ycyB7CgkJCWlmIHZhbGlkYXRvciA9PSBuaWwgewoJCQkJY29udGludWUKCQkJfQoKCQkJaWYgZXJyIDo9IHZhbGlkYXRvcihwYXJhbXNbaV0pOyBlcnIgIT0gbmlsIHsKCQkJCXJldHVybiB1Zm10LkVycm9yZigicGFyYW1bJWRdOiAldiIsIGksIGVycikKCQkJfQoJCX0KCX0KCglpZiBoLmNvbXBvc2l0ZVZhbGlkYXRvciAhPSBuaWwgewoJCWlmIGVyciA6PSBoLmNvbXBvc2l0ZVZhbGlkYXRvcihwYXJhbXMpOyBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCglyZXR1cm4gbmlsCn0KCi8vIFBhcmFtZXRlclJlZ2lzdHJ5IG1hbmFnZXMgdGhlIGNvbGxlY3Rpb24gb2YgcGFyYW1ldGVyIGhhbmRsZXJzIGZvciBnb3Zlcm5hbmNlIGV4ZWN1dGlvbi4KLy8gVGhpcyByZWdpc3RyeSBhbGxvd3MgcHJvcG9zYWxzIHRvIGV4ZWN1dGUgcGFyYW1ldGVyIGNoYW5nZXMgYWNyb3NzIGRpZmZlcmVudCBzeXN0ZW0gY29udHJhY3RzLgp0eXBlIFBhcmFtZXRlclJlZ2lzdHJ5IHN0cnVjdCB7CgloYW5kbGVycyBtYXBbc3RyaW5nXVBhcmFtZXRlckhhbmRsZXJPcHRpb25zIC8vIE1hcCBzdG9yaW5nIGhhbmRsZXIgY29uZmlndXJhdGlvbnMga2V5ZWQgYnkgcGFja2FnZTpmdW5jdGlvbgp9CgovLyBSZWdpc3RlciBhZGRzIGEgbmV3IHBhcmFtZXRlciBoYW5kbGVyIHRvIHRoZSByZWdpc3RyeS4KLy8gRWFjaCBoYW5kbGVyIGlzIGlkZW50aWZpZWQgYnkgYSB1bmlxdWUgY29tYmluYXRpb24gb2YgcGFja2FnZSBwYXRoIGFuZCBmdW5jdGlvbiBuYW1lLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gaGFuZGxlcjogcGFyYW1ldGVyIGhhbmRsZXIgY29uZmlndXJhdGlvbiB0byByZWdpc3RlcgpmdW5jIChyICpQYXJhbWV0ZXJSZWdpc3RyeSkgUmVnaXN0ZXIoaGFuZGxlciBQYXJhbWV0ZXJIYW5kbGVyT3B0aW9ucykgewoJci5oYW5kbGVyc1toYW5kbGVyLkhhbmRsZXJLZXkoKV0gPSBoYW5kbGVyCn0KCi8vIEhhbmRsZXIgcmV0cmlldmVzIGEgcGFyYW1ldGVyIGhhbmRsZXIgYnkgaXRzIHBhY2thZ2U6ZnVuY3Rpb24ga2V5LgovLyBUaGlzIG1ldGhvZCBpcyB1c2VkIGR1cmluZyBwcm9wb3NhbCBleGVjdXRpb24gdG8gZmluZCB0aGUgYXBwcm9wcmlhdGUgaGFuZGxlci4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGtleTogaGFuZGxlciBrZXkgcmV0dXJuZWQgYnkgSGFuZGxlcktleSwgaW4gInBrZ1BhdGg6ZnVuY3Rpb24iIGZvcm1hdAovLwovLyBSZXR1cm5zOgovLyAgIC0gUGFyYW1ldGVySGFuZGxlcjogdGhlIG1hdGNoaW5nIHBhcmFtZXRlciBoYW5kbGVyCi8vICAgLSBlcnJvcjogZXJyb3IgaWYgdGhlIGtleSBoYXMgbm8gcmVnaXN0ZXJlZCBoYW5kbGVyCmZ1bmMgKHIgKlBhcmFtZXRlclJlZ2lzdHJ5KSBIYW5kbGVyKGtleSBzdHJpbmcpIChQYXJhbWV0ZXJIYW5kbGVyLCBlcnJvcikgewoJLy8gUmV0cmlldmUgaGFuZGxlciBmcm9tIHJlZ2lzdHJ5CgloYW5kbGVyLCBleGlzdHMgOj0gci5oYW5kbGVyc1trZXldCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gbmlsLCB1Zm10LkVycm9yZigiaGFuZGxlciBub3QgZm91bmQgZm9yICVzIiwga2V5KQoJfQoKCXJldHVybiAmaGFuZGxlciwgbmlsCn0KCi8vIE5ld1BhcmFtZXRlclJlZ2lzdHJ5IGNyZWF0ZXMgYSBuZXcgZW1wdHkgcGFyYW1ldGVyIHJlZ2lzdHJ5LgovLwovLyBSZXR1cm5zOgovLyAgIC0gKlBhcmFtZXRlclJlZ2lzdHJ5OiBuZXcgcmVnaXN0cnkgaW5zdGFuY2UKZnVuYyBOZXdQYXJhbWV0ZXJSZWdpc3RyeSgpICpQYXJhbWV0ZXJSZWdpc3RyeSB7CglyZXR1cm4gJlBhcmFtZXRlclJlZ2lzdHJ5e2hhbmRsZXJzOiBtYWtlKG1hcFtzdHJpbmddUGFyYW1ldGVySGFuZGxlck9wdGlvbnMpfQp9CgovLyBtYWtlSGFuZGxlcktleSBjcmVhdGVzIGEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIGEgaGFuZGxlciBiYXNlZCBvbiBwYWNrYWdlIHBhdGggYW5kIGZ1bmN0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcGtnUGF0aDogcGFja2FnZSBwYXRoIG9mIHRoZSB0YXJnZXQgY29udHJhY3QKLy8gICAtIGZ1bmN0aW9uOiBmdW5jdGlvbiBuYW1lIHRvIGJlIGNhbGxlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gc3RyaW5nOiB1bmlxdWUga2V5IGluIGZvcm1hdCAicGtnUGF0aDpmdW5jdGlvbiIKZnVuYyBtYWtlSGFuZGxlcktleShwa2dQYXRoLCBmdW5jdGlvbiBzdHJpbmcpIHN0cmluZyB7CglyZXR1cm4gcGtnUGF0aCArICI6IiArIGZ1bmN0aW9uCn0KCi8vIENyZWF0ZVBhcmFtZXRlckhhbmRsZXJzIGluaXRpYWxpemVzIGFuZCBjb25maWd1cmVzIGFsbCBzdXBwb3J0ZWQgcGFyYW1ldGVyIGhhbmRsZXJzLgovLyBUaGlzIGZ1bmN0aW9uIGRlZmluZXMgYWxsIHRoZSBwYXJhbWV0ZXIgY2hhbmdlcyB0aGF0IGNhbiBiZSBleGVjdXRlZCB0aHJvdWdoIGdvdmVybmFuY2UgcHJvcG9zYWxzLgovLyBJdCBjb3ZlcnMgY29uZmlndXJhdGlvbiBjaGFuZ2VzIGZvciB2YXJpb3VzIHN5c3RlbSBjb21wb25lbnRzIGluY2x1ZGluZyBwb29scywgc3Rha2luZywgZmVlcywgZXRjLgovLwovLyBSZXR1cm5zOgovLyAgIC0gKlBhcmFtZXRlclJlZ2lzdHJ5OiBmdWxseSBjb25maWd1cmVkIHJlZ2lzdHJ5IHdpdGggYWxsIHN1cHBvcnRlZCBoYW5kbGVycwpmdW5jIENyZWF0ZVBhcmFtZXRlckhhbmRsZXJzKCkgKlBhcmFtZXRlclJlZ2lzdHJ5IHsKCXJlZ2lzdHJ5IDo9IE5ld1BhcmFtZXRlclJlZ2lzdHJ5KCkKCgkvLyBEZWZpbmUgYWxsIGhhbmRsZXIgY29uZmlndXJhdGlvbnMgZm9yIGRpZmZlcmVudCBzeXN0ZW0gY29tcG9uZW50cy4KCS8vCgkvLyBFYWNoIGNsb3N1cmUgcmVjZWl2ZXMgYChfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpYCBhbmQgdGhyZWFkcwoJLy8gYHJsbWAgaW50byB0aGUgdGFyZ2V0ZWQgL3IvIHJlYWxtIGNhbGwuIFRoZSBjbG9zdXJlIGlzIGludm9rZWQgZnJvbQoJLy8gUGFyYW1ldGVySGFuZGxlck9wdGlvbnMuRXhlY3V0ZSB3aGljaCBmb3J3YXJkcyB0aGUgZ292ZXJuYW5jZSBwcm94eSdzCgkvLyByZWFsbSB2YWx1ZSwgc28gY3Jvc3MtcmVhbG0gY2FsbHMgbGFuZCBvbiB0aGUgdGFyZ2V0ZWQgcmVhbG0gd2l0aCB0aGUKCS8vIGdvdmVybmFuY2UgcHJveHkgYXMgdGhlIGltbWVkaWF0ZSBjYWxsZXIuCgloYW5kbGVycyA6PSBbXSpQYXJhbWV0ZXJIYW5kbGVyT3B0aW9uc3sKCQkvLyBDb21tdW5pdHkgcG9vbCB0b2tlbiB0cmFuc2ZlcnMKCQl7CgkJCXBrZ1BhdGg6ICAgIENPTU1VTklUWV9QT09MX1BBVEgsCgkJCWZ1bmN0aW9uOiAgICJUcmFuc2ZlclRva2VuIiwKCQkJcGFyYW1Db3VudDogMywKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJc3RyaW5nVmFsaWRhdG9yLCAgLy8gcGtnUGF0aAoJCQkJYWRkcmVzc1ZhbGlkYXRvciwgLy8gdG8KCQkJCXBvc2l0aXZlSW50NjRWYWxpZGF0b3IoImFtb3VudCIpLAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIFRyYW5zZmVyIHRva2VucyBmcm9tIGNvbW11bml0eSBwb29sIHRvIHNwZWNpZmllZCBhZGRyZXNzCgkJCQljcC5UcmFuc2ZlclRva2VuKAoJCQkJCWNyb3NzKHJsbSksCgkJCQkJcGFyYW1zWzBdLCAgICAgICAgICAvLyBwa2dQYXRoCgkJCQkJYWRkcmVzcyhwYXJhbXNbMV0pLCAvLyB0bwoJCQkJCXBhcnNlTnVtYmVyKHBhcmFtc1syXSwga2luZEludDY0KS4oaW50NjQpLCAvLyBhbW91bnQKCQkJCSkKCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCQkvLyBFbWlzc2lvbiBkaXN0cmlidXRpb24gY29uZmlndXJhdGlvbgoJCXsKCQkJcGtnUGF0aDogICAgRU1JU1NJT05fUEFUSCwKCQkJZnVuY3Rpb246ICAgIlNldERpc3RyaWJ1dGlvblN0YXJ0VGltZSIsCgkJCXBhcmFtQ291bnQ6IDEsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCW51bWJlclZhbGlkYXRvcihraW5kSW50NjQpLCAvLyBzdGFydCB0aW1lCgkJCX0sCgkJCWhhbmRsZXJGdW5jOiBmdW5jKF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBbXXN0cmluZykgZXJyb3IgewoJCQkJLy8gU2V0IGRpc3RyaWJ1dGlvbiBzdGFydCB0aW1lCgkJCQllbi5TZXREaXN0cmlidXRpb25TdGFydFRpbWUoY3Jvc3MocmxtKSwgcGFyc2VJbnQ2NChwYXJhbXNbMF0pKQoKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoJCXsKCQkJcGtnUGF0aDogICAgRU1JU1NJT05fUEFUSCwKCQkJZnVuY3Rpb246ICAgIkNoYW5nZURpc3RyaWJ1dGlvblBjdCIsCgkJCXBhcmFtQ291bnQ6IDQsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCW51bWJlclZhbGlkYXRvcihraW5kSW50NjQpLCAvLyBsaXF1aWRpdHlTdGFrZXJQY3QKCQkJCW51bWJlclZhbGlkYXRvcihraW5kSW50NjQpLCAvLyBkZXZPcHNQY3QKCQkJCW51bWJlclZhbGlkYXRvcihraW5kSW50NjQpLCAvLyBjb21tdW5pdHlQb29sUGN0CgkJCQludW1iZXJWYWxpZGF0b3Ioa2luZEludDY0KSwgLy8gZ292U3Rha2VyUGN0CgkJCX0sCgkJCWNvbXBvc2l0ZVZhbGlkYXRvcjogZGlzdHJpYnV0aW9uUGN0Q29tcG9zaXRlVmFsaWRhdG9yLAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCWxpcXVpZGl0eVN0YWtlclBjdCA6PSBwYXJzZU51bWJlcihwYXJhbXNbMF0sIGtpbmRJbnQ2NCkuKGludDY0KQoJCQkJZGV2T3BzUGN0IDo9IHBhcnNlTnVtYmVyKHBhcmFtc1sxXSwga2luZEludDY0KS4oaW50NjQpCgkJCQljb21tdW5pdHlQb29sUGN0IDo9IHBhcnNlTnVtYmVyKHBhcmFtc1syXSwga2luZEludDY0KS4oaW50NjQpCgkJCQlnb3ZTdGFrZXJQY3QgOj0gcGFyc2VOdW1iZXIocGFyYW1zWzNdLCBraW5kSW50NjQpLihpbnQ2NCkKCgkJCQllbi5DaGFuZ2VEaXN0cmlidXRpb25QY3QoCgkJCQkJY3Jvc3MocmxtKSwKCQkJCQlsaXF1aWRpdHlTdGFrZXJQY3QsCgkJCQkJZGV2T3BzUGN0LAoJCQkJCWNvbW11bml0eVBvb2xQY3QsCgkJCQkJZ292U3Rha2VyUGN0LAoJCQkJKQoKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoJCS8vIEdvdmVybmFuY2UgY29uZmlndXJhdGlvbiBjaGFuZ2VzCgkJewoJCQlwa2dQYXRoOiAgICBHT1ZfR09WRVJOQU5DRV9QQVRILAoJCQlmdW5jdGlvbjogICAiUmVjb25maWd1cmUiLAoJCQlwYXJhbUNvdW50OiA3LAoJCQlwYXJhbVZhbGlkYXRvcnM6IFtdcGFyYW1WYWxpZGF0b3J7CgkJCQludW1iZXJWYWxpZGF0b3Ioa2luZEludDY0KSwgLy8gdm90aW5nU3RhcnREZWxheQoJCQkJbnVtYmVyVmFsaWRhdG9yKGtpbmRJbnQ2NCksIC8vIHZvdGluZ1BlcmlvZAoJCQkJbnVtYmVyVmFsaWRhdG9yKGtpbmRJbnQ2NCksIC8vIHZvdGluZ1dlaWdodFNtb290aGluZ0R1cmF0aW9uCgkJCQludW1iZXJWYWxpZGF0b3Ioa2luZEludDY0KSwgLy8gcXVvcnVtCgkJCQludW1iZXJWYWxpZGF0b3Ioa2luZEludDY0KSwgLy8gcHJvcG9zYWxDcmVhdGlvblRocmVzaG9sZAoJCQkJbnVtYmVyVmFsaWRhdG9yKGtpbmRJbnQ2NCksIC8vIGV4ZWN1dGlvbkRlbGF5CgkJCQludW1iZXJWYWxpZGF0b3Ioa2luZEludDY0KSwgLy8gZXhlY3V0aW9uV2luZG93CgkJCX0sCgkJCWhhbmRsZXJGdW5jOiBmdW5jKF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBbXXN0cmluZykgZXJyb3IgewoJCQkJLy8gUGFyc2UgZ292ZXJuYW5jZSBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMKCQkJCXZvdGluZ1N0YXJ0RGVsYXkgOj0gcGFyc2VJbnQ2NChwYXJhbXNbMF0pCgkJCQl2b3RpbmdQZXJpb2QgOj0gcGFyc2VJbnQ2NChwYXJhbXNbMV0pCgkJCQl2b3RpbmdXZWlnaHRTbW9vdGhpbmdEdXJhdGlvbiA6PSBwYXJzZUludDY0KHBhcmFtc1syXSkKCQkJCXF1b3J1bSA6PSBwYXJzZUludDY0KHBhcmFtc1szXSkKCQkJCXByb3Bvc2FsQ3JlYXRpb25UaHJlc2hvbGQgOj0gcGFyc2VJbnQ2NChwYXJhbXNbNF0pCgkJCQlleGVjdXRpb25EZWxheSA6PSBwYXJzZUludDY0KHBhcmFtc1s1XSkKCQkJCWV4ZWN1dGlvbldpbmRvdyA6PSBwYXJzZUludDY0KHBhcmFtc1s2XSkKCgkJCQkvLyBSZWNvbmZpZ3VyZSBnb3Zlcm5hbmNlIHBhcmFtZXRlcnMgdGhyb3VnaCBnb3Zlcm5hbmNlIHByb2Nlc3MKCQkJCWdvdmVybmFuY2UuUmVjb25maWd1cmUoCgkJCQkJY3Jvc3MocmxtKSwKCQkJCQl2b3RpbmdTdGFydERlbGF5LAoJCQkJCXZvdGluZ1BlcmlvZCwKCQkJCQl2b3RpbmdXZWlnaHRTbW9vdGhpbmdEdXJhdGlvbiwKCQkJCQlxdW9ydW0sCgkJCQkJcHJvcG9zYWxDcmVhdGlvblRocmVzaG9sZCwKCQkJCQlleGVjdXRpb25EZWxheSwKCQkJCQlleGVjdXRpb25XaW5kb3csCgkJCQkpCgoJCQkJcmV0dXJuIG5pbAoJCQl9LAoJCX0sCgoJCS8vIFBvb2wgcHJvdG9jb2wgZmVlIGNvbmZpZ3VyYXRpb24KCQl7CgkJCXBrZ1BhdGg6ICAgIFBPT0xfUEFUSCwKCQkJZnVuY3Rpb246ICAgIkNvbGxlY3RQcm90b2NvbCIsCgkJCXBhcmFtQ291bnQ6IDYsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCXN0cmluZ1ZhbGlkYXRvciwgIC8vIHRva2VuMFBhdGgKCQkJCXN0cmluZ1ZhbGlkYXRvciwgIC8vIHRva2VuMVBhdGgKCQkJCXVpbnQ2NFZhbGlkYXRvciwgIC8vIGZlZQoJCQkJYWRkcmVzc1ZhbGlkYXRvciwgLy8gcmVjaXBpZW50CgkJCQlub25OZWdhdGl2ZUludDY0VmFsaWRhdG9yKCJhbW91bnQwUmVxdWVzdGVkIiksCgkJCQlub25OZWdhdGl2ZUludDY0VmFsaWRhdG9yKCJhbW91bnQxUmVxdWVzdGVkIiksCgkJCX0sCgkJCWhhbmRsZXJGdW5jOiBmdW5jKF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBbXXN0cmluZykgZXJyb3IgewoJCQkJcGwuQ29sbGVjdFByb3RvY29sKAoJCQkJCWNyb3NzKHJsbSksCgkJCQkJcGFyYW1zWzBdLCAgICAgICAgICAgICAgICAgICAgICAvLyB0b2tlbjBQYXRoCgkJCQkJcGFyYW1zWzFdLCAgICAgICAgICAgICAgICAgICAgICAvLyB0b2tlbjFQYXRoCgkJCQkJdWludDMyKHBhcnNlVWludDY0KHBhcmFtc1syXSkpLCAvLyBmZWUKCQkJCQlhZGRyZXNzKHBhcmFtc1szXSksICAgICAgICAgICAgIC8vIHJlY2lwaWVudAoJCQkJCXBhcmFtc1s0XSwgICAgICAgICAgICAgICAgICAgICAgLy8gYW1vdW50MFJlcXVlc3RlZAoJCQkJCXBhcmFtc1s1XSwgICAgICAgICAgICAgICAgICAgICAgLy8gYW1vdW50MVJlcXVlc3RlZAoJCQkJKQoKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoJCXsKCQkJcGtnUGF0aDogICAgUE9PTF9QQVRILAoJCQlmdW5jdGlvbjogICAiU2V0RmVlUHJvdG9jb2wiLAoJCQlwYXJhbUNvdW50OiAyLAoJCQlwYXJhbVZhbGlkYXRvcnM6IFtdcGFyYW1WYWxpZGF0b3J7CgkJCQl1aW50OFJhbmdlVmFsaWRhdG9yKCJmZWVQcm90b2NvbDAiKSwKCQkJCXVpbnQ4UmFuZ2VWYWxpZGF0b3IoImZlZVByb3RvY29sMSIpLAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIFBhcnNlIGFuZCB2YWxpZGF0ZSBmZWUgcHJvdG9jb2wgdmFsdWVzCgkJCQlmZWVQcm90b2NvbDAgOj0gcGFyc2VJbnQ2NChwYXJhbXNbMF0pCgkJCQlmZWVQcm90b2NvbDEgOj0gcGFyc2VJbnQ2NChwYXJhbXNbMV0pCgoJCQkJLy8gVmFsaWRhdGUgZmVlIHByb3RvY29sIHZhbHVlcyBhcmUgd2l0aGluIHVpbnQ4IHJhbmdlCgkJCQlpZiBmZWVQcm90b2NvbDAgPiAyNTUgewoJCQkJCXBhbmljKHVmbXQuU3ByaW50ZigiZmVlUHJvdG9jb2wwIG91dCBvZiByYW5nZTogJWQiLCBmZWVQcm90b2NvbDApKQoJCQkJfQoKCQkJCWlmIGZlZVByb3RvY29sMSA+IDI1NSB7CgkJCQkJcGFuaWModWZtdC5TcHJpbnRmKCJmZWVQcm90b2NvbDEgb3V0IG9mIHJhbmdlOiAlZCIsIGZlZVByb3RvY29sMSkpCgkJCQl9CgoJCQkJLy8gU2V0IHByb3RvY29sIGZlZSBwZXJjZW50YWdlcwoJCQkJcGwuU2V0RmVlUHJvdG9jb2woCgkJCQkJY3Jvc3MocmxtKSwKCQkJCQl1aW50OChmZWVQcm90b2NvbDApLCAvLyBmZWVQcm90b2NvbDAKCQkJCQl1aW50OChmZWVQcm90b2NvbDEpLCAvLyBmZWVQcm90b2NvbDEKCQkJCSkKCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCQkvLyBQb29sIGNyZWF0aW9uIGZlZQoJCXsKCQkJcGtnUGF0aDogICAgUE9PTF9QQVRILAoJCQlmdW5jdGlvbjogICAiU2V0UG9vbENyZWF0aW9uRmVlIiwKCQkJcGFyYW1Db3VudDogMSwKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJbm9uTmVnYXRpdmVJbnQ2NFZhbGlkYXRvcigiZmVlIiksCgkJCX0sCgkJCWhhbmRsZXJGdW5jOiBmdW5jKF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBbXXN0cmluZykgZXJyb3IgewoJCQkJLy8gU2V0IGZlZSByZXF1aXJlZCB0byBjcmVhdGUgbmV3IHBvb2xzCgkJCQlwbC5TZXRQb29sQ3JlYXRpb25GZWUoY3Jvc3MocmxtKSwgcGFyc2VJbnQ2NChwYXJhbXNbMF0pKSAvLyBmZWUKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoJCS8vIFBvb2wgd2l0aGRyYXdhbCBmZWUKCQl7CgkJCXBrZ1BhdGg6ICAgIFBPT0xfUEFUSCwKCQkJZnVuY3Rpb246ICAgIlNldFdpdGhkcmF3YWxGZWUiLAoJCQlwYXJhbUNvdW50OiAxLAoJCQlwYXJhbVZhbGlkYXRvcnM6IFtdcGFyYW1WYWxpZGF0b3J7CgkJCQl1aW50NjRSYW5nZVZhbGlkYXRvcigiZmVlIiwgMTAwMCksCgkJCX0sCgkJCWhhbmRsZXJGdW5jOiBmdW5jKF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBbXXN0cmluZykgZXJyb3IgewoJCQkJLy8gU2V0IGZlZSBmb3Igd2l0aGRyYXdpbmcgZnJvbSBwb29scwoJCQkJcGwuU2V0V2l0aGRyYXdhbEZlZShjcm9zcyhybG0pLCBwYXJzZVVpbnQ2NChwYXJhbXNbMF0pKSAvLyBmZWUKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoKCQkvLyBQcm90b2NvbCBmZWUgZGlzdHJpYnV0aW9uCgkJewoJCQlwa2dQYXRoOiAgICBQUk9UT0NPTF9GRUVfUEFUSCwKCQkJZnVuY3Rpb246ICAgIlNldERldk9wc1BjdCIsCgkJCXBhcmFtQ291bnQ6IDEsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCWludDY0UmFuZ2VWYWxpZGF0b3IoInBjdCIsIDAsIDEwMDAwKSwKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQkvLyBTZXQgcGVyY2VudGFnZSBvZiBwcm90b2NvbCBmZWVzIGdvaW5nIHRvIGRldmVsb3BtZW50IG9wZXJhdGlvbnMKCQkJCXBmLlNldERldk9wc1BjdChjcm9zcyhybG0pLCBwYXJzZUludDY0KHBhcmFtc1swXSkpIC8vIHBjdAoJCQkJcmV0dXJuIG5pbAoJCQl9LAoJCX0sCgoJCS8vIFJvdXRlciBzd2FwIGZlZQoJCXsKCQkJcGtnUGF0aDogICAgUk9VVEVSX1BBVEgsCgkJCWZ1bmN0aW9uOiAgICJTZXRTd2FwRmVlIiwKCQkJcGFyYW1Db3VudDogMSwKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJdWludDY0UmFuZ2VWYWxpZGF0b3IoImZlZSIsIDEwMDApLAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIFNldCBmZWUgY2hhcmdlZCBmb3IgdG9rZW4gc3dhcHMKCQkJCXJyLlNldFN3YXBGZWUoY3Jvc3MocmxtKSwgcGFyc2VVaW50NjQocGFyYW1zWzBdKSkgLy8gZmVlCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCgkJLy8gU3Rha2VyIGNvbmZpZ3VyYXRpb24gaGFuZGxlcnMKCQl7CgkJCXBrZ1BhdGg6ICAgIFNUQUtFUl9QQVRILAoJCQlmdW5jdGlvbjogICAiU2V0RGVwb3NpdEduc0Ftb3VudCIsCgkJCXBhcmFtQ291bnQ6IDEsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCW5vbk5lZ2F0aXZlSW50NjRWYWxpZGF0b3IoImFtb3VudCIpLAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIFNldCBtaW5pbXVtIEdOUyBhbW91bnQgcmVxdWlyZWQgZm9yIHN0YWtpbmcgZGVwb3NpdHMKCQkJCXNyLlNldERlcG9zaXRHbnNBbW91bnQoY3Jvc3MocmxtKSwgcGFyc2VJbnQ2NChwYXJhbXNbMF0pKSAvLyBhbW91bnQKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoJCXsKCQkJcGtnUGF0aDogICAgU1RBS0VSX1BBVEgsCgkJCWZ1bmN0aW9uOiAgICJTZXRNaW5pbXVtUmV3YXJkQW1vdW50IiwKCQkJcGFyYW1Db3VudDogMSwKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJbm9uTmVnYXRpdmVJbnQ2NFZhbGlkYXRvcigiYW1vdW50IiksCgkJCX0sCgkJCWhhbmRsZXJGdW5jOiBmdW5jKF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBbXXN0cmluZykgZXJyb3IgewoJCQkJLy8gU2V0IG1pbmltdW0gR05TIGFtb3VudCByZXF1aXJlZCBmb3Igc3Rha2luZyBkZXBvc2l0cwoJCQkJc3IuU2V0TWluaW11bVJld2FyZEFtb3VudChjcm9zcyhybG0pLCBwYXJzZUludDY0KHBhcmFtc1swXSkpIC8vIGFtb3VudAoJCQkJcmV0dXJuIG5pbAoJCQl9LAoJCX0sCgkJewoJCQlwa2dQYXRoOiAgICBTVEFLRVJfUEFUSCwKCQkJZnVuY3Rpb246ICAgIlNldFRva2VuTWluaW11bVJld2FyZEFtb3VudCIsCgkJCXBhcmFtQ291bnQ6IDEsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCXRva2VuTWluaW11bVJld2FyZEFtb3VudFZhbGlkYXRvciwKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQkvLyBTZXQgbWluaW11bSBHTlMgYW1vdW50IHJlcXVpcmVkIGZvciBzdGFraW5nIGRlcG9zaXRzCgkJCQkvLyBwYXJhbXNbMF0gaXMgYSBzdHJpbmcgaW4gdGhlIGZvcm1hdCAidG9rZW5QYXRoOmFtb3VudCIKCQkJCXNyLlNldFRva2VuTWluaW11bVJld2FyZEFtb3VudChjcm9zcyhybG0pLCBwYXJhbXNbMF0pIC8vIGFtb3VudAoJCQkJcmV0dXJuIG5pbAoJCQl9LAoJCX0sCgkJewoJCQlwa2dQYXRoOiAgICBTVEFLRVJfUEFUSCwKCQkJZnVuY3Rpb246ICAgIlNldFBvb2xUaWVyIiwKCQkJcGFyYW1Db3VudDogMiwKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJc3RyaW5nVmFsaWRhdG9yLCAvLyBwb29sCgkJCQl1aW50NjRSYW5nZVZhbGlkYXRvcigidGllciIsIHNyLkFsbFRpZXJDb3VudC0xKSwKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQkvLyBBc3NpZ24gdGllciBsZXZlbCB0byBhIHNwZWNpZmljIHBvb2wKCQkJCXNyLlNldFBvb2xUaWVyKAoJCQkJCWNyb3NzKHJsbSksCgkJCQkJcGFyYW1zWzBdLCAgICAgICAgICAgICAgLy8gcG9vbAoJCQkJCXBhcnNlVWludDY0KHBhcmFtc1sxXSksIC8vIHRpZXIKCQkJCSkKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoJCXsKCQkJcGtnUGF0aDogICAgU1RBS0VSX1BBVEgsCgkJCWZ1bmN0aW9uOiAgICJDaGFuZ2VQb29sVGllciIsCgkJCXBhcmFtQ291bnQ6IDIsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCXN0cmluZ1ZhbGlkYXRvciwgLy8gcG9vbAoJCQkJdWludDY0UmFuZ2VWYWxpZGF0b3IoInRpZXIiLCBzci5BbGxUaWVyQ291bnQtMSksCgkJCX0sCgkJCWhhbmRsZXJGdW5jOiBmdW5jKF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBbXXN0cmluZykgZXJyb3IgewoJCQkJLy8gQ2hhbmdlIGV4aXN0aW5nIHBvb2wncyB0aWVyIGxldmVsCgkJCQlzci5DaGFuZ2VQb29sVGllcigKCQkJCQljcm9zcyhybG0pLAoJCQkJCXBhcmFtc1swXSwgICAgICAgICAgICAgIC8vIHBvb2wKCQkJCQlwYXJzZVVpbnQ2NChwYXJhbXNbMV0pLCAvLyB0aWVyCgkJCQkpCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCQl7CgkJCXBrZ1BhdGg6ICAgIFNUQUtFUl9QQVRILAoJCQlmdW5jdGlvbjogICAiUmVtb3ZlUG9vbFRpZXIiLAoJCQlwYXJhbUNvdW50OiAxLAoJCQlwYXJhbVZhbGlkYXRvcnM6IFtdcGFyYW1WYWxpZGF0b3J7CgkJCQlzdHJpbmdWYWxpZGF0b3IsIC8vIHBvb2wKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQkvLyBSZW1vdmUgdGllciBhc3NpZ25tZW50IGZyb20gYSBwb29sCgkJCQlzci5SZW1vdmVQb29sVGllcihjcm9zcyhybG0pLCBwYXJhbXNbMF0pIC8vIHBvb2wKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoJCXsKCQkJcGtnUGF0aDogICAgU1RBS0VSX1BBVEgsCgkJCWZ1bmN0aW9uOiAgICJTZXRVblN0YWtpbmdGZWUiLAoJCQlwYXJhbUNvdW50OiAxLAoJCQlwYXJhbVZhbGlkYXRvcnM6IFtdcGFyYW1WYWxpZGF0b3J7CgkJCQl1aW50NjRSYW5nZVZhbGlkYXRvcigiZmVlIiwgMTAwMCksCgkJCX0sCgkJCWhhbmRsZXJGdW5jOiBmdW5jKF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBbXXN0cmluZykgZXJyb3IgewoJCQkJLy8gU2V0IGZlZSBjaGFyZ2VkIGZvciB1bnN0YWtpbmcgb3BlcmF0aW9ucwoJCQkJZmVlIDo9IHBhcnNlVWludDY0KHBhcmFtc1swXSkKCQkJCXNyLlNldFVuU3Rha2luZ0ZlZShjcm9zcyhybG0pLCBmZWUpCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCQl7CgkJCXBrZ1BhdGg6ICAgIFNUQUtFUl9QQVRILAoJCQlmdW5jdGlvbjogICAiU2V0V2FybVVwIiwKCQkJcGFyYW1Db3VudDogMiwKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJbnVtYmVyVmFsaWRhdG9yKGtpbmRJbnQ2NCksIC8vIHBlcmNlbnQKCQkJCW51bWJlclZhbGlkYXRvcihraW5kSW50NjQpLCAvLyBibG9jawoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIFNldCB3YXJtLXVwIHBlcmlvZCBjb25maWd1cmF0aW9uIGZvciBzdGFraW5nCgkJCQlwZXJjZW50IDo9IHBhcnNlSW50NjQocGFyYW1zWzBdKQoJCQkJYmxvY2sgOj0gcGFyc2VOdW1iZXIocGFyYW1zWzFdLCBraW5kSW50NjQpLihpbnQ2NCkKCQkJCXNyLlNldFdhcm1VcChjcm9zcyhybG0pLCBwZXJjZW50LCBibG9jaykKCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCgkJLy8gU3lzdGVtIGhhbHQgY29udHJvbHMKCQl7CgkJCXBrZ1BhdGg6ICAgIEhBTFRfUEFUSCwKCQkJZnVuY3Rpb246ICAgIlNldEhhbHRMZXZlbCIsCgkJCXBhcmFtQ291bnQ6IDEsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCWhhbHRMZXZlbFZhbGlkYXRvciwKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQkvLyBTZXQgc3lzdGVtLXdpZGUgaGFsdCBzdGF0dXMKCQkJCWhhbHQuU2V0SGFsdExldmVsKGNyb3NzKHJsbSksIGhhbHQuSGFsdExldmVsKHBhcmFtc1swXSkpIC8vIHRydWUgPSBoYWx0LCBmYWxzZSA9IG5vIGhhbHQKCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCQl7CgkJCXBrZ1BhdGg6ICAgIEhBTFRfUEFUSCwKCQkJZnVuY3Rpb246ICAgIlNldE9wZXJhdGlvblN0YXR1cyIsCgkJCXBhcmFtQ291bnQ6IDIsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCWhhbHRPcGVyYXRpb25UeXBlVmFsaWRhdG9yLAoJCQkJYm9vbFZhbGlkYXRvciwgLy8gYWxsb3dlZAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIEVuYWJsZSBvciBkaXNhYmxlIHNwZWNpZmljIG9wZXJhdGlvbiB0eXBlcwoJCQkJb3BUeXBlIDo9IGhhbHQuT3BUeXBlKHBhcmFtc1swXSkKCQkJCWFsbG93ZWQgOj0gcGFyc2VCb29sKHBhcmFtc1sxXSkKCgkJCQloYWx0LlNldE9wZXJhdGlvblN0YXR1cyhjcm9zcyhybG0pLCBvcFR5cGUsIGFsbG93ZWQpCgoJCQkJcmV0dXJuIG5pbAoJCQl9LAoJCX0sCgoJCS8vIFJCQUMgY29uZmlndXJhdGlvbgoJCXsKCQkJcGtnUGF0aDogICAgUkJBQ19QQVRILAoJCQlmdW5jdGlvbjogICAiUmVnaXN0ZXJSb2xlIiwKCQkJcGFyYW1Db3VudDogMiwKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJcm9sZU5hbWVWYWxpZGF0b3IsCgkJCQlhZGRyZXNzVmFsaWRhdG9yLCAvLyByb2xlQWRkcmVzcwoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCXJvbGVOYW1lIDo9IHBhcmFtc1swXQoJCQkJcm9sZUFkZHJlc3MgOj0gYWRkcmVzcyhwYXJhbXNbMV0pCgoJCQkJLy8gUmVnaXN0ZXIgYSBuZXcgcm9sZQoJCQkJcmJhYy5SZWdpc3RlclJvbGUoY3Jvc3MocmxtKSwgcm9sZU5hbWUsIHJvbGVBZGRyZXNzKQoKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoJCXsKCQkJcGtnUGF0aDogICAgUkJBQ19QQVRILAoJCQlmdW5jdGlvbjogICAiVXBkYXRlUm9sZUFkZHJlc3MiLAoJCQlwYXJhbUNvdW50OiAyLAoJCQlwYXJhbVZhbGlkYXRvcnM6IFtdcGFyYW1WYWxpZGF0b3J7CgkJCQl1cGRhdGFibGVSb2xlTmFtZVZhbGlkYXRvciwKCQkJCWFkZHJlc3NWYWxpZGF0b3IsIC8vIHJvbGVBZGRyZXNzCgkJCX0sCgkJCWhhbmRsZXJGdW5jOiBmdW5jKF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBbXXN0cmluZykgZXJyb3IgewoJCQkJcm9sZU5hbWUgOj0gcGFyYW1zWzBdCgkJCQlyb2xlQWRkcmVzcyA6PSBhZGRyZXNzKHBhcmFtc1sxXSkKCgkJCQkvLyBVcGRhdGUgcm9sZSBhZGRyZXNzCgkJCQlyYmFjLlVwZGF0ZVJvbGVBZGRyZXNzKGNyb3NzKHJsbSksIHJvbGVOYW1lLCByb2xlQWRkcmVzcykKCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCQl7CgkJCXBrZ1BhdGg6ICAgIFJCQUNfUEFUSCwKCQkJZnVuY3Rpb246ICAgIlJlbW92ZVJvbGUiLAoJCQlwYXJhbUNvdW50OiAxLAoJCQlwYXJhbVZhbGlkYXRvcnM6IFtdcGFyYW1WYWxpZGF0b3J7CgkJCQlyZW1vdmFibGVSb2xlTmFtZVZhbGlkYXRvciwKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQlyb2xlTmFtZSA6PSBwYXJhbXNbMF0KCgkJCQkvLyBSZW1vdmUgcm9sZQoJCQkJcmJhYy5SZW1vdmVSb2xlKGNyb3NzKHJsbSksIHJvbGVOYW1lKQoKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoKCQkvLyBQcm90b2NvbCBmZWUgLSBTZXRHb3ZTdGFrZXJQY3QKCQl7CgkJCXBrZ1BhdGg6ICAgIFBST1RPQ09MX0ZFRV9QQVRILAoJCQlmdW5jdGlvbjogICAiU2V0R292U3Rha2VyUGN0IiwKCQkJcGFyYW1Db3VudDogMSwKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJaW50NjRSYW5nZVZhbGlkYXRvcigicGN0IiwgMCwgMTAwMDApLAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIFNldCBwZXJjZW50YWdlIG9mIHByb3RvY29sIGZlZXMgZ29pbmcgdG8gZ292ZXJuYW5jZSBzdGFrZXJzCgkJCQlwZi5TZXRHb3ZTdGFrZXJQY3QoY3Jvc3MocmxtKSwgcGFyc2VJbnQ2NChwYXJhbXNbMF0pKSAvLyBwY3QKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoKCQkvLyBTdGFrZXIgLSBUb2tlbiBsaXN0IG1hbmFnZW1lbnQKCQl7CgkJCXBrZ1BhdGg6ICAgIFNUQUtFUl9QQVRILAoJCQlmdW5jdGlvbjogICAiQWRkVG9rZW4iLAoJCQlwYXJhbUNvdW50OiAxLAoJCQlwYXJhbVZhbGlkYXRvcnM6IFtdcGFyYW1WYWxpZGF0b3J7CgkJCQlzdHJpbmdWYWxpZGF0b3IsIC8vIHRva2VuUGF0aAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIEFkZCB0b2tlbiB0byBhbGxvd2VkIHRva2VuIGxpc3QgZm9yIGV4dGVybmFsIGluY2VudGl2ZXMKCQkJCXNyLkFkZFRva2VuKGNyb3NzKHJsbSksIHBhcmFtc1swXSkgLy8gdG9rZW5QYXRoCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCQl7CgkJCXBrZ1BhdGg6ICAgIFNUQUtFUl9QQVRILAoJCQlmdW5jdGlvbjogICAiUmVtb3ZlVG9rZW4iLAoJCQlwYXJhbUNvdW50OiAxLAoJCQlwYXJhbVZhbGlkYXRvcnM6IFtdcGFyYW1WYWxpZGF0b3J7CgkJCQlzdHJpbmdWYWxpZGF0b3IsIC8vIHRva2VuUGF0aAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIFJlbW92ZSB0b2tlbiBmcm9tIGFsbG93ZWQgdG9rZW4gbGlzdAoJCQkJc3IuUmVtb3ZlVG9rZW4oY3Jvc3MocmxtKSwgcGFyYW1zWzBdKSAvLyB0b2tlblBhdGgKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoJCXsKCQkJcGtnUGF0aDogICAgU1RBS0VSX1BBVEgsCgkJCWZ1bmN0aW9uOiAgICJTZXREZW5pZWRSZXdhcmRUb2tlbiIsCgkJCXBhcmFtQ291bnQ6IDIsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCXN0cmluZ1ZhbGlkYXRvciwgLy8gdG9rZW5QYXRoCgkJCQlib29sVmFsaWRhdG9yLCAgIC8vIGRlbmllZAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIERlbnkgb3IgcmUtYWxsb3cgYSB0b2tlbiBhcyBhbiBleHRlcm5hbCBpbmNlbnRpdmUgcmV3YXJkIHRva2VuCgkJCQlzci5TZXREZW5pZWRSZXdhcmRUb2tlbihjcm9zcyhybG0pLCBwYXJhbXNbMF0sIHBhcnNlQm9vbChwYXJhbXNbMV0pKQoJCQkJcmV0dXJuIG5pbAoJCQl9LAoJCX0sCgoJCS8vIFN0YWtlciAtIEV4dGVybmFsIGluY2VudGl2ZSByZWNvdmVyeQoJCXsKCQkJcGtnUGF0aDogICAgU1RBS0VSX1BBVEgsCgkJCWZ1bmN0aW9uOiAgICJDYW5jZWxFeHRlcm5hbEluY2VudGl2ZSIsCgkJCXBhcmFtQ291bnQ6IDIsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCXN0cmluZ1ZhbGlkYXRvciwgLy8gdGFyZ2V0UG9vbFBhdGgKCQkJCXN0cmluZ1ZhbGlkYXRvciwgLy8gaW5jZW50aXZlSWQKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQkvLyBDYW5jZWwgYSBub3QteWV0LXN0YXJ0ZWQgZXh0ZXJuYWwgaW5jZW50aXZlOyB0aGUgcmV3YXJkIHRva2VucwoJCQkJLy8gYW5kIHRoZSBHTlMgZGVwb3NpdCBhcmUgcmVmdW5kZWQgdG8gdGhlIGluY2VudGl2ZSBjcmVhdG9yCgkJCQlzci5DYW5jZWxFeHRlcm5hbEluY2VudGl2ZSgKCQkJCQljcm9zcyhybG0pLAoJCQkJCXBhcmFtc1swXSwgLy8gdGFyZ2V0UG9vbFBhdGgKCQkJCQlwYXJhbXNbMV0sIC8vIGluY2VudGl2ZUlkCgkJCQkpCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCgkJLy8gTGF1bmNocGFkIC0gUHJvamVjdCBtYW5hZ2VtZW50CgkJewoJCQlwa2dQYXRoOiAgICBMQVVOQ0hQQURfUEFUSCwKCQkJZnVuY3Rpb246ICAgIkNyZWF0ZVByb2plY3QiLAoJCQlwYXJhbUNvdW50OiAxMCwKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJc3RyaW5nVmFsaWRhdG9yLCAgICAgICAgICAgIC8vIG5hbWUKCQkJCXN0cmluZ1ZhbGlkYXRvciwgICAgICAgICAgICAvLyB0b2tlblBhdGgKCQkJCWFkZHJlc3NWYWxpZGF0b3IsICAgICAgICAgICAvLyByZWNpcGllbnQKCQkJCW51bWJlclZhbGlkYXRvcihraW5kSW50NjQpLCAvLyBkZXBvc2l0QW1vdW50CgkJCQlzdHJpbmdWYWxpZGF0b3IsICAgICAgICAgICAgLy8gY29uZGl0aW9uVG9rZW5zCgkJCQlzdHJpbmdWYWxpZGF0b3IsICAgICAgICAgICAgLy8gY29uZGl0aW9uQW1vdW50cwoJCQkJbnVtYmVyVmFsaWRhdG9yKGtpbmRJbnQ2NCksIC8vIHRpZXIzMFJhdGlvCgkJCQludW1iZXJWYWxpZGF0b3Ioa2luZEludDY0KSwgLy8gdGllcjkwUmF0aW8KCQkJCW51bWJlclZhbGlkYXRvcihraW5kSW50NjQpLCAvLyB0aWVyMTgwUmF0aW8KCQkJCW51bWJlclZhbGlkYXRvcihraW5kSW50NjQpLCAvLyBzdGFydFRpbWUKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQkvLyBDcmVhdGUgYSBuZXcgbGF1bmNocGFkIHByb2plY3QKCQkJCWxwLkNyZWF0ZVByb2plY3QoCgkJCQkJY3Jvc3MocmxtKSwKCQkJCQlwYXJhbXNbMF0sICAgICAgICAgIC8vIG5hbWUKCQkJCQlwYXJhbXNbMV0sICAgICAgICAgIC8vIHRva2VuUGF0aAoJCQkJCWFkZHJlc3MocGFyYW1zWzJdKSwgLy8gcmVjaXBpZW50CgkJCQkJcGFyc2VOdW1iZXIocGFyYW1zWzNdLCBraW5kSW50NjQpLihpbnQ2NCksIC8vIGRlcG9zaXRBbW91bnQKCQkJCQlwYXJhbXNbNF0sIC8vIGNvbmRpdGlvblRva2VucwoJCQkJCXBhcmFtc1s1XSwgLy8gY29uZGl0aW9uQW1vdW50cwoJCQkJCXBhcnNlTnVtYmVyKHBhcmFtc1s2XSwga2luZEludDY0KS4oaW50NjQpLCAvLyB0aWVyMzBSYXRpbwoJCQkJCXBhcnNlTnVtYmVyKHBhcmFtc1s3XSwga2luZEludDY0KS4oaW50NjQpLCAvLyB0aWVyOTBSYXRpbwoJCQkJCXBhcnNlTnVtYmVyKHBhcmFtc1s4XSwga2luZEludDY0KS4oaW50NjQpLCAvLyB0aWVyMTgwUmF0aW8KCQkJCQlwYXJzZU51bWJlcihwYXJhbXNbOV0sIGtpbmRJbnQ2NCkuKGludDY0KSwgLy8gc3RhcnRUaW1lCgkJCQkpCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCQkvLyBVcGdyYWRlIGhhbmRsZXJzIGZvciB2YXJpb3VzIGRvbWFpbnMKCQl7CgkJCXBrZ1BhdGg6ICAgIFBPT0xfUEFUSCwKCQkJZnVuY3Rpb246ICAgIlVwZ3JhZGVJbXBsIiwKCQkJcGFyYW1Db3VudDogMSwKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJc3RyaW5nVmFsaWRhdG9yLCAvLyBwYWNrYWdlUGF0aAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIFVwZ3JhZGUgcG9vbCBpbXBsZW1lbnRhdGlvbgoJCQkJcGwuVXBncmFkZUltcGwoY3Jvc3MocmxtKSwgcGFyYW1zWzBdKSAvLyBwYWNrYWdlUGF0aAoJCQkJcmV0dXJuIG5pbAoJCQl9LAoJCX0sCgkJewoJCQlwa2dQYXRoOiAgICBQT1NJVElPTl9QQVRILAoJCQlmdW5jdGlvbjogICAiVXBncmFkZUltcGwiLAoJCQlwYXJhbUNvdW50OiAxLAoJCQlwYXJhbVZhbGlkYXRvcnM6IFtdcGFyYW1WYWxpZGF0b3J7CgkJCQlzdHJpbmdWYWxpZGF0b3IsIC8vIHBhY2thZ2VQYXRoCgkJCX0sCgkJCWhhbmRsZXJGdW5jOiBmdW5jKF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBbXXN0cmluZykgZXJyb3IgewoJCQkJLy8gVXBncmFkZSBwb3NpdGlvbiBpbXBsZW1lbnRhdGlvbgoJCQkJcG9zLlVwZ3JhZGVJbXBsKGNyb3NzKHJsbSksIHBhcmFtc1swXSkgLy8gcGFja2FnZVBhdGgKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoJCXsKCQkJcGtnUGF0aDogICAgU1RBS0VSX1BBVEgsCgkJCWZ1bmN0aW9uOiAgICJVcGdyYWRlSW1wbCIsCgkJCXBhcmFtQ291bnQ6IDEsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCXN0cmluZ1ZhbGlkYXRvciwgLy8gcGFja2FnZVBhdGgKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQkvLyBVcGdyYWRlIHN0YWtlciBpbXBsZW1lbnRhdGlvbgoJCQkJc3IuVXBncmFkZUltcGwoY3Jvc3MocmxtKSwgcGFyYW1zWzBdKSAvLyBwYWNrYWdlUGF0aAoJCQkJcmV0dXJuIG5pbAoJCQl9LAoJCX0sCgkJewoJCQlwa2dQYXRoOiAgICBMQVVOQ0hQQURfUEFUSCwKCQkJZnVuY3Rpb246ICAgIlVwZ3JhZGVJbXBsIiwKCQkJcGFyYW1Db3VudDogMSwKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJc3RyaW5nVmFsaWRhdG9yLCAvLyBwYWNrYWdlUGF0aAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIFVwZ3JhZGUgbGF1bmNocGFkIGltcGxlbWVudGF0aW9uCgkJCQlscC5VcGdyYWRlSW1wbChjcm9zcyhybG0pLCBwYXJhbXNbMF0pIC8vIHBhY2thZ2VQYXRoCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCQl7CgkJCXBrZ1BhdGg6ICAgIEdPVl9HT1ZFUk5BTkNFX1BBVEgsCgkJCWZ1bmN0aW9uOiAgICJVcGdyYWRlSW1wbCIsCgkJCXBhcmFtQ291bnQ6IDEsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCXN0cmluZ1ZhbGlkYXRvciwgLy8gdGFyZ2V0UGFja2FnZVBhdGgKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQkvLyBVcGdyYWRlIGdvdmVybmFuY2UgaW1wbGVtZW50YXRpb24KCQkJCWdvdmVybmFuY2UuVXBncmFkZUltcGwoY3Jvc3MocmxtKSwgcGFyYW1zWzBdKSAvLyBwYWNrYWdlUGF0aAoJCQkJcmV0dXJuIG5pbAoJCQl9LAoJCX0sCgkJewoJCQlwa2dQYXRoOiAgICBHT1ZfU1RBS0VSX1BBVEgsCgkJCWZ1bmN0aW9uOiAgICJVcGdyYWRlSW1wbCIsCgkJCXBhcmFtQ291bnQ6IDEsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCXN0cmluZ1ZhbGlkYXRvciwgLy8gcGFja2FnZVBhdGgKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQkvLyBVcGdyYWRlIGdvdiBzdGFrZXIgaW1wbGVtZW50YXRpb24KCQkJCWdzLlVwZ3JhZGVJbXBsKGNyb3NzKHJsbSksIHBhcmFtc1swXSkgLy8gcGFja2FnZVBhdGgKCQkJCXJldHVybiBuaWwKCQkJfSwKCQl9LAoJCXsKCQkJcGtnUGF0aDogICAgUk9VVEVSX1BBVEgsCgkJCWZ1bmN0aW9uOiAgICJVcGdyYWRlSW1wbCIsCgkJCXBhcmFtQ291bnQ6IDEsCgkJCXBhcmFtVmFsaWRhdG9yczogW11wYXJhbVZhbGlkYXRvcnsKCQkJCXN0cmluZ1ZhbGlkYXRvciwgLy8gcGFja2FnZVBhdGgKCQkJfSwKCQkJaGFuZGxlckZ1bmM6IGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIFtdc3RyaW5nKSBlcnJvciB7CgkJCQkvLyBVcGdyYWRlIHJvdXRlciBpbXBsZW1lbnRhdGlvbgoJCQkJcnIuVXBncmFkZUltcGwoY3Jvc3MocmxtKSwgcGFyYW1zWzBdKSAvLyBwYWNrYWdlUGF0aAoJCQkJcmV0dXJuIG5pbAoJCQl9LAoJCX0sCgkJewoJCQlwa2dQYXRoOiAgICBQUk9UT0NPTF9GRUVfUEFUSCwKCQkJZnVuY3Rpb246ICAgIlVwZ3JhZGVJbXBsIiwKCQkJcGFyYW1Db3VudDogMSwKCQkJcGFyYW1WYWxpZGF0b3JzOiBbXXBhcmFtVmFsaWRhdG9yewoJCQkJc3RyaW5nVmFsaWRhdG9yLCAvLyBwYWNrYWdlUGF0aAoJCQl9LAoJCQloYW5kbGVyRnVuYzogZnVuYyhfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCQkJCS8vIFVwZ3JhZGUgcHJvdG9jb2wgZmVlIGltcGxlbWVudGF0aW9uCgkJCQlwZi5VcGdyYWRlSW1wbChjcm9zcyhybG0pLCBwYXJhbXNbMF0pIC8vIHBhY2thZ2VQYXRoCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCQl7CgkJCXBrZ1BhdGg6ICAgIENPTU1PTl9QQVRILAoJCQlmdW5jdGlvbjogICAiVXBncmFkZUltcGwiLAoJCQlwYXJhbUNvdW50OiAxLAoJCQlwYXJhbVZhbGlkYXRvcnM6IFtdcGFyYW1WYWxpZGF0b3J7CgkJCQlzdHJpbmdWYWxpZGF0b3IsIC8vIHBhY2thZ2VQYXRoCgkJCX0sCgkJCWhhbmRsZXJGdW5jOiBmdW5jKF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBbXXN0cmluZykgZXJyb3IgewoJCQkJLy8gVXBncmFkZSBjb21tb24gKHRva2VuIHJlc29sdXRpb24pIGltcGxlbWVudGF0aW9uCgkJCQljbS5VcGdyYWRlSW1wbChjcm9zcyhybG0pLCBwYXJhbXNbMF0pIC8vIHBhY2thZ2VQYXRoCgkJCQlyZXR1cm4gbmlsCgkJCX0sCgkJfSwKCX0KCgkvLyBSZWdpc3RlciBhbGwgY29uZmlndXJlZCBoYW5kbGVycyBpbiB0aGUgcmVnaXN0cnkKCXJlZ2lzdGVySGFuZGxlcnMocmVnaXN0cnksIGhhbmRsZXJzKQoKCXJldHVybiByZWdpc3RyeQp9CgovLyByZWdpc3RlckhhbmRsZXJzIGJhdGNoIHJlZ2lzdGVycyBhbGwgY29uZmlndXJlZCBoYW5kbGVycyBpbnRvIHRoZSByZWdpc3RyeS4KLy8gVGhpcyBoZWxwZXIgZnVuY3Rpb24gcHJvY2Vzc2VzIHRoZSBoYW5kbGVyIGNvbmZpZ3VyYXRpb24gYXJyYXkgYW5kIGFkZHMgZWFjaCBoYW5kbGVyIHRvIHRoZSByZWdpc3RyeS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHJlZ2lzdHJ5OiB0aGUgcGFyYW1ldGVyIHJlZ2lzdHJ5IHRvIGFkZCBoYW5kbGVycyB0bwovLyAgIC0gaGFuZGxlck9wdGlvbnM6IHNsaWNlIG9mIGhhbmRsZXIgY29uZmlndXJhdGlvbnMgdG8gcmVnaXN0ZXIKZnVuYyByZWdpc3RlckhhbmRsZXJzKHJlZ2lzdHJ5ICpQYXJhbWV0ZXJSZWdpc3RyeSwgaGFuZGxlck9wdGlvbnMgW10qUGFyYW1ldGVySGFuZGxlck9wdGlvbnMpIHsKCWZvciBfLCBoYW5kbGVyT3B0aW9uIDo9IHJhbmdlIGhhbmRsZXJPcHRpb25zIHsKCQlyZWdpc3RyeS5SZWdpc3RlcigqaGFuZGxlck9wdGlvbikKCX0KfQoKLy8gcnVuVmFsaWRhdG9yIGV4ZWN1dGVzIGEgdmFsaWRhdG9yIGZ1bmN0aW9uIGFuZCBjb252ZXJ0cyBwYW5pY3MgdG8gZXJyb3JzLgpmdW5jIHJ1blZhbGlkYXRvcihmbiBmdW5jKCkpIChlcnIgZXJyb3IpIHsKCWRlZmVyIGZ1bmMoKSB7CgkJaWYgciA6PSByZWNvdmVyKCk7IHIgIT0gbmlsIHsKCQkJaWYgZSwgb2sgOj0gci4oZXJyb3IpOyBvayB7CgkJCQllcnIgPSBlCgkJCQlyZXR1cm4KCQkJfQoJCQllcnIgPSB1Zm10LkVycm9yZigiJXYiLCByKQoJCX0KCX0oKQoKCWZuKCkKCXJldHVybiBuaWwKfQoKLy8gQmFzaWMgcmV1c2FibGUgdmFsaWRhdG9ycyBmb3IgcHJvcG9zYWwtdGltZSB0eXBlIGNoZWNraW5nLgp2YXIgKAoJc3RyaW5nVmFsaWRhdG9yID0gZnVuYyhzIHN0cmluZykgZXJyb3IgewoJCXJldHVybiBuaWwKCX0KCWJvb2xWYWxpZGF0b3IgPSBmdW5jKHMgc3RyaW5nKSBlcnJvciB7CgkJcmV0dXJuIHJ1blZhbGlkYXRvcihmdW5jKCkgewoJCQlwYXJzZUJvb2wocykKCQl9KQoJfQoJdWludDY0VmFsaWRhdG9yID0gZnVuYyhzIHN0cmluZykgZXJyb3IgewoJCXJldHVybiBydW5WYWxpZGF0b3IoZnVuYygpIHsKCQkJcGFyc2VVaW50NjQocykKCQl9KQoJfQoJYWRkcmVzc1ZhbGlkYXRvciA9IGZ1bmMocyBzdHJpbmcpIGVycm9yIHsKCQlyZXR1cm4gcnVuVmFsaWRhdG9yKGZ1bmMoKSB7CgkJCWFkZHIgOj0gYWRkcmVzcyhzKQoJCQlpZiAhYWRkci5Jc1ZhbGlkKCkgewoJCQkJcGFuaWModWZtdC5TcHJpbnRmKCJpbnZhbGlkIGFkZHJlc3M6ICVzIiwgYWRkcikpCgkJCX0KCQl9KQoJfQopCgpmdW5jIG51bWJlclZhbGlkYXRvcihraW5kIG51bWJlcktpbmQpIHBhcmFtVmFsaWRhdG9yIHsKCXJldHVybiBmdW5jKHMgc3RyaW5nKSBlcnJvciB7CgkJcmV0dXJuIHJ1blZhbGlkYXRvcihmdW5jKCkgewoJCQlwYXJzZU51bWJlcihzLCBraW5kKQoJCX0pCgl9Cn0KCmZ1bmMgdWludDhSYW5nZVZhbGlkYXRvcihuYW1lIHN0cmluZykgcGFyYW1WYWxpZGF0b3IgewoJcmV0dXJuIGZ1bmMocyBzdHJpbmcpIGVycm9yIHsKCQlyZXR1cm4gcnVuVmFsaWRhdG9yKGZ1bmMoKSB7CgkJCXZhbHVlIDo9IHBhcnNlSW50NjQocykKCQkJaWYgdmFsdWUgPCAwIHx8IHZhbHVlID4gMjU1IHsKCQkJCXBhbmljKHVmbXQuU3ByaW50ZigiJXMgb3V0IG9mIHJhbmdlOiAlZCIsIG5hbWUsIHZhbHVlKSkKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgcm9sZU5hbWVWYWxpZGF0b3IocyBzdHJpbmcpIGVycm9yIHsKCXJldHVybiBydW5WYWxpZGF0b3IoZnVuYygpIHsKCQlyb2xlTmFtZSA6PSBzdHJpbmdzLlRyaW1TcGFjZShzKQoJCWlmIHJvbGVOYW1lID09ICIiIHsKCQkJcGFuaWModWZtdC5TcHJpbnRmKCJyb2xlIG5hbWUgaXMgZW1wdHk6ICVxIiwgcykpCgkJfQoJfSkKfQoKZnVuYyB1cGRhdGFibGVSb2xlTmFtZVZhbGlkYXRvcihzIHN0cmluZykgZXJyb3IgewoJcmV0dXJuIHJ1blZhbGlkYXRvcihmdW5jKCkgewoJCXJvbGVOYW1lIDo9IHN0cmluZ3MuVHJpbVNwYWNlKHMpCgkJaWYgZXJyIDo9IHJvbGVOYW1lVmFsaWRhdG9yKHJvbGVOYW1lKTsgZXJyICE9IG5pbCB7CgkJCXBhbmljKGVycikKCQl9CgoJCWlmIHJvbGVOYW1lID09IHByYmFjLlJPTEVfQURNSU4uU3RyaW5nKCkgewoJCQlwYW5pYyh1Zm10LlNwcmludGYoImFkbWluIHJvbGUgY2Fubm90IGJlIHVwZGF0ZWQ6ICVzIiwgcm9sZU5hbWUpKQoJCX0KCX0pCn0KCmZ1bmMgcmVtb3ZhYmxlUm9sZU5hbWVWYWxpZGF0b3IocyBzdHJpbmcpIGVycm9yIHsKCXJldHVybiBydW5WYWxpZGF0b3IoZnVuYygpIHsKCQlyb2xlTmFtZSA6PSBzdHJpbmdzLlRyaW1TcGFjZShzKQoJCWlmIGVyciA6PSByb2xlTmFtZVZhbGlkYXRvcihyb2xlTmFtZSk7IGVyciAhPSBuaWwgewoJCQlwYW5pYyhlcnIpCgkJfQoKCQlpZiBwcmJhYy5Jc1N5c3RlbVJvbGUocm9sZU5hbWUpIHsKCQkJcGFuaWModWZtdC5TcHJpbnRmKCJzeXN0ZW0gcm9sZSBjYW5ub3QgYmUgcmVtb3ZlZDogJXMiLCByb2xlTmFtZSkpCgkJfQoJfSkKfQoKZnVuYyBub25OZWdhdGl2ZUludDY0VmFsaWRhdG9yKG5hbWUgc3RyaW5nKSBwYXJhbVZhbGlkYXRvciB7CglyZXR1cm4gZnVuYyhzIHN0cmluZykgZXJyb3IgewoJCXJldHVybiBydW5WYWxpZGF0b3IoZnVuYygpIHsKCQkJdmFsdWUgOj0gcGFyc2VJbnQ2NChzKQoJCQlpZiB2YWx1ZSA8IDAgewoJCQkJcGFuaWModWZtdC5TcHJpbnRmKCIlcyBtdXN0IGJlIG5vbi1uZWdhdGl2ZTogJWQiLCBuYW1lLCB2YWx1ZSkpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIHBvc2l0aXZlSW50NjRWYWxpZGF0b3IobmFtZSBzdHJpbmcpIHBhcmFtVmFsaWRhdG9yIHsKCXJldHVybiBmdW5jKHMgc3RyaW5nKSBlcnJvciB7CgkJcmV0dXJuIHJ1blZhbGlkYXRvcihmdW5jKCkgewoJCQl2YWx1ZSA6PSBwYXJzZUludDY0KHMpCgkJCWlmIHZhbHVlIDw9IDAgewoJCQkJcGFuaWModWZtdC5TcHJpbnRmKCIlcyBtdXN0IGJlIHBvc2l0aXZlOiAlZCIsIG5hbWUsIHZhbHVlKSkKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgaW50NjRSYW5nZVZhbGlkYXRvcihuYW1lIHN0cmluZywgbWluLCBtYXggaW50NjQpIHBhcmFtVmFsaWRhdG9yIHsKCXJldHVybiBmdW5jKHMgc3RyaW5nKSBlcnJvciB7CgkJcmV0dXJuIHJ1blZhbGlkYXRvcihmdW5jKCkgewoJCQl2YWx1ZSA6PSBwYXJzZUludDY0KHMpCgkJCWlmIHZhbHVlIDwgbWluIHx8IHZhbHVlID4gbWF4IHsKCQkJCXBhbmljKHVmbXQuU3ByaW50ZigiJXMgbXVzdCBiZSBpbiByYW5nZSAlZCB0byAlZDogJWQiLCBuYW1lLCBtaW4sIG1heCwgdmFsdWUpKQoJCQl9CgkJfSkKCX0KfQoKZnVuYyB1aW50NjRSYW5nZVZhbGlkYXRvcihuYW1lIHN0cmluZywgbWF4IHVpbnQ2NCkgcGFyYW1WYWxpZGF0b3IgewoJcmV0dXJuIGZ1bmMocyBzdHJpbmcpIGVycm9yIHsKCQlyZXR1cm4gcnVuVmFsaWRhdG9yKGZ1bmMoKSB7CgkJCXZhbHVlIDo9IHBhcnNlVWludDY0KHMpCgkJCWlmIHZhbHVlID4gbWF4IHsKCQkJCXBhbmljKHVmbXQuU3ByaW50ZigiJXMgbXVzdCBiZSBpbiByYW5nZSAwIHRvICVkOiAlZCIsIG5hbWUsIG1heCwgdmFsdWUpKQoJCQl9CgkJfSkKCX0KfQoKZnVuYyBoYWx0TGV2ZWxWYWxpZGF0b3IocyBzdHJpbmcpIGVycm9yIHsKCXJldHVybiBydW5WYWxpZGF0b3IoZnVuYygpIHsKCQlpZiAhaGFsdC5IYWx0TGV2ZWwocykuSXNWYWxpZCgpIHsKCQkJcGFuaWModWZtdC5TcHJpbnRmKCJpbnZhbGlkIGhhbHQgbGV2ZWw6ICVzIiwgcykpCgkJfQoJfSkKfQoKZnVuYyBoYWx0T3BlcmF0aW9uVHlwZVZhbGlkYXRvcihzIHN0cmluZykgZXJyb3IgewoJcmV0dXJuIHJ1blZhbGlkYXRvcihmdW5jKCkgewoJCWlmICFoYWx0Lk9wVHlwZShzKS5Jc1ZhbGlkKCkgewoJCQlwYW5pYyh1Zm10LlNwcmludGYoImludmFsaWQgb3BlcmF0aW9uIHR5cGU6ICVzIiwgcykpCgkJfQoJfSkKfQoKZnVuYyB0b2tlbk1pbmltdW1SZXdhcmRBbW91bnRWYWxpZGF0b3IocyBzdHJpbmcpIGVycm9yIHsKCXJldHVybiBydW5WYWxpZGF0b3IoZnVuYygpIHsKCQlwYXJ0cyA6PSBzdHJpbmdzLlNwbGl0TihzLCAiOiIsIDIpCgkJaWYgbGVuKHBhcnRzKSAhPSAyIHx8IHBhcnRzWzBdID09ICIiIHsKCQkJcGFuaWMoInRva2VuIG1pbmltdW0gcmV3YXJkIGFtb3VudCBtdXN0IGJlIHRva2VuUGF0aDphbW91bnQiKQoJCX0KCQlhbW91bnQgOj0gcGFyc2VJbnQ2NChwYXJ0c1sxXSkKCQlpZiBhbW91bnQgPCAwIHsKCQkJcGFuaWModWZtdC5TcHJpbnRmKCJtaW5pbXVtIHJld2FyZCBhbW91bnQgbXVzdCBiZSBub24tbmVnYXRpdmU6ICVkIiwgYW1vdW50KSkKCQl9Cgl9KQp9CgpmdW5jIGRpc3RyaWJ1dGlvblBjdENvbXBvc2l0ZVZhbGlkYXRvcihwYXJhbXMgW11zdHJpbmcpIGVycm9yIHsKCXJldHVybiBydW5WYWxpZGF0b3IoZnVuYygpIHsKCQlzdW0gOj0gaW50NjQoMCkKCQlmb3IgaSwgcGFyYW0gOj0gcmFuZ2UgcGFyYW1zIHsKCQkJcGN0IDo9IHBhcnNlSW50NjQocGFyYW0pCgkJCWlmIHBjdCA8IDAgfHwgcGN0ID4gMTAwMDAgewoJCQkJcGFuaWModWZtdC5TcHJpbnRmKCJwZXJjZW50YWdlICVkIG11c3QgYmUgaW4gcmFuZ2UgMCB0byAxMDAwMDogJWQiLCBpKzEsIHBjdCkpCgkJCX0KCQkJc3VtICs9IHBjdAoJCX0KCQlpZiBzdW0gIT0gMTAwMDAgewoJCQlwYW5pYyh1Zm10LlNwcmludGYoInN1bSBvZiBwZXJjZW50YWdlcyBtdXN0IGJlIDEwMDAwLCBnb3QgJWQiLCBzdW0pKQoJCX0KCX0pCn0KCmZ1bmMgc3BsaXRFeGVjdXRpb25zUmF3KGV4ZWN1dGlvbnMgc3RyaW5nKSBbXXN0cmluZyB7CglpZiBleGVjdXRpb25zID09ICIiIHsKCQlyZXR1cm4gW11zdHJpbmd7fQoJfQoKCXJldHVybiBzdHJpbmdzLlNwbGl0KGV4ZWN1dGlvbnMsIG1lc3NhZ2VTZXBhcmF0b3IpCn0KCmZ1bmMgcGFyc2VFeGVjdXRpb25NZXNzYWdlKG1zZyBzdHJpbmcpIChwa2dQYXRoIHN0cmluZywgZnVuY3Rpb24gc3RyaW5nLCBwYXJhbXMgW11zdHJpbmcsIHBhcnRDb3VudCBpbnQpIHsKCXBhcnRzIDo9IHN0cmluZ3MuU3BsaXQobXNnLCBwYXJhbWV0ZXJTZXBhcmF0b3IpCglwYXJ0Q291bnQgPSBsZW4ocGFydHMpCglpZiBwYXJ0Q291bnQgIT0gMyB7CgkJcmV0dXJuICIiLCAiIiwgbmlsLCBwYXJ0Q291bnQKCX0KCglwa2dQYXRoID0gcGFydHNbMF0KCWZ1bmN0aW9uID0gcGFydHNbMV0KCWlmIHBhcnRzWzJdID09ICIiIHsKCQlyZXR1cm4gcGtnUGF0aCwgZnVuY3Rpb24sIFtdc3RyaW5ne30sIHBhcnRDb3VudAoJfQoKCXJldHVybiBwa2dQYXRoLCBmdW5jdGlvbiwgc3RyaW5ncy5TcGxpdChwYXJ0c1syXSwgIiwiKSwgcGFydENvdW50Cn0KCi8vIHZhbGlkYXRlRXhlY3V0aW9ucyB2YWxpZGF0ZXMgdGhhdCBhbGwgZXhlY3V0aW9ucyBpbiBhIHBhcmFtZXRlciBjaGFuZ2UgcHJvcG9zYWwKLy8gY29ycmVzcG9uZCB0byByZWdpc3RlcmVkIGhhbmRsZXJzIGluIHRoZSBnbG9iYWwgcGFyYW1ldGVyIHJlZ2lzdHJ5LgovLyBUaGlzIGZ1bmN0aW9uIHBlcmZvcm1zIGNvbXByZWhlbnNpdmUgdmFsaWRhdGlvbiBpbmNsdWRpbmc6Ci8vIC0gQmFzaWMgZm9ybWF0IHZhbGlkYXRpb24gKGNvdW50LCBzdHJ1Y3R1cmUpCi8vIC0gSGFuZGxlciBleGlzdGVuY2UgdmVyaWZpY2F0aW9uIGluIHRoZSByZWdpc3RyeQovLyAtIFBhcmFtZXRlciBjb3VudCB2YWxpZGF0aW9uIGFnYWluc3QgaGFuZGxlciBleHBlY3RhdGlvbnMKLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIG51bVRvRXhlY3V0ZTogbnVtYmVyIG9mIHBhcmFtZXRlciBjaGFuZ2VzIHRvIGV4ZWN1dGUKLy8gICAtIG1zZ3M6IHByZS1zcGxpdCBzbGljZSBvZiBleGVjdXRpb24gbWVzc2FnZXMsIHdoZXJlIGVhY2ggbWVzc2FnZQovLyAgICAgaXMgZm9ybWF0dGVkIGFzIDxwa2dQYXRoPipFWEUqPGZ1bmN0aW9uPipFWEUqPHBhcmFtcz4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGVycm9yOiB2YWxpZGF0aW9uIGVycm9yIGlmIGFueSBleGVjdXRpb24gaXMgaW52YWxpZApmdW5jIHZhbGlkYXRlRXhlY3V0aW9ucyhudW1Ub0V4ZWN1dGUgaW50NjQsIG1zZ3MgW11zdHJpbmcpIGVycm9yIHsKCS8vIFZhbGlkYXRlIGV4ZWN1dGlvbiBjb3VudCBpcyBwb3NpdGl2ZQoJaWYgbnVtVG9FeGVjdXRlIDw9IDAgewoJCXJldHVybiBtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZElucHV0LAoJCQkibnVtVG9FeGVjdXRlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byAwIiwKCQkpCgl9CgoJLy8gQ2hlY2sgaWYgZXhlY3V0aW9ucyBhcmUgZW1wdHkKCWlmIGxlbihtc2dzKSA9PSAwIHsKCQlyZXR1cm4gbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRJbnB1dCwKCQkJImV4ZWN1dGlvbnMgaXMgZW1wdHkiLAoJCSkKCX0KCgkvLyBWYWxpZGF0ZSBleGVjdXRpb24gY291bnQgZG9lc24ndCBleGNlZWQgbWF4aW11bQoJaWYgbnVtVG9FeGVjdXRlID4gbWF4TnVtYmVyT2ZFeGVjdXRpb24gewoJCXJldHVybiBtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZElucHV0LAoJCQl1Zm10LlNwcmludGYoIm51bVRvRXhlY3V0ZSBpcyBncmVhdGVyIHRoYW4gJWQiLCBtYXhOdW1iZXJPZkV4ZWN1dGlvbiksCgkJKQoJfQoKCW1zZ0NvdW50IDo9IGxlbihtc2dzKQoJLy8gVmFsaWRhdGUgZXhlY3V0aW9uIGNvdW50IG1hdGNoZXMgbWVzc2FnZSBjb3VudAoJaWYgbXNnQ291bnQgIT0gaW50KG51bVRvRXhlY3V0ZSkgewoJCXJldHVybiBtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZElucHV0LAoJCQl1Zm10LlNwcmludGYoImV4ZWN1dGlvbnMgY291bnQgKCVkKSBkb2VzIG5vdCBtYXRjaCBudW1Ub0V4ZWN1dGUgKCVkKSIsIGxlbihtc2dzKSwgbnVtVG9FeGVjdXRlKSwKCQkpCgl9CgoJLy8gUGFyc2UgYW5kIHZhbGlkYXRlIGVhY2ggZXhlY3V0aW9uIG1lc3NhZ2UKCWZvciBpLCBleGVjdXRpb24gOj0gcmFuZ2UgbXNncyB7CgkJcGtnUGF0aCwgZnVuY3Rpb24sIHBhcmFtcywgcGFydENvdW50IDo9IHBhcnNlRXhlY3V0aW9uTWVzc2FnZShleGVjdXRpb24pCgkJaWYgcGFydENvdW50ICE9IDMgewoJCQkvLyBQcm92aWRlIG1vcmUgaGVscGZ1bCBlcnJvciBtZXNzYWdlIGJhc2VkIG9uIHdoYXQncyB3cm9uZwoJCQlkZXRhaWwgOj0gdWZtdC5TcHJpbnRmKCJleGVjdXRpb25bJWRdOiBleHBlY3RlZCAzIHBhcnRzIChwa2dQYXRoLCBmdW5jdGlvbiwgcGFyYW1zKSwgZ290ICVkIiwgaSwgcGFydENvdW50KQoJCQlyZXR1cm4gbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCQllcnJJbnZhbGlkTWVzc2FnZUZvcm1hdCwKCQkJCWRldGFpbCwKCQkJKQoJCX0KCgkJLy8gVmFsaWRhdGUgcGFja2FnZSBwYXRoIGFuZCBmdW5jdGlvbiBhcmUgbm90IGVtcHR5CgkJaWYgcGtnUGF0aCA9PSAiIiB7CgkJCXJldHVybiBtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJCWVyckludmFsaWRJbnB1dCwKCQkJCXVmbXQuU3ByaW50ZigiZXhlY3V0aW9uWyVkXTogcGFja2FnZSBwYXRoIGlzIGVtcHR5IiwgaSksCgkJCSkKCQl9CgoJCWlmIGZ1bmN0aW9uID09ICIiIHsKCQkJcmV0dXJuIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQkJZXJySW52YWxpZElucHV0LAoJCQkJdWZtdC5TcHJpbnRmKCJleGVjdXRpb25bJWRdOiBmdW5jdGlvbiBuYW1lIGlzIGVtcHR5IiwgaSksCgkJCSkKCQl9CgoJCS8vIENoZWNrIGlmIGhhbmRsZXIgZXhpc3RzIGluIHJlZ2lzdHJ5CgkJa2V5IDo9IG1ha2VIYW5kbGVyS2V5KHBrZ1BhdGgsIGZ1bmN0aW9uKQoJCWhhbmRsZXIsIGVyciA6PSBnbG9iYWxQYXJhbWV0ZXJSZWdpc3RyeS5IYW5kbGVyKGtleSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQkJZXJySW52YWxpZEV4ZWN1dGlvbiwKCQkJCXVmbXQuU3ByaW50ZigiZXhlY3V0aW9uWyVkXTogJXMgKGtleTogJXMpIiwgaSwgZXJyLkVycm9yKCksIGtleSksCgkJCSkKCQl9CgoJCS8vIEdldCBleHBlY3RlZCBwYXJhbWV0ZXIgY291bnQgZnJvbSBoYW5kbGVyCgkJaGFuZGxlck9wdHMsIG9rIDo9IGhhbmRsZXIuKCpQYXJhbWV0ZXJIYW5kbGVyT3B0aW9ucykKCQlpZiAhb2sgewoJCQlyZXR1cm4gbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCQllcnJJbnZhbGlkRXhlY3V0aW9uLAoJCQkJdWZtdC5TcHJpbnRmKCJleGVjdXRpb25bJWRdOiBmYWlsZWQgdG8gZ2V0IGhhbmRsZXIgb3B0aW9ucyIsIGkpLAoJCQkpCgkJfQoKCQkvLyBWYWxpZGF0ZSBwYXJhbWV0ZXIgdHlwZXMvZm9ybWF0IGFoZWFkIG9mIHByb3Bvc2FsIGNyZWF0aW9uCgkJaWYgZXJyIDo9IGhhbmRsZXJPcHRzLlZhbGlkYXRlUGFyYW1zKHBhcmFtcyk7IGVyciAhPSBuaWwgewoJCQlyZXR1cm4gbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCQllcnJJbnZhbGlkSW5wdXQsCgkJCQl1Zm10LlNwcmludGYoImV4ZWN1dGlvblslZF06ICV2IiwgaSwgZXJyKSwKCQkJKQoJCX0KCX0KCglyZXR1cm4gbmlsCn0KGpIzCgxwcm9wb3NhbC5nbm8SgTNwYWNrYWdlIGdvdmVybmFuY2UKCmltcG9ydCAoCgkiZXJyb3JzIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvZ292L2dvdmVybmFuY2UiCikKCnR5cGUgUHJvcG9zYWxSZXNvbHZlciBzdHJ1Y3QgewoJKmdvdmVybmFuY2UuUHJvcG9zYWwKCXN0YXR1c1Jlc29sdmVyICAgKlByb3Bvc2FsU3RhdHVzUmVzb2x2ZXIKCWRhdGFSZXNvbHZlciAgICAgKlByb3Bvc2FsRGF0YVJlc29sdmVyCgltZXRhZGF0YVJlc29sdmVyICpQcm9wb3NhbE1ldGFkYXRhUmVzb2x2ZXIKfQoKLy8gTmV3UHJvcG9zYWxSZXNvbHZlciB3cmFwcyBhIHBlcnNpc3RlZCBnb3Zlcm5hbmNlIHByb3Bvc2FsIGFuZCBpbml0aWFsaXplcwovLyByZXNvbHZlcnMgZm9yIGl0cyBzdGF0dXMsIHR5cGUtc3BlY2lmaWMgZGF0YSwgYW5kIG1ldGFkYXRhLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcHJvcG9zYWw6IHBlcnNpc3RlZCBwcm9wb3NhbCB0byByZXNvbHZlCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqUHJvcG9zYWxSZXNvbHZlcjogcmVzb2x2ZXIgYmFja2VkIGJ5IHByb3Bvc2FsIGFuZCBpdHMgbmVzdGVkIHN0YXRlCmZ1bmMgTmV3UHJvcG9zYWxSZXNvbHZlcihwcm9wb3NhbCAqZ292ZXJuYW5jZS5Qcm9wb3NhbCkgKlByb3Bvc2FsUmVzb2x2ZXIgewoJc3RhdHVzUmVzb2x2ZXIgOj0gTmV3UHJvcG9zYWxTdGF0dXNSZXNvbHZlcihwcm9wb3NhbC5TdGF0dXMoKSkKCWRhdGFSZXNvbHZlciA6PSBOZXdQcm9wb3NhbERhdGFSZXNvbHZlcihwcm9wb3NhbC5EYXRhKCkpCgltZXRhZGF0YVJlc29sdmVyIDo9IE5ld1Byb3Bvc2FsTWV0YWRhdGFSZXNvbHZlcihwcm9wb3NhbC5NZXRhZGF0YSgpKQoJcmV0dXJuICZQcm9wb3NhbFJlc29sdmVyewoJCVByb3Bvc2FsOiAgICAgICAgIHByb3Bvc2FsLAoJCXN0YXR1c1Jlc29sdmVyOiAgIHN0YXR1c1Jlc29sdmVyLAoJCWRhdGFSZXNvbHZlcjogICAgIGRhdGFSZXNvbHZlciwKCQltZXRhZGF0YVJlc29sdmVyOiBtZXRhZGF0YVJlc29sdmVyLAoJfQp9CgovLyBWb3RpbmdUb3RhbFdlaWdodCByZXR1cm5zIHRoZSB0b3RhbCB3ZWlnaHQgb2YgYWxsIHZvdGVzIGNhc3QgYnkgY29tYmluaW5nCi8vIHRoZSBwcm9wb3NhbCdzIHllcyBhbmQgbm8gdGFsbGllcy4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBjb21iaW5lZCB3ZWlnaHQgb2YgYWxsIHJlY29yZGVkIHZvdGVzCmZ1bmMgKHIgKlByb3Bvc2FsUmVzb2x2ZXIpIFZvdGluZ1RvdGFsV2VpZ2h0KCkgaW50NjQgewoJcmV0dXJuIHIuc3RhdHVzUmVzb2x2ZXIuVG90YWxWb3RlV2VpZ2h0KCkKfQoKLy8gSXNBY3RpdmUgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBwcm9wb3NhbCBpcyBhY3RpdmUgYXQgY3VycmVudC4KLy8gVXBjb21pbmcsIHZvdGluZywgYW5kIHBhc3NlZCBleGVjdXRhYmxlIHByb3Bvc2FscyBhcmUgYWN0aXZlOyByZWplY3RlZCwKLy8gZXhwaXJlZCwgZXhlY3V0ZWQsIGNhbmNlbGVkLCBhbmQgcGFzc2VkIHRleHQgcHJvcG9zYWxzIGFyZSBpbmFjdGl2ZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnQ6IHRpbWVzdGFtcCBhdCB3aGljaCB0aGUgcHJvcG9zYWwgc3RhdHVzIGlzIGV2YWx1YXRlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSB3aGVuIHRoZSBwcm9wb3NhbCBjYW4gc3RpbGwgYmUgdm90ZWQgb24gb3IgZXhlY3V0ZWQgYXQgY3VycmVudApmdW5jIChyICpQcm9wb3NhbFJlc29sdmVyKSBJc0FjdGl2ZShjdXJyZW50IGludDY0KSBib29sIHsKCS8vIENhbGN1bGF0ZSBzdGF0dXMgb25jZSBhbmQgcmV1c2UgdG8gYXZvaWQgcmVkdW5kYW50IGNvbXB1dGF0aW9ucwoJc3RhdHVzIDo9IHIuc3RhdHVzUmVzb2x2ZXIuU3RhdHVzVHlwZShjdXJyZW50KQoKCXN3aXRjaCBzdGF0dXMgewoJY2FzZSBnb3Zlcm5hbmNlLlN0YXR1c1JlamVjdGVkLAoJCWdvdmVybmFuY2UuU3RhdHVzRXhwaXJlZCwKCQlnb3Zlcm5hbmNlLlN0YXR1c0V4ZWN1dGVkLAoJCWdvdmVybmFuY2UuU3RhdHVzQ2FuY2VsZWQ6CgkJcmV0dXJuIGZhbHNlCgljYXNlIGdvdmVybmFuY2UuU3RhdHVzUGFzc2VkOgoJCS8vIFRleHQgcHJvcG9zYWxzIGJlY29tZSBpbmFjdGl2ZSBvbmNlIHRoZXkgcGFzcyAobm8gZXhlY3V0aW9uIG5lZWRlZCkKCQlyZXR1cm4gIXIuSXNUZXh0VHlwZSgpCglkZWZhdWx0OgoJCS8vIFN0YXR1c1VwY29taW5nLCBTdGF0dXNBY3RpdmUsIFN0YXR1c0V4ZWN1dGFibGUgYXJlIGNvbnNpZGVyZWQgYWN0aXZlCgkJcmV0dXJuIHRydWUKCX0KfQoKLy8gVmFsaWRhdGUgcGVyZm9ybXMgY29tcHJlaGVuc2l2ZSB2YWxpZGF0aW9uIG9mIHRoZSBwcm9wb3NhbCdzIHR5cGUtc3BlY2lmaWMKLy8gZGF0YSBhbmQgbWV0YWRhdGEgYmVmb3JlIHRoZSBwcm9wb3NhbCBpcyBzdG9yZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBlcnJvcjogbmlsIHdoZW4gYm90aCBkYXRhIGFuZCBtZXRhZGF0YSB2YWxpZGF0ZTsgdGhlIGZpcnN0IHZhbGlkYXRpb24gZXJyb3Igb3RoZXJ3aXNlCmZ1bmMgKHIgKlByb3Bvc2FsUmVzb2x2ZXIpIFZhbGlkYXRlKCkgZXJyb3IgewoJLy8gVmFsaWRhdGUgdHlwZS1zcGVjaWZpYyBwcm9wb3NhbCBkYXRhCglpZiBlcnIgOj0gci5kYXRhUmVzb2x2ZXIuVmFsaWRhdGUoKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCS8vIFZhbGlkYXRlIHByb3Bvc2FsIG1ldGFkYXRhICh0aXRsZSBhbmQgZGVzY3JpcHRpb24pCglpZiBlcnIgOj0gci5tZXRhZGF0YVJlc29sdmVyLlZhbGlkYXRlKCk7IGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCglyZXR1cm4gbmlsCn0KCi8vIFN0YXR1cyByZXR1cm5zIHRoZSBjdXJyZW50IHN0YXR1cyBzdHJpbmcgb2YgdGhlIHByb3Bvc2FsIGF0IGN1cnJlbnQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjdXJyZW50OiB0aW1lc3RhbXAgYXQgd2hpY2ggdGhlIHByb3Bvc2FsIHN0YXR1cyBpcyBldmFsdWF0ZWQKLy8KLy8gUmV0dXJuczoKLy8gICAtIHN0cmluZzogaHVtYW4tcmVhZGFibGUgc3RhdHVzIG5hbWUgZm9yIHRoZSBwcm9wb3NhbCBhdCBjdXJyZW50CmZ1bmMgKHIgKlByb3Bvc2FsUmVzb2x2ZXIpIFN0YXR1cyhjdXJyZW50IGludDY0KSBzdHJpbmcgewoJcmV0dXJuIHIuc3RhdHVzUmVzb2x2ZXIuU3RhdHVzVHlwZShjdXJyZW50KS5TdHJpbmcoKQp9CgovLyBTdGF0dXNUeXBlIHJldHVybnMgdGhlIGN1cnJlbnQgc3RhdHVzIHR5cGUgb2YgdGhlIHByb3Bvc2FsIGF0IGN1cnJlbnQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjdXJyZW50OiB0aW1lc3RhbXAgYXQgd2hpY2ggdGhlIHByb3Bvc2FsIHN0YXR1cyBpcyBldmFsdWF0ZWQKLy8KLy8gUmV0dXJuczoKLy8gICAtIGdvdmVybmFuY2UuUHJvcG9zYWxTdGF0dXNUeXBlOiBsaWZlY3ljbGUgc3RhdHVzIGF0IGN1cnJlbnQKZnVuYyAociAqUHJvcG9zYWxSZXNvbHZlcikgU3RhdHVzVHlwZShjdXJyZW50IGludDY0KSBnb3Zlcm5hbmNlLlByb3Bvc2FsU3RhdHVzVHlwZSB7CglyZXR1cm4gci5zdGF0dXNSZXNvbHZlci5TdGF0dXNUeXBlKGN1cnJlbnQpCn0KCi8vIElzVm90aW5nUGVyaW9kIHJlcG9ydHMgd2hldGhlciB2b3RlZEF0IGZhbGxzIHdpdGhpbiB0aGUgcHJvcG9zYWwncyBhY3RpdmUKLy8gdm90aW5nIHN0YXR1cy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHZvdGVkQXQ6IHRpbWVzdGFtcCBhdCB3aGljaCB2b3RpbmcgZWxpZ2liaWxpdHkgaXMgY2hlY2tlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSB3aGVuIHRoZSBwcm9wb3NhbCBzdGF0dXMgYXQgdm90ZWRBdCBpcyBTdGF0dXNBY3RpdmUKZnVuYyAociAqUHJvcG9zYWxSZXNvbHZlcikgSXNWb3RpbmdQZXJpb2Qodm90ZWRBdCBpbnQ2NCkgYm9vbCB7CglyZXR1cm4gci5TdGF0dXNUeXBlKHZvdGVkQXQpID09IGdvdmVybmFuY2UuU3RhdHVzQWN0aXZlCn0KCi8vIElzRXhlY3V0YWJsZSBkZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHByb3Bvc2FsIGNhbiBiZSBleGVjdXRlZCBhdCBjdXJyZW50LgovLyBUaGUgcHJvcG9zYWwgdHlwZSBtdXN0IHN1cHBvcnQgZXhlY3V0aW9uIGFuZCBpdHMgc3RhdHVzIG11c3QgYmUgZXhlY3V0YWJsZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnQ6IHRpbWVzdGFtcCBhdCB3aGljaCBleGVjdXRpb24gZWxpZ2liaWxpdHkgaXMgZXZhbHVhdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIHdoZW4gdGhpcyB0eXBlIGFuZCBjdXJyZW50IGxpZmVjeWNsZSBzdGF0ZSBwZXJtaXQgZXhlY3V0aW9uCmZ1bmMgKHIgKlByb3Bvc2FsUmVzb2x2ZXIpIElzRXhlY3V0YWJsZShjdXJyZW50IGludDY0KSBib29sIHsKCS8vIE9ubHkgY2VydGFpbiBwcm9wb3NhbCB0eXBlcyBjYW4gYmUgZXhlY3V0ZWQKCWlmICFyLmRhdGFSZXNvbHZlci5Qcm9wb3NhbFR5cGUoKS5Jc0V4ZWN1dGFibGUoKSB7CgkJcmV0dXJuIGZhbHNlCgl9CgoJcmV0dXJuIHIuc3RhdHVzUmVzb2x2ZXIuSXNFeGVjdXRhYmxlKGN1cnJlbnQpCn0KCi8vIENvbW11bml0eVBvb2xTcGVuZFRva2VuUGF0aCByZXR1cm5zIHRoZSB0b2tlbiBwYXRoIGZvciBhIGNvbW11bml0eSBwb29sIHNwZW5kIHByb3Bvc2FsLgovLyBJdCByZXR1cm5zIGFuIGVtcHR5IHN0cmluZyB3aGVuIHRoZSBwcm9wb3NhbCBoYXMgbm8gY29tbXVuaXR5LXBvb2wgc3BlbmQgZGF0YS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHN0cmluZzogdG9rZW4gcGFja2FnZSBwYXRoIHRvIHNwZW5kLCBvciBlbXB0eSBzdHJpbmcgZm9yIG90aGVyIHByb3Bvc2FsIHR5cGVzCmZ1bmMgKHIgKlByb3Bvc2FsUmVzb2x2ZXIpIENvbW11bml0eVBvb2xTcGVuZFRva2VuUGF0aCgpIHN0cmluZyB7CglpZiByLkRhdGEoKSA9PSBuaWwgewoJCXJldHVybiAiIgoJfQoKCWNvbW11bml0eVBvb2xTcGVuZCA6PSByLmRhdGFSZXNvbHZlci5Db21tdW5pdHlQb29sU3BlbmQoKQoJaWYgY29tbXVuaXR5UG9vbFNwZW5kID09IG5pbCB7CgkJcmV0dXJuICIiCgl9CgoJcmV0dXJuIGNvbW11bml0eVBvb2xTcGVuZC5Ub2tlblBhdGgoKQp9CgovLyBWb3RlIHJlY29yZHMgYSB2b3RlIGZvciB0aGlzIHByb3Bvc2FsIGFuZCB1cGRhdGVzIGl0cyB5ZXMgb3Igbm8gdGFsbHkuCi8vIFRoaXMgaXMgYW4gaW50ZXJuYWwgbWV0aG9kIGNhbGxlZCBkdXJpbmcgdGhlIHZvdGluZyBwcm9jZXNzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gdm90ZWRZZXM6IHRydWUgdG8gYWRkIHdlaWdodCB0byB0aGUgeWVzIHRhbGx5OyBmYWxzZSB0byBhZGQgaXQgdG8gbm8KLy8gICAtIHdlaWdodDogdm90aW5nIHdlaWdodCB0byBhZGQgdG8gdGhlIHNlbGVjdGVkIHRhbGx5Ci8vCi8vIFJldHVybnM6Ci8vICAgLSBlcnJvcjogbmlsIHdoZW4gdGhlIHNlbGVjdGVkIHRhbGx5IGlzIHVwZGF0ZWQ7IGFuIGVycm9yIGZyb20gdm90ZS1zdGF0dXMgdmFsaWRhdGlvbiBvdGhlcndpc2UKZnVuYyAociAqUHJvcG9zYWxSZXNvbHZlcikgVm90ZSh2b3RlZFllcyBib29sLCB3ZWlnaHQgaW50NjQpIGVycm9yIHsKCXJldHVybiByLnN0YXR1c1Jlc29sdmVyLnZvdGUodm90ZWRZZXMsIHdlaWdodCkKfQoKLy8gZXhlY3V0ZSBtYXJrcyB0aGUgcHJvcG9zYWwgYXMgZXhlY3V0ZWQgYW5kIHJlY29yZHMgZXhlY3V0aW9uIGRldGFpbHMuCi8vIFRoaXMgbWV0aG9kIHZhbGlkYXRlcyBleGVjdXRpb24gY29uZGl0aW9ucyBiZWZvcmUgcHJvY2VlZGluZy4KZnVuYyAociAqUHJvcG9zYWxSZXNvbHZlcikgZXhlY3V0ZSgKCWV4ZWN1dGVkQXQsIGV4ZWN1dGVkSGVpZ2h0IGludDY0LAoJZXhlY3V0ZWRCeSBhZGRyZXNzLAopIGVycm9yIHsKCS8vIFZlcmlmeSBwcm9wb3NhbCBpcyBpbiBleGVjdXRhYmxlIHN0YXRlCglpZiAhci5Jc0V4ZWN1dGFibGUoZXhlY3V0ZWRBdCkgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyclByb3Bvc2FsTm90RXhlY3V0YWJsZSkKCX0KCgkvLyBNYXJrIHByb3Bvc2FsIGFzIGV4ZWN1dGVkCglyZXR1cm4gci5zdGF0dXNSZXNvbHZlci5leGVjdXRlKGV4ZWN1dGVkQXQsIGV4ZWN1dGVkSGVpZ2h0LCBleGVjdXRlZEJ5KQp9CgovLyBjYW5jZWwgbWFya3MgdGhlIHByb3Bvc2FsIGFzIGNhbmNlbGVkIGFuZCByZWNvcmRzIGNhbmNlbGxhdGlvbiBkZXRhaWxzLgovLyBUaGlzIG1ldGhvZCB2YWxpZGF0ZXMgY2FuY2VsbGF0aW9uIGNvbmRpdGlvbnMgYmVmb3JlIHByb2NlZWRpbmcuCmZ1bmMgKHIgKlByb3Bvc2FsUmVzb2x2ZXIpIGNhbmNlbCgKCWNhbmNlbGVkQXQsIGNhbmNlbGVkSGVpZ2h0IGludDY0LAoJY2FuY2VsZWRCeSBhZGRyZXNzLAopIGVycm9yIHsKCWlmIHIuc3RhdHVzUmVzb2x2ZXIuSXNDYW5jZWxlZChjYW5jZWxlZEF0KSB7CgkJcmV0dXJuIGVycm9ycy5OZXcoZXJyQWxyZWFkeUNhbmNlbGVkUHJvcG9zYWwpCgl9CgoJaWYgIXIuc3RhdHVzUmVzb2x2ZXIuSXNVcGNvbWluZyhjYW5jZWxlZEF0KSB7CgkJcmV0dXJuIGVycm9ycy5OZXcoZXJyVW5hYmxlVG9DYW5jZWxWb3RpbmdQcm9wb3NhbCkKCX0KCgkvLyBNYXJrIHByb3Bvc2FsIGFzIGNhbmNlbGVkCglyZXR1cm4gci5zdGF0dXNSZXNvbHZlci5jYW5jZWwoY2FuY2VsZWRBdCwgY2FuY2VsZWRIZWlnaHQsIGNhbmNlbGVkQnkpCn0KGrQSChpwcm9wb3NhbF9hY3Rpb25fc3RhdHVzLmdubxKVEnBhY2thZ2UgZ292ZXJuYW5jZQoKaW1wb3J0ICgKCSJlcnJvcnMiCgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3YvZ292ZXJuYW5jZSIKKQoKdHlwZSBQcm9wb3NhbEFjdGlvblN0YXR1c1Jlc29sdmVyIHN0cnVjdCB7CgkqZ292ZXJuYW5jZS5Qcm9wb3NhbEFjdGlvblN0YXR1cwp9CgovLyBOZXdQcm9wb3NhbEFjdGlvblN0YXR1c1Jlc29sdmVyIHdyYXBzIGEgcHJvcG9zYWwgYWN0aW9uIHN0YXR1cyBmb3IgbXV0YXRpb24KLy8gYW5kIGV4ZWN1dGlvbi1zdGF0ZSBxdWVyaWVzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gc3RhdHVzOiBwcm9wb3NhbCBhY3Rpb24gc3RhdHVzIHRvIHJlc29sdmUgYW5kIHVwZGF0ZS4KLy8KLy8gUmV0dXJuczoKLy8gICAtICpQcm9wb3NhbEFjdGlvblN0YXR1c1Jlc29sdmVyOiByZXNvbHZlciBiYWNrZWQgYnkgc3RhdHVzLgpmdW5jIE5ld1Byb3Bvc2FsQWN0aW9uU3RhdHVzUmVzb2x2ZXIoc3RhdHVzICpnb3Zlcm5hbmNlLlByb3Bvc2FsQWN0aW9uU3RhdHVzKSAqUHJvcG9zYWxBY3Rpb25TdGF0dXNSZXNvbHZlciB7CglyZXR1cm4gJlByb3Bvc2FsQWN0aW9uU3RhdHVzUmVzb2x2ZXJ7c3RhdHVzfQp9CgovLyBjYW5jZWwgbWFya3MgdGhlIHByb3Bvc2FsIGFzIGNhbmNlbGVkIGFuZCByZWNvcmRzIGNhbmNlbGxhdGlvbiBkZXRhaWxzLgovLyBUaGlzIG1ldGhvZCB2YWxpZGF0ZXMgdGhhdCB0aGUgcHJvcG9zYWwgaXMgZWxpZ2libGUgZm9yIGNhbmNlbGxhdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGNhbmNlbGVkQXQ6IHRpbWVzdGFtcCB3aGVuIGNhbmNlbGxhdGlvbiBvY2N1cnJlZAovLyAgIC0gY2FuY2VsZWRIZWlnaHQ6IGJsb2NrIGhlaWdodCB3aGVuIGNhbmNlbGxhdGlvbiBvY2N1cnJlZAovLyAgIC0gY2FuY2VsZWRCeTogYWRkcmVzcyBwZXJmb3JtaW5nIHRoZSBjYW5jZWxsYXRpb24KLy8KLy8gUmV0dXJuczoKLy8gICAtIGVycm9yOiBhbHJlYWR5IGNhbmNlbGVkIGVycm9yIGlmIHByb3Bvc2FsIGFjdGlvbiBzdGF0dXMgaXMgYWxyZWFkeSBjYW5jZWxlZApmdW5jIChwICpQcm9wb3NhbEFjdGlvblN0YXR1c1Jlc29sdmVyKSBjYW5jZWwoCgljYW5jZWxlZEF0LCBjYW5jZWxlZEhlaWdodCBpbnQ2NCwKCWNhbmNlbGVkQnkgYWRkcmVzcywKKSBlcnJvciB7CglpZiBwLkNhbmNlbGVkKCkgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyckFscmVhZHlDYW5jZWxlZFByb3Bvc2FsKQoJfQoKCS8vIFJlY29yZCBjYW5jZWxsYXRpb24gZGV0YWlscwoJcC5TZXRDYW5jZWxlZCh0cnVlKQoJcC5TZXRDYW5jZWxlZEF0KGNhbmNlbGVkQXQpCglwLlNldENhbmNlbGVkSGVpZ2h0KGNhbmNlbGVkSGVpZ2h0KQoJcC5TZXRDYW5jZWxlZEJ5KGNhbmNlbGVkQnkpCgoJcmV0dXJuIG5pbAp9CgovLyBFeGVjdXRlIG1hcmtzIHRoZSBwcm9wb3NhbCBhcyBleGVjdXRlZCBhbmQgcmVjb3JkcyBleGVjdXRpb24gZGV0YWlscy4KLy8gVGhpcyBtZXRob2QgdmFsaWRhdGVzIHRoYXQgdGhlIHByb3Bvc2FsIGlzIGVsaWdpYmxlIGZvciBleGVjdXRpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBleGVjdXRlZEF0OiBVbml4IHRpbWVzdGFtcCB3aGVuIGV4ZWN1dGlvbiBvY2N1cnJlZC4KLy8gICAtIGV4ZWN1dGVkSGVpZ2h0OiBibG9jayBoZWlnaHQgd2hlbiBleGVjdXRpb24gb2NjdXJyZWQuCi8vICAgLSBleGVjdXRlZEJ5OiBhZGRyZXNzIHBlcmZvcm1pbmcgdGhlIGV4ZWN1dGlvbi4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGVycm9yOiBuaWwgb24gc3VjY2VzczsgYW4gZXJyb3Igd2hlbiB0aGUgcHJvcG9zYWwgaXMgbm90IGV4ZWN1dGFibGUgb3IKLy8gICAgIGhhcyBhbHJlYWR5IGJlZW4gY2FuY2VsZWQuCmZ1bmMgKHAgKlByb3Bvc2FsQWN0aW9uU3RhdHVzUmVzb2x2ZXIpIEV4ZWN1dGUoCglleGVjdXRlZEF0LCBleGVjdXRlZEhlaWdodCBpbnQ2NCwKCWV4ZWN1dGVkQnkgYWRkcmVzcywKKSBlcnJvciB7CgkvLyBPbmx5IGV4ZWN1dGFibGUgcHJvcG9zYWxzIGNhbiBiZSBleGVjdXRlZCAodGV4dCBwcm9wb3NhbHMgY2Fubm90KQoJaWYgIXAuSXNFeGVjdXRhYmxlKCkgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyclByb3Bvc2FsTm90RXhlY3V0YWJsZSkKCX0KCglpZiBwLkNhbmNlbGVkKCkgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyckFscmVhZHlDYW5jZWxlZFByb3Bvc2FsKQoJfQoKCS8vIFJlY29yZCBleGVjdXRpb24gZGV0YWlscwoJcC5TZXRFeGVjdXRlZCh0cnVlKQoJcC5TZXRFeGVjdXRlZEF0KGV4ZWN1dGVkQXQpCglwLlNldEV4ZWN1dGVkSGVpZ2h0KGV4ZWN1dGVkSGVpZ2h0KQoJcC5TZXRFeGVjdXRlZEJ5KGV4ZWN1dGVkQnkpCgoJcmV0dXJuIG5pbAp9ChriQwoRcHJvcG9zYWxfZGF0YS5nbm8SzENwYWNrYWdlIGdvdmVybmFuY2UKCmltcG9ydCAoCgkic3RyaW5ncyIKCgkiZ25vLmxhbmQvcC9nbm9zd2FwL3V0aWxzL3YxIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvZ292L2dvdmVybmFuY2UiCikKCnR5cGUgUHJvcG9zYWxNZXRhZGF0YVJlc29sdmVyIHN0cnVjdCB7CgkqZ292ZXJuYW5jZS5Qcm9wb3NhbE1ldGFkYXRhCn0KCi8vIE5ld1Byb3Bvc2FsTWV0YWRhdGFSZXNvbHZlciB3cmFwcyBwcm9wb3NhbCBtZXRhZGF0YSBmb3IgdmFsaWRhdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIG1ldGFkYXRhOiBwcm9wb3NhbCB0aXRsZSBhbmQgZGVzY3JpcHRpb24gdG8gdmFsaWRhdGUuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqUHJvcG9zYWxNZXRhZGF0YVJlc29sdmVyOiByZXNvbHZlciBiYWNrZWQgYnkgbWV0YWRhdGEuCmZ1bmMgTmV3UHJvcG9zYWxNZXRhZGF0YVJlc29sdmVyKG1ldGFkYXRhICpnb3Zlcm5hbmNlLlByb3Bvc2FsTWV0YWRhdGEpICpQcm9wb3NhbE1ldGFkYXRhUmVzb2x2ZXIgewoJcmV0dXJuICZQcm9wb3NhbE1ldGFkYXRhUmVzb2x2ZXJ7CgkJUHJvcG9zYWxNZXRhZGF0YTogbWV0YWRhdGEsCgl9Cn0KCi8vIFZhbGlkYXRlIHBlcmZvcm1zIGNvbXByZWhlbnNpdmUgdmFsaWRhdGlvbiBvZiB0aGUgcHJvcG9zYWwgbWV0YWRhdGEuCi8vIENoZWNrcyB0aXRsZSBhbmQgZGVzY3JpcHRpb24gbGVuZ3RoIGFuZCBjb250ZW50IHJlcXVpcmVtZW50cy4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGVycm9yOiB2YWxpZGF0aW9uIGVycm9yIGlmIG1ldGFkYXRhIGlzIGludmFsaWQKZnVuYyAociAqUHJvcG9zYWxNZXRhZGF0YVJlc29sdmVyKSBWYWxpZGF0ZSgpIGVycm9yIHsKCS8vIFZhbGlkYXRlIHRpdGxlIG1lZXRzIHJlcXVpcmVtZW50cwoJaWYgZXJyIDo9IHIudmFsaWRhdGVUaXRsZShyLlRpdGxlKCkpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJLy8gVmFsaWRhdGUgZGVzY3JpcHRpb24gbWVldHMgcmVxdWlyZW1lbnRzCglpZiBlcnIgOj0gci52YWxpZGF0ZURlc2NyaXB0aW9uKHIuRGVzY3JpcHRpb24oKSk7IGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCglyZXR1cm4gbmlsCn0KCi8vIHZhbGlkYXRlVGl0bGUgY2hlY2tzIGlmIHRoZSBwcm9wb3NhbCB0aXRsZSBtZWV0cyBsZW5ndGggYW5kIGNvbnRlbnQgcmVxdWlyZW1lbnRzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gdGl0bGU6IHRpdGxlIHN0cmluZyB0byB2YWxpZGF0ZQovLwovLyBSZXR1cm5zOgovLyAgIC0gZXJyb3I6IHZhbGlkYXRpb24gZXJyb3IgaWYgdGl0bGUgaXMgaW52YWxpZApmdW5jIChyICpQcm9wb3NhbE1ldGFkYXRhUmVzb2x2ZXIpIHZhbGlkYXRlVGl0bGUodGl0bGUgc3RyaW5nKSBlcnJvciB7CgkvLyBUaXRsZSBjYW5ub3QgYmUgZW1wdHkKCWlmIHRpdGxlID09ICIiIHsKCQlyZXR1cm4gbWFrZUVycm9yV2l0aERldGFpbHMoZXJySW52YWxpZElucHV0LCAidGl0bGUgaXMgZW1wdHkiKQoJfQoKCS8vIFRpdGxlIGNhbm5vdCBleGNlZWQgbWF4aW11bSBsZW5ndGgKCWlmIGxlbih0aXRsZSkgPiBtYXhUaXRsZUxlbmd0aCB7CgkJcmV0dXJuIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkSW5wdXQsCgkJCSJ0aXRsZSBpcyB0b28gbG9uZywgbWF4IGxlbmd0aCBpcyAyNTUgY2hhcmFjdGVycyIsCgkJKQoJfQoKCXJldHVybiBuaWwKfQoKLy8gdmFsaWRhdGVEZXNjcmlwdGlvbiBjaGVja3MgaWYgdGhlIHByb3Bvc2FsIGRlc2NyaXB0aW9uIG1lZXRzIGxlbmd0aCBhbmQgY29udGVudCByZXF1aXJlbWVudHMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBkZXNjcmlwdGlvbjogZGVzY3JpcHRpb24gc3RyaW5nIHRvIHZhbGlkYXRlCi8vCi8vIFJldHVybnM6Ci8vICAgLSBlcnJvcjogdmFsaWRhdGlvbiBlcnJvciBpZiBkZXNjcmlwdGlvbiBpcyBpbnZhbGlkCmZ1bmMgKHIgKlByb3Bvc2FsTWV0YWRhdGFSZXNvbHZlcikgdmFsaWRhdGVEZXNjcmlwdGlvbihkZXNjcmlwdGlvbiBzdHJpbmcpIGVycm9yIHsKCS8vIERlc2NyaXB0aW9uIGNhbm5vdCBiZSBlbXB0eQoJaWYgZGVzY3JpcHRpb24gPT0gIiIgewoJCXJldHVybiBtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZElucHV0LAoJCQkiZGVzY3JpcHRpb24gaXMgZW1wdHkiLAoJCSkKCX0KCgkvLyBEZXNjcmlwdGlvbiBjYW5ub3QgZXhjZWVkIG1heGltdW0gbGVuZ3RoCglpZiBsZW4oZGVzY3JpcHRpb24pID4gbWF4RGVzY3JpcHRpb25MZW5ndGggewoJCXJldHVybiBtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZElucHV0LAoJCQkiZGVzY3JpcHRpb24gaXMgdG9vIGxvbmcsIG1heCBsZW5ndGggaXMgMTAsMDAwIGNoYXJhY3RlcnMiLAoJCSkKCX0KCglyZXR1cm4gbmlsCn0KCi8vIFByb3Bvc2FsRGF0YVJlc29sdmVyIGhhbmRsZXMgYnVzaW5lc3MgbG9naWMgZm9yIHByb3Bvc2FsIGRhdGEuCnR5cGUgUHJvcG9zYWxEYXRhUmVzb2x2ZXIgc3RydWN0IHsKCSpnb3Zlcm5hbmNlLlByb3Bvc2FsRGF0YQp9CgovLyBOZXdQcm9wb3NhbERhdGFSZXNvbHZlciB3cmFwcyBwcm9wb3NhbCBkYXRhIGZvciB0eXBlLXNwZWNpZmljIHZhbGlkYXRpb24gYW5kCi8vIGV4ZWN1dGlvbi1tZXNzYWdlIHBhcnNpbmcuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwcm9wb3NhbERhdGE6IHByb3Bvc2FsIGRhdGEgdG8gcmVzb2x2ZSBhbmQgdmFsaWRhdGUuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqUHJvcG9zYWxEYXRhUmVzb2x2ZXI6IHJlc29sdmVyIGJhY2tlZCBieSBwcm9wb3NhbERhdGEuCmZ1bmMgTmV3UHJvcG9zYWxEYXRhUmVzb2x2ZXIocHJvcG9zYWxEYXRhICpnb3Zlcm5hbmNlLlByb3Bvc2FsRGF0YSkgKlByb3Bvc2FsRGF0YVJlc29sdmVyIHsKCXJldHVybiAmUHJvcG9zYWxEYXRhUmVzb2x2ZXJ7CgkJUHJvcG9zYWxEYXRhOiBwcm9wb3NhbERhdGEsCgl9Cn0KCi8vIFZhbGlkYXRlIHBlcmZvcm1zIHR5cGUtc3BlY2lmaWMgdmFsaWRhdGlvbiBvZiB0aGUgcHJvcG9zYWwgZGF0YS4KLy8gRGlmZmVyZW50IHByb3Bvc2FsIHR5cGVzIGhhdmUgZGlmZmVyZW50IHZhbGlkYXRpb24gcmVxdWlyZW1lbnRzLgovLwovLyBSZXR1cm5zOgovLyAgIC0gZXJyb3I6IHZhbGlkYXRpb24gZXJyb3IgaWYgZGF0YSBpcyBpbnZhbGlkCmZ1bmMgKHIgKlByb3Bvc2FsRGF0YVJlc29sdmVyKSBWYWxpZGF0ZSgpIGVycm9yIHsKCXN3aXRjaCByLlByb3Bvc2FsVHlwZSgpIHsKCWNhc2UgZ292ZXJuYW5jZS5UZXh0OgoJCXJldHVybiByLnZhbGlkYXRlVGV4dCgpCgljYXNlIGdvdmVybmFuY2UuQ29tbXVuaXR5UG9vbFNwZW5kOgoJCXJldHVybiByLnZhbGlkYXRlQ29tbXVuaXR5UG9vbFNwZW5kKCkKCWNhc2UgZ292ZXJuYW5jZS5QYXJhbWV0ZXJDaGFuZ2U6CgkJcmV0dXJuIHIudmFsaWRhdGVQYXJhbWV0ZXJDaGFuZ2UoKQoJfQoJcmV0dXJuIG5pbAp9CgovLyB2YWxpZGF0ZVRleHQgdmFsaWRhdGVzIHRleHQgcHJvcG9zYWwgZGF0YS4KLy8gVGV4dCBwcm9wb3NhbHMgaGF2ZSBubyBhZGRpdGlvbmFsIHZhbGlkYXRpb24gcmVxdWlyZW1lbnRzLgovLwovLyBSZXR1cm5zOgovLyAgIC0gZXJyb3I6IGFsd2F5cyBuaWwgZm9yIHRleHQgcHJvcG9zYWxzCmZ1bmMgKHIgKlByb3Bvc2FsRGF0YVJlc29sdmVyKSB2YWxpZGF0ZVRleHQoKSBlcnJvciB7CglyZXR1cm4gbmlsCn0KCi8vIHZhbGlkYXRlQ29tbXVuaXR5UG9vbFNwZW5kIHZhbGlkYXRlcyBjb21tdW5pdHkgcG9vbCBzcGVuZCBwcm9wb3NhbCBkYXRhLgovLyBDaGVja3MgcmVjaXBpZW50IGFkZHJlc3MsIHRva2VuIHBhdGgsIGFuZCBhbW91bnQgdmFsaWRpdHkuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBlcnJvcjogdmFsaWRhdGlvbiBlcnJvciBpZiBjb21tdW5pdHkgcG9vbCBzcGVuZCBkYXRhIGlzIGludmFsaWQKZnVuYyAociAqUHJvcG9zYWxEYXRhUmVzb2x2ZXIpIHZhbGlkYXRlQ29tbXVuaXR5UG9vbFNwZW5kKCkgZXJyb3IgewoJLy8gVmFsaWRhdGUgcmVjaXBpZW50IGFkZHJlc3MKCWNvbW11bml0eVBvb2xTcGVuZCA6PSByLlByb3Bvc2FsRGF0YS5Db21tdW5pdHlQb29sU3BlbmQoKQoJaWYgY29tbXVuaXR5UG9vbFNwZW5kID09IG5pbCB7CgkJcmV0dXJuIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkSW5wdXQsICJjb21tdW5pdHkgcG9vbCBzcGVuZCBpbmZvIGlzIG1pc3NpbmciKQoJfQoKCWlmICFjb21tdW5pdHlQb29sU3BlbmQuVG8oKS5Jc1ZhbGlkKCkgewoJCXJldHVybiBtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZElucHV0LCAidG8gaXMgaW52YWxpZCBhZGRyZXNzIikKCX0KCgkvLyBWYWxpZGF0ZSBhbW91bnQgaXMgZ3JlYXRlciB0aGFuIDAKCWlmIGNvbW11bml0eVBvb2xTcGVuZC5BbW91bnQoKSA8PSAwIHsKCQlyZXR1cm4gbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRJbnB1dCwgImFtb3VudCBpcyBub3QgcG9zaXRpdmUiKQoJfQoKCXJldHVybiBuaWwKfQoKLy8gdmFsaWRhdGVQYXJhbWV0ZXJDaGFuZ2UgdmFsaWRhdGVzIHBhcmFtZXRlciBjaGFuZ2UgcHJvcG9zYWwgZGF0YS4KLy8gRGVsZWdhdGVzIHRvIHZhbGlkYXRlRXhlY3V0aW9ucyBmb3IgZnVsbCB2YWxpZGF0aW9uIGluY2x1ZGluZyBjb3VudCBjaGVja3MsCi8vIG1lc3NhZ2UgZm9ybWF0LCBoYW5kbGVyIGV4aXN0ZW5jZSwgYW5kIHBhcmFtZXRlciB0eXBlIHZhbGlkYXRpb24uCi8vCi8vIFJldHVybnM6Ci8vICAgLSBlcnJvcjogdmFsaWRhdGlvbiBlcnJvciBpZiBwYXJhbWV0ZXIgY2hhbmdlIGRhdGEgaXMgaW52YWxpZApmdW5jIChyICpQcm9wb3NhbERhdGFSZXNvbHZlcikgdmFsaWRhdGVQYXJhbWV0ZXJDaGFuZ2UoKSBlcnJvciB7CglleGVjdXRpb24gOj0gci5FeGVjdXRpb24oKQoJaWYgZXhlY3V0aW9uID09IG5pbCB7CgkJcmV0dXJuIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkSW5wdXQsCgkJCSJleGVjdXRpb24gaW5mbyBpcyBtaXNzaW5nIiwKCQkpCgl9CglyZXR1cm4gdmFsaWRhdGVFeGVjdXRpb25zKGV4ZWN1dGlvbi5OdW0oKSwgZXhlY3V0aW9uLk1zZ3MoKSkKfQoKLy8gUGFyYW1ldGVyQ2hhbmdlc0luZm9zIHBhcnNlcyB0aGUgZXhlY3V0aW9uIG1lc3NhZ2VzIGFuZCByZXR1cm5zIHN0cnVjdHVyZWQgcGFyYW1ldGVyIGNoYW5nZSBpbmZvcm1hdGlvbi4KLy8gRWFjaCBtZXNzYWdlIGlzIGV4cGVjdGVkIHRvIGJlIGluIGZvcm1hdDogcGtnUGF0aCpFWEUqZnVuY3Rpb24qRVhFKnBhcmFtcwovLwovLyBSZXR1cm5zOgovLyAgIC0gW11QYXJhbWV0ZXJDaGFuZ2VJbmZvOiBzbGljZSBvZiBwYXJzZWQgcGFyYW1ldGVyIGNoYW5nZSBpbmZvcm1hdGlvbgovLyAgIC0gZXJyb3I6IHZhbGlkYXRpb24gZXJyb3IgaWYgYW55IGV4ZWN1dGlvbiBtZXNzYWdlIGlzIG1hbGZvcm1lZApmdW5jIChyICpQcm9wb3NhbERhdGFSZXNvbHZlcikgUGFyYW1ldGVyQ2hhbmdlc0luZm9zKCkgKFtdZ292ZXJuYW5jZS5QYXJhbWV0ZXJDaGFuZ2VJbmZvLCBlcnJvcikgewoJaW5mb3MgOj0gbWFrZShbXWdvdmVybmFuY2UuUGFyYW1ldGVyQ2hhbmdlSW5mbywgMCkKCgkvLyBSZXR1cm4gZW1wdHkgc2xpY2UgaWYgbm8gZXhlY3V0aW9ucwoJZXhlY3V0aW9uIDo9IHIuRXhlY3V0aW9uKCkKCWlmIGV4ZWN1dGlvbiA9PSBuaWwgfHwgZXhlY3V0aW9uLk51bSgpIDw9IDAgewoJCXJldHVybiBpbmZvcywgbmlsCgl9CgoJLy8gUGFyc2UgZWFjaCBleGVjdXRpb24gbWVzc2FnZQoJZm9yIF8sIG1zZyA6PSByYW5nZSBleGVjdXRpb24uTXNncygpIHsKCQlwa2dQYXRoLCBmdW5jdGlvbiwgcGFyYW1zLCBwYXJ0Q291bnQgOj0gcGFyc2VFeGVjdXRpb25NZXNzYWdlKG1zZykKCQlpZiBwYXJ0Q291bnQgIT0gMyB7CgkJCXJldHVybiBuaWwsIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQkJZXJySW52YWxpZE1lc3NhZ2VGb3JtYXQsCgkJCQl1Zm10LlNwcmludGYoIm1hbGZvcm1lZCBleGVjdXRpb24gbWVzc2FnZTogZXhwZWN0ZWQgMyBwYXJ0cyAocGtnUGF0aCwgZnVuY3Rpb24sIHBhcmFtcyksIGdvdCAlZCIsIHBhcnRDb3VudCksCgkJCSkKCQl9CgoJCS8vIENyZWF0ZSBwYXJhbWV0ZXIgY2hhbmdlIGluZm8gc3RydWN0dXJlCgkJaW5mbyA6PSBnb3Zlcm5hbmNlLk5ld1BhcmFtZXRlckNoYW5nZUluZm8ocGtnUGF0aCwgZnVuY3Rpb24sIHBhcmFtcykKCQlpbmZvcyA9IGFwcGVuZChpbmZvcywgaW5mbykKCX0KCglyZXR1cm4gaW5mb3MsIG5pbAp9CgovLyBOZXdQcm9wb3NhbFRleHREYXRhIGNyZWF0ZXMgcHJvcG9zYWwgZGF0YSBmb3IgYSB0ZXh0IHByb3Bvc2FsLgovLyBUZXh0IHByb3Bvc2FscyBoYXZlIG5vIGFkZGl0aW9uYWwgZGF0YSByZXF1aXJlbWVudHMuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqUHJvcG9zYWxEYXRhOiBwcm9wb3NhbCBkYXRhIGNvbmZpZ3VyZWQgZm9yIHRleHQgcHJvcG9zYWwKZnVuYyBOZXdQcm9wb3NhbFRleHREYXRhKCkgKmdvdmVybmFuY2UuUHJvcG9zYWxEYXRhIHsKCXJldHVybiBnb3Zlcm5hbmNlLk5ld1Byb3Bvc2FsRGF0YShnb3Zlcm5hbmNlLlRleHQsIG5pbCwgbmlsKQp9CgovLyBOZXdQcm9wb3NhbENvbW11bml0eVBvb2xTcGVuZERhdGEgY3JlYXRlcyBwcm9wb3NhbCBkYXRhIGZvciBhIGNvbW11bml0eSBwb29sIHNwZW5kIHByb3Bvc2FsLgovLyBBdXRvbWF0aWNhbGx5IGdlbmVyYXRlcyB0aGUgZXhlY3V0aW9uIG1lc3NhZ2UgZm9yIHRoZSB0b2tlbiB0cmFuc2Zlci4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHRva2VuUGF0aDogcGF0aCBvZiB0aGUgdG9rZW4gdG8gdHJhbnNmZXIKLy8gICAtIHRvOiByZWNpcGllbnQgYWRkcmVzcyBmb3IgdGhlIHRyYW5zZmVyCi8vICAgLSBhbW91bnQ6IGFtb3VudCBvZiB0b2tlbnMgdG8gdHJhbnNmZXIKLy8gICAtIGNvbW11bml0eVBvb2xQYWNrYWdlUGF0aDogcGFja2FnZSBwYXRoIG9mIHRoZSBjb21tdW5pdHkgcG9vbCBjb250cmFjdAovLwovLyBSZXR1cm5zOgovLyAgIC0gKlByb3Bvc2FsRGF0YTogcHJvcG9zYWwgZGF0YSBjb25maWd1cmVkIGZvciBjb21tdW5pdHkgcG9vbCBzcGVuZGluZwpmdW5jIE5ld1Byb3Bvc2FsQ29tbXVuaXR5UG9vbFNwZW5kRGF0YSgKCXRva2VuUGF0aCBzdHJpbmcsCgl0byBhZGRyZXNzLAoJYW1vdW50IGludDY0LAoJY29tbXVuaXR5UG9vbFBhY2thZ2VQYXRoIHN0cmluZywKKSAqZ292ZXJuYW5jZS5Qcm9wb3NhbERhdGEgewoJLy8gQ3JlYXRlIGV4ZWN1dGlvbiBtZXNzYWdlIGZvciB0aGUgdG9rZW4gdHJhbnNmZXIKCWV4ZWN1dGlvbkluZm9NZXNzYWdlIDo9IG1ha2VFeGVjdXRlTWVzc2FnZSgKCQljb21tdW5pdHlQb29sUGFja2FnZVBhdGgsCgkJIlRyYW5zZmVyVG9rZW4iLAoJCVtdc3RyaW5ne3Rva2VuUGF0aCwgdG8uU3RyaW5nKCksIHV0aWxzLkZvcm1hdEludChhbW91bnQpfSwKCSkKCglyZXR1cm4gZ292ZXJuYW5jZS5OZXdQcm9wb3NhbERhdGEoCgkJZ292ZXJuYW5jZS5Db21tdW5pdHlQb29sU3BlbmQsCgkJZ292ZXJuYW5jZS5OZXdDb21tdW5pdHlQb29sU3BlbmRJbmZvKHRvLCB0b2tlblBhdGgsIGFtb3VudCksCgkJZ292ZXJuYW5jZS5OZXdFeGVjdXRpb25JbmZvKDEsIFtdc3RyaW5ne2V4ZWN1dGlvbkluZm9NZXNzYWdlfSksCgkpCn0KCi8vIE5ld1Byb3Bvc2FsRXhlY3V0aW9uRGF0YSBjcmVhdGVzIHByb3Bvc2FsIGRhdGEgZm9yIGEgcGFyYW1ldGVyIGNoYW5nZSBwcm9wb3NhbC4KLy8gRWFjaCBtZXNzYWdlIGluIGV4ZWN1dGlvbnMgc2hvdWxkIGJlIGZvcm1hdHRlZCBhcyA8cGtnUGF0aD4qRVhFKjxmdW5jdGlvbj4qRVhFKjxwYXJhbXM+LAovLyBzZXBhcmF0ZWQgYnkgKkdPViogd2hlbiB0aGVyZSBhcmUgbXVsdGlwbGUgbWVzc2FnZXMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBudW1Ub0V4ZWN1dGU6IG51bWJlciBvZiBwYXJhbWV0ZXIgY2hhbmdlcyB0byBleGVjdXRlCi8vICAgLSBleGVjdXRpb25zOiByYXcgZW5jb2RlZCBleGVjdXRpb24gc3RyaW5nIHdpdGggcGFyYW1ldGVyIGNoYW5nZXMKLy8KLy8gUmV0dXJuczoKLy8gICAtICpQcm9wb3NhbERhdGE6IHByb3Bvc2FsIGRhdGEgY29uZmlndXJlZCBmb3IgcGFyYW1ldGVyIGNoYW5nZXMKZnVuYyBOZXdQcm9wb3NhbEV4ZWN1dGlvbkRhdGEobnVtVG9FeGVjdXRlIGludDY0LCBleGVjdXRpb25zIHN0cmluZykgKmdvdmVybmFuY2UuUHJvcG9zYWxEYXRhIHsKCXJldHVybiBnb3Zlcm5hbmNlLk5ld1Byb3Bvc2FsRGF0YSgKCQlnb3Zlcm5hbmNlLlBhcmFtZXRlckNoYW5nZSwKCQluaWwsCgkJZ292ZXJuYW5jZS5OZXdFeGVjdXRpb25JbmZvKG51bVRvRXhlY3V0ZSwgc3BsaXRFeGVjdXRpb25zUmF3KGV4ZWN1dGlvbnMpKSwKCSkKfQoKLy8gbWFrZUV4ZWN1dGVNZXNzYWdlIGNyZWF0ZXMgYSBtZXNzYWdlIHRvIGV4ZWN1dGUgYSBmdW5jdGlvbi4KLy8gTWVzc2FnZSBmb3JtYXQ6IDxwa2dQYXRoPipFWEUqPGZ1bmN0aW9uPipFWEUqPHBhcmFtcz4uCmZ1bmMgbWFrZUV4ZWN1dGVNZXNzYWdlKHBrZ1BhdGgsIGZ1bmN0aW9uIHN0cmluZywgcGFyYW1zIFtdc3RyaW5nKSBzdHJpbmcgewoJbWVzc2FnZVBhcmFtcyA6PSBbXXN0cmluZ3sKCQlwa2dQYXRoLAoJCWZ1bmN0aW9uLAoJCXN0cmluZ3MuSm9pbihwYXJhbXMsICIsIiksCgl9CglyZXR1cm4gc3RyaW5ncy5Kb2luKG1lc3NhZ2VQYXJhbXMsIHBhcmFtZXRlclNlcGFyYXRvcikKfQoa1R8KHHByb3Bvc2FsX3NjaGVkdWxlX3N0YXR1cy5nbm8StB9wYWNrYWdlIGdvdmVybmFuY2UKCmltcG9ydCAoCglnbnNtYXRoICJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9nb3Zlcm5hbmNlIgopCgp0eXBlIFByb3Bvc2FsU2NoZWR1bGVTdGF0dXNSZXNvbHZlciBzdHJ1Y3QgewoJKmdvdmVybmFuY2UuUHJvcG9zYWxTY2hlZHVsZVN0YXR1cwp9CgovLyBOZXdQcm9wb3NhbFNjaGVkdWxlU3RhdHVzUmVzb2x2ZXIgd3JhcHMgYSBwcm9wb3NhbCBzY2hlZHVsZSBmb3IgcGhhc2UtYm91bmRhcnkgcXVlcmllcy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHN0YXR1czogcHJvcG9zYWwgc2NoZWR1bGUgY29udGFpbmluZyBjcmVhdGlvbiwgdm90aW5nLCBhbmQgZXhlY3V0aW9uIHRpbWVzdGFtcHMKLy8KLy8gUmV0dXJuczoKLy8gICAtICpQcm9wb3NhbFNjaGVkdWxlU3RhdHVzUmVzb2x2ZXI6IHJlc29sdmVyIGJhY2tlZCBieSBzdGF0dXMKZnVuYyBOZXdQcm9wb3NhbFNjaGVkdWxlU3RhdHVzUmVzb2x2ZXIoc3RhdHVzICpnb3Zlcm5hbmNlLlByb3Bvc2FsU2NoZWR1bGVTdGF0dXMpICpQcm9wb3NhbFNjaGVkdWxlU3RhdHVzUmVzb2x2ZXIgewoJcmV0dXJuICZQcm9wb3NhbFNjaGVkdWxlU3RhdHVzUmVzb2x2ZXJ7c3RhdHVzfQp9CgovLyBJc1Bhc3NlZENyZWF0ZWRBdCBjaGVja3MgaWYgdGhlIGN1cnJlbnQgdGltZSBoYXMgcGFzc2VkIHRoZSBwcm9wb3NhbCBjcmVhdGlvbiB0aW1lLgovLyBUaGlzIGlzIGFsd2F5cyB0cnVlIG9uY2UgYSBwcm9wb3NhbCBleGlzdHMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjdXJyZW50OiB0aW1lc3RhbXAgdG8gY2hlY2sgYWdhaW5zdAovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSBpZiBjdXJyZW50IHRpbWUgaXMgYXQgb3IgYWZ0ZXIgY3JlYXRpb24gdGltZQpmdW5jIChwICpQcm9wb3NhbFNjaGVkdWxlU3RhdHVzUmVzb2x2ZXIpIElzUGFzc2VkQ3JlYXRlZEF0KGN1cnJlbnQgaW50NjQpIGJvb2wgewoJcmV0dXJuIHAuQ3JlYXRlVGltZSgpIDw9IGN1cnJlbnQKfQoKLy8gSXNQYXNzZWRBY3RpdmVBdCBjaGVja3MgaWYgdGhlIGN1cnJlbnQgdGltZSBoYXMgcGFzc2VkIHRoZSB2b3Rpbmcgc3RhcnQgdGltZS4KLy8gV2hlbiB0cnVlLCB0aGUgcHJvcG9zYWwgZW50ZXJzIGl0cyBhY3RpdmUgdm90aW5nIHBlcmlvZC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnQ6IHRpbWVzdGFtcCB0byBjaGVjayBhZ2FpbnN0Ci8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIGlmIHZvdGluZyBwZXJpb2QgaGFzIHN0YXJ0ZWQKZnVuYyAocCAqUHJvcG9zYWxTY2hlZHVsZVN0YXR1c1Jlc29sdmVyKSBJc1Bhc3NlZEFjdGl2ZUF0KGN1cnJlbnQgaW50NjQpIGJvb2wgewoJcmV0dXJuIHAuQWN0aXZlVGltZSgpIDw9IGN1cnJlbnQKfQoKLy8gSXNQYXNzZWRWb3RpbmdFbmRlZEF0IGNoZWNrcyBpZiB0aGUgY3VycmVudCB0aW1lIGhhcyBwYXNzZWQgdGhlIHZvdGluZyBlbmQgdGltZS4KLy8gV2hlbiB0cnVlLCBubyBtb3JlIHZvdGVzIGNhbiBiZSBjYXN0IG9uIHRoZSBwcm9wb3NhbC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnQ6IHRpbWVzdGFtcCB0byBjaGVjayBhZ2FpbnN0Ci8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIGlmIHZvdGluZyBwZXJpb2QgaGFzIGVuZGVkCmZ1bmMgKHAgKlByb3Bvc2FsU2NoZWR1bGVTdGF0dXNSZXNvbHZlcikgSXNQYXNzZWRWb3RpbmdFbmRlZEF0KGN1cnJlbnQgaW50NjQpIGJvb2wgewoJcmV0dXJuIHAuVm90aW5nRW5kVGltZSgpIDw9IGN1cnJlbnQKfQoKLy8gSXNQYXNzZWRFeGVjdXRhYmxlQXQgY2hlY2tzIGlmIHRoZSBjdXJyZW50IHRpbWUgaGFzIHBhc3NlZCB0aGUgZXhlY3V0aW9uIHN0YXJ0IHRpbWUuCi8vIFdoZW4gdHJ1ZSwgYXBwcm92ZWQgcHJvcG9zYWxzIGNhbiBiZSBleGVjdXRlZCAoYWZ0ZXIgZXhlY3V0aW9uIGRlbGF5KS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnQ6IHRpbWVzdGFtcCB0byBjaGVjayBhZ2FpbnN0Ci8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIGlmIGV4ZWN1dGlvbiB3aW5kb3cgaGFzIHN0YXJ0ZWQKZnVuYyAocCAqUHJvcG9zYWxTY2hlZHVsZVN0YXR1c1Jlc29sdmVyKSBJc1Bhc3NlZEV4ZWN1dGFibGVBdChjdXJyZW50IGludDY0KSBib29sIHsKCXJldHVybiBwLkV4ZWN1dGFibGVUaW1lKCkgPD0gY3VycmVudAp9CgovLyBJc1Bhc3NlZEV4cGlyZWRBdCBjaGVja3MgaWYgdGhlIGN1cnJlbnQgdGltZSBoYXMgcGFzc2VkIHRoZSBleGVjdXRpb24gZXhwaXJhdGlvbiB0aW1lLgovLyBXaGVuIHRydWUsIHRoZSBwcm9wb3NhbCBjYW4gbm8gbG9uZ2VyIGJlIGV4ZWN1dGVkIGFuZCBoYXMgZXhwaXJlZC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnQ6IHRpbWVzdGFtcCB0byBjaGVjayBhZ2FpbnN0Ci8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIGlmIGV4ZWN1dGlvbiB3aW5kb3cgaGFzIGV4cGlyZWQKZnVuYyAocCAqUHJvcG9zYWxTY2hlZHVsZVN0YXR1c1Jlc29sdmVyKSBJc1Bhc3NlZEV4cGlyZWRBdChjdXJyZW50IGludDY0KSBib29sIHsKCXJldHVybiBwLkV4cGlyZWRUaW1lKCkgPD0gY3VycmVudAp9CgovLyBOZXdQcm9wb3NhbFNjaGVkdWxlU3RhdHVzIGNyZWF0ZXMgYSBuZXcgc2NoZWR1bGUgc3RhdHVzIHdpdGggY2FsY3VsYXRlZCB0aW1lc3RhbXBzLgovLyBUaGlzIGNvbnN0cnVjdG9yIHRha2VzIHRoZSBnb3Zlcm5hbmNlIHRpbWluZyBwYXJhbWV0ZXJzIGFuZCBjYWxjdWxhdGVzIGFsbAovLyBpbXBvcnRhbnQgdGltZXN0YW1wcyBmb3IgdGhlIHByb3Bvc2FsJ3MgbGlmZWN5Y2xlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gdm90aW5nU3RhcnREZWxheTogZGVsYXkgYmVmb3JlIHZvdGluZyBzdGFydHMgKHNlY29uZHMpCi8vICAgLSB2b3RpbmdQZXJpb2Q6IGR1cmF0aW9uIG9mIHZvdGluZyBwZXJpb2QgKHNlY29uZHMpCi8vICAgLSBleGVjdXRpb25EZWxheTogZGVsYXkgYmVmb3JlIGV4ZWN1dGlvbiBjYW4gc3RhcnQgKHNlY29uZHMpCi8vICAgLSBleGVjdXRpb25XaW5kb3c6IHdpbmRvdyBkdXJpbmcgd2hpY2ggZXhlY3V0aW9uIGlzIGFsbG93ZWQgKHNlY29uZHMpCi8vICAgLSBjcmVhdGVkQXQ6IHRpbWVzdGFtcCB3aGVuIHByb3Bvc2FsIHdhcyBjcmVhdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqUHJvcG9zYWxTY2hlZHVsZVN0YXR1czogbmV3IHNjaGVkdWxlIHN0YXR1cyB3aXRoIGNhbGN1bGF0ZWQgdGltZXMKZnVuYyBOZXdQcm9wb3NhbFNjaGVkdWxlU3RhdHVzKAoJdm90aW5nU3RhcnREZWxheSwKCXZvdGluZ1BlcmlvZCwKCWV4ZWN1dGlvbkRlbGF5LAoJZXhlY3V0aW9uV2luZG93LAoJY3JlYXRlZEF0IGludDY0LAopICpnb3Zlcm5hbmNlLlByb3Bvc2FsU2NoZWR1bGVTdGF0dXMgewoJLy8gQ2FsY3VsYXRlIGFsbCBwaGFzZSB0aW1lc3RhbXBzIGJhc2VkIG9uIGNyZWF0aW9uIHRpbWUgYW5kIGNvbmZpZ3VyYXRpb24KCWNyZWF0ZVRpbWUgOj0gY3JlYXRlZEF0CglhY3RpdmVUaW1lIDo9IGduc21hdGguU2FmZUFkZEludDY0KGNyZWF0ZVRpbWUsIHZvdGluZ1N0YXJ0RGVsYXkpICAgICAgLy8gV2hlbiB2b3RpbmcgY2FuIHN0YXJ0Cgl2b3RpbmdFbmRUaW1lIDo9IGduc21hdGguU2FmZUFkZEludDY0KGFjdGl2ZVRpbWUsIHZvdGluZ1BlcmlvZCkgICAgICAgLy8gV2hlbiB2b3RpbmcgZW5kcwoJZXhlY3V0YWJsZVRpbWUgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQodm90aW5nRW5kVGltZSwgZXhlY3V0aW9uRGVsYXkpIC8vIFdoZW4gZXhlY3V0aW9uIGNhbiBzdGFydAoJZXhwaXJlZFRpbWUgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQoZXhlY3V0YWJsZVRpbWUsIGV4ZWN1dGlvbldpbmRvdykgIC8vIFdoZW4gZXhlY3V0aW9uIHdpbmRvdyBjbG9zZXMKCglyZXR1cm4gZ292ZXJuYW5jZS5OZXdQcm9wb3NhbFNjaGVkdWxlU3RhdHVzKGNyZWF0ZVRpbWUsIGFjdGl2ZVRpbWUsIHZvdGluZ0VuZFRpbWUsIGV4ZWN1dGFibGVUaW1lLCBleHBpcmVkVGltZSkKfQoavT4KE3Byb3Bvc2FsX3N0YXR1cy5nbm8SpT5wYWNrYWdlIGdvdmVybmFuY2UKCmltcG9ydCAoCglnbnNtYXRoICJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9nb3Zlcm5hbmNlIgopCgp0eXBlIFByb3Bvc2FsU3RhdHVzUmVzb2x2ZXIgc3RydWN0IHsKCSpnb3Zlcm5hbmNlLlByb3Bvc2FsU3RhdHVzCglzY2hlZHVsZVJlc29sdmVyICAgICAqUHJvcG9zYWxTY2hlZHVsZVN0YXR1c1Jlc29sdmVyCglhY3Rpb25TdGF0dXNSZXNvbHZlciAqUHJvcG9zYWxBY3Rpb25TdGF0dXNSZXNvbHZlcgoJdm90ZVN0YXR1c1Jlc29sdmVyICAgKlByb3Bvc2FsVm90ZVN0YXR1c1Jlc29sdmVyCn0KCi8vIE5ld1Byb3Bvc2FsU3RhdHVzUmVzb2x2ZXIgd3JhcHMgcHJvcG9zYWwgc3RhdHVzIGNvbXBvbmVudHMgZm9yIGxpZmVjeWNsZSBhbmQgdm90ZSBxdWVyaWVzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gc3RhdHVzOiBwcm9wb3NhbCBzdGF0dXMgY29udGFpbmluZyBzY2hlZHVsZSwgYWN0aW9uLCBhbmQgdm90ZSBzdGF0ZQovLwovLyBSZXR1cm5zOgovLyAgIC0gKlByb3Bvc2FsU3RhdHVzUmVzb2x2ZXI6IHJlc29sdmVyIGJhY2tlZCBieSBzdGF0dXMKZnVuYyBOZXdQcm9wb3NhbFN0YXR1c1Jlc29sdmVyKHN0YXR1cyAqZ292ZXJuYW5jZS5Qcm9wb3NhbFN0YXR1cykgKlByb3Bvc2FsU3RhdHVzUmVzb2x2ZXIgewoJcmV0dXJuICZQcm9wb3NhbFN0YXR1c1Jlc29sdmVyewoJCVByb3Bvc2FsU3RhdHVzOiAgICAgICBzdGF0dXMsCgkJc2NoZWR1bGVSZXNvbHZlcjogICAgIE5ld1Byb3Bvc2FsU2NoZWR1bGVTdGF0dXNSZXNvbHZlcihzdGF0dXMuU2NoZWR1bGUoKSksCgkJYWN0aW9uU3RhdHVzUmVzb2x2ZXI6IE5ld1Byb3Bvc2FsQWN0aW9uU3RhdHVzUmVzb2x2ZXIoc3RhdHVzLkFjdGlvblN0YXR1cygpKSwKCQl2b3RlU3RhdHVzUmVzb2x2ZXI6ICAgTmV3UHJvcG9zYWxWb3RlU3RhdHVzUmVzb2x2ZXIoc3RhdHVzLlZvdGVTdGF0dXMoKSksCgl9Cn0KCi8vIFRvdGFsVm90ZVdlaWdodCByZXR1cm5zIHRoZSB0b3RhbCB3ZWlnaHQgb2YgYWxsIHZvdGVzIGNhc3QuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogdG90YWwgdm90ZSB3ZWlnaHQKZnVuYyAocCAqUHJvcG9zYWxTdGF0dXNSZXNvbHZlcikgVG90YWxWb3RlV2VpZ2h0KCkgaW50NjQgewoJcmV0dXJuIHAudm90ZVN0YXR1c1Jlc29sdmVyLlRvdGFsVm90ZVdlaWdodCgpCn0KCi8vIFN0YXR1c1R5cGUgZGV0ZXJtaW5lcyB0aGUgY3VycmVudCBzdGF0dXMgb2YgdGhlIHByb3Bvc2FsIGJhc2VkIG9uIHRpbWluZywgdm90aW5nLCBhbmQgYWN0aW9ucy4KLy8gVGhpcyBpcyB0aGUgbWFpbiBzdGF0dXMgY2FsY3VsYXRpb24gbWV0aG9kIHRoYXQgY29uc2lkZXJzIGFsbCBmYWN0b3JzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gY3VycmVudDogY3VycmVudCB0aW1lc3RhbXAgdG8gZXZhbHVhdGUgc3RhdHVzIGF0Ci8vCi8vIFJldHVybnM6Ci8vICAgLSBQcm9wb3NhbFN0YXR1c1R5cGU6IGN1cnJlbnQgc3RhdHVzIG9mIHRoZSBwcm9wb3NhbApmdW5jIChwICpQcm9wb3NhbFN0YXR1c1Jlc29sdmVyKSBTdGF0dXNUeXBlKGN1cnJlbnQgaW50NjQpIGdvdmVybmFuY2UuUHJvcG9zYWxTdGF0dXNUeXBlIHsKCWFjdGlvblN0YXR1cyA6PSBwLkFjdGlvblN0YXR1cygpCgoJLy8gQ2hlY2sgYWN0aW9uLWJhc2VkIHN0YXR1c2VzIGZpcnN0ICh0aGVzZSBvdmVycmlkZSB0aW1lLWJhc2VkIHN0YXR1c2VzKQoJaWYgYWN0aW9uU3RhdHVzLklzRXhlY3V0ZWQoKSB7CgkJcmV0dXJuIGdvdmVybmFuY2UuU3RhdHVzRXhlY3V0ZWQKCX0KCglpZiBhY3Rpb25TdGF0dXMuQ2FuY2VsZWQoKSB7CgkJcmV0dXJuIGdvdmVybmFuY2UuU3RhdHVzQ2FuY2VsZWQKCX0KCgkvLyBDaGVjayB0aW1lLWJhc2VkIHN0YXR1c2VzCglpZiAhcC5zY2hlZHVsZVJlc29sdmVyLklzUGFzc2VkQWN0aXZlQXQoY3VycmVudCkgewoJCXJldHVybiBnb3Zlcm5hbmNlLlN0YXR1c1VwY29taW5nCgl9CgoJaWYgIXAuc2NoZWR1bGVSZXNvbHZlci5Jc1Bhc3NlZFZvdGluZ0VuZGVkQXQoY3VycmVudCkgewoJCXJldHVybiBnb3Zlcm5hbmNlLlN0YXR1c0FjdGl2ZQoJfQoKCS8vIENoZWNrIHZvdGluZyBvdXRjb21lIGFmdGVyIHZvdGluZyBwZXJpb2QgZW5kcwoJaWYgIXAudm90ZVN0YXR1c1Jlc29sdmVyLklzUGFzc2VkKCkgewoJCXJldHVybiBnb3Zlcm5hbmNlLlN0YXR1c1JlamVjdGVkCgl9CgoJLy8gRm9yIHBhc3NlZCBwcm9wb3NhbHMsIGNoZWNrIGV4ZWN1dGlvbiBzdGF0dXMKCWlmICFwLkFjdGlvblN0YXR1cygpLklzRXhlY3V0YWJsZSgpIHx8ICFwLnNjaGVkdWxlUmVzb2x2ZXIuSXNQYXNzZWRFeGVjdXRhYmxlQXQoY3VycmVudCkgewoJCXJldHVybiBnb3Zlcm5hbmNlLlN0YXR1c1Bhc3NlZAoJfQoKCWlmICFwLnNjaGVkdWxlUmVzb2x2ZXIuSXNQYXNzZWRFeHBpcmVkQXQoY3VycmVudCkgewoJCXJldHVybiBnb3Zlcm5hbmNlLlN0YXR1c0V4ZWN1dGFibGUKCX0KCglyZXR1cm4gZ292ZXJuYW5jZS5TdGF0dXNFeHBpcmVkCn0KCi8vIElzVXBjb21pbmcgY2hlY2tzIGlmIHRoZSBwcm9wb3NhbCBpcyBpbiB1cGNvbWluZyBzdGF0dXMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjdXJyZW50OiB0aW1lc3RhbXAgdG8gY2hlY2sgc3RhdHVzIGF0Ci8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIGlmIHByb3Bvc2FsIGlzIHVwY29taW5nCmZ1bmMgKHAgKlByb3Bvc2FsU3RhdHVzUmVzb2x2ZXIpIElzVXBjb21pbmcoY3VycmVudCBpbnQ2NCkgYm9vbCB7CglyZXR1cm4gcC5TdGF0dXNUeXBlKGN1cnJlbnQpID09IGdvdmVybmFuY2UuU3RhdHVzVXBjb21pbmcKfQoKLy8gSXNBY3RpdmUgY2hlY2tzIGlmIHRoZSBwcm9wb3NhbCBpcyBpbiBhY3RpdmUgdm90aW5nIHN0YXR1cy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnQ6IHRpbWVzdGFtcCB0byBjaGVjayBzdGF0dXMgYXQKLy8KLy8gUmV0dXJuczoKLy8gICAtIGJvb2w6IHRydWUgaWYgcHJvcG9zYWwgaXMgYWN0aXZlICh2b3RpbmcgcGVyaW9kKQpmdW5jIChwICpQcm9wb3NhbFN0YXR1c1Jlc29sdmVyKSBJc0FjdGl2ZShjdXJyZW50IGludDY0KSBib29sIHsKCXJldHVybiBwLlN0YXR1c1R5cGUoY3VycmVudCkgPT0gZ292ZXJuYW5jZS5TdGF0dXNBY3RpdmUKfQoKLy8gSXNQYXNzZWQgY2hlY2tzIGlmIHRoZSBwcm9wb3NhbCBoYXMgcGFzc2VkIHZvdGluZy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnQ6IHRpbWVzdGFtcCB0byBjaGVjayBzdGF0dXMgYXQKLy8KLy8gUmV0dXJuczoKLy8gICAtIGJvb2w6IHRydWUgaWYgcHJvcG9zYWwgaGFzIHBhc3NlZApmdW5jIChwICpQcm9wb3NhbFN0YXR1c1Jlc29sdmVyKSBJc1Bhc3NlZChjdXJyZW50IGludDY0KSBib29sIHsKCXJldHVybiBwLlN0YXR1c1R5cGUoY3VycmVudCkgPT0gZ292ZXJuYW5jZS5TdGF0dXNQYXNzZWQKfQoKLy8gSXNSZWplY3RlZCBjaGVja3MgaWYgdGhlIHByb3Bvc2FsIGhhcyBiZWVuIHJlamVjdGVkIGJ5IHZvdGluZy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnQ6IHRpbWVzdGFtcCB0byBjaGVjayBzdGF0dXMgYXQKLy8KLy8gUmV0dXJuczoKLy8gICAtIGJvb2w6IHRydWUgaWYgcHJvcG9zYWwgd2FzIHJlamVjdGVkCmZ1bmMgKHAgKlByb3Bvc2FsU3RhdHVzUmVzb2x2ZXIpIElzUmVqZWN0ZWQoY3VycmVudCBpbnQ2NCkgYm9vbCB7CglyZXR1cm4gcC5TdGF0dXNUeXBlKGN1cnJlbnQpID09IGdvdmVybmFuY2UuU3RhdHVzUmVqZWN0ZWQKfQoKLy8gSXNFeGVjdXRhYmxlIGNoZWNrcyBpZiB0aGUgcHJvcG9zYWwgaXMgaW4gZXhlY3V0YWJsZSBzdGF0dXMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjdXJyZW50OiB0aW1lc3RhbXAgdG8gY2hlY2sgc3RhdHVzIGF0Ci8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIGlmIHByb3Bvc2FsIGNhbiBiZSBleGVjdXRlZApmdW5jIChwICpQcm9wb3NhbFN0YXR1c1Jlc29sdmVyKSBJc0V4ZWN1dGFibGUoY3VycmVudCBpbnQ2NCkgYm9vbCB7CglyZXR1cm4gcC5TdGF0dXNUeXBlKGN1cnJlbnQpID09IGdvdmVybmFuY2UuU3RhdHVzRXhlY3V0YWJsZQp9CgovLyBJc0V4cGlyZWQgY2hlY2tzIGlmIHRoZSBwcm9wb3NhbCBleGVjdXRpb24gd2luZG93IGhhcyBleHBpcmVkLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gY3VycmVudDogdGltZXN0YW1wIHRvIGNoZWNrIHN0YXR1cyBhdAovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSBpZiBwcm9wb3NhbCBoYXMgZXhwaXJlZApmdW5jIChwICpQcm9wb3NhbFN0YXR1c1Jlc29sdmVyKSBJc0V4cGlyZWQoY3VycmVudCBpbnQ2NCkgYm9vbCB7CglyZXR1cm4gcC5TdGF0dXNUeXBlKGN1cnJlbnQpID09IGdvdmVybmFuY2UuU3RhdHVzRXhwaXJlZAp9CgovLyBJc0V4ZWN1dGVkIGNoZWNrcyBpZiB0aGUgcHJvcG9zYWwgaGFzIGJlZW4gZXhlY3V0ZWQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjdXJyZW50OiB0aW1lc3RhbXAgdG8gY2hlY2sgc3RhdHVzIGF0Ci8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIGlmIHByb3Bvc2FsIGhhcyBiZWVuIGV4ZWN1dGVkCmZ1bmMgKHAgKlByb3Bvc2FsU3RhdHVzUmVzb2x2ZXIpIElzRXhlY3V0ZWQoY3VycmVudCBpbnQ2NCkgYm9vbCB7CglyZXR1cm4gcC5TdGF0dXNUeXBlKGN1cnJlbnQpID09IGdvdmVybmFuY2UuU3RhdHVzRXhlY3V0ZWQKfQoKLy8gSXNDYW5jZWxlZCBjaGVja3MgaWYgdGhlIHByb3Bvc2FsIGhhcyBiZWVuIGNhbmNlbGVkLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gY3VycmVudDogdGltZXN0YW1wIHRvIGNoZWNrIHN0YXR1cyBhdAovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSBpZiBwcm9wb3NhbCBoYXMgYmVlbiBjYW5jZWxlZApmdW5jIChwICpQcm9wb3NhbFN0YXR1c1Jlc29sdmVyKSBJc0NhbmNlbGVkKGN1cnJlbnQgaW50NjQpIGJvb2wgewoJcmV0dXJuIHAuU3RhdHVzVHlwZShjdXJyZW50KSA9PSBnb3Zlcm5hbmNlLlN0YXR1c0NhbmNlbGVkCn0KCi8vIGNhbmNlbCBtYXJrcyB0aGUgcHJvcG9zYWwgYXMgY2FuY2VsZWQgd2l0aCB0aGUgcHJvdmlkZWQgZGV0YWlscy4KLy8gVGhpcyBkZWxlZ2F0ZXMgdG8gdGhlIGFjdGlvbiBzdGF0dXMgZm9yIGFjdHVhbCBjYW5jZWxsYXRpb24gbG9naWMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjYW5jZWxlZEF0OiB0aW1lc3RhbXAgd2hlbiBwcm9wb3NhbCB3YXMgY2FuY2VsZWQKLy8gICAtIGNhbmNlbGVkSGVpZ2h0OiBibG9jayBoZWlnaHQgd2hlbiBwcm9wb3NhbCB3YXMgY2FuY2VsZWQKLy8gICAtIGNhbmNlbGVkQnk6IGFkZHJlc3MgdGhhdCBjYW5jZWxlZCB0aGUgcHJvcG9zYWwKLy8KLy8gUmV0dXJuczoKLy8gICAtIGVycm9yOiBjYW5jZWxsYXRpb24gZXJyb3IgaWYgb3BlcmF0aW9uIGZhaWxzCmZ1bmMgKHAgKlByb3Bvc2FsU3RhdHVzUmVzb2x2ZXIpIGNhbmNlbChjYW5jZWxlZEF0IGludDY0LCBjYW5jZWxlZEhlaWdodCBpbnQ2NCwgY2FuY2VsZWRCeSBhZGRyZXNzKSBlcnJvciB7CglyZXR1cm4gcC5hY3Rpb25TdGF0dXNSZXNvbHZlci5jYW5jZWwoY2FuY2VsZWRBdCwgY2FuY2VsZWRIZWlnaHQsIGNhbmNlbGVkQnkpCn0KCi8vIGV4ZWN1dGUgbWFya3MgdGhlIHByb3Bvc2FsIGFzIGV4ZWN1dGVkIHdpdGggdGhlIHByb3ZpZGVkIGRldGFpbHMuCi8vIFRoaXMgZGVsZWdhdGVzIHRvIHRoZSBhY3Rpb24gc3RhdHVzIGZvciBhY3R1YWwgZXhlY3V0aW9uIGxvZ2ljLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gZXhlY3V0ZWRBdDogdGltZXN0YW1wIHdoZW4gcHJvcG9zYWwgd2FzIGV4ZWN1dGVkCi8vICAgLSBleGVjdXRlZEhlaWdodDogYmxvY2sgaGVpZ2h0IHdoZW4gcHJvcG9zYWwgd2FzIGV4ZWN1dGVkCi8vICAgLSBleGVjdXRlZEJ5OiBhZGRyZXNzIHRoYXQgZXhlY3V0ZWQgdGhlIHByb3Bvc2FsCi8vCi8vIFJldHVybnM6Ci8vICAgLSBlcnJvcjogZXhlY3V0aW9uIGVycm9yIGlmIG9wZXJhdGlvbiBmYWlscwpmdW5jIChwICpQcm9wb3NhbFN0YXR1c1Jlc29sdmVyKSBleGVjdXRlKGV4ZWN1dGVkQXQgaW50NjQsIGV4ZWN1dGVkSGVpZ2h0IGludDY0LCBleGVjdXRlZEJ5IGFkZHJlc3MpIGVycm9yIHsKCXJldHVybiBwLmFjdGlvblN0YXR1c1Jlc29sdmVyLkV4ZWN1dGUoZXhlY3V0ZWRBdCwgZXhlY3V0ZWRIZWlnaHQsIGV4ZWN1dGVkQnkpCn0KCi8vIHZvdGUgcmVjb3JkcyBhIHZvdGUgb24gdGhlIHByb3Bvc2FsIGFuZCB1cGRhdGVzIHZvdGUgdGFsbGllcy4KLy8gVGhpcyBkZWxlZ2F0ZXMgdG8gdGhlIHZvdGUgc3RhdHVzIGZvciBhY3R1YWwgdm90ZSByZWNvcmRpbmcuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB2b3RlZFllczogdHJ1ZSBmb3IgInllcyIgdm90ZSwgZmFsc2UgZm9yICJubyIgdm90ZQovLyAgIC0gd2VpZ2h0OiB2b3Rpbmcgd2VpZ2h0IHRvIGFwcGx5Ci8vCi8vIFJldHVybnM6Ci8vICAgLSBlcnJvcjogdm90aW5nIGVycm9yIGlmIG9wZXJhdGlvbiBmYWlscwpmdW5jIChwICpQcm9wb3NhbFN0YXR1c1Jlc29sdmVyKSB2b3RlKHZvdGVkWWVzIGJvb2wsIHdlaWdodCBpbnQ2NCkgZXJyb3IgewoJaWYgdm90ZWRZZXMgewoJCXJldHVybiBwLnZvdGVTdGF0dXNSZXNvbHZlci5BZGRZZXNWb3RlV2VpZ2h0KHdlaWdodCkKCX0KCglyZXR1cm4gcC52b3RlU3RhdHVzUmVzb2x2ZXIuQWRkTm9Wb3RlV2VpZ2h0KHdlaWdodCkKfQoKLy8gTmV3UHJvcG9zYWxTdGF0dXMgY3JlYXRlcyBhIG5ldyBwcm9wb3NhbCBzdGF0dXMgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbmZpZ3VyYXRpb24uCi8vIFRoaXMgaW5pdGlhbGl6ZXMgYWxsIHN0YXR1cyBjb21wb25lbnRzIHdpdGggdGhlIGdvdmVybmFuY2UgY29uZmlndXJhdGlvbiBhbmQgdGltaW5nLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gY29uZmlnOiBnb3Zlcm5hbmNlIGNvbmZpZ3VyYXRpb24gdG8gdXNlCi8vICAgLSBtYXhWb3RpbmdXZWlnaHQ6IG1heGltdW0gdm90aW5nIHdlaWdodCBmb3IgdGhpcyBwcm9wb3NhbAovLyAgIC0gZXhlY3V0YWJsZTogd2hldGhlciB0aGlzIHByb3Bvc2FsIHR5cGUgY2FuIGJlIGV4ZWN1dGVkCi8vICAgLSBjcmVhdGVkQXQ6IHRpbWVzdGFtcCB3aGVuIHByb3Bvc2FsIHdhcyBjcmVhdGVkCi8vICAgLSBxdW9ydW1XZWlnaHQ6IHRvdGFsIHhHTlMgc3VwcGx5IGF0IHByb3Bvc2FsIGNyZWF0aW9uLCB1c2VkIGFzIHRoZSBxdW9ydW0gYmFzZQovLwovLyBSZXR1cm5zOgovLyAgIC0gKlByb3Bvc2FsU3RhdHVzOiBuZXcgcHJvcG9zYWwgc3RhdHVzIGluc3RhbmNlCmZ1bmMgTmV3UHJvcG9zYWxTdGF0dXMoCgljb25maWcgZ292ZXJuYW5jZS5Db25maWcsCgltYXhWb3RpbmdXZWlnaHQgaW50NjQsCglleGVjdXRhYmxlIGJvb2wsCgljcmVhdGVkQXQgaW50NjQsCglxdW9ydW1XZWlnaHQgaW50NjQsCikgKmdvdmVybmFuY2UuUHJvcG9zYWxTdGF0dXMgewoJc2NoZWR1bGUgOj0gTmV3UHJvcG9zYWxTY2hlZHVsZVN0YXR1cygKCQljb25maWcuVm90aW5nU3RhcnREZWxheSwKCQljb25maWcuVm90aW5nUGVyaW9kLAoJCWNvbmZpZy5FeGVjdXRpb25EZWxheSwKCQljb25maWcuRXhlY3V0aW9uV2luZG93LAoJCWNyZWF0ZWRBdCwKCSkKCWFjdGlvblN0YXR1cyA6PSBnb3Zlcm5hbmNlLk5ld1Byb3Bvc2FsQWN0aW9uU3RhdHVzKGV4ZWN1dGFibGUpCgoJLy8gQ2FsY3VsYXRlIHRoZSBxdW9ydW0gYW1vdW50IGZyb20gdGhlIGN1cnJlbnQgeEdOUyBzdXBwbHksIG5vdCB0aGUgc21vb3RoZWQgdm90aW5nIHdlaWdodC4KCXF1b3J1bUFtb3VudCA6PSBnbnNtYXRoLlNhZmVNdWxEaXZJbnQ2NChxdW9ydW1XZWlnaHQsIGNvbmZpZy5RdW9ydW0sIDEwMCkKCXZvdGVTdGF0dXMgOj0gZ292ZXJuYW5jZS5OZXdQcm9wb3NhbFZvdGVTdGF0dXMobWF4Vm90aW5nV2VpZ2h0LCBxdW9ydW1BbW91bnQpCgoJcmV0dXJuIGdvdmVybmFuY2UuTmV3UHJvcG9zYWxTdGF0dXNCeShzY2hlZHVsZSwgYWN0aW9uU3RhdHVzLCB2b3RlU3RhdHVzKQp9ChrrEAoYcHJvcG9zYWxfdm90ZV9zdGF0dXMuZ25vEs4QcGFja2FnZSBnb3Zlcm5hbmNlCgppbXBvcnQgKAoJZ25zbWF0aCAiZ25vLmxhbmQvcC9nbm9zd2FwL2duc21hdGgvdjEiCgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3YvZ292ZXJuYW5jZSIKKQoKdHlwZSBQcm9wb3NhbFZvdGVTdGF0dXNSZXNvbHZlciBzdHJ1Y3QgewoJKmdvdmVybmFuY2UuUHJvcG9zYWxWb3RlU3RhdHVzCn0KCi8vIE5ld1Byb3Bvc2FsVm90ZVN0YXR1c1Jlc29sdmVyIHdyYXBzIHBlcnNpc3RlZCB2b3RlIHN0YXR1cyBmb3Igdm90ZSB0YWxseQovLyBjYWxjdWxhdGlvbnMgYW5kIG11dGF0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gdm90ZVN0YXR1czogcGVyc2lzdGVkIHByb3Bvc2FsIHZvdGUgc3RhdHVzIHRvIHJlc29sdmUKLy8KLy8gUmV0dXJuczoKLy8gICAtICpQcm9wb3NhbFZvdGVTdGF0dXNSZXNvbHZlcjogcmVzb2x2ZXIgYmFja2VkIGJ5IHZvdGVTdGF0dXMKZnVuYyBOZXdQcm9wb3NhbFZvdGVTdGF0dXNSZXNvbHZlcih2b3RlU3RhdHVzICpnb3Zlcm5hbmNlLlByb3Bvc2FsVm90ZVN0YXR1cykgKlByb3Bvc2FsVm90ZVN0YXR1c1Jlc29sdmVyIHsKCXJldHVybiAmUHJvcG9zYWxWb3RlU3RhdHVzUmVzb2x2ZXJ7dm90ZVN0YXR1c30KfQoKLy8gVG90YWxWb3RlV2VpZ2h0IHJldHVybnMgdGhlIHRvdGFsIHdlaWdodCBvZiBhbGwgdm90ZXMgY2FzdCAoeWVzICsgbm8pLgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IGNvbWJpbmVkICJ5ZXMiIGFuZCAibm8iIHZvdGUgd2VpZ2h0CmZ1bmMgKHAgKlByb3Bvc2FsVm90ZVN0YXR1c1Jlc29sdmVyKSBUb3RhbFZvdGVXZWlnaHQoKSBpbnQ2NCB7CglyZXR1cm4gZ25zbWF0aC5TYWZlQWRkSW50NjQocC5ZZXNXZWlnaHQoKSwgcC5Ob1dlaWdodCgpKQp9CgovLyBJc1Bhc3NlZCBkZXRlcm1pbmVzIGlmIHRoZSBwcm9wb3NhbCBoYXMgcGFzc2VkIHRoZSB2b3RpbmcgcmVxdWlyZW1lbnRzLgovLyBBIHByb3Bvc2FsIHBhc3NlcyB3aGVuIHRvdGFsIHZvdGUgd2VpZ2h0IHJlYWNoZXMgcXVvcnVtIGFuZCAieWVzIiB2b3RlcwovLyBzdHJpY3RseSBleGNlZWQgIm5vIiB2b3Rlcy4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGJvb2w6IHRydWUgd2hlbiBxdW9ydW0gaXMgbWV0IGFuZCB5ZXMgd2VpZ2h0IGlzIGdyZWF0ZXIgdGhhbiBubyB3ZWlnaHQKZnVuYyAocCAqUHJvcG9zYWxWb3RlU3RhdHVzUmVzb2x2ZXIpIElzUGFzc2VkKCkgYm9vbCB7CglpZiBwLlRvdGFsVm90ZVdlaWdodCgpIDwgcC5RdW9ydW1BbW91bnQoKSB7CgkJcmV0dXJuIGZhbHNlCgl9CgoJcmV0dXJuIHAuWWVzV2VpZ2h0KCkgPiBwLk5vV2VpZ2h0KCkKfQoKLy8gYWRkWWVzVm90ZVdlaWdodCBhZGRzIHRoZSBzcGVjaWZpZWQgd2VpZ2h0IHRvIHRoZSAieWVzIiB2b3RlIHRhbGx5LgovLyBUaGlzIGlzIGNhbGxlZCB3aGVuIGEgdXNlciB2b3RlcyAieWVzIiBvbiB0aGUgcHJvcG9zYWwuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB5ZWE6IHZvdGUgd2VpZ2h0IHRvIGFkZCB0byAieWVzIiB2b3RlcwovLwovLyBSZXR1cm5zOgovLyAgIC0gZXJyb3I6IGFsd2F5cyBuaWwgKHJlc2VydmVkIGZvciBmdXR1cmUgdmFsaWRhdGlvbikKZnVuYyAocCAqUHJvcG9zYWxWb3RlU3RhdHVzUmVzb2x2ZXIpIEFkZFllc1ZvdGVXZWlnaHQoeWVhIGludDY0KSBlcnJvciB7CglwLlNldFllc1dlaWdodChnbnNtYXRoLlNhZmVBZGRJbnQ2NChwLlllc1dlaWdodCgpLCB5ZWEpKQoJcmV0dXJuIG5pbAp9CgovLyBhZGROb1ZvdGVXZWlnaHQgYWRkcyB0aGUgc3BlY2lmaWVkIHdlaWdodCB0byB0aGUgIm5vIiB2b3RlIHRhbGx5LgovLyBUaGlzIGlzIGNhbGxlZCB3aGVuIGEgdXNlciB2b3RlcyAibm8iIG9uIHRoZSBwcm9wb3NhbC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIG5heTogdm90ZSB3ZWlnaHQgdG8gYWRkIHRvICJubyIgdm90ZXMKLy8KLy8gUmV0dXJuczoKLy8gICAtIGVycm9yOiBhbHdheXMgbmlsIChyZXNlcnZlZCBmb3IgZnV0dXJlIHZhbGlkYXRpb24pCmZ1bmMgKHAgKlByb3Bvc2FsVm90ZVN0YXR1c1Jlc29sdmVyKSBBZGROb1ZvdGVXZWlnaHQobmF5IGludDY0KSBlcnJvciB7CglwLlNldE5vV2VpZ2h0KGduc21hdGguU2FmZUFkZEludDY0KHAuTm9XZWlnaHQoKSwgbmF5KSkKCXJldHVybiBuaWwKfQoaqAcKCnJlbmRlci5nbm8SmQdwYWNrYWdlIGdvdmVybmFuY2UKCmltcG9ydCAoCgkic3RyaW5ncyIKCgkiZ25vLmxhbmQvcC9tb3VsL21kL3YwIgoJImduby5sYW5kL3AvbW91bC9tZHRhYmxlL3YwIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3YvZ292ZXJuYW5jZSIKKQoKZnVuYyAoZyAqZ292ZXJuYW5jZVYxKSBSZW5kZXIocGF0aCBzdHJpbmcpIHN0cmluZyB7CglpZiBwYXRoICE9ICIiIHsKCQlyZXR1cm4gIjQwNFxuIgoJfQoKCWltcGxlbWVudGF0aW9uIDo9IGdvdmVybmFuY2UuR2V0SW1wbGVtZW50YXRpb25QYWNrYWdlUGF0aCgpCgoJb3V0IDo9IG1kLkgxKCJHbm9zd2FwIEdvdmVybmFuY2UiKQoJb3V0ICs9IG1kLkgyKCJHb3Zlcm5hbmNlIGNvbmZpZ3VyYXRpb24iKQoJY29uZmlndXJhdGlvblRhYmxlIDo9IG1kdGFibGUuVGFibGV7CgkJSGVhZGVyczogW11zdHJpbmd7IkZpZWxkIiwgIlZhbHVlIn0sCgkJUm93czogW11bXXN0cmluZ3sKCQkJeyJBY3RpdmUgaW1wbGVtZW50YXRpb24iLCBtZC5MaW5rKGltcGxlbWVudGF0aW9uLCBzdHJpbmdzLlRyaW1QcmVmaXgoaW1wbGVtZW50YXRpb24sICJnbm8ubGFuZCIpKX0sCgkJCXsiTGF0ZXN0IGNvbmZpZ3VyYXRpb24gdmVyc2lvbiIsIHVmbXQuU3ByaW50ZigiJWQiLCBnb3Zlcm5hbmNlLkdldExhdGVzdENvbmZpZ1ZlcnNpb24oKSl9LAoJCQl7IkN1cnJlbnQgcHJvcG9zYWwgSUQiLCB1Zm10LlNwcmludGYoIiVkIiwgZ292ZXJuYW5jZS5HZXRDdXJyZW50UHJvcG9zYWxJRCgpKX0sCgkJCXsiTWF4aW11bSBzbW9vdGhpbmcgcGVyaW9kIiwgdWZtdC5TcHJpbnRmKCIlZCIsIGdvdmVybmFuY2UuR2V0TWF4U21vb3RoaW5nUGVyaW9kKCkpfSwKCQl9LAoJfQoJb3V0ICs9IGNvbmZpZ3VyYXRpb25UYWJsZS5TdHJpbmcoKQoKCXJldHVybiBvdXQKfQoaqBQKCXV0aWxzLmdubxKaFHBhY2thZ2UgZ292ZXJuYW5jZQoKaW1wb3J0ICgKCSJzdHJjb252IgoJInN0cmluZ3MiCgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgopCgovLyBudW1iZXJLaW5kIHJlcHJlc2VudHMgdGhlIHR5cGUgb2YgbnVtYmVyIHRvIHBhcnNlLgp0eXBlIG51bWJlcktpbmQgaW50Cgpjb25zdCAoCglraW5kSW50IG51bWJlcktpbmQgPSBpb3RhCglraW5kSW50NjQKCWtpbmRVaW50NjQKKQoKLy8gcGFyc2VOdW1iZXIgcGFyc2VzIGEgc3RyaW5nIHRvIGEgbnVtYmVyIChpbnQsIGludDY0LCBvciB1aW50NjQpIHdpdGggcHJvcGVyIHZhbGlkYXRpb24uCmZ1bmMgcGFyc2VOdW1iZXIocyBzdHJpbmcsIGtpbmQgbnVtYmVyS2luZCkgYW55IHsKCWlmIGxlbihzdHJpbmdzLlRyaW1TcGFjZShzKSkgPT0gMCB7CgkJcGFuaWModWZtdC5TcHJpbnQoImludmFsaWQgbnVtYmVyIHZhbHVlOiBlbXB0eSBvciB3aGl0ZXNwYWNlIHN0cmluZyIpKQoJfQoKCXN3aXRjaCBraW5kIHsKCWNhc2Uga2luZEludDoKCQludW0sIGVyciA6PSBzdHJjb252LlBhcnNlSW50KHMsIDEwLCA2NCkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcGFuaWModWZtdC5TcHJpbnRmKCJpbnZhbGlkIGludCB2YWx1ZTogJXMiLCBzKSkKCQl9CgkJcmV0dXJuIGludChudW0pCgljYXNlIGtpbmRJbnQ2NDoKCQludW0sIGVyciA6PSBzdHJjb252LlBhcnNlSW50KHMsIDEwLCA2NCkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcGFuaWModWZtdC5TcHJpbnRmKCJpbnZhbGlkIGludDY0IHZhbHVlOiAlcyIsIHMpKQoJCX0KCQlyZXR1cm4gbnVtCgljYXNlIGtpbmRVaW50NjQ6CgkJbnVtLCBlcnIgOj0gc3RyY29udi5QYXJzZVVpbnQocywgMTAsIDY0KQoJCWlmIGVyciAhPSBuaWwgewoJCQlwYW5pYyh1Zm10LlNwcmludGYoImludmFsaWQgdWludDY0IHZhbHVlOiAlcyIsIHMpKQoJCX0KCQlyZXR1cm4gbnVtCglkZWZhdWx0OgoJCXBhbmljKHVmbXQuU3ByaW50ZigidW5zdXBwb3J0ZWQgbnVtYmVyIGtpbmQ6ICV2Iiwga2luZCkpCgl9Cn0KCi8vIHBhcnNlQm9vbCBwYXJzZXMgYSBzdHJpbmcgdG8gYSBib29sZWFuLgpmdW5jIHBhcnNlQm9vbChzIHN0cmluZykgYm9vbCB7CglpZiBsZW4oc3RyaW5ncy5UcmltU3BhY2UocykpID09IDAgewoJCXBhbmljKHVmbXQuU3ByaW50KCJpbnZhbGlkIGJvb2wgdmFsdWU6IGVtcHR5IG9yIHdoaXRlc3BhY2Ugc3RyaW5nIikpCgl9CgoJc3dpdGNoIHMgewoJY2FzZSAidHJ1ZSI6CgkJcmV0dXJuIHRydWUKCWNhc2UgImZhbHNlIjoKCQlyZXR1cm4gZmFsc2UKCWRlZmF1bHQ6CgkJcGFuaWModWZtdC5TcHJpbnRmKCJpbnZhbGlkIGJvb2wgdmFsdWU6ICVzIiwgcykpCgl9Cn0KCi8vIHBhcnNlSW50IHBhcnNlcyBhIHN0cmluZyB0byBpbnQgd2l0aCBwcm9wZXIgdmFsaWRhdGlvbiBhbmQgb3ZlcmZsb3cgY2hlY2tpbmcuCmZ1bmMgcGFyc2VJbnQocyBzdHJpbmcpIGludCB7CglpZiBsZW4oc3RyaW5ncy5UcmltU3BhY2UocykpID09IDAgewoJCXBhbmljKHVmbXQuU3ByaW50KCJpbnZhbGlkIGludCB2YWx1ZTogZW1wdHkgb3Igd2hpdGVzcGFjZSBzdHJpbmciKSkKCX0KCgludW0sIGVyciA6PSBzdHJjb252LlBhcnNlSW50KHMsIDEwLCA2NCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKHVmbXQuU3ByaW50ZigiaW52YWxpZCBpbnQgdmFsdWU6ICVzIiwgcykpCgl9CgoJY29uc3QgbWF4SW50ID0gaW50KF51aW50KDApID4+IDEpCgljb25zdCBtaW5JbnQgPSAtbWF4SW50IC0gMQoKCWlmIG51bSA+IGludDY0KG1heEludCkgfHwgbnVtIDwgaW50NjQobWluSW50KSB7CgkJcGFuaWModWZtdC5TcHJpbnRmKCJpbnQgb3ZlcmZsb3c6IHZhbHVlICVkIGV4Y2VlZHMgaW50IHJhbmdlIFslZCwgJWRdIiwgbnVtLCBtaW5JbnQsIG1heEludCkpCgl9CgoJcmV0dXJuIGludChudW0pCn0KCi8vIHBhcnNlSW50NjQgcGFyc2VzIGEgc3RyaW5nIHRvIGludDY0IHdpdGggcHJvcGVyIHZhbGlkYXRpb24uCmZ1bmMgcGFyc2VJbnQ2NChzIHN0cmluZykgaW50NjQgewoJaWYgbGVuKHN0cmluZ3MuVHJpbVNwYWNlKHMpKSA9PSAwIHsKCQlwYW5pYyh1Zm10LlNwcmludCgiaW52YWxpZCBpbnQ2NCB2YWx1ZTogZW1wdHkgb3Igd2hpdGVzcGFjZSBzdHJpbmciKSkKCX0KCgludW0sIGVyciA6PSBzdHJjb252LlBhcnNlSW50KHMsIDEwLCA2NCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKHVmbXQuU3ByaW50ZigiaW52YWxpZCBpbnQ2NCB2YWx1ZTogJXMiLCBzKSkKCX0KCglyZXR1cm4gbnVtCn0KCi8vIHBhcnNlVWludDY0IHBhcnNlcyBhIHN0cmluZyB0byB1aW50NjQgd2l0aCBwcm9wZXIgdmFsaWRhdGlvbi4KZnVuYyBwYXJzZVVpbnQ2NChzIHN0cmluZykgdWludDY0IHsKCWlmIGxlbihzdHJpbmdzLlRyaW1TcGFjZShzKSkgPT0gMCB7CgkJcGFuaWModWZtdC5TcHJpbnQoImludmFsaWQgdWludDY0IHZhbHVlOiBlbXB0eSBvciB3aGl0ZXNwYWNlIHN0cmluZyIpKQoJfQoKCW51bSwgZXJyIDo9IHN0cmNvbnYuUGFyc2VVaW50KHMsIDEwLCA2NCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKHVmbXQuU3ByaW50ZigiaW52YWxpZCB1aW50NjQgdmFsdWU6ICVzIiwgcykpCgl9CgoJcmV0dXJuIG51bQp9CiIiChMvZ25vLk1lbVBhY2thZ2VUeXBlEgsKCU1QVXNlckFsbBITCPqnsNEBEgsyMTk1NDl1Z25vdBqoAQo6ChMvdG0uUHViS2V5U2VjcDI1NmsxEiMKIQMEnNUEw+LSOqLPC53myjgfoun1lzihgX/ZUaUiNcK64RJAHGr4KUp6bkJ+z7Ifsoc2Jt1yzzsQRKOCE4fTzpUQbNNHFS3Hp7d7hywj4aD96Yib9vLcrq/rPNhYWJMpDAWanBooZzFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFsdXV4ZQ==