Ly8KLy8gQ29weXJpZ2h0IKkgMjAxMiBMaW5hcm8gTGltaXRlZAovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgZ2xtYXJrMiBPcGVuR0wgKEVTKSAyLjAgYmVuY2htYXJrLgovLwovLyBnbG1hcmsyIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlCi8vIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKLy8gRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIKLy8gdmVyc2lvbi4KLy8KLy8gZ2xtYXJrMiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKLy8gV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUwovLyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCi8vIGRldGFpbHMuCi8vCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGgKLy8gZ2xtYXJrMi4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KLy8KLy8gQXV0aG9yczoKLy8gIEplc3NlIEJhcmtlcgovLwojaW5jbHVkZSAiZWdsLXN0YXRlLmgiCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgIm9wdGlvbnMuaCIKI2luY2x1ZGUgImxpbWl0cy5oIgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPHNzdHJlYW0+Cgp1c2luZyBzdGQ6OnZlY3RvcjsKdXNpbmcgc3RkOjpzdHJpbmc7CgpFZ2xDb25maWc6OkVnbENvbmZpZyhFR0xEaXNwbGF5IGRweSwgRUdMQ29uZmlnIGNvbmZpZykgOgogICAgaGFuZGxlXyhjb25maWcpLAogICAgYnVmZmVyU2l6ZV8oMCksCiAgICByZWRTaXplXygwKSwKICAgIGdyZWVuU2l6ZV8oMCksCiAgICBibHVlU2l6ZV8oMCksCiAgICBsdW1pbmFuY2VTaXplXygwKSwKICAgIGFscGhhU2l6ZV8oMCksCiAgICBhbHBoYU1hc2tTaXplXygwKSwKICAgIGJpbmRUZXhSR0JfKGZhbHNlKSwKICAgIGJpbmRUZXhSR0JBXyhmYWxzZSksCiAgICBidWZmZXJUeXBlXyhFR0xfUkdCX0JVRkZFUiksCiAgICBjYXZlYXRfKDApLAogICAgY29uZmlnSURfKDApLAogICAgY29uZm9ybWFudF8oMCksCiAgICBkZXB0aFNpemVfKDApLAogICAgbGV2ZWxfKDApLAogICAgcGJ1ZmZlcldpZHRoXygwKSwKICAgIHBidWZmZXJIZWlnaHRfKDApLAogICAgcGJ1ZmZlclBpeGVsc18oMCksCiAgICBtaW5Td2FwSW50ZXJ2YWxfKDApLAogICAgbWF4U3dhcEludGVydmFsXygwKSwKICAgIG5hdGl2ZUlEXygwKSwKICAgIG5hdGl2ZVR5cGVfKDApLAogICAgbmF0aXZlUmVuZGVyYWJsZV8oZmFsc2UpLAogICAgc2FtcGxlQnVmZmVyc18oMCksCiAgICBzYW1wbGVzXygwKSwKICAgIHN0ZW5jaWxTaXplXygwKSwKICAgIHN1cmZhY2VUeXBlXygwKSwKICAgIHhwYXJlbnRUeXBlXygwKSwKICAgIHhwYXJlbnRSZWRWYWx1ZV8oMCksCiAgICB4cGFyZW50R3JlZW5WYWx1ZV8oMCksCiAgICB4cGFyZW50Qmx1ZVZhbHVlXygwKQp7CiAgICB2ZWN0b3I8c3RyaW5nPiBiYWRBdHRyaWJWZWM7CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9DT05GSUdfSUQsICZjb25maWdJRF8pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9DT05GSUdfSUQiKTsKICAgIH0KICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX0NPTkZJR19DQVZFQVQsICZjYXZlYXRfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfQ09ORklHX0NBVkVBVCIpOwogICAgfQogICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfQ09ORk9STUFOVCwgJmNvbmZvcm1hbnRfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfQ09ORk9STUFOVCIpOwogICAgfQogICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfQ09MT1JfQlVGRkVSX1RZUEUsICZidWZmZXJUeXBlXykpCiAgICB7CiAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX0NPTE9SX0JVRkZFUl9UWVBFIik7CiAgICB9CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9CVUZGRVJfU0laRSwgJmJ1ZmZlclNpemVfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfQlVGRkVSX1NJWkUiKTsKICAgIH0KCiAgICBpZiAoYnVmZmVyVHlwZV8gPT0gRUdMX1JHQl9CVUZGRVIpCiAgICB7CiAgICAgICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfUkVEX1NJWkUsICZyZWRTaXplXykpCiAgICAgICAgewogICAgICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfUkVEX1NJWkUiKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfR1JFRU5fU0laRSwgJmdyZWVuU2l6ZV8pKQogICAgICAgIHsKICAgICAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX0dSRUVOX1NJWkUiKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfQkxVRV9TSVpFLCAmYmx1ZVNpemVfKSkKICAgICAgICB7CiAgICAgICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9CTFVFX1NJWkUiKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfTFVNSU5BTkNFX1NJWkUsICZsdW1pbmFuY2VTaXplXykpCiAgICAgICAgewogICAgICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfTFVNSU5BTkNFX1NJWkUiKTsKICAgICAgICB9CiAgICB9CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9BTFBIQV9TSVpFLCAmYWxwaGFTaXplXykpCiAgICB7CiAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX0FMUEhBX1NJWkUiKTsKICAgIH0KICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX0FMUEhBX01BU0tfU0laRSwgJmFscGhhTWFza1NpemVfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfQUxQSEFfTUFTS19TSVpFIik7CiAgICB9CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9ERVBUSF9TSVpFLCAmZGVwdGhTaXplXykpCiAgICB7CiAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX0RFUFRIX1NJWkUiKTsKICAgIH0KICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX1NURU5DSUxfU0laRSwgJnN0ZW5jaWxTaXplXykpCiAgICB7CiAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX1NURU5DSUxfU0laRSIpOwogICAgfQogICAgRUdMaW50IGRvQmluZChFR0xfRkFMU0UpOwogICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfQklORF9UT19URVhUVVJFX1JHQiwgJmRvQmluZCkpCiAgICB7CiAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX0JJTkRfVE9fVEVYVFVSRV9SR0IiKTsKICAgIH0KICAgIGJpbmRUZXhSR0JfID0gKGRvQmluZCA9PSBFR0xfVFJVRSk7CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9CSU5EX1RPX1RFWFRVUkVfUkdCQSwgJmRvQmluZCkpCiAgICB7CiAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX0JJTkRfVE9fVEVYVFVSRV9SR0JBIik7CiAgICB9CiAgICBiaW5kVGV4UkdCQV8gPSAoZG9CaW5kID09IEVHTF9UUlVFKTsKICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX0xFVkVMLCAmbGV2ZWxfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfTEVWRUwiKTsKICAgIH0KICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX01BWF9QQlVGRkVSX1dJRFRILCAmcGJ1ZmZlcldpZHRoXykpCiAgICB7CiAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX01BWF9QQlVGRkVSX1dJRFRIIik7CiAgICB9CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9NQVhfUEJVRkZFUl9IRUlHSFQsICZwYnVmZmVySGVpZ2h0XykpCiAgICB7CiAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX01BWF9QQlVGRkVSX0hFSUdIVCIpOwogICAgfQogICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfTUFYX1BCVUZGRVJfUElYRUxTLCAmcGJ1ZmZlclBpeGVsc18pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9NQVhfUEJVRkZFUl9QSVhFTFMiKTsKICAgIH0KICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX01JTl9TV0FQX0lOVEVSVkFMLCAmbWluU3dhcEludGVydmFsXykpCiAgICB7CiAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX01JTl9TV0FQX0lOVEVSVkFMIik7CiAgICB9CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9NQVhfU1dBUF9JTlRFUlZBTCwgJm1heFN3YXBJbnRlcnZhbF8pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9NQVhfU1dBUF9JTlRFUlZBTCIpOwogICAgfQogICAgRUdMaW50IGRvTmF0aXZlKEVHTF9GQUxTRSk7CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9OQVRJVkVfUkVOREVSQUJMRSwgJmRvTmF0aXZlKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfTkFUSVZFX1JFTkRFUkFCTEUiKTsKICAgIH0KICAgIG5hdGl2ZVJlbmRlcmFibGVfID0gKGRvTmF0aXZlID09IEVHTF9UUlVFKTsKICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX05BVElWRV9WSVNVQUxfVFlQRSwgJm5hdGl2ZVR5cGVfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfTkFUSVZFX1ZJU1VBTF9UWVBFIik7CiAgICB9CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9OQVRJVkVfVklTVUFMX0lELCAmbmF0aXZlSURfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfTkFUSVZFX1ZJU1VBTF9JRCIpOwogICAgfQogICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfU1VSRkFDRV9UWVBFLCAmc3VyZmFjZVR5cGVfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfU1VSRkFDRV9UWVBFIik7CiAgICB9CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9TQU1QTEVfQlVGRkVSUywgJnNhbXBsZUJ1ZmZlcnNfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfU0FNUExFX0JVRkZFUlMiKTsKICAgIH0KICAgIGlmIChzYW1wbGVCdWZmZXJzXykKICAgIHsKICAgICAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9TQU1QTEVTLCAmc2FtcGxlc18pKQogICAgICAgIHsKICAgICAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX1NBTVBMRVMiKTsKICAgICAgICB9ICAgICAgICAKICAgIH0gICAgCiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9UUkFOU1BBUkVOVF9UWVBFLCAmeHBhcmVudFR5cGVfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfVFJBTlNQQVJFTlRfVFlQRSIpOwogICAgfQogICAgLy9pZiAoeHBhcmVudFR5cGVfICE9IEVHTF9OT05FKQogICAgewogICAgICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX1RSQU5TUEFSRU5UX1JFRF9WQUxVRSwgJnhwYXJlbnRSZWRWYWx1ZV8pKQogICAgICAgIHsKICAgICAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX1RSQU5TUEFSRU5UX1JFRF9WQUxVRSIpOwogICAgICAgIH0KICAgICAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9UUkFOU1BBUkVOVF9HUkVFTl9WQUxVRSwgJnhwYXJlbnRHcmVlblZhbHVlXykpCiAgICAgICAgewogICAgICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfVFJBTlNQQVJFTlRfR1JFRU5fVkFMVUUiKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfVFJBTlNQQVJFTlRfQkxVRV9WQUxVRSwgJnhwYXJlbnRCbHVlVmFsdWVfKSkKICAgICAgICB7CiAgICAgICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9UUkFOU1BBUkVOVF9CTFVFX1ZBTFVFIik7CiAgICAgICAgfQogICAgfQoKICAgIGlmICghYmFkQXR0cmliVmVjLmVtcHR5KCkpCiAgICB7CiAgICAgICAgTG9nOjplcnJvcigiRmFpbGVkIHRvIGdldCB0aGUgZm9sbG93aW5nIGNvbmZpZyBhdHRyaWJ1dGVzIGZvciBjb25maWcgMHgleDpcbiIsCiAgICAgICAgICAgICAgICAgICAgY29uZmlnKTsKICAgICAgICBmb3IgKHZlY3RvcjxzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBhdHRyaWJJdCA9IGJhZEF0dHJpYlZlYy5iZWdpbigpOwogICAgICAgICAgICAgYXR0cmliSXQgIT0gYmFkQXR0cmliVmVjLmVuZCgpOwogICAgICAgICAgICAgYXR0cmliSXQrKykKICAgICAgICB7CiAgICAgICAgICAgIExvZzo6ZXJyb3IoIiVzXG4iLCBhdHRyaWJJdC0+Y19zdHIoKSk7CiAgICAgICAgfQogICAgfQp9Cgp2b2lkCkVnbENvbmZpZzo6cHJpbnRfaGVhZGVyKCkKewogICAgTG9nOjpkZWJ1ZygiXG4iKTsKICAgIExvZzo6ZGVidWcoIiAgICBjZmcgYnVmICByZ2IgIGNvbG9yYnVmZmVyIGRwIHN0IGNvbmZpZyBuYXRpdmUgc3VwcG9ydCBzdXJmYWNlIHNhbXBsZVxuIik7CiAgICBMb2c6OmRlYnVnKCIgICAgIGlkICBzeiAgbHVtICByICBnICBiICBhICB0aCBjbCBjYXZlYXQgcmVuZGVyICB2aXNpZCAgICB0eXBlICBidWYgbnNcbiIpOwogICAgTG9nOjpkZWJ1ZygiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKfQoKdm9pZApFZ2xDb25maWc6OnByaW50KCkgY29uc3QKewogICAgc3RkOjpvc3RyaW5nc3RyZWFtIHM7CiAgICBzLnNldGYoc3RkOjppb3M6OnNob3diYXNlKTsKICAgIHMuZmlsbCgnICcpOwogICAgcyA8PCBzdGQ6OnNldHcoNykgPDwgc3RkOjpoZXggPDwgY29uZmlnSURfOwogICAgcyA8PCBzdGQ6OnNldHcoNCkgPDwgc3RkOjpkZWMgPDwgYnVmZmVyU2l6ZV87CiAgICBpZiAoYnVmZmVyVHlwZV8gPT0gRUdMX1JHQl9CVUZGRVIpCiAgICB7CiAgICAgICAgcyA8PCBzdGQ6OnNldHcoNSkgPDwgInJnYiI7CiAgICAgICAgcyA8PCBzdGQ6OnNldHcoMykgPDwgcmVkU2l6ZV87CiAgICAgICAgcyA8PCBzdGQ6OnNldHcoMykgPDwgZ3JlZW5TaXplXzsKICAgICAgICBzIDw8IHN0ZDo6c2V0dygzKSA8PCBibHVlU2l6ZV87CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcyA8PCBzdGQ6OnNldHcoNSkgPDwgImx1bSI7CiAgICAgICAgcyA8PCBzdGQ6OnNldHcoMykgPDwgbHVtaW5hbmNlU2l6ZV87CiAgICAgICAgcyA8PCBzdGQ6OnNldHcoMykgPDwgMDsKICAgICAgICBzIDw8IHN0ZDo6c2V0dygzKSA8PCAwOwogICAgfQogICAgcyA8PCBzdGQ6OnNldHcoMykgPDwgYWxwaGFTaXplXzsKICAgIHMgPDwgc3RkOjpzZXR3KDQpIDw8IGRlcHRoU2l6ZV87CiAgICBzIDw8IHN0ZDo6c2V0dygzKSA8PCBzdGVuY2lsU2l6ZV87CiAgICBzdHJpbmcgY2F2ZWF0KCJOb25lIik7CiAgICBzd2l0Y2ggKGNhdmVhdF8pCiAgICB7CiAgICAgICAgY2FzZSBFR0xfU0xPV19DT05GSUc6CiAgICAgICAgICAgIGNhdmVhdCA9IHN0cmluZygiU2xvdyIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEVHTF9OT05fQ09ORk9STUFOVF9DT05GSUc6CiAgICAgICAgICAgIGNhdmVhdCA9IHN0cmluZygiTmNvbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEVHTF9OT05FOgogICAgICAgICAgICAvLyBJbml0aWFsaXplZCB0byBub25lLgogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHMgPDwgc3RkOjpzZXR3KDcpIDw8IGNhdmVhdDsKICAgIHN0cmluZyBkb05hdGl2ZShuYXRpdmVSZW5kZXJhYmxlXyA/ICJ0cnVlIiA6ICJmYWxzZSIpOwogICAgcyA8PCBzdGQ6OnNldHcoNykgPDwgZG9OYXRpdmU7CiAgICBzIDw8IHN0ZDo6c2V0dyg4KSA8PCBzdGQ6OmhleCA8PCBuYXRpdmVJRF87CiAgICBzIDw8IHN0ZDo6c2V0dyg4KSA8PCBzdGQ6OmhleCA8PCBzdXJmYWNlVHlwZV87CiAgICBzIDw8IHN0ZDo6c2V0dyg0KSA8PCBzdGQ6OmRlYyA8PCBzYW1wbGVCdWZmZXJzXzsKICAgIHMgPDwgc3RkOjpzZXR3KDMpIDw8IHN0ZDo6ZGVjIDw8IHNhbXBsZXNfOwogICAgTG9nOjpkZWJ1ZygiJXNcbiIsIHMuc3RyKCkuY19zdHIoKSk7Cn0KCgpib29sCkVHTFN0YXRlOjppbml0X2Rpc3BsYXkoRUdMTmF0aXZlRGlzcGxheVR5cGUgbmF0aXZlX2Rpc3BsYXksIEdMVmlzdWFsQ29uZmlnJiB2aXN1YWxfY29uZmlnKQp7CiAgICBuYXRpdmVfZGlzcGxheV8gPSBuYXRpdmVfZGlzcGxheTsKICAgIHZpc3VhbF9jb25maWdfID0gdmlzdWFsX2NvbmZpZzsKCiAgICByZXR1cm4gZ290VmFsaWREaXNwbGF5KCk7Cn0KCmJvb2wKRUdMU3RhdGU6OmluaXRfc3VyZmFjZShFR0xOYXRpdmVXaW5kb3dUeXBlIG5hdGl2ZV93aW5kb3cpCnsKICAgIG5hdGl2ZV93aW5kb3dfID0gcmVpbnRlcnByZXRfY2FzdDxFR0xOYXRpdmVXaW5kb3dUeXBlPihuYXRpdmVfd2luZG93KTsKCiAgICByZXR1cm4gZ290VmFsaWRTdXJmYWNlKCk7Cn0KCnZvaWQKRUdMU3RhdGU6OnN3YXAoKQp7CiAgICBlZ2xTd2FwQnVmZmVycyhlZ2xfZGlzcGxheV8sIGVnbF9zdXJmYWNlXyk7Cn0KCmJvb2wKRUdMU3RhdGU6OmdvdFZhbGlkRGlzcGxheSgpCnsKICAgIGlmIChlZ2xfZGlzcGxheV8pCiAgICAgICAgcmV0dXJuIHRydWU7CgogICAgZWdsX2Rpc3BsYXlfID0gZWdsR2V0RGlzcGxheShuYXRpdmVfZGlzcGxheV8pOwogICAgaWYgKCFlZ2xfZGlzcGxheV8pIHsKICAgICAgICBMb2c6OmVycm9yKCJlZ2xHZXREaXNwbGF5KCkgZmFpbGVkIHdpdGggZXJyb3I6IDB4JXhcbiIsIGVnbEdldEVycm9yKCkpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGludCBlZ2xfbWFqb3IoLTEpOwogICAgaW50IGVnbF9taW5vcigtMSk7CiAgICBpZiAoIWVnbEluaXRpYWxpemUoZWdsX2Rpc3BsYXlfLCAmZWdsX21ham9yLCAmZWdsX21pbm9yKSkgewogICAgICAgIExvZzo6ZXJyb3IoImVnbEluaXRpYWxpemUoKSBmYWlsZWQgd2l0aCBlcnJvcjogMHgleFxuIiwgZWdsR2V0RXJyb3IoKSk7CiAgICAgICAgZWdsX2Rpc3BsYXlfID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgojaWYgVVNFX0dMRVN2MgogICAgRUdMZW51bSBhcGlUeXBlKEVHTF9PUEVOR0xfRVNfQVBJKTsKI2VsaWYgVVNFX0dMCiAgICBFR0xlbnVtIGFwaVR5cGUoRUdMX09QRU5HTF9BUEkpOwojZW5kaWYKICAgIGlmICghZWdsQmluZEFQSShhcGlUeXBlKSkgewogICAgICAgIExvZzo6ZXJyb3IoIkZhaWxlZCB0byBiaW5kIGFwaSBFR0xfT1BFTkdMX0VTX0FQSVxuIik7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHJldHVybiB0cnVlOwp9Cgp2b2lkCkVHTFN0YXRlOjpnZXRfZ2x2aXN1YWxjb25maWcoRUdMQ29uZmlnIGNvbmZpZywgR0xWaXN1YWxDb25maWcmIHZpc3VhbF9jb25maWcpCnsKICAgIGVnbEdldENvbmZpZ0F0dHJpYihlZ2xfZGlzcGxheV8sIGNvbmZpZywgRUdMX0JVRkZFUl9TSVpFLCAmdmlzdWFsX2NvbmZpZy5idWZmZXIpOwogICAgZWdsR2V0Q29uZmlnQXR0cmliKGVnbF9kaXNwbGF5XywgY29uZmlnLCBFR0xfUkVEX1NJWkUsICZ2aXN1YWxfY29uZmlnLnJlZCk7CiAgICBlZ2xHZXRDb25maWdBdHRyaWIoZWdsX2Rpc3BsYXlfLCBjb25maWcsIEVHTF9HUkVFTl9TSVpFLCAmdmlzdWFsX2NvbmZpZy5ncmVlbik7CiAgICBlZ2xHZXRDb25maWdBdHRyaWIoZWdsX2Rpc3BsYXlfLCBjb25maWcsIEVHTF9CTFVFX1NJWkUsICZ2aXN1YWxfY29uZmlnLmJsdWUpOwogICAgZWdsR2V0Q29uZmlnQXR0cmliKGVnbF9kaXNwbGF5XywgY29uZmlnLCBFR0xfQUxQSEFfU0laRSwgJnZpc3VhbF9jb25maWcuYWxwaGEpOwogICAgZWdsR2V0Q29uZmlnQXR0cmliKGVnbF9kaXNwbGF5XywgY29uZmlnLCBFR0xfREVQVEhfU0laRSwgJnZpc3VhbF9jb25maWcuZGVwdGgpOwogICAgZWdsR2V0Q29uZmlnQXR0cmliKGVnbF9kaXNwbGF5XywgY29uZmlnLCBFR0xfU1RFTkNJTF9TSVpFLCAmdmlzdWFsX2NvbmZpZy5zdGVuY2lsKTsKfQoKRUdMQ29uZmlnCkVHTFN0YXRlOjpzZWxlY3RfYmVzdF9jb25maWcoc3RkOjp2ZWN0b3I8RUdMQ29uZmlnPiYgY29uZmlncykKewogICAgaW50IGJlc3Rfc2NvcmUoSU5UX01JTik7CiAgICBFR0xDb25maWcgYmVzdF9jb25maWcoMCk7CgogICAgLyoKICAgICAqIEdvIHRocm91Z2ggYWxsIHRoZSBjb25maWdzIGFuZCBjaG9vc2UgdGhlIG9uZSB3aXRoIHRoZSBiZXN0IHNjb3JlLAogICAgICogaS5lLiwgdGhlIG9uZSBiZXR0ZXIgbWF0Y2hpbmcgdGhlIHJlcXVlc3RlZCBjb25maWcuCiAgICAgKi8KICAgIGZvciAoc3RkOjp2ZWN0b3I8RUdMQ29uZmlnPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGNvbmZpZ3MuYmVnaW4oKTsKICAgICAgICAgaXRlciAhPSBjb25maWdzLmVuZCgpOwogICAgICAgICBpdGVyKyspCiAgICB7CiAgICAgICAgY29uc3QgRUdMQ29uZmlnIGNvbmZpZygqaXRlcik7CiAgICAgICAgR0xWaXN1YWxDb25maWcgdmM7CiAgICAgICAgaW50IHNjb3JlOwoKICAgICAgICBnZXRfZ2x2aXN1YWxjb25maWcoY29uZmlnLCB2Yyk7CgogICAgICAgIHNjb3JlID0gdmMubWF0Y2hfc2NvcmUodmlzdWFsX2NvbmZpZ18pOwoKICAgICAgICBpZiAoc2NvcmUgPiBiZXN0X3Njb3JlKSB7CiAgICAgICAgICAgIGJlc3Rfc2NvcmUgPSBzY29yZTsKICAgICAgICAgICAgYmVzdF9jb25maWcgPSBjb25maWc7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBiZXN0X2NvbmZpZzsKfQoKYm9vbApFR0xTdGF0ZTo6Z290VmFsaWRDb25maWcoKQp7CiAgICBpZiAoZWdsX2NvbmZpZ18pCiAgICAgICAgcmV0dXJuIHRydWU7CgogICAgaWYgKCFnb3RWYWxpZERpc3BsYXkoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgY29uc3QgRUdMaW50IGNvbmZpZ19hdHRyaWJzW10gPSB7CiAgICAgICAgRUdMX1JFRF9TSVpFLCB2aXN1YWxfY29uZmlnXy5yZWQsCiAgICAgICAgRUdMX0dSRUVOX1NJWkUsIHZpc3VhbF9jb25maWdfLmdyZWVuLAogICAgICAgIEVHTF9CTFVFX1NJWkUsIHZpc3VhbF9jb25maWdfLmJsdWUsCiAgICAgICAgRUdMX0FMUEhBX1NJWkUsIHZpc3VhbF9jb25maWdfLmFscGhhLAogICAgICAgIEVHTF9ERVBUSF9TSVpFLCB2aXN1YWxfY29uZmlnXy5kZXB0aCwKICAgICAgICBFR0xfU1RFTkNJTF9TSVpFLCB2aXN1YWxfY29uZmlnXy5zdGVuY2lsLAojaWYgVVNFX0dMRVN2MgogICAgICAgIEVHTF9SRU5ERVJBQkxFX1RZUEUsIEVHTF9PUEVOR0xfRVMyX0JJVCwKI2VsaWYgVVNFX0dMCiAgICAgICAgRUdMX1JFTkRFUkFCTEVfVFlQRSwgRUdMX09QRU5HTF9CSVQsCiNlbmRpZgogICAgICAgIEVHTF9OT05FCiAgICB9OwoKICAgIC8vIEZpbmQgb3V0IGhvdyBtYW55IGNvbmZpZ3MgbWF0Y2ggdGhlIGF0dHJpYnV0ZXMuCiAgICBFR0xpbnQgbnVtX2NvbmZpZ3MoMCk7CiAgICBpZiAoIWVnbENob29zZUNvbmZpZyhlZ2xfZGlzcGxheV8sIGNvbmZpZ19hdHRyaWJzLCAwLCAwLCAmbnVtX2NvbmZpZ3MpKSB7CiAgICAgICAgTG9nOjplcnJvcigiZWdsQ2hvb3NlQ29uZmlnKCkgKGNvdW50IHF1ZXJ5KSBmYWlsZWQgd2l0aCBlcnJvcjogJWRcbiIsCiAgICAgICAgICAgICAgICAgICBlZ2xHZXRFcnJvcigpKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgaWYgKG51bV9jb25maWdzID09IDApIHsKICAgICAgICBMb2c6OmVycm9yKCJlZ2xDaG9vc2VDb25maWcoKSBkaWRuJ3QgcmV0dXJuIGFueSBjb25maWdzXG4iKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLy8gR2V0IGFsbCB0aGUgbWF0Y2hpbmcgY29uZmlncwogICAgdmVjdG9yPEVHTENvbmZpZz4gY29uZmlncyhudW1fY29uZmlncyk7CiAgICBpZiAoIWVnbENob29zZUNvbmZpZyhlZ2xfZGlzcGxheV8sIGNvbmZpZ19hdHRyaWJzLCAmY29uZmlncy5mcm9udCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgbnVtX2NvbmZpZ3MsICZudW1fY29uZmlncykpCiAgICB7CiAgICAgICAgTG9nOjplcnJvcigiZWdsQ2hvb3NlQ29uZmlnKCkgZmFpbGVkIHdpdGggZXJyb3I6ICVkXG4iLAogICAgICAgICAgICAgICAgICAgICBlZ2xHZXRFcnJvcigpKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLy8gU2VsZWN0IHRoZSBiZXN0IG1hdGNoaW5nIGNvbmZpZwogICAgZWdsX2NvbmZpZ18gPSBzZWxlY3RfYmVzdF9jb25maWcoY29uZmlncyk7CgogICAgdmVjdG9yPEVnbENvbmZpZz4gY29uZmlnVmVjOwogICAgZm9yICh2ZWN0b3I8RUdMQ29uZmlnPjo6Y29uc3RfaXRlcmF0b3IgY29uZmlnSXQgPSBjb25maWdzLmJlZ2luKCk7CiAgICAgICAgIGNvbmZpZ0l0ICE9IGNvbmZpZ3MuZW5kKCk7CiAgICAgICAgIGNvbmZpZ0l0KyspCiAgICB7CiAgICAgICAgRWdsQ29uZmlnIGNmZyhlZ2xfZGlzcGxheV8sICpjb25maWdJdCk7CiAgICAgICAgY29uZmlnVmVjLnB1c2hfYmFjayhjZmcpOwogICAgICAgIGlmICgqY29uZmlnSXQgPT0gZWdsX2NvbmZpZ18pIHsKICAgICAgICAgICAgYmVzdF9jb25maWdfID0gY2ZnOwogICAgICAgIH0KICAgIH0gCgogICAgLy8gUHJpbnQgb3V0IHRoZSBjb25maWcgaW5mb3JtYXRpb24sIGFuZCBsZXQgdGhlIHVzZXIga25vdyB0aGUgZGVjaXNpb24KICAgIC8vIGFib3V0IHRoZSAiYmVzdCIgb25lIHdpdGggcmVzcGVjdCB0byB0aGUgb3B0aW9ucy4KICAgIHVuc2lnbmVkIGludCBsaW5lTnVtYmVyKDApOwogICAgTG9nOjpkZWJ1ZygiR290ICV1IHN1aXRhYmxlIEVHTENvbmZpZ3M6XG4iLCBudW1fY29uZmlncyk7CiAgICBmb3IgKHZlY3RvcjxFZ2xDb25maWc+Ojpjb25zdF9pdGVyYXRvciBjb25maWdJdCA9IGNvbmZpZ1ZlYy5iZWdpbigpOwogICAgICAgICBjb25maWdJdCAhPSBjb25maWdWZWMuZW5kKCk7CiAgICAgICAgIGNvbmZpZ0l0KyssIGxpbmVOdW1iZXIrKykKICAgIHsKICAgICAgICBpZiAoIShsaW5lTnVtYmVyICUgMzIpKQogICAgICAgIHsKICAgICAgICAgICAgY29uZmlnSXQtPnByaW50X2hlYWRlcigpOwogICAgICAgIH0KICAgICAgICBjb25maWdJdC0+cHJpbnQoKTsKICAgIH0KICAgIExvZzo6ZGVidWcoIlxuIik7CiAgICBMb2c6OmRlYnVnKCJCZXN0IEVHTENvbmZpZyBJRDogMHgleFxuIiwgYmVzdF9jb25maWdfLmNvbmZpZ0lEKCkpOwoKICAgIHJldHVybiB0cnVlOwp9Cgpib29sCkVHTFN0YXRlOjpnb3RWYWxpZFN1cmZhY2UoKQp7CiAgICBpZiAoZWdsX3N1cmZhY2VfKQogICAgICAgIHJldHVybiB0cnVlOwoKICAgIGlmICghZ290VmFsaWREaXNwbGF5KCkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIGlmICghZ290VmFsaWRDb25maWcoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgZWdsX3N1cmZhY2VfID0gZWdsQ3JlYXRlV2luZG93U3VyZmFjZShlZ2xfZGlzcGxheV8sIGVnbF9jb25maWdfLCBuYXRpdmVfd2luZG93XywgMCk7CiAgICBpZiAoIWVnbF9zdXJmYWNlXykgewogICAgICAgIExvZzo6ZXJyb3IoImVnbENyZWF0ZVdpbmRvd1N1cmZhY2UgZmFpbGVkIHdpdGggZXJyb3I6IDB4JXhcbiIsIGVnbEdldEVycm9yKCkpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICByZXR1cm4gdHJ1ZTsKfQoKYm9vbApFR0xTdGF0ZTo6Z290VmFsaWRDb250ZXh0KCkKewogICAgaWYgKGVnbF9jb250ZXh0XykKICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICBpZiAoIWdvdFZhbGlkRGlzcGxheSgpKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICBpZiAoIWdvdFZhbGlkQ29uZmlnKCkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIHN0YXRpYyBjb25zdCBFR0xpbnQgY29udGV4dF9hdHRyaWJzW10gPSB7CiNpZmRlZiBVU0VfR0xFU3YyCiAgICAgICAgRUdMX0NPTlRFWFRfQ0xJRU5UX1ZFUlNJT04sIDIsCiNlbmRpZgogICAgICAgIEVHTF9OT05FCiAgICB9OwoKICAgIGVnbF9jb250ZXh0XyA9IGVnbENyZWF0ZUNvbnRleHQoZWdsX2Rpc3BsYXlfLCBlZ2xfY29uZmlnXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUdMX05PX0NPTlRFWFQsIGNvbnRleHRfYXR0cmlicyk7CiAgICBpZiAoIWVnbF9jb250ZXh0XykgewogICAgICAgIExvZzo6ZXJyb3IoImVnbENyZWF0ZUNvbnRleHQoKSBmYWlsZWQgd2l0aCBlcnJvcjogMHgleFxuIiwKICAgICAgICAgICAgICAgICAgIGVnbEdldEVycm9yKCkpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICByZXR1cm4gdHJ1ZTsKfQoKYm9vbApFR0xTdGF0ZTo6dmFsaWQoKQp7CiAgICBpZiAoIWdvdFZhbGlkRGlzcGxheSgpKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICBpZiAoIWdvdFZhbGlkQ29uZmlnKCkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIGlmICghZ290VmFsaWRTdXJmYWNlKCkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIGlmICghZ290VmFsaWRDb250ZXh0KCkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIGlmIChlZ2xfY29udGV4dF8gPT0gZWdsR2V0Q3VycmVudENvbnRleHQoKSkKICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICBpZiAoIWVnbE1ha2VDdXJyZW50KGVnbF9kaXNwbGF5XywgZWdsX3N1cmZhY2VfLCBlZ2xfc3VyZmFjZV8sIGVnbF9jb250ZXh0XykpIHsKICAgICAgICBMb2c6OmVycm9yKCJlZ2xNYWtlQ3VycmVudCBmYWlsZWQgd2l0aCBlcnJvcjogMHgleFxuIiwgZWdsR2V0RXJyb3IoKSk7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIGlmICghZWdsU3dhcEludGVydmFsKGVnbF9kaXNwbGF5XywgMCkpIHsKICAgICAgICBMb2c6OmluZm8oIioqIEZhaWxlZCB0byBzZXQgc3dhcCBpbnRlcnZhbC4gUmVzdWx0cyBtYXkgYmUgYm91bmRlZCBhYm92ZSBieSByZWZyZXNoIHJhdGUuXG4iKTsKICAgIH0KCiAgICByZXR1cm4gdHJ1ZTsKfQoKYm9vbApFR0xTdGF0ZTo6Z290TmF0aXZlQ29uZmlnKGludCYgdmlkKQp7CiAgICBpZiAoIWdvdFZhbGlkQ29uZmlnKCkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIEVHTGludCBuYXRpdmVfaWQ7CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihlZ2xfZGlzcGxheV8sIGVnbF9jb25maWdfLCBFR0xfTkFUSVZFX1ZJU1VBTF9JRCwKICAgICAgICAmbmF0aXZlX2lkKSkKICAgIHsKICAgICAgICBMb2c6OmRlYnVnKCJGYWlsZWQgdG8gZ2V0IG5hdGl2ZSB2aXN1YWwgaWQgZm9yIEVHTENvbmZpZyAweCV4XG4iLCBlZ2xfY29uZmlnXyk7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHZpZCA9IG5hdGl2ZV9pZDsKICAgIHJldHVybiB0cnVlOwp9Cgpib29sCkVHTFN0YXRlOjpyZXNldCgpCnsKICAgIGlmICghZ290VmFsaWREaXNwbGF5KCkpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgaWYgKCFlZ2xfY29udGV4dF8pIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBpZiAoRUdMX0ZBTFNFID09IGVnbERlc3Ryb3lDb250ZXh0KGVnbF9kaXNwbGF5XywgZWdsX2NvbnRleHRfKSkgewogICAgICAgIExvZzo6ZGVidWcoImVnbERlc3Ryb3lDb250ZXh0IGZhaWxlZCB3aXRoIGVycm9yOiAweCV4XG4iLCBlZ2xHZXRFcnJvcigpKTsKICAgIH0KCiAgICBlZ2xfY29udGV4dF8gPSAwOwoKICAgIHJldHVybiB0cnVlOwp9Cg==