Transaction executed successfully

Transaction Details

Inspect execution, participants, message data, gas usage, events and raw transaction data.

Transaction hash
82D1A5ACAF020658997205F76600679B74600D6AB09AD0967F42F1686308A061

Transaction overview

Status
Success
Execution completed
Block
#77265
Included in block
Message Type
m_addpkg
Primary message

Execution summary

TX INDEX
0
Position in block
GAS WANTED
294,235,175
Requested gas limit
GAS USED
245,196,029
Gas consumed
FEE
294236ugnot
Transaction fee

Participants

Sender
Package / Realm
Not available
Memo
None

Message

Message #1
m_addpkg
Caller
Arguments
g1q5tjjv3kkslzwf2na9y9wk7e5a8ugph8xfsk04

Execution log

msg:0,success:true,log:,events:[]

Events

No events emitted by this transaction.

Raw encoded transaction

CtiFDAoML3ZtLm1fYWRkcGtnEsaFDAooZzFxNXRqanYza2tzbHp3ZjJuYTl5OXdrN2U1YTh1Z3BoOHhmc2swNBKYhQwKBHBvb2wSGmduby5sYW5kL3IvZ25vc3dhcC9wb29sL3YxGstJCglSRUFETUUubWQSvUkjIFBvb2wKCkNvbmNlbnRyYXRlZCBsaXF1aWRpdHkgQU1NIHBvb2xzIHdpdGggdGljay1iYXNlZCBwcmljaW5nLgoKIyMgT3ZlcnZpZXcKClBvb2wgY29udHJhY3RzIGltcGxlbWVudCBVbmlzd2FwIFYzLXN0eWxlIGNvbmNlbnRyYXRlZCBsaXF1aWRpdHksIGFsbG93aW5nIExQcyB0byBwcm92aWRlIGxpcXVpZGl0eSB3aXRoaW4gY3VzdG9tIHByaWNlIHJhbmdlcyBmb3IgbWF4aW11bSBjYXBpdGFsIGVmZmljaWVuY3kuCgojIyBDb25maWd1cmF0aW9uCgotICoqUG9vbCBDcmVhdGlvbiBGZWUqKjogMTAwIEdOUyAoZGVmYXVsdCkKLSAqKlByb3RvY29sIEZlZSoqOiBEaXNhYmxlZCAoMCkgb3IgYSBkZW5vbWluYXRvciBvZiA0LTEwLCByb3V0aW5nIDEvNCB0bwogIDEvMTAgb2Ygc3dhcCBmZWVzIHRvIHRoZSBwcm90b2NvbAotICoqV2l0aGRyYXdhbCBGZWUqKjogMSUgb24gZmVlLWJlYXJpbmcgY29sbGVjdGlvbiAoY29uZmlndXJhYmxlKQotICoqRmVlIFRpZXJzKio6IDAuMDElLCAwLjA1JSwgMC4zJSwgMSUKLSAqKlRpY2sgU3BhY2luZyoqOiBBdXRvLXNldCBieSBmZWUgdGllcgotICoqTWF4IExpcXVpZGl0eSBQZXIgVGljayoqOiBEZXBlbmRzIG9uIHRpY2sgc3BhY2luZzsgdXNlCiAgYEdldE1heExpcXVpZGl0eVBlclRpY2tgIHJhdGhlciB0aGFuIGAyXjEyOCAtIDFgCgojIyBDb3JlIENvbmNlcHRzCgojIyMgQ29uY2VudHJhdGVkIExpcXVpZGl0eQoKTGlxdWlkaXR5IHByb3ZpZGVycyBjb25jZW50cmF0ZSBjYXBpdGFsIHdpdGhpbiBjdXN0b20gcHJpY2UgcmFuZ2VzIGluc3RlYWQgb2YgMC3iiJ4uIFRoaXMgYWxsb3dzIExQcyB0byBhbGxvY2F0ZSBjYXBpdGFsIHdoZXJlIGl0J3MgbW9zdCBsaWtlbHkgdG8gZ2VuZXJhdGUgZmVlcyAtIG5lYXIgdGhlIGN1cnJlbnQgcHJpY2UgZm9yIHZvbGF0aWxlIHBhaXJzLCBvciB3aXRoaW4gdGlnaHQgcmFuZ2VzIGZvciBzdGFibGUgcGFpcnMuIENhcGl0YWwgZWZmaWNpZW5jeSBjYW4gaW1wcm92ZSBieSBvcmRlcnMgb2YgbWFnbml0dWRlIGRlcGVuZGluZyBvbiByYW5nZSBzZWxlY3Rpb24gYW5kIHBhaXIgdm9sYXRpbGl0eS4gRm9yIG1vcmUgZGV0YWlscywgY2hlY2sgb3V0IFtHbm9Td2FwIERvY3NdKGh0dHBzOi8vZG9jcy5nbm9zd2FwLmlvL2NvcmUtY29uY2VwdHMvYW1tL2NvbmNlbnRyYXRlZC1saXF1aWRpdHkpLgoKIyMjIFRpY2sgU3lzdGVtCgotIFByaWNlIHNwYWNlIGRpdmlkZWQgaW50byBkaXNjcmV0ZSB0aWNrcyAoMC4wMSUgYXBhcnQpCi0gRWFjaCB0aWNrIHJlcHJlc2VudHMgfjAuMDElIHByaWNlIGNoYW5nZQotIFBvc2l0aW9ucyBkZWZpbmVkIGJ5IHVwcGVyL2xvd2VyIHRpY2sgYm91bmRhcmllcwotIExpcXVpZGl0eSBhY3RpdmF0ZWQgb25seSB3aGVuIHByaWNlIGluIHJhbmdlCgojIyBLZXkgRnVuY3Rpb25zCgojIyMgYENyZWF0ZVBvb2xgCgpEZXBsb3lzIGEgbmV3IHRyYWRpbmcgcGFpci4KCi0gUmVxdWlyZXMgMTAwIEdOUyBjcmVhdGlvbiBmZWUgYnkgZGVmYXVsdAotIFZhbGlkIGZlZSB0aWVyIHJlcXVpcmVkCi0gQWNjZXB0cyBlaXRoZXIgdG9rZW4gcGF0aCBvcmRlciBhbmQgY2Fub25pY2FsaXplcyB0b2tlbjAvdG9rZW4xCi0gSWYgcGF0aHMgYXJlIHJldmVyc2VkLCB0aGUgaW5pdGlhbCBzcXVhcmUtcm9vdCBwcmljZSBpcyBpbnZlcnRlZAotIEluaXRpYWwgYHNxcnRQcmljZVg5NmAgbXVzdCBiZSBpbiBgW01JTl9TUVJUX1JBVElPLCBNQVhfU1FSVF9SQVRJTylgCi0gRG9lcyBub3QgY29tcGFyZSB0aGUgaW5pdGlhbCBwcmljZSB3aXRoIGFuIG9yYWNsZSBvciBleHRlcm5hbCBtYXJrZXQgcHJpY2UKCiMjIyBgTWludGAKCkFkZHMgbGlxdWlkaXR5IHRvIHBvc2l0aW9uIChjYWxsZWQgYnkgUG9zaXRpb24gY29udHJhY3QpLgoKLSBDYWxjdWxhdGVzIHRva2VuIGFtb3VudHMgZnJvbSBsaXF1aWRpdHkKLSBVcGRhdGVzIHRpY2sgYml0bWFwCi0gVHJhbnNmZXJzIHRva2VucyBmcm9tIG93bmVyCi0gUmV0dXJucyBhY3R1YWwgYW1vdW50cyB1c2VkCgojIyMgYEJ1cm5gCgpSZW1vdmVzIGxpcXVpZGl0eSB3aXRob3V0IGNvbGxlY3RpbmcgdG9rZW5zLgoKLSBQb29sLWxldmVsIG9wZXJhdGlvbjogYnVybiBmaXJzdCwgdGhlbiBjb2xsZWN0IG93ZWQgdG9rZW5zCi0gQ2FsY3VsYXRlcyBvd2VkIHByaW5jaXBhbAotIFVwZGF0ZXMgcG9zaXRpb24gc3RhdGUKCiMjIyBgQ29sbGVjdGAKClBheXMgdG9rZW5zIG93ZWQgYnkgYSBwb29sIHBvc2l0aW9uIHdpdGhvdXQgYSB3aXRoZHJhd2FsIGZlZS4gVGhpcyBmZWUtZnJlZQpwYXRoIGlzIG5vcm1hbGx5IHVzZWQgZm9yIHByaW5jaXBhbCBhZnRlciBgQnVybmAuCgotIFRyYW5zZmVycyB0aGUgcmVxdWVzdGVkIHBvcnRpb24gb2YgYHRva2Vuc093ZWRgCi0gVXBkYXRlcyBgdG9rZW5zT3dlZGAKCiMjIyBgQ29sbGVjdFN3YXBGZWVgCgpQYXlzIGFjY3J1ZWQgc3dhcCBmZWVzIHRocm91Z2ggdGhlIGZlZS1iZWFyaW5nIGNvbGxlY3Rpb24gcGF0aC4KCi0gQXBwbGllcyB0aGUgY29uZmlndXJlZCB3aXRoZHJhd2FsIGZlZQotIFJldHVybnMgZ3Jvc3MgY29sbGVjdGVkIGFtb3VudHMgYW5kIHRoZSBmZWUgd2l0aGhlbGQKLSBgUG9zaXRpb24uRGVjcmVhc2VMaXF1aWRpdHlgIGFuZCBgUG9zaXRpb24uQ29sbGVjdEZlZWAgaW52b2tlIHRoZSBhcHByb3ByaWF0ZQogIHBvb2wgcGF0aHMgaW50ZXJuYWxseQoKIyMjIGBTd2FwYAoKQ29yZSBzd2FwIGV4ZWN1dGlvbiAoY2FsbGVkIGJ5IFJvdXRlcikuCgotIEl0ZXJhdGVzIHRocm91Z2ggdGlja3MKLSBVcGRhdGVzIHByaWNlIGFuZCBsaXF1aWRpdHkKLSBDYWxjdWxhdGVzIGZlZXMKLSBNYWludGFpbnMgVFdBUCBvcmFjbGUKCiMjIyMgU3dhcCBDYWxsYmFjawoKVGhlIGBTd2FwYCBmdW5jdGlvbiB1c2VzIGEgY2FsbGJhY2sgcGF0dGVybiBmb3IgdG9rZW4gdHJhbnNmZXJzLCBmb2xsb3dpbmcgdGhlIFVuaXN3YXAgVjMgZmxhc2ggc3dhcCBkZXNpZ24uCgoqKkNhbGxiYWNrIFNpZ25hdHVyZSoqOgoKYGBgZ28KZnVuYyBzd2FwQ2FsbGJhY2soY3VyIHJlYWxtLCBhbW91bnQwRGVsdGEsIGFtb3VudDFEZWx0YSBpbnQ2NCwgXyAqcG9vbC5DYWxsYmFja01hcmtlcikgZXJyb3IKYGBgCgoqKkRlbHRhIENvbnZlbnRpb24qKjoKfCBEZWx0YSB8IE1lYW5pbmcgfAp8LS0tLS0tLXwtLS0tLS0tLS18CnwgUG9zaXRpdmUgKGA+IDBgKSB8IEFtb3VudCB0aGUgcG9vbCBtdXN0IFJFQ0VJVkUgKGlucHV0IHRva2VuKSB8CnwgTmVnYXRpdmUgKGA8IDBgKSB8IEFtb3VudCB0aGUgcG9vbCBoYXMgU0VOVCAob3V0cHV0IHRva2VuKSB8CgoqKlN3YXAgRGlyZWN0aW9uIEV4YW1wbGVzKio6CgpGb3IgYHplcm9Gb3JPbmUgPSB0cnVlYCAodG9rZW4wIOKGkiB0b2tlbjEpOgoKLSBgYW1vdW50MERlbHRhID4gMGA6IFBvb2wgcmVjZWl2ZXMgdG9rZW4wIChpbnB1dCkKLSBgYW1vdW50MURlbHRhIDwgMGA6IFBvb2wgc2VuZHMgdG9rZW4xIChvdXRwdXQpCgpGb3IgYHplcm9Gb3JPbmUgPSBmYWxzZWAgKHRva2VuMSDihpIgdG9rZW4wKToKCi0gYGFtb3VudDBEZWx0YSA8IDBgOiBQb29sIHNlbmRzIHRva2VuMCAob3V0cHV0KQotIGBhbW91bnQxRGVsdGEgPiAwYDogUG9vbCByZWNlaXZlcyB0b2tlbjEgKGlucHV0KQoKKipDYWxsYmFjayBJbXBsZW1lbnRhdGlvbiBFeGFtcGxlKio6CgpgYGBnbwpmdW5jIHN3YXBDYWxsYmFjayhjdXIgcmVhbG0sIGFtb3VudDBEZWx0YSwgYW1vdW50MURlbHRhIGludDY0LCBfICpwb29sLkNhbGxiYWNrTWFya2VyKSBlcnJvciB7CiAgICBjYWxsZXIgOj0gY3VyLlByZXZpb3VzKCkuQWRkcmVzcygpCiAgICBwb29sQWRkciA6PSBjaGFpbi5QYWNrYWdlQWRkcmVzcygiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiKQoKICAgIC8vIFNlY3VyaXR5IGNoZWNrOiBlbnN1cmUgdGhpcyBjYWxsYmFjayBpcyBpbnZva2VkIGJ5IHRoZSBsZWdpdGltYXRlIHBvb2wKICAgIGlmIGNhbGxlciAhPSBwb29sQWRkciB7CiAgICAgICAgcmV0dXJuIGVycm9ycy5OZXcoInVuYXV0aG9yaXplZCBjYWxsZXIiKQogICAgfQoKICAgIGlmIGFtb3VudDBEZWx0YSA+IDAgewogICAgICAgIC8vIFRyYW5zZmVyIHRva2VuMCB0byBwb29sCiAgICAgICAgY29tbW9uLlNhZmVHUkMyMFRyYW5zZmVyKDAsIGN1ciwgdG9rZW4wUGF0aCwgcG9vbEFkZHIsIGFtb3VudDBEZWx0YSkKICAgIH0KICAgIGlmIGFtb3VudDFEZWx0YSA+IDAgewogICAgICAgIC8vIFRyYW5zZmVyIHRva2VuMSB0byBwb29sCiAgICAgICAgY29tbW9uLlNhZmVHUkMyMFRyYW5zZmVyKDAsIGN1ciwgdG9rZW4xUGF0aCwgcG9vbEFkZHIsIGFtb3VudDFEZWx0YSkKICAgIH0KICAgIHJldHVybiBuaWwKfQpgYGAKCioqSW1wb3J0YW50IE5vdGVzKio6CgotIEEgY3VzdG9tIGNhbGxiYWNrIHNob3VsZCB2ZXJpZnkgdGhhdCB0aGUgY2FsbGVyIGlzIHRoZSBsZWdpdGltYXRlIHBvb2wuCi0gSW4gdGhlIHJvdXRlciBmbG93LCB0aGUgc3VwcGxpZWQgY2xvc3VyZSBwZXJmb3JtcyB0aGF0IHBvb2wtb3JpZ2luIGNoZWNrCiAgYmVmb3JlIGNhbGxpbmcgYHJvdXRlci5Td2FwQ2FsbGJhY2tgOyB0aGUgUm91dGVyIGltcGxlbWVudGF0aW9uIHRoZW4gY2hlY2tzCiAgdGhhdCBpdHMgY2FsbGVyIGlzIFJvdXRlciB2MS4KLSBUaGUgY2FsbGJhY2sgTVVTVCB0cmFuc2ZlciBhdCBsZWFzdCB0aGUgcG9zaXRpdmUgZGVsdGEgYW1vdW50IHRvIHRoZSBwb29sLgotIFJldHVybiBgbmlsYCBvbiBzdWNjZXNzLCBvciBhbiBlcnJvciB0byByZXZlcnQgdGhlIHN3YXAuCi0gUG9vbCB2YWxpZGF0ZXMgdGhlIGJhbGFuY2UgaW5jcmVhc2UgYWZ0ZXIgY2FsbGJhY2sgZXhlY3V0aW9uLgoKIyMgVGVjaG5pY2FsIERldGFpbHMKCiMjIyBQcmljZSBNYXRoCgoqKlE5NiBGb3JtYXQqKjogUHJpY2VzIHN0b3JlZCBhcyBgc3FydFByaWNlWDk2ID0gc3FydChwcmljZSkgKiAyXjk2YAoKYGBgClByaWNlIDE6MSAgIOKGkiBzcXJ0UHJpY2VYOTYgPSA3OTIyODE2MjUxNDI2NDMzNzU5MzU0Mzk1MDMzNgpQcmljZSAxOjQgICDihpIgc3FydFByaWNlWDk2ID0gMzk2MTQwODEyNTcxMzIxNjg3OTY3NzE5NzUxNjgKUHJpY2UgMTAwOjEg4oaSIHNxcnRQcmljZVg5NiA9IDc5MjI4MTYyNTE0MjY0MzM3NTkzNTQzOTUwMzM2MApgYGAKCioqVGljayB0byBQcmljZSoqOiBgcHJpY2UgPSAxLjAwMDFedGlja2AKCmBgYAp0aWNrIDAgICAgID0gcHJpY2UgMQp0aWNrIDY5MzIgID0gcHJpY2UgfjIKdGljayAtNjkzMiA9IHByaWNlIH4wLjUKYGBgCgoqKlJhbmdlIExpcXVpZGl0eSoqOgoKTGlxdWlkaXR5IGlzIGNhbGN1bGF0ZWQgZnJvbSB0aGUgdG9rZW4gcmVxdWlyZWQgYnkgdGhlIGN1cnJlbnQgcHJpY2U6CgotIEJlbG93IHRoZSByYW5nZSAoYGN1cnJlbnQgPCBsb3dlcmApOiB0b2tlbjAgb25seQotIEluIHRoZSByYW5nZSAoYGxvd2VyIDw9IGN1cnJlbnQgPCB1cHBlcmApOiBib3RoIHRva2VuMCBhbmQgdG9rZW4xCi0gQWJvdmUgdGhlIHJhbmdlIChgY3VycmVudCA+PSB1cHBlcmApOiB0b2tlbjEgb25seQoKVGhlIGludGVnZXIgZm9ybXVsYXMgdXNlIHRoZSBzcXVhcmUtcm9vdCBwcmljZXMgYW5kIHJvdW5kIGluIHRoZSBkaXJlY3Rpb24KcmVxdWlyZWQgYnkgdGhlIG1pbnQgb3IgYnVybiBvcGVyYXRpb247IHRoZXJlIGlzIG5vIHNpbmdsZSBgYW1vdW50YCBmb3JtdWxhCnRoYXQgYXBwbGllcyB0byBhbGwgdGhyZWUgY2FzZXMuCgoqKkltcGVybWFuZW50IExvc3MqKjoKCi0gTmFycm93IHJhbmdlOiBIaWdoZXIgZmVlcywgaGlnaGVyIElMCi0gV2lkZSByYW5nZTogTG93ZXIgZmVlcywgbG93ZXIgSUwKLSBTdGFibGUgcGFpcnM6IMKxMC4xJSByYW5nZXMgb3B0aW1hbAotIFZvbGF0aWxlIHBhaXJzOiDCsTEwJSsgcmFuZ2VzIHJlY29tbWVuZGVkCgojIyMgRmVlIE1lY2hhbmljcwoKKipTd2FwIEZlZXMqKjoKCi0gQ2hhcmdlZCBvbiBpbnB1dCBhbW91bnQKLSBBY2N1bXVsYXRlcyBhcyBmZWVHcm93dGhHbG9iYWwKLSBEaXN0cmlidXRlZCBwcm8tcmF0YSB0byBpbi1yYW5nZSBsaXF1aWRpdHkKCioqRmVlIENhbGN1bGF0aW9uKio6CgpgYGAKZmVlcyA9IGZlZUdyb3d0aEluc2lkZSAqIGxpcXVpZGl0eQpmZWVHcm93dGhJbnNpZGUgPSBmZWVHcm93dGhHbG9iYWwgLSBmZWVHcm93dGhPdXRzaWRlCmBgYAoKKipQcm90b2NvbCBmZWVzKio6CgotIGAwYCBkaXNhYmxlcyBwcm90b2NvbCBmZWUgY29sbGVjdGlvbgotIGA0YCB0aHJvdWdoIGAxMGAgYXJlIGRlbm9taW5hdG9yczogYDRgIHJvdXRlcyAyNSUgYW5kIGAxMGAgcm91dGVzIDEwJSBvZgogIHN3YXAgZmVlcyB0byB0aGUgcHJvdG9jb2wKLSBHb3Zlcm5hbmNlLW1hbmFnZWQgY29uZmlndXJhdGlvbiBhcHBsaWVzIHRvIHRoZSBwb29sIHNldCwgbm90IGFuIGluZGVwZW5kZW50CiAgcGVyY2VudGFnZSBzZWxlY3RlZCBvbiBlYWNoIHBvb2wKCiMjIFNlY3VyaXR5CgojIyMgUmVlbnRyYW5jeSBQcm90ZWN0aW9uCgotIFRoZSBsaXZlIGd1YXJkIGlzIHRoZSBwb29sLXdpZGUgYFVubG9ja2VkYCBrZXkgaW4gdGhlIHBvb2wgS1Ygc3RvcmUsIG1hbmFnZWQKICBieSBgcG9vbC92MS9sb2NrLmdub2AuIGBTbG90MC51bmxvY2tlZGAgaXMgYSBzZXBhcmF0ZSBzdG9yZWQgZmllbGQgYW5kIGlzIG5vdAogIHRoZSBndWFyZDsgYEdldFNsb3QwVW5sb2NrZWRgIHJlcG9ydHMgdGhhdCBmaWVsZCwgbm90IHRoZSBsaXZlIGxvY2suCi0gVGhlIGxvY2sgaXMgbm90IHN3YXAtc3BlY2lmaWMuIGBDcmVhdGVQb29sYCwgYE1pbnRgLCBgQnVybmAsIGBDb2xsZWN0YCwKICBgQ29sbGVjdFN3YXBGZWVgLCBgQ29sbGVjdFByb3RvY29sYCwgYFNldEZlZVByb3RvY29sYCwgYFNldFdpdGhkcmF3YWxGZWVgLAogIGBTZXRQb29sQ3JlYXRpb25GZWVgLCBgSW5jcmVhc2VPYnNlcnZhdGlvbkNhcmRpbmFsaXR5TmV4dGAsCiAgYFNldFN3YXBTdGFydEhvb2tgLCBgU2V0U3dhcEVuZEhvb2tgLCBgU2V0VGlja0Nyb3NzSG9va2AsIGBTd2FwYCwgYW5kIHRoZQogIHJlYWQtb25seSBgRHJ5U3dhcGAgYWxsIGFzc2VydCB0aGF0IHRoZSBwb29sIGlzIHVubG9ja2VkIGJlZm9yZSBkb2luZyBhbnkKICB3b3JrLgotIFRoZSB1bmxvY2tlZCBhc3NlcnRpb24gaXMgcmVhZC1vbmx5IGFuZCBydW5zIGJlZm9yZSB0aGUgYWNjZXNzIGNoZWNrcywgc28gYQogIGNhbGwgdGhhdCBhYm9ydHMgb24gYXV0aG9yaXphdGlvbiBsZWF2ZXMgbm8gcGVyc2lzdGVkIGxvY2sgYmVoaW5kLgotIFNldHRsZW1lbnQgb3JkZXIgaXMgb3BlcmF0aW9uLXNwZWNpZmljIHJhdGhlciB0aGFuIHVuaWZvcm1seQogIGNoZWNrcy1lZmZlY3RzLWludGVyYWN0aW9ucy4gYFN3YXBgIHNldHRsZXMgb3B0aW1pc3RpY2FsbHkgdGhyb3VnaCB0aGUKICBjYWxsYmFjayBhbmQgdmVyaWZpZXMgdGhlIHJlc3VsdGluZyBiYWxhbmNlIGluY3JlYXNlIGFmdGVyd2FyZHMsIHdoaWxlIGBNaW50YAogIHB1bGxzIHRva2VucyBiZWZvcmUgaXRzIGZpbmFsIHBvb2wgc2F2ZS4gUmV2aWV3IHRoZSBzcGVjaWZpYyBwYXRoIHJhdGhlciB0aGFuCiAgYXNzdW1pbmcgZXZlcnkgd3JpdGUgcHJlY2VkZXMgZXZlcnkgZXh0ZXJuYWwgY2FsbC4KCiMjIyBQcmljZSBNYW5pcHVsYXRpb24KCi0gVFdBUCBvcmFjbGUgcHJvdmlkZXMgdGltZS13ZWlnaHRlZCBvYnNlcnZhdGlvbnMgZm9yIG1vbml0b3Jpbmc7IGl0IGlzIG5vdCBhbgogIGF1dG9tYXRpYyBpbml0aWFsLXByaWNlIGd1YXJkCi0gTGFyZ2Ugc3dhcHMgbGltaXRlZCBieSBsaXF1aWRpdHkKLSBTbGlwcGFnZSBwcm90ZWN0aW9uIHJlcXVpcmVkCgojIyMgUG9vbCBDcmVhdGlvbiBHcmllZmluZwoKKipJc3N1ZSoqOiBgQ3JlYXRlUG9vbGAgdmFsaWRhdGVzIHRoZSBmZWUgdGllciwgdG9rZW4gY2Fub25pY2FsaXphdGlvbiwgYW5kCnNxdWFyZS1yb290IHByaWNlIGJvdW5kcywgYnV0IGRvZXMgbm90IGNvbXBhcmUgdGhlIGluaXRpYWwgcHJpY2Ugd2l0aCBhbgpvcmFjbGUgb3IgZXh0ZXJuYWwgbWFya2V0IHByaWNlLiBBIHBvb2wgY2FuIHRoZXJlZm9yZSBiZSBjcmVhdGVkIGF0IGFuCmVjb25vbWljYWxseSBpbmFwcHJvcHJpYXRlIGV4dHJlbWUgcHJpY2UuCgoqKkltcGFjdCoqOgoKLSBQb29sIG1heSBiZSB0ZW1wb3JhcmlseSB1bnVzYWJsZQotIE5vIHJhdGlvbmFsIExQIG1heSBwcm92aWRlIGxpcXVpZGl0eSBhdCBhIGRpc3RvcnRlZCBwcmljZQotIFByaWNlIGNhbm5vdCBzZWxmLWNvcnJlY3Qgd2l0aG91dCBsaXF1aWRpdHkKCioqUmVjb3ZlcnkgTWVjaGFuaXNtKio6ClJlY292ZXJ5IHJlcXVpcmVzIGNvb3JkaW5hdGVkIGxpcXVpZGl0eSBwcm92aXNpb24gYW5kIHN3YXBzIHRvIG1vdmUgdGhlIHByaWNlCnRvd2FyZCBhIGRlc2lyZWQgbWFya2V0IHJhdGUsIGZvbGxvd2VkIGJ5IGxpcXVpZGl0eSByZW1vdmFsLiBUaGUgcHJvdG9jb2wgZG9lcwpub3QgcGVyZm9ybSB0aGlzIGNvcnJlY3Rpb24gYXV0b21hdGljYWxseSwgYW5kIHByb2ZpdGFiaWxpdHkgZGVwZW5kcyBvbiBtYXJrZXQKY29uZGl0aW9ucywgZmVlcywgYW5kIHNsaXBwYWdlLgoKKipFeGFtcGxlIFJlY292ZXJ5IFNlcXVlbmNlKio6CgpUaGlzIHBzZXVkb2NvZGUgYXNzdW1lcyB0aGUgaW50ZWdyYXRpbmcgcmVhbG0gZnVuY3Rpb24gaGFzIGEgY3VycmVudCBgY3VyYCB0b2tlbi4KCmBgYAovLyBJbGx1c3RyYXRpdmUgc2VxdWVuY2U7IHRoZSBjYWxsZXIgbXVzdCBjb21wb3NlIGFuZCBleGVjdXRlIHRoZXNlIG9wZXJhdGlvbnMKMS4gcG9zaXRpb24uTWludChjcm9zcyhjdXIpLCAuLi4sIGZ1bGxSYW5nZSwgbGFyZ2VBbW91bnQsIC4uLikgIC8vIEFkZCBsaXF1aWRpdHkKMi4gcm91dGVyLkV4YWN0SW5Td2FwUm91dGUoY3Jvc3MoY3VyKSwgLi4uLCB0YXJnZXRSb3V0ZSwgLi4uKSAgICAvLyBGaXggcHJpY2UgdmlhIGFyYml0cmFnZQozLiBwb3NpdGlvbi5EZWNyZWFzZUxpcXVpZGl0eShjcm9zcyhjdXIpLCBwb3NpdGlvbklkLCAuLi4pICAgICAgIC8vIFJlbW92ZSBsaXF1aWRpdHkgYW5kIGNvbGxlY3QgcHJpbmNpcGFsCjQuIHBvc2l0aW9uLkNvbGxlY3RGZWUoY3Jvc3MoY3VyKSwgcG9zaXRpb25JZCkgICAgICAgICAgICAgICAgICAgLy8gQ29sbGVjdCBhbnkgcmVtYWluaW5nIGZlZXMKYGBgCgoqKlByZXZlbnRpb24qKjoKCi0gMTAwIEdOUyBjcmVhdGlvbiBmZWUgcHJvdmlkZXMgZGV0ZXJyZW50Ci0gQ29uc2lkZXIgaW1wbGVtZW50aW5nIHByaWNlIG9yYWNsZSB2YWxpZGF0aW9uIGZvciBoaWdoLXZhbHVlIHBhaXJzCi0gTW9uaXRvciBwb29sIGNyZWF0aW9uIGV2ZW50cyBmb3Igc3VzcGljaW91cyBhY3Rpdml0eQoKIyMjIFJvdW5kaW5nCgotIEludGVnZXIgbWF0aCByb3VuZHMgZGlyZWN0aW9uYWxseSBmb3IgdGhlIGlucHV0L291dHB1dCBpbnZhcmlhbnQ7IG5vdCBldmVyeQogIGRpdmlzaW9uIHJvdW5kcyBkb3duCi0gTWluaW11bSBsaXF1aWRpdHkgZW5mb3JjZWQKLSBGdWxsIHByZWNpc2lvbiBmb3IgYW1vdW50cwoajw0KCmFzc2VydC5nbm8SgA1wYWNrYWdlIHBvb2wKCmltcG9ydCAoCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCglwbCAiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiCikKCmZ1bmMgYXNzZXJ0SXNOb3RVc2VyQ2FsbChfIGludCwgcmxtIHJlYWxtKSB7CglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCglpZiBwcmV2aW91c1JlYWxtLklzVXNlckNhbGwoKSB7CgkJcGFuaWMobmV3RXJyb3JXaXRoRGV0YWlsKAoJCQllcnJOb3RBY2Nlc3NFT0EsCgkJCXVmbXQuU3ByaW50ZigicHJldmlvdXNSZWFsbSglcykgaXMgRU9BIiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkpLAoJCSkpCgl9Cn0KCi8vIGFzc2VydElzTm90RXF1YWxzVG9rZW5zIGFzc2VydHMgdGhhdCB0aGUgdG9rZW4wUGF0aCBhbmQgdG9rZW4xUGF0aCBhcmUgbm90IGVxdWFsLgpmdW5jIGFzc2VydElzTm90RXF1YWxzVG9rZW5zKHRva2VuMFBhdGgsIHRva2VuMVBhdGggc3RyaW5nKSB7CglpZiB0b2tlbjBQYXRoID09IHRva2VuMVBhdGggewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbCgKCQkJZXJyRHVwbGljYXRlVG9rZW5JblBvb2wsCgkJCXVmbXQuU3ByaW50ZigiZXhwZWN0ZWQgdG9rZW4wUGF0aCglcykgIT0gdG9rZW4xUGF0aCglcykiLCB0b2tlbjBQYXRoLCB0b2tlbjFQYXRoKSwKCQkpKQoJfQp9CgovLyBhc3NlcnRJc1N1cHBvcnRlZEZlZVRpZXIgYXNzZXJ0cyB0aGF0IHRoZSBmZWUgaXMgYSBzdXBwb3J0ZWQgZmVlIHRpZXIuCmZ1bmMgYXNzZXJ0SXNTdXBwb3J0ZWRGZWVUaWVyKGZlZSB1aW50MzIpIHsKCWlmICFpc1ZhbGlkRmVlVGllcihmZWUpIHsKCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoCgkJCWVyclVuc3VwcG9ydGVkRmVlVGllciwKCQkJdWZtdC5TcHJpbnRmKCJleHBlY3RlZCBmZWUoJWQpIHRvIGJlIG9uZSBvZiAlZCwgJWQsICVkLCAlZCIsIGZlZSwgRmVlVGllcjEwMCwgRmVlVGllcjUwMCwgRmVlVGllcjMwMDAsIEZlZVRpZXIxMDAwMCksCgkJKSkKCX0KfQoKLy8gYXNzZXJ0SXNOb3RFeGlzdHNQb29sUGF0aCBhc3NlcnRzIHRoYXQgdGhlIHBvb2wgcGF0aCBkb2VzIG5vdCBleGlzdC4KZnVuYyBhc3NlcnRJc05vdEV4aXN0c1Bvb2xQYXRoKGluc3RhbmNlICpwb29sVjEsIHRva2VuMFBhdGgsIHRva2VuMVBhdGggc3RyaW5nLCBmZWUgdWludDMyKSB7Cglwb29sUGF0aCA6PSBwbC5HZXRQb29sUGF0aCh0b2tlbjBQYXRoLCB0b2tlbjFQYXRoLCBmZWUpCgoJcG9vbHMgOj0gaW5zdGFuY2Uuc3RvcmUuR2V0UG9vbHMoKQoJaWYgcG9vbHMuSGFzKHBvb2xQYXRoKSB7CgkJcGFuaWMobmV3RXJyb3JXaXRoRGV0YWlsKAoJCQllcnJQb29sQWxyZWFkeUV4aXN0cywKCQkJdWZtdC5TcHJpbnRmKCJleHBlY3RlZCBwb29sUGF0aCglczolczolZCkgbm90IHRvIGV4aXN0IiwgdG9rZW4wUGF0aCwgdG9rZW4xUGF0aCwgZmVlKSwKCQkpKQoJfQp9CgpmdW5jIGFzc2VydElzVmFsaWRUb2tlbk9yZGVyKHRva2VuMFBhdGgsIHRva2VuMVBhdGggc3RyaW5nKSB7CglpZiB0b2tlbjBQYXRoID49IHRva2VuMVBhdGggewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbCgKCQkJZXJySW52YWxpZElucHV0LAoJCQl1Zm10LlNwcmludGYoImV4cGVjdGVkIHRva2VuMFBhdGgoJXMpIDwgdG9rZW4xUGF0aCglcykiLCB0b2tlbjBQYXRoLCB0b2tlbjFQYXRoKSwKCQkpKQoJfQp9ChqPBAoHZG9jLmdubxKDBC8vIHBhY2thZ2UgdjEgaW1wbGVtZW50cyBHbm9Td2FwJ3MgY29uY2VudHJhdGVkIGxpcXVpZGl0eSBwb29scyBiYXNlZCBvbiBVbmlzd2FwIFYzLgovLyBJdCBtYW5hZ2VzIGxpcXVpZGl0eSBwb3NpdGlvbnMsIGV4ZWN1dGVzIHN3YXBzLCBhbmQgbWFpbnRhaW5zIHBvb2wgc3RhdGUgaW5jbHVkaW5nCi8vIHByaWNlLCBsaXF1aWRpdHksIGFuZCBmZWUgY2FsY3VsYXRpb25zLgovLwovLyBUaGUgcG9vbCBjb250cmFjdCBpcyB0aGUgY29yZSBvZiB0aGUgR25vU3dhcCBBTU0sIHN1cHBvcnRpbmc6Ci8vIC0gQ29uY2VudHJhdGVkIGxpcXVpZGl0eSB3aXRoaW4gY3VzdG9tIHByaWNlIHJhbmdlcwovLyAtIE11bHRpcGxlIGZlZSB0aWVycyAoMC4wMSUsIDAuMDUlLCAwLjMlLCAxJSkKLy8gLSBTaW5nbGUtdGljayBhbmQgY3Jvc3MtdGljayBzd2FwcwovLyAtIFByb3RvY29sIGZlZSBjb2xsZWN0aW9uCi8vIC0gVGljayBiaXRtYXAgb3B0aW1pemF0aW9uIGZvciBnYXMgZWZmaWNpZW5jeQpwYWNrYWdlIHBvb2wKGtkUCgplcnJvcnMuZ25vEsoUcGFja2FnZSBwb29sCgppbXBvcnQgKAoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgopCgovLyBFcnJvciBkZWZpbml0aW9ucyBmb3IgcG9vbCBvcGVyYXRpb25zCmNvbnN0ICgKCWVyclVuc3VwcG9ydGVkRmVlVGllciAgICAgICAgPSAiW0dOT1NXQVAtUE9PTC0wMDFdIHVuc3VwcG9ydGVkIGZlZSB0aWVyIgoJZXJyUG9vbEFscmVhZHlFeGlzdHMgICAgICAgICA9ICJbR05PU1dBUC1QT09MLTAwMl0gcG9vbCBhbHJlYWR5IGNyZWF0ZWQiCgllcnJPdXRPZlJhbmdlICAgICAgICAgICAgICAgID0gIltHTk9TV0FQLVBPT0wtMDAzXSBvdXQgb2YgcmFuZ2UgZm9yIG51bWVyaWMgdmFsdWUiCgllcnJJbnZhbGlkSW5wdXQgICAgICAgICAgICAgID0gIltHTk9TV0FQLVBPT0wtMDA0XSBpbnZhbGlkIGlucHV0IGRhdGEiCgllcnJEYXRhTm90Rm91bmQgICAgICAgICAgICAgID0gIltHTk9TV0FQLVBPT0wtMDA1XSByZXF1ZXN0ZWQgZGF0YSBub3QgZm91bmQiCgllcnJMaXF1aWRpdHlDYWxjdWxhdGlvbiAgICAgID0gIltHTk9TV0FQLVBPT0wtMDA2XSBpbnZhbGlkIGxpcXVpZGl0eSBjYWxjdWxhdGVkIgoJZXJyWmVyb0xpcXVpZGl0eSAgICAgICAgICAgICA9ICJbR05PU1dBUC1QT09MLTAwN10gemVybyBsaXF1aWRpdHkiCgllcnJEdXBsaWNhdGVUb2tlbkluUG9vbCAgICAgID0gIltHTk9TV0FQLVBPT0wtMDA4XSBzYW1lIHRva2VuIHVzZWQgaW4gc2luZ2xlIHBvb2wiCgllcnJUaWNrTG93ZXJJbnZhbGlkICAgICAgICAgID0gIltHTk9TV0FQLVBPT0wtMDA5XSB0aWNrTG93ZXIgaXMgaW52YWxpZCIKCWVyclRpY2tVcHBlckludmFsaWQgICAgICAgICAgPSAiW0dOT1NXQVAtUE9PTC0wMTBdIHRpY2tVcHBlciBpcyBpbnZhbGlkIgoJZXJySW52YWxpZFN3YXBBbW91bnQgICAgICAgICA9ICJbR05PU1dBUC1QT09MLTAxMV0gaW52YWxpZCBzd2FwIGFtb3VudCIKCWVyckludmFsaWRQcm90b2NvbEZlZVBjdCAgICAgPSAiW0dOT1NXQVAtUE9PTC0wMTJdIGludmFsaWQgcHJvdG9jb2wgZmVlIHBlcmNlbnRhZ2UiCgllcnJJbnZhbGlkV2l0aGRyYXdhbEZlZVBjdCAgID0gIltHTk9TV0FQLVBPT0wtMDEzXSBpbnZhbGlkIHdpdGhkcmF3YWwgZmVlIHBlcmNlbnRhZ2UiCgllcnJMb2NrZWRQb29sICAgICAgICAgICAgICAgID0gIltHTk9TV0FQLVBPT0wtMDE0XSBjYW5ub3QgbW9kaWZ5IHBvb2wgd2hpbGUgbG9ja2VkIgoJZXJyUHJpY2VPdXRPZlJhbmdlICAgICAgICAgICA9ICJbR05PU1dBUC1QT09MLTAxNV0gc3dhcCBwcmljZSBvdXQgb2YgcmFuZ2UiCgllcnJUcmFuc2ZlckZhaWxlZCAgICAgICAgICAgID0gIltHTk9TV0FQLVBPT0wtMDE2XSB0b2tlbiB0cmFuc2ZlciBmYWlsZWQiCgllcnJJbnZhbGlkVGlja0FuZFRpY2tTcGFjaW5nID0gIltHTk9TV0FQLVBPT0wtMDE3XSBpbnZhbGlkIHRpY2sgYW5kIHRpY2sgc3BhY2luZyByZXF1ZXN0ZWQiCgllcnJJbnZhbGlkVGlja1JhbmdlICAgICAgICAgID0gIltHTk9TV0FQLVBPT0wtMDE4XSB0aWNrTG93ZXIgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRpY2tVcHBlciIKCWVyclVuZGVyZmxvdyAgICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtUE9PTC0wMTldIHVuZGVyZmxvdyIKCWVyck92ZXJmbG93ICAgICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtUE9PTC0wMjBdIG92ZXJmbG93IgoJZXJyQmFsYW5jZVVwZGF0ZUZhaWxlZCAgICAgICA9ICJbR05PU1dBUC1QT09MLTAyMV0gYmFsYW5jZSB1cGRhdGUgZmFpbGVkIgoJZXJyTm90QWNjZXNzRU9BICAgICAgICAgICAgICA9ICJbR05PU1dBUC1QT09MLTAyMl0gbm90IGFjY2VzcyBFT0EiCgllcnJJbnN1ZmZpY2llbnRQYXltZW50ICAgICAgID0gIltHTk9TV0FQLVBPT0wtMDIzXSBpbnN1ZmZpY2llbnQgcGF5bWVudCIKCWVyck5vdEluaXRpYWxpemVkT2JzZXJ2YXRpb24gPSAiW0dOT1NXQVAtUE9PTC0wMjRdIG5vdCBpbml0aWFsaXplZCBvYnNlcnZhdGlvbiIKCWVyck9ic2VydmF0aW9uVG9vT2xkICAgICAgICAgPSAiW0dOT1NXQVAtUE9PTC0wMjVdIHRhcmdldCB0aW1lc3RhbXAgYmVmb3JlIG9sZGVzdCBvYnNlcnZhdGlvbiIKCWVyck9ic2VydmF0aW9uQmVmb3JlRXBvY2ggICAgPSAiW0dOT1NXQVAtUE9PTC0wMjZdIGxvb2tiYWNrIHdpbmRvdyBzdGFydHMgYmVmb3JlIHVuaXggZXBvY2giCgllcnJJbnN1ZmZpY2llbnRQb29sQmFsYW5jZSAgID0gIltHTk9TV0FQLVBPT0wtMDI3XSBpbnN1ZmZpY2llbnQgcG9vbCBiYWxhbmNlIGZvciBzd2FwIgopCgovLyBuZXdFcnJvcldpdGhEZXRhaWwgYWRkcyBkZXRhaWwgdG8gYW4gZXJyb3IgbWVzc2FnZS4KZnVuYyBuZXdFcnJvcldpdGhEZXRhaWwobWVzc2FnZSBzdHJpbmcsIGRldGFpbCBzdHJpbmcpIHN0cmluZyB7CglmaW5hbEVyciA6PSB1Zm10LkVycm9yZigiJXMgfHwgJXMiLCBtZXNzYWdlLCBkZXRhaWwpCglyZXR1cm4gZmluYWxFcnIuRXJyb3IoKQp9CgovLyBtYWtlRXJyb3JXaXRoRGV0YWlscyBjcmVhdGVzIGFuIGVycm9yIHdpdGggYWRkaXRpb25hbCBjb250ZXh0LgpmdW5jIG1ha2VFcnJvcldpdGhEZXRhaWxzKG1lc3NhZ2Ugc3RyaW5nLCBkZXRhaWxzIHN0cmluZykgZXJyb3IgewoJcmV0dXJuIHVmbXQuRXJyb3JmKCIlcyB8fCAlcyIsIG1lc3NhZ2UsIGRldGFpbHMpCn0KGqoMCg5ldmVudF9pbmZvLmdubxKXDHBhY2thZ2UgcG9vbAoKaW1wb3J0ICgKCSJnbm8ubGFuZC9wL2dub3N3YXAvdXRpbHMvdjEiCgoJcGwgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgopCgp0eXBlIHRpY2tFdmVudEluZm8gc3RydWN0IHsKCXRpY2tJRCAgIGludDMyCgl0aWNrSW5mbyBwbC5UaWNrSW5mbwp9CgovLyBUb1N0cmluZyBzZXJpYWxpemVzIHRpY2sgZXZlbnQgaW5mb3JtYXRpb24gYXMgYSBjb21wYWN0IEpTT04gb2JqZWN0LgovLyBUaGUgb2JqZWN0IGluY2x1ZGVzIHRoZSB0aWNrIGluZGV4IGFuZCBldmVyeSBwZXJzaXN0ZWQgVGlja0luZm8gZmllbGQgdXNpbmcKLy8gdGhlIHNob3J0IGV2ZW50IGtleXMgZG9jdW1lbnRlZCBiZWxvdy4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHN0cmluZzogSlNPTiBvYmplY3QgY29udGFpbmluZyB0aWNrLCBsaXF1aWRpdHksIGZlZS1ncm93dGgsIGN1bXVsYXRpdmUtdGltZSwgYW5kIGluaXRpYWxpemF0aW9uIGZpZWxkcy4KZnVuYyAodCAqdGlja0V2ZW50SW5mbykgVG9TdHJpbmcoKSBzdHJpbmcgewoJcmV0dXJuICJ7XCJ0XCI6IiArIHV0aWxzLkZvcm1hdEludCh0LnRpY2tJRCkgKwoJCSIsXCJsZ1wiOlwiIiArIHQudGlja0luZm8uTGlxdWlkaXR5R3Jvc3MoKSArICJcIiIgKwoJCSIsXCJsblwiOlwiIiArIHQudGlja0luZm8uTGlxdWlkaXR5TmV0KCkgKyAiXCIiICsKCQkiLFwiZmcwXCI6XCIiICsgdC50aWNrSW5mby5GZWVHcm93dGhPdXRzaWRlMFgxMjgoKSArICJcIiIgKwoJCSIsXCJmZzFcIjpcIiIgKyB0LnRpY2tJbmZvLkZlZUdyb3d0aE91dHNpZGUxWDEyOCgpICsgIlwiIiArCgkJIixcInRjb1wiOlwiIiArIHV0aWxzLkZvcm1hdEludCh0LnRpY2tJbmZvLlRpY2tDdW11bGF0aXZlT3V0c2lkZSgpKSArICJcIiIgKwoJCSIsXCJzcGxcIjpcIiIgKyB0LnRpY2tJbmZvLlNlY29uZHNQZXJMaXF1aWRpdHlPdXRzaWRlWDEyOCgpICsgIlwiIiArCgkJIixcInNvXCI6XCIiICsgdXRpbHMuRm9ybWF0VWludCh0LnRpY2tJbmZvLlNlY29uZHNPdXRzaWRlKCkpICsgIlwiIiArCgkJIixcImlcIjpcIiIgKyB1dGlscy5Gb3JtYXRCb29sKHQudGlja0luZm8uSW5pdGlhbGl6ZWQoKSkgKyAiXCJ9Igp9CgovLyBOZXdUaWNrRXZlbnRJbmZvIGNyZWF0ZXMgZXZlbnQgZGF0YSBmb3Igb25lIHRpY2sgYW5kIGl0cyBwZXJzaXN0ZWQgc3RhdGUuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0aWNrSUQ6IHRpY2sgaW5kZXggcmVwcmVzZW50ZWQgYnkgdGhlIGV2ZW50LgovLyAgIC0gdGlja0luZm86IHRpY2sgc3RhdGUgd2hvc2UgZmllbGRzIGFyZSBzZXJpYWxpemVkIGJ5IFRvU3RyaW5nLgovLwovLyBSZXR1cm5zOgovLyAgIC0gKnRpY2tFdmVudEluZm86IGV2ZW50IGluZm9ybWF0aW9uIHZhbHVlIHJldGFpbmluZyB0aGUgc3VwcGxpZWQgdGljayBpbmRleCBhbmQgc3RhdGUuCmZ1bmMgTmV3VGlja0V2ZW50SW5mbyh0aWNrSUQgaW50MzIsIHRpY2tJbmZvIHBsLlRpY2tJbmZvKSAqdGlja0V2ZW50SW5mbyB7CglyZXR1cm4gJnRpY2tFdmVudEluZm97CgkJdGlja0lEOiAgIHRpY2tJRCwKCQl0aWNrSW5mbzogdGlja0luZm8sCgl9Cn0KGuAbChFmYWN0b3J5X3BhcmFtLmdubxLKG3BhY2thZ2UgcG9vbAoKaW1wb3J0ICgKCSJzdHJpbmdzIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvY29uc3RzL3YxIgoJdTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL3VpbnQyNTYvdjEiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgkiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiCikKCmNvbnN0ICgKCUZlZVRpZXIxMDAgICB1aW50MzIgPSAxMDAKCUZlZVRpZXI1MDAgICB1aW50MzIgPSA1MDAKCUZlZVRpZXIzMDAwICB1aW50MzIgPSAzMDAwCglGZWVUaWVyMTAwMDAgdWludDMyID0gMTAwMDAKKQoKY29uc3QgKAoJTUlOX1NRUlRfUkFUSU8gc3RyaW5nID0gIjQyOTUxMjg3MzkiCglNQVhfU1FSVF9SQVRJTyBzdHJpbmcgPSAiMTQ2MTQ0NjcwMzQ4NTIxMDEwMzI4NzI3MzA1MjIwMzk4ODgyMjM3ODcyMzk3MDM0MiIKKQoKLy8gcG9vbENyZWF0ZUNvbmZpZyBob2xkcyB0aGUgZXNzZW50aWFsIHBhcmFtZXRlcnMgZm9yIGNyZWF0aW5nIGEgbmV3IHBvb2wuCnR5cGUgcG9vbENyZWF0ZUNvbmZpZyBzdHJ1Y3QgewoJdG9rZW4wUGF0aCAgICAgICBzdHJpbmcKCXRva2VuMVBhdGggICAgICAgc3RyaW5nCglmZWUgICAgICAgICAgICAgIHVpbnQzMgoJc3FydFByaWNlWDk2ICAgICAqdTI1Ni5VaW50Cgl0aWNrU3BhY2luZyAgICAgIGludDMyCglzbG90MEZlZVByb3RvY29sIHVpbnQ4Cn0KCi8vIG5ld1Bvb2xQYXJhbXMgZGVmaW5lcyB0aGUgZXNzZW50aWFsIHBhcmFtZXRlcnMgZm9yIGNyZWF0aW5nIGEgbmV3IHBvb2wuCmZ1bmMgbmV3UG9vbFBhcmFtcygKCXRva2VuMFBhdGggc3RyaW5nLAoJdG9rZW4xUGF0aCBzdHJpbmcsCglmZWUgdWludDMyLAoJc3FydFByaWNlWDk2IHN0cmluZywKCXRpY2tTcGFjaW5nIGludDMyLAoJc2xvdDBGZWVQcm90b2NvbCB1aW50OCwKKSAqcG9vbENyZWF0ZUNvbmZpZyB7CglwcmljZSA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChzcXJ0UHJpY2VYOTYpCglyZXR1cm4gJnBvb2xDcmVhdGVDb25maWd7CgkJdG9rZW4wUGF0aDogICAgICAgdG9rZW4wUGF0aCwKCQl0b2tlbjFQYXRoOiAgICAgICB0b2tlbjFQYXRoLAoJCWZlZTogICAgICAgICAgICAgIGZlZSwKCQlzcXJ0UHJpY2VYOTY6ICAgICBwcmljZSwKCQl0aWNrU3BhY2luZzogICAgICB0aWNrU3BhY2luZywKCQlzbG90MEZlZVByb3RvY29sOiBzbG90MEZlZVByb3RvY29sLAoJfQp9CgovLyBSZXR1cm5zOgovLyAgIC0gc3FydFByaWNlWDk2OiBjb25maWd1cmVkIGluaXRpYWwgc3F1YXJlLXJvb3QgcHJpY2UgYXMgYSBtdXRhYmxlIHUyNTYKLy8gICAgIGludGVnZXIgaW4gUTY0Ljk2IHJlcHJlc2VudGF0aW9uLgpmdW5jIChwICpwb29sQ3JlYXRlQ29uZmlnKSBTcXJ0UHJpY2VYOTYoKSAqdTI1Ni5VaW50IHsgcmV0dXJuIHAuc3FydFByaWNlWDk2IH0KCi8vIFJldHVybnM6Ci8vICAgLSB0aWNrU3BhY2luZzogY29uZmlndXJlZCBzcGFjaW5nIGJldHdlZW4gdXNhYmxlIGluaXRpYWxpemVkIHRpY2tzLgpmdW5jIChwICpwb29sQ3JlYXRlQ29uZmlnKSBUaWNrU3BhY2luZygpIGludDMyIHsgcmV0dXJuIHAudGlja1NwYWNpbmcgfQoKLy8gUmV0dXJuczoKLy8gICAtIHRva2VuMFBhdGg6IGNvbmZpZ3VyZWQgdG9rZW4wIGNvbnRyYWN0IHBhdGguCmZ1bmMgKHAgKnBvb2xDcmVhdGVDb25maWcpIFRva2VuMFBhdGgoKSBzdHJpbmcgeyByZXR1cm4gcC50b2tlbjBQYXRoIH0KCi8vIFJldHVybnM6Ci8vICAgLSB0b2tlbjFQYXRoOiBjb25maWd1cmVkIHRva2VuMSBjb250cmFjdCBwYXRoLgpmdW5jIChwICpwb29sQ3JlYXRlQ29uZmlnKSBUb2tlbjFQYXRoKCkgc3RyaW5nIHsgcmV0dXJuIHAudG9rZW4xUGF0aCB9CgovLyBSZXR1cm5zOgovLyAgIC0gZmVlOiBjb25maWd1cmVkIHBvb2wgZmVlIHRpZXIgYXMgYSB1aW50MzIgZmVlLXVuaXQgdmFsdWUuCmZ1bmMgKHAgKnBvb2xDcmVhdGVDb25maWcpIEZlZSgpIHVpbnQzMiB7IHJldHVybiBwLmZlZSB9CgpmdW5jIChwICpwb29sQ3JlYXRlQ29uZmlnKSB1cGRhdGUoKSBlcnJvciB7Cgl0b2tlbjBQYXRoIDo9IHAudG9rZW4wUGF0aAoJdG9rZW4xUGF0aCA6PSBwLnRva2VuMVBhdGgKCgkvLyBBbHdheXMgdmFsaWRhdGUgdGhhdCB0aGUgcHJpY2UgaXMgd2l0aGluIHZhbGlkIHJhbmdlCglpZiBlcnIgOj0gdmFsaWRhdGVTcXJ0UHJpY2VYOTYocC5zcXJ0UHJpY2VYOTYpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJaWYgIXAuaXNJbk9yZGVyKCkgewoJCXRva2VuMFBhdGgsIHRva2VuMVBhdGggPSB0b2tlbjFQYXRoLCB0b2tlbjBQYXRoCgoJCS8vIG5ld1ByaWNlID0gMl4xOTIgLyBvbGRQcmljZQoJCW5ld1ByaWNlIDo9IHUyNTYuWmVybygpLkRpdihjb25zdHMuUTE5MigpLCBwLnNxcnRQcmljZVg5NikKCgkJLy8gQ2hlY2sgaWYgY2FsY3VsYXRlZCBwcmljZSBpcyB3aXRoaW4gdmFsaWQgcmFuZ2UKCQlpZiBlcnIgOj0gdmFsaWRhdGVTcXJ0UHJpY2VYOTYobmV3UHJpY2UpOyBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCgkJcC5zcXJ0UHJpY2VYOTYgPSBuZXdQcmljZQoJfQoKCXAudG9rZW4wUGF0aCA9IHRva2VuMFBhdGgKCXAudG9rZW4xUGF0aCA9IHRva2VuMVBhdGgKCglyZXR1cm4gbmlsCn0KCi8vIGlzSW5PcmRlciBjaGVja3MgaWYgdG9rZW4gcGF0aHMgYXJlIGluIGxleGljb2dyYXBoaWNhbCAob3IsIGFscGhhYmV0aWNhbCkgb3JkZXIKZnVuYyAocCAqcG9vbENyZWF0ZUNvbmZpZykgaXNJbk9yZGVyKCkgYm9vbCB7CglpZiBzdHJpbmdzLkNvbXBhcmUocC50b2tlbjBQYXRoLCBwLnRva2VuMVBhdGgpIDwgMCB7CgkJcmV0dXJuIHRydWUKCX0KCXJldHVybiBmYWxzZQp9CgpmdW5jIChwICpwb29sQ3JlYXRlQ29uZmlnKSBwb29sUGF0aCgpIHN0cmluZyB7CglyZXR1cm4gcG9vbC5HZXRQb29sUGF0aChwLnRva2VuMFBhdGgsIHAudG9rZW4xUGF0aCwgcC5mZWUpCn0KCi8vIHZhbGlkYXRlU3FydFByaWNlWDk2IHZhbGlkYXRlcyB0aGF0IHRoZSBnaXZlbiBzcXJ0UHJpY2VYOTYgaXMgd2l0aGluIHZhbGlkIHJhbmdlCmZ1bmMgdmFsaWRhdGVTcXJ0UHJpY2VYOTYoc3FydFByaWNlWDk2ICp1MjU2LlVpbnQpIGVycm9yIHsKCS8vIFZhbGlkIHJhbmdlIGlzIFttaW5TcXJ0UmF0aW8sIG1heFNxcnRSYXRpbykgLSBzYW1lIGFzIFRpY2tNYXRoR2V0VGlja0F0U3FydFJhdGlvCglpZiBzcXJ0UHJpY2VYOTYuTHQoY29uc3RzLk1pblNxcnRSYXRpbygpKSB8fCBzcXJ0UHJpY2VYOTYuR3RlKGNvbnN0cy5NYXhTcXJ0UmF0aW8oKSkgewoJCXJldHVybiBtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJyT3V0T2ZSYW5nZSwKCQkJdWZtdC5TcHJpbnRmKCJzcXJ0UHJpY2VYOTYoJXMpIGlzIG91dCBvZiByYW5nZSIsIHNxcnRQcmljZVg5Ni5Ub1N0cmluZygpKSwKCQkpCgl9CglyZXR1cm4gbmlsCn0KCmZ1bmMgaXNWYWxpZEZlZVRpZXIoZmVlVGllciB1aW50MzIpIGJvb2wgewoJc3dpdGNoIGZlZVRpZXIgewoJY2FzZSBGZWVUaWVyMTAwLCBGZWVUaWVyNTAwLCBGZWVUaWVyMzAwMCwgRmVlVGllcjEwMDAwOgoJCXJldHVybiB0cnVlCgl9CgoJcmV0dXJuIGZhbHNlCn0KGoLhAQoKZ2V0dGVyLmdubxLy4AFwYWNrYWdlIHBvb2wKCmltcG9ydCAoCgkiZXJyb3JzIgoJInRpbWUiCgoJdTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL3VpbnQyNTYvdjEiCglyb3RyZWUgImduby5sYW5kL3AvbnQvYnB0cmVlL3JvdHJlZS92MCIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCXBsICJnbm8ubGFuZC9yL2dub3N3YXAvcG9vbCIKKQoKLy8gR2V0UG9vbFBhdGggZ2VuZXJhdGVzIGEgdW5pcXVlIHBvb2wgcGF0aCBzdHJpbmcgYmFzZWQgb24gdGhlIHRva2VuIHBhdGhzIGFuZCBmZWUgdGllci4KLy8gUGFyYW1ldGVyczoKLy8gICAtIHRva2VuMFBhdGg6IGZpcnN0IHRva2VuIGNvbnRyYWN0IHBhdGg7IHBvb2wgcGF0aHMgY2Fub25pY2FsaXplIHRva2VuIG9yZGVyLgovLyAgIC0gdG9rZW4xUGF0aDogc2Vjb25kIHRva2VuIGNvbnRyYWN0IHBhdGg7IHBvb2wgcGF0aHMgY2Fub25pY2FsaXplIHRva2VuIG9yZGVyLgovLyAgIC0gZmVlOiBmZWUgdGllciBlbmNvZGVkIGluIHRoZSBwb29sIGlkZW50aWZpZXIuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHRva2VuMDp0b2tlbjE6ZmVlIHBvb2wgaWRlbnRpZmllci4KZnVuYyBHZXRQb29sUGF0aCh0b2tlbjBQYXRoLCB0b2tlbjFQYXRoIHN0cmluZywgZmVlIHVpbnQzMikgc3RyaW5nIHsKCXJldHVybiBwbC5HZXRQb29sUGF0aCh0b2tlbjBQYXRoLCB0b2tlbjFQYXRoLCBmZWUpCn0KCi8vIEdldEZlZUFtb3VudFRpY2tTcGFjaW5nIHJldHJpZXZlcyB0aGUgdGljayBzcGFjaW5nIGFzc29jaWF0ZWQgd2l0aCBhIGdpdmVuIGZlZSBhbW91bnQuCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBmZWU6IGZlZSB0aWVyIHdob3NlIGNvbmZpZ3VyZWQgdGljayBzcGFjaW5nIGlzIHJlcXVlc3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHNwYWNpbmc6IGNvbmZpZ3VyZWQgc2lnbmVkIHRpY2sgaW50ZXJ2YWwgZm9yIGZlZS4KLy8gICAtIGVycjogbmlsIHdoZW4gZmVlIGlzIGNvbmZpZ3VyZWQ7IGFuIHVuc3VwcG9ydGVkLWZlZSBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0RmVlQW1vdW50VGlja1NwYWNpbmcoZmVlIHVpbnQzMikgKHNwYWNpbmcgaW50MzIsIGVyciBlcnJvcikgewoJZmVlQW1vdW50VGlja1NwYWNpbmcgOj0gaS5zdG9yZS5HZXRGZWVBbW91bnRUaWNrU3BhY2luZygpCgoJc3BhY2luZywgZXhpc3QgOj0gZmVlQW1vdW50VGlja1NwYWNpbmdbZmVlXQoJaWYgIWV4aXN0IHsKCQlyZXR1cm4gMCwgZXJyb3JzLk5ldyhuZXdFcnJvcldpdGhEZXRhaWwoCgkJCWVyclVuc3VwcG9ydGVkRmVlVGllciwKCQkJdWZtdC5TcHJpbnRmKCJleHBlY3RlZCBmZWUoJWQpIHRvIGJlIG9uZSBvZiAlZCwgJWQsICVkLCAlZCIsIGZlZSwgRmVlVGllcjEwMCwgRmVlVGllcjUwMCwgRmVlVGllcjMwMDAsIEZlZVRpZXIxMDAwMCksCgkJKSkKCX0KCglyZXR1cm4gc3BhY2luZywgbmlsCn0KCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciB0byBsb29rIHVwLgovLwovLyBSZXR1cm5zOgovLyAgIC0gdG9rZW4wUGF0aDogY2Fub25pY2FsIHRva2VuMCBjb250cmFjdCBwYXRoIHN0b3JlZCBpbiB0aGUgcG9vbC4KLy8gICAtIGVycjogbmlsIHdoZW4gdGhlIHBvb2wgZXhpc3RzOyB0aGUgcG9vbCBsb29rdXAgZXJyb3Igb3RoZXJ3aXNlLgpmdW5jIChpICpwb29sVjEpIEdldFRva2VuMFBhdGgocG9vbFBhdGggc3RyaW5nKSAoc3RyaW5nLCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgZXJyCgl9CglyZXR1cm4gcG9vbC5Ub2tlbjBQYXRoKCksIG5pbAp9CgovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IGNhbm9uaWNhbCBwb29sIGlkZW50aWZpZXIgdG8gbG9vayB1cC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHRva2VuMVBhdGg6IGNhbm9uaWNhbCB0b2tlbjEgY29udHJhY3QgcGF0aCBzdG9yZWQgaW4gdGhlIHBvb2wuCi8vICAgLSBlcnI6IG5pbCB3aGVuIHRoZSBwb29sIGV4aXN0czsgdGhlIHBvb2wgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRUb2tlbjFQYXRoKHBvb2xQYXRoIHN0cmluZykgKHN0cmluZywgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoJcmV0dXJuIHBvb2wuVG9rZW4xUGF0aCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIHRvIGxvb2sgdXAuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBmZWU6IGNvbmZpZ3VyZWQgZmVlIHRpZXIgc3RvcmVkIGluIHRoZSBwb29sLgovLyAgIC0gZXJyOiBuaWwgd2hlbiB0aGUgcG9vbCBleGlzdHM7IHRoZSBwb29sIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0RmVlKHBvb2xQYXRoIHN0cmluZykgKHVpbnQzMiwgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CglyZXR1cm4gcG9vbC5GZWUoKSwgbmlsCn0KCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciB0byBsb29rIHVwLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYmFsYW5jZVRva2VuMDogcG9vbC1oZWxkIHRva2VuMCBiYWxhbmNlIGluIHRoZSB0b2tlbidzIHNtYWxsZXN0IHVuaXQuCi8vICAgLSBlcnI6IG5pbCB3aGVuIHRoZSBwb29sIGV4aXN0czsgdGhlIHBvb2wgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRCYWxhbmNlVG9rZW4wKHBvb2xQYXRoIHN0cmluZykgKGludDY0LCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCXJldHVybiBwb29sLkJhbGFuY2VUb2tlbjAoKSwgbmlsCn0KCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciB0byBsb29rIHVwLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYmFsYW5jZVRva2VuMTogcG9vbC1oZWxkIHRva2VuMSBiYWxhbmNlIGluIHRoZSB0b2tlbidzIHNtYWxsZXN0IHVuaXQuCi8vICAgLSBlcnI6IG5pbCB3aGVuIHRoZSBwb29sIGV4aXN0czsgdGhlIHBvb2wgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRCYWxhbmNlVG9rZW4xKHBvb2xQYXRoIHN0cmluZykgKGludDY0LCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCXJldHVybiBwb29sLkJhbGFuY2VUb2tlbjEoKSwgbmlsCn0KCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciB0byBsb29rIHVwLgovLwovLyBSZXR1cm5zOgovLyAgIC0gdGlja1NwYWNpbmc6IGNvbmZpZ3VyZWQgc2lnbmVkIGludGVydmFsIGJldHdlZW4gdXNhYmxlIGluaXRpYWxpemVkIHRpY2tzLgovLyAgIC0gZXJyOiBuaWwgd2hlbiB0aGUgcG9vbCBleGlzdHM7IHRoZSBwb29sIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0VGlja1NwYWNpbmcocG9vbFBhdGggc3RyaW5nKSAoaW50MzIsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoJcmV0dXJuIHBvb2wuVGlja1NwYWNpbmcoKSwgbmlsCn0KCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciB0byBsb29rIHVwLgovLwovLyBSZXR1cm5zOgovLyAgIC0gbWF4TGlxdWlkaXR5OiBkZWNpbWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtYXhpbXVtIGxpcXVpZGl0eSBwZXJtaXR0ZWQKLy8gICAgIGF0IG9uZSB0aWNrIGZvciB0aGUgcG9vbCdzIHRpY2sgc3BhY2luZy4KLy8gICAtIGVycjogbmlsIHdoZW4gdGhlIHBvb2wgZXhpc3RzOyB0aGUgcG9vbCBsb29rdXAgZXJyb3Igb3RoZXJ3aXNlLgpmdW5jIChpICpwb29sVjEpIEdldE1heExpcXVpZGl0eVBlclRpY2socG9vbFBhdGggc3RyaW5nKSAoc3RyaW5nLCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgZXJyCgl9CglyZXR1cm4gY2FsY3VsYXRlTWF4TGlxdWlkaXR5UGVyVGljayhwb29sLlRpY2tTcGFjaW5nKCkpLlRvU3RyaW5nKCksIG5pbAp9CgovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IGNhbm9uaWNhbCBwb29sIGlkZW50aWZpZXIgdG8gbG9vayB1cC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGZlZVByb3RvY29sOiBwYWNrZWQgdG9rZW4wL3Rva2VuMSBwcm90b2NvbC1mZWUgZGVub21pbmF0b3IgY29uZmlndXJhdGlvbgovLyAgICAgc3RvcmVkIGluIHNsb3QwLgovLyAgIC0gZXJyOiBuaWwgd2hlbiB0aGUgcG9vbCBleGlzdHM7IHRoZSBwb29sIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0U2xvdDBGZWVQcm90b2NvbChwb29sUGF0aCBzdHJpbmcpICh1aW50OCwgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CglyZXR1cm4gcG9vbC5TbG90MEZlZVByb3RvY29sKCksIG5pbAp9CgovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IGNhbm9uaWNhbCBwb29sIGlkZW50aWZpZXIgdG8gbG9vayB1cC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHVubG9ja2VkOiB0cnVlIHdoZW4gdGhlIHBvb2wncyBzbG90MCByZWVudHJhbmN5IGxvY2sgaXMgb3Blbi4KLy8gICAtIGVycjogbmlsIHdoZW4gdGhlIHBvb2wgZXhpc3RzOyB0aGUgcG9vbCBsb29rdXAgZXJyb3Igb3RoZXJ3aXNlLgpmdW5jIChpICpwb29sVjEpIEdldFNsb3QwVW5sb2NrZWQocG9vbFBhdGggc3RyaW5nKSAoYm9vbCwgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZmFsc2UsIGVycgoJfQoJcmV0dXJuIHBvb2wuU2xvdDBVbmxvY2tlZCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIHRvIGxvb2sgdXAuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBzbG90MDogY3VycmVudCBwb29sIHByaWNlLCB0aWNrLCBvYnNlcnZhdGlvbiwgYW5kIGxvY2sgbWV0YWRhdGE7IHBhbmljcwovLyAgICAgd2hlbiBwb29sUGF0aCBkb2VzIG5vdCBpZGVudGlmeSBhbiBleGlzdGluZyBwb29sLgpmdW5jIChpICpwb29sVjEpIEdldFNsb3QwKHBvb2xQYXRoIHN0cmluZykgcGwuU2xvdDAgewoJcmV0dXJuIGkubXVzdEdldFBvb2wocG9vbFBhdGgpLlNsb3QwKCkKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIG9ic2VydmF0aW9uIHJpbmcuCi8vICAgLSBpbmRleDogb2JzZXJ2YXRpb24gc2xvdCBpbmRleDsgaW4tcmFuZ2UgdW53cml0dGVuIHNsb3RzIHJldHVybiBhIGRlZmF1bHQKLy8gICAgIG9ic2VydmF0aW9uLCB3aGlsZSBpbmRpY2VzIGF0IG9yIGFib3ZlIG1heE9ic2VydmF0aW9uQ2FyZGluYWxpdHkgZXJyb3IuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBvYnNlcnZhdGlvbjogb2JzZXJ2YXRpb24gc3RvcmVkIGF0IGluZGV4LCBvciB0aGUgZGVmYXVsdCB6ZXJvIG9ic2VydmF0aW9uCi8vICAgICBmb3IgYW4gaW4tcmFuZ2Ugc2xvdCB0aGF0IGhhcyBuZXZlciBiZWVuIHdyaXR0ZW4uCi8vICAgLSBlcnI6IG5pbCBmb3IgYSB2YWxpZCBwb29sIGFuZCBpbmRleDsgYSBwb29sLCBvYnNlcnZhdGlvbiwgb3IgcmFuZ2UgZXJyb3IKLy8gICAgIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRPYnNlcnZhdGlvbkF0KHBvb2xQYXRoIHN0cmluZywgaW5kZXggdWludDE2KSAocGwuT2JzZXJ2YXRpb24sIGVycm9yKSB7CglpZiBfLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIHBsLkRlZmF1bHRPYnNlcnZhdGlvbigpLCBlcnIKCX0KCgkvLyBVbmlzd2FwJ3Mgb2JzZXJ2YXRpb25zKHVpbnQyNTYpIGdldHRlciBpcyBiYWNrZWQgYnkgYSBmaXhlZC1zaXplIGFycmF5OgoJLy8gYW4gaW4tcmFuZ2UgYnV0IG5ldmVyLXdyaXR0ZW4gc2xvdCByZXR1cm5zIHRoZSB6ZXJvIG9ic2VydmF0aW9uLCB3aGlsZSBhbgoJLy8gb3V0LW9mLXJhbmdlIGluZGV4IHJldmVydHMuCglpZiBpbmRleCA+PSBtYXhPYnNlcnZhdGlvbkNhcmRpbmFsaXR5IHsKCQlyZXR1cm4gcGwuRGVmYXVsdE9ic2VydmF0aW9uKCksIG1ha2VFcnJvcldpdGhEZXRhaWxzKGVyckRhdGFOb3RGb3VuZCwgdWZtdC5TcHJpbnRmKCJvYnNlcnZhdGlvbiBpbmRleCAlZCBvdXQgb2YgcmFuZ2UiLCBpbmRleCkpCgl9CgoJb2JzZXJ2YXRpb25zLCBlcnIgOj0gaS5nZXRPYnNlcnZhdGlvbnMocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gcGwuRGVmYXVsdE9ic2VydmF0aW9uKCksIGVycgoJfQoKCW9ic2VydmF0aW9uLCBvayA6PSBvYnNlcnZhdGlvbnMuR2V0KGluZGV4KQoJaWYgIW9rIHsKCQlyZXR1cm4gcGwuRGVmYXVsdE9ic2VydmF0aW9uKCksIG5pbAoJfQoKCXJldHVybiBvYnNlcnZhdGlvbiwgbmlsCn0KCi8vIE9ic2VydmUgcmV0dXJucyB0aGUgdGljayBhbmQgc2Vjb25kcy1wZXItbGlxdWlkaXR5IGN1bXVsYXRpdmVzIGZvciBlYWNoCi8vIHJlcXVlc3RlZCBsb29rYmFjay4gSXQgcmVhZHMgdGhlIGN1cnJlbnQgYmxvY2sgdGltZXN0YW1wIG9uY2UgYW5kIG5ldmVyCi8vIHdyaXRlcyBhbiBvYnNlcnZhdGlvbiwgbWF0Y2hpbmcgVW5pc3dhcCBWMydzIHZpZXctb25seSBvYnNlcnZlIGNhbGwuCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciB3aG9zZSBvYnNlcnZhdGlvbiBoaXN0b3J5IGlzIHF1ZXJpZWQuCi8vICAgLSBzZWNvbmRzQWdvczogbG9va2JhY2sgZHVyYXRpb25zIGluIHNlY29uZHM7IG9uZSBjdW11bGF0aXZlIHBhaXIgaXMKLy8gICAgIHByb2R1Y2VkIGZvciBlYWNoIGVudHJ5LCB3aXRoIHplcm8gbWVhbmluZyB0aGUgY3VycmVudCBjdW11bGF0aXZlIHZhbHVlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gdGlja0N1bXVsYXRpdmVzOiBjdW11bGF0aXZlIHRpY2sgdmFsdWVzIGFsaWduZWQgYnkgaW5kZXggd2l0aCBzZWNvbmRzQWdvcy4KLy8gICAtIHNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOHM6IGN1bXVsYXRpdmUgc2Vjb25kcy1wZXItbGlxdWlkaXR5Ci8vICAgICB2YWx1ZXMgYWxpZ25lZCB3aXRoIHNlY29uZHNBZ29zIGFuZCBzY2FsZWQgYnkgMl4xMjggYXMgZGVjaW1hbCBzdHJpbmdzLgovLyAgIC0gZXJyOiBuaWwgd2hlbiBldmVyeSByZXF1ZXN0ZWQgbG9va2JhY2sgY2FuIGJlIHJlc29sdmVkOyBhbiBvYnNlcnZhdGlvbgovLyAgICAgaGlzdG9yeSwgZXBvY2gsIGNhcmRpbmFsaXR5LCBvciBpbnRlcnBvbGF0aW9uIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBPYnNlcnZlKHBvb2xQYXRoIHN0cmluZywgc2Vjb25kc0Fnb3MgW111aW50MzIpIChbXWludDY0LCBbXXN0cmluZywgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBuaWwsIGVycgoJfQoKCW9ic2VydmF0aW9ucywgZXJyIDo9IGkuZ2V0T2JzZXJ2YXRpb25zKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIG5pbCwgbmlsLCBlcnIKCX0KCglzbG90MCA6PSBwb29sLlNsb3QwKCkKCXJldHVybiBvYnNlcnZlKAoJCW9ic2VydmF0aW9ucywKCQl0aW1lLk5vdygpLlVuaXgoKSwKCQlzZWNvbmRzQWdvcywKCQlzbG90MC5UaWNrKCksCgkJc2xvdDAuT2JzZXJ2YXRpb25JbmRleCgpLAoJCXBvb2wuTGlxdWlkaXR5KCksCgkJc2xvdDAuT2JzZXJ2YXRpb25DYXJkaW5hbGl0eSgpLAoJKQp9CgovLyBTbmFwc2hvdEN1bXVsYXRpdmVzSW5zaWRlIHJldHVybnMgdGhlIG9yYWNsZSBhY2N1bXVsYXRvcnMgdGhhdCBhY2NydWVkIHdoaWxlCi8vIHRoZSBwb29sIHByaWNlIHdhcyBpbnNpZGUgW3RpY2tMb3dlciwgdGlja1VwcGVyKS4KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIHdob3NlIG9yYWNsZSBhY2N1bXVsYXRvcnMgYXJlIHF1ZXJpZWQuCi8vICAgLSB0aWNrTG93ZXI6IGluY2x1c2l2ZSBsb3dlciB0aWNrIGJvdW5kYXJ5IG9mIHRoZSByYW5nZS4KLy8gICAtIHRpY2tVcHBlcjogZXhjbHVzaXZlIHVwcGVyIHRpY2sgYm91bmRhcnkgb2YgdGhlIHJhbmdlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gdGlja0N1bXVsYXRpdmVJbnNpZGU6IGN1bXVsYXRpdmUgdGljayB2YWx1ZSBhY2NydWVkIHdoaWxlIHByaWNlIHdhcwovLyAgICAgaW5zaWRlIFt0aWNrTG93ZXIsIHRpY2tVcHBlcikuCi8vICAgLSBzZWNvbmRzUGVyTGlxdWlkaXR5SW5zaWRlWDEyODogc2Vjb25kcy1wZXItbGlxdWlkaXR5IGFjY3VtdWxhdG9yIGFjY3J1ZWQKLy8gICAgIGluc2lkZSB0aGUgcmFuZ2UsIHNjYWxlZCBieSAyXjEyOC4KLy8gICAtIHNlY29uZHNJbnNpZGU6IG51bWJlciBvZiBzZWNvbmRzIGR1cmluZyB3aGljaCBwcmljZSB3YXMgaW5zaWRlIHRoZSByYW5nZS4KLy8gICAtIGVycjogbmlsIHdoZW4gYm91bmRzLCBib3VuZGFyeSB0aWNrcywgYW5kIG9ic2VydmF0aW9ucyBhcmUgdmFsaWQ7IHRoZQovLyAgICAgY29ycmVzcG9uZGluZyB2YWxpZGF0aW9uIG9yIG9ic2VydmF0aW9uIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBTbmFwc2hvdEN1bXVsYXRpdmVzSW5zaWRlKAoJcG9vbFBhdGggc3RyaW5nLAoJdGlja0xvd2VyIGludDMyLAoJdGlja1VwcGVyIGludDMyLAopIChpbnQ2NCwgKnUyNTYuVWludCwgdWludDMyLCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBuaWwsIDAsIGVycgoJfQoKCW9ic2VydmF0aW9ucywgZXJyIDo9IGkuZ2V0T2JzZXJ2YXRpb25zKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIG5pbCwgMCwgZXJyCgl9CgoJcmV0dXJuIHNuYXBzaG90Q3VtdWxhdGl2ZXNJbnNpZGUocG9vbCwgb2JzZXJ2YXRpb25zLCB0aWNrTG93ZXIsIHRpY2tVcHBlcikKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIHRvIGxvb2sgdXAuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBmZWVHcm93dGhHbG9iYWwwWDEyODogZ2xvYmFsIHRva2VuMCBmZWUtZ3Jvd3RoIGFjY3VtdWxhdG9yIHNjYWxlZCBieSAyXjEyOC4KLy8gICAtIGVycjogbmlsIHdoZW4gdGhlIHBvb2wgZXhpc3RzOyB0aGUgcG9vbCBsb29rdXAgZXJyb3Igb3RoZXJ3aXNlLgpmdW5jIChpICpwb29sVjEpIEdldEZlZUdyb3d0aEdsb2JhbDBYMTI4KHBvb2xQYXRoIHN0cmluZykgKCp1MjU2LlVpbnQsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIG5pbCwgZXJyCgl9CglyZXR1cm4gcG9vbC5GZWVHcm93dGhHbG9iYWwwWDEyOCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIHRvIGxvb2sgdXAuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBmZWVHcm93dGhHbG9iYWwxWDEyODogZ2xvYmFsIHRva2VuMSBmZWUtZ3Jvd3RoIGFjY3VtdWxhdG9yIHNjYWxlZCBieSAyXjEyOC4KLy8gICAtIGVycjogbmlsIHdoZW4gdGhlIHBvb2wgZXhpc3RzOyB0aGUgcG9vbCBsb29rdXAgZXJyb3Igb3RoZXJ3aXNlLgpmdW5jIChpICpwb29sVjEpIEdldEZlZUdyb3d0aEdsb2JhbDFYMTI4KHBvb2xQYXRoIHN0cmluZykgKCp1MjU2LlVpbnQsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIG5pbCwgZXJyCgl9CglyZXR1cm4gcG9vbC5GZWVHcm93dGhHbG9iYWwxWDEyOCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIHRvIGxvb2sgdXAuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBwcm90b2NvbEZlZXNUb2tlbjA6IHByb3RvY29sIGZlZXMgYWNjcnVlZCBpbiB0b2tlbjAncyBzbWFsbGVzdCB1bml0LgovLyAgIC0gZXJyOiBuaWwgd2hlbiB0aGUgcG9vbCBleGlzdHM7IHRoZSBwb29sIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0UHJvdG9jb2xGZWVzVG9rZW4wKHBvb2xQYXRoIHN0cmluZykgKGludDY0LCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCXJldHVybiBwb29sLlByb3RvY29sRmVlc1Rva2VuMCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIHRvIGxvb2sgdXAuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBwcm90b2NvbEZlZXNUb2tlbjE6IHByb3RvY29sIGZlZXMgYWNjcnVlZCBpbiB0b2tlbjEncyBzbWFsbGVzdCB1bml0LgovLyAgIC0gZXJyOiBuaWwgd2hlbiB0aGUgcG9vbCBleGlzdHM7IHRoZSBwb29sIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0UHJvdG9jb2xGZWVzVG9rZW4xKHBvb2xQYXRoIHN0cmluZykgKGludDY0LCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCXJldHVybiBwb29sLlByb3RvY29sRmVlc1Rva2VuMSgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIHRvIGxvb2sgdXAuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBsaXF1aWRpdHk6IGN1cnJlbnQgYWN0aXZlIHBvb2wgbGlxdWlkaXR5IGFzIGEgdTI1NiBpbnRlZ2VyLgovLyAgIC0gZXJyOiBuaWwgd2hlbiB0aGUgcG9vbCBleGlzdHM7IHRoZSBwb29sIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0TGlxdWlkaXR5KHBvb2xQYXRoIHN0cmluZykgKCp1MjU2LlVpbnQsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIG5pbCwgZXJyCgl9CglyZXR1cm4gcG9vbC5MaXF1aWRpdHkoKSwgbmlsCn0KCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciBjb250YWluaW5nIHRoZSBwb3NpdGlvbi4KLy8gICAtIGtleTogcG9zaXRpb24ga2V5IGlkZW50aWZ5aW5nIGl0cyBsb3dlciBhbmQgdXBwZXIgdGljayByYW5nZS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHBvc2l0aW9uOiBwb2ludGVyIHRvIGEgY29weSBvZiB0aGUgc3RvcmVkIHBvc2l0aW9uIGluZm9ybWF0aW9uOyBwYW5pY3MKLy8gICAgIHdoZW4gdGhlIHBvb2wgb3IgcG9zaXRpb24gaXMgYWJzZW50IG9yIGhhcyBhbiB1bmV4cGVjdGVkIHR5cGUuCmZ1bmMgKGkgKnBvb2xWMSkgTXVzdEdldFBvc2l0aW9uKHBvb2xQYXRoLCBrZXkgc3RyaW5nKSAqcGwuUG9zaXRpb25JbmZvIHsKCXBvb2wgOj0gaS5tdXN0R2V0UG9vbChwb29sUGF0aCkKCglwb3NpdGlvbnMgOj0gcG9vbC5Qb3NpdGlvbnMoKQoKCXJlc3VsdCA6PSBwb3NpdGlvbnMuR2V0KGtleSkKCWlmIHJlc3VsdCA9PSBuaWwgewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbCgKCQkJZXJyRGF0YU5vdEZvdW5kLAoJCQl1Zm10LlNwcmludGYoImV4cGVjdGVkIHBvc2l0aW9uKCVzKSB0byBleGlzdCIsIGtleSksCgkJKSkKCX0KCglwb3NpdGlvbiwgb2sgOj0gcmVzdWx0LihwbC5Qb3NpdGlvbkluZm8pCglpZiAhb2sgewoJCXBhbmljKCJmYWlsZWQgdG8gY2FzdCBwb3NpdGlvbiB0byBQb3NpdGlvbkluZm8iKQoJfQoKCXJldHVybiAmcG9zaXRpb24KfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHBvc2l0aW9uLgovLyAgIC0ga2V5OiBwb3NpdGlvbiBrZXkgaWRlbnRpZnlpbmcgaXRzIGxvd2VyIGFuZCB1cHBlciB0aWNrIHJhbmdlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gZmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4OiB0b2tlbjAgZmVlLWdyb3d0aC1pbnNpZGUgdmFsdWUgbGFzdCBhY2NvdW50ZWQKLy8gICAgIGZvciB0aGUgcG9zaXRpb24sIGVuY29kZWQgYXMgYSBkZWNpbWFsIGludGVnZXIgc2NhbGVkIGJ5IDJeMTI4LgovLyAgIC0gZXJyOiBuaWwgd2hlbiBwb29sIGFuZCBwb3NpdGlvbiBleGlzdDsgdGhlIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0UG9zaXRpb25GZWVHcm93dGhJbnNpZGUwTGFzdFgxMjgocG9vbFBhdGgsIGtleSBzdHJpbmcpIChzdHJpbmcsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuICIiLCBlcnIKCX0KCXBvc2l0aW9uLCBlcnIgOj0gcG9vbC5HZXRQb3NpdGlvbihrZXkpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoJcmV0dXJuIHBvc2l0aW9uLkZlZUdyb3d0aEluc2lkZTBMYXN0WDEyOCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHBvc2l0aW9uLgovLyAgIC0ga2V5OiBwb3NpdGlvbiBrZXkgaWRlbnRpZnlpbmcgaXRzIGxvd2VyIGFuZCB1cHBlciB0aWNrIHJhbmdlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gZmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4OiB0b2tlbjEgZmVlLWdyb3d0aC1pbnNpZGUgdmFsdWUgbGFzdCBhY2NvdW50ZWQKLy8gICAgIGZvciB0aGUgcG9zaXRpb24sIGVuY29kZWQgYXMgYSBkZWNpbWFsIGludGVnZXIgc2NhbGVkIGJ5IDJeMTI4LgovLyAgIC0gZXJyOiBuaWwgd2hlbiBwb29sIGFuZCBwb3NpdGlvbiBleGlzdDsgdGhlIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0UG9zaXRpb25GZWVHcm93dGhJbnNpZGUxTGFzdFgxMjgocG9vbFBhdGgsIGtleSBzdHJpbmcpIChzdHJpbmcsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuICIiLCBlcnIKCX0KCXBvc2l0aW9uLCBlcnIgOj0gcG9vbC5HZXRQb3NpdGlvbihrZXkpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoJcmV0dXJuIHBvc2l0aW9uLkZlZUdyb3d0aEluc2lkZTFMYXN0WDEyOCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHBvc2l0aW9uLgovLyAgIC0ga2V5OiBwb3NpdGlvbiBrZXkgaWRlbnRpZnlpbmcgaXRzIGxvd2VyIGFuZCB1cHBlciB0aWNrIHJhbmdlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gdG9rZW5zT3dlZDA6IHRva2VuMCBmZWVzIG93ZWQgdG8gdGhlIHBvc2l0aW9uIGluIHRva2VuMCdzIHNtYWxsZXN0IHVuaXQuCi8vICAgLSBlcnI6IG5pbCB3aGVuIHBvb2wgYW5kIHBvc2l0aW9uIGV4aXN0OyB0aGUgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRQb3NpdGlvblRva2Vuc093ZWQwKHBvb2xQYXRoLCBrZXkgc3RyaW5nKSAoaW50NjQsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoJcG9zaXRpb24sIGVyciA6PSBwb29sLkdldFBvc2l0aW9uKGtleSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCXJldHVybiBwb3NpdGlvbi5Ub2tlbnNPd2VkMCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHBvc2l0aW9uLgovLyAgIC0ga2V5OiBwb3NpdGlvbiBrZXkgaWRlbnRpZnlpbmcgaXRzIGxvd2VyIGFuZCB1cHBlciB0aWNrIHJhbmdlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gdG9rZW5zT3dlZDE6IHRva2VuMSBmZWVzIG93ZWQgdG8gdGhlIHBvc2l0aW9uIGluIHRva2VuMSdzIHNtYWxsZXN0IHVuaXQuCi8vICAgLSBlcnI6IG5pbCB3aGVuIHBvb2wgYW5kIHBvc2l0aW9uIGV4aXN0OyB0aGUgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRQb3NpdGlvblRva2Vuc093ZWQxKHBvb2xQYXRoLCBrZXkgc3RyaW5nKSAoaW50NjQsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoJcG9zaXRpb24sIGVyciA6PSBwb29sLkdldFBvc2l0aW9uKGtleSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCXJldHVybiBwb3NpdGlvbi5Ub2tlbnNPd2VkMSgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHRpY2suCi8vICAgLSB0aWNrOiBzaWduZWQgdGljayBpbmRleCB3aG9zZSBncm9zcyBsaXF1aWRpdHkgaXMgcmVxdWVzdGVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gbGlxdWlkaXR5R3Jvc3M6IHRvdGFsIGxpcXVpZGl0eSByZWZlcmVuY2luZyB0aGUgdGljaywgZW5jb2RlZCBhcyBhIGRlY2ltYWwKLy8gICAgIGludGVnZXIgc3RyaW5nLgovLyAgIC0gZXJyOiBuaWwgd2hlbiBwb29sIGFuZCB0aWNrIGV4aXN0OyB0aGUgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRUaWNrTGlxdWlkaXR5R3Jvc3MocG9vbFBhdGggc3RyaW5nLCB0aWNrIGludDMyKSAoc3RyaW5nLCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgZXJyCgl9CgoJdGlja0luZm8sIGVyciA6PSBwb29sLkdldFRpY2sodGljaykKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgZXJyCgl9CglyZXR1cm4gdGlja0luZm8uTGlxdWlkaXR5R3Jvc3MoKSwgbmlsCn0KCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciBjb250YWluaW5nIHRoZSB0aWNrLgovLyAgIC0gdGljazogc2lnbmVkIHRpY2sgaW5kZXggd2hvc2UgbmV0IGxpcXVpZGl0eSBjaGFuZ2UgaXMgcmVxdWVzdGVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gbGlxdWlkaXR5TmV0OiBzaWduZWQgbmV0IGxpcXVpZGl0eSBjaGFuZ2UgYXBwbGllZCB3aGVuIGNyb3NzaW5nIHRoZSB0aWNrLAovLyAgICAgZW5jb2RlZCBhcyBhIGRlY2ltYWwgaW50ZWdlciBzdHJpbmcuCi8vICAgLSBlcnI6IG5pbCB3aGVuIHBvb2wgYW5kIHRpY2sgZXhpc3Q7IHRoZSBsb29rdXAgZXJyb3Igb3RoZXJ3aXNlLgpmdW5jIChpICpwb29sVjEpIEdldFRpY2tMaXF1aWRpdHlOZXQocG9vbFBhdGggc3RyaW5nLCB0aWNrIGludDMyKSAoc3RyaW5nLCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgZXJyCgl9CgoJdGlja0luZm8sIGVyciA6PSBwb29sLkdldFRpY2sodGljaykKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgZXJyCgl9CglyZXR1cm4gdGlja0luZm8uTGlxdWlkaXR5TmV0KCksIG5pbAp9CgovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IGNhbm9uaWNhbCBwb29sIGlkZW50aWZpZXIgY29udGFpbmluZyB0aGUgdGljay4KLy8gICAtIHRpY2s6IHNpZ25lZCB0aWNrIGluZGV4IHdob3NlIHRva2VuMCBmZWUtZ3Jvd3RoLW91dHNpZGUgdmFsdWUgaXMgcmVxdWVzdGVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gZmVlR3Jvd3RoT3V0c2lkZTBYMTI4OiB0b2tlbjAgZmVlLWdyb3d0aC1vdXRzaWRlIGFjY3VtdWxhdG9yIHNjYWxlZCBieQovLyAgICAgMl4xMjgsIGVuY29kZWQgYXMgYSBkZWNpbWFsIHN0cmluZy4KLy8gICAtIGVycjogbmlsIHdoZW4gcG9vbCBhbmQgdGljayBleGlzdDsgdGhlIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0VGlja0ZlZUdyb3d0aE91dHNpZGUwWDEyOChwb29sUGF0aCBzdHJpbmcsIHRpY2sgaW50MzIpIChzdHJpbmcsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuICIiLCBlcnIKCX0KCgl0aWNrSW5mbywgZXJyIDo9IHBvb2wuR2V0VGljayh0aWNrKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuICIiLCBlcnIKCX0KCXJldHVybiB0aWNrSW5mby5GZWVHcm93dGhPdXRzaWRlMFgxMjgoKSwgbmlsCn0KCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciBjb250YWluaW5nIHRoZSB0aWNrLgovLyAgIC0gdGljazogc2lnbmVkIHRpY2sgaW5kZXggd2hvc2UgdG9rZW4xIGZlZS1ncm93dGgtb3V0c2lkZSB2YWx1ZSBpcyByZXF1ZXN0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBmZWVHcm93dGhPdXRzaWRlMVgxMjg6IHRva2VuMSBmZWUtZ3Jvd3RoLW91dHNpZGUgYWNjdW11bGF0b3Igc2NhbGVkIGJ5Ci8vICAgICAyXjEyOCwgZW5jb2RlZCBhcyBhIGRlY2ltYWwgc3RyaW5nLgovLyAgIC0gZXJyOiBuaWwgd2hlbiBwb29sIGFuZCB0aWNrIGV4aXN0OyB0aGUgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRUaWNrRmVlR3Jvd3RoT3V0c2lkZTFYMTI4KHBvb2xQYXRoIHN0cmluZywgdGljayBpbnQzMikgKHN0cmluZywgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoKCXRpY2tJbmZvLCBlcnIgOj0gcG9vbC5HZXRUaWNrKHRpY2spCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoJcmV0dXJuIHRpY2tJbmZvLkZlZUdyb3d0aE91dHNpZGUxWDEyOCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHRpY2suCi8vICAgLSB0aWNrOiBzaWduZWQgdGljayBpbmRleCB3aG9zZSB0b2tlbiBmZWUtZ3Jvd3RoLW91dHNpZGUgdmFsdWVzIGFyZSByZXF1ZXN0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBmZWVHcm93dGhPdXRzaWRlMFgxMjg6IHRva2VuMCBmZWUtZ3Jvd3RoLW91dHNpZGUgYWNjdW11bGF0b3Igc2NhbGVkIGJ5IDJeMTI4LAovLyAgICAgZW5jb2RlZCBhcyBhIGRlY2ltYWwgc3RyaW5nLgovLyAgIC0gZmVlR3Jvd3RoT3V0c2lkZTFYMTI4OiB0b2tlbjEgZmVlLWdyb3d0aC1vdXRzaWRlIGFjY3VtdWxhdG9yIHNjYWxlZCBieSAyXjEyOCwKLy8gICAgIGVuY29kZWQgYXMgYSBkZWNpbWFsIHN0cmluZy4KLy8gICAtIGVycjogbmlsIHdoZW4gcG9vbCBhbmQgdGljayBleGlzdDsgdGhlIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0VGlja0ZlZUdyb3d0aE91dHNpZGVYMTI4KHBvb2xQYXRoIHN0cmluZywgdGljayBpbnQzMikgKHN0cmluZywgc3RyaW5nLCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgIiIsIGVycgoJfQoKCXRpY2tJbmZvLCBlcnIgOj0gcG9vbC5HZXRUaWNrKHRpY2spCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsICIiLCBlcnIKCX0KCglyZXR1cm4gdGlja0luZm8uRmVlR3Jvd3RoT3V0c2lkZTBYMTI4KCksIHRpY2tJbmZvLkZlZUdyb3d0aE91dHNpZGUxWDEyOCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHRpY2suCi8vICAgLSB0aWNrOiBzaWduZWQgdGljayBpbmRleCB3aG9zZSBjdW11bGF0aXZlIHRpY2stb3V0c2lkZSB2YWx1ZSBpcyByZXF1ZXN0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSB0aWNrQ3VtdWxhdGl2ZU91dHNpZGU6IGN1bXVsYXRpdmUgdGljayB2YWx1ZSByZWNvcmRlZCBvdXRzaWRlIHRoZSB0aWNrJ3MKLy8gICAgIGFjdGl2ZSByYW5nZS4KLy8gICAtIGVycjogbmlsIHdoZW4gcG9vbCBhbmQgdGljayBleGlzdDsgdGhlIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0VGlja0N1bXVsYXRpdmVPdXRzaWRlKHBvb2xQYXRoIHN0cmluZywgdGljayBpbnQzMikgKGludDY0LCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCgl0aWNrSW5mbywgZXJyIDo9IHBvb2wuR2V0VGljayh0aWNrKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoJcmV0dXJuIHRpY2tJbmZvLlRpY2tDdW11bGF0aXZlT3V0c2lkZSgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHRpY2suCi8vICAgLSB0aWNrOiBzaWduZWQgdGljayBpbmRleCB3aG9zZSBzZWNvbmRzLXBlci1saXF1aWRpdHkgYWNjdW11bGF0b3IgaXMKLy8gICAgIHJlcXVlc3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHNlY29uZHNQZXJMaXF1aWRpdHlPdXRzaWRlWDEyODogc2Vjb25kcy1wZXItbGlxdWlkaXR5LW91dHNpZGUgYWNjdW11bGF0b3IKLy8gICAgIGVuY29kZWQgYXMgYSBkZWNpbWFsIGludGVnZXIgc2NhbGVkIGJ5IDJeMTI4LgovLyAgIC0gZXJyOiBuaWwgd2hlbiBwb29sIGFuZCB0aWNrIGV4aXN0OyB0aGUgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRUaWNrU2Vjb25kc1BlckxpcXVpZGl0eU91dHNpZGVYMTI4KHBvb2xQYXRoIHN0cmluZywgdGljayBpbnQzMikgKHN0cmluZywgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoKCXRpY2tJbmZvLCBlcnIgOj0gcG9vbC5HZXRUaWNrKHRpY2spCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoJcmV0dXJuIHRpY2tJbmZvLlNlY29uZHNQZXJMaXF1aWRpdHlPdXRzaWRlWDEyOCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHRpY2suCi8vICAgLSB0aWNrOiBzaWduZWQgdGljayBpbmRleCB3aG9zZSBzZWNvbmRzLW91dHNpZGUgYWNjdW11bGF0b3IgaXMgcmVxdWVzdGVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gc2Vjb25kc091dHNpZGU6IHNlY29uZHMgZWxhcHNlZCBvdXRzaWRlIHRoZSB0aWNrJ3Mgc2lkZSBvZiB0aGUgYWN0aXZlCi8vICAgICByYW5nZSwgYXMgcmVjb3JkZWQgYnkgdGhlIHBvb2wuCi8vICAgLSBlcnI6IG5pbCB3aGVuIHBvb2wgYW5kIHRpY2sgZXhpc3Q7IHRoZSBsb29rdXAgZXJyb3Igb3RoZXJ3aXNlLgpmdW5jIChpICpwb29sVjEpIEdldFRpY2tTZWNvbmRzT3V0c2lkZShwb29sUGF0aCBzdHJpbmcsIHRpY2sgaW50MzIpICh1aW50MzIsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoKCXRpY2tJbmZvLCBlcnIgOj0gcG9vbC5HZXRUaWNrKHRpY2spCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CglyZXR1cm4gdGlja0luZm8uU2Vjb25kc091dHNpZGUoKSwgbmlsCn0KCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciBjb250YWluaW5nIHRoZSB0aWNrLgovLyAgIC0gdGljazogc2lnbmVkIHRpY2sgaW5kZXggd2hvc2UgaW5pdGlhbGl6YXRpb24gZmxhZyBpcyByZXF1ZXN0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbml0aWFsaXplZDogdHJ1ZSB3aGVuIHRoZSB0aWNrIGhhcyBiZWVuIGluaXRpYWxpemVkIGluIHRoZSBwb29sLgovLyAgIC0gZXJyOiBuaWwgd2hlbiBwb29sIGFuZCB0aWNrIGNhbiBiZSByZWFkOyB0aGUgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRUaWNrSW5pdGlhbGl6ZWQocG9vbFBhdGggc3RyaW5nLCB0aWNrIGludDMyKSAoYm9vbCwgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZmFsc2UsIGVycgoJfQoKCXRpY2tJbmZvLCBlcnIgOj0gcG9vbC5HZXRUaWNrKHRpY2spCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZmFsc2UsIGVycgoJfQoJcmV0dXJuIHRpY2tJbmZvLkluaXRpYWxpemVkKCksIG5pbAp9CgovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IGNhbm9uaWNhbCBwb29sIGlkZW50aWZpZXIgdG8gbG9vayB1cC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHRpY2s6IGN1cnJlbnQgc2lnbmVkIHNsb3QwIHRpY2suCi8vICAgLSBlcnI6IG5pbCB3aGVuIHRoZSBwb29sIGV4aXN0czsgdGhlIHBvb2wgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRTbG90MFRpY2socG9vbFBhdGggc3RyaW5nKSAoaW50MzIsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoJcmV0dXJuIHBvb2wuU2xvdDBUaWNrKCksIG5pbAp9CgovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IGNhbm9uaWNhbCBwb29sIGlkZW50aWZpZXIgdG8gbG9vayB1cC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHNxcnRQcmljZVg5NjogY3VycmVudCBzcXVhcmUtcm9vdCBwcmljZSBhcyBhIHUyNTYgUTY0Ljk2IGludGVnZXIuCi8vICAgLSBlcnI6IG5pbCB3aGVuIHRoZSBwb29sIGV4aXN0czsgdGhlIHBvb2wgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRTbG90MFNxcnRQcmljZVg5Nihwb29sUGF0aCBzdHJpbmcpICgqdTI1Ni5VaW50LCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBuaWwsIGVycgoJfQoJcmV0dXJuIHBvb2wuU2xvdDBTcXJ0UHJpY2VYOTYoKSwgbmlsCn0KCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciB0byBsb29rIHVwLgovLwovLyBSZXR1cm5zOgovLyAgIC0gZmVlR3Jvd3RoR2xvYmFsMFgxMjg6IGdsb2JhbCB0b2tlbjAgZmVlLWdyb3d0aCBhY2N1bXVsYXRvciBzY2FsZWQgYnkgMl4xMjguCi8vICAgLSBmZWVHcm93dGhHbG9iYWwxWDEyODogZ2xvYmFsIHRva2VuMSBmZWUtZ3Jvd3RoIGFjY3VtdWxhdG9yIHNjYWxlZCBieSAyXjEyOC4KLy8gICAtIGVycjogbmlsIHdoZW4gdGhlIHBvb2wgZXhpc3RzOyB0aGUgcG9vbCBsb29rdXAgZXJyb3Igb3RoZXJ3aXNlLgpmdW5jIChpICpwb29sVjEpIEdldEZlZUdyb3d0aEdsb2JhbFgxMjgocG9vbFBhdGggc3RyaW5nKSAoKnUyNTYuVWludCwgKnUyNTYuVWludCwgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBuaWwsIGVycgoJfQoJcmV0dXJuIHBvb2wuRmVlR3Jvd3RoR2xvYmFsMFgxMjgoKSwgcG9vbC5GZWVHcm93dGhHbG9iYWwxWDEyOCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHBvc2l0aW9uLgovLyAgIC0ga2V5OiBwb3NpdGlvbiBrZXkgaWRlbnRpZnlpbmcgaXRzIGxvd2VyIGFuZCB1cHBlciB0aWNrIHJhbmdlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gZmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4OiB0b2tlbjAgZmVlLWdyb3d0aC1pbnNpZGUgdmFsdWUgbGFzdCBhY2NvdW50ZWQKLy8gICAgIGZvciB0aGUgcG9zaXRpb24sIGVuY29kZWQgYXMgYSBkZWNpbWFsIGludGVnZXIgc2NhbGVkIGJ5IDJeMTI4LgovLyAgIC0gZmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4OiB0b2tlbjEgZmVlLWdyb3d0aC1pbnNpZGUgdmFsdWUgbGFzdCBhY2NvdW50ZWQKLy8gICAgIGZvciB0aGUgcG9zaXRpb24sIGVuY29kZWQgYXMgYSBkZWNpbWFsIGludGVnZXIgc2NhbGVkIGJ5IDJeMTI4LgovLyAgIC0gZXJyOiBuaWwgd2hlbiBwb29sIGFuZCBwb3NpdGlvbiBleGlzdDsgdGhlIGxvb2t1cCBlcnJvciBvdGhlcndpc2UuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0UG9zaXRpb25GZWVHcm93dGhJbnNpZGVMYXN0WDEyOChwb29sUGF0aCwga2V5IHN0cmluZykgKHN0cmluZywgc3RyaW5nLCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgIiIsIGVycgoJfQoJcG9zaXRpb24sIGVyciA6PSBwb29sLkdldFBvc2l0aW9uKGtleSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgIiIsIGVycgoJfQoJcmV0dXJuIHBvc2l0aW9uLkZlZUdyb3d0aEluc2lkZTBMYXN0WDEyOCgpLAoJCXBvc2l0aW9uLkZlZUdyb3d0aEluc2lkZTFMYXN0WDEyOCgpLCBuaWwKfQoKLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHBvc2l0aW9uLgovLyAgIC0ga2V5OiBwb3NpdGlvbiBrZXkgaWRlbnRpZnlpbmcgaXRzIGxvd2VyIGFuZCB1cHBlciB0aWNrIHJhbmdlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gbGlxdWlkaXR5OiBwb3NpdGlvbiBsaXF1aWRpdHkgZW5jb2RlZCBhcyBhIGRlY2ltYWwgaW50ZWdlciBzdHJpbmcuCi8vICAgLSBlcnI6IG5pbCB3aGVuIHBvb2wgYW5kIHBvc2l0aW9uIGV4aXN0OyB0aGUgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRQb3NpdGlvbkxpcXVpZGl0eShwb29sUGF0aCwga2V5IHN0cmluZykgKHN0cmluZywgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoJcG9zaXRpb24sIGVyciA6PSBwb29sLkdldFBvc2l0aW9uKGtleSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgZXJyCgl9CglyZXR1cm4gcG9zaXRpb24uTGlxdWlkaXR5KCksIG5pbAp9CgovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IGNhbm9uaWNhbCBwb29sIGlkZW50aWZpZXIgd2hvc2UgZXhpc3RlbmNlIGlzIGNoZWNrZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBleGlzdHM6IHRydWUgd2hlbiB0aGUgcG9vbCB0cmVlIGNvbnRhaW5zIHBvb2xQYXRoLgpmdW5jIChpICpwb29sVjEpIEV4aXN0c1Bvb2xQYXRoKHBvb2xQYXRoIHN0cmluZykgYm9vbCB7Cglwb29scyA6PSBpLnN0b3JlLkdldFBvb2xzKCkKCXJldHVybiBwb29scy5IYXMocG9vbFBhdGgpCn0KCi8vIFJldHVybnM6Ci8vICAgLSBwb29sQ3JlYXRpb25GZWU6IGNvbmZpZ3VyZWQgcG9vbC1jcmVhdGlvbiBjaGFyZ2UgaW4gdGhlIGNoYWluJ3Mgc21hbGxlc3QKLy8gICAgIGN1cnJlbmN5IHVuaXQuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0UG9vbENyZWF0aW9uRmVlKCkgaW50NjQgewoJcmV0dXJuIGkuc3RvcmUuR2V0UG9vbENyZWF0aW9uRmVlKCkKfQoKLy8gUmV0dXJuczoKLy8gICAtIHdpdGhkcmF3YWxGZWVCUFM6IGNvbmZpZ3VyZWQgd2l0aGRyYXdhbCBmZWUgaW4gYmFzaXMgcG9pbnRzLCB3aGVyZSAxMDAKLy8gICAgIGJhc2lzIHBvaW50cyBlcXVhbHMgb25lIHBlcmNlbnQuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0V2l0aGRyYXdhbEZlZSgpIHVpbnQ2NCB7CglyZXR1cm4gaS5zdG9yZS5HZXRXaXRoZHJhd2FsRmVlQlBTKCkKfQoKLy8gT3JhY2xlQ29uc3VsdCByZXR1cm5zIHRoZSB0aW1lLXdlaWdodGVkIGF2ZXJhZ2UgcHJpY2UgZm9yIGEgcG9vbCBvdmVyIGEgc3BlY2lmaWVkIHBlcmlvZC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIHdob3NlIG9ic2VydmF0aW9ucyBhcmUgY29uc3VsdGVkLgovLyAgIC0gc2Vjb25kc0FnbzogbG9va2JhY2sgZHVyYXRpb24gaW4gc2Vjb25kcyBmb3IgdGhlIHRpbWUtd2VpZ2h0ZWQgcXVlcnkuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBhcml0aG1ldGljTWVhblRpY2s6IGFyaXRobWV0aWMgbWVhbiB0aWNrIG92ZXIgdGhlIHJlcXVlc3RlZCBsb29rYmFjay4KLy8gICAtIGhhcm1vbmljTWVhbkxpcXVpZGl0eTogaGFybW9uaWMgbWVhbiBhY3RpdmUgbGlxdWlkaXR5IGFzIGEgdTI1NiBpbnRlZ2VyLgovLyAgIC0gZXJyOiBuaWwgd2hlbiB0aGUgcG9vbCBoaXN0b3J5IGNvdmVycyBzZWNvbmRzQWdvOyBhbiBvYnNlcnZhdGlvbiBvcgovLyAgICAgbG9va2JhY2sgZXJyb3Igb3RoZXJ3aXNlLgpmdW5jIChpICpwb29sVjEpIE9yYWNsZUNvbnN1bHQocG9vbFBhdGggc3RyaW5nLCBzZWNvbmRzQWdvIHVpbnQzMikgKGludDMyLCAqdTI1Ni5VaW50LCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IGkuZ2V0UG9vbChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBuaWwsIGVycgoJfQoKCW9ic2VydmF0aW9ucywgZXJyIDo9IGkuZ2V0T2JzZXJ2YXRpb25zKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIG5pbCwgZXJyCgl9CgoJdGljaywgbGlxdWlkaXR5LCBlcnIgOj0gb3JhY2xlQ29uc3VsdChwb29sLCBvYnNlcnZhdGlvbnMsIHNlY29uZHNBZ28pCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgbmlsLCBlcnIKCX0KCglyZXR1cm4gdGljaywgbGlxdWlkaXR5LCBuaWwKfQoKLy8gR2V0UG9vbHMgcmV0dXJucyBhIHJlYWQtb25seSB2aWV3IG9mIGV2ZXJ5IHBvb2wsIGtleWVkIGJ5IHBvb2wgcGF0aC4KLy8gQ2FsbGVycyBwYWdpbmF0ZSBpdCB0aGVtc2VsdmVzIHRocm91Z2ggSXRlcmF0ZUJ5T2Zmc2V0LgovLyBSZXR1cm5zOgovLyAgIC0gcG9vbHM6IHJlYWQtb25seSB0cmVlIGtleWVkIGJ5IGNhbm9uaWNhbCBwb29sIHBhdGg7IGVudHJpZXMgYXJlIGV4cG9zZWQKLy8gICAgIHRocm91Z2ggc2FmZSByZWFkLW9ubHkgd3JhcHBlcnMgYW5kIGNhbGxlcnMgcGFnaW5hdGUgdGhlIHRyZWUgdGhlbXNlbHZlcy4KZnVuYyAoaSAqcG9vbFYxKSBHZXRQb29scygpICpyb3RyZWUuUmVhZE9ubHlUcmVlIHsKCXJldHVybiByb3RyZWUuV3JhcChpLnN0b3JlLkdldFBvb2xzKCksIGNsb25lUG9vbEVudHJ5KQp9CgovLyBHZXRGZWVBbW91bnRUaWNrU3BhY2luZ3MgcmV0dXJucyBhbGwgZmVlIHRpZXIgdG8gdGljayBzcGFjaW5nIG1hcHBpbmdzLgovLyBSZXR1cm5zOgovLyAgIC0gZmVlQW1vdW50VGlja1NwYWNpbmdzOiBjb3B5IG9mIHRoZSBjb25maWd1cmVkIGZlZS10aWVyIHRvIHRpY2stc3BhY2luZwovLyAgICAgbWFwcGluZy4KZnVuYyAoaSAqcG9vbFYxKSBHZXRGZWVBbW91bnRUaWNrU3BhY2luZ3MoKSBtYXBbdWludDMyXWludDMyIHsKCXJldHVybiBpLnN0b3JlLkdldEZlZUFtb3VudFRpY2tTcGFjaW5nKCkKfQoKLy8gR2V0UG9vbFBvc2l0aW9ucyByZXR1cm5zIGEgcmVhZC1vbmx5IHZpZXcgb2YgYSBwb29sJ3MgcG9zaXRpb25zLCBrZXllZCBieQovLyBwb3NpdGlvbiBrZXkuIENhbGxlcnMgcGFnaW5hdGUgaXQgdGhlbXNlbHZlcyB0aHJvdWdoIEl0ZXJhdGVCeU9mZnNldC4KLy8gbmlsIGlzIHJldHVybmVkIHdoZW4gdGhlIHBvb2wgZG9lcyBub3QgZXhpc3QuCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogY2Fub25pY2FsIHBvb2wgaWRlbnRpZmllciB3aG9zZSBwb3NpdGlvbnMgYXJlIGV4cG9zZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBwb3NpdGlvbnM6IHJlYWQtb25seSB0cmVlIGtleWVkIGJ5IHBvc2l0aW9uIGtleSwgb3IgbmlsIHdoZW4gcG9vbFBhdGgKLy8gICAgIGRvZXMgbm90IGlkZW50aWZ5IGFuIGV4aXN0aW5nIHBvb2wuCmZ1bmMgKGkgKnBvb2xWMSkgR2V0UG9vbFBvc2l0aW9ucyhwb29sUGF0aCBzdHJpbmcpICpyb3RyZWUuUmVhZE9ubHlUcmVlIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsCgl9CgoJLy8gbWFrZUVudHJ5U2FmZUZuIGlzIGEgZnVuY3Rpb24gdGhhdCBtYWtlcyBhbiBlbnRyeSBzYWZlIHRvIHJlYWQuCgkvLyBCdXQgUG9zaXRpb25JbmZvIGlzIGltbXV0YWJsZSwgc28gd2UgY2FuIGp1c3QgcmV0dXJuIHRoZSBlbnRyeSBhcyBpcy4KCXJldHVybiByb3RyZWUuV3JhcChwb29sLlBvc2l0aW9ucygpLCBuaWwpCn0KCi8vIFRpY2sgZW51bWVyYXRpb24KCi8vIEdldEluaXRpYWxpemVkVGlja3NJblJhbmdlIHJldHVybnMgaW5pdGlhbGl6ZWQgdGlja3Mgd2l0aGluIHRoZSBnaXZlbiByYW5nZS4KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIHdob3NlIGluaXRpYWxpemVkIHRpY2tzIGFyZSBsaXN0ZWQuCi8vICAgLSB0aWNrTG93ZXI6IGluY2x1c2l2ZSBsb3dlciB0aWNrIGJvdW5kIGZvciBlbnVtZXJhdGlvbi4KLy8gICAtIHRpY2tVcHBlcjogaW5jbHVzaXZlIHVwcGVyIHRpY2sgYm91bmQgZm9yIGVudW1lcmF0aW9uLgovLwovLyBSZXR1cm5zOgovLyAgIC0gdGlja3M6IGluaXRpYWxpemVkIHRpY2sgaW5kaWNlcyBpbiB0aGUgcmVxdWVzdGVkIGluY2x1c2l2ZSByYW5nZSwgaW4KLy8gICAgIGVuY29kZWQgdHJlZSBvcmRlcjsgZW1wdHkgd2hlbiBubyB0aWNrcyBhcmUgaW5pdGlhbGl6ZWQgdGhlcmUuCi8vICAgLSBlcnI6IG5pbCB3aGVuIHRoZSBwb29sIGV4aXN0czsgdGhlIHBvb2wgbG9va3VwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRJbml0aWFsaXplZFRpY2tzSW5SYW5nZShwb29sUGF0aCBzdHJpbmcsIHRpY2tMb3dlciwgdGlja1VwcGVyIGludDMyKSAoW11pbnQzMiwgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBlcnIKCX0KCgl0aWNrcyA6PSBtYWtlKFtdaW50MzIsIDApCgoJcG9vbC5JdGVyYXRlVGlja3ModGlja0xvd2VyLCB0aWNrVXBwZXIsIGZ1bmModGljayBpbnQzMiwgXyBwbC5UaWNrSW5mbykgYm9vbCB7CgkJdGlja3MgPSBhcHBlbmQodGlja3MsIHRpY2spCgkJcmV0dXJuIGZhbHNlCgl9KQoKCXJldHVybiB0aWNrcywgbmlsCn0KCi8vIFN0cnVjdHVyZSBnZXR0ZXJzCgovLyBHZXRUaWNrSW5mbyByZXR1cm5zIHRoZSB0aWNrIGluZm8gZm9yIGEgZ2l2ZW4gdGljay4KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBjYW5vbmljYWwgcG9vbCBpZGVudGlmaWVyIGNvbnRhaW5pbmcgdGhlIHRpY2suCi8vICAgLSB0aWNrOiBzaWduZWQgdGljayBpbmRleCB3aG9zZSBmdWxsIHN0YXRlIGlzIHJlcXVlc3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHRpY2tJbmZvOiBpbml0aWFsaXplZCBzdGF0ZSBhbmQgb3V0c2lkZSBhY2N1bXVsYXRvcnMgZm9yIHRpY2suCi8vICAgLSBlcnI6IG5pbCB3aGVuIHRoZSBwb29sIGFuZCB0aWNrIGNhbiBiZSByZWFkOyB0aGUgY29ycmVzcG9uZGluZyBsb29rdXAKLy8gICAgIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRUaWNrSW5mbyhwb29sUGF0aCBzdHJpbmcsIHRpY2sgaW50MzIpIChwbC5UaWNrSW5mbywgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBpLmdldFBvb2wocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gcGwuTmV3VGlja0luZm8oKSwgZXJyCgl9CgoJcmV0dXJuIHBvb2wuR2V0VGljayh0aWNrKQp9CgovLyBHZXRUaWNrQml0bWFwcyByZXR1cm5zIHRoZSB0aWNrIGJpdG1hcCBmb3IgYSBnaXZlbiB3b3JkIHBvc2l0aW9uLgovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IGNhbm9uaWNhbCBwb29sIGlkZW50aWZpZXIgd2hvc2UgYml0bWFwIG1hcCBpcyBxdWVyaWVkLgovLyAgIC0gd29yZFBvczogc2lnbmVkIGJpdG1hcC13b3JkIHBvc2l0aW9uIHRvIHJldHJpZXZlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYml0bWFwOiBkZWNpbWFsIHN0cmluZyBlbmNvZGluZyB0aGUgaW5pdGlhbGl6ZWQtdGljayBiaXRtYXAgd29yZCBhdAovLyAgICAgd29yZFBvcy4KLy8gICAtIGVycjogbmlsIHdoZW4gdGhlIHBvb2wgYW5kIGJpdG1hcCB3b3JkIGV4aXN0OyB0aGUgcG9vbCBsb29rdXAgb3IgbWlzc2luZwovLyAgICAgYml0bWFwIGVycm9yIG90aGVyd2lzZS4KZnVuYyAoaSAqcG9vbFYxKSBHZXRUaWNrQml0bWFwcyhwb29sUGF0aCBzdHJpbmcsIHdvcmRQb3MgaW50MTYpIChzdHJpbmcsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuICIiLCBlcnIKCX0KCgl0aWNrQml0bWFwLCBvayA6PSBwb29sLlRpY2tCaXRtYXBzKClbd29yZFBvc10KCWlmICFvayB7CgkJcmV0dXJuICIiLCB1Zm10LkVycm9yZigidGljayBiaXRtYXAgJWQgbm90IGZvdW5kIiwgd29yZFBvcykKCX0KCglyZXR1cm4gdGlja0JpdG1hcCwgbmlsCn0KGtUFChBnZXR0ZXJfdXRpbHMuZ25vEsAFcGFja2FnZSBwb29sCgppbXBvcnQgKAoJcGwgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgopCgovLyBUaGUgZnVuY3Rpb25zIGJlbG93IGFyZSBtYWtlRW50cnlTYWZlRm4gdHJhbnNmb3JtYXRpb25zIGhhbmRlZCB0bwovLyByb3RyZWUuV3JhcC4gVGhleSBydW4gb24gZXZlcnkgcmVhZCB0aHJvdWdoIGEgcmVhZC1vbmx5IHZpZXcsIHNvIGVhY2ggb25lCi8vIHJldHVybnMgYSB2YWx1ZSB0aGUgY2FsbGVyIG1heSBob2xkIHdpdGhvdXQgcmVhY2hpbmcgcmVhbG0tb3duZWQgc3RhdGUuCgovLyBjbG9uZVBvb2xFbnRyeSBpcyB0aGUgdHJhbnNmb3JtYXRpb24gZm9yIHRoZSBwb29sIHRyZWUuIFBvb2wgaXMgbXV0YWJsZSBhbmQKLy8gaXRzIHNldHRlcnMgYXJlIGRlY2xhcmVkIGluIC9yL2dub3N3YXAvcG9vbCwgc28gYW4gZXh0ZXJuYWwgaG9sZGVyIG9mIHRoZQovLyBzdG9yZWQgcG9pbnRlciBjb3VsZCB3cml0ZSByZWFsbSBzdGF0ZSB0aHJvdWdoIGl0LgovLwovLyBQb29sLkNsb25lIGxlYXZlcyB0aGUgcG9vbCdzIGNvbGxlY3Rpb25zIG5pbDsgc2VlIGl0IGZvciB3aGljaCBsb29rdXBzIHJlYWQKLy8gdGhlbSBpbnN0ZWFkLgpmdW5jIGNsb25lUG9vbEVudHJ5KHZhbHVlIGFueSkgYW55IHsKCXBvb2wsIG9rIDo9IHZhbHVlLigqcGwuUG9vbCkKCWlmICFvayB7CgkJcmV0dXJuIG5pbAoJfQoKCXJldHVybiBwb29sLkNsb25lKCkKfQoaQQoLZ25vbW9kLnRvbWwSMm1vZHVsZSA9ICJnbm8ubGFuZC9yL2dub3N3YXAvcG9vbC92MSIKZ25vID0gIjAuOSIKGrMhCghpbml0LmdubxKmIXBhY2thZ2UgcG9vbAoKaW1wb3J0ICgKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCSJnbm8ubGFuZC9yL2dub3N3YXAvYWNjZXNzL3YxIgoJImduby5sYW5kL3IvZ25vc3dhcC9lbWlzc2lvbiIKCSJnbm8ubGFuZC9yL2dub3N3YXAvcG9vbCIKKQoKY29uc3QgKAoJLy8gc2xvdDBGZWVQcm90b2NvbCBpcyB0aGUgcHJvdG9jb2wtZmVlIGRlbm9taW5hdG9yICgwIG9yIDQtMTApLgoJLy8gWmVybyBkaXNhYmxlcyBwcm90b2NvbCBmZWVzOyA0IHJvdXRlcyAxLzQgb2Ygc3dhcCBmZWVzIHRvIHRoZSBwcm90b2NvbC4KCS8vIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBtb2RpZmllZCB0aHJvdWdoIGdvdmVybmFuY2UuCglkZWZhdWx0U2xvdDBGZWVQcm90b2NvbCA9IHVpbnQ4KDApCgoJLy8gcG9vbENyZWF0aW9uRmVlIGlzIHRoZSBmZWUgdGhhdCBpcyBjaGFyZ2VkIHdoZW4gYSB1c2VyIGNyZWF0ZXMgYSBwb29sLgoJLy8gVGhlIGZlZSBpcyBkZW5vbWluYXRlZCBpbiBHTlMgdG9rZW5zLgoJLy8gVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIG1vZGlmaWVkIHRocm91Z2ggZ292ZXJuYW5jZS4KCWRlZmF1bHRQb29sQ3JlYXRpb25GZWUgPSBpbnQ2NCgxMDBfMDAwXzAwMCkgLy8gMTAwX0dOUwoKCS8vIHdpdGhkcmF3YWxGZWVCUFMgaXMgdGhlIGZlZSB0aGF0IGlzIGNoYXJnZWQgd2hlbiBhIHVzZXIgd2l0aGRyYXdzIHRoZWlyIGNvbGxlY3RlZCBmZWVzCgkvLyBUaGUgZmVlIGlzIGRlbm9taW5hdGVkIGluIEJQUyAoQmFzaXMgUG9pbnRzKQoJLy8gRXhhbXBsZTogMTAwIEJQUyA9IDElCgkvLyBUaGlzIHBhcmFtZXRlciBjYW4gYmUgbW9kaWZpZWQgdGhyb3VnaCBnb3Zlcm5hbmNlLgoJZGVmYXVsdFdpdGhkcmF3YWxGZWVCUFMgPSB1aW50NjQoMTAwKQoKCWRlZmF1bHRVbmxvY2tlZCA9IHRydWUKKQoKZnVuYyBpbml0KGN1ciByZWFsbSkgewoJcmVnaXN0ZXJQb29sVjEoY3VyKQp9CgpmdW5jIHJlZ2lzdGVyUG9vbFYxKGN1ciByZWFsbSkgewoJcG9vbC5SZWdpc3RlckluaXRpYWxpemVyKGNyb3NzKGN1ciksIGZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcG9vbFN0b3JlIHBvb2wuSVBvb2xTdG9yZSkgcG9vbC5JUG9vbCB7CgkJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJCWVyciA6PSBpbml0U3RvcmVEYXRhKDAsIHJsbSwgcG9vbFN0b3JlKQoJCWlmIGVyciAhPSBuaWwgewoJCQlwYW5pYyhlcnIpCgkJfQoKCQllbWlzc2lvbi5TZXREZWZhdWx0SW5pdGlhbFBvb2xDaGVja2VyKGNyb3NzKHJsbSksIGZ1bmMocG9vbFBhdGggc3RyaW5nKSBib29sIHsKCQkJcmV0dXJuIHBvb2wuRXhpc3RzUG9vbFBhdGgocG9vbFBhdGgpCgkJfSkKCgkJcmV0dXJuIE5ld1Bvb2xWMShwb29sU3RvcmUpCgl9KQp9CgpmdW5jIGluaXRTdG9yZURhdGEoXyBpbnQsIHJsbSByZWFsbSwgcG9vbFN0b3JlIHBvb2wuSVBvb2xTdG9yZSkgZXJyb3IgewoJaWYgIXBvb2xTdG9yZS5IYXNQb29scygpIHsKCQllcnIgOj0gcG9vbFN0b3JlLlNldFBvb2xzKDAsIHJsbSwgcG9vbC5OZXdQb29sc1RyZWUoKSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCglpZiAhcG9vbFN0b3JlLkhhc09ic2VydmF0aW9ucygpIHsKCQllcnIgOj0gcG9vbFN0b3JlLlNldE9ic2VydmF0aW9ucygwLCBybG0sIHBvb2wuTmV3T2JzZXJ2YXRpb25zVHJlZSgpKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmIGVyciA6PSB2YWxpZGF0ZVBvb2xPYnNlcnZhdGlvbnMocG9vbFN0b3JlKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCWlmICFwb29sU3RvcmUuSGFzRmVlQW1vdW50VGlja1NwYWNpbmcoKSB7CgkJZXJyIDo9IHBvb2xTdG9yZS5TZXRGZWVBbW91bnRUaWNrU3BhY2luZygwLCBybG0sIHBvb2wuTmV3RGVmYXVsdEZlZUFtb3VudFRpY2tTcGFjaW5nKCkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJaWYgIXBvb2xTdG9yZS5IYXNQb29sQ3JlYXRpb25GZWUoKSB7CgkJZXJyIDo9IHBvb2xTdG9yZS5TZXRQb29sQ3JlYXRpb25GZWUoMCwgcmxtLCBkZWZhdWx0UG9vbENyZWF0aW9uRmVlKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCXBlbmRpbmdQcm90b2NvbEZlZXMgOj0gbWFrZShtYXBbc3RyaW5nXWludDY0KQoJaWYgcG9vbFN0b3JlLkhhc1BlbmRpbmdQcm90b2NvbEZlZXMoKSB7CgkJcGVuZGluZ1Byb3RvY29sRmVlcyA9IHBvb2xTdG9yZS5HZXRQZW5kaW5nUHJvdG9jb2xGZWVzKCkKCX0KCWlmIGVyciA6PSBwb29sU3RvcmUuU2V0UGVuZGluZ1Byb3RvY29sRmVlcygwLCBybG0sIHBlbmRpbmdQcm90b2NvbEZlZXMpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJaWYgIXBvb2xTdG9yZS5IYXNTbG90MEZlZVByb3RvY29sKCkgewoJCWVyciA6PSBwb29sU3RvcmUuU2V0U2xvdDBGZWVQcm90b2NvbCgwLCBybG0sIGRlZmF1bHRTbG90MEZlZVByb3RvY29sKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFwb29sU3RvcmUuSGFzV2l0aGRyYXdhbEZlZUJQUygpIHsKCQllcnIgOj0gcG9vbFN0b3JlLlNldFdpdGhkcmF3YWxGZWVCUFMoMCwgcmxtLCBkZWZhdWx0V2l0aGRyYXdhbEZlZUJQUykKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCglpZiAhcG9vbFN0b3JlLkhhc1VubG9ja2VkKCkgewoJCWVyciA6PSBwb29sU3RvcmUuU2V0VW5sb2NrZWQoMCwgcmxtLCBkZWZhdWx0VW5sb2NrZWQpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJLy8gSW5pdGlhbGl6ZSBzd2FwIHN0YXJ0IGhvb2sgd2l0aCBuby1vcCBmdW5jdGlvbgoJaWYgIXBvb2xTdG9yZS5IYXNTd2FwU3RhcnRIb29rKCkgewoJCW5vb3BTd2FwU3RhcnQgOj0gZnVuYyhjdXIgcmVhbG0sIHBvb2xQYXRoIHN0cmluZywgdGltZXN0YW1wIGludDY0KSB7fQoJCWVyciA6PSBwb29sU3RvcmUuU2V0U3dhcFN0YXJ0SG9vaygwLCBybG0sIG5vb3BTd2FwU3RhcnQpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJLy8gSW5pdGlhbGl6ZSBzd2FwIGVuZCBob29rIHdpdGggbm8tb3AgZnVuY3Rpb24KCWlmICFwb29sU3RvcmUuSGFzU3dhcEVuZEhvb2soKSB7CgkJbm9vcFN3YXBFbmQgOj0gZnVuYyhjdXIgcmVhbG0sIHBvb2xQYXRoIHN0cmluZykgZXJyb3IgewoJCQlyZXR1cm4gbmlsCgkJfQoJCWVyciA6PSBwb29sU3RvcmUuU2V0U3dhcEVuZEhvb2soMCwgcmxtLCBub29wU3dhcEVuZCkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCgkvLyBJbml0aWFsaXplIHRpY2sgY3Jvc3MgaG9vayB3aXRoIG5vLW9wIGZ1bmN0aW9uCglpZiAhcG9vbFN0b3JlLkhhc1RpY2tDcm9zc0hvb2soKSB7CgkJbm9vcFRpY2tDcm9zcyA6PSBmdW5jKGN1ciByZWFsbSwgcG9vbFBhdGggc3RyaW5nLCB0aWNrSWQgaW50MzIsIHplcm9Gb3JPbmUgYm9vbCwgdGltZXN0YW1wIGludDY0KSB7fQoJCWVyciA6PSBwb29sU3RvcmUuU2V0VGlja0Nyb3NzSG9vaygwLCBybG0sIG5vb3BUaWNrQ3Jvc3MpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJcmV0dXJuIG5pbAp9CgovLyB2YWxpZGF0ZVBvb2xPYnNlcnZhdGlvbnMgZW5zdXJlcyBldmVyeSBwZXJzaXN0ZWQgcG9vbCBvd25zIGFuIG9ic2VydmF0aW9uIHRyZWUuCi8vIENyZWF0ZVBvb2wgaW5pdGlhbGl6ZXMgdGhlIHBhaXIgaW4gb25lIHRyYW5zYWN0aW9uOyB0aGlzIGNoZWNrIGNhdGNoZXMgYW4KLy8gaW1wbGVtZW50YXRpb24gb3IgdXBncmFkZSB0aGF0IHdvdWxkIG90aGVyd2lzZSBsZWF2ZSBhIHBvb2wgdW51c2FibGUgbGF0ZXIuCmZ1bmMgdmFsaWRhdGVQb29sT2JzZXJ2YXRpb25zKHBvb2xTdG9yZSBwb29sLklQb29sU3RvcmUpIGVycm9yIHsKCXBvb2xzIDo9IHBvb2xTdG9yZS5HZXRQb29scygpCglvYnNlcnZhdGlvbnMgOj0gcG9vbFN0b3JlLkdldE9ic2VydmF0aW9ucygpCgoJdmFyIHZhbGlkYXRpb25FcnIgZXJyb3IKCXBvb2xzLkl0ZXJhdGUoIiIsICIiLCBmdW5jKHBvb2xQYXRoIHN0cmluZywgXyBhbnkpIGJvb2wgewoJCWlmICFvYnNlcnZhdGlvbnMuSGFzKHBvb2xQYXRoKSB7CgkJCXZhbGlkYXRpb25FcnIgPSB1Zm10LkVycm9yZigiZXhwZWN0ZWQgb2JzZXJ2YXRpb25zIGZvciBwb29sUGF0aCglcykgdG8gZXhpc3QiLCBwb29sUGF0aCkKCQkJcmV0dXJuIHRydWUKCQl9CgkJcmV0dXJuIGZhbHNlCgl9KQoKCXJldHVybiB2YWxpZGF0aW9uRXJyCn0KGskDCgxpbnN0YW5jZS5nbm8SuANwYWNrYWdlIHBvb2wKCmltcG9ydCAoCgkiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiCikKCnR5cGUgcG9vbFYxIHN0cnVjdCB7CglzdG9yZSBwb29sLklQb29sU3RvcmUKfQoKLy8gTmV3UG9vbFYxIGNvbnN0cnVjdHMgdGhlIHZlcnNpb24tb25lIHBvb2wgaW1wbGVtZW50YXRpb24gYXJvdW5kIHNoYXJlZAovLyBwZXJzaXN0ZW50IHN0b3JhZ2UuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBzdG9yZTogcG9vbC1kb21haW4gc3RvcmFnZSBpbXBsZW1lbnRhdGlvbiB1c2VkIGJ5IHRoZSByZXR1cm5lZCBBUEkuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbXBsZW1lbnRhdGlvbjogSVBvb2wgYmFja2VkIGJ5IHN0b3JlLgpmdW5jIE5ld1Bvb2xWMShzdG9yZSBwb29sLklQb29sU3RvcmUpIHBvb2wuSVBvb2wgewoJcmV0dXJuICZwb29sVjF7CgkJc3RvcmU6IHN0b3JlLAoJfQp9ChrnBwoIbG9jay5nbm8S2gdwYWNrYWdlIHBvb2wKCmltcG9ydCAiZXJyb3JzIgoKLy8gYXNzZXJ0UG9vbFVubG9ja2VkIGlzIHRoZSByZWFkLW9ubHkgcmVlbnRyYW5jeSBndWFyZC4gSXQgcmVwb3J0cyB0aGUgZ2xvYmFsCi8vIHBvb2wgbG9jayBzdGF0ZSB3aXRob3V0IG11dGF0aW5nIGl0LCBzbyBpdCBpcyBzYWZlIHRvIGNhbGwgYmVmb3JlIHRoZSBhY2Nlc3MKLy8gY2hlY2tzOiBhIGNhbGwgdGhhdCBhYm9ydHMgb24gYXV0aG9yaXphdGlvbiBhZnRlcndhcmRzIGxlYXZlcyBubyBwZXJzaXN0ZWQKLy8gbG9jayBiZWhpbmQgKHdoaWNoIHdvdWxkIG90aGVyd2lzZSBsZWFrIHVuZGVyIGludGVycmVhbG0gdjIsIHdoZXJlIGEgcGFuaWMKLy8gY3Jvc3NpbmcgdGhlIHJlYWxtIGJvdW5kYXJ5IHNraXBzIHRoZSBkZWZlcnJlZCB1bmxvY2tQb29sKS4gSXQgYWxzbyBrZWVwcyB0aGUKLy8gImNhbm5vdCBtb2RpZnkgcG9vbCB3aGlsZSBsb2NrZWQiIG1lc3NhZ2UgYXMgdGhlIGZpcnN0IGZhaWx1cmUgZm9yIGFueQovLyBlbnRyeXBvaW50IGludm9rZWQgd2hpbGUgYSBzd2FwIGhvbGRzIHRoZSBsb2NrIChyZWVudHJhbmN5IHByb3RlY3Rpb24pLgpmdW5jIChpICpwb29sVjEpIGFzc2VydFBvb2xVbmxvY2tlZCgpIHsKCWlmIGkuc3RvcmUuSGFzVW5sb2NrZWQoKSAmJiAhaS5zdG9yZS5HZXRVbmxvY2tlZCgpIHsKCQlwYW5pYyhlcnJvcnMuTmV3KGVyckxvY2tlZFBvb2wpKQoJfQp9CgpmdW5jIChpICpwb29sVjEpIGxvY2tQb29sKF8gaW50LCBybG0gcmVhbG0pIHsKCWkuYXNzZXJ0UG9vbFVubG9ja2VkKCkKCglpZiBlcnIgOj0gaS5zdG9yZS5TZXRVbmxvY2tlZCgwLCBybG0sIGZhbHNlKTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQp9CgpmdW5jIChpICpwb29sVjEpIHVubG9ja1Bvb2woXyBpbnQsIHJsbSByZWFsbSkgewoJaWYgZXJyIDo9IGkuc3RvcmUuU2V0VW5sb2NrZWQoMCwgcmxtLCB0cnVlKTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQp9Chr2XAoLbWFuYWdlci5nbm8S5lxwYWNrYWdlIHBvb2wKCmltcG9ydCAoCgkiY2hhaW4iCgkiZXJyb3JzIgoJInRpbWUiCgoJcHJhYmMgImduby5sYW5kL3AvZ25vc3dhcC9yYmFjL3YxIgoJImduby5sYW5kL3AvZ25vc3dhcC91dGlscy92MSIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKCSJnbm8ubGFuZC9yL2dub3N3YXAvY29tbW9uIgoJZ25zICJnbm8ubGFuZC9yL2dub3N3YXAvZ25zIgoJImduby5sYW5kL3IvZ25vc3dhcC9oYWx0L3YxIgoJcGwgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgoKCWVuICJnbm8ubGFuZC9yL2dub3N3YXAvZW1pc3Npb24iCikKCmNvbnN0IEdOU19UT0tFTl9LRVkgc3RyaW5nID0gImduby5sYW5kL3IvZ25vc3dhcC9nbnMuR05TIgoKLy8gQ3JlYXRlUG9vbCBjcmVhdGVzIGEgbmV3IGNvbmNlbnRyYXRlZCBsaXF1aWRpdHkgcG9vbC4KLy8KLy8gRGVwbG95cyBhIG5ldyBBTU0gcG9vbCBmb3IgYSB0b2tlbiBwYWlyIHdpdGggdGhlIHNwZWNpZmllZCBmZWUgdGllci4KLy8gQ2hhcmdlcyB0aGUgY29uZmlndXJlZCBwb29sLWNyZWF0aW9uIGZlZSAoMTAwIEdOUyBieSBkZWZhdWx0KS4KLy8gQWNjZXB0cyBlaXRoZXIgdG9rZW4gcGF0aCBvcmRlciwgY2Fub25pY2FsaXplcyB0b2tlbjAvdG9rZW4xLCBhbmQgc2V0cyB0aGUKLy8gaW5pdGlhbCBwcmljZSBhbmQgdGljayBzcGFjaW5nIGZvciB0aGF0IGNhbm9uaWNhbCBvcmRlci4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgcG9vbCBwcm94eS4KLy8gICAtIHRva2VuMFBhdGg6IGZpcnN0IHRva2VuIGNvbnRyYWN0IHBhdGg7IGVpdGhlciBvcmRlciBpcyBhY2NlcHRlZCBhbmQgdGhlCi8vICAgICBzdG9yZWQgcGFpciBpcyBjYW5vbmljYWxpemVkLgovLyAgIC0gdG9rZW4xUGF0aDogc2Vjb25kIHRva2VuIGNvbnRyYWN0IHBhdGg7IGVpdGhlciBvcmRlciBpcyBhY2NlcHRlZCBhbmQgdGhlCi8vICAgICBzdG9yZWQgcGFpciBpcyBjYW5vbmljYWxpemVkLgovLyAgIC0gZmVlOiBzdXBwb3J0ZWQgcG9vbCBmZWUgdGllciAoMTAwPTAuMDElLCA1MDA9MC4wNSUsIDMwMDA9MC4zJSwgMTAwMDA9MSUpLgovLyAgIC0gc3FydFByaWNlWDk2OiBpbml0aWFsIHNxdWFyZS1yb290IHByaWNlIGluIFE2NC45NiBmb3JtYXQsIGNvbnN0cmFpbmVkIHRvCi8vICAgICBbTUlOX1NRUlRfUkFUSU8sIE1BWF9TUVJUX1JBVElPKS4KLy8KLy8gVGljayBzcGFjaW5nIGJ5IGZlZSB0aWVyOgovLyAgIC0gMC4wMSU6IDEgdGljawovLyAgIC0gMC4wNSU6IDEwIHRpY2tzCi8vICAgLSAwLjMwJTogNjAgdGlja3MKLy8gICAtIDEuMDAlOiAyMDAgdGlja3MKLy8KLy8gUmVxdWlyZW1lbnRzOgovLyAgIC0gVG9rZW5zIG11c3QgYmUgZGlmZmVyZW50IGFmdGVyIGNhbm9uaWNhbGl6YXRpb24vd3JhcHBpbmcKLy8gICAtIEZlZSB0aWVyIG11c3QgYmUgc3VwcG9ydGVkCi8vICAgLSBQb29sIG11c3Qgbm90IGFscmVhZHkgZXhpc3QKLy8gICAtIENhbGxlciBtdXN0IGhhdmUgdGhlIGNvbmZpZ3VyZWQgY3JlYXRpb24gZmVlCi8vCi8vIFByaWNlIGluaXRpYWxpemF0aW9uOgovLyAgIC0gVGhlIGluaXRpYWwgc3FydCBwcmljZSBtdXN0IGJlIGluIFtNSU5fU1FSVF9SQVRJTywgTUFYX1NRUlRfUkFUSU8pLgovLyAgIC0gTm8gb3JhY2xlIG9yIGV4dGVybmFsIG1hcmtldC1wcmljZSBzYW5pdHkgY2hlY2sgaXMgcGVyZm9ybWVkLgovLyAgIC0gSWYgcGF0aHMgYXJlIHN1cHBsaWVkIGluIHJldmVyc2Ugb3JkZXIsIHRoZSBzdG9yZWQgc3FydCBwcmljZSBpcwovLyAgICAgaW52ZXJ0ZWQgdG8gbWF0Y2ggdGhlIGNhbm9uaWNhbCB0b2tlbjAvdG9rZW4xIG9yZGVyLgovLwovLyBSZWNvdmVyeSBmcm9tIGFuIGVjb25vbWljYWxseSBpbmFwcHJvcHJpYXRlIHByaWNlOgovLyAgMS4gQWRkIHdpZGUtcmFuZ2UgbGlxdWlkaXR5IGF0IHRoZSBjdXJyZW50IHByaWNlLgovLyAgMi4gRXhlY3V0ZSBhIHN3YXAgdG8gbW92ZSB0aGUgcHJpY2UgdG93YXJkIHRoZSBkZXNpcmVkIG1hcmtldCByYXRlLgovLyAgMy4gUmVtb3ZlIHRoZSBsaXF1aWRpdHkuCi8vCi8vIFRoZSBleGVjdXRvcidzIExQIGxvc3NlcyBvZmZzZXQgYXJiaXRyYWdlIGdhaW5zLCBtaW51cyBmZWVzIGFuZCBzbGlwcGFnZS4KZnVuYyAoaSAqcG9vbFYxKSBDcmVhdGVQb29sKAoJXyBpbnQsCglybG0gcmVhbG0sCgl0b2tlbjBQYXRoIHN0cmluZywKCXRva2VuMVBhdGggc3RyaW5nLAoJZmVlIHVpbnQzMiwKCXNxcnRQcmljZVg5NiBzdHJpbmcsCikgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaS5hc3NlcnRQb29sVW5sb2NrZWQoKQoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFBvb2woKQoKCWFzc2VydElzU3VwcG9ydGVkRmVlVGllcihmZWUpCglhc3NlcnRJc05vdEV4aXN0c1Bvb2xQYXRoKGksIHRva2VuMFBhdGgsIHRva2VuMVBhdGgsIGZlZSkKCglpLmxvY2tQb29sKDAsIHJsbSkKCWRlZmVyIGkudW5sb2NrUG9vbCgwLCBybG0pCgoJZW4uTWludEFuZERpc3RyaWJ1dGVHbnMoY3Jvc3MocmxtKSkKCglzbG90MEZlZVByb3RvY29sIDo9IGkuc3RvcmUuR2V0U2xvdDBGZWVQcm90b2NvbCgpCgoJdGlja1NwYWNpbmcsIGVyciA6PSBpLkdldEZlZUFtb3VudFRpY2tTcGFjaW5nKGZlZSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglwb29sSW5mbyA6PSBuZXdQb29sUGFyYW1zKAoJCXRva2VuMFBhdGgsCgkJdG9rZW4xUGF0aCwKCQlmZWUsCgkJc3FydFByaWNlWDk2LAoJCXRpY2tTcGFjaW5nLAoJCXNsb3QwRmVlUHJvdG9jb2wsCgkpCgoJZXJyID0gcG9vbEluZm8udXBkYXRlKCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgkvLyB2YWxpZGF0ZSB0b2tlbiBwYXRocyBhcmUgbm90IHRoZSBzYW1lIGFmdGVyIHdyYXBwaW5nCglhc3NlcnRJc05vdEVxdWFsc1Rva2Vucyhwb29sSW5mby50b2tlbjBQYXRoLCBwb29sSW5mby50b2tlbjFQYXRoKQoKCS8vIGNoZWNrIGlmIHdyYXBwZWQgdG9rZW4gcGF0aHMgYXJlIHJlZ2lzdGVyZWQKCWNvbW1vbi5NdXN0UmVnaXN0ZXJlZChwb29sSW5mby50b2tlbjBQYXRoLCBwb29sSW5mby50b2tlbjFQYXRoKQoKCXBvb2wgOj0gbmV3UG9vbChwb29sSW5mbykKCXBvb2xQYXRoIDo9IHBvb2xJbmZvLnBvb2xQYXRoKCkKCglwb29scyA6PSBpLnN0b3JlLkdldFBvb2xzKCkKCXBvb2xzLlNldChwb29sUGF0aCwgcG9vbCkKCgllcnIgPSBpLnN0b3JlLlNldFBvb2xzKDAsIHJsbSwgcG9vbHMpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJb2JzZXJ2YXRpb25zIDo9IGkuc3RvcmUuR2V0T2JzZXJ2YXRpb25zKCkKCW9ic2VydmF0aW9ucy5TZXQocG9vbFBhdGgsIHBsLk5ld1Bvb2xPYnNlcnZhdGlvbnNUcmVlKHRpbWUuTm93KCkuVW5peCgpKSkKCWlmIGVyciA6PSBpLnN0b3JlLlNldE9ic2VydmF0aW9ucygwLCBybG0sIG9ic2VydmF0aW9ucyk7IGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglwb29sQ3JlYXRpb25GZWUgOj0gaS5zdG9yZS5HZXRQb29sQ3JlYXRpb25GZWUoKQoKCWlmIHBvb2xDcmVhdGlvbkZlZSA+IDAgewoJCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCQlwcmV2aW91c1JlYWxtQWRkciA6PSBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKQoJCXBvb2xBZGRyIDo9IGFjY2Vzcy5NdXN0R2V0QWRkcmVzcyhwcmFiYy5ST0xFX1BPT0wuU3RyaW5nKCkpCgkJZ25zLlRyYW5zZmVyRnJvbShjcm9zcyhybG0pLCBwcmV2aW91c1JlYWxtQWRkciwgcG9vbEFkZHIsIHBvb2xDcmVhdGlvbkZlZSkKCgkJY2hhaW4uRW1pdCgKCQkJIlBvb2xDcmVhdGlvbkZlZSIsCgkJCSJwcmV2QWRkciIsIHByZXZpb3VzUmVhbG1BZGRyLlN0cmluZygpLAoJCQkicHJldlJlYWxtIiwgcHJldmlvdXNSZWFsbS5Qa2dQYXRoKCksCgkJCSJwb29sUGF0aCIsIHBvb2xQYXRoLAoJCQkiZmVlVG9rZW5QYXRoIiwgR05TX1RPS0VOX0tFWSwKCQkJImZlZUFtb3VudCIsIHV0aWxzLkZvcm1hdEludChwb29sQ3JlYXRpb25GZWUpLAoJCSkKCX0KCglpLnNldHRsZVByb3RvY29sRmVlKDAsIHJsbSwgR05TX1RPS0VOX0tFWSwgcG9vbENyZWF0aW9uRmVlKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWNoYWluLkVtaXQoCgkJIkNyZWF0ZVBvb2wiLAoJCSJwcmV2QWRkciIsIHByZXZpb3VzUmVhbG0uQWRkcmVzcygpLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2aW91c1JlYWxtLlBrZ1BhdGgoKSwKCQkidG9rZW4wUGF0aCIsIHBvb2xJbmZvLlRva2VuMFBhdGgoKSwKCQkidG9rZW4xUGF0aCIsIHBvb2xJbmZvLlRva2VuMVBhdGgoKSwKCQkiZmVlIiwgdXRpbHMuRm9ybWF0VWludChmZWUpLAoJCSJzcXJ0UHJpY2VYOTYiLCBwb29sSW5mby5TcXJ0UHJpY2VYOTYoKS5Ub1N0cmluZygpLAoJCSJwb29sUGF0aCIsIHBvb2xQYXRoLAoJCSJ0aWNrIiwgdXRpbHMuRm9ybWF0SW50KHBvb2wuU2xvdDBUaWNrKCkpLAoJCSJ0aWNrU3BhY2luZyIsIHV0aWxzLkZvcm1hdEludChwb29sSW5mby5UaWNrU3BhY2luZygpKSwKCSkKfQoKLy8gU2V0RmVlUHJvdG9jb2wgc2V0cyB0aGUgcHJvdG9jb2wgZmVlIGRlbm9taW5hdG9ycyBmb3IgYWxsIG1hbmFnZWQgcG9vbHMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCB1bmNoYW5nZWQgYnkgdGhlIHBvb2wgcHJveHkuCi8vICAgLSBmZWVQcm90b2NvbDA6IHRva2VuMCBwcm90b2NvbC1mZWUgZGVub21pbmF0b3I7IG11c3QgYmUgMCBvciA0LTEwLgovLyAgICAgWmVybyBkaXNhYmxlcyBwcm90b2NvbCBmZWVzOyA0IHJvdXRlcyBvbmUgcXVhcnRlciBvZiBzd2FwIGZlZXMgYW5kIDEwCi8vICAgICByb3V0ZXMgb25lIHRlbnRoIHRvIHRoZSBwcm90b2NvbC4KLy8gICAtIGZlZVByb3RvY29sMTogdG9rZW4xIHByb3RvY29sLWZlZSBkZW5vbWluYXRvciB3aXRoIHRoZSBzYW1lIDAgb3IgNC0xMAovLyAgICAgY29uc3RyYWludCBhbmQgZmVlIHNoYXJlIHNlbWFudGljcyBhcyBmZWVQcm90b2NvbDAuCi8vCi8vIE9ubHkgY2FsbGFibGUgYnkgYWRtaW4gb3IgZ292ZXJuYW5jZS4KZnVuYyAoaSAqcG9vbFYxKSBTZXRGZWVQcm90b2NvbChfIGludCwgcmxtIHJlYWxtLCBmZWVQcm90b2NvbDAsIGZlZVByb3RvY29sMSB1aW50OCkgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaS5hc3NlcnRQb29sVW5sb2NrZWQoKQoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFBvb2woKQoKCWNhbGxlciA6PSBybG0uUHJldmlvdXMoKS5BZGRyZXNzKCkKCWFjY2Vzcy5Bc3NlcnRJc0FkbWluT3JHb3Zlcm5hbmNlKGNhbGxlcikKCglpLmxvY2tQb29sKDAsIHJsbSkKCWRlZmVyIGkudW5sb2NrUG9vbCgwLCBybG0pCgoJZXJyIDo9IGkuc2V0RmVlUHJvdG9jb2xJbnRlcm5hbCgwLCBybG0sIGZlZVByb3RvY29sMCwgZmVlUHJvdG9jb2wxKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQp9CgovLyBzZXRGZWVBbW91bnRUaWNrU3BhY2luZyBhc3NvY2lhdGVzIGEgdGljayBzcGFjaW5nIHZhbHVlIHdpdGggYSBmZWUgYW1vdW50LgpmdW5jIChpICpwb29sVjEpIHNldEZlZUFtb3VudFRpY2tTcGFjaW5nKF8gaW50LCBybG0gcmVhbG0sIGZlZSB1aW50MzIsIHRpY2tTcGFjaW5nIGludDMyKSBlcnJvciB7CglmZWVBbW91bnRUaWNrU3BhY2luZyA6PSBpLnN0b3JlLkdldEZlZUFtb3VudFRpY2tTcGFjaW5nKCkKCWZlZUFtb3VudFRpY2tTcGFjaW5nW2ZlZV0gPSB0aWNrU3BhY2luZwoKCXJldHVybiBpLnN0b3JlLlNldEZlZUFtb3VudFRpY2tTcGFjaW5nKDAsIHJsbSwgZmVlQW1vdW50VGlja1NwYWNpbmcpCn0KCmZ1bmMgKGkgKnBvb2xWMSkgZ2V0UG9vbChwb29sUGF0aCBzdHJpbmcpICgqcGwuUG9vbCwgZXJyb3IpIHsKCXBvb2xzIDo9IGkuc3RvcmUuR2V0UG9vbHMoKQoKCWlQb29sIDo9IHBvb2xzLkdldChwb29sUGF0aCkKCWlmIGlQb29sID09IG5pbCB7CgkJcmV0dXJuIG5pbCwgdWZtdC5FcnJvcmYoImV4cGVjdGVkIHBvb2xQYXRoKCVzKSB0byBleGlzdCIsIHBvb2xQYXRoKQoJfQoKCXAsIG9rIDo9IGlQb29sLigqcGwuUG9vbCkKCWlmICFvayB7CgkJcmV0dXJuIG5pbCwgdWZtdC5FcnJvcmYoImZhaWxlZCB0byBjYXN0IHBvb2wgdG8gKlBvb2w6ICVUIiwgaVBvb2wpCgl9CgoJcmV0dXJuIHAsIG5pbAp9CgovLyBtdXN0R2V0UG9vbCByZXRyaWV2ZXMgYSBwb29sIGluc3RhbmNlIGJ5IGl0cyBwYXRoIGFuZCBlbnN1cmVzIGl0IGV4aXN0cy4KZnVuYyAoaSAqcG9vbFYxKSBtdXN0R2V0UG9vbChwb29sUGF0aCBzdHJpbmcpIChwb29sICpwbC5Qb29sKSB7CglwLCBlcnIgOj0gaS5nZXRQb29sKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoZXJyRGF0YU5vdEZvdW5kLCBlcnIuRXJyb3IoKSkpCgl9CgoJcmV0dXJuIHAKfQoKZnVuYyAoaSAqcG9vbFYxKSBtdXN0R2V0UG9vbEJ5KHRva2VuMFBhdGgsIHRva2VuMVBhdGggc3RyaW5nLCBmZWUgdWludDMyKSAqcGwuUG9vbCB7Cglwb29sUGF0aCA6PSBHZXRQb29sUGF0aCh0b2tlbjBQYXRoLCB0b2tlbjFQYXRoLCBmZWUpCglyZXR1cm4gaS5tdXN0R2V0UG9vbChwb29sUGF0aCkKfQoKZnVuYyAoaSAqcG9vbFYxKSBnZXRPYnNlcnZhdGlvbnMocG9vbFBhdGggc3RyaW5nKSAoKnBsLk9ic2VydmF0aW9uVHJlZSwgZXJyb3IpIHsKCW9ic2VydmF0aW9ucyA6PSBpLnN0b3JlLkdldE9ic2VydmF0aW9ucygpCgl2YWx1ZSA6PSBvYnNlcnZhdGlvbnMuR2V0KHBvb2xQYXRoKQoJaWYgdmFsdWUgPT0gbmlsIHsKCQlyZXR1cm4gbmlsLCB1Zm10LkVycm9yZigiZXhwZWN0ZWQgb2JzZXJ2YXRpb25zIGZvciBwb29sUGF0aCglcykgdG8gZXhpc3QiLCBwb29sUGF0aCkKCX0KCgl0cmVlLCBvayA6PSB2YWx1ZS4oKnBsLk9ic2VydmF0aW9uVHJlZSkKCWlmICFvayB7CgkJcmV0dXJuIG5pbCwgdWZtdC5FcnJvcmYoImZhaWxlZCB0byBjYXN0IG9ic2VydmF0aW9ucyBmb3IgcG9vbFBhdGgoJXMpOiAlVCIsIHBvb2xQYXRoLCB2YWx1ZSkKCX0KCglyZXR1cm4gdHJlZSwgbmlsCn0KCmZ1bmMgKGkgKnBvb2xWMSkgbXVzdEdldE9ic2VydmF0aW9ucyhwb29sUGF0aCBzdHJpbmcpICpwbC5PYnNlcnZhdGlvblRyZWUgewoJdHJlZSwgZXJyIDo9IGkuZ2V0T2JzZXJ2YXRpb25zKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoZXJyRGF0YU5vdEZvdW5kLCBlcnIuRXJyb3IoKSkpCgl9CglyZXR1cm4gdHJlZQp9CgovLyBzYXZlUG9vbCB1cGRhdGVzIGEgcG9vbCBpbiB0aGUgcG9vbHMgbWFwIGFuZCBwZXJzaXN0cyB0byBzdG9yYWdlLgovLyBUaGlzIGVuc3VyZXMgdGhhdCBtb2RpZmljYXRpb25zIHRvIHBvb2wgb2JqZWN0cyBhcmUgcHJvcGVybHkgc2F2ZWQuCmZ1bmMgKGkgKnBvb2xWMSkgc2F2ZVBvb2woXyBpbnQsIHJsbSByZWFsbSwgcG9vbCAqcGwuUG9vbCkgZXJyb3IgewoJcG9vbHMgOj0gaS5zdG9yZS5HZXRQb29scygpCglwb29scy5TZXQocG9vbC5Qb29sUGF0aCgpLCBwb29sKQoKCXJldHVybiBpLnN0b3JlLlNldFBvb2xzKDAsIHJsbSwgcG9vbHMpCn0KCi8vIHNldEZlZVByb3RvY29sSW50ZXJuYWwgdXBkYXRlcyB0aGUgcHJvdG9jb2wgZmVlIGZvciBhbGwgcG9vbHMgYW5kIGVtaXRzIGFuIGV2ZW50LgpmdW5jIChpICpwb29sVjEpIHNldEZlZVByb3RvY29sSW50ZXJuYWwoXyBpbnQsIHJsbSByZWFsbSwgZmVlUHJvdG9jb2wwLCBmZWVQcm90b2NvbDEgdWludDgpIGVycm9yIHsKCW9sZEZlZSA6PSBpLnN0b3JlLkdldFNsb3QwRmVlUHJvdG9jb2woKQoJbmV3RmVlLCBlcnIgOj0gaS5zZXRGZWVQcm90b2NvbCgwLCBybG0sIGZlZVByb3RvY29sMCwgZmVlUHJvdG9jb2wxKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCWZlZVByb3RvY29sME9sZCA6PSBvbGRGZWUgJSAxNgoJZmVlUHJvdG9jb2wxT2xkIDo9IG9sZEZlZSA+PiA0CgoJcHJldmlvdXNSZWFsbSA6PSBybG0uUHJldmlvdXMoKQoJY2hhaW4uRW1pdCgKCQkiU2V0RmVlUHJvdG9jb2wiLAoJCSJwcmV2QWRkciIsIHByZXZpb3VzUmVhbG0uQWRkcmVzcygpLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2aW91c1JlYWxtLlBrZ1BhdGgoKSwKCQkicHJldkZlZVByb3RvY29sMCIsIHV0aWxzLkZvcm1hdFVpbnQoZmVlUHJvdG9jb2wwT2xkKSwKCQkicHJldkZlZVByb3RvY29sMSIsIHV0aWxzLkZvcm1hdFVpbnQoZmVlUHJvdG9jb2wxT2xkKSwKCQkiZmVlUHJvdG9jb2wwIiwgdXRpbHMuRm9ybWF0VWludChmZWVQcm90b2NvbDApLAoJCSJmZWVQcm90b2NvbDEiLCB1dGlscy5Gb3JtYXRVaW50KGZlZVByb3RvY29sMSksCgkJIm5ld0ZlZSIsIHV0aWxzLkZvcm1hdFVpbnQobmV3RmVlKSwKCSkKCglyZXR1cm4gbmlsCn0KCi8vIHNldEZlZVByb3RvY29sIHVwZGF0ZXMgdGhlIHByb3RvY29sIGZlZSBjb25maWd1cmF0aW9uIGZvciBhbGwgbWFuYWdlZCBwb29scy4KLy8KLy8gVGhpcyBmdW5jdGlvbiBjb21iaW5lcyB0aGUgcHJvdG9jb2wgZmVlIHZhbHVlcyBmb3IgdG9rZW4wIGFuZCB0b2tlbjEgaW50byBhIHNpbmdsZSBgdWludDhgIHZhbHVlLAovLyB3aGVyZToKLy8gICAtIExvd2VyIDQgYml0cyBzdG9yZSBmZWVQcm90b2NvbDAgKGZvciB0b2tlbjApLgovLyAgIC0gVXBwZXIgNCBiaXRzIHN0b3JlIGZlZVByb3RvY29sMSAoZm9yIHRva2VuMSkuCi8vCi8vIFRoZSB1cGRhdGVkIGZlZSBwcm90b2NvbCBpcyBhcHBsaWVkIHVuaWZvcm1seSB0byBhbGwgcG9vbHMgbWFuYWdlZCBieSB0aGUgc3lzdGVtLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gZmVlUHJvdG9jb2wwOiBwcm90b2NvbCBmZWUgZm9yIHRva2VuMCAobXVzdCBiZSAwIG9yIGJldHdlZW4gNCBhbmQgMTAgaW5jbHVzaXZlKS4KLy8gICAtIGZlZVByb3RvY29sMTogcHJvdG9jb2wgZmVlIGZvciB0b2tlbjEgKG11c3QgYmUgMCBvciBiZXR3ZWVuIDQgYW5kIDEwIGluY2x1c2l2ZSkuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBuZXdGZWUgKHVpbnQ4KTogdGhlIGNvbWJpbmVkIGZlZSBwcm90b2NvbCB2YWx1ZS4KLy8KLy8gRXhhbXBsZToKLy8gSWYgZmVlUHJvdG9jb2wwID0gNCBhbmQgZmVlUHJvdG9jb2wxID0gNToKLy8KLy8JbmV3RmVlID0gNCArICg1IDw8IDQpCi8vCS8vIFJlc3VsdHMgaW46IDB4NTQgKDg0IGluIGRlY2ltYWwpCi8vCS8vIEJpbmFyeTogMDEwMSAwMTAwCi8vCS8vICAgICAgICAgXl5eXiBeXl5eCi8vCS8vICAgICAgIGZlZTE9NSAgZmVlMD00Ci8vCi8vIE5vdGVzOgovLyAgIC0gVGhpcyBmdW5jdGlvbiBlbnN1cmVzIHRoYXQgYWxsIHBvb2xzIHVuZGVyIG1hbmFnZW1lbnQgYXJlIHVwZGF0ZWQgdG8gdXNlIHRoZSBzYW1lIGZlZSBwcm90b2NvbC4KLy8gICAtIENhbGxlciByZXN0cmljdGlvbnMgKGUuZy4sIGFkbWluIG9yIGdvdmVybmFuY2UpIGFyZSBub3QgZW5mb3JjZWQgaW4gdGhpcyBmdW5jdGlvbi4KLy8gICAtIEVuc3VyZSB0aGUgc3lzdGVtIGlzIG5vdCBoYWx0ZWQgYmVmb3JlIHVwZGF0aW5nIGZlZXMuCmZ1bmMgKGkgKnBvb2xWMSkgc2V0RmVlUHJvdG9jb2woXyBpbnQsIHJsbSByZWFsbSwgZmVlUHJvdG9jb2wwLCBmZWVQcm90b2NvbDEgdWludDgpICh1aW50OCwgZXJyb3IpIHsKCWlmIGVyciA6PSB2YWxpZGF0ZUZlZVByb3RvY29sKGZlZVByb3RvY29sMCwgZmVlUHJvdG9jb2wxKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoKCS8vIGNvbWJpbmUgYm90aCBwcm90b2NvbCBmZWUgaW50byBhIHNpbmdsZSBieXRlOgoJLy8gLSBmZWVQcnRvY29sMCBvY2N1cGllcyB0aGUgbG93ZXIgNCBiaXRzCgkvLyAtIGZlZVByb3RvY29sMSBpcyBzaGlmdGVkIHRoZSBsb3dlciA0IHBvc2l0aW9ucyB0byBvY2N1cHkgdGhlIHVwcGVyIDQgYml0cwoJbmV3RmVlIDo9IGZlZVByb3RvY29sMCArIChmZWVQcm90b2NvbDEgPDwgNCkgLy8gKCA8PCA0ICkgPSAoICogMTYgKQoKCXBvb2xzIDo9IGkuc3RvcmUuR2V0UG9vbHMoKQoKCS8vIFVwZGF0ZSBzbG90MCBmb3IgZWFjaCBwb29sCglwb29scy5JdGVyYXRlKCIiLCAiIiwgZnVuYyhwb29sUGF0aCBzdHJpbmcsIHBvb2xJIGFueSkgYm9vbCB7CgkJcG9vbCwgb2sgOj0gcG9vbEkuKCpwbC5Qb29sKQoJCWlmICFvayB7CgkJCXBhbmljKHVmbXQuRXJyb3JmKCJmYWlsZWQgdG8gY2FzdCBwb29sIHRvICpQb29sOiAlVCIsIHBvb2wpKQoJCX0KCgkJc2xvdDAgOj0gcG9vbC5TbG90MCgpCgkJc2xvdDAuU2V0RmVlUHJvdG9jb2wobmV3RmVlKQoKCQlwb29sLlNldFNsb3QwKHNsb3QwKQoJCXJldHVybiBmYWxzZQoJfSkKCgkvLyB1cGRhdGUgc2xvdDAKCWVyciA6PSBpLnN0b3JlLlNldFNsb3QwRmVlUHJvdG9jb2woMCwgcmxtLCBuZXdGZWUpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CgoJcmV0dXJuIG5ld0ZlZSwgbmlsCn0KCi8vIHZhbGlkYXRlRmVlUHJvdG9jb2wgdmFsaWRhdGVzIHRoZSBmZWUgcHJvdG9jb2wgdmFsdWVzIGZvciB0b2tlbjAgYW5kIHRva2VuMS4KLy8KLy8gVGhpcyBmdW5jdGlvbiBjaGVja3Mgd2hldGhlciB0aGUgcHJvdmlkZWQgZmVlIHByb3RvY29sIHZhbHVlcyAoYGZlZVByb3RvY29sMGAgYW5kIGBmZWVQcm90b2NvbDFgKQovLyBhcmUgdmFsaWQgdXNpbmcgdGhlIGBpc1ZhbGlkRmVlUHJvdG9jb2xWYWx1ZWAgZnVuY3Rpb24uIElmIGVpdGhlciB2YWx1ZSBpcyBpbnZhbGlkLCBpdCByZXR1cm5zCi8vIGFuIGVycm9yIGluZGljYXRpbmcgdGhhdCB0aGUgcHJvdG9jb2wgZmVlIHBlcmNlbnRhZ2UgaXMgaW52YWxpZC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGZlZVByb3RvY29sMDogdWludDgsIHRoZSBmZWUgcHJvdG9jb2wgdmFsdWUgZm9yIHRva2VuMC4KLy8gICAtIGZlZVByb3RvY29sMTogdWludDgsIHRoZSBmZWUgcHJvdG9jb2wgdmFsdWUgZm9yIHRva2VuMS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGVycm9yOiBSZXR1cm5zIGBlcnJJbnZhbGlkUHJvdG9jb2xGZWVQY3RgIGlmIGVpdGhlciBgZmVlUHJvdG9jb2wwYCBvciBgZmVlUHJvdG9jb2wxYCBpcyBpbnZhbGlkLgovLyAgICAgUmV0dXJucyBgbmlsYCBpZiBib3RoIHZhbHVlcyBhcmUgdmFsaWQuCmZ1bmMgdmFsaWRhdGVGZWVQcm90b2NvbChmZWVQcm90b2NvbDAsIGZlZVByb3RvY29sMSB1aW50OCkgZXJyb3IgewoJaWYgIWlzVmFsaWRGZWVQcm90b2NvbFZhbHVlKGZlZVByb3RvY29sMCkgfHwgIWlzVmFsaWRGZWVQcm90b2NvbFZhbHVlKGZlZVByb3RvY29sMSkgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyckludmFsaWRQcm90b2NvbEZlZVBjdCkKCX0KCXJldHVybiBuaWwKfQoKLy8gaXNWYWxpZEZlZVByb3RvY29sVmFsdWUgY2hlY2tzIGlmIGEgZmVlIHByb3RvY29sIHZhbHVlIGlzIHdpdGhpbiBhY2NlcHRhYmxlIHJhbmdlLgovLyBWYWxpZCB2YWx1ZXMgYXJlIGVpdGhlciAwIChkaXNhYmxlZCkgb3IgYmV0d2VlbiA0IGFuZCAxMCBpbmNsdXNpdmUuCi8vCi8vIFRoZSB2YWx1ZSBpcyB1c2VkIGFzIGEgZGVub21pbmF0b3I6IHByb3RvY29sRmVlID0gc3dhcEZlZSAvIGZlZVByb3RvY29sCi8vIChlLmcuLCBmZWVQcm90b2NvbD00IG1lYW5zIDEvNCA9IDI1JSBvZiBzd2FwIGZlZXMgZ28gdG8gcHJvdG9jb2wpCmZ1bmMgaXNWYWxpZEZlZVByb3RvY29sVmFsdWUodmFsdWUgdWludDgpIGJvb2wgewoJcmV0dXJuIHZhbHVlID09IDAgfHwgKHZhbHVlID49IDQgJiYgdmFsdWUgPD0gMTApCn0KGr1vCgpvcmFjbGUuZ25vEq5vcGFja2FnZSBwb29sCgppbXBvcnQgKAoJImVycm9ycyIKCSJ0aW1lIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvY29uc3RzL3YxIgoJdTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL3VpbnQyNTYvdjEiCglwbCAiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiCikKCi8vIG1heE9ic2VydmF0aW9uQ2FyZGluYWxpdHkgZGVmaW5lcyB0aGUgbWF4aW11bSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIHRvIHN0b3JlCmNvbnN0IG1heE9ic2VydmF0aW9uQ2FyZGluYWxpdHkgdWludDE2ID0gNjU1MzUKCi8vIG9yYWNsZUNvbnN1bHQgY2FsY3VsYXRlcyB0aGUgdGltZS13ZWlnaHRlZCBhdmVyYWdlIHByaWNlIGJldHdlZW4gdHdvIHBvaW50cyBpbiB0aW1lLgovLyBJdCByZXR1cm5zIHRoZSBhcml0aG1ldGljIG1lYW4gdGljayBhbmQgaGFybW9uaWMgbWVhbiBsaXF1aWRpdHkgb3ZlciB0aGUgdGltZSBwZXJpb2QuCmZ1bmMgb3JhY2xlQ29uc3VsdChwICpwbC5Qb29sLCBvYnNlcnZhdGlvbnMgKnBsLk9ic2VydmF0aW9uVHJlZSwgc2Vjb25kc0FnbyB1aW50MzIpIChpbnQzMiwgKnUyNTYuVWludCwgZXJyb3IpIHsKCWlmIHNlY29uZHNBZ28gPT0gMCB7CgkJcmV0dXJuIDAsIG5pbCwgZXJyb3JzLk5ldygic2Vjb25kc0FnbyBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIikKCX0KCglpZiBvYnNlcnZhdGlvbnMgPT0gbmlsIHsKCQlyZXR1cm4gMCwgbmlsLCBlcnJvcnMuTmV3KCJvYnNlcnZhdGlvbnMgbm90IGluaXRpYWxpemVkIikKCX0KCXNsb3QwIDo9IHAuU2xvdDAoKQoKCS8vIEdldCBvYnNlcnZhdGlvbnMgZm9yIGN1cnJlbnQgdGltZSBhbmQgc2Vjb25kc0FnbwoJc2Vjb25kc0Fnb3MgOj0gW111aW50MzJ7c2Vjb25kc0FnbywgMH0KCWJsb2NrVGltZXN0YW1wIDo9IHRpbWUuTm93KCkuVW5peCgpCgoJdGlja0N1bXVsYXRpdmVzLCBzZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjhzLCBlcnIgOj0gb2JzZXJ2ZSgKCQlvYnNlcnZhdGlvbnMsCgkJYmxvY2tUaW1lc3RhbXAsCgkJc2Vjb25kc0Fnb3MsCgkJc2xvdDAuVGljaygpLAoJCXNsb3QwLk9ic2VydmF0aW9uSW5kZXgoKSwKCQlwLkxpcXVpZGl0eSgpLAoJCXNsb3QwLk9ic2VydmF0aW9uQ2FyZGluYWxpdHkoKSwKCSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBuaWwsIGVycgoJfQoKCXRpY2tDdW11bGF0aXZlc0RlbHRhIDo9IHRpY2tDdW11bGF0aXZlc1sxXSAtIHRpY2tDdW11bGF0aXZlc1swXQoJc2Vjb25kc1BlckxpcXVpZGl0eURlbHRhIDo9IHUyNTYuWmVybygpLlN1YigKCQl1MjU2Lk11c3RGcm9tRGVjaW1hbChzZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjhzWzFdKSwKCQl1MjU2Lk11c3RGcm9tRGVjaW1hbChzZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjhzWzBdKSwKCSkKCglhcml0aG1ldGljTWVhblRpY2sgOj0gaW50MzIodGlja0N1bXVsYXRpdmVzRGVsdGEgLyBpbnQ2NChzZWNvbmRzQWdvKSkKCWlmIHRpY2tDdW11bGF0aXZlc0RlbHRhIDwgMCAmJiAodGlja0N1bXVsYXRpdmVzRGVsdGElaW50NjQoc2Vjb25kc0FnbykgIT0gMCkgewoJCWFyaXRobWV0aWNNZWFuVGljay0tCgl9CgoJaWYgc2Vjb25kc1BlckxpcXVpZGl0eURlbHRhLklzWmVybygpIHsKCQlyZXR1cm4gYXJpdGhtZXRpY01lYW5UaWNrLCB1MjU2Llplcm8oKSwgbmlsCgl9CgoJLy8gQ2FsY3VsYXRlIGhhcm1vbmljIG1lYW4gbGlxdWlkaXR5CglzZWNvbmRzQWdvWDE2MCA6PSB1MjU2Llplcm8oKS5NdWwodTI1Ni5OZXdVaW50KHVpbnQ2NChzZWNvbmRzQWdvKSksIGNvbnN0cy5NYXgxNjAoKSkKCWRlbm9taW5hdG9yIDo9IHUyNTYuWmVybygpLkxzaChzZWNvbmRzUGVyTGlxdWlkaXR5RGVsdGEsIDMyKQoJaGFybW9uaWNNZWFuTGlxdWlkaXR5IDo9IHUyNTYuWmVybygpLkRpdihzZWNvbmRzQWdvWDE2MCwgZGVub21pbmF0b3IpCgoJcmV0dXJuIGFyaXRobWV0aWNNZWFuVGljaywgaGFybW9uaWNNZWFuTGlxdWlkaXR5LCBuaWwKfQoKLy8gc25hcHNob3RDdW11bGF0aXZlc0luc2lkZSByZXR1cm5zIHRoZSBhY2N1bXVsYXRvcnMgdGhhdCBhY2NydWVkIHdoaWxlIHRoZQovLyBjdXJyZW50IHByaWNlIHdhcyBpbnNpZGUgW3RpY2tMb3dlciwgdGlja1VwcGVyKSwgZm9sbG93aW5nIFVuaXN3YXAgVjMncwovLyBzbmFwc2hvdEN1bXVsYXRpdmVzSW5zaWRlIGZsb3cuCmZ1bmMgc25hcHNob3RDdW11bGF0aXZlc0luc2lkZSgKCXAgKnBsLlBvb2wsCglvYnNlcnZhdGlvbnMgKnBsLk9ic2VydmF0aW9uVHJlZSwKCXRpY2tMb3dlciBpbnQzMiwKCXRpY2tVcHBlciBpbnQzMiwKKSAoaW50NjQsICp1MjU2LlVpbnQsIHVpbnQzMiwgZXJyb3IpIHsKCWlmIGVyciA6PSB2YWxpZGF0ZVRpY2tzKHRpY2tMb3dlciwgdGlja1VwcGVyKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIG5pbCwgMCwgZXJyCgl9CgoJbG93ZXIgOj0gZ2V0VGljayhwLCB0aWNrTG93ZXIpCglpZiAhbG93ZXIuSW5pdGlhbGl6ZWQoKSB7CgkJcmV0dXJuIDAsIG5pbCwgMCwgbWFrZUVycm9yV2l0aERldGFpbHMoZXJyRGF0YU5vdEZvdW5kLCAibG93ZXIgdGljayBpcyBub3QgaW5pdGlhbGl6ZWQiKQoJfQoKCXVwcGVyIDo9IGdldFRpY2socCwgdGlja1VwcGVyKQoJaWYgIXVwcGVyLkluaXRpYWxpemVkKCkgewoJCXJldHVybiAwLCBuaWwsIDAsIG1ha2VFcnJvcldpdGhEZXRhaWxzKGVyckRhdGFOb3RGb3VuZCwgInVwcGVyIHRpY2sgaXMgbm90IGluaXRpYWxpemVkIikKCX0KCglsb3dlclNlY29uZHNQZXJMaXF1aWRpdHlPdXRzaWRlWDEyOCA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChsb3dlci5TZWNvbmRzUGVyTGlxdWlkaXR5T3V0c2lkZVgxMjgoKSkKCXVwcGVyU2Vjb25kc1BlckxpcXVpZGl0eU91dHNpZGVYMTI4IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHVwcGVyLlNlY29uZHNQZXJMaXF1aWRpdHlPdXRzaWRlWDEyOCgpKQoJc2xvdDAgOj0gcC5TbG90MCgpCgoJaWYgc2xvdDAuVGljaygpIDwgdGlja0xvd2VyIHsKCQlyZXR1cm4gbG93ZXIuVGlja0N1bXVsYXRpdmVPdXRzaWRlKCkgLSB1cHBlci5UaWNrQ3VtdWxhdGl2ZU91dHNpZGUoKSwKCQkJdTI1Ni5aZXJvKCkuU3ViKGxvd2VyU2Vjb25kc1BlckxpcXVpZGl0eU91dHNpZGVYMTI4LCB1cHBlclNlY29uZHNQZXJMaXF1aWRpdHlPdXRzaWRlWDEyOCksCgkJCWxvd2VyLlNlY29uZHNPdXRzaWRlKCkgLSB1cHBlci5TZWNvbmRzT3V0c2lkZSgpLCBuaWwKCX0KCglpZiBzbG90MC5UaWNrKCkgPCB0aWNrVXBwZXIgewoJCWlmIG9ic2VydmF0aW9ucyA9PSBuaWwgewoJCQlyZXR1cm4gMCwgbmlsLCAwLCBlcnJvcnMuTmV3KCJvYnNlcnZhdGlvbnMgbm90IGluaXRpYWxpemVkIikKCQl9CgoJCWN1cnJlbnRUaW1lIDo9IHRpbWUuTm93KCkuVW5peCgpCgkJdGlja0N1bXVsYXRpdmUsIHNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCwgZXJyIDo9IG9ic2VydmVTaW5nbGUoCgkJCW9ic2VydmF0aW9ucywKCQkJY3VycmVudFRpbWUsCgkJCTAsCgkJCXNsb3QwLlRpY2soKSwKCQkJc2xvdDAuT2JzZXJ2YXRpb25JbmRleCgpLAoJCQlwLkxpcXVpZGl0eSgpLAoJCQlzbG90MC5PYnNlcnZhdGlvbkNhcmRpbmFsaXR5KCksCgkJKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gMCwgbmlsLCAwLCBlcnIKCQl9CgoJCXNlY29uZHNQZXJMaXF1aWRpdHlJbnNpZGVYMTI4IDo9IHUyNTYuWmVybygpLlN1YigKCQkJdTI1Ni5aZXJvKCkuU3ViKAoJCQkJdTI1Ni5NdXN0RnJvbURlY2ltYWwoc2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4KSwKCQkJCWxvd2VyU2Vjb25kc1BlckxpcXVpZGl0eU91dHNpZGVYMTI4LAoJCQkpLAoJCQl1cHBlclNlY29uZHNQZXJMaXF1aWRpdHlPdXRzaWRlWDEyOCwKCQkpCgoJCXJldHVybiB0aWNrQ3VtdWxhdGl2ZSAtIGxvd2VyLlRpY2tDdW11bGF0aXZlT3V0c2lkZSgpIC0gdXBwZXIuVGlja0N1bXVsYXRpdmVPdXRzaWRlKCksCgkJCXNlY29uZHNQZXJMaXF1aWRpdHlJbnNpZGVYMTI4LAoJCQl1aW50MzIoY3VycmVudFRpbWUpIC0gbG93ZXIuU2Vjb25kc091dHNpZGUoKSAtIHVwcGVyLlNlY29uZHNPdXRzaWRlKCksIG5pbAoJfQoKCXJldHVybiB1cHBlci5UaWNrQ3VtdWxhdGl2ZU91dHNpZGUoKSAtIGxvd2VyLlRpY2tDdW11bGF0aXZlT3V0c2lkZSgpLAoJCXUyNTYuWmVybygpLlN1Yih1cHBlclNlY29uZHNQZXJMaXF1aWRpdHlPdXRzaWRlWDEyOCwgbG93ZXJTZWNvbmRzUGVyTGlxdWlkaXR5T3V0c2lkZVgxMjgpLAoJCXVwcGVyLlNlY29uZHNPdXRzaWRlKCkgLSBsb3dlci5TZWNvbmRzT3V0c2lkZSgpLCBuaWwKfQoKZnVuYyB0cmFuc2Zvcm0obGFzdCBwbC5PYnNlcnZhdGlvbiwgYmxvY2tUaW1lc3RhbXAgaW50NjQsIHRpY2sgaW50MzIsIGxpcXVpZGl0eSAqdTI1Ni5VaW50KSAocGwuT2JzZXJ2YXRpb24sIGVycm9yKSB7Cgl0aW1lRGVsdGEgOj0gYmxvY2tUaW1lc3RhbXAgLSBsYXN0LkJsb2NrVGltZXN0YW1wKCkKCWlmIHRpbWVEZWx0YSA8IDAgewoJCXJldHVybiBwbC5EZWZhdWx0T2JzZXJ2YXRpb24oKSwgZXJyb3JzLk5ldygidGltZSBkZWx0YSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIikKCX0KCgkvLyBjYWxjdWxhdGUgY3VtdWxhdGl2ZSB2YWx1ZXMKCXRpY2tDdW11bGF0aXZlIDo9IGxhc3QuVGlja0N1bXVsYXRpdmUoKSArIGludDY0KHRpY2spKnRpbWVEZWx0YQoKCS8vIGNhbGN1bGF0ZSBzZWNvbmRzIHBlciBsaXF1aWRpdHkKCWxpcXVpZGl0eUZvckNhbGMgOj0gbGlxdWlkaXR5CglpZiBsaXF1aWRpdHkuSXNaZXJvKCkgewoJCWxpcXVpZGl0eUZvckNhbGMgPSB1MjU2Lk9uZSgpCgl9CgoJLy8gc2Vjb25kc1BlckxpcXVpZGl0eSArPSB0aW1lRGVsdGEgKiAyXjEyOCAvIG1heCgxLCBsaXF1aWRpdHkpCglzZWNvbmRzUGVyTGlxdWlkaXR5RGVsdGEgOj0gdTI1Ni5NdWxEaXYoCgkJdTI1Ni5OZXdVaW50RnJvbUludDY0KHRpbWVEZWx0YSksCgkJY29uc3RzLlExMjgoKSwKCQlsaXF1aWRpdHlGb3JDYWxjLAoJKQoKCXByZXZTZWNQZXJMaXEgOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwobGFzdC5TZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjgoKSkKCXNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCA6PSB1MjU2Llplcm8oKS5BZGQoCgkJcHJldlNlY1BlckxpcSwKCQlzZWNvbmRzUGVyTGlxdWlkaXR5RGVsdGEsCgkpCgoJb2JzZXJ2YXRpb24gOj0gcGwuTWFrZU9ic2VydmF0aW9uKAoJCWJsb2NrVGltZXN0YW1wLAoJCXRpY2tDdW11bGF0aXZlLAoJCXNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOC5Ub1N0cmluZygpLAoJCXRydWUsCgkpCglyZXR1cm4gb2JzZXJ2YXRpb24sIG5pbAp9CgpmdW5jIGdyb3cob2JzZXJ2YXRpb25zICpwbC5PYnNlcnZhdGlvblRyZWUsIGN1cnJlbnQsIG5leHQgdWludDE2KSAodWludDE2LCBlcnJvcikgewoJaWYgb2JzZXJ2YXRpb25zID09IG5pbCB7CgkJcmV0dXJuIGN1cnJlbnQsIGVycm9ycy5OZXcoIm9ic2VydmF0aW9ucyBub3QgaW5pdGlhbGl6ZWQiKQoJfQoKCWlmIGN1cnJlbnQgPD0gMCB7CgkJcmV0dXJuIGN1cnJlbnQsIGVycm9ycy5OZXcoImN1cnJlbnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gMCIpCgl9CgoJaWYgbmV4dCA8PSBjdXJyZW50IHsKCQlyZXR1cm4gY3VycmVudCwgbmlsCgl9CgoJaWYgbmV4dCA+IG1heE9ic2VydmF0aW9uQ2FyZGluYWxpdHkgewoJCXJldHVybiBjdXJyZW50LCBlcnJvcnMuTmV3KCJuZXh0IGV4Y2VlZHMgbWF4aW11bSIpCgl9CgoJLy8gUmVzZXJ2ZSBldmVyeSBuZXcgc2xvdCBub3cgc28gdGhlIGNhbGxlciB0aGF0IGluY3JlYXNlcyBjYXBhY2l0eSBwYXlzIGZvcgoJLy8gaXRzIHN0b3JhZ2UuIFRoaXMgbWF0Y2hlcyBVbmlzd2FwJ3MgT3JhY2xlLmdyb3cgYmVoYXZpb3IgYW5kIHByZXZlbnRzIGFuCgkvLyB1bnJlc3RyaWN0ZWQgcmVzZXJ2YXRpb24gZnJvbSBzaGlmdGluZyBhbGxvY2F0aW9uIGNvc3QgdG8gbGF0ZXIgc3dhcHBlcnMuCglmb3IgaSA6PSBjdXJyZW50OyBpIDwgbmV4dDsgaSsrIHsKCQlvYnNlcnZhdGlvbnMuU2V0KGksIHBsLk1ha2VPYnNlcnZhdGlvbigxLCAwLCAiMCIsIGZhbHNlKSkKCX0KCglyZXR1cm4gbmV4dCwgbmlsCn0KCmZ1bmMgd3JpdGVPYnNlcnZhdGlvbigKCW9ic2VydmF0aW9ucyAqcGwuT2JzZXJ2YXRpb25UcmVlLAoJaW5kZXggdWludDE2LAoJYmxvY2tUaW1lc3RhbXAgaW50NjQsCgl0aWNrIGludDMyLAoJbGlxdWlkaXR5ICp1MjU2LlVpbnQsCgljYXJkaW5hbGl0eSB1aW50MTYsCgljYXJkaW5hbGl0eU5leHQgdWludDE2LAopIChpbmRleFVwZGF0ZWQgdWludDE2LCBjYXJkaW5hbGl0eVVwZGF0ZWQgdWludDE2LCBlcnIgZXJyb3IpIHsKCWlmIG9ic2VydmF0aW9ucyA9PSBuaWwgewoJCXJldHVybiAwLCAwLCBlcnJvcnMuTmV3KCJvYnNlcnZhdGlvbnMgbm90IGluaXRpYWxpemVkIikKCX0KCWlmIGNhcmRpbmFsaXR5ID09IDAgewoJCXJldHVybiAwLCAwLCBlcnJvcnMuTmV3KCJvYnNlcnZhdGlvbiBjYXJkaW5hbGl0eSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIikKCX0KCglsYXN0LCBlcnIgOj0gb2JzZXJ2YXRpb25BdChvYnNlcnZhdGlvbnMsIGluZGV4KQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIDAsIGVycgoJfQoKCWlmIGxhc3QuQmxvY2tUaW1lc3RhbXAoKSA9PSBibG9ja1RpbWVzdGFtcCB7CgkJcmV0dXJuIGluZGV4LCBjYXJkaW5hbGl0eSwgbmlsCgl9CgoJLy8gQ2hlY2sgaWYgd2UgbmVlZCB0byBncm93IHRoZSBjYXJkaW5hbGl0eQoJaWYgY2FyZGluYWxpdHlOZXh0ID4gY2FyZGluYWxpdHkgJiYgaW5kZXggPT0gY2FyZGluYWxpdHktMSB7CgkJY2FyZGluYWxpdHlVcGRhdGVkID0gY2FyZGluYWxpdHlOZXh0Cgl9IGVsc2UgewoJCWNhcmRpbmFsaXR5VXBkYXRlZCA9IGNhcmRpbmFsaXR5Cgl9CgoJaW5kZXhVcGRhdGVkID0gKGluZGV4ICsgMSkgJSBjYXJkaW5hbGl0eVVwZGF0ZWQKCW9ic2VydmF0aW9uLCBlcnIgOj0gdHJhbnNmb3JtKGxhc3QsIGJsb2NrVGltZXN0YW1wLCB0aWNrLCBsaXF1aWRpdHkpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgMCwgZXJyCgl9CgoJb2JzZXJ2YXRpb25zLlNldChpbmRleFVwZGF0ZWQsIG9ic2VydmF0aW9uKQoJcmV0dXJuIGluZGV4VXBkYXRlZCwgY2FyZGluYWxpdHlVcGRhdGVkLCBuaWwKfQoKLy8gb2JzZXJ2YXRpb25BdCByZXR1cm5zIHRoZSBvYnNlcnZhdGlvbiBhdCBhIHNwZWNpZmljIGluZGV4Ci8vIFJldHVybnMgZXJyb3IgaWYgdGhlIG9ic2VydmF0aW9uIGRvZXNuJ3QgZXhpc3QKZnVuYyBvYnNlcnZhdGlvbkF0KG9ic2VydmF0aW9ucyAqcGwuT2JzZXJ2YXRpb25UcmVlLCBpbmRleCB1aW50MTYpIChwbC5PYnNlcnZhdGlvbiwgZXJyb3IpIHsKCWlmIG9ic2VydmF0aW9ucyA9PSBuaWwgewoJCXJldHVybiBwbC5EZWZhdWx0T2JzZXJ2YXRpb24oKSwgZXJyb3JzLk5ldygib2JzZXJ2YXRpb25zIG5vdCBpbml0aWFsaXplZCIpCgl9CglvYnMsIG9rIDo9IG9ic2VydmF0aW9ucy5HZXQoaW5kZXgpCglpZiAhb2sgewoJCXJldHVybiBwbC5EZWZhdWx0T2JzZXJ2YXRpb24oKSwgZXJyb3JzLk5ldyhlcnJOb3RJbml0aWFsaXplZE9ic2VydmF0aW9uKQoJfQoKCXJldHVybiBvYnMsIG5pbAp9CgovLyBvYnNlcnZlU2luZ2xlIHJldHVybnMgdGhlIGRhdGEgZm9yIGEgc2luZ2xlIG9ic2VydmF0aW9uIGF0IGEgc3BlY2lmaWMgdGltZSBhZ28KZnVuYyBvYnNlcnZlU2luZ2xlKAoJb2JzZXJ2YXRpb25zICpwbC5PYnNlcnZhdGlvblRyZWUsCgl0aW1lIGludDY0LAoJc2Vjb25kc0FnbyB1aW50MzIsCgl0aWNrIGludDMyLAoJaW5kZXggdWludDE2LAoJbGlxdWlkaXR5ICp1MjU2LlVpbnQsCgljYXJkaW5hbGl0eSB1aW50MTYsCikgKGludDY0LCBzdHJpbmcsIGVycm9yKSB7CglpZiBzZWNvbmRzQWdvID09IDAgewoJCS8vIGlmIHNlY29uZHNBZ28gaXMgMCwgcmV0dXJuIGN1cnJlbnQgdmFsdWVzCgkJbGFzdCwgZXJyIDo9IG9ic2VydmF0aW9uQXQob2JzZXJ2YXRpb25zLCBpbmRleCkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIDAsICIiLCBlcnIKCQl9CgoJCWlmIGxhc3QuQmxvY2tUaW1lc3RhbXAoKSAhPSB0aW1lIHsKCQkJLy8gbmVlZCB0byBjcmVhdGUgdmlydHVhbCBvYnNlcnZhdGlvbiBmb3IgY3VycmVudCB0aW1lCgkJCXRyYW5zZm9ybWVkLCBlcnIgOj0gdHJhbnNmb3JtKGxhc3QsIHRpbWUsIHRpY2ssIGxpcXVpZGl0eSkKCQkJaWYgZXJyICE9IG5pbCB7CgkJCQlyZXR1cm4gMCwgIiIsIGVycgoJCQl9CgoJCQlyZXR1cm4gdHJhbnNmb3JtZWQuVGlja0N1bXVsYXRpdmUoKSwgdHJhbnNmb3JtZWQuU2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4KCksIG5pbAoJCX0KCgkJcmV0dXJuIGxhc3QuVGlja0N1bXVsYXRpdmUoKSwgbGFzdC5TZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjgoKSwgbmlsCgl9CgoJLy8gQSBsb29rYmFjayBsb25nZXIgdGhhbiB0aGUgY2hhaW4ncyBvd24gYWdlIHdvdWxkIHBsYWNlIHRoZSB0YXJnZXQgYmVmb3JlIHVuaXggZXBvY2guCglpZiBpbnQ2NChzZWNvbmRzQWdvKSA+IHRpbWUgewoJCXJldHVybiAwLCAiIiwgZXJyb3JzLk5ldyhlcnJPYnNlcnZhdGlvbkJlZm9yZUVwb2NoKQoJfQoKCXRhcmdldCA6PSB0aW1lIC0gaW50NjQoc2Vjb25kc0FnbykKCgkvLyBmaW5kIHRoZSBvYnNlcnZhdGlvbnMgYmVmb3JlIGFuZCBhZnRlciB0aGUgdGFyZ2V0CgliZWZvcmVPckF0LCBhdE9yQWZ0ZXIsIGVyciA6PSBnZXRTdXJyb3VuZGluZ09ic2VydmF0aW9ucygKCQlvYnNlcnZhdGlvbnMsCgkJdGFyZ2V0LAoJCXRpY2ssCgkJaW5kZXgsCgkJbGlxdWlkaXR5LAoJCWNhcmRpbmFsaXR5LAoJKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsICIiLCBlcnIKCX0KCglpZiB0YXJnZXQgPT0gYmVmb3JlT3JBdC5CbG9ja1RpbWVzdGFtcCgpIHsKCQlyZXR1cm4gYmVmb3JlT3JBdC5UaWNrQ3VtdWxhdGl2ZSgpLCBiZWZvcmVPckF0LlNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCgpLCBuaWwKCX0KCglpZiB0YXJnZXQgPT0gYXRPckFmdGVyLkJsb2NrVGltZXN0YW1wKCkgewoJCXJldHVybiBhdE9yQWZ0ZXIuVGlja0N1bXVsYXRpdmUoKSwgYXRPckFmdGVyLlNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCgpLCBuaWwKCX0KCgkvLyBpbnRlcnBvbGF0ZSBiZXR3ZWVuIHRoZSB0d28gb2JzZXJ2YXRpb25zCglvYnNlcnZhdGlvblRpbWVEZWx0YSA6PSBhdE9yQWZ0ZXIuQmxvY2tUaW1lc3RhbXAoKSAtIGJlZm9yZU9yQXQuQmxvY2tUaW1lc3RhbXAoKQoJdGFyZ2V0RGVsdGEgOj0gdGFyZ2V0IC0gYmVmb3JlT3JBdC5CbG9ja1RpbWVzdGFtcCgpCgoJLy8gdGlja0N1bXVsYXRpdmUgKz0gKHRpY2tDdW11bGF0aXZlQWZ0ZXIgLSB0aWNrQ3VtdWxhdGl2ZUJlZm9yZSkgLyBvYnNlcnZhdGlvblRpbWVEZWx0YSAqIHRhcmdldERlbHRhCgl0aWNrQ3VtdWxhdGl2ZSA6PSBiZWZvcmVPckF0LlRpY2tDdW11bGF0aXZlKCkgKwoJCSgoYXRPckFmdGVyLlRpY2tDdW11bGF0aXZlKCktYmVmb3JlT3JBdC5UaWNrQ3VtdWxhdGl2ZSgpKS9vYnNlcnZhdGlvblRpbWVEZWx0YSkqdGFyZ2V0RGVsdGEKCgliZWZvcmVTZWNQZXJMaXEgOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwoYmVmb3JlT3JBdC5TZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjgoKSkKCWFmdGVyU2VjUGVyTGlxIDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKGF0T3JBZnRlci5TZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjgoKSkKCgkvLyBmb3Igc2Vjb25kc1BlckxpcXVpZGl0eSwgbmVlZCB0byBpbnRlcnBvbGF0ZSBjYXJlZnVsbHkKCXNlY29uZHNQZXJMaXF1aWRpdHlEZWx0YSA6PSB1MjU2Llplcm8oKS5TdWIoYWZ0ZXJTZWNQZXJMaXEsIGJlZm9yZVNlY1BlckxpcSkKCglzZWNvbmRzUGVyTGlxdWlkaXR5IDo9IHUyNTYuWmVybygpLkFkZCgKCQliZWZvcmVTZWNQZXJMaXEsCgkJdTI1Ni5NdWxEaXYoCgkJCXNlY29uZHNQZXJMaXF1aWRpdHlEZWx0YSwKCQkJdTI1Ni5OZXdVaW50RnJvbUludDY0KHRhcmdldERlbHRhKSwKCQkJdTI1Ni5OZXdVaW50RnJvbUludDY0KG9ic2VydmF0aW9uVGltZURlbHRhKSwKCQkpLAoJKQoKCXJldHVybiB0aWNrQ3VtdWxhdGl2ZSwgc2Vjb25kc1BlckxpcXVpZGl0eS5Ub1N0cmluZygpLCBuaWwKfQoKLy8gZ2V0U3Vycm91bmRpbmdPYnNlcnZhdGlvbnMgZmluZHMgdGhlIG9ic2VydmF0aW9ucyBpbW1lZGlhdGVseSBiZWZvcmUgYW5kIGFmdGVyIHRoZSB0YXJnZXQgdGltZXN0YW1wLgovLyBJdCB1c2VzIGJpbmFyeSBzZWFyY2ggb3ZlciB0aGUgbG9naWNhbCB0aW1lLW9yZGVyZWQgdmlldyBvZiB0aGUgY2lyY3VsYXIgYnVmZmVyLgovLyBMb2dpY2FsIG9yZGVyIHN0YXJ0cyBhdCAoaW5kZXgrMSkgJSBjYXJkaW5hbGl0eSAob2xkZXN0KSBhbmQgZW5kcyBhdCBpbmRleCAobGF0ZXN0KS4KZnVuYyBnZXRTdXJyb3VuZGluZ09ic2VydmF0aW9ucygKCW9ic2VydmF0aW9ucyAqcGwuT2JzZXJ2YXRpb25UcmVlLAoJdGFyZ2V0IGludDY0LAoJdGljayBpbnQzMiwKCWluZGV4IHVpbnQxNiwKCWxpcXVpZGl0eSAqdTI1Ni5VaW50LAoJY2FyZGluYWxpdHkgdWludDE2LAopIChwbC5PYnNlcnZhdGlvbiwgcGwuT2JzZXJ2YXRpb24sIGVycm9yKSB7CgkvLyBPcHRpbWlzdGljYWxseSBzZXQgYmVmb3JlIHRvIHRoZSBuZXdlc3Qgb2JzZXJ2YXRpb24KCWJlZm9yZU9yQXQsIGVyciA6PSBvYnNlcnZhdGlvbkF0KG9ic2VydmF0aW9ucywgaW5kZXgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gcGwuRGVmYXVsdE9ic2VydmF0aW9uKCksIHBsLkRlZmF1bHRPYnNlcnZhdGlvbigpLCBlcnIKCX0KCgkvLyBUaW1lc3RhbXBzIGFyZSBpbnQ2NCwgc28gbmF0dXJhbCBvcmRlcmluZyBhcHBsaWVzLiBVbmlzd2FwIFYzIG5lZWRzIGEKCS8vIHdyYXBhcm91bmQtYXdhcmUgY29tcGFyaXNvbiBoZXJlIG9ubHkgYmVjYXVzZSBpdCBzdG9yZXMgdGhlbSBhcyB1aW50MzIuCgkvLyBJZiB0aGUgdGFyZ2V0IGlzIGNocm9ub2xvZ2ljYWxseSBhdCBvciBhZnRlciB0aGUgbmV3ZXN0IG9ic2VydmF0aW9uLCB3ZSBjYW4gZWFybHkgcmV0dXJuCglpZiBiZWZvcmVPckF0LkJsb2NrVGltZXN0YW1wKCkgPD0gdGFyZ2V0IHsKCQlpZiBiZWZvcmVPckF0LkJsb2NrVGltZXN0YW1wKCkgPT0gdGFyZ2V0IHsKCQkJLy8gSWYgbmV3ZXN0IG9ic2VydmF0aW9uIGVxdWFscyB0YXJnZXQsIHdlJ3JlIGluIHRoZSBzYW1lIGJsb2NrLCBzbyB3ZSBjYW4gaWdub3JlIGF0T3JBZnRlcgoJCQlyZXR1cm4gYmVmb3JlT3JBdCwgcGwuRGVmYXVsdE9ic2VydmF0aW9uKCksIG5pbAoJCX0KCQkvLyBPdGhlcndpc2UsIHdlIG5lZWQgdG8gdHJhbnNmb3JtCgkJYXRPckFmdGVyLCBlcnIgOj0gdHJhbnNmb3JtKGJlZm9yZU9yQXQsIHRhcmdldCwgdGljaywgbGlxdWlkaXR5KQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gcGwuRGVmYXVsdE9ic2VydmF0aW9uKCksIHBsLkRlZmF1bHRPYnNlcnZhdGlvbigpLCBlcnIKCQl9CgkJcmV0dXJuIGJlZm9yZU9yQXQsIGF0T3JBZnRlciwgbmlsCgl9CgoJLy8gTm93LCBzZXQgYmVmb3JlIHRvIHRoZSBvbGRlc3Qgb2JzZXJ2YXRpb24KCXN0YXJ0IDo9IChpbmRleCArIDEpICUgY2FyZGluYWxpdHkKCWJlZm9yZU9yQXQsIGVyciA9IG9ic2VydmF0aW9uQXQob2JzZXJ2YXRpb25zLCBzdGFydCkKCWlmIGVyciAhPSBuaWwgfHwgIWJlZm9yZU9yQXQuSW5pdGlhbGl6ZWQoKSB7CgkJYmVmb3JlT3JBdCwgZXJyID0gb2JzZXJ2YXRpb25BdChvYnNlcnZhdGlvbnMsIDApCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBwbC5EZWZhdWx0T2JzZXJ2YXRpb24oKSwgcGwuRGVmYXVsdE9ic2VydmF0aW9uKCksIGVycgoJCX0KCX0KCgkvLyBFbnN1cmUgdGhhdCB0aGUgdGFyZ2V0IGlzIGNocm9ub2xvZ2ljYWxseSBhdCBvciBhZnRlciB0aGUgb2xkZXN0IG9ic2VydmF0aW9uCglpZiBiZWZvcmVPckF0LkJsb2NrVGltZXN0YW1wKCkgPiB0YXJnZXQgewoJCXJldHVybiBwbC5EZWZhdWx0T2JzZXJ2YXRpb24oKSwgcGwuRGVmYXVsdE9ic2VydmF0aW9uKCksIGVycm9ycy5OZXcoZXJyT2JzZXJ2YXRpb25Ub29PbGQpCgl9CgoJLy8gSWYgd2UndmUgcmVhY2hlZCB0aGlzIHBvaW50LCB3ZSBoYXZlIHRvIGJpbmFyeSBzZWFyY2gKCXJldHVybiBiaW5hcnlTZWFyY2gob2JzZXJ2YXRpb25zLCB0YXJnZXQsIGluZGV4LCBjYXJkaW5hbGl0eSkKfQoKZnVuYyBiaW5hcnlTZWFyY2goCglvYnNlcnZhdGlvbnMgKnBsLk9ic2VydmF0aW9uVHJlZSwKCXRhcmdldCBpbnQ2NCwKCWluZGV4IHVpbnQxNiwKCWNhcmRpbmFsaXR5IHVpbnQxNiwKKSAocGwuT2JzZXJ2YXRpb24sIHBsLk9ic2VydmF0aW9uLCBlcnJvcikgewoJbCA6PSB1aW50NjQoKGluZGV4ICsgMSkgJSBjYXJkaW5hbGl0eSkgLy8gb2xkZXN0IG9ic2VydmF0aW9uCglyIDo9IGwgKyB1aW50NjQoY2FyZGluYWxpdHkpIC0gMSAgICAgICAvLyBuZXdlc3Qgb2JzZXJ2YXRpb24KCXZhciBpIHVpbnQ2NAoJdmFyIGJlZm9yZU9yQXQsIGF0T3JBZnRlciBwbC5PYnNlcnZhdGlvbgoJdmFyIGVyciBlcnJvcgoKCWZvciB7CgkJaSA9IChsICsgcikgLyAyCgoJCWJlZm9yZUluZGV4IDo9IHVpbnQxNihpICUgdWludDY0KGNhcmRpbmFsaXR5KSkKCQliZWZvcmVPckF0LCBlcnIgPSBvYnNlcnZhdGlvbkF0KG9ic2VydmF0aW9ucywgYmVmb3JlSW5kZXgpCgkJaWYgZXJyICE9IG5pbCB8fCAhYmVmb3JlT3JBdC5Jbml0aWFsaXplZCgpIHsKCQkJLy8gd2UndmUgbGFuZGVkIG9uIGFuIHVuaW5pdGlhbGl6ZWQgdGljaywga2VlcCBzZWFyY2hpbmcgaGlnaGVyIChtb3JlIHJlY2VudGx5KQoJCQlsID0gaSArIDEKCQkJY29udGludWUKCQl9CgoJCWFmdGVySW5kZXggOj0gdWludDE2KChpICsgMSkgJSB1aW50NjQoY2FyZGluYWxpdHkpKQoJCWF0T3JBZnRlciwgZXJyID0gb2JzZXJ2YXRpb25BdChvYnNlcnZhdGlvbnMsIGFmdGVySW5kZXgpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBwbC5EZWZhdWx0T2JzZXJ2YXRpb24oKSwgcGwuRGVmYXVsdE9ic2VydmF0aW9uKCksIGVycgoJCX0KCgkJdGFyZ2V0QXRPckFmdGVyIDo9IGJlZm9yZU9yQXQuQmxvY2tUaW1lc3RhbXAoKSA8PSB0YXJnZXQKCgkJLy8gY2hlY2sgaWYgd2UndmUgZm91bmQgdGhlIGFuc3dlciEKCQlpZiB0YXJnZXRBdE9yQWZ0ZXIgJiYgdGFyZ2V0IDw9IGF0T3JBZnRlci5CbG9ja1RpbWVzdGFtcCgpIHsKCQkJYnJlYWsKCQl9CgoJCWlmICF0YXJnZXRBdE9yQWZ0ZXIgewoJCQlyID0gaSAtIDEKCQl9IGVsc2UgewoJCQlsID0gaSArIDEKCQl9Cgl9CgoJcmV0dXJuIGJlZm9yZU9yQXQsIGF0T3JBZnRlciwgbmlsCn0KCi8vIG9ic2VydmUgcmV0dXJucyB0aGUgY3VtdWxhdGl2ZSB0aWNrIGFuZCBsaXF1aWRpdHkgYXMgb2YgZWFjaCB0aW1lc3RhbXAgc2Vjb25kc0FnbyBmcm9tIHRoZSBjdXJyZW50IHRpbWUuCmZ1bmMgb2JzZXJ2ZSgKCW9ic2VydmF0aW9ucyAqcGwuT2JzZXJ2YXRpb25UcmVlLAoJdGltZSBpbnQ2NCwKCXNlY29uZHNBZ29zIFtddWludDMyLAoJdGljayBpbnQzMiwKCWluZGV4IHVpbnQxNiwKCWxpcXVpZGl0eSAqdTI1Ni5VaW50LAoJY2FyZGluYWxpdHkgdWludDE2LAopIChbXWludDY0LCBbXXN0cmluZywgZXJyb3IpIHsKCWlmIGNhcmRpbmFsaXR5IDw9IDAgewoJCXJldHVybiBuaWwsIG5pbCwgZXJyb3JzLk5ldygib2JzZXJ2YXRpb24gY2FyZGluYWxpdHkgbXVzdCBiZSBncmVhdGVyIHRoYW4gMCIpCgl9CgoJaGlzdG9yeUNvdW50IDo9IGxlbihzZWNvbmRzQWdvcykKCXRpY2tDdW11bGF0aXZlcyA6PSBtYWtlKFtdaW50NjQsIGhpc3RvcnlDb3VudCkKCXNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOHMgOj0gbWFrZShbXXN0cmluZywgaGlzdG9yeUNvdW50KQoKCWZvciBpLCBzZWNvbmRzQWdvIDo9IHJhbmdlIHNlY29uZHNBZ29zIHsKCQl0aWNrQ3VtdWxhdGl2ZSwgc2Vjb25kc1BlckxpcXVpZGl0eSwgZXJyIDo9IG9ic2VydmVTaW5nbGUoCgkJCW9ic2VydmF0aW9ucywKCQkJdGltZSwKCQkJc2Vjb25kc0FnbywKCQkJdGljaywKCQkJaW5kZXgsCgkJCWxpcXVpZGl0eSwKCQkJY2FyZGluYWxpdHksCgkJKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gbmlsLCBuaWwsIGVycgoJCX0KCgkJdGlja0N1bXVsYXRpdmVzW2ldID0gdGlja0N1bXVsYXRpdmUKCQlzZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjhzW2ldID0gc2Vjb25kc1BlckxpcXVpZGl0eQoJfQoKCXJldHVybiB0aWNrQ3VtdWxhdGl2ZXMsIHNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOHMsIG5pbAp9Chr5mQEKCHBvb2wuZ25vEuuZAXBhY2thZ2UgcG9vbAoKaW1wb3J0ICgKCSJjaGFpbiIKCSJlcnJvcnMiCgoJImduby5sYW5kL3IvZ25vc3dhcC9jb21tb24iCgkiZ25vLmxhbmQvci9nbm9zd2FwL2hhbHQvdjEiCglwbCAiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiCgoJImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJaTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL2ludDI1Ni92MSIKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJImduby5sYW5kL3AvZ25vc3dhcC91dGlscy92MSIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCglwcmFiYyAiZ25vLmxhbmQvcC9nbm9zd2FwL3JiYWMvdjEiCglfICJnbm8ubGFuZC9yL2dub3N3YXAvcmJhYy92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKKQoKLy8gTWludCBhZGRzIGxpcXVpZGl0eSB0byBhIHBvb2wgcG9zaXRpb24uCi8vCi8vIEluY3JlYXNlcyBsaXF1aWRpdHkgZm9yIGEgcG9zaXRpb24gd2l0aGluIHNwZWNpZmllZCB0aWNrIHJhbmdlLgovLyBDYWxjdWxhdGVzIHJlcXVpcmVkIHRva2VuIGFtb3VudHMgYmFzZWQgb24gY3VycmVudCBwb29sIHByaWNlLgovLyBVcGRhdGVzIHRpY2sgc3RhdGUgYW5kIHRyYW5zZmVycyB0b2tlbnMgYXRvbWljYWxseS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgcG9vbCBwcm94eS4KLy8gICAtIHRva2VuMFBhdGg6IFJlZ2lzdGVyZWQgdG9rZW4gY29udHJhY3QgcGF0aCBmb3IgdG9rZW4wLgovLyAgIC0gdG9rZW4xUGF0aDogUmVnaXN0ZXJlZCB0b2tlbiBjb250cmFjdCBwYXRoIGZvciB0b2tlbjEuCi8vICAgLSBmZWU6IEZlZSB0aWVyOyBzdXBwb3J0ZWQgdGllcnMgYXJlIDEwMCwgNTAwLCAzMDAwLCBhbmQgMTAwMDAgKDAuMDElLCAwLjA1JSwgMC4zJSwgYW5kIDElKS4KLy8gICAtIHRpY2tMb3dlcjogSW5jbHVzaXZlIGxvd2VyIHByaWNlLXJhbmdlIHRpY2s7IG11c3QgYmUgYWxpZ25lZCB0byB0aGUgcG9vbCB0aWNrIHNwYWNpbmcuCi8vICAgLSB0aWNrVXBwZXI6IEV4Y2x1c2l2ZSB1cHBlciBwcmljZS1yYW5nZSB0aWNrOyBtdXN0IGJlIGFsaWduZWQgdG8gdGhlIHBvb2wgdGljayBzcGFjaW5nLgovLyAgIC0gbGlxdWlkaXR5QW1vdW50OiBQb3NpdGl2ZSBkZWNpbWFsIHN0cmluZyBzcGVjaWZ5aW5nIGxpcXVpZGl0eSB0byBhZGQ7IGl0IGlzIGNvbnZlcnRlZCB0byB1aW50MjU2IGFuZCB0aGVuIGludDEyOC4KLy8gICAtIHBvc2l0aW9uQ2FsbGVyOiBOb256ZXJvIHBvc2l0aW9uLWNvbnRyYWN0IGFkZHJlc3MgdGhhdCBzdXBwbGllcyB0b2tlbnMgZm9yIHRoaXMgbWludC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGFtb3VudDA6IFRva2VuMCBhbW91bnQgY29uc3VtZWQsIHJldHVybmVkIGFzIGEgZGVjaW1hbCBzdHJpbmcuCi8vICAgLSBhbW91bnQxOiBUb2tlbjEgYW1vdW50IGNvbnN1bWVkLCByZXR1cm5lZCBhcyBhIGRlY2ltYWwgc3RyaW5nLgovLwovLyBSZXF1aXJlbWVudHM6Ci8vICAgLSBQb29sIG11c3QgZXhpc3QgZm9yIHRva2VuIHBhaXIgYW5kIGZlZQovLyAgIC0gTGlxdWlkaXR5IGFtb3VudCBtdXN0IGJlIHBvc2l0aXZlCi8vICAgLSBUaWNrcyBtdXN0IGJlIHZhbGlkIGFuZCBhbGlnbmVkIHRvIHNwYWNpbmcKLy8KLy8gT25seSBjYWxsYWJsZSBieSBwb3NpdGlvbiBjb250cmFjdC4KZnVuYyAoaSAqcG9vbFYxKSBNaW50KAoJXyBpbnQsCglybG0gcmVhbG0sCgl0b2tlbjBQYXRoIHN0cmluZywKCXRva2VuMVBhdGggc3RyaW5nLAoJZmVlIHVpbnQzMiwKCXRpY2tMb3dlciBpbnQzMiwKCXRpY2tVcHBlciBpbnQzMiwKCWxpcXVpZGl0eUFtb3VudCBzdHJpbmcsCglwb3NpdGlvbkNhbGxlciBhZGRyZXNzLAopIChzdHJpbmcsIHN0cmluZykgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaS5hc3NlcnRQb29sVW5sb2NrZWQoKQoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFBvb2woKQoKCWNhbGxlciA6PSBybG0uUHJldmlvdXMoKS5BZGRyZXNzKCkKCWFjY2Vzcy5Bc3NlcnRJc1Bvc2l0aW9uKGNhbGxlcikKCWFjY2Vzcy5Bc3NlcnRJc1ZhbGlkQWRkcmVzcyhwb3NpdGlvbkNhbGxlcikKCglpLmxvY2tQb29sKDAsIHJsbSkKCWRlZmVyIGkudW5sb2NrUG9vbCgwLCBybG0pCgoJbGlxdWlkaXR5IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKGxpcXVpZGl0eUFtb3VudCkKCWlmIGxpcXVpZGl0eS5Jc1plcm8oKSB7CgkJcGFuaWMoZXJyb3JzLk5ldyhlcnJaZXJvTGlxdWlkaXR5KSkKCX0KCglwb29sIDo9IGkubXVzdEdldFBvb2xCeSh0b2tlbjBQYXRoLCB0b2tlbjFQYXRoLCBmZWUpCgoJdGlja1NwYWNpbmcgOj0gcG9vbC5UaWNrU3BhY2luZygpCgljaGVja1RpY2tTcGFjaW5nKHRpY2tMb3dlciwgdGlja1NwYWNpbmcpCgljaGVja1RpY2tTcGFjaW5nKHRpY2tVcHBlciwgdGlja1NwYWNpbmcpCgoJbGlxdWlkaXR5RGVsdGEgOj0gZ25zbWF0aC5TYWZlQ29udmVydFRvSW50MTI4KGxpcXVpZGl0eSkKCXBvc2l0aW9uUGFyYW0gOj0gbmV3TW9kaWZ5UG9zaXRpb25QYXJhbXMocG9zaXRpb25DYWxsZXIsIHRpY2tMb3dlciwgdGlja1VwcGVyLCBsaXF1aWRpdHlEZWx0YSkKCW9ic2VydmF0aW9ucyA6PSBpLm11c3RHZXRPYnNlcnZhdGlvbnMocG9vbC5Qb29sUGF0aCgpKQoJXywgYW1vdW50MCwgYW1vdW50MSwgZXJyIDo9IG1vZGlmeVBvc2l0aW9uKHBvb2wsIG9ic2VydmF0aW9ucywgcG9zaXRpb25QYXJhbSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglwb29sQWRkciA6PSBhY2Nlc3MuTXVzdEdldEFkZHJlc3MocHJhYmMuUk9MRV9QT09MLlN0cmluZygpKQoKCWlmIGFtb3VudDAuR3QodTI1Ni5aZXJvKCkpIHsKCQlpLnNhZmVUcmFuc2ZlckZyb20oMCwgcmxtLCBwb29sLCBwb3NpdGlvbkNhbGxlciwgcG9vbEFkZHIsIHBvb2wuVG9rZW4wUGF0aCgpLCBhbW91bnQwLCB0cnVlKQoJfQoKCWlmIGFtb3VudDEuR3QodTI1Ni5aZXJvKCkpIHsKCQlpLnNhZmVUcmFuc2ZlckZyb20oMCwgcmxtLCBwb29sLCBwb3NpdGlvbkNhbGxlciwgcG9vbEFkZHIsIHBvb2wuVG9rZW4xUGF0aCgpLCBhbW91bnQxLCBmYWxzZSkKCX0KCgkvLyBTYXZlIHBvb2wgc3RhdGUgYWZ0ZXIgbW9kaWZ5UG9zaXRpb24gbWF5IGhhdmUgdXBkYXRlZCBsaXF1aWRpdHkKCWVyciA9IGkuc2F2ZVBvb2woMCwgcmxtLCBwb29sKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCXJldHVybiBhbW91bnQwLlRvU3RyaW5nKCksIGFtb3VudDEuVG9TdHJpbmcoKQp9CgovLyBCdXJuIHJlbW92ZXMgbGlxdWlkaXR5IGZyb20gYSBwb29sIHBvc2l0aW9uIGFuZCBjcmVkaXRzIHByaW5jaXBhbCBhcyB0b2tlbnMKLy8gb3dlZCB0byB0aGF0IHBvb2wtbGV2ZWwgcG9zaXRpb24gZW50cnkuCi8vCi8vIFRoZSBwb29sIG9wZXJhdGlvbiBpdHNlbGYgZG9lcyBub3QgdHJhbnNmZXIgdG9rZW5zOyBhIHN1YnNlcXVlbnQgQ29sbGVjdCBjYWxsCi8vIHBheXMgdGhlIGNyZWRpdGVkIHByaW5jaXBhbC4gUG9zaXRpb24uRGVjcmVhc2VMaXF1aWRpdHkgd3JhcHMgQnVybiBhbmQgdGhlCi8vIGZlZS1mcmVlIENvbGxlY3QgY2FsbCB3aXRoaW4gb25lIGF0b21pYyBwdWJsaWMgb3BlcmF0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdW5jaGFuZ2VkIGJ5IHRoZSBwb29sIHByb3h5LgovLyAgIC0gdG9rZW4wUGF0aDogUmVnaXN0ZXJlZCB0b2tlbiBjb250cmFjdCBwYXRoIGZvciB0b2tlbjAuCi8vICAgLSB0b2tlbjFQYXRoOiBSZWdpc3RlcmVkIHRva2VuIGNvbnRyYWN0IHBhdGggZm9yIHRva2VuMS4KLy8gICAtIGZlZTogRmVlIHRpZXIgaWRlbnRpZnlpbmcgdGhlIHBvb2wuCi8vICAgLSB0aWNrTG93ZXI6IExvd2VyIHRpY2sgb2YgdGhlIHBvc2l0aW9uJ3MgcHJpY2UgcmFuZ2U7IG11c3QgbWF0Y2ggcG9vbCBzcGFjaW5nLgovLyAgIC0gdGlja1VwcGVyOiBVcHBlciB0aWNrIG9mIHRoZSBwb3NpdGlvbidzIHByaWNlIHJhbmdlOyBtdXN0IG1hdGNoIHBvb2wgc3BhY2luZy4KLy8gICAtIGxpcXVpZGl0eUFtb3VudDogTm9uLW5lZ2F0aXZlIGRlY2ltYWwgbGlxdWlkaXR5IGFtb3VudCwgYXQgbW9zdCAyXjEyNy0xIGFmdGVyIGNvbnZlcnNpb24gdG8gaW50MTI4LgovLyAgIC0gcG9zaXRpb25DYWxsZXI6IE5vbnplcm8gcG9zaXRpb24tY29udHJhY3QgYWRkcmVzcyBhc3NvY2lhdGVkIHdpdGggdGhlIHBvb2wgcG9zaXRpb24uCi8vCi8vIFJldHVybnM6Ci8vICAgLSBhbW91bnQwOiBUb2tlbjAgcHJpbmNpcGFsIGNyZWRpdGVkIHRvIHRoZSBwb29sIHBvc2l0aW9uLCBhcyBhIGRlY2ltYWwgc3RyaW5nLgovLyAgIC0gYW1vdW50MTogVG9rZW4xIHByaW5jaXBhbCBjcmVkaXRlZCB0byB0aGUgcG9vbCBwb3NpdGlvbiwgYXMgYSBkZWNpbWFsIHN0cmluZy4KLy8KLy8gTm90ZTogVG9rZW5zIHJlbWFpbiBpbiBwb29sIHVudGlsIENvbGxlY3QgaXMgY2FsbGVkLgovLyBPbmx5IGNhbGxhYmxlIGJ5IHBvc2l0aW9uIGNvbnRyYWN0LgpmdW5jIChpICpwb29sVjEpIEJ1cm4oCglfIGludCwKCXJsbSByZWFsbSwKCXRva2VuMFBhdGggc3RyaW5nLAoJdG9rZW4xUGF0aCBzdHJpbmcsCglmZWUgdWludDMyLAoJdGlja0xvd2VyIGludDMyLAoJdGlja1VwcGVyIGludDMyLAoJbGlxdWlkaXR5QW1vdW50IHN0cmluZywgLy8gcGFyc2VkIGFzIHVpbnQyNTYsIHRoZW4gY2hlY2tlZCBhZ2FpbnN0IGludDEyOAoJcG9zaXRpb25DYWxsZXIgYWRkcmVzcywKKSAoc3RyaW5nLCBzdHJpbmcpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWkuYXNzZXJ0UG9vbFVubG9ja2VkKCkKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRXaXRoZHJhdygpCgoJY2FsbGVyIDo9IHJsbS5QcmV2aW91cygpLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzUG9zaXRpb24oY2FsbGVyKQoJYWNjZXNzLkFzc2VydElzVmFsaWRBZGRyZXNzKHBvc2l0aW9uQ2FsbGVyKQoKCWkubG9ja1Bvb2woMCwgcmxtKQoJZGVmZXIgaS51bmxvY2tQb29sKDAsIHJsbSkKCglsaXFBbW91bnQgOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwobGlxdWlkaXR5QW1vdW50KQoJbGlxQW1vdW50SW50MjU2IDo9IGduc21hdGguU2FmZUNvbnZlcnRUb0ludDEyOChsaXFBbW91bnQpCglsaXFEZWx0YSA6PSBpMjU2Llplcm8oKS5OZWcobGlxQW1vdW50SW50MjU2KQoKCXBvc1BhcmFtcyA6PSBuZXdNb2RpZnlQb3NpdGlvblBhcmFtcyhwb3NpdGlvbkNhbGxlciwgdGlja0xvd2VyLCB0aWNrVXBwZXIsIGxpcURlbHRhKQoJcG9vbCA6PSBpLm11c3RHZXRQb29sQnkodG9rZW4wUGF0aCwgdG9rZW4xUGF0aCwgZmVlKQoJb2JzZXJ2YXRpb25zIDo9IGkubXVzdEdldE9ic2VydmF0aW9ucyhwb29sLlBvb2xQYXRoKCkpCglwb3NpdGlvbiwgYW1vdW50MCwgYW1vdW50MSwgZXJyIDo9IG1vZGlmeVBvc2l0aW9uKHBvb2wsIG9ic2VydmF0aW9ucywgcG9zUGFyYW1zKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWlmIGFtb3VudDAuR3QodTI1Ni5aZXJvKCkpIHx8IGFtb3VudDEuR3QodTI1Ni5aZXJvKCkpIHsKCQlhbW91bnQwID0gdG9VaW50MTI4KGFtb3VudDApCgkJYW1vdW50MSA9IHRvVWludDEyOChhbW91bnQxKQoKCQlwb3NpdGlvbi5TZXRUb2tlbnNPd2VkMChnbnNtYXRoLlNhZmVBZGRJbnQ2NChwb3NpdGlvbi5Ub2tlbnNPd2VkMCgpLCBnbnNtYXRoLlNhZmVDb252ZXJ0VG9JbnQ2NChhbW91bnQwKSkpCgkJcG9zaXRpb24uU2V0VG9rZW5zT3dlZDEoZ25zbWF0aC5TYWZlQWRkSW50NjQocG9zaXRpb24uVG9rZW5zT3dlZDEoKSwgZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQoYW1vdW50MSkpKQoJfQoKCXBvc2l0aW9uS2V5IDo9IGdldFBvc2l0aW9uS2V5KHRpY2tMb3dlciwgdGlja1VwcGVyKQoKCXNldFBvc2l0aW9uKHBvb2wsIHBvc2l0aW9uS2V5LCBwb3NpdGlvbikKCgllcnIgPSBpLnNhdmVQb29sKDAsIHJsbSwgcG9vbCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgkvLyBhY3R1YWwgdG9rZW4gdHJhbnNmZXIgaGFwcGVucyBpbiBDb2xsZWN0KCkKCXJldHVybiBhbW91bnQwLlRvU3RyaW5nKCksIGFtb3VudDEuVG9TdHJpbmcoKQp9CgovLyBDb2xsZWN0U3dhcEZlZSBwYXlzIG91dCBhY2NydWVkIHN3YXAgZmVlcyBmb3IgYSBwb3NpdGlvbi4KLy8KLy8gVGhlIHdpdGhkcmF3YWwgZmVlIGlzIGRlZHVjdGVkIGZyb20gdGhlIGNvbGxlY3RlZCBhbW91bnQgYW5kIHNldHRsZWQgdG8gdGhlCi8vIHByb3RvY29sIGZlZSByZWFsbTsgdGhlIHJlbWFpbmRlciBpcyB0cmFuc2ZlcnJlZCB0byByZWNpcGllbnQuIE9ubHkgYWNjcnVlZAovLyBzd2FwIGZlZXMgYmVsb25nIG9uIHRoaXMgcGF0aCAtIHByaW5jaXBhbCByZXR1cm5lZCBieSBCdXJuIGlzIG5vdCBmZWUKLy8gYmVhcmluZyBhbmQgbXVzdCBnbyB0aHJvdWdoIENvbGxlY3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCB1bmNoYW5nZWQgYnkgdGhlIHBvb2wgcHJveHkuCi8vICAgLSB0b2tlbjBQYXRoOiBSZWdpc3RlcmVkIHRva2VuIGNvbnRyYWN0IHBhdGggZm9yIHRva2VuMC4KLy8gICAtIHRva2VuMVBhdGg6IFJlZ2lzdGVyZWQgdG9rZW4gY29udHJhY3QgcGF0aCBmb3IgdG9rZW4xLgovLyAgIC0gZmVlOiBGZWUgdGllciBpZGVudGlmeWluZyB0aGUgcG9vbC4KLy8gICAtIHJlY2lwaWVudDogTm9uemVybyBhZGRyZXNzIHJlY2VpdmluZyB0aGUgcG9zdC1mZWUgdG9rZW4gYW1vdW50cy4KLy8gICAtIHRpY2tMb3dlcjogTG93ZXIgdGljayBvZiB0aGUgcG9zaXRpb24ncyBwcmljZSByYW5nZS4KLy8gICAtIHRpY2tVcHBlcjogVXBwZXIgdGljayBvZiB0aGUgcG9zaXRpb24ncyBwcmljZSByYW5nZS4KLy8gICAtIGFtb3VudDBSZXF1ZXN0ZWQ6IE5vbi1uZWdhdGl2ZSBkZWNpbWFsIGludDY0IGFtb3VudCBvZiB0b2tlbjAgcmVxdWVzdGVkOyB0aGUgaW50NjQgbWF4aW11bSByZXF1ZXN0cyBhbGwgb3dlZCB0b2tlbjAuCi8vICAgLSBhbW91bnQxUmVxdWVzdGVkOiBOb24tbmVnYXRpdmUgZGVjaW1hbCBpbnQ2NCBhbW91bnQgb2YgdG9rZW4xIHJlcXVlc3RlZDsgdGhlIGludDY0IG1heGltdW0gcmVxdWVzdHMgYWxsIG93ZWQgdG9rZW4xLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYW1vdW50MDogVG9rZW4wIGFtb3VudCBjb2xsZWN0ZWQgYmVmb3JlIHdpdGhkcmF3YWwtZmVlIGRlZHVjdGlvbiwgYXMgYSBkZWNpbWFsIHN0cmluZy4KLy8gICAtIGFtb3VudDE6IFRva2VuMSBhbW91bnQgY29sbGVjdGVkIGJlZm9yZSB3aXRoZHJhd2FsLWZlZSBkZWR1Y3Rpb24sIGFzIGEgZGVjaW1hbCBzdHJpbmcuCi8vICAgLSBmZWUwOiBXaXRoZHJhd2FsIGZlZSB3aXRoaGVsZCBmcm9tIHRva2VuMCwgYXMgYSBkZWNpbWFsIHN0cmluZy4KLy8gICAtIGZlZTE6IFdpdGhkcmF3YWwgZmVlIHdpdGhoZWxkIGZyb20gdG9rZW4xLCBhcyBhIGRlY2ltYWwgc3RyaW5nLgovLwovLyBPbmx5IGNhbGxhYmxlIGJ5IHBvc2l0aW9uIGNvbnRyYWN0LgpmdW5jIChpICpwb29sVjEpIENvbGxlY3RTd2FwRmVlKAoJXyBpbnQsCglybG0gcmVhbG0sCgl0b2tlbjBQYXRoIHN0cmluZywKCXRva2VuMVBhdGggc3RyaW5nLAoJZmVlIHVpbnQzMiwKCXJlY2lwaWVudCBhZGRyZXNzLAoJdGlja0xvd2VyIGludDMyLAoJdGlja1VwcGVyIGludDMyLAoJYW1vdW50MFJlcXVlc3RlZCBzdHJpbmcsCglhbW91bnQxUmVxdWVzdGVkIHN0cmluZywKKSAoYW1vdW50MCwgYW1vdW50MSwgZmVlMCwgZmVlMSBzdHJpbmcpIHsKCWNvbGxlY3RlZDAsIGNvbGxlY3RlZDEsIHdpdGhoZWxkMCwgd2l0aGhlbGQxIDo9IGkuY29sbGVjdCgKCQkwLCBybG0sCgkJdG9rZW4wUGF0aCwgdG9rZW4xUGF0aCwgZmVlLAoJCXJlY2lwaWVudCwKCQl0aWNrTG93ZXIsIHRpY2tVcHBlciwKCQlhbW91bnQwUmVxdWVzdGVkLCBhbW91bnQxUmVxdWVzdGVkLAoJCXRydWUsCgkpCgoJcmV0dXJuIHV0aWxzLkZvcm1hdEludChjb2xsZWN0ZWQwKSwgdXRpbHMuRm9ybWF0SW50KGNvbGxlY3RlZDEpLAoJCXV0aWxzLkZvcm1hdEludCh3aXRoaGVsZDApLCB1dGlscy5Gb3JtYXRJbnQod2l0aGhlbGQxKQp9CgovLyBDb2xsZWN0IHBheXMgb3V0IHRva2VucyBvd2VkIHRvIGEgcG9zaXRpb24sIHRyYW5zZmVycmluZyB0aGUgZnVsbCBhbW91bnQgdG8KLy8gcmVjaXBpZW50LgovLwovLyBObyB3aXRoZHJhd2FsIGZlZSBpcyBjaGFyZ2VkOiB0aGlzIHBhdGggY2FycmllcyBwcmluY2lwYWwgY3JlZGl0ZWQgYnkgQnVybiwKLy8gd2hpY2ggdGhlIHByb3RvY29sIGRvZXMgbm90IHRheC4gQWNjcnVlZCBzd2FwIGZlZXMgYmVsb25nIG9uIENvbGxlY3RTd2FwRmVlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdW5jaGFuZ2VkIGJ5IHRoZSBwb29sIHByb3h5LgovLyAgIC0gdG9rZW4wUGF0aDogUmVnaXN0ZXJlZCB0b2tlbiBjb250cmFjdCBwYXRoIGZvciB0b2tlbjAuCi8vICAgLSB0b2tlbjFQYXRoOiBSZWdpc3RlcmVkIHRva2VuIGNvbnRyYWN0IHBhdGggZm9yIHRva2VuMS4KLy8gICAtIGZlZTogRmVlIHRpZXIgaWRlbnRpZnlpbmcgdGhlIHBvb2wuCi8vICAgLSByZWNpcGllbnQ6IE5vbnplcm8gYWRkcmVzcyByZWNlaXZpbmcgdGhlIG93ZWQgdG9rZW4gYW1vdW50cy4KLy8gICAtIHRpY2tMb3dlcjogTG93ZXIgdGljayBvZiB0aGUgcG9zaXRpb24ncyBwcmljZSByYW5nZS4KLy8gICAtIHRpY2tVcHBlcjogVXBwZXIgdGljayBvZiB0aGUgcG9zaXRpb24ncyBwcmljZSByYW5nZS4KLy8gICAtIGFtb3VudDBSZXF1ZXN0ZWQ6IE5vbi1uZWdhdGl2ZSBkZWNpbWFsIGludDY0IGFtb3VudCBvZiB0b2tlbjAgcmVxdWVzdGVkOyB0aGUgaW50NjQgbWF4aW11bSByZXF1ZXN0cyBhbGwgb3dlZCB0b2tlbjAuCi8vICAgLSBhbW91bnQxUmVxdWVzdGVkOiBOb24tbmVnYXRpdmUgZGVjaW1hbCBpbnQ2NCBhbW91bnQgb2YgdG9rZW4xIHJlcXVlc3RlZDsgdGhlIGludDY0IG1heGltdW0gcmVxdWVzdHMgYWxsIG93ZWQgdG9rZW4xLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYW1vdW50MDogVG9rZW4wIHByaW5jaXBhbCB0cmFuc2ZlcnJlZCB0byByZWNpcGllbnQsIGFzIGEgZGVjaW1hbCBzdHJpbmcuCi8vICAgLSBhbW91bnQxOiBUb2tlbjEgcHJpbmNpcGFsIHRyYW5zZmVycmVkIHRvIHJlY2lwaWVudCwgYXMgYSBkZWNpbWFsIHN0cmluZy4KLy8KLy8gT25seSBjYWxsYWJsZSBieSBwb3NpdGlvbiBjb250cmFjdC4KZnVuYyAoaSAqcG9vbFYxKSBDb2xsZWN0KAoJXyBpbnQsCglybG0gcmVhbG0sCgl0b2tlbjBQYXRoIHN0cmluZywKCXRva2VuMVBhdGggc3RyaW5nLAoJZmVlIHVpbnQzMiwKCXJlY2lwaWVudCBhZGRyZXNzLAoJdGlja0xvd2VyIGludDMyLAoJdGlja1VwcGVyIGludDMyLAoJYW1vdW50MFJlcXVlc3RlZCBzdHJpbmcsCglhbW91bnQxUmVxdWVzdGVkIHN0cmluZywKKSAoYW1vdW50MCwgYW1vdW50MSBzdHJpbmcpIHsKCWNvbGxlY3RlZDAsIGNvbGxlY3RlZDEsIF8sIF8gOj0gaS5jb2xsZWN0KAoJCTAsIHJsbSwKCQl0b2tlbjBQYXRoLCB0b2tlbjFQYXRoLCBmZWUsCgkJcmVjaXBpZW50LAoJCXRpY2tMb3dlciwgdGlja1VwcGVyLAoJCWFtb3VudDBSZXF1ZXN0ZWQsIGFtb3VudDFSZXF1ZXN0ZWQsCgkJZmFsc2UsCgkpCgoJcmV0dXJuIHV0aWxzLkZvcm1hdEludChjb2xsZWN0ZWQwKSwgdXRpbHMuRm9ybWF0SW50KGNvbGxlY3RlZDEpCn0KCi8vIGNvbGxlY3Qgc2V0dGxlcyB0aGUgcG9vbCBsZWRnZXIgZm9yIGEgcG9zaXRpb24gYW5kIHBheXMgdGhlIHJlY2lwaWVudC4KLy8KLy8gVGhlIHBheW91dCBpcyBjYXBwZWQgYnkgdGhlIHBvc2l0aW9uJ3MgdG9rZW5zT3dlZCwgbmV2ZXIgYnkgYSBjYWxsZXIKLy8gc3VwcGxpZWQgbnVtYmVyLCBhbmQgdGhlIGxlZGdlciBpcyB3cml0dGVuIGJlZm9yZSBhbnkgdG9rZW4gbGVhdmVzIHRoZQovLyByZWFsbS4gQm90aCBoYXBwZW4gdW5kZXIgYSBzaW5nbGUgcG9vbCBsb2NrLCBzbyB0aGUgcG9vbCdzIGFjY291bnRpbmcgYW5kCi8vIGl0cyB0b2tlbiBiYWxhbmNlIGFyZSBuZXZlciBvYnNlcnZhYmx5IG91dCBvZiBzdGVwLgovLwovLyBUaGUgY29sbGVjdGVkIGFtb3VudCBpcyBOT1QgY2FwcGVkIGJ5IHRoZSBwb29sJ3MgaW50ZXJuYWwgYmFsYW5jZTogYSBiYWxhbmNlCi8vIHNob3J0IG9mIHRoZSBvd2VkIGFtb3VudCBtZWFucyB0aGUgaW50ZXJuYWwgbGVkZ2VyIGhhcyBkcmlmdGVkLCBzbyB0aGUgY2FsbAovLyByZXZlcnRzIHJhdGhlciB0aGFuIHNpbGVudGx5IHBheWluZyBvdXQgbGVzcy4KLy8KLy8gYXBwbHlXaXRoZHJhd2FsRmVlIHNlbGVjdHMgdGhlIGZlZSBwb2xpY3k7IHBhc3MgZmFsc2UgZm9yIGEgZmVlLWZyZWUgcGF5b3V0LgovLyBJdCBpcyB0aGUgZW50cnkgcG9pbnQsIG5vdCB0aGUgY29uZmlndXJlZCByYXRlLCB0aGF0IGRlY2lkZXMgd2hldGhlciB0aGUKLy8gcHJvdG9jb2wgZmVlIGlzIHNldHRsZWQ6IGEgcmF0ZSBvZiB6ZXJvIG11c3Qgc3RpbGwgZmx1c2ggYSBiYWNrbG9nIGxlZnQKLy8gcGVuZGluZyBieSBhbiBlYXJsaWVyIGhhbHRlZCBzZXR0bGVtZW50LgpmdW5jIChpICpwb29sVjEpIGNvbGxlY3QoCglfIGludCwKCXJsbSByZWFsbSwKCXRva2VuMFBhdGggc3RyaW5nLAoJdG9rZW4xUGF0aCBzdHJpbmcsCglmZWUgdWludDMyLAoJcmVjaXBpZW50IGFkZHJlc3MsCgl0aWNrTG93ZXIgaW50MzIsCgl0aWNrVXBwZXIgaW50MzIsCglhbW91bnQwUmVxdWVzdGVkIHN0cmluZywKCWFtb3VudDFSZXF1ZXN0ZWQgc3RyaW5nLAoJYXBwbHlXaXRoZHJhd2FsRmVlIGJvb2wsCikgKGFtb3VudDAsIGFtb3VudDEsIGZlZTAsIGZlZTEgaW50NjQpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWkuYXNzZXJ0UG9vbFVubG9ja2VkKCkKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRXaXRoZHJhdygpCgoJY2FsbGVyIDo9IHJsbS5QcmV2aW91cygpLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzUG9zaXRpb24oY2FsbGVyKQoJYWNjZXNzLkFzc2VydElzVmFsaWRBZGRyZXNzKHJlY2lwaWVudCkKCglpLmxvY2tQb29sKDAsIHJsbSkKCWRlZmVyIGkudW5sb2NrUG9vbCgwLCBybG0pCgoJYW1vdW50MFJlcSA6PSB1dGlscy5TYWZlUGFyc2VJbnQ2NChhbW91bnQwUmVxdWVzdGVkKQoJYW1vdW50MVJlcSA6PSB1dGlscy5TYWZlUGFyc2VJbnQ2NChhbW91bnQxUmVxdWVzdGVkKQoKCWlmIGFtb3VudDBSZXEgPCAwIHx8IGFtb3VudDFSZXEgPCAwIHsKCQlwYW5pYyhlcnJvcnMuTmV3KGVyckludmFsaWRJbnB1dCkpCgl9CgoJcG9vbCA6PSBpLm11c3RHZXRQb29sQnkodG9rZW4wUGF0aCwgdG9rZW4xUGF0aCwgZmVlKQoJLy8gVGhlIHBvb2wgcG9zaXRpb24ga2V5IGVuY29kZXMgb25seSB0aGUgbG93ZXIgYW5kIHVwcGVyIHRpY2tzLiBJdCBpcyBzY29wZWQKCS8vIHRvIHRoaXMgcG9vbCwgc28gTkZUcyBzaGFyaW5nIGEgcmFuZ2UgdXNlIHRoZSBzYW1lIGFnZ3JlZ2F0ZSBwb29sIGVudHJ5LgoJcG9zaXRpb25LZXkgOj0gZ2V0UG9zaXRpb25LZXkodGlja0xvd2VyLCB0aWNrVXBwZXIpCglwb3NpdGlvbiwgZXJyIDo9IHBvb2wuR2V0UG9zaXRpb24ocG9zaXRpb25LZXkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoCgkJCWVyckRhdGFOb3RGb3VuZCwKCQkJdWZtdC5TcHJpbnRmKCJwb3NpdGlvbktleSglcykgZG9lcyBub3QgZXhpc3QiLCBwb3NpdGlvbktleSksCgkJKSkKCX0KCglhbW91bnQwID0gbWluUmVxdWVzdGVkQW1vdW50KGFtb3VudDBSZXEsIHBvc2l0aW9uLlRva2Vuc093ZWQwKCkpCglhbW91bnQxID0gbWluUmVxdWVzdGVkQW1vdW50KGFtb3VudDFSZXEsIHBvc2l0aW9uLlRva2Vuc093ZWQxKCkpCgoJaWYgYW1vdW50MCA+IDAgewoJCXRva2VuT3dlZDAgOj0gZ25zbWF0aC5TYWZlU3ViSW50NjQocG9zaXRpb24uVG9rZW5zT3dlZDAoKSwgYW1vdW50MCkKCQl0b2tlbjBCYWxhbmNlLCBlcnIgOj0gdXBkYXRlUG9vbEJhbGFuY2UocG9vbC5CYWxhbmNlVG9rZW4wKCksIHBvb2wuQmFsYW5jZVRva2VuMSgpLCBhbW91bnQwLCB0cnVlKQoJCWlmIGVyciAhPSBuaWwgewoJCQlwYW5pYyhlcnIpCgkJfQoKCQlwb3NpdGlvbi5TZXRUb2tlbnNPd2VkMCh0b2tlbk93ZWQwKQoJCXBvb2wuU2V0QmFsYW5jZVRva2VuMCh0b2tlbjBCYWxhbmNlKQoJfQoJaWYgYW1vdW50MSA+IDAgewoJCXRva2VuT3dlZDEgOj0gZ25zbWF0aC5TYWZlU3ViSW50NjQocG9zaXRpb24uVG9rZW5zT3dlZDEoKSwgYW1vdW50MSkKCQl0b2tlbjFCYWxhbmNlLCBlcnIgOj0gdXBkYXRlUG9vbEJhbGFuY2UocG9vbC5CYWxhbmNlVG9rZW4wKCksIHBvb2wuQmFsYW5jZVRva2VuMSgpLCBhbW91bnQxLCBmYWxzZSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcGFuaWMoZXJyKQoJCX0KCgkJcG9zaXRpb24uU2V0VG9rZW5zT3dlZDEodG9rZW5Pd2VkMSkKCQlwb29sLlNldEJhbGFuY2VUb2tlbjEodG9rZW4xQmFsYW5jZSkKCX0KCglzZXRQb3NpdGlvbihwb29sLCBwb3NpdGlvbktleSwgcG9zaXRpb24pCgoJaWYgZXJyIDo9IGkuc2F2ZVBvb2woMCwgcmxtLCBwb29sKTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCXdpdGhkcmF3YWxGZWVCUFMgOj0gWmVyb0JwcwoJaWYgYXBwbHlXaXRoZHJhd2FsRmVlIHsKCQl3aXRoZHJhd2FsRmVlQlBTID0gaS5zdG9yZS5HZXRXaXRoZHJhd2FsRmVlQlBTKCkKCX0KCgkvLyBFZmZlY3RzIGFyZSBwZXJzaXN0ZWQgYWJvdmU7IGV2ZXJ5dGhpbmcgYmVsb3cgbGVhdmVzIHRoZSByZWFsbS4KCWZlZTAsIGFtb3VudDBBZnRlckZlZSA6PSBkZWR1Y3RXaXRoZHJhd2FsRmVlKGFtb3VudDAsIHdpdGhkcmF3YWxGZWVCUFMpCglmZWUxLCBhbW91bnQxQWZ0ZXJGZWUgOj0gZGVkdWN0V2l0aGRyYXdhbEZlZShhbW91bnQxLCB3aXRoZHJhd2FsRmVlQlBTKQoKCWlmIGFwcGx5V2l0aGRyYXdhbEZlZSB7CgkJLy8gQ2FsbGVkIGV2ZW4gZm9yIGEgemVybyBmZWUsIGFuZCBmb3IgYSB6ZXJvIHdpdGhkcmF3YWwgZmVlIHJhdGUsIHNvIHRoYXQKCQkvLyBhbnl0aGluZyBsZWZ0IHBlbmRpbmcgZm9yIHRoZXNlIHRva2VucyBieSBhbiBlYXJsaWVyIGhhbHRlZCBzZXR0bGVtZW50CgkJLy8gaXMgZmx1c2hlZC4KCQlpLnNldHRsZVByb3RvY29sRmVlKDAsIHJsbSwgdG9rZW4wUGF0aCwgZmVlMCkKCQlpLnNldHRsZVByb3RvY29sRmVlKDAsIHJsbSwgdG9rZW4xUGF0aCwgZmVlMSkKCX0KCglpZiBhbW91bnQwQWZ0ZXJGZWUgPiAwIHsKCQljb21tb24uU2FmZUdSQzIwVHJhbnNmZXIoMCwgcmxtLCB0b2tlbjBQYXRoLCByZWNpcGllbnQsIGFtb3VudDBBZnRlckZlZSkKCX0KCWlmIGFtb3VudDFBZnRlckZlZSA+IDAgewoJCWNvbW1vbi5TYWZlR1JDMjBUcmFuc2ZlcigwLCBybG0sIHRva2VuMVBhdGgsIHJlY2lwaWVudCwgYW1vdW50MUFmdGVyRmVlKQoJfQoKCXJldHVybiBhbW91bnQwLCBhbW91bnQxLCBmZWUwLCBmZWUxCn0KCi8vIENvbGxlY3RQcm90b2NvbCBjb2xsZWN0cyBhY2N1bXVsYXRlZCBwcm90b2NvbCBmZWVzIGZyb20gc3dhcCBvcGVyYXRpb25zLgovLyBPbmx5IGNhbGxhYmxlIGJ5IGFkbWluIG9yIGdvdmVybmFuY2UuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCB1bmNoYW5nZWQgYnkgdGhlIHBvb2wgcHJveHkuCi8vICAgLSB0b2tlbjBQYXRoOiBSZWdpc3RlcmVkIHRva2VuIGNvbnRyYWN0IHBhdGggZm9yIHRva2VuMC4KLy8gICAtIHRva2VuMVBhdGg6IFJlZ2lzdGVyZWQgdG9rZW4gY29udHJhY3QgcGF0aCBmb3IgdG9rZW4xLgovLyAgIC0gZmVlOiBGZWUgdGllciBpZGVudGlmeWluZyB0aGUgcG9vbC4KLy8gICAtIHJlY2lwaWVudDogTm9uemVybyBhZGRyZXNzIHJlY2VpdmluZyB0aGUgY29sbGVjdGVkIHByb3RvY29sIGZlZXMuCi8vICAgLSBhbW91bnQwUmVxdWVzdGVkOiBOb24tbmVnYXRpdmUgZGVjaW1hbCBhbW91bnQgb2YgdG9rZW4wIHByb3RvY29sIGZlZXMgcmVxdWVzdGVkOyBjYXBwZWQgYXQgdGhlIGF2YWlsYWJsZSBiYWxhbmNlLgovLyAgIC0gYW1vdW50MVJlcXVlc3RlZDogTm9uLW5lZ2F0aXZlIGRlY2ltYWwgYW1vdW50IG9mIHRva2VuMSBwcm90b2NvbCBmZWVzIHJlcXVlc3RlZDsgY2FwcGVkIGF0IHRoZSBhdmFpbGFibGUgYmFsYW5jZS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGFtb3VudDA6IFRva2VuMCBwcm90b2NvbCBmZWVzIHRyYW5zZmVycmVkIHRvIHJlY2lwaWVudCwgYXMgYSBkZWNpbWFsIHN0cmluZy4KLy8gICAtIGFtb3VudDE6IFRva2VuMSBwcm90b2NvbCBmZWVzIHRyYW5zZmVycmVkIHRvIHJlY2lwaWVudCwgYXMgYSBkZWNpbWFsIHN0cmluZy4KZnVuYyAoaSAqcG9vbFYxKSBDb2xsZWN0UHJvdG9jb2woCglfIGludCwKCXJsbSByZWFsbSwKCXRva2VuMFBhdGggc3RyaW5nLAoJdG9rZW4xUGF0aCBzdHJpbmcsCglmZWUgdWludDMyLAoJcmVjaXBpZW50IGFkZHJlc3MsCglhbW91bnQwUmVxdWVzdGVkIHN0cmluZywgLy8gdWludDEyOAoJYW1vdW50MVJlcXVlc3RlZCBzdHJpbmcsIC8vIHVpbnQxMjgKKSAoc3RyaW5nLCBzdHJpbmcpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWkuYXNzZXJ0UG9vbFVubG9ja2VkKCkKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRXaXRoZHJhdygpCgoJcHJldmlvdXNSZWFsbSA6PSBybG0uUHJldmlvdXMoKQoJY2FsbGVyIDo9IHByZXZpb3VzUmVhbG0uQWRkcmVzcygpCglhY2Nlc3MuQXNzZXJ0SXNBZG1pbk9yR292ZXJuYW5jZShjYWxsZXIpCgoJY29tbW9uLk11c3RSZWdpc3RlcmVkKHRva2VuMFBhdGgsIHRva2VuMVBhdGgpCgoJaS5sb2NrUG9vbCgwLCBybG0pCglkZWZlciBpLnVubG9ja1Bvb2woMCwgcmxtKQoKCWFtb3VudDAsIGFtb3VudDEgOj0gaS5jb2xsZWN0UHJvdG9jb2woCgkJMCwKCQlybG0sCgkJdG9rZW4wUGF0aCwKCQl0b2tlbjFQYXRoLAoJCWZlZSwKCQlyZWNpcGllbnQsCgkJYW1vdW50MFJlcXVlc3RlZCwKCQlhbW91bnQxUmVxdWVzdGVkLAoJKQoKCWNoYWluLkVtaXQoCgkJIkNvbGxlY3RQcm90b2NvbCIsCgkJInByZXZBZGRyIiwgY2FsbGVyLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2aW91c1JlYWxtLlBrZ1BhdGgoKSwKCQkidG9rZW4wUGF0aCIsIHRva2VuMFBhdGgsCgkJInRva2VuMVBhdGgiLCB0b2tlbjFQYXRoLAoJCSJmZWUiLCB1dGlscy5Gb3JtYXRVaW50KGZlZSksCgkJInJlY2lwaWVudCIsIHJlY2lwaWVudC5TdHJpbmcoKSwKCQkiaW50ZXJuYWxfYW1vdW50MCIsIGFtb3VudDAsCgkJImludGVybmFsX2Ftb3VudDEiLCBhbW91bnQxLAoJKQoKCXJldHVybiBhbW91bnQwLCBhbW91bnQxCn0KCi8vIGNvbGxlY3RQcm90b2NvbCBwZXJmb3JtcyB0aGUgYWN0dWFsIHByb3RvY29sIGZlZSBjb2xsZWN0aW9uLgovLyBJdCBlbnN1cmVzIHJlcXVlc3RlZCBhbW91bnRzIGRvbid0IGV4Y2VlZCBhdmFpbGFibGUgcHJvdG9jb2wgZmVlcy4KLy8gUmV0dXJucyBhbW91bnQwLCBhbW91bnQxIGFzIHN0cmluZ3MgcmVwcmVzZW50aW5nIGNvbGxlY3RlZCBmZWVzLgpmdW5jIChpICpwb29sVjEpIGNvbGxlY3RQcm90b2NvbCgKCV8gaW50LAoJcmxtIHJlYWxtLAoJdG9rZW4wUGF0aCBzdHJpbmcsCgl0b2tlbjFQYXRoIHN0cmluZywKCWZlZSB1aW50MzIsCglyZWNpcGllbnQgYWRkcmVzcywKCWFtb3VudDBSZXF1ZXN0ZWQgc3RyaW5nLAoJYW1vdW50MVJlcXVlc3RlZCBzdHJpbmcsCikgKHN0cmluZywgc3RyaW5nKSB7Cglwb29sIDo9IGkubXVzdEdldFBvb2xCeSh0b2tlbjBQYXRoLCB0b2tlbjFQYXRoLCBmZWUpCgoJYW1vdW50MFJlcSA6PSB1dGlscy5TYWZlUGFyc2VJbnQ2NChhbW91bnQwUmVxdWVzdGVkKQoJYW1vdW50MVJlcSA6PSB1dGlscy5TYWZlUGFyc2VJbnQ2NChhbW91bnQxUmVxdWVzdGVkKQoKCWlmIGFtb3VudDBSZXEgPCAwIHx8IGFtb3VudDFSZXEgPCAwIHsKCQlwYW5pYyhlcnJvcnMuTmV3KGVyckludmFsaWRJbnB1dCkpCgl9CgoJYW1vdW50MCA6PSBtaW5SZXF1ZXN0ZWRBbW91bnQoYW1vdW50MFJlcSwgcG9vbC5Qcm90b2NvbEZlZXNUb2tlbjAoKSkKCWFtb3VudDEgOj0gbWluUmVxdWVzdGVkQW1vdW50KGFtb3VudDFSZXEsIHBvb2wuUHJvdG9jb2xGZWVzVG9rZW4xKCkpCgoJYW1vdW50MCwgYW1vdW50MSA9IGkuc2F2ZVByb3RvY29sRmVlcyhwb29sLCBhbW91bnQwLCBhbW91bnQxKQoKCW5ld0JhbGFuY2VUb2tlbjAsIGVyciA6PSB1cGRhdGVQb29sQmFsYW5jZShwb29sLkJhbGFuY2VUb2tlbjAoKSwgcG9vbC5CYWxhbmNlVG9rZW4xKCksIGFtb3VudDAsIHRydWUpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9Cglwb29sLlNldEJhbGFuY2VUb2tlbjAobmV3QmFsYW5jZVRva2VuMCkKCgluZXdCYWxhbmNlVG9rZW4xLCBlcnIgOj0gdXBkYXRlUG9vbEJhbGFuY2UocG9vbC5CYWxhbmNlVG9rZW4wKCksIHBvb2wuQmFsYW5jZVRva2VuMSgpLCBhbW91bnQxLCBmYWxzZSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCXBvb2wuU2V0QmFsYW5jZVRva2VuMShuZXdCYWxhbmNlVG9rZW4xKQoKCWVyciA9IGkuc2F2ZVBvb2woMCwgcmxtLCBwb29sKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWNvbW1vbi5TYWZlR1JDMjBUcmFuc2ZlcigwLCBybG0sIHBvb2wuVG9rZW4wUGF0aCgpLCByZWNpcGllbnQsIGFtb3VudDApCgljb21tb24uU2FmZUdSQzIwVHJhbnNmZXIoMCwgcmxtLCBwb29sLlRva2VuMVBhdGgoKSwgcmVjaXBpZW50LCBhbW91bnQxKQoKCXJldHVybiB1dGlscy5Gb3JtYXRJbnQoYW1vdW50MCksIHV0aWxzLkZvcm1hdEludChhbW91bnQxKQp9CgovLyBzYXZlUHJvdG9jb2xGZWVzIHVwZGF0ZXMgdGhlIHByb3RvY29sIGZlZSBiYWxhbmNlcyBhZnRlciBjb2xsZWN0aW9uLgovLyBSZXR1cm5zIGFtb3VudDAsIGFtb3VudDEgcmVwcmVzZW50aW5nIHRoZSBmZWVzIGRlZHVjdGVkIGZyb20gcHJvdG9jb2wgcmVzZXJ2ZXMuCmZ1bmMgKGkgKnBvb2xWMSkgc2F2ZVByb3RvY29sRmVlcyhwb29sICpwbC5Qb29sLCBhbW91bnQwLCBhbW91bnQxIGludDY0KSAoaW50NjQsIGludDY0KSB7CglpZiBwb29sLlByb3RvY29sRmVlc1Rva2VuMCgpIDwgYW1vdW50MCB7CgkJcGFuaWMoZXJyb3JzLk5ldyhlcnJVbmRlcmZsb3cpKQoJfQoJcG9vbC5TZXRQcm90b2NvbEZlZXNUb2tlbjAoZ25zbWF0aC5TYWZlU3ViSW50NjQocG9vbC5Qcm90b2NvbEZlZXNUb2tlbjAoKSwgYW1vdW50MCkpCgoJaWYgcG9vbC5Qcm90b2NvbEZlZXNUb2tlbjEoKSA8IGFtb3VudDEgewoJCXBhbmljKGVycm9ycy5OZXcoZXJyVW5kZXJmbG93KSkKCX0KCXBvb2wuU2V0UHJvdG9jb2xGZWVzVG9rZW4xKGduc21hdGguU2FmZVN1YkludDY0KHBvb2wuUHJvdG9jb2xGZWVzVG9rZW4xKCksIGFtb3VudDEpKQoKCXJldHVybiBhbW91bnQwLCBhbW91bnQxCn0KCmZ1bmMgbWluUmVxdWVzdGVkQW1vdW50KHJlcXVlc3QsIGF2YWlsYWJsZSBpbnQ2NCkgaW50NjQgewoJaWYgcmVxdWVzdCA+IGF2YWlsYWJsZSB7CgkJcmV0dXJuIGF2YWlsYWJsZQoJfQoKCXJldHVybiByZXF1ZXN0Cn0KCi8vIEluY3JlYXNlT2JzZXJ2YXRpb25DYXJkaW5hbGl0eU5leHQgc2NoZWR1bGVzIGdyb3d0aCBvZiBhIHBvb2wncyBjaXJjdWxhciBvYnNlcnZhdGlvbiBidWZmZXIuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCB1bmNoYW5nZWQgYnkgdGhlIHBvb2wgcHJveHkuCi8vICAgLSB0b2tlbjBQYXRoOiBSZWdpc3RlcmVkIHRva2VuIGNvbnRyYWN0IHBhdGggZm9yIHRva2VuMC4KLy8gICAtIHRva2VuMVBhdGg6IFJlZ2lzdGVyZWQgdG9rZW4gY29udHJhY3QgcGF0aCBmb3IgdG9rZW4xLgovLyAgIC0gZmVlOiBGZWUgdGllciBpZGVudGlmeWluZyB0aGUgcG9vbC4KLy8gICAtIGNhcmRpbmFsaXR5TmV4dDogUmVxdWVzdGVkIG9ic2VydmF0aW9uLWJ1ZmZlciBjYXBhY2l0eTsgbXVzdCBub3QgZXhjZWVkIHRoZSBjb25maWd1cmVkIG1heGltdW0uCmZ1bmMgKGkgKnBvb2xWMSkgSW5jcmVhc2VPYnNlcnZhdGlvbkNhcmRpbmFsaXR5TmV4dCgKCV8gaW50LAoJcmxtIHJlYWxtLAoJdG9rZW4wUGF0aCBzdHJpbmcsCgl0b2tlbjFQYXRoIHN0cmluZywKCWZlZSB1aW50MzIsCgljYXJkaW5hbGl0eU5leHQgdWludDE2LAopIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWkuYXNzZXJ0UG9vbFVubG9ja2VkKCkKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRQb29sKCkKCglwb29sIDo9IGkubXVzdEdldFBvb2xCeSh0b2tlbjBQYXRoLCB0b2tlbjFQYXRoLCBmZWUpCglzbG90MEJlZm9yZSA6PSBwb29sLlNsb3QwKCkKCW9ic2VydmF0aW9uQ2FyZGluYWxpdHlOZXh0T2xkIDo9IHNsb3QwQmVmb3JlLk9ic2VydmF0aW9uQ2FyZGluYWxpdHlOZXh0KCkKCglpLmxvY2tQb29sKDAsIHJsbSkKCWRlZmVyIGkudW5sb2NrUG9vbCgwLCBybG0pCgoJb2JzZXJ2YXRpb25zIDo9IGkubXVzdEdldE9ic2VydmF0aW9ucyhwb29sLlBvb2xQYXRoKCkpCglpZiBjYXJkaW5hbGl0eU5leHQgPiBtYXhPYnNlcnZhdGlvbkNhcmRpbmFsaXR5IHsKCQlwYW5pYygib2JzZXJ2YXRpb24gY2FyZGluYWxpdHkgbmV4dCBleGNlZWRzIG1heGltdW0iKQoJfQoJb2JzZXJ2YXRpb25DYXJkaW5hbGl0eU5leHROZXcsIGVyciA6PSBncm93KAoJCW9ic2VydmF0aW9ucywKCQlzbG90MEJlZm9yZS5PYnNlcnZhdGlvbkNhcmRpbmFsaXR5TmV4dCgpLAoJCWNhcmRpbmFsaXR5TmV4dCwKCSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCXNsb3QwQWZ0ZXIgOj0gcG9vbC5TbG90MCgpCglzbG90MEFmdGVyLlNldE9ic2VydmF0aW9uQ2FyZGluYWxpdHlOZXh0KG9ic2VydmF0aW9uQ2FyZGluYWxpdHlOZXh0TmV3KQoJcG9vbC5TZXRTbG90MChzbG90MEFmdGVyKQoKCWlmIG9ic2VydmF0aW9uQ2FyZGluYWxpdHlOZXh0T2xkICE9IG9ic2VydmF0aW9uQ2FyZGluYWxpdHlOZXh0TmV3IHsKCQlwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgkJY2hhaW4uRW1pdCgKCQkJIkluY3JlYXNlT2JzZXJ2YXRpb25DYXJkaW5hbGl0eU5leHQiLAoJCQkicHJldkFkZHIiLCBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCQkicG9vbFBhdGgiLCBwb29sLlBvb2xQYXRoKCksCgkJCSJjYXJkaW5hbGl0eU5leHQiLCB1dGlscy5Gb3JtYXRVaW50KG9ic2VydmF0aW9uQ2FyZGluYWxpdHlOZXh0TmV3KSwKCQkpCgl9Cn0KGvhiCgxwb3NpdGlvbi5nbm8S52JwYWNrYWdlIHBvb2wKCmltcG9ydCAoCgkiZXJyb3JzIgoJInRpbWUiCgoJImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJaTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL2ludDI1Ni92MSIKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoKCXBsICJnbm8ubGFuZC9yL2dub3N3YXAvcG9vbCIKKQoKLy8gZ2V0UG9zaXRpb25LZXkgZ2VuZXJhdGVzIGEgY29tcGFjdCBkZXRlcm1pbmlzdGljIGtleSBmb3IgYSBsaXF1aWRpdHkgcG9zaXRpb24uCi8vCi8vIENyZWF0ZXMgZGV0ZXJtaW5pc3RpYyBpZGVudGlmaWVyIGZvciBwb3NpdGlvbiB0cmFja2luZy4KLy8gRW5zdXJlcyB1bmlxdWUgcG9zaXRpb25zIHBlciBwcmljZSByYW5nZSB3aGlsZSBwcmVzZXJ2aW5nIGxleGljYWwgb3JkZXJpbmcuCi8vCi8vIFVzZWQgaW50ZXJuYWxseSBmb3IgcG9zaXRpb24gc3RhdGUgbWFuYWdlbWVudC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHRpY2tMb3dlcjogTG93ZXIgYm91bmRhcnkgdGljayBvZiBwb3NpdGlvbiByYW5nZQovLyAgIC0gdGlja1VwcGVyOiBVcHBlciBib3VuZGFyeSB0aWNrIG9mIHBvc2l0aW9uIHJhbmdlCi8vCi8vIEtleSBGb3JtYXQ6IEVuY29kZVBvc2l0aW9uS2V5KHRpY2tMb3dlciwgdGlja1VwcGVyKQpmdW5jIGdldFBvc2l0aW9uS2V5KAoJdGlja0xvd2VyIGludDMyLAoJdGlja1VwcGVyIGludDMyLAopIHN0cmluZyB7CglyZXR1cm4gcGwuRW5jb2RlUG9zaXRpb25LZXkodGlja0xvd2VyLCB0aWNrVXBwZXIpCn0KCi8vIHBvc2l0aW9uVXBkYXRlIHVwZGF0ZXMgYSBwb3NpdGlvbidzIGxpcXVpZGl0eSBhbmQgY2FsY3VsYXRlcyBmZWVzIG93ZWQuCi8vIFJldHVybnMgdGhlIHVwZGF0ZWQgcG9zaXRpb24gaW5mb3JtYXRpb24gYW5kIGFueSBlcnJvci4KZnVuYyBwb3NpdGlvblVwZGF0ZSgKCXBvc2l0aW9uIHBsLlBvc2l0aW9uSW5mbywKCWxpcXVpZGl0eURlbHRhICppMjU2LkludCwKCWZlZUdyb3d0aEluc2lkZTBYMTI4ICp1MjU2LlVpbnQsCglmZWVHcm93dGhJbnNpZGUxWDEyOCAqdTI1Ni5VaW50LAopIChwbC5Qb3NpdGlvbkluZm8sIGVycm9yKSB7Cglpc1plcm9MaXF1aWRpdHlEZWx0YSA6PSBsaXF1aWRpdHlEZWx0YS5Jc1plcm8oKQoKCXBvc0xpcXVpZGl0eSA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChwb3NpdGlvbi5MaXF1aWRpdHkoKSkKCWlmIHBvc0xpcXVpZGl0eS5Jc1plcm8oKSAmJiBpc1plcm9MaXF1aWRpdHlEZWx0YSB7CgkJcmV0dXJuIHBsLk5ld0RlZmF1bHRQb3NpdGlvbkluZm8oKSwgbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyclplcm9MaXF1aWRpdHksCgkJCSJib3RoIGxpcXVpZGl0eURlbHRhIGFuZCBjdXJyZW50IHBvc2l0aW9uJ3MgbGlxdWlkaXR5IGFyZSB6ZXJvIiwKCQkpCgl9CgoJaWYgbGlxdWlkaXR5RGVsdGEuSXNOZWcoKSB7CgkJYWJzRGVsdGEgOj0gaTI1Ni5aZXJvKCkuU2V0KGxpcXVpZGl0eURlbHRhKS5BYnMoKQoJCWlmIGFic0RlbHRhLkd0KHBvc0xpcXVpZGl0eSkgewoJCQlyZXR1cm4gcGwuTmV3RGVmYXVsdFBvc2l0aW9uSW5mbygpLCBtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJCWVyclplcm9MaXF1aWRpdHksCgkJCQl1Zm10LlNwcmludGYoImxpcXVpZGl0eSBkZWx0YSglcykgaXMgZ3JlYXRlciB0aGFuIGN1cnJlbnQgbGlxdWlkaXR5KCVzKSIsCgkJCQkJbGlxdWlkaXR5RGVsdGEuVG9TdHJpbmcoKSwgcG9zTGlxdWlkaXR5LlRvU3RyaW5nKCkpLAoJCQkpCgkJfQoJfQoKCXZhciBsaXF1aWRpdHlOZXh0ICp1MjU2LlVpbnQKCWlmIGlzWmVyb0xpcXVpZGl0eURlbHRhIHsKCQlsaXF1aWRpdHlOZXh0ID0gcG9zTGlxdWlkaXR5Cgl9IGVsc2UgewoJCWxpcXVpZGl0eU5leHQgPSBnbnNtYXRoLkxpcXVpZGl0eU1hdGhBZGREZWx0YShwb3NMaXF1aWRpdHksIGxpcXVpZGl0eURlbHRhKQoJfQoKCWZlZUdyb3d0aExhc3QwIDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHBvc2l0aW9uLkZlZUdyb3d0aEluc2lkZTBMYXN0WDEyOCgpKQoJZmVlR3Jvd3RoTGFzdDEgOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwocG9zaXRpb24uRmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4KCkpCgoJZGlmZjAgOj0gdTI1Ni5aZXJvKCkuU3ViKGZlZUdyb3d0aEluc2lkZTBYMTI4LCBmZWVHcm93dGhMYXN0MCkKCWRpZmYxIDo9IHUyNTYuWmVybygpLlN1YihmZWVHcm93dGhJbnNpZGUxWDEyOCwgZmVlR3Jvd3RoTGFzdDEpCgoJdG9rZW5zT3dlZDAgOj0gdTI1Ni5aZXJvKCkKCWlmICFkaWZmMC5Jc1plcm8oKSB7CgkJdG9rZW5zT3dlZDAgPSB1MjU2Lk11bERpdihkaWZmMCwgcG9zTGlxdWlkaXR5LCBxMTI4RnJvbURlY2ltYWwpCgl9CgoJdG9rZW5zT3dlZDEgOj0gdTI1Ni5aZXJvKCkKCWlmICFkaWZmMS5Jc1plcm8oKSB7CgkJdG9rZW5zT3dlZDEgPSB1MjU2Lk11bERpdihkaWZmMSwgcG9zTGlxdWlkaXR5LCBxMTI4RnJvbURlY2ltYWwpCgl9CgoJaWYgIWlzWmVyb0xpcXVpZGl0eURlbHRhIHsKCQlwb3NpdGlvbi5TZXRMaXF1aWRpdHkobGlxdWlkaXR5TmV4dC5Ub1N0cmluZygpKQoJfQoKCXBvc2l0aW9uLlNldEZlZUdyb3d0aEluc2lkZTBMYXN0WDEyOChmZWVHcm93dGhJbnNpZGUwWDEyOC5Ub1N0cmluZygpKQoJcG9zaXRpb24uU2V0RmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4KGZlZUdyb3d0aEluc2lkZTFYMTI4LlRvU3RyaW5nKCkpCgoJaWYgdG9rZW5zT3dlZDAuR3QoemVybykgfHwgdG9rZW5zT3dlZDEuR3QoemVybykgewoJCW93ZWQwIDo9IGduc21hdGguU2FmZUFkZEludDY0KHBvc2l0aW9uLlRva2Vuc093ZWQwKCksIGduc21hdGguU2FmZUNvbnZlcnRUb0ludDY0KHRva2Vuc093ZWQwKSkKCQlvd2VkMSA6PSBnbnNtYXRoLlNhZmVBZGRJbnQ2NChwb3NpdGlvbi5Ub2tlbnNPd2VkMSgpLCBnbnNtYXRoLlNhZmVDb252ZXJ0VG9JbnQ2NCh0b2tlbnNPd2VkMSkpCgoJCXBvc2l0aW9uLlNldFRva2Vuc093ZWQwKG93ZWQwKQoJCXBvc2l0aW9uLlNldFRva2Vuc093ZWQxKG93ZWQxKQoJfQoKCXJldHVybiBwb3NpdGlvbiwgbmlsCn0KCi8vIGNhbGN1bGF0ZVRva2VuMEFtb3VudCBjYWxjdWxhdGVzIHRoZSBhbW91bnQgb2YgdG9rZW4wIGJhc2VkIG9uIHByaWNlIHJhbmdlIGFuZCBsaXF1aWRpdHkgZGVsdGEuCmZ1bmMgY2FsY3VsYXRlVG9rZW4wQW1vdW50KHNxcnRQcmljZUxvd2VyLCBzcXJ0UHJpY2VVcHBlciAqdTI1Ni5VaW50LCBsaXF1aWRpdHlEZWx0YSAqaTI1Ni5JbnQpICppMjU2LkludCB7CglyZXR1cm4gZ25zbWF0aC5HZXRBbW91bnQwRGVsdGEoc3FydFByaWNlTG93ZXIsIHNxcnRQcmljZVVwcGVyLCBsaXF1aWRpdHlEZWx0YSkKfQoKLy8gY2FsY3VsYXRlVG9rZW4xQW1vdW50IGNhbGN1bGF0ZXMgdGhlIGFtb3VudCBvZiB0b2tlbjEgYmFzZWQgb24gcHJpY2UgcmFuZ2UgYW5kIGxpcXVpZGl0eSBkZWx0YS4KZnVuYyBjYWxjdWxhdGVUb2tlbjFBbW91bnQoc3FydFByaWNlTG93ZXIsIHNxcnRQcmljZVVwcGVyICp1MjU2LlVpbnQsIGxpcXVpZGl0eURlbHRhICppMjU2LkludCkgKmkyNTYuSW50IHsKCXJldHVybiBnbnNtYXRoLkdldEFtb3VudDFEZWx0YShzcXJ0UHJpY2VMb3dlciwgc3FydFByaWNlVXBwZXIsIGxpcXVpZGl0eURlbHRhKQp9CgovLyBwb3NpdGlvblVwZGF0ZVdpdGhLZXkgdXBkYXRlcyBhIHBvc2l0aW9uIGluIHRoZSBwb29sIGFuZCByZXR1cm5zIHRoZSB1cGRhdGVkIHBvc2l0aW9uLgpmdW5jIHBvc2l0aW9uVXBkYXRlV2l0aEtleSgKCXAgKnBsLlBvb2wsCglwb3NpdGlvbktleSBzdHJpbmcsCglsaXF1aWRpdHlEZWx0YSAqaTI1Ni5JbnQsCglmZWVHcm93dGhJbnNpZGUwWDEyOCwgZmVlR3Jvd3RoSW5zaWRlMVgxMjggKnUyNTYuVWludCwKKSAocGwuUG9zaXRpb25JbmZvLCBlcnJvcikgewoJLy8gaWYgcG9zaXRpb24gZG9lcyBub3QgZXhpc3QsIGNyZWF0ZSBhIG5ldyBwb3NpdGlvbgoJLy8KCS8vIE5vdGU6IFRoZSBwb3NpdGlvblVwZGF0ZSBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBoYW5kbGUgYm90aCBuZXcgcG9zaXRpb25zIGFuZCBleGlzdGluZyBwb3NpdGlvbnMsCgkvLyBzbyB0aGVyZSdzIG5vIG5lZWQgdG8gY2hlY2sgZm9yIGV4aXN0ZW5jZSBpbiBHZXRQb3NpdGlvbi4KCXBvc2l0aW9uVG9VcGRhdGUsIGVyciA6PSBwLkdldFBvc2l0aW9uKHBvc2l0aW9uS2V5KQoJaWYgZXJyICE9IG5pbCB7CgkJcG9zaXRpb25Ub1VwZGF0ZSA9IHBsLk5ld0RlZmF1bHRQb3NpdGlvbkluZm8oKQoJfQoKCXBvc2l0aW9uQWZ0ZXJVcGRhdGUsIGVyciA6PSBwb3NpdGlvblVwZGF0ZShwb3NpdGlvblRvVXBkYXRlLCBsaXF1aWRpdHlEZWx0YSwgZmVlR3Jvd3RoSW5zaWRlMFgxMjgsIGZlZUdyb3d0aEluc2lkZTFYMTI4KQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIHBsLk5ld0RlZmF1bHRQb3NpdGlvbkluZm8oKSwgZXJyCgl9CgoJc2V0UG9zaXRpb24ocCwgcG9zaXRpb25LZXksIHBvc2l0aW9uQWZ0ZXJVcGRhdGUpCgoJcmV0dXJuIHBvc2l0aW9uQWZ0ZXJVcGRhdGUsIG5pbAp9CgovLyBzZXRQb3NpdGlvbiBzZXRzIHRoZSBwb3NpdGlvbiBpbmZvIGZvciBhIGdpdmVuIGtleS4KZnVuYyBzZXRQb3NpdGlvbihwICpwbC5Qb29sLCBwb3NLZXkgc3RyaW5nLCBwb3NpdGlvbkluZm8gcGwuUG9zaXRpb25JbmZvKSB7CglwLlNldFBvc2l0aW9uKHBvc0tleSwgcG9zaXRpb25JbmZvKQp9CgovLyBtb2RpZnlQb3NpdGlvbiB1cGRhdGVzIGEgcG9zaXRpb24gaW4gdGhlIHBvb2wgYW5kIGNhbGN1bGF0ZXMgdGhlIGFtb3VudCBvZiB0b2tlbnMKLy8gbmVlZGVkIChmb3IgbWludGluZykgb3IgcmV0dXJuZWQgKGZvciBidXJuaW5nKS4gVGhlIGNhbGN1bGF0aW9uIGRlcGVuZHMgb24gdGhlIGN1cnJlbnQKLy8gcHJpY2UgKHRpY2spIHJlbGF0aXZlIHRvIHRoZSBwb3NpdGlvbidzIHByaWNlIHJhbmdlLgovLwovLyBUaGUgZnVuY3Rpb24gaGFuZGxlcyB0aHJlZSBjYXNlczoKLy8gIDEuIEN1cnJlbnQgcHJpY2UgYmVsb3cgcmFuZ2UgKHRpY2sgPCB0aWNrTG93ZXIpOiBvbmx5IHRva2VuMCBpcyB1c2VkL3JldHVybmVkCi8vICAyLiBDdXJyZW50IHByaWNlIGluIHJhbmdlICh0aWNrTG93ZXIgPD0gdGljayA8IHRpY2tVcHBlcik6IGJvdGggdG9rZW5zIGFyZSB1c2VkL3JldHVybmVkCi8vICAzLiBDdXJyZW50IHByaWNlIGFib3ZlIHJhbmdlICh0aWNrID49IHRpY2tVcHBlcik6IG9ubHkgdG9rZW4xIGlzIHVzZWQvcmV0dXJuZWQKLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBhcmFtczogTW9kaWZ5UG9zaXRpb25QYXJhbXMgY29udGFpbmluZyBvd25lciwgdGlja0xvd2VyLCB0aWNrVXBwZXIsIGFuZCBsaXF1aWRpdHlEZWx0YQovLwovLyBSZXR1cm5zOgovLyAgIC0gUG9zaXRpb25JbmZvOiB1cGRhdGVkIHBvc2l0aW9uIGluZm9ybWF0aW9uCi8vICAgLSAqdTI1Ni5VaW50OiBhbW91bnQgb2YgdG9rZW4wIG5lZWRlZC9yZXR1cm5lZAovLyAgIC0gKnUyNTYuVWludDogYW1vdW50IG9mIHRva2VuMSBuZWVkZWQvcmV0dXJuZWQKZnVuYyBtb2RpZnlQb3NpdGlvbihwICpwbC5Qb29sLCBvYnNlcnZhdGlvbnMgKnBsLk9ic2VydmF0aW9uVHJlZSwgcGFyYW1zIE1vZGlmeVBvc2l0aW9uUGFyYW1zKSAocGwuUG9zaXRpb25JbmZvLCAqdTI1Ni5VaW50LCAqdTI1Ni5VaW50LCBlcnJvcikgewoJaWYgZXJyIDo9IHZhbGlkYXRlVGlja3MocGFyYW1zLnRpY2tMb3dlciwgcGFyYW1zLnRpY2tVcHBlcik7IGVyciAhPSBuaWwgewoJCXJldHVybiBwbC5OZXdEZWZhdWx0UG9zaXRpb25JbmZvKCksIHplcm8sIHplcm8sIGVycgoJfQoKCS8vIGdldCBjdXJyZW50IHN0YXRlIGFuZCBwcmljZSBib3VuZHMKCXRpY2sgOj0gcC5TbG90MFRpY2soKQoJLy8gdXBkYXRlIHBvc2l0aW9uIHN0YXRlCglwb3NpdGlvbiwgZXJyIDo9IHVwZGF0ZVBvc2l0aW9uKHAsIG9ic2VydmF0aW9ucywgcGFyYW1zLCB0aWNrKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIHBsLk5ld0RlZmF1bHRQb3NpdGlvbkluZm8oKSwgemVybywgemVybywgZXJyCgl9CgoJbGlxRGVsdGEgOj0gcGFyYW1zLmxpcXVpZGl0eURlbHRhCglpZiBsaXFEZWx0YS5Jc1plcm8oKSB7CgkJcmV0dXJuIHBvc2l0aW9uLCB6ZXJvLCB6ZXJvLCBuaWwKCX0KCglhbW91bnQwLCBhbW91bnQxIDo9IGkyNTYuWmVybygpLCBpMjU2Llplcm8oKQoKCS8vIGNvdmVydCB0aWNrcyB0byBzcXJ0IHByaWNlIHRvIHVzZSBpbiBhbW91bnQgY2FsY3VsYXRpb25zCgkvLyBwcmljZSA9IDEuMDAwMV50aWNrLCBidXQgd2UgdXNlIHNxcnRQcmljZVg5NgoJc3FydFJhdGlvTG93ZXIgOj0gZ25zbWF0aC5UaWNrTWF0aEdldFNxcnRSYXRpb0F0VGljayhwYXJhbXMudGlja0xvd2VyKQoJc3FydFJhdGlvVXBwZXIgOj0gZ25zbWF0aC5UaWNrTWF0aEdldFNxcnRSYXRpb0F0VGljayhwYXJhbXMudGlja1VwcGVyKQoJc3FydFByaWNlWDk2IDo9IHAuU2xvdDBTcXJ0UHJpY2VYOTYoKQoKCS8vIGNhbGN1bGF0ZSB0b2tlbiBhbW91bnRzIGJhc2VkIG9uIGN1cnJlbnQgcHJpY2UgcG9zaXRpb24gcmVsYXRpdmUgdG8gcmFuZ2UKCXN3aXRjaCB7CgljYXNlIHRpY2sgPCBwYXJhbXMudGlja0xvd2VyOgoJCS8vIGNhc2UgMQoJCS8vIGZ1bGwgcmFuZ2UgYmV0d2VlbiBsb3dlciBhbmQgdXBwZXIgdGljayBpcyB1c2VkIGZvciB0b2tlbjAKCQkvLyBjdXJyZW50IHRpY2sgaXMgYmVsb3cgdGhlIHBhc3NlZCByYW5nZTsgbGlxdWlkaXR5IGNhbiBvbmx5IGJlY29tZSBpbiByYW5nZSBieSBjcm9zc2luZyBmcm9tIGxlZnQgdG8KCQkvLyByaWdodCwgd2hlbiB3ZSdsbCBuZWVkIF9tb3JlXyB0b2tlbjAgKGl0J3MgYmVjb21pbmcgbW9yZSB2YWx1YWJsZSkgc28gdXNlciBtdXN0IHByb3ZpZGUgaXQKCQlhbW91bnQwID0gY2FsY3VsYXRlVG9rZW4wQW1vdW50KHNxcnRSYXRpb0xvd2VyLCBzcXJ0UmF0aW9VcHBlciwgbGlxRGVsdGEpCgoJY2FzZSB0aWNrIDwgcGFyYW1zLnRpY2tVcHBlcjoKCQkvLyBjYXNlIDI6IEN1cnJlbnQgcHJpY2UgaXMgd2l0aGluIHRoZSBwb3NpdGlvbiByYW5nZQoJCWxpcXVpZGl0eUJlZm9yZSA6PSBwLkxpcXVpZGl0eSgpCgkJY3VycmVudFRpbWUgOj0gdGltZS5Ob3coKS5Vbml4KCkKCQkvLyBVcGRhdGUgb3JhY2xlIEJFRk9SRSBsaXF1aWRpdHkgY2hhbmdlcwoJCWlmIG9ic2VydmF0aW9ucyA9PSBuaWwgewoJCQlyZXR1cm4gcGwuTmV3RGVmYXVsdFBvc2l0aW9uSW5mbygpLCB6ZXJvLCB6ZXJvLCBlcnJvcnMuTmV3KCJvYnNlcnZhdGlvbnMgbm90IGluaXRpYWxpemVkIikKCQl9CgkJc2xvdDAgOj0gcC5TbG90MCgpCgkJb2JzZXJ2YXRpb25JbmRleCwgb2JzZXJ2YXRpb25DYXJkaW5hbGl0eSwgZXJyIDo9IHdyaXRlT2JzZXJ2YXRpb24oCgkJCW9ic2VydmF0aW9ucywKCQkJc2xvdDAuT2JzZXJ2YXRpb25JbmRleCgpLAoJCQljdXJyZW50VGltZSwKCQkJdGljaywKCQkJbGlxdWlkaXR5QmVmb3JlLAoJCQlzbG90MC5PYnNlcnZhdGlvbkNhcmRpbmFsaXR5KCksCgkJCXNsb3QwLk9ic2VydmF0aW9uQ2FyZGluYWxpdHlOZXh0KCksCgkJKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gcGwuTmV3RGVmYXVsdFBvc2l0aW9uSW5mbygpLCB6ZXJvLCB6ZXJvLCBlcnIKCQl9CgkJc2xvdDAuU2V0T2JzZXJ2YXRpb25JbmRleChvYnNlcnZhdGlvbkluZGV4KQoJCXNsb3QwLlNldE9ic2VydmF0aW9uQ2FyZGluYWxpdHkob2JzZXJ2YXRpb25DYXJkaW5hbGl0eSkKCQlwLlNldFNsb3QwKHNsb3QwKQoKCQkvLyB0b2tlbjAgdXNlZCBmcm9tIGN1cnJlbnQgcHJpY2UgdG8gdXBwZXIgdGljawoJCWFtb3VudDAgPSBjYWxjdWxhdGVUb2tlbjBBbW91bnQoc3FydFByaWNlWDk2LCBzcXJ0UmF0aW9VcHBlciwgbGlxRGVsdGEpCgkJLy8gdG9rZW4xIHVzZWQgZnJvbSBsb3dlciB0aWNrIHRvIGN1cnJlbnQgcHJpY2UKCQlhbW91bnQxID0gY2FsY3VsYXRlVG9rZW4xQW1vdW50KHNxcnRSYXRpb0xvd2VyLCBzcXJ0UHJpY2VYOTYsIGxpcURlbHRhKQoJCS8vIHVwZGF0ZSBwb29sJ3MgYWN0aXZlIGxpcXVpZGl0eSBzaW5jZSBwcmljZSBpcyBpbiByYW5nZQoJCXAuU2V0TGlxdWlkaXR5KGduc21hdGguTGlxdWlkaXR5TWF0aEFkZERlbHRhKGxpcXVpZGl0eUJlZm9yZSwgbGlxRGVsdGEpKQoKCWRlZmF1bHQ6CgkJLy8gY2FzZSAzCgkJLy8gZnVsbCByYW5nZSBiZXR3ZWVuIGxvd2VyIGFuZCB1cHBlciB0aWNrIGlzIHVzZWQgZm9yIHRva2VuMQoJCS8vIGN1cnJlbnQgdGljayBpcyBhYm92ZSB0aGUgcGFzc2VkIHJhbmdlOyBsaXF1aWRpdHkgY2FuIG9ubHkgYmVjb21lIGluIHJhbmdlIGJ5IGNyb3NzaW5nIGZyb20gcmlnaHQgdG8KCQkvLyBsZWZ0LCB3aGVuIHdlJ2xsIG5lZWQgX21vcmVfIHRva2VuMSAoaXQncyBiZWNvbWluZyBtb3JlIHZhbHVhYmxlKSBzbyB1c2VyIG11c3QgcHJvdmlkZSBpdAoJCWFtb3VudDEgPSBjYWxjdWxhdGVUb2tlbjFBbW91bnQoc3FydFJhdGlvTG93ZXIsIHNxcnRSYXRpb1VwcGVyLCBsaXFEZWx0YSkKCX0KCglyZXR1cm4gcG9zaXRpb24sIGFtb3VudDAuQWJzKCksIGFtb3VudDEuQWJzKCksIG5pbAp9CgovLyB1cGRhdGVQb3NpdGlvbiBtb2RpZmllcyB0aGUgcG9zaXRpb24ncyBsaXF1aWRpdHkgYW5kIHVwZGF0ZXMgdGhlIGNvcnJlc3BvbmRpbmcgdGljayBzdGF0ZXMuCi8vCi8vIFRoaXMgZnVuY3Rpb24gdXBkYXRlcyB0aGUgcG9zaXRpb24gZGF0YSBiYXNlZCBvbiB0aGUgc3BlY2lmaWVkIGxpcXVpZGl0eSBkZWx0YSBhbmQgdGljayByYW5nZS4KLy8gSXQgYWxzbyBtYW5hZ2VzIHRoZSBmZWUgZ3Jvd3RoLCB0aWNrIHN0YXRlIGZsaXBwaW5nLCBhbmQgY2xlYW51cCBvZiB1bnVzZWQgdGljayBkYXRhLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9zaXRpb25QYXJhbXM6IE1vZGlmeVBvc2l0aW9uUGFyYW1zLCB0aGUgcGFyYW1ldGVycyBmb3IgdGhlIHBvc2l0aW9uIG1vZGlmaWNhdGlvbiwgd2hpY2ggaW5jbHVkZToKLy8gICAtIG93bmVyOiBUaGUgYWRkcmVzcyBvZiB0aGUgcG9zaXRpb24gb3duZXIuCi8vICAgLSB0aWNrTG93ZXI6IFRoZSBsb3dlciB0aWNrIGJvdW5kYXJ5IG9mIHRoZSBwb3NpdGlvbi4KLy8gICAtIHRpY2tVcHBlcjogVGhlIHVwcGVyIHRpY2sgYm91bmRhcnkgb2YgdGhlIHBvc2l0aW9uLgovLyAgIC0gbGlxdWlkaXR5RGVsdGE6IFRoZSBjaGFuZ2UgaW4gbGlxdWlkaXR5IChwb3NpdGl2ZSBvciBuZWdhdGl2ZSkuCi8vICAgLSB0aWNrOiBpbnQzMiwgdGhlIGN1cnJlbnQgdGljayBwb3NpdGlvbi4KLy8KLy8gUmV0dXJuczoKLy8gICAtIFBvc2l0aW9uSW5mbzogVGhlIHVwZGF0ZWQgcG9zaXRpb24gaW5mb3JtYXRpb24uCi8vCi8vIFdvcmtmbG93OgovLyAgMS4gQ2xvbmUgdGhlIGdsb2JhbCBmZWUgZ3Jvd3RoIHZhbHVlcyAodG9rZW4gMCBhbmQgdG9rZW4gMSkuCi8vICAyLiBJZiB0aGUgbGlxdWlkaXR5IGRlbHRhIGlzIG5vbi16ZXJvOgovLyAgICAgLSBVcGRhdGUgdGhlIGxvd2VyIGFuZCB1cHBlciB0aWNrcyB1c2luZyBgdGlja1VwZGF0ZWAsIGZsaXBwaW5nIHRoZWlyIHN0YXRlcyBpZiBuZWNlc3NhcnkuCi8vICAgICAtIElmIGEgdGljaydzIHN0YXRlIHdhcyBmbGlwcGVkLCB1cGRhdGUgdGhlIHRpY2sgYml0bWFwIHRvIHJlZmxlY3QgdGhlIG5ldyBzdGF0ZS4KLy8gIDMuIENhbGN1bGF0ZSB0aGUgZmVlIGdyb3d0aCBpbnNpZGUgdGhlIHRpY2sgcmFuZ2UgdXNpbmcgYGdldEZlZUdyb3d0aEluc2lkZWAuCi8vICA0LiBHZW5lcmF0ZSBhIHVuaXF1ZSBwb3NpdGlvbiBrZXkgYW5kIHVwZGF0ZSB0aGUgcG9zaXRpb24gZGF0YSB1c2luZyBgcG9zaXRpb25VcGRhdGVXaXRoS2V5YC4KLy8gIDUuIElmIGxpcXVpZGl0eSBpcyBiZWluZyByZW1vdmVkIChuZWdhdGl2ZSBkZWx0YSksIGNsZWFuIHVwIHVudXNlZCB0aWNrIGRhdGEgYnkgZGVsZXRpbmcgdGhlIHRpY2sgZW50cmllcy4KLy8gIDYuIFJldHVybiB0aGUgdXBkYXRlZCBwb3NpdGlvbi4KLy8KLy8gTm90ZXM6Ci8vICAgLSBUaGUgZnVuY3Rpb24gZmxpcHMgdGhlIHRpY2sgc3RhdGVzIGFuZCBjbGVhbnMgdXAgdW51c2VkIHRpY2sgZGF0YSB3aGVuIGxpcXVpZGl0eSBpcyByZW1vdmVkLgovLyAgIC0gSXQgZW5zdXJlcyBmZWUgZ3Jvd3RoIGFuZCBwb3NpdGlvbiBkYXRhIHJlbWFpbiBhY2N1cmF0ZSBhZnRlciB0aGUgdXBkYXRlLgovLwovLyBFeGFtcGxlIFVzYWdlOgovLwovLyBgYGBnbm8KLy8KLy8JdXBkYXRlZFBvc2l0aW9uIDo9IHBvb2wudXBkYXRlUG9zaXRpb24ocG9zaXRpb25QYXJhbXMsIGN1cnJlbnRUaWNrKQovLwlwcmludGxuKCJVcGRhdGVkIFBvc2l0aW9uIEluZm86IiwgdXBkYXRlZFBvc2l0aW9uKQovLwovLyBgYGAKZnVuYyB1cGRhdGVQb3NpdGlvbihwICpwbC5Qb29sLCBvYnNlcnZhdGlvbnMgKnBsLk9ic2VydmF0aW9uVHJlZSwgcG9zaXRpb25QYXJhbXMgTW9kaWZ5UG9zaXRpb25QYXJhbXMsIHRpY2sgaW50MzIpIChwbC5Qb3NpdGlvbkluZm8sIGVycm9yKSB7CglmZWVHcm93dGhHbG9iYWwwWDEyOCA6PSBwLkZlZUdyb3d0aEdsb2JhbDBYMTI4KCkuQ2xvbmUoKQoJZmVlR3Jvd3RoR2xvYmFsMVgxMjggOj0gcC5GZWVHcm93dGhHbG9iYWwxWDEyOCgpLkNsb25lKCkKCWxpcXVpZGl0eURlbHRhIDo9IHBvc2l0aW9uUGFyYW1zLmxpcXVpZGl0eURlbHRhCgoJdmFyIGZsaXBwZWRMb3dlciwgZmxpcHBlZFVwcGVyIGJvb2wKCWlmICFsaXF1aWRpdHlEZWx0YS5Jc1plcm8oKSB7CgkJYmxvY2tUaW1lc3RhbXAgOj0gdGltZS5Ob3coKS5Vbml4KCkKCQlpZiBvYnNlcnZhdGlvbnMgPT0gbmlsIHsKCQkJcmV0dXJuIHBsLk5ld0RlZmF1bHRQb3NpdGlvbkluZm8oKSwgZXJyb3JzLk5ldygib2JzZXJ2YXRpb25zIG5vdCBpbml0aWFsaXplZCIpCgkJfQoJCXNsb3QwIDo9IHAuU2xvdDAoKQoJCXRpY2tDdW11bGF0aXZlLCBzZWNvbmRzUGVyTGlxdWlkaXR5U3RyLCBlcnIgOj0gb2JzZXJ2ZVNpbmdsZSgKCQkJb2JzZXJ2YXRpb25zLAoJCQlibG9ja1RpbWVzdGFtcCwKCQkJMCwKCQkJc2xvdDAuVGljaygpLAoJCQlzbG90MC5PYnNlcnZhdGlvbkluZGV4KCksCgkJCXAuTGlxdWlkaXR5KCksCgkJCXNsb3QwLk9ic2VydmF0aW9uQ2FyZGluYWxpdHkoKSwKCQkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBwbC5OZXdEZWZhdWx0UG9zaXRpb25JbmZvKCksIGVycgoJCX0KCgkJc2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHNlY29uZHNQZXJMaXF1aWRpdHlTdHIpCgoJCWZsaXBwZWRMb3dlciA9IHRpY2tVcGRhdGUoCgkJCXAsCgkJCXBvc2l0aW9uUGFyYW1zLnRpY2tMb3dlciwKCQkJdGljaywKCQkJbGlxdWlkaXR5RGVsdGEsCgkJCWZlZUdyb3d0aEdsb2JhbDBYMTI4LAoJCQlmZWVHcm93dGhHbG9iYWwxWDEyOCwKCQkJc2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4LAoJCQl0aWNrQ3VtdWxhdGl2ZSwKCQkJYmxvY2tUaW1lc3RhbXAsCgkJCWZhbHNlLAoJCQljYWxjdWxhdGVNYXhMaXF1aWRpdHlQZXJUaWNrKHAuVGlja1NwYWNpbmcoKSksCgkJKQoKCQlmbGlwcGVkVXBwZXIgPSB0aWNrVXBkYXRlKAoJCQlwLAoJCQlwb3NpdGlvblBhcmFtcy50aWNrVXBwZXIsCgkJCXRpY2ssCgkJCWxpcXVpZGl0eURlbHRhLAoJCQlmZWVHcm93dGhHbG9iYWwwWDEyOCwKCQkJZmVlR3Jvd3RoR2xvYmFsMVgxMjgsCgkJCXNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCwKCQkJdGlja0N1bXVsYXRpdmUsCgkJCWJsb2NrVGltZXN0YW1wLAoJCQl0cnVlLAoJCQljYWxjdWxhdGVNYXhMaXF1aWRpdHlQZXJUaWNrKHAuVGlja1NwYWNpbmcoKSksCgkJKQoKCQlpZiBmbGlwcGVkTG93ZXIgewoJCQl0aWNrQml0bWFwRmxpcFRpY2socCwgcG9zaXRpb25QYXJhbXMudGlja0xvd2VyLCBwLlRpY2tTcGFjaW5nKCkpCgkJfQoKCQlpZiBmbGlwcGVkVXBwZXIgewoJCQl0aWNrQml0bWFwRmxpcFRpY2socCwgcG9zaXRpb25QYXJhbXMudGlja1VwcGVyLCBwLlRpY2tTcGFjaW5nKCkpCgkJfQoJfQoKCWZlZUdyb3d0aEluc2lkZTBYMTI4LCBmZWVHcm93dGhJbnNpZGUxWDEyOCA6PSBnZXRGZWVHcm93dGhJbnNpZGUoCgkJcCwKCQlwb3NpdGlvblBhcmFtcy50aWNrTG93ZXIsCgkJcG9zaXRpb25QYXJhbXMudGlja1VwcGVyLAoJCXRpY2ssCgkJZmVlR3Jvd3RoR2xvYmFsMFgxMjgsCgkJZmVlR3Jvd3RoR2xvYmFsMVgxMjgsCgkpCgoJcG9zaXRpb25LZXkgOj0gZ2V0UG9zaXRpb25LZXkocG9zaXRpb25QYXJhbXMudGlja0xvd2VyLCBwb3NpdGlvblBhcmFtcy50aWNrVXBwZXIpCgoJcG9zaXRpb24sIGVyciA6PSBwb3NpdGlvblVwZGF0ZVdpdGhLZXkoCgkJcCwKCQlwb3NpdGlvbktleSwKCQlsaXF1aWRpdHlEZWx0YSwKCQlmZWVHcm93dGhJbnNpZGUwWDEyOC5DbG9uZSgpLAoJCWZlZUdyb3d0aEluc2lkZTFYMTI4LkNsb25lKCksCgkpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gcGwuTmV3RGVmYXVsdFBvc2l0aW9uSW5mbygpLCBlcnIKCX0KCgkvLyBjbGVhciBhbnkgdGljayBkYXRhIHRoYXQgaXMgbm8gbG9uZ2VyIG5lZWRlZAoJaWYgbGlxdWlkaXR5RGVsdGEuSXNOZWcoKSB7CgkJaWYgZmxpcHBlZExvd2VyIHsKCQkJZGVsZXRlVGljayhwLCBwb3NpdGlvblBhcmFtcy50aWNrTG93ZXIpCgkJfQoJCWlmIGZsaXBwZWRVcHBlciB7CgkJCWRlbGV0ZVRpY2socCwgcG9zaXRpb25QYXJhbXMudGlja1VwcGVyKQoJCX0KCX0KCglyZXR1cm4gcG9zaXRpb24sIG5pbAp9ChrTNQoQcHJvdG9jb2xfZmVlLmdubxK+NXBhY2thZ2UgcG9vbAoKaW1wb3J0ICgKCSJjaGFpbiIKCSJlcnJvcnMiCgoJImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJcHJhYmMgImduby5sYW5kL3AvZ25vc3dhcC9yYmFjL3YxIgoJdTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL3VpbnQyNTYvdjEiCgkiZ25vLmxhbmQvcC9nbm9zd2FwL3V0aWxzL3YxIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvYWNjZXNzL3YxIgoJImduby5sYW5kL3IvZ25vc3dhcC9jb21tb24iCgkiZ25vLmxhbmQvci9nbm9zd2FwL2hhbHQvdjEiCglwZiAiZ25vLmxhbmQvci9nbm9zd2FwL3Byb3RvY29sX2ZlZSIKKQoKY29uc3QgKAoJTWF4QnBzVmFsdWUgPSB1aW50NjQoMTAwMCkgLy8gMTAlCglaZXJvQnBzICAgICA9IHVpbnQ2NCgwKQopCgovLyBkZWR1Y3RXaXRoZHJhd2FsRmVlIHNwbGl0cyBhbW91bnQgaW50byB0aGUgZmVlIHdpdGhoZWxkIGZvciB0aGUgcHJvdG9jb2wgYW5kCi8vIHRoZSByZW1haW5kZXIgcGFpZCBvdXQgdG8gdGhlIGNvbGxlY3Rvci4KLy8KLy8gUm91bmRpbmcgZmF2b3VycyB0aGUgY29sbGVjdG9yOiB0aGUgZmVlIGlzIHRydW5jYXRlZC4gVGhlIHR3byByZXN1bHRzIGFsd2F5cwovLyBzdW0gYmFjayB0byBhbW91bnQsIHNvIGEgY2FsbGVyIHRoYXQgZGViaXRzIGFtb3VudCBhbmQgcGF5cyBvdXQKLy8gYW1vdW50QWZ0ZXJGZWUgbmV2ZXIgbGVhdmVzIHRoZSBwb29sIHNob3J0LgpmdW5jIGRlZHVjdFdpdGhkcmF3YWxGZWUoYW1vdW50IGludDY0LCB3aXRoZHJhd2FsRmVlQlBTIHVpbnQ2NCkgKGZlZUFtb3VudCwgYW1vdW50QWZ0ZXJGZWUgaW50NjQpIHsKCWlmIGFtb3VudCA8PSAwIHx8IHdpdGhkcmF3YWxGZWVCUFMgPT0gWmVyb0JwcyB7CgkJcmV0dXJuIDAsIGFtb3VudAoJfQoKCWZlZSwgYWZ0ZXJGZWUgOj0gY2FsY3VsYXRlQW1vdW50V2l0aEZlZSgKCQl1MjU2Lk5ld1VpbnQodWludDY0KGFtb3VudCkpLAoJCXUyNTYuTmV3VWludCh3aXRoZHJhd2FsRmVlQlBTKSwKCSkKCglyZXR1cm4gZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQoZmVlKSwgZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQoYWZ0ZXJGZWUpCn0KCi8vIEdldFBlbmRpbmdQcm90b2NvbEZlZXMgcmV0dXJucyB0aGUgcGVuZGluZyBwcm90b2NvbCBmZWUgYW1vdW50IHBlciB0b2tlbiBwYXRoLgovLwovLyBSZXR1cm5zOgovLyAgIC0gbWFwW3N0cmluZ11pbnQ2NDogUGVuZGluZyBwcm90b2NvbCBmZWUgYW1vdW50cyBrZXllZCBieSB0b2tlbiBjb250cmFjdAovLyAgICAgcGF0aCwgd2l0aCB2YWx1ZXMgaW4gdG9rZW4gYmFzZSB1bml0cy4KZnVuYyAoaSAqcG9vbFYxKSBHZXRQZW5kaW5nUHJvdG9jb2xGZWVzKCkgbWFwW3N0cmluZ11pbnQ2NCB7CglyZXR1cm4gaS5zdG9yZS5HZXRQZW5kaW5nUHJvdG9jb2xGZWVzKCkKfQoKZnVuYyAoaSAqcG9vbFYxKSBhZGRQZW5kaW5nUHJvdG9jb2xGZWUoXyBpbnQsIHJsbSByZWFsbSwgdG9rZW5QYXRoIHN0cmluZywgYW1vdW50IGludDY0KSB7CglpZiBhbW91bnQgPD0gMCB7CgkJcmV0dXJuCgl9CgoJcGVuZGluZ0Ftb3VudCA6PSBnbnNtYXRoLlNhZmVBZGRJbnQ2NChpLnN0b3JlLkdldFBlbmRpbmdQcm90b2NvbEZlZSh0b2tlblBhdGgpLCBhbW91bnQpCglpZiBlcnIgOj0gaS5zdG9yZS5TZXRQZW5kaW5nUHJvdG9jb2xGZWUoMCwgcmxtLCB0b2tlblBhdGgsIHBlbmRpbmdBbW91bnQpOyBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9Cn0KCi8vIHNldHRsZVByb3RvY29sRmVlIGZvcndhcmRzIGFtb3VudCwgcGx1cyBhbnl0aGluZyBhbHJlYWR5IHBlbmRpbmcgZm9yIHRva2VuUGF0aCwgdG8KLy8gdGhlIHByb3RvY29sIGZlZSByZWFsbS4gV2hlbiBjb2xsZWN0aW9uIGlzIGhhbHRlZCBvciB0aGUgdHJhbnNmZXIgZmFpbHMsIHRoZSBhbW91bnQKLy8gaXMgcmVjb3JkZWQgYXMgcGVuZGluZyBpbnN0ZWFkIGFuZCBzZXR0bGVkIGJ5IGEgbGF0ZXIgY2FsbCBmb3IgdGhlIHNhbWUgdG9rZW4sIHdoaWNoCi8vIGV2ZXJ5IGZlZSBwYXRoIG1ha2VzIGV2ZW4gd2hlbiB0aGUgZmVlIGlzIHplcm8uCi8vCi8vIE9ubHkgdG9rZW5QYXRoIGlzIHRvdWNoZWQsIHNvIGFuIHVucmVsYXRlZCB0b2tlbiBjYW4gbmV2ZXIgYmxvY2sgc2V0dGxlbWVudC4gVGhlCi8vIHBlbmRpbmcgZW50cnkgaXMgd3JpdHRlbiBvbmx5IHdoZW4gdGhlIGZlZSBjYW5ub3QgYmUgZm9yd2FyZGVkLCBzbyB0aGUgY29tbW9uIHBhdGgKLy8gcGVyZm9ybXMgbm8gc3RvcmUgd3JpdGUgYXQgYWxsLgpmdW5jIChpICpwb29sVjEpIHNldHRsZVByb3RvY29sRmVlKF8gaW50LCBybG0gcmVhbG0sIHRva2VuUGF0aCBzdHJpbmcsIGFtb3VudCBpbnQ2NCkgewoJaWYgaGFsdC5Jc0hhbHRlZFByb3RvY29sRmVlKCkgewoJCWkuYWRkUGVuZGluZ1Byb3RvY29sRmVlKDAsIHJsbSwgdG9rZW5QYXRoLCBhbW91bnQpCgkJcmV0dXJuCgl9CgoJcGVuZGluZ0Ftb3VudCA6PSBpLnN0b3JlLkdldFBlbmRpbmdQcm90b2NvbEZlZSh0b2tlblBhdGgpCgl0b3RhbEFtb3VudCA6PSBnbnNtYXRoLlNhZmVBZGRJbnQ2NChwZW5kaW5nQW1vdW50LCBhbW91bnQpCgoJaWYgdG90YWxBbW91bnQgPiAwIHsKCQlwcm90b2NvbEZlZUFkZHIgOj0gYWNjZXNzLk11c3RHZXRBZGRyZXNzKHByYWJjLlJPTEVfUFJPVE9DT0xfRkVFLlN0cmluZygpKQoJCWNvbW1vbi5TYWZlR1JDMjBBcHByb3ZlKDAsIHJsbSwgdG9rZW5QYXRoLCBwcm90b2NvbEZlZUFkZHIsIHRvdGFsQW1vdW50KQoKCQkvLyBBZGRUb1Byb3RvY29sRmVlIG9ubHkgcmVwb3J0cyBhbiBlcnJvciBmb3IgYSBoYWx0ZWQgcmVhbG0sIHdoaWNoIGlzIGhhbmRsZWQKCQkvLyBhYm92ZS4gVGhlIGJyYW5jaCBrZWVwcyB0aGUgYW1vdW50IHBlbmRpbmcgc2hvdWxkIHRoYXQgZXZlciBjaGFuZ2UsIGFuZAoJCS8vIHdpdGhkcmF3cyB0aGUgYXBwcm92YWwgc28gbm8gdW5zcGVudCBhbGxvd2FuY2Ugb3V0bGl2ZXMgdGhlIGNhbGwuCgkJaWYgZXJyIDo9IHBmLkFkZFRvUHJvdG9jb2xGZWUoY3Jvc3MocmxtKSwgdG9rZW5QYXRoLCB0b3RhbEFtb3VudCk7IGVyciAhPSBuaWwgewoJCQljb21tb24uU2FmZUdSQzIwQXBwcm92ZSgwLCBybG0sIHRva2VuUGF0aCwgcHJvdG9jb2xGZWVBZGRyLCAwKQoJCQlpLmFkZFBlbmRpbmdQcm90b2NvbEZlZSgwLCBybG0sIHRva2VuUGF0aCwgYW1vdW50KQoJCQlyZXR1cm4KCQl9Cgl9CgoJaWYgZXJyIDo9IGkuc3RvcmUuUmVtb3ZlUGVuZGluZ1Byb3RvY29sRmVlKDAsIHJsbSwgdG9rZW5QYXRoKTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQp9CgovLyBTZXRQb29sQ3JlYXRpb25GZWUgc2V0cyB0aGUgcG9vbENyZWF0aW9uRmVlLgovLyBPbmx5IGFkbWluIG9yIGdvdmVybmFuY2UgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IExlYWRpbmcgaW50ZWdlciBkaXNjcmltaW5hdG9yIGZvciB0aGUgZm9yd2FyZGVkIHJlYWxtIGNhbGw7IGNhbGxlcnMKLy8gICAgIHBhc3MgMC4KLy8gICAtIHJsbTogUHJvcGFnYXRlZCByZWFsbSBjb250ZXh0IHZhbGlkYXRlZCBhcyBjdXJyZW50IGJlZm9yZSB0aGUgZmVlIGlzCi8vICAgICB3cml0dGVuLgovLyAgIC0gZmVlOiBOZXcgbm9uLW5lZ2F0aXZlIHBvb2wgY3JlYXRpb24gZmVlIGluIGNvbmZpZ3VyZWQgbmF0aXZlLXRva2VuIGJhc2UKLy8gICAgIHVuaXRzLgpmdW5jIChpICpwb29sVjEpIFNldFBvb2xDcmVhdGlvbkZlZShfIGludCwgcmxtIHJlYWxtLCBmZWUgaW50NjQpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWkuYXNzZXJ0UG9vbFVubG9ja2VkKCkKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRQb29sKCkKCglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkKCWFjY2Vzcy5Bc3NlcnRJc0FkbWluT3JHb3Zlcm5hbmNlKGNhbGxlcikKCglpLmxvY2tQb29sKDAsIHJsbSkKCWRlZmVyIGkudW5sb2NrUG9vbCgwLCBybG0pCgoJcHJldlBvb2xDcmVhdGlvbkZlZSA6PSBpLnN0b3JlLkdldFBvb2xDcmVhdGlvbkZlZSgpCgllcnIgOj0gaS5zZXRQb29sQ3JlYXRpb25GZWUoMCwgcmxtLCBmZWUpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJY2hhaW4uRW1pdCgKCQkiU2V0UG9vbENyZWF0aW9uRmVlIiwKCQkicHJldkFkZHIiLCBjYWxsZXIuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJwcmV2RmVlIiwgdXRpbHMuRm9ybWF0SW50KHByZXZQb29sQ3JlYXRpb25GZWUpLAoJCSJuZXdGZWUiLCB1dGlscy5Gb3JtYXRJbnQoZmVlKSwKCSkKfQoKLy8gU2V0V2l0aGRyYXdhbEZlZSBzZXRzIHRoZSB3aXRoZHJhd2FsIGZlZS4KLy8gT25seSBhZG1pbiBvciBnb3Zlcm5hbmNlIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBMZWFkaW5nIGludGVnZXIgZGlzY3JpbWluYXRvciBmb3IgdGhlIGZvcndhcmRlZCByZWFsbSBjYWxsOyBjYWxsZXJzCi8vICAgICBwYXNzIDAuCi8vICAgLSBybG06IFByb3BhZ2F0ZWQgcmVhbG0gY29udGV4dCB2YWxpZGF0ZWQgYXMgY3VycmVudCBiZWZvcmUgdGhlIGZlZSBpcwovLyAgICAgd3JpdHRlbi4KLy8gICAtIGZlZTogTmV3IHdpdGhkcmF3YWwgZmVlIGluIGJhc2lzIHBvaW50czsgdGhlIHNldHRlciBhY2NlcHRzIDAgdGhyb3VnaAovLyAgICAgMSwwMDAgKDEwJSkgaW5jbHVzaXZlLgpmdW5jIChpICpwb29sVjEpIFNldFdpdGhkcmF3YWxGZWUoXyBpbnQsIHJsbSByZWFsbSwgZmVlIHVpbnQ2NCkgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaS5hc3NlcnRQb29sVW5sb2NrZWQoKQoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFBvb2woKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzQWRtaW5PckdvdmVybmFuY2UoY2FsbGVyKQoKCWkubG9ja1Bvb2woMCwgcmxtKQoJZGVmZXIgaS51bmxvY2tQb29sKDAsIHJsbSkKCglwcmV2V2l0aGRyYXdhbEZlZSA6PSBpLnN0b3JlLkdldFdpdGhkcmF3YWxGZWVCUFMoKQoKCWVyciA6PSBpLnNldFdpdGhkcmF3YWxGZWUoMCwgcmxtLCBmZWUpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJY2hhaW4uRW1pdCgKCQkiU2V0V2l0aGRyYXdhbEZlZSIsCgkJInByZXZBZGRyIiwgY2FsbGVyLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2aW91c1JlYWxtLlBrZ1BhdGgoKSwKCQkicHJldkZlZSIsIHV0aWxzLkZvcm1hdFVpbnQocHJldldpdGhkcmF3YWxGZWUpLAoJCSJuZXdGZWUiLCB1dGlscy5Gb3JtYXRVaW50KGZlZSksCgkpCn0KCi8vIGNhbGN1bGF0ZUFtb3VudFdpdGhGZWUgY2FsY3VsYXRlcyB0aGUgZmVlIGFtb3VudCBhbmQgdGhlIGFtb3VudCBhZnRlciB0aGUgZmVlCi8vCi8vIElucHV0czoKLy8gLSBhbW91bnQ6IHRoZSBhbW91bnQgYmVmb3JlIHRoZSBmZWUKLy8gLSBmZWU6IHRoZSBmZWUgaW4gQlBTCi8vCi8vIE91dHB1dHM6Ci8vIC0gdGhlIGZlZSBhbW91bnQKLy8gLSB0aGUgYW1vdW50IGFmdGVyIHRoZSBmZWUgYXBwbGllZApmdW5jIGNhbGN1bGF0ZUFtb3VudFdpdGhGZWUoYW1vdW50LCBmZWUgKnUyNTYuVWludCkgKGZlZUFtb3VudCwgYWZ0ZXJBbW91bnQgKnUyNTYuVWludCkgewoJZmVlQW1vdW50LCBvdmVyZmxvdyA6PSB1MjU2Llplcm8oKS5NdWxPdmVyZmxvdyhhbW91bnQsIGZlZSkKCWlmIG92ZXJmbG93IHsKCQlwYW5pYyhlcnJvcnMuTmV3KGVyck92ZXJmbG93KSkKCX0KCWZlZUFtb3VudCA9IHUyNTYuWmVybygpLkRpdihmZWVBbW91bnQsIHUyNTYuTmV3VWludCgxMF8wMDApKQoJYWZ0ZXJBbW91bnQgPSB1MjU2Llplcm8oKS5TdWIoYW1vdW50LCBmZWVBbW91bnQpCglyZXR1cm4gZmVlQW1vdW50LCBhZnRlckFtb3VudAp9CgovLyBzZXRQb29sQ3JlYXRpb25GZWUgdGhpcyBmdW5jdGlvbiBpcyBpbnRlcm5hbCBmdW5jdGlvbiBjYWxsZWQgYnkgU2V0UG9vbENyZWF0aW9uRmVlCi8vIEFuZCBTZXRQb29sQ3JlYXRpb25GZWUKZnVuYyAoaSAqcG9vbFYxKSBzZXRQb29sQ3JlYXRpb25GZWUoXyBpbnQsIHJsbSByZWFsbSwgZmVlIGludDY0KSBlcnJvciB7CglpZiBmZWUgPCAwIHsKCQlyZXR1cm4gbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRJbnB1dCwKCQkJInBvb2wgY3JlYXRpb24gZmVlIGNhbm5vdCBiZSBuZWdhdGl2ZSIsCgkJKQoJfQoKCS8vIHVwZGF0ZSBwb29sIGNyZWF0aW9uIGZlZQoJZXJyIDo9IGkuc3RvcmUuU2V0UG9vbENyZWF0aW9uRmVlKDAsIHJsbSwgZmVlKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCXJldHVybiBuaWwKfQoKLy8gc2V0V2l0aGRyYXdhbEZlZSB0aGlzIGZ1bmN0aW9uIGlzIGludGVybmFsIGZ1bmN0aW9uIGNhbGxlZCBieSBTZXRXaXRoZHJhd2FsRmVlCi8vIGZ1bmN0aW9uIGFuZCBTZXRXaXRoZHJhd2FsRmVlIGZ1bmN0aW9uCmZ1bmMgKGkgKnBvb2xWMSkgc2V0V2l0aGRyYXdhbEZlZShfIGludCwgcmxtIHJlYWxtLCBmZWUgdWludDY0KSBlcnJvciB7CglpZiBmZWUgPiBNYXhCcHNWYWx1ZSB7CgkJcmV0dXJuIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkV2l0aGRyYXdhbEZlZVBjdCwKCQkJdWZtdC5TcHJpbnRmKCJmZWUoJWQpIG11c3QgYmUgaW4gcmFuZ2UgMCB+ICVkIiwgZmVlLCBNYXhCcHNWYWx1ZSksCgkJKQoJfQoKCWVyciA6PSBpLnN0b3JlLlNldFdpdGhkcmF3YWxGZWVCUFMoMCwgcmxtLCBmZWUpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJcmV0dXJuIG5pbAp9ChqZEgoKcmVuZGVyLmdubxKKEnBhY2thZ2UgcG9vbAoKaW1wb3J0ICgKCSJjaGFpbiIKCSJzdHJpbmdzIgoKCSJnbm8ubGFuZC9wL21vdWwvbWQvdjAiCgkiZ25vLmxhbmQvcC9tb3VsL21kdGFibGUvdjAiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgoJImduby5sYW5kL3IvZ25vc3dhcC9oYWx0L3YxIgoJcG9vbFJvb3QgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgopCgpmdW5jIChwICpwb29sVjEpIFJlbmRlcihwYXRoIHN0cmluZykgc3RyaW5nIHsKCWlmIHBhdGggIT0gIiIgewoJCXJldHVybiAiNDA0XG4iCgl9CgoJZmVlQW1vdW50VGlja1NwYWNpbmcgOj0gcC5zdG9yZS5HZXRGZWVBbW91bnRUaWNrU3BhY2luZygpCglwcm90b2NvbEZlZSA6PSBwLnN0b3JlLkdldFNsb3QwRmVlUHJvdG9jb2woKQoJaW1wbGVtZW50YXRpb24gOj0gcG9vbFJvb3QuR2V0SW1wbGVtZW50YXRpb25QYWNrYWdlUGF0aCgpCglpbXBsZW1lbnRhdGlvblRhYmxlIDo9IG1kdGFibGUuVGFibGV7CgkJSGVhZGVyczogW11zdHJpbmd7IkZpZWxkIiwgIlZhbHVlIn0sCgkJUm93czogW11bXXN0cmluZ3sKCQkJeyJSZWFsbSBhZGRyZXNzIiwgbWQuSW5saW5lQ29kZShjaGFpbi5QYWNrYWdlQWRkcmVzcygiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiKS5TdHJpbmcoKSl9LAoJCQl7IkFjdGl2ZSBpbXBsZW1lbnRhdGlvbiIsIG1kLkxpbmsoaW1wbGVtZW50YXRpb24sIHN0cmluZ3MuVHJpbVByZWZpeChpbXBsZW1lbnRhdGlvbiwgImduby5sYW5kIikpfSwKCQkJeyJQb29sIG9wZXJhdGlvbnMgaGFsdGVkIiwgdWZtdC5TcHJpbnRmKCIldCIsIGhhbHQuSXNIYWx0ZWRQb29sKCkpfSwKCQkJeyJQcm90b2NvbC1mZWUgb3BlcmF0aW9ucyBoYWx0ZWQiLCB1Zm10LlNwcmludGYoIiV0IiwgaGFsdC5Jc0hhbHRlZFByb3RvY29sRmVlKCkpfSwKCQkJeyJXaXRoZHJhd2FscyBoYWx0ZWQiLCB1Zm10LlNwcmludGYoIiV0IiwgaGFsdC5Jc0hhbHRlZFdpdGhkcmF3KCkpfSwKCQl9LAoJfQoJZmVlVGFibGUgOj0gbWR0YWJsZS5UYWJsZXsKCQlIZWFkZXJzOiBbXXN0cmluZ3siRmllbGQiLCAiVmFsdWUifSwKCQlSb3dzOiBbXVtdc3RyaW5newoJCQl7IlN0b3JlZCBwb29sIHJlY29yZHMiLCB1Zm10LlNwcmludGYoIiVkIiwgcC5zdG9yZS5HZXRQb29scygpLlNpemUoKSl9LAoJCQl7IlBvb2wgY3JlYXRpb24gZmVlIChHTlMgYmFzZSB1bml0czsgNiBkZWNpbWFscykiLCB1Zm10LlNwcmludGYoIiVkIiwgcC5zdG9yZS5HZXRQb29sQ3JlYXRpb25GZWUoKSl9LAoJCQl7IldpdGhkcmF3YWwgZmVlIiwgdWZtdC5TcHJpbnRmKCIlZCBicHMiLCBwLnN0b3JlLkdldFdpdGhkcmF3YWxGZWVCUFMoKSl9LAoJCQl7IkZlZSB0aWVycyAocGlwcykiLCAiMTAwICgwLjAxJSkgLyA1MDAgKDAuMDUlKSAvIDMwMDAgKDAuMzAlKSAvIDEwMDAwICgxLjAwJSkifSwKCQkJeyJUaWNrIHNwYWNpbmcgKHRpY2tzOyBzYW1lIHRpZXIgb3JkZXIpIiwgdWZtdC5TcHJpbnRmKCIlZCAvICVkIC8gJWQgLyAlZCIsCgkJCQlmZWVBbW91bnRUaWNrU3BhY2luZ1sxMDBdLAoJCQkJZmVlQW1vdW50VGlja1NwYWNpbmdbNTAwXSwKCQkJCWZlZUFtb3VudFRpY2tTcGFjaW5nWzMwMDBdLAoJCQkJZmVlQW1vdW50VGlja1NwYWNpbmdbMTAwMDBdLAoJCQkpfSwKCQkJeyJQcm90b2NvbCBmZWUgZGVub21pbmF0b3JzICh0b2tlbjAgLyB0b2tlbjEpIiwgdWZtdC5TcHJpbnRmKCIlZCAvICVkIiwgcHJvdG9jb2xGZWUmMTUsIHByb3RvY29sRmVlPj40KX0sCgkJfSwKCX0KCglvdXQgOj0gbWQuSDEoIkdub3N3YXAgUG9vbCIpICsgIlxuIgoJb3V0ICs9IG1kLlBhcmFncmFwaChgUG9vbCBjcmVhdGlvbiBmZWVzIGFyZSBjaGFyZ2VkIGluIEdOUy4gR05TIGFtb3VudHMgdXNlIHRoZSB0b2tlbidzIHNpeC1kZWNpbWFsCmJhc2UgdW5pdHM7IHBvb2wgdG9rZW4gYW1vdW50cyB1c2UgZWFjaCB0b2tlbidzIG93biBiYXNlIHVuaXRzLiBXaXRoZHJhd2FsIGZlZXMKYXBwbHkgdG8gY29sbGVjdGVkIHN3YXAgZmVlcyBhbmQgYXJlIGV4cHJlc3NlZCBpbiBiYXNpcyBwb2ludHMuIFByb3RvY29sIGZlZQpkZW5vbWluYXRvcnMgYXBwbHkgdG8gc3dhcCBmZWVzOyB6ZXJvIGRpc2FibGVzIHRoZSBjb3JyZXNwb25kaW5nIHRva2VuJ3MgZmVlLmApCglvdXQgKz0gbWQuSDIoIkltcGxlbWVudGF0aW9uIGFuZCBvcGVyYXRpb24gc3RhdHVzIikgKyAiXG4iCglvdXQgKz0gaW1wbGVtZW50YXRpb25UYWJsZS5TdHJpbmcoKSArICJcbiIKCW91dCArPSBtZC5IMigiUG9vbHMgYW5kIGZlZSBjb25maWd1cmF0aW9uIikgKyAiXG4iCglvdXQgKz0gZmVlVGFibGUuU3RyaW5nKCkKCXJldHVybiBvdXQKfQoa8N8BCghzd2FwLmdubxLi3wFwYWNrYWdlIHBvb2wKCmltcG9ydCAoCgkiY2hhaW4iCgkiZXJyb3JzIgoJInN0cmNvbnYiCgkidGltZSIKCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKCSJnbm8ubGFuZC9yL2dub3N3YXAvaGFsdC92MSIKCgkiZ25vLmxhbmQvcC9nbm9zd2FwL2NvbnN0cy92MSIKCSJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCWkyNTYgImduby5sYW5kL3AvZ25vc3dhcC9pbnQyNTYvdjEiCgl1MjU2ICJnbm8ubGFuZC9wL2dub3N3YXAvdWludDI1Ni92MSIKCSJnbm8ubGFuZC9wL2dub3N3YXAvdXRpbHMvdjEiCgoJcGwgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgopCgovLyBIb29rIGZ1bmN0aW9ucyBhbGxvdyBleHRlcm5hbCBjb250cmFjdHMgdG8gYmUgbm90aWZpZWQgb2Ygc3dhcCBldmVudHMuCnZhciAoCgkvLyBNVVNUIEJFIElNTVVUQUJMRS4KCS8vIERPIE5PVCBVU0UgVEhJUyBWQUxVRSBJTiBBTlkgQVJJVEhNRVRJQyBPUEVSQVRJT05TJyBJTklUSUFMSVpBVElPTgoJemVybyAgICAgICAgICAgPSB1MjU2Llplcm8oKQoJemVyb0kyNTYgICAgICAgPSBpMjU2Llplcm8oKSAvKiByZWFkb25seSAqLwoJZml4ZWRQb2ludFExMjggPSB1MjU2Lk11c3RGcm9tRGVjaW1hbChRMTI4KQoKCW1heEludDI1NiA9IHUyNTYuTXVzdEZyb21EZWNpbWFsKE1BWF9JTlQyNTYpCgltYXhJbnQ2NCAgPSBpMjU2Llplcm8oKS5TZXRJbnQ2NChJTlQ2NF9NQVgpCgltaW5JbnQ2NCAgPSBpMjU2Llplcm8oKS5TZXRJbnQ2NChJTlQ2NF9NSU4pCikKCi8vIFNldFRpY2tDcm9zc0hvb2sgc2V0cyB0aGUgaG9vayBmdW5jdGlvbiBjYWxsZWQgd2hlbiBhIHRpY2sgaXMgY3Jvc3NlZCBkdXJpbmcgc3dhcHMuCi8vCi8vIEFsbG93cyBzdGFrZXIgdG8gbW9uaXRvciBsaXF1aWRpdHkgY2hhbmdlcyBhdCBwcmljZSBsZXZlbHMuCi8vIFVzZWQgZm9yIHJld2FyZCBjYWxjdWxhdGlvbiB3aGVuIHBvc2l0aW9ucyBlbnRlci9leGl0IHJhbmdlLgovLwovLyBPbmx5IGNhbGxhYmxlIGJ5IHN0YWtlciBjb250cmFjdC4KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IExlYWRpbmcgaW50ZWdlciBkaXNjcmltaW5hdG9yIGZvciB0aGUgZm9yd2FyZGVkIHJlYWxtIGNhbGw7IGNhbGxlcnMKLy8gICAgIHBhc3MgMC4KLy8gICAtIHJsbTogUHJvcGFnYXRlZCByZWFsbSBjb250ZXh0IHZhbGlkYXRlZCBhcyBjdXJyZW50IGJlZm9yZSB0aGUgaG9vayBpcwovLyAgICAgc3RvcmVkLgovLyAgIC0gaG9vazogQ2FsbGJhY2sgaW52b2tlZCBhZnRlciBhbiBpbml0aWFsaXplZCB0aWNrIGlzIGNyb3NzZWQgd2l0aCB0aGUKLy8gICAgIGN1cnJlbnQgcG9vbCByZWFsbSwgcG9vbCBwYXRoLCB0aWNrIGluZGV4LCBzd2FwIGRpcmVjdGlvbiwgYW5kIHRpbWVzdGFtcC4KZnVuYyAoaSAqcG9vbFYxKSBTZXRUaWNrQ3Jvc3NIb29rKF8gaW50LCBybG0gcmVhbG0sIGhvb2sgZnVuYyhjdXIgcmVhbG0sIHBvb2xQYXRoIHN0cmluZywgdGlja0lkIGludDMyLCB6ZXJvRm9yT25lIGJvb2wsIHRpbWVzdGFtcCBpbnQ2NCkpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWkuYXNzZXJ0UG9vbFVubG9ja2VkKCkKCgljYWxsZXIgOj0gcmxtLlByZXZpb3VzKCkuQWRkcmVzcygpCglhY2Nlc3MuQXNzZXJ0SXNTdGFrZXIoY2FsbGVyKQoKCWkubG9ja1Bvb2woMCwgcmxtKQoJZGVmZXIgaS51bmxvY2tQb29sKDAsIHJsbSkKCgllcnIgOj0gaS5zdG9yZS5TZXRUaWNrQ3Jvc3NIb29rKDAsIHJsbSwgaG9vaykKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KfQoKLy8gU2V0U3dhcFN0YXJ0SG9vayBzZXRzIHRoZSBob29rIGZ1bmN0aW9uIGNhbGxlZCBhdCB0aGUgYmVnaW5uaW5nIG9mIGEgc3dhcC4KLy8KLy8gRW5hYmxlcyBwcmUtc3dhcCBzdGF0ZSB0cmFja2luZyBmb3IgcmV3YXJkIGRpc3RyaWJ1dGlvbi4KLy8gQ2FwdHVyZXMgdGltZXN0YW1wIGZvciB0aW1lLXdlaWdodGVkIGNhbGN1bGF0aW9ucy4KLy8KLy8gT25seSBjYWxsYWJsZSBieSBzdGFrZXIgY29udHJhY3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBMZWFkaW5nIGludGVnZXIgZGlzY3JpbWluYXRvciBmb3IgdGhlIGZvcndhcmRlZCByZWFsbSBjYWxsOyBjYWxsZXJzCi8vICAgICBwYXNzIDAuCi8vICAgLSBybG06IFByb3BhZ2F0ZWQgcmVhbG0gY29udGV4dCB2YWxpZGF0ZWQgYXMgY3VycmVudCBiZWZvcmUgdGhlIGhvb2sgaXMKLy8gICAgIHN0b3JlZC4KLy8gICAtIGhvb2s6IENhbGxiYWNrIGludm9rZWQgYmVmb3JlIHN3YXAgY29tcHV0YXRpb24gd2l0aCB0aGUgY3VycmVudCBwb29sCi8vICAgICByZWFsbSwgcG9vbCBwYXRoLCBhbmQgYmxvY2sgdGltZXN0YW1wLgpmdW5jIChpICpwb29sVjEpIFNldFN3YXBTdGFydEhvb2soXyBpbnQsIHJsbSByZWFsbSwgaG9vayBmdW5jKGN1ciByZWFsbSwgcG9vbFBhdGggc3RyaW5nLCB0aW1lc3RhbXAgaW50NjQpKSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCglpLmFzc2VydFBvb2xVbmxvY2tlZCgpCgoJY2FsbGVyIDo9IHJsbS5QcmV2aW91cygpLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzU3Rha2VyKGNhbGxlcikKCglpLmxvY2tQb29sKDAsIHJsbSkKCWRlZmVyIGkudW5sb2NrUG9vbCgwLCBybG0pCgoJZXJyIDo9IGkuc3RvcmUuU2V0U3dhcFN0YXJ0SG9vaygwLCBybG0sIGhvb2spCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9Cn0KCi8vIFNldFN3YXBFbmRIb29rIHNldHMgdGhlIGhvb2sgZnVuY3Rpb24gY2FsbGVkIGF0IHRoZSBlbmQgb2YgYSBzd2FwLgovLwovLyBGaW5hbGl6ZXMgcmV3YXJkIGNhbGN1bGF0aW9ucyBhZnRlciBzd2FwIGNvbXBsZXRpb24uCi8vIEFsbG93cyBlcnJvciBwcm9wYWdhdGlvbiB0byByZXZlcnQgaW52YWxpZCBzd2Fwcy4KLy8KLy8gT25seSBjYWxsYWJsZSBieSBzdGFrZXIgY29udHJhY3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBMZWFkaW5nIGludGVnZXIgZGlzY3JpbWluYXRvciBmb3IgdGhlIGZvcndhcmRlZCByZWFsbSBjYWxsOyBjYWxsZXJzCi8vICAgICBwYXNzIDAuCi8vICAgLSBybG06IFByb3BhZ2F0ZWQgcmVhbG0gY29udGV4dCB2YWxpZGF0ZWQgYXMgY3VycmVudCBiZWZvcmUgdGhlIGhvb2sgaXMKLy8gICAgIHN0b3JlZC4KLy8gICAtIGhvb2s6IENhbGxiYWNrIGludm9rZWQgYWZ0ZXIgc3dhcCBzZXR0bGVtZW50IHdpdGggdGhlIGN1cnJlbnQgcG9vbCByZWFsbQovLyAgICAgYW5kIHBvb2wgcGF0aDsgYSBub24tbmlsIGVycm9yIGFib3J0cyB0aGUgc3Vycm91bmRpbmcgc3dhcC4KZnVuYyAoaSAqcG9vbFYxKSBTZXRTd2FwRW5kSG9vayhfIGludCwgcmxtIHJlYWxtLCBob29rIGZ1bmMoY3VyIHJlYWxtLCBwb29sUGF0aCBzdHJpbmcpIGVycm9yKSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCglpLmFzc2VydFBvb2xVbmxvY2tlZCgpCgoJY2FsbGVyIDo9IHJsbS5QcmV2aW91cygpLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzU3Rha2VyKGNhbGxlcikKCglpLmxvY2tQb29sKDAsIHJsbSkKCWRlZmVyIGkudW5sb2NrUG9vbCgwLCBybG0pCgoJZXJyIDo9IGkuc3RvcmUuU2V0U3dhcEVuZEhvb2soMCwgcmxtLCBob29rKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQp9CgovLyBTd2FwUmVzdWx0IGVuY2Fwc3VsYXRlcyBhbGwgc3RhdGUgY2hhbmdlcyBmcm9tIGEgc3dhcC4KLy8gSXQgZW5zdXJlcyBhdG9taWMgc3RhdGUgdHJhbnNpdGlvbnMgdGhhdCBjYW4gYmUgYXBwbGllZCBhdCBvbmNlLgp0eXBlIFN3YXBSZXN1bHQgc3RydWN0IHsKCUFtb3VudDAgICAgICAgICAgICAgICppMjU2LkludAoJQW1vdW50MSAgICAgICAgICAgICAgKmkyNTYuSW50CglOZXdTcXJ0UHJpY2UgICAgICAgICAqdTI1Ni5VaW50CglOZXdUaWNrICAgICAgICAgICAgICBpbnQzMgoJTmV3TGlxdWlkaXR5ICAgICAgICAgKnUyNTYuVWludAoJTmV3UHJvdG9jb2xGZWVUb2tlbjAgaW50NjQKCU5ld1Byb3RvY29sRmVlVG9rZW4xIGludDY0CglGZWVHcm93dGhHbG9iYWwwWDEyOCAqdTI1Ni5VaW50CglGZWVHcm93dGhHbG9iYWwxWDEyOCAqdTI1Ni5VaW50Cn0KCi8vIFN3YXBDb21wdXRhdGlvbiBlbmNhcHN1bGF0ZXMgdGhlIHB1cmUgY29tcHV0YXRpb24gbG9naWMgZm9yIHN3YXBzLgp0eXBlIFN3YXBDb21wdXRhdGlvbiBzdHJ1Y3QgewoJQW1vdW50U3BlY2lmaWVkICAgKmkyNTYuSW50CglTcXJ0UHJpY2VMaW1pdFg5NiAqdTI1Ni5VaW50CglaZXJvRm9yT25lICAgICAgICBib29sCglFeGFjdElucHV0ICAgICAgICBib29sCglJbml0aWFsU3RhdGUgICAgICBTd2FwU3RhdGUKCUNhY2hlICAgICAgICAgICAgICpTd2FwQ2FjaGUKfQoKLy8gU3dhcCBleGVjdXRlcyBhIHN3YXAgd2l0aCBjYWxsYmFjayBwYXR0ZXJuIGZvciBvcHRpbWlzdGljIHRyYW5zZmVycy4KLy8gVGhpcyBhbGxvd3MgZmxhc2ggc3dhcHMgd2hlcmUgdG9rZW5zIGFyZSBzZW50IGJlZm9yZSBwYXltZW50IGlzIHJlY2VpdmVkLgovLwovLyBUaGUgZmxvdyBpczoKLy8gMS4gUG9vbCBzZW5kcyBvdXRwdXQgdG9rZW5zIHRvIHJlY2lwaWVudAovLyAyLiBQb29sIGNhbGxzIGNhbGxiYWNrIG9uIG1zZy5zZW5kZXIKLy8gMy4gQ2FsbGJhY2sgbXVzdCBlbnN1cmUgcG9vbCByZWNlaXZlcyBpbnB1dCB0b2tlbnMKLy8gNC4gUG9vbCB2YWxpZGF0ZXMgaXRzIGJhbGFuY2UgaW5jcmVhc2VkIGNvcnJlY3RseQovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTGVhZGluZyBpbnRlZ2VyIGRpc2NyaW1pbmF0b3IgZm9yIHRoZSBmb3J3YXJkZWQgcmVhbG0gY2FsbDsgY2FsbGVycwovLyAgICAgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHByb3BhZ2F0ZWQgcmVhbG0gY29udGV4dDsgaXQgaXMgdmFsaWRhdGVkIGFzIGN1cnJlbnQgYW5kCi8vICAgICB1c2VkIGZvciB0b2tlbiB0cmFuc2ZlcnMgYW5kIGNhbGxiYWNrcy4KLy8gICAtIHRva2VuMFBhdGg6IFJlZ2lzdGVyZWQgcGF0aCBvZiB0b2tlbjA7IGl0IG11c3QgYmUgdGhlIGZpcnN0IHRva2VuIGluIHRoZQovLyAgICAgcG9vbCdzIGNhbm9uaWNhbCB0b2tlbiBvcmRlcmluZy4KLy8gICAtIHRva2VuMVBhdGg6IFJlZ2lzdGVyZWQgcGF0aCBvZiB0b2tlbjE7IGl0IG11c3QgYmUgdGhlIHNlY29uZCB0b2tlbiBpbgovLyAgICAgdGhlIHBvb2wncyBjYW5vbmljYWwgdG9rZW4gb3JkZXJpbmcuCi8vICAgLSBmZWU6IEZlZSB0aWVyIGlkZW50aWZ5aW5nIHRoZSByZWdpc3RlcmVkIHBvb2wgdG8gc3dhcCBhZ2FpbnN0LgovLyAgIC0gcmVjaXBpZW50OiBBZGRyZXNzIHRoYXQgcmVjZWl2ZXMgdGhlIG91dHB1dCB0b2tlbiB0cmFuc2Zlci4KLy8gICAtIHplcm9Gb3JPbmU6IFN3YXAgZGlyZWN0aW9uOyB0cnVlIHNlbGxzIHRva2VuMCBmb3IgdG9rZW4xLCBmYWxzZSBzZWxscwovLyAgICAgdG9rZW4xIGZvciB0b2tlbjAuCi8vICAgLSBhbW91bnRTcGVjaWZpZWQ6IFNpZ25lZCBkZWNpbWFsIGFtb3VudDsgcG9zaXRpdmUgdmFsdWVzIHJlcXVlc3QgZXhhY3QKLy8gICAgIGlucHV0LCBuZWdhdGl2ZSB2YWx1ZXMgcmVxdWVzdCBleGFjdCBvdXRwdXQsIGFuZCB6ZXJvIGlzIGludmFsaWQuCi8vICAgLSBzcXJ0UHJpY2VMaW1pdFg5NjogRGVjaW1hbCBROTYgc3F1YXJlLXJvb3QtcHJpY2UgbGltaXQgdGhhdCBib3VuZHMgdGhlCi8vICAgICBzd2FwIGluIGl0cyBkaXJlY3Rpb247IGFuIGludmFsaWQgYm91bmQgY2F1c2VzIHRoZSBjYWxsIHRvIHBhbmljLgovLyAgIC0gc3dhcENhbGxiYWNrOiBDYWxsYmFjayB0aGF0IG11c3Qgc2V0dGxlIHRoZSBpbnB1dCBkZWx0YSBhZnRlciBvdXRwdXQgaXMKLy8gICAgIHNlbnQ7IGl0IHJlY2VpdmVzIHNpZ25lZCBpbnQ2NCB0b2tlbiBkZWx0YXMgYW5kIGEgY2FsbGJhY2sgbWFya2VyLCBhbmQgYQovLyAgICAgbm9uLW5pbCBlcnJvciBhYm9ydHMgdGhlIHN3YXAuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBzdHJpbmc6IFNpZ25lZCBkZWNpbWFsIHRva2VuMCBkZWx0YSBmcm9tIHRoZSBwb29sJ3MgcGVyc3BlY3RpdmU7IGEKLy8gICAgIHBvc2l0aXZlIHZhbHVlIGlzIG93ZWQgdG8gdGhlIHBvb2wgYW5kIGEgbmVnYXRpdmUgdmFsdWUgaXMgc2VudCBvdXQuCi8vICAgLSBzdHJpbmc6IFNpZ25lZCBkZWNpbWFsIHRva2VuMSBkZWx0YSBmcm9tIHRoZSBwb29sJ3MgcGVyc3BlY3RpdmU7IGEKLy8gICAgIHBvc2l0aXZlIHZhbHVlIGlzIG93ZWQgdG8gdGhlIHBvb2wgYW5kIGEgbmVnYXRpdmUgdmFsdWUgaXMgc2VudCBvdXQuCmZ1bmMgKGkgKnBvb2xWMSkgU3dhcCgKCV8gaW50LAoJcmxtIHJlYWxtLAoJdG9rZW4wUGF0aCBzdHJpbmcsCgl0b2tlbjFQYXRoIHN0cmluZywKCWZlZSB1aW50MzIsCglyZWNpcGllbnQgYWRkcmVzcywKCXplcm9Gb3JPbmUgYm9vbCwKCWFtb3VudFNwZWNpZmllZCBzdHJpbmcsCglzcXJ0UHJpY2VMaW1pdFg5NiBzdHJpbmcsCglzd2FwQ2FsbGJhY2sgZnVuYyhjdXIgcmVhbG0sIGFtb3VudDBEZWx0YSwgYW1vdW50MURlbHRhIGludDY0LCBfICpwbC5DYWxsYmFja01hcmtlcikgZXJyb3IsCikgKHN0cmluZywgc3RyaW5nKSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCglpLmFzc2VydFBvb2xVbmxvY2tlZCgpCgloYWx0LkFzc2VydElzTm90SGFsdGVkUG9vbCgpCgoJYXNzZXJ0SXNOb3RVc2VyQ2FsbCgwLCBybG0pCglhc3NlcnRJc1ZhbGlkVG9rZW5PcmRlcih0b2tlbjBQYXRoLCB0b2tlbjFQYXRoKQoKCWFtb3VudHMgOj0gaTI1Ni5NdXN0RnJvbURlY2ltYWwoYW1vdW50U3BlY2lmaWVkKQoJaWYgYW1vdW50cy5Jc1plcm8oKSB7CgkJcGFuaWMobmV3RXJyb3JXaXRoRGV0YWlsKAoJCQllcnJJbnZhbGlkU3dhcEFtb3VudCwKCQkJImFtb3VudFNwZWNpZmllZCA9PSAwIiwKCQkpKQoJfQoKCXBvb2wgOj0gaS5tdXN0R2V0UG9vbEJ5KHRva2VuMFBhdGgsIHRva2VuMVBhdGgsIGZlZSkKCW9ic2VydmF0aW9ucyA6PSBpLm11c3RHZXRPYnNlcnZhdGlvbnMocG9vbC5Qb29sUGF0aCgpKQoKCXNsb3QwU3RhcnQgOj0gcG9vbC5TbG90MCgpCglpLmxvY2tQb29sKDAsIHJsbSkKCWRlZmVyIGkudW5sb2NrUG9vbCgwLCBybG0pCgoJYmxvY2tUaW1lc3RhbXAgOj0gdGltZS5Ob3coKS5Vbml4KCkKCgkvLyBDYWxsIHN3YXAgc3RhcnQgaG9vayBpZiBzZXQKCWlmIGkuc3RvcmUuSGFzU3dhcFN0YXJ0SG9vaygpIHsKCQlzd2FwU3RhcnRIb29rIDo9IGkuc3RvcmUuR2V0U3dhcFN0YXJ0SG9vaygpCgoJCWlmIHN3YXBTdGFydEhvb2sgIT0gbmlsIHsKCQkJc3dhcFN0YXJ0SG9vayhjcm9zcyhybG0pLCBwb29sLlBvb2xQYXRoKCksIGJsb2NrVGltZXN0YW1wKQoJCX0KCX0KCglzcXJ0UHJpY2VMaW1pdCA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChzcXJ0UHJpY2VMaW1pdFg5NikKCXZhbGlkYXRlUHJpY2VMaW1pdHMoc2xvdDBTdGFydCwgemVyb0Zvck9uZSwgc3FydFByaWNlTGltaXQpCgoJZmVlR3Jvd3RoR2xvYmFsWDEyOCA6PSBnZXRGZWVHcm93dGhHbG9iYWwocG9vbCwgemVyb0Zvck9uZSkKCWZlZVByb3RvY29sIDo9IGdldEZlZVByb3RvY29sKHNsb3QwU3RhcnQsIHplcm9Gb3JPbmUpCgljYWNoZSA6PSBuZXdTd2FwQ2FjaGUoZmVlUHJvdG9jb2wsIHBvb2wuTGlxdWlkaXR5KCkuQ2xvbmUoKSwgYmxvY2tUaW1lc3RhbXAsIHNsb3QwU3RhcnQpCglzdGF0ZSA6PSBuZXdTd2FwU3RhdGUoYW1vdW50cywgZmVlR3Jvd3RoR2xvYmFsWDEyOCwgY2FjaGUubGlxdWlkaXR5U3RhcnQuQ2xvbmUoKSwgc2xvdDBTdGFydCkKCgljb21wIDo9IFN3YXBDb21wdXRhdGlvbnsKCQlBbW91bnRTcGVjaWZpZWQ6ICAgYW1vdW50cywKCQlTcXJ0UHJpY2VMaW1pdFg5Njogc3FydFByaWNlTGltaXQsCgkJWmVyb0Zvck9uZTogICAgICAgIHplcm9Gb3JPbmUsCgkJRXhhY3RJbnB1dDogICAgICAgIGFtb3VudHMuR3QoemVyb0kyNTYpLAoJCUluaXRpYWxTdGF0ZTogICAgICBzdGF0ZSwKCQlDYWNoZTogICAgICAgICAgICAgY2FjaGUsCgl9CgoJdmFyIGhvb2sgZnVuYyhjdXIgcmVhbG0sIHBvb2xQYXRoIHN0cmluZywgdGlja0lkIGludDMyLCB6ZXJvRm9yT25lIGJvb2wsIHRpbWVzdGFtcCBpbnQ2NCkKCWlmIGkuc3RvcmUuSGFzVGlja0Nyb3NzSG9vaygpIHsKCQlob29rID0gaS5zdG9yZS5HZXRUaWNrQ3Jvc3NIb29rKCkKCX0KCW9uVGlja0Nyb3NzIDo9IGZ1bmMocG9vbCAqcGwuUG9vbCwgdGlja0lkIGludDMyLCB6ZXJvRm9yT25lIGJvb2wsIHRpbWVzdGFtcCBpbnQ2NCkgewoJCWNoYWluLkVtaXQoCgkJCSJQb29sVGlja0Nyb3NzIiwKCQkJInBvb2xQYXRoIiwgcG9vbC5Qb29sUGF0aCgpLAoJCQkidGljayIsIE5ld1RpY2tFdmVudEluZm8odGlja0lkLCAqbXVzdEdldFRpY2socG9vbCwgdGlja0lkKSkuVG9TdHJpbmcoKSwKCQkpCgkJaWYgaG9vayAhPSBuaWwgewoJCQlob29rKGNyb3NzKHJsbSksIHBvb2wuUG9vbFBhdGgoKSwgdGlja0lkLCB6ZXJvRm9yT25lLCB0aW1lc3RhbXApCgkJfQoJfQoKCXJlc3VsdCwgZXJyIDo9IGkuY29tcHV0ZVN3YXAocG9vbCwgb2JzZXJ2YXRpb25zLCBjb21wLCBvblRpY2tDcm9zcykKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgkvLyBVcGRhdGUgb3JhY2xlIEJFRk9SRSBhcHBseWluZyBzd2FwIHJlc3VsdCAodXNpbmcgcHJlLXN3YXAgc3RhdGUpCglpZiByZXN1bHQuTmV3VGljayAhPSBzbG90MFN0YXJ0LlRpY2soKSB7CgkJb2JzZXJ2YXRpb25JbmRleCwgb2JzZXJ2YXRpb25DYXJkaW5hbGl0eSwgZXJyIDo9IHdyaXRlT2JzZXJ2YXRpb24oCgkJCW9ic2VydmF0aW9ucywKCQkJc2xvdDBTdGFydC5PYnNlcnZhdGlvbkluZGV4KCksCgkJCWNhY2hlLmJsb2NrVGltZXN0YW1wLAoJCQlzbG90MFN0YXJ0LlRpY2soKSwKCQkJY2FjaGUubGlxdWlkaXR5U3RhcnQsCgkJCXNsb3QwU3RhcnQuT2JzZXJ2YXRpb25DYXJkaW5hbGl0eSgpLAoJCQlzbG90MFN0YXJ0Lk9ic2VydmF0aW9uQ2FyZGluYWxpdHlOZXh0KCksCgkJKQoJCWlmIGVyciAhPSBuaWwgewoJCQlwYW5pYyhlcnIpCgkJfQoJCXNsb3QwIDo9IHBvb2wuU2xvdDAoKQoJCXNsb3QwLlNldE9ic2VydmF0aW9uSW5kZXgob2JzZXJ2YXRpb25JbmRleCkKCQlzbG90MC5TZXRPYnNlcnZhdGlvbkNhcmRpbmFsaXR5KG9ic2VydmF0aW9uQ2FyZGluYWxpdHkpCgkJcG9vbC5TZXRTbG90MChzbG90MCkKCX0KCglhcHBseVN3YXBSZXN1bHQocG9vbCwgcmVzdWx0KQoKCWlmIGkuc3RvcmUuSGFzU3dhcEVuZEhvb2soKSB7CgkJc3dhcEVuZEhvb2sgOj0gaS5zdG9yZS5HZXRTd2FwRW5kSG9vaygpCgkJaWYgc3dhcEVuZEhvb2sgIT0gbmlsIHsKCQkJZXJyIDo9IHN3YXBFbmRIb29rKGNyb3NzKHJsbSksIHBvb2wuUG9vbFBhdGgoKSkKCQkJaWYgZXJyICE9IG5pbCB7CgkJCQlwYW5pYyhlcnIpCgkJCX0KCQl9Cgl9CgoJLy8gdHJhbnNmZXIgc3dhcCByZXN1bHQgdG8gcmVjaXBpZW50IHRoZW4gcmVjZWl2ZSBpbnB1dCB0b2tlbnMgZnJvbSBzd2FwIGNhbGxiYWNrCglpZiB6ZXJvRm9yT25lIHsKCQkvLyByZWNlaXZlIHRva2VuMCBmcm9tIHN3YXAgY2FsbGJhY2sKCQkvLyBzZW5kIHRva2VuMSB0byByZWNpcGllbnQgKG91dHB1dCkKCQlpZiByZXN1bHQuQW1vdW50MS5Jc05lZygpIHsKCQkJaS5zYWZlVHJhbnNmZXIoMCwgcmxtLCBwb29sLCByZWNpcGllbnQsIHRva2VuMVBhdGgsIHJlc3VsdC5BbW91bnQxLkFicygpLCBmYWxzZSkKCQl9CgkJaS5zYWZlU3dhcENhbGxiYWNrKDAsIHJsbSwgcG9vbCwgdG9rZW4wUGF0aCwgcmVzdWx0LkFtb3VudDAsIHJlc3VsdC5BbW91bnQxLCB6ZXJvRm9yT25lLCBzd2FwQ2FsbGJhY2spCgl9IGVsc2UgewoJCS8vIHJlY2VpdmUgdG9rZW4xIGZyb20gc3dhcCBjYWxsYmFjawoJCS8vIHNlbmQgdG9rZW4wIHRvIHJlY2lwaWVudCAob3V0cHV0KQoJCWlmIHJlc3VsdC5BbW91bnQwLklzTmVnKCkgewoJCQlpLnNhZmVUcmFuc2ZlcigwLCBybG0sIHBvb2wsIHJlY2lwaWVudCwgdG9rZW4wUGF0aCwgcmVzdWx0LkFtb3VudDAuQWJzKCksIHRydWUpCgkJfQoJCWkuc2FmZVN3YXBDYWxsYmFjaygwLCBybG0sIHBvb2wsIHRva2VuMVBhdGgsIHJlc3VsdC5BbW91bnQxLCByZXN1bHQuQW1vdW50MCwgemVyb0Zvck9uZSwgc3dhcENhbGxiYWNrKQoJfQoKCXNsb3QwIDo9IHBvb2wuU2xvdDAoKQoJbGFzdE9ic2VydmF0aW9uLCBlcnIgOj0gb2JzZXJ2YXRpb25BdChvYnNlcnZhdGlvbnMsIHNsb3QwLk9ic2VydmF0aW9uSW5kZXgoKSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgl0b2tlbjBBbW91bnQgOj0gcmVzdWx0LkFtb3VudDAuVG9TdHJpbmcoKQoJdG9rZW4xQW1vdW50IDo9IHJlc3VsdC5BbW91bnQxLlRvU3RyaW5nKCkKCglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgoJY2hhaW4uRW1pdCgKCQkiU3dhcCIsCgkJInByZXZBZGRyIiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJwb29sUGF0aCIsIHBvb2wuUG9vbFBhdGgoKSwKCQkiemVyb0Zvck9uZSIsIHV0aWxzLkZvcm1hdEJvb2woemVyb0Zvck9uZSksCgkJInJlcXVlc3RBbW91bnQiLCBhbW91bnRTcGVjaWZpZWQsCgkJInNxcnRQcmljZUxpbWl0WDk2Iiwgc3FydFByaWNlTGltaXRYOTYsCgkJInJlY2lwaWVudCIsIHJlY2lwaWVudC5TdHJpbmcoKSwKCQkidG9rZW4wQW1vdW50IiwgdG9rZW4wQW1vdW50LAoJCSJ0b2tlbjFBbW91bnQiLCB0b2tlbjFBbW91bnQsCgkJInByb3RvY29sRmVlMCIsIHV0aWxzLkZvcm1hdEludChwb29sLlByb3RvY29sRmVlc1Rva2VuMCgpKSwKCQkicHJvdG9jb2xGZWUxIiwgdXRpbHMuRm9ybWF0SW50KHBvb2wuUHJvdG9jb2xGZWVzVG9rZW4xKCkpLAoJCSJzcXJ0UHJpY2VYOTYiLCBwb29sLlNsb3QwU3FydFByaWNlWDk2KCkuVG9TdHJpbmcoKSwKCQkiZXhhY3RJbiIsIHN0cmNvbnYuRm9ybWF0Qm9vbChjb21wLkV4YWN0SW5wdXQpLAoJCSJjdXJyZW50VGljayIsIHN0cmNvbnYuRm9ybWF0SW50KGludDY0KHBvb2wuU2xvdDBUaWNrKCkpLCAxMCksCgkJImxpcXVpZGl0eSIsIHBvb2wuTGlxdWlkaXR5KCkuVG9TdHJpbmcoKSwKCQkiZmVlR3Jvd3RoR2xvYmFsMFgxMjgiLCBwb29sLkZlZUdyb3d0aEdsb2JhbDBYMTI4KCkuVG9TdHJpbmcoKSwKCQkiZmVlR3Jvd3RoR2xvYmFsMVgxMjgiLCBwb29sLkZlZUdyb3d0aEdsb2JhbDFYMTI4KCkuVG9TdHJpbmcoKSwKCQkiYmFsYW5jZVRva2VuMCIsIHV0aWxzLkZvcm1hdEludChwb29sLkJhbGFuY2VUb2tlbjAoKSksCgkJImJhbGFuY2VUb2tlbjEiLCB1dGlscy5Gb3JtYXRJbnQocG9vbC5CYWxhbmNlVG9rZW4xKCkpLAoJCSJ0aWNrQ3VtdWxhdGl2ZSIsIHV0aWxzLkZvcm1hdEludChsYXN0T2JzZXJ2YXRpb24uVGlja0N1bXVsYXRpdmUoKSksCgkJInNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCIsIGxhc3RPYnNlcnZhdGlvbi5TZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjgoKSwKCQkib2JzZXJ2YXRpb25UaW1lc3RhbXAiLCB1dGlscy5Gb3JtYXRJbnQobGFzdE9ic2VydmF0aW9uLkJsb2NrVGltZXN0YW1wKCkpLAoJKQoKCXJldHVybiB0b2tlbjBBbW91bnQsIHRva2VuMUFtb3VudAp9CgovLyBEcnlTd2FwIHNpbXVsYXRlcyBhIHN3YXAgYWdhaW5zdCBhbiBpc29sYXRlZCBwb29sIGFuZCBvYnNlcnZhdGlvbiBzbmFwc2hvdDsKLy8gaXQgbmV2ZXIgd3JpdGVzIHN0b3JlZCBwb29sIG9yIG9yYWNsZSBzdGF0ZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHRva2VuMFBhdGg6IFJlZ2lzdGVyZWQgcGF0aCBvZiB0b2tlbjA7IGl0IG11c3QgYmUgdGhlIGZpcnN0IHRva2VuIGluIHRoZQovLyAgICAgcG9vbCdzIGNhbm9uaWNhbCB0b2tlbiBvcmRlcmluZy4KLy8gICAtIHRva2VuMVBhdGg6IFJlZ2lzdGVyZWQgcGF0aCBvZiB0b2tlbjE7IGl0IG11c3QgYmUgdGhlIHNlY29uZCB0b2tlbiBpbgovLyAgICAgdGhlIHBvb2wncyBjYW5vbmljYWwgdG9rZW4gb3JkZXJpbmcuCi8vICAgLSBmZWU6IEZlZSB0aWVyIGlkZW50aWZ5aW5nIHRoZSByZWdpc3RlcmVkIHBvb2wgdG8gc2ltdWxhdGUuCi8vICAgLSB6ZXJvRm9yT25lOiBTd2FwIGRpcmVjdGlvbjsgdHJ1ZSBzZWxscyB0b2tlbjAgZm9yIHRva2VuMSwgZmFsc2Ugc2VsbHMKLy8gICAgIHRva2VuMSBmb3IgdG9rZW4wLgovLyAgIC0gYW1vdW50U3BlY2lmaWVkOiBTaWduZWQgZGVjaW1hbCBhbW91bnQ7IHBvc2l0aXZlIHZhbHVlcyByZXF1ZXN0IGV4YWN0Ci8vICAgICBpbnB1dCwgbmVnYXRpdmUgdmFsdWVzIHJlcXVlc3QgZXhhY3Qgb3V0cHV0LCBhbmQgemVybyBpcyBpbnZhbGlkLgovLyAgIC0gc3FydFByaWNlTGltaXRYOTY6IERlY2ltYWwgUTk2IHNxdWFyZS1yb290LXByaWNlIGxpbWl0IHRoYXQgYm91bmRzIHRoZQovLyAgICAgc2ltdWxhdGlvbiBpbiBpdHMgZGlyZWN0aW9uLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYW1vdW50MDogU2lnbmVkIGRlY2ltYWwgdG9rZW4wIGRlbHRhIGZyb20gdGhlIHBvb2wncyBwZXJzcGVjdGl2ZSwgb3IKLy8gICAgICIwIiB3aGVuIHNpbXVsYXRpb24gZmFpbHMuCi8vICAgLSBhbW91bnQxOiBTaWduZWQgZGVjaW1hbCB0b2tlbjEgZGVsdGEgZnJvbSB0aGUgcG9vbCdzIHBlcnNwZWN0aXZlLCBvcgovLyAgICAgIjAiIHdoZW4gc2ltdWxhdGlvbiBmYWlscy4KLy8gICAtIGVycjogTmlsIHdoZW4gdGhlIHNpbXVsYXRpb24gc3VjY2VlZHM7IG5vbi1uaWwgZm9yIGludmFsaWQgaW5wdXRzLAovLyAgICAgbWlzc2luZyBwb29sIHN0YXRlLCBpbnZhbGlkIGxpbWl0cywgY29tcHV0YXRpb24gZmFpbHVyZXMsIG9yIGluc3VmZmljaWVudAovLyAgICAgcG9vbCBvdXRwdXQgYmFsYW5jZS4KZnVuYyAoaSAqcG9vbFYxKSBEcnlTd2FwKAoJdG9rZW4wUGF0aCBzdHJpbmcsCgl0b2tlbjFQYXRoIHN0cmluZywKCWZlZSB1aW50MzIsCgl6ZXJvRm9yT25lIGJvb2wsCglhbW91bnRTcGVjaWZpZWQgc3RyaW5nLAoJc3FydFByaWNlTGltaXRYOTYgc3RyaW5nLAopIChhbW91bnQwLCBhbW91bnQxIHN0cmluZywgZXJyIGVycm9yKSB7CglkZWZlciBmdW5jKCkgewoJCWlmIHIgOj0gcmVjb3ZlcigpOyByICE9IG5pbCB7CgkJCWFtb3VudDAgPSAiMCIKCQkJYW1vdW50MSA9ICIwIgoJCQlpZiByZWNvdmVyZWRFcnIsIG9rIDo9IHIuKGVycm9yKTsgb2sgewoJCQkJZXJyID0gcmVjb3ZlcmVkRXJyCgkJCX0gZWxzZSB7CgkJCQllcnIgPSB1Zm10LkVycm9yZigiJXYiLCByKQoJCQl9CgkJfQoJfSgpCgoJaS5hc3NlcnRQb29sVW5sb2NrZWQoKQoKCWFtb3VudHMgOj0gaTI1Ni5NdXN0RnJvbURlY2ltYWwoYW1vdW50U3BlY2lmaWVkKQoJaWYgYW1vdW50cy5Jc1plcm8oKSB7CgkJcmV0dXJuICIwIiwgIjAiLCBlcnJvcnMuTmV3KGVyckludmFsaWRTd2FwQW1vdW50KQoJfQoKCXBvb2wgOj0gaS5tdXN0R2V0UG9vbEJ5KHRva2VuMFBhdGgsIHRva2VuMVBhdGgsIGZlZSkKCWJsb2NrVGltZXN0YW1wIDo9IHRpbWUuTm93KCkuVW5peCgpCgoJc2xvdDBTdGFydCA6PSBwb29sLlNsb3QwKCkKCXNxcnRQcmljZUxpbWl0IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHNxcnRQcmljZUxpbWl0WDk2KQoJdmFsaWRhdGVQcmljZUxpbWl0cyhzbG90MFN0YXJ0LCB6ZXJvRm9yT25lLCBzcXJ0UHJpY2VMaW1pdCkKCglmZWVHcm93dGhHbG9iYWxYMTI4IDo9IGdldEZlZUdyb3d0aEdsb2JhbChwb29sLCB6ZXJvRm9yT25lKQoJZmVlUHJvdG9jb2wgOj0gZ2V0RmVlUHJvdG9jb2woc2xvdDBTdGFydCwgemVyb0Zvck9uZSkKCWNhY2hlIDo9IG5ld1N3YXBDYWNoZShmZWVQcm90b2NvbCwgcG9vbC5MaXF1aWRpdHkoKS5DbG9uZSgpLCBibG9ja1RpbWVzdGFtcCwgc2xvdDBTdGFydCkKCWNhY2hlLnJlYWRPbmx5ID0gdHJ1ZQoJc3RhdGUgOj0gbmV3U3dhcFN0YXRlKGFtb3VudHMsIGZlZUdyb3d0aEdsb2JhbFgxMjgsIGNhY2hlLmxpcXVpZGl0eVN0YXJ0LCBzbG90MFN0YXJ0KQoKCWNvbXAgOj0gU3dhcENvbXB1dGF0aW9uewoJCUFtb3VudFNwZWNpZmllZDogICBhbW91bnRzLAoJCVNxcnRQcmljZUxpbWl0WDk2OiBzcXJ0UHJpY2VMaW1pdCwKCQlaZXJvRm9yT25lOiAgICAgICAgemVyb0Zvck9uZSwKCQlFeGFjdElucHV0OiAgICAgICAgYW1vdW50cy5HdCh6ZXJvSTI1NiksCgkJSW5pdGlhbFN0YXRlOiAgICAgIHN0YXRlLAoJCUNhY2hlOiAgICAgICAgICAgICBjYWNoZSwKCX0KCglyZXN1bHQsIGVyciA6PSBpLmNvbXB1dGVTd2FwKHBvb2wsIG5pbCwgY29tcCwgbmlsKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuICIwIiwgIjAiLCBlcnIKCX0KCglpZiB6ZXJvRm9yT25lIHsKCQlpZiBwb29sLkJhbGFuY2VUb2tlbjEoKSA8IGduc21hdGguU2FmZUNvbnZlcnRUb0ludDY0KHJlc3VsdC5BbW91bnQxLkFicygpKSB7CgkJCXJldHVybiAiMCIsICIwIiwgZXJyb3JzLk5ldyhlcnJJbnN1ZmZpY2llbnRQb29sQmFsYW5jZSkKCQl9Cgl9IGVsc2UgewoJCWlmIHBvb2wuQmFsYW5jZVRva2VuMCgpIDwgZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQocmVzdWx0LkFtb3VudDAuQWJzKCkpIHsKCQkJcmV0dXJuICIwIiwgIjAiLCBlcnJvcnMuTmV3KGVyckluc3VmZmljaWVudFBvb2xCYWxhbmNlKQoJCX0KCX0KCglyZXR1cm4gcmVzdWx0LkFtb3VudDAuVG9TdHJpbmcoKSwgcmVzdWx0LkFtb3VudDEuVG9TdHJpbmcoKSwgbmlsCn0KCi8vIHRpY2tDcm9zc0hvb2tGbiBpcyBpbnZva2VkIGFmdGVyIGFuIGluaXRpYWxpemVkIHRpY2sgaXMgY3Jvc3NlZC4gU3dhcCB1c2VzIGl0Ci8vIGZvciBleHRlcm5hbGx5IHZpc2libGUgc2lkZSBlZmZlY3RzOyBEcnlTd2FwIHBhc3NlcyBuaWwuCnR5cGUgdGlja0Nyb3NzSG9va0ZuIGZ1bmMocG9vbCAqcGwuUG9vbCwgdGlja0lkIGludDMyLCB6ZXJvRm9yT25lIGJvb2wsIHRpbWVzdGFtcCBpbnQ2NCkKCi8vIGNvbXB1dGVTd2FwIGNhbGN1bGF0ZXMgc3dhcCBhbW91bnRzOyB0aWNrIGFjY291bnRpbmcgaXMgd3JpdHRlbiB1bmxlc3MgQ2FjaGUucmVhZE9ubHkgaXMgc2V0LgovLyBUaGUgY29tcHV0YXRpb24gY29udGludWVzIHVudGlsIGVpdGhlcjoKLy8gLSBUaGUgZW50aXJlIGFtb3VudCBpcyBjb25zdW1lZCAoYW1vdW50U3BlY2lmaWVkUmVtYWluaW5nID0gMCkKLy8gLSBUaGUgcHJpY2UgbGltaXQgaXMgcmVhY2hlZCAoc3FydFByaWNlWDk2ID0gc3FydFByaWNlTGltaXRYOTYpCi8vCi8vIEltcG9ydGFudDogVGhpcyBmdW5jdGlvbiBpcyBjcml0aWNhbCBmb3IgQU1NIHByaWNlIGRpc2NvdmVyeS4gSXQgaXRlcmF0ZXMgdGhyb3VnaAovLyB0aWNrIHJhbmdlcywgY2FsY3VsYXRpbmcgc3dhcCBhbW91bnRzIGFuZCBmZWVzIGZvciBlYWNoIGxpcXVpZGl0eSBzZWdtZW50LgovLyBSZXR1cm5zIGFuIGVycm9yIGlmIHRoZSBjb21wdXRhdGlvbiBmYWlscyBhdCBhbnkgc3RlcC4KLy8KLy8gVGhlIG9wdGlvbmFsIGBvblRpY2tDcm9zc2AgY2FsbGJhY2sgaXMgaW52b2tlZCB3aGVuIGFuIGluaXRpYWxpemVkIHRpY2sgaXMKLy8gY3Jvc3NlZDsgU3dhcCBzdXBwbGllcyBhIGhvb2sgdGhhdCBwZXJmb3JtcyBhIGNyb3NzLXJlYWxtIGNhbGwgaW50byB0aGUKLy8gY29uZmlndXJlZCB0aWNrLWNyb3NzIGhvb2ssIHdoaWxlIERyeVN3YXAgcGFzc2VzIG5pbC4KZnVuYyAoaSAqcG9vbFYxKSBjb21wdXRlU3dhcChwb29sICpwbC5Qb29sLCBvYnNlcnZhdGlvbnMgKnBsLk9ic2VydmF0aW9uVHJlZSwgY29tcCBTd2FwQ29tcHV0YXRpb24sIG9uVGlja0Nyb3NzIHRpY2tDcm9zc0hvb2tGbikgKCpTd2FwUmVzdWx0LCBlcnJvcikgewoJc3RhdGUgOj0gY29tcC5Jbml0aWFsU3RhdGUKCXZhciBlcnIgZXJyb3IKCgkvLyBDb21wdXRlIHN3YXAgc3RlcHMgdW50aWwgY29tcGxldGlvbgoJZm9yIHNob3VsZENvbnRpbnVlU3dhcChzdGF0ZSwgY29tcC5TcXJ0UHJpY2VMaW1pdFg5NikgewoJCXN0YXRlLCBlcnIgPSBpLmNvbXB1dGVTd2FwU3RlcChzdGF0ZSwgcG9vbCwgb2JzZXJ2YXRpb25zLCBjb21wLlplcm9Gb3JPbmUsIGNvbXAuU3FydFByaWNlTGltaXRYOTYsIGNvbXAuRXhhY3RJbnB1dCwgY29tcC5DYWNoZSwgb25UaWNrQ3Jvc3MpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBuaWwsIGVycgoJCX0KCX0KCgkvLyBDYWxjdWxhdGUgZmluYWwgYW1vdW50cwoJYW1vdW50MCA6PSBzdGF0ZS5hbW91bnRDYWxjdWxhdGVkCglhbW91bnQxIDo9IGkyNTYuWmVybygpLlN1Yihjb21wLkFtb3VudFNwZWNpZmllZCwgc3RhdGUuYW1vdW50U3BlY2lmaWVkUmVtYWluaW5nKQoJaWYgY29tcC5aZXJvRm9yT25lID09IGNvbXAuRXhhY3RJbnB1dCB7CgkJYW1vdW50MCwgYW1vdW50MSA9IGFtb3VudDEsIGFtb3VudDAKCX0KCgkvLyBQcmVwYXJlIHJlc3VsdAoJcmVzdWx0IDo9ICZTd2FwUmVzdWx0ewoJCUFtb3VudDA6ICAgICAgICAgICAgICBhbW91bnQwLAoJCUFtb3VudDE6ICAgICAgICAgICAgICBhbW91bnQxLAoJCU5ld1NxcnRQcmljZTogICAgICAgICBzdGF0ZS5zcXJ0UHJpY2VYOTYsCgkJTmV3VGljazogICAgICAgICAgICAgIHN0YXRlLnRpY2ssCgkJTmV3TGlxdWlkaXR5OiAgICAgICAgIHN0YXRlLmxpcXVpZGl0eSwKCQlOZXdQcm90b2NvbEZlZVRva2VuMDogcG9vbC5Qcm90b2NvbEZlZXNUb2tlbjAoKSwKCQlOZXdQcm90b2NvbEZlZVRva2VuMTogcG9vbC5Qcm90b2NvbEZlZXNUb2tlbjEoKSwKCQlGZWVHcm93dGhHbG9iYWwwWDEyODogcG9vbC5GZWVHcm93dGhHbG9iYWwwWDEyOCgpLAoJCUZlZUdyb3d0aEdsb2JhbDFYMTI4OiBwb29sLkZlZUdyb3d0aEdsb2JhbDFYMTI4KCksCgl9CgoJLy8gVXBkYXRlIHByb3RvY29sIGZlZXMgaWYgbmVjZXNzYXJ5CglpZiBjb21wLlplcm9Gb3JPbmUgewoJCWlmIHN0YXRlLnByb3RvY29sRmVlLkd0KHplcm8pIHsKCQkJcmVzdWx0Lk5ld1Byb3RvY29sRmVlVG9rZW4wID0gZ25zbWF0aC5TYWZlQWRkSW50NjQocmVzdWx0Lk5ld1Byb3RvY29sRmVlVG9rZW4wLCBnbnNtYXRoLlNhZmVDb252ZXJ0VG9JbnQ2NChzdGF0ZS5wcm90b2NvbEZlZSkpCgkJfQoJCXJlc3VsdC5GZWVHcm93dGhHbG9iYWwwWDEyOCA9IHN0YXRlLmZlZUdyb3d0aEdsb2JhbFgxMjguQ2xvbmUoKQoJfSBlbHNlIHsKCQlpZiBzdGF0ZS5wcm90b2NvbEZlZS5HdCh6ZXJvKSB7CgkJCXJlc3VsdC5OZXdQcm90b2NvbEZlZVRva2VuMSA9IGduc21hdGguU2FmZUFkZEludDY0KHJlc3VsdC5OZXdQcm90b2NvbEZlZVRva2VuMSwgZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQoc3RhdGUucHJvdG9jb2xGZWUpKQoJCX0KCQlyZXN1bHQuRmVlR3Jvd3RoR2xvYmFsMVgxMjggPSBzdGF0ZS5mZWVHcm93dGhHbG9iYWxYMTI4LkNsb25lKCkKCX0KCglyZXR1cm4gcmVzdWx0LCBuaWwKfQoKLy8gYXBwbHlTd2FwUmVzdWx0IHVwZGF0ZXMgcG9vbCBzdGF0ZSB3aXRoIGNvbXB1dGVkIHJlc3VsdHMuCi8vIEFsbCBzdGF0ZSBjaGFuZ2VzIGFyZSBhcHBsaWVkIGF0IG9uY2UgdG8gbWFpbnRhaW4gY29uc2lzdGVuY3kKZnVuYyBhcHBseVN3YXBSZXN1bHQocG9vbCAqcGwuUG9vbCwgcmVzdWx0ICpTd2FwUmVzdWx0KSB7CglzbG90MCA6PSBwb29sLlNsb3QwKCkKCXNsb3QwLlNldFNxcnRQcmljZVg5NihyZXN1bHQuTmV3U3FydFByaWNlKQoJc2xvdDAuU2V0VGljayhyZXN1bHQuTmV3VGljaykKCXBvb2wuU2V0U2xvdDAoc2xvdDApCgoJcG9vbC5TZXRMaXF1aWRpdHkocmVzdWx0Lk5ld0xpcXVpZGl0eSkKCXBvb2wuU2V0UHJvdG9jb2xGZWVzVG9rZW4wKHJlc3VsdC5OZXdQcm90b2NvbEZlZVRva2VuMCkKCXBvb2wuU2V0UHJvdG9jb2xGZWVzVG9rZW4xKHJlc3VsdC5OZXdQcm90b2NvbEZlZVRva2VuMSkKCXBvb2wuU2V0RmVlR3Jvd3RoR2xvYmFsMFgxMjgocmVzdWx0LkZlZUdyb3d0aEdsb2JhbDBYMTI4KQoJcG9vbC5TZXRGZWVHcm93dGhHbG9iYWwxWDEyOChyZXN1bHQuRmVlR3Jvd3RoR2xvYmFsMVgxMjgpCn0KCi8vIHZhbGlkYXRlUHJpY2VMaW1pdHMgZW5zdXJlcyB0aGUgcHJvdmlkZWQgcHJpY2UgbGltaXQgaXMgdmFsaWQgZm9yIHRoZSBzd2FwIGRpcmVjdGlvbgovLyBUaGUgZnVuY3Rpb24gZW5mb3JjZXMgdGhhdDoKLy8gRm9yIHplcm9Gb3JPbmUgKHNlbGxpbmcgdG9rZW4wKToKLy8gICAtIFByaWNlIGxpbWl0IG11c3QgYmUgYmVsb3cgY3VycmVudCBwcmljZQovLyAgIC0gUHJpY2UgbGltaXQgbXVzdCBiZSBhYm92ZSBNSU5fU1FSVF9SQVRJTwovLwovLyBGb3IgIXplcm9Gb3JPbmUgKHNlbGxpbmcgdG9rZW4xKToKLy8gICAtIFByaWNlIGxpbWl0IG11c3QgYmUgYWJvdmUgY3VycmVudCBwcmljZQovLyAgIC0gUHJpY2UgbGltaXQgbXVzdCBiZSBiZWxvdyBNQVhfU1FSVF9SQVRJTwpmdW5jIHZhbGlkYXRlUHJpY2VMaW1pdHMoc2xvdDAgcGwuU2xvdDAsIHplcm9Gb3JPbmUgYm9vbCwgc3FydFByaWNlTGltaXRYOTYgKnUyNTYuVWludCkgewoJaWYgemVyb0Zvck9uZSB7CgkJY29uZDEgOj0gc3FydFByaWNlTGltaXRYOTYuTHQoc2xvdDAuU3FydFByaWNlWDk2KCkpCgkJY29uZDIgOj0gc3FydFByaWNlTGltaXRYOTYuR3QoY29uc3RzLk1pblNxcnRSYXRpbygpKQoJCWlmICEoY29uZDEgJiYgY29uZDIpIHsKCQkJcGFuaWMobmV3RXJyb3JXaXRoRGV0YWlsKAoJCQkJZXJyUHJpY2VPdXRPZlJhbmdlLAoJCQkJdWZtdC5TcHJpbnRmKCJzcXJ0UHJpY2VMaW1pdFg5NiglcykgPCBzbG90MFN0YXJ0LnNxcnRQcmljZVg5NiglcykgJiYgc3FydFByaWNlTGltaXRYOTYoJXMpID4gTUlOX1NRUlRfUkFUSU8oJXMpIiwKCQkJCQlzcXJ0UHJpY2VMaW1pdFg5Ni5Ub1N0cmluZygpLAoJCQkJCXNsb3QwLlNxcnRQcmljZVg5NigpLlRvU3RyaW5nKCksCgkJCQkJc3FydFByaWNlTGltaXRYOTYuVG9TdHJpbmcoKSwKCQkJCQlNSU5fU1FSVF9SQVRJTyksCgkJCSkpCgkJfQoJfSBlbHNlIHsKCQljb25kMSA6PSBzcXJ0UHJpY2VMaW1pdFg5Ni5HdChzbG90MC5TcXJ0UHJpY2VYOTYoKSkKCQljb25kMiA6PSBzcXJ0UHJpY2VMaW1pdFg5Ni5MdChjb25zdHMuTWF4U3FydFJhdGlvKCkpCgkJaWYgIShjb25kMSAmJiBjb25kMikgewoJCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoCgkJCQllcnJQcmljZU91dE9mUmFuZ2UsCgkJCQl1Zm10LlNwcmludGYoInNxcnRQcmljZUxpbWl0WDk2KCVzKSA+IHNsb3QwU3RhcnQuc3FydFByaWNlWDk2KCVzKSAmJiBzcXJ0UHJpY2VMaW1pdFg5NiglcykgPCBNQVhfU1FSVF9SQVRJTyglcykiLAoJCQkJCXNxcnRQcmljZUxpbWl0WDk2LlRvU3RyaW5nKCksCgkJCQkJc2xvdDAuU3FydFByaWNlWDk2KCkuVG9TdHJpbmcoKSwKCQkJCQlzcXJ0UHJpY2VMaW1pdFg5Ni5Ub1N0cmluZygpLAoJCQkJCU1BWF9TUVJUX1JBVElPKSwKCQkJKSkKCQl9Cgl9Cn0KCi8vIGdldEZlZVByb3RvY29sIHJldHVybnMgdGhlIGFwcHJvcHJpYXRlIGZlZSBwcm90b2NvbCBiYXNlZCBvbiB6ZXJvIGZvciBvbmUuCi8vIFdoZW4gemVyb0Zvck9uZSBpcyB0cnVlLCB3ZSB3YW50IHRoZSBsb3dlciA0IGJpdHMgKCUgMTYpLgovLyBPdGhlcndpc2UsIHdlIHdhbnQgdGhlIHVwcGVyIDQgYml0cyAoLyAxNikuCmZ1bmMgZ2V0RmVlUHJvdG9jb2woc2xvdDAgcGwuU2xvdDAsIHplcm9Gb3JPbmUgYm9vbCkgdWludDggewoJc2hpZnQgOj0gdWludDgoMCkKCWlmICF6ZXJvRm9yT25lIHsKCQlzaGlmdCA9IDQKCX0KCXJldHVybiAoc2xvdDAuRmVlUHJvdG9jb2woKSA+PiBzaGlmdCkgJiB1aW50OCgweEYpCn0KCi8vIGdldEZlZUdyb3d0aEdsb2JhbCByZXR1cm5zIHRoZSBhcHByb3ByaWF0ZSBmZWUgZ3Jvd3RoIGdsb2JhbCBiYXNlZCBvbiB6ZXJvIGZvciBvbmUuCmZ1bmMgZ2V0RmVlR3Jvd3RoR2xvYmFsKHBvb2wgKnBsLlBvb2wsIHplcm9Gb3JPbmUgYm9vbCkgKnUyNTYuVWludCB7CglpZiB6ZXJvRm9yT25lIHsKCQlyZXR1cm4gcG9vbC5GZWVHcm93dGhHbG9iYWwwWDEyOCgpLkNsb25lKCkKCX0KCXJldHVybiBwb29sLkZlZUdyb3d0aEdsb2JhbDFYMTI4KCkuQ2xvbmUoKQp9CgovLyBzaG91bGRDb250aW51ZVN3YXAgY2hlY2tzIGlmIHN3YXAgc2hvdWxkIGNvbnRpbnVlIGJhc2VkIG9uIHJlbWFpbmluZyBhbW91bnQgYW5kIHByaWNlIGxpbWl0LgpmdW5jIHNob3VsZENvbnRpbnVlU3dhcChzdGF0ZSBTd2FwU3RhdGUsIHNxcnRQcmljZUxpbWl0WDk2ICp1MjU2LlVpbnQpIGJvb2wgewoJcmV0dXJuICFzdGF0ZS5hbW91bnRTcGVjaWZpZWRSZW1haW5pbmcuSXNaZXJvKCkgJiYgIXN0YXRlLnNxcnRQcmljZVg5Ni5FcShzcXJ0UHJpY2VMaW1pdFg5NikKfQoKLy8gY29tcHV0ZVN3YXBTdGVwIGV4ZWN1dGVzIGEgc2luZ2xlIHN0ZXAgb2Ygc3dhcCBhbmQgcmV0dXJucyBuZXcgc3RhdGUKZnVuYyAoaSAqcG9vbFYxKSBjb21wdXRlU3dhcFN0ZXAoCglzdGF0ZSBTd2FwU3RhdGUsCglwb29sICpwbC5Qb29sLAoJb2JzZXJ2YXRpb25zICpwbC5PYnNlcnZhdGlvblRyZWUsCgl6ZXJvRm9yT25lIGJvb2wsCglzcXJ0UHJpY2VMaW1pdFg5NiAqdTI1Ni5VaW50LAoJZXhhY3RJbnB1dCBib29sLAoJY2FjaGUgKlN3YXBDYWNoZSwKCW9uVGlja0Nyb3NzIHRpY2tDcm9zc0hvb2tGbiwKKSAoU3dhcFN0YXRlLCBlcnJvcikgewoJc3RlcCA6PSBjb21wdXRlU3dhcFN0ZXBJbml0KHN0YXRlLCBwb29sLCB6ZXJvRm9yT25lKQoKCS8vIGRldGVybWluaW5nIHRoZSBwcmljZSB0YXJnZXQgZm9yIHRoaXMgc3RlcAoJc3FydFJhdGlvVGFyZ2V0WDk2IDo9IGNvbXB1dGVUYXJnZXRTcXJ0UmF0aW8oc3RlcCwgc3FydFByaWNlTGltaXRYOTYsIHplcm9Gb3JPbmUpLkNsb25lKCkKCgkvLyBjb21wdXRpbmcgdGhlIGFtb3VudHMgdG8gYmUgc3dhcHBlZCBhdCB0aGlzIHN0ZXAKCXZhciAoCgkJbmV3U3RhdGUgU3dhcFN0YXRlCgkJZXJyICAgICAgZXJyb3IKCSkKCgluZXdTdGF0ZSwgc3RlcCA9IGNvbXB1dGVBbW91bnRzKHN0YXRlLCBzcXJ0UmF0aW9UYXJnZXRYOTYsIHBvb2wsIHN0ZXApCgluZXdTdGF0ZSwgZXJyID0gdXBkYXRlQW1vdW50cyhzdGVwLCBuZXdTdGF0ZSwgZXhhY3RJbnB1dCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBzdGF0ZSwgZXJyCgl9CgoJLy8gaWYgdGhlIHByb3RvY29sIGZlZSBpcyBvbiwgY2FsY3VsYXRlIGhvdyBtdWNoIGlzIG93ZWQsCgkvLyBkZWNyZW1lbnQgZmVlIGFtb3VudCwgYW5kIGluY3JlbWVudCBwcm90b2NvbCBmZWUKCWlmIGNhY2hlLmZlZVByb3RvY29sID4gMCB7CgkJbmV3U3RhdGUsIHN0ZXAsIGVyciA9IHVwZGF0ZUZlZVByb3RvY29sKHN0ZXAsIGNhY2hlLmZlZVByb3RvY29sLCBuZXdTdGF0ZSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIHN0YXRlLCBlcnIKCQl9Cgl9CgoJLy8gdXBkYXRlIGdsb2JhbCBmZWUgdHJhY2tlcgoJaWYgbmV3U3RhdGUubGlxdWlkaXR5Lkd0KHUyNTYuWmVybygpKSB7CgkJdXBkYXRlIDo9IHUyNTYuTXVsRGl2KHN0ZXAuZmVlQW1vdW50LCBmaXhlZFBvaW50UTEyOCwgbmV3U3RhdGUubGlxdWlkaXR5KQoJCWZlZUdyb3d0aEdsb2JhbFgxMjggOj0gdTI1Ni5aZXJvKCkuQWRkKG5ld1N0YXRlLmZlZUdyb3d0aEdsb2JhbFgxMjgsIHVwZGF0ZSkKCQluZXdTdGF0ZS5zZXRGZWVHcm93dGhHbG9iYWxYMTI4KGZlZUdyb3d0aEdsb2JhbFgxMjgpCgl9CgoJLy8gaGFuZGxpbmcgdGljayB0cmFuc2l0aW9ucwoJaWYgbmV3U3RhdGUuc3FydFByaWNlWDk2LkVxKHN0ZXAuc3FydFByaWNlTmV4dFg5NikgewoJCW5ld1N0YXRlLCBlcnIgPSBpLnRpY2tUcmFuc2l0aW9uKHN0ZXAsIHplcm9Gb3JPbmUsIG5ld1N0YXRlLCBwb29sLCBvYnNlcnZhdGlvbnMsIGNhY2hlLCBvblRpY2tDcm9zcykKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIHN0YXRlLCBlcnIKCQl9Cgl9IGVsc2UgaWYgbmV3U3RhdGUuc3FydFByaWNlWDk2Lk5lcShzdGVwLnNxcnRQcmljZVN0YXJ0WDk2KSB7CgkJbmV3U3RhdGUuc2V0VGljayhnbnNtYXRoLlRpY2tNYXRoR2V0VGlja0F0U3FydFJhdGlvKG5ld1N0YXRlLnNxcnRQcmljZVg5NikpCgl9CgoJcmV0dXJuIG5ld1N0YXRlLCBuaWwKfQoKLy8gdXBkYXRlRmVlUHJvdG9jb2wgY2FsY3VsYXRlcyBhbmQgdXBkYXRlcyBwcm90b2NvbCBmZWVzIGZvciB0aGUgY3VycmVudCBzdGVwLgpmdW5jIHVwZGF0ZUZlZVByb3RvY29sKHN0ZXAgU3RlcENvbXB1dGF0aW9ucywgZmVlUHJvdG9jb2wgdWludDgsIHN0YXRlIFN3YXBTdGF0ZSkgKFN3YXBTdGF0ZSwgU3RlcENvbXB1dGF0aW9ucywgZXJyb3IpIHsKCWRlbHRhIDo9IHUyNTYuWmVybygpLkRpdihzdGVwLmZlZUFtb3VudCwgdTI1Ni5OZXdVaW50KHVpbnQ2NChmZWVQcm90b2NvbCkpKQoKCW5ld0ZlZUFtb3VudCwgb3ZlcmZsb3cgOj0gdTI1Ni5aZXJvKCkuU3ViT3ZlcmZsb3coc3RlcC5mZWVBbW91bnQsIGRlbHRhKQoJaWYgb3ZlcmZsb3cgewoJCXJldHVybiBzdGF0ZSwgc3RlcCwgZXJyb3JzLk5ldyhlcnJVbmRlcmZsb3cpCgl9CgoJc3RlcC5mZWVBbW91bnQgPSBuZXdGZWVBbW91bnQKCgluZXdQcm90b2NvbEZlZSwgb3ZlcmZsb3cgOj0gdTI1Ni5aZXJvKCkuQWRkT3ZlcmZsb3coc3RhdGUucHJvdG9jb2xGZWUsIGRlbHRhKQoJaWYgb3ZlcmZsb3cgewoJCXJldHVybiBzdGF0ZSwgc3RlcCwgZXJyb3JzLk5ldyhlcnJPdmVyZmxvdykKCX0KCXN0YXRlLnByb3RvY29sRmVlID0gbmV3UHJvdG9jb2xGZWUKCglyZXR1cm4gc3RhdGUsIHN0ZXAsIG5pbAp9CgovLyBjb21wdXRlU3dhcFN0ZXBJbml0IGluaXRpYWxpemVzIHRoZSBjb21wdXRhdGlvbiBmb3IgYSBzaW5nbGUgc3dhcCBzdGVwLgpmdW5jIGNvbXB1dGVTd2FwU3RlcEluaXQoc3RhdGUgU3dhcFN0YXRlLCBwb29sICpwbC5Qb29sLCB6ZXJvRm9yT25lIGJvb2wpIFN0ZXBDb21wdXRhdGlvbnMgewoJdmFyIHN0ZXAgU3RlcENvbXB1dGF0aW9ucwoJc3RlcC5zcXJ0UHJpY2VTdGFydFg5NiA9IHN0YXRlLnNxcnRQcmljZVg5NgoJdGlja05leHQsIGluaXRpYWxpemVkIDo9IHRpY2tCaXRtYXBOZXh0SW5pdGlhbGl6ZWRUaWNrV2l0aEluT25lV29yZCgKCQlwb29sLAoJCXN0YXRlLnRpY2ssCgkJcG9vbC5UaWNrU3BhY2luZygpLAoJCXplcm9Gb3JPbmUsCgkpCgoJc3RlcC50aWNrTmV4dCA9IHRpY2tOZXh0CglzdGVwLmluaXRpYWxpemVkID0gaW5pdGlhbGl6ZWQKCgkvLyBwcmV2ZW50IG92ZXJzaG9vdCB0aGUgbWluL21heCB0aWNrCglzdGVwLmNsYW1wVGlja05leHQoKQoJLy8gZ2V0IHRoZSBwcmljZSBmb3IgdGhlIG5leHQgdGljawoJc3RlcC5zcXJ0UHJpY2VOZXh0WDk2ID0gZ25zbWF0aC5UaWNrTWF0aEdldFNxcnRSYXRpb0F0VGljayhzdGVwLnRpY2tOZXh0KQoJcmV0dXJuIHN0ZXAKfQoKLy8gY29tcHV0ZVRhcmdldFNxcnRSYXRpbyBkZXRlcm1pbmVzIHRoZSB0YXJnZXQgc3FydCBwcmljZSBmb3IgdGhlIGN1cnJlbnQgc3dhcCBzdGVwLgpmdW5jIGNvbXB1dGVUYXJnZXRTcXJ0UmF0aW8oc3RlcCBTdGVwQ29tcHV0YXRpb25zLCBzcXJ0UHJpY2VMaW1pdFg5NiAqdTI1Ni5VaW50LCB6ZXJvRm9yT25lIGJvb2wpICp1MjU2LlVpbnQgewoJaWYgc2hvdWxkVXNlUHJpY2VMaW1pdChzdGVwLnNxcnRQcmljZU5leHRYOTYsIHNxcnRQcmljZUxpbWl0WDk2LCB6ZXJvRm9yT25lKSB7CgkJcmV0dXJuIHNxcnRQcmljZUxpbWl0WDk2Cgl9CglyZXR1cm4gc3RlcC5zcXJ0UHJpY2VOZXh0WDk2Cn0KCi8vIHNob3VsZFVzZVByaWNlTGltaXQgcmV0dXJucyB0cnVlIGlmIHRoZSBwcmljZSBsaW1pdCBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIHRoZSBuZXh0IHRpY2sgcHJpY2UKZnVuYyBzaG91bGRVc2VQcmljZUxpbWl0KHNxcnRQcmljZU5leHQsIHNxcnRQcmljZUxpbWl0ICp1MjU2LlVpbnQsIHplcm9Gb3JPbmUgYm9vbCkgYm9vbCB7CglpZiB6ZXJvRm9yT25lIHsKCQlyZXR1cm4gc3FydFByaWNlTmV4dC5MdChzcXJ0UHJpY2VMaW1pdCkKCX0KCXJldHVybiBzcXJ0UHJpY2VOZXh0Lkd0KHNxcnRQcmljZUxpbWl0KQp9CgovLyBjb21wdXRlQW1vdW50cyBjYWxjdWxhdGVzIHRoZSBpbnB1dCBhbmQgb3V0cHV0IGFtb3VudHMgZm9yIHRoZSBjdXJyZW50IHN3YXAgc3RlcC4KZnVuYyBjb21wdXRlQW1vdW50cyhzdGF0ZSBTd2FwU3RhdGUsIHNxcnRSYXRpb1RhcmdldFg5NiAqdTI1Ni5VaW50LCBwb29sICpwbC5Qb29sLCBzdGVwIFN0ZXBDb21wdXRhdGlvbnMpIChTd2FwU3RhdGUsIFN0ZXBDb21wdXRhdGlvbnMpIHsKCXNxcnRQcmljZVg5NiwgYW1vdW50SW4sIGFtb3VudE91dCwgZmVlQW1vdW50IDo9IGduc21hdGguU3dhcE1hdGhDb21wdXRlU3dhcFN0ZXAoCgkJc3RhdGUuc3FydFByaWNlWDk2LAoJCXNxcnRSYXRpb1RhcmdldFg5NiwKCQlzdGF0ZS5saXF1aWRpdHksCgkJc3RhdGUuYW1vdW50U3BlY2lmaWVkUmVtYWluaW5nLAoJCXVpbnQ2NChwb29sLkZlZSgpKSwKCSkKCglzdGVwLmFtb3VudEluID0gYW1vdW50SW4KCXN0ZXAuYW1vdW50T3V0ID0gYW1vdW50T3V0CglzdGVwLmZlZUFtb3VudCA9IGZlZUFtb3VudAoKCXN0YXRlLnNldFNxcnRQcmljZVg5NihzcXJ0UHJpY2VYOTYpCgoJcmV0dXJuIHN0YXRlLCBzdGVwCn0KCi8vIHVwZGF0ZUFtb3VudHMgY2FsY3VsYXRlcyBuZXcgcmVtYWluaW5nIGFuZCBjYWxjdWxhdGVkIGFtb3VudHMgYmFzZWQgb24gdGhlIHN3YXAgc3RlcC4KLy8gRm9yIGV4YWN0IGlucHV0IHN3YXBzOgovLyAgIC0gRGVjcmVtZW50cyByZW1haW5pbmcgaW5wdXQgYW1vdW50IGJ5IChhbW91bnRJbiArIGZlZUFtb3VudCkKLy8gICAtIERlY3JlbWVudHMgY2FsY3VsYXRlZCBhbW91bnQgYnkgYW1vdW50T3V0Ci8vCi8vIEZvciBleGFjdCBvdXRwdXQgc3dhcHM6Ci8vICAgLSBJbmNyZW1lbnRzIHJlbWFpbmluZyBvdXRwdXQgYW1vdW50IGJ5IGFtb3VudE91dAovLyAgIC0gSW5jcmVtZW50cyBjYWxjdWxhdGVkIGFtb3VudCBieSAoYW1vdW50SW4gKyBmZWVBbW91bnQpCmZ1bmMgdXBkYXRlQW1vdW50cyhzdGVwIFN0ZXBDb21wdXRhdGlvbnMsIHN0YXRlIFN3YXBTdGF0ZSwgZXhhY3RJbnB1dCBib29sKSAoU3dhcFN0YXRlLCBlcnJvcikgewoJYW1vdW50SW5XaXRoRmVlVTI1NiA6PSB1MjU2Llplcm8oKS5BZGQoc3RlcC5hbW91bnRJbiwgc3RlcC5mZWVBbW91bnQpCglpZiBhbW91bnRJbldpdGhGZWVVMjU2Lkd0KG1heEludDI1NikgewoJCXJldHVybiBzdGF0ZSwgZXJyb3JzLk5ldyhlcnJPdmVyZmxvdykKCX0KCglhbW91bnRJbldpdGhGZWUgOj0gaTI1Ni5Gcm9tVWludDI1NihhbW91bnRJbldpdGhGZWVVMjU2KQoJaWYgc3RlcC5hbW91bnRPdXQuR3QobWF4SW50MjU2KSB7CgkJcmV0dXJuIHN0YXRlLCBlcnJvcnMuTmV3KGVyck92ZXJmbG93KQoJfQoKCXZhciAoCgkJYW1vdW50U3BlY2lmaWVkUmVtYWluaW5nICppMjU2LkludAoJCWFtb3VudENhbGN1bGF0ZWQgICAgICAgICAqaTI1Ni5JbnQKCQlvdmVyZmxvdyAgICAgICAgICAgICAgICAgYm9vbAoJKQoKCWlmIGV4YWN0SW5wdXQgewoJCWFtb3VudFNwZWNpZmllZFJlbWFpbmluZywgb3ZlcmZsb3cgPSBpMjU2Llplcm8oKS5TdWJPdmVyZmxvdyhzdGF0ZS5hbW91bnRTcGVjaWZpZWRSZW1haW5pbmcsIGFtb3VudEluV2l0aEZlZSkKCQlpZiBvdmVyZmxvdyB7CgkJCXJldHVybiBzdGF0ZSwgZXJyb3JzLk5ldyhlcnJVbmRlcmZsb3cpCgkJfQoJCWFtb3VudENhbGN1bGF0ZWQsIG92ZXJmbG93ID0gaTI1Ni5aZXJvKCkuU3ViT3ZlcmZsb3coc3RhdGUuYW1vdW50Q2FsY3VsYXRlZCwgaTI1Ni5Gcm9tVWludDI1NihzdGVwLmFtb3VudE91dCkpCgkJaWYgb3ZlcmZsb3cgewoJCQlyZXR1cm4gc3RhdGUsIGVycm9ycy5OZXcoZXJyVW5kZXJmbG93KQoJCX0KCX0gZWxzZSB7CgkJYW1vdW50U3BlY2lmaWVkUmVtYWluaW5nLCBvdmVyZmxvdyA9IGkyNTYuWmVybygpLkFkZE92ZXJmbG93KHN0YXRlLmFtb3VudFNwZWNpZmllZFJlbWFpbmluZywgaTI1Ni5Gcm9tVWludDI1NihzdGVwLmFtb3VudE91dCkpCgkJaWYgb3ZlcmZsb3cgewoJCQlyZXR1cm4gc3RhdGUsIGVycm9ycy5OZXcoZXJyT3ZlcmZsb3cpCgkJfQoJCWFtb3VudENhbGN1bGF0ZWQsIG92ZXJmbG93ID0gaTI1Ni5aZXJvKCkuQWRkT3ZlcmZsb3coc3RhdGUuYW1vdW50Q2FsY3VsYXRlZCwgYW1vdW50SW5XaXRoRmVlKQoJCWlmIG92ZXJmbG93IHsKCQkJcmV0dXJuIHN0YXRlLCBlcnJvcnMuTmV3KGVyck92ZXJmbG93KQoJCX0KCX0KCgkvLyBJZiBhbiBvdmVyZmxvd2VkIHZhbHVlIGlzIHN0b3JlZCBpbiBzdGF0ZSwgaXQgbWF5IGNhdXNlIHByb2JsZW1zIGluIHRoZSBuZXh0IHN0ZXAKCWlmIGFtb3VudENhbGN1bGF0ZWQuR3QobWF4SW50NjQpIHx8IGFtb3VudFNwZWNpZmllZFJlbWFpbmluZy5HdChtYXhJbnQ2NCkgewoJCXJldHVybiBzdGF0ZSwgZXJyb3JzLk5ldyhlcnJPdmVyZmxvdykKCX0KCgkvLyBJZiBhbiB1bmRlcmZsb3dlZCB2YWx1ZSBpcyBzdG9yZWQgaW4gc3RhdGUsIGl0IG1heSBjYXVzZSBwcm9ibGVtcyBpbiB0aGUgbmV4dCBzdGVwCglpZiBhbW91bnRDYWxjdWxhdGVkLkx0KG1pbkludDY0KSB8fCBhbW91bnRTcGVjaWZpZWRSZW1haW5pbmcuTHQobWluSW50NjQpIHsKCQlyZXR1cm4gc3RhdGUsIGVycm9ycy5OZXcoZXJyVW5kZXJmbG93KQoJfQoKCXN0YXRlLmFtb3VudFNwZWNpZmllZFJlbWFpbmluZyA9IGFtb3VudFNwZWNpZmllZFJlbWFpbmluZwoJc3RhdGUuYW1vdW50Q2FsY3VsYXRlZCA9IGFtb3VudENhbGN1bGF0ZWQKCglyZXR1cm4gc3RhdGUsIG5pbAp9CgovLyB0aWNrVHJhbnNpdGlvbiBoYW5kbGVzIHRoZSB0cmFuc2l0aW9uIGJldHdlZW4gcHJpY2UgdGlja3MgZHVyaW5nIGEgc3dhcApmdW5jIChpICpwb29sVjEpIHRpY2tUcmFuc2l0aW9uKHN0ZXAgU3RlcENvbXB1dGF0aW9ucywgemVyb0Zvck9uZSBib29sLCBzdGF0ZSBTd2FwU3RhdGUsIHBvb2wgKnBsLlBvb2wsIG9ic2VydmF0aW9ucyAqcGwuT2JzZXJ2YXRpb25UcmVlLCBjYWNoZSAqU3dhcENhY2hlLCBvblRpY2tDcm9zcyB0aWNrQ3Jvc3NIb29rRm4pIChTd2FwU3RhdGUsIGVycm9yKSB7CgkvLyBlbnN1cmUgZXhpc3Rpbmcgc3RhdGUgdG8ga2VlcCBpbW11dGFiaWxpdHkKCW5ld1N0YXRlIDo9IHN0YXRlCgoJaWYgc3RlcC5pbml0aWFsaXplZCB7CgkJdmFyIGxpcXVpZGl0eU5ldCAqaTI1Ni5JbnQKCQlpZiBjYWNoZS5yZWFkT25seSB7CgkJCS8vIFF1b3RlcyBuZWVkIG9ubHkgdGhlIGxpcXVpZGl0eSBkZWx0YS4gT3V0c2lkZSBmZWUvb3JhY2xlIGFjY3VtdWxhdG9ycwoJCQkvLyBkbyBub3QgYWZmZWN0IHByaWNpbmcsIGFuZCB0aGUgbW9ub3RvbmljIHBhdGggbmV2ZXIgcmV2aXNpdHMgYSB0aWNrLgoJCQl0aWNrIDo9IGdldFRpY2socG9vbCwgc3RlcC50aWNrTmV4dCkKCQkJbGlxdWlkaXR5TmV0ID0gaTI1Ni5NdXN0RnJvbURlY2ltYWwodGljay5MaXF1aWRpdHlOZXQoKSkKCQl9IGVsc2UgewoJCQkvLyBDb21wdXRlIG9yYWNsZSB2YWx1ZXMgb24gZmlyc3QgaW5pdGlhbGl6ZWQgdGljayBjcm9zcy4KCQkJaWYgIWNhY2hlLmNvbXB1dGVkTGF0ZXN0T2JzZXJ2YXRpb24gewoJCQkJdGlja0N1bXVsYXRpdmUsIHNlY29uZHNQZXJMaXF1aWRpdHlTdHIsIGVyciA6PSBvYnNlcnZlU2luZ2xlKAoJCQkJCW9ic2VydmF0aW9ucywKCQkJCQljYWNoZS5ibG9ja1RpbWVzdGFtcCwKCQkJCQkwLAoJCQkJCWNhY2hlLnNsb3QwU3RhcnQuVGljaygpLAoJCQkJCWNhY2hlLnNsb3QwU3RhcnQuT2JzZXJ2YXRpb25JbmRleCgpLAoJCQkJCWNhY2hlLmxpcXVpZGl0eVN0YXJ0LAoJCQkJCWNhY2hlLnNsb3QwU3RhcnQuT2JzZXJ2YXRpb25DYXJkaW5hbGl0eSgpLAoJCQkJKQoJCQkJaWYgZXJyICE9IG5pbCB7CgkJCQkJcmV0dXJuIG5ld1N0YXRlLCBlcnIKCQkJCX0KCgkJCQljYWNoZS50aWNrQ3VtdWxhdGl2ZSA9IHRpY2tDdW11bGF0aXZlCgkJCQljYWNoZS5zZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjggPSB1MjU2Lk11c3RGcm9tRGVjaW1hbChzZWNvbmRzUGVyTGlxdWlkaXR5U3RyKQoJCQkJY2FjaGUuY29tcHV0ZWRMYXRlc3RPYnNlcnZhdGlvbiA9IHRydWUKCQkJfQoKCQkJZmVlMCwgZmVlMSA6PSB1MjU2Llplcm8oKSwgdTI1Ni5aZXJvKCkKCQkJaWYgemVyb0Zvck9uZSB7CgkJCQlmZWUwID0gc3RhdGUuZmVlR3Jvd3RoR2xvYmFsWDEyOAoJCQkJZmVlMSA9IHBvb2wuRmVlR3Jvd3RoR2xvYmFsMVgxMjgoKQoJCQl9IGVsc2UgewoJCQkJZmVlMCA9IHBvb2wuRmVlR3Jvd3RoR2xvYmFsMFgxMjgoKQoJCQkJZmVlMSA9IHN0YXRlLmZlZUdyb3d0aEdsb2JhbFgxMjgKCQkJfQoKCQkJbGlxdWlkaXR5TmV0ID0gdGlja0Nyb3NzKAoJCQkJcG9vbCwKCQkJCXN0ZXAudGlja05leHQsCgkJCQlmZWUwLAoJCQkJZmVlMSwKCQkJCWNhY2hlLnNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCwKCQkJCWNhY2hlLnRpY2tDdW11bGF0aXZlLAoJCQkJY2FjaGUuYmxvY2tUaW1lc3RhbXAsCgkJCSkKCQl9CgoJCWlmIHplcm9Gb3JPbmUgewoJCQlsaXF1aWRpdHlOZXQgPSBpMjU2Llplcm8oKS5OZWcobGlxdWlkaXR5TmV0KQoJCX0KCgkJbmV3U3RhdGUubGlxdWlkaXR5ID0gZ25zbWF0aC5MaXF1aWRpdHlNYXRoQWRkRGVsdGEoc3RhdGUubGlxdWlkaXR5LCBsaXF1aWRpdHlOZXQpCgoJCWlmICFjYWNoZS5yZWFkT25seSAmJiBvblRpY2tDcm9zcyAhPSBuaWwgewoJCQlvblRpY2tDcm9zcyhwb29sLCBzdGVwLnRpY2tOZXh0LCB6ZXJvRm9yT25lLCBjYWNoZS5ibG9ja1RpbWVzdGFtcCkKCQl9Cgl9CgoJbmV3U3RhdGUudGljayA9IHN0ZXAudGlja05leHQKCWlmIHplcm9Gb3JPbmUgewoJCW5ld1N0YXRlLnRpY2sgPSBzdGVwLnRpY2tOZXh0IC0gMQoJfQoKCXJldHVybiBuZXdTdGF0ZSwgbmlsCn0KGpuWAQoIdGljay5nbm8SjZYBcGFja2FnZSBwb29sCgppbXBvcnQgKAoJImduby5sYW5kL3AvZ25vc3dhcC9jb25zdHMvdjEiCgkiZ25vLmxhbmQvcC9nbm9zd2FwL2duc21hdGgvdjEiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgoJaTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL2ludDI1Ni92MSIKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJcGwgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgopCgovLyBNQVhfTElRVUlESVRZX1BFUl9USUNLXyogdmFsdWVzIGFyZSBzcGFjaW5nLXNwZWNpZmljIGxpbWl0cyByZXR1cm5lZCBieQovLyBjYWxjdWxhdGVNYXhMaXF1aWRpdHlQZXJUaWNrOyB0aGV5IGFyZSBub3QgYSB1bml2ZXJzYWwgdWludDEyOCBtYXhpbXVtLgoKY29uc3QgKAoJTUFYX0xJUVVJRElUWV9QRVJfVElDS19TUEFDSU5HXzEgICAgICAgICA9ICIxOTE3NTc1MzA0NzczNTUzMDE0NzkxODE3NjYyNzM0NzciCglNQVhfTElRVUlESVRZX1BFUl9USUNLX1NQQUNJTkdfMTAgICAgICAgID0gIjE5MTc1Njk5MDE3ODMyMDM5ODY3MTk4NzA0MzE1NTU5OTAiCglNQVhfTElRVUlESVRZX1BFUl9USUNLX1NQQUNJTkdfNjAgICAgICAgID0gIjExNTA1NzQzNTk4MzQxMTE0NTcxODgwNzk4MjIyNTQ0OTk0IgoJTUFYX0xJUVVJRElUWV9QRVJfVElDS19TUEFDSU5HXzIwMCAgICAgICA9ICIzODM1MDMxNzQ3MTA4NTE0MTgzMDY1MTkzMzY2NzUwNDU4OCIKCU1JTl9USUNLICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzIgPSAtODg3MjcyCglNQVhfVElDSyAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyID0gODg3MjcyCikKCi8vIG1heExpcXVpZGl0eVBlclRpY2tTcGFjaW5nKiByZXR1cm4gdGhlIHByZWNvbXB1dGVkIG1heC1saXF1aWRpdHktcGVyLXRpY2sgZm9yCi8vIGVhY2ggc3VwcG9ydGVkIHRpY2sgc3BhY2luZy4gVGhleSBhcmUgY29uc3RydWN0b3JzIChub3QgcGFja2FnZS1sZXZlbCB2YXJzKSBzbwovLyBlYWNoIGNhbGxlciByZWNlaXZlcyBhIGZyZXNoIGluc3RhbmNlIOKAlCBjYWxjdWxhdGVNYXhMaXF1aWRpdHlQZXJUaWNrIHJldHVybnMKLy8gdGhlIHZhbHVlIGRpcmVjdGx5IHRvIGNhbGxlcnMsIGFuZCBhIHNoYXJlZCBzaW5nbGV0b24gY291bGQgb3RoZXJ3aXNlIGJlCi8vIG11dGF0ZWQgaW4gcGxhY2UgYW5kIGNvcnJ1cHQgZXZlcnkgY2FsbGVyLiBWYWx1ZXMgYXJlIGJ1aWx0IGZyb20gbGl0dGxlLWVuZGlhbgovLyBbNF11aW50NjQgbGl0ZXJhbHMgdG8gYXZvaWQgcnVudGltZSBkZWNpbWFsIHBhcnNpbmcuCmZ1bmMgbWF4TGlxdWlkaXR5UGVyVGlja1NwYWNpbmcxRnJvbURlYygpICp1MjU2LlVpbnQgewoJcmV0dXJuICZ1MjU2LlVpbnR7MzYzOTUyNDYzNzY0NTY0NjI3NywgMTAzOTUxOTY1NTY3MDAsIDAsIDB9IC8vIDE5MTc1NzUzMDQ3NzM1NTMwMTQ3OTE4MTc2NjI3MzQ3Nwp9CgpmdW5jIG1heExpcXVpZGl0eVBlclRpY2tTcGFjaW5nMTBGcm9tRGVjKCkgKnUyNTYuVWludCB7CglyZXR1cm4gJnUyNTYuVWludHs0NzI3MzA2MjY2MzU0OTM4MjYyLCAxMDM5NTE2NzI2NzAzMDgsIDAsIDB9IC8vIDE5MTc1Njk5MDE3ODMyMDM5ODY3MTk4NzA0MzE1NTU5OTAKfQoKZnVuYyBtYXhMaXF1aWRpdHlQZXJUaWNrU3BhY2luZzYwRnJvbURlYygpICp1MjU2LlVpbnQgewoJcmV0dXJuICZ1MjU2LlVpbnR7MTQyODk1OTk1NTEyNjU3OTI5OCwgNjIzNzI3NjEwMjY5MTMxLCAwLCAwfSAvLyAxMTUwNTc0MzU5ODM0MTExNDU3MTg4MDc5ODIyMjU0NDk5NAp9CgpmdW5jIG1heExpcXVpZGl0eVBlclRpY2tTcGFjaW5nMjAwRnJvbURlYygpICp1MjU2LlVpbnQgewoJcmV0dXJuICZ1MjU2LlVpbnR7NjU5MjQyOTMzMTQyNDg4MzE0OCwgMjA3ODk3NDg3NTg4Mjk2NSwgMCwgMH0gLy8gMzgzNTAzMTc0NzEwODUxNDE4MzA2NTE5MzM2Njc1MDQ1ODgKfQoKLy8gZ2V0RmVlR3Jvd3RoSW5zaWRlIGNhbGN1bGF0ZXMgdGhlIGZlZSBncm93dGggd2l0aGluIGEgc3BlY2lmaWVkIHRpY2sgcmFuZ2UuCi8vCi8vIFRoaXMgZnVuY3Rpb24gY29tcHV0ZXMgdGhlIGFjY3VtdWxhdGVkIGZlZSBncm93dGggZm9yIHRva2VuIDAgYW5kIHRva2VuIDEgaW5zaWRlIGEgZ2l2ZW4gdGljayByYW5nZQovLyAoYHRpY2tMb3dlcmAgdG8gYHRpY2tVcHBlcmApIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHRpY2sgcG9zaXRpb24gKGB0aWNrQ3VycmVudGApLiBJdCBpc29sYXRlcyB0aGUgZmVlCi8vIGdyb3d0aCB3aXRoaW4gdGhlIHJhbmdlIGJ5IHN1YnRyYWN0aW5nIHRoZSBmZWUgZ3Jvd3RoIGJlbG93IHRoZSBsb3dlciB0aWNrIGFuZCBhYm92ZSB0aGUgdXBwZXIgdGljawovLyBmcm9tIHRoZSBnbG9iYWwgZmVlIGdyb3d0aC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHRpY2tMb3dlcjogaW50MzIsIHRoZSBsb3dlciB0aWNrIGJvdW5kYXJ5IG9mIHRoZSByYW5nZS4KLy8gICAtIHRpY2tVcHBlcjogaW50MzIsIHRoZSB1cHBlciB0aWNrIGJvdW5kYXJ5IG9mIHRoZSByYW5nZS4KLy8gICAtIHRpY2tDdXJyZW50OiBpbnQzMiwgdGhlIGN1cnJlbnQgdGljayBpbmRleC4KLy8gICAtIGZlZUdyb3d0aEdsb2JhbDBYMTI4OiAqdTI1Ni5VaW50LCB0aGUgZ2xvYmFsIGZlZSBncm93dGggZm9yIHRva2VuIDAgaW4gWDEyOCBwcmVjaXNpb24uCi8vICAgLSBmZWVHcm93dGhHbG9iYWwxWDEyODogKnUyNTYuVWludCwgdGhlIGdsb2JhbCBmZWUgZ3Jvd3RoIGZvciB0b2tlbiAxIGluIFgxMjggcHJlY2lzaW9uLgovLwovLyBSZXR1cm5zOgovLyAgIC0gKnUyNTYuVWludDogRmVlIGdyb3d0aCBpbnNpZGUgdGhlIHRpY2sgcmFuZ2UgZm9yIHRva2VuIDAuCi8vICAgLSAqdTI1Ni5VaW50OiBGZWUgZ3Jvd3RoIGluc2lkZSB0aGUgdGljayByYW5nZSBmb3IgdG9rZW4gMS4KLy8KLy8gV29ya2Zsb3c6Ci8vICAxLiBSZXRyaWV2ZSB0aGUgdGljayBpbmZvcm1hdGlvbiAoYGxvd2VyYCBhbmQgYHVwcGVyYCkgZm9yIHRoZSBsb3dlciBhbmQgdXBwZXIgdGljayBib3VuZGFyaWVzCi8vICAgICB1c2luZyBgcC5nZXRUaWNrYC4KLy8gIDIuIENhbGN1bGF0ZSB0aGUgZmVlIGdyb3d0aCBiZWxvdyB0aGUgbG93ZXIgdGljayB1c2luZyBgZ2V0RmVlR3Jvd3RoQmVsb3dYMTI4YC4KLy8gIDMuIENhbGN1bGF0ZSB0aGUgZmVlIGdyb3d0aCBhYm92ZSB0aGUgdXBwZXIgdGljayB1c2luZyBgZ2V0RmVlR3Jvd3RoQWJvdmVYMTI4YC4KLy8gIDQuIFN1YnRyYWN0IHRoZSBmZWUgZ3Jvd3RoIGJlbG93IGFuZCBhYm92ZSB0aGUgcmFuZ2UgZnJvbSB0aGUgZ2xvYmFsIGZlZSBncm93dGggdmFsdWVzOgovLyAgICAgZmVlR3Jvd3RoSW5zaWRlID0gZmVlR3Jvd3RoR2xvYmFsIC0gZmVlR3Jvd3RoQmVsb3cgLSBmZWVHcm93dGhBYm92ZQovLyAgNS4gUmV0dXJuIHRoZSBjb21wdXRlZCBmZWUgZ3Jvd3RoIHZhbHVlcyBmb3IgdG9rZW4gMCBhbmQgdG9rZW4gMSB3aXRoaW4gdGhlIHJhbmdlLgovLwovLyBCZWhhdmlvcjoKLy8gICAtIFRoZSBmZWUgZ3Jvd3RoIGlzIGlzb2xhdGVkIHdpdGhpbiB0aGUgcmFuZ2UgYFt0aWNrTG93ZXIsIHRpY2tVcHBlcl1gLgovLyAgIC0gVGhlIGZ1bmN0aW9uIGVuc3VyZXMgdGhlIGNhbGN1bGF0aW9ucyBhY2N1cmF0ZWx5IGNvbnNpZGVyIHRoZSB0aWNrIGJvdW5kYXJpZXMgYW5kIHRoZSBjdXJyZW50IHRpY2sgcG9zaXRpb24uCi8vCi8vIEV4YW1wbGU6Ci8vCi8vIGBgYGdubwovLwovLwlmZWVHcm93dGgwLCBmZWVHcm93dGgxIDo9IHBvb2wuZ2V0RmVlR3Jvd3RoSW5zaWRlKAovLwkgICAgMTAwLCAyMDAsIDE1MCwgZ2xvYmFsRmVlR3Jvd3RoMCwgZ2xvYmFsRmVlR3Jvd3RoMSwKLy8JKQovLwlwcmludGxuKCJGZWUgR3Jvd3RoIEluc2lkZSAoVG9rZW4gMCk6IiwgZmVlR3Jvd3RoMCkKLy8JcHJpbnRsbigiRmVlIEdyb3d0aCBJbnNpZGUgKFRva2VuIDEpOiIsIGZlZUdyb3d0aDEpCi8vCi8vIGBgYApmdW5jIGdldEZlZUdyb3d0aEluc2lkZSgKCXAgKnBsLlBvb2wsCgl0aWNrTG93ZXIgaW50MzIsCgl0aWNrVXBwZXIgaW50MzIsCgl0aWNrQ3VycmVudCBpbnQzMiwKCWZlZUdyb3d0aEdsb2JhbDBYMTI4ICp1MjU2LlVpbnQsCglmZWVHcm93dGhHbG9iYWwxWDEyOCAqdTI1Ni5VaW50LAopICgqdTI1Ni5VaW50LCAqdTI1Ni5VaW50KSB7Cglsb3dlciA6PSBnZXRUaWNrKHAsIHRpY2tMb3dlcikKCXVwcGVyIDo9IGdldFRpY2socCwgdGlja1VwcGVyKQoKCWZlZUdyb3d0aEJlbG93MFgxMjgsIGZlZUdyb3d0aEJlbG93MVgxMjggOj0gZ2V0RmVlR3Jvd3RoQmVsb3dYMTI4KHRpY2tMb3dlciwgdGlja0N1cnJlbnQsIGZlZUdyb3d0aEdsb2JhbDBYMTI4LCBmZWVHcm93dGhHbG9iYWwxWDEyOCwgbG93ZXIpCglmZWVHcm93dGhBYm92ZTBYMTI4LCBmZWVHcm93dGhBYm92ZTFYMTI4IDo9IGdldEZlZUdyb3d0aEFib3ZlWDEyOCh0aWNrVXBwZXIsIHRpY2tDdXJyZW50LCBmZWVHcm93dGhHbG9iYWwwWDEyOCwgZmVlR3Jvd3RoR2xvYmFsMVgxMjgsIHVwcGVyKQoKCWZlZUdyb3d0aEluc2lkZTBYMTI4IDo9IHUyNTYuWmVybygpLlN1Yih1MjU2Llplcm8oKS5TdWIoZmVlR3Jvd3RoR2xvYmFsMFgxMjgsIGZlZUdyb3d0aEJlbG93MFgxMjgpLCBmZWVHcm93dGhBYm92ZTBYMTI4KQoJZmVlR3Jvd3RoSW5zaWRlMVgxMjggOj0gdTI1Ni5aZXJvKCkuU3ViKHUyNTYuWmVybygpLlN1YihmZWVHcm93dGhHbG9iYWwxWDEyOCwgZmVlR3Jvd3RoQmVsb3cxWDEyOCksIGZlZUdyb3d0aEFib3ZlMVgxMjgpCgoJcmV0dXJuIGZlZUdyb3d0aEluc2lkZTBYMTI4LCBmZWVHcm93dGhJbnNpZGUxWDEyOAp9CgovLyB0aWNrVXBkYXRlIHVwZGF0ZXMgdGhlIHN0YXRlIG9mIGEgc3BlY2lmaWMgdGljay4KLy8KLy8gVGhpcyBmdW5jdGlvbiBhcHBsaWVzIGEgZ2l2ZW4gbGlxdWlkaXR5IGNoYW5nZSAobGlxdWlkaXR5RGVsdGEpIHRvIHRoZSBzcGVjaWZpZWQgdGljaywgdXBkYXRlcwovLyB0aGUgZmVlIGdyb3d0aCB2YWx1ZXMgaWYgbmVjZXNzYXJ5LCBhbmQgYWRqdXN0cyB0aGUgbmV0IGxpcXVpZGl0eSBiYXNlZCBvbiB3aGV0aGVyIHRoZSB0aWNrCi8vIGlzIGFuIHVwcGVyIG9yIGxvd2VyIGJvdW5kYXJ5LiBJdCBhbHNvIHZlcmlmaWVzIHRoYXQgdGhlIHRvdGFsIGxpcXVpZGl0eSBkb2VzIG5vdCBleGNlZWQgdGhlCi8vIG1heGltdW0gYWxsb3dlZCB2YWx1ZSBhbmQgZW5zdXJlcyB0aGUgbmV0IGxpcXVpZGl0eSBzdGF5cyB3aXRoaW4gdGhlIHZhbGlkIGludDEyOCByYW5nZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHRpY2s6ICAgICAgICAgIGludDMyLCB0aGUgaW5kZXggb2YgdGhlIHRpY2sgdG8gdXBkYXRlLgovLyAgIC0gdGlja0N1cnJlbnQ6ICAgaW50MzIsIHRoZSBjdXJyZW50IGFjdGl2ZSB0aWNrIGluZGV4LgovLyAgIC0gbGlxdWlkaXR5RGVsdGE6ICppMjU2LkludCwgdGhlIGFtb3VudCBvZiBsaXF1aWRpdHkgdG8gYWRkIG9yIHJlbW92ZS4KLy8gICAtIGZlZUdyb3d0aEdsb2JhbDBYMTI4OiAqdTI1Ni5VaW50LCB0aGUgZ2xvYmFsIGZlZSBncm93dGggdmFsdWUgZm9yIHRva2VuIDAuCi8vICAgLSBmZWVHcm93dGhHbG9iYWwxWDEyODogKnUyNTYuVWludCwgdGhlIGdsb2JhbCBmZWUgZ3Jvd3RoIHZhbHVlIGZvciB0b2tlbiAxLgovLyAgIC0gc2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4OiAqdTI1Ni5VaW50LCB0aGUgY3VycmVudCBvcmFjbGUgYWNjdW11bGF0b3IgdXNlZCB0bwovLyAgICAgc2VlZCB0aGUgb3V0c2lkZSBhY2N1bXVsYXRvciBvZiBhIG5ld2x5IGluaXRpYWxpemVkIGFjdGl2ZSB0aWNrICh0aWNrIDw9IHRpY2tDdXJyZW50KS4KLy8gICAtIHRpY2tDdW11bGF0aXZlOiBpbnQ2NCwgdGhlIGN1cnJlbnQgb3JhY2xlIHRpY2sgYWNjdW11bGF0b3IgdXNlZCBmb3IgdGhlIHNhbWUgc2VlZGluZy4KLy8gICAtIGJsb2NrVGltZXN0YW1wOiBpbnQ2NCwgdGhlIGN1cnJlbnQgYmxvY2sgdGltZXN0YW1wIHVzZWQgZm9yIHRoZSBzYW1lIHNlZWRpbmcuCi8vICAgLSB1cHBlcjogICAgICAgICBib29sLCBpbmRpY2F0ZXMgaWYgdGhpcyBpcyB0aGUgdXBwZXIgYm91bmRhcnkgKHRydWUgZm9yIHVwcGVyLCBmYWxzZSBmb3IgbG93ZXIpLgovLyAgIC0gbWF4TGlxdWlkaXR5OiAgKnUyNTYuVWludCwgdGhlIG1heGltdW0gYWxsb3dlZCBsaXF1aWRpdHkuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBmbGlwcGVkOiBib29sLCBpbmRpY2F0ZXMgaWYgdGhlIHRpY2sncyBpbml0aWFsaXphdGlvbiBzdGF0ZSBoYXMgY2hhbmdlZC4KLy8gICAgIChlLmcuLCBsaXF1aWRpdHkgdHJhbnNpdGlvbmluZyBmcm9tIHplcm8gdG8gbm9uLXplcm8sIG9yIHZpY2UgdmVyc2EpCi8vCi8vIFdvcmtmbG93OgovLyAxLiBOaWwgaW5wdXQgdmFsdWVzIGFyZSByZXBsYWNlZCB3aXRoIHplcm8uCi8vIDIuIFRoZSBmdW5jdGlvbiByZXRyaWV2ZXMgdGhlIHRpY2sgaW5mb3JtYXRpb24gZm9yIHRoZSBzcGVjaWZpZWQgdGljayBpbmRleC4KLy8gMy4gQXBwbGllcyB0aGUgbGlxdWlkaXR5RGVsdGEgdG8gY29tcHV0ZSB0aGUgbmV3IHRvdGFsIGxpcXVpZGl0eSAobGlxdWlkaXR5R3Jvc3MpLgovLyAgIC0gSWYgdGhlIHRvdGFsIGxpcXVpZGl0eSBleGNlZWRzIHRoZSBtYXhpbXVtIGFsbG93ZWQgdmFsdWUsIHRoZSBmdW5jdGlvbiBwYW5pY3MuCi8vICAgICA0LiBDaGVja3Mgd2hldGhlciB0aGUgdGljaydzIGluaXRpYWxpemVkIHN0YXRlIGhhcyBjaGFuZ2VkIGFuZCBzZXRzIHRoZSBgZmxpcHBlZGAgZmxhZy4KLy8gICAgIDUuIElmIHRoZSB0aWNrIHdhcyBwcmV2aW91c2x5IHVuaW5pdGlhbGl6ZWQgYW5kIGl0cyBpbmRleCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGN1cnJlbnQgdGljaywKLy8gICAgIHRoZSBmZWUgZ3Jvd3RoIHZhbHVlcyBhcmUgaW5pdGlhbGl6ZWQgdG8gdGhlIGN1cnJlbnQgZ2xvYmFsIHZhbHVlcy4KLy8gICAgIDYuIFVwZGF0ZXMgdGhlIHRpY2sncyBuZXQgbGlxdWlkaXR5OgovLyAgIC0gRm9yIGFuIHVwcGVyIGJvdW5kYXJ5LCBpdCBzdWJ0cmFjdHMgbGlxdWlkaXR5RGVsdGEuCi8vICAgLSBGb3IgYSBsb3dlciBib3VuZGFyeSwgaXQgYWRkcyBsaXF1aWRpdHlEZWx0YS4KLy8gICAtIEVuc3VyZXMgdGhlIG5ldCBsaXF1aWRpdHkgcmVtYWlucyB3aXRoaW4gdGhlIGludDEyOCByYW5nZSB1c2luZyBgY2hlY2tPdmVyRmxvd0ludDEyOGAuCi8vICAgICA3LiBVcGRhdGVzIHRoZSB0aWNrJ3Mgc3RhdGUgd2l0aCB0aGUgbmV3IHZhbHVlcy4KLy8gICAgIDguIFJldHVybnMgd2hldGhlciB0aGUgdGljaydzIGluaXRpYWxpemVkIHN0YXRlIGhhcyBmbGlwcGVkLgovLwovLyBQYW5pYyBDb25kaXRpb25zOgovLyAtIFRoZSB0b3RhbCBsaXF1aWRpdHkgKGxpcXVpZGl0eUdyb3NzKSBleGNlZWRzIHRoZSBtYXhpbXVtIGFsbG93ZWQgbGlxdWlkaXR5IChtYXhMaXF1aWRpdHkpLgovLyAtIFRoZSBuZXQgbGlxdWlkaXR5IChsaXF1aWRpdHlOZXQpIGV4Y2VlZHMgdGhlIGludDEyOCByYW5nZS4KLy8KLy8gRXhhbXBsZToKLy8KLy8gYGBgZ25vCi8vCi8vCWZsaXBwZWQgOj0gcG9vbC50aWNrVXBkYXRlKDEwLCA1LCBsaXF1aWRpdHlEZWx0YSwgZmVlR3Jvd3RoMCwgZmVlR3Jvd3RoMSwgc2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4LCB0aWNrQ3VtdWxhdGl2ZSwgYmxvY2tUaW1lc3RhbXAsIHRydWUsIG1heExpcXVpZGl0eSkKLy8JcHJpbnRsbigiVGljayBmbGlwcGVkOiIsIGZsaXBwZWQpCi8vCi8vIGBgYApmdW5jIHRpY2tVcGRhdGUoCglwICpwbC5Qb29sLAoJdGljayBpbnQzMiwKCXRpY2tDdXJyZW50IGludDMyLAoJbGlxdWlkaXR5RGVsdGEgKmkyNTYuSW50LAoJZmVlR3Jvd3RoR2xvYmFsMFgxMjggKnUyNTYuVWludCwKCWZlZUdyb3d0aEdsb2JhbDFYMTI4ICp1MjU2LlVpbnQsCglzZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjggKnUyNTYuVWludCwKCXRpY2tDdW11bGF0aXZlIGludDY0LAoJYmxvY2tUaW1lc3RhbXAgaW50NjQsCgl1cHBlciBib29sLAoJbWF4TGlxdWlkaXR5ICp1MjU2LlVpbnQsCikgKGZsaXBwZWQgYm9vbCkgewoJdGlja0luZm8gOj0gZ2V0VGljayhwLCB0aWNrKQoKCWxpcXVpZGl0eUdyb3NzQmVmb3JlIDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHRpY2tJbmZvLkxpcXVpZGl0eUdyb3NzKCkpCglsaXF1aWRpdHlHcm9zc0FmdGVyIDo9IGduc21hdGguTGlxdWlkaXR5TWF0aEFkZERlbHRhKGxpcXVpZGl0eUdyb3NzQmVmb3JlLCBsaXF1aWRpdHlEZWx0YSkKCglpZiAhbGlxdWlkaXR5R3Jvc3NBZnRlci5MdGUobWF4TGlxdWlkaXR5KSB7CgkJcGFuaWMobmV3RXJyb3JXaXRoRGV0YWlsKAoJCQllcnJMaXF1aWRpdHlDYWxjdWxhdGlvbiwKCQkJdWZtdC5TcHJpbnRmKCJsaXF1aWRpdHlHcm9zc0FmdGVyKCVzKSBvdmVyZmxvd3MgbWF4TGlxdWlkaXR5KCVzKSIsIGxpcXVpZGl0eUdyb3NzQWZ0ZXIuVG9TdHJpbmcoKSwgbWF4TGlxdWlkaXR5LlRvU3RyaW5nKCkpLAoJCSkpCgl9CgoJZmxpcHBlZCA9IGxpcXVpZGl0eUdyb3NzQWZ0ZXIuSXNaZXJvKCkgIT0gbGlxdWlkaXR5R3Jvc3NCZWZvcmUuSXNaZXJvKCkKCglpZiBsaXF1aWRpdHlHcm9zc0JlZm9yZS5Jc1plcm8oKSB7CgkJaWYgdGljayA8PSB0aWNrQ3VycmVudCB7CgkJCXRpY2tJbmZvLlNldEZlZUdyb3d0aE91dHNpZGUwWDEyOChmZWVHcm93dGhHbG9iYWwwWDEyOC5Ub1N0cmluZygpKQoJCQl0aWNrSW5mby5TZXRGZWVHcm93dGhPdXRzaWRlMVgxMjgoZmVlR3Jvd3RoR2xvYmFsMVgxMjguVG9TdHJpbmcoKSkKCQkJdGlja0luZm8uU2V0U2Vjb25kc1BlckxpcXVpZGl0eU91dHNpZGVYMTI4KHNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOC5Ub1N0cmluZygpKQoJCQl0aWNrSW5mby5TZXRUaWNrQ3VtdWxhdGl2ZU91dHNpZGUodGlja0N1bXVsYXRpdmUpCgkJCXRpY2tJbmZvLlNldFNlY29uZHNPdXRzaWRlKHVpbnQzMihibG9ja1RpbWVzdGFtcCkpCgkJfQoJCXRpY2tJbmZvLlNldEluaXRpYWxpemVkKHRydWUpCgl9CgoJdGlja0luZm8uU2V0TGlxdWlkaXR5R3Jvc3MobGlxdWlkaXR5R3Jvc3NBZnRlci5Ub1N0cmluZygpKQoKCWxpcXVpZGl0eU5ldCA6PSBpMjU2Lk11c3RGcm9tRGVjaW1hbCh0aWNrSW5mby5MaXF1aWRpdHlOZXQoKSkKCWlmIHVwcGVyIHsKCQluZXdMaXF1aWRpdHlOZXQgOj0gaTI1Ni5aZXJvKCkuU3ViKGxpcXVpZGl0eU5ldCwgbGlxdWlkaXR5RGVsdGEpCgkJY2hlY2tPdmVyRmxvd0ludDEyOChuZXdMaXF1aWRpdHlOZXQpCgkJdGlja0luZm8uU2V0TGlxdWlkaXR5TmV0KG5ld0xpcXVpZGl0eU5ldC5Ub1N0cmluZygpKQoJfSBlbHNlIHsKCQluZXdMaXF1aWRpdHlOZXQgOj0gaTI1Ni5aZXJvKCkuQWRkKGxpcXVpZGl0eU5ldCwgbGlxdWlkaXR5RGVsdGEpCgkJY2hlY2tPdmVyRmxvd0ludDEyOChuZXdMaXF1aWRpdHlOZXQpCgkJdGlja0luZm8uU2V0TGlxdWlkaXR5TmV0KG5ld0xpcXVpZGl0eU5ldC5Ub1N0cmluZygpKQoJfQoKCXNldFRpY2socCwgdGljaywgdGlja0luZm8pCgoJcmV0dXJuIGZsaXBwZWQKfQoKLy8gdGlja0Nyb3NzIHVwZGF0ZXMgYSB0aWNrJ3Mgc3RhdGUgd2hlbiBpdCBpcyBjcm9zc2VkIGFuZCByZXR1cm5zIHRoZSBsaXF1aWRpdHkgbmV0LgovLyBVcGRhdGVzIGZlZSBncm93dGggYW5kIG9yYWNsZSBhY2N1bXVsYXRvciB2YWx1ZXMgZm9yIHRoZSB0aWNrLgpmdW5jIHRpY2tDcm9zcygKCXAgKnBsLlBvb2wsCgl0aWNrIGludDMyLAoJZmVlR3Jvd3RoR2xvYmFsMFgxMjggKnUyNTYuVWludCwKCWZlZUdyb3d0aEdsb2JhbDFYMTI4ICp1MjU2LlVpbnQsCglzZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjggKnUyNTYuVWludCwKCXRpY2tDdW11bGF0aXZlIGludDY0LAoJYmxvY2tUaW1lc3RhbXAgaW50NjQsCikgKmkyNTYuSW50IHsKCXRoaXNUaWNrIDo9IGdldFRpY2socCwgdGljaykKCglmZWVPdXRzaWRlMCA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbCh0aGlzVGljay5GZWVHcm93dGhPdXRzaWRlMFgxMjgoKSkKCWZlZU91dHNpZGUxIDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHRoaXNUaWNrLkZlZUdyb3d0aE91dHNpZGUxWDEyOCgpKQoJdGhpc1RpY2suU2V0RmVlR3Jvd3RoT3V0c2lkZTBYMTI4KHUyNTYuWmVybygpLlN1YihmZWVHcm93dGhHbG9iYWwwWDEyOCwgZmVlT3V0c2lkZTApLlRvU3RyaW5nKCkpCgl0aGlzVGljay5TZXRGZWVHcm93dGhPdXRzaWRlMVgxMjgodTI1Ni5aZXJvKCkuU3ViKGZlZUdyb3d0aEdsb2JhbDFYMTI4LCBmZWVPdXRzaWRlMSkuVG9TdHJpbmcoKSkKCgl0aWNrU2Vjb25kc1BlckxpcXVpZGl0eSA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbCh0aGlzVGljay5TZWNvbmRzUGVyTGlxdWlkaXR5T3V0c2lkZVgxMjgoKSkKCXRoaXNUaWNrLlNldFNlY29uZHNQZXJMaXF1aWRpdHlPdXRzaWRlWDEyOCh1MjU2Llplcm8oKS5TdWIoc2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4LCB0aWNrU2Vjb25kc1BlckxpcXVpZGl0eSkuVG9TdHJpbmcoKSkKCXRoaXNUaWNrLlNldFRpY2tDdW11bGF0aXZlT3V0c2lkZSh0aWNrQ3VtdWxhdGl2ZSAtIHRoaXNUaWNrLlRpY2tDdW11bGF0aXZlT3V0c2lkZSgpKQoJdGhpc1RpY2suU2V0U2Vjb25kc091dHNpZGUodWludDMyKGJsb2NrVGltZXN0YW1wKSAtIHRoaXNUaWNrLlNlY29uZHNPdXRzaWRlKCkpCgoJc2V0VGljayhwLCB0aWNrLCB0aGlzVGljaykKCglyZXR1cm4gaTI1Ni5NdXN0RnJvbURlY2ltYWwodGhpc1RpY2suTGlxdWlkaXR5TmV0KCkpCn0KCi8vIHNldFRpY2sgdXBkYXRlcyB0aGUgdGljayBkYXRhIGZvciB0aGUgc3BlY2lmaWVkIHRpY2sgaW5kZXggaW4gdGhlIHBvb2wuCmZ1bmMgc2V0VGljayhwICpwbC5Qb29sLCB0aWNrIGludDMyLCBuZXdUaWNrSW5mbyBwbC5UaWNrSW5mbykgewoJcC5TZXRUaWNrKHRpY2ssIG5ld1RpY2tJbmZvKQp9CgovLyBkZWxldGVUaWNrIGRlbGV0ZXMgdGhlIHRpY2sgZGF0YSBmb3IgdGhlIHNwZWNpZmllZCB0aWNrIGluZGV4IGluIHRoZSBwb29sLgpmdW5jIGRlbGV0ZVRpY2socCAqcGwuUG9vbCwgdGljayBpbnQzMikgewoJcC5EZWxldGVUaWNrKHRpY2spCn0KCi8vIGdldFRpY2sgcmV0cmlldmVzIHRoZSBUaWNrSW5mbyBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCB0aWNrIGluZGV4IGZyb20gdGhlIHBvb2wuCi8vIElmIHRoZSBUaWNrSW5mbyBjb250YWlucyBhbnkgbmlsIGZpZWxkcywgdGhleSBhcmUgcmVwbGFjZWQgd2l0aCB6ZXJvIHZhbHVlcyB1c2luZyB2YWx1ZU9yWmVyby4KLy8KLy8gUGFyYW1ldGVyczoKLy8gLSB0aWNrOiBUaGUgdGljayBpbmRleCAoaW50MzIpIGZvciB3aGljaCB0aGUgVGlja0luZm8gaXMgdG8gYmUgcmV0cmlldmVkLgovLwovLyBCZWhhdmlvcjoKLy8gLSBSZXRyaWV2ZXMgdGhlIFRpY2tJbmZvIGZvciB0aGUgZ2l2ZW4gdGljayBmcm9tIHRoZSBwb29sJ3MgdGljayBtYXAuCi8vIC0gRW5zdXJlcyB0aGF0IGFsbCBmaWVsZHMgb2YgVGlja0luZm8gYXJlIG5vbi1uaWwgYnkgY2FsbGluZyB2YWx1ZU9yWmVybywgd2hpY2ggcmVwbGFjZXMgbmlsIHZhbHVlcyB3aXRoIHplcm8uCi8vIC0gUmV0dXJucyB0aGUgdXBkYXRlZCBUaWNrSW5mby4KLy8KLy8gUmV0dXJuczoKLy8gLSBUaWNrSW5mbzogVGhlIHRpY2sgZGF0YSB3aXRoIGFsbCBmaWVsZHMgZ3VhcmFudGVlZCB0byBoYXZlIHZhbGlkIHZhbHVlcyAobmlsIGZpZWxkcyBhcmUgc2V0IHRvIHplcm8pLgovLwovLyBVc2UgQ2FzZToKLy8gVGhpcyBmdW5jdGlvbiBlbnN1cmVzIHRoZSByZXRyaWV2ZWQgdGljayBkYXRhIGlzIGFsd2F5cyB2YWxpZCBhbmQgc2FmZSBmb3IgZnVydGhlciBvcGVyYXRpb25zLAovLyBzdWNoIGFzIGNhbGN1bGF0aW9ucyBvciB1cGRhdGVzLCBieSBzYW5pdGl6aW5nIG5pbCBmaWVsZHMgaW4gdGhlIFRpY2tJbmZvIHN0cnVjdHVyZS4KZnVuYyBnZXRUaWNrKHAgKnBsLlBvb2wsIHRpY2sgaW50MzIpIHBsLlRpY2tJbmZvIHsKCXRpY2tJbmZvLCBlcnIgOj0gcC5HZXRUaWNrKHRpY2spCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gcGwuTmV3VGlja0luZm8oKQoJfQoKCXJldHVybiB0aWNrSW5mbwp9CgovLyBtdXN0R2V0VGljayByZXRyaWV2ZXMgdGhlIFRpY2tJbmZvIGZvciBhIHNwZWNpZmljIHRpY2ssIHBhbmlja2luZyBpZiB0aGUgdGljayBkb2VzIG5vdCBleGlzdC4KLy8KLy8gVGhpcyBmdW5jdGlvbiBlbnN1cmVzIHRoYXQgdGhlIHJlcXVlc3RlZCB0aWNrIGRhdGEgZXhpc3RzIGluIHRoZSBwb29sJ3MgdGljayBtYXBwaW5nLgovLyBJZiB0aGUgdGljayBkb2VzIG5vdCBleGlzdCwgaXQgcGFuaWNzIHdpdGggYW4gYXBwcm9wcmlhdGUgZXJyb3IgbWVzc2FnZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHRpY2s6IGludDMyLCB0aGUgaW5kZXggb2YgdGhlIHRpY2sgdG8gcmV0cmlldmUuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBUaWNrSW5mbzogVGhlIGluZm9ybWF0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIHRpY2suCi8vCi8vIEJlaGF2aW9yOgovLyAgIC0gQ2hlY2tzIGlmIHRoZSB0aWNrIGV4aXN0cyBpbiB0aGUgcG9vbCdzIHRpY2sgbWFwcGluZyAoYHAudGlja3NgKS4KLy8gICAtIElmIHRoZSB0aWNrIGV4aXN0cywgaXQgcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyBgVGlja0luZm9gLgovLyAgIC0gSWYgdGhlIHRpY2sgZG9lcyBub3QgZXhpc3QsIHRoZSBmdW5jdGlvbiBwYW5pY3Mgd2l0aCBhIGRlc2NyaXB0aXZlIGVycm9yLgovLwovLyBQYW5pYyBDb25kaXRpb25zOgovLyAgIC0gVGhlIHNwZWNpZmllZCB0aWNrIGRvZXMgbm90IGV4aXN0IGluIHRoZSBwb29sJ3MgbWFwcGluZy4KLy8KLy8gRXhhbXBsZToKLy8KLy8gYGBgZ25vCi8vCi8vCXRpY2tJbmZvIDo9IHBvb2wubXVzdEdldFRpY2soMTApCi8vCXVmbXQuUHJpbnRsbigiVGljayBJbmZvOiIsIHRpY2tJbmZvKQovLwovLyBgYGAKZnVuYyBtdXN0R2V0VGljayhwICpwbC5Qb29sLCB0aWNrIGludDMyKSAqcGwuVGlja0luZm8gewoJdGlja0luZm8sIGVyciA6PSBwLkdldFRpY2sodGljaykKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglyZXR1cm4gJnRpY2tJbmZvCn0KCi8vIGNhbGN1bGF0ZU1heExpcXVpZGl0eVBlclRpY2sgY2FsY3VsYXRlcyB0aGUgbWF4aW11bSBsaXF1aWRpdHkKLy8gcGVyIHRpY2sgZm9yIGEgZ2l2ZW4gdGljayBzcGFjaW5nLgpmdW5jIGNhbGN1bGF0ZU1heExpcXVpZGl0eVBlclRpY2sodGlja1NwYWNpbmcgaW50MzIpICp1MjU2LlVpbnQgewoJc3dpdGNoIHRpY2tTcGFjaW5nIHsKCWNhc2UgMToKCQlyZXR1cm4gbWF4TGlxdWlkaXR5UGVyVGlja1NwYWNpbmcxRnJvbURlYygpCgljYXNlIDEwOgoJCXJldHVybiBtYXhMaXF1aWRpdHlQZXJUaWNrU3BhY2luZzEwRnJvbURlYygpCgljYXNlIDYwOgoJCXJldHVybiBtYXhMaXF1aWRpdHlQZXJUaWNrU3BhY2luZzYwRnJvbURlYygpCgljYXNlIDIwMDoKCQlyZXR1cm4gbWF4TGlxdWlkaXR5UGVyVGlja1NwYWNpbmcyMDBGcm9tRGVjKCkKCWRlZmF1bHQ6CgkJbWluVGljayA6PSAoTUlOX1RJQ0sgLyB0aWNrU3BhY2luZykgKiB0aWNrU3BhY2luZwoJCW1heFRpY2sgOj0gKE1BWF9USUNLIC8gdGlja1NwYWNpbmcpICogdGlja1NwYWNpbmcKCQludW1UaWNrcyA6PSB1aW50NjQoKG1heFRpY2stbWluVGljaykvdGlja1NwYWNpbmcpICsgMQoKCQlyZXR1cm4gdTI1Ni5aZXJvKCkuRGl2KGNvbnN0cy5NYXhVaW50MTI4KCksIHUyNTYuTmV3VWludChudW1UaWNrcykpCgl9Cn0KCi8vIGdldEZlZUdyb3d0aEJlbG93WDEyOCBjYWxjdWxhdGVzIHRoZSBmZWUgZ3Jvd3RoIGJlbG93IGEgc3BlY2lmaWVkIHRpY2suCi8vCi8vIFRoaXMgZnVuY3Rpb24gY29tcHV0ZXMgdGhlIGZlZSBncm93dGggZm9yIHRva2VuIDAgYW5kIHRva2VuIDEgYmVsb3cgYSBnaXZlbiB0aWNrIChgdGlja0xvd2VyYCkKLy8gcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgdGljayAoYHRpY2tDdXJyZW50YCkuIFRoZSBmZWUgZ3Jvd3RoIHZhbHVlcyBhcmUgYWRqdXN0ZWQgYmFzZWQgb24gd2hldGhlcgovLyB0aGUgYHRpY2tDdXJyZW50YCBpcyBhYm92ZSBvciBiZWxvdyB0aGUgYHRpY2tMb3dlcmAuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0aWNrTG93ZXI6IGludDMyLCB0aGUgbG93ZXIgdGljayBib3VuZGFyeSBmb3IgZmVlIGNhbGN1bGF0aW9uLgovLyAgIC0gdGlja0N1cnJlbnQ6IGludDMyLCB0aGUgY3VycmVudCB0aWNrIGluZGV4LgovLyAgIC0gZmVlR3Jvd3RoR2xvYmFsMFgxMjg6ICp1MjU2LlVpbnQsIHRoZSBnbG9iYWwgZmVlIGdyb3d0aCBmb3IgdG9rZW4gMCBpbiBYMTI4IHByZWNpc2lvbi4KLy8gICAtIGZlZUdyb3d0aEdsb2JhbDFYMTI4OiAqdTI1Ni5VaW50LCB0aGUgZ2xvYmFsIGZlZSBncm93dGggZm9yIHRva2VuIDEgaW4gWDEyOCBwcmVjaXNpb24uCi8vICAgLSBsb3dlclRpY2s6IFRpY2tJbmZvLCB0aGUgZmVlIGdyb3d0aCBhbmQgbGlxdWlkaXR5IGRldGFpbHMgZm9yIHRoZSBsb3dlciB0aWNrLgovLwovLyBSZXR1cm5zOgovLyAgIC0gKnUyNTYuVWludDogRmVlIGdyb3d0aCBiZWxvdyBgdGlja0xvd2VyYCBmb3IgdG9rZW4gMC4KLy8gICAtICp1MjU2LlVpbnQ6IEZlZSBncm93dGggYmVsb3cgYHRpY2tMb3dlcmAgZm9yIHRva2VuIDEuCi8vCi8vIFdvcmtmbG93OgovLyAgMS4gSWYgYHRpY2tDdXJyZW50YCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYHRpY2tMb3dlcmA6Ci8vICAgICAtIFJldHVybiB0aGUgYGZlZUdyb3d0aE91dHNpZGUwWDEyOGAgYW5kIGBmZWVHcm93dGhPdXRzaWRlMVgxMjhgIHZhbHVlcyBvZiB0aGUgYGxvd2VyVGlja2AuCi8vICAyLiBJZiBgdGlja0N1cnJlbnRgIGlzIGJlbG93IGB0aWNrTG93ZXJgOgovLyAgICAgLSBDb21wdXRlIHRoZSBmZWUgZ3Jvd3RoIGJlbG93IHRoZSBsb3dlciB0aWNrIGJ5IHN1YnRyYWN0aW5nIGBmZWVHcm93dGhPdXRzaWRlYCB2YWx1ZXMKLy8gICAgIGZyb20gdGhlIGdsb2JhbCBmZWUgZ3Jvd3RoIHZhbHVlcyAoYGZlZUdyb3d0aEdsb2JhbDBYMTI4YCBhbmQgYGZlZUdyb3d0aEdsb2JhbDFYMTI4YCkuCi8vICAzLiBSZXR1cm4gdGhlIGNhbGN1bGF0ZWQgZmVlIGdyb3d0aCB2YWx1ZXMgZm9yIGJvdGggdG9rZW5zLgovLwovLyBCZWhhdmlvcjoKLy8gICAtIElmIGB0aWNrQ3VycmVudCA+PSB0aWNrTG93ZXJgLCB0aGUgZmVlIGdyb3d0aCBvdXRzaWRlIHRoZSBsb3dlciB0aWNrIGlzIHJldHVybmVkIGFzLWlzLgovLyAgIC0gSWYgYHRpY2tDdXJyZW50IDwgdGlja0xvd2VyYCwgdGhlIGZlZSBncm93dGggaXMgY2FsY3VsYXRlZCBhczoKLy8gICAgIGZlZUdyb3d0aEJlbG93ID0gZmVlR3Jvd3RoR2xvYmFsIC0gZmVlR3Jvd3RoT3V0c2lkZQovLwovLyBFeGFtcGxlOgovLwovLyBgYGBnbm8KLy8KLy8JZmVlR3Jvd3RoMCwgZmVlR3Jvd3RoMSA6PSBnZXRGZWVHcm93dGhCZWxvd1gxMjgoCi8vCSAgICAxMDAsIDE1MCwgZ2xvYmFsRmVlR3Jvd3RoMCwgZ2xvYmFsRmVlR3Jvd3RoMSwgbG93ZXJUaWNrSW5mbywKLy8JKQovLwlwcmludGxuKCJGZWUgR3Jvd3RoIEJlbG93OiIsIGZlZUdyb3d0aDAsIGZlZUdyb3d0aDEpCmZ1bmMgZ2V0RmVlR3Jvd3RoQmVsb3dYMTI4KAoJdGlja0xvd2VyLCB0aWNrQ3VycmVudCBpbnQzMiwKCWZlZUdyb3d0aEdsb2JhbDBYMTI4LCBmZWVHcm93dGhHbG9iYWwxWDEyOCAqdTI1Ni5VaW50LAoJbG93ZXJUaWNrIHBsLlRpY2tJbmZvLAopICgqdTI1Ni5VaW50LCAqdTI1Ni5VaW50KSB7CglmZWVPdXRzaWRlMCA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChsb3dlclRpY2suRmVlR3Jvd3RoT3V0c2lkZTBYMTI4KCkpCglmZWVPdXRzaWRlMSA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChsb3dlclRpY2suRmVlR3Jvd3RoT3V0c2lkZTFYMTI4KCkpCgoJaWYgdGlja0N1cnJlbnQgPj0gdGlja0xvd2VyIHsKCQlyZXR1cm4gZmVlT3V0c2lkZTAsIGZlZU91dHNpZGUxCgl9CgoJZmVlR3Jvd3RoQmVsb3cwWDEyOCA6PSB1MjU2Llplcm8oKS5TdWIoZmVlR3Jvd3RoR2xvYmFsMFgxMjgsIGZlZU91dHNpZGUwKQoJZmVlR3Jvd3RoQmVsb3cxWDEyOCA6PSB1MjU2Llplcm8oKS5TdWIoZmVlR3Jvd3RoR2xvYmFsMVgxMjgsIGZlZU91dHNpZGUxKQoKCXJldHVybiBmZWVHcm93dGhCZWxvdzBYMTI4LCBmZWVHcm93dGhCZWxvdzFYMTI4Cn0KCi8vIGdldEZlZUdyb3d0aEFib3ZlWDEyOCBjYWxjdWxhdGVzIHRoZSBmZWUgZ3Jvd3RoIGFib3ZlIGEgc3BlY2lmaWVkIHRpY2suCi8vCi8vIFRoaXMgZnVuY3Rpb24gY29tcHV0ZXMgdGhlIGZlZSBncm93dGggZm9yIHRva2VuIDAgYW5kIHRva2VuIDEgYWJvdmUgYSBnaXZlbiB0aWNrIChgdGlja1VwcGVyYCkKLy8gcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgdGljayAoYHRpY2tDdXJyZW50YCkuIFRoZSBmZWUgZ3Jvd3RoIHZhbHVlcyBhcmUgYWRqdXN0ZWQgYmFzZWQgb24gd2hldGhlcgovLyB0aGUgYHRpY2tDdXJyZW50YCBpcyBhYm92ZSBvciBiZWxvdyB0aGUgYHRpY2tVcHBlcmAuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0aWNrVXBwZXI6IGludDMyLCB0aGUgdXBwZXIgdGljayBib3VuZGFyeSBmb3IgZmVlIGNhbGN1bGF0aW9uLgovLyAgIC0gdGlja0N1cnJlbnQ6IGludDMyLCB0aGUgY3VycmVudCB0aWNrIGluZGV4LgovLyAgIC0gZmVlR3Jvd3RoR2xvYmFsMFgxMjg6ICp1MjU2LlVpbnQsIHRoZSBnbG9iYWwgZmVlIGdyb3d0aCBmb3IgdG9rZW4gMCBpbiBYMTI4IHByZWNpc2lvbi4KLy8gICAtIGZlZUdyb3d0aEdsb2JhbDFYMTI4OiAqdTI1Ni5VaW50LCB0aGUgZ2xvYmFsIGZlZSBncm93dGggZm9yIHRva2VuIDEgaW4gWDEyOCBwcmVjaXNpb24uCi8vICAgLSB1cHBlclRpY2s6IFRpY2tJbmZvLCB0aGUgZmVlIGdyb3d0aCBhbmQgbGlxdWlkaXR5IGRldGFpbHMgZm9yIHRoZSB1cHBlciB0aWNrLgovLwovLyBSZXR1cm5zOgovLyAgIC0gKnUyNTYuVWludDogRmVlIGdyb3d0aCBhYm92ZSBgdGlja1VwcGVyYCBmb3IgdG9rZW4gMC4KLy8gICAtICp1MjU2LlVpbnQ6IEZlZSBncm93dGggYWJvdmUgYHRpY2tVcHBlcmAgZm9yIHRva2VuIDEuCi8vCi8vIFdvcmtmbG93OgovLyAgMS4gSWYgYHRpY2tDdXJyZW50YCBpcyBsZXNzIHRoYW4gYHRpY2tVcHBlcmA6Ci8vICAgICAtIFJldHVybiB0aGUgYGZlZUdyb3d0aE91dHNpZGUwWDEyOGAgYW5kIGBmZWVHcm93dGhPdXRzaWRlMVgxMjhgIHZhbHVlcyBvZiB0aGUgYHVwcGVyVGlja2AuCi8vICAyLiBJZiBgdGlja0N1cnJlbnRgIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgdGlja1VwcGVyYDoKLy8gICAgIC0gQ29tcHV0ZSB0aGUgZmVlIGdyb3d0aCBhYm92ZSB0aGUgdXBwZXIgdGljayBieSBzdWJ0cmFjdGluZyBgZmVlR3Jvd3RoT3V0c2lkZWAgdmFsdWVzCi8vICAgICBmcm9tIHRoZSBnbG9iYWwgZmVlIGdyb3d0aCB2YWx1ZXMgKGBmZWVHcm93dGhHbG9iYWwwWDEyOGAgYW5kIGBmZWVHcm93dGhHbG9iYWwxWDEyOGApLgovLyAgMy4gUmV0dXJuIHRoZSBjYWxjdWxhdGVkIGZlZSBncm93dGggdmFsdWVzIGZvciBib3RoIHRva2Vucy4KLy8KLy8gQmVoYXZpb3I6Ci8vICAgLSBJZiBgdGlja0N1cnJlbnQgPCB0aWNrVXBwZXJgLCB0aGUgZmVlIGdyb3d0aCBvdXRzaWRlIHRoZSB1cHBlciB0aWNrIGlzIHJldHVybmVkIGFzLWlzLgovLyAgIC0gSWYgYHRpY2tDdXJyZW50ID49IHRpY2tVcHBlcmAsIHRoZSBmZWUgZ3Jvd3RoIGlzIGNhbGN1bGF0ZWQgYXM6Ci8vICAgICBmZWVHcm93dGhBYm92ZSA9IGZlZUdyb3d0aEdsb2JhbCAtIGZlZUdyb3d0aE91dHNpZGUKLy8KLy8gRXhhbXBsZToKLy8KLy8JZmVlR3Jvd3RoMCwgZmVlR3Jvd3RoMSA6PSBnZXRGZWVHcm93dGhBYm92ZVgxMjgoCi8vCSAgICAyMDAsIDE1MCwgZ2xvYmFsRmVlR3Jvd3RoMCwgZ2xvYmFsRmVlR3Jvd3RoMSwgdXBwZXJUaWNrSW5mbywKLy8JKQovLwlwcmludGxuKCJGZWUgR3Jvd3RoIEFib3ZlOiIsIGZlZUdyb3d0aDAsIGZlZUdyb3d0aDEpCi8vCi8vIGBgYApmdW5jIGdldEZlZUdyb3d0aEFib3ZlWDEyOCgKCXRpY2tVcHBlciwgdGlja0N1cnJlbnQgaW50MzIsCglmZWVHcm93dGhHbG9iYWwwWDEyOCwgZmVlR3Jvd3RoR2xvYmFsMVgxMjggKnUyNTYuVWludCwKCXVwcGVyVGljayBwbC5UaWNrSW5mbywKKSAoKnUyNTYuVWludCwgKnUyNTYuVWludCkgewoJZmVlT3V0c2lkZTAgOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwodXBwZXJUaWNrLkZlZUdyb3d0aE91dHNpZGUwWDEyOCgpKQoJZmVlT3V0c2lkZTEgOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwodXBwZXJUaWNrLkZlZUdyb3d0aE91dHNpZGUxWDEyOCgpKQoKCWlmIHRpY2tDdXJyZW50IDwgdGlja1VwcGVyIHsKCQlyZXR1cm4gZmVlT3V0c2lkZTAsIGZlZU91dHNpZGUxCgl9CgoJZmVlR3Jvd3RoQWJvdmUwWDEyOCA6PSB1MjU2Llplcm8oKS5TdWIoZmVlR3Jvd3RoR2xvYmFsMFgxMjgsIGZlZU91dHNpZGUwKQoJZmVlR3Jvd3RoQWJvdmUxWDEyOCA6PSB1MjU2Llplcm8oKS5TdWIoZmVlR3Jvd3RoR2xvYmFsMVgxMjgsIGZlZU91dHNpZGUxKQoKCXJldHVybiBmZWVHcm93dGhBYm92ZTBYMTI4LCBmZWVHcm93dGhBYm92ZTFYMTI4Cn0KCi8vIHZhbGlkYXRlVGlja3MgdmFsaWRhdGVzIHRoZSB0aWNrIHJhbmdlIGZvciBhIGxpcXVpZGl0eSBwb3NpdGlvbi4KLy8KLy8gVGhpcyBmdW5jdGlvbiBwZXJmb3JtcyB0aHJlZSBlc3NlbnRpYWwgY2hlY2tzIHRvIGVuc3VyZSB0aGUgcHJvdmlkZWQKLy8gdGljayB2YWx1ZXMgYXJlIHZhbGlkIGJlZm9yZSBjcmVhdGluZyBvciBtb2RpZnlpbmcgYSBsaXF1aWRpdHkgcG9zaXRpb24uCmZ1bmMgdmFsaWRhdGVUaWNrcyh0aWNrTG93ZXIsIHRpY2tVcHBlciBpbnQzMikgZXJyb3IgewoJaWYgdGlja0xvd2VyID49IHRpY2tVcHBlciB7CgkJcmV0dXJuIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkVGlja1JhbmdlLAoJCQl1Zm10LlNwcmludGYoInRpY2tMb3dlciglZCksIHRpY2tVcHBlciglZCkiLCB0aWNrTG93ZXIsIHRpY2tVcHBlciksCgkJKQoJfQoKCWlmIHRpY2tMb3dlciA8IE1JTl9USUNLIHsKCQlyZXR1cm4gbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyclRpY2tMb3dlckludmFsaWQsCgkJCXVmbXQuU3ByaW50ZigidGlja0xvd2VyKCVkKSA8IE1JTl9USUNLKCVkKSIsIHRpY2tMb3dlciwgTUlOX1RJQ0spLAoJCSkKCX0KCglpZiB0aWNrVXBwZXIgPiBNQVhfVElDSyB7CgkJcmV0dXJuIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJUaWNrVXBwZXJJbnZhbGlkLAoJCQl1Zm10LlNwcmludGYoInRpY2tVcHBlciglZCkgPiBNQVhfVElDSyglZCkiLCB0aWNrVXBwZXIsIE1BWF9USUNLKSwKCQkpCgl9CgoJcmV0dXJuIG5pbAp9Chr1KgoPdGlja19iaXRtYXAuZ25vEuEqcGFja2FnZSBwb29sCgppbXBvcnQgKAoJImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJdTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL3VpbnQyNTYvdjEiCglwbCAiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiCikKCi8vIGJpdE1hc2s4IGlzIHVzZWQgZm9yIGVmZmljaWVudCBtb2R1bG8gMjU2IG9wZXJhdGlvbnMKY29uc3QgYml0TWFzazggPSAweGZmIC8vIDI1NiAtIDEKCi8vIHRpY2tCaXRtYXBGbGlwVGljayBmbGlwcyB0aGUgc3RhdGUgb2YgYSB0aWNrIGluIHRoZSB0aWNrIGJpdG1hcC4KLy8KLy8gVGhpcyBmdW5jdGlvbiB0b2dnbGVzIHRoZSAiaW5pdGlhbGl6ZWQiIHN0YXRlIG9mIGEgdGljayBpbiB0aGUgdGljayBiaXRtYXAuCi8vIEl0IGVuc3VyZXMgdGhhdCB0aGUgdGljayBhbGlnbnMgd2l0aCB0aGUgc3BlY2lmaWVkIHRpY2sgc3BhY2luZyBhbmQgdGhlbgovLyBmbGlwcyB0aGUgY29ycmVzcG9uZGluZyBiaXQgaW4gdGhlIGJpdG1hcCByZXByZXNlbnRhdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHRpY2s6IGludDMyLCB0aGUgdGljayBpbmRleCB0byB0b2dnbGUuCi8vICAgLSB0aWNrU3BhY2luZzogaW50MzIsIHRoZSBzcGFjaW5nIGJldHdlZW4gdmFsaWQgdGlja3MuCi8vICAgICBUaGUgdGljayBtdXN0IGFsaWduIHdpdGggdGhpcyBzcGFjaW5nLgovLwovLyBXb3JrZmxvdzoKLy8gIDEuIFZhbGlkYXRlcyB0aGF0IHRoZSBgdGlja2AgYWxpZ25zIHdpdGggYHRpY2tTcGFjaW5nYCB1c2luZyBgY2hlY2tUaWNrU3BhY2luZ2AuCi8vICAyLiBDb21wdXRlcyB0aGUgcG9zaXRpb24gb2YgdGhlIGJpdCBpbiB0aGUgdGljayBiaXRtYXA6Ci8vICAgICAtIGB3b3JkUG9zYDogRGV0ZXJtaW5lcyB3aGljaCB3b3JkIGluIHRoZSBiaXRtYXAgY29udGFpbnMgdGhlIGJpdC4KLy8gICAgIC0gYGJpdFBvc2A6IElkZW50aWZpZXMgdGhlIHBvc2l0aW9uIG9mIHRoZSBiaXQgd2l0aGluIHRoZSB3b3JkLgovLyAgMy4gQ3JlYXRlcyBhIGJpdG1hc2sgdXNpbmcgYExzaGAgKExlZnQgU2hpZnQpIHRvIHRhcmdldCB0aGUgYml0IGF0IGBiaXRQb3NgLgovLyAgNC4gVG9nZ2xlcyAoZmxpcHMpIHRoZSBiaXQgdXNpbmcgWE9SIHdpdGggdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHRpY2sgYml0bWFwLgovLyAgNS4gVXBkYXRlcyB0aGUgdGljayBiaXRtYXAgd2l0aCB0aGUgbW9kaWZpZWQgd29yZC4KLy8KLy8gQmVoYXZpb3I6Ci8vICAgLSBJZiB0aGUgYml0IGlzIGAwYCAodW5pbml0aWFsaXplZCksIGl0IHdpbGwgYmUgZmxpcHBlZCB0byBgMWAgKGluaXRpYWxpemVkKS4KLy8gICAtIElmIHRoZSBiaXQgaXMgYDFgIChpbml0aWFsaXplZCksIGl0IHdpbGwgYmUgZmxpcHBlZCB0byBgMGAgKHVuaW5pdGlhbGl6ZWQpLgovLwovLyBFeGFtcGxlOgovLwovLwlwb29sLnRpY2tCaXRtYXBGbGlwVGljaygxMjAsIDYwKQovLwkvLyBUaGlzIGZsaXBzIHRoZSBiaXQgZm9yIHRpY2sgMTIwIHdpdGggYSB0aWNrIHNwYWNpbmcgb2YgNjAuCi8vCi8vIE5vdGVzOgovLyAgIC0gVGhlIGB0aWNrYCBtdXN0IGJlIGRpdmlzaWJsZSBieSBgdGlja1NwYWNpbmdgLiBJZiBub3QsIHRoZSBmdW5jdGlvbiB3aWxsIHBhbmljLgpmdW5jIHRpY2tCaXRtYXBGbGlwVGljaygKCXAgKnBsLlBvb2wsCgl0aWNrIGludDMyLAoJdGlja1NwYWNpbmcgaW50MzIsCikgewoJY2hlY2tUaWNrU3BhY2luZyh0aWNrLCB0aWNrU3BhY2luZykKCXdvcmRQb3MsIGJpdFBvcyA6PSB0aWNrQml0bWFwUG9zaXRpb24odGljayAvIHRpY2tTcGFjaW5nKQoKCW1hc2sgOj0gdTI1Ni5aZXJvKCkuTHNoKHUyNTYuT25lKCksIHVpbnQoYml0UG9zKSkKCWN1cnJlbnQgOj0gZ2V0VGlja0JpdG1hcChwLCB3b3JkUG9zKQoJbmV4dCA6PSB1MjU2Llplcm8oKS5Yb3IoY3VycmVudCwgbWFzaykKCWlmIG5leHQuSXNaZXJvKCkgewoJCWRlbGV0ZVRpY2tCaXRtYXAocCwgd29yZFBvcykKCQlyZXR1cm4KCX0KCglzZXRUaWNrQml0bWFwKHAsIHdvcmRQb3MsIG5leHQpCn0KCi8vIHRpY2tCaXRtYXBOZXh0SW5pdGlhbGl6ZWRUaWNrV2l0aEluT25lV29yZCBmaW5kcyB0aGUgbmV4dCBpbml0aWFsaXplZCB0aWNrIHdpdGhpbgovLyBvbmUgd29yZCBvZiB0aGUgYml0bWFwLgpmdW5jIHRpY2tCaXRtYXBOZXh0SW5pdGlhbGl6ZWRUaWNrV2l0aEluT25lV29yZCgKCXAgKnBsLlBvb2wsCgl0aWNrIGludDMyLAoJdGlja1NwYWNpbmcgaW50MzIsCglsdGUgYm9vbCwKKSAoaW50MzIsIGJvb2wpIHsKCWNvbXByZXNzIDo9IHRpY2sgLyB0aWNrU3BhY2luZwoJLy8gUm91bmQgdG93YXJkcyBuZWdhdGl2ZSBpbmZpbml0eSBmb3IgbmVnYXRpdmUgdGlja3MKCWlmIHRpY2sgPCAwICYmIHRpY2sldGlja1NwYWNpbmcgIT0gMCB7CgkJY29tcHJlc3MtLQoJfQoKCXdvcmRQb3MsIGJpdFBvcyA6PSBnZXRXb3JkQW5kQml0UG9zKGNvbXByZXNzLCBsdGUpCgltYXNrIDo9IGdldE1hc2tCaXQodWludChiaXRQb3MpLCBsdGUpCgltYXNrZWQgOj0gdTI1Ni5aZXJvKCkuQW5kKGdldFRpY2tCaXRtYXAocCwgd29yZFBvcyksIG1hc2spCglpbml0aWFsaXplZCA6PSAhbWFza2VkLklzWmVybygpCgoJbmV4dFRpY2sgOj0gZ2V0TmV4dFRpY2sobHRlLCBpbml0aWFsaXplZCwgY29tcHJlc3MsIGJpdFBvcywgdGlja1NwYWNpbmcsIG1hc2tlZCkKCXJldHVybiBuZXh0VGljaywgaW5pdGlhbGl6ZWQKfQoKLy8gZ2V0VGlja0JpdG1hcCBnZXRzIHRoZSB0aWNrIGJpdG1hcCBmb3IgdGhlIGdpdmVuIHdvcmQgcG9zaXRpb24uCi8vIE1pc3Npbmcgd29yZHMgYXJlIGltcGxpY2l0IHplcm9lcy4KZnVuYyBnZXRUaWNrQml0bWFwKHAgKnBsLlBvb2wsIHdvcmRQb3MgaW50MTYpICp1MjU2LlVpbnQgewoJdmFsdWUsIGV4aXN0IDo9IHAuVGlja0JpdG1hcHMoKVt3b3JkUG9zXQoJaWYgIWV4aXN0IHsKCQlyZXR1cm4gdTI1Ni5aZXJvKCkKCX0KCglyZXR1cm4gdTI1Ni5NdXN0RnJvbURlY2ltYWwodmFsdWUpCn0KCi8vIHNldFRpY2tCaXRtYXAgc2V0cyB0aGUgdGljayBiaXRtYXAgZm9yIHRoZSBnaXZlbiB3b3JkIHBvc2l0aW9uLgpmdW5jIHNldFRpY2tCaXRtYXAocCAqcGwuUG9vbCwgd29yZFBvcyBpbnQxNiwgdGlja0JpdG1hcCAqdTI1Ni5VaW50KSB7CglwLlNldFRpY2tCaXRtYXAod29yZFBvcywgdGlja0JpdG1hcC5Ub1N0cmluZygpKQp9CgovLyBkZWxldGVUaWNrQml0bWFwIGRlbGV0ZXMgdGhlIHRpY2sgYml0bWFwIGZvciB0aGUgZ2l2ZW4gd29yZCBwb3NpdGlvbi4KZnVuYyBkZWxldGVUaWNrQml0bWFwKHAgKnBsLlBvb2wsIHdvcmRQb3MgaW50MTYpIHsKCXAuRGVsZXRlVGlja0JpdG1hcCh3b3JkUG9zKQp9CgovLyB0aWNrQml0bWFwUG9zaXRpb24gY2FsY3VsYXRlcyB0aGUgd29yZCBhbmQgYml0IHBvc2l0aW9uIGZvciBhIGdpdmVuIHRpY2sKZnVuYyB0aWNrQml0bWFwUG9zaXRpb24odGljayBpbnQzMikgKGludDE2LCB1aW50OCkgewoJcmV0dXJuIGludDE2KHRpY2sgPj4gOCksIHVpbnQ4KHRpY2spICYgYml0TWFzazgKfQoKLy8gZ2V0V29yZEFuZEJpdFBvcyBnZXRzIHRpY2sncyB3b3JkUG9zIGFuZCBiaXRQb3MgZGVwZW5kaW5nIG9uIHRoZSBzd2FwIGRpcmVjdGlvbgpmdW5jIGdldFdvcmRBbmRCaXRQb3ModGljayBpbnQzMiwgbHRlIGJvb2wpIChpbnQxNiwgdWludDgpIHsKCWlmICFsdGUgewoJCXRpY2srKwoJfQoJcmV0dXJuIHRpY2tCaXRtYXBQb3NpdGlvbih0aWNrKQp9CgovLyBnZXRNYXNrQml0IGdlbmVyYXRlcyBhIG1hc2sgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGJpdCBwb3NpdGlvbiAoYml0UG9zKSBhbmQgYSBib29sZWFuIGZsYWcgKGx0ZSkuCi8vIFRoZSBmdW5jdGlvbiBjb25zdHJ1Y3RzIGEgYml0bWFzayB3aXRoIGEgc2hpZnQgZGVwZW5kaW5nIG9uIHRoZSBiaXQgcG9zaXRpb24gYW5kIHRoZSBib29sZWFuIHZhbHVlLgovLyBJdCBlaXRoZXIgcmV0dXJucyB0aGUgbWFzayBvciBpdHMgbmVnYXRpb24sIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiAnbHRlJyAoc3dhcCBkaXJlY3Rpb24pLgovLwovLyBOT1RFOiBzaG91bGQgYWx3YXlzIHVzZSBhIG5ld2x5IGNyZWF0ZWQgYHUyNTYuT25lKClgIG9iamVjdC4KZnVuYyBnZXRNYXNrQml0KGJpdFBvcyB1aW50LCBsdGUgYm9vbCkgKnUyNTYuVWludCB7CglpZiBsdGUgewoJCWlmIGJpdFBvcyA9PSBiaXRNYXNrOCB7CgkJCXJldHVybiB1MjU2Llplcm8oKS5TZXRBbGxPbmUoKQoJCX0KCQlyZXR1cm4gdTI1Ni5aZXJvKCkuU3ViKHUyNTYuWmVybygpLkxzaCh1MjU2Lk9uZSgpLCBiaXRQb3MrMSksIHUyNTYuT25lKCkpCgl9CglpZiBiaXRQb3MgPT0gMCB7CgkJcmV0dXJuIHUyNTYuWmVybygpLlNldEFsbE9uZSgpCgl9CglyZXR1cm4gdTI1Ni5aZXJvKCkuTm90KHUyNTYuWmVybygpLlN1Yih1MjU2Llplcm8oKS5Mc2godTI1Ni5PbmUoKSwgYml0UG9zKSwgdTI1Ni5PbmUoKSkpCn0KCi8vIGdldE5leHRUaWNrIGdldHMgdGhlIG5leHQgdGljayBkZXBlbmRpbmcgb24gdGhlIGluaXRpYWxpemVkIHN0YXRlIGFuZCB0aGUgc3dhcCBkaXJlY3Rpb24KZnVuYyBnZXROZXh0VGljayhsdGUsIGluaXRpYWxpemVkIGJvb2wsIGNvbXByZXNzIGludDMyLCBiaXRQb3MgdWludDgsIHRpY2tTcGFjaW5nIGludDMyLCBtYXNrZWQgKnUyNTYuVWludCkgaW50MzIgewoJaWYgaW5pdGlhbGl6ZWQgewoJCXJldHVybiBnZXRUaWNrSWZJbml0aWFsaXplZChjb21wcmVzcywgdGlja1NwYWNpbmcsIGJpdFBvcywgbWFza2VkLCBsdGUpCgl9CglyZXR1cm4gZ2V0VGlja0lmTm90SW5pdGlhbGl6ZWQoY29tcHJlc3MsIHRpY2tTcGFjaW5nLCBiaXRQb3MsIGx0ZSkKfQoKLy8gZ2V0VGlja0lmSW5pdGlhbGl6ZWQgZ2V0cyB0aGUgbmV4dCB0aWNrIGlmIHRoZSB0aWNrIGJpdG1hcCBpcyBpbml0aWFsaXplZApmdW5jIGdldFRpY2tJZkluaXRpYWxpemVkKGNvbXByZXNzLCB0aWNrU3BhY2luZyBpbnQzMiwgYml0UG9zIHVpbnQ4LCBtYXNrZWQgKnUyNTYuVWludCwgbHRlIGJvb2wpIGludDMyIHsKCWlmIGx0ZSB7CgkJcmV0dXJuIChjb21wcmVzcyAtIGludDMyKGJpdFBvcy1nbnNtYXRoLkJpdE1hdGhNb3N0U2lnbmlmaWNhbnRCaXQobWFza2VkKSkpICogdGlja1NwYWNpbmcKCX0KCXJldHVybiAoY29tcHJlc3MgKyAxICsgaW50MzIoZ25zbWF0aC5CaXRNYXRoTGVhc3RTaWduaWZpY2FudEJpdChtYXNrZWQpLWJpdFBvcykpICogdGlja1NwYWNpbmcKfQoKLy8gZ2V0VGlja0lmTm90SW5pdGlhbGl6ZWQgZ2V0cyB0aGUgbmV4dCB0aWNrIGlmIHRoZSB0aWNrIGJpdG1hcCBpcyBub3QgaW5pdGlhbGl6ZWQKZnVuYyBnZXRUaWNrSWZOb3RJbml0aWFsaXplZChjb21wcmVzcywgdGlja1NwYWNpbmcgaW50MzIsIGJpdFBvcyB1aW50OCwgbHRlIGJvb2wpIGludDMyIHsKCWlmIGx0ZSB7CgkJcmV0dXJuIChjb21wcmVzcyAtIGludDMyKGJpdFBvcykpICogdGlja1NwYWNpbmcKCX0KCXJldHVybiAoY29tcHJlc3MgKyAxICsgaW50MzIoYml0TWFzazgtYml0UG9zKSkgKiB0aWNrU3BhY2luZwp9ChqMUgoMdHJhbnNmZXIuZ25vEvtRcGFja2FnZSBwb29sCgppbXBvcnQgKAoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoKCXByYWJjICJnbm8ubGFuZC9wL2dub3N3YXAvcmJhYy92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKCSJnbm8ubGFuZC9yL2dub3N3YXAvY29tbW9uIgoJcGwgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCWkyNTYgImduby5sYW5kL3AvZ25vc3dhcC9pbnQyNTYvdjEiCgl1MjU2ICJnbm8ubGFuZC9wL2dub3N3YXAvdWludDI1Ni92MSIKKQoKLy8gc2FmZVRyYW5zZmVyIHBlcmZvcm1zIGEgdG9rZW4gdHJhbnNmZXIgb3V0IG9mIHRoZSBwb29sIHdoaWxlIGVuc3VyaW5nCi8vIHRoZSBwb29sIGhhcyBzdWZmaWNpZW50IGJhbGFuY2UgYW5kIHVwZGF0aW5nIGludGVybmFsIGFjY291bnRpbmcuCi8vIFRoaXMgZnVuY3Rpb24gaXMgdHlwaWNhbGx5IHVzZWQgZHVyaW5nIHN3YXBzIGFuZCBsaXF1aWRpdHkgcmVtb3ZhbHMuCi8vCi8vIEltcG9ydGFudCByZXF1aXJlbWVudHM6Ci8vICAgLSBUaGUgYW1vdW50IG11c3QgYmUgYSBwb3NpdGl2ZSB2YWx1ZSByZXByZXNlbnRpbmcgdG9rZW5zIHRvIHRyYW5zZmVyIG91dAovLyAgIC0gVGhlIHBvb2wgbXVzdCBoYXZlIHN1ZmZpY2llbnQgYmFsYW5jZSBmb3IgdGhlIHRyYW5zZmVyCi8vICAgLSBUaGUgdHJhbnNmZXIgYW1vdW50IG11c3QgZml0IHdpdGhpbiBpbnQ2NCByYW5nZQovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcDogdGhlIHBvb2wgaW5zdGFuY2UKLy8gICAtIHRvOiBkZXN0aW5hdGlvbiBhZGRyZXNzIGZvciB0aGUgdHJhbnNmZXIKLy8gICAtIHRva2VuUGF0aDogcGF0aCBpZGVudGlmaWVyIG9mIHRoZSB0b2tlbiB0byB0cmFuc2ZlcgovLyAgIC0gYW1vdW50OiBhbW91bnQgdG8gdHJhbnNmZXIgKHBvc2l0aXZlIHUyNTYuVWludCB2YWx1ZSkKLy8gICAtIGlzVG9rZW4wOiB0cnVlIGlmIHRyYW5zZmVycmluZyB0b2tlbjAsIGZhbHNlIGZvciB0b2tlbjEKLy8KLy8gVGhlIGZ1bmN0aW9uIHdpbGw6Ci8vICAxLiBDaGVjayBwb29sIGhhcyBzdWZmaWNpZW50IGJhbGFuY2UKLy8gIDIuIEV4ZWN1dGUgdGhlIHRyYW5zZmVyCi8vICAzLiBTdWJ0cmFjdCB0aGUgYW1vdW50IGZyb20gcG9vbCdzIGludGVybmFsIGJhbGFuY2UKLy8KLy8gUGFuaWNzIGlmIGFueSB2YWxpZGF0aW9uIGZhaWxzIG9yIGlmIHRoZSB0cmFuc2ZlciBmYWlscwpmdW5jIChpICpwb29sVjEpIHNhZmVUcmFuc2ZlcigKCV8gaW50LAoJcmxtIHJlYWxtLAoJcCAqcGwuUG9vbCwKCXRvIGFkZHJlc3MsCgl0b2tlblBhdGggc3RyaW5nLAoJYW1vdW50ICp1MjU2LlVpbnQsCglpc1Rva2VuMCBib29sLAopIHsKCXRva2VuMCA6PSBwLkJhbGFuY2VUb2tlbjAoKQoJdG9rZW4xIDo9IHAuQmFsYW5jZVRva2VuMSgpCglhbW91bnRJbnQ2NCA6PSBnbnNtYXRoLlNhZmVDb252ZXJ0VG9JbnQ2NChhbW91bnQpCgoJaWYgZXJyIDo9IHZhbGlkYXRlUG9vbEJhbGFuY2UodG9rZW4wLCB0b2tlbjEsIGFtb3VudEludDY0LCBpc1Rva2VuMCk7IGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgljb21tb24uU2FmZUdSQzIwVHJhbnNmZXIoMCwgcmxtLCB0b2tlblBhdGgsIHRvLCBhbW91bnRJbnQ2NCkKCgluZXdCYWxhbmNlLCBlcnIgOj0gdXBkYXRlUG9vbEJhbGFuY2UodG9rZW4wLCB0b2tlbjEsIGFtb3VudEludDY0LCBpc1Rva2VuMCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglwb29sQmFsYW5jZXMgOj0gcC5CYWxhbmNlcygpCgoJaWYgaXNUb2tlbjAgewoJCXBvb2xCYWxhbmNlcy5TZXRUb2tlbjAobmV3QmFsYW5jZSkKCX0gZWxzZSB7CgkJcG9vbEJhbGFuY2VzLlNldFRva2VuMShuZXdCYWxhbmNlKQoJfQoKCXAuU2V0QmFsYW5jZXMocG9vbEJhbGFuY2VzKQp9CgovLyBzYWZlVHJhbnNmZXJGcm9tIHNlY3VyZWx5IHRyYW5zZmVycyB0b2tlbnMgaW50byB0aGUgcG9vbCB3aGlsZSBlbnN1cmluZyBiYWxhbmNlIGNvbnNpc3RlbmN5LgovLwovLyBUaGlzIGZ1bmN0aW9uIHBlcmZvcm1zIHRoZSBmb2xsb3dpbmcgc3RlcHM6Ci8vIDEuIFZhbGlkYXRlcyBhbmQgY29udmVydHMgdGhlIHRyYW5zZmVyIGFtb3VudCB0byBgaW50NjRgIHVzaW5nIGBnbnNtYXRoLlNhZmVDb252ZXJ0VG9JbnQ2NGAuCi8vIDIuIEV4ZWN1dGVzIHRoZSB0b2tlbiB0cmFuc2ZlciB1c2luZyBgVHJhbnNmZXJGcm9tYCB2aWEgdGhlIHRva2VuIHRlbGxlciBjb250cmFjdC4KLy8gMy4gVmVyaWZpZXMgdGhhdCB0aGUgZGVzdGluYXRpb24gYmFsYW5jZSByZWZsZWN0cyB0aGUgY29ycmVjdCBhbW91bnQgYWZ0ZXIgdHJhbnNmZXIuCi8vIDQuIFVwZGF0ZXMgdGhlIHBvb2wncyBpbnRlcm5hbCBiYWxhbmNlcyAoYHRva2VuMGAgb3IgYHRva2VuMWApIGFuZCB2YWxpZGF0ZXMgdGhlIHVwZGF0ZWQgc3RhdGUuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vIC0gcCAoKnBsLlBvb2wpOiBUaGUgcG9vbCBpbnN0YW5jZSB0byB0cmFuc2ZlciB0b2tlbnMgaW50by4KLy8gLSBmcm9tIChhZGRyZXNzKTogU291cmNlIGFkZHJlc3MgZm9yIHRoZSB0b2tlbiB0cmFuc2Zlci4KLy8gLSB0byAoYWRkcmVzcyk6IERlc3RpbmF0aW9uIGFkZHJlc3MsIHR5cGljYWxseSB0aGUgcG9vbCBhZGRyZXNzLgovLyAtIHRva2VuUGF0aCAoc3RyaW5nKTogUGF0aCBpZGVudGlmaWVyIGZvciB0aGUgdG9rZW4gYmVpbmcgdHJhbnNmZXJyZWQuCi8vIC0gYW1vdW50ICgqdTI1Ni5VaW50KTogVGhlIGFtb3VudCBvZiB0b2tlbnMgdG8gdHJhbnNmZXIgKG11c3QgYmUgYSBwb3NpdGl2ZSB2YWx1ZSkuCi8vIC0gaXNUb2tlbjAgKGJvb2wpOiBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSB0b2tlbiBiZWluZyB0cmFuc2ZlcnJlZCBpcyB0b2tlbjAgKGB0cnVlYCkgb3IgdG9rZW4xIChgZmFsc2VgKS4KLy8KLy8gUGFuaWNzOgovLyAtIElmIHRoZSBgYW1vdW50YCBleGNlZWRzIHRoZSBpbnQ2NCByYW5nZSBkdXJpbmcgY29udmVyc2lvbi4KLy8gLSBJZiB0aGUgdG9rZW4gdHJhbnNmZXIgKGBUcmFuc2ZlckZyb21gKSBmYWlscy4KLy8gLSBJZiB0aGUgZGVzdGluYXRpb24gYmFsYW5jZSBhZnRlciB0aGUgdHJhbnNmZXIgZG9lcyBub3QgbWF0Y2ggdGhlIGV4cGVjdGVkIGFtb3VudC4KLy8gLSBJZiB0aGUgcG9vbCdzIGludGVybmFsIGJhbGFuY2VzIChgdG9rZW4wYCBvciBgdG9rZW4xYCkgb3ZlcmZsb3cgb3IgYmVjb21lIGluY29uc2lzdGVudC4KLy8KLy8gTm90ZXM6Ci8vIC0gVGhlIGZ1bmN0aW9uIGFzc3VtZXMgdGhhdCB0aGUgc2VuZGVyIChgZnJvbWApIGhhcyBhcHByb3ZlZCB0aGUgcG9vbCB0byBzcGVuZCB0aGUgc3BlY2lmaWVkIHRva2Vucy4KLy8gLSBUaGUgYmFsYW5jZSBjb25zaXN0ZW5jeSBjaGVjayBlbnN1cmVzIHRoYXQgbm8gdG9rZW5zIGFyZSBsb3N0IG9yIGRvdWJsZS1jb3VudGVkIGR1cmluZyB0aGUgdHJhbnNmZXIuCi8vIC0gUG9vbCBiYWxhbmNlIHVwZGF0ZXMgYXJlIHBlcmZvcm1lZCBhdG9taWNhbGx5IHRvIGVuc3VyZSBpbnRlcm5hbCBjb25zaXN0ZW5jeS4KZnVuYyAoaSAqcG9vbFYxKSBzYWZlVHJhbnNmZXJGcm9tKAoJXyBpbnQsCglybG0gcmVhbG0sCglwICpwbC5Qb29sLAoJZnJvbSwgdG8gYWRkcmVzcywKCXRva2VuUGF0aCBzdHJpbmcsCglhbW91bnQgKnUyNTYuVWludCwKCWlzVG9rZW4wIGJvb2wsCikgewoJYW1vdW50SW50NjQgOj0gZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQoYW1vdW50KQoKCWJlZm9yZUJhbGFuY2UgOj0gY29tbW9uLkJhbGFuY2VPZih0b2tlblBhdGgsIHRvKQoKCWNvbW1vbi5TYWZlR1JDMjBUcmFuc2ZlckZyb20oMCwgcmxtLCB0b2tlblBhdGgsIGZyb20sIHRvLCBhbW91bnRJbnQ2NCkKCglhZnRlckJhbGFuY2UgOj0gY29tbW9uLkJhbGFuY2VPZih0b2tlblBhdGgsIHRvKQoJaWYgZ25zbWF0aC5TYWZlQWRkSW50NjQoYmVmb3JlQmFsYW5jZSwgYW1vdW50SW50NjQpICE9IGFmdGVyQmFsYW5jZSB7CgkJcGFuaWModWZtdC5TcHJpbnRmKAoJCQkiJXYuIGJlZm9yZUJhbGFuY2UoJWQpICsgYW1vdW50KCVkKSAhPSBhZnRlckJhbGFuY2UoJWQpIiwKCQkJZXJyVHJhbnNmZXJGYWlsZWQsIGJlZm9yZUJhbGFuY2UsIGFtb3VudEludDY0LCBhZnRlckJhbGFuY2UsCgkJKSkKCX0KCglwb29sQmFsYW5jZXMgOj0gcC5CYWxhbmNlcygpCgoJLy8gdXBkYXRlIHBvb2wgYmFsYW5jZXMKCWlmIGlzVG9rZW4wIHsKCQlwb29sQmFsYW5jZXMuU2V0VG9rZW4wKGduc21hdGguU2FmZUFkZEludDY0KHBvb2xCYWxhbmNlcy5Ub2tlbjAoKSwgYW1vdW50SW50NjQpKQoJfSBlbHNlIHsKCQlwb29sQmFsYW5jZXMuU2V0VG9rZW4xKGduc21hdGguU2FmZUFkZEludDY0KHBvb2xCYWxhbmNlcy5Ub2tlbjEoKSwgYW1vdW50SW50NjQpKQoJfQoKCXAuU2V0QmFsYW5jZXMocG9vbEJhbGFuY2VzKQp9CgovLyBzYWZlU3dhcENhbGxiYWNrIGV4ZWN1dGVzIGEgc3dhcCBjYWxsYmFjayBhbmQgdmFsaWRhdGVzIHRoZSB0b2tlbiBwYXltZW50LgovLwovLyBUaGlzIGZ1bmN0aW9uIGltcGxlbWVudHMgdGhlIGZsYXNoIHN3YXAgcGF0dGVybiB3aGVyZSB0aGUgcG9vbCBmaXJzdCBzZW5kcyBvdXRwdXQgdG9rZW5zCi8vIHRvIHRoZSByZWNpcGllbnQsIHRoZW4gaW52b2tlcyB0aGUgY2FsbGJhY2sgdG8gcmVjZWl2ZSBpbnB1dCB0b2tlbnMgZnJvbSB0aGUgY2FsbGVyLgovLyBUaGUgY2FsbGJhY2sgaXMgcmVzcG9uc2libGUgZm9yIHRyYW5zZmVycmluZyB0aGUgcmVxdWlyZWQgaW5wdXQgdG9rZW5zIHRvIHRoZSBwb29sLgovLwovLyBDYWxsYmFjayBTaWduYXR1cmU6Ci8vCi8vCWZ1bmMoY3VyIHJlYWxtLCBhbW91bnQwRGVsdGEsIGFtb3VudDFEZWx0YSBpbnQ2NCwgXyAqcG9vbC5DYWxsYmFja01hcmtlcikgZXJyb3IKLy8KLy8gRGVsdGEgQ29udmVudGlvbiAoZm9sbG93aW5nIFVuaXN3YXAgVjMgc3RhbmRhcmQpOgovLyAgIC0gUG9zaXRpdmUgZGVsdGE6IEFtb3VudCB0aGUgcG9vbCBtdXN0IFJFQ0VJVkUgKGlucHV0IHRva2VuKQovLyAgIC0gTmVnYXRpdmUgZGVsdGE6IEFtb3VudCB0aGUgcG9vbCBoYXMgU0VOVCAob3V0cHV0IHRva2VuKQovLwovLyBGb3IgemVyb0Zvck9uZSBzd2FwcyAodG9rZW4wIOKGkiB0b2tlbjEpOgovLyAgIC0gYW1vdW50MERlbHRhID4gMDogUG9vbCByZWNlaXZlcyB0b2tlbjAgKGlucHV0KQovLyAgIC0gYW1vdW50MURlbHRhIDwgMDogUG9vbCBzZW5kcyB0b2tlbjEgKG91dHB1dCkKLy8KLy8gRm9yIG9uZUZvclplcm8gc3dhcHMgKHRva2VuMSDihpIgdG9rZW4wKToKLy8gICAtIGFtb3VudDBEZWx0YSA8IDA6IFBvb2wgc2VuZHMgdG9rZW4wIChvdXRwdXQpCi8vICAgLSBhbW91bnQxRGVsdGEgPiAwOiBQb29sIHJlY2VpdmVzIHRva2VuMSAoaW5wdXQpCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwOiBUaGUgcG9vbCBpbnN0YW5jZQovLyAgIC0gdG9rZW5QYXRoOiBQYXRoIG9mIHRoZSBpbnB1dCB0b2tlbiB0aGF0IHBvb2wgbXVzdCByZWNlaXZlCi8vICAgLSBhbW91bnRJbkludDI1NjogQW1vdW50IHBvb2wgbXVzdCByZWNlaXZlIChwb3NpdGl2ZSBpMjU2LkludCkKLy8gICAtIGFtb3VudE91dEludDI1NjogQW1vdW50IHBvb2wgaGFzIHNlbnQgKG5lZ2F0aXZlIGkyNTYuSW50KQovLyAgIC0gemVyb0Zvck9uZTogU3dhcCBkaXJlY3Rpb24gKHRydWUgPSB0b2tlbjAgdG8gdG9rZW4xKQovLyAgIC0gc3dhcENhbGxiYWNrOiBDYWxsYmFjayBmdW5jdGlvbiB0aGF0IG11c3QgdHJhbnNmZXIgaW5wdXQgdG9rZW5zIHRvIHBvb2wKLy8KLy8gVGhlIGNhbGxiYWNrIG5lZWRlZDoKLy8gIDEuIFZlcmlmeSB0aGUgY2FsbGVyIGlzIHRoZSBsZWdpdGltYXRlIHBvb2wgY29udHJhY3QgYWRkcmVzcyB0byBwcmV2ZW50IHVuYXV0aG9yaXplZCBpbnZvY2F0aW9ucwovLyAgMi4gVHJhbnNmZXIgYXQgbGVhc3QgYGFtb3VudEluYCBvZiBpbnB1dCB0b2tlbnMgdG8gdGhlIHBvb2wKLy8gIDMuIFJldHVybiBuaWwgb24gc3VjY2Vzcywgb3IgYW4gZXJyb3IgdG8gcmV2ZXJ0IHRoZSBzd2FwCi8vCi8vIEV4YW1wbGUgY2FsbGJhY2sgaW1wbGVtZW50YXRpb246Ci8vCi8vCWZ1bmMoY3VyIHJlYWxtLCBhbW91bnQwRGVsdGEsIGFtb3VudDFEZWx0YSBpbnQ2NCwgXyAqcG9vbC5DYWxsYmFja01hcmtlcikgZXJyb3IgewovLwkgICAgLy8gU2VjdXJpdHkgY2hlY2s6IGVuc3VyZSB0aGlzIGNhbGxiYWNrIGlzIGludm9rZWQgYnkgdGhlIGxlZ2l0aW1hdGUgcG9vbAovLwkgICAgY2FsbGVyIDo9IHJ1bnRpbWUuUHJldmlvdXNSZWFsbSgpLkFkZHJlc3MoKQovLwkgICAgcG9vbEFkZHIgOj0gY2hhaW4uUGFja2FnZUFkZHJlc3MoImduby5sYW5kL3IvZ25vc3dhcC9wb29sIikKLy8KLy8JICAgIGlmIGNhbGxlciAhPSBwb29sQWRkciB7Ci8vCSAgICAgICAgcGFuaWMoInVuYXV0aG9yaXplZCBjYWxsZXIiKQovLwkgICAgfQovLwovLwkgICAgaWYgYW1vdW50MERlbHRhID4gMCB7Ci8vCSAgICAgICAgLy8gVHJhbnNmZXIgdG9rZW4wIHRvIHBvb2wKLy8JICAgICAgICB0b2tlbjAuVHJhbnNmZXIoY3Jvc3MsIHBvb2xBZGRyLCBhbW91bnQwRGVsdGEpCi8vCSAgICB9Ci8vCSAgICBpZiBhbW91bnQxRGVsdGEgPiAwIHsKLy8JICAgICAgICAvLyBUcmFuc2ZlciB0b2tlbjEgdG8gcG9vbAovLwkgICAgICAgIHRva2VuMS5UcmFuc2Zlcihjcm9zcywgcG9vbEFkZHIsIGFtb3VudDFEZWx0YSkKLy8JICAgIH0KLy8JICAgIHJldHVybiBuaWwKLy8JfQpmdW5jIChpICpwb29sVjEpIHNhZmVTd2FwQ2FsbGJhY2soCglfIGludCwKCXJsbSByZWFsbSwKCXAgKnBsLlBvb2wsCgl0b2tlblBhdGggc3RyaW5nLAoJYW1vdW50SW5JbnQyNTYgKmkyNTYuSW50LAoJYW1vdW50T3V0SW50MjU2ICppMjU2LkludCwKCXplcm9Gb3JPbmUgYm9vbCwKCXN3YXBDYWxsYmFjayBmdW5jKGN1ciByZWFsbSwgYW1vdW50MERlbHRhLCBhbW91bnQxRGVsdGEgaW50NjQsIF8gKnBsLkNhbGxiYWNrTWFya2VyKSBlcnJvciwKKSB7CglpZiBzd2FwQ2FsbGJhY2sgPT0gbmlsIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZElucHV0LAoJCQkic3dhcENhbGxiYWNrIGlzIG5pbCIsCgkJKSkKCX0KCgljdXJyZW50QWRkcmVzcyA6PSBhY2Nlc3MuTXVzdEdldEFkZHJlc3MocHJhYmMuUk9MRV9QT09MLlN0cmluZygpKQoKCWFtb3VudEluIDo9IGFtb3VudEluSW50MjU2LkludDY0KCkKCWFtb3VudE91dCA6PSBhbW91bnRPdXRJbnQyNTYuSW50NjQoKQoJYmFsYW5jZUJlZm9yZSA6PSBjb21tb24uQmFsYW5jZU9mKHRva2VuUGF0aCwgY3VycmVudEFkZHJlc3MpCgoJLy8gTWFrZSBjYWxsYmFjayB0byB0aGUgY2FsbGluZyBjb250cmFjdAoJLy8gVGhlIGNvbnRyYWN0IHNob3VsZCB0cmFuc2ZlciB0b2tlbnMgdG8gcG9vbCB3aXRoaW4gdGhpcyBjYWxsYmFjawoJLy8gRm9sbG93aW5nIFVuaXN3YXAgVjMgY29udmVudGlvbjoKCS8vIC0gUG9zaXRpdmUgZGVsdGE6IGFtb3VudCB0aGUgcG9vbCBtdXN0IHJlY2VpdmUgKGlucHV0IHRva2VuKQoJLy8gLSBOZWdhdGl2ZSBkZWx0YTogYW1vdW50IHRoZSBwb29sIGhhcyBzZW50IChvdXRwdXQgdG9rZW4pCgl2YXIgYW1vdW50MERlbHRhLCBhbW91bnQxRGVsdGEsIGJlZm9yZVRva2VuQmFsYW5jZSBpbnQ2NAoKCWlmIHplcm9Gb3JPbmUgewoJCS8vIHplcm9Gb3JPbmU6IHBvb2wgcmVjZWl2ZXMgdG9rZW4wIChwb3NpdGl2ZSksIHNlbmRzIHRva2VuMSAobmVnYXRpdmUpCgkJYW1vdW50MERlbHRhID0gYW1vdW50SW4KCQlhbW91bnQxRGVsdGEgPSBhbW91bnRPdXQKCQliZWZvcmVUb2tlbkJhbGFuY2UgPSBwLkJhbGFuY2VUb2tlbjAoKQoJfSBlbHNlIHsKCQkvLyAhemVyb0Zvck9uZTogcG9vbCByZWNlaXZlcyB0b2tlbjEgKHBvc2l0aXZlKSwgc2VuZHMgdG9rZW4wIChuZWdhdGl2ZSkKCQlhbW91bnQwRGVsdGEgPSBhbW91bnRPdXQKCQlhbW91bnQxRGVsdGEgPSBhbW91bnRJbgoJCWJlZm9yZVRva2VuQmFsYW5jZSA9IHAuQmFsYW5jZVRva2VuMSgpCgl9CgoJLy8gZXhlY3V0ZSBzd2FwIGNhbGxiYWNrCgkvLyBDYWxsYmFja01hcmtlciBpcyBjcmVhdGVkIGJ5IHRoZSBwb29sIG1vZHVsZSB0byBlbmZvcmNlIHR5cGUtc3lzdGVtIGxldmVsIHZhbGlkYXRpb24uCgkvLyBBbGxvY2F0aW9uIGdvZXMgdGhyb3VnaCBwbC5OZXdDYWxsYmFja01hcmtlciBzbyB0aGUgYWxsb2MgaGFwcGVucyBpbiBwb29sIHJlYWxtCgkvLyAoaW50ZXJyZWFsbSB2MiBmb3JiaWRzIC9yLy1kZWNsYXJlZCB0eXBlcyBiZWluZyBjb25zdHJ1Y3RlZCBvdXRzaWRlIHRoZWlyIG93bmVyKS4KCWVyciA6PSBzd2FwQ2FsbGJhY2soY3Jvc3MocmxtKSwgYW1vdW50MERlbHRhLCBhbW91bnQxRGVsdGEsIHBsLk5ld0NhbGxiYWNrTWFya2VyKCkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJYmFsYW5jZUFmdGVyIDo9IGNvbW1vbi5CYWxhbmNlT2YodG9rZW5QYXRoLCBjdXJyZW50QWRkcmVzcykKCWJhbGFuY2VJbmNyZWFzZSA6PSBnbnNtYXRoLlNhZmVTdWJJbnQ2NChiYWxhbmNlQWZ0ZXIsIGJhbGFuY2VCZWZvcmUpCgoJLy8gY2hlY2sgaW5zdWZmaWNpZW50IHBheW1lbnQgYnkgc3dhcCBjYWxsYmFjawoJaWYgYmFsYW5jZUluY3JlYXNlIDwgYW1vdW50SW4gewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnN1ZmZpY2llbnRQYXltZW50LAoJCQl1Zm10LlNwcmludGYoImluc3VmZmljaWVudCBwYXltZW50OiBleHBlY3RlZCAlZCwgcmVjZWl2ZWQgJWQiLCBhbW91bnRJbiwgYmFsYW5jZUluY3JlYXNlKSwKCQkpKQoJfQoKCS8vIGNoZWNrIG92ZXJmbG93IHVwZGF0ZSBwb29sIGJhbGFuY2UKCXJlc3VsdFRva2VuQmFsYW5jZSA6PSBnbnNtYXRoLlNhZmVBZGRJbnQ2NChiZWZvcmVUb2tlbkJhbGFuY2UsIGFtb3VudEluKQoKCXBvb2xCYWxhbmNlcyA6PSBwLkJhbGFuY2VzKCkKCglpZiB6ZXJvRm9yT25lIHsKCQlwb29sQmFsYW5jZXMuU2V0VG9rZW4wKHJlc3VsdFRva2VuQmFsYW5jZSkKCX0gZWxzZSB7CgkJcG9vbEJhbGFuY2VzLlNldFRva2VuMShyZXN1bHRUb2tlbkJhbGFuY2UpCgl9CgoJcC5TZXRCYWxhbmNlcyhwb29sQmFsYW5jZXMpCn0KCi8vIHZhbGlkYXRlUG9vbEJhbGFuY2UgY2hlY2tzIGlmIHRoZSBwb29sIGhhcyBzdWZmaWNpZW50IGJhbGFuY2Ugb2YgZWl0aGVyIHRva2VuMCBhbmQgdG9rZW4xCi8vIGJlZm9yZSBwcm9jZWVkaW5nIHdpdGggYSB0cmFuc2Zlci4gVGhpcyBwcmV2ZW50cyB0aGUgcG9vbCB3b24ndCBnbyBpbnRvIGEgbmVnYXRpdmUgYmFsYW5jZS4KZnVuYyB2YWxpZGF0ZVBvb2xCYWxhbmNlKHRva2VuMCwgdG9rZW4xLCBhbW91bnQgaW50NjQsIGlzVG9rZW4wIGJvb2wpIGVycm9yIHsKCWlmIGFtb3VudCA8IDAgewoJCXJldHVybiB1Zm10LkVycm9yZigiJXYuIGFtb3VudCglZCkgbXVzdCBiZSBwb3NpdGl2ZSIsIGVyclRyYW5zZmVyRmFpbGVkLCBhbW91bnQpCgl9CgoJaWYgaXNUb2tlbjAgewoJCWlmIHRva2VuMCA8IGFtb3VudCB7CgkJCXJldHVybiB1Zm10LkVycm9yZigKCQkJCSIldi4gdG9rZW4wKCVkKSA+PSBhbW91bnQoJWQpIiwKCQkJCWVyclRyYW5zZmVyRmFpbGVkLCB0b2tlbjAsIGFtb3VudCwKCQkJKQoJCX0KCQlyZXR1cm4gbmlsCgl9CglpZiB0b2tlbjEgPCBhbW91bnQgewoJCXJldHVybiB1Zm10LkVycm9yZigKCQkJIiV2LiB0b2tlbjEoJWQpID49IGFtb3VudCglZCkiLAoJCQllcnJUcmFuc2ZlckZhaWxlZCwgdG9rZW4xLCBhbW91bnQsCgkJKQoJfQoJcmV0dXJuIG5pbAp9CgovLyB1cGRhdGVQb29sQmFsYW5jZSBjYWxjdWxhdGVzIHRoZSBuZXcgYmFsYW5jZSBhZnRlciBhIHRyYW5zZmVyIGFuZCB2YWxpZGF0ZS4KLy8gSXQgZW5zdXJlcyB0aGUgcmVzdWx0aW5nIGJhbGFuY2Ugd29uJ3QgYmUgbmVnYXRpdmUgb3Igb3ZlcmZsb3cuCmZ1bmMgdXBkYXRlUG9vbEJhbGFuY2UoCgl0b2tlbjAsIHRva2VuMSwgYW1vdW50IGludDY0LAoJaXNUb2tlbjAgYm9vbCwKKSAoaW50NjQsIGVycm9yKSB7CglpZiBhbW91bnQgPCAwIHsKCQlyZXR1cm4gMCwgdWZtdC5FcnJvcmYoIiV2LiBhbW91bnQoJWQpIG11c3QgYmUgcG9zaXRpdmUiLCBlcnJCYWxhbmNlVXBkYXRlRmFpbGVkLCBhbW91bnQpCgl9CgoJaWYgaXNUb2tlbjAgewoJCWlmIHRva2VuMCA8IGFtb3VudCB7CgkJCXJldHVybiAwLCB1Zm10LkVycm9yZigKCQkJCSIldi4gY2Fubm90IGRlY3JlYXNlLCB0b2tlbjAoJWQpIC0gYW1vdW50KCVkKSIsCgkJCQllcnJCYWxhbmNlVXBkYXRlRmFpbGVkLCB0b2tlbjAsIGFtb3VudCwKCQkJKQoJCX0KCQlyZXR1cm4gZ25zbWF0aC5TYWZlU3ViSW50NjQodG9rZW4wLCBhbW91bnQpLCBuaWwKCX0KCglpZiB0b2tlbjEgPCBhbW91bnQgewoJCXJldHVybiAwLCB1Zm10LkVycm9yZigKCQkJIiV2LiBjYW5ub3QgZGVjcmVhc2UsIHRva2VuMSglZCkgLSBhbW91bnQoJWQpIiwKCQkJZXJyQmFsYW5jZVVwZGF0ZUZhaWxlZCwgdG9rZW4xLCBhbW91bnQsCgkJKQoJfQoJcmV0dXJuIGduc21hdGguU2FmZVN1YkludDY0KHRva2VuMSwgYW1vdW50KSwgbmlsCn0KGuk0Cgh0eXBlLmdubxLcNHBhY2thZ2UgcG9vbAoKaW1wb3J0ICgKCSJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCWkyNTYgImduby5sYW5kL3AvZ25vc3dhcC9pbnQyNTYvdjEiCgl1MjU2ICJnbm8ubGFuZC9wL2dub3N3YXAvdWludDI1Ni92MSIKCglwbCAiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiCikKCi8vIE1vZGlmeVBvc2l0aW9uUGFyYW1zIHJlcGVyc2VudHMgdGhlIHBhcmFtZXRlcnMgZm9yIG1vZGlmeWluZyBhIGxpcXVpZGl0eSBwb3NpdGlvbi4KLy8gVGhpcyBzdHJ1Y3R1cmUgaXMgdXNlZCBpbnRlcm5hbGx5IGJvdGggYE1pbnRgIGFuZCBgQnVybmAgb3BlcmF0aW9uIHRvIG1hbmFnZQovLyB0aGUgbGlxdWlkaXR5IHBvc2l0aW9ucy4KdHlwZSBNb2RpZnlQb3NpdGlvblBhcmFtcyBzdHJ1Y3QgewoJLy8gb3duZXIgaXMgdGhlIGFkZHJlc3MgdGhhdCBvd25zIHRoZSBwb3NpdGlvbgoJb3duZXIgYWRkcmVzcwoKCS8vIHRpY2tMb3dlciBhbmQgYXRpY2tVcHBlciBkZWZpbmUgdGhlIHByaWNlIHJhbmdlCgkvLyBUaGUgYWN0dWFsIHByaWNlIHJhbmdlIGlzIGNhbGN1bGF0ZWQgYXMgMS4wMDAxXnRpY2sKCS8vIFRoaXMgYWxsb3dzIGZvciBwcmVjaXNpb24gaW4gcHJpY2UgcmFuZ2Ugd2hpbGUgdXNpbmcgaW50ZWdlciBtYXRoLgoKCXRpY2tMb3dlciBpbnQzMiAvLyBsb3dlciB0aWNrIG9mIHRoZSBwb3NpdGlvbgoJdGlja1VwcGVyIGludDMyIC8vIHVwcGVyIHRpY2sgb2YgdGhlIHBvc2l0aW9uCgoJLy8gbGlxdWlkaXR5RGVsdGEgcmVwcmVzZW50cyB0aGUgY2hhbmdlIGluIGxpcXVpZGl0eQoJLy8gUG9zaXRpdmUgZm9yIG1pbnRpbmcsIG5lZ2F0aXZlIGZvciBidXJuaW5nCglsaXF1aWRpdHlEZWx0YSAqaTI1Ni5JbnQKfQoKLy8gbmV3TW9kaWZ5UG9zaXRpb25QYXJhbXMgY3JlYXRlcyBhIG5ldyBgTW9kaWZ5UG9zaXRpb25QYXJhbXNgIGluc3RhbmNlLgovLyBUaGlzIGlzIHVzZWQgdG8gcHJlYXJlIHBhcmFtZXRlcnMgZm9yIHRoZSBgbW9kaWZ5UG9zaXRpb25gIGZ1bmN0aW9uLAovLyB3aGljaCBoYW5kbGVzIGJvdGggbWludGluZyBhbmQgYnVybmluZyBvZiBsaXF1aWRpdHkgcG9zaXRpb25zLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gb3duZXI6IGFkZHJlc3MgdGhhdCB3aWxsIG93biAob3Igb3ducykgdGhlIHBvc2l0aW9uCi8vICAgLSB0aWNrTG93ZXI6IGxvd2VyIHRpY2sgYm91bmQgb2YgdGhlIHBvc2l0aW9uCi8vICAgLSB0aWNrVXBwZXI6IHVwcGVyIHRpY2sgYm91bmQgb2YgdGhlIHBvc2l0aW9uCi8vICAgLSBsaXF1aWRpdHlEZWx0YTogYW1vdW50IG9mIGxpcXVpZGl0eSB0byBhZGQgKHBvc2l0aXZlKSBvciByZW1vdmUgKG5lZ2F0aXZlKQovLwovLyBUaGUgdGljayBwYXJhbWV0ZXJzIHJlcHJlc2VudCBwcmljZXMgYXMgcG93ZXJzIG9mIDEuMDAwMToKLy8gLSBhY3R1YWxfcHJpY2UgPSAxLjAwMDFedGljawovLyAtIEZvciBleGFtcGxlLCB0aWNrID0gMTAwIG1lYW5zIHByaWNlID0gMS4wMDAxXjEwMAovLwovLyBSZXR1cm5zOgovLyAgIC0gTW9kaWZ5UG9zaXRpb25QYXJhbXM6IGEgbmV3IGluc3RhbmNlIG9mIE1vZGlmeVBvc2l0aW9uUGFyYW1zCmZ1bmMgbmV3TW9kaWZ5UG9zaXRpb25QYXJhbXMoCglvd25lciBhZGRyZXNzLAoJdGlja0xvd2VyIGludDMyLAoJdGlja1VwcGVyIGludDMyLAoJbGlxdWlkaXR5RGVsdGEgKmkyNTYuSW50LAopIE1vZGlmeVBvc2l0aW9uUGFyYW1zIHsKCXJldHVybiBNb2RpZnlQb3NpdGlvblBhcmFtc3sKCQlvd25lcjogICAgICAgICAgb3duZXIsCgkJdGlja0xvd2VyOiAgICAgIHRpY2tMb3dlciwKCQl0aWNrVXBwZXI6ICAgICAgdGlja1VwcGVyLAoJCWxpcXVpZGl0eURlbHRhOiBsaXF1aWRpdHlEZWx0YSwKCX0KfQoKLy8gU3dhcENhY2hlIGhvbGRzIGltbXV0YWJsZSBzd2FwLXN0YXJ0IGlucHV0cyBhbmQgb3JhY2xlIGN1bXVsYXRpdmVzIHRoYXQgYXJlCi8vIHBvcHVsYXRlZCBsYXppbHkgd2hlbiB0aGUgc3dhcCBmaXJzdCBjcm9zc2VzIGFuIGluaXRpYWxpemVkIHRpY2suCnR5cGUgU3dhcENhY2hlIHN0cnVjdCB7CglmZWVQcm90b2NvbCAgICAgICAgICAgICAgICAgICAgICAgdWludDggICAgICAvLyBwcm90b2NvbCBmZWUgZm9yIHRoZSBpbnB1dCB0b2tlbgoJbGlxdWlkaXR5U3RhcnQgICAgICAgICAgICAgICAgICAgICp1MjU2LlVpbnQgLy8gbGlxdWlkaXR5IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN3YXAKCWJsb2NrVGltZXN0YW1wICAgICAgICAgICAgICAgICAgICBpbnQ2NCAgICAgIC8vIGN1cnJlbnQgYmxvY2sgdGltZXN0YW1wCgl0aWNrQ3VtdWxhdGl2ZSAgICAgICAgICAgICAgICAgICAgaW50NjQgICAgICAvLyBjdXJyZW50IHRpY2sgYWNjdW11bGF0b3IgdmFsdWUKCXNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCAqdTI1Ni5VaW50IC8vIGN1cnJlbnQgc2Vjb25kcyBwZXIgbGlxdWlkaXR5IGFjY3VtdWxhdG9yCgljb21wdXRlZExhdGVzdE9ic2VydmF0aW9uICAgICAgICAgYm9vbCAgICAgICAvLyB3aGV0aGVyIHdlJ3ZlIGNvbXB1dGVkIHRoZSBhYm92ZSBhY2N1bXVsYXRvcnMKCXNsb3QwU3RhcnQgICAgICAgICAgICAgICAgICAgICAgICBwbC5TbG90MCAgIC8vIGltbXV0YWJsZSBTbG90MCBzbmFwc2hvdCBjYXB0dXJlZCBhdCBzd2FwIHN0YXJ0CglyZWFkT25seSAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCAgICAgICAvLyBxdW90ZSB3aXRob3V0IHRpY2sgYWNjb3VudGluZyBvciBob29rcwp9CgpmdW5jIG5ld1N3YXBDYWNoZSgKCWZlZVByb3RvY29sIHVpbnQ4LAoJbGlxdWlkaXR5U3RhcnQgKnUyNTYuVWludCwKCWJsb2NrVGltZXN0YW1wIGludDY0LAoJc2xvdDBTdGFydCBwbC5TbG90MCwKKSAqU3dhcENhY2hlIHsKCXJldHVybiAmU3dhcENhY2hlewoJCWZlZVByb3RvY29sOiAgICAgICAgICAgICAgICAgICAgICAgZmVlUHJvdG9jb2wsCgkJbGlxdWlkaXR5U3RhcnQ6ICAgICAgICAgICAgICAgICAgICBsaXF1aWRpdHlTdGFydCwKCQlibG9ja1RpbWVzdGFtcDogICAgICAgICAgICAgICAgICAgIGJsb2NrVGltZXN0YW1wLAoJCXRpY2tDdW11bGF0aXZlOiAgICAgICAgICAgICAgICAgICAgMCwKCQlzZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjg6IHUyNTYuWmVybygpLAoJCWNvbXB1dGVkTGF0ZXN0T2JzZXJ2YXRpb246ICAgICAgICAgZmFsc2UsCgkJc2xvdDBTdGFydDogICAgICAgICAgICAgICAgICAgICAgICBzbG90MFN0YXJ0LkNsb25lKCksCgl9Cn0KCi8vIFN3YXBTdGF0ZSB0cmFja3MgdGhlIGNoYW5naW5nIHZhbHVlcyBkdXJpbmcgYSBzd2FwLgovLyBUaGlzIHR5cGUgaGVscHMgbWFuYWdlIHRoZSBzdGF0ZSB0cmFuc2l0aW9ucyB0aGF0IG9jY3VyIGFzIHRoZSBzd2FwIHByb2dyZXNzZXMKLy8gYWNyb3NzIGRpZmZlcmVudCBwcmljZSByYW5nZXMuCnR5cGUgU3dhcFN0YXRlIHN0cnVjdCB7CglhbW91bnRTcGVjaWZpZWRSZW1haW5pbmcgKmkyNTYuSW50ICAvLyBhbW91bnQgcmVtYWluaW5nIHRvIGJlIHN3YXBwZWQgaW4vb3V0IG9mIHRoZSBpbnB1dC9vdXRwdXQgdG9rZW4KCWFtb3VudENhbGN1bGF0ZWQgICAgICAgICAqaTI1Ni5JbnQgIC8vIGFtb3VudCBhbHJlYWR5IHN3YXBwZWQgb3V0L2luIG9mIHRoZSBvdXRwdXQvaW5wdXQgdG9rZW4KCXNxcnRQcmljZVg5NiAgICAgICAgICAgICAqdTI1Ni5VaW50IC8vIGN1cnJlbnQgc3FydChwcmljZSkKCXRpY2sgICAgICAgICAgICAgICAgICAgICBpbnQzMiAgICAgIC8vIHRpY2sgYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXJyZW50IHNxcnQocHJpY2UpCglmZWVHcm93dGhHbG9iYWxYMTI4ICAgICAgKnUyNTYuVWludCAvLyBnbG9iYWwgZmVlIGdyb3d0aCBvZiB0aGUgaW5wdXQgdG9rZW4KCXByb3RvY29sRmVlICAgICAgICAgICAgICAqdTI1Ni5VaW50IC8vIGFtb3VudCBvZiBpbnB1dCB0b2tlbiBwYWlkIGFzIHByb3RvY29sIGZlZQoJbGlxdWlkaXR5ICAgICAgICAgICAgICAgICp1MjU2LlVpbnQgLy8gY3VycmVudCBsaXF1aWRpdHkgaW4gcmFuZ2UKfQoKZnVuYyBuZXdTd2FwU3RhdGUoCglhbW91bnRTcGVjaWZpZWRSZW1haW5pbmcgKmkyNTYuSW50LAoJZmVlR3Jvd3RoR2xvYmFsWDEyOCAqdTI1Ni5VaW50LAoJbGlxdWlkaXR5ICp1MjU2LlVpbnQsCglzbG90MCBwbC5TbG90MCwKKSBTd2FwU3RhdGUgewoJcmV0dXJuIFN3YXBTdGF0ZXsKCQlhbW91bnRTcGVjaWZpZWRSZW1haW5pbmc6IGFtb3VudFNwZWNpZmllZFJlbWFpbmluZywKCQlhbW91bnRDYWxjdWxhdGVkOiAgICAgICAgIGkyNTYuWmVybygpLAoJCXNxcnRQcmljZVg5NjogICAgICAgICAgICAgc2xvdDAuU3FydFByaWNlWDk2KCksCgkJdGljazogICAgICAgICAgICAgICAgICAgICBzbG90MC5UaWNrKCksCgkJZmVlR3Jvd3RoR2xvYmFsWDEyODogICAgICBmZWVHcm93dGhHbG9iYWxYMTI4LAoJCXByb3RvY29sRmVlOiAgICAgICAgICAgICAgdTI1Ni5aZXJvKCksCgkJbGlxdWlkaXR5OiAgICAgICAgICAgICAgICBsaXF1aWRpdHksCgl9Cn0KCmZ1bmMgKHMgKlN3YXBTdGF0ZSkgc2V0U3FydFByaWNlWDk2KHNxcnRQcmljZVg5NiAqdTI1Ni5VaW50KSB7CglzLnNxcnRQcmljZVg5NiA9IHNxcnRQcmljZVg5Ni5DbG9uZSgpCn0KCmZ1bmMgKHMgKlN3YXBTdGF0ZSkgc2V0VGljayh0aWNrIGludDMyKSB7CglzLnRpY2sgPSB0aWNrCn0KCmZ1bmMgKHMgKlN3YXBTdGF0ZSkgc2V0RmVlR3Jvd3RoR2xvYmFsWDEyOChmZWVHcm93dGhHbG9iYWxYMTI4ICp1MjU2LlVpbnQpIHsKCXMuZmVlR3Jvd3RoR2xvYmFsWDEyOCA9IGZlZUdyb3d0aEdsb2JhbFgxMjgKfQoKZnVuYyAocyAqU3dhcFN0YXRlKSBzZXRQcm90b2NvbEZlZShmZWUgKnUyNTYuVWludCkgewoJcy5wcm90b2NvbEZlZSA9IGZlZQp9CgovLyBTdGVwQ29tcHV0YXRpb25zIGhvbGRzIGludGVybWVkaWF0ZSB2YWx1ZXMgdXNlZCBkdXJpbmcgYSBzaW5nbGUgc3RlcCBvZiBhIHN3YXAuCi8vIEVhY2ggc3RlcCByZXByZXNlbnRzIG1vdmVtZW50IGZyb20gdGhlIGN1cnJlbnQgdGljayB0byB0aGUgbmV4dCBpbml0aWFsaXplZCB0aWNrCi8vIG9yIHRoZSB0YXJnZXQgcHJpY2UsIHdoaWNoZXZlciBjb21lcyBmaXJzdC4KdHlwZSBTdGVwQ29tcHV0YXRpb25zIHN0cnVjdCB7CglzcXJ0UHJpY2VTdGFydFg5NiAqdTI1Ni5VaW50IC8vIHByaWNlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0ZXAKCXRpY2tOZXh0ICAgICAgICAgIGludDMyICAgICAgLy8gbmV4dCB0aWNrIHRvIHN3YXAgdG8gZnJvbSB0aGUgY3VycmVudCB0aWNrIGluIHRoZSBzd2FwIGRpcmVjdGlvbgoJaW5pdGlhbGl6ZWQgICAgICAgYm9vbCAgICAgICAvLyB3aGV0aGVyIHRpY2tOZXh0IGlzIGluaXRpYWxpemVkCglzcXJ0UHJpY2VOZXh0WDk2ICAqdTI1Ni5VaW50IC8vIHNxcnQocHJpY2UpIGZvciB0aGUgbmV4dCB0aWNrICh0b2tlbjEvdG9rZW4wKSBROTYKCWFtb3VudEluICAgICAgICAgICp1MjU2LlVpbnQgLy8gaG93IG11Y2ggYmVpbmcgc3dhcHBlZCBpbiB0aGlzIHN0ZXAKCWFtb3VudE91dCAgICAgICAgICp1MjU2LlVpbnQgLy8gaG93IG11Y2ggaXMgYmVpbmcgc3dhcHBlZCBvdXQgaW4gdGhpcyBzdGVwCglmZWVBbW91bnQgICAgICAgICAqdTI1Ni5VaW50IC8vIGhvdyBtdWNoIGZlZSBpcyBiZWluZyBwYWlkIGluIHRoaXMgc3RlcAp9CgovLyBpbml0IGluaXRpYWxpemVzIHRoZSBjb21wdXRhdGlvbiBmb3IgYSBzaW5nbGUgc3dhcCBzdGVwCmZ1bmMgKHN0ZXAgKlN0ZXBDb21wdXRhdGlvbnMpIGluaXRTd2FwU3RlcChzdGF0ZSBTd2FwU3RhdGUsIHAgKnBsLlBvb2wsIHplcm9Gb3JPbmUgYm9vbCkgewoJc3RlcC5zcXJ0UHJpY2VTdGFydFg5NiA9IHN0YXRlLnNxcnRQcmljZVg5NgoJc3RlcC50aWNrTmV4dCwgc3RlcC5pbml0aWFsaXplZCA9IHRpY2tCaXRtYXBOZXh0SW5pdGlhbGl6ZWRUaWNrV2l0aEluT25lV29yZCgKCQlwLAoJCXN0YXRlLnRpY2ssCgkJcC5UaWNrU3BhY2luZygpLAoJCXplcm9Gb3JPbmUsCgkpCgoJLy8gcHJldmVudCBvdmVyc2hvb3QgdGhlIG1pbi9tYXggdGljawoJc3RlcC5jbGFtcFRpY2tOZXh0KCkKCgkvLyBnZXQgdGhlIHByaWNlIGZvciB0aGUgbmV4dCB0aWNrCglzdGVwLnNxcnRQcmljZU5leHRYOTYgPSBnbnNtYXRoLlRpY2tNYXRoR2V0U3FydFJhdGlvQXRUaWNrKHN0ZXAudGlja05leHQpCn0KCi8vIGNsYW1wVGlja05leHQgZW5zdXJlcyB0aGF0IGB0aWNrTmV4dGAgc3RheXMgd2l0aGluIHRoZSBtaW4sIG1heCB0aWNrIGJvdW5kYXJpZXMKLy8gYXMgdGhlIHRpY2sgYml0bWFwIGlzIG5vdCBhd2FyZSBvZiB0aGVzZSBib3VuZHMKZnVuYyAoc3RlcCAqU3RlcENvbXB1dGF0aW9ucykgY2xhbXBUaWNrTmV4dCgpIHsKCWlmIHN0ZXAudGlja05leHQgPCBNSU5fVElDSyB7CgkJc3RlcC50aWNrTmV4dCA9IE1JTl9USUNLCgl9IGVsc2UgaWYgc3RlcC50aWNrTmV4dCA+IE1BWF9USUNLIHsKCQlzdGVwLnRpY2tOZXh0ID0gTUFYX1RJQ0sKCX0KfQoKZnVuYyBuZXdQb29sKHBvb2xJbmZvICpwb29sQ3JlYXRlQ29uZmlnKSAqcGwuUG9vbCB7Cgl0aWNrIDo9IGduc21hdGguVGlja01hdGhHZXRUaWNrQXRTcXJ0UmF0aW8ocG9vbEluZm8uU3FydFByaWNlWDk2KCkpCgoJcmV0dXJuIHBsLk5ld1Bvb2woCgkJcG9vbEluZm8uVG9rZW4wUGF0aCgpLAoJCXBvb2xJbmZvLlRva2VuMVBhdGgoKSwKCQlwb29sSW5mby5GZWUoKSwKCQlwb29sSW5mby5TcXJ0UHJpY2VYOTYoKSwKCQlwb29sSW5mby5UaWNrU3BhY2luZygpLAoJCXRpY2ssCgkJcG9vbEluZm8uc2xvdDBGZWVQcm90b2NvbCwKCSkKfQoaux8KCXV0aWxzLmdubxKtH3BhY2thZ2UgcG9vbAoKaW1wb3J0ICgKCWkyNTYgImduby5sYW5kL3AvZ25vc3dhcC9pbnQyNTYvdjEiCgl1MjU2ICJnbm8ubGFuZC9wL2dub3N3YXAvdWludDI1Ni92MSIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKKQoKY29uc3QgKAoJTUFYX1VJTlQ2NCAgc3RyaW5nID0gIjE4NDQ2NzQ0MDczNzA5NTUxNjE1IgoJTUFYX0lOVDY0ICAgc3RyaW5nID0gIjkyMjMzNzIwMzY4NTQ3NzU4MDciCglNQVhfSU5UMTI4ICBzdHJpbmcgPSAiMTcwMTQxMTgzNDYwNDY5MjMxNzMxNjg3MzAzNzE1ODg0MTA1NzI3IgoJTUlOX0lOVDEyOCAgc3RyaW5nID0gIi0xNzAxNDExODM0NjA0NjkyMzE3MzE2ODczMDM3MTU4ODQxMDU3MjgiCglNQVhfVUlOVDEyOCBzdHJpbmcgPSAiMzQwMjgyMzY2OTIwOTM4NDYzNDYzMzc0NjA3NDMxNzY4MjExNDU1IgoJTUFYX0lOVDI1NiAgc3RyaW5nID0gIjU3ODk2MDQ0NjE4NjU4MDk3NzExNzg1NDkyNTA0MzQzOTUzOTI2NjM0OTkyMzMyODIwMjgyMDE5NzI4NzkyMDAzOTU2NTY0ODE5OTY3IgoKCUlOVDY0X01JTiBpbnQ2NCA9IC05MjIzMzcyMDM2ODU0Nzc1ODA4CglJTlQ2NF9NQVggaW50NjQgPSA5MjIzMzcyMDM2ODU0Nzc1ODA3CgoJUTk2X1JFU09MVVRJT04gIHVpbnQgPSA5NgoJUTEyOF9SRVNPTFVUSU9OIHVpbnQgPSAxMjgKCglRNjQgIHN0cmluZyA9ICIxODQ0Njc0NDA3MzcwOTU1MTYxNiIgICAgICAgICAgICAgICAgICAgIC8vIDIgKiogNjQKCVE5NiAgc3RyaW5nID0gIjc5MjI4MTYyNTE0MjY0MzM3NTkzNTQzOTUwMzM2IiAgICAgICAgICAgLy8gMiAqKiA5NgoJUTEyOCBzdHJpbmcgPSAiMzQwMjgyMzY2OTIwOTM4NDYzNDYzMzc0NjA3NDMxNzY4MjExNDU2IiAvLyAyICoqIDEyOAopCgp2YXIgKAoJbWF4SW50MTI4RnJvbURlY2ltYWwgID0gaTI1Ni5NdXN0RnJvbURlY2ltYWwoTUFYX0lOVDEyOCkKCW1pbkludDEyOEZyb21EZWNpbWFsICA9IGkyNTYuTXVzdEZyb21EZWNpbWFsKE1JTl9JTlQxMjgpCgltYXhVaW50MTI4RnJvbURlY2ltYWwgPSB1MjU2Lk11c3RGcm9tRGVjaW1hbChNQVhfVUlOVDEyOCkKCXExMjhGcm9tRGVjaW1hbCAgICAgICA9IHUyNTYuTXVzdEZyb21EZWNpbWFsKFExMjgpCikKCnZhciB1aW50MTI4TWFzayA9IGZ1bmMoKSAqdTI1Ni5VaW50IHsKCW0gOj0gdTI1Ni5aZXJvKCkuTHNoKHUyNTYuT25lKCksIFExMjhfUkVTT0xVVElPTikKCXJldHVybiBtLlN1YihtLCB1MjU2Lk9uZSgpKQp9KCkKCi8vIHRvVWludDEyOCBlbnN1cmVzIGEgKnUyNTYuVWludCB2YWx1ZSBmaXRzIHdpdGhpbiB0aGUgdWludDEyOCByYW5nZS4KLy8KLy8gVGhpcyBmdW5jdGlvbiB2YWxpZGF0ZXMgdGhhdCB0aGUgZ2l2ZW4gYHZhbHVlYCBpcyBwcm9wZXJseSBpbml0aWFsaXplZCBhbmQgY2hlY2tzIHdoZXRoZXIKLy8gaXQgZXhjZWVkcyB0aGUgbWF4aW11bSB2YWx1ZSBvZiB1aW50MTI4LiBJZiB0aGUgdmFsdWUgZXhjZWVkcyB0aGUgdWludDEyOCByYW5nZSwKLy8gaXQgYXBwbGllcyBhIG1hc2tpbmcgb3BlcmF0aW9uIHRvIHRydW5jYXRlIHRoZSB2YWx1ZSB0byBmaXQgd2l0aGluIHRoZSB1aW50MTI4IGxpbWl0LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gdmFsdWU6ICp1MjU2LlVpbnQsIHRoZSB2YWx1ZSB0byBiZSBjaGVja2VkIGFuZCBwb3NzaWJseSB0cnVuY2F0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqdTI1Ni5VaW50OiBBIHZhbHVlIGd1YXJhbnRlZWQgdG8gZml0IHdpdGhpbiB0aGUgdWludDEyOCByYW5nZS4KLy8KLy8gTm90ZXM6Ci8vICAgLSBUaGUgZnVuY3Rpb24gZmlyc3QgY2hlY2tzIGlmIHRoZSB2YWx1ZSBpcyBub3QgbmlsIHRvIGF2b2lkIHBvdGVudGlhbCBydW50aW1lIGVycm9ycy4KLy8gICAtIFRoZSBtYXNrIGVuc3VyZXMgdGhhdCBvbmx5IHRoZSBsb3dlciAxMjggYml0cyBvZiB0aGUgdmFsdWUgYXJlIHJldGFpbmVkLgovLyAgIC0gSWYgdGhlIGlucHV0IHZhbHVlIGlzIGFscmVhZHkgd2l0aGluIHRoZSB1aW50MTI4IHJhbmdlLCBpdCBpcyByZXR1cm5lZCB1bmNoYW5nZWQuCi8vICAgLSBJZiBtYXNraW5nIGlzIHJlcXVpcmVkLCBhIG5ldyBpbnN0YW5jZSBpcyByZXR1cm5lZCB3aXRob3V0IG1vZGlmeWluZyB0aGUgaW5wdXQuCi8vICAgLSBNQVhfVUlOVDEyOCBpcyBhIGNvbnN0YW50IHJlcHJlc2VudGluZyBgMl4xMjggLSAxYC4KZnVuYyB0b1VpbnQxMjgodmFsdWUgKnUyNTYuVWludCkgKnUyNTYuVWludCB7CglpZiB2YWx1ZSA9PSBuaWwgewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbChlcnJJbnZhbGlkSW5wdXQsICJ2YWx1ZSBpcyBuaWwiKSkKCX0KCglpZiB2YWx1ZS5HdChtYXhVaW50MTI4RnJvbURlY2ltYWwpIHsKCQlyZXR1cm4gdTI1Ni5aZXJvKCkuQW5kKHZhbHVlLCB1aW50MTI4TWFzaykKCX0KCXJldHVybiB2YWx1ZQp9CgovLyB1MjU2TWluIHJldHVybnMgdGhlIHNtYWxsZXIgb2YgdHdvICp1MjU2LlVpbnQgdmFsdWVzLgovLwovLyBUaGlzIGZ1bmN0aW9uIGNvbXBhcmVzIHR3byB1bnNpZ25lZCAyNTYtYml0IGludGVnZXJzIGFuZCByZXR1cm5zIHRoZSBzbWFsbGVyIG9mIHRoZSB0d28uCi8vIElmIGBudW0xYCBpcyBsZXNzIHRoYW4gYG51bTJgLCBpdCByZXR1cm5zIGBudW0xYDsgb3RoZXJ3aXNlLCBpdCByZXR1cm5zIGBudW0yYC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gLSBudW0xICgqdTI1Ni5VaW50KTogVGhlIGZpcnN0IHVuc2lnbmVkIDI1Ni1iaXQgaW50ZWdlci4KLy8gLSBudW0yICgqdTI1Ni5VaW50KTogVGhlIHNlY29uZCB1bnNpZ25lZCAyNTYtYml0IGludGVnZXIuCi8vCi8vIFJldHVybnM6Ci8vIC0gKnUyNTYuVWludDogVGhlIHNtYWxsZXIgb2YgYG51bTFgIGFuZCBgbnVtMmAuCi8vCi8vIE5vdGVzOgovLyAgIC0gVGhpcyBmdW5jdGlvbiB1c2VzIHRoZSBgTHRgIChsZXNzIHRoYW4pIG1ldGhvZCBvZiBgKnUyNTYuVWludGAgdG8gcGVyZm9ybSB0aGUgY29tcGFyaXNvbi4KLy8gICAtIFRoZSBmdW5jdGlvbiBhc3N1bWVzIGJvdGggaW5wdXQgdmFsdWVzIGFyZSBub24tbmlsLiBJZiBuaWwgaW5wdXRzIGFyZSBwb3NzaWJsZSBpbiB0aGUgdXNhZ2UgY29udGV4dCwKLy8gICAgIGFkZGl0aW9uYWwgdmFsaWRhdGlvbiBtYXkgYmUgbmVlZGVkLgovLwovLyBFeGFtcGxlOgovLyBzbWFsbGVyIDo9IHUyNTZNaW4odTI1Ni5NdXN0RnJvbURlY2ltYWwoIjEwIiksIHUyNTYuTXVzdEZyb21EZWNpbWFsKCIyMCIpKSAvLyBSZXR1cm5zIDEwCi8vIHNtYWxsZXIgOj0gdTI1Nk1pbih1MjU2Lk11c3RGcm9tRGVjaW1hbCgiMzAiKSwgdTI1Ni5NdXN0RnJvbURlY2ltYWwoIjIwIikpIC8vIFJldHVybnMgMjAKZnVuYyB1MjU2TWluKG51bTEsIG51bTIgKnUyNTYuVWludCkgKnUyNTYuVWludCB7CglpZiBudW0xLkx0KG51bTIpIHsKCQlyZXR1cm4gbnVtMQoJfQoJcmV0dXJuIG51bTIKfQoKLy8gY2hlY2tPdmVyRmxvd0ludDEyOCBjaGVja3MgaWYgdGhlIHZhbHVlIG92ZXJmbG93cyB0aGUgaW50MTI4IHJhbmdlLgpmdW5jIGNoZWNrT3ZlckZsb3dJbnQxMjgodmFsdWUgKmkyNTYuSW50KSB7CglpZiB2YWx1ZS5HdChtYXhJbnQxMjhGcm9tRGVjaW1hbCkgfHwgdmFsdWUuTHQobWluSW50MTI4RnJvbURlY2ltYWwpIHsKCQlwYW5pYyh1Zm10LlNwcmludGYoCgkJCSIldjogYW1vdW50KCVzKSBvdmVyZmxvd3MgaW50MTI4IHJhbmdlIiwKCQkJZXJyT3ZlcmZsb3csIHZhbHVlLlRvU3RyaW5nKCksCgkJKSkKCX0KfQoKLy8gY2hlY2tUaWNrU3BhY2luZyBjaGVja3MgaWYgdGhlIHRpY2sgaXMgZGl2aXNpYmxlIGJ5IHRoZSB0aWNrU3BhY2luZy4KZnVuYyBjaGVja1RpY2tTcGFjaW5nKHRpY2ssIHRpY2tTcGFjaW5nIGludDMyKSB7CglpZiB0aWNrJXRpY2tTcGFjaW5nICE9IDAgewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbCgKCQkJZXJySW52YWxpZFRpY2tBbmRUaWNrU3BhY2luZywKCQkJdWZtdC5TcHJpbnRmKCJ0aWNrKCVkKSBNT0QgdGlja1NwYWNpbmcoJWQpICE9IDAoJWQpIiwgdGljaywgdGlja1NwYWNpbmcsIHRpY2sldGlja1NwYWNpbmcpLAoJCSkpCgl9Cn0KIiIKEy9nbm8uTWVtUGFja2FnZVR5cGUSCwoJTVBVc2VyQWxsEhMIzrDNmAISCzI5NDIzNnVnbm90GqgBCjoKEy90bS5QdWJLZXlTZWNwMjU2azESIwohAwSc1QTD4tI6os8LnebKOB+i6fWXOKGBf9lRpSI1wrrhEkBUSq7ARnpMKTP4fie9udZ+qulrZLQawHfB4sx/+DidmUC4OAziDQ3T5OoUVvRWLPs59n+Hbni27f/jRG4e/w0UGihnMXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcWx1dXhl

Raw transaction data

Raw JSON data