LyoKICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKLy8gVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwovLyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLy8gSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwovLyBmaWxlOgovLwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLwovLyAgTGl0dGxlIENvbG9yIE1hbmFnZW1lbnQgU3lzdGVtCi8vICBDb3B5cmlnaHQgKGMpIDE5OTgtMjAxMiBNYXJ0aSBNYXJpYSBTYWd1ZXIKLy8KLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nCi8vIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwKLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbgovLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwKLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlCi8vIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Ci8vCi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgovLwovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKLy8gRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPCi8vIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5ECi8vIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUKLy8gTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTgovLyBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04KLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCi8vCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vCgojaW5jbHVkZSAibGNtczJfaW50ZXJuYWwuaCIKCgovLyBJVDguNyAvIENHQVRTLjE3LTIwMHggaGFuZGxpbmcgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgojZGVmaW5lIE1BWElEICAgICAgICAxMjggICAgIC8vIE1heCBsZW5ndGggb2YgaWRlbnRpZmllcgojZGVmaW5lIE1BWFNUUiAgICAgIDEwMjQgICAgIC8vIE1heCBsZW5ndGggb2Ygc3RyaW5nCiNkZWZpbmUgTUFYVEFCTEVTICAgIDI1NSAgICAgLy8gTWF4IE51bWJlciBvZiB0YWJsZXMgaW4gYSBzaW5nbGUgc3RyZWFtCiNkZWZpbmUgTUFYSU5DTFVERSAgICAyMCAgICAgLy8gTWF4IG51bWJlciBvZiBuZXN0ZWQgaW5jbHVkZXMKCiNkZWZpbmUgREVGQVVMVF9EQkxfRk9STUFUICAiJS4xMGciIC8vIERvdWJsZSBmb3JtYXR0aW5nCgojaWZkZWYgQ01TX0lTX1dJTkRPV1NfCiMgICAgaW5jbHVkZSA8aW8uaD4KIyAgICBkZWZpbmUgRElSX0NIQVIgICAgJ1xcJwojZWxzZQojICAgIGRlZmluZSBESVJfQ0hBUiAgICAnLycKI2VuZGlmCgoKLy8gU3ltYm9scwp0eXBlZGVmIGVudW0gewoKICAgICAgICBTVU5ERUZJTkVELAogICAgICAgIFNJTlVNLCAgICAgIC8vIEludGVnZXIKICAgICAgICBTRE5VTSwgICAgICAvLyBSZWFsCiAgICAgICAgU0lERU5ULCAgICAgLy8gSWRlbnRpZmllcgogICAgICAgIFNTVFJJTkcsICAgIC8vIHN0cmluZwogICAgICAgIFNDT01NRU5ULCAgIC8vIGNvbW1lbnQKICAgICAgICBTRU9MTiwgICAgICAvLyBFbmQgb2YgbGluZQogICAgICAgIFNFT0YsICAgICAgIC8vIEVuZCBvZiBzdHJlYW0KICAgICAgICBTU1lORVJST1IsICAvLyBTeW50YXggZXJyb3IgZm91bmQgb24gc3RyZWFtCgogICAgICAgIC8vIEtleXdvcmRzCgogICAgICAgIFNCRUdJTl9EQVRBLAogICAgICAgIFNCRUdJTl9EQVRBX0ZPUk1BVCwKICAgICAgICBTRU5EX0RBVEEsCiAgICAgICAgU0VORF9EQVRBX0ZPUk1BVCwKICAgICAgICBTS0VZV09SRCwKICAgICAgICBTREFUQV9GT1JNQVRfSUQsCiAgICAgICAgU0lOQ0xVREUKCiAgICB9IFNZTUJPTDsKCgovLyBIb3cgdG8gd3JpdGUgdGhlIHZhbHVlCnR5cGVkZWYgZW51bSB7CgogICAgICAgIFdSSVRFX1VOQ09PS0VELAogICAgICAgIFdSSVRFX1NUUklOR0lGWSwKICAgICAgICBXUklURV9IRVhBREVDSU1BTCwKICAgICAgICBXUklURV9CSU5BUlksCiAgICAgICAgV1JJVEVfUEFJUgoKICAgIH0gV1JJVEVNT0RFOwoKLy8gTGlua2VkIGxpc3Qgb2YgdmFyaWFibGUgbmFtZXMKdHlwZWRlZiBzdHJ1Y3QgX0tleVZhbCB7CgogICAgICAgIHN0cnVjdCBfS2V5VmFsKiAgTmV4dDsKICAgICAgICBjaGFyKiAgICAgICAgICAgIEtleXdvcmQ7ICAgICAgIC8vIE5hbWUgb2YgdmFyaWFibGUKICAgICAgICBzdHJ1Y3QgX0tleVZhbCogIE5leHRTdWJrZXk7ICAgIC8vIElmIGtleSBpcyBhIGRpY3Rpb25hcnksIHBvaW50cyB0byB0aGUgbmV4dCBpdGVtCiAgICAgICAgY2hhciogICAgICAgICAgICBTdWJrZXk7ICAgICAgICAvLyBJZiBrZXkgaXMgYSBkaWN0aW9uYXJ5LCBwb2ludHMgdG8gdGhlIHN1YmtleSBuYW1lCiAgICAgICAgY2hhciogICAgICAgICAgICBWYWx1ZTsgICAgICAgICAvLyBQb2ludHMgdG8gdmFsdWUKICAgICAgICBXUklURU1PREUgICAgICAgIFdyaXRlQXM7ICAgICAgIC8vIEhvdyB0byB3cml0ZSB0aGUgdmFsdWUKCiAgIH0gS0VZVkFMVUU7CgoKLy8gTGlua2VkIGxpc3Qgb2YgbWVtb3J5IGNodW5rcyAoTWVtb3J5IHNpbmspCnR5cGVkZWYgc3RydWN0IF9Pd25lZE1lbSB7CgogICAgICAgIHN0cnVjdCBfT3duZWRNZW0qIE5leHQ7CiAgICAgICAgdm9pZCAqICAgICAgICAgICAgUHRyOyAgICAgICAgICAvLyBQb2ludCB0byB2YWx1ZQoKICAgfSBPV05FRE1FTTsKCi8vIFN1YmFsbG9jYXRvcgp0eXBlZGVmIHN0cnVjdCBfU3ViQWxsb2NhdG9yIHsKCiAgICAgICAgIGNtc1VJbnQ4TnVtYmVyKiBCbG9jazsKICAgICAgICAgY21zVUludDMyTnVtYmVyIEJsb2NrU2l6ZTsKICAgICAgICAgY21zVUludDMyTnVtYmVyIFVzZWQ7CgogICAgfSBTVUJBTExPQ0FUT1I7CgovLyBUYWJsZS4gRWFjaCBpbmRpdmlkdWFsIHRhYmxlIGNhbiBob2xkIHByb3BlcnRpZXMgYW5kIHJvd3MgJiBjb2xzCnR5cGVkZWYgc3RydWN0IF9UYWJsZSB7CgogICAgICAgIGNoYXIgU2hlZXRUeXBlW01BWFNUUl07ICAgICAgICAgICAgICAgLy8gVGhlIGZpcnN0IHJvdyBvZiB0aGUgSVQ4ICh0aGUgdHlwZSkKCiAgICAgICAgaW50ICAgICAgICAgICAgblNhbXBsZXMsIG5QYXRjaGVzOyAgICAvLyBDb2xzLCBSb3dzCiAgICAgICAgaW50ICAgICAgICAgICAgU2FtcGxlSUQ7ICAgICAgICAgICAgICAvLyBQb3Mgb2YgSUQKCiAgICAgICAgS0VZVkFMVUUqICAgICAgSGVhZGVyTGlzdDsgICAgICAgICAgICAvLyBUaGUgcHJvcGVydGllcwoKICAgICAgICBjaGFyKiogICAgICAgICBEYXRhRm9ybWF0OyAgICAgICAgICAgIC8vIFRoZSBiaW5hcnkgc3RyZWFtIGRlc2NyaXB0b3IKICAgICAgICBjaGFyKiogICAgICAgICBEYXRhOyAgICAgICAgICAgICAgICAgIC8vIFRoZSBiaW5hcnkgc3RyZWFtCgogICAgfSBUQUJMRTsKCi8vIEZpbGUgc3RyZWFtIGJlaW5nIHBhcnNlZAp0eXBlZGVmIHN0cnVjdCBfRmlsZUNvbnRleHQgewogICAgICAgIGNoYXIgICAgICAgICAgIEZpbGVOYW1lW2Ntc01BWF9QQVRIXTsgICAgLy8gRmlsZSBuYW1lIGlmIGJlaW5nIHJlYWRlZCBmcm9tIGZpbGUKICAgICAgICBGSUxFKiAgICAgICAgICBTdHJlYW07ICAgICAgICAgICAgICAgICAgIC8vIEZpbGUgc3RyZWFtIG9yIE5VTEwgaWYgaG9sZGVkIGluIG1lbW9yeQogICAgfSBGSUxFQ1RYOwoKLy8gVGhpcyBzdHJ1Y3QgaG9sZCBhbGwgaW5mb3JtYXRpb24gYWJvdXQgYW4gb3BlbiBJVDggaGFuZGxlci4KdHlwZWRlZiBzdHJ1Y3QgewoKCiAgICAgICAgY21zVUludDMyTnVtYmVyICBUYWJsZXNDb3VudDsgICAgICAgICAgICAgICAgICAgICAvLyBIb3cgbWFueSB0YWJsZXMgaW4gdGhpcyBzdHJlYW0KICAgICAgICBjbXNVSW50MzJOdW1iZXIgIG5UYWJsZTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBhY3R1YWwgdGFibGUKCiAgICAgICAgVEFCTEUgVGFiW01BWFRBQkxFU107CgogICAgICAgIC8vIE1lbW9yeSBtYW5hZ2VtZW50CiAgICAgICAgT1dORURNRU0qICAgICAgTWVtb3J5U2luazsgICAgICAgICAgICAvLyBUaGUgc3RvcmFnZSBiYWNrZW5kCiAgICAgICAgU1VCQUxMT0NBVE9SICAgQWxsb2NhdG9yOyAgICAgICAgICAgICAvLyBTdHJpbmcgc3ViYWxsb2NhdG9yIC0tIGp1c3QgdG8ga2VlcCBpdCBmYXN0CgogICAgICAgIC8vIFBhcnNlciBzdGF0ZSBtYWNoaW5lCiAgICAgICAgU1lNQk9MICAgICAgICAgc3k7ICAgICAgICAgICAgICAgICAgICAvLyBDdXJyZW50IHN5bWJvbAogICAgICAgIGludCAgICAgICAgICAgIGNoOyAgICAgICAgICAgICAgICAgICAgLy8gQ3VycmVudCBjaGFyYWN0ZXIKCiAgICAgICAgaW50ICAgICAgICAgICAgaW51bTsgICAgICAgICAgICAgICAgICAvLyBpbnRlZ2VyIHZhbHVlCiAgICAgICAgY21zRmxvYXQ2NE51bWJlciAgICAgICAgIGRudW07ICAgICAgICAgICAgICAgICAgLy8gcmVhbCB2YWx1ZQogICAgICAgIGNoYXIgICAgICAgICAgIGlkW01BWElEXTsgICAgICAgICAgICAgLy8gaWRlbnRpZmllcgogICAgICAgIGNoYXIgICAgICAgICAgIHN0cltNQVhTVFJdOyAgICAgICAgICAgLy8gc3RyaW5nCgogICAgICAgIC8vIEFsbG93ZWQga2V5d29yZHMgJiBkYXRhc2V0cy4gVGhleSBoYXZlIHZpc2liaWxpdHkgb24gd2hvbGUgc3RyZWFtCiAgICAgICAgS0VZVkFMVUUqICAgICBWYWxpZEtleXdvcmRzOwogICAgICAgIEtFWVZBTFVFKiAgICAgVmFsaWRTYW1wbGVJRDsKCiAgICAgICAgY2hhciogICAgICAgICAgU291cmNlOyAgICAgICAgICAgICAgICAvLyBQb2ludHMgdG8gbG9jLiBiZWluZyBwYXJzZWQKICAgICAgICBpbnQgICAgICAgICAgICBsaW5lbm87ICAgICAgICAgICAgICAgIC8vIGxpbmUgY291bnRlciBmb3IgZXJyb3IgcmVwb3J0aW5nCgogICAgICAgIEZJTEVDVFgqICAgICAgIEZpbGVTdGFja1tNQVhJTkNMVURFXTsgLy8gU3RhY2sgb2YgZmlsZXMgYmVpbmcgcGFyc2VkCiAgICAgICAgaW50ICAgICAgICAgICAgSW5jbHVkZVNQOyAgICAgICAgICAgICAvLyBJbmNsdWRlIFN0YWNrIFBvaW50ZXIKCiAgICAgICAgY2hhciogICAgICAgICAgTWVtb3J5QmxvY2s7ICAgICAgICAgICAvLyBUaGUgc3RyZWFtIGlmIGhvbGRlZCBpbiBtZW1vcnkKCiAgICAgICAgY2hhciAgICAgICAgICAgRG91YmxlRm9ybWF0dGVyW01BWElEXTsvLyBQcmludGYtbGlrZSAnY21zRmxvYXQ2NE51bWJlcicgZm9ybWF0dGVyCgogICAgICAgIGNtc0NvbnRleHQgICAgQ29udGV4dElEOyAgICAgICAgICAgICAgLy8gVGhlIHRocmVhZGluZyBjb250ZXh0CgogICB9IGNtc0lUODsKCgovLyBUaGUgc3RyZWFtIGZvciBzYXZlIG9wZXJhdGlvbnMKdHlwZWRlZiBzdHJ1Y3QgewoKICAgICAgICBGSUxFKiBzdHJlYW07ICAgLy8gRm9yIHNhdmUtdG8tZmlsZSBiZWhhdmlvdXIKCiAgICAgICAgY21zVUludDhOdW1iZXIqIEJhc2U7CiAgICAgICAgY21zVUludDhOdW1iZXIqIFB0cjsgICAgICAgIC8vIEZvciBzYXZlLXRvLW1lbSBiZWhhdmlvdXIKICAgICAgICBjbXNVSW50MzJOdW1iZXIgVXNlZDsKICAgICAgICBjbXNVSW50MzJOdW1iZXIgTWF4OwoKICAgIH0gU0FWRVNUUkVBTTsKCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY21zSVQ4IHBhcnNpbmcgcm91dGluZXMKCgovLyBBIGtleXdvcmQKdHlwZWRlZiBzdHJ1Y3QgewoKICAgICAgICBjb25zdCBjaGFyICppZDsKICAgICAgICBTWU1CT0wgc3k7CgogICB9IEtFWVdPUkQ7CgovLyBUaGUga2V5d29yZC0+c3ltYm9sIHRyYW5zbGF0aW9uIHRhYmxlLiBTb3J0aW5nIGlzIHJlcXVpcmVkLgpzdGF0aWMgY29uc3QgS0VZV09SRCBUYWJLZXlzW10gPSB7CgogICAgICAgIHsiJElOQ0xVREUiLCAgICAgICAgICAgICAgIFNJTkNMVURFfSwgICAvLyBUaGlzIGlzIGFuIGV4dGVuc2lvbiEKICAgICAgICB7Ii5JTkNMVURFIiwgICAgICAgICAgICAgICBTSU5DTFVERX0sICAgLy8gVGhpcyBpcyBhbiBleHRlbnNpb24hCgogICAgICAgIHsiQkVHSU5fREFUQSIsICAgICAgICAgICAgIFNCRUdJTl9EQVRBIH0sCiAgICAgICAgeyJCRUdJTl9EQVRBX0ZPUk1BVCIsICAgICAgU0JFR0lOX0RBVEFfRk9STUFUIH0sCiAgICAgICAgeyJEQVRBX0ZPUk1BVF9JREVOVElGSUVSIiwgU0RBVEFfRk9STUFUX0lEfSwKICAgICAgICB7IkVORF9EQVRBIiwgICAgICAgICAgICAgICBTRU5EX0RBVEF9LAogICAgICAgIHsiRU5EX0RBVEFfRk9STUFUIiwgICAgICAgIFNFTkRfREFUQV9GT1JNQVR9LAogICAgICAgIHsiS0VZV09SRCIsICAgICAgICAgICAgICAgIFNLRVlXT1JEfQogICAgICAgIH07CgojZGVmaW5lIE5VTUtFWVMgKHNpemVvZihUYWJLZXlzKS9zaXplb2YoS0VZV09SRCkpCgovLyBQcmVkZWZpbmVkIHByb3BlcnRpZXMKCi8vIEEgcHJvcGVydHkKdHlwZWRlZiBzdHJ1Y3QgewogICAgICAgIGNvbnN0IGNoYXIgKmlkOyAgICAvLyBUaGUgaWRlbnRpZmllcgogICAgICAgIFdSSVRFTU9ERSBhczsgICAgICAvLyBIb3cgaXMgc3VwcG9zZWQgdG8gYmUgd3JpdHRlbgogICAgfSBQUk9QRVJUWTsKCnN0YXRpYyBQUk9QRVJUWSBQcmVkZWZpbmVkUHJvcGVydGllc1tdID0gewoKICAgICAgICB7Ik5VTUJFUl9PRl9GSUVMRFMiLCBXUklURV9VTkNPT0tFRH0sICAgIC8vIFJlcXVpcmVkIC0gTlVNQkVSIE9GIEZJRUxEUwogICAgICAgIHsiTlVNQkVSX09GX1NFVFMiLCAgIFdSSVRFX1VOQ09PS0VEfSwgICAgLy8gUmVxdWlyZWQgLSBOVU1CRVIgT0YgU0VUUwogICAgICAgIHsiT1JJR0lOQVRPUiIsICAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gUmVxdWlyZWQgLSBJZGVudGlmaWVzIHRoZSBzcGVjaWZpYyBzeXN0ZW0sIG9yZ2FuaXphdGlvbiBvciBpbmRpdmlkdWFsIHRoYXQgY3JlYXRlZCB0aGUgZGF0YSBmaWxlLgogICAgICAgIHsiRklMRV9ERVNDUklQVE9SIiwgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gUmVxdWlyZWQgLSBEZXNjcmliZXMgdGhlIHB1cnBvc2Ugb3IgY29udGVudHMgb2YgdGhlIGRhdGEgZmlsZS4KICAgICAgICB7IkNSRUFURUQiLCAgICAgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIFJlcXVpcmVkIC0gSW5kaWNhdGVzIGRhdGUgb2YgY3JlYXRpb24gb2YgdGhlIGRhdGEgZmlsZS4KICAgICAgICB7IkRFU0NSSVBUT1IiLCAgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIFJlcXVpcmVkICAtIERlc2NyaWJlcyB0aGUgcHVycG9zZSBvciBjb250ZW50cyBvZiB0aGUgZGF0YSBmaWxlLgogICAgICAgIHsiRElGRlVTRV9HRU9NRVRSWSIsIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gVGhlIGRpZmZ1c2UgZ2VvbWV0cnkgdXNlZC4gQWxsb3dlZCB2YWx1ZXMgYXJlICJzcGhlcmUiIG9yICJvcGFsIi4KICAgICAgICB7Ik1BTlVGQUNUVVJFUiIsICAgICBXUklURV9TVFJJTkdJRll9LAogICAgICAgIHsiTUFOVUZBQ1RVUkUiLCAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gU29tZSBicm9rZW4gRnVqaSB0YXJnZXRzIGRvZXMgc3RvcmUgdGhpcyB2YWx1ZQogICAgICAgIHsiUFJPRF9EQVRFIiwgICAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gSWRlbnRpZmllcyB5ZWFyIGFuZCBtb250aCBvZiBwcm9kdWN0aW9uIG9mIHRoZSB0YXJnZXQgaW4gdGhlIGZvcm0geXl5eTptbS4KICAgICAgICB7IlNFUklBTCIsICAgICAgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIFVuaXF1ZWx5IGlkZW50aWZpZXMgaW5kaXZpZHVhbCBwaHlzaWNhbCB0YXJnZXQuCgogICAgICAgIHsiTUFURVJJQUwiLCAgICAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gSWRlbnRpZmllcyB0aGUgbWF0ZXJpYWwgb24gd2hpY2ggdGhlIHRhcmdldCB3YXMgcHJvZHVjZWQgdXNpbmcgYSBjb2RlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1bmlxdWVseSBpZGVudGlmeWluZyB0aCBlIG1hdGVyaWFsLiBUaGlzIGlzIGludGVuZCBlZCB0byBiZSB1c2VkIGZvciBJVDguNwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcGh5c2ljYWwgdGFyZ2V0cyBvbmx5IChpLmUgLiBJVDguNy8xIGEgbmQgSVQ4LjcvMikuCgogICAgICAgIHsiSU5TVFJVTUVOVEFUSU9OIiwgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gVXNlZCB0byByZXBvcnQgdGhlIHNwZWNpZmljIGluc3RydW1lbnRhdGlvbiB1c2VkIChtYW51ZmFjdHVyZXIgYW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtb2RlbCBudW1iZXIpIHRvIGdlbmVyYXRlIHRoZSBkYXRhIHJlcG9ydGVkLiBUaGlzIGRhdGEgd2lsbCBvZnRlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJvdmlkZSBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwYXJ0aWN1bGFyIGRhdGEgY29sbGVjdGVkIHRoYW4gYW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dGVuc2l2ZSBsaXN0IG9mIHNwZWNpZmljIGRldGFpbHMuIFRoaXMgaXMgcGFydGljdWxhcmx5IGltcG9ydGFudCBmb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNwZWN0cmFsIGRhdGEgb3IgZGF0YSBkZXJpdmVkIGZyb20gc3BlY3Ryb3Bob3RvbWV0cnkuCgogICAgICAgIHsiTUVBU1VSRU1FTlRfU09VUkNFIiwgV1JJVEVfU1RSSU5HSUZZfSwgLy8gSWxsdW1pbmF0aW9uIHVzZWQgZm9yIHNwZWN0cmFsIG1lYXN1cmVtZW50cy4gVGhpcyBkYXRhIGhlbHBzIHByb3ZpZGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgZ3VpZGUgdG8gdGhlIHBvdGVudGlhbCBmb3IgaXNzdWVzIG9mIHBhcGVyIGZsdW9yZXNjZW5jZSwgZXRjLgoKICAgICAgICB7IlBSSU5UX0NPTkRJVElPTlMiLCBXUklURV9TVFJJTkdJRll9LCAgIC8vIFVzZWQgdG8gZGVmaW5lIHRoZSBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIHByaW50ZWQgc2hlZXQgYmVpbmcgcmVwb3J0ZWQuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGVyZSBzdGFuZGFyZCBjb25kaXRpb25zIGhhdmUgYmVlbiBkZWZpbmVkIChlLmcuLCBTV09QIGF0IG5vbWluYWwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBuYW1lZCBjb25kaXRpb25zIG1heSBzdWZmaWNlLiBPdGhlcndpc2UsIGRldGFpbGVkIGluZm9ybWF0aW9uIGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBuZWVkZWQuCgogICAgICAgIHsiU0FNUExFX0JBQ0tJTkciLCAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gSWRlbnRpZmllcyB0aGUgYmFja2luZyBtYXRlcmlhbCB1c2VkIGJlaGluZCB0aGUgc2FtcGxlIGR1cmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWVhc3VyZW1lbnQuIEFsbG93ZWQgdmFsdWVzIGFyZSCTYmxhY2uULCCTd2hpdGWULCBvciB7Im5hIi4KCiAgICAgICAgeyJDSElTUV9ET0YiLCAgICAgICAgV1JJVEVfU1RSSU5HSUZZfSwgICAvLyBEZWdyZWVzIG9mIGZyZWVkb20gYXNzb2NpYXRlZCB3aXRoIHRoZSBDaGkgc3F1YXJlZCBzdGF0aXN0aWMKCiAgICAgICAvLyBiZWxvdyBwcm9wZXJ0aWVzIGFyZSBuZXcgaW4gcmVjZW50IHNwZWNzOgoKICAgICAgICB7Ik1FQVNVUkVNRU5UX0dFT01FVFJZIiwgV1JJVEVfU1RSSU5HSUZZfSwgLy8gVGhlIHR5cGUgb2YgbWVhc3VyZW1lbnQsIGVpdGhlciByZWZsZWN0aW9uIG9yIHRyYW5zbWlzc2lvbiwgc2hvdWxkIGJlIGluZGljYXRlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWxvbmcgd2l0aCBkZXRhaWxzIG9mIHRoZSBnZW9tZXRyeSBhbmQgdGhlIGFwZXJ0dXJlIHNpemUgYW5kIHNoYXBlLiBGb3IgZXhhbXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciB0cmFuc21pc3Npb24gbWVhc3VyZW1lbnRzIGl0IGlzIGltcG9ydGFudCB0byBpZGVudGlmeSAwL2RpZmZ1c2UsIGRpZmZ1c2UvMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9wYWwgb3IgaW50ZWdyYXRpbmcgc3BoZXJlLCBldGMuIEZvciByZWZsZWN0aW9uIGl0IGlzIGltcG9ydGFudCB0byBpZGVudGlmeSAwLzQ1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gNDUvMCwgc3BoZXJlIChzcGVjdWxhciBpbmNsdWRlZCBvciBleGNsdWRlZCksIGV0Yy4KCiAgICAgICB7IkZJTFRFUiIsICAgICAgICAgICAgV1JJVEVfU1RSSU5HSUZZfSwgICAvLyBJZGVudGlmaWVzIHRoZSB1c2Ugb2YgcGh5c2ljYWwgZmlsdGVyKHMpIGR1cmluZyBtZWFzdXJlbWVudC4gVHlwaWNhbGx5IHVzZWQgdG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlbm90ZSB0aGUgdXNlIG9mIGZpbHRlcnMgc3VjaCBhcyBub25lLCBENjUsIFJlZCwgR3JlZW4gb3IgQmx1ZS4KCiAgICAgICB7IlBPTEFSSVpBVElPTiIsICAgICAgV1JJVEVfU1RSSU5HSUZZfSwgICAvLyBJZGVudGlmaWVzIHRoZSB1c2Ugb2YgYSBwaHlzaWNhbCBwb2xhcml6YXRpb24gZmlsdGVyIGR1cmluZyBtZWFzdXJlbWVudC4gQWxsb3dlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFsdWVzIGFyZSB7Inllc5QsIJN3aGl0ZZQsIJNub25llCBvciCTbmGULgoKICAgICAgIHsiV0VJR0hUSU5HX0ZVTkNUSU9OIiwgV1JJVEVfUEFJUn0sICAgLy8gSW5kaWNhdGVzIHN1Y2ggZnVuY3Rpb25zIGFzOiB0aGUgQ0lFIHN0YW5kYXJkIG9ic2VydmVyIGZ1bmN0aW9ucyB1c2VkIGluIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRpb24gb2YgdmFyaW91cyBkYXRhIHBhcmFtZXRlcnMgKDIgZGVncmVlIGFuZCAxMCBkZWdyZWUpLCBDSUUgc3RhbmRhcmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlsbHVtaW5hbnQgZnVuY3Rpb25zIHVzZWQgaW4gdGhlIGNhbGN1bGF0aW9uIG9mIHZhcmlvdXMgZGF0YSBwYXJhbWV0ZXJzIChlLmcuLCBENTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBENjUsIGV0Yy4pLCBkZW5zaXR5IHN0YXR1cyByZXNwb25zZSwgZXRjLiBJZiB1c2VkIHRoZXJlIHNoYWxsIGJlIGF0IGxlYXN0IG9uZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmFtZS12YWx1ZSBwYWlyIGZvbGxvd2luZyB0aGUgV0VJR0hUSU5HX0ZVTkNUSU9OIHRhZy9rZXl3b3JkLiBUaGUgZmlyc3QgYXR0cmlidXRlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbiB0aGUgc2V0IHNoYWxsIGJlIHsibmFtZSIgYW5kIHNoYWxsIGlkZW50aWZ5IHRoZSBwYXJ0aWN1bGFyIHBhcmFtZXRlciB1c2VkLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHNlY29uZCBzaGFsbCBiZSB7InZhbHVlIiBhbmQgc2hhbGwgcHJvdmlkZSB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoYXQgbmFtZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvciBBU0NJSSBkYXRhLCBhIHN0cmluZyBjb250YWluaW5nIHRoZSBOYW1lIGFuZCBWYWx1ZSBhdHRyaWJ1dGUgcGFpcnMgc2hhbGwgZm9sbG93CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgd2VpZ2h0aW5nIGZ1bmN0aW9uIGtleXdvcmQuIEEgc2VtaS1jb2xvbiBzZXBhcmF0ZXMgYXR0cmlidXRlIHBhaXJzIGZyb20gZWFjaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3RoZXIgYW5kIHdpdGhpbiB0aGUgYXR0cmlidXRlIHRoZSBuYW1lIGFuZCB2YWx1ZSBhcmUgc2VwYXJhdGVkIGJ5IGEgY29tbWEuCgogICAgICAgeyJDT01QVVRBVElPTkFMX1BBUkFNRVRFUiIsIFdSSVRFX1BBSVJ9LCAvLyBQYXJhbWV0ZXIgdGhhdCBpcyB1c2VkIGluIGNvbXB1dGluZyBhIHZhbHVlIGZyb20gbWVhc3VyZWQgZGF0YS4gTmFtZSBpcyB0aGUgbmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2YgdGhlIGNhbGN1bGF0aW9uLCBwYXJhbWV0ZXIgaXMgdGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciB1c2VkIGluIHRoZSBjYWxjdWxhdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHZhbHVlIGlzIHRoZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLgoKICAgICAgIHsiVEFSR0VUX1RZUEUiLCAgICAgICAgV1JJVEVfU1RSSU5HSUZZfSwgIC8vIFRoZSB0eXBlIG9mIHRhcmdldCBiZWluZyBtZWFzdXJlZCwgZS5nLiBJVDguNy8xLCBJVDguNy8zLCB1c2VyIGRlZmluZWQsIGV0Yy4KCiAgICAgICB7IkNPTE9SQU5UIiwgICAgICAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAvLyBJZGVudGlmaWVzIHRoZSBjb2xvcmFudChzKSB1c2VkIGluIGNyZWF0aW5nIHRoZSB0YXJnZXQuCgogICAgICAgeyJUQUJMRV9ERVNDUklQVE9SIiwgICBXUklURV9TVFJJTkdJRll9LCAgLy8gRGVzY3JpYmVzIHRoZSBwdXJwb3NlIG9yIGNvbnRlbnRzIG9mIGEgZGF0YSB0YWJsZS4KCiAgICAgICB7IlRBQkxFX05BTUUiLCAgICAgICAgIFdSSVRFX1NUUklOR0lGWX0gICAvLyBQcm92aWRlcyBhIHNob3J0IG5hbWUgZm9yIGEgZGF0YSB0YWJsZS4KfTsKCiNkZWZpbmUgTlVNUFJFREVGSU5FRFBST1BTIChzaXplb2YoUHJlZGVmaW5lZFByb3BlcnRpZXMpL3NpemVvZihQUk9QRVJUWSkpCgoKLy8gUHJlZGVmaW5lZCBzYW1wbGUgdHlwZXMgb24gZGF0YXNldApzdGF0aWMgY29uc3QgY2hhciogUHJlZGVmaW5lZFNhbXBsZUlEW10gPSB7CiAgICAgICAgIlNBTVBMRV9JRCIsICAgICAgLy8gSWRlbnRpZmllcyBzYW1wbGUgdGhhdCBkYXRhIHJlcHJlc2VudHMKICAgICAgICAiU1RSSU5HIiwgICAgICAgICAvLyBJZGVudGlmaWVzIGxhYmVsLCBvciBvdGhlciBub24tbWFjaGluZSByZWFkYWJsZSB2YWx1ZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWYWx1ZSBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBhICIgc3ltYm9sCgogICAgICAgICJDTVlLX0MiLCAgICAgICAgIC8vIEN5YW4gY29tcG9uZW50IG9mIENNWUsgZGF0YSBleHByZXNzZWQgYXMgYSBwZXJjZW50YWdlCiAgICAgICAgIkNNWUtfTSIsICAgICAgICAgLy8gTWFnZW50YSBjb21wb25lbnQgb2YgQ01ZSyBkYXRhIGV4cHJlc3NlZCBhcyBhIHBlcmNlbnRhZ2UKICAgICAgICAiQ01ZS19ZIiwgICAgICAgICAvLyBZZWxsb3cgY29tcG9uZW50IG9mIENNWUsgZGF0YSBleHByZXNzZWQgYXMgYSBwZXJjZW50YWdlCiAgICAgICAgIkNNWUtfSyIsICAgICAgICAgLy8gQmxhY2sgY29tcG9uZW50IG9mIENNWUsgZGF0YSBleHByZXNzZWQgYXMgYSBwZXJjZW50YWdlCiAgICAgICAgIkRfUkVEIiwgICAgICAgICAgLy8gUmVkIGZpbHRlciBkZW5zaXR5CiAgICAgICAgIkRfR1JFRU4iLCAgICAgICAgLy8gR3JlZW4gZmlsdGVyIGRlbnNpdHkKICAgICAgICAiRF9CTFVFIiwgICAgICAgICAvLyBCbHVlIGZpbHRlciBkZW5zaXR5CiAgICAgICAgIkRfVklTIiwgICAgICAgICAgLy8gVmlzdWFsIGZpbHRlciBkZW5zaXR5CiAgICAgICAgIkRfTUFKT1JfRklMVEVSIiwgLy8gTWFqb3IgZmlsdGVyIGQgZW5zaXR5CiAgICAgICAgIlJHQl9SIiwgICAgICAgICAgLy8gUmVkIGNvbXBvbmVudCBvZiBSR0IgZGF0YQogICAgICAgICJSR0JfRyIsICAgICAgICAgIC8vIEdyZWVuIGNvbXBvbmVudCBvZiBSR0IgZGF0YQogICAgICAgICJSR0JfQiIsICAgICAgICAgIC8vIEJsdWUgY29tIHBvbmVudCBvZiBSR0IgZGF0YQogICAgICAgICJTUEVDVFJBTF9OTSIsICAgIC8vIFdhdmVsZW5ndGggb2YgbWVhc3VyZW1lbnQgZXhwcmVzc2VkIGluIG5hbm9tZXRlcnMKICAgICAgICAiU1BFQ1RSQUxfUENUIiwgICAvLyBQZXJjZW50YWdlIHJlZmxlY3RhbmNlL3RyYW5zbWl0dGFuY2UKICAgICAgICAiU1BFQ1RSQUxfREVDIiwgICAvLyBSZWZsZWN0YW5jZS90cmFuc21pdHRhbmNlCiAgICAgICAgIlhZWl9YIiwgICAgICAgICAgLy8gWCBjb21wb25lbnQgb2YgdHJpc3RpbXVsdXMgZGF0YQogICAgICAgICJYWVpfWSIsICAgICAgICAgIC8vIFkgY29tcG9uZW50IG9mIHRyaXN0aW11bHVzIGRhdGEKICAgICAgICAiWFlaX1oiLCAgICAgICAgICAvLyBaIGNvbXBvbmVudCBvZiB0cmlzdGltdWx1cyBkYXRhCiAgICAgICAgIlhZWV9YIiwgICAgICAgICAgLy8geCBjb21wb25lbnQgb2YgY2hyb21hdGljaXR5IGRhdGEKICAgICAgICAiWFlZX1kiLCAgICAgICAgICAvLyB5IGNvbXBvbmVudCBvZiBjaHJvbWF0aWNpdHkgZGF0YQogICAgICAgICJYWVlfQ0FQWSIsICAgICAgIC8vIFkgY29tcG9uZW50IG9mIHRyaXN0aW11bHVzIGRhdGEKICAgICAgICAiTEFCX0wiLCAgICAgICAgICAvLyBMKiBjb21wb25lbnQgb2YgTGFiIGRhdGEKICAgICAgICAiTEFCX0EiLCAgICAgICAgICAvLyBhKiBjb21wb25lbnQgb2YgTGFiIGRhdGEKICAgICAgICAiTEFCX0IiLCAgICAgICAgICAvLyBiKiBjb21wb25lbnQgb2YgTGFiIGRhdGEKICAgICAgICAiTEFCX0MiLCAgICAgICAgICAvLyBDKmFiIGNvbXBvbmVudCBvZiBMYWIgZGF0YQogICAgICAgICJMQUJfSCIsICAgICAgICAgIC8vIGhhYiBjb21wb25lbnQgb2YgTGFiIGRhdGEKICAgICAgICAiTEFCX0RFIiwgICAgICAgICAvLyBDSUUgZEUKICAgICAgICAiTEFCX0RFXzk0IiwgICAgICAvLyBDSUUgZEUgdXNpbmcgQ0lFIDk0CiAgICAgICAgIkxBQl9ERV9DTUMiLCAgICAgLy8gZEUgdXNpbmcgQ01DCiAgICAgICAgIkxBQl9ERV8yMDAwIiwgICAgLy8gQ0lFIGRFIHVzaW5nIENJRSBERSAyMDAwCiAgICAgICAgIk1FQU5fREUiLCAgICAgICAgLy8gTWVhbiBEZWx0YSBFIChMQUJfREUpIG9mIHNhbXBsZXMgY29tcGFyZWQgdG8gYmF0Y2ggYXZlcmFnZQogICAgICAgICAgICAgICAgICAgICAgICAgIC8vIChVc2VkIGZvciBkYXRhIGZpbGVzIGZvciBBTlNJIElUOC43LzEgYW5kIElUOC43LzIgdGFyZ2V0cykKICAgICAgICAiU1RERVZfWCIsICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgWCAodHJpc3RpbXVsdXMgZGF0YSkKICAgICAgICAiU1RERVZfWSIsICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgWSAodHJpc3RpbXVsdXMgZGF0YSkKICAgICAgICAiU1RERVZfWiIsICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgWiAodHJpc3RpbXVsdXMgZGF0YSkKICAgICAgICAiU1RERVZfTCIsICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgTCoKICAgICAgICAiU1RERVZfQSIsICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgYSoKICAgICAgICAiU1RERVZfQiIsICAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgYioKICAgICAgICAiU1RERVZfREUiLCAgICAgICAvLyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgQ0lFIGRFCiAgICAgICAgIkNISV9TUURfUEFSIn07ICAgLy8gVGhlIGF2ZXJhZ2Ugb2YgdGhlIHN0YW5kYXJkIGRldmlhdGlvbnMgb2YgTCosIGEqIGFuZCBiKi4gSXQgaXMKICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2VkIHRvIGRlcml2ZSBhbiBlc3RpbWF0ZSBvZiB0aGUgY2hpLXNxdWFyZWQgcGFyYW1ldGVyIHdoaWNoIGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVjb21tZW5kZWQgYXMgdGhlIHByZWRpY3RvciBvZiB0aGUgdmFyaWFiaWxpdHkgb2YgZEUKCiNkZWZpbmUgTlVNUFJFREVGSU5FRFNBTVBMRUlEIChzaXplb2YoUHJlZGVmaW5lZFNhbXBsZUlEKS9zaXplb2YoY2hhciAqKSkKCi8vRm9yd2FyZCBkZWNsYXJhdGlvbiBvZiBzb21lIGludGVybmFsIGZ1bmN0aW9ucwpzdGF0aWMgdm9pZCogQWxsb2NDaHVuayhjbXNJVDgqIGl0OCwgY21zVUludDMyTnVtYmVyIHNpemUpOwoKLy8gQ2hlY2tzIHdoYXRldmVyIGMgaXMgYSBzZXBhcmF0b3IKc3RhdGljCmNtc0Jvb2wgaXNzZXBhcmF0b3IoaW50IGMpCnsKICAgIHJldHVybiAoYyA9PSAnICcpIHx8IChjID09ICdcdCcpIDsKfQoKLy8gQ2hlY2tzIHdoYXRldmVyIGMgaXMgYSB2YWxpZCBpZGVudGlmaWVyIGNoYXIKc3RhdGljCmNtc0Jvb2wgaXNtaWRkbGUoaW50IGMpCnsKICAgcmV0dXJuICghaXNzZXBhcmF0b3IoYykgJiYgKGMgIT0gJyMnKSAmJiAoYyAhPSdcIicpICYmIChjICE9ICdcJycpICYmIChjID4gMzIpICYmIChjIDwgMTI3KSk7Cn0KCi8vIENoZWNrcyB3aGF0c2V2ZXIgYyBpcyBhIHZhbGlkIGlkZW50aWZpZXIgbWlkZGxlIGNoYXIuCnN0YXRpYwpjbXNCb29sIGlzaWRjaGFyKGludCBjKQp7CiAgIHJldHVybiBpc2FsbnVtKGMpIHx8IGlzbWlkZGxlKGMpOwp9CgovLyBDaGVja3Mgd2hhdHNldmVyIGMgaXMgYSB2YWxpZCBpZGVudGlmaWVyIGZpcnN0IGNoYXIuCnN0YXRpYwpjbXNCb29sIGlzZmlyc3RpZGNoYXIoaW50IGMpCnsKICAgICByZXR1cm4gIWlzZGlnaXQoYykgJiYgaXNtaWRkbGUoYyk7Cn0KCi8vIEd1ZXNzIHdoZXRoZXIgdGhlIHN1cHBsaWVkIHBhdGggbG9va3MgbGlrZSBhbiBhYnNvbHV0ZSBwYXRoCnN0YXRpYwpjbXNCb29sIGlzYWJzb2x1dGVwYXRoKGNvbnN0IGNoYXIgKnBhdGgpCnsKICAgIGNoYXIgVGhyZWVDaGFyc1s0XTsKCiAgICBpZihwYXRoID09IE5VTEwpCiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgaWYgKHBhdGhbMF0gPT0gMCkKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgc3RybmNweShUaHJlZUNoYXJzLCBwYXRoLCAzKTsKICAgIFRocmVlQ2hhcnNbM10gPSAwOwoKICAgIGlmKFRocmVlQ2hhcnNbMF0gPT0gRElSX0NIQVIpCiAgICAgICAgcmV0dXJuIFRSVUU7CgojaWZkZWYgIENNU19JU19XSU5ET1dTXwogICAgaWYgKGlzYWxwaGEoKGludCkgVGhyZWVDaGFyc1swXSkgJiYgVGhyZWVDaGFyc1sxXSA9PSAnOicpCiAgICAgICAgcmV0dXJuIFRSVUU7CiNlbmRpZgogICAgcmV0dXJuIEZBTFNFOwp9CgoKLy8gTWFrZXMgYSBmaWxlIHBhdGggYmFzZWQgb24gYSBnaXZlbiByZWZlcmVuY2UgcGF0aAovLyBOT1RFOiB0aGlzIGZ1bmN0aW9uIGRvZXNuJ3QgY2hlY2sgaWYgdGhlIHBhdGggZXhpc3RzIG9yIGV2ZW4gaWYgaXQncyBsZWdhbApzdGF0aWMKY21zQm9vbCBCdWlsZEFic29sdXRlUGF0aChjb25zdCBjaGFyICpyZWxQYXRoLCBjb25zdCBjaGFyICpiYXNlUGF0aCwgY2hhciAqYnVmZmVyLCBjbXNVSW50MzJOdW1iZXIgTWF4TGVuKQp7CiAgICBjaGFyICp0YWlsOwogICAgY21zVUludDMyTnVtYmVyIGxlbjsKCiAgICAvLyBBbHJlYWR5IGFic29sdXRlPwogICAgaWYgKGlzYWJzb2x1dGVwYXRoKHJlbFBhdGgpKSB7CgogICAgICAgIHN0cm5jcHkoYnVmZmVyLCByZWxQYXRoLCBNYXhMZW4pOwogICAgICAgIGJ1ZmZlcltNYXhMZW4tMV0gPSAwOwogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIC8vIE5vLCBzZWFyY2ggZm9yIGxhc3QKICAgIHN0cm5jcHkoYnVmZmVyLCBiYXNlUGF0aCwgTWF4TGVuKTsKICAgIGJ1ZmZlcltNYXhMZW4tMV0gPSAwOwoKICAgIHRhaWwgPSBzdHJyY2hyKGJ1ZmZlciwgRElSX0NIQVIpOwogICAgaWYgKHRhaWwgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOyAgICAvLyBJcyBub3QgYWJzb2x1dGUgYW5kIGhhcyBubyBzZXBhcmF0b3JzPz8KCiAgICBsZW4gPSAoY21zVUludDMyTnVtYmVyKSAodGFpbCAtIGJ1ZmZlcik7CiAgICBpZiAobGVuID49IE1heExlbikgcmV0dXJuIEZBTFNFOwoKICAgIC8vIE5vIG5lZWQgdG8gYXNzdXJlIHplcm8gdGVybWluYXRvciBvdmVyIGhlcmUKICAgIHN0cm5jcHkodGFpbCArIDEsIHJlbFBhdGgsIE1heExlbiAtIGxlbik7CgogICAgcmV0dXJuIFRSVUU7Cn0KCgovLyBNYWtlIHN1cmUgbm8gZXhwbG9pdCBpcyBiZWluZyBldmVuIHRyaWVkCnN0YXRpYwpjb25zdCBjaGFyKiBOb01ldGEoY29uc3QgY2hhciogc3RyKQp7CiAgICBpZiAoc3RyY2hyKHN0ciwgJyUnKSAhPSBOVUxMKQogICAgICAgIHJldHVybiAiKioqKiBDT1JSVVBURUQgRk9STUFUIFNUUklORyAqKioiOwoKICAgIHJldHVybiBzdHI7Cn0KCi8vIFN5bnRheCBlcnJvcgpzdGF0aWMKY21zQm9vbCBTeW5FcnJvcihjbXNJVDgqIGl0OCwgY29uc3QgY2hhciAqVHh0LCAuLi4pCnsKICAgIGNoYXIgQnVmZmVyWzI1Nl0sIEVyck1zZ1sxMDI0XTsKICAgIHZhX2xpc3QgYXJnczsKCiAgICB2YV9zdGFydChhcmdzLCBUeHQpOwogICAgdnNucHJpbnRmKEJ1ZmZlciwgMjU1LCBUeHQsIGFyZ3MpOwogICAgQnVmZmVyWzI1NV0gPSAwOwogICAgdmFfZW5kKGFyZ3MpOwoKICAgIHNucHJpbnRmKEVyck1zZywgMTAyMywgIiVzOiBMaW5lICVkLCAlcyIsIGl0OC0+RmlsZVN0YWNrW2l0OCAtPkluY2x1ZGVTUF0tPkZpbGVOYW1lLCBpdDgtPmxpbmVubywgQnVmZmVyKTsKICAgIEVyck1zZ1sxMDIzXSA9IDA7CiAgICBpdDgtPnN5ID0gU1NZTkVSUk9SOwogICAgY21zU2lnbmFsRXJyb3IoaXQ4IC0+Q29udGV4dElELCBjbXNFUlJPUl9DT1JSVVBUSU9OX0RFVEVDVEVELCAiJXMiLCBFcnJNc2cpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovLyBDaGVjayBpZiBjdXJyZW50IHN5bWJvbCBpcyBzYW1lIGFzIHNwZWNpZmllZC4gaXNzdWUgYW4gZXJyb3IgZWxzZS4Kc3RhdGljCmNtc0Jvb2wgQ2hlY2soY21zSVQ4KiBpdDgsIFNZTUJPTCBzeSwgY29uc3QgY2hhciogRXJyKQp7CiAgICAgICAgaWYgKGl0OCAtPiBzeSAhPSBzeSkKICAgICAgICAgICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsIE5vTWV0YShFcnIpKTsKICAgICAgICByZXR1cm4gVFJVRTsKfQoKLy8gUmVhZCBOZXh0IGNoYXJhY3RlciBmcm9tIHN0cmVhbQpzdGF0aWMKdm9pZCBOZXh0Q2goY21zSVQ4KiBpdDgpCnsKICAgIGlmIChpdDggLT4gRmlsZVN0YWNrW2l0OCAtPkluY2x1ZGVTUF0tPlN0cmVhbSkgewoKICAgICAgICBpdDggLT5jaCA9IGZnZXRjKGl0OCAtPkZpbGVTdGFja1tpdDggLT5JbmNsdWRlU1BdLT5TdHJlYW0pOwoKICAgICAgICBpZiAoZmVvZihpdDggLT4gRmlsZVN0YWNrW2l0OCAtPkluY2x1ZGVTUF0tPlN0cmVhbSkpICB7CgogICAgICAgICAgICBpZiAoaXQ4IC0+SW5jbHVkZVNQID4gMCkgewoKICAgICAgICAgICAgICAgIGZjbG9zZShpdDggLT5GaWxlU3RhY2tbaXQ4LT5JbmNsdWRlU1AtLV0tPlN0cmVhbSk7CiAgICAgICAgICAgICAgICBpdDggLT4gY2ggPSAnICc7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdoaXRlc3BhY2UgdG8gYmUgaWdub3JlZAoKICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICBpdDggLT5jaCA9IDA7ICAgLy8gRU9GCiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgaXQ4LT5jaCA9ICppdDgtPlNvdXJjZTsKICAgICAgICBpZiAoaXQ4LT5jaCkgaXQ4LT5Tb3VyY2UrKzsKICAgIH0KfQoKCi8vIFRyeSB0byBzZWUgaWYgY3VycmVudCBpZGVudGlmaWVyIGlzIGEga2V5d29yZCwgaWYgc28gcmV0dXJuIHRoZSByZWZlcnJlZCBzeW1ib2wKc3RhdGljClNZTUJPTCBCaW5TcmNoS2V5KGNvbnN0IGNoYXIgKmlkKQp7CiAgICBpbnQgbCA9IDE7CiAgICBpbnQgciA9IE5VTUtFWVM7CiAgICBpbnQgeCwgcmVzOwoKICAgIHdoaWxlIChyID49IGwpCiAgICB7CiAgICAgICAgeCA9IChsK3IpLzI7CiAgICAgICAgcmVzID0gY21zc3RyY2FzZWNtcChpZCwgVGFiS2V5c1t4LTFdLmlkKTsKICAgICAgICBpZiAocmVzID09IDApIHJldHVybiBUYWJLZXlzW3gtMV0uc3k7CiAgICAgICAgaWYgKHJlcyA8IDApIHIgPSB4IC0gMTsKICAgICAgICBlbHNlIGwgPSB4ICsgMTsKICAgIH0KCiAgICByZXR1cm4gU1VOREVGSU5FRDsKfQoKCi8vIDEwIF5uCnN0YXRpYwpjbXNGbG9hdDY0TnVtYmVyIHhwb3cxMChpbnQgbikKewogICAgcmV0dXJuIHBvdygxMCwgKGNtc0Zsb2F0NjROdW1iZXIpIG4pOwp9CgoKLy8gIFJlYWRzIGEgUmVhbCBudW1iZXIsIHRyaWVzIHRvIGZvbGxvdyBmcm9tIGludGVnZXIgbnVtYmVyCnN0YXRpYwp2b2lkIFJlYWRSZWFsKGNtc0lUOCogaXQ4LCBpbnQgaW51bSkKewogICAgaXQ4LT5kbnVtID0gKGNtc0Zsb2F0NjROdW1iZXIpIGludW07CgogICAgd2hpbGUgKGlzZGlnaXQoaXQ4LT5jaCkpIHsKCiAgICAgICAgaXQ4LT5kbnVtID0gaXQ4LT5kbnVtICogMTAuMCArIChpdDgtPmNoIC0gJzAnKTsKICAgICAgICBOZXh0Q2goaXQ4KTsKICAgIH0KCiAgICBpZiAoaXQ4LT5jaCA9PSAnLicpIHsgICAgICAgIC8vIERlY2ltYWwgcG9pbnQKCiAgICAgICAgY21zRmxvYXQ2NE51bWJlciBmcmFjID0gMC4wOyAgICAgIC8vIGZyYWN0aW9uCiAgICAgICAgaW50IHByZWMgPSAwOyAgICAgICAgICAgICAgICAgICAgIC8vIHByZWNpc2lvbgoKICAgICAgICBOZXh0Q2goaXQ4KTsgICAgICAgICAgICAgICAvLyBFYXRzIGRlYy4gcG9pbnQKCiAgICAgICAgd2hpbGUgKGlzZGlnaXQoaXQ4LT5jaCkpIHsKCiAgICAgICAgICAgIGZyYWMgPSBmcmFjICogMTAuMCArIChpdDgtPmNoIC0gJzAnKTsKICAgICAgICAgICAgcHJlYysrOwogICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICB9CgogICAgICAgIGl0OC0+ZG51bSA9IGl0OC0+ZG51bSArIChmcmFjIC8geHBvdzEwKHByZWMpKTsKICAgIH0KCiAgICAvLyBFeHBvbmVudCwgZXhhbXBsZSAzNC4wMEUrMjAKICAgIGlmICh0b3VwcGVyKGl0OC0+Y2gpID09ICdFJykgewoKICAgICAgICBpbnQgZTsKICAgICAgICBpbnQgc2duOwoKICAgICAgICBOZXh0Q2goaXQ4KTsgc2duID0gMTsKCiAgICAgICAgaWYgKGl0OC0+Y2ggPT0gJy0nKSB7CgogICAgICAgICAgICBzZ24gPSAtMTsgTmV4dENoKGl0OCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgaWYgKGl0OC0+Y2ggPT0gJysnKSB7CgogICAgICAgICAgICAgICAgc2duID0gKzE7CiAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZSA9IDA7CiAgICAgICAgICAgIHdoaWxlIChpc2RpZ2l0KGl0OC0+Y2gpKSB7CgogICAgICAgICAgICAgICAgaWYgKChjbXNGbG9hdDY0TnVtYmVyKSBlICogMTBMIDwgSU5UX01BWCkKICAgICAgICAgICAgICAgICAgICBlID0gZSAqIDEwICsgKGl0OC0+Y2ggLSAnMCcpOwoKICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBlID0gc2duKmU7CiAgICAgICAgICAgIGl0OCAtPiBkbnVtID0gaXQ4IC0+IGRudW0gKiB4cG93MTAoZSk7CiAgICB9Cn0KCi8vIFBhcnNlcyBhIGZsb2F0IG51bWJlcgovLyBUaGlzIGNhbiBub3QgY2FsbCBkaXJlY3RseSBhdG9mIGJlY2F1c2UgaXQgdXNlcyBsb2NhbGUgZGVwZW5kYW50Ci8vIHBhcnNpbmcsIHdoaWxlIENDTVggZmlsZXMgYWx3YXlzIHVzZSAuIGFzIGRlY2ltYWwgc2VwYXJhdG9yCnN0YXRpYwpjbXNGbG9hdDY0TnVtYmVyIFBhcnNlRmxvYXROdW1iZXIoY29uc3QgY2hhciAqQnVmZmVyKQp7CiAgICBjbXNGbG9hdDY0TnVtYmVyIGRudW0gPSAwLjA7CiAgICBpbnQgc2lnbiA9IDE7CgogICAgLy8ga2VlcCBzYWZlCiAgICBpZiAoQnVmZmVyID09IE5VTEwpIHJldHVybiAwLjA7CgogICAgaWYgKCpCdWZmZXIgPT0gJy0nIHx8ICpCdWZmZXIgPT0gJysnKSB7CgogICAgICAgICBzaWduID0gKCpCdWZmZXIgPT0gJy0nKSA/IC0xIDogMTsKICAgICAgICAgQnVmZmVyKys7CiAgICB9CgoKICAgIHdoaWxlICgqQnVmZmVyICYmIGlzZGlnaXQoKGludCkgKkJ1ZmZlcikpIHsKCiAgICAgICAgZG51bSA9IGRudW0gKiAxMC4wICsgKCpCdWZmZXIgLSAnMCcpOwogICAgICAgIGlmICgqQnVmZmVyKSBCdWZmZXIrKzsKICAgIH0KCiAgICBpZiAoKkJ1ZmZlciA9PSAnLicpIHsKCiAgICAgICAgY21zRmxvYXQ2NE51bWJlciBmcmFjID0gMC4wOyAgICAgIC8vIGZyYWN0aW9uCiAgICAgICAgaW50IHByZWMgPSAwOyAgICAgICAgICAgICAgICAgICAgIC8vIHByZWNpc3Npb24KCiAgICAgICAgaWYgKCpCdWZmZXIpIEJ1ZmZlcisrOwoKICAgICAgICB3aGlsZSAoKkJ1ZmZlciAmJiBpc2RpZ2l0KChpbnQpICpCdWZmZXIpKSB7CgogICAgICAgICAgICBmcmFjID0gZnJhYyAqIDEwLjAgKyAoKkJ1ZmZlciAtICcwJyk7CiAgICAgICAgICAgIHByZWMrKzsKICAgICAgICAgICAgaWYgKCpCdWZmZXIpIEJ1ZmZlcisrOwogICAgICAgIH0KCiAgICAgICAgZG51bSA9IGRudW0gKyAoZnJhYyAvIHhwb3cxMChwcmVjKSk7CiAgICB9CgogICAgLy8gRXhwb25lbnQsIGV4YW1wbGUgMzQuMDBFKzIwCiAgICBpZiAoKkJ1ZmZlciAmJiB0b3VwcGVyKCpCdWZmZXIpID09ICdFJykgewoKICAgICAgICBpbnQgZTsKICAgICAgICBpbnQgc2duOwoKICAgICAgICBpZiAoKkJ1ZmZlcikgQnVmZmVyKys7CiAgICAgICAgc2duID0gMTsKCiAgICAgICAgaWYgKCpCdWZmZXIgPT0gJy0nKSB7CgogICAgICAgICAgICBzZ24gPSAtMTsKICAgICAgICAgICAgaWYgKCpCdWZmZXIpIEJ1ZmZlcisrOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIGlmICgqQnVmZmVyID09ICcrJykgewoKICAgICAgICAgICAgICAgIHNnbiA9ICsxOwogICAgICAgICAgICAgICAgaWYgKCpCdWZmZXIpIEJ1ZmZlcisrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBlID0gMDsKICAgICAgICAgICAgd2hpbGUgKCpCdWZmZXIgJiYgaXNkaWdpdCgoaW50KSAqQnVmZmVyKSkgewoKICAgICAgICAgICAgICAgIGlmICgoY21zRmxvYXQ2NE51bWJlcikgZSAqIDEwTCA8IElOVF9NQVgpCiAgICAgICAgICAgICAgICAgICAgZSA9IGUgKiAxMCArICgqQnVmZmVyIC0gJzAnKTsKCiAgICAgICAgICAgICAgICBpZiAoKkJ1ZmZlcikgQnVmZmVyKys7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGUgPSBzZ24qZTsKICAgICAgICAgICAgZG51bSA9IGRudW0gKiB4cG93MTAoZSk7CiAgICB9CgogICAgcmV0dXJuIHNpZ24gKiBkbnVtOwp9CgoKLy8gUmVhZHMgbmV4dCBzeW1ib2wKc3RhdGljCnZvaWQgSW5TeW1ib2woY21zSVQ4KiBpdDgpCnsKICAgIHJlZ2lzdGVyIGNoYXIgKmlkcHRyOwogICAgcmVnaXN0ZXIgaW50IGs7CiAgICBTWU1CT0wga2V5OwogICAgaW50IHNuZzsKCiAgICBkbyB7CgogICAgICAgIHdoaWxlIChpc3NlcGFyYXRvcihpdDgtPmNoKSkKICAgICAgICAgICAgTmV4dENoKGl0OCk7CgogICAgICAgIGlmIChpc2ZpcnN0aWRjaGFyKGl0OC0+Y2gpKSB7ICAgICAgICAgIC8vIElkZW50aWZpZXIKCiAgICAgICAgICAgIGsgPSAwOwogICAgICAgICAgICBpZHB0ciA9IGl0OC0+aWQ7CgogICAgICAgICAgICBkbyB7CgogICAgICAgICAgICAgICAgaWYgKCsrayA8IE1BWElEKSAqaWRwdHIrKyA9IChjaGFyKSBpdDgtPmNoOwoKICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwoKICAgICAgICAgICAgfSB3aGlsZSAoaXNpZGNoYXIoaXQ4LT5jaCkpOwoKICAgICAgICAgICAgKmlkcHRyID0gJ1wwJzsKCgogICAgICAgICAgICBrZXkgPSBCaW5TcmNoS2V5KGl0OC0+aWQpOwogICAgICAgICAgICBpZiAoa2V5ID09IFNVTkRFRklORUQpIGl0OC0+c3kgPSBTSURFTlQ7CiAgICAgICAgICAgIGVsc2UgaXQ4LT5zeSA9IGtleTsKCiAgICAgICAgfQogICAgICAgIGVsc2UgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXMgYSBudW1iZXI/CiAgICAgICAgICAgIGlmIChpc2RpZ2l0KGl0OC0+Y2gpIHx8IGl0OC0+Y2ggPT0gJy4nIHx8IGl0OC0+Y2ggPT0gJy0nIHx8IGl0OC0+Y2ggPT0gJysnKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgc2lnbiA9IDE7CgogICAgICAgICAgICAgICAgaWYgKGl0OC0+Y2ggPT0gJy0nKSB7CiAgICAgICAgICAgICAgICAgICAgc2lnbiA9IC0xOwogICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGl0OC0+aW51bSA9IDA7CiAgICAgICAgICAgICAgICBpdDgtPnN5ICAgPSBTSU5VTTsKCiAgICAgICAgICAgICAgICBpZiAoaXQ4LT5jaCA9PSAnMCcpIHsgICAgICAgICAgLy8gMHhubm5uIChIZXhhKSBvciAwYm5ubm4gKEJpbmFyeSkKCiAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRvdXBwZXIoaXQ4LT5jaCkgPT0gJ1gnKSB7CgogICAgICAgICAgICAgICAgICAgICAgICBpbnQgajsKCiAgICAgICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaXN4ZGlnaXQoaXQ4LT5jaCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0OC0+Y2ggPSB0b3VwcGVyKGl0OC0+Y2gpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0OC0+Y2ggPj0gJ0EnICYmIGl0OC0+Y2ggPD0gJ0YnKSAgaiA9IGl0OC0+Y2ggLSdBJysxMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaiA9IGl0OC0+Y2ggLSAnMCc7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChsb25nKSBpdDgtPmludW0gKiAxNkwgPiAobG9uZykgSU5UX01BWCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeW5FcnJvcihpdDgsICJJbnZhbGlkIGhleGFkZWNpbWFsIG51bWJlciIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdDgtPmludW0gPSBpdDgtPmludW0gKiAxNiArIGo7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAodG91cHBlcihpdDgtPmNoKSA9PSAnQicpIHsgIC8vIEJpbmFyeQoKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGo7CgogICAgICAgICAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGl0OC0+Y2ggPT0gJzAnIHx8IGl0OC0+Y2ggPT0gJzEnKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqID0gaXQ4LT5jaCAtICcwJzsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGxvbmcpIGl0OC0+aW51bSAqIDJMID4gKGxvbmcpIElOVF9NQVgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3luRXJyb3IoaXQ4LCAiSW52YWxpZCBiaW5hcnkgbnVtYmVyIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0OC0+aW51bSA9IGl0OC0+aW51bSAqIDIgKyBqOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICAgICAgd2hpbGUgKGlzZGlnaXQoaXQ4LT5jaCkpIHsKCiAgICAgICAgICAgICAgICAgICAgaWYgKChsb25nKSBpdDgtPmludW0gKiAxMEwgPiAobG9uZykgSU5UX01BWCkgewogICAgICAgICAgICAgICAgICAgICAgICBSZWFkUmVhbChpdDgsIGl0OC0+aW51bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGl0OC0+c3kgPSBTRE5VTTsKICAgICAgICAgICAgICAgICAgICAgICAgaXQ4LT5kbnVtICo9IHNpZ247CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGl0OC0+aW51bSA9IGl0OC0+aW51bSAqIDEwICsgKGl0OC0+Y2ggLSAnMCcpOwogICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChpdDgtPmNoID09ICcuJykgewoKICAgICAgICAgICAgICAgICAgICBSZWFkUmVhbChpdDgsIGl0OC0+aW51bSk7CiAgICAgICAgICAgICAgICAgICAgaXQ4LT5zeSA9IFNETlVNOwogICAgICAgICAgICAgICAgICAgIGl0OC0+ZG51bSAqPSBzaWduOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpdDggLT4gaW51bSAqPSBzaWduOwoKICAgICAgICAgICAgICAgIC8vIFNwZWNpYWwgY2FzZS4gTnVtYmVycyBmb2xsb3dlZCBieSBsZXR0ZXJzIGFyZSB0YWtlbiBhcyBpZGVudGlmaWVycwoKICAgICAgICAgICAgICAgIGlmIChpc2lkY2hhcihpdDggLT5jaCkpIHsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGl0OCAtPnN5ID09IFNJTlVNKSB7CgogICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKGl0OC0+aWQsICIlZCIsIGl0OC0+aW51bSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewoKICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZihpdDgtPmlkLCBpdDggLT5Eb3VibGVGb3JtYXR0ZXIsIGl0OC0+ZG51bSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBrID0gKGludCkgc3RybGVuKGl0OCAtPmlkKTsKICAgICAgICAgICAgICAgICAgICBpZHB0ciA9IGl0OCAtPmlkICsgazsKICAgICAgICAgICAgICAgICAgICBkbyB7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoKytrIDwgTUFYSUQpICppZHB0cisrID0gKGNoYXIpIGl0OC0+Y2g7CgogICAgICAgICAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKCiAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoaXNpZGNoYXIoaXQ4LT5jaCkpOwoKICAgICAgICAgICAgICAgICAgICAqaWRwdHIgPSAnXDAnOwogICAgICAgICAgICAgICAgICAgIGl0OC0+c3kgPSBTSURFTlQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm47CgogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHN3aXRjaCAoKGludCkgaXQ4LT5jaCkgewoKICAgICAgICAvLyBFT0YgbWFya2VyIC0tIGlnbm9yZSBpdAogICAgICAgIGNhc2UgJ1x4MWEnOgogICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIC8vIEVvZiBzdHJlYW0gbWFya2VycwogICAgICAgIGNhc2UgMDoKICAgICAgICBjYXNlIC0xOgogICAgICAgICAgICBpdDgtPnN5ID0gU0VPRjsKICAgICAgICAgICAgYnJlYWs7CgoKICAgICAgICAvLyBOZXh0IGxpbmUKICAgICAgICBjYXNlICdccic6CiAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICBpZiAoaXQ4IC0+Y2ggPT0gJ1xuJykKICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICBpdDgtPnN5ID0gU0VPTE47CiAgICAgICAgICAgIGl0OC0+bGluZW5vKys7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlICdcbic6CiAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICBpdDgtPnN5ID0gU0VPTE47CiAgICAgICAgICAgIGl0OC0+bGluZW5vKys7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAvLyBDb21tZW50CiAgICAgICAgY2FzZSAnIyc6CiAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICB3aGlsZSAoaXQ4LT5jaCAmJiBpdDgtPmNoICE9ICdcbicgJiYgaXQ4LT5jaCAhPSAnXHInKQogICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CgogICAgICAgICAgICBpdDgtPnN5ID0gU0NPTU1FTlQ7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAvLyBTdHJpbmcuCiAgICAgICAgY2FzZSAnXCcnOgogICAgICAgIGNhc2UgJ1wiJzoKICAgICAgICAgICAgaWRwdHIgPSBpdDgtPnN0cjsKICAgICAgICAgICAgc25nID0gaXQ4LT5jaDsKICAgICAgICAgICAgayA9IDA7CiAgICAgICAgICAgIE5leHRDaChpdDgpOwoKICAgICAgICAgICAgd2hpbGUgKGsgPCBNQVhTVFIgJiYgaXQ4LT5jaCAhPSBzbmcpIHsKCiAgICAgICAgICAgICAgICBpZiAoaXQ4LT5jaCA9PSAnXG4nfHwgaXQ4LT5jaCA9PSAnXHInKSBrID0gTUFYU1RSKzE7CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAqaWRwdHIrKyA9IChjaGFyKSBpdDgtPmNoOwogICAgICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgICAgIGsrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaXQ4LT5zeSA9IFNTVFJJTkc7CiAgICAgICAgICAgICppZHB0ciA9ICdcMCc7CiAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICBicmVhazsKCgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIlVucmVjb2duaXplZCBjaGFyYWN0ZXI6IDB4JXgiLCBpdDggLT5jaCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgIH0gd2hpbGUgKGl0OC0+c3kgPT0gU0NPTU1FTlQpOwoKICAgIC8vIEhhbmRsZSB0aGUgaW5jbHVkZSBzcGVjaWFsIHRva2VuCgogICAgaWYgKGl0OCAtPiBzeSA9PSBTSU5DTFVERSkgewoKICAgICAgICAgICAgICAgIEZJTEVDVFgqIEZpbGVOZXN0OwoKICAgICAgICAgICAgICAgIGlmKGl0OCAtPiBJbmNsdWRlU1AgPj0gKE1BWElOQ0xVREUtMSkpIHsKCiAgICAgICAgICAgICAgICAgICAgU3luRXJyb3IoaXQ4LCAiVG9vIG1hbnkgcmVjdXJzaW9uIGxldmVscyIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgaWYgKCFDaGVjayhpdDgsIFNTVFJJTkcsICJGaWxlbmFtZSBleHBlY3RlZCIpKSByZXR1cm47CgogICAgICAgICAgICAgICAgRmlsZU5lc3QgPSBpdDggLT4gRmlsZVN0YWNrW2l0OCAtPiBJbmNsdWRlU1AgKyAxXTsKICAgICAgICAgICAgICAgIGlmKEZpbGVOZXN0ID09IE5VTEwpIHsKCiAgICAgICAgICAgICAgICAgICAgRmlsZU5lc3QgPSBpdDggLT5GaWxlU3RhY2tbaXQ4IC0+IEluY2x1ZGVTUCArIDFdID0gKEZJTEVDVFgqKUFsbG9jQ2h1bmsoaXQ4LCBzaXplb2YoRklMRUNUWCkpOwogICAgICAgICAgICAgICAgICAgIC8vaWYoRmlsZU5lc3QgPT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAvLyAgVE9ETzogaG93IHRvIG1hbmFnZSBvdXQtb2YtbWVtb3J5IGNvbmRpdGlvbnM/CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKEJ1aWxkQWJzb2x1dGVQYXRoKGl0OC0+c3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0OC0+RmlsZVN0YWNrW2l0OC0+SW5jbHVkZVNQXS0+RmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZU5lc3QtPkZpbGVOYW1lLCBjbXNNQVhfUEFUSC0xKSA9PSBGQUxTRSkgewogICAgICAgICAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIkZpbGUgcGF0aCB0b28gbG9uZyIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBGaWxlTmVzdC0+U3RyZWFtID0gZm9wZW4oRmlsZU5lc3QtPkZpbGVOYW1lLCAicnQiKTsKICAgICAgICAgICAgICAgIGlmIChGaWxlTmVzdC0+U3RyZWFtID09IE5VTEwpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIkZpbGUgJXMgbm90IGZvdW5kIiwgRmlsZU5lc3QtPkZpbGVOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaXQ4LT5JbmNsdWRlU1ArKzsKCiAgICAgICAgICAgICAgICBpdDggLT5jaCA9ICcgJzsKICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICB9Cgp9CgovLyBDaGVja3MgZW5kIG9mIGxpbmUgc2VwYXJhdG9yCnN0YXRpYwpjbXNCb29sIENoZWNrRU9MTihjbXNJVDgqIGl0OCkKewogICAgICAgIGlmICghQ2hlY2soaXQ4LCBTRU9MTiwgIkV4cGVjdGVkIHNlcGFyYXRvciIpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgd2hpbGUgKGl0OCAtPiBzeSA9PSBTRU9MTikKICAgICAgICAgICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICByZXR1cm4gVFJVRTsKCn0KCi8vIFNraXAgYSBzeW1ib2wKCnN0YXRpYwp2b2lkIFNraXAoY21zSVQ4KiBpdDgsIFNZTUJPTCBzeSkKewogICAgICAgIGlmIChpdDgtPnN5ID09IHN5ICYmIGl0OC0+c3kgIT0gU0VPRikKICAgICAgICAgICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKfQoKCi8vIFNraXAgbXVsdGlwbGUgRU9MTgpzdGF0aWMKdm9pZCBTa2lwRU9MTihjbXNJVDgqIGl0OCkKewogICAgd2hpbGUgKGl0OC0+c3kgPT0gU0VPTE4pIHsKICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICB9Cn0KCgovLyBSZXR1cm5zIGEgc3RyaW5nIGhvbGRpbmcgY3VycmVudCB2YWx1ZQpzdGF0aWMKY21zQm9vbCBHZXRWYWwoY21zSVQ4KiBpdDgsIGNoYXIqIEJ1ZmZlciwgY21zVUludDMyTnVtYmVyIG1heCwgY29uc3QgY2hhciogRXJyb3JUaXRsZSkKewogICAgc3dpdGNoIChpdDgtPnN5KSB7CgogICAgY2FzZSBTRU9MTjogICAvLyBFbXB0eSB2YWx1ZQogICAgICAgICAgICAgICAgICBCdWZmZXJbMF09MDsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICBjYXNlIFNJREVOVDogIHN0cm5jcHkoQnVmZmVyLCBpdDgtPmlkLCBtYXgpOwogICAgICAgICAgICAgICAgICBCdWZmZXJbbWF4LTFdPTA7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgY2FzZSBTSU5VTTogICBzbnByaW50ZihCdWZmZXIsIG1heCwgIiVkIiwgaXQ4IC0+IGludW0pOyBicmVhazsKICAgIGNhc2UgU0ROVU06ICAgc25wcmludGYoQnVmZmVyLCBtYXgsIGl0OC0+RG91YmxlRm9ybWF0dGVyLCBpdDggLT4gZG51bSk7IGJyZWFrOwogICAgY2FzZSBTU1RSSU5HOiBzdHJuY3B5KEJ1ZmZlciwgaXQ4LT5zdHIsIG1heCk7CiAgICAgICAgICAgICAgICAgIEJ1ZmZlclttYXgtMV0gPSAwOwogICAgICAgICAgICAgICAgICBicmVhazsKCgogICAgZGVmYXVsdDoKICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIiVzIiwgRXJyb3JUaXRsZSk7CiAgICB9CgogICAgQnVmZmVyW21heF0gPSAwOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVGFibGUKCnN0YXRpYwpUQUJMRSogR2V0VGFibGUoY21zSVQ4KiBpdDgpCnsKICAgaWYgKChpdDggLT4gblRhYmxlID49IGl0OCAtPlRhYmxlc0NvdW50KSkgewoKICAgICAgICAgICBTeW5FcnJvcihpdDgsICJUYWJsZSAlZCBvdXQgb2Ygc2VxdWVuY2UiLCBpdDggLT4gblRhYmxlKTsKICAgICAgICAgICByZXR1cm4gaXQ4IC0+IFRhYjsKICAgfQoKICAgcmV0dXJuIGl0OCAtPlRhYiArIGl0OCAtPm5UYWJsZTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNZW1vcnkgbWFuYWdlbWVudAoKCi8vIEZyZWVzIGFuIGFsbG9jYXRvciBhbmQgb3duZWQgbWVtb3J5CnZvaWQgQ01TRVhQT1JUIGNtc0lUOEZyZWUoY21zSEFORExFIGhJVDgpCnsKICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKCiAgICBpZiAoaXQ4ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChpdDgtPk1lbW9yeVNpbmspIHsKCiAgICAgICAgT1dORURNRU0qIHA7CiAgICAgICAgT1dORURNRU0qIG47CgogICAgICAgIGZvciAocCA9IGl0OC0+TWVtb3J5U2luazsgcCAhPSBOVUxMOyBwID0gbikgewoKICAgICAgICAgICAgbiA9IHAtPk5leHQ7CiAgICAgICAgICAgIGlmIChwLT5QdHIpIF9jbXNGcmVlKGl0OCAtPkNvbnRleHRJRCwgcC0+UHRyKTsKICAgICAgICAgICAgX2Ntc0ZyZWUoaXQ4IC0+Q29udGV4dElELCBwKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGl0OC0+TWVtb3J5QmxvY2spCiAgICAgICAgX2Ntc0ZyZWUoaXQ4IC0+Q29udGV4dElELCBpdDgtPk1lbW9yeUJsb2NrKTsKCiAgICBfY21zRnJlZShpdDggLT5Db250ZXh0SUQsIGl0OCk7Cn0KCgovLyBBbGxvY2F0ZXMgYSBjaHVuayBvZiBkYXRhLCBrZWVwIGxpbmtlZCBsaXN0CnN0YXRpYwp2b2lkKiBBbGxvY0JpZ0Jsb2NrKGNtc0lUOCogaXQ4LCBjbXNVSW50MzJOdW1iZXIgc2l6ZSkKewogICAgT1dORURNRU0qIHB0cjE7CiAgICB2b2lkKiBwdHIgPSBfY21zTWFsbG9jWmVybyhpdDgtPkNvbnRleHRJRCwgc2l6ZSk7CgogICAgaWYgKHB0ciAhPSBOVUxMKSB7CgogICAgICAgIHB0cjEgPSAoT1dORURNRU0qKSBfY21zTWFsbG9jWmVybyhpdDggLT5Db250ZXh0SUQsIHNpemVvZihPV05FRE1FTSkpOwoKICAgICAgICBpZiAocHRyMSA9PSBOVUxMKSB7CgogICAgICAgICAgICBfY21zRnJlZShpdDggLT5Db250ZXh0SUQsIHB0cik7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KCiAgICAgICAgcHRyMS0+IFB0ciAgICAgICAgPSBwdHI7CiAgICAgICAgcHRyMS0+IE5leHQgICAgICAgPSBpdDggLT4gTWVtb3J5U2luazsKICAgICAgICBpdDggLT4gTWVtb3J5U2luayA9IHB0cjE7CiAgICB9CgogICAgcmV0dXJuIHB0cjsKfQoKCi8vIFN1YmFsbG9jYXRvci4Kc3RhdGljCnZvaWQqIEFsbG9jQ2h1bmsoY21zSVQ4KiBpdDgsIGNtc1VJbnQzMk51bWJlciBzaXplKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgRnJlZSA9IGl0OCAtPkFsbG9jYXRvci5CbG9ja1NpemUgLSBpdDggLT5BbGxvY2F0b3IuVXNlZDsKICAgIGNtc1VJbnQ4TnVtYmVyKiBwdHI7CgogICAgc2l6ZSA9IF9jbXNBTElHTk1FTShzaXplKTsKCiAgICBpZiAoc2l6ZSA+IEZyZWUpIHsKCiAgICAgICAgaWYgKGl0OCAtPiBBbGxvY2F0b3IuQmxvY2tTaXplID09IDApCgogICAgICAgICAgICAgICAgaXQ4IC0+IEFsbG9jYXRvci5CbG9ja1NpemUgPSAyMCoxMDI0OwogICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGl0OCAtPkFsbG9jYXRvci5CbG9ja1NpemUgKj0gMjsKCiAgICAgICAgaWYgKGl0OCAtPkFsbG9jYXRvci5CbG9ja1NpemUgPCBzaXplKQogICAgICAgICAgICAgICAgaXQ4IC0+QWxsb2NhdG9yLkJsb2NrU2l6ZSA9IHNpemU7CgogICAgICAgIGl0OCAtPkFsbG9jYXRvci5Vc2VkID0gMDsKICAgICAgICBpdDggLT5BbGxvY2F0b3IuQmxvY2sgPSAoY21zVUludDhOdW1iZXIqKSAgQWxsb2NCaWdCbG9jayhpdDgsIGl0OCAtPkFsbG9jYXRvci5CbG9ja1NpemUpOwogICAgfQoKICAgIHB0ciA9IGl0OCAtPkFsbG9jYXRvci5CbG9jayArIGl0OCAtPkFsbG9jYXRvci5Vc2VkOwogICAgaXQ4IC0+QWxsb2NhdG9yLlVzZWQgKz0gc2l6ZTsKCiAgICByZXR1cm4gKHZvaWQqKSBwdHI7Cgp9CgoKLy8gQWxsb2NhdGVzIGEgc3RyaW5nCnN0YXRpYwpjaGFyICpBbGxvY1N0cmluZyhjbXNJVDgqIGl0OCwgY29uc3QgY2hhciogc3RyKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgU2l6ZSA9IChjbXNVSW50MzJOdW1iZXIpIHN0cmxlbihzdHIpKzE7CiAgICBjaGFyICpwdHI7CgoKICAgIHB0ciA9IChjaGFyICopIEFsbG9jQ2h1bmsoaXQ4LCBTaXplKTsKICAgIGlmIChwdHIpIHN0cm5jcHkgKHB0ciwgc3RyLCBTaXplLTEpOwoKICAgIHJldHVybiBwdHI7Cn0KCi8vIFNlYXJjaGVzIHRocm91Z2ggbGlua2VkIGxpc3QKCnN0YXRpYwpjbXNCb29sIElzQXZhaWxhYmxlT25MaXN0KEtFWVZBTFVFKiBwLCBjb25zdCBjaGFyKiBLZXksIGNvbnN0IGNoYXIqIFN1YmtleSwgS0VZVkFMVUUqKiBMYXN0UHRyKQp7CiAgICBpZiAoTGFzdFB0cikgKkxhc3RQdHIgPSBwOwoKICAgIGZvciAoOyAgcCAhPSBOVUxMOyBwID0gcC0+TmV4dCkgewoKICAgICAgICBpZiAoTGFzdFB0cikgKkxhc3RQdHIgPSBwOwoKICAgICAgICBpZiAoKktleSAhPSAnIycpIHsgLy8gQ29tbWVudHMgYXJlIGlnbm9yZWQKCiAgICAgICAgICAgIGlmIChjbXNzdHJjYXNlY21wKEtleSwgcC0+S2V5d29yZCkgPT0gMCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAocCA9PSBOVUxMKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAoU3Via2V5ID09IDApCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgZm9yICg7IHAgIT0gTlVMTDsgcCA9IHAtPk5leHRTdWJrZXkpIHsKCiAgICAgICAgaWYgKHAgLT5TdWJrZXkgPT0gTlVMTCkgY29udGludWU7CgogICAgICAgIGlmIChMYXN0UHRyKSAqTGFzdFB0ciA9IHA7CgogICAgICAgIGlmIChjbXNzdHJjYXNlY21wKFN1YmtleSwgcC0+U3Via2V5KSA9PSAwKQogICAgICAgICAgICByZXR1cm4gVFJVRTsKICAgIH0KCiAgICByZXR1cm4gRkFMU0U7Cn0KCgoKLy8gQWRkIGEgcHJvcGVydHkgaW50byBhIGxpbmtlZCBsaXN0CnN0YXRpYwpLRVlWQUxVRSogQWRkVG9MaXN0KGNtc0lUOCogaXQ4LCBLRVlWQUxVRSoqIEhlYWQsIGNvbnN0IGNoYXIgKktleSwgY29uc3QgY2hhciAqU3Via2V5LCBjb25zdCBjaGFyKiB4VmFsdWUsIFdSSVRFTU9ERSBXcml0ZUFzKQp7CiAgICBLRVlWQUxVRSogcDsKICAgIEtFWVZBTFVFKiBsYXN0OwoKCiAgICAvLyBDaGVjayBpZiBwcm9wZXJ0eSBpcyBhbHJlYWR5IGluIGxpc3QKCiAgICBpZiAoSXNBdmFpbGFibGVPbkxpc3QoKkhlYWQsIEtleSwgU3Via2V5LCAmcCkpIHsKCiAgICAgICAgLy8gVGhpcyBtYXkgd29yayBmb3IgZWRpdGluZyBwcm9wZXJ0aWVzCgogICAgICAgIC8vICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiZHVwbGljYXRlIGtleSA8JXM+IiwgS2V5KTsKICAgIH0KICAgIGVsc2UgewoKICAgICAgICBsYXN0ID0gcDsKCiAgICAgICAgLy8gQWxsb2NhdGUgdGhlIGNvbnRhaW5lcgogICAgICAgIHAgPSAoS0VZVkFMVUUqKSBBbGxvY0NodW5rKGl0OCwgc2l6ZW9mKEtFWVZBTFVFKSk7CiAgICAgICAgaWYgKHAgPT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIkFkZFRvTGlzdDogb3V0IG9mIG1lbW9yeSIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CgogICAgICAgIC8vIFN0b3JlIG5hbWUgYW5kIHZhbHVlCiAgICAgICAgcC0+S2V5d29yZCA9IEFsbG9jU3RyaW5nKGl0OCwgS2V5KTsKICAgICAgICBwLT5TdWJrZXkgPSAoU3Via2V5ID09IE5VTEwpID8gTlVMTCA6IEFsbG9jU3RyaW5nKGl0OCwgU3Via2V5KTsKCiAgICAgICAgLy8gS2VlcCB0aGUgY29udGFpbmVyIGluIG91ciBsaXN0CiAgICAgICAgaWYgKCpIZWFkID09IE5VTEwpIHsKICAgICAgICAgICAgKkhlYWQgPSBwOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZiAoU3Via2V5ICE9IE5VTEwgJiYgbGFzdCAhPSBOVUxMKSB7CgogICAgICAgICAgICAgICAgbGFzdC0+TmV4dFN1YmtleSA9IHA7CgogICAgICAgICAgICAgICAgLy8gSWYgU3Via2V5IGlzIG5vdCBudWxsLCB0aGVuIGxhc3QgaXMgdGhlIGxhc3QgcHJvcGVydHkgd2l0aCB0aGUgc2FtZSBrZXksCiAgICAgICAgICAgICAgICAvLyBidXQgbm90IG5lY2Vzc2FyaWx5IGlzIHRoZSBsYXN0IHByb3BlcnR5IGluIHRoZSBsaXN0LCBzbyB3ZSBuZWVkIHRvIG1vdmUKICAgICAgICAgICAgICAgIC8vIHRvIHRoZSBhY3R1YWwgbGlzdCBlbmQKICAgICAgICAgICAgICAgIHdoaWxlIChsYXN0LT5OZXh0ICE9IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0ID0gbGFzdC0+TmV4dDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGxhc3QgIT0gTlVMTCkgbGFzdC0+TmV4dCA9IHA7CiAgICAgICAgfQoKICAgICAgICBwLT5OZXh0ICAgID0gTlVMTDsKICAgICAgICBwLT5OZXh0U3Via2V5ID0gTlVMTDsKICAgIH0KCiAgICBwLT5Xcml0ZUFzID0gV3JpdGVBczsKCiAgICBpZiAoeFZhbHVlICE9IE5VTEwpIHsKCiAgICAgICAgcC0+VmFsdWUgICA9IEFsbG9jU3RyaW5nKGl0OCwgeFZhbHVlKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHAtPlZhbHVlICAgPSBOVUxMOwogICAgfQoKICAgIHJldHVybiBwOwp9CgpzdGF0aWMKS0VZVkFMVUUqIEFkZEF2YWlsYWJsZVByb3BlcnR5KGNtc0lUOCogaXQ4LCBjb25zdCBjaGFyKiBLZXksIFdSSVRFTU9ERSBhcykKewogICAgcmV0dXJuIEFkZFRvTGlzdChpdDgsICZpdDgtPlZhbGlkS2V5d29yZHMsIEtleSwgTlVMTCwgTlVMTCwgYXMpOwp9CgoKc3RhdGljCktFWVZBTFVFKiBBZGRBdmFpbGFibGVTYW1wbGVJRChjbXNJVDgqIGl0OCwgY29uc3QgY2hhciogS2V5KQp7CiAgICByZXR1cm4gQWRkVG9MaXN0KGl0OCwgJml0OC0+VmFsaWRTYW1wbGVJRCwgS2V5LCBOVUxMLCBOVUxMLCBXUklURV9VTkNPT0tFRCk7Cn0KCgpzdGF0aWMKdm9pZCBBbGxvY1RhYmxlKGNtc0lUOCogaXQ4KQp7CiAgICBUQUJMRSogdDsKCiAgICB0ID0gaXQ4IC0+VGFiICsgaXQ4IC0+VGFibGVzQ291bnQ7CgogICAgdC0+SGVhZGVyTGlzdCA9IE5VTEw7CiAgICB0LT5EYXRhRm9ybWF0ID0gTlVMTDsKICAgIHQtPkRhdGEgICAgICAgPSBOVUxMOwoKICAgIGl0OCAtPlRhYmxlc0NvdW50Kys7Cn0KCgpjbXNJbnQzMk51bWJlciBDTVNFWFBPUlQgY21zSVQ4U2V0VGFibGUoY21zSEFORExFICBJVDgsIGNtc1VJbnQzMk51bWJlciBuVGFibGUpCnsKICAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBJVDg7CgogICAgIGlmIChuVGFibGUgPj0gaXQ4IC0+VGFibGVzQ291bnQpIHsKCiAgICAgICAgIGlmIChuVGFibGUgPT0gaXQ4IC0+VGFibGVzQ291bnQpIHsKCiAgICAgICAgICAgICBBbGxvY1RhYmxlKGl0OCk7CiAgICAgICAgIH0KICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICBTeW5FcnJvcihpdDgsICJUYWJsZSAlZCBpcyBvdXQgb2Ygc2VxdWVuY2UiLCBuVGFibGUpOwogICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICB9CiAgICAgfQoKICAgICBpdDggLT5uVGFibGUgPSBuVGFibGU7CgogICAgIHJldHVybiAoY21zSW50MzJOdW1iZXIpIG5UYWJsZTsKfQoKCgovLyBJbml0IGFuIGVtcHR5IGNvbnRhaW5lcgpjbXNIQU5ETEUgIENNU0VYUE9SVCBjbXNJVDhBbGxvYyhjbXNDb250ZXh0IENvbnRleHRJRCkKewogICAgY21zSVQ4KiBpdDg7CiAgICBjbXNVSW50MzJOdW1iZXIgaTsKCiAgICBpdDggPSAoY21zSVQ4KikgX2Ntc01hbGxvY1plcm8oQ29udGV4dElELCBzaXplb2YoY21zSVQ4KSk7CiAgICBpZiAoaXQ4ID09IE5VTEwpIHJldHVybiBOVUxMOwoKICAgIEFsbG9jVGFibGUoaXQ4KTsKCiAgICBpdDgtPk1lbW9yeUJsb2NrID0gTlVMTDsKICAgIGl0OC0+TWVtb3J5U2luayAgPSBOVUxMOwoKICAgIGl0OCAtPm5UYWJsZSA9IDA7CgogICAgaXQ4LT5Db250ZXh0SUQgPSBDb250ZXh0SUQ7CiAgICBpdDgtPkFsbG9jYXRvci5Vc2VkID0gMDsKICAgIGl0OC0+QWxsb2NhdG9yLkJsb2NrID0gTlVMTDsKICAgIGl0OC0+QWxsb2NhdG9yLkJsb2NrU2l6ZSA9IDA7CgogICAgaXQ4LT5WYWxpZEtleXdvcmRzID0gTlVMTDsKICAgIGl0OC0+VmFsaWRTYW1wbGVJRCA9IE5VTEw7CgogICAgaXQ4IC0+IHN5ID0gU1VOREVGSU5FRDsKICAgIGl0OCAtPiBjaCA9ICcgJzsKICAgIGl0OCAtPiBTb3VyY2UgPSBOVUxMOwogICAgaXQ4IC0+IGludW0gPSAwOwogICAgaXQ4IC0+IGRudW0gPSAwLjA7CgogICAgaXQ4LT5GaWxlU3RhY2tbMF0gPSAoRklMRUNUWCopQWxsb2NDaHVuayhpdDgsIHNpemVvZihGSUxFQ1RYKSk7CiAgICBpdDgtPkluY2x1ZGVTUCAgID0gMDsKICAgIGl0OCAtPiBsaW5lbm8gPSAxOwoKICAgIHN0cmNweShpdDgtPkRvdWJsZUZvcm1hdHRlciwgREVGQVVMVF9EQkxfRk9STUFUKTsKICAgIGNtc0lUOFNldFNoZWV0VHlwZSgoY21zSEFORExFKSBpdDgsICJDR0FUUy4xNyIpOwoKICAgIC8vIEluaXRpYWxpemUgcHJlZGVmaW5lZCBwcm9wZXJ0aWVzICYgZGF0YQoKICAgIGZvciAoaT0wOyBpIDwgTlVNUFJFREVGSU5FRFBST1BTOyBpKyspCiAgICAgICAgICAgIEFkZEF2YWlsYWJsZVByb3BlcnR5KGl0OCwgUHJlZGVmaW5lZFByb3BlcnRpZXNbaV0uaWQsIFByZWRlZmluZWRQcm9wZXJ0aWVzW2ldLmFzKTsKCiAgICBmb3IgKGk9MDsgaSA8IE5VTVBSRURFRklORURTQU1QTEVJRDsgaSsrKQogICAgICAgICAgICBBZGRBdmFpbGFibGVTYW1wbGVJRChpdDgsIFByZWRlZmluZWRTYW1wbGVJRFtpXSk7CgoKICAgcmV0dXJuIChjbXNIQU5ETEUpIGl0ODsKfQoKCmNvbnN0IGNoYXIqIENNU0VYUE9SVCBjbXNJVDhHZXRTaGVldFR5cGUoY21zSEFORExFIGhJVDgpCnsKICAgICAgICByZXR1cm4gR2V0VGFibGUoKGNtc0lUOCopIGhJVDgpLT5TaGVldFR5cGU7Cn0KCmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNldFNoZWV0VHlwZShjbXNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogVHlwZSkKewogICAgICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoKGNtc0lUOCopIGhJVDgpOwoKICAgICAgICBzdHJuY3B5KHQgLT5TaGVldFR5cGUsIFR5cGUsIE1BWFNUUi0xKTsKICAgICAgICB0IC0+U2hlZXRUeXBlW01BWFNUUi0xXSA9IDA7CiAgICAgICAgcmV0dXJuIFRSVUU7Cn0KCmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNldENvbW1lbnQoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIFZhbCkKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKCiAgICBpZiAoIVZhbCkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCEqVmFsKSByZXR1cm4gRkFMU0U7CgogICAgcmV0dXJuIEFkZFRvTGlzdChpdDgsICZHZXRUYWJsZShpdDgpLT5IZWFkZXJMaXN0LCAiIyAiLCBOVUxMLCBWYWwsIFdSSVRFX1VOQ09PS0VEKSAhPSBOVUxMOwp9CgovLyBTZXRzIGEgcHJvcGVydHkKY21zQm9vbCBDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlTdHIoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIEtleSwgY29uc3QgY2hhciAqVmFsKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwoKICAgIGlmICghVmFsKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoISpWYWwpIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gQWRkVG9MaXN0KGl0OCwgJkdldFRhYmxlKGl0OCktPkhlYWRlckxpc3QsIEtleSwgTlVMTCwgVmFsLCBXUklURV9TVFJJTkdJRlkpICE9IE5VTEw7Cn0KCmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNldFByb3BlcnR5RGJsKGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCwgY21zRmxvYXQ2NE51bWJlciBWYWwpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CiAgICBjaGFyIEJ1ZmZlclsxMDI0XTsKCiAgICBzcHJpbnRmKEJ1ZmZlciwgaXQ4LT5Eb3VibGVGb3JtYXR0ZXIsIFZhbCk7CgogICAgcmV0dXJuIEFkZFRvTGlzdChpdDgsICZHZXRUYWJsZShpdDgpLT5IZWFkZXJMaXN0LCBjUHJvcCwgTlVMTCwgQnVmZmVyLCBXUklURV9VTkNPT0tFRCkgIT0gTlVMTDsKfQoKY21zQm9vbCBDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlIZXgoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNQcm9wLCBjbXNVSW50MzJOdW1iZXIgVmFsKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwogICAgY2hhciBCdWZmZXJbMTAyNF07CgogICAgc3ByaW50ZihCdWZmZXIsICIldSIsIFZhbCk7CgogICAgcmV0dXJuIEFkZFRvTGlzdChpdDgsICZHZXRUYWJsZShpdDgpLT5IZWFkZXJMaXN0LCBjUHJvcCwgTlVMTCwgQnVmZmVyLCBXUklURV9IRVhBREVDSU1BTCkgIT0gTlVMTDsKfQoKY21zQm9vbCBDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlVbmNvb2tlZChjbXNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogS2V5LCBjb25zdCBjaGFyKiBCdWZmZXIpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CgogICAgcmV0dXJuIEFkZFRvTGlzdChpdDgsICZHZXRUYWJsZShpdDgpLT5IZWFkZXJMaXN0LCBLZXksIE5VTEwsIEJ1ZmZlciwgV1JJVEVfVU5DT09LRUQpICE9IE5VTEw7Cn0KCmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNldFByb3BlcnR5TXVsdGkoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIEtleSwgY29uc3QgY2hhciogU3ViS2V5LCBjb25zdCBjaGFyICpCdWZmZXIpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CgogICAgcmV0dXJuIEFkZFRvTGlzdChpdDgsICZHZXRUYWJsZShpdDgpLT5IZWFkZXJMaXN0LCBLZXksIFN1YktleSwgQnVmZmVyLCBXUklURV9QQUlSKSAhPSBOVUxMOwp9CgovLyBHZXRzIGEgcHJvcGVydHkKY29uc3QgY2hhciogQ01TRVhQT1JUIGNtc0lUOEdldFByb3BlcnR5KGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBLZXkpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CiAgICBLRVlWQUxVRSogcDsKCiAgICBpZiAoSXNBdmFpbGFibGVPbkxpc3QoR2V0VGFibGUoaXQ4KSAtPiBIZWFkZXJMaXN0LCBLZXksIE5VTEwsICZwKSkKICAgIHsKICAgICAgICByZXR1cm4gcCAtPiBWYWx1ZTsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgoKY21zRmxvYXQ2NE51bWJlciBDTVNFWFBPUlQgY21zSVQ4R2V0UHJvcGVydHlEYmwoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNQcm9wKQp7CiAgICBjb25zdCBjaGFyICp2ID0gY21zSVQ4R2V0UHJvcGVydHkoaElUOCwgY1Byb3ApOwoKICAgIGlmICh2ID09IE5VTEwpIHJldHVybiAwLjA7CgogICAgcmV0dXJuIFBhcnNlRmxvYXROdW1iZXIodik7Cn0KCmNvbnN0IGNoYXIqIENNU0VYUE9SVCBjbXNJVDhHZXRQcm9wZXJ0eU11bHRpKGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBLZXksIGNvbnN0IGNoYXIgKlN1YktleSkKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKICAgIEtFWVZBTFVFKiBwOwoKICAgIGlmIChJc0F2YWlsYWJsZU9uTGlzdChHZXRUYWJsZShpdDgpIC0+IEhlYWRlckxpc3QsIEtleSwgU3ViS2V5LCAmcCkpIHsKICAgICAgICByZXR1cm4gcCAtPiBWYWx1ZTsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBEYXRhc2V0cwoKCnN0YXRpYwp2b2lkIEFsbG9jYXRlRGF0YUZvcm1hdChjbXNJVDgqIGl0OCkKewogICAgVEFCTEUqIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGlmICh0IC0+IERhdGFGb3JtYXQpIHJldHVybjsgICAgLy8gQWxyZWFkeSBhbGxvY2F0ZWQKCiAgICB0IC0+IG5TYW1wbGVzICA9IChpbnQpIGNtc0lUOEdldFByb3BlcnR5RGJsKGl0OCwgIk5VTUJFUl9PRl9GSUVMRFMiKTsKCiAgICBpZiAodCAtPiBuU2FtcGxlcyA8PSAwKSB7CgogICAgICAgIFN5bkVycm9yKGl0OCwgIkFsbG9jYXRlRGF0YUZvcm1hdDogVW5rbm93biBOVU1CRVJfT0ZfRklFTERTIik7CiAgICAgICAgdCAtPiBuU2FtcGxlcyA9IDEwOwogICAgICAgIH0KCiAgICB0IC0+IERhdGFGb3JtYXQgPSAoY2hhcioqKSBBbGxvY0NodW5rIChpdDgsICgoY21zVUludDMyTnVtYmVyKSB0LT5uU2FtcGxlcyArIDEpICogc2l6ZW9mKGNoYXIgKikpOwogICAgaWYgKHQtPkRhdGFGb3JtYXQgPT0gTlVMTCkgewoKICAgICAgICBTeW5FcnJvcihpdDgsICJBbGxvY2F0ZURhdGFGb3JtYXQ6IFVuYWJsZSB0byBhbGxvY2F0ZSBkYXRhRm9ybWF0IGFycmF5Iik7CiAgICB9Cgp9CgpzdGF0aWMKY29uc3QgY2hhciAqR2V0RGF0YUZvcm1hdChjbXNJVDgqIGl0OCwgaW50IG4pCnsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBpZiAodC0+RGF0YUZvcm1hdCkKICAgICAgICByZXR1cm4gdC0+RGF0YUZvcm1hdFtuXTsKCiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljCmNtc0Jvb2wgU2V0RGF0YUZvcm1hdChjbXNJVDgqIGl0OCwgaW50IG4sIGNvbnN0IGNoYXIgKmxhYmVsKQp7CiAgICBUQUJMRSogdCA9IEdldFRhYmxlKGl0OCk7CgogICAgaWYgKCF0LT5EYXRhRm9ybWF0KQogICAgICAgIEFsbG9jYXRlRGF0YUZvcm1hdChpdDgpOwoKICAgIGlmIChuID4gdCAtPiBuU2FtcGxlcykgewogICAgICAgIFN5bkVycm9yKGl0OCwgIk1vcmUgdGhhbiBOVU1CRVJfT0ZfRklFTERTIGZpZWxkcy4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKHQtPkRhdGFGb3JtYXQpIHsKICAgICAgICB0LT5EYXRhRm9ybWF0W25dID0gQWxsb2NTdHJpbmcoaXQ4LCBsYWJlbCk7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCgpjbXNCb29sIENNU0VYUE9SVCBjbXNJVDhTZXREYXRhRm9ybWF0KGNtc0hBTkRMRSAgaCwgaW50IG4sIGNvbnN0IGNoYXIgKlNhbXBsZSkKewogICAgICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGg7CiAgICAgICAgcmV0dXJuIFNldERhdGFGb3JtYXQoaXQ4LCBuLCBTYW1wbGUpOwp9CgpzdGF0aWMKdm9pZCBBbGxvY2F0ZURhdGFTZXQoY21zSVQ4KiBpdDgpCnsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBpZiAodCAtPiBEYXRhKSByZXR1cm47ICAgIC8vIEFscmVhZHkgYWxsb2NhdGVkCgogICAgdC0+IG5TYW1wbGVzICAgPSBhdG9pKGNtc0lUOEdldFByb3BlcnR5KGl0OCwgIk5VTUJFUl9PRl9GSUVMRFMiKSk7CiAgICB0LT4gblBhdGNoZXMgICA9IGF0b2koY21zSVQ4R2V0UHJvcGVydHkoaXQ4LCAiTlVNQkVSX09GX1NFVFMiKSk7CgogICAgdC0+IERhdGEgPSAoY2hhcioqKUFsbG9jQ2h1bmsgKGl0OCwgKChjbXNVSW50MzJOdW1iZXIpIHQtPm5TYW1wbGVzICsgMSkgKiAoKGNtc1VJbnQzMk51bWJlcikgdC0+blBhdGNoZXMgKyAxKSAqc2l6ZW9mIChjaGFyKikpOwogICAgaWYgKHQtPkRhdGEgPT0gTlVMTCkgewoKICAgICAgICBTeW5FcnJvcihpdDgsICJBbGxvY2F0ZURhdGFTZXQ6IFVuYWJsZSB0byBhbGxvY2F0ZSBkYXRhIGFycmF5Iik7CiAgICB9Cgp9CgpzdGF0aWMKY2hhciogR2V0RGF0YShjbXNJVDgqIGl0OCwgaW50IG5TZXQsIGludCBuRmllbGQpCnsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKICAgIGludCAgblNhbXBsZXMgICA9IHQgLT4gblNhbXBsZXM7CiAgICBpbnQgIG5QYXRjaGVzICAgPSB0IC0+IG5QYXRjaGVzOwoKICAgIGlmIChuU2V0ID49IG5QYXRjaGVzIHx8IG5GaWVsZCA+PSBuU2FtcGxlcykKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBpZiAoIXQtPkRhdGEpIHJldHVybiBOVUxMOwogICAgcmV0dXJuIHQtPkRhdGEgW25TZXQgKiBuU2FtcGxlcyArIG5GaWVsZF07Cn0KCnN0YXRpYwpjbXNCb29sIFNldERhdGEoY21zSVQ4KiBpdDgsIGludCBuU2V0LCBpbnQgbkZpZWxkLCBjb25zdCBjaGFyICpWYWwpCnsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBpZiAoIXQtPkRhdGEpCiAgICAgICAgQWxsb2NhdGVEYXRhU2V0KGl0OCk7CgogICAgaWYgKCF0LT5EYXRhKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKG5TZXQgPiB0IC0+IG5QYXRjaGVzIHx8IG5TZXQgPCAwKSB7CgogICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiUGF0Y2ggJWQgb3V0IG9mIHJhbmdlLCB0aGVyZSBhcmUgJWQgcGF0Y2hlcyIsIG5TZXQsIHQgLT4gblBhdGNoZXMpOwogICAgfQoKICAgIGlmIChuRmllbGQgPiB0IC0+blNhbXBsZXMgfHwgbkZpZWxkIDwgMCkgewogICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiU2FtcGxlICVkIG91dCBvZiByYW5nZSwgdGhlcmUgYXJlICVkIHNhbXBsZXMiLCBuRmllbGQsIHQgLT5uU2FtcGxlcyk7CgogICAgfQoKICAgIHQtPkRhdGEgW25TZXQgKiB0IC0+IG5TYW1wbGVzICsgbkZpZWxkXSA9IEFsbG9jU3RyaW5nKGl0OCwgVmFsKTsKICAgIHJldHVybiBUUlVFOwp9CgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpbGUgSS9PCgoKLy8gV3JpdGVzIGEgc3RyaW5nIHRvIGZpbGUKc3RhdGljCnZvaWQgV3JpdGVTdHIoU0FWRVNUUkVBTSogZiwgY29uc3QgY2hhciAqc3RyKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgbGVuOwoKICAgIGlmIChzdHIgPT0gTlVMTCkKICAgICAgICBzdHIgPSAiICI7CgogICAgLy8gTGVuZ3RoIHRvIHdyaXRlCiAgICBsZW4gPSAoY21zVUludDMyTnVtYmVyKSBzdHJsZW4oc3RyKTsKICAgIGYgLT5Vc2VkICs9IGxlbjsKCgogICAgaWYgKGYgLT5zdHJlYW0pIHsgICAvLyBTaG91bGQgSSB3cml0ZSBpdCB0byBhIGZpbGU/CgogICAgICAgIGlmIChmd3JpdGUoc3RyLCAxLCBsZW4sIGYtPnN0cmVhbSkgIT0gbGVuKSB7CiAgICAgICAgICAgIGNtc1NpZ25hbEVycm9yKDAsIGNtc0VSUk9SX1dSSVRFLCAiV3JpdGUgdG8gZmlsZSBlcnJvciBpbiBDR0FUUyBwYXJzZXIiKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICB9CiAgICBlbHNlIHsgIC8vIE9yIHRvIGEgbWVtb3J5IGJsb2NrPwoKICAgICAgICBpZiAoZiAtPkJhc2UpIHsgICAvLyBBbSBJIGp1c3QgY291bnRpbmcgdGhlIGJ5dGVzPwoKICAgICAgICAgICAgaWYgKGYgLT5Vc2VkID4gZiAtPk1heCkgewoKICAgICAgICAgICAgICAgICBjbXNTaWduYWxFcnJvcigwLCBjbXNFUlJPUl9XUklURSwgIldyaXRlIHRvIG1lbW9yeSBvdmVyZmxvd3MgaW4gQ0dBVFMgcGFyc2VyIik7CiAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBtZW1tb3ZlKGYgLT5QdHIsIHN0ciwgbGVuKTsKICAgICAgICAgICAgZi0+UHRyICs9IGxlbjsKICAgICAgICB9CgogICAgfQp9CgoKLy8gV3JpdGUgZm9ybWF0dGVkCgpzdGF0aWMKdm9pZCBXcml0ZWYoU0FWRVNUUkVBTSogZiwgY29uc3QgY2hhciogZnJtLCAuLi4pCnsKICAgIGNoYXIgQnVmZmVyWzQwOTZdOwogICAgdmFfbGlzdCBhcmdzOwoKICAgIHZhX3N0YXJ0KGFyZ3MsIGZybSk7CiAgICB2c25wcmludGYoQnVmZmVyLCA0MDk1LCBmcm0sIGFyZ3MpOwogICAgQnVmZmVyWzQwOTVdID0gMDsKICAgIFdyaXRlU3RyKGYsIEJ1ZmZlcik7CiAgICB2YV9lbmQoYXJncyk7Cgp9CgovLyBXcml0ZXMgZnVsbCBoZWFkZXIKc3RhdGljCnZvaWQgV3JpdGVIZWFkZXIoY21zSVQ4KiBpdDgsIFNBVkVTVFJFQU0qIGZwKQp7CiAgICBLRVlWQUxVRSogcDsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICAvLyBXcml0ZXMgdGhlIHR5cGUKICAgIFdyaXRlU3RyKGZwLCB0LT5TaGVldFR5cGUpOwogICAgV3JpdGVTdHIoZnAsICJcbiIpOwoKICAgIGZvciAocCA9IHQtPkhlYWRlckxpc3Q7IChwICE9IE5VTEwpOyBwID0gcC0+TmV4dCkKICAgIHsKICAgICAgICBpZiAoKnAgLT5LZXl3b3JkID09ICcjJykgewoKICAgICAgICAgICAgY2hhciogUHQ7CgogICAgICAgICAgICBXcml0ZVN0cihmcCwgIiNcbiMgIik7CiAgICAgICAgICAgIGZvciAoUHQgPSBwIC0+VmFsdWU7ICpQdDsgUHQrKykgewoKCiAgICAgICAgICAgICAgICBXcml0ZWYoZnAsICIlYyIsICpQdCk7CgogICAgICAgICAgICAgICAgaWYgKCpQdCA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgV3JpdGVTdHIoZnAsICIjICIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBXcml0ZVN0cihmcCwgIlxuI1xuIik7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCgogICAgICAgIGlmICghSXNBdmFpbGFibGVPbkxpc3QoaXQ4LT4gVmFsaWRLZXl3b3JkcywgcC0+S2V5d29yZCwgTlVMTCwgTlVMTCkpIHsKCiNpZmRlZiBDTVNfU1RSSUNUX0NHQVRTCiAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAiS0VZV09SRFx0XCIiKTsKICAgICAgICAgICAgV3JpdGVTdHIoZnAsIHAtPktleXdvcmQpOwogICAgICAgICAgICBXcml0ZVN0cihmcCwgIlwiXG4iKTsKI2VuZGlmCgogICAgICAgICAgICBBZGRBdmFpbGFibGVQcm9wZXJ0eShpdDgsIHAtPktleXdvcmQsIFdSSVRFX1VOQ09PS0VEKTsKICAgICAgICB9CgogICAgICAgIFdyaXRlU3RyKGZwLCBwLT5LZXl3b3JkKTsKICAgICAgICBpZiAocC0+VmFsdWUpIHsKCiAgICAgICAgICAgIHN3aXRjaCAocCAtPldyaXRlQXMpIHsKCiAgICAgICAgICAgIGNhc2UgV1JJVEVfVU5DT09LRUQ6CiAgICAgICAgICAgICAgICAgICAgV3JpdGVmKGZwLCAiXHQlcyIsIHAgLT5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdSSVRFX1NUUklOR0lGWToKICAgICAgICAgICAgICAgICAgICBXcml0ZWYoZnAsICJcdFwiJXNcIiIsIHAtPlZhbHVlICk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdSSVRFX0hFWEFERUNJTUFMOgogICAgICAgICAgICAgICAgICAgIFdyaXRlZihmcCwgIlx0MHglWCIsIGF0b2kocCAtPlZhbHVlKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdSSVRFX0JJTkFSWToKICAgICAgICAgICAgICAgICAgICBXcml0ZWYoZnAsICJcdDB4JUIiLCBhdG9pKHAgLT5WYWx1ZSkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXUklURV9QQUlSOgogICAgICAgICAgICAgICAgICAgIFdyaXRlZihmcCwgIlx0XCIlcywlc1wiIiwgcC0+U3Via2V5LCBwLT5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OiBTeW5FcnJvcihpdDgsICJVbmtub3duIHdyaXRlIG1vZGUgJWQiLCBwIC0+V3JpdGVBcyk7CiAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgV3JpdGVTdHIgKGZwLCAiXG4iKTsKICAgIH0KCn0KCgovLyBXcml0ZXMgdGhlIGRhdGEgZm9ybWF0CnN0YXRpYwp2b2lkIFdyaXRlRGF0YUZvcm1hdChTQVZFU1RSRUFNKiBmcCwgY21zSVQ4KiBpdDgpCnsKICAgIGludCBpLCBuU2FtcGxlczsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBpZiAoIXQgLT4gRGF0YUZvcm1hdCkgcmV0dXJuOwoKICAgICAgIFdyaXRlU3RyKGZwLCAiQkVHSU5fREFUQV9GT1JNQVRcbiIpOwogICAgICAgV3JpdGVTdHIoZnAsICIgIik7CiAgICAgICBuU2FtcGxlcyA9IGF0b2koY21zSVQ4R2V0UHJvcGVydHkoaXQ4LCAiTlVNQkVSX09GX0ZJRUxEUyIpKTsKCiAgICAgICBmb3IgKGkgPSAwOyBpIDwgblNhbXBsZXM7IGkrKykgewoKICAgICAgICAgICAgICBXcml0ZVN0cihmcCwgdC0+RGF0YUZvcm1hdFtpXSk7CiAgICAgICAgICAgICAgV3JpdGVTdHIoZnAsICgoaSA9PSAoblNhbXBsZXMtMSkpID8gIlxuIiA6ICJcdCIpKTsKICAgICAgICAgIH0KCiAgICAgICBXcml0ZVN0ciAoZnAsICJFTkRfREFUQV9GT1JNQVRcbiIpOwp9CgoKLy8gV3JpdGVzIGRhdGEgYXJyYXkKc3RhdGljCnZvaWQgV3JpdGVEYXRhKFNBVkVTVFJFQU0qIGZwLCBjbXNJVDgqIGl0OCkKewogICAgICAgaW50ICBpLCBqOwogICAgICAgVEFCTEUqIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgICAgIGlmICghdC0+RGF0YSkgcmV0dXJuOwoKICAgICAgIFdyaXRlU3RyIChmcCwgIkJFR0lOX0RBVEFcbiIpOwoKICAgICAgIHQtPm5QYXRjaGVzID0gYXRvaShjbXNJVDhHZXRQcm9wZXJ0eShpdDgsICJOVU1CRVJfT0ZfU0VUUyIpKTsKCiAgICAgICBmb3IgKGkgPSAwOyBpIDwgdC0+IG5QYXRjaGVzOyBpKyspIHsKCiAgICAgICAgICAgICAgV3JpdGVTdHIoZnAsICIgIik7CgogICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCB0LT5uU2FtcGxlczsgaisrKSB7CgogICAgICAgICAgICAgICAgICAgICBjaGFyICpwdHIgPSB0LT5EYXRhW2kqdC0+blNhbXBsZXMral07CgogICAgICAgICAgICAgICAgICAgICBpZiAocHRyID09IE5VTEwpIFdyaXRlU3RyKGZwLCAiXCJcIiIpOwogICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHZhbHVlIGNvbnRhaW5zIHdoaXRlc3BhY2UsIGVuY2xvc2Ugd2l0aGluIHF1b3RlCgogICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmNocihwdHIsICcgJykgIT0gTlVMTCkgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXcml0ZVN0cihmcCwgIlwiIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV3JpdGVTdHIoZnAsIHB0cik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV3JpdGVTdHIoZnAsICJcIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgV3JpdGVTdHIoZnAsIHB0cik7CiAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAoKGogPT0gKHQtPm5TYW1wbGVzLTEpKSA/ICJcbiIgOiAiXHQiKSk7CiAgICAgICAgICAgICAgfQogICAgICAgfQogICAgICAgV3JpdGVTdHIgKGZwLCAiRU5EX0RBVEFcbiIpOwp9CgoKCi8vIFNhdmVzIHdob2xlIGZpbGUKY21zQm9vbCBDTVNFWFBPUlQgY21zSVQ4U2F2ZVRvRmlsZShjbXNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY0ZpbGVOYW1lKQp7CiAgICBTQVZFU1RSRUFNIHNkOwogICAgY21zVUludDMyTnVtYmVyIGk7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwoKICAgIG1lbXNldCgmc2QsIDAsIHNpemVvZihzZCkpOwoKICAgIHNkLnN0cmVhbSA9IGZvcGVuKGNGaWxlTmFtZSwgInd0Iik7CiAgICBpZiAoIXNkLnN0cmVhbSkgcmV0dXJuIEZBTFNFOwoKICAgIGZvciAoaT0wOyBpIDwgaXQ4IC0+VGFibGVzQ291bnQ7IGkrKykgewoKICAgICAgICAgICAgY21zSVQ4U2V0VGFibGUoaElUOCwgaSk7CiAgICAgICAgICAgIFdyaXRlSGVhZGVyKGl0OCwgJnNkKTsKICAgICAgICAgICAgV3JpdGVEYXRhRm9ybWF0KCZzZCwgaXQ4KTsKICAgICAgICAgICAgV3JpdGVEYXRhKCZzZCwgaXQ4KTsKICAgIH0KCiAgICBpZiAoZmNsb3NlKHNkLnN0cmVhbSkgIT0gMCkgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBUUlVFOwp9CgoKLy8gU2F2ZXMgdG8gbWVtb3J5CmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNhdmVUb01lbShjbXNIQU5ETEUgaElUOCwgdm9pZCAqTWVtUHRyLCBjbXNVSW50MzJOdW1iZXIqIEJ5dGVzTmVlZGVkKQp7CiAgICBTQVZFU1RSRUFNIHNkOwogICAgY21zVUludDMyTnVtYmVyIGk7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwoKICAgIG1lbXNldCgmc2QsIDAsIHNpemVvZihzZCkpOwoKICAgIHNkLnN0cmVhbSA9IE5VTEw7CiAgICBzZC5CYXNlICAgPSAoY21zVUludDhOdW1iZXIqKSAgTWVtUHRyOwogICAgc2QuUHRyICAgID0gc2QuQmFzZTsKCiAgICBzZC5Vc2VkID0gMDsKCiAgICBpZiAoc2QuQmFzZSkKICAgICAgICBzZC5NYXggID0gKkJ5dGVzTmVlZGVkOyAgICAgLy8gV3JpdGUgdG8gbWVtb3J5PwogICAgZWxzZQogICAgICAgIHNkLk1heCAgPSAwOyAgICAgICAgICAgICAgICAvLyBKdXN0IGNvdW50aW5nIHRoZSBuZWVkZWQgYnl0ZXMKCiAgICBmb3IgKGk9MDsgaSA8IGl0OCAtPlRhYmxlc0NvdW50OyBpKyspIHsKCiAgICAgICAgY21zSVQ4U2V0VGFibGUoaElUOCwgaSk7CiAgICAgICAgV3JpdGVIZWFkZXIoaXQ4LCAmc2QpOwogICAgICAgIFdyaXRlRGF0YUZvcm1hdCgmc2QsIGl0OCk7CiAgICAgICAgV3JpdGVEYXRhKCZzZCwgaXQ4KTsKICAgIH0KCiAgICBzZC5Vc2VkKys7ICAvLyBUaGUgXDAgYXQgdGhlIHZlcnkgZW5kCgogICAgaWYgKHNkLkJhc2UpCiAgICAgICAgKnNkLlB0ciA9IDA7CgogICAgKkJ5dGVzTmVlZGVkID0gc2QuVXNlZDsKCiAgICByZXR1cm4gVFJVRTsKfQoKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEhpZ2VyIGxldmVsIHBhcnNpbmcKCnN0YXRpYwpjbXNCb29sIERhdGFGb3JtYXRTZWN0aW9uKGNtc0lUOCogaXQ4KQp7CiAgICBpbnQgaUZpZWxkID0gMDsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBJblN5bWJvbChpdDgpOyAgIC8vIEVhdHMgIkJFR0lOX0RBVEFfRk9STUFUIgogICAgQ2hlY2tFT0xOKGl0OCk7CgogICAgd2hpbGUgKGl0OC0+c3kgIT0gU0VORF9EQVRBX0ZPUk1BVCAmJgogICAgICAgIGl0OC0+c3kgIT0gU0VPTE4gJiYKICAgICAgICBpdDgtPnN5ICE9IFNFT0YgJiYKICAgICAgICBpdDgtPnN5ICE9IFNTWU5FUlJPUikgIHsKCiAgICAgICAgICAgIGlmIChpdDgtPnN5ICE9IFNJREVOVCkgewoKICAgICAgICAgICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsICJTYW1wbGUgdHlwZSBleHBlY3RlZCIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIVNldERhdGFGb3JtYXQoaXQ4LCBpRmllbGQsIGl0OC0+aWQpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIGlGaWVsZCsrOwoKICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICAgICAgU2tpcEVPTE4oaXQ4KTsKICAgICAgIH0KCiAgICAgICBTa2lwRU9MTihpdDgpOwogICAgICAgU2tpcChpdDgsIFNFTkRfREFUQV9GT1JNQVQpOwogICAgICAgU2tpcEVPTE4oaXQ4KTsKCiAgICAgICBpZiAoaUZpZWxkICE9IHQgLT5uU2FtcGxlcykgewogICAgICAgICAgIFN5bkVycm9yKGl0OCwgIkNvdW50IG1pc21hdGNoLiBOVU1CRVJfT0ZfRklFTERTIHdhcyAlZCwgZm91bmQgJWRcbiIsIHQgLT5uU2FtcGxlcywgaUZpZWxkKTsKCgogICAgICAgfQoKICAgICAgIHJldHVybiBUUlVFOwp9CgoKCnN0YXRpYwpjbXNCb29sIERhdGFTZWN0aW9uIChjbXNJVDgqIGl0OCkKewogICAgaW50ICBpRmllbGQgPSAwOwogICAgaW50ICBpU2V0ICAgPSAwOwogICAgY2hhciBCdWZmZXJbMjU2XTsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBJblN5bWJvbChpdDgpOyAgIC8vIEVhdHMgIkJFR0lOX0RBVEEiCiAgICBDaGVja0VPTE4oaXQ4KTsKCiAgICBpZiAoIXQtPkRhdGEpCiAgICAgICAgQWxsb2NhdGVEYXRhU2V0KGl0OCk7CgogICAgd2hpbGUgKGl0OC0+c3kgIT0gU0VORF9EQVRBICYmIGl0OC0+c3kgIT0gU0VPRikKICAgIHsKICAgICAgICBpZiAoaUZpZWxkID49IHQgLT4gblNhbXBsZXMpIHsKICAgICAgICAgICAgaUZpZWxkID0gMDsKICAgICAgICAgICAgaVNldCsrOwoKICAgICAgICB9CgogICAgICAgIGlmIChpdDgtPnN5ICE9IFNFTkRfREFUQSAmJiBpdDgtPnN5ICE9IFNFT0YpIHsKCiAgICAgICAgICAgIGlmICghR2V0VmFsKGl0OCwgQnVmZmVyLCAyNTUsICJTYW1wbGUgZGF0YSBleHBlY3RlZCIpKQogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgICAgICAgICAgaWYgKCFTZXREYXRhKGl0OCwgaVNldCwgaUZpZWxkLCBCdWZmZXIpKQogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgICAgICAgICAgaUZpZWxkKys7CgogICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICBTa2lwRU9MTihpdDgpOwogICAgICAgIH0KICAgIH0KCiAgICBTa2lwRU9MTihpdDgpOwogICAgU2tpcChpdDgsIFNFTkRfREFUQSk7CiAgICBTa2lwRU9MTihpdDgpOwoKICAgIC8vIENoZWNrIGZvciBkYXRhIGNvbXBsZXRpb24uCgogICAgaWYgKChpU2V0KzEpICE9IHQgLT4gblBhdGNoZXMpCiAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIkNvdW50IG1pc21hdGNoLiBOVU1CRVJfT0ZfU0VUUyB3YXMgJWQsIGZvdW5kICVkXG4iLCB0IC0+blBhdGNoZXMsIGlTZXQrMSk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCgoKCnN0YXRpYwpjbXNCb29sIEhlYWRlclNlY3Rpb24oY21zSVQ4KiBpdDgpCnsKICAgIGNoYXIgVmFyTmFtZVtNQVhJRF07CiAgICBjaGFyIEJ1ZmZlcltNQVhTVFJdOwogICAgS0VZVkFMVUUqIEtleTsKCiAgICAgICAgd2hpbGUgKGl0OC0+c3kgIT0gU0VPRiAmJgogICAgICAgICAgICAgICBpdDgtPnN5ICE9IFNTWU5FUlJPUiAmJgogICAgICAgICAgICAgICBpdDgtPnN5ICE9IFNCRUdJTl9EQVRBX0ZPUk1BVCAmJgogICAgICAgICAgICAgICBpdDgtPnN5ICE9IFNCRUdJTl9EQVRBKSB7CgoKICAgICAgICBzd2l0Y2ggKGl0OCAtPiBzeSkgewoKICAgICAgICBjYXNlIFNLRVlXT1JEOgogICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICAgICAgICAgIGlmICghR2V0VmFsKGl0OCwgQnVmZmVyLCBNQVhTVFItMSwgIktleXdvcmQgZXhwZWN0ZWQiKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICAgICAgaWYgKCFBZGRBdmFpbGFibGVQcm9wZXJ0eShpdDgsIEJ1ZmZlciwgV1JJVEVfVU5DT09LRUQpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgYnJlYWs7CgoKICAgICAgICBjYXNlIFNEQVRBX0ZPUk1BVF9JRDoKICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgICAgICBpZiAoIUdldFZhbChpdDgsIEJ1ZmZlciwgTUFYU1RSLTEsICJLZXl3b3JkIGV4cGVjdGVkIikpIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgICAgIGlmICghQWRkQXZhaWxhYmxlU2FtcGxlSUQoaXQ4LCBCdWZmZXIpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgYnJlYWs7CgoKICAgICAgICBjYXNlIFNJREVOVDoKICAgICAgICAgICAgICAgIHN0cm5jcHkoVmFyTmFtZSwgaXQ4LT5pZCwgTUFYSUQtMSk7CiAgICAgICAgICAgICAgICBWYXJOYW1lW01BWElELTFdID0gMDsKCiAgICAgICAgICAgICAgICBpZiAoIUlzQXZhaWxhYmxlT25MaXN0KGl0OC0+IFZhbGlkS2V5d29yZHMsIFZhck5hbWUsIE5VTEwsICZLZXkpKSB7CgojaWZkZWYgQ01TX1NUUklDVF9DR0FUUwogICAgICAgICAgICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsICJVbmRlZmluZWQga2V5d29yZCAnJXMnIiwgVmFyTmFtZSk7CiNlbHNlCiAgICAgICAgICAgICAgICAgICAgS2V5ID0gQWRkQXZhaWxhYmxlUHJvcGVydHkoaXQ4LCBWYXJOYW1lLCBXUklURV9VTkNPT0tFRCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKEtleSA9PSBOVUxMKSByZXR1cm4gRkFMU0U7CiNlbmRpZgogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgICAgICBpZiAoIUdldFZhbChpdDgsIEJ1ZmZlciwgTUFYU1RSLTEsICJQcm9wZXJ0eSBkYXRhIGV4cGVjdGVkIikpIHJldHVybiBGQUxTRTsKCiAgICAgICAgICAgICAgICBpZihLZXktPldyaXRlQXMgIT0gV1JJVEVfUEFJUikgewogICAgICAgICAgICAgICAgICAgIEFkZFRvTGlzdChpdDgsICZHZXRUYWJsZShpdDgpLT5IZWFkZXJMaXN0LCBWYXJOYW1lLCBOVUxMLCBCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGl0OC0+c3kgPT0gU1NUUklORykgPyBXUklURV9TVFJJTkdJRlkgOiBXUklURV9VTkNPT0tFRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpTdWJrZXk7CiAgICAgICAgICAgICAgICAgICAgY2hhciAqTmV4dGtleTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXQ4LT5zeSAhPSBTU1RSSU5HKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiSW52YWxpZCB2YWx1ZSAnJXMnIGZvciBwcm9wZXJ0eSAnJXMnLiIsIEJ1ZmZlciwgVmFyTmFtZSk7CgogICAgICAgICAgICAgICAgICAgIC8vIGNob3AgdGhlIHN0cmluZyBhcyBhIGxpc3Qgb2YgInN1YmtleSwgdmFsdWUiIHBhaXJzLCB1c2luZyAnOycgYXMgYSBzZXBhcmF0b3IKICAgICAgICAgICAgICAgICAgICBmb3IgKFN1YmtleSA9IEJ1ZmZlcjsgU3Via2V5ICE9IE5VTEw7IFN1YmtleSA9IE5leHRrZXkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjaGFyICpWYWx1ZSwgKnRlbXA7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyAgaWRlbnRpZnkgdG9rZW4gcGFpciBib3VuZGFyeQogICAgICAgICAgICAgICAgICAgICAgICBOZXh0a2V5ID0gKGNoYXIqKSBzdHJjaHIoU3Via2V5LCAnOycpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihOZXh0a2V5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKk5leHRrZXkrKyA9ICdcMCc7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgZWFjaCBwYWlyLCBzcGxpdCB0aGUgc3Via2V5IGFuZCB0aGUgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgPSAoY2hhciopIHN0cnJjaHIoU3Via2V5LCAnLCcpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihWYWx1ZSA9PSBOVUxMKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIkludmFsaWQgdmFsdWUgZm9yIHByb3BlcnR5ICclcycuIiwgVmFyTmFtZSk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBnb2JibGUgdGhlIHNwYWNlcyBiZWZvcmUgdGhlIGNvbWEsIGFuZCB0aGUgY29tYSBpdHNlbGYKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IFZhbHVlKys7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvICp0ZW1wLS0gPSAnXDAnOyB3aGlsZSh0ZW1wID49IFN1YmtleSAmJiAqdGVtcCA9PSAnICcpOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ29iYmxlIGFueSBzcGFjZSBhdCB0aGUgcmlnaHQKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IFZhbHVlICsgc3RybGVuKFZhbHVlKSAtIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKCp0ZW1wID09ICcgJykgKnRlbXAtLSA9ICdcMCc7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyB0cmltIHRoZSBzdHJpbmdzIGZyb20gdGhlIGxlZnQKICAgICAgICAgICAgICAgICAgICAgICAgU3Via2V5ICs9IHN0cnNwbihTdWJrZXksICIgIik7CiAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlICs9IHN0cnNwbihWYWx1ZSwgIiAiKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKFN1YmtleVswXSA9PSAwIHx8IFZhbHVlWzBdID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiSW52YWxpZCB2YWx1ZSBmb3IgcHJvcGVydHkgJyVzJy4iLCBWYXJOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgQWRkVG9MaXN0KGl0OCwgJkdldFRhYmxlKGl0OCktPkhlYWRlckxpc3QsIFZhck5hbWUsIFN1YmtleSwgVmFsdWUsIFdSSVRFX1BBSVIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgYnJlYWs7CgoKICAgICAgICBjYXNlIFNFT0xOOiBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsICJleHBlY3RlZCBrZXl3b3JkIG9yIGlkZW50aWZpZXIiKTsKICAgICAgICB9CgogICAgU2tpcEVPTE4oaXQ4KTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKCn0KCgpzdGF0aWMKdm9pZCBSZWFkVHlwZShjbXNJVDgqIGl0OCwgY2hhciogU2hlZXRUeXBlUHRyKQp7CiAgICAvLyBGaXJzdCBsaW5lIGlzIGEgdmVyeSBzcGVjaWFsIGNhc2UuCgogICAgd2hpbGUgKGlzc2VwYXJhdG9yKGl0OC0+Y2gpKQogICAgICAgICAgICBOZXh0Q2goaXQ4KTsKCiAgICB3aGlsZSAoaXQ4LT5jaCAhPSAnXHInICYmIGl0OCAtPmNoICE9ICdcbicgJiYgaXQ4LT5jaCAhPSAnXHQnICYmIGl0OCAtPiBjaCAhPSAtMSkgewoKICAgICAgICAqU2hlZXRUeXBlUHRyKys9IChjaGFyKSBpdDggLT5jaDsKICAgICAgICBOZXh0Q2goaXQ4KTsKICAgIH0KCiAgICAqU2hlZXRUeXBlUHRyID0gMDsKfQoKCnN0YXRpYwpjbXNCb29sIFBhcnNlSVQ4KGNtc0lUOCogaXQ4LCBjbXNCb29sIG5vc2hlZXQpCnsKICAgIGNoYXIqIFNoZWV0VHlwZVB0ciA9IGl0OCAtPlRhYlswXS5TaGVldFR5cGU7CgogICAgaWYgKG5vc2hlZXQgPT0gMCkgewogICAgICAgIFJlYWRUeXBlKGl0OCwgU2hlZXRUeXBlUHRyKTsKICAgIH0KCiAgICBJblN5bWJvbChpdDgpOwoKICAgIFNraXBFT0xOKGl0OCk7CgogICAgd2hpbGUgKGl0OC0+IHN5ICE9IFNFT0YgJiYKICAgICAgICAgICBpdDgtPiBzeSAhPSBTU1lORVJST1IpIHsKCiAgICAgICAgICAgIHN3aXRjaCAoaXQ4IC0+IHN5KSB7CgogICAgICAgICAgICBjYXNlIFNCRUdJTl9EQVRBX0ZPUk1BVDoKICAgICAgICAgICAgICAgICAgICBpZiAoIURhdGFGb3JtYXRTZWN0aW9uKGl0OCkpIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU0JFR0lOX0RBVEE6CgogICAgICAgICAgICAgICAgICAgIGlmICghRGF0YVNlY3Rpb24oaXQ4KSkgcmV0dXJuIEZBTFNFOwoKICAgICAgICAgICAgICAgICAgICBpZiAoaXQ4IC0+IHN5ICE9IFNFT0YpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbGxvY1RhYmxlKGl0OCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdDggLT5uVGFibGUgPSBpdDggLT5UYWJsZXNDb3VudCAtIDE7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVhZCBzaGVldCB0eXBlIGlmIHByZXNlbnQuIFdlIG9ubHkgc3VwcG9ydCBpZGVudGlmaWVyIGFuZCBzdHJpbmcuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8aWRlbnQ+IDxlb2xuPiBpcyBhIHR5cGUgc3RyaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbnl0aGluZyBlbHNlLCBpcyBub3QgYSB0eXBlIHN0cmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vc2hlZXQgPT0gMCkgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXQ4IC0+c3kgPT0gU0lERU5UKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNYXkgYmUgYSB0eXBlIHNoZWV0IG9yIG1heSBiZSBhIHByb3AgdmFsdWUgc3RhdGVtZW50LiBXZSBjYW5ub3QgdXNlIGluc3ltYm9sIGluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgc3BlY2lhbCBjYXNlLi4uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaXNzZXBhcmF0b3IoaXQ4LT5jaCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgYSBuZXdsaW5lIGlzIGZvdW5kLCB0aGVuIHRoaXMgaXMgYSB0eXBlIHN0cmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXQ4IC0+Y2ggPT0gJ1xuJyB8fCBpdDgtPmNoID09ICdccicpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zSVQ4U2V0U2hlZXRUeXBlKGl0OCwgaXQ4IC0+aWQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJdCBpcyBub3QuIEp1c3QgY29udGludWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc0lUOFNldFNoZWV0VHlwZShpdDgsICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZhbGlkYXRlIHF1b3RlZCBzdHJpbmdzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdDggLT5zeSA9PSBTU1RSSU5HKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNJVDhTZXRTaGVldFR5cGUoaXQ4LCBpdDggLT5zdHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU0VPTE46CiAgICAgICAgICAgICAgICAgICAgU2tpcEVPTE4oaXQ4KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKCFIZWFkZXJTZWN0aW9uKGl0OCkpIHJldHVybiBGQUxTRTsKICAgICAgICAgICB9CgogICAgfQoKICAgIHJldHVybiAoaXQ4IC0+IHN5ICE9IFNTWU5FUlJPUik7Cn0KCgoKLy8gSW5pdCB1c2VmdWxsIHBvaW50ZXJzCgpzdGF0aWMKdm9pZCBDb29rUG9pbnRlcnMoY21zSVQ4KiBpdDgpCnsKICAgIGludCBpZEZpZWxkLCBpOwogICAgY2hhciogRmxkOwogICAgY21zVUludDMyTnVtYmVyIGo7CiAgICBjbXNVSW50MzJOdW1iZXIgbk9sZFRhYmxlID0gaXQ4IC0+blRhYmxlOwoKICAgIGZvciAoaj0wOyBqIDwgaXQ4IC0+VGFibGVzQ291bnQ7IGorKykgewoKICAgIFRBQkxFKiB0ID0gaXQ4IC0+VGFiICsgajsKCiAgICB0IC0+IFNhbXBsZUlEID0gMDsKICAgIGl0OCAtPm5UYWJsZSA9IGo7CgogICAgZm9yIChpZEZpZWxkID0gMDsgaWRGaWVsZCA8IHQgLT4gblNhbXBsZXM7IGlkRmllbGQrKykKICAgIHsKICAgICAgICBpZiAodCAtPkRhdGFGb3JtYXQgPT0gTlVMTCl7CiAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIlVuZGVmaW5lZCBEQVRBX0ZPUk1BVCIpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBGbGQgPSB0LT5EYXRhRm9ybWF0W2lkRmllbGRdOwogICAgICAgIGlmICghRmxkKSBjb250aW51ZTsKCgogICAgICAgIGlmIChjbXNzdHJjYXNlY21wKEZsZCwgIlNBTVBMRV9JRCIpID09IDApIHsKCiAgICAgICAgICAgIHQgLT4gU2FtcGxlSUQgPSBpZEZpZWxkOwoKICAgICAgICAgICAgZm9yIChpPTA7IGkgPCB0IC0+IG5QYXRjaGVzOyBpKyspIHsKCiAgICAgICAgICAgICAgICBjaGFyICpEYXRhID0gR2V0RGF0YShpdDgsIGksIGlkRmllbGQpOwogICAgICAgICAgICAgICAgaWYgKERhdGEpIHsKICAgICAgICAgICAgICAgICAgICBjaGFyIEJ1ZmZlclsyNTZdOwoKICAgICAgICAgICAgICAgICAgICBzdHJuY3B5KEJ1ZmZlciwgRGF0YSwgMjU1KTsKICAgICAgICAgICAgICAgICAgICBCdWZmZXJbMjU1XSA9IDA7CgogICAgICAgICAgICAgICAgICAgIGlmIChzdHJsZW4oQnVmZmVyKSA8PSBzdHJsZW4oRGF0YSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmNweShEYXRhLCBCdWZmZXIpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgU2V0RGF0YShpdDgsIGksIGlkRmllbGQsIEJ1ZmZlcik7CgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgIH0KCiAgICAgICAgLy8gIkxBQkVMIiBpcyBhbiBleHRlbnNpb24uIEl0IGtlZXBzIHJlZmVyZW5jZXMgdG8gZm9yd2FyZCB0YWJsZXMKCiAgICAgICAgaWYgKChjbXNzdHJjYXNlY21wKEZsZCwgIkxBQkVMIikgPT0gMCkgfHwgRmxkWzBdID09ICckJyApIHsKCiAgICAgICAgICAgICAgICAgICAgLy8gU2VhcmNoIGZvciB0YWJsZSByZWZlcmVuY2VzLi4uCiAgICAgICAgICAgICAgICAgICAgZm9yIChpPTA7IGkgPCB0IC0+IG5QYXRjaGVzOyBpKyspIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICpMYWJlbCA9IEdldERhdGEoaXQ4LCBpLCBpZEZpZWxkKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoTGFiZWwpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIGs7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGxhYmVsLCBzZWFyY2ggZm9yIGEgdGFibGUgY29udGFpbmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgcHJvcGVydHkKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrPTA7IGsgPCBpdDggLT5UYWJsZXNDb3VudDsgaysrKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUQUJMRSogVGFibGUgPSBpdDggLT5UYWIgKyBrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlWQUxVRSogcDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChJc0F2YWlsYWJsZU9uTGlzdChUYWJsZS0+SGVhZGVyTGlzdCwgTGFiZWwsIE5VTEwsICZwKSkgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF2YWlsYWJsZSwga2VlcCB0eXBlIGFuZCB0YWJsZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciBCdWZmZXJbMjU2XTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICpUeXBlICA9IHAgLT5WYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAgblRhYmxlID0gKGludCkgazsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbnByaW50ZihCdWZmZXIsIDI1NSwgIiVzICVkICVzIiwgTGFiZWwsIG5UYWJsZSwgVHlwZSApOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldERhdGEoaXQ4LCBpLCBpZEZpZWxkLCBCdWZmZXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIH0KCgogICAgICAgIH0KCiAgICB9CiAgICB9CgogICAgaXQ4IC0+blRhYmxlID0gbk9sZFRhYmxlOwp9CgovLyBUcnkgdG8gaW5mZXJlIGlmIHRoZSBmaWxlIGlzIGEgQ0dBVFMvSVQ4IGZpbGUgYXQgYWxsLiBSZWFkIGZpcnN0IGxpbmUKLy8gdGhhdCBzaG91bGQgYmUgc29tZXRoaW5nIGxpa2Ugc29tZSBwcmludGFibGUgY2hhcmFjdGVycyBwbHVzIGEgXG4KLy8gcmV0dXJucyAwIGlmIHRoaXMgaXMgbm90IGxpa2UgYSBDR0FUUywgb3IgYW4gaW50ZWdlciBvdGhlcndpc2UuIFRoaXMgaW50ZWdlciBpcyB0aGUgbnVtYmVyIG9mIHdvcmRzIGluIGZpcnN0IGxpbmU/CnN0YXRpYwppbnQgSXNNeUJsb2NrKGNtc1VJbnQ4TnVtYmVyKiBCdWZmZXIsIGludCBuKQp7CiAgICBpbnQgd29yZHMgPSAxLCBzcGFjZSA9IDAsIHF1b3QgPSAwOwogICAgaW50IGk7CgogICAgaWYgKG4gPCAxMCkgcmV0dXJuIDA7ICAgLy8gVG9vIHNtYWxsCgogICAgaWYgKG4gPiAxMzIpCiAgICAgICAgbiA9IDEzMjsKCiAgICBmb3IgKGkgPSAxOyBpIDwgbjsgaSsrKSB7CgogICAgICAgIHN3aXRjaChCdWZmZXJbaV0pCiAgICAgICAgewogICAgICAgIGNhc2UgJ1xuJzoKICAgICAgICBjYXNlICdccic6CiAgICAgICAgICAgIHJldHVybiAoKHF1b3QgPT0gMSkgfHwgKHdvcmRzID4gMikpID8gMCA6IHdvcmRzOwogICAgICAgIGNhc2UgJ1x0JzoKICAgICAgICBjYXNlICcgJzoKICAgICAgICAgICAgaWYoIXF1b3QgJiYgIXNwYWNlKQogICAgICAgICAgICAgICAgc3BhY2UgPSAxOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdcIic6CiAgICAgICAgICAgIHF1b3QgPSAhcXVvdDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaWYgKEJ1ZmZlcltpXSA8IDMyKSByZXR1cm4gMDsKICAgICAgICAgICAgaWYgKEJ1ZmZlcltpXSA+IDEyNykgcmV0dXJuIDA7CiAgICAgICAgICAgIHdvcmRzICs9IHNwYWNlOwogICAgICAgICAgICBzcGFjZSA9IDA7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gMDsKfQoKCnN0YXRpYwpjbXNCb29sIElzTXlGaWxlKGNvbnN0IGNoYXIqIEZpbGVOYW1lKQp7CiAgIEZJTEUgKmZwOwogICBjbXNVSW50MzJOdW1iZXIgU2l6ZTsKICAgY21zVUludDhOdW1iZXIgUHRyWzEzM107CgogICBmcCA9IGZvcGVuKEZpbGVOYW1lLCAicnQiKTsKICAgaWYgKCFmcCkgewogICAgICAgY21zU2lnbmFsRXJyb3IoMCwgY21zRVJST1JfRklMRSwgIkZpbGUgJyVzJyBub3QgZm91bmQiLCBGaWxlTmFtZSk7CiAgICAgICByZXR1cm4gRkFMU0U7CiAgIH0KCiAgIFNpemUgPSAoY21zVUludDMyTnVtYmVyKSBmcmVhZChQdHIsIDEsIDEzMiwgZnApOwoKICAgaWYgKGZjbG9zZShmcCkgIT0gMCkKICAgICAgIHJldHVybiBGQUxTRTsKCiAgIFB0cltTaXplXSA9ICdcMCc7CgogICByZXR1cm4gSXNNeUJsb2NrKFB0ciwgU2l6ZSk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRXhwb3J0ZWQgcm91dGluZXMKCgpjbXNIQU5ETEUgIENNU0VYUE9SVCBjbXNJVDhMb2FkRnJvbU1lbShjbXNDb250ZXh0IENvbnRleHRJRCwgdm9pZCAqUHRyLCBjbXNVSW50MzJOdW1iZXIgbGVuKQp7CiAgICBjbXNIQU5ETEUgaElUODsKICAgIGNtc0lUOCogIGl0ODsKICAgIGludCB0eXBlOwoKICAgIF9jbXNBc3NlcnQoUHRyICE9IE5VTEwpOwogICAgX2Ntc0Fzc2VydChsZW4gIT0gMCk7CgogICAgdHlwZSA9IElzTXlCbG9jaygoY21zVUludDhOdW1iZXIqKVB0ciwgbGVuKTsKICAgIGlmICh0eXBlID09IDApIHJldHVybiBOVUxMOwoKICAgIGhJVDggPSBjbXNJVDhBbGxvYyhDb250ZXh0SUQpOwogICAgaWYgKCFoSVQ4KSByZXR1cm4gTlVMTDsKCiAgICBpdDggPSAoY21zSVQ4KikgaElUODsKICAgIGl0OCAtPk1lbW9yeUJsb2NrID0gKGNoYXIqKSBfY21zTWFsbG9jKENvbnRleHRJRCwgbGVuICsgMSk7CgogICAgc3RybmNweShpdDggLT5NZW1vcnlCbG9jaywgKGNvbnN0IGNoYXIqKSBQdHIsIGxlbik7CiAgICBpdDggLT5NZW1vcnlCbG9ja1tsZW5dID0gMDsKCiAgICBzdHJuY3B5KGl0OC0+RmlsZVN0YWNrWzBdLT5GaWxlTmFtZSwgIiIsIGNtc01BWF9QQVRILTEpOwogICAgaXQ4LT4gU291cmNlID0gaXQ4IC0+IE1lbW9yeUJsb2NrOwoKICAgIGlmICghUGFyc2VJVDgoaXQ4LCB0eXBlLTEpKSB7CgogICAgICAgIGNtc0lUOEZyZWUoaElUOCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIENvb2tQb2ludGVycyhpdDgpOwogICAgaXQ4IC0+blRhYmxlID0gMDsKCiAgICBfY21zRnJlZShDb250ZXh0SUQsIGl0OC0+TWVtb3J5QmxvY2spOwogICAgaXQ4IC0+IE1lbW9yeUJsb2NrID0gTlVMTDsKCiAgICByZXR1cm4gaElUODsKCgp9CgoKY21zSEFORExFICBDTVNFWFBPUlQgY21zSVQ4TG9hZEZyb21GaWxlKGNtc0NvbnRleHQgQ29udGV4dElELCBjb25zdCBjaGFyKiBjRmlsZU5hbWUpCnsKCiAgICAgY21zSEFORExFIGhJVDg7CiAgICAgY21zSVQ4KiAgaXQ4OwogICAgIGludCB0eXBlOwoKICAgICBfY21zQXNzZXJ0KGNGaWxlTmFtZSAhPSBOVUxMKTsKCiAgICAgdHlwZSA9IElzTXlGaWxlKGNGaWxlTmFtZSk7CiAgICAgaWYgKHR5cGUgPT0gMCkgcmV0dXJuIE5VTEw7CgogICAgIGhJVDggPSBjbXNJVDhBbGxvYyhDb250ZXh0SUQpOwogICAgIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwogICAgIGlmICghaElUOCkgcmV0dXJuIE5VTEw7CgoKICAgICBpdDggLT5GaWxlU3RhY2tbMF0tPlN0cmVhbSA9IGZvcGVuKGNGaWxlTmFtZSwgInJ0Iik7CgogICAgIGlmICghaXQ4IC0+RmlsZVN0YWNrWzBdLT5TdHJlYW0pIHsKICAgICAgICAgY21zSVQ4RnJlZShoSVQ4KTsKICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgfQoKCiAgICBzdHJuY3B5KGl0OC0+RmlsZVN0YWNrWzBdLT5GaWxlTmFtZSwgY0ZpbGVOYW1lLCBjbXNNQVhfUEFUSC0xKTsKICAgIGl0OC0+RmlsZVN0YWNrWzBdLT5GaWxlTmFtZVtjbXNNQVhfUEFUSC0xXSA9IDA7CgogICAgaWYgKCFQYXJzZUlUOChpdDgsIHR5cGUtMSkpIHsKCiAgICAgICAgICAgIGZjbG9zZShpdDggLT5GaWxlU3RhY2tbMF0tPlN0cmVhbSk7CiAgICAgICAgICAgIGNtc0lUOEZyZWUoaElUOCk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIENvb2tQb2ludGVycyhpdDgpOwogICAgaXQ4IC0+blRhYmxlID0gMDsKCiAgICBpZiAoZmNsb3NlKGl0OCAtPkZpbGVTdGFja1swXS0+U3RyZWFtKSE9IDApIHsKICAgICAgICAgICAgY21zSVQ4RnJlZShoSVQ4KTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIGhJVDg7Cgp9CgppbnQgQ01TRVhQT1JUIGNtc0lUOEVudW1EYXRhRm9ybWF0KGNtc0hBTkRMRSBoSVQ4LCBjaGFyICoqKlNhbXBsZU5hbWVzKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwogICAgVEFCTEUqIHQ7CgogICAgX2Ntc0Fzc2VydChoSVQ4ICE9IE5VTEwpOwoKICAgIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGlmIChTYW1wbGVOYW1lcykKICAgICAgICAqU2FtcGxlTmFtZXMgPSB0IC0+IERhdGFGb3JtYXQ7CiAgICByZXR1cm4gdCAtPiBuU2FtcGxlczsKfQoKCmNtc1VJbnQzMk51bWJlciBDTVNFWFBPUlQgY21zSVQ4RW51bVByb3BlcnRpZXMoY21zSEFORExFIGhJVDgsIGNoYXIgKioqUHJvcGVydHlOYW1lcykKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKICAgIEtFWVZBTFVFKiBwOwogICAgY21zVUludDMyTnVtYmVyIG47CiAgICBjaGFyICoqUHJvcHM7CiAgICBUQUJMRSogdDsKCiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgdCA9IEdldFRhYmxlKGl0OCk7CgogICAgLy8gUGFzcyMxIC0gY291bnQgcHJvcGVydGllcwoKICAgIG4gPSAwOwogICAgZm9yIChwID0gdCAtPiBIZWFkZXJMaXN0OyAgcCAhPSBOVUxMOyBwID0gcC0+TmV4dCkgewogICAgICAgIG4rKzsKICAgIH0KCgogICAgUHJvcHMgPSAoY2hhciAqKikgQWxsb2NDaHVuayhpdDgsIHNpemVvZihjaGFyICopICogbik7CgogICAgLy8gUGFzcyMyIC0gRmlsbCBwb2ludGVycwogICAgbiA9IDA7CiAgICBmb3IgKHAgPSB0IC0+IEhlYWRlckxpc3Q7ICBwICE9IE5VTEw7IHAgPSBwLT5OZXh0KSB7CiAgICAgICAgUHJvcHNbbisrXSA9IHAgLT4gS2V5d29yZDsKICAgIH0KCiAgICAqUHJvcGVydHlOYW1lcyA9IFByb3BzOwogICAgcmV0dXJuIG47Cn0KCmNtc1VJbnQzMk51bWJlciBDTVNFWFBPUlQgY21zSVQ4RW51bVByb3BlcnR5TXVsdGkoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNQcm9wLCBjb25zdCBjaGFyICoqKlN1YnByb3BlcnR5TmFtZXMpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CiAgICBLRVlWQUxVRSAqcCwgKnRtcDsKICAgIGNtc1VJbnQzMk51bWJlciBuOwogICAgY29uc3QgY2hhciAqKlByb3BzOwogICAgVEFCTEUqIHQ7CgogICAgX2Ntc0Fzc2VydChoSVQ4ICE9IE5VTEwpOwoKCiAgICB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBpZighSXNBdmFpbGFibGVPbkxpc3QodC0+SGVhZGVyTGlzdCwgY1Byb3AsIE5VTEwsICZwKSkgewogICAgICAgICpTdWJwcm9wZXJ0eU5hbWVzID0gMDsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvLyBQYXNzIzEgLSBjb3VudCBwcm9wZXJ0aWVzCgogICAgbiA9IDA7CiAgICBmb3IgKHRtcCA9IHA7ICB0bXAgIT0gTlVMTDsgdG1wID0gdG1wLT5OZXh0U3Via2V5KSB7CiAgICAgICAgaWYodG1wLT5TdWJrZXkgIT0gTlVMTCkKICAgICAgICAgICAgbisrOwogICAgfQoKCiAgICBQcm9wcyA9IChjb25zdCBjaGFyICoqKSBBbGxvY0NodW5rKGl0OCwgc2l6ZW9mKGNoYXIgKikgKiBuKTsKCiAgICAvLyBQYXNzIzIgLSBGaWxsIHBvaW50ZXJzCiAgICBuID0gMDsKICAgIGZvciAodG1wID0gcDsgIHRtcCAhPSBOVUxMOyB0bXAgPSB0bXAtPk5leHRTdWJrZXkpIHsKICAgICAgICBpZih0bXAtPlN1YmtleSAhPSBOVUxMKQogICAgICAgICAgICBQcm9wc1tuKytdID0gcCAtPlN1YmtleTsKICAgIH0KCiAgICAqU3VicHJvcGVydHlOYW1lcyA9IFByb3BzOwogICAgcmV0dXJuIG47Cn0KCnN0YXRpYwppbnQgTG9jYXRlUGF0Y2goY21zSVQ4KiBpdDgsIGNvbnN0IGNoYXIqIGNQYXRjaCkKewogICAgaW50IGk7CiAgICBjb25zdCBjaGFyICpkYXRhOwogICAgVEFCTEUqIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGZvciAoaT0wOyBpIDwgdC0+IG5QYXRjaGVzOyBpKyspIHsKCiAgICAgICAgZGF0YSA9IEdldERhdGEoaXQ4LCBpLCB0LT5TYW1wbGVJRCk7CgogICAgICAgIGlmIChkYXRhICE9IE5VTEwpIHsKCiAgICAgICAgICAgICAgICBpZiAoY21zc3RyY2FzZWNtcChkYXRhLCBjUGF0Y2gpID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gU3luRXJyb3IoaXQ4LCAiQ291bGRuJ3QgZmluZCBwYXRjaCAnJXMnXG4iLCBjUGF0Y2gpOwogICAgICAgIHJldHVybiAtMTsKfQoKCnN0YXRpYwppbnQgTG9jYXRlRW1wdHlQYXRjaChjbXNJVDgqIGl0OCkKewogICAgaW50IGk7CiAgICBjb25zdCBjaGFyICpkYXRhOwogICAgVEFCTEUqIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGZvciAoaT0wOyBpIDwgdC0+IG5QYXRjaGVzOyBpKyspIHsKCiAgICAgICAgZGF0YSA9IEdldERhdGEoaXQ4LCBpLCB0LT5TYW1wbGVJRCk7CgogICAgICAgIGlmIChkYXRhID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiBpOwoKICAgIH0KCiAgICByZXR1cm4gLTE7Cn0KCnN0YXRpYwppbnQgTG9jYXRlU2FtcGxlKGNtc0lUOCogaXQ4LCBjb25zdCBjaGFyKiBjU2FtcGxlKQp7CiAgICBpbnQgaTsKICAgIGNvbnN0IGNoYXIgKmZsZDsKICAgIFRBQkxFKiB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBmb3IgKGk9MDsgaSA8IHQtPm5TYW1wbGVzOyBpKyspIHsKCiAgICAgICAgZmxkID0gR2V0RGF0YUZvcm1hdChpdDgsIGkpOwogICAgICAgIGlmIChmbGQgIT0gTlVMTCkgewogICAgICAgIGlmIChjbXNzdHJjYXNlY21wKGZsZCwgY1NhbXBsZSkgPT0gMCkKICAgICAgICAgICAgcmV0dXJuIGk7CiAgICB9CiAgICB9CgogICAgcmV0dXJuIC0xOwoKfQoKCmludCBDTVNFWFBPUlQgY21zSVQ4RmluZERhdGFGb3JtYXQoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNTYW1wbGUpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CgogICAgX2Ntc0Fzc2VydChoSVQ4ICE9IE5VTEwpOwoKICAgIHJldHVybiBMb2NhdGVTYW1wbGUoaXQ4LCBjU2FtcGxlKTsKfQoKCgpjb25zdCBjaGFyKiBDTVNFWFBPUlQgY21zSVQ4R2V0RGF0YVJvd0NvbChjbXNIQU5ETEUgaElUOCwgaW50IHJvdywgaW50IGNvbCkKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKCiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgcmV0dXJuIEdldERhdGEoaXQ4LCByb3csIGNvbCk7Cn0KCgpjbXNGbG9hdDY0TnVtYmVyIENNU0VYUE9SVCBjbXNJVDhHZXREYXRhUm93Q29sRGJsKGNtc0hBTkRMRSBoSVQ4LCBpbnQgcm93LCBpbnQgY29sKQp7CiAgICBjb25zdCBjaGFyKiBCdWZmZXI7CgogICAgQnVmZmVyID0gY21zSVQ4R2V0RGF0YVJvd0NvbChoSVQ4LCByb3csIGNvbCk7CgogICAgaWYgKEJ1ZmZlciA9PSBOVUxMKSByZXR1cm4gMC4wOwoKICAgIHJldHVybiBQYXJzZUZsb2F0TnVtYmVyKEJ1ZmZlcik7Cn0KCgpjbXNCb29sIENNU0VYUE9SVCBjbXNJVDhTZXREYXRhUm93Q29sKGNtc0hBTkRMRSBoSVQ4LCBpbnQgcm93LCBpbnQgY29sLCBjb25zdCBjaGFyKiBWYWwpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CgogICAgX2Ntc0Fzc2VydChoSVQ4ICE9IE5VTEwpOwoKICAgIHJldHVybiBTZXREYXRhKGl0OCwgcm93LCBjb2wsIFZhbCk7Cn0KCgpjbXNCb29sIENNU0VYUE9SVCBjbXNJVDhTZXREYXRhUm93Q29sRGJsKGNtc0hBTkRMRSBoSVQ4LCBpbnQgcm93LCBpbnQgY29sLCBjbXNGbG9hdDY0TnVtYmVyIFZhbCkKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKICAgIGNoYXIgQnVmZlsyNTZdOwoKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCiAgICBzcHJpbnRmKEJ1ZmYsIGl0OC0+RG91YmxlRm9ybWF0dGVyLCBWYWwpOwoKICAgIHJldHVybiBTZXREYXRhKGl0OCwgcm93LCBjb2wsIEJ1ZmYpOwp9CgoKCmNvbnN0IGNoYXIqIENNU0VYUE9SVCBjbXNJVDhHZXREYXRhKGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUGF0Y2gsIGNvbnN0IGNoYXIqIGNTYW1wbGUpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CiAgICBpbnQgaUZpZWxkLCBpU2V0OwoKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCiAgICBpRmllbGQgPSBMb2NhdGVTYW1wbGUoaXQ4LCBjU2FtcGxlKTsKICAgIGlmIChpRmllbGQgPCAwKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaVNldCA9IExvY2F0ZVBhdGNoKGl0OCwgY1BhdGNoKTsKICAgIGlmIChpU2V0IDwgMCkgewogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gR2V0RGF0YShpdDgsIGlTZXQsIGlGaWVsZCk7Cn0KCgpjbXNGbG9hdDY0TnVtYmVyIENNU0VYUE9SVCBjbXNJVDhHZXREYXRhRGJsKGNtc0hBTkRMRSAgaXQ4LCBjb25zdCBjaGFyKiBjUGF0Y2gsIGNvbnN0IGNoYXIqIGNTYW1wbGUpCnsKICAgIGNvbnN0IGNoYXIqIEJ1ZmZlcjsKCiAgICBCdWZmZXIgPSBjbXNJVDhHZXREYXRhKGl0OCwgY1BhdGNoLCBjU2FtcGxlKTsKCiAgICByZXR1cm4gUGFyc2VGbG9hdE51bWJlcihCdWZmZXIpOwp9CgoKCmNtc0Jvb2wgQ01TRVhQT1JUIGNtc0lUOFNldERhdGEoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNQYXRjaCwgY29uc3QgY2hhciogY1NhbXBsZSwgY29uc3QgY2hhciAqVmFsKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwogICAgaW50IGlGaWVsZCwgaVNldDsKICAgIFRBQkxFKiB0OwoKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCiAgICB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBpRmllbGQgPSBMb2NhdGVTYW1wbGUoaXQ4LCBjU2FtcGxlKTsKCiAgICBpZiAoaUZpZWxkIDwgMCkKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKHQtPiBuUGF0Y2hlcyA9PSAwKSB7CgogICAgICAgIEFsbG9jYXRlRGF0YUZvcm1hdChpdDgpOwogICAgICAgIEFsbG9jYXRlRGF0YVNldChpdDgpOwogICAgICAgIENvb2tQb2ludGVycyhpdDgpOwogICAgfQoKICAgIGlmIChjbXNzdHJjYXNlY21wKGNTYW1wbGUsICJTQU1QTEVfSUQiKSA9PSAwKSB7CgogICAgICAgIGlTZXQgICA9IExvY2F0ZUVtcHR5UGF0Y2goaXQ4KTsKICAgICAgICBpZiAoaVNldCA8IDApIHsKICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIkNvdWxkbid0IGFkZCBtb3JlIHBhdGNoZXMgJyVzJ1xuIiwgY1BhdGNoKTsKICAgICAgICB9CgogICAgICAgIGlGaWVsZCA9IHQgLT4gU2FtcGxlSUQ7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBpU2V0ID0gTG9jYXRlUGF0Y2goaXQ4LCBjUGF0Y2gpOwogICAgICAgIGlmIChpU2V0IDwgMCkgewogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBTZXREYXRhKGl0OCwgaVNldCwgaUZpZWxkLCBWYWwpOwp9CgoKY21zQm9vbCBDTVNFWFBPUlQgY21zSVQ4U2V0RGF0YURibChjbXNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1BhdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGNTYW1wbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zRmxvYXQ2NE51bWJlciBWYWwpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CiAgICBjaGFyIEJ1ZmZbMjU2XTsKCiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgc25wcmludGYoQnVmZiwgMjU1LCBpdDgtPkRvdWJsZUZvcm1hdHRlciwgVmFsKTsKICAgIHJldHVybiBjbXNJVDhTZXREYXRhKGhJVDgsIGNQYXRjaCwgY1NhbXBsZSwgQnVmZik7Cn0KCi8vIEJ1ZmZlciBzaG91bGQgZ2V0IE1BWFNUUiBhdCBsZWFzdAoKY29uc3QgY2hhciogQ01TRVhQT1JUIGNtc0lUOEdldFBhdGNoTmFtZShjbXNIQU5ETEUgaElUOCwgaW50IG5QYXRjaCwgY2hhciogYnVmZmVyKQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwogICAgVEFCTEUqIHQ7CiAgICBjaGFyKiBEYXRhOwoKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCiAgICB0ID0gR2V0VGFibGUoaXQ4KTsKICAgIERhdGEgPSBHZXREYXRhKGl0OCwgblBhdGNoLCB0LT5TYW1wbGVJRCk7CgogICAgaWYgKCFEYXRhKSByZXR1cm4gTlVMTDsKICAgIGlmICghYnVmZmVyKSByZXR1cm4gRGF0YTsKCiAgICBzdHJuY3B5KGJ1ZmZlciwgRGF0YSwgTUFYU1RSLTEpOwogICAgYnVmZmVyW01BWFNUUi0xXSA9IDA7CiAgICByZXR1cm4gYnVmZmVyOwp9CgppbnQgQ01TRVhQT1JUIGNtc0lUOEdldFBhdGNoQnlOYW1lKGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyICpjUGF0Y2gpCnsKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCiAgICByZXR1cm4gTG9jYXRlUGF0Y2goKGNtc0lUOCopaElUOCwgY1BhdGNoKTsKfQoKY21zVUludDMyTnVtYmVyIENNU0VYUE9SVCBjbXNJVDhUYWJsZUNvdW50KGNtc0hBTkRMRSBoSVQ4KQp7CiAgICBjbXNJVDgqIGl0OCA9IChjbXNJVDgqKSBoSVQ4OwoKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCiAgICByZXR1cm4gaXQ4IC0+VGFibGVzQ291bnQ7Cn0KCi8vIFRoaXMgaGFuZGxlcyB0aGUgIkxBQkVMIiBleHRlbnNpb24uCi8vIExhYmVsLCBuVGFibGUsIFR5cGUKCmludCBDTVNFWFBPUlQgY21zSVQ4U2V0VGFibGVCeUxhYmVsKGNtc0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjU2V0LCBjb25zdCBjaGFyKiBjRmllbGQsIGNvbnN0IGNoYXIqIEV4cGVjdGVkVHlwZSkKewogICAgY29uc3QgY2hhciogY0xhYmVsRmxkOwogICAgY2hhciBUeXBlWzI1Nl0sIExhYmVsWzI1Nl07CiAgICBpbnQgblRhYmxlOwoKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCiAgICBpZiAoY0ZpZWxkICE9IE5VTEwgJiYgKmNGaWVsZCA9PSAwKQogICAgICAgICAgICBjRmllbGQgPSAiTEFCRUwiOwoKICAgIGlmIChjRmllbGQgPT0gTlVMTCkKICAgICAgICAgICAgY0ZpZWxkID0gIkxBQkVMIjsKCiAgICBjTGFiZWxGbGQgPSBjbXNJVDhHZXREYXRhKGhJVDgsIGNTZXQsIGNGaWVsZCk7CiAgICBpZiAoIWNMYWJlbEZsZCkgcmV0dXJuIC0xOwoKICAgIGlmIChzc2NhbmYoY0xhYmVsRmxkLCAiJTI1NXMgJWQgJTI1NXMiLCBMYWJlbCwgJm5UYWJsZSwgVHlwZSkgIT0gMykKICAgICAgICAgICAgcmV0dXJuIC0xOwoKICAgIGlmIChFeHBlY3RlZFR5cGUgIT0gTlVMTCAmJiAqRXhwZWN0ZWRUeXBlID09IDApCiAgICAgICAgRXhwZWN0ZWRUeXBlID0gTlVMTDsKCiAgICBpZiAoRXhwZWN0ZWRUeXBlKSB7CgogICAgICAgIGlmIChjbXNzdHJjYXNlY21wKFR5cGUsIEV4cGVjdGVkVHlwZSkgIT0gMCkgcmV0dXJuIC0xOwogICAgfQoKICAgIHJldHVybiBjbXNJVDhTZXRUYWJsZShoSVQ4LCBuVGFibGUpOwp9CgoKY21zQm9vbCBDTVNFWFBPUlQgY21zSVQ4U2V0SW5kZXhDb2x1bW4oY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNTYW1wbGUpCnsKICAgIGNtc0lUOCogaXQ4ID0gKGNtc0lUOCopIGhJVDg7CiAgICBpbnQgcG9zOwoKICAgIF9jbXNBc3NlcnQoaElUOCAhPSBOVUxMKTsKCiAgICBwb3MgPSBMb2NhdGVTYW1wbGUoaXQ4LCBjU2FtcGxlKTsKICAgIGlmKHBvcyA9PSAtMSkKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaXQ4LT5UYWJbaXQ4LT5uVGFibGVdLlNhbXBsZUlEID0gcG9zOwogICAgcmV0dXJuIFRSVUU7Cn0KCgp2b2lkIENNU0VYUE9SVCBjbXNJVDhEZWZpbmVEYmxGb3JtYXQoY21zSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIEZvcm1hdHRlcikKewogICAgY21zSVQ4KiBpdDggPSAoY21zSVQ4KikgaElUODsKCiAgICBfY21zQXNzZXJ0KGhJVDggIT0gTlVMTCk7CgogICAgaWYgKEZvcm1hdHRlciA9PSBOVUxMKQogICAgICAgIHN0cmNweShpdDgtPkRvdWJsZUZvcm1hdHRlciwgREVGQVVMVF9EQkxfRk9STUFUKTsKICAgIGVsc2UKICAgICAgICBzdHJuY3B5KGl0OC0+RG91YmxlRm9ybWF0dGVyLCBGb3JtYXR0ZXIsIHNpemVvZihpdDgtPkRvdWJsZUZvcm1hdHRlcikpOwoKICAgIGl0OCAtPkRvdWJsZUZvcm1hdHRlcltzaXplb2YoaXQ4IC0+RG91YmxlRm9ybWF0dGVyKS0xXSA9IDA7Cn0KCg==