LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiAgIHVuaWNvZGVkYXRhIC0tIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgVW5pY29kZSA1LjIgZGF0YSBiYXNlLg0KDQogICBEYXRhIHdhcyBleHRyYWN0ZWQgZnJvbSB0aGUgVW5pY29kZSA1LjIgVW5pY29kZURhdGEudHh0IGZpbGUuDQoNCiAgIFdyaXR0ZW4gYnkgTWFyYy1BbmRyZSBMZW1idXJnIChtYWxAbGVtYnVyZy5jb20pLg0KICAgTW9kaWZpZWQgZm9yIFB5dGhvbiAyLjAgYnkgRnJlZHJpayBMdW5kaCAoZnJlZHJpa0BweXRob253YXJlLmNvbSkNCiAgIE1vZGlmaWVkIGJ5IE1hcnRpbiB2LiBM9ndpcyAobWFydGluQHYubG9ld2lzLmRlKQ0KDQogICBDb3B5cmlnaHQgKGMpIENvcnBvcmF0aW9uIGZvciBOYXRpb25hbCBSZXNlYXJjaCBJbml0aWF0aXZlcy4NCg0KICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQoNCiNpbmNsdWRlICJQeXRob24uaCINCiNpbmNsdWRlICJ1Y25oYXNoLmgiDQojaW5jbHVkZSAic3RydWN0bWVtYmVyLmgiDQoNCi8qIGNoYXJhY3RlciBwcm9wZXJ0aWVzICovDQoNCnR5cGVkZWYgc3RydWN0IHsNCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIGNhdGVnb3J5OyAgICAgICAvKiBpbmRleCBpbnRvDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX1B5VW5pY29kZV9DYXRlZ29yeU5hbWVzICovDQogICAgY29uc3QgdW5zaWduZWQgY2hhciBjb21iaW5pbmc7ICAgICAgLyogY29tYmluaW5nIGNsYXNzIHZhbHVlIDAgLSAyNTUgKi8NCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIGJpZGlyZWN0aW9uYWw7ICAvKiBpbmRleCBpbnRvDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX1B5VW5pY29kZV9CaWRpcmVjdGlvbmFsTmFtZXMgKi8NCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIG1pcnJvcmVkOyAgICAgICAvKiB0cnVlIGlmIG1pcnJvcmVkIGluIGJpZGlyIG1vZGUgKi8NCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIGVhc3RfYXNpYW5fd2lkdGg7ICAgICAgIC8qIGluZGV4IGludG8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9QeVVuaWNvZGVfRWFzdEFzaWFuV2lkdGggKi8NCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIG5vcm1hbGl6YXRpb25fcXVpY2tfY2hlY2s7IC8qIHNlZSBpc19ub3JtYWxpemVkKCkgKi8NCn0gX1B5VW5pY29kZV9EYXRhYmFzZVJlY29yZDsNCg0KdHlwZWRlZiBzdHJ1Y3QgY2hhbmdlX3JlY29yZCB7DQogICAgLyogc2VxdWVuY2Ugb2YgZmllbGRzIHNob3VsZCBiZSB0aGUgc2FtZSBhcyBpbiBtZXJnZV9vbGRfdmVyc2lvbiAqLw0KICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgYmlkaXJfY2hhbmdlZDsNCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIGNhdGVnb3J5X2NoYW5nZWQ7DQogICAgY29uc3QgdW5zaWduZWQgY2hhciBkZWNpbWFsX2NoYW5nZWQ7DQogICAgY29uc3QgdW5zaWduZWQgY2hhciBtaXJyb3JlZF9jaGFuZ2VkOw0KICAgIGNvbnN0IGRvdWJsZSBudW1lcmljX2NoYW5nZWQ7DQp9IGNoYW5nZV9yZWNvcmQ7DQoNCi8qIGRhdGEgZmlsZSBnZW5lcmF0ZWQgYnkgVG9vbHMvdW5pY29kZS9tYWtldW5pY29kZWRhdGEucHkgKi8NCiNpbmNsdWRlICJ1bmljb2RlZGF0YV9kYi5oIg0KDQpzdGF0aWMgY29uc3QgX1B5VW5pY29kZV9EYXRhYmFzZVJlY29yZCoNCl9nZXRyZWNvcmRfZXgoUHlfVUNTNCBjb2RlKQ0Kew0KICAgIGludCBpbmRleDsNCiAgICBpZiAoY29kZSA+PSAweDExMDAwMCkNCiAgICAgICAgaW5kZXggPSAwOw0KICAgIGVsc2Ugew0KICAgICAgICBpbmRleCA9IGluZGV4MVsoY29kZT4+U0hJRlQpXTsNCiAgICAgICAgaW5kZXggPSBpbmRleDJbKGluZGV4PDxTSElGVCkrKGNvZGUmKCgxPDxTSElGVCktMSkpXTsNCiAgICB9DQoNCiAgICByZXR1cm4gJl9QeVVuaWNvZGVfRGF0YWJhc2VfUmVjb3Jkc1tpbmRleF07DQp9DQoNCi8qIC0tLS0tLS0tLS0tLS0gUHJldmlvdXMtdmVyc2lvbiBBUEkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KdHlwZWRlZiBzdHJ1Y3QgcHJldmlvdXNfdmVyc2lvbiB7DQogICAgUHlPYmplY3RfSEVBRA0KICAgIGNvbnN0IGNoYXIgKm5hbWU7DQogICAgY29uc3QgY2hhbmdlX3JlY29yZCogKCpnZXRyZWNvcmQpKFB5X1VDUzQpOw0KICAgIFB5X1VDUzQgKCpub3JtYWxpemF0aW9uKShQeV9VQ1M0KTsNCn0gUHJldmlvdXNEQlZlcnNpb247DQoNCiNkZWZpbmUgZ2V0X29sZF9yZWNvcmQoc2VsZiwgdikgICAgKCgoKFByZXZpb3VzREJWZXJzaW9uKilzZWxmKS0+Z2V0cmVjb3JkKSh2KSkNCg0Kc3RhdGljIFB5TWVtYmVyRGVmIERCX21lbWJlcnNbXSA9IHsNCiAgICAgICAgeyJ1bmlkYXRhX3ZlcnNpb24iLCBUX1NUUklORywgb2Zmc2V0b2YoUHJldmlvdXNEQlZlcnNpb24sIG5hbWUpLCBSRUFET05MWX0sDQogICAgICAgIHtOVUxMfQ0KfTsNCg0KLyogZm9yd2FyZCBkZWNsYXJhdGlvbiAqLw0Kc3RhdGljIFB5VHlwZU9iamVjdCBVQ0RfVHlwZTsNCg0Kc3RhdGljIFB5T2JqZWN0Kg0KbmV3X3ByZXZpb3VzX3ZlcnNpb24oY29uc3QgY2hhcipuYW1lLCBjb25zdCBjaGFuZ2VfcmVjb3JkKiAoKmdldHJlY29yZCkoUHlfVUNTNCksDQogICAgICAgICAgICAgICAgICAgICBQeV9VQ1M0ICgqbm9ybWFsaXphdGlvbikoUHlfVUNTNCkpDQp7DQogICAgICAgIFByZXZpb3VzREJWZXJzaW9uICpzZWxmOw0KICAgICAgICBzZWxmID0gUHlPYmplY3RfTmV3KFByZXZpb3VzREJWZXJzaW9uLCAmVUNEX1R5cGUpOw0KICAgICAgICBpZiAoc2VsZiA9PSBOVUxMKQ0KICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOw0KICAgICAgICBzZWxmLT5uYW1lID0gbmFtZTsNCiAgICAgICAgc2VsZi0+Z2V0cmVjb3JkID0gZ2V0cmVjb3JkOw0KICAgICAgICBzZWxmLT5ub3JtYWxpemF0aW9uID0gbm9ybWFsaXphdGlvbjsNCiAgICAgICAgcmV0dXJuIChQeU9iamVjdCopc2VsZjsNCn0NCg0KDQpzdGF0aWMgUHlfVUNTNCBnZXR1Y2hhcihQeVVuaWNvZGVPYmplY3QgKm9iaikNCnsNCiAgICBQeV9VTklDT0RFICp2ID0gUHlVbmljb2RlX0FTX1VOSUNPREUob2JqKTsNCg0KICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUob2JqKSA9PSAxKQ0KICAgICAgICByZXR1cm4gKnY7DQojaWZuZGVmIFB5X1VOSUNPREVfV0lERQ0KICAgIGVsc2UgaWYgKChQeVVuaWNvZGVfR0VUX1NJWkUob2JqKSA9PSAyKSAmJg0KICAgICAgICAgICAgICgweEQ4MDAgPD0gdlswXSAmJiB2WzBdIDw9IDB4REJGRikgJiYNCiAgICAgICAgICAgICAoMHhEQzAwIDw9IHZbMV0gJiYgdlsxXSA8PSAweERGRkYpKQ0KICAgICAgICByZXR1cm4gKCgodlswXSAmIDB4M0ZGKTw8MTApIHwgKHZbMV0gJiAweDNGRikpICsgMHgxMDAwMDsNCiNlbmRpZg0KICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsDQogICAgICAgICAgICAgICAgICAgICJuZWVkIGEgc2luZ2xlIFVuaWNvZGUgY2hhcmFjdGVyIGFzIHBhcmFtZXRlciIpOw0KICAgIHJldHVybiAoUHlfVUNTNCktMTsNCn0NCg0KLyogLS0tIE1vZHVsZSBBUEkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQoNClB5RG9jX1NUUlZBUih1bmljb2RlZGF0YV9kZWNpbWFsX19kb2NfXywNCiJkZWNpbWFsKHVuaWNoclssIGRlZmF1bHRdKVxuXA0KXG5cDQpSZXR1cm5zIHRoZSBkZWNpbWFsIHZhbHVlIGFzc2lnbmVkIHRvIHRoZSBVbmljb2RlIGNoYXJhY3RlciB1bmljaHJcblwNCmFzIGludGVnZXIuIElmIG5vIHN1Y2ggdmFsdWUgaXMgZGVmaW5lZCwgZGVmYXVsdCBpcyByZXR1cm5lZCwgb3IsIGlmXG5cDQpub3QgZ2l2ZW4sIFZhbHVlRXJyb3IgaXMgcmFpc2VkLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QgKg0KdW5pY29kZWRhdGFfZGVjaW1hbChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpDQp7DQogICAgUHlVbmljb2RlT2JqZWN0ICp2Ow0KICAgIFB5T2JqZWN0ICpkZWZvYmogPSBOVUxMOw0KICAgIGludCBoYXZlX29sZCA9IDA7DQogICAgbG9uZyByYzsNCiAgICBQeV9VQ1M0IGM7DQoNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hfE86ZGVjaW1hbCIsICZQeVVuaWNvZGVfVHlwZSwgJnYsICZkZWZvYmopKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KDQogICAgaWYgKHNlbGYpIHsNCiAgICAgICAgY29uc3QgY2hhbmdlX3JlY29yZCAqb2xkID0gZ2V0X29sZF9yZWNvcmQoc2VsZiwgYyk7DQogICAgICAgIGlmIChvbGQtPmNhdGVnb3J5X2NoYW5nZWQgPT0gMCkgew0KICAgICAgICAgICAgLyogdW5hc3NpZ25lZCAqLw0KICAgICAgICAgICAgaGF2ZV9vbGQgPSAxOw0KICAgICAgICAgICAgcmMgPSAtMTsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlIGlmIChvbGQtPmRlY2ltYWxfY2hhbmdlZCAhPSAweEZGKSB7DQogICAgICAgICAgICBoYXZlX29sZCA9IDE7DQogICAgICAgICAgICByYyA9IG9sZC0+ZGVjaW1hbF9jaGFuZ2VkOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgaWYgKCFoYXZlX29sZCkNCiAgICAgICAgcmMgPSBQeV9VTklDT0RFX1RPREVDSU1BTChjKTsNCiAgICBpZiAocmMgPCAwKSB7DQogICAgICAgIGlmIChkZWZvYmogPT0gTlVMTCkgew0KICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vdCBhIGRlY2ltYWwiKTsNCiAgICAgICAgICAgIHJldHVybiBOVUxMOw0KICAgICAgICB9DQogICAgICAgIGVsc2Ugew0KICAgICAgICAgICAgUHlfSU5DUkVGKGRlZm9iaik7DQogICAgICAgICAgICByZXR1cm4gZGVmb2JqOw0KICAgICAgICB9DQogICAgfQ0KICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhyYyk7DQp9DQoNClB5RG9jX1NUUlZBUih1bmljb2RlZGF0YV9kaWdpdF9fZG9jX18sDQoiZGlnaXQodW5pY2hyWywgZGVmYXVsdF0pXG5cDQpcblwNClJldHVybnMgdGhlIGRpZ2l0IHZhbHVlIGFzc2lnbmVkIHRvIHRoZSBVbmljb2RlIGNoYXJhY3RlciB1bmljaHIgYXNcblwNCmludGVnZXIuIElmIG5vIHN1Y2ggdmFsdWUgaXMgZGVmaW5lZCwgZGVmYXVsdCBpcyByZXR1cm5lZCwgb3IsIGlmXG5cDQpub3QgZ2l2ZW4sIFZhbHVlRXJyb3IgaXMgcmFpc2VkLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QgKg0KdW5pY29kZWRhdGFfZGlnaXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQ0Kew0KICAgIFB5VW5pY29kZU9iamVjdCAqdjsNCiAgICBQeU9iamVjdCAqZGVmb2JqID0gTlVMTDsNCiAgICBsb25nIHJjOw0KICAgIFB5X1VDUzQgYzsNCg0KICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyF8TzpkaWdpdCIsICZQeVVuaWNvZGVfVHlwZSwgJnYsICZkZWZvYmopKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIHJjID0gUHlfVU5JQ09ERV9UT0RJR0lUKGMpOw0KICAgIGlmIChyYyA8IDApIHsNCiAgICAgICAgaWYgKGRlZm9iaiA9PSBOVUxMKSB7DQogICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIm5vdCBhIGRpZ2l0Iik7DQogICAgICAgICAgICByZXR1cm4gTlVMTDsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlIHsNCiAgICAgICAgICAgIFB5X0lOQ1JFRihkZWZvYmopOw0KICAgICAgICAgICAgcmV0dXJuIGRlZm9iajsNCiAgICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcocmMpOw0KfQ0KDQpQeURvY19TVFJWQVIodW5pY29kZWRhdGFfbnVtZXJpY19fZG9jX18sDQoibnVtZXJpYyh1bmljaHJbLCBkZWZhdWx0XSlcblwNClxuXA0KUmV0dXJucyB0aGUgbnVtZXJpYyB2YWx1ZSBhc3NpZ25lZCB0byB0aGUgVW5pY29kZSBjaGFyYWN0ZXIgdW5pY2hyXG5cDQphcyBmbG9hdC4gSWYgbm8gc3VjaCB2YWx1ZSBpcyBkZWZpbmVkLCBkZWZhdWx0IGlzIHJldHVybmVkLCBvciwgaWZcblwNCm5vdCBnaXZlbiwgVmFsdWVFcnJvciBpcyByYWlzZWQuIik7DQoNCnN0YXRpYyBQeU9iamVjdCAqDQp1bmljb2RlZGF0YV9udW1lcmljKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykNCnsNCiAgICBQeVVuaWNvZGVPYmplY3QgKnY7DQogICAgUHlPYmplY3QgKmRlZm9iaiA9IE5VTEw7DQogICAgaW50IGhhdmVfb2xkID0gMDsNCiAgICBkb3VibGUgcmM7DQogICAgUHlfVUNTNCBjOw0KDQogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPIXxPOm51bWVyaWMiLCAmUHlVbmljb2RlX1R5cGUsICZ2LCAmZGVmb2JqKSkNCiAgICAgICAgcmV0dXJuIE5VTEw7DQogICAgYyA9IGdldHVjaGFyKHYpOw0KICAgIGlmIChjID09IChQeV9VQ1M0KS0xKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCg0KICAgIGlmIChzZWxmKSB7DQogICAgICAgIGNvbnN0IGNoYW5nZV9yZWNvcmQgKm9sZCA9IGdldF9vbGRfcmVjb3JkKHNlbGYsIGMpOw0KICAgICAgICBpZiAob2xkLT5jYXRlZ29yeV9jaGFuZ2VkID09IDApIHsNCiAgICAgICAgICAgIC8qIHVuYXNzaWduZWQgKi8NCiAgICAgICAgICAgIGhhdmVfb2xkID0gMTsNCiAgICAgICAgICAgIHJjID0gLTEuMDsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlIGlmIChvbGQtPmRlY2ltYWxfY2hhbmdlZCAhPSAweEZGKSB7DQogICAgICAgICAgICBoYXZlX29sZCA9IDE7DQogICAgICAgICAgICByYyA9IG9sZC0+ZGVjaW1hbF9jaGFuZ2VkOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgaWYgKCFoYXZlX29sZCkNCiAgICAgICAgcmMgPSBQeV9VTklDT0RFX1RPTlVNRVJJQyhjKTsNCiAgICBpZiAocmMgPT0gLTEuMCkgew0KICAgICAgICBpZiAoZGVmb2JqID09IE5VTEwpIHsNCiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAibm90IGEgbnVtZXJpYyBjaGFyYWN0ZXIiKTsNCiAgICAgICAgICAgIHJldHVybiBOVUxMOw0KICAgICAgICB9DQogICAgICAgIGVsc2Ugew0KICAgICAgICAgICAgUHlfSU5DUkVGKGRlZm9iaik7DQogICAgICAgICAgICByZXR1cm4gZGVmb2JqOw0KICAgICAgICB9DQogICAgfQ0KICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUocmMpOw0KfQ0KDQpQeURvY19TVFJWQVIodW5pY29kZWRhdGFfY2F0ZWdvcnlfX2RvY19fLA0KImNhdGVnb3J5KHVuaWNocilcblwNClxuXA0KUmV0dXJucyB0aGUgZ2VuZXJhbCBjYXRlZ29yeSBhc3NpZ25lZCB0byB0aGUgVW5pY29kZSBjaGFyYWN0ZXJcblwNCnVuaWNociBhcyBzdHJpbmcuIik7DQoNCnN0YXRpYyBQeU9iamVjdCAqDQp1bmljb2RlZGF0YV9jYXRlZ29yeShQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpDQp7DQogICAgUHlVbmljb2RlT2JqZWN0ICp2Ow0KICAgIGludCBpbmRleDsNCiAgICBQeV9VQ1M0IGM7DQoNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hOmNhdGVnb3J5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgJlB5VW5pY29kZV9UeXBlLCAmdikpDQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIGMgPSBnZXR1Y2hhcih2KTsNCiAgICBpZiAoYyA9PSAoUHlfVUNTNCktMSkNCiAgICAgICAgcmV0dXJuIE5VTEw7DQogICAgaW5kZXggPSAoaW50KSBfZ2V0cmVjb3JkX2V4KGMpLT5jYXRlZ29yeTsNCiAgICBpZiAoc2VsZikgew0KICAgICAgICBjb25zdCBjaGFuZ2VfcmVjb3JkICpvbGQgPSBnZXRfb2xkX3JlY29yZChzZWxmLCBjKTsNCiAgICAgICAgaWYgKG9sZC0+Y2F0ZWdvcnlfY2hhbmdlZCAhPSAweEZGKQ0KICAgICAgICAgICAgaW5kZXggPSBvbGQtPmNhdGVnb3J5X2NoYW5nZWQ7DQogICAgfQ0KICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKF9QeVVuaWNvZGVfQ2F0ZWdvcnlOYW1lc1tpbmRleF0pOw0KfQ0KDQpQeURvY19TVFJWQVIodW5pY29kZWRhdGFfYmlkaXJlY3Rpb25hbF9fZG9jX18sDQoiYmlkaXJlY3Rpb25hbCh1bmljaHIpXG5cDQpcblwNClJldHVybnMgdGhlIGJpZGlyZWN0aW9uYWwgY2xhc3MgYXNzaWduZWQgdG8gdGhlIFVuaWNvZGUgY2hhcmFjdGVyXG5cDQp1bmljaHIgYXMgc3RyaW5nLiBJZiBubyBzdWNoIHZhbHVlIGlzIGRlZmluZWQsIGFuIGVtcHR5IHN0cmluZyBpc1xuXA0KcmV0dXJuZWQuIik7DQoNCnN0YXRpYyBQeU9iamVjdCAqDQp1bmljb2RlZGF0YV9iaWRpcmVjdGlvbmFsKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykNCnsNCiAgICBQeVVuaWNvZGVPYmplY3QgKnY7DQogICAgaW50IGluZGV4Ow0KICAgIFB5X1VDUzQgYzsNCg0KICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyE6YmlkaXJlY3Rpb25hbCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICZQeVVuaWNvZGVfVHlwZSwgJnYpKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIGluZGV4ID0gKGludCkgX2dldHJlY29yZF9leChjKS0+YmlkaXJlY3Rpb25hbDsNCiAgICBpZiAoc2VsZikgew0KICAgICAgICBjb25zdCBjaGFuZ2VfcmVjb3JkICpvbGQgPSBnZXRfb2xkX3JlY29yZChzZWxmLCBjKTsNCiAgICAgICAgaWYgKG9sZC0+Y2F0ZWdvcnlfY2hhbmdlZCA9PSAwKQ0KICAgICAgICAgICAgaW5kZXggPSAwOyAvKiB1bmFzc2lnbmVkICovDQogICAgICAgIGVsc2UgaWYgKG9sZC0+YmlkaXJfY2hhbmdlZCAhPSAweEZGKQ0KICAgICAgICAgICAgaW5kZXggPSBvbGQtPmJpZGlyX2NoYW5nZWQ7DQogICAgfQ0KICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKF9QeVVuaWNvZGVfQmlkaXJlY3Rpb25hbE5hbWVzW2luZGV4XSk7DQp9DQoNClB5RG9jX1NUUlZBUih1bmljb2RlZGF0YV9jb21iaW5pbmdfX2RvY19fLA0KImNvbWJpbmluZyh1bmljaHIpXG5cDQpcblwNClJldHVybnMgdGhlIGNhbm9uaWNhbCBjb21iaW5pbmcgY2xhc3MgYXNzaWduZWQgdG8gdGhlIFVuaWNvZGVcblwNCmNoYXJhY3RlciB1bmljaHIgYXMgaW50ZWdlci4gUmV0dXJucyAwIGlmIG5vIGNvbWJpbmluZyBjbGFzcyBpc1xuXA0KZGVmaW5lZC4iKTsNCg0Kc3RhdGljIFB5T2JqZWN0ICoNCnVuaWNvZGVkYXRhX2NvbWJpbmluZyhQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpDQp7DQogICAgUHlVbmljb2RlT2JqZWN0ICp2Ow0KICAgIGludCBpbmRleDsNCiAgICBQeV9VQ1M0IGM7DQoNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hOmNvbWJpbmluZyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICZQeVVuaWNvZGVfVHlwZSwgJnYpKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIGluZGV4ID0gKGludCkgX2dldHJlY29yZF9leChjKS0+Y29tYmluaW5nOw0KICAgIGlmIChzZWxmKSB7DQogICAgICAgIGNvbnN0IGNoYW5nZV9yZWNvcmQgKm9sZCA9IGdldF9vbGRfcmVjb3JkKHNlbGYsIGMpOw0KICAgICAgICBpZiAob2xkLT5jYXRlZ29yeV9jaGFuZ2VkID09IDApDQogICAgICAgICAgICBpbmRleCA9IDA7IC8qIHVuYXNzaWduZWQgKi8NCiAgICB9DQogICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKGluZGV4KTsNCn0NCg0KUHlEb2NfU1RSVkFSKHVuaWNvZGVkYXRhX21pcnJvcmVkX19kb2NfXywNCiJtaXJyb3JlZCh1bmljaHIpXG5cDQpcblwNClJldHVybnMgdGhlIG1pcnJvcmVkIHByb3BlcnR5IGFzc2lnbmVkIHRvIHRoZSBVbmljb2RlIGNoYXJhY3RlclxuXA0KdW5pY2hyIGFzIGludGVnZXIuIFJldHVybnMgMSBpZiB0aGUgY2hhcmFjdGVyIGhhcyBiZWVuIGlkZW50aWZpZWQgYXNcblwNCmEgXCJtaXJyb3JlZFwiIGNoYXJhY3RlciBpbiBiaWRpcmVjdGlvbmFsIHRleHQsIDAgb3RoZXJ3aXNlLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QgKg0KdW5pY29kZWRhdGFfbWlycm9yZWQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQ0Kew0KICAgIFB5VW5pY29kZU9iamVjdCAqdjsNCiAgICBpbnQgaW5kZXg7DQogICAgUHlfVUNTNCBjOw0KDQogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPITptaXJyb3JlZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICZQeVVuaWNvZGVfVHlwZSwgJnYpKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIGluZGV4ID0gKGludCkgX2dldHJlY29yZF9leChjKS0+bWlycm9yZWQ7DQogICAgaWYgKHNlbGYpIHsNCiAgICAgICAgY29uc3QgY2hhbmdlX3JlY29yZCAqb2xkID0gZ2V0X29sZF9yZWNvcmQoc2VsZiwgYyk7DQogICAgICAgIGlmIChvbGQtPmNhdGVnb3J5X2NoYW5nZWQgPT0gMCkNCiAgICAgICAgICAgIGluZGV4ID0gMDsgLyogdW5hc3NpZ25lZCAqLw0KICAgICAgICBlbHNlIGlmIChvbGQtPm1pcnJvcmVkX2NoYW5nZWQgIT0gMHhGRikNCiAgICAgICAgICAgIGluZGV4ID0gb2xkLT5taXJyb3JlZF9jaGFuZ2VkOw0KICAgIH0NCiAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoaW5kZXgpOw0KfQ0KDQpQeURvY19TVFJWQVIodW5pY29kZWRhdGFfZWFzdF9hc2lhbl93aWR0aF9fZG9jX18sDQoiZWFzdF9hc2lhbl93aWR0aCh1bmljaHIpXG5cDQpcblwNClJldHVybnMgdGhlIGVhc3QgYXNpYW4gd2lkdGggYXNzaWduZWQgdG8gdGhlIFVuaWNvZGUgY2hhcmFjdGVyXG5cDQp1bmljaHIgYXMgc3RyaW5nLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QgKg0KdW5pY29kZWRhdGFfZWFzdF9hc2lhbl93aWR0aChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpDQp7DQogICAgUHlVbmljb2RlT2JqZWN0ICp2Ow0KICAgIGludCBpbmRleDsNCiAgICBQeV9VQ1M0IGM7DQoNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hOmVhc3RfYXNpYW5fd2lkdGgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAmUHlVbmljb2RlX1R5cGUsICZ2KSkNCiAgICAgICAgcmV0dXJuIE5VTEw7DQogICAgYyA9IGdldHVjaGFyKHYpOw0KICAgIGlmIChjID09IChQeV9VQ1M0KS0xKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBpbmRleCA9IChpbnQpIF9nZXRyZWNvcmRfZXgoYyktPmVhc3RfYXNpYW5fd2lkdGg7DQogICAgaWYgKHNlbGYpIHsNCiAgICAgICAgY29uc3QgY2hhbmdlX3JlY29yZCAqb2xkID0gZ2V0X29sZF9yZWNvcmQoc2VsZiwgYyk7DQogICAgICAgIGlmIChvbGQtPmNhdGVnb3J5X2NoYW5nZWQgPT0gMCkNCiAgICAgICAgICAgIGluZGV4ID0gMDsgLyogdW5hc3NpZ25lZCAqLw0KICAgIH0NCiAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyhfUHlVbmljb2RlX0Vhc3RBc2lhbldpZHRoTmFtZXNbaW5kZXhdKTsNCn0NCg0KUHlEb2NfU1RSVkFSKHVuaWNvZGVkYXRhX2RlY29tcG9zaXRpb25fX2RvY19fLA0KImRlY29tcG9zaXRpb24odW5pY2hyKVxuXA0KXG5cDQpSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgZGVjb21wb3NpdGlvbiBtYXBwaW5nIGFzc2lnbmVkIHRvIHRoZSBVbmljb2RlXG5cDQpjaGFyYWN0ZXIgdW5pY2hyIGFzIHN0cmluZy4gQW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkIGluIGNhc2Ugbm9cblwNCnN1Y2ggbWFwcGluZyBpcyBkZWZpbmVkLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QgKg0KdW5pY29kZWRhdGFfZGVjb21wb3NpdGlvbihQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpDQp7DQogICAgUHlVbmljb2RlT2JqZWN0ICp2Ow0KICAgIGNoYXIgZGVjb21wWzI1Nl07DQogICAgaW50IGNvZGUsIGluZGV4LCBjb3VudCwgaTsNCiAgICB1bnNpZ25lZCBpbnQgcHJlZml4X2luZGV4Ow0KICAgIFB5X1VDUzQgYzsNCg0KICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyE6ZGVjb21wb3NpdGlvbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICZQeVVuaWNvZGVfVHlwZSwgJnYpKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KDQogICAgY29kZSA9IChpbnQpYzsNCg0KICAgIGlmIChzZWxmKSB7DQogICAgICAgIGNvbnN0IGNoYW5nZV9yZWNvcmQgKm9sZCA9IGdldF9vbGRfcmVjb3JkKHNlbGYsIGMpOw0KICAgICAgICBpZiAob2xkLT5jYXRlZ29yeV9jaGFuZ2VkID09IDApDQogICAgICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiIik7IC8qIHVuYXNzaWduZWQgKi8NCiAgICB9DQoNCiAgICBpZiAoY29kZSA8IDAgfHwgY29kZSA+PSAweDExMDAwMCkNCiAgICAgICAgaW5kZXggPSAwOw0KICAgIGVsc2Ugew0KICAgICAgICBpbmRleCA9IGRlY29tcF9pbmRleDFbKGNvZGU+PkRFQ09NUF9TSElGVCldOw0KICAgICAgICBpbmRleCA9IGRlY29tcF9pbmRleDJbKGluZGV4PDxERUNPTVBfU0hJRlQpKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29kZSYoKDE8PERFQ09NUF9TSElGVCktMSkpXTsNCiAgICB9DQoNCiAgICAvKiBoaWdoIGJ5dGUgaXMgbnVtYmVyIG9mIGhleCBieXRlcyAodXN1YWxseSBvbmUgb3IgdHdvKSwgbG93IGJ5dGUNCiAgICAgICBpcyBwcmVmaXggY29kZSAoZnJvbSovDQogICAgY291bnQgPSBkZWNvbXBfZGF0YVtpbmRleF0gPj4gODsNCg0KICAgIC8qIFhYWDogY291bGQgYWxsb2NhdGUgdGhlIFB5U3RyaW5nIHVwIGZyb250IGluc3RlYWQNCiAgICAgICAoc3RybGVuKHByZWZpeCkgKyA1ICogY291bnQgKyAxIGJ5dGVzKSAqLw0KDQogICAgLyogQmFzZWQgb24gaG93IGluZGV4IGlzIGNhbGN1bGF0ZWQgYWJvdmUgYW5kIGRlY29tcF9kYXRhIGlzIGdlbmVyYXRlZA0KICAgICAgIGZyb20gVG9vbHMvdW5pY29kZS9tYWtldW5pY29kZWRhdGEucHksIGl0IHNob3VsZCBub3QgYmUgcG9zc2libGUNCiAgICAgICB0byBvdmVyZmxvdyBkZWNvbXBfcHJlZml4LiAqLw0KICAgIHByZWZpeF9pbmRleCA9IGRlY29tcF9kYXRhW2luZGV4XSAmIDI1NTsNCiAgICBhc3NlcnQocHJlZml4X2luZGV4IDwgKHNpemVvZihkZWNvbXBfcHJlZml4KS9zaXplb2YoKmRlY29tcF9wcmVmaXgpKSk7DQoNCiAgICAvKiBjb3B5IHByZWZpeCAqLw0KICAgIGkgPSBzdHJsZW4oZGVjb21wX3ByZWZpeFtwcmVmaXhfaW5kZXhdKTsNCiAgICBtZW1jcHkoZGVjb21wLCBkZWNvbXBfcHJlZml4W3ByZWZpeF9pbmRleF0sIGkpOw0KDQogICAgd2hpbGUgKGNvdW50LS0gPiAwKSB7DQogICAgICAgIGlmIChpKQ0KICAgICAgICAgICAgZGVjb21wW2krK10gPSAnICc7DQogICAgICAgIGFzc2VydCgoc2l6ZV90KWkgPCBzaXplb2YoZGVjb21wKSk7DQogICAgICAgIFB5T1Nfc25wcmludGYoZGVjb21wICsgaSwgc2l6ZW9mKGRlY29tcCkgLSBpLCAiJTA0WCIsDQogICAgICAgICAgICAgICAgICAgICAgZGVjb21wX2RhdGFbKytpbmRleF0pOw0KICAgICAgICBpICs9IHN0cmxlbihkZWNvbXAgKyBpKTsNCiAgICB9DQoNCiAgICBkZWNvbXBbaV0gPSAnXDAnOw0KDQogICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmcoZGVjb21wKTsNCn0NCg0Kc3RhdGljIHZvaWQNCmdldF9kZWNvbXBfcmVjb3JkKFB5T2JqZWN0ICpzZWxmLCBQeV9VQ1M0IGNvZGUsIGludCAqaW5kZXgsIGludCAqcHJlZml4LCBpbnQgKmNvdW50KQ0Kew0KICAgIGlmIChjb2RlID49IDB4MTEwMDAwKSB7DQogICAgICAgICppbmRleCA9IDA7DQogICAgfSBlbHNlIGlmIChzZWxmICYmIGdldF9vbGRfcmVjb3JkKHNlbGYsIGNvZGUpLT5jYXRlZ29yeV9jaGFuZ2VkPT0wKSB7DQogICAgICAgIC8qIHVuYXNzaWduZWQgaW4gb2xkIHZlcnNpb24gKi8NCiAgICAgICAgKmluZGV4ID0gMDsNCiAgICB9DQogICAgZWxzZSB7DQogICAgICAgICppbmRleCA9IGRlY29tcF9pbmRleDFbKGNvZGU+PkRFQ09NUF9TSElGVCldOw0KICAgICAgICAqaW5kZXggPSBkZWNvbXBfaW5kZXgyWygqaW5kZXg8PERFQ09NUF9TSElGVCkrDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvZGUmKCgxPDxERUNPTVBfU0hJRlQpLTEpKV07DQogICAgfQ0KDQogICAgLyogaGlnaCBieXRlIGlzIG51bWJlciBvZiBoZXggYnl0ZXMgKHVzdWFsbHkgb25lIG9yIHR3byksIGxvdyBieXRlDQogICAgICAgaXMgcHJlZml4IGNvZGUgKGZyb20qLw0KICAgICpjb3VudCA9IGRlY29tcF9kYXRhWyppbmRleF0gPj4gODsNCiAgICAqcHJlZml4ID0gZGVjb21wX2RhdGFbKmluZGV4XSAmIDI1NTsNCg0KICAgICgqaW5kZXgpKys7DQp9DQoNCiNkZWZpbmUgU0Jhc2UgICAweEFDMDANCiNkZWZpbmUgTEJhc2UgICAweDExMDANCiNkZWZpbmUgVkJhc2UgICAweDExNjENCiNkZWZpbmUgVEJhc2UgICAweDExQTcNCiNkZWZpbmUgTENvdW50ICAxOQ0KI2RlZmluZSBWQ291bnQgIDIxDQojZGVmaW5lIFRDb3VudCAgMjgNCiNkZWZpbmUgTkNvdW50ICAoVkNvdW50KlRDb3VudCkNCiNkZWZpbmUgU0NvdW50ICAoTENvdW50Kk5Db3VudCkNCg0Kc3RhdGljIFB5T2JqZWN0Kg0KbmZkX25ma2QoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICppbnB1dCwgaW50IGspDQp7DQogICAgUHlPYmplY3QgKnJlc3VsdDsNCiAgICBQeV9VTklDT0RFICppLCAqZW5kLCAqbzsNCiAgICAvKiBMb25nZXN0IGRlY29tcG9zaXRpb24gaW4gVW5pY29kZSAzLjI6IFUrRkRGQSAqLw0KICAgIFB5X1VOSUNPREUgc3RhY2tbMjBdOw0KICAgIFB5X3NzaXplX3Qgc3BhY2UsIGlzaXplOw0KICAgIGludCBpbmRleCwgcHJlZml4LCBjb3VudCwgc3RhY2twdHI7DQogICAgdW5zaWduZWQgY2hhciBwcmV2LCBjdXI7DQoNCiAgICBzdGFja3B0ciA9IDA7DQogICAgaXNpemUgPSBQeVVuaWNvZGVfR0VUX1NJWkUoaW5wdXQpOw0KICAgIHNwYWNlID0gaXNpemU7DQogICAgLyogT3ZlcmFsbG9jYXRlIGF0IG1vc3QgMTAgY2hhcmFjdGVycy4gKi8NCiAgICBpZiAoc3BhY2UgPiAxMCkgew0KICAgICAgICBpZiAoc3BhY2UgPD0gUFlfU1NJWkVfVF9NQVggLSAxMCkNCiAgICAgICAgICAgIHNwYWNlICs9IDEwOw0KICAgIH0NCiAgICBlbHNlIHsNCiAgICAgICAgc3BhY2UgKj0gMjsNCiAgICB9DQogICAgcmVzdWx0ID0gUHlVbmljb2RlX0Zyb21Vbmljb2RlKE5VTEwsIHNwYWNlKTsNCiAgICBpZiAoIXJlc3VsdCkNCiAgICAgICAgcmV0dXJuIE5VTEw7DQogICAgaSA9IFB5VW5pY29kZV9BU19VTklDT0RFKGlucHV0KTsNCiAgICBlbmQgPSBpICsgaXNpemU7DQogICAgbyA9IFB5VW5pY29kZV9BU19VTklDT0RFKHJlc3VsdCk7DQoNCiAgICB3aGlsZSAoaSA8IGVuZCkgew0KICAgICAgICBzdGFja1tzdGFja3B0cisrXSA9ICppKys7DQogICAgICAgIHdoaWxlKHN0YWNrcHRyKSB7DQogICAgICAgICAgICBQeV9VTklDT0RFIGNvZGUgPSBzdGFja1stLXN0YWNrcHRyXTsNCiAgICAgICAgICAgIC8qIEhhbmd1bCBEZWNvbXBvc2l0aW9uIGFkZHMgdGhyZWUgY2hhcmFjdGVycyBpbg0KICAgICAgICAgICAgICAgYSBzaW5nbGUgc3RlcCwgc28gd2UgbmVlZCBhdCBsZWFzdCB0aGF0IG11Y2ggcm9vbS4gKi8NCiAgICAgICAgICAgIGlmIChzcGFjZSA8IDMpIHsNCiAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IG5ld3NpemUgPSBQeVN0cmluZ19HRVRfU0laRShyZXN1bHQpICsgMTA7DQogICAgICAgICAgICAgICAgc3BhY2UgKz0gMTA7DQogICAgICAgICAgICAgICAgaWYgKFB5VW5pY29kZV9SZXNpemUoJnJlc3VsdCwgbmV3c2l6ZSkgPT0gLTEpDQogICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOw0KICAgICAgICAgICAgICAgIG8gPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShyZXN1bHQpICsgbmV3c2l6ZSAtIHNwYWNlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgLyogSGFuZ3VsIERlY29tcG9zaXRpb24uICovDQogICAgICAgICAgICBpZiAoU0Jhc2UgPD0gY29kZSAmJiBjb2RlIDwgKFNCYXNlK1NDb3VudCkpIHsNCiAgICAgICAgICAgICAgICBpbnQgU0luZGV4ID0gY29kZSAtIFNCYXNlOw0KICAgICAgICAgICAgICAgIGludCBMID0gTEJhc2UgKyBTSW5kZXggLyBOQ291bnQ7DQogICAgICAgICAgICAgICAgaW50IFYgPSBWQmFzZSArIChTSW5kZXggJSBOQ291bnQpIC8gVENvdW50Ow0KICAgICAgICAgICAgICAgIGludCBUID0gVEJhc2UgKyBTSW5kZXggJSBUQ291bnQ7DQogICAgICAgICAgICAgICAgKm8rKyA9IEw7DQogICAgICAgICAgICAgICAgKm8rKyA9IFY7DQogICAgICAgICAgICAgICAgc3BhY2UgLT0gMjsNCiAgICAgICAgICAgICAgICBpZiAoVCAhPSBUQmFzZSkgew0KICAgICAgICAgICAgICAgICAgICAqbysrID0gVDsNCiAgICAgICAgICAgICAgICAgICAgc3BhY2UgLS07DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgLyogbm9ybWFsaXphdGlvbiBjaGFuZ2VzICovDQogICAgICAgICAgICBpZiAoc2VsZikgew0KICAgICAgICAgICAgICAgIFB5X1VDUzQgdmFsdWUgPSAoKFByZXZpb3VzREJWZXJzaW9uKilzZWxmKS0+bm9ybWFsaXphdGlvbihjb2RlKTsNCiAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gMCkgew0KICAgICAgICAgICAgICAgICAgICBzdGFja1tzdGFja3B0cisrXSA9IHZhbHVlOw0KICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8qIE90aGVyIGRlY29tcG9zaXRpb25zLiAqLw0KICAgICAgICAgICAgZ2V0X2RlY29tcF9yZWNvcmQoc2VsZiwgY29kZSwgJmluZGV4LCAmcHJlZml4LCAmY291bnQpOw0KDQogICAgICAgICAgICAvKiBDb3B5IGNoYXJhY3RlciBpZiBpdCBpcyBub3QgZGVjb21wb3NhYmxlLCBvciBoYXMgYQ0KICAgICAgICAgICAgICAgY29tcGF0aWJpbGl0eSBkZWNvbXBvc2l0aW9uLCBidXQgd2UgZG8gTkZELiAqLw0KICAgICAgICAgICAgaWYgKCFjb3VudCB8fCAocHJlZml4ICYmICFrKSkgew0KICAgICAgICAgICAgICAgICpvKysgPSBjb2RlOw0KICAgICAgICAgICAgICAgIHNwYWNlLS07DQogICAgICAgICAgICAgICAgY29udGludWU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICAvKiBDb3B5IGRlY29tcG9zaXRpb24gb250byB0aGUgc3RhY2ssIGluIHJldmVyc2UNCiAgICAgICAgICAgICAgIG9yZGVyLiAgKi8NCiAgICAgICAgICAgIHdoaWxlKGNvdW50KSB7DQogICAgICAgICAgICAgICAgY29kZSA9IGRlY29tcF9kYXRhW2luZGV4ICsgKC0tY291bnQpXTsNCiAgICAgICAgICAgICAgICBzdGFja1tzdGFja3B0cisrXSA9IGNvZGU7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvKiBEcm9wIG92ZXJhbGxvY2F0aW9uLiBDYW5ub3QgZmFpbC4gKi8NCiAgICBQeVVuaWNvZGVfUmVzaXplKCZyZXN1bHQsIFB5VW5pY29kZV9HRVRfU0laRShyZXN1bHQpIC0gc3BhY2UpOw0KDQogICAgLyogU29ydCBjYW5vbmljYWxseS4gKi8NCiAgICBpID0gUHlVbmljb2RlX0FTX1VOSUNPREUocmVzdWx0KTsNCiAgICBwcmV2ID0gX2dldHJlY29yZF9leCgqaSktPmNvbWJpbmluZzsNCiAgICBlbmQgPSBpICsgUHlVbmljb2RlX0dFVF9TSVpFKHJlc3VsdCk7DQogICAgZm9yIChpKys7IGkgPCBlbmQ7IGkrKykgew0KICAgICAgICBjdXIgPSBfZ2V0cmVjb3JkX2V4KCppKS0+Y29tYmluaW5nOw0KICAgICAgICBpZiAocHJldiA9PSAwIHx8IGN1ciA9PSAwIHx8IHByZXYgPD0gY3VyKSB7DQogICAgICAgICAgICBwcmV2ID0gY3VyOw0KICAgICAgICAgICAgY29udGludWU7DQogICAgICAgIH0NCiAgICAgICAgLyogTm9uLWNhbm9uaWNhbCBvcmRlci4gTmVlZCB0byBzd2l0Y2ggKmkgd2l0aCBwcmV2aW91cy4gKi8NCiAgICAgICAgbyA9IGkgLSAxOw0KICAgICAgICB3aGlsZSAoMSkgew0KICAgICAgICAgICAgUHlfVU5JQ09ERSB0bXAgPSBvWzFdOw0KICAgICAgICAgICAgb1sxXSA9IG9bMF07DQogICAgICAgICAgICBvWzBdID0gdG1wOw0KICAgICAgICAgICAgby0tOw0KICAgICAgICAgICAgaWYgKG8gPCBQeVVuaWNvZGVfQVNfVU5JQ09ERShyZXN1bHQpKQ0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgcHJldiA9IF9nZXRyZWNvcmRfZXgoKm8pLT5jb21iaW5pbmc7DQogICAgICAgICAgICBpZiAocHJldiA9PSAwIHx8IHByZXYgPD0gY3VyKQ0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICB9DQogICAgICAgIHByZXYgPSBfZ2V0cmVjb3JkX2V4KCppKS0+Y29tYmluaW5nOw0KICAgIH0NCiAgICByZXR1cm4gcmVzdWx0Ow0KfQ0KDQpzdGF0aWMgaW50DQpmaW5kX25mY19pbmRleChQeU9iamVjdCAqc2VsZiwgc3RydWN0IHJlaW5kZXgqIG5mYywgUHlfVU5JQ09ERSBjb2RlKQ0Kew0KICAgIGludCBpbmRleDsNCiAgICBmb3IgKGluZGV4ID0gMDsgbmZjW2luZGV4XS5zdGFydDsgaW5kZXgrKykgew0KICAgICAgICBpbnQgc3RhcnQgPSBuZmNbaW5kZXhdLnN0YXJ0Ow0KICAgICAgICBpZiAoY29kZSA8IHN0YXJ0KQ0KICAgICAgICAgICAgcmV0dXJuIC0xOw0KICAgICAgICBpZiAoY29kZSA8PSBzdGFydCArIG5mY1tpbmRleF0uY291bnQpIHsNCiAgICAgICAgICAgIGludCBkZWx0YSA9IGNvZGUgLSBzdGFydDsNCiAgICAgICAgICAgIHJldHVybiBuZmNbaW5kZXhdLmluZGV4ICsgZGVsdGE7DQogICAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuIC0xOw0KfQ0KDQpzdGF0aWMgUHlPYmplY3QqDQpuZmNfbmZrYyhQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmlucHV0LCBpbnQgaykNCnsNCiAgICBQeU9iamVjdCAqcmVzdWx0Ow0KICAgIFB5X1VOSUNPREUgKmksICppMSwgKm8sICplbmQ7DQogICAgaW50IGYsbCxpbmRleCxpbmRleDEsY29tYjsNCiAgICBQeV9VTklDT0RFIGNvZGU7DQogICAgUHlfVU5JQ09ERSAqc2tpcHBlZFsyMF07DQogICAgaW50IGNza2lwcGVkID0gMDsNCg0KICAgIHJlc3VsdCA9IG5mZF9uZmtkKHNlbGYsIGlucHV0LCBrKTsNCiAgICBpZiAoIXJlc3VsdCkNCiAgICAgICAgcmV0dXJuIE5VTEw7DQoNCiAgICAvKiBXZSBhcmUgZ29pbmcgdG8gbW9kaWZ5IHJlc3VsdCBpbi1wbGFjZS4NCiAgICAgICBJZiBuZmRfbmZrZCBpcyBjaGFuZ2VkIHRvIHNvbWV0aW1lcyByZXR1cm4gdGhlIGlucHV0LA0KICAgICAgIHRoaXMgY29kZSBuZWVkcyB0byBiZSByZXZpZXdlZC4gKi8NCiAgICBhc3NlcnQocmVzdWx0ICE9IGlucHV0KTsNCg0KICAgIGkgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShyZXN1bHQpOw0KICAgIGVuZCA9IGkgKyBQeVVuaWNvZGVfR0VUX1NJWkUocmVzdWx0KTsNCiAgICBvID0gUHlVbmljb2RlX0FTX1VOSUNPREUocmVzdWx0KTsNCg0KICBhZ2FpbjoNCiAgICB3aGlsZSAoaSA8IGVuZCkgew0KICAgICAgZm9yIChpbmRleCA9IDA7IGluZGV4IDwgY3NraXBwZWQ7IGluZGV4KyspIHsNCiAgICAgICAgICBpZiAoc2tpcHBlZFtpbmRleF0gPT0gaSkgew0KICAgICAgICAgICAgICAvKiAqaSBjaGFyYWN0ZXIgaXMgc2tpcHBlZC4NCiAgICAgICAgICAgICAgICAgUmVtb3ZlIGZyb20gbGlzdC4gKi8NCiAgICAgICAgICAgICAgc2tpcHBlZFtpbmRleF0gPSBza2lwcGVkW2Nza2lwcGVkLTFdOw0KICAgICAgICAgICAgICBjc2tpcHBlZC0tOw0KICAgICAgICAgICAgICBpKys7DQogICAgICAgICAgICAgIGdvdG8gYWdhaW47IC8qIGNvbnRpbnVlIHdoaWxlICovDQogICAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgLyogSGFuZ3VsIENvbXBvc2l0aW9uLiBXZSBkb24ndCBuZWVkIHRvIGNoZWNrIGZvciA8TFYsVD4NCiAgICAgICAgIHBhaXJzLCBzaW5jZSB3ZSBhbHdheXMgaGF2ZSBkZWNvbXBvc2VkIGRhdGEuICovDQogICAgICBpZiAoTEJhc2UgPD0gKmkgJiYgKmkgPCAoTEJhc2UrTENvdW50KSAmJg0KICAgICAgICAgIGkgKyAxIDwgZW5kICYmDQogICAgICAgICAgVkJhc2UgPD0gaVsxXSAmJiBpWzFdIDw9IChWQmFzZStWQ291bnQpKSB7DQogICAgICAgICAgaW50IExJbmRleCwgVkluZGV4Ow0KICAgICAgICAgIExJbmRleCA9IGlbMF0gLSBMQmFzZTsNCiAgICAgICAgICBWSW5kZXggPSBpWzFdIC0gVkJhc2U7DQogICAgICAgICAgY29kZSA9IFNCYXNlICsgKExJbmRleCpWQ291bnQrVkluZGV4KSpUQ291bnQ7DQogICAgICAgICAgaSs9MjsNCiAgICAgICAgICBpZiAoaSA8IGVuZCAmJg0KICAgICAgICAgICAgICBUQmFzZSA8PSAqaSAmJiAqaSA8PSAoVEJhc2UrVENvdW50KSkgew0KICAgICAgICAgICAgICBjb2RlICs9ICppLVRCYXNlOw0KICAgICAgICAgICAgICBpKys7DQogICAgICAgICAgfQ0KICAgICAgICAgICpvKysgPSBjb2RlOw0KICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KDQogICAgICBmID0gZmluZF9uZmNfaW5kZXgoc2VsZiwgbmZjX2ZpcnN0LCAqaSk7DQogICAgICBpZiAoZiA9PSAtMSkgew0KICAgICAgICAgICpvKysgPSAqaSsrOw0KICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgfQ0KICAgICAgLyogRmluZCBuZXh0IHVuYmxvY2tlZCBjaGFyYWN0ZXIuICovDQogICAgICBpMSA9IGkrMTsNCiAgICAgIGNvbWIgPSAwOw0KICAgICAgd2hpbGUgKGkxIDwgZW5kKSB7DQogICAgICAgICAgaW50IGNvbWIxID0gX2dldHJlY29yZF9leCgqaTEpLT5jb21iaW5pbmc7DQogICAgICAgICAgaWYgKGNvbWIpIHsNCiAgICAgICAgICAgICAgaWYgKGNvbWIxID09IDApDQogICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgaWYgKGNvbWIgPj0gY29tYjEpIHsNCiAgICAgICAgICAgICAgICAgIC8qIENoYXJhY3RlciBpcyBibG9ja2VkLiAqLw0KICAgICAgICAgICAgICAgICAgaTErKzsNCiAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICAgIGwgPSBmaW5kX25mY19pbmRleChzZWxmLCBuZmNfbGFzdCwgKmkxKTsNCiAgICAgICAgICAvKiAqaTEgY2Fubm90IGJlIGNvbWJpbmVkIHdpdGggKmkuIElmICppMQ0KICAgICAgICAgICAgIGlzIGEgc3RhcnRlciwgd2UgZG9uJ3QgbmVlZCB0byBsb29rIGZ1cnRoZXIuDQogICAgICAgICAgICAgT3RoZXJ3aXNlLCByZWNvcmQgdGhlIGNvbWJpbmluZyBjbGFzcy4gKi8NCiAgICAgICAgICBpZiAobCA9PSAtMSkgew0KICAgICAgICAgICAgbm90X2NvbWJpbmFibGU6DQogICAgICAgICAgICAgIGlmIChjb21iMSA9PSAwKQ0KICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgIGNvbWIgPSBjb21iMTsNCiAgICAgICAgICAgICAgaTErKzsNCiAgICAgICAgICAgICAgY29udGludWU7DQogICAgICAgICAgfQ0KICAgICAgICAgIGluZGV4ID0gZipUT1RBTF9MQVNUICsgbDsNCiAgICAgICAgICBpbmRleDEgPSBjb21wX2luZGV4W2luZGV4ID4+IENPTVBfU0hJRlRdOw0KICAgICAgICAgIGNvZGUgPSBjb21wX2RhdGFbKGluZGV4MTw8Q09NUF9TSElGVCkrDQogICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5kZXgmKCgxPDxDT01QX1NISUZUKS0xKSldOw0KICAgICAgICAgIGlmIChjb2RlID09IDApDQogICAgICAgICAgICAgIGdvdG8gbm90X2NvbWJpbmFibGU7DQoNCiAgICAgICAgICAvKiBSZXBsYWNlIHRoZSBvcmlnaW5hbCBjaGFyYWN0ZXIuICovDQogICAgICAgICAgKmkgPSBjb2RlOw0KICAgICAgICAgIC8qIE1hcmsgdGhlIHNlY29uZCBjaGFyYWN0ZXIgdW51c2VkLiAqLw0KICAgICAgICAgIGFzc2VydChjc2tpcHBlZCA8IDIwKTsNCiAgICAgICAgICBza2lwcGVkW2Nza2lwcGVkKytdID0gaTE7DQogICAgICAgICAgaTErKzsNCiAgICAgICAgICBmID0gZmluZF9uZmNfaW5kZXgoc2VsZiwgbmZjX2ZpcnN0LCAqaSk7DQogICAgICAgICAgaWYgKGYgPT0gLTEpDQogICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgfQ0KICAgICAgKm8rKyA9ICppKys7DQogICAgfQ0KICAgIGlmIChvICE9IGVuZCkNCiAgICAgICAgUHlVbmljb2RlX1Jlc2l6ZSgmcmVzdWx0LCBvIC0gUHlVbmljb2RlX0FTX1VOSUNPREUocmVzdWx0KSk7DQogICAgcmV0dXJuIHJlc3VsdDsNCn0NCg0KLyogUmV0dXJuIDEgaWYgdGhlIGlucHV0IGlzIGNlcnRhaW5seSBub3JtYWxpemVkLCAwIGlmIGl0IG1pZ2h0IG5vdCBiZS4gKi8NCnN0YXRpYyBpbnQNCmlzX25vcm1hbGl6ZWQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICppbnB1dCwgaW50IG5mYywgaW50IGspDQp7DQogICAgUHlfVU5JQ09ERSAqaSwgKmVuZDsNCiAgICB1bnNpZ25lZCBjaGFyIHByZXZfY29tYmluaW5nID0gMCwgcXVpY2tjaGVja19tYXNrOw0KDQogICAgLyogQW4gb2xkZXIgdmVyc2lvbiBvZiB0aGUgZGF0YWJhc2UgaXMgcmVxdWVzdGVkLCBxdWlja2NoZWNrcyBtdXN0IGJlDQogICAgICAgZGlzYWJsZWQuICovDQogICAgaWYgKHNlbGYgIT0gTlVMTCkNCiAgICAgICAgcmV0dXJuIDA7DQoNCiAgICAvKiBUaGUgdHdvIHF1aWNrY2hlY2sgYml0cyBhdCB0aGlzIHNoaWZ0IG1lYW4gMD1ZZXMsIDE9TWF5YmUsIDI9Tm8sDQogICAgICAgYXMgZGVzY3JpYmVkIGluIGh0dHA6Ly91bmljb2RlLm9yZy9yZXBvcnRzL3RyMTUvI0FubmV4OC4gKi8NCiAgICBxdWlja2NoZWNrX21hc2sgPSAzIDw8ICgobmZjID8gNCA6IDApICsgKGsgPyAyIDogMCkpOw0KDQogICAgaSA9IFB5VW5pY29kZV9BU19VTklDT0RFKGlucHV0KTsNCiAgICBlbmQgPSBpICsgUHlVbmljb2RlX0dFVF9TSVpFKGlucHV0KTsNCiAgICB3aGlsZSAoaSA8IGVuZCkgew0KICAgICAgICBjb25zdCBfUHlVbmljb2RlX0RhdGFiYXNlUmVjb3JkICpyZWNvcmQgPSBfZ2V0cmVjb3JkX2V4KCppKyspOw0KICAgICAgICB1bnNpZ25lZCBjaGFyIGNvbWJpbmluZyA9IHJlY29yZC0+Y29tYmluaW5nOw0KICAgICAgICB1bnNpZ25lZCBjaGFyIHF1aWNrY2hlY2sgPSByZWNvcmQtPm5vcm1hbGl6YXRpb25fcXVpY2tfY2hlY2s7DQoNCiAgICAgICAgaWYgKHF1aWNrY2hlY2sgJiBxdWlja2NoZWNrX21hc2spDQogICAgICAgICAgICByZXR1cm4gMDsgLyogdGhpcyBzdHJpbmcgbWlnaHQgbmVlZCBub3JtYWxpemF0aW9uICovDQogICAgICAgIGlmIChjb21iaW5pbmcgJiYgcHJldl9jb21iaW5pbmcgPiBjb21iaW5pbmcpDQogICAgICAgICAgICByZXR1cm4gMDsgLyogbm9uLWNhbm9uaWNhbCBzb3J0IG9yZGVyLCBub3Qgbm9ybWFsaXplZCAqLw0KICAgICAgICBwcmV2X2NvbWJpbmluZyA9IGNvbWJpbmluZzsNCiAgICB9DQogICAgcmV0dXJuIDE7IC8qIGNlcnRhaW5seSBub3JtYWxpemVkICovDQp9DQoNClB5RG9jX1NUUlZBUih1bmljb2RlZGF0YV9ub3JtYWxpemVfX2RvY19fLA0KIm5vcm1hbGl6ZShmb3JtLCB1bmlzdHIpXG5cDQpcblwNClJldHVybiB0aGUgbm9ybWFsIGZvcm0gJ2Zvcm0nIGZvciB0aGUgVW5pY29kZSBzdHJpbmcgdW5pc3RyLiAgVmFsaWRcblwNCnZhbHVlcyBmb3IgZm9ybSBhcmUgJ05GQycsICdORktDJywgJ05GRCcsIGFuZCAnTkZLRCcuIik7DQoNCnN0YXRpYyBQeU9iamVjdCoNCnVuaWNvZGVkYXRhX25vcm1hbGl6ZShQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpDQp7DQogICAgY2hhciAqZm9ybTsNCiAgICBQeU9iamVjdCAqaW5wdXQ7DQoNCiAgICBpZighUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAic08hOm5vcm1hbGl6ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgJmZvcm0sICZQeVVuaWNvZGVfVHlwZSwgJmlucHV0KSkNCiAgICAgICAgcmV0dXJuIE5VTEw7DQoNCiAgICBpZiAoUHlVbmljb2RlX0dldFNpemUoaW5wdXQpID09IDApIHsNCiAgICAgICAgLyogU3BlY2lhbCBjYXNlIGVtcHR5IGlucHV0IHN0cmluZ3MsIHNpbmNlIHJlc2l6aW5nDQogICAgICAgICAgIHRoZW0gIGxhdGVyIHdvdWxkIGNhdXNlIGludGVybmFsIGVycm9ycy4gKi8NCiAgICAgICAgUHlfSU5DUkVGKGlucHV0KTsNCiAgICAgICAgcmV0dXJuIGlucHV0Ow0KICAgIH0NCg0KICAgIGlmIChzdHJjbXAoZm9ybSwgIk5GQyIpID09IDApIHsNCiAgICAgICAgaWYgKGlzX25vcm1hbGl6ZWQoc2VsZiwgaW5wdXQsIDEsIDApKSB7DQogICAgICAgICAgICBQeV9JTkNSRUYoaW5wdXQpOw0KICAgICAgICAgICAgcmV0dXJuIGlucHV0Ow0KICAgICAgICB9DQogICAgICAgIHJldHVybiBuZmNfbmZrYyhzZWxmLCBpbnB1dCwgMCk7DQogICAgfQ0KICAgIGlmIChzdHJjbXAoZm9ybSwgIk5GS0MiKSA9PSAwKSB7DQogICAgICAgIGlmIChpc19ub3JtYWxpemVkKHNlbGYsIGlucHV0LCAxLCAxKSkgew0KICAgICAgICAgICAgUHlfSU5DUkVGKGlucHV0KTsNCiAgICAgICAgICAgIHJldHVybiBpbnB1dDsNCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gbmZjX25ma2Moc2VsZiwgaW5wdXQsIDEpOw0KICAgIH0NCiAgICBpZiAoc3RyY21wKGZvcm0sICJORkQiKSA9PSAwKSB7DQogICAgICAgIGlmIChpc19ub3JtYWxpemVkKHNlbGYsIGlucHV0LCAwLCAwKSkgew0KICAgICAgICAgICAgUHlfSU5DUkVGKGlucHV0KTsNCiAgICAgICAgICAgIHJldHVybiBpbnB1dDsNCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gbmZkX25ma2Qoc2VsZiwgaW5wdXQsIDApOw0KICAgIH0NCiAgICBpZiAoc3RyY21wKGZvcm0sICJORktEIikgPT0gMCkgew0KICAgICAgICBpZiAoaXNfbm9ybWFsaXplZChzZWxmLCBpbnB1dCwgMCwgMSkpIHsNCiAgICAgICAgICAgIFB5X0lOQ1JFRihpbnB1dCk7DQogICAgICAgICAgICByZXR1cm4gaW5wdXQ7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIG5mZF9uZmtkKHNlbGYsIGlucHV0LCAxKTsNCiAgICB9DQogICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJpbnZhbGlkIG5vcm1hbGl6YXRpb24gZm9ybSIpOw0KICAgIHJldHVybiBOVUxMOw0KfQ0KDQovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLyogdW5pY29kZSBjaGFyYWN0ZXIgbmFtZSB0YWJsZXMgKi8NCg0KLyogZGF0YSBmaWxlIGdlbmVyYXRlZCBieSBUb29scy91bmljb2RlL21ha2V1bmljb2RlZGF0YS5weSAqLw0KI2luY2x1ZGUgInVuaWNvZGVuYW1lX2RiLmgiDQoNCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQovKiBkYXRhYmFzZSBjb2RlIChjdXQgYW5kIHBhc3RlZCBmcm9tIHRoZSB1bmlkYiBwYWNrYWdlKSAqLw0KDQpzdGF0aWMgdW5zaWduZWQgbG9uZw0KX2dldGhhc2goY29uc3QgY2hhciAqcywgaW50IGxlbiwgaW50IHNjYWxlKQ0Kew0KICAgIGludCBpOw0KICAgIHVuc2lnbmVkIGxvbmcgaCA9IDA7DQogICAgdW5zaWduZWQgbG9uZyBpeDsNCiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsNCiAgICAgICAgaCA9IChoICogc2NhbGUpICsgKHVuc2lnbmVkIGNoYXIpIFB5X1RPVVBQRVIoUHlfQ0hBUk1BU0soc1tpXSkpOw0KICAgICAgICBpeCA9IGggJiAweGZmMDAwMDAwOw0KICAgICAgICBpZiAoaXgpDQogICAgICAgICAgICBoID0gKGggXiAoKGl4Pj4yNCkgJiAweGZmKSkgJiAweDAwZmZmZmZmOw0KICAgIH0NCiAgICByZXR1cm4gaDsNCn0NCg0Kc3RhdGljIGNoYXIgKmhhbmd1bF9zeWxsYWJsZXNbXVszXSA9IHsNCiAgICB7ICJHIiwgICJBIiwgICAiIiAgIH0sDQogICAgeyAiR0ciLCAiQUUiLCAgIkciICB9LA0KICAgIHsgIk4iLCAgIllBIiwgICJHRyIgfSwNCiAgICB7ICJEIiwgICJZQUUiLCAiR1MiIH0sDQogICAgeyAiREQiLCAiRU8iLCAgIk4iLCB9LA0KICAgIHsgIlIiLCAgIkUiLCAgICJOSiIgfSwNCiAgICB7ICJNIiwgICJZRU8iLCAiTkgiIH0sDQogICAgeyAiQiIsICAiWUUiLCAgIkQiICB9LA0KICAgIHsgIkJCIiwgIk8iLCAgICJMIiAgfSwNCiAgICB7ICJTIiwgICJXQSIsICAiTEciIH0sDQogICAgeyAiU1MiLCAiV0FFIiwgIkxNIiB9LA0KICAgIHsgIiIsICAgIk9FIiwgICJMQiIgfSwNCiAgICB7ICJKIiwgICJZTyIsICAiTFMiIH0sDQogICAgeyAiSkoiLCAiVSIsICAgIkxUIiB9LA0KICAgIHsgIkMiLCAgIldFTyIsICJMUCIgfSwNCiAgICB7ICJLIiwgICJXRSIsICAiTEgiIH0sDQogICAgeyAiVCIsICAiV0kiLCAgIk0iICB9LA0KICAgIHsgIlAiLCAgIllVIiwgICJCIiAgfSwNCiAgICB7ICJIIiwgICJFVSIsICAiQlMiIH0sDQogICAgeyAwLCAgICAiWUkiLCAgIlMiICB9LA0KICAgIHsgMCwgICAgIkkiLCAgICJTUyIgfSwNCiAgICB7IDAsICAgIDAsICAgICAiTkciIH0sDQogICAgeyAwLCAgICAwLCAgICAgIkoiICB9LA0KICAgIHsgMCwgICAgMCwgICAgICJDIiAgfSwNCiAgICB7IDAsICAgIDAsICAgICAiSyIgIH0sDQogICAgeyAwLCAgICAwLCAgICAgIlQiICB9LA0KICAgIHsgMCwgICAgMCwgICAgICJQIiAgfSwNCiAgICB7IDAsICAgIDAsICAgICAiSCIgIH0NCn07DQoNCnN0YXRpYyBpbnQNCmlzX3VuaWZpZWRfaWRlb2dyYXBoKFB5X1VDUzQgY29kZSkNCnsNCiAgICByZXR1cm4gKA0KICAgICAgICAoMHgzNDAwIDw9IGNvZGUgJiYgY29kZSA8PSAweDREQjUpIHx8IC8qIENKSyBJZGVvZ3JhcGggRXh0ZW5zaW9uIEEgKi8NCiAgICAgICAgKDB4NEUwMCA8PSBjb2RlICYmIGNvZGUgPD0gMHg5RkNCKSB8fCAvKiBDSksgSWRlb2dyYXBoLCBVbmljb2RlIDUuMiAqLw0KICAgICAgICAoMHgyMDAwMCA8PSBjb2RlICYmIGNvZGUgPD0gMHgyQTZENikgfHwgLyogQ0pLIElkZW9ncmFwaCBFeHRlbnNpb24gQiAqLw0KICAgICAgICAoMHgyQTcwMCA8PSBjb2RlICYmIGNvZGUgPD0gMHgyQjczNCkpOyAgLyogQ0pLIElkZW9ncmFwaCBFeHRlbnNpb24gQyAqLw0KfQ0KDQpzdGF0aWMgaW50DQpfZ2V0dWNuYW1lKFB5T2JqZWN0ICpzZWxmLCBQeV9VQ1M0IGNvZGUsIGNoYXIqIGJ1ZmZlciwgaW50IGJ1ZmxlbikNCnsNCiAgICBpbnQgb2Zmc2V0Ow0KICAgIGludCBpOw0KICAgIGludCB3b3JkOw0KICAgIHVuc2lnbmVkIGNoYXIqIHc7DQoNCiAgICBpZiAoY29kZSA+PSAweDExMDAwMCkNCiAgICAgICAgcmV0dXJuIDA7DQoNCiAgICBpZiAoc2VsZikgew0KICAgICAgICBjb25zdCBjaGFuZ2VfcmVjb3JkICpvbGQgPSBnZXRfb2xkX3JlY29yZChzZWxmLCBjb2RlKTsNCiAgICAgICAgaWYgKG9sZC0+Y2F0ZWdvcnlfY2hhbmdlZCA9PSAwKSB7DQogICAgICAgICAgICAvKiB1bmFzc2lnbmVkICovDQogICAgICAgICAgICByZXR1cm4gMDsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIGlmIChTQmFzZSA8PSBjb2RlICYmIGNvZGUgPCBTQmFzZStTQ291bnQpIHsNCiAgICAgICAgLyogSGFuZ3VsIHN5bGxhYmxlLiAqLw0KICAgICAgICBpbnQgU0luZGV4ID0gY29kZSAtIFNCYXNlOw0KICAgICAgICBpbnQgTCA9IFNJbmRleCAvIE5Db3VudDsNCiAgICAgICAgaW50IFYgPSAoU0luZGV4ICUgTkNvdW50KSAvIFRDb3VudDsNCiAgICAgICAgaW50IFQgPSBTSW5kZXggJSBUQ291bnQ7DQoNCiAgICAgICAgaWYgKGJ1ZmxlbiA8IDI3KQ0KICAgICAgICAgICAgLyogV29yc3QgY2FzZTogSEFOR1VMIFNZTExBQkxFIDwxMGNoYXJzPi4gKi8NCiAgICAgICAgICAgIHJldHVybiAwOw0KICAgICAgICBzdHJjcHkoYnVmZmVyLCAiSEFOR1VMIFNZTExBQkxFICIpOw0KICAgICAgICBidWZmZXIgKz0gMTY7DQogICAgICAgIHN0cmNweShidWZmZXIsIGhhbmd1bF9zeWxsYWJsZXNbTF1bMF0pOw0KICAgICAgICBidWZmZXIgKz0gc3RybGVuKGhhbmd1bF9zeWxsYWJsZXNbTF1bMF0pOw0KICAgICAgICBzdHJjcHkoYnVmZmVyLCBoYW5ndWxfc3lsbGFibGVzW1ZdWzFdKTsNCiAgICAgICAgYnVmZmVyICs9IHN0cmxlbihoYW5ndWxfc3lsbGFibGVzW1ZdWzFdKTsNCiAgICAgICAgc3RyY3B5KGJ1ZmZlciwgaGFuZ3VsX3N5bGxhYmxlc1tUXVsyXSk7DQogICAgICAgIGJ1ZmZlciArPSBzdHJsZW4oaGFuZ3VsX3N5bGxhYmxlc1tUXVsyXSk7DQogICAgICAgICpidWZmZXIgPSAnXDAnOw0KICAgICAgICByZXR1cm4gMTsNCiAgICB9DQoNCiAgICBpZiAoaXNfdW5pZmllZF9pZGVvZ3JhcGgoY29kZSkpIHsNCiAgICAgICAgaWYgKGJ1ZmxlbiA8IDI4KQ0KICAgICAgICAgICAgLyogV29yc3QgY2FzZTogQ0pLIFVOSUZJRUQgSURFT0dSQVBILTIwMDAwICovDQogICAgICAgICAgICByZXR1cm4gMDsNCiAgICAgICAgc3ByaW50ZihidWZmZXIsICJDSksgVU5JRklFRCBJREVPR1JBUEgtJVgiLCBjb2RlKTsNCiAgICAgICAgcmV0dXJuIDE7DQogICAgfQ0KDQogICAgLyogZ2V0IG9mZnNldCBpbnRvIHBocmFzZWJvb2sgKi8NCiAgICBvZmZzZXQgPSBwaHJhc2Vib29rX29mZnNldDFbKGNvZGU+PnBocmFzZWJvb2tfc2hpZnQpXTsNCiAgICBvZmZzZXQgPSBwaHJhc2Vib29rX29mZnNldDJbKG9mZnNldDw8cGhyYXNlYm9va19zaGlmdCkgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb2RlJigoMTw8cGhyYXNlYm9va19zaGlmdCktMSkpXTsNCiAgICBpZiAoIW9mZnNldCkNCiAgICAgICAgcmV0dXJuIDA7DQoNCiAgICBpID0gMDsNCg0KICAgIGZvciAoOzspIHsNCiAgICAgICAgLyogZ2V0IHdvcmQgaW5kZXggKi8NCiAgICAgICAgd29yZCA9IHBocmFzZWJvb2tbb2Zmc2V0XSAtIHBocmFzZWJvb2tfc2hvcnQ7DQogICAgICAgIGlmICh3b3JkID49IDApIHsNCiAgICAgICAgICAgIHdvcmQgPSAod29yZCA8PCA4KSArIHBocmFzZWJvb2tbb2Zmc2V0KzFdOw0KICAgICAgICAgICAgb2Zmc2V0ICs9IDI7DQogICAgICAgIH0gZWxzZQ0KICAgICAgICAgICAgd29yZCA9IHBocmFzZWJvb2tbb2Zmc2V0KytdOw0KICAgICAgICBpZiAoaSkgew0KICAgICAgICAgICAgaWYgKGkgPiBidWZsZW4pDQogICAgICAgICAgICAgICAgcmV0dXJuIDA7IC8qIGJ1ZmZlciBvdmVyZmxvdyAqLw0KICAgICAgICAgICAgYnVmZmVyW2krK10gPSAnICc7DQogICAgICAgIH0NCiAgICAgICAgLyogY29weSB3b3JkIHN0cmluZyBmcm9tIGxleGljb24uICB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlDQogICAgICAgICAgIHdvcmQgaGFzIGJpdCA3IHNldC4gIHRoZSBsYXN0IHdvcmQgaW4gYSBzdHJpbmcgZW5kcyB3aXRoDQogICAgICAgICAgIDB4ODAgKi8NCiAgICAgICAgdyA9IGxleGljb24gKyBsZXhpY29uX29mZnNldFt3b3JkXTsNCiAgICAgICAgd2hpbGUgKCp3IDwgMTI4KSB7DQogICAgICAgICAgICBpZiAoaSA+PSBidWZsZW4pDQogICAgICAgICAgICAgICAgcmV0dXJuIDA7IC8qIGJ1ZmZlciBvdmVyZmxvdyAqLw0KICAgICAgICAgICAgYnVmZmVyW2krK10gPSAqdysrOw0KICAgICAgICB9DQogICAgICAgIGlmIChpID49IGJ1ZmxlbikNCiAgICAgICAgICAgIHJldHVybiAwOyAvKiBidWZmZXIgb3ZlcmZsb3cgKi8NCiAgICAgICAgYnVmZmVyW2krK10gPSAqdyAmIDEyNzsNCiAgICAgICAgaWYgKCp3ID09IDEyOCkNCiAgICAgICAgICAgIGJyZWFrOyAvKiBlbmQgb2Ygd29yZCAqLw0KICAgIH0NCg0KICAgIHJldHVybiAxOw0KfQ0KDQpzdGF0aWMgaW50DQpfY21wbmFtZShQeU9iamVjdCAqc2VsZiwgaW50IGNvZGUsIGNvbnN0IGNoYXIqIG5hbWUsIGludCBuYW1lbGVuKQ0Kew0KICAgIC8qIGNoZWNrIGlmIGNvZGUgY29ycmVzcG9uZHMgdG8gdGhlIGdpdmVuIG5hbWUgKi8NCiAgICBpbnQgaTsNCiAgICBjaGFyIGJ1ZmZlcltOQU1FX01BWExFTl07DQogICAgaWYgKCFfZ2V0dWNuYW1lKHNlbGYsIGNvZGUsIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpKQ0KICAgICAgICByZXR1cm4gMDsNCiAgICBmb3IgKGkgPSAwOyBpIDwgbmFtZWxlbjsgaSsrKSB7DQogICAgICAgIGlmIChQeV9UT1VQUEVSKFB5X0NIQVJNQVNLKG5hbWVbaV0pKSAhPSBidWZmZXJbaV0pDQogICAgICAgICAgICByZXR1cm4gMDsNCiAgICB9DQogICAgcmV0dXJuIGJ1ZmZlcltuYW1lbGVuXSA9PSAnXDAnOw0KfQ0KDQpzdGF0aWMgdm9pZA0KZmluZF9zeWxsYWJsZShjb25zdCBjaGFyICpzdHIsIGludCAqbGVuLCBpbnQgKnBvcywgaW50IGNvdW50LCBpbnQgY29sdW1uKQ0Kew0KICAgIGludCBpLCBsZW4xOw0KICAgICpsZW4gPSAtMTsNCiAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgew0KICAgICAgICBjaGFyICpzID0gaGFuZ3VsX3N5bGxhYmxlc1tpXVtjb2x1bW5dOw0KICAgICAgICBsZW4xID0gc3RybGVuKHMpOw0KICAgICAgICBpZiAobGVuMSA8PSAqbGVuKQ0KICAgICAgICAgICAgY29udGludWU7DQogICAgICAgIGlmIChzdHJuY21wKHN0ciwgcywgbGVuMSkgPT0gMCkgew0KICAgICAgICAgICAgKmxlbiA9IGxlbjE7DQogICAgICAgICAgICAqcG9zID0gaTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICBpZiAoKmxlbiA9PSAtMSkgew0KICAgICAgICAqbGVuID0gMDsNCiAgICB9DQp9DQoNCnN0YXRpYyBpbnQNCl9nZXRjb2RlKFB5T2JqZWN0KiBzZWxmLCBjb25zdCBjaGFyKiBuYW1lLCBpbnQgbmFtZWxlbiwgUHlfVUNTNCogY29kZSkNCnsNCiAgICB1bnNpZ25lZCBpbnQgaCwgdjsNCiAgICB1bnNpZ25lZCBpbnQgbWFzayA9IGNvZGVfc2l6ZS0xOw0KICAgIHVuc2lnbmVkIGludCBpLCBpbmNyOw0KDQogICAgLyogQ2hlY2sgZm9yIGhhbmd1bCBzeWxsYWJsZXMuICovDQogICAgaWYgKHN0cm5jbXAobmFtZSwgIkhBTkdVTCBTWUxMQUJMRSAiLCAxNikgPT0gMCkgew0KICAgICAgICBpbnQgbGVuLCBMID0gLTEsIFYgPSAtMSwgVCA9IC0xOw0KICAgICAgICBjb25zdCBjaGFyICpwb3MgPSBuYW1lICsgMTY7DQogICAgICAgIGZpbmRfc3lsbGFibGUocG9zLCAmbGVuLCAmTCwgTENvdW50LCAwKTsNCiAgICAgICAgcG9zICs9IGxlbjsNCiAgICAgICAgZmluZF9zeWxsYWJsZShwb3MsICZsZW4sICZWLCBWQ291bnQsIDEpOw0KICAgICAgICBwb3MgKz0gbGVuOw0KICAgICAgICBmaW5kX3N5bGxhYmxlKHBvcywgJmxlbiwgJlQsIFRDb3VudCwgMik7DQogICAgICAgIHBvcyArPSBsZW47DQogICAgICAgIGlmIChMICE9IC0xICYmIFYgIT0gLTEgJiYgVCAhPSAtMSAmJiBwb3MtbmFtZSA9PSBuYW1lbGVuKSB7DQogICAgICAgICAgICAqY29kZSA9IFNCYXNlICsgKEwqVkNvdW50K1YpKlRDb3VudCArIFQ7DQogICAgICAgICAgICByZXR1cm4gMTsNCiAgICAgICAgfQ0KICAgICAgICAvKiBPdGhlcndpc2UsIGl0J3MgYW4gaWxsZWdhbCBzeWxsYWJsZSBuYW1lLiAqLw0KICAgICAgICByZXR1cm4gMDsNCiAgICB9DQoNCiAgICAvKiBDaGVjayBmb3IgdW5pZmllZCBpZGVvZ3JhcGhzLiAqLw0KICAgIGlmIChzdHJuY21wKG5hbWUsICJDSksgVU5JRklFRCBJREVPR1JBUEgtIiwgMjIpID09IDApIHsNCiAgICAgICAgLyogRm91ciBvciBmaXZlIGhleGRpZ2l0cyBtdXN0IGZvbGxvdy4gKi8NCiAgICAgICAgdiA9IDA7DQogICAgICAgIG5hbWUgKz0gMjI7DQogICAgICAgIG5hbWVsZW4gLT0gMjI7DQogICAgICAgIGlmIChuYW1lbGVuICE9IDQgJiYgbmFtZWxlbiAhPSA1KQ0KICAgICAgICAgICAgcmV0dXJuIDA7DQogICAgICAgIHdoaWxlIChuYW1lbGVuLS0pIHsNCiAgICAgICAgICAgIHYgKj0gMTY7DQogICAgICAgICAgICBpZiAoKm5hbWUgPj0gJzAnICYmICpuYW1lIDw9ICc5JykNCiAgICAgICAgICAgICAgICB2ICs9ICpuYW1lIC0gJzAnOw0KICAgICAgICAgICAgZWxzZSBpZiAoKm5hbWUgPj0gJ0EnICYmICpuYW1lIDw9ICdGJykNCiAgICAgICAgICAgICAgICB2ICs9ICpuYW1lIC0gJ0EnICsgMTA7DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICAgcmV0dXJuIDA7DQogICAgICAgICAgICBuYW1lKys7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFpc191bmlmaWVkX2lkZW9ncmFwaCh2KSkNCiAgICAgICAgICAgIHJldHVybiAwOw0KICAgICAgICAqY29kZSA9IHY7DQogICAgICAgIHJldHVybiAxOw0KICAgIH0NCg0KICAgIC8qIHRoZSBmb2xsb3dpbmcgaXMgdGhlIHNhbWUgYXMgcHl0aG9uJ3MgZGljdGlvbmFyeSBsb29rdXAsIHdpdGgNCiAgICAgICBvbmx5IG1pbm9yIGNoYW5nZXMuICBzZWUgdGhlIG1ha2V1bmljb2RlZGF0YSBzY3JpcHQgZm9yIG1vcmUNCiAgICAgICBkZXRhaWxzICovDQoNCiAgICBoID0gKHVuc2lnbmVkIGludCkgX2dldGhhc2gobmFtZSwgbmFtZWxlbiwgY29kZV9tYWdpYyk7DQogICAgaSA9ICh+aCkgJiBtYXNrOw0KICAgIHYgPSBjb2RlX2hhc2hbaV07DQogICAgaWYgKCF2KQ0KICAgICAgICByZXR1cm4gMDsNCiAgICBpZiAoX2NtcG5hbWUoc2VsZiwgdiwgbmFtZSwgbmFtZWxlbikpIHsNCiAgICAgICAgKmNvZGUgPSB2Ow0KICAgICAgICByZXR1cm4gMTsNCiAgICB9DQogICAgaW5jciA9IChoIF4gKGggPj4gMykpICYgbWFzazsNCiAgICBpZiAoIWluY3IpDQogICAgICAgIGluY3IgPSBtYXNrOw0KICAgIGZvciAoOzspIHsNCiAgICAgICAgaSA9IChpICsgaW5jcikgJiBtYXNrOw0KICAgICAgICB2ID0gY29kZV9oYXNoW2ldOw0KICAgICAgICBpZiAoIXYpDQogICAgICAgICAgICByZXR1cm4gMDsNCiAgICAgICAgaWYgKF9jbXBuYW1lKHNlbGYsIHYsIG5hbWUsIG5hbWVsZW4pKSB7DQogICAgICAgICAgICAqY29kZSA9IHY7DQogICAgICAgICAgICByZXR1cm4gMTsNCiAgICAgICAgfQ0KICAgICAgICBpbmNyID0gaW5jciA8PCAxOw0KICAgICAgICBpZiAoaW5jciA+IG1hc2spDQogICAgICAgICAgICBpbmNyID0gaW5jciBeIGNvZGVfcG9seTsNCiAgICB9DQp9DQoNCnN0YXRpYyBjb25zdCBfUHlVbmljb2RlX05hbWVfQ0FQSSBoYXNoQVBJID0NCnsNCiAgICBzaXplb2YoX1B5VW5pY29kZV9OYW1lX0NBUEkpLA0KICAgIF9nZXR1Y25hbWUsDQogICAgX2dldGNvZGUNCn07DQoNCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQovKiBQeXRob24gYmluZGluZ3MgKi8NCg0KUHlEb2NfU1RSVkFSKHVuaWNvZGVkYXRhX25hbWVfX2RvY19fLA0KIm5hbWUodW5pY2hyWywgZGVmYXVsdF0pXG5cDQpSZXR1cm5zIHRoZSBuYW1lIGFzc2lnbmVkIHRvIHRoZSBVbmljb2RlIGNoYXJhY3RlciB1bmljaHIgYXMgYVxuXA0Kc3RyaW5nLiBJZiBubyBuYW1lIGlzIGRlZmluZWQsIGRlZmF1bHQgaXMgcmV0dXJuZWQsIG9yLCBpZiBub3RcblwNCmdpdmVuLCBWYWx1ZUVycm9yIGlzIHJhaXNlZC4iKTsNCg0Kc3RhdGljIFB5T2JqZWN0ICoNCnVuaWNvZGVkYXRhX25hbWUoUHlPYmplY3QqIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQ0Kew0KICAgIGNoYXIgbmFtZVtOQU1FX01BWExFTl07DQogICAgUHlfVUNTNCBjOw0KDQogICAgUHlVbmljb2RlT2JqZWN0KiB2Ow0KICAgIFB5T2JqZWN0KiBkZWZvYmogPSBOVUxMOw0KICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyF8TzpuYW1lIiwgJlB5VW5pY29kZV9UeXBlLCAmdiwgJmRlZm9iaikpDQogICAgICAgIHJldHVybiBOVUxMOw0KDQogICAgYyA9IGdldHVjaGFyKHYpOw0KICAgIGlmIChjID09IChQeV9VQ1M0KS0xKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCg0KICAgIGlmICghX2dldHVjbmFtZShzZWxmLCBjLCBuYW1lLCBzaXplb2YobmFtZSkpKSB7DQogICAgICAgIGlmIChkZWZvYmogPT0gTlVMTCkgew0KICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJubyBzdWNoIG5hbWUiKTsNCiAgICAgICAgICAgIHJldHVybiBOVUxMOw0KICAgICAgICB9DQogICAgICAgIGVsc2Ugew0KICAgICAgICAgICAgUHlfSU5DUkVGKGRlZm9iaik7DQogICAgICAgICAgICByZXR1cm4gZGVmb2JqOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgcmV0dXJuIFB5X0J1aWxkVmFsdWUoInMiLCBuYW1lKTsNCn0NCg0KUHlEb2NfU1RSVkFSKHVuaWNvZGVkYXRhX2xvb2t1cF9fZG9jX18sDQoibG9va3VwKG5hbWUpXG5cDQpcblwNCkxvb2sgdXAgY2hhcmFjdGVyIGJ5IG5hbWUuICBJZiBhIGNoYXJhY3RlciB3aXRoIHRoZVxuXA0KZ2l2ZW4gbmFtZSBpcyBmb3VuZCwgcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIFVuaWNvZGVcblwNCmNoYXJhY3Rlci4gIElmIG5vdCBmb3VuZCwgS2V5RXJyb3IgaXMgcmFpc2VkLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QgKg0KdW5pY29kZWRhdGFfbG9va3VwKFB5T2JqZWN0KiBzZWxmLCBQeU9iamVjdCogYXJncykNCnsNCiAgICBQeV9VQ1M0IGNvZGU7DQogICAgUHlfVU5JQ09ERSBzdHJbMl07DQoNCiAgICBjaGFyKiBuYW1lOw0KICAgIGludCBuYW1lbGVuOw0KICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAicyM6bG9va3VwIiwgJm5hbWUsICZuYW1lbGVuKSkNCiAgICAgICAgcmV0dXJuIE5VTEw7DQoNCiAgICBpZiAoIV9nZXRjb2RlKHNlbGYsIG5hbWUsIG5hbWVsZW4sICZjb2RlKSkgew0KICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfS2V5RXJyb3IsICJ1bmRlZmluZWQgY2hhcmFjdGVyIG5hbWUgJyVzJyIsDQogICAgICAgICAgICAgICAgICAgICBuYW1lKTsNCiAgICAgICAgcmV0dXJuIE5VTEw7DQogICAgfQ0KDQojaWZuZGVmIFB5X1VOSUNPREVfV0lERQ0KICAgIGlmIChjb2RlID49IDB4MTAwMDApIHsNCiAgICAgICAgc3RyWzBdID0gMHhkODAwICsgKChjb2RlIC0gMHgxMDAwMCkgPj4gMTApOw0KICAgICAgICBzdHJbMV0gPSAweGRjMDAgKyAoKGNvZGUgLSAweDEwMDAwKSAmIDB4M2ZmKTsNCiAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9Gcm9tVW5pY29kZShzdHIsIDIpOw0KICAgIH0NCiNlbmRpZg0KICAgIHN0clswXSA9IChQeV9VTklDT0RFKSBjb2RlOw0KICAgIHJldHVybiBQeVVuaWNvZGVfRnJvbVVuaWNvZGUoc3RyLCAxKTsNCn0NCg0KLyogWFhYIEFkZCBkb2Mgc3RyaW5ncy4gKi8NCg0Kc3RhdGljIFB5TWV0aG9kRGVmIHVuaWNvZGVkYXRhX2Z1bmN0aW9uc1tdID0gew0KICAgIHsiZGVjaW1hbCIsIHVuaWNvZGVkYXRhX2RlY2ltYWwsIE1FVEhfVkFSQVJHUywgdW5pY29kZWRhdGFfZGVjaW1hbF9fZG9jX199LA0KICAgIHsiZGlnaXQiLCB1bmljb2RlZGF0YV9kaWdpdCwgTUVUSF9WQVJBUkdTLCB1bmljb2RlZGF0YV9kaWdpdF9fZG9jX199LA0KICAgIHsibnVtZXJpYyIsIHVuaWNvZGVkYXRhX251bWVyaWMsIE1FVEhfVkFSQVJHUywgdW5pY29kZWRhdGFfbnVtZXJpY19fZG9jX199LA0KICAgIHsiY2F0ZWdvcnkiLCB1bmljb2RlZGF0YV9jYXRlZ29yeSwgTUVUSF9WQVJBUkdTLA0KICAgICAgICAgICAgICAgICB1bmljb2RlZGF0YV9jYXRlZ29yeV9fZG9jX199LA0KICAgIHsiYmlkaXJlY3Rpb25hbCIsIHVuaWNvZGVkYXRhX2JpZGlyZWN0aW9uYWwsIE1FVEhfVkFSQVJHUywNCiAgICAgICAgICAgICAgICAgICAgICB1bmljb2RlZGF0YV9iaWRpcmVjdGlvbmFsX19kb2NfX30sDQogICAgeyJjb21iaW5pbmciLCB1bmljb2RlZGF0YV9jb21iaW5pbmcsIE1FVEhfVkFSQVJHUywNCiAgICAgICAgICAgICAgICAgIHVuaWNvZGVkYXRhX2NvbWJpbmluZ19fZG9jX199LA0KICAgIHsibWlycm9yZWQiLCB1bmljb2RlZGF0YV9taXJyb3JlZCwgTUVUSF9WQVJBUkdTLA0KICAgICAgICAgICAgICAgICB1bmljb2RlZGF0YV9taXJyb3JlZF9fZG9jX199LA0KICAgIHsiZWFzdF9hc2lhbl93aWR0aCIsIHVuaWNvZGVkYXRhX2Vhc3RfYXNpYW5fd2lkdGgsIE1FVEhfVkFSQVJHUywNCiAgICAgICAgICAgICAgICAgICAgICAgICB1bmljb2RlZGF0YV9lYXN0X2FzaWFuX3dpZHRoX19kb2NfX30sDQogICAgeyJkZWNvbXBvc2l0aW9uIiwgdW5pY29kZWRhdGFfZGVjb21wb3NpdGlvbiwgTUVUSF9WQVJBUkdTLA0KICAgICAgICAgICAgICAgICAgICAgIHVuaWNvZGVkYXRhX2RlY29tcG9zaXRpb25fX2RvY19ffSwNCiAgICB7Im5hbWUiLCB1bmljb2RlZGF0YV9uYW1lLCBNRVRIX1ZBUkFSR1MsIHVuaWNvZGVkYXRhX25hbWVfX2RvY19ffSwNCiAgICB7Imxvb2t1cCIsIHVuaWNvZGVkYXRhX2xvb2t1cCwgTUVUSF9WQVJBUkdTLCB1bmljb2RlZGF0YV9sb29rdXBfX2RvY19ffSwNCiAgICB7Im5vcm1hbGl6ZSIsIHVuaWNvZGVkYXRhX25vcm1hbGl6ZSwgTUVUSF9WQVJBUkdTLA0KICAgICAgICAgICAgICAgICAgdW5pY29kZWRhdGFfbm9ybWFsaXplX19kb2NfX30sDQogICAge05VTEwsIE5VTEx9ICAgICAgICAgICAgICAgIC8qIHNlbnRpbmVsICovDQp9Ow0KDQpzdGF0aWMgUHlUeXBlT2JqZWN0IFVDRF9UeXBlID0gew0KICAgICAgICAvKiBUaGUgb2JfdHlwZSBmaWVsZCBtdXN0IGJlIGluaXRpYWxpemVkIGluIHRoZSBtb2R1bGUgaW5pdCBmdW5jdGlvbg0KICAgICAgICAgKiB0byBiZSBwb3J0YWJsZSB0byBXaW5kb3dzIHdpdGhvdXQgdXNpbmcgQysrLiAqLw0KICAgICAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoTlVMTCwgMCkNCiAgICAgICAgInVuaWNvZGVkYXRhLlVDRCIsICAgICAgICAgICAgICAvKnRwX25hbWUqLw0KICAgICAgICBzaXplb2YoUHJldmlvdXNEQlZlcnNpb24pLCAgICAgIC8qdHBfYmFzaWNzaXplKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pdGVtc2l6ZSovDQogICAgICAgIC8qIG1ldGhvZHMgKi8NCiAgICAgICAgKGRlc3RydWN0b3IpUHlPYmplY3RfRGVsLCAvKnRwX2RlYWxsb2MqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX3ByaW50Ki8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9nZXRhdHRyKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9zZXRhdHRyKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9jb21wYXJlKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9yZXByKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19udW1iZXIqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FzX3NlcXVlbmNlKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19tYXBwaW5nKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9oYXNoKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9jYWxsKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9zdHIqLw0KICAgICAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwvKnRwX2dldGF0dHJvKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9zZXRhdHRybyovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfYnVmZmVyKi8NCiAgICAgICAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgLyp0cF9mbGFncyovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZG9jKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF90cmF2ZXJzZSovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY2xlYXIqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX3JpY2hjb21wYXJlKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF93ZWFrbGlzdG9mZnNldCovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXRlciovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXRlcm5leHQqLw0KICAgICAgICB1bmljb2RlZGF0YV9mdW5jdGlvbnMsICAvKnRwX21ldGhvZHMqLw0KICAgICAgICBEQl9tZW1iZXJzLCAgICAgICAgICAgICAvKnRwX21lbWJlcnMqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2dldHNldCovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYmFzZSovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGljdCovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGVzY3JfZ2V0Ki8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kZXNjcl9zZXQqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2RpY3RvZmZzZXQqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2luaXQqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FsbG9jKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9uZXcqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2ZyZWUqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2lzX2djKi8NCn07DQoNClB5RG9jX1NUUlZBUih1bmljb2RlZGF0YV9kb2NzdHJpbmcsDQoiVGhpcyBtb2R1bGUgcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBVbmljb2RlIENoYXJhY3RlciBEYXRhYmFzZSB3aGljaFxuXA0KZGVmaW5lcyBjaGFyYWN0ZXIgcHJvcGVydGllcyBmb3IgYWxsIFVuaWNvZGUgY2hhcmFjdGVycy4gVGhlIGRhdGEgaW5cblwNCnRoaXMgZGF0YWJhc2UgaXMgYmFzZWQgb24gdGhlIFVuaWNvZGVEYXRhLnR4dCBmaWxlIHZlcnNpb25cblwNCjUuMi4wIHdoaWNoIGlzIHB1YmxpY2FsbHkgYXZhaWxhYmxlIGZyb20gZnRwOi8vZnRwLnVuaWNvZGUub3JnLy5cblwNClxuXA0KVGhlIG1vZHVsZSB1c2VzIHRoZSBzYW1lIG5hbWVzIGFuZCBzeW1ib2xzIGFzIGRlZmluZWQgYnkgdGhlXG5cDQpVbmljb2RlRGF0YSBGaWxlIEZvcm1hdCA1LjIuMCAoc2VlXG5cDQpodHRwOi8vd3d3LnVuaWNvZGUub3JnL3JlcG9ydHMvdHI0NC90cjQ0LTQuaHRtbCkuIik7DQoNClB5TU9ESU5JVF9GVU5DDQppbml0dW5pY29kZWRhdGEodm9pZCkNCnsNCiAgICBQeU9iamVjdCAqbSwgKnY7DQoNCiAgICBQeV9UWVBFKCZVQ0RfVHlwZSkgPSAmUHlUeXBlX1R5cGU7DQoNCiAgICBtID0gUHlfSW5pdE1vZHVsZTMoDQogICAgICAgICJ1bmljb2RlZGF0YSIsIHVuaWNvZGVkYXRhX2Z1bmN0aW9ucywgdW5pY29kZWRhdGFfZG9jc3RyaW5nKTsNCiAgICBpZiAoIW0pDQogICAgICAgIHJldHVybjsNCg0KICAgIFB5TW9kdWxlX0FkZFN0cmluZ0NvbnN0YW50KG0sICJ1bmlkYXRhX3ZlcnNpb24iLCBVTklEQVRBX1ZFUlNJT04pOw0KICAgIFB5X0lOQ1JFRigmVUNEX1R5cGUpOw0KICAgIFB5TW9kdWxlX0FkZE9iamVjdChtLCAiVUNEIiwgKFB5T2JqZWN0KikmVUNEX1R5cGUpOw0KDQogICAgLyogUHJldmlvdXMgdmVyc2lvbnMgKi8NCiAgICB2ID0gbmV3X3ByZXZpb3VzX3ZlcnNpb24oIjMuMi4wIiwgZ2V0X2NoYW5nZV8zXzJfMCwgbm9ybWFsaXphdGlvbl8zXzJfMCk7DQogICAgaWYgKHYgIT0gTlVMTCkNCiAgICAgICAgUHlNb2R1bGVfQWRkT2JqZWN0KG0sICJ1Y2RfM18yXzAiLCB2KTsNCg0KICAgIC8qIEV4cG9ydCBDIEFQSSAqLw0KICAgIHYgPSBQeUNhcHN1bGVfTmV3KCh2b2lkICopJmhhc2hBUEksIFB5VW5pY29kZURhdGFfQ0FQU1VMRV9OQU1FLCBOVUxMKTsNCiAgICBpZiAodiAhPSBOVUxMKQ0KICAgICAgICBQeU1vZHVsZV9BZGRPYmplY3QobSwgInVjbmhhc2hfQ0FQSSIsIHYpOw0KfQ0KDQovKg0KTG9jYWwgdmFyaWFibGVzOg0KYy1iYXNpYy1vZmZzZXQ6IDQNCmluZGVudC10YWJzLW1vZGU6IG5pbA0KRW5kOg0KKi8NCg==