LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgImV4dHJhY2h1bmsuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJ2ZncuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCi8qIHJlYWRzIGEgY2h1bmsgb3V0b2YgdGhlIGV4dHJhY2h1bmstc3RydWN0dXJlICovCkhSRVNVTFQgUmVhZEV4dHJhQ2h1bmsoTFBFWFRSQUNIVU5LUyBleHRyYSxGT1VSQ0MgY2tpZCxMUFZPSUQgbHBEYXRhLAoJCSAgICAgICBMUExPTkcgc2l6ZSkKewogIExQQllURSBscDsKICBEV09SRCAgY2I7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KGV4dHJhICE9IE5VTEwpOwogIGFzc2VydChzaXplICE9IE5VTEwpOwoKICBscCA9IGV4dHJhLT5scDsKICBjYiA9IGV4dHJhLT5jYjsKCiAgaWYgKGxwICE9IE5VTEwpIHsKICAgIHdoaWxlIChjYiA+IDApIHsKICAgICAgaWYgKCgoRk9VUkNDKilscClbMF0gPT0gY2tpZCkgewoJLyogZm91bmQgY29ycmVjdCBjaHVuayAqLwoJaWYgKGxwRGF0YSAhPSBOVUxMICYmICpzaXplID4gMCkKCSAgbWVtY3B5KGxwRGF0YSwgbHAgKyAyICogc2l6ZW9mKERXT1JEKSwKCQkgbWluKCgoTFBEV09SRClscClbMV0sICooTFBEV09SRClzaXplKSk7CgoJKihMUERXT1JEKXNpemUgPSAoKExQRFdPUkQpbHApWzFdOwoKCXJldHVybiBBVklFUlJfT0s7CiAgICAgIH0gZWxzZSB7CgkvKiBza2lwIHRvIG5leHQgY2h1bmsgKi8KCWNiIC09ICgoTFBEV09SRClscClbMV0gKyAyICogc2l6ZW9mKERXT1JEKTsKCWxwICs9ICgoTFBEV09SRClscClbMV0gKyAyICogc2l6ZW9mKERXT1JEKTsKICAgICAgfQogICAgfQogIH0KCiAgLyogd2FudGVkIGNodW5rIGRvZXNuJ3QgZXhpc3QgKi8KICAqc2l6ZSA9IDA7CgogIHJldHVybiBBVklFUlJfTk9EQVRBOwp9CgovKiB3cml0ZXMgYSBjaHVuayBpbnRvIHRoZSBleHRyYWNodW5rLXN0cnVjdHVyZSAqLwpIUkVTVUxUIFdyaXRlRXh0cmFDaHVuayhMUEVYVFJBQ0hVTktTIGV4dHJhLEZPVVJDQyBja2lkLExQVk9JRCBscERhdGEsCgkJCUxPTkcgc2l6ZSkKewogIExQRFdPUkQgbHA7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KGV4dHJhICE9IE5VTEwpOwogIGFzc2VydChscERhdGEgIT0gTlVMTCk7CiAgYXNzZXJ0KHNpemUgPiAwKTsKCiAgaWYgKGV4dHJhLT5scCkKICAgIGxwID0gKExQRFdPUkQpR2xvYmFsUmVBbGxvY1B0cihleHRyYS0+bHAsIGV4dHJhLT5jYiArIHNpemUgKyAyICogc2l6ZW9mKERXT1JEKSwgR0hORCk7CiAgZWxzZQogICAgbHAgPSAoTFBEV09SRClHbG9iYWxBbGxvY1B0cihHSE5ELCBzaXplICsgMiAqIHNpemVvZihEV09SRCkpOwoKICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBleHRyYS0+bHAgID0gbHA7CiAgKChMUEJZVEUpbHApICs9IGV4dHJhLT5jYjsKICBleHRyYS0+Y2IgKz0gc2l6ZSArIDIgKiBzaXplb2YoRFdPUkQpOwoKICAvKiBpbnNlcnQgY2h1bmstaGVhZGVyIGluIGJsb2NrICovCiAgbHBbMF0gPSBja2lkOwogIGxwWzFdID0gc2l6ZTsKCiAgaWYgKGxwRGF0YSAhPSBOVUxMICYmIHNpemUgPiAwKQogICAgbWVtY3B5KGxwICsgMiwgbHBEYXRhLCBzaXplKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKLyogcmVhZHMgYSBjaHVuayBmb21yIHRoZSBITU1JTyBpbnRvIHRoZSBleHRyYWNodW5rLXN0cnVjdHVyZSAqLwpIUkVTVUxUIFJlYWRDaHVua0ludG9FeHRyYShMUEVYVFJBQ0hVTktTIGV4dHJhLEhNTUlPIGhtbWlvLE1NQ0tJTkZPICpscGNrKQp7CiAgTFBEV09SRCBscDsKICBEV09SRCAgIGNiOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChleHRyYSAhPSBOVUxMKTsKICBhc3NlcnQoaG1taW8gIT0gTlVMTCk7CiAgYXNzZXJ0KGxwY2sgICE9IE5VTEwpOwoKICBjYiAgPSBscGNrLT5ja3NpemUgKyAyICogc2l6ZW9mKERXT1JEKTsKICBjYiArPSAoY2IgJiAxKTsKCiAgaWYgKGV4dHJhLT5scCAhPSBOVUxMKSB7CiAgICBscCA9IChMUERXT1JEKUdsb2JhbFJlQWxsb2NQdHIoZXh0cmEtPmxwLCBleHRyYS0+Y2IgKyBjYiwgR0hORCk7CiAgfSBlbHNlCiAgICBscCA9IChMUERXT1JEKUdsb2JhbEFsbG9jUHRyKEdITkQsIGNiKTsKCiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgZXh0cmEtPmxwICA9IGxwOwogICgoTFBCWVRFKWxwKSArPSBleHRyYS0+Y2I7CiAgZXh0cmEtPmNiICs9IGNiOwoKICAvKiBpbnNlcnQgY2h1bmstaGVhZGVyIGluIGJsb2NrICovCiAgbHBbMF0gPSBscGNrLT5ja2lkOwogIGxwWzFdID0gbHBjay0+Y2tzaXplOwoKICBpZiAobHBjay0+Y2tzaXplID4gMCkgewogICAgaWYgKG1taW9TZWVrKGhtbWlvLCBscGNrLT5kd0RhdGFPZmZzZXQsIFNFRUtfU0VUKSA9PSAtMSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgIGlmIChtbWlvUmVhZChobW1pbywgKEhQU1RSKSZscFsyXSwgbHBjay0+Y2tzaXplKSAhPSAoTE9ORylscGNrLT5ja3NpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKiByZWFkcyBhbGwgbm9uLWp1bmsgY2h1bmtzIGludG8gdGhlIGV4dHJhY2h1bmstc3RydWN0dXJlIHVudGlsIGl0IGZpbmRzCiAqIHRoZSBnaXZlbiBjaHVuayBvciB0aGUgb3B0aW9uYWwgcGFyZW50LWNodW5rIGlzIGF0IHRoZSBlbmQgKi8KSFJFU1VMVCBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKExQRVhUUkFDSFVOS1MgZXh0cmEsSE1NSU8gaG1taW8sTU1DS0lORk8gKmxwY2ssCgkJCSAgICAgICBNTUNLSU5GTyAqbHBja1BhcmVudCxVSU5UIGZsYWdzKQp7CiAgRk9VUkNDICBja2lkOwogIEZPVVJDQyAgZmNjVHlwZTsKICBIUkVTVUxUIGhyOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChleHRyYSAhPSBOVUxMKTsKICBhc3NlcnQoaG1taW8gIT0gTlVMTCk7CiAgYXNzZXJ0KGxwY2sgICE9IE5VTEwpOwoKICBUUkFDRSgiKHslcCwlbHV9LCVwLCVwLCVwLDB4JVgpXG4iLCBleHRyYS0+bHAsIGV4dHJhLT5jYiwgaG1taW8sIGxwY2ssCglscGNrUGFyZW50LCBmbGFncyk7CgogIC8qIHdoYXQgY2h1bmsgaWQgYW5kIGZvcm0vbGlzdCB0eXBlIHNob2l1bGQgd2Ugc2VhcmNoPyAqLwogIGlmIChmbGFncyAmIE1NSU9fRklORENIVU5LKSB7CiAgICBja2lkICAgID0gbHBjay0+Y2tpZDsKICAgIGZjY1R5cGUgPSAwOwogIH0gZWxzZSBpZiAoZmxhZ3MgJiBNTUlPX0ZJTkRMSVNUKSB7CiAgICBja2lkICAgID0gRk9VUkNDX0xJU1Q7CiAgICBmY2NUeXBlID0gbHBjay0+ZmNjVHlwZTsKICB9IGVsc2UgaWYgKGZsYWdzICYgTU1JT19GSU5EUklGRikgewogICAgY2tpZCAgICA9IEZPVVJDQ19SSUZGOwogICAgZmNjVHlwZSA9IGxwY2stPmZjY1R5cGU7CiAgfSBlbHNlCiAgICBja2lkID0gZmNjVHlwZSA9IChGT1VSQ0MpLTE7IC8qIGNvbGxlY3QgZXZlcnl0aGluZyBpbnRvIGV4dHJhISAqLwoKICBUUkFDRSgiOiBmaW5kIGNraWQ9MHglMDhsWCBmY2NUeXBlPTB4JTA4bFhcbiIsIGNraWQsIGZjY1R5cGUpOwoKICBmb3IgKDs7KSB7CiAgICBociA9IG1taW9EZXNjZW5kKGhtbWlvLCBscGNrLCBscGNrUGFyZW50LCAwKTsKICAgIGlmIChociAhPSBTX09LKSB7CiAgICAgIC8qIE5vIGV4dHJhIGNodW5rcyBpbmZyb250IG9mIGRlc2lyZWQgY2h1bms/ICovCiAgICAgIGlmIChmbGFncyA9PSAwICYmIGhyID09IE1NSU9FUlJfQ0hVTktOT1RGT1VORCkKCWhyID0gQVZJRVJSX09LOwogICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogSGF2ZSB3ZSBmb3VuZCB3aGF0IHdlIHNlYXJjaCBmb3I/ICovCiAgICBpZiAoKGxwY2stPmNraWQgPT0gY2tpZCkgJiYKCShmY2NUeXBlID09IChGT1VSQ0MpMCB8fCBscGNrLT5mY2NUeXBlID09IGZjY1R5cGUpKQogICAgICByZXR1cm4gQVZJRVJSX09LOwoKICAgIC8qIFNraXAgcGFkZGluZyBjaHVua3MsIHRoZSBvdGhlcnMgcHV0IGludG8gdGhlIGV4dHJhY2h1bmstc3RydWN0dXJlICovCiAgICBpZiAobHBjay0+Y2tpZCA9PSBja2lkQVZJUEFERElORyB8fAoJbHBjay0+Y2tpZCA9PSBtbWlvRk9VUkNDKCdwJywnYScsJ2QnLCdkJykpCiAgICAgIGhyID0gbW1pb0FzY2VuZChobW1pbywgbHBjaywgMCk7CiAgICBlbHNlCiAgICAgIGhyID0gUmVhZENodW5rSW50b0V4dHJhKGV4dHJhLCBobW1pbywgbHBjayk7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KfQo=