LyoKICogQUlYNCBtZW1vcnkgc3RhdGlzdGljcyBtb2R1bGUgZm9yIG5ldC1zbm1wCiAqCiAqIFZlcnNpb24gMC4xIC0gSW5pdGlhbCByZWxlYXNlIC0gMDUvSnVuLzIwMDMKICoKICogRGVyaXZlZCBmcm9tIG1lbW9yeV9zb2xhcmlzMi5jCiAqIFVzaW5nIGxpYnBlcmZzdGF0IGZvciBzdGF0aXN0aWNzIChSZWRib29rIFNHMjQtNjAzOSkKICoKICogUG9ydGVkIHRvIEFJWCBieSBNaWNoYWVsIEt1a2F0IDxtaWNoYWVsLmt1a2F0QHRvLmNvbT4KICogVGhpbmtpbmcgT2JqZWN0cyBTb2Z0d2FyZSBHbWJICiAqIExpbGllbnRoYWxzdHJh32UgMgogKiA3MDgyNSBTdHV0dGdhcnQtS29ybnRhbAogKiBodHRwOi8vd3d3LnRvLmNvbS8KICoKICogVGhhbmtzIGdvIHRvIEpvY2hlbiBLbWlldHNjaCBmb3IgdGhlIHNvbGFyaXMyIHN1cHBvcnQgYW5kCiAqIHRvIERhaW1sZXJDaHJ5c2xlciBBRyBTdHV0dGdhcnQgZm9yIG1ha2luZyB0aGlzIHBvcnQgcG9zc2libGUKICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+ICAgLyogbG9jYWwgU05NUCBjb25maWd1cmF0aW9uIGRldGFpbHMgKi8KI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZW5kaWYKI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L2F1dG9fbmxpc3QuaD4KCiNpbmNsdWRlICJ1dGlsX2Z1bmNzLmgiICAgICAgICAgLyogdXRpbGl0eSBmdW5jdGlvbiBkZWNsYXJhdGlvbnMgKi8KI2luY2x1ZGUgIm1lbW9yeS5oIiAgICAgICAgICAgICAvKiB0aGUgbW9kdWxlLXNwZWNpZmljIGhlYWRlciAqLwojaW5jbHVkZSAibWVtb3J5X2FpeDQuaCIgICAgLyogdGhlIG1vZHVsZS1zcGVjaWZpYyBoZWFkZXIgKi8KCiNpbmNsdWRlIDxsaWJwZXJmc3RhdC5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgoKI2RlZmluZSBNQVhTVFJTSVpFCTgwCgppbnQgICAgICAgICAgICAgbWluaW11bXN3YXA7CnN0YXRpYyBjaGFyICAgICBlcnJtc2dbMTAyNF07CgpzdGF0aWMgRmluZFZhck1ldGhvZCB2YXJfZXh0ZW5zaWJsZV9tZW07CnN0YXRpYyBsb25nICAgICBnZXRGcmVlU3dhcCh2b2lkKTsKc3RhdGljIGxvbmcgICAgIGdldFRvdGFsRnJlZSh2b2lkKTsKc3RhdGljIGxvbmcgICAgIGdldFRvdGFsU3dhcCh2b2lkKTsKc3RhdGljIGxvbmcgICAgIGdldEZyZWVSZWFsKHZvaWQpOwpzdGF0aWMgbG9uZyAgICAgZ2V0VG90YWxSZWFsKHZvaWQpOwoKdm9pZAppbml0X21lbW9yeV9haXg0KHZvaWQpCnsKCiAgICBzdHJ1Y3QgdmFyaWFibGUyIGV4dGVuc2libGVfbWVtX3ZhcmlhYmxlc1tdID0gewogICAgICAgIHtNSUJJTkRFWCwgQVNOX0lOVEVHRVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtNSUJJTkRFWH19LAogICAgICAgIHtFUlJPUk5BTUUsIEFTTl9PQ1RFVF9TVFIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsCiAgICAgICAgIHtFUlJPUk5BTUV9fSwKICAgICAgICB7TUVNVE9UQUxTV0FQLCBBU05fSU5URUdFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX21lbSwgMSwKICAgICAgICAge01FTVRPVEFMU1dBUH19LAogICAgICAgIHtNRU1BVkFJTFNXQVAsIEFTTl9JTlRFR0VSLCBST05MWSwgdmFyX2V4dGVuc2libGVfbWVtLCAxLAogICAgICAgICB7TUVNQVZBSUxTV0FQfX0sCiAgICAgICAge01FTVRPVEFMUkVBTCwgQVNOX0lOVEVHRVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsCiAgICAgICAgIHtNRU1UT1RBTFJFQUx9fSwKICAgICAgICB7TUVNQVZBSUxSRUFMLCBBU05fSU5URUdFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX21lbSwgMSwKICAgICAgICAge01FTUFWQUlMUkVBTH19LAogICAgICAgIHtNRU1UT1RBTFNXQVBUWFQsIEFTTl9JTlRFR0VSLCBST05MWSwgdmFyX2V4dGVuc2libGVfbWVtLCAxLAogICAgICAgICB7TUVNVE9UQUxTV0FQVFhUfX0sCiAgICAgICAge01FTVVTRURTV0FQVFhULCBBU05fSU5URUdFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX21lbSwgMSwKICAgICAgICAge01FTVVTRURTV0FQVFhUfX0sCiAgICAgICAge01FTVRPVEFMUkVBTFRYVCwgQVNOX0lOVEVHRVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsCiAgICAgICAgIHtNRU1UT1RBTFJFQUxUWFR9fSwKICAgICAgICB7TUVNVVNFRFJFQUxUWFQsIEFTTl9JTlRFR0VSLCBST05MWSwgdmFyX2V4dGVuc2libGVfbWVtLCAxLAogICAgICAgICB7TUVNVVNFRFJFQUxUWFR9fSwKICAgICAgICB7TUVNVE9UQUxGUkVFLCBBU05fSU5URUdFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX21lbSwgMSwKICAgICAgICAge01FTVRPVEFMRlJFRX19LAogICAgICAgIHtNRU1TV0FQTUlOSU1VTSwgQVNOX0lOVEVHRVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsCiAgICAgICAgIHtNRU1TV0FQTUlOSU1VTX19LAogICAgICAgIHtNRU1TSEFSRUQsIEFTTl9JTlRFR0VSLCBST05MWSwgdmFyX2V4dGVuc2libGVfbWVtLCAxLAogICAgICAgICB7TUVNU0hBUkVEfX0sCiAgICAgICAge01FTUJVRkZFUiwgQVNOX0lOVEVHRVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsCiAgICAgICAgIHtNRU1CVUZGRVJ9fSwKICAgICAgICB7TUVNQ0FDSEVELCBBU05fSU5URUdFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX21lbSwgMSwKICAgICAgICAge01FTUNBQ0hFRH19LAogICAgICAgIHtFUlJPUkZMQUcsIEFTTl9JTlRFR0VSLCBST05MWSwgdmFyX2V4dGVuc2libGVfbWVtLCAxLAogICAgICAgICB7RVJST1JGTEFHfX0sCiAgICAgICAge0VSUk9STVNHLCBBU05fT0NURVRfU1RSLCBST05MWSwgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7RVJST1JNU0d9fQogICAgfTsKCiAgICAvKgogICAgICogRGVmaW5lIHRoZSBPSUQgcG9pbnRlciB0byB0aGUgdG9wIG9mIHRoZSBtaWIgdHJlZSB0aGF0IHdlJ3JlCiAgICAgKiByZWdpc3RlcmluZyB1bmRlcm5lYXRoIAogICAgICovCiAgICBvaWQgICAgICAgICAgICAgbWVtX3ZhcmlhYmxlc19vaWRbXSA9IHsgTkVUU05NUF9VQ0RBVklTX01JQiwgTkVUU05NUF9NRU1NSUJOVU0gfTsKCiAgICAvKgogICAgICogcmVnaXN0ZXIgb3Vyc2VsdmVzIHdpdGggdGhlIGFnZW50IHRvIGhhbmRsZSBvdXIgbWliIHRyZWUgCiAgICAgKi8KICAgIFJFR0lTVEVSX01JQigidWNkLXNubXAvbWVtb3J5IiwgZXh0ZW5zaWJsZV9tZW1fdmFyaWFibGVzLCB2YXJpYWJsZTIsCiAgICAgICAgICAgICAgICAgbWVtX3ZhcmlhYmxlc19vaWQpOwoKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJzd2FwIiwgbWVtb3J5X3BhcnNlX2NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbW9yeV9mcmVlX2NvbmZpZywgIm1pbi1hdmFpbCIpOwoKfQoKc3RhdGljIHVfY2hhciAgKgp2YXJfZXh0ZW5zaWJsZV9tZW0oc3RydWN0IHZhcmlhYmxlICp2cCwKICAgICAgICAgICAgICAgICAgIG9pZCAqIG5hbWUsCiAgICAgICAgICAgICAgICAgICBzaXplX3QgKiBsZW5ndGgsCiAgICAgICAgICAgICAgICAgICBpbnQgZXhhY3QsCiAgICAgICAgICAgICAgICAgICBzaXplX3QgKiB2YXJfbGVuLCBXcml0ZU1ldGhvZCAqKiB3cml0ZV9tZXRob2QpCnsKICAgIHN0YXRpYyBsb25nICAgICBsb25nX3JldDsKCiAgICAvKgogICAgICogSW5pdGlhbGl6ZSB0aGUgcmV0dXJuIHZhbHVlIHRvIDAgCiAgICAgKi8KICAgIGxvbmdfcmV0ID0gMDsKCiAgICBpZiAoaGVhZGVyX2dlbmVyaWModnAsIG5hbWUsIGxlbmd0aCwgZXhhY3QsIHZhcl9sZW4sIHdyaXRlX21ldGhvZCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBzd2l0Y2ggKHZwLT5tYWdpYykgewogICAgY2FzZSBNSUJJTkRFWDoKICAgICAgICBsb25nX3JldCA9IDA7CiAgICAgICAgcmV0dXJuICgodV9jaGFyICopICgmbG9uZ19yZXQpKTsKICAgIGNhc2UgRVJST1JOQU1FOiAgICAgICAgICAgIC8qIGR1bW15IG5hbWUgKi8KICAgICAgICBzcHJpbnRmKGVycm1zZywgInN3YXAiKTsKICAgICAgICAqdmFyX2xlbiA9IHN0cmxlbihlcnJtc2cpOwogICAgICAgIHJldHVybiAoKHVfY2hhciAqKSAoZXJybXNnKSk7CiAgICBjYXNlIE1FTVRPVEFMU1dBUDoKICAgICAgICBsb25nX3JldCA9IGdldFRvdGFsU3dhcCgpICogKGdldHBhZ2VzaXplKCkgLyAxMDI0KTsKICAgICAgICByZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwogICAgY2FzZSBNRU1BVkFJTFNXQVA6CiAgICAgICAgbG9uZ19yZXQgPSBnZXRGcmVlU3dhcCgpICogKGdldHBhZ2VzaXplKCkgLyAxMDI0KTsKICAgICAgICByZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwogICAgY2FzZSBNRU1TV0FQTUlOSU1VTToKICAgICAgICBsb25nX3JldCA9IG1pbmltdW1zd2FwOwogICAgICAgIHJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CiAgICBjYXNlIE1FTVRPVEFMUkVBTDoKCQkgIGxvbmdfcmV0ID0gZ2V0VG90YWxSZWFsKCkgKiAoZ2V0cGFnZXNpemUoKSAvIDEwMjQpOwoJCSAgcmV0dXJuICgodV9jaGFyICopICgmbG9uZ19yZXQpKTsKICAgIGNhc2UgTUVNQVZBSUxSRUFMOgoJCSAgbG9uZ19yZXQgPSBnZXRGcmVlUmVhbCgpICogKGdldHBhZ2VzaXplKCkgLyAxMDI0KTsKCQkgIHJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CiAgICBjYXNlIE1FTVRPVEFMRlJFRToKICAgICAgICBsb25nX3JldCA9IGdldFRvdGFsRnJlZSgpICogKGdldHBhZ2VzaXplKCkgLyAxMDI0KTsKICAgICAgICByZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwoKICAgIGNhc2UgRVJST1JGTEFHOgogICAgICAgIGxvbmdfcmV0ID0gZ2V0VG90YWxGcmVlKCkgKiAoZ2V0cGFnZXNpemUoKSAvIDEwMjQpOwogICAgICAgIGxvbmdfcmV0ID0gKGxvbmdfcmV0ID4gbWluaW11bXN3YXApID8gMCA6IDE7CiAgICAgICAgcmV0dXJuICgodV9jaGFyICopICgmbG9uZ19yZXQpKTsKCiAgICBjYXNlIEVSUk9STVNHOgogICAgICAgIGxvbmdfcmV0ID0gZ2V0VG90YWxGcmVlKCkgKiAoZ2V0cGFnZXNpemUoKSAvIDEwMjQpOwogICAgICAgIGlmICgobG9uZ19yZXQgPiBtaW5pbXVtc3dhcCkgPyAwIDogMSkKICAgICAgICAgICAgc3ByaW50ZihlcnJtc2csICJSdW5uaW5nIG91dCBvZiBzd2FwIHNwYWNlICglbGQpIiwgbG9uZ19yZXQpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZXJybXNnWzBdID0gMDsKICAgICAgICAqdmFyX2xlbiA9IHN0cmxlbihlcnJtc2cpOwogICAgICAgIHJldHVybiAoKHVfY2hhciAqKSAoZXJybXNnKSk7CgogICAgfQoKICAgIHJldHVybiAoTlVMTCk7Cn0KCiNkZWZpbmUgREVGQVVMVE1JTklNVU1TV0FQIDE2MDAwICAgICAgICAvKiBraWxvYnl0ZXMgKi8KCnZvaWQKbWVtb3J5X3BhcnNlX2NvbmZpZyhjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0cikKewogICAgbWluaW11bXN3YXAgPSBhdG9pKGNwdHIpOwp9Cgp2b2lkCm1lbW9yeV9mcmVlX2NvbmZpZyh2b2lkKQp7CiAgICBtaW5pbXVtc3dhcCA9IERFRkFVTFRNSU5JTVVNU1dBUDsKfQoKc3RhdGljIGxvbmcKZ2V0VG90YWxTd2FwKHZvaWQpCnsKICAgIGxvbmcgICAgICAgICAgICB0b3RhbF9tZW0gPSAtMTsKCSBwZXJmc3RhdF9tZW1vcnlfdG90YWxfdCBtZW07CgoJIGlmKHBlcmZzdGF0X21lbW9yeV90b3RhbCgocGVyZnN0YXRfaWRfdCAqKU5VTEwsICZtZW0sIHNpemVvZihwZXJmc3RhdF9tZW1vcnlfdG90YWxfdCksIDEpID49IDEpIHsKCQkgdG90YWxfbWVtID0gbWVtLnBnc3BfdG90YWw7CgkgfQoKICAgIHJldHVybiAodG90YWxfbWVtKTsKfQoKc3RhdGljIGxvbmcKZ2V0RnJlZVN3YXAodm9pZCkKewogICAgbG9uZyAgICAgICAgICAgIGZyZWVfbWVtID0gLTE7CgkgcGVyZnN0YXRfbWVtb3J5X3RvdGFsX3QgbWVtOwoKCSBpZihwZXJmc3RhdF9tZW1vcnlfdG90YWwoKHBlcmZzdGF0X2lkX3QgKilOVUxMLCAmbWVtLCBzaXplb2YocGVyZnN0YXRfbWVtb3J5X3RvdGFsX3QpLCAxKSA+PSAxKSB7CgkJIGZyZWVfbWVtID0gbWVtLnBnc3BfZnJlZTsKCSB9CgogICAgcmV0dXJuIChmcmVlX21lbSk7Cn0KCnN0YXRpYyBsb25nCmdldFRvdGFsRnJlZSh2b2lkKQp7CiAgICBsb25nICAgICAgICAgICAgZnJlZV9tZW0gPSAtMTsKCSBwZXJmc3RhdF9tZW1vcnlfdG90YWxfdCBtZW07CgoJIGlmKHBlcmZzdGF0X21lbW9yeV90b3RhbCgocGVyZnN0YXRfaWRfdCAqKU5VTEwsICZtZW0sIHNpemVvZihwZXJmc3RhdF9tZW1vcnlfdG90YWxfdCksIDEpID49IDEpIHsKCQkgZnJlZV9tZW0gPSBtZW0ucGdzcF9mcmVlICsgbWVtLnJlYWxfZnJlZTsKCSB9CgogICAgcmV0dXJuIChmcmVlX21lbSk7Cn0KCnN0YXRpYyBsb25nCmdldFRvdGFsUmVhbCh2b2lkKQp7CiAgICBsb25nICAgICAgICAgICAgdG90YWxfbWVtID0gLTE7CgkgcGVyZnN0YXRfbWVtb3J5X3RvdGFsX3QgbWVtOwoKCSBpZihwZXJmc3RhdF9tZW1vcnlfdG90YWwoKHBlcmZzdGF0X2lkX3QgKilOVUxMLCAmbWVtLCBzaXplb2YocGVyZnN0YXRfbWVtb3J5X3RvdGFsX3QpLCAxKSA+PSAxKSB7CgkJIHRvdGFsX21lbSA9IG1lbS5yZWFsX3RvdGFsOwoJIH0KCiAgICByZXR1cm4gKHRvdGFsX21lbSk7Cn0KCnN0YXRpYyBsb25nCmdldEZyZWVSZWFsKHZvaWQpCnsKICAgIGxvbmcgICAgICAgICAgICBmcmVlX21lbSA9IC0xOwoJIHBlcmZzdGF0X21lbW9yeV90b3RhbF90IG1lbTsKCgkgaWYocGVyZnN0YXRfbWVtb3J5X3RvdGFsKChwZXJmc3RhdF9pZF90ICopTlVMTCwgJm1lbSwgc2l6ZW9mKHBlcmZzdGF0X21lbW9yeV90b3RhbF90KSwgMSkgPj0gMSkgewoJCSBmcmVlX21lbSA9IG1lbS5yZWFsX2ZyZWU7CgkgfQoKICAgIHJldHVybiAoZnJlZV9tZW0pOwp9Cg==