LyoKICogIEFVVEhPUgogKiAgICBDbGF1cyBFa3N0cvhtLCBla3N0cm9tQGRpbmEua3ZsLmRrCiAqICAgIEp1bHkgMTUsIDIwMDMuCiAqCiAqICBNZXJnZSBpbiB0byBSOgogKglDb3B5cmlnaHQgKEMpIDIwMDMtMjAxNSBUaGUgUiBGb3VuZGF0aW9uCiAqCiAqICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiAgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqICAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqICBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCBhIGNvcHkgaXMgYXZhaWxhYmxlIGF0CiAqICBodHRwczovL3d3dy5SLXByb2plY3Qub3JnL0xpY2Vuc2VzLwogKgogKgogKiAgTk9URQogKgogKiAgICBSZXF1aXJlcyB0aGUgZm9sbG93aW5nIGF1eGlsaWFyeSByb3V0aW5lczoKICoKICoJbGdhbW1hZm4oeCkJLSBsb2cgZ2FtbWEgZnVuY3Rpb24KICoJcG50KHgsIGRmLCBuY3ApIC0gdGhlIGRpc3RyaWJ1dGlvbiBmdW5jdGlvbiBmb3IKICoJCQkgIHRoZSBub24tY2VudHJhbCB0IGRpc3RyaWJ1dGlvbgogKgogKgogKiBERVNDUklQVElPTgogKgogKiAgICBGcm9tIEpvaG5zb24sIEtvdHogYW5kIEJhbGFrcmlzaG5hbiAoMTk5NSkgWzJuZCBlZC47IGZvcm11bGEgKDMxLjE1KSwgcC41MTZdLAogKiAgICB0aGUgbm9uLWNlbnRyYWwgdCBkZW5zaXR5IGlzCiAqCiAqICAgICAgZih4LCBkZiwgbmNwKSA9CiAqCiAqICAgICAgICBleHAoLS41Km5jcF4yKSAqIGdhbW1hKChkZisxKS8yKSAvIChzcXJ0KHBpKmRmKSogZ2FtbWEoZGYvMikpICogKGRmLyhkZit4XjIpKV4oKGRmKzEpLzIpICoKICogICAgICAgICAgc3VtX3tqPTB9XkluZiAgZ2FtbWEoKGRmK2orMSkvMikvKGZhY3RvcmlhbChqKSogZ2FtbWEoKGRmKzEpLzIpKSAqICh4Km5jcCpzcXJ0KDIpL3NxcnQoZGYreF4yKSleIGoKICoKICoKICogICAgVGhlIGZ1bmN0aW9uYWwgcmVsYXRpb25zaGlwCiAqCiAqCSAgIGYoeCwgZGYsIG5jcCkgPSBkZi94ICoKICoJCQkgICAgICAoRihzcXJ0KChkZisyKS9kZikqeCwgZGYrMiwgbmNwKSAtIEYoeCwgZGYsIG5jcCkpCiAqCiAqICAgIGlzIHVzZWQgdG8gZXZhbHVhdGUgdGhlIGRlbnNpdHkgYXQgeCAhPSAwIGFuZAogKgogKgkgICBmKDAsIGRmLCBuY3ApID0gZXhwKC0uNSpuY3BeMikgLwogKgkJCQkoc3FydChwaSkqc3FydChkZikqZ2FtbWEoZGYvMikpKmdhbW1hKChkZisxKS8yKQogKgogKiAgICBpcyB1c2VkIGZvciB4PTAuCiAqCiAqICAgIEFsbCBjYWxjdWxhdGlvbnMgYXJlIGRvbmUgb24gbG9nLXNjYWxlIHRvIGluY3JlYXNlIHN0YWJpbGl0eS4KICoKICogRklYTUU6IHBudCgpIGlzIGtub3duIHRvIGJlIGluYWNjdXJhdGUgaW4gdGhlICh2ZXJ5KSBsZWZ0IHRhaWwgYW5kIGZvciBuY3AgPiAzOAogKiAgICAgICA9PT4gdXNlIGEgZGlyZWN0IGxvZy1zcGFjZSBzdW1tYXRpb24gZm9ybXVsYSBpbiB0aGF0IGNhc2UKICovCgojaW5jbHVkZSAibm1hdGguaCIKI2luY2x1ZGUgImRwcS5oIgoKZG91YmxlIGRudChkb3VibGUgeCwgZG91YmxlIGRmLCBkb3VibGUgbmNwLCBpbnQgZ2l2ZV9sb2cpCnsKICAgIGRvdWJsZSB1OwojaWZkZWYgSUVFRV83NTQKICAgIGlmIChJU05BTih4KSB8fCBJU05BTihkZikpCglyZXR1cm4geCArIGRmOwojZW5kaWYKCiAgICAvKiBJZiBub24tcG9zaXRpdmUgZGYgdGhlbiBlcnJvciAqLwogICAgaWYgKGRmIDw9IDAuMCkgTUxfRVJSX3JldHVybl9OQU47CgogICAgaWYobmNwID09IDAuMCkgcmV0dXJuIGR0KHgsIGRmLCBnaXZlX2xvZyk7CgogICAgLyogSWYgeCBpcyBpbmZpbml0ZSB0aGVuIHJldHVybiAwICovCiAgICBpZighUl9GSU5JVEUoeCkpCglyZXR1cm4gUl9EX18wOwoKICAgIC8qIElmIGluZmluaXRlIGRmIHRoZW4gdGhlIGRlbnNpdHkgaXMgaWRlbnRpY2FsIHRvIGEKICAgICAgIG5vcm1hbCBkaXN0cmlidXRpb24gd2l0aCBtZWFuID0gbmNwLiAgSG93ZXZlciwgdGhlIGZvcm11bGEKICAgICAgIGxvc2VzIGEgbG90IG9mIGFjY3VyYWN5IGFyb3VuZCBkZj0xZTkKICAgICovCiAgICBpZighUl9GSU5JVEUoZGYpIHx8IGRmID4gMWU4KQoJcmV0dXJuIGRub3JtKHgsIG5jcCwgMS4sIGdpdmVfbG9nKTsKCiAgICAvKiBEbyBjYWxjdWxhdGlvbnMgb24gbG9nIHNjYWxlIHRvIHN0YWJpbGl6ZSAqLwoKICAgIC8qIENvbnNpZGVyIHR3byBjYXNlczogeCB+PSAwIG9yIG5vdCAqLwogICAgaWYgKGZhYnMoeCkgPiBzcXJ0KGRmICogREJMX0VQU0lMT04pKSB7Cgl1ID0gbG9nKGRmKSAtIGxvZyhmYWJzKHgpKSArCgkgICAgbG9nKGZhYnMocG50KHgqc3FydCgoZGYrMikvZGYpLCBkZisyLCBuY3AsIDEsIDApIC0KCQkgICAgIHBudCh4LCBkZiwgbmNwLCAxLCAwKSkpOwoJLyogRklYTUU6IHRoZSBhYm92ZSBzdGlsbCBzdWZmZXJzIGZyb20gY2FuY2VsbGF0aW9uIChidXQgbm90IGhvcnJpYmx5KSAqLwogICAgfQogICAgZWxzZSB7ICAvKiB4IH49IDAgOiAtPiBzYW1lIHZhbHVlIGFzIGZvciAgeCA9IDAgKi8KCXUgPSBsZ2FtbWFmbigoZGYrMSkvMikgLSBsZ2FtbWFmbihkZi8yKQoJICAgIC0gKE1fTE5fU1FSVF9QSSArIC41Kihsb2coZGYpICsgbmNwKm5jcCkpOwogICAgfQoKICAgIHJldHVybiAoZ2l2ZV9sb2cgPyB1IDogZXhwKHUpKTsKfQo=