LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCIDxkYW5pZWxAb21pY3Jvbi5zZT4uCiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKLyogc3R1ZmYgc3BlY2lmaWMgZm9yIHRoZSBzYzUyMCwgYnV0IGluZGVwZW5kZW50IG9mIGltcGxlbWVudGF0aW9uICovCgojaW5jbHVkZSA8Y29tbW9uLmg+CiNpbmNsdWRlIDxwY2kuaD4KI2luY2x1ZGUgPGFzbS9wY2kuaD4KI2luY2x1ZGUgPGFzbS9pYy9zYzUyMC5oPgoKc3RhdGljIHN0cnVjdCB7Cgl1OCBwcmlvcml0eTsKCXUxNiBsZXZlbF9yZWc7Cgl1OCBsZXZlbF9iaXQ7Cn0gc2M1MjBfaXJxW10gPSB7Cgl7IFNDNTIwX0lSUTAsICAwLCAweDAxIH0sCgl7IFNDNTIwX0lSUTEsICAwLCAweDAyIH0sCgl7IFNDNTIwX0lSUTIsICAxLCAweDAyIH0sCgl7IFNDNTIwX0lSUTMsICAwLCAweDA4IH0sCgl7IFNDNTIwX0lSUTQsICAwLCAweDEwIH0sCgl7IFNDNTIwX0lSUTUsICAwLCAweDIwIH0sCgl7IFNDNTIwX0lSUTYsICAwLCAweDQwIH0sCgl7IFNDNTIwX0lSUTcsICAwLCAweDgwIH0sCgoJeyBTQzUyMF9JUlE4LCAgMSwgMHgwMSB9LAoJeyBTQzUyMF9JUlE5LCAgMSwgMHgwMiB9LAoJeyBTQzUyMF9JUlExMCwgMSwgMHgwNCB9LAoJeyBTQzUyMF9JUlExMSwgMSwgMHgwOCB9LAoJeyBTQzUyMF9JUlExMiwgMSwgMHgxMCB9LAoJeyBTQzUyMF9JUlExMywgMSwgMHgyMCB9LAoJeyBTQzUyMF9JUlExNCwgMSwgMHg0MCB9LAoJeyBTQzUyMF9JUlExNSwgMSwgMHg4MCB9Cn07CgoKLyogVGhlIGludGVycnVwdCB1c2VkIGZvciBQQ0kgSU5UQS1JTlREICAqLwppbnQgc2M1MjBfcGNpX2ludHNbMTVdID0gewoJLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLAoJCS0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xCn07CgovKiB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNvbmZpZ3VyZSBhIHBjaSBpbnRlcnJ1cHQgKi8KaW50IHBjaV9zYzUyMF9zZXRfaXJxKGludCBwY2lfcGluLCBpbnQgaXJxKQp7CglpbnQgaTsKCiMgaWYgMQoJcHJpbnRmKCJzZXRfaXJxKCk6IG1hcCBJTlQlYyB0byBJUlElZFxuIiwgcGNpX3BpbiArICdBJywgaXJxKTsKI2VuZGlmCglpZiAoaXJxIDwgMCB8fCBpcnEgPiAxNSkgewoJCXJldHVybiAtMTsgLyogaWxsZWdhbCBpcnEgKi8KCX0KCglpZiAocGNpX3BpbiA8IDAgfHwgcGNpX3BpbiA+IDE1KSB7CgkJcmV0dXJuIC0xOyAvKiBpbGxlZ2FsIHBjaSBpbnQgcGluICovCgl9CgoJLyogZmlyc3QgZGlzYWJsZSBhbnkgbm9uLXBjaSBpbnRlcnJ1cHQgc291cmNlIHRoYXQgdXNlCgkgKiB0aGlzIGxldmVsICovCgoJLyogUENJIGludGVycnVwdCBtYXBwaW5nIChBIHRocm91Z2ggRCkqLwoJZm9yIChpPTA7IGk8PTMgO2krKykgewoJCWlmIChzYzUyMF9tbWNyLT5wY2lfaW50X21hcFtpXSA9PSBzYzUyMF9pcnFbaXJxXS5wcmlvcml0eSkKCQkJc2M1MjBfbW1jci0+cGNpX2ludF9tYXBbaV0gPSBTQzUyMF9JUlFfRElTQUJMRUQ7Cgl9CgoJLyogR1AgSVJRIGludGVycnVwdCBtYXBwaW5nICovCglmb3IgKGk9MDsgaTw9MTAgO2krKykgewoJCWlmIChzYzUyMF9tbWNyLT5ncF9pbnRfbWFwW2ldID09IHNjNTIwX2lycVtpcnFdLnByaW9yaXR5KQoJCQlzYzUyMF9tbWNyLT5ncF9pbnRfbWFwW2ldID0gU0M1MjBfSVJRX0RJU0FCTEVEOwoJfQoKCS8qIFNldCB0aGUgdHJpZ2dlciB0byBsZXZlbCAqLwoJc2M1MjBfbW1jci0+cGljX21vZGVbc2M1MjBfaXJxW2lycV0ubGV2ZWxfcmVnXSA9CgkJc2M1MjBfbW1jci0+cGljX21vZGVbc2M1MjBfaXJxW2lycV0ubGV2ZWxfcmVnXSB8IHNjNTIwX2lycVtpcnFdLmxldmVsX2JpdDsKCgoJaWYgKHBjaV9waW4gPCA0KSB7CgkJLyogUENJIElOVEEtSU5URCAqLwoJCS8qIHJvdXRlIHRoZSBpbnRlcnJ1cHQgKi8KCQlzYzUyMF9tbWNyLT5wY2lfaW50X21hcFtwY2lfcGluXSA9IHNjNTIwX2lycVtpcnFdLnByaW9yaXR5OwoJfSBlbHNlIHsKCQkvKiBHUElSUTAtR1BJUlExMCB1c2VkIGZvciBhZGRpdGlvbmFsIFBDSSBJTlRTICovCgkJc2M1MjBfbW1jci0+Z3BfaW50X21hcFtwY2lfcGluIC0gNF0gPSBzYzUyMF9pcnFbaXJxXS5wcmlvcml0eTsKCgkJLyogYWxzbyBzZXQgdGhlIHBvbGFyaXR5IGluIHRoaXMgY2FzZSAqLwoJCXNjNTIwX21tY3ItPmludHBpbnBvbCA9IHNjNTIwX21tY3ItPmludHBpbnBvbCB8ICgxIDw8IChwY2lfcGluLTQpKTsKCX0KCgkvKiByZWdpc3RlciB0aGUgcGluICovCglzYzUyMF9wY2lfaW50c1twY2lfcGluXSA9IGlycTsKCgoJcmV0dXJuIDA7IC8qIE9LICovCn0KCnZvaWQgcGNpX3NjNTIwX2luaXQoc3RydWN0IHBjaV9jb250cm9sbGVyICpob3NlKQp7Cglob3NlLT5maXJzdF9idXNubyA9IDA7Cglob3NlLT5sYXN0X2J1c25vID0gMHhmZjsKCgkvKiBTeXN0ZW0gbWVtb3J5IHNwYWNlICovCglwY2lfc2V0X3JlZ2lvbihob3NlLT5yZWdpb25zICsgMCwKCQkgICAgICAgU0M1MjBfUENJX01FTU9SWV9CVVMsCgkJICAgICAgIFNDNTIwX1BDSV9NRU1PUllfUEhZUywKCQkgICAgICAgU0M1MjBfUENJX01FTU9SWV9TSVpFLAoJCSAgICAgICBQQ0lfUkVHSU9OX01FTSB8IFBDSV9SRUdJT05fU1lTX01FTU9SWSk7CgoJLyogUENJIG1lbW9yeSBzcGFjZSAqLwoJcGNpX3NldF9yZWdpb24oaG9zZS0+cmVnaW9ucyArIDEsCgkJICAgICAgIFNDNTIwX1BDSV9NRU1fQlVTLAoJCSAgICAgICBTQzUyMF9QQ0lfTUVNX1BIWVMsCgkJICAgICAgIFNDNTIwX1BDSV9NRU1fU0laRSwKCQkgICAgICAgUENJX1JFR0lPTl9NRU0pOwoKCS8qIElTQS9QQ0kgbWVtb3J5IHNwYWNlICovCglwY2lfc2V0X3JlZ2lvbihob3NlLT5yZWdpb25zICsgMiwKCQkgICAgICAgU0M1MjBfSVNBX01FTV9CVVMsCgkJICAgICAgIFNDNTIwX0lTQV9NRU1fUEhZUywKCQkgICAgICAgU0M1MjBfSVNBX01FTV9TSVpFLAoJCSAgICAgICBQQ0lfUkVHSU9OX01FTSk7CgoJLyogUENJIEkvTyBzcGFjZSAqLwoJcGNpX3NldF9yZWdpb24oaG9zZS0+cmVnaW9ucyArIDMsCgkJICAgICAgIFNDNTIwX1BDSV9JT19CVVMsCgkJICAgICAgIFNDNTIwX1BDSV9JT19QSFlTLAoJCSAgICAgICBTQzUyMF9QQ0lfSU9fU0laRSwKCQkgICAgICAgUENJX1JFR0lPTl9JTyk7CgoJLyogSVNBL1BDSSBJL08gc3BhY2UgKi8KCXBjaV9zZXRfcmVnaW9uKGhvc2UtPnJlZ2lvbnMgKyA0LAoJCSAgICAgICBTQzUyMF9JU0FfSU9fQlVTLAoJCSAgICAgICBTQzUyMF9JU0FfSU9fUEhZUywKCQkgICAgICAgU0M1MjBfSVNBX0lPX1NJWkUsCgkJICAgICAgIFBDSV9SRUdJT05fSU8pOwoKCWhvc2UtPnJlZ2lvbl9jb3VudCA9IDU7CgoJcGNpX3NldHVwX3R5cGUxKGhvc2UsCgkJCVNDNTIwX1JFR19BRERSLAoJCQlTQzUyMF9SRUdfREFUQSk7CgoJcGNpX3JlZ2lzdGVyX2hvc2UoaG9zZSk7CgoJaG9zZS0+bGFzdF9idXNubyA9IHBjaV9ob3NlX3NjYW4oaG9zZSk7CgoJLyogZW5hYmxlIHRhcmdldCBtZW1vcnkgYWNjZXNlcyBvbiBob3N0IGJyaWdlICovCglwY2lfd3JpdGVfY29uZmlnX3dvcmQoMCwgUENJX0NPTU1BTkQsCgkJCSAgICAgIFBDSV9DT01NQU5EX01FTU9SWSB8IFBDSV9DT01NQU5EX01BU1RFUik7Cgp9Cg==