LyoKICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKLy8gVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwovLyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLy8gSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwovLyBmaWxlOgovLwovLwovLyAgTGl0dGxlIGNtcwovLyAgQ29weXJpZ2h0IChDKSAxOTk4LTIwMDcgTWFydGkgTWFyaWEKLy8KLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nCi8vIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwKLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbgovLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwKLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlCi8vIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Ci8vCi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgovLwovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKLy8gRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPCi8vIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5ECi8vIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUKLy8gTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTgovLyBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04KLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCi8vCi8vIElUOC43IC8gQ0dBVFMuMTctMjAweCBoYW5kbGluZwoKI2luY2x1ZGUgImxjbXMuaCIKCgpMQ01TQVBJIExDTVNIQU5ETEUgICAgICBMQ01TRVhQT1JUIGNtc0lUOEFsbG9jKHZvaWQpOwpMQ01TQVBJIHZvaWQgICAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOEZyZWUoTENNU0hBTkRMRSBJVDgpOwoKLy8gVGFibGVzCgpMQ01TQVBJIGludCAgICAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFRhYmxlQ291bnQoTENNU0hBTkRMRSBJVDgpOwpMQ01TQVBJIGludCAgICAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNldFRhYmxlKExDTVNIQU5ETEUgSVQ4LCBpbnQgblRhYmxlKTsKCi8vIFBlcnNpc3RlbmNlCkxDTVNBUEkgTENNU0hBTkRMRSAgICAgIExDTVNFWFBPUlQgY21zSVQ4TG9hZEZyb21GaWxlKGNvbnN0IGNoYXIqIGNGaWxlTmFtZSk7CkxDTVNBUEkgTENNU0hBTkRMRSAgICAgIExDTVNFWFBPUlQgY21zSVQ4TG9hZEZyb21NZW0odm9pZCAqUHRyLCBzaXplX3QgbGVuKTsKTENNU0FQSSBMQ01TQk9PTCAgICAgICAgTENNU0VYUE9SVCBjbXNJVDhTYXZlVG9GaWxlKExDTVNIQU5ETEUgSVQ4LCBjb25zdCBjaGFyKiBjRmlsZU5hbWUpOwoKLy8gUHJvcGVydGllcwpMQ01TQVBJIGNvbnN0IGNoYXIqICAgICBMQ01TRVhQT1JUIGNtc0lUOEdldFNoZWV0VHlwZShMQ01TSEFORExFIGhJVDgpOwpMQ01TQVBJIExDTVNCT09MICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNldFNoZWV0VHlwZShMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIFR5cGUpOwoKTENNU0FQSSBMQ01TQk9PTCAgICAgICAgTENNU0VYUE9SVCBjbXNJVDhTZXRDb21tZW50KExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY0NvbW1lbnQpOwoKTENNU0FQSSBMQ01TQk9PTCAgICAgICAgTENNU0VYUE9SVCBjbXNJVDhTZXRQcm9wZXJ0eVN0cihMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNQcm9wLCBjb25zdCBjaGFyICpTdHIpOwpMQ01TQVBJIExDTVNCT09MICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNldFByb3BlcnR5RGJsKExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1Byb3AsIGRvdWJsZSBWYWwpOwpMQ01TQVBJIExDTVNCT09MICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNldFByb3BlcnR5SGV4KExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1Byb3AsIGludCBWYWwpOwpMQ01TQVBJIExDTVNCT09MICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNldFByb3BlcnR5TXVsdGkoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCwgY29uc3QgY2hhciogY1N1YlByb3AsIGNvbnN0IGNoYXIgKlZhbCk7CkxDTVNBUEkgTENNU0JPT0wgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlVbmNvb2tlZChMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIEtleSwgY29uc3QgY2hhciogQnVmZmVyKTsKCkxDTVNBUEkgY29uc3QgY2hhciogICAgIExDTVNFWFBPUlQgY21zSVQ4R2V0UHJvcGVydHkoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCk7CkxDTVNBUEkgZG91YmxlICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4R2V0UHJvcGVydHlEYmwoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCk7CkxDTVNBUEkgY29uc3QgY2hhciogICAgIExDTVNFWFBPUlQgY21zSVQ4R2V0UHJvcGVydHlNdWx0aShMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNQcm9wLCBjb25zdCBjaGFyICpjU3ViUHJvcCk7CkxDTVNBUEkgaW50ICAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4RW51bVByb3BlcnRpZXMoTENNU0hBTkRMRSBJVDgsIGNvbnN0IGNoYXIgKioqUHJvcGVydHlOYW1lcyk7CkxDTVNBUEkgaW50ICAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4RW51bVByb3BlcnR5TXVsdGkoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUHJvcCwgY29uc3QgY2hhcioqKiBTdWJwcm9wZXJ0eU5hbWVzKTsKCi8vIERhdGFzZXRzCgpMQ01TQVBJIGNvbnN0IGNoYXIqICAgICBMQ01TRVhQT1JUIGNtc0lUOEdldFBhdGNoTmFtZShMQ01TSEFORExFIGhJVDgsIGludCBuUGF0Y2gsIGNoYXIqIGJ1ZmZlcik7CgpMQ01TQVBJIGNvbnN0IGNoYXIqICAgICBMQ01TRVhQT1JUIGNtc0lUOEdldERhdGFSb3dDb2woTENNU0hBTkRMRSBJVDgsIGludCByb3csIGludCBjb2wpOwpMQ01TQVBJIGRvdWJsZSAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOEdldERhdGFSb3dDb2xEYmwoTENNU0hBTkRMRSBJVDgsIGludCBjb2wsIGludCByb3cpOwoKTENNU0FQSSBMQ01TQk9PTCAgICAgICAgTENNU0VYUE9SVCBjbXNJVDhTZXREYXRhUm93Q29sKExDTVNIQU5ETEUgaElUOCwgaW50IHJvdywgaW50IGNvbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogVmFsKTsKCkxDTVNBUEkgTENNU0JPT0wgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4U2V0RGF0YVJvd0NvbERibChMQ01TSEFORExFIGhJVDgsIGludCByb3csIGludCBjb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBWYWwpOwoKTENNU0FQSSBjb25zdCBjaGFyKiAgICAgTENNU0VYUE9SVCBjbXNJVDhHZXREYXRhKExDTVNIQU5ETEUgSVQ4LCBjb25zdCBjaGFyKiBjUGF0Y2gsIGNvbnN0IGNoYXIqIGNTYW1wbGUpOwoKCkxDTVNBUEkgZG91YmxlICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4R2V0RGF0YURibChMQ01TSEFORExFIElUOCwgY29uc3QgY2hhciogY1BhdGNoLCBjb25zdCBjaGFyKiBjU2FtcGxlKTsKCkxDTVNBUEkgTENNU0JPT0wgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4U2V0RGF0YShMQ01TSEFORExFIElUOCwgY29uc3QgY2hhciogY1BhdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBjU2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpWYWwpOwoKTENNU0FQSSBMQ01TQk9PTCAgICAgICAgTENNU0VYUE9SVCBjbXNJVDhTZXREYXRhRGJsKExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1BhdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBjU2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgVmFsKTsKCkxDTVNBUEkgTENNU0JPT0wgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4U2V0RGF0YUZvcm1hdChMQ01TSEFORExFIElUOCwgaW50IG4sIGNvbnN0IGNoYXIgKlNhbXBsZSk7CkxDTVNBUEkgaW50ICAgICAgICAgICAgIExDTVNFWFBPUlQgY21zSVQ4RW51bURhdGFGb3JtYXQoTENNU0hBTkRMRSBJVDgsIGNoYXIgKioqU2FtcGxlTmFtZXMpOwoKTENNU0FQSSB2b2lkICAgICAgICAgICAgTENNU0VYUE9SVCBjbXNJVDhEZWZpbmVEYmxGb3JtYXQoTENNU0hBTkRMRSBJVDgsIGNvbnN0IGNoYXIqIEZvcm1hdHRlcik7CgpMQ01TQVBJIGludCAgICAgICAgICAgICBMQ01TRVhQT1JUIGNtc0lUOFNldFRhYmxlQnlMYWJlbChMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNTZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogY0ZpZWxkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIEV4cGVjdGVkVHlwZSk7CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEltcGxlbWVudGF0aW9uCgoKI2RlZmluZSBTSVpFT0ZMT05HTUlOVVMxICAgIChzaXplb2YobG9uZyktMSkKI2RlZmluZSBBTElHTkxPTkcoeCkgKCgoeCkrU0laRU9GTE9OR01JTlVTMSkgJiB+KFNJWkVPRkxPTkdNSU5VUzEpKQoKLy8gI2RlZmluZSBTVFJJQ1RfQ0dBVFMgIDEKCiNkZWZpbmUgTUFYSUQgICAgICAgMTI4ICAgICAvLyBNYXggbGVuZ2h0IG9mIGlkZW50aWZpZXIKI2RlZmluZSBNQVhTVFIgICAgICAxMDI0ICAgICAvLyBNYXggbGVuZ2h0IG9mIHN0cmluZwojZGVmaW5lIE1BWFRBQkxFUyAgIDI1NSAgICAgLy8gTWF4IE51bWJlciBvZiB0YWJsZXMgaW4gYSBzaW5nbGUgc3RyZWFtCiNkZWZpbmUgTUFYSU5DTFVERSAgIDIwICAgICAvLyBNYXggbnVtYmVyIG9mIG5lc3RlZCBpbmNsdWRlcwoKI2RlZmluZSBERUZBVUxUX0RCTF9GT1JNQVQgICIlLjEwZyIgLy8gRG91YmxlIGZvcm1hdHRpbmcKCiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8bGltaXRzLmg+CgojaWZuZGVmIE5PTl9XSU5ET1dTCiNpbmNsdWRlIDxpby5oPgojZGVmaW5lIERJUl9DSEFSICAgICdcXCcKI2Vsc2UKI2RlZmluZSBESVJfQ0hBUiAgICAnLycKI2VuZGlmCgovLyBTeW1ib2xzCgp0eXBlZGVmIGVudW0gewoKICAgICAgICBTTk9ORSwKICAgICAgICBTSU5VTSwgICAgICAvLyBJbnRlZ2VyCiAgICAgICAgU0ROVU0sICAgICAgLy8gUmVhbAogICAgICAgIFNJREVOVCwgICAgIC8vIElkZW50aWZpZXIKICAgICAgICBTU1RSSU5HLCAgICAvLyBzdHJpbmcKICAgICAgICBTQ09NTUVOVCwgICAvLyBjb21tZW50CiAgICAgICAgU0VPTE4sICAgICAgLy8gRW5kIG9mIGxpbmUKICAgICAgICBTRU9GLCAgICAgICAvLyBFbmQgb2Ygc3RyZWFtCiAgICAgICAgU1NZTkVSUk9SLCAgLy8gU3ludGF4IGVycm9yIGZvdW5kIG9uIHN0cmVhbQoKICAgICAgICAvLyBLZXl3b3JkcwoKICAgICAgICBTQkVHSU5fREFUQSwKICAgICAgICBTQkVHSU5fREFUQV9GT1JNQVQsCiAgICAgICAgU0VORF9EQVRBLAogICAgICAgIFNFTkRfREFUQV9GT1JNQVQsCiAgICAgICAgU0tFWVdPUkQsCiAgICAgICAgU0RBVEFfRk9STUFUX0lELAogICAgICAgIFNJTkNMVURFCgogICAgfSBTWU1CT0w7CgoKLy8gSG93IHRvIHdyaXRlIHRoZSB2YWx1ZQoKdHlwZWRlZiBlbnVtIHsKICAgICAgICBXUklURV9VTkNPT0tFRCwKICAgICAgICBXUklURV9TVFJJTkdJRlksCiAgICAgICAgV1JJVEVfSEVYQURFQ0lNQUwsCiAgICAgICAgV1JJVEVfQklOQVJZLAogICAgICAgIFdSSVRFX1BBSVIKCiAgICB9IFdSSVRFTU9ERTsKCi8vIExpbmtlZCBsaXN0IG9mIHZhcmlhYmxlIG5hbWVzCgp0eXBlZGVmIHN0cnVjdCBfS2V5VmFsIHsKCiAgICAgICAgc3RydWN0IF9LZXlWYWwqICBOZXh0OwogICAgICAgIGNoYXIqICAgICAgICAgICAgS2V5d29yZDsgICAgICAgLy8gTmFtZSBvZiB2YXJpYWJsZQogICAgICAgIHN0cnVjdCBfS2V5VmFsKiAgTmV4dFN1YmtleTsgICAgLy8gSWYga2V5IGlzIGEgZGljdGlvbmFyeSwgcG9pbnRzIHRvIHRoZSBuZXh0IGl0ZW0KICAgICAgICBjaGFyKiAgICAgICAgICAgIFN1YmtleTsgICAgICAgIC8vIElmIGtleSBpcyBhIGRpY3Rpb25hcnksIHBvaW50cyB0byB0aGUgc3Via2V5IG5hbWUKICAgICAgICBjaGFyKiAgICAgICAgICAgIFZhbHVlOyAgICAgICAgIC8vIFBvaW50cyB0byB2YWx1ZQogICAgICAgIFdSSVRFTU9ERSAgICAgICAgV3JpdGVBczsgICAgICAgLy8gSG93IHRvIHdyaXRlIHRoZSB2YWx1ZQoKICAgfSBLRVlWQUxVRSwgKkxQS0VZVkFMVUU7CgoKLy8gTGlua2VkIGxpc3Qgb2YgbWVtb3J5IGNodW5rcyAoTWVtb3J5IHNpbmspCgp0eXBlZGVmIHN0cnVjdCBfT3duZWRNZW0gewoKICAgICAgICBzdHJ1Y3QgX093bmVkTWVtKiBOZXh0OwogICAgICAgIHZvaWQgKiAgICAgICAgICAgIFB0cjsgICAgICAgICAgLy8gUG9pbnQgdG8gdmFsdWUKCiAgIH0gT1dORURNRU0sICpMUE9XTkVETUVNOwoKLy8gU3ViYWxsb2NhdG9yCgp0eXBlZGVmIHN0cnVjdCBfU3ViQWxsb2NhdG9yIHsKCiAgICAgICAgIExQQllURSBCbG9jazsKICAgICAgICAgc2l6ZV90IEJsb2NrU2l6ZTsKICAgICAgICAgc2l6ZV90IFVzZWQ7CgogICAgfSBTVUJBTExPQ0FUT1IsICpMUFNVQkFMTE9DQVRPUjsKCi8vIFRhYmxlLiBFYWNoIGluZGl2aWR1YWwgdGFibGUgY2FuIGhvbGQgcHJvcGVydGllcyBhbmQgcm93cyAmIGNvbHMKCnR5cGVkZWYgc3RydWN0IF9UYWJsZSB7CgogICAgICAgIGludCAgICAgICAgICAgIG5TYW1wbGVzLCBuUGF0Y2hlczsgICAgLy8gQ29scywgUm93cwogICAgICAgIGludCAgICAgICAgICAgIFNhbXBsZUlEOyAgICAgICAgICAgICAgLy8gUG9zIG9mIElECgogICAgICAgIExQS0VZVkFMVUUgICAgIEhlYWRlckxpc3Q7ICAgICAgICAgICAgLy8gVGhlIHByb3BlcnRpZXMKCiAgICAgICAgY2hhcioqICAgICAgICAgRGF0YUZvcm1hdDsgICAgICAgICAgICAvLyBUaGUgYmluYXJ5IHN0cmVhbSBkZXNjcmlwdG9yCiAgICAgICAgY2hhcioqICAgICAgICAgRGF0YTsgICAgICAgICAgICAgICAgICAvLyBUaGUgYmluYXJ5IHN0cmVhbQoKICAgIH0gVEFCTEUsICpMUFRBQkxFOwoKLy8gRmlsZSBzdHJlYW0gYmVpbmcgcGFyc2VkCgp0eXBlZGVmIHN0cnVjdCBfRmlsZUNvbnRleHQgewogICAgICAgIGNoYXIgICAgICAgICAgIEZpbGVOYW1lW01BWF9QQVRIXTsgICAgLy8gRmlsZSBuYW1lIGlmIGJlaW5nIHJlYWRlZCBmcm9tIGZpbGUKICAgICAgICBGSUxFKiAgICAgICAgICBTdHJlYW07ICAgICAgICAgICAgICAgIC8vIEZpbGUgc3RyZWFtIG9yIE5VTEwgaWYgaG9sZGVkIGluIG1lbW9yeQogICAgfSBGSUxFQ1RYLCAqTFBGSUxFQ1RYOwoKLy8gVGhpcyBzdHJ1Y3QgaG9sZCBhbGwgaW5mb3JtYXRpb24gYWJvdXQgYW4gb3BlbmVuZWQKLy8gSVQ4IGhhbmRsZXIuIE9ubHkgb25lIGRhdGFzZXQgaXMgYWxsb3dlZC4KCnR5cGVkZWYgc3RydWN0IHsKCiAgICAgICAgY2hhciBTaGVldFR5cGVbTUFYU1RSXTsKCiAgICAgICAgaW50ICBUYWJsZXNDb3VudDsgICAgICAgICAgICAgICAgICAgICAvLyBIb3cgbWFueSB0YWJsZXMgaW4gdGhpcyBzdHJlYW0KICAgICAgICBpbnQgIG5UYWJsZTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBhY3R1YWwgdGFibGUKCiAgICAgICAgVEFCTEUgVGFiW01BWFRBQkxFU107CgogICAgICAgIC8vIE1lbW9yeSBtYW5hZ2VtZW50CgogICAgICAgIExQT1dORURNRU0gICAgIE1lbW9yeVNpbms7ICAgICAgICAgICAgLy8gVGhlIHN0b3JhZ2UgYmFja2VuZAogICAgICAgIFNVQkFMTE9DQVRPUiAgIEFsbG9jYXRvcjsgICAgICAgICAgICAgLy8gU3RyaW5nIHN1YmFsbG9jYXRvciAtLSBqdXN0IHRvIGtlZXAgaXQgZmFzdAoKICAgICAgICAvLyBQYXJzZXIgc3RhdGUgbWFjaGluZQoKICAgICAgICBTWU1CT0wgICAgICAgICBzeTsgICAgICAgICAgICAgICAgICAgIC8vIEN1cnJlbnQgc3ltYm9sCiAgICAgICAgaW50ICAgICAgICAgICAgY2g7ICAgICAgICAgICAgICAgICAgICAvLyBDdXJyZW50IGNoYXJhY3RlcgoKICAgICAgICBpbnQgICAgICAgICAgICBpbnVtOyAgICAgICAgICAgICAgICAgIC8vIGludGVnZXIgdmFsdWUKICAgICAgICBkb3VibGUgICAgICAgICBkbnVtOyAgICAgICAgICAgICAgICAgIC8vIHJlYWwgdmFsdWUKICAgICAgICBjaGFyICAgICAgICAgICBpZFtNQVhJRF07ICAgICAgICAgICAgIC8vIGlkZW50aWZpZXIKICAgICAgICBjaGFyICAgICAgICAgICBzdHJbTUFYU1RSXTsgICAgICAgICAgIC8vIHN0cmluZwoKICAgICAgICAvLyBBbGxvd2VkIGtleXdvcmRzICYgZGF0YXNldHMuIFRoZXkgaGF2ZSB2aXNpYmlsaXR5IG9uIHdob2xlIHN0cmVhbQoKICAgICAgICBMUEtFWVZBTFVFICAgICBWYWxpZEtleXdvcmRzOwogICAgICAgIExQS0VZVkFMVUUgICAgIFZhbGlkU2FtcGxlSUQ7CgogICAgICAgIGNoYXIqICAgICAgICAgIFNvdXJjZTsgICAgICAgICAgICAgICAgLy8gUG9pbnRzIHRvIGxvYy4gYmVpbmcgcGFyc2VkCiAgICAgICAgaW50ICAgICAgICAgICAgbGluZW5vOyAgICAgICAgICAgICAgICAvLyBsaW5lIGNvdW50ZXIgZm9yIGVycm9yIHJlcG9ydGluZwoKICAgICAgICBMUEZJTEVDVFggICAgICBGaWxlU3RhY2tbTUFYSU5DTFVERV07IC8vIFN0YWNrIG9mIGZpbGVzIGJlaW5nIHBhcnNlZAogICAgICAgIGludCAgICAgICAgICAgIEluY2x1ZGVTUDsgICAgICAgICAgICAgLy8gSW5jbHVkZSBTdGFjayBQb2ludGVyCgogICAgICAgIGNoYXIqICAgICAgICAgIE1lbW9yeUJsb2NrOyAgICAgICAgICAgLy8gVGhlIHN0cmVhbSBpZiBob2xkZWQgaW4gbWVtb3J5CgogICAgICAgIGNoYXIgICAgICAgICAgIERvdWJsZUZvcm1hdHRlcltNQVhJRF07ICAgLy8gUHJpbnRmLWxpa2UgJ2RvdWJsZScgZm9ybWF0dGVyCgogICB9IElUOCwgKkxQSVQ4OwoKCgp0eXBlZGVmIHN0cnVjdCB7CgogICAgICAgIEZJTEUqIHN0cmVhbTsgICAvLyBGb3Igc2F2ZS10by1maWxlIGJlaGF2aW91cgoKICAgICAgICBMUEJZVEUgQmFzZTsKICAgICAgICBMUEJZVEUgUHRyOyAgICAgLy8gRm9yIHNhdmUtdG8tbWVtIGJlaGF2aW91cgogICAgICAgIHNpemVfdCBVc2VkOwogICAgICAgIHNpemVfdCBNYXg7CgogICAgfSBTQVZFU1RSRUFNLCBGQVIqIExQU0FWRVNUUkVBTTsKCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSVQ4IHBhcnNpbmcgcm91dGluZXMKCgovLyBBIGtleXdvcmQKdHlwZWRlZiBzdHJ1Y3QgewoKICAgICAgICBjb25zdCBjaGFyICppZDsKICAgICAgICBTWU1CT0wgc3k7CgogICB9IEtFWVdPUkQ7CgovLyBUaGUga2V5d29yZC0+c3ltYm9sIHRyYW5zbGF0aW9uIHRhYmxlLiBTb3J0aW5nIGlzIHJlcXVpcmVkLgpzdGF0aWMgY29uc3QgS0VZV09SRCBUYWJLZXlzW10gPSB7CgogICAgICAgIHsiJElOQ0xVREUiLCAgICAgICAgICAgIFNJTkNMVURFfSwKICAgICAgICB7Ii5JTkNMVURFIiwgICAgICAgICAgICBTSU5DTFVERX0sCiAgICAgICAgeyJCRUdJTl9EQVRBIiwgICAgICAgICAgU0JFR0lOX0RBVEEgfSwKICAgICAgICB7IkJFR0lOX0RBVEFfRk9STUFUIiwgICBTQkVHSU5fREFUQV9GT1JNQVQgfSwKICAgICAgICB7IkRBVEFfRk9STUFUX0lERU5USUZJRVIiLCBTREFUQV9GT1JNQVRfSUR9LAogICAgICAgIHsiRU5EX0RBVEEiLCAgICAgICAgICAgIFNFTkRfREFUQX0sCiAgICAgICAgeyJFTkRfREFUQV9GT1JNQVQiLCAgICAgU0VORF9EQVRBX0ZPUk1BVH0sCiAgICAgICAgeyJLRVlXT1JEIiwgICAgICAgICAgICAgU0tFWVdPUkR9CiAgICAgICAgfTsKCiNkZWZpbmUgTlVNS0VZUyAoc2l6ZW9mKFRhYktleXMpL3NpemVvZihLRVlXT1JEKSkKCi8vIFByZWRlZmluZWQgcHJvcGVydGllcwoKLy8gQSBwcm9wZXJ0eQp0eXBlZGVmIHN0cnVjdCB7CiAgICAgICAgY29uc3QgY2hhciAqaWQ7CiAgICAgICAgV1JJVEVNT0RFIGFzOwogICAgfSBQUk9QRVJUWTsKCnN0YXRpYyBQUk9QRVJUWSBQcmVkZWZpbmVkUHJvcGVydGllc1tdID0gewoKICAgICAgICB7Ik5VTUJFUl9PRl9GSUVMRFMiLCBXUklURV9VTkNPT0tFRH0sICAgIC8vIFJlcXVpcmVkIC0gTlVNQkVSIE9GIEZJRUxEUwogICAgICAgIHsiTlVNQkVSX09GX1NFVFMiLCAgIFdSSVRFX1VOQ09PS0VEfSwgICAgLy8gUmVxdWlyZWQgLSBOVU1CRVIgT0YgU0VUUwogICAgICAgIHsiT1JJR0lOQVRPUiIsICAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gUmVxdWlyZWQgLSBJZGVudGlmaWVzIHRoZSBzcGVjaWZpYyBzeXN0ZW0sIG9yZ2FuaXphdGlvbiBvciBpbmRpdmlkdWFsIHRoYXQgY3JlYXRlZCB0aGUgZGF0YSBmaWxlLgogICAgICAgIHsiRklMRV9ERVNDUklQVE9SIiwgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gUmVxdWlyZWQgLSBEZXNjcmliZXMgdGhlIHB1cnBvc2Ugb3IgY29udGVudHMgb2YgdGhlIGRhdGEgZmlsZS4KICAgICAgICB7IkNSRUFURUQiLCAgICAgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIFJlcXVpcmVkIC0gSW5kaWNhdGVzIGRhdGUgb2YgY3JlYXRpb24gb2YgdGhlIGRhdGEgZmlsZS4KICAgICAgICB7IkRFU0NSSVBUT1IiLCAgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIFJlcXVpcmVkICAtIERlc2NyaWJlcyB0aGUgcHVycG9zZSBvciBjb250ZW50cyBvZiB0aGUgZGF0YSBmaWxlLgogICAgICAgIHsiRElGRlVTRV9HRU9NRVRSWSIsIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gVGhlIGRpZmZ1c2UgZ2VvbWV0cnkgdXNlZC4gQWxsb3dlZCB2YWx1ZXMgYXJlICJzcGhlcmUiIG9yICJvcGFsIi4KICAgICAgICB7Ik1BTlVGQUNUVVJFUiIsICAgICBXUklURV9TVFJJTkdJRll9LAogICAgICAgIHsiTUFOVUZBQ1RVUkUiLCAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gU29tZSBicm9rZW4gRnVqaSB0YXJnZXRzIGRvZXMgc3RvcmUgdGhpcyB2YWx1ZQogICAgICAgIHsiUFJPRF9EQVRFIiwgICAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gSWRlbnRpZmllcyB5ZWFyIGFuZCBtb250aCBvZiBwcm9kdWN0aW9uIG9mIHRoZSB0YXJnZXQgaW4gdGhlIGZvcm0geXl5eTptbS4KICAgICAgICB7IlNFUklBTCIsICAgICAgICAgICBXUklURV9TVFJJTkdJRll9LCAgIC8vIFVuaXF1ZWx5IGlkZW50aWZpZXMgaW5kaXZpZHVhbCBwaHlzaWNhbCB0YXJnZXQuCgogICAgICAgIHsiTUFURVJJQUwiLCAgICAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gSWRlbnRpZmllcyB0aGUgbWF0ZXJpYWwgb24gd2hpY2ggdGhlIHRhcmdldCB3YXMgcHJvZHVjZWQgdXNpbmcgYSBjb2RlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1bmlxdWVseSBpZGVudGlmeWluZyB0aCBlIG1hdGVyaWFsLiBUaGlzIGlzIGludGVuZCBlZCB0byBiZSB1c2VkIGZvciBJVDguNwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcGh5c2ljYWwgdGFyZ2V0cyBvbmx5IChpLmUgLiBJVDguNy8xIGEgbmQgSVQ4LjcvMikuCgogICAgICAgIHsiSU5TVFJVTUVOVEFUSU9OIiwgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gVXNlZCB0byByZXBvcnQgdGhlIHNwZWNpZmljIGluc3RydW1lbnRhdGlvbiB1c2VkIChtYW51ZmFjdHVyZXIgYW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtb2RlbCBudW1iZXIpIHRvIGdlbmVyYXRlIHRoZSBkYXRhIHJlcG9ydGVkLiBUaGlzIGRhdGEgd2lsbCBvZnRlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJvdmlkZSBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwYXJ0aWN1bGFyIGRhdGEgY29sbGVjdGVkIHRoYW4gYW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dGVuc2l2ZSBsaXN0IG9mIHNwZWNpZmljIGRldGFpbHMuIFRoaXMgaXMgcGFydGljdWxhcmx5IGltcG9ydGFudCBmb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNwZWN0cmFsIGRhdGEgb3IgZGF0YSBkZXJpdmVkIGZyb20gc3BlY3Ryb3Bob3RvbWV0cnkuCgogICAgICAgIHsiTUVBU1VSRU1FTlRfU09VUkNFIiwgV1JJVEVfU1RSSU5HSUZZfSwgLy8gSWxsdW1pbmF0aW9uIHVzZWQgZm9yIHNwZWN0cmFsIG1lYXN1cmVtZW50cy4gVGhpcyBkYXRhIGhlbHBzIHByb3ZpZGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgZ3VpZGUgdG8gdGhlIHBvdGVudGlhbCBmb3IgaXNzdWVzIG9mIHBhcGVyIGZsdW9yZXNjZW5jZSwgZXRjLgoKICAgICAgICB7IlBSSU5UX0NPTkRJVElPTlMiLCBXUklURV9TVFJJTkdJRll9LCAgIC8vIFVzZWQgdG8gZGVmaW5lIHRoZSBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIHByaW50ZWQgc2hlZXQgYmVpbmcgcmVwb3J0ZWQuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGVyZSBzdGFuZGFyZCBjb25kaXRpb25zIGhhdmUgYmVlbiBkZWZpbmVkIChlLmcuLCBTV09QIGF0IG5vbWluYWwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBuYW1lZCBjb25kaXRpb25zIG1heSBzdWZmaWNlLiBPdGhlcndpc2UsIGRldGFpbGVkIGluZm9ybWF0aW9uIGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBuZWVkZWQuCgogICAgICAgIHsiU0FNUExFX0JBQ0tJTkciLCAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gSWRlbnRpZmllcyB0aGUgYmFja2luZyBtYXRlcmlhbCB1c2VkIGJlaGluZCB0aGUgc2FtcGxlIGR1cmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWVhc3VyZW1lbnQuIEFsbG93ZWQgdmFsdWVzIGFyZSCTYmxhY2uULCCTd2hpdGWULCBvciB7Im5hIi4KCiAgICAgICAgeyJDSElTUV9ET0YiLCAgICAgICAgV1JJVEVfU1RSSU5HSUZZfSwgICAvLyBEZWdyZWVzIG9mIGZyZWVkb20gYXNzb2NpYXRlZCB3aXRoIHRoZSBDaGkgc3F1YXJlZCBzdGF0aXN0aWMKCi8vICAgIG5ldyBpbiByZWNlbnQgc3BlY3M6CiAgICAgICAgeyJNRUFTVVJFTUVOVF9HRU9NRVRSWSIsIFdSSVRFX1NUUklOR0lGWX0sIC8vIFRoZSB0eXBlIG9mIG1lYXN1cmVtZW50LCBlaXRoZXIgcmVmbGVjdGlvbiBvciB0cmFuc21pc3Npb24sIHNob3VsZCBiZSBpbmRpY2F0ZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFsb25nIHdpdGggZGV0YWlscyBvZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBhcGVydHVyZSBzaXplIGFuZCBzaGFwZS4gRm9yIGV4YW1wbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgdHJhbnNtaXNzaW9uIG1lYXN1cmVtZW50cyBpdCBpcyBpbXBvcnRhbnQgdG8gaWRlbnRpZnkgMC9kaWZmdXNlLCBkaWZmdXNlLzAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvcGFsIG9yIGludGVncmF0aW5nIHNwaGVyZSwgZXRjLiBGb3IgcmVmbGVjdGlvbiBpdCBpcyBpbXBvcnRhbnQgdG8gaWRlbnRpZnkgMC80NSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDQ1LzAsIHNwaGVyZSAoc3BlY3VsYXIgaW5jbHVkZWQgb3IgZXhjbHVkZWQpLCBldGMuCgogICAgICAgeyJGSUxURVIiLCAgICAgICAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gSWRlbnRpZmllcyB0aGUgdXNlIG9mIHBoeXNpY2FsIGZpbHRlcihzKSBkdXJpbmcgbWVhc3VyZW1lbnQuIFR5cGljYWxseSB1c2VkIHRvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZW5vdGUgdGhlIHVzZSBvZiBmaWx0ZXJzIHN1Y2ggYXMgbm9uZSwgRDY1LCBSZWQsIEdyZWVuIG9yIEJsdWUuCgogICAgICAgeyJQT0xBUklaQVRJT04iLCAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAgLy8gSWRlbnRpZmllcyB0aGUgdXNlIG9mIGEgcGh5c2ljYWwgcG9sYXJpemF0aW9uIGZpbHRlciBkdXJpbmcgbWVhc3VyZW1lbnQuIEFsbG93ZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhbHVlcyBhcmUgeyJ5ZXOULCCTd2hpdGWULCCTbm9uZZQgb3Igk25hlC4KCiAgICAgICB7IldFSUdIVElOR19GVU5DVElPTiIsIFdSSVRFX1BBSVJ9LCAgIC8vIEluZGljYXRlcyBzdWNoIGZ1bmN0aW9ucyBhczogdGhlIENJRSBzdGFuZGFyZCBvYnNlcnZlciBmdW5jdGlvbnMgdXNlZCBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0aW9uIG9mIHZhcmlvdXMgZGF0YSBwYXJhbWV0ZXJzICgyIGRlZ3JlZSBhbmQgMTAgZGVncmVlKSwgQ0lFIHN0YW5kYXJkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbGx1bWluYW50IGZ1bmN0aW9ucyB1c2VkIGluIHRoZSBjYWxjdWxhdGlvbiBvZiB2YXJpb3VzIGRhdGEgcGFyYW1ldGVycyAoZS5nLiwgRDUwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRDY1LCBldGMuKSwgZGVuc2l0eSBzdGF0dXMgcmVzcG9uc2UsIGV0Yy4gSWYgdXNlZCB0aGVyZSBzaGFsbCBiZSBhdCBsZWFzdCBvbmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5hbWUtdmFsdWUgcGFpciBmb2xsb3dpbmcgdGhlIFdFSUdIVElOR19GVU5DVElPTiB0YWcva2V5d29yZC4gVGhlIGZpcnN0IGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW4gdGhlIHNldCBzaGFsbCBiZSB7Im5hbWUiIGFuZCBzaGFsbCBpZGVudGlmeSB0aGUgcGFydGljdWxhciBwYXJhbWV0ZXIgdXNlZC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBzZWNvbmQgc2hhbGwgYmUgeyJ2YWx1ZSIgYW5kIHNoYWxsIHByb3ZpZGUgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGF0IG5hbWUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3IgQVNDSUkgZGF0YSwgYSBzdHJpbmcgY29udGFpbmluZyB0aGUgTmFtZSBhbmQgVmFsdWUgYXR0cmlidXRlIHBhaXJzIHNoYWxsIGZvbGxvdwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHdlaWdodGluZyBmdW5jdGlvbiBrZXl3b3JkLiBBIHNlbWktY29sb24gc2VwYXJhdGVzIGF0dHJpYnV0ZSBwYWlycyBmcm9tIGVhY2gKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG90aGVyIGFuZCB3aXRoaW4gdGhlIGF0dHJpYnV0ZSB0aGUgbmFtZSBhbmQgdmFsdWUgYXJlIHNlcGFyYXRlZCBieSBhIGNvbW1hLgoKICAgICAgIHsiQ09NUFVUQVRJT05BTF9QQVJBTUVURVIiLCBXUklURV9QQUlSfSwgLy8gUGFyYW1ldGVyIHRoYXQgaXMgdXNlZCBpbiBjb21wdXRpbmcgYSB2YWx1ZSBmcm9tIG1lYXN1cmVkIGRhdGEuIE5hbWUgaXMgdGhlIG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9mIHRoZSBjYWxjdWxhdGlvbiwgcGFyYW1ldGVyIGlzIHRoZSBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIgdXNlZCBpbiB0aGUgY2FsY3VsYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB2YWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4KCiAgICAgICB7IlRBUkdFVF9UWVBFIiwgICAgICAgIFdSSVRFX1NUUklOR0lGWX0sICAvLyBUaGUgdHlwZSBvZiB0YXJnZXQgYmVpbmcgbWVhc3VyZWQsIGUuZy4gSVQ4LjcvMSwgSVQ4LjcvMywgdXNlciBkZWZpbmVkLCBldGMuCgogICAgICAgeyJDT0xPUkFOVCIsICAgICAgICAgICBXUklURV9TVFJJTkdJRll9LCAgLy8gSWRlbnRpZmllcyB0aGUgY29sb3JhbnQocykgdXNlZCBpbiBjcmVhdGluZyB0aGUgdGFyZ2V0LgoKICAgICAgIHsiVEFCTEVfREVTQ1JJUFRPUiIsICAgV1JJVEVfU1RSSU5HSUZZfSwgIC8vIERlc2NyaWJlcyB0aGUgcHVycG9zZSBvciBjb250ZW50cyBvZiBhIGRhdGEgdGFibGUuCgogICAgICAgeyJUQUJMRV9OQU1FIiwgICAgICAgICBXUklURV9TVFJJTkdJRll9ICAgLy8gUHJvdmlkZXMgYSBzaG9ydCBuYW1lIGZvciBhIGRhdGEgdGFibGUuCn07CgojZGVmaW5lIE5VTVBSRURFRklORURQUk9QUyAoc2l6ZW9mKFByZWRlZmluZWRQcm9wZXJ0aWVzKS9zaXplb2YoUFJPUEVSVFkpKQoKCi8vIFByZWRlZmluZWQgc2FtcGxlIHR5cGVzIG9uIGRhdGFzZXQKc3RhdGljIGNvbnN0IGNoYXIqIFByZWRlZmluZWRTYW1wbGVJRFtdID0gewogICAgICAgICJTQU1QTEVfSUQiLCAgICAgIC8vIElkZW50aWZpZXMgc2FtcGxlIHRoYXQgZGF0YSByZXByZXNlbnRzCiAgICAgICAgIlNUUklORyIsICAgICAgICAgLy8gSWRlbnRpZmllcyBsYWJlbCwgb3Igb3RoZXIgbm9uLW1hY2hpbmUgcmVhZGFibGUgdmFsdWUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmFsdWUgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggYSAiIHN5bWJvbAoKICAgICAgICAiQ01ZS19DIiwgICAgICAgICAvLyBDeWFuIGNvbXBvbmVudCBvZiBDTVlLIGRhdGEgZXhwcmVzc2VkIGFzIGEgcGVyY2VudGFnZQogICAgICAgICJDTVlLX00iLCAgICAgICAgIC8vIE1hZ2VudGEgY29tcG9uZW50IG9mIENNWUsgZGF0YSBleHByZXNzZWQgYXMgYSBwZXJjZW50YWdlCiAgICAgICAgIkNNWUtfWSIsICAgICAgICAgLy8gWWVsbG93IGNvbXBvbmVudCBvZiBDTVlLIGRhdGEgZXhwcmVzc2VkIGFzIGEgcGVyY2VudGFnZQogICAgICAgICJDTVlLX0siLCAgICAgICAgIC8vIEJsYWNrIGNvbXBvbmVudCBvZiBDTVlLIGRhdGEgZXhwcmVzc2VkIGFzIGEgcGVyY2VudGFnZQogICAgICAgICJEX1JFRCIsICAgICAgICAgIC8vIFJlZCBmaWx0ZXIgZGVuc2l0eQogICAgICAgICJEX0dSRUVOIiwgICAgICAgIC8vIEdyZWVuIGZpbHRlciBkZW5zaXR5CiAgICAgICAgIkRfQkxVRSIsICAgICAgICAgLy8gQmx1ZSBmaWx0ZXIgZGVuc2l0eQogICAgICAgICJEX1ZJUyIsICAgICAgICAgIC8vIFZpc3VhbCBmaWx0ZXIgZGVuc2l0eQogICAgICAgICJEX01BSk9SX0ZJTFRFUiIsIC8vIE1ham9yIGZpbHRlciBkIGVuc2l0eQogICAgICAgICJSR0JfUiIsICAgICAgICAgIC8vIFJlZCBjb21wb25lbnQgb2YgUkdCIGRhdGEKICAgICAgICAiUkdCX0ciLCAgICAgICAgICAvLyBHcmVlbiBjb21wb25lbnQgb2YgUkdCIGRhdGEKICAgICAgICAiUkdCX0IiLCAgICAgICAgICAvLyBCbHVlIGNvbSBwb25lbnQgb2YgUkdCIGRhdGEKICAgICAgICAiU1BFQ1RSQUxfTk0iLCAgICAvLyBXYXZlbGVuZ3RoIG9mIG1lYXN1cmVtZW50IGV4cHJlc3NlZCBpbiBuYW5vbWV0ZXJzCiAgICAgICAgIlNQRUNUUkFMX1BDVCIsICAgLy8gUGVyY2VudGFnZSByZWZsZWN0YW5jZS90cmFuc21pdHRhbmNlCiAgICAgICAgIlNQRUNUUkFMX0RFQyIsICAgLy8gUmVmbGVjdGFuY2UvdHJhbnNtaXR0YW5jZQogICAgICAgICJYWVpfWCIsICAgICAgICAgIC8vIFggY29tcG9uZW50IG9mIHRyaXN0aW11bHVzIGRhdGEKICAgICAgICAiWFlaX1kiLCAgICAgICAgICAvLyBZIGNvbXBvbmVudCBvZiB0cmlzdGltdWx1cyBkYXRhCiAgICAgICAgIlhZWl9aIiwgICAgICAgICAgLy8gWiBjb21wb25lbnQgb2YgdHJpc3RpbXVsdXMgZGF0YQogICAgICAgICJYWVlfWCIgICAgICAgICAgIC8vIHggY29tcG9uZW50IG9mIGNocm9tYXRpY2l0eSBkYXRhCiAgICAgICAgIlhZWV9ZIiwgICAgICAgICAgLy8geSBjb21wb25lbnQgb2YgY2hyb21hdGljaXR5IGRhdGEKICAgICAgICAiWFlZX0NBUFkiLCAgICAgICAvLyBZIGNvbXBvbmVudCBvZiB0cmlzdGltdWx1cyBkYXRhCiAgICAgICAgIkxBQl9MIiwgICAgICAgICAgLy8gTCogY29tcG9uZW50IG9mIExhYiBkYXRhCiAgICAgICAgIkxBQl9BIiwgICAgICAgICAgLy8gYSogY29tcG9uZW50IG9mIExhYiBkYXRhCiAgICAgICAgIkxBQl9CIiwgICAgICAgICAgLy8gYiogY29tcG9uZW50IG9mIExhYiBkYXRhCiAgICAgICAgIkxBQl9DIiwgICAgICAgICAgLy8gQyphYiBjb21wb25lbnQgb2YgTGFiIGRhdGEKICAgICAgICAiTEFCX0giLCAgICAgICAgICAvLyBoYWIgY29tcG9uZW50IG9mIExhYiBkYXRhCiAgICAgICAgIkxBQl9ERSIsICAgICAgICAgLy8gIENJRSBkRQogICAgICAgICJMQUJfREVfOTQiLCAgICAgIC8vICBDSUUgZEUgdXNpbmcgQ0lFIDk0CiAgICAgICAgIkxBQl9ERV9DTUMiLCAgICAgLy8gIGRFIHVzaW5nIENNQwogICAgICAgICJMQUJfREVfMjAwMCIsICAgIC8vIENJRSBkRSB1c2luZyBDSUUgREUgMjAwMAogICAgICAgICJNRUFOX0RFIiwgICAgICAgIC8vIE1lYW4gRGVsdGEgRSAoTEFCX0RFKSBvZiBzYW1wbGVzIGNvbXBhcmVkIHRvIGJhdGNoIGF2ZXJhZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAoVXNlZCBmb3IgZGF0YSBmaWxlcyBmb3IgQU5TSSBJVDguNy8xIGFuZCBJVDguNy8yIHRhcmdldHMpCiAgICAgICAgIlNUREVWX1giLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIFggKHRyaXN0aW11bHVzIGRhdGEpCiAgICAgICAgIlNUREVWX1kiLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIFkgKHRyaXN0aW11bHVzIGRhdGEpCiAgICAgICAgIlNUREVWX1oiLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIFogKHRyaXN0aW11bHVzIGRhdGEpCiAgICAgICAgIlNUREVWX0wiLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIEwqCiAgICAgICAgIlNUREVWX0EiLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIGEqCiAgICAgICAgIlNUREVWX0IiLCAgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIGIqCiAgICAgICAgIlNUREVWX0RFIiwgICAgICAgLy8gU3RhbmRhcmQgZGV2aWF0aW9uIG9mIENJRSBkRQogICAgICAgICJDSElfU1FEX1BBUiJ9OyAgIC8vIFRoZSBhdmVyYWdlIG9mIHRoZSBzdGFuZGFyZCBkZXZpYXRpb25zIG9mIEwqLCBhKiBhbmQgYiouIEl0IGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlZCB0byBkZXJpdmUgYW4gZXN0aW1hdGUgb2YgdGhlIGNoaS1zcXVhcmVkIHBhcmFtZXRlciB3aGljaCBpcwogICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlY29tbWVuZGVkIGFzIHRoZSBwcmVkaWN0b3Igb2YgdGhlIHZhcmlhYmlsaXR5IG9mIGRFCgojZGVmaW5lIE5VTVBSRURFRklORURTQU1QTEVJRCAoc2l6ZW9mKFByZWRlZmluZWRTYW1wbGVJRCkvc2l6ZW9mKGNoYXIgKikpCgovL0ZvcndhcmQgZGVjbGFyYXRpb24gb2Ygc29tZSBpbnRlcm5hbCBmdW5jdGlvbnMKc3RhdGljCnZvaWQqIEFsbG9jQ2h1bmsoTFBJVDggaXQ4LCBzaXplX3Qgc2l6ZSk7CgovLyBDaGVja3MgaWYgYyBpcyBhIHNlcGFyYXRvcgpzdGF0aWMKTENNU0JPT0wgaXNzZXBhcmF0b3IoaW50IGMpCnsKICAgICAgICByZXR1cm4gKGMgPT0gJyAnKSB8fCAoYyA9PSAnXHQnKSB8fCAoYyA9PSAnXHInKTsKfQoKLy8gQ2hlY2tzIHdoYXRldmVyIGlmIGMgaXMgYSB2YWxpZCBpZGVudGlmaWVyIGNoYXIKc3RhdGljCkxDTVNCT09MIGlzbWlkZGxlKGludCBjKQp7CiAgIHJldHVybiAoIWlzc2VwYXJhdG9yKGMpICYmIChjICE9ICcjJykgJiYgKGMgIT0nXCInKSAmJiAoYyAhPSAnXCcnKSAmJiAoYyA+IDMyKSAmJiAoYyA8IDEyNykpOwp9CgovLyBDaGVja3Mgd2hhdHNldmVyIGlmIGMgaXMgYSB2YWxpZCBpZGVudGlmaWVyIG1pZGRsZSBjaGFyLgpzdGF0aWMKTENNU0JPT0wgaXNpZGNoYXIoaW50IGMpCnsKICAgcmV0dXJuIGlzYWxudW0oYykgfHwgaXNtaWRkbGUoYyk7Cn0KCi8vIENoZWNrcyB3aGF0c2V2ZXIgaWYgYyBpcyBhIHZhbGlkIGlkZW50aWZpZXIgZmlyc3QgY2hhci4Kc3RhdGljCkxDTVNCT09MIGlzZmlyc3RpZGNoYXIoaW50IGMpCnsKICAgICByZXR1cm4gIWlzZGlnaXQoYykgJiYgaXNtaWRkbGUoYyk7Cn0KCi8vIGNoZWNrcyB3aGV0aGVyIHRoZSBzdXBwbGllZCBwYXRoIGxvb2tzIGxpa2UgYW4gYWJzb2x1dGUgcGF0aAovLyBOT1RFOiB0aGlzIGZ1bmN0aW9uIGRvZXNuJ3QgY2hlY2tzIGlmIHRoZSBwYXRoIGV4aXN0cyBvciBldmVuIGlmIGl0J3MgbGVnYWwKc3RhdGljCkxDTVNCT09MIGlzYWJzb2x1dGVwYXRoKGNvbnN0IGNoYXIgKnBhdGgpCnsKICAgIGlmKHBhdGggPT0gTlVMTCkKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYocGF0aFswXSA9PSBESVJfQ0hBUikKICAgICAgICByZXR1cm4gVFJVRTsKCiNpZm5kZWYgTk9OX1dJTkRPV1MKICAgIGlmKGlzYWxwaGEocGF0aFswXSkgJiYgcGF0aFsxXSA9PSAnOicpCiAgICAgICAgcmV0dXJuIFRSVUU7CiNlbmRpZgogICAgcmV0dXJuIEZBTFNFOwp9CgovLyBNYWtlcyBhIGZpbGUgcGF0aCBiYXNlZCBvbiBhIGdpdmVuIHJlZmVyZW5jZSBwYXRoCi8vIE5PVEU6IGJ1ZmZlciBpcyBhc3N1bWVkIHRvIHBvaW50IHRvIGF0IGxlYXN0IE1BWF9QQVRIIGJ5dGVzCi8vIE5PVEU6IGJvdGggcmVsUGF0aCBhbmQgYmFzZVBhdGggYXJlIGFzc3VtZWQgdG8gYmUgbm8gbW9yZSB0aGFuIE1BWF9QQVRIIGNoYXJhY3RlcnMgbG9uZyAoaW5jbHVkaW5nIHRoZSBudWxsIHRlcm1pbmF0b3IhKQovLyBOT1RFOiB0aGlzIGZ1bmN0aW9uIGRvZXNuJ3QgY2hlY2sgaWYgdGhlIHBhdGggZXhpc3RzIG9yIGV2ZW4gaWYgaXQncyBsZWdhbApzdGF0aWMKTENNU0JPT0wgX2Ntc01ha2VQYXRoKGNvbnN0IGNoYXIgKnJlbFBhdGgsIGNvbnN0IGNoYXIgKmJhc2VQYXRoLCBjaGFyICpidWZmZXIpCnsKICAgIGlmICghaXNhYnNvbHV0ZXBhdGgocmVsUGF0aCkpIHsKCiAgICAgICAgY2hhciAqdGFpbDsKCiAgICAgICAgc3RybmNweShidWZmZXIsIGJhc2VQYXRoLCBNQVhfUEFUSC0xKTsKICAgICAgICB0YWlsID0gc3RycmNocihidWZmZXIsIERJUl9DSEFSKTsKICAgICAgICBpZiAodGFpbCAhPSBOVUxMKSB7CgogICAgICAgICAgICBzaXplX3QgbGVuID0gdGFpbCAtIGJ1ZmZlcjsKICAgICAgICAgICAgc3RybmNweSh0YWlsICsgMSwgcmVsUGF0aCwgTUFYX1BBVEggLSBsZW4gLTEpOwogICAgICAgICAgICAvLyAgVE9ETzogaWYgY29tYmluZWQgcGF0aCBpcyBsb25nZXIgdGhhbiBNQVhfUEFUSCwgdGhpcyBzaG91bGQgcmV0dXJuIEZBTFNFIQogICAgICAgICAgICByZXR1cm4gVFJVRTsKICAgICAgICB9CiAgICB9CiAgICBzdHJuY3B5KGJ1ZmZlciwgcmVsUGF0aCwgTUFYX1BBVEggLSAxKTsKICAgICAgICBidWZmZXJbTUFYX1BBVEgtMV0gPSAwOwogICAgcmV0dXJuIFRSVUU7Cn0KCgovLyBNYWtlIHN1cmUgbm8gZXhwbG9pdCBpcyBiZWluZyBldmVuIHRyaWVkCgpzdGF0aWMKY29uc3QgY2hhciogTm9NZXRhKGNvbnN0IGNoYXIqIHN0cikKewogICAgaWYgKHN0cmNocihzdHIsICclJykgIT0gTlVMTCkKICAgICAgICByZXR1cm4gIioqKiogQ09SUlVQVEVEIEZPUk1BVCBTVFJJTkcgKioqIjsKCiAgICByZXR1cm4gc3RyOwp9CgoKLy8gU3ludGF4IGVycm9yCnN0YXRpYwpMQ01TQk9PTCBTeW5FcnJvcihMUElUOCBpdDgsIGNvbnN0IGNoYXIgKlR4dCwgLi4uKQp7CiAgICAgICAgY2hhciBCdWZmZXJbMjU2XSwgRXJyTXNnWzEwMjRdOwogICAgICAgIHZhX2xpc3QgYXJnczsKCiAgICAgICAgdmFfc3RhcnQoYXJncywgVHh0KTsKICAgICAgICB2c25wcmludGYoQnVmZmVyLCAyNTUsIFR4dCwgYXJncyk7CiAgICAgICAgQnVmZmVyWzI1NV0gPSAwOwogICAgICAgIHZhX2VuZChhcmdzKTsKCiAgICAgICAgc25wcmludGYoRXJyTXNnLCAxMDIzLCAiJXM6IExpbmUgJWQsICVzIiwgaXQ4LT5GaWxlU3RhY2tbaXQ4IC0+SW5jbHVkZVNQXS0+RmlsZU5hbWUsIGl0OC0+bGluZW5vLCBCdWZmZXIpOwogICAgICAgIEVyck1zZ1sxMDIzXSA9IDA7CiAgICAgICAgaXQ4LT5zeSA9IFNTWU5FUlJPUjsKICAgICAgICBjbXNTaWduYWxFcnJvcihMQ01TX0VSUkNfQUJPUlRFRCwgIiVzIiwgRXJyTXNnKTsKICAgICAgICByZXR1cm4gRkFMU0U7Cn0KCi8vIENoZWNrIGlmIGN1cnJlbnQgc3ltYm9sIGlzIHNhbWUgYXMgc3BlY2lmaWVkLiBpc3N1ZSBhbiBlcnJvciBlbHNlLgpzdGF0aWMKTENNU0JPT0wgQ2hlY2soTFBJVDggaXQ4LCBTWU1CT0wgc3ksIGNvbnN0IGNoYXIqIEVycikKewogICAgICAgIGlmIChpdDggLT4gc3kgIT0gc3kpCiAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCBOb01ldGEoRXJyKSk7CiAgICAgICAgcmV0dXJuIFRSVUU7Cn0KCgoKLy8gUmVhZCBOZXh0IGNoYXJhY3RlciBmcm9tIHN0cmVhbQpzdGF0aWMKdm9pZCBOZXh0Q2goTFBJVDggaXQ4KQp7CiAgICBpZiAoaXQ4IC0+IEZpbGVTdGFja1tpdDggLT5JbmNsdWRlU1BdLT5TdHJlYW0pIHsKCiAgICAgICAgaXQ4IC0+Y2ggPSBmZ2V0YyhpdDggLT5GaWxlU3RhY2tbaXQ4IC0+SW5jbHVkZVNQXS0+U3RyZWFtKTsKCiAgICAgICAgaWYgKGZlb2YoaXQ4IC0+IEZpbGVTdGFja1tpdDggLT5JbmNsdWRlU1BdLT5TdHJlYW0pKSAgewoKICAgICAgICAgICAgaWYgKGl0OCAtPkluY2x1ZGVTUCA+IDApIHsKCiAgICAgICAgICAgICAgICBmY2xvc2UoaXQ4IC0+RmlsZVN0YWNrW2l0OC0+SW5jbHVkZVNQLS1dLT5TdHJlYW0pOwogICAgICAgICAgICAgICAgaXQ4IC0+IGNoID0gJyAnOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGl0ZXNwYWNlIHRvIGJlIGlnbm9yZWQKCiAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgaXQ4IC0+Y2ggPSAwOyAgIC8vIEVPRgogICAgICAgIH0KCgoKICAgIH0KICAgIGVsc2UgewogICAgICAgIGl0OC0+Y2ggPSAqaXQ4LT5Tb3VyY2U7CiAgICAgICAgaWYgKGl0OC0+Y2gpIGl0OC0+U291cmNlKys7CiAgICB9Cn0KCgovLyBUcnkgdG8gc2VlIGlmIGN1cnJlbnQgaWRlbnRpZmllciBpcyBhIGtleXdvcmQsIGlmIHNvIHJldHVybiB0aGUgcmVmZXJyZWQgc3ltYm9sCnN0YXRpYwpTWU1CT0wgQmluU3JjaEtleShjb25zdCBjaGFyICppZCkKewogICAgICAgIGludCBsID0gMTsKICAgICAgICBpbnQgciA9IE5VTUtFWVM7CiAgICAgICAgaW50IHgsIHJlczsKCiAgICAgICAgd2hpbGUgKHIgPj0gbCkKICAgICAgICB7CiAgICAgICAgICAgICAgICB4ID0gKGwrcikvMjsKICAgICAgICAgICAgICAgIHJlcyA9IHN0cmljbXAoaWQsIFRhYktleXNbeC0xXS5pZCk7CiAgICAgICAgICAgICAgICBpZiAocmVzID09IDApIHJldHVybiBUYWJLZXlzW3gtMV0uc3k7CiAgICAgICAgICAgICAgICBpZiAocmVzIDwgMCkgciA9IHggLSAxOwogICAgICAgICAgICAgICAgZWxzZSBsID0geCArIDE7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gU05PTkU7Cn0KCgovLyAxMCBebgpzdGF0aWMKZG91YmxlIHhwb3cxMChpbnQgbikKewogICAgcmV0dXJuIHBvdygxMCwgKGRvdWJsZSkgbik7Cn0KCgovLyAgUmVhZHMgYSBSZWFsIG51bWJlciwgdHJpZXMgdG8gZm9sbG93IGZyb20gaW50ZWdlciBudW1iZXIKc3RhdGljCnZvaWQgUmVhZFJlYWwoTFBJVDggaXQ4LCBpbnQgaW51bSkKewogICAgICAgIGl0OC0+ZG51bSA9IChkb3VibGUpIGludW07CgogICAgICAgIHdoaWxlIChpc2RpZ2l0KGl0OC0+Y2gpKSB7CgogICAgICAgIGl0OC0+ZG51bSA9IGl0OC0+ZG51bSAqIDEwLjAgKyAoaXQ4LT5jaCAtICcwJyk7CiAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXQ4LT5jaCA9PSAnLicpIHsgICAgICAgIC8vIERlY2ltYWwgcG9pbnQKCiAgICAgICAgICAgICAgICBkb3VibGUgZnJhYyA9IDAuMDsgICAgICAvLyBmcmFjdGlvbgogICAgICAgICAgICAgICAgaW50IHByZWMgPSAwOyAgICAgICAgICAgLy8gcHJlY2lzc2lvbgoKICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOyAgICAgICAgICAgICAgIC8vIEVhdHMgZGVjLiBwb2ludAoKICAgICAgICAgICAgICAgIHdoaWxlIChpc2RpZ2l0KGl0OC0+Y2gpKSB7CgogICAgICAgICAgICAgICAgICAgICAgICBmcmFjID0gZnJhYyAqIDEwLjAgKyAoaXQ4LT5jaCAtICcwJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHByZWMrKzsKICAgICAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaXQ4LT5kbnVtID0gaXQ4LT5kbnVtICsgKGZyYWMgLyB4cG93MTAocHJlYykpOwogICAgICAgIH0KCiAgICAgICAgLy8gRXhwb25lbnQsIGV4YW1wbGUgMzQuMDBFKzIwCiAgICAgICAgaWYgKHRvdXBwZXIoaXQ4LT5jaCkgPT0gJ0UnKSB7CgogICAgICAgICAgICAgICAgaW50IGU7CiAgICAgICAgICAgICAgICBpbnQgc2duOwoKICAgICAgICAgICAgICAgIE5leHRDaChpdDgpOyBzZ24gPSAxOwoKICAgICAgICAgICAgICAgIGlmIChpdDgtPmNoID09ICctJykgewoKICAgICAgICAgICAgICAgICAgICAgICAgc2duID0gLTE7IE5leHRDaChpdDgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgaWYgKGl0OC0+Y2ggPT0gJysnKSB7CgogICAgICAgICAgICAgICAgICAgICAgICBzZ24gPSArMTsKICAgICAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgICAgICB9CgoKICAgICAgICAgICAgICAgIGUgPSAwOwogICAgICAgICAgICAgICAgd2hpbGUgKGlzZGlnaXQoaXQ4LT5jaCkpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZG91YmxlKSBlICogMTBMIDwgSU5UX01BWCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUgPSBlICogMTAgKyAoaXQ4LT5jaCAtICcwJyk7CgogICAgICAgICAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBlID0gc2duKmU7CgogICAgICAgICAgICAgICAgaXQ4IC0+IGRudW0gPSBpdDggLT4gZG51bSAqIHhwb3cxMChlKTsKICAgICAgICB9Cn0KCgoKLy8gUmVhZHMgbmV4dCBzeW1ib2wKc3RhdGljCnZvaWQgSW5TeW1ib2woTFBJVDggaXQ4KQp7CiAgICByZWdpc3RlciBjaGFyICppZHB0cjsKICAgIHJlZ2lzdGVyIGludCBrOwogICAgU1lNQk9MIGtleTsKICAgIGludCBzbmc7CgogICAgZG8gewoKICAgICAgICB3aGlsZSAoaXNzZXBhcmF0b3IoaXQ4LT5jaCkpCiAgICAgICAgICAgIE5leHRDaChpdDgpOwoKICAgICAgICBpZiAoaXNmaXJzdGlkY2hhcihpdDgtPmNoKSkgeyAgICAgICAgICAvLyBJZGVudGlmaWVyCgoKICAgICAgICAgICAgayA9IDA7CiAgICAgICAgICAgIGlkcHRyID0gaXQ4LT5pZDsKCiAgICAgICAgICAgIGRvIHsKCiAgICAgICAgICAgICAgICBpZiAoKytrIDwgTUFYSUQpICppZHB0cisrID0gKGNoYXIpIGl0OC0+Y2g7CgogICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CgogICAgICAgICAgICB9IHdoaWxlIChpc2lkY2hhcihpdDgtPmNoKSk7CgogICAgICAgICAgICAqaWRwdHIgPSAnXDAnOwoKCiAgICAgICAgICAgIGtleSA9IEJpblNyY2hLZXkoaXQ4LT5pZCk7CiAgICAgICAgICAgIGlmIChrZXkgPT0gU05PTkUpIGl0OC0+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+Y2g7CgogICAgICAgICAgICAgICAgICAgICAgICBOZXh0Q2goaXQ4KTsKCiAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoaXNpZGNoYXIoaXQ4LT5jaCkpOwoKICAgICAgICAgICAgICAgICAgICAqaWRwdHIgPSAnXDAnOwoKICAgICAgICAgICAgICAgICAgICBpdDgtPnN5ID0gU0lERU5UOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBzd2l0Y2ggKChpbnQpIGl0OC0+Y2gpIHsKCiAgICAgICAgLy8gRU9GIG1hcmtlciAtLSBpZ25vcmUgaXQKICAgICAgICBjYXNlICdceDFhJzoKICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAvLyBFb2Ygc3RyZWFtIG1hcmtlcnMKCiAgICAgICAgY2FzZSAwOgogICAgICAgIGNhc2UgLTE6CiAgICAgICAgICAgIGl0OC0+c3kgPSBTRU9GOwogICAgICAgICAgICBicmVhazsKCgogICAgICAgIC8vIE5leHQgbGluZQoKICAgICAgICBjYXNlICdcbic6CiAgICAgICAgICAgIE5leHRDaChpdDgpOwogICAgICAgICAgICBpdDgtPnN5ID0gU0VPTE47CiAgICAgICAgICAgIGl0OC0+bGluZW5vKys7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAvLyBDb21tZW50CgogICAgICAgIGNhc2UgJyMnOgogICAgICAgICAgICBOZXh0Q2goaXQ4KTsKICAgICAgICAgICAgd2hpbGUgKGl0OC0+Y2ggJiYgaXQ4LT5jaCAhPSAnXG4nKQogICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CgogICAgICAgICAgICBpdDgtPnN5ID0gU0NPTU1FTlQ7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgLy8gU3RyaW5nLgoKICAgICAgICBjYXNlICdcJyc6CiAgICAgICAgY2FzZSAnXCInOgogICAgICAgICAgICBpZHB0ciA9IGl0OC0+c3RyOwogICAgICAgICAgICBzbmcgPSBpdDgtPmNoOwogICAgICAgICAgICBrID0gMDsKICAgICAgICAgICAgTmV4dENoKGl0OCk7CgogICAgICAgICAgICB3aGlsZSAoayA8IE1BWFNUUiAmJiBpdDgtPmNoICE9IHNuZykgewoKICAgICAgICAgICAgICAgIGlmIChpdDgtPmNoID09ICdcbid8fCBpdDgtPmNoID09ICdccicpIGsgPSBNQVhTVFIrMTsKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICppZHB0cisrID0gKGNoYXIpIGl0OC0+Y2g7CiAgICAgICAgICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgICAgICAgICAgaysrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpdDgtPnN5ID0gU1NUUklORzsKICAgICAgICAgICAgKmlkcHRyID0gJ1wwJzsKICAgICAgICAgICAgTmV4dENoKGl0OCk7CiAgICAgICAgICAgIGJyZWFrOwoKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgU3luRXJyb3IoaXQ4LCAiVW5yZWNvZ25pemVkIGNoYXJhY3RlcjogMHgleCIsIGl0OCAtPmNoKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgfSB3aGlsZSAoaXQ4LT5zeSA9PSBTQ09NTUVOVCk7CgogICAgLy8gSGFuZGxlIHRoZSBpbmNsdWRlIHNwZWNpYWwgdG9rZW4KCiAgICBpZiAoaXQ4IC0+IHN5ID09IFNJTkNMVURFKSB7CgogICAgICAgICAgICAgICAgTFBGSUxFQ1RYIEZpbGVOZXN0OwoKICAgICAgICAgICAgICAgIGlmKGl0OCAtPiBJbmNsdWRlU1AgPj0gKE1BWElOQ0xVREUtMSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgU3luRXJyb3IoaXQ4LCAiVG9vIG1hbnkgcmVjdXJzaW9uIGxldmVscyIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgaWYgKCFDaGVjayhpdDgsIFNTVFJJTkcsICJGaWxlbmFtZSBleHBlY3RlZCIpKSByZXR1cm47CgogICAgICAgICAgICAgICAgRmlsZU5lc3QgPSBpdDggLT4gRmlsZVN0YWNrW2l0OCAtPiBJbmNsdWRlU1AgKyAxXTsKICAgICAgICAgICAgICAgIGlmKEZpbGVOZXN0ID09IE5VTEwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRmlsZU5lc3QgPSBpdDggLT5GaWxlU3RhY2tbaXQ4IC0+IEluY2x1ZGVTUCArIDFdID0gKExQRklMRUNUWClBbGxvY0NodW5rKGl0OCwgc2l6ZW9mKEZJTEVDVFgpKTsKICAgICAgICAgICAgICAgICAgICAvL2lmKEZpbGVOZXN0ID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vICBUT0RPOiBob3cgdG8gbWFuYWdlIG91dC1vZi1tZW1vcnkgY29uZGl0aW9ucz8KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZihfY21zTWFrZVBhdGgoaXQ4LT5zdHIsIGl0OC0+RmlsZVN0YWNrW2l0OC0+SW5jbHVkZVNQXS0+RmlsZU5hbWUsIEZpbGVOZXN0LT5GaWxlTmFtZSkgPT0gRkFMU0UpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgU3luRXJyb3IoaXQ4LCAiRmlsZSBwYXRoIHRvbyBsb25nIik7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEZpbGVOZXN0LT5TdHJlYW0gPSBmb3BlbihGaWxlTmVzdC0+RmlsZU5hbWUsICJydCIpOwogICAgICAgICAgICAgICAgaWYgKEZpbGVOZXN0LT5TdHJlYW0gPT0gTlVMTCkgewoKICAgICAgICAgICAgICAgICAgICAgICAgU3luRXJyb3IoaXQ4LCAiRmlsZSAlcyBub3QgZm91bmQiLCBGaWxlTmVzdC0+RmlsZU5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpdDgtPkluY2x1ZGVTUCsrOwoKICAgICAgICAgICAgICAgIGl0OCAtPmNoID0gJyAnOwogICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgIH0KCn0KCi8vIENoZWNrcyBlbmQgb2YgbGluZSBzZXBhcmF0b3IKc3RhdGljCkxDTVNCT09MIENoZWNrRU9MTihMUElUOCBpdDgpCnsKICAgICAgICBpZiAoIUNoZWNrKGl0OCwgU0VPTE4sICJFeHBlY3RlZCBzZXBhcmF0b3IiKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIHdoaWxlIChpdDggLT4gc3kgPT0gU0VPTE4pCiAgICAgICAgICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgcmV0dXJuIFRSVUU7Cgp9CgovLyBTa2lwIGEgc3ltYm9sCgpzdGF0aWMKdm9pZCBTa2lwKExQSVQ4IGl0OCwgU1lNQk9MIHN5KQp7CiAgICAgICAgaWYgKGl0OC0+c3kgPT0gc3kgJiYgaXQ4LT5zeSAhPSBTRU9GKQogICAgICAgICAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwp9CgoKLy8gU2tpcCBtdWx0aXBsZSBFT0xOCnN0YXRpYwp2b2lkIFNraXBFT0xOKExQSVQ4IGl0OCkKewogICAgd2hpbGUgKGl0OC0+c3kgPT0gU0VPTE4pIHsKICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICB9Cn0KCgovLyBSZXR1cm5zIGEgc3RyaW5nIGhvbGRpbmcgY3VycmVudCB2YWx1ZQpzdGF0aWMKTENNU0JPT0wgR2V0VmFsKExQSVQ4IGl0OCwgY2hhciogQnVmZmVyLCBzaXplX3QgbWF4LCBjb25zdCBjaGFyKiBFcnJvclRpdGxlKQp7CiAgICBzd2l0Y2ggKGl0OC0+c3kpIHsKCiAgICBjYXNlIFNJREVOVDogIHN0cm5jcHkoQnVmZmVyLCBpdDgtPmlkLCBtYXgpOwogICAgICAgICAgICAgICAgICBCdWZmZXJbbWF4LTFdPTA7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgY2FzZSBTSU5VTTogICBzbnByaW50ZihCdWZmZXIsIG1heCwgIiVkIiwgaXQ4IC0+IGludW0pOyBicmVhazsKICAgIGNhc2UgU0ROVU06ICAgc25wcmludGYoQnVmZmVyLCBtYXgsIGl0OC0+RG91YmxlRm9ybWF0dGVyLCBpdDggLT4gZG51bSk7IGJyZWFrOwogICAgY2FzZSBTU1RSSU5HOiBzdHJuY3B5KEJ1ZmZlciwgaXQ4LT5zdHIsIG1heCk7CiAgICAgICAgICAgICAgICAgIEJ1ZmZlclttYXgtMV0gPSAwOwogICAgICAgICAgICAgICAgICBicmVhazsKCgogICAgZGVmYXVsdDoKICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIiVzIiwgRXJyb3JUaXRsZSk7CiAgICB9CgogICAgQnVmZmVyW21heF0gPSAwOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVGFibGUKCnN0YXRpYwpMUFRBQkxFIEdldFRhYmxlKExQSVQ4IGl0OCkKewogICBpZiAoKGl0OCAtPiBuVGFibGUgPj0gaXQ4IC0+VGFibGVzQ291bnQpIHx8IChpdDggLT4gblRhYmxlIDwgMCkpIHsKCiAgICAgICAgICAgU3luRXJyb3IoaXQ4LCAiVGFibGUgJWQgb3V0IG9mIHNlcXVlbmNlIiwgaXQ4IC0+IG5UYWJsZSk7CiAgICAgICAgICAgcmV0dXJuIGl0OCAtPiBUYWI7CiAgIH0KCiAgIHJldHVybiBpdDggLT5UYWIgKyBpdDggLT5uVGFibGU7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gTWVtb3J5IG1hbmFnZW1lbnQKCgoKLy8gRnJlZXMgYW4gYWxsb2NhdG9yIGFuZCBvd25lZCBtZW1vcnkKdm9pZCBMQ01TRVhQT1JUIGNtc0lUOEZyZWUoTENNU0hBTkRMRSBoSVQ4KQp7CiAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKCiAgICBpZiAoaXQ4ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKCiAgICBpZiAoaXQ4LT5NZW1vcnlTaW5rKSB7CgogICAgICAgIExQT1dORURNRU0gcDsKICAgICAgICBMUE9XTkVETUVNIG47CgogICAgICAgIGZvciAocCA9IGl0OC0+TWVtb3J5U2luazsgcCAhPSBOVUxMOyBwID0gbikgewoKICAgICAgICAgICAgbiA9IHAtPk5leHQ7CiAgICAgICAgICAgIGlmIChwLT5QdHIpIF9jbXNGcmVlKHAtPlB0cik7CiAgICAgICAgICAgIF9jbXNGcmVlKHApOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoaXQ4LT5NZW1vcnlCbG9jaykKICAgICAgICBfY21zRnJlZShpdDgtPk1lbW9yeUJsb2NrKTsKCiAgICAgX2Ntc0ZyZWUoaXQ4KTsKfQoKCi8vIEFsbG9jYXRlcyBhIGNodW5rIG9mIGRhdGEsIGtlZXAgbGlua2VkIGxpc3QKc3RhdGljCnZvaWQqIEFsbG9jQmlnQmxvY2soTFBJVDggaXQ4LCBzaXplX3Qgc2l6ZSkKewogICBMUE9XTkVETUVNIHB0cjE7CiAgIHZvaWQqIHB0ciA9IF9jbXNNYWxsb2Moc2l6ZSk7CgogICAgICAgIGlmIChwdHIpIHsKCiAgICAgICAgICAgICAgICBaZXJvTWVtb3J5KHB0ciwgc2l6ZSk7CiAgICAgICAgICAgICAgICBwdHIxID0gKExQT1dORURNRU0pIF9jbXNNYWxsb2Moc2l6ZW9mKE9XTkVETUVNKSk7CgogICAgICAgICAgICAgICAgaWYgKHB0cjEgPT0gTlVMTCkgewoKICAgICAgICAgICAgICAgICAgICAgX2Ntc0ZyZWUocHRyKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBaZXJvTWVtb3J5KHB0cjEsIHNpemVvZihPV05FRE1FTSkpOwoKICAgICAgICAgICAgICAgIHB0cjEtPiBQdHIgICAgICAgID0gcHRyOwogICAgICAgICAgICAgICAgcHRyMS0+IE5leHQgICAgICAgPSBpdDggLT4gTWVtb3J5U2luazsKICAgICAgICAgICAgICAgIGl0OCAtPiBNZW1vcnlTaW5rID0gcHRyMTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBwdHI7Cn0KCgovLyBTdWJhbGxvY2F0b3IuCnN0YXRpYwp2b2lkKiBBbGxvY0NodW5rKExQSVQ4IGl0OCwgc2l6ZV90IHNpemUpCnsKICAgIHNpemVfdCBmcmVlID0gaXQ4IC0+QWxsb2NhdG9yLkJsb2NrU2l6ZSAtIGl0OCAtPkFsbG9jYXRvci5Vc2VkOwogICAgTFBCWVRFIHB0cjsKCiAgICBzaXplID0gQUxJR05MT05HKHNpemUpOwoKICAgIGlmIChzaXplID4gZnJlZSkgewoKICAgICAgICBpZiAoaXQ4IC0+IEFsbG9jYXRvci5CbG9ja1NpemUgPT0gMCkKCiAgICAgICAgICAgICAgICBpdDggLT4gQWxsb2NhdG9yLkJsb2NrU2l6ZSA9IDIwKjEwMjQ7CiAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgaXQ4IC0+QWxsb2NhdG9yLkJsb2NrU2l6ZSAqPSAyOwoKICAgICAgICBpZiAoaXQ4IC0+QWxsb2NhdG9yLkJsb2NrU2l6ZSA8IHNpemUpCiAgICAgICAgICAgICAgICBpdDggLT5BbGxvY2F0b3IuQmxvY2tTaXplID0gc2l6ZTsKCiAgICAgICAgaXQ4IC0+QWxsb2NhdG9yLlVzZWQgPSAwOwogICAgICAgIGl0OCAtPkFsbG9jYXRvci5CbG9jayA9IChMUEJZVEUpIEFsbG9jQmlnQmxvY2soaXQ4LCBpdDggLT5BbGxvY2F0b3IuQmxvY2tTaXplKTsKICAgIH0KCiAgICBwdHIgPSBpdDggLT5BbGxvY2F0b3IuQmxvY2sgKyBpdDggLT5BbGxvY2F0b3IuVXNlZDsKICAgIGl0OCAtPkFsbG9jYXRvci5Vc2VkICs9IHNpemU7CgogICAgcmV0dXJuICh2b2lkKikgcHRyOwoKfQoKCi8vIEFsbG9jYXRlcyBhIHN0cmluZwpzdGF0aWMKY2hhciAqQWxsb2NTdHJpbmcoTFBJVDggaXQ4LCBjb25zdCBjaGFyKiBzdHIpCnsKICAgIHNpemVfdCBTaXplID0gc3RybGVuKHN0cikrMTsKICAgIGNoYXIgKnB0cjsKCgogICAgcHRyID0gKGNoYXIgKikgQWxsb2NDaHVuayhpdDgsIFNpemUpOwogICAgaWYgKHB0cikgc3RybmNweSAocHRyLCBzdHIsIFNpemUtMSk7CgogICAgcmV0dXJuIHB0cjsKfQoKLy8gU2VhcmNoZXMgdGhyb3VnaCBsaW5rZWQgbGlzdAoKc3RhdGljCkxDTVNCT09MIElzQXZhaWxhYmxlT25MaXN0KExQS0VZVkFMVUUgcCwgY29uc3QgY2hhciogS2V5LCBjb25zdCBjaGFyKiBTdWJrZXksIExQS0VZVkFMVUUqIExhc3RQdHIpCnsKICAgIGlmIChMYXN0UHRyKSAqTGFzdFB0ciA9IHA7CgogICAgZm9yICg7ICBwICE9IE5VTEw7IHAgPSBwLT5OZXh0KSB7CgogICAgICAgIGlmIChMYXN0UHRyKSAqTGFzdFB0ciA9IHA7CgogICAgICAgIGlmICgqS2V5ICE9ICcjJykgeyAvLyBDb21tZW50cyBhcmUgaWdub3JlZAoKICAgICAgICAgICAgaWYgKHN0cmljbXAoS2V5LCBwLT5LZXl3b3JkKSA9PSAwKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICB9CgogICAgaWYgKHAgPT0gTlVMTCkKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKFN1YmtleSA9PSAwKQogICAgICAgIHJldHVybiBUUlVFOwoKICAgIGZvciAoOyBwICE9IE5VTEw7IHAgPSBwLT5OZXh0U3Via2V5KSB7CgogICAgICAgIGlmIChMYXN0UHRyKSAqTGFzdFB0ciA9IHA7CgogICAgICAgIGlmIChzdHJpY21wKFN1YmtleSwgcC0+U3Via2V5KSA9PSAwKQogICAgICAgICAgICByZXR1cm4gVFJVRTsKICAgIH0KCiAgICByZXR1cm4gRkFMU0U7Cn0KCgoKLy8gQWRkIGEgcHJvcGVydHkgaW50byBhIGxpbmtlZCBsaXN0CnN0YXRpYwpMUEtFWVZBTFVFIEFkZFRvTGlzdChMUElUOCBpdDgsIExQS0VZVkFMVUUqIEhlYWQsIGNvbnN0IGNoYXIgKktleSwgY29uc3QgY2hhciAqU3Via2V5LCBjb25zdCBjaGFyKiB4VmFsdWUsIFdSSVRFTU9ERSBXcml0ZUFzKQp7CiAgICBMUEtFWVZBTFVFIHA7CgogICAgLy8gQ2hlY2sgaWYgcHJvcGVydHkgaXMgYWxyZWFkeSBpbiBsaXN0ICh0aGlzIGlzIGFuIGVycm9yKQoKICAgIGlmIChJc0F2YWlsYWJsZU9uTGlzdCgqSGVhZCwgS2V5LCBTdWJrZXksICZwKSkgewoKICAgICAgICAgICAgLy8gVGhpcyBtYXkgd29yayBmb3IgZWRpdGluZyBwcm9wZXJ0aWVzCgogICAgICAgIC8vICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiZHVwbGljYXRlIGtleSA8JXM+IiwgS2V5KTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIExQS0VZVkFMVUUgbGFzdCA9IHA7CgogICAgLy8gQWxsb2NhdGUgdGhlIGNvbnRhaW5lcgogICAgcCA9IChMUEtFWVZBTFVFKSBBbGxvY0NodW5rKGl0OCwgc2l6ZW9mKEtFWVZBTFVFKSk7CiAgICBpZiAocCA9PSBOVUxMKQogICAgewogICAgICAgICAgICBTeW5FcnJvcihpdDgsICJBZGRUb0xpc3Q6IG91dCBvZiBtZW1vcnkiKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLy8gU3RvcmUgbmFtZSBhbmQgdmFsdWUKICAgIHAtPktleXdvcmQgPSBBbGxvY1N0cmluZyhpdDgsIEtleSk7CiAgICAgICAgcC0+U3Via2V5ID0gKFN1YmtleSA9PSBOVUxMKSA/IE5VTEwgOiBBbGxvY1N0cmluZyhpdDgsIFN1YmtleSk7CgogICAgICAgIC8vIEtlZXAgdGhlIGNvbnRhaW5lciBpbiBvdXIgbGlzdAogICAgICAgIGlmICgqSGVhZCA9PSBOVUxMKQogICAgICAgICAgICAqSGVhZCA9IHA7CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYoU3Via2V5ICE9IDAgJiYgbGFzdCAhPSAwKSB7CiAgICAgICAgICAgICAgICBsYXN0LT5OZXh0U3Via2V5ID0gcDsKCiAgICAgICAgICAgICAgICAvLyBJZiBTdWJrZXkgaXMgbm90IG51bGwsIHRoZW4gbGFzdCBpcyB0aGUgbGFzdCBwcm9wZXJ0eSB3aXRoIHRoZSBzYW1lIGtleSwKICAgICAgICAgICAgICAgIC8vIGJ1dCBub3QgbmVjZXNzYXJpbHkgaXMgdGhlIGxhc3QgcHJvcGVydHkgaW4gdGhlIGxpc3QsIHNvIHdlIG5lZWQgdG8gbW92ZQogICAgICAgICAgICAgICAgLy8gdG8gdGhlIGFjdHVhbCBsaXN0IGVuZAogICAgICAgICAgICAgICAgd2hpbGUobGFzdC0+TmV4dCAhPSAwKQogICAgICAgICAgICAgICAgICAgIGxhc3QgPSBsYXN0LT5OZXh0OwogICAgfQogICAgICAgICAgICBsYXN0LT5OZXh0ID0gcDsKICAgIH0KCiAgICBwLT5OZXh0ICAgID0gTlVMTDsKICAgICAgICBwLT5OZXh0U3Via2V5ID0gTlVMTDsKICAgIH0KCiAgICBwLT5Xcml0ZUFzID0gV3JpdGVBczsKICAgIGlmICh4VmFsdWUgIT0gTlVMTCkgewoKICAgICAgICBwLT5WYWx1ZSAgID0gQWxsb2NTdHJpbmcoaXQ4LCB4VmFsdWUpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgcC0+VmFsdWUgICA9IE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHA7Cn0KCnN0YXRpYwpMUEtFWVZBTFVFIEFkZEF2YWlsYWJsZVByb3BlcnR5KExQSVQ4IGl0OCwgY29uc3QgY2hhciogS2V5LCBXUklURU1PREUgYXMpCnsKICAgICAgICByZXR1cm4gQWRkVG9MaXN0KGl0OCwgJml0OC0+VmFsaWRLZXl3b3JkcywgS2V5LCBOVUxMLCBOVUxMLCBhcyk7Cn0KCgpzdGF0aWMKTFBLRVlWQUxVRSBBZGRBdmFpbGFibGVTYW1wbGVJRChMUElUOCBpdDgsIGNvbnN0IGNoYXIqIEtleSkKewogICAgICAgIHJldHVybiBBZGRUb0xpc3QoaXQ4LCAmaXQ4LT5WYWxpZFNhbXBsZUlELCBLZXksIE5VTEwsIE5VTEwsIFdSSVRFX1VOQ09PS0VEKTsKfQoKCnN0YXRpYwp2b2lkIEFsbG9jVGFibGUoTFBJVDggaXQ4KQp7CiAgICBMUFRBQkxFIHQ7CgogICAgdCA9IGl0OCAtPlRhYiArIGl0OCAtPlRhYmxlc0NvdW50OwoKICAgIHQtPkhlYWRlckxpc3QgPSBOVUxMOwogICAgdC0+RGF0YUZvcm1hdCA9IE5VTEw7CiAgICB0LT5EYXRhICAgICAgID0gTlVMTDsKCiAgICBpdDggLT5UYWJsZXNDb3VudCsrOwp9CgoKaW50IExDTVNFWFBPUlQgY21zSVQ4U2V0VGFibGUoTENNU0hBTkRMRSBJVDgsIGludCBuVGFibGUpCnsKICAgICBMUElUOCBpdDggPSAoTFBJVDgpIElUODsKCiAgICAgaWYgKG5UYWJsZSA+PSBpdDggLT5UYWJsZXNDb3VudCkgewoKICAgICAgICAgaWYgKG5UYWJsZSA9PSBpdDggLT5UYWJsZXNDb3VudCkgewoKICAgICAgICAgICAgIEFsbG9jVGFibGUoaXQ4KTsKICAgICAgICAgfQogICAgICAgICBlbHNlIHsKICAgICAgICAgICAgIFN5bkVycm9yKGl0OCwgIlRhYmxlICVkIGlzIG91dCBvZiBzZXF1ZW5jZSIsIG5UYWJsZSk7CiAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgIH0KICAgICB9CgogICAgIGl0OCAtPm5UYWJsZSA9IG5UYWJsZTsKCiAgICAgcmV0dXJuIG5UYWJsZTsKfQoKCgovLyBJbml0IGFuIGVtcHR5IGNvbnRhaW5lcgpMQ01TSEFORExFIExDTVNFWFBPUlQgY21zSVQ4QWxsb2Modm9pZCkKewogICAgTFBJVDggaXQ4OwogICAgaW50IGk7CgogICAgaXQ4ID0gKExQSVQ4KSBtYWxsb2Moc2l6ZW9mKElUOCkpOwogICAgaWYgKGl0OCA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBaZXJvTWVtb3J5KGl0OCwgc2l6ZW9mKElUOCkpOwoKICAgIEFsbG9jVGFibGUoaXQ4KTsKCiAgICBpdDgtPk1lbW9yeUJsb2NrID0gTlVMTDsKICAgIGl0OC0+TWVtb3J5U2luayAgPSBOVUxMOwoKICAgIGl0OCAtPm5UYWJsZSA9IDA7CgogICAgaXQ4LT5BbGxvY2F0b3IuVXNlZCA9IDA7CiAgICBpdDgtPkFsbG9jYXRvci5CbG9jayA9IE5VTEw7CiAgICBpdDgtPkFsbG9jYXRvci5CbG9ja1NpemUgPSAwOwoKICAgIGl0OC0+VmFsaWRLZXl3b3JkcyA9IE5VTEw7CiAgICBpdDgtPlZhbGlkU2FtcGxlSUQgPSBOVUxMOwoKICAgIGl0OCAtPiBzeSA9IFNOT05FOwogICAgaXQ4IC0+IGNoID0gJyAnOwogICAgaXQ4IC0+IFNvdXJjZSA9IE5VTEw7CiAgICBpdDggLT4gaW51bSA9IDA7CiAgICBpdDggLT4gZG51bSA9IDAuMDsKCiAgICBpdDgtPkZpbGVTdGFja1swXSA9IChMUEZJTEVDVFgpQWxsb2NDaHVuayhpdDgsIHNpemVvZihGSUxFQ1RYKSk7CiAgICBpdDgtPkluY2x1ZGVTUCAgID0gMDsKICAgIGl0OCAtPiBsaW5lbm8gPSAxOwoKICAgIHN0cmNweShpdDgtPkRvdWJsZUZvcm1hdHRlciwgREVGQVVMVF9EQkxfRk9STUFUKTsKICAgIHN0cmNweShpdDgtPlNoZWV0VHlwZSwgIkNHQVRTLjE3Iik7CgogICAgLy8gSW5pdGlhbGl6ZSBwcmVkZWZpbmVkIHByb3BlcnRpZXMgJiBkYXRhCgogICAgZm9yIChpPTA7IGkgPCBOVU1QUkVERUZJTkVEUFJPUFM7IGkrKykKICAgICAgICAgICAgQWRkQXZhaWxhYmxlUHJvcGVydHkoaXQ4LCBQcmVkZWZpbmVkUHJvcGVydGllc1tpXS5pZCwgUHJlZGVmaW5lZFByb3BlcnRpZXNbaV0uYXMpOwoKICAgIGZvciAoaT0wOyBpIDwgTlVNUFJFREVGSU5FRFNBTVBMRUlEOyBpKyspCiAgICAgICAgICAgIEFkZEF2YWlsYWJsZVNhbXBsZUlEKGl0OCwgUHJlZGVmaW5lZFNhbXBsZUlEW2ldKTsKCgogICByZXR1cm4gKExDTVNIQU5ETEUpIGl0ODsKfQoKCmNvbnN0IGNoYXIqIExDTVNFWFBPUlQgY21zSVQ4R2V0U2hlZXRUeXBlKExDTVNIQU5ETEUgaElUOCkKewogICAgICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKCiAgICAgICAgcmV0dXJuIGl0OCAtPlNoZWV0VHlwZTsKCn0KCkxDTVNCT09MICBMQ01TRVhQT1JUIGNtc0lUOFNldFNoZWV0VHlwZShMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIFR5cGUpCnsKICAgICAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CgogICAgICAgIHN0cm5jcHkoaXQ4IC0+U2hlZXRUeXBlLCBUeXBlLCBNQVhTVFItMSk7CiAgICAgICAgaXQ4IC0+U2hlZXRUeXBlW01BWFNUUi0xXSA9IDA7CiAgICAgICAgcmV0dXJuIFRSVUU7Cn0KCkxDTVNCT09MIExDTVNFWFBPUlQgY21zSVQ4U2V0Q29tbWVudChMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIFZhbCkKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwoKICAgIGlmICghVmFsKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoISpWYWwpIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gQWRkVG9MaXN0KGl0OCwgJkdldFRhYmxlKGl0OCktPkhlYWRlckxpc3QsICIjICIsIE5VTEwsIFZhbCwgV1JJVEVfVU5DT09LRUQpICE9IE5VTEw7Cn0KCgoKLy8gU2V0cyBhIHByb3BlcnR5CkxDTVNCT09MIExDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlTdHIoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBLZXksIGNvbnN0IGNoYXIgKlZhbCkKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwoKICAgIGlmICghVmFsKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoISpWYWwpIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gQWRkVG9MaXN0KGl0OCwgJkdldFRhYmxlKGl0OCktPkhlYWRlckxpc3QsIEtleSwgTlVMTCwgVmFsLCBXUklURV9TVFJJTkdJRlkpICE9IE5VTEw7Cn0KCgpMQ01TQk9PTCBMQ01TRVhQT1JUIGNtc0lUOFNldFByb3BlcnR5RGJsKExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1Byb3AsIGRvdWJsZSBWYWwpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKICAgIGNoYXIgQnVmZmVyWzEwMjRdOwoKICAgIHNwcmludGYoQnVmZmVyLCBpdDgtPkRvdWJsZUZvcm1hdHRlciwgVmFsKTsKCiAgICByZXR1cm4gQWRkVG9MaXN0KGl0OCwgJkdldFRhYmxlKGl0OCktPkhlYWRlckxpc3QsIGNQcm9wLCBOVUxMLCBCdWZmZXIsIFdSSVRFX1VOQ09PS0VEKSAhPSBOVUxMOwp9CgpMQ01TQk9PTCBMQ01TRVhQT1JUIGNtc0lUOFNldFByb3BlcnR5SGV4KExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1Byb3AsIGludCBWYWwpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKICAgIGNoYXIgQnVmZmVyWzEwMjRdOwoKICAgIHNwcmludGYoQnVmZmVyLCAiJWQiLCBWYWwpOwoKICAgIHJldHVybiBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgY1Byb3AsIE5VTEwsIEJ1ZmZlciwgV1JJVEVfSEVYQURFQ0lNQUwpICE9IE5VTEw7Cn0KCkxDTVNCT09MIExDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlVbmNvb2tlZChMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIEtleSwgY29uc3QgY2hhciogQnVmZmVyKQp7CiAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CgogICAgcmV0dXJuIEFkZFRvTGlzdChpdDgsICZHZXRUYWJsZShpdDgpLT5IZWFkZXJMaXN0LCBLZXksIE5VTEwsIEJ1ZmZlciwgV1JJVEVfVU5DT09LRUQpICE9IE5VTEw7Cn0KCkxDTVNCT09MIExDTVNFWFBPUlQgY21zSVQ4U2V0UHJvcGVydHlNdWx0aShMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIEtleSwgY29uc3QgY2hhciogU3ViS2V5LCBjb25zdCBjaGFyICpCdWZmZXIpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKCiAgICByZXR1cm4gQWRkVG9MaXN0KGl0OCwgJkdldFRhYmxlKGl0OCktPkhlYWRlckxpc3QsIEtleSwgU3ViS2V5LCBCdWZmZXIsIFdSSVRFX1BBSVIpICE9IE5VTEw7Cn0KCi8vIEdldHMgYSBwcm9wZXJ0eQpjb25zdCBjaGFyKiBMQ01TRVhQT1JUIGNtc0lUOEdldFByb3BlcnR5KExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogS2V5KQp7CiAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CiAgICBMUEtFWVZBTFVFIHA7CgogICAgaWYgKElzQXZhaWxhYmxlT25MaXN0KEdldFRhYmxlKGl0OCkgLT4gSGVhZGVyTGlzdCwgS2V5LCBOVUxMLCAmcCkpCiAgICB7CiAgICAgICAgcmV0dXJuIHAgLT4gVmFsdWU7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKCmRvdWJsZSBMQ01TRVhQT1JUIGNtc0lUOEdldFByb3BlcnR5RGJsKExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1Byb3ApCnsKICAgIGNvbnN0IGNoYXIgKnYgPSBjbXNJVDhHZXRQcm9wZXJ0eShoSVQ4LCBjUHJvcCk7CgogICAgaWYgKHYpIHJldHVybiBhdG9mKHYpOwogICAgZWxzZSByZXR1cm4gMC4wOwp9Cgpjb25zdCBjaGFyKiBMQ01TRVhQT1JUIGNtc0lUOEdldFByb3BlcnR5TXVsdGkoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBLZXksIGNvbnN0IGNoYXIgKlN1YktleSkKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgTFBLRVlWQUxVRSBwOwoKICAgIGlmIChJc0F2YWlsYWJsZU9uTGlzdChHZXRUYWJsZShpdDgpIC0+IEhlYWRlckxpc3QsIEtleSwgU3ViS2V5LCAmcCkpCiAgICB7CiAgICAgICAgcmV0dXJuIHAgLT4gVmFsdWU7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRGF0YXNldHMKCgpzdGF0aWMKdm9pZCBBbGxvY2F0ZURhdGFGb3JtYXQoTFBJVDggaXQ4KQp7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGlmICh0IC0+IERhdGFGb3JtYXQpIHJldHVybjsgICAgLy8gQWxyZWFkeSBhbGxvY2F0ZWQKCiAgICB0IC0+IG5TYW1wbGVzICA9IChpbnQpIGNtc0lUOEdldFByb3BlcnR5RGJsKGl0OCwgIk5VTUJFUl9PRl9GSUVMRFMiKTsKCiAgICBpZiAodCAtPiBuU2FtcGxlcyA8PSAwKSB7CgogICAgICAgIFN5bkVycm9yKGl0OCwgIkFsbG9jYXRlRGF0YUZvcm1hdDogVW5rbm93biBOVU1CRVJfT0ZfRklFTERTIik7CiAgICAgICAgdCAtPiBuU2FtcGxlcyA9IDEwOwogICAgICAgIH0KCiAgICB0IC0+IERhdGFGb3JtYXQgPSAoY2hhcioqKSBBbGxvY0NodW5rIChpdDgsICh0LT5uU2FtcGxlcyArIDEpICogc2l6ZW9mKGNoYXIgKikpOwogICAgaWYgKHQtPkRhdGFGb3JtYXQgPT0gTlVMTCkKICAgIHsKICAgICAgICBTeW5FcnJvcihpdDgsICJBbGxvY2F0ZURhdGFGb3JtYXQ6IFVuYWJsZSB0byBhbGxvY2F0ZSBkYXRhRm9ybWF0IGFycmF5Iik7CiAgICB9Cgp9CgpzdGF0aWMKY29uc3QgY2hhciAqR2V0RGF0YUZvcm1hdChMUElUOCBpdDgsIGludCBuKQp7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGlmICh0LT5EYXRhRm9ybWF0KQogICAgICAgIHJldHVybiB0LT5EYXRhRm9ybWF0W25dOwoKICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMKTENNU0JPT0wgU2V0RGF0YUZvcm1hdChMUElUOCBpdDgsIGludCBuLCBjb25zdCBjaGFyICpsYWJlbCkKewogICAgTFBUQUJMRSB0ID0gR2V0VGFibGUoaXQ4KTsKCiNpZmRlZiAgU1RSSUNUX0NHQVRTCiAgICBpZiAoIUlzQXZhaWxhYmxlT25MaXN0KGl0OC0+IFZhbGlkU2FtcGxlSUQsIGxhYmVsLCBOVUxMLCBOVUxMKSkgewogICAgICAgIFN5bkVycm9yKGl0OCwgIkludmFsaWQgZGF0YSBmb3JtYXQgJyVzJy4iLCBsYWJlbCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQojZW5kaWYKCiAgICBpZiAoIXQtPkRhdGFGb3JtYXQpCiAgICAgICAgQWxsb2NhdGVEYXRhRm9ybWF0KGl0OCk7CgogICAgaWYgKG4gPiB0IC0+IG5TYW1wbGVzKSB7CiAgICAgICAgU3luRXJyb3IoaXQ4LCAiTW9yZSB0aGFuIE5VTUJFUl9PRl9GSUVMRFMgZmllbGRzLiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCgogICAgaWYgKHQtPkRhdGFGb3JtYXQpIHsKICAgICAgICB0LT5EYXRhRm9ybWF0W25dID0gQWxsb2NTdHJpbmcoaXQ4LCBsYWJlbCk7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCgpMQ01TQk9PTCBMQ01TRVhQT1JUIGNtc0lUOFNldERhdGFGb3JtYXQoTENNU0hBTkRMRSBoLCBpbnQgbiwgY29uc3QgY2hhciAqU2FtcGxlKQp7CiAgICAgICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoOwogICAgICAgIHJldHVybiBTZXREYXRhRm9ybWF0KGl0OCwgbiwgU2FtcGxlKTsKfQoKc3RhdGljCnZvaWQgQWxsb2NhdGVEYXRhU2V0KExQSVQ4IGl0OCkKewogICAgTFBUQUJMRSB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBpZiAodCAtPiBEYXRhKSByZXR1cm47ICAgIC8vIEFscmVhZHkgYWxsb2NhdGVkCgogICAgdC0+IG5TYW1wbGVzICAgPSBhdG9pKGNtc0lUOEdldFByb3BlcnR5KGl0OCwgIk5VTUJFUl9PRl9GSUVMRFMiKSk7CiAgICB0LT4gblBhdGNoZXMgICA9IGF0b2koY21zSVQ4R2V0UHJvcGVydHkoaXQ4LCAiTlVNQkVSX09GX1NFVFMiKSk7CgogICAgdC0+IERhdGEgPSAoY2hhcioqKUFsbG9jQ2h1bmsgKGl0OCwgKHQtPm5TYW1wbGVzICsgMSkgKiAodC0+blBhdGNoZXMgKyAxKSAqc2l6ZW9mIChjaGFyKikpOwogICAgaWYgKHQtPkRhdGEgPT0gTlVMTCkKICAgIHsKICAgICAgICBTeW5FcnJvcihpdDgsICJBbGxvY2F0ZURhdGFTZXQ6IFVuYWJsZSB0byBhbGxvY2F0ZSBkYXRhIGFycmF5Iik7CiAgICB9Cgp9CgpzdGF0aWMKY2hhciogR2V0RGF0YShMUElUOCBpdDgsIGludCBuU2V0LCBpbnQgbkZpZWxkKQp7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwogICAgaW50ICBuU2FtcGxlcyAgID0gdCAtPiBuU2FtcGxlczsKICAgIGludCAgblBhdGNoZXMgICA9IHQgLT4gblBhdGNoZXM7CgoKICAgIGlmIChuU2V0ID49IG5QYXRjaGVzIHx8IG5GaWVsZCA+PSBuU2FtcGxlcykKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBpZiAoIXQtPkRhdGEpIHJldHVybiBOVUxMOwogICAgcmV0dXJuIHQtPkRhdGEgW25TZXQgKiBuU2FtcGxlcyArIG5GaWVsZF07Cn0KCnN0YXRpYwpMQ01TQk9PTCBTZXREYXRhKExQSVQ4IGl0OCwgaW50IG5TZXQsIGludCBuRmllbGQsIGNvbnN0IGNoYXIgKlZhbCkKewogICAgTFBUQUJMRSB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBpZiAoIXQtPkRhdGEpCiAgICAgICAgQWxsb2NhdGVEYXRhU2V0KGl0OCk7CgogICAgaWYgKCF0LT5EYXRhKSByZXR1cm4gRkFMU0U7CgoKCiAgICBpZiAoblNldCA+IHQgLT4gblBhdGNoZXMgfHwgblNldCA8IDApIHsKCiAgICAgICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsICJQYXRjaCAlZCBvdXQgb2YgcmFuZ2UsIHRoZXJlIGFyZSAlZCBwYXRjaGVzIiwgblNldCwgdCAtPiBuUGF0Y2hlcyk7CiAgICB9CgogICAgaWYgKG5GaWVsZCA+IHQgLT5uU2FtcGxlcyB8fCBuRmllbGQgPCAwKSB7CiAgICAgICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsICJTYW1wbGUgJWQgb3V0IG9mIHJhbmdlLCB0aGVyZSBhcmUgJWQgc2FtcGxlcyIsIG5GaWVsZCwgdCAtPm5TYW1wbGVzKTsKCiAgICB9CgoKICAgIHQtPkRhdGEgW25TZXQgKiB0IC0+IG5TYW1wbGVzICsgbkZpZWxkXSA9IEFsbG9jU3RyaW5nKGl0OCwgVmFsKTsKICAgIHJldHVybiBUUlVFOwp9CgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpbGUgSS9PCgoKLy8gV3JpdGVzIGEgc3RyaW5nIHRvIGZpbGUKc3RhdGljCnZvaWQgV3JpdGVTdHIoTFBTQVZFU1RSRUFNIGYsIGNvbnN0IGNoYXIgKnN0cikKewoKICAgIHNpemVfdCBsZW47CgogICAgaWYgKHN0ciA9PSBOVUxMKQogICAgICAgIHN0ciA9ICIgIjsKCiAgICAvLyBMZW5naHRoIHRvIHdyaXRlCiAgICBsZW4gPSBzdHJsZW4oc3RyKTsKICAgIGYgLT5Vc2VkICs9IGxlbjsKCgogICAgaWYgKGYgLT5zdHJlYW0pIHsgICAvLyBTaG91bGQgSSB3cml0ZSBpdCB0byBhIGZpbGU/CgogICAgICAgIGZ3cml0ZShzdHIsIDEsIGxlbiwgZi0+c3RyZWFtKTsKCiAgICB9CiAgICBlbHNlIHsgIC8vIE9yIHRvIGEgbWVtb3J5IGJsb2NrPwoKCiAgICAgICAgaWYgKGYgLT5CYXNlKSB7ICAgLy8gQW0gSSBqdXN0IGNvdW50aW5nIHRoZSBieXRlcz8KCiAgICAgICAgICAgIGlmIChmIC0+VXNlZCA+IGYgLT5NYXgpIHsKCiAgICAgICAgICAgICAgICBjbXNTaWduYWxFcnJvcihMQ01TX0VSUkNfQUJPUlRFRCwgIldyaXRlIHRvIG1lbW9yeSBvdmVyZmxvd3MgaW4gQ0dBVFMgcGFyc2VyIik7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIENvcHlNZW1vcnkoZiAtPlB0ciwgc3RyLCBsZW4pOwogICAgICAgICAgICBmLT5QdHIgKz0gbGVuOwoKICAgICAgICB9CgogICAgfQp9CgoKLy8gV3JpdGUgZm9ybWF0dGVkCgpzdGF0aWMKdm9pZCBXcml0ZWYoTFBTQVZFU1RSRUFNIGYsIGNvbnN0IGNoYXIqIGZybSwgLi4uKQp7CiAgICBjaGFyIEJ1ZmZlcls0MDk2XTsKICAgIHZhX2xpc3QgYXJnczsKCiAgICB2YV9zdGFydChhcmdzLCBmcm0pOwogICAgdnNucHJpbnRmKEJ1ZmZlciwgNDA5NSwgZnJtLCBhcmdzKTsKICAgIEJ1ZmZlcls0MDk1XSA9IDA7CiAgICBXcml0ZVN0cihmLCBCdWZmZXIpOwogICAgdmFfZW5kKGFyZ3MpOwoKfQoKLy8gV3JpdGVzIGZ1bGwgaGVhZGVyCnN0YXRpYwp2b2lkIFdyaXRlSGVhZGVyKExQSVQ4IGl0OCwgTFBTQVZFU1RSRUFNIGZwKQp7CiAgICBMUEtFWVZBTFVFIHA7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKCiAgICBmb3IgKHAgPSB0LT5IZWFkZXJMaXN0OyAocCAhPSBOVUxMKTsgcCA9IHAtPk5leHQpCiAgICB7CiAgICAgICAgaWYgKCpwIC0+S2V5d29yZCA9PSAnIycpIHsKCiAgICAgICAgICAgIGNoYXIqIFB0OwoKICAgICAgICAgICAgV3JpdGVTdHIoZnAsICIjXG4jICIpOwogICAgICAgICAgICBmb3IgKFB0ID0gcCAtPlZhbHVlOyAqUHQ7IFB0KyspIHsKCgogICAgICAgICAgICAgICAgV3JpdGVmKGZwLCAiJWMiLCAqUHQpOwoKICAgICAgICAgICAgICAgIGlmICgqUHQgPT0gJ1xuJykgewogICAgICAgICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAiIyAiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgV3JpdGVTdHIoZnAsICJcbiNcbiIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoKICAgICAgICBpZiAoIUlzQXZhaWxhYmxlT25MaXN0KGl0OC0+IFZhbGlkS2V5d29yZHMsIHAtPktleXdvcmQsIE5VTEwsIE5VTEwpKSB7CgojaWZkZWYgU1RSSUNUX0NHQVRTCiAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAiS0VZV09SRFx0XCIiKTsKICAgICAgICAgICAgV3JpdGVTdHIoZnAsIHAtPktleXdvcmQpOwogICAgICAgICAgICBXcml0ZVN0cihmcCwgIlwiXG4iKTsKI2VuZGlmCgogICAgICAgICAgICBBZGRBdmFpbGFibGVQcm9wZXJ0eShpdDgsIHAtPktleXdvcmQsIFdSSVRFX1VOQ09PS0VEKTsKCiAgICAgICAgfQoKICAgICAgICBXcml0ZVN0cihmcCwgcC0+S2V5d29yZCk7CiAgICAgICAgaWYgKHAtPlZhbHVlKSB7CgogICAgICAgICAgICBzd2l0Y2ggKHAgLT5Xcml0ZUFzKSB7CgogICAgICAgICAgICBjYXNlIFdSSVRFX1VOQ09PS0VEOgogICAgICAgICAgICAgICAgICAgIFdyaXRlZihmcCwgIlx0JXMiLCBwIC0+VmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXUklURV9TVFJJTkdJRlk6CiAgICAgICAgICAgICAgICAgICAgV3JpdGVmKGZwLCAiXHRcIiVzXCIiLCBwLT5WYWx1ZSApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXUklURV9IRVhBREVDSU1BTDoKICAgICAgICAgICAgICAgICAgICBXcml0ZWYoZnAsICJcdDB4JVgiLCBhdG9pKHAgLT5WYWx1ZSkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXUklURV9CSU5BUlk6CiAgICAgICAgICAgICAgICAgICAgV3JpdGVmKGZwLCAiXHQweCVCIiwgYXRvaShwIC0+VmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgV1JJVEVfUEFJUjoKICAgICAgICAgICAgICAgICAgICBXcml0ZWYoZnAsICJcdFwiJXMsJXNcIiIsIHAtPlN1YmtleSwgcC0+VmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDogU3luRXJyb3IoaXQ4LCAiVW5rbm93biB3cml0ZSBtb2RlICVkIiwgcCAtPldyaXRlQXMpOwogICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFdyaXRlU3RyIChmcCwgIlxuIik7CiAgICB9Cgp9CgoKLy8gV3JpdGVzIHRoZSBkYXRhIGZvcm1hdApzdGF0aWMKdm9pZCBXcml0ZURhdGFGb3JtYXQoTFBTQVZFU1RSRUFNIGZwLCBMUElUOCBpdDgpCnsKICAgIGludCBpLCBuU2FtcGxlczsKICAgIExQVEFCTEUgdCA9IEdldFRhYmxlKGl0OCk7CgogICAgaWYgKCF0IC0+IERhdGFGb3JtYXQpIHJldHVybjsKCiAgICAgICBXcml0ZVN0cihmcCwgIkJFR0lOX0RBVEFfRk9STUFUXG4iKTsKICAgICAgIFdyaXRlU3RyKGZwLCAiICIpOwogICAgICAgblNhbXBsZXMgPSBhdG9pKGNtc0lUOEdldFByb3BlcnR5KGl0OCwgIk5VTUJFUl9PRl9GSUVMRFMiKSk7CgogICAgICAgZm9yIChpID0gMDsgaSA8IG5TYW1wbGVzOyBpKyspIHsKCiAgICAgICAgICAgICAgV3JpdGVTdHIoZnAsIHQtPkRhdGFGb3JtYXRbaV0pOwogICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAoKGkgPT0gKG5TYW1wbGVzLTEpKSA/ICJcbiIgOiAiXHQiKSk7CiAgICAgICAgICB9CgogICAgICAgV3JpdGVTdHIgKGZwLCAiRU5EX0RBVEFfRk9STUFUXG4iKTsKfQoKCi8vIFdyaXRlcyBkYXRhIGFycmF5CnN0YXRpYwp2b2lkIFdyaXRlRGF0YShMUFNBVkVTVFJFQU0gZnAsIExQSVQ4IGl0OCkKewogICAgICAgaW50ICBpLCBqOwogICAgICAgTFBUQUJMRSB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICAgICBpZiAoIXQtPkRhdGEpIHJldHVybjsKCiAgICAgICBXcml0ZVN0ciAoZnAsICJCRUdJTl9EQVRBXG4iKTsKCiAgICAgICB0LT5uUGF0Y2hlcyA9IGF0b2koY21zSVQ4R2V0UHJvcGVydHkoaXQ4LCAiTlVNQkVSX09GX1NFVFMiKSk7CgogICAgICAgZm9yIChpID0gMDsgaSA8IHQtPiBuUGF0Y2hlczsgaSsrKSB7CgogICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAiICIpOwoKICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgdC0+blNhbXBsZXM7IGorKykgewoKICAgICAgICAgICAgICAgICAgICAgY2hhciAqcHRyID0gdC0+RGF0YVtpKnQtPm5TYW1wbGVzK2pdOwoKICAgICAgICAgICAgICAgICAgICAgaWYgKHB0ciA9PSBOVUxMKSBXcml0ZVN0cihmcCwgIlwiXCIiKTsKICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB2YWx1ZSBjb250YWlucyB3aGl0ZXNwYWNlLCBlbmNsb3NlIHdpdGhpbiBxdW90ZQoKICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJjaHIocHRyLCAnICcpICE9IE5VTEwpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV3JpdGVTdHIoZnAsICJcIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCBwdHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCAiXCIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdyaXRlU3RyKGZwLCBwdHIpOwogICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICBXcml0ZVN0cihmcCwgKChqID09ICh0LT5uU2FtcGxlcy0xKSkgPyAiXG4iIDogIlx0IikpOwogICAgICAgICAgICAgIH0KICAgICAgIH0KICAgICAgIFdyaXRlU3RyIChmcCwgIkVORF9EQVRBXG4iKTsKfQoKCgovLyBTYXZlcyB3aG9sZSBmaWxlCkxDTVNCT09MIExDTVNFWFBPUlQgY21zSVQ4U2F2ZVRvRmlsZShMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNGaWxlTmFtZSkKewogICAgU0FWRVNUUkVBTSBzZDsKICAgIGludCBpOwogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwoKICAgIFplcm9NZW1vcnkoJnNkLCBzaXplb2YoU0FWRVNUUkVBTSkpOwoKICAgIHNkLnN0cmVhbSA9IGZvcGVuKGNGaWxlTmFtZSwgInd0Iik7CiAgICBpZiAoIXNkLnN0cmVhbSkgcmV0dXJuIEZBTFNFOwoKICAgIFdyaXRlU3RyKCZzZCwgaXQ4LT5TaGVldFR5cGUpOwogICAgV3JpdGVTdHIoJnNkLCAiXG4iKTsKICAgIGZvciAoaT0wOyBpIDwgaXQ4IC0+VGFibGVzQ291bnQ7IGkrKykgewoKICAgICAgICAgICAgY21zSVQ4U2V0VGFibGUoaElUOCwgaSk7CiAgICAgICAgICAgIFdyaXRlSGVhZGVyKGl0OCwgJnNkKTsKICAgICAgICAgICAgV3JpdGVEYXRhRm9ybWF0KCZzZCwgaXQ4KTsKICAgICAgICAgICAgV3JpdGVEYXRhKCZzZCwgaXQ4KTsKICAgIH0KCiAgICBmY2xvc2Uoc2Quc3RyZWFtKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKCi8vIFNhdmVzIHRvIG1lbW9yeQpMQ01TQk9PTCBMQ01TRVhQT1JUIGNtc0lUOFNhdmVUb01lbShMQ01TSEFORExFIGhJVDgsIHZvaWQgKk1lbVB0ciwgc2l6ZV90KiBCeXRlc05lZWRlZCkKewogICAgU0FWRVNUUkVBTSBzZDsKICAgIGludCBpOwogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwoKICAgIFplcm9NZW1vcnkoJnNkLCBzaXplb2YoU0FWRVNUUkVBTSkpOwoKICAgIHNkLnN0cmVhbSA9IE5VTEw7CiAgICBzZC5CYXNlICAgPSAoTFBCWVRFKSBNZW1QdHI7CiAgICBzZC5QdHIgICAgPSBzZC5CYXNlOwoKICAgIHNkLlVzZWQgPSAwOwoKICAgIGlmIChzZC5CYXNlKQogICAgICAgIHNkLk1heCAgPSAqQnl0ZXNOZWVkZWQ7ICAgICAvLyBXcml0ZSB0byBtZW1vcnk/CiAgICBlbHNlCiAgICAgICAgc2QuTWF4ICA9IDA7ICAgICAgICAgICAgICAgIC8vIEp1c3QgY291bnRpbmcgdGhlIG5lZWRlZCBieXRlcwoKICAgIFdyaXRlU3RyKCZzZCwgaXQ4LT5TaGVldFR5cGUpOwogICAgV3JpdGVTdHIoJnNkLCAiXG4iKTsKICAgIGZvciAoaT0wOyBpIDwgaXQ4IC0+VGFibGVzQ291bnQ7IGkrKykgewoKICAgICAgICAgICAgY21zSVQ4U2V0VGFibGUoaElUOCwgaSk7CiAgICAgICAgICAgIFdyaXRlSGVhZGVyKGl0OCwgJnNkKTsKICAgICAgICAgICAgV3JpdGVEYXRhRm9ybWF0KCZzZCwgaXQ4KTsKICAgICAgICAgICAgV3JpdGVEYXRhKCZzZCwgaXQ4KTsKICAgIH0KCiAgICBzZC5Vc2VkKys7ICAvLyBUaGUgXDAgYXQgdGhlIHZlcnkgZW5kCgogICAgaWYgKHNkLkJhc2UpCiAgICAgICAgc2QuUHRyID0gMDsKCiAgICAqQnl0ZXNOZWVkZWQgPSBzZC5Vc2VkOwoKICAgIHJldHVybiBUUlVFOwp9CgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSGlnZXIgbGV2ZWwgcGFyc2luZwoKc3RhdGljCkxDTVNCT09MIERhdGFGb3JtYXRTZWN0aW9uKExQSVQ4IGl0OCkKewogICAgaW50IGlGaWVsZCA9IDA7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIEluU3ltYm9sKGl0OCk7ICAgLy8gRWF0cyAiQkVHSU5fREFUQV9GT1JNQVQiCiAgICBDaGVja0VPTE4oaXQ4KTsKCiAgICB3aGlsZSAoaXQ4LT5zeSAhPSBTRU5EX0RBVEFfRk9STUFUICYmCiAgICAgICAgaXQ4LT5zeSAhPSBTRU9MTiAmJgogICAgICAgIGl0OC0+c3kgIT0gU0VPRiAmJgogICAgICAgIGl0OC0+c3kgIT0gU1NZTkVSUk9SKSAgewoKICAgICAgICAgICAgaWYgKGl0OC0+c3kgIT0gU0lERU5UKSB7CgogICAgICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIlNhbXBsZSB0eXBlIGV4cGVjdGVkIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghU2V0RGF0YUZvcm1hdChpdDgsIGlGaWVsZCwgaXQ4LT5pZCkpIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgaUZpZWxkKys7CgogICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICBTa2lwRU9MTihpdDgpOwogICAgICAgfQoKICAgICAgIFNraXBFT0xOKGl0OCk7CiAgICAgICBTa2lwKGl0OCwgU0VORF9EQVRBX0ZPUk1BVCk7CiAgICAgICBTa2lwRU9MTihpdDgpOwoKICAgICAgIGlmIChpRmllbGQgIT0gdCAtPm5TYW1wbGVzKSB7CiAgICAgICAgICAgU3luRXJyb3IoaXQ4LCAiQ291bnQgbWlzbWF0Y2guIE5VTUJFUl9PRl9GSUVMRFMgd2FzICVkLCBmb3VuZCAlZFxuIiwgdCAtPm5TYW1wbGVzLCBpRmllbGQpOwoKCiAgICAgICB9CgogICAgICAgcmV0dXJuIFRSVUU7Cn0KCgoKc3RhdGljCkxDTVNCT09MIERhdGFTZWN0aW9uIChMUElUOCBpdDgpCnsKICAgIGludCAgaUZpZWxkID0gMDsKICAgIGludCAgaVNldCAgID0gMDsKICAgIGNoYXIgQnVmZmVyW01BWFNUUl07CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIEluU3ltYm9sKGl0OCk7ICAgLy8gRWF0cyAiQkVHSU5fREFUQSIKICAgIENoZWNrRU9MTihpdDgpOwoKICAgIGlmICghdC0+RGF0YSkKICAgICAgICBBbGxvY2F0ZURhdGFTZXQoaXQ4KTsKCiAgICB3aGlsZSAoaXQ4LT5zeSAhPSBTRU5EX0RBVEEgJiYgaXQ4LT5zeSAhPSBTRU9GKQogICAgewogICAgICAgIGlmIChpRmllbGQgPj0gdCAtPiBuU2FtcGxlcykgewogICAgICAgICAgICBpRmllbGQgPSAwOwogICAgICAgICAgICBpU2V0Kys7CgogICAgICAgIH0KCiAgICAgICAgaWYgKGl0OC0+c3kgIT0gU0VORF9EQVRBICYmIGl0OC0+c3kgIT0gU0VPRikgewoKICAgICAgICAgICAgaWYgKCFHZXRWYWwoaXQ4LCBCdWZmZXIsIDI1NSwgIlNhbXBsZSBkYXRhIGV4cGVjdGVkIikpCiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgICAgICAgICBpZiAoIVNldERhdGEoaXQ4LCBpU2V0LCBpRmllbGQsIEJ1ZmZlcikpCiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgICAgICAgICBpRmllbGQrKzsKCiAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgIFNraXBFT0xOKGl0OCk7CiAgICAgICAgfQogICAgfQoKICAgIFNraXBFT0xOKGl0OCk7CiAgICBTa2lwKGl0OCwgU0VORF9EQVRBKTsKICAgIFNraXBFT0xOKGl0OCk7CgogICAgLy8gQ2hlY2sgZm9yIGRhdGEgY29tcGxldGlvbi4KCiAgICBpZiAoKGlTZXQrMSkgIT0gdCAtPiBuUGF0Y2hlcykKICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiQ291bnQgbWlzbWF0Y2guIE5VTUJFUl9PRl9TRVRTIHdhcyAlZCwgZm91bmQgJWRcbiIsIHQgLT5uUGF0Y2hlcywgaVNldCsxKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKCgoKc3RhdGljCkxDTVNCT09MIEhlYWRlclNlY3Rpb24oTFBJVDggaXQ4KQp7CiAgICBjaGFyIFZhck5hbWVbTUFYSURdOwogICAgY2hhciBCdWZmZXJbTUFYU1RSXTsKICAgIExQS0VZVkFMVUUgS2V5OwoKICAgICAgICB3aGlsZSAoaXQ4LT5zeSAhPSBTRU9GICYmCiAgICAgICAgICAgICAgIGl0OC0+c3kgIT0gU1NZTkVSUk9SICYmCiAgICAgICAgICAgICAgIGl0OC0+c3kgIT0gU0JFR0lOX0RBVEFfRk9STUFUICYmCiAgICAgICAgICAgICAgIGl0OC0+c3kgIT0gU0JFR0lOX0RBVEEpIHsKCgogICAgICAgIHN3aXRjaCAoaXQ4IC0+IHN5KSB7CgogICAgICAgIGNhc2UgU0tFWVdPUkQ6CiAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgaWYgKCFHZXRWYWwoaXQ4LCBCdWZmZXIsIE1BWFNUUi0xLCAiS2V5d29yZCBleHBlY3RlZCIpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgICAgICBpZiAoIUFkZEF2YWlsYWJsZVByb3BlcnR5KGl0OCwgQnVmZmVyLCBXUklURV9VTkNPT0tFRCkpIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgICAgICBicmVhazsKCgogICAgICAgIGNhc2UgU0RBVEFfRk9STUFUX0lEOgogICAgICAgICAgICAgICAgSW5TeW1ib2woaXQ4KTsKICAgICAgICAgICAgICAgIGlmICghR2V0VmFsKGl0OCwgQnVmZmVyLCBNQVhTVFItMSwgIktleXdvcmQgZXhwZWN0ZWQiKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICAgICAgaWYgKCFBZGRBdmFpbGFibGVTYW1wbGVJRChpdDgsIEJ1ZmZlcikpIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgICAgIEluU3ltYm9sKGl0OCk7CiAgICAgICAgICAgICAgICBicmVhazsKCgogICAgICAgIGNhc2UgU0lERU5UOgogICAgICAgICAgICAgICAgc3RybmNweShWYXJOYW1lLCBpdDgtPmlkLCBNQVhJRC0xKTsKICAgICAgICAgICAgICAgIFZhck5hbWVbTUFYSUQtMV0gPSAwOwoKICAgICAgICAgICAgICAgIGlmICghSXNBdmFpbGFibGVPbkxpc3QoaXQ4LT4gVmFsaWRLZXl3b3JkcywgVmFyTmFtZSwgTlVMTCwgJktleSkpIHsKCiNpZmRlZiBTVFJJQ1RfQ0dBVFMKICAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiVW5kZWZpbmVkIGtleXdvcmQgJyVzJyIsIFZhck5hbWUpOwojZWxzZQogICAgICAgICAgICAgICAgICAgIEtleSA9IEFkZEF2YWlsYWJsZVByb3BlcnR5KGl0OCwgVmFyTmFtZSwgV1JJVEVfVU5DT09LRUQpOwogICAgICAgICAgICAgICAgICAgIGlmIChLZXkgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwojZW5kaWYKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgaWYgKCFHZXRWYWwoaXQ4LCBCdWZmZXIsIE1BWFNUUi0xLCAiUHJvcGVydHkgZGF0YSBleHBlY3RlZCIpKSByZXR1cm4gRkFMU0U7CgogICAgICAgICAgICAgICAgaWYoS2V5LT5Xcml0ZUFzICE9IFdSSVRFX1BBSVIpIHsKICAgICAgICAgICAgICAgICAgICBBZGRUb0xpc3QoaXQ4LCAmR2V0VGFibGUoaXQ4KS0+SGVhZGVyTGlzdCwgVmFyTmFtZSwgTlVMTCwgQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpdDgtPnN5ID09IFNTVFJJTkcpID8gV1JJVEVfU1RSSU5HSUZZIDogV1JJVEVfVU5DT09LRUQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqU3Via2V5OwogICAgICAgICAgICAgICAgICAgIGNoYXIgKk5leHRrZXk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGl0OC0+c3kgIT0gU1NUUklORykKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIkludmFsaWQgdmFsdWUgJyVzJyBmb3IgcHJvcGVydHkgJyVzJy4iLCBCdWZmZXIsIFZhck5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAvLyBjaG9wIHRoZSBzdHJpbmcgYXMgYSBsaXN0IG9mICJzdWJrZXksIHZhbHVlIiBwYWlycywgdXNpbmcgJzsnIGFzIGEgc2VwYXJhdG9yCiAgICAgICAgICAgICAgICAgICAgZm9yKFN1YmtleSA9IEJ1ZmZlcjsgU3Via2V5ICE9IE5VTEw7IFN1YmtleSA9IE5leHRrZXkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjaGFyICpWYWx1ZSwgKnRlbXA7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyAgaWRlbnRpZnkgdG9rZW4gcGFpciBib3VuZGFyeQogICAgICAgICAgICAgICAgICAgICAgICBOZXh0a2V5ID0gKGNoYXIqKSBzdHJjaHIoU3Via2V5LCAnOycpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihOZXh0a2V5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKk5leHRrZXkrKyA9ICdcMCc7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgZWFjaCBwYWlyLCBzcGxpdCB0aGUgc3Via2V5IGFuZCB0aGUgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgPSAoY2hhciopIHN0cnJjaHIoU3Via2V5LCAnLCcpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihWYWx1ZSA9PSBOVUxMKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIkludmFsaWQgdmFsdWUgZm9yIHByb3BlcnR5ICclcycuIiwgVmFyTmFtZSk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBnb2JibGUgdGhlIHNwYWNlcyBiZWZvcmUgdGhlIGNvbWEsIGFuZCB0aGUgY29tYSBpdHNlbGYKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IFZhbHVlKys7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvICp0ZW1wLS0gPSAnXDAnOyB3aGlsZSh0ZW1wID49IFN1YmtleSAmJiAqdGVtcCA9PSAnICcpOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ29iYmxlIGFueSBzcGFjZSBhdCB0aGUgcmlnaHQKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IFZhbHVlICsgc3RybGVuKFZhbHVlKSAtIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKCp0ZW1wID09ICcgJykgKnRlbXAtLSA9ICdcMCc7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyB0cmltIHRoZSBzdHJpbmdzIGZyb20gdGhlIGxlZnQKICAgICAgICAgICAgICAgICAgICAgICAgU3Via2V5ICs9IHN0cnNwbihTdWJrZXksICIgIik7CiAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlICs9IHN0cnNwbihWYWx1ZSwgIiAiKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKFN1YmtleVswXSA9PSAwIHx8IFZhbHVlWzBdID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU3luRXJyb3IoaXQ4LCAiSW52YWxpZCB2YWx1ZSBmb3IgcHJvcGVydHkgJyVzJy4iLCBWYXJOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgQWRkVG9MaXN0KGl0OCwgJkdldFRhYmxlKGl0OCktPkhlYWRlckxpc3QsIFZhck5hbWUsIFN1YmtleSwgVmFsdWUsIFdSSVRFX1BBSVIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBJblN5bWJvbChpdDgpOwogICAgICAgICAgICAgICAgYnJlYWs7CgoKICAgICAgICBjYXNlIFNFT0xOOiBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiBTeW5FcnJvcihpdDgsICJleHBlY3RlZCBrZXl3b3JkIG9yIGlkZW50aWZpZXIiKTsKICAgICAgICB9CgogICAgU2tpcEVPTE4oaXQ4KTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKCn0KCgpzdGF0aWMKTENNU0JPT0wgUGFyc2VJVDgoTFBJVDggaXQ4LCBMQ01TQk9PTCBub3NoZWV0KQp7CiAgICBjaGFyKiBTaGVldFR5cGVQdHIgPSBpdDggLT5TaGVldFR5cGU7CgogICAgaWYgKG5vc2hlZXQgPT0gMCkgewoKICAgIC8vIEZpcnN0IGxpbmUgaXMgYSB2ZXJ5IHNwZWNpYWwgY2FzZS4KCiAgICB3aGlsZSAoaXNzZXBhcmF0b3IoaXQ4LT5jaCkpCiAgICAgICAgICAgIE5leHRDaChpdDgpOwoKICAgIHdoaWxlIChpdDgtPmNoICE9ICdccicgJiYgaXQ4IC0+Y2ggIT0gJ1xuJyAmJiBpdDgtPmNoICE9ICdcdCcgJiYgaXQ4IC0+IGNoICE9IC0xKSB7CgogICAgICAgICpTaGVldFR5cGVQdHIrKz0gKGNoYXIpIGl0OCAtPmNoOwogICAgICAgIE5leHRDaChpdDgpOwogICAgfQogICAgfQoKICAgICpTaGVldFR5cGVQdHIgPSAwOwogICAgSW5TeW1ib2woaXQ4KTsKCiAgICBTa2lwRU9MTihpdDgpOwoKICAgIHdoaWxlIChpdDgtPiBzeSAhPSBTRU9GICYmCiAgICAgICAgICAgaXQ4LT4gc3kgIT0gU1NZTkVSUk9SKSB7CgogICAgICAgICAgICBzd2l0Y2ggKGl0OCAtPiBzeSkgewoKICAgICAgICAgICAgY2FzZSBTQkVHSU5fREFUQV9GT1JNQVQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKCFEYXRhRm9ybWF0U2VjdGlvbihpdDgpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNCRUdJTl9EQVRBOgoKICAgICAgICAgICAgICAgICAgICBpZiAoIURhdGFTZWN0aW9uKGl0OCkpIHJldHVybiBGQUxTRTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGl0OCAtPiBzeSAhPSBTRU9GKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgQWxsb2NUYWJsZShpdDgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQ4IC0+blRhYmxlID0gaXQ4IC0+VGFibGVzQ291bnQgLSAxOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU0VPTE46CiAgICAgICAgICAgICAgICAgICAgU2tpcEVPTE4oaXQ4KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKCFIZWFkZXJTZWN0aW9uKGl0OCkpIHJldHVybiBGQUxTRTsKICAgICAgICAgICB9CgogICAgfQoKICAgIHJldHVybiAoaXQ4IC0+IHN5ICE9IFNTWU5FUlJPUik7Cn0KCgoKLy8gSW5pdCB1c2VmdWxsIHBvaW50ZXJzCgpzdGF0aWMKdm9pZCBDb29rUG9pbnRlcnMoTFBJVDggaXQ4KQp7CiAgICBpbnQgaWRGaWVsZCwgaTsKICAgIGNoYXIqIEZsZDsKICAgIGludCBqOwogICAgaW50IG5PbGRUYWJsZSA9IGl0OCAtPm5UYWJsZTsKCiAgICBmb3IgKGo9MDsgaiA8IGl0OCAtPlRhYmxlc0NvdW50OyBqKyspIHsKCiAgICBMUFRBQkxFIHQgPSBpdDggLT5UYWIgKyBqOwoKICAgIHQgLT4gU2FtcGxlSUQgPSAwOwogICAgaXQ4IC0+blRhYmxlID0gajsKCiAgICBmb3IgKGlkRmllbGQgPSAwOyBpZEZpZWxkIDwgdCAtPiBuU2FtcGxlczsgaWRGaWVsZCsrKQogICAgewogICAgICAgIGlmICh0IC0+RGF0YUZvcm1hdCA9PSBOVUxMKSB7CiAgICAgICAgICAgICBTeW5FcnJvcihpdDgsICJVbmRlZmluZWQgREFUQV9GT1JNQVQiKTsKICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgfQoKICAgICAgICBGbGQgPSB0LT5EYXRhRm9ybWF0W2lkRmllbGRdOwogICAgICAgIGlmICghRmxkKSBjb250aW51ZTsKCgogICAgICAgIGlmIChzdHJpY21wKEZsZCwgIlNBTVBMRV9JRCIpID09IDApIHsKCiAgICAgICAgICAgICAgICAgICAgdCAtPiBTYW1wbGVJRCA9IGlkRmllbGQ7CgogICAgICAgIGZvciAoaT0wOyBpIDwgdCAtPiBuUGF0Y2hlczsgaSsrKSB7CgogICAgICAgICAgICAgICAgY2hhciAqRGF0YSA9IEdldERhdGEoaXQ4LCBpLCBpZEZpZWxkKTsKICAgICAgICAgICAgICAgIGlmIChEYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgY2hhciBCdWZmZXJbMjU2XTsKCiAgICAgICAgICAgICAgICAgICAgc3RybmNweShCdWZmZXIsIERhdGEsIDI1NSk7CiAgICAgICAgICAgICAgICAgICAgQnVmZmVyWzI1NV0gPSAwOwoKICAgICAgICAgICAgICAgICAgICBpZiAoc3RybGVuKEJ1ZmZlcikgPD0gc3RybGVuKERhdGEpKQogICAgICAgICAgICAgICAgICAgICAgICBzdHJjcHkoRGF0YSwgQnVmZmVyKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIFNldERhdGEoaXQ4LCBpLCBpZEZpZWxkLCBCdWZmZXIpOwoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgfQoKICAgICAgICAvLyAiTEFCRUwiIGlzIGFuIGV4dGVuc2lvbi4gSXQga2VlcHMgcmVmZXJlbmNlcyB0byBmb3J3YXJkIHRhYmxlcwoKICAgICAgICBpZiAoKHN0cmljbXAoRmxkLCAiTEFCRUwiKSA9PSAwKSB8fCBGbGRbMF0gPT0gJyQnICkgewoKICAgICAgICAgICAgICAgICAgICAvLyBTZWFyY2ggZm9yIHRhYmxlIHJlZmVyZW5jZXMuLi4KICAgICAgICAgICAgICAgICAgICBmb3IgKGk9MDsgaSA8IHQgLT4gblBhdGNoZXM7IGkrKykgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKkxhYmVsID0gR2V0RGF0YShpdDgsIGksIGlkRmllbGQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChMYWJlbCkgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgazsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgbGFiZWwsIHNlYXJjaCBmb3IgYSB0YWJsZSBjb250YWluaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBwcm9wZXJ0eQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGs9MDsgayA8IGl0OCAtPlRhYmxlc0NvdW50OyBrKyspIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVEFCTEUgVGFibGUgPSBpdDggLT5UYWIgKyBrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEtFWVZBTFVFIHA7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoSXNBdmFpbGFibGVPbkxpc3QoVGFibGUtPkhlYWRlckxpc3QsIExhYmVsLCBOVUxMLCAmcCkpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBdmFpbGFibGUsIGtlZXAgdHlwZSBhbmQgdGFibGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgQnVmZmVyWzI1Nl07CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqVHlwZSAgPSBwIC0+VmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgIG5UYWJsZSA9IGs7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25wcmludGYoQnVmZmVyLCAyNTUsICIlcyAlZCAlcyIsIExhYmVsLCBuVGFibGUsIFR5cGUgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXREYXRhKGl0OCwgaSwgaWRGaWVsZCwgQnVmZmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB9CgoKICAgICAgICB9CgogICAgfQogICAgfQoKICAgIGl0OCAtPm5UYWJsZSA9IG5PbGRUYWJsZTsKfQoKLy8gVHJ5IHRvIGluZmVyZSBpZiB0aGUgZmlsZSBpcyBhIENHQVRTL0lUOCBmaWxlIGF0IGFsbC4gUmVhZCBmaXJzdCBsaW5lCi8vIHRoYXQgc2hvdWxkIGJlIHNvbWV0aGluZyBsaWtlIHNvbWUgcHJpbnRhYmxlIGNoYXJhY3RlcnMgcGx1cyBhIFxuCgpzdGF0aWMKaW50IElzTXlCbG9jayhMUEJZVEUgQnVmZmVyLCBzaXplX3QgbikKewogICAgaW50IGNvbHMgPSAxLCBzcGFjZSA9IDAsIHF1b3QgPSAwOwogICAgc2l6ZV90IGk7CgogICAgaWYgKG4gPCAxMCkgcmV0dXJuIEZBTFNFOyAgIC8vIFRvbyBzbWFsbAoKICAgIGlmIChuID4gMTMyKQogICAgICAgIG4gPSAxMzI7CgogICAgZm9yIChpID0gMTsgaSA8IG47IGkrKykgewoKICAgICAgICBzd2l0Y2goQnVmZmVyW2ldKQogICAgICAgIHsKICAgICAgICBjYXNlICdcbic6CiAgICAgICAgY2FzZSAnXHInOgogICAgICAgICAgICByZXR1cm4gcXVvdCA9PSAxIHx8IGNvbHMgPiAyID8gMCA6IGNvbHM7CiAgICAgICAgY2FzZSAnXHQnOgogICAgICAgIGNhc2UgJyAnOgogICAgICAgICAgICBpZighcXVvdCAmJiAhc3BhY2UpCiAgICAgICAgICAgICAgICBzcGFjZSA9IDE7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ1wiJzoKICAgICAgICAgICAgcXVvdCA9ICFxdW90OwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBpZiAoQnVmZmVyW2ldIDwgMzIpIHJldHVybiAwOwogICAgICAgICAgICBpZiAoQnVmZmVyW2ldID4gMTI3KSByZXR1cm4gMDsKICAgICAgICAgICAgY29scyArPSBzcGFjZTsKICAgICAgICAgICAgc3BhY2UgPSAwOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIEZBTFNFOwoKfQoKCnN0YXRpYwppbnQgSXNNeUZpbGUoY29uc3QgY2hhciogRmlsZU5hbWUpCnsKICAgRklMRSAqZnA7CiAgIHNpemVfdCBTaXplOwogICBCWVRFIFB0clsxMzNdOwoKICAgZnAgPSBmb3BlbihGaWxlTmFtZSwgInJ0Iik7CiAgIGlmICghZnApIHsKICAgICAgIGNtc1NpZ25hbEVycm9yKExDTVNfRVJSQ19BQk9SVEVELCAiRmlsZSAnJXMnIG5vdCBmb3VuZCIsIEZpbGVOYW1lKTsKICAgICAgIHJldHVybiBGQUxTRTsKICAgfQoKICAgU2l6ZSA9IGZyZWFkKFB0ciwgMSwgMTMyLCBmcCk7CiAgIGZjbG9zZShmcCk7CgogICBQdHJbU2l6ZV0gPSAnXDAnOwoKICAgcmV0dXJuIElzTXlCbG9jayhQdHIsIFNpemUpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV4cG9ydGVkIHJvdXRpbmVzCgoKTENNU0hBTkRMRSBMQ01TRVhQT1JUIGNtc0lUOExvYWRGcm9tTWVtKHZvaWQgKlB0ciwgc2l6ZV90IGxlbikKewogICAgTENNU0hBTkRMRSBoSVQ4OwogICAgTFBJVDggIGl0ODsKCiAgICBpbnQgdHlwZSA9IElzTXlCbG9jaygoTFBCWVRFKSBQdHIsIGxlbik7CiAgICBpZiAodHlwZSA9PSAwKSByZXR1cm4gTlVMTDsKCiAgICBoSVQ4ID0gY21zSVQ4QWxsb2MoKTsKICAgIGlmICghaElUOCkgcmV0dXJuIE5VTEw7CgogICAgaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgaXQ4IC0+TWVtb3J5QmxvY2sgPSAoY2hhciopIF9jbXNNYWxsb2MobGVuICsgMSk7CgogICAgc3RybmNweShpdDggLT5NZW1vcnlCbG9jaywgKGNvbnN0IGNoYXIqKSBQdHIsIGxlbik7CiAgICBpdDggLT5NZW1vcnlCbG9ja1tsZW5dID0gMDsKCiAgICBzdHJuY3B5KGl0OC0+RmlsZVN0YWNrWzBdLT5GaWxlTmFtZSwgIiIsIE1BWF9QQVRILTEpOwogICAgaXQ4LT4gU291cmNlID0gaXQ4IC0+IE1lbW9yeUJsb2NrOwoKICAgIGlmICghUGFyc2VJVDgoaXQ4LCB0eXBlLTEpKSB7CgogICAgICAgIGNtc0lUOEZyZWUoaElUOCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIENvb2tQb2ludGVycyhpdDgpOwogICAgaXQ4IC0+blRhYmxlID0gMDsKCiAgICAgX2Ntc0ZyZWUoaXQ4LT5NZW1vcnlCbG9jayk7CiAgICBpdDggLT4gTWVtb3J5QmxvY2sgPSBOVUxMOwoKICAgIHJldHVybiBoSVQ4OwoKCn0KCgpMQ01TSEFORExFIExDTVNFWFBPUlQgY21zSVQ4TG9hZEZyb21GaWxlKGNvbnN0IGNoYXIqIGNGaWxlTmFtZSkKewoKICAgICBMQ01TSEFORExFIGhJVDg7CiAgICAgTFBJVDggIGl0ODsKCiAgICAgaW50IHR5cGUgPSBJc015RmlsZShjRmlsZU5hbWUpOwogICAgIGlmICh0eXBlID09IDApIHJldHVybiBOVUxMOwoKICAgICBoSVQ4ID0gY21zSVQ4QWxsb2MoKTsKICAgICBpdDggPSAoTFBJVDgpIGhJVDg7CiAgICAgaWYgKCFoSVQ4KSByZXR1cm4gTlVMTDsKCgogICAgIGl0OCAtPkZpbGVTdGFja1swXS0+U3RyZWFtID0gZm9wZW4oY0ZpbGVOYW1lLCAicnQiKTsKCiAgICAgaWYgKCFpdDggLT5GaWxlU3RhY2tbMF0tPlN0cmVhbSkgewogICAgICAgICBjbXNJVDhGcmVlKGhJVDgpOwogICAgICAgICByZXR1cm4gTlVMTDsKICAgICB9CgoKICAgIHN0cm5jcHkoaXQ4LT5GaWxlU3RhY2tbMF0tPkZpbGVOYW1lLCBjRmlsZU5hbWUsIE1BWF9QQVRILTEpOwogICAgaXQ4LT5GaWxlU3RhY2tbMF0tPkZpbGVOYW1lW01BWF9QQVRILTFdID0gMDsKCiAgICBpZiAoIVBhcnNlSVQ4KGl0OCwgdHlwZS0xKSkgewoKICAgICAgICAgICAgZmNsb3NlKGl0OCAtPkZpbGVTdGFja1swXS0+U3RyZWFtKTsKICAgICAgICAgICAgY21zSVQ4RnJlZShoSVQ4KTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgQ29va1BvaW50ZXJzKGl0OCk7CiAgICBpdDggLT5uVGFibGUgPSAwOwoKICAgIGZjbG9zZShpdDggLT5GaWxlU3RhY2tbMF0tPlN0cmVhbSk7CiAgICByZXR1cm4gaElUODsKCn0KCmludCBMQ01TRVhQT1JUIGNtc0lUOEVudW1EYXRhRm9ybWF0KExDTVNIQU5ETEUgaElUOCwgY2hhciAqKipTYW1wbGVOYW1lcykKewogICAgICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKICAgICAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgICAgICAqU2FtcGxlTmFtZXMgPSB0IC0+IERhdGFGb3JtYXQ7CiAgICAgICAgcmV0dXJuIHQgLT4gblNhbXBsZXM7Cn0KCgppbnQgTENNU0VYUE9SVCBjbXNJVDhFbnVtUHJvcGVydGllcyhMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIgKioqUHJvcGVydHlOYW1lcykKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgTFBLRVlWQUxVRSBwOwogICAgaW50IG47CiAgICBjb25zdCBjaGFyICoqUHJvcHM7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIC8vIFBhc3MjMSAtIGNvdW50IHByb3BlcnRpZXMKCiAgICBuID0gMDsKICAgIGZvciAocCA9IHQgLT4gSGVhZGVyTGlzdDsgIHAgIT0gTlVMTDsgcCA9IHAtPk5leHQpIHsKICAgICAgICBuKys7CiAgICB9CgoKICAgIFByb3BzID0gKGNvbnN0IGNoYXIgKiopIEFsbG9jQ2h1bmsoaXQ4LCBzaXplb2YoY2hhciAqKSAqIG4pOwoKICAgIC8vIFBhc3MjMiAtIEZpbGwgcG9pbnRlcnMKICAgIG4gPSAwOwogICAgZm9yIChwID0gdCAtPiBIZWFkZXJMaXN0OyAgcCAhPSBOVUxMOyBwID0gcC0+TmV4dCkgewogICAgICAgIFByb3BzW24rK10gPSBwIC0+IEtleXdvcmQ7CiAgICB9CgogICAgKlByb3BlcnR5TmFtZXMgPSBQcm9wczsKICAgIHJldHVybiBuOwp9CgppbnQgTENNU0VYUE9SVCBjbXNJVDhFbnVtUHJvcGVydHlNdWx0aShMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNQcm9wLCBjb25zdCBjaGFyICoqKlN1YnByb3BlcnR5TmFtZXMpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKICAgIExQS0VZVkFMVUUgcCwgdG1wOwogICAgaW50IG47CiAgICBjb25zdCBjaGFyICoqUHJvcHM7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGlmKCFJc0F2YWlsYWJsZU9uTGlzdCh0LT5IZWFkZXJMaXN0LCBjUHJvcCwgTlVMTCwgJnApKSB7CiAgICAgICAgKlN1YnByb3BlcnR5TmFtZXMgPSAwOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8vIFBhc3MjMSAtIGNvdW50IHByb3BlcnRpZXMKCiAgICBuID0gMDsKICAgIGZvciAodG1wID0gcDsgIHRtcCAhPSBOVUxMOyB0bXAgPSB0bXAtPk5leHRTdWJrZXkpIHsKICAgICAgICBpZih0bXAtPlN1YmtleSAhPSBOVUxMKQogICAgICAgICAgICBuKys7CiAgICB9CgoKICAgIFByb3BzID0gKGNvbnN0IGNoYXIgKiopIEFsbG9jQ2h1bmsoaXQ4LCBzaXplb2YoY2hhciAqKSAqIG4pOwoKICAgIC8vIFBhc3MjMiAtIEZpbGwgcG9pbnRlcnMKICAgIG4gPSAwOwogICAgZm9yICh0bXAgPSBwOyAgdG1wICE9IE5VTEw7IHRtcCA9IHRtcC0+TmV4dFN1YmtleSkgewogICAgICAgIGlmKHRtcC0+U3Via2V5ICE9IE5VTEwpCiAgICAgICAgICAgIFByb3BzW24rK10gPSBwIC0+U3Via2V5OwogICAgfQoKICAgICpTdWJwcm9wZXJ0eU5hbWVzID0gUHJvcHM7CiAgICByZXR1cm4gbjsKfQoKc3RhdGljCmludCBMb2NhdGVQYXRjaChMUElUOCBpdDgsIGNvbnN0IGNoYXIqIGNQYXRjaCkKewogICAgaW50IGk7CiAgICBjb25zdCBjaGFyICpkYXRhOwogICAgTFBUQUJMRSB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBmb3IgKGk9MDsgaSA8IHQtPiBuUGF0Y2hlczsgaSsrKSB7CgogICAgICAgIGRhdGEgPSBHZXREYXRhKGl0OCwgaSwgdC0+U2FtcGxlSUQpOwoKICAgICAgICBpZiAoZGF0YSAhPSBOVUxMKSB7CgogICAgICAgICAgICAgICAgaWYgKHN0cmljbXAoZGF0YSwgY1BhdGNoKSA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFN5bkVycm9yKGl0OCwgIkNvdWxkbid0IGZpbmQgcGF0Y2ggJyVzJ1xuIiwgY1BhdGNoKTsKICAgICAgICByZXR1cm4gLTE7Cn0KCgpzdGF0aWMKaW50IExvY2F0ZUVtcHR5UGF0Y2goTFBJVDggaXQ4KQp7CiAgICBpbnQgaTsKICAgIGNvbnN0IGNoYXIgKmRhdGE7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKICAgIGZvciAoaT0wOyBpIDwgdC0+IG5QYXRjaGVzOyBpKyspIHsKCiAgICAgICAgZGF0YSA9IEdldERhdGEoaXQ4LCBpLCB0LT5TYW1wbGVJRCk7CgogICAgICAgIGlmIChkYXRhID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CgogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIC0xOwp9CgpzdGF0aWMKaW50IExvY2F0ZVNhbXBsZShMUElUOCBpdDgsIGNvbnN0IGNoYXIqIGNTYW1wbGUpCnsKICAgIGludCBpOwogICAgY29uc3QgY2hhciAqZmxkOwogICAgTFBUQUJMRSB0ID0gR2V0VGFibGUoaXQ4KTsKCiAgICBmb3IgKGk9MDsgaSA8IHQtPm5TYW1wbGVzOyBpKyspIHsKCiAgICAgICAgZmxkID0gR2V0RGF0YUZvcm1hdChpdDgsIGkpOwogICAgICAgIGlmIChzdHJpY21wKGZsZCwgY1NhbXBsZSkgPT0gMCkKICAgICAgICAgICAgcmV0dXJuIGk7CiAgICB9CgoKICAgIC8vIFN5bkVycm9yKGl0OCwgIkNvdWxkbid0IGZpbmQgZGF0YSBmaWVsZCAlc1xuIiwgY1NhbXBsZSk7CiAgICByZXR1cm4gLTE7Cgp9CgoKaW50IExDTVNFWFBPUlQgY21zSVQ4R2V0RGF0YUZvcm1hdChMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNTYW1wbGUpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKICAgIHJldHVybiBMb2NhdGVTYW1wbGUoaXQ4LCBjU2FtcGxlKTsKfQoKCgpjb25zdCBjaGFyKiBMQ01TRVhQT1JUIGNtc0lUOEdldERhdGFSb3dDb2woTENNU0hBTkRMRSBoSVQ4LCBpbnQgcm93LCBpbnQgY29sKQp7CiAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CgogICAgcmV0dXJuIEdldERhdGEoaXQ4LCByb3csIGNvbCk7Cn0KCgpkb3VibGUgTENNU0VYUE9SVCBjbXNJVDhHZXREYXRhUm93Q29sRGJsKExDTVNIQU5ETEUgaElUOCwgaW50IHJvdywgaW50IGNvbCkKewogICAgY29uc3QgY2hhciogQnVmZmVyOwoKICAgIEJ1ZmZlciA9IGNtc0lUOEdldERhdGFSb3dDb2woaElUOCwgcm93LCBjb2wpOwoKICAgIGlmIChCdWZmZXIpIHsKCiAgICAgICAgcmV0dXJuIGF0b2YoQnVmZmVyKTsKCiAgICB9IGVsc2UKICAgICAgICByZXR1cm4gMDsKCn0KCgpMQ01TQk9PTCBMQ01TRVhQT1JUIGNtc0lUOFNldERhdGFSb3dDb2woTENNU0hBTkRMRSBoSVQ4LCBpbnQgcm93LCBpbnQgY29sLCBjb25zdCBjaGFyKiBWYWwpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKCiAgICByZXR1cm4gU2V0RGF0YShpdDgsIHJvdywgY29sLCBWYWwpOwp9CgoKTENNU0JPT0wgTENNU0VYUE9SVCBjbXNJVDhTZXREYXRhUm93Q29sRGJsKExDTVNIQU5ETEUgaElUOCwgaW50IHJvdywgaW50IGNvbCwgZG91YmxlIFZhbCkKewogICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwogICAgY2hhciBCdWZmWzI1Nl07CgogICAgc3ByaW50ZihCdWZmLCBpdDgtPkRvdWJsZUZvcm1hdHRlciwgVmFsKTsKCiAgICByZXR1cm4gU2V0RGF0YShpdDgsIHJvdywgY29sLCBCdWZmKTsKfQoKCgpjb25zdCBjaGFyKiBMQ01TRVhQT1JUIGNtc0lUOEdldERhdGEoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjUGF0Y2gsIGNvbnN0IGNoYXIqIGNTYW1wbGUpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKICAgIGludCBpRmllbGQsIGlTZXQ7CgoKICAgIGlGaWVsZCA9IExvY2F0ZVNhbXBsZShpdDgsIGNTYW1wbGUpOwogICAgaWYgKGlGaWVsZCA8IDApIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCgogICAgaVNldCA9IExvY2F0ZVBhdGNoKGl0OCwgY1BhdGNoKTsKICAgIGlmIChpU2V0IDwgMCkgewogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gR2V0RGF0YShpdDgsIGlTZXQsIGlGaWVsZCk7Cn0KCgpkb3VibGUgTENNU0VYUE9SVCBjbXNJVDhHZXREYXRhRGJsKExDTVNIQU5ETEUgaXQ4LCBjb25zdCBjaGFyKiBjUGF0Y2gsIGNvbnN0IGNoYXIqIGNTYW1wbGUpCnsKICAgIGNvbnN0IGNoYXIqIEJ1ZmZlcjsKCiAgICBCdWZmZXIgPSBjbXNJVDhHZXREYXRhKGl0OCwgY1BhdGNoLCBjU2FtcGxlKTsKCiAgICBpZiAoQnVmZmVyKSB7CgogICAgICAgIHJldHVybiBhdG9mKEJ1ZmZlcik7CgogICAgfSBlbHNlIHsKCiAgICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KCgoKTENNU0JPT0wgTENNU0VYUE9SVCBjbXNJVDhTZXREYXRhKExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1BhdGNoLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBjU2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpWYWwpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKICAgIGludCBpRmllbGQsIGlTZXQ7CiAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwoKCiAgICBpRmllbGQgPSBMb2NhdGVTYW1wbGUoaXQ4LCBjU2FtcGxlKTsKCiAgICBpZiAoaUZpZWxkIDwgMCkKICAgICAgICByZXR1cm4gRkFMU0U7CgoKCiAgICAgICAgaWYgKHQtPiBuUGF0Y2hlcyA9PSAwKSB7CgogICAgICAgICAgICAgICAgQWxsb2NhdGVEYXRhRm9ybWF0KGl0OCk7CiAgICAgICAgICAgICAgICBBbGxvY2F0ZURhdGFTZXQoaXQ4KTsKICAgICAgICAgICAgICAgIENvb2tQb2ludGVycyhpdDgpOwogICAgICAgIH0KCgogICAgICAgIGlmIChzdHJpY21wKGNTYW1wbGUsICJTQU1QTEVfSUQiKSA9PSAwKQogICAgICAgIHsKCiAgICAgICAgICAgICAgICBpU2V0ICAgPSBMb2NhdGVFbXB0eVBhdGNoKGl0OCk7CiAgICAgICAgICAgICAgICBpZiAoaVNldCA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFN5bkVycm9yKGl0OCwgIkNvdWxkbid0IGFkZCBtb3JlIHBhdGNoZXMgJyVzJ1xuIiwgY1BhdGNoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpRmllbGQgPSB0IC0+IFNhbXBsZUlEOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGlTZXQgPSBMb2NhdGVQYXRjaChpdDgsIGNQYXRjaCk7CiAgICAgICAgICAgICAgICBpZiAoaVNldCA8IDApIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBTZXREYXRhKGl0OCwgaVNldCwgaUZpZWxkLCBWYWwpOwp9CgoKTENNU0JPT0wgTENNU0VYUE9SVCBjbXNJVDhTZXREYXRhRGJsKExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciogY1BhdGNoLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBjU2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgVmFsKQp7CiAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CiAgICBjaGFyIEJ1ZmZbMjU2XTsKCiAgICAgICAgc25wcmludGYoQnVmZiwgMjU1LCBpdDgtPkRvdWJsZUZvcm1hdHRlciwgVmFsKTsKICAgICAgICByZXR1cm4gY21zSVQ4U2V0RGF0YShoSVQ4LCBjUGF0Y2gsIGNTYW1wbGUsIEJ1ZmYpOwoKfQoKLy8gQnVmZmVyIHNob3VsZCBnZXQgTUFYU1RSIGF0IGxlYXN0Cgpjb25zdCBjaGFyKiBMQ01TRVhQT1JUIGNtc0lUOEdldFBhdGNoTmFtZShMQ01TSEFORExFIGhJVDgsIGludCBuUGF0Y2gsIGNoYXIqIGJ1ZmZlcikKewogICAgICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKICAgICAgICBMUFRBQkxFIHQgPSBHZXRUYWJsZShpdDgpOwogICAgICAgIGNoYXIqIERhdGEgPSBHZXREYXRhKGl0OCwgblBhdGNoLCB0LT5TYW1wbGVJRCk7CgogICAgICAgIGlmICghRGF0YSkgcmV0dXJuIE5VTEw7CiAgICAgICAgaWYgKCFidWZmZXIpIHJldHVybiBEYXRhOwoKICAgICAgICBzdHJuY3B5KGJ1ZmZlciwgRGF0YSwgTUFYU1RSLTEpOwogICAgICAgIGJ1ZmZlcltNQVhTVFItMV0gPSAwOwogICAgICAgIHJldHVybiBidWZmZXI7Cn0KCmludCBMQ01TRVhQT1JUIGNtc0lUOEdldFBhdGNoQnlOYW1lKExDTVNIQU5ETEUgaElUOCwgY29uc3QgY2hhciAqY1BhdGNoKQp7CiAgICByZXR1cm4gTG9jYXRlUGF0Y2goKExQSVQ4KWhJVDgsIGNQYXRjaCk7Cn0KCmludCBMQ01TRVhQT1JUIGNtc0lUOFRhYmxlQ291bnQoTENNU0hBTkRMRSBoSVQ4KQp7CiAgICAgICAgTFBJVDggaXQ4ID0gKExQSVQ4KSBoSVQ4OwoKICAgICAgICByZXR1cm4gaXQ4IC0+VGFibGVzQ291bnQ7Cn0KCi8vIFRoaXMgaGFuZGxlcyB0aGUgIkxBQkVMIiBleHRlbnNpb24uCi8vIExhYmVsLCBuVGFibGUsIFR5cGUKCmludCBMQ01TRVhQT1JUIGNtc0lUOFNldFRhYmxlQnlMYWJlbChMQ01TSEFORExFIGhJVDgsIGNvbnN0IGNoYXIqIGNTZXQsIGNvbnN0IGNoYXIqIGNGaWVsZCwgY29uc3QgY2hhciogRXhwZWN0ZWRUeXBlKQp7CiAgICBjb25zdCBjaGFyKiBjTGFiZWxGbGQ7CiAgICBjaGFyIFR5cGVbMjU2XSwgTGFiZWxbMjU2XTsKICAgIGludCBuVGFibGU7CgogICAgaWYgKGNGaWVsZCAhPSBOVUxMICYmICpjRmllbGQgPT0gMCkKICAgICAgICAgICAgY0ZpZWxkID0gIkxBQkVMIjsKCiAgICBpZiAoY0ZpZWxkID09IE5VTEwpCiAgICAgICAgICAgIGNGaWVsZCA9ICJMQUJFTCI7CgogICAgY0xhYmVsRmxkID0gY21zSVQ4R2V0RGF0YShoSVQ4LCBjU2V0LCBjRmllbGQpOwogICAgaWYgKCFjTGFiZWxGbGQpIHJldHVybiAtMTsKCiAgICBpZiAoc3NjYW5mKGNMYWJlbEZsZCwgIiUyNTVzICVkICUyNTVzIiwgTGFiZWwsICZuVGFibGUsIFR5cGUpICE9IDMpCiAgICAgICAgICAgIHJldHVybiAtMTsKCiAgICBpZiAoRXhwZWN0ZWRUeXBlICE9IE5VTEwgJiYgKkV4cGVjdGVkVHlwZSA9PSAwKQogICAgICAgIEV4cGVjdGVkVHlwZSA9IE5VTEw7CgogICAgaWYgKEV4cGVjdGVkVHlwZSkgewoKICAgICAgICBpZiAoc3RyaWNtcChUeXBlLCBFeHBlY3RlZFR5cGUpICE9IDApIHJldHVybiAtMTsKICAgIH0KCiAgICByZXR1cm4gY21zSVQ4U2V0VGFibGUoaElUOCwgblRhYmxlKTsKfQoKCkxDTVNCT09MIExDTVNFWFBPUlQgY21zSVQ4U2V0SW5kZXhDb2x1bW4oTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBjU2FtcGxlKQp7CiAgICBMUElUOCBpdDggPSAoTFBJVDgpIGhJVDg7CgogICAgaW50IHBvcyA9IExvY2F0ZVNhbXBsZShpdDgsIGNTYW1wbGUpOwogICAgaWYocG9zID09IC0xKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpdDgtPlRhYltpdDgtPm5UYWJsZV0uU2FtcGxlSUQgPSBwb3M7CiAgICByZXR1cm4gVFJVRTsKfQoKCnZvaWQgTENNU0VYUE9SVCBjbXNJVDhEZWZpbmVEYmxGb3JtYXQoTENNU0hBTkRMRSBoSVQ4LCBjb25zdCBjaGFyKiBGb3JtYXR0ZXIpCnsKICAgIExQSVQ4IGl0OCA9IChMUElUOCkgaElUODsKCiAgICBpZiAoRm9ybWF0dGVyID09IE5VTEwpCiAgICAgICAgc3RyY3B5KGl0OC0+RG91YmxlRm9ybWF0dGVyLCBERUZBVUxUX0RCTF9GT1JNQVQpOwogICAgZWxzZQogICAgICAgIHN0cmNweShpdDgtPkRvdWJsZUZvcm1hdHRlciwgRm9ybWF0dGVyKTsKfQoK