LyoKICogUHJvamVjdDogVml6S2l0CiAqIFZlcnNpb246IDIuMwogCiAqIERhdGU6IDIwMDkwODIzCiAqIEZpbGU6IFZpc3VhbEdyYXBoaWNzLmNwcAogKgogKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKIAogQ29weXJpZ2h0IChjKSAyMDA0LTIwMDkgSGVpa28gV2ljaG1hbm4gKGh0dHA6Ly93d3cuaW1hZ29tYXQuZGUvdml6a2l0KQogCiAKIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzc2VkIG9yIGltcGxpZWQgd2FycmFudHkuIAogSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuCiAKIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLAogaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOgogCiAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IAogeW91IG11c3Qgbm90IGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gCiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCAKIGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUgYXBwcmVjaWF0ZWQgCiBidXQgaXMgbm90IHJlcXVpcmVkLgogCiAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIAogYW5kIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KIAogMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgIlZpc3VhbEdyYXBoaWNzLmgiCiNpbmNsdWRlICJWaXN1YWxHcmFwaGljVHlwZXMuaCIKI2luY2x1ZGUgIlZpc3VhbFZlcnRleC5oIgojaW5jbHVkZSAiVmlzdWFsRXJyb3JIYW5kbGluZy5oIgojaW5jbHVkZSAiVmlzdWFsR3JhcGhpY3NDb3JlLmgiCiNpbmNsdWRlICJWaXN1YWxDb252b2x1dGlvbkZpbHRlci5oIgojaW5jbHVkZSAiVmlzdWFsTnVyYnMuaCIKI2luY2x1ZGUgIlZpc3VhbERpc3BhdGNoLmgiCiNpbmNsdWRlICJWaXN1YWxUaW1pbmcuaCIKI2luY2x1ZGUgIlZpc3VhbENvbG9yVG9vbHMuaCIKI2luY2x1ZGUgIlZpc3VhbFByZWZlcmVuY2VzLmgiCiNpbmNsdWRlICJWaXN1YWxGaWxlLmgiCiNpbmNsdWRlICJWaXN1YWxJbnRlcnBvbGF0aW9uLmgiCiNpbmNsdWRlICJWaXN1YWxDYW1lcmEuaCIKCiNpbmNsdWRlIDxpb3N0cmVhbT4KCiNpbmNsdWRlIDxhbGdvcml0aG0+IC8vIHNvcnQgb24gdmVjdG9yCgojaW5jbHVkZSA8bWF0aC5oPgojaWZuZGVmIE1fUEkKI2RlZmluZSBNX1BJIDMuMTQxNTkyNjUzNTg5NzkzMjM4NDYyNjQzMzgzMjc5NTAyODgKI2VuZGlmCgojaWYgVEFSR0VUX09TX01BQwojaW5jbHVkZSA8T3BlbkdML2dsLmg+CiNpbmNsdWRlIDxPcGVuR0wvZ2xleHQuaD4KI2luY2x1ZGUgPE9wZW5HTC9nbHUuaD4KI2luY2x1ZGUgPEdMVVQvZ2x1dC5oPgojZW5kaWYKCiNpZiBUQVJHRVRfT1NfV0lOCiNpbmNsdWRlIDxHTC9nbC5oPgojaW5jbHVkZSA8R0wvZ2x1Lmg+CiNpbmNsdWRlICJ3aW4vd2dsZXh0LmgiCiNpbmNsdWRlICJ3aW4vZ2xleHQuaCIKI2luY2x1ZGUgIndpbi9yZXNvdXJjZS5oIgojZW5kaWYKCiNpZiBUQVJHRVRfT1NfV0lOCiNpbmNsdWRlIDx3aW5kb3dzLmg+CiNpbmNsdWRlIDxnZGlwbHVzLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojZW5kaWYKCgoKdXNpbmcgbmFtZXNwYWNlIFZpektpdDsKCgoKVmlzdWFsR3JhcGhpY3MqIFZpc3VhbEdyYXBoaWNzOjp0aGVWaXN1YWxHcmFwaGljcyA9IE5VTEw7ICAvLyBzaW5nbGV0b24KCgojaWYgVEFSR0VUX09TX1dJTgpHTHVpbnQgYmFzZTsgLy8gQmFzZSBEaXNwbGF5IExpc3QgRm9yIFRoZSBGb250IFNldAojZW5kaWYKCgpWaXN1YWxHcmFwaGljczo6VmlzdWFsR3JhcGhpY3MoKSB7Cglpc1NldFVwT25GdWxsc2NyZWVuID0gZmFsc2U7CgkKCWNhbnZhc0JhY2tncm91bmRDb2xvci5yID0gVmlzdWFsUHJlZmVyZW5jZXM6OmdldFZhbHVlKFZpc3VhbFByZWZlcmVuY2VzOjprQ2FudmFzQmFja2dyb3VuZENvbG9yUmVkKTsKCWNhbnZhc0JhY2tncm91bmRDb2xvci5nID0gVmlzdWFsUHJlZmVyZW5jZXM6OmdldFZhbHVlKFZpc3VhbFByZWZlcmVuY2VzOjprQ2FudmFzQmFja2dyb3VuZENvbG9yR3JlZW4pOwoJY2FudmFzQmFja2dyb3VuZENvbG9yLmIgPSBWaXN1YWxQcmVmZXJlbmNlczo6Z2V0VmFsdWUoVmlzdWFsUHJlZmVyZW5jZXM6OmtDYW52YXNCYWNrZ3JvdW5kQ29sb3JCbHVlKTsKCWNhbnZhc0JhY2tncm91bmRDb2xvci5hID0gVmlzdWFsUHJlZmVyZW5jZXM6OmdldFZhbHVlKFZpc3VhbFByZWZlcmVuY2VzOjprQ2FudmFzQmFja2dyb3VuZENvbG9yQWxwaGEpOwoJCglzdXJmYWNlQmFja2dyb3VuZENvbG9yLnIgPSBWaXN1YWxQcmVmZXJlbmNlczo6Z2V0VmFsdWUoVmlzdWFsUHJlZmVyZW5jZXM6OmtTdXJmYWNlQmFja2dyb3VuZENvbG9yUmVkKTsKCXN1cmZhY2VCYWNrZ3JvdW5kQ29sb3IuZyA9IFZpc3VhbFByZWZlcmVuY2VzOjpnZXRWYWx1ZShWaXN1YWxQcmVmZXJlbmNlczo6a1N1cmZhY2VCYWNrZ3JvdW5kQ29sb3JHcmVlbik7CglzdXJmYWNlQmFja2dyb3VuZENvbG9yLmIgPSBWaXN1YWxQcmVmZXJlbmNlczo6Z2V0VmFsdWUoVmlzdWFsUHJlZmVyZW5jZXM6OmtTdXJmYWNlQmFja2dyb3VuZENvbG9yQmx1ZSk7CglzdXJmYWNlQmFja2dyb3VuZENvbG9yLmEgPSBWaXN1YWxQcmVmZXJlbmNlczo6Z2V0VmFsdWUoVmlzdWFsUHJlZmVyZW5jZXM6OmtTdXJmYWNlQmFja2dyb3VuZENvbG9yQWxwaGEpOwoJCglzdXJmYWNlUmVjdC5waXhlbFJlY3Qud2lkdGggPSAwOwoJc3VyZmFjZVJlY3QucGl4ZWxSZWN0LmhlaWdodCA9IDA7CglzdXJmYWNlUmVjdC5ib3R0b21MZWZ0UGl4ZWwueCA9IDA7CglzdXJmYWNlUmVjdC5ib3R0b21MZWZ0UGl4ZWwueSA9IDA7CgkKCXN1cmZhY2VSZWN0VmVydGljYWxPZmZzZXRGcm9tQm90dG9tID0gMDsKCQp9CgoKVmlzdWFsR3JhcGhpY3M6On5WaXN1YWxHcmFwaGljcygpIHsKCQoJZm9yIChOdXJic01hcEl0ZXJhdG9yIGl0ID0gdGhpcy0+bnVyYnNNYXAuYmVnaW4oKTsgaXQgIT0gdGhpcy0+bnVyYnNNYXAuZW5kKCk7IGl0KyspIHsKCQlkZWxldGUgaXQtPnNlY29uZDsKCQlpdC0+c2Vjb25kID0gTlVMTDsKCX0KCW51cmJzTWFwLmNsZWFyKCk7CgkKfQoKClZpc3VhbEdyYXBoaWNzKiBWaXN1YWxHcmFwaGljczo6Z2V0SW5zdGFuY2UoKSB7CiAgICBpZiAodGhlVmlzdWFsR3JhcGhpY3MgPT0gTlVMTCkgewoJCXRoZVZpc3VhbEdyYXBoaWNzID0gbmV3IFZpc3VhbEdyYXBoaWNzOwogICAgfQoJcmV0dXJuIHRoZVZpc3VhbEdyYXBoaWNzOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6ZGlzcG9zZSgpIHsKCQoJVmlzdWFsR3JhcGhpY3NDb3JlOjpkaXNwb3NlKCk7CgkKCWlmICh0aGVWaXN1YWxHcmFwaGljcyAhPSBOVUxMKSB7CgkJZGVsZXRlIHRoZVZpc3VhbEdyYXBoaWNzOwoJCXRoZVZpc3VhbEdyYXBoaWNzID0gTlVMTDsKCX0KfQoKCmJvb2wgVmlzdWFsR3JhcGhpY3M6OmlzSW5pdGlhbGl6ZWQoKSB7CglpZiAodGhlVmlzdWFsR3JhcGhpY3MgPT0gTlVMTCkgewoJCXJldHVybiBmYWxzZTsKCX0gZWxzZSB7CgkJcmV0dXJuIHRydWU7Cgl9Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpzZXRHcmFwaGljc0RldmljZVBvcnQoY29uc3QgR1JBUEhJQ1NfREVWSUNFIHRoZVBvcnQpewoJVmlzdWFsR3JhcGhpY3NDb3JlKiB0aGVWaXN1YWxHcmFwaGljc0NvcmUgPSBWaXN1YWxHcmFwaGljc0NvcmU6OmdldEluc3RhbmNlKCk7Cgl0aGVWaXN1YWxHcmFwaGljc0NvcmUtPnNldEdyYXBoaWNzRGV2aWNlUG9ydCh0aGVQb3J0KTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OnNldENhbnZhc1JlY3QoY29uc3QgVG9wTGVmdFBvc2l0aW9uZWRQaXhlbFJlY3QmIGFDYW52YXNSZWN0KSB7Cgl0aGlzLT5jYW52YXNSZWN0LnBpeGVsUmVjdC53aWR0aCA9IGFDYW52YXNSZWN0LnBpeGVsUmVjdC53aWR0aDsKCXRoaXMtPmNhbnZhc1JlY3QucGl4ZWxSZWN0LmhlaWdodCA9IGFDYW52YXNSZWN0LnBpeGVsUmVjdC5oZWlnaHQ7Cgl0aGlzLT5jYW52YXNSZWN0LmJvdHRvbUxlZnRQaXhlbC54ID0gYUNhbnZhc1JlY3QudG9wTGVmdFBpeGVsLng7Cgl0aGlzLT5jYW52YXNSZWN0LmJvdHRvbUxlZnRQaXhlbC55ID0gKCh0aGlzLT5zdXJmYWNlUmVjdC5waXhlbFJlY3QuaGVpZ2h0IC0gYUNhbnZhc1JlY3QucGl4ZWxSZWN0LmhlaWdodCkgLyAyKSArIHRoaXMtPnN1cmZhY2VSZWN0LmJvdHRvbUxlZnRQaXhlbC55Owp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6c2V0VG90YWxWaXN1YWxpemVyUmVjdChUb3BMZWZ0UG9zaXRpb25lZFBpeGVsUmVjdCB0b3RhbFZpc3VhbGl6ZXJSZWN0KSB7Cgl0aGlzLT5zdXJmYWNlUmVjdC5waXhlbFJlY3Qud2lkdGggPSB0b3RhbFZpc3VhbGl6ZXJSZWN0LnBpeGVsUmVjdC53aWR0aDsKCXRoaXMtPnN1cmZhY2VSZWN0LnBpeGVsUmVjdC5oZWlnaHQgPSB0b3RhbFZpc3VhbGl6ZXJSZWN0LnBpeGVsUmVjdC5oZWlnaHQ7Cgl0aGlzLT5zdXJmYWNlUmVjdC5ib3R0b21MZWZ0UGl4ZWwueCA9IHRvdGFsVmlzdWFsaXplclJlY3QudG9wTGVmdFBpeGVsLng7Cgl0aGlzLT5zdXJmYWNlUmVjdC5ib3R0b21MZWZ0UGl4ZWwueSA9IHRoaXMtPnN1cmZhY2VSZWN0VmVydGljYWxPZmZzZXRGcm9tQm90dG9tOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6c2V0VG90YWxWaXN1YWxpemVyUmVjdFZlcnRpY2FsT2Zmc2V0RnJvbUJvdHRvbShpbnQgdG9wLCBpbnQgaGVpZ2h0KSB7CglWaXN1YWxHcmFwaGljc0NvcmUqIHRoZVZpc3VhbEdyYXBoaWNzQ29yZSA9IFZpc3VhbEdyYXBoaWNzQ29yZTo6Z2V0SW5zdGFuY2UoKTsKCVBpeGVsUmVjdCBjYW52YXNTdXJyb3VuZGluZ1JlY3QgPSB0aGVWaXN1YWxHcmFwaGljc0NvcmUtPmdldENhbnZhc1N1cnJvdW5kaW5nUmVjdCgpOwoJdGhpcy0+c3VyZmFjZVJlY3RWZXJ0aWNhbE9mZnNldEZyb21Cb3R0b20gPSBjYW52YXNTdXJyb3VuZGluZ1JlY3QuaGVpZ2h0IC0gKHRvcCArIGhlaWdodCk7Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjppc1NldHVwRm9yRnVsbFNjcmVlbk1vZGUoY29uc3QgYm9vbCBpc0Z1bGxzY3JlZW4pIHsKCXRoaXMtPmlzU2V0VXBPbkZ1bGxzY3JlZW4gPSBpc0Z1bGxzY3JlZW47Cn0KCgpCb3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdCBWaXN1YWxHcmFwaGljczo6Z2V0Q2FudmFzUmVjdCgpIHsKCXJldHVybiB0aGlzLT5jYW52YXNSZWN0Owp9CgoKUGl4ZWxSZWN0IFZpc3VhbEdyYXBoaWNzOjpnZXRTY3JlZW5SZWN0KCkgewoJVmlzdWFsR3JhcGhpY3NDb3JlKiB0aGVWaXN1YWxHcmFwaGljc0NvcmUgPSBWaXN1YWxHcmFwaGljc0NvcmU6OmdldEluc3RhbmNlKCk7CglyZXR1cm4gdGhlVmlzdWFsR3JhcGhpY3NDb3JlLT5nZXRTY3JlZW5SZWN0KCk7Cn0KCgp1aW50MTYgVmlzdWFsR3JhcGhpY3M6OmdldEJpdHNQZXJQaXhlbE9mU2NyZWVuKCkgewoJVmlzdWFsR3JhcGhpY3NDb3JlKiB0aGVWaXN1YWxHcmFwaGljc0NvcmUgPSBWaXN1YWxHcmFwaGljc0NvcmU6OmdldEluc3RhbmNlKCk7CglyZXR1cm4gdGhlVmlzdWFsR3JhcGhpY3NDb3JlLT5nZXRCaXRzUGVyUGl4ZWxPZlNjcmVlbigpOwp9CgoKdWludDE2IFZpc3VhbEdyYXBoaWNzOjpnZXRSZWZyZXNoUmF0ZU9mU2NyZWVuKCkgewoJVmlzdWFsR3JhcGhpY3NDb3JlKiB0aGVWaXN1YWxHcmFwaGljc0NvcmU7Cgl0aGVWaXN1YWxHcmFwaGljc0NvcmUgPSBWaXN1YWxHcmFwaGljc0NvcmU6OmdldEluc3RhbmNlKCk7CglyZXR1cm4gdGhlVmlzdWFsR3JhcGhpY3NDb3JlLT5nZXRSZWZyZXNoUmF0ZU9mU2NyZWVuKCk7Cn0KCgp1aW50MzIgVmlzdWFsR3JhcGhpY3M6OmdldENhbnZhc1BpeGVsV2lkdGgoKSB7CglyZXR1cm4gY2FudmFzUmVjdC5waXhlbFJlY3Qud2lkdGg7Cn0KCgp1aW50MzIgVmlzdWFsR3JhcGhpY3M6OmdldENhbnZhc1BpeGVsSGVpZ2h0KCkgewoJcmV0dXJuIGNhbnZhc1JlY3QucGl4ZWxSZWN0LmhlaWdodDsKfQoKCkJvdHRvbUxlZnRQb3NpdGlvbmVkUGl4ZWxSZWN0IFZpc3VhbEdyYXBoaWNzOjpnZXRWaWV3cG9ydFJlY3QoKSB7CglCb3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdCBib3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdDsKCUdMaW50IHZpZXdwb3J0UmVjdFs0XTsKICAgIGdsR2V0SW50ZWdlcnYoR0xfVklFV1BPUlQsIHZpZXdwb3J0UmVjdCk7Cglib3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdC5ib3R0b21MZWZ0UGl4ZWwueCA9IHZpZXdwb3J0UmVjdFswXTsKCWJvdHRvbUxlZnRQb3NpdGlvbmVkUGl4ZWxSZWN0LmJvdHRvbUxlZnRQaXhlbC55ID0gdmlld3BvcnRSZWN0WzFdOwoJYm90dG9tTGVmdFBvc2l0aW9uZWRQaXhlbFJlY3QucGl4ZWxSZWN0LndpZHRoID0gdmlld3BvcnRSZWN0WzJdOwoJYm90dG9tTGVmdFBvc2l0aW9uZWRQaXhlbFJlY3QucGl4ZWxSZWN0LmhlaWdodCA9IHZpZXdwb3J0UmVjdFszXTsKCXJldHVybiBib3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdDsKfQoKClBpeGVsIFZpc3VhbEdyYXBoaWNzOjpnZXRWaWV3cG9ydEJvdHRvbUxlZnRPcmlnaW4oKSB7CglQaXhlbCBib3R0b21MZWZ0UGl4ZWw7CglCb3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdCBib3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdCA9IHRoaXMtPmdldFZpZXdwb3J0UmVjdCgpOwoJYm90dG9tTGVmdFBpeGVsLnggPSBib3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdC5ib3R0b21MZWZ0UGl4ZWwueDsKCWJvdHRvbUxlZnRQaXhlbC55ID0gYm90dG9tTGVmdFBvc2l0aW9uZWRQaXhlbFJlY3QuYm90dG9tTGVmdFBpeGVsLnk7CglyZXR1cm4gYm90dG9tTGVmdFBpeGVsOwp9CgoKUmVsYXRpb25hbFJlY3QgVmlzdWFsR3JhcGhpY3M6OmdldFZpZXdwb3J0T3JpZW50YXRpb25BbmRBc3BlY3RSYXRpbygpIHsKCVJlbGF0aW9uYWxSZWN0IHJlbGF0aW9uYWxSZWN0OwoJcmVsYXRpb25hbFJlY3Qub3JpZW50YXRpb24gPSBrU3F1YXJlOwoJcmVsYXRpb25hbFJlY3QuYXNwZWN0UmF0aW8gPSAxLjA7CglCb3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdCBib3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdCA9IHRoaXMtPmdldFZpZXdwb3J0UmVjdCgpOwoJaWYgKChib3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdC5waXhlbFJlY3QuaGVpZ2h0KSA+IChib3R0b21MZWZ0UG9zaXRpb25lZFBpeGVsUmVjdC5waXhlbFJlY3Qud2lkdGgpKSB7CgkJcmVsYXRpb25hbFJlY3Qub3JpZW50YXRpb24gPSBrUG9ydHJhaXQ7CgkJcmVsYXRpb25hbFJlY3QuYXNwZWN0UmF0aW8gPSAoZG91YmxlKWJvdHRvbUxlZnRQb3NpdGlvbmVkUGl4ZWxSZWN0LnBpeGVsUmVjdC5oZWlnaHQgLyAoZG91YmxlKWJvdHRvbUxlZnRQb3NpdGlvbmVkUGl4ZWxSZWN0LnBpeGVsUmVjdC53aWR0aDsKCX0gZWxzZSBpZiAoKGJvdHRvbUxlZnRQb3NpdGlvbmVkUGl4ZWxSZWN0LnBpeGVsUmVjdC53aWR0aCkgPiAoYm90dG9tTGVmdFBvc2l0aW9uZWRQaXhlbFJlY3QucGl4ZWxSZWN0LmhlaWdodCkpIHsKCQlyZWxhdGlvbmFsUmVjdC5vcmllbnRhdGlvbiA9IGtMYW5kc2NhcGU7CgkJcmVsYXRpb25hbFJlY3QuYXNwZWN0UmF0aW8gPSAoZG91YmxlKWJvdHRvbUxlZnRQb3NpdGlvbmVkUGl4ZWxSZWN0LnBpeGVsUmVjdC53aWR0aCAvIChkb3VibGUpYm90dG9tTGVmdFBvc2l0aW9uZWRQaXhlbFJlY3QucGl4ZWxSZWN0LmhlaWdodDsKCX0KCXJldHVybiByZWxhdGlvbmFsUmVjdDsKfQoKCiNpZiBUQVJHRVRfT1NfV0lOCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmluaXRHZGlwbHVzKCkgewoJR2RpcGx1czo6R2RpcGx1c1N0YXJ0dXBJbnB1dCBnZGlwbHVzU3RhcnR1cElucHV0OwoJR2RpcGx1c1N0YXJ0dXAoJmdkaXBsdXNUb2tlbiwgJmdkaXBsdXNTdGFydHVwSW5wdXQsIE5VTEwpOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6dGVybWluYXRlR2RpcGx1cygpIHsKCUdkaXBsdXM6OkdkaXBsdXNTaHV0ZG93bihnZGlwbHVzVG9rZW4pOwp9CgoKYm9vbCBWaXN1YWxHcmFwaGljczo6Z2V0R2RpcGx1c0VuY29kZXJDbHNpZChjb25zdCBXQ0hBUiogZm9ybWF0LCBDTFNJRCogcENsc2lkKSB7Cglib29sIHN1Y2Nlc3MgPSBmYWxzZTsKCQoJVUlOVCAgbnVtID0gMDsKCVVJTlQgIHNpemUgPSAwOwoJCglHZGlwbHVzOjpJbWFnZUNvZGVjSW5mbyogcEltYWdlQ29kZWNJbmZvID0gTlVMTDsKCQoJR2RpcGx1czo6R2V0SW1hZ2VFbmNvZGVyc1NpemUoJm51bSwgJnNpemUpOwoJaWYgKHNpemUgPT0gMCkKCQlyZXR1cm4gc3VjY2VzczsKCQoJcEltYWdlQ29kZWNJbmZvID0gKEdkaXBsdXM6OkltYWdlQ29kZWNJbmZvKikobWFsbG9jKHNpemUpKTsKCWlmIChwSW1hZ2VDb2RlY0luZm8gPT0gTlVMTCkKCQlyZXR1cm4gc3VjY2VzczsKCQoJR2V0SW1hZ2VFbmNvZGVycyhudW0sIHNpemUsIHBJbWFnZUNvZGVjSW5mbyk7CgkKCWZvciAoVUlOVCBqID0gMDsgaiA8IG51bTsgKytqKSB7CgkJaWYgKHdjc2NtcChwSW1hZ2VDb2RlY0luZm9bal0uTWltZVR5cGUsIGZvcm1hdCkgPT0gMCApIHsKCQkJKnBDbHNpZCA9IHBJbWFnZUNvZGVjSW5mb1tqXS5DbHNpZDsKCQkJZnJlZShwSW1hZ2VDb2RlY0luZm8pOwoJCQlyZXR1cm4gdHJ1ZTsgIC8vIHN1Y2Nlc3MKCQl9Cgl9CgkKCWZyZWUocEltYWdlQ29kZWNJbmZvKTsKCXJldHVybiBzdWNjZXNzOyAvLyBmYWlsdXJlCn0KCiNlbmRpZgoKCmJvb2wgVmlzdWFsR3JhcGhpY3M6OnNldHVwQ29udGV4dCgpIHsKCVZpc3VhbEdyYXBoaWNzQ29yZSogdGhlVmlzdWFsR3JhcGhpY3NDb3JlID0gVmlzdWFsR3JhcGhpY3NDb3JlOjpnZXRJbnN0YW5jZSgpOwoJYm9vbCBzdWNjZXNzID0gdGhlVmlzdWFsR3JhcGhpY3NDb3JlLT5zZXR1cENvbnRleHQoKTsKCXJldHVybiBzdWNjZXNzOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6ZGlzcG9zZUNvbnRleHQoKSB7CglWaXN1YWxHcmFwaGljc0NvcmUqIHRoZVZpc3VhbEdyYXBoaWNzQ29yZTsKCXRoZVZpc3VhbEdyYXBoaWNzQ29yZSA9IFZpc3VhbEdyYXBoaWNzQ29yZTo6Z2V0SW5zdGFuY2UoKTsKI2lmIFRBUkdFVF9PU19NQUMKCXRoZVZpc3VhbEdyYXBoaWNzQ29yZS0+Y2xlYW51cEFHTCgpOwojZW5kaWYKI2lmIFRBUkdFVF9PU19XSU4KCXRoZVZpc3VhbEdyYXBoaWNzQ29yZS0+Y2xlYW5VcFdHTCgpOwoJdGhpcy0+a2lsbEZvbnQoKTsKI2VuZGlmCn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpzZXRDYW52YXNWaWV3cG9ydCgpIHsKCVZpc3VhbEdyYXBoaWNzQ29yZSogdGhlVmlzdWFsR3JhcGhpY3NDb3JlID0gVmlzdWFsR3JhcGhpY3NDb3JlOjpnZXRJbnN0YW5jZSgpOwoJdGhlVmlzdWFsR3JhcGhpY3NDb3JlLT5zZXRWaWV3cG9ydCh0aGlzLT5jYW52YXNSZWN0LCB0aGlzLT5pc1NldFVwT25GdWxsc2NyZWVuKTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OnNldFN1cmZhY2VWaWV3cG9ydCgpIHsKCVZpc3VhbEdyYXBoaWNzQ29yZSogdGhlVmlzdWFsR3JhcGhpY3NDb3JlID0gVmlzdWFsR3JhcGhpY3NDb3JlOjpnZXRJbnN0YW5jZSgpOwoJdGhlVmlzdWFsR3JhcGhpY3NDb3JlLT5zZXRWaWV3cG9ydCh0aGlzLT5zdXJmYWNlUmVjdCwgdGhpcy0+aXNTZXRVcE9uRnVsbHNjcmVlbik7Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpzZXRPcnRob2dyYXBoaWNQcm9qZWN0aW9uKGRvdWJsZSBtYXhMZWZ0Q29vcmQsIGRvdWJsZSBtYXhSaWdodENvb3JkLCBkb3VibGUgbWF4Qm90dG9tQ29vcmQsIGRvdWJsZSBtYXhUb3BDb29yZCwgZG91YmxlIG1heE5lYXJQb3MsIGRvdWJsZSBtYXhGYXJQb3MsIGRvdWJsZSB6b29tRmFjdG9yKSB7CiAgICBnbE1hdHJpeE1vZGUoR0xfUFJPSkVDVElPTik7CiAgICBnbExvYWRJZGVudGl0eSgpOwoJCglnbE9ydGhvKG1heExlZnRDb29yZCAqIHpvb21GYWN0b3IsIG1heFJpZ2h0Q29vcmQgKiB6b29tRmFjdG9yLCBtYXhCb3R0b21Db29yZCAqIHpvb21GYWN0b3IsIG1heFRvcENvb3JkICogem9vbUZhY3RvciwgbWF4TmVhclBvcywgbWF4RmFyUG9zKTsKCQoJZ2xNYXRyaXhNb2RlKEdMX01PREVMVklFVyk7Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpzZXRQZXJzcGVjdGl2ZVByb2plY3Rpb24oZG91YmxlIG1heExlZnRDb29yZCwgZG91YmxlIG1heFJpZ2h0Q29vcmQsIGRvdWJsZSBtYXhCb3R0b21Db29yZCwgZG91YmxlIG1heFRvcENvb3JkLCBkb3VibGUgbWF4TmVhclBvcywgZG91YmxlIG1heEZhclBvcywgZG91YmxlIHpvb21GYWN0b3IpIHsKCWdsTWF0cml4TW9kZShHTF9QUk9KRUNUSU9OKTsKICAgIGdsTG9hZElkZW50aXR5KCk7CgkKCWdsRnJ1c3R1bShtYXhMZWZ0Q29vcmQgKiB6b29tRmFjdG9yLCBtYXhSaWdodENvb3JkICogem9vbUZhY3RvciwgbWF4Qm90dG9tQ29vcmQgKiB6b29tRmFjdG9yLCBtYXhUb3BDb29yZCAqIHpvb21GYWN0b3IsIG1heE5lYXJQb3MsIG1heEZhclBvcyk7CgkKCWdsTWF0cml4TW9kZShHTF9NT0RFTFZJRVcpOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6bG9hZE1vZGVsVmlld0lkZW50aXR5TWF0cml4KCkgewoJZ2xMb2FkSWRlbnRpdHkoKTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6Omxvb2tBdChQb2ludDNEIGV5ZSwgUG9pbnQzRCBjZW50ZXIsIFZlY3RvciB1cCkgewoJZ2x1TG9va0F0KGV5ZS54LCBleWUueSwgZXllLnosIGNlbnRlci54LCBjZW50ZXIueSwgY2VudGVyLnosIHVwLngsIHVwLnksIHVwLnopOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6c2V0Q2FudmFzQmFja2dyb3VuZENvbG9yKGNvbnN0IFJHQkFDb2xvciYgYUNvbG9yVmFsKSB7Cgl0aGlzLT5jYW52YXNCYWNrZ3JvdW5kQ29sb3IuciA9IGFDb2xvclZhbC5yOwoJdGhpcy0+Y2FudmFzQmFja2dyb3VuZENvbG9yLmcgPSBhQ29sb3JWYWwuZzsKCXRoaXMtPmNhbnZhc0JhY2tncm91bmRDb2xvci5iID0gYUNvbG9yVmFsLmI7Cgl0aGlzLT5jYW52YXNCYWNrZ3JvdW5kQ29sb3IuYSA9IGFDb2xvclZhbC5hOwp9CgoKUkdCQUNvbG9yIFZpc3VhbEdyYXBoaWNzOjpnZXRCYWNrZ3JvdW5kQ29sb3IoKSB7CglyZXR1cm4gdGhpcy0+Y2FudmFzQmFja2dyb3VuZENvbG9yOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6Y2xlYXJDYW52YXNCYWNrZ3JvdW5kKCkgewoJZ2xDbGVhckNvbG9yKChHTGNsYW1wZiljYW52YXNCYWNrZ3JvdW5kQ29sb3IuciwgKEdMY2xhbXBmKWNhbnZhc0JhY2tncm91bmRDb2xvci5nLCAoR0xjbGFtcGYpY2FudmFzQmFja2dyb3VuZENvbG9yLmIsIChHTGNsYW1wZiljYW52YXNCYWNrZ3JvdW5kQ29sb3IuYSk7CiAgICBnbENsZWFyKEdMX0NPTE9SX0JVRkZFUl9CSVQgfCBHTF9ERVBUSF9CVUZGRVJfQklUKTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmNsZWFyU3VyZmFjZUJhY2tncm91bmQoKSB7CglnbENsZWFyQ29sb3IoKEdMY2xhbXBmKXN1cmZhY2VCYWNrZ3JvdW5kQ29sb3IuciwgKEdMY2xhbXBmKXN1cmZhY2VCYWNrZ3JvdW5kQ29sb3IuZywgKEdMY2xhbXBmKXN1cmZhY2VCYWNrZ3JvdW5kQ29sb3IuYiwgKEdMY2xhbXBmKXN1cmZhY2VCYWNrZ3JvdW5kQ29sb3IuYSk7CiAgICBnbENsZWFyKEdMX0NPTE9SX0JVRkZFUl9CSVQgfCBHTF9ERVBUSF9CVUZGRVJfQklUKTsKfQoKCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpzZXRQaXhlbFN0b3JhZ2VQYXJhbXMoKSB7CglnbFBpeGVsU3RvcmVpKEdMX1BBQ0tfUk9XX0xFTkdUSCwgMCk7CglnbFBpeGVsU3RvcmVpKEdMX1BBQ0tfQUxJR05NRU5ULCA0KTsKCWdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIDApOwoJZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQUxJR05NRU5ULCA0KTsKI2lmIFRBUkdFVF9PU19NQUMKCWdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0NMSUVOVF9TVE9SQUdFX0FQUExFLCBHTF9GQUxTRSk7CiNlbmRpZgp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6cmVzZXRNb2RlbFZpZXdNYXRyaXgoKSB7CglnbE1hdHJpeE1vZGUoR0xfTU9ERUxWSUVXKTsKICAgIGdsTG9hZElkZW50aXR5KCk7CglnbFRyYW5zbGF0ZWQoMC4wLCAwLjAsIDAuMCk7Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjp0cmFuc2xhdGVNYXRyaXgoZG91YmxlIHhOdW0sIGRvdWJsZSB5TnVtLCBkb3VibGUgek51bSkgewoJZ2xUcmFuc2xhdGVkKHhOdW0sIHlOdW0sIHpOdW0pOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6cm90YXRlTWF0cml4KGRvdWJsZSBhbmdsZSwgZG91YmxlIHhBbW91bnQsIGRvdWJsZSB5QW1vdW50LCBkb3VibGUgekFtb3VudCkgewoJZ2xSb3RhdGVkKGFuZ2xlLCB4QW1vdW50LCB5QW1vdW50LCB6QW1vdW50KTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OnNjYWxlTWF0cml4KGRvdWJsZSB4RmFjdG9yLCBkb3VibGUgeUZhY3RvciwgZG91YmxlIHpGYWN0b3IpIHsKCWdsU2NhbGVkKHhGYWN0b3IsIHlGYWN0b3IsIHpGYWN0b3IpOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6ZW5hYmxlVGV4dHVyaW5nKGJvb2wgdXNlUmVjdEV4dGVuc2lvbikgewoJaWYgKHVzZVJlY3RFeHRlbnNpb24gPT0gZmFsc2UpIHsKICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKICAgIH0gZWxzZSB7CiNpZiBUQVJHRVRfT1NfTUFDCiAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV9SRUNUQU5HTEVfRVhUKTsKI2VuZGlmCgl9Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpkaXNhYmxlVGV4dHVyaW5nKGJvb2wgdXNlUmVjdEV4dGVuc2lvbikgewogICAgaWYgKHVzZVJlY3RFeHRlbnNpb24gPT0gZmFsc2UpIHsKICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV8yRCk7Cgl9IGVsc2UgewojaWYgVEFSR0VUX09TX01BQwogICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFX1JFQ1RBTkdMRV9FWFQpOwojZW5kaWYKICAgIH0KfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmJpbmRUZXh0dXJlKHVpbnQzMiB0ZXh0dXJlTmFtZSwgYm9vbCB1c2VSZWN0RXh0ZW5zaW9uKSB7CglpZiAodXNlUmVjdEV4dGVuc2lvbiA9PSBmYWxzZSkgewoJCWdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgKEdMdWludCl0ZXh0dXJlTmFtZSk7Cgl9IGVsc2UgewojaWYgVEFSR0VUX09TX01BQwoJCWdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV9SRUNUQU5HTEVfRVhULCAoR0x1aW50KXRleHR1cmVOYW1lKTsKI2VuZGlmCgl9Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpnZXRQaXhlbHNPZkN1cnJlbnRUZXh0dXJlKGJvb2wgdXNlUmVjdEV4dGVuc2lvbiwgdWludDE2IGZvcm1hdCwgdWludDE2IHR5cGUsIHVpbnQzMioqIGJ1ZmZlcikgewoJaWYgKHVzZVJlY3RFeHRlbnNpb24gPT0gZmFsc2UpIHsKCQlnbEdldFRleEltYWdlKEdMX1RFWFRVUkVfMkQsIDAsIGZvcm1hdCwgdHlwZSwgKmJ1ZmZlcik7Cgl9IGVsc2UgewojaWYgVEFSR0VUX09TX01BQwoJCWdsR2V0VGV4SW1hZ2UoR0xfVEVYVFVSRV9SRUNUQU5HTEVfRVhULCAwLCBmb3JtYXQsIHR5cGUsICpidWZmZXIpOwojZW5kaWYKCX0KfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmVuYWJsZUFscGhhQmxlbmRpbmcoKSB7CiAgICBnbEVuYWJsZShHTF9CTEVORCk7CiAgICBnbEJsZW5kRnVuYyhHTF9TUkNfQUxQSEEsIEdMX09ORV9NSU5VU19TUkNfQUxQSEEpOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6ZGlzYWJsZUJsZW5kaW5nKCkgewoJZ2xEaXNhYmxlKEdMX0JMRU5EKTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OnNldENvbG9yKGNvbnN0IFJHQkFDb2xvciYgdGhlQ29sb3IpIHsKCWdsQ29sb3I0ZCh0aGVDb2xvci5yLCB0aGVDb2xvci5nLCB0aGVDb2xvci5iLCB0aGVDb2xvci5hKTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OnNldExpbmVXaWR0aChkb3VibGUgd2lkdGgpIHsKCWdsTGluZVdpZHRoKHN0YXRpY19jYXN0PEdMZmxvYXQ+KHdpZHRoKSk7Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjplbmFibGVEZXB0aFRlc3QoKSB7CglnbEVuYWJsZShHTF9ERVBUSF9URVNUKTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmRpc2FibGVEZXB0aFRlc3QoKSB7CglnbERpc2FibGUoR0xfREVQVEhfVEVTVCk7Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjplbmFibGVDdWxsRmFjZSgpIHsKCWdsRW5hYmxlKEdMX0NVTExfRkFDRSk7Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpkaXNhYmxlQ3VsbEZhY2UoKSB7CglnbERpc2FibGUoR0xfQ1VMTF9GQUNFKTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmN1bGxGYWNlRnJvbnQoKSB7CglnbEN1bGxGYWNlKEdMX0ZST05UKTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmN1bGxGYWNlQmFjaygpIHsKCWdsQ3VsbEZhY2UoR0xfQkFDSyk7Cn0KCgp1aW50OCBWaXN1YWxHcmFwaGljczo6Z2V0T3BlbkdMRXJyb3IgKGNoYXIqIG91dEVycm9yU3RyaW5nKSB7CiAgICBHTGVudW0gZ2xFcnJvck51bTsKICAgIGNvbnN0IEdMdWJ5dGUgKmdsRXJyb3JTdHJpbmc7ICAKCQogICAgZ2xFcnJvck51bSA9IGdsR2V0RXJyb3IoKTsKICAgIGlmIChnbEVycm9yTnVtICE9IEdMX05PX0VSUk9SKSB7CiAgICAgICAgZ2xFcnJvclN0cmluZyA9IGdsdUVycm9yU3RyaW5nKGdsRXJyb3JOdW0pOwogICAgICAgIHN0cmNweShvdXRFcnJvclN0cmluZywgKGNoYXIqKWdsRXJyb3JTdHJpbmcpOwogICAgICAgIHJldHVybiAxOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KfQoKCnVpbnQxNiBWaXN1YWxHcmFwaGljczo6c2V0Q3VycmVudENvbnRleHQoKSB7CglWaXN1YWxHcmFwaGljc0NvcmUqIHRoZVZpc3VhbEdyYXBoaWNzQ29yZTsKCXRoZVZpc3VhbEdyYXBoaWNzQ29yZSA9IFZpc3VhbEdyYXBoaWNzQ29yZTo6Z2V0SW5zdGFuY2UoKTsKCXJldHVybiB0aGVWaXN1YWxHcmFwaGljc0NvcmUtPnNldEN1cnJlbnRDb250ZXh0KCk7Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpmaW5pc2hHTERyYXdpbmcoKSB7CglWaXN1YWxHcmFwaGljc0NvcmUqIHRoZVZpc3VhbEdyYXBoaWNzQ29yZSA9IFZpc3VhbEdyYXBoaWNzQ29yZTo6Z2V0SW5zdGFuY2UoKTsKCXRoZVZpc3VhbEdyYXBoaWNzQ29yZS0+ZmluaXNoR0xEcmF3aW5nKCk7Cn0KCgppbnQgVmlzdWFsR3JhcGhpY3M6OmdldEN1cnJlbnRDb2xvckJ1ZmZlckZvclBpeGVsUmVhZGluZ09wZXJhdGlvbnMoKSB7CglHTGludCBjdXJyUmVhZEJ1ZmZlcjsKCWdsR2V0SW50ZWdlcnYoR0xfUkVBRF9CVUZGRVIsICZjdXJyUmVhZEJ1ZmZlcik7CglyZXR1cm4gY3VyclJlYWRCdWZmZXI7Cn0KCgppbnQgVmlzdWFsR3JhcGhpY3M6OmdldEN1cnJlbnRDb2xvckJ1ZmZlckZvclBpeGVsRHJhd2luZ09wZXJhdGlvbnMoKSB7CglHTGludCBjdXJyRHJhd0J1ZmZlcjsKCWdsR2V0SW50ZWdlcnYoR0xfRFJBV19CVUZGRVIsICZjdXJyRHJhd0J1ZmZlcik7CglyZXR1cm4gY3VyckRyYXdCdWZmZXI7Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpzZXRDb2xvckJ1ZmZlckZvclBpeGVsUmVhZGluZ09wZXJhdGlvbnMoaW50IGNvbG9yQnVmZmVyKSB7CglnbFJlYWRCdWZmZXIoY29sb3JCdWZmZXIpOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6c2V0Q29sb3JCdWZmZXJGb3JQaXhlbERyYXdpbmdPcGVyYXRpb25zKGludCBjb2xvckJ1ZmZlcikgewoJZ2xEcmF3QnVmZmVyKGNvbG9yQnVmZmVyKTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmRyYXdUZXh0dXJlKHVpbnQzMiB0ZXh0dXJlTnVtYmVyLCBjb25zdCBWZXJ0ZXhDaGFpbiogY29uc3QgdmVydGV4Q2hhaW4sIGJvb2wgY2FuVXNlUmVjdEV4dGVuc2lvbiwgQmxlbmRNb2RlIGFCbGVuZE1vZGUsIGJvb2wgZGVidWcpIHsKICAgIAoJaWYgKGFCbGVuZE1vZGUgPT0ga0JsZW5kKSB7CgkJZ2xFbmFibGUoR0xfQkxFTkQpOwoJCWdsQmxlbmRGdW5jKEdMX09ORSwgR0xfT05FX01JTlVTX1NSQ19BTFBIQSk7Cgl9CgkKCWlmIChjYW5Vc2VSZWN0RXh0ZW5zaW9uID09IGZhbHNlKSB7CiAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7CiAgICB9IGVsc2UgewojaWYgVEFSR0VUX09TX01BQwogICAgICAgIGdsRW5hYmxlIChHTF9URVhUVVJFX1JFQ1RBTkdMRV9FWFQpOwojZW5kaWYKCX0KCQoJaWYgKGNhblVzZVJlY3RFeHRlbnNpb24gPT0gZmFsc2UpIHsKCQlnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX0NMQU1QKTsKCQlnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX0NMQU1QKTsKICAgIH0gZWxzZSB7CiNpZiBUQVJHRVRfT1NfTUFDCgkJZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfUkVDVEFOR0xFX0VYVCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX0NMQU1QKTsKCQlnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV9SRUNUQU5HTEVfRVhULCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfQ0xBTVApOwojZW5kaWYKCX0KCQoJaWYgKGNhblVzZVJlY3RFeHRlbnNpb24gPT0gZmFsc2UpIHsKICAgICAgICBnbEJpbmRUZXh0dXJlIChHTF9URVhUVVJFXzJELCAoR0x1aW50KXRleHR1cmVOdW1iZXIpOwogICAgfSBlbHNlIHsKI2lmIFRBUkdFVF9PU19NQUMKICAgICAgICBnbEJpbmRUZXh0dXJlIChHTF9URVhUVVJFX1JFQ1RBTkdMRV9FWFQsIChHTHVpbnQpdGV4dHVyZU51bWJlcik7CiNlbmRpZgogICAgfQogICAgCglpZiAoYUJsZW5kTW9kZSA9PSBrQmxlbmQpIHsKCQlnbFRleEVudmYoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX01PRFVMQVRFKTsKCX0KCQoJZ2xCZWdpbihHTF9QT0xZR09OKTsKCQoJZm9yIChDb25zdFZlcnRleENoYWluQ29uc3RJdGVyYXRvciBpdCA9IHZlcnRleENoYWluLT5iZWdpbigpOyBpdCAhPSB2ZXJ0ZXhDaGFpbi0+ZW5kKCk7IGl0KyspIHsKCQlnbENvbG9yNGQoKCppdCktPnZlcnRleENvbG9yLnIsICgqaXQpLT52ZXJ0ZXhDb2xvci5nLCAoKml0KS0+dmVydGV4Q29sb3IuYiwgKCppdCktPnZlcnRleENvbG9yLmEpOwoJCWlmIChkZWJ1ZyA9PSB0cnVlKSB7CgkJCWNoYXIgbG9nU3RyWzEyOF07CgkJCXNwcmludGYobG9nU3RyLCAicjogJWYsIGc6ICVmLCBiOiAlZiwgYTogJWZcbiIsICgqaXQpLT52ZXJ0ZXhDb2xvci5yLCAoKml0KS0+dmVydGV4Q29sb3IuZywgKCppdCktPnZlcnRleENvbG9yLmIsICgqaXQpLT52ZXJ0ZXhDb2xvci5hKTsKCQkJd3JpdGVMb2cobG9nU3RyKTsKCQl9CgkJZ2xUZXhDb29yZDJkKCgqaXQpLT50ZXhDb29yZFBvc2l0aW9uLmNvb3JkLnMsICgqaXQpLT50ZXhDb29yZFBvc2l0aW9uLmNvb3JkLnQpOwoJCWdsVmVydGV4M2QoKCppdCktPnZlcnRleFBvc2l0aW9uLmNvb3JkLngsICgqaXQpLT52ZXJ0ZXhQb3NpdGlvbi5jb29yZC55LCAoKml0KS0+dmVydGV4UG9zaXRpb24uY29vcmQueik7CgkJaWYgKGRlYnVnID09IHRydWUpIHsKCQkJY2hhciBsb2dTdHJbMTI4XTsKCQkJc3ByaW50Zihsb2dTdHIsICJ4OiAlZiwgeTogJWYsIHo6ICVmXG4iLCAoKml0KS0+dmVydGV4UG9zaXRpb24uY29vcmQueCwgKCppdCktPnZlcnRleFBvc2l0aW9uLmNvb3JkLnksICgqaXQpLT52ZXJ0ZXhQb3NpdGlvbi5jb29yZC56KTsKCQkJd3JpdGVMb2cobG9nU3RyKTsKCQl9Cgl9CgkKICAgIGdsRW5kKCk7CgkKICAgIGlmIChjYW5Vc2VSZWN0RXh0ZW5zaW9uID09IGZhbHNlKSB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgfSBlbHNlIHsKI2lmIFRBUkdFVF9PU19NQUMKICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV9SRUNUQU5HTEVfRVhUKTsKI2VuZGlmCiAgICB9CgkKCWlmIChhQmxlbmRNb2RlID09IGtCbGVuZCkgewoJCWdsRGlzYWJsZShHTF9CTEVORCk7Cgl9CgkKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmRyYXdWZXJ0ZXhDaGFpbihjb25zdCBWZXJ0ZXhDaGFpbiYgdmVydGV4Q2hhaW4sIGludCBkcmF3TW9kZSwgQmxlbmRNb2RlIGFCbGVuZE1vZGUpIHsKCWlmIChhQmxlbmRNb2RlID09IGtCbGVuZCkgewoJCWdsRW5hYmxlKEdMX0JMRU5EKTsKCQlnbEJsZW5kRnVuYyhHTF9PTkUsIEdMX09ORV9NSU5VU19TUkNfQUxQSEEpOwoJfQoJZ2xCZWdpbihkcmF3TW9kZSk7Cglmb3IgKENvbnN0VmVydGV4Q2hhaW5Db25zdEl0ZXJhdG9yIGl0ID0gdmVydGV4Q2hhaW4uYmVnaW4oKTsgaXQgIT0gdmVydGV4Q2hhaW4uZW5kKCk7IGl0KyspIHsKCQlpZiAoKCppdCktPmNvbG9ySGFzQmVlblNldCgpID09IHRydWUpIHsKCQkJZ2xDb2xvcjRkKCgqaXQpLT52ZXJ0ZXhDb2xvci5yLCAoKml0KS0+dmVydGV4Q29sb3IuZywgKCppdCktPnZlcnRleENvbG9yLmIsICgqaXQpLT52ZXJ0ZXhDb2xvci5hKTsKCQl9CgkJZ2xWZXJ0ZXgzZCgoKml0KS0+dmVydGV4UG9zaXRpb24uY29vcmQueCwgKCppdCktPnZlcnRleFBvc2l0aW9uLmNvb3JkLnksICgqaXQpLT52ZXJ0ZXhQb3NpdGlvbi5jb29yZC56KTsKCQkvL2NoYXIgY29vcmRMb2dTdHJbMTI4XTsKCQkvL3NwcmludGYoY29vcmRMb2dTdHIsICJ4OiAlZiwgeTogJWYsIHo6ICVmXG4iLCAoKml0KS0+dmVydGV4UG9zaXRpb24uY29vcmQueCwgKCppdCktPnZlcnRleFBvc2l0aW9uLmNvb3JkLnksICgqaXQpLT52ZXJ0ZXhQb3NpdGlvbi5jb29yZC56KTsKCQkvL3dyaXRlTG9nKGNvb3JkTG9nU3RyKTsKCX0KICAgIGdsRW5kKCk7CglpZiAoYUJsZW5kTW9kZSA9PSBrQmxlbmQpIHsKCQlnbERpc2FibGUoR0xfQkxFTkQpOwoJfQp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6ZHJhd0RlYnVnVmVydGV4Q2hhaW4oY29uc3QgVmVydGV4Q2hhaW4mIHZlcnRleENoYWluLCBjb25zdCBWaXN1YWxDYW1lcmEmIGFDYW1lcmEpIHsKCWdsQ29sb3IzZCgxLjAsIDAuMCwgMC4wKTsKCWdsTGluZVdpZHRoKDMuMGYpOwoJZ2xCZWdpbiAoR0xfTElORV9MT09QKTsKCWZvciAoQ29uc3RWZXJ0ZXhDaGFpbkNvbnN0SXRlcmF0b3IgaXQgPSB2ZXJ0ZXhDaGFpbi5iZWdpbigpOyBpdCAhPSB2ZXJ0ZXhDaGFpbi5lbmQoKTsgaXQrKykgewoJCWdsVmVydGV4M2QoKCppdCktPnZlcnRleFBvc2l0aW9uLmNvb3JkLngsICgqaXQpLT52ZXJ0ZXhQb3NpdGlvbi5jb29yZC55LCAoKml0KS0+dmVydGV4UG9zaXRpb24uY29vcmQueik7Cgl9CglnbEVuZCgpOwoJCglDb29yZCBjb29yZDsKCWdsVHJhbnNsYXRlZCgwLjAsIDAuMCwgMC4wKTsKCWdsQ29sb3IzZCgxLjAsIDEuMCwgMC4wKTsKCWNoYXIgcG9zU3RyWzY0XTsKCWZvciAoQ29uc3RWZXJ0ZXhDaGFpbkNvbnN0SXRlcmF0b3IgaXQgPSB2ZXJ0ZXhDaGFpbi5iZWdpbigpOyBpdCAhPSB2ZXJ0ZXhDaGFpbi5lbmQoKTsgaXQrKykgewoJCXNwcmludGYocG9zU3RyLCAidGV4Lng6JS4yZiwgdGV4Lnk6JS4yZiIsICgqaXQpLT50ZXhDb29yZFBvc2l0aW9uLmNvb3JkLnMsICgqaXQpLT50ZXhDb29yZFBvc2l0aW9uLmNvb3JkLnQpOwoJCWNvb3JkLnggPSAoKml0KS0+dmVydGV4UG9zaXRpb24uY29vcmQueDsKCQljb29yZC55ID0gKCppdCktPnZlcnRleFBvc2l0aW9uLmNvb3JkLnkgKyB0aGlzLT55UGl4ZWxUb0Nvb3JkKDEzLCBhQ2FtZXJhKTs7CgkJY29vcmQueiA9ICgqaXQpLT52ZXJ0ZXhQb3NpdGlvbi5jb29yZC56OwoJCXNob3dQcm9jZXNzSW5mb1Jvdyhjb29yZCwgcG9zU3RyKTsKCQlzcHJpbnRmKHBvc1N0ciwgIng6JS4yZiwgeTolLjJmLCB6OiUuMmYiLCAoKml0KS0+dmVydGV4UG9zaXRpb24uY29vcmQueCwgKCppdCktPnZlcnRleFBvc2l0aW9uLmNvb3JkLnksICgqaXQpLT52ZXJ0ZXhQb3NpdGlvbi5jb29yZC56KTsKCQljb29yZC55ID0gKCppdCktPnZlcnRleFBvc2l0aW9uLmNvb3JkLnk7CgkJc2hvd1Byb2Nlc3NJbmZvUm93KGNvb3JkLCBwb3NTdHIpOwoJfQp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6ZHJhd1BpeGVscyhQaXhlbENvbG9yKiogcGl4ZWxEYXRhLCBkb3VibGUgeENvb3JkLCBkb3VibGUgeUNvb3JkLCB1aW50MzIgd2lkdGgsIHVpbnQzMiBoZWlnaHQsIHVpbnQxNiBmb3JtYXQsIHVpbnQxNiBkYXRhVHlwZSwgY29uc3QgVmlzdWFsQ29udm9sdXRpb25GaWx0ZXIqIGNvbnN0IGFDb252b2x1dGlvbkZpbHRlcikgewoJCglib29sIHVzZUdMQ29udm9sdXRpb25GaWx0ZXIgPSBmYWxzZTsKCUdMZmxvYXQqIGtlcm5lbCA9IE5VTEw7CgkKI2lmIFRBUkdFVF9PU19XSU4KCS8vIERlY2xhcmUgZnVuY3Rpb24gcG9pbnRlcnMKCVBGTkdMQ09OVk9MVVRJT05GSUxURVIyRFBST0MgZ2xDb252b2x1dGlvbkZpbHRlcjJEOwoJUEZOR0xDT05WT0xVVElPTlBBUkFNRVRFUklQUk9DIGdsQ29udm9sdXRpb25QYXJhbWV0ZXJpOwoJUEZOR0xDT05WT0xVVElPTlBBUkFNRVRFUkZWUFJPQyBnbENvbnZvbHV0aW9uUGFyYW1ldGVyZnY7CiNlbmRpZgoJCglpZiAoYUNvbnZvbHV0aW9uRmlsdGVyICE9IE5VTEwpIHsKI2lmIFRBUkdFVF9PU19XSU4KCQkvLyBPYnRhaW4gdGhlIGFkZHJlc3Mgb2YgdGhlIGV4dGVuc2lvbiBlbnRyeSBwb2ludHMKCQlnbENvbnZvbHV0aW9uRmlsdGVyMkQgPSAoUEZOR0xDT05WT0xVVElPTkZJTFRFUjJEUFJPQyl3Z2xHZXRQcm9jQWRkcmVzcygiZ2xDb252b2x1dGlvbkZpbHRlcjJEIik7IAoJCWdsQ29udm9sdXRpb25QYXJhbWV0ZXJpID0gKFBGTkdMQ09OVk9MVVRJT05QQVJBTUVURVJJUFJPQyl3Z2xHZXRQcm9jQWRkcmVzcygiZ2xDb252b2x1dGlvblBhcmFtZXRlcmkiKTsKCQlnbENvbnZvbHV0aW9uUGFyYW1ldGVyZnYgPSAoUEZOR0xDT05WT0xVVElPTlBBUkFNRVRFUkZWRVhUUFJPQyl3Z2xHZXRQcm9jQWRkcmVzcygiZ2xDb252b2x1dGlvblBhcmFtZXRlcmZ2Iik7CgkJaWYgKGdsQ29udm9sdXRpb25GaWx0ZXIyRCkgdXNlR0xDb252b2x1dGlvbkZpbHRlciA9IHRydWU7CiNlbmRpZgojaWYgVEFSR0VUX09TX01BQwoJCXVzZUdMQ29udm9sdXRpb25GaWx0ZXIgPSB0aGlzLT5jYXBhYmlsaXRpZXMuZkltYWdpbmc7CiNlbmRpZgoJfQoJCgkvL3VzZUdMQ29udm9sdXRpb25GaWx0ZXIgPSBmYWxzZTsgLy8gdGVzdAoJCglpZiAodXNlR0xDb252b2x1dGlvbkZpbHRlciA9PSBmYWxzZSAmJiBhQ29udm9sdXRpb25GaWx0ZXIgIT0gTlVMTCkgewoJCVBpeGVsQ29sb3IqIGZpbHRlcmVkUGl4ZWxzID0gTlVMTDsKCQlhQ29udm9sdXRpb25GaWx0ZXItPmFwcGx5VG9QaXhlbERhdGEoKnBpeGVsRGF0YSwgd2lkdGgsIGhlaWdodCwgZm9ybWF0LCBkYXRhVHlwZSwgJmZpbHRlcmVkUGl4ZWxzKTsKCQlmcmVlKCpwaXhlbERhdGEpOwoJCSpwaXhlbERhdGEgPSBmaWx0ZXJlZFBpeGVsczsKCX0KCQoJaWYgKHVzZUdMQ29udm9sdXRpb25GaWx0ZXIgPT0gdHJ1ZSkgewoJCWtlcm5lbCA9IChHTGZsb2F0KiltYWxsb2MoYUNvbnZvbHV0aW9uRmlsdGVyLT5nZXROdW1iZXJPZktlcm5lbFZhbHVlQ29sdW1ucygpICogYUNvbnZvbHV0aW9uRmlsdGVyLT5nZXROdW1iZXJPZktlcm5lbFZhbHVlUm93cygpICogc2l6ZW9mKEdMZmxvYXQpKTsKCQlhQ29udm9sdXRpb25GaWx0ZXItPmNvcHlLZXJuZWxWYWx1ZXMoa2VybmVsKTsKCQkKCQlHTGZsb2F0IGJvcmRlckNvbG9yWzRdOwoJCWJvcmRlckNvbG9yWzBdID0gMC4wZjsKCQlib3JkZXJDb2xvclsxXSA9IDAuMGY7CgkJYm9yZGVyQ29sb3JbMl0gPSAwLjBmOwoJCWJvcmRlckNvbG9yWzNdID0gMC4wZjsKCQkKI2lmIFRBUkdFVF9PU19XSU4KCQkvLyBDYWxsIHRoZSBmdW5jdGlvbiB2aWEgZnVuY3Rpb24gcG9pbnRlcgoJCSgqZ2xDb252b2x1dGlvbkZpbHRlcjJEKShHTF9DT05WT0xVVElPTl8yRCwgR0xfTFVNSU5BTkNFLCBhQ29udm9sdXRpb25GaWx0ZXItPmdldE51bWJlck9mS2VybmVsVmFsdWVDb2x1bW5zKCksIGFDb252b2x1dGlvbkZpbHRlci0+Z2V0TnVtYmVyT2ZLZXJuZWxWYWx1ZVJvd3MoKSwgR0xfTFVNSU5BTkNFLCBHTF9GTE9BVCwga2VybmVsKTsKCQkoKmdsQ29udm9sdXRpb25QYXJhbWV0ZXJpKSAoR0xfQ09OVk9MVVRJT05fMkQsIEdMX0NPTlZPTFVUSU9OX0JPUkRFUl9NT0RFLCBHTF9DT05TVEFOVF9CT1JERVIpOwoJCSgqZ2xDb252b2x1dGlvblBhcmFtZXRlcmZ2KSAoR0xfQ09OVk9MVVRJT05fMkQsIEdMX0NPTlZPTFVUSU9OX0JPUkRFUl9DT0xPUiwgYm9yZGVyQ29sb3IpOwojZWxzZQoJCWdsQ29udm9sdXRpb25GaWx0ZXIyRChHTF9DT05WT0xVVElPTl8yRCwgR0xfTFVNSU5BTkNFLCBhQ29udm9sdXRpb25GaWx0ZXItPmdldE51bWJlck9mS2VybmVsVmFsdWVDb2x1bW5zKCksIGFDb252b2x1dGlvbkZpbHRlci0+Z2V0TnVtYmVyT2ZLZXJuZWxWYWx1ZVJvd3MoKSwgR0xfTFVNSU5BTkNFLCBHTF9GTE9BVCwga2VybmVsKTsKCQlnbENvbnZvbHV0aW9uUGFyYW1ldGVyaShHTF9DT05WT0xVVElPTl8yRCwgR0xfQ09OVk9MVVRJT05fQk9SREVSX01PREUsIEdMX0NPTlNUQU5UX0JPUkRFUik7CgkJZ2xDb252b2x1dGlvblBhcmFtZXRlcmZ2KEdMX0NPTlZPTFVUSU9OXzJELCBHTF9DT05WT0xVVElPTl9CT1JERVJfQ09MT1IsIGJvcmRlckNvbG9yKTsKI2VuZGlmCgkJLy8gZ2xDb252b2x1dGlvblBhcmFtZXRlcmZ2KEdMX0NPTlZPTFVUSU9OXzJELCBHTF9DT05WT0xVVElPTl9GSUxURVJfU0NBTEUsIGZpbHRlclNjYWxlKTsKCQkKCQlnbEVuYWJsZShHTF9DT05WT0xVVElPTl8yRCk7CgkJCgkJZ2xQaXhlbFRyYW5zZmVyZihHTF9QT1NUX0NPTlZPTFVUSU9OX1JFRF9TQ0FMRSwgYUNvbnZvbHV0aW9uRmlsdGVyLT5nZXRQb3N0Q29udm9sdXRpb25TY2FsZUZhY3RvcigpKTsKCQlnbFBpeGVsVHJhbnNmZXJmKEdMX1BPU1RfQ09OVk9MVVRJT05fR1JFRU5fU0NBTEUsIGFDb252b2x1dGlvbkZpbHRlci0+Z2V0UG9zdENvbnZvbHV0aW9uU2NhbGVGYWN0b3IoKSk7CgkJZ2xQaXhlbFRyYW5zZmVyZihHTF9QT1NUX0NPTlZPTFVUSU9OX0JMVUVfU0NBTEUsIGFDb252b2x1dGlvbkZpbHRlci0+Z2V0UG9zdENvbnZvbHV0aW9uU2NhbGVGYWN0b3IoKSk7CgkJZ2xQaXhlbFRyYW5zZmVyZihHTF9QT1NUX0NPTlZPTFVUSU9OX0FMUEhBX1NDQUxFLCBhQ29udm9sdXRpb25GaWx0ZXItPmdldFBvc3RDb252b2x1dGlvblNjYWxlRmFjdG9yKCkpOwoJCQoJCWdsUGl4ZWxUcmFuc2ZlcmYoR0xfUE9TVF9DT05WT0xVVElPTl9SRURfQklBUywgYUNvbnZvbHV0aW9uRmlsdGVyLT5nZXRQb3N0Q29udm9sdXRpb25CaWFzKCkpOwoJCWdsUGl4ZWxUcmFuc2ZlcmYoR0xfUE9TVF9DT05WT0xVVElPTl9HUkVFTl9CSUFTLCBhQ29udm9sdXRpb25GaWx0ZXItPmdldFBvc3RDb252b2x1dGlvbkJpYXMoKSk7CgkJZ2xQaXhlbFRyYW5zZmVyZihHTF9QT1NUX0NPTlZPTFVUSU9OX0JMVUVfQklBUywgYUNvbnZvbHV0aW9uRmlsdGVyLT5nZXRQb3N0Q29udm9sdXRpb25CaWFzKCkpOwoJCWdsUGl4ZWxUcmFuc2ZlcmYoR0xfUE9TVF9DT05WT0xVVElPTl9BTFBIQV9CSUFTLCBhQ29udm9sdXRpb25GaWx0ZXItPmdldFBvc3RDb252b2x1dGlvbkJpYXMoKSk7CgkJCgl9CgkKCWdsUmFzdGVyUG9zMmQoeENvb3JkLCB5Q29vcmQpOwoJCgkvKgoJIFdoZW4gdGhlIEdMX0FSQl9pbWFnaW5nIGV4dGVuc2lvbiAgaXMgIHN1cHBvcnRlZCwgIHRoZXJlICBhcmUgIGRpc3RpbmN0CgkgcmFzdGVyICB0ZXh0dXJlICBjb29yZGluYXRlcyBmb3IgZWFjaCB0ZXh0dXJlIHVuaXQuIEVhY2ggdGV4dHVyZSB1bml0J3MKCSBjdXJyZW50IHJhc3RlciB0ZXh0dXJlIGNvb3JkaW5hdGVzIGFyZSB1cGRhdGVkIGJ5IGdsUmFzdGVyUG9zLgoJICovCgkKCXRoaXMtPnNldFBpeGVsU3RvcmFnZVBhcmFtcygpOwoJCglnbERyYXdQaXhlbHMod2lkdGgsIGhlaWdodCwgZm9ybWF0LCBkYXRhVHlwZSwgKnBpeGVsRGF0YSk7CgkKCWlmICh1c2VHTENvbnZvbHV0aW9uRmlsdGVyID09IHRydWUpIHsKCQlnbERpc2FibGUoR0xfQ09OVk9MVVRJT05fMkQpOwoJCWZyZWUoa2VybmVsKTsKCX0KCQp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6cmVzYW1wbGUodWludDE2IGZvcm1hdEluLCB1aW50MzIgd2lkdGhJbiwgdWludDMyIGhlaWdodEluLCB1aW50MTYgZGF0YVR5cGVJbiwgUGl4ZWxDb2xvciogcGl4ZWxEYXRhSW4sIHVpbnQzMiB3aWR0aE91dCwgdWludDMyIGhlaWdodE91dCwgdWludDE2IGRhdGFUeXBlT3V0LCBQaXhlbENvbG9yKiogcGl4ZWxEYXRhT3V0KSB7CgkKCXRoaXMtPnNldFBpeGVsU3RvcmFnZVBhcmFtcygpOwoJZ2x1U2NhbGVJbWFnZSgoR0xlbnVtKWZvcm1hdEluLCAoR0xpbnQpd2lkdGhJbiwgKEdMaW50KWhlaWdodEluLCAoR0xlbnVtKWRhdGFUeXBlSW4sICh2b2lkKilwaXhlbERhdGFJbiwgKEdMaW50KXdpZHRoT3V0LCAoR0xpbnQpaGVpZ2h0T3V0LCAoR0xlbnVtKWRhdGFUeXBlT3V0LCAodm9pZCopKCpwaXhlbERhdGFPdXQpKTsKCXJldHVybjsKCQoJLyoKCSB1aW50MzIgd2lkdGhCbG9ja1JhdGlvID0gKHVpbnQzMikoKGRvdWJsZSl3aWR0aEluIC8gKGRvdWJsZSl3aWR0aE91dCk7CgkgdWludDMyIGhlaWdodEJsb2NrUmF0aW8gPSAodWludDMyKSgoZG91YmxlKWhlaWdodEluIC8gKGRvdWJsZSloZWlnaHRPdXQpOwoJIAoJIHVpbnQzMiogcGl4ZWxEYXRhb3V0U3RvcmUgPSAqcGl4ZWxEYXRhT3V0OwoJIAoJIHVpbnQzMiBvdXRQaXhlbElkeCA9IDA7CgkgCgkgdWludDMyIGhlaWdodElkeCA9IDA7CgkgdWludDMyIHN0YXJ0SWR4ID0gMDsKCSB1aW50MzIgbGFzdFN0YXJ0SWR4ID0gMDsKCSBmb3IgKHVpbnQzMiB5ID0gMDsgeSA8IGhlaWdodE91dDsgeSsrKSB7CgkgaGVpZ2h0SWR4ID0geSAqIGhlaWdodEJsb2NrUmF0aW87CgkgZm9yICh1aW50MzIgeCA9IDA7IHggPCB3aWR0aE91dDsgeCsrKSB7Cgkgc3RhcnRJZHggPSAoaGVpZ2h0SWR4ICogd2lkdGhJbikgKyAoeCAqIHdpZHRoQmxvY2tSYXRpbyk7CgkgaWYgKChzdGFydElkeCArIHdpZHRoQmxvY2tSYXRpbykgPCAoKGhlaWdodElkeCAqIHdpZHRoSW4pICsgd2lkdGhJbikpIHsKCSBWaXN1YWxDb2xvclRvb2xzOjpnZXRNZWFuUGl4ZWxDb2xvcihwaXhlbERhdGFJbiArIHN0YXJ0SWR4LCB3aWR0aEJsb2NrUmF0aW8sIHBpeGVsRGF0YW91dFN0b3JlW3kgKiB3aWR0aE91dCArIHhdKTsKCSBsYXN0U3RhcnRJZHggPSBzdGFydElkeDsKCSB9IGVsc2UgewoJIHBpeGVsRGF0YW91dFN0b3JlW3kgKiB3aWR0aE91dCArIHhdID0gMHhmZjAwMDBmZjsKCSAvL1Zpc3VhbENvbG9yVG9vbHM6OmdldE1lYW5QaXhlbENvbG9yKHBpeGVsRGF0YUluICsgbGFzdFN0YXJ0SWR4LCB3aWR0aEJsb2NrUmF0aW8sIHBpeGVsRGF0YW91dFN0b3JlW3kgKiB3aWR0aE91dCArIHhdKTsKCSB9CgkgfQoJIH0KCSAqLwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6cmVhZFBpeGVscyhkb3VibGUgeENvb3JkLCBkb3VibGUgeUNvb3JkLCB1aW50MzIgd2lkdGgsIHVpbnQzMiBoZWlnaHQsIHVpbnQzMioqIHBpeGVsRGF0YSwgdWludDE2IGZvcm1hdCwgdWludDE2IGRhdGFUeXBlLCBjb25zdCBWaXN1YWxDYW1lcmEmIGFDYW1lcmEpIHsKCXVpbnQxNiB4UG9zLCB5UG9zOwoJeFBvcyA9IHhDb29yZFRvUGl4ZWwoeENvb3JkLCBhQ2FtZXJhKTsKCXlQb3MgPSB5Q29vcmRUb1BpeGVsKHlDb29yZCwgYUNhbWVyYSk7Cgl0aGlzLT5zZXRQaXhlbFN0b3JhZ2VQYXJhbXMoKTsKCWdsUmVhZFBpeGVscyh4UG9zLCB5UG9zLCB3aWR0aCwgaGVpZ2h0LCBmb3JtYXQsIGRhdGFUeXBlLCAqcGl4ZWxEYXRhKTsKfQoKCiNpZiBUQVJHRVRfT1NfV0lOCmJvb2wgVmlzdWFsR3JhcGhpY3M6Om1ha2VUZXh0dXJlT2ZTdHJpbmdXaW4od2NoYXJfdCogc3RyaW5nVmFsdWUsIAoJCQkJCQkJCQkJCWludCBzdHJpbmdWYWx1ZUxlbmd0aCwgCgkJCQkJCQkJCQkJdWludDMyIHRleHR1cmVOdW1iZXIsIAoJCQkJCQkJCQkJCXVpbnQzMiAmdGV4dHVyZVdpZHRoLCAKCQkJCQkJCQkJCQl1aW50MzIgJnRleHR1cmVIZWlnaHQsIAoJCQkJCQkJCQkJCXVpbnQzMiAmaW1hZ2VXaWR0aCwgCgkJCQkJCQkJCQkJdWludDMyICZpbWFnZUhlaWdodCwgCgkJCQkJCQkJCQkJY29uc3QgY2hhciogY29uc3QgZm9udE5hbWUsIAoJCQkJCQkJCQkJCXVpbnQxNiBmb250U2l6ZSwgCgkJCQkJCQkJCQkJdWludDggcmVkLCAKCQkJCQkJCQkJCQl1aW50OCBncmVlbiwgCgkJCQkJCQkJCQkJdWludDggYmx1ZSwKCQkJCQkJCQkJCQlIb3Jpem9udGFsQWxpZ25tZW50IGFsaWdubWVudCwKCQkJCQkJCQkJCQl1aW50MzIgbWF4UGl4ZWxXaWR0aCwKCQkJCQkJCQkJCQl1aW50MzIgbWF4UGl4ZWxIZWlnaHQpIHsKCS8vI2RlZmluZSB1c2VHZXRESUJpdHMKCQoJYm9vbCBzdWNjZXNzID0gdHJ1ZTsKCQoJTE9HRk9OVCBsRm9udDsKCUhEQyBoZGNUZW1wOwojaWZuZGVmIHVzZUdldERJQml0cwoJQklUTUFQVjVIRUFERVIgYmk7CiNlbmRpZgoJQllURSogYml0bWFwQml0cyA9IE5VTEw7CglIQklUTUFQIGhibXBUZW1wOwoJSEZPTlQgdHJhY2tUaXRsZUZvbnQ7Cgl1aW50MzIgc3RyaW5nU2l6ZVdpZHRoID0gMDsKCXVpbnQzMiBzdHJpbmdTaXplSGVpZ2h0ID0gMDsKCQoJY2hhciBlcnJTdHJbMjU2XTsKCQoJVmlzdWFsR3JhcGhpY3MqIHRoZVZpc3VhbEdyYXBoaWNzID0gVmlzdWFsR3JhcGhpY3M6OmdldEluc3RhbmNlKCk7CgkKCVVJTlQgdGV4dEZvcm1hdCA9IChEVF9FWFBBTkRUQUJTfERUX05PUFJFRklYKTsKCXN3aXRjaCAoYWxpZ25tZW50KSB7CgkJY2FzZSAoa0xlZnRBbGlnbmVkKToKCQkJdGV4dEZvcm1hdCB8PSBEVF9MRUZUOwoJCQlicmVhazsKCQljYXNlIChrQ2VudGVyQWxpZ25lZCk6CgkJCXRleHRGb3JtYXQgfD0gRFRfQ0VOVEVSOwoJCQlicmVhazsKCQljYXNlIChrUmlnaHRBbGlnbmVkKToKCQkJdGV4dEZvcm1hdCB8PSBEVF9SSUdIVDsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJc3ByaW50ZihlcnJTdHIsICJ1bmtub3duIHN3aXRjaCBjYXNlICglZCkgaW4gZmlsZTogJXMgKGxpbmU6ICVkKSBbJXNdKSIsIGFsaWdubWVudCwgX19GSUxFX18sIF9fTElORV9fLCBfX0ZVTkNUSU9OX18pOwoJCQl3cml0ZUxvZyhlcnJTdHIpOwoJfQoJCglWaXN1YWxHcmFwaGljc0NvcmUqIHRoZVZpc3VhbEdyYXBoaWNzQ29yZTsKCXRoZVZpc3VhbEdyYXBoaWNzQ29yZSA9IFZpc3VhbEdyYXBoaWNzQ29yZTo6Z2V0SW5zdGFuY2UoKTsKCQoJaGRjVGVtcCA9IENyZWF0ZUNvbXBhdGlibGVEQyh0aGVWaXN1YWxHcmFwaGljc0NvcmUtPmdldFdpbmRvd0RDKCkpOwoJCglaZXJvTWVtb3J5KCZsRm9udCxzaXplb2YoTE9HRk9OVCkpOwoJbEZvbnQubGZIZWlnaHQgPSBNdWxEaXYoZm9udFNpemUsIEdldERldmljZUNhcHMoaGRjVGVtcCwgTE9HUElYRUxTWSksIDcyKTsKCWxGb250LmxmV2lkdGggPSAwOwoJbEZvbnQubGZFc2NhcGVtZW50ID0gMDsKCWxGb250LmxmT3JpZW50YXRpb24gPSAwOwoJbEZvbnQubGZXZWlnaHQgPSBGV19ET05UQ0FSRTsKCWxGb250LmxmSXRhbGljID0gRkFMU0U7CglsRm9udC5sZlVuZGVybGluZSA9IEZBTFNFOwoJbEZvbnQubGZTdHJpa2VPdXQgPSBGQUxTRTsKCWxGb250LmxmQ2hhclNldCA9IERFRkFVTFRfQ0hBUlNFVDsKCWxGb250LmxmT3V0UHJlY2lzaW9uID0gT1VUX09VVExJTkVfUFJFQ0lTOwoJbEZvbnQubGZDbGlwUHJlY2lzaW9uID0gQ0xJUF9ERUZBVUxUX1BSRUNJUzsKCWxGb250LmxmUXVhbGl0eSA9IEFOVElBTElBU0VEX1FVQUxJVFk7CglsRm9udC5sZlBpdGNoQW5kRmFtaWx5ID0gREVGQVVMVF9QSVRDSDsKCWlmIChzdHJsZW4oZm9udE5hbWUpID4gMzIpIHsKCQlzcHJpbnRmKGVyclN0ciwgImxlbmd0aCBvZiBmb250TmFtZSBtdXN0IG5vdCBleGNlZWQgMzIgY2hhcmFjdGVycyBidXQgaXMgJWQgaW4gZmlsZTogJXMgKGxpbmU6ICVkKSBbJXNdKSIsIHN0cmxlbihmb250TmFtZSksIF9fRklMRV9fLCBfX0xJTkVfXywgX19GVU5DVElPTl9fKTsKCQl3cml0ZUxvZyhlcnJTdHIpOwoJCXN0cmNweShsRm9udC5sZkZhY2VOYW1lLCAiQXJpYWwiKTsgLy8gZmFsbGJhY2sgZm9udCBuYW1lCgl9IGVsc2UgewoJCXN0cmNweShsRm9udC5sZkZhY2VOYW1lLCBmb250TmFtZSk7IC8vIGxlbmd0aCBvZiBmb250TmFtZSBtdXN0IG5vdCBleGNlZWQgMzIgY2hhcmFjdGVycyAoaW5jbC4gbnVsbCB0ZXJtaW5hdG9yKQoJfQoJCgl0cmFja1RpdGxlRm9udCA9IENyZWF0ZUZvbnRJbmRpcmVjdCgmbEZvbnQpOwoJCglpZiAoIXRyYWNrVGl0bGVGb250KSB7CgkJc3ByaW50ZihlcnJTdHIsICJFcnIgYWZ0ZXIgQ3JlYXRlRm9udEluZGlyZWN0KCkgaW4gZmlsZTogJXMgKGxpbmU6ICVkKSBbJXNdKSIsIF9fRklMRV9fLCBfX0xJTkVfXywgX19GVU5DVElPTl9fKTsKCQl3cml0ZUxvZyhlcnJTdHIpOwoJfQoJCglTZWxlY3RPYmplY3QoaGRjVGVtcCwgdHJhY2tUaXRsZUZvbnQpOwoJU2V0VGV4dENvbG9yKGhkY1RlbXAsIFJHQigoQllURSlyZWQsIChCWVRFKWdyZWVuLCAoQllURSlibHVlKSk7CgkKCVJFQ1QgdGV4dERyYXdSZWN0OwoJdGV4dERyYXdSZWN0LnRvcCA9IDA7Cgl0ZXh0RHJhd1JlY3QubGVmdCA9IDA7Cgl0ZXh0RHJhd1JlY3QucmlnaHQgPSB0aGlzLT5nZXRDYW52YXNQaXhlbFdpZHRoKCk7Cgl0ZXh0RHJhd1JlY3QuYm90dG9tID0gMDsKCWludCBkcmF3VGV4dFJlc3VsdCA9IDA7CglkcmF3VGV4dFJlc3VsdCA9IERyYXdUZXh0VyhoZGNUZW1wLCBzdHJpbmdWYWx1ZSwgc3RyaW5nVmFsdWVMZW5ndGgsICZ0ZXh0RHJhd1JlY3QsIERUX0NBTENSRUNUfHRleHRGb3JtYXQpOwoJCglpZiAodGV4dERyYXdSZWN0LmJvdHRvbSA9PSAwKSB7CgkJc3ByaW50ZihlcnJTdHIsICJFcnIgKHRleHREcmF3UmVjdC5ib3R0b20gPT0gMCkgaW4gZmlsZTogJXMgKGxpbmU6ICVkKSBbJXNdKSIsIF9fRklMRV9fLCBfX0xJTkVfXywgX19GVU5DVElPTl9fKTsKCQl3cml0ZUxvZyhlcnJTdHIpOwoJfQoJaWYgKGRyYXdUZXh0UmVzdWx0ID09IDApIHsKCQlzcHJpbnRmKGVyclN0ciwgIkVyciAoZHJhd1RleHRSZXN1bHQgPT0gMCkgaW4gZmlsZTogJXMgKGxpbmU6ICVkKSBbJXNdKSIsIF9fRklMRV9fLCBfX0xJTkVfXywgX19GVU5DVElPTl9fKTsKCQl3cml0ZUxvZyhlcnJTdHIpOwoJCXJldHVybiBmYWxzZTsKCX0KCglzdHJpbmdTaXplV2lkdGggPSB0ZXh0RHJhd1JlY3QucmlnaHQgLSB0ZXh0RHJhd1JlY3QubGVmdDsKCXN0cmluZ1NpemVIZWlnaHQgPSB0ZXh0RHJhd1JlY3QuYm90dG9tIC0gdGV4dERyYXdSZWN0LnRvcDsKCQoJLy9TSVpFIHN0cmluZ1NpemU7Cgl1aW50MTYgYUZvbnRTaXplID0gZm9udFNpemU7CglpZiAoKG1heFBpeGVsV2lkdGggPiAwKSAmJiAobWF4UGl4ZWxIZWlnaHQgPiAwKSkgewoJCXdoaWxlICgoc3RyaW5nU2l6ZVdpZHRoID4gbWF4UGl4ZWxXaWR0aCkgfHwgKHN0cmluZ1NpemVIZWlnaHQgPiBtYXhQaXhlbEhlaWdodCkpIHsKCQkJbEZvbnQubGZIZWlnaHQgPSBNdWxEaXYoYUZvbnRTaXplLCBHZXREZXZpY2VDYXBzKGhkY1RlbXAsIExPR1BJWEVMU1kpLCA3Mik7CgkJCURlbGV0ZU9iamVjdCh0cmFja1RpdGxlRm9udCk7CgkJCXRyYWNrVGl0bGVGb250ID0gQ3JlYXRlRm9udEluZGlyZWN0KCZsRm9udCk7CgkJCVNlbGVjdE9iamVjdChoZGNUZW1wLCB0cmFja1RpdGxlRm9udCk7CgkJCS8qCgkJCUJPT0wgdGV4dEV4dGVuZFN1Y2Nlc3MgPSBHZXRUZXh0RXh0ZW50UG9pbnQzMlcoaGRjVGVtcCwgc3RyaW5nVmFsdWUsIHN0cmluZ1ZhbHVlTGVuZ3RoLCAmc3RyaW5nU2l6ZSk7CgkJCWlmICghdGV4dEV4dGVuZFN1Y2Nlc3MpIHsKCQkJCXNwcmludGYoZXJyU3RyLCAiRXJyICghdGV4dEV4dGVuZFN1Y2Nlc3MpIGluIGZpbGU6ICVzIChsaW5lOiAlZCkgWyVzXSkiLCBfX0ZJTEVfXywgX19MSU5FX18sIF9fRlVOQ1RJT05fXyk7CgkJCQl3cml0ZUxvZyhlcnJTdHIpOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJCSovCgkJCS8vc3RyaW5nU2l6ZVdpZHRoID0gc3RyaW5nU2l6ZS5jeDsKCQkJLy9zdHJpbmdTaXplSGVpZ2h0ID0gc3RyaW5nU2l6ZS5jeTsKCQkJZHJhd1RleHRSZXN1bHQgPSBEcmF3VGV4dFcoaGRjVGVtcCwgc3RyaW5nVmFsdWUsIHN0cmluZ1ZhbHVlTGVuZ3RoLCAmdGV4dERyYXdSZWN0LCBEVF9DQUxDUkVDVHx0ZXh0Rm9ybWF0KTsKCQkJaWYgKGRyYXdUZXh0UmVzdWx0ID09IDApIHsKCQkJCXNwcmludGYoZXJyU3RyLCAiRXJyIChkcmF3VGV4dFJlc3VsdCA9PSAwKSBpbiBmaWxlOiAlcyAobGluZTogJWQpIFslc10pIiwgX19GSUxFX18sIF9fTElORV9fLCBfX0ZVTkNUSU9OX18pOwoJCQkJd3JpdGVMb2coZXJyU3RyKTsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCQlzdHJpbmdTaXplV2lkdGggPSB0ZXh0RHJhd1JlY3QucmlnaHQgLSB0ZXh0RHJhd1JlY3QubGVmdDsKCQkJc3RyaW5nU2l6ZUhlaWdodCA9IHRleHREcmF3UmVjdC5ib3R0b20gLSB0ZXh0RHJhd1JlY3QudG9wOwoJCQlhRm9udFNpemUgPSBhRm9udFNpemUgLSAxOwoJCQlpZiAoYUZvbnRTaXplID09IDApIHsKCQkJCXNwcmludGYoZXJyU3RyLCAiRXJyIChhRm9udFNpemUgPT0gMCkgaW4gZmlsZTogJXMgKGxpbmU6ICVkKSBbJXNdKSIsIF9fRklMRV9fLCBfX0xJTkVfXywgX19GVU5DVElPTl9fKTsKCQkJCXdyaXRlTG9nKGVyclN0cik7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9Cgl9IGVsc2UgaWYgKG1heFBpeGVsV2lkdGggPiAwKSB7CgkJd2hpbGUgKHN0cmluZ1NpemVXaWR0aCA+IG1heFBpeGVsV2lkdGgpIHsKCQkJbEZvbnQubGZIZWlnaHQgPSBNdWxEaXYoYUZvbnRTaXplLCBHZXREZXZpY2VDYXBzKGhkY1RlbXAsIExPR1BJWEVMU1kpLCA3Mik7CgkJCURlbGV0ZU9iamVjdCh0cmFja1RpdGxlRm9udCk7CgkJCXRyYWNrVGl0bGVGb250ID0gQ3JlYXRlRm9udEluZGlyZWN0KCZsRm9udCk7CgkJCVNlbGVjdE9iamVjdChoZGNUZW1wLCB0cmFja1RpdGxlRm9udCk7CgkJCS8qCgkJCUJPT0wgdGV4dEV4dGVuZFN1Y2Nlc3MgPSBHZXRUZXh0RXh0ZW50UG9pbnQzMlcoaGRjVGVtcCwgc3RyaW5nVmFsdWUsIHN0cmluZ1ZhbHVlTGVuZ3RoLCAmc3RyaW5nU2l6ZSk7CgkJCWlmICghdGV4dEV4dGVuZFN1Y2Nlc3MpIHsKCQkJCXNwcmludGYoZXJyU3RyLCAiRXJyICghdGV4dEV4dGVuZFN1Y2Nlc3MpIGluIGZpbGU6ICVzIChsaW5lOiAlZCkgWyVzXSkiLCBfX0ZJTEVfXywgX19MSU5FX18sIF9fRlVOQ1RJT05fXyk7CgkJCQl3cml0ZUxvZyhlcnJTdHIpOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJCSovCgkJCS8vc3RyaW5nU2l6ZVdpZHRoID0gc3RyaW5nU2l6ZS5jeDsKCQkJLy9zdHJpbmdTaXplSGVpZ2h0ID0gc3RyaW5nU2l6ZS5jeTsKCQkJZHJhd1RleHRSZXN1bHQgPSBEcmF3VGV4dFcoaGRjVGVtcCwgc3RyaW5nVmFsdWUsIHN0cmluZ1ZhbHVlTGVuZ3RoLCAmdGV4dERyYXdSZWN0LCBEVF9DQUxDUkVDVHx0ZXh0Rm9ybWF0KTsKCQkJaWYgKGRyYXdUZXh0UmVzdWx0ID09IDApIHsKCQkJCXNwcmludGYoZXJyU3RyLCAiRXJyIChkcmF3VGV4dFJlc3VsdCA9PSAwKSBpbiBmaWxlOiAlcyAobGluZTogJWQpIFslc10pIiwgX19GSUxFX18sIF9fTElORV9fLCBfX0ZVTkNUSU9OX18pOwoJCQkJd3JpdGVMb2coZXJyU3RyKTsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCQlzdHJpbmdTaXplV2lkdGggPSB0ZXh0RHJhd1JlY3QucmlnaHQgLSB0ZXh0RHJhd1JlY3QubGVmdDsKCQkJc3RyaW5nU2l6ZUhlaWdodCA9IHRleHREcmF3UmVjdC5ib3R0b20gLSB0ZXh0RHJhd1JlY3QudG9wOwoJCQlhRm9udFNpemUgPSBhRm9udFNpemUgLSAxOwoJCQlpZiAoYUZvbnRTaXplID09IDApIHsKCQkJCXNwcmludGYoZXJyU3RyLCAiRXJyIChhRm9udFNpemUgPT0gMCkgaW4gZmlsZTogJXMgKGxpbmU6ICVkKSBbJXNdKSIsIF9fRklMRV9fLCBfX0xJTkVfXywgX19GVU5DVElPTl9fKTsKCQkJCXdyaXRlTG9nKGVyclN0cik7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9Cgl9IGVsc2UgaWYgKG1heFBpeGVsSGVpZ2h0ID4gMCkgewoJCXdoaWxlIChzdHJpbmdTaXplSGVpZ2h0ID4gbWF4UGl4ZWxIZWlnaHQpIHsKCQkJbEZvbnQubGZIZWlnaHQgPSBNdWxEaXYoYUZvbnRTaXplLCBHZXREZXZpY2VDYXBzKGhkY1RlbXAsIExPR1BJWEVMU1kpLCA3Mik7CgkJCURlbGV0ZU9iamVjdCh0cmFja1RpdGxlRm9udCk7CgkJCXRyYWNrVGl0bGVGb250ID0gQ3JlYXRlRm9udEluZGlyZWN0KCZsRm9udCk7CgkJCVNlbGVjdE9iamVjdChoZGNUZW1wLCB0cmFja1RpdGxlRm9udCk7CgkJCS8qCgkJCUJPT0wgdGV4dEV4dGVuZFN1Y2Nlc3MgPSBHZXRUZXh0RXh0ZW50UG9pbnQzMlcoaGRjVGVtcCwgc3RyaW5nVmFsdWUsIHN0cmluZ1ZhbHVlTGVuZ3RoLCAmc3RyaW5nU2l6ZSk7CgkJCWlmICghdGV4dEV4dGVuZFN1Y2Nlc3MpIHsKCQkJCXNwcmludGYoZXJyU3RyLCAiRXJyICghdGV4dEV4dGVuZFN1Y2Nlc3MpIGluIGZpbGU6ICVzIChsaW5lOiAlZCkgWyVzXSkiLCBfX0ZJTEVfXywgX19MSU5FX18sIF9fRlVOQ1RJT05fXyk7CgkJCQl3cml0ZUxvZyhlcnJTdHIpOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJCSovCgkJCS8vc3RyaW5nU2l6ZVdpZHRoID0gc3RyaW5nU2l6ZS5jeDsKCQkJLy9zdHJpbmdTaXplSGVpZ2h0ID0gc3RyaW5nU2l6ZS5jeTsKCQkJZHJhd1RleHRSZXN1bHQgPSBEcmF3VGV4dFcoaGRjVGVtcCwgc3RyaW5nVmFsdWUsIHN0cmluZ1ZhbHVlTGVuZ3RoLCAmdGV4dERyYXdSZWN0LCBEVF9DQUxDUkVDVHx0ZXh0Rm9ybWF0KTsKCQkJaWYgKGRyYXdUZXh0UmVzdWx0ID09IDApIHsKCQkJCXNwcmludGYoZXJyU3RyLCAiRXJyIChkcmF3VGV4dFJlc3VsdCA9PSAwKSBpbiBmaWxlOiAlcyAobGluZTogJWQpIFslc10pIiwgX19GSUxFX18sIF9fTElORV9fLCBfX0ZVTkNUSU9OX18pOwoJCQkJd3JpdGVMb2coZXJyU3RyKTsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCQlzdHJpbmdTaXplV2lkdGggPSB0ZXh0RHJhd1JlY3QucmlnaHQgLSB0ZXh0RHJhd1JlY3QubGVmdDsKCQkJc3RyaW5nU2l6ZUhlaWdodCA9IHRleHREcmF3UmVjdC5ib3R0b20gLSB0ZXh0RHJhd1JlY3QudG9wOwoJCQlhRm9udFNpemUgPSBhRm9udFNpemUgLSAxOwoJCQlpZiAoYUZvbnRTaXplID09IDApIHsKCQkJCXNwcmludGYoZXJyU3RyLCAiRXJyIChhRm9udFNpemUgPT0gMCkgaW4gZmlsZTogJXMgKGxpbmU6ICVkKSBbJXNdKSIsIF9fRklMRV9fLCBfX0xJTkVfXywgX19GVU5DVElPTl9fKTsKCQkJCXdyaXRlTG9nKGVyclN0cik7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9Cgl9CgojaWZuZGVmIHVzZUdldERJQml0cwoJCglaZXJvTWVtb3J5KCZiaSxzaXplb2YoQklUTUFQVjVIRUFERVIpKTsKCWJpLmJWNVNpemUgPSBzaXplb2YoQklUTUFQVjVIRUFERVIpOwoJYmkuYlY1V2lkdGggPSBzdHJpbmdTaXplV2lkdGg7CgliaS5iVjVIZWlnaHQgPSBzdHJpbmdTaXplSGVpZ2h0OwoJYmkuYlY1UGxhbmVzID0gMTsKCWJpLmJWNUJpdENvdW50ID0gMzI7CgliaS5iVjVDb21wcmVzc2lvbiA9IEJJX0JJVEZJRUxEUzsKCQoJLy8gc3VwcG9ydGVkIDMyIEJQUCBhbHBoYSBmb3JtYXQgZm9yIFdpbmRvd3MgWFAgKEFSR0IpCgliaS5iVjVBbHBoYU1hc2sgPSAweEZGMDAwMDAwOwoJYmkuYlY1UmVkTWFzayA9IDB4MDBGRjAwMDA7CgliaS5iVjVHcmVlbk1hc2sgPSAweDAwMDBGRjAwOwoJYmkuYlY1Qmx1ZU1hc2sgPSAweDAwMDAwMEZGOwoJCgloYm1wVGVtcCA9IENyZWF0ZURJQlNlY3Rpb24oaGRjVGVtcCwgKEJJVE1BUElORk8gKikmYmksIERJQl9SR0JfQ09MT1JTLCAodm9pZCoqKSZiaXRtYXBCaXRzLCBOVUxMLCAoRFdPUkQpMCk7CgkKCWlmICghaGJtcFRlbXApIHsKCQlEZWxldGVEQyhoZGNUZW1wKTsKCQlSZWxlYXNlREModGhlVmlzdWFsR3JhcGhpY3NDb3JlLT5nZXRHcmFwaGljc0RldmljZVBvcnQoKSwgaGRjVGVtcCk7CgkJc3ByaW50ZihlcnJTdHIsICJlcnIgYWZ0ZXIgQ3JlYXRlRElCU2VjdGlvbigpIGluIGZpbGU6ICVzIChsaW5lOiAlZCkgWyVzXSkiLCBfX0ZJTEVfXywgX19MSU5FX18sIF9fRlVOQ1RJT05fXyk7CgkJd3JpdGVMb2coZXJyU3RyKTsKCQlyZXR1cm4gZmFsc2U7Cgl9CgkKI2VuZGlmCgkKI2lmZGVmIHVzZUdldERJQml0cwoJCgloYm1wVGVtcCA9IENyZWF0ZUNvbXBhdGlibGVCaXRtYXAodGhlVmlzdWFsR3JhcGhpY3NDb3JlLT5nZXRXaW5kb3dEQygpLCBzdHJpbmdTaXplV2lkdGgsIHN0cmluZ1NpemVIZWlnaHQpOwoJaWYgKCFoYm1wVGVtcCkgewoJCXNwcmludGYoZXJyU3RyLCAiZXJyIGFmdGVyIENyZWF0ZUNvbXBhdGlibGVCaXRtYXAoKSBpbiBmaWxlOiAlcyAobGluZTogJWQpIFslc10pIiwgX19GSUxFX18sIF9fTElORV9fLCBfX0ZVTkNUSU9OX18pOwoJCXdyaXRlTG9nKGVyclN0cik7Cgl9CgkKI2VuZGlmCgkKCVNlbGVjdE9iamVjdChoZGNUZW1wLCBoYm1wVGVtcCk7CglTZXRCa01vZGUoaGRjVGVtcCwgVFJBTlNQQVJFTlQpOwoJCglTZWxlY3RPYmplY3QoaGRjVGVtcCwgdHJhY2tUaXRsZUZvbnQpOwoJU2V0QmtNb2RlKGhkY1RlbXAsIFRSQU5TUEFSRU5UKTsKCQoJU2V0VGV4dENvbG9yKGhkY1RlbXAsIFJHQigoQllURSlyZWQsIChCWVRFKWdyZWVuLCAoQllURSlibHVlKSk7CglTZXRUZXh0QWxpZ24oaGRjVGVtcCwgVEFfVE9QIHwgVEFfTEVGVCk7CgkKCURyYXdUZXh0VyhoZGNUZW1wLCBzdHJpbmdWYWx1ZSwgc3RyaW5nVmFsdWVMZW5ndGgsICZ0ZXh0RHJhd1JlY3QsIHRleHRGb3JtYXQpOwoJCglHZGlGbHVzaCgpOwoJCiNpZmRlZiB1c2VHZXRESUJpdHMKCQoJYml0bWFwQml0cyA9IChCWVRFKiltYWxsb2Moc3RyaW5nU2l6ZVdpZHRoICogc3RyaW5nU2l6ZUhlaWdodCAqIHNpemVvZihQaXhlbENvbG9yKSk7CgkKCUJJVE1BUElORk8gYm1pOwoJYm1pLmJtaUhlYWRlci5iaVNpemUgPSBzaXplb2YoYm1pLmJtaUhlYWRlcik7CglibWkuYm1pSGVhZGVyLmJpV2lkdGggPSBzdHJpbmdTaXplV2lkdGg7CglibWkuYm1pSGVhZGVyLmJpSGVpZ2h0ID0gc3RyaW5nU2l6ZUhlaWdodDsKCWJtaS5ibWlIZWFkZXIuYmlQbGFuZXMgPSAxOwoJYm1pLmJtaUhlYWRlci5iaUJpdENvdW50ID0gMzI7CglibWkuYm1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9SR0I7CgkKCUdldERJQml0cyhoZGNUZW1wLCBoYm1wVGVtcCwgMCwgc3RyaW5nU2l6ZUhlaWdodCwgYml0bWFwQml0cywgJmJtaSwgRElCX1JHQl9DT0xPUlMpOwoJCiNlbmRpZgoJCgkvLyBzZXQgYWxwaGEgYml0cwoJLy8gYWxwaGEgPSAxIHdoZXJlIG5vdCBlbXB0eSAod2hlcmUgdGV4dCBoYXMgYmVlbiByZW5kZXJlZCkKCS8vIGFscGhhID0gMCB3aGVyZSBubyB0ZXh0CgoJIERXT1JEIHgseTsKCSBEV09SRCogbHBkd1BpeGVsczsKCSBscGR3UGl4ZWxzID0gKERXT1JEKiliaXRtYXBCaXRzOwoJIGZvciAoeCA9IDA7IHggPCBzdHJpbmdTaXplV2lkdGg7IHgrKykgewoJCWZvciAoeSA9IDA7IHkgPCBzdHJpbmdTaXplSGVpZ2h0OyB5KyspIHsKCQkJaWYgKCgqbHBkd1BpeGVscyAmIDB4MDBGRkZGRkYpICE9IDB4MDAwMDAwMDApIHsKCQkJCSpscGR3UGl4ZWxzIHw9IDB4RkYwMDAwMDA7CgkJCX0gZWxzZSB7CgkJCQkqbHBkd1BpeGVscyAmPSAweDAwRkZGRkZGOwoJCQl9CgkJCWxwZHdQaXhlbHMrKzsKCQl9CgkgfQoKCWNvbnN0IFBpeGVsQ29sb3IqIHBpeGVscyA9IChQaXhlbENvbG9yKiliaXRtYXBCaXRzOwoJdGhpcy0+Y29weUFSR0JCaXRtYXBEYXRhVG9UZXh0dXJlKHRleHR1cmVOdW1iZXIsIHN0cmluZ1NpemVXaWR0aCwgc3RyaW5nU2l6ZUhlaWdodCwgdGhpcy0+Y2FuVXNlVGV4dHVyZVJlY3RFeHRlbnNpb24oKSwgJnBpeGVscyk7CgoJRGVsZXRlT2JqZWN0KHRyYWNrVGl0bGVGb250KTsKCQojaWZkZWYgdXNlR2V0RElCaXRzCglmcmVlKGJpdG1hcEJpdHMpOwojZW5kaWYKCQoJRGVsZXRlT2JqZWN0KGhibXBUZW1wKTsKCQoJRGVsZXRlREMoaGRjVGVtcCk7CgoJaWYgKHRoaXMtPmNhblVzZVRleHR1cmVSZWN0RXh0ZW5zaW9uKCkgPT0gZmFsc2UpIHsKCQl0ZXh0dXJlV2lkdGggPSB0aGlzLT5wb3dlcjJDZWlsaW5nKCh1aW50MzIpc3RyaW5nU2l6ZVdpZHRoKTsKCQl0ZXh0dXJlSGVpZ2h0ID0gdGhpcy0+cG93ZXIyQ2VpbGluZygodWludDMyKXN0cmluZ1NpemVIZWlnaHQpOwoJfSBlbHNlIHsKCQl0ZXh0dXJlV2lkdGggPSAodWludDMyKXN0cmluZ1NpemVXaWR0aDsKCQl0ZXh0dXJlSGVpZ2h0ID0gKHVpbnQzMilzdHJpbmdTaXplSGVpZ2h0OwoJfQoJaW1hZ2VXaWR0aCA9ICh1aW50MzIpc3RyaW5nU2l6ZVdpZHRoOwoJaW1hZ2VIZWlnaHQgPSAodWludDMyKXN0cmluZ1NpemVIZWlnaHQ7CgoJcmV0dXJuIHN1Y2Nlc3M7Cn0KI2VuZGlmCgoKdm9pZCBWaXN1YWxHcmFwaGljczo6ZHJhd1Nwb3QoY29uc3QgZG91YmxlIHhOdW0sIGNvbnN0IGRvdWJsZSB5TnVtLCBjb25zdCBkb3VibGUgciwgY29uc3QgZG91YmxlIGcsIGNvbnN0IGRvdWJsZSBiLCB1aW50MTYgd2F2ZWZvcm1JbnRlbnNpdHlWYWwsIGRvdWJsZSBpbnRlbnNpdHksIGNvbnN0IHVpbnQ4IHRhaWxTaXplKSB7CgkKICAgIGZsb2F0IG1heFJhZGl1cyA9IDAuM2Y7CiAgICBpbnQgc2xpY2VzID0gNDA7CiAgICBpbnQgaTsKICAgIGZsb2F0IHNjYWxlUmF0aW87CiAgICAvL2Zsb2F0IHhOdW0sIHlOdW0sIHIsIGcsIGI7CiAgICAvL3VpbnQ4IHdhdmVmb3JtSW50ZW5zaXR5VmFsOwogICAgLy9mbG9hdCBpbnRlbnNpdHk7CiAgICBmbG9hdCByb3RhdGlvblZhbD0zLjBmOwogICAgdWludDggbnVtYmVyT2ZJdGVyYXRpb25zOwogICAgCiAgICAvKiB6ZW50cmFsZSBNZXRob2RlIHp1bSBNYWxlbiBlaW5lcyBMaWNodHB1bmt0ZXMgKi8KICAgIC8qIHhOdW0gdW5kIHlOdW0gOiBQb3NpdGlvbiAqLwogICAgLyogciwgZywgYiA6IEZhcmJlICovCiAgICAvKiB3YXZlZm9ybUludGVuc2l0eVZhbCA6IFVtZmFuZyAoMC0xMDApICovCiAgICAvKiBpbnRlbnNpdHkgOiBhbHBoYVZhbCAoMC4wIC0gMS4wKSAqLwogICAgCiAgICAvL3hOdW0gPSBwTGljaHRwdW5rdC0+eFBvczsKICAgIC8veU51bSA9IHBMaWNodHB1bmt0LT55UG9zOwogICAgLy9yID0gcExpY2h0cHVua3QtPnJlZFZhbDsKICAgIC8vZyA9IHBMaWNodHB1bmt0LT5ncmVlblZhbDsKICAgIC8vYiA9IHBMaWNodHB1bmt0LT5ibHVlVmFsOwogICAgLy93YXZlZm9ybUludGVuc2l0eVZhbCA9IHBMaWNodHB1bmt0LT53YXZlZm9ybUludGVuc2l0eVZhbDsKICAgIC8vaW50ZW5zaXR5ID0gcExpY2h0cHVua3QtPmxpZmV0aW1lSW50ZW5zaXR5OwoJCgkKICAgIGlmICh3YXZlZm9ybUludGVuc2l0eVZhbD4xMDApIHsKICAgIAl3YXZlZm9ybUludGVuc2l0eVZhbCA9IDEwMDsgLy8gbWF4CiAgICB9CgkKICAgIGlmIChpbnRlbnNpdHkgPiAxLjApIHsKICAgICAgICBpbnRlbnNpdHkgPSAxLjA7IC8vbWF4CiAgICB9CiAgICAKICAgIGludGVuc2l0eSA9IGludGVuc2l0eS8yLjJmOyAvLyBtYXggYWxwaGFWYWwgaXN0IDwgMS4wCiAgICAKICAgIHNsaWNlcyA9IChpbnQpKChmbG9hdClzbGljZXMgKiAoKGZsb2F0KXdhdmVmb3JtSW50ZW5zaXR5VmFsLzEwMC4wKSk7CiAgICAKICAgIHNjYWxlUmF0aW8gPSAoZmxvYXQpd2F2ZWZvcm1JbnRlbnNpdHlWYWwvMTAwLjBmOwogICAgCiAgICAKICAgIGlmICh0YWlsU2l6ZSA9PSAwKSB7CiAgICAgICAgbnVtYmVyT2ZJdGVyYXRpb25zID0gMTsKICAgIH0gZWxzZSB7CiAgICAgICAgbnVtYmVyT2ZJdGVyYXRpb25zID0gdGFpbFNpemU7CiAgICB9CiAgICAKICAgIGZvciAoaW50IG0gPSAxOyBtIDw9IG51bWJlck9mSXRlcmF0aW9uczsgbSsrKSB7CiAgICAgICAgcm90YXRpb25WYWwgLT00LjBmOwoJCWdsTG9hZElkZW50aXR5KCk7CgkJCiAgICAgICAgZ2xTY2FsZWQoMS4wLCAxLjAsIDEuMCk7CiAgICAgICAgZ2xSb3RhdGVkKHJvdGF0aW9uVmFsLCAwLjAsIDAuMCwgMS4wKTsKICAgICAgICBnbFRyYW5zbGF0ZWQoeE51bSwgeU51bSwgMC4wKTsKCQkKICAgICAgICBnbFNjYWxlZChzY2FsZVJhdGlvLCBzY2FsZVJhdGlvLCBzY2FsZVJhdGlvKTsKCQkKICAgICAgICAvLyBBdXNzZW5zY2hlaW4KICAgICAgICBnbEJlZ2luIChHTF9UUklBTkdMRV9GQU4pOwoJCQoJCQoJCS8vICAgIGlmIChpbnRlbnNpdHk+MC44KSB7CgkJLy8gICAgCS8vIGRhcyBMaWNodCBzY2hlaW50IGxhbmdzYW0gYXVmCgkJLy8gICAgCS8vICh1bmQgc3RhcnRldCBuaWNodCBtaXQgZnVsbCBwb3dlcikKCQkvLyAgICAJZ2xDb2xvcjRmKHIsZyxiLCAoMS4wIC0gaW50ZW5zaXR5KSk7CgkJLy8gICAgfSBlbHNlIHsKCQkvLyAgICAJZ2xDb2xvcjRmKHIsZyxiLCBpbnRlbnNpdHkqKDEuMC8wLjgpKTsKCQkvLyAgICB9CiAgICAgICAgCiAgICAgICAgCgkJLy9nbENvbG9yNGYocixnLGIsIGludGVuc2l0eSk7CgkJZ2xDb2xvcjRkKHIsIGcsIGIsIGludGVuc2l0eS9tKTsKICAgICAgICAKCQlnbFZlcnRleDJkKDAuMCwgMC4wKTsKICAgICAgICAKCQlnbENvbG9yNGQociwgZywgYiwgMC4wKTsgLy9nbENvbG9yNGYocixnLGIsIGludGVuc2l0eSooaW50ZW5zaXR5LzIuMCkpOyAvLyBhdWZibGVuZGVuICh0ZXN0KQogICAgICAgIAoJCWZvciAoaSA9IDA7IGkgPD0gc2xpY2VzOyBpKyspIHsKCQkJZ2xWZXJ0ZXgyZiAobWF4UmFkaXVzICogKGZsb2F0KShjb3MgKCgyLjBmICogKGZsb2F0KU1fUEkpICogKGZsb2F0KSBpLyhmbG9hdCkgc2xpY2VzKSksCgkJCQkJCW1heFJhZGl1cyAqIChmbG9hdCkoc2luICgoMi4wZiAqIChmbG9hdClNX1BJKSAqIChmbG9hdCkgaS8oZmxvYXQpIHNsaWNlcykpKTsKCQl9CgkJCiAgICAgICAgZ2xFbmQoKTsKCQkKICAgICAgICBpZiAobT09MSkgewogICAgICAgICAgICAvLyAobnVyIGRlciBLb3BmIGhhdCBlaW5lbiBLZXJuKQogICAgICAgICAgICAvLyBLZXJuCiAgICAgICAgICAgIGdsQmVnaW4gKEdMX1RSSUFOR0xFX0ZBTik7CgkJCQoJCQkvL2dsQ29sb3I0ZiAoMS4wLCAxLjAsIDEuMCwgKGludGVuc2l0eS8zLjApKTsgLy8gd2Vpc3MKCQkJZ2xDb2xvcjRkKDEuMCwgMS4wLCAxLjAsIChpbnRlbnNpdHkvMy4wL20pKTsgLy8gd2Vpc3MKCQkJZ2xWZXJ0ZXgyZCgwLjAsIDAuMCk7CgkJCQoJCQlnbENvbG9yNGQociwgZywgYiwgMC4wKTsKCQkJCgkJCWZvciAoaSA9IDA7IGkgPD0gc2xpY2VzOyBpKyspIHsKCQkJCWdsVmVydGV4MmYgKChtYXhSYWRpdXMvNC4wZikgKiAoZmxvYXQpKGNvcyAoKDIuMCAqIChmbG9hdClNX1BJKSAqIChmbG9hdCkgaS8oZmxvYXQpIHNsaWNlcykpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1heFJhZGl1cy80LjBmKSAqIChmbG9hdCkoc2luICgoMi4wZiAqIChmbG9hdClNX1BJKSAqIChmbG9hdCkgaS8oZmxvYXQpIHNsaWNlcykpKTsKCQkJfQoJCQkKICAgICAgICAgICAgZ2xFbmQoKTsKICAgICAgICB9CiAgICB9CgkKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmRyYXdUcmlhbmdsZSgpIHsKCQoJR0xmbG9hdCB0b3BQb3MgPSAxLjBmOwoJc3RhdGljIEdMZmxvYXQgcmVkOwoJR0xmbG9hdCBncmVlbjsKCUdMZmxvYXQgYmx1ZTsKCQoJc3RhdGljIEdMZmxvYXQgcm90YXRlQW5nbGUgPSAwLjBmOwoJCglyZWQgPSByZWQgKyAwLjAwM2Y7CiAgICAKICAgIGdyZWVuID0gcmVkOwogICAgYmx1ZSA9IDEuMGYgLSByZWQ7CiAgICAKICAgIHJvdGF0ZUFuZ2xlID0gcm90YXRlQW5nbGUgKyAwLjNmOwogICAgaWYgKHJvdGF0ZUFuZ2xlID4gMzYwLjApIHsKICAgICAgICByb3RhdGVBbmdsZSA9IDAuMGY7CiAgICB9CgkKICAgIGdsUm90YXRlZihyb3RhdGVBbmdsZSwwLjBmLDEuMGYsMC4wZik7CgkKICAgIGdsQmVnaW4oR0xfVFJJQU5HTEVTKTsKCWdsQ29sb3IzZChyZWQsMC4wLDAuMCk7CglnbFZlcnRleDJkKDAuMCwgdG9wUG9zKTsKCWdsQ29sb3IzZCgwLjAsZ3JlZW4sMC4wKTsKCWdsVmVydGV4MmQoLTEuMCwtMS4wKTsKCWdsQ29sb3IzZCgwLjAsMC4wLGJsdWUpOwoJZ2xWZXJ0ZXgyZCggMS4wLC0xLjApOwoJCiAgICBnbEVuZCgpOwoJCn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpzcG90R0woZG91YmxlIHpQbGFuZSkgewoJZ2xFbmFibGUoR0xfUE9JTlRfU01PT1RIKTsKCWdsUG9pbnRTaXplKDUuMGYpOwoJZ2xCZWdpbihHTF9QT0lOVFMpOwoJZ2xDb2xvcjNkKDEuMCwgMS4wLCAwLjApOwoJZ2xWZXJ0ZXgzZCggMC4wLCAwLjAsIHpQbGFuZSk7CglnbEVuZCgpOwoJZ2xEaXNhYmxlKEdMX1BPSU5UX1NNT09USCk7Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpkcmF3UHJvamVjdGlvbk1ldHJpY3MoY29uc3QgVmlzdWFsQ2FtZXJhJiBhQ2FtZXJhKSB7CgkvLyBzb21lIGdyZXkgbnVtYmVycyBhbG9uZyB0aGUgYXhlcyBvZiB0aGUgcHJvamVjdGlvbiBzcGFjZQoJdWludDMyIG51bWJlck9mTWFya3MgPSAxMDsKCWdsQ29sb3I0ZCgwLjQsIDAuNCwgMC40LCAxLjApOwoJY2hhciBzdHJbMzJdOwoJZG91YmxlIGRpc3RhbmNlID0gYUNhbWVyYS5nZXREZXB0aCgpOwoJZG91YmxlIG5lYXJQb3MgPSBhQ2FtZXJhLmdldE1heE5lYXJQb3MoKSAqIC0xLjA7Cglkb3VibGUgZmFyUG9zID0gYUNhbWVyYS5nZXRNYXhGYXJQb3MoKSAqIC0xLjA7Cglmb3IgKHVpbnQzMiBpID0gMDsgaSA8IG51bWJlck9mTWFya3M7IGkrKykgewoJCWdsUmFzdGVyUG9zM2QoYUNhbWVyYS5nZXRNYXhMZWZ0Q29vcmQoKSwgYUNhbWVyYS5nZXRNYXhCb3R0b21Db29yZCgpLCBuZWFyUG9zIC0gKChkaXN0YW5jZSAvIG51bWJlck9mTWFya3MpICogaSkpOwoJCXNwcmludGYoc3RyLCAiJS4yZiIsIG5lYXJQb3MgLSAoKGRpc3RhbmNlIC8gbnVtYmVyT2ZNYXJrcykgKiBpKSk7CgkJdGhpcy0+ZHJhd0NTdHJpbmdXaXRoR0woc3RyLCBzdHJsZW4oc3RyKSk7Cgl9Cglmb3IgKHVpbnQzMiBpID0gMDsgaSA8IG51bWJlck9mTWFya3M7IGkrKykgewoJCWdsUmFzdGVyUG9zM2QoYUNhbWVyYS5nZXRNYXhSaWdodENvb3JkKCksIGFDYW1lcmEuZ2V0TWF4Qm90dG9tQ29vcmQoKSwgbmVhclBvcyAtICgoZGlzdGFuY2UgLyBudW1iZXJPZk1hcmtzKSAqIGkpKTsKCQlzcHJpbnRmKHN0ciwgIiUuMmYiLCBuZWFyUG9zIC0gKChkaXN0YW5jZSAvIG51bWJlck9mTWFya3MpICogaSkpOwoJCXRoaXMtPmRyYXdDU3RyaW5nV2l0aEdMKHN0ciwgc3RybGVuKHN0cikpOwoJfQoJZm9yICh1aW50MzIgaSA9IDA7IGkgPCBudW1iZXJPZk1hcmtzOyBpKyspIHsKCQlnbFJhc3RlclBvczNkKGFDYW1lcmEuZ2V0TWF4TGVmdENvb3JkKCksIGFDYW1lcmEuZ2V0TWF4VG9wQ29vcmQoKSwgbmVhclBvcyAtICgoZGlzdGFuY2UgLyBudW1iZXJPZk1hcmtzKSAqIGkpKTsKCQlzcHJpbnRmKHN0ciwgIiUuMmYiLCBuZWFyUG9zIC0gKChkaXN0YW5jZSAvIG51bWJlck9mTWFya3MpICogaSkpOwoJCXRoaXMtPmRyYXdDU3RyaW5nV2l0aEdMKHN0ciwgc3RybGVuKHN0cikpOwoJfQoJZm9yICh1aW50MzIgaSA9IDA7IGkgPCBudW1iZXJPZk1hcmtzOyBpKyspIHsKCQlnbFJhc3RlclBvczNkKGFDYW1lcmEuZ2V0TWF4UmlnaHRDb29yZCgpLCBhQ2FtZXJhLmdldE1heFRvcENvb3JkKCksIG5lYXJQb3MgLSAoKGRpc3RhbmNlIC8gbnVtYmVyT2ZNYXJrcykgKiBpKSk7CgkJc3ByaW50ZihzdHIsICIlLjJmIiwgbmVhclBvcyAtICgoZGlzdGFuY2UgLyBudW1iZXJPZk1hcmtzKSAqIGkpKTsKCQl0aGlzLT5kcmF3Q1N0cmluZ1dpdGhHTChzdHIsIHN0cmxlbihzdHIpKTsKCX0KCWRvdWJsZSB2ZXJ0aWNhbERpc3RhbmNlID0gYUNhbWVyYS5nZXRDb29yZEhlaWdodCgpOwoJZm9yICh1aW50MzIgaSA9IDA7IGkgPCBudW1iZXJPZk1hcmtzOyBpKyspIHsKCQlnbFJhc3RlclBvczNkKGFDYW1lcmEuZ2V0TWF4TGVmdENvb3JkKCksIGFDYW1lcmEuZ2V0TWF4Qm90dG9tQ29vcmQoKSArICgodmVydGljYWxEaXN0YW5jZSAvIG51bWJlck9mTWFya3MpICogaSksIG5lYXJQb3MpOwoJCXNwcmludGYoc3RyLCAiJS4yZiIsIGFDYW1lcmEuZ2V0TWF4Qm90dG9tQ29vcmQoKSArICgodmVydGljYWxEaXN0YW5jZSAvIG51bWJlck9mTWFya3MpICogaSkpOwoJCXRoaXMtPmRyYXdDU3RyaW5nV2l0aEdMKHN0ciwgc3RybGVuKHN0cikpOwoJfQoJZm9yICh1aW50MzIgaSA9IDA7IGkgPCBudW1iZXJPZk1hcmtzOyBpKyspIHsKCQlnbFJhc3RlclBvczNkKGFDYW1lcmEuZ2V0TWF4UmlnaHRDb29yZCgpIC0gMC4yLCBhQ2FtZXJhLmdldE1heEJvdHRvbUNvb3JkKCkgKyAoKHZlcnRpY2FsRGlzdGFuY2UgLyBudW1iZXJPZk1hcmtzKSAqIGkpLCBuZWFyUG9zKTsKCQlzcHJpbnRmKHN0ciwgIiUuMmYiLCBhQ2FtZXJhLmdldE1heEJvdHRvbUNvb3JkKCkgKyAoKHZlcnRpY2FsRGlzdGFuY2UgLyBudW1iZXJPZk1hcmtzKSAqIGkpKTsKCQl0aGlzLT5kcmF3Q1N0cmluZ1dpdGhHTChzdHIsIHN0cmxlbihzdHIpKTsKCX0KCWRvdWJsZSBob3Jpem9udGFsRGlzdGFuY2UgPSBhQ2FtZXJhLmdldENvb3JkV2lkdGgoKTsKCWZvciAodWludDMyIGkgPSAwOyBpIDwgbnVtYmVyT2ZNYXJrczsgaSsrKSB7CgkJZ2xSYXN0ZXJQb3MzZChhQ2FtZXJhLmdldE1heExlZnRDb29yZCgpICsgKChob3Jpem9udGFsRGlzdGFuY2UgLyBudW1iZXJPZk1hcmtzKSAqIGkpLCBhQ2FtZXJhLmdldE1heEJvdHRvbUNvb3JkKCksIG5lYXJQb3MpOwoJCXNwcmludGYoc3RyLCAiJS4yZiIsIGFDYW1lcmEuZ2V0TWF4TGVmdENvb3JkKCkgKyAoKGhvcml6b250YWxEaXN0YW5jZSAvIG51bWJlck9mTWFya3MpICogaSkpOwoJCXRoaXMtPmRyYXdDU3RyaW5nV2l0aEdMKHN0ciwgc3RybGVuKHN0cikpOwoJfQoJZm9yICh1aW50MzIgaSA9IDA7IGkgPCBudW1iZXJPZk1hcmtzOyBpKyspIHsKCQlnbFJhc3RlclBvczNkKGFDYW1lcmEuZ2V0TWF4TGVmdENvb3JkKCkgKyAoKGhvcml6b250YWxEaXN0YW5jZSAvIG51bWJlck9mTWFya3MpICogaSksIGFDYW1lcmEuZ2V0TWF4VG9wQ29vcmQoKSAtIDAuMSwgbmVhclBvcyk7CgkJc3ByaW50ZihzdHIsICIlLjJmIiwgYUNhbWVyYS5nZXRNYXhMZWZ0Q29vcmQoKSArICgoaG9yaXpvbnRhbERpc3RhbmNlIC8gbnVtYmVyT2ZNYXJrcykgKiBpKSk7CgkJdGhpcy0+ZHJhd0NTdHJpbmdXaXRoR0woc3RyLCBzdHJsZW4oc3RyKSk7Cgl9Cglmb3IgKHVpbnQzMiBpID0gMDsgaSA8IG51bWJlck9mTWFya3M7IGkrKykgewoJCWdsUmFzdGVyUG9zM2QoYUNhbWVyYS5nZXRNYXhMZWZ0Q29vcmQoKSwgYUNhbWVyYS5nZXRNYXhCb3R0b21Db29yZCgpICsgKCh2ZXJ0aWNhbERpc3RhbmNlIC8gbnVtYmVyT2ZNYXJrcykgKiBpKSwgZmFyUG9zKTsKCQlzcHJpbnRmKHN0ciwgIiUuMmYiLCBhQ2FtZXJhLmdldE1heEJvdHRvbUNvb3JkKCkgKyAoKHZlcnRpY2FsRGlzdGFuY2UgLyBudW1iZXJPZk1hcmtzKSAqIGkpKTsKCQl0aGlzLT5kcmF3Q1N0cmluZ1dpdGhHTChzdHIsIHN0cmxlbihzdHIpKTsKCX0KCWZvciAodWludDMyIGkgPSAwOyBpIDwgbnVtYmVyT2ZNYXJrczsgaSsrKSB7CgkJZ2xSYXN0ZXJQb3MzZChhQ2FtZXJhLmdldE1heFJpZ2h0Q29vcmQoKSAtIDAuMiwgYUNhbWVyYS5nZXRNYXhCb3R0b21Db29yZCgpICsgKCh2ZXJ0aWNhbERpc3RhbmNlIC8gbnVtYmVyT2ZNYXJrcykgKiBpKSwgZmFyUG9zKTsKCQlzcHJpbnRmKHN0ciwgIiUuMmYiLCBhQ2FtZXJhLmdldE1heEJvdHRvbUNvb3JkKCkgKyAoKHZlcnRpY2FsRGlzdGFuY2UgLyBudW1iZXJPZk1hcmtzKSAqIGkpKTsKCQl0aGlzLT5kcmF3Q1N0cmluZ1dpdGhHTChzdHIsIHN0cmxlbihzdHIpKTsKCX0KCWZvciAodWludDMyIGkgPSAwOyBpIDwgbnVtYmVyT2ZNYXJrczsgaSsrKSB7CgkJZ2xSYXN0ZXJQb3MzZChhQ2FtZXJhLmdldE1heExlZnRDb29yZCgpICsgKChob3Jpem9udGFsRGlzdGFuY2UgLyBudW1iZXJPZk1hcmtzKSAqIGkpLCBhQ2FtZXJhLmdldE1heEJvdHRvbUNvb3JkKCksIGZhclBvcyk7CgkJc3ByaW50ZihzdHIsICIlLjJmIiwgYUNhbWVyYS5nZXRNYXhMZWZ0Q29vcmQoKSArICgoaG9yaXpvbnRhbERpc3RhbmNlIC8gbnVtYmVyT2ZNYXJrcykgKiBpKSk7CgkJdGhpcy0+ZHJhd0NTdHJpbmdXaXRoR0woc3RyLCBzdHJsZW4oc3RyKSk7Cgl9Cglmb3IgKHVpbnQzMiBpID0gMDsgaSA8IG51bWJlck9mTWFya3M7IGkrKykgewoJCWdsUmFzdGVyUG9zM2QoYUNhbWVyYS5nZXRNYXhMZWZ0Q29vcmQoKSArICgoaG9yaXpvbnRhbERpc3RhbmNlIC8gbnVtYmVyT2ZNYXJrcykgKiBpKSwgYUNhbWVyYS5nZXRNYXhUb3BDb29yZCgpLCBmYXJQb3MpOwoJCXNwcmludGYoc3RyLCAiJS4yZiIsIGFDYW1lcmEuZ2V0TWF4TGVmdENvb3JkKCkgKyAoKGhvcml6b250YWxEaXN0YW5jZSAvIG51bWJlck9mTWFya3MpICogaSkpOwoJCXRoaXMtPmRyYXdDU3RyaW5nV2l0aEdMKHN0ciwgc3RybGVuKHN0cikpOwoJfQp9CgoKQ29vcmQgVmlzdWFsR3JhcGhpY3M6OmdldENpcmNsZVBvaW50KHVpbnQzMiBzbGljZUlkeCwgdWludDMyIHNsaWNlc0NvdW50LCBkb3VibGUgcmFkaXVzLCBDb29yZCBjaXJjbGVDZW50ZXIpIHsKCUNvb3JkIGNvb3JkUG9pbnQ7Cgljb29yZFBvaW50LnggPSBjb3MoKDIuMCAqIE1fUEkpICogc3RhdGljX2Nhc3Q8ZG91YmxlPihzbGljZUlkeCkvc3RhdGljX2Nhc3Q8ZG91YmxlPihzbGljZXNDb3VudCkpICogcmFkaXVzOwoJY29vcmRQb2ludC54ICs9IGNpcmNsZUNlbnRlci54OwoJY29vcmRQb2ludC55ID0gc2luKCgyLjAgKiBNX1BJKSAqIHN0YXRpY19jYXN0PGRvdWJsZT4oc2xpY2VJZHgpL3N0YXRpY19jYXN0PGRvdWJsZT4oc2xpY2VzQ291bnQpKSAqIHJhZGl1czsKCWNvb3JkUG9pbnQueSArPSBjaXJjbGVDZW50ZXIueTsKCXJldHVybiBjb29yZFBvaW50Owp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6ZHJhd0JlYXRIaXN0b2dyYW0oY29uc3QgdWludDMyKiBjb25zdCBiZWF0SGlzdG9ncmFtLCBjb25zdCBWaXN1YWxDYW1lcmEmIGFDYW1lcmEpIHsKICAgIEdMZG91YmxlIHhQb3M7CiAgICBHTGRvdWJsZSB4UG9zSW5jVmFsOwoJR0xkb3VibGUgaGVpZ2h0OwoJdWludDMyIG1heHZhbD0wOwoJdWludDggaTsKCWZvciAoaSA9IDA7IGkgPCAxMDA7IGkrKykgewoJCWlmIChiZWF0SGlzdG9ncmFtW2ldID4gbWF4dmFsKSB7CgkJCW1heHZhbCA9IGJlYXRIaXN0b2dyYW1baV07CgkJfQoJfQoJeFBvcyA9IGFDYW1lcmEuZ2V0TWF4TGVmdENvb3JkKCkgKyAwLjI7Cgl4UG9zSW5jVmFsID0gKChhQ2FtZXJhLmdldE1heFJpZ2h0Q29vcmQoKSAtIGFDYW1lcmEuZ2V0TWF4TGVmdENvb3JkKCkpIC8gMi4wIC8gMTAwLjApOwoJaGVpZ2h0ID0gYUNhbWVyYS5nZXRNYXhUb3BDb29yZCgpIC0gYUNhbWVyYS5nZXRNYXhCb3R0b21Db29yZCgpOwoJaGVpZ2h0IC89IDMuNTsKCS8vZ2xMb2FkSWRlbnRpdHkoKTsKCWdsTGluZVdpZHRoKDEuMGYpOwoJZ2xDb2xvcjNkKDEuMCwgMS4wLCAwLjApOwoJLy9nbFRyYW5zbGF0ZWYoMC41ZiwgMC4wZiwgMC4wZik7CglnbEJlZ2luIChHTF9MSU5FX1NUUklQKTsKCXhQb3MgPSB4UG9zICsgeFBvc0luY1ZhbDsKCWZvciAoaSA9IDA7IGkgPCAxMDA7IGkrKykgewoJCWdsVmVydGV4MmQoeFBvcywgKGhlaWdodCAqICgoR0xkb3VibGUpYmVhdEhpc3RvZ3JhbVtpXSAvIChHTGRvdWJsZSltYXh2YWwpKSk7CgkJeFBvcyA9IHhQb3MgKyB4UG9zSW5jVmFsOwoJCWdsVmVydGV4MmQoeFBvcywgKGhlaWdodCAqICgoR0xkb3VibGUpYmVhdEhpc3RvZ3JhbVtpXSAvIChHTGRvdWJsZSltYXh2YWwpKSk7Cgl9CglnbEVuZCgpOwp9CgoKYm9vbCBWaXN1YWxHcmFwaGljczo6Y2FuVXNlVGV4dHVyZVJlY3RFeHRlbnNpb24oKSB7CiNpZiBUQVJHRVRfT1NfTUFDCgkvKgoJIHByaW50Zih0aGlzLT5jYXBhYmlsaXRpZXMuc3RyUmVuZGVyZXJOYW1lKTsKCSBwcmludGYoIlxuIik7CgkgcHJpbnRmKHRoaXMtPmNhcGFiaWxpdGllcy5zdHJSZW5kZXJlclZlbmRvcik7CgkgcHJpbnRmKCJcbiIpOwoJIHByaW50Zih0aGlzLT5jYXBhYmlsaXRpZXMuc3RyUmVuZGVyZXJWZXJzaW9uKTsKCSBwcmludGYoIlxuIik7CgkgaWYgKHRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb24gPj0gMHgwMTQwKSB7CgkgcHJpbnRmKCJPcGVuIEdMIDEuNFxuIik7CgkgfSBlbHNlIGlmICh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDEzMCkgewoJIHByaW50ZigiT3BlbiBHTCAxLjNcbiIpOwoJIH0gZWxzZSBpZiAodGhpcy0+Y2FwYWJpbGl0aWVzLmdsVmVyc2lvbiA+PSAweDAxMjApIHsKCSBwcmludGYoIk9wZW4gR0wgMS4yXG4iKTsKCSB9IGVsc2UgaWYgKHRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb24gPj0gMHgwMTEwKSB7CgkgcHJpbnRmKCJPcGVuIEdMIDEuMVxuIik7CgkgfSBlbHNlIGlmICh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDEwMCkgewoJIHByaW50ZigiT3BlbiBHTCAxLjBcbiIpOwoJIH0gZWxzZSB7CgkgcHJpbnRmKCJPcGVuIEdMID8uPyIpOwoJIH0KCSAqLwkKCS8vcmV0dXJuIGZhbHNlOyAvLyB0ZXN0CgkKCWlmICh0aGlzLT5jYXBhYmlsaXRpZXMuZlRleFJlY3QpIHsKCQkvL3ByaW50ZigiZlRleFJlY3QgdHJ1ZVxuIik7CgkJcmV0dXJuIHRydWU7Cgl9IGVsc2UgewoJCS8vcHJpbnRmKCJmVGV4UmVjdCBmYWxzZVxuIik7CgkJcmV0dXJuIGZhbHNlOwoJfQoJCgkvL2NvbnN0IEdMdWJ5dGUqIHN0ckV4dDsKCS8vc3RyRXh0ID0gZ2xHZXRTdHJpbmcgKEdMX0VYVEVOU0lPTlMpOwoJLy9yZXR1cm4gZmFsc2U7CgkvL3JldHVybiAoZ2x1Q2hlY2tFeHRlbnNpb24gKCJHTF9FWFRfdGV4dHVyZV9yZWN0YW5nbGUiLCBzdHJFeHQpKTsKI2VuZGlmCiNpZiBUQVJHRVRfT1NfV0lOCglyZXR1cm4gZmFsc2U7CiNlbmRpZgp9CgoKYm9vbCBWaXN1YWxHcmFwaGljczo6ZG9lc1N1cHBvcnRHTENvbnZvbHV0aW9uRmlsdGVyKCkgewoJYm9vbCB1c2VHTENvbnZvbHV0aW9uRmlsdGVyID0gZmFsc2U7CiNpZiBUQVJHRVRfT1NfV0lOCgkvLyBEZWNsYXJlIGZ1bmN0aW9uIHBvaW50ZXJzCglQRk5HTENPTlZPTFVUSU9ORklMVEVSMkRQUk9DIGdsQ29udm9sdXRpb25GaWx0ZXIyRDsKCWdsQ29udm9sdXRpb25GaWx0ZXIyRCA9IChQRk5HTENPTlZPTFVUSU9ORklMVEVSMkRQUk9DKXdnbEdldFByb2NBZGRyZXNzKCJnbENvbnZvbHV0aW9uRmlsdGVyMkQiKTsKCS8vaWYgKGdsQ29udm9sdXRpb25GaWx0ZXIyRCkgdXNlR0xDb252b2x1dGlvbkZpbHRlciA9IHRydWU7CgkvLyBCZWNhdXNlIHdlIHdhbnQgdG8gdXNlIHRoZSBzb2Z0d2FyZSBwYXRoIG9uIFdpbmRvd3MgZm9yIGNvbnZvbHV0aW9uIGZpbHRlciwgCgkvLyB3ZSBnZW5lcmFsbHkgcmV0dXJuIGZhbHNlIG9uIFdpbmRvd3MgZm9yIG5vdwojZW5kaWYKI2lmIFRBUkdFVF9PU19NQUMKCXVzZUdMQ29udm9sdXRpb25GaWx0ZXIgPSB0cnVlOwojZW5kaWYKCXJldHVybiB1c2VHTENvbnZvbHV0aW9uRmlsdGVyOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6ZHJhd1dhdmVmb3JtKGNvbnN0IHNpbnQxNiBoaXN0b3J5TnVtLCBjb25zdCB1aW50MTYgbWF4TnVtYmVyT2ZIaXN0b3JpZXMsIGNvbnN0IHVpbnQzMiBudW1iZXJPZldhdmVmb3JtRW50cmllcywgc2ludDE2Kiogd2F2ZWZvcm1EYXRhTW9ub0FycmF5LCBjb25zdCBWaXN1YWxDYW1lcmEmIGFDYW1lcmEpIHsKICAgIAoJaWYgKGhpc3RvcnlOdW0gPT0gLTEpIHJldHVybjsKCQoJR0xkb3VibGUgaGVpZ2h0T2ZXYXZlZm9ybTsKCUdMZG91YmxlIHdpZHRoT2ZXYXZlZm9ybTsKCUdMZG91YmxlIGJvdHRvbUNvb3JkOwoJR0xkb3VibGUgcmlnaHRDb29yZDsKICAgIHNpbnQxNiBoaXN0b3J5SWR4OwoJdWludDMyIGksIGs7CgkKICAgIEdMZG91YmxlIHhQb3M7CiAgICBHTGRvdWJsZSB4UG9zSW5jVmFsOwoJCglDb29yZFNpemUzRCBzaXplID0gYUNhbWVyYS5nZXRTaXplKCk7Cgl3aWR0aE9mV2F2ZWZvcm0gPSBzaXplLndpZHRoIC0gdGhpcy0+eFBpeGVsVG9Db29yZCgzMDAsIGFDYW1lcmEpIC0gdGhpcy0+eFBpeGVsVG9Db29yZCgzMCwgYUNhbWVyYSk7CgloZWlnaHRPZldhdmVmb3JtID0gc2l6ZS5oZWlnaHQgLyA3LjA7Cglib3R0b21Db29yZCA9IGFDYW1lcmEuZ2V0TWF4Qm90dG9tQ29vcmQoKSArIHRoaXMtPnlQaXhlbFRvQ29vcmQoMTAsIGFDYW1lcmEpOwoJcmlnaHRDb29yZCA9IGFDYW1lcmEuZ2V0TWF4TGVmdENvb3JkKCkgKyB0aGlzLT54UGl4ZWxUb0Nvb3JkKDEwLCBhQ2FtZXJhKSArIHdpZHRoT2ZXYXZlZm9ybTsKCXhQb3NJbmNWYWwgPSB3aWR0aE9mV2F2ZWZvcm0gLyAoKGZsb2F0KW51bWJlck9mV2F2ZWZvcm1FbnRyaWVzICogKGZsb2F0KW1heE51bWJlck9mSGlzdG9yaWVzKTsKCQogICAgZ2xMaW5lV2lkdGgoMS4wZik7CiAgICBnbENvbG9yM2QoMC43LCAwLjcsIDAuNyk7CiAgICAKCWdsTG9hZElkZW50aXR5KCk7CglnbFRyYW5zbGF0ZWQoMC4wLCBhQ2FtZXJhLmdldE1heEJvdHRvbUNvb3JkKCkgKyB0aGlzLT54UGl4ZWxUb0Nvb3JkKDYwLCBhQ2FtZXJhKSArIGhlaWdodE9mV2F2ZWZvcm0sIDAuMGYpOwoJCgkvLyB3YXZlZm9ybSBoaXN0b3J5CgloaXN0b3J5SWR4ID0gaGlzdG9yeU51bTsKCXhQb3MgPSByaWdodENvb3JkOwoJZm9yIChpID0gMDsgaSA8IG1heE51bWJlck9mSGlzdG9yaWVzOyBpKyspIHsKCQlnbEJlZ2luKEdMX0xJTkVfU1RSSVApOwoJCWZvciAoayA9IDA7IGsgPCBudW1iZXJPZldhdmVmb3JtRW50cmllczsgaysrKSB7CgkJCS8vZ2xWZXJ0ZXgyZiAoeFBvcywgc3RhdGljX2Nhc3Q8R0xmbG9hdD4od2F2ZWZvcm1EYXRhTW9ub0FycmF5W2hpc3RvcnlJZHggKiBudW1iZXJPZldhdmVmb3JtRW50cmllcyArIGtdKSAvIDEyOC4wZiAqIGhlaWdodE9mV2F2ZWZvcm0pOwoJCQkvL3dhdmVmb3JtRGF0YU1vbm9BcnJheVtoaXN0b3J5SWR4XVtrXSA9IDEyODsKCQkJZ2xWZXJ0ZXgyZCh4UG9zLCBzdGF0aWNfY2FzdDxHTGRvdWJsZT4od2F2ZWZvcm1EYXRhTW9ub0FycmF5W2hpc3RvcnlJZHhdW2tdKSAvIDEyOC4wICogaGVpZ2h0T2ZXYXZlZm9ybSk7CgkJCS8vZ2xWZXJ0ZXgyZiAoeFBvcywgaGVpZ2h0T2ZXYXZlZm9ybSk7CgkJCXhQb3MgLT0geFBvc0luY1ZhbDsKCQl9CgkJZ2xFbmQoKTsKCQlpZiAoKGhpc3RvcnlJZHggLSAxKSA8IDApIHsKCQkJaGlzdG9yeUlkeCA9IG1heE51bWJlck9mSGlzdG9yaWVzIC0gMTsKCQl9IGVsc2UgewoJCQloaXN0b3J5SWR4LS07CgkJfQoJfQoJCgkvLyB3YXZlZm9ybSBvZiBjdXJyZW50IHdhdmVmb3JtIGRhdGEgY2h1bmsKCWdsTG9hZElkZW50aXR5KCk7CglnbFRyYW5zbGF0ZWQoMC4wLCBhQ2FtZXJhLmdldE1heEJvdHRvbUNvb3JkKCkgKyB0aGlzLT54UGl4ZWxUb0Nvb3JkKDEwLCBhQ2FtZXJhKSArIChoZWlnaHRPZldhdmVmb3JtIC8gMi4wKSwgMC4wKTsKCQoJeFBvcyA9IHJpZ2h0Q29vcmQ7Cgl4UG9zSW5jVmFsID0gd2lkdGhPZldhdmVmb3JtIC8gKGZsb2F0KW51bWJlck9mV2F2ZWZvcm1FbnRyaWVzOwoJZ2xCZWdpbiAoR0xfTElORV9TVFJJUCk7Cglmb3IgKGsgPSAwOyBrIDwgbnVtYmVyT2ZXYXZlZm9ybUVudHJpZXM7IGsrKykgewoJCS8vZ2xWZXJ0ZXgyZih4UG9zLCBzdGF0aWNfY2FzdDxHTGZsb2F0Pih3YXZlZm9ybURhdGFNb25vQXJyYXlbaGlzdG9yeUlkeCAqIG51bWJlck9mV2F2ZWZvcm1FbnRyaWVzICsga10pIC8gMTI4LjBmICogaGVpZ2h0T2ZXYXZlZm9ybSk7CgkJLy9nbFZlcnRleDJmKHhQb3MsIHN0YXRpY19jYXN0PEdMZmxvYXQ+KHdhdmVmb3JtRGF0YU1vbm9BcnJheVtoaXN0b3J5SWR4ICogbnVtYmVyT2ZXYXZlZm9ybUVudHJpZXMgKyBrXSkgLyAxMjguMGYgKiBoZWlnaHRPZldhdmVmb3JtKTsKCQlnbFZlcnRleDJkKHhQb3MsIHN0YXRpY19jYXN0PEdMZG91YmxlPih3YXZlZm9ybURhdGFNb25vQXJyYXlbaGlzdG9yeU51bV1ba10pIC8gMTI4LjAgKiBoZWlnaHRPZldhdmVmb3JtKTsKCQl4UG9zIC09IHhQb3NJbmNWYWw7Cgl9CglnbEVuZCgpOwogICAgCn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpkcmF3SGlzdG9yeURpYWdyYW0oc3RkOjp2ZWN0b3I8ZG91YmxlPiYgYVZlY3Rvciwgc2l6ZV90IGJhc2VJZHgsIGRvdWJsZSBtaW5WYWwsIGRvdWJsZSBtYXhWYWwsIGNvbnN0IFZpc3VhbENhbWVyYSYgYUNhbWVyYSkgewoJCglib29sIGRyYXdCb3JkZXIgPSB0cnVlOwoJCgl0aGVWaXN1YWxHcmFwaGljcyA9IFZpc3VhbEdyYXBoaWNzOjpnZXRJbnN0YW5jZSgpOwoJCglDb29yZFNpemUzRCBzaXplID0gYUNhbWVyYS5nZXRTaXplKCk7CglHTGRvdWJsZSBkaWFncmFtQ29vcmRXaWR0aCA9IHNpemUud2lkdGggLyAzLjA7CglHTGRvdWJsZSBkaWFncmFtQ29vcmRIZWlnaHQgPSBzaXplLmhlaWdodCAvIDcuMDsKCUdMZG91YmxlIHRvcENvb3JkID0gYUNhbWVyYS5nZXRNYXhUb3BDb29yZCgpIC0gdGhlVmlzdWFsR3JhcGhpY3MtPnhQaXhlbFRvQ29vcmQoMTAsIGFDYW1lcmEpOzsKCUdMZG91YmxlIGxlZnRDb29yZCA9IGFDYW1lcmEuZ2V0TWF4TGVmdENvb3JkKCkgKyB0aGVWaXN1YWxHcmFwaGljcy0+eFBpeGVsVG9Db29yZCgxMCwgYUNhbWVyYSk7CglHTGRvdWJsZSB4Q29vcmRTdGVwV2lkdGggPSBkaWFncmFtQ29vcmRXaWR0aCAvIHN0YXRpY19jYXN0PEdMZG91YmxlPihhVmVjdG9yLnNpemUoKSk7CgkKICAgIGdsTGluZVdpZHRoKDEuMGYpOwogICAgZ2xDb2xvcjNkKDAuMCwgMC4wLCAxLjApOwoJCglnbEJlZ2luIChHTF9MSU5FX1NUUklQKTsKCQoJR0xkb3VibGUgeENvb3JkID0gbGVmdENvb3JkICsgZGlhZ3JhbUNvb3JkV2lkdGg7CglzaXplX3QgY291bnQgPSAwOwoJc2l6ZV90IGN1cnJJZHggPSBiYXNlSWR4OwoJZG91YmxlIHZhbHVlUmFuZ2UgPSBtYXhWYWwgLSBtaW5WYWw7Cgl3aGlsZSAoY291bnQgPCBhVmVjdG9yLnNpemUoKSkgewoJCQoJCWdsVmVydGV4MmQoeENvb3JkLCB0b3BDb29yZCAtIGRpYWdyYW1Db29yZEhlaWdodCArIChzdGF0aWNfY2FzdDxHTGRvdWJsZT4oYVZlY3RvcltjdXJySWR4XSAvIHZhbHVlUmFuZ2UgKiBkaWFncmFtQ29vcmRIZWlnaHQpKSk7CgkJeENvb3JkIC09IHhDb29yZFN0ZXBXaWR0aDsKCQkKCQlpZiAoY3VycklkeCA9PSAwKSB7CgkJCWN1cnJJZHggPSAoYVZlY3Rvci5zaXplKCkgLSAxKTsKCQl9IGVsc2UgewoJCQljdXJySWR4LS07CgkJfQoJCWNvdW50Kys7Cgl9CgkKCWdsRW5kKCk7CgkKCWlmIChkcmF3Qm9yZGVyID09IHRydWUpIHsKCQlnbExpbmVXaWR0aCgxLjBmKTsKCQlnbENvbG9yNGQoMC4wLCAwLjAsIDEuMCwgMC43KTsKCQlnbEJlZ2luIChHTF9MSU5FX0xPT1ApOwoJCWdsVmVydGV4MmQobGVmdENvb3JkLCB0b3BDb29yZCAtIGRpYWdyYW1Db29yZEhlaWdodCk7CgkJZ2xWZXJ0ZXgyZChsZWZ0Q29vcmQsIHRvcENvb3JkKTsKCQlnbFZlcnRleDJkKGxlZnRDb29yZCArIGRpYWdyYW1Db29yZFdpZHRoLCB0b3BDb29yZCk7CgkJZ2xWZXJ0ZXgyZChsZWZ0Q29vcmQgKyBkaWFncmFtQ29vcmRXaWR0aCwgdG9wQ29vcmQgLSBkaWFncmFtQ29vcmRIZWlnaHQpOwoJCWdsRW5kKCk7Cgl9CgkKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmRyYXdXYXZlZm9ybVNwaXJhbChjb25zdCB1aW50MTYgY3Vyckhpc3RvcnlOdW0sIGNvbnN0IHVpbnQxNiBudW1iZXJPZldhdmVmb3JtRW50cmllcywgY29uc3Qgc2ludDE2KiBjb25zdCB3YXZlZm9ybURhdGFNb25vQXJyYXkpIHsKICAgIC8vIGVpbmUgU3ByaWFsZSBkZXIgd2F2ZWZvcm0tSGlzdG9yeQoJCgkKCS8vIG5ldWUgVmVyc2lvbiBkZXIgZHJhd1dhdmVmb3JtU3BpcmFsCgkvLzIwMDMwMTI5IChIVykKCS8vCgkKICAgIHVpbnQxNiBpbmRleDsKICAgIHVpbnQxNiBoaXN0b3J5SW5kZXg7CiAgICBHTGZsb2F0IHdhdmVmb3JtVmFsOwogICAgc3RhdGljIEdMZmxvYXQgY29zVHdvVGltZXNQaSA9IDAuMGY7CiAgICBzdGF0aWMgR0xmbG9hdCBzaW5Ud29UaW1lc1BpID0gMC4wZjsKICAgIC8vIGZsb2F0IHJhZGl1cyA9IDAuMjU7CiAgICBmbG9hdCByYWRpdXMgPSAwLjAyZjsKICAgIGZsb2F0IHdhdmVSYWRpdXM7CiAgICAvL3VpbnQ4IHdhdmVmb3JtSGlzdG9yeVsyMF1ba1Zpc3VhbE51bVdhdmVmb3JtRW50cmllc107CiAgICAvL3VpbnQxNiB0aW1lU3RvcmVJbmRleDsKICAgIC8vc3RhdGljIHVpbnQxNiBhY2N1RWxhcHNlZE1pbGxpU2VjczsKICAgIHVpbnQzMiBhY2N1RWxhcHNlZE1pbGxpU2VjczsKICAgIC8vdWludDggb25lU2Vjb25kSXNPdmVyQm9vbCA9IDA7CiAgICBzdGF0aWMgc2ludDggcmVkSGlzdG9yeU51bSA9IDA7Cgl1aW50MTYgdGhlQ3Vyckhpc3RvcnlOdW07CgkKCXRoZUN1cnJIaXN0b3J5TnVtID0gY3Vyckhpc3RvcnlOdW07CgkKICAgIGlmIChjb3NUd29UaW1lc1BpID09IDAuMCkgewogICAgICAgIGNvc1R3b1RpbWVzUGkgPSAoZmxvYXQpKGNvcygyLjBmICogTV9QSSkpOwogICAgfQoJCiAgICBpZiAoc2luVHdvVGltZXNQaSA9PSAwLjApIHsKICAgICAgICBzaW5Ud29UaW1lc1BpID0gKGZsb2F0KShzaW4oMi4wZiAqIE1fUEkpKTsKICAgIH0KICAgIAogICAgLy9jdXJyTXVzaWNEYXRhSGlzdG9yeU51bSA9IHBNdXNpY1N0YXRzU3RydWN0LT5nZXRDdXJyTXVzaWNEYXRhSGlzdG9yeSgpOwoJCiAgICAvL3RpbWVTdG9yZUluZGV4ID0gcFRpbWluZy0+c3RvcmVNeVRpbWUoIndhdmVmb3JtU3BpcmFsIik7CiAgICAvL2FjY3VFbGFwc2VkTWlsbGlTZWNzICs9IHBUaW1pbmctPmdldE15RWxhcHNlZE1pbGxpc2Vjb25kcyh0aW1lU3RvcmVJbmRleCk7CiAgICBhY2N1RWxhcHNlZE1pbGxpU2VjcyA9IFZpc3VhbFRpbWluZzo6Z2V0RWxhcHNlZE1pbGxpU2Vjc1NpbmNlUmVzZXQoIndhdmVmb3JtU3BpcmFsIik7CgkKCS8qCgkgaWYgKGFjY3VFbGFwc2VkTWlsbGlTZWNzID4gMTAwMCkgewoJIG9uZVNlY29uZElzT3ZlckJvb2wgPSAxOwoJIC8vYWNjdUVsYXBzZWRNaWxsaVNlY3MgPSAwOwoJIC8vcFRpbWluZy0+Y2xlYXJNeVRpbWVTdG9yZSh0aW1lU3RvcmVJbmRleCk7CgkgcFRpbWluZy0+cmVzZXRUaW1lc3RhbXAoIndhdmVmb3JtU3BpcmFsIik7CgkgcmVkSGlzdG9yeU51bSA9IHRoZUN1cnJIaXN0b3J5TnVtOwoJIH0gZWxzZSB7CgkgcmVkSGlzdG9yeU51bS0tOwoJIGlmIChyZWRIaXN0b3J5TnVtID09IC0xKSB7CgkgcmVkSGlzdG9yeU51bSA9IDIwOwoJIH0KCSB9CgkgKi8JCglyZWRIaXN0b3J5TnVtLS07CglpZiAocmVkSGlzdG9yeU51bSA9PSAtMSkgewoJCXJlZEhpc3RvcnlOdW0gPSAyMDsKCX0KCQogICAgLy9wTXVzaWNTdGF0c1N0cnVjdC0+Z2V0TW9ub1dhdmVmb3JtRGF0YSh3YXZlZm9ybUhpc3RvcnkpOwoJLy9wTXVzaWNTdGF0c1N0cnVjdC0+Z2V0TW9ub1dhdmVmb3JtRGF0YSgodWludDgqKXdhdmVmb3JtSGlzdG9yeSwgMjApOwogICAgCglnbENvbG9yNGQoMC4wLCAwLjAsIDAuMCwgMS4wKTsKICAgIGdsTGluZVdpZHRoKDEuMGYpOwogICAgZ2xFbmFibGUgKEdMX0JMRU5EKTsKICAgIGdsQmxlbmRGdW5jIChHTF9TUkNfQUxQSEEsIEdMX09ORV9NSU5VU19TUkNfQUxQSEEpOwogICAgZ2xCZWdpbiAoR0xfTElORV9TVFJJUCk7CiAgICAKICAgIGZvciAoaGlzdG9yeUluZGV4ID0gMDsgaGlzdG9yeUluZGV4IDwgMjA7IGhpc3RvcnlJbmRleCsrKSB7CgkJCiAgICAgICAgdGhlQ3Vyckhpc3RvcnlOdW0gKys7CiAgICAgICAgaWYgKHRoZUN1cnJIaXN0b3J5TnVtID09IDIwKSB7CiAgICAgICAgICAgIHRoZUN1cnJIaXN0b3J5TnVtID0gMDsKICAgICAgICB9CgkJCiAgICAgICAgZm9yIChpbmRleCA9IDA7IGluZGV4IDwgbnVtYmVyT2ZXYXZlZm9ybUVudHJpZXM7IGluZGV4KyspIHsKCQkJCgkJCXdhdmVmb3JtVmFsID0gd2F2ZWZvcm1EYXRhTW9ub0FycmF5W3RoZUN1cnJIaXN0b3J5TnVtICogbnVtYmVyT2ZXYXZlZm9ybUVudHJpZXMgKyBpbmRleF07CiAgICAgICAgICAgIAogICAgICAgICAgICByYWRpdXMgPSByYWRpdXMgKyAwLjAwMDA5ZjsKICAgICAgICAgICAgLy8gcmFkaXVzID0gcmFkaXVzICsgKDAuMDAwNCAqICgoZmxvYXQpaW5kZXgyLzE4LjApKTsKICAgICAgICAgICAgLy8gd2F2ZVJhZGl1cyA9IHJhZGl1cyArICh3YXZlZm9ybVZhbC8xMDI0LjApOwogICAgICAgICAgICB3YXZlUmFkaXVzID0gcmFkaXVzICsgKCh3YXZlZm9ybVZhbC8yNTUuMGYpICogMC4xZik7CiAgICAgICAgICAgIC8vd2F2ZVJhZGl1cyA9IHJhZGl1cyArICgod2F2ZWZvcm1WYWwvMjU1LjApKjAuNik7CiAgICAgICAgICAgIGlmIChoaXN0b3J5SW5kZXggPT0gcmVkSGlzdG9yeU51bSkgewogICAgICAgICAgICAgICAgZ2xDb2xvcjRkKDEuMCwgMC4wLCAwLjAsIDEuMCk7IC8vIHJlZAogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2xDb2xvcjRkKDAuMCwgMC4wLCAwLjAsIDEuMCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gbnVyIGplZGVyIDEwdGUgUHVua3Qgd2lyZCBnZW1hbHQKICAgICAgICAgICAgaWYgKGluZGV4JTEwID09IDApIHsKCQkJCWdsVmVydGV4MmYgKHdhdmVSYWRpdXMgKiAoZmxvYXQpKGNvcyAoKDIuMGYgKiBNX1BJKSAqIChmbG9hdCkgaW5kZXgvKGZsb2F0KSBudW1iZXJPZldhdmVmb3JtRW50cmllcykpLAoJCQkJCQkJd2F2ZVJhZGl1cyAqIChmbG9hdCkoc2luICgoMi4wZiAqIE1fUEkpICogKGZsb2F0KSBpbmRleC8oZmxvYXQpIG51bWJlck9mV2F2ZWZvcm1FbnRyaWVzKSkpOwogICAgICAgICAgICB9CgkJCQogICAgICAgIH0KICAgIH0KICAgIAogICAgZ2xFbmQoKTsKICAgIGdsRGlzYWJsZSAoR0xfQkxFTkQpOwoJCn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpkcmF3U3BlY3RydW1BbmFseXplcihjb25zdCBzaW50MTYgY3Vyckhpc3RvcnlOdW0sIGNvbnN0IHVpbnQxNiBudW1iZXJPZkhpc3RvcmllcywgY29uc3QgdWludDMyIG51bWJlck9mU3BlY3RydW1FbnRyaWVzLCBjb25zdCB1aW50MTYgbnVtYmVyT2ZBdWRpb0NoYW5uZWxzLCBjb25zdCB1aW50OCoqKiBjb25zdCBzcGVjdHJ1bURhdGFBcnJheSwgY29uc3QgVmlzdWFsQ2FtZXJhJiBhQ2FtZXJhKSB7CiAgICAKCWlmIChjdXJySGlzdG9yeU51bSA9PSAtMSkgcmV0dXJuOwoJCiAgICBHTGRvdWJsZSB4UG9zOwoJR0xkb3VibGUgeVBvczsKCUdMZG91YmxlIGNvb3JkV2lkdGg7CglHTGRvdWJsZSBjb29yZEhlaWdodDsKICAgIHVpbnQxNiBpbmRleCwgaSwgazsKICAgIEdMZG91YmxlIHNwZWN0cnVtVmFsOwoJdWludDE2IG51bWJlck9mU3ViQmFuZHMgPSAxNTsKCWZsb2F0KiBzcGVjdHJ1bURhdGFTdWJCYW5kczsKCWZsb2F0IG1heFNwZWN0cnVtU3VtID0gMDsKCXVpbnQzMiBudW1iZXJPZkVudHJpZXNQZXJCYXJHcmFwaDsKCXVpbnQxNiBudW1iZXJPZkJsb2Nrc1BlckJhckdyYXBoID0gMTA7CglHTGRvdWJsZSBoZWlnaHRPZkNlbGw7IC8vIGhlaWdodE9mQ2VsbCA9IGhlaWdodE9mQmxvY2sgKyBoZWlnaHRPZkdhcEJldHdlZW5CbG9ja3MKCUdMZG91YmxlIGhlaWdodE9mQmxvY2s7CglHTGRvdWJsZSBoZWlnaHRPZkdhcEJldHdlZW5CbG9ja3M7CglHTGRvdWJsZSB3aWR0aE9mQ2VsbDsKCUdMZG91YmxlIHdpZHRoT2ZCbG9jazsKCQoJc3BlY3RydW1EYXRhU3ViQmFuZHMgPSAoZmxvYXQqKW1hbGxvYyhudW1iZXJPZlN1YkJhbmRzICogc2l6ZW9mKGZsb2F0KSk7Cglmb3IgKGkgPSAwOyBpIDwgbnVtYmVyT2ZTdWJCYW5kczsgaSsrKSB7CgkJc3BlY3RydW1EYXRhU3ViQmFuZHNbaV0gPSAwLjBmOwoJfQoJbnVtYmVyT2ZFbnRyaWVzUGVyQmFyR3JhcGggPSBudW1iZXJPZlNwZWN0cnVtRW50cmllcyAvIDIgLyBudW1iZXJPZlN1YkJhbmRzOwoJCgkvLyBwb3NpdGlvbiBvbiBzY3JlZW4KCWNvb3JkV2lkdGggPSB0aGlzLT54UGl4ZWxUb0Nvb3JkKDMwMCwgYUNhbWVyYSk7Cgljb29yZEhlaWdodCA9IHRoaXMtPnlQaXhlbFRvQ29vcmQoNzAsIGFDYW1lcmEpOwoJaGVpZ2h0T2ZDZWxsID0gY29vcmRIZWlnaHQgLyAoZmxvYXQpbnVtYmVyT2ZCbG9ja3NQZXJCYXJHcmFwaDsKCWhlaWdodE9mQmxvY2sgPSBoZWlnaHRPZkNlbGwgKiAwLjg7CgloZWlnaHRPZkdhcEJldHdlZW5CbG9ja3MgPSBoZWlnaHRPZkNlbGwgKiAwLjI7Cgl3aWR0aE9mQ2VsbCA9IGNvb3JkV2lkdGggLyAoZmxvYXQpbnVtYmVyT2ZTdWJCYW5kczsKCXdpZHRoT2ZCbG9jayA9IHdpZHRoT2ZDZWxsICogMC45OwoJCgl4UG9zID0gYUNhbWVyYS5nZXRNYXhSaWdodENvb3JkKCkgLSBjb29yZFdpZHRoOwoJeFBvcyAtPSB0aGlzLT54UGl4ZWxUb0Nvb3JkKDEwLCBhQ2FtZXJhKTsKICAgIAogICAgZ2xMaW5lV2lkdGgoMS4wZik7CiAgICBnbENvbG9yM2QoMC43LDAuNywwLjcpOwogICAgCglnbExvYWRJZGVudGl0eSgpOwoJCglnbFBvaW50U2l6ZSgxLjBmKTsKICAgIAoJZ2xUcmFuc2xhdGVkKDAuMCwgYUNhbWVyYS5nZXRNYXhCb3R0b21Db29yZCgpICsgdGhpcy0+eFBpeGVsVG9Db29yZCgxMCwgYUNhbWVyYSksIDAuMCk7CgkKCS8vIGNvbGxlY3QgdmFsdWVzIGZvciBlYWNoIHN1YkJhbmQKCWluZGV4ID0gMDsKCWZvciAoaSA9IDA7IGkgPCAobnVtYmVyT2ZTcGVjdHJ1bUVudHJpZXMgLyAyKTsgaSsrKSB7CgkJaWYgKChpID4gMCkgJiYgKGklbnVtYmVyT2ZFbnRyaWVzUGVyQmFyR3JhcGggPT0gMCkpIGluZGV4Kys7CgkJaWYgKGluZGV4IDwgKG51bWJlck9mU3ViQmFuZHMgLSAxKSkgewoJCQkvL3NwZWN0cnVtRGF0YVN1YkJhbmRzW2luZGV4XSArPSAoZmxvYXQpc3BlY3RydW1EYXRhQXJyYXlbY3Vyckhpc3RvcnlOdW0gKiBudW1iZXJPZkF1ZGlvQ2hhbm5lbHMgKiBudW1iZXJPZlNwZWN0cnVtRW50cmllcyArIGkgKyAwXTsgLy8gY2hhbm5lbCAwCgkJCXNwZWN0cnVtRGF0YVN1YkJhbmRzW2luZGV4XSArPSAoZmxvYXQpc3BlY3RydW1EYXRhQXJyYXlbY3Vyckhpc3RvcnlOdW1dWzBdW2ldOyAvLyBjaGFubmVsIDAKCQkJLy9zcGVjdHJ1bURhdGFTdWJCYW5kc1tpbmRleF0gKz0gKGZsb2F0KTEwOwoJCX0KCX0KCQoJZm9yIChpID0gMDsgaSA8IG51bWJlck9mU3ViQmFuZHM7IGkrKykgewoJCWlmIChzcGVjdHJ1bURhdGFTdWJCYW5kc1tpXSA+IG1heFNwZWN0cnVtU3VtKSB7CgkJCW1heFNwZWN0cnVtU3VtID0gc3BlY3RydW1EYXRhU3ViQmFuZHNbaV07CgkJfQoJfQoJZm9yIChpID0gMDsgaSA8IG51bWJlck9mU3ViQmFuZHM7IGkrKykgewoJCXNwZWN0cnVtRGF0YVN1YkJhbmRzW2ldID0gIHNwZWN0cnVtRGF0YVN1YkJhbmRzW2ldIC8gbWF4U3BlY3RydW1TdW07IC8vIG1heGltdW0gdmFsdWUgMS4wCgl9CiAgICAKCQogICAgZ2xFbmFibGUgKEdMX0JMRU5EKTsKICAgIGdsQmxlbmRGdW5jIChHTF9TUkNfQUxQSEEsIEdMX09ORV9NSU5VU19TUkNfQUxQSEEpOwoJCglnbEJlZ2luIChHTF9RVUFEUyk7Cglmb3IgKGkgPSAwOyBpIDwgbnVtYmVyT2ZTdWJCYW5kczsgaSsrKSB7CgkJc3BlY3RydW1WYWwgPSBzcGVjdHJ1bURhdGFTdWJCYW5kc1tpXTsKCQlmb3IgKGsgPSAwOyBrIDwgbnVtYmVyT2ZCbG9ja3NQZXJCYXJHcmFwaDsgaysrKSB7CgkJCWlmICgoc3BlY3RydW1WYWwgKiBjb29yZEhlaWdodCkgPiAoayAqIGhlaWdodE9mQ2VsbCkpIHsKCQkJCWdsQ29sb3I0ZCgwLjAsIDAuMCwgMC4wLCAwLjYpOwoJCQl9IGVsc2UgewoJCQkJZ2xDb2xvcjRkKDAuOCwgMC44LCAwLjgsIDAuMSk7CgkJCX0KCQkJeVBvcyA9IChmbG9hdClrICogaGVpZ2h0T2ZDZWxsICsgKGZsb2F0KWhlaWdodE9mR2FwQmV0d2VlbkJsb2NrczsKCQkJZ2xWZXJ0ZXgyZCh4UG9zLCAwLjAgKyB5UG9zKTsKCQkJZ2xWZXJ0ZXgyZCh4UG9zICsgd2lkdGhPZkJsb2NrLCAwLjAgKyB5UG9zKTsKCQkJZ2xWZXJ0ZXgyZCh4UG9zICsgd2lkdGhPZkJsb2NrLCAwLjAgKyB5UG9zICsgaGVpZ2h0T2ZCbG9jayk7CgkJCWdsVmVydGV4MmQoeFBvcywgMC4wICsgeVBvcyArIGhlaWdodE9mQmxvY2spOwoJCX0KCQl4UG9zICs9IHdpZHRoT2ZDZWxsOwoJfQoJZ2xFbmQoKTsKICAgIGdsRGlzYWJsZSAoR0xfQkxFTkQpOwoJCglmcmVlKHNwZWN0cnVtRGF0YVN1YkJhbmRzKTsKICAgIAp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6ZHJhd1NwZWN0cm9ncmFtKGNvbnN0IHNpbnQxNiBjdXJySGlzdG9yeU51bSwgY29uc3QgdWludDE2IG51bWJlck9mSGlzdG9yaWVzLCBjb25zdCB1aW50MzIgbnVtYmVyT2ZTcGVjdHJ1bUVudHJpZXMsIGNvbnN0IHVpbnQxNiBudW1iZXJPZkF1ZGlvQ2hhbm5lbHMsIGNvbnN0IHVpbnQ4KioqIGNvbnN0IHNwZWN0cnVtRGF0YUFycmF5LCBjb25zdCBWaXN1YWxDYW1lcmEmIGFDYW1lcmEpIHsKICAgIAoJaWYgKGN1cnJIaXN0b3J5TnVtID09IC0xKSByZXR1cm47CgkKCUdMZG91YmxlIGhlaWdodE9mU3BlY3Ryb2dyYW07CglHTGRvdWJsZSB3aWR0aE9mU3BlY3Ryb2dyYW07CglHTGRvdWJsZSBib3R0b21Db29yZDsKCUdMZG91YmxlIGxlZnRDb29yZDsKCUdMZG91YmxlIHJvd0Nvb3JkSGVpZ2h0OwoJR0xkb3VibGUgeENvb3JkU3RlcFNpemU7CglHTGRvdWJsZSB4Q29vcmRQb3M7CglHTGRvdWJsZSB5Q29vcmRQb3M7Cgl1aW50MTYgaTsKCXVpbnQxNiBrOwoJc2ludDE2IGhpc3RvcnlJZHg7CgljaGFyIHN0ckluQ1szMl07CgkKCUNvb3JkU2l6ZTNEIHNpemUgPSBhQ2FtZXJhLmdldFNpemUoKTsKCXdpZHRoT2ZTcGVjdHJvZ3JhbSA9IHRoaXMtPnhQaXhlbFRvQ29vcmQoMzAwLCBhQ2FtZXJhKTsKCWhlaWdodE9mU3BlY3Ryb2dyYW0gPSBzaXplLmhlaWdodCAtIHRoaXMtPnlQaXhlbFRvQ29vcmQoOTUsIGFDYW1lcmEpOwoJYm90dG9tQ29vcmQgPSBhQ2FtZXJhLmdldE1heEJvdHRvbUNvb3JkKCkgKyB0aGlzLT55UGl4ZWxUb0Nvb3JkKDg1LCBhQ2FtZXJhKTsKCWxlZnRDb29yZCA9IGFDYW1lcmEuZ2V0TWF4UmlnaHRDb29yZCgpIC0gd2lkdGhPZlNwZWN0cm9ncmFtIC0gdGhpcy0+eVBpeGVsVG9Db29yZCgxMCwgYUNhbWVyYSk7Cglyb3dDb29yZEhlaWdodCA9IGhlaWdodE9mU3BlY3Ryb2dyYW0gLyAoZmxvYXQpbnVtYmVyT2ZIaXN0b3JpZXM7Cgl4Q29vcmRTdGVwU2l6ZSA9IHdpZHRoT2ZTcGVjdHJvZ3JhbSAvIChudW1iZXJPZlNwZWN0cnVtRW50cmllcyAvIDIpOwoJCiAgICAKCS8vZ2xFbmFibGUgKEdMX0JMRU5EKTsKICAgIC8vZ2xCbGVuZEZ1bmMgKEdMX1NSQ19BTFBIQSwgR0xfT05FX01JTlVTX1NSQ19BTFBIQSk7CgkvL2dsQmxlbmRGdW5jIChHTF9TUkNfQUxQSEEsIEdMX1pFUk8pOwoJc3ByaW50ZihzdHJJbkMsICIlZCIsIGN1cnJIaXN0b3J5TnVtKTsKCXNldFByb2Nlc3NJbmZvICgiQ3Vyckhpc3RvcnlOdW0iLCBzdHJJbkMpOwoJCgl5Q29vcmRQb3MgPSBib3R0b21Db29yZDsKCWhpc3RvcnlJZHggPSBjdXJySGlzdG9yeU51bTsKCQoJZm9yIChpID0gMDsgaSA8IG51bWJlck9mSGlzdG9yaWVzOyBpKyspIHsKCQl4Q29vcmRQb3MgPSBsZWZ0Q29vcmQ7CgkJZ2xCZWdpbihHTF9UUklBTkdMRV9TVFJJUCk7CgkJZm9yIChrID0gMDsgayA8IChudW1iZXJPZlNwZWN0cnVtRW50cmllcyAvIDIpOyBrKyspIHsKCQkJLy9nbENvbG9yNGYoKGZsb2F0KXNwZWN0cnVtRGF0YUFycmF5W2hpc3RvcnlJZHggKiBudW1iZXJPZkF1ZGlvQ2hhbm5lbHMgKiBudW1iZXJPZlNwZWN0cnVtRW50cmllcyArIGsgKyAwXSAvIDI1NS4wZiwgMC4wZiwgMC4wZiwgMC44Zik7CgkJCWdsQ29sb3I0ZCgoZmxvYXQpc3BlY3RydW1EYXRhQXJyYXlbaGlzdG9yeUlkeF1bMF1ba10gLyAyNTUuMCwgMC4wLCAwLjAsIDAuOCk7CgkJCWdsVmVydGV4MmQoeENvb3JkUG9zLCB5Q29vcmRQb3MgKyByb3dDb29yZEhlaWdodCk7CgkJCWdsVmVydGV4MmQoeENvb3JkUG9zLCB5Q29vcmRQb3MpOwoJCQl4Q29vcmRQb3MrPSB4Q29vcmRTdGVwU2l6ZTsKCQl9CgkJZ2xFbmQoKTsKCQl5Q29vcmRQb3MrPSByb3dDb29yZEhlaWdodDsKCQlpZiAoKGhpc3RvcnlJZHggLSAxKSA8IDApIHsKCQkJaGlzdG9yeUlkeCA9IG51bWJlck9mSGlzdG9yaWVzIC0gMTsKCQl9IGVsc2UgewoJCQloaXN0b3J5SWR4LS07CgkJfQoJfQoJCgkvL2dsRGlzYWJsZSAoR0xfQkxFTkQpOwoJCn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpkcmF3V2F2ZWZvcm1DaXJjbGUgKGNvbnN0IGZsb2F0IHhOdW0sIGNvbnN0IGZsb2F0IHlOdW0sIGNvbnN0IGZsb2F0IHJvdFZhbCwgY29uc3QgZmxvYXQgcmFkaXVzKSB7CglHTFVxdWFkcmljT2JqICpxb2JqOwoJCgkvLyBnbExvYWRJZGVudGl0eSgpOwoJCglnbFJvdGF0ZWYocm90VmFsLCAwLjBmLCAwLjBmLCAxLjBmKTsKCWdsVHJhbnNsYXRlZih4TnVtLCB5TnVtLCAwLjBmKTsKCQoJLy8gZ2xDYWxsTGlzdChzdGFydExpc3QpOwoJCglnbENsZWFyQ29sb3IoMC4wZiwgMC4wZiwgMC4wZiwgMC4wZik7CgkKCXFvYmogPSBnbHVOZXdRdWFkcmljKCk7CgkKCWdsdVF1YWRyaWNEcmF3U3R5bGUocW9iaiwgR0xVX1NJTEhPVUVUVEUpOwoJCglnbHVEaXNrIChxb2JqLCAwLjAsIHJhZGl1cywgMTAsIDEpOwoJCn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpkcmF3Q1N0cmluZ1dpdGhHTCAoY29uc3QgY2hhciogY29uc3QgY1N0cmluZywgY29uc3QgdWludDE2IHN0cmluZ0xlbmd0aCkgewojaWYgVEFSR0VUX09TX01BQwogICAgZm9yICh1aW50MTYgaSA9IDA7IGkgPCBzdHJpbmdMZW5ndGg7IGkrKykgewogICAgICAgIGdsdXRCaXRtYXBDaGFyYWN0ZXIoR0xVVF9CSVRNQVBfOF9CWV8xMywgY1N0cmluZ1tpXSk7CiAgICB9CiNlbmRpZgojaWYgVEFSR0VUX09TX1dJTgoJdGhpcy0+Z2xQcmludChjU3RyaW5nKTsKI2VuZGlmCn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpkb0ZhbGxiYWNrQWN0b3JTaG93KGNvbnN0IGNoYXIqIGNvbnN0IHZpc3VhbEFjdG9yTmFtZSkgewoJR0xkb3VibGUgeENvb3JkUG9zLCB5Q29vcmRQb3M7CiAgICBpbnQgbGVuOwoJY2hhciBmYWxsYmFja0FjdG9yU3RyaW5nWzEyOF07CglzdHJjcHkoZmFsbGJhY2tBY3RvclN0cmluZywgdmlzdWFsQWN0b3JOYW1lKTsKCXN0cmNhdChmYWxsYmFja0FjdG9yU3RyaW5nLCAiOiB1bmltcGxlbWVudGVkIHNob3coKSBtZXRob2QgaW4gVmlzdWFsQWN0b3IgaW1wbGVtZW50YXRpb24iKTsKCWxlbiA9IChpbnQpc3RybGVuKGZhbGxiYWNrQWN0b3JTdHJpbmcpOwoJCglWaXN1YWxDYW1lcmEqIGFDYW1lcmEgPSBWaXN1YWxDYW1lcmE6OmNyZWF0ZURlZmF1bHRDYW1lcmEoKTsKCXhDb29yZFBvcyA9IGFDYW1lcmEtPmdldE1heExlZnRDb29yZCgpICsgdGhpcy0+eFBpeGVsVG9Db29yZCgxMCwgKmFDYW1lcmEpOwoJeUNvb3JkUG9zID0gYUNhbWVyYS0+Z2V0TWF4Qm90dG9tQ29vcmQoKSArIHRoaXMtPnlQaXhlbFRvQ29vcmQoNjIsICphQ2FtZXJhKTsKCWRlbGV0ZSBhQ2FtZXJhOwoJZ2xDb2xvcjNkKDEuMCwgMS4wLCAwLjApOwoJZ2xSYXN0ZXJQb3MzZCh4Q29vcmRQb3MsIHlDb29yZFBvcywgMC4wKTsKICAgIHRoaXMtPmRyYXdDU3RyaW5nV2l0aEdMKGZhbGxiYWNrQWN0b3JTdHJpbmcsIGxlbik7Cn0KCgpmbG9hdCBWaXN1YWxHcmFwaGljczo6Z2V0Q29zVHdvVGltZXNQaSgpIHsKICAgIHJldHVybiAoZmxvYXQpKGNvcyAoMi4wZiAqIChmbG9hdClNX1BJKSk7Cn0KCgpmbG9hdCBWaXN1YWxHcmFwaGljczo6Z2V0U2luVHdvVGltZXNQaSgpIHsKICAgIHJldHVybiAoZmxvYXQpKHNpbiAoMi4wZiAqIChmbG9hdClNX1BJKSk7Cn0KCgp1aW50MzIgVmlzdWFsR3JhcGhpY3M6OmdldE5leHRGcmVlVGV4dHVyZU5hbWUoKSB7CglHTHVpbnQgYVRleHR1cmVOYW1lOwoJZ2xHZW5UZXh0dXJlcygxLCAmYVRleHR1cmVOYW1lKTsKCXJldHVybiAodWludDMyKWFUZXh0dXJlTmFtZTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmRlbGV0ZVRleHR1cmVzKGNvbnN0IHVpbnQxNiBudW1iZXJPZlRleHR1cmVzLCBjb25zdCB1aW50MzIqIGNvbnN0IHRleHR1cmVOYW1lcykgewoJZ2xEZWxldGVUZXh0dXJlcyhudW1iZXJPZlRleHR1cmVzLCAoR0x1aW50Kil0ZXh0dXJlTmFtZXMpOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6c2hvd1Byb2Nlc3NJbmZvUm93KENvb3JkIGNvb3JkLCBjb25zdCBjaGFyKiBjb25zdCB0ZXh0Um93U3RyKSB7CiAgICBpbnQgbGVuOwoJZ2xSYXN0ZXJQb3MzZChjb29yZC54LCBjb29yZC55LCBjb29yZC56KTsKICAgIGxlbiA9IChpbnQpc3RybGVuKHRleHRSb3dTdHIpOwogICAgdGhpcy0+ZHJhd0NTdHJpbmdXaXRoR0wodGV4dFJvd1N0ciwgbGVuKTsKfQoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OnNob3dQcm9jZXNzSW5mb05vdGUoKSB7CgljaGFyIG5vdGVTdHJbMTI4XTsKCUdMZG91YmxlIHhDb29yZFBvcywgeUNvb3JkUG9zOwoJZ2xDb2xvcjNkKDEuMCwgMS4wLCAxLjApOwoJc3RyY3B5KG5vdGVTdHIsICJQcmVzcyBbc10gb24gdGhlIGtleWJvYXJkIHRvIGhpZGUgUHJvY2VzcyBNb25pdG9yIEluZm8iKTsKCVZpc3VhbENhbWVyYSogYUNhbWVyYSA9IFZpc3VhbENhbWVyYTo6Y3JlYXRlRGVmYXVsdENhbWVyYSgpOwoJeENvb3JkUG9zID0gYUNhbWVyYS0+Z2V0TWF4TGVmdENvb3JkKCkgKyB0aGlzLT54UGl4ZWxUb0Nvb3JkKDEwLCAqYUNhbWVyYSk7Cgl5Q29vcmRQb3MgPSBhQ2FtZXJhLT5nZXRNYXhCb3R0b21Db29yZCgpICsgdGhpcy0+eVBpeGVsVG9Db29yZCgzNiwgKmFDYW1lcmEpOwoJZ2xSYXN0ZXJQb3MzZCh4Q29vcmRQb3MsIHlDb29yZFBvcywgMC4wKTsKCXRoaXMtPmRyYXdDU3RyaW5nV2l0aEdMKG5vdGVTdHIsIHN0cmxlbihub3RlU3RyKSk7CglzdHJjcHkobm90ZVN0ciwgIlByZXNzIFthXSBvbiB0aGUga2V5Ym9hcmQgdG8gaGlkZSBQcm9jZXNzIE1vbml0b3IgQXVkaW8gSW5mbyIpOwoJeENvb3JkUG9zID0gYUNhbWVyYS0+Z2V0TWF4TGVmdENvb3JkKCkgKyB0aGlzLT54UGl4ZWxUb0Nvb3JkKDEwLCAqYUNhbWVyYSk7Cgl5Q29vcmRQb3MgPSBhQ2FtZXJhLT5nZXRNYXhCb3R0b21Db29yZCgpICsgdGhpcy0+eVBpeGVsVG9Db29yZCgxOCwgKmFDYW1lcmEpOwoJZGVsZXRlIGFDYW1lcmE7CglnbFJhc3RlclBvczNkKHhDb29yZFBvcywgeUNvb3JkUG9zLCAwLjApOwoJdGhpcy0+ZHJhd0NTdHJpbmdXaXRoR0wobm90ZVN0ciwgc3RybGVuKG5vdGVTdHIpKTsKfQoKClBpeGVsQ29sb3IqIFZpc3VhbEdyYXBoaWNzOjpjbGlwUGl4ZWxEYXRhKGNvbnN0IFBpeGVsQ29sb3IqIGluUGl4ZWxEYXRhLCBjb25zdCBQaXhlbFJlY3QmIGluUGl4ZWxSZWN0LCBjb25zdCBUb3BMZWZ0UG9zaXRpb25lZFBpeGVsUmVjdCYgY2xpcFJlY3QpIHsKCXVpbnQ4IG51bWJlck9mQnl0ZXNQZXJQaXhlbCA9IDQ7CglQaXhlbENvbG9yKiBjbGlwcGVkUGl4ZWxEYXRhID0gKHVpbnQzMiopbWFsbG9jKGNsaXBSZWN0LnBpeGVsUmVjdC53aWR0aCAqIGNsaXBSZWN0LnBpeGVsUmVjdC5oZWlnaHQgKiBudW1iZXJPZkJ5dGVzUGVyUGl4ZWwpOwoJZm9yICh1aW50MzIgeSA9IGNsaXBSZWN0LnRvcExlZnRQaXhlbC55OyB5IDwgY2xpcFJlY3QucGl4ZWxSZWN0LmhlaWdodDsgeSsrKSB7CgkJZm9yICh1aW50MzIgeCA9IGNsaXBSZWN0LnRvcExlZnRQaXhlbC54OyB4IDwgY2xpcFJlY3QucGl4ZWxSZWN0LndpZHRoOyB4KyspIHsKCQkJY2xpcHBlZFBpeGVsRGF0YVt5ICogY2xpcFJlY3QucGl4ZWxSZWN0LndpZHRoICsgeF0gPSBpblBpeGVsRGF0YVt5ICogaW5QaXhlbFJlY3Qud2lkdGggKyB4XTsKCQl9Cgl9CglyZXR1cm4gY2xpcHBlZFBpeGVsRGF0YTsKfQoKCiNpZiBUQVJHRVRfT1NfTUFDCkNHQ29udGV4dFJlZiBWaXN1YWxHcmFwaGljczo6Y3JlYXRlQml0bWFwQ29udGV4dChzaXplX3QgcGl4ZWxXaWR0aCwgc2l6ZV90IHBpeGVsSGVpZ2h0KSB7CgkKCXNpemVfdCBiaXRzUGVyQ29tcG9uZW50ID0gODsKCQogICAgdWludDE2IGJpdG1hcEJ5dGVzUGVyUm93ID0gcGl4ZWxXaWR0aCAqIDQ7CiAgICB1aW50MzIgYml0bWFwQnl0ZUNvdW50ID0gYml0bWFwQnl0ZXNQZXJSb3cgKiBwaXhlbEhlaWdodDsKCQogICAgLy9DR0NvbG9yU3BhY2VSZWYgY29sb3JTcGFjZSA9IENHQ29sb3JTcGFjZUNyZWF0ZVdpdGhOYW1lKGtDR0NvbG9yU3BhY2VHZW5lcmljUkdCKTsKCUNHQ29sb3JTcGFjZVJlZiBjb2xvclNwYWNlID0gQ0dDb2xvclNwYWNlQ3JlYXRlRGV2aWNlUkdCKCk7IC8vIEluIE1hYyBPUyBYIHYxMC40IGFuZCBsYXRlciwgdGhpcyBjb2xvciBzcGFjZSBpcyBubyBsb25nZXIgZGV2aWNlLWRlcGVuZGVudCBhbmQgaXMgcmVwbGFjZWQgYnkgdGhlIGdlbmVyaWMgY291bnRlcnBhcnQglyBrQ0dDb2xvclNwYWNlR2VuZXJpY1JHQiAKCQogICAgdWludDgqIGJpdG1hcERhdGEgPSAodWludDgqKW1hbGxvYyhiaXRtYXBCeXRlQ291bnQpOwogICAgaWYgKGJpdG1hcERhdGEgPT0gTlVMTCkgewogICAgICAgIHdyaXRlTG9nKCJiaXRtYXBEYXRhIGlzIE5VTEwgaW4gY3JlYXRlQml0bWFwQ29udGV4dCIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoJbWVtc2V0KGJpdG1hcERhdGEsIDAsIGJpdG1hcEJ5dGVDb3VudCk7CgkKCUNHQml0bWFwSW5mbyBiaXRtYXBJbmZvID0gKGtDR0ltYWdlQWxwaGFQcmVtdWx0aXBsaWVkRmlyc3QgfCBrQ0dCaXRtYXBCeXRlT3JkZXIzMkhvc3QpOwoJQ0dDb250ZXh0UmVmIGNvbnRleHQgPSBDR0JpdG1hcENvbnRleHRDcmVhdGUoYml0bWFwRGF0YSwgcGl4ZWxXaWR0aCwgcGl4ZWxIZWlnaHQsIGJpdHNQZXJDb21wb25lbnQsIGJpdG1hcEJ5dGVzUGVyUm93LCBjb2xvclNwYWNlLCBiaXRtYXBJbmZvKTsKICAgIGlmIChjb250ZXh0ID09IE5VTEwpIHsKCQlmcmVlIChiaXRtYXBEYXRhKTsKICAgICAgICB3cml0ZUxvZygiY29udGV4dCBpcyBOVUxMIGluIGNyZWF0ZUJpdG1hcENvbnRleHQiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIENHQ29sb3JTcGFjZVJlbGVhc2UoY29sb3JTcGFjZSk7CgkKICAgIHJldHVybiBjb250ZXh0Owp9CiNlbmRpZgoKCmJvb2wgVmlzdWFsR3JhcGhpY3M6OmNvcHlBUkdCQml0bWFwRGF0YVRvVGV4dHVyZSh1aW50MzIgdGV4dHVyZU51bWJlciwgdWludDMyIGltYWdlV2lkdGgsIHVpbnQzMiBpbWFnZUhlaWdodCwgYm9vbCBjYW5Vc2VSZWN0RXh0ZW5zaW9uLCBjb25zdCBQaXhlbENvbG9yKiogYml0bWFwRGF0YSwgYm9vbCBkZWJ1ZykgewoJCglib29sIHN1Y2Nlc3MgPSB0cnVlOwoJCglHTHZvaWQqIGFyZ2JQaXhlbHMgPSBOVUxMOwoJCglpZiAoZGVidWcgPT0gdHJ1ZSkgewoJCWFyZ2JQaXhlbHMgPSAoR0x2b2lkKilWaXN1YWxDb2xvclRvb2xzOjpjcmVhdGVBUkdCQ2hlY2tQaXhlbHMoaW1hZ2VXaWR0aCwgaW1hZ2VIZWlnaHQpOwoJfSBlbHNlIHsKCQlhcmdiUGl4ZWxzID0gKEdMdm9pZCopKmJpdG1hcERhdGE7Cgl9CgkKCWlmIChjYW5Vc2VSZWN0RXh0ZW5zaW9uID09IGZhbHNlKSB7CgkJZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7Cgl9IGVsc2UgewojaWYgVEFSR0VUX09TX01BQwoJCWdsRW5hYmxlKEdMX1RFWFRVUkVfUkVDVEFOR0xFX0VYVCk7CiNlbmRpZgoJfQoJCglpZiAoY2FuVXNlUmVjdEV4dGVuc2lvbiA9PSBmYWxzZSkgewoJCWdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgKEdMdWludCl0ZXh0dXJlTnVtYmVyKTsKCQkKCQlnbFRleEVudmkoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX0RFQ0FMKTsKCQlnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX0NMQU1QKTsKCQlnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX0NMQU1QKTsKCQlnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9MSU5FQVIpOwoJCWdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX0xJTkVBUik7CgkJLy8gZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX0dFTkVSQVRFX01JUE1BUCwgR0xfRkFMU0UpOwoJCQoJfSBlbHNlIHsKI2lmIFRBUkdFVF9PU19NQUMKCQlnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfUkVDVEFOR0xFX0VYVCwgKEdMdWludCl0ZXh0dXJlTnVtYmVyKTsKI2VuZGlmCgl9CgkKCXRoaXMtPnNldFBpeGVsU3RvcmFnZVBhcmFtcygpOwoJCgkvLyBHTF9CR1JBL0dMX1VOU0lHTkVEX0JZVEUgYW5kIEdMX0JHUkEvR0xfVU5TSUdORURfSU5UXzhfOF84XzhfUkVWIGFyZSBlcXVpdmFsZW50IG9uIGxpdHRsZSBlbmRpYW4gbWFjaGluZXMKCQoJaWYgKGNhblVzZVJlY3RFeHRlbnNpb24gPT0gZmFsc2UpIHsKCQkKCQl1aW50MzIgcG90V2lkdGggPSB0aGlzLT5wb3dlcjJDZWlsaW5nKGltYWdlV2lkdGgpOwoJCXVpbnQzMiBwb3RIZWlnaHQgPSB0aGlzLT5wb3dlcjJDZWlsaW5nKGltYWdlSGVpZ2h0KTsKCQlQaXhlbENvbG9yKiBwb3dlck9mVHdvUGl4ZWxEYXRhID0gKFBpeGVsQ29sb3IqKWNhbGxvYyhwb3RXaWR0aCAqIHBvdEhlaWdodCwgc2l6ZW9mKFBpeGVsQ29sb3IpKTsKCQlnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwgR0xfUkdCQTgsIHBvdFdpZHRoLCBwb3RIZWlnaHQsIDAsIEdMX0JHUkEsIEdMX1VOU0lHTkVEX0JZVEUsIHBvd2VyT2ZUd29QaXhlbERhdGEpOwoJCWZyZWUocG93ZXJPZlR3b1BpeGVsRGF0YSk7CgkJCiNpZiBfX0JJR19FTkRJQU5fXwoJCVZpc3VhbENvbG9yVG9vbHM6OmNvbnZlcnRJbnRlcmxlYXZlZFBpeGVsczEyMzRUbzQzMjEoKFBpeGVsQ29sb3IqKWFyZ2JQaXhlbHMsIGltYWdlV2lkdGggKiBpbWFnZUhlaWdodCk7CiNlbmRpZgoJCQoJCWdsVGV4U3ViSW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCAwLCAwLCBpbWFnZVdpZHRoLCBpbWFnZUhlaWdodCwgR0xfQkdSQSwgR0xfVU5TSUdORURfQllURSwgYXJnYlBpeGVscyk7CgkJCgl9IGVsc2UgewojaWYgVEFSR0VUX09TX01BQwoJCWdsVGV4SW1hZ2UyRChHTF9URVhUVVJFX1JFQ1RBTkdMRV9FWFQsIDAsIEdMX1JHQkEsIGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0LCAwLCBHTF9CR1JBLCBHTF9VTlNJR05FRF9JTlRfOF84XzhfOF9SRVYsIGFyZ2JQaXhlbHMpOwojZW5kaWYKCX0KCQoJaWYgKGNhblVzZVJlY3RFeHRlbnNpb24gPT0gZmFsc2UpIHsKCQlnbERpc2FibGUgKEdMX1RFWFRVUkVfMkQpOwoJfSBlbHNlIHsKI2lmIFRBUkdFVF9PU19NQUMKCQlnbERpc2FibGUgKEdMX1RFWFRVUkVfUkVDVEFOR0xFX0VYVCk7CiNlbmRpZgoJfQoJCglpZiAoZGVidWcgPT0gdHJ1ZSkgewoJCWZyZWUoYXJnYlBpeGVscyk7Cgl9CgkKCXJldHVybiBzdWNjZXNzOwoJCn0KCgojaWYgVEFSR0VUX09TX1dJTgoKCnZvaWQgVmlzdWFsR3JhcGhpY3M6OmJ1aWxkRm9udCgpCQkJCQkJCQkvLyBCdWlsZCBPdXIgQml0bWFwIEZvbnQKewoJSEZPTlQJZm9udDsJCQkJCQkJCQkJLy8gV2luZG93cyBGb250IElECglIRk9OVAlvbGRmb250OwkJCQkJCQkJCS8vIFVzZWQgRm9yIEdvb2QgSG91c2UgS2VlcGluZwoJCgliYXNlID0gZ2xHZW5MaXN0cyg5Nik7CQkJCQkJCQkvLyBTdG9yYWdlIEZvciA5NiBDaGFyYWN0ZXJzCgkKCWZvbnQgPSBDcmVhdGVGb250KAktMTUsCQkJCQkJCS8vIEhlaWdodCBPZiBGb250CgkJCQkJICAwLAkJCQkJCQkJLy8gV2lkdGggT2YgRm9udAoJCQkJCSAgMCwJCQkJCQkJCS8vIEFuZ2xlIE9mIEVzY2FwZW1lbnQKCQkJCQkgIDAsCQkJCQkJCQkvLyBPcmllbnRhdGlvbiBBbmdsZQoJCQkJCSAgRldfTk9STUFMLAkJCQkJCS8vIEZvbnQgV2VpZ2h0CgkJCQkJICBGQUxTRSwJCQkJCQkJLy8gSXRhbGljCgkJCQkJICBGQUxTRSwJCQkJCQkJLy8gVW5kZXJsaW5lCgkJCQkJICBGQUxTRSwJCQkJCQkJLy8gU3RyaWtlb3V0CgkJCQkJICBBTlNJX0NIQVJTRVQsCQkJCQkvLyBDaGFyYWN0ZXIgU2V0IElkZW50aWZpZXIKCQkJCQkgIE9VVF9UVF9QUkVDSVMsCQkJCQkvLyBPdXRwdXQgUHJlY2lzaW9uCgkJCQkJICBDTElQX0RFRkFVTFRfUFJFQ0lTLAkJCS8vIENsaXBwaW5nIFByZWNpc2lvbgoJCQkJCSAgREVGQVVMVF9RVUFMSVRZLAkJCS8vIE91dHB1dCBRdWFsaXR5CgkJCQkJICBGRl9ET05UQ0FSRXxERUZBVUxUX1BJVENILAkJLy8gRmFtaWx5IEFuZCBQaXRjaAoJCQkJCSAgIkFyaWFsIik7CQkJCQkvLyBGb250IE5hbWUKCQoJVmlzdWFsR3JhcGhpY3NDb3JlKiB0aGVWaXN1YWxHcmFwaGljc0NvcmU7Cgl0aGVWaXN1YWxHcmFwaGljc0NvcmUgPSBWaXN1YWxHcmFwaGljc0NvcmU6OmdldEluc3RhbmNlKCk7CgkKCW9sZGZvbnQgPSAoSEZPTlQpU2VsZWN0T2JqZWN0KHRoZVZpc3VhbEdyYXBoaWNzQ29yZS0+Z2V0V2luZG93REMoKSwgZm9udCk7ICAgICAgICAgICAvLyBTZWxlY3RzIFRoZSBGb250IFdlIFdhbnQKCXdnbFVzZUZvbnRCaXRtYXBzKHRoZVZpc3VhbEdyYXBoaWNzQ29yZS0+Z2V0V2luZG93REMoKSwgMzIsIDk2LCBiYXNlKTsJCQkJLy8gQnVpbGRzIDk2IENoYXJhY3RlcnMgU3RhcnRpbmcgQXQgQ2hhcmFjdGVyIDMyCglTZWxlY3RPYmplY3QodGhlVmlzdWFsR3JhcGhpY3NDb3JlLT5nZXRXaW5kb3dEQygpLCBvbGRmb250KTsJCQkJCQkJLy8gU2VsZWN0cyBUaGUgRm9udCBXZSBXYW50CglEZWxldGVPYmplY3QoZm9udCk7CQkJCQkJCQkJLy8gRGVsZXRlIFRoZSBGb250Cn0KCgp2b2lkIFZpc3VhbEdyYXBoaWNzOjpraWxsRm9udCh2b2lkKSB7CgkvLyBEZWxldGUgQWxsIDk2IENoYXJhY3RlcnMKCWdsRGVsZXRlTGlzdHMoYmFzZSwgOTYpOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6Z2xQcmludChjb25zdCBjaGFyICpmbXQsIC4uLikgewoJLy8gQ3VzdG9tIEdMICJQcmludCIgUm91dGluZQoJY2hhcgkJdGV4dFsyNTZdOwkJCQkJCQkJLy8gSG9sZHMgT3VyIFN0cmluZwoJdmFfbGlzdAkJYXA7CQkJCQkJCQkJCS8vIFBvaW50ZXIgVG8gTGlzdCBPZiBBcmd1bWVudHMKCQoJaWYgKGZtdCA9PSBOVUxMKQkJCQkJCQkJCS8vIElmIFRoZXJlJ3MgTm8gVGV4dAoJCXJldHVybjsJCQkJCQkJCQkJCS8vIERvIE5vdGhpbmcKCQoJdmFfc3RhcnQoYXAsIGZtdCk7CQkJCQkJCQkJLy8gUGFyc2VzIFRoZSBTdHJpbmcgRm9yIFZhcmlhYmxlcwoJdnNwcmludGYodGV4dCwgZm10LCBhcCk7CQkJCQkJLy8gQW5kIENvbnZlcnRzIFN5bWJvbHMgVG8gQWN0dWFsIE51bWJlcnMKCXZhX2VuZChhcCk7CQkJCQkJCQkJCQkvLyBSZXN1bHRzIEFyZSBTdG9yZWQgSW4gVGV4dAoJCglnbFB1c2hBdHRyaWIoR0xfTElTVF9CSVQpOwkJCQkJCQkvLyBQdXNoZXMgVGhlIERpc3BsYXkgTGlzdCBCaXRzCglnbExpc3RCYXNlKGJhc2UgLSAzMik7CQkJCQkJCQkvLyBTZXRzIFRoZSBCYXNlIENoYXJhY3RlciB0byAzMgoJZ2xDYWxsTGlzdHMoc3RybGVuKHRleHQpLCBHTF9VTlNJR05FRF9CWVRFLCB0ZXh0KTsJLy8gRHJhd3MgVGhlIERpc3BsYXkgTGlzdCBUZXh0CglnbFBvcEF0dHJpYigpOwkJCQkJCQkJCQkvLyBQb3BzIFRoZSBEaXNwbGF5IExpc3QgQml0cwoJCn0KCiNlbmRpZgoKCmNvbnN0IGNoYXIqIGNvbnN0IFZpc3VhbEdyYXBoaWNzOjpnZXRSZW5kZXJlck5hbWUoKSB7CglyZXR1cm4gdGhpcy0+Y2FwYWJpbGl0aWVzLnN0clJlbmRlcmVyTmFtZTsKfQoKCmNvbnN0IGNoYXIqIGNvbnN0IFZpc3VhbEdyYXBoaWNzOjpnZXRSZW5kZXJlclZlbmRvcigpIHsKCXJldHVybiB0aGlzLT5jYXBhYmlsaXRpZXMuc3RyUmVuZGVyZXJWZW5kb3I7Cn0KCgpjb25zdCBjaGFyKiBjb25zdCBWaXN1YWxHcmFwaGljczo6Z2V0UmVuZGVyZXJWZXJzaW9uKCkgewoJcmV0dXJuIHRoaXMtPmNhcGFiaWxpdGllcy5zdHJSZW5kZXJlclZlcnNpb247Cn0KCgp1bnNpZ25lZCBzaG9ydCBWaXN1YWxHcmFwaGljczo6Z2V0R0xWZXJzaW9uKCkgewoJcmV0dXJuIHRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb247Cn0KCgpsb25nIFZpc3VhbEdyYXBoaWNzOjpnZXRNYXhUZXh0dXJlU2l6ZSgpIHsKCXJldHVybiAobG9uZyl0aGlzLT5jYXBhYmlsaXRpZXMubWF4VGV4dHVyZVNpemU7Cn0KCgpkb3VibGUgVmlzdWFsR3JhcGhpY3M6OnhQaXhlbFRvQ29vcmQodWludDMyIHBpeGVsUG9zLCBjb25zdCBWaXN1YWxDYW1lcmEmIGFDYW1lcmEpIHsKCUNvb3JkU2l6ZTNEIHNpemUgPSBhQ2FtZXJhLmdldFNpemUoKTsKCXJldHVybiAoKGRvdWJsZSlwaXhlbFBvcyAqIChzaXplLndpZHRoIC8gKGRvdWJsZSl0aGlzLT5nZXRDYW52YXNQaXhlbFdpZHRoKCkpKTsKfQoKCmRvdWJsZSBWaXN1YWxHcmFwaGljczo6eVBpeGVsVG9Db29yZCh1aW50MzIgcGl4ZWxQb3MsIGNvbnN0IFZpc3VhbENhbWVyYSYgYUNhbWVyYSkgewoJQ29vcmRTaXplM0Qgc2l6ZSA9IGFDYW1lcmEuZ2V0U2l6ZSgpOwoJcmV0dXJuICgoZG91YmxlKXBpeGVsUG9zICogKHNpemUuaGVpZ2h0IC8gKGRvdWJsZSl0aGlzLT5nZXRDYW52YXNQaXhlbEhlaWdodCgpKSk7Cn0KCgp1aW50MTYgVmlzdWFsR3JhcGhpY3M6OnhDb29yZFRvUGl4ZWwoZG91YmxlIGNvb3JkUG9zLCBjb25zdCBWaXN1YWxDYW1lcmEmIGFDYW1lcmEpIHsKCUNvb3JkU2l6ZTNEIHNpemUgPSBhQ2FtZXJhLmdldFNpemUoKTsKCVZpc3VhbEdyYXBoaWNzQ29yZSogdGhlVmlzdWFsR3JhcGhpY3NDb3JlOwoJdGhlVmlzdWFsR3JhcGhpY3NDb3JlID0gVmlzdWFsR3JhcGhpY3NDb3JlOjpnZXRJbnN0YW5jZSgpOwoJZG91YmxlIHRlbXBDb29yZCA9IGNvb3JkUG9zICsgKHNpemUud2lkdGggLyAyLjApOwoJCglyZXR1cm4gKHVpbnQxNikodGVtcENvb3JkICogKChkb3VibGUpdGhpcy0+Z2V0Q2FudmFzUGl4ZWxXaWR0aCgpIC8gc2l6ZS53aWR0aCkpOwp9CgoKdWludDE2IFZpc3VhbEdyYXBoaWNzOjp5Q29vcmRUb1BpeGVsKGRvdWJsZSBjb29yZFBvcywgY29uc3QgVmlzdWFsQ2FtZXJhJiBhQ2FtZXJhKSB7CglDb29yZFNpemUzRCBzaXplID0gYUNhbWVyYS5nZXRTaXplKCk7CglWaXN1YWxHcmFwaGljc0NvcmUqIHRoZVZpc3VhbEdyYXBoaWNzQ29yZTsKCXRoZVZpc3VhbEdyYXBoaWNzQ29yZSA9IFZpc3VhbEdyYXBoaWNzQ29yZTo6Z2V0SW5zdGFuY2UoKTsKCWRvdWJsZSB0ZW1wQ29vcmQgPSBjb29yZFBvcyArIChzaXplLmhlaWdodCAvIDIuMCk7CgkKCXJldHVybiAodWludDE2KSh0ZW1wQ29vcmQgKiAoKGRvdWJsZSl0aGlzLT5nZXRDYW52YXNQaXhlbEhlaWdodCgpIC8gc2l6ZS5oZWlnaHQpKTsKfQoKCmJvb2wgVmlzdWFsR3JhcGhpY3M6OmdldENvb3Jkc09mUGl4ZWxQb3NpdGlvbigKCQkJCQkJCQkJCQkgIGRvdWJsZSB4UGl4ZWxQb3MsIAoJCQkJCQkJCQkJCSAgZG91YmxlIHlQaXhlbFBvcywgCgkJCQkJCQkJCQkJICBkb3VibGUgekF4aXNQb3MsIAoJCQkJCQkJCQkJCSAgZG91YmxlKiB4Q29vcmRQb3MsCgkJCQkJCQkJCQkJICBkb3VibGUqIHlDb29yZFBvcywKCQkJCQkJCQkJCQkgIGRvdWJsZSogekNvb3JkUG9zKSB7Cglib29sIHN1Y2Nlc3MgPSBmYWxzZTsKCQoJR0xkb3VibGUgbW9kZWx2aWV3TWF0cml4WzE2XTsKCUdMZG91YmxlIHByb2plY3Rpb25NYXRyaXhbMTZdOwoJR0xpbnQgdmlld3BvcnRbNF07CglHTGludCByZXRWYWw7CglnbEdldERvdWJsZXYoR0xfTU9ERUxWSUVXX01BVFJJWCwgbW9kZWx2aWV3TWF0cml4KTsKCWdsR2V0RG91YmxldihHTF9QUk9KRUNUSU9OX01BVFJJWCwgcHJvamVjdGlvbk1hdHJpeCk7CglnbEdldEludGVnZXJ2KEdMX1ZJRVdQT1JULCB2aWV3cG9ydCk7CglyZXRWYWwgPSBnbHVVblByb2plY3QoeFBpeGVsUG9zLAoJCQkJCQkgIHlQaXhlbFBvcywKCQkJCQkJICB6QXhpc1BvcywKCQkJCQkJICBtb2RlbHZpZXdNYXRyaXgsCgkJCQkJCSAgcHJvamVjdGlvbk1hdHJpeCwKCQkJCQkJICB2aWV3cG9ydCwKCQkJCQkJICB4Q29vcmRQb3MsCgkJCQkJCSAgeUNvb3JkUG9zLAoJCQkJCQkgIHpDb29yZFBvcyk7CglpZiAocmV0VmFsID09IEdMX1RSVUUpIHsKCQlzdWNjZXNzID0gdHJ1ZTsKCX0KCXJldHVybiBzdWNjZXNzOwp9CgoKYm9vbCBWaXN1YWxHcmFwaGljczo6Z2V0UGl4ZWxzT2ZDb29yZFBvc2l0aW9uKAoJCQkJCQkJCQkJCSAgZG91YmxlIHhDb29yZFBvcywKCQkJCQkJCQkJCQkgIGRvdWJsZSB5Q29vcmRQb3MsCgkJCQkJCQkJCQkJICBkb3VibGUgekNvb3JkUG9zLAoJCQkJCQkJCQkJCSAgZG91YmxlKiB4UGl4ZWxQb3MsIAoJCQkJCQkJCQkJCSAgZG91YmxlKiB5UGl4ZWxQb3MsIAoJCQkJCQkJCQkJCSAgZG91YmxlKiB6QXhpc1BvcykgewoJYm9vbCBzdWNjZXNzID0gZmFsc2U7CgkKCUdMZG91YmxlIG1vZGVsdmlld01hdHJpeFsxNl07CglHTGRvdWJsZSBwcm9qZWN0aW9uTWF0cml4WzE2XTsKCUdMaW50IHZpZXdwb3J0WzRdOwoJR0xpbnQgcmV0VmFsOwoJZ2xHZXREb3VibGV2KEdMX01PREVMVklFV19NQVRSSVgsIG1vZGVsdmlld01hdHJpeCk7CglnbEdldERvdWJsZXYoR0xfUFJPSkVDVElPTl9NQVRSSVgsIHByb2plY3Rpb25NYXRyaXgpOwoJZ2xHZXRJbnRlZ2VydihHTF9WSUVXUE9SVCwgdmlld3BvcnQpOwoJLyoJCgkgZm9yIChpbnQgaSA9IDA7IGkgPCAxNjsgaSsrKSB7CgkgcHJpbnRmKCJtb2RlbHZpZXdNYXRyaXg6ICUuMmZcbiIsIG1vZGVsdmlld01hdHJpeFtpXSk7CgkgfQoJIAoJIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgewoJIHByaW50ZigicHJvamVjdGlvbk1hdHJpeDogJS4yZlxuIiwgcHJvamVjdGlvbk1hdHJpeFtpXSk7CgkgfQoJIAoJIGZvciAoaW50IGkgPSAwOyBpIDwgNDsgaSsrKSB7CgkgcHJpbnRmKCJ2aWV3cG9ydDogJWRcbiIsIHZpZXdwb3J0W2ldKTsKCSB9CgkgKi8JCglyZXRWYWwgPSBnbHVQcm9qZWN0KHhDb29yZFBvcywKCQkJCQkJeUNvb3JkUG9zLAoJCQkJCQl6Q29vcmRQb3MsCgkJCQkJCW1vZGVsdmlld01hdHJpeCwKCQkJCQkJcHJvamVjdGlvbk1hdHJpeCwKCQkJCQkJdmlld3BvcnQsCgkJCQkJCXhQaXhlbFBvcywKCQkJCQkJeVBpeGVsUG9zLAoJCQkJCQl6QXhpc1Bvcyk7CglpZiAocmV0VmFsID09IEdMX1RSVUUpIHsKCQlzdWNjZXNzID0gdHJ1ZTsKCX0KCXJldHVybiBzdWNjZXNzOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6Z2F0aGVyT3BlbkdMQ2FwYWJpbGl0aWVzKCkgewoJCgljb25zdCBHTHVieXRlKiBzdHJFeHQ7CgkKCWNvbnN0IEdMdWJ5dGUqIHN0clJlbmQ7Cgljb25zdCBHTHVieXRlKiBzdHJWZXJzOwoJY29uc3QgR0x1Ynl0ZSogc3RyVmVuZDsKCQoJR0xpbnQgbWF4VGV4dHVyZVNpemU7CgkKCXRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb24gPSAwOwoJCgkvLyBnZXQgcmVuZGVyZXIgc3RyaW5ncwoJc3RyUmVuZCA9IGdsR2V0U3RyaW5nIChHTF9SRU5ERVJFUik7CglzdHJuY3B5ICh0aGlzLT5jYXBhYmlsaXRpZXMuc3RyUmVuZGVyZXJOYW1lLCAoY2hhciopc3RyUmVuZCwgMjU1KTsKCXN0clZlbmQgPSBnbEdldFN0cmluZyAoR0xfVkVORE9SKTsKCXN0cm5jcHkgKHRoaXMtPmNhcGFiaWxpdGllcy5zdHJSZW5kZXJlclZlbmRvciwgKGNoYXIqKXN0clZlbmQsIDI1NSk7CglzdHJWZXJzID0gZ2xHZXRTdHJpbmcgKEdMX1ZFUlNJT04pOwoJc3RybmNweSAodGhpcy0+Y2FwYWJpbGl0aWVzLnN0clJlbmRlcmVyVmVyc2lvbiwgKGNoYXIqKXN0clZlcnMsIDI1NSk7Cgl7IC8vIGdldCBCQ0QgdmVyc2lvbgoJCXNob3J0IGogPSAwOwoJCXNob3J0IHNoaWZ0VmFsID0gODsKCQl3aGlsZSAoKChzdHJWZXJzW2pdIDw9ICc5JykgJiYgKHN0clZlcnNbal0gPj0gJzAnKSkgfHwgKHN0clZlcnNbal0gPT0gJy4nKSkgeyAKCQkJLy8gZ2V0IG9ubHkgYmFzaWMgdmVyc2lvbiBpbmZvICh1bnRpbCBmaXJzdCBub24tZGlnaXQgb3Igbm9uLS4pCgkJCWlmICgoc3RyVmVyc1tqXSA8PSAnOScpICYmIChzdHJWZXJzW2pdID49ICcwJykpIHsKCQkJCXRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb24gKz0gKHN0clZlcnNbal0gLSAnMCcpIDw8IHNoaWZ0VmFsOwoJCQkJc2hpZnRWYWwgLT0gNDsKCQkJfQoJCQlqKys7CgkJfQoJfQoJCglzdHJFeHQgPSBnbEdldFN0cmluZyAoR0xfRVhURU5TSU9OUyk7CgkvL3dyaXRlTG9nKChjaGFyKilzdHJFeHQpOwoJCgkvKgoJIHVpbnQxNiBjbnQgPSAwOwoJIGNoYXIqIHRva2VuID0gTlVMTDsKCSBjaGFyKiB0ZXh0PShjaGFyICopbWFsbG9jKHN0cmxlbigoY2hhciAqKWdsR2V0U3RyaW5nKEdMX0VYVEVOU0lPTlMpKSsxKTsJLy8gQWxsb2NhdGUgTWVtb3J5IEZvciBPdXIgRXh0ZW5zaW9uIFN0cmluZwoJIHN0cmNweSAodGV4dCwoY2hhciAqKWdsR2V0U3RyaW5nKEdMX0VYVEVOU0lPTlMpKTsJCS8vIEdyYWIgVGhlIEV4dGVuc2lvbiBMaXN0LCBTdG9yZSBJbiBUZXh0CgkgCgkgdG9rZW49c3RydG9rKHRleHQsIiAiKTsJCQkJCQkJCQkvLyBQYXJzZSAndGV4dCcgRm9yIFdvcmRzLCBTZXBlcmF0ZWQgQnkgIiAiIChzcGFjZXMpCgkgdWludDE2IG1heHRva2VucyA9IDgwOwoJIHdoaWxlKHRva2VuIT1OVUxMKQkJCQkJCQkJCQkvLyBXaGlsZSBUaGUgVG9rZW4gSXNuJ3QgTlVMTAoJIHsKCSAKCSAvL2dsQ29sb3IzZigwLjVmLDEuMGYsMC41Zik7CQkJCQkJCS8vIFNldCBDb2xvciBUbyBCcmlnaHQgR3JlZW4KCSAvL2dsUHJpbnQoMCw5NisoY250KjMyKS1zY3JvbGwsMCwiJWkiLGNudCk7CQkJLy8gUHJpbnQgQ3VycmVudCBFeHRlbnNpb24gTnVtYmVyCgkgLy9nbENvbG9yM2YoMS4wZiwxLjBmLDAuNWYpOwkJCQkJCQkvLyBTZXQgQ29sb3IgVG8gWWVsbG93CgkgLy9nbFByaW50KDUwLDk2KyhjbnQqMzIpLXNjcm9sbCwwLHRva2VuKTsJCQkJLy8gUHJpbnQgVGhlIEN1cnJlbnQgVG9rZW4gKFBhcnNlZCBFeHRlbnNpb24gTmFtZSkKCSB3cml0ZUxvZyh0b2tlbik7CgkgdG9rZW49c3RydG9rKE5VTEwsIiAiKTsJCQkJCQkJCS8vIFNlYXJjaCBGb3IgVGhlIE5leHQgVG9rZW4KCSBjbnQrKzsJCQkJCQkJCQkJCQkvLyBJbmNyZWFzZSBUaGUgQ291bnRlcgoJIGlmIChjbnQ+bWF4dG9rZW5zKQkJCQkJCQkJCS8vIElzICdtYXh0b2tlbnMnIExlc3MgVGhhbiAnY250JwoJIHsKCSB0b2tlbiA9IE5VTEw7CQkJCQkJCQkJLy8gSWYgU28sIFNldCAnbWF4dG9rZW5zJyBFcXVhbCBUbyAnY250JwoJIH0KCSB9CgkgKi8KCQoJCgkKCWdsR2V0SW50ZWdlcnYgKEdMX01BWF9URVhUVVJFX1NJWkUsICZtYXhUZXh0dXJlU2l6ZSk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMubWF4VGV4dHVyZVNpemUgPSAobG9uZyltYXhUZXh0dXJlU2l6ZTsKCQoJLy8gZ2V0IGNhcHMKI2lmIFRBUkdFVF9PU19NQUMKCWdsR2V0SW50ZWdlcnYgKEdMX01BWF9URVhUVVJFX1VOSVRTLCAKCQkJCSAgIChHTGludCopJnRoaXMtPmNhcGFiaWxpdGllcy50ZXh0dXJlVW5pdHMpOwoJZ2xHZXRJbnRlZ2VydiAoR0xfTUFYXzNEX1RFWFRVUkVfU0laRSwgCgkJCQkgICAoR0xpbnQqKSZ0aGlzLT5jYXBhYmlsaXRpZXMubWF4M0RUZXh0dXJlU2l6ZSk7CglnbEdldEludGVnZXJ2IChHTF9NQVhfQ1VCRV9NQVBfVEVYVFVSRV9TSVpFLCAKCQkJCSAgIChHTGludCopJnRoaXMtPmNhcGFiaWxpdGllcy5tYXhDdWJlTWFwVGV4dHVyZVNpemUpOwoJCgkvLyBnZXQgZnVuY3Rpb25hbGl0eSBpbmZvCgl0aGlzLT5jYXBhYmlsaXRpZXMuZlNwZWN1bGFyVmVjdG9yID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUFBMRV9zcGVjdWxhcl92ZWN0b3IiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZUcmFuc2Zvcm1IaW50ID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUFBMRV90cmFuc2Zvcm1faGludCIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlBhY2tlZFBpeGVscyA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVBQTEVfcGFja2VkX3BpeGVscyIsIHN0ckV4dCkgfHwgCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUFBMRV9wYWNrZWRfcGl4ZWwiLCBzdHJFeHQpICB8fCAKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDEyMCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkNsaWVudFN0b3JhZ2UgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FQUExFX2NsaWVudF9zdG9yYWdlIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mWUNiQ3IgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FQUExFX3ljYmNyXzQyMiIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlRleHR1cmVSYW5nZSA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVBQTEVfdGV4dHVyZV9yYW5nZSIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkZlbmNlID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUFBMRV9mZW5jZSIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlZBUiA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVBQTEVfdmVydGV4X2FycmF5X3JhbmdlIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mVkFPID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUFBMRV92ZXJ0ZXhfYXJyYXlfb2JqZWN0Iiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mRWxlbWVudEFycmF5ID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUFBMRV9lbGVtZW50X2FycmF5Iiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mVlBFdmFscyA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24oKEdMdWJ5dGUqKSJHTF9BUFBMRV92ZXJ0ZXhfcHJvZ3JhbV9ldmFsdWF0b3JzIixzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZGbG9hdFBpeGVscyA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVBQTEVfZmxvYXRfcGl4ZWxzIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mRmx1c2hSZW5kZXJlciA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVBQTEVfZmx1c2hfcmVuZGVyIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mUGl4ZWxCdWZmZXIgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FQUExFX3BpeGVsX2J1ZmZlciIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkltYWdpbmcgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl9pbWFnaW5nIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mVHJhbnNwb3NlTWF0cml4ID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfdHJhbnNwb3NlX21hdHJpeCIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDEzMCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZk11bHRpdGV4dHVyZSA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVJCX211bHRpdGV4dHVyZSIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDEzMCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlRleEVudkFkZCA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVJCX3RleHR1cmVfZW52X2FkZCIsIHN0ckV4dCkgfHwKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF90ZXh0dXJlX2Vudl9hZGQiLCBzdHJFeHQpIHx8CgkodGhpcy0+Y2FwYWJpbGl0aWVzLmdsVmVyc2lvbiA+PSAweDAxMzApOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZUZXhFbnZDb21iaW5lID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfdGV4dHVyZV9lbnZfY29tYmluZSIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDEzMCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlRleEVudkRvdDMgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl90ZXh0dXJlX2Vudl9kb3QzIiwgc3RyRXh0KSB8fAoJKHRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb24gPj0gMHgwMTMwKTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mVGV4RW52Q3Jvc3NiYXIgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl90ZXh0dXJlX2Vudl9jcm9zc2JhciIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDE0MCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlRleEN1YmVNYXAgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl90ZXh0dXJlX2N1YmVfbWFwIiwgc3RyRXh0KSB8fAoJKHRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb24gPj0gMHgwMTMwKTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mVGV4Q29tcHJlc3MgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl90ZXh0dXJlX2NvbXByZXNzaW9uIiwgc3RyRXh0KSB8fAoJKHRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb24gPj0gMHgwMTMwKTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mTXVsdGlzYW1wbGUgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl9tdWx0aXNhbXBsZSIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDEzMCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlRleEJvcmRlckNsYW1wID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfdGV4dHVyZV9ib3JkZXJfY2xhbXAiLCBzdHJFeHQpIHx8CgkodGhpcy0+Y2FwYWJpbGl0aWVzLmdsVmVyc2lvbiA+PSAweDAxMzApOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZQb2ludFBhcmFtID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfcG9pbnRfcGFyYW1ldGVycyIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDE0MCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlZlcnRleFByb2cgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl92ZXJ0ZXhfcHJvZ3JhbSIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkZyYWdtZW50UHJvZyA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVJCX2ZyYWdtZW50X3Byb2dyYW0iLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZUZXhNaXJyb3JSZXBlYXQgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl90ZXh0dXJlX21pcnJvcmVkX3JlcGVhdCIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDE0MCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkRlcHRoVGV4ID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfZGVwdGhfdGV4dHVyZSIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDE0MCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlNoYWRvdyA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVJCX3NoYWRvdyIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDE0MCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlNoYWRvd0FtYmllbnQgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl9zaGFkb3dfYW1iaWVudCIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlZlcnRleEJsZW5kID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfdmVydGV4X2JsZW5kIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mV2luZG93UG9zID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfd2luZG93X3BvcyIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDE0MCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlRleDNEID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9FWFRfdGV4dHVyZTNEIiwgc3RyRXh0KSB8fAoJKHRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb24gPj0gMHgwMTIwKTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mQ2xpcFZvbEhpbnQgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF9jbGlwX3ZvbHVtZV9oaW50Iiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mUmVzY2FsZU5vcm0gPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF9yZXNjYWxlX25vcm1hbCIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDEyMCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkJsZW5kQ29sb3IgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF9ibGVuZF9jb2xvciIsIHN0ckV4dCkgfHwKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl9pbWFnaW5nIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mQmxlbmRNaW5NYXggPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF9ibGVuZF9taW5tYXgiLCBzdHJFeHQpIHx8CglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfaW1hZ2luZyIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkJsZW5kU3ViID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9FWFRfYmxlbmRfc3VidHJhY3QiLCBzdHJFeHQpIHx8CglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfaW1hZ2luZyIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkNWQSA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfRVhUX2NvbXBpbGVkX3ZlcnRleF9hcnJheSIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlRleExPREJpYXMgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF90ZXh0dXJlX2xvZF9iaWFzIiwgc3RyRXh0KSB8fAoJKHRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb24gPj0gMHgwMTQwKTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mQUJHUiA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfRVhUX2FiZ3IiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZCR1JBID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9FWFRfYmdyYSIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDEyMCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlRleEZpbHRlckFuaXNvID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9FWFRfdGV4dHVyZV9maWx0ZXJfYW5pc290cm9waWMiLHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlBhbGV0dGVUZXggPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF9wYWxldHRlZF90ZXh0dXJlIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mU2hhcmVUZXhQYWxldHRlID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9FWFRfc2hhcmVkX3RleHR1cmVfcGFsZXR0ZSIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlNlY0NvbG9yID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9FWFRfc2Vjb25kYXJ5X2NvbG9yIiwgc3RyRXh0KSB8fAoJKHRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb24gPj0gMHgwMTQwKTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mVGV4Q29tcHJlc3NTM1RDID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9FWFRfdGV4dHVyZV9jb21wcmVzc2lvbl9zM3RjIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mVGV4UmVjdCA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfRVhUX3RleHR1cmVfcmVjdGFuZ2xlIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mRm9nQ29vcmQgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF9mb2dfY29vcmQiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZEcmF3UmFuZ2VFbGVtZW50cyA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfRVhUX2RyYXdfcmFuZ2VfZWxlbWVudHMiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZTdGVuY2lsV3JhcCA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfRVhUX3N0ZW5jaWxfd3JhcCIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDE0MCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkJsZW5kRnVuY1NlcCA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfRVhUX2JsZW5kX2Z1bmNfc2VwYXJhdGUiLCBzdHJFeHQpIHx8CgkodGhpcy0+Y2FwYWJpbGl0aWVzLmdsVmVyc2lvbiA+PSAweDAxNDApOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZNdWx0aURyYXdBcnJheXMgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF9tdWx0aV9kcmF3X2FycmF5cyIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDE0MCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlNoYWRvd0Z1bmMgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF9zaGFkb3dfZnVuY3MiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZTdGVuY2lsMlNpZGUgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF9zdGVuY2lsX3R3b19zaWRlIiwgc3RyRXh0KSB8fAoJKHRoaXMtPmNhcGFiaWxpdGllcy5nbFZlcnNpb24gPj0gMHgwMTQwKTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mQ29sb3JTdWJ0YWJsZSA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfRVhUX2NvbG9yX3N1YnRhYmxlIiwgc3RyRXh0KSB8fCAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl9pbWFnaW5nIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mQ29udm9sdXRpb24gPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0VYVF9jb252b2x1dGlvbiIsIHN0ckV4dCkgfHwgCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfaW1hZ2luZyIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkhpc3RvZ3JhbSA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfRVhUX2hpc3RvZ3JhbSIsIHN0ckV4dCkgfHwgCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfaW1hZ2luZyIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkNvbG9yVGFibGUgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX1NHSV9jb2xvcl90YWJsZSIsIHN0ckV4dCkgfHwgCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfaW1hZ2luZyIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkNvbG9yTWF0cml4ID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9TR0lfY29sb3JfbWF0cml4Iiwgc3RyRXh0KSB8fCAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FSQl9pbWFnaW5nIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mVGV4RWRnZUNsYW1wID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9TR0lTX3RleHR1cmVfZWRnZV9jbGFtcCIsIHN0ckV4dCkgfHwKCSh0aGlzLT5jYXBhYmlsaXRpZXMuZ2xWZXJzaW9uID49IDB4MDEyMCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkdlbk1pcG1hcCA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfU0dJU19nZW5lcmF0ZV9taXBtYXAiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZUZXhMT0QgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX1NHSVNfdGV4dHVyZV9sb2QiLCBzdHJFeHQpIHx8CgkodGhpcy0+Y2FwYWJpbGl0aWVzLmdsVmVyc2lvbiA+PSAweDAxMjApOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZQb2ludEN1bGwgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FUSV9wb2ludF9jdWxsX21vZGUiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZUZXhNaXJyb3JPbmNlID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BVElfdGV4dHVyZV9taXJyb3Jfb25jZSIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlBOdHJpYW5nbGVzID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BVElfcG5fdHJpYW5nbGVzIiwgc3RyRXh0KSB8fAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVRJWF9wbl90cmlhbmdsZXMiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZUZXh0RnJhZ1NoYWRlciA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVRJX3RleHRfZnJhZ21lbnRfc2hhZGVyIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mQmxlbmRFcVNlcCA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVRJX2JsZW5kX2VxdWF0aW9uX3NlcGFyYXRlIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mQmxlbmRXZWlnaHRNaW5NYXggPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FUSV9ibGVuZF93ZWlnaHRlZF9taW5tYXgiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZDb21iaW5lMyA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVRJX3RleHR1cmVfZW52X2NvbWJpbmUzIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mU2VwU3RlbmNpbCA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfQVRJX3NlcGFyYXRlX3N0ZW5jaWwiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZBcnJheVJldkNvbXBzNEJ5dGUgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX0FUSV9hcnJheV9yZXZfY29tcHNfaW5fNF9ieXRlcyIsc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mUG9pbnRTcHJpdGUgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX05WX3BvaW50X3Nwcml0ZSIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlJlZ0NvbWJpbmVycyA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfTlZfcmVnaXN0ZXJfY29tYmluZXJzIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mUmVnQ29tYmluZXJzMiA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfTlZfcmVnaXN0ZXJfY29tYmluZXJzMiIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZlRleEVudkNvbWJpbmU0ID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9OVl90ZXh0dXJlX2Vudl9jb21iaW5lNCIsIHN0ckV4dCk7Cgl0aGlzLT5jYXBhYmlsaXRpZXMuZkJsZW5kU3F1YXJlID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9OVl9ibGVuZF9zcXVhcmUiLCBzdHJFeHQpIHx8CgkodGhpcy0+Y2FwYWJpbGl0aWVzLmdsVmVyc2lvbiA+PSAweDAxNDApOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZGb2dEaXN0ID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9OVl9mb2dfZGlzdGFuY2UiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZNdWx0aXNhbXBsZUZpbHRlckhpbnQgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX05WX211bHRpc2FtcGxlX2ZpbHRlcl9oaW50Iiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mVGV4R2VuUmVmbGVjdCA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfTlZfdGV4Z2VuX3JlZmxlY3Rpb24iLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZUZXhTaGFkZXIgPSAKCWdsdUNoZWNrRXh0ZW5zaW9uICgoR0x1Ynl0ZSopIkdMX05WX3RleHR1cmVfc2hhZGVyIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mVGV4U2hhZGVyMiA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfTlZfdGV4dHVyZV9zaGFkZXIyIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mVGV4U2hhZGVyMyA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfTlZfdGV4dHVyZV9zaGFkZXIzIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mRGVwdGhDbGFtcCA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfTlZfZGVwdGhfY2xhbXAiLCBzdHJFeHQpOwoJdGhpcy0+Y2FwYWJpbGl0aWVzLmZMaWdodE1heEV4cCA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfTlZfbGlnaHRfbWF4X2V4cG9uZW50Iiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mUmFzdGVyUG9zQ2xpcCA9IAoJZ2x1Q2hlY2tFeHRlbnNpb24gKChHTHVieXRlKikiR0xfSUJNX3Jhc3RlcnBvc19jbGlwIiwgc3RyRXh0KTsKCXRoaXMtPmNhcGFiaWxpdGllcy5mQ29udkJvcmRlck1vZGVzID0gCglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9IUF9jb252b2x1dGlvbl9ib3JkZXJfbW9kZXMiLCBzdHJFeHQpIHx8CglnbHVDaGVja0V4dGVuc2lvbiAoKEdMdWJ5dGUqKSJHTF9BUkJfaW1hZ2luZyIsIHN0ckV4dCk7CgkKCWlmICh0aGlzLT5jYXBhYmlsaXRpZXMuZlRleFJlY3QpIHsKCQkvLyBvbmx5IGNoZWNrIGlmIGV4dGVuc2lvbiBzdXBwb3J0ZWQKCQlnbEdldEludGVnZXJ2IChHTF9NQVhfUkVDVEFOR0xFX1RFWFRVUkVfU0laRV9FWFQsIChHTGludCopJnRoaXMtPmNhcGFiaWxpdGllcy5tYXhSZWN0VGV4dHVyZVNpemUpOwoJfSBlbHNlIHsKCQl0aGlzLT5jYXBhYmlsaXRpZXMubWF4UmVjdFRleHR1cmVTaXplID0gMDsKCX0KI2VuZGlmCn0KCgp1aW50MzIgVmlzdWFsR3JhcGhpY3M6OnBvd2VyMkNlaWxpbmcodWludDMyIG4pIHsKICAgIHVpbnQzMiBpID0gMTsKICAgIHdoaWxlIChpIDwgbikgaSA8PD0gMTsKICAgIHJldHVybiBpOwp9CgoKVmlzdWFsTnVyYnMqIFZpc3VhbEdyYXBoaWNzOjpjcmVhdGVOdXJic09iamVjdChjb25zdCBWaXN1YWxJdGVtSWRlbnRpZmllciYgaWRlbnRpZmllciwgdWludDggc051bUtub3RzLCBmbG9hdCogc0tub3RzLCB1aW50OCB0TnVtS25vdHMsIGZsb2F0KiB0S25vdHMsIHVpbnQxNiBzU3RyaWRlLCB1aW50MTYgdFN0cmlkZSwgdWludDE2IHNPcmRlciwgdWludDE2IHRPcmRlcikgewoJCglWaXN1YWxOdXJicyogYVZpc3VhbE51cmJzID0gbmV3IFZpc3VhbE51cmJzKHNOdW1Lbm90cywgc0tub3RzLCB0TnVtS25vdHMsIHRLbm90cywgc1N0cmlkZSwgdFN0cmlkZSwgc09yZGVyLCB0T3JkZXIpOwoJCglOdXJic01hcEl0ZXJhdG9yIGl0OwoJaXQgPSB0aGlzLT5udXJic01hcC5maW5kKGlkZW50aWZpZXIpOwoJaWYgKGl0ID09IHRoaXMtPm51cmJzTWFwLmVuZCgpKSB7CgkJdGhpcy0+bnVyYnNNYXBbaWRlbnRpZmllcl0gPSBhVmlzdWFsTnVyYnM7Cgl9IGVsc2UgewoJCWlmIChpdC0+c2Vjb25kKSB7CgkJCWRlbGV0ZSBpdC0+c2Vjb25kOwoJCX0KCQlpdC0+c2Vjb25kID0gYVZpc3VhbE51cmJzOwoJfQoJcmV0dXJuIGFWaXN1YWxOdXJiczsKfQoKClZpc3VhbE51cmJzKiBWaXN1YWxHcmFwaGljczo6Z2V0TnVyYnNPYmplY3QoY29uc3QgVmlzdWFsSXRlbUlkZW50aWZpZXImIGlkZW50aWZpZXIpIHsKCQoJTnVyYnNNYXBJdGVyYXRvciBpdCA9IHRoaXMtPm51cmJzTWFwLmZpbmQoaWRlbnRpZmllcik7CglpZiAoaXQgIT0gdGhpcy0+bnVyYnNNYXAuZW5kKCkpIHsKCQlyZXR1cm4gaXQtPnNlY29uZDsKCX0KCXJldHVybiBOVUxMOwp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6ZGVsZXRlTnVyYnNPYmplY3QoY29uc3QgVmlzdWFsSXRlbUlkZW50aWZpZXImIGlkZW50aWZpZXIpIHsKCU51cmJzTWFwSXRlcmF0b3IgaXQgPSB0aGlzLT5udXJic01hcC5maW5kKGlkZW50aWZpZXIpOwoJaWYgKGl0ICE9IHRoaXMtPm51cmJzTWFwLmVuZCgpKSB7CgkJZGVsZXRlIGl0LT5zZWNvbmQ7CgkJdGhpcy0+bnVyYnNNYXAuZXJhc2UoaXQpOwoJfQp9CgoKdm9pZCBWaXN1YWxHcmFwaGljczo6Y29weUZyYW1lYnVmZmVyVG9UZXh0dXJlKHVpbnQzMiB0ZXh0dXJlTnVtYmVyLCBib29sIGNhblVzZVJlY3RFeHRlbnNpb24sIGNvbnN0IEJvdHRvbUxlZnRQb3NpdGlvbmVkUGl4ZWxSZWN0JiBjbGlwUmVjdCwgdWludDE2IHBpeGVsRm9ybWF0LCB1aW50MTYgZGF0YVR5cGUpIHsKCQoJYm9vbCBkZWJ1ZyA9IGZhbHNlOwoJCgl0aGVWaXN1YWxHcmFwaGljcyA9IFZpc3VhbEdyYXBoaWNzOjpnZXRJbnN0YW5jZSgpOwoJUGl4ZWwgYm90dG9tTGVmdFZpZXdwb3J0T3JpZ2luID0gdGhpcy0+Z2V0Vmlld3BvcnRCb3R0b21MZWZ0T3JpZ2luKCk7CgkKCWlmIChjYW5Vc2VSZWN0RXh0ZW5zaW9uID09IGZhbHNlKSB7CiAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7CiAgICB9IGVsc2UgewojaWYgVEFSR0VUX09TX01BQwogICAgICAgIGdsRW5hYmxlIChHTF9URVhUVVJFX1JFQ1RBTkdMRV9FWFQpOwojZW5kaWYKCX0KCQoJaWYgKGNhblVzZVJlY3RFeHRlbnNpb24gPT0gZmFsc2UpIHsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIChHTHVpbnQpdGV4dHVyZU51bWJlcik7CiAgICB9IGVsc2UgewojaWYgVEFSR0VUX09TX01BQwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV9SRUNUQU5HTEVfRVhULCAoR0x1aW50KXRleHR1cmVOdW1iZXIpOwojZW5kaWYKICAgIH0KCQoJZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfV1JBUF9TLCBHTF9DTEFNUCk7CglnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX0NMQU1QKTsKCWdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX0xJTkVBUik7CglnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9MSU5FQVIpOwoJCglpZiAoZGVidWcgPT0gZmFsc2UpIHsKCQlpZiAoY2FuVXNlUmVjdEV4dGVuc2lvbiA9PSBmYWxzZSkgewoJCQlnbENvcHlUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIEdMX1JHQkEsIChib3R0b21MZWZ0Vmlld3BvcnRPcmlnaW4ueCArIGNsaXBSZWN0LmJvdHRvbUxlZnRQaXhlbC54KSwgKGJvdHRvbUxlZnRWaWV3cG9ydE9yaWdpbi55ICsgY2xpcFJlY3QuYm90dG9tTGVmdFBpeGVsLnkpLCBjbGlwUmVjdC5waXhlbFJlY3Qud2lkdGgsIGNsaXBSZWN0LnBpeGVsUmVjdC5oZWlnaHQsIDApOwoJCX0gZWxzZSB7CiNpZiBUQVJHRVRfT1NfTUFDCgkJCWdsQ29weVRleEltYWdlMkQoR0xfVEVYVFVSRV9SRUNUQU5HTEVfRVhULCAwLCBHTF9SR0JBLCAoYm90dG9tTGVmdFZpZXdwb3J0T3JpZ2luLnggKyBjbGlwUmVjdC5ib3R0b21MZWZ0UGl4ZWwueCksIChib3R0b21MZWZ0Vmlld3BvcnRPcmlnaW4ueSArIGNsaXBSZWN0LmJvdHRvbUxlZnRQaXhlbC55KSwgY2xpcFJlY3QucGl4ZWxSZWN0LndpZHRoLCBjbGlwUmVjdC5waXhlbFJlY3QuaGVpZ2h0LCAwKTsKI2VuZGlmCgkJfQoJfSBlbHNlIHsKCQl1aW50MzIqIGltYWdlID0gTlVMTDsKI2lmIFRBUkdFVF9PU19XSU4KCQlpbWFnZSA9IFZpc3VhbENvbG9yVG9vbHM6OmNyZWF0ZUJHUkFDaGVja1BpeGVscyhjbGlwUmVjdC5waXhlbFJlY3Qud2lkdGgsIGNsaXBSZWN0LnBpeGVsUmVjdC5oZWlnaHQsIGJsdWUpOwojZW5kaWYKI2lmIFRBUkdFVF9PU19NQUMKCQlpbWFnZSA9IFZpc3VhbENvbG9yVG9vbHM6OmNyZWF0ZUFSR0JDaGVja1BpeGVscyhjbGlwUmVjdC5waXhlbFJlY3Qud2lkdGgsIGNsaXBSZWN0LnBpeGVsUmVjdC5oZWlnaHQsIGJsdWUpOwojZW5kaWYKCQl0aGlzLT5zZXRQaXhlbFN0b3JhZ2VQYXJhbXMoKTsKCQlpZiAoY2FuVXNlUmVjdEV4dGVuc2lvbiA9PSBmYWxzZSkgewojaWYgVEFSR0VUX09TX1dJTgoJCQlnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwgR0xfUkdCQSwgY2xpcFJlY3QucGl4ZWxSZWN0LndpZHRoLCBjbGlwUmVjdC5waXhlbFJlY3QuaGVpZ2h0LCAwLCBwaXhlbEZvcm1hdCwgZGF0YVR5cGUsIChHTHVieXRlKilpbWFnZSk7CiNlbmRpZgojaWYgVEFSR0VUX09TX01BQwoJCQlnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwgR0xfUkdCQSwgY2xpcFJlY3QucGl4ZWxSZWN0LndpZHRoLCBjbGlwUmVjdC5waXhlbFJlY3QuaGVpZ2h0LCAwLCBwaXhlbEZvcm1hdCwgZGF0YVR5cGUsIChHTHVpbnQqKWltYWdlKTsKI2VuZGlmCgkJfSBlbHNlIHsKI2lmIFRBUkdFVF9PU19NQUMKCQkJZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfUkVDVEFOR0xFX0VYVCwgMCwgR0xfUkdCQSwgY2xpcFJlY3QucGl4ZWxSZWN0LndpZHRoLCBjbGlwUmVjdC5waXhlbFJlY3QuaGVpZ2h0LCAwLCBwaXhlbEZvcm1hdCwgZGF0YVR5cGUsIChHTHVpbnQqKWltYWdlKTsKI2VuZGlmCgkJfQoJCWZyZWUoaW1hZ2UpOwoJfQoJCiAgICBpZiAoY2FuVXNlUmVjdEV4dGVuc2lvbiA9PSBmYWxzZSkgewogICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzJEKTsKCX0gZWxzZSB7CiNpZiBUQVJHRVRfT1NfTUFDCiAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfUkVDVEFOR0xFX0VYVCk7CiNlbmRpZgogICAgfQoJCn0K