LyoKICogTkRSIC1PaSwtT2lmLC1PaWNmIEludGVycHJldGVyCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAzLTUgUm9iZXJ0IFNoZWFybWFuIChmb3IgQ29kZVdlYXZlcnMpCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBUT0RPOgogKiAgLSBQaXBlcwogKiAgLSBTb21lIHR5cGVzIG9mIGJpbmRpbmcgaGFuZGxlcwogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgIm9iamJhc2UuaCIKI2luY2x1ZGUgInJwYy5oIgojaW5jbHVkZSAicnBjcHJveHkuaCIKI2luY2x1ZGUgIm5kcnR5cGVzLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS9ycGNmYy5oIgoKI2luY2x1ZGUgIm5kcl9taXNjLmgiCiNpbmNsdWRlICJjcHNmLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChycGMpOwoKI2RlZmluZSBORFJfVEFCTEVfTUFTSyAxMjcKCnN0YXRpYyBpbmxpbmUgdm9pZCBjYWxsX2J1ZmZlcl9zaXplcihQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csIHVuc2lnbmVkIGNoYXIgKnBNZW1vcnksIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICAgIE5EUl9CVUZGRVJTSVpFIG0gPSBOZHJCdWZmZXJTaXplcltwRm9ybWF0WzBdICYgTkRSX1RBQkxFX01BU0tdOwogICAgaWYgKG0pIG0ocFN0dWJNc2csIHBNZW1vcnksIHBGb3JtYXQpOwogICAgZWxzZQogICAgewogICAgICAgIEZJWE1FKCJmb3JtYXQgdHlwZSAweCV4IG5vdCBpbXBsZW1lbnRlZFxuIiwgcEZvcm1hdFswXSk7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICB9Cn0KCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgY2hhciAqY2FsbF9tYXJzaGFsbGVyKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgdW5zaWduZWQgY2hhciAqcE1lbW9yeSwgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCkKewogICAgTkRSX01BUlNIQUxMIG0gPSBOZHJNYXJzaGFsbGVyW3BGb3JtYXRbMF0gJiBORFJfVEFCTEVfTUFTS107CiAgICBpZiAobSkgcmV0dXJuIG0ocFN0dWJNc2csIHBNZW1vcnksIHBGb3JtYXQpOwogICAgZWxzZQogICAgewogICAgICAgIEZJWE1FKCJmb3JtYXQgdHlwZSAweCV4IG5vdCBpbXBsZW1lbnRlZFxuIiwgcEZvcm1hdFswXSk7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9Cn0KCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgY2hhciAqY2FsbF91bm1hcnNoYWxsZXIoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCB1bnNpZ25lZCBjaGFyICoqcHBNZW1vcnksIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQsIHVuc2lnbmVkIGNoYXIgZk11c3RBbGxvYykKewogICAgTkRSX1VOTUFSU0hBTEwgbSA9IE5kclVubWFyc2hhbGxlcltwRm9ybWF0WzBdICYgTkRSX1RBQkxFX01BU0tdOwogICAgaWYgKG0pIHJldHVybiBtKHBTdHViTXNnLCBwcE1lbW9yeSwgcEZvcm1hdCwgZk11c3RBbGxvYyk7CiAgICBlbHNlCiAgICB7CiAgICAgICAgRklYTUUoImZvcm1hdCB0eXBlIDB4JXggbm90IGltcGxlbWVudGVkXG4iLCBwRm9ybWF0WzBdKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KfQoKc3RhdGljIGlubGluZSB2b2lkIGNhbGxfZnJlZXIoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCB1bnNpZ25lZCBjaGFyICpwTWVtb3J5LCBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgICBORFJfRlJFRSBtID0gTmRyRnJlZXJbcEZvcm1hdFswXSAmIE5EUl9UQUJMRV9NQVNLXTsKICAgIGlmIChtKSBtKHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKICAgIGVsc2UKICAgIHsKICAgICAgICBGSVhNRSgiZm9ybWF0IHR5cGUgMHgleCBub3QgaW1wbGVtZW50ZWRcbiIsIHBGb3JtYXRbMF0pOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgfQp9CgpzdGF0aWMgaW5saW5lIHVuc2lnbmVkIGxvbmcgY2FsbF9tZW1vcnlfc2l6ZXIoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgICBORFJfTUVNT1JZU0laRSBtID0gTmRyTWVtb3J5U2l6ZXJbcEZvcm1hdFswXSAmIE5EUl9UQUJMRV9NQVNLXTsKICAgIGlmIChtKSByZXR1cm4gbShwU3R1Yk1zZywgcEZvcm1hdCk7CiAgICBlbHNlCiAgICB7CiAgICAgICAgRklYTUUoImZvcm1hdCB0eXBlIDB4JXggbm90IGltcGxlbWVudGVkXG4iLCBwRm9ybWF0WzBdKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KfQoKLyogdGhlcmUgY2FuJ3QgYmUgYW55IGFsaWdubWVudCB3aXRoIHRoZSBzdHJ1Y3R1cmVzIGluIHRoaXMgZmlsZSAqLwojaW5jbHVkZSAicHNocGFjazEuaCIKCiNkZWZpbmUgU1RVQkxFU1NfVU5NQVJTSEFMICAxCiNkZWZpbmUgU1RVQkxFU1NfQ0FMTFNFUlZFUiAyCiNkZWZpbmUgU1RVQkxFU1NfQ0FMQ1NJWkUgICAzCiNkZWZpbmUgU1RVQkxFU1NfR0VUQlVGRkVSICA0CiNkZWZpbmUgU1RVQkxFU1NfTUFSU0hBTCAgICA1CgovKiBGcm9tIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvcnBjL3JwYy9wYXJhbWV0ZXJfZGVzY3JpcHRvcnMuYXNwICovCnR5cGVkZWYgc3RydWN0IF9ORFJfUFJPQ19IRUFERVIKewogICAgLyogdHlwZSBvZiBoYW5kbGUgdG8gdXNlOgogICAgICogUlBDX0ZDX0JJTkRfRVhQTElDSVQgPSAwIC0gRXhwbGljaXQgaGFuZGxlLgogICAgICogICBIYW5kbGUgaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyIHRvIHRoZSBmdW5jdGlvbi4KICAgICAqICAgSW5kaWNhdGVzIHRoYXQgZXhwbGljaXQgaGFuZGxlIGluZm9ybWF0aW9uIGZvbGxvd3MgdGhlIGhlYWRlciwKICAgICAqICAgd2hpY2ggYWN0dWFsbHkgZGVzY3JpYmVzIHRoZSBoYW5kbGUuCiAgICAgKiBSUENfRkNfQklORF9HRU5FUklDID0gMzEgLSBJbXBsaWNpdCBoYW5kbGUgd2l0aCBjdXN0b20gYmluZGluZyByb3V0aW5lcwogICAgICogICAoTUlETF9TVFVCX0RFU0M6OklNUExJQ0lUX0hBTkRMRV9JTkZPOjpwR2VuZXJpY0JpbmRpbmdJbmZvKQogICAgICogUlBDX0ZDX0JJTkRfUFJJTUlUSVZFID0gMzIgLSBJbXBsaWNpdCBoYW5kbGUgdXNpbmcgaGFuZGxlX3QgY3JlYXRlZCBieQogICAgICogICBjYWxsaW5nIGFwcGxpY2F0aW9uCiAgICAgKiBSUENfRkNfQVVUT19IQU5ETEUgPSAzMyAtIEF1dG9tYXRpYyBoYW5kbGUKICAgICAqIFJQQ19GQ19DQUxMQkFDS19IQU5ETEUgPSAzNCAtIHVuZG9jbWVudGVkCiAgICAgKi8KICAgIHVuc2lnbmVkIGNoYXIgaGFuZGxlX3R5cGU7CgogICAgLyogcHJvY2VkdXJlIGZsYWdzOgogICAgICogT2lfRlVMTF9QVFJfVVNFRCA9IDB4MDEgLSBBIGZ1bGwgcG9pbnRlciBjYW4gaGF2ZSB0aGUgdmFsdWUgTlVMTCBhbmQgY2FuCiAgICAgKiAgIGNoYW5nZSBkdXJpbmcgdGhlIGNhbGwgZnJvbSBOVUxMIHRvIG5vbi1OVUxMIGFuZCBzdXBwb3J0cyBhbGlhc2luZwogICAgICogICBhbmQgY3ljbGVzLiBJbmRpY2F0ZXMgdGhhdCB0aGUgTmRyRnVsbFBvaW50ZXJYbGF0SW5pdCBmdW5jdGlvbgogICAgICogICBzaG91bGQgYmUgY2FsbGVkLgogICAgICogT2lfUlBDU1NfQUxMT0NfVVNFRCA9IDB4MDIgLSBVc2UgUnBjU1MgYWxsb2NhdGUvZnJlZSByb3V0aW5lcyBpbnN0ZWFkIG9mCiAgICAgKiAgIG5vcm1hbCBhbGxvY2F0ZS9mcmVlIHJvdXRpbmVzCiAgICAgKiBPaV9PQkpFQ1RfUFJPQyA9IDB4MDQgLSBJbmRpY2F0ZXMgYSBwcm9jZWR1cmUgdGhhdCBpcyBwYXJ0IG9mIGFuIE9MRQogICAgICogICBpbnRlcmZhY2UsIHJhdGhlciB0aGFuIGEgRENFIFJQQyBpbnRlcmZhY2UuCiAgICAgKiBPaV9IQVNfUlBDRkxBR1MgPSAweDA4IC0gSW5kaWNhdGVzIHRoYXQgdGhlIHJwY19mbGFncyBlbGVtZW50IGlzIAogICAgICogICBwcmVzZW50IGluIHRoZSBoZWFkZXIuCiAgICAgKiBPaV9IQVNfQ09NTV9PUl9GQVVMVCA9IDB4MjAgLSBJZiBPaV9PQkpFQ1RfUFJPQyBub3QgcHJlc2VudCBvbmx5IHRoZW4KICAgICAqICAgaW5kaWNhdGVzIHRoYXQgdGhlIHByb2NlZHVyZSBoYXMgdGhlIGNvbW1fc3RhdHVzIG9yIGZhdWx0X3N0YXR1cwogICAgICogICBNSURMIGF0dHJpYnV0ZS4KICAgICAqIE9pX09CSl9VU0VfVjJfSU5URVJQUkVURVIgPSAweDIwIC0gSWYgT2lfT0JKRUNUX1BST0MgcHJlc2VudCBvbmx5CiAgICAgKiAgIHRoZW4gaW5kaWNhdGVzIHRoYXQgdGhlIGZvcm1hdCBzdHJpbmcgaXMgaW4gLU9pZiBvciAtT2ljZiBmb3JtYXQKICAgICAqIE9pX1VTRV9ORVdfSU5JVF9ST1VUSU5FUyA9IDB4NDAgLSBVc2UgTmRyWEluaXRpYWxpemVOZXcgaW5zdGVhZCBvZgogICAgICogICBOZHJYSW5pdGlhbGl6ZT8KICAgICAqLwogICAgdW5zaWduZWQgY2hhciBPaV9mbGFnczsKCiAgICAvKiB0aGUgemVyby1iYXNlZCBpbmRleCBvZiB0aGUgcHJvY2VkdXJlICovCiAgICB1bnNpZ25lZCBzaG9ydCBwcm9jX251bTsKCiAgICAvKiB0b3RhbCBzaXplIG9mIGFsbCBwYXJhbWV0ZXJzIG9uIHRoZSBzdGFjaywgaW5jbHVkaW5nIGFueSAidGhpcyIKICAgICAqIHBvaW50ZXIgYW5kL29yIHJldHVybiB2YWx1ZSAqLwogICAgdW5zaWduZWQgc2hvcnQgc3RhY2tfc2l6ZTsKfSBORFJfUFJPQ19IRUFERVI7CgovKiBzYW1lIGFzIGFib3ZlIHN0cnVjdCBleGNlcHQgYWRkaXRpb25hbCBlbGVtZW50IHJwY19mbGFncyAqLwp0eXBlZGVmIHN0cnVjdCBfTkRSX1BST0NfSEVBREVSX1JQQwp7CiAgICB1bnNpZ25lZCBjaGFyIGhhbmRsZV90eXBlOwogICAgdW5zaWduZWQgY2hhciBPaV9mbGFnczsKCiAgICAvKgogICAgICogUlBDRl9JZGVtcG90ZW50ID0gMHgwMDAxIC0gW2lkZW1wb3RlbnRdIE1JREwgYXR0cmlidXRlCiAgICAgKiBSUENGX0Jyb2FkY2FzdCA9IDB4MDAwMiAtIFticm9hZGNhc3RdIE1JREwgYXR0cmlidXRlCiAgICAgKiBSUENGX01heWJlID0gMHgwMDA0IC0gW21heWJlXSBNSURMIGF0dHJpYnV0ZQogICAgICogUmVzZXJ2ZWQgPSAweDAwMDggLSAweDAwODAKICAgICAqIFJQQ0ZfTWVzc2FnZSA9IDB4MDEwMCAtIFttZXNzYWdlXSBNSURMIGF0dHJpYnV0ZQogICAgICogUmVzZXJ2ZWQgPSAweDAyMDAgLSAweDEwMDAKICAgICAqIFJQQ0ZfSW5wdXRTeW5jaHJvbm91cyA9IDB4MjAwMCAtIHVua25vd24KICAgICAqIFJQQ0ZfQXN5bmNocm9ub3VzID0gMHg0MDAwIC0gW2FzeW5jXSBNSURMIGF0dHJpYnV0ZQogICAgICogUmVzZXJ2ZWQgPSAweDgwMDAKICAgICAqLwogICAgdW5zaWduZWQgbG9uZyBycGNfZmxhZ3M7CiAgICB1bnNpZ25lZCBzaG9ydCBwcm9jX251bTsKICAgIHVuc2lnbmVkIHNob3J0IHN0YWNrX3NpemU7Cgp9IE5EUl9QUk9DX0hFQURFUl9SUEM7Cgp0eXBlZGVmIHN0cnVjdCBfTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSCnsKICAgIC8qIHRoZSBwcmUtY29tcHV0ZWQgY2xpZW50IGJ1ZmZlciBzaXplIHNvIHRoYXQgaW50ZXJwcmV0ZXIgY2FuIHNraXAgYWxsCiAgICAgKiBvciBzb21lIChpZiB0aGUgZmxhZyBSUENfRkNfUFJPQ19PSTJGX0NMVE1VU1RTSVpFIGlzIHNwZWNpZmllZCkgb2YgdGhlCiAgICAgKiBzaXppbmcgcGFzcyAqLwogICAgdW5zaWduZWQgc2hvcnQgY29uc3RhbnRfY2xpZW50X2J1ZmZlcl9zaXplOwoKICAgIC8qIHRoZSBwcmUtY29tcHV0ZWQgc2VydmVyIGJ1ZmZlciBzaXplIHNvIHRoYXQgaW50ZXJwcmV0ZXIgY2FuIHNraXAgYWxsCiAgICAgKiBvciBzb21lIChpZiB0aGUgZmxhZyBSUENfRkNfUFJPQ19PSTJGX1NSVk1VU1RTSVpFIGlzIHNwZWNpZmllZCkgb2YgdGhlCiAgICAgKiBzaXppbmcgcGFzcyAqLwogICAgdW5zaWduZWQgc2hvcnQgY29uc3RhbnRfc2VydmVyX2J1ZmZlcl9zaXplOwoKICAgIElOVEVSUFJFVEVSX09QVF9GTEFHUyBPaTJGbGFnczsKCiAgICAvKiBudW1iZXIgb2YgcGFyYW1zICovCiAgICB1bnNpZ25lZCBjaGFyIG51bWJlcl9vZl9wYXJhbXM7Cn0gTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSOwoKdHlwZWRlZiBzdHJ1Y3QgX05EUl9QQVJBTV9PSV9CQVNFVFlQRQp7CiAgICAvKiBwYXJhbWV0ZXIgZGlyZWN0aW9uLiBPbmUgb2Y6CiAgICAgKiBGQ19JTl9QQVJBTV9CQVNFVFlQRSA9IDB4NGUgLSBhbiBpbiBwYXJhbQogICAgICogRkNfUkVUVVJOX1BBUkFNX0JBU0VUWVBFID0gMHg1MyAtIGEgcmV0dXJuIHBhcmFtCiAgICAgKi8KICAgIHVuc2lnbmVkIGNoYXIgcGFyYW1fZGlyZWN0aW9uOwoKICAgIC8qIE9uZSBvZjogRkNfQllURSxGQ19DSEFSLEZDX1NNQUxMLEZDX1VTTUFMTCxGQ19XQ0hBUixGQ19TSE9SVCxGQ19VU0hPUlQsCiAgICAgKiBGQ19MT05HLEZDX1VMT05HLEZDX0ZMT0FULEZDX0hZUEVSLEZDX0RPVUJMRSxGQ19FTlVNMTYsRkNfRU5VTTMyLAogICAgICogRkNfRVJST1JfU1RBVFVTX1QsRkNfSU5UMzI2NCxGQ19VSU5UMzI2NCAqLwogICAgdW5zaWduZWQgY2hhciB0eXBlX2Zvcm1hdF9jaGFyOwp9IE5EUl9QQVJBTV9PSV9CQVNFVFlQRTsKCnR5cGVkZWYgc3RydWN0IF9ORFJfUEFSQU1fT0lfT1RIRVIKewogICAgLyogT25lIG9mOgogICAgICogRkNfSU5fUEFSQU0gPSAweDRkIC0gQW4gaW4gcGFyYW0KICAgICAqIEZDX0lOX09VVF9QQVJBTSA9IDB4NTAgLSBBbiBpbi9vdXQgcGFyYW0KICAgICAqIEZDX09VVF9QQVJBTSA9IDB4NTEgLSBBbiBvdXQgcGFyYW0KICAgICAqIEZDX1JFVFVSTl9QQVJBTSA9IDB4NTIgLSBBIHJldHVybiB2YWx1ZQogICAgICogRkNfSU5fUEFSQU1fTk9fRlJFRV9JTlNUID0gMHg0ZiAtIEEgcGFyYW0gZm9yIHdoaWNoIG5vIGZyZWVpbmcgaXMgZG9uZQogICAgICovCiAgICB1bnNpZ25lZCBjaGFyIHBhcmFtX2RpcmVjdGlvbjsKCiAgICAvKiBTaXplIG9mIHBhcmFtIG9uIHN0YWNrIGluIE5VTUJFUlMgT0YgSU5UUyAqLwogICAgdW5zaWduZWQgY2hhciBzdGFja19zaXplOwoKICAgIC8qIG9mZnNldCBpbiB0aGUgdHlwZSBmb3JtYXQgc3RyaW5nIHRhYmxlICovCiAgICB1bnNpZ25lZCBzaG9ydCB0eXBlX29mZnNldDsKfSBORFJfUEFSQU1fT0lfT1RIRVI7Cgp0eXBlZGVmIHN0cnVjdCBfTkRSX1BBUkFNX09JRl9CQVNFVFlQRQp7CiAgICBQQVJBTV9BVFRSSUJVVEVTIHBhcmFtX2F0dHJpYnV0ZXM7CgogICAgLyogdGhlIG9mZnNldCBvbiB0aGUgY2FsbGluZyBzdGFjayB3aGVyZSB0aGUgcGFyYW1ldGVyIGlzIGxvY2F0ZWQgKi8KICAgIHVuc2lnbmVkIHNob3J0IHN0YWNrX29mZnNldDsKCiAgICAvKiBzZWUgTkRSX1BBUkFNX09JX0JBU0VUWVBFOjp0eXBlX2Zvcm1hdF9jaGFyICovCiAgICB1bnNpZ25lZCBjaGFyIHR5cGVfZm9ybWF0X2NoYXI7CgogICAgLyogYWx3YXlzIEZDX1BBRCAqLwogICAgdW5zaWduZWQgY2hhciB1bnVzZWQ7Cn0gTkRSX1BBUkFNX09JRl9CQVNFVFlQRTsKCnR5cGVkZWYgc3RydWN0IF9ORFJfUEFSQU1fT0lGX09USEVSCnsKICAgIFBBUkFNX0FUVFJJQlVURVMgcGFyYW1fYXR0cmlidXRlczsKCiAgICAvKiBzZWUgTkRSX1BBUkFNX09JRl9CQVNFVFlQRTo6c3RhY2tfb2Zmc2V0ICovCiAgICB1bnNpZ25lZCBzaG9ydCBzdGFja19vZmZzZXQ7CgogICAgLyogb2Zmc2V0IGludG8gdGhlIHByb3ZpZGVkIHR5cGUgZm9ybWF0IHN0cmluZyB3aGVyZSB0aGUgdHlwZSBmb3IgdGhpcwogICAgICogcGFyYW1ldGVyIHN0YXJ0cyAqLwogICAgdW5zaWduZWQgc2hvcnQgdHlwZV9vZmZzZXQ7Cn0gTkRSX1BBUkFNX09JRl9PVEhFUjsKCi8qIGV4cGxpY2l0IGhhbmRsZSBkZXNjcmlwdGlvbiBmb3IgRkNfQklORF9QUklNSVRJVkUgdHlwZSAqLwp0eXBlZGVmIHN0cnVjdCBfTkRSX0VIRF9QUklNSVRJVkUKewogICAgLyogRkNfQklORF9QUklNSVRJVkUgKi8KICAgIHVuc2lnbmVkIGNoYXIgaGFuZGxlX3R5cGU7CgogICAgLyogaXMgdGhlIGhhbmRsZSBwYXNzZWQgaW4gdmlhIGEgcG9pbnRlcj8gKi8KICAgIHVuc2lnbmVkIGNoYXIgZmxhZzsKCiAgICAvKiBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdGFjayB0byB0aGUgaGFuZGxlIGluIGJ5dGVzICovCiAgICB1bnNpZ25lZCBzaG9ydCBvZmZzZXQ7Cn0gTkRSX0VIRF9QUklNSVRJVkU7CgovKiBleHBsaWNpdCBoYW5kbGUgZGVzY3JpcHRpb24gZm9yIEZDX0JJTkRfR0VORVJJQyB0eXBlICovCnR5cGVkZWYgc3RydWN0IF9ORFJfRUhEX0dFTkVSSUMKewogICAgLyogRkNfQklORF9HRU5FUklDICovCiAgICB1bnNpZ25lZCBjaGFyIGhhbmRsZV90eXBlOwoKICAgIC8qIHVwcGVyIDRiaXRzIGlzIGEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGhhbmRsZSBpcyBwYXNzZWQgaW4KICAgICAqIHZpYSBhIHBvaW50ZXIuIGxvd2VyIDRiaXRzIGlzIHRoZSBzaXplIG9mIHRoZSB1c2VyIGRlZmluZWQgZ2VuZXJpYwogICAgICogaGFuZGxlIHR5cGUuIHRoZSBzaXplIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBtYWNoaW5lCiAgICAgKiByZWdpc3RlciBzaXplICovCiAgICB1bnNpZ25lZCBjaGFyIGZsYWdfYW5kX3NpemU7CgogICAgLyogb2Zmc2V0IGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RhY2sgdG8gdGhlIGhhbmRsZSBpbiBieXRlcyAqLwogICAgdW5zaWduZWQgc2hvcnQgb2Zmc2V0OwoKICAgIC8qIHRoZSBpbmRleCBpbnRvIHRoZSBhR2VuZXJpY0JpbmRpbmdSb3V0aW5lc1BhaXJzIGZpZWxkIG9mIE1JRExfU1RVQl9ERVNDCiAgICAgKiBnaXZpbmcgdGhlIGJpbmQgYW5kIHVuYmluZCByb3V0aW5lcyBmb3IgdGhlIGhhbmRsZSAqLwogICAgdW5zaWduZWQgY2hhciBiaW5kaW5nX3JvdXRpbmVfcGFpcl9pbmRleDsKCiAgICAvKiBGQ19QQUQgKi8KICAgIHVuc2lnbmVkIGNoYXIgdW51c2VkOwp9IE5EUl9FSERfR0VORVJJQzsKCi8qIGV4cGxpY2l0IGhhbmRsZSBkZXNjcmlwdGlvbiBmb3IgRkNfQklORF9DT05URVhUIHR5cGUgKi8KdHlwZWRlZiBzdHJ1Y3QgX05EUl9FSERfQ09OVEVYVAp7CiAgICAvKiBGQ19CSU5EX0NPTlRFWFQgKi8KICAgIHVuc2lnbmVkIGNoYXIgaGFuZGxlX3R5cGU7CgogICAgLyogQW55IG9mIHRoZSBmb2xsb3dpbmcgZmxhZ3M6CiAgICAgKiBORFJfQ09OVEVYVF9IQU5ETEVfQ0FOTk9UX0JFX05VTEwgPSAweDAxCiAgICAgKiBORFJfQ09OVEVYVF9IQU5ETEVfU0VSSUFMSVpFID0gMHgwMgogICAgICogTkRSX0NPTlRFWFRfSEFORExFX05PX1NFUklBTElaRSA9IDB4MDQKICAgICAqIE5EUl9TVFJJQ1RfQ09OVEVYVF9IQU5ETEUgPSAweDA4CiAgICAgKiBIQU5ETEVfUEFSQU1fSVNfT1VUID0gMHgyMAogICAgICogSEFORExFX1BBUkFNX0lTX1JFVFVSTiA9IDB4MjEKICAgICAqIEhBTkRMRV9QQVJBTV9JU19JTiA9IDB4NDAKICAgICAqIEhBTkRMRV9QQVJBTV9JU19WSUFfUFRSID0gMHg4MAogICAgICovCiAgICB1bnNpZ25lZCBjaGFyIGZsYWdzOwoKICAgIC8qIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0YWNrIHRvIHRoZSBoYW5kbGUgaW4gYnl0ZXMgKi8KICAgIHVuc2lnbmVkIHNob3J0IG9mZnNldDsKCiAgICAvKiB6ZXJvLWJhc2VkIGluZGV4IG9uIHJ1bmRvd24gcm91dGluZSBpbiBhcGZuTmRyUnVuZG93blJvdXRpbmVzIGZpZWxkCiAgICAgKiBvZiBNSURMX1NUVUJfREVTQyAqLwogICAgdW5zaWduZWQgY2hhciBjb250ZXh0X3J1bmRvd25fcm91dGluZV9pbmRleDsKCiAgICAvKiB2YXJpZXMgZGVwZW5kaW5nIG9uIE5EUiB2ZXJzaW9uIHVzZWQuCiAgICAgKiBWMTogemVyby1iYXNlZCBpbmRleCBpbnRvIHBhcmFtZXRlcnMgCiAgICAgKiBWMjogemVyby1iYXNlZCBpbmRleCBpbnRvIGhhbmRsZXMgdGhhdCBhcmUgcGFyYW1ldGVycyAqLwogICAgdW5zaWduZWQgY2hhciBwYXJhbV9udW07Cn0gTkRSX0VIRF9DT05URVhUOwoKI2luY2x1ZGUgInBvcHBhY2suaCIKCnZvaWQgV0lOQVBJIE5kclJwY1NtU2V0Q2xpZW50VG9Pc2YoUE1JRExfU1RVQl9NRVNTQUdFIHBNZXNzYWdlKQp7CiNpZiAwIC8qIHRoZXNlIGZ1bmN0aW9ucyBhcmUgbm90IGRlZmluZWQgeWV0ICovCiAgICBwTWVzc2FnZS0+cGZuQWxsb2NhdGUgPSBOZHJScGNTbUNsaWVudEFsbG9jYXRlOwogICAgcE1lc3NhZ2UtPnBmbkZyZWUgPSBOZHJScGNTbUNsaWVudEZyZWU7CiNlbmRpZgp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgZHVtcF9SUENfRkNfUFJPQ19QRihQQVJBTV9BVFRSSUJVVEVTIHBhcmFtX2F0dHJpYnV0ZXMpCnsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLk11c3RTaXplKSBUUkFDRSgiIE11c3RTaXplIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5NdXN0RnJlZSkgVFJBQ0UoIiBNdXN0RnJlZSIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNQaXBlKSBUUkFDRSgiIElzUGlwZSIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNJbikgVFJBQ0UoIiBJc0luIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc091dCkgVFJBQ0UoIiBJc091dCIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNSZXR1cm4pIFRSQUNFKCIgSXNSZXR1cm4iKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLklzQmFzZXR5cGUpIFRSQUNFKCIgSXNCYXNldHlwZSIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNCeVZhbHVlKSBUUkFDRSgiIElzQnlWYWx1ZSIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNTaW1wbGVSZWYpIFRSQUNFKCIgSXNTaW1wbGVSZWYiKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLklzRG9udENhbGxGcmVlSW5zdCkgVFJBQ0UoIiBJc0RvbnRDYWxsRnJlZUluc3QiKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLlNhdmVGb3JBc3luY0ZpbmlzaCkgVFJBQ0UoIiBTYXZlRm9yQXN5bmNGaW5pc2giKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLlNlcnZlckFsbG9jU2l6ZSkgVFJBQ0UoIiBTZXJ2ZXJBbGxvY1NpemUgPSAlZCIsIHBhcmFtX2F0dHJpYnV0ZXMuU2VydmVyQWxsb2NTaXplICogOCk7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBkdW1wX0lOVEVSUFJFVEVSX09QVF9GTEFHUyhJTlRFUlBSRVRFUl9PUFRfRkxBR1MgT2kyRmxhZ3MpCnsKICAgIGlmIChPaTJGbGFncy5TZXJ2ZXJNdXN0U2l6ZSkgVFJBQ0UoIiBTZXJ2ZXJNdXN0U2l6ZSIpOwogICAgaWYgKE9pMkZsYWdzLkNsaWVudE11c3RTaXplKSBUUkFDRSgiIENsaWVudE11c3RTaXplIik7CiAgICBpZiAoT2kyRmxhZ3MuSGFzUmV0dXJuKSBUUkFDRSgiIEhhc1JldHVybiIpOwogICAgaWYgKE9pMkZsYWdzLkhhc1BpcGVzKSBUUkFDRSgiIEhhc1BpcGVzIik7CiAgICBpZiAoT2kyRmxhZ3MuVW51c2VkKSBUUkFDRSgiIFVudXNlZCIpOwogICAgaWYgKE9pMkZsYWdzLkhhc0FzeW5jVXVpZCkgVFJBQ0UoIiBIYXNBc3luY1V1aWQiKTsKICAgIGlmIChPaTJGbGFncy5IYXNFeHRlbnNpb25zKSBUUkFDRSgiIEhhc0V4dGVuc2lvbnMiKTsKICAgIGlmIChPaTJGbGFncy5IYXNBc3luY0hhbmRsZSkgVFJBQ0UoIiBIYXNBc3luY0hhbmRsZSIpOwogICAgVFJBQ0UoIlxuIik7Cn0KCi8qIEZJWE1FOiB0aGlzIHdpbGwgYmUgZGlmZmVyZW50IG9uIG90aGVyIHBsYWZ0b3JtcyB0aGFuIGkzODYgKi8KI2RlZmluZSBBUkdfRlJPTV9PRkZTRVQoYXJncywgb2Zmc2V0KSAoKih1bnNpZ25lZCBjaGFyICoqKWFyZ3MgKyBvZmZzZXQpCgovKiB0aGUgcmV0dXJuIHR5cGUgc2hvdWxkIGJlIENMSUVOVF9DQUxMX1JFVFVSTiwgYnV0IHRoaXMgaXMgaW5jb21wYXRpYmxlCiAqIHdpdGggdGhlIHdheSBnY2MgcmV0dXJucyBzdHJ1Y3R1cmVzLiAidm9pZCAqIiBzaG91bGQgYmUgdGhlIGxhcmdlc3QgdHlwZQogKiB0aGF0IE1JREwgc2hvdWxkIGFsbG93IHlvdSB0byByZXR1cm4gYW55d2F5ICovCkxPTkdfUFRSIFdJTkFQSVYgTmRyQ2xpZW50Q2FsbDIoUE1JRExfU1RVQl9ERVNDIHBTdHViRGVzYywgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCwgLi4uKQp7CiAgICAvKiBwb2ludGVyIHRvIHN0YXJ0IG9mIHN0YWNrIHdoZXJlIGFyZ3VtZW50cyBzdGFydCAqLwogICAgLyogRklYTUU6IG5vdCBwb3J0YWJsZSAqLwogICAgdW5zaWduZWQgY2hhciAqYXJncyA9ICh1bnNpZ25lZCBjaGFyICopKCZwRm9ybWF0KzEpOwogICAgUlBDX01FU1NBR0UgcnBjTXNnOwogICAgTUlETF9TVFVCX01FU1NBR0Ugc3R1Yk1zZzsKICAgIGhhbmRsZV90IGhCaW5kaW5nID0gTlVMTDsKICAgIC8qIHByb2NlZHVyZSBudW1iZXIgKi8KICAgIHVuc2lnbmVkIHNob3J0IHByb2NlZHVyZV9udW1iZXI7CiAgICAvKiBzaXplIG9mIHN0YWNrICovCiAgICB1bnNpZ25lZCBzaG9ydCBzdGFja19zaXplOwogICAgLyogY3VycmVudCBzdGFjayBvZmZzZXQgKi8KICAgIHVuc2lnbmVkIHNob3J0IGN1cnJlbnRfc3RhY2tfb2Zmc2V0OwogICAgLyogbnVtYmVyIG9mIHBhcmFtZXRlcnMuIG9wdGlvbmFsIGZvciBjbGllbnQgdG8gZ2l2ZSBpdCB0byB1cyAqLwogICAgdW5zaWduZWQgY2hhciBudW1iZXJfb2ZfcGFyYW1zID0gfjA7CiAgICAvKiBjb3VudGVyICovCiAgICB1bnNpZ25lZCBzaG9ydCBpOwogICAgLyogY2FjaGUgb2YgT2lmX2ZsYWdzIGZyb20gdjIgcHJvY2VkdXJlIGhlYWRlciAqLwogICAgSU5URVJQUkVURVJfT1BUX0ZMQUdTIE9pZl9mbGFncyA9IHsgMCB9OwogICAgLyogY2FjaGUgb2YgZXh0ZW5zaW9uIGZsYWdzIGZyb20gTkRSX1BST0NfSEVBREVSX0VYVFMgKi8KICAgIElOVEVSUFJFVEVSX09QVF9GTEFHUzIgZXh0X2ZsYWdzID0geyAwIH07CiAgICAvKiB0aGUgdHlwZSBvZiBwYXNzIHdlIGFyZSBjdXJyZW50bHkgZG9pbmcgKi8KICAgIGludCBwaGFzZTsKICAgIC8qIGhlYWRlciBmb3IgcHJvY2VkdXJlIHN0cmluZyAqLwogICAgY29uc3QgTkRSX1BST0NfSEVBREVSICogcFByb2NIZWFkZXIgPSAoY29uc3QgTkRSX1BST0NfSEVBREVSICopJnBGb3JtYXRbMF07CiAgICAvKiBvZmZzZXQgaW4gZm9ybWF0IHN0cmluZyBmb3Igc3RhcnQgb2YgcGFyYW1zICovCiAgICBpbnQgcGFyYW1ldGVyX3N0YXJ0X29mZnNldDsKICAgIC8qIGN1cnJlbnQgZm9ybWF0IHN0cmluZyBvZmZzZXQgKi8KICAgIGludCBjdXJyZW50X29mZnNldDsKICAgIC8qIC1PaWYgb3IgLU9pY2YgZ2VuZXJhdGVkIGZvcm1hdCAqLwogICAgQk9PTCBiVjJGb3JtYXQgPSBGQUxTRTsKICAgIC8qIHRoZSB2YWx1ZSB0byByZXR1cm4gdG8gdGhlIGNsaWVudCBmcm9tIHRoZSByZW1vdGUgcHJvY2VkdXJlICovCiAgICBMT05HX1BUUiBSZXRWYWwgPSAwOwogICAgLyogdGhlIHBvaW50ZXIgdG8gdGhlIG9iamVjdCB3aGVuIGluIE9MRSBtb2RlICovCiAgICB2b2lkICogVGhpcyA9IE5VTEw7CgogICAgVFJBQ0UoInBTdHViRGVzYyAlcCwgcEZvcm1hdCAlcCwgLi4uXG4iLCBwU3R1YkRlc2MsIHBGb3JtYXQpOwogICAgVFJBQ0UoIiZmaXJzdF9hcmd1bWVudCA9ICVwIC0+ICVwXG4iLCBhcmdzLCBBUkdfRlJPTV9PRkZTRVQoYXJncywgMCkpOwoKICAgIC8qIExhdGVyIE5EUiBsYW5ndWFnZSB2ZXJzaW9ucyBwcm9iYWJseSB3b24ndCBiZSBiYWNrd2FyZHMgY29tcGF0aWJsZSAqLwogICAgaWYgKHBTdHViRGVzYy0+VmVyc2lvbiA+IDB4NTAwMDIpCiAgICB7CiAgICAgICAgRklYTUUoIkluY29tcGF0aWJsZSBzdHViIGRlc2NyaXB0aW9uIHZlcnNpb246IDB4JWx4XG4iLCBwU3R1YkRlc2MtPlZlcnNpb24pOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX1dST05HX1NUVUJfVkVSU0lPTik7CiAgICB9CgogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9SUENGTEFHUykKICAgIHsKICAgICAgICBORFJfUFJPQ19IRUFERVJfUlBDICogcFByb2NIZWFkZXIgPSAoTkRSX1BST0NfSEVBREVSX1JQQyAqKSZwRm9ybWF0WzBdOwogICAgICAgIHN0YWNrX3NpemUgPSBwUHJvY0hlYWRlci0+c3RhY2tfc2l6ZTsKICAgICAgICBwcm9jZWR1cmVfbnVtYmVyID0gcFByb2NIZWFkZXItPnByb2NfbnVtOwogICAgICAgIGN1cnJlbnRfb2Zmc2V0ID0gc2l6ZW9mKE5EUl9QUk9DX0hFQURFUl9SUEMpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHN0YWNrX3NpemUgPSBwUHJvY0hlYWRlci0+c3RhY2tfc2l6ZTsKICAgICAgICBwcm9jZWR1cmVfbnVtYmVyID0gcFByb2NIZWFkZXItPnByb2NfbnVtOwogICAgICAgIFRSQUNFKCJwcm9jIG51bTogJWRcbiIsIHByb2NlZHVyZV9udW1iZXIpOwogICAgICAgIGN1cnJlbnRfb2Zmc2V0ID0gc2l6ZW9mKE5EUl9QUk9DX0hFQURFUik7CiAgICB9CgogICAgVFJBQ0UoIk9pX2ZsYWdzID0gMHglMDJ4XG4iLCBwUHJvY0hlYWRlci0+T2lfZmxhZ3MpOwogICAgVFJBQ0UoIk1JREwgc3R1YiB2ZXJzaW9uID0gMHglbHhcbiIsIHBTdHViRGVzYy0+TUlETFZlcnNpb24pOwoKICAgIC8qIHdlIG9ubHkgbmVlZCBhIGhhbmRsZSBpZiB0aGlzIGlzbid0IGFuIG9iamVjdCBtZXRob2QgKi8KICAgIGlmICghKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9PQkpFQ1QpKQogICAgewogICAgICAgIC8qIGJpbmRpbmcgKi8KICAgICAgICBzd2l0Y2ggKHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSkKICAgICAgICB7CiAgICAgICAgLyogZXhwbGljaXQgYmluZGluZzogcGFyc2UgYWRkaXRpb25hbCBzZWN0aW9uICovCiAgICAgICAgY2FzZSBSUENfRkNfQklORF9FWFBMSUNJVDoKICAgICAgICAgICAgc3dpdGNoIChwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XSkgLyogaGFuZGxlX3R5cGUgKi8KICAgICAgICAgICAgewogICAgICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX1BSSU1JVElWRTogLyogZXhwbGljaXQgcHJpbWl0aXZlICovCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTkRSX0VIRF9QUklNSVRJVkUgKiBwRGVzYyA9IChORFJfRUhEX1BSSU1JVElWRSAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkV4cGxpY2l0IHByaW1pdGl2ZSBoYW5kbGUgQCAlZFxuIiwgcERlc2MtPm9mZnNldCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChwRGVzYy0+ZmxhZykgLyogcG9pbnRlciB0byBiaW5kaW5nICovCiAgICAgICAgICAgICAgICAgICAgICAgIGhCaW5kaW5nID0gKiooaGFuZGxlX3QgKiopQVJHX0ZST01fT0ZGU0VUKGFyZ3MsIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgaEJpbmRpbmcgPSAqKGhhbmRsZV90ICopQVJHX0ZST01fT0ZGU0VUKGFyZ3MsIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfRUhEX1BSSU1JVElWRSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfR0VORVJJQzogLyogZXhwbGljaXQgZ2VuZXJpYyAqLwogICAgICAgICAgICAgICAgRklYTUUoIlJQQ19GQ19CSU5EX0dFTkVSSUNcbiIpOwogICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfV1JPTkdfU1RVQl9WRVJTSU9OKTsgLyogRklYTUU6IHJlbW92ZSB3aGVuIGltcGxlbWVudGVkICovCiAgICAgICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX0VIRF9HRU5FUklDKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX0NPTlRFWFQ6IC8qIGV4cGxpY2l0IGNvbnRleHQgKi8KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBORFJfRUhEX0NPTlRFWFQgKiBwRGVzYyA9IChORFJfRUhEX0NPTlRFWFQgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkV4cGxpY2l0IGJpbmQgY29udGV4dFxuIik7CiAgICAgICAgICAgICAgICAgICAgaEJpbmRpbmcgPSBORFJDQ29udGV4dEJpbmRpbmcoKihORFJfQ0NPTlRFWFQgKilBUkdfRlJPTV9PRkZTRVQoYXJncywgcERlc2MtPm9mZnNldCkpOwogICAgICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBzaG91bGQgd2Ugc3RvcmUgdGhpcyBzdHJ1Y3R1cmUgaW4gc3R1Yk1zZy5wQ29udGV4dD8gKi8KICAgICAgICAgICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX0VIRF9DT05URVhUKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEVSUigiYmFkIGV4cGxpY2l0IGJpbmRpbmcgaGFuZGxlIHR5cGUgKDB4JTAyeClcbiIsIHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSk7CiAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX0dFTkVSSUM6IC8qIGltcGxpY2l0IGdlbmVyaWMgKi8KICAgICAgICAgICAgRklYTUUoIlJQQ19GQ19CSU5EX0dFTkVSSUNcbiIpOwogICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsgLyogRklYTUU6IHJlbW92ZSB3aGVuIGltcGxlbWVudGVkICovCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfUFJJTUlUSVZFOiAvKiBpbXBsaWNpdCBwcmltaXRpdmUgKi8KICAgICAgICAgICAgVFJBQ0UoIkltcGxpY2l0IHByaW1pdGl2ZSBoYW5kbGVcbiIpOwogICAgICAgICAgICBoQmluZGluZyA9ICpwU3R1YkRlc2MtPklNUExJQ0lUX0hBTkRMRV9JTkZPLnBQcmltaXRpdmVIYW5kbGU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUlBDX0ZDX0NBTExCQUNLX0hBTkRMRTogLyogaW1wbGljaXQgY2FsbGJhY2sgKi8KICAgICAgICAgICAgRklYTUUoIlJQQ19GQ19DQUxMQkFDS19IQU5ETEVcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJQQ19GQ19BVVRPX0hBTkRMRTogLyogaW1wbGljaXQgYXV0byBoYW5kbGUgKi8KICAgICAgICAgICAgLyogc3RyaWN0bHkgc3BlYWtpbmcsIGl0IGlzbid0IG5lY2Vzc2FyeSB0byBzZXQgaEJpbmRpbmcgaGVyZQogICAgICAgICAgICAqIHNpbmNlIGl0IGlzbid0IGFjdHVhbGx5IHVzZWQgKGhlbmNlIHRoZSBhdXRvbWF0aWMgaW4gaXRzIG5hbWUpLAogICAgICAgICAgICAqIGJ1dCB0aGVuIHdoeSBkb2VzIE1JREwgZ2VuZXJhdGUgYSB2YWxpZCBlbnRyeSBpbiB0aGUKICAgICAgICAgICAgKiBNSURMX1NUVUJfREVTQyBmb3IgaXQ/ICovCiAgICAgICAgICAgIFRSQUNFKCJJbXBsaWNpdCBhdXRvIGhhbmRsZVxuIik7CiAgICAgICAgICAgIGhCaW5kaW5nID0gKnBTdHViRGVzYy0+SU1QTElDSVRfSEFORExFX0lORk8ucEF1dG9IYW5kbGU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiYmFkIGltcGxpY2l0IGJpbmRpbmcgaGFuZGxlIHR5cGUgKDB4JTAyeClcbiIsIHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSk7CiAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgICAgIH0KICAgIH0KCiAgICBiVjJGb3JtYXQgPSAocFN0dWJEZXNjLT5WZXJzaW9uID49IDB4MjAwMDApOwoKICAgIGlmIChiVjJGb3JtYXQpCiAgICB7CiAgICAgICAgTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSICogcE9JRkhlYWRlciA9CiAgICAgICAgICAgIChORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgT2lmX2ZsYWdzID0gcE9JRkhlYWRlci0+T2kyRmxhZ3M7CiAgICAgICAgbnVtYmVyX29mX3BhcmFtcyA9IHBPSUZIZWFkZXItPm51bWJlcl9vZl9wYXJhbXM7CgogICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIpOwogICAgfQoKICAgIFRSQUNFKCJPaWZfZmxhZ3MgPSAiKTsgZHVtcF9JTlRFUlBSRVRFUl9PUFRfRkxBR1MoT2lmX2ZsYWdzKTsKCiAgICBpZiAoT2lmX2ZsYWdzLkhhc0V4dGVuc2lvbnMpCiAgICB7CiAgICAgICAgTkRSX1BST0NfSEVBREVSX0VYVFMgKiBwRXh0ZW5zaW9ucyA9CiAgICAgICAgICAgIChORFJfUFJPQ19IRUFERVJfRVhUUyAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKICAgICAgICBleHRfZmxhZ3MgPSBwRXh0ZW5zaW9ucy0+RmxhZ3MyOwogICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHBFeHRlbnNpb25zLT5TaXplOwogICAgfQoKICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgewogICAgICAgIC8qIG9iamVjdCBpcyBhbHdheXMgdGhlIGZpcnN0IGFyZ3VtZW50ICovCiAgICAgICAgVGhpcyA9ICoodm9pZCAqKilBUkdfRlJPTV9PRkZTRVQoYXJncywgMCk7CiAgICAgICAgTmRyUHJveHlJbml0aWFsaXplKFRoaXMsICZycGNNc2csICZzdHViTXNnLCBwU3R1YkRlc2MsIHByb2NlZHVyZV9udW1iZXIpOwogICAgfQogICAgZWxzZQogICAgICAgIE5kckNsaWVudEluaXRpYWxpemVOZXcoJnJwY01zZywgJnN0dWJNc2csIHBTdHViRGVzYywgcHJvY2VkdXJlX251bWJlcik7CgogICAgLyogY3JlYXRlIHRoZSBmdWxsIHBvaW50ZXIgdHJhbnNsYXRpb24gdGFibGVzLCBpZiByZXF1ZXN0ZWQgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfRlVMTFBUUikKI2lmIDAKICAgICAgICBzdHViTXNnLkZ1bGxQdHJYbGF0VGFibGVzID0gTmRyRnVsbFBvaW50ZXJYbGF0SW5pdCgwLFhMQVRfQ0xJRU5UKTsKI2Vsc2UKICAgICAgICBGSVhNRSgiaW5pdGlhbGl6ZSBmdWxsIHBvaW50ZXIgdHJhbnNsYXRpb24gdGFibGVzXG4iKTsKI2VuZGlmCgogICAgc3R1Yk1zZy5CdWZmZXJMZW5ndGggPSAwOwogICAgLyogbmVlZGVkIGZvciBjb25mb3JtYW5jZSBvZiB0b3AtbGV2ZWwgb2JqZWN0cyAqLwogICAgc3R1Yk1zZy5TdGFja1RvcCA9ICoodW5zaWduZWQgY2hhciAqKilhcmdzOwoKICAgIC8qIHN0b3JlIHRoZSBSUEMgZmxhZ3MgYXdheSAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9SUENGTEFHUykKICAgICAgICBycGNNc2cuUnBjRmxhZ3MgPSAoKE5EUl9QUk9DX0hFQURFUl9SUEMgKilwUHJvY0hlYWRlciktPnJwY19mbGFnczsKCiAgICAvKiB1c2UgYWx0ZXJuYXRlIG1lbW9yeSBhbGxvY2F0aW9uIHJvdXRpbmVzICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX1JQQ1NTQUxMT0MpCiAgICAgICAgTmRyUnBjU21TZXRDbGllbnRUb09zZigmc3R1Yk1zZyk7CgogICAgaWYgKE9pZl9mbGFncy5IYXNQaXBlcykKICAgIHsKICAgICAgICBGSVhNRSgicGlwZXMgbm90IHN1cHBvcnRlZCB5ZXRcbiIpOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX1dST05HX1NUVUJfVkVSU0lPTik7IC8qIEZJWE1FOiByZW1vdmUgd2hlbiBpbXBsZW1lbnRlZCAqLwogICAgICAgIC8qIGluaXQgcGlwZXMgcGFja2FnZSAqLwogICAgICAgIC8qIE5kclBpcGVzSW5pdGlhbGl6ZSguLi4pICovCiAgICB9CiAgICBpZiAoZXh0X2ZsYWdzLkhhc05ld0NvcnJEZXNjKQogICAgewogICAgICAgIC8qIGluaXRpYWxpemUgZXh0cmEgY29ycmVsYXRpb24gcGFja2FnZSAqLwogICAgICAgIEZJWE1FKCJuZXcgY29ycmVsYXRpb24gZGVzY3JpcHRpb24gbm90IGltcGxlbWVudGVkXG4iKTsKICAgICAgICBzdHViTXNnLmZIYXNOZXdDb3JyRGVzYyA9IFRSVUU7CiAgICB9CgogICAgcGFyYW1ldGVyX3N0YXJ0X29mZnNldCA9IGN1cnJlbnRfb2Zmc2V0OwoKICAgIC8qIG9yZGVyIG9mIHBoYXNlczoKICAgICAqIDEuIFBST1hZX0NBTENTSVpFIC0gY2FsY3VsYXRlIHRoZSBidWZmZXIgc2l6ZQogICAgICogMi4gUFJPWFlfR0VUQlVGRkVSIC0gYWxsb2NhdGUgdGhlIGJ1ZmZlcgogICAgICogMy4gUFJPWFlfTUFSSFNBTCAtIG1hcnNoYWwgW2luXSBwYXJhbXMgaW50byB0aGUgYnVmZmVyCiAgICAgKiA0LiBQUk9YWV9TRU5EUkVDRUlWRSAtIHNlbmQvcmVjZWl2ZSBidWZmZXIKICAgICAqIDUuIFBST1hZX1VOTUFSSFNBTCAtIHVubWFyc2hhbCBbb3V0XSBwYXJhbXMgZnJvbSBidWZmZXIKICAgICAqLwogICAgZm9yIChwaGFzZSA9IFBST1hZX0NBTENTSVpFOyBwaGFzZSA8PSBQUk9YWV9VTk1BUlNIQUw7IHBoYXNlKyspCiAgICB7CiAgICAgICAgVFJBQ0UoInBoYXNlID0gJWRcbiIsIHBoYXNlKTsKICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgIHsKICAgICAgICBjYXNlIFBST1hZX0dFVEJVRkZFUjoKICAgICAgICAgICAgLyogYWxsb2NhdGUgdGhlIGJ1ZmZlciAqLwogICAgICAgICAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX09CSkVDVCkKICAgICAgICAgICAgICAgIE5kclByb3h5R2V0QnVmZmVyKFRoaXMsICZzdHViTXNnKTsKICAgICAgICAgICAgZWxzZSBpZiAoT2lmX2ZsYWdzLkhhc1BpcGVzKQogICAgICAgICAgICAgICAgLyogTmRyR2V0UGlwZUJ1ZmZlciguLi4pICovCiAgICAgICAgICAgICAgICBGSVhNRSgicGlwZXMgbm90IHN1cHBvcnRlZCB5ZXRcbiIpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUgPT0gUlBDX0ZDX0FVVE9fSEFORExFKQojaWYgMAogICAgICAgICAgICAgICAgICAgIE5kck5zR2V0QnVmZmVyKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlckxlbmd0aCwgaEJpbmRpbmcpOwojZWxzZQogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJ1c2luZyBhdXRvIGhhbmRsZSAtIGNhbGwgTmRyTnNHZXRCdWZmZXIgd2hlbiBpdCBnZXRzIGltcGxlbWVudGVkXG4iKTsKI2VuZGlmCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgTmRyR2V0QnVmZmVyKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlckxlbmd0aCwgaEJpbmRpbmcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUFJPWFlfU0VORFJFQ0VJVkU6CiAgICAgICAgICAgIC8qIHNlbmQgdGhlIFtpbl0gcGFyYW1zIGFuZCByZWNlaXZlIHRoZSBbb3V0XSBhbmQgW3JldHZhbF0KICAgICAgICAgICAgICogcGFyYW1zICovCiAgICAgICAgICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgICAgICAgICAgICAgTmRyUHJveHlTZW5kUmVjZWl2ZShUaGlzLCAmc3R1Yk1zZyk7CiAgICAgICAgICAgIGVsc2UgaWYgKE9pZl9mbGFncy5IYXNQaXBlcykKICAgICAgICAgICAgICAgIC8qIE5kclBpcGVzU2VuZFJlY2VpdmUoLi4uKSAqLwogICAgICAgICAgICAgICAgRklYTUUoInBpcGVzIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocFByb2NIZWFkZXItPmhhbmRsZV90eXBlID09IFJQQ19GQ19BVVRPX0hBTkRMRSkKI2lmIDAKICAgICAgICAgICAgICAgICAgICBOZHJOc1NlbmRSZWNlaXZlKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlciwgcFN0dWJEZXNjLT5JTVBMSUNJVF9IQU5ETEVfSU5GTy5wQXV0b0hhbmRsZSk7CiNlbHNlCiAgICAgICAgICAgICAgICAgICAgRklYTUUoInVzaW5nIGF1dG8gaGFuZGxlIC0gY2FsbCBOZHJOc1NlbmRSZWNlaXZlIHdoZW4gaXQgZ2V0cyBpbXBsZW1lbnRlZFxuIik7CiNlbmRpZgogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIE5kclNlbmRSZWNlaXZlKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlcik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGNvbnZlcnQgc3RyaW5ncywgZmxvYXRpbmcgcG9pbnQgdmFsdWVzIGFuZCBlbmRpYW5lc3MgaW50byBvdXIKICAgICAgICAgICAgICogcHJlZmVycmVkIGZvcm1hdCAqLwogICAgICAgICAgICBpZiAoKHJwY01zZy5EYXRhUmVwcmVzZW50YXRpb24gJiAweDAwMDBGRkZGVUwpICE9IE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OKQogICAgICAgICAgICAgICAgTmRyQ29udmVydCgmc3R1Yk1zZywgcEZvcm1hdCk7CgogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFBST1hZX0NBTENTSVpFOgogICAgICAgIGNhc2UgUFJPWFlfTUFSU0hBTDoKICAgICAgICBjYXNlIFBST1hZX1VOTUFSU0hBTDoKICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgPSBwYXJhbWV0ZXJfc3RhcnRfb2Zmc2V0OwogICAgICAgICAgICBjdXJyZW50X3N0YWNrX29mZnNldCA9IDA7CgogICAgICAgICAgICAvKiBOT1RFOiBWMSBzdHlsZSBmb3JtYXQgZG9lcyd0IHRlcm1pbmF0ZSBvbiB0aGUgbnVtYmVyX29mX3BhcmFtcwogICAgICAgICAgICAgKiBjb25kaXRpb24gYXMgaXQgZG9lc24ndCBoYXZlIHRoaXMgYXR0cmlidXRlLiBJbnN0ZWFkIGl0CiAgICAgICAgICAgICAqIHRlcm1pbmF0ZXMgd2hlbiB0aGUgc3RhY2sgc2l6ZSBnaXZlbiBpbiB0aGUgaGVhZGVyIGlzIGV4Y2VlZGVkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG51bWJlcl9vZl9wYXJhbXM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGJWMkZvcm1hdCkgLyogbmV3IHBhcmFtZXRlciBmb3JtYXQgKi8KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBORFJfUEFSQU1fT0lGX0JBU0VUWVBFICogcFBhcmFtID0KICAgICAgICAgICAgICAgICAgICAgICAgKE5EUl9QQVJBTV9PSUZfQkFTRVRZUEUgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CiAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqIHBBcmc7CgogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfc3RhY2tfb2Zmc2V0ID0gcFBhcmFtLT5zdGFja19vZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgcEFyZyA9IEFSR19GUk9NX09GRlNFVChhcmdzLCBjdXJyZW50X3N0YWNrX29mZnNldCk7CgogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJwYXJhbVslZF06IG5ldyBmb3JtYXRcbiIsIGkpOwogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdHBhcmFtX2F0dHJpYnV0ZXM6Iik7IGR1bXBfUlBDX0ZDX1BST0NfUEYocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzKTsgVFJBQ0UoIlxuIik7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0c3RhY2tfb2Zmc2V0OiAweCV4XG4iLCBjdXJyZW50X3N0YWNrX29mZnNldCk7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0bWVtb3J5IGFkZHIgKGJlZm9yZSk6ICVwXG4iLCBwQXJnKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0Jhc2V0eXBlKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqIHBUeXBlRm9ybWF0ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwUGFyYW0tPnR5cGVfZm9ybWF0X2NoYXI7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzU2ltcGxlUmVmKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcEFyZyA9ICoodW5zaWduZWQgY2hhciAqKilwQXJnOwoKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0YmFzZSB0eXBlOiAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUFJPWFlfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9idWZmZXJfc2l6ZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFBST1hZX01BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9tYXJzaGFsbGVyKCZzdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQUk9YWV9VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzT3V0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnBSZXRWYWwgPSAodW5zaWduZWQgY2hhciAqKSZSZXRWYWw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIoJnN0dWJNc2csICZwUmV0VmFsLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcigmc3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgicFJldFZhbCA9ICVwXG4iLCBwUmV0VmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1NfSU5URVJOQUxfRVJST1IpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BBUkFNX09JRl9CQVNFVFlQRSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIE5EUl9QQVJBTV9PSUZfT1RIRVIgKiBwUGFyYW1PdGhlciA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTkRSX1BBUkFNX09JRl9PVEhFUiAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKiBwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKHBTdHViRGVzYy0+cEZvcm1hdFR5cGVzW3BQYXJhbU90aGVyLT50eXBlX29mZnNldF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgLyogaWYgYSBzaW1wbGUgcmVmIHBvaW50ZXIgdGhlbiB3ZSBoYXZlIHRvIGRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgKiBjaGVjayBmb3IgdGhlIHBvaW50ZXIgYmVpbmcgbm9uLU5VTEwuICovCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNTaW1wbGVSZWYpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKih1bnNpZ25lZCBjaGFyICoqKXBBcmcpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfTlVMTF9SRUZfUE9JTlRFUik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdGNvbXBsZXggdHlwZTogMHglMDJ4XG4iLCAqcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFBST1hZX0NBTENTSVpFOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0luKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNCeVZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9idWZmZXJfc2l6ZXIoJnN0dWJNc2csICoodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQUk9YWV9NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0luKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNCeVZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFBST1hZX1VOTUFSU0hBTDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNPdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqcFJldFZhbCA9ICh1bnNpZ25lZCBjaGFyICopJlJldFZhbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzUmV0dXJuKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcigmc3R1Yk1zZywgJnBSZXRWYWwsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNCeVZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcigmc3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSUZfT1RIRVIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRtZW1vcnkgYWRkciAoYWZ0ZXIpOiAlcFxuIiwgcEFyZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIC8qIG9sZCBwYXJhbWV0ZXIgZm9ybWF0ICovCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTkRSX1BBUkFNX09JX0JBU0VUWVBFICogcFBhcmFtID0KICAgICAgICAgICAgICAgICAgICAgICAgKE5EUl9QQVJBTV9PSV9CQVNFVFlQRSAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICogcEFyZyA9IEFSR19GUk9NX09GRlNFVChhcmdzLCBjdXJyZW50X3N0YWNrX29mZnNldCk7CgogICAgICAgICAgICAgICAgICAgIC8qIG5vIG1vcmUgcGFyYW1ldGVyczsgZXhpdCBsb29wICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRfc3RhY2tfb2Zmc2V0ID4gc3RhY2tfc2l6ZSkKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJwYXJhbVslZF06IG9sZCBmb3JtYXRcbiIsIGkpOwogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdHBhcmFtX2RpcmVjdGlvbjogJXhcbiIsIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uKTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRzdGFja19vZmZzZXQ6IDB4JXhcbiIsIGN1cnJlbnRfc3RhY2tfb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRtZW1vcnkgYWRkciAoYmVmb3JlKTogJXBcbiIsIHBBcmcpOwoKICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX1BBUkFNX0JBU0VUWVBFIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU1fQkFTRVRZUEUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyICogcFR5cGVGb3JtYXQgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBQYXJhbS0+dHlwZV9mb3JtYXRfY2hhcjsKCiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdGJhc2UgdHlwZSAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUFJPWFlfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKCZzdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQUk9YWV9NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFBST1hZX1VOTUFSU0hBTDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiAmIFJQQ19GQ19SRVRVUk5fUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAodW5zaWduZWQgY2hhciAqKikmUmV0VmFsLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcigmc3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1NfSU5URVJOQUxfRVJST1IpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X3N0YWNrX29mZnNldCArPSBjYWxsX21lbW9yeV9zaXplcigmc3R1Yk1zZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BBUkFNX09JX0JBU0VUWVBFKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgTkRSX1BBUkFNX09JX09USEVSICogcFBhcmFtT3RoZXIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChORFJfUEFSQU1fT0lfT1RIRVIgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CgogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyICpwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFN0dWJEZXNjLT5wRm9ybWF0VHlwZXNbcFBhcmFtT3RoZXItPnR5cGVfb2Zmc2V0XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdGNvbXBsZXggdHlwZSAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUFJPWFlfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gJiBSUENfRkNfSU5fT1VUX1BBUkFNKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKCZzdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQUk9YWV9NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uICYgUlBDX0ZDX0lOX09VVF9QQVJBTSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFBST1hZX1VOTUFSU0hBTDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fT1VUX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX09VVF9QQVJBTSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIoJnN0dWJNc2csICZwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAodW5zaWduZWQgY2hhciAqKikmUmV0VmFsLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9zdGFja19vZmZzZXQgKz0gcFBhcmFtT3RoZXItPnN0YWNrX3NpemUgKiBzaXplb2YoSU5UKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSV9PVEhFUik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdG1lbW9yeSBhZGRyIChhZnRlcik6ICVwXG4iLCBwQXJnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJzaG91bGRuJ3QgcmVhY2ggaGVyZS4gcGhhc2UgJWRcbiIsIHBoYXNlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIC8qIEZJWE1FOiB1bmJpbmQgdGhlIGJpbmRpbmcgaGFuZGxlICovCgogICAgaWYgKGV4dF9mbGFncy5IYXNOZXdDb3JyRGVzYykKICAgIHsKICAgICAgICAvKiBmcmVlIGV4dHJhIGNvcnJlbGF0aW9uIHBhY2thZ2UgKi8KICAgICAgICAvKiBOZHJDb3JyZWxhdGlvbkZyZWUoJnN0dWJNc2cpOyAqLwogICAgfQoKICAgIGlmIChPaWZfZmxhZ3MuSGFzUGlwZXMpCiAgICB7CiAgICAgICAgLyogTmRyUGlwZXNEb25lKC4uLikgKi8KICAgIH0KCiNpZiAwCiAgICAvKiBmcmVlIHRoZSBmdWxsIHBvaW50ZXIgdHJhbnNsYXRpb24gdGFibGVzICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX0ZVTExQVFIpCiAgICAgICAgTmRyRnVsbFBvaW50ZXJYbGF0RnJlZShzdHViTXNnLkZ1bGxQdHJYbGF0VGFibGVzKTsKI2VuZGlmCgogICAgLyogZnJlZSBtYXJzaGFsbGluZyBidWZmZXIgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgICAgIE5kclByb3h5RnJlZUJ1ZmZlcihUaGlzLCAmc3R1Yk1zZyk7CiAgICBlbHNlCiAgICAgICAgTmRyRnJlZUJ1ZmZlcigmc3R1Yk1zZyk7CgogICAgVFJBQ0UoIlJldFZhbCA9IDB4JWx4XG4iLCBSZXRWYWwpOwoKICAgIHJldHVybiBSZXRWYWw7Cn0KCi8qIGNhbGxzIGEgZnVuY3Rpb24gd2l0aCB0aGUgc3BlY2lmaWNlZCBhcmd1bWVudHMsIHJlc3RvcmluZyB0aGUgc3RhY2sKICogcHJvcGVybHkgYWZ0ZXJ3YXJkcyBhcyB3ZSBkb24ndCBrbm93IHRoZSBjYWxsaW5nIGNvbnZlbnRpb24gb2YgdGhlCiAqIGZ1bmN0aW9uICovCiNpZiBkZWZpbmVkIF9faTM4Nl9fICYmIGRlZmluZWQgX01TQ19WRVIKX19kZWNsc3BlYyhuYWtlZCkgTE9OR19QVFIgX19jZGVjbCBjYWxsX3NlcnZlcl9mdW5jKFNFUlZFUl9ST1VUSU5FIGZ1bmMsIHVuc2lnbmVkIGNoYXIgKiBhcmdzLCB1bnNpZ25lZCBpbnQgc3RhY2tfc2l6ZSkKewogICAgX19hc20KICAgIHsKICAgICAgICBwdXNoIGVicAogICAgICAgIHB1c2ggZWRpICAgICAgICAgICAgOyBTYXZlIHJlZ2lzdGVycwogICAgICAgIHB1c2ggZXNpCiAgICAgICAgbW92IGVicCwgZXNwCiAgICAgICAgbW92IGVheCwgW2VicCsxNl0gICA7IEdldCBzdGFjayBzaXplCiAgICAgICAgc3ViIGVzcCwgZWF4ICAgICAgICA7IE1ha2Ugcm9vbSBpbiBzdGFjayBmb3IgYXJndW1lbnRzCiAgICAgICAgbW92IGVkaSwgZXNwCiAgICAgICAgbW92IGVjeCwgZWF4CiAgICAgICAgbW92IGVzaSwgW2VicCsxMl0KICAgICAgICBzaHIgZWN4LCAyCiAgICAgICAgY2xkCiAgICAgICAgcmVwIG1vdnNkICAgICAgICAgICA7IENvcHkgZHdvcmQgYmxvY2tzCiAgICAgICAgY2FsbCBbZWJwKzhdICAgICAgICA7IENhbGwgZnVuY3Rpb24KICAgICAgICBsZWEgZXNwLCBbZWJwLThdICAgIDsgUmVzdG9yZSBzdGFjawogICAgICAgIHBvcCBlc2kgICAgICAgICAgICAgOyBSZXN0b3JlIHJlZ2lzdGVycwogICAgICAgIHBvcCBlZGkKICAgICAgICBwb3AgZWJwCiAgICAgICAgcmV0CiAgICB9Cn0KI2VsaWYgZGVmaW5lZCBfX2kzODZfXyAmJiBkZWZpbmVkIF9fR05VQ19fCkxPTkdfUFRSIF9fY2RlY2wgY2FsbF9zZXJ2ZXJfZnVuYyhTRVJWRVJfUk9VVElORSBmdW5jLCB1bnNpZ25lZCBjaGFyICogYXJncywgdW5zaWduZWQgaW50IHN0YWNrX3NpemUpOwpfX0FTTV9HTE9CQUxfRlVOQyhjYWxsX3NlcnZlcl9mdW5jLAogICAgInB1c2hsICVlYnBcblx0IgogICAgIm1vdmwgJWVzcCwgJWVicFxuXHQiCiAgICAicHVzaGwgJWVkaVxuXHQiICAgICAgICAgICAgLyogU2F2ZSByZWdpc3RlcnMgKi8KICAgICJwdXNobCAlZXNpXG5cdCIKICAgICJtb3ZsIDE2KCVlYnApLCAlZWF4XG5cdCIgICAvKiBHZXQgc3RhY2sgc2l6ZSAqLwogICAgInN1YmwgJWVheCwgJWVzcFxuXHQiICAgICAgIC8qIE1ha2Ugcm9vbSBpbiBzdGFjayBmb3IgYXJndW1lbnRzICovCiAgICAiYW5kbCAkfjE1LCAlZXNwXG5cdCIJLyogTWFrZSBzdXJlIHN0YWNrIGhhcyAxNi1ieXRlIGFsaWdubWVudCBmb3IgTWFjT1MgWCAqLwogICAgIm1vdmwgJWVzcCwgJWVkaVxuXHQiCiAgICAibW92bCAlZWF4LCAlZWN4XG5cdCIKICAgICJtb3ZsIDEyKCVlYnApLCAlZXNpXG5cdCIKICAgICJzaHJsICQyLCAlZWN4XG5cdCIgICAgICAgICAvKiBkaXZpZGUgYnkgNCAqLwogICAgImNsZFxuXHQiCiAgICAicmVwOyBtb3ZzbFxuXHQiICAgICAgICAgICAgLyogQ29weSBkd29yZCBibG9ja3MgKi8KICAgICJjYWxsICo4KCVlYnApXG5cdCIgICAgICAgICAvKiBDYWxsIGZ1bmN0aW9uICovCiAgICAibGVhbCAtOCglZWJwKSwgJWVzcFxuXHQiICAgLyogUmVzdG9yZSBzdGFjayAqLwogICAgInBvcGwgJWVzaVxuXHQiICAgICAgICAgICAgIC8qIFJlc3RvcmUgcmVnaXN0ZXJzICovCiAgICAicG9wbCAlZWRpXG5cdCIKICAgICJwb3BsICVlYnBcblx0IgogICAgInJldFxuIiApOwojZWxzZQojd2FybmluZyBjYWxsX3NlcnZlcl9mdW5jIG5vdCBpbXBsZW1lbnRlZCBmb3IgeW91ciBhcmNoaXRlY3R1cmUKTE9OR19QVFIgX19jZGVjbCBjYWxsX3NlcnZlcl9mdW5jKFNFUlZFUl9ST1VUSU5FIGZ1bmMsIHVuc2lnbmVkIGNoYXIgKiBhcmdzLCB1bnNpZ25lZCBzaG9ydCBzdGFja19zaXplKQp7CiAgICBGSVhNRSgiTm90IGltcGxlbWVudGVkIGZvciB5b3VyIGFyY2hpdGVjdHVyZVxuIik7CiAgICByZXR1cm4gMDsKfQojZW5kaWYKCi8qIEZJWE1FOiBuZWVkIHRvIGZyZWUgc29tZSBzdHVmZiBpbiBoZXJlIHRvbyAqLwpsb25nIFdJTkFQSSBOZHJTdHViQ2FsbDIoCiAgICBzdHJ1Y3QgSVJwY1N0dWJCdWZmZXIgKiBwVGhpcywKICAgIHN0cnVjdCBJUnBjQ2hhbm5lbEJ1ZmZlciAqIHBDaGFubmVsLAogICAgUFJQQ19NRVNTQUdFIHBScGNNc2csCiAgICB1bnNpZ25lZCBsb25nICogcGR3U3R1YlBoYXNlKQp7CiAgICBjb25zdCBNSURMX1NFUlZFUl9JTkZPICpwU2VydmVySW5mbzsKICAgIGNvbnN0IE1JRExfU1RVQl9ERVNDICpwU3R1YkRlc2M7CiAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0OwogICAgTUlETF9TVFVCX01FU1NBR0Ugc3R1Yk1zZzsKICAgIC8qIHBvaW50ZXIgdG8gc3RhcnQgb2Ygc3RhY2sgdG8gcGFzcyBpbnRvIHN0dWIgaW1wbGVtZW50YXRpb24gKi8KICAgIHVuc2lnbmVkIGNoYXIgKiBhcmdzOwogICAgLyogc2l6ZSBvZiBzdGFjayAqLwogICAgdW5zaWduZWQgc2hvcnQgc3RhY2tfc2l6ZTsKICAgIC8qIGN1cnJlbnQgc3RhY2sgb2Zmc2V0ICovCiAgICB1bnNpZ25lZCBzaG9ydCBjdXJyZW50X3N0YWNrX29mZnNldDsKICAgIC8qIG51bWJlciBvZiBwYXJhbWV0ZXJzLiBvcHRpb25hbCBmb3IgY2xpZW50IHRvIGdpdmUgaXQgdG8gdXMgKi8KICAgIHVuc2lnbmVkIGNoYXIgbnVtYmVyX29mX3BhcmFtcyA9IH4wOwogICAgLyogY291bnRlciAqLwogICAgdW5zaWduZWQgc2hvcnQgaTsKICAgIC8qIGNhY2hlIG9mIE9pZl9mbGFncyBmcm9tIHYyIHByb2NlZHVyZSBoZWFkZXIgKi8KICAgIElOVEVSUFJFVEVSX09QVF9GTEFHUyBPaWZfZmxhZ3MgPSB7IDAgfTsKICAgIC8qIGNhY2hlIG9mIGV4dGVuc2lvbiBmbGFncyBmcm9tIE5EUl9QUk9DX0hFQURFUl9FWFRTICovCiAgICBJTlRFUlBSRVRFUl9PUFRfRkxBR1MyIGV4dF9mbGFncyA9IHsgMCB9OwogICAgLyogdGhlIHR5cGUgb2YgcGFzcyB3ZSBhcmUgY3VycmVudGx5IGRvaW5nICovCiAgICBpbnQgcGhhc2U7CiAgICAvKiBoZWFkZXIgZm9yIHByb2NlZHVyZSBzdHJpbmcgKi8KICAgIGNvbnN0IE5EUl9QUk9DX0hFQURFUiAqcFByb2NIZWFkZXI7CiAgICAvKiBvZmZzZXQgaW4gZm9ybWF0IHN0cmluZyBmb3Igc3RhcnQgb2YgcGFyYW1zICovCiAgICBpbnQgcGFyYW1ldGVyX3N0YXJ0X29mZnNldDsKICAgIC8qIGN1cnJlbnQgZm9ybWF0IHN0cmluZyBvZmZzZXQgKi8KICAgIGludCBjdXJyZW50X29mZnNldDsKICAgIC8qIC1PaWYgb3IgLU9pY2YgZ2VuZXJhdGVkIGZvcm1hdCAqLwogICAgQk9PTCBiVjJGb3JtYXQgPSBGQUxTRTsKICAgIC8qIGxvY2F0aW9uIHRvIHB1dCByZXR2YWwgaW50byAqLwogICAgTE9OR19QVFIgKnJldHZhbF9wdHIgPSBOVUxMOwoKICAgIFRSQUNFKCJwVGhpcyAlcCwgcENoYW5uZWwgJXAsIHBScGNNc2cgJXAsIHBkd1N0dWJQaGFzZSAlcFxuIiwgcFRoaXMsIHBDaGFubmVsLCBwUnBjTXNnLCBwZHdTdHViUGhhc2UpOwoKICAgIGlmIChwVGhpcykKICAgICAgICBwU2VydmVySW5mbyA9IENTdGRTdHViQnVmZmVyX0dldFNlcnZlckluZm8ocFRoaXMpOwogICAgZWxzZQogICAgICAgIHBTZXJ2ZXJJbmZvID0gKChSUENfU0VSVkVSX0lOVEVSRkFDRSAqKXBScGNNc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uKS0+SW50ZXJwcmV0ZXJJbmZvOwoKICAgIHBTdHViRGVzYyA9IHBTZXJ2ZXJJbmZvLT5wU3R1YkRlc2M7CiAgICBwRm9ybWF0ID0gcFNlcnZlckluZm8tPlByb2NTdHJpbmcgKyBwU2VydmVySW5mby0+Rm10U3RyaW5nT2Zmc2V0W3BScGNNc2ctPlByb2NOdW1dOwogICAgcFByb2NIZWFkZXIgPSAoY29uc3QgTkRSX1BST0NfSEVBREVSICopJnBGb3JtYXRbMF07CgogICAgLyogTGF0ZXIgTkRSIGxhbmd1YWdlIHZlcnNpb25zIHByb2JhYmx5IHdvbid0IGJlIGJhY2t3YXJkcyBjb21wYXRpYmxlICovCiAgICBpZiAocFN0dWJEZXNjLT5WZXJzaW9uID4gMHg1MDAwMikKICAgIHsKICAgICAgICBGSVhNRSgiSW5jb21wYXRpYmxlIHN0dWIgZGVzY3JpcHRpb24gdmVyc2lvbjogMHglbHhcbiIsIHBTdHViRGVzYy0+VmVyc2lvbik7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfV1JPTkdfU1RVQl9WRVJTSU9OKTsKICAgIH0KCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX1JQQ0ZMQUdTKQogICAgewogICAgICAgIE5EUl9QUk9DX0hFQURFUl9SUEMgKiBwUHJvY0hlYWRlciA9IChORFJfUFJPQ19IRUFERVJfUlBDICopJnBGb3JtYXRbMF07CiAgICAgICAgc3RhY2tfc2l6ZSA9IHBQcm9jSGVhZGVyLT5zdGFja19zaXplOwogICAgICAgIGN1cnJlbnRfb2Zmc2V0ID0gc2l6ZW9mKE5EUl9QUk9DX0hFQURFUl9SUEMpOwoKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzdGFja19zaXplID0gcFByb2NIZWFkZXItPnN0YWNrX3NpemU7CiAgICAgICAgY3VycmVudF9vZmZzZXQgPSBzaXplb2YoTkRSX1BST0NfSEVBREVSKTsKICAgIH0KCiAgICBUUkFDRSgiT2lfZmxhZ3MgPSAweCUwMnhcbiIsIHBQcm9jSGVhZGVyLT5PaV9mbGFncyk7CgogICAgLyogYmluZGluZyAqLwogICAgc3dpdGNoIChwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUpCiAgICB7CiAgICAvKiBleHBsaWNpdCBiaW5kaW5nOiBwYXJzZSBhZGRpdGlvbmFsIHNlY3Rpb24gKi8KICAgIGNhc2UgUlBDX0ZDX0JJTkRfRVhQTElDSVQ6CiAgICAgICAgc3dpdGNoIChwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XSkgLyogaGFuZGxlX3R5cGUgKi8KICAgICAgICB7CiAgICAgICAgY2FzZSBSUENfRkNfQklORF9QUklNSVRJVkU6IC8qIGV4cGxpY2l0IHByaW1pdGl2ZSAqLwogICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX0VIRF9QUklNSVRJVkUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX0dFTkVSSUM6IC8qIGV4cGxpY2l0IGdlbmVyaWMgKi8KICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9FSERfR0VORVJJQyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfQ09OVEVYVDogLyogZXhwbGljaXQgY29udGV4dCAqLwogICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX0VIRF9DT05URVhUKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJiYWQgZXhwbGljaXQgYmluZGluZyBoYW5kbGUgdHlwZSAoMHglMDJ4KVxuIiwgcFByb2NIZWFkZXItPmhhbmRsZV90eXBlKTsKICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBSUENfRkNfQklORF9HRU5FUklDOiAvKiBpbXBsaWNpdCBnZW5lcmljICovCiAgICBjYXNlIFJQQ19GQ19CSU5EX1BSSU1JVElWRTogLyogaW1wbGljaXQgcHJpbWl0aXZlICovCiAgICBjYXNlIFJQQ19GQ19DQUxMQkFDS19IQU5ETEU6IC8qIGltcGxpY2l0IGNhbGxiYWNrICovCiAgICBjYXNlIFJQQ19GQ19BVVRPX0hBTkRMRTogLyogaW1wbGljaXQgYXV0byBoYW5kbGUgKi8KICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgRVJSKCJiYWQgaW1wbGljaXQgYmluZGluZyBoYW5kbGUgdHlwZSAoMHglMDJ4KVxuIiwgcFByb2NIZWFkZXItPmhhbmRsZV90eXBlKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsKICAgIH0KCiAgICBiVjJGb3JtYXQgPSAocFN0dWJEZXNjLT5WZXJzaW9uID49IDB4MjAwMDApOwoKICAgIGlmIChiVjJGb3JtYXQpCiAgICB7CiAgICAgICAgTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSICogcE9JRkhlYWRlciA9CiAgICAgICAgICAgIChORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgT2lmX2ZsYWdzID0gcE9JRkhlYWRlci0+T2kyRmxhZ3M7CiAgICAgICAgbnVtYmVyX29mX3BhcmFtcyA9IHBPSUZIZWFkZXItPm51bWJlcl9vZl9wYXJhbXM7CgogICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIpOwogICAgfQoKICAgIFRSQUNFKCJPaWZfZmxhZ3MgPSAiKTsgZHVtcF9JTlRFUlBSRVRFUl9PUFRfRkxBR1MoT2lmX2ZsYWdzKTsKCiAgICBpZiAoT2lmX2ZsYWdzLkhhc0V4dGVuc2lvbnMpCiAgICB7CiAgICAgICAgTkRSX1BST0NfSEVBREVSX0VYVFMgKiBwRXh0ZW5zaW9ucyA9CiAgICAgICAgICAgIChORFJfUFJPQ19IRUFERVJfRVhUUyAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKICAgICAgICBleHRfZmxhZ3MgPSBwRXh0ZW5zaW9ucy0+RmxhZ3MyOwogICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHBFeHRlbnNpb25zLT5TaXplOwogICAgfQoKICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgICAgIE5kclN0dWJJbml0aWFsaXplKHBScGNNc2csICZzdHViTXNnLCBwU3R1YkRlc2MsIHBDaGFubmVsKTsKICAgIGVsc2UKICAgICAgICBOZHJTZXJ2ZXJJbml0aWFsaXplTmV3KHBScGNNc2csICZzdHViTXNnLCBwU3R1YkRlc2MpOwoKICAgIC8qIGNyZWF0ZSB0aGUgZnVsbCBwb2ludGVyIHRyYW5zbGF0aW9uIHRhYmxlcywgaWYgcmVxdWVzdGVkICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX0ZVTExQVFIpCiNpZiAwCiAgICAgICAgc3R1Yk1zZy5GdWxsUHRyWGxhdFRhYmxlcyA9IE5kckZ1bGxQb2ludGVyWGxhdEluaXQoMCxYTEFUX1NFUlZFUik7CiNlbHNlCiAgICAgICAgRklYTUUoImluaXRpYWxpemUgZnVsbCBwb2ludGVyIHRyYW5zbGF0aW9uIHRhYmxlc1xuIik7CiNlbmRpZgoKICAgIC8qIHN0b3JlIHRoZSBSUEMgZmxhZ3MgYXdheSAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9SUENGTEFHUykKICAgICAgICBwUnBjTXNnLT5ScGNGbGFncyA9ICgoTkRSX1BST0NfSEVBREVSX1JQQyAqKXBQcm9jSGVhZGVyKS0+cnBjX2ZsYWdzOwoKICAgIC8qIHVzZSBhbHRlcm5hdGUgbWVtb3J5IGFsbG9jYXRpb24gcm91dGluZXMgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfUlBDU1NBTExPQykKI2lmIDAKICAgICAgICAgIE5kclJwY1NzRW5hYmxlQWxsb2NhdGUoJnN0dWJNc2cpOwojZWxzZQogICAgICAgICAgRklYTUUoIlNldCBSUENTUyBtZW1vcnkgYWxsb2NhdGlvbiByb3V0aW5lc1xuIik7CiNlbmRpZgoKICAgIGlmIChPaWZfZmxhZ3MuSGFzUGlwZXMpCiAgICB7CiAgICAgICAgRklYTUUoInBpcGVzIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9XUk9OR19TVFVCX1ZFUlNJT04pOyAvKiBGSVhNRTogcmVtb3ZlIHdoZW4gaW1wbGVtZW50ZWQgKi8KICAgICAgICAvKiBpbml0IHBpcGVzIHBhY2thZ2UgKi8KICAgICAgICAvKiBOZHJQaXBlc0luaXRpYWxpemUoLi4uKSAqLwogICAgfQogICAgaWYgKGV4dF9mbGFncy5IYXNOZXdDb3JyRGVzYykKICAgIHsKICAgICAgICAvKiBpbml0aWFsaXplIGV4dHJhIGNvcnJlbGF0aW9uIHBhY2thZ2UgKi8KICAgICAgICBGSVhNRSgibmV3IGNvcnJlbGF0aW9uIGRlc2NyaXB0aW9uIG5vdCBpbXBsZW1lbnRlZFxuIik7CiAgICAgICAgc3R1Yk1zZy5mSGFzTmV3Q29yckRlc2MgPSBUUlVFOwogICAgfQoKICAgIC8qIGNvbnZlcnQgc3RyaW5ncywgZmxvYXRpbmcgcG9pbnQgdmFsdWVzIGFuZCBlbmRpYW5lc3MgaW50byBvdXIKICAgICAqIHByZWZlcnJlZCBmb3JtYXQgKi8KICAgIGlmICgocFJwY01zZy0+RGF0YVJlcHJlc2VudGF0aW9uICYgMHgwMDAwRkZGRlVMKSAhPSBORFJfTE9DQUxfREFUQV9SRVBSRVNFTlRBVElPTikKICAgICAgICBOZHJDb252ZXJ0KCZzdHViTXNnLCBwRm9ybWF0KTsKCiAgICBwYXJhbWV0ZXJfc3RhcnRfb2Zmc2V0ID0gY3VycmVudF9vZmZzZXQ7CgogICAgVFJBQ0UoImFsbG9jYXRpbmcgbWVtb3J5IGZvciBzdGFjayBvZiBzaXplICV4XG4iLCBzdGFja19zaXplKTsKCiAgICBhcmdzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHN0YWNrX3NpemUpOwogICAgc3R1Yk1zZy5TdGFja1RvcCA9IGFyZ3M7IC8qIHVzZWQgYnkgY29uZm9ybWFuY2Ugb2YgdG9wLWxldmVsIG9iamVjdHMgKi8KCiAgICAvKiBhZGQgdGhlIGltcGxpY2l0IFRoaXMgcG9pbnRlciBhcyB0aGUgZmlyc3QgYXJnIHRvIHRoZSBmdW5jdGlvbiBpZiB3ZQogICAgICogYXJlIGNhbGxpbmcgYW4gb2JqZWN0IG1ldGhvZCAqLwogICAgaWYgKHBUaGlzKQogICAgICAgICoodm9pZCAqKilhcmdzID0gKChDU3RkU3R1YkJ1ZmZlciAqKXBUaGlzKS0+cHZTZXJ2ZXJPYmplY3Q7CgogICAgLyogb3JkZXIgb2YgcGhhc2VzOgogICAgICogMS4gU1RVQkxFU1NfVU5NQVJIU0FMIC0gdW5tYXJzaGFsIFtpbl0gcGFyYW1zIGZyb20gYnVmZmVyCiAgICAgKiAyLiBTVFVCTEVTU19DQUxMU0VSVkVSIC0gc2VuZC9yZWNlaXZlIGJ1ZmZlcgogICAgICogMy4gU1RVQkxFU1NfQ0FMQ1NJWkUgLSBnZXQgW291dF0gYnVmZmVyIHNpemUKICAgICAqIDQuIFNUVUJMRVNTX0dFVEJVRkZFUiAtIGFsbG9jYXRlIFtvdXRdIGJ1ZmZlcgogICAgICogNS4gU1RVQkxFU1NfTUFSSFNBTCAtIG1hcnNoYWwgW291dF0gcGFyYW1zIHRvIGJ1ZmZlcgogICAgICovCiAgICBmb3IgKHBoYXNlID0gU1RVQkxFU1NfVU5NQVJTSEFMOyBwaGFzZSA8PSBTVFVCTEVTU19NQVJTSEFMOyBwaGFzZSsrKQogICAgewogICAgICAgIFRSQUNFKCJwaGFzZSA9ICVkXG4iLCBwaGFzZSk7CiAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICB7CiAgICAgICAgY2FzZSBTVFVCTEVTU19DQUxMU0VSVkVSOgogICAgICAgICAgICAvKiBjYWxsIHRoZSBzZXJ2ZXIgZnVuY3Rpb24gKi8KICAgICAgICAgICAgaWYgKHBTZXJ2ZXJJbmZvLT5UaHVua1RhYmxlICYmIHBTZXJ2ZXJJbmZvLT5UaHVua1RhYmxlW3BScGNNc2ctPlByb2NOdW1dKQogICAgICAgICAgICAgICAgcFNlcnZlckluZm8tPlRodW5rVGFibGVbcFJwY01zZy0+UHJvY051bV0oJnN0dWJNc2cpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNFUlZFUl9ST1VUSU5FIGZ1bmM7CiAgICAgICAgICAgICAgICBMT05HX1BUUiByZXR2YWw7CgogICAgICAgICAgICAgICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9PQkpFQ1QpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgU0VSVkVSX1JPVVRJTkUgKnZ0YmwgPSAqKFNFUlZFUl9ST1VUSU5FICoqKSgoQ1N0ZFN0dWJCdWZmZXIgKilwVGhpcyktPnB2U2VydmVyT2JqZWN0OwogICAgICAgICAgICAgICAgICAgIGZ1bmMgPSB2dGJsW3BScGNNc2ctPlByb2NOdW1dOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGZ1bmMgPSBwU2VydmVySW5mby0+RGlzcGF0Y2hUYWJsZVtwUnBjTXNnLT5Qcm9jTnVtXTsKCiAgICAgICAgICAgICAgICAvKiBGSVhNRTogd2hhdCBoYXBwZW5zIHdpdGggcmV0dXJuIHZhbHVlcyB0aGF0IGRvbid0IGZpdCBpbnRvIGEgc2luZ2xlIHJlZ2lzdGVyIG9uIHg4Nj8gKi8KICAgICAgICAgICAgICAgIHJldHZhbCA9IGNhbGxfc2VydmVyX2Z1bmMoZnVuYywgYXJncywgc3RhY2tfc2l6ZSk7CgogICAgICAgICAgICAgICAgaWYgKHJldHZhbF9wdHIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoInN0dWIgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgMHglbHhcbiIsIHJldHZhbCk7CiAgICAgICAgICAgICAgICAgICAgKnJldHZhbF9wdHIgPSByZXR2YWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoInZvaWQgc3R1YiBpbXBsZW1lbnRhdGlvblxuIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN0dWJNc2cuQnVmZmVyID0gTlVMTDsKICAgICAgICAgICAgc3R1Yk1zZy5CdWZmZXJMZW5ndGggPSAwOwoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBTVFVCTEVTU19HRVRCVUZGRVI6CiAgICAgICAgICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgICAgICAgICAgICAgTmRyU3R1YkdldEJ1ZmZlcihwVGhpcywgcENoYW5uZWwsICZzdHViTXNnKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSUENfU1RBVFVTIFN0YXR1czsKCiAgICAgICAgICAgICAgICBwUnBjTXNnLT5CdWZmZXJMZW5ndGggPSBzdHViTXNnLkJ1ZmZlckxlbmd0aDsKICAgICAgICAgICAgICAgIC8qIGFsbG9jYXRlIGJ1ZmZlciBmb3IgW291dF0gYW5kIFtyZXRdIHBhcmFtcyAqLwogICAgICAgICAgICAgICAgU3RhdHVzID0gSV9ScGNHZXRCdWZmZXIocFJwY01zZyk7IAogICAgICAgICAgICAgICAgaWYgKFN0YXR1cykKICAgICAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihTdGF0dXMpOwogICAgICAgICAgICAgICAgc3R1Yk1zZy5CdWZmZXJTdGFydCA9IHBScGNNc2ctPkJ1ZmZlcjsKICAgICAgICAgICAgICAgIHN0dWJNc2cuQnVmZmVyRW5kID0gc3R1Yk1zZy5CdWZmZXJTdGFydCArIHN0dWJNc2cuQnVmZmVyTGVuZ3RoOwogICAgICAgICAgICAgICAgc3R1Yk1zZy5CdWZmZXIgPSBzdHViTXNnLkJ1ZmZlclN0YXJ0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgU1RVQkxFU1NfTUFSU0hBTDoKICAgICAgICBjYXNlIFNUVUJMRVNTX1VOTUFSU0hBTDoKICAgICAgICBjYXNlIFNUVUJMRVNTX0NBTENTSVpFOgogICAgICAgICAgICBjdXJyZW50X29mZnNldCA9IHBhcmFtZXRlcl9zdGFydF9vZmZzZXQ7CiAgICAgICAgICAgIGN1cnJlbnRfc3RhY2tfb2Zmc2V0ID0gMDsKCiAgICAgICAgICAgIC8qIE5PVEU6IFYxIHN0eWxlIGZvcm1hdCBkb2VzJ3QgdGVybWluYXRlIG9uIHRoZSBudW1iZXJfb2ZfcGFyYW1zCiAgICAgICAgICAgICAqIGNvbmRpdGlvbiBhcyBpdCBkb2Vzbid0IGhhdmUgdGhpcyBhdHRyaWJ1dGUuIEluc3RlYWQgaXQKICAgICAgICAgICAgICogdGVybWluYXRlcyB3aGVuIHRoZSBzdGFjayBzaXplIGdpdmVuIGluIHRoZSBoZWFkZXIgaXMgZXhjZWVkZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbnVtYmVyX29mX3BhcmFtczsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoYlYyRm9ybWF0KSAvKiBuZXcgcGFyYW1ldGVyIGZvcm1hdCAqLwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNvbnN0IE5EUl9QQVJBTV9PSUZfQkFTRVRZUEUgKnBQYXJhbSA9CiAgICAgICAgICAgICAgICAgICAgICAgIChORFJfUEFSQU1fT0lGX0JBU0VUWVBFICopJnBGb3JtYXRbY3VycmVudF9vZmZzZXRdOwogICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnBBcmc7CgogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfc3RhY2tfb2Zmc2V0ID0gcFBhcmFtLT5zdGFja19vZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgcEFyZyA9ICh1bnNpZ25lZCBjaGFyICopKGFyZ3MrY3VycmVudF9zdGFja19vZmZzZXQpOwoKICAgICAgICAgICAgICAgICAgICBUUkFDRSgicGFyYW1bJWRdOiBuZXcgZm9ybWF0XG4iLCBpKTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRwYXJhbV9hdHRyaWJ1dGVzOiIpOyBkdW1wX1JQQ19GQ19QUk9DX1BGKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcyk7IFRSQUNFKCJcbiIpOwogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdHN0YWNrX29mZnNldDogJXhcbiIsIGN1cnJlbnRfc3RhY2tfb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRtZW1vcnkgYWRkciAoYmVmb3JlKTogJXAgLT4gJXBcbiIsIHBBcmcsICoodW5zaWduZWQgY2hhciAqKilwQXJnKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5TZXJ2ZXJBbGxvY1NpemUpCiAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJTZXJ2ZXJBbGxvY1NpemUgb2YgJWQgaWdub3JlZCBmb3IgcGFyYW1ldGVyICVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLlNlcnZlckFsbG9jU2l6ZSAqIDgsIGkpOwoKICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzQmFzZXR5cGUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyICpwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFBhcmFtLT50eXBlX2Zvcm1hdF9jaGFyOwoKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0YmFzZSB0eXBlOiAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfTUFSU0hBTDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNPdXQgfHwgcFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzUmV0dXJuKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNTaW1wbGVSZWYpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRklYTUU6IGNhbGwgY2FsbF9mcmVlciBoZXJlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1NpbXBsZVJlZikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIoJnN0dWJNc2csICh1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAmcEFyZywgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG1ha2UgYSBub3RlIG9mIHRoZSBhZGRyZXNzIG9mIHRoZSByZXR1cm4gdmFsdWUgcGFyYW1ldGVyIGZvciBsYXRlciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR2YWxfcHRyID0gKExPTkdfUFRSICopcEFyZzsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19DQUxDU0laRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNPdXQgfHwgcFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzUmV0dXJuKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNTaW1wbGVSZWYpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKCZzdHViTXNnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9idWZmZXJfc2l6ZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1NfSU5URVJOQUxfRVJST1IpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BBUkFNX09JRl9CQVNFVFlQRSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIE5EUl9QQVJBTV9PSUZfT1RIRVIgKiBwUGFyYW1PdGhlciA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTkRSX1BBUkFNX09JRl9PVEhFUiAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKiBwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKHBTdHViRGVzYy0+cEZvcm1hdFR5cGVzW3BQYXJhbU90aGVyLT50eXBlX29mZnNldF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0Y29tcGxleCB0eXBlIDB4JTAyeFxuIiwgKnBUeXBlRm9ybWF0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocGhhc2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCB8fCBwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNSZXR1cm4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R1Yk1zZy5wZm5GcmVlKCoodm9pZCAqKilwQXJnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBGSVhNRTogY2FsbCBjYWxsX2ZyZWVyIGhlcmUgZm9yIElOIHR5cGVzICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAmcEFyZywgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIoJnN0dWJNc2csICh1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIXBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKih2b2lkICoqKXBBcmcgPSBOZHJBbGxvY2F0ZSgmc3R1Yk1zZywgc2l6ZW9mKHZvaWQgKikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoqKHZvaWQgKioqKXBBcmcgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzT3V0IHx8IHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzQnlWYWx1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9idWZmZXJfc2l6ZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKCZzdHViTXNnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfU19JTlRFUk5BTF9FUlJPUik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUEFSQU1fT0lGX09USEVSKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0bWVtb3J5IGFkZHIgKGFmdGVyKTogJXAgLT4gJXBcbiIsIHBBcmcsICoodW5zaWduZWQgY2hhciAqKilwQXJnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgLyogb2xkIHBhcmFtZXRlciBmb3JtYXQgKi8KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBORFJfUEFSQU1fT0lfQkFTRVRZUEUgKnBQYXJhbSA9CiAgICAgICAgICAgICAgICAgICAgICAgIChORFJfUEFSQU1fT0lfQkFTRVRZUEUgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CiAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqcEFyZyA9ICh1bnNpZ25lZCBjaGFyICopKGFyZ3MrY3VycmVudF9zdGFja19vZmZzZXQpOwoKICAgICAgICAgICAgICAgICAgICAvKiBubyBtb3JlIHBhcmFtZXRlcnM7IGV4aXQgbG9vcCAqLwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50X3N0YWNrX29mZnNldCA+IHN0YWNrX3NpemUpCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBUUkFDRSgicGFyYW1bJWRdOiBvbGQgZm9ybWF0XG5cdHBhcmFtX2RpcmVjdGlvbjogMHgleFxuIiwgaSwgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24pOwoKICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX1BBUkFNX0JBU0VUWVBFIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU1fQkFTRVRZUEUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyICpwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFBhcmFtLT50eXBlX2Zvcm1hdF9jaGFyOwoKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0YmFzZSB0eXBlIDB4JTAyeFxuIiwgKnBUeXBlRm9ybWF0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocGhhc2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU1fQkFTRVRZUEUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9tYXJzaGFsbGVyKCZzdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAmcEFyZywgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfU19JTlRFUk5BTF9FUlJPUik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfc3RhY2tfb2Zmc2V0ICs9IGNhbGxfbWVtb3J5X3NpemVyKCZzdHViTXNnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUEFSQU1fT0lfQkFTRVRZUEUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBORFJfUEFSQU1fT0lfT1RIRVIgKiBwUGFyYW1PdGhlciA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKE5EUl9QQVJBTV9PSV9PVEhFUiAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKiBwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFN0dWJEZXNjLT5wRm9ybWF0VHlwZXNbcFBhcmFtT3RoZXItPnR5cGVfb2Zmc2V0XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdGNvbXBsZXggdHlwZSAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfTUFSU0hBTDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfT1VUX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX09VVF9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9tYXJzaGFsbGVyKCZzdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX09VVF9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcigmc3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX0NBTENTSVpFOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19PVVRfUEFSQU0gfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fT1VUX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfU19JTlRFUk5BTF9FUlJPUik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfc3RhY2tfb2Zmc2V0ICs9IHBQYXJhbU90aGVyLT5zdGFja19zaXplICogc2l6ZW9mKElOVCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUEFSQU1fT0lfT1RIRVIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJzaG91bGRuJ3QgcmVhY2ggaGVyZS4gcGhhc2UgJWRcbiIsIHBoYXNlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIHBScGNNc2ctPkJ1ZmZlckxlbmd0aCA9ICh1bnNpZ25lZCBpbnQpKHN0dWJNc2cuQnVmZmVyIC0gKHVuc2lnbmVkIGNoYXIgKilwUnBjTXNnLT5CdWZmZXIpOwoKICAgIGlmIChleHRfZmxhZ3MuSGFzTmV3Q29yckRlc2MpCiAgICB7CiAgICAgICAgLyogZnJlZSBleHRyYSBjb3JyZWxhdGlvbiBwYWNrYWdlICovCiAgICAgICAgLyogTmRyQ29ycmVsYXRpb25GcmVlKCZzdHViTXNnKTsgKi8KICAgIH0KCiAgICBpZiAoT2lmX2ZsYWdzLkhhc1BpcGVzKQogICAgewogICAgICAgIC8qIE5kclBpcGVzRG9uZSguLi4pICovCiAgICB9CgojaWYgMAogICAgLyogZnJlZSB0aGUgZnVsbCBwb2ludGVyIHRyYW5zbGF0aW9uIHRhYmxlcyAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9GVUxMUFRSKQogICAgICAgIE5kckZ1bGxQb2ludGVyWGxhdEZyZWUoc3R1Yk1zZy5GdWxsUHRyWGxhdFRhYmxlcyk7CiNlbmRpZgoKICAgIC8qIGZyZWUgc2VydmVyIGZ1bmN0aW9uIHN0YWNrICovCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhcmdzKTsKCiAgICByZXR1cm4gU19PSzsKfQoKdm9pZCBXSU5BUEkgTmRyU2VydmVyQ2FsbDIoUFJQQ19NRVNTQUdFIHBScGNNc2cpCnsKICAgIERXT1JEIGR3UGhhc2U7CiAgICBOZHJTdHViQ2FsbDIoTlVMTCwgTlVMTCwgcFJwY01zZywgJmR3UGhhc2UpOwp9Cg==