Ly8KLy8gQ29weXJpZ2h0IKkgMjAxMiBMaW5hcm8gTGltaXRlZAovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgZ2xtYXJrMiBPcGVuR0wgKEVTKSAyLjAgYmVuY2htYXJrLgovLwovLyBnbG1hcmsyIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlCi8vIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKLy8gRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIKLy8gdmVyc2lvbi4KLy8KLy8gZ2xtYXJrMiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKLy8gV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUwovLyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCi8vIGRldGFpbHMuCi8vCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGgKLy8gZ2xtYXJrMi4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KLy8KLy8gQXV0aG9yczoKLy8gIEplc3NlIEJhcmtlcgovLwojaW5jbHVkZSAic2NlbmUtcmVmcmFjdC5oIgojaW5jbHVkZSAibW9kZWwuaCIKI2luY2x1ZGUgInRleHR1cmUuaCIKI2luY2x1ZGUgInV0aWwuaCIKI2luY2x1ZGUgImxvZy5oIgojaW5jbHVkZSAic2hhZGVyLXNvdXJjZS5oIgoKdXNpbmcgc3RkOjpzdHJpbmc7CnVzaW5nIHN0ZDo6dmVjdG9yOwp1c2luZyBzdGQ6Om1hcDsKdXNpbmcgTGliTWF0cml4OjptYXQ0Owp1c2luZyBMaWJNYXRyaXg6OnZlYzQ7CnVzaW5nIExpYk1hdHJpeDo6dmVjMzsKCnN0YXRpYyBjb25zdCB2ZWM0IGxpZ2h0UG9zaXRpb24oMS4wZiwgMS4wZiwgMi4wZiwgMS4wZik7CgovLwovLyBQdWJsaWMgaW50ZXJmYWNlcwovLwoKU2NlbmVSZWZyYWN0OjpTY2VuZVJlZnJhY3QoQ2FudmFzJiBjYW52YXMpIDoKICAgIFNjZW5lKGNhbnZhcywgInJlZnJhY3QiKSwKICAgIHByaXZfKDApCnsKICAgIGNvbnN0IE1vZGVsTWFwJiBtb2RlbE1hcCA9IE1vZGVsOjpmaW5kX21vZGVscygpOwogICAgc3RyaW5nIG9wdGlvblZhbHVlczsKICAgIGZvciAoTW9kZWxNYXA6OmNvbnN0X2l0ZXJhdG9yIG1vZGVsSXQgPSBtb2RlbE1hcC5iZWdpbigpOwogICAgICAgICBtb2RlbEl0ICE9IG1vZGVsTWFwLmVuZCgpOwogICAgICAgICBtb2RlbEl0KyspCiAgICB7CiAgICAgICAgc3RhdGljIGJvb2wgZG9TZXBhcmF0b3IoZmFsc2UpOwogICAgICAgIGlmIChkb1NlcGFyYXRvcikKICAgICAgICB7CiAgICAgICAgICAgIG9wdGlvblZhbHVlcyArPSAiLCI7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHN0cmluZyYgY3VyTmFtZSA9IG1vZGVsSXQtPmZpcnN0OwogICAgICAgIG9wdGlvblZhbHVlcyArPSBjdXJOYW1lOwogICAgICAgIGRvU2VwYXJhdG9yID0gdHJ1ZTsKICAgIH0KICAgIG9wdGlvbnNfWyJtb2RlbCJdID0gU2NlbmU6Ok9wdGlvbigibW9kZWwiLCAiYnVubnkiLCAiV2hpY2ggbW9kZWwgdG8gdXNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25WYWx1ZXMpOwogICAgb3B0aW9uVmFsdWVzID0gIiI7CiAgICBjb25zdCBUZXh0dXJlTWFwJiB0ZXh0dXJlTWFwID0gVGV4dHVyZTo6ZmluZF90ZXh0dXJlcygpOwogICAgZm9yIChUZXh0dXJlTWFwOjpjb25zdF9pdGVyYXRvciB0ZXh0dXJlSXQgPSB0ZXh0dXJlTWFwLmJlZ2luKCk7CiAgICAgICAgIHRleHR1cmVJdCAhPSB0ZXh0dXJlTWFwLmVuZCgpOwogICAgICAgICB0ZXh0dXJlSXQrKykKICAgIHsKICAgICAgICBzdGF0aWMgYm9vbCBkb1NlcGFyYXRvcihmYWxzZSk7CiAgICAgICAgaWYgKGRvU2VwYXJhdG9yKQogICAgICAgIHsKICAgICAgICAgICAgb3B0aW9uVmFsdWVzICs9ICIsIjsKICAgICAgICB9CiAgICAgICAgY29uc3Qgc3RyaW5nJiBjdXJOYW1lID0gdGV4dHVyZUl0LT5maXJzdDsKICAgICAgICBvcHRpb25WYWx1ZXMgKz0gY3VyTmFtZTsKICAgICAgICBkb1NlcGFyYXRvciA9IHRydWU7CiAgICB9CiAgICBvcHRpb25zX1sidGV4dHVyZSJdID0gU2NlbmU6Ok9wdGlvbigidGV4dHVyZSIsICJuYXNhMSIsICJXaGljaCB0ZXh0dXJlIHRvIHVzZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25WYWx1ZXMpOwogICAgb3B0aW9uc19bInVzZS12Ym8iXSA9IFNjZW5lOjpPcHRpb24oInVzZS12Ym8iLCAidHJ1ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiV2hldGhlciB0byB1c2UgVkJPcyBmb3IgcmVuZGVyaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWxzZSx0cnVlIik7CiAgICBvcHRpb25zX1siaW50ZXJsZWF2ZSJdID0gU2NlbmU6Ok9wdGlvbigiaW50ZXJsZWF2ZSIsICJmYWxzZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiV2hldGhlciB0byBpbnRlcmxlYXZlIHZlcnRleCBhdHRyaWJ1dGUgZGF0YSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFsc2UsdHJ1ZSIpOwp9CgpTY2VuZVJlZnJhY3Q6On5TY2VuZVJlZnJhY3QoKQp7CiAgICBkZWxldGUgcHJpdl87Cn0KCmJvb2wKU2NlbmVSZWZyYWN0OjpzdXBwb3J0ZWQoYm9vbCBzaG93X2Vycm9ycykKewogICAgc3RhdGljIGNvbnN0IHN0cmluZyBvZXNfZGVwdGhfdGV4dHVyZSgiR0xfT0VTX2RlcHRoX3RleHR1cmUiKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgYXJiX2RlcHRoX3RleHR1cmUoIkdMX0FSQl9kZXB0aF90ZXh0dXJlIik7CiAgICBpZiAoIUdMRXh0ZW5zaW9uczo6c3VwcG9ydChvZXNfZGVwdGhfdGV4dHVyZSkgJiYKICAgICAgICAhR0xFeHRlbnNpb25zOjpzdXBwb3J0KGFyYl9kZXB0aF90ZXh0dXJlKSkgewogICAgICAgIGlmIChzaG93X2Vycm9ycykgewogICAgICAgICAgICBMb2c6OmVycm9yKCJXZSBkbyBub3QgaGF2ZSB0aGUgZGVwdGggdGV4dHVyZSBleHRlbnNpb24hISFcbiIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgcmV0dXJuIHRydWU7Cn0KCmJvb2wKU2NlbmVSZWZyYWN0Ojpsb2FkKCkKewogICAgcnVubmluZ18gPSBmYWxzZTsKICAgIHJldHVybiB0cnVlOwp9Cgp2b2lkClNjZW5lUmVmcmFjdDo6dW5sb2FkKCkKewp9Cgpib29sClNjZW5lUmVmcmFjdDo6c2V0dXAoKQp7CiAgICAvLyBJZiB0aGUgc2NlbmUgaXNuJ3Qgc3VwcG9ydGVkLCBkb24ndCBib3RoZXIgdG8gZ28gdGhyb3VnaCBzZXR1cC4KICAgIGlmICghc3VwcG9ydGVkKGZhbHNlKSB8fCAhU2NlbmU6OnNldHVwKCkpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHByaXZfID0gbmV3IFJlZnJhY3RQcml2YXRlKGNhbnZhc18pOwogICAgaWYgKCFwcml2Xy0+c2V0dXAob3B0aW9uc18pKSB7CiAgICAgICAgZGVsZXRlIHByaXZfOwogICAgICAgIHByaXZfID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLy8gU2V0IGNvcmUgc2NlbmUgdGltaW5nIGFmdGVyIGFjdHVhbCBpbml0aWFsaXphdGlvbiBzbyB3ZSBkb24ndCBtZWFzdXJlCiAgICAvLyBzZXQgdXAgdGltZS4KICAgIHN0YXJ0VGltZV8gPSBVdGlsOjpnZXRfdGltZXN0YW1wX3VzKCkgLyAxMDAwMDAwLjA7CiAgICBsYXN0VXBkYXRlVGltZV8gPSBzdGFydFRpbWVfOwogICAgcnVubmluZ18gPSB0cnVlOwoKICAgIHJldHVybiB0cnVlOwp9Cgp2b2lkClNjZW5lUmVmcmFjdDo6dGVhcmRvd24oKQp7CiAgICAvLyBBZGQgc2NlbmUtc3BlY2lmaWMgdGVhcmRvd24gaGVyZQogICAgcHJpdl8tPnRlYXJkb3duKCk7CiAgICBTY2VuZTo6dGVhcmRvd24oKTsKfQoKdm9pZApTY2VuZVJlZnJhY3Q6OnVwZGF0ZSgpCnsKICAgIFNjZW5lOjp1cGRhdGUoKTsKICAgIC8vIEFkZCBzY2VuZS1zcGVjaWZpYyB1cGRhdGUgaGVyZQogICAgcHJpdl8tPnVwZGF0ZShsYXN0VXBkYXRlVGltZV8gLSBzdGFydFRpbWVfKTsKfQoKdm9pZApTY2VuZVJlZnJhY3Q6OmRyYXcoKQp7CiAgICBwcml2Xy0+ZHJhdygpOwp9CgpTY2VuZTo6VmFsaWRhdGlvblJlc3VsdApTY2VuZVJlZnJhY3Q6OnZhbGlkYXRlKCkKewogICAgcmV0dXJuIFNjZW5lOjpWYWxpZGF0aW9uVW5rbm93bjsKfQoKLy8KLy8gUHJpdmF0ZSBpbnRlcmZhY2VzCi8vCgpib29sCkRpc3RhbmNlUmVuZGVyVGFyZ2V0OjpzZXR1cCh1bnNpZ25lZCBpbnQgd2lkdGgsIHVuc2lnbmVkIGludCBoZWlnaHQpCnsKICAgIGNhbnZhc193aWR0aF8gPSB3aWR0aDsKICAgIGNhbnZhc19oZWlnaHRfID0gaGVpZ2h0OwogICAgd2lkdGhfID0gY2FudmFzX3dpZHRoXyAqIDI7CiAgICBoZWlnaHRfID0gY2FudmFzX2hlaWdodF8gKiAyOwoKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgdnR4X3NoYWRlcl9maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2RlcHRoLnZlcnQiKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgZnJnX3NoYWRlcl9maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2RlcHRoLmZyYWciKTsKCiAgICBTaGFkZXJTb3VyY2UgdnR4X3NvdXJjZSh2dHhfc2hhZGVyX2ZpbGVuYW1lKTsKICAgIFNoYWRlclNvdXJjZSBmcmdfc291cmNlKGZyZ19zaGFkZXJfZmlsZW5hbWUpOwoKICAgIGlmICghU2NlbmU6OmxvYWRfc2hhZGVyc19mcm9tX3N0cmluZ3MocHJvZ3JhbV8sIHZ0eF9zb3VyY2Uuc3RyKCksIGZyZ19zb3VyY2Uuc3RyKCkpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIGdsR2VuVGV4dHVyZXMoMiwgJnRleF9bMF0pOwogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCB0ZXhfW0RFUFRIXSk7CiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfV1JBUF9TLCBHTF9DTEFNUF9UT19FREdFKTsKICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfQ0xBTVBfVE9fRURHRSk7CiAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwgR0xfREVQVEhfQ09NUE9ORU5ULCB3aWR0aF8sIGhlaWdodF8sIDAsCiAgICAgICAgICAgICAgICAgR0xfREVQVEhfQ09NUE9ORU5ULCBHTF9VTlNJR05FRF9JTlQsIDApOwogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCB0ZXhfW0NPTE9SXSk7CiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9MSU5FQVJfTUlQTUFQX0xJTkVBUik7CiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfUywgR0xfQ0xBTVBfVE9fRURHRSk7CiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX0NMQU1QX1RPX0VER0UpOwogICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIEdMX1JHQkEsIHdpZHRoXywgaGVpZ2h0XywgMCwKICAgICAgICAgICAgICAgICBHTF9SR0JBLCBHTF9VTlNJR05FRF9CWVRFLCAwKTsKICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CgogICAgZ2xHZW5GcmFtZWJ1ZmZlcnMoMSwgJmZib18pOwogICAgZ2xCaW5kRnJhbWVidWZmZXIoR0xfRlJBTUVCVUZGRVIsIGZib18pOwogICAgZ2xGcmFtZWJ1ZmZlclRleHR1cmUyRChHTF9GUkFNRUJVRkZFUiwgR0xfREVQVEhfQVRUQUNITUVOVCwgR0xfVEVYVFVSRV8yRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4X1tERVBUSF0sIDApOwogICAgZ2xGcmFtZWJ1ZmZlclRleHR1cmUyRChHTF9GUkFNRUJVRkZFUiwgR0xfQ09MT1JfQVRUQUNITUVOVDAsIEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleF9bQ09MT1JdLCAwKTsKICAgIHVuc2lnbmVkIGludCBzdGF0dXMgPSBnbENoZWNrRnJhbWVidWZmZXJTdGF0dXMoR0xfRlJBTUVCVUZGRVIpOwogICAgaWYgKHN0YXR1cyAhPSBHTF9GUkFNRUJVRkZFUl9DT01QTEVURSkgewogICAgICAgIExvZzo6ZXJyb3IoIkRlcHRoUmVuZGVyU3RhdGU6OnNldHVwOiBnbENoZWNrRnJhbWVidWZmZXJTdGF0dXMgZmFpbGVkICgweCV4KVxuIiwgc3RhdHVzKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBnbEJpbmRGcmFtZWJ1ZmZlcihHTF9GUkFNRUJVRkZFUiwgMCk7CgogICAgcmV0dXJuIHRydWU7Cn0KCnZvaWQKRGlzdGFuY2VSZW5kZXJUYXJnZXQ6OnRlYXJkb3duKCkKewogICAgcHJvZ3JhbV8uc3RvcCgpOwogICAgcHJvZ3JhbV8ucmVsZWFzZSgpOwogICAgaWYgKHRleF8pIHsKICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDIsICZ0ZXhfWzBdKTsKICAgICAgICB0ZXhfW0RFUFRIXSA9IHRleF9bQ09MT1JdID0gMDsKICAgIH0KICAgIGlmIChmYm9fKSB7CiAgICAgICAgZ2xEZWxldGVGcmFtZWJ1ZmZlcnMoMSwgJmZib18pOwogICAgICAgIGZib18gPSAwOwogICAgfQp9Cgp2b2lkCkRpc3RhbmNlUmVuZGVyVGFyZ2V0OjplbmFibGUoY29uc3QgbWF0NCYgbXZwKQp7CiAgICBwcm9ncmFtXy5zdGFydCgpOwogICAgcHJvZ3JhbV9bIk1vZGVsVmlld1Byb2plY3Rpb25NYXRyaXgiXSA9IG12cDsKICAgIGdsQmluZEZyYW1lYnVmZmVyKEdMX0ZSQU1FQlVGRkVSLCBmYm9fKTsKICAgIGdsRnJhbWVidWZmZXJUZXh0dXJlMkQoR0xfRlJBTUVCVUZGRVIsIEdMX0RFUFRIX0FUVEFDSE1FTlQsIEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleF9bREVQVEhdLCAwKTsKICAgIGdsRnJhbWVidWZmZXJUZXh0dXJlMkQoR0xfRlJBTUVCVUZGRVIsIEdMX0NPTE9SX0FUVEFDSE1FTlQwLCBHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXhfW0NPTE9SXSwgMCk7CiAgICBnbFZpZXdwb3J0KDAsIDAsIHdpZHRoXywgaGVpZ2h0Xyk7CiAgICBnbENsZWFyKEdMX0RFUFRIX0JVRkZFUl9CSVQgfCBHTF9DT0xPUl9CVUZGRVJfQklUKTsKICAgIGdsQ3VsbEZhY2UoR0xfRlJPTlQpOwogICAgZ2xEZXB0aEZ1bmMoR0xfR1JFQVRFUik7Cn0KCnZvaWQgRGlzdGFuY2VSZW5kZXJUYXJnZXQ6OmRpc2FibGUoKQp7CiAgICBnbEJpbmRGcmFtZWJ1ZmZlcihHTF9GUkFNRUJVRkZFUiwgMCk7CiAgICBnbFZpZXdwb3J0KDAsIDAsIGNhbnZhc193aWR0aF8sIGNhbnZhc19oZWlnaHRfKTsKICAgIGdsQ3VsbEZhY2UoR0xfQkFDSyk7CiAgICBnbERlcHRoRnVuYyhHTF9MRVFVQUwpOwp9Cgpib29sClJlZnJhY3RQcml2YXRlOjpzZXR1cChtYXA8c3RyaW5nLCBTY2VuZTo6T3B0aW9uPiYgb3B0aW9ucykKewogICAgLy8gUHJvZ3JhbSBvYmplY3Qgc2V0dXAKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgdnR4X3NoYWRlcl9maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2xpZ2h0LXJlZnJhY3QudmVydCIpOwogICAgc3RhdGljIGNvbnN0IHN0cmluZyBmcmdfc2hhZGVyX2ZpbGVuYW1lKEdMTUFSS19EQVRBX1BBVEgiL3NoYWRlcnMvbGlnaHQtcmVmcmFjdC5mcmFnIik7CiAgICBzdGF0aWMgY29uc3QgdmVjNCBtYXRlcmlhbERpZmZ1c2UoMS4wZiwgMS4wZiwgMS4wZiwgMC4wZik7CiAgICBzdGF0aWMgY29uc3QgdmVjNCBsaWdodENvbG9yKDAuNCwgMC40LCAwLjQsIDEuMCk7CgogICAgU2hhZGVyU291cmNlIHZ0eF9zb3VyY2UodnR4X3NoYWRlcl9maWxlbmFtZSk7CiAgICBTaGFkZXJTb3VyY2UgZnJnX3NvdXJjZShmcmdfc2hhZGVyX2ZpbGVuYW1lKTsKCiAgICBmcmdfc291cmNlLmFkZF9jb25zdCgiTGlnaHRDb2xvciIsIGxpZ2h0Q29sb3IpOwogICAgZnJnX3NvdXJjZS5hZGRfY29uc3QoIkxpZ2h0U291cmNlUG9zaXRpb24iLCBsaWdodFBvc2l0aW9uKTsKICAgIGZyZ19zb3VyY2UuYWRkX2NvbnN0KCJNYXRlcmlhbERpZmZ1c2UiLCBtYXRlcmlhbERpZmZ1c2UpOwoKICAgIGlmICghU2NlbmU6OmxvYWRfc2hhZGVyc19mcm9tX3N0cmluZ3MocHJvZ3JhbV8sIHZ0eF9zb3VyY2Uuc3RyKCksIGZyZ19zb3VyY2Uuc3RyKCkpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIGNvbnN0IHN0cmluZyYgd2hpY2hUZXh0dXJlKG9wdGlvbnNbInRleHR1cmUiXS52YWx1ZSk7CiAgICBpZiAoIVRleHR1cmU6OmxvYWQod2hpY2hUZXh0dXJlLCAmdGV4dHVyZV8sIEdMX0xJTkVBUiwgR0xfTElORUFSLCAwKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgLy8gTW9kZWwgc2V0dXAKICAgIE1vZGVsIG1vZGVsOwogICAgY29uc3Qgc3RyaW5nJiB3aGljaE1vZGVsKG9wdGlvbnNbIm1vZGVsIl0udmFsdWUpOwogICAgYm9vbCBtb2RlbExvYWRlZCA9IG1vZGVsLmxvYWQod2hpY2hNb2RlbCk7CgogICAgaWYoIW1vZGVsTG9hZGVkKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAvLyBOb3cgdGhhdCB3ZSdyZSBzdWNjZXNzZnVsbHkgbG9hZGVkLCB0aGVyZSBhcmUgYSBmZXcgcXVpcmtzIGFib3V0CiAgICAvLyBzb21lIG9mIHRoZSBrbm93biBtb2RlbHMgdGhhdCB3ZSBuZWVkIHRvIGFjY291bnQgZm9yLiAgVGhlIGRyYXcKICAgIC8vIGxvZ2ljIGZvciB0aGUgc2NlbmUgd2FudHMgdG8gcm90YXRlIHRoZSBtb2RlbCBhcm91bmQgdGhlIFkgYXhpcy4KICAgIC8vIE1vc3Qgb2Ygb3VyIG1vZGVscyBhcmUgZGVzY3JpYmVkIHRoaXMgd2F5LiAgU29tZSBuZWVkIGFkanVzdG1lbnQKICAgIC8vIChhbiBhZGRpdGlvbmFsIHJvdGF0aW9uIHRoYXQgZ2V0cyB0aGUgbW9kZWwgaW50byB0aGUgY29ycmVjdAogICAgLy8gb3JpZW50YXRpb24pLgogICAgLy8KICAgIC8vIEhlcmUncyBhIHN1bW1hcnk6CiAgICAvLwogICAgLy8gQW5nZWwgcm90YXRlcyBhcm91bmQgdGhlIFkgYXhpcwogICAgLy8gQXJtYWRpbGxvIHJvdGF0ZXMgYXJvdW5kIHRoZSBZIGF4aXMKICAgIC8vIEJ1ZGRoYSByb3RhdGVzIGFyb3VuZCB0aGUgWCBheGlzCiAgICAvLyBCdW5ueSByb3RhdGVzIGFyb3VuZCB0aGUgWSBheGlzCiAgICAvLyBEcmFnb24gcm90YXRlcyBhcm91bmQgdGhlIFggYXhpcwogICAgLy8gSG9yc2Ugcm90YXRlcyBhcm91bmQgdGhlIFkgYXhpcwogICAgaWYgKHdoaWNoTW9kZWwgPT0gImJ1ZGRoYSIgfHwgd2hpY2hNb2RlbCA9PSAiZHJhZ29uIikKICAgIHsKICAgICAgICBvcmllbnRNb2RlbF8gPSB0cnVlOwogICAgICAgIG9yaWVudGF0aW9uQW5nbGVfID0gLTkwLjA7CiAgICAgICAgb3JpZW50YXRpb25WZWNfID0gdmVjMygxLjAsIDAuMCwgMC4wKTsKICAgIH0KICAgIGVsc2UgaWYgKHdoaWNoTW9kZWwgPT0gImFybWFkaWxsbyIpCiAgICB7CiAgICAgICAgb3JpZW50TW9kZWxfID0gdHJ1ZTsKICAgICAgICBvcmllbnRhdGlvbkFuZ2xlXyA9IDE4MC4wOyAKICAgICAgICBvcmllbnRhdGlvblZlY18gPSB2ZWMzKDAuMCwgMS4wLCAwLjApOwogICAgfQoKICAgIG1vZGVsLmNhbGN1bGF0ZV9ub3JtYWxzKCk7CgogICAgLy8gTWVzaCBzZXR1cAogICAgdmVjdG9yPHN0ZDo6cGFpcjxNb2RlbDo6QXR0cmliVHlwZSwgaW50PiA+IGF0dHJpYnM7CiAgICBhdHRyaWJzLnB1c2hfYmFjayhzdGQ6OnBhaXI8TW9kZWw6OkF0dHJpYlR5cGUsIGludD4oTW9kZWw6OkF0dHJpYlR5cGVQb3NpdGlvbiwgMykpOwogICAgYXR0cmlicy5wdXNoX2JhY2soc3RkOjpwYWlyPE1vZGVsOjpBdHRyaWJUeXBlLCBpbnQ+KE1vZGVsOjpBdHRyaWJUeXBlTm9ybWFsLCAzKSk7CiAgICBtb2RlbC5jb252ZXJ0X3RvX21lc2gobWVzaF8sIGF0dHJpYnMpOwoKICAgIHVzZVZib18gPSAob3B0aW9uc1sidXNlLXZibyJdLnZhbHVlID09ICJ0cnVlIik7CiAgICBib29sIGludGVybGVhdmUgPSAob3B0aW9uc1siaW50ZXJsZWF2ZSJdLnZhbHVlID09ICJ0cnVlIik7CiAgICBtZXNoXy52Ym9fdXBkYXRlX21ldGhvZChNZXNoOjpWQk9VcGRhdGVNZXRob2RNYXApOwogICAgbWVzaF8uaW50ZXJsZWF2ZShpbnRlcmxlYXZlKTsKCiAgICBpZiAodXNlVmJvXykgewogICAgICAgIG1lc2hfLmJ1aWxkX3ZibygpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgbWVzaF8uYnVpbGRfYXJyYXkoKTsKICAgIH0KCiAgICAvLyBDYWxjdWxhdGUgYSBwcm9qZWN0aW9uIG1hdHJpeCB0aGF0IGlzIGEgZ29vZCBmaXQgZm9yIHRoZSBtb2RlbAogICAgdmVjMyBtYXhWZWMgPSBtb2RlbC5tYXhWZWMoKTsKICAgIHZlYzMgbWluVmVjID0gbW9kZWwubWluVmVjKCk7CiAgICB2ZWMzIGRpZmZWZWMgPSBtYXhWZWMgLSBtaW5WZWM7CiAgICBjZW50ZXJWZWNfID0gbWF4VmVjICsgbWluVmVjOwogICAgY2VudGVyVmVjXyAvPSAyLjA7CiAgICBmbG9hdCBkaWFtZXRlciA9IGRpZmZWZWMubGVuZ3RoKCk7CiAgICByYWRpdXNfID0gZGlhbWV0ZXIgLyAyOwogICAgZmxvYXQgZm92eSA9IDIuMCAqIGF0YW5mKHJhZGl1c18gLyAoMi4wICsgcmFkaXVzXykpOwogICAgZm92eSAvPSBNX1BJOwogICAgZm92eSAqPSAxODAuMDsKICAgIGZsb2F0IGFzcGVjdChzdGF0aWNfY2FzdDxmbG9hdD4oY2FudmFzXy53aWR0aCgpKS9zdGF0aWNfY2FzdDxmbG9hdD4oY2FudmFzXy5oZWlnaHQoKSkpOwogICAgcHJvamVjdGlvbl8ucGVyc3BlY3RpdmUoZm92eSwgYXNwZWN0LCAyLjAsIDIuMCArIGRpYW1ldGVyKTsKCiAgICAvLyBTZXQgdXAgdGhlIGxpZ2h0IG1hdHJpeCB3aXRoIGEgYmlhcyB0aGF0IHdpbGwgY29udmVydCB2YWx1ZXMKICAgIC8vIGluIHRoZSByYW5nZSBvZiBbLTEsIDFdIHRvIFswLCAxKV0sIHRoZW4gYWRkIGluIHRoZSBwcm9qZWN0aW9uCiAgICAvLyBhbmQgdGhlICJsb29rIGF0IiBtYXRyaXggZnJvbSB0aGUgbGlnaHQgcG9zaXRpb24uCiAgICBsaWdodF8gKj0gTGliTWF0cml4OjpNYXQ0Ojp0cmFuc2xhdGUoMC41LCAwLjUsIDAuNSk7CiAgICBsaWdodF8gKj0gTGliTWF0cml4OjpNYXQ0OjpzY2FsZSgwLjUsIDAuNSwgMC41KTsKICAgIGxpZ2h0XyAqPSBwcm9qZWN0aW9uXy5nZXRDdXJyZW50KCk7CiAgICBsaWdodF8gKj0gTGliTWF0cml4OjpNYXQ0Ojpsb29rQXQobGlnaHRQb3NpdGlvbi54KCksIGxpZ2h0UG9zaXRpb24ueSgpLCBsaWdodFBvc2l0aW9uLnooKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLjAsIDAuMCwgMC4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAuMCwgMS4wLCAwLjApOwoKICAgIGlmICghZGVwdGhUYXJnZXRfLnNldHVwKGNhbnZhc18ud2lkdGgoKSwgY2FudmFzXy5oZWlnaHQoKSkpIHsKICAgICAgICBMb2c6OmVycm9yKCJGYWlsZWQgdG8gc2V0IHVwIHRoZSByZW5kZXIgdGFyZ2V0IGZvciB0aGUgZGVwdGggcGFzc1xuIik7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHJldHVybiB0cnVlOwp9CnZvaWQKUmVmcmFjdFByaXZhdGU6OnRlYXJkb3duKCkKewogICAgZGVwdGhUYXJnZXRfLnRlYXJkb3duKCk7CiAgICBwcm9ncmFtXy5zdG9wKCk7CiAgICBwcm9ncmFtXy5yZWxlYXNlKCk7CiAgICBtZXNoXy5yZXNldCgpOwp9Cgp2b2lkClJlZnJhY3RQcml2YXRlOjp1cGRhdGUoZG91YmxlIGVsYXBzZWRUaW1lKQp7CiAgICByb3RhdGlvbl8gPSByb3RhdGlvblNwZWVkXyAqIGVsYXBzZWRUaW1lOwp9Cgp2b2lkClJlZnJhY3RQcml2YXRlOjpkcmF3KCkKewogICAgLy8gVG8gcGVyZm9ybSB0aGUgZGVwdGggcGFzcywgc2V0IHVwIHRoZSBtb2RlbC12aWV3IHRyYW5zZm9ybWF0aW9uIHNvCiAgICAvLyB0aGF0IHdlJ3JlIGxvb2tpbmcgYXQgdGhlIGhvcnNlIGZyb20gdGhlIGxpZ2h0IHBvc2l0aW9uLiAgVGhhdCB3aWxsCiAgICAvLyBnaXZlIHVzIHRoZSBhcHByb3ByaWF0ZSB2aWV3IGZvciB0aGUgc2hhZG93LgogICAgbW9kZWx2aWV3Xy5wdXNoKCk7CiAgICBtb2RlbHZpZXdfLmxvYWRJZGVudGl0eSgpOwogICAgbW9kZWx2aWV3Xy5sb29rQXQobGlnaHRQb3NpdGlvbi54KCksIGxpZ2h0UG9zaXRpb24ueSgpLCBsaWdodFBvc2l0aW9uLnooKSwKICAgICAgICAgICAgICAgICAgICAgIDAuMCwgMC4wLCAwLjAsCiAgICAgICAgICAgICAgICAgICAgICAwLjAsIDEuMCwgMC4wKTsKICAgIG1vZGVsdmlld18ucm90YXRlKHJvdGF0aW9uXywgMC4wZiwgMS4wZiwgMC4wZik7CiAgICBpZiAob3JpZW50TW9kZWxfKQogICAgewogICAgICAgIG1vZGVsdmlld18ucm90YXRlKG9yaWVudGF0aW9uQW5nbGVfLCBvcmllbnRhdGlvblZlY18ueCgpLCBvcmllbnRhdGlvblZlY18ueSgpLCBvcmllbnRhdGlvblZlY18ueigpKTsKICAgIH0KICAgIG1hdDQgbXZwKHByb2plY3Rpb25fLmdldEN1cnJlbnQoKSk7CiAgICBtdnAgKj0gbW9kZWx2aWV3Xy5nZXRDdXJyZW50KCk7CiAgICBtb2RlbHZpZXdfLnBvcCgpOwoKICAgIC8vIEVuYWJsZSB0aGUgZGVwdGggcmVuZGVyIHRhcmdldCB3aXRoIG91ciB0cmFuc2Zvcm1hdGlvbiBhbmQgcmVuZGVyLgogICAgZGVwdGhUYXJnZXRfLmVuYWJsZShtdnApOwogICAgdmVjdG9yPEdMaW50PiBhdHRyaWJfbG9jYXRpb25zOwogICAgYXR0cmliX2xvY2F0aW9ucy5wdXNoX2JhY2soZGVwdGhUYXJnZXRfLnByb2dyYW0oKVsicG9zaXRpb24iXS5sb2NhdGlvbigpKTsKICAgIGF0dHJpYl9sb2NhdGlvbnMucHVzaF9iYWNrKGRlcHRoVGFyZ2V0Xy5wcm9ncmFtKClbIm5vcm1hbCJdLmxvY2F0aW9uKCkpOwogICAgbWVzaF8uc2V0X2F0dHJpYl9sb2NhdGlvbnMoYXR0cmliX2xvY2F0aW9ucyk7CiAgICBpZiAodXNlVmJvXykgewogICAgICAgIG1lc2hfLnJlbmRlcl92Ym8oKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIG1lc2hfLnJlbmRlcl9hcnJheSgpOwogICAgfQogICAgZGVwdGhUYXJnZXRfLmRpc2FibGUoKTsKCiAgICAvLyBEcmF3IHRoZSAibm9ybWFsIiB2aWV3IG9mIHRoZSBob3JzZQogICAgbW9kZWx2aWV3Xy5wdXNoKCk7CiAgICBtb2RlbHZpZXdfLnRyYW5zbGF0ZSgtY2VudGVyVmVjXy54KCksIC1jZW50ZXJWZWNfLnkoKSwgLShjZW50ZXJWZWNfLnooKSArIDIuMCArIHJhZGl1c18pKTsKICAgIG1vZGVsdmlld18ucm90YXRlKHJvdGF0aW9uXywgMC4wZiwgMS4wZiwgMC4wZik7CiAgICBpZiAob3JpZW50TW9kZWxfKQogICAgewogICAgICAgIG1vZGVsdmlld18ucm90YXRlKG9yaWVudGF0aW9uQW5nbGVfLCBvcmllbnRhdGlvblZlY18ueCgpLCBvcmllbnRhdGlvblZlY18ueSgpLCBvcmllbnRhdGlvblZlY18ueigpKTsKICAgIH0KICAgIG12cCA9IHByb2plY3Rpb25fLmdldEN1cnJlbnQoKTsKICAgIG12cCAqPSBtb2RlbHZpZXdfLmdldEN1cnJlbnQoKTsKCiAgICBwcm9ncmFtXy5zdGFydCgpOwogICAgZ2xBY3RpdmVUZXh0dXJlKEdMX1RFWFRVUkUwKTsKICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgZGVwdGhUYXJnZXRfLmRlcHRoVGV4dHVyZSgpKTsKICAgIHByb2dyYW1fWyJEaXN0YW5jZU1hcCJdID0gMDsKICAgIGdsQWN0aXZlVGV4dHVyZShHTF9URVhUVVJFMSk7CiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIGRlcHRoVGFyZ2V0Xy5jb2xvclRleHR1cmUoKSk7CiAgICBwcm9ncmFtX1siTm9ybWFsTWFwIl0gPSAxOwogICAgZ2xBY3RpdmVUZXh0dXJlKEdMX1RFWFRVUkUyKTsKICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdGV4dHVyZV8pOwogICAgcHJvZ3JhbV9bIkltYWdlTWFwIl0gPSAyOwogICAgLy8gTG9hZCBib3RoIHRoZSBtb2RlbHZpZXcqcHJvamVjdGlvbiBhcyB3ZWxsIGFzIHRoZSBtb2RlbHZpZXcgbWF0cml4IGl0c2VsZgogICAgcHJvZ3JhbV9bIk1vZGVsVmlld1Byb2plY3Rpb25NYXRyaXgiXSA9IG12cDsKICAgIHByb2dyYW1fWyJNb2RlbFZpZXdNYXRyaXgiXSA9IG1vZGVsdmlld18uZ2V0Q3VycmVudCgpOwogICAgLy8gTG9hZCB0aGUgTm9ybWFsTWF0cml4IHVuaWZvcm0gaW4gdGhlIHNoYWRlci4gVGhlIE5vcm1hbE1hdHJpeCBpcyB0aGUKICAgIC8vIGludmVyc2UgdHJhbnNwb3NlIG9mIHRoZSBtb2RlbCB2aWV3IG1hdHJpeC4KICAgIG1hdDQgbm9ybWFsX21hdHJpeChtb2RlbHZpZXdfLmdldEN1cnJlbnQoKSk7CiAgICBub3JtYWxfbWF0cml4LmludmVyc2UoKS50cmFuc3Bvc2UoKTsKICAgIHByb2dyYW1fWyJOb3JtYWxNYXRyaXgiXSA9IG5vcm1hbF9tYXRyaXg7CiAgICBwcm9ncmFtX1siTGlnaHRNYXRyaXgiXSA9IGxpZ2h0XzsKICAgIGF0dHJpYl9sb2NhdGlvbnMuY2xlYXIoKTsKICAgIGF0dHJpYl9sb2NhdGlvbnMucHVzaF9iYWNrKHByb2dyYW1fWyJwb3NpdGlvbiJdLmxvY2F0aW9uKCkpOwogICAgYXR0cmliX2xvY2F0aW9ucy5wdXNoX2JhY2socHJvZ3JhbV9bIm5vcm1hbCJdLmxvY2F0aW9uKCkpOwogICAgbWVzaF8uc2V0X2F0dHJpYl9sb2NhdGlvbnMoYXR0cmliX2xvY2F0aW9ucyk7CiAgICBpZiAodXNlVmJvXykgewogICAgICAgIG1lc2hfLnJlbmRlcl92Ym8oKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIG1lc2hfLnJlbmRlcl9hcnJheSgpOwogICAgfQoKICAgIC8vIFBlci1mcmFtZSBjbGVhbnVwCiAgICBtb2RlbHZpZXdfLnBvcCgpOwp9Cgo=