LyoNCglGcmVlUlRPUyBWNS40LjEgLSBDb3B5cmlnaHQgKEMpIDIwMDkgUmVhbCBUaW1lIEVuZ2luZWVycyBMdGQuDQoNCglUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgRnJlZVJUT1MgZGlzdHJpYnV0aW9uLg0KDQoJRnJlZVJUT1MgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAl1bmRlciANCgl0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlICh2ZXJzaW9uIDIpIGFzIHB1Ymxpc2hlZCBieSB0aGUgDQoJRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCBtb2RpZmllZCBieSB0aGUgRnJlZVJUT1MgZXhjZXB0aW9uLg0KCSoqTk9URSoqIFRoZSBleGNlcHRpb24gdG8gdGhlIEdQTCBpcyBpbmNsdWRlZCB0byBhbGxvdyB5b3UgdG8gZGlzdHJpYnV0ZSBhDQoJY29tYmluZWQgd29yayB0aGF0IGluY2x1ZGVzIEZyZWVSVE9TIHdpdGhvdXQgYmVpbmcgb2JsaWdlZCB0byBwcm92aWRlIHRoZSANCglzb3VyY2UgY29kZSBmb3IgcHJvcHJpZXRhcnkgY29tcG9uZW50cyBvdXRzaWRlIG9mIHRoZSBGcmVlUlRPUyBrZXJuZWwuICANCglBbHRlcm5hdGl2ZSBjb21tZXJjaWFsIGxpY2Vuc2UgYW5kIHN1cHBvcnQgdGVybXMgYXJlIGFsc28gYXZhaWxhYmxlIHVwb24gDQoJcmVxdWVzdC4gIFNlZSB0aGUgbGljZW5zaW5nIHNlY3Rpb24gb2YgaHR0cDovL3d3dy5GcmVlUlRPUy5vcmcgZm9yIGZ1bGwgDQoJbGljZW5zZSBkZXRhaWxzLg0KDQoJRnJlZVJUT1MgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwJYnV0IFdJVEhPVVQNCglBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3INCglGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yDQoJbW9yZSBkZXRhaWxzLg0KDQoJWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYWxvbmcNCgl3aXRoIEZyZWVSVE9TOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sIDU5DQoJVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQS4NCg0KDQoJKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQoJKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqDQoJKiBMb29raW5nIGZvciBhIHF1aWNrIHN0YXJ0PyAgVGhlbiBjaGVjayBvdXQgdGhlIEZyZWVSVE9TIGVCb29rISAgICAgICAgICAqDQoJKiBTZWUgaHR0cDovL3d3dy5GcmVlUlRPUy5vcmcvRG9jdW1lbnRhdGlvbiBmb3IgZGV0YWlscyAgICAgICAgICAgICAgICAgICAqDQoJKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqDQoJKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQoNCgkxIHRhYiA9PSA0IHNwYWNlcyENCg0KCVBsZWFzZSBlbnN1cmUgdG8gcmVhZCB0aGUgY29uZmlndXJhdGlvbiBhbmQgcmVsZXZhbnQgcG9ydCBzZWN0aW9ucyBvZiB0aGUNCglvbmxpbmUgZG9jdW1lbnRhdGlvbi4NCg0KCWh0dHA6Ly93d3cuRnJlZVJUT1Mub3JnIC0gRG9jdW1lbnRhdGlvbiwgbGF0ZXN0IGluZm9ybWF0aW9uLCBsaWNlbnNlIGFuZA0KCWNvbnRhY3QgZGV0YWlscy4NCg0KCWh0dHA6Ly93d3cuU2FmZVJUT1MuY29tIC0gQSB2ZXJzaW9uIHRoYXQgaXMgY2VydGlmaWVkIGZvciB1c2UgaW4gc2FmZXR5DQoJY3JpdGljYWwgc3lzdGVtcy4NCg0KCWh0dHA6Ly93d3cuT3BlblJUT1MuY29tIC0gQ29tbWVyY2lhbCBzdXBwb3J0LCBkZXZlbG9wbWVudCwgcG9ydGluZywNCglsaWNlbnNpbmcgYW5kIHRyYWluaW5nIHNlcnZpY2VzLg0KKi8NCg0KLyogU3RhbmRhcmQgaW5jbHVkZXMuICovDQojaW5jbHVkZSA8c3RyaW5nLmg+DQoNCi8qIFNjaGVkdWxlciBpbmNsdWRlcy4gKi8NCiNpbmNsdWRlICJGcmVlUlRPUy5oIg0KI2luY2x1ZGUgInNlbXBoci5oIg0KI2luY2x1ZGUgInRhc2suaCINCg0KLyogRGVtbyBhcHBsaWNhdGlvbiBpbmNsdWRlcy4gKi8NCiNpbmNsdWRlICJTQU03X0VNQUMuaCINCg0KLyogdUlQIGluY2x1ZGVzLiAqLw0KI2luY2x1ZGUgInVpcC5oIg0KDQovKiBIYXJkd2FyZSBzcGVjaWZpYyBpbmNsdWRlcy4gKi8NCiNpbmNsdWRlICJFbWFjLmgiDQojaW5jbHVkZSAibWlpLmgiDQojaW5jbHVkZSAiQVQ5MVNBTTdYMjU2LmgiDQoNCg0KLyogVVNFX1JNSUlfSU5URVJGQUNFIG11c3QgYmUgZGVmaW5lZCBhcyAxIHRvIHVzZSBhbiBSTUlJIGludGVyZmFjZSwgb3IgMA0KdG8gdXNlIGFuIE1JSSBpbnRlcmZhY2UuICovDQojZGVmaW5lIFVTRV9STUlJX0lOVEVSRkFDRSAwDQoNCi8qIFRoZSBidWZmZXIgYWRkcmVzc2VzIHdyaXR0ZW4gaW50byB0aGUgZGVzY3JpcHRvcnMgbXVzdCBiZSBhbGlnbmVkIHNvIHRoZQ0KbGFzdCBmZXcgYml0cyBhcmUgemVyby4gIFRoZXNlIGJpdHMgaGF2ZSBzcGVjaWFsIG1lYW5pbmcgZm9yIHRoZSBFTUFDDQpwZXJpcGhlcmFsIGFuZCBjYW5ub3QgYmUgdXNlZCBhcyBwYXJ0IG9mIHRoZSBhZGRyZXNzLiAqLw0KI2RlZmluZSBlbWFjQUREUkVTU19NQVNLCQkJKCAoIHVuc2lnbmVkIHBvcnRMT05HICkgMHhGRkZGRkZGQyApDQoNCi8qIEJpdCB1c2VkIHdpdGhpbiB0aGUgYWRkcmVzcyBzdG9yZWQgaW4gdGhlIGRlc2NyaXB0b3IgdG8gbWFyayB0aGUgbGFzdA0KZGVzY3JpcHRvciBpbiB0aGUgYXJyYXkuICovDQojZGVmaW5lIGVtYWNSWF9XUkFQX0JJVAkJCQkoICggdW5zaWduZWQgcG9ydExPTkcgKSAweDAyICkNCg0KLyogQml0IHVzZWQgd2l0aGluIHRoZSBUeCBkZXNjcmlwdG9yIHN0YXR1cyB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoZQ0KZGVzY3JpcHRvciBpcyB1bmRlciB0aGUgY29udHJvbCBvZiB0aGUgRU1BQyBvciB0aGUgc29mdHdhcmUuICovDQojZGVmaW5lIGVtYWNUWF9CVUZfVVNFRAkJCQkoICggdW5zaWduZWQgcG9ydExPTkcgKSAweDgwMDAwMDAwICkNCg0KLyogQSBzaG9ydCBkZWxheSBpcyB1c2VkIHRvIHdhaXQgZm9yIGEgYnVmZmVyIHRvIGJlY29tZSBhdmFpbGFibGUsIHNob3VsZA0Kb25lIG5vdCBiZSBpbW1lZGlhdGVseSBhdmFpbGFibGUgd2hlbiB0cnlpbmcgdG8gdHJhbnNtaXQgYSBmcmFtZS4gKi8NCiNkZWZpbmUgZW1hY0JVRkZFUl9XQUlUX0RFTEFZCQkoIDIgKQ0KI2RlZmluZSBlbWFjTUFYX1dBSVRfQ1lDTEVTCQkJKCBjb25maWdUSUNLX1JBVEVfSFogLyA0MCApDQoNCi8qIE1pc2MgZGVmaW5lcy4gKi8NCiNkZWZpbmUgZW1hY0lOVEVSUlVQVF9MRVZFTAkJCSggNSApDQojZGVmaW5lIGVtYWNOT19ERUxBWQkJCQkoIDAgKQ0KI2RlZmluZSBlbWFjVE9UQUxfRlJBTUVfSEVBREVSX1NJWkUJKCA1NCApDQojZGVmaW5lIGVtYWNQSFlfSU5JVF9ERUxBWQkJCSggNTAwMCAvIHBvcnRUSUNLX1JBVEVfTVMgKQ0KI2RlZmluZSBlbWFjUkVTRVRfS0VZCQkJCSggKCB1bnNpZ25lZCBwb3J0TE9ORyApIDB4QTUwMDAwMDAgKQ0KI2RlZmluZSBlbWFjUkVTRVRfTEVOR1RICQkJKCAoIHVuc2lnbmVkIHBvcnRMT05HICkgKCAweDAxIDw8IDggKSApDQoNCi8qIFRoZSBBdG1lbCBoZWFkZXIgZmlsZSBvbmx5IGRlZmluZXMgdGhlIFRYIGZyYW1lIGxlbmd0aCBtYXNrLiAqLw0KI2RlZmluZSBlbWFjUlhfTEVOR1RIX0ZSQU1FCQkJKCAweGZmZiApDQoNCi8qIFBlcmlwaGVyYWwgc2V0dXAgZm9yIHRoZSBFTUFDLiAqLw0KI2RlZmluZSBlbWFjUEVSSVBIRVJBTF9BX1NFVFVQIAkJKCAoIHVuc2lnbmVkIHBvcnRMT05HICkgQVQ5MUNfUEIyX0VUWDAJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIHBvcnRMT05HICkgQVQ5MUNfUEIxMl9FVFhFUgkJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBwb3J0TE9ORyApIEFUOTFDX1BCMTZfRUNPTAkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgcG9ydExPTkcgKSBBVDkxQ19QQjExX0VUWDMJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIHBvcnRMT05HICkgQVQ5MUNfUEI2X0VSWDEJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIHBvcnRMT05HICkgQVQ5MUNfUEIxNV9FUlhEVgkJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBwb3J0TE9ORyApIEFUOTFDX1BCMTNfRVJYMgkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgcG9ydExPTkcgKSBBVDkxQ19QQjNfRVRYMQkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgcG9ydExPTkcgKSBBVDkxQ19QQjhfRU1EQwkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgcG9ydExPTkcgKSBBVDkxQ19QQjVfRVJYMAkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgcG9ydExPTkcgKSBBVDkxQ19QQjE0X0VSWDMJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIHBvcnRMT05HICkgQVQ5MUNfUEI0X0VDUlNfRUNSU0RWCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgcG9ydExPTkcgKSBBVDkxQ19QQjFfRVRYRU4JCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIHBvcnRMT05HICkgQVQ5MUNfUEIxMF9FVFgyCQkJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBwb3J0TE9ORyApIEFUOTFDX1BCMF9FVFhDS19FUkVGQ0sJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBwb3J0TE9ORyApIEFUOTFDX1BCOV9FTURJTwkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgcG9ydExPTkcgKSBBVDkxQ19QQjdfRVJYRVIJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIHBvcnRMT05HICkgQVQ5MUNfUEIxN19FUlhDSwkJKTsNCg0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCi8qDQogKiBQcm90b3R5cGUgZm9yIHRoZSBFTUFDIGludGVycnVwdCBmdW5jdGlvbiAtIGNhbGxlZCBieSB0aGUgYXNtIHdyYXBwZXIuDQogKi8NCmV4dGVybiB2b2lkIHZFTUFDSVNSX1dyYXBwZXIoIHZvaWQgKSBfX2F0dHJpYnV0ZV9fKChuYWtlZCkpOw0KDQovKg0KICogSW5pdGlhbGlzZSBib3RoIHRoZSBUeCBhbmQgUnggZGVzY3JpcHRvcnMgdXNlZCBieSB0aGUgRU1BQy4NCiAqLw0Kc3RhdGljIHZvaWQgcHJ2U2V0dXBEZXNjcmlwdG9ycyh2b2lkKTsNCg0KLyoNCiAqIFdyaXRlIG91ciBNQUMgYWRkcmVzcyBpbnRvIHRoZSBFTUFDLiAgVGhlIE1BQyBhZGRyZXNzIGlzIHNldCBhcyBvbmUgb2YgdGhlDQogKiB1aXAgb3B0aW9ucy4NCiAqLw0Kc3RhdGljIHZvaWQgcHJ2U2V0dXBNQUNBZGRyZXNzKCB2b2lkICk7DQoNCi8qDQogKiBDb25maWd1cmUgdGhlIEVNQUMgYW5kIEFJQyBmb3IgRU1BQyBpbnRlcnJ1cHRzLg0KICovDQpzdGF0aWMgdm9pZCBwcnZTZXR1cEVNQUNJbnRlcnJ1cHQoIHZvaWQgKTsNCg0KLyoNCiAqIFNvbWUgaW5pdGlhbGlzYXRpb24gZnVuY3Rpb25zIHRha2VuIGZyb20gdGhlIEF0bWVsIEVNQUMgc2FtcGxlIGNvZGUuDQogKi8NCnN0YXRpYyB2b2lkIHZSZWFkUEhZKCB1bnNpZ25lZCBwb3J0Q0hBUiB1Y1BIWUFkZHJlc3MsIHVuc2lnbmVkIHBvcnRDSEFSIHVjQWRkcmVzcywgdW5zaWduZWQgcG9ydExPTkcgKnB1bFZhbHVlICk7DQojaWYgVVNFX1JNSUlfSU5URVJGQUNFICE9IDENCglzdGF0aWMgdm9pZCB2V3JpdGVQSFkoIHVuc2lnbmVkIHBvcnRDSEFSIHVjUEhZQWRkcmVzcywgdW5zaWduZWQgcG9ydENIQVIgdWNBZGRyZXNzLCB1bnNpZ25lZCBwb3J0TE9ORyB1bFZhbHVlKTsNCiNlbmRpZg0Kc3RhdGljIHBvcnRCQVNFX1RZUEUgeEdldExpbmtTcGVlZCggdm9pZCApOw0Kc3RhdGljIHBvcnRCQVNFX1RZUEUgcHJ2UHJvYmVQSFkoIHZvaWQgKTsNCg0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCi8qIEJ1ZmZlciB3cml0dGVuIHRvIGJ5IHRoZSBFTUFDIERNQS4gIE11c3QgYmUgYWxpZ25lZCBhcyBkZXNjcmliZWQgYnkgdGhlDQpjb21tZW50IGFib3ZlIHRoZSBlbWFjQUREUkVTU19NQVNLIGRlZmluaXRpb24uICovDQojcHJhZ21hIGRhdGFfYWxpZ25tZW50PTgNCnN0YXRpYyB2b2xhdGlsZSBwb3J0Q0hBUiBwY1J4QnVmZmVyWyBOQl9SWF9CVUZGRVJTICogRVRIX1JYX0JVRkZFUl9TSVpFIF07DQoNCi8qIEJ1ZmZlciByZWFkIGJ5IHRoZSBFTUFDIERNQS4gIE11c3QgYmUgYWxpZ25lZCBhcyBkZXNjcmliZWQgYnkgaGUgY29tbWVudA0KYWJvdmUgdGhlIGVtYWNBRERSRVNTX01BU0sgZGVmaW5pdGlvbi4gKi8NCiNwcmFnbWEgZGF0YV9hbGlnbm1lbnQ9OA0Kc3RhdGljIHBvcnRDSEFSIHBjVHhCdWZmZXJbIE5CX1RYX0JVRkZFUlMgKiBFVEhfVFhfQlVGRkVSX1NJWkUgXTsNCg0KLyogRGVzY3JpcHRvcnMgdXNlZCB0byBjb21tdW5pY2F0ZSBiZXR3ZWVuIHRoZSBwcm9ncmFtIGFuZCB0aGUgRU1BQyBwZXJpcGhlcmFsLg0KVGhlc2UgZGVzY3JpcHRvcnMgaG9sZCB0aGUgbG9jYXRpb25zIGFuZCBzdGF0ZSBvZiB0aGUgUnggYW5kIFR4IGJ1ZmZlcnMuICovDQpzdGF0aWMgdm9sYXRpbGUgQVQ5MVNfVHhUZERlc2NyaXB0b3IgeFR4RGVzY3JpcHRvcnNbIE5CX1RYX0JVRkZFUlMgXTsNCnN0YXRpYyB2b2xhdGlsZSBBVDkxU19SeFRkRGVzY3JpcHRvciB4UnhEZXNjcmlwdG9yc1sgTkJfUlhfQlVGRkVSUyBdOw0KDQovKiBUaGUgSVAgYW5kIEV0aGVybmV0IGFkZHJlc3NlcyBhcmUgcmVhZCBmcm9tIHRoZSB1SVAgc2V0dXAuICovDQpjb25zdCBwb3J0Q0hBUiBjTUFDQWRkcmVzc1sgNiBdID0geyB1aXBNQUNfQUREUjAsIHVpcE1BQ19BRERSMSwgdWlwTUFDX0FERFIyLCB1aXBNQUNfQUREUjMsIHVpcE1BQ19BRERSNCwgdWlwTUFDX0FERFI1IH07DQpjb25zdCB1bnNpZ25lZCBjaGFyIHVjSVBBZGRyZXNzWyA0IF0gID0geyB1aXBJUF9BRERSMCwgdWlwSVBfQUREUjEsIHVpcElQX0FERFIyLCB1aXBJUF9BRERSMyB9Ow0KDQovKiBUaGUgc2VtYXBob3JlIHVzZWQgYnkgdGhlIEVNQUMgSVNSIHRvIHdha2UgdGhlIEVNQUMgdGFzay4gKi8NCnN0YXRpYyB4U2VtYXBob3JlSGFuZGxlIHhTZW1hcGhvcmUgPSBOVUxMOw0KDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KeFNlbWFwaG9yZUhhbmRsZSB4RU1BQ0luaXQoIHZvaWQgKQ0Kew0KCS8qIENvZGUgc3VwcGxpZWQgYnkgQXRtZWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCgkvKiBEaXNhYmxlIHB1bGwgdXAgb24gUlhEViA9PiBQSFkgbm9ybWFsIG1vZGUgKG5vdCBpbiB0ZXN0IG1vZGUpLA0KCVBIWSBoYXMgaW50ZXJuYWwgcHVsbCBkb3duLiAqLw0KCUFUOTFDX0JBU0VfUElPQi0+UElPX1BQVURSID0gMSA8PCAxNTsNCg0KCSNpZiBVU0VfUk1JSV9JTlRFUkZBQ0UgIT0gMQ0KCSAgCS8qIFBIWSBoYXMgaW50ZXJuYWwgcHVsbCBkb3duIDogc2V0IE1JSSBtb2RlLiAqLw0KCSAgCUFUOTFDX0JBU0VfUElPQi0+UElPX1BQVURSID0gMSA8PCAxNjsNCgkjZW5kaWYNCg0KCS8qIENsZWFyIFBCMTggPD0+IFBIWSBwb3dlcmRvd24uICovDQogICAJQVQ5MUNfQkFTRV9QSU9CLT5QSU9fUEVSID0gMSA8PCAxODsNCglBVDkxQ19CQVNFX1BJT0ItPlBJT19PRVIgPSAxIDw8IDE4Ow0KCUFUOTFDX0JBU0VfUElPQi0+UElPX0NPRFIgPSAxIDw8IDE4Ow0KDQoJLyogQWZ0ZXIgUEhZIHBvd2VyIHVwLCBoYXJkd2FyZSByZXNldC4gKi8NCglBVDkxQ19CQVNFX1JTVEMtPlJTVENfUk1SID0gZW1hY1JFU0VUX0tFWSB8IGVtYWNSRVNFVF9MRU5HVEg7DQoJQVQ5MUNfQkFTRV9SU1RDLT5SU1RDX1JDUiA9IGVtYWNSRVNFVF9LRVkgfCBBVDkxQ19SU1RDX0VYVFJTVDsNCg0KCS8qIFdhaXQgZm9yIGhhcmR3YXJlIHJlc2V0IGVuZC4gKi8NCgl3aGlsZSggISggQVQ5MUNfQkFTRV9SU1RDLT5SU1RDX1JTUiAmIEFUOTFDX1JTVENfTlJTVEwgKSApDQoJew0KCQlfX2FzbSB2b2xhdGlsZSAoICJOT1AiICk7DQoJfQ0KICAgIF9fYXNtIHZvbGF0aWxlICggIk5PUCIgKTsNCg0KCS8qIFNldHVwIHRoZSBwaW5zLiAqLw0KCUFUOTFDX0JBU0VfUElPQi0+UElPX0FTUiA9IGVtYWNQRVJJUEhFUkFMX0FfU0VUVVA7DQoJQVQ5MUNfQkFTRV9QSU9CLT5QSU9fUERSID0gZW1hY1BFUklQSEVSQUxfQV9TRVRVUDsNCg0KCS8qIEVuYWJsZSBjb20gYmV0d2VlbiBFTUFDIFBIWS4NCg0KCUVuYWJsZSBtYW5hZ2VtZW50IHBvcnQuICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DUiB8PSBBVDkxQ19FTUFDX01QRTsJDQoNCgkvKiBNREMgPSBNQ0svMzIuICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSIHw9ICggMiApIDw8IDEwOwkNCg0KCS8qIFdhaXQgZm9yIFBIWSBhdXRvIGluaXQgZW5kIChyYXRoZXIgY3J1ZGUgZGVsYXkhKS4gKi8NCgl2VGFza0RlbGF5KCBlbWFjUEhZX0lOSVRfREVMQVkgKTsNCg0KCS8qIFBIWSBjb25maWd1cmF0aW9uLiAqLw0KCSNpZiBVU0VfUk1JSV9JTlRFUkZBQ0UgIT0gMQ0KCXsNCgkJdW5zaWduZWQgcG9ydExPTkcgdWxDb250cm9sOw0KDQoJCS8qIFBIWSBoYXMgaW50ZXJuYWwgcHVsbCBkb3duIDogZGlzYWJsZSBNSUkgaXNvbGF0ZS4gKi8NCgkJdlJlYWRQSFkoIEFUOTFDX1BIWV9BRERSLCBNSUlfQk1DUiwgJnVsQ29udHJvbCApOw0KCQl2UmVhZFBIWSggQVQ5MUNfUEhZX0FERFIsIE1JSV9CTUNSLCAmdWxDb250cm9sICk7DQoJCXVsQ29udHJvbCAmPSB+Qk1DUl9JU09MQVRFOw0KCQl2V3JpdGVQSFkoIEFUOTFDX1BIWV9BRERSLCBNSUlfQk1DUiwgdWxDb250cm9sICk7DQoJfQ0KCSNlbmRpZg0KDQoJLyogRGlzYWJsZSBtYW5hZ2VtZW50IHBvcnQgYWdhaW4uICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DUiAmPSB+QVQ5MUNfRU1BQ19NUEU7DQoNCgkjaWYgVVNFX1JNSUlfSU5URVJGQUNFICE9IDENCgkJLyogRW5hYmxlIEVNQUMgaW4gTUlJIG1vZGUsIGVuYWJsZSBjbG9jayBFUlhDSyBhbmQgRVRYQ0suICovDQoJCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19VU1JJTyA9IEFUOTFDX0VNQUNfQ0xLRU4gOw0KCSNlbHNlDQoJCS8qIEVuYWJsZSBFTUFDIGluIFJNSUkgbW9kZSwgZW5hYmxlIFJNSUkgY2xvY2sgKDUwTUh6IGZyb20gb3NjaWxsYXRvcg0KCQlvbiBFUkZDSykuICovDQoJCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19VU1JJTyA9IEFUOTFDX0VNQUNfUk1JSSB8IEFUOTFDX0VNQUNfQ0xLRU4gOw0KCSNlbmRpZg0KDQoJLyogRW5kIG9mIGNvZGUgc3VwcGxpZWQgYnkgQXRtZWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KCS8qIFNldHVwIHRoZSBidWZmZXJzIGFuZCBkZXNjcmlwdG9ycy4gKi8NCglwcnZTZXR1cERlc2NyaXB0b3JzKCk7DQoJDQoJLyogTG9hZCBvdXIgTUFDIGFkZHJlc3MgaW50byB0aGUgRU1BQy4gKi8NCglwcnZTZXR1cE1BQ0FkZHJlc3MoKTsNCg0KCS8qIEFyZSB3ZSBjb25uZWN0ZWQ/ICovDQoJaWYoIHBydlByb2JlUEhZKCkgKQ0KCXsNCgkJLyogRW5hYmxlIHRoZSBpbnRlcnJ1cHQhICovDQoJCXBvcnRFTlRFUl9DUklUSUNBTCgpOw0KCQl7DQoJCQlwcnZTZXR1cEVNQUNJbnRlcnJ1cHQoKTsNCgkJCXZQYXNzRU1BQ1NlbWFwaG9yZSggeFNlbWFwaG9yZSApOw0KCQl9DQoJCXBvcnRFWElUX0NSSVRJQ0FMKCk7DQoJfQ0KDQoJcmV0dXJuIHhTZW1hcGhvcmU7DQp9DQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KcG9ydExPTkcgbEVNQUNTZW5kKCB2b2lkICkNCnsNCnN0YXRpYyB1bnNpZ25lZCBwb3J0QkFTRV9UWVBFIHV4VHhCdWZmZXJJbmRleCA9IDA7DQpwb3J0QkFTRV9UWVBFIHhXYWl0Q3ljbGVzID0gMDsNCnBvcnRMT05HIGxSZXR1cm4gPSBwZFBBU1M7DQpwb3J0Q0hBUiAqcGNCdWZmZXI7DQoNCgkvKiBJcyBhIGJ1ZmZlciBhdmFpbGFibGU/ICovDQoJd2hpbGUoICEoIHhUeERlc2NyaXB0b3JzWyB1eFR4QnVmZmVySW5kZXggXS5VX1N0YXR1cy5zdGF0dXMgJiBBVDkxQ19UUkFOU01JVF9PSyApICkNCgl7DQoJCS8qIFRoZXJlIGlzIG5vIHJvb20gdG8gd3JpdGUgdGhlIFR4IGRhdGEgdG8gdGhlIFR4IGJ1ZmZlci4gIFdhaXQgYQ0KCQlzaG9ydCB3aGlsZSwgdGhlbiB0cnkgYWdhaW4uICovDQoJCXhXYWl0Q3ljbGVzKys7DQoJCWlmKCB4V2FpdEN5Y2xlcyA+IGVtYWNNQVhfV0FJVF9DWUNMRVMgKQ0KCQl7DQoJCQkvKiBHaXZlIHVwLiAqLw0KCQkJbFJldHVybiA9IHBkRkFJTDsNCgkJCWJyZWFrOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJdlRhc2tEZWxheSggZW1hY0JVRkZFUl9XQUlUX0RFTEFZICk7DQoJCX0NCgl9DQoNCgkvKiBsUmV0dXJuIHdpbGwgb25seSBiZSBwZFBBU1MgaWYgYSBidWZmZXIgaXMgYXZhaWxhYmxlLiAqLw0KCWlmKCBsUmV0dXJuID09IHBkUEFTUyApDQoJew0KCQkvKiBDb3B5IHRoZSBoZWFkZXJzIGludG8gdGhlIFR4IGJ1ZmZlci4gIFRoZXNlIHdpbGwgYmUgaW4gdGhlIHVJUCBidWZmZXIuICovDQoJCXBjQnVmZmVyID0gKCBwb3J0Q0hBUiAqICkgeFR4RGVzY3JpcHRvcnNbIHV4VHhCdWZmZXJJbmRleCBdLmFkZHI7DQoJCW1lbWNweSggKCB2b2lkICogKSBwY0J1ZmZlciwgKCB2b2lkICogKSB1aXBfYnVmLCBlbWFjVE9UQUxfRlJBTUVfSEVBREVSX1NJWkUgKTsNCg0KCQkvKiBJZiB0aGVyZSBpcyByb29tLCBhbHNvIGNvcHkgaW4gdGhlIGFwcGxpY2F0aW9uIGRhdGEgaWYgYW55LiAqLw0KCQlpZiggKCB1aXBfbGVuID4gZW1hY1RPVEFMX0ZSQU1FX0hFQURFUl9TSVpFICkgJiYgKCB1aXBfbGVuIDw9ICggRVRIX1RYX0JVRkZFUl9TSVpFIC0gZW1hY1RPVEFMX0ZSQU1FX0hFQURFUl9TSVpFICkgKSApDQoJCXsNCgkJCW1lbWNweSggKCB2b2lkICogKSAmKCBwY0J1ZmZlclsgZW1hY1RPVEFMX0ZSQU1FX0hFQURFUl9TSVpFIF0gKSwgKCB2b2lkICogKSB1aXBfYXBwZGF0YSwgKCB1aXBfbGVuIC0gZW1hY1RPVEFMX0ZSQU1FX0hFQURFUl9TSVpFICkgKTsNCgkJfQ0KDQoJCS8qIFNlbmQuICovCQ0KCQlwb3J0RU5URVJfQ1JJVElDQUwoKTsNCgkJew0KCQkJaWYoIHV4VHhCdWZmZXJJbmRleCA+PSAoIE5CX1RYX0JVRkZFUlMgLSAxICkgKQ0KCQkJew0KCQkJCS8qIEZpbGwgb3V0IHRoZSBuZWNlc3NhcnkgaW4gdGhlIGRlc2NyaXB0b3IgdG8gZ2V0IHRoZSBkYXRhIHNlbnQuICovDQoJCQkJeFR4RGVzY3JpcHRvcnNbIHV4VHhCdWZmZXJJbmRleCBdLlVfU3RhdHVzLnN0YXR1cyA9IAkoIHVpcF9sZW4gJiAoIHVuc2lnbmVkIHBvcnRMT05HICkgQVQ5MUNfTEVOR1RIX0ZSQU1FICkNCgkJCQkJCQkJCQkJCQkJCQkJCXwgQVQ5MUNfTEFTVF9CVUZGRVINCgkJCQkJCQkJCQkJCQkJCQkJCXwgQVQ5MUNfVFJBTlNNSVRfV1JBUDsNCgkJCQl1eFR4QnVmZmVySW5kZXggPSAwOw0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCS8qIEZpbGwgb3V0IHRoZSBuZWNlc3NhcnkgaW4gdGhlIGRlc2NyaXB0b3IgdG8gZ2V0IHRoZSBkYXRhIHNlbnQuICovDQoJCQkJeFR4RGVzY3JpcHRvcnNbIHV4VHhCdWZmZXJJbmRleCBdLlVfU3RhdHVzLnN0YXR1cyA9IAkoIHVpcF9sZW4gJiAoIHVuc2lnbmVkIHBvcnRMT05HICkgQVQ5MUNfTEVOR1RIX0ZSQU1FICkNCgkJCQkJCQkJCQkJCQkJCQkJCXwgQVQ5MUNfTEFTVF9CVUZGRVI7DQoJCQkJdXhUeEJ1ZmZlckluZGV4Kys7DQoJCQl9DQoJDQoJCQlBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTkNSIHw9IEFUOTFDX0VNQUNfVFNUQVJUOw0KCQl9DQoJCXBvcnRFWElUX0NSSVRJQ0FMKCk7DQoJfQ0KDQoJcmV0dXJuIGxSZXR1cm47DQp9DQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KdW5zaWduZWQgcG9ydExPTkcgdWxFTUFDUG9sbCggdm9pZCApDQp7DQpzdGF0aWMgdW5zaWduZWQgcG9ydEJBU0VfVFlQRSB1bE5leHRSeEJ1ZmZlciA9IDA7DQp1bnNpZ25lZCBwb3J0TE9ORyB1bFNlY3Rpb25MZW5ndGggPSAwLCB1bExlbmd0aFNvRmFyID0gMCwgdWxFT0YgPSBwZEZBTFNFOw0KcG9ydENIQVIgKnBjU291cmNlOw0KDQoJLyogU2tpcCBhbnkgZnJhZ21lbnRzLiAqLw0KCXdoaWxlKCAoIHhSeERlc2NyaXB0b3JzWyB1bE5leHRSeEJ1ZmZlciBdLmFkZHIgJiBBVDkxQ19PV05FUlNISVBfQklUICkgJiYgISggeFJ4RGVzY3JpcHRvcnNbIHVsTmV4dFJ4QnVmZmVyIF0uVV9TdGF0dXMuc3RhdHVzICYgQVQ5MUNfU09GICkgKQ0KCXsNCgkJLyogTWFyayB0aGUgYnVmZmVyIGFzIGZyZWUgYWdhaW4uICovDQoJCXhSeERlc2NyaXB0b3JzWyB1bE5leHRSeEJ1ZmZlciBdLmFkZHIgJj0gfiggQVQ5MUNfT1dORVJTSElQX0JJVCApOwkJDQoJCXVsTmV4dFJ4QnVmZmVyKys7DQoJCWlmKCB1bE5leHRSeEJ1ZmZlciA+PSBOQl9SWF9CVUZGRVJTICkNCgkJew0KCQkJdWxOZXh0UnhCdWZmZXIgPSAwOw0KCQl9DQoJfQ0KDQoJLyogSXMgdGhlcmUgYSBwYWNrZXQgcmVhZHk/ICovDQoNCgl3aGlsZSggKCB4UnhEZXNjcmlwdG9yc1sgdWxOZXh0UnhCdWZmZXIgXS5hZGRyICYgQVQ5MUNfT1dORVJTSElQX0JJVCApICYmICF1bFNlY3Rpb25MZW5ndGggKQ0KCXsNCgkJcGNTb3VyY2UgPSAoIHBvcnRDSEFSICogKSggeFJ4RGVzY3JpcHRvcnNbIHVsTmV4dFJ4QnVmZmVyIF0uYWRkciAmIGVtYWNBRERSRVNTX01BU0sgKTsNCgkJdWxTZWN0aW9uTGVuZ3RoID0geFJ4RGVzY3JpcHRvcnNbIHVsTmV4dFJ4QnVmZmVyIF0uVV9TdGF0dXMuc3RhdHVzICYgZW1hY1JYX0xFTkdUSF9GUkFNRTsNCg0KCQlpZiggdWxTZWN0aW9uTGVuZ3RoID09IDAgKQ0KCQl7DQoJCQkvKiBUaGUgZnJhbWUgaXMgbG9uZ2VyIHRoYW4gdGhlIGJ1ZmZlciBwb2ludGVkIHRvIGJ5IHRoaXMNCgkJCWRlc2NyaXB0b3Igc28gY29weSB0aGUgZW50aXJlIGJ1ZmZlciB0byB1SVAgLSB0aGVuIG1vdmUgb250bw0KCQkJdGhlIG5leHQgZGVzY3JpcHRvciB0byBnZXQgdGhlIHJlc3Qgb2YgdGhlIGZyYW1lLiAqLw0KCQkJaWYoICggdWxMZW5ndGhTb0ZhciArIEVUSF9SWF9CVUZGRVJfU0laRSApIDw9IFVJUF9CVUZTSVpFICkNCgkJCXsNCgkJCQltZW1jcHkoICYoIHVpcF9idWZbIHVsTGVuZ3RoU29GYXIgXSApLCBwY1NvdXJjZSwgRVRIX1JYX0JVRkZFUl9TSVpFICk7DQoJCQkJdWxMZW5ndGhTb0ZhciArPSBFVEhfUlhfQlVGRkVSX1NJWkU7DQoJCQl9CQkJDQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQkvKiBUaGlzIGlzIHRoZSBsYXN0IHNlY3Rpb24gb2YgdGhlIGZyYW1lLiAgQ29weSB0aGUgc2VjdGlvbiB0bw0KCQkJdUlQLiAqLw0KCQkJaWYoIHVsU2VjdGlvbkxlbmd0aCA8IFVJUF9CVUZTSVpFICkNCgkJCXsNCgkJCQkvKiBUaGUgc2VjdGlvbiBsZW5ndGggaG9sZHMgdGhlIGxlbmd0aCBvZiB0aGUgZW50aXJlIGZyYW1lLg0KCQkJCXVsTGVuZ3RoU29GYXIgaG9sZHMgdGhlIGxlbmd0aCBvZiB0aGUgZnJhbWUgc2VjdGlvbnMgYWxyZWFkeQ0KCQkJCWNvcGllZCB0byB1SVAsIHNvIHRoZSBsZW5ndGggb2YgdGhlIGZpbmFsIHNlY3Rpb24gaXMNCgkJCQl1bFNlY3Rpb25MZW5ndGggLSB1bExlbmd0aFNvRmFyOyAqLw0KCQkJCWlmKCB1bFNlY3Rpb25MZW5ndGggPiB1bExlbmd0aFNvRmFyICkNCgkJCQl7DQoJCQkJCW1lbWNweSggJiggdWlwX2J1ZlsgdWxMZW5ndGhTb0ZhciBdICksIHBjU291cmNlLCAoIHVsU2VjdGlvbkxlbmd0aCAtIHVsTGVuZ3RoU29GYXIgKSApOw0KCQkJCX0NCgkJCX0JCQkNCg0KCQkJLyogSXMgdGhpcyB0aGUgbGFzdCBidWZmZXIgZm9yIHRoZSBmcmFtZT8gIElmIG5vdCB3aHk/ICovDQoJCQl1bEVPRiA9IHhSeERlc2NyaXB0b3JzWyB1bE5leHRSeEJ1ZmZlciBdLlVfU3RhdHVzLnN0YXR1cyAmIEFUOTFDX0VPRjsNCgkJfQ0KDQoJCS8qIE1hcmsgdGhlIGJ1ZmZlciBhcyBmcmVlIGFnYWluLiAqLw0KCQl4UnhEZXNjcmlwdG9yc1sgdWxOZXh0UnhCdWZmZXIgXS5hZGRyICY9IH4oIEFUOTFDX09XTkVSU0hJUF9CSVQgKTsNCg0KCQkvKiBJbmNyZW1lbnQgdG8gdGhlIG5leHQgYnVmZmVyLCB3cmFwcGluZyBpZiBuZWNlc3NhcnkuICovDQoJCXVsTmV4dFJ4QnVmZmVyKys7DQoJCWlmKCB1bE5leHRSeEJ1ZmZlciA+PSBOQl9SWF9CVUZGRVJTICkNCgkJew0KCQkJdWxOZXh0UnhCdWZmZXIgPSAwOw0KCQl9DQoJfQ0KDQoJLyogSWYgd2Ugb2J0YWluZWQgZGF0YSBidXQgZm9yIHNvbWUgcmVhc29uIGRpZCBub3QgZmluZCB0aGUgZW5kIG9mIHRoZQ0KCWZyYW1lIHRoZW4gZGlzY2FyZCB0aGUgZGF0YSBhcyBpdCBtdXN0IGNvbnRhaW4gYW4gZXJyb3IuICovDQoJaWYoICF1bEVPRiApDQoJew0KCQl1bFNlY3Rpb25MZW5ndGggPSAwOw0KCX0NCg0KCXJldHVybiB1bFNlY3Rpb25MZW5ndGg7DQp9DQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0Kc3RhdGljIHZvaWQgcHJ2U2V0dXBEZXNjcmlwdG9ycyh2b2lkKQ0Kew0KdW5zaWduZWQgcG9ydEJBU0VfVFlQRSB4SW5kZXg7DQp1bnNpZ25lZCBwb3J0TE9ORyB1bEFkZHJlc3M7DQoNCgkvKiBJbml0aWFsaXNlIHhSeERlc2NyaXB0b3JzIGRlc2NyaXB0b3IuICovDQoJZm9yKCB4SW5kZXggPSAwOyB4SW5kZXggPCBOQl9SWF9CVUZGRVJTOyArK3hJbmRleCApDQoJew0KCQkvKiBDYWxjdWxhdGUgdGhlIGFkZHJlc3Mgb2YgdGhlIG50aCBidWZmZXIgd2l0aGluIHRoZSBhcnJheS4gKi8NCgkJdWxBZGRyZXNzID0gKCB1bnNpZ25lZCBwb3J0TE9ORyApKCBwY1J4QnVmZmVyICsgKCB4SW5kZXggKiBFVEhfUlhfQlVGRkVSX1NJWkUgKSApOw0KDQoJCS8qIFdyaXRlIHRoZSBidWZmZXIgYWRkcmVzcyBpbnRvIHRoZSBkZXNjcmlwdG9yLiAgVGhlIERNQSB3aWxsIHBsYWNlDQoJCXRoZSBkYXRhIGF0IHRoaXMgYWRkcmVzcyB3aGVuIHRoaXMgZGVzY3JpcHRvciBpcyBiZWluZyB1c2VkLiAgTWFzayBvZmYNCgkJdGhlIGJvdHRvbSBiaXRzIG9mIHRoZSBhZGRyZXNzIGFzIHRoZXNlIGhhdmUgc3BlY2lhbCBtZWFuaW5nLiAqLw0KCQl4UnhEZXNjcmlwdG9yc1sgeEluZGV4IF0uYWRkciA9IHVsQWRkcmVzcyAmIGVtYWNBRERSRVNTX01BU0s7DQoJfQkNCg0KCS8qIFRoZSBsYXN0IGJ1ZmZlciBoYXMgdGhlIHdyYXAgYml0IHNldCBzbyB0aGUgRU1BQyBrbm93cyB0byB3cmFwIGJhY2sNCgl0byB0aGUgZmlyc3QgYnVmZmVyLiAqLw0KCXhSeERlc2NyaXB0b3JzWyBOQl9SWF9CVUZGRVJTIC0gMSBdLmFkZHIgfD0gZW1hY1JYX1dSQVBfQklUOw0KDQoJLyogSW5pdGlhbGlzZSB4VHhEZXNjcmlwdG9ycy4gKi8NCglmb3IoIHhJbmRleCA9IDA7IHhJbmRleCA8IE5CX1RYX0JVRkZFUlM7ICsreEluZGV4ICkNCgl7DQoJCS8qIENhbGN1bGF0ZSB0aGUgYWRkcmVzcyBvZiB0aGUgbnRoIGJ1ZmZlciB3aXRoaW4gdGhlIGFycmF5LiAqLw0KCQl1bEFkZHJlc3MgPSAoIHVuc2lnbmVkIHBvcnRMT05HICkoIHBjVHhCdWZmZXIgKyAoIHhJbmRleCAqIEVUSF9UWF9CVUZGRVJfU0laRSApICk7DQoNCgkJLyogV3JpdGUgdGhlIGJ1ZmZlciBhZGRyZXNzIGludG8gdGhlIGRlc2NyaXB0b3IuICBUaGUgRE1BIHdpbGwgcmVhZA0KCQlkYXRhIGZyb20gaGVyZSB3aGVuIHRoZSBkZXNjcmlwdG9yIGlzIGJlaW5nIHVzZWQuICovDQoJCXhUeERlc2NyaXB0b3JzWyB4SW5kZXggXS5hZGRyID0gdWxBZGRyZXNzICYgZW1hY0FERFJFU1NfTUFTSzsNCgkJeFR4RGVzY3JpcHRvcnNbIHhJbmRleCBdLlVfU3RhdHVzLnN0YXR1cyA9IEFUOTFDX1RSQU5TTUlUX09LOw0KCX0JDQoNCgkvKiBUaGUgbGFzdCBidWZmZXIgaGFzIHRoZSB3cmFwIGJpdCBzZXQgc28gdGhlIEVNQUMga25vd3MgdG8gd3JhcCBiYWNrDQoJdG8gdGhlIGZpcnN0IGJ1ZmZlci4gKi8NCgl4VHhEZXNjcmlwdG9yc1sgTkJfVFhfQlVGRkVSUyAtIDEgXS5VX1N0YXR1cy5zdGF0dXMgPSBBVDkxQ19UUkFOU01JVF9XUkFQIHwgQVQ5MUNfVFJBTlNNSVRfT0s7DQoNCgkvKiBUZWxsIHRoZSBFTUFDIHdoZXJlIHRvIGZpbmQgdGhlIGRlc2NyaXB0b3JzLiAqLw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19SQlFQID0gKCB1bnNpZ25lZCBwb3J0TE9ORyApIHhSeERlc2NyaXB0b3JzOw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19UQlFQID0gKCB1bnNpZ25lZCBwb3J0TE9ORyApIHhUeERlc2NyaXB0b3JzOw0KCQ0KCS8qIENsZWFyIGFsbCB0aGUgYml0cyBpbiB0aGUgcmVjZWl2ZSBzdGF0dXMgcmVnaXN0ZXIuICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX1JTUiA9ICggQVQ5MUNfRU1BQ19PVlIgfCBBVDkxQ19FTUFDX1JFQyB8IEFUOTFDX0VNQUNfQk5BICk7DQoNCgkvKiBFbmFibGUgdGhlIGNvcHkgb2YgZGF0YSBpbnRvIHRoZSBidWZmZXJzLCBpZ25vcmUgYnJvYWRjYXN0cywNCglhbmQgZG9uJ3QgY29weSBGQ1MuICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSIHw9ICggQVQ5MUNfRU1BQ19DQUYgfCBBVDkxQ19FTUFDX05CQyB8IEFUOTFDX0VNQUNfRFJGQ1MpOw0KDQoJLyogRW5hYmxlIFJ4IGFuZCBUeCwgcGx1cyB0aGUgc3RhdHMgcmVnaXN0ZXIuICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DUiB8PSAoIEFUOTFDX0VNQUNfVEUgfCBBVDkxQ19FTUFDX1JFIHwgQVQ5MUNfRU1BQ19XRVNUQVQgKTsNCn0JDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0Kc3RhdGljIHZvaWQgcHJ2U2V0dXBNQUNBZGRyZXNzKCB2b2lkICkNCnsNCgkvKiBNdXN0IGJlIHdyaXR0ZW4gU0ExTCB0aGVuIFNBMUguICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX1NBMUwgPQkoICggdW5zaWduZWQgcG9ydExPTkcgKSBjTUFDQWRkcmVzc1sgMyBdIDw8IDI0ICkgfA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIHBvcnRMT05HICkgY01BQ0FkZHJlc3NbIDIgXSA8PCAxNiApIHwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBwb3J0TE9ORyApIGNNQUNBZGRyZXNzWyAxIF0gPDwgOCAgKSB8DQoJCQkJCQkJCQljTUFDQWRkcmVzc1sgMCBdOw0KDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX1NBMUggPQkoICggdW5zaWduZWQgcG9ydExPTkcgKSBjTUFDQWRkcmVzc1sgNSBdIDw8IDggKSB8DQoJCQkJCQkJCQljTUFDQWRkcmVzc1sgNCBdOw0KfQ0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCnN0YXRpYyB2b2lkIHBydlNldHVwRU1BQ0ludGVycnVwdCggdm9pZCApDQp7DQoJLyogQ3JlYXRlIHRoZSBzZW1hcGhvcmUgdXNlZCB0byB0cmlnZ2VyIHRoZSBFTUFDIHRhc2suICovDQoJdlNlbWFwaG9yZUNyZWF0ZUJpbmFyeSggeFNlbWFwaG9yZSApOw0KCWlmKCB4U2VtYXBob3JlICkNCgl7DQoJCS8qIFdlIHN0YXJ0IGJ5ICd0YWtpbmcnIHRoZSBzZW1hcGhvcmUgc28gdGhlIElTUiBjYW4gJ2dpdmUnIGl0IHdoZW4gdGhlDQoJCWZpcnN0IGludGVycnVwdCBvY2N1cnMuICovDQoJCXhTZW1hcGhvcmVUYWtlKCB4U2VtYXBob3JlLCBlbWFjTk9fREVMQVkgKTsNCgkJcG9ydEVOVEVSX0NSSVRJQ0FMKCk7DQoJCXsNCgkJCS8qIFdlIHdhbnQgdG8gaW50ZXJydXB0IG9uIFJ4IGV2ZW50cy4gKi8NCgkJCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19JRVIgPSBBVDkxQ19FTUFDX1JDT01QOw0KDQoJCQkvKiBFbmFibGUgdGhlIGludGVycnVwdHMgaW4gdGhlIEFJQy4gKi8NCgkJCUFUOTFGX0FJQ19Db25maWd1cmVJdCggQVQ5MUNfSURfRU1BQywgZW1hY0lOVEVSUlVQVF9MRVZFTCwgQVQ5MUNfQUlDX1NSQ1RZUEVfSU5UX0hJR0hfTEVWRUwsICggdm9pZCAoKikoIHZvaWQgKSApIHZFTUFDSVNSX1dyYXBwZXIgKTsNCgkJCUFUOTFDX0JBU0VfQUlDLT5BSUNfSUVDUiA9IDB4MSA8PCBBVDkxQ19JRF9FTUFDOw0KCQl9DQoJCXBvcnRFWElUX0NSSVRJQ0FMKCk7DQoJfQ0KfQ0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCg0KDQoNCi8qDQogKiBUaGUgZm9sbG93aW5nIGZ1bmN0aW9ucyBhcmUgaW5pdGlhbGlzYXRpb24gZnVuY3Rpb25zIHRha2VuIGZyb20gdGhlIEF0bWVsDQogKiBFTUFDIHNhbXBsZSBjb2RlLg0KICovDQoNCnN0YXRpYyBwb3J0QkFTRV9UWVBFIHBydlByb2JlUEhZKCB2b2lkICkNCnsNCnVuc2lnbmVkIHBvcnRMT05HIHVsUEhZSWQxLCB1bFBIWUlkMiwgdWxTdGF0dXM7DQpwb3J0QkFTRV9UWVBFIHhSZXR1cm4gPSBwZFBBU1M7DQoJDQoJLyogQ29kZSBzdXBwbGllZCBieSBBdG1lbCAocmVmb3JtYXR0ZWQpIC0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KCS8qIEVuYWJsZSBtYW5hZ2VtZW50IHBvcnQgKi8NCglBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTkNSIHw9IEFUOTFDX0VNQUNfTVBFOwkNCglBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTkNGR1IgfD0gKCAyICkgPDwgMTA7DQoNCgkvKiBSZWFkIHRoZSBQSFkgSUQuICovDQoJdlJlYWRQSFkoIEFUOTFDX1BIWV9BRERSLCBNSUlfUEhZU0lEMSwgJnVsUEhZSWQxICk7DQoJdlJlYWRQSFkoIEFUOTFDX1BIWV9BRERSLCBNSUlfUEhZU0lEMiwgJnVsUEhZSWQyICk7DQoNCgkvKiBBTUQgQU03OUM4NzU6DQoJCQlQSFlfSUQxID0gMHgwMDIyDQoJCQlQSFlfSUQyID0gMHg1NTQxDQoJCQlCaXRzIDM6MCBSZXZpc2lvbiBOdW1iZXIgRm91ciBiaXQgbWFudWZhY3R1cmVyknMgcmV2aXNpb24gbnVtYmVyLg0KCQkJCTAwMDEgc3RhbmRzIGZvciBSZXYuIEEsIGV0Yy4NCgkqLw0KCWlmKCAoICggdWxQSFlJZDEgPDwgMTYgKSB8ICggdWxQSFlJZDIgJiAweGZmZjAgKSApICE9IE1JSV9ETTkxNjFfSUQgKQ0KCXsNCgkJLyogRGlkIG5vdCBleHBlY3QgdGhpcyBJRC4gKi8NCgkJeFJldHVybiA9IHBkRkFJTDsNCgl9DQoJZWxzZQ0KCXsNCgkJdWxTdGF0dXMgPSB4R2V0TGlua1NwZWVkKCk7DQoNCgkJaWYoIHVsU3RhdHVzICE9IHBkUEFTUyApDQoJCXsNCgkJCXhSZXR1cm4gPSBwZEZBSUw7DQoJCX0NCgl9DQoNCgkvKiBEaXNhYmxlIG1hbmFnZW1lbnQgcG9ydCAqLw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ1IgJj0gfkFUOTFDX0VNQUNfTVBFOwkNCg0KCS8qIEVuZCBvZiBjb2RlIHN1cHBsaWVkIGJ5IEF0bWVsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCglyZXR1cm4geFJldHVybjsNCn0NCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQpzdGF0aWMgdm9pZCB2UmVhZFBIWSggdW5zaWduZWQgcG9ydENIQVIgdWNQSFlBZGRyZXNzLCB1bnNpZ25lZCBwb3J0Q0hBUiB1Y0FkZHJlc3MsIHVuc2lnbmVkIHBvcnRMT05HICpwdWxWYWx1ZSApDQp7DQoJLyogQ29kZSBzdXBwbGllZCBieSBBdG1lbCAocmVmb3JtYXR0ZWQpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX01BTiA9IAkoQVQ5MUNfRU1BQ19TT0YgJiAoMHgwMTw8MzApKQ0KCQkJCQkJCQkJfCAoMiA8PCAxNikgfCAoMiA8PCAyOCkNCgkJCQkJCQkJCXwgKCh1Y1BIWUFkZHJlc3MgJiAweDFmKSA8PCAyMykNCgkJCQkJCQkJCXwgKHVjQWRkcmVzcyA8PCAxOCk7DQoNCgkvKiBXYWl0IHVudGlsIElETEUgYml0IGluIE5ldHdvcmsgU3RhdHVzIHJlZ2lzdGVyIGlzIGNsZWFyZWQuICovDQoJd2hpbGUoICEoIEFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OU1IgJiBBVDkxQ19FTUFDX0lETEUgKSApDQoJew0KCQlfX2FzbSggIk5PUCIgKTsNCgl9DQoNCgkqcHVsVmFsdWUgPSAoIEFUOTFDX0JBU0VfRU1BQy0+RU1BQ19NQU4gJiAweDAwMDBmZmZmICk7CQ0KDQoJLyogRW5kIG9mIGNvZGUgc3VwcGxpZWQgYnkgQXRtZWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCn0NCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQojaWYgVVNFX1JNSUlfSU5URVJGQUNFICE9IDENCnN0YXRpYyB2b2lkIHZXcml0ZVBIWSggdW5zaWduZWQgcG9ydENIQVIgdWNQSFlBZGRyZXNzLCB1bnNpZ25lZCBwb3J0Q0hBUiB1Y0FkZHJlc3MsIHVuc2lnbmVkIHBvcnRMT05HIHVsVmFsdWUgKQ0Kew0KCS8qIENvZGUgc3VwcGxpZWQgYnkgQXRtZWwgKHJlZm9ybWF0dGVkKSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19NQU4gPSAoKCBBVDkxQ19FTUFDX1NPRiAmICgweDAxPDwzMCkpDQoJCQkJCQkJCXwgKDIgPDwgMTYpIHwgKDEgPDwgMjgpDQoJCQkJCQkJCXwgKCh1Y1BIWUFkZHJlc3MgJiAweDFmKSA8PCAyMykNCgkJCQkJCQkJfCAodWNBZGRyZXNzIDw8IDE4KSkNCgkJCQkJCQkJfCAodWxWYWx1ZSAmIDB4ZmZmZik7DQoNCgkvKiBXYWl0IHVudGlsIElETEUgYml0IGluIE5ldHdvcmsgU3RhdHVzIHJlZ2lzdGVyIGlzIGNsZWFyZWQgKi8NCgl3aGlsZSggISggQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05TUiAmIEFUOTFDX0VNQUNfSURMRSApICkNCgl7DQoJCV9fYXNtKCAiTk9QIiApOw0KCX07DQoNCgkvKiBFbmQgb2YgY29kZSBzdXBwbGllZCBieSBBdG1lbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KfQ0KI2VuZGlmDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0Kc3RhdGljIHBvcnRCQVNFX1RZUEUgeEdldExpbmtTcGVlZCggdm9pZCApDQp7DQoJdW5zaWduZWQgcG9ydExPTkcgdWxCTVNSLCB1bEJNQ1IsIHVsTFBBLCB1bE1BQ0NmZywgdWxTcGVlZCwgdWxEdXBsZXg7DQoNCgkvKiBDb2RlIHN1cHBsaWVkIGJ5IEF0bWVsIChyZWZvcm1hdHRlZCkgLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQoJLyogTGluayBzdGF0dXMgaXMgbGF0Y2hlZCwgc28gcmVhZCB0d2ljZSB0byBnZXQgY3VycmVudCB2YWx1ZSAqLw0KCXZSZWFkUEhZKEFUOTFDX1BIWV9BRERSLCBNSUlfQk1TUiwgJnVsQk1TUik7DQoJdlJlYWRQSFkoQVQ5MUNfUEhZX0FERFIsIE1JSV9CTVNSLCAmdWxCTVNSKTsNCg0KCWlmKCAhKCB1bEJNU1IgJiBCTVNSX0xTVEFUVVMgKSApDQoJewkNCgkJLyogTm8gTGluay4gKi8NCgkJcmV0dXJuIHBkRkFJTDsNCgl9DQoNCgl2UmVhZFBIWShBVDkxQ19QSFlfQUREUiwgTUlJX0JNQ1IsICZ1bEJNQ1IpOw0KCWlmICh1bEJNQ1IgJiBCTUNSX0FORU5BQkxFKQ0KCXsJCQkJDQoJCS8qIEF1dG9OZWdvdGlhdGlvbiBpcyBlbmFibGVkLiAqLw0KCQlpZiAoISh1bEJNU1IgJiBCTVNSX0FORUdDT01QTEVURSkpDQoJCXsNCgkJCS8qIEF1dG8tbmVnb3RpYXRpb24gaW4gcHJvZ3Jlc3MuICovDQoJCQlyZXR1cm4gcGRGQUlMOwkJCQkNCgkJfQkJDQoNCgkJdlJlYWRQSFkoQVQ5MUNfUEhZX0FERFIsIE1JSV9MUEEsICZ1bExQQSk7DQoJCWlmKCAoIHVsTFBBICYgTFBBXzEwMEZVTEwgKSB8fCAoIHVsTFBBICYgTFBBXzEwMEhBTEYgKSApDQoJCXsNCgkJCXVsU3BlZWQgPSBTUEVFRF8xMDA7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQl1bFNwZWVkID0gU1BFRURfMTA7DQoJCX0NCg0KCQlpZiggKCB1bExQQSAmIExQQV8xMDBGVUxMICkgfHwgKCB1bExQQSAmIExQQV8xMEZVTEwgKSApDQoJCXsNCgkJCXVsRHVwbGV4ID0gRFVQTEVYX0ZVTEw7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQl1bER1cGxleCA9IERVUExFWF9IQUxGOw0KCQl9DQoJfQ0KCWVsc2UNCgl7DQoJCXVsU3BlZWQgPSAoIHVsQk1DUiAmIEJNQ1JfU1BFRUQxMDAgKSA/IFNQRUVEXzEwMCA6IFNQRUVEXzEwOw0KCQl1bER1cGxleCA9ICggdWxCTUNSICYgQk1DUl9GVUxMRFBMWCApID8gRFVQTEVYX0ZVTEwgOiBEVVBMRVhfSEFMRjsNCgl9DQoNCgkvKiBVcGRhdGUgdGhlIE1BQyAqLw0KCXVsTUFDQ2ZnID0gQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSICYgfiggQVQ5MUNfRU1BQ19TUEQgfCBBVDkxQ19FTUFDX0ZEICk7DQoJaWYoIHVsU3BlZWQgPT0gU1BFRURfMTAwICkNCgl7DQoJCWlmKCB1bER1cGxleCA9PSBEVVBMRVhfRlVMTCApDQoJCXsNCgkJCS8qIDEwMCBGdWxsIER1cGxleCAqLw0KCQkJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSID0gdWxNQUNDZmcgfCBBVDkxQ19FTUFDX1NQRCB8IEFUOTFDX0VNQUNfRkQ7DQoJCX0NCgkJZWxzZQ0KCQl7CQkJCQkNCgkJCS8qIDEwMCBIYWxmIER1cGxleCAqLw0KCQkJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSID0gdWxNQUNDZmcgfCBBVDkxQ19FTUFDX1NQRDsNCgkJfQ0KCX0NCgllbHNlDQoJew0KCQlpZiAodWxEdXBsZXggPT0gRFVQTEVYX0ZVTEwpDQoJCXsNCgkJCS8qIDEwIEZ1bGwgRHVwbGV4ICovDQoJCQlBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTkNGR1IgPSB1bE1BQ0NmZyB8IEFUOTFDX0VNQUNfRkQ7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQkvKiAxMCBIYWxmIER1cGxleCAqLw0KCQkJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSID0gdWxNQUNDZmc7DQoJCX0NCgl9DQoNCgkvKiBFbmQgb2YgY29kZSBzdXBwbGllZCBieSBBdG1lbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQoJcmV0dXJuIHBkUEFTUzsNCn0NCg==