LyoKICogKEMpIENvcHlyaWdodCAyMDA4LTIwMTEKICogR3JhZW1lIFJ1c3MsIDxncmFlbWUucnVzc0BnbWFpbC5jb20+CiAqCiAqIChDKSBDb3B5cmlnaHQgMjAwMgogKiBEYW5pZWwgRW5nc3Ry9m0sIE9taWNyb24gQ2V0aSBBQiwgPGRhbmllbEBvbWljcm9uLnNlPgogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPHBjaS5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vcGNpLmg+CiNpbmNsdWRlIDxhc20vaWMvcGNpLmg+CiNpbmNsdWRlIDxhc20vaWMvc2M1MjAuaD4KCnN0YXRpYyBzdHJ1Y3QgewoJdTggcHJpb3JpdHk7Cgl1MTYgbGV2ZWxfcmVnOwoJdTggbGV2ZWxfYml0Owp9IHNjNTIwX2lycVtdID0gewoJeyBTQzUyMF9JUlEwLCAgMCwgMHgwMSB9LAoJeyBTQzUyMF9JUlExLCAgMCwgMHgwMiB9LAoJeyBTQzUyMF9JUlEyLCAgMSwgMHgwMiB9LAoJeyBTQzUyMF9JUlEzLCAgMCwgMHgwOCB9LAoJeyBTQzUyMF9JUlE0LCAgMCwgMHgxMCB9LAoJeyBTQzUyMF9JUlE1LCAgMCwgMHgyMCB9LAoJeyBTQzUyMF9JUlE2LCAgMCwgMHg0MCB9LAoJeyBTQzUyMF9JUlE3LCAgMCwgMHg4MCB9LAoKCXsgU0M1MjBfSVJROCwgIDEsIDB4MDEgfSwKCXsgU0M1MjBfSVJROSwgIDEsIDB4MDIgfSwKCXsgU0M1MjBfSVJRMTAsIDEsIDB4MDQgfSwKCXsgU0M1MjBfSVJRMTEsIDEsIDB4MDggfSwKCXsgU0M1MjBfSVJRMTIsIDEsIDB4MTAgfSwKCXsgU0M1MjBfSVJRMTMsIDEsIDB4MjAgfSwKCXsgU0M1MjBfSVJRMTQsIDEsIDB4NDAgfSwKCXsgU0M1MjBfSVJRMTUsIDEsIDB4ODAgfQp9OwoKLyogVGhlIGludGVycnVwdCB1c2VkIGZvciBQQ0kgSU5UQS1JTlREICAqLwppbnQgc2M1MjBfcGNpX2ludHNbMTVdID0gewoJLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLAoJCS0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xCn07CgovKiB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNvbmZpZ3VyZSBhIHBjaSBpbnRlcnJ1cHQgKi8KaW50IHBjaV9zYzUyMF9zZXRfaXJxKGludCBwY2lfcGluLCBpbnQgaXJxKQp7CglpbnQgaTsKCXU4IHRtcGI7Cgl1MTYgdG1wdzsKCglkZWJ1Zygic2V0X2lycSgpOiBtYXAgSU5UJWMgdG8gSVJRJWRcbiIsIHBjaV9waW4gKyAnQScsIGlycSk7CgoJaWYgKGlycSA8IDAgfHwgaXJxID4gMTUpIHsKCQlyZXR1cm4gLTE7IC8qIGlsbGVnYWwgaXJxICovCgl9CgoJaWYgKHBjaV9waW4gPCAwIHx8IHBjaV9waW4gPiAxNSkgewoJCXJldHVybiAtMTsgLyogaWxsZWdhbCBwY2kgaW50IHBpbiAqLwoJfQoKCS8qIGZpcnN0IGRpc2FibGUgYW55IG5vbi1wY2kgaW50ZXJydXB0IHNvdXJjZSB0aGF0IHVzZQoJICogdGhpcyBsZXZlbCAqLwoKCS8qIFBDSSBpbnRlcnJ1cHQgbWFwcGluZyAoQSB0aHJvdWdoIEQpKi8KCWZvciAoaT0wOyBpPD0zIDtpKyspIHsKCQlpZiAocmVhZGIoJnNjNTIwX21tY3ItPnBjaV9pbnRfbWFwW2ldKSA9PSBzYzUyMF9pcnFbaXJxXS5wcmlvcml0eSkKCQkJd3JpdGViKFNDNTIwX0lSUV9ESVNBQkxFRCwgJnNjNTIwX21tY3ItPnBjaV9pbnRfbWFwW2ldKTsKCX0KCgkvKiBHUCBJUlEgaW50ZXJydXB0IG1hcHBpbmcgKi8KCWZvciAoaT0wOyBpPD0xMCA7aSsrKSB7CgkJaWYgKHJlYWRiKCZzYzUyMF9tbWNyLT5ncF9pbnRfbWFwW2ldKSA9PSBzYzUyMF9pcnFbaXJxXS5wcmlvcml0eSkKCQkJd3JpdGViKFNDNTIwX0lSUV9ESVNBQkxFRCwgJnNjNTIwX21tY3ItPmdwX2ludF9tYXBbaV0pOwoJfQoKCS8qIFNldCB0aGUgdHJpZ2dlciB0byBsZXZlbCAqLwoJdG1wYiA9IHJlYWRiKCZzYzUyMF9tbWNyLT5waWNfbW9kZVtzYzUyMF9pcnFbaXJxXS5sZXZlbF9yZWddKTsKCXRtcGIgfD0gc2M1MjBfaXJxW2lycV0ubGV2ZWxfYml0OwoJd3JpdGViKHRtcGIsICZzYzUyMF9tbWNyLT5waWNfbW9kZVtzYzUyMF9pcnFbaXJxXS5sZXZlbF9yZWddKTsKCgoJaWYgKHBjaV9waW4gPCA0KSB7CgkJLyogUENJIElOVEEtSU5URCAqLwoJCS8qIHJvdXRlIHRoZSBpbnRlcnJ1cHQgKi8KCQl3cml0ZWIoc2M1MjBfaXJxW2lycV0ucHJpb3JpdHksICZzYzUyMF9tbWNyLT5wY2lfaW50X21hcFtwY2lfcGluXSk7Cgl9IGVsc2UgewoJCS8qIEdQSVJRMC1HUElSUTEwIHVzZWQgZm9yIGFkZGl0aW9uYWwgUENJIElOVFMgKi8KCQl3cml0ZWIoc2M1MjBfaXJxW2lycV0ucHJpb3JpdHksICZzYzUyMF9tbWNyLT5ncF9pbnRfbWFwW3BjaV9waW4gLSA0XSk7CgoJCS8qIGFsc28gc2V0IHRoZSBwb2xhcml0eSBpbiB0aGlzIGNhc2UgKi8KCQl0bXB3ID0gcmVhZHcoJnNjNTIwX21tY3ItPmludHBpbnBvbCk7CgkJdG1wdyB8PSAoMSA8PCAocGNpX3Bpbi00KSk7CgkJd3JpdGV3KHRtcHcsICZzYzUyMF9tbWNyLT5pbnRwaW5wb2wpOwoJfQoKCS8qIHJlZ2lzdGVyIHRoZSBwaW4gKi8KCXNjNTIwX3BjaV9pbnRzW3BjaV9waW5dID0gaXJxOwoKCglyZXR1cm4gMDsgLyogT0sgKi8KfQoKdm9pZCBwY2lfc2M1MjBfaW5pdChzdHJ1Y3QgcGNpX2NvbnRyb2xsZXIgKmhvc2UpCnsKCWhvc2UtPmZpcnN0X2J1c25vID0gMDsKCWhvc2UtPmxhc3RfYnVzbm8gPSAweGZmOwoJaG9zZS0+cmVnaW9uX2NvdW50ID0gcGNpX3NldF9yZWdpb25zKGhvc2UpOwoKCXBjaV9zZXR1cF90eXBlMShob3NlLAoJCQlTQzUyMF9SRUdfQUREUiwKCQkJU0M1MjBfUkVHX0RBVEEpOwoKCXBjaV9yZWdpc3Rlcl9ob3NlKGhvc2UpOwoKCWhvc2UtPmxhc3RfYnVzbm8gPSBwY2lfaG9zZV9zY2FuKGhvc2UpOwoKCS8qIGVuYWJsZSB0YXJnZXQgbWVtb3J5IGFjY2VzZXMgb24gaG9zdCBicmlnZSAqLwoJcGNpX3dyaXRlX2NvbmZpZ193b3JkKDAsIFBDSV9DT01NQU5ELAoJCQkgICAgICBQQ0lfQ09NTUFORF9NRU1PUlkgfCBQQ0lfQ09NTUFORF9NQVNURVIpOwp9Cg==