LyoKICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIFN1biBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBTdW4gaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiwgNDE1MCBOZXR3b3JrIENpcmNsZSwgU2FudGEgQ2xhcmEsCiAqIENBIDk1MDU0IFVTQSBvciB2aXNpdCB3d3cuc3VuLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yCiAqIGhhdmUgYW55IHF1ZXN0aW9ucy4KICovCgovLyBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi8vIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgovLyBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi8vIGZpbGU6Ci8vCi8vCi8vICBMaXR0bGUgY21zCi8vICBDb3B5cmlnaHQgKEMpIDE5OTgtMjAwNiBNYXJ0aSBNYXJpYQovLwovLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcKLy8gYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAovLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCi8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAovLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUKLy8gaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLy8KLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCi8vCi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELAovLyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8KLy8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQKLy8gTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRQovLyBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OCi8vIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTgovLyBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KLy8KLy8gSVQ4LjcgLyBDR0FUUy4xNy0yMDB4IGhhbmRsaW5nCgojaW5jbHVkZSAibGNtcy5oIgoKCkxDTVNBUEkgTENNU0hBTkRMRSAgICAgIExDTVNFWFBPUlQgY21zSVQ4QWxsb2Modm9pZCk7CkxDTVNBUEkgdm9pZCAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4RnJlZShMQ01TSEFORExFIElUOCk7CgovLyBUYWJsZXMKCkxDTVNBUEkgaW50ICAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4VGFibGVDb3VudChMQ01TSEFORExFIElUOCk7CkxDTVNBUEkgaW50ICAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4U2V0VGFibGUoTENNU0hBTkRMRSBJVDgsIGludCBuVGFibGUpOwoKLy8gUGVyc2lzdGVuY2UKTENNU0FQSSBMQ01TSEFORExFICAgICAgTENNU0VYUE9SVCBjbXNJVDhMb2FkRnJvbUZpbGUoY29uc3QgY2hhciogY0ZpbGVOYW1lKTsKTENNU0FQSSBMQ01TSEFORExFICAgICAgTENNU0VYUE9SVCBjbXNJVDhMb2FkRnJvbU1lbSh2b2lkICpQdHIsIHNpemVfdCBsZW4pOwpMQ01TQVBJIEJPT0wgICAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNhdmVUb0ZpbGUoTENNU0hBTkRMRSBJVDgsIGNvbnN0IGNoYXIqIGNGaWxlTmFtZSk7CgovLyBQcm9wZXJ0aWVzCkxDTVNBUEkgY29uc3QgY2hhciogICAgIExDTVNFWFBPUlQgY21zSVQ4R2V0U2hlZXRUeXBlKExDTVNIQU5ETEUgaElUOCk7CkxDTVNBUEkgQk9PTCAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4U2V0U2hlZXRUeXBlKExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogVHlwZSk7CgpMQ01TQVBJIEJPT0wgICAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNldENvbW1lbnQoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjQ29tbWVudCk7CgpMQ01TQVBJIEJPT0wgICAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNldFByb3BlcnR5U3RyKExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1Byb3AsIGNvbnN0IGNoYXIgKlN0cik7CkxDTVNBUEkgQk9PTCAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlEYmwoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCwgZG91YmxlIFZhbCk7CkxDTVNBUEkgQk9PTCAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlIZXgoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCwgaW50IFZhbCk7CkxDTVNBUEkgQk9PTCAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlVbmNvb2tlZChMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIEtleSwgY29uc3QgY2hhciogQnVmZmVyKTsKCkxDTVNBUEkgY29uc3QgY2hhciogICAgIExDTVNFWFBPUlQgY21zSVQ4R2V0UHJvcGVydHkoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCk7CkxDTVNBUEkgZG91YmxlICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4R2V0UHJvcGVydHlEYmwoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCk7CkxDTVNBUEkgaW50ICAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4RW51bVByb3BlcnRpZXMoTENNU0hBTkRMRSBJVDgsIGNoYXIgKioqUHJvcGVydHlOYW1lcyk7CgovLyBEYXRhc2V0cwoKTENNU0FQSSBjb25zdCBjaGFyKiAgICAgTENNU0VYUE9SVCBjbXNJVDhHZXRQYXRjaE5hbWUoTENNU0hBTkRMRSBoSVQ4LCBpbnQgblBhdGNoLCBjaGFyKiBidWZmZXIpOwoKTENNU0FQSSBjb25zdCBjaGFyKiAgICAgTENNU0VYUE9SVCBjbXNJVDhHZXREYXRhUm93Q29sKExDTVNIQU5ETEUgSVQ4LCBpbnQgcm93LCBpbnQgY29sKTsKTENNU0FQSSBkb3VibGUgICAgICAgICAgTENNU0VYUE9SVCBjbXNJVDhHZXREYXRhUm93Q29sRGJsKExDTVNIQU5ETEUgSVQ4LCBpbnQgY29sLCBpbnQgcm93KTsKCkxDTVNBUEkgQk9PTCAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4U2V0RGF0YVJvd0NvbChMQ01TSEFORExFIGhJVDgsIGludCByb3csIGludCBjb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIFZhbCk7CgpMQ01TQVBJIEJPT0wgICAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNldERhdGFSb3dDb2xEYmwoTENNU0hBTkRMRSBoSVQ4LCBpbnQgcm93LCBpbnQgY29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgVmFsKTsKCkxDTVNBUEkgY29uc3QgY2hhciogICAgIExDTVNFWFBPUlQgY21zSVQ4R2V0RGF0YShMQ01TSEFORExFIElUOCwgY29uc3QgY2hhciogY1BhdGNoLCBjb25zdCBjaGFyKiBjU2FtcGxlKTsKCgpMQ01TQVBJIGRvdWJsZSAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOEdldERhdGFEYmwoTENNU0hBTkRMRSBJVDgsIGNvbnN0IGNoYXIqIGNQYXRjaCwgY29uc3QgY2hhciogY1NhbXBsZSk7CgpMQ01TQVBJIEJPT0wgICAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNldERhdGEoTENNU0hBTkRMRSBJVDgsIGNvbnN0IGNoYXIqIGNQYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogY1NhbXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqVmFsKTsKCkxDTVNBUEkgQk9PTCAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4U2V0RGF0YURibChMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNQYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogY1NhbXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIFZhbCk7CgpMQ01TQVBJIEJPT0wgICAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNldERhdGFGb3JtYXQoTENNU0hBTkRMRSBJVDgsIGludCBuLCBjb25zdCBjaGFyICpTYW1wbGUpOwpMQ01TQVBJIGludCAgICAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOEVudW1EYXRhRm9ybWF0KExDTVNIQU5ETEUgSVQ4LCBjaGFyICoqKlNhbXBsZU5hbWVzKTsKCkxDTVNBUEkgdm9pZCAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4RGVmaW5lRGJsRm9ybWF0KExDTVNIQU5ETEUgSVQ4LCBjb25zdCBjaGFyKiBGb3JtYXR0ZXIpOwoKTENNU0FQSSBpbnQgICAgICAgICAgICAgTENNU0VYUE9SVCBjbXNJVDhTZXRUYWJsZUJ5TGFiZWwoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjU2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGNGaWVsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBFeHBlY3RlZFR5cGUpOwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBJbXBsZW1lbnRhdGlvbgoKCiNkZWZpbmUgU0laRU9GTE9OR01JTlVTMSAgICAoc2l6ZW9mKGxvbmcpLTEpCiNkZWZpbmUgQUxJR05MT05HKHgpICgoKHgpK1NJWkVPRkxPTkdNSU5VUzEpICYgfihTSVpFT0ZMT05HTUlOVVMxKSkKCi8vICNkZWZpbmUgU1RSSUNUX0NHQVRTICAxCgojZGVmaW5lIE1BWElEICAgICAgIDEyOCAgICAgLy8gTWF4IGxlbmdodCBvZiBpZGVudGlmaWVyCiNkZWZpbmUgTUFYU1RSICAgICAgMjU1ICAgICAvLyBNYXggbGVuZ2h0IG9mIHN0cmluZwojZGVmaW5lIE1BWFRBQkxFUyAgIDI1NSAgICAgLy8gTWF4IE51bWJlciBvZiB0YWJsZXMgaW4gYSBzaW5nbGUgc3RyZWFtCiNkZWZpbmUgTUFYSU5DTFVERSAgIDIwICAgICAvLyBNYXggbnVtYmVyIG9mIG5lc3RlZCBpbmNsdWRlcwoKI2RlZmluZSBERUZBVUxUX0RCTF9GT1JNQVQgICIlLjEwZyIgLy8gRG91YmxlIGZvcm1hdHRpbmcKCiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8bGltaXRzLmg+CgojaWZuZGVmIE5PTl9XSU5ET1dTCiNpbmNsdWRlIDxpby5oPgojZW5kaWYKCi8vIFN5bWJvbHMKCnR5cGVkZWYgZW51bSB7CgogICAgICAgIFNOT05FLAogICAgICAgIFNJTlVNLCAgICAgIC8vIEludGVnZXIKICAgICAgICBTRE5VTSwgICAgICAvLyBSZWFsCiAgICAgICAgU0lERU5ULCAgICAgLy8gSWRlbnRpZmllcgogICAgICAgIFNTVFJJTkcsICAgIC8vIHN0cmluZwogICAgICAgIFNDT01NRU5ULCAgIC8vIGNvbW1lbnQKICAgICAgICBTRU9MTiwgICAgICAvLyBFbmQgb2YgbGluZQogICAgICAgIFNFT0YsICAgICAgIC8vIEVuZCBvZiBzdHJlYW0KICAgICAgICBTU1lORVJST1IsICAvLyBTeW50YXggZXJyb3IgZm91bmQgb24gc3RyZWFtCgogICAgICAgIC8vIEtleXdvcmRzCgogICAgICAgIFNCRUdJTl9EQVRBLAogICAgICAgIFNCRUdJTl9EQVRBX0ZPUk1BVCwKICAgICAgICBTRU5EX0RBVEEsCiAgICAgICAgU0VORF9EQVRBX0ZPUk1BVCwKICAgICAgICBTS0VZV09SRCwKICAgICAgICBTSU5DTFVERQoKICAgIH0gU1lNQk9MOwoKCi8vIEhvdyB0byB3cml0ZSB0aGUgdmFsdWUKCnR5cGVkZWYgZW51bSB7CiAgICAgICAgV1JJVEVfVU5DT09LRUQsCiAgICAgICAgV1JJVEVfU1RSSU5HSUZZLAogICAgICAgIFdSSVRFX0hFWEFERUNJTUFMLAogICAgICAgIFdSSVRFX0JJTkFSWQoKICAgIH0gV1JJVEVNT0RFOwoKLy8gTGlua2VkIGxpc3Qgb2YgdmFyaWFibGUgbmFtZXMKCnR5cGVkZWYgc3RydWN0IF9LZXlWYWwgewoKICAgICAgICBzdHJ1Y3QgX0tleVZhbCogIE5leHQ7CiAgICAgICAgY2hhciogICAgICAgICAgICBLZXl3b3JkOyAgICAgICAvLyBOYW1lIG9mIHZhcmlhYmxlCiAgICAgICAgY2hhciogICAgICAgICAgICBWYWx1ZTsgICAgICAgICAvLyBQb2ludHMgdG8gdmFsdWUKICAgICAgICBXUklURU1PREUgICAgICAgIFdyaXRlQXM7ICAgICAgIC8vIEhvdyB0byB3cml0ZSB0aGUgdmFsdWUKCiAgIH0gS0VZVkFMVUUsICpMUEtFWVZBTFVFOwoKCi8vIExpbmtlZCBsaXN0IG9mIG1lbW9yeSBjaHVua3MgKE1lbW9yeSBzaW5rKQoKdHlwZWRlZiBzdHJ1Y3QgX093bmVkTWVtIHsKCiAgICAgICAgc3RydWN0IF9Pd25lZE1lbSogTmV4dDsKICAgICAgICB2b2lkICogICAgICAgICAgICBQdHI7ICAgICAgICAgIC8vIFBvaW50IHRvIHZhbHVlCgogICB9IE9XTkVETUVNLCAqTFBPV05FRE1FTTsKCi8vIFN1YmFsbG9jYXRvcgoKdHlwZWRlZiBzdHJ1Y3QgX1N1YkFsbG9jYXRvciB7CgogICAgICAgICBMUEJZVEUgQmxvY2s7CiAgICAgICAgIHNpemVfdCBCbG9ja1NpemU7CiAgICAgICAgIHNpemVfdCBVc2VkOwoKICAgIH0gU1VCQUxMT0NBVE9SLCAqTFBTVUJBTExPQ0FUT1I7CgovLyBUYWJsZS4gRWFjaCBpbmRpdmlkdWFsIHRhYmxlIGNhbiBob2xkIHByb3BlcnRpZXMgYW5kIHJvd3MgJiBjb2xzCgp0eXBlZGVmIHN0cnVjdCBfVGFibGUgewoKICAgICAgICBpbnQgICAgICAgICAgICBuU2FtcGxlcywgblBhdGNoZXM7ICAgIC8vIENvbHMsIFJvd3MKICAgICAgICBpbnQgICAgICAgICAgICBTYW1wbGVJRDsgICAgICAgICAgICAgIC8vIFBvcyBvZiBJRAoKICAgICAgICBMUEtFWVZBTFVFICAgICBIZWFkZXJMaXN0OyAgICAgICAgICAgIC8vIFRoZSBwcm9wZXJ0aWVzCgogICAgICAgIGNoYXIqKiAgICAgICAgIERhdGFGb3JtYXQ7ICAgICAgICAgICAgLy8gVGhlIGJpbmFyeSBzdHJlYW0gZGVzY3JpcHRvcgogICAgICAgIGNoYXIqKiAgICAgICAgIERhdGE7ICAgICAgICAgICAgICAgICAgLy8gVGhlIGJpbmFyeSBzdHJlYW0KCiAgICB9IFRBQkxFLCAqTFBUQUJMRTsKCgoKLy8gVGhpcyBzdHJ1Y3QgaG9sZCBhbGwgaW5mb3JtYXRpb24gYWJvdXQgYW4gb3BlbmVuZWQKLy8gSVQ4IGhhbmRsZXIuIE9ubHkgb25lIGRhdGFzZXQgaXMgYWxsb3dlZC4KCnR5cGVkZWYgc3RydWN0IHsKCiAgICAgICAgY2hhciBTaGVldFR5cGVbTUFYU1RSXTsKCiAgICAgICAgaW50ICBUYWJsZXNDb3VudDsgICAgICAgICAgICAgICAgICAgICAvLyBIb3cgbWFueSB0YWJsZXMgaW4gdGhpcyBzdHJlYW0KICAgICAgICBpbnQgIG5UYWJsZTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBhY3R1YWwgdGFibGUKCiAgICAgICAgVEFCTEUgVGFiW01BWFRBQkxFU107CgogICAgICAgIC8vIE1lbW9yeSBtYW5hZ2VtZW50CgogICAgICAgIExQT1dORURNRU0gICAgIE1lbW9yeVNpbms7ICAgICAgICAgICAgLy8gVGhlIHN0b3JhZ2UgYmFja2VuZAogICAgICAgIFNVQkFMTE9DQVRPUiAgIEFsbG9jYXRvcjsgICAgICAgICAgICAgLy8gU3RyaW5nIHN1YmFsbG9jYXRvciAtLSBqdXN0IHRvIGtlZXAgaXQgZmFzdAoKICAgICAgICAvLyBQYXJzZXIgc3RhdGUgbWFjaGluZQoKICAgICAgICBTWU1CT0wgICAgICAgICBzeTsgICAgICAgICAgICAgICAgICAgIC8vIEN1cnJlbnQgc3ltYm9sCiAgICAgICAgaW50ICAgICAgICAgICAgY2g7ICAgICAgICAgICAgICAgICAgICAvLyBDdXJyZW50IGNoYXJhY3RlcgoKICAgICAgICBpbnQgICAgICAgICAgICBpbnVtOyAgICAgICAgICAgICAgICAgIC8vIGludGVnZXIgdmFsdWUKICAgICAgICBkb3VibGUgICAgICAgICBkbnVtOyAgICAgICAgICAgICAgICAgIC8vIHJlYWwgdmFsdWUKICAgICAgICBjaGFyICAgICAgICAgICBpZFtNQVhJRF07ICAgICAgICAgICAgIC8vIGlkZW50aWZpZXIKICAgICAgICBjaGFyICAgICAgICAgICBzdHJbTUFYU1RSXTsgICAgICAgICAgIC8vIHN0cmluZwoKICAgICAgICAvLyBBbGxvd2VkIGtleXdvcmRzICYgZGF0YXNldHMuIFRoZXkgaGF2ZSB2aXNpYmlsaXR5IG9uIHdob2xlIHN0cmVhbQoKICAgICAgICBMUEtFWVZBTFVFICAgICBWYWxpZEtleXdvcmRzOwogICAgICAgIExQS0VZVkFMVUUgICAgIFZhbGlkU2FtcGxlSUQ7CgogICAgICAgIGNoYXIqICAgICAgICAgIFNvdXJjZTsgICAgICAgICAgICAgICAgLy8gUG9pbnRzIHRvIGxvYy4gYmVpbmcgcGFyc2VkCiAgICAgICAgaW50ICAgICAgICAgICAgbGluZW5vOyAgICAgICAgICAgICAgICAvLyBsaW5lIGNvdW50ZXIgZm9yIGVycm9yIHJlcG9ydGluZwoKICAgICAgICBjaGFyICAgICAgICAgICBGaWxlTmFtZVtNQVhfUEFUSF07ICAgIC8vIEZpbGUgbmFtZSBpZiBiZWluZyByZWFkZWQgZnJvbSBmaWxlCiAgICAgICAgRklMRSogICAgICAgICAgU3RyZWFtW01BWElOQ0xVREVdOyAgICAvLyBGaWxlIHN0cmVhbSBvciBOVUxMIGlmIGhvbGRlZCBpbiBtZW1vcnkKICAgICAgICBpbnQgICAgICAgICAgICBJbmNsdWRlU1A7ICAgICAgICAgICAgIC8vIEluY2x1ZGUgU3RhY2sgUG9pbnRlcgogICAgICAgIGNoYXIqICAgICAgICAgIE1lbW9yeUJsb2NrOyAgICAgICAgICAgLy8gVGhlIHN0cmVhbSBpZiBob2xkZWQgaW4gbWVtb3J5CgogICAgICAgIGNoYXIgICAgICAgICAgIERvdWJsZUZvcm1hdHRlcltNQVhJRF07ICAgLy8gUHJpbnRmLWxpa2UgJ2RvdWJsZScgZm9ybWF0dGVyCgogICB9IElUOCwgKkxQSVQ4OwoKCgp0eXBlZGVmIHN0cnVjdCB7CgogICAgICAgICAgICAgICAgRklMRSogc3RyZWFtOyAgIC8vIEZvciBzYXZlLXRvLWZpbGUgYmVoYXZpb3VyCgogICAgICAgICAgICAgICAgTFBCWVRFIEJhc2U7CiAgICAgICAgICAgICAgICBMUEJZVEUgUHRyOyAgICAgICAgICAgICAvLyBGb3Igc2F2ZS10by1tZW0gYmVoYXZpb3VyCiAgICAgICAgICAgICAgICBzaXplX3QgVXNlZDsKICAgICAgICAgICAgICAgIHNpemVfdCBNYXg7CgogICAgICAgIH0gU0FWRVNUUkVBTSwgRkFSKiBMUFNBVkVTVFJFQU07CgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIElUOCBwYXJzaW5nIHJvdXRpbmVzCgoKLy8gQSBrZXl3b3JkCnR5cGVkZWYgc3RydWN0IHsKCiAgICAgICAgY29uc3QgY2hhciAqaWQ7CiAgICAgICAgU1lNQk9MIHN5OwoKICAgfSBLRVlXT1JEOwoKLy8gVGhlIGtleXdvcmQtPnN5bWJvbCB0cmFuc2xhdGlvbiB0YWJsZS4gU29ydGluZyBpcyByZXF1aXJlZC4Kc3RhdGljIGNvbnN0IEtFWVdPUkQgVGFiS2V5c1tdID0gewoKICAgICAgICB7IiRJTkNMVURFIiwgICAgICAgICAgICBTSU5DTFVERX0sCiAgICAgICAgeyIuSU5DTFVERSIsICAgICAgICAgICAgU0lOQ0xVREV9LAogICAgICAgIHsiQkVHSU5fREFUQSIsICAgICAgICAgIFNCRUdJTl9EQVRBIH0sCiAgICAgICAgeyJCRUdJTl9EQVRBX0ZPUk1BVCIsICAgU0JFR0lOX0RBVEFfRk9STUFUIH0sCiAgICAgICAgeyJFTkRfREFUQSIsICAgICAgICAgICAgU0VORF9EQVRBfSwKICAgICAgICB7IkVORF9EQVRBX0ZPUk1BVCIsICAgICBTRU5EX0RBVEFfRk9STUFUfSwKICAgICAgICB7IktFWVdPUkQiLCAgICAgICAgICAgICBTS0VZV09SRH0KCiAgICAgICAgfTsKCiNkZWZpbmUgTlVNS0VZUyAoc2l6ZW9mKFRhYktleXMpL3NpemVvZihLRVlXT1JEKSkKCi8vIFByZWRlZmluZWQgcHJvcGVydGllcwoKc3RhdGljIGNvbnN0IGNoYXIqIFByZWRlZmluZWRQcm9wZXJ0aWVzW10gPSB7CgogICAgICAgICJOVU1CRVJfT0ZfRklFTERTIiwgICAgLy8gUmVxdWlyZWQgLSBOVU1CRVIgT0YgRklFTERTCiAgICAgICAgIk5VTUJFUl9PRl9TRVRTIiwgICAgICAvLyBSZXF1aXJlZCAtIE5VTUJFUiBPRiBTRVRTCiAgICAgICAgIk9SSUdJTkFUT1IiLCAgICAgICAgICAvLyBSZXF1aXJlZCAtIElkZW50aWZpZXMgdGhlIHNwZWNpZmljIHN5c3RlbSwgb3JnYW5pemF0aW9uIG9yIGluZGl2aWR1YWwgdGhhdCBjcmVhdGVkIHRoZSBkYXRhIGZpbGUuCiAgICAgICAgIkZJTEVfREVTQ1JJUFRPUiIsICAgICAvLyBSZXF1aXJlZCAtIERlc2NyaWJlcyB0aGUgcHVycG9zZSBvciBjb250ZW50cyBvZiB0aGUgZGF0YSBmaWxlLgogICAgICAgICJDUkVBVEVEIiwgICAgICAgICAgICAgLy8gUmVxdWlyZWQgLSBJbmRpY2F0ZXMgZGF0ZSBvZiBjcmVhdGlvbiBvZiB0aGUgZGF0YSBmaWxlLgogICAgICAgICJERVNDUklQVE9SIiwgICAgICAgICAgLy8gUmVxdWlyZWQgIC0gRGVzY3JpYmVzIHRoZSBwdXJwb3NlIG9yIGNvbnRlbnRzIG9mIHRoZSBkYXRhIGZpbGUuCiAgICAgICAgIkRJRkZVU0VfR0VPTUVUUlkiLCAgICAvLyBUaGUgZGlmZnVzZSBnZW9tZXRyeSB1c2VkLiBBbGxvd2VkIHZhbHVlcyBhcmUgInNwaGVyZSIgb3IgIm9wYWwiLgogICAgICAgICJNQU5VRkFDVFVSRVIiLAogICAgICAgICJNQU5VRkFDVFVSRSIsICAgICAgICAgLy8gU29tZSBicm9rZW4gRnVqaSB0YXJnZXRzIGRvZXMgc3RvcmUgdGhpcyB2YWx1ZQogICAgICAgICJQUk9EX0RBVEUiLCAgICAgICAgICAgLy8gSWRlbnRpZmllcyB5ZWFyIGFuZCBtb250aCBvZiBwcm9kdWN0aW9uIG9mIHRoZSB0YXJnZXQgaW4gdGhlIGZvcm0geXl5eTptbS4KICAgICAgICAiU0VSSUFMIiwgICAgICAgICAgICAgIC8vIFVuaXF1ZWx5IGlkZW50aWZpZXMgaW5kaXZpZHVhbCBwaHlzaWNhbCB0YXJnZXQuCgogICAgICAgICJNQVRFUklBTCIsICAgICAgICAgICAgLy8gSWRlbnRpZmllcyB0aGUgbWF0ZXJpYWwgb24gd2hpY2ggdGhlIHRhcmdldCB3YXMgcHJvZHVjZWQgdXNpbmcgYSBjb2RlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1bmlxdWVseSBpZGVudGlmeWluZyB0aCBlIG1hdGVyaWFsLiBUaGlzIGlzIGludGVuZCBlZCB0byBiZSB1c2VkIGZvciBJVDguNwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcGh5c2ljYWwgdGFyZ2V0cyBvbmx5IChpLmUgLiBJVDguNy8xIGEgbmQgSVQ4LjcvMikuCgogICAgICAgICJJTlNUUlVNRU5UQVRJT04iLCAgICAgLy8gVXNlZCB0byByZXBvcnQgdGhlIHNwZWNpZmljIGluc3RydW1lbnRhdGlvbiB1c2VkIChtYW51ZmFjdHVyZXIgYW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtb2RlbCBudW1iZXIpIHRvIGdlbmVyYXRlIHRoZSBkYXRhIHJlcG9ydGVkLiBUaGlzIGRhdGEgd2lsbCBvZnRlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJvdmlkZSBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwYXJ0aWN1bGFyIGRhdGEgY29sbGVjdGVkIHRoYW4gYW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dGVuc2l2ZSBsaXN0IG9mIHNwZWNpZmljIGRldGFpbHMuIFRoaXMgaXMgcGFydGljdWxhcmx5IGltcG9ydGFudCBmb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNwZWN0cmFsIGRhdGEgb3IgZGF0YSBkZXJpdmVkIGZyb20gc3BlY3Ryb3Bob3RvbWV0cnkuCgogICAgICAgICJNRUFTVVJFTUVOVF9TT1VSQ0UiLCAgLy8gSWxsdW1pbmF0aW9uIHVzZWQgZm9yIHNwZWN0cmFsIG1lYXN1cmVtZW50cy4gVGhpcyBkYXRhIGhlbHBzIHByb3ZpZGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgZ3VpZGUgdG8gdGhlIHBvdGVudGlhbCBmb3IgaXNzdWVzIG9mIHBhcGVyIGZsdW9yZXNjZW5jZSwgZXRjLgoKICAgICAgICAiUFJJTlRfQ09ORElUSU9OUyIsICAgIC8vIFVzZWQgdG8gZGVmaW5lIHRoZSBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIHByaW50ZWQgc2hlZXQgYmVpbmcgcmVwb3J0ZWQuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGVyZSBzdGFuZGFyZCBjb25kaXRpb25zIGhhdmUgYmVlbiBkZWZpbmVkIChlLmcuLCBTV09QIGF0IG5vbWluYWwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBuYW1lZCBjb25kaXRpb25zIG1heSBzdWZmaWNlLiBPdGhlcndpc2UsIGRldGFpbGVkIGluZm9ybWF0aW9uIGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBuZWVkZWQuCgogICAgICAgICJTQU1QTEVfQkFDS0lORyIsICAgICAgLy8gSWRlbnRpZmllcyB0aGUgYmFja2luZyBtYXRlcmlhbCB1c2VkIGJlaGluZCB0aGUgc2FtcGxlIGR1cmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWVhc3VyZW1lbnQuIEFsbG93ZWQgdmFsdWVzIGFyZSCTYmxhY2uULCCTd2hpdGWULCBvciAibmEiLgoKICAgICAgICAiQ0hJU1FfRE9GIiAgICAgICAgICAgIC8vIERlZ3JlZXMgb2YgZnJlZWRvbSBhc3NvY2lhdGVkIHdpdGggdGhlIENoaSBzcXVhcmVkIHN0YXRpc3RpYwp9OwoKI2RlZmluZSBOVU1QUkVERUZJTkVEUFJPUFMgKHNpemVvZihQcmVkZWZpbmVkUHJvcGVydGllcykvc2l6ZW9mKGNoYXIgKikpCgoKLy8gUHJlZGVmaW5lZCBzYW1wbGUgdHlwZXMgb24gZGF0YXNldApzdGF0aWMgY29uc3QgY2hhciogUHJlZGVmaW5lZFNhbXBsZUlEW10gPSB7CgogICAgICAgICJDTVlLX0MiLCAgICAgICAgIC8vIEN5YW4gY29tcG9uZW50IG9mIENNWUsgZGF0YSBleHByZXNzZWQgYXMgYSBwZXJjZW50YWdlCiAgICAgICAgIkNNWUtfTSIsICAgICAgICAgLy8gTWFnZW50YSBjb21wb25lbnQgb2YgQ01ZSyBkYXRhIGV4cHJlc3NlZCBhcyBhIHBlcmNlbnRhZ2UKICAgICAgICAiQ01ZS19ZIiwgICAgICAgICAvLyBZZWxsb3cgY29tcG9uZW50IG9mIENNWUsgZGF0YSBleHByZXNzZWQgYXMgYSBwZXJjZW50YWdlCiAgICAgICAgIkNNWUtfSyIsICAgICAgICAgLy8gQmxhY2sgY29tcG9uZW50IG9mIENNWUsgZGF0YSBleHByZXNzZWQgYXMgYSBwZXJjZW50YWdlCiAgICAgICAgIkRfUkVEIiwgICAgICAgICAgLy8gUmVkIGZpbHRlciBkZW5zaXR5CiAgICAgICAgIkRfR1JFRU4iLCAgICAgICAgLy8gR3JlZW4gZmlsdGVyIGRlbnNpdHkKICAgICAgICAiRF9CTFVFIiwgICAgICAgICAvLyBCbHVlIGZpbHRlciBkZW5zaXR5CiAgICAgICAgIkRfVklTIiwgICAgICAgICAgLy8gVmlzdWFsIGZpbHRlciBkZW5zaXR5CiAgICAgICAgIkRfTUFKT1JfRklMVEVSIiwgLy8gTWFqb3IgZmlsdGVyIGQgZW5zaXR5CiAgICAgICAgIlJHQl9SIiwgICAgICAgICAgLy8gUmVkIGNvbXBvbmVudCBvZiBSR0IgZGF0YQogICAgICAgICJSR0JfRyIsICAgICAgICAgIC8vIEdyZWVuIGNvbXBvbmVudCBvZiBSR0IgZGF0YQogICAgICAgICJSR0JfQiIsICAgICAgICAgIC8vIEJsdWUgY29tIHBvbmVudCBvZiBSR0IgZGF0YQogICAgICAgICJTUEVDVFJBTF9OTSIsICAgIC8vIFdhdmVsZW5ndGggb2YgbWVhc3VyZW1lbnQgZXhwcmVzc2VkIGluIG5hbm9tZXRlcnMKICAgICAgICAiU1BFQ1RSQUxfUENUIiwgICAvLyBQZXJjZW50YWdlIHJlZmxlY3RhbmNlL3RyYW5zbWl0dGFuY2UKICAgICAgICAiU1BFQ1RSQUxfREVDIiwgICAvLyBSZWZsZWN0YW5jZS90cmFuc21pdHRhbmNlCiAgICAgICAgIlhZWl9YIiwgICAgICAgICAgLy8gWCBjb21wb25lbnQgb2YgdHJpc3RpbXVsdXMgZGF0YQogICAgICAgICJYWVpfWSIsICAgICAgICAgIC8vIFkgY29tcG9uZW50IG9mIHRyaXN0aW11bHVzIGRhdGEKICAgICAgICAiWFlaX1oiLCAgICAgICAgICAvLyBaIGNvbXBvbmVudCBvZiB0cmlzdGltdWx1cyBkYXRhCiAgICAgICAgIlhZWV9YIiAgICAgICAgICAgLy8geCBjb21wb25lbnQgb2YgY2hyb21hdGljaXR5IGRhdGEKICAgICAgICAiWFlZX1kiLCAgICAgICAgICAvLyB5IGNvbXBvbmVudCBvZiBjaHJvbWF0aWNpdHkgZGF0YQogICAgICAgICJYWVlfQ0FQWSIsICAgICAgIC8vIFkgY29tcG9uZW50IG9mIHRyaXN0aW11bHVzIGRhdGEKICAgICAgICAiTEFCX0wiLCAgICAgICAgICAvLyBMKiBjb21wb25lbnQgb2YgTGFiIGRhdGEKICAgICAgICAiTEFCX0EiLCAgICAgICAgICAvLyBhKiBjb21wb25lbnQgb2YgTGFiIGRhdGEKICAgICAgICAiTEFCX0IiLCAgICAgICAgICAvLyBiKiBjb21wb25lbnQgb2YgTGFiIGRhdGEKICAgICAgICAiTEFCX0MiLCAgICAgICAgICAvLyBDKmFiIGNvbXBvbmVudCBvZiBMYWIgZGF0YQogICAgICAgICJMQUJfSCIsICAgICAgICAgIC8vIGhhYiBjb21wb25lbnQgb2YgTGFiIGRhdGEKICAgICAgICAiTEFCX0RFIiAgICAgICAgICAvLyAgQ0lFIGRFCiAgICAgICAgIkxBQl9ERV85NCIsICAgICAgLy8gIENJRSBkRSB1c2luZyBDSUUgOTQKICAgICAgICAiTEFCX0RFX0NNQyIsICAgICAvLyAgZEUgdXNpbmcgQ01DCiAgICAgICAgIkxBQl9ERV8yMDAwIiwgICAgLy8gQ0lFIGRFIHVzaW5nIENJRSBERSAyMDAwCiAgICAgICAgIk1FQU5fREUiLCAgICAgICAgLy8gTWVhbiBEZWx0YSBFIChMQUJfREUpIG9mIHNhbXBsZXMgY29tcGFyZWQgdG8gYmF0Y2ggYXZlcmFnZQogICAgICAgICAgICAgICAgICAgICAgICAgIC8vIChVc2VkIGZvciBkYXRhIGZpbGVzIGZvciBBTlNJIElUOC43LzEgYW5kIElUOC43LzIgdGFyZ2V0cykKICAgICAgICAiU1RERVZfWCIsICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgWCAodHJpc3RpbXVsdXMgZGF0YSkKICAgICAgICAiU1RERVZfWSIsICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgWSAodHJpc3RpbXVsdXMgZGF0YSkKICAgICAgICAiU1RERVZfWiIsICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgWiAodHJpc3RpbXVsdXMgZGF0YSkKICAgICAgICAiU1RERVZfTCIsICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgTCoKICAgICAgICAiU1RERVZfQSIgICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgYSoKICAgICAgICAiU1RERVZfQiIsICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgYioKICAgICAgICAiU1RERVZfREUiLCAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgQ0lFIGRFCiAgICAgICAgIkNISV9TUURfUEFSIn07ICAgLy8gVGhlIGF2ZXJhZ2Ugb2YgdGhlIHN0YW5kYXJkIGRldmlhdGlvbnMgb2YgTCosIGEqIGFuZCBiKi4gSXQgaXMKICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2VkIHRvIGRlcml2ZSBhbiBlc3RpbWF0ZSBvZiB0aGUgY2hpLXNxdWFyZWQgcGFyYW1ldGVyIHdoaWNoIGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVjb21tZW5kZWQgYXMgdGhlIHByZWRpY3RvciBvZiB0aGUgdmFyaWFiaWxpdHkgb2YgZEUKCiNkZWZpbmUgTlVNUFJFREVGSU5FRFNBTVBMRUlEIChzaXplb2YoUHJlZGVmaW5lZFNhbXBsZUlEKS9zaXplb2YoY2hhciAqKSkKCi8vIENoZWNrcyBpZiBjIGlzIGEgc2VwYXJhdG9yCnN0YXRpYwpCT09MIGlzc2VwYXJhdG9yKGludCBjKQp7CiAgICAgICAgcmV0dXJuIChjID09ICcgJykgfHwgKGMgPT0gJ1x0JykgfHwgKGMgPT0gJ1xyJyk7Cn0KCi8vIENoZWNrcyB3aGF0ZXZlciBpZiBjIGlzIGEgdmFsaWQgaWRlbnRpZmllciBjaGFyCgpzdGF0aWMKQk9PTCBpc21pZGRsZShpbnQgYykKewogICByZXR1cm4gKCFpc3NlcGFyYXRvcihjKSAmJiAoYyAhPSAnIycpICYmIChjICE9J1wiJykgJiYgKGMgIT0gJ1wnJykgJiYgKGMgPiAzMikgJiYgKGMgPCAxMjcpKTsKfQoKLy8gQ2hlY2tzIHdoYXRzZXZlciBpZiBjIGlzIGEgdmFsaWQgaWRlbnRpZmllciBtaWRkbGUgY2hhci4Kc3RhdGljCkJPT0wgaXNpZGNoYXIoaW50IGMpCnsKICAgcmV0dXJuIGlzYWxudW0oYykgfHwgaXNtaWRkbGUoYyk7Cn0KCi8vIENoZWNrcyB3aGF0c2V2ZXIgaWYgYyBpcyBhIHZhbGlkIGlkZW50aWZpZXIgZmlyc3QgY2hhci4Kc3RhdGljCkJPT0wgaXNmaXJzdGlkY2hhcihpbnQgYykKewogICAgIHJldHVybiAhaXNkaWdpdChjKSAmJiBpc21pZGRsZShjKTsKfQoKCnN0YXRpYwpCT09MIFN5bkVycm9yKExQSVQ4IGl0OCwgY29uc3QgY2hhciAqVHh0LCAuLi4pCnsKICAgICAgICBjaGFyIEJ1ZmZlclsyNTZdLCBFcnJNc2dbMTAyNF07CiAgICAgICAgdmFfbGlzdCBhcmdzOwoKICAgICAgICB2YV9zdGFydChhcmdzLCBUeHQpOwogICAgICAgIHZzcHJpbnRmKEJ1ZmZlciwgVHh0LCBhcmdzKTsKICAgICAgICB2YV9lbmQoYXJncyk7CgogICAgICAgIHNwcmludGYoRXJyTXNnLCAiJXM6IExpbmUgJWQsICVzIiwgaXQ4LT5GaWxlTmFtZSwgaXQ4LT5saW5lbm8sIEJ1ZmZlcik7CiAgICAgICAgaXQ4LT5zeSA9IFNTWU5FUlJPUjsKICAgICAgICBjbXNTaWduYWxFcnJvcihMQ01TX0VSUkNfQUJPUlRFRCwgRXJyTXNnKTsKICAgICAgICByZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYwpCT09MIENoZWNrKExQSVQ4IGl0OCwgU1lNQk9MIHN5LCBjb25zdCBjaGFyKiBFcnIpCnsKICAgICAgICBpZiAoaXQ4IC0+IHN5ICE9IHN5KQogICAgICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgRXJyKTsKICAgICAgICByZXR1cm4gVFJVRTsKfQoKCgovLyBSZWFkIE5leHQgY2hhcmFjdGVyIGZyb20gc3RyZWFtCnN0YXRpYwp2b2lkIE5leHRDaChMUElUOCBpdDgpCnsKICAgIGlmIChpdDggLT4gU3RyZWFtW2l0OCAtPkluY2x1ZGVTUF0pIHsKCiAgICAgICAgaXQ4IC0+Y2ggPSBmZ2V0YyhpdDggLT5TdHJlYW1baXQ4IC0+SW5jbHVkZVNQXSk7CgogICAgICAgIGlmIChmZW9mKGl0OCAtPiBTdHJlYW1baXQ4IC0+SW5jbHVkZVNQXSkpICB7CgogICAgICAgICAgICBpZiAoaXQ4IC0+SW5jbHVkZVNQID4gMCkgewoKICAgICAgICAgICAgICAgIGZjbG9zZShpdDggLT5TdHJlYW1baXQ4LT5JbmNsdWRlU1AtLV0pOwogICAgICAgICAgICAgICAgaXQ4IC0+IGNoID0gJyAnOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGl0ZXNwYWNlIHRvIGJlIGlnbm9yZWQKCiAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgaXQ4IC0+Y2ggPSAwOyAgIC8vIEVPRgogICAgICAgIH0KCgoKICAgIH0KICAgIGVsc2UgewoKICAgICAgICBpdDgtPmNoID0gKml0OC0+U291cmNlOwogICAgICAgIGlmIChpdDgtPmNoKSBpdDgtPlNvdXJjZSsrOwogICAgfQp9CgoKLy8gVHJ5IHRvIHNlZSBpZiBjdXJyZW50IGlkZW50aWZpZXIgaXMgYSBrZXl3b3JkLCBpZiBzbyByZXR1cm4gdGhlIHJlZmVycmVkIHN5bWJvbApzdGF0aWMKU1lNQk9MIEJpblNyY2hLZXkoY29uc3QgY2hhciAqaWQpCnsKICAgICAgICBpbnQgbCA9IDE7CiAgICAgICAgaW50IHIgPSBOVU1LRVlTOwogICAgICAgIGludCB4LCByZXM7CgogICAgICAgIHdoaWxlIChyID49IGwpCiAgICAgICAgewogICAgICAgICAgICAgICAgeCA9IChsK3IpLzI7CiAgICAgICAgICAgICAgICByZXMgPSBzdHJpY21wKGlkLCBUYWJLZXlzW3gtMV0uaWQpOwogICAgICAgICAgICAgICAgaWYgKHJlcyA9PSAwKSByZXR1cm4gVGFiS2V5c1t4LTFdLnN5OwogICAgICAgICAgICAgICAgaWYgKHJlcyA8IDApIHIgPSB4IC0gMTsKICAgICAgICAgICAgICAgIGVsc2UgbCA9IHggKyAxOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFNOT05FOwp9CgoKLy8gMTAgXm4Kc3RhdGljCmRvdWJsZSB4cG93MTAoaW50IG4pCnsKICAgIHJldHVybiBwb3coMTAsIChkb3VibGUpIG4pOwp9CgoKLy8gIFJlYWRzIGEgUmVhbCBudW1iZXIsIHRyaWVzIHRvIGZvbGxvdyBmcm9tIGludGVnZXIgbnVtYmVyCnN0YXRpYwp2b2lkIFJlYWRSZWFsKExQSVQ4IGl0OCwgaW50IGludW0pCnsKICAgICAgICBpdDgtPmRudW0gPSAoZG91YmxlKSBpbnVtOwoKICAgICAgICB3aGlsZSAoaXNkaWdpdChpdDgtPmNoKSkgewoKICAgICAgICBpdDgtPmRudW0gPSBpdDgtPmRudW0gKiAxMC4wICsgKGl0OC0+Y2ggLSAnMCcpOwogICAgICAgIE5leHRDaChpdDgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGl0OC0+Y2ggPT0gJy4nKSB7ICAgICAgICAvLyBEZWNpbWFsIHBvaW50CgogICAgICAgICAgICAgICAgZG91YmxlIGZyYWMgPSAwLjA7ICAgICAgLy8gZnJhY3Rpb24KICAgICAgICAgICAgICAgIGludCBwcmVjID0gMDsgICAgICAgICAgIC8vIHByZWNpc3Npb24KCiAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsgICAgICAgICAgICAgICAvLyBFYXRzIGRlYy4gcG9pbnQKCiAgICAgICAgICAgICAgICB3aGlsZSAoaXNkaWdpdChpdDgtPmNoKSkgewoKICAgICAgICAgICAgICAgICAgICAgICAgZnJhYyA9IGZyYWMgKiAxMC4wICsgKGl0OC0+Y2ggLSAnMCcpOwogICAgICAgICAgICAgICAgICAgICAgICBwcmVjKys7CiAgICAgICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGl0OC0+ZG51bSA9IGl0OC0+ZG51bSArIChmcmFjIC8geHBvdzEwKHByZWMpKTsKICAgICAgICB9CgogICAgICAgIC8vIEV4cG9uZW50LCBleGFtcGxlIDM0LjAwRSsyMAogICAgICAgIGlmICh0b3VwcGVyKGl0OC0+Y2gpID09ICdFJykgewoKICAgICAgICAgICAgICAgIGludCBlOwogICAgICAgICAgICAgICAgaW50IHNnbjsKCiAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsgc2duID0gMTsKCiAgICAgICAgICAgICAgICBpZiAoaXQ4LT5jaCA9PSAnLScpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIHNnbiA9IC0xOyBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGlmIChpdDgtPmNoID09ICcrJykgewoKICAgICAgICAgICAgICAgICAgICAgICAgc2duID0gKzE7CiAgICAgICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICBlID0gMDsKICAgICAgICAgICAgICAgIHdoaWxlIChpc2RpZ2l0KGl0OC0+Y2gpKSB7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGRvdWJsZSkgZSAqIDEwTCA8IElOVF9NQVgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlID0gZSAqIDEwICsgKGl0OC0+Y2ggLSAnMCcpOwoKICAgICAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZSA9IHNnbiplOwoKICAgICAgICAgICAgICAgIGl0OCAtPiBkbnVtID0gaXQ4IC0+IGRudW0gKiB4cG93MTAoZSk7CiAgICAgICAgfQp9CgoKCi8vIFJlYWRzIG5leHQgc3ltYm9sCnN0YXRpYwp2b2lkIEluU3ltYm9sKExQSVQ4IGl0OCkKewogICAgcmVnaXN0ZXIgY2hhciAqaWRwdHI7CiAgICByZWdpc3RlciBpbnQgazsKICAgIFNZTUJPTCBrZXk7CiAgICBpbnQgc25nOwoKICAgIGRvIHsKCiAgICAgICAgd2hpbGUgKGlzc2VwYXJhdG9yKGl0OC0+Y2gpKQogICAgICAgICAgICBOZXh0Q2goaXQ4KTsKCiAgICAgICAgaWYgKGlzZmlyc3RpZGNoYXIoaXQ4LT5jaCkpIHsgICAgICAgICAgLy8gSWRlbnRpZmllcgoKCiAgICAgICAgICAgIGsgPSAwOwogICAgICAgICAgICBpZHB0ciA9IGl0OC0+aWQ7CgogICAgICAgICAgICBkbyB7CgogICAgICAgICAgICAgICAgaWYgKCsrayA8IE1BWElEKSAqaWRwdHIrKyA9IChjaGFyKSBpdDgtPmNoOwoKICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwoKICAgICAgICAgICAgfSB3aGlsZSAoaXNpZGNoYXIoaXQ4LT5jaCkpOwoKICAgICAgICAgICAgKmlkcHRyID0gJ1wwJzsKCgogICAgICAgICAgICBrZXkgPSBCaW5TcmNoS2V5KGl0OC0+aWQpOwogICAgICAgICAgICBpZiAoa2V5ID09IFNOT05FKSBpdDgtPnN5ID0gU0lERU5UOwogICAgICAgICAgICBlbHNlIGl0OC0+c3kgPSBrZXk7CgogICAgICAgIH0KICAgICAgICBlbHNlICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElzIGEgbnVtYmVyPwogICAgICAgICAgICBpZiAoaXNkaWdpdChpdDgtPmNoKSB8fCBpdDgtPmNoID09ICcuJyB8fCBpdDgtPmNoID09ICctJyB8fCBpdDgtPmNoID09ICcrJykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IHNpZ24gPSAxOwoKICAgICAgICAgICAgICAgIGlmIChpdDgtPmNoID09ICctJykgewogICAgICAgICAgICAgICAgICAgIHNpZ24gPSAtMTsKICAgICAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpdDgtPmludW0gPSAwOwogICAgICAgICAgICAgICAgaXQ4LT5zeSAgID0gU0lOVU07CgogICAgICAgICAgICAgICAgaWYgKGl0OC0+Y2ggPT0gJzAnKSB7ICAgICAgICAgIC8vIDB4bm5ubiAoSGV4YSkgb3IgMGJubm5uIChCaW5hcnkpCgogICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgICAgIGlmICh0b3VwcGVyKGl0OC0+Y2gpID09ICdYJykgewoKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGo7CgogICAgICAgICAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGlzeGRpZ2l0KGl0OC0+Y2gpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdDgtPmNoID0gdG91cHBlcihpdDgtPmNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdDgtPmNoID49ICdBJyAmJiBpdDgtPmNoIDw9ICdGJykgIGogPSBpdDgtPmNoIC0nQScrMTA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGogPSBpdDgtPmNoIC0gJzAnOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobG9uZykgaXQ4LT5pbnVtICogMTZMID4gKGxvbmcpIElOVF9NQVgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3luRXJyb3IoaXQ4LCAiSW52YWxpZCBoZXhhZGVjaW1hbCBudW1iZXIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQ4LT5pbnVtID0gaXQ4LT5pbnVtICogMTYgKyBqOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKHRvdXBwZXIoaXQ4LT5jaCkgPT0gJ0InKSB7ICAvLyBCaW5hcnkKCiAgICAgICAgICAgICAgICAgICAgICAgIGludCBqOwoKICAgICAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChpdDgtPmNoID09ICcwJyB8fCBpdDgtPmNoID09ICcxJykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaiA9IGl0OC0+Y2ggLSAnMCc7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChsb25nKSBpdDgtPmludW0gKiAyTCA+IChsb25nKSBJTlRfTUFYKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIkludmFsaWQgYmluYXJ5IG51bWJlciIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdDgtPmludW0gPSBpdDgtPmludW0gKiAyICsgajsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgoKICAgICAgICAgICAgICAgIHdoaWxlIChpc2RpZ2l0KGl0OC0+Y2gpKSB7CgogICAgICAgICAgICAgICAgICAgIGlmICgobG9uZykgaXQ4LT5pbnVtICogMTBMID4gKGxvbmcpIElOVF9NQVgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgUmVhZFJlYWwoaXQ4LCBpdDgtPmludW0pOwogICAgICAgICAgICAgICAgICAgICAgICBpdDgtPnN5ID0gU0ROVU07CiAgICAgICAgICAgICAgICAgICAgICAgIGl0OC0+ZG51bSAqPSBzaWduOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpdDgtPmludW0gPSBpdDgtPmludW0gKiAxMCArIChpdDgtPmNoIC0gJzAnKTsKICAgICAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoaXQ4LT5jaCA9PSAnLicpIHsKCiAgICAgICAgICAgICAgICAgICAgUmVhZFJlYWwoaXQ4LCBpdDgtPmludW0pOwogICAgICAgICAgICAgICAgICAgIGl0OC0+c3kgPSBTRE5VTTsKICAgICAgICAgICAgICAgICAgICBpdDgtPmRudW0gKj0gc2lnbjsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaXQ4IC0+IGludW0gKj0gc2lnbjsKCiAgICAgICAgICAgICAgICAvLyBTcGVjaWFsIGNhc2UuIE51bWJlcnMgZm9sbG93ZWQgYnkgbGV0dGVycyBhcmUgdGFrZW4gYXMgaWRlbnRpZmllcnMKCiAgICAgICAgICAgICAgICBpZiAoaXNpZGNoYXIoaXQ4IC0+Y2gpKSB7CgogICAgICAgICAgICAgICAgICAgIGlmIChpdDggLT5zeSA9PSBTSU5VTSkgewoKICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZihpdDgtPmlkLCAiJWQiLCBpdDgtPmludW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoaXQ4LT5pZCwgaXQ4IC0+RG91YmxlRm9ybWF0dGVyLCBpdDgtPmRudW0pOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgayA9IChpbnQpIHN0cmxlbihpdDggLT5pZCk7CiAgICAgICAgICAgICAgICAgICAgaWRwdHIgPSBpdDggLT5pZCArIGs7CiAgICAgICAgICAgICAgICAgICAgZG8gewoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCsrayA8IE1BWElEKSAqaWRwdHIrKyA9IChjaGFyKSBpdDgtPmNoOwoKICAgICAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CgogICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKGlzaWRjaGFyKGl0OC0+Y2gpKTsKCiAgICAgICAgICAgICAgICAgICAgKmlkcHRyID0gJ1wwJzsKCiAgICAgICAgICAgICAgICAgICAgaXQ4LT5zeSA9IFNJREVOVDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgc3dpdGNoICgoaW50KSBpdDgtPmNoKSB7CgogICAgICAgIC8vIEVPRiBtYXJrZXIgLS0gaWdub3JlIGl0CiAgICAgICAgY2FzZSAnXHgxYSc6CiAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgLy8gRW9mIHN0cmVhbSBtYXJrZXJzCgogICAgICAgIGNhc2UgMDoKICAgICAgICBjYXNlIC0xOgogICAgICAgICAgICBpdDgtPnN5ID0gU0VPRjsKICAgICAgICAgICAgYnJlYWs7CgoKICAgICAgICAvLyBOZXh0IGxpbmUKCiAgICAgICAgY2FzZSAnXG4nOgogICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgaXQ4LT5zeSA9IFNFT0xOOwogICAgICAgICAgICBpdDgtPmxpbmVubysrOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgLy8gQ29tbWVudAoKICAgICAgICBjYXNlICcjJzoKICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgIHdoaWxlIChpdDgtPmNoICYmIGl0OC0+Y2ggIT0gJ1xuJykKICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwoKICAgICAgICAgICAgaXQ4LT5zeSA9IFNDT01NRU5UOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIC8vIFN0cmluZy4KCiAgICAgICAgY2FzZSAnXCcnOgogICAgICAgIGNhc2UgJ1wiJzoKICAgICAgICAgICAgaWRwdHIgPSBpdDgtPnN0cjsKICAgICAgICAgICAgc25nID0gaXQ4LT5jaDsKICAgICAgICAgICAgayA9IDA7CiAgICAgICAgICAgIE5leHRDaChpdDgpOwoKICAgICAgICAgICAgd2hpbGUgKGsgPCBNQVhTVFIgJiYgaXQ4LT5jaCAhPSBzbmcpIHsKCiAgICAgICAgICAgICAgICBpZiAoaXQ4LT5jaCA9PSAnXG4nfHwgaXQ4LT5jaCA9PSAnXHInKSBrID0gTUFYU1RSKzE7CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAqaWRwdHIrKyA9IChjaGFyKSBpdDgtPmNoOwogICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgICAgIGsrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaXQ4LT5zeSA9IFNTVFJJTkc7CiAgICAgICAgICAgICppZHB0ciA9ICdcMCc7CiAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICBicmVhazsKCgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIlVucmVjb2duaXplZCBjaGFyYWN0ZXI6IDB4JXgiLCBpdDggLT5jaCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgIH0gd2hpbGUgKGl0OC0+c3kgPT0gU0NPTU1FTlQpOwoKICAgIC8vIEhhbmRsZSB0aGUgaW5jbHVkZSBzcGVjaWFsIHRva2VuCgogICAgaWYgKGl0OCAtPiBzeSA9PSBTSU5DTFVERSkgewoKICAgICAgICAgICAgICAgIEZJTEUqIEluY2x1ZGVGaWxlOwoKICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgICAgICBpZiAoIUNoZWNrKGl0OCwgU1NUUklORywgIkZpbGVuYW1lIGV4cGVjdGVkIikpIHJldHVybjsKICAgICAgICAgICAgICAgIEluY2x1ZGVGaWxlID0gZm9wZW4oaXQ4IC0+IHN0ciwgInJ0Iik7CiAgICAgICAgICAgICAgICBpZiAoSW5jbHVkZUZpbGUgPT0gTlVMTCkgewoKICAgICAgICAgICAgICAgICAgICAgICAgU3luRXJyb3IoaXQ4LCAiRmlsZSAlcyBub3QgZm91bmQiLCBpdDggLT5zdHIpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaXQ4IC0+IFN0cmVhbVsrK2l0OCAtPiBJbmNsdWRlU1BdID0gSW5jbHVkZUZpbGU7CiAgICAgICAgICAgICAgICBpdDggLT5jaCA9ICcgJzsKICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICB9Cgp9CgovLyBDaGVja3MgZW5kIG9mIGxpbmUgc2VwYXJhdG9yCnN0YXRpYwpCT09MIENoZWNrRU9MTihMUElUOCBpdDgpCnsKICAgICAgICBpZiAoIUNoZWNrKGl0OCwgU0VPTE4sICJFeHBlY3RlZCBzZXBhcmF0b3IiKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIHdoaWxlIChpdDggLT4gc3kgPT0gU0VPTE4pCiAgICAgICAgICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgcmV0dXJuIFRSVUU7Cgp9CgovLyBTa2lwIGEgc3ltYm9sCgpzdGF0aWMKdm9pZCBTa2lwKExQSVQ4IGl0OCwgU1lNQk9MIHN5KQp7CiAgICAgICAgaWYgKGl0OC0+c3kgPT0gc3kgJiYgaXQ4LT5zeSAhPSBTRU9GKQogICAgICAgICAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwp9CgoKLy8gU2tpcCBtdWx0aXBsZSBFT0xOCnN0YXRpYwp2b2lkIFNraXBFT0xOKExQSVQ4IGl0OCkKewogICAgd2hpbGUgKGl0OC0+c3kgPT0gU0VPTE4pIHsKICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICB9Cn0KCgovLyBSZXR1cm5zIGEgc3RyaW5nIGhvbGRpbmcgY3VycmVudCB2YWx1ZQpzdGF0aWMKQk9PTCBHZXRWYWwoTFBJVDggaXQ4LCBjaGFyKiBCdWZmZXIsIGNvbnN0IGNoYXIqIEVycm9yVGl0bGUpCnsKICAgIHN3aXRjaCAoaXQ4LT5zeSkgewoKICAgIGNhc2UgU0lERU5UOiAgc3RybmNweShCdWZmZXIsIGl0OC0+aWQsIE1BWElELTEpOyBicmVhazsKICAgIGNhc2UgU0lOVU06ICAgc3ByaW50ZihCdWZmZXIsICIlZCIsIGl0OCAtPiBpbnVtKTsgYnJlYWs7CiAgICBjYXNlIFNETlVNOiAgIHNwcmludGYoQnVmZmVyLCBpdDgtPkRvdWJsZUZvcm1hdHRlciwgaXQ4IC0+IGRudW0pOyBicmVhazsKICAgIGNhc2UgU1NUUklORzogc3RybmNweShCdWZmZXIsIGl0OC0+c3RyLCBNQVhTVFItMSk7IGJyZWFrOwoKCiAgICBkZWZhdWx0OgogICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCBFcnJvclRpdGxlKTsKICAgIH0KCiAgICAgcmV0dXJuIFRSVUU7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVGFibGUKCnN0YXRpYwpMUFRBQkxFIEdldFRhYmxlKExQSVQ4IGl0OCkKewogICAgcmV0dXJuIGl0OCAtPlRhYiArIGl0OCAtPm5UYWJsZTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNZW1vcnkgbWFuYWdlbWVudAoKCgovLyBGcmVlcyBhbiBhbGxvY2F0b3IgYW5kIG93bmVkIG1lbW9yeQp2b2lkIExDTVNFWFBPUlQgY21zSVQ4RnJlZShMQ01TSEFORExFIGhJVDgpCnsKICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwoKICAgIGlmIChpdDggPT0gTlVMTCkKICAgICAgICByZXR1cm47CgoKICAgIGlmIChpdDgtPk1lbW9yeVNpbmspIHsKCiAgICAgICAgTFBPV05FRE1FTSBwOwogICAgICAgIExQT1dORURNRU0gbjsKCiAgICAgICAgZm9yIChwID0gaXQ4LT5NZW1vcnlTaW5rOyBwICE9IE5VTEw7IHAgPSBuKSB7CgogICAgICAgICAgICBuID0gcC0+TmV4dDsKICAgICAgICAgICAgaWYgKHAtPlB0cikgZnJlZShwLT5QdHIpOwogICAgICAgICAgICBmcmVlKHApOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoaXQ4LT5NZW1vcnlCbG9jaykKICAgICAgICBmcmVlKGl0OC0+TWVtb3J5QmxvY2spOwoKICAgIGZyZWUoaXQ4KTsKfQoKCi8vIEFsbG9jYXRlcyBhIGNodW5rIG9mIGRhdGEsIGtlZXAgbGlua2VkIGxpc3QKc3RhdGljCnZvaWQqIEFsbG9jQmlnQmxvY2soTFBJVDggaXQ4LCBzaXplX3Qgc2l6ZSkKewogICBMUE9XTkVETUVNIHB0cjE7CiAgIHZvaWQqIHB0ciA9IG1hbGxvYyhzaXplKTsKCiAgICAgICAgaWYgKHB0cikgewoKICAgICAgICAgICAgICAgIFplcm9NZW1vcnkocHRyLCBzaXplKTsKICAgICAgICAgICAgICAgIHB0cjEgPSAoTFBPV05FRE1FTSkgbWFsbG9jKHNpemVvZihPV05FRE1FTSkpOwoKICAgICAgICAgICAgICAgIGlmIChwdHIxID09IE5VTEwpIHsKCiAgICAgICAgICAgICAgICAgICAgZnJlZShwdHIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIFplcm9NZW1vcnkocHRyMSwgc2l6ZW9mKE9XTkVETUVNKSk7CgogICAgICAgICAgICAgICAgcHRyMS0+IFB0ciAgICAgICAgPSBwdHI7CiAgICAgICAgICAgICAgICBwdHIxLT4gTmV4dCAgICAgICA9IGl0OCAtPiBNZW1vcnlTaW5rOwogICAgICAgICAgICAgICAgaXQ4IC0+IE1lbW9yeVNpbmsgPSBwdHIxOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHB0cjsKfQoKCi8vIFN1YmFsbG9jYXRvci4Kc3RhdGljCnZvaWQqIEFsbG9jQ2h1bmsoTFBJVDggaXQ4LCBzaXplX3Qgc2l6ZSkKewogICAgc2l6ZV90IGZyZWUgPSBpdDggLT5BbGxvY2F0b3IuQmxvY2tTaXplIC0gaXQ4IC0+QWxsb2NhdG9yLlVzZWQ7CiAgICBMUEJZVEUgcHRyOwoKICAgIHNpemUgPSBBTElHTkxPTkcoc2l6ZSk7CgogICAgaWYgKHNpemUgPiBmcmVlKSB7CgogICAgICAgIGlmIChpdDggLT4gQWxsb2NhdG9yLkJsb2NrU2l6ZSA9PSAwKQoKICAgICAgICAgICAgICAgIGl0OCAtPiBBbGxvY2F0b3IuQmxvY2tTaXplID0gMjAqMTAyNDsKICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBpdDggLT5BbGxvY2F0b3IuQmxvY2tTaXplICo9IDI7CgogICAgICAgIGlmIChpdDggLT5BbGxvY2F0b3IuQmxvY2tTaXplIDwgc2l6ZSkKICAgICAgICAgICAgICAgIGl0OCAtPkFsbG9jYXRvci5CbG9ja1NpemUgPSBzaXplOwoKICAgICAgICBpdDggLT5BbGxvY2F0b3IuVXNlZCA9IDA7CiAgICAgICAgaXQ4IC0+QWxsb2NhdG9yLkJsb2NrID0gKExQQllURSkgQWxsb2NCaWdCbG9jayhpdDgsIGl0OCAtPkFsbG9jYXRvci5CbG9ja1NpemUpOwogICAgfQoKICAgIHB0ciA9IGl0OCAtPkFsbG9jYXRvci5CbG9jayArIGl0OCAtPkFsbG9jYXRvci5Vc2VkOwogICAgaXQ4IC0+QWxsb2NhdG9yLlVzZWQgKz0gc2l6ZTsKCiAgICByZXR1cm4gKHZvaWQqKSBwdHI7Cgp9CgoKLy8gQWxsb2NhdGVzIGEgc3RyaW5nCnN0YXRpYwpjaGFyICpBbGxvY1N0cmluZyhMUElUOCBpdDgsIGNvbnN0IGNoYXIqIHN0cikKewogICAgc2l6ZV90IFNpemUgPSBzdHJsZW4oc3RyKSsxOwogICAgY2hhciAqcHRyOwoKCiAgICBwdHIgPSAoY2hhciAqKSBBbGxvY0NodW5rKGl0OCwgU2l6ZSk7CiAgICBpZiAocHRyKSBzdHJuY3B5IChwdHIsIHN0ciwgU2l6ZS0xKTsKCiAgICByZXR1cm4gcHRyOwp9CgovLyBTZWFyY2hlcyB0aHJvdWdoIGxpbmtlZCBsaXN0CgpzdGF0aWMKQk9PTCBJc0F2YWlsYWJsZU9uTGlzdChMUEtFWVZBTFVFIHAsIGNvbnN0IGNoYXIqIEtleSwgTFBLRVlWQUxVRSogTGFzdFB0cikKewoKICAgIGZvciAoOyAgcCAhPSBOVUxMOyBwID0gcC0+TmV4dCkgewoKICAgICAgICBpZiAoTGFzdFB0cikgKkxhc3RQdHIgPSBwOwoKICAgICAgICBpZiAoKktleSAhPSAnIycpIHsgLy8gQ29tbWVudHMgYXJlIGlnbm9yZWQKCiAgICAgICAgICAgIGlmIChzdHJpY21wKEtleSwgcC0+S2V5d29yZCkgPT0gMCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVFJVRTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIEZBTFNFOwp9CgoKCi8vIEFkZCBhIHByb3BlcnR5IGludG8gYSBsaW5rZWQgbGlzdApzdGF0aWMKQk9PTCBBZGRUb0xpc3QoTFBJVDggaXQ4LCBMUEtFWVZBTFVFKiBIZWFkLCBjb25zdCBjaGFyICpLZXksIGNvbnN0IGNoYXIqIHhWYWx1ZSwgV1JJVEVNT0RFIFdyaXRlQXMpCnsKICAgIExQS0VZVkFMVUUgcDsKICAgIExQS0VZVkFMVUUgbGFzdDsKCgogICAgLy8gQ2hlY2sgaWYgcHJvcGVydHkgaXMgYWxyZWFkeSBpbiBsaXN0ICh0aGlzIGlzIGFuIGVycm9yKQoKICAgIGlmIChJc0F2YWlsYWJsZU9uTGlzdCgqSGVhZCwgS2V5LCAmbGFzdCkpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgbWF5IHdvcmsgZm9yIGVkaXRpbmcgcHJvcGVydGllcwoKICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3QtPlZhbHVlICAgPSBBbGxvY1N0cmluZyhpdDgsIHhWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0LT5Xcml0ZUFzID0gV3JpdGVBczsKICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUUlVFOwoKICAgICAgICAgICAgIC8vIHJldHVybiBTeW5FcnJvcihpdDgsICJkdXBsaWNhdGUga2V5IDwlcz4iLCBLZXkpOwogICAgfQoKICAgICAgICAvLyBBbGxvY2F0ZSB0aGUgY29udGFpbmVyCiAgICBwID0gKExQS0VZVkFMVUUpIEFsbG9jQ2h1bmsoaXQ4LCBzaXplb2YoS0VZVkFMVUUpKTsKICAgIGlmIChwID09IE5VTEwpCiAgICB7CiAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIkFkZFRvTGlzdDogb3V0IG9mIG1lbW9yeSIpOwogICAgfQoKICAgIC8vIFN0b3JlIG5hbWUgYW5kIHZhbHVlCiAgICBwLT5LZXl3b3JkID0gQWxsb2NTdHJpbmcoaXQ4LCBLZXkpOwoKICAgIGlmICh4VmFsdWUgIT0gTlVMTCkgewoKICAgICAgICBwLT5WYWx1ZSAgID0gQWxsb2NTdHJpbmcoaXQ4LCB4VmFsdWUpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgcC0+VmFsdWUgICA9IE5VTEw7CiAgICB9CgogICAgcC0+TmV4dCAgICA9IE5VTEw7CiAgICBwLT5Xcml0ZUFzID0gV3JpdGVBczsKCiAgICAvLyBLZWVwIHRoZSBjb250YWluZXIgaW4gb3VyIGxpc3QKICAgIGlmICgqSGVhZCA9PSBOVUxMKQogICAgICAgICpIZWFkID0gcDsKICAgIGVsc2UKICAgICAgICBsYXN0LT5OZXh0ID0gcDsKCiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljCkJPT0wgQWRkQXZhaWxhYmxlUHJvcGVydHkoTFBJVDggaXQ4LCBjb25zdCBjaGFyKiBLZXkpCnsKICAgICAgICByZXR1cm4gQWRkVG9MaXN0KGl0OCwgJml0OC0+VmFsaWRLZXl3b3JkcywgS2V5LCBOVUxMLCBXUklURV9VTkNPT0tFRCk7Cn0KCgpzdGF0aWMKQk9PTCBBZGRBdmFpbGFibGVTYW1wbGVJRChMUElUOCBpdDgsIGNvbnN0IGNoYXIqIEtleSkKewogICAgICAgIHJldHVybiBBZGRUb0xpc3QoaXQ4LCAmaXQ4LT5WYWxpZFNhbXBsZUlELCBLZXksIE5VTEwsIFdSSVRFX1VOQ09PS0VEKTsKfQoKCnN0YXRpYwp2b2lkIEFsbG9jVGFibGUoTFBJVDggaXQ4KQp7CiAgICBMUFRBQkxFIHQ7CgogICAgdCA9IGl0OCAtPlRhYiArIGl0OCAtPlRhYmxlc0NvdW50OwoKICAgIHQtPkhlYWRlckxpc3QgPSBOVUxMOwogICAgdC0+RGF0YUZvcm1hdCA9IE5VTEw7CiAgICB0LT5EYXRhICAgICAgID0gTlVMTDsKCiAgICBpdDggLT5UYWJsZXNDb3VudCsrOwp9CgoKaW50IExDTVNFWFBPUlQgY21zSVQ4U2V0VGFibGUoTENNU0hBTkRMRSBJVDgsIGludCBuVGFibGUpCnsKICAgICBMUElUOCBpdDggPSAoTFBJVDgpIElUODsKCiAgICAgaWYgKG5UYWJsZSA+PSBpdDggLT5UYWJsZXNDb3VudCkgewoKICAgICAgICAgaWYgKG5UYWJsZSA9PSBpdDggLT5UYWJsZXNDb3VudCkgewoKICAgICAgICAgICAgIEFsbG9jVGFibGUoaXQ4KTsKICAgICAgICAgfQogICAgICAgICBlbHNlIHsKICAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIlRhYmxlICVkIGlzIG91dCBvZiBzZXF1ZW5jZSIsIG5UYWJsZSk7CiAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgIH0KICAgICB9CgogICAgIGl0OCAtPm5UYWJsZSA9IG5UYWJsZTsKCiAgICAgcmV0dXJuIG5UYWJsZTsKfQoKCgovLyBJbml0IGFuIGVtcHR5IGNvbnRhaW5lcgpMQ01TSEFORExFIExDTVNFWFBPUlQgY21zSVQ4QWxsb2Modm9pZCkKewogICAgTFBJVDggaXQ4OwogICAgaW50IGk7CgogICAgaXQ4ID0gKExQSVQ4KSBtYWxsb2Moc2l6ZW9mKElUOCkpOwogICAgaWYgKGl0OCA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBaZXJvTWVtb3J5KGl0OCwgc2l6ZW9mKElUOCkpOwoKICAgIEFsbG9jVGFibGUoaXQ4KTsKCiAgICBpdDgtPk1lbW9yeUJsb2NrID0gTlVMTDsKICAgIGl0OC0+U3RyZWFtWzBdICAgPSBOVUxMOwogICAgaXQ4LT5JbmNsdWRlU1AgICA9IDA7CiAgICBpdDgtPk1lbW9yeVNpbmsgID0gTlVMTDsKCiAgICBpdDggLT5uVGFibGUgPSAwOwoKICAgIGl0OC0+QWxsb2NhdG9yLlVzZWQgPSAwOwogICAgaXQ4LT5BbGxvY2F0b3IuQmxvY2sgPSBOVUxMOwogICAgaXQ4LT5BbGxvY2F0b3IuQmxvY2tTaXplID0gMDsKCiAgICBpdDgtPlZhbGlkS2V5d29yZHMgPSBOVUxMOwogICAgaXQ4LT5WYWxpZFNhbXBsZUlEID0gTlVMTDsKCiAgICBpdDggLT4gc3kgPSBTTk9ORTsKICAgIGl0OCAtPiBjaCA9ICcgJzsKICAgIGl0OCAtPiBTb3VyY2UgPSBOVUxMOwogICAgaXQ4IC0+IGludW0gPSAwOwogICAgaXQ4IC0+IGRudW0gPSAwLjA7CgogICAgaXQ4IC0+IGxpbmVubyA9IDE7CgogICAgc3RyY3B5KGl0OC0+RG91YmxlRm9ybWF0dGVyLCBERUZBVUxUX0RCTF9GT1JNQVQpOwogICAgc3RyY3B5KGl0OC0+U2hlZXRUeXBlLCAiQ0dBVFMuMTciKTsKCiAgICAvLyBJbml0aWFsaXplIHByZWRlZmluZWQgcHJvcGVydGllcyAmIGRhdGEKCiAgICBmb3IgKGk9MDsgaSA8IE5VTVBSRURFRklORURQUk9QUzsgaSsrKQogICAgICAgICAgICBBZGRBdmFpbGFibGVQcm9wZXJ0eShpdDgsIFByZWRlZmluZWRQcm9wZXJ0aWVzW2ldKTsKCiAgICBmb3IgKGk9MDsgaSA8IE5VTVBSRURFRklORURTQU1QTEVJRDsgaSsrKQogICAgICAgICAgICBBZGRBdmFpbGFibGVTYW1wbGVJRChpdDgsIFByZWRlZmluZWRTYW1wbGVJRFtpXSk7CgoKICAgcmV0dXJuIChMQ01TSEFORExFKSBpdDg7Cn0KCgpjb25zdCBjaGFyKiBMQ01TRVhQT1JUIGNtc0lUOEdldFNoZWV0VHlwZShMQ01TSEFORExFIGhJVDgpCnsKICAgICAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CgogICAgICAgIHJldHVybiBpdDggLT5TaGVldFR5cGU7Cgp9CgpCT09MICBMQ01TRVhQT1JUIGNtc0lUOFNldFNoZWV0VHlwZShMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIFR5cGUpCnsKICAgICAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CgogICAgICAgIHN0cm5jcHkoaXQ4IC0+U2hlZXRUeXBlLCBUeXBlLCBNQVhTVFItMSk7CiAgICAgICAgcmV0dXJuIFRSVUU7Cn0KCkJPT0wgTENNU0VYUE9SVCBjbXNJVDhTZXRDb21tZW50KExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogVmFsKQp7CiAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CgogICAgaWYgKCFWYWwpIHJldHVybiBGQUxTRTsKICAgIGlmICghKlZhbCkgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgIiMgIiwgVmFsLCBXUklURV9VTkNPT0tFRCk7Cn0KCgoKLy8gU2V0cyBhIHByb3BlcnR5CkJPT0wgTENNU0VYUE9SVCBjbXNJVDhTZXRQcm9wZXJ0eVN0cihMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIEtleSwgY29uc3QgY2hhciAqVmFsKQp7CiAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CgogICAgaWYgKCFWYWwpIHJldHVybiBGQUxTRTsKICAgIGlmICghKlZhbCkgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgS2V5LCBWYWwsIFdSSVRFX1NUUklOR0lGWSk7Cn0KCgpCT09MIExDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlEYmwoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCwgZG91YmxlIFZhbCkKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgY2hhciBCdWZmZXJbMTAyNF07CgogICAgc3ByaW50ZihCdWZmZXIsIGl0OC0+RG91YmxlRm9ybWF0dGVyLCBWYWwpOwoKICAgIHJldHVybiBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgY1Byb3AsIEJ1ZmZlciwgV1JJVEVfVU5DT09LRUQpOwp9CgpCT09MIExDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlIZXgoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCwgaW50IFZhbCkKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgY2hhciBCdWZmZXJbMTAyNF07CgogICAgc3ByaW50ZihCdWZmZXIsICIlZCIsIFZhbCk7CgogICAgcmV0dXJuIEFkZFRvTGlzdChpdDgsICZHZXRUYWJsZShpdDgpLT5IZWFkZXJMaXN0LCBjUHJvcCwgQnVmZmVyLCBXUklURV9IRVhBREVDSU1BTCk7Cn0KCkJPT0wgTENNU0VYUE9SVCBjbXNJVDhTZXRQcm9wZXJ0eVVuY29va2VkKExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogS2V5LCBjb25zdCBjaGFyKiBCdWZmZXIpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKCiAgICByZXR1cm4gQWRkVG9MaXN0KGl0OCwgJkdldFRhYmxlKGl0OCktPkhlYWRlckxpc3QsIEtleSwgQnVmZmVyLCBXUklURV9VTkNPT0tFRCk7Cn0KCgovLyBHZXRzIGEgcHJvcGVydHkKY29uc3QgY2hhciogTENNU0VYUE9SVCBjbXNJVDhHZXRQcm9wZXJ0eShMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIEtleSkKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgTFBLRVlWQUxVRSBwOwoKICAgIGlmIChJc0F2YWlsYWJsZU9uTGlzdChHZXRUYWJsZShpdDgpIC0+IEhlYWRlckxpc3QsIEtleSwgJnApKQogICAgewogICAgICAgIHJldHVybiBwIC0+IFZhbHVlOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCgpkb3VibGUgTENNU0VYUE9SVCBjbXNJVDhHZXRQcm9wZXJ0eURibChMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNQcm9wKQp7CiAgICBjb25zdCBjaGFyICp2ID0gY21zSVQ4R2V0UHJvcGVydHkoaElUOCwgY1Byb3ApOwoKICAgIGlmICh2KSByZXR1cm4gYXRvZih2KTsKICAgIGVsc2UgcmV0dXJuIDAuMDsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRGF0YXNldHMKCgpzdGF0aWMKdm9pZCBBbGxvY2F0ZURhdGFGb3JtYXQoTFBJVDggaXQ4KQp7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGlmICh0IC0+IERhdGFGb3JtYXQpIHJldHVybjsgICAgLy8gQWxyZWFkeSBhbGxvY2F0ZWQKCiAgICB0IC0+IG5TYW1wbGVzICA9IChpbnQpIGNtc0lUOEdldFByb3BlcnR5RGJsKGl0OCwgIk5VTUJFUl9PRl9GSUVMRFMiKTsKCiAgICBpZiAodCAtPiBuU2FtcGxlcyA8PSAwKSB7CgogICAgICAgIFN5bkVycm9yKGl0OCwgIkFsbG9jYXRlRGF0YUZvcm1hdDogVW5rbm93biBOVU1CRVJfT0ZfRklFTERTIik7CiAgICAgICAgdCAtPiBuU2FtcGxlcyA9IDEwOwogICAgICAgIH0KCiAgICB0IC0+IERhdGFGb3JtYXQgPSAoY2hhcioqKSBBbGxvY0NodW5rIChpdDgsICh0LT5uU2FtcGxlcyArIDEpICogc2l6ZW9mKGNoYXIgKikpOwogICAgaWYgKHQtPkRhdGFGb3JtYXQgPT0gTlVMTCkKICAgIHsKICAgICAgICBTeW5FcnJvcihpdDgsICJBbGxvY2F0ZURhdGFGb3JtYXQ6IFVuYWJsZSB0byBhbGxvY2F0ZSBkYXRhRm9ybWF0IGFycmF5Iik7CiAgICB9Cgp9CgpzdGF0aWMKY29uc3QgY2hhciAqR2V0RGF0YUZvcm1hdChMUElUOCBpdDgsIGludCBuKQp7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGlmICh0LT5EYXRhRm9ybWF0KQogICAgICAgIHJldHVybiB0LT5EYXRhRm9ybWF0W25dOwoKICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMKQk9PTCBTZXREYXRhRm9ybWF0KExQSVQ4IGl0OCwgaW50IG4sIGNvbnN0IGNoYXIgKmxhYmVsKQp7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGlmICghdC0+RGF0YUZvcm1hdCkKICAgICAgICBBbGxvY2F0ZURhdGFGb3JtYXQoaXQ4KTsKCiAgICBpZiAobiA+IHQgLT4gblNhbXBsZXMpIHsKICAgICAgICBTeW5FcnJvcihpdDgsICJNb3JlIHRoYW4gTlVNQkVSX09GX0ZJRUxEUyBmaWVsZHMuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKCiAgICBpZiAodC0+RGF0YUZvcm1hdCkgewogICAgICAgIHQtPkRhdGFGb3JtYXRbbl0gPSBBbGxvY1N0cmluZyhpdDgsIGxhYmVsKTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKCkJPT0wgTENNU0VYUE9SVCBjbXNJVDhTZXREYXRhRm9ybWF0KExDTVNIQU5ETEUgaCwgaW50IG4sIGNvbnN0IGNoYXIgKlNhbXBsZSkKewogICAgICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaDsKICAgICAgICByZXR1cm4gU2V0RGF0YUZvcm1hdChpdDgsIG4sIFNhbXBsZSk7Cn0KCnN0YXRpYwp2b2lkIEFsbG9jYXRlRGF0YVNldChMUElUOCBpdDgpCnsKICAgIExQVEFCTEUgdCA9IEdldFRhYmxlKGl0OCk7CgogICAgaWYgKHQgLT4gRGF0YSkgcmV0dXJuOyAgICAvLyBBbHJlYWR5IGFsbG9jYXRlZAoKICAgIHQtPiBuU2FtcGxlcyAgID0gYXRvaShjbXNJVDhHZXRQcm9wZXJ0eShpdDgsICJOVU1CRVJfT0ZfRklFTERTIikpOwogICAgdC0+IG5QYXRjaGVzICAgPSBhdG9pKGNtc0lUOEdldFByb3BlcnR5KGl0OCwgIk5VTUJFUl9PRl9TRVRTIikpOwoKICAgIHQtPiBEYXRhID0gKGNoYXIqKilBbGxvY0NodW5rIChpdDgsICh0LT5uU2FtcGxlcyArIDEpICogKHQtPm5QYXRjaGVzICsgMSkgKnNpemVvZiAoY2hhciopKTsKICAgIGlmICh0LT5EYXRhID09IE5VTEwpCiAgICB7CiAgICAgICAgU3luRXJyb3IoaXQ4LCAiQWxsb2NhdGVEYXRhU2V0OiBVbmFibGUgdG8gYWxsb2NhdGUgZGF0YSBhcnJheSIpOwogICAgfQoKfQoKc3RhdGljCmNoYXIqIEdldERhdGEoTFBJVDggaXQ4LCBpbnQgblNldCwgaW50IG5GaWVsZCkKewogICAgTFBUQUJMRSB0ID0gR2V0VGFibGUoaXQ4KTsKICAgIGludCAgblNhbXBsZXMgICA9IHQgLT4gblNhbXBsZXM7CiAgICBpbnQgIG5QYXRjaGVzICAgPSB0IC0+IG5QYXRjaGVzOwoKCiAgICBpZiAoblNldCA+PSBuUGF0Y2hlcyB8fCBuRmllbGQgPj0gblNhbXBsZXMpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKCF0LT5EYXRhKSByZXR1cm4gTlVMTDsKICAgIHJldHVybiB0LT5EYXRhIFtuU2V0ICogblNhbXBsZXMgKyBuRmllbGRdOwp9CgpzdGF0aWMKQk9PTCBTZXREYXRhKExQSVQ4IGl0OCwgaW50IG5TZXQsIGludCBuRmllbGQsIGNvbnN0IGNoYXIgKlZhbCkKewogICAgTFBUQUJMRSB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBpZiAoIXQtPkRhdGEpCiAgICAgICAgQWxsb2NhdGVEYXRhU2V0KGl0OCk7CgogICAgaWYgKCF0LT5EYXRhKSByZXR1cm4gRkFMU0U7CgoKCiAgICBpZiAoblNldCA+IHQgLT4gblBhdGNoZXMgfHwgblNldCA8IDApIHsKCiAgICAgICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsICJQYXRjaCAlZCBvdXQgb2YgcmFuZ2UsIHRoZXJlIGFyZSAlZCBwYXRjaGVzIiwgblNldCwgdCAtPiBuUGF0Y2hlcyk7CiAgICB9CgogICAgaWYgKG5GaWVsZCA+IHQgLT5uU2FtcGxlcyB8fCBuRmllbGQgPCAwKSB7CiAgICAgICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsICJTYW1wbGUgJWQgb3V0IG9mIHJhbmdlLCB0aGVyZSBhcmUgJWQgc2FtcGxlcyIsIG5GaWVsZCwgdCAtPm5TYW1wbGVzKTsKCiAgICB9CgoKICAgIHQtPkRhdGEgW25TZXQgKiB0IC0+IG5TYW1wbGVzICsgbkZpZWxkXSA9IEFsbG9jU3RyaW5nKGl0OCwgVmFsKTsKICAgIHJldHVybiBUUlVFOwp9CgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpbGUgSS9PCgoKLy8gV3JpdGVzIGEgc3RyaW5nIHRvIGZpbGUKc3RhdGljCnZvaWQgV3JpdGVTdHIoTFBTQVZFU1RSRUFNIGYsIGNvbnN0IGNoYXIgKnN0cikKewoKICAgICAgICBzaXplX3QgbGVuOwoKICAgICAgICBpZiAoc3RyID09IE5VTEwpCiAgICAgICAgICAgICAgICBzdHIgPSAiICI7CgogICAgICAgIC8vIExlbmdodGggdG8gd3JpdGUKICAgICAgICBsZW4gPSBzdHJsZW4oc3RyKTsKICAgIGYgLT5Vc2VkICs9IGxlbjsKCgogICAgICAgIGlmIChmIC0+c3RyZWFtKSB7ICAgICAgIC8vIFNob3VsZCBJIHdyaXRlIGl0IHRvIGEgZmlsZT8KCiAgICAgICAgICAgICAgICBmd3JpdGUoc3RyLCAxLCBsZW4sIGYtPnN0cmVhbSk7CgogICAgICAgIH0KICAgICAgICBlbHNlIHsgIC8vIE9yIHRvIGEgbWVtb3J5IGJsb2NrPwoKCiAgICAgICAgICAgICAgICBpZiAoZiAtPkJhc2UpIHsgICAvLyBBbSBJIGp1c3QgY291bnRpbmcgdGhlIGJ5dGVzPwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGYgLT5Vc2VkID4gZiAtPk1heCkgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNTaWduYWxFcnJvcihMQ01TX0VSUkNfQUJPUlRFRCwgIldyaXRlIHRvIG1lbW9yeSBvdmVyZmxvd3MgaW4gQ0dBVFMgcGFyc2VyIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBDb3B5TWVtb3J5KGYgLT5QdHIsIHN0ciwgbGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgZi0+UHRyICs9IGxlbjsKCiAgICAgICAgICAgICAgICB9CgogICAgICAgIH0KfQoKCi8vCnN0YXRpYwp2b2lkIFdyaXRlZihMUFNBVkVTVFJFQU0gZiwgY29uc3QgY2hhciogZnJtLCAuLi4pCnsKICAgIGNoYXIgQnVmZmVyWzQwOTZdOwogICAgdmFfbGlzdCBhcmdzOwoKICAgIHZhX3N0YXJ0KGFyZ3MsIGZybSk7CiAgICB2c3ByaW50ZihCdWZmZXIsIGZybSwgYXJncyk7CiAgICBXcml0ZVN0cihmLCBCdWZmZXIpOwogICAgdmFfZW5kKGFyZ3MpOwoKfQoKLy8gV3JpdGVzIGZ1bGwgaGVhZGVyCnN0YXRpYwp2b2lkIFdyaXRlSGVhZGVyKExQSVQ4IGl0OCwgTFBTQVZFU1RSRUFNIGZwKQp7CiAgICBMUEtFWVZBTFVFIHA7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKCiAgICBmb3IgKHAgPSB0LT5IZWFkZXJMaXN0OyAocCAhPSBOVUxMKTsgcCA9IHAtPk5leHQpCiAgICB7CiAgICAgICAgaWYgKCpwIC0+S2V5d29yZCA9PSAnIycpIHsKCiAgICAgICAgICAgIGNoYXIqIFB0OwoKICAgICAgICAgICAgV3JpdGVTdHIoZnAsICIjXG4jICIpOwogICAgICAgICAgICBmb3IgKFB0ID0gcCAtPlZhbHVlOyAqUHQ7IFB0KyspIHsKCgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdyaXRlZihmcCwgIiVjIiwgKlB0KTsKCiAgICAgICAgICAgICAgICBpZiAoKlB0ID09ICdcbicpIHsKICAgICAgICAgICAgICAgICAgICBXcml0ZVN0cihmcCwgIiMgIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAiXG4jXG4iKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKCiAgICAgICAgaWYgKCFJc0F2YWlsYWJsZU9uTGlzdChpdDgtPiBWYWxpZEtleXdvcmRzLCBwLT5LZXl3b3JkLCBOVUxMKSkgewoKI2lmZGVmIFNUUklDVF9DR0FUUwogICAgICAgICAgICBXcml0ZVN0cihmcCwgIktFWVdPUkRcdFwiIik7CiAgICAgICAgICAgIFdyaXRlU3RyKGZwLCBwLT5LZXl3b3JkKTsKICAgICAgICAgICAgV3JpdGVTdHIoZnAsICJcIlxuIik7CiNlbmRpZgoKICAgICAgICAgICAgQWRkQXZhaWxhYmxlUHJvcGVydHkoaXQ4LCBwLT5LZXl3b3JkKTsKCiAgICAgICAgfQoKICAgICAgICBXcml0ZVN0cihmcCwgcC0+S2V5d29yZCk7CiAgICAgICAgaWYgKHAtPlZhbHVlKSB7CgogICAgICAgICAgICBzd2l0Y2ggKHAgLT5Xcml0ZUFzKSB7CgogICAgICAgICAgICBjYXNlIFdSSVRFX1VOQ09PS0VEOgogICAgICAgICAgICAgICAgICAgIFdyaXRlZihmcCwgIlx0JXMiLCBwIC0+VmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXUklURV9TVFJJTkdJRlk6CiAgICAgICAgICAgICAgICAgICAgV3JpdGVmKGZwLCAiXHRcIiVzXCIiLCBwLT5WYWx1ZSApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXUklURV9IRVhBREVDSU1BTDoKICAgICAgICAgICAgICAgICAgICBXcml0ZWYoZnAsICJcdDB4JVgiLCBhdG9pKHAgLT5WYWx1ZSkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXUklURV9CSU5BUlk6CiAgICAgICAgICAgICAgICAgICAgV3JpdGVmKGZwLCAiXHQweCVCIiwgYXRvaShwIC0+VmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6IFN5bkVycm9yKGl0OCwgIlVua25vd24gd3JpdGUgbW9kZSAlZCIsIHAgLT5Xcml0ZUFzKTsKICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBXcml0ZVN0ciAoZnAsICJcbiIpOwogICAgfQoKfQoKCi8vIFdyaXRlcyB0aGUgZGF0YSBmb3JtYXQKc3RhdGljCnZvaWQgV3JpdGVEYXRhRm9ybWF0KExQU0FWRVNUUkVBTSBmcCwgTFBJVDggaXQ4KQp7CiAgICBpbnQgaSwgblNhbXBsZXM7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGlmICghdCAtPiBEYXRhRm9ybWF0KSByZXR1cm47CgogICAgICAgV3JpdGVTdHIoZnAsICJCRUdJTl9EQVRBX0ZPUk1BVFxuIik7CiAgICAgICBXcml0ZVN0cihmcCwgIiAiKTsKICAgICAgIG5TYW1wbGVzID0gYXRvaShjbXNJVDhHZXRQcm9wZXJ0eShpdDgsICJOVU1CRVJfT0ZfRklFTERTIikpOwoKICAgICAgIGZvciAoaSA9IDA7IGkgPCBuU2FtcGxlczsgaSsrKSB7CgogICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCB0LT5EYXRhRm9ybWF0W2ldKTsKICAgICAgICAgICAgICBXcml0ZVN0cihmcCwgKChpID09IChuU2FtcGxlcy0xKSkgPyAiXG4iIDogIlx0IikpOwogICAgICAgICAgfQoKICAgICAgIFdyaXRlU3RyIChmcCwgIkVORF9EQVRBX0ZPUk1BVFxuIik7Cn0KCgovLyBXcml0ZXMgZGF0YSBhcnJheQpzdGF0aWMKdm9pZCBXcml0ZURhdGEoTFBTQVZFU1RSRUFNIGZwLCBMUElUOCBpdDgpCnsKICAgICAgIGludCAgaSwgajsKICAgICAgIExQVEFCTEUgdCA9IEdldFRhYmxlKGl0OCk7CgogICAgICAgaWYgKCF0LT5EYXRhKSByZXR1cm47CgogICAgICAgV3JpdGVTdHIgKGZwLCAiQkVHSU5fREFUQVxuIik7CgogICAgICAgdC0+blBhdGNoZXMgPSBhdG9pKGNtc0lUOEdldFByb3BlcnR5KGl0OCwgIk5VTUJFUl9PRl9TRVRTIikpOwoKICAgICAgIGZvciAoaSA9IDA7IGkgPCB0LT4gblBhdGNoZXM7IGkrKykgewoKICAgICAgICAgICAgICBXcml0ZVN0cihmcCwgIiAiKTsKCiAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IHQtPm5TYW1wbGVzOyBqKyspIHsKCiAgICAgICAgICAgICAgICAgICAgIGNoYXIgKnB0ciA9IHQtPkRhdGFbaSp0LT5uU2FtcGxlcytqXTsKCiAgICAgICAgICAgICAgICAgICAgIGlmIChwdHIgPT0gTlVMTCkgV3JpdGVTdHIoZnAsICJcIlwiIik7CiAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdmFsdWUgY29udGFpbnMgd2hpdGVzcGFjZSwgZW5jbG9zZSB3aXRoaW4gcXVvdGUKCiAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RyY2hyKHB0ciwgJyAnKSAhPSBOVUxMKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAiXCIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXcml0ZVN0cihmcCwgcHRyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXcml0ZVN0cihmcCwgIlwiIik7CiAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBXcml0ZVN0cihmcCwgcHRyKTsKICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgV3JpdGVTdHIoZnAsICgoaiA9PSAodC0+blNhbXBsZXMtMSkpID8gIlxuIiA6ICJcdCIpKTsKICAgICAgICAgICAgICB9CiAgICAgICB9CiAgICAgICBXcml0ZVN0ciAoZnAsICJFTkRfREFUQVxuIik7Cn0KCgoKLy8gU2F2ZXMgd2hvbGUgZmlsZQpCT09MIExDTVNFWFBPUlQgY21zSVQ4U2F2ZVRvRmlsZShMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNGaWxlTmFtZSkKewogICAgU0FWRVNUUkVBTSBzZDsKICAgIGludCBpOwogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwoKICAgICAgICBaZXJvTWVtb3J5KCZzZCwgc2l6ZW9mKFNBVkVTVFJFQU0pKTsKCiAgICBzZC5zdHJlYW0gPSBmb3BlbihjRmlsZU5hbWUsICJ3dCIpOwogICAgaWYgKCFzZC5zdHJlYW0pIHJldHVybiBGQUxTRTsKCiAgICBXcml0ZVN0cigmc2QsIGl0OC0+U2hlZXRUeXBlKTsKICAgIFdyaXRlU3RyKCZzZCwgIlxuIik7CiAgICBmb3IgKGk9MDsgaSA8IGl0OCAtPlRhYmxlc0NvdW50OyBpKyspIHsKCiAgICAgICAgICAgIGNtc0lUOFNldFRhYmxlKGhJVDgsIGkpOwogICAgICAgICAgICBXcml0ZUhlYWRlcihpdDgsICZzZCk7CiAgICAgICAgICAgIFdyaXRlRGF0YUZvcm1hdCgmc2QsIGl0OCk7CiAgICAgICAgICAgIFdyaXRlRGF0YSgmc2QsIGl0OCk7CiAgICB9CgogICAgICAgIGZjbG9zZShzZC5zdHJlYW0pOwoKICAgIHJldHVybiBUUlVFOwp9CgoKLy8gU2F2ZXMgdG8gbWVtb3J5CkJPT0wgTENNU0VYUE9SVCBjbXNJVDhTYXZlVG9NZW0oTENNU0hBTkRMRSBoSVQ4LCB2b2lkICpNZW1QdHIsIHNpemVfdCogQnl0ZXNOZWVkZWQpCnsKICAgIFNBVkVTVFJFQU0gc2Q7CiAgICBpbnQgaTsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKCiAgICAgICAgWmVyb01lbW9yeSgmc2QsIHNpemVvZihTQVZFU1RSRUFNKSk7CgogICAgc2Quc3RyZWFtID0gTlVMTDsKICAgICAgICBzZC5CYXNlICAgPSAoTFBCWVRFKSBNZW1QdHI7CiAgICAgICAgc2QuUHRyICAgID0gc2QuQmFzZTsKCiAgICAgICAgc2QuVXNlZCA9IDA7CgogICAgICAgIGlmIChzZC5CYXNlKQogICAgICAgICAgICAgICAgc2QuTWF4ICA9ICpCeXRlc05lZWRlZDsgICAgICAgICAvLyBXcml0ZSB0byBtZW1vcnk/CiAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgc2QuTWF4ICA9IDA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEp1c3QgY291bnRpbmcgdGhlIG5lZWRlZCBieXRlcwoKICAgIFdyaXRlU3RyKCZzZCwgaXQ4LT5TaGVldFR5cGUpOwogICAgV3JpdGVTdHIoJnNkLCAiXG4iKTsKICAgIGZvciAoaT0wOyBpIDwgaXQ4IC0+VGFibGVzQ291bnQ7IGkrKykgewoKICAgICAgICAgICAgY21zSVQ4U2V0VGFibGUoaElUOCwgaSk7CiAgICAgICAgICAgIFdyaXRlSGVhZGVyKGl0OCwgJnNkKTsKICAgICAgICAgICAgV3JpdGVEYXRhRm9ybWF0KCZzZCwgaXQ4KTsKICAgICAgICAgICAgV3JpdGVEYXRhKCZzZCwgaXQ4KTsKICAgIH0KCiAgICAgICAgc2QuVXNlZCsrOyAgICAgIC8vIFRoZSBcMCBhdCB0aGUgdmVyeSBlbmQKCiAgICAgICAgaWYgKHNkLkJhc2UpCiAgICAgICAgICAgICAgICBzZC5QdHIgPSAwOwoKICAgICAgICAqQnl0ZXNOZWVkZWQgPSBzZC5Vc2VkOwoKICAgIHJldHVybiBUUlVFOwp9CgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSGlnZXIgbGV2ZWwgcGFyc2luZwoKc3RhdGljCkJPT0wgRGF0YUZvcm1hdFNlY3Rpb24oTFBJVDggaXQ4KQp7CiAgICBpbnQgaUZpZWxkID0gMDsKICAgIExQVEFCTEUgdCA9IEdldFRhYmxlKGl0OCk7CgogICAgSW5TeW1ib2woaXQ4KTsgICAvLyBFYXRzICJCRUdJTl9EQVRBX0ZPUk1BVCIKICAgIENoZWNrRU9MTihpdDgpOwoKICAgIHdoaWxlIChpdDgtPnN5ICE9IFNFTkRfREFUQV9GT1JNQVQgJiYKICAgICAgICBpdDgtPnN5ICE9IFNFT0xOICYmCiAgICAgICAgaXQ4LT5zeSAhPSBTRU9GICYmCiAgICAgICAgaXQ4LT5zeSAhPSBTU1lORVJST1IpICB7CgogICAgICAgICAgICBpZiAoaXQ4LT5zeSAhPSBTSURFTlQpIHsKCiAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiU2FtcGxlIHR5cGUgZXhwZWN0ZWQiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFTZXREYXRhRm9ybWF0KGl0OCwgaUZpZWxkLCBpdDgtPmlkKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICBpRmllbGQrKzsKCiAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgIFNraXBFT0xOKGl0OCk7CiAgICAgICB9CgogICAgICAgU2tpcEVPTE4oaXQ4KTsKICAgICAgIFNraXAoaXQ4LCBTRU5EX0RBVEFfRk9STUFUKTsKICAgICAgIFNraXBFT0xOKGl0OCk7CgogICAgICAgaWYgKGlGaWVsZCAhPSB0IC0+blNhbXBsZXMpIHsKICAgICAgICAgICBTeW5FcnJvcihpdDgsICJDb3VudCBtaXNtYXRjaC4gTlVNQkVSX09GX0ZJRUxEUyB3YXMgJWQsIGZvdW5kICVkXG4iLCB0IC0+blNhbXBsZXMsIGlGaWVsZCk7CgoKICAgICAgIH0KCiAgICAgICByZXR1cm4gVFJVRTsKfQoKCgpzdGF0aWMKQk9PTCBEYXRhU2VjdGlvbiAoTFBJVDggaXQ4KQp7CiAgICBpbnQgIGlGaWVsZCA9IDA7CiAgICBpbnQgIGlTZXQgICA9IDA7CiAgICBjaGFyIEJ1ZmZlclsyNTZdOwogICAgTFBUQUJMRSB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBJblN5bWJvbChpdDgpOyAgIC8vIEVhdHMgIkJFR0lOX0RBVEEiCiAgICBDaGVja0VPTE4oaXQ4KTsKCiAgICB3aGlsZSAoaXQ4LT5zeSAhPSBTRU5EX0RBVEEgJiYgaXQ4LT5zeSAhPSBTRU9GKQogICAgewogICAgICAgIGlmIChpRmllbGQgPj0gdCAtPiBuU2FtcGxlcykgewogICAgICAgICAgICBpRmllbGQgPSAwOwogICAgICAgICAgICBpU2V0Kys7CgogICAgICAgIH0KCiAgICAgICAgaWYgKGl0OC0+c3kgIT0gU0VORF9EQVRBICYmIGl0OC0+c3kgIT0gU0VPRikgewoKICAgICAgICAgICAgaWYgKCFHZXRWYWwoaXQ4LCBCdWZmZXIsICJTYW1wbGUgZGF0YSBleHBlY3RlZCIpKQogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgICAgICAgICAgaWYgKCFTZXREYXRhKGl0OCwgaVNldCwgaUZpZWxkLCBCdWZmZXIpKQogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgICAgICAgICAgaUZpZWxkKys7CgogICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICBTa2lwRU9MTihpdDgpOwogICAgICAgIH0KICAgIH0KCiAgICBTa2lwRU9MTihpdDgpOwogICAgU2tpcChpdDgsIFNFTkRfREFUQSk7CiAgICBTa2lwRU9MTihpdDgpOwoKICAgIC8vIENoZWNrIGZvciBkYXRhIGNvbXBsZXRpb24uCgogICAgaWYgKChpU2V0KzEpICE9IHQgLT4gblBhdGNoZXMpCiAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIkNvdW50IG1pc21hdGNoLiBOVU1CRVJfT0ZfU0VUUyB3YXMgJWQsIGZvdW5kICVkXG4iLCB0IC0+blBhdGNoZXMsIGlTZXQrMSk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCgoKCnN0YXRpYwpCT09MIEhlYWRlclNlY3Rpb24oTFBJVDggaXQ4KQp7CiAgICBjaGFyIFZhck5hbWVbTUFYSURdOwogICAgY2hhciBCdWZmZXJbTUFYU1RSXTsKCiAgICAgICAgd2hpbGUgKGl0OC0+c3kgIT0gU0VPRiAmJgogICAgICAgICAgICAgICBpdDgtPnN5ICE9IFNTWU5FUlJPUiAmJgogICAgICAgICAgICAgICBpdDgtPnN5ICE9IFNCRUdJTl9EQVRBX0ZPUk1BVCAmJgogICAgICAgICAgICAgICBpdDgtPnN5ICE9IFNCRUdJTl9EQVRBKSB7CgoKICAgICAgICBzd2l0Y2ggKGl0OCAtPiBzeSkgewoKICAgICAgICBjYXNlIFNLRVlXT1JEOgogICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICAgICAgICAgIGlmICghR2V0VmFsKGl0OCwgQnVmZmVyLCAiS2V5d29yZCBleHBlY3RlZCIpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgICAgICBpZiAoIUFkZEF2YWlsYWJsZVByb3BlcnR5KGl0OCwgQnVmZmVyKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKCiAgICAgICAgY2FzZSBTSURFTlQ6CiAgICAgICAgICAgICAgICBzdHJuY3B5KFZhck5hbWUsIGl0OC0+aWQsIE1BWElELTEpOwoKICAgICAgICAgICAgICAgIGlmICghSXNBdmFpbGFibGVPbkxpc3QoaXQ4LT4gVmFsaWRLZXl3b3JkcywgVmFyTmFtZSwgTlVMTCkpIHsKCiNpZmRlZiBTVFJJQ1RfQ0dBVFMKICAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiVW5kZWZpbmVkIGtleXdvcmQgJyVzJyIsIFZhck5hbWUpOwojZWxzZQogICAgICAgICAgICAgICAgaWYgKCFBZGRBdmFpbGFibGVQcm9wZXJ0eShpdDgsIFZhck5hbWUpKSByZXR1cm4gRkFMU0U7CiNlbmRpZgogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgICAgICBpZiAoIUdldFZhbChpdDgsIEJ1ZmZlciwgIlByb3BlcnR5IGRhdGEgZXhwZWN0ZWQiKSkgcmV0dXJuIEZBTFNFOwoKCiAgICAgICAgICAgICAgICBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgVmFyTmFtZSwgQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGl0OC0+c3kgPT0gU1NUUklORykgPyBXUklURV9TVFJJTkdJRlkgOiBXUklURV9VTkNPT0tFRCk7CgogICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKCiAgICAgICAgY2FzZSBTRU9MTjogYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiZXhwZWN0ZWQga2V5d29yZCBvciBpZGVudGlmaWVyIik7CiAgICAgICAgfQoKICAgIFNraXBFT0xOKGl0OCk7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cgp9CgoKc3RhdGljCkJPT0wgUGFyc2VJVDgoTFBJVDggaXQ4KQp7CiAgICBjaGFyKiBTaGVldFR5cGVQdHI7CgogICAgLy8gRmlyc3QgbGluZSBpcyBhIHZlcnkgc3BlY2lhbCBjYXNlLgoKICAgIHdoaWxlIChpc3NlcGFyYXRvcihpdDgtPmNoKSkKICAgICAgICAgICAgTmV4dENoKGl0OCk7CgogICAgU2hlZXRUeXBlUHRyID0gaXQ4IC0+U2hlZXRUeXBlOwoKICAgIHdoaWxlIChpdDgtPmNoICE9ICdccicgJiYgaXQ4IC0+Y2ggIT0gJ1xuJyAmJiBpdDgtPmNoICE9ICdcdCcgJiYgaXQ4IC0+IGNoICE9IC0xKSB7CgogICAgICAgICpTaGVldFR5cGVQdHIrKz0gKGNoYXIpIGl0OCAtPmNoOwogICAgICAgIE5leHRDaChpdDgpOwogICAgfQoKICAgICpTaGVldFR5cGVQdHIgPSAwOwogICAgSW5TeW1ib2woaXQ4KTsKCiAgICBTa2lwRU9MTihpdDgpOwoKICAgIHdoaWxlIChpdDgtPiBzeSAhPSBTRU9GICYmCiAgICAgICAgICAgaXQ4LT4gc3kgIT0gU1NZTkVSUk9SKSB7CgogICAgICAgICAgICBzd2l0Y2ggKGl0OCAtPiBzeSkgewoKICAgICAgICAgICAgY2FzZSBTQkVHSU5fREFUQV9GT1JNQVQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKCFEYXRhRm9ybWF0U2VjdGlvbihpdDgpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNCRUdJTl9EQVRBOgoKICAgICAgICAgICAgICAgICAgICBpZiAoIURhdGFTZWN0aW9uKGl0OCkpIHJldHVybiBGQUxTRTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGl0OCAtPiBzeSAhPSBTRU9GKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgQWxsb2NUYWJsZShpdDgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQ4IC0+blRhYmxlID0gaXQ4IC0+VGFibGVzQ291bnQgLSAxOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU0VPTE46CiAgICAgICAgICAgICAgICAgICAgU2tpcEVPTE4oaXQ4KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKCFIZWFkZXJTZWN0aW9uKGl0OCkpIHJldHVybiBGQUxTRTsKICAgICAgICAgICB9CgogICAgfQoKICAgIHJldHVybiAoaXQ4IC0+IHN5ICE9IFNTWU5FUlJPUik7Cn0KCgoKLy8gSW5pdCB1c2VmdWxsIHBvaW50ZXJzCgpzdGF0aWMKdm9pZCBDb29rUG9pbnRlcnMoTFBJVDggaXQ4KQp7CiAgICBpbnQgaWRGaWVsZCwgaTsKICAgIGNoYXIqIEZsZDsKICAgIGludCBqOwogICAgaW50IG5PbGRUYWJsZSA9IGl0OCAtPm5UYWJsZTsKCiAgICBmb3IgKGo9MDsgaiA8IGl0OCAtPlRhYmxlc0NvdW50OyBqKyspIHsKCiAgICBMUFRBQkxFIHQgPSBpdDggLT5UYWIgKyBqOwoKICAgIHQgLT4gU2FtcGxlSUQgPSAwOwogICAgaXQ4IC0+blRhYmxlID0gajsKCiAgICBmb3IgKGlkRmllbGQgPSAwOyBpZEZpZWxkIDwgdCAtPiBuU2FtcGxlczsgaWRGaWVsZCsrKQogICAgewogICAgICAgIEZsZCA9IHQtPkRhdGFGb3JtYXRbaWRGaWVsZF07CiAgICAgICAgaWYgKCFGbGQpIGNvbnRpbnVlOwoKCiAgICAgICAgaWYgKHN0cmljbXAoRmxkLCAiU0FNUExFX0lEIikgPT0gMCkgewoKICAgICAgICAgICAgICAgICAgICB0IC0+IFNhbXBsZUlEID0gaWRGaWVsZDsKCiAgICAgICAgZm9yIChpPTA7IGkgPCB0IC0+IG5QYXRjaGVzOyBpKyspIHsKCiAgICAgICAgICAgICAgICBjaGFyICpEYXRhID0gR2V0RGF0YShpdDgsIGksIGlkRmllbGQpOwogICAgICAgICAgICAgICAgaWYgKERhdGEpIHsKICAgICAgICAgICAgICAgICAgICBjaGFyIEJ1ZmZlclsyNTZdOwoKICAgICAgICAgICAgICAgICAgICBzdHJuY3B5KEJ1ZmZlciwgRGF0YSwgMjU1KTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmxlbihCdWZmZXIpIDw9IHN0cmxlbihEYXRhKSkKICAgICAgICAgICAgICAgICAgICAgICAgc3RyY3B5KERhdGEsIEJ1ZmZlcik7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBTZXREYXRhKGl0OCwgaSwgaWRGaWVsZCwgQnVmZmVyKTsKCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgIH0KCiAgICAgICAgLy8gIkxBQkVMIiBpcyBhbiBleHRlbnNpb24uIEl0IGtlZXBzIHJlZmVyZW5jZXMgdG8gZm9yd2FyZCB0YWJsZXMKCiAgICAgICAgaWYgKChzdHJpY21wKEZsZCwgIkxBQkVMIikgPT0gMCkgfHwgRmxkWzBdID09ICckJyApIHsKCiAgICAgICAgICAgICAgICAgICAgLy8gU2VhcmNoIGZvciB0YWJsZSByZWZlcmVuY2VzLi4uCiAgICAgICAgICAgICAgICAgICAgZm9yIChpPTA7IGkgPCB0IC0+IG5QYXRjaGVzOyBpKyspIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICpMYWJlbCA9IEdldERhdGEoaXQ4LCBpLCBpZEZpZWxkKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoTGFiZWwpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGs7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGxhYmVsLCBzZWFyY2ggZm9yIGEgdGFibGUgY29udGFpbmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgcHJvcGVydHkKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrPTA7IGsgPCBpdDggLT5UYWJsZXNDb3VudDsgaysrKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFRBQkxFIFRhYmxlID0gaXQ4IC0+VGFiICsgazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBLRVlWQUxVRSBwOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKElzQXZhaWxhYmxlT25MaXN0KFRhYmxlLT5IZWFkZXJMaXN0LCBMYWJlbCwgJnApKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZhaWxhYmxlLCBrZWVwIHR5cGUgYW5kIHRhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIEJ1ZmZlclsyNTZdOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKlR5cGUgID0gcCAtPlZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICBuVGFibGUgPSBrOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoQnVmZmVyLCAiJXMgJWQgJXMiLCBMYWJlbCwgblRhYmxlLCBUeXBlICk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0RGF0YShpdDgsIGksIGlkRmllbGQsIEJ1ZmZlcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgfQoKCiAgICAgICAgfQoKICAgIH0KICAgIH0KCiAgICBpdDggLT5uVGFibGUgPSBuT2xkVGFibGU7Cn0KCi8vIFRyeSB0byBpbmZlcmUgaWYgdGhlIGZpbGUgaXMgYSBDR0FUUy9JVDggZmlsZSBhdCBhbGwuIFJlYWQgZmlyc3QgbGluZQovLyB0aGF0IHNob3VsZCBiZSBzb21ldGhpbmcgbGlrZSBzb21lIHByaW50YWJsZSBjaGFyYWN0ZXJzIHBsdXMgYSBcbgoKc3RhdGljCkJPT0wgSXNNeUJsb2NrKExQQllURSBCdWZmZXIsIHNpemVfdCBuKQp7CiAgICBzaXplX3QgaTsKCiAgICBpZiAobiA8IDEwKSByZXR1cm4gRkFMU0U7ICAgLy8gVG9vIHNtYWxsCgogICAgaWYgKG4gPiAxMzIpCiAgICAgICAgbiA9IDEzMjsKCiAgICBmb3IgKGkgPSAxOyBpIDwgbjsgaSsrKSB7CgogICAgICAgIGlmIChCdWZmZXJbaV0gPT0gJ1xuJyB8fCBCdWZmZXJbaV0gPT0gJ1xyJyB8fCBCdWZmZXJbaV0gPT0gJ1x0JykgcmV0dXJuIFRSVUU7CiAgICAgICAgaWYgKEJ1ZmZlcltpXSA8IDMyKSByZXR1cm4gRkFMU0U7CgogICAgfQoKICAgIHJldHVybiBGQUxTRTsKCn0KCgpzdGF0aWMKQk9PTCBJc015RmlsZShjb25zdCBjaGFyKiBGaWxlTmFtZSkKewogICBGSUxFICpmcDsKICAgc2l6ZV90IFNpemU7CiAgIEJZVEUgUHRyWzEzM107CgogICBmcCA9IGZvcGVuKEZpbGVOYW1lLCAicnQiKTsKICAgaWYgKCFmcCkgewogICAgICAgY21zU2lnbmFsRXJyb3IoTENNU19FUlJDX0FCT1JURUQsICJGaWxlICclcycgbm90IGZvdW5kIiwgRmlsZU5hbWUpOwogICAgICAgcmV0dXJuIEZBTFNFOwogICB9CgogICBTaXplID0gZnJlYWQoUHRyLCAxLCAxMzIsIGZwKTsKICAgZmNsb3NlKGZwKTsKCiAgIFB0cltTaXplXSA9ICdcMCc7CgogICByZXR1cm4gSXNNeUJsb2NrKFB0ciwgU2l6ZSk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRXhwb3J0ZWQgcm91dGluZXMKCgpMQ01TSEFORExFIExDTVNFWFBPUlQgY21zSVQ4TG9hZEZyb21NZW0odm9pZCAqUHRyLCBzaXplX3QgbGVuKQp7CiAgICBMQ01TSEFORExFIGhJVDg7CiAgICBMUElUOCAgaXQ4OwoKICAgIGlmICghSXNNeUJsb2NrKChMUEJZVEUpIFB0ciwgbGVuKSkgcmV0dXJuIE5VTEw7CgogICAgaElUOCA9IGNtc0lUOEFsbG9jKCk7CiAgICBpZiAoIWhJVDgpIHJldHVybiBOVUxMOwoKICAgIGl0OCA9IChMUElUOCkgaElUODsKICAgIGl0OCAtPk1lbW9yeUJsb2NrID0gKGNoYXIqKSBtYWxsb2MobGVuICsgMSk7CgogICAgc3RybmNweShpdDggLT5NZW1vcnlCbG9jaywgKGNvbnN0IGNoYXIqKSBQdHIsIGxlbik7CiAgICBpdDggLT5NZW1vcnlCbG9ja1tsZW5dID0gMDsKCiAgICBzdHJuY3B5KGl0OC0+RmlsZU5hbWUsICIiLCBNQVhfUEFUSC0xKTsKICAgIGl0OC0+IFNvdXJjZSA9IGl0OCAtPiBNZW1vcnlCbG9jazsKCiAgICBpZiAoIVBhcnNlSVQ4KGl0OCkpIHsKCiAgICAgICAgY21zSVQ4RnJlZShoSVQ4KTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgQ29va1BvaW50ZXJzKGl0OCk7CiAgICBpdDggLT5uVGFibGUgPSAwOwoKICAgIGZyZWUoaXQ4LT5NZW1vcnlCbG9jayk7CiAgICBpdDggLT4gTWVtb3J5QmxvY2sgPSBOVUxMOwoKICAgIHJldHVybiBoSVQ4OwoKCn0KCgpMQ01TSEFORExFIExDTVNFWFBPUlQgY21zSVQ4TG9hZEZyb21GaWxlKGNvbnN0IGNoYXIqIGNGaWxlTmFtZSkKewoKICAgICBMQ01TSEFORExFIGhJVDg7CiAgICAgTFBJVDggIGl0ODsKCiAgICAgaWYgKCFJc015RmlsZShjRmlsZU5hbWUpKSByZXR1cm4gTlVMTDsKCiAgICAgaElUOCA9IGNtc0lUOEFsbG9jKCk7CiAgICAgaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgIGlmICghaElUOCkgcmV0dXJuIE5VTEw7CgoKICAgICBpdDggLT5TdHJlYW1bMF0gPSBmb3BlbihjRmlsZU5hbWUsICJydCIpOwoKICAgICBpZiAoIWl0OCAtPlN0cmVhbVswXSkgewogICAgICAgICBjbXNJVDhGcmVlKGhJVDgpOwogICAgICAgICByZXR1cm4gTlVMTDsKICAgICB9CgoKICAgIHN0cm5jcHkoaXQ4LT5GaWxlTmFtZSwgY0ZpbGVOYW1lLCBNQVhfUEFUSC0xKTsKCiAgICBpZiAoIVBhcnNlSVQ4KGl0OCkpIHsKCiAgICAgICAgICAgIGZjbG9zZShpdDggLT5TdHJlYW1bMF0pOwogICAgICAgICAgICBjbXNJVDhGcmVlKGhJVDgpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBDb29rUG9pbnRlcnMoaXQ4KTsKICAgIGl0OCAtPm5UYWJsZSA9IDA7CgogICAgZmNsb3NlKGl0OCAtPlN0cmVhbVswXSk7CiAgICByZXR1cm4gaElUODsKCn0KCmludCBMQ01TRVhQT1JUIGNtc0lUOEVudW1EYXRhRm9ybWF0KExDTVNIQU5ETEUgaElUOCwgY2hhciAqKipTYW1wbGVOYW1lcykKewogICAgICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKICAgICAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgICAgICAqU2FtcGxlTmFtZXMgPSB0IC0+IERhdGFGb3JtYXQ7CiAgICAgICAgcmV0dXJuIHQgLT4gblNhbXBsZXM7Cn0KCgppbnQgTENNU0VYUE9SVCBjbXNJVDhFbnVtUHJvcGVydGllcyhMQ01TSEFORExFIGhJVDgsIGNoYXIgKioqUHJvcGVydHlOYW1lcykKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgTFBLRVlWQUxVRSBwOwogICAgaW50IG47CiAgICBjaGFyICoqUHJvcHM7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIC8vIFBhc3MjMSAtIGNvdW50IHByb3BlcnRpZXMKCiAgICBuID0gMDsKICAgIGZvciAocCA9IHQgLT4gSGVhZGVyTGlzdDsgIHAgIT0gTlVMTDsgcCA9IHAtPk5leHQpIHsKICAgICAgICBuKys7CiAgICB9CgoKICAgIFByb3BzID0gKGNoYXIgKiopIEFsbG9jQ2h1bmsoaXQ4LCBzaXplb2YoY2hhciAqKSAqIG4pOwoKICAgIC8vIFBhc3MjMiAtIEZpbGwgcG9pbnRlcnMKICAgIG4gPSAwOwogICAgZm9yIChwID0gdCAtPiBIZWFkZXJMaXN0OyAgcCAhPSBOVUxMOyBwID0gcC0+TmV4dCkgewogICAgICAgIFByb3BzW24rK10gPSBwIC0+IEtleXdvcmQ7CiAgICB9CgogICAgKlByb3BlcnR5TmFtZXMgPSBQcm9wczsKICAgIHJldHVybiBuOwp9CgpzdGF0aWMKaW50IExvY2F0ZVBhdGNoKExQSVQ4IGl0OCwgY29uc3QgY2hhciogY1BhdGNoKQp7CiAgICBpbnQgaTsKICAgIGNvbnN0IGNoYXIgKmRhdGE7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGZvciAoaT0wOyBpIDwgdC0+IG5QYXRjaGVzOyBpKyspIHsKCiAgICAgICAgZGF0YSA9IEdldERhdGEoaXQ4LCBpLCB0LT5TYW1wbGVJRCk7CgogICAgICAgIGlmIChkYXRhICE9IE5VTEwpIHsKCiAgICAgICAgICAgICAgICBpZiAoc3RyaWNtcChkYXRhLCBjUGF0Y2gpID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gU3luRXJyb3IoaXQ4LCAiQ291bGRuJ3QgZmluZCBwYXRjaCAnJXMnXG4iLCBjUGF0Y2gpOwogICAgICAgIHJldHVybiAtMTsKfQoKCnN0YXRpYwppbnQgTG9jYXRlRW1wdHlQYXRjaChMUElUOCBpdDgpCnsKICAgIGludCBpOwogICAgY29uc3QgY2hhciAqZGF0YTsKICAgIExQVEFCTEUgdCA9IEdldFRhYmxlKGl0OCk7CgogICAgZm9yIChpPTA7IGkgPCB0LT4gblBhdGNoZXM7IGkrKykgewoKICAgICAgICBkYXRhID0gR2V0RGF0YShpdDgsIGksIHQtPlNhbXBsZUlEKTsKCiAgICAgICAgaWYgKGRhdGEgPT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKCiAgICAgICAgfQoKICAgICAgICByZXR1cm4gLTE7Cn0KCnN0YXRpYwppbnQgTG9jYXRlU2FtcGxlKExQSVQ4IGl0OCwgY29uc3QgY2hhciogY1NhbXBsZSkKewogICAgaW50IGk7CiAgICBjb25zdCBjaGFyICpmbGQ7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGZvciAoaT0wOyBpIDwgdC0+blNhbXBsZXM7IGkrKykgewoKICAgICAgICBmbGQgPSBHZXREYXRhRm9ybWF0KGl0OCwgaSk7CiAgICAgICAgaWYgKHN0cmljbXAoZmxkLCBjU2FtcGxlKSA9PSAwKQogICAgICAgICAgICByZXR1cm4gaTsKICAgIH0KCgogICAgLy8gU3luRXJyb3IoaXQ4LCAiQ291bGRuJ3QgZmluZCBkYXRhIGZpZWxkICVzXG4iLCBjU2FtcGxlKTsKICAgIHJldHVybiAtMTsKCn0KCgppbnQgTENNU0VYUE9SVCBjbXNJVDhHZXREYXRhRm9ybWF0KExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1NhbXBsZSkKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgcmV0dXJuIExvY2F0ZVNhbXBsZShpdDgsIGNTYW1wbGUpOwp9CgoKCmNvbnN0IGNoYXIqIExDTVNFWFBPUlQgY21zSVQ4R2V0RGF0YVJvd0NvbChMQ01TSEFORExFIGhJVDgsIGludCByb3csIGludCBjb2wpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKCiAgICByZXR1cm4gR2V0RGF0YShpdDgsIHJvdywgY29sKTsKfQoKCmRvdWJsZSBMQ01TRVhQT1JUIGNtc0lUOEdldERhdGFSb3dDb2xEYmwoTENNU0hBTkRMRSBoSVQ4LCBpbnQgcm93LCBpbnQgY29sKQp7CiAgICBjb25zdCBjaGFyKiBCdWZmZXI7CgogICAgQnVmZmVyID0gY21zSVQ4R2V0RGF0YVJvd0NvbChoSVQ4LCByb3csIGNvbCk7CgogICAgaWYgKEJ1ZmZlcikgewoKICAgICAgICByZXR1cm4gYXRvZihCdWZmZXIpOwoKICAgIH0gZWxzZQogICAgICAgIHJldHVybiAwOwoKfQoKCkJPT0wgTENNU0VYUE9SVCBjbXNJVDhTZXREYXRhUm93Q29sKExDTVNIQU5ETEUgaElUOCwgaW50IHJvdywgaW50IGNvbCwgY29uc3QgY2hhciogVmFsKQp7CiAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CgogICAgcmV0dXJuIFNldERhdGEoaXQ4LCByb3csIGNvbCwgVmFsKTsKfQoKCkJPT0wgTENNU0VYUE9SVCBjbXNJVDhTZXREYXRhUm93Q29sRGJsKExDTVNIQU5ETEUgaElUOCwgaW50IHJvdywgaW50IGNvbCwgZG91YmxlIFZhbCkKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgY2hhciBCdWZmWzI1Nl07CgogICAgc3ByaW50ZihCdWZmLCBpdDgtPkRvdWJsZUZvcm1hdHRlciwgVmFsKTsKCiAgICByZXR1cm4gU2V0RGF0YShpdDgsIHJvdywgY29sLCBCdWZmKTsKfQoKCgpjb25zdCBjaGFyKiBMQ01TRVhQT1JUIGNtc0lUOEdldERhdGEoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUGF0Y2gsIGNvbnN0IGNoYXIqIGNTYW1wbGUpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKICAgIGludCBpRmllbGQsIGlTZXQ7CgoKICAgIGlGaWVsZCA9IExvY2F0ZVNhbXBsZShpdDgsIGNTYW1wbGUpOwogICAgaWYgKGlGaWVsZCA8IDApIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCgogICAgaVNldCA9IExvY2F0ZVBhdGNoKGl0OCwgY1BhdGNoKTsKICAgIGlmIChpU2V0IDwgMCkgewogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gR2V0RGF0YShpdDgsIGlTZXQsIGlGaWVsZCk7Cn0KCgpkb3VibGUgTENNU0VYUE9SVCBjbXNJVDhHZXREYXRhRGJsKExDTVNIQU5ETEUgaXQ4LCBjb25zdCBjaGFyKiBjUGF0Y2gsIGNvbnN0IGNoYXIqIGNTYW1wbGUpCnsKICAgIGNvbnN0IGNoYXIqIEJ1ZmZlcjsKCiAgICBCdWZmZXIgPSBjbXNJVDhHZXREYXRhKGl0OCwgY1BhdGNoLCBjU2FtcGxlKTsKCiAgICBpZiAoQnVmZmVyKSB7CgogICAgICAgIHJldHVybiBhdG9mKEJ1ZmZlcik7CgogICAgfSBlbHNlIHsKCiAgICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KCgoKQk9PTCBMQ01TRVhQT1JUIGNtc0lUOFNldERhdGEoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUGF0Y2gsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGNTYW1wbGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKlZhbCkKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgaW50IGlGaWVsZCwgaVNldDsKICAgIExQVEFCTEUgdCA9IEdldFRhYmxlKGl0OCk7CgoKICAgIGlGaWVsZCA9IExvY2F0ZVNhbXBsZShpdDgsIGNTYW1wbGUpOwoKICAgIGlmIChpRmllbGQgPCAwKQogICAgICAgIHJldHVybiBGQUxTRTsKCgoKICAgICAgICBpZiAodC0+IG5QYXRjaGVzID09IDApIHsKCiAgICAgICAgICAgICAgICBBbGxvY2F0ZURhdGFGb3JtYXQoaXQ4KTsKICAgICAgICAgICAgICAgIEFsbG9jYXRlRGF0YVNldChpdDgpOwogICAgICAgICAgICAgICAgQ29va1BvaW50ZXJzKGl0OCk7CiAgICAgICAgfQoKCiAgICAgICAgaWYgKHN0cmljbXAoY1NhbXBsZSwgIlNBTVBMRV9JRCIpID09IDApCiAgICAgICAgewoKICAgICAgICAgICAgICAgIGlTZXQgICA9IExvY2F0ZUVtcHR5UGF0Y2goaXQ4KTsKICAgICAgICAgICAgICAgIGlmIChpU2V0IDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiQ291bGRuJ3QgYWRkIG1vcmUgcGF0Y2hlcyAnJXMnXG4iLCBjUGF0Y2gpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlGaWVsZCA9IHQgLT4gU2FtcGxlSUQ7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgaVNldCA9IExvY2F0ZVBhdGNoKGl0OCwgY1BhdGNoKTsKICAgICAgICAgICAgICAgIGlmIChpU2V0IDwgMCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFNldERhdGEoaXQ4LCBpU2V0LCBpRmllbGQsIFZhbCk7Cn0KCgpCT09MIExDTVNFWFBPUlQgY21zSVQ4U2V0RGF0YURibChMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNQYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogY1NhbXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIFZhbCkKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgY2hhciBCdWZmWzI1Nl07CgogICAgICAgIHNwcmludGYoQnVmZiwgaXQ4LT5Eb3VibGVGb3JtYXR0ZXIsIFZhbCk7CiAgICAgICAgcmV0dXJuIGNtc0lUOFNldERhdGEoaElUOCwgY1BhdGNoLCBjU2FtcGxlLCBCdWZmKTsKCn0KCgpjb25zdCBjaGFyKiBMQ01TRVhQT1JUIGNtc0lUOEdldFBhdGNoTmFtZShMQ01TSEFORExFIGhJVDgsIGludCBuUGF0Y2gsIGNoYXIqIGJ1ZmZlcikKewogICAgICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKICAgICAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwogICAgICAgIGNoYXIqIERhdGEgPSBHZXREYXRhKGl0OCwgblBhdGNoLCB0LT5TYW1wbGVJRCk7CgogICAgICAgIGlmICghRGF0YSkgcmV0dXJuIE5VTEw7CiAgICAgICAgaWYgKCFidWZmZXIpIHJldHVybiBEYXRhOwoKICAgICAgICBzdHJjcHkoYnVmZmVyLCBEYXRhKTsKICAgICAgICByZXR1cm4gYnVmZmVyOwp9CgppbnQgTENNU0VYUE9SVCBjbXNJVDhUYWJsZUNvdW50KExDTVNIQU5ETEUgaElUOCkKewogICAgICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKCiAgICAgICAgcmV0dXJuIGl0OCAtPlRhYmxlc0NvdW50Owp9CgovLyBUaGlzIGhhbmRsZXMgdGhlICJMQUJFTCIgZXh0ZW5zaW9uLgovLyBMYWJlbCwgblRhYmxlLCBUeXBlCgppbnQgTENNU0VYUE9SVCBjbXNJVDhTZXRUYWJsZUJ5TGFiZWwoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjU2V0LCBjb25zdCBjaGFyKiBjRmllbGQsIGNvbnN0IGNoYXIqIEV4cGVjdGVkVHlwZSkKewogICAgY29uc3QgY2hhciogY0xhYmVsRmxkOwogICAgY2hhciBUeXBlWzI1Nl0sIExhYmVsWzI1Nl07CiAgICBpbnQgblRhYmxlOwoKICAgIGlmIChjRmllbGQgIT0gTlVMTCAmJiAqY0ZpZWxkID09IDApCiAgICAgICAgICAgIGNGaWVsZCA9ICJMQUJFTCI7CgogICAgaWYgKGNGaWVsZCA9PSBOVUxMKQogICAgICAgICAgICBjRmllbGQgPSAiTEFCRUwiOwoKICAgIGNMYWJlbEZsZCA9IGNtc0lUOEdldERhdGEoaElUOCwgY1NldCwgY0ZpZWxkKTsKICAgIGlmICghY0xhYmVsRmxkKSByZXR1cm4gLTE7CgogICAgaWYgKHNzY2FuZihjTGFiZWxGbGQsICIlcyAlZCAlcyIsIExhYmVsLCAmblRhYmxlLCBUeXBlKSAhPSAzKQogICAgICAgICAgICByZXR1cm4gLTE7CgogICAgaWYgKEV4cGVjdGVkVHlwZSAhPSBOVUxMICYmICpFeHBlY3RlZFR5cGUgPT0gMCkKICAgICAgICBFeHBlY3RlZFR5cGUgPSBOVUxMOwoKICAgIGlmIChFeHBlY3RlZFR5cGUpIHsKCiAgICAgICAgaWYgKHN0cmljbXAoVHlwZSwgRXhwZWN0ZWRUeXBlKSAhPSAwKSByZXR1cm4gLTE7CiAgICB9CgogICAgcmV0dXJuIGNtc0lUOFNldFRhYmxlKGhJVDgsIG5UYWJsZSk7Cn0KCgp2b2lkIExDTVNFWFBPUlQgY21zSVQ4RGVmaW5lRGJsRm9ybWF0KExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogRm9ybWF0dGVyKQp7CiAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CgogICAgaWYgKEZvcm1hdHRlciA9PSBOVUxMKQogICAgICAgIHN0cmNweShpdDgtPkRvdWJsZUZvcm1hdHRlciwgREVGQVVMVF9EQkxfRk9STUFUKTsKICAgIGVsc2UKICAgICAgICBzdHJjcHkoaXQ4LT5Eb3VibGVGb3JtYXR0ZXIsIEZvcm1hdHRlcik7Cn0K