LyoKICogT0xFMzIgY2FsbG91dHMsIENPTSBpbnRlcmZhY2UgbWFyc2hhbGxpbmcKICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqCiAqIFRPRE86CiAqICAtIGZpeCB0aGUgd2lyZS1wcm90b2NvbCB0byBtYXRjaCBNUy9SUEMKICogIC0gZmluaXNoIFJwY1N0cmVhbV9WdGJsCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCiNkZWZpbmUgTk9OQU1FTEVTU1VOSU9OCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgIm9iamJhc2UuaCIKCiNpbmNsdWRlICJuZHJfbWlzYy5oIgojaW5jbHVkZSAicnBjbmRyLmgiCiNpbmNsdWRlICJycGNwcm94eS5oIgojaW5jbHVkZSAid2luZS9ycGNmYy5oIgojaW5jbHVkZSAiY3BzZi5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7CgpzdGF0aWMgSE1PRFVMRSBoT0xFOwoKc3RhdGljIEhSRVNVTFQgKFdJTkFQSSAqQ09NX0dldE1hcnNoYWxTaXplTWF4KShVTE9ORyAqLFJFRklJRCxMUFVOS05PV04sRFdPUkQsTFBWT0lELERXT1JEKTsKc3RhdGljIEhSRVNVTFQgKFdJTkFQSSAqQ09NX01hcnNoYWxJbnRlcmZhY2UpKExQU1RSRUFNLFJFRklJRCxMUFVOS05PV04sRFdPUkQsTFBWT0lELERXT1JEKTsKc3RhdGljIEhSRVNVTFQgKFdJTkFQSSAqQ09NX1VubWFyc2hhbEludGVyZmFjZSkoTFBTVFJFQU0sUkVGSUlELExQVk9JRCopOwpzdGF0aWMgSFJFU1VMVCAoV0lOQVBJICpDT01fUmVsZWFzZU1hcnNoYWxEYXRhKShMUFNUUkVBTSk7CnN0YXRpYyBIUkVTVUxUIChXSU5BUEkgKkNPTV9HZXRDbGFzc09iamVjdCkoUkVGQ0xTSUQsRFdPUkQsQ09TRVJWRVJJTkZPICosUkVGSUlELExQVk9JRCAqKTsKc3RhdGljIEhSRVNVTFQgKFdJTkFQSSAqQ09NX0dldFBTQ2xzaWQpKFJFRklJRCxDTFNJRCAqKTsKc3RhdGljIExQVk9JRCAoV0lOQVBJICpDT01fTWVtQWxsb2MpKFVMT05HKTsKc3RhdGljIHZvaWQgKFdJTkFQSSAqQ09NX01lbUZyZWUpKExQVk9JRCk7CgpzdGF0aWMgSE1PRFVMRSBMb2FkQ09NKHZvaWQpCnsKICBpZiAoaE9MRSkgcmV0dXJuIGhPTEU7CiAgaE9MRSA9IExvYWRMaWJyYXJ5QSgiT0xFMzIuRExMIik7CiAgaWYgKCFoT0xFKSByZXR1cm4gMDsKICBDT01fR2V0TWFyc2hhbFNpemVNYXggID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29HZXRNYXJzaGFsU2l6ZU1heCIpOwogIENPTV9NYXJzaGFsSW50ZXJmYWNlICAgPSAoTFBWT0lEKUdldFByb2NBZGRyZXNzKGhPTEUsICJDb01hcnNoYWxJbnRlcmZhY2UiKTsKICBDT01fVW5tYXJzaGFsSW50ZXJmYWNlID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29Vbm1hcnNoYWxJbnRlcmZhY2UiKTsKICBDT01fUmVsZWFzZU1hcnNoYWxEYXRhID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29SZWxlYXNlTWFyc2hhbERhdGEiKTsKICBDT01fR2V0Q2xhc3NPYmplY3QgICAgID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29HZXRDbGFzc09iamVjdCIpOwogIENPTV9HZXRQU0Nsc2lkICAgICAgICAgPSAoTFBWT0lEKUdldFByb2NBZGRyZXNzKGhPTEUsICJDb0dldFBTQ2xzaWQiKTsKICBDT01fTWVtQWxsb2MgPSAoTFBWT0lEKUdldFByb2NBZGRyZXNzKGhPTEUsICJDb1Rhc2tNZW1BbGxvYyIpOwogIENPTV9NZW1GcmVlICA9IChMUFZPSUQpR2V0UHJvY0FkZHJlc3MoaE9MRSwgIkNvVGFza01lbUZyZWUiKTsKICByZXR1cm4gaE9MRTsKfQoKLyogQ29NYXJzaGFsSW50ZXJmYWNlL0NvVW5tYXJzaGFsSW50ZXJmYWNlIHdvcmtzIG9uIHN0cmVhbXMsCiAqIHNvIGltcGxlbWVudCBhIHNpbXBsZSBzdHJlYW0gb24gdG9wIG9mIHRoZSBSUEMgYnVmZmVyCiAqICh3aGljaCBhbHNvIGltcGxlbWVudHMgdGhlIE1JbnRlcmZhY2VQb2ludGVyIHN0cnVjdHVyZSkgKi8KdHlwZWRlZiBzdHJ1Y3QgUnBjU3RyZWFtSW1wbAp7CiAgY29uc3QgSVN0cmVhbVZ0YmwgKmxwVnRibDsKICBEV09SRCBSZWZDb3VudDsKICBQTUlETF9TVFVCX01FU1NBR0UgcE1zZzsKICBMUERXT1JEIHNpemU7CiAgY2hhciAqZGF0YTsKICBEV09SRCBwb3M7Cn0gUnBjU3RyZWFtSW1wbDsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNTdHJlYW1fUXVlcnlJbnRlcmZhY2UoTFBTVFJFQU0gaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqb2JqKQp7CiAgUnBjU3RyZWFtSW1wbCAqVGhpcyA9IChScGNTdHJlYW1JbXBsICopaWZhY2U7CiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSVNlcXVlbnRpYWxTdHJlYW0sIHJpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSVN0cmVhbSwgcmlpZCkpIHsKICAgICpvYmogPSBUaGlzOwogICAgVGhpcy0+UmVmQ291bnQrKzsKICAgIHJldHVybiBTX09LOwogIH0KICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBScGNTdHJlYW1fQWRkUmVmKExQU1RSRUFNIGlmYWNlKQp7CiAgUnBjU3RyZWFtSW1wbCAqVGhpcyA9IChScGNTdHJlYW1JbXBsICopaWZhY2U7CiAgcmV0dXJuICsrKFRoaXMtPlJlZkNvdW50KTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBScGNTdHJlYW1fUmVsZWFzZShMUFNUUkVBTSBpZmFjZSkKewogIFJwY1N0cmVhbUltcGwgKlRoaXMgPSAoUnBjU3RyZWFtSW1wbCAqKWlmYWNlOwogIGlmICghLS0oVGhpcy0+UmVmQ291bnQpKSB7CiAgICBUUkFDRSgic2l6ZT0lZFxuIiwgKlRoaXMtPnNpemUpOwogICAgVGhpcy0+cE1zZy0+QnVmZmVyID0gKHVuc2lnbmVkIGNoYXIqKVRoaXMtPmRhdGEgKyAqVGhpcy0+c2l6ZTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gVGhpcy0+UmVmQ291bnQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNTdHJlYW1fUmVhZChMUFNUUkVBTSBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqcHYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGNiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyAqcGNiUmVhZCkKewogIFJwY1N0cmVhbUltcGwgKlRoaXMgPSAoUnBjU3RyZWFtSW1wbCAqKWlmYWNlOwogIEhSRVNVTFQgaHIgPSBTX09LOwogIGlmIChUaGlzLT5wb3MgKyBjYiA+ICpUaGlzLT5zaXplKQogIHsKICAgIGNiID0gKlRoaXMtPnNpemUgLSBUaGlzLT5wb3M7CiAgICBociA9IFNfRkFMU0U7CiAgfQogIGlmIChjYikgewogICAgbWVtY3B5KHB2LCBUaGlzLT5kYXRhICsgVGhpcy0+cG9zLCBjYik7CiAgICBUaGlzLT5wb3MgKz0gY2I7CiAgfQogIGlmIChwY2JSZWFkKSAqcGNiUmVhZCA9IGNiOwogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJwY1N0cmVhbV9Xcml0ZShMUFNUUkVBTSBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKnB2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgY2IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyAqcGNiV3JpdHRlbikKewogIFJwY1N0cmVhbUltcGwgKlRoaXMgPSAoUnBjU3RyZWFtSW1wbCAqKWlmYWNlOwogIGlmIChUaGlzLT5kYXRhICsgY2IgPiAoY2hhciAqKVRoaXMtPnBNc2ctPkJ1ZmZlckVuZCkKICAgIHJldHVybiBTVEdfRV9NRURJVU1GVUxMOwogIG1lbWNweShUaGlzLT5kYXRhICsgVGhpcy0+cG9zLCBwdiwgY2IpOwogIFRoaXMtPnBvcyArPSBjYjsKICBpZiAoVGhpcy0+cG9zID4gKlRoaXMtPnNpemUpICpUaGlzLT5zaXplID0gVGhpcy0+cG9zOwogIGlmIChwY2JXcml0dGVuKSAqcGNiV3JpdHRlbiA9IGNiOwogIHJldHVybiBTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUnBjU3RyZWFtX1NlZWsoTFBTVFJFQU0gaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExBUkdFX0lOVEVHRVIgbW92ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgb3JpZ2luLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTEFSR0VfSU5URUdFUiAqbmV3UG9zKQp7CiAgUnBjU3RyZWFtSW1wbCAqVGhpcyA9IChScGNTdHJlYW1JbXBsICopaWZhY2U7CiAgc3dpdGNoIChvcmlnaW4pIHsKICBjYXNlIFNUUkVBTV9TRUVLX1NFVDoKICAgIFRoaXMtPnBvcyA9IG1vdmUudS5Mb3dQYXJ0OwogICAgYnJlYWs7CiAgY2FzZSBTVFJFQU1fU0VFS19DVVI6CiAgICBUaGlzLT5wb3MgPSBUaGlzLT5wb3MgKyBtb3ZlLnUuTG93UGFydDsKICAgIGJyZWFrOwogIGNhc2UgU1RSRUFNX1NFRUtfRU5EOgogICAgVGhpcy0+cG9zID0gKlRoaXMtPnNpemUgKyBtb3ZlLnUuTG93UGFydDsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gU1RHX0VfSU5WQUxJREZVTkNUSU9OOwogIH0KICBpZiAobmV3UG9zKSB7CiAgICBuZXdQb3MtPnUuTG93UGFydCA9IFRoaXMtPnBvczsKICAgIG5ld1Bvcy0+dS5IaWdoUGFydCA9IDA7CiAgfQogIHJldHVybiBTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUnBjU3RyZWFtX1NldFNpemUoTFBTVFJFQU0gaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMQVJHRV9JTlRFR0VSIG5ld1NpemUpCnsKICBScGNTdHJlYW1JbXBsICpUaGlzID0gKFJwY1N0cmVhbUltcGwgKilpZmFjZTsKICAqVGhpcy0+c2l6ZSA9IG5ld1NpemUudS5Mb3dQYXJ0OwogIHJldHVybiBTX09LOwp9CgpzdGF0aWMgY29uc3QgSVN0cmVhbVZ0YmwgUnBjU3RyZWFtX1Z0YmwgPQp7CiAgUnBjU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlLAogIFJwY1N0cmVhbV9BZGRSZWYsCiAgUnBjU3RyZWFtX1JlbGVhc2UsCiAgUnBjU3RyZWFtX1JlYWQsCiAgUnBjU3RyZWFtX1dyaXRlLAogIFJwY1N0cmVhbV9TZWVrLAogIFJwY1N0cmVhbV9TZXRTaXplLAogIE5VTEwsIC8qIENvcHlUbyAqLwogIE5VTEwsIC8qIENvbW1pdCAqLwogIE5VTEwsIC8qIFJldmVydCAqLwogIE5VTEwsIC8qIExvY2tSZWdpb24gKi8KICBOVUxMLCAvKiBVbmxvY2tSZWdpb24gKi8KICBOVUxMLCAvKiBTdGF0ICovCiAgTlVMTCAgLyogQ2xvbmUgKi8KfTsKCnN0YXRpYyBMUFNUUkVBTSBScGNTdHJlYW1fQ3JlYXRlKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgQk9PTCBpbml0KQp7CiAgUnBjU3RyZWFtSW1wbCAqVGhpczsKICBUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoUnBjU3RyZWFtSW1wbCkpOwogIGlmICghVGhpcykgcmV0dXJuIE5VTEw7CiAgVGhpcy0+bHBWdGJsID0gJlJwY1N0cmVhbV9WdGJsOwogIFRoaXMtPlJlZkNvdW50ID0gMTsKICBUaGlzLT5wTXNnID0gcFN0dWJNc2c7CiAgVGhpcy0+c2l6ZSA9IChMUERXT1JEKXBTdHViTXNnLT5CdWZmZXI7CiAgVGhpcy0+ZGF0YSA9IChjaGFyKikoVGhpcy0+c2l6ZSArIDEpOwogIFRoaXMtPnBvcyA9IDA7CiAgaWYgKGluaXQpICpUaGlzLT5zaXplID0gMDsKICBUUkFDRSgiaW5pdCBzaXplPSVkXG4iLCAqVGhpcy0+c2l6ZSk7CiAgcmV0dXJuIChMUFNUUkVBTSlUaGlzOwp9CgpzdGF0aWMgY29uc3QgSUlEKiBnZXRfaXBfaWlkKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgdW5zaWduZWQgY2hhciAqcE1lbW9yeSwgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCkKewogIGNvbnN0IElJRCAqcmlpZDsKICBpZiAoIXBGb3JtYXQpIHJldHVybiAmSUlEX0lVbmtub3duOwogIFRSQUNFKCJmb3JtYXQ9JTAyeCAlMDJ4XG4iLCBwRm9ybWF0WzBdLCBwRm9ybWF0WzFdKTsKICBpZiAocEZvcm1hdFswXSAhPSBSUENfRkNfSVApIEZJWE1FKCJmb3JtYXQ9JWRcbiIsIHBGb3JtYXRbMF0pOwogIGlmIChwRm9ybWF0WzFdID09IFJQQ19GQ19DT05TVEFOVF9JSUQpIHsKICAgIHJpaWQgPSAoY29uc3QgSUlEICopJnBGb3JtYXRbMl07CiAgfSBlbHNlIHsKICAgIENvbXB1dGVDb25mb3JtYW5jZShwU3R1Yk1zZywgcE1lbW9yeSwgcEZvcm1hdCsyLCAwKTsKICAgIHJpaWQgPSAoY29uc3QgSUlEICopcFN0dWJNc2ctPk1heENvdW50OwogIH0KICBpZiAoIXJpaWQpIHJpaWQgPSAmSUlEX0lVbmtub3duOwogIFRSQUNFKCJnb3QgJXNcbiIsIGRlYnVnc3RyX2d1aWQocmlpZCkpOwogIHJldHVybiByaWlkOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckludGVyZmFjZVBvaW50ZXJNYXJzaGFsbCBbUlBDUlQ0LkBdCiAqLwp1bnNpZ25lZCBjaGFyICogV0lOQVBJIE5kckludGVyZmFjZVBvaW50ZXJNYXJzaGFsbChQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqcE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgY29uc3QgSUlEICpyaWlkID0gZ2V0X2lwX2lpZChwU3R1Yk1zZywgcE1lbW9yeSwgcEZvcm1hdCk7CiAgTFBTVFJFQU0gc3RyZWFtOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBwU3R1Yk1zZywgcE1lbW9yeSwgcEZvcm1hdCk7CiAgcFN0dWJNc2ctPk1heENvdW50ID0gMDsKICBpZiAoIUxvYWRDT00oKSkgcmV0dXJuIE5VTEw7CiAgaWYgKHBTdHViTXNnLT5CdWZmZXIgKyBzaXplb2YoRFdPUkQpIDw9ICh1bnNpZ25lZCBjaGFyICopcFN0dWJNc2ctPlJwY01zZy0+QnVmZmVyICsgcFN0dWJNc2ctPkJ1ZmZlckxlbmd0aCkgewogICAgc3RyZWFtID0gUnBjU3RyZWFtX0NyZWF0ZShwU3R1Yk1zZywgVFJVRSk7CiAgICBpZiAoc3RyZWFtKSB7CiAgICAgIGlmIChwTWVtb3J5KQogICAgICAgIGhyID0gQ09NX01hcnNoYWxJbnRlcmZhY2Uoc3RyZWFtLCByaWlkLCAoTFBVTktOT1dOKXBNZW1vcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU3R1Yk1zZy0+ZHdEZXN0Q29udGV4dCwgcFN0dWJNc2ctPnB2RGVzdENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNU0hMRkxBR1NfTk9STUFMKTsKICAgICAgZWxzZQogICAgICAgIGhyID0gU19PSzsKCiAgICAgIElTdHJlYW1fUmVsZWFzZShzdHJlYW0pOwogICAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihocik7CiAgICB9CiAgfQogIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckludGVyZmFjZVBvaW50ZXJVbm1hcnNoYWxsIFtSUENSVDQuQF0KICovCnVuc2lnbmVkIGNoYXIgKiBXSU5BUEkgTmRySW50ZXJmYWNlUG9pbnRlclVubWFyc2hhbGwoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqKnBwTWVtb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgZk11c3RBbGxvYykKewogIExQU1RSRUFNIHN0cmVhbTsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVkKVxuIiwgcFN0dWJNc2csIHBwTWVtb3J5LCBwRm9ybWF0LCBmTXVzdEFsbG9jKTsKICBpZiAoIUxvYWRDT00oKSkgcmV0dXJuIE5VTEw7CiAgKihMUFZPSUQqKXBwTWVtb3J5ID0gTlVMTDsKICBpZiAocFN0dWJNc2ctPkJ1ZmZlciArIHNpemVvZihEV09SRCkgPCAodW5zaWduZWQgY2hhciAqKXBTdHViTXNnLT5ScGNNc2ctPkJ1ZmZlciArIHBTdHViTXNnLT5CdWZmZXJMZW5ndGgpIHsKICAgIHN0cmVhbSA9IFJwY1N0cmVhbV9DcmVhdGUocFN0dWJNc2csIEZBTFNFKTsKICAgIGlmIChzdHJlYW0pIHsKICAgICAgaHIgPSBDT01fVW5tYXJzaGFsSW50ZXJmYWNlKHN0cmVhbSwgJklJRF9OVUxMLCAoTFBWT0lEKilwcE1lbW9yeSk7CiAgICAgIElTdHJlYW1fUmVsZWFzZShzdHJlYW0pOwogICAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihocik7CiAgICB9CiAgfQogIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckludGVyZmFjZVBvaW50ZXJCdWZmZXJTaXplIFtSUENSVDQuQF0KICovCnZvaWQgV0lOQVBJIE5kckludGVyZmFjZVBvaW50ZXJCdWZmZXJTaXplKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpwTWVtb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICBjb25zdCBJSUQgKnJpaWQgPSBnZXRfaXBfaWlkKHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKICBVTE9ORyBzaXplID0gMDsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgcFN0dWJNc2csIHBNZW1vcnksIHBGb3JtYXQpOwogIGlmICghTG9hZENPTSgpKSByZXR1cm47CiAgaHIgPSBDT01fR2V0TWFyc2hhbFNpemVNYXgoJnNpemUsIHJpaWQsIChMUFVOS05PV04pcE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTdHViTXNnLT5kd0Rlc3RDb250ZXh0LCBwU3R1Yk1zZy0+cHZEZXN0Q29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1TSExGTEFHU19OT1JNQUwpOwogIFRSQUNFKCJzaXplPSVkXG4iLCBzaXplKTsKICBwU3R1Yk1zZy0+QnVmZmVyTGVuZ3RoICs9IHNpemVvZihEV09SRCkgKyBzaXplOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckludGVyZmFjZVBvaW50ZXJNZW1vcnlTaXplIFtSUENSVDQuQF0KICovClVMT05HIFdJTkFQSSBOZHJJbnRlcmZhY2VQb2ludGVyTWVtb3J5U2l6ZShQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgVUxPTkcgc2l6ZTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIHBTdHViTXNnLCBwRm9ybWF0KTsKCiAgc2l6ZSA9ICooVUxPTkcgKilwU3R1Yk1zZy0+QnVmZmVyOwogIHBTdHViTXNnLT5CdWZmZXIgKz0gNDsKICBwU3R1Yk1zZy0+TWVtb3J5U2l6ZSArPSA0OwoKICBwU3R1Yk1zZy0+QnVmZmVyICs9IHNpemU7CgogIHJldHVybiBwU3R1Yk1zZy0+TWVtb3J5U2l6ZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJJbnRlcmZhY2VQb2ludGVyRnJlZSBbUlBDUlQ0LkBdCiAqLwp2b2lkIFdJTkFQSSBOZHJJbnRlcmZhY2VQb2ludGVyRnJlZShQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqcE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgTFBVTktOT1dOIHBVbmsgPSAoTFBVTktOT1dOKXBNZW1vcnk7CiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKICBpZiAocFVuaykgSVVua25vd25fUmVsZWFzZShwVW5rKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJPbGVBbGxvY2F0ZSBbUlBDUlQ0LkBdCiAqLwp2b2lkICogV0lOQVBJIE5kck9sZUFsbG9jYXRlKHNpemVfdCBTaXplKQp7CiAgaWYgKCFMb2FkQ09NKCkpIHJldHVybiBOVUxMOwogIHJldHVybiBDT01fTWVtQWxsb2MoU2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyT2xlRnJlZSBbUlBDUlQ0LkBdCiAqLwp2b2lkIFdJTkFQSSBOZHJPbGVGcmVlKHZvaWQgKk5vZGVUb0ZyZWUpCnsKICBpZiAoIUxvYWRDT00oKSkgcmV0dXJuOwogIENPTV9NZW1GcmVlKE5vZGVUb0ZyZWUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhIHN0dWIuCiAqIFRoaXMgcHJvYmFibHkgbG9va3MgdmVyeSBtdWNoIGxpa2UgTmRycENyZWF0ZVN0dWIuCiAqLwpIUkVTVUxUIGNyZWF0ZV9zdHViKFJFRklJRCBpaWQsIElVbmtub3duICpwVW5rLCBJUnBjU3R1YkJ1ZmZlciAqKnBwc3R1YikKewogICAgQ0xTSUQgY2xzaWQ7CiAgICBJUFNGYWN0b3J5QnVmZmVyICpwc2ZhYzsKICAgIEhSRVNVTFQgcjsKCiAgICBpZighTG9hZENPTSgpKSByZXR1cm4gRV9GQUlMOwoKICAgIHIgPSBDT01fR2V0UFNDbHNpZCggaWlkLCAmY2xzaWQgKTsKICAgIGlmKEZBSUxFRChyKSkgcmV0dXJuIHI7CgogICAgciA9IENPTV9HZXRDbGFzc09iamVjdCggJmNsc2lkLCBDTFNDVFhfSU5QUk9DX1NFUlZFUiwgTlVMTCwgJklJRF9JUFNGYWN0b3J5QnVmZmVyLCAodm9pZCoqKSZwc2ZhYyApOwogICAgaWYoRkFJTEVEKHIpKSByZXR1cm4gcjsKCiAgICByID0gSVBTRmFjdG9yeUJ1ZmZlcl9DcmVhdGVTdHViKHBzZmFjLCBpaWQsIHBVbmssIHBwc3R1Yik7CgogICAgSVBTRmFjdG9yeUJ1ZmZlcl9SZWxlYXNlKHBzZmFjKTsKICAgIHJldHVybiByOwp9Cg==