LyoNCiAqIFByb2plY3Q6IFZpektpdA0KICogVmVyc2lvbjogMS45DQogDQogKiBEYXRlOiAyMDA3MDUwMw0KICogRmlsZTogRGlzcGxheVJlc29sdXRpb25QYW5lLmNwcA0KICoNCiAqLw0KDQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQoNCkNvcHlyaWdodCAoYykgMjAwNC0yMDA3IEhlaWtvIFdpY2htYW5uIChodHRwOi8vd3d3LmltYWdvbWF0LmRlL3ZpemtpdCkNCg0KDQpUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3NlZCBvciBpbXBsaWVkIHdhcnJhbnR5Lg0KSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMNCmFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuDQoNClBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLA0KaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdA0KZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOg0KDQoxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7DQogICB5b3UgbXVzdCBub3QgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLg0KICAgSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQNCiAgIGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUgYXBwcmVjaWF0ZWQNCiAgIGJ1dCBpcyBub3QgcmVxdWlyZWQuDQoNCjIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwNCiAgIGFuZCBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuDQoNCjMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uDQoNCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovDQoNCiNpbmNsdWRlICJEaXNwbGF5UmVzb2x1dGlvblBhbmUuaCINCiNpbmNsdWRlICJWaXN1YWxDb25maWd1cmF0aW9uLmgiDQojaW5jbHVkZSAiVmlzdWFsR3JhcGhpY3MuaCINCiNpbmNsdWRlICJWaXN1YWxEYXRhU3RvcmUuaCINCiNpbmNsdWRlICJWaXN1YWxQcm9wZXJ0eVNoZWV0LmgiDQoNCiNpZmRlZiBfREVCVUcNCiNkZWZpbmUgbmV3IERFQlVHX05FVw0KI3VuZGVmIFRISVNfRklMRQ0Kc3RhdGljIGNoYXIgVEhJU19GSUxFW10gPSBfX0ZJTEVfXzsNCiNlbmRpZg0KDQoNCnVzaW5nIG5hbWVzcGFjZSBWaXpLaXQ7DQoNCklNUExFTUVOVF9EWU5DUkVBVEUoQ0Rpc3BsYXlSZXNvbHV0aW9uUGFuZSwgQ1Byb3BlcnR5UGFnZSkNCg0KQ0Rpc3BsYXlSZXNvbHV0aW9uUGFuZTo6Q0Rpc3BsYXlSZXNvbHV0aW9uUGFuZSgpIDogQ1Byb3BlcnR5UGFnZShDRGlzcGxheVJlc29sdXRpb25QYW5lOjpJREQpIHsNCgkvL3t7QUZYX0RBVEFfSU5JVChDRGlzcGxheVJlc29sdXRpb25QYW5lKQ0KCQkvLw0KCS8vfX1BRlhfREFUQV9JTklUDQp9DQoNCg0KQ0Rpc3BsYXlSZXNvbHV0aW9uUGFuZTo6fkNEaXNwbGF5UmVzb2x1dGlvblBhbmUoKSB7DQp9DQoNCg0Kdm9pZCBDRGlzcGxheVJlc29sdXRpb25QYW5lOjpEb0RhdGFFeGNoYW5nZShDRGF0YUV4Y2hhbmdlKiBwRFgpDQp7DQoJQ1Byb3BlcnR5UGFnZTo6RG9EYXRhRXhjaGFuZ2UocERYKTsNCgkvL3t7QUZYX0RBVEFfTUFQKENEaXNwbGF5UmVzb2x1dGlvblBhbmUpDQoJCS8vDQoJLy99fUFGWF9EQVRBX01BUA0KfQ0KDQoNCkJFR0lOX01FU1NBR0VfTUFQKENEaXNwbGF5UmVzb2x1dGlvblBhbmUsIENQcm9wZXJ0eVBhZ2UpDQoJLy97e0FGWF9NU0dfTUFQKENEaXNwbGF5UmVzb2x1dGlvblBhbmUpDQoJT05fQ0JOX1NFTENIQU5HRShJRENfQ09NQk8xLCBPblNlbGNoYW5nZUNvbWJvMSkNCgkvL319QUZYX01TR19NQVANCkVORF9NRVNTQUdFX01BUCgpDQoNCg0Kdm9pZCBDRGlzcGxheVJlc29sdXRpb25QYW5lOjpPblNlbGNoYW5nZUNvbWJvMSgpIHsNCgljaGFyIHN0clszMl07DQoJQ0NvbWJvQm94KiBwQ0IgPSAoQ0NvbWJvQm94KikgR2V0RGxnSXRlbShJRENfQ09NQk8xKTsNCg0KCXBDQi0+R2V0TEJUZXh0KHBDQi0+R2V0Q3VyU2VsKCksIHN0cik7DQoNCglWaXN1YWxHcmFwaGljcyogdGhlVmlzdWFsR3JhcGhpY3MgPSBWaXN1YWxHcmFwaGljczo6Z2V0SW5zdGFuY2UoKTsNCglVSW50MTYgaG9yaXpvbnRhbFBpeGVsczsNCglVSW50MTYgdmVydGljYWxQaXhlbHM7DQoJVUludDE2IGJpdHNQZXJQaXhlbDsNCglVSW50MTYgcmVmcmVzaFJhdGU7DQoJdGhlVmlzdWFsR3JhcGhpY3MtPm1hdGNoRGlzcGxheVJlc29sdXRpb25TaG93U3RyV2l0aFByZWZzKHN0ciwgaG9yaXpvbnRhbFBpeGVscywgdmVydGljYWxQaXhlbHMsIGJpdHNQZXJQaXhlbCwgcmVmcmVzaFJhdGUpOw0KDQoJVmlzdWFsRGF0YVN0b3JlOjpzZXRQcmVmZXJlbmNlVmFsdWVJbnQoVmlzdWFsQ29uZmlndXJhdGlvbjo6a0Z1bGxzY3JlZW5XaWR0aCwgaG9yaXpvbnRhbFBpeGVscyk7DQoJVmlzdWFsRGF0YVN0b3JlOjpzZXRQcmVmZXJlbmNlVmFsdWVJbnQoVmlzdWFsQ29uZmlndXJhdGlvbjo6a0Z1bGxzY3JlZW5IZWlnaHQsIHZlcnRpY2FsUGl4ZWxzKTsNCglWaXN1YWxEYXRhU3RvcmU6OnNldFByZWZlcmVuY2VWYWx1ZUludChWaXN1YWxDb25maWd1cmF0aW9uOjprRnVsbHNjcmVlbkJpdHNQZXJQaXhlbCwgYml0c1BlclBpeGVsKTsNCglWaXN1YWxEYXRhU3RvcmU6OnNldFByZWZlcmVuY2VWYWx1ZUludChWaXN1YWxDb25maWd1cmF0aW9uOjprRnVsbHNjcmVlblJlZnJlc2hSYXRlLCByZWZyZXNoUmF0ZSk7DQoJDQoJVmlzdWFsRGF0YVN0b3JlOjpzdG9yZVByZWZlcmVuY2VzKCk7DQoJDQoJVUludDE2IG1pbkJpdHNQZXJQaXhlbCA9IDI0Ow0KCVVJbnQxNiBtYXhCaXRzUGVyUGl4ZWwgPSAzMjsNCglWaXN1YWxEYXRhU3RvcmU6OnNldFByZWZlcnJlZERpc3BsYXlSZXNvbHV0aW9uKG1pbkJpdHNQZXJQaXhlbCwgbWF4Qml0c1BlclBpeGVsLCBiaXRzUGVyUGl4ZWwsIGhvcml6b250YWxQaXhlbHMsIHZlcnRpY2FsUGl4ZWxzKTsNCg0KfQ0KDQoNCkJPT0wgQ0Rpc3BsYXlSZXNvbHV0aW9uUGFuZTo6T25Jbml0RGlhbG9nKCkgew0KDQoJQ1Byb3BlcnR5UGFnZTo6T25Jbml0RGlhbG9nKCk7DQoNCglVSW50OCBpc1NlbGVjdGVkOw0KDQoJQ0NvbWJvQm94KiBwQ0IgPSAoQ0NvbWJvQm94KikgR2V0RGxnSXRlbShJRENfQ09NQk8xKTsNCg0KCVZpc3VhbEdyYXBoaWNzKiB0aGVWaXN1YWxHcmFwaGljczsNCgl0aGVWaXN1YWxHcmFwaGljcyA9IFZpc3VhbEdyYXBoaWNzOjpnZXRJbnN0YW5jZSgpOw0KCXRoZVZpc3VhbEdyYXBoaWNzLT5ldmFsdWF0ZUZ1bGxzY3JlZW5EaXNwbGF5UmVzb2x1dGlvbigpOw0KCS8vdGhlVmlzdWFsR3JhcGhpY3MtPmdhdGhlckF2YWlsYWJsZURpc3BsYXlSZXNvbHV0aW9ucygpOw0KDQoJLy90aGVWaXN1YWxHcmFwaGljcy0+cmVzZXREaXNwbGF5UmVzb2x1dGlvbkl0ZXJJbmRleCgpOw0KCWNoYXIgc2hvd1N0clszMl07DQoJVUludDE2IGNvdW50ID0gMDsNCglVSW50MTYgc2VsSWR4ID0gMDsNCgl3aGlsZSh0aGVWaXN1YWxHcmFwaGljcy0+Z2V0TmV4dEF2YWlsYWJsZURpc3BsYXlSZXNvbHV0aW9uKHNob3dTdHIsICZpc1NlbGVjdGVkKSkgew0KCQlpZiAoaXNTZWxlY3RlZCA9PSAxKSB7DQoJCQlzZWxJZHggPSBjb3VudDsNCgkJfQ0KCQlpZiAocENCLT5BZGRTdHJpbmcoc2hvd1N0cikgPT0gQ0JfRVJSKSB7DQoJCQlBZnhNZXNzYWdlQm94KCJBbkVycm9yIG9jY3VycmVkIHdoaWxlIGFkZGluZyBtb24gcmVzIGl0ZW0gdG8gY29tYm8gbGlzdC4iKTsNCgkJfQ0KCQljb3VudCsrOw0KCX0NCg0KCXBDQi0+U2V0Q3VyU2VsKHNlbElkeCk7DQoJDQoJcmV0dXJuIFRSVUU7ICAvLyByZXR1cm4gVFJVRSB1bmxlc3MgeW91IHNldCB0aGUgZm9jdXMgdG8gYSBjb250cm9sDQoJICAgICAgICAgICAgICAvLyBFWENFUFRJT046IE9DWC1FaWdlbnNjaGFmdGVuc2VpdGVuIHNvbGx0ZW4gRkFMU0UgenVy/GNrZ2ViZW4NCn0NCg0KDQpCT09MIENEaXNwbGF5UmVzb2x1dGlvblBhbmU6Ok9uU2V0QWN0aXZlKCkgDQp7DQoJQk9PTCBzdWNjZXNzOw0KCWludCBsYXN0UGFuZSA9IDA7DQoNCglzdWNjZXNzID0gQ1Byb3BlcnR5UGFnZTo6T25TZXRBY3RpdmUoKTsNCg0KCWlmIChDVmlzdWFsUHJvcGVydHlTaGVldDo6aXNJbml0aWFsaXplZCgpID09IHRydWUpIHsNCgkJbGFzdFBhbmUgPSBWaXN1YWxEYXRhU3RvcmU6OmdldFByZWZlcmVuY2VWYWx1ZUludChWaXN1YWxDb25maWd1cmF0aW9uOjprUHJlZmVyZW5jZVBhbmUpOw0KCQlpZiAobGFzdFBhbmUgIT0gMSkgew0KCQkJVmlzdWFsRGF0YVN0b3JlOjpzZXRQcmVmZXJlbmNlVmFsdWVJbnQoVmlzdWFsQ29uZmlndXJhdGlvbjo6a1ByZWZlcmVuY2VQYW5lLCAxKTsNCgkJCVZpc3VhbERhdGFTdG9yZTo6c3RvcmVQcmVmZXJlbmNlcygpOw0KCQl9DQoJfQ0KDQoJcmV0dXJuIHN1Y2Nlc3M7DQoNCn0NCg==