Ly8KLy8gQ29weXJpZ2h0IKkgMjAxMiBMaW5hcm8gTGltaXRlZAovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgZ2xtYXJrMiBPcGVuR0wgKEVTKSAyLjAgYmVuY2htYXJrLgovLwovLyBnbG1hcmsyIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlCi8vIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKLy8gRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIKLy8gdmVyc2lvbi4KLy8KLy8gZ2xtYXJrMiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKLy8gV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUwovLyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCi8vIGRldGFpbHMuCi8vCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGgKLy8gZ2xtYXJrMi4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KLy8KLy8gQXV0aG9yczoKLy8gIEplc3NlIEJhcmtlcgovLwojaW5jbHVkZSAic2NlbmUtcmVmcmFjdC5oIgojaW5jbHVkZSAibW9kZWwuaCIKI2luY2x1ZGUgInRleHR1cmUuaCIKI2luY2x1ZGUgInV0aWwuaCIKI2luY2x1ZGUgImxvZy5oIgojaW5jbHVkZSAic2hhZGVyLXNvdXJjZS5oIgoKdXNpbmcgc3RkOjpzdHJpbmc7CnVzaW5nIHN0ZDo6dmVjdG9yOwp1c2luZyBzdGQ6Om1hcDsKdXNpbmcgTGliTWF0cml4OjptYXQ0Owp1c2luZyBMaWJNYXRyaXg6OnZlYzQ7CnVzaW5nIExpYk1hdHJpeDo6dmVjMzsKCnN0YXRpYyBjb25zdCB2ZWM0IGxpZ2h0UG9zaXRpb24oMS4wZiwgMS4wZiwgMi4wZiwgMS4wZik7CgovLwovLyBQdWJsaWMgaW50ZXJmYWNlcwovLwoKU2NlbmVSZWZyYWN0OjpTY2VuZVJlZnJhY3QoQ2FudmFzJiBjYW52YXMpIDoKICAgIFNjZW5lKGNhbnZhcywgInJlZnJhY3QiKSwKICAgIHByaXZfKDApCnsKICAgIGNvbnN0IE1vZGVsTWFwJiBtb2RlbE1hcCA9IE1vZGVsOjpmaW5kX21vZGVscygpOwogICAgc3RyaW5nIG9wdGlvblZhbHVlczsKICAgIGZvciAoTW9kZWxNYXA6OmNvbnN0X2l0ZXJhdG9yIG1vZGVsSXQgPSBtb2RlbE1hcC5iZWdpbigpOwogICAgICAgICBtb2RlbEl0ICE9IG1vZGVsTWFwLmVuZCgpOwogICAgICAgICBtb2RlbEl0KyspCiAgICB7CiAgICAgICAgc3RhdGljIGJvb2wgZG9TZXBhcmF0b3IoZmFsc2UpOwogICAgICAgIGlmIChkb1NlcGFyYXRvcikKICAgICAgICB7CiAgICAgICAgICAgIG9wdGlvblZhbHVlcyArPSAiLCI7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHN0cmluZyYgY3VyTmFtZSA9IG1vZGVsSXQtPmZpcnN0OwogICAgICAgIG9wdGlvblZhbHVlcyArPSBjdXJOYW1lOwogICAgICAgIGRvU2VwYXJhdG9yID0gdHJ1ZTsKICAgIH0KICAgIG9wdGlvbnNfWyJtb2RlbCJdID0gU2NlbmU6Ok9wdGlvbigibW9kZWwiLCAiYnVubnkiLCAiV2hpY2ggbW9kZWwgdG8gdXNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25WYWx1ZXMpOwogICAgb3B0aW9uVmFsdWVzID0gIiI7CiAgICBjb25zdCBUZXh0dXJlTWFwJiB0ZXh0dXJlTWFwID0gVGV4dHVyZTo6ZmluZF90ZXh0dXJlcygpOwogICAgZm9yIChUZXh0dXJlTWFwOjpjb25zdF9pdGVyYXRvciB0ZXh0dXJlSXQgPSB0ZXh0dXJlTWFwLmJlZ2luKCk7CiAgICAgICAgIHRleHR1cmVJdCAhPSB0ZXh0dXJlTWFwLmVuZCgpOwogICAgICAgICB0ZXh0dXJlSXQrKykKICAgIHsKICAgICAgICBzdGF0aWMgYm9vbCBkb1NlcGFyYXRvcihmYWxzZSk7CiAgICAgICAgaWYgKGRvU2VwYXJhdG9yKQogICAgICAgIHsKICAgICAgICAgICAgb3B0aW9uVmFsdWVzICs9ICIsIjsKICAgICAgICB9CiAgICAgICAgY29uc3Qgc3RyaW5nJiBjdXJOYW1lID0gdGV4dHVyZUl0LT5maXJzdDsKICAgICAgICBvcHRpb25WYWx1ZXMgKz0gY3VyTmFtZTsKICAgICAgICBkb1NlcGFyYXRvciA9IHRydWU7CiAgICB9CiAgICBvcHRpb25zX1sidGV4dHVyZSJdID0gU2NlbmU6Ok9wdGlvbigidGV4dHVyZSIsICJuYXNhMSIsICJXaGljaCB0ZXh0dXJlIHRvIHVzZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25WYWx1ZXMpOwogICAgb3B0aW9uc19bImluZGV4Il0gPSBTY2VuZTo6T3B0aW9uKCJpbmRleCIsICIxLjIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbmRleCBvZiByZWZyYWN0aW9uIG9mIHRoZSBtZWRpdW0gdG8gc2ltdWxhdGUiKTsKICAgIG9wdGlvbnNfWyJ1c2UtdmJvIl0gPSBTY2VuZTo6T3B0aW9uKCJ1c2UtdmJvIiwgInRydWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIldoZXRoZXIgdG8gdXNlIFZCT3MgZm9yIHJlbmRlcmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFsc2UsdHJ1ZSIpOwogICAgb3B0aW9uc19bImludGVybGVhdmUiXSA9IFNjZW5lOjpPcHRpb24oImludGVybGVhdmUiLCAiZmFsc2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIldoZXRoZXIgdG8gaW50ZXJsZWF2ZSB2ZXJ0ZXggYXR0cmlidXRlIGRhdGEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZhbHNlLHRydWUiKTsKfQoKU2NlbmVSZWZyYWN0Ojp+U2NlbmVSZWZyYWN0KCkKewogICAgZGVsZXRlIHByaXZfOwp9Cgpib29sClNjZW5lUmVmcmFjdDo6c3VwcG9ydGVkKGJvb2wgc2hvd19lcnJvcnMpCnsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgb2VzX2RlcHRoX3RleHR1cmUoIkdMX09FU19kZXB0aF90ZXh0dXJlIik7CiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIGFyYl9kZXB0aF90ZXh0dXJlKCJHTF9BUkJfZGVwdGhfdGV4dHVyZSIpOwogICAgaWYgKCFHTEV4dGVuc2lvbnM6OnN1cHBvcnQob2VzX2RlcHRoX3RleHR1cmUpICYmCiAgICAgICAgIUdMRXh0ZW5zaW9uczo6c3VwcG9ydChhcmJfZGVwdGhfdGV4dHVyZSkpIHsKICAgICAgICBpZiAoc2hvd19lcnJvcnMpIHsKICAgICAgICAgICAgTG9nOjplcnJvcigiV2UgZG8gbm90IGhhdmUgdGhlIGRlcHRoIHRleHR1cmUgZXh0ZW5zaW9uISEhXG4iKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIHJldHVybiB0cnVlOwp9Cgpib29sClNjZW5lUmVmcmFjdDo6bG9hZCgpCnsKICAgIHJ1bm5pbmdfID0gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKfQoKdm9pZApTY2VuZVJlZnJhY3Q6OnVubG9hZCgpCnsKfQoKYm9vbApTY2VuZVJlZnJhY3Q6OnNldHVwKCkKewogICAgLy8gSWYgdGhlIHNjZW5lIGlzbid0IHN1cHBvcnRlZCwgZG9uJ3QgYm90aGVyIHRvIGdvIHRocm91Z2ggc2V0dXAuCiAgICBpZiAoIXN1cHBvcnRlZChmYWxzZSkgfHwgIVNjZW5lOjpzZXR1cCgpKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwcml2XyA9IG5ldyBSZWZyYWN0UHJpdmF0ZShjYW52YXNfKTsKICAgIGlmICghcHJpdl8tPnNldHVwKG9wdGlvbnNfKSkgewogICAgICAgIGRlbGV0ZSBwcml2XzsKICAgICAgICBwcml2XyA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8vIFNldCBjb3JlIHNjZW5lIHRpbWluZyBhZnRlciBhY3R1YWwgaW5pdGlhbGl6YXRpb24gc28gd2UgZG9uJ3QgbWVhc3VyZQogICAgLy8gc2V0IHVwIHRpbWUuCiAgICBzdGFydFRpbWVfID0gVXRpbDo6Z2V0X3RpbWVzdGFtcF91cygpIC8gMTAwMDAwMC4wOwogICAgbGFzdFVwZGF0ZVRpbWVfID0gc3RhcnRUaW1lXzsKICAgIHJ1bm5pbmdfID0gdHJ1ZTsKCiAgICByZXR1cm4gdHJ1ZTsKfQoKdm9pZApTY2VuZVJlZnJhY3Q6OnRlYXJkb3duKCkKewogICAgLy8gQWRkIHNjZW5lLXNwZWNpZmljIHRlYXJkb3duIGhlcmUKICAgIHByaXZfLT50ZWFyZG93bigpOwogICAgU2NlbmU6OnRlYXJkb3duKCk7Cn0KCnZvaWQKU2NlbmVSZWZyYWN0Ojp1cGRhdGUoKQp7CiAgICBTY2VuZTo6dXBkYXRlKCk7CiAgICAvLyBBZGQgc2NlbmUtc3BlY2lmaWMgdXBkYXRlIGhlcmUKICAgIHByaXZfLT51cGRhdGUobGFzdFVwZGF0ZVRpbWVfIC0gc3RhcnRUaW1lXyk7Cn0KCnZvaWQKU2NlbmVSZWZyYWN0OjpkcmF3KCkKewogICAgcHJpdl8tPmRyYXcoKTsKfQoKU2NlbmU6OlZhbGlkYXRpb25SZXN1bHQKU2NlbmVSZWZyYWN0Ojp2YWxpZGF0ZSgpCnsKICAgIHJldHVybiBTY2VuZTo6VmFsaWRhdGlvblVua25vd247Cn0KCi8vCi8vIFByaXZhdGUgaW50ZXJmYWNlcwovLwoKYm9vbApEaXN0YW5jZVJlbmRlclRhcmdldDo6c2V0dXAodW5zaWduZWQgaW50IHdpZHRoLCB1bnNpZ25lZCBpbnQgaGVpZ2h0KQp7CiAgICBjYW52YXNfd2lkdGhfID0gd2lkdGg7CiAgICBjYW52YXNfaGVpZ2h0XyA9IGhlaWdodDsKICAgIHdpZHRoXyA9IGNhbnZhc193aWR0aF8gKiAyOwogICAgaGVpZ2h0XyA9IGNhbnZhc19oZWlnaHRfICogMjsKCiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIHZ0eF9zaGFkZXJfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9kZXB0aC52ZXJ0Iik7CiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIGZyZ19zaGFkZXJfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9kZXB0aC5mcmFnIik7CgogICAgU2hhZGVyU291cmNlIHZ0eF9zb3VyY2UodnR4X3NoYWRlcl9maWxlbmFtZSk7CiAgICBTaGFkZXJTb3VyY2UgZnJnX3NvdXJjZShmcmdfc2hhZGVyX2ZpbGVuYW1lKTsKCiAgICBpZiAoIVNjZW5lOjpsb2FkX3NoYWRlcnNfZnJvbV9zdHJpbmdzKHByb2dyYW1fLCB2dHhfc291cmNlLnN0cigpLCBmcmdfc291cmNlLnN0cigpKSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBnbEdlblRleHR1cmVzKDIsICZ0ZXhfWzBdKTsKICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdGV4X1tERVBUSF0pOwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfUywgR0xfQ0xBTVBfVE9fRURHRSk7CiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX0NMQU1QX1RPX0VER0UpOwogICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIEdMX0RFUFRIX0NPTVBPTkVOVCwgd2lkdGhfLCBoZWlnaHRfLCAwLAogICAgICAgICAgICAgICAgIEdMX0RFUFRIX0NPTVBPTkVOVCwgR0xfVU5TSUdORURfSU5ULCAwKTsKICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdGV4X1tDT0xPUl0pOwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTElORUFSX01JUE1BUF9MSU5FQVIpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgR0xfTElORUFSKTsKICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfUywgR0xfQ0xBTVBfVE9fRURHRSk7CiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX0NMQU1QX1RPX0VER0UpOwogICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIEdMX1JHQkEsIHdpZHRoXywgaGVpZ2h0XywgMCwKICAgICAgICAgICAgICAgICBHTF9SR0JBLCBHTF9VTlNJR05FRF9CWVRFLCAwKTsKICAgIGdsR2VuZXJhdGVNaXBtYXAoR0xfVEVYVFVSRV8yRCk7CiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIDApOwoKICAgIGdsR2VuRnJhbWVidWZmZXJzKDEsICZmYm9fKTsKICAgIGdsQmluZEZyYW1lYnVmZmVyKEdMX0ZSQU1FQlVGRkVSLCBmYm9fKTsKICAgIGdsRnJhbWVidWZmZXJUZXh0dXJlMkQoR0xfRlJBTUVCVUZGRVIsIEdMX0RFUFRIX0FUVEFDSE1FTlQsIEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleF9bREVQVEhdLCAwKTsKICAgIGdsRnJhbWVidWZmZXJUZXh0dXJlMkQoR0xfRlJBTUVCVUZGRVIsIEdMX0NPTE9SX0FUVEFDSE1FTlQwLCBHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXhfW0NPTE9SXSwgMCk7CiAgICB1bnNpZ25lZCBpbnQgc3RhdHVzID0gZ2xDaGVja0ZyYW1lYnVmZmVyU3RhdHVzKEdMX0ZSQU1FQlVGRkVSKTsKICAgIGlmIChzdGF0dXMgIT0gR0xfRlJBTUVCVUZGRVJfQ09NUExFVEUpIHsKICAgICAgICBMb2c6OmVycm9yKCJEZXB0aFJlbmRlclN0YXRlOjpzZXR1cDogZ2xDaGVja0ZyYW1lYnVmZmVyU3RhdHVzIGZhaWxlZCAoMHgleClcbiIsIHN0YXR1cyk7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgZ2xCaW5kRnJhbWVidWZmZXIoR0xfRlJBTUVCVUZGRVIsIDApOwoKICAgIHJldHVybiB0cnVlOwp9Cgp2b2lkCkRpc3RhbmNlUmVuZGVyVGFyZ2V0Ojp0ZWFyZG93bigpCnsKICAgIHByb2dyYW1fLnN0b3AoKTsKICAgIHByb2dyYW1fLnJlbGVhc2UoKTsKICAgIGlmICh0ZXhfKSB7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygyLCAmdGV4X1swXSk7CiAgICAgICAgdGV4X1tERVBUSF0gPSB0ZXhfW0NPTE9SXSA9IDA7CiAgICB9CiAgICBpZiAoZmJvXykgewogICAgICAgIGdsRGVsZXRlRnJhbWVidWZmZXJzKDEsICZmYm9fKTsKICAgICAgICBmYm9fID0gMDsKICAgIH0KfQoKdm9pZApEaXN0YW5jZVJlbmRlclRhcmdldDo6ZW5hYmxlKGNvbnN0IG1hdDQmIG12cCkKewogICAgcHJvZ3JhbV8uc3RhcnQoKTsKICAgIHByb2dyYW1fWyJNb2RlbFZpZXdQcm9qZWN0aW9uTWF0cml4Il0gPSBtdnA7CiAgICBnbEJpbmRGcmFtZWJ1ZmZlcihHTF9GUkFNRUJVRkZFUiwgZmJvXyk7CiAgICBnbEZyYW1lYnVmZmVyVGV4dHVyZTJEKEdMX0ZSQU1FQlVGRkVSLCBHTF9ERVBUSF9BVFRBQ0hNRU5ULCBHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXhfW0RFUFRIXSwgMCk7CiAgICBnbEZyYW1lYnVmZmVyVGV4dHVyZTJEKEdMX0ZSQU1FQlVGRkVSLCBHTF9DT0xPUl9BVFRBQ0hNRU5UMCwgR0xfVEVYVFVSRV8yRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4X1tDT0xPUl0sIDApOwogICAgZ2xWaWV3cG9ydCgwLCAwLCB3aWR0aF8sIGhlaWdodF8pOwogICAgZ2xDbGVhcihHTF9ERVBUSF9CVUZGRVJfQklUIHwgR0xfQ09MT1JfQlVGRkVSX0JJVCk7CiAgICBnbEN1bGxGYWNlKEdMX0ZST05UKTsKfQoKdm9pZCBEaXN0YW5jZVJlbmRlclRhcmdldDo6ZGlzYWJsZSgpCnsKICAgIGdsQmluZEZyYW1lYnVmZmVyKEdMX0ZSQU1FQlVGRkVSLCAwKTsKICAgIGdsVmlld3BvcnQoMCwgMCwgY2FudmFzX3dpZHRoXywgY2FudmFzX2hlaWdodF8pOwogICAgZ2xDdWxsRmFjZShHTF9CQUNLKTsKfQoKYm9vbApSZWZyYWN0UHJpdmF0ZTo6c2V0dXAobWFwPHN0cmluZywgU2NlbmU6Ok9wdGlvbj4mIG9wdGlvbnMpCnsKICAgIC8vIFByb2dyYW0gb2JqZWN0IHNldHVwCiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIHZ0eF9zaGFkZXJfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9saWdodC1yZWZyYWN0LnZlcnQiKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgZnJnX3NoYWRlcl9maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2xpZ2h0LXJlZnJhY3QuZnJhZyIpOwogICAgc3RhdGljIGNvbnN0IHZlYzQgbGlnaHRDb2xvcigwLjQsIDAuNCwgMC40LCAxLjApOwoKICAgIFNoYWRlclNvdXJjZSB2dHhfc291cmNlKHZ0eF9zaGFkZXJfZmlsZW5hbWUpOwogICAgU2hhZGVyU291cmNlIGZyZ19zb3VyY2UoZnJnX3NoYWRlcl9maWxlbmFtZSk7CgogICAgZnJnX3NvdXJjZS5hZGRfY29uc3QoIkxpZ2h0Q29sb3IiLCBsaWdodENvbG9yKTsKICAgIGZyZ19zb3VyY2UuYWRkX2NvbnN0KCJMaWdodFNvdXJjZVBvc2l0aW9uIiwgbGlnaHRQb3NpdGlvbik7CiAgICBmbG9hdCByZWZyYWN0aXZlX2luZGV4KFV0aWw6OmZyb21TdHJpbmc8ZmxvYXQ+KG9wdGlvbnNbImluZGV4Il0udmFsdWUpKTsKICAgIGZyZ19zb3VyY2UuYWRkX2NvbnN0KCJSZWZyYWN0aXZlSW5kZXgiLCByZWZyYWN0aXZlX2luZGV4KTsKCiAgICBpZiAoIVNjZW5lOjpsb2FkX3NoYWRlcnNfZnJvbV9zdHJpbmdzKHByb2dyYW1fLCB2dHhfc291cmNlLnN0cigpLCBmcmdfc291cmNlLnN0cigpKSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBjb25zdCBzdHJpbmcmIHdoaWNoVGV4dHVyZShvcHRpb25zWyJ0ZXh0dXJlIl0udmFsdWUpOwogICAgaWYgKCFUZXh0dXJlOjpsb2FkKHdoaWNoVGV4dHVyZSwgJnRleHR1cmVfLCBHTF9MSU5FQVIsIEdMX0xJTkVBUiwgMCkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIC8vIE1vZGVsIHNldHVwCiAgICBNb2RlbCBtb2RlbDsKICAgIGNvbnN0IHN0cmluZyYgd2hpY2hNb2RlbChvcHRpb25zWyJtb2RlbCJdLnZhbHVlKTsKICAgIGJvb2wgbW9kZWxMb2FkZWQgPSBtb2RlbC5sb2FkKHdoaWNoTW9kZWwpOwoKICAgIGlmKCFtb2RlbExvYWRlZCkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgLy8gTm93IHRoYXQgd2UncmUgc3VjY2Vzc2Z1bGx5IGxvYWRlZCwgdGhlcmUgYXJlIGEgZmV3IHF1aXJrcyBhYm91dAogICAgLy8gc29tZSBvZiB0aGUga25vd24gbW9kZWxzIHRoYXQgd2UgbmVlZCB0byBhY2NvdW50IGZvci4gIFRoZSBkcmF3CiAgICAvLyBsb2dpYyBmb3IgdGhlIHNjZW5lIHdhbnRzIHRvIHJvdGF0ZSB0aGUgbW9kZWwgYXJvdW5kIHRoZSBZIGF4aXMuCiAgICAvLyBNb3N0IG9mIG91ciBtb2RlbHMgYXJlIGRlc2NyaWJlZCB0aGlzIHdheS4gIFNvbWUgbmVlZCBhZGp1c3RtZW50CiAgICAvLyAoYW4gYWRkaXRpb25hbCByb3RhdGlvbiB0aGF0IGdldHMgdGhlIG1vZGVsIGludG8gdGhlIGNvcnJlY3QKICAgIC8vIG9yaWVudGF0aW9uKS4KICAgIC8vCiAgICAvLyBIZXJlJ3MgYSBzdW1tYXJ5OgogICAgLy8KICAgIC8vIEFuZ2VsIHJvdGF0ZXMgYXJvdW5kIHRoZSBZIGF4aXMKICAgIC8vIEFybWFkaWxsbyByb3RhdGVzIGFyb3VuZCB0aGUgWSBheGlzCiAgICAvLyBCdWRkaGEgcm90YXRlcyBhcm91bmQgdGhlIFggYXhpcwogICAgLy8gQnVubnkgcm90YXRlcyBhcm91bmQgdGhlIFkgYXhpcwogICAgLy8gRHJhZ29uIHJvdGF0ZXMgYXJvdW5kIHRoZSBYIGF4aXMKICAgIC8vIEhvcnNlIHJvdGF0ZXMgYXJvdW5kIHRoZSBZIGF4aXMKICAgIGlmICh3aGljaE1vZGVsID09ICJidWRkaGEiIHx8IHdoaWNoTW9kZWwgPT0gImRyYWdvbiIpCiAgICB7CiAgICAgICAgb3JpZW50TW9kZWxfID0gdHJ1ZTsKICAgICAgICBvcmllbnRhdGlvbkFuZ2xlXyA9IC05MC4wOwogICAgICAgIG9yaWVudGF0aW9uVmVjXyA9IHZlYzMoMS4wLCAwLjAsIDAuMCk7CiAgICB9CiAgICBlbHNlIGlmICh3aGljaE1vZGVsID09ICJhcm1hZGlsbG8iKQogICAgewogICAgICAgIG9yaWVudE1vZGVsXyA9IHRydWU7CiAgICAgICAgb3JpZW50YXRpb25BbmdsZV8gPSAxODAuMDsgCiAgICAgICAgb3JpZW50YXRpb25WZWNfID0gdmVjMygwLjAsIDEuMCwgMC4wKTsKICAgIH0KCiAgICBtb2RlbC5jYWxjdWxhdGVfbm9ybWFscygpOwoKICAgIC8vIE1lc2ggc2V0dXAKICAgIHZlY3RvcjxzdGQ6OnBhaXI8TW9kZWw6OkF0dHJpYlR5cGUsIGludD4gPiBhdHRyaWJzOwogICAgYXR0cmlicy5wdXNoX2JhY2soc3RkOjpwYWlyPE1vZGVsOjpBdHRyaWJUeXBlLCBpbnQ+KE1vZGVsOjpBdHRyaWJUeXBlUG9zaXRpb24sIDMpKTsKICAgIGF0dHJpYnMucHVzaF9iYWNrKHN0ZDo6cGFpcjxNb2RlbDo6QXR0cmliVHlwZSwgaW50PihNb2RlbDo6QXR0cmliVHlwZU5vcm1hbCwgMykpOwogICAgbW9kZWwuY29udmVydF90b19tZXNoKG1lc2hfLCBhdHRyaWJzKTsKCiAgICB1c2VWYm9fID0gKG9wdGlvbnNbInVzZS12Ym8iXS52YWx1ZSA9PSAidHJ1ZSIpOwogICAgYm9vbCBpbnRlcmxlYXZlID0gKG9wdGlvbnNbImludGVybGVhdmUiXS52YWx1ZSA9PSAidHJ1ZSIpOwogICAgbWVzaF8udmJvX3VwZGF0ZV9tZXRob2QoTWVzaDo6VkJPVXBkYXRlTWV0aG9kTWFwKTsKICAgIG1lc2hfLmludGVybGVhdmUoaW50ZXJsZWF2ZSk7CgogICAgaWYgKHVzZVZib18pIHsKICAgICAgICBtZXNoXy5idWlsZF92Ym8oKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIG1lc2hfLmJ1aWxkX2FycmF5KCk7CiAgICB9CgogICAgLy8gQ2FsY3VsYXRlIGEgcHJvamVjdGlvbiBtYXRyaXggdGhhdCBpcyBhIGdvb2QgZml0IGZvciB0aGUgbW9kZWwKICAgIHZlYzMgbWF4VmVjID0gbW9kZWwubWF4VmVjKCk7CiAgICB2ZWMzIG1pblZlYyA9IG1vZGVsLm1pblZlYygpOwogICAgdmVjMyBkaWZmVmVjID0gbWF4VmVjIC0gbWluVmVjOwogICAgY2VudGVyVmVjXyA9IG1heFZlYyArIG1pblZlYzsKICAgIGNlbnRlclZlY18gLz0gMi4wOwogICAgZmxvYXQgZGlhbWV0ZXIgPSBkaWZmVmVjLmxlbmd0aCgpOwogICAgcmFkaXVzXyA9IGRpYW1ldGVyIC8gMjsKICAgIGZsb2F0IGZvdnkgPSAyLjAgKiBhdGFuZihyYWRpdXNfIC8gKDIuMCArIHJhZGl1c18pKTsKICAgIGZvdnkgLz0gTV9QSTsKICAgIGZvdnkgKj0gMTgwLjA7CiAgICBmbG9hdCBhc3BlY3Qoc3RhdGljX2Nhc3Q8ZmxvYXQ+KGNhbnZhc18ud2lkdGgoKSkvc3RhdGljX2Nhc3Q8ZmxvYXQ+KGNhbnZhc18uaGVpZ2h0KCkpKTsKICAgIHByb2plY3Rpb25fLnBlcnNwZWN0aXZlKGZvdnksIGFzcGVjdCwgMi4wLCAyLjAgKyBkaWFtZXRlcik7CgogICAgLy8gU2V0IHVwIHRoZSBsaWdodCBtYXRyaXggd2l0aCBhIGJpYXMgdGhhdCB3aWxsIGNvbnZlcnQgdmFsdWVzCiAgICAvLyBpbiB0aGUgcmFuZ2Ugb2YgWy0xLCAxXSB0byBbMCwgMSldLCB0aGVuIGFkZCBpbiB0aGUgcHJvamVjdGlvbgogICAgLy8gYW5kIHRoZSAibG9vayBhdCIgbWF0cml4IGZyb20gdGhlIGxpZ2h0IHBvc2l0aW9uLgogICAgbGlnaHRfICo9IExpYk1hdHJpeDo6TWF0NDo6dHJhbnNsYXRlKDAuNSwgMC41LCAwLjUpOwogICAgbGlnaHRfICo9IExpYk1hdHJpeDo6TWF0NDo6c2NhbGUoMC41LCAwLjUsIDAuNSk7CiAgICBsaWdodF8gKj0gcHJvamVjdGlvbl8uZ2V0Q3VycmVudCgpOwogICAgbGlnaHRfICo9IExpYk1hdHJpeDo6TWF0NDo6bG9va0F0KGxpZ2h0UG9zaXRpb24ueCgpLCBsaWdodFBvc2l0aW9uLnkoKSwgbGlnaHRQb3NpdGlvbi56KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMC4wLCAwLjAsIDAuMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLjAsIDEuMCwgMC4wKTsKCiAgICBpZiAoIWRlcHRoVGFyZ2V0Xy5zZXR1cChjYW52YXNfLndpZHRoKCksIGNhbnZhc18uaGVpZ2h0KCkpKSB7CiAgICAgICAgTG9nOjplcnJvcigiRmFpbGVkIHRvIHNldCB1cCB0aGUgcmVuZGVyIHRhcmdldCBmb3IgdGhlIGRlcHRoIHBhc3NcbiIpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICByZXR1cm4gdHJ1ZTsKfQp2b2lkClJlZnJhY3RQcml2YXRlOjp0ZWFyZG93bigpCnsKICAgIGRlcHRoVGFyZ2V0Xy50ZWFyZG93bigpOwogICAgcHJvZ3JhbV8uc3RvcCgpOwogICAgcHJvZ3JhbV8ucmVsZWFzZSgpOwogICAgbWVzaF8ucmVzZXQoKTsKfQoKdm9pZApSZWZyYWN0UHJpdmF0ZTo6dXBkYXRlKGRvdWJsZSBlbGFwc2VkVGltZSkKewogICAgcm90YXRpb25fID0gcm90YXRpb25TcGVlZF8gKiBlbGFwc2VkVGltZTsKfQoKdm9pZApSZWZyYWN0UHJpdmF0ZTo6ZHJhdygpCnsKICAgIC8vIFRvIHBlcmZvcm0gdGhlIGRlcHRoIHBhc3MsIHNldCB1cCB0aGUgbW9kZWwtdmlldyB0cmFuc2Zvcm1hdGlvbiBzbwogICAgLy8gdGhhdCB3ZSdyZSBsb29raW5nIGF0IHRoZSBob3JzZSBmcm9tIHRoZSBsaWdodCBwb3NpdGlvbi4gIFRoYXQgd2lsbAogICAgLy8gZ2l2ZSB1cyB0aGUgYXBwcm9wcmlhdGUgdmlldyBmb3IgdGhlIHNoYWRvdy4KICAgIG1vZGVsdmlld18ucHVzaCgpOwogICAgbW9kZWx2aWV3Xy5sb2FkSWRlbnRpdHkoKTsKICAgIG1vZGVsdmlld18ubG9va0F0KGxpZ2h0UG9zaXRpb24ueCgpLCBsaWdodFBvc2l0aW9uLnkoKSwgbGlnaHRQb3NpdGlvbi56KCksCiAgICAgICAgICAgICAgICAgICAgICAwLjAsIDAuMCwgMC4wLAogICAgICAgICAgICAgICAgICAgICAgMC4wLCAxLjAsIDAuMCk7CiAgICBtb2RlbHZpZXdfLnJvdGF0ZShyb3RhdGlvbl8sIDAuMGYsIDEuMGYsIDAuMGYpOwogICAgaWYgKG9yaWVudE1vZGVsXykKICAgIHsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZShvcmllbnRhdGlvbkFuZ2xlXywgb3JpZW50YXRpb25WZWNfLngoKSwgb3JpZW50YXRpb25WZWNfLnkoKSwgb3JpZW50YXRpb25WZWNfLnooKSk7CiAgICB9CiAgICBtYXQ0IG12cChwcm9qZWN0aW9uXy5nZXRDdXJyZW50KCkpOwogICAgbXZwICo9IG1vZGVsdmlld18uZ2V0Q3VycmVudCgpOwogICAgbW9kZWx2aWV3Xy5wb3AoKTsKCiAgICAvLyBFbmFibGUgdGhlIGRlcHRoIHJlbmRlciB0YXJnZXQgd2l0aCBvdXIgdHJhbnNmb3JtYXRpb24gYW5kIHJlbmRlci4KICAgIGRlcHRoVGFyZ2V0Xy5lbmFibGUobXZwKTsKICAgIHZlY3RvcjxHTGludD4gYXR0cmliX2xvY2F0aW9uczsKICAgIGF0dHJpYl9sb2NhdGlvbnMucHVzaF9iYWNrKGRlcHRoVGFyZ2V0Xy5wcm9ncmFtKClbInBvc2l0aW9uIl0ubG9jYXRpb24oKSk7CiAgICBhdHRyaWJfbG9jYXRpb25zLnB1c2hfYmFjayhkZXB0aFRhcmdldF8ucHJvZ3JhbSgpWyJub3JtYWwiXS5sb2NhdGlvbigpKTsKICAgIG1lc2hfLnNldF9hdHRyaWJfbG9jYXRpb25zKGF0dHJpYl9sb2NhdGlvbnMpOwogICAgaWYgKHVzZVZib18pIHsKICAgICAgICBtZXNoXy5yZW5kZXJfdmJvKCk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBtZXNoXy5yZW5kZXJfYXJyYXkoKTsKICAgIH0KICAgIGRlcHRoVGFyZ2V0Xy5kaXNhYmxlKCk7CgogICAgLy8gRHJhdyB0aGUgIm5vcm1hbCIgdmlldyBvZiB0aGUgaG9yc2UKICAgIG1vZGVsdmlld18ucHVzaCgpOwogICAgbW9kZWx2aWV3Xy50cmFuc2xhdGUoLWNlbnRlclZlY18ueCgpLCAtY2VudGVyVmVjXy55KCksIC0oY2VudGVyVmVjXy56KCkgKyAyLjAgKyByYWRpdXNfKSk7CiAgICBtb2RlbHZpZXdfLnJvdGF0ZShyb3RhdGlvbl8sIDAuMGYsIDEuMGYsIDAuMGYpOwogICAgaWYgKG9yaWVudE1vZGVsXykKICAgIHsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZShvcmllbnRhdGlvbkFuZ2xlXywgb3JpZW50YXRpb25WZWNfLngoKSwgb3JpZW50YXRpb25WZWNfLnkoKSwgb3JpZW50YXRpb25WZWNfLnooKSk7CiAgICB9CiAgICBtdnAgPSBwcm9qZWN0aW9uXy5nZXRDdXJyZW50KCk7CiAgICBtdnAgKj0gbW9kZWx2aWV3Xy5nZXRDdXJyZW50KCk7CgogICAgcHJvZ3JhbV8uc3RhcnQoKTsKICAgIGdsQWN0aXZlVGV4dHVyZShHTF9URVhUVVJFMCk7CiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIGRlcHRoVGFyZ2V0Xy5kZXB0aFRleHR1cmUoKSk7CiAgICBwcm9ncmFtX1siRGlzdGFuY2VNYXAiXSA9IDA7CiAgICBnbEFjdGl2ZVRleHR1cmUoR0xfVEVYVFVSRTEpOwogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBkZXB0aFRhcmdldF8uY29sb3JUZXh0dXJlKCkpOwogICAgcHJvZ3JhbV9bIk5vcm1hbE1hcCJdID0gMTsKICAgIGdsQWN0aXZlVGV4dHVyZShHTF9URVhUVVJFMik7CiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHRleHR1cmVfKTsKICAgIHByb2dyYW1fWyJJbWFnZU1hcCJdID0gMjsKICAgIC8vIExvYWQgYm90aCB0aGUgbW9kZWx2aWV3KnByb2plY3Rpb24gYXMgd2VsbCBhcyB0aGUgbW9kZWx2aWV3IG1hdHJpeCBpdHNlbGYKICAgIHByb2dyYW1fWyJNb2RlbFZpZXdQcm9qZWN0aW9uTWF0cml4Il0gPSBtdnA7CiAgICBwcm9ncmFtX1siTW9kZWxWaWV3TWF0cml4Il0gPSBtb2RlbHZpZXdfLmdldEN1cnJlbnQoKTsKICAgIC8vIExvYWQgdGhlIE5vcm1hbE1hdHJpeCB1bmlmb3JtIGluIHRoZSBzaGFkZXIuIFRoZSBOb3JtYWxNYXRyaXggaXMgdGhlCiAgICAvLyBpbnZlcnNlIHRyYW5zcG9zZSBvZiB0aGUgbW9kZWwgdmlldyBtYXRyaXguCiAgICBtYXQ0IG5vcm1hbF9tYXRyaXgobW9kZWx2aWV3Xy5nZXRDdXJyZW50KCkpOwogICAgbm9ybWFsX21hdHJpeC5pbnZlcnNlKCkudHJhbnNwb3NlKCk7CiAgICBwcm9ncmFtX1siTm9ybWFsTWF0cml4Il0gPSBub3JtYWxfbWF0cml4OwogICAgcHJvZ3JhbV9bIkxpZ2h0TWF0cml4Il0gPSBsaWdodF87CiAgICBhdHRyaWJfbG9jYXRpb25zLmNsZWFyKCk7CiAgICBhdHRyaWJfbG9jYXRpb25zLnB1c2hfYmFjayhwcm9ncmFtX1sicG9zaXRpb24iXS5sb2NhdGlvbigpKTsKICAgIGF0dHJpYl9sb2NhdGlvbnMucHVzaF9iYWNrKHByb2dyYW1fWyJub3JtYWwiXS5sb2NhdGlvbigpKTsKICAgIG1lc2hfLnNldF9hdHRyaWJfbG9jYXRpb25zKGF0dHJpYl9sb2NhdGlvbnMpOwogICAgaWYgKHVzZVZib18pIHsKICAgICAgICBtZXNoXy5yZW5kZXJfdmJvKCk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBtZXNoXy5yZW5kZXJfYXJyYXkoKTsKICAgIH0KCiAgICAvLyBQZXItZnJhbWUgY2xlYW51cAogICAgbW9kZWx2aWV3Xy5wb3AoKTsKfQoK