Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBBdXRob3Iocyk6ICAgUm9iZXJ0IFdlaWRuZXIgKERTUCBTb2x1dGlvbnMpCiAgIERlc2NyaXB0aW9uOiBIQ1IgRGVjb2RlcjogUHJlcGFyZSBkZWNvZGluZyBvZiBub24tUENXcywgc2VnbWVudGF0aW9uLSBhbmQKICAgICAgICAgICAgICAgIGJpdGZpZWxkLWhhbmRsaW5nLCBIQ1ItU3RhdGVtYWNoaW5lCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgImFhY2RlY19oY3JzLmgiCgoKI2luY2x1ZGUgImFhY2RlY19oY3IuaCIKCiNpbmNsdWRlICJhYWNkZWNfaGNyX2JpdC5oIgojaW5jbHVkZSAiYWFjX3JvbS5oIgojaW5jbHVkZSAiYWFjX3JhbS5oIgoKCnN0YXRpYyBVSU5UIEluaXRTZWdtZW50Qml0ZmllbGQoVUlOVCAgICpwTnVtU2VnbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgKnBSZW1haW5pbmdCaXRzSW5TZWdtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAqcFNlZ21lbnRCaXRmaWVsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAgKnBOdW1Xb3JkRm9yQml0ZmllbGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVNIT1JUICpwTnVtQml0VmFsaWRJbkxhc3RXb3JkKTsKCnN0YXRpYyB2b2lkIEluaXROb25QQ1dTaWRlSW5mb3JtYXRpb25Gb3JDdXJyZW50U2V0KEhfSENSX0lORk8gcEhjcik7CgpzdGF0aWMgSU5UIE1vZHVsb1ZhbHVlKElOVCBpbnB1dCwgSU5UIGJ1ZmZlcmxlbmd0aCk7CgpzdGF0aWMgdm9pZCBDbGVhckJpdEZyb21CaXRmaWVsZChTVEFURUZVTkMgKnB0clN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UICAgb2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UICAqcEJpdGZpZWxkKTsKCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIGRlc2NyaXB0aW9uOiBUaGlzIGZ1bmN0aW9uIGRlY29kZXMgYWxsIG5vbi1wcmlvcml0eSBjb2Rld29yZHMgKG5vbi1QQ1dzKSBieSB1c2luZyBhCiAgICAgICAgICAgICAgICAgIHN0YXRlLW1hY2hpbmUuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCnZvaWQgIERlY29kZU5vblBDV3MoSEFORExFX0ZES19CSVRTVFJFQU0gYnMsIEhfSENSX0lORk8gcEhjcikKewogIFVJTlQgICAgbnVtVmFsaWRTZWdtZW50OwogIElOVCAgICAgc2VnbWVudE9mZnNldDsKICBJTlQgICAgIGNvZGV3b3JkT2Zmc2V0QmFzZTsKICBJTlQgICAgIGNvZGV3b3JkT2Zmc2V0OwogIFVJTlQgICAgdHJpYWw7CgogIFVJTlQgICAqcE51bVNlZ21lbnQ7CiAgU0NIQVIgICpwUmVtYWluaW5nQml0c0luU2VnbWVudDsKICBVSU5UICAgKnBTZWdtZW50Qml0ZmllbGQ7CiAgVUNIQVIgICpwTnVtV29yZEZvckJpdGZpZWxkOwogIFVTSE9SVCAqcE51bUJpdFZhbGlkSW5MYXN0V29yZDsKICBVSU5UICAgKnBDb2Rld29yZEJpdGZpZWxkOwogIElOVCAgICAgYml0ZmllbGRXb3JkOwogIElOVCAgICAgYml0SW5Xb3JkOwogIFVJTlQgICAgdGVtcFdvcmQ7CiAgVUlOVCAgICBpbnRlck1lZGlhdGVXb3JkOwogIElOVCAgICAgdGVtcEJpdDsKICBJTlQgICAgIGNhcnJ5OwoKICBVSU5UICAgIG51bUNvZGV3b3JkOwogIFVDSEFSICAgbnVtU2V0OwogIFVDSEFSICAgY3VycmVudFNldDsKICBVSU5UICAgIGNvZGV3b3JkSW5TZXQ7CiAgVUlOVCAgICByZW1haW5pbmdDb2Rld29yZHNJblNldDsKICBTQ0hBUiAgKnBTdGE7CiAgVUlOVCAgICByZXQ7CgogIHBOdW1TZWdtZW50ICAgICAgICAgICAgID0gJihwSGNyLT5zZWdtZW50SW5mby5udW1TZWdtZW50KTsKICBwUmVtYWluaW5nQml0c0luU2VnbWVudCA9ICAgcEhjci0+c2VnbWVudEluZm8ucFJlbWFpbmluZ0JpdHNJblNlZ21lbnQ7CiAgcFNlZ21lbnRCaXRmaWVsZCAgICAgICAgPSAgIHBIY3ItPnNlZ21lbnRJbmZvLnBTZWdtZW50Qml0ZmllbGQ7CiAgcE51bVdvcmRGb3JCaXRmaWVsZCAgICAgPSAmKHBIY3ItPnNlZ21lbnRJbmZvLm51bVdvcmRGb3JCaXRmaWVsZCk7CiAgcE51bUJpdFZhbGlkSW5MYXN0V29yZCAgPSAmKHBIY3ItPnNlZ21lbnRJbmZvLnBOdW1CaXRWYWxpZEluTGFzdFdvcmQpOwogIHBTdGEgICAgICAgICAgICAgICAgICAgID0gICBwSGNyLT5ub25QY3dTaWRlaW5mby5wU3RhOwoKICBudW1WYWxpZFNlZ21lbnQgPSBJbml0U2VnbWVudEJpdGZpZWxkKHBOdW1TZWdtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFJlbWFpbmluZ0JpdHNJblNlZ21lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2VnbWVudEJpdGZpZWxkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE51bVdvcmRGb3JCaXRmaWVsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOdW1CaXRWYWxpZEluTGFzdFdvcmQpOwoKICBpZiAoIG51bVZhbGlkU2VnbWVudCAhPSAwICkgewogICAgbnVtQ29kZXdvcmQgPSBwSGNyLT5zZWN0aW9uSW5mby5udW1Db2Rld29yZDsKICAgIG51bVNldCA9ICgobnVtQ29kZXdvcmQgLSAxKSAvICpwTnVtU2VnbWVudCkgKyAxOwoKCiAgICBwSGNyLT5zZWdtZW50SW5mby5yZWFkRGlyZWN0aW9uID0gRlJPTV9SSUdIVF9UT19MRUZUOwoKICAgIC8qIFByb2Nlc3Mgc2V0cyBzdWJzZXF1ZW50bHkgKi8KICAgIGZvciAoIGN1cnJlbnRTZXQgPSAxOyBjdXJyZW50U2V0IDwgbnVtU2V0IDsgY3VycmVudFNldCsrICkgewoKCgogICAgICAvKiBzdGVwIDEgKi8KICAgICAgbnVtQ29kZXdvcmQgLT0gKnBOdW1TZWdtZW50OyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgcmVtYWluaW5nIG5vbiBQQ1dzIFtmb3IgYWxsIHNldHNdICovCiAgICAgIGlmICggbnVtQ29kZXdvcmQgPCAqcE51bVNlZ21lbnQgKSB7CiAgICAgICAgY29kZXdvcmRJblNldCA9IG51bUNvZGV3b3JkOyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZm9yIGxhc3Qgc2V0ICovCiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgY29kZXdvcmRJblNldCA9ICpwTnVtU2VnbWVudDsgICAgICAgICAgICAgICAgICAgICAgICAgLyogZm9yIGFsbCBzZXRzIGV4Y2VwdCBsYXN0IHNldCAqLwogICAgICB9CgogICAgICAvKiBzdGVwIDIgKi8KICAgICAgLyogcHJlcGFyZSBhcnJheSAnQ29kZXdvcmRCaXRmaWVsZCc7IGFzIG11Y2ggb25lcyBhcmUgd3JpdHRlbiBmcm9tIGxlZnQgaW4gYWxsIHdvcmRzLCBhcyBtdWNoIGRlY29kZWRDb2Rld29yZEluU2V0Q291bnRlciBub25QQ1dzIGV4aXN0IGluIHRoaXMgc2V0ICovCiAgICAgIHRlbXBXb3JkID0gMHhGRkZGRkZGRjsKICAgICAgcENvZGV3b3JkQml0ZmllbGQgPSBwSGNyLT5zZWdtZW50SW5mby5wQ29kZXdvcmRCaXRmaWVsZDsKCiAgICAgIGZvciAoIGJpdGZpZWxkV29yZCA9ICpwTnVtV29yZEZvckJpdGZpZWxkOyBiaXRmaWVsZFdvcmQgIT0wOyBiaXRmaWVsZFdvcmQtLSApIHsgLyogbG9vcCBvdmVyIGFsbCB1c2VkIHdvcmRzICovCiAgICAgICAgaWYgKCBjb2Rld29yZEluU2V0ID4gTlVNQkVSX09GX0JJVF9JTl9XT1JEICkgeyAgICAgICAgLyogbW9yZSBjb2Rld29yZHMgdGhhbiBudW1iZXIgb2YgYml0cyA9PiBmaWxsIG9uZXMgKi8KICAgICAgICAgIC8qIGZpbGwgYSB3aG9sZSB3b3JkIHdpdGggb25lcyAqLwogICAgICAgICAgKnBDb2Rld29yZEJpdGZpZWxkKysgPSB0ZW1wV29yZDsKICAgICAgICAgIGNvZGV3b3JkSW5TZXQgLT0gTlVNQkVSX09GX0JJVF9JTl9XT1JEOyAgICAgICAgICAgICAvKiBzdWJ0cmFjdCBudW1iZXIgb2YgYml0cyAqLwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgIC8qIHByZXBhcmUgbGFzdCB0ZW1wV29yZCAqLwogICAgICAgICAgZm9yIChyZW1haW5pbmdDb2Rld29yZHNJblNldCA9IGNvZGV3b3JkSW5TZXQ7IHJlbWFpbmluZ0NvZGV3b3Jkc0luU2V0IDwgTlVNQkVSX09GX0JJVF9JTl9XT1JEIDsgcmVtYWluaW5nQ29kZXdvcmRzSW5TZXQrKyApIHsKICAgICAgICAgICAgdGVtcFdvcmQgPSB0ZW1wV29yZCAmIH4oMSA8PCAoTlVNQkVSX09GX0JJVF9JTl9XT1JELTEtcmVtYWluaW5nQ29kZXdvcmRzSW5TZXQpKTsgLyogc2V0IGEgemVybyBhdCBiaXQgbnVtYmVyIChOVU1CRVJfT0ZfQklUX0lOX1dPUkQtMS1pKSBpbiB0ZW1wV29yZCAqLwogICAgICAgICAgfQogICAgICAgICAgKnBDb2Rld29yZEJpdGZpZWxkKysgPSB0ZW1wV29yZDsKICAgICAgICAgIHRlbXBXb3JkID0gMHgwMDAwMDAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgcENvZGV3b3JkQml0ZmllbGQgPSBwSGNyLT5zZWdtZW50SW5mby5wQ29kZXdvcmRCaXRmaWVsZDsKCiAgICAgIC8qIHN0ZXAgMyAqLwogICAgICAvKiBidWlsZCBub24tUENXIHNpZGVpbmZvIGZvciBlYWNoIG5vbi1QQ1cgb2YgdGhlIGN1cnJlbnQgc2V0ICovCiAgICAgIEluaXROb25QQ1dTaWRlSW5mb3JtYXRpb25Gb3JDdXJyZW50U2V0KHBIY3IpOwoKICAgICAgLyogc3RlcCA0ICovCiAgICAgIC8qIGRlY29kZSBhbGwgbm9uLVBDV3MgYmVsb25naW5nIHRvIHRoaXMgc2V0ICovCgogICAgICAvKiBsb29wIG92ZXIgdHJpYWxzICovCiAgICAgIGNvZGV3b3JkT2Zmc2V0QmFzZSA9IDA7CiAgICAgIGZvciAoIHRyaWFsID0gKnBOdW1TZWdtZW50OyB0cmlhbCA+IDA7IHRyaWFsLS0gKSB7CgogICAgICAgIC8qIGxvb3Agb3ZlciBudW1iZXIgb2Ygd29yZHMgaW4gYml0ZmllbGRzICovCiAgICAgICAgc2VnbWVudE9mZnNldCA9IDA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3RhcnQgYXQgemVybyBpbiBldmVyeSBzZWdtZW50ICovCiAgICAgICAgcEhjci0+c2VnbWVudEluZm8uc2VnbWVudE9mZnNldCA9IHNlZ21lbnRPZmZzZXQ7ICAgICAgICAgLyogc3RvcmUgaW4gc3RydWN0dXJlIGZvciBzdGF0ZXMgKi8KICAgICAgICBjb2Rld29yZE9mZnNldCA9IGNvZGV3b3JkT2Zmc2V0QmFzZTsKICAgICAgICBwSGNyLT5ub25QY3dTaWRlaW5mby5jb2Rld29yZE9mZnNldCA9IGNvZGV3b3JkT2Zmc2V0OyAgICAvKiBzdG9yZSBpbiBzdHJ1Y3R1cmUgZm9yIHN0YXRlcyAqLwoKICAgICAgICBmb3IgKCBiaXRmaWVsZFdvcmQ9MDsgYml0ZmllbGRXb3JkIDwgKnBOdW1Xb3JkRm9yQml0ZmllbGQ7IGJpdGZpZWxkV29yZCsrICkgewoKICAgICAgICAgIC8qIGRlcml2ZSB0ZW1wV29yZCB3aXRoIGJpdHdpc2UgYW5kICovCiAgICAgICAgICB0ZW1wV29yZCA9IHBTZWdtZW50Qml0ZmllbGRbYml0ZmllbGRXb3JkXSAmIHBDb2Rld29yZEJpdGZpZWxkW2JpdGZpZWxkV29yZF07CgogICAgICAgICAgLyogaWYgdGVtcFdvcmQgaXMgbm90IHplcm8sIGRlY29kZSBzb21ldGhpbmcgKi8KICAgICAgICAgIGlmICggdGVtcFdvcmQgIT0gMCApIHsKCgogICAgICAgICAgICAvKiBsb29wIG92ZXIgYWxsIGJpdHMgaW4gdGVtcFdvcmQ7IHN0YXJ0IHN0YXRlIG1hY2hpbmUgaWYgJiBpcyB0cnVlICovCiAgICAgICAgICAgIGZvciAoIGJpdEluV29yZCA9IE5VTUJFUl9PRl9CSVRfSU5fV09SRDsgYml0SW5Xb3JkID4gMDsgYml0SW5Xb3JkLS0gKSB7CgogICAgICAgICAgICAgIGludGVyTWVkaWF0ZVdvcmQgPSAoKFVJTlQpMSA8PCAoYml0SW5Xb3JkLTEpICk7CiAgICAgICAgICAgICAgaWYgKCAoIHRlbXBXb3JkICYgaW50ZXJNZWRpYXRlV29yZCApID09IGludGVyTWVkaWF0ZVdvcmQgKSB7CgogICAgICAgICAgICAgICAgLyogZ2V0IHN0YXRlIGFuZCBzdGFydCBzdGF0ZSBtYWNoaW5lICovCiAgICAgICAgICAgICAgICBwSGNyLT5ub25QY3dTaWRlaW5mby5wU3RhdGUgPSBhU3RhdGVDb25zdGFudDJTdGF0ZVtwU3RhW2NvZGV3b3JkT2Zmc2V0XV07CgogICAgICAgICAgICAgICAgd2hpbGUocEhjci0+bm9uUGN3U2lkZWluZm8ucFN0YXRlKSB7CiAgICAgICAgICAgICAgICAgIHJldCA9ICgoU1RBVEVGVU5DKSBwSGNyLT5ub25QY3dTaWRlaW5mby5wU3RhdGUpKGJzLCBwSGNyKTsKI2lmIFNUQVRFX01BQ0hJTkVfRVJST1JfQ0hFQ0sKICAgICAgICAgICAgICAgICAgaWYgKCByZXQgIT0gMCApIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvKiB1cGRhdGUgYm90aCBvZmZzZXRzICovCiAgICAgICAgICAgICAgc2VnbWVudE9mZnNldCArPSAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGFkZCBOVU1CRVJfT0ZfQklUX0lOX1dPUkQgdGltZXMgb25lICovCiAgICAgICAgICAgICAgcEhjci0+c2VnbWVudEluZm8uc2VnbWVudE9mZnNldCA9IHNlZ21lbnRPZmZzZXQ7CiAgICAgICAgICAgICAgY29kZXdvcmRPZmZzZXQgKz0gMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGFkZCBOVU1CRVJfT0ZfQklUX0lOX1dPUkQgdGltZXMgb25lICovCiAgICAgICAgICAgICAgY29kZXdvcmRPZmZzZXQgPSBNb2R1bG9WYWx1ZShjb2Rld29yZE9mZnNldCwqcE51bVNlZ21lbnQpOyAgICAgIC8qIGluZGV4IG9mIHRoZSBjdXJyZW50IGNvZGV3b3JkIGxpZXMgd2l0aGluIG1vZHVsbyByYW5nZSAqLwogICAgICAgICAgICAgIHBIY3ItPm5vblBjd1NpZGVpbmZvLmNvZGV3b3JkT2Zmc2V0ID0gY29kZXdvcmRPZmZzZXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgewogICAgICAgICAgICBzZWdtZW50T2Zmc2V0ICs9IE5VTUJFUl9PRl9CSVRfSU5fV09SRDsgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBhZGQgTlVNQkVSX09GX0JJVF9JTl9XT1JEIGF0IG9uY2UgKi8KICAgICAgICAgICAgcEhjci0+c2VnbWVudEluZm8uc2VnbWVudE9mZnNldCA9IHNlZ21lbnRPZmZzZXQ7CiAgICAgICAgICAgIGNvZGV3b3JkT2Zmc2V0ICs9IE5VTUJFUl9PRl9CSVRfSU5fV09SRDsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGFkZCBOVU1CRVJfT0ZfQklUX0lOX1dPUkQgYXQgb25jZSAqLwogICAgICAgICAgICBjb2Rld29yZE9mZnNldCA9IE1vZHVsb1ZhbHVlKGNvZGV3b3JkT2Zmc2V0LCpwTnVtU2VnbWVudCk7ICAgICAgICAvKiBpbmRleCBvZiB0aGUgY3VycmVudCBjb2Rld29yZCBsaWVzIHdpdGhpbiBtb2R1bG8gcmFuZ2UgKi8KICAgICAgICAgICAgcEhjci0+bm9uUGN3U2lkZWluZm8uY29kZXdvcmRPZmZzZXQgPSBjb2Rld29yZE9mZnNldDsKICAgICAgICAgIH0KICAgICAgICB9IC8qIGVuZCBvZiBiaXRmaWVsZCB3b3JkIGxvb3AgKi8KCiAgICAgICAgLyogZGVjcmVtZW50IGNvZGV3b3JkIC0gcG9pbnRlciAqLwogICAgICAgIGNvZGV3b3JkT2Zmc2V0QmFzZSAtPSAxOwogICAgICAgIGNvZGV3b3JkT2Zmc2V0QmFzZSA9IE1vZHVsb1ZhbHVlKGNvZGV3b3JkT2Zmc2V0QmFzZSwqcE51bVNlZ21lbnQpOyAgICAvKiBpbmRleCBvZiB0aGUgY3VycmVudCBjb2Rld29yZCBiYXNlIGxpZXMgd2l0aGluIG1vZHVsbyByYW5nZSAqLwoKICAgICAgICAvKiByb3RhdGUgbnVtU2VnbWVudCBiaXRzIGluIGNvZGV3b3JkQml0ZmllbGQgKi8KICAgICAgICAvKiByb3RhdGlvbiBvZiAqbnVtU2VnbWVudCBiaXRzIGluIGJpdGZpZWxkIG9mIGNvZGV3b3JkcyAoY2lyY2xlLXJvdGF0aW9uKSAqLwogICAgICAgIC8qIGdldCBsYXN0IHZhbGlkIGJpdCAqLwogICAgICAgIHRlbXBCaXQgPSBwQ29kZXdvcmRCaXRmaWVsZFsqcE51bVdvcmRGb3JCaXRmaWVsZC0xXSAmICgxIDw8IChOVU1CRVJfT0ZfQklUX0lOX1dPUkQgLSAqcE51bUJpdFZhbGlkSW5MYXN0V29yZCkpOwogICAgICAgIHRlbXBCaXQgPSB0ZW1wQml0ID4+IChOVU1CRVJfT0ZfQklUX0lOX1dPUkQgLSAqcE51bUJpdFZhbGlkSW5MYXN0V29yZCk7CgogICAgICAgIC8qIHdyaXRlIHplcm8gaW50byBwbGFjZSB3aGVyZSB0ZW1wQml0IHdhcyBmZXRjaGVkIGZyb20gKi8KICAgICAgICBwQ29kZXdvcmRCaXRmaWVsZFsqcE51bVdvcmRGb3JCaXRmaWVsZC0xXSA9IHBDb2Rld29yZEJpdGZpZWxkWypwTnVtV29yZEZvckJpdGZpZWxkLTFdICYgfigxIDw8IChOVU1CRVJfT0ZfQklUX0lOX1dPUkQgLSAqcE51bUJpdFZhbGlkSW5MYXN0V29yZCkpOwoKICAgICAgICAvKiByb3RhdGUgbGFzdCB2YWxpZCB3b3JkICovCiAgICAgICAgcENvZGV3b3JkQml0ZmllbGRbKnBOdW1Xb3JkRm9yQml0ZmllbGQtMV0gPSBwQ29kZXdvcmRCaXRmaWVsZFsqcE51bVdvcmRGb3JCaXRmaWVsZC0xXSA+PiAxOwoKICAgICAgICAvKiB0cmFuc2ZhcmUgY2FycnkgYml0IDAgZnJvbSBjdXJyZW50IHdvcmQgaW50byBiaXRwb3NpdGlvbiAzMSBmcm9tIG5leHQgd29yZCBhbmQgcm90YXRlIGN1cnJlbnQgd29yZCAqLwogICAgICAgIGZvciAoIGJpdGZpZWxkV29yZCA9ICpwTnVtV29yZEZvckJpdGZpZWxkLTI7IGJpdGZpZWxkV29yZCA+IC0xIDsgYml0ZmllbGRXb3JkLS0gKSB7CiAgICAgICAgICAvKiBnZXQgY2FycnkgKD1iaXQgYXQgcG9zaXRpb24gMCkgZnJvbSBjdXJyZW50IHdvcmQgKi8KICAgICAgICAgIGNhcnJ5ID0gcENvZGV3b3JkQml0ZmllbGRbYml0ZmllbGRXb3JkXSAmIDE7CgogICAgICAgICAgLyogcHV0IHRoZSBjYXJyeSBiaXQgYXQgcG9zaXRpb24gMzEgaW50byB3b3JkIHJpZ2h0IGZyb20gY3VycmVudCB3b3JkICovCiAgICAgICAgICBwQ29kZXdvcmRCaXRmaWVsZFtiaXRmaWVsZFdvcmQrMV0gPSBwQ29kZXdvcmRCaXRmaWVsZFtiaXRmaWVsZFdvcmQrMV0gfCAoY2FycnkgPDwgKE5VTUJFUl9PRl9CSVRfSU5fV09SRC0xKSk7CgogICAgICAgICAgLyogc2hpZnQgY3VycmVudCB3b3JkICovCiAgICAgICAgICBwQ29kZXdvcmRCaXRmaWVsZFtiaXRmaWVsZFdvcmRdID0gcENvZGV3b3JkQml0ZmllbGRbYml0ZmllbGRXb3JkXSA+PiAxOwogICAgICAgIH0KCiAgICAgICAgLyogcHV0IHRlbXBCaXQgaW50byBmcmVlIGJpdC1wb3NpdGlvbiAzMSBmcm9tIGZpcnN0IHdvcmQgKi8KICAgICAgICBwQ29kZXdvcmRCaXRmaWVsZFswXSA9IHBDb2Rld29yZEJpdGZpZWxkWzBdIHwgKHRlbXBCaXQgPDwgKE5VTUJFUl9PRl9CSVRfSU5fV09SRC0xKSk7CgogICAgICB9IC8qIGVuZCBvZiB0cmlhbCBsb29wICovCgogICAgICAvKiB0b2dnbGUgcmVhZCBkaXJlY3Rpb24gKi8KICAgICAgcEhjci0+c2VnbWVudEluZm8ucmVhZERpcmVjdGlvbiA9IFRvZ2dsZVJlYWREaXJlY3Rpb24ocEhjci0+c2VnbWVudEluZm8ucmVhZERpcmVjdGlvbik7CgogICAgfQogICAgLyogZW5kIG9mIHNldCBsb29wICovCgogICAgLyogYWxsIG5vbi1QQ1dzIG9mIHRoaXMgc3BlY3RydW0gYXJlIGRlY29kZWQgKi8KICB9CgogIC8qIGFsbCBQQ1dzIGFuZCBhbGwgbm9uIFBDV3MgYXJlIGRlY29kZWQuIFRoZXkgYXJlIHVuYmFja3NvcnRlZCBpbiBvdXRwdXQgYnVmZmVyLiBIZXJlIGlzIHRoZSBJbnRlcmZhY2Ugd2l0aCBjb21wYXJpbmcgUVNDcyB0byBhc20gZGVjb2RpbmcgKi8KfQoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgZGVzY3JpcHRpb246ICAgVGhpcyBmdW5jdGlvbiBwcmVwYXJlcyB0aGUgYml0ZmllbGQgdXNlZCBmb3IgdGhlCiAgICAgICAgICAgICAgICAgICAgc2VnbWVudHMuIFRoZSBsaXN0IGlzIHNldCB1cCBvbmNlIHRvIGJlIHVzZWQgaW4gYWxsIGZvbGxvd2luZyBzZXRzLiBJZiBhCiAgICAgICAgICAgICAgICAgICAgc2VnbWVudCBpcyBkZWNvZGVkIGVtcHR5LCB0aGUgYWNjb3JkaW5nIGJpdCBmcm9tIHRoZSBCaXRmaWVsZCBpcyByZW1vdmVkLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIHJldHVybjogICAgIG51bVZhbGlkU2VnbWVudCA9IHRoZSBudW1iZXIgb2YgdmFsaWQgc2VnbWVudHMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8Kc3RhdGljIFVJTlQgSW5pdFNlZ21lbnRCaXRmaWVsZChVSU5UICAgKnBOdW1TZWdtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDSEFSICAqcFJlbWFpbmluZ0JpdHNJblNlZ21lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCAgICpwU2VnbWVudEJpdGZpZWxkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICAqcE51bVdvcmRGb3JCaXRmaWVsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0hPUlQgKnBOdW1CaXRWYWxpZEluTGFzdFdvcmQpCnsKICBTSE9SVCAgIGk7CiAgVVNIT1JUICByOwogIFVDSEFSICAgYml0ZmllbGRXb3JkOwogIFVJTlQgICAgdGVtcFdvcmQ7CiAgVVNIT1JUICBudW1WYWxpZFNlZ21lbnQ7CgogICpwTnVtV29yZEZvckJpdGZpZWxkID0gKCgqcE51bVNlZ21lbnQtMSkgPj4gVEhJUlRZVFdPX0xPR19ESVZfVFdPX0xPRykgKyAxOwoKICAvKiBsb29wIG92ZXIgYWxsIHdvcmRzLCB3aGljaCBhcmUgY29tcGxldGVseSB1c2VkIG9yIG9ubHkgcGFydGlhbCAqLwogIC8qIGJpdCBpbiBwU2VnbWVudEJpdGZpZWxkIGlzIHplcm8gaWYgc2VnbWVudCBpcyBlbXB0eTsgYml0IGluIHBTZWdtZW50Qml0ZmllbGQgaXMgb25lIGlmIHNlZ21lbnQgaXMgbm90IGVtcHR5ICovCiAgbnVtVmFsaWRTZWdtZW50ID0gMDsKICAqcE51bUJpdFZhbGlkSW5MYXN0V29yZCA9ICpwTnVtU2VnbWVudDsKCiAgLyogbG9vcCBvdmVyIHdvcmRzICovCiAgZm9yICggYml0ZmllbGRXb3JkPTA7IGJpdGZpZWxkV29yZCA8ICpwTnVtV29yZEZvckJpdGZpZWxkIC0gMTsgYml0ZmllbGRXb3JkKysgKSB7CiAgICB0ZW1wV29yZCA9IDB4RkZGRkZGRkY7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzZXQgb25lcyAqLwogICAgciA9IGJpdGZpZWxkV29yZCA8PCBUSElSVFlUV09fTE9HX0RJVl9UV09fTE9HOwogICAgZm9yICggaT0wOyBpIDwgTlVNQkVSX09GX0JJVF9JTl9XT1JEOyBpKyspIHsKICAgICAgaWYgKCBwUmVtYWluaW5nQml0c0luU2VnbWVudFtyICsgaV0gPT0gMCApIHsKICAgICAgICB0ZW1wV29yZCA9IHRlbXBXb3JkICYgfigxIDw8IChOVU1CRVJfT0ZfQklUX0lOX1dPUkQtMS1pKSk7ICAgICAgICAgIC8qIHNldCBhIHplcm8gYXQgYml0IG51bWJlciAoTlVNQkVSX09GX0JJVF9JTl9XT1JELTEtaSkgaW4gdGVtcFdvcmQgKi8KICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBudW1WYWxpZFNlZ21lbnQgKz0gMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNvdW50IHNlZ21lbnRzIHdoaWNoIGFyZSBub3QgZW1wdHkgKi8KICAgICAgfQogICAgfQogICAgcFNlZ21lbnRCaXRmaWVsZFtiaXRmaWVsZFdvcmRdID0gdGVtcFdvcmQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3RvcmUgcmVzdWx0ICovCiAgICAqcE51bUJpdFZhbGlkSW5MYXN0V29yZCAtPSBOVU1CRVJfT0ZfQklUX0lOX1dPUkQ7ICAgICAgICAgICAgICAgICAgICAgICAvKiBjYWxjdWxhdGUgbnVtYmVyIG9mIHplcm9zIG9uIExTQiBzaWRlIGluIHRoZSBsYXN0IHdvcmQgKi8KICB9CgoKICAvKiBjYWxjdWxhdGUgbGFzdCB3b3JkOiBwcmVwYXJlIHNwZWNpYWwgdGVtcFdvcmQgKi8KICB0ZW1wV29yZCA9IDB4RkZGRkZGRkY7CiAgZm9yICggaT0wOyBpIDwgKCBOVU1CRVJfT0ZfQklUX0lOX1dPUkQgLSAqcE51bUJpdFZhbGlkSW5MYXN0V29yZCApOyBpKysgKSB7CiAgICB0ZW1wV29yZCA9IHRlbXBXb3JkICYgfigxIDw8IGkpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjbGVhciBiaXQgaSBpbiB0ZW1wV29yZCAqLwogIH0KCiAgLyogY2FsY3VsYXRlIGxhc3Qgd29yZCAqLwogIHIgPSBiaXRmaWVsZFdvcmQgPDwgVEhJUlRZVFdPX0xPR19ESVZfVFdPX0xPRzsKICBmb3IgKCBpPTA7IGk8KnBOdW1CaXRWYWxpZEluTGFzdFdvcmQ7IGkrKykgewogICAgaWYgKCBwUmVtYWluaW5nQml0c0luU2VnbWVudFtyICsgaV0gPT0gMCApIHsKICAgICAgdGVtcFdvcmQgPSB0ZW1wV29yZCAmIH4oMSA8PCAoTlVNQkVSX09GX0JJVF9JTl9XT1JELTEtaSkpOyAgICAgICAgICAgIC8qIHNldCBhIHplcm8gYXQgYml0IG51bWJlciAoTlVNQkVSX09GX0JJVF9JTl9XT1JELTEtaSkgaW4gdGVtcFdvcmQgKi8KICAgIH0KICAgIGVsc2UgewogICAgICBudW1WYWxpZFNlZ21lbnQgKz0gMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY291bnQgc2VnbWVudHMgd2hpY2ggYXJlIG5vdCBlbXB0eSAqLwogICAgfQogIH0KICBwU2VnbWVudEJpdGZpZWxkW2JpdGZpZWxkV29yZF0gPSB0ZW1wV29yZDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHN0b3JlIHJlc3VsdCAqLwoKCgogIHJldHVybiBudW1WYWxpZFNlZ21lbnQ7Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIGRlc2NyaXB0aW9uOiAgVGhpcyBmdW5jdGlvbiBzZXRzIHVwIHNpZGVpbmZvIGZvciB0aGUgbm9uLVBDVyBkZWNvZGVyIChmb3IgdGhlIGN1cnJlbnQgc2V0KS4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIHZvaWQgSW5pdE5vblBDV1NpZGVJbmZvcm1hdGlvbkZvckN1cnJlbnRTZXQoSF9IQ1JfSU5GTyBwSGNyKQp7CiAgVVNIT1JUICAgICBpLGs7CiAgVUNIQVIgICAgICBjb2RlYm9va0RpbTsKICBVSU5UICAgICAgIHN0YXJ0Tm9kZTsKCiAgVUNIQVIgICAgICpwQ29kZWJvb2sgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICAgcEhjci0+bm9uUGN3U2lkZWluZm8ucENvZGVib29rOwogIFVJTlQgICAgICAqaU5vZGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAgIHBIY3ItPm5vblBjd1NpZGVpbmZvLmlOb2RlOwogIFVDSEFSICAgICAqcENudFNpZ24gICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAgIHBIY3ItPm5vblBjd1NpZGVpbmZvLnBDbnRTaWduOwogIFVTSE9SVCAgICAqaVJlc3VsdFBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgPSAgIHBIY3ItPm5vblBjd1NpZGVpbmZvLmlSZXN1bHRQb2ludGVyOwogIFVJTlQgICAgICAqcEVzY2FwZVNlcXVlbmNlSW5mbyAgICAgICAgICAgICAgICAgPSAgIHBIY3ItPm5vblBjd1NpZGVpbmZvLnBFc2NhcGVTZXF1ZW5jZUluZm87CiAgU0NIQVIgICAgICpwU3RhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICAgcEhjci0+bm9uUGN3U2lkZWluZm8ucFN0YTsKICBVU0hPUlQgICAgKnBOdW1FeHRlbmRlZFNvcnRlZENvZGV3b3JkSW5TZWN0aW9uID0gICBwSGNyLT5zZWN0aW9uSW5mby5wTnVtRXh0ZW5kZWRTb3J0ZWRDb2Rld29yZEluU2VjdGlvbjsKICBpbnQgICAgICAgIG51bUV4dGVuZGVkU29ydGVkQ29kZXdvcmRJblNlY3Rpb25JZHggPSAgIHBIY3ItPnNlY3Rpb25JbmZvLm51bUV4dGVuZGVkU29ydGVkQ29kZXdvcmRJblNlY3Rpb25JZHg7CiAgVUNIQVIgICAgICpwRXh0ZW5kZWRTb3J0ZWRDb2RlYm9vayAgICAgICAgICAgICA9ICAgcEhjci0+c2VjdGlvbkluZm8ucEV4dGVuZGVkU29ydGVkQ29kZWJvb2s7CiAgaW50ICAgICAgICBleHRlbmRlZFNvcnRlZENvZGVib29rSWR4ICAgICAgICAgICA9ICAgcEhjci0+c2VjdGlvbkluZm8uZXh0ZW5kZWRTb3J0ZWRDb2RlYm9va0lkeDsKICBVU0hPUlQgICAgKnBOdW1FeHRlbmRlZFNvcnRlZFNlY3Rpb25zSW5TZXRzICAgID0gICBwSGNyLT5zZWN0aW9uSW5mby5wTnVtRXh0ZW5kZWRTb3J0ZWRTZWN0aW9uc0luU2V0czsKICBpbnQgICAgICAgIG51bUV4dGVuZGVkU29ydGVkU2VjdGlvbnNJblNldHNJZHggID0gICBwSGNyLT5zZWN0aW9uSW5mby5udW1FeHRlbmRlZFNvcnRlZFNlY3Rpb25zSW5TZXRzSWR4OwogIEZJWFBfREJMICAqcFF1YW50aXplZFNwZWN0cmFsQ29lZmZpY2llbnRzICAgICAgPSAgIFNQRUNfTE9ORyhwSGNyLT5kZWNJbk91dC5wUXVhbnRpemVkU3BlY3RyYWxDb2VmZmljaWVudHNCYXNlKTsKICBpbnQgICAgICAgIHF1YW50aXplZFNwZWN0cmFsQ29lZmZpY2llbnRzSWR4ICAgID0gICBwSGNyLT5kZWNJbk91dC5xdWFudGl6ZWRTcGVjdHJhbENvZWZmaWNpZW50c0lkeDsKICBjb25zdCBVQ0hBUiAgICAgKnBDYkRpbWVuc2lvbiAgICAgICAgICAgICAgICAgID0gICBwSGNyLT50YWJsZUluZm8ucENiRGltZW5zaW9uOwogIGludCBpdGVyYXRpb25Db3VudGVyID0gMDsKCiAgLyogbG9vcCBvdmVyIG51bWJlciBvZiBleHRlbmRlZCBzb3J0ZWQgc2VjdGlvbnMgaW4gdGhlIGN1cnJlbnQgc2V0IHNvIGFsbCBjb2Rld29yZHMgc2lkZWluZm8gdmFyaWFibGVzIHdpdGhpbiB0aGlzIHNldCBjYW4gYmUgcHJlcGFyZWQgZm9yIGRlY29kaW5nICovCiAgZm9yICggaT1wTnVtRXh0ZW5kZWRTb3J0ZWRTZWN0aW9uc0luU2V0c1tudW1FeHRlbmRlZFNvcnRlZFNlY3Rpb25zSW5TZXRzSWR4XTsgaSAhPSAwOyBpLS0gKSB7CgogICAgY29kZWJvb2tEaW0gPSBwQ2JEaW1lbnNpb25bcEV4dGVuZGVkU29ydGVkQ29kZWJvb2tbZXh0ZW5kZWRTb3J0ZWRDb2RlYm9va0lkeF1dOwogICAgc3RhcnROb2RlICAgPSAqYUh1ZmZUYWJsZVtwRXh0ZW5kZWRTb3J0ZWRDb2RlYm9va1tleHRlbmRlZFNvcnRlZENvZGVib29rSWR4XV07CiAgICAKICAgIGZvciAoIGsgPSBwTnVtRXh0ZW5kZWRTb3J0ZWRDb2Rld29yZEluU2VjdGlvbltudW1FeHRlbmRlZFNvcnRlZENvZGV3b3JkSW5TZWN0aW9uSWR4XTsgayAhPSAwOyBrLS0gKSB7CiAgICAgIGl0ZXJhdGlvbkNvdW50ZXIrKzsKICAgICAgaWYgKGl0ZXJhdGlvbkNvdW50ZXIgPiAoMTAyND4+MikpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgKnBTdGErKyAgICAgICAgICAgICAgICAgPSBhQ29kZWJvb2syU3RhcnRJbnRbcEV4dGVuZGVkU29ydGVkQ29kZWJvb2tbZXh0ZW5kZWRTb3J0ZWRDb2RlYm9va0lkeF1dOwogICAgICAqcENvZGVib29rKysgICAgICAgICAgICA9IHBFeHRlbmRlZFNvcnRlZENvZGVib29rW2V4dGVuZGVkU29ydGVkQ29kZWJvb2tJZHhdOwogICAgICAqaU5vZGUrKyAgICAgICAgICAgICAgICA9IHN0YXJ0Tm9kZTsKICAgICAgKnBDbnRTaWduKysgICAgICAgICAgICAgPSAwOwogICAgICAqaVJlc3VsdFBvaW50ZXIrKyAgICAgICA9IHF1YW50aXplZFNwZWN0cmFsQ29lZmZpY2llbnRzSWR4OwogICAgICAqcEVzY2FwZVNlcXVlbmNlSW5mbysrICA9IDA7CiAgICAgIHF1YW50aXplZFNwZWN0cmFsQ29lZmZpY2llbnRzSWR4ICs9IGNvZGVib29rRGltOyAgICAgICAgICAgICAgICAgICAgIC8qIHVwZGF0ZSBwb2ludGVyIGJ5IGNvZGVib29rRGltIC0tPiBwb2ludCB0byBuZXh0IHN0YXJ0aW5nIHZhbHVlIGZvciB3cml0aW5nIG91dCAqLwogICAgICBpZiAocXVhbnRpemVkU3BlY3RyYWxDb2VmZmljaWVudHNJZHggPj0gMTAyNCkgewogICAgICAgIHJldHVybjsKICAgICAgfQogICAgfQogICAgbnVtRXh0ZW5kZWRTb3J0ZWRDb2Rld29yZEluU2VjdGlvbklkeCsrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbmMgcHRyIGZvciBuZXh0IGV4dCBzb3J0IHNlYyBpbiBjdXJyZW50IHNldCAqLwogICAgZXh0ZW5kZWRTb3J0ZWRDb2RlYm9va0lkeCsrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbmMgcHRyIGZvciBuZXh0IGV4dCBzb3J0IHNlYyBpbiBjdXJyZW50IHNldCAqLwogICAgaWYgKG51bUV4dGVuZGVkU29ydGVkQ29kZXdvcmRJblNlY3Rpb25JZHggPj0gKE1BWF9TRkJfSENSK01BWF9IQ1JfU0VUUykgfHwgZXh0ZW5kZWRTb3J0ZWRDb2RlYm9va0lkeCA+PSAoTUFYX1NGQl9IQ1IrTUFYX0hDUl9TRVRTKSkgewogICAgICByZXR1cm47CiAgICB9CiAgfQogIG51bUV4dGVuZGVkU29ydGVkU2VjdGlvbnNJblNldHNJZHgrKzsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbmMgcHRyIGZvciBuZXh0IHNldCBvZiBub24tUENXcyAqLwogIGlmIChudW1FeHRlbmRlZFNvcnRlZENvZGV3b3JkSW5TZWN0aW9uSWR4ID49IChNQVhfU0ZCX0hDUitNQVhfSENSX1NFVFMpKSB7CiAgICByZXR1cm47CiAgfQoKICAvKiBXcml0ZSBiYWNrIGluZGV4ZXMgKi8KICBwSGNyLT5zZWN0aW9uSW5mby5udW1FeHRlbmRlZFNvcnRlZENvZGV3b3JkSW5TZWN0aW9uSWR4ID0gbnVtRXh0ZW5kZWRTb3J0ZWRDb2Rld29yZEluU2VjdGlvbklkeDsKICBwSGNyLT5zZWN0aW9uSW5mby5leHRlbmRlZFNvcnRlZENvZGVib29rSWR4ID0gZXh0ZW5kZWRTb3J0ZWRDb2RlYm9va0lkeDsKICBwSGNyLT5zZWN0aW9uSW5mby5udW1FeHRlbmRlZFNvcnRlZFNlY3Rpb25zSW5TZXRzSWR4ID0gbnVtRXh0ZW5kZWRTb3J0ZWRTZWN0aW9uc0luU2V0c0lkeDsKICBwSGNyLT5zZWN0aW9uSW5mby5udW1FeHRlbmRlZFNvcnRlZENvZGV3b3JkSW5TZWN0aW9uSWR4ID0gbnVtRXh0ZW5kZWRTb3J0ZWRDb2Rld29yZEluU2VjdGlvbklkeDsKICBwSGNyLT5kZWNJbk91dC5xdWFudGl6ZWRTcGVjdHJhbENvZWZmaWNpZW50c0lkeCA9IHF1YW50aXplZFNwZWN0cmFsQ29lZmZpY2llbnRzSWR4Owp9CgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICBkZXNjcmlwdGlvbjogVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBpbnB1dCB2YWx1ZSBpZiB0aGUgdmFsdWUgaXMgaW4gdGhlCiAgICAgICAgICAgICAgICAgIHJhbmdlIG9mIGJ1ZmZlcmxlbmd0aC4gSWYgPGlucHV0PiBpcyBzbWFsbGVyLCBvbmUgYnVmZmVybGVuZ3RoIGlzIGFkZGVkLAogICAgICAgICAgICAgICAgICBpZiA8aW5wdXQ+IGlzIGJpZ2dlciBvbmUgYnVmZmVybGVuZ3RoIGlzIHN1YnRyYWN0ZWQuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgcmV0dXJuOiAgIG1vZHVsbyByZXN1bHQKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8Kc3RhdGljIElOVCBNb2R1bG9WYWx1ZShJTlQgaW5wdXQsIElOVCBidWZmZXJsZW5ndGgpCnsKICBpZiAoIGlucHV0ID4gKGJ1ZmZlcmxlbmd0aCAtIDEpICkgewogICAgcmV0dXJuIChpbnB1dCAtIGJ1ZmZlcmxlbmd0aCk7CiAgfQogIGlmICggaW5wdXQgPCAwICkgewogICAgcmV0dXJuIChpbnB1dCArIGJ1ZmZlcmxlbmd0aCk7CiAgfQogIHJldHVybiBpbnB1dDsKfQoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgZGVzY3JpcHRpb246IFRoaXMgZnVuY3Rpb24gY2xlYXJzIGEgYml0IGZyb20gY3VycmVudCBiaXRmaWVsZCBhbmQKICAgICAgICAgICAgICAgICAgc3dpdGNoZXMgb2ZmIHRoZSBzdGF0ZW1hY2hpbmUuCgogICAgICAgICAgICAgICAgICBBIGJpdCBpcyBjbGVhcmVkIGluIHR3byBjYXNlczoKICAgICAgICAgICAgICAgICAgYSkgYSBjb2Rld29yZCBpcyBkZWNvZGVkLCB0aGVuIGEgYml0IGlzIGNsZWFyZWQgaW4gY29kZXdvcmQgYml0ZmllbGQKICAgICAgICAgICAgICAgICAgYikgYSBzZWdtZW50IGlzIGRlY29kZWQgZW1wdHksIHRoZW4gYSBiaXQgaXMgY2xlYXJlZCBpbiBzZWdtZW50IGJpdGZpZWxkCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCnN0YXRpYyB2b2lkIENsZWFyQml0RnJvbUJpdGZpZWxkKFNUQVRFRlVOQyAqcHRyU3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICBvZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICpwQml0ZmllbGQpCnsKICBVSU5UICBudW1CaXRmaWVsZFdvcmQ7CiAgVUlOVCAgbnVtQml0ZmllbGRCaXQ7CgogIC8qIGdldCBib3RoIHZhbHVlcyBuZWVkZWQgZm9yIGNsZWFyaW5nIHRoZSBiaXQgKi8KICBudW1CaXRmaWVsZFdvcmQgPSBvZmZzZXQgPj4gVEhJUlRZVFdPX0xPR19ESVZfVFdPX0xPRzsgICAgICAgICAgICAgICAgICAgICAgLyogaW50ICAgPSB3b3JkTnIgKi8KICBudW1CaXRmaWVsZEJpdCAgPSBvZmZzZXQgLSAobnVtQml0ZmllbGRXb3JkIDw8IFRISVJUWVRXT19MT0dfRElWX1RXT19MT0cpOyAgLyogZnJhY3QgPSBiaXROciAgKi8KCiAgLyogY2xlYXIgYSBiaXQgaW4gYml0ZmllbGQgKi8KICBwQml0ZmllbGRbbnVtQml0ZmllbGRXb3JkXSA9IHBCaXRmaWVsZFtudW1CaXRmaWVsZFdvcmRdICYgfigxIDw8IChOVU1CRVJfT0ZfQklUX0lOX1dPUkQtMSAtIG51bUJpdGZpZWxkQml0KSk7CgogIC8qIHN3aXRjaCBvZmYgc3RhdGUgbWFjaGluZSBiZWNhdXNlIGNvZGV3b3JkIGlzIGRlY29kZWQgYW5kL29yIGJlY2F1c2Ugc2VnbWVudCBpcyBlbXB0eSAqLwogICpwdHJTdGF0ZSA9IE5VTEw7Cn0KCgoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHN0YXRlcyBvZiB0aGUgc3RhdGVtYWNoaW5lCiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICBkZXNjcmlwdGlvbjogIERlY29kZXMgdGhlIGJvZHkgb2YgYSBjb2Rld29yZC4gVGhpcyBTdGF0ZSBpcyB1c2VkIGZvciBjb2RlYm9va3MgMSwyLDUgYW5kIDYuCiAgICAgICAgICAgICAgICAgICBObyBzaWduIGJpdHMgYXJlIGRlY29kZWQsIGJlY2F1c2UgdGhlIHRhYmxlIG9mIHRoZSBxdWFudGl6ZWQgc3BlY3RyYWwgdmFsdWVzCiAgICAgICAgICAgICAgICAgICBoYXMgZ290IGEgdmFsaWQgc2lnbiBhdCB0aGUgcXVhbnRpemVkIHNwZWN0cmFsIGxpbmVzLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIG91dHB1dDogICBUd28gb3IgZm91ciBxdWFudGl6ZXMgc3BlY3RyYWwgdmFsdWVzIHdyaXR0ZW4gYXQgcG9zaXRpb24gd2hlcmUgcFJlc3VsdFBvaW50cgogICAgICAgICAgICAgICAgICBwb2ludHMgdG8KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICByZXR1cm46ICAgMAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwpVSU5UIEhjcl9TdGF0ZV9CT0RZX09OTFkoSEFORExFX0ZES19CSVRTVFJFQU0gYnMsIHZvaWQgKnB0cikKewogIEhfSENSX0lORk8gcEhjciA9IChIX0hDUl9JTkZPKXB0cjsKICBVSU5UICAgICAgICAqcFNlZ21lbnRCaXRmaWVsZDsKICBVSU5UICAgICAgICAqcENvZGV3b3JkQml0ZmllbGQ7CiAgVUlOVCAgICAgICAgIHNlZ21lbnRPZmZzZXQ7CiAgRklYUF9EQkwgICAgKnBSZXN1bHRCYXNlOwogIFVJTlQgICAgICAgICppTm9kZTsKICBVU0hPUlQgICAgICAqaVJlc3VsdFBvaW50ZXI7CiAgVUlOVCAgICAgICAgIGNvZGV3b3JkT2Zmc2V0OwogIFVJTlQgICAgICAgICBicmFuY2hOb2RlOwogIFVJTlQgICAgICAgICBicmFuY2hWYWx1ZTsKICBVSU5UICAgICAgICAgaVFTQzsKICBVSU5UICAgICAgICAgdHJlZU5vZGU7CiAgVUNIQVIgICAgICAgIGNhcnJ5Qml0OwogIFVTSE9SVCAgICAgICpwTGVmdFN0YXJ0T2ZTZWdtZW50OwogIFVTSE9SVCAgICAgICpwUmlnaHRTdGFydE9mU2VnbWVudDsKICBTQ0hBUiAgICAgICAqcFJlbWFpbmluZ0JpdHNJblNlZ21lbnQ7CiAgVUNIQVIgICAgICAgIHJlYWREaXJlY3Rpb247CiAgVUNIQVIgICAgICAgKnBDb2RlYm9vazsKICBVQ0hBUiAgICAgICAgZGltQ250cjsKICBjb25zdCBVSU5UICAqcEN1cnJlbnRUcmVlOwogIGNvbnN0IFVDSEFSICpwQ2JEaW1lbnNpb247CiAgY29uc3QgU0NIQVIgKnBRdWFudFZhbDsKICBjb25zdCBTQ0hBUiAqcFF1YW50VmFsQmFzZTsKCiAgcFJlbWFpbmluZ0JpdHNJblNlZ21lbnQgPSBwSGNyLT5zZWdtZW50SW5mby5wUmVtYWluaW5nQml0c0luU2VnbWVudDsKICBwTGVmdFN0YXJ0T2ZTZWdtZW50ICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBMZWZ0U3RhcnRPZlNlZ21lbnQ7CiAgcFJpZ2h0U3RhcnRPZlNlZ21lbnQgICAgPSBwSGNyLT5zZWdtZW50SW5mby5wUmlnaHRTdGFydE9mU2VnbWVudDsKICByZWFkRGlyZWN0aW9uICAgICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnJlYWREaXJlY3Rpb247CiAgcFNlZ21lbnRCaXRmaWVsZCAgICAgICAgPSBwSGNyLT5zZWdtZW50SW5mby5wU2VnbWVudEJpdGZpZWxkOwogIHBDb2Rld29yZEJpdGZpZWxkICAgICAgID0gcEhjci0+c2VnbWVudEluZm8ucENvZGV3b3JkQml0ZmllbGQ7CiAgc2VnbWVudE9mZnNldCAgICAgICAgICAgPSBwSGNyLT5zZWdtZW50SW5mby5zZWdtZW50T2Zmc2V0OwoKICBwQ29kZWJvb2sgICAgICAgICAgICAgICA9IHBIY3ItPm5vblBjd1NpZGVpbmZvLnBDb2RlYm9vazsKICBpTm9kZSAgICAgICAgICAgICAgICAgICA9IHBIY3ItPm5vblBjd1NpZGVpbmZvLmlOb2RlOwogIHBSZXN1bHRCYXNlICAgICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8ucFJlc3VsdEJhc2U7CiAgaVJlc3VsdFBvaW50ZXIgICAgICAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5pUmVzdWx0UG9pbnRlcjsKICBjb2Rld29yZE9mZnNldCAgICAgICAgICA9IHBIY3ItPm5vblBjd1NpZGVpbmZvLmNvZGV3b3JkT2Zmc2V0OwoKICBwQ2JEaW1lbnNpb24gICAgICAgICAgICA9IHBIY3ItPnRhYmxlSW5mby5wQ2JEaW1lbnNpb247CgogIHRyZWVOb2RlICAgICAgICAgICAgICAgID0gaU5vZGVbY29kZXdvcmRPZmZzZXRdOwogIHBDdXJyZW50VHJlZSAgICAgICAgICAgID0gYUh1ZmZUYWJsZVtwQ29kZWJvb2tbY29kZXdvcmRPZmZzZXRdXTsKCgogIGZvciAoIDsgcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gPiAwIDsgcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gLT0gMSApIHsKCiAgICBjYXJyeUJpdCA9IEhjckdldEFCaXRGcm9tQml0c3RyZWFtKCBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBMZWZ0U3RhcnRPZlNlZ21lbnRbc2VnbWVudE9mZnNldF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwUmlnaHRTdGFydE9mU2VnbWVudFtzZWdtZW50T2Zmc2V0XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWREaXJlY3Rpb24pOwoKICAgIENhcnJ5Qml0VG9CcmFuY2hWYWx1ZShjYXJyeUJpdCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBtYWtlIGEgc3RlcCBpbiBkZWNvZGluZyB0cmVlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZU5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJmJyYW5jaFZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICZicmFuY2hOb2RlKTsKCiAgICAvKiBpZiBlbmQgb2YgYnJhbmNoIHJlYWNoZWQgd3JpdGUgb3V0IGxpbmVzIGFuZCBjb3VudCBiaXRzIG5lZWRlZCBmb3Igc2lnbiwgb3RoZXJ3aXNlIHN0b3JlIG5vZGUgaW4gY29kZXdvcmQgc2lkZWluZm8gKi8KICAgIGlmICgoYnJhbmNoTm9kZSAmIFRFU1RfQklUXzEwKSA9PSBURVNUX0JJVF8xMCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0ZXN0IGJpdCAxMCA7ID09PiBib2R5IGlzIGNvbXBsZXRlICovCiAgICAgIHBRdWFudFZhbEJhc2UgPSBhUXVhbnRUYWJsZVtwQ29kZWJvb2tbY29kZXdvcmRPZmZzZXRdXTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZ2V0IGJhc2UgYWRkcmVzcyBvZiBxdWFudGl6ZWQgdmFsdWVzIGJlbG9uZ2luZyB0byBjdXJyZW50IGNvZGVib29rICovCiAgICAgIHBRdWFudFZhbCA9IHBRdWFudFZhbEJhc2UgKyBicmFuY2hWYWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2V0IHBvaW50ZXIgdG8gZmlyc3QgdmFsaWQgbGluZSBbb2YgMiBvciA0IHF1YW50aXplZCB2YWx1ZXNdICovCgogICAgICBpUVNDID0gaVJlc3VsdFBvaW50ZXJbY29kZXdvcmRPZmZzZXRdOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZ2V0IHBvc2l0aW9uIG9mIGZpcnN0IGxpbmUgZm9yIHdyaXRpbmcgb3V0IHJlc3VsdCAqLwoKICAgICAgZm9yICggZGltQ250ciA9IHBDYkRpbWVuc2lvbltwQ29kZWJvb2tbY29kZXdvcmRPZmZzZXRdXTsgZGltQ250ciAhPSAwOyBkaW1DbnRyLS0gKSB7CiAgICAgICAgcFJlc3VsdEJhc2VbaVFTQysrXSA9IChGSVhQX0RCTCkqcFF1YW50VmFsKys7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHdyaXRlIG91dCAyIG9yIDQgbGluZXMgaW50byBzcGVjdHJ1bTsgbm8gU2lnbiBiaXRzIGF2YWlsYWJsZSBpbiB0aGlzIHN0YXRlICovCiAgICAgIH0KCiAgICAgIENsZWFyQml0RnJvbUJpdGZpZWxkKCYocEhjci0+bm9uUGN3U2lkZWluZm8ucFN0YXRlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VnbWVudE9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcENvZGV3b3JkQml0ZmllbGQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjbGVhciBhIGJpdCBpbiBiaXRmaWVsZCBhbmQgc3dpdGNoIG9mZiBzdGF0ZW1hY2hpbmUgKi8KICAgICAgcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gLT0gMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBsYXN0IHJlaW5pdGlhbHphdGlvbiBvZiBmb3IgbG9vcCBjb3VudGVyIChzZWUgYWJvdmUpIGlzIGRvbmUgaGVyZSAqLwogICAgICBicmVhazsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBvZiBicmFuY2ggaW4gdHJlZSByZWFjaGVkICBpLmUuIGEgd2hvbGUgbm9uUENXLUJvZHkgaXMgZGVjb2RlZCAqLwogICAgfQogICAgZWxzZSB7IC8qIGJvZHkgaXMgbm90IGRlY29kZWQgY29tcGxldGVseTogKi8KICAgICAgdHJlZU5vZGUgPSAqKHBDdXJyZW50VHJlZSArIGJyYW5jaFZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB1cGRhdGUgdHJlZU5vZGUgZm9yIGZ1cnRoZXIgc3RlcCBpbiBkZWNvZGluZyB0cmVlICovCiAgICB9CiAgfQogIGlOb2RlW2NvZGV3b3JkT2Zmc2V0XSA9IHRyZWVOb2RlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHN0b3JlIHVwZGF0ZWQgdHJlZU5vZGUgYmVjYXVzZSBtYXliZSBkZWNvZGluZyBvZiBjb2Rld29yZCBib2R5IG5vdCBmaW5pc2hlZCB5ZXQgKi8KCiAgaWYgKCBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSA8PSAwICkgewogICAgQ2xlYXJCaXRGcm9tQml0ZmllbGQoJihwSGNyLT5ub25QY3dTaWRlaW5mby5wU3RhdGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgc2VnbWVudE9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgIHBTZWdtZW50Qml0ZmllbGQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjbGVhciBhIGJpdCBpbiBiaXRmaWVsZCBhbmQgc3dpdGNoIG9mZiBzdGF0ZW1hY2hpbmUgKi8KCiNpZiBTVEFURV9NQUNISU5FX0VSUk9SX0NIRUNLCiAgICBpZiAoIHBSZW1haW5pbmdCaXRzSW5TZWdtZW50W3NlZ21lbnRPZmZzZXRdIDwgMCApIHsKICAgICAgcEhjci0+ZGVjSW5PdXQuZXJyb3JMb2cgfD0gU1RBVEVfRVJST1JfQk9EWV9PTkxZOwogICAgICByZXR1cm4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT0RZX09OTFk7CiAgICB9CiNlbmRpZgogIH0KCiAgcmV0dXJuIFNUT1BfVEhJU19TVEFURTsKfQoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgZGVzY3JpcHRpb246IERlY29kZXMgdGhlIGNvZGV3b3JkIGJvZHksIHdyaXRlcyBvdXQgcmVzdWx0IGFuZCBjb3VudHMgdGhlIG51bWJlciBvZiBxdWFudGl6ZWQKICAgICAgICAgICAgICAgICAgc3BlY3RyYWwgdmFsdWVzLCB3aGljaCBhcmUgZGlmZmVyZW50IGZvcm0gemVyby4gRm9yIHRob3NlIHZhbHVlcyBzaWduIGJpdHMgYXJlCiAgICAgICAgICAgICAgICAgIG5lZWRlZC4KCiAgICAgICAgICAgICAgICAgIElmIHNpZ24gYml0IGNvdW50ZXIgY250U2lnbiBpcyBkaWZmZXJlbnQgZnJvbSB6ZXJvLCBzd2l0Y2ggdG8gbmV4dCBzdGF0ZSB0bwogICAgICAgICAgICAgICAgICBkZWNvZGUgc2lnbiBCaXRzIHRoZXJlLgogICAgICAgICAgICAgICAgICBJZiBzaWduIGJpdCBjb3VudGVyIGNudFNpZ24gaXMgemVybywgbm8gc2lnbiBiaXRzIGFyZSBuZWVkZWQgYW5kIGNvZGV3b3JkIGlzCiAgICAgICAgICAgICAgICAgIGRlY29kZWQuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgb3V0cHV0OiAgIFR3byBvciBmb3VyIHdyaXR0ZW4gcXVhbnRpemVzIHNwZWN0cmFsIHZhbHVlcyB3cml0dGVuIGF0IHBvc2l0aW9uIHdoZXJlCiAgICAgICAgICAgICAgICAgIHBSZXN1bHRQb2ludHIgcG9pbnRzIHRvLiBUaGUgc2lnbnMgb2YgdGhvc2UgbGluZXMgbWF5IGJlIHdyb25nLiBJZiB0aGUgc2lnbnMKICAgICAgICAgICAgICAgICAgW29uIGp1c3Qgb25lIHNpZ25sZSBzaWduXSBpcyB3cm9uZywgdGhlIG5leHQgc3RhdGUgd2lsbCBjb3JyZWN0IGl0LgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIHJldHVybjogICAwCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovClVJTlQgSGNyX1N0YXRlX0JPRFlfU0lHTl9fQk9EWShIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywgdm9pZCAqcHRyKQp7CiAgSF9IQ1JfSU5GTyBwSGNyID0gKEhfSENSX0lORk8pcHRyOwogIFNDSEFSICAgICAgICpwUmVtYWluaW5nQml0c0luU2VnbWVudDsKICBVU0hPUlQgICAgICAqcExlZnRTdGFydE9mU2VnbWVudDsKICBVU0hPUlQgICAgICAqcFJpZ2h0U3RhcnRPZlNlZ21lbnQ7CiAgVUNIQVIgICAgICAgIHJlYWREaXJlY3Rpb247CiAgVUlOVCAgICAgICAgKnBTZWdtZW50Qml0ZmllbGQ7CiAgVUlOVCAgICAgICAgKnBDb2Rld29yZEJpdGZpZWxkOwogIFVJTlQgICAgICAgICBzZWdtZW50T2Zmc2V0OwoKICBVQ0hBUiAgICAgICAqcENvZGVib29rOwogIFVJTlQgICAgICAgICppTm9kZTsKICBVQ0hBUiAgICAgICAqcENudFNpZ247CiAgRklYUF9EQkwgICAgKnBSZXN1bHRCYXNlOwogIFVTSE9SVCAgICAgICppUmVzdWx0UG9pbnRlcjsKICBVSU5UICAgICAgICAgY29kZXdvcmRPZmZzZXQ7CgogIFVJTlQgICAgICAgICBpUVNDOwogIFVJTlQgICAgICAgICBjbnRTaWduOwogIFVDSEFSICAgICAgICBkaW1DbnRyOwogIFVDSEFSICAgICAgICBjYXJyeUJpdDsKICBTQ0hBUiAgICAgICAqcFN0YTsKICBVSU5UICAgICAgICAgdHJlZU5vZGU7CiAgVUlOVCAgICAgICAgIGJyYW5jaFZhbHVlOwogIFVJTlQgICAgICAgICBicmFuY2hOb2RlOwogIGNvbnN0IFVDSEFSICpwQ2JEaW1lbnNpb247CiAgY29uc3QgVUlOVCAgKnBDdXJyZW50VHJlZTsKICBjb25zdCBTQ0hBUiAqcFF1YW50VmFsQmFzZTsKICBjb25zdCBTQ0hBUiAqcFF1YW50VmFsOwoKICBwUmVtYWluaW5nQml0c0luU2VnbWVudCAgICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBSZW1haW5pbmdCaXRzSW5TZWdtZW50OwogIHBMZWZ0U3RhcnRPZlNlZ21lbnQgICAgICAgICAgICAgID0gcEhjci0+c2VnbWVudEluZm8ucExlZnRTdGFydE9mU2VnbWVudDsKICBwUmlnaHRTdGFydE9mU2VnbWVudCAgICAgICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBSaWdodFN0YXJ0T2ZTZWdtZW50OwogIHJlYWREaXJlY3Rpb24gICAgICAgICAgICAgICAgICAgID0gcEhjci0+c2VnbWVudEluZm8ucmVhZERpcmVjdGlvbjsKICBwU2VnbWVudEJpdGZpZWxkICAgICAgICAgICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBTZWdtZW50Qml0ZmllbGQ7CiAgcENvZGV3b3JkQml0ZmllbGQgICAgICAgICAgICAgICAgPSBwSGNyLT5zZWdtZW50SW5mby5wQ29kZXdvcmRCaXRmaWVsZDsKICBzZWdtZW50T2Zmc2V0ICAgICAgICAgICAgICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnNlZ21lbnRPZmZzZXQ7CgogIHBDb2RlYm9vayAgICAgICAgICAgICAgICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8ucENvZGVib29rOwogIGlOb2RlICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8uaU5vZGU7CiAgcENudFNpZ24gICAgICAgICAgICAgICAgICAgICAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5wQ250U2lnbjsKICBwUmVzdWx0QmFzZSAgICAgICAgICAgICAgICAgICAgICA9IHBIY3ItPm5vblBjd1NpZGVpbmZvLnBSZXN1bHRCYXNlOwogIGlSZXN1bHRQb2ludGVyICAgICAgICAgICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8uaVJlc3VsdFBvaW50ZXI7CiAgY29kZXdvcmRPZmZzZXQgICAgICAgICAgICAgICAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5jb2Rld29yZE9mZnNldDsKICBwU3RhICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IHBIY3ItPm5vblBjd1NpZGVpbmZvLnBTdGE7CgogIHBDYkRpbWVuc2lvbiAgICAgICAgICAgICAgICAgICAgID0gcEhjci0+dGFibGVJbmZvLnBDYkRpbWVuc2lvbjsKCiAgdHJlZU5vZGUgICAgICAgICAgICAgICAgICAgICAgICAgPSBpTm9kZVtjb2Rld29yZE9mZnNldF07CiAgcEN1cnJlbnRUcmVlICAgICAgICAgICAgICAgICAgICAgPSBhSHVmZlRhYmxlW3BDb2RlYm9va1tjb2Rld29yZE9mZnNldF1dOwoKCiAgZm9yICggOyBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSA+IDAgOyBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSAtPSAxICkgewoKICAgIGNhcnJ5Qml0ID0gSGNyR2V0QUJpdEZyb21CaXRzdHJlYW0oIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcExlZnRTdGFydE9mU2VnbWVudFtzZWdtZW50T2Zmc2V0XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBSaWdodFN0YXJ0T2ZTZWdtZW50W3NlZ21lbnRPZmZzZXRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZERpcmVjdGlvbik7CgogICAgQ2FycnlCaXRUb0JyYW5jaFZhbHVlKGNhcnJ5Qml0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG1ha2UgYSBzdGVwIGluIGRlY29kaW5nIHRyZWUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlTm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAmYnJhbmNoVmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJmJyYW5jaE5vZGUpOwoKICAgIC8qIGlmIGVuZCBvZiBicmFuY2ggcmVhY2hlZCB3cml0ZSBvdXQgbGluZXMgYW5kIGNvdW50IGJpdHMgbmVlZGVkIGZvciBzaWduLCBvdGhlcndpc2Ugc3RvcmUgbm9kZSBpbiBjb2Rld29yZCBzaWRlaW5mbyAqLwogICAgaWYgKChicmFuY2hOb2RlICYgVEVTVF9CSVRfMTApID09IFRFU1RfQklUXzEwKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRlc3QgYml0IDEwIDsgaWYgc2V0IGJvZHkgY29tcGxldGUgKi8KICAgICAgLyogYm9keSBjb21wbGV0ZWx5IGRlY29kZWQ7IGJyYW5jaFZhbHVlIGlzIHZhbGlkLCBzZXQgcFF1YW50VmFsIHRvIGZpcnN0IChvZiB0d28gb3IgZm91cikgcXVhbnRpemVkIHNwZWN0cmFsIGNvZWZmaWNpZW50cyAqLwogICAgICBwUXVhbnRWYWxCYXNlID0gYVF1YW50VGFibGVbcENvZGVib29rW2NvZGV3b3JkT2Zmc2V0XV07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGdldCBiYXNlIGFkZHJlc3Mgb2YgcXVhbnRpemVkIHZhbHVlcyBiZWxvbmdpbmcgdG8gY3VycmVudCBjb2RlYm9vayAqLwogICAgICBwUXVhbnRWYWwgPSBwUXVhbnRWYWxCYXNlICsgYnJhbmNoVmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNldCBwb2ludGVyIHRvIGZpcnN0IHZhbGlkIGxpbmUgW29mIDIgb3IgNCBxdWFudGl6ZWQgdmFsdWVzXSAqLwoKICAgICAgaVFTQyA9IGlSZXN1bHRQb2ludGVyW2NvZGV3b3JkT2Zmc2V0XTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBnZXQgcG9zaXRpb24gb2YgZmlyc3QgbGluZSBmb3Igd3JpdGluZyByZXN1bHQgKi8KCiAgICAgIC8qIGNvZGV3b3JkIGRlY29kaW5nIHJlc3VsdCBpcyB3cml0dGVuIG91dCBoZXJlOiBXcml0ZSBvdXQgMiBvciA0IHF1YW50aXplZCBzcGVjdHJhbCB2YWx1ZXMgd2l0aCBwcm9iYWJseSAqLwogICAgICAvKiB3cm9uZyBzaWduIGFuZCBjb3VudCBudW1iZXIgb2YgdmFsdWVzIHdoaWNoIGFyZSBkaWZmZXJlbnQgZnJvbSB6ZXJvIGZvciBzaWduIGJpdCBkZWNvZGluZyBbd2hpY2ggaGFwcGVucyBpbiBuZXh0IHN0YXRlXSAqLwogICAgICBjbnRTaWduID0gMDsKICAgICAgZm9yICggZGltQ250ciA9IHBDYkRpbWVuc2lvbltwQ29kZWJvb2tbY29kZXdvcmRPZmZzZXRdXTsgZGltQ250ciAhPSAwOyBkaW1DbnRyLS0gKSB7CiAgICAgICAgcFJlc3VsdEJhc2VbaVFTQysrXSA9IChGSVhQX0RCTCkqcFF1YW50VmFsOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHdyaXRlIHF1YW50LiBzcGVjLiBjb2VmLiBpbnRvIHNwZWN0cnVtICovCiAgICAgICAgaWYgKCAqcFF1YW50VmFsKysgIT0gMCApIHsKICAgICAgICAgIGNudFNpZ24gKz0gMTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmICggY250U2lnbiA9PSAwICkgewogICAgICAgIENsZWFyQml0RnJvbUJpdGZpZWxkKCYocEhjci0+bm9uUGN3U2lkZWluZm8ucFN0YXRlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWdtZW50T2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDb2Rld29yZEJpdGZpZWxkKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNsZWFyIGEgYml0IGluIGJpdGZpZWxkIGFuZCBzd2l0Y2ggb2ZmIHN0YXRlbWFjaGluZSAqLwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIHBDbnRTaWduW2NvZGV3b3JkT2Zmc2V0XSA9IGNudFNpZ247ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHdyaXRlIHNpZ24gY291bnQgcmVzdWx0IGludG8gY29kZXdvcmRzaWRlaW5mbyBvZiBjdXJyZW50IGNvZGV3b3JkICovCiAgICAgICAgcFN0YVtjb2Rld29yZE9mZnNldF0gPSBCT0RZX1NJR05fX1NJR047ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY2hhbmdlIHN0YXRlICovCiAgICAgICAgcEhjci0+bm9uUGN3U2lkZWluZm8ucFN0YXRlID0gYVN0YXRlQ29uc3RhbnQyU3RhdGVbcFN0YVtjb2Rld29yZE9mZnNldF1dOyAgICAgICAgICAgLyogZ2V0IHN0YXRlIGZyb20gc2VwYXJhdGUgYXJyYXkgb2YgY3ctc2lkZWluZm8gKi8KICAgICAgfQogICAgICBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSAtPSAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxhc3QgcmVpbml0aWFsemF0aW9uIG9mIGZvciBsb29wIGNvdW50ZXIgKHNlZSBhYm92ZSkgaXMgZG9uZSBoZXJlICovCiAgICAgIGJyZWFrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIG9mIGJyYW5jaCBpbiB0cmVlIHJlYWNoZWQgIGkuZS4gYSB3aG9sZSBub25QQ1ctQm9keSBpcyBkZWNvZGVkICovCiAgICB9CiAgICBlbHNlIHsvKiBib2R5IGlzIG5vdCBkZWNvZGVkIGNvbXBsZXRlbHk6ICovCiAgICAgIHRyZWVOb2RlID0gKihwQ3VycmVudFRyZWUgKyBicmFuY2hWYWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdXBkYXRlIHRyZWVOb2RlIGZvciBmdXJ0aGVyIHN0ZXAgaW4gZGVjb2RpbmcgdHJlZSAqLwogICAgfQogIH0KICBpTm9kZVtjb2Rld29yZE9mZnNldF0gPSB0cmVlTm9kZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzdG9yZSB1cGRhdGVkIHRyZWVOb2RlIGJlY2F1c2UgbWF5YmUgZGVjb2Rpbmcgb2YgY29kZXdvcmQgYm9keSBub3QgZmluaXNoZWQgeWV0ICovCgogIGlmICggcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gPD0gMCApIHsKICAgIENsZWFyQml0RnJvbUJpdGZpZWxkKCYocEhjci0+bm9uUGN3U2lkZWluZm8ucFN0YXRlKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnRPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICBwU2VnbWVudEJpdGZpZWxkKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY2xlYXIgYSBiaXQgaW4gYml0ZmllbGQgYW5kIHN3aXRjaCBvZmYgc3RhdGVtYWNoaW5lICovCgojaWYgU1RBVEVfTUFDSElORV9FUlJPUl9DSEVDSwogICAgaWYgKCBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSA8IDAgKSB7CiAgICAgIHBIY3ItPmRlY0luT3V0LmVycm9yTG9nIHw9IFNUQVRFX0VSUk9SX0JPRFlfU0lHTl9fQk9EWTsKICAgICAgcmV0dXJuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9EWV9TSUdOX19CT0RZOwogICAgfQojZW5kaWYKICB9CgogIHJldHVybiBTVE9QX1RISVNfU1RBVEU7Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIGRlc2NyaXB0aW9uOiBUaGlzIHN0YXRlIGRlY29kZXMgdGhlIHNpZ24gYml0cyBiZWxvbmdpbmcgdG8gYSBjb2Rld29yZC4gVGhlIHN0YXRlIGlzIGNhbGxlZAogICAgICAgICAgICAgICAgICBhcyBvZnRlbiBpbiBkaWZmZXJlbnQgInRyaWFscyIgdW50aWwgcENudFNnbltjb2Rld29yZE9mZnNldF0gaXMgemVyby4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICBvdXRwdXQ6ICAgVGhlIHR3byBvciBmb3VyIHF1YW50aXplcyBzcGVjdHJhbCB2YWx1ZXMgKHdyaXR0ZW4gaW4gcHJldmlvdXMgc3RhdGUpIGhhdmUKICAgICAgICAgICAgICAgICAgbm93IHRoZSBjb3JyZWN0IHNpZ24uCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgcmV0dXJuOiAgIDAKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KVUlOVCBIY3JfU3RhdGVfQk9EWV9TSUdOX19TSUdOKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLCB2b2lkICpwdHIpCnsKICBIX0hDUl9JTkZPIHBIY3IgPSAoSF9IQ1JfSU5GTylwdHI7CiAgU0NIQVIgICAgICAgKnBSZW1haW5pbmdCaXRzSW5TZWdtZW50OwogIFVTSE9SVCAgICAgICpwTGVmdFN0YXJ0T2ZTZWdtZW50OwogIFVTSE9SVCAgICAgICpwUmlnaHRTdGFydE9mU2VnbWVudDsKICBVQ0hBUiAgICAgICAgcmVhZERpcmVjdGlvbjsKICBVSU5UICAgICAgICAqcFNlZ21lbnRCaXRmaWVsZDsKICBVSU5UICAgICAgICAqcENvZGV3b3JkQml0ZmllbGQ7CiAgVUlOVCAgICAgICAgIHNlZ21lbnRPZmZzZXQ7CgogIFVDSEFSICAgICAgICpwQ250U2lnbjsKICBGSVhQX0RCTCAgICAqcFJlc3VsdEJhc2U7CiAgVVNIT1JUICAgICAgKmlSZXN1bHRQb2ludGVyOwogIFVJTlQgICAgICAgICBjb2Rld29yZE9mZnNldDsKICBVQ0hBUiAgICAgICAgY2FycnlCaXQ7CiAgVUlOVCAgICAgICAgIGlRU0M7CiAgVUNIQVIgICAgICAgIGNudFNpZ247CgogIHBSZW1haW5pbmdCaXRzSW5TZWdtZW50ID0gcEhjci0+c2VnbWVudEluZm8ucFJlbWFpbmluZ0JpdHNJblNlZ21lbnQ7CiAgcExlZnRTdGFydE9mU2VnbWVudCAgICAgPSBwSGNyLT5zZWdtZW50SW5mby5wTGVmdFN0YXJ0T2ZTZWdtZW50OwogIHBSaWdodFN0YXJ0T2ZTZWdtZW50ICAgID0gcEhjci0+c2VnbWVudEluZm8ucFJpZ2h0U3RhcnRPZlNlZ21lbnQ7CiAgcmVhZERpcmVjdGlvbiAgICAgICAgICAgPSBwSGNyLT5zZWdtZW50SW5mby5yZWFkRGlyZWN0aW9uOwogIHBTZWdtZW50Qml0ZmllbGQgICAgICAgID0gcEhjci0+c2VnbWVudEluZm8ucFNlZ21lbnRCaXRmaWVsZDsKICBwQ29kZXdvcmRCaXRmaWVsZCAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBDb2Rld29yZEJpdGZpZWxkOwogIHNlZ21lbnRPZmZzZXQgICAgICAgICAgID0gcEhjci0+c2VnbWVudEluZm8uc2VnbWVudE9mZnNldDsKCiAgcENudFNpZ24gICAgICAgICAgICAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5wQ250U2lnbjsKICBwUmVzdWx0QmFzZSAgICAgICAgICAgICA9IHBIY3ItPm5vblBjd1NpZGVpbmZvLnBSZXN1bHRCYXNlOwogIGlSZXN1bHRQb2ludGVyICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8uaVJlc3VsdFBvaW50ZXI7CiAgY29kZXdvcmRPZmZzZXQgICAgICAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5jb2Rld29yZE9mZnNldDsKICBpUVNDICAgICAgICAgICAgICAgICAgICA9IGlSZXN1bHRQb2ludGVyW2NvZGV3b3JkT2Zmc2V0XTsKICBjbnRTaWduICAgICAgICAgICAgICAgICA9IHBDbnRTaWduW2NvZGV3b3JkT2Zmc2V0XTsKCgoKICAvKiBsb29wIGZvciBzaWduIGJpdCBkZWNvZGluZyAqLwogIGZvciAoIDsgcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gPiAwIDsgcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gLT0gMSApIHsKCiAgICBjYXJyeUJpdCA9IEhjckdldEFCaXRGcm9tQml0c3RyZWFtKCBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBMZWZ0U3RhcnRPZlNlZ21lbnRbc2VnbWVudE9mZnNldF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwUmlnaHRTdGFydE9mU2VnbWVudFtzZWdtZW50T2Zmc2V0XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWREaXJlY3Rpb24pOwogICAgY250U2lnbiAtPSAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRlY3JlbWVudCBzaWduIGNvdW50ZXIgYmVjYXVzZSBvbmUgc2lnbiBiaXQgaGFzIGJlZW4gcmVhZCAqLwoKICAgIC8qIHNlYXJjaCBmb3IgYSBsaW5lICh3aGljaCB3YXMgZGVjb2RlZCBpbiBwcmV2aW91cyBzdGF0ZSkgd2hpY2ggaXMgbm90IHplcm8uIFtUaGlzIHZhbHVlIHdpbGwgZ2V0IGEgc2lnbl0gKi8KICAgIHdoaWxlICggcFJlc3VsdEJhc2VbaVFTQ10gPT0gKEZJWFBfREJMKTAgKSB7CiAgICAgIGlRU0MrKzsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogcG9pbnRzIHRvIGN1cnJlbnQgdmFsdWUgZGlmZmVyZW50IGZyb20gemVybyAqLwogICAgICBpZiAoaVFTQyA+PSAxMDI0KSB7CiAgICAgICAgcmV0dXJuIEJPRFlfU0lHTl9fU0lHTjsKICAgICAgfQogICAgfQoKICAgIC8qIHB1dCBzaWduIHRvZ2V0aGVyIHdpdGggbGluZTsgaWYgY2FycnlCaXQgaXMgemVybywgdGhlIHNpZ24gaXMgb2sgYWxyZWFkeTsgbm8gd3JpdGUgb3BlcmF0aW9uIG5lY2Vzc2FyeSBpbiB0aGlzIGNhc2UgKi8KICAgIGlmICggY2FycnlCaXQgIT0gMCApIHsKICAgICAgcFJlc3VsdEJhc2VbaVFTQ10gPSAtcFJlc3VsdEJhc2VbaVFTQ107ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjYXJyeUJpdCA9IDEgLS0+IG1pbnVzICovCiAgICB9CgogICAgaVFTQysrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHVwZGF0ZSBwb2ludGVyIHRvIG5leHQgKG1heWJlIHZhbGlkKSB2YWx1ZSAqLwoKICAgIGlmICggY250U2lnbiA9PSAwICkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpZiAoY250U2lnbj09MCkgID09PiAgc2V0IHN0YXRlIENPREVXT1JEX0RFQ09ERUQgKi8KICAgICAgQ2xlYXJCaXRGcm9tQml0ZmllbGQoJihwSGNyLT5ub25QY3dTaWRlaW5mby5wU3RhdGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZWdtZW50T2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBwQ29kZXdvcmRCaXRmaWVsZCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNsZWFyIGEgYml0IGluIGJpdGZpZWxkIGFuZCBzd2l0Y2ggb2ZmIHN0YXRlbWFjaGluZSAqLwogICAgICBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSAtPSAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxhc3QgcmVpbml0aWFsemF0aW9uIG9mIGZvciBsb29wIGNvdW50ZXIgKHNlZSBhYm92ZSkgaXMgZG9uZSBoZXJlICovCiAgICAgIGJyZWFrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogd2hvbGUgbm9uUENXLUJvZHkgYW5kIGFjY29yZGluZyBzaWduIGJpdHMgYXJlIGRlY29kZWQgKi8KICAgICB9CiAgfQogIHBDbnRTaWduW2NvZGV3b3JkT2Zmc2V0XSA9IGNudFNpZ247CiAgaVJlc3VsdFBvaW50ZXJbY29kZXdvcmRPZmZzZXRdID0gaVFTQzsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3RvcmUgdXBkYXRlZCBwUmVzdWx0UG9pbnRlciAqLwoKICBpZiAoIHBSZW1haW5pbmdCaXRzSW5TZWdtZW50W3NlZ21lbnRPZmZzZXRdIDw9IDAgKSB7CiAgICBDbGVhckJpdEZyb21CaXRmaWVsZCgmKHBIY3ItPm5vblBjd1NpZGVpbmZvLnBTdGF0ZSksCiAgICAgICAgICAgICAgICAgICAgICAgICBzZWdtZW50T2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgcFNlZ21lbnRCaXRmaWVsZCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNsZWFyIGEgYml0IGluIGJpdGZpZWxkIGFuZCBzd2l0Y2ggb2ZmIHN0YXRlbWFjaGluZSAqLwoKI2lmIFNUQVRFX01BQ0hJTkVfRVJST1JfQ0hFQ0sKICAgIGlmICggcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gPCAwICkgewogICAgICBwSGNyLT5kZWNJbk91dC5lcnJvckxvZyB8PSBTVEFURV9FUlJPUl9CT0RZX1NJR05fX1NJR047CiAgICAgIHJldHVybiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPRFlfU0lHTl9fU0lHTjsKICAgIH0KI2VuZGlmCiAgfQoKICByZXR1cm4gU1RPUF9USElTX1NUQVRFOwp9CgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICBkZXNjcmlwdGlvbjogRGVjb2RlcyB0aGUgY29kZXdvcmQgYm9keSBpbiBjYXNlIG9mIGNvZGVib29rIGlzIDExLiBXcml0ZXMgb3V0IHJlc3VsdGluZwogICAgICAgICAgICAgICAgICB0d28gb3IgZm91ciBsaW5lcyBbd2l0aCBwcm9iYWJseSB3cm9uZyBzaWduXSBhbmQgY291bnRzIHRoZSBudW1iZXIgb2YKICAgICAgICAgICAgICAgICAgbGluZXMsIHdoaWNoIGFyZSBkaWZmZXJlbnQgZm9ybSB6ZXJvLiBUaGlzIGluZm9ybWF0aW9uIGlzIG5lZWRlZCBpbiBuZXh0CiAgICAgICAgICAgICAgICAgIHN0YXRlIHdoZXJlIHNpZ24gYml0cyB3aWxsIGJlIGRlY29kZWQsIGlmIG5lY2Vzc2FyeS4KICAgICAgICAgICAgICAgICAgSWYgc2lnbiBiaXQgY291bnRlciBjbnRTaWduIGlzIHplcm8sIG5vIHNpZ24gYml0cyBhcmUgbmVlZGVkIGFuZCBjb2Rld29yZCBpcwogICAgICAgICAgICAgICAgICBkZWNvZGVkIGNvbXBsZXRlbHkuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgb3V0cHV0OiAgIFR3byBsaW5lcyAocXVhbnRpemVzIHNwZWN0cmFsIGNvZWZmaWNpZW50cykgd2hpY2ggYXJlIHByb2JhYmx5IHdyb25nLiBUaGUKICAgICAgICAgICAgICAgICAgc2lnbiBtYXkgYmUgd3JvbmcgYW5kIGlmIG9uZSBvciB0d28gdmFsdWVzIGlzL2FyZSAxNiwgdGhlIGZvbGxvd2luZyBzdGF0ZXMKICAgICAgICAgICAgICAgICAgd2lsbCBkZWNvZGUgdGhlIGVzY2FwZSBzZXF1ZW5jZSB0byBjb3JyZWN0IHRoZSB2YWx1ZXMgd2hpY2ggYXJlIHdpcnR0ZW4gaGVyZS4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICByZXR1cm46ICAgMAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwpVSU5UIEhjcl9TdGF0ZV9CT0RZX1NJR05fRVNDX19CT0RZKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLCB2b2lkICpwdHIpCnsKICBIX0hDUl9JTkZPIHBIY3IgPSAoSF9IQ1JfSU5GTylwdHI7CiAgU0NIQVIgICAgICAgKnBSZW1haW5pbmdCaXRzSW5TZWdtZW50OwogIFVTSE9SVCAgICAgICpwTGVmdFN0YXJ0T2ZTZWdtZW50OwogIFVTSE9SVCAgICAgICpwUmlnaHRTdGFydE9mU2VnbWVudDsKICBVQ0hBUiAgICAgICAgcmVhZERpcmVjdGlvbjsKICBVSU5UICAgICAgICAqcFNlZ21lbnRCaXRmaWVsZDsKICBVSU5UICAgICAgICAqcENvZGV3b3JkQml0ZmllbGQ7CiAgVUlOVCAgICAgICAgIHNlZ21lbnRPZmZzZXQ7CgogIFVJTlQgICAgICAgICppTm9kZTsKICBVQ0hBUiAgICAgICAqcENudFNpZ247CiAgRklYUF9EQkwgICAgKnBSZXN1bHRCYXNlOwogIFVTSE9SVCAgICAgICppUmVzdWx0UG9pbnRlcjsKICBVSU5UICAgICAgICAgY29kZXdvcmRPZmZzZXQ7CgogIFVDSEFSICAgICAgICBjYXJyeUJpdDsKICBVSU5UICAgICAgICAgaVFTQzsKICBVSU5UICAgICAgICAgY250U2lnbjsKICBVSU5UICAgICAgICAgZGltQ250cjsKICBVSU5UICAgICAgICAgdHJlZU5vZGU7CiAgU0NIQVIgICAgICAgKnBTdGE7CiAgVUlOVCAgICAgICAgIGJyYW5jaE5vZGU7CiAgVUlOVCAgICAgICAgIGJyYW5jaFZhbHVlOwogIGNvbnN0IFVJTlQgICpwQ3VycmVudFRyZWU7CiAgY29uc3QgU0NIQVIgKnBRdWFudFZhbEJhc2U7CiAgY29uc3QgU0NIQVIgKnBRdWFudFZhbDsKCiAgcFJlbWFpbmluZ0JpdHNJblNlZ21lbnQgPSBwSGNyLT5zZWdtZW50SW5mby5wUmVtYWluaW5nQml0c0luU2VnbWVudDsKICBwTGVmdFN0YXJ0T2ZTZWdtZW50ICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBMZWZ0U3RhcnRPZlNlZ21lbnQ7CiAgcFJpZ2h0U3RhcnRPZlNlZ21lbnQgICAgPSBwSGNyLT5zZWdtZW50SW5mby5wUmlnaHRTdGFydE9mU2VnbWVudDsKICByZWFkRGlyZWN0aW9uICAgICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnJlYWREaXJlY3Rpb247CiAgcFNlZ21lbnRCaXRmaWVsZCAgICAgICAgPSBwSGNyLT5zZWdtZW50SW5mby5wU2VnbWVudEJpdGZpZWxkOwogIHBDb2Rld29yZEJpdGZpZWxkICAgICAgID0gcEhjci0+c2VnbWVudEluZm8ucENvZGV3b3JkQml0ZmllbGQ7CiAgc2VnbWVudE9mZnNldCAgICAgICAgICAgPSBwSGNyLT5zZWdtZW50SW5mby5zZWdtZW50T2Zmc2V0OwoKICBpTm9kZSAgICAgICAgICAgICAgICAgICA9IHBIY3ItPm5vblBjd1NpZGVpbmZvLmlOb2RlOwogIHBDbnRTaWduICAgICAgICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8ucENudFNpZ247CiAgcFJlc3VsdEJhc2UgICAgICAgICAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5wUmVzdWx0QmFzZTsKICBpUmVzdWx0UG9pbnRlciAgICAgICAgICA9IHBIY3ItPm5vblBjd1NpZGVpbmZvLmlSZXN1bHRQb2ludGVyOwogIGNvZGV3b3JkT2Zmc2V0ICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8uY29kZXdvcmRPZmZzZXQ7CiAgcFN0YSAgICAgICAgICAgICAgICAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5wU3RhOwoKICB0cmVlTm9kZSAgICAgICAgICAgICAgICA9IGlOb2RlW2NvZGV3b3JkT2Zmc2V0XTsKICBwQ3VycmVudFRyZWUgICAgICAgICAgICA9IGFIdWZmVGFibGVbRVNDQVBFX0NPREVCT09LXTsKCgogIGZvciAoIDsgcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gPiAwIDsgcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gLT0gMSApIHsKCiAgICBjYXJyeUJpdCA9IEhjckdldEFCaXRGcm9tQml0c3RyZWFtKCBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBMZWZ0U3RhcnRPZlNlZ21lbnRbc2VnbWVudE9mZnNldF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwUmlnaHRTdGFydE9mU2VnbWVudFtzZWdtZW50T2Zmc2V0XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWREaXJlY3Rpb24pOwoKICAgIC8qIG1ha2UgYSBzdGVwIGluIHRyZWUgKi8KICAgIENhcnJ5Qml0VG9CcmFuY2hWYWx1ZShjYXJyeUJpdCwKICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlTm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAmYnJhbmNoVmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJmJyYW5jaE5vZGUpOwoKICAgIC8qIGlmIGVuZCBvZiBicmFuY2ggcmVhY2hlZCB3cml0ZSBvdXQgbGluZXMgYW5kIGNvdW50IGJpdHMgbmVlZGVkIGZvciBzaWduLCBvdGhlcndpc2Ugc3RvcmUgbm9kZSBpbiBjb2Rld29yZCBzaWRlaW5mbyAqLwogICAgaWYgKChicmFuY2hOb2RlICYgVEVTVF9CSVRfMTApID09IFRFU1RfQklUXzEwKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRlc3QgYml0IDEwIDsgaWYgc2V0IGJvZHkgY29tcGxldGUgKi8KCiAgICAgIC8qIGJvZHkgY29tcGxldGVseSBkZWNvZGVkOyBicmFuY2hWYWx1ZSBpcyB2YWxpZCAqLwogICAgICAvKiBzZXQgcFF1YW50Vm9sIHRvIGZpcnN0IChvZiB0d28gb3IgZm91cikgcXVhbnRpemVkIHNwZWN0cmFsIGNvZWZmaWNpZW50cyAqLwogICAgICBwUXVhbnRWYWxCYXNlID0gYVF1YW50VGFibGVbRVNDQVBFX0NPREVCT09LXTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZ2V0IGJhc2UgYWRkcmVzcyBvZiBxdWFudGl6ZWQgdmFsdWVzIGJlbG9uZ2luZyB0byBjdXJyZW50IGNvZGVib29rICovCiAgICAgIHBRdWFudFZhbCA9IHBRdWFudFZhbEJhc2UgKyBicmFuY2hWYWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzZXQgcG9pbnRlciB0byBmaXJzdCB2YWxpZCBsaW5lIFtvZiAyIG9yIDQgcXVhbnRpemVkIHZhbHVlc10gKi8KCiAgICAgIC8qIG1ha2UgYmFja3VwIGZyb20gb3JpZ2luYWwgcmVzdWx0UG9pbnRlciBpbiBub2RlIHN0b3JhZ2UgZm9yIHN0YXRlIEJPRFlfU0lHTl9FU0NfX1NJR04gKi8KICAgICAgaU5vZGVbY29kZXdvcmRPZmZzZXRdID0gaVJlc3VsdFBvaW50ZXJbY29kZXdvcmRPZmZzZXRdOwoKICAgICAgLyogZ2V0IHBvc2l0aW9uIG9mIGZpcnN0IGxpbmUgZm9yIHdyaXRpbmcgcmVzdWx0ICovCiAgICAgIGlRU0MgPSBpUmVzdWx0UG9pbnRlcltjb2Rld29yZE9mZnNldF07CgogICAgICAvKiBjb2Rld29yZCBkZWNvZGluZyByZXN1bHQgaXMgd3JpdHRlbiBvdXQgaGVyZTogV3JpdGUgb3V0IDIgb3IgNCBxdWFudGl6ZWQgc3BlY3RyYWwgdmFsdWVzIHdpdGggcHJvYmFibHkgKi8KICAgICAgLyogd3Jvbmcgc2lnbiBhbmQgY291bnQgbnVtYmVyIG9mIHZhbHVlcyB3aGljaCBhcmUgZGlmZmVyZW50IGZyb20gemVybyBmb3Igc2lnbiBiaXQgZGVjb2RpbmcgW3doaWNoIGhhcHBlbnMgaW4gbmV4dCBzdGF0ZV0gKi8KICAgICAgY250U2lnbiA9IDA7CgogICAgICBmb3IgKCBkaW1DbnRyID0gRElNRU5TSU9OX09GX0VTQ0FQRV9DT0RFQk9PSzsgZGltQ250ciAhPSAwOyBkaW1DbnRyLS0gKSB7CiAgICAgICAgcFJlc3VsdEJhc2VbaVFTQysrXSA9IChGSVhQX0RCTCkqcFF1YW50VmFsOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHdyaXRlIHF1YW50LiBzcGVjLiBjb2VmLiBpbnRvIHNwZWN0cnVtICovCiAgICAgICAgaWYgKCAqcFF1YW50VmFsKysgIT0gMCApIHsKICAgICAgICAgIGNudFNpZ24gKz0gMTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmICggY250U2lnbiA9PSAwICkgewogICAgICAgIENsZWFyQml0RnJvbUJpdGZpZWxkKCYocEhjci0+bm9uUGN3U2lkZWluZm8ucFN0YXRlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWdtZW50T2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDb2Rld29yZEJpdGZpZWxkKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY2xlYXIgYSBiaXQgaW4gYml0ZmllbGQgYW5kIHN3aXRjaCBvZmYgc3RhdGVtYWNoaW5lICovCiAgICAgICAgLyogY29kZXdvcmQgZGVjb2RlZCAqLwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIC8qIHdyaXRlIHNpZ24gY291bnQgcmVzdWx0IGludG8gY29kZXdvcmRzaWRlaW5mbyBvZiBjdXJyZW50IGNvZGV3b3JkICovCiAgICAgICAgcENudFNpZ25bY29kZXdvcmRPZmZzZXRdID0gY250U2lnbjsKICAgICAgICBwU3RhW2NvZGV3b3JkT2Zmc2V0XSA9IEJPRFlfU0lHTl9FU0NfX1NJR047ICAgICAgICAgICAgICAgICAvKiBjaGFuZ2Ugc3RhdGUgKi8KICAgICAgICBwSGNyLT5ub25QY3dTaWRlaW5mby5wU3RhdGUgPSBhU3RhdGVDb25zdGFudDJTdGF0ZVtwU3RhW2NvZGV3b3JkT2Zmc2V0XV07ICAgICAgICAgICAvKiBnZXQgc3RhdGUgZnJvbSBzZXBhcmF0ZSBhcnJheSBvZiBjdy1zaWRlaW5mbyAqLwogICAgICB9CiAgICAgIHBSZW1haW5pbmdCaXRzSW5TZWdtZW50W3NlZ21lbnRPZmZzZXRdIC09IDE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdGhlIGxhc3QgcmVpbml0aWFsemF0aW9uIG9mIGZvciBsb29wIGNvdW50ZXIgKHNlZSBhYm92ZSkgaXMgZG9uZSBoZXJlICovCiAgICAgIGJyZWFrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIG9mIGJyYW5jaCBpbiB0cmVlIHJlYWNoZWQgIGkuZS4gYSB3aG9sZSBub25QQ1ctQm9keSBpcyBkZWNvZGVkICovCiAgICB9CiAgICBlbHNlIHsgLyogYm9keSBpcyBub3QgZGVjb2RlZCBjb21wbGV0ZWx5OiAqLwogICAgICAvKiB1cGRhdGUgdHJlZU5vZGUgZm9yIGZ1cnRoZXIgc3RlcCBpbiBkZWNvZGluZyB0cmVlIGFuZCBzdG9yZSB1cGRhdGVkIHRyZWVOb2RlIGJlY2F1c2UgbWF5YmUgbm8gbW9yZSBiaXRzIGxlZnQgaW4gc2VnbWVudCAqLwogICAgICB0cmVlTm9kZSA9ICoocEN1cnJlbnRUcmVlICsgYnJhbmNoVmFsdWUpOwogICAgICBpTm9kZVtjb2Rld29yZE9mZnNldF0gPSB0cmVlTm9kZTsKICAgIH0KICB9CgogIGlmICggcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gPD0gMCApIHsKICAgIENsZWFyQml0RnJvbUJpdGZpZWxkKCYocEhjci0+bm9uUGN3U2lkZWluZm8ucFN0YXRlKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnRPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICBwU2VnbWVudEJpdGZpZWxkKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNsZWFyIGEgYml0IGluIGJpdGZpZWxkIGFuZCBzd2l0Y2ggb2ZmIHN0YXRlbWFjaGluZSAqLwoKI2lmIFNUQVRFX01BQ0hJTkVfRVJST1JfQ0hFQ0sKICAgIGlmICggcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gPCAwICkgewogICAgICBwSGNyLT5kZWNJbk91dC5lcnJvckxvZyB8PSBTVEFURV9FUlJPUl9CT0RZX1NJR05fRVNDX19CT0RZOwogICAgICByZXR1cm4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT0RZX1NJR05fRVNDX19CT0RZOwogICAgfQojZW5kaWYKICB9CgogIHJldHVybiBTVE9QX1RISVNfU1RBVEU7Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIGRlc2NyaXB0aW9uOiBUaGlzIHN0YXRlIGRlY29kZXMgdGhlIHNpZ24gYml0cywgaWYgYSBjb2Rld29yZCBvZiBjb2RlYm9vayAxMSBuZWVkcyBzb21lLgogICAgICAgICAgICAgICAgICBBIGZsYWcgbmFtZWQgJ2ZsYWdCJyBpbiBjb2Rld29yZCBzaWRlaW5mbyBpcyBzZXQsIGlmIHRoZSBzZWNvbmQgbGluZSBvZgogICAgICAgICAgICAgICAgICBxdWFudGl6ZWQgc3BlY3RyYWwgdmFsdWVzIGlzIDE2LiBUaGUgJ2ZsYWdCJyBpcyB1c2VkIGluIGNhc2Ugb2YgZGVjb2RpbmcKICAgICAgICAgICAgICAgICAgb2YgYSBlc2NhcGUgc2VxdWVuY2UgaXMgbmVjZXNzYXJ5IGFzIGZhciBhcyB0aGUgc2Vjb25kIGxpbmUgaXMgY29uY2VybmVkLgoKICAgICAgICAgICAgICAgICAgSWYgb25seSB0aGUgZmlyc3QgbGluZSBuZWVkcyBhbiBlc2NhcGUgc2VxdWVuY2UsIHRoZSBmbGFnQiBpcyBjbGVhcmVkLgogICAgICAgICAgICAgICAgICBJZiBvbmx5IHRoZSBzZWNvbmQgbGluZSBuZWVkcyBhbiBlc2NhcGUgc2VxdWVuY2UsIHRoZSBmbGFnQiBpcyBub3QgdXNlZC4KCiAgICAgICAgICAgICAgICAgIEZvciBzdG9yaW5nIHNpZGVpbmZvIGluIGNhc2Ugb2YgZXNjYXBlIHNlcXVlbmNlIGRlY29kaW5nIG9uZSBzaW5nbGUgd29yZAogICAgICAgICAgICAgICAgICBjYW4gYmUgdXNlZCBmb3IgYm90aCBlc2NhcGUgc2VxdWVuY2VzIGJlY2F1c2UgdGhleSBhcmUgZGVjb2RlZCBub3QgYXQgdGhlCiAgICAgICAgICAgICAgICAgIHNhbWUgdGltZToKCgogICAgICAgICAgICAgICAgICBiaXQgMjMgMjIgMjEgMjAgMTkgMTggMTcgMTYgMTUgMTQgMTMgMTIgMTEgMTAgIDkgIDggIDcgIDYgIDUgIDQgIDMgIDIgIDEgIDAKICAgICAgICAgICAgICAgICAgICAgID09PT09ID09ID09ID09PT09PT09PT09ID09PT09PT09PT09ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAgICAgICAgICAgICAgICAgICBeICAgICAgXiAgXiAgICAgICAgIF4gICAgICAgICAgICBeICAgICAgICAgICAgICAgICAgICBeCiAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgfCAgfCAgICAgICAgIHwgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICB8CiAgICAgICAgICAgICAgICAgICAgcmVzLiBmbGFnQSAgZmxhZ0IgIGVzY2FwZVByZWZpeFVwICBlc2NhcGVQcmVmaXhEb3duICBlc2NhcGVXb3JkCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIG91dHB1dDogICBUd28gbGluZXMgd2l0aCBjb3JyZWN0IHNpZ24uIElmIG9uZSBvciB0d28gdmFsdWVzIGlzL2FyZSAxNiwgdGhlIGxpbmVzIGFyZQogICAgICAgICAgICAgICAgICBub3QgdmFsaWQsIG90aGVyd2lzZSB0aGV5IGFyZS4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICByZXR1cm46ICAgMAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwpVSU5UIEhjcl9TdGF0ZV9CT0RZX1NJR05fRVNDX19TSUdOKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLCB2b2lkICpwdHIpCnsKICBIX0hDUl9JTkZPIHBIY3IgPSAoSF9IQ1JfSU5GTylwdHI7CiAgU0NIQVIgICAgICpwUmVtYWluaW5nQml0c0luU2VnbWVudDsKICBVU0hPUlQgICAgKnBMZWZ0U3RhcnRPZlNlZ21lbnQ7CiAgVVNIT1JUICAgICpwUmlnaHRTdGFydE9mU2VnbWVudDsKICBVQ0hBUiAgICAgIHJlYWREaXJlY3Rpb247CiAgVUlOVCAgICAgICpwU2VnbWVudEJpdGZpZWxkOwogIFVJTlQgICAgICAqcENvZGV3b3JkQml0ZmllbGQ7CiAgVUlOVCAgICAgICBzZWdtZW50T2Zmc2V0OwoKICBVSU5UICAgICAgKmlOb2RlOwogIFVDSEFSICAgICAqcENudFNpZ247CiAgRklYUF9EQkwgICpwUmVzdWx0QmFzZTsKICBVU0hPUlQgICAgKmlSZXN1bHRQb2ludGVyOwogIFVJTlQgICAgICAqcEVzY2FwZVNlcXVlbmNlSW5mbzsKICBVSU5UICAgICAgIGNvZGV3b3JkT2Zmc2V0OwoKICBVSU5UICAgICAgIGlRU0M7CiAgVUNIQVIgICAgICBjbnRTaWduOwogIFVJTlQgICAgICAgZmxhZ0E7CiAgVUlOVCAgICAgICBmbGFnQjsKICBVSU5UICAgICAgIGZsYWdzOwogIFVDSEFSICAgICAgY2FycnlCaXQ7CiAgU0NIQVIgICAgICpwU3RhOwoKICBwUmVtYWluaW5nQml0c0luU2VnbWVudCA9IHBIY3ItPnNlZ21lbnRJbmZvLnBSZW1haW5pbmdCaXRzSW5TZWdtZW50OwogIHBMZWZ0U3RhcnRPZlNlZ21lbnQgICAgID0gcEhjci0+c2VnbWVudEluZm8ucExlZnRTdGFydE9mU2VnbWVudDsKICBwUmlnaHRTdGFydE9mU2VnbWVudCAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBSaWdodFN0YXJ0T2ZTZWdtZW50OwogIHJlYWREaXJlY3Rpb24gICAgICAgICAgID0gcEhjci0+c2VnbWVudEluZm8ucmVhZERpcmVjdGlvbjsKICBwU2VnbWVudEJpdGZpZWxkICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBTZWdtZW50Qml0ZmllbGQ7CiAgcENvZGV3b3JkQml0ZmllbGQgICAgICAgPSBwSGNyLT5zZWdtZW50SW5mby5wQ29kZXdvcmRCaXRmaWVsZDsKICBzZWdtZW50T2Zmc2V0ICAgICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnNlZ21lbnRPZmZzZXQ7CgogIGlOb2RlICAgICAgICAgICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8uaU5vZGU7CiAgcENudFNpZ24gICAgICAgICAgICAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5wQ250U2lnbjsKICBwUmVzdWx0QmFzZSAgICAgICAgICAgICA9IHBIY3ItPm5vblBjd1NpZGVpbmZvLnBSZXN1bHRCYXNlOwogIGlSZXN1bHRQb2ludGVyICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8uaVJlc3VsdFBvaW50ZXI7CiAgcEVzY2FwZVNlcXVlbmNlSW5mbyAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5wRXNjYXBlU2VxdWVuY2VJbmZvOwogIGNvZGV3b3JkT2Zmc2V0ICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8uY29kZXdvcmRPZmZzZXQ7CiAgcFN0YSAgICAgICAgICAgICAgICAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5wU3RhOwoKICBpUVNDICAgICAgICAgICAgICAgICAgICA9IGlSZXN1bHRQb2ludGVyW2NvZGV3b3JkT2Zmc2V0XTsKICBjbnRTaWduICAgICAgICAgICAgICAgICA9IHBDbnRTaWduW2NvZGV3b3JkT2Zmc2V0XTsKCgogIC8qIGxvb3AgZm9yIHNpZ24gYml0IGRlY29kaW5nICovCiAgZm9yICggOyBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSA+IDAgOyBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSAtPSAxICkgewoKICAgIGNhcnJ5Qml0ID0gSGNyR2V0QUJpdEZyb21CaXRzdHJlYW0oIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcExlZnRTdGFydE9mU2VnbWVudFtzZWdtZW50T2Zmc2V0XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBSaWdodFN0YXJ0T2ZTZWdtZW50W3NlZ21lbnRPZmZzZXRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZERpcmVjdGlvbik7CgogICAgLyogZGVjcmVtZW50IHNpZ24gY291bnRlciBiZWNhdXNlIG9uZSBzaWduIGJpdCBoYXMgYmVlbiByZWFkICovCiAgICBjbnRTaWduIC09IDE7CiAgICBwQ250U2lnbltjb2Rld29yZE9mZnNldF0gPSBjbnRTaWduOwoKICAgIC8qIGdldCBhIHF1YW50aXplZCBzcGVjdHJhbCB2YWx1ZSAod2hpY2ggd2FzIGRlY29kZWQgaW4gcHJldmlvdXMgc3RhdGUpIHdoaWNoIGlzIG5vdCB6ZXJvLiBbVGhpcyB2YWx1ZSB3aWxsIGdldCBhIHNpZ25dICovCiAgICB3aGlsZSAoIHBSZXN1bHRCYXNlW2lRU0NdID09IChGSVhQX0RCTCkwICkgewogICAgICBpUVNDKys7CiAgICB9CiAgICBpUmVzdWx0UG9pbnRlcltjb2Rld29yZE9mZnNldF0gPSBpUVNDOwoKICAgIC8qIHB1dCBuZWdhdGl2ZSBzaWduIHRvZ2V0aGVyIHdpdGggcXVhbnRpemVkIHNwZWN0cmFsIHZhbHVlOyBpZiBjYXJyeUJpdCBpcyB6ZXJvLCB0aGUgc2lnbiBpcyBvayBhbHJlYWR5OyBubyB3cml0ZSBvcGVyYXRpb24gbmVjZXNzYXJ5IGluIHRoaXMgY2FzZSAqLwogICAgaWYgKCBjYXJyeUJpdCAhPSAwICkgewogICAgICBwUmVzdWx0QmFzZVtpUVNDXSA9IC0gcFJlc3VsdEJhc2VbaVFTQ107ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNhcnJ5Qml0ID0gMSAtLT4gbWludXMgKi8KICAgIH0KICAgIGlRU0MrKzsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB1cGRhdGUgaW5kZXggdG8gbmV4dCAobWF5YmUgdmFsaWQpIHZhbHVlICovCiAgICBpUmVzdWx0UG9pbnRlcltjb2Rld29yZE9mZnNldF0gPSBpUVNDOwoKICAgIGlmICggY250U2lnbiA9PSAwICkgewogICAgICAvKiBhbGwgc2lnbiBiaXRzIGFyZSBkZWNvZGVkIG5vdyAqLwogICAgICBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSAtPSAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxhc3QgcmVpbml0aWFsemF0aW9uIG9mIGZvciBsb29wIGNvdW50ZXIgKHNlZSBhYm92ZSkgaXMgZG9uZSBoZXJlICovCgogICAgICAvKiBjaGVjayBkZWNvZGVkIHZhbHVlcyBpZiBjb2Rld29yZCBpcyBkZWNvZGVkOiBDaGVjayBpZiBvbmUgb3IgdHdvIGVzY2FwZSBzZXF1ZW5jZXMgMTYgZm9sbG93ICovCgogICAgICAvKiBzdGVwIDAgKi8KICAgICAgLyogcmVzdG9yZSBwb2ludGVyIHRvIGZpcnN0IGRlY29kZWQgcXVhbnRpemVkIHZhbHVlIFsgPSBvcmlnaW5hbCBwUmVzdWx0UG9pbnRyXSBmcm9tIGluZGV4IGlOb2RlIHByZXBhcmVkIGluIFN0YXRlX0JPRFlfU0lHTl9FU0NfX0JPRFkgKi8KICAgICAgaVFTQyA9IGlOb2RlW2NvZGV3b3JkT2Zmc2V0XTsKCiAgICAgIC8qIHN0ZXAgMSAqLwogICAgICAvKiB0ZXN0IGZpcnN0IHZhbHVlIGlmIGVzY2FwZSBzZXF1ZW5jZSBmb2xsb3dzICovCiAgICAgIGZsYWdBID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZm9yIGZpcnN0IHBvc3NpYmxlIGVzY2FwZSBzZXF1ZW5jZSAqLwogICAgICBpZiAoIGZpeHBfYWJzKHBSZXN1bHRCYXNlW2lRU0MrK10pID09IChGSVhQX0RCTClFU0NBUEVfVkFMVUUgKSB7CiAgICAgICAgZmxhZ0EgPSAxOwogICAgICB9CgogICAgICAvKiBzdGVwIDIgKi8KICAgICAgLyogdGVzdCBzZWNvbmQgdmFsdWUgaWYgZXNjYXBlIHNlcXVlbmNlIGZvbGxvd3MgKi8KICAgICAgZmxhZ0IgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBmb3Igc2Vjb25kIHBvc3NpYmxlIGVzY2FwZSBzZXF1ZW5jZSAqLwogICAgICBpZiAoIGZpeHBfYWJzKHBSZXN1bHRCYXNlW2lRU0NdKSA9PSAoRklYUF9EQkwpRVNDQVBFX1ZBTFVFICkgewogICAgICAgIGZsYWdCID0gMTsKICAgICAgfQoKCiAgICAgIC8qIHN0ZXAgMyAqLwogICAgICAvKiBldmFsdWF0ZSBmbGFnIHJlc3VsdCBhbmQgZ28gb24gaWYgbmVjZXNzYXJ5ICovCiAgICAgIGlmICggIWZsYWdBICYmICFmbGFnQiApIHsKICAgICAgICBDbGVhckJpdEZyb21CaXRmaWVsZCgmKHBIY3ItPm5vblBjd1NpZGVpbmZvLnBTdGF0ZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VnbWVudE9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQ29kZXdvcmRCaXRmaWVsZCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjbGVhciBhIGJpdCBpbiBiaXRmaWVsZCBhbmQgc3dpdGNoIG9mZiBzdGF0ZW1hY2hpbmUgKi8KICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICAvKiBhdCBsZWFzdCBvbmUgb2YgdHdvIGxpbmVzIGlzIDE2ICovCiAgICAgICAgLyogc3RvcmUgYm90aCBmbGFncyBhdCBjb3JyZWN0IHBvc2l0aW9ucyBpbiBub24gUENXIGNvZGV3b3JkIHNpZGVpbmZvIHBFc2NhcGVTZXF1ZW5jZUluZm9bY29kZXdvcmRPZmZzZXRdICovCiAgICAgICAgZmxhZ3MgPSAwOwogICAgICAgIGZsYWdzID0gICBmbGFnQSA8PCBQT1NJVElPTl9PRl9GTEFHX0E7CiAgICAgICAgZmxhZ3MgfD0gKGZsYWdCIDw8IFBPU0lUSU9OX09GX0ZMQUdfQik7CiAgICAgICAgcEVzY2FwZVNlcXVlbmNlSW5mb1tjb2Rld29yZE9mZnNldF0gPSBmbGFnczsKCgogICAgICAgIC8qIHNldCBuZXh0IHN0YXRlICovCiAgICAgICAgcFN0YVtjb2Rld29yZE9mZnNldF0gPSBCT0RZX1NJR05fRVNDX19FU0NfUFJFRklYOwogICAgICAgIHBIY3ItPm5vblBjd1NpZGVpbmZvLnBTdGF0ZSA9IGFTdGF0ZUNvbnN0YW50MlN0YXRlW3BTdGFbY29kZXdvcmRPZmZzZXRdXTsgICAgICAgICAgIC8qIGdldCBzdGF0ZSBmcm9tIHNlcGFyYXRlIGFycmF5IG9mIGN3LXNpZGVpbmZvICovCgogICAgICAgIC8qIHNldCByZXN1bHQgcG9pbnRlciB0byB0aGUgZmlyc3QgbGluZSBvZiB0aGUgdHdvIGRlY29kZWQgbGluZXMgKi8KICAgICAgICBpUmVzdWx0UG9pbnRlcltjb2Rld29yZE9mZnNldF0gPSBpTm9kZVtjb2Rld29yZE9mZnNldF07CgogICAgICAgIGlmICggIWZsYWdBICYmIGZsYWdCICkgewogICAgICAgICAgLyogdXBkYXRlIHBSZXN1bHRQb2ludHIgPT0+IHN0YXRlIFN0YXRfQk9EWV9TSUdOX0VTQ19fRVNDX1dPUkQgd3JpdGVzIHRvIGNvcnJlY3QgcG9zaXRpb24uIFNlY29uZCB2YWx1ZSBpcyB0aGUgb25lIGFuZCBvbmx5IGVzY2FwZSB2YWx1ZSAqLwogICAgICAgICAgaVFTQyA9IGlSZXN1bHRQb2ludGVyW2NvZGV3b3JkT2Zmc2V0XTsKICAgICAgICAgIGlRU0MrKzsKICAgICAgICAgIGlSZXN1bHRQb2ludGVyW2NvZGV3b3JkT2Zmc2V0XSA9IGlRU0M7CiAgICAgICAgfQoKICAgICAgfSAgICAgLyogYXQgbGVhc3Qgb25lIG9mIHR3byBsaW5lcyBpcyAxNiAqLwogICAgICBicmVhazsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5vblBDVy1Cb2R5IGF0IGNiIDExIGFuZCBhY2NvcmRpbmcgc2lnbiBiaXRzIGFyZSBkZWNvZGVkICovCgogICAgfSAvKiBpZiAoIGNudFNpZ24gPT0gMCApICovCiAgfSAvKiBsb29wIG92ZXIgcmVtYWluaW5nIEJpdHMgaW4gc2VnbWVudCAqLwoKICBpZiAoIHBSZW1haW5pbmdCaXRzSW5TZWdtZW50W3NlZ21lbnRPZmZzZXRdIDw9IDAgKSB7CiAgICBDbGVhckJpdEZyb21CaXRmaWVsZCgmKHBIY3ItPm5vblBjd1NpZGVpbmZvLnBTdGF0ZSksCiAgICAgICAgICAgICAgICAgICAgICAgICBzZWdtZW50T2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgcFNlZ21lbnRCaXRmaWVsZCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNsZWFyIGEgYml0IGluIGJpdGZpZWxkIGFuZCBzd2l0Y2ggb2ZmIHN0YXRlbWFjaGluZSAqLwoKI2lmIFNUQVRFX01BQ0hJTkVfRVJST1JfQ0hFQ0sKICAgIGlmICggcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gPCAwICkgewogICAgICBwSGNyLT5kZWNJbk91dC5lcnJvckxvZyB8PSBTVEFURV9FUlJPUl9CT0RZX1NJR05fRVNDX19TSUdOOwogICAgICByZXR1cm4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT0RZX1NJR05fRVNDX19TSUdOOwogICAgfQojZW5kaWYKCiAgfQogIHJldHVybiBTVE9QX1RISVNfU1RBVEU7Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIGRlc2NyaXB0aW9uOiBEZWNvZGUgZXNjYXBlIHByZWZpeCBvZiBmaXJzdCBvciBzZWNvbmQgZXNjYXBlIHNlcXVlbmNlLiBUaGUgZXNjYXBlIHByZWZpeAogICAgICAgICAgICAgICAgICBjb25zaXN0cyBvZiBvbmVzLiBUaGUgZm9sbG93aW5nIHplcm8gaXMgYWxzbyBkZWNvZGVkIGhlcmUuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgb3V0cHV0OiAgIElmIHRoZSBzaW5nbGUgc2VwYXJhdG9yLXplcm8gd2hpY2ggZm9sbG93cyB0aGUgZXNjYXBlLXByZWZpeC1vbmVzIGlzIG5vdCB5ZXQgZGVjb2RlZDoKICAgICAgICAgICAgICAgICAgICBUaGUgdmFsdWUgJ2VzY2FwZVByZWZpeFVwJyBpbiB3b3JkIHBFc2NhcGVTZXF1ZW5jZUluZm9bY29kZXdvcmRPZmZzZXRdIGlzIHVwZGF0ZWQuCgogICAgICAgICAgICAgICAgICBJZiB0aGUgc2luZ2xlIHNlcGFyYXRvci16ZXJvIHdoaWNoIGZvbGxvd3MgdGhlIGVzY2FwZS1wcmVmaXgtb25lcyBpcyBkZWNvZGVkOgogICAgICAgICAgICAgICAgICAgIFR3byB1cGRhdGVkIHZhbHVlcyAnZXNjYXBlUHJlZml4VXAnIGFuZCAnZXNjYXBlUHJlZml4RG93bicgaW4gd29yZAogICAgICAgICAgICAgICAgICAgIHBFc2NhcGVTZXF1ZW5jZUluZm9bY29kZXdvcmRPZmZzZXRdLiBUaGlzIFN0YXRlIGlzIGZpbmlzaGVkLiBTd2l0Y2ggdG8gbmV4dCBzdGF0ZS4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICByZXR1cm46ICAgMAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwpVSU5UIEhjcl9TdGF0ZV9CT0RZX1NJR05fRVNDX19FU0NfUFJFRklYKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLCB2b2lkICpwdHIpCnsKICBIX0hDUl9JTkZPIHBIY3IgPSAoSF9IQ1JfSU5GTylwdHI7CiAgU0NIQVIgICpwUmVtYWluaW5nQml0c0luU2VnbWVudDsKICBVU0hPUlQgKnBMZWZ0U3RhcnRPZlNlZ21lbnQ7CiAgVVNIT1JUICpwUmlnaHRTdGFydE9mU2VnbWVudDsKICBVQ0hBUiAgIHJlYWREaXJlY3Rpb247CiAgVUlOVCAgICpwU2VnbWVudEJpdGZpZWxkOwogIFVJTlQgICAgc2VnbWVudE9mZnNldDsKICBVSU5UICAgKnBFc2NhcGVTZXF1ZW5jZUluZm87CiAgVUlOVCAgICBjb2Rld29yZE9mZnNldDsKICBVQ0hBUiAgIGNhcnJ5Qml0OwogIFVJTlQgICAgZXNjYXBlUHJlZml4VXA7CiAgU0NIQVIgICpwU3RhOwoKICBwUmVtYWluaW5nQml0c0luU2VnbWVudCAgICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBSZW1haW5pbmdCaXRzSW5TZWdtZW50OwogIHBMZWZ0U3RhcnRPZlNlZ21lbnQgICAgICAgICAgICAgID0gcEhjci0+c2VnbWVudEluZm8ucExlZnRTdGFydE9mU2VnbWVudDsKICBwUmlnaHRTdGFydE9mU2VnbWVudCAgICAgICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBSaWdodFN0YXJ0T2ZTZWdtZW50OwogIHJlYWREaXJlY3Rpb24gICAgICAgICAgICAgICAgICAgID0gcEhjci0+c2VnbWVudEluZm8ucmVhZERpcmVjdGlvbjsKICBwU2VnbWVudEJpdGZpZWxkICAgICAgICAgICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBTZWdtZW50Qml0ZmllbGQ7CiAgc2VnbWVudE9mZnNldCAgICAgICAgICAgICAgICAgICAgPSBwSGNyLT5zZWdtZW50SW5mby5zZWdtZW50T2Zmc2V0OwogIHBFc2NhcGVTZXF1ZW5jZUluZm8gICAgICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8ucEVzY2FwZVNlcXVlbmNlSW5mbzsKICBjb2Rld29yZE9mZnNldCAgICAgICAgICAgICAgICAgICA9IHBIY3ItPm5vblBjd1NpZGVpbmZvLmNvZGV3b3JkT2Zmc2V0OwogIHBTdGEgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8ucFN0YTsKCiAgZXNjYXBlUHJlZml4VXAgID0gKHBFc2NhcGVTZXF1ZW5jZUluZm9bY29kZXdvcmRPZmZzZXRdICYgTUFTS19FU0NBUEVfUFJFRklYX1VQKSA+PiBMU0JfRVNDQVBFX1BSRUZJWF9VUDsKCgogIC8qIGRlY29kZSBlc2NhcGUgcHJlZml4ICovCiAgZm9yICggOyBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSA+IDAgOyBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSAtPSAxICkgewoKICAgIGNhcnJ5Qml0ID0gSGNyR2V0QUJpdEZyb21CaXRzdHJlYW0oIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcExlZnRTdGFydE9mU2VnbWVudFtzZWdtZW50T2Zmc2V0XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBSaWdodFN0YXJ0T2ZTZWdtZW50W3NlZ21lbnRPZmZzZXRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZERpcmVjdGlvbik7CgogICAgLyogY291bnQgb25lcyBhbmQgc3RvcmUgc3VtIGluIGVzY2FwZVByZWZpeFVwICovCiAgICBpZiAoIGNhcnJ5Qml0ID09IDEgKSB7CiAgICAgIGVzY2FwZVByZWZpeFVwICs9IDE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB1cGRhdGUgY29udGVyIGZvciBvbmVzICovCgogICAgICAvKiBzdG9yZSB1cGRhdGVkIGNvdW50ZXIgaW4gc2lkZWluZm8gb2YgY3VycmVudCBjb2Rld29yZCAqLwogICAgICBwRXNjYXBlU2VxdWVuY2VJbmZvW2NvZGV3b3JkT2Zmc2V0XSAmPSB+TUFTS19FU0NBUEVfUFJFRklYX1VQOyAgICAgICAgLyogZGVsZXRlIG9sZCBlc2NhcGVQcmVmaXhVcCAqLwogICAgICBlc2NhcGVQcmVmaXhVcCA8PD0gTFNCX0VTQ0FQRV9QUkVGSVhfVVA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2hpZnQgdG8gY29ycmVjdCBwb3NpdGlvbiAqLwogICAgICBwRXNjYXBlU2VxdWVuY2VJbmZvW2NvZGV3b3JkT2Zmc2V0XSB8PSBlc2NhcGVQcmVmaXhVcDsgICAgICAgICAgICAgICAgLyogaW5zZXJ0IG5ldyBlc2NhcGVQcmVmaXhVcCAqLwogICAgICBlc2NhcGVQcmVmaXhVcCA+Pj0gTFNCX0VTQ0FQRV9QUkVGSVhfVVA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2hpZnQgYmFjayBkb3duICovCiAgICB9CiAgICBlbHNlIHsgIC8qIHNlcGFyYXRvciBbemVyb10gcmVhY2hlZCAqLwogICAgICBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSAtPSAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbGFzdCByZWluaXRpYWx6YXRpb24gb2YgZm9yIGxvb3AgY291bnRlciAoc2VlIGFib3ZlKSBpcyBkb25lIGhlcmUgKi8KICAgICAgZXNjYXBlUHJlZml4VXAgKz0gNDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGlmIGVzY2FwZV9zZXBhcmF0b3IgJzAnIGFwcGVhcnMsIGFkZCA0IGFuZCA9PT4gYnJlYWsgKi8KCiAgICAgIC8qIHN0b3JlIGVzY2FwZVByZWZpeFVwIGluIHBFc2NhcGVTZXF1ZW5jZUluZm9bY29kZXdvcmRPZmZzZXRdIGF0IGJpdCBwb3NpdGlvbiBlc2NhcGVQcmVmaXhVcCAqLwogICAgICBwRXNjYXBlU2VxdWVuY2VJbmZvW2NvZGV3b3JkT2Zmc2V0XSAmPSB+TUFTS19FU0NBUEVfUFJFRklYX1VQOyAgICAgICAgLyogZGVsZXRlIG9sZCBlc2NhcGVQcmVmaXhVcCAqLwogICAgICBlc2NhcGVQcmVmaXhVcCA8PD0gTFNCX0VTQ0FQRV9QUkVGSVhfVVA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2hpZnQgdG8gY29ycmVjdCBwb3NpdGlvbiAqLwogICAgICBwRXNjYXBlU2VxdWVuY2VJbmZvW2NvZGV3b3JkT2Zmc2V0XSB8PSBlc2NhcGVQcmVmaXhVcDsgICAgICAgICAgICAgICAgLyogaW5zZXJ0IG5ldyBlc2NhcGVQcmVmaXhVcCAqLwogICAgICBlc2NhcGVQcmVmaXhVcCA+Pj0gTFNCX0VTQ0FQRV9QUkVGSVhfVVA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2hpZnQgYmFjayBkb3duICovCgogICAgICAvKiBzdG9yZSBlc2NhcGVQcmVmaXhVcCBpbiBwRXNjYXBlU2VxdWVuY2VJbmZvW2NvZGV3b3JkT2Zmc2V0XSBhdCBiaXQgcG9zaXRpb24gZXNjYXBlUHJlZml4RG93biAqLwogICAgICBwRXNjYXBlU2VxdWVuY2VJbmZvW2NvZGV3b3JkT2Zmc2V0XSAmPSB+TUFTS19FU0NBUEVfUFJFRklYX0RPV047ICAgICAgLyogZGVsZXRlIG9sZCBlc2NhcGVQcmVmaXhEb3duICovCiAgICAgIGVzY2FwZVByZWZpeFVwIDw8PSBMU0JfRVNDQVBFX1BSRUZJWF9ET1dOOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzaGlmdCB0byBjb3JyZWN0IHBvc2l0aW9uICovCiAgICAgIHBFc2NhcGVTZXF1ZW5jZUluZm9bY29kZXdvcmRPZmZzZXRdIHw9IGVzY2FwZVByZWZpeFVwOyAgICAgICAgICAgICAgICAvKiBpbnNlcnQgbmV3IGVzY2FwZVByZWZpeERvd24gKi8KICAgICAgZXNjYXBlUHJlZml4VXAgPj49IExTQl9FU0NBUEVfUFJFRklYX0RPV047ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNoaWZ0IGJhY2sgZG93biAqLwoKICAgICAgcFN0YVtjb2Rld29yZE9mZnNldF0gPSBCT0RZX1NJR05fRVNDX19FU0NfV09SRDsgICAgICAgICAgICAgICAgICAgICAgIC8qIHNldCBuZXh0IHN0YXRlICovCiAgICAgIHBIY3ItPm5vblBjd1NpZGVpbmZvLnBTdGF0ZSA9IGFTdGF0ZUNvbnN0YW50MlN0YXRlW3BTdGFbY29kZXdvcmRPZmZzZXRdXTsgICAgICAgICAgIC8qIGdldCBzdGF0ZSBmcm9tIHNlcGFyYXRlIGFycmF5IG9mIGN3LXNpZGVpbmZvICovCiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgaWYgKCBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSA8PSAwICkgewogICAgQ2xlYXJCaXRGcm9tQml0ZmllbGQoJihwSGNyLT5ub25QY3dTaWRlaW5mby5wU3RhdGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgc2VnbWVudE9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgIHBTZWdtZW50Qml0ZmllbGQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNsZWFyIGEgYml0IGluIGJpdGZpZWxkIGFuZCBzd2l0Y2ggb2ZmIHN0YXRlbWFjaGluZSAqLwoKI2lmIFNUQVRFX01BQ0hJTkVfRVJST1JfQ0hFQ0sKICAgIGlmICggcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gPCAwICkgewogICAgICBwSGNyLT5kZWNJbk91dC5lcnJvckxvZyB8PSBTVEFURV9FUlJPUl9CT0RZX1NJR05fRVNDX19FU0NfUFJFRklYOwogICAgICByZXR1cm4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT0RZX1NJR05fRVNDX19FU0NfUFJFRklYOwogICAgfQojZW5kaWYKICB9CgogIHJldHVybiBTVE9QX1RISVNfU1RBVEU7Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIGRlc2NyaXB0aW9uOiBEZWNvZGUgZXNjYXBlV29yZCBvZiBlc2NhcGUgc2VxdWVuY2UuIElmIHRoZSBlc2NhcGUgc2VxdWVuY2UgaXMgZGVjb2RlZAogICAgICAgICAgICAgICAgICBjb21wbGV0ZWx5LCBhc3NlbWJsZSBxdWFudGl6ZWQtc3BlY3RyYWwtZXNjYXBlLWNvZWZmaWNpZW50IGFuZCByZXBsYWNlIHRoZQogICAgICAgICAgICAgICAgICBwcmV2aW91cyBkZWNvZGVkIDE2IGJ5IHRoZSBuZXcgdmFsdWUuCiAgICAgICAgICAgICAgICAgIFRlc3QgZmxhZ0IuIElmIGZsYWdCIGlzIHNldCwgdGhlIHNlY29uZCBlc2NhcGUgc2VxdWVuY2UgbXVzdCBiZSBkZWNvZGVkLiBJZgogICAgICAgICAgICAgICAgICBmbGFnQiBpcyBub3Qgc2V0LCB0aGUgY29kZXdvcmQgaXMgZGVjb2RlZCBhbmQgdGhlIHN0YXRlIG1hY2hpbmUgaXMgc3dpdGNoZWQKICAgICAgICAgICAgICAgICAgb2ZmLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIG91dHB1dDogICBUd28gbGluZXMgd2l0aCB2YWxpZCBzaWduLiBBdCBsZWFzdCBvbmUgb2YgYm90aCBsaW5lcyBoYXMgZ290IHRoZSBjb3JyZWN0CiAgICAgICAgICAgICAgICAgIHZhbHVlLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIHJldHVybjogICAwCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovClVJTlQgSGNyX1N0YXRlX0JPRFlfU0lHTl9FU0NfX0VTQ19XT1JEKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLCB2b2lkICpwdHIpCnsKICBIX0hDUl9JTkZPIHBIY3IgPSAoSF9IQ1JfSU5GTylwdHI7CiAgU0NIQVIgICAgICpwUmVtYWluaW5nQml0c0luU2VnbWVudDsKICBVU0hPUlQgICAgKnBMZWZ0U3RhcnRPZlNlZ21lbnQ7CiAgVVNIT1JUICAgICpwUmlnaHRTdGFydE9mU2VnbWVudDsKICBVQ0hBUiAgICAgIHJlYWREaXJlY3Rpb247CiAgVUlOVCAgICAgICpwU2VnbWVudEJpdGZpZWxkOwogIFVJTlQgICAgICAqcENvZGV3b3JkQml0ZmllbGQ7CiAgVUlOVCAgICAgICBzZWdtZW50T2Zmc2V0OwoKICBGSVhQX0RCTCAgKnBSZXN1bHRCYXNlOwogIFVTSE9SVCAgICAqaVJlc3VsdFBvaW50ZXI7CiAgVUlOVCAgICAgICpwRXNjYXBlU2VxdWVuY2VJbmZvOwogIFVJTlQgICAgICAgY29kZXdvcmRPZmZzZXQ7CgogIFVJTlQgICAgICAgZXNjYXBlV29yZDsKICBVSU5UICAgICAgIGVzY2FwZVByZWZpeERvd247CiAgVUlOVCAgICAgICBlc2NhcGVQcmVmaXhVcDsKICBVQ0hBUiAgICAgIGNhcnJ5Qml0OwogIFVJTlQgICAgICAgaVFTQzsKICBJTlQgICAgICAgIHNpZ247CiAgVUlOVCAgICAgICBmbGFnQTsKICBVSU5UICAgICAgIGZsYWdCOwogIFNDSEFSICAgICAqcFN0YTsKCiAgcFJlbWFpbmluZ0JpdHNJblNlZ21lbnQgPSBwSGNyLT5zZWdtZW50SW5mby5wUmVtYWluaW5nQml0c0luU2VnbWVudDsKICBwTGVmdFN0YXJ0T2ZTZWdtZW50ICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnBMZWZ0U3RhcnRPZlNlZ21lbnQ7CiAgcFJpZ2h0U3RhcnRPZlNlZ21lbnQgICAgPSBwSGNyLT5zZWdtZW50SW5mby5wUmlnaHRTdGFydE9mU2VnbWVudDsKICByZWFkRGlyZWN0aW9uICAgICAgICAgICA9IHBIY3ItPnNlZ21lbnRJbmZvLnJlYWREaXJlY3Rpb247CiAgcFNlZ21lbnRCaXRmaWVsZCAgICAgICAgPSBwSGNyLT5zZWdtZW50SW5mby5wU2VnbWVudEJpdGZpZWxkOwogIHBDb2Rld29yZEJpdGZpZWxkICAgICAgID0gcEhjci0+c2VnbWVudEluZm8ucENvZGV3b3JkQml0ZmllbGQ7CiAgc2VnbWVudE9mZnNldCAgICAgICAgICAgPSBwSGNyLT5zZWdtZW50SW5mby5zZWdtZW50T2Zmc2V0OwoKICBwUmVzdWx0QmFzZSAgICAgICAgICAgICA9IHBIY3ItPm5vblBjd1NpZGVpbmZvLnBSZXN1bHRCYXNlOwogIGlSZXN1bHRQb2ludGVyICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8uaVJlc3VsdFBvaW50ZXI7CiAgcEVzY2FwZVNlcXVlbmNlSW5mbyAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5wRXNjYXBlU2VxdWVuY2VJbmZvOwogIGNvZGV3b3JkT2Zmc2V0ICAgICAgICAgID0gcEhjci0+bm9uUGN3U2lkZWluZm8uY29kZXdvcmRPZmZzZXQ7CiAgcFN0YSAgICAgICAgICAgICAgICAgICAgPSBwSGNyLT5ub25QY3dTaWRlaW5mby5wU3RhOwoKICBlc2NhcGVXb3JkICAgICAgID0gIHBFc2NhcGVTZXF1ZW5jZUluZm9bY29kZXdvcmRPZmZzZXRdICYgTUFTS19FU0NBUEVfV09SRDsKICBlc2NhcGVQcmVmaXhEb3duID0gKHBFc2NhcGVTZXF1ZW5jZUluZm9bY29kZXdvcmRPZmZzZXRdICYgTUFTS19FU0NBUEVfUFJFRklYX0RPV04pID4+IExTQl9FU0NBUEVfUFJFRklYX0RPV047CgoKICAvKiBkZWNvZGUgZXNjYXBlIHdvcmQgKi8KICBmb3IgKCA7IHBSZW1haW5pbmdCaXRzSW5TZWdtZW50W3NlZ21lbnRPZmZzZXRdID4gMCA7IHBSZW1haW5pbmdCaXRzSW5TZWdtZW50W3NlZ21lbnRPZmZzZXRdIC09IDEgKSB7CgogICAgY2FycnlCaXQgPSBIY3JHZXRBQml0RnJvbUJpdHN0cmVhbSggYnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTGVmdFN0YXJ0T2ZTZWdtZW50W3NlZ21lbnRPZmZzZXRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFJpZ2h0U3RhcnRPZlNlZ21lbnRbc2VnbWVudE9mZnNldF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkRGlyZWN0aW9uKTsKCiAgICAvKiBidWlsZCBlc2NhcGUgd29yZCAqLwogICAgZXNjYXBlV29yZCA8PD0gMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbGVmdCBzaGlmdCBwcmV2aW91cyBkZWNvZGVkIHBhcnQgb2YgZXNjYXBlV29yZCBieSBvbiBiaXQgKi8KICAgIGVzY2FwZVdvcmQgPSBlc2NhcGVXb3JkIHwgY2FycnlCaXQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGFzc2VtYmxlIGVzY2FwZSB3b3JkIGJ5IGJpdHdpc2Ugb3IgKi8KCiAgICAvKiBkZWNyZW1lbnQgY291bnRlciBmb3IgbGVuZ3RoIG9mIGVzY2FwZSB3b3JkIGJlY2F1c2Ugb25lIG1vcmUgYml0IHdhcyBkZWNvZGVkICovCiAgICBlc2NhcGVQcmVmaXhEb3duIC09IDE7CgogICAgLyogc3RvcmUgdXBkYXRlZCBlc2NhcGVQcmVmaXhEb3duICovCiAgICBwRXNjYXBlU2VxdWVuY2VJbmZvW2NvZGV3b3JkT2Zmc2V0XSAmPSB+TUFTS19FU0NBUEVfUFJFRklYX0RPV047ICAgICAgICAvKiBkZWxldGUgb2xkIGVzY2FwZVByZWZpeERvd24gKi8KICAgIGVzY2FwZVByZWZpeERvd24gPDw9IExTQl9FU0NBUEVfUFJFRklYX0RPV047ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNoaWZ0IHRvIGNvcnJlY3QgcG9zaXRpb24gKi8KICAgIHBFc2NhcGVTZXF1ZW5jZUluZm9bY29kZXdvcmRPZmZzZXRdIHw9IGVzY2FwZVByZWZpeERvd247ICAgICAgICAgICAgICAgIC8qIGluc2VydCBuZXcgZXNjYXBlUHJlZml4RG93biAqLwogICAgZXNjYXBlUHJlZml4RG93biA+Pj0gTFNCX0VTQ0FQRV9QUkVGSVhfRE9XTjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2hpZnQgYmFjayAqLwoKCiAgICAvKiBzdG9yZSB1cGRhdGVkIGVzY2FwZVdvcmQgKi8KICAgIHBFc2NhcGVTZXF1ZW5jZUluZm9bY29kZXdvcmRPZmZzZXRdICY9IH5NQVNLX0VTQ0FQRV9XT1JEOyAgICAgICAgICAgICAgIC8qIGRlbGV0ZSBvbGQgZXNjYXBlV29yZCAqLwogICAgcEVzY2FwZVNlcXVlbmNlSW5mb1tjb2Rld29yZE9mZnNldF0gfD0gZXNjYXBlV29yZDsgICAgICAgICAgICAgICAgICAgICAgLyogaW5zZXJ0IG5ldyBlc2NhcGVXb3JkICovCgoKICAgIGlmICggZXNjYXBlUHJlZml4RG93biA9PSAwICkgewogICAgICBwUmVtYWluaW5nQml0c0luU2VnbWVudFtzZWdtZW50T2Zmc2V0XSAtPSAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbGFzdCByZWluaXRpYWx6YXRpb24gb2YgZm9yIGxvb3AgY291bnRlciAoc2VlIGFib3ZlKSBpcyBkb25lIGhlcmUgKi8KCiAgICAgIC8qIGVzY2FwZSBzZXF1ZW5jZSBkZWNvZGVkLiBBc3NlbWJsZSBlc2NhcGUtbGluZSBhbmQgcmVwbGFjZSBvcmlnaW5hbCBsaW5lICovCgogICAgICAvKiBzdGVwIDAgKi8KICAgICAgLyogZGVyaXZlIHNpZ24gKi8KICAgICAgaVFTQyA9IGlSZXN1bHRQb2ludGVyW2NvZGV3b3JkT2Zmc2V0XTsKICAgICAgc2lnbiA9IChwUmVzdWx0QmFzZVtpUVNDXSA+PSAoRklYUF9EQkwpMCkgPyAxIDogLTE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBnZXQgc2lnbiBvZiBlc2NhcGUgdmFsdWUgMTYgKi8KCiAgICAgIC8qIHN0ZXAgMSAqLwogICAgICAvKiBnZXQgZXNjYXBlUHJlZml4VXAgKi8KICAgICAgZXNjYXBlUHJlZml4VXAgPSAocEVzY2FwZVNlcXVlbmNlSW5mb1tjb2Rld29yZE9mZnNldF0gJiBNQVNLX0VTQ0FQRV9QUkVGSVhfVVApID4+IExTQl9FU0NBUEVfUFJFRklYX1VQOwoKICAgICAgLyogc3RlcCAyICovCiAgICAgIC8qIGNhbGN1bGF0ZSBlc2NhcGUgdmFsdWUgKi8KICAgICAgcFJlc3VsdEJhc2VbaVFTQ10gPSAoRklYUF9EQkwpKHNpZ24gKiAoKChJTlQpIDEgPDwgZXNjYXBlUHJlZml4VXApICsgZXNjYXBlV29yZCkpOwoKICAgICAgLyogZ2V0IGJvdGggZmxhZ3MgZnJvbSBzaWRlaW5mbyAoZmxhZ3MgYXJlIG5vdCBzaGlmdGVkIHRvIHRoZSBsc2ItcG9zaXRpb24pICovCiAgICAgIGZsYWdBID0gcEVzY2FwZVNlcXVlbmNlSW5mb1tjb2Rld29yZE9mZnNldF0gJiBNQVNLX0ZMQUdfQTsKICAgICAgZmxhZ0IgPSBwRXNjYXBlU2VxdWVuY2VJbmZvW2NvZGV3b3JkT2Zmc2V0XSAmIE1BU0tfRkxBR19COwoKICAgICAgLyogc3RlcCAzICovCiAgICAgIC8qIGNsZWFyIHRoZSB3aG9sZSBlc2NhcGUgc2lkZWluZm8gd29yZCAqLwogICAgICBwRXNjYXBlU2VxdWVuY2VJbmZvW2NvZGV3b3JkT2Zmc2V0XSA9IDA7CgogICAgICAvKiBjaGFuZ2Ugc3RhdGUgaW4gZGVwZW5kZW5jZSBvZiBmbGFnIGZsYWdCICovCiAgICAgIGlmICggZmxhZ0EgIT0gMCApIHsKICAgICAgICAvKiBmaXJzdCBlc2NhcGUgc2VxdWVuY2UgZGVjb2RlZDsgcHJldmlvdXMgZGVjb2RlZCAxNiBoYXMgYmVlbiByZXBsYWNlZCBieSB2YWxpZCBsaW5lICovCgogICAgICAgIC8qIGNsZWFyIGZsYWdBIGluIHNpZGVpbmZvIHdvcmQgYmVjYXVzZSB0aGlzIGVzY2FwZSBzZXF1ZW5jZSBoYXMgYWxyZWFkeSBiZWVkIGRlY29kZWQgKi8KICAgICAgICBwRXNjYXBlU2VxdWVuY2VJbmZvW2NvZGV3b3JkT2Zmc2V0XSAmPSB+TUFTS19GTEFHX0E7CgogICAgICAgIGlmICggZmxhZ0IgPT0gMCApIHsKICAgICAgICAgIENsZWFyQml0RnJvbUJpdGZpZWxkKCYocEhjci0+bm9uUGN3U2lkZWluZm8ucFN0YXRlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnRPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQ29kZXdvcmRCaXRmaWVsZCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjbGVhciBhIGJpdCBpbiBiaXRmaWVsZCBhbmQgc3dpdGNoIG9mZiBzdGF0ZW1hY2hpbmUgKi8KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAvKiB1cGRhdGVkIHBvaW50ZXIgdG8gbmV4dCBhbmQgbGFzdCAxNiAqLwogICAgICAgICAgaVFTQysrOwogICAgICAgICAgaVJlc3VsdFBvaW50ZXJbY29kZXdvcmRPZmZzZXRdID0gaVFTQzsKCiAgICAgICAgICAvKiBjaGFuZ2Ugc3RhdGUgKi8KICAgICAgICAgIHBTdGFbY29kZXdvcmRPZmZzZXRdID0gQk9EWV9TSUdOX0VTQ19fRVNDX1BSRUZJWDsKICAgICAgICAgIHBIY3ItPm5vblBjd1NpZGVpbmZvLnBTdGF0ZSA9IGFTdGF0ZUNvbnN0YW50MlN0YXRlW3BTdGFbY29kZXdvcmRPZmZzZXRdXTsgLyogZ2V0IHN0YXRlIGZyb20gc2VwYXJhdGUgYXJyYXkgb2YgY3ctc2lkZWluZm8gKi8KICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgQ2xlYXJCaXRGcm9tQml0ZmllbGQoJihwSGNyLT5ub25QY3dTaWRlaW5mby5wU3RhdGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnRPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcENvZGV3b3JkQml0ZmllbGQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjbGVhciBhIGJpdCBpbiBiaXRmaWVsZCBhbmQgc3dpdGNoIG9mZiBzdGF0ZW1hY2hpbmUgKi8KICAgICAgfQogICAgICBicmVhazsKICAgIH0KICB9CgogIGlmICggcFJlbWFpbmluZ0JpdHNJblNlZ21lbnRbc2VnbWVudE9mZnNldF0gPD0gMCApIHsKICAgIENsZWFyQml0RnJvbUJpdGZpZWxkKCYocEhjci0+bm9uUGN3U2lkZWluZm8ucFN0YXRlKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnRPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICBwU2VnbWVudEJpdGZpZWxkKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjbGVhciBhIGJpdCBpbiBiaXRmaWVsZCBhbmQgc3dpdGNoIG9mZiBzdGF0ZW1hY2hpbmUgKi8KCiNpZiBTVEFURV9NQUNISU5FX0VSUk9SX0NIRUNLCiAgICBpZiAoIHBSZW1haW5pbmdCaXRzSW5TZWdtZW50W3NlZ21lbnRPZmZzZXRdIDwgMCApIHsKICAgICAgcEhjci0+ZGVjSW5PdXQuZXJyb3JMb2cgfD0gU1RBVEVfRVJST1JfQk9EWV9TSUdOX0VTQ19fRVNDX1dPUkQ7CiAgICAgIHJldHVybiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPRFlfU0lHTl9FU0NfX0VTQ19XT1JEOwogICAgfQojZW5kaWYKICB9CgogIHJldHVybiBTVE9QX1RISVNfU1RBVEU7Cn0KCg==