LyoKICogQ29weXJpZ2h0IDIwMDEsIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IDIwMDIgR3JlZyBUdXJuZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqCiAqIC0tLS0gcnBjc3NfbWFpbi5jOgogKiAgIEluaXRpYWxpemUgYW5kIHN0YXJ0IHNlcnZpbmcgcmVxdWVzdHMuICBCYWlsIGlmIHJwY3NzIGFscmVhZHkgaXMKICogICBydW5uaW5nLgogKgogKiAtLS0tIFJQQ1NTLkVYRToKICogICAKICogICBXaW5lIG5lZWRzIGEgc2VydmVyIHdob3NlIHJvbGUgaXMgc29tZXdoYXQgbGlrZSB0aGF0CiAqICAgb2YgcnBjc3MuZXhlIGluIHdpbmRvd3MuICBUaGlzIGlzIG5vdCBhIGNsb25lIG9mCiAqICAgd2luZG93cyBycGNzcyBhdCBhbGwuICBJdCBoYXMgYmVlbiBnaXZlbiB0aGUgc2FtZSBuYW1lLCBob3dldmVyLAogKiAgIHRvIHByb3ZpZGUgZm9yIHRoZSBwb3NzaWJpbGl0eSB0aGF0IGF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHVyZSwgCiAqICAgaXQgbWF5IGJlY29tZSBpbnRlcmZhY2UgY29tcGF0aWJsZSB3aXRoIHRoZSAicmVhbCIgcnBjc3MuZXhlIG9uCiAqICAgV2luZG93cy4KICoKICogLS0tLSBLTk9XTiBCVUdTIC8gVE9ETzoKICoKICogICBvIFNlcnZpY2UgaG9va3MgYXJlIHVuaW1wbGVtZW50ZWQgKGlmIHlvdSBib3RoZXIgdG8gaW1wbGVtZW50CiAqICAgICB0aGVzZSwgYWxzbyBpbXBsZW1lbnQgbmV0LmV4ZSwgYXQgbGVhc3QgZm9yICJuZXQgc3RhcnQiIGFuZAogKiAgICAgIm5ldCBzdG9wIiAoc2hvdWxkIGJlIHByZXR0eSBlYXN5IEkgZ3Vlc3MsIGFzc3VtaW5nIHRoZSByZXN0CiAqICAgICBvZiB0aGUgc2VydmljZXMgQVBJIGluZnJhc3RydWN0dXJlIHdvcmtzLgogKiAKICogICBvIElzIHN1cHBvc2VkIHRvIHVzZSBSUEMsIG5vdCByYW5kb20ga2x1ZGdlcywgdG8gbWFwIGVuZHBvaW50cy4KICoKICogICBvIFByb2JhYmx5IG5hbWUgc2VydmljZXMgc2hvdWxkIGJlIGltcGxlbWVudGVkIGhlcmUgYXMgd2VsbC4KICoKICogICBvIFdpbmUncyBuYW1lZCBwaXBlcyAoaW4gZ2VuZXJhbCkgbWF5IG5vdCBpbnRlcm9wZXJhdGUgd2l0aCB0aG9zZSBvZiAKICogICAgIFdpbmRvd3MgeWV0ICg/KQogKgogKiAgIG8gVGhlcmUgaXMgYSBsb29taW5nIHByb2JsZW0gcmVnYXJkaW5nIGxpc3RlbmluZyBvbiBwcml2aWxlZ2VkCiAqICAgICBwb3J0cy4gIFdlIHdpbGwgbmVlZCB0byBiZSBhYmxlIHRvIGNvZXhpc3Qgd2l0aCBTQU1CQSwgYW5kIGJlIGFibGUKICogICAgIHRvIGZ1bmN0aW9uIHdpdGhvdXQgcnVubmluZyB3aW5lbGliIGNvZGUgYXMgcm9vdC4gIFRoaXMgbWF5CiAqICAgICB0YWtlIHNvbWUgZG9pbmcsIGluY2x1ZGluZyBzaWduaWZpY2FudCByZWNvbmNlcHR1YWxpemF0aW9uIG9mIHRoZQogKiAgICAgcm9sZSBvZiBycGNzcy5leGUgaW4gd2luZS4KICoKICogICBvIFdobyBrbm93cz8gIFdoYXRldmVyIHJwY3NzIGRvZXMsIHdlIG91Z2h0IHRvIGF0CiAqICAgICBsZWFzdCB0aGluayBhYm91dCBkb2luZy4uLiBidXQgd2hhdCAvZG9lcy8gaXQgZG8/CiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxsaW1pdHMuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KI2RlZmluZSBOT05BTUVMRVNTU1RSVUNUCiNpbmNsdWRlICJycGNzcy5oIgojaW5jbHVkZSAid2lubnQuaCIKI2luY2x1ZGUgImlyb3QuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKc3RhdGljIEhBTkRMRSBtYXN0ZXJfbXV0ZXg7CnN0YXRpYyBIQU5ETEUgZXhpdF9ldmVudDsKCmV4dGVybiBIQU5ETEUgX193aW5lX21ha2VfcHJvY2Vzc19zeXN0ZW0odm9pZCk7CgpIQU5ETEUgUlBDU1NfR2V0TWFzdGVyTXV0ZXgodm9pZCkKewogIHJldHVybiBtYXN0ZXJfbXV0ZXg7Cn0KCnN0YXRpYyBCT09MIFJQQ1NTX3dvcmsoSEFORExFIGV4aXRfZXZlbnQpCnsKICByZXR1cm4gUlBDU1NfTlBEb1dvcmsoZXhpdF9ldmVudCk7Cn0KCnN0YXRpYyBCT09MIFJQQ1NTX0luaXRpYWxpemUodm9pZCkKewogIHN0YXRpYyB1bnNpZ25lZCBzaG9ydCBpcm90X3Byb3RzZXFbXSA9IElST1RfUFJPVFNFUTsKICBzdGF0aWMgdW5zaWduZWQgc2hvcnQgaXJvdF9lbmRwb2ludFtdID0gSVJPVF9FTkRQT0lOVDsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgV0lORV9UUkFDRSgiXG4iKTsKCiAgZXhpdF9ldmVudCA9IF9fd2luZV9tYWtlX3Byb2Nlc3Nfc3lzdGVtKCk7CgogIG1hc3Rlcl9tdXRleCA9IENyZWF0ZU11dGV4QSggTlVMTCwgRkFMU0UsIFJQQ1NTX01BU1RFUl9NVVRFWF9OQU1FKTsKICBpZiAoIW1hc3Rlcl9tdXRleCkgewogICAgV0lORV9FUlIoIkZhaWxlZCB0byBjcmVhdGUgbWFzdGVyIG11dGV4XG4iKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIGlmICghUlBDU1NfQmVjb21lUGlwZVNlcnZlcigpKSB7CiAgICBXSU5FX1dBUk4oIlNlcnZlciBhbHJlYWR5IHJ1bm5pbmc6IGV4aXRpbmcuXG4iKTsKCiAgICBDbG9zZUhhbmRsZShtYXN0ZXJfbXV0ZXgpOwogICAgbWFzdGVyX211dGV4ID0gTlVMTDsKCiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICBzdGF0dXMgPSBScGNTZXJ2ZXJVc2VQcm90c2VxRXBXKGlyb3RfcHJvdHNlcSwgUlBDX0NfUFJPVFNFUV9NQVhfUkVRU19ERUZBVUxULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXJvdF9lbmRwb2ludCwgTlVMTCk7CiAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgICAgc3RhdHVzID0gUnBjU2VydmVyUmVnaXN0ZXJJZihJcm90X3YwXzJfc19pZnNwZWMsIE5VTEwsIE5VTEwpOwogIGlmIChzdGF0dXMgPT0gUlBDX1NfT0spCiAgICAgIHN0YXR1cyA9IFJwY1NlcnZlckxpc3RlbigxLCBSUENfQ19MSVNURU5fTUFYX0NBTExTX0RFRkFVTFQsIFRSVUUpOwogIGVsc2UKICAgICAgUnBjU2VydmVyVW5yZWdpc3RlcklmKElyb3RfdjBfMl9zX2lmc3BlYywgTlVMTCwgRkFMU0UpOwoKICByZXR1cm4gc3RhdHVzID09IFJQQ19TX09LOwp9CgovKiByZXR1cm5zIGZhbHNlIGlmIHdlIGRpc2NvdmVyIGF0IHRoZSBsYXN0IG1vbWVudCB0aGF0IHdlCiAgIGFyZW4ndCByZWFkeSB0byB0ZXJtaW5hdGUgKi8Kc3RhdGljIEJPT0wgUlBDU1NfU2h1dGRvd24odm9pZCkKewogIGlmICghUlBDU1NfVW5CZWNvbWVQaXBlU2VydmVyKCkpCiAgICByZXR1cm4gRkFMU0U7CiAgIAogIGlmICghQ2xvc2VIYW5kbGUobWFzdGVyX211dGV4KSkKICAgIFdJTkVfV0FSTigiRmFpbGVkIHRvIHJlbGVhc2UgbWFzdGVyIG11dGV4XG4iKTsKCiAgbWFzdGVyX211dGV4ID0gTlVMTDsKCiAgUnBjTWdtdFN0b3BTZXJ2ZXJMaXN0ZW5pbmcoTlVMTCk7CiAgUnBjU2VydmVyVW5yZWdpc3RlcklmKElyb3RfdjBfMl9zX2lmc3BlYywgTlVMTCwgVFJVRSk7CgogIENsb3NlSGFuZGxlKGV4aXRfZXZlbnQpOwoKICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIHZvaWQgUlBDU1NfTWFpbkxvb3Aodm9pZCkKewogIFdJTkVfVFJBQ0UoIlxuIik7CgogIHdoaWxlICggUlBDU1Nfd29yayhleGl0X2V2ZW50KSApCiAgICAgIDsKfQoKaW50IG1haW4oIGludCBhcmdjLCBjaGFyICoqYXJndiApCnsKICAvKiAKICAgKiBXZSBhcmUgaW52b2tlZCBhcyBhIHN0YW5kYXJkIGV4ZWN1dGFibGU7IHdlIGFjdCBpbiBhCiAgICogImxhenkiIG1hbm5lci4gIFdlIG9wZW4gdXAgb3VyIHBpcGUsIGFuZCBoYW5nIGFyb3VuZCB1bnRpbCB3ZSBhbGwKICAgKiB1c2VyIHByb2Nlc3NlcyBleGl0LCBhbmQgdGhlbiBzaWxlbnRseSB0ZXJtaW5hdGUuCiAgICovCgogIGlmIChSUENTU19Jbml0aWFsaXplKCkpIHsKICAgIFJQQ1NTX01haW5Mb29wKCk7CiAgICBSUENTU19TaHV0ZG93bigpOwogIH0KCiAgcmV0dXJuIDA7Cn0K