LyoKICogT0xFMzIgY2FsbG91dHMsIENPTSBpbnRlcmZhY2UgbWFyc2hhbGxpbmcKICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqCiAqIFRPRE86CiAqICAtIGZpeCB0aGUgd2lyZS1wcm90b2NvbCB0byBtYXRjaCBNUy9SUEMKICogIC0gZmluaXNoIFJwY1N0cmVhbV9WdGJsCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCiNkZWZpbmUgTk9OQU1FTEVTU1VOSU9OCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgIm9iamJhc2UuaCIKCiNpbmNsdWRlICJuZHJfbWlzYy5oIgojaW5jbHVkZSAicnBjbmRyLmgiCiNpbmNsdWRlICJycGNwcm94eS5oIgojaW5jbHVkZSAid2luZS9ycGNmYy5oIgojaW5jbHVkZSAiY3BzZi5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7CgpzdGF0aWMgSE1PRFVMRSBoT0xFOwoKc3RhdGljIEhSRVNVTFQgKFdJTkFQSSAqQ09NX0dldE1hcnNoYWxTaXplTWF4KShVTE9ORyAqLFJFRklJRCxMUFVOS05PV04sRFdPUkQsTFBWT0lELERXT1JEKTsKc3RhdGljIEhSRVNVTFQgKFdJTkFQSSAqQ09NX01hcnNoYWxJbnRlcmZhY2UpKExQU1RSRUFNLFJFRklJRCxMUFVOS05PV04sRFdPUkQsTFBWT0lELERXT1JEKTsKc3RhdGljIEhSRVNVTFQgKFdJTkFQSSAqQ09NX1VubWFyc2hhbEludGVyZmFjZSkoTFBTVFJFQU0sUkVGSUlELExQVk9JRCopOwpzdGF0aWMgSFJFU1VMVCAoV0lOQVBJICpDT01fUmVsZWFzZU1hcnNoYWxEYXRhKShMUFNUUkVBTSk7CnN0YXRpYyBIUkVTVUxUIChXSU5BUEkgKkNPTV9HZXRDbGFzc09iamVjdCkoUkVGQ0xTSUQsRFdPUkQsQ09TRVJWRVJJTkZPICosUkVGSUlELExQVk9JRCAqKTsKc3RhdGljIEhSRVNVTFQgKFdJTkFQSSAqQ09NX0dldFBTQ2xzaWQpKFJFRklJRCxDTFNJRCAqKTsKc3RhdGljIExQVk9JRCAoV0lOQVBJICpDT01fTWVtQWxsb2MpKFVMT05HKTsKc3RhdGljIHZvaWQgKFdJTkFQSSAqQ09NX01lbUZyZWUpKExQVk9JRCk7CgpzdGF0aWMgSE1PRFVMRSBMb2FkQ09NKHZvaWQpCnsKICBpZiAoaE9MRSkgcmV0dXJuIGhPTEU7CiAgaE9MRSA9IExvYWRMaWJyYXJ5QSgiT0xFMzIuRExMIik7CiAgaWYgKCFoT0xFKSByZXR1cm4gMDsKICBDT01fR2V0TWFyc2hhbFNpemVNYXggID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29HZXRNYXJzaGFsU2l6ZU1heCIpOwogIENPTV9NYXJzaGFsSW50ZXJmYWNlICAgPSAoTFBWT0lEKUdldFByb2NBZGRyZXNzKGhPTEUsICJDb01hcnNoYWxJbnRlcmZhY2UiKTsKICBDT01fVW5tYXJzaGFsSW50ZXJmYWNlID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29Vbm1hcnNoYWxJbnRlcmZhY2UiKTsKICBDT01fUmVsZWFzZU1hcnNoYWxEYXRhID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29SZWxlYXNlTWFyc2hhbERhdGEiKTsKICBDT01fR2V0Q2xhc3NPYmplY3QgICAgID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29HZXRDbGFzc09iamVjdCIpOwogIENPTV9HZXRQU0Nsc2lkICAgICAgICAgPSAoTFBWT0lEKUdldFByb2NBZGRyZXNzKGhPTEUsICJDb0dldFBTQ2xzaWQiKTsKICBDT01fTWVtQWxsb2MgPSAoTFBWT0lEKUdldFByb2NBZGRyZXNzKGhPTEUsICJDb1Rhc2tNZW1BbGxvYyIpOwogIENPTV9NZW1GcmVlICA9IChMUFZPSUQpR2V0UHJvY0FkZHJlc3MoaE9MRSwgIkNvVGFza01lbUZyZWUiKTsKICByZXR1cm4gaE9MRTsKfQoKLyogQ29NYXJzaGFsSW50ZXJmYWNlL0NvVW5tYXJzaGFsSW50ZXJmYWNlIHdvcmtzIG9uIHN0cmVhbXMsCiAqIHNvIGltcGxlbWVudCBhIHNpbXBsZSBzdHJlYW0gb24gdG9wIG9mIHRoZSBSUEMgYnVmZmVyCiAqICh3aGljaCBhbHNvIGltcGxlbWVudHMgdGhlIE1JbnRlcmZhY2VQb2ludGVyIHN0cnVjdHVyZSkgKi8KdHlwZWRlZiBzdHJ1Y3QgUnBjU3RyZWFtSW1wbAp7CiAgY29uc3QgSVN0cmVhbVZ0YmwgKmxwVnRibDsKICBEV09SRCBSZWZDb3VudDsKICBQTUlETF9TVFVCX01FU1NBR0UgcE1zZzsKICBMUERXT1JEIHNpemU7CiAgY2hhciAqZGF0YTsKICBEV09SRCBwb3M7Cn0gUnBjU3RyZWFtSW1wbDsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNTdHJlYW1fUXVlcnlJbnRlcmZhY2UoTFBTVFJFQU0gaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqb2JqKQp7CiAgUnBjU3RyZWFtSW1wbCAqVGhpcyA9IChScGNTdHJlYW1JbXBsICopaWZhY2U7CiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSVNlcXVlbnRpYWxTdHJlYW0sIHJpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSVN0cmVhbSwgcmlpZCkpIHsKICAgICpvYmogPSBUaGlzOwogICAgVGhpcy0+UmVmQ291bnQrKzsKICAgIHJldHVybiBTX09LOwogIH0KICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBScGNTdHJlYW1fQWRkUmVmKExQU1RSRUFNIGlmYWNlKQp7CiAgUnBjU3RyZWFtSW1wbCAqVGhpcyA9IChScGNTdHJlYW1JbXBsICopaWZhY2U7CiAgcmV0dXJuICsrKFRoaXMtPlJlZkNvdW50KTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBScGNTdHJlYW1fUmVsZWFzZShMUFNUUkVBTSBpZmFjZSkKewogIFJwY1N0cmVhbUltcGwgKlRoaXMgPSAoUnBjU3RyZWFtSW1wbCAqKWlmYWNlOwogIGlmICghLS0oVGhpcy0+UmVmQ291bnQpKSB7CiAgICBUUkFDRSgic2l6ZT0lbGRcbiIsICpUaGlzLT5zaXplKTsKICAgIFRoaXMtPnBNc2ctPkJ1ZmZlciA9ICh1bnNpZ25lZCBjaGFyKilUaGlzLT5kYXRhICsgKlRoaXMtPnNpemU7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgICByZXR1cm4gMDsKICB9CiAgcmV0dXJuIFRoaXMtPlJlZkNvdW50Owp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUnBjU3RyZWFtX1JlYWQoTFBTVFJFQU0gaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKnB2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyBjYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgKnBjYlJlYWQpCnsKICBScGNTdHJlYW1JbXBsICpUaGlzID0gKFJwY1N0cmVhbUltcGwgKilpZmFjZTsKICBIUkVTVUxUIGhyID0gU19PSzsKICBpZiAoVGhpcy0+cG9zICsgY2IgPiAqVGhpcy0+c2l6ZSkKICB7CiAgICBjYiA9ICpUaGlzLT5zaXplIC0gVGhpcy0+cG9zOwogICAgaHIgPSBTX0ZBTFNFOwogIH0KICBpZiAoY2IpIHsKICAgIG1lbWNweShwdiwgVGhpcy0+ZGF0YSArIFRoaXMtPnBvcywgY2IpOwogICAgVGhpcy0+cG9zICs9IGNiOwogIH0KICBpZiAocGNiUmVhZCkgKnBjYlJlYWQgPSBjYjsKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNTdHJlYW1fV3JpdGUoTFBTVFJFQU0gaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpwdiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGNiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgKnBjYldyaXR0ZW4pCnsKICBScGNTdHJlYW1JbXBsICpUaGlzID0gKFJwY1N0cmVhbUltcGwgKilpZmFjZTsKICBpZiAoVGhpcy0+ZGF0YSArIGNiID4gKGNoYXIgKilUaGlzLT5wTXNnLT5CdWZmZXJFbmQpCiAgICByZXR1cm4gU1RHX0VfTUVESVVNRlVMTDsKICBtZW1jcHkoVGhpcy0+ZGF0YSArIFRoaXMtPnBvcywgcHYsIGNiKTsKICBUaGlzLT5wb3MgKz0gY2I7CiAgaWYgKFRoaXMtPnBvcyA+ICpUaGlzLT5zaXplKSAqVGhpcy0+c2l6ZSA9IFRoaXMtPnBvczsKICBpZiAocGNiV3JpdHRlbikgKnBjYldyaXR0ZW4gPSBjYjsKICByZXR1cm4gU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJwY1N0cmVhbV9TZWVrKExQU1RSRUFNIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMQVJHRV9JTlRFR0VSIG1vdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIG9yaWdpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxBUkdFX0lOVEVHRVIgKm5ld1BvcykKewogIFJwY1N0cmVhbUltcGwgKlRoaXMgPSAoUnBjU3RyZWFtSW1wbCAqKWlmYWNlOwogIHN3aXRjaCAob3JpZ2luKSB7CiAgY2FzZSBTVFJFQU1fU0VFS19TRVQ6CiAgICBUaGlzLT5wb3MgPSBtb3ZlLnUuTG93UGFydDsKICAgIGJyZWFrOwogIGNhc2UgU1RSRUFNX1NFRUtfQ1VSOgogICAgVGhpcy0+cG9zID0gVGhpcy0+cG9zICsgbW92ZS51Lkxvd1BhcnQ7CiAgICBicmVhazsKICBjYXNlIFNUUkVBTV9TRUVLX0VORDoKICAgIFRoaXMtPnBvcyA9ICpUaGlzLT5zaXplICsgbW92ZS51Lkxvd1BhcnQ7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgcmV0dXJuIFNUR19FX0lOVkFMSURGVU5DVElPTjsKICB9CiAgaWYgKG5ld1BvcykgewogICAgbmV3UG9zLT51Lkxvd1BhcnQgPSBUaGlzLT5wb3M7CiAgICBuZXdQb3MtPnUuSGlnaFBhcnQgPSAwOwogIH0KICByZXR1cm4gU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJwY1N0cmVhbV9TZXRTaXplKExQU1RSRUFNIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTEFSR0VfSU5URUdFUiBuZXdTaXplKQp7CiAgUnBjU3RyZWFtSW1wbCAqVGhpcyA9IChScGNTdHJlYW1JbXBsICopaWZhY2U7CiAgKlRoaXMtPnNpemUgPSBuZXdTaXplLnUuTG93UGFydDsKICByZXR1cm4gU19PSzsKfQoKc3RhdGljIGNvbnN0IElTdHJlYW1WdGJsIFJwY1N0cmVhbV9WdGJsID0KewogIFJwY1N0cmVhbV9RdWVyeUludGVyZmFjZSwKICBScGNTdHJlYW1fQWRkUmVmLAogIFJwY1N0cmVhbV9SZWxlYXNlLAogIFJwY1N0cmVhbV9SZWFkLAogIFJwY1N0cmVhbV9Xcml0ZSwKICBScGNTdHJlYW1fU2VlaywKICBScGNTdHJlYW1fU2V0U2l6ZSwKICBOVUxMLCAvKiBDb3B5VG8gKi8KICBOVUxMLCAvKiBDb21taXQgKi8KICBOVUxMLCAvKiBSZXZlcnQgKi8KICBOVUxMLCAvKiBMb2NrUmVnaW9uICovCiAgTlVMTCwgLyogVW5sb2NrUmVnaW9uICovCiAgTlVMTCwgLyogU3RhdCAqLwogIE5VTEwgIC8qIENsb25lICovCn07CgpzdGF0aWMgTFBTVFJFQU0gUnBjU3RyZWFtX0NyZWF0ZShQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csIEJPT0wgaW5pdCkKewogIFJwY1N0cmVhbUltcGwgKlRoaXM7CiAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKFJwY1N0cmVhbUltcGwpKTsKICBpZiAoIVRoaXMpIHJldHVybiBOVUxMOwogIFRoaXMtPmxwVnRibCA9ICZScGNTdHJlYW1fVnRibDsKICBUaGlzLT5SZWZDb3VudCA9IDE7CiAgVGhpcy0+cE1zZyA9IHBTdHViTXNnOwogIFRoaXMtPnNpemUgPSAoTFBEV09SRClwU3R1Yk1zZy0+QnVmZmVyOwogIFRoaXMtPmRhdGEgPSAoY2hhciopKFRoaXMtPnNpemUgKyAxKTsKICBUaGlzLT5wb3MgPSAwOwogIGlmIChpbml0KSAqVGhpcy0+c2l6ZSA9IDA7CiAgVFJBQ0UoImluaXQgc2l6ZT0lbGRcbiIsICpUaGlzLT5zaXplKTsKICByZXR1cm4gKExQU1RSRUFNKVRoaXM7Cn0KCnN0YXRpYyBjb25zdCBJSUQqIGdldF9pcF9paWQoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCB1bnNpZ25lZCBjaGFyICpwTWVtb3J5LCBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgY29uc3QgSUlEICpyaWlkOwogIGlmICghcEZvcm1hdCkgcmV0dXJuICZJSURfSVVua25vd247CiAgVFJBQ0UoImZvcm1hdD0lMDJ4ICUwMnhcbiIsIHBGb3JtYXRbMF0sIHBGb3JtYXRbMV0pOwogIGlmIChwRm9ybWF0WzBdICE9IFJQQ19GQ19JUCkgRklYTUUoImZvcm1hdD0lZFxuIiwgcEZvcm1hdFswXSk7CiAgaWYgKHBGb3JtYXRbMV0gPT0gUlBDX0ZDX0NPTlNUQU5UX0lJRCkgewogICAgcmlpZCA9IChjb25zdCBJSUQgKikmcEZvcm1hdFsyXTsKICB9IGVsc2UgewogICAgQ29tcHV0ZUNvbmZvcm1hbmNlKHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KzIsIDApOwogICAgcmlpZCA9IChjb25zdCBJSUQgKilwU3R1Yk1zZy0+TWF4Q291bnQ7CiAgfQogIGlmICghcmlpZCkgcmlpZCA9ICZJSURfSVVua25vd247CiAgVFJBQ0UoImdvdCAlc1xuIiwgZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgcmV0dXJuIHJpaWQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRySW50ZXJmYWNlUG9pbnRlck1hcnNoYWxsIFtSUENSVDQuQF0KICovCnVuc2lnbmVkIGNoYXIgKiBXSU5BUEkgTmRySW50ZXJmYWNlUG9pbnRlck1hcnNoYWxsKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpwTWVtb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICBjb25zdCBJSUQgKnJpaWQgPSBnZXRfaXBfaWlkKHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKICBMUFNUUkVBTSBzdHJlYW07CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKICBwU3R1Yk1zZy0+TWF4Q291bnQgPSAwOwogIGlmICghTG9hZENPTSgpKSByZXR1cm4gTlVMTDsKICBpZiAocFN0dWJNc2ctPkJ1ZmZlciArIHNpemVvZihEV09SRCkgPD0gKHVuc2lnbmVkIGNoYXIgKilwU3R1Yk1zZy0+UnBjTXNnLT5CdWZmZXIgKyBwU3R1Yk1zZy0+QnVmZmVyTGVuZ3RoKSB7CiAgICBzdHJlYW0gPSBScGNTdHJlYW1fQ3JlYXRlKHBTdHViTXNnLCBUUlVFKTsKICAgIGlmIChzdHJlYW0pIHsKICAgICAgaWYgKHBNZW1vcnkpCiAgICAgICAgaHIgPSBDT01fTWFyc2hhbEludGVyZmFjZShzdHJlYW0sIHJpaWQsIChMUFVOS05PV04pcE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTdHViTXNnLT5kd0Rlc3RDb250ZXh0LCBwU3R1Yk1zZy0+cHZEZXN0Q29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1TSExGTEFHU19OT1JNQUwpOwogICAgICBlbHNlCiAgICAgICAgaHIgPSBTX09LOwoKICAgICAgSVN0cmVhbV9SZWxlYXNlKHN0cmVhbSk7CiAgICAgIGlmIChGQUlMRUQoaHIpKQogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKGhyKTsKICAgIH0KICB9CiAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRySW50ZXJmYWNlUG9pbnRlclVubWFyc2hhbGwgW1JQQ1JUNC5AXQogKi8KdW5zaWduZWQgY2hhciAqIFdJTkFQSSBOZHJJbnRlcmZhY2VQb2ludGVyVW5tYXJzaGFsbChQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICoqcHBNZW1vcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciBmTXVzdEFsbG9jKQp7CiAgTFBTVFJFQU0gc3RyZWFtOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXAsJWQpXG4iLCBwU3R1Yk1zZywgcHBNZW1vcnksIHBGb3JtYXQsIGZNdXN0QWxsb2MpOwogIGlmICghTG9hZENPTSgpKSByZXR1cm4gTlVMTDsKICAqKExQVk9JRCopcHBNZW1vcnkgPSBOVUxMOwogIGlmIChwU3R1Yk1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKSA8ICh1bnNpZ25lZCBjaGFyICopcFN0dWJNc2ctPlJwY01zZy0+QnVmZmVyICsgcFN0dWJNc2ctPkJ1ZmZlckxlbmd0aCkgewogICAgc3RyZWFtID0gUnBjU3RyZWFtX0NyZWF0ZShwU3R1Yk1zZywgRkFMU0UpOwogICAgaWYgKHN0cmVhbSkgewogICAgICBociA9IENPTV9Vbm1hcnNoYWxJbnRlcmZhY2Uoc3RyZWFtLCAmSUlEX05VTEwsIChMUFZPSUQqKXBwTWVtb3J5KTsKICAgICAgSVN0cmVhbV9SZWxlYXNlKHN0cmVhbSk7CiAgICAgIGlmIChGQUlMRUQoaHIpKQogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKGhyKTsKICAgIH0KICB9CiAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRySW50ZXJmYWNlUG9pbnRlckJ1ZmZlclNpemUgW1JQQ1JUNC5AXQogKi8Kdm9pZCBXSU5BUEkgTmRySW50ZXJmYWNlUG9pbnRlckJ1ZmZlclNpemUoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnBNZW1vcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCkKewogIGNvbnN0IElJRCAqcmlpZCA9IGdldF9pcF9paWQocFN0dWJNc2csIHBNZW1vcnksIHBGb3JtYXQpOwogIFVMT05HIHNpemUgPSAwOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBwU3R1Yk1zZywgcE1lbW9yeSwgcEZvcm1hdCk7CiAgaWYgKCFMb2FkQ09NKCkpIHJldHVybjsKICBociA9IENPTV9HZXRNYXJzaGFsU2l6ZU1heCgmc2l6ZSwgcmlpZCwgKExQVU5LTk9XTilwTWVtb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcFN0dWJNc2ctPmR3RGVzdENvbnRleHQsIHBTdHViTXNnLT5wdkRlc3RDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTVNITEZMQUdTX05PUk1BTCk7CiAgVFJBQ0UoInNpemU9JWxkXG4iLCBzaXplKTsKICBwU3R1Yk1zZy0+QnVmZmVyTGVuZ3RoICs9IHNpemVvZihEV09SRCkgKyBzaXplOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckludGVyZmFjZVBvaW50ZXJNZW1vcnlTaXplIFtSUENSVDQuQF0KICovCnVuc2lnbmVkIGxvbmcgV0lOQVBJIE5kckludGVyZmFjZVBvaW50ZXJNZW1vcnlTaXplKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgVUxPTkcgc2l6ZTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIHBTdHViTXNnLCBwRm9ybWF0KTsKCiAgc2l6ZSA9ICooVUxPTkcgKilwU3R1Yk1zZy0+QnVmZmVyOwogIHBTdHViTXNnLT5CdWZmZXIgKz0gNDsKICBwU3R1Yk1zZy0+TWVtb3J5U2l6ZSArPSA0OwoKICBwU3R1Yk1zZy0+QnVmZmVyICs9IHNpemU7CgogIHJldHVybiBwU3R1Yk1zZy0+TWVtb3J5U2l6ZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJJbnRlcmZhY2VQb2ludGVyRnJlZSBbUlBDUlQ0LkBdCiAqLwp2b2lkIFdJTkFQSSBOZHJJbnRlcmZhY2VQb2ludGVyRnJlZShQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqcE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgTFBVTktOT1dOIHBVbmsgPSAoTFBVTktOT1dOKXBNZW1vcnk7CiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKICBpZiAocFVuaykgSVVua25vd25fUmVsZWFzZShwVW5rKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJPbGVBbGxvY2F0ZSBbUlBDUlQ0LkBdCiAqLwp2b2lkICogV0lOQVBJIE5kck9sZUFsbG9jYXRlKHNpemVfdCBTaXplKQp7CiAgaWYgKCFMb2FkQ09NKCkpIHJldHVybiBOVUxMOwogIHJldHVybiBDT01fTWVtQWxsb2MoU2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyT2xlRnJlZSBbUlBDUlQ0LkBdCiAqLwp2b2lkIFdJTkFQSSBOZHJPbGVGcmVlKHZvaWQgKk5vZGVUb0ZyZWUpCnsKICBpZiAoIUxvYWRDT00oKSkgcmV0dXJuOwogIENPTV9NZW1GcmVlKE5vZGVUb0ZyZWUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHN0dWIuCiAqIFRoaXMgcHJvYmFibHkgbG9va3MgdmVyeSBtdWNoIGxpa2UgTmRycENyZWF0ZVN0dWIuCiAqLwpIUkVTVUxUIGNyZWF0ZV9zdHViKFJFRklJRCBpaWQsIElVbmtub3duICpwVW5rLCBJUnBjU3R1YkJ1ZmZlciAqKnBwc3R1YikKewogICAgQ0xTSUQgY2xzaWQ7CiAgICBJUFNGYWN0b3J5QnVmZmVyICpwc2ZhYzsKICAgIEhSRVNVTFQgcjsKCiAgICBpZighTG9hZENPTSgpKSByZXR1cm4gRV9GQUlMOwoKICAgIHIgPSBDT01fR2V0UFNDbHNpZCggaWlkLCAmY2xzaWQgKTsKICAgIGlmKEZBSUxFRChyKSkgcmV0dXJuIHI7CgogICAgciA9IENPTV9HZXRDbGFzc09iamVjdCggJmNsc2lkLCBDTFNDVFhfSU5QUk9DX1NFUlZFUiwgTlVMTCwgJklJRF9JUFNGYWN0b3J5QnVmZmVyLCAodm9pZCoqKSZwc2ZhYyApOwogICAgaWYoRkFJTEVEKHIpKSByZXR1cm4gcjsKCiAgICByID0gSVBTRmFjdG9yeUJ1ZmZlcl9DcmVhdGVTdHViKHBzZmFjLCBpaWQsIHBVbmssIHBwc3R1Yik7CgogICAgSVBTRmFjdG9yeUJ1ZmZlcl9SZWxlYXNlKHBzZmFjKTsKICAgIHJldHVybiByOwp9Cg==