LyoqIEBmaWxlDQogIE1kZSBVRUZJIGxpYnJhcnkgZnVuY3Rpb25zLg0KDQogIENvcHlyaWdodCAoYykgMjAwNiwgSW50ZWwgQ29ycG9yYXRpb248QlI+DQogIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICBhcmUgbGljZW5zZWQgYW5kIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB0aGUgQlNEIExpY2Vuc2UgICAgICAgICANCiAgd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24uICBUaGUgZnVsbCB0ZXh0IG9mIHRoZSBsaWNlbnNlIG1heSBiZSBmb3VuZCBhdCAgICAgICAgDQogIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9ic2QtbGljZW5zZS5waHAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KDQogIFRIRSBQUk9HUkFNIElTIERJU1RSSUJVVEVEIFVOREVSIFRIRSBCU0QgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCAgICAgICAgICAgICAgICAgICAgIA0KICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgUkVQUkVTRU5UQVRJT05TIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELiAgICAgICAgICAgICANCg0KICBNb2R1bGUgTmFtZTogIFVlZmlMaWIuYw0KDQoqKi8NCg0KLyoqDQogIENvbXBhcmUgd2hldGhlciB0d28gbmFtZXMgb2YgbGFuZ3VhZ2VzIGFyZSBpZGVudGljYWwuDQoNCiAgQHBhcmFtICBMYW5ndWFnZTEgTmFtZSBvZiBsYW5ndWFnZSAxLg0KICBAcGFyYW0gIExhbmd1YWdlMiBOYW1lIG9mIGxhbmd1YWdlIDIuDQoNCiAgQHJldHZhbCBUUlVFICAgICAgTGFuZ3VhZ2UgMSBhbmQgbGFuZ3VhZ2UgMiBhcmUgdGhlIHNhbWUuDQogIEByZXR2YWwgRkFMU0UgICAgIExhbmd1YWdlIDEgYW5kIGxhbmd1YWdlIDIgYXJlIG5vdCB0aGUgc2FtZS4NCg0KKiovDQpCT09MRUFODQpDb21wYXJlSXNvNjM5TGFuZ3VhZ2VDb2RlICgNCiAgSU4gQ09OU1QgQ0hBUjggICpMYW5ndWFnZTEsDQogIElOIENPTlNUIENIQVI4ICAqTGFuZ3VhZ2UyDQogICkNCnsNCiAgcmV0dXJuIChCT09MRUFOKSAoUmVhZFVuYWxpZ25lZDI0ICgoQ09OU1QgVUlOVDMyICopIExhbmd1YWdlMSkgPT0gUmVhZFVuYWxpZ25lZDI0ICgoQ09OU1QgVUlOVDMyICopIExhbmd1YWdlMikpOw0KfQ0KDQovKioNCiAgVGhpcyBmdW5jdGlvbiBzZWFyY2hlcyB0aGUgbGlzdCBvZiBjb25maWd1cmF0aW9uIHRhYmxlcyBzdG9yZWQgaW4gdGhlIEVGSSBTeXN0ZW0gDQogIFRhYmxlIGZvciBhIHRhYmxlIHdpdGggYSBHVUlEIHRoYXQgbWF0Y2hlcyBUYWJsZUd1aWQuICBJZiBhIG1hdGNoIGlzIGZvdW5kLCANCiAgdGhlbiBhIHBvaW50ZXIgdG8gdGhlIGNvbmZpZ3VyYXRpb24gdGFibGUgaXMgcmV0dXJuZWQgaW4gVGFibGUsIGFuZCBFRklfU1VDQ0VTUyANCiAgaXMgcmV0dXJuZWQuICBJZiBhIG1hdGNoaW5nIEdVSUQgaXMgbm90IGZvdW5kLCB0aGVuIEVGSV9OT1RfRk9VTkQgaXMgcmV0dXJuZWQuDQoNCiAgQHBhcmFtICBUYWJsZUd1aWQgICAgICAgUG9pbnRlciB0byB0YWJsZSdzIEdVSUQgdHlwZS4uDQogIEBwYXJhbSAgVGFibGUgICAgICAgICAgIFBvaW50ZXIgdG8gdGhlIHRhYmxlIGFzc29jaWF0ZWQgd2l0aCBUYWJsZUd1aWQgaW4gdGhlIEVGSSBTeXN0ZW0gVGFibGUuDQoNCiAgQHJldHZhbCBFRklfU1VDQ0VTUyAgICAgQSBjb25maWd1cmF0aW9uIHRhYmxlIG1hdGNoaW5nIFRhYmxlR3VpZCB3YXMgZm91bmQuDQogIEByZXR2YWwgRUZJX05PVF9GT1VORCAgIEEgY29uZmlndXJhdGlvbiB0YWJsZSBtYXRjaGluZyBUYWJsZUd1aWQgY291bGQgbm90IGJlIGZvdW5kLg0KDQoqKi8NCkVGSV9TVEFUVVMNCkVGSUFQSQ0KRWZpR2V0U3lzdGVtQ29uZmlndXJhdGlvblRhYmxlICggIA0KICBJTiAgRUZJX0dVSUQgICpUYWJsZUd1aWQsDQogIE9VVCBWT0lEICAgICAgKipUYWJsZQ0KICApDQp7DQogIEVGSV9TWVNURU1fVEFCTEUgICpTeXN0ZW1UYWJsZTsNCiAgVUlOVE4gICAgICAgICAgICAgSW5kZXg7DQoNCiAgQVNTRVJUIChUYWJsZUd1aWQgIT0gTlVMTCk7DQogIEFTU0VSVCAoVGFibGUgIT0gTlVMTCk7DQoNCiAgU3lzdGVtVGFibGUgPSBnU1Q7DQogICpUYWJsZSA9IE5VTEw7DQogIGZvciAoSW5kZXggPSAwOyBJbmRleCA8IFN5c3RlbVRhYmxlLT5OdW1iZXJPZlRhYmxlRW50cmllczsgSW5kZXgrKykgew0KICAgIGlmIChDb21wYXJlR3VpZCAoVGFibGVHdWlkLCAmKFN5c3RlbVRhYmxlLT5Db25maWd1cmF0aW9uVGFibGVbSW5kZXhdLlZlbmRvckd1aWQpKSkgew0KICAgICAgKlRhYmxlID0gU3lzdGVtVGFibGUtPkNvbmZpZ3VyYXRpb25UYWJsZVtJbmRleF0uVmVuZG9yVGFibGU7DQogICAgICByZXR1cm4gRUZJX1NVQ0NFU1M7DQogICAgfQ0KICB9DQoNCiAgcmV0dXJuIEVGSV9OT1RfRk9VTkQ7DQp9DQoNCi8qKg0KICBUaGlzIGZ1bmN0aW9uIGNhdXNlcyB0aGUgbm90aWZpY2F0aW9uIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGZvciBldmVyeSBwcm90b2NvbCANCiAgb2YgdHlwZSBQcm90b2NvbEd1aWQgaW5zdGFuY2UgdGhhdCBleGlzdHMgaW4gdGhlIHN5c3RlbSB3aGVuIHRoaXMgZnVuY3Rpb24gaXMgDQogIGludm9rZWQuICBJbiBhZGRpdGlvbiwgZXZlcnkgdGltZSBhIHByb3RvY29sIG9mIHR5cGUgUHJvdG9jb2xHdWlkIGluc3RhbmNlIGlzIA0KICBpbnN0YWxsZWQgb3IgcmVpbnN0YWxsZWQsIHRoZSBub3RpZmljYXRpb24gZnVuY3Rpb24gaXMgYWxzbyBleGVjdXRlZC4NCg0KICBAcGFyYW0gIFByb3RvY29sR3VpZCAgICBTdXBwbGllcyBHVUlEIG9mIHRoZSBwcm90b2NvbCB1cG9uIHdob3NlIGluc3RhbGxhdGlvbiB0aGUgZXZlbnQgaXMgZmlyZWQuDQogIEBwYXJhbSAgTm90aWZ5VHBsICAgICAgIFN1cHBsaWVzIHRoZSB0YXNrIHByaW9yaXR5IGxldmVsIG9mIHRoZSBldmVudCBub3RpZmljYXRpb25zLg0KICBAcGFyYW0gIE5vdGlmeUZ1bmN0aW9uICBTdXBwbGllcyB0aGUgZnVuY3Rpb24gdG8gbm90aWZ5IHdoZW4gdGhlIGV2ZW50IGlzIHNpZ25hbGVkLg0KICBAcGFyYW0gIE5vdGlmeUNvbnRleHQgICBUaGUgY29udGV4dCBwYXJhbWV0ZXIgdG8gcGFzcyB0byBOb3RpZnlGdW5jdGlvbi4NCiAgQHBhcmFtICBSZWdpc3RyYXRpb24gICAgQSBwb2ludGVyIHRvIGEgbWVtb3J5IGxvY2F0aW9uIHRvIHJlY2VpdmUgdGhlIHJlZ2lzdHJhdGlvbiB2YWx1ZS4NCg0KICBAcmV0dXJuIFRoZSBub3RpZmljYXRpb24gZXZlbnQgdGhhdCB3YXMgY3JlYXRlZC4gDQoNCioqLw0KRUZJX0VWRU5UDQpFRklBUEkNCkVmaUNyZWF0ZVByb3RvY29sTm90aWZ5RXZlbnQoDQogIElOICBFRklfR1VJRCAgICAgICAgICAqUHJvdG9jb2xHdWlkLA0KICBJTiAgRUZJX1RQTCAgICAgICAgICAgTm90aWZ5VHBsLA0KICBJTiAgRUZJX0VWRU5UX05PVElGWSAgTm90aWZ5RnVuY3Rpb24sDQogIElOICBWT0lEICAgICAgICAgICAgICAqTm90aWZ5Q29udGV4dCwgIE9QVElPTkFMDQogIE9VVCBWT0lEICAgICAgICAgICAgICAqUmVnaXN0cmF0aW9uDQogICkNCnsNCiAgRUZJX1NUQVRVUyAgU3RhdHVzOw0KICBFRklfRVZFTlQgICBFdmVudDsNCg0KICAvLw0KICAvLyBDcmVhdGUgdGhlIGV2ZW50DQogIC8vDQoNCiAgU3RhdHVzID0gZ0JTLT5DcmVhdGVFdmVudCAoDQogICAgICAgICAgICAgICAgICBFRklfRVZFTlRfTk9USUZZX1NJR05BTCwNCiAgICAgICAgICAgICAgICAgIE5vdGlmeVRwbCwNCiAgICAgICAgICAgICAgICAgIE5vdGlmeUZ1bmN0aW9uLA0KICAgICAgICAgICAgICAgICAgTm90aWZ5Q29udGV4dCwNCiAgICAgICAgICAgICAgICAgICZFdmVudA0KICAgICAgICAgICAgICAgICAgKTsNCiAgQVNTRVJUX0VGSV9FUlJPUiAoU3RhdHVzKTsNCg0KICAvLw0KICAvLyBSZWdpc3RlciBmb3IgcHJvdG9jb2wgbm90aWZhY3Rpb25zIG9uIHRoaXMgZXZlbnQNCiAgLy8NCg0KICBTdGF0dXMgPSBnQlMtPlJlZ2lzdGVyUHJvdG9jb2xOb3RpZnkgKA0KICAgICAgICAgICAgICAgICAgUHJvdG9jb2xHdWlkLA0KICAgICAgICAgICAgICAgICAgRXZlbnQsDQogICAgICAgICAgICAgICAgICBSZWdpc3RyYXRpb24NCiAgICAgICAgICAgICAgICAgICk7DQoNCiAgQVNTRVJUX0VGSV9FUlJPUiAoU3RhdHVzKTsNCg0KICAvLw0KICAvLyBLaWNrIHRoZSBldmVudCBzbyB3ZSB3aWxsIHBlcmZvcm0gYW4gaW5pdGlhbCBwYXNzIG9mDQogIC8vIGN1cnJlbnQgaW5zdGFsbGVkIGRyaXZlcnMNCiAgLy8NCg0KICBnQlMtPlNpZ25hbEV2ZW50IChFdmVudCk7DQogIHJldHVybiBFdmVudDsNCn0NCg0KLyoqDQogIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyBhbiBldmVudCB1c2luZyBOb3RpZnlUcGwsIE5vaWZ5RnVuY3Rpb24sIGFuZCBOb3RpZnlDb250ZXh0Lg0KICBUaGlzIGV2ZW50IGlzIHNpZ25hbGVkIHdpdGggRWZpTmFtZWRFdmVudFNpZ25hbCgpLiAgVGhpcyBwcm92aWRlIHRoZSBhYmlsaXR5IGZvciANCiAgb25lIG9yIG1vcmUgbGlzdGVuZXJzIG9uIHRoZSBzYW1lIGV2ZW50IG5hbWVkIGJ5IHRoZSBHVUlEIHNwZWNpZmllZCBieSBOYW1lLg0KDQogIEBwYXJhbSAgTmFtZSAgICAgICAgICAgICAgICAgIFN1cHBsaWVzIEdVSUQgbmFtZSBvZiB0aGUgZXZlbnQuDQogIEBwYXJhbSAgTm90aWZ5VHBsICAgICAgICAgICAgIFN1cHBsaWVzIHRoZSB0YXNrIHByaW9yaXR5IGxldmVsIG9mIHRoZSBldmVudCBub3RpZmljYXRpb25zLg0KICBAcGFyYW0gIE5vdGlmeUZ1bmN0aW9uICAgICAgICBTdXBwbGllcyB0aGUgZnVuY3Rpb24gdG8gbm90aWZ5IHdoZW4gdGhlIGV2ZW50IGlzIHNpZ25hbGVkLg0KICBAcGFyYW0gIE5vdGlmeUNvbnRleHQgICAgICAgICBUaGUgY29udGV4dCBwYXJhbWV0ZXIgdG8gcGFzcyB0byBOb3RpZnlGdW5jdGlvbi4gDQogIEBwYXJhbSAgUmVnaXN0cmF0aW9uICAgICAgICAgIEEgcG9pbnRlciB0byBhIG1lbW9yeSBsb2NhdGlvbiB0byByZWNlaXZlIHRoZSByZWdpc3RyYXRpb24gdmFsdWUuDQoNCiAgQHJldHZhbCBFRklfU1VDQ0VTUyAgICAgICAgICAgQSBuYW1lZCBldmVudCB3YXMgY3JlYXRlZC4NCiAgQHJldHZhbCBFRklfT1VUX09GX1JFU09VUkNFUyAgVGhlcmUgYXJlIG5vdCBlbm91Z2ggcmVzb3VyY2UgdG8gY3JlYXRlIHRoZSBuYW1lZCBldmVudC4NCg0KKiovDQpFRklfU1RBVFVTDQpFRklBUEkNCkVmaU5hbWVkRXZlbnRMaXN0ZW4gKA0KICBJTiBDT05TVCBFRklfR1VJRCAgICAqTmFtZSwNCiAgSU4gRUZJX1RQTCAgICAgICAgICAgTm90aWZ5VHBsLA0KICBJTiBFRklfRVZFTlRfTk9USUZZICBOb3RpZnlGdW5jdGlvbiwNCiAgSU4gQ09OU1QgVk9JRCAgICAgICAgKk5vdGlmeUNvbnRleHQsICBPUFRJT05BTA0KICBPVVQgVk9JRCAgICAgICAgICAgICAqUmVnaXN0cmF0aW9uICAgIE9QVElPTkFMDQogICkNCnsNCiAgRUZJX1NUQVRVUyAgU3RhdHVzOw0KICBFRklfRVZFTlQgICBFdmVudDsNCiAgVk9JRCAgICAgICAgKlJlZ2lzdHJhdGlvbkxvY2FsOw0KDQogIC8vDQogIC8vIENyZWF0ZSBldmVudA0KICAvLw0KICBTdGF0dXMgPSBnQlMtPkNyZWF0ZUV2ZW50ICgNCiAgICAgICAgICAgICAgICAgIEVGSV9FVkVOVF9OT1RJRllfU0lHTkFMLA0KICAgICAgICAgICAgICAgICAgTm90aWZ5VHBsLA0KICAgICAgICAgICAgICAgICAgTm90aWZ5RnVuY3Rpb24sDQogICAgICAgICAgICAgICAgICAoVk9JRCAqKSBOb3RpZnlDb250ZXh0LA0KICAgICAgICAgICAgICAgICAgJkV2ZW50DQogICAgICAgICAgICAgICAgICApOw0KICBBU1NFUlRfRUZJX0VSUk9SIChTdGF0dXMpOw0KDQogIC8vDQogIC8vIFRoZSBSZWdpc3RyYXRpb24gaXMgbm90IG9wdGlvbmFsIHRvIFJlZ2lzdGVyUHJvdG9jb2xOb3RpZnkoKS4NCiAgLy8gVG8gbWFrZSBpdCBvcHRpb25hbCB0byBFZmlOYW1lZEV2ZW50TGlzdGVuKCksIG1heSBuZWVkIHRvIHN1YnN0aXR1dGUgd2l0aCBhIGxvY2FsLg0KICAvLw0KICBpZiAoUmVnaXN0cmF0aW9uICE9IE5VTEwpIHsNCiAgICBSZWdpc3RyYXRpb25Mb2NhbCA9IFJlZ2lzdHJhdGlvbjsNCiAgfSBlbHNlIHsNCiAgICBSZWdpc3RyYXRpb25Mb2NhbCA9ICZSZWdpc3RyYXRpb25Mb2NhbDsNCiAgfQ0KDQogIC8vDQogIC8vIFJlZ2lzdGVyIGZvciBhbiBpbnN0YWxsYXRpb24gb2YgcHJvdG9jb2wgaW50ZXJmYWNlDQogIC8vDQoNCiAgU3RhdHVzID0gZ0JTLT5SZWdpc3RlclByb3RvY29sTm90aWZ5ICgNCiAgICAgICAgICAgICAgICAgIChFRklfR1VJRCAqKSBOYW1lLA0KICAgICAgICAgICAgICAgICAgRXZlbnQsDQogICAgICAgICAgICAgICAgICBSZWdpc3RyYXRpb25Mb2NhbA0KICAgICAgICAgICAgICAgICAgKTsNCiAgQVNTRVJUX0VGSV9FUlJPUiAoU3RhdHVzKTsNCg0KICByZXR1cm4gRUZJX1NVQ0NFU1M7DQp9DQoNCi8qKg0KICBUaGlzIGZ1bmN0aW9uIHNpZ25hbHMgdGhlIG5hbWVkIGV2ZW50IHNwZWNpZmllZCBieSBOYW1lLiAgVGhlIG5hbWVkIGV2ZW50IG11c3QgDQogIGhhdmUgYmVlbiBjcmVhdGVkIHdpdGggRWZpTmFtZWRFdmVudExpc3RlbigpLg0KDQogIEBwYXJhbSAgTmFtZSAgICAgICAgICAgICAgICAgIFN1cHBsaWVzIEdVSUQgbmFtZSBvZiB0aGUgZXZlbnQuDQoNCiAgQHJldHZhbCBFRklfU1VDQ0VTUyAgICAgICAgICAgQSBuYW1lZCBldmVudCB3YXMgc2lnbmFsZWQuDQogIEByZXR2YWwgRUZJX09VVF9PRl9SRVNPVVJDRVMgIFRoZXJlIGFyZSBub3QgZW5vdWdoIHJlc291cmNlIHRvIHNpZ25hbCB0aGUgbmFtZWQgZXZlbnQuDQoNCioqLw0KRUZJX1NUQVRVUw0KRUZJQVBJDQpFZmlOYW1lZEV2ZW50U2lnbmFsICgNCiAgSU4gQ09OU1QgRUZJX0dVSUQgICpOYW1lDQogICkNCnsNCiAgRUZJX1NUQVRVUyAgU3RhdHVzOw0KICBFRklfSEFORExFICBIYW5kbGU7DQoNCiAgSGFuZGxlID0gTlVMTDsNCiAgU3RhdHVzID0gZ0JTLT5JbnN0YWxsUHJvdG9jb2xJbnRlcmZhY2UgKA0KICAgICAgICAgICAgICAgICAgJkhhbmRsZSwNCiAgICAgICAgICAgICAgICAgIChFRklfR1VJRCAqKSBOYW1lLA0KICAgICAgICAgICAgICAgICAgRUZJX05BVElWRV9JTlRFUkZBQ0UsDQogICAgICAgICAgICAgICAgICBOVUxMDQogICAgICAgICAgICAgICAgICApOw0KICBBU1NFUlRfRUZJX0VSUk9SIChTdGF0dXMpOw0KDQogIFN0YXR1cyA9IGdCUy0+VW5pbnN0YWxsUHJvdG9jb2xJbnRlcmZhY2UgKA0KICAgICAgICAgICAgICAgICAgSGFuZGxlLA0KICAgICAgICAgICAgICAgICAgKEVGSV9HVUlEICopIE5hbWUsDQogICAgICAgICAgICAgICAgICBOVUxMDQogICAgICAgICAgICAgICAgICApOw0KICBBU1NFUlRfRUZJX0VSUk9SIChTdGF0dXMpOw0KDQogIHJldHVybiBFRklfU1VDQ0VTUzsNCn0NCg0KDQovKioNCiAgVGhpcyBmdW5jdGlvbiBpbml0aWFsaXplcyBhIGJhc2ljIG11dHVhbCBleGNsdXNpb24gbG9jayB0byB0aGUgcmVsZWFzZWQgc3RhdGUgDQogIGFuZCByZXR1cm5zIHRoZSBsb2NrLiAgRWFjaCBsb2NrIHByb3ZpZGVzIG11dHVhbCBleGNsdXNpb24gYWNjZXNzIGF0IGl0cyB0YXNrIA0KICBwcmlvcml0eSBsZXZlbC4gIFNpbmNlIHRoZXJlIGlzIG5vIHByZWVtcHRpb24gb3IgbXVsdGlwcm9jZXNzb3Igc3VwcG9ydCBpbiBFRkksDQogIGFjcXVpcmluZyB0aGUgbG9jayBvbmx5IGNvbnNpc3RzIG9mIHJhaXNpbmcgdG8gdGhlIGxvY2tzIFRQTC4NCg0KICBAcGFyYW0gIExvY2sgICAgICAgQSBwb2ludGVyIHRvIHRoZSBsb2NrIGRhdGEgc3RydWN0dXJlIHRvIGluaXRpYWxpemUuDQogIEBwYXJhbSAgUHJpb3JpdHkgICBFRkkgVFBMIGFzc29jaWF0ZWQgd2l0aCB0aGUgbG9jay4NCg0KICBAcmV0dXJuIFRoZSBsb2NrLg0KDQoqKi8NCkVGSV9MT0NLICoNCkVGSUFQSQ0KRWZpSW5pdGlhbGl6ZUxvY2sgKA0KICBJTiBPVVQgRUZJX0xPQ0sgICpMb2NrLA0KICBJTiBFRklfVFBMICAgICAgICBQcmlvcml0eQ0KICApDQp7DQogIEFTU0VSVCAoTG9jayAhPSBOVUxMKTsNCiAgQVNTRVJUIChQcmlvcml0eSA8PSBFRklfVFBMX0hJR0hfTEVWRUwpOw0KDQogIExvY2stPlRwbCAgICAgICA9IFByaW9yaXR5Ow0KICBMb2NrLT5Pd25lclRwbCAgPSBFRklfVFBMX0FQUExJQ0FUSU9OOw0KICBMb2NrLT5Mb2NrICAgICAgPSBFZmlMb2NrUmVsZWFzZWQgOw0KICByZXR1cm4gTG9jazsNCn0NCg0KLyoqDQogIFRoaXMgZnVuY3Rpb24gcmFpc2VzIHRoZSBzeXN0ZW2hr3MgY3VycmVudCB0YXNrIHByaW9yaXR5IGxldmVsIHRvIHRoZSB0YXNrIA0KICBwcmlvcml0eSBsZXZlbCBvZiB0aGUgbXV0dWFsIGV4Y2x1c2lvbiBsb2NrLiAgVGhlbiwgaXQgcGxhY2VzIHRoZSBsb2NrIGluIHRoZSANCiAgYWNxdWlyZWQgc3RhdGUuDQoNCiAgQHBhcmFtICBQcmlvcml0eSAgVGhlIHRhc2sgcHJpb3JpdHkgbGV2ZWwgb2YgdGhlIGxvY2suDQoNCioqLw0KVk9JRA0KRUZJQVBJDQpFZmlBY3F1aXJlTG9jayAoDQogIElOIEVGSV9MT0NLICAqTG9jaw0KICApDQp7DQogIEFTU0VSVCAoTG9jayAhPSBOVUxMKTsNCiAgQVNTRVJUIChMb2NrLT5Mb2NrID09IEVmaUxvY2tSZWxlYXNlZCk7DQoNCiAgTG9jay0+T3duZXJUcGwgPSBnQlMtPlJhaXNlVFBMIChMb2NrLT5UcGwpOw0KICBMb2NrLT5Mb2NrICAgICA9IEVmaUxvY2tBY3F1aXJlZDsNCn0NCg0KLyoqDQogIFRoaXMgZnVuY3Rpb24gcmFpc2VzIHRoZSBzeXN0ZW2hr3MgY3VycmVudCB0YXNrIHByaW9yaXR5IGxldmVsIHRvIHRoZSB0YXNrIA0KICBwcmlvcml0eSBsZXZlbCBvZiB0aGUgbXV0dWFsIGV4Y2x1c2lvbiBsb2NrLiAgVGhlbiwgaXQgYXR0ZW1wdHMgdG8gcGxhY2UgdGhlIA0KICBsb2NrIGluIHRoZSBhY3F1aXJlZCBzdGF0ZS4NCg0KICBAcGFyYW0gIExvY2sgICAgICAgICAgICAgIEEgcG9pbnRlciB0byB0aGUgbG9jayB0byBhY3F1aXJlLg0KDQogIEByZXR2YWwgRUZJX1NVQ0NFU1MgICAgICAgVGhlIGxvY2sgd2FzIGFjcXVpcmVkLg0KICBAcmV0dmFsIEVGSV9BQ0NFU1NfREVOSUVEIFRoZSBsb2NrIGNvdWxkIG5vdCBiZSBhY3F1aXJlZCBiZWNhdXNlIGl0IGlzIGFscmVhZHkgb3duZWQuDQoNCioqLw0KRUZJX1NUQVRVUw0KRUZJQVBJDQpFZmlBY3F1aXJlTG9ja09yRmFpbCAoDQogIElOIEVGSV9MT0NLICAqTG9jaw0KICApDQp7DQoNCiAgQVNTRVJUIChMb2NrICE9IE5VTEwpOw0KICBBU1NFUlQgKExvY2stPkxvY2sgIT0gRWZpTG9ja1VuaW5pdGlhbGl6ZWQpOw0KDQogIGlmIChMb2NrLT5Mb2NrID09IEVmaUxvY2tBY3F1aXJlZCkgew0KICAgIC8vDQogICAgLy8gTG9jayBpcyBhbHJlYWR5IG93bmVkLCBzbyBiYWlsIG91dA0KICAgIC8vDQogICAgcmV0dXJuIEVGSV9BQ0NFU1NfREVOSUVEOw0KICB9DQoNCiAgTG9jay0+T3duZXJUcGwgPSBnQlMtPlJhaXNlVFBMIChMb2NrLT5UcGwpOw0KDQogIExvY2stPkxvY2sgPSBFZmlMb2NrQWNxdWlyZWQ7DQoNCiAgcmV0dXJuIEVGSV9TVUNDRVNTOw0KfQ0KDQovKioNCiAgVGhpcyBmdW5jdGlvbiB0cmFuc2l0aW9ucyBhIG11dHVhbCBleGNsdXNpb24gbG9jayBmcm9tIHRoZSBhY3F1aXJlZCBzdGF0ZSB0byANCiAgdGhlIHJlbGVhc2VkIHN0YXRlLCBhbmQgcmVzdG9yZXMgdGhlIHN5c3RlbaGvcyB0YXNrIHByaW9yaXR5IGxldmVsIHRvIGl0cyANCiAgcHJldmlvdXMgbGV2ZWwuDQoNCiAgQHBhcmFtICBMb2NrICBBIHBvaW50ZXIgdG8gdGhlIGxvY2sgdG8gcmVsZWFzZS4NCg0KKiovDQpWT0lEDQpFRklBUEkNCkVmaVJlbGVhc2VMb2NrICgNCiAgSU4gRUZJX0xPQ0sgICpMb2NrDQogICkNCnsNCiAgRUZJX1RQTCBUcGw7DQoNCiAgQVNTRVJUIChMb2NrICE9IE5VTEwpOw0KICBBU1NFUlQgKExvY2stPkxvY2sgPT0gRWZpTG9ja0FjcXVpcmVkKTsNCg0KICBUcGwgPSBMb2NrLT5Pd25lclRwbDsNCiAgDQogIExvY2stPkxvY2sgPSBFZmlMb2NrUmVsZWFzZWQ7DQoNCiAgZ0JTLT5SZXN0b3JlVFBMIChUcGwpOw0KfQ0KDQovKioNCiAgVGhpcyBmdW5jdGlvbiBsb29rcyB1cCBhIFVuaWNvZGUgc3RyaW5nIGluIFVuaWNvZGVTdHJpbmdUYWJsZS4gIElmIExhbmd1YWdlIGlzIA0KICBhIG1lbWJlciBvZiBTdXBwb3J0ZWRMYW5ndWFnZXMgYW5kIGEgVW5pY29kZSBzdHJpbmcgaXMgZm91bmQgaW4gVW5pY29kZVN0cmluZ1RhYmxlDQogIHRoYXQgbWF0Y2hlcyB0aGUgbGFuZ3VhZ2UgY29kZSBzcGVjaWZpZWQgYnkgTGFuZ3VhZ2UsIHRoZW4gaXQgaXMgcmV0dXJuZWQgaW4gDQogIFVuaWNvZGVTdHJpbmcuDQoNCiAgQHBhcmFtICBMYW5ndWFnZSAgICAgICAgICAgICAgICBBIHBvaW50ZXIgdG8gdGhlIElTTyA2MzktMiBsYW5ndWFnZSBjb2RlIGZvciB0aGUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZSBzdHJpbmcgdG8gbG9vayB1cCBhbmQgcmV0dXJuLg0KICBAcGFyYW0gIFN1cHBvcnRlZExhbmd1YWdlcyAgICAgIEEgcG9pbnRlciB0byB0aGUgc2V0IG9mIElTTyA2MzktMiBsYW5ndWFnZSBjb2RlcyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0IHRoZSBVbmljb2RlIHN0cmluZyB0YWJsZSBzdXBwb3J0cy4gIExhbmd1YWdlIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11c3QgYmUgYSBtZW1iZXIgb2YgdGhpcyBzZXQuDQogIEBwYXJhbSAgVW5pY29kZVN0cmluZ1RhYmxlICAgICAgQSBwb2ludGVyIHRvIHRoZSB0YWJsZSBvZiBVbmljb2RlIHN0cmluZ3MuDQogIEBwYXJhbSAgVW5pY29kZVN0cmluZyAgICAgICAgICAgQSBwb2ludGVyIHRvIHRoZSBVbmljb2RlIHN0cmluZyBmcm9tIFVuaWNvZGVTdHJpbmdUYWJsZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQgbWF0Y2hlcyB0aGUgbGFuZ3VhZ2Ugc3BlY2lmaWVkIGJ5IExhbmd1YWdlLg0KDQogIEByZXR2YWwgIEVGSV9TVUNDRVNTICAgICAgICAgICAgVGhlIFVuaWNvZGUgc3RyaW5nIHRoYXQgbWF0Y2hlcyB0aGUgbGFuZ3VhZ2UgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGJ5IExhbmd1YWdlIHdhcyBmb3VuZA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluIHRoZSB0YWJsZSBvZiBVbmljb2lkZSBzdHJpbmdzIFVuaWNvZGVTdHJpbmdUYWJsZSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIGl0IHdhcyByZXR1cm5lZCBpbiBVbmljb2RlU3RyaW5nLg0KICBAcmV0dmFsICBFRklfSU5WQUxJRF9QQVJBTUVURVIgIExhbmd1YWdlIGlzIE5VTEwuDQogIEByZXR2YWwgIEVGSV9JTlZBTElEX1BBUkFNRVRFUiAgVW5pY29kZVN0cmluZyBpcyBOVUxMLg0KICBAcmV0dmFsICBFRklfVU5TVVBQT1JURUQgICAgICAgIFN1cHBvcnRlZExhbmd1YWdlcyBpcyBOVUxMLg0KICBAcmV0dmFsICBFRklfVU5TVVBQT1JURUQgICAgICAgIFVuaWNvZGVTdHJpbmdUYWJsZSBpcyBOVUxMLg0KICBAcmV0dmFsICBFRklfVU5TVVBQT1JURUQgICAgICAgIFRoZSBsYW5ndWFnZSBzcGVjaWZpZWQgYnkgTGFuZ3VhZ2UgaXMgbm90IGEgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtYmVyIG9mIFN1cHBvcnRlZExhbmd1YWdlcy4NCiAgQHJldHZhbCAgRUZJX1VOU1VQUE9SVEVEICAgICAgICBUaGUgbGFuZ3VhZ2Ugc3BlY2lmaWVkIGJ5IExhbmd1YWdlIGlzIG5vdCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0ZWQgYnkgVW5pY29kZVN0cmluZ1RhYmxlLg0KDQoqKi8NCkVGSV9TVEFUVVMNCkVGSUFQSQ0KTG9va3VwVW5pY29kZVN0cmluZyAoDQogIElOIENPTlNUIENIQVI4ICAgICAgICAgICAgICAgICAgICAgKkxhbmd1YWdlLA0KICBJTiBDT05TVCBDSEFSOCAgICAgICAgICAgICAgICAgICAgICpTdXBwb3J0ZWRMYW5ndWFnZXMsDQogIElOIENPTlNUIEVGSV9VTklDT0RFX1NUUklOR19UQUJMRSAgKlVuaWNvZGVTdHJpbmdUYWJsZSwNCiAgT1VUIENIQVIxNiAgICAgICAgICAgICAgICAgICAgICAgICAqKlVuaWNvZGVTdHJpbmcNCiAgKQ0Kew0KICAvLw0KICAvLyBNYWtlIHN1cmUgdGhlIHBhcmFtZXRlcnMgYXJlIHZhbGlkDQogIC8vDQogIGlmIChMYW5ndWFnZSA9PSBOVUxMIHx8IFVuaWNvZGVTdHJpbmcgPT0gTlVMTCkgew0KICAgIHJldHVybiBFRklfSU5WQUxJRF9QQVJBTUVURVI7DQogIH0NCg0KICAvLw0KICAvLyBJZiB0aGVyZSBhcmUgbm8gc3VwcG9ydGVkIGxhbmd1YWdlcywgb3IgdGhlIFVuaWNvZGUgU3RyaW5nIFRhYmxlIGlzIGVtcHR5LCB0aGVuIHRoZQ0KICAvLyBVbmljb2RlIFN0cmluZyBzcGVjaWZpZWQgYnkgTGFuZ3VhZ2UgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIFVuaWNvZGUgU3RyaW5nIFRhYmxlDQogIC8vDQogIGlmIChTdXBwb3J0ZWRMYW5ndWFnZXMgPT0gTlVMTCB8fCBVbmljb2RlU3RyaW5nVGFibGUgPT0gTlVMTCkgew0KICAgIHJldHVybiBFRklfVU5TVVBQT1JURUQ7DQogIH0NCg0KICAvLw0KICAvLyBNYWtlIHN1cmUgTGFuZ3VhZ2UgaXMgaW4gdGhlIHNldCBvZiBTdXBwb3J0ZWQgTGFuZ3VhZ2VzDQogIC8vDQogIHdoaWxlICgqU3VwcG9ydGVkTGFuZ3VhZ2VzICE9IDApIHsNCiAgICBpZiAoQ29tcGFyZUlzbzYzOUxhbmd1YWdlQ29kZSAoTGFuZ3VhZ2UsIFN1cHBvcnRlZExhbmd1YWdlcykpIHsNCg0KICAgICAgLy8NCiAgICAgIC8vIFNlYXJjaCB0aGUgVW5pY29kZSBTdHJpbmcgVGFibGUgZm9yIHRoZSBtYXRjaGluZyBMYW5ndWFnZSBzcGVjaWZpZXINCiAgICAgIC8vDQogICAgICB3aGlsZSAoVW5pY29kZVN0cmluZ1RhYmxlLT5MYW5ndWFnZSAhPSBOVUxMKSB7DQogICAgICAgIGlmIChDb21wYXJlSXNvNjM5TGFuZ3VhZ2VDb2RlIChMYW5ndWFnZSwgVW5pY29kZVN0cmluZ1RhYmxlLT5MYW5ndWFnZSkpIHsNCg0KICAgICAgICAgIC8vDQogICAgICAgICAgLy8gQSBtYXRjaGluZyBzdHJpbmcgd2FzIGZvdW5kLCBzbyByZXR1cm4gaXQNCiAgICAgICAgICAvLw0KICAgICAgICAgICpVbmljb2RlU3RyaW5nID0gVW5pY29kZVN0cmluZ1RhYmxlLT5Vbmljb2RlU3RyaW5nOw0KICAgICAgICAgIHJldHVybiBFRklfU1VDQ0VTUzsNCiAgICAgICAgfQ0KDQogICAgICAgIFVuaWNvZGVTdHJpbmdUYWJsZSsrOw0KICAgICAgfQ0KDQogICAgICByZXR1cm4gRUZJX1VOU1VQUE9SVEVEOw0KICAgIH0NCg0KICAgIFN1cHBvcnRlZExhbmd1YWdlcyArPSAzOw0KICB9DQoNCiAgcmV0dXJuIEVGSV9VTlNVUFBPUlRFRDsNCn0NCg0KLyoqDQogIFRoaXMgZnVuY3Rpb24gYWRkcyBhIFVuaWNvZGUgc3RyaW5nIHRvIFVuaWNvZGVTdHJpbmdUYWJsZS4NCiAgSWYgTGFuZ3VhZ2UgaXMgYSBtZW1iZXIgb2YgU3VwcG9ydGVkTGFuZ3VhZ2VzIHRoZW4gVW5pY29kZVN0cmluZyBpcyBhZGRlZCB0byANCiAgVW5pY29kZVN0cmluZ1RhYmxlLiAgTmV3IGJ1ZmZlcnMgYXJlIGFsbG9jYXRlZCBmb3IgYm90aCBMYW5ndWFnZSBhbmQgDQogIFVuaWNvZGVTdHJpbmcuICBUaGUgY29udGVudHMgb2YgTGFuZ3VhZ2UgYW5kIFVuaWNvZGVTdHJpbmcgYXJlIGNvcGllZCBpbnRvIA0KICB0aGVzZSBuZXcgYnVmZmVycy4gIFRoZXNlIGJ1ZmZlcnMgYXJlIGF1dG9tYXRpY2FsbHkgZnJlZWQgd2hlbiANCiAgRnJlZVVuaWNvZGVTdHJpbmdUYWJsZSgpIGlzIGNhbGxlZC4NCg0KICBAcGFyYW0gIExhbmd1YWdlICAgICAgICAgICAgICAgIEEgcG9pbnRlciB0byB0aGUgSVNPIDYzOS0yIGxhbmd1YWdlIGNvZGUgZm9yIHRoZSBVbmljb2RlIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyB0byBhZGQuDQogIEBwYXJhbSAgU3VwcG9ydGVkTGFuZ3VhZ2VzICAgICAgQSBwb2ludGVyIHRvIHRoZSBzZXQgb2YgSVNPIDYzOS0yIGxhbmd1YWdlIGNvZGVzDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCB0aGUgVW5pY29kZSBzdHJpbmcgdGFibGUgc3VwcG9ydHMuDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGFuZ3VhZ2UgbXVzdCBiZSBhIG1lbWJlciBvZiB0aGlzIHNldC4NCiAgQHBhcmFtICBVbmljb2RlU3RyaW5nVGFibGUgICAgICBBIHBvaW50ZXIgdG8gdGhlIHRhYmxlIG9mIFVuaWNvZGUgc3RyaW5ncy4NCiAgQHBhcmFtICBVbmljb2RlU3RyaW5nICAgICAgICAgICBBIHBvaW50ZXIgdG8gdGhlIFVuaWNvZGUgc3RyaW5nIHRvIGFkZC4NCg0KICBAcmV0dmFsIEVGSV9TVUNDRVNTICAgICAgICAgICAgIFRoZSBVbmljb2RlIHN0cmluZyB0aGF0IG1hdGNoZXMgdGhlIGxhbmd1YWdlIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBieSBMYW5ndWFnZSB3YXMgZm91bmQgaW4gdGhlIHRhYmxlIG9mIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGUgc3RyaW5ncyBVbmljb2RlU3RyaW5nVGFibGUsIGFuZCBpdCB3YXMgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuZWQgaW4gVW5pY29kZVN0cmluZy4NCiAgQHJldHZhbCBFRklfSU5WQUxJRF9QQVJBTUVURVIgICBMYW5ndWFnZSBpcyBOVUxMLg0KICBAcmV0dmFsIEVGSV9JTlZBTElEX1BBUkFNRVRFUiAgIFVuaWNvZGVTdHJpbmcgaXMgTlVMTC4NCiAgQHJldHZhbCBFRklfSU5WQUxJRF9QQVJBTUVURVIgICBVbmljb2RlU3RyaW5nIGlzIGFuIGVtcHR5IHN0cmluZy4NCiAgQHJldHZhbCBFRklfVU5TVVBQT1JURUQgICAgICAgICBTdXBwb3J0ZWRMYW5ndWFnZXMgaXMgTlVMTC4NCiAgQHJldHZhbCBFRklfQUxSRUFEWV9TVEFSVEVEICAgICBBIFVuaWNvZGUgc3RyaW5nIHdpdGggbGFuZ3VhZ2UgTGFuZ3VhZ2UgaXMgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxyZWFkeSBwcmVzZW50IGluIFVuaWNvZGVTdHJpbmdUYWJsZS4NCiAgQHJldHZhbCBFRklfT1VUX09GX1JFU09VUkNFUyAgICBUaGVyZSBpcyBub3QgZW5vdWdoIG1lbW9yeSB0byBhZGQgYW5vdGhlciANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlIHN0cmluZyB0byBVbmljb2RlU3RyaW5nVGFibGUuDQogIEByZXR2YWwgRUZJX1VOU1VQUE9SVEVEICAgICAgICAgVGhlIGxhbmd1YWdlIHNwZWNpZmllZCBieSBMYW5ndWFnZSBpcyBub3QgYSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1iZXIgb2YgU3VwcG9ydGVkTGFuZ3VhZ2VzLg0KDQoqKi8NCkVGSV9TVEFUVVMNCkVGSUFQSQ0KQWRkVW5pY29kZVN0cmluZyAoDQogIElOIENPTlNUIENIQVI4ICAgICAgICAgICAgICAgKkxhbmd1YWdlLA0KICBJTiBDT05TVCBDSEFSOCAgICAgICAgICAgICAgICpTdXBwb3J0ZWRMYW5ndWFnZXMsDQogIElOIEVGSV9VTklDT0RFX1NUUklOR19UQUJMRSAgKipVbmljb2RlU3RyaW5nVGFibGUsDQogIElOIENPTlNUIENIQVIxNiAgICAgICAgICAgICAgKlVuaWNvZGVTdHJpbmcNCiAgKQ0Kew0KICBVSU5UTiAgICAgICAgICAgICAgICAgICAgIE51bWJlck9mRW50cmllczsNCiAgRUZJX1VOSUNPREVfU1RSSU5HX1RBQkxFICAqT2xkVW5pY29kZVN0cmluZ1RhYmxlOw0KICBFRklfVU5JQ09ERV9TVFJJTkdfVEFCTEUgICpOZXdVbmljb2RlU3RyaW5nVGFibGU7DQogIFVJTlROICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZ0xlbmd0aDsNCg0KICAvLw0KICAvLyBNYWtlIHN1cmUgdGhlIHBhcmFtZXRlciBhcmUgdmFsaWQNCiAgLy8NCiAgaWYgKExhbmd1YWdlID09IE5VTEwgfHwgVW5pY29kZVN0cmluZyA9PSBOVUxMIHx8IFVuaWNvZGVTdHJpbmdUYWJsZSA9PSBOVUxMKSB7DQogICAgcmV0dXJuIEVGSV9JTlZBTElEX1BBUkFNRVRFUjsNCiAgfQ0KDQogIC8vDQogIC8vIElmIHRoZXJlIGFyZSBubyBzdXBwb3J0ZWQgbGFuZ3VhZ2VzLCB0aGVuIGEgVW5pY29kZSBTdHJpbmcgY2FuIG5vdCBiZSBhZGRlZA0KICAvLw0KICBpZiAoU3VwcG9ydGVkTGFuZ3VhZ2VzID09IE5VTEwpIHsNCiAgICByZXR1cm4gRUZJX1VOU1VQUE9SVEVEOw0KICB9DQoNCiAgLy8NCiAgLy8gSWYgdGhlIFVuaWNvZGUgU3RyaW5nIGlzIGVtcHR5LCB0aGVuIGEgVW5pY29kZSBTdHJpbmcgY2FuIG5vdCBiZSBhZGRlZA0KICAvLw0KICBpZiAoVW5pY29kZVN0cmluZ1swXSA9PSAwKSB7DQogICAgcmV0dXJuIEVGSV9JTlZBTElEX1BBUkFNRVRFUjsNCiAgfQ0KDQogIC8vDQogIC8vIE1ha2Ugc3VyZSBMYW5ndWFnZSBpcyBhIG1lbWJlciBvZiBTdXBwb3J0ZWRMYW5ndWFnZXMNCiAgLy8NCiAgd2hpbGUgKCpTdXBwb3J0ZWRMYW5ndWFnZXMgIT0gMCkgew0KICAgIGlmIChDb21wYXJlSXNvNjM5TGFuZ3VhZ2VDb2RlIChMYW5ndWFnZSwgU3VwcG9ydGVkTGFuZ3VhZ2VzKSkgew0KDQogICAgICAvLw0KICAgICAgLy8gRGV0ZXJtaW5lIHRoZSBzaXplIG9mIHRoZSBVbmljb2RlIFN0cmluZyBUYWJsZSBieSBsb29raW5nIGZvciBhIE5VTEwgTGFuZ3VhZ2UgZW50cnkNCiAgICAgIC8vDQogICAgICBOdW1iZXJPZkVudHJpZXMgPSAwOw0KICAgICAgaWYgKCpVbmljb2RlU3RyaW5nVGFibGUgIT0gTlVMTCkgew0KICAgICAgICBPbGRVbmljb2RlU3RyaW5nVGFibGUgPSAqVW5pY29kZVN0cmluZ1RhYmxlOw0KICAgICAgICB3aGlsZSAoT2xkVW5pY29kZVN0cmluZ1RhYmxlLT5MYW5ndWFnZSAhPSBOVUxMKSB7DQogICAgICAgICAgaWYgKENvbXBhcmVJc282MzlMYW5ndWFnZUNvZGUgKExhbmd1YWdlLCBPbGRVbmljb2RlU3RyaW5nVGFibGUtPkxhbmd1YWdlKSkgew0KICAgICAgICAgICAgcmV0dXJuIEVGSV9BTFJFQURZX1NUQVJURUQ7DQogICAgICAgICAgfQ0KDQogICAgICAgICAgT2xkVW5pY29kZVN0cmluZ1RhYmxlKys7DQogICAgICAgICAgTnVtYmVyT2ZFbnRyaWVzKys7DQogICAgICAgIH0NCiAgICAgIH0NCg0KICAgICAgLy8NCiAgICAgIC8vIEFsbG9jYXRlIHNwYWNlIGZvciBhIG5ldyBVbmljb2RlIFN0cmluZyBUYWJsZS4gIEl0IG11c3QgaG9sZCB0aGUgY3VycmVudCBudW1iZXIgb2YNCiAgICAgIC8vIGVudHJpZXMsIHBsdXMgMSBlbnRyeSBmb3IgdGhlIG5ldyBVbmljb2RlIFN0cmluZywgcGx1cyAxIGVudHJ5IGZvciB0aGUgZW5kIG9mIHRhYmxlDQogICAgICAvLyBtYXJrZXINCiAgICAgIC8vDQogICAgICBOZXdVbmljb2RlU3RyaW5nVGFibGUgPSBBbGxvY2F0ZVBvb2wgKChOdW1iZXJPZkVudHJpZXMgKyAyKSAqIHNpemVvZiAoRUZJX1VOSUNPREVfU1RSSU5HX1RBQkxFKSk7DQogICAgICBpZiAoTmV3VW5pY29kZVN0cmluZ1RhYmxlID09IE5VTEwpIHsNCiAgICAgICAgcmV0dXJuIEVGSV9PVVRfT0ZfUkVTT1VSQ0VTOw0KICAgICAgfQ0KDQogICAgICAvLw0KICAgICAgLy8gSWYgdGhlIGN1cnJlbnQgVW5pY29kZSBTdHJpbmcgVGFibGUgY29udGFpbnMgYW55IGVudHJpZXMsIHRoZW4gY29weSB0aGVtIHRvIHRoZQ0KICAgICAgLy8gbmV3bHkgYWxsb2NhdGVkIFVuaWNvZGUgU3RyaW5nIFRhYmxlLg0KICAgICAgLy8NCiAgICAgIGlmICgqVW5pY29kZVN0cmluZ1RhYmxlICE9IE5VTEwpIHsNCiAgICAgICAgQ29weU1lbSAoDQogICAgICAgICAgIE5ld1VuaWNvZGVTdHJpbmdUYWJsZSwNCiAgICAgICAgICAgKlVuaWNvZGVTdHJpbmdUYWJsZSwNCiAgICAgICAgICAgTnVtYmVyT2ZFbnRyaWVzICogc2l6ZW9mIChFRklfVU5JQ09ERV9TVFJJTkdfVEFCTEUpDQogICAgICAgICAgICk7DQogICAgICB9DQoNCiAgICAgIC8vDQogICAgICAvLyBBbGxvY2F0ZSBzcGFjZSBmb3IgYSBjb3B5IG9mIHRoZSBMYW5ndWFnZSBzcGVjaWZpZXINCiAgICAgIC8vDQogICAgICBOZXdVbmljb2RlU3RyaW5nVGFibGVbTnVtYmVyT2ZFbnRyaWVzXS5MYW5ndWFnZSA9IEFsbG9jYXRlQ29weVBvb2wgKDMsIExhbmd1YWdlKTsNCiAgICAgIGlmIChOZXdVbmljb2RlU3RyaW5nVGFibGVbTnVtYmVyT2ZFbnRyaWVzXS5MYW5ndWFnZSA9PSBOVUxMKSB7DQogICAgICAgIGdCUy0+RnJlZVBvb2wgKE5ld1VuaWNvZGVTdHJpbmdUYWJsZSk7DQogICAgICAgIHJldHVybiBFRklfT1VUX09GX1JFU09VUkNFUzsNCiAgICAgIH0NCg0KICAgICAgLy8NCiAgICAgIC8vIENvbXB1dGUgdGhlIGxlbmd0aCBvZiB0aGUgVW5pY29kZSBTdHJpbmcNCiAgICAgIC8vDQogICAgICBmb3IgKFVuaWNvZGVTdHJpbmdMZW5ndGggPSAwOyBVbmljb2RlU3RyaW5nW1VuaWNvZGVTdHJpbmdMZW5ndGhdICE9IDA7IFVuaWNvZGVTdHJpbmdMZW5ndGgrKykNCiAgICAgICAgOw0KDQogICAgICAvLw0KICAgICAgLy8gQWxsb2NhdGUgc3BhY2UgZm9yIGEgY29weSBvZiB0aGUgVW5pY29kZSBTdHJpbmcNCiAgICAgIC8vDQogICAgICBOZXdVbmljb2RlU3RyaW5nVGFibGVbTnVtYmVyT2ZFbnRyaWVzXS5Vbmljb2RlU3RyaW5nID0gQWxsb2NhdGVDb3B5UG9vbCAoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChVbmljb2RlU3RyaW5nTGVuZ3RoICsgMSkgKiBzaXplb2YgKENIQVIxNiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsNCiAgICAgIGlmIChOZXdVbmljb2RlU3RyaW5nVGFibGVbTnVtYmVyT2ZFbnRyaWVzXS5Vbmljb2RlU3RyaW5nID09IE5VTEwpIHsNCiAgICAgICAgZ0JTLT5GcmVlUG9vbCAoTmV3VW5pY29kZVN0cmluZ1RhYmxlW051bWJlck9mRW50cmllc10uTGFuZ3VhZ2UpOw0KICAgICAgICBnQlMtPkZyZWVQb29sIChOZXdVbmljb2RlU3RyaW5nVGFibGUpOw0KICAgICAgICByZXR1cm4gRUZJX09VVF9PRl9SRVNPVVJDRVM7DQogICAgICB9DQoNCiAgICAgIC8vDQogICAgICAvLyBNYXJrIHRoZSBlbmQgb2YgdGhlIFVuaWNvZGUgU3RyaW5nIFRhYmxlDQogICAgICAvLw0KICAgICAgTmV3VW5pY29kZVN0cmluZ1RhYmxlW051bWJlck9mRW50cmllcyArIDFdLkxhbmd1YWdlICAgICAgID0gTlVMTDsNCiAgICAgIE5ld1VuaWNvZGVTdHJpbmdUYWJsZVtOdW1iZXJPZkVudHJpZXMgKyAxXS5Vbmljb2RlU3RyaW5nICA9IE5VTEw7DQoNCiAgICAgIC8vDQogICAgICAvLyBGcmVlIHRoZSBvbGQgVW5pY29kZSBTdHJpbmcgVGFibGUNCiAgICAgIC8vDQogICAgICBpZiAoKlVuaWNvZGVTdHJpbmdUYWJsZSAhPSBOVUxMKSB7DQogICAgICAgIGdCUy0+RnJlZVBvb2wgKCpVbmljb2RlU3RyaW5nVGFibGUpOw0KICAgICAgfQ0KDQogICAgICAvLw0KICAgICAgLy8gUG9pbnQgVW5pY29kZVN0cmluZ1RhYmxlIGF0IHRoZSBuZXdseSBhbGxvY2F0ZWQgVW5pY29kZSBTdHJpbmcgVGFibGUNCiAgICAgIC8vDQogICAgICAqVW5pY29kZVN0cmluZ1RhYmxlID0gTmV3VW5pY29kZVN0cmluZ1RhYmxlOw0KDQogICAgICByZXR1cm4gRUZJX1NVQ0NFU1M7DQogICAgfQ0KDQogICAgU3VwcG9ydGVkTGFuZ3VhZ2VzICs9IDM7DQogIH0NCg0KICByZXR1cm4gRUZJX1VOU1VQUE9SVEVEOw0KfQ0KDQovKioNCiAgVGhpcyBmdW5jdGlvbiBmcmVlcyB0aGUgdGFibGUgb2YgVW5pY29kZSBzdHJpbmdzIGluIFVuaWNvZGVTdHJpbmdUYWJsZS4NCiAgSWYgVW5pY29kZVN0cmluZ1RhYmxlIGlzIE5VTEwsIHRoZW4gRUZJX1NVQ0NFU1MgaXMgcmV0dXJuZWQuDQogIE90aGVyd2lzZSwgZWFjaCBsYW5ndWFnZSBjb2RlLCBhbmQgZWFjaCBVbmljb2RlIHN0cmluZyBpbiB0aGUgVW5pY29kZSBzdHJpbmcgDQogIHRhYmxlIGFyZSBmcmVlZCwgYW5kIEVGSV9TVUNDRVNTIGlzIHJldHVybmVkLg0KDQogIEBwYXJhbSAgVW5pY29kZVN0cmluZ1RhYmxlICBBIHBvaW50ZXIgdG8gdGhlIHRhYmxlIG9mIFVuaWNvZGUgc3RyaW5ncy4NCg0KICBAcmV0dmFsIEVGSV9TVUNDRVNTICAgICAgICAgVGhlIFVuaWNvZGUgc3RyaW5nIHRhYmxlIHdhcyBmcmVlZC4NCg0KKiovDQpFRklfU1RBVFVTDQpFRklBUEkNCkZyZWVVbmljb2RlU3RyaW5nVGFibGUgKA0KICBJTiBFRklfVU5JQ09ERV9TVFJJTkdfVEFCTEUgICpVbmljb2RlU3RyaW5nVGFibGUNCiAgKQ0Kew0KICBVSU5UTiBJbmRleDsNCg0KICAvLw0KICAvLyBJZiB0aGUgVW5pY29kZSBTdHJpbmcgVGFibGUgaXMgTlVMTCwgdGhlbiBpdCBpcyBhbHJlYWR5IGZyZWVkDQogIC8vDQogIGlmIChVbmljb2RlU3RyaW5nVGFibGUgPT0gTlVMTCkgew0KICAgIHJldHVybiBFRklfU1VDQ0VTUzsNCiAgfQ0KDQogIC8vDQogIC8vIExvb3AgdGhyb3VnaCB0aGUgVW5pY29kZSBTdHJpbmcgVGFibGUgdW50aWwgd2UgcmVhY2ggdGhlIGVuZCBvZiB0YWJsZSBtYXJrZXINCiAgLy8NCiAgZm9yIChJbmRleCA9IDA7IFVuaWNvZGVTdHJpbmdUYWJsZVtJbmRleF0uTGFuZ3VhZ2UgIT0gTlVMTDsgSW5kZXgrKykgew0KDQogICAgLy8NCiAgICAvLyBGcmVlIHRoZSBMYW5ndWFnZSBzdHJpbmcgZnJvbSB0aGUgVW5pY29kZSBTdHJpbmcgVGFibGUNCiAgICAvLw0KICAgIGdCUy0+RnJlZVBvb2wgKFVuaWNvZGVTdHJpbmdUYWJsZVtJbmRleF0uTGFuZ3VhZ2UpOw0KDQogICAgLy8NCiAgICAvLyBGcmVlIHRoZSBVbmljb2RlIFN0cmluZyBmcm9tIHRoZSBVbmljb2RlIFN0cmluZyBUYWJsZQ0KICAgIC8vDQogICAgaWYgKFVuaWNvZGVTdHJpbmdUYWJsZVtJbmRleF0uVW5pY29kZVN0cmluZyAhPSBOVUxMKSB7DQogICAgICBnQlMtPkZyZWVQb29sIChVbmljb2RlU3RyaW5nVGFibGVbSW5kZXhdLlVuaWNvZGVTdHJpbmcpOw0KICAgIH0NCiAgfQ0KDQogIC8vDQogIC8vIEZyZWUgdGhlIFVuaWNvZGUgU3RyaW5nIFRhYmxlIGl0c2VsZg0KICAvLw0KICBnQlMtPkZyZWVQb29sIChVbmljb2RlU3RyaW5nVGFibGUpOw0KDQogIHJldHVybiBFRklfU1VDQ0VTUzsNCn0NCg==