LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm9sZTIuaCIKCiNpbmNsdWRlICJpbml0Z3VpZC5oIgojaW5jbHVkZSAidmZ3LmgiCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCkhNT0RVTEUgQVZJRklMRV9oTW9kdWxlICAgPSBOVUxMOwoKc3RhdGljIEJPT0wgICAgQVZJRklMRV9iTG9ja2VkOwpzdGF0aWMgVUlOVCAgICBBVklGSUxFX3VVc2VDb3VudDsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuUXVlcnlJbnRlcmZhY2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcG9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuQWRkUmVmKExQQ0xBU1NGQUNUT1JZIGlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5DcmVhdGVJbnN0YW5jZShMUENMQVNTRkFDVE9SWSBpZmFjZSxMUFVOS05PV04gcE91dGVyLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmopOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNsYXNzRmFjdG9yeV9mbkxvY2tTZXJ2ZXIoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsQk9PTCBkb2xvY2spOwoKc3RhdGljIGNvbnN0IElDbGFzc0ZhY3RvcnlWdGJsIGljbGFzc2ZhY3QgPSB7CiAgSUNsYXNzRmFjdG9yeV9mblF1ZXJ5SW50ZXJmYWNlLAogIElDbGFzc0ZhY3RvcnlfZm5BZGRSZWYsCiAgSUNsYXNzRmFjdG9yeV9mblJlbGVhc2UsCiAgSUNsYXNzRmFjdG9yeV9mbkNyZWF0ZUluc3RhbmNlLAogIElDbGFzc0ZhY3RvcnlfZm5Mb2NrU2VydmVyCn07Cgp0eXBlZGVmIHN0cnVjdAp7CiAgLyogSVVua25vd24gZmllbGRzICovCiAgY29uc3QgSUNsYXNzRmFjdG9yeVZ0YmwgKmxwVnRibDsKICBEV09SRAkgZHdSZWY7CgogIENMU0lEICBjbHNpZDsKfSBJQ2xhc3NGYWN0b3J5SW1wbDsKCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlQ2xhc3NGYWN0b3J5KGNvbnN0IENMU0lEICpwY2xzaWQsIGNvbnN0IElJRCAqcmlpZCwKCQkJCQkgIExQVk9JRCAqcHB2KQp7CiAgSUNsYXNzRmFjdG9yeUltcGwgKnBDbGFzc0ZhY3RvcnkgPSBOVUxMOwogIEhSRVNVTFQgICAgICAgICAgICBocjsKCiAgKnBwdiA9IE5VTEw7CgogIHBDbGFzc0ZhY3RvcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpwQ2xhc3NGYWN0b3J5KSk7CiAgaWYgKHBDbGFzc0ZhY3RvcnkgPT0gTlVMTCkKICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICBwQ2xhc3NGYWN0b3J5LT5scFZ0YmwgICAgPSAmaWNsYXNzZmFjdDsKICBwQ2xhc3NGYWN0b3J5LT5kd1JlZiAgICAgPSAwOwogIHBDbGFzc0ZhY3RvcnktPmNsc2lkICAgICA9ICpwY2xzaWQ7CgogIGhyID0gSUNsYXNzRmFjdG9yeV9RdWVyeUludGVyZmFjZSgoSUNsYXNzRmFjdG9yeSopcENsYXNzRmFjdG9yeSwgcmlpZCwgcHB2KTsKICBpZiAoRkFJTEVEKGhyKSkgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcENsYXNzRmFjdG9yeSk7CiAgICAqcHB2ID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5RdWVyeUludGVyZmFjZShMUENMQVNTRkFDVE9SWSBpZmFjZSwKCQkJCQkJICAgICBSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqKQp7CiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIGlmYWNlLCByaWlkLCBwcG9iaik7CgogIGlmICgoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93biwgcmlpZCkpIHx8CiAgICAgIChJc0VxdWFsR1VJRCgmSUlEX0lDbGFzc0ZhY3RvcnksIHJpaWQpKSkgewogICAgKnBwb2JqID0gaWZhY2U7CiAgICBJQ2xhc3NGYWN0b3J5X0FkZFJlZihpZmFjZSk7CiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5BZGRSZWYoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpCnsKICBJQ2xhc3NGYWN0b3J5SW1wbCAqVGhpcyA9IChJQ2xhc3NGYWN0b3J5SW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIiwgaWZhY2UpOwoKICByZXR1cm4gKysoVGhpcy0+ZHdSZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKQp7CiAgSUNsYXNzRmFjdG9yeUltcGwgKlRoaXMgPSAoSUNsYXNzRmFjdG9yeUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcClcbiIsIGlmYWNlKTsKICBpZiAoKC0tKFRoaXMtPmR3UmVmKSkgPiAwKQogICAgcmV0dXJuIFRoaXMtPmR3UmVmOwoKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuQ3JlYXRlSW5zdGFuY2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsCgkJCQkJCSAgICAgTFBVTktOT1dOIHBPdXRlciwKCQkJCQkJICAgICBSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqKQp7CiAgSUNsYXNzRmFjdG9yeUltcGwgKlRoaXMgPSAoSUNsYXNzRmFjdG9yeUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlcywlcClcbiIsIGlmYWNlLCBwT3V0ZXIsIGRlYnVnc3RyX2d1aWQocmlpZCksCglwcG9iaik7CgogIGlmIChwcG9iaiA9PSBOVUxMIHx8IHBPdXRlciAhPSBOVUxMKQogICAgcmV0dXJuIEVfRkFJTDsKICAqcHBvYmogPSBOVUxMOwoKICBpZiAoSXNFcXVhbEdVSUQoJkNMU0lEX0FWSUZpbGUsICZUaGlzLT5jbHNpZCkpCiAgICByZXR1cm4gQVZJRklMRV9DcmVhdGVBVklGaWxlKHJpaWQscHBvYmopOwogIGlmIChJc0VxdWFsR1VJRCgmQ0xTSURfSUNNU3RyZWFtLCAmVGhpcy0+Y2xzaWQpKQogICAgcmV0dXJuIEFWSUZJTEVfQ3JlYXRlSUNNU3RyZWFtKHJpaWQscHBvYmopOwogIGlmIChJc0VxdWFsR1VJRCgmQ0xTSURfV0FWRmlsZSwgJlRoaXMtPmNsc2lkKSkKICAgIHJldHVybiBBVklGSUxFX0NyZWF0ZVdBVkZpbGUocmlpZCxwcG9iaik7CiAgaWYgKElzRXF1YWxHVUlEKCZDTFNJRF9BQ01TdHJlYW0sICZUaGlzLT5jbHNpZCkpCiAgICByZXR1cm4gQVZJRklMRV9DcmVhdGVBQ01TdHJlYW0ocmlpZCxwcG9iaik7CgogIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNsYXNzRmFjdG9yeV9mbkxvY2tTZXJ2ZXIoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsQk9PTCBkb2xvY2spCnsKICBUUkFDRSgiKCVwLCVkKVxuIixpZmFjZSxkb2xvY2spOwoKICBBVklGSUxFX2JMb2NrZWQgPSBkb2xvY2s7CgogIHJldHVybiBTX09LOwp9CgpMUENXU1RSIEFWSUZJTEVfQmFzZW5hbWVXKExQQ1dTVFIgc3pQYXRoKQp7CiNkZWZpbmUgU0xBU0godykgKCh3KSA9PSAnLycgfHwgKHcpID09ICdcXCcpCgogIExQQ1dTVFIgc3pDdXI7CgogIGZvciAoc3pDdXIgPSBzelBhdGggKyBsc3RybGVuVyhzelBhdGgpOwogICAgICAgc3pDdXIgPiBzelBhdGggJiYgIVNMQVNIKCpzekN1cikgJiYgKnN6Q3VyICE9ICc6JzspCiAgICBzekN1ci0tOwoKICBpZiAoc3pDdXIgPT0gc3pQYXRoKQogICAgcmV0dXJuIHN6Q3VyOwogIGVsc2UKICAgIHJldHVybiBzekN1ciArIDE7CgojdW5kZWYgU0xBU0gKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlEbGxHZXRDbGFzc09iamVjdCAoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIERsbEdldENsYXNzT2JqZWN0KFJFRkNMU0lEIHBjbHNpZCwgUkVGSUlEIHBpaWQsIExQVk9JRCAqcHB2KQp7CiAgVFJBQ0UoIiglcywlcywlcClcbiIsIGRlYnVnc3RyX2d1aWQocGNsc2lkKSwgZGVidWdzdHJfZ3VpZChwaWlkKSwgcHB2KTsKCiAgaWYgKHBjbHNpZCA9PSBOVUxMIHx8IHBpaWQgPT0gTlVMTCB8fCBwcHYgPT0gTlVMTCkKICAgIHJldHVybiBFX0ZBSUw7CgogIHJldHVybiBBVklGSUxFX0NyZWF0ZUNsYXNzRmFjdG9yeShwY2xzaWQscGlpZCxwcHYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURsbENhblVubG9hZE5vdwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBEbGxDYW5VbmxvYWROb3codm9pZCkKewogIHJldHVybiAoKEFWSUZJTEVfYkxvY2tlZCB8fCBBVklGSUxFX3VVc2VDb3VudCkgPyBTX0ZBTFNFIDogU19PSyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRGxsTWFpbgkJW0FWSUZJTDMyLmluaXRdCiAqLwpCT09MIFdJTkFQSSBEbGxNYWluKEhJTlNUQU5DRSBoSW5zdERsbCwgRFdPUkQgZmR3UmVhc29uLCBMUFZPSUQgbHB2UmVzZXJ2ZWQpCnsKICBUUkFDRSgiKCVwLCVkLCVwKVxuIiwgaEluc3REbGwsIGZkd1JlYXNvbiwgbHB2UmVzZXJ2ZWQpOwoKICBzd2l0Y2ggKGZkd1JlYXNvbikgewogIGNhc2UgRExMX1BST0NFU1NfQVRUQUNIOgogICAgRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyhoSW5zdERsbCk7CiAgICBBVklGSUxFX2hNb2R1bGUgPSBoSW5zdERsbDsKICAgIGJyZWFrOwogIGNhc2UgRExMX1BST0NFU1NfREVUQUNIOgogICAgYnJlYWs7CiAgfTsKCiAgcmV0dXJuIFRSVUU7Cn0K