LyoKICogSVdpbmVEM0RCYXNlVGV4dHVyZSBJbXBsZW1lbnRhdGlvbgogKgogKiBDb3B5cmlnaHQgMjAwMi0yMDA0IEphc29uIEVkbWVhZGVzCiAqIENvcHlyaWdodCAyMDAyLTIwMDQgUmFwaGFlbCBKdW5xdWVpcmEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDctMjAwOCBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmVkM2RfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZDNkX3RleHR1cmUpOwojZGVmaW5lIEdMSU5GT19MT0NBVElPTiBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5hZGFwdGVyLT5nbF9pbmZvCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgIElXaW5lRDNEQmFzZVRleHR1cmUgSVVua25vd24gcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfUXVlcnlJbnRlcmZhY2UoSVdpbmVEM0RCYXNlVGV4dHVyZSAqaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwb2JqKQp7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqVGhpcyA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKICAgIGlmIChJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lVbmtub3duKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVdpbmVEM0RCYXNlKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVdpbmVEM0RSZXNvdXJjZSkKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUpKSB7CiAgICAgICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqcHBvYmogPSBUaGlzOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQogICAgKnBwb2JqID0gTlVMTDsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpVTE9ORyBXSU5BUEkgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfQWRkUmVmKElXaW5lRDNEQmFzZVRleHR1cmUgKmlmYWNlKSB7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqVGhpcyA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlc291cmNlLnJlZik7CgogICAgVFJBQ0UoIiglcCkgOiBBZGRSZWYgaW5jcmVhc2luZyBmcm9tICVkXG4iLCBUaGlzLHJlZiAtIDEpOwogICAgcmV0dXJuIHJlZjsKfQoKVUxPTkcgV0lOQVBJIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX1JlbGVhc2UoSVdpbmVEM0RCYXNlVGV4dHVyZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICpUaGlzID0gKElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZiArIDEpOwogICAgaWYgKHJlZiA9PSAwKSB7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfQ2xlYW5VcChpZmFjZSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICB9CiAgICByZXR1cm4gcmVmOwp9CgovKiBjbGFzcyBzdGF0aWMgKi8Kdm9pZCBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9DbGVhblVwKElXaW5lRDNEQmFzZVRleHR1cmUgKmlmYWNlKSB7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqVGhpcyA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgIFRSQUNFKCIoJXApIDogdGV4dHVyZU5hbWUoJWQpXG4iLCBUaGlzLCBUaGlzLT5iYXNlVGV4dHVyZS50ZXh0dXJlTmFtZSk7CiAgICBpZiAoVGhpcy0+YmFzZVRleHR1cmUudGV4dHVyZU5hbWUgIT0gMCkgewogICAgICAgIEFjdGl2YXRlQ29udGV4dChkZXZpY2UsIGRldmljZS0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIFRSQUNFKCIoJXApIDogRGVsZXRpbmcgdGV4dHVyZSAlZFxuIiwgVGhpcywgVGhpcy0+YmFzZVRleHR1cmUudGV4dHVyZU5hbWUpOwogICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJlRoaXMtPmJhc2VUZXh0dXJlLnRleHR1cmVOYW1lKTsKICAgICAgICBMRUFWRV9HTCgpOwogICAgfQogICAgSVdpbmVEM0RSZXNvdXJjZUltcGxfQ2xlYW5VcCgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzREJhc2VUZXh0dXJlIElXaW5lRDNEUmVzb3VyY2UgcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfR2V0RGV2aWNlKElXaW5lRDNEQmFzZVRleHR1cmUgKmlmYWNlLCBJV2luZUQzRERldmljZSoqIHBwRGV2aWNlKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0RGV2aWNlKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHBwRGV2aWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfU2V0UHJpdmF0ZURhdGEoSVdpbmVEM0RCYXNlVGV4dHVyZSAqaWZhY2UsIFJFRkdVSUQgcmVmZ3VpZCwgQ09OU1Qgdm9pZCogcERhdGEsIERXT1JEIFNpemVPZkRhdGEsIERXT1JEIEZsYWdzKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfU2V0UHJpdmF0ZURhdGEoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcmVmZ3VpZCwgcERhdGEsIFNpemVPZkRhdGEsIEZsYWdzKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfR2V0UHJpdmF0ZURhdGEoSVdpbmVEM0RCYXNlVGV4dHVyZSAqaWZhY2UsIFJFRkdVSUQgcmVmZ3VpZCwgdm9pZCogcERhdGEsIERXT1JEKiBwU2l6ZU9mRGF0YSkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldFByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQsIHBEYXRhLCBwU2l6ZU9mRGF0YSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0ZyZWVQcml2YXRlRGF0YShJV2luZUQzREJhc2VUZXh0dXJlICppZmFjZSwgUkVGR1VJRCByZWZndWlkKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfRnJlZVByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQpOwp9CgpEV09SRCAgICBXSU5BUEkgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX1NldFByaW9yaXR5KElXaW5lRDNEQmFzZVRleHR1cmUgKmlmYWNlLCBEV09SRCBQcmlvcml0eU5ldykgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX1NldFByaW9yaXR5KChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIFByaW9yaXR5TmV3KTsKfQoKRFdPUkQgICAgV0lOQVBJICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9HZXRQcmlvcml0eShJV2luZUQzREJhc2VUZXh0dXJlICppZmFjZSkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldFByaW9yaXR5KChJV2luZUQzRFJlc291cmNlICopaWZhY2UpOwp9Cgp2b2lkICAgICBXSU5BUEkgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX1ByZUxvYWQoSVdpbmVEM0RCYXNlVGV4dHVyZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEUmVzb3VyY2VJbXBsX1ByZUxvYWQoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSk7Cn0KCnZvaWQgICAgIFdJTkFQSSAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfVW5Mb2FkKElXaW5lRDNEQmFzZVRleHR1cmUgKmlmYWNlKSB7CiAgICBJV2luZUQzRFRleHR1cmVJbXBsICpUaGlzID0gKElXaW5lRDNEVGV4dHVyZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKCiAgICBpZihUaGlzLT5iYXNlVGV4dHVyZS50ZXh0dXJlTmFtZSkgewogICAgICAgIEFjdGl2YXRlQ29udGV4dChkZXZpY2UsIGRldmljZS0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJlRoaXMtPmJhc2VUZXh0dXJlLnRleHR1cmVOYW1lKTsKICAgICAgICBUaGlzLT5iYXNlVGV4dHVyZS50ZXh0dXJlTmFtZSA9IDA7CiAgICAgICAgTEVBVkVfR0woKTsKICAgIH0KICAgIFRoaXMtPmJhc2VUZXh0dXJlLmRpcnR5ID0gVFJVRTsKfQoKV0lORUQzRFJFU09VUkNFVFlQRSBXSU5BUEkgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfR2V0VHlwZShJV2luZUQzREJhc2VUZXh0dXJlICppZmFjZSkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldFR5cGUoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0dldFBhcmVudChJV2luZUQzREJhc2VUZXh0dXJlICppZmFjZSwgSVVua25vd24gKipwUGFyZW50KSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0UGFyZW50KChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHBQYXJlbnQpOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RCYXNlVGV4dHVyZSBJV2luZUQzREJhc2VUZXh0dXJlIHBhcnRzIGZvbGxvdwogICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KCi8qIFRoZXJlIGlzIG5vIE9wZW5HTCBlcXVpdmFsZW50IG9mIHNldExPRCwgZ2V0TE9ELiBBbGwgdGhleSBkbyBhbnl3YXkgaXMgcHJpb3JpdGl6ZSB0ZXh0dXJlIGxvYWRpbmcKICogc28ganVzdCBwcmV0ZW5kIHRoYXQgdGhleSB3b3JrIHVubGVzcyBzb21ldGhpbmcgcmVhbGx5IG5lZWRzIGEgZmFpbHVyZS4gKi8KRFdPUkQgV0lOQVBJIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX1NldExPRChJV2luZUQzREJhc2VUZXh0dXJlICppZmFjZSwgRFdPUkQgTE9ETmV3KSB7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqVGhpcyA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKWlmYWNlOwoKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5wb29sICE9IFdJTkVEM0RQT09MX01BTkFHRUQpIHsKICAgICAgICByZXR1cm4gIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoTE9ETmV3ID49IFRoaXMtPmJhc2VUZXh0dXJlLmxldmVscykKICAgICAgICBMT0ROZXcgPSBUaGlzLT5iYXNlVGV4dHVyZS5sZXZlbHMgLSAxOwogICAgIFRoaXMtPmJhc2VUZXh0dXJlLkxPRCA9IExPRE5ldzsKCiAgICBUUkFDRSgiKCVwKSA6IHNldCBib2d1cyBMT0QgdG8gJWRcbiIsIFRoaXMsIFRoaXMtPmJhc2VUZXh0dXJlLkxPRCk7CgogICAgcmV0dXJuIFRoaXMtPmJhc2VUZXh0dXJlLkxPRDsKfQoKRFdPUkQgV0lOQVBJIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0dldExPRChJV2luZUQzREJhc2VUZXh0dXJlICppZmFjZSkgewogICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKilpZmFjZTsKCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UucG9vbCAhPSBXSU5FRDNEUE9PTF9NQU5BR0VEKSB7CiAgICAgICAgcmV0dXJuICBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICVkXG4iLCBUaGlzLCBUaGlzLT5iYXNlVGV4dHVyZS5MT0QpOwoKICAgIHJldHVybiBUaGlzLT5iYXNlVGV4dHVyZS5MT0Q7Cn0KCkRXT1JEIFdJTkFQSSBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9HZXRMZXZlbENvdW50KElXaW5lRDNEQmFzZVRleHR1cmUgKmlmYWNlKSB7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqVGhpcyA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmcgJWRcbiIsIFRoaXMsIFRoaXMtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICByZXR1cm4gVGhpcy0+YmFzZVRleHR1cmUubGV2ZWxzOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9TZXRBdXRvR2VuRmlsdGVyVHlwZShJV2luZUQzREJhc2VUZXh0dXJlICppZmFjZSwgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIEZpbHRlclR5cGUpIHsKICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqVGhpcyA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKWlmYWNlOwogIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICBVSU5UIHRleHR1cmVEaW1lbnNpb25zID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUZXh0dXJlRGltZW5zaW9ucyhpZmFjZSk7CgogIGlmICghKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX0FVVE9HRU5NSVBNQVApKSB7CiAgICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nIGludmFsaWQgY2FsbFxuIiwgVGhpcyk7CiAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogIH0KICBpZihUaGlzLT5iYXNlVGV4dHVyZS5maWx0ZXJUeXBlICE9IEZpbHRlclR5cGUpIHsKICAgICAgLyogV2hhdCBhYm91dCBtdWx0aXRocmVhZGluZz8gRG8gd2Ugd2FudCBhbGwgdGhlIGNvbnRleHQgb3ZlcmhlYWQganVzdCB0byBzZXQgdGhpcyB2YWx1ZT8KICAgICAgICogT3Igc2hvdWxkIHdlIGRlbGF5IHRoZSBhcHBseWluZyB1bnRpbCB0aGUgdGV4dHVyZSBpcyB1c2VkIGZvciBkcmF3aW5nPyBGb3Igbm93LCBhcHBseQogICAgICAgKiBpbW1lZGlhdGVseS4KICAgICAgICovCiAgICAgIEFjdGl2YXRlQ29udGV4dChkZXZpY2UsIGRldmljZS0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgRU5URVJfR0woKTsKICAgICAgZ2xCaW5kVGV4dHVyZSh0ZXh0dXJlRGltZW5zaW9ucywgVGhpcy0+YmFzZVRleHR1cmUudGV4dHVyZU5hbWUpOwogICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwogICAgICBzd2l0Y2goRmlsdGVyVHlwZSkgewogICAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9OT05FOgogICAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9QT0lOVDoKICAgICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkodGV4dHVyZURpbWVuc2lvbnMsIEdMX0dFTkVSQVRFX01JUE1BUF9ISU5UX1NHSVMsIEdMX0ZBU1RFU1QpOwogICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkodGV4dHVyZURpbWVuc2lvbnMsIEdMX0dFTkVSQVRFX01JUE1BUF9ISU5UX1NHSVMsIEdMX0ZBU1RFU1QpIik7CgogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9MSU5FQVI6CiAgICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKHRleHR1cmVEaW1lbnNpb25zLCBHTF9HRU5FUkFURV9NSVBNQVBfSElOVF9TR0lTLCBHTF9OSUNFU1QpOwogICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkodGV4dHVyZURpbWVuc2lvbnMsIEdMX0dFTkVSQVRFX01JUE1BUF9ISU5UX1NHSVMsIEdMX05JQ0VTVCkiKTsKCiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgIFdBUk4oIlVuZXhwZWN0ZWQgZmlsdGVyIHR5cGUgJWQsIHNldHRpbmcgdG8gR0xfTklDRVNUXG4iLCBGaWx0ZXJUeXBlKTsKICAgICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkodGV4dHVyZURpbWVuc2lvbnMsIEdMX0dFTkVSQVRFX01JUE1BUF9ISU5UX1NHSVMsIEdMX05JQ0VTVCk7CiAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSh0ZXh0dXJlRGltZW5zaW9ucywgR0xfR0VORVJBVEVfTUlQTUFQX0hJTlRfU0dJUywgR0xfTklDRVNUKSIpOwogICAgICB9CiAgICAgIExFQVZFX0dMKCk7CiAgfQogIFRoaXMtPmJhc2VUZXh0dXJlLmZpbHRlclR5cGUgPSBGaWx0ZXJUeXBlOwogIFRSQUNFKCIoJXApIDpcbiIsIFRoaXMpOwogIHJldHVybiBXSU5FRDNEX09LOwp9CgpXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgV0lOQVBJIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0dldEF1dG9HZW5GaWx0ZXJUeXBlKElXaW5lRDNEQmFzZVRleHR1cmUgKmlmYWNlKSB7CiAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKilpZmFjZTsKICBGSVhNRSgiKCVwKSA6IHN0dWJcbiIsIFRoaXMpOwogIGlmICghKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX0FVVE9HRU5NSVBNQVApKSB7CiAgICAgcmV0dXJuIFdJTkVEM0RURVhGX05PTkU7CiAgfQogIHJldHVybiBUaGlzLT5iYXNlVGV4dHVyZS5maWx0ZXJUeXBlOwp9Cgp2b2lkIFdJTkFQSSBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9HZW5lcmF0ZU1pcFN1YkxldmVscyhJV2luZUQzREJhc2VUZXh0dXJlICppZmFjZSkgewogIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICpUaGlzID0gKElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICopaWZhY2U7CiAgLyogVE9ETzogaW1wbGVtZW50IGZpbHRlcnMgdXNpbmcgR0xfU0dJX2dlbmVyYXRlX21pcG1hcHMgaHR0cDovL29zcy5zZ2kuY29tL3Byb2plY3RzL29nbC1zYW1wbGUvcmVnaXN0cnkvU0dJUy9nZW5lcmF0ZV9taXBtYXAudHh0ICovCiAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICByZXR1cm4gOwp9CgovKiBJbnRlcm5hbCBmdW5jdGlvbiwgTm8gZDNkIG1hcHBpbmcgKi8KQk9PTCBXSU5BUEkgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfU2V0RGlydHkoSVdpbmVEM0RCYXNlVGV4dHVyZSAqaWZhY2UsIEJPT0wgZGlydHkpIHsKICAgIEJPT0wgb2xkOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKilpZmFjZTsKICAgIG9sZCA9IFRoaXMtPmJhc2VUZXh0dXJlLmRpcnR5OwogICAgVGhpcy0+YmFzZVRleHR1cmUuZGlydHkgPSBkaXJ0eTsKICAgIHJldHVybiBvbGQ7Cn0KCkJPT0wgV0lOQVBJIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0dldERpcnR5KElXaW5lRDNEQmFzZVRleHR1cmUgKmlmYWNlKSB7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqVGhpcyA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKWlmYWNlOwogICAgcmV0dXJuIFRoaXMtPmJhc2VUZXh0dXJlLmRpcnR5Owp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9CaW5kVGV4dHVyZShJV2luZUQzREJhc2VUZXh0dXJlICppZmFjZSkgewogICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKilpZmFjZTsKICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwogICAgVUlOVCB0ZXh0dXJlRGltZW5zaW9uczsKICAgIEJPT0wgaXNOZXdUZXh0dXJlID0gRkFMU0U7CiAgICBUUkFDRSgiKCVwKSA6IEFib3V0IHRvIGJpbmQgdGV4dHVyZVxuIiwgVGhpcyk7CgogICAgdGV4dHVyZURpbWVuc2lvbnMgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFRleHR1cmVEaW1lbnNpb25zKGlmYWNlKTsKICAgIEVOVEVSX0dMKCk7CiAgICAvKiBHZW5lcmF0ZSBhIHRleHR1cmUgbmFtZSBpZiB3ZSBkb24ndCBhbHJlYWR5IGhhdmUgb25lICovCiAgICBpZiAoVGhpcy0+YmFzZVRleHR1cmUudGV4dHVyZU5hbWUgPT0gMCkgewogICAgICAgIGdsR2VuVGV4dHVyZXMoMSwgJlRoaXMtPmJhc2VUZXh0dXJlLnRleHR1cmVOYW1lKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5UZXh0dXJlcyIpOwogICAgICAgIFRSQUNFKCJHZW5lcmF0ZWQgdGV4dHVyZSAlZFxuIiwgVGhpcy0+YmFzZVRleHR1cmUudGV4dHVyZU5hbWUpOwogICAgICAgIGlmIChUaGlzLT5yZXNvdXJjZS5wb29sID09IFdJTkVEM0RQT09MX0RFRkFVTFQpIHsKICAgICAgICAgICAgLyogVGVsbCBvcGVuZ2wgdG8gdHJ5IGFuZCBrZWVwIHRoaXMgdGV4dHVyZSBpbiB2aWRlbyByYW0gKHdlbGwgbW9zdGx5KSAqLwogICAgICAgICAgICBHTGNsYW1wZiB0bXA7CiAgICAgICAgICAgIHRtcCA9IDAuOWY7CiAgICAgICAgICAgIGdsUHJpb3JpdGl6ZVRleHR1cmVzKDEsICZUaGlzLT5iYXNlVGV4dHVyZS50ZXh0dXJlTmFtZSwgJnRtcCk7CgogICAgICAgIH0KICAgICAgICAvKiBJbml0aWFsaXNlIHRoZSBzdGF0ZSBvZiB0aGUgdGV4dHVyZSBvYmplY3QKICAgICAgICB0byB0aGUgb3BlbkdMIGRlZmF1bHRzLCBub3QgdGhlIGRpcmVjdHggZGVmYXVsdHMgKi8KICAgICAgICBUaGlzLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9BRERSRVNTVV0gICAgICA9IFdJTkVEM0RUQUREUkVTU19XUkFQOwogICAgICAgIFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX0FERFJFU1NWXSAgICAgID0gV0lORUQzRFRBRERSRVNTX1dSQVA7CiAgICAgICAgVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfQUREUkVTU1ddICAgICAgPSBXSU5FRDNEVEFERFJFU1NfV1JBUDsKICAgICAgICBUaGlzLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9CT1JERVJDT0xPUl0gICA9IDA7CiAgICAgICAgVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUFHRklMVEVSXSAgICAgPSBXSU5FRDNEVEVYRl9MSU5FQVI7CiAgICAgICAgVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUlORklMVEVSXSAgICAgPSBXSU5FRDNEVEVYRl9QT0lOVDsgLyogR0xfTkVBUkVTVF9NSVBNQVBfTElORUFSICovCiAgICAgICAgVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUlQRklMVEVSXSAgICAgPSBXSU5FRDNEVEVYRl9MSU5FQVI7IC8qIEdMX05FQVJFU1RfTUlQTUFQX0xJTkVBUiAqLwogICAgICAgIFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01BWE1JUExFVkVMXSAgID0gMDsKICAgICAgICBUaGlzLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NQVhBTklTT1RST1BZXSA9IDA7CiAgICAgICAgVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfU1JHQlRFWFRVUkVdICAgPSAwOwogICAgICAgIFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX0VMRU1FTlRJTkRFWF0gID0gMDsKICAgICAgICBUaGlzLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9ETUFQT0ZGU0VUXSAgICA9IDA7CiAgICAgICAgVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfVFNTQUREUkVTU1ddICAgPSBXSU5FRDNEVEFERFJFU1NfV1JBUDsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1NldERpcnR5KGlmYWNlLCBUUlVFKTsKICAgICAgICBpc05ld1RleHR1cmUgPSBUUlVFOwoKICAgICAgICBpZihUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9BVVRPR0VOTUlQTUFQKSB7CiAgICAgICAgICAgIC8qIFRoaXMgbWVhbnMgZG91YmxlIGJpbmRpbmcgdGhlIHRleHR1cmUgYXQgY3JlYXRpb24sIGJ1dCBrZWVwcyB0aGUgY29kZSBzaW1wbGVyIGFsbAogICAgICAgICAgICAgKiBpbiBhbGwsIGFuZCB0aGUgcnVuLXRpbWUgcGF0aCBmcmVlIGZyb20gYWRkaXRpb25hbCBjaGVja3MKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGdsQmluZFRleHR1cmUodGV4dHVyZURpbWVuc2lvbnMsIFRoaXMtPmJhc2VUZXh0dXJlLnRleHR1cmVOYW1lKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUiKTsKICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKHRleHR1cmVEaW1lbnNpb25zLCBHTF9HRU5FUkFURV9NSVBNQVBfU0dJUywgR0xfVFJVRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkodGV4dHVyZURpbWVuc2lvbnMsIEdMX0dFTkVSQVRFX01JUE1BUF9TR0lTLCBHTF9UUlVFKSIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBCaW5kIHRoZSB0ZXh0dXJlICovCiAgICBpZiAoVGhpcy0+YmFzZVRleHR1cmUudGV4dHVyZU5hbWUgIT0gMCkgewogICAgICAgIGdsQmluZFRleHR1cmUodGV4dHVyZURpbWVuc2lvbnMsIFRoaXMtPmJhc2VUZXh0dXJlLnRleHR1cmVOYW1lKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwogICAgICAgIGlmIChpc05ld1RleHR1cmUpIHsKICAgICAgICAgICAgLyogRm9yIGEgbmV3IHRleHR1cmUgd2UgaGF2ZSB0byBzZXQgdGhlIHRleHR1cmVzIGxldmVscyBhZnRlciBiaW5kaW5nIHRoZSB0ZXh0dXJlLgogICAgICAgICAgICAgKiBJbiB0aGVvcnkgdGhpcyBpcyBhbGwgd2Ugc2hvdWxkIGV2ZXIgaGF2ZSB0byBkbywgYnV0IGJlY2F1c2UgQVRJJ3MgZHJpdmVycyBhcmUgYnJva2VuLCB3ZQogICAgICAgICAgICAgKiBhbHNvIG5lZWQgdG8gc2V0IHRoZSB0ZXh0dXJlIGRpbWVuc2lvbnMgYmVmb3JlIHRoZSB0ZXh0dXJlIGlzIHNldAogICAgICAgICAgICAgKiBCZXdhcmUgdGhhdCB0ZXh0dXJlIHJlY3RhbmdsZXMgZG8gbm90IHN1cHBvcnQgbWlwbWFwcGluZy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKHRleHR1cmVEaW1lbnNpb25zICE9IEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQikgewogICAgICAgICAgICAgICAgVFJBQ0UoIlNldHRpbmcgR0xfVEVYVFVSRV9NQVhfTEVWRUwgdG8gJWRcbiIsIFRoaXMtPmJhc2VUZXh0dXJlLmxldmVscyAtIDEpOwogICAgICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKHRleHR1cmVEaW1lbnNpb25zLCBHTF9URVhUVVJFX01BWF9MRVZFTCwgVGhpcy0+YmFzZVRleHR1cmUubGV2ZWxzIC0gMSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpKHRleHR1cmVEaW1lbnNpb25zLCBHTF9URVhUVVJFX01BWF9MRVZFTCwgVGhpcy0+YmFzZVRleHR1cmUubGV2ZWxzKSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKHRleHR1cmVEaW1lbnNpb25zPT1HTF9URVhUVVJFX0NVQkVfTUFQX0FSQikgewogICAgICAgICAgICAgICAgLyogQ3ViZW1hcHMgYXJlIGFsd2F5cyBzZXQgdG8gY2xhbXAsIHJlZ2FyZGxlc3Mgb2YgdGhlIHNhbXBsZXIgc3RhdGUuICovCiAgICAgICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkodGV4dHVyZURpbWVuc2lvbnMsIEdMX1RFWFRVUkVfV1JBUF9TLCBHTF9DTEFNUF9UT19FREdFKTsKICAgICAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaSh0ZXh0dXJlRGltZW5zaW9ucywgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX0NMQU1QX1RPX0VER0UpOwogICAgICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKHRleHR1cmVEaW1lbnNpb25zLCBHTF9URVhUVVJFX1dSQVBfUiwgR0xfQ0xBTVBfVE9fRURHRSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgkJCiAgICB9IGVsc2UgeyAvKiB0aGlzIG9ubHkgaGFwcGVuZWQgaWYgd2UndmUgcnVuIG91dCBvZiBvcGVuR0wgdGV4dHVyZXMgKi8KICAgICAgICBXQVJOKCJUaGlzIHRleHR1cmUgZG9lc24ndCBoYXZlIGFuIG9wZW5HTCB0ZXh0dXJlIGFzc2lnbmVkIHRvIGl0XG4iKTsKICAgICAgICBociA9ICBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIExFQVZFX0dMKCk7CiAgICByZXR1cm4gaHI7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX1VuQmluZFRleHR1cmUoSVdpbmVEM0RCYXNlVGV4dHVyZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICpUaGlzID0gKElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICopaWZhY2U7CiAgICBVSU5UIHRleHR1cmVEaW1lbnNpb25zOwoKICAgIFRSQUNFKCIoJXApIDogQWJvdXQgdG8gYmluZCB0ZXh0dXJlXG4iLCBUaGlzKTsKICAgIHRleHR1cmVEaW1lbnNpb25zID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUZXh0dXJlRGltZW5zaW9ucyhpZmFjZSk7CgogICAgRU5URVJfR0woKTsKCiAgICBnbEJpbmRUZXh0dXJlKHRleHR1cmVEaW1lbnNpb25zLCAwKTsKI2lmIDAgLyogVE9ETzogY29udGV4dCBtYW5hZ2VyIHN1cHBvcnQgKi8KICAgICBJV2luZUQzRENvbnRleHRNYW5hZ2VyX1BvcFN0YXRlKFRoaXMtPmNvbnRleHRNYW5hZ2VyLCB0ZXh0dXJlRGltZW5zaW9ucywgRU5BQkxFRCwgTk9XIC8qIG1ha2Ugc3VyZSB0aGUgc3RhdGUgaXMgYXBwbGllZCBub3cgKi8pOwojZWxzZQogICAgZ2xEaXNhYmxlKHRleHR1cmVEaW1lbnNpb25zKTsKI2VuZGlmCgogICAgTEVBVkVfR0woKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpVSU5UIFdJTkFQSSBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9HZXRUZXh0dXJlRGltZW5zaW9ucyhJV2luZUQzREJhc2VUZXh0dXJlICppZmFjZSl7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqVGhpcyA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKWlmYWNlOwogICAgRklYTUUoIiglcCkgOiBUaGlzIHNob3VsZG4ndCBiZSBjYWxsZWRcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBpbmxpbmUgR0xlbnVtIHdhcnBMb29rdXBUeXBlKFdJTkVEM0RTQU1QTEVSU1RBVEVUWVBFIFR5cGUpIHsKICAgIHN3aXRjaChUeXBlKSB7CiAgICBjYXNlIFdJTkVEM0RTQU1QX0FERFJFU1NVOgogICAgICAgIHJldHVybiBHTF9URVhUVVJFX1dSQVBfUzsKICAgIGNhc2UgV0lORUQzRFNBTVBfQUREUkVTU1Y6CiAgICAgICAgcmV0dXJuIEdMX1RFWFRVUkVfV1JBUF9UOwogICAgY2FzZSBXSU5FRDNEU0FNUF9BRERSRVNTVzoKICAgICAgICByZXR1cm4gR0xfVEVYVFVSRV9XUkFQX1I7CiAgICBkZWZhdWx0OgogICAgICAgIEZJWE1FKCJVbmV4cGVjdGVkIHdhcnAgdHlwZSAlZFxuIiwgVHlwZSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBhcHBseV93cmFwKGNvbnN0IEdMaW50IHRleHR1cmVEaW1lbnNpb25zLCBjb25zdCBEV09SRCBzdGF0ZSwgY29uc3QgR0xpbnQgdHlwZSkgewogICAgR0xpbnQgd3JhcFBhcm07CgogICAgaWYgKHN0YXRlIDwgbWluTG9va3VwW1dJTkVMT09LVVBfV0FSUFBBUkFNXSB8fCBzdGF0ZSA+IG1heExvb2t1cFtXSU5FTE9PS1VQX1dBUlBQQVJBTV0pIHsKICAgICAgICBGSVhNRSgiVW5yZWNvZ25pemVkIG9yIHVuc3VwcG9ydGVkIFdJTkVEM0RUQUREUkVTU19VIHZhbHVlICVkXG4iLCBzdGF0ZSk7CiAgICB9IGVsc2UgewogICAgICAgIGlmKHRleHR1cmVEaW1lbnNpb25zPT1HTF9URVhUVVJFX0NVQkVfTUFQX0FSQikgewogICAgICAgICAgICAvKiBDdWJlbWFwcyBhcmUgYWx3YXlzIHNldCB0byBjbGFtcCwgcmVnYXJkbGVzcyBvZiB0aGUgc2FtcGxlciBzdGF0ZS4gKi8KICAgICAgICAgICAgd3JhcFBhcm0gPSBHTF9DTEFNUF9UT19FREdFOwogICAgICAgIH0gZWxzZSBpZih0ZXh0dXJlRGltZW5zaW9ucz09R0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCKSB7CiAgICAgICAgICAgIGlmKHN0YXRlID09IFdJTkVEM0RUQUREUkVTU19XUkFQKSB7CiAgICAgICAgICAgICAgICB3cmFwUGFybSA9IEdMX0NMQU1QX1RPX0VER0U7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB3cmFwUGFybSA9IHN0YXRlTG9va3VwW1dJTkVMT09LVVBfV0FSUFBBUkFNXVtzdGF0ZSAtIG1pbkxvb2t1cFtXSU5FTE9PS1VQX1dBUlBQQVJBTV1dOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgd3JhcFBhcm0gPSBzdGF0ZUxvb2t1cFtXSU5FTE9PS1VQX1dBUlBQQVJBTV1bc3RhdGUgLSBtaW5Mb29rdXBbV0lORUxPT0tVUF9XQVJQUEFSQU1dXTsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIlNldHRpbmcgV1JBUF9TIHRvICVkIGZvciAleFxuIiwgd3JhcFBhcm0sIHRleHR1cmVEaW1lbnNpb25zKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkodGV4dHVyZURpbWVuc2lvbnMsIHR5cGUsIHdyYXBQYXJtKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpKC4uLiwgdHlwZSwgd3JhcFBhcm0pIik7CiAgICB9Cn0KCnZvaWQgV0lOQVBJIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0FwcGx5U3RhdGVDaGFuZ2VzKElXaW5lRDNEQmFzZVRleHR1cmUgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEV09SRCB0ZXh0dXJlU3RhdGVzW1dJTkVEM0RfSElHSEVTVF9URVhUVVJFX1NUQVRFICsgMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERXT1JEIHNhbXBsZXJTdGF0ZXNbV0lORUQzRF9ISUdIRVNUX1NBTVBMRVJfU1RBVEUgKyAxXSkgewogICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKilpZmFjZTsKICAgIERXT1JEIHN0YXRlOwogICAgR0xpbnQgdGV4dHVyZURpbWVuc2lvbnMgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFRleHR1cmVEaW1lbnNpb25zKGlmYWNlKTsKCiAgICBJV2luZUQzREJhc2VUZXh0dXJlX1ByZUxvYWQoaWZhY2UpOwoKICAgIGlmKHNhbXBsZXJTdGF0ZXNbV0lORUQzRFNBTVBfQUREUkVTU1VdICAgICAgIT0gVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfQUREUkVTU1VdKSB7CiAgICAgICAgc3RhdGUgPSBzYW1wbGVyU3RhdGVzW1dJTkVEM0RTQU1QX0FERFJFU1NVXTsKICAgICAgICBhcHBseV93cmFwKHRleHR1cmVEaW1lbnNpb25zLCBzdGF0ZSwgR0xfVEVYVFVSRV9XUkFQX1MpOwogICAgICAgIFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX0FERFJFU1NVXSA9IHN0YXRlOwogICAgfQoKICAgIGlmKHNhbXBsZXJTdGF0ZXNbV0lORUQzRFNBTVBfQUREUkVTU1ZdICAgICAgIT0gVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfQUREUkVTU1ZdKSB7CiAgICAgICAgc3RhdGUgPSBzYW1wbGVyU3RhdGVzW1dJTkVEM0RTQU1QX0FERFJFU1NWXTsKICAgICAgICBhcHBseV93cmFwKHRleHR1cmVEaW1lbnNpb25zLCBzdGF0ZSwgR0xfVEVYVFVSRV9XUkFQX1QpOwogICAgICAgIFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX0FERFJFU1NWXSA9IHN0YXRlOwogICAgfQoKICAgIGlmKHNhbXBsZXJTdGF0ZXNbV0lORUQzRFNBTVBfQUREUkVTU1ddICAgICAgIT0gVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfQUREUkVTU1ddKSB7CiAgICAgICAgc3RhdGUgPSBzYW1wbGVyU3RhdGVzW1dJTkVEM0RTQU1QX0FERFJFU1NXXTsKICAgICAgICBhcHBseV93cmFwKHRleHR1cmVEaW1lbnNpb25zLCBzdGF0ZSwgR0xfVEVYVFVSRV9XUkFQX1IpOwogICAgICAgIFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX0FERFJFU1NXXSA9IHN0YXRlOwogICAgfQoKICAgIGlmKHNhbXBsZXJTdGF0ZXNbV0lORUQzRFNBTVBfQk9SREVSQ09MT1JdICAgIT0gVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfQk9SREVSQ09MT1JdKSB7CiAgICAgICAgZmxvYXQgY29sWzRdOwoKICAgICAgICBzdGF0ZSA9IHNhbXBsZXJTdGF0ZXNbV0lORUQzRFNBTVBfQk9SREVSQ09MT1JdOwogICAgICAgIEQzRENPTE9SVE9HTEZMT0FUNChzdGF0ZSwgY29sKTsKICAgICAgICBUUkFDRSgiU2V0dGluZyBib3JkZXIgY29sb3IgZm9yICV1IHRvICV4XG4iLCB0ZXh0dXJlRGltZW5zaW9ucywgc3RhdGUpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyZnYodGV4dHVyZURpbWVuc2lvbnMsIEdMX1RFWFRVUkVfQk9SREVSX0NPTE9SLCAmY29sWzBdKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpKC4uLiwgR0xfVEVYVFVSRV9CT1JERVJfQ09MT1IsIC4uLikiKTsKICAgICAgICBUaGlzLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9CT1JERVJDT0xPUl0gPSBzdGF0ZTsKICAgIH0KCiAgICBpZihzYW1wbGVyU3RhdGVzW1dJTkVEM0RTQU1QX01BR0ZJTFRFUl0gICAgICE9IFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01BR0ZJTFRFUl0pIHsKICAgICAgICBHTGludCBnbFZhbHVlOwogICAgICAgIHN0YXRlID0gc2FtcGxlclN0YXRlc1tXSU5FRDNEU0FNUF9NQUdGSUxURVJdOwogICAgICAgIGlmIChzdGF0ZSA+IFdJTkVEM0RURVhGX0FOSVNPVFJPUElDKSB7CiAgICAgICAgICAgIEZJWE1FKCJVbnJlY29nbml6ZWQgb3IgdW5zdXBwb3J0ZWQgTUFHRklMVEVSKiB2YWx1ZSAlZFxuIiwgc3RhdGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsVmFsdWUgPSAoKlRoaXMtPmJhc2VUZXh0dXJlLm1hZ0xvb2t1cClbc3RhdGUgLSBXSU5FRDNEVEVYRl9OT05FXTsKICAgICAgICAgICAgVFJBQ0UoIlZhbHVlTUFHPSVkIHNldHRpbmcgTUFHRklMVEVSIHRvICV4XG4iLCBzdGF0ZSwgZ2xWYWx1ZSk7CiAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaSh0ZXh0dXJlRGltZW5zaW9ucywgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBnbFZhbHVlKTsKICAgICAgICAgICAgLyogV2UgbmVlZCB0byByZXNldCB0aGUgQW5pc290cm9waWMgZmlsdGVyaW5nIHN0YXRlIHdoZW4gd2UgY2hhbmdlIHRoZSBtYWcgZmlsdGVyIHRvIFdJTkVEM0RURVhGX0FOSVNPVFJPUElDICh0aGlzIHNlZW1zIGEgYml0IHdlaXJkLCBjaGVjayB0aGUgZG9jdW1lbnRhdGlvbiB0byBzZWUgaG93IGl0IHNob3VsZCBiZSBzd2l0Y2hlZCBvZmYuICovCiAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEVYVF9URVhUVVJFX0ZJTFRFUl9BTklTT1RST1BJQykgJiYgV0lORUQzRFRFWEZfQU5JU09UUk9QSUMgPT0gc3RhdGUgJiYKICAgICAgICAgICAgICAgIHRleHR1cmVEaW1lbnNpb25zICE9IEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQikgewogICAgICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKHRleHR1cmVEaW1lbnNpb25zLCBHTF9URVhUVVJFX01BWF9BTklTT1RST1BZX0VYVCwgc2FtcGxlclN0YXRlc1tXSU5FRDNEU0FNUF9NQVhBTklTT1RST1BZXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUFHRklMVEVSXSA9IHN0YXRlOwogICAgICAgIH0KICAgIH0KCiAgICBpZih0ZXh0dXJlRGltZW5zaW9ucyAhPSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkIgJiYKICAgICAgIChzYW1wbGVyU3RhdGVzW1dJTkVEM0RTQU1QX01JTkZJTFRFUl0gICAgICE9IFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01JTkZJTFRFUl0gfHwKICAgICAgICBzYW1wbGVyU3RhdGVzW1dJTkVEM0RTQU1QX01JUEZJTFRFUl0gICAgICE9IFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01JUEZJTFRFUl0gfHwKICAgICAgICBzYW1wbGVyU3RhdGVzW1dJTkVEM0RTQU1QX01BWE1JUExFVkVMXSAgICE9IFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01BWE1JUExFVkVMXSkpIHsKICAgICAgICBHTGludCBnbFZhbHVlOwoKICAgICAgICBUaGlzLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NSVBGSUxURVJdID0gc2FtcGxlclN0YXRlc1tXSU5FRDNEU0FNUF9NSVBGSUxURVJdOwogICAgICAgIFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01JTkZJTFRFUl0gPSBzYW1wbGVyU3RhdGVzW1dJTkVEM0RTQU1QX01JTkZJTFRFUl07CiAgICAgICAgVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUFYTUlQTEVWRUxdID0gc2FtcGxlclN0YXRlc1tXSU5FRDNEU0FNUF9NQVhNSVBMRVZFTF07CgogICAgICAgIGlmIChUaGlzLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NSU5GSUxURVJdID4gV0lORUQzRFRFWEZfQU5JU09UUk9QSUMgfHwKICAgICAgICAgICAgVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUlQRklMVEVSXSA+IFdJTkVEM0RURVhGX0xJTkVBUikKICAgICAgICB7CgogICAgICAgICAgICBGSVhNRSgiVW5yZWNvZ25pemVkIG9yIHVuc3VwcG9ydGVkIEQzRFNBTVBfTUlORklMVEVSIHZhbHVlICVkIEQzRFNBTVBfTUlQRklMVEVSIHZhbHVlICVkXG4iLAogICAgICAgICAgICAgICAgICBUaGlzLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NSU5GSUxURVJdLAogICAgICAgICAgICAgICAgICBUaGlzLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NSVBGSUxURVJdKTsKICAgICAgICB9CiAgICAgICAgZ2xWYWx1ZSA9ICgqVGhpcy0+YmFzZVRleHR1cmUubWluTWlwTG9va3VwKQogICAgICAgICAgICAgICAgW21pbihtYXgoc2FtcGxlclN0YXRlc1tXSU5FRDNEU0FNUF9NSU5GSUxURVJdLFdJTkVEM0RURVhGX05PTkUpLCBXSU5FRDNEVEVYRl9BTklTT1RST1BJQyldCiAgICAgICAgICAgICAgICBbbWluKG1heChzYW1wbGVyU3RhdGVzW1dJTkVEM0RTQU1QX01JUEZJTFRFUl0sV0lORUQzRFRFWEZfTk9ORSksIFdJTkVEM0RURVhGX0xJTkVBUildOwoKICAgICAgICBUUkFDRSgiVmFsdWVNSU49JWQsIFZhbHVlTUlQPSVkLCBzZXR0aW5nIE1JTkZJTFRFUiB0byAleFxuIiwKICAgICAgICAgICAgICBzYW1wbGVyU3RhdGVzW1dJTkVEM0RTQU1QX01JTkZJTFRFUl0sCiAgICAgICAgICAgICAgc2FtcGxlclN0YXRlc1tXSU5FRDNEU0FNUF9NSVBGSUxURVJdLCBnbFZhbHVlKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkodGV4dHVyZURpbWVuc2lvbnMsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgZ2xWYWx1ZSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgLi4uIik7CgogICAgICAgIGlmKFRoaXMtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01JUEZJTFRFUl0gPT0gV0lORUQzRFRFWEZfTk9ORSkgewogICAgICAgICAgICBnbFZhbHVlID0gMDsKICAgICAgICB9IGVsc2UgaWYoVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUFYTUlQTEVWRUxdID49IFRoaXMtPmJhc2VUZXh0dXJlLmxldmVscykgewogICAgICAgICAgICBnbFZhbHVlID0gVGhpcy0+YmFzZVRleHR1cmUubGV2ZWxzIC0gMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbFZhbHVlID0gVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUFYTUlQTEVWRUxdOwogICAgICAgIH0KICAgICAgICBnbFRleFBhcmFtZXRlcmkodGV4dHVyZURpbWVuc2lvbnMsIEdMX1RFWFRVUkVfQkFTRV9MRVZFTCwgZ2xWYWx1ZSk7CiAgICB9CgogICAgaWYoc2FtcGxlclN0YXRlc1tXSU5FRDNEU0FNUF9NQVhBTklTT1RST1BZXSAhPSBUaGlzLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NQVhBTklTT1RST1BZXSkgewogICAgICAgIGlmIChHTF9TVVBQT1JUKEVYVF9URVhUVVJFX0ZJTFRFUl9BTklTT1RST1BJQykgJiYgdGV4dHVyZURpbWVuc2lvbnMgIT0gR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCKSB7CiAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaSh0ZXh0dXJlRGltZW5zaW9ucywgR0xfVEVYVFVSRV9NQVhfQU5JU09UUk9QWV9FWFQsIHNhbXBsZXJTdGF0ZXNbV0lORUQzRFNBTVBfTUFYQU5JU09UUk9QWV0pOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIEdMX1RFWFRVUkVfTUFYX0FOSVNPVFJPUFlfRVhUIC4uLiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFdBUk4oIlVuc3VwcG9ydGVkIGluIGxvY2FsIE9wZW5HTCBpbXBsZW1lbnRhdGlvbjogZ2xUZXhQYXJhbWV0ZXJpIEdMX1RFWFRVUkVfTUFYX0FOSVNPVFJPUFlfRVhUXG4iKTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUFYQU5JU09UUk9QWV0gPSBzYW1wbGVyU3RhdGVzW1dJTkVEM0RTQU1QX01BWEFOSVNPVFJPUFldOwogICAgfQp9CgoKc3RhdGljIGNvbnN0IElXaW5lRDNEQmFzZVRleHR1cmVWdGJsIElXaW5lRDNEQmFzZVRleHR1cmVfVnRibCA9CnsKICAgIC8qIElVbmtub3duICovCiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0FkZFJlZiwKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX1JlbGVhc2UsCiAgICAvKiBJV2luZUQzRFJlc291cmNlICovCiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9HZXRQYXJlbnQsCiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9HZXREZXZpY2UsCiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9TZXRQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0dldFByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfRnJlZVByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfU2V0UHJpb3JpdHksCiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9HZXRQcmlvcml0eSwKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX1ByZUxvYWQsCiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9VbkxvYWQsCiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9HZXRUeXBlLAogICAgLypJV2luZUQzREJhc2VUZXh0dXJlKi8KICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX1NldExPRCwKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0dldExPRCwKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0dldExldmVsQ291bnQsCiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9TZXRBdXRvR2VuRmlsdGVyVHlwZSwKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0dldEF1dG9HZW5GaWx0ZXJUeXBlLAogICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfR2VuZXJhdGVNaXBTdWJMZXZlbHMsCiAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbF9TZXREaXJ0eSwKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0dldERpcnR5LAogICAgLyogaW50ZXJuYWwgKi8KICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0JpbmRUZXh0dXJlLAogICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfVW5CaW5kVGV4dHVyZSwKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsX0dldFRleHR1cmVEaW1lbnNpb25zLAogICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGxfQXBwbHlTdGF0ZUNoYW5nZXMKCn07Cg==