LyoKICAgVENQU3RyZWFtLmgKCiAgIFRDUFN0cmVhbSBjbGFzcyBkZWZpbml0aW9uLiBUQ1BTdHJlYW0gcHJvdmlkZXMgbWV0aG9kcyB0byB0cmFzbmZlcgogICBkYXRhIGJldHdlZW4gcGVlcnMgb3ZlciBhIFRDUC9JUCBjb25uZWN0aW9uLgoKICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICBDb3B5cmlnaHQgqSAyMDEzIFtWaWMgSGFyZ3JhdmUgLSBodHRwOi8vdmljaGFyZ3JhdmUuY29tXQoKICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CgogICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCgogICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgoqLwoKI2luY2x1ZGUgIlRDUFN0cmVhbS5oIgoKI2lmZGVmIF9XSU4zMgojaW5jbHVkZSA8V2luU29jazIuaD4KI2Vsc2UKI2luY2x1ZGUgPGFycGEvaW5ldC5oPgojaW5jbHVkZSA8bmV0aW5ldC90Y3AuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKClRDUFN0cmVhbTo6VENQU3RyZWFtKGludCBzZCwgc3RydWN0IHNvY2thZGRyX2luKiBhZGRyZXNzKSA6IG1fc2Qoc2QpIHsKICBjaGFyIGlwWzUwXTsKI2lmZGVmIF9XSU4zMgogIHVuc2lnbmVkIGxvbmcgc2l6ZSA9IHNpemVvZihpcCkgLSAxOwogIFdTQUFkZHJlc3NUb1N0cmluZygoc3RydWN0IHNvY2thZGRyKilhZGRyZXNzLCBzaXplb2Ygc29ja2FkZHJfaW4sIG51bGxwdHIsIGlwLCAmc2l6ZSk7CiNlbHNlCiAgaW5ldF9udG9wKFBGX0lORVQsIChzdHJ1Y3QgaW5fYWRkciopJihhZGRyZXNzLT5zaW5fYWRkci5zX2FkZHIpLCBpcCwKICAgICAgICAgICAgc2l6ZW9mKGlwKSAtIDEpOwojZW5kaWYKICBtX3BlZXJJUCA9IGlwOwogIG1fcGVlclBvcnQgPSBudG9ocyhhZGRyZXNzLT5zaW5fcG9ydCk7Cn0KClRDUFN0cmVhbTo6flRDUFN0cmVhbSgpIHsgY2xvc2UoKTsgfQoKc3RkOjpzaXplX3QgVENQU3RyZWFtOjpzZW5kKGNvbnN0IGNoYXIqIGJ1ZmZlciwgc3RkOjpzaXplX3QgbGVuLCBFcnJvciogZXJyKSB7CiAgaWYgKG1fc2QgPCAwKSB7CiAgICAqZXJyID0ga0Nvbm5lY3Rpb25DbG9zZWQ7CiAgICByZXR1cm4gMDsKICB9CiNpZmRlZiBfV0lOMzIKICBXU0FCVUYgd3NhQnVmOwogIHdzYUJ1Zi5idWYgPSBjb25zdF9jYXN0PGNoYXIqPihidWZmZXIpOwogIHdzYUJ1Zi5sZW4gPSAoVUxPTkcpbGVuOwogIERXT1JEIHJ2OwogIGJvb2wgcmVzdWx0ID0gdHJ1ZTsKICB3aGlsZSAoV1NBU2VuZChtX3NkLCAmd3NhQnVmLCAxLCAmcnYsIDAsIG51bGxwdHIsIG51bGxwdHIpID09IFNPQ0tFVF9FUlJPUikgewogICAgaWYgKFdTQUdldExhc3RFcnJvcigpICE9IFdTQUVXT1VMREJMT0NLKSB7CiAgICAgIHJlc3VsdCA9IGZhbHNlOwogICAgICBicmVhazsKICAgIH0KICAgIFNsZWVwKDEpOwogIH0KICBpZiAoIXJlc3VsdCkgewogICAgY2hhciBCdWZmZXJbMTI4XTsKI2lmZGVmIF9NU0NfVkVSCiAgICBzcHJpbnRmX3MoQnVmZmVyLCAiU2VuZCgpIGZhaWxlZDogV1NBIGVycm9yPSVkXG4iLCBXU0FHZXRMYXN0RXJyb3IoKSk7CiNlbHNlCiAgICBzdGQ6OnNucHJpbnRmKEJ1ZmZlciwgMTI4LCAiU2VuZCgpIGZhaWxlZDogV1NBIGVycm9yPSVkXG4iLCBXU0FHZXRMYXN0RXJyb3IoKSk7CiNlbmRpZgogICAgT3V0cHV0RGVidWdTdHJpbmdBKEJ1ZmZlcik7CiAgICAqZXJyID0ga0Nvbm5lY3Rpb25SZXNldDsKICAgIHJldHVybiAwOwogIH0KI2Vsc2UKICBzc2l6ZV90IHJ2ID0gd3JpdGUobV9zZCwgYnVmZmVyLCBsZW4pOwogIGlmIChydiA8IDApIHsKICAgICplcnIgPSBrQ29ubmVjdGlvblJlc2V0OwogICAgcmV0dXJuIDA7CiAgfQojZW5kaWYKICByZXR1cm4gc3RhdGljX2Nhc3Q8c3RkOjpzaXplX3Q+KHJ2KTsKfQoKc3RkOjpzaXplX3QgVENQU3RyZWFtOjpyZWNlaXZlKGNoYXIqIGJ1ZmZlciwgc3RkOjpzaXplX3QgbGVuLCBFcnJvciogZXJyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHRpbWVvdXQpIHsKICBpZiAobV9zZCA8IDApIHsKICAgICplcnIgPSBrQ29ubmVjdGlvbkNsb3NlZDsKICAgIHJldHVybiAwOwogIH0KI2lmZGVmIF9XSU4zMgogIGludCBydjsKI2Vsc2UKICBzc2l6ZV90IHJ2OwojZW5kaWYKICBpZiAodGltZW91dCA8PSAwKSB7CiNpZmRlZiBfV0lOMzIKICAgIHJ2ID0gcmVjdihtX3NkLCBidWZmZXIsIGxlbiwgMCk7CiNlbHNlCiAgICBydiA9IHJlYWQobV9zZCwgYnVmZmVyLCBsZW4pOwojZW5kaWYKICB9CiAgZWxzZSBpZiAoV2FpdEZvclJlYWRFdmVudCh0aW1lb3V0KSkgewojaWZkZWYgX1dJTjMyCiAgICBydiA9IHJlY3YobV9zZCwgYnVmZmVyLCBsZW4sIDApOwojZWxzZQogICAgcnYgPSByZWFkKG1fc2QsIGJ1ZmZlciwgbGVuKTsKI2VuZGlmCiAgfSBlbHNlIHsKICAgICplcnIgPSBrQ29ubmVjdGlvblRpbWVkT3V0OwogICAgcmV0dXJuIDA7CiAgfQogIGlmIChydiA8IDApIHsKICAgICplcnIgPSBrQ29ubmVjdGlvblJlc2V0OwogICAgcmV0dXJuIDA7CiAgfQogIHJldHVybiBzdGF0aWNfY2FzdDxzdGQ6OnNpemVfdD4ocnYpOwp9Cgp2b2lkIFRDUFN0cmVhbTo6Y2xvc2UoKSB7CiAgaWYgKG1fc2QgPj0gMCkgewojaWZkZWYgX1dJTjMyCiAgICA6OnNodXRkb3duKG1fc2QsIFNEX0JPVEgpOwogICAgY2xvc2Vzb2NrZXQobV9zZCk7CiNlbHNlCiAgICA6OnNodXRkb3duKG1fc2QsIFNIVVRfUkRXUik7CiAgICA6OmNsb3NlKG1fc2QpOwojZW5kaWYKICB9CiAgbV9zZCA9IC0xOwp9CgpsbHZtOjpTdHJpbmdSZWYgVENQU3RyZWFtOjpnZXRQZWVySVAoKSBjb25zdCB7IHJldHVybiBtX3BlZXJJUDsgfQoKaW50IFRDUFN0cmVhbTo6Z2V0UGVlclBvcnQoKSBjb25zdCB7IHJldHVybiBtX3BlZXJQb3J0OyB9Cgp2b2lkIFRDUFN0cmVhbTo6c2V0Tm9EZWxheSgpIHsKICBpbnQgb3B0dmFsID0gMTsKICBzZXRzb2Nrb3B0KG1fc2QsIElQUFJPVE9fVENQLCBUQ1BfTk9ERUxBWSwgKGNoYXIqKSZvcHR2YWwsIHNpemVvZiBvcHR2YWwpOwp9Cgpib29sIFRDUFN0cmVhbTo6V2FpdEZvclJlYWRFdmVudChpbnQgdGltZW91dCkgewogIGZkX3NldCBzZHNldDsKICBzdHJ1Y3QgdGltZXZhbCB0djsKCiAgdHYudHZfc2VjID0gdGltZW91dDsKICB0di50dl91c2VjID0gMDsKICBGRF9aRVJPKCZzZHNldCk7CiAgRkRfU0VUKG1fc2QsICZzZHNldCk7CiAgaWYgKHNlbGVjdChtX3NkICsgMSwgJnNkc2V0LCBOVUxMLCBOVUxMLCAmdHYpID4gMCkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIHJldHVybiBmYWxzZTsKfQo=