I2lmbmRlZiBHSU1fVFJJX0NPTExJU0lPTl9IX0lOQ0xVREVECiNkZWZpbmUgR0lNX1RSSV9DT0xMSVNJT05fSF9JTkNMVURFRAoKLyohIFxmaWxlIGdpbV90cmlfY29sbGlzaW9uLmgKXGF1dGhvciBGcmFuY2lzY28gTGV/biBO32plcmEKKi8KLyoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVGhpcyBzb3VyY2UgZmlsZSBpcyBwYXJ0IG9mIEdJTVBBQ1QgTGlicmFyeS4KCkZvciB0aGUgbGF0ZXN0IGluZm8sIHNlZSBodHRwOi8vZ2ltcGFjdC5zb3VyY2Vmb3JnZS5uZXQvCgpDb3B5cmlnaHQgKGMpIDIwMDYgRnJhbmNpc2NvIExlb24gTmFqZXJhLiBDLkMuIDgwMDg3MzcxLgplbWFpbDogcHJvamVjdGlsZW1hbkB5YWhvby5jb20KCiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIEVJVEhFUjoKICAgKDEpIFRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlCiAgICAgICBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdAogICAgICAgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLiBUaGUgdGV4dCBvZiB0aGUgR05VIExlc3NlcgogICAgICAgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBpcyBpbmNsdWRlZCB3aXRoIHRoaXMgbGlicmFyeSBpbiB0aGUKICAgICAgIGZpbGUgR0lNUEFDVC1MSUNFTlNFLUxHUEwuVFhULgogICAoMikgVGhlIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgaXMgaW5jbHVkZWQgd2l0aCB0aGlzIGxpYnJhcnkgaW4KICAgICAgIHRoZSBmaWxlIEdJTVBBQ1QtTElDRU5TRS1CU0QuVFhULgogICAoMykgVGhlIHpsaWIvbGlicG5nIGxpY2Vuc2UgdGhhdCBpcyBpbmNsdWRlZCB3aXRoIHRoaXMgbGlicmFyeSBpbgogICAgICAgdGhlIGZpbGUgR0lNUEFDVC1MSUNFTlNFLVpMSUIuVFhULgoKIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIHRoZSBmaWxlcwogR0lNUEFDVC1MSUNFTlNFLUxHUEwuVFhULCBHSU1QQUNULUxJQ0VOU0UtWkxJQi5UWFQgYW5kIEdJTVBBQ1QtTElDRU5TRS1CU0QuVFhUIGZvciBtb3JlIGRldGFpbHMuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoqLwoKI2luY2x1ZGUgImdpbV9ib3hfY29sbGlzaW9uLmgiCiNpbmNsdWRlICJnaW1fY2xpcF9wb2x5Z29uLmgiCgoKCgojZGVmaW5lIE1BWF9UUklfQ0xJUFBJTkcgMTYKCi8vISBTdHJ1Y3R1cmUgZm9yIGNvbGxpc2lvbgpzdHJ1Y3QgR0lNX1RSSUFOR0xFX0NPTlRBQ1RfREFUQQp7CiAgICBHUkVBTCBtX3BlbmV0cmF0aW9uX2RlcHRoOwogICAgR1VJTlQgbV9wb2ludF9jb3VudDsKICAgIGJ0VmVjdG9yNCBtX3NlcGFyYXRpbmdfbm9ybWFsOwogICAgYnRWZWN0b3IzIG1fcG9pbnRzW01BWF9UUklfQ0xJUFBJTkddOwoKCVNJTURfRk9SQ0VfSU5MSU5FIHZvaWQgY29weV9mcm9tKGNvbnN0IEdJTV9UUklBTkdMRV9DT05UQUNUX0RBVEEmIG90aGVyKQoJewoJCW1fcGVuZXRyYXRpb25fZGVwdGggPSBvdGhlci5tX3BlbmV0cmF0aW9uX2RlcHRoOwoJCW1fc2VwYXJhdGluZ19ub3JtYWwgPSBvdGhlci5tX3NlcGFyYXRpbmdfbm9ybWFsOwoJCW1fcG9pbnRfY291bnQgPSBvdGhlci5tX3BvaW50X2NvdW50OwoJCUdVSU5UIGkgPSBtX3BvaW50X2NvdW50OwoJCXdoaWxlKGktLSkKCQl7CgkJCW1fcG9pbnRzW2ldID0gb3RoZXIubV9wb2ludHNbaV07CgkJfQoJfQoKCUdJTV9UUklBTkdMRV9DT05UQUNUX0RBVEEoKQoJewoJfQoKCUdJTV9UUklBTkdMRV9DT05UQUNUX0RBVEEoY29uc3QgR0lNX1RSSUFOR0xFX0NPTlRBQ1RfREFUQSYgb3RoZXIpCgl7CgkJY29weV9mcm9tKG90aGVyKTsKCX0KCgkKCQoKICAgIC8vISBjbGFzc2lmeSBwb2ludHMgdGhhdCBhcmUgY2xvc2VyCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBESVNUQU5DRV9GVU5DLHR5cGVuYW1lIENMQVNTX1BMQU5FPgogICAgU0lNRF9GT1JDRV9JTkxJTkUgdm9pZCBtZXJnZXBvaW50c19nZW5lcmljKGNvbnN0IENMQVNTX1BMQU5FICYgcGxhbmUsCiAgICAJCQkJR1JFQUwgbWFyZ2luLCBjb25zdCBidFZlY3RvcjMgKiBwb2ludHMsIEdVSU5UIHBvaW50X2NvdW50LCBESVNUQU5DRV9GVU5DIGRpc3RhbmNlX2Z1bmMpCiAgICB7CQogICAgCW1fcG9pbnRfY291bnQgPSAwOwogICAgCW1fcGVuZXRyYXRpb25fZGVwdGg9IC0xMDAwLjBmOwoKCQlHVUlOVCBwb2ludF9pbmRpY2VzW01BWF9UUklfQ0xJUFBJTkddOwoKCQlHVUlOVCBfazsKCgkJZm9yKF9rPTA7X2s8cG9pbnRfY291bnQ7X2srKykKCQl7CgkJCUdSRUFMIF9kaXN0ID0gLWRpc3RhbmNlX2Z1bmMocGxhbmUscG9pbnRzW19rXSkgKyBtYXJnaW47CgoJCQlpZihfZGlzdD49MC4wZikKCQkJewoJCQkJaWYoX2Rpc3Q+bV9wZW5ldHJhdGlvbl9kZXB0aCkKCQkJCXsKCQkJCQltX3BlbmV0cmF0aW9uX2RlcHRoID0gX2Rpc3Q7CgkJCQkJcG9pbnRfaW5kaWNlc1swXSA9IF9rOwoJCQkJCW1fcG9pbnRfY291bnQ9MTsKCQkJCX0KCQkJCWVsc2UgaWYoKF9kaXN0K0dfRVBTSUxPTik+PW1fcGVuZXRyYXRpb25fZGVwdGgpCgkJCQl7CgkJCQkJcG9pbnRfaW5kaWNlc1ttX3BvaW50X2NvdW50XSA9IF9rOwoJCQkJCW1fcG9pbnRfY291bnQrKzsKCQkJCX0KCQkJfQoJCX0KCgkJZm9yKCBfaz0wO19rPG1fcG9pbnRfY291bnQ7X2srKykKCQl7CgkJCW1fcG9pbnRzW19rXSA9IHBvaW50c1twb2ludF9pbmRpY2VzW19rXV07CgkJfQoJfQoKCS8vISBjbGFzc2lmeSBwb2ludHMgdGhhdCBhcmUgY2xvc2VyCglTSU1EX0ZPUkNFX0lOTElORSB2b2lkIG1lcmdlX3BvaW50cyhjb25zdCBidFZlY3RvcjQgJiBwbGFuZSwgR1JFQUwgbWFyZ2luLAoJCQkJCQkJCQkJIGNvbnN0IGJ0VmVjdG9yMyAqIHBvaW50cywgR1VJTlQgcG9pbnRfY291bnQpCgl7CgkJbV9zZXBhcmF0aW5nX25vcm1hbCA9IHBsYW5lOwoJCW1lcmdlcG9pbnRzX2dlbmVyaWMocGxhbmUsIG1hcmdpbiwgcG9pbnRzLCBwb2ludF9jb3VudCwgRElTVEFOQ0VfUExBTkVfM0RfRlVOQygpKTsKCX0KfTsKCgovLyEgQ2xhc3MgZm9yIGNvbGxpZGluZyB0cmlhbmdsZXMKY2xhc3MgR0lNX1RSSUFOR0xFCnsKcHVibGljOgoJYnRTY2FsYXIgbV9tYXJnaW47CiAgICBidFZlY3RvcjMgbV92ZXJ0aWNlc1szXTsKCiAgICBHSU1fVFJJQU5HTEUoKTptX21hcmdpbigwLjFmKQogICAgewogICAgfQoKICAgIFNJTURfRk9SQ0VfSU5MSU5FIEdJTV9BQUJCIGdldF9ib3goKSAgY29uc3QKICAgIHsKICAgIAlyZXR1cm4gR0lNX0FBQkIobV92ZXJ0aWNlc1swXSxtX3ZlcnRpY2VzWzFdLG1fdmVydGljZXNbMl0sbV9tYXJnaW4pOwogICAgfQoKICAgIFNJTURfRk9SQ0VfSU5MSU5FIHZvaWQgZ2V0X25vcm1hbChidFZlY3RvcjMgJm5vcm1hbCkgIGNvbnN0CiAgICB7CiAgICAJVFJJQU5HTEVfTk9STUFMKG1fdmVydGljZXNbMF0sbV92ZXJ0aWNlc1sxXSxtX3ZlcnRpY2VzWzJdLG5vcm1hbCk7CiAgICB9CgogICAgU0lNRF9GT1JDRV9JTkxJTkUgdm9pZCBnZXRfcGxhbmUoYnRWZWN0b3I0ICZwbGFuZSkgIGNvbnN0CiAgICB7CiAgICAJVFJJQU5HTEVfUExBTkUobV92ZXJ0aWNlc1swXSxtX3ZlcnRpY2VzWzFdLG1fdmVydGljZXNbMl0scGxhbmUpOzsKICAgIH0KCiAgICBTSU1EX0ZPUkNFX0lOTElORSB2b2lkIGFwcGx5X3RyYW5zZm9ybShjb25zdCBidFRyYW5zZm9ybSAmIHRyYW5zKQogICAgewogICAgCW1fdmVydGljZXNbMF0gPSB0cmFucyhtX3ZlcnRpY2VzWzBdKTsKICAgIAltX3ZlcnRpY2VzWzFdID0gdHJhbnMobV92ZXJ0aWNlc1sxXSk7CiAgICAJbV92ZXJ0aWNlc1syXSA9IHRyYW5zKG1fdmVydGljZXNbMl0pOwogICAgfQoKICAgIFNJTURfRk9SQ0VfSU5MSU5FIHZvaWQgZ2V0X2VkZ2VfcGxhbmUoR1VJTlQgZWRnZV9pbmRleCxjb25zdCBidFZlY3RvcjMgJnRyaWFuZ2xlX25vcm1hbCxidFZlY3RvcjQgJnBsYW5lKSAgY29uc3QKICAgIHsKCQljb25zdCBidFZlY3RvcjMgJiBlMCA9IG1fdmVydGljZXNbZWRnZV9pbmRleF07CgkJY29uc3QgYnRWZWN0b3IzICYgZTEgPSBtX3ZlcnRpY2VzWyhlZGdlX2luZGV4KzEpJTNdOwoJCUVER0VfUExBTkUoZTAsZTEsdHJpYW5nbGVfbm9ybWFsLHBsYW5lKTsKICAgIH0KCiAgICAvLyEgR2V0cyB0aGUgcmVsYXRpdmUgdHJhbnNmb3JtYXRpb24gb2YgdGhpcyB0cmlhbmdsZQogICAgLyohCiAgICBUaGUgdHJhbnNmb3JtYXRpb24gaXMgb3JpZW50ZWQgdG8gdGhlIHRyaWFuZ2xlIG5vcm1hbCAsIGFuZCBhbGlnbmVkIHRvIHRoZSAxc3QgZWRnZSBvZiB0aGlzIHRyaWFuZ2xlLiBUaGUgcG9zaXRpb24gY29ycmVzcG9uZHMgdG8gdmVydGljZSAwOgogICAgLSB0cmlhbmdsZSBub3JtYWwgY29ycmVzcG9uZHMgdG8gWiBheGlzLgogICAgLSAxc3Qgbm9ybWFsaXplZCBlZGdlIGNvcnJlc3BvbmRzIHRvIFggYXhpcywKCiAgICAqLwogICAgU0lNRF9GT1JDRV9JTkxJTkUgdm9pZCBnZXRfdHJpYW5nbGVfdHJhbnNmb3JtKGJ0VHJhbnNmb3JtICYgdHJpYW5nbGVfdHJhbnNmb3JtKSAgY29uc3QKICAgIHsKICAgIAlidE1hdHJpeDN4MyAmIG1hdHJpeCA9IHRyaWFuZ2xlX3RyYW5zZm9ybS5nZXRCYXNpcygpOwoKICAgIAlidFZlY3RvcjMgemF4aXM7CiAgICAJZ2V0X25vcm1hbCh6YXhpcyk7CiAgICAJTUFUX1NFVF9aKG1hdHJpeCx6YXhpcyk7CgogICAgCWJ0VmVjdG9yMyB4YXhpcyA9IG1fdmVydGljZXNbMV0gLSBtX3ZlcnRpY2VzWzBdOwogICAgCVZFQ19OT1JNQUxJWkUoeGF4aXMpOwogICAgCU1BVF9TRVRfWChtYXRyaXgseGF4aXMpOwoKICAgIAkvL3kgYXhpcwogICAgCXhheGlzID0gemF4aXMuY3Jvc3MoeGF4aXMpOwogICAgCU1BVF9TRVRfWShtYXRyaXgseGF4aXMpOwoKICAgIAl0cmlhbmdsZV90cmFuc2Zvcm0uc2V0T3JpZ2luKG1fdmVydGljZXNbMF0pOwogICAgfQoKCgkvLyEgVGVzdCB0cmlhbmdsZXMgYnkgZmluZGluZyBzZXBhcmF0aW5nIGF4aXMKCS8qIQoJXHBhcmFtIG90aGVyIFRyaWFuZ2xlIGZvciBjb2xsaWRlCglccGFyYW0gY29udGFjdF9kYXRhIFN0cnVjdHVyZSBmb3IgaG9sZGluZyBjb250YWN0IHBvaW50cywgbm9ybWFsIGFuZCBwZW5ldHJhdGlvbiBkZXB0aDsgVGhlIG5vcm1hbCBpcyBwb2ludGluZyB0b3dhcmQgdGhpcyB0cmlhbmdsZSBmcm9tIHRoZSBvdGhlciB0cmlhbmdsZQoJKi8KCWJvb2wgY29sbGlkZV90cmlhbmdsZV9oYXJkX3Rlc3QoCgkJY29uc3QgR0lNX1RSSUFOR0xFICYgb3RoZXIsCgkJR0lNX1RSSUFOR0xFX0NPTlRBQ1RfREFUQSAmIGNvbnRhY3RfZGF0YSkgY29uc3Q7CgoJLy8hIFRlc3QgYm94ZXMgYmVmb3JlIGRvaW5nIGhhcmQgdGVzdAoJLyohCglccGFyYW0gb3RoZXIgVHJpYW5nbGUgZm9yIGNvbGxpZGUKCVxwYXJhbSBjb250YWN0X2RhdGEgU3RydWN0dXJlIGZvciBob2xkaW5nIGNvbnRhY3QgcG9pbnRzLCBub3JtYWwgYW5kIHBlbmV0cmF0aW9uIGRlcHRoOyBUaGUgbm9ybWFsIGlzIHBvaW50aW5nIHRvd2FyZCB0aGlzIHRyaWFuZ2xlIGZyb20gdGhlIG90aGVyIHRyaWFuZ2xlCglcCgkqLwoJU0lNRF9GT1JDRV9JTkxJTkUgYm9vbCBjb2xsaWRlX3RyaWFuZ2xlKAoJCWNvbnN0IEdJTV9UUklBTkdMRSAmIG90aGVyLAoJCUdJTV9UUklBTkdMRV9DT05UQUNUX0RBVEEgJiBjb250YWN0X2RhdGEpIGNvbnN0Cgl7CgkJLy90ZXN0IGJveCBjb2xsaXNpb2luCgkJR0lNX0FBQkIgYm94dShtX3ZlcnRpY2VzWzBdLG1fdmVydGljZXNbMV0sbV92ZXJ0aWNlc1syXSxtX21hcmdpbik7CgkJR0lNX0FBQkIgYm94dihvdGhlci5tX3ZlcnRpY2VzWzBdLG90aGVyLm1fdmVydGljZXNbMV0sb3RoZXIubV92ZXJ0aWNlc1syXSxvdGhlci5tX21hcmdpbik7CgkJaWYoIWJveHUuaGFzX2NvbGxpc2lvbihib3h2KSkgcmV0dXJuIGZhbHNlOwoKCQkvL2RvIGhhcmQgdGVzdAoJCXJldHVybiBjb2xsaWRlX3RyaWFuZ2xlX2hhcmRfdGVzdChvdGhlcixjb250YWN0X2RhdGEpOwoJfQoKCS8qIQoKCVNvbHZlIHRoZSBTeXN0ZW0gZm9yIHUsdiBwYXJhbWV0ZXJzOgoKCXUqYXhlMVtpMV0gKyB2KmF4ZTJbaTFdID0gdmVjcHJvaltpMV0KCXUqYXhlMVtpMl0gKyB2KmF4ZTJbaTJdID0gdmVjcHJvaltpMl0KCglzdXN0aXR1dGU6Cgl2ID0gKHZlY3Byb2pbaTJdIC0gdSpheGUxW2kyXSkvYXhlMltpMl0KCgl0aGVuIHRoZSBmaXJzdCBlcXVhdGlvbiBpbiB0ZXJtcyBvZiAndSc6CgoJLS0+IHUqYXhlMVtpMV0gKyAoKHZlY3Byb2pbaTJdIC0gdSpheGUxW2kyXSkvYXhlMltpMl0pKmF4ZTJbaTFdID0gdmVjcHJvaltpMV0KCgktLT4gdSpheGUxW2kxXSArIHZlY3Byb2pbaTJdKmF4ZTJbaTFdL2F4ZTJbaTJdIC0gdSpheGUxW2kyXSpheGUyW2kxXS9heGUyW2kyXSA9IHZlY3Byb2pbaTFdCgoJLS0+IHUqKGF4ZTFbaTFdICAtIGF4ZTFbaTJdKmF4ZTJbaTFdL2F4ZTJbaTJdKSA9IHZlY3Byb2pbaTFdIC0gdmVjcHJvaltpMl0qYXhlMltpMV0vYXhlMltpMl0KCgktLT4gdSooKGF4ZTFbaTFdKmF4ZTJbaTJdICAtIGF4ZTFbaTJdKmF4ZTJbaTFdKS9heGUyW2kyXSkgPSAodmVjcHJvaltpMV0qYXhlMltpMl0gLSB2ZWNwcm9qW2kyXSpheGUyW2kxXSkvYXhlMltpMl0KCgktLT4gdSooYXhlMVtpMV0qYXhlMltpMl0gIC0gYXhlMVtpMl0qYXhlMltpMV0pID0gdmVjcHJvaltpMV0qYXhlMltpMl0gLSB2ZWNwcm9qW2kyXSpheGUyW2kxXQoKCS0tPiB1ID0gKHZlY3Byb2pbaTFdKmF4ZTJbaTJdIC0gdmVjcHJvaltpMl0qYXhlMltpMV0pIC8oYXhlMVtpMV0qYXhlMltpMl0gIC0gYXhlMVtpMl0qYXhlMltpMV0pCgppZiAwLjA8PSB1K3YgPD0xLjAgdGhlbiB0aGV5IGFyZSBpbnNpZGUgb2YgdHJpYW5nbGUKCglccmV0dXJuIGZhbHNlIGlmIHRoZSBwb2ludCBpcyBvdXRzaWRlIG9mIHRyaWFuZ2xlLlRoaXMgZnVuY3Rpb24gIGRvZXNuJ3QgdGFrZSB0aGUgbWFyZ2luCgkqLwoJU0lNRF9GT1JDRV9JTkxJTkUgYm9vbCBnZXRfdXZfcGFyYW1ldGVycygKCQkJY29uc3QgYnRWZWN0b3IzICYgcG9pbnQsCgkJCWNvbnN0IGJ0VmVjdG9yMyAmIHRyaV9wbGFuZSwKCQkJR1JFQUwgJiB1LCBHUkVBTCAmIHYpIGNvbnN0Cgl7CgkJYnRWZWN0b3IzIF9heGUxID0gbV92ZXJ0aWNlc1sxXS1tX3ZlcnRpY2VzWzBdOwoJCWJ0VmVjdG9yMyBfYXhlMiA9IG1fdmVydGljZXNbMl0tbV92ZXJ0aWNlc1swXTsKCQlidFZlY3RvcjMgX3ZlY3Byb2ogPSBwb2ludCAtIG1fdmVydGljZXNbMF07CgkJR1VJTlQgX2kxID0gKHRyaV9wbGFuZS5jbG9zZXN0QXhpcygpKzEpJTM7CgkJR1VJTlQgX2kyID0gKF9pMSsxKSUzOwoJCWlmKGJ0RmFicyhfYXhlMltfaTJdKTxHX0VQU0lMT04pCgkJewoJCQl1ID0gKF92ZWNwcm9qW19pMl0qX2F4ZTJbX2kxXSAtIF92ZWNwcm9qW19pMV0qX2F4ZTJbX2kyXSkgLyhfYXhlMVtfaTJdKl9heGUyW19pMV0gIC0gX2F4ZTFbX2kxXSpfYXhlMltfaTJdKTsKCQkJdiA9IChfdmVjcHJvaltfaTFdIC0gdSpfYXhlMVtfaTFdKS9fYXhlMltfaTFdOwoJCX0KCQllbHNlCgkJewoJCQl1ID0gKF92ZWNwcm9qW19pMV0qX2F4ZTJbX2kyXSAtIF92ZWNwcm9qW19pMl0qX2F4ZTJbX2kxXSkgLyhfYXhlMVtfaTFdKl9heGUyW19pMl0gIC0gX2F4ZTFbX2kyXSpfYXhlMltfaTFdKTsKCQkJdiA9IChfdmVjcHJvaltfaTJdIC0gdSpfYXhlMVtfaTJdKS9fYXhlMltfaTJdOwoJCX0KCgkJaWYodTwtR19FUFNJTE9OKQoJCXsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQllbHNlIGlmKHY8LUdfRVBTSUxPTikKCQl7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJZWxzZQoJCXsKCQkJYnRTY2FsYXIgc3VtdXY7CgkJCXN1bXV2ID0gdSt2OwoJCQlpZihzdW11djwtR19FUFNJTE9OKQoJCQl7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQkJZWxzZSBpZihzdW11di0xLjBmPkdfRVBTSUxPTikKCQkJewoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJfQoJCXJldHVybiB0cnVlOwoJfQoKCS8vISBpcyBwb2ludCBpbiB0cmlhbmdsZSBiZWFtPwoJLyohCglUZXN0IGlmIHBvaW50IGlzIGluIHRyaWFuZ2xlLCB3aXRoIG1fbWFyZ2luIHRvbGVyYW5jZQoJKi8KCVNJTURfRk9SQ0VfSU5MSU5FIGJvb2wgaXNfcG9pbnRfaW5zaWRlKGNvbnN0IGJ0VmVjdG9yMyAmIHBvaW50LCBjb25zdCBidFZlY3RvcjMgJiB0cmlfbm9ybWFsKSBjb25zdAoJewoJCS8vVGVzdCB3aXRoIGVkZ2UgMAoJCWJ0VmVjdG9yNCBlZGdlX3BsYW5lOwoJCXRoaXMtPmdldF9lZGdlX3BsYW5lKDAsdHJpX25vcm1hbCxlZGdlX3BsYW5lKTsKCQlHUkVBTCBkaXN0ID0gRElTVEFOQ0VfUExBTkVfUE9JTlQoZWRnZV9wbGFuZSxwb2ludCk7CgkJaWYoZGlzdC1tX21hcmdpbj4wLjBmKSByZXR1cm4gZmFsc2U7IC8vIG91dHNpZGUgcGxhbmUKCgkJdGhpcy0+Z2V0X2VkZ2VfcGxhbmUoMSx0cmlfbm9ybWFsLGVkZ2VfcGxhbmUpOwoJCWRpc3QgPSBESVNUQU5DRV9QTEFORV9QT0lOVChlZGdlX3BsYW5lLHBvaW50KTsKCQlpZihkaXN0LW1fbWFyZ2luPjAuMGYpIHJldHVybiBmYWxzZTsgLy8gb3V0c2lkZSBwbGFuZQoKCQl0aGlzLT5nZXRfZWRnZV9wbGFuZSgyLHRyaV9ub3JtYWwsZWRnZV9wbGFuZSk7CgkJZGlzdCA9IERJU1RBTkNFX1BMQU5FX1BPSU5UKGVkZ2VfcGxhbmUscG9pbnQpOwoJCWlmKGRpc3QtbV9tYXJnaW4+MC4wZikgcmV0dXJuIGZhbHNlOyAvLyBvdXRzaWRlIHBsYW5lCgkJcmV0dXJuIHRydWU7Cgl9CgoKCS8vISBCaWRpcmVjY2lvbmFsIHJheSBjb2xsaXNpb24KCVNJTURfRk9SQ0VfSU5MSU5FIGJvb2wgcmF5X2NvbGxpc2lvbigKCQljb25zdCBidFZlY3RvcjMgJiB2UG9pbnQsCgkJY29uc3QgYnRWZWN0b3IzICYgdkRpciwgYnRWZWN0b3IzICYgcG91dCwgYnRWZWN0b3IzICYgdHJpYW5nbGVfbm9ybWFsLAoJCUdSRUFMICYgdHBhcmFtLCBHUkVBTCB0bWF4ID0gR19SRUFMX0lORklOSVRZKQoJewoJCWJ0VmVjdG9yNCBmYWNlcGxhbmU7CgkJewoJCQlidFZlY3RvcjMgZGlmMSA9IG1fdmVydGljZXNbMV0gLSBtX3ZlcnRpY2VzWzBdOwoJCQlidFZlY3RvcjMgZGlmMiA9IG1fdmVydGljZXNbMl0gLSBtX3ZlcnRpY2VzWzBdOwogICAgCQlWRUNfQ1JPU1MoZmFjZXBsYW5lLGRpZjEsZGlmMik7CiAgICAJCWZhY2VwbGFuZVszXSA9IG1fdmVydGljZXNbMF0uZG90KGZhY2VwbGFuZSk7CgkJfQoKCQlHVUlOVCByZXMgPSBMSU5FX1BMQU5FX0NPTExJU0lPTihmYWNlcGxhbmUsdkRpcix2UG9pbnQscG91dCx0cGFyYW0sIGJ0U2NhbGFyKDApLCB0bWF4KTsKCQlpZihyZXMgPT0gMCkgcmV0dXJuIGZhbHNlOwoJCWlmKCEgaXNfcG9pbnRfaW5zaWRlKHBvdXQsZmFjZXBsYW5lKSkgcmV0dXJuIGZhbHNlOwoKCQlpZihyZXM9PTIpIC8vaW52ZXJ0IG5vcm1hbAoJCXsKCQkJdHJpYW5nbGVfbm9ybWFsLnNldFZhbHVlKC1mYWNlcGxhbmVbMF0sLWZhY2VwbGFuZVsxXSwtZmFjZXBsYW5lWzJdKTsKCQl9CgkJZWxzZQoJCXsKCQkJdHJpYW5nbGVfbm9ybWFsLnNldFZhbHVlKGZhY2VwbGFuZVswXSxmYWNlcGxhbmVbMV0sZmFjZXBsYW5lWzJdKTsKCQl9CgoJCVZFQ19OT1JNQUxJWkUodHJpYW5nbGVfbm9ybWFsKTsKCgkJcmV0dXJuIHRydWU7Cgl9CgoKCS8vISBvbmUgZGlyZWNjaW9uIHJheSBjb2xsaXNpb24KCVNJTURfRk9SQ0VfSU5MSU5FIGJvb2wgcmF5X2NvbGxpc2lvbl9mcm9udF9zaWRlKAoJCWNvbnN0IGJ0VmVjdG9yMyAmIHZQb2ludCwKCQljb25zdCBidFZlY3RvcjMgJiB2RGlyLCBidFZlY3RvcjMgJiBwb3V0LCBidFZlY3RvcjMgJiB0cmlhbmdsZV9ub3JtYWwsCgkJR1JFQUwgJiB0cGFyYW0sIEdSRUFMIHRtYXggPSBHX1JFQUxfSU5GSU5JVFkpCgl7CgkJYnRWZWN0b3I0IGZhY2VwbGFuZTsKCQl7CgkJCWJ0VmVjdG9yMyBkaWYxID0gbV92ZXJ0aWNlc1sxXSAtIG1fdmVydGljZXNbMF07CgkJCWJ0VmVjdG9yMyBkaWYyID0gbV92ZXJ0aWNlc1syXSAtIG1fdmVydGljZXNbMF07CiAgICAJCVZFQ19DUk9TUyhmYWNlcGxhbmUsZGlmMSxkaWYyKTsKICAgIAkJZmFjZXBsYW5lWzNdID0gbV92ZXJ0aWNlc1swXS5kb3QoZmFjZXBsYW5lKTsKCQl9CgoJCUdVSU5UIHJlcyA9IExJTkVfUExBTkVfQ09MTElTSU9OKGZhY2VwbGFuZSx2RGlyLHZQb2ludCxwb3V0LHRwYXJhbSwgYnRTY2FsYXIoMCksIHRtYXgpOwoJCWlmKHJlcyAhPSAxKSByZXR1cm4gZmFsc2U7CgoJCWlmKCFpc19wb2ludF9pbnNpZGUocG91dCxmYWNlcGxhbmUpKSByZXR1cm4gZmFsc2U7CgoJCXRyaWFuZ2xlX25vcm1hbC5zZXRWYWx1ZShmYWNlcGxhbmVbMF0sZmFjZXBsYW5lWzFdLGZhY2VwbGFuZVsyXSk7CgoJCVZFQ19OT1JNQUxJWkUodHJpYW5nbGVfbm9ybWFsKTsKCgkJcmV0dXJuIHRydWU7Cgl9Cgp9OwoKCgoKI2VuZGlmIC8vIEdJTV9UUklfQ09MTElTSU9OX0hfSU5DTFVERUQK